diff --git a/.gitignore b/.gitignore index 59d383265d43..fb3dd5b33b90 100644 --- a/.gitignore +++ b/.gitignore @@ -9,11 +9,8 @@ *~ .gdb_history Doc/build/ -Doc/tools/docutils/ -Doc/tools/jinja/ -Doc/tools/jinja2/ -Doc/tools/pygments/ -Doc/tools/sphinx/ +Doc/venv/ +Lib/distutils/command/*.pdb Lib/lib2to3/*.pickle Lib/test/data/* Lib/_sysconfigdata.py @@ -27,18 +24,30 @@ Modules/Setup.config Modules/Setup.local Modules/config.c Modules/ld_so_aix -Modules/_freeze_importlib -Modules/_testembed -PCbuild/*.bsc -PCbuild/*.dll -PCbuild/*.exe -PCbuild/*.exp -PCbuild/*.lib -PCbuild/*.ncb -PCbuild/*.o -PCbuild/*.pdb -PCbuild/Win32-temp-* +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/amd64/ +PCbuild/obj +PCBuild/win32 .purify Parser/pgen __pycache__ @@ -61,6 +70,7 @@ pyconfig.h python python-config python-config.py +python.bat python.exe python-gdb.py python.exe-gdb.py @@ -70,4 +80,8 @@ tags TAGS .coverage coverage/ +externals/ htmlcov/ +Tools/msi/obj +Tools/ssl/amd64 +Tools/ssl/win32 diff --git a/.hgeol b/.hgeol index aad79c21136b..2919f76a110b 100644 --- a/.hgeol +++ b/.hgeol @@ -38,6 +38,8 @@ Lib/test/xmltestdata/* = BIN Lib/venv/scripts/nt/* = BIN +Lib/test/coding20731.py = BIN + # All other files (which presumably are human-editable) are "native". # This must be the last rule! diff --git a/.hgignore b/.hgignore index 6128c2bbaef1..7a5260691dcf 100644 --- a/.hgignore +++ b/.hgignore @@ -9,6 +9,7 @@ TAGS$ autom4te.cache$ ^build/ ^Doc/build/ +^Doc/venv/ buildno$ config.cache config.log @@ -18,17 +19,13 @@ db_home platform$ pyconfig.h$ python$ +python.bat$ python.exe$ python-config$ python-config.py$ reflog.txt$ tags$ Lib/plat-mac/errors.rsrc.df.rsrc -Doc/tools/sphinx/ -Doc/tools/docutils/ -Doc/tools/jinja/ -Doc/tools/jinja2/ -Doc/tools/pygments/ Misc/python.pc Misc/python-config.sh$ Modules/Setup$ @@ -53,13 +50,12 @@ libpython*.so* *.pyd *.cover *~ +Lib/distutils/command/*.pdb Lib/lib2to3/*.pickle Lib/test/data/* Misc/*.wpu PC/python_nt*.h PC/pythonnt_rc*.h -PC/*.obj -PC/*.exe PC/*/*.exe PC/*/*.exp PC/*/*.lib @@ -72,31 +68,28 @@ PC/*/*.suo PC/*/Win32-temp-* PC/*/x64-temp-* PC/*/amd64 -PCbuild/*.exe -PCbuild/*.dll -PCbuild/*.pdb -PCbuild/*.lib -PCbuild/*.exp -PCbuild/*.o -PCbuild/*.ncb -PCbuild/*.bsc PCbuild/*.user PCbuild/*.suo PCbuild/*.*sdf -PCbuild/Win32-temp-* -PCbuild/x64-temp-* +PCbuild/*-pgi +PCbuild/*-pgo PCbuild/amd64 -PCbuild/ipch +PCbuild/obj +PCbuild/win32 Tools/unicode/build/ Tools/unicode/MAPPINGS/ BuildLog.htm __pycache__ -Modules/_freeze_importlib -Modules/_testembed +Programs/_freeze_importlib +Programs/_testembed .coverage coverage/ +externals/ htmlcov/ *.gcda *.gcno *.gcov coverage.info +Tools/msi/obj +Tools/ssl/amd64 +Tools/ssl/win32 diff --git a/.hgtouch b/.hgtouch index 7e3a5e737088..b9be0f11fdb8 100644 --- a/.hgtouch +++ b/.hgtouch @@ -2,7 +2,9 @@ # Define dependencies of generated files that are checked into hg. # The syntax of this file uses make rule dependencies, without actions -Python/importlib.h: Lib/importlib/_bootstrap.py Modules/_freeze_importlib.c +Python/importlib.h: Lib/importlib/_bootstrap.py Programs/_freeze_importlib.c + +Include/opcode.h: Lib/opcode.py Tools/scripts/generate_opcode_h.py Include/Python-ast.h: Parser/Python.asdl Parser/asdl.py Parser/asdl_c.py Python/Python-ast.c: Include/Python-ast.h diff --git a/Doc/Makefile b/Doc/Makefile index 3c7196e367bf..200a9f7d1fd1 100644 --- a/Doc/Makefile +++ b/Doc/Makefile @@ -5,24 +5,24 @@ # You can set these variables from the command line. PYTHON = python -SVNROOT = http://svn.python.org/projects -SPHINXOPTS = +SPHINXBUILD = sphinx-build PAPER = SOURCES = -DISTVERSION = $(shell $(PYTHON) tools/sphinxext/patchlevel.py) +DISTVERSION = $(shell $(PYTHON) tools/extensions/patchlevel.py) ALLSPHINXOPTS = -b $(BUILDER) -d build/doctrees -D latex_paper_size=$(PAPER) \ $(SPHINXOPTS) . build/$(BUILDER) $(SOURCES) -.PHONY: help checkout update build html htmlhelp latex text changes linkcheck \ +.PHONY: help build html htmlhelp latex text changes linkcheck \ suspicious coverage doctest pydoc-topics htmlview clean dist check serve \ - autobuild-dev autobuild-stable + autobuild-dev autobuild-stable venv help: @echo "Please use \`make ' where is one of" @echo " clean to remove build files" - @echo " update to update build tools" + @echo " venv to create a venv with necessary tools" @echo " html to make standalone HTML files" + @echo " htmlview to open the index page built by the html target in your browser" @echo " htmlhelp to make HTML files and a HTML help project" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " text to make plain text files" @@ -37,30 +37,8 @@ help: @echo " check to run a check for frequent markup errors" @echo " serve to serve the documentation on the localhost (8000)" -# Note: if you update versions here, do the same in make.bat and README.txt -checkout: - @if [ ! -d tools/sphinx ]; then \ - echo "Checking out Sphinx..."; \ - svn checkout $(SVNROOT)/external/Sphinx-1.0.7/sphinx tools/sphinx; \ - fi - @if [ ! -d tools/docutils ]; then \ - echo "Checking out Docutils..."; \ - svn checkout $(SVNROOT)/external/docutils-0.6/docutils tools/docutils; \ - fi - @if [ ! -d tools/jinja2 ]; then \ - echo "Checking out Jinja..."; \ - svn checkout $(SVNROOT)/external/Jinja-2.3.1/jinja2 tools/jinja2; \ - fi - @if [ ! -d tools/pygments ]; then \ - echo "Checking out Pygments..."; \ - svn checkout $(SVNROOT)/external/Pygments-1.5dev-20120930/pygments tools/pygments; \ - fi - -update: clean checkout - -build: checkout - mkdir -p build/$(BUILDER) build/doctrees - $(PYTHON) tools/sphinx-build.py $(ALLSPHINXOPTS) +build: + $(SPHINXBUILD) $(ALLSPHINXOPTS) @echo html: BUILDER = html @@ -91,24 +69,30 @@ changes: build @echo "The overview file is in build/changes." linkcheck: BUILDER = linkcheck -linkcheck: build - @echo "Link check complete; look for any errors in the above output" \ - "or in build/$(BUILDER)/output.txt" +linkcheck: + @$(MAKE) build BUILDER=$(BUILDER) || { \ + echo "Link check complete; look for any errors in the above output" \ + "or in build/$(BUILDER)/output.txt"; \ + false; } suspicious: BUILDER = suspicious -suspicious: build - @echo "Suspicious check complete; look for any errors in the above output" \ - "or in build/$(BUILDER)/suspicious.csv. If all issues are false" \ - "positives, append that file to tools/sphinxext/susp-ignored.csv." +suspicious: + @$(MAKE) build BUILDER=$(BUILDER) || { \ + echo "Suspicious check complete; look for any errors in the above output" \ + "or in build/$(BUILDER)/suspicious.csv. If all issues are false" \ + "positives, append that file to tools/susp-ignored.csv."; \ + false; } coverage: BUILDER = coverage coverage: build @echo "Coverage finished; see c.txt and python.txt in build/coverage" doctest: BUILDER = doctest -doctest: build - @echo "Testing of doctests in the sources finished, look at the" \ - "results in build/doctest/output.txt" +doctest: + @$(MAKE) build BUILDER=$(BUILDER) || { \ + echo "Testing of doctests in the sources finished, look at the" \ + "results in build/doctest/output.txt"; \ + false; } pydoc-topics: BUILDER = pydoc-topics pydoc-topics: build @@ -119,11 +103,11 @@ htmlview: html $(PYTHON) -c "import webbrowser; webbrowser.open('build/html/index.html')" clean: - -rm -rf build/* - -rm -rf tools/sphinx - -rm -rf tools/pygments - -rm -rf tools/jinja2 - -rm -rf tools/docutils + -rm -rf build/* venv/* + +venv: + $(PYTHON) -m venv venv + ./venv/bin/python3 -m pip install -U Sphinx dist: rm -rf dist @@ -163,16 +147,10 @@ dist: cp build/latex/docs-pdf.zip dist/python-$(DISTVERSION)-docs-pdf-letter.zip cp build/latex/docs-pdf.tar.bz2 dist/python-$(DISTVERSION)-docs-pdf-letter.tar.bz2 - # archive the epub build + # copy the epub build rm -rf build/epub make epub - mkdir -p dist/python-$(DISTVERSION)-docs-epub - cp -pPR build/epub/*.epub dist/python-$(DISTVERSION)-docs-epub/ - tar -C dist -cf dist/python-$(DISTVERSION)-docs-epub.tar python-$(DISTVERSION)-docs-epub - bzip2 -9 -k dist/python-$(DISTVERSION)-docs-epub.tar - (cd dist; zip -q -r -9 python-$(DISTVERSION)-docs-epub.zip python-$(DISTVERSION)-docs-epub) - rm -r dist/python-$(DISTVERSION)-docs-epub - rm dist/python-$(DISTVERSION)-docs-epub.tar + cp -pPR build/epub/Python.epub dist/python-$(DISTVERSION)-docs.epub check: $(PYTHON) tools/rstlint.py -i tools @@ -184,7 +162,6 @@ serve: # for development releases: always build autobuild-dev: - make update make dist SPHINXOPTS='-A daily=1 -A versionswitcher=1' -make suspicious @@ -192,11 +169,11 @@ autobuild-dev: autobuild-html: make html SPHINXOPTS='-A daily=1 -A versionswitcher=1' -# for stable releases: only build if not in pre-release stage (alpha, beta, rc) +# for stable releases: only build if not in pre-release stage (alpha, beta) +# release candidate downloads are okay, since the stable tree can be in that stage autobuild-stable: - @case $(DISTVERSION) in *[abc]*) \ + @case $(DISTVERSION) in *[ab]*) \ echo "Not building; $(DISTVERSION) is not a release version."; \ exit 1;; \ esac @make autobuild-dev - diff --git a/Doc/README.txt b/Doc/README.txt index 64e307ee6543..580d10241db5 100644 --- a/Doc/README.txt +++ b/Doc/README.txt @@ -3,124 +3,116 @@ Python Documentation README This directory contains the reStructuredText (reST) sources to the Python documentation. You don't need to build them yourself, prebuilt versions are -available at http://docs.python.org/download/. +available at . -Documentation on the authoring Python documentation, including information about +Documentation on authoring Python documentation, including information about both style and markup, is available in the "Documenting Python" chapter of the -developers guide (http://docs.python.org/devguide/documenting.html). -There's also a chapter intended to point out differences to -those familiar with the previous docs written in LaTeX. +developers guide . Building the docs ================= -You need to have Python 2.4 or higher installed; the toolset used to build the -docs is written in Python. It is called *Sphinx*, it is not included in this -tree, but maintained separately. Also needed are the docutils, supplying the -base markup that Sphinx uses, Jinja, a templating engine, and optionally -Pygments, a code highlighter. +You need to have Sphinx installed; it is the toolset +used to build the docs. It is not included in this tree, but maintained +separately and available from PyPI . Using make ---------- -Luckily, a Makefile has been prepared so that on Unix, provided you have -installed Python and Subversion, you can just run :: +A Makefile has been prepared so that on Unix, provided you have installed +Sphinx, you can just run :: make html -to check out the necessary toolset in the `tools/` subdirectory and build the -HTML output files. To view the generated HTML, point your favorite browser at -the top-level index `build/html/index.html` after running "make". +to build the HTML output files. + +On Windows, we try to emulate the Makefile as closely as possible with a +``make.bat`` file. To use a Python interpreter that's not called ``python``, use the standard way to set Makefile variables, using e.g. :: - make html PYTHON=/usr/bin/python2.5 - -Available make targets are: - - * "html", which builds standalone HTML files for offline viewing. - - * "htmlhelp", which builds HTML files and a HTML Help project file usable to - convert them into a single Compiled HTML (.chm) file -- these are popular - under Microsoft Windows, but very handy on every platform. - - To create the CHM file, you need to run the Microsoft HTML Help Workshop over - the generated project (.hhp) file. + make html PYTHON=python3 - * "latex", which builds LaTeX source files as input to "pdflatex" to produce - PDF documents. +On Windows, set the PYTHON environment variable instead. - * "text", which builds a plain text file for each source file. +To use a specific sphinx-build (something other than ``sphinx-build``), set +the SPHINXBUILD variable. - * "epub", which builds an EPUB document, suitable to be viewed on e-book - readers. - - * "linkcheck", which checks all external references to see whether they are - broken, redirected or malformed, and outputs this information to stdout as - well as a plain-text (.txt) file. +Available make targets are: - * "changes", which builds an overview over all versionadded/versionchanged/ - deprecated items in the current version. This is meant as a help for the - writer of the "What's New" document. +* "clean", which removes all build files. - * "coverage", which builds a coverage overview for standard library modules and - C API. +* "html", which builds standalone HTML files for offline viewing. - * "pydoc-topics", which builds a Python module containing a dictionary with - plain text documentation for the labels defined in - `tools/sphinxext/pyspecific.py` -- pydoc needs these to show topic and - keyword help. +* "htmlview", which re-uses the "html" builder, but then opens the main page + in your default web browser. -A "make update" updates the Subversion checkouts in `tools/`. +* "htmlhelp", which builds HTML files and a HTML Help project file usable to + convert them into a single Compiled HTML (.chm) file -- these are popular + under Microsoft Windows, but very handy on every platform. + To create the CHM file, you need to run the Microsoft HTML Help Workshop + over the generated project (.hhp) file. The make.bat script does this for + you on Windows. -Without make ------------- +* "latex", which builds LaTeX source files as input to "pdflatex" to produce + PDF documents. -You'll need to install the Sphinx package, either by checking it out via :: +* "text", which builds a plain text file for each source file. - svn co http://svn.python.org/projects/external/Sphinx-1.0.7/sphinx tools/sphinx +* "epub", which builds an EPUB document, suitable to be viewed on e-book + readers. -or by installing it from PyPI. +* "linkcheck", which checks all external references to see whether they are + broken, redirected or malformed, and outputs this information to stdout as + well as a plain-text (.txt) file. -Then, you need to install Docutils, either by checking it out via :: +* "changes", which builds an overview over all versionadded/versionchanged/ + deprecated items in the current version. This is meant as a help for the + writer of the "What's New" document. - svn co http://svn.python.org/projects/external/docutils-0.6/docutils tools/docutils +* "coverage", which builds a coverage overview for standard library modules and + C API. -or by installing it from http://docutils.sf.net/. +* "pydoc-topics", which builds a Python module containing a dictionary with + plain text documentation for the labels defined in + `tools/pyspecific.py` -- pydoc needs these to show topic and keyword help. -You also need Jinja2, either by checking it out via :: +* "suspicious", which checks the parsed markup for text that looks like + malformed and thus unconverted reST. - svn co http://svn.python.org/projects/external/Jinja-2.3.1/jinja2 tools/jinja2 +* "check", which checks for frequent markup errors. -or by installing it from PyPI. +* "serve", which serves the build/html directory on port 8000. -You can optionally also install Pygments, either as a checkout via :: +* "dist", (Unix only) which creates distributable archives of HTML, text, + PDF, and EPUB builds. - svn co http://svn.python.org/projects/external/Pygments-1.3.1/pygments tools/pygments -or from PyPI at http://pypi.python.org/pypi/Pygments. +Without make +------------ +Install the Sphinx package and its dependencies from PyPI. -Then, make an output directory, e.g. under `build/`, and run :: +Then, from the ``Doc`` directory, run :: - python tools/sphinx-build.py -b . build/ + sphinx-build -b . build/ -where `` is one of html, text, latex, or htmlhelp (for explanations see -the make targets above). +where ```` is one of html, text, latex, or htmlhelp (for explanations +see the make targets above). Contributing ============ Bugs in the content should be reported to the Python bug tracker at -http://bugs.python.org. +https://bugs.python.org. Bugs in the toolset should be reported in the Sphinx bug tracker at -http://www.bitbucket.org/birkenfeld/sphinx/issues/. +https://www.bitbucket.org/birkenfeld/sphinx/issues/. You can also send a mail to the Python Documentation Team at docs@python.org, and we will process your request as soon as possible. @@ -136,7 +128,7 @@ The Python source is copyrighted, but you can freely use and copy it as long as you don't change or remove the copyright notice: ---------------------------------------------------------------------- -Copyright (c) 2000-2013 Python Software Foundation. +Copyright (c) 2000-2015 Python Software Foundation. All rights reserved. Copyright (c) 2000 BeOpen.com. diff --git a/Doc/about.rst b/Doc/about.rst index d316f09ff345..3ea311fa629d 100644 --- a/Doc/about.rst +++ b/Doc/about.rst @@ -6,29 +6,27 @@ About these documents These documents are generated from `reStructuredText`_ sources by `Sphinx`_, a document processor specifically written for the Python documentation. -.. _reStructuredText: http://docutils.sf.net/rst.html -.. _Sphinx: http://sphinx.pocoo.org/ +.. _reStructuredText: http://docutils.sourceforge.net/rst.html +.. _Sphinx: http://sphinx-doc.org/ .. In the online version of these documents, you can submit comments and suggest changes directly on the documentation pages. -Development of the documentation and its toolchain takes place on the -docs@python.org mailing list. We're always looking for volunteers wanting -to help with the docs, so feel free to send a mail there! +Development of the documentation and its toolchain is an entirely volunteer +effort, just like Python itself. If you want to contribute, please take a +look at the :ref:`reporting-bugs` page for information on how to do so. New +volunteers are always welcome! Many thanks go to: * Fred L. Drake, Jr., the creator of the original Python documentation toolset and writer of much of the content; -* the `Docutils `_ project for creating +* the `Docutils `_ project for creating reStructuredText and the Docutils suite; * Fredrik Lundh for his `Alternative Python Reference `_ project from which Sphinx got many good ideas. -See :ref:`reporting-bugs` for information how to report bugs in this -documentation, or Python itself. - Contributors to the Python Documentation ---------------------------------------- diff --git a/Doc/bugs.rst b/Doc/bugs.rst index 3785ccb72b30..f01ae0e3900e 100644 --- a/Doc/bugs.rst +++ b/Doc/bugs.rst @@ -13,21 +13,23 @@ Documentation bugs ================== If you find a bug in this documentation or would like to propose an improvement, -please send an e-mail to docs@python.org describing the bug and where you found -it. If you have a suggestion how to fix it, include that as well. +please submit a bug report on the :ref:`tracker `. If you +have a suggestion how to fix it, include that as well. -docs@python.org is a mailing list run by volunteers; your request will be -noticed, even if it takes a while to be processed. +If you're short on time, you can also email your bug report to docs@python.org. +'docs@' is a mailing list run by volunteers; your request will be noticed, +though it may take a while to be processed. -Of course, if you want a more persistent record of your issue, you can use the -issue tracker for documentation bugs as well. +.. seealso:: + `Documentation bugs`_ on the Python issue tracker +.. _using-the-tracker: Using the Python issue tracker ============================== Bug reports for Python itself should be submitted via the Python Bug Tracker -(http://bugs.python.org/). The bug tracker offers a Web form which allows +(https://bugs.python.org/). The bug tracker offers a Web form which allows pertinent information to be entered and submitted to the developers. The first step in filing a report is to determine whether the problem has @@ -62,14 +64,24 @@ taken on the bug. .. seealso:: - `Python Developer's Guide `_ - Detailed description of the issue workflow and developers tools. - `How to Report Bugs Effectively `_ Article which goes into some detail about how to create a useful bug report. This describes what kind of information is useful and why it is useful. - `Bug Writing Guidelines `_ + `Bug Writing Guidelines `_ Information about writing a good bug report. Some of this is specific to the Mozilla project, but describes general good practices. + +Getting started contributing to Python yourself +=============================================== + +Beyond just reporting bugs that you find, you are also welcome to submit +patches to fix them. You can find more information on how to get started +patching Python in the `Python Developer's Guide`_. If you have questions, +the `core-mentorship mailing list`_ is a friendly place to get answers to +any and all questions pertaining to the process of fixing issues in Python. + +.. _Documentation bugs: https://bugs.python.org/issue?@filter=status&@filter=components&components=4&status=1&@columns=id,activity,title,status&@sort=-activity +.. _Python Developer's Guide: https://docs.python.org/devguide/ +.. _core-mentorship mailing list: https://mail.python.org/mailman/listinfo/core-mentorship/ diff --git a/Doc/c-api/arg.rst b/Doc/c-api/arg.rst index b4efbf00f76f..3c0f4b98cdba 100644 --- a/Doc/c-api/arg.rst +++ b/Doc/c-api/arg.rst @@ -45,6 +45,7 @@ in any early abort case). Unless otherwise stated, buffers are not NUL-terminated. .. note:: + For all ``#`` variants of formats (``s#``, ``y#``, etc.), the type of the length argument (int or :c:type:`Py_ssize_t`) is controlled by defining the macro :c:macro:`PY_SSIZE_T_CLEAN` before including @@ -64,19 +65,20 @@ Unless otherwise stated, buffers are not NUL-terminated. :exc:`UnicodeError` is raised. .. note:: - This format does not accept bytes-like objects. If you want to accept + This format does not accept :term:`bytes-like objects + `. If you want to accept filesystem paths and convert them to C character strings, it is preferable to use the ``O&`` format with :c:func:`PyUnicode_FSConverter` as *converter*. -``s*`` (:class:`str`, :class:`bytes`, :class:`bytearray` or buffer compatible object) [Py_buffer] - This format accepts Unicode objects as well as :term:`bytes-like object`\ s. +``s*`` (:class:`str` or :term:`bytes-like object`) [Py_buffer] + This format accepts Unicode objects as well as bytes-like objects. It fills a :c:type:`Py_buffer` structure provided by the caller. In this case the resulting C string may contain embedded NUL bytes. Unicode objects are converted to C strings using ``'utf-8'`` encoding. -``s#`` (:class:`str`, :class:`bytes` or read-only buffer compatible object) [const char \*, int or :c:type:`Py_ssize_t`] - Like ``s*``, except that it doesn't accept mutable buffer-like objects +``s#`` (:class:`str`, read-only :term:`bytes-like object`) [const char \*, int or :c:type:`Py_ssize_t`] + Like ``s*``, except that it doesn't accept mutable bytes-like objects such as :class:`bytearray`. The result is stored into two C variables, the first one a pointer to a C string, the second one its length. The string may contain embedded null bytes. Unicode objects are converted @@ -86,28 +88,28 @@ Unless otherwise stated, buffers are not NUL-terminated. Like ``s``, but the Python object may also be ``None``, in which case the C pointer is set to *NULL*. -``z*`` (:class:`str`, :class:`bytes`, :class:`bytearray`, buffer compatible object or ``None``) [Py_buffer] +``z*`` (:class:`str`, :term:`bytes-like object` or ``None``) [Py_buffer] Like ``s*``, but the Python object may also be ``None``, in which case the ``buf`` member of the :c:type:`Py_buffer` structure is set to *NULL*. -``z#`` (:class:`str`, :class:`bytes`, read-only buffer compatible object or ``None``) [const char \*, int] +``z#`` (:class:`str`, read-only :term:`bytes-like object` or ``None``) [const char \*, int] Like ``s#``, but the Python object may also be ``None``, in which case the C pointer is set to *NULL*. -``y`` (:class:`bytes`) [const char \*] +``y`` (read-only :term:`bytes-like object`) [const char \*] This format converts a bytes-like object to a C pointer to a character string; it does not accept Unicode objects. The bytes buffer must not contain embedded NUL bytes; if it does, a :exc:`TypeError` exception is raised. -``y*`` (:class:`bytes`, :class:`bytearray` or :term:`bytes-like object`) [Py_buffer] +``y*`` (:term:`bytes-like object`) [Py_buffer] This variant on ``s*`` doesn't accept Unicode objects, only - :term:`bytes-like object`\ s. **This is the recommended way to accept + bytes-like objects. **This is the recommended way to accept binary data.** -``y#`` (:class:`bytes`) [const char \*, int] - This variant on ``s#`` doesn't accept Unicode objects, only :term:`bytes-like - object`\ s. +``y#`` (read-only :term:`bytes-like object`) [const char \*, int] + This variant on ``s#`` doesn't accept Unicode objects, only bytes-like + objects. ``S`` (:class:`bytes`) [PyBytesObject \*] Requires that the Python object is a :class:`bytes` object, without @@ -294,6 +296,8 @@ Other objects the object pointer is stored. If the Python object does not have the required type, :exc:`TypeError` is raised. +.. _o_ampersand: + ``O&`` (object) [*converter*, *anything*] Convert a Python object to a C variable through a *converter* function. This takes two arguments: the first is a function, the second is the address of a C @@ -426,10 +430,11 @@ API Functions Function used to deconstruct the argument lists of "old-style" functions --- these are functions which use the :const:`METH_OLDARGS` parameter parsing - method. This is not recommended for use in parameter parsing in new code, and - most code in the standard interpreter has been modified to no longer use this - for that purpose. It does remain a convenient way to decompose other tuples, - however, and may continue to be used for that purpose. + method, which has been removed in Python 3. This is not recommended for use + in parameter parsing in new code, and most code in the standard interpreter + has been modified to no longer use this for that purpose. It does remain a + convenient way to decompose other tuples, however, and may continue to be + used for that purpose. .. c:function:: int PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, ...) @@ -513,7 +518,7 @@ Building values ``None`` is returned. ``y`` (:class:`bytes`) [char \*] - This converts a C string to a Python :func:`bytes` object. If the C + This converts a C string to a Python :class:`bytes` object. If the C string pointer is *NULL*, ``None`` is returned. ``y#`` (:class:`bytes`) [char \*, int] diff --git a/Doc/c-api/buffer.rst b/Doc/c-api/buffer.rst index f703e9caf781..e6330e752198 100644 --- a/Doc/c-api/buffer.rst +++ b/Doc/c-api/buffer.rst @@ -89,6 +89,16 @@ a buffer, see :c:func:`PyObject_GetBuffer`. .. c:type:: Py_buffer + .. c:member:: void \*buf + + A pointer to the start of the logical structure described by the buffer + fields. This can be any location within the underlying physical memory + block of the exporter. For example, with negative :c:member:`~Py_buffer.strides` + the value may point to the end of the memory block. + + For contiguous arrays, the value points to the beginning of the memory + block. + .. c:member:: void \*obj A new reference to the exporting object. The reference is owned by @@ -101,16 +111,6 @@ a buffer, see :c:func:`PyObject_GetBuffer`. this field is *NULL*. In general, exporting objects MUST NOT use this scheme. - .. c:member:: void \*buf - - A pointer to the start of the logical structure described by the buffer - fields. This can be any location within the underlying physical memory - block of the exporter. For example, with negative :c:member:`~Py_buffer.strides` - the value may point to the end of the memory block. - - For contiguous arrays, the value points to the beginning of the memory - block. - .. c:member:: Py_ssize_t len ``product(shape) * itemsize``. For contiguous arrays, this is the length @@ -198,6 +198,9 @@ a buffer, see :c:func:`PyObject_GetBuffer`. indicates that no de-referencing should occur (striding in a contiguous memory block). + If all suboffsets are negative (i.e. no de-referencing is needed, then + this field must be NULL (the default value). + This type of array representation is used by the Python Imaging Library (PIL). See `complex arrays`_ for further information how to access elements of such an array. @@ -489,8 +492,8 @@ Buffer-related functions :c:member:`view->obj` to *NULL* and return -1; If this function is used as part of a :ref:`getbufferproc `, - *exporter* MUST be set to the exporting object. Otherwise, *exporter* MUST - be NULL. + *exporter* MUST be set to the exporting object and *flags* must be passed + unmodified. Otherwise, *exporter* MUST be NULL. diff --git a/Doc/c-api/codec.rst b/Doc/c-api/codec.rst index 83252afbb7f7..dfe3d436e5f4 100644 --- a/Doc/c-api/codec.rst +++ b/Doc/c-api/codec.rst @@ -116,3 +116,8 @@ Registry API for Unicode encoding error handlers Replace the unicode encode error with backslash escapes (``\x``, ``\u`` and ``\U``). +.. c:function:: PyObject* PyCodec_NameReplaceErrors(PyObject *exc) + + Replace the unicode encode error with ``\N{...}`` escapes. + + .. versionadded:: 3.5 diff --git a/Doc/c-api/dict.rst b/Doc/c-api/dict.rst index 5a9dca284500..aeff640564b0 100644 --- a/Doc/c-api/dict.rst +++ b/Doc/c-api/dict.rst @@ -201,8 +201,11 @@ Dictionary Objects .. c:function:: int PyDict_Update(PyObject *a, PyObject *b) - This is the same as ``PyDict_Merge(a, b, 1)`` in C, or ``a.update(b)`` in - Python. Return ``0`` on success or ``-1`` if an exception was raised. + This is the same as ``PyDict_Merge(a, b, 1)`` in C, and is similar to + ``a.update(b)`` in Python except that :c:func:`PyDict_Update` doesn't fall + back to the iterating over a sequence of key value pairs if the second + argument has no "keys" attribute. Return ``0`` on success or ``-1`` if an + exception was raised. .. c:function:: int PyDict_MergeFromSeq2(PyObject *a, PyObject *seq2, int override) diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst index 8658a5854104..814317b3593f 100644 --- a/Doc/c-api/exceptions.rst +++ b/Doc/c-api/exceptions.rst @@ -9,13 +9,19 @@ Exception Handling The functions described in this chapter will let you handle and raise Python exceptions. It is important to understand some of the basics of Python -exception handling. It works somewhat like the Unix :c:data:`errno` variable: +exception handling. It works somewhat like the POSIX :c:data:`errno` variable: there is a global indicator (per thread) of the last error that occurred. Most -functions don't clear this on success, but will set it to indicate the cause of -the error on failure. Most functions also return an error indicator, usually -*NULL* if they are supposed to return a pointer, or ``-1`` if they return an -integer (exception: the :c:func:`PyArg_\*` functions return ``1`` for success and -``0`` for failure). +C API functions don't clear this on success, but will set it to indicate the +cause of the error on failure. Most C API functions also return an error +indicator, usually *NULL* if they are supposed to return a pointer, or ``-1`` +if they return an integer (exception: the :c:func:`PyArg_\*` functions +return ``1`` for success and ``0`` for failure). + +Concretely, the error indicator consists of three object pointers: the +exception's type, the exception's value, and the traceback object. Any +of those pointers can be NULL if non-set (although some combinations are +forbidden, for example you can't have a non-NULL traceback if the exception +type is NULL). When a function must fail because some function it called failed, it generally doesn't set the error indicator; the function it called already set it. It is @@ -27,12 +33,21 @@ the caller that an error has been set. If the error is not handled or carefully propagated, additional calls into the Python/C API may not behave as intended and may fail in mysterious ways. -The error indicator consists of three Python objects corresponding to the result -of ``sys.exc_info()``. API functions exist to interact with the error indicator -in various ways. There is a separate error indicator for each thread. +.. note:: + The error indicator is **not** the result of :func:`sys.exc_info()`. + The former corresponds to an exception that is not yet caught (and is + therefore still propagating), while the latter returns an exception after + it is caught (and has therefore stopped propagating). -.. XXX Order of these should be more thoughtful. - Either alphabetical or some kind of structure. + +Printing and clearing +===================== + + +.. c:function:: void PyErr_Clear() + + Clear the error indicator. If the error indicator is not set, there is no + effect. .. c:function:: void PyErr_PrintEx(int set_sys_last_vars) @@ -51,117 +66,24 @@ in various ways. There is a separate error indicator for each thread. Alias for ``PyErr_PrintEx(1)``. -.. c:function:: PyObject* PyErr_Occurred() - - Test whether the error indicator is set. If set, return the exception *type* - (the first argument to the last call to one of the :c:func:`PyErr_Set\*` - functions or to :c:func:`PyErr_Restore`). If not set, return *NULL*. You do not - own a reference to the return value, so you do not need to :c:func:`Py_DECREF` - it. - - .. note:: - - Do not compare the return value to a specific exception; use - :c:func:`PyErr_ExceptionMatches` instead, shown below. (The comparison could - easily fail since the exception may be an instance instead of a class, in the - case of a class exception, or it may the a subclass of the expected exception.) - - -.. c:function:: int PyErr_ExceptionMatches(PyObject *exc) - - Equivalent to ``PyErr_GivenExceptionMatches(PyErr_Occurred(), exc)``. This - should only be called when an exception is actually set; a memory access - violation will occur if no exception has been raised. - - -.. c:function:: int PyErr_GivenExceptionMatches(PyObject *given, PyObject *exc) - - Return true if the *given* exception matches the exception in *exc*. If - *exc* is a class object, this also returns true when *given* is an instance - of a subclass. If *exc* is a tuple, all exceptions in the tuple (and - recursively in subtuples) are searched for a match. - - -.. c:function:: void PyErr_NormalizeException(PyObject**exc, PyObject**val, PyObject**tb) - - Under certain circumstances, the values returned by :c:func:`PyErr_Fetch` below - can be "unnormalized", meaning that ``*exc`` is a class object but ``*val`` is - not an instance of the same class. This function can be used to instantiate - the class in that case. If the values are already normalized, nothing happens. - The delayed normalization is implemented to improve performance. - - -.. c:function:: void PyErr_Clear() - - Clear the error indicator. If the error indicator is not set, there is no - effect. - - -.. c:function:: void PyErr_Fetch(PyObject **ptype, PyObject **pvalue, PyObject **ptraceback) - - Retrieve the error indicator into three variables whose addresses are passed. - If the error indicator is not set, set all three variables to *NULL*. If it is - set, it will be cleared and you own a reference to each object retrieved. The - value and traceback object may be *NULL* even when the type object is not. - - .. note:: - - This function is normally only used by code that needs to handle exceptions or - by code that needs to save and restore the error indicator temporarily. - - -.. c:function:: void PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback) - - Set the error indicator from the three objects. If the error indicator is - already set, it is cleared first. If the objects are *NULL*, the error - indicator is cleared. Do not pass a *NULL* type and non-*NULL* value or - traceback. The exception type should be a class. Do not pass an invalid - exception type or value. (Violating these rules will cause subtle problems - later.) This call takes away a reference to each object: you must own a - reference to each object before the call and after the call you no longer own - these references. (If you don't understand this, don't use this function. I - warned you.) - - .. note:: - - This function is normally only used by code that needs to save and restore the - error indicator temporarily; use :c:func:`PyErr_Fetch` to save the current - exception state. - - -.. c:function:: void PyErr_GetExcInfo(PyObject **ptype, PyObject **pvalue, PyObject **ptraceback) - - Retrieve the exception info, as known from ``sys.exc_info()``. This refers - to an exception that was already caught, not to an exception that was - freshly raised. Returns new references for the three objects, any of which - may be *NULL*. Does not modify the exception info state. - - .. note:: - - This function is not normally used by code that wants to handle exceptions. - Rather, it can be used when code needs to save and restore the exception - state temporarily. Use :c:func:`PyErr_SetExcInfo` to restore or clear the - exception state. - - .. versionadded:: 3.3 - +.. c:function:: void PyErr_WriteUnraisable(PyObject *obj) -.. c:function:: void PyErr_SetExcInfo(PyObject *type, PyObject *value, PyObject *traceback) + This utility function prints a warning message to ``sys.stderr`` when an + exception has been set but it is impossible for the interpreter to actually + raise the exception. It is used, for example, when an exception occurs in an + :meth:`__del__` method. - Set the exception info, as known from ``sys.exc_info()``. This refers - to an exception that was already caught, not to an exception that was - freshly raised. This function steals the references of the arguments. - To clear the exception state, pass *NULL* for all three arguments. - For general rules about the three arguments, see :c:func:`PyErr_Restore`. + The function is called with a single argument *obj* that identifies the context + in which the unraisable exception occurred. The repr of *obj* will be printed in + the warning message. - .. note:: - This function is not normally used by code that wants to handle exceptions. - Rather, it can be used when code needs to save and restore the exception - state temporarily. Use :c:func:`PyErr_GetExcInfo` to read the exception - state. +Raising exceptions +================== - .. versionadded:: 3.3 +These functions help you set the current thread's error indicator. +For convenience, some of these functions will always return a +NULL pointer for use in a ``return`` statement. .. c:function:: void PyErr_SetString(PyObject *type, const char *message) @@ -187,6 +109,14 @@ in various ways. There is a separate error indicator for each thread. string. +.. c:function:: PyObject* PyErr_FormatV(PyObject *exception, const char *format, va_list vargs) + + Same as :c:func:`PyErr_Format`, but taking a :c:type:`va_list` argument rather + than a variable number of arguments. + + .. versionadded:: 3.5 + + .. c:function:: void PyErr_SetNone(PyObject *type) This is a shorthand for ``PyErr_SetObject(type, Py_None)``. @@ -226,11 +156,20 @@ in various ways. There is a separate error indicator for each thread. Similar to :c:func:`PyErr_SetFromErrno`, with the additional behavior that if *filenameObject* is not *NULL*, it is passed to the constructor of *type* as - a third parameter. In the case of exceptions such as :exc:`IOError` and - :exc:`OSError`, this is used to define the :attr:`filename` attribute of the + a third parameter. In the case of :exc:`OSError` exception, + this is used to define the :attr:`filename` attribute of the exception instance. +.. c:function:: PyObject* PyErr_SetFromErrnoWithFilenameObjects(PyObject *type, PyObject *filenameObject, PyObject *filenameObject2) + + Similar to :c:func:`PyErr_SetFromErrnoWithFilenameObject`, but takes a second + filename object, for raising errors when a function that takes two filenames + fails. + + .. versionadded:: 3.4 + + .. c:function:: PyObject* PyErr_SetFromErrnoWithFilename(PyObject *type, const char *filename) Similar to :c:func:`PyErr_SetFromErrnoWithFilenameObject`, but the filename @@ -256,13 +195,6 @@ in various ways. There is a separate error indicator for each thread. specifying the exception type to be raised. Availability: Windows. -.. c:function:: PyObject* PyErr_SetFromWindowsErrWithFilenameObject(int ierr, PyObject *filenameObject) - - Similar to :c:func:`PyErr_SetFromWindowsErr`, with the additional behavior - that if *filenameObject* is not *NULL*, it is passed to the constructor of - :exc:`WindowsError` as a third parameter. Availability: Windows. - - .. c:function:: PyObject* PyErr_SetFromWindowsErrWithFilename(int ierr, const char *filename) Similar to :c:func:`PyErr_SetFromWindowsErrWithFilenameObject`, but the @@ -277,6 +209,15 @@ in various ways. There is a separate error indicator for each thread. Availability: Windows. +.. c:function:: PyObject* PyErr_SetExcFromWindowsErrWithFilenameObjects(PyObject *type, int ierr, PyObject *filename, PyObject *filename2) + + Similar to :c:func:`PyErr_SetExcFromWindowsErrWithFilenameObject`, + but accepts a second filename object. + Availability: Windows. + + .. versionadded:: 3.4 + + .. c:function:: PyObject* PyErr_SetExcFromWindowsErrWithFilename(PyObject *type, int ierr, const char *filename) Similar to :c:func:`PyErr_SetFromWindowsErrWithFilename`, with an additional @@ -300,7 +241,7 @@ in various ways. There is a separate error indicator for each thread. attributes, which make the exception printing subsystem think the exception is a :exc:`SyntaxError`. -.. versionadded:: 3.4 + .. versionadded:: 3.4 .. c:function:: void PyErr_SyntaxLocationEx(char *filename, int lineno, int col_offset) @@ -308,7 +249,7 @@ in various ways. There is a separate error indicator for each thread. Like :c:func:`PyErr_SyntaxLocationObject`, but *filename* is a byte string decoded from the filesystem encoding (:func:`os.fsdecode`). -.. versionadded:: 3.2 + .. versionadded:: 3.2 .. c:function:: void PyErr_SyntaxLocation(char *filename, int lineno) @@ -325,7 +266,23 @@ in various ways. There is a separate error indicator for each thread. use. -.. c:function:: int PyErr_WarnEx(PyObject *category, char *message, int stack_level) +Issuing warnings +================ + +Use these functions to issue warnings from C code. They mirror similar +functions exported by the Python :mod:`warnings` module. They normally +print a warning message to *sys.stderr*; however, it is +also possible that the user has specified that warnings are to be turned into +errors, and in that case they will raise an exception. It is also possible that +the functions raise an exception because of a problem with the warning machinery. +The return value is ``0`` if no exception is raised, or ``-1`` if an exception +is raised. (It is not possible to determine whether a warning message is +actually printed, nor what the reason is for the exception; this is +intentional.) If an exception is raised, the caller should do its normal +exception handling (for example, :c:func:`Py_DECREF` owned references and return +an error value). + +.. c:function:: int PyErr_WarnEx(PyObject *category, const char *message, Py_ssize_t stack_level) Issue a warning message. The *category* argument is a warning category (see below) or *NULL*; the *message* argument is an UTF-8 encoded string. *stack_level* is a @@ -334,18 +291,6 @@ in various ways. There is a separate error indicator for each thread. is the function calling :c:func:`PyErr_WarnEx`, 2 is the function above that, and so forth. - This function normally prints a warning message to *sys.stderr*; however, it is - also possible that the user has specified that warnings are to be turned into - errors, and in that case this will raise an exception. It is also possible that - the function raises an exception because of a problem with the warning machinery - (the implementation imports the :mod:`warnings` module to do the heavy lifting). - The return value is ``0`` if no exception is raised, or ``-1`` if an exception - is raised. (It is not possible to determine whether a warning message is - actually printed, nor what the reason is for the exception; this is - intentional.) If an exception is raised, the caller should do its normal - exception handling (for example, :c:func:`Py_DECREF` owned references and return - an error value). - Warning categories must be subclasses of :c:data:`Warning`; the default warning category is :c:data:`RuntimeWarning`. The standard Python warning categories are available as global variables whose names are ``PyExc_`` followed by the Python @@ -389,6 +334,139 @@ in various ways. There is a separate error indicator for each thread. .. versionadded:: 3.2 +Querying the error indicator +============================ + +.. c:function:: PyObject* PyErr_Occurred() + + Test whether the error indicator is set. If set, return the exception *type* + (the first argument to the last call to one of the :c:func:`PyErr_Set\*` + functions or to :c:func:`PyErr_Restore`). If not set, return *NULL*. You do not + own a reference to the return value, so you do not need to :c:func:`Py_DECREF` + it. + + .. note:: + + Do not compare the return value to a specific exception; use + :c:func:`PyErr_ExceptionMatches` instead, shown below. (The comparison could + easily fail since the exception may be an instance instead of a class, in the + case of a class exception, or it may be a subclass of the expected exception.) + + +.. c:function:: int PyErr_ExceptionMatches(PyObject *exc) + + Equivalent to ``PyErr_GivenExceptionMatches(PyErr_Occurred(), exc)``. This + should only be called when an exception is actually set; a memory access + violation will occur if no exception has been raised. + + +.. c:function:: int PyErr_GivenExceptionMatches(PyObject *given, PyObject *exc) + + Return true if the *given* exception matches the exception type in *exc*. If + *exc* is a class object, this also returns true when *given* is an instance + of a subclass. If *exc* is a tuple, all exception types in the tuple (and + recursively in subtuples) are searched for a match. + + +.. c:function:: void PyErr_Fetch(PyObject **ptype, PyObject **pvalue, PyObject **ptraceback) + + Retrieve the error indicator into three variables whose addresses are passed. + If the error indicator is not set, set all three variables to *NULL*. If it is + set, it will be cleared and you own a reference to each object retrieved. The + value and traceback object may be *NULL* even when the type object is not. + + .. note:: + + This function is normally only used by code that needs to catch exceptions or + by code that needs to save and restore the error indicator temporarily, e.g.:: + + { + PyObject **type, **value, **traceback; + PyErr_Fetch(&type, &value, &traceback); + + /* ... code that might produce other errors ... */ + + PyErr_Restore(type, value, traceback); + } + + +.. c:function:: void PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback) + + Set the error indicator from the three objects. If the error indicator is + already set, it is cleared first. If the objects are *NULL*, the error + indicator is cleared. Do not pass a *NULL* type and non-*NULL* value or + traceback. The exception type should be a class. Do not pass an invalid + exception type or value. (Violating these rules will cause subtle problems + later.) This call takes away a reference to each object: you must own a + reference to each object before the call and after the call you no longer own + these references. (If you don't understand this, don't use this function. I + warned you.) + + .. note:: + + This function is normally only used by code that needs to save and restore the + error indicator temporarily. Use :c:func:`PyErr_Fetch` to save the current + error indicator. + + +.. c:function:: void PyErr_NormalizeException(PyObject**exc, PyObject**val, PyObject**tb) + + Under certain circumstances, the values returned by :c:func:`PyErr_Fetch` below + can be "unnormalized", meaning that ``*exc`` is a class object but ``*val`` is + not an instance of the same class. This function can be used to instantiate + the class in that case. If the values are already normalized, nothing happens. + The delayed normalization is implemented to improve performance. + + .. note:: + + This function *does not* implicitly set the ``__traceback__`` + attribute on the exception value. If setting the traceback + appropriately is desired, the following additional snippet is needed:: + + if (tb != NULL) { + PyException_SetTraceback(val, tb); + } + + +.. c:function:: void PyErr_GetExcInfo(PyObject **ptype, PyObject **pvalue, PyObject **ptraceback) + + Retrieve the exception info, as known from ``sys.exc_info()``. This refers + to an exception that was *already caught*, not to an exception that was + freshly raised. Returns new references for the three objects, any of which + may be *NULL*. Does not modify the exception info state. + + .. note:: + + This function is not normally used by code that wants to handle exceptions. + Rather, it can be used when code needs to save and restore the exception + state temporarily. Use :c:func:`PyErr_SetExcInfo` to restore or clear the + exception state. + + .. versionadded:: 3.3 + + +.. c:function:: void PyErr_SetExcInfo(PyObject *type, PyObject *value, PyObject *traceback) + + Set the exception info, as known from ``sys.exc_info()``. This refers + to an exception that was *already caught*, not to an exception that was + freshly raised. This function steals the references of the arguments. + To clear the exception state, pass *NULL* for all three arguments. + For general rules about the three arguments, see :c:func:`PyErr_Restore`. + + .. note:: + + This function is not normally used by code that wants to handle exceptions. + Rather, it can be used when code needs to save and restore the exception + state temporarily. Use :c:func:`PyErr_GetExcInfo` to read the exception + state. + + .. versionadded:: 3.3 + + +Signal Handling +=============== + + .. c:function:: int PyErr_CheckSignals() .. index:: @@ -422,13 +500,21 @@ in various ways. There is a separate error indicator for each thread. .. c:function:: int PySignal_SetWakeupFd(int fd) - This utility function specifies a file descriptor to which a ``'\0'`` byte will - be written whenever a signal is received. It returns the previous such file - descriptor. The value ``-1`` disables the feature; this is the initial state. + This utility function specifies a file descriptor to which the signal number + is written as a single byte whenever a signal is received. *fd* must be + non-blocking. It returns the previous such file descriptor. + + The value ``-1`` disables the feature; this is the initial state. This is equivalent to :func:`signal.set_wakeup_fd` in Python, but without any error checking. *fd* should be a valid file descriptor. The function should only be called from the main thread. + .. versionchanged:: 3.5 + On Windows, the function now also supports socket handles. + + +Exception Classes +================= .. c:function:: PyObject* PyErr_NewException(char *name, PyObject *base, PyObject *dict) @@ -454,18 +540,6 @@ in various ways. There is a separate error indicator for each thread. .. versionadded:: 3.2 -.. c:function:: void PyErr_WriteUnraisable(PyObject *obj) - - This utility function prints a warning message to ``sys.stderr`` when an - exception has been set but it is impossible for the interpreter to actually - raise the exception. It is used, for example, when an exception occurs in an - :meth:`__del__` method. - - The function is called with a single argument *obj* that identifies the context - in which the unraisable exception occurred. The repr of *obj* will be printed in - the warning message. - - Exception Objects ================= @@ -504,11 +578,11 @@ Exception Objects reference, as accessible from Python through :attr:`__cause__`. -.. c:function:: void PyException_SetCause(PyObject *ex, PyObject *ctx) +.. c:function:: void PyException_SetCause(PyObject *ex, PyObject *cause) - Set the cause associated with the exception to *ctx*. Use *NULL* to clear - it. There is no type check to make sure that *ctx* is either an exception - instance or :const:`None`. This steals a reference to *ctx*. + Set the cause associated with the exception to *cause*. Use *NULL* to clear + it. There is no type check to make sure that *cause* is either an exception + instance or :const:`None`. This steals a reference to *cause*. :attr:`__suppress_context__` is implicitly set to ``True`` by this function. diff --git a/Doc/c-api/import.rst b/Doc/c-api/import.rst index 6cd2b8bea0e1..3641fc69b1ad 100644 --- a/Doc/c-api/import.rst +++ b/Doc/c-api/import.rst @@ -132,8 +132,14 @@ Importing Modules such modules have no way to know that the module object is an unknown (and probably damaged with respect to the module author's intents) state. + The module's :attr:`__spec__` and :attr:`__loader__` will be set, if + not set already, with the appropriate values. The spec's loader will + be set to the module's ``__loader__`` (if set) and to an instance of + :class:`SourceFileLoader` otherwise. + The module's :attr:`__file__` attribute will be set to the code object's - :c:member:`co_filename`. + :c:member:`co_filename`. If applicable, :attr:`__cached__` will also + be set. This function will reload the module if it was already imported. See :c:func:`PyImport_ReloadModule` for the intended way to reload a module. @@ -245,6 +251,9 @@ Importing Modules .. versionadded:: 3.3 + .. versionchanged:: 3.4 + The ``__file__`` attribute is no longer set on the module. + .. c:function:: int PyImport_ImportFrozenModule(const char *name) diff --git a/Doc/c-api/init.rst b/Doc/c-api/init.rst index 6439d7f11de3..fac9b478cfe5 100644 --- a/Doc/c-api/init.rst +++ b/Doc/c-api/init.rst @@ -134,6 +134,9 @@ Process-wide parameters change for the duration of the program's execution. No code in the Python interpreter will change the contents of this storage. + Use :c:func:`Py_DecodeLocale` to decode a bytes string to get a + :c:type:`wchar_*` string. + .. c:function:: wchar* Py_GetProgramName() @@ -236,13 +239,21 @@ Process-wide parameters :c:func:`Py_Initialize`, then :c:func:`Py_GetPath` won't attempt to compute a default search path but uses the one provided instead. This is useful if Python is embedded by an application that has full knowledge of the location - of all modules. The path components should be separated by semicolons. + of all modules. The path components should be separated by the platform + dependent delimiter character, which is ``':'`` on Unix and Mac OS X, ``';'`` + on Windows. This also causes :data:`sys.executable` to be set only to the raw program name (see :c:func:`Py_SetProgramName`) and for :data:`sys.prefix` and :data:`sys.exec_prefix` to be empty. It is up to the caller to modify these if required after calling :c:func:`Py_Initialize`. + Use :c:func:`Py_DecodeLocale` to decode a bytes string to get a + :c:type:`wchar_*` string. + + The path argument is copied internally, so the caller may free it after the + call completes. + .. c:function:: const char* Py_GetVersion() @@ -339,6 +350,9 @@ Process-wide parameters :data:`sys.path`, which is the same as prepending the current working directory (``"."``). + Use :c:func:`Py_DecodeLocale` to decode a bytes string to get a + :c:type:`wchar_*` string. + .. note:: It is recommended that applications embedding the Python interpreter for purposes other than executing a single script pass 0 as *updatepath*, @@ -363,6 +377,9 @@ Process-wide parameters to 1 unless the :program:`python` interpreter was started with the :option:`-I`. + Use :c:func:`Py_DecodeLocale` to decode a bytes string to get a + :c:type:`wchar_*` string. + .. versionchanged:: 3.4 The *updatepath* value depends on :option:`-I`. @@ -377,6 +394,9 @@ Process-wide parameters execution. No code in the Python interpreter will change the contents of this storage. + Use :c:func:`Py_DecodeLocale` to decode a bytes string to get a + :c:type:`wchar_*` string. + .. c:function:: w_char* Py_GetPythonHome() @@ -582,6 +602,7 @@ code, or when embedding the Python interpreter: .. index:: module: _thread .. note:: + When only the main thread exists, no GIL operations are needed. This is a common situation (most Python programs do not use threads), and the lock operations slow the interpreter down a bit. Therefore, the lock is not @@ -1176,7 +1197,7 @@ These functions are only intended to be used by advanced debugging tools. .. c:function:: PyThreadState * PyInterpreterState_ThreadHead(PyInterpreterState *interp) - Return the a pointer to the first :c:type:`PyThreadState` object in the list of + Return the pointer to the first :c:type:`PyThreadState` object in the list of threads associated with the interpreter *interp*. diff --git a/Doc/c-api/memory.rst b/Doc/c-api/memory.rst index a82e1c2f2c50..5d78f385ee09 100644 --- a/Doc/c-api/memory.rst +++ b/Doc/c-api/memory.rst @@ -92,8 +92,8 @@ functions are thread-safe, the :term:`GIL ` does not need to be held. The default raw memory block allocator uses the following functions: -:c:func:`malloc`, :c:func:`realloc` and :c:func:`free`; call ``malloc(1)`` when -requesting zero bytes. +:c:func:`malloc`, :c:func:`calloc`, :c:func:`realloc` and :c:func:`free`; call +``malloc(1)`` (or ``calloc(1, 1)``) when requesting zero bytes. .. versionadded:: 3.4 @@ -106,6 +106,17 @@ requesting zero bytes. been initialized in any way. +.. c:function:: void* PyMem_RawCalloc(size_t nelem, size_t elsize) + + Allocates *nelem* elements each whose size in bytes is *elsize* and returns + a pointer of type :c:type:`void\*` to the allocated memory, or *NULL* if the + request fails. The memory is initialized to zeros. Requesting zero elements + or elements of size zero bytes returns a distinct non-*NULL* pointer if + possible, as if ``PyMem_RawCalloc(1, 1)`` had been called instead. + + .. versionadded:: 3.5 + + .. c:function:: void* PyMem_RawRealloc(void *p, size_t n) Resizes the memory block pointed to by *p* to *n* bytes. The contents will @@ -136,8 +147,8 @@ behavior when requesting zero bytes, are available for allocating and releasing memory from the Python heap. The default memory block allocator uses the following functions: -:c:func:`malloc`, :c:func:`realloc` and :c:func:`free`; call ``malloc(1)`` when -requesting zero bytes. +:c:func:`malloc`, :c:func:`calloc`, :c:func:`realloc` and :c:func:`free`; call +``malloc(1)`` (or ``calloc(1, 1)``) when requesting zero bytes. .. warning:: @@ -152,6 +163,17 @@ requesting zero bytes. been called instead. The memory will not have been initialized in any way. +.. c:function:: void* PyMem_Calloc(size_t nelem, size_t elsize) + + Allocates *nelem* elements each whose size in bytes is *elsize* and returns + a pointer of type :c:type:`void\*` to the allocated memory, or *NULL* if the + request fails. The memory is initialized to zeros. Requesting zero elements + or elements of size zero bytes returns a distinct non-*NULL* pointer if + possible, as if ``PyMem_Calloc(1, 1)`` had been called instead. + + .. versionadded:: 3.5 + + .. c:function:: void* PyMem_Realloc(void *p, size_t n) Resizes the memory block pointed to by *p* to *n* bytes. The contents will be @@ -210,7 +232,7 @@ Customize Memory Allocators .. versionadded:: 3.4 -.. c:type:: PyMemAllocator +.. c:type:: PyMemAllocatorEx Structure used to describe a memory block allocator. The structure has four fields: @@ -222,11 +244,19 @@ Customize Memory Allocators +----------------------------------------------------------+---------------------------------------+ | ``void* malloc(void *ctx, size_t size)`` | allocate a memory block | +----------------------------------------------------------+---------------------------------------+ + | ``void* calloc(void *ctx, size_t nelem, size_t elsize)`` | allocate a memory block initialized | + | | with zeros | + +----------------------------------------------------------+---------------------------------------+ | ``void* realloc(void *ctx, void *ptr, size_t new_size)`` | allocate or resize a memory block | +----------------------------------------------------------+---------------------------------------+ | ``void free(void *ctx, void *ptr)`` | free a memory block | +----------------------------------------------------------+---------------------------------------+ + .. versionchanged:: 3.5 + The :c:type:`PyMemAllocator` structure was renamed to + :c:type:`PyMemAllocatorEx` and a new ``calloc`` field was added. + + .. c:type:: PyMemAllocatorDomain Enum used to identify an allocator domain. Domains: @@ -239,12 +269,12 @@ Customize Memory Allocators :c:func:`PyObject_Realloc` and :c:func:`PyObject_Free` -.. c:function:: void PyMem_GetAllocator(PyMemAllocatorDomain domain, PyMemAllocator *allocator) +.. c:function:: void PyMem_GetAllocator(PyMemAllocatorDomain domain, PyMemAllocatorEx *allocator) Get the memory block allocator of the specified domain. -.. c:function:: void PyMem_SetAllocator(PyMemAllocatorDomain domain, PyMemAllocator *allocator) +.. c:function:: void PyMem_SetAllocator(PyMemAllocatorDomain domain, PyMemAllocatorEx *allocator) Set the memory block allocator of the specified domain. diff --git a/Doc/c-api/module.rst b/Doc/c-api/module.rst index 26c4384f856a..985a347d63d2 100644 --- a/Doc/c-api/module.rst +++ b/Doc/c-api/module.rst @@ -120,7 +120,7 @@ There are only a few functions special to module objects. Return a pointer to the :c:type:`PyModuleDef` struct from which the module was created, or *NULL* if the module wasn't created with - :c:func:`PyModule_Create`.i + :c:func:`PyModule_Create`. .. c:function:: PyObject* PyState_FindModule(PyModuleDef *def) diff --git a/Doc/c-api/number.rst b/Doc/c-api/number.rst index 21951c38c0df..9bcb649c9d57 100644 --- a/Doc/c-api/number.rst +++ b/Doc/c-api/number.rst @@ -30,6 +30,14 @@ Number Protocol the equivalent of the Python expression ``o1 * o2``. +.. c:function:: PyObject* PyNumber_MatrixMultiply(PyObject *o1, PyObject *o2) + + Returns the result of matrix multiplication on *o1* and *o2*, or *NULL* on + failure. This is the equivalent of the Python expression ``o1 @ o2``. + + .. versionadded:: 3.5 + + .. c:function:: PyObject* PyNumber_FloorDivide(PyObject *o1, PyObject *o2) Return the floor of *o1* divided by *o2*, or *NULL* on failure. This is @@ -146,6 +154,15 @@ Number Protocol the Python statement ``o1 *= o2``. +.. c:function:: PyObject* PyNumber_InPlaceMatrixMultiply(PyObject *o1, PyObject *o2) + + Returns the result of matrix multiplication on *o1* and *o2*, or *NULL* on + failure. The operation is done *in-place* when *o1* supports it. This is + the equivalent of the Python statement ``o1 @= o2``. + + .. versionadded:: 3.5 + + .. c:function:: PyObject* PyNumber_InPlaceFloorDivide(PyObject *o1, PyObject *o2) Returns the mathematical floor of dividing *o1* by *o2*, or *NULL* on failure. diff --git a/Doc/c-api/object.rst b/Doc/c-api/object.rst index be6d798f631e..187ac017a786 100644 --- a/Doc/c-api/object.rst +++ b/Doc/c-api/object.rst @@ -101,7 +101,7 @@ Object Protocol This is the equivalent of the Python statement ``del o.attr_name``. -.. c:function:: PyObject* PyType_GenericGetDict(PyObject *o, void *context) +.. c:function:: PyObject* PyObject_GenericGetDict(PyObject *o, void *context) A generic implementation for the getter of a ``__dict__`` descriptor. It creates the dictionary if necessary. @@ -109,7 +109,7 @@ Object Protocol .. versionadded:: 3.3 -.. c:function:: int PyType_GenericSetDict(PyObject *o, void *context) +.. c:function:: int PyObject_GenericSetDict(PyObject *o, void *context) A generic implementation for the setter of a ``__dict__`` descriptor. This implementation does not allow the dictionary to be deleted. @@ -149,6 +149,9 @@ Object Protocol representation on success, *NULL* on failure. This is the equivalent of the Python expression ``repr(o)``. Called by the :func:`repr` built-in function. + .. versionchanged:: 3.4 + This function now includes a debug assertion to help ensure that it + does not silently discard an active exception. .. c:function:: PyObject* PyObject_ASCII(PyObject *o) @@ -170,6 +173,10 @@ Object Protocol Python expression ``str(o)``. Called by the :func:`str` built-in function and, therefore, by the :func:`print` function. + .. versionchanged:: 3.4 + This function now includes a debug assertion to help ensure that it + does not silently discard an active exception. + .. c:function:: PyObject* PyObject_Bytes(PyObject *o) .. index:: builtin: bytes @@ -180,40 +187,45 @@ Object Protocol a TypeError is raised when *o* is an integer instead of a zero-initialized bytes object. + +.. c:function:: int PyObject_IsSubclass(PyObject *derived, PyObject *cls) + + Return ``1`` if the class *derived* is identical to or derived from the class + *cls*, otherwise return ``0``. In case of an error, return ``-1``. + + If *cls* is a tuple, the check will be done against every entry in *cls*. + The result will be ``1`` when at least one of the checks returns ``1``, + otherwise it will be ``0``. + + If *cls* has a :meth:`~class.__subclasscheck__` method, it will be called to + determine the subclass status as described in :pep:`3119`. Otherwise, + *derived* is a subclass of *cls* if it is a direct or indirect subclass, + i.e. contained in ``cls.__mro__``. + + Normally only class objects, i.e. instances of :class:`type` or a derived + class, are considered classes. However, objects can override this by haivng + a :attr:`__bases__` attribute (which must be a tuple of base classes). + + .. c:function:: int PyObject_IsInstance(PyObject *inst, PyObject *cls) - Returns ``1`` if *inst* is an instance of the class *cls* or a subclass of - *cls*, or ``0`` if not. On error, returns ``-1`` and sets an exception. If - *cls* is a type object rather than a class object, :c:func:`PyObject_IsInstance` - returns ``1`` if *inst* is of type *cls*. If *cls* is a tuple, the check will - be done against every entry in *cls*. The result will be ``1`` when at least one - of the checks returns ``1``, otherwise it will be ``0``. If *inst* is not a - class instance and *cls* is neither a type object, nor a class object, nor a - tuple, *inst* must have a :attr:`~instance.__class__` attribute --- the - class relationship of the value of that attribute with *cls* will be used - to determine the result of this function. - - -Subclass determination is done in a fairly straightforward way, but includes a -wrinkle that implementors of extensions to the class system may want to be aware -of. If :class:`A` and :class:`B` are class objects, :class:`B` is a subclass of -:class:`A` if it inherits from :class:`A` either directly or indirectly. If -either is not a class object, a more general mechanism is used to determine the -class relationship of the two objects. When testing if *B* is a subclass of -*A*, if *A* is *B*, :c:func:`PyObject_IsSubclass` returns true. If *A* and *B* -are different objects, *B*'s :attr:`~class.__bases__` attribute is searched in -a depth-first fashion for *A* --- the presence of the :attr:`~class.__bases__` -attribute is considered sufficient for this determination. + Return ``1`` if *inst* is an instance of the class *cls* or a subclass of + *cls*, or ``0`` if not. On error, returns ``-1`` and sets an exception. + If *cls* is a tuple, the check will be done against every entry in *cls*. + The result will be ``1`` when at least one of the checks returns ``1``, + otherwise it will be ``0``. -.. c:function:: int PyObject_IsSubclass(PyObject *derived, PyObject *cls) + If *cls* has a :meth:`~class.__instancecheck__` method, it will be called to + determine the subclass status as described in :pep:`3119`. Otherwise, *inst* + is an instance of *cls* if its class is a subclass of *cls*. + + An instance *inst* can override what is considered its class by having a + :attr:`__class__` attribute. - Returns ``1`` if the class *derived* is identical to or derived from the class - *cls*, otherwise returns ``0``. In case of an error, returns ``-1``. If *cls* - is a tuple, the check will be done against every entry in *cls*. The result will - be ``1`` when at least one of the checks returns ``1``, otherwise it will be - ``0``. If either *derived* or *cls* is not an actual class object (or tuple), - this function uses the generic algorithm described above. + An object *cls* can override if it is considered a class, and what its base + classes are, by having a :attr:`__bases__` attribute (which must be a tuple + of base classes). .. c:function:: int PyCallable_Check(PyObject *o) @@ -350,13 +362,14 @@ attribute is considered sufficient for this determination. .. c:function:: Py_ssize_t PyObject_LengthHint(PyObject *o, Py_ssize_t default) - Return an estimated length for the object *o*. First trying to return its - actual length, then an estimate using ``__length_hint__``, and finally - returning the default value. On error ``-1`` is returned. This is the + Return an estimated length for the object *o*. First try to return its + actual length, then an estimate using :meth:`~object.__length_hint__`, and + finally return the default value. On error return ``-1``. This is the equivalent to the Python expression ``operator.length_hint(o, default)``. .. versionadded:: 3.4 + .. c:function:: PyObject* PyObject_GetItem(PyObject *o, PyObject *key) Return element of *o* corresponding to the object *key* or *NULL* on failure. diff --git a/Doc/c-api/sequence.rst b/Doc/c-api/sequence.rst index 0297ba3588b0..cf1e1420e0bb 100644 --- a/Doc/c-api/sequence.rst +++ b/Doc/c-api/sequence.rst @@ -123,10 +123,10 @@ Sequence Protocol .. c:function:: PyObject* PySequence_Fast(PyObject *o, const char *m) - Returns the sequence *o* as a tuple, unless it is already a tuple or list, in - which case *o* is returned. Use :c:func:`PySequence_Fast_GET_ITEM` to access the - members of the result. Returns *NULL* on failure. If the object is not a - sequence, raises :exc:`TypeError` with *m* as the message text. + Return the sequence *o* as a list, unless it is already a tuple or list, in + which case *o* is returned. Use :c:func:`PySequence_Fast_GET_ITEM` to access + the members of the result. Returns *NULL* on failure. If the object is not + a sequence, raises :exc:`TypeError` with *m* as the message text. .. c:function:: PyObject* PySequence_Fast_GET_ITEM(PyObject *o, Py_ssize_t i) diff --git a/Doc/c-api/structures.rst b/Doc/c-api/structures.rst index bb741fb099ea..66a3443b2d40 100644 --- a/Doc/c-api/structures.rst +++ b/Doc/c-api/structures.rst @@ -131,7 +131,7 @@ The :attr:`ml_meth` is a C function pointer. The functions may be of different types, but they always return :c:type:`PyObject\*`. If the function is not of the :c:type:`PyCFunction`, the compiler will require a cast in the method table. Even though :c:type:`PyCFunction` defines the first parameter as -:c:type:`PyObject\*`, it is common that the method implementation uses a the +:c:type:`PyObject\*`, it is common that the method implementation uses the specific C type of the *self* object. The :attr:`ml_flags` field is a bitfield which can include the following flags. diff --git a/Doc/c-api/sys.rst b/Doc/c-api/sys.rst index 9760dca2df1e..a6a939ccc29f 100644 --- a/Doc/c-api/sys.rst +++ b/Doc/c-api/sys.rst @@ -47,6 +47,60 @@ Operating System Utilities not call those functions directly! :c:type:`PyOS_sighandler_t` is a typedef alias for :c:type:`void (\*)(int)`. +.. c:function:: wchar_t* Py_DecodeLocale(const char* arg, size_t *size) + + Decode a byte string from the locale encoding with the :ref:`surrogateescape + error handler `: undecodable bytes are decoded as + characters in range U+DC80..U+DCFF. If a byte sequence can be decoded as a + surrogate character, escape the bytes using the surrogateescape error + handler instead of decoding them. + + Return a pointer to a newly allocated wide character string, use + :c:func:`PyMem_RawFree` to free the memory. If size is not ``NULL``, write + the number of wide characters excluding the null character into ``*size`` + + Return ``NULL`` on decoding error or memory allocation error. If *size* is + not ``NULL``, ``*size`` is set to ``(size_t)-1`` on memory error or set to + ``(size_t)-2`` on decoding error. + + Decoding errors should never happen, unless there is a bug in the C + library. + + Use the :c:func:`Py_EncodeLocale` function to encode the character string + back to a byte string. + + .. seealso:: + + The :c:func:`PyUnicode_DecodeFSDefaultAndSize` and + :c:func:`PyUnicode_DecodeLocaleAndSize` functions. + + .. versionadded:: 3.5 + + +.. c:function:: char* Py_EncodeLocale(const wchar_t *text, size_t *error_pos) + + Encode a wide character string to the locale encoding with the + :ref:`surrogateescape error handler `: surrogate characters + in the range U+DC80..U+DCFF are converted to bytes 0x80..0xFF. + + Return a pointer to a newly allocated byte string, use :c:func:`PyMem_Free` + to free the memory. Return ``NULL`` on encoding error or memory allocation + error + + If error_pos is not ``NULL``, ``*error_pos`` is set to the index of the + invalid character on encoding error, or set to ``(size_t)-1`` otherwise. + + Use the :c:func:`Py_DecodeLocale` function to decode the bytes string back + to a wide character string. + + .. seealso:: + + The :c:func:`PyUnicode_EncodeFSDefault` and + :c:func:`PyUnicode_EncodeLocale` functions. + + .. versionadded:: 3.5 + + .. _systemfunctions: System Functions diff --git a/Doc/c-api/tuple.rst b/Doc/c-api/tuple.rst index 184affb2224f..3922d50f80a2 100644 --- a/Doc/c-api/tuple.rst +++ b/Doc/c-api/tuple.rst @@ -129,6 +129,14 @@ type. Initializes a struct sequence type *type* from *desc* in place. +.. c:function:: int PyStructSequence_InitType2(PyTypeObject *type, PyStructSequence_Desc *desc) + + The same as ``PyStructSequence_InitType``, but returns ``0`` on success and ``-1`` on + failure. + + .. versionadded:: 3.4 + + .. c:type:: PyStructSequence_Desc Contains the meta information of a struct sequence type to create. diff --git a/Doc/c-api/type.rst b/Doc/c-api/type.rst index 5d832541f20c..60c5e73960b3 100644 --- a/Doc/c-api/type.rst +++ b/Doc/c-api/type.rst @@ -44,6 +44,7 @@ Type Objects .. versionadded:: 3.2 + .. c:function:: void PyType_Modified(PyTypeObject *type) Invalidate the internal lookup cache for the type and all of its @@ -67,6 +68,11 @@ Type Objects Return true if *a* is a subtype of *b*. + This function only checks for actual subtypes, which means that + :meth:`~class.__subclasscheck__` is not called on *b*. Call + :c:func:`PyObject_IsSubclass` to do the same check that :func:`issubclass` + would do. + .. c:function:: PyObject* PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems) @@ -97,3 +103,13 @@ Type Objects types. This allows the caller to reference other heap types as base types. .. versionadded:: 3.3 + +.. c:function:: void* PyType_GetSlot(PyTypeObject *type, int slot) + + Return the function pointer stored in the given slot. If the + result is *NULL*, this indicates that either the slot is *NULL*, + or that the function was called with invalid parameters. + Callers will typically cast the result pointer into the appropriate + function type. + + .. versionadded:: 3.4 diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index 48b13e57aeb1..eb637051c6f9 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -189,31 +189,7 @@ type objects) *must* have the :attr:`ob_size` field. .. c:member:: printfunc PyTypeObject.tp_print - An optional pointer to the instance print function. - - The print function is only called when the instance is printed to a *real* file; - when it is printed to a pseudo-file (like a :class:`io.StringIO` instance), the - instance's :c:member:`~PyTypeObject.tp_repr` or :c:member:`~PyTypeObject.tp_str` function is called to convert it to - a string. These are also called when the type's :c:member:`~PyTypeObject.tp_print` field is - *NULL*. A type should never implement :c:member:`~PyTypeObject.tp_print` in a way that produces - different output than :c:member:`~PyTypeObject.tp_repr` or :c:member:`~PyTypeObject.tp_str` would. - - The print function is called with the same signature as :c:func:`PyObject_Print`: - ``int tp_print(PyObject *self, FILE *file, int flags)``. The *self* argument is - the instance to be printed. The *file* argument is the stdio file to which it - is to be printed. The *flags* argument is composed of flag bits. The only flag - bit currently defined is :const:`Py_PRINT_RAW`. When the :const:`Py_PRINT_RAW` - flag bit is set, the instance should be printed the same way as :c:member:`~PyTypeObject.tp_str` - would format it; when the :const:`Py_PRINT_RAW` flag bit is clear, the instance - should be printed the same was as :c:member:`~PyTypeObject.tp_repr` would format it. It should - return ``-1`` and set an exception condition when an error occurred during the - comparison. - - It is possible that the :c:member:`~PyTypeObject.tp_print` field will be deprecated. In any case, - it is recommended not to define :c:member:`~PyTypeObject.tp_print`, but instead to rely on - :c:member:`~PyTypeObject.tp_repr` and :c:member:`~PyTypeObject.tp_str` for printing. - - This field is inherited by subtypes. + Reserved slot, formerly used for print formatting in Python 2.x. .. c:member:: getattrfunc PyTypeObject.tp_getattr @@ -465,6 +441,24 @@ type objects) *must* have the :attr:`ob_size` field. :const:`Py_TPFLAGS_HAVE_VERSION_TAG`. + .. data:: Py_TPFLAGS_LONG_SUBCLASS + .. data:: Py_TPFLAGS_LIST_SUBCLASS + .. data:: Py_TPFLAGS_TUPLE_SUBCLASS + .. data:: Py_TPFLAGS_BYTES_SUBCLASS + .. data:: Py_TPFLAGS_UNICODE_SUBCLASS + .. data:: Py_TPFLAGS_DICT_SUBCLASS + .. data:: Py_TPFLAGS_BASE_EXC_SUBCLASS + .. data:: Py_TPFLAGS_TYPE_SUBCLASS + + These flags are used by functions such as + :c:func:`PyLong_Check` to quickly determine if a type is a subclass + of a built-in type; such specific checks are faster than a generic + check, like :c:func:`PyObject_IsInstance`. Custom types that inherit + from built-ins should have their :c:member:`~PyTypeObject.tp_flags` + set appropriately, or the code that interacts with such types + will behave differently depending on what kind of check is used. + + .. data:: Py_TPFLAGS_HAVE_FINALIZE This bit is set when the :c:member:`~PyTypeObject.tp_finalize` slot is present in the @@ -580,7 +574,9 @@ type objects) *must* have the :attr:`ob_size` field. .. c:member:: richcmpfunc PyTypeObject.tp_richcompare An optional pointer to the rich comparison function, whose signature is - ``PyObject *tp_richcompare(PyObject *a, PyObject *b, int op)``. + ``PyObject *tp_richcompare(PyObject *a, PyObject *b, int op)``. The first + parameter is guaranteed to be an instance of the type that is defined + by :c:type:`PyTypeObject`. The function should return the result of the comparison (usually ``Py_True`` or ``Py_False``). If the comparison is undefined, it must return @@ -1122,6 +1118,9 @@ Number Object Structures binaryfunc nb_inplace_true_divide; unaryfunc nb_index; + + binaryfunc nb_matrix_multiply; + binaryfunc nb_inplace_matrix_multiply; } PyNumberMethods; .. note:: @@ -1200,7 +1199,8 @@ Sequence Object Structures This function is used by :c:func:`PySequence_Repeat` and has the same signature. It is also used by the ``*`` operator, after trying numeric - multiplication via the :c:member:`~PyTypeObject.tp_as_number.nb_mul` slot. + multiplication via the :c:member:`~PyTypeObject.tp_as_number.nb_multiply` + slot. .. c:member:: ssizeargfunc PySequenceMethods.sq_item diff --git a/Doc/c-api/unicode.rst b/Doc/c-api/unicode.rst index c7ed5e598793..00063d0b5e98 100644 --- a/Doc/c-api/unicode.rst +++ b/Doc/c-api/unicode.rst @@ -556,7 +556,8 @@ APIs: Coerce an encoded object *obj* to an Unicode object and return a reference with incremented refcount. - :class:`bytes`, :class:`bytearray` and other char buffer compatible objects + :class:`bytes`, :class:`bytearray` and other + :term:`bytes-like objects ` are decoded according to the given *encoding* and using the error handling defined by *errors*. Both can be *NULL* to have the interface use the default values (see the next section for details). @@ -758,11 +759,13 @@ system. *errors* is ``NULL``. *str* must end with a null character but cannot contain embedded null characters. + Use :c:func:`PyUnicode_DecodeFSDefaultAndSize` to decode a string from + :c:data:`Py_FileSystemDefaultEncoding` (the locale encoding read at + Python startup). + .. seealso:: - Use :c:func:`PyUnicode_DecodeFSDefaultAndSize` to decode a string from - :c:data:`Py_FileSystemDefaultEncoding` (the locale encoding read at - Python startup). + The :c:func:`Py_DecodeLocale` function. .. versionadded:: 3.3 @@ -783,11 +786,13 @@ system. *errors* is ``NULL``. Return a :class:`bytes` object. *str* cannot contain embedded null characters. + Use :c:func:`PyUnicode_EncodeFSDefault` to encode a string to + :c:data:`Py_FileSystemDefaultEncoding` (the locale encoding read at + Python startup). + .. seealso:: - Use :c:func:`PyUnicode_EncodeFSDefault` to encode a string to - :c:data:`Py_FileSystemDefaultEncoding` (the locale encoding read at - Python startup). + The :c:func:`Py_EncodeLocale` function. .. versionadded:: 3.3 @@ -832,12 +837,14 @@ used, passing :c:func:`PyUnicode_FSDecoder` as the conversion function: If :c:data:`Py_FileSystemDefaultEncoding` is not set, fall back to the locale encoding. + :c:data:`Py_FileSystemDefaultEncoding` is initialized at startup from the + locale encoding and cannot be modified later. If you need to decode a string + from the current locale encoding, use + :c:func:`PyUnicode_DecodeLocaleAndSize`. + .. seealso:: - :c:data:`Py_FileSystemDefaultEncoding` is initialized at startup from the - locale encoding and cannot be modified later. If you need to decode a - string from the current locale encoding, use - :c:func:`PyUnicode_DecodeLocaleAndSize`. + The :c:func:`Py_DecodeLocale` function. .. versionchanged:: 3.2 Use ``"strict"`` error handler on Windows. @@ -867,12 +874,13 @@ used, passing :c:func:`PyUnicode_FSDecoder` as the conversion function: If :c:data:`Py_FileSystemDefaultEncoding` is not set, fall back to the locale encoding. + :c:data:`Py_FileSystemDefaultEncoding` is initialized at startup from the + locale encoding and cannot be modified later. If you need to encode a string + to the current locale encoding, use :c:func:`PyUnicode_EncodeLocale`. + .. seealso:: - :c:data:`Py_FileSystemDefaultEncoding` is initialized at startup from the - locale encoding and cannot be modified later. If you need to encode a - string to the current locale encoding, use - :c:func:`PyUnicode_EncodeLocale`. + The :c:func:`Py_EncodeLocale` function. .. versionadded:: 3.2 @@ -1133,7 +1141,7 @@ These are the UTF-32 codec APIs: mark (U+FEFF). In the other two modes, no BOM mark is prepended. If *Py_UNICODE_WIDE* is not defined, surrogate pairs will be output - as a single codepoint. + as a single code point. Return *NULL* if an exception was raised by the codec. @@ -1568,7 +1576,7 @@ They all return *NULL* or ``-1`` if an exception occurs. Unicode string. -.. c:function:: int PyUnicode_Tailmatch(PyObject *str, PyObject *substr, \ +.. c:function:: Py_ssize_t PyUnicode_Tailmatch(PyObject *str, PyObject *substr, \ Py_ssize_t start, Py_ssize_t end, int direction) Return 1 if *substr* matches ``str[start:end]`` at the given tail end @@ -1624,7 +1632,7 @@ They all return *NULL* or ``-1`` if an exception occurs. Compare a unicode object, *uni*, with *string* and return -1, 0, 1 for less than, equal, and greater than, respectively. It is best to pass only ASCII-encoded strings, but the function interprets the input string as - ISO-8859-1 if it contains non-ASCII characters". + ISO-8859-1 if it contains non-ASCII characters. .. c:function:: PyObject* PyUnicode_RichCompare(PyObject *left, PyObject *right, int op) @@ -1646,7 +1654,7 @@ They all return *NULL* or ``-1`` if an exception occurs. .. c:function:: PyObject* PyUnicode_Format(PyObject *format, PyObject *args) Return a new string object from *format* and *args*; this is analogous to - ``format % args``. The *args* argument must be a tuple. + ``format % args``. .. c:function:: int PyUnicode_Contains(PyObject *container, PyObject *element) diff --git a/Doc/c-api/veryhigh.rst b/Doc/c-api/veryhigh.rst index 9f21b89b9421..f7ed4c77139f 100644 --- a/Doc/c-api/veryhigh.rst +++ b/Doc/c-api/veryhigh.rst @@ -322,6 +322,10 @@ the same library that the Python runtime is using. it causes an exception to immediately be thrown; this is used for the :meth:`~generator.throw` methods of generator objects. + .. versionchanged:: 3.4 + This function now includes a debug assertion to help ensure that it + does not silently discard an active exception. + .. c:function:: int PyEval_MergeCompilerFlags(PyCompilerFlags *cf) diff --git a/Doc/conf.py b/Doc/conf.py index 5b63cad02891..f803de238e7c 100644 --- a/Doc/conf.py +++ b/Doc/conf.py @@ -7,26 +7,18 @@ # that aren't pickleable (module imports are okay, they're removed automatically). import sys, os, time -sys.path.append(os.path.abspath('tools/sphinxext')) +sys.path.append(os.path.abspath('tools/extensions')) # General configuration # --------------------- extensions = ['sphinx.ext.coverage', 'sphinx.ext.doctest', 'pyspecific', 'c_annotations'] -templates_path = ['tools/sphinxext'] # General substitutions. project = 'Python' copyright = '1990-%s, Python Software Foundation' % time.strftime('%Y') -# The default replacements for |version| and |release|. -# -# The short X.Y version. -# version = '2.6' -# The full version, including alpha/beta/rc tags. -# release = '2.6a0' - # We look for the Include/patchlevel.h file in the current Python source tree # and replace the values accordingly. import patchlevel @@ -38,46 +30,30 @@ # Else, today_fmt is used as the format for a strftime call. today_fmt = '%B %d, %Y' -# List of files that shouldn't be included in the build. -unused_docs = [ - 'maclib/scrap', - 'library/xmllib', - 'library/xml.etree', -] - -# Ignore .rst in Sphinx its self. -exclude_trees = ['tools/sphinx'] - -# Relative filename of the reference count data file. -refcount_file = 'data/refcounts.dat' - -# If true, '()' will be appended to :func: etc. cross-reference text. -add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -add_module_names = True - # By default, highlight as Python 3. highlight_language = 'python3' +# Require Sphinx 1.2 for build. +needs_sphinx = '1.2' + # Options for HTML output # ----------------------- +# Use our custom theme. html_theme = 'pydoctheme' -html_theme_path = ['tools/sphinxext'] +html_theme_path = ['tools'] html_theme_options = {'collapsiblesidebar': True} +# Short title used e.g. for HTML tags. html_short_title = '%s Documentation' % release # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. html_last_updated_fmt = '%b %d, %Y' -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -html_use_smartypants = True +# Path to find HTML templates. +templates_path = ['tools/templates'] # Custom sidebar templates, filenames relative to this file. html_sidebars = { @@ -91,10 +67,10 @@ } # Output an OpenSearch description file. -html_use_opensearch = 'http://docs.python.org/' + version +html_use_opensearch = 'https://docs.python.org/' + version # Additional static files. -html_static_path = ['tools/sphinxext/static'] +html_static_path = ['tools/static'] # Output file base name for HTML help builder. htmlhelp_basename = 'python' + release.replace('.', '') @@ -114,15 +90,15 @@ # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, document class [howto/manual]). -_stdauthor = r'Guido van Rossum\\Fred L. Drake, Jr., editor' +_stdauthor = r'Guido van Rossum\\and the Python development team' latex_documents = [ ('c-api/index', 'c-api.tex', 'The Python/C API', _stdauthor, 'manual'), - ('distutils/index', 'distutils.tex', + ('distributing/index', 'distributing.tex', 'Distributing Python Modules', _stdauthor, 'manual'), ('extending/index', 'extending.tex', 'Extending and Embedding Python', _stdauthor, 'manual'), - ('install/index', 'install.tex', + ('installing/index', 'installing.tex', 'Installing Python Modules', _stdauthor, 'manual'), ('library/index', 'library.tex', 'The Python Library Reference', _stdauthor, 'manual'), @@ -159,6 +135,7 @@ # Get LaTeX to handle Unicode correctly latex_elements = {'inputenc': r'\usepackage[utf8x]{inputenc}', 'utf8extra': ''} + # Options for the coverage checker # -------------------------------- @@ -194,3 +171,19 @@ coverage_ignore_c_items = { # 'cfunction': [...] } + + +# Options for the link checker +# ---------------------------- + +# Ignore certain URLs. +linkcheck_ignore = [r'https://bugs.python.org/(issue)?\d+', + # Ignore PEPs for now, they all have permanent redirects. + r'http://www.python.org/dev/peps/pep-\d+'] + + +# Options for extensions +# ---------------------- + +# Relative filename of the reference count data file. +refcount_file = 'data/refcounts.dat' diff --git a/Doc/contents.rst b/Doc/contents.rst index c0c6af34d9d1..8690de77bf3d 100644 --- a/Doc/contents.rst +++ b/Doc/contents.rst @@ -11,8 +11,8 @@ library/index.rst extending/index.rst c-api/index.rst - distutils/index.rst - install/index.rst + distributing/index.rst + installing/index.rst howto/index.rst faq/index.rst glossary.rst @@ -21,3 +21,11 @@ bugs.rst copyright.rst license.rst + +.. to include legacy packaging docs in build + +.. toctree:: + :hidden: + + distutils/index.rst + install/index.rst diff --git a/Doc/copyright.rst b/Doc/copyright.rst index 94f777c4ef69..2b2f88700f63 100644 --- a/Doc/copyright.rst +++ b/Doc/copyright.rst @@ -4,7 +4,7 @@ Copyright Python and this documentation is: -Copyright © 2001-2013 Python Software Foundation. All rights reserved. +Copyright © 2001-2015 Python Software Foundation. All rights reserved. Copyright © 2000 BeOpen.com. All rights reserved. diff --git a/Doc/data/refcounts.dat b/Doc/data/refcounts.dat index 814c3b043793..d1c24e5fcaca 100644 --- a/Doc/data/refcounts.dat +++ b/Doc/data/refcounts.dat @@ -29,7 +29,7 @@ # reference to the item argument! # The parameter names are as they appear in the API manual, not the source -# code. +# code. PyBool_FromLong:PyObject*::+1: PyBool_FromLong:long:v:0: @@ -349,6 +349,11 @@ PyErr_Format:PyObject*:exception:+1: PyErr_Format:const char*:format:: PyErr_Format::...:: +PyErr_FormatV:PyObject*::null: +PyErr_FormatV:PyObject*:exception:+1: +PyErr_FormatV:const char*:format:: +PyErr_FormatV:va_list:vargs:: + PyErr_WarnEx:int::: PyErr_WarnEx:PyObject*:category:0: PyErr_WarnEx:const char*:message:: @@ -907,7 +912,7 @@ PyNumber_Xor:PyObject*::+1: PyNumber_Xor:PyObject*:o1:0: PyNumber_Xor:PyObject*:o2:0: -PyObject_AsFileDescriptor:int::: +PyObject_AsFileDescriptor:int::: PyObject_AsFileDescriptor:PyObject*:o:0: PyObject_Call:PyObject*::+1: diff --git a/Doc/distributing/index.rst b/Doc/distributing/index.rst new file mode 100644 index 000000000000..1774d23643ec --- /dev/null +++ b/Doc/distributing/index.rst @@ -0,0 +1,170 @@ +.. _distributing-index: + +############################### + Distributing Python Modules +############################### + +:Email: distutils-sig@python.org + + +As a popular open source development project, Python has an active +supporting community of contributors and users that also make their software +available for other Python developers to use under open source license terms. + +This allows Python users to share and collaborate effectively, benefiting +from the solutions others have already created to common (and sometimes +even rare!) problems, as well as potentially contributing their own +solutions to the common pool. + +This guide covers the distribution part of the process. For a guide to +installing other Python projects, refer to the +:ref:`installation guide <installing-index>`. + +.. note:: + + For corporate and other institutional users, be aware that many + organisations have their own policies around using and contributing to + open source software. Please take such policies into account when making + use of the distribution and installation tools provided with Python. + + +Key terms +========= + +* the `Python Packaging Index <https://pypi.python.org/pypi>`__ is a public + repository of open source licensed packages made available for use by + other Python users +* the `Python Packaging Authority + <https://packaging.python.org/en/latest/future.html>`__ are the group of + developers and documentation authors responsible for the maintenance and + evolution of the standard packaging tools and the associated metadata and + file format standards. They maintain a variety of tools, documentation + and issue trackers on both `GitHub <https://github.com/pypa>`__ and + `BitBucket <https://bitbucket.org/pypa/>`__. +* :mod:`distutils` is the original build and distribution system first added + to the Python standard library in 1998. While direct use of :mod:`distutils` + is being phased out, it still laid the foundation for the current packaging + and distribution infrastructure, and it not only remains part of the + standard library, but its name lives on in other ways (such as the name + of the mailing list used to coordinate Python packaging standards + development). +* `setuptools`_ is a (largely) drop-in replacement for :mod:`distutils` first + published in 2004. Its most notable addition over the unmodified + :mod:`distutils` tools was the ability to declare dependencies on other + packages. It is currently recommended as a more regularly updated + alternative to :mod:`distutils` that offers consistent support for more + recent packaging standards across a wide range of Python versions. +* `wheel`_ (in this context) is a project that adds the ``bdist_wheel`` + command to :mod:`distutils`/`setuptools`_. This produces a cross platform + binary packaging format (called "wheels" or "wheel files" and defined in + :pep:`427`) that allows Python libraries, even those including binary + extensions, to be installed on a system without needing to be built + locally. + +.. _setuptools: https://setuptools.pypa.io/en/latest/setuptools.html +.. _wheel: http://wheel.readthedocs.org + +Open source licensing and collaboration +======================================= + +In most parts of the world, software is automatically covered by copyright. +This means that other developers require explicit permission to copy, use, +modify and redistribute the software. + +Open source licensing is a way of explicitly granting such permission in a +relatively consistent way, allowing developers to share and collaborate +efficiently by making common solutions to various problems freely available. +This leaves many developers free to spend more time focusing on the problems +that are relatively unique to their specific situation. + +The distribution tools provided with Python are designed to make it +reasonably straightforward for developers to make their own contributions +back to that common pool of software if they choose to do so. + +The same distribution tools can also be used to distribute software within +an organisation, regardless of whether that software is published as open +source software or not. + + +Installing the tools +==================== + +The standard library does not include build tools that support modern +Python packaging standards, as the core development team has found that it +is important to have standard tools that work consistently, even on older +versions of Python. + +The currently recommended build and distribution tools can be installed +by invoking the ``pip`` module at the command line:: + + python -m pip install setuptools wheel twine + +.. note:: + + For POSIX users (including Mac OS X and Linux users), these instructions + assume the use of a :term:`virtual environment`. + + For Windows users, these instructions assume that the option to + adjust the system PATH environment variable was selected when installing + Python. + +The Python Packaging User Guide includes more details on the `currently +recommended tools`_. + +.. _currently recommended tools: https://packaging.python.org/en/latest/current.html#packaging-tool-recommendations + +Reading the guide +================= + +The Python Packaging User Guide covers the various key steps and elements +involved in creating a project: + +* `Project structure`_ +* `Building and packaging the project`_ +* `Uploading the project to the Python Packaging Index`_ + +.. _Project structure: \ + https://packaging.python.org/en/latest/distributing.html#creating-your-own-project +.. _Building and packaging the project: \ + https://packaging.python.org/en/latest/distributing.html#packaging-your-project +.. _Uploading the project to the Python Packaging Index: \ + https://packaging.python.org/en/latest/distributing.html#uploading-your-project-to-pypi + + +How do I...? +============ + +These are quick answers or links for some common tasks. + +... choose a name for my project? +--------------------------------- + +This isn't an easy topic, but here are a few tips: + +* check the Python Packaging Index to see if the name is already in use +* check popular hosting sites like GitHub, BitBucket, etc to see if there + is already a project with that name +* check what comes up in a web search for the name you're considering +* avoid particularly common words, especially ones with multiple meanings, + as they can make it difficult for users to find your software when + searching for it + + +... create and distribute binary extensions? +-------------------------------------------- + +This is actually quite a complex topic, with a variety of alternatives +available depending on exactly what you're aiming to achieve. See the +Python Packaging User Guide for more information and recommendations. + +.. seealso:: + + `Python Packaging User Guide: Binary Extensions + <https://packaging.python.org/en/latest/extensions.html>`__ + +.. other topics: + + Once the Development & Deployment part of PPUG is fleshed out, some of + those sections should be linked from new questions here (most notably, + we should have a question about avoiding depending on PyPI that links to + https://packaging.python.org/en/latest/deployment.html#pypi-mirrors-and-caches) diff --git a/Doc/distutils/apiref.rst b/Doc/distutils/apiref.rst index 54f0a4eca6fa..53d7527c657e 100644 --- a/Doc/distutils/apiref.rst +++ b/Doc/distutils/apiref.rst @@ -78,7 +78,7 @@ setup script). Indirectly provides the :class:`distutils.dist.Distribution` and | | be built | :class:`distutils.core.Extension` | +--------------------+--------------------------------+-------------------------------------------------------------+ | *classifiers* | A list of categories for the | a list of strings; valid classifiers are listed on `PyPI | - | | package | <http://pypi.python.org/pypi?:action=list_classifiers>`_. | + | | package | <https://pypi.python.org/pypi?:action=list_classifiers>`_. | +--------------------+--------------------------------+-------------------------------------------------------------+ | *distclass* | the :class:`Distribution` | a subclass of | | | class to use | :class:`distutils.core.Distribution` | @@ -853,17 +853,6 @@ Windows. It also contains the Mingw32CCompiler class which handles the mingw32 port of GCC (same as cygwin in no-cygwin mode). -:mod:`distutils.emxccompiler` --- OS/2 EMX Compiler -=================================================== - -.. module:: distutils.emxccompiler - :synopsis: OS/2 EMX Compiler support - - -This module provides the EMXCCompiler class, a subclass of -:class:`UnixCCompiler` that handles the EMX port of the GNU C compiler to OS/2. - - :mod:`distutils.archive_util` --- Archiving utilities ====================================================== @@ -975,7 +964,7 @@ directories. .. function:: create_tree(base_dir, files[, mode=0o777, verbose=0, dry_run=0]) Create all the empty directories under *base_dir* needed to put *files* there. - *base_dir* is just the a name of a directory which doesn't necessarily exist + *base_dir* is just the name of a directory which doesn't necessarily exist yet; *files* is a list of filenames to be interpreted relative to *base_dir*. *base_dir* + the directory portion of every file in *files* will be created if it doesn't already exist. *mode*, *verbose* and *dry_run* flags are as for @@ -1004,7 +993,7 @@ directories. Files in *src* that begin with :file:`.nfs` are skipped (more information on these files is available in answer D2 of the `NFS FAQ page - <http://nfs.sourceforge.net/#section_d>`_. + <http://nfs.sourceforge.net/#section_d>`_). .. versionchanged:: 3.3.1 NFS files are ignored. @@ -1110,13 +1099,13 @@ other utility module. during the build of Python), not the OS version of the current system. For universal binary builds on Mac OS X the architecture value reflects - the univeral binary status instead of the architecture of the current + the universal binary status instead of the architecture of the current processor. For 32-bit universal binaries the architecture is ``fat``, for 64-bit universal binaries the architecture is ``fat64``, and for 4-way universal binaries the architecture is ``universal``. Starting from Python 2.7 and Python 3.2 the architecture ``fat3`` is used for a 3-way universal build (ppc, i386, x86_64) and ``intel`` is used for - a univeral build with the i386 and x86_64 architectures + a universal build with the i386 and x86_64 architectures Examples of returned values on Mac OS X: @@ -1171,15 +1160,6 @@ other utility module. underscore. No { } or ( ) style quoting is available. -.. function:: grok_environment_error(exc[, prefix='error: ']) - - Generate a useful error message from an :exc:`OSError` exception object. - Handles Python 1.5.1 and later styles, and does what it can to deal with - exception objects that don't have a filename (which happens when the error - is due to a two-file operation, such as :func:`~os.rename` or :func:`~os.link`). - Returns the error message as a string prefixed with *prefix*. - - .. function:: split_quoted(s) Split a string up according to Unix shell-like rules for quotes and backslashes. @@ -1943,8 +1923,12 @@ Subclasses of :class:`Command` must define the following methods. .. module:: distutils.command.clean :synopsis: Clean a package build area +This command removes the temporary files created by :command:`build` +and its subcommands, like intermediary compiled object files. With +the ``--all`` option, the complete build directory will be removed. -.. % todo +Extension modules built :ref:`in place <distutils-build-ext-inplace>` +will not be cleaned, as they are not in the build directory. :mod:`distutils.command.config` --- Perform package configuration diff --git a/Doc/distutils/builtdist.rst b/Doc/distutils/builtdist.rst index 83c68ae20c75..c5827b63cf9c 100644 --- a/Doc/distutils/builtdist.rst +++ b/Doc/distutils/builtdist.rst @@ -186,21 +186,21 @@ Distutils configuration files. Various options and sections in the +------------------------------------------+----------------------------------------------+ | RPM :file:`.spec` file option or section | Distutils setup script option | +==========================================+==============================================+ -| Name | :option:`name` | +| Name | ``name`` | +------------------------------------------+----------------------------------------------+ -| Summary (in preamble) | :option:`description` | +| Summary (in preamble) | ``description`` | +------------------------------------------+----------------------------------------------+ -| Version | :option:`version` | +| Version | ``version`` | +------------------------------------------+----------------------------------------------+ -| Vendor | :option:`author` and :option:`author_email`, | -| | or --- & :option:`maintainer` and | -| | :option:`maintainer_email` | +| Vendor | ``author`` and ``author_email``, | +| | or --- & ``maintainer`` and | +| | ``maintainer_email`` | +------------------------------------------+----------------------------------------------+ -| Copyright | :option:`license` | +| Copyright | ``license`` | +------------------------------------------+----------------------------------------------+ -| Url | :option:`url` | +| Url | ``url`` | +------------------------------------------+----------------------------------------------+ -| %description (section) | :option:`long_description` | +| %description (section) | ``long_description`` | +------------------------------------------+----------------------------------------------+ Additionally, there are many options in :file:`.spec` files that don't have @@ -211,27 +211,27 @@ options to the :command:`bdist_rpm` command as follows: | RPM :file:`.spec` file option | :command:`bdist_rpm` option | default value | | or section | | | +===============================+=============================+=========================+ -| Release | :option:`release` | "1" | +| Release | ``release`` | "1" | +-------------------------------+-----------------------------+-------------------------+ -| Group | :option:`group` | "Development/Libraries" | +| Group | ``group`` | "Development/Libraries" | +-------------------------------+-----------------------------+-------------------------+ -| Vendor | :option:`vendor` | (see above) | +| Vendor | ``vendor`` | (see above) | +-------------------------------+-----------------------------+-------------------------+ -| Packager | :option:`packager` | (none) | +| Packager | ``packager`` | (none) | +-------------------------------+-----------------------------+-------------------------+ -| Provides | :option:`provides` | (none) | +| Provides | ``provides`` | (none) | +-------------------------------+-----------------------------+-------------------------+ -| Requires | :option:`requires` | (none) | +| Requires | ``requires`` | (none) | +-------------------------------+-----------------------------+-------------------------+ -| Conflicts | :option:`conflicts` | (none) | +| Conflicts | ``conflicts`` | (none) | +-------------------------------+-----------------------------+-------------------------+ -| Obsoletes | :option:`obsoletes` | (none) | +| Obsoletes | ``obsoletes`` | (none) | +-------------------------------+-----------------------------+-------------------------+ -| Distribution | :option:`distribution_name` | (none) | +| Distribution | ``distribution_name`` | (none) | +-------------------------------+-----------------------------+-------------------------+ -| BuildRequires | :option:`build_requires` | (none) | +| BuildRequires | ``build_requires`` | (none) | +-------------------------------+-----------------------------+-------------------------+ -| Icon | :option:`icon` | (none) | +| Icon | ``icon`` | (none) | +-------------------------------+-----------------------------+-------------------------+ Obviously, supplying even a few of these options on the command-line would be @@ -355,7 +355,7 @@ support this option, so the command:: would create a 64bit installation executable on your 32bit version of Windows. To cross-compile, you must download the Python source code and cross-compile -Python itself for the platform you are targetting - it is not possible from a +Python itself for the platform you are targeting - it is not possible from a binary installation of Python (as the .lib etc file for other platforms are not included.) In practice, this means the user of a 32 bit operating system will need to use Visual Studio 2008 to open the diff --git a/Doc/distutils/configfile.rst b/Doc/distutils/configfile.rst index 890047c08e54..8faffe6c200d 100644 --- a/Doc/distutils/configfile.rst +++ b/Doc/distutils/configfile.rst @@ -67,7 +67,9 @@ universal :option:`--help` option, e.g. :: [...] Note that an option spelled :option:`--foo-bar` on the command-line is spelled -:option:`foo_bar` in configuration files. +``foo_bar`` in configuration files. + +.. _distutils-build-ext-inplace: For example, say you want your extensions to be built "in-place"---that is, you have an extension :mod:`pkg.ext`, and you want the compiled extension file @@ -112,7 +114,7 @@ own :file:`setup.cfg`:: doc/ examples/ -Note that the :option:`doc_files` option is simply a whitespace-separated string +Note that the ``doc_files`` option is simply a whitespace-separated string split across multiple lines for readability. diff --git a/Doc/distutils/examples.rst b/Doc/distutils/examples.rst index 5eb654a529a1..af9125a7b3f1 100644 --- a/Doc/distutils/examples.rst +++ b/Doc/distutils/examples.rst @@ -11,7 +11,7 @@ Distutils Cookbook. .. seealso:: - `Distutils Cookbook <http://wiki.python.org/moin/Distutils/Cookbook>`_ + `Distutils Cookbook <https://wiki.python.org/moin/Distutils/Cookbook>`_ Collection of recipes showing how to achieve more control over distutils. @@ -22,7 +22,7 @@ Pure Python distribution (by module) If you're just distributing a couple of modules, especially if they don't live in a particular package, you can specify them individually using the -:option:`py_modules` option in the setup script. +``py_modules`` option in the setup script. In the simplest case, you'll have two files to worry about: a setup script and the single module you're distributing, :file:`foo.py` in this example:: @@ -41,12 +41,12 @@ directory.) A minimal setup script to describe this situation would be:: ) Note that the name of the distribution is specified independently with the -:option:`name` option, and there's no rule that says it has to be the same as +``name`` option, and there's no rule that says it has to be the same as the name of the sole module in the distribution (although that's probably a good convention to follow). However, the distribution name is used to generate filenames, so you should stick to letters, digits, underscores, and hyphens. -Since :option:`py_modules` is a list, you can of course specify multiple +Since ``py_modules`` is a list, you can of course specify multiple modules, eg. if you're distributing modules :mod:`foo` and :mod:`bar`, your setup might look like this:: @@ -130,7 +130,7 @@ requires the least work to describe in your setup script:: ) If you want to put modules in directories not named for their package, then you -need to use the :option:`package_dir` option again. For example, if the +need to use the ``package_dir`` option again. For example, if the :file:`src` directory holds modules in the :mod:`foobar` package:: <root>/ @@ -169,8 +169,8 @@ in which case your setup script would be :: (The empty string also stands for the current directory.) -If you have sub-packages, they must be explicitly listed in :option:`packages`, -but any entries in :option:`package_dir` automatically extend to sub-packages. +If you have sub-packages, they must be explicitly listed in ``packages``, +but any entries in ``package_dir`` automatically extend to sub-packages. (In other words, the Distutils does *not* scan your source tree, trying to figure out which directories correspond to Python packages by looking for :file:`__init__.py` files.) Thus, if the default layout grows a sub-package:: @@ -193,17 +193,14 @@ then the corresponding setup script would be :: packages=['foobar', 'foobar.subfoo'], ) -(Again, the empty string in :option:`package_dir` stands for the current -directory.) - .. _single-ext: Single extension module ======================= -Extension modules are specified using the :option:`ext_modules` option. -:option:`package_dir` has no effect on where extension source files are found; +Extension modules are specified using the ``ext_modules`` option. +``package_dir`` has no effect on where extension source files are found; it only affects the source for pure Python modules. The simplest case, a single extension module in a single C source file, is:: @@ -267,7 +264,7 @@ For example, if the :file:`setup.py` script is changed like this:: desc = """\ My description - ============= + ============== This is the description of the ``foobar`` package. """ @@ -289,20 +286,20 @@ Reading the metadata The :func:`distutils.core.setup` function provides a command-line interface that allows you to query the metadata fields of a project through the -`setup.py` script of a given project:: +``setup.py`` script of a given project:: $ python setup.py --name distribute -This call reads the `name` metadata by running the +This call reads the ``name`` metadata by running the :func:`distutils.core.setup` function. Although, when a source or binary distribution is created with Distutils, the metadata fields are written in a static file called :file:`PKG-INFO`. When a Distutils-based project is installed in Python, the :file:`PKG-INFO` file is copied alongside the modules and packages of the distribution under :file:`NAME-VERSION-pyX.X.egg-info`, -where `NAME` is the name of the project, `VERSION` its version as defined -in the Metadata, and `pyX.X` the major and minor version of Python like -`2.7` or `3.2`. +where ``NAME`` is the name of the project, ``VERSION`` its version as defined +in the Metadata, and ``pyX.X`` the major and minor version of Python like +``2.7`` or ``3.2``. You can read back this static file, by using the :class:`distutils.dist.DistributionMetadata` class and its diff --git a/Doc/distutils/extending.rst b/Doc/distutils/extending.rst index 5a70d031cc6c..5139c6dc81f8 100644 --- a/Doc/distutils/extending.rst +++ b/Doc/distutils/extending.rst @@ -61,7 +61,7 @@ commands to be added which can support existing :file:`setup.py` scripts without requiring modifications to the Python installation. This is expected to allow third-party extensions to provide support for additional packaging systems, but the commands can be used for anything distutils commands can be used for. A new -configuration option, :option:`command_packages` (command-line option +configuration option, ``command_packages`` (command-line option :option:`--command-packages`), can be used to specify additional packages to be searched for modules implementing commands. Like all distutils options, this can be specified on the command line or in a configuration file. This option @@ -75,7 +75,7 @@ This new option can be used to add any number of packages to the list of packages searched for command implementations; multiple package names should be separated by commas. When not specified, the search is only performed in the :mod:`distutils.command` package. When :file:`setup.py` is run with the option -:option:`--command-packages` :option:`distcmds,buildcmds`, however, the packages +``--command-packages distcmds,buildcmds``, however, the packages :mod:`distutils.command`, :mod:`distcmds`, and :mod:`buildcmds` will be searched in that order. New commands are expected to be implemented in modules of the same name as the command by classes sharing the same name. Given the example diff --git a/Doc/distutils/index.rst b/Doc/distutils/index.rst index 1cd5f3c5dc6e..90d1c1ab34f6 100644 --- a/Doc/distutils/index.rst +++ b/Doc/distutils/index.rst @@ -1,8 +1,8 @@ .. _distutils-index: -############################### - Distributing Python Modules -############################### +############################################## + Distributing Python Modules (Legacy version) +############################################## :Authors: Greg Ward, Anthony Baxter :Email: distutils-sig@python.org @@ -12,6 +12,16 @@ the module developer's point of view, describing how to use the Distutils to make Python modules and extensions easily available to a wider audience with very little overhead for build/release/install mechanics. +.. note:: + + This guide only covers the basic tools for building and distributing + extensions that are provided as part of this version of Python. Third + party tools offer easier to use and more secure alternatives. Refer to the + `quick recommendations section + <https://python-packaging-user-guide.readthedocs.org/en/latest/current.html>`__ + in the Python Packaging User Guide for more information. + + .. toctree:: :maxdepth: 2 :numbered: diff --git a/Doc/distutils/packageindex.rst b/Doc/distutils/packageindex.rst index dae8c545d0d3..daf934526487 100644 --- a/Doc/distutils/packageindex.rst +++ b/Doc/distutils/packageindex.rst @@ -8,26 +8,57 @@ The Python Package Index (PyPI) ******************************* -The `Python Package Index (PyPI)`_ holds :ref:`meta-data <meta-data>` +The `Python Package Index (PyPI)`_ stores :ref:`meta-data <meta-data>` describing distributions packaged with distutils, as well as package data like -distribution files if the package author wishes. +distribution files if a package author wishes. + +Distutils provides the :command:`register` and :command:`upload` commands for +pushing meta-data and distribution files to PyPI, respectively. See +:ref:`package-commands` for information on these commands. + + +PyPI overview +============= + +PyPI lets you submit any number of versions of your distribution to the index. +If you alter the meta-data for a particular version, you can submit it again +and the index will be updated. + +PyPI holds a record for each (name, version) combination submitted. The first +user to submit information for a given name is designated the Owner of that +name. Changes can be submitted through the :command:`register` command or +through the web interface. Owners can designate other users as Owners or +Maintainers. Maintainers can edit the package information, but not designate +new Owners or Maintainers. + +By default PyPI displays only the newest version of a given package. The web +interface lets one change this default behavior and manually select which +versions to display and hide. + +For each version, PyPI displays a home page. The home page is created from +the ``long_description`` which can be submitted via the :command:`register` +command. See :ref:`package-display` for more information. + + +.. _package-commands: + +Distutils commands +================== Distutils exposes two commands for submitting package data to PyPI: the :ref:`register <package-register>` command for submitting meta-data to PyPI and the :ref:`upload <package-upload>` command for submitting distribution -files. Both commands read configuration data from a special file called the -:ref:`.pypirc file <pypirc>`. PyPI :ref:`displays a home page -<package-display>` for each package created from the ``long_description`` -submitted by the :command:`register` command. +files. Both commands read configuration data from a special file called a +:ref:`.pypirc file <pypirc>`. .. _package-register: -Registering Packages -==================== +The ``register`` command +------------------------ The distutils command :command:`register` is used to submit your distribution's -meta-data to the index. It is invoked as follows:: +meta-data to an index server. It is invoked as follows:: python setup.py register @@ -42,7 +73,8 @@ Distutils will respond with the following prompt:: Your selection [default 1]: Note: if your username and password are saved locally, you will not see this -menu. +menu. Also, refer to :ref:`pypirc` for how to store your credentials in a +:file:`.pypirc` file. If you have not registered with PyPI, then you will need to do so now. You should choose option 2, and enter your details as required. Soon after @@ -53,26 +85,13 @@ Once you are registered, you may choose option 1 from the menu. You will be prompted for your PyPI username and password, and :command:`register` will then submit your meta-data to the index. -You may submit any number of versions of your distribution to the index. If you -alter the meta-data for a particular version, you may submit it again and the -index will be updated. - -PyPI holds a record for each (name, version) combination submitted. The first -user to submit information for a given name is designated the Owner of that -name. They may submit changes through the :command:`register` command or through -the web interface. They may also designate other users as Owners or Maintainers. -Maintainers may edit the package information, but not designate other Owners or -Maintainers. - -By default PyPI displays only the newest version of a given package. The web -interface lets one change this default behavior and manually select which -versions to display and hide. +See :ref:`package-cmdoptions` for options to the :command:`register` command. .. _package-upload: -Uploading Packages -================== +The ``upload`` command +---------------------- The distutils command :command:`upload` pushes the distribution files to PyPI. @@ -86,29 +105,42 @@ PyPI. Note that these will be uploaded even if they are built using an earlier invocation of :file:`setup.py`, but that only distributions named on the command line for the invocation including the :command:`upload` command are uploaded. -The :command:`upload` command uses the username, password, and repository URL -from the :file:`$HOME/.pypirc` file (see section :ref:`pypirc` for more on this -file). If a :command:`register` command was previously called in the same command, +If a :command:`register` command was previously called in the same command, and if the password was entered in the prompt, :command:`upload` will reuse the -entered password. This is useful if you do not want to store a clear text -password in the :file:`$HOME/.pypirc` file. - -You can specify another PyPI server with the ``--repository=url`` option:: - - python setup.py sdist bdist_wininst upload -r http://example.com/pypi - -See section :ref:`pypirc` for more on defining several servers. +entered password. This is useful if you do not want to store a password in +clear text in a :file:`.pypirc` file. You can use the ``--sign`` option to tell :command:`upload` to sign each uploaded file using GPG (GNU Privacy Guard). The :program:`gpg` program must be available for execution on the system :envvar:`PATH`. You can also specify which key to use for signing using the ``--identity=name`` option. -Other :command:`upload` options include ``--repository=url`` or -``--repository=section`` where *url* is the url of the server and -*section* the name of the section in :file:`$HOME/.pypirc`, and -``--show-response`` (which displays the full response text from the PyPI -server for help in debugging upload problems). +See :ref:`package-cmdoptions` for additional options to the :command:`upload` +command. + + +.. _package-cmdoptions: + +Additional command options +-------------------------- + +This section describes options common to both the :command:`register` and +:command:`upload` commands. + +The ``--repository`` or ``-r`` option lets you specify a PyPI server +different from the default. For example:: + + python setup.py sdist bdist_wininst upload -r https://example.com/pypi + +For convenience, a name can be used in place of the URL when the +:file:`.pypirc` file is configured to do so. For example:: + + python setup.py register -r other + +See :ref:`pypirc` for more information on defining alternate servers. + +The ``--show-response`` option displays the full response text from the PyPI +server, which is useful when debugging problems with registering and uploading. .. index:: @@ -117,10 +149,14 @@ server for help in debugging upload problems). .. _pypirc: -The .pypirc file -================ +The ``.pypirc`` file +-------------------- -The format of the :file:`.pypirc` file is as follows:: +The :command:`register` and :command:`upload` commands both check for the +existence of a :file:`.pypirc` file at the location :file:`$HOME/.pypirc`. +If this file exists, the command uses the username, password, and repository +URL configured in the file. The format of a :file:`.pypirc` file is as +follows:: [distutils] index-servers = @@ -137,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 - ``http://www.python.org/pypi``. + ``https://www.python.org/pypi``. - *username*, which is the registered username on the PyPI server. - *password*, that will be used to authenticate. If omitted the user will be prompt to type it when needed. @@ -156,19 +192,17 @@ listed in the *index-servers* variable:: password: <password> [other] - repository: http://example.com/pypi + repository: https://example.com/pypi username: <username> password: <password> -:command:`register` can then be called with the -r option to point the -repository to work with:: - - python setup.py register -r http://example.com/pypi +This allows the :command:`register` and :command:`upload` commands to be +called with the ``--repository`` option as described in +:ref:`package-cmdoptions`. -For convenience, the name of the section that describes the repository -may also be used:: - - python setup.py register -r other +Specifically, you might want to add the `PyPI Test Repository +<https://wiki.python.org/moin/TestPyPI>`_ to your ``.pypirc`` to facilitate +testing before doing your first upload to ``PyPI`` itself. .. _package-display: @@ -210,4 +244,4 @@ without warnings does not guarantee that PyPI will convert the content successfully. -.. _Python Package Index (PyPI): http://pypi.python.org/ +.. _Python Package Index (PyPI): https://pypi.python.org/pypi diff --git a/Doc/distutils/setupscript.rst b/Doc/distutils/setupscript.rst index ee96302ce1ee..3edcf878c7cd 100644 --- a/Doc/distutils/setupscript.rst +++ b/Doc/distutils/setupscript.rst @@ -28,7 +28,7 @@ the package into Python 1.5.2.) :: description='Python Distribution Utilities', author='Greg Ward', author_email='gward@python.net', - url='http://www.python.org/sigs/distutils-sig/', + url='https://www.python.org/sigs/distutils-sig/', packages=['distutils', 'distutils.command'], ) @@ -62,9 +62,9 @@ code instead of hardcoding path separators:: Listing whole packages ====================== -The :option:`packages` option tells the Distutils to process (build, distribute, +The ``packages`` option tells the Distutils to process (build, distribute, install, etc.) all pure Python modules found in each package mentioned in the -:option:`packages` list. In order to do this, of course, there has to be a +``packages`` list. In order to do this, of course, there has to be a correspondence between package names and directories in the filesystem. The default correspondence is the most obvious one, i.e. package :mod:`distutils` is found in the directory :file:`distutils` relative to the distribution root. @@ -75,7 +75,7 @@ the directory where your setup script lives. If you break this promise, the Distutils will issue a warning but still process the broken package anyway. If you use a different convention to lay out your source directory, that's no -problem: you just have to supply the :option:`package_dir` option to tell the +problem: you just have to supply the ``package_dir`` option to tell the Distutils about your convention. For example, say you keep all Python source under :file:`lib`, so that modules in the "root package" (i.e., not in any package at all) are in :file:`lib`, modules in the :mod:`foo` package are in @@ -94,13 +94,13 @@ written in the setup script as :: package_dir = {'foo': 'lib'} -A ``package: dir`` entry in the :option:`package_dir` dictionary implicitly +A ``package: dir`` entry in the ``package_dir`` dictionary implicitly applies to all packages below *package*, so the :mod:`foo.bar` case is automatically handled here. In this example, having ``packages = ['foo', 'foo.bar']`` tells the Distutils to look for :file:`lib/__init__.py` and -:file:`lib/bar/__init__.py`. (Keep in mind that although :option:`package_dir` +:file:`lib/bar/__init__.py`. (Keep in mind that although ``package_dir`` applies recursively, you must explicitly list all packages in -:option:`packages`: the Distutils will *not* recursively scan your source tree +``packages``: the Distutils will *not* recursively scan your source tree looking for any directory with an :file:`__init__.py` file.) @@ -120,7 +120,7 @@ This describes two modules, one of them in the "root" package, the other in the :mod:`pkg` package. Again, the default package/directory layout implies that these two modules can be found in :file:`mod1.py` and :file:`pkg/mod2.py`, and that :file:`pkg/__init__.py` exists as well. And again, you can override the -package/directory correspondence using the :option:`package_dir` option. +package/directory correspondence using the ``package_dir`` option. .. _describing-extensions: @@ -138,7 +138,7 @@ directories, libraries to link with, etc.). .. XXX read over this section All of this is done through another keyword argument to :func:`setup`, the -:option:`ext_modules` option. :option:`ext_modules` is just a list of +``ext_modules`` option. ``ext_modules`` is just a list of :class:`~distutils.core.Extension` instances, each of which describes a single extension module. Suppose your distribution includes a single extension, called :mod:`foo` and @@ -181,7 +181,7 @@ in the filesystem (and therefore where in Python's namespace hierarchy) the resulting extension lives. If you have a number of extensions all in the same package (or all under the -same base package), use the :option:`ext_package` keyword argument to +same base package), use the ``ext_package`` keyword argument to :func:`setup`. For example, :: setup(..., @@ -336,24 +336,24 @@ Other options There are still some other options which can be used to handle special cases. -The :option:`optional` option is a boolean; if it is true, +The ``optional`` option is a boolean; if it is true, a build failure in the extension will not abort the build process, but instead simply not install the failing extension. -The :option:`extra_objects` option is a list of object files to be passed to the +The ``extra_objects`` option is a list of object files to be passed to the linker. These files must not have extensions, as the default extension for the compiler is used. -:option:`extra_compile_args` and :option:`extra_link_args` can be used to +``extra_compile_args`` and ``extra_link_args`` can be used to specify additional command line options for the respective compiler and linker command lines. -:option:`export_symbols` is only useful on Windows. It can contain a list of +``export_symbols`` is only useful on Windows. It can contain a list of symbols (functions or variables) to be exported. This option is not needed when building compiled extensions: Distutils will automatically add ``initmodule`` to the list of exported symbols. -The :option:`depends` option is a list of files that the extension depends on +The ``depends`` option is a list of files that the extension depends on (for example header files). The build command will call the compiler on the sources to rebuild extension if any on this files has been modified since the previous build. @@ -449,7 +449,7 @@ to refer to the current interpreter location. By default, it is replaced with the current interpreter location. The :option:`--executable` (or :option:`-e`) option will allow the interpreter path to be explicitly overridden. -The :option:`scripts` option simply is a list of files to be handled in this +The ``scripts`` option simply is a list of files to be handled in this way. From the PyXML setup script:: setup(..., @@ -514,11 +514,11 @@ The corresponding call to :func:`setup` might be:: Installing Additional Files =========================== -The :option:`data_files` option can be used to specify additional files needed +The ``data_files`` option can be used to specify additional files needed by the module distribution: configuration files, message catalogs, data files, anything which doesn't fit in the previous categories. -:option:`data_files` specifies a sequence of (*directory*, *files*) pairs in the +``data_files`` specifies a sequence of (*directory*, *files*) pairs in the following way:: setup(..., @@ -539,7 +539,7 @@ modules). Each file name in *files* is interpreted relative to the directory information from *files* is used to determine the final location of the installed file; only the name of the file is used. -You can specify the :option:`data_files` options as a simple sequence of files +You can specify the ``data_files`` options as a simple sequence of files without specifying a target directory, but this is not recommended, and the :command:`install` command will print a warning in this case. To install data files directly in the target directory, an empty string should be given as the @@ -609,7 +609,7 @@ Notes: (4) These fields should not be used if your package is to be compatible with Python versions prior to 2.2.3 or 2.3. The list is available from the `PyPI website - <http://pypi.python.org/pypi>`_. + <https://pypi.python.org/pypi>`_. (5) The ``long_description`` field is used by PyPI when you are @@ -628,7 +628,7 @@ Notes: 'long string' Multiple lines of plain text in reStructuredText format (see - http://docutils.sf.net/). + http://docutils.sourceforge.net/). 'list of strings' See below. @@ -650,7 +650,7 @@ information is sometimes used to indicate sub-releases. These are 1.0.1a2 the second alpha release of the first patch version of 1.0 -:option:`classifiers` are specified in a Python list:: +``classifiers`` are specified in a Python list:: setup(..., classifiers=[ @@ -685,6 +685,8 @@ include the following code fragment in your :file:`setup.py` before the DistributionMetadata.download_url = None +.. _debug-setup-script: + Debugging the setup script ========================== @@ -700,7 +702,8 @@ installation is broken because they don't read all the way down to the bottom and see that it's a permission problem. On the other hand, this doesn't help the developer to find the cause of the -failure. For this purpose, the DISTUTILS_DEBUG environment variable can be set +failure. For this purpose, the :envvar:`DISTUTILS_DEBUG` environment variable can be set to anything except an empty string, and distutils will now print detailed -information what it is doing, and prints the full traceback in case an exception -occurs. +information about what it is doing, dump the full traceback when an exception +occurs, and print the whole command line when an external program (like a C +compiler) fails. diff --git a/Doc/distutils/sourcedist.rst b/Doc/distutils/sourcedist.rst index 9f7a38eda66d..b9f0cc863b92 100644 --- a/Doc/distutils/sourcedist.rst +++ b/Doc/distutils/sourcedist.rst @@ -72,16 +72,16 @@ If you don't supply an explicit list of files (or instructions on how to generate one), the :command:`sdist` command puts a minimal default set into the source distribution: -* all Python source files implied by the :option:`py_modules` and - :option:`packages` options +* all Python source files implied by the ``py_modules`` and + ``packages`` options -* all C source files mentioned in the :option:`ext_modules` or - :option:`libraries` options ( +* all C source files mentioned in the ``ext_modules`` or + ``libraries`` options .. XXX getting C library sources currently broken---no :meth:`get_source_files` method in :file:`build_clib.py`! -* scripts identified by the :option:`scripts` option +* scripts identified by the ``scripts`` option See :ref:`distutils-installing-scripts`. * anything that looks like a test script: :file:`test/test\*.py` (currently, the @@ -167,7 +167,7 @@ source distribution: #. include all Python source files in the :file:`distutils` and :file:`distutils/command` subdirectories (because packages corresponding to - those two directories were mentioned in the :option:`packages` option in the + those two directories were mentioned in the ``packages`` option in the setup script---see section :ref:`setup-script`) #. include :file:`README.txt`, :file:`setup.py`, and :file:`setup.cfg` (standard diff --git a/Doc/extending/building.rst b/Doc/extending/building.rst index 08b0cc2ceda2..06d300547d4d 100644 --- a/Doc/extending/building.rst +++ b/Doc/extending/building.rst @@ -81,7 +81,7 @@ example below. :: description = 'This is a demo package', author = 'Martin v. Loewis', author_email = 'martin@v.loewis.de', - url = 'http://docs.python.org/extending/building', + url = 'https://docs.python.org/extending/building', long_description = ''' This is really just a demo package. ''', diff --git a/Doc/extending/embedding.rst b/Doc/extending/embedding.rst index 6cb686ab096a..acd60aef8c81 100644 --- a/Doc/extending/embedding.rst +++ b/Doc/extending/embedding.rst @@ -58,12 +58,18 @@ perform some operation on a file. :: int main(int argc, char *argv[]) { - Py_SetProgramName(argv[0]); /* optional but recommended */ - Py_Initialize(); - PyRun_SimpleString("from time import time,ctime\n" - "print('Today is', ctime(time()))\n"); - Py_Finalize(); - return 0; + wchar_t *program = Py_DecodeLocale(argv[0], NULL); + if (program == NULL) { + fprintf(stderr, "Fatal error: cannot decode argv[0]\n"); + exit(1); + } + Py_SetProgramName(program); /* optional but recommended */ + Py_Initialize(); + PyRun_SimpleString("from time import time,ctime\n" + "print('Today is', ctime(time()))\n"); + Py_Finalize(); + PyMem_RawFree(program); + return 0; } The :c:func:`Py_SetProgramName` function should be called before @@ -160,7 +166,7 @@ for data conversion between Python and C, and for error reporting. The interesting part with respect to embedding Python starts with :: Py_Initialize(); - pName = PyUnicode_FromString(argv[1]); + pName = PyUnicode_DecodeFSDefault(argv[1]); /* Error checking of pName left out */ pModule = PyImport_Import(pName); diff --git a/Doc/extending/extending.rst b/Doc/extending/extending.rst index a3bf2656ed84..17cfdeb965d3 100644 --- a/Doc/extending/extending.rst +++ b/Doc/extending/extending.rst @@ -20,12 +20,17 @@ source file by including the header ``"Python.h"``. The compilation of an extension module depends on its intended use as well as on your system setup; details are given in later chapters. -Do note that if your use case is calling C library functions or system calls, -you should consider using the :mod:`ctypes` module rather than writing custom -C code. Not only does :mod:`ctypes` let you write Python code to interface -with C code, but it is more portable between implementations of Python than -writing and compiling an extension module which typically ties you to CPython. +.. note:: + The C extension interface is specific to CPython, and extension modules do + not work on other Python implementations. In many cases, it is possible to + avoid writing C extensions and preserve portability to other implementations. + For example, if your use case is calling C library functions or system calls, + you should consider using the :mod:`ctypes` module or the `cffi + <http://cffi.readthedocs.org>`_ library rather than writing custom C code. + These modules let you write Python code to interface with C code and are more + portable between implementations of Python than writing and compiling a C + extension module. .. _extending-simpleexample: @@ -370,11 +375,17 @@ optionally followed by an import of the module:: int main(int argc, char *argv[]) { + wchar_t *program = Py_DecodeLocale(argv[0], NULL); + if (program == NULL) { + fprintf(stderr, "Fatal error: cannot decode argv[0]\n"); + exit(1); + } + /* Add a built-in module, before Py_Initialize */ PyImport_AppendInittab("spam", PyInit_spam); /* Pass argv[0] to the Python interpreter */ - Py_SetProgramName(argv[0]); + Py_SetProgramName(program); /* Initialize the Python interpreter. Required. */ Py_Initialize(); @@ -386,6 +397,10 @@ optionally followed by an import of the module:: ... + PyMem_RawFree(program); + return 0; + } + .. note:: Removing entries from ``sys.modules`` or importing compiled modules into @@ -857,11 +872,8 @@ reclaim the memory belonging to any objects in a reference cycle, or referenced from the objects in the cycle, even though there are no further references to the cycle itself. -The cycle detector is able to detect garbage cycles and can reclaim them so long -as there are no finalizers implemented in Python (:meth:`__del__` methods). -When there are such finalizers, the detector exposes the cycles through the -:mod:`gc` module (specifically, the :attr:`~gc.garbage` variable in that module). -The :mod:`gc` module also exposes a way to run the detector (the +The cycle detector is able to detect garbage cycles and can reclaim them. +The :mod:`gc` module exposes a way to run the detector (the :func:`~gc.collect` function), as well as configuration interfaces and the ability to disable the detector at runtime. The cycle detector is considered an optional component; though it is included by default, diff --git a/Doc/extending/index.rst b/Doc/extending/index.rst index 611294399585..dd4392645023 100644 --- a/Doc/extending/index.rst +++ b/Doc/extending/index.rst @@ -21,6 +21,32 @@ Python) that give the language its wide application range. For a detailed description of the whole Python/C API, see the separate :ref:`c-api-index`. + +Recommended third party tools +============================= + +This guide only covers the basic tools for creating extensions provided +as part of this version of CPython. Third party tools like Cython, +``cffi``, SWIG and Numba offer both simpler and more sophisticated +approaches to creating C and C++ extensions for Python. + +.. seealso:: + + `Python Packaging User Guide: Binary Extensions <https://packaging.python.org/en/latest/extensions.html>`_ + The Python Packaging User Guide not only covers several available + tools that simplify the creation of binary extensions, but also + discusses the various reasons why creating an extension module may be + desirable in the first place. + + +Creating extensions without third party tools +============================================= + +This section of the guide covers creating C and C++ extensions without +assistance from third party tools. It is intended primarily for creators +of those tools, rather than being a recommended way to create your own +C extensions. + .. toctree:: :maxdepth: 2 :numbered: @@ -29,4 +55,17 @@ For a detailed description of the whole Python/C API, see the separate newtypes.rst building.rst windows.rst + +Embedding the CPython runtime in a larger application +===================================================== + +Sometimes, rather than creating an extension that runs inside the Python +interpreter as the main application, it is desirable to instead embed +the CPython runtime inside a larger application. This section covers +some of the details involved in doing that successfully. + +.. toctree:: + :maxdepth: 2 + :numbered: + embedding.rst diff --git a/Doc/extending/newtypes.rst b/Doc/extending/newtypes.rst index 45b57211b679..d52070221ea7 100644 --- a/Doc/extending/newtypes.rst +++ b/Doc/extending/newtypes.rst @@ -1205,7 +1205,7 @@ Here is an example:: { if (strcmp(name, "data") == 0) { - return PyInt_FromLong(obj->data); + return PyLong_FromLong(obj->data); } PyErr_Format(PyExc_AttributeError, diff --git a/Doc/faq/design.rst b/Doc/faq/design.rst index 49e0c6d7deb8..9fdf8cb94981 100644 --- a/Doc/faq/design.rst +++ b/Doc/faq/design.rst @@ -49,7 +49,7 @@ Why are floating-point calculations so inaccurate? Users are often surprised by results like this:: >>> 1.2 - 1.0 - 0.199999999999999996 + 0.19999999999999996 and think it is a bug in Python. It's not. This has little to do with Python, and much more to do with how the underlying platform handles floating-point @@ -368,9 +368,9 @@ Can Python be compiled to machine code, C or some other language? Practical answer: -`Cython <http://cython.org/>`_ and `Pyrex <http://www.cosc.canterbury.ac.nz/~greg/python/Pyrex/>`_ +`Cython <http://cython.org/>`_ and `Pyrex <http://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/>`_ compile a modified version of Python with optional annotations into C -extensions. `Weave <http://www.scipy.org/Weave>`_ makes it easy to +extensions. `Weave <http://docs.scipy.org/doc/scipy-dev/reference/tutorial/weave.html>`_ makes it easy to intermingle Python and C code in various ways to increase performance. `Nuitka <http://www.nuitka.net/>`_ is an up-and-coming compiler of Python into C++ code, aiming to support the full Python language. @@ -386,13 +386,13 @@ mostly of calls into the Python run-time system, even for seemingly simple operations like ``x+1``. Several projects described in the Python newsgroup or at past `Python -conferences <http://python.org/community/workshops/>`_ have shown that this +conferences <https://www.python.org/community/workshops/>`_ have shown that this approach is feasible, although the speedups reached so far are only modest (e.g. 2x). Jython uses the same strategy for compiling to Java bytecode. (Jim Hugunin has demonstrated that in combination with whole-program analysis, speedups of 1000x are feasible for small demo programs. See the proceedings from the `1997 Python conference -<http://python.org/workshops/1997-10/proceedings/>`_ for more information.) +<http://legacy.python.org/workshops/1997-10/proceedings/>`_ for more information.) How does Python manage memory? @@ -664,62 +664,6 @@ before you write any of the actual code. Of course Python allows you to be sloppy and not write test cases at all. -Why are default values shared between objects? ----------------------------------------------- - -This type of bug commonly bites neophyte programmers. Consider this function:: - - def foo(mydict={}): # Danger: shared reference to one dict for all calls - ... compute something ... - mydict[key] = value - return mydict - -The first time you call this function, ``mydict`` contains a single item. The -second time, ``mydict`` contains two items because when ``foo()`` begins -executing, ``mydict`` starts out with an item already in it. - -It is often expected that a function call creates new objects for default -values. This is not what happens. Default values are created exactly once, when -the function is defined. If that object is changed, like the dictionary in this -example, subsequent calls to the function will refer to this changed object. - -By definition, immutable objects such as numbers, strings, tuples, and ``None``, -are safe from change. Changes to mutable objects such as dictionaries, lists, -and class instances can lead to confusion. - -Because of this feature, it is good programming practice to not use mutable -objects as default values. Instead, use ``None`` as the default value and -inside the function, check if the parameter is ``None`` and create a new -list/dictionary/whatever if it is. For example, don't write:: - - def foo(mydict={}): - ... - -but:: - - def foo(mydict=None): - if mydict is None: - mydict = {} # create a new dict for local namespace - -This feature can be useful. When you have a function that's time-consuming to -compute, a common technique is to cache the parameters and the resulting value -of each call to the function, and return the cached value if the same value is -requested again. This is called "memoizing", and can be implemented like this:: - - # Callers will never provide a third parameter for this function. - def expensive(arg1, arg2, _cache={}): - if (arg1, arg2) in _cache: - return _cache[(arg1, arg2)] - - # Calculate the value - result = ... expensive computation ... - _cache[(arg1, arg2)] = result # Store result in the cache - return result - -You could use a global variable containing a dictionary instead of the default -value; it's a matter of taste. - - Why is there no goto? --------------------- diff --git a/Doc/faq/extending.rst b/Doc/faq/extending.rst index a9a234b1ecae..02bba591cfd1 100644 --- a/Doc/faq/extending.rst +++ b/Doc/faq/extending.rst @@ -42,7 +42,7 @@ on what you're trying to do. .. XXX make sure these all work `Cython <http://cython.org>`_ and its relative `Pyrex -<http://www.cosc.canterbury.ac.nz/~greg/python/Pyrex/>`_ are compilers +<http://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/>`_ are compilers that accept a slightly modified form of Python and generate the corresponding C code. Cython and Pyrex make it possible to write an extension without having to learn Python's C API. @@ -50,11 +50,11 @@ to learn Python's C API. If you need to interface to some C or C++ library for which no Python extension currently exists, you can try wrapping the library's data types and functions with a tool such as `SWIG <http://www.swig.org>`_. `SIP -<http://www.riverbankcomputing.co.uk/software/sip/>`__, `CXX +<http://www.riverbankcomputing.co.uk/software/sip/intro>`__, `CXX <http://cxx.sourceforge.net/>`_ `Boost <http://www.boost.org/libs/python/doc/index.html>`_, or `Weave -<http://www.scipy.org/Weave>`_ are also alternatives for wrapping -C++ libraries. +<http://docs.scipy.org/doc/scipy-dev/reference/tutorial/weave.html>`_ are also +alternatives for wrapping C++ libraries. How can I execute arbitrary Python statements from C? @@ -95,8 +95,8 @@ To test the type of an object, first make sure it isn't *NULL*, and then use There is also a high-level API to Python objects which is provided by the so-called 'abstract' interface -- read ``Include/abstract.h`` for further details. It allows interfacing with any kind of Python sequence using calls -like :c:func:`PySequence_Length`, :c:func:`PySequence_GetItem`, etc.) as well -as many other useful protocols such as numbers (:c:func:`PyNumber_Index` et. +like :c:func:`PySequence_Length`, :c:func:`PySequence_GetItem`, etc. as well +as many other useful protocols such as numbers (:c:func:`PyNumber_Index` et al.) and mappings in the PyMapping APIs. diff --git a/Doc/faq/general.rst b/Doc/faq/general.rst index 9a893eca2f13..e3ea96264795 100644 --- a/Doc/faq/general.rst +++ b/Doc/faq/general.rst @@ -25,7 +25,7 @@ Finally, Python is portable: it runs on many Unix variants, on the Mac, and on Windows 2000 and later. To find out more, start with :ref:`tutorial-index`. The `Beginner's Guide to -Python <http://wiki.python.org/moin/BeginnersGuide>`_ links to other +Python <https://wiki.python.org/moin/BeginnersGuide>`_ links to other introductory tutorials and resources for learning Python. @@ -36,11 +36,11 @@ The Python Software Foundation is an independent non-profit organization that holds the copyright on Python versions 2.1 and newer. The PSF's mission is to advance open source technology related to the Python programming language and to publicize the use of Python. The PSF's home page is at -http://www.python.org/psf/. +https://www.python.org/psf/. Donations to the PSF are tax-exempt in the US. If you use Python and find it helpful, please contribute via `the PSF donation page -<http://www.python.org/psf/donations/>`_. +<https://www.python.org/psf/donations/>`_. Are there copyright restrictions on the use of Python? @@ -53,12 +53,12 @@ commercial use, to sell copies of Python in source or binary form (modified or unmodified), or to sell products that incorporate Python in some form. We would still like to know about all commercial use of Python, of course. -See `the PSF license page <http://python.org/psf/license/>`_ to find further +See `the PSF license page <https://docs.python.org/3/license/>`_ to find further explanations and a link to the full text of the license. The Python logo is trademarked, and in certain cases permission is required to use it. Consult `the Trademark Usage Policy -<http://www.python.org/psf/trademarks/>`__ for more information. +<https://www.python.org/psf/trademarks/>`__ for more information. Why was Python created in the first place? @@ -117,7 +117,7 @@ programming), software engineering (unit testing, logging, profiling, parsing Python code), and operating system interfaces (system calls, filesystems, TCP/IP sockets). Look at the table of contents for :ref:`library-index` to get an idea of what's available. A wide variety of third-party extensions are also -available. Consult `the Python Package Index <http://pypi.python.org/pypi>`_ to +available. Consult `the Python Package Index <https://pypi.python.org/pypi>`_ to find packages of interest to you. @@ -159,15 +159,16 @@ How do I obtain a copy of the Python source? -------------------------------------------- The latest Python source distribution is always available from python.org, at -http://www.python.org/download/. The latest development sources can be obtained -via anonymous Mercurial access at http://hg.python.org/cpython. +https://www.python.org/download/. The latest development sources can be obtained +via anonymous Mercurial access at https://hg.python.org/cpython. The source distribution is a gzipped tar file containing the complete C source, Sphinx-formatted documentation, Python library modules, example programs, and several useful pieces of freely distributable software. The source will compile and run out of the box on most UNIX platforms. -Consult the `Developer FAQ <http://docs.python.org/devguide/faq>`__ for more +Consult the `Getting Started section of the Python Developer's Guide +<https://docs.python.org/devguide/setup.html>`__ for more information on getting the source code and compiling it. @@ -177,12 +178,12 @@ How do I get documentation on Python? .. XXX mention py3k The standard documentation for the current stable version of Python is available -at http://docs.python.org/. PDF, plain text, and downloadable HTML versions are -also available at http://docs.python.org/download.html. +at https://docs.python.org/3/. PDF, plain text, and downloadable HTML versions are +also available at https://docs.python.org/3/download.html. The documentation is written in reStructuredText and processed by `the Sphinx -documentation tool <http://sphinx.pocoo.org/>`__. The reStructuredText source -for the documentation is part of the Python source distribution. +documentation tool <http://sphinx-doc.org/>`__. The reStructuredText source for +the documentation is part of the Python source distribution. I've never programmed before. Is there a Python tutorial? @@ -191,7 +192,7 @@ I've never programmed before. Is there a Python tutorial? There are numerous tutorials and books available. The standard documentation includes :ref:`tutorial-index`. -Consult `the Beginner's Guide <http://wiki.python.org/moin/BeginnersGuide>`_ to +Consult `the Beginner's Guide <https://wiki.python.org/moin/BeginnersGuide>`_ to find information for beginning Python programmers, including lists of tutorials. @@ -199,7 +200,7 @@ Is there a newsgroup or mailing list devoted to Python? ------------------------------------------------------- There is a newsgroup, :newsgroup:`comp.lang.python`, and a mailing list, -`python-list <http://mail.python.org/mailman/listinfo/python-list>`_. The +`python-list <https://mail.python.org/mailman/listinfo/python-list>`_. The newsgroup and mailing list are gatewayed into each other -- if you can read news it's unnecessary to subscribe to the mailing list. :newsgroup:`comp.lang.python` is high-traffic, receiving hundreds of postings @@ -208,38 +209,38 @@ every day, and Usenet readers are often more able to cope with this volume. Announcements of new software releases and events can be found in comp.lang.python.announce, a low-traffic moderated list that receives about five postings per day. It's available as `the python-announce mailing list -<http://mail.python.org/mailman/listinfo/python-announce-list>`_. +<https://mail.python.org/mailman/listinfo/python-announce-list>`_. More info about other mailing lists and newsgroups -can be found at http://www.python.org/community/lists/. +can be found at https://www.python.org/community/lists/. How do I get a beta test version of Python? ------------------------------------------- -Alpha and beta releases are available from http://www.python.org/download/. All +Alpha and beta releases are available from https://www.python.org/download/. All releases are announced on the comp.lang.python and comp.lang.python.announce -newsgroups and on the Python home page at http://www.python.org/; an RSS feed of +newsgroups and on the Python home page at https://www.python.org/; an RSS feed of news is available. -You can also access the development version of Python through Subversion. See -http://docs.python.org/devguide/faq for details. +You can also access the development version of Python through Mercurial. See +https://docs.python.org/devguide/faq.html for details. How do I submit bug reports and patches for Python? --------------------------------------------------- To report a bug or submit a patch, please use the Roundup installation at -http://bugs.python.org/. +https://bugs.python.org/. You must have a Roundup account to report bugs; this makes it possible for us to contact you if we have follow-up questions. It will also enable Roundup to send you updates as we act on your bug. If you had previously used SourceForge to report bugs to Python, you can obtain your Roundup password through Roundup's -`password reset procedure <http://bugs.python.org/user?@template=forgotten>`_. +`password reset procedure <https://bugs.python.org/user?@template=forgotten>`_. For more information on how Python is developed, consult `the Python Developer's -Guide <http://docs.python.org/devguide/>`_. +Guide <https://docs.python.org/devguide/>`_. Are there any published articles about Python that I can reference? @@ -259,7 +260,7 @@ Are there any books on Python? ------------------------------ Yes, there are many, and more are being published. See the python.org wiki at -http://wiki.python.org/moin/PythonBooks for a list. +https://wiki.python.org/moin/PythonBooks for a list. You can also search online bookstores for "Python" and filter out the Monty Python references; or perhaps search for "Python" and "language". @@ -268,9 +269,14 @@ Python references; or perhaps search for "Python" and "language". Where in the world is www.python.org located? --------------------------------------------- -It's currently in Amsterdam, graciously hosted by `XS4ALL -<http://www.xs4all.nl>`_. Thanks to Thomas Wouters for his work in arranging -python.org's hosting. +The Python project's infrastructure is located all over the world. +`www.python.org <https://www.python.org>`_ is graciously hosted by `Rackspace +<http://www.rackspace.com>`_, with CDN caching provided by `Fastly +<https://www.fastly.com>`_. `Upfront Systems +<http://www.upfrontsystems.co.za>`_ hosts `bugs.python.org +<https://bugs.python.org>`_. Many other Python services like `the Wiki +<https://wiki.python.org>`_ are hosted by `Oregon State +University Open Source Lab <https://osuosl.org>`_. Why is it called Python? @@ -278,7 +284,7 @@ Why is it called Python? When he began implementing Python, Guido van Rossum was also reading the published scripts from `"Monty Python's Flying Circus" -<http://pythonline.com/>`__, a BBC comedy series from the 1970s. Van Rossum +<http://en.wikipedia.org/wiki/Monty_Python>`__, a BBC comedy series from the 1970s. Van Rossum thought he needed a name that was short, unique, and slightly mysterious, so he decided to call the language Python. @@ -307,7 +313,7 @@ guaranteed that interfaces will remain the same throughout a series of bugfix releases. The latest stable releases can always be found on the `Python download page -<http://python.org/download/>`_. There are two recommended production-ready +<https://www.python.org/download/>`_. There are two recommended production-ready versions at this point in time, because at the moment there are two branches of stable releases: 2.x and 3.x. Python 3.x may be less useful than 2.x, since currently there is more third party software available for Python 2 than for @@ -331,9 +337,9 @@ the group or even read it. Have any significant projects been done in Python? -------------------------------------------------- -See http://python.org/about/success for a list of projects that use Python. +See https://www.python.org/about/success for a list of projects that use Python. Consulting the proceedings for `past Python conferences -<http://python.org/community/workshops/>`_ will reveal contributions from many +<https://www.python.org/community/workshops/>`_ will reveal contributions from many different companies and organizations. High-profile Python projects include `the Mailman mailing list manager @@ -347,14 +353,14 @@ include Google, Yahoo, and Lucasfilm Ltd. What new developments are expected for Python in the future? ------------------------------------------------------------ -See http://www.python.org/dev/peps/ for the Python Enhancement Proposals +See https://www.python.org/dev/peps/ for the Python Enhancement Proposals (PEPs). PEPs are design documents describing a suggested new feature for Python, providing a concise technical specification and a rationale. Look for a PEP titled "Python X.Y Release Schedule", where X.Y is a version that hasn't been publicly released yet. New development is discussed on `the python-dev mailing list -<http://mail.python.org/mailman/listinfo/python-dev/>`_. +<https://mail.python.org/mailman/listinfo/python-dev/>`_. Is it reasonable to propose incompatible changes to Python? @@ -372,43 +378,6 @@ Providing a gradual upgrade path is necessary if a feature has to be changed. changes while minimizing disruption for users. -Is Python Y2K (Year 2000) Compliant? ------------------------------------- - -.. remove this question? - -As of August, 2003 no major problems have been reported and Y2K compliance seems -to be a non-issue. - -Python does very few date calculations and for those it does perform relies on -the C library functions. Python generally represents times either as seconds -since 1970 or as a ``(year, month, day, ...)`` tuple where the year is expressed -with four digits, which makes Y2K bugs unlikely. So as long as your C library -is okay, Python should be okay. Of course, it's possible that a particular -application written in Python makes assumptions about 2-digit years. - -Because Python is available free of charge, there are no absolute guarantees. -If there *are* unforeseen problems, liability is the user's problem rather than -the developers', and there is nobody you can sue for damages. The Python -copyright notice contains the following disclaimer: - - 4. PSF is making Python 2.3 available to Licensee on an "AS IS" - basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY - WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND DISCLAIMS ANY - REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR - PURPOSE OR THAT THE USE OF PYTHON 2.3 WILL NOT INFRINGE ANY THIRD PARTY - RIGHTS. - - 5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON - 2.3 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS - A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 2.3, - OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. - -The good news is that *if* you encounter a problem, you have full source -available to track it down and fix it. This is one advantage of an open source -programming environment. - - Is Python a good language for beginning programmers? ---------------------------------------------------- @@ -447,14 +416,25 @@ while they enter their program's source in another window. If they can't remember the methods for a list, they can do something like this:: >>> L = [] - >>> dir(L) - ['append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', + >>> dir(L) # doctest: +NORMALIZE_WHITESPACE + ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', + '__dir__', '__doc__', '__eq__', '__format__', '__ge__', + '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', + '__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__', + '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', + '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', + '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', + 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort'] + >>> [d for d in dir(L) if '__' not in d] + ['append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort'] + >>> help(L.append) Help on built-in function append: - + <BLANKLINE> append(...) - L.append(object) -- append object to end + L.append(object) -> None -- append object to end + <BLANKLINE> >>> L.append(1) >>> L [1] @@ -467,8 +447,9 @@ that is written in Python using Tkinter. PythonWin is a Windows-specific IDE. Emacs users will be happy to know that there is a very good Python mode for Emacs. All of these programming environments provide syntax highlighting, auto-indenting, and access to the interactive interpreter while coding. Consult -http://www.python.org/editors/ for a full list of Python editing environments. +`the Python wiki <https://wiki.python.org/moin/PythonEditors>`_ for a full list +of Python editing environments. If you want to discuss Python's use in education, you may be interested in joining `the edu-sig mailing list -<http://python.org/community/sigs/current/edu-sig>`_. +<https://www.python.org/community/sigs/current/edu-sig>`_. diff --git a/Doc/faq/gui.rst b/Doc/faq/gui.rst index 5827f28c3bdc..f130d33cae9b 100644 --- a/Doc/faq/gui.rst +++ b/Doc/faq/gui.rst @@ -29,17 +29,17 @@ Tkinter Standard builds of Python include an object-oriented interface to the Tcl/Tk widget set, called :ref:`tkinter <Tkinter>`. This is probably the easiest to install (since it comes included with most -`binary distributions <http://www.python.org/download/>`_ of Python) and use. +`binary distributions <https://www.python.org/download/>`_ of Python) and use. For more info about Tk, including pointers to the source, see the `Tcl/Tk home page <http://www.tcl.tk>`_. Tcl/Tk is fully portable to the -MacOS, Windows, and Unix platforms. +Mac OS X, Windows, and Unix platforms. wxWidgets --------- wxWidgets (http://www.wxwidgets.org) is a free, portable GUI class library written in C++ that provides a native look and feel on a -number of platforms, with Windows, MacOS X, GTK, X11, all listed as +number of platforms, with Windows, Mac OS X, GTK, X11, all listed as current stable targets. Language bindings are available for a number of languages including Python, Perl, Ruby, etc. @@ -58,14 +58,14 @@ Qt --- There are bindings available for the Qt toolkit (using either `PyQt -<http://www.riverbankcomputing.co.uk/software/pyqt/>`_ or `PySide -<http://www.pyside.org/>`_) and for KDE (`PyKDE <http://www.riverbankcomputing.co.uk/software/pykde/intro>`__). +<http://www.riverbankcomputing.co.uk/software/pyqt/intro>`_ or `PySide +<http://www.pyside.org/>`_) and for KDE (`PyKDE <https://techbase.kde.org/Development/Languages/Python>`__). PyQt is currently more mature than PySide, but you must buy a PyQt license from `Riverbank Computing <http://www.riverbankcomputing.co.uk/software/pyqt/license>`_ if you want to write proprietary applications. PySide is free for all applications. Qt 4.5 upwards is licensed under the LGPL license; also, commercial licenses -are available from `Nokia <http://qt.nokia.com/>`_. +are available from `The Qt Company <http://www.qt.io/licensing/>`_. Gtk+ ---- @@ -102,13 +102,9 @@ For OpenGL bindings, see `PyOpenGL <http://pyopengl.sourceforge.net>`_. What platform-specific GUI toolkits exist for Python? ======================================================== -`The Mac port <http://python.org/download/mac>`_ by Jack Jansen has a rich and -ever-growing set of modules that support the native Mac toolbox calls. The port -supports MacOS X's Carbon libraries. - By installing the `PyObjc Objective-C bridge -<http://pyobjc.sourceforge.net>`_, Python programs can use MacOS X's -Cocoa libraries. See the documentation that comes with the Mac port. +<https://pythonhosted.org/pyobjc/>`_, Python programs can use Mac OS X's +Cocoa libraries. :ref:`Pythonwin <windows-faq>` by Mark Hammond includes an interface to the Microsoft Foundation Classes and a Python programming environment diff --git a/Doc/faq/installed.rst b/Doc/faq/installed.rst index efec9bf7910a..42296533e26f 100644 --- a/Doc/faq/installed.rst +++ b/Doc/faq/installed.rst @@ -11,7 +11,7 @@ language because Python is easy to learn, but it's also used by professional software developers at places such as Google, NASA, and Lucasfilm Ltd. If you wish to learn more about Python, start with the `Beginner's Guide to -Python <http://wiki.python.org/moin/BeginnersGuide>`_. +Python <https://wiki.python.org/moin/BeginnersGuide>`_. Why is Python installed on my machine? diff --git a/Doc/faq/library.rst b/Doc/faq/library.rst index 8bd774bdce20..d71a9b47fbd7 100644 --- a/Doc/faq/library.rst +++ b/Doc/faq/library.rst @@ -19,7 +19,7 @@ standard library module. (Eventually you'll learn what's in the standard library and will be able to skip this step.) For third-party packages, search the `Python Package Index -<http://pypi.python.org/pypi>`_ or try `Google <http://www.google.com>`_ or +<https://pypi.python.org/pypi>`_ or try `Google <https://www.google.com>`_ or another Web search engine. Searching for "Python" plus a keyword or two for your topic of interest will usually find something helpful. @@ -181,8 +181,8 @@ How do I create documentation from doc strings? The :mod:`pydoc` module can create HTML from the doc strings in your Python source code. An alternative for creating API documentation purely from -docstrings is `epydoc <http://epydoc.sf.net/>`_. `Sphinx -<http://sphinx.pocoo.org>`_ can also include docstring content. +docstrings is `epydoc <http://epydoc.sourceforge.net/>`_. `Sphinx +<http://sphinx-doc.org>`_ can also include docstring content. How do I get a single keypress at a time? @@ -513,6 +513,7 @@ For data that is more regular (e.g. a homogeneous list of ints or floats), you can also use the :mod:`array` module. .. note:: + To read and write binary data, it is mandatory to open the file in binary mode (here, passing ``"rb"`` to :func:`open`). If you use ``"r"`` instead (the default), the file will be open in text mode @@ -606,7 +607,7 @@ use ``p.read(n)``. "expect" library. A Python extension that interfaces to expect is called "expy" and available from http://expectpy.sourceforge.net. A pure Python solution that works like expect is `pexpect - <http://pypi.python.org/pypi/pexpect/>`_. + <https://pypi.python.org/pypi/pexpect/>`_. How do I access the serial (RS232) port? @@ -662,7 +663,7 @@ and client-side web systems. .. XXX check if wiki page is still up to date A summary of available frameworks is maintained by Paul Boddie at -http://wiki.python.org/moin/WebProgramming . +https://wiki.python.org/moin/WebProgramming\ . Cameron Laird maintains a useful set of pages about Python web technologies at http://phaseit.net/claird/comp.lang.python/web_python. @@ -705,7 +706,7 @@ What module should I use to help with generating HTML? .. XXX add modern template languages You can find a collection of useful links on the `Web Programming wiki page -<http://wiki.python.org/moin/WebProgramming>`_. +<https://wiki.python.org/moin/WebProgramming>`_. How do I send mail from a Python script? @@ -772,7 +773,7 @@ socket to select to check if it's writable. .. note:: The :mod:`asyncore` module presents a framework-like approach to the problem of writing non-blocking networking code. - The third-party `Twisted <http://twistedmatrix.com/>`_ library is + The third-party `Twisted <https://twistedmatrix.com/trac/>`_ library is a popular and feature-rich alternative. @@ -791,7 +792,7 @@ database. Support for most relational databases is available. See the `DatabaseProgramming wiki page -<http://wiki.python.org/moin/DatabaseProgramming>`_ for details. +<https://wiki.python.org/moin/DatabaseProgramming>`_ for details. How do you implement persistent objects in Python? diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst index ac12da3d7476..1a71c47cb83c 100644 --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -23,15 +23,14 @@ for pdb as an example. The IDLE interactive development environment, which is part of the standard Python distribution (normally available as Tools/scripts/idle), includes a -graphical debugger. There is documentation for the IDLE debugger at -http://www.python.org/idle/doc/idle2.html#Debugger. +graphical debugger. PythonWin is a Python IDE that includes a GUI debugger based on pdb. The Pythonwin debugger colors breakpoints and has quite a few cool features such as debugging non-Pythonwin programs. Pythonwin is available as part of the `Python for Windows Extensions <http://sourceforge.net/projects/pywin32/>`__ project and as a part of the ActivePython distribution (see -http://www.activestate.com/Products/ActivePython/index.html). +http://www.activestate.com/activepython\ ). `Boa Constructor <http://boa-constructor.sourceforge.net/>`_ is an IDE and GUI builder that uses wxWidgets. It offers visual frame creation and manipulation, @@ -39,7 +38,7 @@ an object inspector, many views on the source like object browsers, inheritance hierarchies, doc string generated html documentation, an advanced debugger, integrated help, and Zope support. -`Eric <http://www.die-offenbachs.de/eric/index.html>`_ is an IDE built on PyQt +`Eric <http://eric-ide.python-projects.org/>`_ is an IDE built on PyQt and the Scintilla editing component. Pydb is a version of the standard Python debugger pdb, modified for use with DDD @@ -51,7 +50,8 @@ There are a number of commercial Python IDEs that include graphical debuggers. They include: * Wing IDE (http://wingware.com/) -* Komodo IDE (http://www.activestate.com/Products/Komodo) +* Komodo IDE (http://komodoide.com/) +* PyCharm (https://www.jetbrains.com/pycharm/) Is there a tool to help find bugs or perform static analysis? @@ -61,7 +61,7 @@ Yes. PyChecker is a static analysis tool that finds bugs in Python source code and warns about code complexity and style. You can get PyChecker from -http://pychecker.sf.net. +http://pychecker.sourceforge.net/. `Pylint <http://www.logilab.org/projects/pylint>`_ is another tool that checks if a module satisfies a coding standard, and also makes it possible to write @@ -69,8 +69,7 @@ plug-ins to add a custom feature. In addition to the bug checking that PyChecker performs, Pylint offers some additional features such as checking line length, whether variable names are well-formed according to your coding standard, whether declared interfaces are fully implemented, and more. -http://www.logilab.org/card/pylint_manual provides a full list of Pylint's -features. +http://docs.pylint.org/ provides a full list of Pylint's features. How can I create a stand-alone binary from a Python script? @@ -101,13 +100,7 @@ which don't. One is Thomas Heller's py2exe (Windows only) at http://www.py2exe.org/ -Another is Christian Tismer's `SQFREEZE <http://starship.python.net/crew/pirx>`_ -which appends the byte code to a specially-prepared Python interpreter that can -find the byte code in the executable. - -Other tools include Fredrik Lundh's `Squeeze -<http://www.pythonware.com/products/python/squeeze>`_ and Anthony Tuininga's -`cx_Freeze <http://starship.python.net/crew/atuining/cx_Freeze/index.html>`_. +Another tool is Anthony Tuininga's `cx_Freeze <http://cx-freeze.sourceforge.net/>`_. Are there coding standards or a style guide for Python programs? @@ -292,9 +285,8 @@ What are the "best practices" for using import in a module? ----------------------------------------------------------- In general, don't use ``from modulename import *``. Doing so clutters the -importer's namespace. Some people avoid this idiom even with the few modules -that were designed to be imported in this manner. Modules designed in this -manner include :mod:`tkinter`, and :mod:`threading`. +importer's namespace, and makes it much harder for linters to detect undefined +names. Import modules at the top of a file. Doing so makes it clear what other modules your code requires and avoids questions of whether the module name is in scope. @@ -308,11 +300,6 @@ It's good practice if you import modules in the following order: directory) -- e.g. mx.DateTime, ZODB, PIL.Image, etc. 3. locally-developed modules -Never use relative package imports. If you're writing code that's in the -``package.sub.m1`` module and want to import ``package.sub.m2``, do not just -write ``from . import m2``, even though it's legal. Write ``from package.sub -import m2`` instead. See :pep:`328` for details. - It is sometimes necessary to move imports to a function or class to avoid problems with circular imports. Gordon McMillan says: @@ -343,13 +330,61 @@ module, but loading a module multiple times is virtually free, costing only a couple of dictionary lookups. Even if the module name has gone out of scope, the module is probably available in :data:`sys.modules`. -If only instances of a specific class use a module, then it is reasonable to -import the module in the class's ``__init__`` method and then assign the module -to an instance variable so that the module is always available (via that -instance variable) during the life of the object. Note that to delay an import -until the class is instantiated, the import must be inside a method. Putting -the import inside the class but outside of any method still causes the import to -occur when the module is initialized. + +Why are default values shared between objects? +---------------------------------------------- + +This type of bug commonly bites neophyte programmers. Consider this function:: + + def foo(mydict={}): # Danger: shared reference to one dict for all calls + ... compute something ... + mydict[key] = value + return mydict + +The first time you call this function, ``mydict`` contains a single item. The +second time, ``mydict`` contains two items because when ``foo()`` begins +executing, ``mydict`` starts out with an item already in it. + +It is often expected that a function call creates new objects for default +values. This is not what happens. Default values are created exactly once, when +the function is defined. If that object is changed, like the dictionary in this +example, subsequent calls to the function will refer to this changed object. + +By definition, immutable objects such as numbers, strings, tuples, and ``None``, +are safe from change. Changes to mutable objects such as dictionaries, lists, +and class instances can lead to confusion. + +Because of this feature, it is good programming practice to not use mutable +objects as default values. Instead, use ``None`` as the default value and +inside the function, check if the parameter is ``None`` and create a new +list/dictionary/whatever if it is. For example, don't write:: + + def foo(mydict={}): + ... + +but:: + + def foo(mydict=None): + if mydict is None: + mydict = {} # create a new dict for local namespace + +This feature can be useful. When you have a function that's time-consuming to +compute, a common technique is to cache the parameters and the resulting value +of each call to the function, and return the cached value if the same value is +requested again. This is called "memoizing", and can be implemented like this:: + + # Callers will never provide a third parameter for this function. + def expensive(arg1, arg2, _cache={}): + if (arg1, arg2) in _cache: + return _cache[(arg1, arg2)] + + # Calculate the value + result = ... expensive computation ... + _cache[(arg1, arg2)] = result # Store result in the cache + return result + +You could use a global variable containing a dictionary instead of the default +value; it's a matter of taste. How can I pass optional or keyword parameters from one function to another? @@ -392,6 +427,81 @@ arguments a function can accept. For example, given the function definition:: the values ``42``, ``314``, and ``somevar`` are arguments. +Why did changing list 'y' also change list 'x'? +------------------------------------------------ + +If you wrote code like:: + + >>> x = [] + >>> y = x + >>> y.append(10) + >>> y + [10] + >>> x + [10] + +you might be wondering why appending an element to ``y`` changed ``x`` too. + +There are two factors that produce this result: + +1) Variables are simply names that refer to objects. Doing ``y = x`` doesn't + create a copy of the list -- it creates a new variable ``y`` that refers to + the same object ``x`` refers to. This means that there is only one object + (the list), and both ``x`` and ``y`` refer to it. +2) Lists are :term:`mutable`, which means that you can change their content. + +After the call to :meth:`~list.append`, the content of the mutable object has +changed from ``[]`` to ``[10]``. Since both the variables refer to the same +object, using either name accesses the modified value ``[10]``. + +If we instead assign an immutable object to ``x``:: + + >>> x = 5 # ints are immutable + >>> y = x + >>> x = x + 1 # 5 can't be mutated, we are creating a new object here + >>> x + 6 + >>> y + 5 + +we can see that in this case ``x`` and ``y`` are not equal anymore. This is +because integers are :term:`immutable`, and when we do ``x = x + 1`` we are not +mutating the int ``5`` by incrementing its value; instead, we are creating a +new object (the int ``6``) and assigning it to ``x`` (that is, changing which +object ``x`` refers to). After this assignment we have two objects (the ints +``6`` and ``5``) and two variables that refer to them (``x`` now refers to +``6`` but ``y`` still refers to ``5``). + +Some operations (for example ``y.append(10)`` and ``y.sort()``) mutate the +object, whereas superficially similar operations (for example ``y = y + [10]`` +and ``sorted(y)``) create a new object. In general in Python (and in all cases +in the standard library) a method that mutates an object will return ``None`` +to help avoid getting the two types of operations confused. So if you +mistakenly write ``y.sort()`` thinking it will give you a sorted copy of ``y``, +you'll instead end up with ``None``, which will likely cause your program to +generate an easily diagnosed error. + +However, there is one class of operations where the same operation sometimes +has different behaviors with different types: the augmented assignment +operators. For example, ``+=`` mutates lists but not tuples or ints (``a_list ++= [1, 2, 3]`` is equivalent to ``a_list.extend([1, 2, 3])`` and mutates +``a_list``, whereas ``some_tuple += (1, 2, 3)`` and ``some_int += 1`` create +new objects). + +In other words: + +* If we have a mutable object (:class:`list`, :class:`dict`, :class:`set`, + etc.), we can use some specific operations to mutate it and all the variables + that refer to it will see the change. +* If we have an immutable object (:class:`str`, :class:`int`, :class:`tuple`, + etc.), all the variables that refer to it will always see the same value, + but operations that transform that value into a new value always return a new + object. + +If you want to know if two variables refer to the same object or not, you can +use the :keyword:`is` operator, or the built-in function :func:`id`. + + How do I write a function with output parameters (call by reference)? --------------------------------------------------------------------- @@ -711,7 +821,7 @@ By default, these interpret the number as decimal, so that ``int('0144') == 144`` and ``int('0x144')`` raises :exc:`ValueError`. ``int(string, base)`` takes the base to convert from as a second optional argument, so ``int('0x144', 16) == 324``. If the base is specified as 0, the number is interpreted using Python's -rules: a leading '0' indicates octal, and '0x' indicates a hex number. +rules: a leading '0o' indicates octal, and '0x' indicates a hex number. Do not use the built-in function :func:`eval` if all you need is to convert strings to numbers. :func:`eval` will be significantly slower and it presents a @@ -732,7 +842,7 @@ To convert, e.g., the number 144 to the string '144', use the built-in type constructor :func:`str`. If you want a hexadecimal or octal representation, use the built-in functions :func:`hex` or :func:`oct`. For fancy formatting, see the :ref:`string-formatting` section, e.g. ``"{:04d}".format(144)`` yields -``'0144'`` and ``"{:.3f}".format(1/3)`` yields ``'0.333'``. +``'0144'`` and ``"{:.3f}".format(1.0/3.0)`` yields ``'0.333'``. How do I modify a string in place? @@ -903,7 +1013,7 @@ performance levels: as builtins and some extension types. For example, be sure to use either the :meth:`list.sort` built-in method or the related :func:`sorted` function to do sorting (and see the - `sorting mini-HOWTO <http://wiki.python.org/moin/HowTo/Sorting>`_ for examples + `sorting mini-HOWTO <https://wiki.python.org/moin/HowTo/Sorting>`_ for examples of moderately advanced usage). * Abstractions tend to create indirections and force the interpreter to work @@ -923,7 +1033,7 @@ yourself. .. seealso:: The wiki page devoted to `performance tips - <http://wiki.python.org/moin/PythonSpeed/PerformanceTips>`_. + <https://wiki.python.org/moin/PythonSpeed/PerformanceTips>`_. .. _efficient_string_concatenation: @@ -1008,7 +1118,7 @@ How do you remove duplicates from a list? See the Python Cookbook for a long discussion of many ways to do this: - http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52560 + http://code.activestate.com/recipes/52560/ If you don't mind reordering the list, sort it and then scan from the end of the list, deleting duplicates as you go:: @@ -1103,6 +1213,7 @@ Use a list comprehension:: result = [obj.method() for obj in mylist] +.. _faq-augmented-assignment-tuple-error: Why does a_tuple[i] += ['item'] raise an exception when the addition works? --------------------------------------------------------------------------- @@ -1607,26 +1718,34 @@ Modules How do I create a .pyc file? ---------------------------- -When a module is imported for the first time (or when the source is more recent -than the current compiled file) a ``.pyc`` file containing the compiled code -should be created in the same directory as the ``.py`` file. +When a module is imported for the first time (or when the source file has +changed since the current compiled file was created) a ``.pyc`` file containing +the compiled code should be created in a ``__pycache__`` subdirectory of the +directory containing the ``.py`` file. The ``.pyc`` file will have a +filename that starts with the same name as the ``.py`` file, and ends with +``.pyc``, with a middle component that depends on the particular ``python`` +binary that created it. (See :pep:`3147` for details.) -One reason that a ``.pyc`` file may not be created is permissions problems with -the directory. This can happen, for example, if you develop as one user but run -as another, such as if you are testing with a web server. Creation of a .pyc -file is automatic if you're importing a module and Python has the ability -(permissions, free space, etc...) to write the compiled module back to the -directory. +One reason that a ``.pyc`` file may not be created is a permissions problem +with the directory containing the source file, meaning that the ``__pycache__`` +subdirectory cannot be created. This can happen, for example, if you develop as +one user but run as another, such as if you are testing with a web server. + +Unless the :envvar:`PYTHONDONTWRITEBYTECODE` environment variable is set, +creation of a .pyc file is automatic if you're importing a module and Python +has the ability (permissions, free space, etc...) to create a ``__pycache__`` +subdirectory and write the compiled module to that subdirectory. Running Python on a top level script is not considered an import and no ``.pyc`` will be created. For example, if you have a top-level module -``foo.py`` that imports another module ``xyz.py``, when you run ``foo``, -``xyz.pyc`` will be created since ``xyz`` is imported, but no ``foo.pyc`` file -will be created since ``foo.py`` isn't being imported. +``foo.py`` that imports another module ``xyz.py``, when you run ``foo`` (by +typing ``python foo.py`` as a shell command), a ``.pyc`` will be created for +``xyz`` because ``xyz`` is imported, but no ``.pyc`` file will be created for +``foo`` since ``foo.py`` isn't being imported. -If you need to create ``foo.pyc`` -- that is, to create a ``.pyc`` file for a module -that is not imported -- you can, using the :mod:`py_compile` and -:mod:`compileall` modules. +If you need to create a ``.pyc`` file for ``foo`` -- that is, to create a +``.pyc`` file for a module that is not imported -- you can, using the +:mod:`py_compile` and :mod:`compileall` modules. The :mod:`py_compile` module can manually compile any module. One way is to use the ``compile()`` function in that module interactively:: @@ -1634,8 +1753,9 @@ the ``compile()`` function in that module interactively:: >>> import py_compile >>> py_compile.compile('foo.py') # doctest: +SKIP -This will write the ``.pyc`` to the same location as ``foo.py`` (or you can -override that with the optional parameter ``cfile``). +This will write the ``.pyc`` to a ``__pycache__`` subdirectory in the same +location as ``foo.py`` (or you can override that with the optional parameter +``cfile``). You can also automatically compile all files in a directory or directories using the :mod:`compileall` module. You can do it from the shell prompt by running @@ -1720,19 +1840,10 @@ These solutions are not mutually exclusive. __import__('x.y.z') returns <module 'x'>; how do I get z? --------------------------------------------------------- -Try:: - - __import__('x.y.z').y.z - -For more realistic situations, you may have to do something like :: - - m = __import__(s) - for i in s.split(".")[1:]: - m = getattr(m, i) - -See :mod:`importlib` for a convenience function called -:func:`~importlib.import_module`. +Consider using the convenience function :func:`~importlib.import_module` from +:mod:`importlib` instead:: + z = importlib.import_module('x.y.z') When I edit an imported module and reimport it, the changes don't show up. Why does this happen? diff --git a/Doc/faq/windows.rst b/Doc/faq/windows.rst index 651ba2268306..7cac8a9739de 100644 --- a/Doc/faq/windows.rst +++ b/Doc/faq/windows.rst @@ -31,7 +31,7 @@ obvious; otherwise, you might need a little more guidance. .. |Python Development on XP| image:: python-video-icon.png .. _`Python Development on XP`: - http://www.showmedo.com/videos/series?name=pythonOzsvaldPyNewbieSeries + http://showmedo.com/videotutorials/series?name=pythonOzsvaldPyNewbieSeries Unless you use some sort of integrated development environment, you will end up *typing* Windows commands into what is variously referred to as a "DOS window" @@ -78,7 +78,7 @@ by entering a few expressions of your choice and seeing the results:: >>> print("Hello") Hello >>> "Hello" * 3 - HelloHelloHello + 'HelloHelloHello' Many people use the interactive mode as a convenient yet highly programmable calculator. When you want to end your interactive Python session, hold the Ctrl @@ -105,7 +105,7 @@ gives you a message like:: .. |Adding Python to DOS Path| image:: python-video-icon.png .. _`Adding Python to DOS Path`: - http://showmedo.com/videos/video?name=960000&fromSeriesID=96 + http://showmedo.com/videotutorials/video?name=960000&fromSeriesID=96 or:: @@ -170,18 +170,20 @@ offender. How do I make an executable from a Python script? ------------------------------------------------- -See http://www.py2exe.org/ for a distutils extension that allows you +See http://cx-freeze.sourceforge.net/ for a distutils extension that allows you to create console and GUI executables from Python code. +`py2exe <http://www.py2exe.org/>`_, the most popular extension for building +Python 2.x-based executables, does not yet support Python 3 but a version that +does is in development. + Is a ``*.pyd`` file the same as a DLL? -------------------------------------- -.. XXX update for py3k (PyInit_foo) - Yes, .pyd files are dll's, but there are a few differences. If you have a DLL -named ``foo.pyd``, then it must have a function ``initfoo()``. You can then +named ``foo.pyd``, then it must have a function ``PyInit_foo()``. You can then write Python "import foo", and Python will search for foo.pyd (as well as -foo.py, foo.pyc) and if it finds it, will attempt to call ``initfoo()`` to +foo.py, foo.pyc) and if it finds it, will attempt to call ``PyInit_foo()`` to initialize it. You do not link your .exe with foo.lib, as that would cause Windows to require the DLL to be present. @@ -247,7 +249,7 @@ Embedding the Python interpreter in a Windows app can be summarized as follows: ... Py_Initialize(); // Initialize Python. initmyAppc(); // Initialize (import) the helper class. - PyRun_SimpleString("import myApp") ; // Import the shadow class. + PyRun_SimpleString("import myApp"); // Import the shadow class. 5. There are two problems with Python's C API which will become apparent if you use a compiler other than MSVC, the compiler used to build pythonNN.dll. diff --git a/Doc/glossary.rst b/Doc/glossary.rst index df470515d61c..578fd113f889 100644 --- a/Doc/glossary.rst +++ b/Doc/glossary.rst @@ -76,7 +76,14 @@ Glossary BDFL Benevolent Dictator For Life, a.k.a. `Guido van Rossum - <http://www.python.org/~guido/>`_, Python's creator. + <https://www.python.org/~guido/>`_, Python's creator. + + binary file + A :term:`file object` able to read and write + :term:`bytes-like objects <bytes-like object>`. + + .. seealso:: + A :term:`text file` reads and writes :class:`str` objects. bytes-like object An object that supports the :ref:`bufferobjects`, like :class:`bytes`, @@ -134,7 +141,7 @@ Glossary CPython The canonical implementation of the Python programming language, as - distributed on `python.org <http://python.org>`_. The term "CPython" + distributed on `python.org <https://www.python.org>`_. The term "CPython" is used when necessary to distinguish this implementation from others such as Jython or IronPython. @@ -225,10 +232,11 @@ Glossary etc.). File objects are also called :dfn:`file-like objects` or :dfn:`streams`. - There are actually three categories of file objects: raw binary files, - buffered binary files and text files. Their interfaces are defined in the - :mod:`io` module. The canonical way to create a file object is by using - the :func:`open` function. + There are actually three categories of file objects: raw + :term:`binary files <binary file>`, buffered + :term:`binary files <binary file>` and :term:`text files <text file>`. + Their interfaces are defined in the :mod:`io` module. The canonical + way to create a file object is by using the :func:`open` function. file-like object A synonym for :term:`file object`. @@ -284,7 +292,7 @@ Glossary generator A function which returns an iterator. It looks like a normal function except that it contains :keyword:`yield` statements for producing a series - a values usable in a for-loop or that can be retrieved one at a time with + of values usable in a for-loop or that can be retrieved one at a time with the :func:`next` function. Each :keyword:`yield` temporarily suspends processing, remembering the location execution state (including local variables and pending try-statements). When the generator resumes, it @@ -347,8 +355,8 @@ Glossary All of Python's immutable built-in objects are hashable, while no mutable containers (such as lists or dictionaries) are. Objects which are instances of user-defined classes are hashable by default; they all - compare unequal (except with themselves), and their hash value is their - :func:`id`. + compare unequal (except with themselves), and their hash value is derived + from their :func:`id`. IDLE An Integrated Development Environment for Python. IDLE is a basic editor @@ -394,6 +402,19 @@ Glossary than compiled ones, though their programs generally also run more slowly. See also :term:`interactive`. + interpreter shutdown + When asked to shut down, the Python interpreter enters a special phase + where it gradually releases all allocated resources, such as modules + and various critical internal structures. It also makes several calls + to the :term:`garbage collector <garbage collection>`. This can trigger + the execution of code in user-defined destructors or weakref callbacks. + Code executed during the shutdown phase can encounter various + exceptions as the resources it relies on may not function anymore + (common examples are library modules or the warnings machinery). + + The main reason for interpreter shutdown is that the ``__main__`` module + or the script being run has finished executing. + iterable An object capable of returning its members one at a time. Examples of iterables include all sequence types (such as :class:`list`, :class:`str`, @@ -436,12 +457,13 @@ Glossary A number of tools in Python accept key functions to control how elements are ordered or grouped. They include :func:`min`, :func:`max`, - :func:`sorted`, :meth:`list.sort`, :func:`heapq.nsmallest`, - :func:`heapq.nlargest`, and :func:`itertools.groupby`. + :func:`sorted`, :meth:`list.sort`, :func:`heapq.merge`, + :func:`heapq.nsmallest`, :func:`heapq.nlargest`, and + :func:`itertools.groupby`. There are several ways to create a key function. For example. the :meth:`str.lower` method can serve as a key function for case insensitive - sorts. Alternatively, an ad-hoc key function can be built from a + sorts. Alternatively, a key function can be built from a :keyword:`lambda` expression such as ``lambda r: (r[0], r[2])``. Also, the :mod:`operator` module provides three key function constructors: :func:`~operator.attrgetter`, :func:`~operator.itemgetter`, and @@ -522,7 +544,7 @@ Glossary method resolution order Method Resolution Order is the order in which base classes are searched for a member during lookup. See `The Python 2.3 Method Resolution Order - <http://www.python.org/download/releases/2.3/mro/>`_. + <https://www.python.org/download/releases/2.3/mro/>`_. module An object that serves as an organizational unit of Python code. Modules @@ -531,6 +553,10 @@ Glossary See also :term:`package`. + module spec + A namespace containing the import-related information used to load a + module. + MRO See :term:`method resolution order`. @@ -771,6 +797,14 @@ Glossary mapping rather than a sequence because the lookups use arbitrary :term:`immutable` keys rather than integers. + The :class:`collections.abc.Sequence` abstract base class + defines a much richer interface that goes beyond just + :meth:`__getitem__` and :meth:`__len__`, adding :meth:`count`, + :meth:`index`, :meth:`__contains__`, and + :meth:`__reversed__`. Types that implement this expanded + interface can be registered explicitly using + :func:`~abc.register`. + single dispatch A form of :term:`generic function` dispatch where the implementation is chosen based on the type of a single argument. @@ -800,6 +834,17 @@ Glossary :meth:`~collections.somenamedtuple._asdict`. Examples of struct sequences include :data:`sys.float_info` and the return value of :func:`os.stat`. + text encoding + A codec which encodes Unicode strings to bytes. + + text file + A :term:`file object` able to read and write :class:`str` objects. + Often, a text file actually accesses a byte-oriented datastream + and handles the :term:`text encoding` automatically. + + .. seealso:: + A :term:`binary file` reads and write :class:`bytes` objects. + triple-quoted string A string which is bound by three instances of either a quotation mark (") or an apostrophe ('). While they don't provide any functionality @@ -820,7 +865,7 @@ Glossary recognized as ending a line: the Unix end-of-line convention ``'\n'``, the Windows convention ``'\r\n'``, and the old Macintosh convention ``'\r'``. See :pep:`278` and :pep:`3116`, as well as - :func:`str.splitlines` for an additional use. + :func:`bytes.splitlines` for an additional use. view The objects returned from :meth:`dict.keys`, :meth:`dict.values`, and @@ -829,6 +874,14 @@ Glossary dictionary view to become a full list use ``list(dictview)``. See :ref:`dict-views`. + virtual environment + A cooperatively isolated runtime environment that allows Python users + and applications to install and upgrade Python distribution packages + without interfering with the behaviour of other Python applications + running on the same system. + + See also :ref:`scripts-pyvenv` + virtual machine A computer defined entirely in software. Python's virtual machine executes the :term:`bytecode` emitted by the bytecode compiler. diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst new file mode 100644 index 000000000000..ca8e1cb87ba9 --- /dev/null +++ b/Doc/howto/clinic.rst @@ -0,0 +1,1686 @@ +********************** +Argument Clinic How-To +********************** + +:author: Larry Hastings + + +.. topic:: Abstract + + Argument Clinic is a preprocessor for CPython C files. + Its purpose is to automate all the boilerplate involved + with writing argument parsing code for "builtins". + This document shows you how to convert your first C + function to work with Argument Clinic, and then introduces + some advanced topics on Argument Clinic usage. + + Currently Argument Clinic is considered internal-only + for CPython. Its use is not supported for files outside + CPython, and no guarantees are made regarding backwards + compatibility for future versions. In other words: if you + maintain an external C extension for CPython, you're welcome + to experiment with Argument Clinic in your own code. But the + version of Argument Clinic that ships with CPython 3.5 *could* + be totally incompatible and break all your code. + +The Goals Of Argument Clinic +============================ + +Argument Clinic's primary goal +is to take over responsibility for all argument parsing code +inside CPython. This means that, when you convert a function +to work with Argument Clinic, that function should no longer +do any of its own argument parsing--the code generated by +Argument Clinic should be a "black box" to you, where CPython +calls in at the top, and your code gets called at the bottom, +with ``PyObject *args`` (and maybe ``PyObject *kwargs``) +magically converted into the C variables and types you need. + +In order for Argument Clinic to accomplish its primary goal, +it must be easy to use. Currently, working with CPython's +argument parsing library is a chore, requiring maintaining +redundant information in a surprising number of places. +When you use Argument Clinic, you don't have to repeat yourself. + +Obviously, no one would want to use Argument Clinic unless +it's solving their problem--and without creating new problems of +its own. +So it's paramount that Argument Clinic generate correct code. +It'd be nice if the code was faster, too, but at the very least +it should not introduce a major speed regression. (Eventually Argument +Clinic *should* make a major speedup possible--we could +rewrite its code generator to produce tailor-made argument +parsing code, rather than calling the general-purpose CPython +argument parsing library. That would make for the fastest +argument parsing possible!) + +Additionally, Argument Clinic must be flexible enough to +work with any approach to argument parsing. Python has +some functions with some very strange parsing behaviors; +Argument Clinic's goal is to support all of them. + +Finally, the original motivation for Argument Clinic was +to provide introspection "signatures" for CPython builtins. +It used to be, the introspection query functions would throw +an exception if you passed in a builtin. With Argument +Clinic, that's a thing of the past! + +One idea you should keep in mind, as you work with +Argument Clinic: the more information you give it, the +better job it'll be able to do. +Argument Clinic is admittedly relatively simple right +now. But as it evolves it will get more sophisticated, +and it should be able to do many interesting and smart +things with all the information you give it. + + +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:: + + % python3 Tools/clinic/clinic.py foo.c + +Argument Clinic will scan over the file looking for lines that +look exactly like this:: + + /*[clinic input] + +When it finds one, it reads everything up to a line that looks +exactly like this:: + + [clinic start generated code]*/ + +Everything in between these two lines is input for Argument Clinic. +All of these lines, including the beginning and ending comment +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:: + + /*[clinic input] + ... clinic input goes here ... + [clinic start generated code]*/ + ... clinic output goes here ... + /*[clinic end generated code: checksum=...]*/ + +If you run Argument Clinic on the same file a second time, Argument Clinic +will discard the old output and write out the new output with a fresh checksum +line. However, if the input hasn't changed, the output won't change either. + +You should never modify the output portion of an Argument Clinic block. Instead, +change the input until it produces the output you want. (That's the purpose of the +checksum--to detect if someone changed the output, as these edits would be lost +the next time Argument Clinic writes out fresh output.) + +For the sake of clarity, here's the terminology we'll use with Argument Clinic: + +* The first line of the comment (``/*[clinic input]``) is the *start line*. +* The last line of the initial comment (``[clinic start generated code]*/``) is the *end line*. +* The last line (``/*[clinic end generated code: checksum=...]*/``) is the *checksum line*. +* In between the start line and the end line is the *input*. +* In between the end line and the checksum line is the *output*. +* All the text collectively, from the start line to the checksum line inclusively, + is the *block*. (A block that hasn't been successfully processed by Argument + Clinic yet doesn't have output or a checksum line, but it's still considered + a block.) + + +Converting Your First Function +============================== + +The best way to get a sense of how Argument Clinic works is to +convert a function to work with it. Here, then, are the bare +minimum steps you'd need to follow to convert a function to +work with Argument Clinic. Note that for code you plan to +check in to CPython, you really should take the conversion farther, +using some of the advanced concepts you'll see later on in +the document (like "return converters" and "self converters"). +But we'll keep it simple for this walkthrough so you can learn. + +Let's dive in! + +0. Make sure you're working with a freshly updated checkout + of the CPython trunk. + +1. Find a Python builtin that calls either :c:func:`PyArg_ParseTuple` + or :c:func:`PyArg_ParseTupleAndKeywords`, and hasn't been converted + to work with Argument Clinic yet. + For my example I'm using ``_pickle.Pickler.dump()``. + +2. If the call to the ``PyArg_Parse`` function uses any of the + following format units:: + + O& + O! + es + es# + et + et# + + or if it has multiple calls to :c:func:`PyArg_ParseTuple`, + you should choose a different function. Argument Clinic *does* + support all of these scenarios. But these are advanced + topics--let's do something simpler for your first function. + + Also, if the function has multiple calls to :c:func:`PyArg_ParseTuple` + or :c:func:`PyArg_ParseTupleAndKeywords` where it supports different + types for the same argument, or if the function uses something besides + PyArg_Parse functions to parse its arguments, it probably + isn't suitable for conversion to Argument Clinic. Argument Clinic + doesn't support generic functions or polymorphic parameters. + +3. Add the following boilerplate above the function, creating our block:: + + /*[clinic input] + [clinic start generated code]*/ + +4. Cut the docstring and paste it in between the ``[clinic]`` lines, + removing all the junk that makes it a properly quoted C string. + When you're done you should have just the text, based at the left + margin, with no line wider than 80 characters. + (Argument Clinic will preserve indents inside the docstring.) + + If the old docstring had a first line that looked like a function + signature, throw that line away. (The docstring doesn't need it + anymore--when you use ``help()`` on your builtin in the future, + the first line will be built automatically based on the function's + signature.) + + Sample:: + + /*[clinic input] + Write a pickled representation of obj to the open file. + [clinic start generated code]*/ + +5. If your docstring doesn't have a "summary" line, Argument Clinic will + complain. So let's make sure it has one. The "summary" line should + be a paragraph consisting of a single 80-column line + at the beginning of the docstring. + + (Our example docstring consists solely of a summary line, so the sample + code doesn't have to change for this step.) + +6. Above the docstring, enter the name of the function, followed + by a blank line. This should be the Python name of the function, + and should be the full dotted path + to the function--it should start with the name of the module, + include any sub-modules, and if the function is a method on + a class it should include the class name too. + + Sample:: + + /*[clinic input] + _pickle.Pickler.dump + + Write a pickled representation of obj to the open file. + [clinic start generated code]*/ + +7. If this is the first time that module or class has been used with Argument + Clinic in this C file, + you must declare the module and/or class. Proper Argument Clinic hygiene + prefers declaring these in a separate block somewhere near the + top of the C file, in the same way that include files and statics go at + the top. (In our sample code we'll just show the two blocks next to + each other.) + + The name of the class and module should be the same as the one + seen by Python. Check the name defined in the :c:type:`PyModuleDef` + or :c:type:`PyTypeObject` as appropriate. + + When you declare a class, you must also specify two aspects of its type + in C: the type declaration you'd use for a pointer to an instance of + this class, and a pointer to the :c:type:`PyTypeObject` for this class. + + Sample:: + + /*[clinic input] + module _pickle + class _pickle.Pickler "PicklerObject *" "&Pickler_Type" + [clinic start generated code]*/ + + /*[clinic input] + _pickle.Pickler.dump + + Write a pickled representation of obj to the open file. + [clinic start generated code]*/ + + + + +8. Declare each of the parameters to the function. Each parameter + should get its own line. All the parameter lines should be + indented from the function name and the docstring. + + The general form of these parameter lines is as follows:: + + name_of_parameter: converter + + If the parameter has a default value, add that after the + converter:: + + name_of_parameter: converter = default_value + + Argument Clinic's support for "default values" is quite sophisticated; + please see :ref:`the section below on default values <default_values>` + for more information. + + Add a blank line below the parameters. + + What's a "converter"? It establishes both the type + of the variable used in C, and the method to convert the Python + value into a C value at runtime. + For now you're going to use what's called a "legacy converter"--a + convenience syntax intended to make porting old code into Argument + Clinic easier. + + For each parameter, copy the "format unit" for that + parameter from the ``PyArg_Parse()`` format argument and + specify *that* as its converter, as a quoted + string. ("format unit" is the formal name for the one-to-three + character substring of the ``format`` parameter that tells + the argument parsing function what the type of the variable + is and how to convert it. For more on format units please + see :ref:`arg-parsing`.) + + For multicharacter format units like ``z#``, use the + entire two-or-three character string. + + Sample:: + + /*[clinic input] + module _pickle + class _pickle.Pickler "PicklerObject *" "&Pickler_Type" + [clinic start generated code]*/ + + /*[clinic input] + _pickle.Pickler.dump + + obj: 'O' + + Write a pickled representation of obj to the open file. + [clinic start generated code]*/ + +9. If your function has ``|`` in the format string, meaning some + parameters have default values, you can ignore it. Argument + Clinic infers which parameters are optional based on whether + or not they have default values. + + If your function has ``$`` in the format string, meaning it + takes keyword-only arguments, specify ``*`` on a line by + itself before the first keyword-only argument, indented the + same as the parameter lines. + + (``_pickle.Pickler.dump`` has neither, so our sample is unchanged.) + + +10. If the existing C function calls :c:func:`PyArg_ParseTuple` + (as opposed to :c:func:`PyArg_ParseTupleAndKeywords`), then all its + arguments are positional-only. + + To mark all parameters as positional-only in Argument Clinic, + add a ``/`` on a line by itself after the last parameter, + indented the same as the parameter lines. + + Currently this is all-or-nothing; either all parameters are + positional-only, or none of them are. (In the future Argument + Clinic may relax this restriction.) + + Sample:: + + /*[clinic input] + module _pickle + class _pickle.Pickler "PicklerObject *" "&Pickler_Type" + [clinic start generated code]*/ + + /*[clinic input] + _pickle.Pickler.dump + + obj: 'O' + / + + Write a pickled representation of obj to the open file. + [clinic start generated code]*/ + +11. It's helpful to write a per-parameter docstring for each parameter. + But per-parameter docstrings are optional; you can skip this step + if you prefer. + + Here's how to add a per-parameter docstring. The first line + of the per-parameter docstring must be indented further than the + parameter definition. The left margin of this first line establishes + the left margin for the whole per-parameter docstring; all the text + you write will be outdented by this amount. You can write as much + text as you like, across multiple lines if you wish. + + Sample:: + + /*[clinic input] + module _pickle + class _pickle.Pickler "PicklerObject *" "&Pickler_Type" + [clinic start generated code]*/ + + /*[clinic input] + _pickle.Pickler.dump + + obj: 'O' + The object to be pickled. + / + + 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]*/ + + /*[clinic input] + _pickle.Pickler.dump + + obj: 'O' + The object to be pickled. + / + + 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]*/ + + 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. + +13. Double-check that the argument-parsing code Argument Clinic generated + looks basically the same as the existing code. + + First, ensure both places use the same argument-parsing function. + The existing code must call either + :c:func:`PyArg_ParseTuple` or :c:func:`PyArg_ParseTupleAndKeywords`; + ensure that the code generated by Argument Clinic calls the + *exact* same function. + + Second, the format string passed in to :c:func:`PyArg_ParseTuple` or + :c:func:`PyArg_ParseTupleAndKeywords` should be *exactly* the same + as the hand-written one in the existing function, up to the colon + or semi-colon. + + (Argument Clinic always generates its format strings + with a ``:`` followed by the name of the function. If the + existing code's format string ends with ``;``, to provide + usage help, this change is harmless--don't worry about it.) + + Third, for parameters whose format units require two arguments + (like a length variable, or an encoding string, or a pointer + to a conversion function), ensure that the second argument is + *exactly* the same between the two invocations. + + Fourth, inside the output portion of the block you'll find a preprocessor + macro defining the appropriate static :c:type:`PyMethodDef` structure for + this builtin:: + + #define __PICKLE_PICKLER_DUMP_METHODDEF \ + {"dump", (PyCFunction)__pickle_Pickler_dump, METH_O, __pickle_Pickler_dump__doc__}, + + This static structure should be *exactly* the same as the existing static + :c:type:`PyMethodDef` structure for this builtin. + + If any of these items differ in *any way*, + adjust your Argument Clinic function specification and rerun + ``Tools/clinic/clinic.py`` until they *are* the same. + + +14. Notice that the last line of its output is the declaration + of your "impl" function. This is where the builtin's implementation goes. + Delete the existing prototype of the function you're modifying, but leave + the opening curly brace. Now delete its argument parsing code and the + declarations of all the variables it dumps the arguments into. + Notice how the Python arguments are now arguments to this impl function; + if the implementation used different names for these variables, fix it. + + Let's reiterate, just because it's kind of weird. Your code should now + look like this:: + + static return_type + your_function_impl(...) + /*[clinic end generated code: checksum=...]*/ + { + ... + + Argument Clinic generated the checksum line and the function prototype just + above it. You should write the opening (and closing) curly braces for the + function, and the implementation inside. + + Sample:: + + /*[clinic input] + module _pickle + class _pickle.Pickler "PicklerObject *" "&Pickler_Type" + [clinic start generated code]*/ + /*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ + + /*[clinic input] + _pickle.Pickler.dump + + obj: 'O' + The object to be pickled. + / + + 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]*/ + { + /* Check whether the Pickler was initialized correctly (issue3664). + Developers often forget to call __init__() in their subclasses, which + would trigger a segfault without this check. */ + if (self->write == NULL) { + PyErr_Format(PicklingError, + "Pickler.__init__() was not called by %s.__init__()", + Py_TYPE(self)->tp_name); + return NULL; + } + + if (_Pickler_ClearBuffer(self) < 0) + return NULL; + + ... + +15. Remember the macro with the :c:type:`PyMethodDef` structure for this + function? Find the existing :c:type:`PyMethodDef` structure for this + function and replace it with a reference to the macro. (If the builtin + is at module scope, this will probably be very near the end of the file; + if the builtin is a class method, this will probably be below but relatively + near to the implementation.) + + Note that the body of the macro contains a trailing comma. So when you + replace the existing static :c:type:`PyMethodDef` structure with the macro, + *don't* add a comma to the end. + + Sample:: + + static struct PyMethodDef Pickler_methods[] = { + __PICKLE_PICKLER_DUMP_METHODDEF + __PICKLE_PICKLER_CLEAR_MEMO_METHODDEF + {NULL, NULL} /* sentinel */ + }; + + +16. Compile, then run the relevant portions of the regression-test suite. + This change should not introduce any new compile-time warnings or errors, + and there should be no externally-visible change to Python's behavior. + + Well, except for one difference: ``inspect.signature()`` run on your function + should now provide a valid signature! + + Congratulations, you've ported your first function to work with Argument Clinic! + +Advanced Topics +=============== + +Now that you've had some experience working with Argument Clinic, it's time +for some advanced topics. + + +Symbolic default values +----------------------- + +The default value you provide for a parameter can't be any arbitrary +expression. Currently the following are explicitly supported: + +* Numeric constants (integer and float) +* String constants +* ``True``, ``False``, and ``None`` +* Simple symbolic constants like ``sys.maxsize``, which must + start with the name of the module + +In case you're curious, this is implemented in ``from_builtin()`` +in ``Lib/inspect.py``. + +(In the future, this may need to get even more elaborate, +to allow full expressions like ``CONSTANT - 1``.) + + +Renaming the C functions and variables generated by Argument Clinic +------------------------------------------------------------------- + +Argument Clinic automatically names the functions it generates for you. +Occasionally this may cause a problem, if the generated name collides with +the name of an existing C function. There's an easy solution: override the names +used for the C functions. Just add the keyword ``"as"`` +to your function declaration line, followed by the function name you wish to use. +Argument Clinic will use that function name for the base (generated) function, +then add ``"_impl"`` to the end and use that for the name of the impl function. + +For example, if we wanted to rename the C function names generated for +``pickle.Pickler.dump``, it'd look like this:: + + /*[clinic input] + pickle.Pickler.dump as pickler_dumper + + ... + +The base function would now be named ``pickler_dumper()``, +and the impl function would now be named ``pickler_dumper_impl()``. + + +Similarly, you may have a problem where you want to give a parameter +a specific Python name, but that name may be inconvenient in C. Argument +Clinic allows you to give a parameter different names in Python and in C, +using the same ``"as"`` syntax:: + + /*[clinic input] + pickle.Pickler.dump + + obj: object + file as file_obj: object + protocol: object = NULL + * + fix_imports: bool = True + +Here, the name used in Python (in the signature and the ``keywords`` +array) would be ``file``, but the C variable would be named ``file_obj``. + +You can use this to rename the ``self`` parameter too! + + +Converting functions using PyArg_UnpackTuple +-------------------------------------------- + +To convert a function parsing its arguments with :c:func:`PyArg_UnpackTuple`, +simply write out all the arguments, specifying each as an ``object``. You +may specify the ``type`` argument to cast the type as appropriate. All +arguments should be marked positional-only (add a ``/`` on a line by itself +after the last argument). + +Currently the generated code will use :c:func:`PyArg_ParseTuple`, but this +will change soon. + +Optional Groups +--------------- + +Some legacy functions have a tricky approach to parsing their arguments: +they count the number of positional arguments, then use a ``switch`` statement +to call one of several different :c:func:`PyArg_ParseTuple` calls depending on +how many positional arguments there are. (These functions cannot accept +keyword-only arguments.) This approach was used to simulate optional +arguments back before :c:func:`PyArg_ParseTupleAndKeywords` was created. + +While functions using this approach can often be converted to +use :c:func:`PyArg_ParseTupleAndKeywords`, optional arguments, and default values, +it's not always possible. Some of these legacy functions have +behaviors :c:func:`PyArg_ParseTupleAndKeywords` doesn't directly support. +The most obvious example is the builtin function ``range()``, which has +an optional argument on the *left* side of its required argument! +Another example is ``curses.window.addch()``, which has a group of two +arguments that must always be specified together. (The arguments are +called ``x`` and ``y``; if you call the function passing in ``x``, +you must also pass in ``y``--and if you don't pass in ``x`` you may not +pass in ``y`` either.) + +In any case, the goal of Argument Clinic is to support argument parsing +for all existing CPython builtins without changing their semantics. +Therefore Argument Clinic supports +this alternate approach to parsing, using what are called *optional groups*. +Optional groups are groups of arguments that must all be passed in together. +They can be to the left or the right of the required arguments. They +can *only* be used with positional-only parameters. + +.. note:: Optional groups are *only* intended for use when converting + functions that make multiple calls to :c:func:`PyArg_ParseTuple`! + Functions that use *any* other approach for parsing arguments + should *almost never* be converted to Argument Clinic using + optional groups. Functions using optional groups currently + cannot have accurate sigantures in Python, because Python just + doesn't understand the concept. Please avoid using optional + groups wherever possible. + +To specify an optional group, add a ``[`` on a line by itself before +the parameters you wish to group together, and a ``]`` on a line by itself +after these parameters. As an example, here's how ``curses.window.addch`` +uses optional groups to make the first two parameters and the last +parameter optional:: + + /*[clinic input] + + curses.window.addch + + [ + x: int + X-coordinate. + y: int + Y-coordinate. + ] + + ch: object + Character to add. + + [ + attr: long + Attributes for the character. + ] + / + + ... + + +Notes: + +* For every optional group, one additional parameter will be passed into the + impl function representing the group. The parameter will be an int named + ``group_{direction}_{number}``, + where ``{direction}`` is either ``right`` or ``left`` depending on whether the group + is before or after the required parameters, and ``{number}`` is a monotonically + increasing number (starting at 1) indicating how far away the group is from + the required parameters. When the impl is called, this parameter will be set + to zero if this group was unused, and set to non-zero if this group was used. + (By used or unused, I mean whether or not the parameters received arguments + in this invocation.) + +* If there are no required arguments, the optional groups will behave + as if they're to the right of the required arguments. + +* In the case of ambiguity, the argument parsing code + favors parameters on the left (before the required parameters). + +* Optional groups can only contain positional-only parameters. + +* Optional groups are *only* intended for legacy code. Please do not + use optional groups for new code. + + +Using real Argument Clinic converters, instead of "legacy converters" +--------------------------------------------------------------------- + +To save time, and to minimize how much you need to learn +to achieve your first port to Argument Clinic, the walkthrough above tells +you to use "legacy converters". "Legacy converters" are a convenience, +designed explicitly to make porting existing code to Argument Clinic +easier. And to be clear, their use is acceptable when porting code for +Python 3.4. + +However, in the long term we probably want all our blocks to +use Argument Clinic's real syntax for converters. Why? A couple +reasons: + +* The proper converters are far easier to read and clearer in their intent. +* There are some format units that are unsupported as "legacy converters", + because they require arguments, and the legacy converter syntax doesn't + support specifying arguments. +* In the future we may have a new argument parsing library that isn't + restricted to what :c:func:`PyArg_ParseTuple` supports; this flexibility + won't be available to parameters using legacy converters. + +Therefore, if you don't mind a little extra effort, please use the normal +converters instead of legacy converters. + +In a nutshell, the syntax for Argument Clinic (non-legacy) converters +looks like a Python function call. However, if there are no explicit +arguments to the function (all functions take their default values), +you may omit the parentheses. Thus ``bool`` and ``bool()`` are exactly +the same converters. + +All arguments to Argument Clinic converters are keyword-only. +All Argument Clinic converters accept the following arguments: + + ``c_default`` + The default value for this parameter when defined in C. + Specifically, this will be the initializer for the variable declared + in the "parse function". See :ref:`the section on default values <default_values>` + for how to use this. + Specified as a string. + + ``annotation`` + The annotation value for this parameter. Not currently supported, + because PEP 8 mandates that the Python library may not use + annotations. + +In addition, some converters accept additional arguments. Here is a list +of these arguments, along with their meanings: + + ``bitwise`` + Only supported for unsigned integers. The native integer value of this + Python argument will be written to the parameter without any range checking, + even for negative values. + + ``converter`` + Only supported by the ``object`` converter. Specifies the name of a + :ref:`C "converter function" <o_ampersand>` + to use to convert this object to a native type. + + ``encoding`` + Only supported for strings. Specifies the encoding to use when converting + this string from a Python str (Unicode) value into a C ``char *`` value. + + ``length`` + Only supported for strings. If true, requests that the length of the + string be passed in to the impl function, just after the string parameter, + in a parameter named ``<parameter_name>_length``. + + ``nullable`` + Only supported for strings. If true, this parameter may also be set to + ``None``, in which case the C parameter will be set to ``NULL``. + + ``subclass_of`` + Only supported for the ``object`` converter. Requires that the Python + value be a subclass of a Python type, as expressed in C. + + ``types`` + Only supported for the ``object`` (and ``self``) converter. Specifies + the C type that will be used to declare the variable. Default value is + ``"PyObject *"``. + + ``types`` + A string containing a list of Python types (and possibly pseudo-types); + this restricts the allowable Python argument to values of these types. + (This is not a general-purpose facility; as a rule it only supports + specific lists of types as shown in the legacy converter table.) + + ``zeroes`` + Only supported for strings. If true, embedded NUL bytes (``'\\0'``) are + permitted inside the value. + +Please note, not every possible combination of arguments will work. +Often these arguments are implemented internally by specific ``PyArg_ParseTuple`` +*format units*, with specific behavior. For example, currently you cannot +call ``str`` and pass in ``zeroes=True`` without also specifying an ``encoding``; +although it's perfectly reasonable to think this would work, these semantics don't +map to any existing format unit. So Argument Clinic doesn't support it. (Or, at +least, not yet.) + +Below is a table showing the mapping of legacy converters into real +Argument Clinic converters. On the left is the legacy converter, +on the right is the text you'd replace it with. + +========= ================================================================================= +``'B'`` ``unsigned_char(bitwise=True)`` +``'b'`` ``unsigned_char`` +``'c'`` ``char`` +``'C'`` ``int(types='str')`` +``'d'`` ``double`` +``'D'`` ``Py_complex`` +``'es#'`` ``str(encoding='name_of_encoding', length=True, zeroes=True)`` +``'es'`` ``str(encoding='name_of_encoding')`` +``'et#'`` ``str(encoding='name_of_encoding', types='bytes bytearray str', length=True)`` +``'et'`` ``str(encoding='name_of_encoding', types='bytes bytearray str')`` +``'f'`` ``float`` +``'h'`` ``short`` +``'H'`` ``unsigned_short(bitwise=True)`` +``'i'`` ``int`` +``'I'`` ``unsigned_int(bitwise=True)`` +``'k'`` ``unsigned_long(bitwise=True)`` +``'K'`` ``unsigned_PY_LONG_LONG(bitwise=True)`` +``'L'`` ``PY_LONG_LONG`` +``'n'`` ``Py_ssize_t`` +``'O!'`` ``object(subclass_of='&PySomething_Type')`` +``'O&'`` ``object(converter='name_of_c_function')`` +``'O'`` ``object`` +``'p'`` ``bool`` +``'s#'`` ``str(length=True)`` +``'S'`` ``PyBytesObject`` +``'s'`` ``str`` +``'s*'`` ``Py_buffer(types='str bytes bytearray buffer')`` +``'u#'`` ``Py_UNICODE(length=True)`` +``'u'`` ``Py_UNICODE`` +``'U'`` ``unicode`` +``'w*'`` ``Py_buffer(types='bytearray rwbuffer')`` +``'y#'`` ``str(types='bytes', length=True)`` +``'Y'`` ``PyByteArrayObject`` +``'y'`` ``str(types='bytes')`` +``'y*'`` ``Py_buffer`` +``'Z#'`` ``Py_UNICODE(nullable=True, length=True)`` +``'z#'`` ``str(nullable=True, length=True)`` +``'Z'`` ``Py_UNICODE(nullable=True)`` +``'z'`` ``str(nullable=True)`` +``'z*'`` ``Py_buffer(types='str bytes bytearray buffer', nullable=True)`` +========= ================================================================================= + +As an example, here's our sample ``pickle.Pickler.dump`` using the proper +converter:: + + /*[clinic input] + pickle.Pickler.dump + + obj: object + The object to be pickled. + / + + Write a pickled representation of obj to the open file. + [clinic start generated code]*/ + +Argument Clinic will show you all the converters it has +available. For each converter it'll show you all the parameters +it accepts, along with the default value for each parameter. +Just run ``Tools/clinic/clinic.py --converters`` to see the full list. + +Py_buffer +--------- + +When using the ``Py_buffer`` converter +(or the ``'s*'``, ``'w*'``, ``'*y'``, or ``'z*'`` legacy converters), +you *must* not call :c:func:`PyBuffer_Release` on the provided buffer. +Argument Clinic generates code that does it for you (in the parsing function). + + + +Advanced converters +------------------- + +Remember those format units you skipped for your first +time because they were advanced? Here's how to handle those too. + +The trick is, all those format units take arguments--either +conversion functions, or types, or strings specifying an encoding. +(But "legacy converters" don't support arguments. That's why we +skipped them for your first function.) The argument you specified +to the format unit is now an argument to the converter; this +argument is either ``converter`` (for ``O&``), ``subclass_of`` (for ``O!``), +or ``encoding`` (for all the format units that start with ``e``). + +When using ``subclass_of``, you may also want to use the other +custom argument for ``object()``: ``type``, which lets you set the type +actually used for the parameter. For example, if you want to ensure +that the object is a subclass of ``PyUnicode_Type``, you probably want +to use the converter ``object(type='PyUnicodeObject *', subclass_of='&PyUnicode_Type')``. + +One possible problem with using Argument Clinic: it takes away some possible +flexibility for the format units starting with ``e``. When writing a +``PyArg_Parse`` call by hand, you could theoretically decide at runtime what +encoding string to pass in to :c:func:`PyArg_ParseTuple`. But now this string must +be hard-coded at Argument-Clinic-preprocessing-time. This limitation is deliberate; +it made supporting this format unit much easier, and may allow for future optimizations. +This restriction doesn't seem unreasonable; CPython itself always passes in static +hard-coded encoding strings for parameters whose format units start with ``e``. + + +.. _default_values: + +Parameter default values +------------------------ + +Default values for parameters can be any of a number of values. +At their simplest, they can be string, int, or float literals:: + + foo: str = "abc" + bar: int = 123 + bat: float = 45.6 + +They can also use any of Python's built-in constants:: + + yep: bool = True + nope: bool = False + nada: object = None + +There's also special support for a default value of ``NULL``, and +for simple expressions, documented in the following sections. + + +The ``NULL`` default value +-------------------------- + +For string and object parameters, you can set them to ``None`` to indicate +that there's no default. However, that means the C variable will be +initialized to ``Py_None``. For convenience's sakes, there's a special +value called ``NULL`` for just this reason: from Python's perspective it +behaves like a default value of ``None``, but the C variable is initialized +with ``NULL``. + +Expressions specified as default values +--------------------------------------- + +The default value for a parameter can be more than just a literal value. +It can be an entire expression, using math operators and looking up attributes +on objects. However, this support isn't exactly simple, because of some +non-obvious semantics. + +Consider the following example:: + + foo: Py_ssize_t = sys.maxsize - 1 + +``sys.maxsize`` can have different values on different platforms. Therefore +Argument Clinic can't simply evaluate that expression locally and hard-code it +in C. So it stores the default in such a way that it will get evaluated at +runtime, when the user asks for the function's signature. + +What namespace is available when the expression is evaluated? It's evaluated +in the context of the module the builtin came from. So, if your module has an +attribute called "``max_widgets``", you may simply use it:: + + foo: Py_ssize_t = max_widgets + +If the symbol isn't found in the current module, it fails over to looking in +``sys.modules``. That's how it can find ``sys.maxsize`` for example. (Since you +don't know in advance what modules the user will load into their interpreter, +it's best to restrict yourself to modules that are preloaded by Python itself.) + +Evaluating default values only at runtime means Argument Clinic can't compute +the correct equivalent C default value. So you need to tell it explicitly. +When you use an expression, you must also specify the equivalent expression +in C, using the ``c_default`` parameter to the converter:: + + foo: Py_ssize_t(c_default="PY_SSIZE_T_MAX - 1") = sys.maxsize - 1 + +Another complication: Argument Clinic can't know in advance whether or not the +expression you supply is valid. It parses it to make sure it looks legal, but +it can't *actually* know. You must be very careful when using expressions to +specify values that are guaranteed to be valid at runtime! + +Finally, because expressions must be representable as static C values, there +are many restrictions on legal expressions. Here's a list of Python features +you're not permitted to use: + +* Function calls. +* Inline if statements (``3 if foo else 5``). +* Automatic sequence unpacking (``*[1, 2, 3]``). +* List/set/dict comprehensions and generator expressions. +* Tuple/list/set/dict literals. + + + +Using a return converter +------------------------ + +By default the impl function Argument Clinic generates for you returns ``PyObject *``. +But your C function often computes some C type, then converts it into the ``PyObject *`` +at the last moment. Argument Clinic handles converting your inputs from Python types +into native C types--why not have it convert your return value from a native C type +into a Python type too? + +That's what a "return converter" does. It changes your impl function to return +some C type, then adds code to the generated (non-impl) function to handle converting +that value into the appropriate ``PyObject *``. + +The syntax for return converters is similar to that of parameter converters. +You specify the return converter like it was a return annotation on the +function itself. Return converters behave much the same as parameter converters; +they take arguments, the arguments are all keyword-only, and if you're not changing +any of the default arguments you can omit the parentheses. + +(If you use both ``"as"`` *and* a return converter for your function, +the ``"as"`` should come before the return converter.) + +There's one additional complication when using return converters: how do you +indicate an error has occurred? Normally, a function returns a valid (non-``NULL``) +pointer for success, and ``NULL`` for failure. But if you use an integer return converter, +all integers are valid. How can Argument Clinic detect an error? Its solution: each return +converter implicitly looks for a special value that indicates an error. If you return +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:: + + bool + int + unsigned int + long + unsigned int + size_t + Py_ssize_t + float + double + DecodeFSDefault + +None of these take parameters. For the first three, return -1 to indicate +error. For ``DecodeFSDefault``, the return type is ``char *``; return a NULL +pointer to indicate an error. + +(There's also an experimental ``NoneType`` converter, which lets you +return ``Py_None`` on success or ``NULL`` on failure, without having +to increment the reference count on ``Py_None``. I'm not sure it adds +enough clarity to be worth using.) + +To see all the return converters Argument Clinic supports, along with +their parameters (if any), +just run ``Tools/clinic/clinic.py --converters`` for the full list. + + +Cloning existing functions +-------------------------- + +If you have a number of functions that look similar, you may be able to +use Clinic's "clone" feature. When you clone an existing function, +you reuse: + +* its parameters, including + + * their names, + + * their converters, with all parameters, + + * their default values, + + * their per-parameter docstrings, + + * their *kind* (whether they're positional only, + positional or keyword, or keyword only), and + +* its return converter. + +The only thing not copied from the original function is its docstring; +the syntax allows you to specify a new docstring. + +Here's the syntax for cloning a function:: + + /*[clinic input] + module.class.new_function [as c_basename] = module.class.existing_function + + Docstring for new_function goes here. + [clinic start generated code]*/ + +(The functions can be in different modules or classes. I wrote +``module.class`` in the sample just to illustrate that you must +use the full path to *both* functions.) + +Sorry, there's no syntax for partially-cloning a function, or cloning a function +then modifying it. Cloning is an all-or nothing proposition. + +Also, the function you are cloning from must have been previously defined +in the current file. + +Calling Python code +------------------- + +The rest of the advanced topics require you to write Python code +which lives inside your C file and modifies Argument Clinic's +runtime state. This is simple: you simply define a Python block. + +A Python block uses different delimiter lines than an Argument +Clinic function block. It looks like this:: + + /*[python input] + # python code goes here + [python start generated code]*/ + +All the code inside the Python block is executed at the +time it's parsed. All text written to stdout inside the block +is redirected into the "output" after the block. + +As an example, here's a Python block that adds a static integer +variable to the C code:: + + /*[python input] + print('static int __ignored_unused_variable__ = 0;') + [python start generated code]*/ + static int __ignored_unused_variable__ = 0; + /*[python checksum:...]*/ + + +Using a "self converter" +------------------------ + +Argument Clinic automatically adds a "self" parameter for you +using a default converter. It automatically sets the ``type`` +of this parameter to the "pointer to an instance" you specified +when you declared the type. However, you can override +Argument Clinic's converter and specify one yourself. +Just add your own ``self`` parameter as the first parameter in a +block, and ensure that its converter is an instance of +``self_converter`` or a subclass thereof. + +What's the point? This lets you override the type of ``self``, +or give it a different default name. + +How do you specify the custom type you want to cast ``self`` to? +If you only have one or two functions with the same type for ``self``, +you can directly use Argument Clinic's existing ``self`` converter, +passing in the type you want to use as the ``type`` parameter:: + + /*[clinic input] + + _pickle.Pickler.dump + + self: self(type="PicklerObject *") + obj: object + / + + Write a pickled representation of the given object to the open file. + [clinic start generated code]*/ + +On the other hand, if you have a lot of functions that will use the same +type for ``self``, it's best to create your own converter, subclassing +``self_converter`` but overwriting the ``type`` member:: + + /*[python input] + class PicklerObject_converter(self_converter): + type = "PicklerObject *" + [python start generated code]*/ + + /*[clinic input] + + _pickle.Pickler.dump + + self: PicklerObject + obj: object + / + + Write a pickled representation of the given object to the open file. + [clinic start generated code]*/ + + + +Writing a custom converter +-------------------------- + +As we hinted at in the previous section... you can write your own converters! +A converter is simply a Python class that inherits from ``CConverter``. +The main purpose of a custom converter is if you have a parameter using +the ``O&`` format unit--parsing this parameter means calling +a :c:func:`PyArg_ParseTuple` "converter function". + +Your converter class should be named ``*something*_converter``. +If the name follows this convention, then your converter class +will be automatically registered with Argument Clinic; its name +will be the name of your class with the ``_converter`` suffix +stripped off. (This is accomplished with a metaclass.) + +You shouldn't subclass ``CConverter.__init__``. Instead, you should +write a ``converter_init()`` function. ``converter_init()`` +always accepts a ``self`` parameter; after that, all additional +parameters *must* be keyword-only. Any arguments passed in to +the converter in Argument Clinic will be passed along to your +``converter_init()``. + +There are some additional members of ``CConverter`` you may wish +to specify in your subclass. Here's the current list: + +``type`` + The C type to use for this variable. + ``type`` should be a Python string specifying the type, e.g. ``int``. + If this is a pointer type, the type string should end with ``' *'``. + +``default`` + The Python default value for this parameter, as a Python value. + Or the magic value ``unspecified`` if there is no default. + +``py_default`` + ``default`` as it should appear in Python code, + as a string. + Or ``None`` if there is no default. + +``c_default`` + ``default`` as it should appear in C code, + as a string. + Or ``None`` if there is no default. + +``c_ignored_default`` + The default value used to initialize the C variable when + there is no default, but not specifying a default may + result in an "uninitialized variable" warning. This can + easily happen when using option groups--although + properly-written code will never actually use this value, + the variable does get passed in to the impl, and the + C compiler will complain about the "use" of the + uninitialized value. This value should always be a + non-empty string. + +``converter`` + The name of the C converter function, as a string. + +``impl_by_reference`` + A boolean value. If true, + Argument Clinic will add a ``&`` in front of the name of + the variable when passing it into the impl function. + +``parse_by_reference`` + A boolean value. If true, + Argument Clinic will add a ``&`` in front of the name of + the variable when passing it into :c:func:`PyArg_ParseTuple`. + + +Here's the simplest example of a custom converter, from ``Modules/zlibmodule.c``:: + + /*[python input] + + class uint_converter(CConverter): + type = 'unsigned int' + converter = 'uint_converter' + + [python start generated code]*/ + /*[python end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ + +This block adds a converter to Argument Clinic named ``uint``. Parameters +declared as ``uint`` will be declared as type ``unsigned int``, and will +be parsed by the ``'O&'`` format unit, which will call the ``uint_converter`` +converter function. +``uint`` variables automatically support default values. + +More sophisticated custom converters can insert custom C code to +handle initialization and cleanup. +You can see more examples of custom converters in the CPython +source tree; grep the C files for the string ``CConverter``. + +Writing a custom return converter +--------------------------------- + +Writing a custom return converter is much like writing +a custom converter. Except it's somewhat simpler, because return +converters are themselves much simpler. + +Return converters must subclass ``CReturnConverter``. +There are no examples yet of custom return converters, +because they are not widely used yet. If you wish to +write your own return converter, please read ``Tools/clinic/clinic.py``, +specifically the implementation of ``CReturnConverter`` and +all its subclasses. + +METH_O and METH_NOARGS +---------------------------------------------- + +To convert a function using ``METH_O``, make sure the function's +single argument is using the ``object`` converter, and mark the +arguments as positional-only:: + + /*[clinic input] + meth_o_sample + + argument: object + / + [clinic start generated code]*/ + + +To convert a function using ``METH_NOARGS``, just don't specify +any arguments. + +You can still use a self converter, a return converter, and specify +a ``type`` argument to the object converter for ``METH_O``. + +tp_new and tp_init functions +---------------------------------------------- + +You can convert ``tp_new`` and ``tp_init`` functions. Just name +them ``__new__`` or ``__init__`` as appropriate. Notes: + +* The function name generated for ``__new__`` doesn't end in ``__new__`` + like it would by default. It's just the name of the class, converted + into a valid C identifier. + +* No ``PyMethodDef`` ``#define`` is generated for these functions. + +* ``__init__`` functions return ``int``, not ``PyObject *``. + +* Use the docstring as the class docstring. + +* Although ``__new__`` and ``__init__`` functions must always + accept both the ``args`` and ``kwargs`` objects, when converting + you may specify any signature for these functions that you like. + (If your function doesn't support keywords, the parsing function + generated will throw an exception if it receives any.) + +Changing and redirecting Clinic's output +---------------------------------------- + +It can be inconvenient to have Clinic's output interspersed with +your conventional hand-edited C code. Luckily, Clinic is configurable: +you can buffer up its output for printing later (or earlier!), or write +its output to a separate file. You can also add a prefix or suffix to +every line of Clinic's generated output. + +While changing Clinic's output in this manner can be a boon to readability, +it may result in Clinic code using types before they are defined, or +your code attempting to use Clinic-generated code befire it is defined. +These problems can be easily solved by rearranging the declarations in your file, +or moving where Clinic's generated code goes. (This is why the default behavior +of Clinic is to output everything into the current block; while many people +consider this hampers readability, it will never require rearranging your +code to fix definition-before-use problems.) + +Let's start with defining some terminology: + +*field* + A field, in this context, is a subsection of Clinic's output. + For example, the ``#define`` for the ``PyMethodDef`` structure + is a field, called ``methoddef_define``. Clinic has seven + different fields it can output per function definition:: + + docstring_prototype + docstring_definition + methoddef_define + impl_prototype + parser_prototype + parser_definition + impl_definition + + All the names are of the form ``"<a>_<b>"``, + where ``"<a>"`` is the semantic object represented (the parsing function, + the impl function, the docstring, or the methoddef structure) and ``"<b>"`` + represents what kind of statement the field is. Field names that end in + ``"_prototype"`` + represent forward declarations of that thing, without the actual body/data + of the thing; field names that end in ``"_definition"`` represent the actual + definition of the thing, with the body/data of the thing. (``"methoddef"`` + is special, it's the only one that ends with ``"_define"``, representing that + it's a preprocessor #define.) + +*destination* + A destination is a place Clinic can write output to. There are + five built-in destinations: + + ``block`` + The default destination: printed in the output section of + the current Clinic block. + + ``buffer`` + A text buffer where you can save text for later. Text sent + here is appended to the end of any exsiting text. It's an + error to have any text left in the buffer when Clinic finishes + processing a file. + + ``file`` + A separate "clinic file" that will be created automatically by Clinic. + The filename chosen for the file is ``{basename}.clinic{extension}``, + where ``basename`` and ``extension`` were assigned the output + from ``os.path.splitext()`` run on the current file. (Example: + the ``file`` destination for ``_pickle.c`` would be written to + ``_pickle.clinic.c``.) + + **Important: When using a** ``file`` **destination, you** + *must check in* **the generated file!** + + ``two-pass`` + A buffer like ``buffer``. However, a two-pass buffer can only + be written once, and it prints out all text sent to it during + all of processing, even from Clinic blocks *after* the + + ``suppress`` + The text is suppressed--thrown away. + + +Clinic defines five new directives that let you reconfigure its output. + +The first new directive is ``dump``:: + + dump <destination> + +This dumps the current contents of the named destination into the output of +the current block, and empties it. This only works with ``buffer`` and +``two-pass`` destinations. + +The second new directive is ``output``. The most basic form of ``output`` +is like this:: + + output <field> <destination> + +This tells Clinic to output *field* to *destination*. ``output`` also +supports a special meta-destination, called ``everything``, which tells +Clinic to output *all* fields to that *destination*. + +``output`` has a number of other functions:: + + output push + output pop + output preset <preset> + + +``output push`` and ``output pop`` allow you to push and pop +configurations on an internal configuration stack, so that you +can temporarily modify the output configuration, then easily restore +the previous configuration. Simply push before your change to save +the current configuration, then pop when you wish to restore the +previous configuration. + +``output preset`` sets Clinic's output to one of several built-in +preset configurations, as follows: + + ``block`` + Clinic's original starting configuration. Writes everything + immediately after the input block. + + Suppress the ``parser_prototype`` + and ``docstring_prototype``, write everything else to ``block``. + + ``file`` + Designed to write everything to the "clinic file" that it can. + You then ``#include`` this file near the top of your file. + You may need to rearrange your file to make this work, though + usually this just means creating forward declarations for various + ``typedef`` and ``PyTypeObject`` definitions. + + Suppress the ``parser_prototype`` + and ``docstring_prototype``, write the ``impl_definition`` to + ``block``, and write everything else to ``file``. + + The default filename is ``"{dirname}/clinic/{basename}.h"``. + + ``buffer`` + Save up all most of the output from Clinic, to be written into + your file near the end. For Python files implementing modules + or builtin types, it's recommended that you dump the buffer + just above the static structures for your module or + builtin type; these are normally very near the end. Using + ``buffer`` may require even more editing than ``file``, if + your file has static ``PyMethodDef`` arrays defined in the + middle of the file. + + Suppress the ``parser_prototype``, ``impl_prototype``, + and ``docstring_prototype``, write the ``impl_definition`` to + ``block``, and write everything else to ``file``. + + ``two-pass`` + Similar to the ``buffer`` preset, but writes forward declarations to + the ``two-pass`` buffer, and definitions to the ``buffer``. + This is similar to the ``buffer`` preset, but may require + less editing than ``buffer``. Dump the ``two-pass`` buffer + near the top of your file, and dump the ``buffer`` near + the end just like you would when using the ``buffer`` preset. + + Suppresses the ``impl_prototype``, write the ``impl_definition`` + to ``block``, write ``docstring_prototype``, ``methoddef_define``, + and ``parser_prototype`` to ``two-pass``, write everything else + to ``buffer``. + + ``partial-buffer`` + Similar to the ``buffer`` preset, but writes more things to ``block``, + only writing the really big chunks of generated code to ``buffer``. + This avoids the definition-before-use problem of ``buffer`` completely, + at the small cost of having slightly more stuff in the block's output. + Dump the ``buffer`` near the end, just like you would when using + the ``buffer`` preset. + + Suppresses the ``impl_prototype``, write the ``docstring_definition`` + and ``parser_defintion`` to ``buffer``, write everything else to ``block``. + +The third new directive is ``destination``:: + + destination <name> <command> [...] + +This performs an operation on the destination named ``name``. + +There are two defined subcommands: ``new`` and ``clear``. + +The ``new`` subcommand works like this:: + + destination <name> new <type> + +This creates a new destination with name ``<name>`` and type ``<type>``. + +There are five destination types: + + ``suppress`` + Throws the text away. + + ``block`` + Writes the text to the current block. This is what Clinic + originally did. + + ``buffer`` + A simple text buffer, like the "buffer" builtin destination above. + + ``file`` + A text file. The file destination takes an extra argument, + a template to use for building the filename, like so: + + destination <name> new <type> <file_template> + + The template can use three strings internally that will be replaced + by bits of the filename: + + {path} + The full path to the file, including directory and full filename. + {dirname} + The name of the directory the file is in. + {basename} + Just the name of the file, not including the directory. + {basename_root} + Basename with the extension clipped off + (everything up to but not including the last '.'). + {basename_extension} + The last '.' and everything after it. If the basename + does not contain a period, this will be the empty string. + + If there are no periods in the filename, {basename} and {filename} + are the same, and {extension} is empty. "{basename}{extension}" + is always exactly the same as "{filename}"." + + ``two-pass`` + A two-pass buffer, like the "two-pass" builtin destination above. + + +The ``clear`` subcommand works like this:: + + destination <name> clear + +It removes all the accumulated text up to this point in the destination. +(I don't know what you'd need this for, but I thought maybe it'd be +useful while someone's experimenting.) + +The fourth new directive is ``set``:: + + set line_prefix "string" + set line_suffix "string" + +``set`` lets you set two internal variables in Clinic. +``line_prefix`` is a string that will be prepended to every line of Clinic's output; +``line_suffix`` is a string that will be appended to every line of Clinic's output. + +Both of these support two format strings: + + ``{block comment start}`` + Turns into the string ``/*``, the start-comment text sequence for C files. + + ``{block comment end}`` + Turns into the string ``*/``, the end-comment text sequence for C files. + +The final new directive is one you shouldn't need to use directly, +called ``preserve``:: + + preserve + +This tells Clinic that the current contents of the output should be kept, unmodifed. +This is used internally by Clinic when dumping output into ``file`` files; wrapping +it in a Clinic block lets Clinic use its existing checksum functionality to ensure +the file was not modified by hand before it gets overwritten. + + +The #ifdef trick +---------------------------------------------- + +If you're converting a function that isn't available on all platforms, +there's a trick you can use to make life a little easier. The existing +code probably looks like this:: + + #ifdef HAVE_FUNCTIONNAME + static module_functionname(...) + { + ... + } + #endif /* HAVE_FUNCTIONNAME */ + +And then in the ``PyMethodDef`` structure at the bottom the existing code +will have:: + + #ifdef HAVE_FUNCTIONNAME + {'functionname', ... }, + #endif /* HAVE_FUNCTIONNAME */ + +In this scenario, you should enclose the body of your impl function inside the ``#ifdef``, +like so:: + + #ifdef HAVE_FUNCTIONNAME + /*[clinic input] + module.functionname + ... + [clinic start generated code]*/ + static module_functionname(...) + { + ... + } + #endif /* HAVE_FUNCTIONNAME */ + +Then, remove those three lines from the ``PyMethodDef`` structure, +replacing them with the macro Argument Clinic generated:: + + MODULE_FUNCTIONNAME_METHODDEF + +(You can find the real name for this macro inside the generated code. +Or you can calculate it yourself: it's the name of your function as defined +on the first line of your block, but with periods changed to underscores, +uppercased, and ``"_METHODDEF"`` added to the end.) + +Perhaps you're wondering: what if ``HAVE_FUNCTIONNAME`` isn't defined? +The ``MODULE_FUNCTIONNAME_METHODDEF`` macro won't be defined either! + +Here's where Argument Clinic gets very clever. It actually detects that the +Argument Clinic block might be deactivated by the ``#ifdef``. When that +happens, it generates a little extra code that looks like this:: + + #ifndef MODULE_FUNCTIONNAME_METHODDEF + #define MODULE_FUNCTIONNAME_METHODDEF + #endif /* !defined(MODULE_FUNCTIONNAME_METHODDEF) */ + +That means the macro always works. If the function is defined, this turns +into the correct structure, including the trailing comma. If the function is +undefined, this turns into nothing. + +However, this causes one ticklish problem: where should Argument Clinic put this +extra code when using the "block" output preset? It can't go in the output block, +because that could be decativated 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:: + + Warning in file "Modules/posixmodule.c" on line 12357: + Destination buffer 'buffer' not empty at end of file, emptying. + +When this happens, just open your file, find the ``dump buffer`` block that +Argument Clinic added to your file (it'll be at the very bottom), then +move it above the ``PyMethodDef`` structure where that macro is used. + + + +Using Argument Clinic in Python files +------------------------------------- + +It's actually possible to use Argument Clinic to preprocess Python files. +There's no point to using Argument Clinic blocks, of course, as the output +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:: + + #/*[python input] + #print("def foo(): pass") + #[python start generated code]*/ + def foo(): pass + #/*[python checksum:...]*/ diff --git a/Doc/howto/cporting.rst b/Doc/howto/cporting.rst index 1ad77d687e7c..d7a708630259 100644 --- a/Doc/howto/cporting.rst +++ b/Doc/howto/cporting.rst @@ -43,10 +43,9 @@ separating others. str/unicode Unification ----------------------- - -Python 3's :func:`str` (``PyString_*`` functions in C) type is equivalent to -Python 2's :func:`unicode` (``PyUnicode_*``). The old 8-bit string type has -become :func:`bytes`. Python 2.6 and later provide a compatibility header, +Python 3's :func:`str` type is equivalent to Python 2's :func:`unicode`; the C +functions are called ``PyUnicode_*`` for both. The old 8-bit string type has become +:func:`bytes`, with C functions called ``PyBytes_*``. Python 2.6 and later provide a compatibility header, :file:`bytesobject.h`, mapping ``PyBytes`` names to ``PyString`` ones. For best compatibility with Python 3, :c:type:`PyUnicode` should be used for textual data and :c:type:`PyBytes` for binary data. It's also important to remember that @@ -253,6 +252,6 @@ Other options ============= If you are writing a new extension module, you might consider `Cython -<http://www.cython.org>`_. It translates a Python-like language to C. The +<http://cython.org/>`_. It translates a Python-like language to C. The extension modules it creates are compatible with Python 3 and Python 2. diff --git a/Doc/howto/curses.rst b/Doc/howto/curses.rst index ea62b1c849e3..87a5cab142bf 100644 --- a/Doc/howto/curses.rst +++ b/Doc/howto/curses.rst @@ -538,12 +538,12 @@ the Python interface. Often this isn't because they're difficult to implement, but because no one has needed them yet. Also, Python doesn't yet support the menu library associated with ncurses. Patches adding support for these would be welcome; see -`the Python Developer's Guide <http://docs.python.org/devguide/>`_ to +`the Python Developer's Guide <https://docs.python.org/devguide/>`_ to learn more about submitting patches to Python. * `Writing Programs with NCURSES <http://invisible-island.net/ncurses/ncurses-intro.html>`_: a lengthy tutorial for C programmers. -* `The ncurses man page <http://www.linuxmanpages.com/man3/ncurses.3x.php>`_ +* `The ncurses man page <http://linux.die.net/man/3/ncurses>`_ * `The ncurses FAQ <http://invisible-island.net/ncurses/ncurses.faq.html>`_ * `"Use curses... don't swear" <http://www.youtube.com/watch?v=eN1eZtjLEnU>`_: video of a PyCon 2013 talk on controlling terminals using curses or Urwid. diff --git a/Doc/howto/descriptor.rst b/Doc/howto/descriptor.rst index a0c698899b72..f018b0e89310 100644 --- a/Doc/howto/descriptor.rst +++ b/Doc/howto/descriptor.rst @@ -92,9 +92,9 @@ For objects, the machinery is in :meth:`object.__getattribute__` which transforms ``b.x`` into ``type(b).__dict__['x'].__get__(b, type(b))``. The implementation works through a precedence chain that gives data descriptors priority over instance variables, instance variables priority over non-data -descriptors, and assigns lowest priority to :meth:`__getattr__` if provided. The -full C implementation can be found in :c:func:`PyObject_GenericGetAttr()` in -`Objects/object.c <http://svn.python.org/view/python/trunk/Objects/object.c?view=markup>`_\. +descriptors, and assigns lowest priority to :meth:`__getattr__` if provided. +The full C implementation can be found in :c:func:`PyObject_GenericGetAttr()` in +:source:`Objects/object.c`. For classes, the machinery is in :meth:`type.__getattribute__` which transforms ``B.x`` into ``B.__dict__['x'].__get__(None, B)``. In pure Python, it looks @@ -124,10 +124,10 @@ and then returns ``A.__dict__['m'].__get__(obj, B)``. If not a descriptor, search using :meth:`object.__getattribute__`. The implementation details are in :c:func:`super_getattro()` in -`Objects/typeobject.c <http://svn.python.org/view/python/trunk/Objects/typeobject.c?view=markup>`_ -and a pure Python equivalent can be found in `Guido's Tutorial`_. +:source:`Objects/typeobject.c`. and a pure Python equivalent can be found in +`Guido's Tutorial`_. -.. _`Guido's Tutorial`: http://www.python.org/2.2.3/descrintro.html#cooperation +.. _`Guido's Tutorial`: https://www.python.org/download/releases/2.2.3/descrintro/#cooperation The details above show that the mechanism for descriptors is embedded in the :meth:`__getattribute__()` methods for :class:`object`, :class:`type`, and @@ -300,10 +300,9 @@ Running the interpreter shows how the function descriptor works in practice:: The output suggests that bound and unbound methods are two different types. While they could have been implemented that way, the actual C implementation of -:c:type:`PyMethod_Type` in -`Objects/classobject.c <http://svn.python.org/view/python/trunk/Objects/classobject.c?view=markup>`_ -is a single object with two different representations depending on whether the -:attr:`im_self` field is set or is *NULL* (the C equivalent of *None*). +:c:type:`PyMethod_Type` in :source:`Objects/classobject.c` is a single object +with two different representations depending on whether the :attr:`im_self` +field is set or is *NULL* (the C equivalent of *None*). Likewise, the effects of calling a method object depend on the :attr:`im_self` field. If set (meaning bound), the original function (stored in the diff --git a/Doc/howto/functional.rst b/Doc/howto/functional.rst index 97c90c7c0b88..1969b3210857 100644 --- a/Doc/howto/functional.rst +++ b/Doc/howto/functional.rst @@ -583,7 +583,7 @@ And here's an example of changing the counter: Because ``yield`` will often be returning ``None``, you should always check for this case. Don't just use its value in expressions unless you're sure that the -:meth:`~generator.send` method will be the only method used resume your +:meth:`~generator.send` method will be the only method used to resume your generator function. In addition to :meth:`~generator.send`, there are two other methods on diff --git a/Doc/howto/index.rst b/Doc/howto/index.rst index 81a4f8b98d5c..2c9d69910a6d 100644 --- a/Doc/howto/index.rst +++ b/Doc/howto/index.rst @@ -28,4 +28,5 @@ Currently, the HOWTOs are: webservers.rst argparse.rst ipaddress.rst + clinic.rst diff --git a/Doc/howto/logging-cookbook.rst b/Doc/howto/logging-cookbook.rst index feb9b6c1a854..e31b6c2bf481 100644 --- a/Doc/howto/logging-cookbook.rst +++ b/Doc/howto/logging-cookbook.rst @@ -325,6 +325,15 @@ which, when run, will produce:: MainThread: Look out! +.. versionchanged:: 3.5 + Prior to Python 3.5, the :class:`QueueListener` always passed every message + received from the queue to every handler it was initialized with. (This was + because it was assumed that level filtering was all done on the other side, + where the queue is filled.) From 3.5 onwards, this behaviour can be changed + by passing a keyword argument ``respect_handler_level=True`` to the + listener's constructor. When this is done, the listener compares the level + of each message with the handler's level, and only passes a message to a + handler if it's appropriate to do so. .. _network-logging: @@ -416,7 +425,7 @@ module. Here is a basic working example:: Simple TCP socket-based logging receiver suitable for testing. """ - allow_reuse_address = 1 + allow_reuse_address = True def __init__(self, host='localhost', port=logging.handlers.DEFAULT_TCP_LOGGING_PORT, @@ -649,7 +658,7 @@ file from your processes. The existing :class:`FileHandler` and subclasses do not make use of :mod:`multiprocessing` at present, though they may do so in the future. Note that at present, the :mod:`multiprocessing` module does not provide working lock functionality on all platforms (see -http://bugs.python.org/issue3770). +https://bugs.python.org/issue3770). .. currentmodule:: logging.handlers @@ -839,7 +848,7 @@ separate thread:: }, 'loggers': { 'foo': { - 'handlers' : ['foofile'] + 'handlers': ['foofile'] } }, 'root': { @@ -1308,7 +1317,7 @@ This dictionary is passed to :func:`~config.dictConfig` to put the configuration } For more information about this configuration, you can see the `relevant -section <https://docs.djangoproject.com/en/1.3/topics/logging/#configuring-logging>`_ +section <https://docs.djangoproject.com/en/1.6/topics/logging/#configuring-logging>`_ of the Django documentation. .. _cookbook-rotator-namer: @@ -1527,7 +1536,7 @@ works:: }, 'loggers': { 'foo': { - 'handlers' : ['foofile'] + 'handlers': ['foofile'] } }, 'root': { @@ -1680,7 +1689,7 @@ as in the following complete example:: def main(): logging.basicConfig(level=logging.INFO, format='%(message)s') - logging.info(_('message 1', set_value=set([1, 2, 3]), snowman='\u2603')) + logging.info(_('message 1', set_value={1, 2, 3}, snowman='\u2603')) if __name__ == '__main__': main() @@ -1692,6 +1701,9 @@ When the above script is run, it prints:: Note that the order of items might be different according to the version of Python used. + +.. _custom-handlers: + .. currentmodule:: logging.config Customizing handlers with :func:`dictConfig` @@ -1827,3 +1839,315 @@ Of course, the approach could also be extended to types of handler other than a :class:`~logging.FileHandler` - for example, one of the rotating file handlers, or a different type of handler altogether. + +.. currentmodule:: logging + +.. _formatting-styles: + +Using particular formatting styles throughout your application +-------------------------------------------------------------- + +In Python 3.2, the :class:`~logging.Formatter` gained a ``style`` keyword +parameter which, while defaulting to ``%`` for backward compatibility, allowed +the specification of ``{`` or ``$`` to support the formatting approaches +supported by :meth:`str.format` and :class:`string.Template`. Note that this +governs the formatting of logging messages for final output to logs, and is +completely orthogonal to how an individual logging message is constructed. + +Logging calls (:meth:`~Logger.debug`, :meth:`~Logger.info` etc.) only take +positional parameters for the actual logging message itself, with keyword +parameters used only for determining options for how to handle the logging call +(e.g. the ``exc_info`` keyword parameter to indicate that traceback information +should be logged, or the ``extra`` keyword parameter to indicate additional +contextual information to be added to the log). So you cannot directly make +logging calls using :meth:`str.format` or :class:`string.Template` syntax, +because internally the logging package uses %-formatting to merge the format +string and the variable arguments. There would no changing this while preserving +backward compatibility, since all logging calls which are out there in existing +code will be using %-format strings. + +There have been suggestions to associate format styles with specific loggers, +but that approach also runs into backward compatibility problems because any +existing code could be using a given logger name and using %-formatting. + +For logging to work interoperably between any third-party libraries and your +code, decisions about formatting need to be made at the level of the +individual logging call. This opens up a couple of ways in which alternative +formatting styles can be accommodated. + + +Using LogRecord factories +^^^^^^^^^^^^^^^^^^^^^^^^^ + +In Python 3.2, along with the :class:`~logging.Formatter` changes mentioned +above, the logging package gained the ability to allow users to set their own +:class:`LogRecord` subclasses, using the :func:`setLogRecordFactory` function. +You can use this to set your own subclass of :class:`LogRecord`, which does the +Right Thing by overriding the :meth:`~LogRecord.getMessage` method. The base +class implementation of this method is where the ``msg % args`` formatting +happens, and where you can substitute your alternate formatting; however, you +should be careful to support all formatting styles and allow %-formatting as +the default, to ensure interoperability with other code. Care should also be +taken to call ``str(self.msg)``, just as the base implementation does. + +Refer to the reference documentation on :func:`setLogRecordFactory` and +:class:`LogRecord` for more information. + + +Using custom message objects +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +There is another, perhaps simpler way that you can use {}- and $- formatting to +construct your individual log messages. You may recall (from +:ref:`arbitrary-object-messages`) that when logging you can use an arbitrary +object as a message format string, and that the logging package will call +:func:`str` on that object to get the actual format string. Consider the +following two classes:: + + class BraceMessage(object): + def __init__(self, fmt, *args, **kwargs): + self.fmt = fmt + self.args = args + self.kwargs = kwargs + + def __str__(self): + return self.fmt.format(*self.args, **self.kwargs) + + class DollarMessage(object): + def __init__(self, fmt, **kwargs): + self.fmt = fmt + self.kwargs = kwargs + + def __str__(self): + from string import Template + return Template(self.fmt).substitute(**self.kwargs) + +Either of these can be used in place of a format string, to allow {}- or +$-formatting to be used to build the actual "message" part which appears in the +formatted log output in place of “%(message)s†or “{message}†or “$messageâ€. +If you find it a little unwieldy to use the class names whenever you want to log +something, you can make it more palatable if you use an alias such as ``M`` or +``_`` for the message (or perhaps ``__``, if you are using ``_`` for +localization). + +Examples of this approach are given below. Firstly, formatting with +:meth:`str.format`:: + + >>> __ = BraceMessage + >>> print(__('Message with {0} {1}', 2, 'placeholders')) + Message with 2 placeholders + >>> class Point: pass + ... + >>> p = Point() + >>> p.x = 0.5 + >>> p.y = 0.5 + >>> print(__('Message with coordinates: ({point.x:.2f}, {point.y:.2f})', point=p)) + Message with coordinates: (0.50, 0.50) + +Secondly, formatting with :class:`string.Template`:: + + >>> __ = DollarMessage + >>> print(__('Message with $num $what', num=2, what='placeholders')) + Message with 2 placeholders + >>> + +One thing to note is that you pay no significant performance penalty with this +approach: the actual formatting happens not when you make the logging call, but +when (and if) the logged message is actually about to be output to a log by a +handler. So the only slightly unusual thing which might trip you up is that the +parentheses go around the format string and the arguments, not just the format +string. That’s because the __ notation is just syntax sugar for a constructor +call to one of the ``XXXMessage`` classes shown above. + + +.. _filters-dictconfig: + +.. currentmodule:: logging.config + +Configuring filters with :func:`dictConfig` +------------------------------------------- + +You *can* configure filters using :func:`~logging.config.dictConfig`, though it +might not be obvious at first glance how to do it (hence this recipe). Since +:class:`~logging.Filter` is the only filter class included in the standard +library, and it is unlikely to cater to many requirements (it's only there as a +base class), you will typically need to define your own :class:`~logging.Filter` +subclass with an overridden :meth:`~logging.Filter.filter` method. To do this, +specify the ``()`` key in the configuration dictionary for the filter, +specifying a callable which will be used to create the filter (a class is the +most obvious, but you can provide any callable which returns a +:class:`~logging.Filter` instance). Here is a complete example:: + + import logging + import logging.config + import sys + + class MyFilter(logging.Filter): + def __init__(self, param=None): + self.param = param + + def filter(self, record): + if self.param is None: + allow = True + else: + allow = self.param not in record.msg + if allow: + record.msg = 'changed: ' + record.msg + return allow + + LOGGING = { + 'version': 1, + 'filters': { + 'myfilter': { + '()': MyFilter, + 'param': 'noshow', + } + }, + 'handlers': { + 'console': { + 'class': 'logging.StreamHandler', + 'filters': ['myfilter'] + } + }, + 'root': { + 'level': 'DEBUG', + 'handlers': ['console'] + }, + } + + if __name__ == '__main__': + logging.config.dictConfig(LOGGING) + logging.debug('hello') + logging.debug('hello - noshow') + +This example shows how you can pass configuration data to the callable which +constructs the instance, in the form of keyword parameters. When run, the above +script will print:: + + changed: hello + +which shows that the filter is working as configured. + +A couple of extra points to note: + +* If you can't refer to the callable directly in the configuration (e.g. if it + lives in a different module, and you can't import it directly where the + configuration dictionary is), you can use the form ``ext://...`` as described + in :ref:`logging-config-dict-externalobj`. For example, you could have used + the text ``'ext://__main__.MyFilter'`` instead of ``MyFilter`` in the above + example. + +* As well as for filters, this technique can also be used to configure custom + handlers and formatters. See :ref:`logging-config-dict-userdef` for more + information on how logging supports using user-defined objects in its + configuration, and see the other cookbook recipe :ref:`custom-handlers` above. + + +.. _custom-format-exception: + +Customized exception formatting +------------------------------- + +There might be times when you want to do customized exception formatting - for +argument's sake, let's say you want exactly one line per logged event, even +when exception information is present. You can do this with a custom formatter +class, as shown in the following example:: + + import logging + + class OneLineExceptionFormatter(logging.Formatter): + def formatException(self, exc_info): + """ + Format an exception so that it prints on a single line. + """ + result = super(OneLineExceptionFormatter, self).formatException(exc_info) + return repr(result) # or format into one line however you want to + + def format(self, record): + s = super(OneLineExceptionFormatter, self).format(record) + if record.exc_text: + s = s.replace('\n', '') + '|' + return s + + def configure_logging(): + fh = logging.FileHandler('output.txt', 'w') + f = OneLineExceptionFormatter('%(asctime)s|%(levelname)s|%(message)s|', + '%d/%m/%Y %H:%M:%S') + fh.setFormatter(f) + root = logging.getLogger() + root.setLevel(logging.DEBUG) + root.addHandler(fh) + + def main(): + configure_logging() + logging.info('Sample message') + try: + x = 1 / 0 + except ZeroDivisionError as e: + logging.exception('ZeroDivisionError: %s', e) + + if __name__ == '__main__': + main() + +When run, this produces a file with exactly two lines:: + + 28/01/2015 07:21:23|INFO|Sample message| + 28/01/2015 07:21:23|ERROR|ZeroDivisionError: integer division or modulo by zero|'Traceback (most recent call last):\n File "logtest7.py", line 30, in main\n x = 1 / 0\nZeroDivisionError: integer division or modulo by zero'| + +While the above treatment is simplistic, it points the way to how exception +information can be formatted to your liking. The :mod:`traceback` module may be +helpful for more specialized needs. + +.. _spoken-messages: + +Speaking logging messages +------------------------- + +There might be situations when it is desirable to have logging messages rendered +in an audible rather than a visible format. This is easy to do if you have text- +to-speech (TTS) functionality available in your system, even if it doesn't have +a Python binding. Most TTS systems have a command line program you can run, and +this can be invoked from a handler using :mod:`subprocess`. It's assumed here +that TTS command line programs won't expect to interact with users or take a +long time to complete, and that the frequency of logged messages will be not so +high as to swamp the user with messages, and that it's acceptable to have the +messages spoken one at a time rather than concurrently, The example implementation +below waits for one message to be spoken before the next is processed, and this +might cause other handlers to be kept waiting. Here is a short example showing +the approach, which assumes that the ``espeak`` TTS package is available:: + + import logging + import subprocess + import sys + + class TTSHandler(logging.Handler): + def emit(self, record): + msg = self.format(record) + # Speak slowly in a female English voice + cmd = ['espeak', '-s150', '-ven+f3', msg] + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + # wait for the program to finish + p.communicate() + + def configure_logging(): + h = TTSHandler() + root = logging.getLogger() + root.addHandler(h) + # the default formatter just returns the message + root.setLevel(logging.DEBUG) + + def main(): + logging.info('Hello') + logging.debug('Goodbye') + + if __name__ == '__main__': + configure_logging() + sys.exit(main()) + +When run, this script should say "Hello" and then "Goodbye" in a female voice. + +The above approach can, of course, be adapted to other TTS systems and even +other systems altogether which can process messages via external programs run +from a command line. + diff --git a/Doc/howto/logging.rst b/Doc/howto/logging.rst index c7a802a1e32c..4ce14f98addc 100644 --- a/Doc/howto/logging.rst +++ b/Doc/howto/logging.rst @@ -122,7 +122,8 @@ Logging to a file ^^^^^^^^^^^^^^^^^ A very common situation is that of recording logging events in a file, so let's -look at that next:: +look at that next. Be sure to try the following in a newly-started Python +interpreter, and don't just continue from the session described above:: import logging logging.basicConfig(filename='example.log',level=logging.DEBUG) @@ -238,7 +239,7 @@ uses the old, %-style of string formatting. This is for backwards compatibility: the logging package pre-dates newer formatting options such as :meth:`str.format` and :class:`string.Template`. These newer formatting options *are* supported, but exploring them is outside the scope of this -tutorial. +tutorial: see :ref:`formatting-styles` for more information. Changing the format of displayed messages @@ -1026,6 +1027,15 @@ You can write code like this:: so that if the logger's threshold is set above ``DEBUG``, the calls to :func:`expensive_func1` and :func:`expensive_func2` are never made. +.. note:: In some cases, :meth:`~Logger.isEnabledFor` can itself be more + expensive than you'd like (e.g. for deeply nested loggers where an explicit + level is only set high up in the logger hierarchy). In such cases (or if you + want to avoid calling a method in tight loops), you can cache the result of a + call to :meth:`~Logger.isEnabledFor` in a local or instance variable, and use + that instead of calling the method each time. Such a cached value would only + need to be recomputed when the logging configuration changes dynamically + while the application is running (which is not all that common). + There are other optimizations which can be made for specific applications which need more precise control over what logging information is collected. Here's a list of things you can do to avoid processing during logging which you don't @@ -1035,6 +1045,12 @@ need: | What you don't want to collect | How to avoid collecting it | +===============================================+========================================+ | Information about where calls were made from. | Set ``logging._srcfile`` to ``None``. | +| | This avoids calling | +| | :func:`sys._getframe`, which may help | +| | to speed up your code in environments | +| | like PyPy (which can't speed up code | +| | that uses :func:`sys._getframe`), if | +| | and when PyPy supports Python 3.x. | +-----------------------------------------------+----------------------------------------+ | Threading information. | Set ``logging.logThreads`` to ``0``. | +-----------------------------------------------+----------------------------------------+ diff --git a/Doc/howto/pyporting.rst b/Doc/howto/pyporting.rst index 9015372bde06..bd80dfd7cf1f 100644 --- a/Doc/howto/pyporting.rst +++ b/Doc/howto/pyporting.rst @@ -10,737 +10,383 @@ Porting Python 2 Code to Python 3 With Python 3 being the future of Python while Python 2 is still in active use, it is good to have your project available for both major releases of - Python. This guide is meant to help you choose which strategy works best - for your project to support both Python 2 & 3 along with how to execute - that strategy. + Python. This guide is meant to help you figure out how best to support both + Python 2 & 3 simultaneously. If you are looking to port an extension module instead of pure Python code, please see :ref:`cporting-howto`. - -Choosing a Strategy -=================== - -When a project chooses to support both Python 2 & 3, -a decision needs to be made as to how to go about accomplishing that goal. -The chosen strategy will depend on how large the project's existing -codebase is and how much divergence you want from your current Python 2 codebase -(e.g., changing your code to work simultaneously with Python 2 and 3). - -If you would prefer to maintain a codebase which is semantically **and** -syntactically compatible with Python 2 & 3 simultaneously, you can write -:ref:`use_same_source`. While this tends to lead to somewhat non-idiomatic -code, it does mean you keep a rapid development process for you, the developer. - -If your project is brand-new or does not have a large codebase, then you may -want to consider writing/porting :ref:`all of your code for Python 3 -and use 3to2 <use_3to2>` to port your code for Python 2. - -Finally, you do have the option of :ref:`using 2to3 <use_2to3>` to translate -Python 2 code into Python 3 code (with some manual help). This can take the -form of branching your code and using 2to3 to start a Python 3 branch. You can -also have users perform the translation at installation time automatically so -that you only have to maintain a Python 2 codebase. - -Regardless of which approach you choose, porting is not as hard or -time-consuming as you might initially think. You can also tackle the problem -piece-meal as a good portion of porting is simply updating your code to follow -current best practices in a Python 2/3 compatible way. - - -Universal Bits of Advice ------------------------- - -Regardless of what strategy you pick, there are a few things you should -consider. - -One is make sure you have a robust test suite. You need to make sure everything -continues to work, just like when you support a new minor/feature release of -Python. This means making sure your test suite is thorough and is ported -properly between Python 2 & 3. You will also most likely want to use something -like tox_ to automate testing between both a Python 2 and Python 3 interpreter. - -Two, once your project has Python 3 support, make sure to add the proper -classifier on the Cheeseshop_ (PyPI_). To have your project listed as Python 3 -compatible it must have the -`Python 3 classifier <http://pypi.python.org/pypi?:action=browse&c=533>`_ -(from -http://techspot.zzzeek.org/2011/01/24/zzzeek-s-guide-to-python-3-porting/):: - - setup( - name='Your Library', - version='1.0', - classifiers=[ - # make sure to use :: Python *and* :: Python :: 3 so - # that pypi can list the package on the python 3 page - 'Programming Language :: Python', - 'Programming Language :: Python :: 3' - ], - packages=['yourlibrary'], - # make sure to add custom_fixers to the MANIFEST.in - include_package_data=True, - # ... - ) - - -Doing so will cause your project to show up in the -`Python 3 packages list -<http://pypi.python.org/pypi?:action=browse&c=533&show=all>`_. You will know -you set the classifier properly as visiting your project page on the Cheeseshop -will show a Python 3 logo in the upper-left corner of the page. - -Three, the six_ project provides a library which helps iron out differences -between Python 2 & 3. If you find there is a sticky point that is a continual -point of contention in your translation or maintenance of code, consider using -a source-compatible solution relying on six. If you have to create your own -Python 2/3 compatible solution, you can use ``sys.version_info[0] >= 3`` as a -guard. - -Four, read all the approaches. Just because some bit of advice applies to one -approach more than another doesn't mean that some advice doesn't apply to other -strategies. This is especially true of whether you decide to use 2to3 or be -source-compatible; tips for one approach almost always apply to the other. - -Five, drop support for older Python versions if possible. `Python 2.5`_ -introduced a lot of useful syntax and libraries which have become idiomatic -in Python 3. `Python 2.6`_ introduced future statements which makes -compatibility much easier if you are going from Python 2 to 3. -`Python 2.7`_ continues the trend in the stdlib. So choose the newest version -of Python which you believe can be your minimum support version -and work from there. - -Six, target the newest version of Python 3 that you can. Beyond just the usual -bugfixes, compatibility has continued to improve between Python 2 and 3 as time -has passed. This is especially true for Python 3.3 where the ``u`` prefix for -strings is allowed, making source-compatible Python code easier. - -Seven, make sure to look at the `Other Resources`_ for tips from other people -which may help you out. - - -.. _tox: http://codespeak.net/tox/ -.. _Cheeseshop: -.. _PyPI: http://pypi.python.org/ -.. _six: http://packages.python.org/six -.. _Python 2.7: http://www.python.org/2.7.x -.. _Python 2.6: http://www.python.org/2.6.x -.. _Python 2.5: http://www.python.org/2.5.x -.. _Python 2.4: http://www.python.org/2.4.x -.. _Python 2.3: http://www.python.org/2.3.x -.. _Python 2.2: http://www.python.org/2.2.x - - -.. _use_3to2: - -Python 3 and 3to2 -================= - -If you are starting a new project or your codebase is small enough, you may -want to consider writing your code for Python 3 and backporting to Python 2 -using 3to2_. Thanks to Python 3 being more strict about things than Python 2 -(e.g., bytes vs. strings), the source translation can be easier and more -straightforward than from Python 2 to 3. Plus it gives you more direct -experience developing in Python 3 which, since it is the future of Python, is a -good thing long-term. - -A drawback of this approach is that 3to2 is a third-party project. This means -that the Python core developers (and thus this guide) can make no promises -about how well 3to2 works at any time. There is nothing to suggest, though, -that 3to2 is not a high-quality project. - - -.. _3to2: https://bitbucket.org/amentajo/lib3to2/overview - - -.. _use_2to3: - -Python 2 and 2to3 -================= - -Included with Python since 2.6, the 2to3_ tool (and :mod:`lib2to3` module) -helps with porting Python 2 to Python 3 by performing various source -translations. This is a perfect solution for projects which wish to branch -their Python 3 code from their Python 2 codebase and maintain them as -independent codebases. You can even begin preparing to use this approach -today by writing future-compatible Python code which works cleanly in -Python 2 in conjunction with 2to3; all steps outlined below will work -with Python 2 code up to the point when the actual use of 2to3 occurs. - -Use of 2to3 as an on-demand translation step at install time is also possible, -preventing the need to maintain a separate Python 3 codebase, but this approach -does come with some drawbacks. While users will only have to pay the -translation cost once at installation, you as a developer will need to pay the -cost regularly during development. If your codebase is sufficiently large -enough then the translation step ends up acting like a compilation step, -robbing you of the rapid development process you are used to with Python. -Obviously the time required to translate a project will vary, so do an -experimental translation just to see how long it takes to evaluate whether you -prefer this approach compared to using :ref:`use_same_source` or simply keeping -a separate Python 3 codebase. - -Below are the typical steps taken by a project which tries to support -Python 2 & 3 while keeping the code directly executable by Python 2. - - -Support Python 2.7 ------------------- - -As a first step, make sure that your project is compatible with `Python 2.7`_. -This is just good to do as Python 2.7 is the last release of Python 2 and thus -will be used for a rather long time. It also allows for use of the ``-3`` flag -to Python to help discover places in your code which 2to3 cannot handle but are -known to cause issues. - -Try to Support `Python 2.6`_ and Newer Only -------------------------------------------- - -While not possible for all projects, if you can support `Python 2.6`_ and newer -**only**, your life will be much easier. Various future statements, stdlib -additions, etc. exist only in Python 2.6 and later which greatly assist in -porting to Python 3. But if you project must keep support for `Python 2.5`_ (or -even `Python 2.4`_) then it is still possible to port to Python 3. - -Below are the benefits you gain if you only have to support Python 2.6 and -newer. Some of these options are personal choice while others are -**strongly** recommended (the ones that are more for personal choice are -labeled as such). If you continue to support older versions of Python then you -at least need to watch out for situations that these solutions fix. - - -``from __future__ import print_function`` -''''''''''''''''''''''''''''''''''''''''' - -This is a personal choice. 2to3 handles the translation from the print -statement to the print function rather well so this is an optional step. This -future statement does help, though, with getting used to typing -``print('Hello, World')`` instead of ``print 'Hello, World'``. - - -``from __future__ import unicode_literals`` -''''''''''''''''''''''''''''''''''''''''''' - -Another personal choice. You can always mark what you want to be a (unicode) -string with a ``u`` prefix to get the same effect. But regardless of whether -you use this future statement or not, you **must** make sure you know exactly -which Python 2 strings you want to be bytes, and which are to be strings. This -means you should, **at minimum** mark all strings that are meant to be text -strings with a ``u`` prefix if you do not use this future statement. Python 3.3 -allows strings to continue to have the ``u`` prefix (it's a no-op in that case) -to make it easier for code to be source-compatible between Python 2 & 3. - - -Bytes literals -'''''''''''''' - -This is a **very** important one. The ability to prefix Python 2 strings that -are meant to contain bytes with a ``b`` prefix help to very clearly delineate -what is and is not a Python 3 string. When you run 2to3 on code, all Python 2 -strings become Python 3 strings **unless** they are prefixed with ``b``. - -This point cannot be stressed enough: make sure you know what all of your string -literals in Python 2 are meant to become in Python 3. Any string literal that -should be treated as bytes should have the ``b`` prefix. Any string literal -that should be Unicode/text in Python 2 should either have the ``u`` literal -(supported, but ignored, in Python 3.3 and later) or you should have -``from __future__ import unicode_literals`` at the top of the file. But the key -point is you should know how Python 3 will treat everyone one of your string -literals and you should mark them as appropriate. - -There are some differences between byte literals in Python 2 and those in -Python 3 thanks to the bytes type just being an alias to ``str`` in Python 2. -Probably the biggest "gotcha" is that indexing results in different values. In -Python 2, the value of ``b'py'[1]`` is ``'y'``, while in Python 3 it's ``121``. -You can avoid this disparity by always slicing at the size of a single element: -``b'py'[1:2]`` is ``'y'`` in Python 2 and ``b'y'`` in Python 3 (i.e., close -enough). - -You cannot concatenate bytes and strings in Python 3. But since Python -2 has bytes aliased to ``str``, it will succeed: ``b'a' + u'b'`` works in -Python 2, but ``b'a' + 'b'`` in Python 3 is a :exc:`TypeError`. A similar issue -also comes about when doing comparisons between bytes and strings. - - -Supporting `Python 2.5`_ and Newer Only ---------------------------------------- - -If you are supporting `Python 2.5`_ and newer there are still some features of -Python that you can utilize. - - -``from __future__ import absolute_import`` -'''''''''''''''''''''''''''''''''''''''''' - -Implicit relative imports (e.g., importing ``spam.bacon`` from within -``spam.eggs`` with the statement ``import bacon``) does not work in Python 3. -This future statement moves away from that and allows the use of explicit -relative imports (e.g., ``from . import bacon``). - -In `Python 2.5`_ you must use -the __future__ statement to get to use explicit relative imports and prevent -implicit ones. In `Python 2.6`_ explicit relative imports are available without -the statement, but you still want the __future__ statement to prevent implicit -relative imports. In `Python 2.7`_ the __future__ statement is not needed. In -other words, unless you are only supporting Python 2.7 or a version earlier -than Python 2.5, use the __future__ statement. - - -Mark all Unicode strings with a ``u`` prefix -''''''''''''''''''''''''''''''''''''''''''''' - -While Python 2.6 has a ``__future__`` statement to automatically cause Python 2 -to treat all string literals as Unicode, Python 2.5 does not have that shortcut. -This means you should go through and mark all string literals with a ``u`` -prefix to turn them explicitly into Unicode strings where appropriate. That -leaves all unmarked string literals to be considered byte literals in Python 3. - - - -Handle Common "Gotchas" + If you would like to read one core Python developer's take on why Python 3 + came into existence, you can read Nick Coghlan's `Python 3 Q & A`_. + + For help with porting, you can email the python-porting_ mailing list with + questions. + +The Short Explanation +===================== + +To make your project be single-source Python 2/3 compatible, the basic steps +are: + +#. Update your code to drop support for Python 2.5 or older (supporting only + Python 2.7 is ideal) +#. 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 Pylint_ to help make sure you don't regress on your Python 3 support + (if only supporting Python 2.7/3.4 or newer; ``pip install pylint``) +#. Use caniusepython3_ to find out which of your dependencies are blocking your + use of Python 3 (``pip install caniusepython3``) +#. Once your dependencies are no longer blocking you, use continuous integration + to make sure you stay compatible with Python 2 & 3 (tox_ can help test + against multiple versions of Python; ``pip install tox``) + +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. + + +Details +======= + +A key point about supporting Python 2 & 3 simultaneously is that you can start +**today**! Even if your dependencies are not supporting Python 3 yet that does +not mean you can't modernize your code **now** to support Python 3. Most changes +required to support Python 3 lead to cleaner code using newer practices even in +Python 2. + +Another key point is that modernizing your Python 2 code to also support +Python 3 is largely automated for you. While you might have to make some API +decisions thanks to Python 3 clarifying text data versus binary data, the +lower-level work is now mostly done for you and thus can at least benefit from +the automated changes immediately. + +Keep those key points in mind while you read on about the details of porting +your code to support Python 2 & 3 simultaneously. + + +Drop support for Python 2.5 and older (at least) +------------------------------------------------ + +While you can make Python 2.5 work with Python 3, it is **much** easier if you +only have to work with Python 2.6 or newer (and easier still if you only have +to work with Python 2.7). If dropping Python 2.5 is not an option then the six_ +project can help you support Python 2.5 & 3 simultaneously +(``pip install six``). Do realize, though, that nearly all the projects listed +in this HOWTO will not be available to you. + +If you are able to only support Python 2.6 or newer, then the required changes +to your code should continue to look and feel like idiomatic Python code. At +worst you will have to use a function instead of a method in some instances or +have to import a function instead of using a built-in one, but otherwise the +overall transformation should not feel foreign to you. + +But please aim for Python 2.7. Bugfixes for that version of Python will continue +until 2020 while Python 2.6 is no longer supported. 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. + +Make sure you specify the proper version support in your ``setup.py`` file +-------------------------------------------------------------------------- + +In your ``setup.py`` file you should have the proper `trove classifier`_ +specifying what versions of Python you support. As your project does not support +Python 3 yet you should at least have +``Programming Language :: Python :: 2 :: Only`` specified. Ideally you should +also specify each major/minor version of Python that you do support, e.g. +``Programming Language :: Python :: 2.7``. + +Have good test coverage ----------------------- -There are a few things that just consistently come up as sticking points for -people which 2to3 cannot handle automatically or can easily be done in Python 2 -to help modernize your code. - +Once you have your code supporting the oldest version of Python 2 you want it +to, you will want to make sure your test suite has good coverage. A good rule of +thumb is that if you want to be confident enough in your test suite that any +failures that appear after having tools rewrite your code are actual bugs in the +tools and not in your code. If you want a number to aim for, try to get over 80% +coverage (and don't feel bad if you can't easily get past 90%). If you +don't already have a tool to measure test coverage then coverage.py_ is +recommended. -``from __future__ import division`` -''''''''''''''''''''''''''''''''''' - -While the exact same outcome can be had by using the ``-Qnew`` argument to -Python, using this future statement lifts the requirement that your users use -the flag to get the expected behavior of division in Python 3 -(e.g., ``1/2 == 0.5; 1//2 == 0``). - - - -Specify when opening a file as binary -''''''''''''''''''''''''''''''''''''' +Learn the differences between Python 2 & 3 +------------------------------------------- +Once you have your code well-tested you are ready to begin porting your code to +Python 3! But to fully understand how your code is going to change and what +you want to look out for while you code, you will want to learn what changes +Python 3 makes in terms of Python 2. Typically the two best ways of doing that +is reading the `"What's New"`_ doc for each release of Python 3 and the +`Porting to Python 3`_ book (which is free online). There is also a handy +`cheat sheet`_ from the Python-Future project. + + +Update your code +---------------- + +Once you feel like you know what is different in Python 3 compared to Python 2, +it's time to update your code! You have a choice between two tools in porting +your code automatically: Modernize_ and Futurize_. 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. + +Regardless of which tool you choose, they will update your code to run under +Python 3 while staying compatible with the version of Python 2 you started with. +Depending on how conservative you want to be, you may want to run the tool over +your test suite first and visually inspect the diff to make sure the +transformation is accurate. After you have transformed your test suite and +verified that all the tests still pass as expected, then you can transform your +application code knowing that any tests which fail is a translation failure. + +Unfortunately the tools can't automate everything to make your code work under +Python 3 and so there are a handful of things you will need to update manually +to get full Python 3 support (which of these steps are necessary vary between +the tools). Read the documentation for the tool you choose to use to see what it +fixes by default and what it can do optionally to know what will (not) be fixed +for you and what you may have to fix on your own (e.g. using ``io.open()`` over +the built-in ``open()`` function is off by default in Modernize). Luckily, +though, there are only a couple of things to watch out for which can be +considered large issues that may be hard to debug if not watched for. + +Division +++++++++ + +In Python 3, ``5 / 2 == 2.5`` and not ``2``; all division between ``int`` values +result in a ``float``. This change has actually been planned since Python 2.2 +which was released in 2002. Since then users have been encouraged to add +``from __future__ import division`` to any and all files which use the ``/`` and +``//`` operators or to be running the interpreter with the ``-Q`` flag. If you +have not been doing this then you will need to go through your code and do two +things: + +#. Add ``from __future__ import division`` to your files +#. Update any division operator as necessary to either use ``//`` to use floor + division or continue using ``/`` and expect a float + +The reason that ``/`` isn't simply translated to ``//`` automatically is that if +an object defines its own ``__div__`` method but not ``__floordiv__`` then your +code would begin to fail. + +Text versus binary data ++++++++++++++++++++++++ + +In Python 2 you could use the ``str`` type for both text and binary data. +Unfortunately this confluence of two different concepts could lead to brittle +code which sometimes worked for either kind of data, sometimes not. It also +could lead to confusing APIs if people didn't explicitly state that something +that accepted ``str`` accepted either text or binary data instead of one +specific type. This complicated the situation especially for anyone supporting +multiple languages as APIs wouldn't bother explicitly supporting ``unicode`` +when they claimed text data support. + +To make the distinction between text and binary data clearer and more +pronounced, Python 3 did what most languages created in the age of the internet +have done and made text and binary data distinct types that cannot blindly be +mixed together (Python predates widespread access to the internet). For any code +that only deals with text or only binary data, this separation doesn't pose an +issue. But for code that has to deal with both, it does mean you might have to +now care about when you are using text compared to binary data, which is why +this cannot be entirely automated. + +To start, you will need to decide which APIs take text and which take binary +(it is **highly** recommended you don't design APIs that can take both due to +the difficulty of keeping the code working; as stated earlier it is difficult to +do well). In Python 2 this means making sure the APIs that take text can work +with ``unicode`` 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 +(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 +between Python 2 and 3 because ``str`` in Python 3 doesn't have the method). + +======================== ===================== +**Text data** **Binary data** +------------------------ --------------------- +__mod__ (``%`` operator) +------------------------ --------------------- +\ decode +------------------------ --------------------- +encode +------------------------ --------------------- +format +------------------------ --------------------- +isdecimal +------------------------ --------------------- +isnumeric +======================== ===================== + +Making the distinction easier to handle can be accomplished by encoding and +decoding between binary data and text at the edge of your code. This means that +when you receive text in binary data, you should immediately decode it. And if +your code needs to send text as binary data then encode it as late as possible. +This allows your code to work with only text internally and thus eliminates +having to keep track of what type of data you are working with. + +The next issue is making sure you know whether the string literals in your code +represent text or binary data. 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. + +As part of this dichotomy you also need to be careful about opening files. Unless you have been working on Windows, there is a chance you have not always bothered to add the ``b`` mode when opening a binary file (e.g., ``rb`` for binary reading). Under Python 3, binary files and text files are clearly distinct and mutually incompatible; see the :mod:`io` module for details. Therefore, you **must** make a decision of whether a file will be used for -binary access (allowing to read and/or write bytes data) or text access -(allowing to read and/or write unicode data). - -Text files -'''''''''' - -Text files created using ``open()`` under Python 2 return byte strings, -while under Python 3 they return unicode strings. Depending on your porting -strategy, this can be an issue. - -If you want text files to return unicode strings in Python 2, you have two -possibilities: - -* Under Python 2.6 and higher, use :func:`io.open`. Since :func:`io.open` - is essentially the same function in both Python 2 and Python 3, it will - help iron out any issues that might arise. - -* If pre-2.6 compatibility is needed, then you should use :func:`codecs.open` - instead. This will make sure that you get back unicode strings in Python 2. - -Subclass ``object`` -''''''''''''''''''' - -New-style classes have been around since `Python 2.2`_. You need to make sure -you are subclassing from ``object`` to avoid odd edge cases involving method -resolution order, etc. This continues to be totally valid in Python 3 (although -unneeded as all classes implicitly inherit from ``object``). - - -Deal With the Bytes/String Dichotomy -'''''''''''''''''''''''''''''''''''' - -One of the biggest issues people have when porting code to Python 3 is handling -the bytes/string dichotomy. Because Python 2 allowed the ``str`` type to hold -textual data, people have over the years been rather loose in their delineation -of what ``str`` instances held text compared to bytes. In Python 3 you cannot -be so care-free anymore and need to properly handle the difference. The key -handling this issue is to make sure that **every** string literal in your -Python 2 code is either syntactically of functionally marked as either bytes or -text data. After this is done you then need to make sure your APIs are designed -to either handle a specific type or made to be properly polymorphic. - - -Mark Up Python 2 String Literals -******************************** - -First thing you must do is designate every single string literal in Python 2 -as either textual or bytes data. If you are only supporting Python 2.6 or -newer, this can be accomplished by marking bytes literals with a ``b`` prefix -and then designating textual data with a ``u`` prefix or using the -``unicode_literals`` future statement. - -If your project supports versions of Python predating 2.6, then you should use -the six_ project and its ``b()`` function to denote bytes literals. For text -literals you can either use six's ``u()`` function or use a ``u`` prefix. - - -Decide what APIs Will Accept -**************************** - -In Python 2 it was very easy to accidentally create an API that accepted both -bytes and textual data. But in Python 3, thanks to the more strict handling of -disparate types, this loose usage of bytes and text together tends to fail. - -Take the dict ``{b'a': 'bytes', u'a': 'text'}`` in Python 2.6. It creates the -dict ``{u'a': 'text'}`` since ``b'a' == u'a'``. But in Python 3 the equivalent -dict creates ``{b'a': 'bytes', 'a': 'text'}``, i.e., no lost data. Similar -issues can crop up when transitioning Python 2 code to Python 3. - -This means you need to choose what an API is going to accept and create and -consistently stick to that API in both Python 2 and 3. - - -Bytes / Unicode Comparison -************************** - -In Python 3, mixing bytes and unicode is forbidden in most situations; it -will raise a :class:`TypeError` where Python 2 would have attempted an implicit -coercion between types. However, there is one case where it doesn't and -it can be very misleading:: - - >>> b"" == "" - False - -This is because an equality comparison is required by the language to always -succeed (and return ``False`` for incompatible types). However, this also -means that code incorrectly ported to Python 3 can display buggy behaviour -if such comparisons are silently executed. To detect such situations, -Python 3 has a ``-b`` flag that will display a warning:: - - $ python3 -b - >>> b"" == "" - __main__:1: BytesWarning: Comparison between bytes and string - False - -To turn the warning into an exception, use the ``-bb`` flag instead:: - - $ python3 -bb - >>> b"" == "" - Traceback (most recent call last): - File "<stdin>", line 1, in <module> - BytesWarning: Comparison between bytes and string - - -Indexing bytes objects -'''''''''''''''''''''' - -Another potentially surprising change is the indexing behaviour of bytes -objects in Python 3:: - - >>> b"xyz"[0] - 120 - -Indeed, Python 3 bytes objects (as well as :class:`bytearray` objects) -are sequences of integers. But code converted from Python 2 will often -assume that indexing a bytestring produces another bytestring, not an -integer. To reconcile both behaviours, use slicing:: - - >>> b"xyz"[0:1] - b'x' - >>> n = 1 - >>> b"xyz"[n:n+1] - b'y' - -The only remaining gotcha is that an out-of-bounds slice returns an empty -bytes object instead of raising ``IndexError``: - - >>> b"xyz"[3] - Traceback (most recent call last): - File "<stdin>", line 1, in <module> - IndexError: index out of range - >>> b"xyz"[3:4] - b'' - - -``__str__()``/``__unicode__()`` -''''''''''''''''''''''''''''''' - -In Python 2, objects can specify both a string and unicode representation of -themselves. In Python 3, though, there is only a string representation. This -becomes an issue as people can inadvertently do things in their ``__str__()`` -methods which have unpredictable results (e.g., infinite recursion if you -happen to use the ``unicode(self).encode('utf8')`` idiom as the body of your -``__str__()`` method). - -There are two ways to solve this issue. One is to use a custom 2to3 fixer. The -blog post at http://lucumr.pocoo.org/2011/1/22/forwards-compatible-python/ -specifies how to do this. That will allow 2to3 to change all instances of ``def -__unicode(self): ...`` to ``def __str__(self): ...``. This does require that you -define your ``__str__()`` method in Python 2 before your ``__unicode__()`` -method. - -The other option is to use a mixin class. This allows you to only define a -``__unicode__()`` method for your class and let the mixin derive -``__str__()`` for you (code from -http://lucumr.pocoo.org/2011/1/22/forwards-compatible-python/):: - - import sys - - class UnicodeMixin(object): - - """Mixin class to handle defining the proper __str__/__unicode__ - methods in Python 2 or 3.""" - - if sys.version_info[0] >= 3: # Python 3 - def __str__(self): - return self.__unicode__() - else: # Python 2 - def __str__(self): - return self.__unicode__().encode('utf8') - - - class Spam(UnicodeMixin): - - def __unicode__(self): - return u'spam-spam-bacon-spam' # 2to3 will remove the 'u' prefix - - -Don't Index on Exceptions -''''''''''''''''''''''''' - -In Python 2, the following worked:: - - >>> exc = Exception(1, 2, 3) - >>> exc.args[1] - 2 - >>> exc[1] # Python 2 only! - 2 - -But in Python 3, indexing directly on an exception is an error. You need to -make sure to only index on the :attr:`BaseException.args` attribute which is a -sequence containing all arguments passed to the :meth:`__init__` method. - -Even better is to use the documented attributes the exception provides. - -Don't use ``__getslice__`` & Friends -'''''''''''''''''''''''''''''''''''' - -Been deprecated for a while, but Python 3 finally drops support for -``__getslice__()``, etc. Move completely over to :meth:`__getitem__` and -friends. - - -Updating doctests -''''''''''''''''' - -2to3_ will attempt to generate fixes for doctests that it comes across. It's -not perfect, though. If you wrote a monolithic set of doctests (e.g., a single -docstring containing all of your doctests), you should at least consider -breaking the doctests up into smaller pieces to make it more manageable to fix. -Otherwise it might very well be worth your time and effort to port your tests -to :mod:`unittest`. - - -Update `map` for imbalanced input sequences -''''''''''''''''''''''''''''''''''''''''''' - -With Python 2, `map` would pad input sequences of unequal length with -`None` values, returning a sequence as long as the longest input sequence. - -With Python 3, if the input sequences to `map` are of unequal length, `map` -will stop at the termination of the shortest of the sequences. For full -compatibility with `map` from Python 2.x, also wrap the sequences in -:func:`itertools.zip_longest`, e.g. ``map(func, *sequences)`` becomes -``list(map(func, itertools.zip_longest(*sequences)))``. - -Eliminate ``-3`` Warnings -------------------------- - -When you run your application's test suite, run it using the ``-3`` flag passed -to Python. This will cause various warnings to be raised during execution about -things that 2to3 cannot handle automatically (e.g., modules that have been -removed). Try to eliminate those warnings to make your code even more portable -to Python 3. - - -Run 2to3 --------- - -Once you have made your Python 2 code future-compatible with Python 3, it's -time to use 2to3_ to actually port your code. - - -Manually -'''''''' - -To manually convert source code using 2to3_, you use the ``2to3`` script that -is installed with Python 2.6 and later.:: - - 2to3 <directory or file to convert> - -This will cause 2to3 to write out a diff with all of the fixers applied for the -converted source code. If you would like 2to3 to go ahead and apply the changes -you can pass it the ``-w`` flag:: - - 2to3 -w <stuff to convert> - -There are other flags available to control exactly which fixers are applied, -etc. - - -During Installation -''''''''''''''''''' - -When a user installs your project for Python 3, you can have either -:mod:`distutils` or Distribute_ run 2to3_ on your behalf. -For distutils, use the following idiom:: - - try: # Python 3 - from distutils.command.build_py import build_py_2to3 as build_py - except ImportError: # Python 2 - from distutils.command.build_py import build_py - - setup(cmdclass = {'build_py': build_py}, - # ... - ) - -For Distribute:: - - setup(use_2to3=True, - # ... - ) - -This will allow you to not have to distribute a separate Python 3 version of -your project. It does require, though, that when you perform development that -you at least build your project and use the built Python 3 source for testing. - - -Verify & Test -------------- - -At this point you should (hopefully) have your project converted in such a way -that it works in Python 3. Verify it by running your unit tests and making sure -nothing has gone awry. If you miss something then figure out how to fix it in -Python 3, backport to your Python 2 code, and run your code through 2to3 again -to verify the fix transforms properly. - - -.. _2to3: http://docs.python.org/py3k/library/2to3.html -.. _Distribute: http://packages.python.org/distribute/ - - -.. _use_same_source: - -Python 2/3 Compatible Source -============================ - -While it may seem counter-intuitive, you can write Python code which is -source-compatible between Python 2 & 3. It does lead to code that is not -entirely idiomatic Python (e.g., having to extract the currently raised -exception from ``sys.exc_info()[1]``), but it can be run under Python 2 -**and** Python 3 without using 2to3_ as a translation step (although the tool -should be used to help find potential portability problems). This allows you to -continue to have a rapid development process regardless of whether you are -developing under Python 2 or Python 3. Whether this approach or using -:ref:`use_2to3` works best for you will be a per-project decision. - -To get a complete idea of what issues you will need to deal with, see the -`What's New in Python 3.0`_. Others have reorganized the data in other formats -such as http://docs.pythonsprints.com/python3_porting/py-porting.html . - -The following are some steps to take to try to support both Python 2 & 3 from -the same source code. - - -.. _What's New in Python 3.0: http://docs.python.org/release/3.0/whatsnew/3.0.html - - -Follow The Steps for Using 2to3_ --------------------------------- - -All of the steps outlined in how to -:ref:`port Python 2 code with 2to3 <use_2to3>` apply -to creating a Python 2/3 codebase. This includes trying only support Python 2.6 -or newer (the :mod:`__future__` statements work in Python 3 without issue), -eliminating warnings that are triggered by ``-3``, etc. - -You should even consider running 2to3_ over your code (without committing the -changes). This will let you know where potential pain points are within your -code so that you can fix them properly before they become an issue. - - -Use six_ --------- - -The six_ project contains many things to help you write portable Python code. -You should make sure to read its documentation from beginning to end and use -any and all features it provides. That way you will minimize any mistakes you -might make in writing cross-version code. - - -Capturing the Currently Raised Exception ----------------------------------------- - -One change between Python 2 and 3 that will require changing how you code (if -you support `Python 2.5`_ and earlier) is -accessing the currently raised exception. In Python 2.5 and earlier the syntax -to access the current exception is:: - - try: - raise Exception() - except Exception, exc: - # Current exception is 'exc' - pass - -This syntax changed in Python 3 (and backported to `Python 2.6`_ and later) -to:: - - try: - raise Exception() - except Exception as exc: - # Current exception is 'exc' - # In Python 3, 'exc' is restricted to the block; Python 2.6 will "leak" - pass - -Because of this syntax change you must change to capturing the current -exception to:: - - try: - raise Exception() - except Exception: - import sys - exc = sys.exc_info()[1] - # Current exception is 'exc' - pass - -You can get more information about the raised exception from -:func:`sys.exc_info` than simply the current exception instance, but you most -likely don't need it. - -.. note:: - In Python 3, the traceback is attached to the exception instance - through the ``__traceback__`` attribute. If the instance is saved in - a local variable that persists outside of the ``except`` block, the - traceback will create a reference cycle with the current frame and its - dictionary of local variables. This will delay reclaiming dead - resources until the next cyclic :term:`garbage collection` pass. - - In Python 2, this problem only occurs if you save the traceback itself - (e.g. the third element of the tuple returned by :func:`sys.exc_info`) - in a variable. - - -Other Resources -=============== - -The authors of the following blog posts, wiki pages, and books deserve special -thanks for making public their tips for porting Python 2 code to Python 3 (and -thus helping provide information for this document): - -* http://python3porting.com/ -* http://docs.pythonsprints.com/python3_porting/py-porting.html -* http://techspot.zzzeek.org/2011/01/24/zzzeek-s-guide-to-python-3-porting/ -* http://dabeaz.blogspot.com/2011/01/porting-py65-and-my-superboard-to.html -* http://lucumr.pocoo.org/2011/1/22/forwards-compatible-python/ -* http://lucumr.pocoo.org/2010/2/11/porting-to-python-3-a-guide/ -* http://wiki.python.org/moin/PortingPythonToPy3k -* https://wiki.ubuntu.com/Python/3 - -If you feel there is something missing from this document that should be added, -please email the python-porting_ mailing list. - -.. _python-porting: http://mail.python.org/mailman/listinfo/python-porting +binary access (allowing to read and/or write binary data) or text access +(allowing to read and/or write text data). You should also use :func:`io.open` +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`). + +The constructors of both ``str`` and ``bytes`` have different semantics for the +same arguments between Python 2 & 3. Passing an integer to ``bytes`` in Python 2 +will give you the string representation of the integer: ``bytes(3) == '3'``. +But in Python 3, an integer argument to ``bytes`` will give you a bytes object +as long as the integer specified, filled with null bytes: +``bytes(3) == b'\x00\x00\x00'``. A similar worry is necessary when passing a +bytes object to ``str``. In Python 2 you just get the bytes object back: +``str(b'3') == b'3'``. But in Python 3 you get the string representation of the +bytes object: ``str(b'3') == "b'3'"``. + +Finally, the indexing of binary data requires careful handling (slicing does +**not** require any special handling). In Python 2, +``b'123'[1] == b'2'`` while in Python 3 ``b'123'[1] == 50``. Because binary data +is simply a collection of binary numbers, Python 3 returns the integer value for +the byte you index on. But in Python 2 because ``bytes == str``, indexing +returns a one-item slice of bytes. The six_ project has a function +named ``six.indexbytes()`` which will return an integer like in Python 3: +``six.indexbytes(b'123', 1)``. + +To summarize: + +#. Decide which of your APIs take text and which take binary data +#. Make sure that your code that works with text also works with ``unicode`` and + code for binary data works with ``bytes`` in Python 2 (see the table above + for what methods you cannot use for each type) +#. Mark all binary literals with a ``b`` prefix, use a ``u`` prefix or + :mod:`__future__` import statement for text literals +#. 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 + +Prevent compatibility regressions +--------------------------------- + +Once you have fully translated your code to be compatible with Python 3, you +will want to make sure your code doesn't regress and stop working under +Python 3. This is especially true if you have a dependency which is blocking you +from actually running under Python 3 at the moment. + +To help with staying compatible, any new modules you create should have +at least the following block of code at the top of it:: + + from __future__ import absolute_import + from __future__ import division + from __future__ import print_function + 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_ +over your code regularly to catch compatibility regressions. This does require +you only support Python 2.7 and Python 3.4 or newer as that is Pylint's +minimum Python version support. + + +Check which dependencies block your transition +---------------------------------------------- + +**After** you have made your code compatible with Python 3 you should begin to +care about whether your dependencies have also been ported. The caniusepython3_ +project was created to help you determine which projects +-- directly or indirectly -- are blocking you from supporting Python 3. There +is both a command-line tool as well as a web interface at +https://caniusepython3.com . + +The project also provides code which you can integrate into your test suite so +that you will have a failing test when you no longer have dependencies blocking +you from using Python 3. This allows you to avoid having to manually check your +dependencies and to be notified quickly when you can start running on Python 3. + +Update your ``setup.py`` file to denote Python 3 compatibility +-------------------------------------------------------------- + +Once your code works under Python 3, you should update the classifiers in +your ``setup.py`` to contain ``Programming Language :: Python :: 3`` and to not +specify sole Python 2 support. This will tell +anyone using your code that you support Python 2 **and** 3. Ideally you will +also want to add classifiers for each major/minor version of Python you now +support. + +Use continuous integration to stay compatible +--------------------------------------------- + +Once you are able to fully run under Python 3 you will want to make sure your +code always works under both Python 2 & 3. Probably the best tool for running +your tests under multiple Python interpreters is tox_. You can then integrate +tox with your continuous integration system so that you never accidentally break +Python 2 or 3 support. + +You may also want to use use the ``-bb`` flag with the Python 3 interpreter to +trigger an exception when you are comparing bytes to strings. Usually it's +simply ``False``, but if you made a mistake in your separation of text/binary +data handling you may be accidentally comparing text and binary data. This flag +will raise an exception when that occurs to help track down such cases. + +And that's mostly it! At this point your code base is compatible with both +Python 2 and 3 simultaneously. Your testing will also be set up so that you +don't accidentally break Python 2 or 3 compatibility regardless of which version +you typically run your tests under while developing. + + +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 + +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``. + + +.. _2to3: https://docs.python.org/3/library/2to3.html +.. _caniusepython3: https://pypi.python.org/pypi/caniusepython3 +.. _cheat sheet: http://python-future.org/compatible_idioms.html +.. _coverage.py: https://pypi.python.org/pypi/coverage +.. _Futurize: http://python-future.org/automatic_conversion.html +.. _Modernize: http://python-modernize.readthedocs.org/en/latest/ +.. _Porting to Python 3: http://python3porting.com/ +.. _Pylint: https://pypi.python.org/pypi/pylint +.. _Python 3 Q & A: http://ncoghlan-devs-python-notes.readthedocs.org/en/latest/python3/questions_and_answers.html + +.. _python-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 diff --git a/Doc/howto/regex.rst b/Doc/howto/regex.rst index fbe763b3f2a3..9ae04d718d8c 100644 --- a/Doc/howto/regex.rst +++ b/Doc/howto/regex.rst @@ -852,7 +852,7 @@ keep track of the group numbers. There are two features which help with this problem. Both of them use a common syntax for regular expression extensions, so we'll look at that first. -Perl 5 is well-known for its powerful additions to standard regular expressions. +Perl 5 is well known for its powerful additions to standard regular expressions. For these new features the Perl developers couldn't choose new single-keystroke metacharacters or new special sequences beginning with ``\`` without making Perl's regular expressions confusingly different from standard REs. If they chose ``&`` as a diff --git a/Doc/howto/sockets.rst b/Doc/howto/sockets.rst index 7a9b0edc1944..04394d49f019 100644 --- a/Doc/howto/sockets.rst +++ b/Doc/howto/sockets.rst @@ -180,7 +180,7 @@ righter than others). Assuming you don't want to end the connection, the simplest solution is a fixed length message:: - class mysocket: + class MySocket: """demonstration class only - coded for clarity, not efficiency """ @@ -189,8 +189,8 @@ length message:: if sock is None: self.sock = socket.socket( socket.AF_INET, socket.SOCK_STREAM) - else: - self.sock = sock + else: + self.sock = sock def connect(self, host, port): self.sock.connect((host, port)) @@ -204,13 +204,15 @@ length message:: totalsent = totalsent + sent def myreceive(self): - msg = b'' - while len(msg) < MSGLEN: - chunk = self.sock.recv(MSGLEN-len(msg)) + chunks = [] + bytes_recd = 0 + while bytes_recd < MSGLEN: + chunk = self.sock.recv(min(MSGLEN - bytes_recd, 2048)) if chunk == b'': raise RuntimeError("socket connection broken") - msg = msg + chunk - return msg + chunks.append(chunk) + bytes_recd = bytes_recd + len(chunk) + return b''.join(chunks) The sending code here is usable for almost any messaging scheme - in Python you send strings, and you can use ``len()`` to determine its length (even if it has @@ -232,7 +234,7 @@ messages to be sent back to back (without some kind of reply), and you pass following message. You'll need to put that aside and hold onto it, until it's needed. -Prefixing the message with it's length (say, as 5 numeric characters) gets more +Prefixing the message with its length (say, as 5 numeric characters) gets more complex, because (believe it or not), you may not get all 5 characters in one ``recv``. In playing around, you'll get away with it; but in high network loads, your code will very quickly break unless you use two ``recv`` loops - the first diff --git a/Doc/howto/unicode.rst b/Doc/howto/unicode.rst index 9d48a787e85d..ee31a9c98193 100644 --- a/Doc/howto/unicode.rst +++ b/Doc/howto/unicode.rst @@ -32,11 +32,11 @@ For a while people just wrote programs that didn't display accents. In the mid-1980s an Apple II BASIC program written by a French speaker might have lines like these:: - PRINT "FICHIER EST COMPLETE." - PRINT "CARACTERE NON ACCEPTE." + PRINT "MISE A JOUR TERMINEE" + PRINT "PARAMETRES ENREGISTRES" -Those messages should contain accents (completé, caractère, accepté), -and they just look wrong to someone who can read French. +Those messages should contain accents (terminée, paramètre, enregistrés) and +they just look wrong to someone who can read French. In the 1980s, almost all personal computers were 8-bit, meaning that bytes could hold values ranging from 0 to 255. ASCII codes only went up to 127, so some @@ -49,7 +49,7 @@ another and managed to catch on. 255 characters aren't very many. For example, you can't fit both the accented characters used in Western Europe and the Cyrillic alphabet used for Russian -into the 128--255 range because there are more than 127 such characters. +into the 128--255 range because there are more than 128 such characters. You could write files using different codes (all your Russian files in a coding system called KOI8, all your French files in a different coding system called @@ -246,7 +246,7 @@ include a Unicode character in a string literal:: try: with open('/tmp/input.txt', 'r') as f: ... - except IOError: + except OSError: # 'File not found' error message. print("Fichier non trouvé") @@ -280,8 +280,9 @@ and optionally an *errors* argument. The *errors* argument specifies the response when the input string can't be converted according to the encoding's rules. Legal values for this argument are ``'strict'`` (raise a :exc:`UnicodeDecodeError` exception), ``'replace'`` (use -``U+FFFD``, ``REPLACEMENT CHARACTER``), or ``'ignore'`` (just leave the -character out of the Unicode result). +``U+FFFD``, ``REPLACEMENT CHARACTER``), ``'ignore'`` (just leave the +character out of the Unicode result), or ``'backslashreplace'`` (inserts a +``\xNN`` escape sequence). The following examples show the differences:: >>> b'\x80abc'.decode("utf-8", "strict") #doctest: +NORMALIZE_WHITESPACE @@ -291,6 +292,8 @@ The following examples show the differences:: invalid start byte >>> b'\x80abc'.decode("utf-8", "replace") '\ufffdabc' + >>> b'\x80abc'.decode("utf-8", "backslashreplace") + '\\x80abc' >>> b'\x80abc'.decode("utf-8", "ignore") 'abc' @@ -325,8 +328,9 @@ The *errors* parameter is the same as the parameter of the :meth:`~bytes.decode` method but supports a few more possible handlers. As well as ``'strict'``, ``'ignore'``, and ``'replace'`` (which in this case inserts a question mark instead of the unencodable character), there is -also ``'xmlcharrefreplace'`` (inserts an XML character reference) and -``backslashreplace`` (inserts a ``\uNNNN`` escape sequence). +also ``'xmlcharrefreplace'`` (inserts an XML character reference), +``backslashreplace`` (inserts a ``\uNNNN`` escape sequence) and +``namereplace`` (inserts a ``\N{...}`` escape sequence). The following example shows the different results:: @@ -346,6 +350,8 @@ The following example shows the different results:: b'ꀀabcd޴' >>> u.encode('ascii', 'backslashreplace') b'\\ua000abcd\\u07b4' + >>> u.encode('ascii', 'namereplace') + b'\\N{YI SYLLABLE IT}abcd\\u07b4' The low-level routines for registering and accessing the available encodings are found in the :mod:`codecs` module. Implementing new @@ -493,10 +499,11 @@ The documentation for the :mod:`unicodedata` module. The documentation for the :mod:`codecs` module. -Marc-André Lemburg gave `a presentation titled "Python and Unicode" (PDF slides) <http://downloads.egenix.com/python/Unicode-EPC2002-Talk.pdf>`_ at -EuroPython 2002. The slides are an excellent overview of the design -of Python 2's Unicode features (where the Unicode string type is -called ``unicode`` and literals start with ``u``). +Marc-André Lemburg gave `a presentation titled "Python and Unicode" (PDF slides) +<https://downloads.egenix.com/python/Unicode-EPC2002-Talk.pdf>`_ at +EuroPython 2002. The slides are an excellent overview of the design of Python +2's Unicode features (where the Unicode string type is called ``unicode`` and +literals start with ``u``). Reading and Writing Unicode Data @@ -696,13 +703,20 @@ encoding the data and writing it back out. References ---------- -One section of `Mastering Python 3 Input/Output <http://pyvideo.org/video/289/pycon-2010--mastering-python-3-i-o>`_, a PyCon 2010 talk by David Beazley, discusses text processing and binary data handling. +One section of `Mastering Python 3 Input/Output +<http://pyvideo.org/video/289/pycon-2010--mastering-python-3-i-o>`_, +a PyCon 2010 talk by David Beazley, discusses text processing and binary data handling. -The `PDF slides for Marc-André Lemburg's presentation "Writing Unicode-aware Applications in Python" <http://downloads.egenix.com/python/LSM2005-Developing-Unicode-aware-applications-in-Python.pdf>`_ +The `PDF slides for Marc-André Lemburg's presentation "Writing Unicode-aware +Applications in Python" +<https://downloads.egenix.com/python/LSM2005-Developing-Unicode-aware-applications-in-Python.pdf>`_ discuss questions of character encodings as well as how to internationalize and localize an application. These slides cover Python 2.x only. -`The Guts of Unicode in Python <http://pyvideo.org/video/1768/the-guts-of-unicode-in-python>`_ is a PyCon 2013 talk by Benjamin Peterson that discusses the internal Unicode representation in Python 3.3. +`The Guts of Unicode in Python +<http://pyvideo.org/video/1768/the-guts-of-unicode-in-python>`_ +is a PyCon 2013 talk by Benjamin Peterson that discusses the internal Unicode +representation in Python 3.3. Acknowledgements diff --git a/Doc/howto/urllib2.rst b/Doc/howto/urllib2.rst index 7b217eaef911..abec05390049 100644 --- a/Doc/howto/urllib2.rst +++ b/Doc/howto/urllib2.rst @@ -26,7 +26,7 @@ Introduction A tutorial on *Basic Authentication*, with examples in Python. -**urllib.request** is a `Python <http://www.python.org>`_ module for fetching URLs +**urllib.request** is a Python module for fetching URLs (Uniform Resource Locators). It offers a very simple interface, in the form of the *urlopen* function. This is capable of fetching URLs using a variety of different protocols. It also offers a slightly more complex interface for @@ -97,7 +97,7 @@ Data ---- Sometimes you want to send data to a URL (often the URL will refer to a CGI -(Common Gateway Interface) script [#]_ or other web application). With HTTP, +(Common Gateway Interface) script or other web application). With HTTP, this is often done using what's known as a **POST** request. This is often what your browser does when you submit a HTML form that you filled in on the web. Not all POSTs have to come from forms: you can use a POST to transmit arbitrary data @@ -160,7 +160,7 @@ We'll discuss here one particular HTTP header, to illustrate how to add headers to your HTTP request. Some websites [#]_ dislike being browsed by programs, or send different versions -to different browsers [#]_ . By default urllib identifies itself as +to different browsers [#]_. By default urllib identifies itself as ``Python-urllib/x.y`` (where ``x`` and ``y`` are the major and minor version numbers of the Python release, e.g. ``Python-urllib/2.5``), which may confuse the site, or just plain @@ -454,7 +454,7 @@ Authentication Tutorial When authentication is required, the server sends a header (as well as the 401 error code) requesting authentication. This specifies the authentication scheme -and a 'realm'. The header looks like : ``WWW-Authenticate: SCHEME +and a 'realm'. The header looks like: ``WWW-Authenticate: SCHEME realm="REALM"``. e.g. :: @@ -526,7 +526,7 @@ the ``ProxyHandler``, which is part of the normal handler chain when a proxy setting is detected. Normally that's a good thing, but there are occasions when it may not be helpful [#]_. One way to do this is to setup our own ``ProxyHandler``, with no proxies defined. This is done using similar steps to -setting up a `Basic Authentication`_ handler : :: +setting up a `Basic Authentication`_ handler: :: >>> proxy_support = urllib.request.ProxyHandler({}) >>> opener = urllib.request.build_opener(proxy_support) @@ -572,12 +572,8 @@ Footnotes This document was reviewed and revised by John Lee. -.. [#] For an introduction to the CGI protocol see - `Writing Web Applications in Python <http://www.pyzine.com/Issue008/Section_Articles/article_CGIOne.html>`_. .. [#] Like Google for example. The *proper* way to use google from a program - is to use `PyGoogle <http://pygoogle.sourceforge.net>`_ of course. See - `Voidspace Google <http://www.voidspace.org.uk/python/recipebook.shtml#google>`_ - for some examples of using the Google API. + is to use `PyGoogle <http://pygoogle.sourceforge.net>`_ of course. .. [#] Browser sniffing is a very bad practise for website design - building sites using web standards is much more sensible. Unfortunately a lot of sites still send different versions to different browsers. @@ -591,5 +587,5 @@ This document was reviewed and revised by John Lee. scripts with a localhost server, I have to prevent urllib from using the proxy. .. [#] urllib opener for SSL proxy (CONNECT method): `ASPN Cookbook Recipe - <http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/456195>`_. + <http://code.activestate.com/recipes/456195/>`_. diff --git a/Doc/howto/webservers.rst b/Doc/howto/webservers.rst index 72ccd1f690aa..9e9b69d9eb48 100644 --- a/Doc/howto/webservers.rst +++ b/Doc/howto/webservers.rst @@ -26,7 +26,7 @@ of the most popular libraries is provided. While this HOWTO tries to give an overview of Python in the web, it cannot always be as up to date as desired. Web development in Python is rapidly moving forward, so the wiki page on `Web Programming - <http://wiki.python.org/moin/WebProgramming>`_ may be more in sync with + <https://wiki.python.org/moin/WebProgramming>`_ may be more in sync with recent development. @@ -86,7 +86,7 @@ available. applications, instead of presenting a "500 Internal Server Error" message The Python wiki features a page on `CGI scripts - <http://wiki.python.org/moin/CgiScripts>`_ with some additional information + <https://wiki.python.org/moin/CgiScripts>`_ with some additional information about CGI in Python. @@ -146,7 +146,7 @@ server may not be needed. tutorial also describes the most common gotchas that might arise. * On lighttpd you need to use the `CGI module - <http://redmine.lighttpd.net/wiki/lighttpd/Docs:ModCGI>`_\ , which can be configured + <http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs_ModCGI>`_\ , which can be configured in a straightforward way. It boils down to setting ``cgi.assign`` properly. @@ -210,7 +210,7 @@ mod_python ---------- People coming from PHP often find it hard to grasp how to use Python in the web. -Their first thought is mostly `mod_python <http://www.modpython.org/>`_\ , +Their first thought is mostly `mod_python <http://modpython.org/>`_\ , because they think that this is the equivalent to ``mod_php``. Actually, there are many differences. What ``mod_python`` does is embed the interpreter into the Apache process, thus speeding up requests by not having to start a Python @@ -260,13 +260,6 @@ the latter. These days, FastCGI is never used directly. Just like ``mod_python``, it is only used for the deployment of WSGI applications. -.. seealso:: - - * `FastCGI, SCGI, and Apache: Background and Future - <http://www.vmunix.com/mark/blog/archives/2006/01/02/fastcgi-scgi-and-apache-background-and-future/>`_ - is a discussion on why the concept of FastCGI and SCGI is better than that - of mod_python. - Setting up FastCGI ^^^^^^^^^^^^^^^^^^ @@ -280,8 +273,8 @@ Each web server requires a specific module. to be loaded by Apache. * lighttpd ships its own `FastCGI module - <http://redmine.lighttpd.net/wiki/lighttpd/Docs:ModFastCGI>`_ as well as an - `SCGI module <http://redmine.lighttpd.net/wiki/lighttpd/Docs:ModSCGI>`_. + <http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs_ModFastCGI>`_ as well as an + `SCGI module <http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs_ModSCGI>`_. * `nginx <http://nginx.org/>`_ also supports `FastCGI <http://wiki.nginx.org/NginxSimplePythonFCGI>`_. @@ -309,13 +302,13 @@ following WSGI-application:: WSGIServer(app).run() This is a simple WSGI application, but you need to install `flup -<http://pypi.python.org/pypi/flup/1.0>`_ first, as flup handles the low level +<https://pypi.python.org/pypi/flup/1.0>`_ first, as flup handles the low level FastCGI access. .. seealso:: There is some documentation on `setting up Django with FastCGI - <http://docs.djangoproject.com/en/dev/howto/deployment/fastcgi/>`_, most of + <https://docs.djangoproject.com/en/dev/howto/deployment/fastcgi/>`_, most of which can be reused for other WSGI-compliant frameworks and libraries. Only the ``manage.py`` part has to be changed, the example used here can be used instead. Django does more or less the exact same thing. @@ -486,7 +479,7 @@ developing a web site. There are far more components than can be presented here. The Python wiki has a page about these components, called - `Web Components <http://wiki.python.org/moin/WebComponents>`_. + `Web Components <https://wiki.python.org/moin/WebComponents>`_. Templates @@ -522,13 +515,13 @@ Popular template engines include: * `Mako <http://www.makotemplates.org/>`_ * `Genshi <http://genshi.edgewall.org/>`_ - * `Jinja <http://jinja.pocoo.org/2/>`_ + * `Jinja <http://jinja.pocoo.org/>`_ .. seealso:: There are many template engines competing for attention, because it is pretty easy to create them in Python. The page `Templating - <http://wiki.python.org/moin/Templating>`_ in the wiki lists a big, + <https://wiki.python.org/moin/Templating>`_ in the wiki lists a big, ever-growing number of these. The three listed above are considered "second generation" template engines and are a good place to start. @@ -578,11 +571,11 @@ alternate storage mechanism. .. seealso:: - * `Persistence Tools <http://wiki.python.org/moin/PersistenceTools>`_ lists + * `Persistence Tools <https://wiki.python.org/moin/PersistenceTools>`_ lists possibilities on how to save data in the file system. Some of these modules are part of the standard library - * `Database Programming <http://wiki.python.org/moin/DatabaseProgramming>`_ + * `Database Programming <https://wiki.python.org/moin/DatabaseProgramming>`_ helps with choosing a method for saving data * `SQLAlchemy <http://www.sqlalchemy.org/>`_, the most powerful OR-Mapper @@ -644,7 +637,7 @@ here. Instead we will briefly touch on some of the most popular. Django ^^^^^^ -`Django <http://www.djangoproject.com/>`_ is a framework consisting of several +`Django <https://www.djangoproject.com/>`_ is a framework consisting of several tightly coupled elements which were written from scratch and work together very well. It includes an ORM which is quite powerful while being simple to use, and has a great online administration interface which makes it possible to edit @@ -657,7 +650,7 @@ which make it possible to create web sites almost without writing any Python cod It has a big, international community, the members of which have created many web sites. There are also a lot of add-on projects which extend Django's normal functionality. This is partly due to Django's well written `online -documentation <http://docs.djangoproject.com/>`_ and the `Django book +documentation <https://docs.djangoproject.com/>`_ and the `Django book <http://www.djangobook.com/>`_. @@ -665,7 +658,7 @@ documentation <http://docs.djangoproject.com/>`_ and the `Django book Although Django is an MVC-style framework, it names the elements differently, which is described in the `Django FAQ - <http://docs.djangoproject.com/en/dev/faq/general/#django-appears-to-be-a-mvc-framework-but-you-call-the-controller-the-view-and-the-view-the-template-how-come-you-don-t-use-the-standard-names>`_. + <https://docs.djangoproject.com/en/dev/faq/general/#django-appears-to-be-a-mvc-framework-but-you-call-the-controller-the-view-and-the-view-the-template-how-come-you-don-t-use-the-standard-names>`_. TurboGears @@ -687,7 +680,7 @@ published, which is a good starting point. The newest version of TurboGears, version 2.0, moves even further in direction of WSGI support and a component-based architecture. TurboGears 2 is based on the WSGI stack of another popular component-based web framework, `Pylons -<http://pylonshq.com/>`_. +<http://www.pylonsproject.org/>`_. Zope @@ -708,7 +701,7 @@ access to these components to the wider Python community. There is even a separate framework based on the Zope components: `Grok <http://grok.zope.org/>`_. -Zope is also the infrastructure used by the `Plone <http://plone.org/>`_ content +Zope is also the infrastructure used by the `Plone <https://plone.org/>`_ content management system, one of the most powerful and popular content management systems available. @@ -732,9 +725,7 @@ found in the Python wiki. .. seealso:: The Python wiki contains an extensive list of `web frameworks - <http://wiki.python.org/moin/WebFrameworks>`_. + <https://wiki.python.org/moin/WebFrameworks>`_. Most frameworks also have their own mailing lists and IRC channels, look out - for these on the projects' web sites. There is also a general "Python in the - Web" IRC channel on freenode called `#python.web - <http://wiki.python.org/moin/PoundPythonWeb>`_. + for these on the projects' web sites. diff --git a/Doc/includes/email-alternative-new-api.py b/Doc/includes/email-alternative-new-api.py new file mode 100644 index 000000000000..c1255a68dfb5 --- /dev/null +++ b/Doc/includes/email-alternative-new-api.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python3 + +import smtplib + +from email.message import EmailMessage +from email.headerregistry import Address +from email.utils import make_msgid + +# Create the base text message. +msg = EmailMessage() +msg['Subject'] = "Ayons asperges pour le déjeuner" +msg['From'] = Address("Pepé Le Pew", "pepe@example.com") +msg['To'] = (Address("Penelope Pussycat", "penelope@example.com"), + Address("Fabrette Pussycat", "fabrette@example.com")) +msg.set_content("""\ +Salut! + +Cela ressemble à un excellent recipie[1] déjeuner. + +[1] http://www.yummly.com/recipe/Roasted-Asparagus-Epicurious-203718 + +--Pepé +""") + +# Add the html version. This converts the message into a multipart/alternative +# container, with the original text message as the first part and the new html +# message as the second part. +asparagus_cid = make_msgid() +msg.add_alternative("""\ +<html> + <head></head> + <body> + <p>Salut!<\p> + <p>Cela ressemble à un excellent + <a href="http://www.yummly.com/recipe/Roasted-Asparagus-Epicurious-203718> + recipie + </a> déjeuner. + </p> + <img src="cid:{asparagus_cid}" \> + </body> +</html> +""".format(asparagus_cid=asparagus_cid[1:-1]), subtype='html') +# note that we needed to peel the <> off the msgid for use in the html. + +# Now add the related image to the html part. +with open("roasted-asparagus.jpg", 'rb') as img: + msg.get_payload()[1].add_related(img.read(), 'image', 'jpeg', + cid=asparagus_cid) + +# Make a local copy of what we are going to send. +with open('outgoing.msg', 'wb') as f: + f.write(bytes(msg)) + +# Send the message via local SMTP server. +with smtplib.SMTP('localhost') as s: + s.send_message(msg) diff --git a/Doc/includes/email-alternative.py b/Doc/includes/email-alternative.py old mode 100644 new mode 100755 index 33c430ab95ca..85070f36ae6d --- a/Doc/includes/email-alternative.py +++ b/Doc/includes/email-alternative.py @@ -17,14 +17,14 @@ msg['To'] = you # Create the body of the message (a plain-text and an HTML version). -text = "Hi!\nHow are you?\nHere is the link you wanted:\nhttp://www.python.org" +text = "Hi!\nHow are you?\nHere is the link you wanted:\nhttps://www.python.org" html = """\ <html> <head></head> <body> <p>Hi!<br> How are you?<br> - Here is the <a href="http://www.python.org">link</a> you wanted. + Here is the <a href="https://www.python.org">link</a> you wanted. </p> </body> </html> diff --git a/Doc/includes/email-read-alternative-new-api.py b/Doc/includes/email-read-alternative-new-api.py new file mode 100644 index 000000000000..8ab4e9fd164d --- /dev/null +++ b/Doc/includes/email-read-alternative-new-api.py @@ -0,0 +1,74 @@ +import os +import sys +import tempfile +import mimetypes +import webbrowser + +# Import the email modules we'll need +from email import policy +from email.parser import BytesParser + +# An imaginary module that would make this work and be safe. +from imaginary import magic_html_parser + +# In a real program you'd get the filename from the arguments. +msg = BytesParser(policy=policy.default).parse(open('outgoing.msg', 'rb')) + +# Now the header items can be accessed as a dictionary, and any non-ASCII will +# be converted to unicode: +print('To:', msg['to']) +print('From:', msg['from']) +print('Subject:', msg['subject']) + +# If we want to print a priview of the message content, we can extract whatever +# the least formatted payload is and print the first three lines. Of course, +# if the message has no plain text part printing the first three lines of html +# is probably useless, but this is just a conceptual example. +simplest = msg.get_body(preferencelist=('plain', 'html')) +print() +print(''.join(simplest.get_content().splitlines(keepends=True)[:3])) + +ans = input("View full message?") +if ans.lower()[0] == 'n': + sys.exit() + +# We can extract the richest alternative in order to display it: +richest = msg.get_body() +partfiles = {} +if richest['content-type'].maintype == 'text': + if richest['content-type'].subtype == 'plain': + for line in richest.get_content().splitlines(): + print(line) + sys.exit() + elif richest['content-type'].subtype == 'html': + body = richest + else: + print("Don't know how to display {}".format(richest.get_content_type())) + sys.exit() +elif richest['content-type'].content_type == 'multipart/related': + body = richest.get_body(preferencelist=('html')) + for part in richest.iter_attachments(): + fn = part.get_filename() + if fn: + extension = os.path.splitext(part.get_filename())[1] + else: + extension = mimetypes.guess_extension(part.get_content_type()) + with tempfile.NamedTemporaryFile(suffix=extension, delete=False) as f: + f.write(part.get_content()) + # again strip the <> to go from email form of cid to html form. + partfiles[part['content-id'][1:-1]] = f.name +else: + print("Don't know how to display {}".format(richest.get_content_type())) + sys.exit() +with tempfile.NamedTemporaryFile(mode='w', delete=False) as f: + # The magic_html_parser has to rewrite the href="cid:...." attributes to + # point to the filenames in partfiles. It also has to do a safety-sanitize + # of the html. It could be written using html.parser. + f.write(magic_html_parser(body.get_content(), partfiles)) +webbrowser.open(f.name) +os.remove(f.name) +for fn in partfiles.values(): + os.remove(fn) + +# Of course, there are lots of email messages that could break this simple +# minded program, but it will handle the most common ones. diff --git a/Doc/includes/run-func.c b/Doc/includes/run-func.c index 1c9860d7a823..986d670319ff 100644 --- a/Doc/includes/run-func.c +++ b/Doc/includes/run-func.c @@ -13,7 +13,7 @@ main(int argc, char *argv[]) } Py_Initialize(); - pName = PyUnicode_FromString(argv[1]); + pName = PyUnicode_DecodeFSDefault(argv[1]); /* Error checking of pName left out */ pModule = PyImport_Import(pName); diff --git a/Doc/install/index.rst b/Doc/install/index.rst index 738aaa152fc8..876f350f90e8 100644 --- a/Doc/install/index.rst +++ b/Doc/install/index.rst @@ -2,9 +2,9 @@ .. _install-index: -***************************** - Installing Python Modules -***************************** +******************************************** + Installing Python Modules (Legacy version) +******************************************** :Author: Greg Ward @@ -20,12 +20,20 @@ Finally, it might be useful to include all the material from my "Care and Feeding of a Python Installation" talk in here somewhere. Yow! -.. topic:: Abstract +This document describes the Python Distribution Utilities ("Distutils") from the +end-user's point-of-view, describing how to extend the capabilities of a +standard Python installation by building and installing third-party Python +modules and extensions. - This document describes the Python Distribution Utilities ("Distutils") from the - end-user's point-of-view, describing how to extend the capabilities of a - standard Python installation by building and installing third-party Python - modules and extensions. + +.. note:: + + This guide only covers the basic tools for installing extensions that are + provided as part of this version of Python. Third party tools offer easier + to use and more secure alternatives. Refer to the + `quick recommendations section + <https://python-packaging-user-guide.readthedocs.org/en/latest/current.html>`__ + in the Python Packaging User Guide for more information. .. _inst-intro: @@ -50,7 +58,8 @@ new goodies to their toolbox. You don't need to know Python to read this document; there will be some brief forays into using Python's interactive mode to explore your installation, but that's it. If you're looking for information on how to distribute your own Python modules so that others may use them, see -the :ref:`distutils-index` manual. +the :ref:`distutils-index` manual. :ref:`debug-setup-script` may also be of +interest. .. _inst-trivial-install: @@ -352,7 +361,7 @@ And here are the values used on Windows: Type of file Installation directory =============== =========================================================== modules :file:`{userbase}\\Python{XY}\\site-packages` -scripts :file:`{userbase}\\Scripts` +scripts :file:`{userbase}\\Python{XY}\\Scripts` data :file:`{userbase}` C headers :file:`{userbase}\\Python{XY}\\Include\\{distname}` =============== =========================================================== @@ -1003,7 +1012,7 @@ section :ref:`inst-config-files`.) .. seealso:: - `C++Builder Compiler <http://www.codegear.com/downloads/free/cppbuilder>`_ + `C++Builder Compiler <http://www.embarcadero.com/downloads>`_ Information about the free C++ compiler from Borland, including links to the download pages. @@ -1075,7 +1084,7 @@ normal libraries do. .. seealso:: - `Building Python modules on MS Windows platform with MinGW <http://www.zope.org/Members/als/tips/win32_mingw_modules>`_ + `Building Python modules on MS Windows platform with MinGW <http://old.zope.org/Members/als/tips/win32_mingw_modules>`_ Information about building the required libraries for the MinGW environment. @@ -1084,7 +1093,7 @@ normal libraries do. .. [#] This also means you could replace all existing COFF-libraries with OMF-libraries of the same name. -.. [#] Check http://sources.redhat.com/cygwin/ and http://www.mingw.org/ for more +.. [#] Check http://www.sourceware.org/cygwin/ and http://www.mingw.org/ for more information .. [#] Then you have no POSIX emulation available, but you also don't need diff --git a/Doc/installing/index.rst b/Doc/installing/index.rst new file mode 100644 index 000000000000..973c689861f5 --- /dev/null +++ b/Doc/installing/index.rst @@ -0,0 +1,220 @@ +.. highlightlang:: none + +.. _installing-index: + +***************************** + Installing Python Modules +***************************** + +:Email: distutils-sig@python.org + +As a popular open source development project, Python has an active +supporting community of contributors and users that also make their software +available for other Python developers to use under open source license terms. + +This allows Python users to share and collaborate effectively, benefiting +from the solutions others have already created to common (and sometimes +even rare!) problems, as well as potentially contributing their own +solutions to the common pool. + +This guide covers the installation part of the process. For a guide to +creating and sharing your own Python projects, refer to the +:ref:`distribution guide <distributing-index>`. + +.. note:: + + For corporate and other institutional users, be aware that many + organisations have their own policies around using and contributing to + open source software. Please take such policies into account when making + use of the distribution and installation tools provided with Python. + + +Key terms +========= + +* ``pip`` is the preferred installer program. Starting with Python 3.4, it + is included by default with the Python binary installers. +* a virtual environment is a semi-isolated Python environment that allows + packages to be installed for use by a particular application, rather than + being installed system wide +* ``pyvenv`` is the standard tool for creating virtual environments, and has + been part of Python since Python 3.3. Starting with Python 3.4, it + defaults to installing ``pip`` into all created virtual environments +* ``virtualenv`` is a third party alternative (and predecessor) to + ``pyvenv``. It allows virtual environments to be used on versions of + Python prior to 3.4, which either don't provide ``pyvenv`` at all, or + aren't able to automatically install ``pip`` into created environments. +* the `Python Packaging Index <https://pypi.python.org/pypi>`__ is a public + repository of open source licensed packages made available for use by + other Python users +* the `Python Packaging Authority + <https://packaging.python.org/en/latest/future.html>`__ are the group of + developers and documentation authors responsible for the maintenance and + evolution of the standard packaging tools and the associated metadata and + file format standards. They maintain a variety of tools, documentation + and issue trackers on both `GitHub <https://github.com/pypa>`__ and + `BitBucket <https://bitbucket.org/pypa/>`__. +* ``distutils`` is the original build and distribution system first added to + the Python standard library in 1998. While direct use of ``distutils`` is + being phased out, it still laid the foundation for the current packaging + and distribution infrastructure, and it not only remains part of the + standard library, but its name lives on in other ways (such as the name + of the mailing list used to coordinate Python packaging standards + development). + + +Basic usage +=========== + +The standard packaging tools are all designed to be used from the command +line. + +The following command will install the latest version of a module and its +dependencies from the Python Packaging Index:: + + python -m pip install SomePackage + +.. note:: + + For POSIX users (including Mac OS X and Linux users), the examples in + this guide assume the use of a :term:`virtual environment`. + + For Windows users, the examples in this guide assume that the option to + adjust the system PATH environment variable was selected when installing + Python. + +It's also possible to specify an exact or minimum version directly on the +command line:: + + python -m pip install SomePackage==1.0.4 # specific version + python -m pip install 'SomePackage>=1.0.4' # minimum version + +Normally, if a suitable module is already installed, attempting to install +it again will have no effect. Upgrading existing modules must be requested +explicitly:: + + python -m pip install --upgrade SomePackage + +More information and resources regarding ``pip`` and its capabilities can be +found in the `Python Packaging User Guide <https://packaging.python.org>`__. + +``pyvenv`` has its own documentation at :ref:`scripts-pyvenv`. Installing +into an active virtual environment uses the commands shown above. + +.. seealso:: + + `Python Packaging User Guide: Installing Python Distribution Packages + <https://packaging.python.org/en/latest/installing.html#installing-python-distribution-packages>`__ + + +How do I ...? +============= + +These are quick answers or links for some common tasks. + +... install ``pip`` in versions of Python prior to Python 3.4? +-------------------------------------------------------------- + +Python only started bundling ``pip`` with Python 3.4. For earlier versions, +``pip`` needs to be "bootstrapped" as described in the Python Packaging +User Guide. + +.. seealso:: + + `Python Packaging User Guide: Setup for Installing Distribution Packages + <https://packaging.python.org/en/latest/installing.html#setup-for-installing-distribution-packages>`__ + + +.. installing-per-user-installation: + +... install packages just for the current user? +----------------------------------------------- + +Passing the ``--user`` option to ``python -m pip install`` will install a +package just for the current user, rather than for all users of the system. + + +... install scientific Python packages? +--------------------------------------- + +A number of scientific Python packages have complex binary dependencies, and +aren't currently easy to install using ``pip`` directly. At this point in +time, it will often be easier for users to install these packages by +`other means +<https://packaging.python.org/en/latest/science.html>`__ +rather than attempting to install them with ``pip``. + +.. seealso:: + + `Python Packaging User Guide: Installing Scientific Packages + <https://packaging.python.org/en/latest/science.html>`__ + + +... work with multiple versions of Python installed in parallel? +---------------------------------------------------------------- + +On Linux, Mac OS X and other POSIX systems, use the versioned Python commands +in combination with the ``-m`` switch to run the appropriate copy of +``pip``:: + + python2 -m pip install SomePackage # default Python 2 + python2.7 -m pip install SomePackage # specifically Python 2.7 + python3 -m pip install SomePackage # default Python 3 + python3.4 -m pip install SomePackage # specifically Python 3.4 + +(appropriately versioned ``pip`` commands may also be available) + +On Windows, use the ``py`` Python launcher in combination with the ``-m`` +switch:: + + py -2 -m pip install SomePackage # default Python 2 + py -2.7 -m pip install SomePackage # specifically Python 2.7 + py -3 -m pip install SomePackage # default Python 3 + py -3.4 -m pip install SomePackage # specifically Python 3.4 + +.. other questions: + + Once the Development & Deployment part of PPUG is fleshed out, some of + those sections should be linked from new questions here (most notably, + we should have a question about avoiding depending on PyPI that links to + https://packaging.python.org/en/latest/deployment.html#pypi-mirrors-and-caches) + + +Common installation issues +========================== + +Installing into the system Python on Linux +------------------------------------------ + +On Linux systems, a Python installation will typically be included as part +of the distribution. Installing into this Python installation requires +root access to the system, and may interfere with the operation of the +system package manager and other components of the system if a component +is unexpectedly upgraded using ``pip``. + +On such systems, it is often better to use a virtual environment or a +per-user installation when installing packages with ``pip``. + + +Installing binary extensions +---------------------------- + +Python has typically relied heavily on source based distribution, with end +users being expected to compile extension modules from source as part of +the installation process. + +With the introduction of support for the binary ``wheel`` format, and the +ability to publish wheels for at least Windows and Mac OS X through the +Python Packaging Index, this problem is expected to diminish over time, +as users are more regularly able to install pre-built extensions rather +than needing to build them themselves. + +Some of the solutions for installing `scientific software +<https://packaging.python.org/en/latest/science.html>`__ +that is not yet available as pre-built ``wheel`` files may also help with +obtaining other binary extensions without needing to build them locally. + +.. seealso:: + + `Python Packaging User Guide: Binary Extensions + <https://packaging.python.org/en/latest/extensions.html>`__ diff --git a/Doc/library/2to3.rst b/Doc/library/2to3.rst index 1092e6b6207d..6473861883f3 100644 --- a/Doc/library/2to3.rst +++ b/Doc/library/2to3.rst @@ -392,7 +392,7 @@ and off individually. They are described here in more detail. Replaces use of the :class:`set` constructor with set literals. This fixer is optional. -.. 2to3fixer:: standard_error +.. 2to3fixer:: standarderror Renames :exc:`StandardError` to :exc:`Exception`. diff --git a/Doc/library/__main__.rst b/Doc/library/__main__.rst index a1d3c24bea5a..a46993d55ed2 100644 --- a/Doc/library/__main__.rst +++ b/Doc/library/__main__.rst @@ -5,13 +5,19 @@ .. module:: __main__ :synopsis: The environment where the top-level script is run. +``'__main__'`` is the name of the scope in which top-level code executes. +A module's __name__ is set equal to ``'__main__'`` when read from +standard input, a script, or from an interactive prompt. -This module represents the (otherwise anonymous) scope in which the -interpreter's main program executes --- commands read either from standard -input, from a script file, or from an interactive prompt. It is this -environment in which the idiomatic "conditional script" stanza causes a script -to run:: +A module can discover whether or not it is running in the main scope by +checking its own ``__name__``, which allows a common idiom for conditionally +executing code in a module when it is run as a script or with ``python +-m`` but not when it is imported:: if __name__ == "__main__": + # execute only if run as a script main() +For a package, the same effect can be achieved by including a +``__main__.py`` module, the contents of which will be executed when the +module is run with ``-m``. diff --git a/Doc/library/_thread.rst b/Doc/library/_thread.rst index 2e130c1e52df..a787e2fd4b79 100644 --- a/Doc/library/_thread.rst +++ b/Doc/library/_thread.rst @@ -176,10 +176,6 @@ In addition to these methods, lock objects can also be used via the * Calling :func:`sys.exit` or raising the :exc:`SystemExit` exception is equivalent to calling :func:`_thread.exit`. -* Not all built-in functions that may block waiting for I/O allow other threads - to run. (The most popular ones (:func:`time.sleep`, :meth:`io.FileIO.read`, - :func:`select.select`) work as expected.) - * It is not possible to interrupt the :meth:`acquire` method on a lock --- the :exc:`KeyboardInterrupt` exception will happen after the lock has been acquired. diff --git a/Doc/library/abc.rst b/Doc/library/abc.rst index 7853d31b55a1..7a73704bf682 100644 --- a/Doc/library/abc.rst +++ b/Doc/library/abc.rst @@ -318,9 +318,9 @@ The :mod:`abc` module also provides the following functions: Returns the current abstract base class cache token. - The token is an opaque integer identifying the current version of the - abstract base class cache for virtual subclasses. This number changes - with every call to :meth:`ABCMeta.register` on any ABC. + The token is an opaque object (that supports equality testing) identifying + the current version of the abstract base class cache for virtual subclasses. + The token changes with every call to :meth:`ABCMeta.register` on any ABC. .. versionadded:: 3.4 diff --git a/Doc/library/aifc.rst b/Doc/library/aifc.rst index 9ffb5a3ffe9d..6fbcf286cf1f 100644 --- a/Doc/library/aifc.rst +++ b/Doc/library/aifc.rst @@ -54,8 +54,8 @@ Module :mod:`aifc` defines the following function: The :func:`.open` function may be used in a :keyword:`with` statement. When the :keyword:`with` block completes, the :meth:`~aifc.close` method is called. -.. versionchanged:: 3.4 - Support for the :keyword:`with` statement was added. + .. versionchanged:: 3.4 + Support for the :keyword:`with` statement was added. Objects returned by :func:`.open` when a file is opened for reading have the following methods: @@ -226,7 +226,7 @@ number of frames must be filled in. file parameters have been set. .. versionchanged:: 3.4 - Any :term:`bytes-like object`\ s are now accepted. + Any :term:`bytes-like object` is now accepted. .. method:: aifc.writeframesraw(data) @@ -235,7 +235,7 @@ number of frames must be filled in. updated. .. versionchanged:: 3.4 - Any :term:`bytes-like object`\ s are now accepted. + Any :term:`bytes-like object` is now accepted. .. method:: aifc.close() diff --git a/Doc/library/allos.rst b/Doc/library/allos.rst index bf9171744791..f7105d8af8e2 100644 --- a/Doc/library/allos.rst +++ b/Doc/library/allos.rst @@ -16,7 +16,6 @@ but they are available on most other systems as well. Here's an overview: io.rst time.rst argparse.rst - optparse.rst getopt.rst logging.rst logging.config.rst diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index 51abc7a90965..1f75cd9e5f2e 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -135,7 +135,7 @@ ArgumentParser objects formatter_class=argparse.HelpFormatter, \ prefix_chars='-', fromfile_prefix_chars=None, \ argument_default=None, conflict_handler='error', \ - add_help=True) + add_help=True, allow_abbrev=True) Create a new :class:`ArgumentParser` object. All parameters should be passed as keyword arguments. Each parameter has its own more detailed description @@ -169,6 +169,12 @@ ArgumentParser objects * 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``) + + .. versionchanged:: 3.5 + *allow_abbrev* parameter was added. + The following sections describe how each of these are used. @@ -518,6 +524,26 @@ calls, we supply ``argument_default=SUPPRESS``:: >>> parser.parse_args([]) Namespace() +.. _allow_abbrev: + +allow_abbrev +^^^^^^^^^^^^ + +Normally, when you pass an argument list to the +:meth:`~ArgumentParser.parse_args` method of a :class:`ArgumentParser`, +it :ref:`recognizes abbreviations <prefix-matching>` of long options. + +This feature can be disabled by setting ``allow_abbrev`` to ``False``:: + + >>> parser = argparse.ArgumentParser(prog='PROG', allow_abbrev=False) + >>> parser.add_argument('--foobar', action='store_true') + >>> parser.add_argument('--foonley', action='store_false') + >>> parser.parse_args([--foon]) + usage: PROG [-h] [--foobar] [--foonley] + PROG: error: unrecognized arguments: --foon + +.. versionadded:: 3.5 + conflict_handler ^^^^^^^^^^^^^^^^ @@ -683,7 +709,7 @@ action actions can do just about anything with the command-line arguments associated with them, though most actions simply add an attribute to the object returned by :meth:`~ArgumentParser.parse_args`. The ``action`` keyword argument specifies -how the command-line arguments should be handled. The supported actions are: +how the command-line arguments should be handled. The supplied actions are: * ``'store'`` - This just stores the argument's value. This is the default action. For example:: @@ -757,28 +783,18 @@ how the command-line arguments should be handled. The supported actions are: >>> parser.parse_args(['--version']) PROG 2.0 -You can also specify an arbitrary action by passing an object that implements -the Action API. The easiest way to do this is to extend -:class:`argparse.Action`, supplying an appropriate ``__call__`` method. The -``__call__`` method should accept four parameters: - -* ``parser`` - The ArgumentParser object which contains this action. - -* ``namespace`` - The :class:`Namespace` object that will be returned by - :meth:`~ArgumentParser.parse_args`. Most actions add an attribute to this - object. - -* ``values`` - The associated command-line arguments, with any type conversions - applied. (Type conversions are specified with the type_ keyword argument to - :meth:`~ArgumentParser.add_argument`.) - -* ``option_string`` - The option string that was used to invoke this action. - The ``option_string`` argument is optional, and will be absent if the action - is associated with a positional argument. +You may also specify an arbitrary action by passing an Action subclass or +other object that implements the same interface. The recommended way to do +this is to extend :class:`Action`, overriding the ``__call__`` method +and optionally the ``__init__`` method. An example of a custom action:: >>> class FooAction(argparse.Action): + ... def __init__(self, option_strings, dest, nargs=None, **kwargs): + ... if nargs is not None: + ... raise ValueError("nargs not allowed") + ... super(FooAction, self).__init__(option_strings, dest, **kwargs) ... def __call__(self, parser, namespace, values, option_string=None): ... print('%r %r %r' % (namespace, values, option_string)) ... setattr(namespace, self.dest, values) @@ -792,6 +808,7 @@ An example of a custom action:: >>> args Namespace(bar='1', foo='2') +For more details, see :class:`Action`. nargs ^^^^^ @@ -1238,6 +1255,49 @@ behavior:: >>> parser.parse_args('--foo XXX'.split()) Namespace(bar='XXX') +Action classes +^^^^^^^^^^^^^^ + +Action classes implement the Action API, a callable which returns a callable +which processes arguments from the command-line. Any object which follows +this API may be passed as the ``action`` parameter to +:meth:`add_argument`. + +.. class:: Action(option_strings, dest, nargs=None, const=None, default=None, \ + type=None, choices=None, required=False, help=None, \ + metavar=None) + +Action objects are used by an ArgumentParser to represent the information +needed to parse a single argument from one or more strings from the +command line. The Action class must accept the two positional arguments +plus any keyword arguments passed to :meth:`ArgumentParser.add_argument` +except for the ``action`` itself. + +Instances of Action (or return value of any callable to the ``action`` +parameter) should have attributes "dest", "option_strings", "default", "type", +"required", "help", etc. defined. The easiest way to ensure these attributes +are defined is to call ``Action.__init__``. + +Action instances should be callable, so subclasses must override the +``__call__`` method, which should accept four parameters: + +* ``parser`` - The ArgumentParser object which contains this action. + +* ``namespace`` - The :class:`Namespace` object that will be returned by + :meth:`~ArgumentParser.parse_args`. Most actions add an attribute to this + object using :func:`setattr`. + +* ``values`` - The associated command-line arguments, with any type conversions + applied. Type conversions are specified with the type_ keyword argument to + :meth:`~ArgumentParser.add_argument`. + +* ``option_string`` - The option string that was used to invoke this action. + The ``option_string`` argument is optional, and will be absent if the action + is associated with a positional argument. + +The ``__call__`` method may perform arbitrary actions, but will typically set +attributes on the ``namespace`` based on ``dest`` and ``values``. + The parse_args() method ----------------------- @@ -1376,9 +1436,9 @@ argument:: Argument abbreviations (prefix matching) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The :meth:`~ArgumentParser.parse_args` method allows long options to be -abbreviated to a prefix, if the abbreviation is unambiguous (the prefix matches -a unique option):: +The :meth:`~ArgumentParser.parse_args` method :ref:`by default <allow_abbrev>` +allows long options to be abbreviated to a prefix, if the abbreviation is +unambiguous (the prefix matches a unique option):: >>> parser = argparse.ArgumentParser(prog='PROG') >>> parser.add_argument('-bacon') @@ -1392,6 +1452,7 @@ a unique option):: PROG: error: ambiguous option: -ba could match -badger, -bacon An error is produced for arguments that could produce more than one options. +This feature can be disabled by setting :ref:`allow_abbrev` to ``False``. Beyond ``sys.argv`` @@ -1487,12 +1548,15 @@ Sub-commands * parser_class - class which will be used to create sub-parser instances, by default the class of the current parser (e.g. ArgumentParser) - * dest - name of the attribute under which sub-command name will be + * action_ - the basic type of action to be taken when this argument is + encountered at the command line + + * dest_ - name of the attribute under which sub-command name will be stored; by default None and no value is stored - * help - help for sub-parser group in help output, by default None + * help_ - help for sub-parser group in help output, by default None - * metavar - string presenting available sub-commands in help; by default it + * metavar_ - string presenting available sub-commands in help; by default it is None and presents sub-commands in form {cmd1, cmd2, ..} Some example usage:: @@ -1671,6 +1735,9 @@ FileType objects >>> parser.parse_args(['-']) Namespace(infile=<_io.TextIOWrapper name='<stdin>' encoding='UTF-8'>) + .. versionadded:: 3.4 + The *encodings* and *errors* keyword arguments. + Argument groups ^^^^^^^^^^^^^^^ @@ -1870,7 +1937,7 @@ Customizing file parsing Arguments that are read from a file (see the *fromfile_prefix_chars* keyword argument to the :class:`ArgumentParser` constructor) are read one - argument per line. :meth:`convert_arg_line_to_args` can be overriden for + argument per line. :meth:`convert_arg_line_to_args` can be overridden for fancier reading. This method takes a single argument *arg_line* which is a string read from @@ -1912,6 +1979,16 @@ transparently, particularly with the changes required to support the new :mod:`optparse` had either been copy-pasted over or monkey-patched, it no longer seemed practical to try to maintain the backwards compatibility. +The :mod:`argparse` module improves on the standard library :mod:`optparse` +module in a number of ways including: + +* Handling positional arguments. +* Supporting sub-commands. +* Allowing alternative option prefixes like ``+`` and ``/``. +* Handling zero-or-more and one-or-more style arguments. +* Producing more informative usage messages. +* Providing a much simpler interface for custom ``type`` and ``action``. + A partial upgrade path from :mod:`optparse` to :mod:`argparse`: * Replace all :meth:`optparse.OptionParser.add_option` calls with diff --git a/Doc/library/ast.rst b/Doc/library/ast.rst index daf28de29e72..1ee511021157 100644 --- a/Doc/library/ast.rst +++ b/Doc/library/ast.rst @@ -115,13 +115,15 @@ and classes for traversing abstract syntax trees: .. function:: literal_eval(node_or_string) - Safely evaluate an expression node or a string containing a Python - expression. The string or node provided may only consist of the following - Python literal structures: strings, bytes, numbers, tuples, lists, dicts, - sets, booleans, and ``None``. - - This can be used for safely evaluating strings containing Python expressions - from untrusted sources without the need to parse the values oneself. + Safely evaluate an expression node or a string containing a Python literal or + container display. The string or node provided may only consist of the + following Python literal structures: strings, bytes, numbers, tuples, lists, + dicts, sets, booleans, and ``None``. + + This can be used for safely evaluating strings containing Python values from + untrusted sources without the need to parse the values oneself. It is not + capable of evaluating arbitrarily complex expressions, for example involving + operators or indexing. .. versionchanged:: 3.2 Now allows bytes and set literals. diff --git a/Doc/library/asynchat.rst b/Doc/library/asynchat.rst index 7b8107434a70..794da8cced7f 100644 --- a/Doc/library/asynchat.rst +++ b/Doc/library/asynchat.rst @@ -61,8 +61,8 @@ connection requests. have only one method, :meth:`more`, which should return data to be transmitted on the channel. The producer indicates exhaustion (*i.e.* that it contains no more data) by - having its :meth:`more` method return the empty string. At this point the - :class:`async_chat` object removes the producer from the fifo and starts + having its :meth:`more` method return the empty bytes object. At this point + the :class:`async_chat` object removes the producer from the fifo and starts using the next producer, if any. When the producer fifo is empty the :meth:`handle_write` method does nothing. You use the channel object's :meth:`set_terminator` method to describe how to recognize the end of, or @@ -147,40 +147,6 @@ connection requests. by the channel after :meth:`found_terminator` is called. -asynchat - Auxiliary Classes ------------------------------------------- - -.. class:: fifo(list=None) - - A :class:`fifo` holding data which has been pushed by the application but - not yet popped for writing to the channel. A :class:`fifo` is a list used - to hold data and/or producers until they are required. If the *list* - argument is provided then it should contain producers or data items to be - written to the channel. - - - .. method:: is_empty() - - Returns ``True`` if and only if the fifo is empty. - - - .. method:: first() - - Returns the least-recently :meth:`push`\ ed item from the fifo. - - - .. method:: push(data) - - Adds the given data (which may be a string or a producer object) to the - producer fifo. - - - .. method:: pop() - - If the fifo is not empty, returns ``True, first()``, deleting the popped - item. Returns ``False, None`` for an empty fifo. - - .. _asynchat-example: asynchat Example @@ -226,7 +192,7 @@ any extraneous data sent by the web client are ignored. :: def found_terminator(self): if self.reading_headers: self.reading_headers = False - self.parse_headers("".join(self.ibuffer)) + self.parse_headers(b"".join(self.ibuffer)) self.ibuffer = [] if self.op.upper() == b"POST": clen = self.headers.getheader("content-length") diff --git a/Doc/library/asyncio-dev.rst b/Doc/library/asyncio-dev.rst new file mode 100644 index 000000000000..bf77a8fb7945 --- /dev/null +++ b/Doc/library/asyncio-dev.rst @@ -0,0 +1,394 @@ +.. currentmodule:: asyncio + +.. _asyncio-dev: + +Develop with asyncio +==================== + +Asynchronous programming is different than classical "sequential" programming. +This page lists common traps and explains how to avoid them. + + +.. _asyncio-debug-mode: + +Debug mode of asyncio +--------------------- + +The implementation of :mod:`asyncio` module has been written for performances. +To development with asyncio, it's required to enable the debug checks to ease +the development of asynchronous code. + +Setup an application to enable all debug checks: + +* Enable the asyncio debug mode globally by setting the environment variable + :envvar:`PYTHONASYNCIODEBUG` to ``1`` +* Set the log level of the :ref:`asyncio logger <asyncio-logger>` to + :py:data:`logging.DEBUG`. For example, call + ``logging.basicConfig(level=logging.DEBUG)`` at startup. +* Configure the :mod:`warnings` module to display :exc:`ResourceWarning` + warnings. For example, use the ``-Wdefault`` command line option of Python to + display them. + +Examples debug checks: + +* Log :ref:`coroutines defined but never "yielded from" + <asyncio-coroutine-not-scheduled>` +* :meth:`~BaseEventLoop.call_soon` and :meth:`~BaseEventLoop.call_at` methods + raise an exception if they are called from the wrong thread. +* Log the execution time of the selector +* Log callbacks taking more than 100 ms to be executed. The + :attr:`BaseEventLoop.slow_callback_duration` attribute is the minimum + duration in seconds of "slow" callbacks. +* :exc:`ResourceWarning` warnings are emitted when transports and event loops + are :ref:`not closed explicitly <asyncio-close-transports>`. + +.. seealso:: + + The :meth:`BaseEventLoop.set_debug` method and the :ref:`asyncio logger + <asyncio-logger>`. + + +Cancellation +------------ + +Cancellation of tasks is not common in classic programming. In asynchronous +programming, not only it is something common, but you have to prepare your +code to handle it. + +Futures and tasks can be cancelled explicitly with their :meth:`Future.cancel` +method. The :func:`wait_for` function cancels the waited task when the timeout +occurs. There are many other cases where a task can be cancelled indirectly. + +Don't call :meth:`~Future.set_result` or :meth:`~Future.set_exception` method +of :class:`Future` if the future is cancelled: it would fail with an exception. +For example, write:: + + if not fut.cancelled(): + fut.set_result('done') + +Don't schedule directly a call to the :meth:`~Future.set_result` or the +:meth:`~Future.set_exception` method of a future with +:meth:`BaseEventLoop.call_soon`: the future can be cancelled before its method +is called. + +If you wait for a future, you should check early if the future was cancelled to +avoid useless operations. Example:: + + @coroutine + def slow_operation(fut): + if fut.cancelled(): + return + # ... slow computation ... + yield from fut + # ... + +The :func:`shield` function can also be used to ignore cancellation. + + +.. _asyncio-multithreading: + +Concurrency and multithreading +------------------------------ + +An event loop runs in a thread and executes all callbacks and tasks in the same +thread. While a task is running in the event loop, no other task is running in +the same thread. But when the task uses ``yield from``, the task is suspended +and the event loop executes the next task. + +To schedule a callback from a different thread, the +:meth:`BaseEventLoop.call_soon_threadsafe` method should be used. Example to +schedule a coroutine from a different thread:: + + loop.call_soon_threadsafe(asyncio.async, coro_func()) + +Most asyncio objects are not thread safe. You should only worry if you access +objects outside the event loop. For example, to cancel a future, don't call +directly its :meth:`Future.cancel` method, but:: + + loop.call_soon_threadsafe(fut.cancel) + +To handle signals and to execute subprocesses, the event loop must be run in +the main thread. + +The :meth:`BaseEventLoop.run_in_executor` method can be used with a thread pool +executor to execute a callback in different thread to not block the thread of +the event loop. + +.. seealso:: + + The :ref:`Synchronization primitives <asyncio-sync>` section describes ways + to synchronize tasks. + + The :ref:`Subprocess and threads <asyncio-subprocess-threads>` section lists + asyncio limitations to run subprocesses from different threads. + + + + +.. _asyncio-handle-blocking: + +Handle blocking functions correctly +----------------------------------- + +Blocking functions should not be called directly. For example, if a function +blocks for 1 second, other tasks are delayed by 1 second which can have an +important impact on reactivity. + +For networking and subprocesses, the :mod:`asyncio` module provides high-level +APIs like :ref:`protocols <asyncio-protocol>`. + +An executor can be used to run a task in a different thread or even in a +different process, to not block the thread of the event loop. See the +:meth:`BaseEventLoop.run_in_executor` method. + +.. seealso:: + + The :ref:`Delayed calls <asyncio-delayed-calls>` section details how the + event loop handles time. + + +.. _asyncio-logger: + +Logging +------- + +The :mod:`asyncio` module logs information with the :mod:`logging` module in +the logger ``'asyncio'``. + + +.. _asyncio-coroutine-not-scheduled: + +Detect coroutine objects never scheduled +---------------------------------------- + +When a coroutine function is called and its result is not passed to +:func:`async` or to the :meth:`BaseEventLoop.create_task` method, the execution +of the coroutine object will never be scheduled which is probably a bug. +:ref:`Enable the debug mode of asyncio <asyncio-debug-mode>` to :ref:`log a +warning <asyncio-logger>` to detect it. + +Example with the bug:: + + import asyncio + + @asyncio.coroutine + def test(): + print("never scheduled") + + test() + +Output in debug mode:: + + Coroutine test() at test.py:3 was never yielded from + Coroutine object created at (most recent call last): + File "test.py", line 7, in <module> + test() + +The fix is to call the :func:`async` function or the +:meth:`BaseEventLoop.create_task` method with the coroutine object. + +.. seealso:: + + :ref:`Pending task destroyed <asyncio-pending-task-destroyed>`. + + +Detect exceptions never consumed +-------------------------------- + +Python usually calls :func:`sys.displayhook` on unhandled exceptions. If +:meth:`Future.set_exception` is called, but the exception is never consumed, +:func:`sys.displayhook` is not called. Instead, :ref:`a log is emitted +<asyncio-logger>` when the future is deleted by the garbage collector, with the +traceback where the exception was raised. + +Example of unhandled exception:: + + import asyncio + + @asyncio.coroutine + def bug(): + raise Exception("not consumed") + + loop = asyncio.get_event_loop() + asyncio.async(bug()) + loop.run_forever() + +Output:: + + Task exception was never retrieved + future: <Task finished coro=<coro() done, defined at asyncio/coroutines.py:139> exception=Exception('not consumed',)> + Traceback (most recent call last): + File "asyncio/tasks.py", line 237, in _step + result = next(coro) + File "asyncio/coroutines.py", line 141, in coro + res = func(*args, **kw) + File "test.py", line 5, in bug + raise Exception("not consumed") + Exception: not consumed + +:ref:`Enable the debug mode of asyncio <asyncio-debug-mode>` to get the +traceback where the task was created. Output in debug mode:: + + Task exception was never retrieved + future: <Task finished coro=<bug() done, defined at test.py:3> exception=Exception('not consumed',) created at test.py:8> + source_traceback: Object created at (most recent call last): + File "test.py", line 8, in <module> + asyncio.async(bug()) + Traceback (most recent call last): + File "asyncio/tasks.py", line 237, in _step + result = next(coro) + File "asyncio/coroutines.py", line 79, in __next__ + return next(self.gen) + File "asyncio/coroutines.py", line 141, in coro + res = func(*args, **kw) + File "test.py", line 5, in bug + raise Exception("not consumed") + Exception: not consumed + +There are different options to fix this issue. The first option is to chain the +coroutine in another coroutine and use classic try/except:: + + @asyncio.coroutine + def handle_exception(): + try: + yield from bug() + except Exception: + print("exception consumed") + + loop = asyncio.get_event_loop() + asyncio.async(handle_exception()) + loop.run_forever() + +Another option is to use the :meth:`BaseEventLoop.run_until_complete` +function:: + + task = asyncio.async(bug()) + try: + loop.run_until_complete(task) + except Exception: + print("exception consumed") + +.. seealso:: + + The :meth:`Future.exception` method. + + +Chain coroutines correctly +-------------------------- + +When a coroutine function calls other coroutine functions and tasks, they +should be chained explicitly with ``yield from``. Otherwise, the execution is +not guaranteed to be sequential. + +Example with different bugs using :func:`asyncio.sleep` to simulate slow +operations:: + + import asyncio + + @asyncio.coroutine + def create(): + yield from asyncio.sleep(3.0) + print("(1) create file") + + @asyncio.coroutine + def write(): + yield from asyncio.sleep(1.0) + print("(2) write into file") + + @asyncio.coroutine + def close(): + print("(3) close file") + + @asyncio.coroutine + def test(): + asyncio.async(create()) + asyncio.async(write()) + asyncio.async(close()) + yield from asyncio.sleep(2.0) + loop.stop() + + loop = asyncio.get_event_loop() + asyncio.async(test()) + loop.run_forever() + print("Pending tasks at exit: %s" % asyncio.Task.all_tasks(loop)) + loop.close() + +Expected output:: + + (1) create file + (2) write into file + (3) close file + Pending tasks at exit: set() + +Actual output:: + + (3) close file + (2) write into file + Pending tasks at exit: {<Task pending create() at test.py:7 wait_for=<Future pending cb=[Task._wakeup()]>>} + Task was destroyed but it is pending! + task: <Task pending create() done at test.py:5 wait_for=<Future pending cb=[Task._wakeup()]>> + +The loop stopped before the ``create()`` finished, ``close()`` has been called +before ``write()``, whereas coroutine functions were called in this order: +``create()``, ``write()``, ``close()``. + +To fix the example, tasks must be marked with ``yield from``:: + + @asyncio.coroutine + def test(): + yield from asyncio.async(create()) + yield from asyncio.async(write()) + yield from asyncio.async(close()) + yield from asyncio.sleep(2.0) + loop.stop() + +Or without ``asyncio.async()``:: + + @asyncio.coroutine + def test(): + yield from create() + yield from write() + yield from close() + yield from asyncio.sleep(2.0) + loop.stop() + + +.. _asyncio-pending-task-destroyed: + +Pending task destroyed +---------------------- + +If a pending task is destroyed, the execution of its wrapped :ref:`coroutine +<coroutine>` did not complete. It is probably a bug and so a warning is logged. + +Example of log:: + + Task was destroyed but it is pending! + task: <Task pending coro=<kill_me() done, defined at test.py:5> wait_for=<Future pending cb=[Task._wakeup()]>> + +:ref:`Enable the debug mode of asyncio <asyncio-debug-mode>` to get the +traceback where the task was created. Example of log in debug mode:: + + Task was destroyed but it is pending! + source_traceback: Object created at (most recent call last): + File "test.py", line 15, in <module> + task = asyncio.async(coro, loop=loop) + task: <Task pending coro=<kill_me() done, defined at test.py:5> wait_for=<Future pending cb=[Task._wakeup()] created at test.py:7> created at test.py:15> + + +.. seealso:: + + :ref:`Detect coroutine objects never scheduled <asyncio-coroutine-not-scheduled>`. + +.. _asyncio-close-transports: + +Close transports and event loops +-------------------------------- + +When a transport is no more needed, call its ``close()`` method to release +resources. Event loops must also be closed explicitly. + +If a transport or an event loop is not closed explicitly, a +:exc:`ResourceWarning` warning will be emitted in its destructor. By default, +:exc:`ResourceWarning` warnings are ignored. The :ref:`Debug mode of asyncio +<asyncio-debug-mode>` section explains how to display them. diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst new file mode 100644 index 000000000000..f2c894569b0e --- /dev/null +++ b/Doc/library/asyncio-eventloop.rst @@ -0,0 +1,832 @@ +.. currentmodule:: asyncio + +.. _asyncio-event-loop: + +Base Event Loop +=============== + +The event loop is the central execution device provided by :mod:`asyncio`. +It provides multiple facilities, amongst which: + +* Registering, executing and cancelling delayed calls (timeouts). + +* Creating client and server :ref:`transports <asyncio-transport>` for various + kinds of communication. + +* Launching subprocesses and the associated :ref:`transports + <asyncio-transport>` for communication with an external program. + +* Delegating costly function calls to a pool of threads. + +.. class:: BaseEventLoop + + Base class of event loops. + +Run an event loop +----------------- + +.. method:: BaseEventLoop.run_forever() + + Run until :meth:`stop` is called. + +.. method:: BaseEventLoop.run_until_complete(future) + + Run until the :class:`Future` is done. + + If the argument is a :ref:`coroutine object <coroutine>`, it is wrapped by + :func:`async`. + + Return the Future's result, or raise its exception. + +.. method:: BaseEventLoop.is_running() + + Returns running status of event loop. + +.. method:: BaseEventLoop.stop() + + Stop running the event loop. + + Every callback scheduled before :meth:`stop` is called will run. + Callbacks scheduled after :meth:`stop` is called will not run. + However, those callbacks will run if :meth:`run_forever` is called + again later. + +.. method:: BaseEventLoop.is_closed() + + Returns ``True`` if the event loop was closed. + + .. versionadded:: 3.4.2 + +.. method:: BaseEventLoop.close() + + Close the event loop. The loop must not be running. + + This clears the queues and shuts down the executor, but does not wait for + the executor to finish. + + This is idempotent and irreversible. No other methods should be called after + this one. + +.. _asyncio-pass-keywords: + +Calls +----- + +Most :mod:`asyncio` functions don't accept keywords. If you want to pass +keywords to your callback, use :func:`functools.partial`. For example, +``loop.call_soon(functools.partial(print, "Hello", flush=True))`` will call +``print("Hello", flush=True)``. + +.. note:: + :func:`functools.partial` is better than ``lambda`` functions, because + :mod:`asyncio` can inspect :func:`functools.partial` object to display + parameters in debug mode, whereas ``lambda`` functions have a poor + representation. + +.. method:: BaseEventLoop.call_soon(callback, \*args) + + Arrange for a callback to be called as soon as possible. The callback is + called after :meth:`call_soon` returns, when control returns to the event + loop. + + This operates as a FIFO queue, callbacks are called in the order in + which they are registered. Each callback will be called exactly once. + + Any positional arguments after the callback will be passed to the + callback when it is called. + + An instance of :class:`asyncio.Handle` is returned. + + :ref:`Use functools.partial to pass keywords to the callback + <asyncio-pass-keywords>`. + +.. method:: BaseEventLoop.call_soon_threadsafe(callback, \*args) + + Like :meth:`call_soon`, but thread safe. + + +.. _asyncio-delayed-calls: + +Delayed calls +------------- + +The event loop has its own internal clock for computing timeouts. +Which clock is used depends on the (platform-specific) event loop +implementation; ideally it is a monotonic clock. This will generally be +a different clock than :func:`time.time`. + +.. note:: + + Timeouts (relative *delay* or absolute *when*) should not exceed one day. + + +.. method:: BaseEventLoop.call_later(delay, callback, *args) + + Arrange for the *callback* to be called after the given *delay* + seconds (either an int or float). + + An instance of :class:`asyncio.Handle` is returned. + + *callback* will be called exactly once per call to :meth:`call_later`. + If two callbacks are scheduled for exactly the same time, it is + undefined which will be called first. + + The optional positional *args* will be passed to the callback when it + is called. If you want the callback to be called with some named + arguments, use a closure or :func:`functools.partial`. + + :ref:`Use functools.partial to pass keywords to the callback + <asyncio-pass-keywords>`. + +.. method:: BaseEventLoop.call_at(when, callback, *args) + + Arrange for the *callback* to be called at the given absolute timestamp + *when* (an int or float), using the same time reference as + :meth:`BaseEventLoop.time`. + + This method's behavior is the same as :meth:`call_later`. + + :ref:`Use functools.partial to pass keywords to the callback + <asyncio-pass-keywords>`. + +.. method:: BaseEventLoop.time() + + Return the current time, as a :class:`float` value, according to the + event loop's internal clock. + +.. seealso:: + + The :func:`asyncio.sleep` function. + + +Coroutines +---------- + +.. method:: BaseEventLoop.create_task(coro) + + Schedule the execution of a :ref:`coroutine object <coroutine>`: wrap it in + a future. Return a :class:`Task` object. + + Third-party event loops can use their own subclass of :class:`Task` for + interoperability. In this case, the result type is a subclass of + :class:`Task`. + + This method was added in Python 3.4.2. Use the :func:`async` function to + support also older Python versions. + + .. versionadded:: 3.4.2 + + +Creating connections +-------------------- + +.. coroutinemethod:: BaseEventLoop.create_connection(protocol_factory, host=None, port=None, \*, ssl=None, family=0, proto=0, flags=0, sock=None, local_addr=None, server_hostname=None) + + Create a streaming transport connection to a given Internet *host* and + *port*: socket family :py:data:`~socket.AF_INET` or + :py:data:`~socket.AF_INET6` depending on *host* (or *family* if specified), + socket type :py:data:`~socket.SOCK_STREAM`. *protocol_factory* must be a + callable returning a :ref:`protocol <asyncio-protocol>` instance. + + This method is a :ref:`coroutine <coroutine>` which will try to + establish the connection in the background. When successful, the + coroutine returns a ``(transport, protocol)`` pair. + + The chronological synopsis of the underlying operation is as follows: + + #. The connection is established, and a :ref:`transport <asyncio-transport>` + is created to represent it. + + #. *protocol_factory* is called without arguments and must return a + :ref:`protocol <asyncio-protocol>` instance. + + #. The protocol instance is tied to the transport, and its + :meth:`connection_made` method is called. + + #. The coroutine returns successfully with the ``(transport, protocol)`` + pair. + + The created transport is an implementation-dependent bidirectional stream. + + .. note:: + *protocol_factory* can be any kind of callable, not necessarily + a class. For example, if you want to use a pre-created + protocol instance, you can pass ``lambda: my_protocol``. + + Options allowing to change how the connection is created: + + * *ssl*: if given and not false, a SSL/TLS transport is created + (by default a plain TCP transport is created). If *ssl* is + a :class:`ssl.SSLContext` object, this context is used to create + the transport; if *ssl* is :const:`True`, a context with some + unspecified default settings is used. + + .. seealso:: :ref:`SSL/TLS security considerations <ssl-security>` + + * *server_hostname*, is only for use together with *ssl*, + and sets or overrides the hostname that the target server's certificate + will be matched against. By default the value of the *host* argument + is used. If *host* is empty, there is no default and you must pass a + value for *server_hostname*. If *server_hostname* is an empty + string, hostname matching is disabled (which is a serious security + risk, allowing for man-in-the-middle-attacks). + + * *family*, *proto*, *flags* are the optional address family, protocol + and flags to be passed through to getaddrinfo() for *host* resolution. + If given, these should all be integers from the corresponding + :mod:`socket` module constants. + + * *sock*, if given, should be an existing, already connected + :class:`socket.socket` object to be used by the transport. + If *sock* is given, none of *host*, *port*, *family*, *proto*, *flags* + and *local_addr* should be specified. + + * *local_addr*, if given, is a ``(local_host, local_port)`` tuple used + to bind the socket to locally. The *local_host* and *local_port* + are looked up using getaddrinfo(), similarly to *host* and *port*. + + On Windows with :class:`ProactorEventLoop`, SSL/TLS is not supported. + + .. seealso:: + + The :func:`open_connection` function can be used to get a pair of + (:class:`StreamReader`, :class:`StreamWriter`) instead of a protocol. + + +.. coroutinemethod:: BaseEventLoop.create_datagram_endpoint(protocol_factory, local_addr=None, remote_addr=None, \*, family=0, proto=0, flags=0) + + Create datagram connection: socket family :py:data:`~socket.AF_INET` or + :py:data:`~socket.AF_INET6` depending on *host* (or *family* if specified), + socket type :py:data:`~socket.SOCK_DGRAM`. + + This method is a :ref:`coroutine <coroutine>` which will try to + establish the connection in the background. When successful, the + coroutine returns a ``(transport, protocol)`` pair. + + See the :meth:`BaseEventLoop.create_connection` method for parameters. + + On Windows with :class:`ProactorEventLoop`, this method is not supported. + + See :ref:`UDP echo client protocol <asyncio-udp-echo-client-protocol>` and + :ref:`UDP echo server protocol <asyncio-udp-echo-server-protocol>` examples. + + +.. coroutinemethod:: BaseEventLoop.create_unix_connection(protocol_factory, path, \*, ssl=None, sock=None, server_hostname=None) + + Create UNIX connection: socket family :py:data:`~socket.AF_UNIX`, socket + type :py:data:`~socket.SOCK_STREAM`. The :py:data:`~socket.AF_UNIX` socket + family is used to communicate between processes on the same machine + efficiently. + + This method is a :ref:`coroutine <coroutine>` which will try to + establish the connection in the background. When successful, the + coroutine returns a ``(transport, protocol)`` pair. + + See the :meth:`BaseEventLoop.create_connection` method for parameters. + + Availability: UNIX. + + +Creating listening connections +------------------------------ + +.. coroutinemethod:: BaseEventLoop.create_server(protocol_factory, host=None, port=None, \*, family=socket.AF_UNSPEC, flags=socket.AI_PASSIVE, sock=None, backlog=100, ssl=None, reuse_address=None) + + Create a TCP server (socket type :data:`~socket.SOCK_STREAM`) bound to + *host* and *port*. + + Return a :class:`Server` object, its :attr:`~Server.sockets` attribute + contains created sockets. Use the :meth:`Server.close` method to stop the + server: close listening sockets. + + Parameters: + + * If *host* is an empty string or ``None``, all interfaces are assumed + and a list of multiple sockets will be returned (most likely + one for IPv4 and another one for IPv6). + + * *family* can be set to either :data:`socket.AF_INET` or + :data:`~socket.AF_INET6` to force the socket to use IPv4 or IPv6. If not set + it will be determined from host (defaults to :data:`socket.AF_UNSPEC`). + + * *flags* is a bitmask for :meth:`getaddrinfo`. + + * *sock* can optionally be specified in order to use a preexisting + socket object. If specified, *host* and *port* should be omitted (must be + :const:`None`). + + * *backlog* is the maximum number of queued connections passed to + :meth:`~socket.socket.listen` (defaults to 100). + + * *ssl* can be set to an :class:`~ssl.SSLContext` to enable SSL over the + accepted connections. + + * *reuse_address* tells the kernel to reuse a local socket in + TIME_WAIT state, without waiting for its natural timeout to + expire. If not specified will automatically be set to True on + UNIX. + + This method is a :ref:`coroutine <coroutine>`. + + On Windows with :class:`ProactorEventLoop`, SSL/TLS is not supported. + + .. seealso:: + + The function :func:`start_server` creates a (:class:`StreamReader`, + :class:`StreamWriter`) pair and calls back a function with this pair. + + +.. coroutinemethod:: BaseEventLoop.create_unix_server(protocol_factory, path=None, \*, sock=None, backlog=100, ssl=None) + + Similar to :meth:`BaseEventLoop.create_server`, but specific to the + socket family :py:data:`~socket.AF_UNIX`. + + This method is a :ref:`coroutine <coroutine>`. + + Availability: UNIX. + + +Watch file descriptors +---------------------- + +On Windows with :class:`SelectorEventLoop`, only socket handles are supported +(ex: pipe file descriptors are not supported). + +On Windows with :class:`ProactorEventLoop`, these methods are not supported. + +.. method:: BaseEventLoop.add_reader(fd, callback, \*args) + + Start watching the file descriptor for read availability and then call the + *callback* with specified arguments. + + :ref:`Use functools.partial to pass keywords to the callback + <asyncio-pass-keywords>`. + +.. method:: BaseEventLoop.remove_reader(fd) + + Stop watching the file descriptor for read availability. + +.. method:: BaseEventLoop.add_writer(fd, callback, \*args) + + Start watching the file descriptor for write availability and then call the + *callback* with specified arguments. + + :ref:`Use functools.partial to pass keywords to the callback + <asyncio-pass-keywords>`. + +.. method:: BaseEventLoop.remove_writer(fd) + + Stop watching the file descriptor for write availability. + +The :ref:`watch a file descriptor for read events <asyncio-watch-read-event>` +example uses the low-level :meth:`BaseEventLoop.add_reader` method to register +the file descriptor of a socket. + + +Low-level socket operations +--------------------------- + +.. coroutinemethod:: BaseEventLoop.sock_recv(sock, nbytes) + + Receive data from the socket. The return value is a bytes object + representing the data received. The maximum amount of data to be received + at once is specified by *nbytes*. + + With :class:`SelectorEventLoop` event loop, the socket *sock* must be + non-blocking. + + This method is a :ref:`coroutine <coroutine>`. + + .. seealso:: + + The :meth:`socket.socket.recv` method. + +.. coroutinemethod:: BaseEventLoop.sock_sendall(sock, data) + + Send data to the socket. The socket must be connected to a remote socket. + This method continues to send data from *data* until either all data has + been sent or an error occurs. ``None`` is returned on success. On error, + an exception is raised, and there is no way to determine how much data, if + any, was successfully processed by the receiving end of the connection. + + With :class:`SelectorEventLoop` event loop, the socket *sock* must be + non-blocking. + + This method is a :ref:`coroutine <coroutine>`. + + .. seealso:: + + The :meth:`socket.socket.sendall` method. + +.. coroutinemethod:: BaseEventLoop.sock_connect(sock, address) + + Connect to a remote socket at *address*. + + The *address* must be already resolved to avoid the trap of hanging the + entire event loop when the address requires doing a DNS lookup. For + example, it must be an IP address, not an hostname, for + :py:data:`~socket.AF_INET` and :py:data:`~socket.AF_INET6` address families. + Use :meth:`getaddrinfo` to resolve the hostname asynchronously. + + With :class:`SelectorEventLoop` event loop, the socket *sock* must be + non-blocking. + + This method is a :ref:`coroutine <coroutine>`. + + .. seealso:: + + The :meth:`BaseEventLoop.create_connection` method, the + :func:`open_connection` function and the :meth:`socket.socket.connect` + method. + + +.. coroutinemethod:: BaseEventLoop.sock_accept(sock) + + Accept a connection. The socket must be bound to an address and listening + for connections. The return value is a pair ``(conn, address)`` where *conn* + is a *new* socket object usable to send and receive data on the connection, + and *address* is the address bound to the socket on the other end of the + connection. + + The socket *sock* must be non-blocking. + + This method is a :ref:`coroutine <coroutine>`. + + .. seealso:: + + The :meth:`BaseEventLoop.create_server` method, the :func:`start_server` + function and the :meth:`socket.socket.accept` method. + + +Resolve host name +----------------- + +.. coroutinemethod:: BaseEventLoop.getaddrinfo(host, port, \*, family=0, type=0, proto=0, flags=0) + + This method is a :ref:`coroutine <coroutine>`, similar to + :meth:`socket.getaddrinfo` function but non-blocking. + +.. coroutinemethod:: BaseEventLoop.getnameinfo(sockaddr, flags=0) + + This method is a :ref:`coroutine <coroutine>`, similar to + :meth:`socket.getnameinfo` function but non-blocking. + + +Connect pipes +------------- + +On Windows with :class:`SelectorEventLoop`, these methods are not supported. +Use :class:`ProactorEventLoop` to support pipes on Windows. + +.. coroutinemethod:: BaseEventLoop.connect_read_pipe(protocol_factory, pipe) + + Register read pipe in eventloop. + + *protocol_factory* should instantiate object with :class:`Protocol` + interface. *pipe* is a :term:`file-like object <file object>`. + Return pair ``(transport, protocol)``, where *transport* supports the + :class:`ReadTransport` interface. + + With :class:`SelectorEventLoop` event loop, the *pipe* is set to + non-blocking mode. + + This method is a :ref:`coroutine <coroutine>`. + +.. coroutinemethod:: BaseEventLoop.connect_write_pipe(protocol_factory, pipe) + + Register write pipe in eventloop. + + *protocol_factory* should instantiate object with :class:`BaseProtocol` + interface. *pipe* is :term:`file-like object <file object>`. + Return pair ``(transport, protocol)``, where *transport* supports + :class:`WriteTransport` interface. + + With :class:`SelectorEventLoop` event loop, the *pipe* is set to + non-blocking mode. + + This method is a :ref:`coroutine <coroutine>`. + +.. seealso:: + + The :meth:`BaseEventLoop.subprocess_exec` and + :meth:`BaseEventLoop.subprocess_shell` methods. + + +UNIX signals +------------ + +Availability: UNIX only. + +.. method:: BaseEventLoop.add_signal_handler(signum, callback, \*args) + + Add a handler for a signal. + + Raise :exc:`ValueError` if the signal number is invalid or uncatchable. + Raise :exc:`RuntimeError` if there is a problem setting up the handler. + + :ref:`Use functools.partial to pass keywords to the callback + <asyncio-pass-keywords>`. + +.. method:: BaseEventLoop.remove_signal_handler(sig) + + Remove a handler for a signal. + + Return ``True`` if a signal handler was removed, ``False`` if not. + +.. seealso:: + + The :mod:`signal` module. + + +Executor +-------- + +Call a function in an :class:`~concurrent.futures.Executor` (pool of threads or +pool of processes). By default, an event loop uses a thread pool executor +(:class:`~concurrent.futures.ThreadPoolExecutor`). + +.. coroutinemethod:: BaseEventLoop.run_in_executor(executor, callback, \*args) + + Arrange for a callback to be called in the specified executor. + + The *executor* argument should be an :class:`~concurrent.futures.Executor` + instance. The default executor is used if *executor* is ``None``. + + :ref:`Use functools.partial to pass keywords to the callback + <asyncio-pass-keywords>`. + + This method is a :ref:`coroutine <coroutine>`. + +.. method:: BaseEventLoop.set_default_executor(executor) + + Set the default executor used by :meth:`run_in_executor`. + + +Error Handling API +------------------ + +Allows to customize how exceptions are handled in the event loop. + +.. method:: BaseEventLoop.set_exception_handler(handler) + + Set *handler* as the new event loop exception handler. + + If *handler* is ``None``, the default exception handler will + be set. + + If *handler* is a callable object, it should have a + matching signature to ``(loop, context)``, where ``loop`` + will be a reference to the active event loop, ``context`` + will be a ``dict`` object (see :meth:`call_exception_handler` + documentation for details about context). + +.. method:: BaseEventLoop.default_exception_handler(context) + + Default exception handler. + + This is called when an exception occurs and no exception + handler is set, and can be called by a custom exception + handler that wants to defer to the default behavior. + + *context* parameter has the same meaning as in + :meth:`call_exception_handler`. + +.. method:: BaseEventLoop.call_exception_handler(context) + + Call the current event loop exception handler. + + *context* is a ``dict`` object containing the following keys + (new keys may be introduced later): + + * 'message': Error message; + * 'exception' (optional): Exception object; + * 'future' (optional): :class:`asyncio.Future` instance; + * 'handle' (optional): :class:`asyncio.Handle` instance; + * 'protocol' (optional): :ref:`Protocol <asyncio-protocol>` instance; + * 'transport' (optional): :ref:`Transport <asyncio-transport>` instance; + * 'socket' (optional): :class:`socket.socket` instance. + + .. note:: + + Note: this method should not be overloaded in subclassed + event loops. For any custom exception handling, use + :meth:`set_exception_handler()` method. + +Debug mode +---------- + +.. method:: BaseEventLoop.get_debug() + + Get the debug mode (:class:`bool`) of the event loop. + + The default value is ``True`` if the environment variable + :envvar:`PYTHONASYNCIODEBUG` is set to a non-empty string, ``False`` + otherwise. + + .. versionadded:: 3.4.2 + +.. method:: BaseEventLoop.set_debug(enabled: bool) + + Set the debug mode of the event loop. + + .. versionadded:: 3.4.2 + +.. seealso:: + + The :ref:`debug mode of asyncio <asyncio-debug-mode>`. + +Server +------ + +.. class:: Server + + Server listening on sockets. + + Object created by the :meth:`BaseEventLoop.create_server` method and the + :func:`start_server` function. Don't instantiate the class directly. + + .. method:: close() + + Stop serving: close listening sockets and set the :attr:`sockets` + attribute to ``None``. + + The sockets that represent existing incoming client connections are + leaved open. + + The server is closed asynchonously, use the :meth:`wait_closed` coroutine + to wait until the server is closed. + + .. coroutinemethod:: wait_closed() + + Wait until the :meth:`close` method completes. + + This method is a :ref:`coroutine <coroutine>`. + + .. attribute:: sockets + + List of :class:`socket.socket` objects the server is listening to, or + ``None`` if the server is closed. + + +Handle +------ + +.. class:: Handle + + A callback wrapper object returned by :func:`BaseEventLoop.call_soon`, + :func:`BaseEventLoop.call_soon_threadsafe`, :func:`BaseEventLoop.call_later`, + and :func:`BaseEventLoop.call_at`. + + .. method:: cancel() + + Cancel the call. + + +Event loop examples +------------------- + +.. _asyncio-hello-world-callback: + +Hello World with call_soon() +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Example using the :meth:`BaseEventLoop.call_soon` method to schedule a +callback. The callback displays ``"Hello World"`` and then stops the event +loop:: + + import asyncio + + def hello_world(loop): + print('Hello World') + loop.stop() + + loop = asyncio.get_event_loop() + + # Schedule a call to hello_world() + loop.call_soon(hello_world, loop) + + # Blocking call interrupted by loop.stop() + loop.run_forever() + loop.close() + +.. seealso:: + + The :ref:`Hello World coroutine <asyncio-hello-world-coroutine>` example + uses a :ref:`coroutine <coroutine>`. + + +.. _asyncio-date-callback: + +Display the current date with call_later() +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Example of callback displaying the current date every second. The callback uses +the :meth:`BaseEventLoop.call_later` method to reschedule itself during 5 +seconds, and then stops the event loop:: + + import asyncio + import datetime + + def display_date(end_time, loop): + print(datetime.datetime.now()) + if (loop.time() + 1.0) < end_time: + loop.call_later(1, display_date, end_time, loop) + else: + loop.stop() + + loop = asyncio.get_event_loop() + + # Schedule the first call to display_date() + end_time = loop.time() + 5.0 + loop.call_soon(display_date, end_time, loop) + + # Blocking call interrupted by loop.stop() + loop.run_forever() + loop.close() + +.. seealso:: + + The :ref:`coroutine displaying the current date + <asyncio-date-coroutine>` example uses a :ref:`coroutine + <coroutine>`. + + +.. _asyncio-watch-read-event: + +Watch a file descriptor for read events +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Wait until a file descriptor received some data using the +:meth:`BaseEventLoop.add_reader` method and then close the event loop:: + + import asyncio + try: + from socket import socketpair + except ImportError: + from asyncio.windows_utils import socketpair + + # Create a pair of connected file descriptors + rsock, wsock = socketpair() + loop = asyncio.get_event_loop() + + def reader(): + data = rsock.recv(100) + print("Received:", data.decode()) + # We are done: unregister the file descriptor + loop.remove_reader(rsock) + # Stop the event loop + loop.stop() + + # Register the file descriptor for read event + loop.add_reader(rsock, reader) + + # Simulate the reception of data from the network + loop.call_soon(wsock.send, 'abc'.encode()) + + # Run the event loop + loop.run_forever() + + # We are done, close sockets and the event loop + rsock.close() + wsock.close() + loop.close() + +.. seealso:: + + The :ref:`register an open socket to wait for data using a protocol + <asyncio-register-socket>` example uses a low-level protocol created by the + :meth:`BaseEventLoop.create_connection` method. + + The :ref:`register an open socket to wait for data using streams + <asyncio-register-socket-streams>` example uses high-level streams + created by the :func:`open_connection` function in a coroutine. + + +Set signal handlers for SIGINT and SIGTERM +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Register handlers for signals :py:data:`SIGINT` and :py:data:`SIGTERM` using +the :meth:`BaseEventLoop.add_signal_handler` method:: + + import asyncio + import functools + import os + import signal + + def ask_exit(signame): + print("got signal %s: exit" % signame) + loop.stop() + + loop = asyncio.get_event_loop() + for signame in ('SIGINT', 'SIGTERM'): + loop.add_signal_handler(getattr(signal, signame), + functools.partial(ask_exit, signame)) + + print("Event loop running forever, press CTRL+c to interrupt.") + print("pid %s: send SIGINT or SIGTERM to exit." % os.getpid()) + try: + loop.run_forever() + finally: + loop.close() + +This example only works on UNIX. diff --git a/Doc/library/asyncio-eventloops.rst b/Doc/library/asyncio-eventloops.rst new file mode 100644 index 000000000000..ae3bf9029806 --- /dev/null +++ b/Doc/library/asyncio-eventloops.rst @@ -0,0 +1,201 @@ +.. currentmodule:: asyncio + +Event loops +=========== + +Event loop functions +-------------------- + +The following functions are convenient shortcuts to accessing the methods of the +global policy. Note that this provides access to the default policy, unless an +alternative policy was set by calling :func:`set_event_loop_policy` earlier in +the execution of the process. + +.. function:: get_event_loop() + + Equivalent to calling ``get_event_loop_policy().get_event_loop()``. + +.. function:: set_event_loop(loop) + + Equivalent to calling ``get_event_loop_policy().set_event_loop(loop)``. + +.. function:: new_event_loop() + + Equivalent to calling ``get_event_loop_policy().new_event_loop()``. + + +.. _asyncio-event-loops: + +Available event loops +--------------------- + +asyncio currently provides two implementations of event loops: +:class:`SelectorEventLoop` and :class:`ProactorEventLoop`. + +.. class:: SelectorEventLoop + + Event loop based on the :mod:`selectors` module. Subclass of + :class:`BaseEventLoop`. + + Use the most efficient selector available on the platform. + + On Windows, only sockets are supported (ex: pipes are not supported): + see the `MSDN documentation of select + <http://msdn.microsoft.com/en-us/library/windows/desktop/ms740141%28v=vs.85%29.aspx>`_. + +.. class:: ProactorEventLoop + + Proactor event loop for Windows using "I/O Completion Ports" aka IOCP. + Subclass of :class:`BaseEventLoop`. + + Availability: Windows. + + .. seealso:: + + `MSDN documentation on I/O Completion Ports + <http://msdn.microsoft.com/en-us/library/windows/desktop/aa365198%28v=vs.85%29.aspx>`_. + +Example to use a :class:`ProactorEventLoop` on Windows:: + + import asyncio, os + + if os.name == 'nt': + loop = asyncio.ProactorEventLoop() + asyncio.set_event_loop(loop) + +.. _asyncio-platform-support: + +Platform support +---------------- + +The :mod:`asyncio` module has been designed to be portable, but each platform +still has subtle differences and may not support all :mod:`asyncio` features. + +Windows +^^^^^^^ + +Common limits of Windows event loops: + +- :meth:`~BaseEventLoop.create_unix_connection` and + :meth:`~BaseEventLoop.create_unix_server` are not supported: the socket + family :data:`socket.AF_UNIX` is specific to UNIX +- :meth:`~BaseEventLoop.add_signal_handler` and + :meth:`~BaseEventLoop.remove_signal_handler` are not supported +- :meth:`EventLoopPolicy.set_child_watcher` is not supported. + :class:`ProactorEventLoop` supports subprocesses. It has only one + implementation to watch child processes, there is no need to configure it. + +:class:`SelectorEventLoop` specific limits: + +- :class:`~selectors.SelectSelector` is used which only supports sockets + and is limited to 512 sockets. +- :meth:`~BaseEventLoop.add_reader` and :meth:`~BaseEventLoop.add_writer` only + accept file descriptors of sockets +- Pipes are not supported + (ex: :meth:`~BaseEventLoop.connect_read_pipe`, + :meth:`~BaseEventLoop.connect_write_pipe`) +- :ref:`Subprocesses <asyncio-subprocess>` are not supported + (ex: :meth:`~BaseEventLoop.subprocess_exec`, + :meth:`~BaseEventLoop.subprocess_shell`) + +:class:`ProactorEventLoop` specific limits: + +- :meth:`~BaseEventLoop.create_datagram_endpoint` (UDP) is not supported +- :meth:`~BaseEventLoop.add_reader` and :meth:`~BaseEventLoop.add_writer` are + not supported + +The resolution of the monotonic clock on Windows is usually around 15.6 msec. +The best resolution is 0.5 msec. The resolution depends on the hardware +(availability of `HPET +<http://fr.wikipedia.org/wiki/High_Precision_Event_Timer>`_) and on the Windows +configuration. See :ref:`asyncio delayed calls <asyncio-delayed-calls>`. + +.. versionchanged:: 3.5 + + :class:`ProactorEventLoop` now supports SSL. + + +Mac OS X +^^^^^^^^ + +Character devices like PTY are only well supported since Mavericks (Mac OS +10.9). They are not supported at all on Mac OS 10.5 and older. + +On Mac OS 10.6, 10.7 and 10.8, the default event loop is +:class:`SelectorEventLoop` which uses :class:`selectors.KqueueSelector`. +:class:`selectors.KqueueSelector` does not support character devices on these +versions. The :class:`SelectorEventLoop` can be used with +:class:`~selectors.SelectSelector` or :class:`~selectors.PollSelector` to +support character devices on these versions of Mac OS X. Example:: + + import asyncio + import selectors + + selector = selectors.SelectSelector() + loop = asyncio.SelectorEventLoop(selector) + asyncio.set_event_loop(loop) + + +Event loop policies and the default policy +------------------------------------------ + +Event loop management is abstracted with a *policy* pattern, to provide maximal +flexibility for custom platforms and frameworks. Throughout the execution of a +process, a single global policy object manages the event loops available to the +process based on the calling context. A policy is an object implementing the +:class:`AbstractEventLoopPolicy` interface. + +For most users of :mod:`asyncio`, policies never have to be dealt with +explicitly, since the default global policy is sufficient. + +The default policy defines context as the current thread, and manages an event +loop per thread that interacts with :mod:`asyncio`. The module-level functions +:func:`get_event_loop` and :func:`set_event_loop` provide convenient access to +event loops managed by the default policy. + + +Event loop policy interface +--------------------------- + +An event loop policy must implement the following interface: + +.. class:: AbstractEventLoopPolicy + + Event loop policy. + + .. method:: get_event_loop() + + Get the event loop for the current context. + + Returns an event loop object implementing the :class:`BaseEventLoop` + interface. + + Raises an exception in case no event loop has been set for the current + context and the current policy does not specify to create one. It must + never return ``None``. + + .. method:: set_event_loop(loop) + + Set the event loop for the current context to *loop*. + + .. method:: new_event_loop() + + Create and return a new event loop object according to this policy's + rules. + + If there's need to set this loop as the event loop for the current + context, :meth:`set_event_loop` must be called explicitly. + + +Access to the global loop policy +-------------------------------- + +.. function:: get_event_loop_policy() + + Get the current event loop policy. + +.. function:: set_event_loop_policy(policy) + + Set the current event loop policy. If *policy* is ``None``, the default + policy is restored. + diff --git a/Doc/library/asyncio-protocol.rst b/Doc/library/asyncio-protocol.rst new file mode 100644 index 000000000000..b6fcc4840b56 --- /dev/null +++ b/Doc/library/asyncio-protocol.rst @@ -0,0 +1,704 @@ +.. currentmodule:: asyncio + ++++++++++++++++++++++++++++++++++++++++++ +Transports and protocols (low-level API) ++++++++++++++++++++++++++++++++++++++++++ + +.. _asyncio-transport: + +Transports +========== + +Transports are classes provided by :mod:`asyncio` in order to abstract +various kinds of communication channels. You generally won't instantiate +a transport yourself; instead, you will call a :class:`BaseEventLoop` method +which will create the transport and try to initiate the underlying +communication channel, calling you back when it succeeds. + +Once the communication channel is established, a transport is always +paired with a :ref:`protocol <asyncio-protocol>` instance. The protocol can +then call the transport's methods for various purposes. + +:mod:`asyncio` currently implements transports for TCP, UDP, SSL, and +subprocess pipes. The methods available on a transport depend on +the transport's kind. + + +BaseTransport +------------- + +.. class:: BaseTransport + + Base class for transports. + + .. method:: close(self) + + Close the transport. If the transport has a buffer for outgoing + data, buffered data will be flushed asynchronously. No more data + will be received. After all buffered data is flushed, the + protocol's :meth:`connection_lost` method will be called with + :const:`None` as its argument. + + + .. method:: get_extra_info(name, default=None) + + Return optional transport information. *name* is a string representing + the piece of transport-specific information to get, *default* is the + value to return if the information doesn't exist. + + This method allows transport implementations to easily expose + channel-specific information. + + * socket: + + - ``'peername'``: the remote address to which the socket is connected, + result of :meth:`socket.socket.getpeername` (``None`` on error) + - ``'socket'``: :class:`socket.socket` instance + - ``'sockname'``: the socket's own address, + result of :meth:`socket.socket.getsockname` + + * SSL socket: + + - ``'compression'``: the compression algorithm being used as a string, + or ``None`` if the connection isn't compressed; result of + :meth:`ssl.SSLSocket.compression` + - ``'cipher'``: a three-value tuple containing the name of the cipher + being used, the version of the SSL protocol that defines its use, and + the number of secret bits being used; result of + :meth:`ssl.SSLSocket.cipher` + - ``'peercert'``: peer certificate; result of + :meth:`ssl.SSLSocket.getpeercert` + - ``'sslcontext'``: :class:`ssl.SSLContext` instance + + * pipe: + + - ``'pipe'``: pipe object + + * subprocess: + + - ``'subprocess'``: :class:`subprocess.Popen` instance + + +ReadTransport +------------- + +.. class:: ReadTransport + + Interface for read-only transports. + + .. method:: pause_reading() + + Pause the receiving end of the transport. No data will be passed to + the protocol's :meth:`data_received` method until :meth:`resume_reading` + is called. + + .. method:: resume_reading() + + Resume the receiving end. The protocol's :meth:`data_received` method + will be called once again if some data is available for reading. + + +WriteTransport +-------------- + +.. class:: WriteTransport + + Interface for write-only transports. + + .. method:: abort() + + Close the transport immediately, without waiting for pending operations + to complete. Buffered data will be lost. No more data will be received. + The protocol's :meth:`connection_lost` method will eventually be + called with :const:`None` as its argument. + + .. method:: can_write_eof() + + Return :const:`True` if the transport supports :meth:`write_eof`, + :const:`False` if not. + + .. method:: get_write_buffer_size() + + Return the current size of the output buffer used by the transport. + + .. method:: get_write_buffer_limits() + + Get the *high*- and *low*-water limits for write flow control. Return a + tuple ``(low, high)`` where *low* and *high* are positive number of + bytes. + + Use :meth:`set_write_buffer_limits` to set the limits. + + .. versionadded:: 3.4.2 + + .. method:: set_write_buffer_limits(high=None, low=None) + + Set the *high*- and *low*-water limits for write flow control. + + These two values control when call the protocol's + :meth:`pause_writing` and :meth:`resume_writing` methods are called. + If specified, the low-water limit must be less than or equal to the + high-water limit. Neither *high* nor *low* can be negative. + + The defaults are implementation-specific. If only the + high-water limit is given, the low-water limit defaults to a + implementation-specific value less than or equal to the + high-water limit. Setting *high* to zero forces *low* to zero as + well, and causes :meth:`pause_writing` to be called whenever the + buffer becomes non-empty. Setting *low* to zero causes + :meth:`resume_writing` to be called only once the buffer is empty. + Use of zero for either limit is generally sub-optimal as it + reduces opportunities for doing I/O and computation + concurrently. + + Use :meth:`get_write_buffer_limits` to get the limits. + + .. method:: write(data) + + Write some *data* bytes to the transport. + + This method does not block; it buffers the data and arranges for it + to be sent out asynchronously. + + .. method:: writelines(list_of_data) + + Write a list (or any iterable) of data bytes to the transport. + This is functionally equivalent to calling :meth:`write` on each + element yielded by the iterable, but may be implemented more efficiently. + + .. method:: write_eof() + + Close the write end of the transport after flushing buffered data. + Data may still be received. + + This method can raise :exc:`NotImplementedError` if the transport + (e.g. SSL) doesn't support half-closes. + + +DatagramTransport +----------------- + +.. method:: DatagramTransport.sendto(data, addr=None) + + Send the *data* bytes to the remote peer given by *addr* (a + transport-dependent target address). If *addr* is :const:`None`, the + data is sent to the target address given on transport creation. + + This method does not block; it buffers the data and arranges for it + to be sent out asynchronously. + +.. method:: DatagramTransport.abort() + + Close the transport immediately, without waiting for pending operations + to complete. Buffered data will be lost. No more data will be received. + The protocol's :meth:`connection_lost` method will eventually be + called with :const:`None` as its argument. + + +BaseSubprocessTransport +----------------------- + +.. class:: BaseSubprocessTransport + + .. method:: get_pid() + + Return the subprocess process id as an integer. + + .. method:: get_pipe_transport(fd) + + Return the transport for the communication pipe corresponding to the + integer file descriptor *fd*: + + * ``0``: readable streaming transport of the standard input (*stdin*), + or :const:`None` if the subprocess was not created with ``stdin=PIPE`` + * ``1``: writable streaming transport of the standard output (*stdout*), + or :const:`None` if the subprocess was not created with ``stdout=PIPE`` + * ``2``: writable streaming transport of the standard error (*stderr*), + or :const:`None` if the subprocess was not created with ``stderr=PIPE`` + * other *fd*: :const:`None` + + .. method:: get_returncode() + + Return the subprocess returncode as an integer or :const:`None` + if it hasn't returned, similarly to the + :attr:`subprocess.Popen.returncode` attribute. + + .. method:: kill(self) + + Kill the subprocess, as in :meth:`subprocess.Popen.kill` + + On POSIX systems, the function sends SIGKILL to the subprocess. + On Windows, this method is an alias for :meth:`terminate`. + + .. method:: send_signal(signal) + + Send the *signal* number to the subprocess, as in + :meth:`subprocess.Popen.send_signal`. + + .. method:: terminate() + + Ask the subprocess to stop, as in :meth:`subprocess.Popen.terminate`. + This method is an alias for the :meth:`close` method. + + On POSIX systems, this method sends SIGTERM to the subprocess. + On Windows, the Windows API function TerminateProcess() is called to + stop the subprocess. + + .. method:: close() + + Ask the subprocess to stop by calling the :meth:`terminate` method if the + subprocess hasn't returned yet, and close transports of all pipes + (*stdin*, *stdout* and *stderr*). + + +.. _asyncio-protocol: + +Protocols +========= + +:mod:`asyncio` provides base classes that you can subclass to implement +your network protocols. Those classes are used in conjunction with +:ref:`transports <asyncio-transport>` (see below): the protocol parses incoming +data and asks for the writing of outgoing data, while the transport is +responsible for the actual I/O and buffering. + +When subclassing a protocol class, it is recommended you override certain +methods. Those methods are callbacks: they will be called by the transport +on certain events (for example when some data is received); you shouldn't +call them yourself, unless you are implementing a transport. + +.. note:: + All callbacks have default implementations, which are empty. Therefore, + you only need to implement the callbacks for the events in which you + are interested. + + +Protocol classes +---------------- + +.. class:: Protocol + + The base class for implementing streaming protocols (for use with + e.g. TCP and SSL transports). + +.. class:: DatagramProtocol + + The base class for implementing datagram protocols (for use with + e.g. UDP transports). + +.. class:: SubprocessProtocol + + The base class for implementing protocols communicating with child + processes (through a set of unidirectional pipes). + + +Connection callbacks +-------------------- + +These callbacks may be called on :class:`Protocol`, :class:`DatagramProtocol` +and :class:`SubprocessProtocol` instances: + +.. method:: BaseProtocol.connection_made(transport) + + Called when a connection is made. + + The *transport* argument is the transport representing the + connection. You are responsible for storing it somewhere + (e.g. as an attribute) if you need to. + +.. method:: BaseProtocol.connection_lost(exc) + + Called when the connection is lost or closed. + + The argument is either an exception object or :const:`None`. + The latter means a regular EOF is received, or the connection was + aborted or closed by this side of the connection. + +:meth:`~BaseProtocol.connection_made` and :meth:`~BaseProtocol.connection_lost` +are called exactly once per successful connection. All other callbacks will be +called between those two methods, which allows for easier resource management +in your protocol implementation. + +The following callbacks may be called only on :class:`SubprocessProtocol` +instances: + +.. method:: SubprocessProtocol.pipe_data_received(fd, data) + + Called when the child process writes data into its stdout or stderr pipe. + *fd* is the integer file descriptor of the pipe. *data* is a non-empty + bytes object containing the data. + +.. method:: SubprocessProtocol.pipe_connection_lost(fd, exc) + + Called when one of the pipes communicating with the child process + is closed. *fd* is the integer file descriptor that was closed. + +.. method:: SubprocessProtocol.process_exited() + + Called when the child process has exited. + + +Streaming protocols +------------------- + +The following callbacks are called on :class:`Protocol` instances: + +.. method:: Protocol.data_received(data) + + Called when some data is received. *data* is a non-empty bytes object + containing the incoming data. + + .. note:: + Whether the data is buffered, chunked or reassembled depends on + the transport. In general, you shouldn't rely on specific semantics + and instead make your parsing generic and flexible enough. However, + data is always received in the correct order. + +.. method:: Protocol.eof_received() + + Calls when the other end signals it won't send any more data + (for example by calling :meth:`write_eof`, if the other end also uses + asyncio). + + This method may return a false value (including None), in which case + the transport will close itself. Conversely, if this method returns a + true value, closing the transport is up to the protocol. Since the + default implementation returns None, it implicitly closes the connection. + + .. note:: + Some transports such as SSL don't support half-closed connections, + in which case returning true from this method will not prevent closing + the connection. + +:meth:`data_received` can be called an arbitrary number of times during +a connection. However, :meth:`eof_received` is called at most once +and, if called, :meth:`data_received` won't be called after it. + +State machine: + + start -> :meth:`~BaseProtocol.connection_made` + [-> :meth:`~Protocol.data_received` \*] + [-> :meth:`~Protocol.eof_received` ?] + -> :meth:`~BaseProtocol.connection_lost` -> end + + +Datagram protocols +------------------ + +The following callbacks are called on :class:`DatagramProtocol` instances. + +.. method:: DatagramProtocol.datagram_received(data, addr) + + Called when a datagram is received. *data* is a bytes object containing + the incoming data. *addr* is the address of the peer sending the data; + the exact format depends on the transport. + +.. method:: DatagramProtocol.error_received(exc) + + Called when a previous send or receive operation raises an + :class:`OSError`. *exc* is the :class:`OSError` instance. + + This method is called in rare conditions, when the transport (e.g. UDP) + detects that a datagram couldn't be delivered to its recipient. + In many conditions though, undeliverable datagrams will be silently + dropped. + + +Flow control callbacks +---------------------- + +These callbacks may be called on :class:`Protocol`, +:class:`DatagramProtocol` and :class:`SubprocessProtocol` instances: + +.. method:: BaseProtocol.pause_writing() + + Called when the transport's buffer goes over the high-water mark. + +.. method:: BaseProtocol.resume_writing() + + Called when the transport's buffer drains below the low-water mark. + + +:meth:`pause_writing` and :meth:`resume_writing` calls are paired -- +:meth:`pause_writing` is called once when the buffer goes strictly over +the high-water mark (even if subsequent writes increases the buffer size +even more), and eventually :meth:`resume_writing` is called once when the +buffer size reaches the low-water mark. + +.. note:: + If the buffer size equals the high-water mark, + :meth:`pause_writing` is not called -- it must go strictly over. + Conversely, :meth:`resume_writing` is called when the buffer size is + equal or lower than the low-water mark. These end conditions + are important to ensure that things go as expected when either + mark is zero. + +.. note:: + On BSD systems (OS X, FreeBSD, etc.) flow control is not supported + for :class:`DatagramProtocol`, because send failures caused by + writing too many packets cannot be detected easily. The socket + always appears 'ready' and excess packets are dropped; an + :class:`OSError` with errno set to :const:`errno.ENOBUFS` may or + may not be raised; if it is raised, it will be reported to + :meth:`DatagramProtocol.error_received` but otherwise ignored. + + +Coroutines and protocols +------------------------ + +Coroutines can be scheduled in a protocol method using :func:`async`, but there +is no guarantee made about the execution order. Protocols are not aware of +coroutines created in protocol methods and so will not wait for them. + +To have a reliable execution order, use :ref:`stream objects <asyncio-streams>` in a +coroutine with ``yield from``. For example, the :meth:`StreamWriter.drain` +coroutine can be used to wait until the write buffer is flushed. + + +Protocol examples +================= + +.. _asyncio-tcp-echo-client-protocol: + +TCP echo client protocol +------------------------ + +TCP echo client using the :meth:`BaseEventLoop.create_connection` method, send +data and wait until the connection is closed:: + + import asyncio + + class EchoClientProtocol(asyncio.Protocol): + def __init__(self, message, loop): + self.message = message + self.loop = loop + + def connection_made(self, transport): + transport.write(self.message.encode()) + print('Data sent: {!r}'.format(self.message)) + + def data_received(self, data): + print('Data received: {!r}'.format(data.decode())) + + def connection_lost(self, exc): + print('The server closed the connection') + print('Stop the event lop') + self.loop.stop() + + loop = asyncio.get_event_loop() + message = 'Hello World!' + coro = loop.create_connection(lambda: EchoClientProtocol(message, loop), + '127.0.0.1', 8888) + loop.run_until_complete(coro) + loop.run_forever() + loop.close() + +The event loop is running twice. The +:meth:`~BaseEventLoop.run_until_complete` method is preferred in this short +example to raise an exception if the server is not listening, instead of +having to write a short coroutine to handle the exception and stop the +running loop. At :meth:`~BaseEventLoop.run_until_complete` exit, the loop is +no longer running, so there is no need to stop the loop in case of an error. + +.. seealso:: + + The :ref:`TCP echo client using streams <asyncio-tcp-echo-client-streams>` + example uses the :func:`asyncio.open_connection` function. + + +.. _asyncio-tcp-echo-server-protocol: + +TCP echo server protocol +------------------------ + +TCP echo server using the :meth:`BaseEventLoop.create_server` method, send back +received data and close the connection:: + + import asyncio + + class EchoServerClientProtocol(asyncio.Protocol): + def connection_made(self, transport): + peername = transport.get_extra_info('peername') + print('Connection from {}'.format(peername)) + self.transport = transport + + def data_received(self, data): + message = data.decode() + print('Data received: {!r}'.format(message)) + + print('Send: {!r}'.format(message)) + self.transport.write(data) + + print('Close the client socket') + self.transport.close() + + loop = asyncio.get_event_loop() + # Each client connection will create a new protocol instance + coro = loop.create_server(EchoServerClientProtocol, '127.0.0.1', 8888) + server = loop.run_until_complete(coro) + + # Serve requests until CTRL+c is pressed + print('Serving on {}'.format(server.sockets[0].getsockname())) + try: + loop.run_forever() + except KeyboardInterrupt: + pass + + # Close the server + server.close() + loop.run_until_complete(server.wait_closed()) + loop.close() + +:meth:`Transport.close` can be called immediately after +:meth:`WriteTransport.write` even if data are not sent yet on the socket: both +methods are asynchronous. ``yield from`` is not needed because these transport +methods are not coroutines. + +.. seealso:: + + The :ref:`TCP echo server using streams <asyncio-tcp-echo-server-streams>` + example uses the :func:`asyncio.start_server` function. + + +.. _asyncio-udp-echo-client-protocol: + +UDP echo client protocol +------------------------ + +UDP echo client using the :meth:`BaseEventLoop.create_datagram_endpoint` +method, send data and close the transport when we received the answer:: + + import asyncio + + class EchoClientProtocol: + def __init__(self, message, loop): + self.message = message + self.loop = loop + self.transport = None + + def connection_made(self, transport): + self.transport = transport + print('Send:', self.message) + self.transport.sendto(self.message.encode()) + + def datagram_received(self, data, addr): + print("Received:", data.decode()) + + print("Close the socket") + self.transport.close() + + def error_received(self, exc): + print('Error received:', exc) + + def connection_lost(self, exc): + print("Socket closed, stop the event loop") + loop = asyncio.get_event_loop() + loop.stop() + + loop = asyncio.get_event_loop() + message = "Hello World!" + connect = loop.create_datagram_endpoint( + lambda: EchoClientProtocol(message, loop), + remote_addr=('127.0.0.1', 9999)) + transport, protocol = loop.run_until_complete(connect) + loop.run_forever() + transport.close() + loop.close() + + +.. _asyncio-udp-echo-server-protocol: + +UDP echo server protocol +------------------------ + +UDP echo server using the :meth:`BaseEventLoop.create_datagram_endpoint` +method, send back received data:: + + import asyncio + + class EchoServerProtocol: + def connection_made(self, transport): + self.transport = transport + + def datagram_received(self, data, addr): + message = data.decode() + print('Received %r from %s' % (message, addr)) + print('Send %r to %s' % (message, addr)) + self.transport.sendto(data, addr) + + loop = asyncio.get_event_loop() + print("Starting UDP server") + # One protocol instance will be created to serve all client requests + listen = loop.create_datagram_endpoint( + EchoServerProtocol, local_addr=('127.0.0.1', 9999)) + transport, protocol = loop.run_until_complete(listen) + + try: + loop.run_forever() + except KeyboardInterrupt: + pass + + transport.close() + loop.close() + + +.. _asyncio-register-socket: + +Register an open socket to wait for data using a protocol +--------------------------------------------------------- + +Wait until a socket receives data using the +:meth:`BaseEventLoop.create_connection` method with a protocol, and then close +the event loop :: + + import asyncio + try: + from socket import socketpair + except ImportError: + from asyncio.windows_utils import socketpair + + # Create a pair of connected sockets + rsock, wsock = socketpair() + loop = asyncio.get_event_loop() + + class MyProtocol(asyncio.Protocol): + transport = None + + def connection_made(self, transport): + self.transport = transport + + def data_received(self, data): + print("Received:", data.decode()) + + # We are done: close the transport (it will call connection_lost()) + self.transport.close() + + def connection_lost(self, exc): + # The socket has been closed, stop the event loop + loop.stop() + + # Register the socket to wait for data + connect_coro = loop.create_connection(MyProtocol, sock=rsock) + transport, protocol = loop.run_until_complete(connect_coro) + + # Simulate the reception of data from the network + loop.call_soon(wsock.send, 'abc'.encode()) + + # Run the event loop + loop.run_forever() + + # We are done, close sockets and the event loop + rsock.close() + wsock.close() + loop.close() + +.. seealso:: + + The :ref:`watch a file descriptor for read events + <asyncio-watch-read-event>` example uses the low-level + :meth:`BaseEventLoop.add_reader` method to register the file descriptor of a + socket. + + The :ref:`register an open socket to wait for data using streams + <asyncio-register-socket-streams>` example uses high-level streams + created by the :func:`open_connection` function in a coroutine. diff --git a/Doc/library/asyncio-stream.rst b/Doc/library/asyncio-stream.rst new file mode 100644 index 000000000000..22b7341cb702 --- /dev/null +++ b/Doc/library/asyncio-stream.rst @@ -0,0 +1,424 @@ +.. currentmodule:: asyncio + +.. _asyncio-streams: + +++++++++++++++++++++++++ +Streams (high-level API) +++++++++++++++++++++++++ + +Stream functions +================ + +.. coroutinefunction:: open_connection(host=None, port=None, \*, loop=None, limit=None, \*\*kwds) + + A wrapper for :meth:`~BaseEventLoop.create_connection()` returning a (reader, + writer) pair. + + The reader returned is a :class:`StreamReader` instance; the writer is + a :class:`StreamWriter` instance. + + The arguments are all the usual arguments to + :meth:`BaseEventLoop.create_connection` except *protocol_factory*; most + common are positional host and port, with various optional keyword arguments + following. + + Additional optional keyword arguments are *loop* (to set the event loop + instance to use) and *limit* (to set the buffer limit passed to the + :class:`StreamReader`). + + (If you want to customize the :class:`StreamReader` and/or + :class:`StreamReaderProtocol` classes, just copy the code -- there's really + nothing special here except some convenience.) + + This function is a :ref:`coroutine <coroutine>`. + +.. coroutinefunction:: start_server(client_connected_cb, host=None, port=None, \*, loop=None, limit=None, \*\*kwds) + + Start a socket server, with a callback for each client connected. The return + value is the same as :meth:`~BaseEventLoop.create_server()`. + + The *client_connected_cb* parameter is called with two parameters: + *client_reader*, *client_writer*. *client_reader* is a + :class:`StreamReader` object, while *client_writer* is a + :class:`StreamWriter` object. The *client_connected_cb* parameter can + either be a plain callback function or a :ref:`coroutine function + <coroutine>`; if it is a coroutine function, it will be automatically + converted into a :class:`Task`. + + The rest of the arguments are all the usual arguments to + :meth:`~BaseEventLoop.create_server()` except *protocol_factory*; most + common are positional *host* and *port*, with various optional keyword + arguments following. + + Additional optional keyword arguments are *loop* (to set the event loop + instance to use) and *limit* (to set the buffer limit passed to the + :class:`StreamReader`). + + This function is a :ref:`coroutine <coroutine>`. + +.. coroutinefunction:: open_unix_connection(path=None, \*, loop=None, limit=None, **kwds) + + A wrapper for :meth:`~BaseEventLoop.create_unix_connection()` returning + a (reader, writer) pair. + + See :func:`open_connection` for information about return value and other + details. + + This function is a :ref:`coroutine <coroutine>`. + + Availability: UNIX. + +.. coroutinefunction:: start_unix_server(client_connected_cb, path=None, \*, loop=None, limit=None, **kwds) + + Start a UNIX Domain Socket server, with a callback for each client connected. + + See :func:`start_server` for information about return value and other + details. + + This function is a :ref:`coroutine <coroutine>`. + + Availability: UNIX. + + +StreamReader +============ + +.. class:: StreamReader(limit=None, loop=None) + + .. method:: exception() + + Get the exception. + + .. method:: feed_eof() + + Acknowledge the EOF. + + .. method:: feed_data(data) + + Feed *data* bytes in the internal buffer. Any operations waiting + for the data will be resumed. + + .. method:: set_exception(exc) + + Set the exception. + + .. method:: set_transport(transport) + + Set the transport. + + .. coroutinemethod:: read(n=-1) + + Read up to *n* bytes. If *n* is not provided, or set to ``-1``, + read until EOF and return all read bytes. + + If the EOF was received and the internal buffer is empty, + return an empty ``bytes`` object. + + This method is a :ref:`coroutine <coroutine>`. + + .. coroutinemethod:: readline() + + Read one line, where "line" is a sequence of bytes ending with ``\n``. + + If EOF is received, and ``\n`` was not found, the method will + return the partial read bytes. + + If the EOF was received and the internal buffer is empty, + return an empty ``bytes`` object. + + This method is a :ref:`coroutine <coroutine>`. + + .. coroutinemethod:: readexactly(n) + + Read exactly *n* bytes. Raise an :exc:`IncompleteReadError` if the end of + the stream is reached before *n* can be read, the + :attr:`IncompleteReadError.partial` attribute of the exception contains + the partial read bytes. + + This method is a :ref:`coroutine <coroutine>`. + + .. method:: at_eof() + + Return ``True`` if the buffer is empty and :meth:`feed_eof` was called. + + +StreamWriter +============ + +.. class:: StreamWriter(transport, protocol, reader, loop) + + Wraps a Transport. + + This exposes :meth:`write`, :meth:`writelines`, :meth:`can_write_eof()`, + :meth:`write_eof`, :meth:`get_extra_info` and :meth:`close`. It adds + :meth:`drain` which returns an optional :class:`Future` on which you can + wait for flow control. It also adds a transport attribute which references + the :class:`Transport` directly. + + .. attribute:: transport + + Transport. + + .. method:: can_write_eof() + + Return :const:`True` if the transport supports :meth:`write_eof`, + :const:`False` if not. See :meth:`WriteTransport.can_write_eof`. + + .. method:: close() + + Close the transport: see :meth:`BaseTransport.close`. + + .. coroutinemethod:: drain() + + Let the write buffer of the underlying transport a chance to be flushed. + + The intended use is to write:: + + w.write(data) + yield from w.drain() + + When the size of the transport buffer reaches the high-water limit (the + protocol is paused), block until the size of the buffer is drained down + to the low-water limit and the protocol is resumed. When there is nothing + to wait for, the yield-from continues immediately. + + Yielding from :meth:`drain` gives the opportunity for the loop to + schedule the write operation and flush the buffer. It should especially + be used when a possibly large amount of data is written to the transport, + and the coroutine does not yield-from between calls to :meth:`write`. + + This method is a :ref:`coroutine <coroutine>`. + + .. method:: get_extra_info(name, default=None) + + Return optional transport information: see + :meth:`BaseTransport.get_extra_info`. + + .. method:: write(data) + + Write some *data* bytes to the transport: see + :meth:`WriteTransport.write`. + + .. method:: writelines(data) + + Write a list (or any iterable) of data bytes to the transport: + see :meth:`WriteTransport.writelines`. + + .. method:: write_eof() + + Close the write end of the transport after flushing buffered data: + see :meth:`WriteTransport.write_eof`. + + +StreamReaderProtocol +==================== + +.. class:: StreamReaderProtocol(stream_reader, client_connected_cb=None, loop=None) + + Trivial helper class to adapt between :class:`Protocol` and + :class:`StreamReader`. Sublclass of :class:`Protocol`. + + *stream_reader* is a :class:`StreamReader` instance, *client_connected_cb* + is an optional function called with (stream_reader, stream_writer) when a + connection is made, *loop* is the event loop instance to use. + + (This is a helper class instead of making :class:`StreamReader` itself a + :class:`Protocol` subclass, because the :class:`StreamReader` has other + potential uses, and to prevent the user of the :class:`StreamReader` to + accidentally call inappropriate methods of the protocol.) + + +IncompleteReadError +=================== + +.. exception:: IncompleteReadError + + Incomplete read error, subclass of :exc:`EOFError`. + + .. attribute:: expected + + Total number of expected bytes (:class:`int`). + + .. attribute:: partial + + Read bytes string before the end of stream was reached (:class:`bytes`). + + +Stream examples +=============== + +.. _asyncio-tcp-echo-client-streams: + +TCP echo client using streams +----------------------------- + +TCP echo client using the :func:`asyncio.open_connection` function:: + + import asyncio + + @asyncio.coroutine + def tcp_echo_client(message, loop): + reader, writer = yield from asyncio.open_connection('127.0.0.1', 8888, + loop=loop) + + print('Send: %r' % message) + writer.write(message.encode()) + + data = yield from reader.read(100) + print('Received: %r' % data.decode()) + + print('Close the socket') + writer.close() + + message = 'Hello World!' + loop = asyncio.get_event_loop() + loop.run_until_complete(tcp_echo_client(message, loop)) + loop.close() + +.. seealso:: + + The :ref:`TCP echo client protocol <asyncio-tcp-echo-client-protocol>` + example uses the :meth:`BaseEventLoop.create_connection` method. + + +.. _asyncio-tcp-echo-server-streams: + +TCP echo server using streams +----------------------------- + +TCP echo server using the :func:`asyncio.start_server` function:: + + import asyncio + + @asyncio.coroutine + def handle_echo(reader, writer): + data = yield from reader.read(100) + message = data.decode() + addr = writer.get_extra_info('peername') + print("Received %r from %r" % (message, addr)) + + print("Send: %r" % message) + writer.write(data) + yield from writer.drain() + + print("Close the client socket") + writer.close() + + loop = asyncio.get_event_loop() + coro = asyncio.start_server(handle_echo, '127.0.0.1', 8888, loop=loop) + server = loop.run_until_complete(coro) + + # Serve requests until CTRL+c is pressed + print('Serving on {}'.format(server.sockets[0].getsockname())) + try: + loop.run_forever() + except KeyboardInterrupt: + pass + + # Close the server + server.close() + loop.run_until_complete(server.wait_closed()) + loop.close() + +.. seealso:: + + The :ref:`TCP echo server protocol <asyncio-tcp-echo-server-protocol>` + example uses the :meth:`BaseEventLoop.create_server` method. + + +Get HTTP headers +---------------- + +Simple example querying HTTP headers of the URL passed on the command line:: + + import asyncio + import urllib.parse + import sys + + @asyncio.coroutine + def print_http_headers(url): + url = urllib.parse.urlsplit(url) + if url.scheme == 'https': + connect = asyncio.open_connection(url.hostname, 443, ssl=True) + else: + connect = asyncio.open_connection(url.hostname, 80) + reader, writer = yield from connect + query = ('HEAD {path} HTTP/1.0\r\n' + 'Host: {hostname}\r\n' + '\r\n').format(path=url.path or '/', hostname=url.hostname) + writer.write(query.encode('latin-1')) + while True: + line = yield from reader.readline() + if not line: + break + line = line.decode('latin1').rstrip() + if line: + print('HTTP header> %s' % line) + + # Ignore the body, close the socket + writer.close() + + url = sys.argv[1] + loop = asyncio.get_event_loop() + task = asyncio.async(print_http_headers(url)) + loop.run_until_complete(task) + loop.close() + +Usage:: + + python example.py http://example.com/path/page.html + +or with HTTPS:: + + python example.py https://example.com/path/page.html + +.. _asyncio-register-socket-streams: + +Register an open socket to wait for data using streams +------------------------------------------------------ + +Coroutine waiting until a socket receives data using the +:func:`open_connection` function:: + + import asyncio + try: + from socket import socketpair + except ImportError: + from asyncio.windows_utils import socketpair + + @asyncio.coroutine + def wait_for_data(loop): + # Create a pair of connected sockets + rsock, wsock = socketpair() + + # Register the open socket to wait for data + reader, writer = yield from asyncio.open_connection(sock=rsock, loop=loop) + + # Simulate the reception of data from the network + loop.call_soon(wsock.send, 'abc'.encode()) + + # Wait for data + data = yield from reader.read(100) + + # Got data, we are done: close the socket + print("Received:", data.decode()) + writer.close() + + # Close the second socket + wsock.close() + + loop = asyncio.get_event_loop() + loop.run_until_complete(wait_for_data(loop)) + loop.close() + +.. seealso:: + + The :ref:`register an open socket to wait for data using a protocol + <asyncio-register-socket>` example uses a low-level protocol created by the + :meth:`BaseEventLoop.create_connection` method. + + The :ref:`watch a file descriptor for read events + <asyncio-watch-read-event>` example uses the low-level + :meth:`BaseEventLoop.add_reader` method to register the file descriptor of a + socket. + diff --git a/Doc/library/asyncio-subprocess.rst b/Doc/library/asyncio-subprocess.rst new file mode 100644 index 000000000000..1334f5b133b2 --- /dev/null +++ b/Doc/library/asyncio-subprocess.rst @@ -0,0 +1,414 @@ +.. currentmodule:: asyncio + +.. _asyncio-subprocess: + +Subprocess +========== + +Windows event loop +------------------ + +On Windows, the default event loop is :class:`SelectorEventLoop` which does not +support subprocesses. :class:`ProactorEventLoop` should be used instead. +Example to use it on Windows:: + + import asyncio, os + + if os.name == 'nt': + loop = asyncio.ProactorEventLoop() + asyncio.set_event_loop(loop) + +.. seealso:: + + :ref:`Available event loops <asyncio-event-loops>` and :ref:`Platform + support <asyncio-platform-support>`. + + +Create a subprocess: high-level API using Process +------------------------------------------------- + +.. coroutinefunction:: create_subprocess_exec(\*args, stdin=None, stdout=None, stderr=None, loop=None, limit=None, \*\*kwds) + + Create a subprocess. + + The *limit* parameter sets the buffer limit passed to the + :class:`StreamReader`. See :meth:`BaseEventLoop.subprocess_exec` for other + parameters. + + Return a :class:`~asyncio.subprocess.Process` instance. + + This function is a :ref:`coroutine <coroutine>`. + +.. coroutinefunction:: create_subprocess_shell(cmd, stdin=None, stdout=None, stderr=None, loop=None, limit=None, \*\*kwds) + + Run the shell command *cmd*. + + The *limit* parameter sets the buffer limit passed to the + :class:`StreamReader`. See :meth:`BaseEventLoop.subprocess_shell` for other + parameters. + + Return a :class:`~asyncio.subprocess.Process` instance. + + It is the application's responsibility to ensure that all whitespace and + metacharacters are quoted appropriately to avoid `shell injection + <http://en.wikipedia.org/wiki/Shell_injection#Shell_injection>`_ + vulnerabilities. The :func:`shlex.quote` function can be used to properly + escape whitespace and shell metacharacters in strings that are going to be + used to construct shell commands. + + This function is a :ref:`coroutine <coroutine>`. + +Use the :meth:`BaseEventLoop.connect_read_pipe` and +:meth:`BaseEventLoop.connect_write_pipe` methods to connect pipes. + + +Create a subprocess: low-level API using subprocess.Popen +--------------------------------------------------------- + +Run subprocesses asynchronously using the :mod:`subprocess` module. + +.. coroutinemethod:: BaseEventLoop.subprocess_exec(protocol_factory, \*args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, \*\*kwargs) + + Create a subprocess from one or more string arguments (character strings or + bytes strings encoded to the :ref:`filesystem encoding + <filesystem-encoding>`), where the first string + specifies the program to execute, and the remaining strings specify the + program's arguments. (Thus, together the string arguments form the + ``sys.argv`` value of the program, assuming it is a Python script.) This is + similar to the standard library :class:`subprocess.Popen` class called with + shell=False and the list of strings passed as the first argument; + however, where :class:`~subprocess.Popen` takes a single argument which is + list of strings, :func:`subprocess_exec` takes multiple string arguments. + + The *protocol_factory* must instanciate a subclass of the + :class:`asyncio.SubprocessProtocol` class. + + Other parameters: + + * *stdin*: Either a file-like object representing the pipe to be connected + to the subprocess's standard input stream using + :meth:`~BaseEventLoop.connect_write_pipe`, or the constant + :const:`subprocess.PIPE` (the default). By default a new pipe will be + created and connected. + + * *stdout*: Either a file-like object representing the pipe to be connected + to the subprocess's standard output stream using + :meth:`~BaseEventLoop.connect_read_pipe`, or the constant + :const:`subprocess.PIPE` (the default). By default a new pipe will be + created and connected. + + * *stderr*: Either a file-like object representing the pipe to be connected + to the subprocess's standard error stream using + :meth:`~BaseEventLoop.connect_read_pipe`, or one of the constants + :const:`subprocess.PIPE` (the default) or :const:`subprocess.STDOUT`. + By default a new pipe will be created and connected. When + :const:`subprocess.STDOUT` is specified, the subprocess's standard error + stream will be connected to the same pipe as the standard output stream. + + * All other keyword arguments are passed to :class:`subprocess.Popen` + without interpretation, except for *bufsize*, *universal_newlines* and + *shell*, which should not be specified at all. + + Returns a pair of ``(transport, protocol)``, where *transport* is an + instance of :class:`BaseSubprocessTransport`. + + This method is a :ref:`coroutine <coroutine>`. + + See the constructor of the :class:`subprocess.Popen` class for parameters. + +.. coroutinemethod:: BaseEventLoop.subprocess_shell(protocol_factory, cmd, \*, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, \*\*kwargs) + + Create a subprocess from *cmd*, which is a character string or a bytes + string encoded to the :ref:`filesystem encoding <filesystem-encoding>`, + using the platform's "shell" syntax. This is similar to the standard library + :class:`subprocess.Popen` class called with ``shell=True``. + + The *protocol_factory* must instanciate a subclass of the + :class:`asyncio.SubprocessProtocol` class. + + See :meth:`~BaseEventLoop.subprocess_exec` for more details about + the remaining arguments. + + Returns a pair of ``(transport, protocol)``, where *transport* is an + instance of :class:`BaseSubprocessTransport`. + + It is the application's responsibility to ensure that all whitespace and + metacharacters are quoted appropriately to avoid `shell injection + <http://en.wikipedia.org/wiki/Shell_injection#Shell_injection>`_ + vulnerabilities. The :func:`shlex.quote` function can be used to properly + escape whitespace and shell metacharacters in strings that are going to be + used to construct shell commands. + + This method is a :ref:`coroutine <coroutine>`. + +.. seealso:: + + The :meth:`BaseEventLoop.connect_read_pipe` and + :meth:`BaseEventLoop.connect_write_pipe` methods. + + +Constants +--------- + +.. data:: asyncio.subprocess.PIPE + + Special value that can be used as the *stdin*, *stdout* or *stderr* argument + to :func:`create_subprocess_shell` and :func:`create_subprocess_exec` and + indicates that a pipe to the standard stream should be opened. + +.. data:: asyncio.subprocess.STDOUT + + Special value that can be used as the *stderr* argument to + :func:`create_subprocess_shell` and :func:`create_subprocess_exec` and + indicates that standard error should go into the same handle as standard + output. + +.. data:: asyncio.subprocess.DEVNULL + + Special value that can be used as the *stdin*, *stdout* or *stderr* argument + to :func:`create_subprocess_shell` and :func:`create_subprocess_exec` and + indicates that the special file :data:`os.devnull` will be used. + + +Process +------- + +.. class:: asyncio.subprocess.Process + + A subprocess created by the :func:`create_subprocess_exec` or the + :func:`create_subprocess_shell` function. + + The API of the :class:`~asyncio.subprocess.Process` class was designed to be + closed the API of the :class:`subprocess.Popen` class, but they are some + differences: + + * There is no explicit :meth:`~subprocess.Popen.poll` method + * The :meth:`~subprocess.Popen.communicate` and + :meth:`~subprocess.Popen.wait` methods don't take a *timeout* parameter: + use the :func:`wait_for` function + * The *universal_newlines* parameter is not supported (only bytes strings + are supported) + * The :meth:`~asyncio.subprocess.Process.wait` method of + the :class:`~asyncio.subprocess.Process` class is asynchronous whereas the + :meth:`~subprocess.Popen.wait` method of the :class:`~subprocess.Popen` + class is implemented as a busy loop. + + .. coroutinemethod:: wait() + + Wait for child process to terminate. Set and return :attr:`returncode` + attribute. + + This method is a :ref:`coroutine <coroutine>`. + + .. note:: + + This will deadlock when using ``stdout=PIPE`` or ``stderr=PIPE`` and + the child process generates enough output to a pipe such that it + blocks waiting for the OS pipe buffer to accept more data. Use the + :meth:`communicate` method when using pipes to avoid that. + + .. coroutinemethod:: communicate(input=None) + + Interact with process: Send data to stdin. Read data from stdout and + stderr, until end-of-file is reached. Wait for process to terminate. + The optional *input* argument should be data to be sent to the child + process, or ``None``, if no data should be sent to the child. The type + of *input* must be bytes. + + :meth:`communicate` returns a tuple ``(stdout_data, stderr_data)``. + + If a :exc:`BrokenPipeError` or :exc:`ConnectionResetError` exception is + raised when writing *input* into stdin, the exception is ignored. It + occurs when the process exits before all data are written into stdin. + + Note that if you want to send data to the process's stdin, you need to + create the Process object with ``stdin=PIPE``. Similarly, to get anything + other than ``None`` in the result tuple, you need to give ``stdout=PIPE`` + and/or ``stderr=PIPE`` too. + + This method is a :ref:`coroutine <coroutine>`. + + .. note:: + + The data read is buffered in memory, so do not use this method if the + data size is large or unlimited. + + .. versionchanged:: 3.4.2 + The method now ignores :exc:`BrokenPipeError` and + :exc:`ConnectionResetError`. + + .. method:: send_signal(signal) + + Sends the signal *signal* to the child process. + + .. note:: + + On Windows, :py:data:`SIGTERM` is an alias for :meth:`terminate`. + ``CTRL_C_EVENT`` and ``CTRL_BREAK_EVENT`` can be sent to processes + started with a *creationflags* parameter which includes + ``CREATE_NEW_PROCESS_GROUP``. + + .. method:: terminate() + + Stop the child. On Posix OSs the method sends :py:data:`signal.SIGTERM` + to the child. On Windows the Win32 API function + :c:func:`TerminateProcess` is called to stop the child. + + .. method:: kill() + + Kills the child. On Posix OSs the function sends :py:data:`SIGKILL` to + the child. On Windows :meth:`kill` is an alias for :meth:`terminate`. + + .. attribute:: stdin + + Standard input stream (:class:`StreamWriter`), ``None`` if the process + was created with ``stdin=None``. + + .. attribute:: stdout + + Standard output stream (:class:`StreamReader`), ``None`` if the process + was created with ``stdout=None``. + + .. attribute:: stderr + + Standard error stream (:class:`StreamReader`), ``None`` if the process + was created with ``stderr=None``. + + .. warning:: + + Use the :meth:`communicate` method rather than :attr:`.stdin.write + <stdin>`, :attr:`.stdout.read <stdout>` or :attr:`.stderr.read <stderr>` + to avoid deadlocks due to streams pausing reading or writing and blocking + the child process. + + .. attribute:: pid + + The identifier of the process. + + Note that for processes created by the :func:`create_subprocess_shell` + function, this attribute is the process identifier of the spawned shell. + + .. attribute:: returncode + + Return code of the process when it exited. A ``None`` value indicates + that the process has not terminated yet. + + A negative value ``-N`` indicates that the child was terminated by signal + ``N`` (Unix only). + + +.. _asyncio-subprocess-threads: + +Subprocess and threads +====================== + +asyncio supports running subprocesses from different threads, but there +are limits: + +* An event loop must run in the main thread +* The child watcher must be instantiated in the main thread, before executing + subprocesses from other threads. Call the :func:`get_child_watcher` + function in the main thread to instantiate the child watcher. + +.. seealso:: + + The :ref:`Concurrency and multithreading in asyncio + <asyncio-multithreading>` section. + + +Subprocess examples +=================== + +Subprocess using transport and protocol +--------------------------------------- + +Example of a subprocess protocol using to get the output of a subprocess and to +wait for the subprocess exit. The subprocess is created by the +:meth:`BaseEventLoop.subprocess_exec` method:: + + import asyncio + import sys + + class DateProtocol(asyncio.SubprocessProtocol): + def __init__(self, exit_future): + self.exit_future = exit_future + self.output = bytearray() + + def pipe_data_received(self, fd, data): + self.output.extend(data) + + def process_exited(self): + self.exit_future.set_result(True) + + @asyncio.coroutine + def get_date(loop): + code = 'import datetime; print(datetime.datetime.now())' + exit_future = asyncio.Future(loop=loop) + + # Create the subprocess controlled by the protocol DateProtocol, + # redirect the standard output into a pipe + create = loop.subprocess_exec(lambda: DateProtocol(exit_future), + sys.executable, '-c', code, + stdin=None, stderr=None) + transport, protocol = yield from create + + # Wait for the subprocess exit using the process_exited() method + # of the protocol + yield from exit_future + + # Close the stdout pipe + transport.close() + + # Read the output which was collected by the pipe_data_received() + # method of the protocol + data = bytes(protocol.output) + return data.decode('ascii').rstrip() + + if sys.platform == "win32": + loop = asyncio.ProactorEventLoop() + asyncio.set_event_loop(loop) + else: + loop = asyncio.get_event_loop() + + date = loop.run_until_complete(get_date(loop)) + print("Current date: %s" % date) + loop.close() + + +Subprocess using streams +------------------------ + +Example using the :class:`~asyncio.subprocess.Process` class to control the +subprocess and the :class:`StreamReader` class to read from the standard +output. The subprocess is created by the :func:`create_subprocess_exec` +function:: + + import asyncio.subprocess + import sys + + @asyncio.coroutine + def get_date(): + code = 'import datetime; print(datetime.datetime.now())' + + # Create the subprocess, redirect the standard output into a pipe + create = asyncio.create_subprocess_exec(sys.executable, '-c', code, + stdout=asyncio.subprocess.PIPE) + proc = yield from create + + # Read one line of output + data = yield from proc.stdout.readline() + line = data.decode('ascii').rstrip() + + # Wait for the subprocess exit + yield from proc.wait() + return line + + if sys.platform == "win32": + loop = asyncio.ProactorEventLoop() + asyncio.set_event_loop(loop) + else: + loop = asyncio.get_event_loop() + + date = loop.run_until_complete(get_date()) + print("Current date: %s" % date) + loop.close() diff --git a/Doc/library/asyncio-sync.rst b/Doc/library/asyncio-sync.rst new file mode 100644 index 000000000000..e3d82b0dc4b4 --- /dev/null +++ b/Doc/library/asyncio-sync.rst @@ -0,0 +1,446 @@ +.. currentmodule:: asyncio +.. _asyncio-sync: + +Synchronization primitives +========================== + +Locks: + +* :class:`Lock` +* :class:`Event` +* :class:`Condition` +* :class:`Semaphore` +* :class:`BoundedSemaphore` + +Queues: + +* :class:`Queue` +* :class:`PriorityQueue` +* :class:`LifoQueue` +* :class:`JoinableQueue` + +asyncio locks and queues API were designed to be close to classes of the +:mod:`threading` module (:class:`~threading.Lock`, :class:`~threading.Event`, +:class:`~threading.Condition`, :class:`~threading.Semaphore`, +:class:`~threading.BoundedSemaphore`) and the :mod:`queue` module +(:class:`~queue.Queue`, :class:`~queue.PriorityQueue`, +:class:`~queue.LifoQueue`), but they have no *timeout* parameter. The +:func:`asyncio.wait_for` function can be used to cancel a task after a timeout. + +Locks +----- + +Lock +^^^^ + +.. class:: Lock(\*, loop=None) + + Primitive lock objects. + + A primitive lock is a synchronization primitive that is not owned by a + particular coroutine when locked. A primitive lock is in one of two states, + 'locked' or 'unlocked'. + + It is created in the unlocked state. It has two basic methods, :meth:`acquire` + and :meth:`release`. When the state is unlocked, acquire() changes the state to + locked and returns immediately. When the state is locked, acquire() blocks + until a call to release() in another coroutine changes it to unlocked, then + the acquire() call resets it to locked and returns. The release() method + should only be called in the locked state; it changes the state to unlocked + and returns immediately. If an attempt is made to release an unlocked lock, + a :exc:`RuntimeError` will be raised. + + When more than one coroutine is blocked in acquire() waiting for the state + to turn to unlocked, only one coroutine proceeds when a release() call + resets the state to unlocked; first coroutine which is blocked in acquire() + is being processed. + + :meth:`acquire` is a coroutine and should be called with ``yield from``. + + Locks also support the context management protocol. ``(yield from lock)`` + should be used as context manager expression. + + Usage:: + + lock = Lock() + ... + yield from lock + try: + ... + finally: + lock.release() + + Context manager usage:: + + lock = Lock() + ... + with (yield from lock): + ... + + Lock objects can be tested for locking state:: + + if not lock.locked(): + yield from lock + else: + # lock is acquired + ... + + .. method:: locked() + + Return ``True`` if the lock is acquired. + + .. coroutinemethod:: acquire() + + Acquire a lock. + + This method blocks until the lock is unlocked, then sets it to locked and + returns ``True``. + + This method is a :ref:`coroutine <coroutine>`. + + .. method:: release() + + Release a lock. + + When the lock is locked, reset it to unlocked, and return. If any other + coroutines are blocked waiting for the lock to become unlocked, allow + exactly one of them to proceed. + + When invoked on an unlocked lock, a :exc:`RuntimeError` is raised. + + There is no return value. + + +Event +^^^^^ + +.. class:: Event(\*, loop=None) + + An Event implementation, asynchronous equivalent to :class:`threading.Event`. + + Class implementing event objects. An event manages a flag that can be set to + true with the :meth:`set` method and reset to false with the :meth:`clear` + method. The :meth:`wait` method blocks until the flag is true. The flag is + initially false. + + .. method:: clear() + + Reset the internal flag to false. Subsequently, coroutines calling + :meth:`wait` will block until :meth:`set` is called to set the internal + flag to true again. + + .. method:: is_set() + + Return ``True`` if and only if the internal flag is true. + + .. method:: set() + + Set the internal flag to true. All coroutines waiting for it to become + true are awakened. Coroutine that call :meth:`wait` once the flag is true + will not block at all. + + .. coroutinemethod:: wait() + + Block until the internal flag is true. + + If the internal flag is true on entry, return ``True`` immediately. + Otherwise, block until another coroutine calls :meth:`set` to set the + flag to true, then return ``True``. + + This method is a :ref:`coroutine <coroutine>`. + + +Condition +^^^^^^^^^ + +.. class:: Condition(lock=None, \*, loop=None) + + A Condition implementation, asynchronous equivalent to + :class:`threading.Condition`. + + This class implements condition variable objects. A condition variable + allows one or more coroutines to wait until they are notified by another + coroutine. + + If the *lock* argument is given and not ``None``, it must be a :class:`Lock` + object, and it is used as the underlying lock. Otherwise, + a new :class:`Lock` object is created and used as the underlying lock. + + .. coroutinemethod:: acquire() + + Acquire the underlying lock. + + This method blocks until the lock is unlocked, then sets it to locked and + returns ``True``. + + This method is a :ref:`coroutine <coroutine>`. + + .. method:: notify(n=1) + + By default, wake up one coroutine waiting on this condition, if any. + If the calling coroutine has not acquired the lock when this method is + called, a :exc:`RuntimeError` is raised. + + This method wakes up at most *n* of the coroutines waiting for the + condition variable; it is a no-op if no coroutines are waiting. + + .. note:: + + An awakened coroutine does not actually return from its :meth:`wait` + call until it can reacquire the lock. Since :meth:`notify` does not + release the lock, its caller should. + + .. method:: locked() + + Return ``True`` if the underlying lock is acquired. + + .. method:: notify_all() + + Wake up all threads waiting on this condition. This method acts like + :meth:`notify`, but wakes up all waiting threads instead of one. If the + calling thread has not acquired the lock when this method is called, a + :exc:`RuntimeError` is raised. + + .. method:: release() + + Release the underlying lock. + + When the lock is locked, reset it to unlocked, and return. If any other + coroutines are blocked waiting for the lock to become unlocked, allow + exactly one of them to proceed. + + When invoked on an unlocked lock, a :exc:`RuntimeError` is raised. + + There is no return value. + + .. coroutinemethod:: wait() + + Wait until notified. + + If the calling coroutine has not acquired the lock when this method is + called, a :exc:`RuntimeError` is raised. + + This method releases the underlying lock, and then blocks until it is + awakened by a :meth:`notify` or :meth:`notify_all` call for the same + condition variable in another coroutine. Once awakened, it re-acquires + the lock and returns ``True``. + + This method is a :ref:`coroutine <coroutine>`. + + .. coroutinemethod:: wait_for(predicate) + + Wait until a predicate becomes true. + + The predicate should be a callable which result will be interpreted as a + boolean value. The final predicate value is the return value. + + This method is a :ref:`coroutine <coroutine>`. + + +Semaphores +---------- + +Semaphore +^^^^^^^^^ + +.. class:: Semaphore(value=1, \*, loop=None) + + A Semaphore implementation. + + A semaphore manages an internal counter which is decremented by each + :meth:`acquire` call and incremented by each :meth:`release` call. The + counter can never go below zero; when :meth:`acquire` finds that it is zero, + it blocks, waiting until some other thread calls :meth:`release`. + + Semaphores also support the context management protocol. + + The optional argument gives the initial value for the internal counter; it + defaults to ``1``. If the value given is less than ``0``, :exc:`ValueError` + is raised. + + .. coroutinemethod:: acquire() + + Acquire a semaphore. + + If the internal counter is larger than zero on entry, decrement it by one + and return ``True`` immediately. If it is zero on entry, block, waiting + until some other coroutine has called :meth:`release` to make it larger + than ``0``, and then return ``True``. + + This method is a :ref:`coroutine <coroutine>`. + + .. method:: locked() + + Returns ``True`` if semaphore can not be acquired immediately. + + .. coroutinemethod:: release() + + Release a semaphore, incrementing the internal counter by one. When it + was zero on entry and another coroutine is waiting for it to become + larger than zero again, wake up that coroutine. + + +BoundedSemaphore +^^^^^^^^^^^^^^^^ + +.. class:: BoundedSemaphore(value=1, \*, loop=None) + + A bounded semaphore implementation. Inherit from :class:`Semaphore`. + + This raises :exc:`ValueError` in :meth:`~Semaphore.release` if it would + increase the value above the initial value. + + +Queues +------ + +Queue +^^^^^ + +.. class:: Queue(maxsize=0, \*, loop=None) + + A queue, useful for coordinating producer and consumer coroutines. + + If *maxsize* is less than or equal to zero, the queue size is infinite. If + it is an integer greater than ``0``, then ``yield from put()`` will block + when the queue reaches *maxsize*, until an item is removed by :meth:`get`. + + Unlike the standard library :mod:`queue`, you can reliably know this Queue's + size with :meth:`qsize`, since your single-threaded asyncio application won't + be interrupted between calling :meth:`qsize` and doing an operation on the + Queue. + + .. versionchanged:: 3.4.3 + New :meth:`join` and :meth:`task_done` methods. + + .. method:: empty() + + Return ``True`` if the queue is empty, ``False`` otherwise. + + .. method:: full() + + Return ``True`` if there are :attr:`maxsize` items in the queue. + + .. note:: + + If the Queue was initialized with ``maxsize=0`` (the default), then + :meth:`full()` is never ``True``. + + .. coroutinemethod:: get() + + Remove and return an item from the queue. If queue is empty, wait until + an item is available. + + This method is a :ref:`coroutine <coroutine>`. + + .. seealso:: + + The :meth:`empty` method. + + .. method:: get_nowait() + + Remove and return an item from the queue. + + Return an item if one is immediately available, else raise + :exc:`QueueEmpty`. + + .. coroutinemethod:: join() + + Block until all items in the queue have been gotten and processed. + + The count of unfinished tasks goes up whenever an item is added to the + queue. The count goes down whenever a consumer thread calls + :meth:`task_done` to indicate that the item was retrieved and all work on + it is complete. When the count of unfinished tasks drops to zero, + :meth:`join` unblocks. + + This method is a :ref:`coroutine <coroutine>`. + + .. versionadded:: 3.4.3 + + .. coroutinemethod:: put(item) + + Put an item into the queue. If the queue is full, wait until a free slot + is available before adding item. + + This method is a :ref:`coroutine <coroutine>`. + + .. seealso:: + + The :meth:`full` method. + + .. method:: put_nowait(item) + + Put an item into the queue without blocking. + + If no free slot is immediately available, raise :exc:`QueueFull`. + + .. method:: qsize() + + Number of items in the queue. + + .. method:: task_done() + + Indicate that a formerly enqueued task is complete. + + Used by queue consumers. For each :meth:`~Queue.get` used to fetch a task, a + subsequent call to :meth:`task_done` tells the queue that the processing + on the task is complete. + + If a :meth:`join` is currently blocking, it will resume when all items + have been processed (meaning that a :meth:`task_done` call was received + for every item that had been :meth:`~Queue.put` into the queue). + + Raises :exc:`ValueError` if called more times than there were items + placed in the queue. + + .. versionadded:: 3.4.3 + + .. attribute:: maxsize + + Number of items allowed in the queue. + + +PriorityQueue +^^^^^^^^^^^^^ + +.. class:: PriorityQueue + + A subclass of :class:`Queue`; retrieves entries in priority order (lowest + first). + + Entries are typically tuples of the form: (priority number, data). + + +LifoQueue +^^^^^^^^^ + +.. class:: LifoQueue + + A subclass of :class:`Queue` that retrieves most recently added entries + first. + + +JoinableQueue +^^^^^^^^^^^^^ + +.. class:: JoinableQueue + + Deprecated alias for :class:`Queue`. + + .. deprecated:: 3.4.3 + + +Exceptions +^^^^^^^^^^ + +.. exception:: QueueEmpty + + Exception raised when the :meth:`~Queue.get_nowait` method is called on a + :class:`Queue` object which is empty. + + +.. exception:: QueueFull + + Exception raised when the :meth:`~Queue.put_nowait` method is called on a + :class:`Queue` object which is full. diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst new file mode 100644 index 000000000000..edc05c3d6ac5 --- /dev/null +++ b/Doc/library/asyncio-task.rst @@ -0,0 +1,646 @@ +.. currentmodule:: asyncio + +Tasks and coroutines +==================== + +.. _coroutine: + +Coroutines +---------- + +A coroutine is a generator that follows certain conventions. For +documentation purposes, all coroutines should be decorated with +``@asyncio.coroutine``, but this cannot be strictly enforced. + +Coroutines use the ``yield from`` syntax introduced in :pep:`380`, +instead of the original ``yield`` syntax. + +The word "coroutine", like the word "generator", is used for two +different (though related) concepts: + +- The function that defines a coroutine (a function definition + decorated with ``@asyncio.coroutine``). If disambiguation is needed + we will call this a *coroutine function* (:func:`iscoroutinefunction` + returns ``True``). + +- The object obtained by calling a coroutine function. This object + represents a computation or an I/O operation (usually a combination) + that will complete eventually. If disambiguation is needed we will + call it a *coroutine object* (:func:`iscoroutine` returns ``True``). + +Things a coroutine can do: + +- ``result = yield from future`` -- suspends the coroutine until the + future is done, then returns the future's result, or raises an + exception, which will be propagated. (If the future is cancelled, + it will raise a ``CancelledError`` exception.) Note that tasks are + futures, and everything said about futures also applies to tasks. + +- ``result = yield from coroutine`` -- wait for another coroutine to + produce a result (or raise an exception, which will be propagated). + The ``coroutine`` expression must be a *call* to another coroutine. + +- ``return expression`` -- produce a result to the coroutine that is + waiting for this one using ``yield from``. + +- ``raise exception`` -- raise an exception in the coroutine that is + waiting for this one using ``yield from``. + +Calling a coroutine does not start its code running -- it is just a +generator, and the coroutine object returned by the call is really a +generator object, which doesn't do anything until you iterate over it. +In the case of a coroutine object, there are two basic ways to start +it running: call ``yield from coroutine`` from another coroutine +(assuming the other coroutine is already running!), or schedule its execution +using the :func:`async` function or the :meth:`BaseEventLoop.create_task` +method. + + +Coroutines (and tasks) can only run when the event loop is running. + +.. decorator:: coroutine + + Decorator to mark coroutines. + + If the coroutine is not yielded from before it is destroyed, an error + message is logged. See :ref:`Detect coroutines never scheduled + <asyncio-coroutine-not-scheduled>`. + +.. note:: + + In this documentation, some methods are documented as coroutines, + even if they are plain Python functions returning a :class:`Future`. + This is intentional to have a freedom of tweaking the implementation + of these functions in the future. If such a function is needed to be + used in a callback-style code, wrap its result with :func:`async`. + + +.. _asyncio-hello-world-coroutine: + +Example: Hello World coroutine +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Example of coroutine displaying ``"Hello World"``:: + + import asyncio + + @asyncio.coroutine + def hello_world(): + print("Hello World!") + + loop = asyncio.get_event_loop() + # Blocking call which returns when the hello_world() coroutine is done + loop.run_until_complete(hello_world()) + loop.close() + +.. seealso:: + + The :ref:`Hello World with call_soon() <asyncio-hello-world-callback>` + example uses the :meth:`BaseEventLoop.call_soon` method to schedule a + callback. + + +.. _asyncio-date-coroutine: + +Example: Coroutine displaying the current date +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Example of coroutine displaying the current date every second during 5 seconds +using the :meth:`sleep` function:: + + import asyncio + import datetime + + @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) + + loop = asyncio.get_event_loop() + # Blocking call which returns when the display_date() coroutine is done + loop.run_until_complete(display_date(loop)) + loop.close() + +.. seealso:: + + The :ref:`display the current date with call_later() + <asyncio-date-callback>` example uses a callback with the + :meth:`BaseEventLoop.call_later` method. + + +Example: Chain coroutines +^^^^^^^^^^^^^^^^^^^^^^^^^ + +Example chaining coroutines:: + + import asyncio + + @asyncio.coroutine + def compute(x, y): + print("Compute %s + %s ..." % (x, y)) + yield from asyncio.sleep(1.0) + return x + y + + @asyncio.coroutine + def print_sum(x, y): + result = yield from compute(x, y) + print("%s + %s = %s" % (x, y, result)) + + loop = asyncio.get_event_loop() + loop.run_until_complete(print_sum(1, 2)) + loop.close() + +``compute()`` is chained to ``print_sum()``: ``print_sum()`` coroutine waits +until ``compute()`` is completed before returning its result. + +Sequence diagram of the example: + +.. image:: tulip_coro.png + :align: center + +The "Task" is created by the :meth:`BaseEventLoop.run_until_complete` method +when it gets a coroutine object instead of a task. + +The diagram shows the control flow, it does not describe exactly how things +work internally. For example, the sleep coroutine creates an internal future +which uses :meth:`BaseEventLoop.call_later` to wake up the task in 1 second. + + +InvalidStateError +----------------- + +.. exception:: InvalidStateError + + The operation is not allowed in this state. + + +TimeoutError +------------ + +.. exception:: TimeoutError + + The operation exceeded the given deadline. + +.. note:: + + This exception is different from the builtin :exc:`TimeoutError` exception! + + +Future +------ + +.. class:: Future(\*, loop=None) + + This class is *almost* compatible with :class:`concurrent.futures.Future`. + + Differences: + + - :meth:`result` and :meth:`exception` do not take a timeout argument and + raise an exception when the future isn't done yet. + + - Callbacks registered with :meth:`add_done_callback` are always called + via the event loop's :meth:`~BaseEventLoop.call_soon_threadsafe`. + + - This class is not compatible with the :func:`~concurrent.futures.wait` and + :func:`~concurrent.futures.as_completed` functions in the + :mod:`concurrent.futures` package. + + .. method:: cancel() + + Cancel the future and schedule callbacks. + + If the future is already done or cancelled, return ``False``. Otherwise, + change the future's state to cancelled, schedule the callbacks and return + ``True``. + + .. method:: cancelled() + + Return ``True`` if the future was cancelled. + + .. method:: done() + + Return True if the future is done. + + Done means either that a result / exception are available, or that the + future was cancelled. + + .. method:: result() + + Return the result this future represents. + + If the future has been cancelled, raises :exc:`CancelledError`. If the + future's result isn't yet available, raises :exc:`InvalidStateError`. If + the future is done and has an exception set, this exception is raised. + + .. method:: exception() + + Return the exception that was set on this future. + + The exception (or ``None`` if no exception was set) is returned only if + the future is done. If the future has been cancelled, raises + :exc:`CancelledError`. If the future isn't done yet, raises + :exc:`InvalidStateError`. + + .. method:: add_done_callback(fn) + + Add a callback to be run when the future becomes done. + + The callback is called with a single argument - the future object. If the + future is already done when this is called, the callback is scheduled + with :meth:`~BaseEventLoop.call_soon`. + + :ref:`Use functools.partial to pass parameters to the callback + <asyncio-pass-keywords>`. For example, + ``fut.add_done_callback(functools.partial(print, "Future:", + flush=True))`` will call ``print("Future:", fut, flush=True)``. + + .. method:: remove_done_callback(fn) + + Remove all instances of a callback from the "call when done" list. + + Returns the number of callbacks removed. + + .. method:: set_result(result) + + Mark the future done and set its result. + + If the future is already done when this method is called, raises + :exc:`InvalidStateError`. + + .. method:: set_exception(exception) + + Mark the future done and set an exception. + + If the future is already done when this method is called, raises + :exc:`InvalidStateError`. + + +Example: Future with run_until_complete() +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Example combining a :class:`Future` and a :ref:`coroutine function +<coroutine>`:: + + import asyncio + + @asyncio.coroutine + def slow_operation(future): + yield from asyncio.sleep(1) + future.set_result('Future is done!') + + loop = asyncio.get_event_loop() + future = asyncio.Future() + asyncio.async(slow_operation(future)) + loop.run_until_complete(future) + print(future.result()) + loop.close() + +The coroutine function is responsible for the computation (which takes 1 second) +and it stores the result into the future. The +:meth:`~BaseEventLoop.run_until_complete` method waits for the completion of +the future. + +.. note:: + The :meth:`~BaseEventLoop.run_until_complete` method uses internally the + :meth:`~Future.add_done_callback` method to be notified when the future is + done. + + +Example: Future with run_forever() +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The previous example can be written differently using the +:meth:`Future.add_done_callback` method to describe explicitly the control +flow:: + + import asyncio + + @asyncio.coroutine + def slow_operation(future): + yield from asyncio.sleep(1) + future.set_result('Future is done!') + + def got_result(future): + print(future.result()) + loop.stop() + + loop = asyncio.get_event_loop() + future = asyncio.Future() + asyncio.async(slow_operation(future)) + future.add_done_callback(got_result) + try: + loop.run_forever() + finally: + loop.close() + +In this example, the future is used to link ``slow_operation()`` to +``got_result()``: when ``slow_operation()`` is done, ``got_result()`` is called +with the result. + + +Task +---- + +.. class:: Task(coro, \*, loop=None) + + Schedule the execution of a :ref:`coroutine <coroutine>`: wrap it in a + future. A task is a subclass of :class:`Future`. + + A task is responsible for executing a coroutine object in an event loop. If + the wrapped coroutine yields from a future, the task suspends the execution + of the wrapped coroutine and waits for the completition of the future. When + the future is done, the execution of the wrapped coroutine restarts with the + result or the exception of the future. + + Event loops use cooperative scheduling: an event loop only runs one task at + a time. Other tasks may run in parallel if other event loops are + running in different threads. While a task waits for the completion of a + future, the event loop executes a new task. + + The cancellation of a task is different from the cancelation of a future. Calling + :meth:`cancel` will throw a :exc:`~concurrent.futures.CancelledError` to the + wrapped coroutine. :meth:`~Future.cancelled` only returns ``True`` if the + wrapped coroutine did not catch the + :exc:`~concurrent.futures.CancelledError` exception, or raised a + :exc:`~concurrent.futures.CancelledError` exception. + + If a pending task is destroyed, the execution of its wrapped :ref:`coroutine + <coroutine>` did not complete. It is probably a bug and a warning is + logged: see :ref:`Pending task destroyed <asyncio-pending-task-destroyed>`. + + Don't directly create :class:`Task` instances: use the :func:`async` + function or the :meth:`BaseEventLoop.create_task` method. + + .. classmethod:: all_tasks(loop=None) + + Return a set of all tasks for an event loop. + + By default all tasks for the current event loop are returned. + + .. classmethod:: current_task(loop=None) + + Return the currently running task in an event loop or ``None``. + + By default the current task for the current event loop is returned. + + ``None`` is returned when called not in the context of a :class:`Task`. + + .. method:: cancel() + + Request that this task cancel itself. + + This arranges for a :exc:`~concurrent.futures.CancelledError` to be + thrown into the wrapped coroutine on the next cycle through the event + loop. The coroutine then has a chance to clean up or even deny the + request using try/except/finally. + + Unlike :meth:`Future.cancel`, this does not guarantee that the task + will be cancelled: the exception might be caught and acted upon, delaying + cancellation of the task or preventing cancellation completely. The task + may also return a value or raise a different exception. + + Immediately after this method is called, :meth:`~Future.cancelled` will + not return ``True`` (unless the task was already cancelled). A task will + be marked as cancelled when the wrapped coroutine terminates with a + :exc:`~concurrent.futures.CancelledError` exception (even if + :meth:`cancel` was not called). + + .. method:: get_stack(\*, limit=None) + + Return the list of stack frames for this task's coroutine. + + If the coroutine is not done, this returns the stack where it is suspended. + If the coroutine has completed successfully or was cancelled, this + returns an empty list. If the coroutine was terminated by an exception, + this returns the list of traceback frames. + + The frames are always ordered from oldest to newest. + + The optional limit gives the maximum number of frames to return; by + default all available frames are returned. Its meaning differs depending + on whether a stack or a traceback is returned: the newest frames of a + stack are returned, but the oldest frames of a traceback are returned. + (This matches the behavior of the traceback module.) + + For reasons beyond our control, only one stack frame is returned for a + suspended coroutine. + + .. method:: print_stack(\*, limit=None, file=None) + + Print the stack or traceback for this task's coroutine. + + This produces output similar to that of the traceback module, for the + frames retrieved by get_stack(). The limit argument is passed to + get_stack(). The file argument is an I/O stream to which the output + is written; by default output is written to sys.stderr. + + +Example: Parallel execution of tasks +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Example executing 3 tasks (A, B, C) in parallel:: + + import asyncio + + @asyncio.coroutine + 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) + f *= i + print("Task %s: factorial(%s) = %s" % (name, number, f)) + + loop = asyncio.get_event_loop() + tasks = [ + asyncio.async(factorial("A", 2)), + asyncio.async(factorial("B", 3)), + asyncio.async(factorial("C", 4))] + loop.run_until_complete(asyncio.wait(tasks)) + loop.close() + +Output:: + + Task A: Compute factorial(2)... + Task B: Compute factorial(2)... + Task C: Compute factorial(2)... + Task A: factorial(2) = 2 + Task B: Compute factorial(3)... + Task C: Compute factorial(3)... + Task B: factorial(3) = 6 + Task C: Compute factorial(4)... + Task C: factorial(4) = 24 + +A task is automatically scheduled for execution when it is created. The event +loop stops when all tasks are done. + + +Task functions +-------------- + +.. note:: + + In the functions below, the optional *loop* argument allows to explicitly set + the event loop object used by the underlying task or coroutine. If it's + not provided, the default event loop is used. + +.. function:: as_completed(fs, \*, loop=None, timeout=None) + + Return an iterator whose values, when waited for, are :class:`Future` + instances. + + Raises :exc:`asyncio.TimeoutError` if the timeout occurs before all Futures + are done. + + Example:: + + for f in as_completed(fs): + result = yield from f # The 'yield from' may raise + # Use result + + .. note:: + + The futures ``f`` are not necessarily members of fs. + +.. function:: async(coro_or_future, \*, loop=None) + + Schedule the execution of a :ref:`coroutine object <coroutine>`: wrap it in + a future. Return a :class:`Task` object. + + If the argument is a :class:`Future`, it is returned directly. + + .. seealso:: + + The :meth:`BaseEventLoop.create_task` method. + +.. function:: gather(\*coros_or_futures, loop=None, return_exceptions=False) + + Return a future aggregating results from the given coroutine objects or + futures. + + All futures must share the same event loop. If all the tasks are done + successfully, the returned future's result is the list of results (in the + order of the original sequence, not necessarily the order of results + arrival). If *return_exceptions* is True, exceptions in the tasks are + treated the same as successful results, and gathered in the result list; + otherwise, the first raised exception will be immediately propagated to the + returned future. + + Cancellation: if the outer Future is cancelled, all children (that have not + completed yet) are also cancelled. If any child is cancelled, this is + treated as if it raised :exc:`~concurrent.futures.CancelledError` -- the + outer Future is *not* cancelled in this case. (This is to prevent the + cancellation of one child to cause other children to be cancelled.) + +.. function:: iscoroutine(obj) + + Return ``True`` if *obj* is a :ref:`coroutine object <coroutine>`. + +.. function:: iscoroutinefunction(obj) + + Return ``True`` if *func* is a decorated :ref:`coroutine function + <coroutine>`. + +.. coroutinefunction:: sleep(delay, result=None, \*, loop=None) + + Create a :ref:`coroutine <coroutine>` that completes after a given + time (in seconds). If *result* is provided, it is produced to the caller + when the coroutine completes. + + The resolution of the sleep depends on the :ref:`granularity of the event + loop <asyncio-delayed-calls>`. + + This function is a :ref:`coroutine <coroutine>`. + +.. function:: shield(arg, \*, loop=None) + + Wait for a future, shielding it from cancellation. + + The statement:: + + res = yield from shield(something()) + + is exactly equivalent to the statement:: + + res = yield from something() + + *except* that if the coroutine containing it is cancelled, the task running + in ``something()`` is not cancelled. From the point of view of + ``something()``, the cancellation did not happen. But its caller is still + cancelled, so the yield-from expression still raises + :exc:`~concurrent.futures.CancelledError`. Note: If ``something()`` is + cancelled by other means this will still cancel ``shield()``. + + If you want to completely ignore cancellation (not recommended) you can + combine ``shield()`` with a try/except clause, as follows:: + + try: + res = yield from shield(something()) + except CancelledError: + res = None + +.. coroutinefunction:: wait(futures, \*, loop=None, timeout=None, return_when=ALL_COMPLETED) + + Wait for the Futures and coroutine objects given by the sequence *futures* + to complete. Coroutines will be wrapped in Tasks. Returns two sets of + :class:`Future`: (done, pending). + + The sequence *futures* must not be empty. + + *timeout* can be used to control the maximum number of seconds to wait before + returning. *timeout* can be an int or float. If *timeout* is not specified + or ``None``, there is no limit to the wait time. + + *return_when* indicates when this function should return. It must be one of + the following constants of the :mod:`concurrent.futures` module: + + .. tabularcolumns:: |l|L| + + +-----------------------------+----------------------------------------+ + | Constant | Description | + +=============================+========================================+ + | :const:`FIRST_COMPLETED` | The function will return when any | + | | future finishes or is cancelled. | + +-----------------------------+----------------------------------------+ + | :const:`FIRST_EXCEPTION` | The function will return when any | + | | future finishes by raising an | + | | exception. If no future raises an | + | | exception then it is equivalent to | + | | :const:`ALL_COMPLETED`. | + +-----------------------------+----------------------------------------+ + | :const:`ALL_COMPLETED` | The function will return when all | + | | futures finish or are cancelled. | + +-----------------------------+----------------------------------------+ + + This function is a :ref:`coroutine <coroutine>`. + + Usage:: + + done, pending = yield from asyncio.wait(fs) + + .. note:: + + This does not raise :exc:`asyncio.TimeoutError`! Futures that aren't done + when the timeout occurs are returned in the second set. + + +.. coroutinefunction:: wait_for(fut, timeout, \*, loop=None) + + Wait for the single :class:`Future` or :ref:`coroutine object <coroutine>` + to complete with timeout. If *timeout* is ``None``, block until the future + completes. + + Coroutine will be wrapped in :class:`Task`. + + Returns result of the Future or coroutine. When a timeout occurs, it + cancels the task and raises :exc:`asyncio.TimeoutError`. To avoid the task + cancellation, wrap it in :func:`shield`. + + This function is a :ref:`coroutine <coroutine>`, usage:: + + result = yield from asyncio.wait_for(fut, 60.0) + diff --git a/Doc/library/asyncio.rst b/Doc/library/asyncio.rst index 1b8d701ccb30..690019859b08 100644 --- a/Doc/library/asyncio.rst +++ b/Doc/library/asyncio.rst @@ -4,6 +4,13 @@ .. module:: asyncio :synopsis: Asynchronous I/O, event loop, coroutines and tasks. +.. note:: + + The asyncio package has been included in the standard library on a + :term:`provisional basis <provisional package>`. Backwards incompatible + changes (up to and including removal of the module) may occur if deemed + necessary by the core developers. + .. versionadded:: 3.4 **Source code:** :source:`Lib/asyncio/` @@ -13,1289 +20,48 @@ This module provides infrastructure for writing single-threaded concurrent code using coroutines, multiplexing I/O access over sockets and other resources, running network clients and servers, and other related primitives. - Here is a more detailed list of the package contents: -* a pluggable :ref:`event loop <event-loop>` with various system-specific +* a pluggable :ref:`event loop <asyncio-event-loop>` with various system-specific implementations; -* :ref:`transport <transport>` and :ref:`protocol <protocol>` abstractions - (similar to those in `Twisted <http://twistedmatrix.com/>`_); +* :ref:`transport <asyncio-transport>` and :ref:`protocol <asyncio-protocol>` abstractions + (similar to those in `Twisted <https://twistedmatrix.com/trac/>`_); * concrete support for TCP, UDP, SSL, subprocess pipes, delayed calls, and others (some may be system-dependent); -* a Future class that mimicks the one in the :mod:`concurrent.futures` module, - but adapted for use with the event loop; +* a :class:`Future` class that mimics the one in the :mod:`concurrent.futures` + module, but adapted for use with the event loop; * coroutines and tasks based on ``yield from`` (:PEP:`380`), to help write concurrent code in a sequential fashion; -* cancellation support for Futures and coroutines; +* cancellation support for :class:`Future`\s and coroutines; -* :ref:`synchronization primitives <sync>` for use between coroutines in +* :ref:`synchronization primitives <asyncio-sync>` for use between coroutines in a single thread, mimicking those in the :mod:`threading` module; * an interface for passing work off to a threadpool, for times when you absolutely, positively have to use a library that makes blocking I/O calls. +Table of contents: -Disclaimer ----------- - -Full documentation is not yet ready; we hope to have it written -before Python 3.4 leaves beta. Until then, the best reference is -:PEP:`3156`. For a motivational primer on transports and protocols, -see :PEP:`3153`. - - -.. XXX should the asyncio documentation come in several pages, as for logging? - - -.. _event-loop: - -Event loops ------------ - -The event loop is the central execution device provided by :mod:`asyncio`. -It provides multiple facilities, amongst which: - -* Registering, executing and cancelling delayed calls (timeouts) - -* Creating client and server :ref:`transports <transport>` for various - kinds of communication - -* Launching subprocesses and the associated :ref:`transports <transport>` - for communication with an external program - -* Delegating costly function calls to a pool of threads - -Getting an event loop -^^^^^^^^^^^^^^^^^^^^^ - -The easiest way to get an event loop is to call the :func:`get_event_loop` -function. - -.. function:: get_event_loop() - - Get the event loop for current context. Returns an event loop object - implementing :class:`BaseEventLoop` interface, or raises an exception in case no - event loop has been set for the current context and the current policy does - not specify to create one. It should never return ``None``. - - -Run an event loop -^^^^^^^^^^^^^^^^^ - -.. method:: BaseEventLoop.run_forever() - - Run until :meth:`stop` is called. - -.. method:: BaseEventLoop.run_until_complete(future) - - Run until the :class:`Future` is done. - - If the argument is a coroutine, it is wrapped in a :class:`Task`. - - Return the Future's result, or raise its exception. - -.. method:: BaseEventLoop.is_running() - - Returns running status of event loop. - -.. method:: stop() - - Stop running the event loop. - - Every callback scheduled before :meth:`stop` is called will run. - Callback scheduled after :meth:`stop` is called won't. However, those - callbacks will run if :meth:`run_forever` is called again later. - -.. method:: BaseEventLoop.close() - - Close the event loop. - - This clears the queues and shuts down the executor, but does not wait for - the executor to finish. - - -Calls -^^^^^ - -.. method:: BaseEventLoop.call_soon(callback, \*args) - - Arrange for a callback to be called as soon as possible. - - This operates as a FIFO queue, callbacks are called in the order in - which they are registered. Each callback will be called exactly once. - - Any positional arguments after the callback will be passed to the - callback when it is called. - -.. method:: BaseEventLoop.call_soon_threadsafe(callback, \*args) - - Like :meth:`call_soon`, but thread safe. - - -Delayed calls -^^^^^^^^^^^^^ - -The event loop has its own internal clock for computing timeouts. -Which clock is used depends on the (platform-specific) event loop -implementation; ideally it is a monotonic clock. This will generally be -a different clock than :func:`time.time`. - -.. method:: BaseEventLoop.call_later(delay, callback, *args) - - Arrange for the *callback* to be called after the given *delay* - seconds (either an int or float). - - A "handle" is returned: an opaque object with a :meth:`cancel` method - that can be used to cancel the call. - - *callback* will be called exactly once per call to :meth:`call_later`. - If two callbacks are scheduled for exactly the same time, it is - undefined which will be called first. - - The optional positional *args* will be passed to the callback when it - is called. If you want the callback to be called with some named - arguments, use a closure or :func:`functools.partial`. - -.. method:: BaseEventLoop.call_at(when, callback, *args) - - Arrange for the *callback* to be called at the given absolute timestamp - *when* (an int or float), using the same time reference as :meth:`time`. - - This method's behavior is the same as :meth:`call_later`. - -.. method:: BaseEventLoop.time() - - Return the current time, as a :class:`float` value, according to the - event loop's internal clock. - - -Executor -^^^^^^^^ - -Call a function in an :class:`~concurrent.futures.Executor` (pool of threads or -pool of processes). By default, an event loop uses a thread pool executor -(:class:`~concurrent.futures.ThreadPoolExecutor`). - -.. method:: BaseEventLoop.run_in_executor(executor, callback, \*args) - - Arrange for a callback to be called in the specified executor. - - *executor* is a :class:`~concurrent.futures.Executor` instance, - the default executor is used if *executor* is ``None``. - -.. method:: BaseEventLoop.set_default_executor(executor) - - Set the default executor used by :meth:`run_in_executor`. - - -Creating listening connections -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. method:: BaseEventLoop.create_server(protocol_factory, host=None, port=None, \*, family=socket.AF_UNSPEC, flags=socket.AI_PASSIVE, sock=None, backlog=100, ssl=None, reuse_address=None) - - XXX - - * *protocol_factory* - * *host*, *port* - * *family* - * *flags* - * *sock* - * *backlog* : the maximum number of queued connections and should be at - least ``0``; the maximum value is system-dependent (usually ``5``), - the minimum value is forced to ``0``. - * *ssl*: ``True`` or :class:`ssl.SSLContext` - * *reuse_address*: if ``True``, set :data:`socket.SO_REUSEADDR` option - on the listening socket. Default value: ``True`` on POSIX systems, - ``False`` on Windows. - - This method returns a :ref:`coroutine <coroutine>`. - -.. method:: BaseEventLoop.create_datagram_endpoint(protocol_factory, local_addr=None, remote_addr=None, \*, family=0, proto=0, flags=0) - - XXX - - This method returns a :ref:`coroutine <coroutine>`. - - - -Creating connections -^^^^^^^^^^^^^^^^^^^^ - -.. method:: BaseEventLoop.create_connection(protocol_factory, host=None, port=None, **options) - - Create a streaming transport connection to a given Internet *host* and - *port*. *protocol_factory* must be a callable returning a - :ref:`protocol <protocol>` instance. - - This method returns a :ref:`coroutine <coroutine>` which will try to - establish the connection in the background. When successful, the - coroutine returns a ``(transport, protocol)`` pair. - - The chronological synopsis of the underlying operation is as follows: - - #. The connection is established, and a :ref:`transport <transport>` - is created to represent it. - - #. *protocol_factory* is called without arguments and must return a - :ref:`protocol <protocol>` instance. - - #. The protocol instance is tied to the transport, and its - :meth:`connection_made` method is called. - - #. The coroutine returns successfully with the ``(transport, protocol)`` - pair. - - The created transport is an implementation-dependent bidirectional stream. - - .. note:: - *protocol_factory* can be any kind of callable, not necessarily - a class. For example, if you want to use a pre-created - protocol instance, you can pass ``lambda: my_protocol``. - - *options* are optional named arguments allowing to change how the - connection is created: - - * *ssl*: if given and not false, a SSL/TLS transport is created - (by default a plain TCP transport is created). If *ssl* is - a :class:`ssl.SSLContext` object, this context is used to create - the transport; if *ssl* is :const:`True`, a context with some - unspecified default settings is used. - - * *server_hostname*, is only for use together with *ssl*, - and sets or overrides the hostname that the target server's certificate - will be matched against. By default the value of the *host* argument - is used. If *host* is empty, there is no default and you must pass a - value for *server_hostname*. If *server_hostname* is an empty - string, hostname matching is disabled (which is a serious security - risk, allowing for man-in-the-middle-attacks). - - * *family*, *proto*, *flags* are the optional address family, protocol - and flags to be passed through to getaddrinfo() for *host* resolution. - If given, these should all be integers from the corresponding - :mod:`socket` module constants. - - * *sock*, if given, should be an existing, already connected - :class:`socket.socket` object to be used by the transport. - If *sock* is given, none of *host*, *port*, *family*, *proto*, *flags* - and *local_addr* should be specified. - - * *local_addr*, if given, is a ``(local_host, local_port)`` tuple used - to bind the socket to locally. The *local_host* and *local_port* - are looked up using getaddrinfo(), similarly to *host* and *port*. - -.. method:: BaseEventLoop.connect_read_pipe(protocol_factory, pipe) - - XXX - - This method returns a :ref:`coroutine <coroutine>`. - -.. method:: BaseEventLoop.connect_write_pipe(protocol_factory, pipe) - - XXX - - This method returns a :ref:`coroutine <coroutine>`. - - -Resolve name -^^^^^^^^^^^^ - -.. method:: BaseEventLoop.getaddrinfo(host, port, \*, family=0, type=0, proto=0, flags=0) - - XXX - -.. method:: BaseEventLoop.getnameinfo(sockaddr, flags=0) - - XXX - - -Running subprocesses -^^^^^^^^^^^^^^^^^^^^ - -Run subprocesses asynchronously using the :mod:`subprocess` module. - -.. method:: BaseEventLoop.subprocess_shell(protocol_factory, cmd, \*, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=False, shell=True, bufsize=0, \*\*kwargs) - - XXX - - This method returns a :ref:`coroutine <coroutine>`. - - See the constructor of the :class:`subprocess.Popen` class for parameters. - -.. method:: BaseEventLoop.subprocess_exec(protocol_factory, \*args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=False, shell=False, bufsize=0, \*\*kwargs) - - XXX - - This method returns a :ref:`coroutine <coroutine>`. - - See the constructor of the :class:`subprocess.Popen` class for parameters. - - -.. _protocol: - -Protocols ---------- - -:mod:`asyncio` provides base classes that you can subclass to implement -your network protocols. Those classes are used in conjunction with -:ref:`transports <transport>` (see below): the protocol parses incoming -data and asks for the writing of outgoing data, while the transport is -responsible for the actual I/O and buffering. - -When subclassing a protocol class, it is recommended you override certain -methods. Those methods are callbacks: they will be called by the transport -on certain events (for example when some data is received); you shouldn't -call them yourself, unless you are implementing a transport. - -.. note:: - All callbacks have default implementations, which are empty. Therefore, - you only need to implement the callbacks for the events in which you - are interested. - - -Protocol classes -^^^^^^^^^^^^^^^^ - -.. class:: Protocol - - The base class for implementing streaming protocols (for use with - e.g. TCP and SSL transports). - -.. class:: DatagramProtocol - - The base class for implementing datagram protocols (for use with - e.g. UDP transports). - -.. class:: SubprocessProtocol - - The base class for implementing protocols communicating with child - processes (through a set of unidirectional pipes). - - -Connection callbacks -^^^^^^^^^^^^^^^^^^^^ - -These callbacks may be called on :class:`Protocol` and -:class:`SubprocessProtocol` instances: - -.. method:: BaseProtocol.connection_made(transport) - - Called when a connection is made. - - The *transport* argument is the transport representing the - connection. You are responsible for storing it somewhere - (e.g. as an attribute) if you need to. - -.. method:: BaseProtocol.connection_lost(exc) - - Called when the connection is lost or closed. - - The argument is either an exception object or :const:`None`. - The latter means a regular EOF is received, or the connection was - aborted or closed by this side of the connection. - -:meth:`connection_made` and :meth:`connection_lost` are called exactly once -per successful connection. All other callbacks will be called between those -two methods, which allows for easier resource management in your protocol -implementation. - -The following callbacks may be called only on :class:`SubprocessProtocol` -instances: - -.. method:: SubprocessProtocol.pipe_data_received(fd, data) - - Called when the child process writes data into its stdout or stderr pipe. - *fd* is the integer file descriptor of the pipe. *data* is a non-empty - bytes object containing the data. - -.. method:: SubprocessProtocol.pipe_connection_lost(fd, exc) - - Called when one of the pipes communicating with the child process - is closed. *fd* is the integer file descriptor that was closed. - -.. method:: SubprocessProtocol.process_exited() - - Called when the child process has exited. - - -Data reception callbacks -^^^^^^^^^^^^^^^^^^^^^^^^ - -Streaming protocols -""""""""""""""""""" - -The following callbacks are called on :class:`Protocol` instances: - -.. method:: Protocol.data_received(data) - - Called when some data is received. *data* is a non-empty bytes object - containing the incoming data. - - .. note:: - Whether the data is buffered, chunked or reassembled depends on - the transport. In general, you shouldn't rely on specific semantics - and instead make your parsing generic and flexible enough. However, - data is always received in the correct order. - -.. method:: Protocol.eof_received() - - Calls when the other end signals it won't send any more data - (for example by calling :meth:`write_eof`, if the other end also uses - asyncio). - - This method may return a false value (including None), in which case - the transport will close itself. Conversely, if this method returns a - true value, closing the transport is up to the protocol. Since the - default implementation returns None, it implicitly closes the connection. - - .. note:: - Some transports such as SSL don't support half-closed connections, - in which case returning true from this method will not prevent closing - the connection. - -:meth:`data_received` can be called an arbitrary number of times during -a connection. However, :meth:`eof_received` is called at most once -and, if called, :meth:`data_received` won't be called after it. - -Datagram protocols -"""""""""""""""""" - -The following callbacks are called on :class:`DatagramProtocol` instances. - -.. method:: DatagramProtocol.datagram_received(data, addr) - - Called when a datagram is received. *data* is a bytes object containing - the incoming data. *addr* is the address of the peer sending the data; - the exact format depends on the transport. - -.. method:: DatagramProtocol.error_received(exc) - - Called when a previous send or receive operation raises an - :class:`OSError`. *exc* is the :class:`OSError` instance. - - This method is called in rare conditions, when the transport (e.g. UDP) - detects that a datagram couldn't be delivered to its recipient. - In many conditions though, undeliverable datagrams will be silently - dropped. - - -Flow control callbacks -^^^^^^^^^^^^^^^^^^^^^^ - -These callbacks may be called on :class:`Protocol` and -:class:`SubprocessProtocol` instances: - -.. method:: BaseProtocol.pause_writing() - - Called when the transport's buffer goes over the high-water mark. - -.. method:: BaseProtocol.resume_writing() - - Called when the transport's buffer drains below the low-water mark. - - -:meth:`pause_writing` and :meth:`resume_writing` calls are paired -- -:meth:`pause_writing` is called once when the buffer goes strictly over -the high-water mark (even if subsequent writes increases the buffer size -even more), and eventually :meth:`resume_writing` is called once when the -buffer size reaches the low-water mark. - -.. note:: - If the buffer size equals the high-water mark, - :meth:`pause_writing` is not called -- it must go strictly over. - Conversely, :meth:`resume_writing` is called when the buffer size is - equal or lower than the low-water mark. These end conditions - are important to ensure that things go as expected when either - mark is zero. - - -.. _transport: - -Transports ----------- - -Transports are classed provided by :mod:`asyncio` in order to abstract -various kinds of communication channels. You generally won't instantiate -a transport yourself; instead, you will call a :class:`BaseEventLoop` method -which will create the transport and try to initiate the underlying -communication channel, calling you back when it succeeds. - -Once the communication channel is established, a transport is always -paired with a :ref:`protocol <protocol>` instance. The protocol can -then call the transport's methods for various purposes. - -:mod:`asyncio` currently implements transports for TCP, UDP, SSL, and -subprocess pipes. The methods available on a transport depend on -the transport's kind. - -Methods common to all transports -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. method:: BaseTransport.close(self) - - Close the transport. If the transport has a buffer for outgoing - data, buffered data will be flushed asynchronously. No more data - will be received. After all buffered data is flushed, the - protocol's :meth:`connection_lost` method will be called with - :const:`None` as its argument. - - -.. method:: BaseTransport.get_extra_info(name, default=None) - - Return optional transport information. *name* is a string representing - the piece of transport-specific information to get, *default* is the - value to return if the information doesn't exist. - - This method allows transport implementations to easily expose - channel-specific information. - -Methods of readable streaming transports -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. method:: ReadTransport.pause_reading() - - Pause the receiving end of the transport. No data will be passed to - the protocol's :meth:`data_received` method until meth:`resume_reading` - is called. - -.. method:: ReadTransport.resume_reading() - - Resume the receiving end. The protocol's :meth:`data_received` method - will be called once again if some data is available for reading. - -Methods of writable streaming transports -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. method:: WriteTransport.write(data) - - Write some *data* bytes to the transport. - - This method does not block; it buffers the data and arranges for it - to be sent out asynchronously. - -.. method:: WriteTransport.writelines(list_of_data) - - Write a list (or any iterable) of data bytes to the transport. - This is functionally equivalent to calling :meth:`write` on each - element yielded by the iterable, but may be implemented more efficiently. - -.. method:: WriteTransport.write_eof() - - Close the write end of the transport after flushing buffered data. - Data may still be received. - - This method can raise :exc:`NotImplementedError` if the transport - (e.g. SSL) doesn't support half-closes. - -.. method:: WriteTransport.can_write_eof() - - Return :const:`True` if the transport supports :meth:`write_eof`, - :const:`False` if not. - -.. method:: WriteTransport.abort() - - Close the transport immediately, without waiting for pending operations - to complete. Buffered data will be lost. No more data will be received. - The protocol's :meth:`connection_lost` method will eventually be - called with :const:`None` as its argument. - -.. method:: WriteTransport.set_write_buffer_limits(high=None, low=None) - - Set the *high*- and *low*-water limits for write flow control. - - These two values control when call the protocol's - :meth:`pause_writing` and :meth:`resume_writing` methods are called. - If specified, the low-water limit must be less than or equal to the - high-water limit. Neither *high* nor *low* can be negative. - - The defaults are implementation-specific. If only the - high-water limit is given, the low-water limit defaults to a - implementation-specific value less than or equal to the - high-water limit. Setting *high* to zero forces *low* to zero as - well, and causes :meth:`pause_writing` to be called whenever the - buffer becomes non-empty. Setting *low* to zero causes - :meth:`resume_writing` to be called only once the buffer is empty. - Use of zero for either limit is generally sub-optimal as it - reduces opportunities for doing I/O and computation - concurrently. - -.. method:: WriteTransport.get_write_buffer_size() - - Return the current size of the output buffer used by the transport. - -Methods of datagram transports -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. method:: DatagramTransport.sendto(data, addr=None) - - Send the *data* bytes to the remote peer given by *addr* (a - transport-dependent target address). If *addr* is :const:`None`, the - data is sent to the target address given on transport creation. - - This method does not block; it buffers the data and arranges for it - to be sent out asynchronously. - -.. method:: DatagramTransport.abort() - - Close the transport immediately, without waiting for pending operations - to complete. Buffered data will be lost. No more data will be received. - The protocol's :meth:`connection_lost` method will eventually be - called with :const:`None` as its argument. - -Methods of subprocess transports -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. method:: BaseSubprocessTransport.get_pid() - - Return the subprocess process id as an integer. - -.. method:: BaseSubprocessTransport.get_returncode() - - Return the subprocess returncode as an integer or :const:`None` - if it hasn't returned, similarly to the - :attr:`subprocess.Popen.returncode` attribute. - -.. method:: BaseSubprocessTransport.get_pipe_transport(fd) - - Return the transport for the communication pipe correspondong to the - integer file descriptor *fd*. The return value can be a readable or - writable streaming transport, depending on the *fd*. If *fd* doesn't - correspond to a pipe belonging to this transport, :const:`None` is - returned. - -.. method:: BaseSubprocessTransport.send_signal(signal) - - Send the *signal* number to the subprocess, as in - :meth:`subprocess.Popen.send_signal`. - -.. method:: BaseSubprocessTransport.terminate() - - Ask the subprocess to stop, as in :meth:`subprocess.Popen.terminate`. - This method is an alias for the :meth:`close` method. - - On POSIX systems, this method sends SIGTERM to the subprocess. - On Windows, the Windows API function TerminateProcess() is called to - stop the subprocess. - -.. method:: BaseSubprocessTransport.kill(self) - - Kill the subprocess, as in :meth:`subprocess.Popen.kill` - - On POSIX systems, the function sends SIGKILL to the subprocess. - On Windows, this method is an alias for :meth:`terminate`. - - -Task functions --------------- - -.. function:: as_completed(fs, *, loop=None, timeout=None) - - Return an iterator whose values, when waited for, are - :class:`~concurrent.futures.Future` instances. - - Raises :exc:`TimeoutError` if the timeout occurs before all Futures are done. - - Example:: - - for f in as_completed(fs): - result = yield from f # The 'yield from' may raise - # Use result - - .. note:: - - The futures ``f`` are not necessarily members of fs. - -.. function:: async(coro_or_future, *, loop=None) - - Wrap a :ref:`coroutine <coroutine>` in a future. - - If the argument is a :class:`~concurrent.futures.Future`, it is returned - directly. - -.. function:: gather(*coros_or_futures, loop=None, return_exceptions=False) - - Return a future aggregating results from the given coroutines or futures. - - All futures must share the same event loop. If all the tasks are done - successfully, the returned future's result is the list of results (in the - order of the original sequence, not necessarily the order of results - arrival). If *result_exception* is True, exceptions in the tasks are - treated the same as successful results, and gathered in the result list; - otherwise, the first raised exception will be immediately propagated to the - returned future. - - Cancellation: if the outer Future is cancelled, all children (that have not - completed yet) are also cancelled. If any child is cancelled, this is - treated as if it raised :exc:`~concurrent.futures.CancelledError` -- the - outer Future is *not* cancelled in this case. (This is to prevent the - cancellation of one child to cause other children to be cancelled.) - -.. function:: iscoroutinefunction(func) - - Return ``True`` if *func* is a decorated coroutine function. - -.. function:: iscoroutine(obj) - - Return ``True`` if *obj* is a coroutine object. - -.. function:: sleep(delay, result=None, *, loop=None) - - Create a :ref:`coroutine <coroutine>` that completes after a given time - (in seconds). - -.. function:: shield(arg, *, loop=None) - - Wait for a future, shielding it from cancellation. - - The statement:: - - res = yield from shield(something()) - - is exactly equivalent to the statement:: - - res = yield from something() - - *except* that if the coroutine containing it is cancelled, the task running - in ``something()`` is not cancelled. From the point of view of - ``something()``, the cancellation did not happen. But its caller is still - cancelled, so the yield-from expression still raises - :exc:`~concurrent.futures.CancelledError`. Note: If ``something()`` is - cancelled by other means this will still cancel ``shield()``. - - If you want to completely ignore cancellation (not recommended) you can - combine ``shield()`` with a try/except clause, as follows:: - - try: - res = yield from shield(something()) - except CancelledError: - res = None - - -Task ----- - -.. class:: Task(coro, *, loop=None) - - A coroutine wrapped in a :class:`~concurrent.futures.Future`. - - .. classmethod:: all_tasks(loop=None) - - Return a set of all tasks for an event loop. - - By default all tasks for the current event loop are returned. - - .. method:: cancel() - - Cancel the task. - - .. method:: get_stack(self, *, limit=None) - - Return the list of stack frames for this task's coroutine. - - If the coroutine is active, this returns the stack where it is suspended. - If the coroutine has completed successfully or was cancelled, this - returns an empty list. If the coroutine was terminated by an exception, - this returns the list of traceback frames. - - The frames are always ordered from oldest to newest. - - The optional limit gives the maximum nummber of frames to return; by - default all available frames are returned. Its meaning differs depending - on whether a stack or a traceback is returned: the newest frames of a - stack are returned, but the oldest frames of a traceback are returned. - (This matches the behavior of the traceback module.) - - For reasons beyond our control, only one stack frame is returned for a - suspended coroutine. - - .. method:: print_stack(*, limit=None, file=None) - - Print the stack or traceback for this task's coroutine. - - This produces output similar to that of the traceback module, for the - frames retrieved by get_stack(). The limit argument is passed to - get_stack(). The file argument is an I/O stream to which the output - goes; by default it goes to sys.stderr. - - -Protocols ---------- - -:mod:`asyncio` provides base classes that you can subclass to implement -your network protocols. Those classes are used in conjunction with -:ref:`transports <transport>` (see below): the protocol parses incoming -data and asks for the writing of outgoing data, while the transport is -responsible for the actual I/O and buffering. - -When subclassing a protocol class, it is recommended you override certain -methods. Those methods are callbacks: they will be called by the transport -on certain events (for example when some data is received); you shouldn't -call them yourself, unless you are implementing a transport. - -.. note:: - All callbacks have default implementations, which are empty. Therefore, - you only need to implement the callbacks for the events in which you - are interested. - - -.. _coroutine: - -Coroutines ----------- - -A coroutine is a generator that follows certain conventions. For -documentation purposes, all coroutines should be decorated with -``@asyncio.coroutine``, but this cannot be strictly enforced. - -Coroutines use the ``yield from`` syntax introduced in :pep:`380`, -instead of the original ``yield`` syntax. - -The word "coroutine", like the word "generator", is used for two -different (though related) concepts: - -- The function that defines a coroutine (a function definition - decorated with ``asyncio.coroutine``). If disambiguation is needed - we will call this a *coroutine function*. - -- The object obtained by calling a coroutine function. This object - represents a computation or an I/O operation (usually a combination) - that will complete eventually. If disambiguation is needed we will - call it a *coroutine object*. - -Things a coroutine can do: - -- ``result = yield from future`` -- suspends the coroutine until the - future is done, then returns the future's result, or raises an - exception, which will be propagated. (If the future is cancelled, - it will raise a ``CancelledError`` exception.) Note that tasks are - futures, and everything said about futures also applies to tasks. - -- ``result = yield from coroutine`` -- wait for another coroutine to - produce a result (or raise an exception, which will be propagated). - The ``coroutine`` expression must be a *call* to another coroutine. - -- ``return expression`` -- produce a result to the coroutine that is - waiting for this one using ``yield from``. - -- ``raise exception`` -- raise an exception in the coroutine that is - waiting for this one using ``yield from``. - -Calling a coroutine does not start its code running -- it is just a -generator, and the coroutine object returned by the call is really a -generator object, which doesn't do anything until you iterate over it. -In the case of a coroutine object, there are two basic ways to start -it running: call ``yield from coroutine`` from another coroutine -(assuming the other coroutine is already running!), or convert it to a -:class:`Task`. - -Coroutines (and tasks) can only run when the event loop is running. - - -.. _sync: - -Synchronization primitives --------------------------- - -.. class:: Lock(\*, loop=None) - - Primitive lock objects. - - A primitive lock is a synchronization primitive that is not owned by a - particular coroutine when locked. A primitive lock is in one of two states, - 'locked' or 'unlocked'. - - It is created in the unlocked state. It has two basic methods, :meth:`acquire` - and :meth:`release`. When the state is unlocked, acquire() changes the state to - locked and returns immediately. When the state is locked, acquire() blocks - until a call to release() in another coroutine changes it to unlocked, then - the acquire() call resets it to locked and returns. The release() method - should only be called in the locked state; it changes the state to unlocked - and returns immediately. If an attempt is made to release an unlocked lock, - a :exc:`RuntimeError` will be raised. - - When more than one coroutine is blocked in acquire() waiting for the state - to turn to unlocked, only one coroutine proceeds when a release() call - resets the state to unlocked; first coroutine which is blocked in acquire() - is being processed. - - :meth:`acquire` is a coroutine and should be called with ``yield from``. - - Locks also support the context manager protocol. ``(yield from lock)`` - should be used as context manager expression. - - Usage:: - - lock = Lock() - ... - yield from lock - try: - ... - finally: - lock.release() - - Context manager usage:: - - lock = Lock() - ... - with (yield from lock): - ... - - Lock objects can be tested for locking state:: - - if not lock.locked(): - yield from lock - else: - # lock is acquired - ... - - .. method:: locked() - - Return ``True`` if lock is acquired. - - .. method:: acquire() - - Acquire a lock. - - This method blocks until the lock is unlocked, then sets it to locked and - returns ``True``. - - This method returns a :ref:`coroutine <coroutine>`. - - .. method:: release() - - Release a lock. - - When the lock is locked, reset it to unlocked, and return. If any other - coroutines are blocked waiting for the lock to become unlocked, allow - exactly one of them to proceed. - - When invoked on an unlocked lock, a :exc:`RuntimeError` is raised. - - There is no return value. - - -.. class:: Event(\*, loop=None) - - An Event implementation, asynchronous equivalent to :class:`threading.Event`. - - Class implementing event objects. An event manages a flag that can be set to - true with the :meth:`set` method and reset to false with the :meth:`clear` - method. The :meth:`wait` method blocks until the flag is true. The flag is - initially false. - - .. method:: is_set() - - Return ``True`` if and only if the internal flag is true. - - .. method:: set() - - Set the internal flag to true. All coroutines waiting for it to become - true are awakened. Coroutine that call :meth:`wait` once the flag is true - will not block at all. - - .. method:: clear() - - Reset the internal flag to false. Subsequently, coroutines calling - :meth:`wait` will block until :meth:`set` is called to set the internal - flag to true again. - - .. method:: wait() - - Block until the internal flag is true. - - If the internal flag is true on entry, return ``True`` immediately. - Otherwise, block until another coroutine calls :meth:`set` to set the - flag to true, then return ``True``. - - This method returns a :ref:`coroutine <coroutine>`. - - -.. class:: Condition(\*, loop=None) - - A Condition implementation, asynchronous equivalent to - :class:`threading.Condition`. - - This class implements condition variable objects. A condition variable - allows one or more coroutines to wait until they are notified by another - coroutine. - - A new :class:`Lock` object is created and used as the underlying lock. - - .. method:: wait() - - Wait until notified. - - If the calling coroutine has not acquired the lock when this method is - called, a :exc:`RuntimeError` is raised. - - This method releases the underlying lock, and then blocks until it is - awakened by a :meth:`notify` or :meth:`notify_all` call for the same - condition variable in another coroutine. Once awakened, it re-acquires - the lock and returns ``True``. - - This method returns a :ref:`coroutine <coroutine>`. - - .. method:: wait_for(predicate) - - Wait until a predicate becomes true. - - The predicate should be a callable which result will be interpreted as a - boolean value. The final predicate value is the return value. - - This method returns a :ref:`coroutine <coroutine>`. - - .. method:: notify(n=1) - - By default, wake up one coroutine waiting on this condition, if any. - If the calling coroutine has not acquired the lock when this method is - called, a :exc:`RuntimeError` is raised. - - This method wakes up at most *n* of the coroutines waiting for the - condition variable; it is a no-op if no coroutines are waiting. - - .. note:: - - An awakened coroutine does not actually return from its :meth:`wait` - call until it can reacquire the lock. Since :meth:`notify` does not - release the lock, its caller should. - - .. method:: notify_all() - - Wake up all threads waiting on this condition. This method acts like - :meth:`notify`, but wakes up all waiting threads instead of one. If the - calling thread has not acquired the lock when this method is called, a - :exc:`RuntimeError` is raised. - - -.. class:: Semaphore(value=1, \*, loop=None) - - A Semaphore implementation. - - A semaphore manages an internal counter which is decremented by each - :meth:`acquire` call and incremented by each :meth:`release` call. The - counter can never go below zero; when :meth:`acquire` finds that it is zero, - it blocks, waiting until some other thread calls :meth:`release`. - - Semaphores also support the context manager protocol. - - The optional argument gives the initial value for the internal counter; it - defaults to ``1``. If the value given is less than ``0``, :exc:`ValueError` - is raised. - - .. method:: locked() - - Returns ``True`` if semaphore can not be acquired immediately. - - .. method:: acquire() - - Acquire a semaphore. - - If the internal counter is larger than zero on entry, decrement it by one - and return ``True`` immediately. If it is zero on entry, block, waiting - until some other coroutine has called :meth:`release` to make it larger - than ``0``, and then return ``True``. - - This method returns a :ref:`coroutine <coroutine>`. - - .. method:: release() - - Release a semaphore, incrementing the internal counter by one. When it - was zero on entry and another coroutine is waiting for it to become - larger than zero again, wake up that coroutine. - - -.. class:: BoundedSemaphore(value=1, \*, loop=None) - - A bounded semaphore implementation. Inherit from :class:`Semaphore`. - - This raises :exc:`ValueError` in :meth:`~Semaphore.release` if it would - increase the value above the initial value. - - -.. class:: Queue(maxsize=0, \*, loop=None) - - A queue, useful for coordinating producer and consumer coroutines. - - If *maxsize* is less than or equal to zero, the queue size is infinite. If - it is an integer greater than ``0``, then ``yield from put()`` will block - when the queue reaches *maxsize*, until an item is removed by :meth:`get`. - - Unlike the standard library :mod:`queue`, you can reliably know this Queue's - size with :meth:`qsize`, since your single-threaded Tulip application won't - be interrupted between calling :meth:`qsize` and doing an operation on the - Queue. - - .. method:: empty() - - Return ``True`` if the queue is empty, ``False`` otherwise. - - .. method:: full() - - Return ``True`` if there are maxsize items in the queue. - - .. note:: - - If the Queue was initialized with ``maxsize=0`` (the default), then - :meth:`full()` is never ``True``. - - .. method:: get() - - Remove and return an item from the queue. - - If you yield from :meth:`get()`, wait until a item is available. - - This method returns a :ref:`coroutine <coroutine>`. - - .. method:: get_nowait() - - Remove and return an item from the queue. - - Return an item if one is immediately available, else raise - :exc:`~queue.Empty`. - - .. method:: put(item) - - Put an item into the queue. - - If you yield from ``put()``, wait until a free slot is available before - adding item. - - This method returns a :ref:`coroutine <coroutine>`. - - .. method:: put_nowait(item) - - Put an item into the queue without blocking. - - If no free slot is immediately available, raise :exc:`~queue.Full`. - - .. method:: qsize() - - Number of items in the queue. - - .. attribute:: maxsize - - Number of items allowed in the queue. - -.. class:: PriorityQueue - - A subclass of :class:`Queue`; retrieves entries in priority order (lowest - first). - - Entries are typically tuples of the form: (priority number, data). - -.. class:: LifoQueue - - A subclass of :class:`Queue` that retrieves most recently added entries - first. - -.. class:: JoinableQueue - - A subclass of :class:`Queue` with :meth:`task_done` and :meth:`join` - methods. - - .. method:: task_done() - - Indicate that a formerly enqueued task is complete. - - Used by queue consumers. For each :meth:`~Queue.get` used to fetch a task, a - subsequent call to :meth:`task_done` tells the queue that the processing - on the task is complete. - - If a :meth:`join` is currently blocking, it will resume when all items - have been processed (meaning that a :meth:`task_done` call was received - for every item that had been :meth:`~Queue.put` into the queue). - - Raises :exc:`ValueError` if called more times than there were items - placed in the queue. - - .. method:: join() - - Block until all items in the queue have been gotten and processed. - - The count of unfinished tasks goes up whenever an item is added to the - queue. The count goes down whenever a consumer thread calls - :meth:`task_done` to indicate that the item was retrieved and all work on - it is complete. When the count of unfinished tasks drops to zero, - :meth:`join` unblocks. - - This method returns a :ref:`coroutine <coroutine>`. - - -Examples --------- - -Hello World (callback) -^^^^^^^^^^^^^^^^^^^^^^ - -Print ``Hello World`` every two seconds, using a callback:: - - import asyncio - - def print_and_repeat(loop): - print('Hello World') - loop.call_later(2, print_and_repeat, loop) - - loop = asyncio.get_event_loop() - print_and_repeat(loop) - loop.run_forever() - - -Hello World (callback) -^^^^^^^^^^^^^^^^^^^^^^ - -Print ``Hello World`` every two seconds, using a coroutine:: - - import asyncio - - @asyncio.coroutine - def greet_every_two_seconds(): - while True: - print('Hello World') - yield from asyncio.sleep(2) - - loop = asyncio.get_event_loop() - loop.run_until_complete(greet_every_two_seconds()) - - -Echo server -^^^^^^^^^^^ - -A :class:`Protocol` implementing an echo server:: - - class EchoServer(asyncio.Protocol): - - TIMEOUT = 5.0 - - def timeout(self): - print('connection timeout, closing.') - self.transport.close() - - def connection_made(self, transport): - print('connection made') - self.transport = transport - - # start 5 seconds timeout timer - self.h_timeout = asyncio.get_event_loop().call_later( - self.TIMEOUT, self.timeout) - - def data_received(self, data): - print('data received: ', data.decode()) - self.transport.write(b'Re: ' + data) +.. toctree:: + :maxdepth: 3 - # restart timeout timer - self.h_timeout.cancel() - self.h_timeout = asyncio.get_event_loop().call_later( - self.TIMEOUT, self.timeout) + asyncio-eventloop.rst + asyncio-eventloops.rst + asyncio-task.rst + asyncio-protocol.rst + asyncio-stream.rst + asyncio-subprocess.rst + asyncio-sync.rst + asyncio-dev.rst - def eof_received(self): - pass +.. seealso:: - def connection_lost(self, exc): - print('connection lost:', exc) - self.h_timeout.cancel() + The :mod:`asyncio` module was designed in :PEP:`3156`. For a + motivational primer on transports and protocols, see :PEP:`3153`. diff --git a/Doc/library/asyncore.rst b/Doc/library/asyncore.rst index 61079c5b34c0..917d0448c2f0 100644 --- a/Doc/library/asyncore.rst +++ b/Doc/library/asyncore.rst @@ -213,7 +213,12 @@ any that have been added to the map during asynchronous service) is closed. .. method:: recv(buffer_size) Read at most *buffer_size* bytes from the socket's remote end-point. An - empty string implies that the channel has been closed from the other end. + empty bytes object implies that the channel has been closed from the + other end. + + Note that :meth:`recv` may raise :exc:`BlockingIOError` , even though + :func:`select.select` or :func:`select.poll` has reported the socket + ready for reading. .. method:: listen(backlog) diff --git a/Doc/library/audioop.rst b/Doc/library/audioop.rst index fbb7fc629442..ce127aa06a61 100644 --- a/Doc/library/audioop.rst +++ b/Doc/library/audioop.rst @@ -12,10 +12,8 @@ integers, unless specified otherwise. .. versionchanged:: 3.4 Support for 24-bit samples was added. - -.. versionchanged:: 3.4 - Any :term:`bytes-like object`\ s are now accepted by all functions in this - module. Strings no more supported. + All functions now accept any :term:`bytes-like object`. + String input now results in an immediate error. .. index:: single: Intel/DVI ADPCM @@ -82,7 +80,7 @@ The module defines the following variables and functions: "Byteswap" all samples in a fragment and returns the modified fragment. Converts big-endian samples to little-endian and vice versa. - .. versionadded: 3.4 + .. versionadded:: 3.4 .. function:: cross(fragment, width) diff --git a/Doc/library/base64.rst b/Doc/library/base64.rst index a7eed0899b8c..3d23dfc765df 100644 --- a/Doc/library/base64.rst +++ b/Doc/library/base64.rst @@ -1,27 +1,33 @@ -:mod:`base64` --- RFC 3548: Base16, Base32, Base64 Data Encodings -================================================================= +:mod:`base64` --- Base16, Base32, Base64, Base85 Data Encodings +=============================================================== .. module:: base64 - :synopsis: RFC 3548: Base16, Base32, Base64 Data Encodings + :synopsis: RFC 3548: Base16, Base32, Base64 Data Encodings; + Base85 and Ascii85 .. index:: pair: base64; encoding single: MIME; base64 encoding -This module provides data encoding and decoding as specified in :rfc:`3548`. -This standard defines the Base16, Base32, and Base64 algorithms for encoding -and decoding arbitrary binary strings into ASCII-only byte strings that can be +This module provides functions for encoding binary data to printable +ASCII characters and decoding such encodings back to binary data. +It provides encoding and decoding functions for the encodings specified in +:rfc:`3548`, which defines the Base16, Base32, and Base64 algorithms, +and for the de-facto standard Ascii85 and Base85 encodings. + +The :rfc:`3548` encodings are suitable for encoding binary data so that it can safely sent by email, used as parts of URLs, or included as part of an HTTP POST request. The encoding algorithm is not the same as the :program:`uuencode` program. -There are two interfaces provided by this module. The modern interface -supports encoding and decoding ASCII byte string objects using all three -alphabets. Additionally, the decoding functions of the modern interface also -accept Unicode strings containing only ASCII characters. The legacy interface -provides for encoding and decoding to and from file-like objects as well as -byte strings, but only using the Base64 standard alphabet. +There are two :rfc:`3548` interfaces provided by this module. The modern +interface supports encoding and decoding ASCII byte string objects using all +three :rfc:`3548` defined alphabets (normal, URL-safe, and filesystem-safe). +Additionally, the decoding functions of the modern interface also accept +Unicode strings containing only ASCII characters. The legacy interface provides +for encoding and decoding to and from file-like objects as well as byte +strings, but only using the Base64 standard alphabet. .. versionchanged:: 3.3 ASCII-only Unicode strings are now accepted by the decoding functions of @@ -29,7 +35,7 @@ byte strings, but only using the Base64 standard alphabet. .. versionchanged:: 3.4 Any :term:`bytes-like object`\ s are now accepted by all - encoding and decoding functions in this module. + encoding and decoding functions in this module. Ascii85/Base85 support added. The modern interface provides: @@ -107,7 +113,7 @@ The modern interface provides: digit 0 is always mapped to the letter O). For security purposes the default is ``None``, so that 0 and 1 are not allowed in the input. - The decoded byte string is returned. A :exc:`binascii.Error` is raised if *s* were + The decoded byte string is returned. A :exc:`binascii.Error` is raised if *s* is incorrectly padded or if there are non-alphabet characters present in the string. diff --git a/Doc/library/binascii.rst b/Doc/library/binascii.rst index c92a8e160a97..3f7df74de98a 100644 --- a/Doc/library/binascii.rst +++ b/Doc/library/binascii.rst @@ -65,9 +65,6 @@ The :mod:`binascii` module defines the following functions: data. More than one line may be passed at a time. If the optional argument *header* is present and true, underscores will be decoded as spaces. - .. versionchanged:: 3.2 - Accept only bytestring or bytearray objects as input. - .. function:: b2a_qp(data, quotetabs=False, istext=True, header=False) @@ -156,9 +153,6 @@ The :mod:`binascii` module defines the following functions: of hexadecimal digits (which can be upper or lower case), otherwise a :exc:`TypeError` is raised. - .. versionchanged:: 3.2 - Accept only bytestring or bytearray objects as input. - .. exception:: Error diff --git a/Doc/library/bz2.rst b/Doc/library/bz2.rst index 9027a3554e83..488cda596855 100644 --- a/Doc/library/bz2.rst +++ b/Doc/library/bz2.rst @@ -95,6 +95,11 @@ All of the classes in this module may safely be accessed from multiple threads. byte of data will be returned (unless at EOF). The exact number of bytes returned is unspecified. + .. note:: While calling :meth:`peek` does not change the file position of + the :class:`BZ2File`, it may change the position of the underlying file + object (e.g. if the :class:`BZ2File` was constructed by passing a file + object for *filename*). + .. versionadded:: 3.3 .. versionchanged:: 3.1 diff --git a/Doc/library/cgi.rst b/Doc/library/cgi.rst index c4e7c60539b2..0a9e88428026 100644 --- a/Doc/library/cgi.rst +++ b/Doc/library/cgi.rst @@ -142,9 +142,11 @@ If a field represents an uploaded file, accessing the value via the method reads the entire file in memory as bytes. This may not be what you want. You can test for an uploaded file by testing either the :attr:`~FieldStorage.filename` attribute or the :attr:`~FieldStorage.file` -attribute. You can then read the data at leisure from the :attr:`!file` -attribute (the :func:`~io.RawIOBase.read` and :func:`~io.IOBase.readline` -methods will return bytes):: +attribute. You can then read the data from the :attr:`!file` +attribute before it is automatically closed as part of the garbage collection of +the :class:`FieldStorage` instance +(the :func:`~io.RawIOBase.read` and :func:`~io.IOBase.readline` methods will +return bytes):: fileitem = form["userfile"] if fileitem.file: @@ -155,6 +157,9 @@ methods will return bytes):: if not line: break linecount = linecount + 1 +:class:`FieldStorage` objects also support being used in a :keyword:`with` +statement, which will automatically close them when done. + If an error is encountered when obtaining the contents of an uploaded file (for example, when the user interrupts the form submission by clicking on a Back or Cancel button) the :attr:`~FieldStorage.done` attribute of the @@ -176,6 +181,15 @@ actually be instances of the class :class:`MiniFieldStorage`. In this case, the A form submitted via POST that also has a query string will contain both :class:`FieldStorage` and :class:`MiniFieldStorage` items. +.. versionchanged:: 3.4 + The :attr:`~FieldStorage.file` attribute is automatically closed upon the + garbage collection of the creating :class:`FieldStorage` instance. + +.. versionchanged:: 3.5 + Added support for the context management protocol to the + :class:`FieldStorage` class. + + Higher Level Interface ---------------------- diff --git a/Doc/library/chunk.rst b/Doc/library/chunk.rst index ae0a22156b43..50b6979f836c 100644 --- a/Doc/library/chunk.rst +++ b/Doc/library/chunk.rst @@ -113,15 +113,15 @@ instance will fail with a :exc:`EOFError` exception. Read at most *size* bytes from the chunk (less if the read hits the end of the chunk before obtaining *size* bytes). If the *size* argument is - negative or omitted, read all data until the end of the chunk. The bytes - are returned as a string object. An empty string is returned when the end - of the chunk is encountered immediately. + negative or omitted, read all data until the end of the chunk. An empty + bytes object is returned when the end of the chunk is encountered + immediately. .. method:: skip() Skip to the end of the chunk. All further calls to :meth:`read` for the - chunk will return ``''``. If you are not interested in the contents of + chunk will return ``b''``. If you are not interested in the contents of the chunk, this method should be called so that the file points to the start of the next chunk. diff --git a/Doc/library/cmath.rst b/Doc/library/cmath.rst index d7778df31730..a981d94a11bc 100644 --- a/Doc/library/cmath.rst +++ b/Doc/library/cmath.rst @@ -149,13 +149,13 @@ Hyperbolic functions .. function:: acosh(x) - Return the hyperbolic arc cosine of *x*. There is one branch cut, extending left - from 1 along the real axis to -∞, continuous from above. + Return the inverse hyperbolic cosine of *x*. There is one branch cut, + extending left from 1 along the real axis to -∞, continuous from above. .. function:: asinh(x) - Return the hyperbolic arc sine of *x*. There are two branch cuts: + Return the inverse hyperbolic sine of *x*. There are two branch cuts: One extends from ``1j`` along the imaginary axis to ``∞j``, continuous from the right. The other extends from ``-1j`` along the imaginary axis to ``-∞j``, continuous from the left. @@ -163,7 +163,7 @@ Hyperbolic functions .. function:: atanh(x) - Return the hyperbolic arc tangent of *x*. There are two branch cuts: One + Return the inverse hyperbolic tangent of *x*. There are two branch cuts: One extends from ``1`` along the real axis to ``∞``, continuous from below. The other extends from ``-1`` along the real axis to ``-∞``, continuous from above. diff --git a/Doc/library/cmd.rst b/Doc/library/cmd.rst index 97229280c31f..1ab2d7423fc4 100644 --- a/Doc/library/cmd.rst +++ b/Doc/library/cmd.rst @@ -148,8 +148,8 @@ A :class:`Cmd` instance has the following methods: Hook method executed once when :meth:`cmdloop` is about to return. This method is a stub in :class:`Cmd`; it exists to be overridden by subclasses. -Instances of :class:`Cmd` subclasses have some public instance variables: +Instances of :class:`Cmd` subclasses have some public instance variables: .. attribute:: Cmd.prompt @@ -166,6 +166,13 @@ Instances of :class:`Cmd` subclasses have some public instance variables: The last nonempty command prefix seen. +.. attribute:: Cmd.cmdqueue + + A list of queued input lines. The cmdqueue list is checked in + :meth:`cmdloop` when new input is needed; if it is nonempty, its elements + will be processed in order, as if entered at the prompt. + + .. attribute:: Cmd.intro A string to issue as an intro or banner. May be overridden by giving the @@ -252,7 +259,7 @@ immediate playback:: 'Move turtle to an absolute position with changing orientation. GOTO 100 200' goto(*parse(arg)) def do_home(self, arg): - 'Return turtle to the home postion: HOME' + 'Return turtle to the home position: HOME' home() def do_circle(self, arg): 'Draw circle with given radius an options extent and steps: CIRCLE 50' diff --git a/Doc/library/code.rst b/Doc/library/code.rst index 5b5d7cc8c1ad..275201c69b9b 100644 --- a/Doc/library/code.rst +++ b/Doc/library/code.rst @@ -4,6 +4,7 @@ .. module:: code :synopsis: Facilities to implement read-eval-print loops. +**Source code:** :source:`Lib/code.py` The ``code`` module provides facilities to implement read-eval-print loops in Python. Two classes and convenience functions are included which can be used to @@ -113,6 +114,9 @@ Interactive Interpreter Objects because it is within the interpreter object implementation. The output is written by the :meth:`write` method. + .. versionchanged:: 3.5 The full chained traceback is displayed instead + of just the primary traceback. + .. method:: InteractiveInterpreter.write(data) @@ -165,4 +169,3 @@ interpreter objects as well as the following additions. newline. When the user enters the EOF key sequence, :exc:`EOFError` is raised. The base implementation reads from ``sys.stdin``; a subclass may replace this with a different implementation. - diff --git a/Doc/library/codecs.rst b/Doc/library/codecs.rst index 843de27ae35b..048f0e9167e2 100644 --- a/Doc/library/codecs.rst +++ b/Doc/library/codecs.rst @@ -7,6 +7,7 @@ .. sectionauthor:: Marc-André Lemburg <mal@lemburg.com> .. sectionauthor:: Martin v. Löwis <martin@v.loewis.de> +**Source code:** :source:`Lib/codecs.py` .. index:: single: Unicode @@ -17,17 +18,24 @@ pair: stackable; streams This module defines base classes for standard Python codecs (encoders and -decoders) and provides access to the internal Python codec registry which -manages the codec and error handling lookup process. - -It defines the following functions: +decoders) and provides access to the internal Python codec registry, which +manages the codec and error handling lookup process. Most standard codecs +are :term:`text encodings <text encoding>`, which encode text to bytes, +but there are also codecs provided that encode text to text, and bytes to +bytes. Custom codecs may encode and decode between arbitrary types, but some +module features are restricted to use specifically with +:term:`text encodings <text encoding>`, or with codecs that encode to +:class:`bytes`. + +The module defines the following functions for encoding and decoding with +any codec: .. function:: encode(obj, encoding='utf-8', errors='strict') Encodes *obj* using the codec registered for *encoding*. *Errors* may be given to set the desired error handling scheme. The - default error handler is ``strict`` meaning that encoding errors raise + default error handler is ``'strict'`` meaning that encoding errors raise :exc:`ValueError` (or a more codec specific subclass, such as :exc:`UnicodeEncodeError`). Refer to :ref:`codec-base-classes` for more information on codec error handling. @@ -37,91 +45,63 @@ It defines the following functions: Decodes *obj* using the codec registered for *encoding*. *Errors* may be given to set the desired error handling scheme. The - default error handler is ``strict`` meaning that decoding errors raise + default error handler is ``'strict'`` meaning that decoding errors raise :exc:`ValueError` (or a more codec specific subclass, such as :exc:`UnicodeDecodeError`). Refer to :ref:`codec-base-classes` for more information on codec error handling. -.. function:: register(search_function) - - Register a codec search function. Search functions are expected to take one - argument, the encoding name in all lower case letters, and return a - :class:`CodecInfo` object having the following attributes: - - * ``name`` The name of the encoding; - - * ``encode`` The stateless encoding function; +The full details for each codec can also be looked up directly: - * ``decode`` The stateless decoding function; - - * ``incrementalencoder`` An incremental encoder class or factory function; - - * ``incrementaldecoder`` An incremental decoder class or factory function; - - * ``streamwriter`` A stream writer class or factory function; - - * ``streamreader`` A stream reader class or factory function. +.. function:: lookup(encoding) - The various functions or classes take the following arguments: + Looks up the codec info in the Python codec registry and returns a + :class:`CodecInfo` object as defined below. - *encode* and *decode*: These must be functions or methods which have the same - interface as the :meth:`~Codec.encode`/:meth:`~Codec.decode` methods of Codec - instances (see :ref:`Codec Interface <codec-objects>`). The functions/methods - are expected to work in a stateless mode. + Encodings are first looked up in the registry's cache. If not found, the list of + registered search functions is scanned. If no :class:`CodecInfo` object is + found, a :exc:`LookupError` is raised. Otherwise, the :class:`CodecInfo` object + is stored in the cache and returned to the caller. - *incrementalencoder* and *incrementaldecoder*: These have to be factory - functions providing the following interface: +.. class:: CodecInfo(encode, decode, streamreader=None, streamwriter=None, incrementalencoder=None, incrementaldecoder=None, name=None) - ``factory(errors='strict')`` + Codec details when looking up the codec registry. The constructor + arguments are stored in attributes of the same name: - The factory functions must return objects providing the interfaces defined by - the base classes :class:`IncrementalEncoder` and :class:`IncrementalDecoder`, - respectively. Incremental codecs can maintain state. - *streamreader* and *streamwriter*: These have to be factory functions providing - the following interface: + .. attribute:: name - ``factory(stream, errors='strict')`` + The name of the encoding. - The factory functions must return objects providing the interfaces defined by - the base classes :class:`StreamReader` and :class:`StreamWriter`, respectively. - Stream codecs can maintain state. - Possible values for errors are + .. attribute:: encode + decode - * ``'strict'``: raise an exception in case of an encoding error - * ``'replace'``: replace malformed data with a suitable replacement marker, - such as ``'?'`` or ``'\ufffd'`` - * ``'ignore'``: ignore malformed data and continue without further notice - * ``'xmlcharrefreplace'``: replace with the appropriate XML character - reference (for encoding only) - * ``'backslashreplace'``: replace with backslashed escape sequences (for - encoding only) - * ``'surrogateescape'``: on decoding, replace with code points in the Unicode - Private Use Area ranging from U+DC80 to U+DCFF. These private code - points will then be turned back into the same bytes when the - ``surrogateescape`` error handler is used when encoding the data. - (See :pep:`383` for more.) + The stateless encoding and decoding functions. These must be + functions or methods which have the same interface as + the :meth:`~Codec.encode` and :meth:`~Codec.decode` methods of Codec + instances (see :ref:`Codec Interface <codec-objects>`). + The functions or methods are expected to work in a stateless mode. - as well as any other error handling name defined via :func:`register_error`. - In case a search function cannot find a given encoding, it should return - ``None``. + .. attribute:: incrementalencoder + incrementaldecoder + Incremental encoder and decoder classes or factory functions. + These have to provide the interface defined by the base classes + :class:`IncrementalEncoder` and :class:`IncrementalDecoder`, + respectively. Incremental codecs can maintain state. -.. function:: lookup(encoding) - Looks up the codec info in the Python codec registry and returns a - :class:`CodecInfo` object as defined above. + .. attribute:: streamwriter + streamreader - Encodings are first looked up in the registry's cache. If not found, the list of - registered search functions is scanned. If no :class:`CodecInfo` object is - found, a :exc:`LookupError` is raised. Otherwise, the :class:`CodecInfo` object - is stored in the cache and returned to the caller. - -To simplify access to the various codecs, the module provides these additional -functions which use :func:`lookup` for the codec lookup: + Stream writer and reader classes or factory functions. These have to + provide the interface defined by the base classes + :class:`StreamWriter` and :class:`StreamReader`, respectively. + Stream codecs can maintain state. +To simplify access to the various codec components, the module provides +these additional functions which use :func:`lookup` for the codec lookup: .. function:: getencoder(encoding) @@ -170,90 +150,43 @@ functions which use :func:`lookup` for the codec lookup: Raises a :exc:`LookupError` in case the encoding cannot be found. +Custom codecs are made available by registering a suitable codec search +function: -.. function:: register_error(name, error_handler) - - Register the error handling function *error_handler* under the name *name*. - *error_handler* will be called during encoding and decoding in case of an error, - when *name* is specified as the errors parameter. - - For encoding *error_handler* will be called with a :exc:`UnicodeEncodeError` - instance, which contains information about the location of the error. The - error handler must either raise this or a different exception or return a - tuple with a replacement for the unencodable part of the input and a position - where encoding should continue. The replacement may be either :class:`str` or - :class:`bytes`. If the replacement is bytes, the encoder will simply copy - them into the output buffer. If the replacement is a string, the encoder will - encode the replacement. Encoding continues on original input at the - specified position. Negative position values will be treated as being - relative to the end of the input string. If the resulting position is out of - bound an :exc:`IndexError` will be raised. - - Decoding and translating works similar, except :exc:`UnicodeDecodeError` or - :exc:`UnicodeTranslateError` will be passed to the handler and that the - replacement from the error handler will be put into the output directly. - - -.. function:: lookup_error(name) - - Return the error handler previously registered under the name *name*. - - Raises a :exc:`LookupError` in case the handler cannot be found. - - -.. function:: strict_errors(exception) - - Implements the ``strict`` error handling: each encoding or decoding error - raises a :exc:`UnicodeError`. - - -.. function:: replace_errors(exception) - - Implements the ``replace`` error handling: malformed data is replaced with a - suitable replacement character such as ``'?'`` in bytestrings and - ``'\ufffd'`` in Unicode strings. - - -.. function:: ignore_errors(exception) - - Implements the ``ignore`` error handling: malformed data is ignored and - encoding or decoding is continued without further notice. - - -.. function:: xmlcharrefreplace_errors(exception) - - Implements the ``xmlcharrefreplace`` error handling (for encoding only): the - unencodable character is replaced by an appropriate XML character reference. - - -.. function:: backslashreplace_errors(exception) - - Implements the ``backslashreplace`` error handling (for encoding only): the - unencodable character is replaced by a backslashed escape sequence. +.. function:: register(search_function) -To simplify working with encoded files or stream, the module also defines these -utility functions: + Register a codec search function. Search functions are expected to take one + argument, being the encoding name in all lower case letters, and return a + :class:`CodecInfo` object. In case a search function cannot find + a given encoding, it should return ``None``. + .. note:: -.. function:: open(filename, mode[, encoding[, errors[, buffering]]]) + Search function registration is not currently reversible, + which may cause problems in some cases, such as unit testing or + module reloading. - Open an encoded file using the given *mode* and return a wrapped version - providing transparent encoding/decoding. The default file mode is ``'r'`` - meaning to open the file in read mode. +While the builtin :func:`open` and the associated :mod:`io` module are the +recommended approach for working with encoded text files, this module +provides additional utility functions and classes that allow the use of a +wider range of codecs when working with binary files: - .. note:: +.. function:: open(filename, mode='r', encoding=None, errors='strict', buffering=1) - The wrapped version's methods will accept and return strings only. Bytes - arguments will be rejected. + Open an encoded file using the given *mode* and return an instance of + :class:`StreamReaderWriter`, providing transparent encoding/decoding. + The default file mode is ``'r'``, meaning to open the file in read mode. .. note:: - Files are always opened in binary mode, even if no binary mode was - specified. This is done to avoid data loss due to encodings using 8-bit - values. This means that no automatic conversion of ``b'\n'`` is done - on reading and writing. + Underlying encoded files are always opened in binary mode. + No automatic conversion of ``'\n'`` is done on reading and writing. + The *mode* argument may be any binary mode acceptable to the built-in + :func:`open` function; the ``'b'`` is automatically added. *encoding* specifies the encoding which is to be used for the file. + Any encoding that encodes to and decodes from bytes is allowed, and + the data types supported by the file methods depend on the codec used. *errors* may be given to define the error handling. It defaults to ``'strict'`` which causes a :exc:`ValueError` to be raised in case an encoding error occurs. @@ -264,12 +197,15 @@ utility functions: .. function:: EncodedFile(file, data_encoding, file_encoding=None, errors='strict') - Return a wrapped version of file which provides transparent encoding - translation. + Return a :class:`StreamRecoder` instance, a wrapped version of *file* + which provides transparent transcoding. The original file is closed + when the wrapped version is closed. - Bytes written to the wrapped file are interpreted according to the given - *data_encoding* and then written to the original file as bytes using the - *file_encoding*. + Data written to the wrapped file is decoded according to the given + *data_encoding* and then written to the original file as bytes using + *file_encoding*. Bytes read from the original file are decoded + according to *file_encoding*, and the result is encoded + using *data_encoding*. If *file_encoding* is not given, it defaults to *data_encoding*. @@ -281,14 +217,16 @@ utility functions: .. function:: iterencode(iterator, encoding, errors='strict', **kwargs) Uses an incremental encoder to iteratively encode the input provided by - *iterator*. This function is a :term:`generator`. *errors* (as well as any + *iterator*. This function is a :term:`generator`. + The *errors* argument (as well as any other keyword argument) is passed through to the incremental encoder. .. function:: iterdecode(iterator, encoding, errors='strict', **kwargs) Uses an incremental decoder to iteratively decode the input provided by - *iterator*. This function is a :term:`generator`. *errors* (as well as any + *iterator*. This function is a :term:`generator`. + The *errors* argument (as well as any other keyword argument) is passed through to the incremental decoder. @@ -307,9 +245,10 @@ and writing to platform dependent files: BOM_UTF32_BE BOM_UTF32_LE - These constants define various encodings of the Unicode byte order mark (BOM) - used in UTF-16 and UTF-32 data streams to indicate the byte order used in the - stream or file and in UTF-8 as a Unicode signature. :const:`BOM_UTF16` is either + These constants define various byte sequences, + being Unicode byte order marks (BOMs) for several encodings. They are + used in UTF-16 and UTF-32 data streams to indicate the byte order used, + and in UTF-8 as a Unicode signature. :const:`BOM_UTF16` is either :const:`BOM_UTF16_BE` or :const:`BOM_UTF16_LE` depending on the platform's native byte order, :const:`BOM` is an alias for :const:`BOM_UTF16`, :const:`BOM_LE` for :const:`BOM_UTF16_LE` and :const:`BOM_BE` for @@ -323,20 +262,26 @@ Codec Base Classes ------------------ The :mod:`codecs` module defines a set of base classes which define the -interface and can also be used to easily write your own codecs for use in -Python. +interfaces for working with codec objects, and can also be used as the basis +for custom codec implementations. Each codec has to define four interfaces to make it usable as codec in Python: stateless encoder, stateless decoder, stream reader and stream writer. The stream reader and writers typically reuse the stateless encoder/decoder to -implement the file protocols. +implement the file protocols. Codec authors also need to define how the +codec will handle encoding and decoding errors. + -The :class:`Codec` class defines the interface for stateless encoders/decoders. +.. _surrogateescape: +.. _error-handlers: + +Error Handlers +^^^^^^^^^^^^^^ -To simplify and standardize error handling, the :meth:`~Codec.encode` and -:meth:`~Codec.decode` methods may implement different error handling schemes by -providing the *errors* string argument. The following string values are defined -and implemented by all standard Python codecs: +To simplify and standardize error handling, +codecs may implement different error handling schemes by +accepting the *errors* string argument. The following string values are +defined and implemented by all standard Python codecs: .. tabularcolumns:: |l|L| @@ -344,36 +289,56 @@ and implemented by all standard Python codecs: | Value | Meaning | +=========================+===============================================+ | ``'strict'`` | Raise :exc:`UnicodeError` (or a subclass); | -| | this is the default. | +| | this is the default. Implemented in | +| | :func:`strict_errors`. | +-------------------------+-----------------------------------------------+ -| ``'ignore'`` | Ignore the character and continue with the | -| | next. | +| ``'ignore'`` | Ignore the malformed data and continue | +| | without further notice. Implemented in | +| | :func:`ignore_errors`. | +-------------------------+-----------------------------------------------+ + +The following error handlers are only applicable to +:term:`text encodings <text encoding>`: + ++-------------------------+-----------------------------------------------+ +| Value | Meaning | ++=========================+===============================================+ | ``'replace'`` | Replace with a suitable replacement | -| | character; Python will use the official | -| | U+FFFD REPLACEMENT CHARACTER for the built-in | -| | Unicode codecs on decoding and '?' on | -| | encoding. | +| | marker; Python will use the official | +| | ``U+FFFD`` REPLACEMENT CHARACTER for the | +| | built-in codecs on decoding, and '?' on | +| | encoding. Implemented in | +| | :func:`replace_errors`. | +-------------------------+-----------------------------------------------+ | ``'xmlcharrefreplace'`` | Replace with the appropriate XML character | -| | reference (only for encoding). | +| | reference (only for encoding). Implemented | +| | in :func:`xmlcharrefreplace_errors`. | +-------------------------+-----------------------------------------------+ -| ``'backslashreplace'`` | Replace with backslashed escape sequences | -| | (only for encoding). | +| ``'backslashreplace'`` | Replace with backslashed escape sequences. | +| | Implemented in | +| | :func:`backslashreplace_errors`. | +-------------------------+-----------------------------------------------+ -| ``'surrogateescape'`` | Replace byte with surrogate U+DCxx, as defined| -| | in :pep:`383`. | +| ``'namereplace'`` | Replace with ``\N{...}`` escape sequences | +| | (only for encoding). Implemented in | +| | :func:`namereplace_errors`. | ++-------------------------+-----------------------------------------------+ +| ``'surrogateescape'`` | On decoding, replace byte with individual | +| | surrogate code ranging from ``U+DC80`` to | +| | ``U+DCFF``. This code will then be turned | +| | back into the same byte when the | +| | ``'surrogateescape'`` error handler is used | +| | when encoding the data. (See :pep:`383` for | +| | more.) | +-------------------------+-----------------------------------------------+ -In addition, the following error handlers are specific to Unicode encoding -schemes: +In addition, the following error handler is specific to the given codecs: +-------------------+------------------------+-------------------------------------------+ -| Value | Codec | Meaning | +| Value | Codecs | Meaning | +===================+========================+===========================================+ |``'surrogatepass'``| utf-8, utf-16, utf-32, | Allow encoding and decoding of surrogate | -| | utf-16-be, utf-16-le, | codes in all the Unicode encoding schemes.| -| | utf-32-be, utf-32-le | | +| | utf-16-be, utf-16-le, | codes. These codecs normally treat the | +| | utf-32-be, utf-32-le | presence of surrogates as an error. | +-------------------+------------------------+-------------------------------------------+ .. versionadded:: 3.1 @@ -382,26 +347,111 @@ schemes: .. versionchanged:: 3.4 The ``'surrogatepass'`` error handlers now works with utf-16\* and utf-32\* codecs. -The set of allowed values can be extended via :meth:`register_error`. +.. versionadded:: 3.5 + The ``'namereplace'`` error handler. + +.. versionchanged:: 3.5 + The ``'backslashreplace'`` error handlers now works with decoding and + translating. + +The set of allowed values can be extended by registering a new named error +handler: + +.. function:: register_error(name, error_handler) + + Register the error handling function *error_handler* under the name *name*. + The *error_handler* argument will be called during encoding and decoding + in case of an error, when *name* is specified as the errors parameter. + + For encoding, *error_handler* will be called with a :exc:`UnicodeEncodeError` + instance, which contains information about the location of the error. The + error handler must either raise this or a different exception, or return a + tuple with a replacement for the unencodable part of the input and a position + where encoding should continue. The replacement may be either :class:`str` or + :class:`bytes`. If the replacement is bytes, the encoder will simply copy + them into the output buffer. If the replacement is a string, the encoder will + encode the replacement. Encoding continues on original input at the + specified position. Negative position values will be treated as being + relative to the end of the input string. If the resulting position is out of + bound an :exc:`IndexError` will be raised. + + Decoding and translating works similarly, except :exc:`UnicodeDecodeError` or + :exc:`UnicodeTranslateError` will be passed to the handler and that the + replacement from the error handler will be put into the output directly. + + +Previously registered error handlers (including the standard error handlers) +can be looked up by name: + +.. function:: lookup_error(name) + + Return the error handler previously registered under the name *name*. + + Raises a :exc:`LookupError` in case the handler cannot be found. + +The following standard error handlers are also made available as module level +functions: + +.. function:: strict_errors(exception) + + Implements the ``'strict'`` error handling: each encoding or + decoding error raises a :exc:`UnicodeError`. + + +.. function:: replace_errors(exception) + + Implements the ``'replace'`` error handling (for :term:`text encodings + <text encoding>` only): substitutes ``'?'`` for encoding errors + (to be encoded by the codec), and ``'\ufffd'`` (the Unicode replacement + character, ``'�'``) for decoding errors. + + +.. function:: ignore_errors(exception) + + Implements the ``'ignore'`` error handling: malformed data is ignored and + encoding or decoding is continued without further notice. + + +.. function:: xmlcharrefreplace_errors(exception) + + Implements the ``'xmlcharrefreplace'`` error handling (for encoding with + :term:`text encodings <text encoding>` only): the + unencodable character is replaced by an appropriate XML character reference. + + +.. function:: backslashreplace_errors(exception) + + Implements the ``'backslashreplace'`` error handling (for + :term:`text encodings <text encoding>` only): malformed data is + replaced by a backslashed escape sequence. + +.. function:: namereplace_errors(exception) + + Implements the ``'namereplace'`` error handling (for encoding with + :term:`text encodings <text encoding>` only): the + unencodable character is replaced by a ``\N{...}`` escape sequence. + + .. versionadded:: 3.5 .. _codec-objects: -Codec Objects -^^^^^^^^^^^^^ +Stateless Encoding and Decoding +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The :class:`Codec` class defines these methods which also define the function -interfaces of the stateless encoder and decoder: +The base :class:`Codec` class defines these methods which also define the +function interfaces of the stateless encoder and decoder: .. method:: Codec.encode(input[, errors]) Encodes the object *input* and returns a tuple (output object, length consumed). - Encoding converts a string object to a bytes object using a particular + For instance, :term:`text encoding` converts + a string object to a bytes object using a particular character set encoding (e.g., ``cp1252`` or ``iso-8859-1``). - *errors* defines the error handling to apply. It defaults to ``'strict'`` - handling. + The *errors* argument defines the error handling to apply. + It defaults to ``'strict'`` handling. The method may not store state in the :class:`Codec` instance. Use :class:`StreamCodec` for codecs which have to keep state in order to make @@ -414,14 +464,16 @@ interfaces of the stateless encoder and decoder: .. method:: Codec.decode(input[, errors]) Decodes the object *input* and returns a tuple (output object, length - consumed). Decoding converts a bytes object encoded using a particular + consumed). For instance, for a :term:`text encoding`, decoding converts + a bytes object encoded using a particular character set encoding to a string object. - *input* must be a bytes object or one which provides the read-only character + For text encodings and bytes-to-bytes codecs, + *input* must be a bytes object or one which provides the read-only buffer interface -- for example, buffer objects and memory mapped files. - *errors* defines the error handling to apply. It defaults to ``'strict'`` - handling. + The *errors* argument defines the error handling to apply. + It defaults to ``'strict'`` handling. The method may not store state in the :class:`Codec` instance. Use :class:`StreamCodec` for codecs which have to keep state in order to make @@ -430,6 +482,10 @@ interfaces of the stateless encoder and decoder: The decoder must be able to handle zero length input and return an empty object of the output object type in this situation. + +Incremental Encoding and Decoding +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + The :class:`IncrementalEncoder` and :class:`IncrementalDecoder` classes provide the basic interface for incremental encoding and decoding. Encoding/decoding the input isn't done with one call to the stateless encoder/decoder function, but @@ -447,14 +503,14 @@ encoded/decoded with the stateless encoder/decoder. .. _incremental-encoder-objects: IncrementalEncoder Objects -^^^^^^^^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~~~~~~~~ The :class:`IncrementalEncoder` class is used for encoding an input in multiple steps. It defines the following methods which every incremental encoder must define in order to be compatible with the Python codec registry. -.. class:: IncrementalEncoder([errors]) +.. class:: IncrementalEncoder(errors='strict') Constructor for an :class:`IncrementalEncoder` instance. @@ -463,26 +519,14 @@ define in order to be compatible with the Python codec registry. the Python codec registry. The :class:`IncrementalEncoder` may implement different error handling schemes - by providing the *errors* keyword argument. These parameters are predefined: - - * ``'strict'`` Raise :exc:`ValueError` (or a subclass); this is the default. - - * ``'ignore'`` Ignore the character and continue with the next. - - * ``'replace'`` Replace with a suitable replacement character - - * ``'xmlcharrefreplace'`` Replace with the appropriate XML character reference - - * ``'backslashreplace'`` Replace with backslashed escape sequences. + by providing the *errors* keyword argument. See :ref:`error-handlers` for + possible values. The *errors* argument will be assigned to an attribute of the same name. Assigning to this attribute makes it possible to switch between different error handling strategies during the lifetime of the :class:`IncrementalEncoder` object. - The set of allowed values for the *errors* argument can be extended with - :func:`register_error`. - .. method:: encode(object[, final]) @@ -494,7 +538,8 @@ define in order to be compatible with the Python codec registry. .. method:: reset() Reset the encoder to the initial state. The output is discarded: call - ``.encode('', final=True)`` to reset the encoder and to get the output. + ``.encode(object, final=True)``, passing an empty byte or text string + if necessary, to reset the encoder and to get the output. .. method:: IncrementalEncoder.getstate() @@ -515,14 +560,14 @@ define in order to be compatible with the Python codec registry. .. _incremental-decoder-objects: IncrementalDecoder Objects -^^^^^^^^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~~~~~~~~ The :class:`IncrementalDecoder` class is used for decoding an input in multiple steps. It defines the following methods which every incremental decoder must define in order to be compatible with the Python codec registry. -.. class:: IncrementalDecoder([errors]) +.. class:: IncrementalDecoder(errors='strict') Constructor for an :class:`IncrementalDecoder` instance. @@ -531,22 +576,14 @@ define in order to be compatible with the Python codec registry. the Python codec registry. The :class:`IncrementalDecoder` may implement different error handling schemes - by providing the *errors* keyword argument. These parameters are predefined: - - * ``'strict'`` Raise :exc:`ValueError` (or a subclass); this is the default. - - * ``'ignore'`` Ignore the character and continue with the next. - - * ``'replace'`` Replace with a suitable replacement character. + by providing the *errors* keyword argument. See :ref:`error-handlers` for + possible values. The *errors* argument will be assigned to an attribute of the same name. Assigning to this attribute makes it possible to switch between different error handling strategies during the lifetime of the :class:`IncrementalDecoder` object. - The set of allowed values for the *errors* argument can be extended with - :func:`register_error`. - .. method:: decode(object[, final]) @@ -585,6 +622,10 @@ define in order to be compatible with the Python codec registry. returned by :meth:`getstate`. +Stream Encoding and Decoding +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + The :class:`StreamWriter` and :class:`StreamReader` classes provide generic working interfaces which can be used to implement new encoding submodules very easily. See :mod:`encodings.utf_8` for an example of how this is done. @@ -593,14 +634,14 @@ easily. See :mod:`encodings.utf_8` for an example of how this is done. .. _stream-writer-objects: StreamWriter Objects -^^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~~ The :class:`StreamWriter` class is a subclass of :class:`Codec` and defines the following methods which every stream writer must define in order to be compatible with the Python codec registry. -.. class:: StreamWriter(stream[, errors]) +.. class:: StreamWriter(stream, errors='strict') Constructor for a :class:`StreamWriter` instance. @@ -608,29 +649,17 @@ compatible with the Python codec registry. additional keyword arguments, but only the ones defined here are used by the Python codec registry. - *stream* must be a file-like object open for writing binary data. + The *stream* argument must be a file-like object open for writing + text or binary data, as appropriate for the specific codec. The :class:`StreamWriter` may implement different error handling schemes by - providing the *errors* keyword argument. These parameters are predefined: - - * ``'strict'`` Raise :exc:`ValueError` (or a subclass); this is the default. - - * ``'ignore'`` Ignore the character and continue with the next. - - * ``'replace'`` Replace with a suitable replacement character - - * ``'xmlcharrefreplace'`` Replace with the appropriate XML character reference - - * ``'backslashreplace'`` Replace with backslashed escape sequences. + providing the *errors* keyword argument. See :ref:`error-handlers` for + the standard error handlers the underlying stream codec may support. The *errors* argument will be assigned to an attribute of the same name. Assigning to this attribute makes it possible to switch between different error handling strategies during the lifetime of the :class:`StreamWriter` object. - The set of allowed values for the *errors* argument can be extended with - :func:`register_error`. - - .. method:: write(object) Writes the object's contents encoded to the stream. @@ -639,7 +668,8 @@ compatible with the Python codec registry. .. method:: writelines(list) Writes the concatenated list of strings to the stream (possibly by reusing - the :meth:`write` method). + the :meth:`write` method). The standard bytes-to-bytes codecs + do not support this method. .. method:: reset() @@ -658,14 +688,14 @@ all other methods and attributes from the underlying stream. .. _stream-reader-objects: StreamReader Objects -^^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~~ The :class:`StreamReader` class is a subclass of :class:`Codec` and defines the following methods which every stream reader must define in order to be compatible with the Python codec registry. -.. class:: StreamReader(stream[, errors]) +.. class:: StreamReader(stream, errors='strict') Constructor for a :class:`StreamReader` instance. @@ -673,16 +703,12 @@ compatible with the Python codec registry. additional keyword arguments, but only the ones defined here are used by the Python codec registry. - *stream* must be a file-like object open for reading (binary) data. + The *stream* argument must be a file-like object open for reading + text or binary data, as appropriate for the specific codec. The :class:`StreamReader` may implement different error handling schemes by - providing the *errors* keyword argument. These parameters are defined: - - * ``'strict'`` Raise :exc:`ValueError` (or a subclass); this is the default. - - * ``'ignore'`` Ignore the character and continue with the next. - - * ``'replace'`` Replace with a suitable replacement character. + providing the *errors* keyword argument. See :ref:`error-handlers` for + the standard error handlers the underlying stream codec may support. The *errors* argument will be assigned to an attribute of the same name. Assigning to this attribute makes it possible to switch between different error @@ -696,17 +722,20 @@ compatible with the Python codec registry. Decodes data from the stream and returns the resulting object. - *chars* indicates the number of characters to read from the - stream. :func:`read` will never return more than *chars* characters, but - it might return less, if there are not enough characters available. + The *chars* argument indicates the number of decoded + code points or bytes to return. The :func:`read` method will + never return more data than requested, but it might return less, + if there is not enough available. - *size* indicates the approximate maximum number of bytes to read from the - stream for decoding purposes. The decoder can modify this setting as + The *size* argument indicates the approximate maximum + number of encoded bytes or code points to read + for decoding. The decoder can modify this setting as appropriate. The default value -1 indicates to read and decode as much as - possible. *size* is intended to prevent having to decode huge files in - one step. + possible. This parameter is intended to + prevent having to decode huge files in one step. - *firstline* indicates that it would be sufficient to only return the first + The *firstline* flag indicates that + it would be sufficient to only return the first line, if there are decoding errors on later lines. The method should use a greedy read strategy meaning that it should read @@ -749,17 +778,13 @@ compatible with the Python codec registry. In addition to the above methods, the :class:`StreamReader` must also inherit all other methods and attributes from the underlying stream. -The next two base classes are included for convenience. They are not needed by -the codec registry, but may provide useful in practice. - - .. _stream-reader-writer: StreamReaderWriter Objects -^^^^^^^^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~~~~~~~~ -The :class:`StreamReaderWriter` allows wrapping streams which work in both read -and write modes. +The :class:`StreamReaderWriter` is a convenience class that allows wrapping +streams which work in both read and write modes. The design is such that one can use the factory functions returned by the :func:`lookup` function to construct the instance. @@ -780,9 +805,9 @@ methods and attributes from the underlying stream. .. _stream-recoder-objects: StreamRecoder Objects -^^^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~~~ -The :class:`StreamRecoder` provide a frontend - backend view of encoding data +The :class:`StreamRecoder` translates data from one encoding to another, which is sometimes useful when dealing with different encoding environments. The design is such that one can use the factory functions returned by the @@ -792,22 +817,20 @@ The design is such that one can use the factory functions returned by the .. class:: StreamRecoder(stream, encode, decode, Reader, Writer, errors) Creates a :class:`StreamRecoder` instance which implements a two-way conversion: - *encode* and *decode* work on the frontend (the input to :meth:`read` and output - of :meth:`write`) while *Reader* and *Writer* work on the backend (reading and - writing to the stream). + *encode* and *decode* work on the frontend — the data visible to + code calling :meth:`read` and :meth:`write`, while *Reader* and *Writer* + work on the backend — the data in *stream*. - You can use these objects to do transparent direct recodings from e.g. Latin-1 + You can use these objects to do transparent transcodings from e.g. Latin-1 to UTF-8 and back. - *stream* must be a file-like object. + The *stream* argument must be a file-like object. - *encode*, *decode* must adhere to the :class:`Codec` interface. *Reader*, + The *encode* and *decode* arguments must + adhere to the :class:`Codec` interface. *Reader* and *Writer* must be factory functions or classes providing objects of the :class:`StreamReader` and :class:`StreamWriter` interface respectively. - *encode* and *decode* are needed for the frontend translation, *Reader* and - *Writer* for the backend translation. - Error handling is done in the same way as defined for the stream readers and writers. @@ -822,31 +845,34 @@ methods and attributes from the underlying stream. Encodings and Unicode --------------------- -Strings are stored internally as sequences of codepoints in range ``0 - 10FFFF`` -(see :pep:`393` for more details about the implementation). -Once a string object is used outside of CPU and memory, CPU endianness -and how these arrays are stored as bytes become an issue. Transforming a -string object into a sequence of bytes is called encoding and recreating the -string object from the sequence of bytes is known as decoding. There are many -different methods for how this transformation can be done (these methods are -also called encodings). The simplest method is to map the codepoints 0-255 to -the bytes ``0x0``-``0xff``. This means that a string object that contains -codepoints above ``U+00FF`` can't be encoded with this method (which is called -``'latin-1'`` or ``'iso-8859-1'``). :func:`str.encode` will raise a -:exc:`UnicodeEncodeError` that looks like this: ``UnicodeEncodeError: 'latin-1' -codec can't encode character '\u1234' in position 3: ordinal not in -range(256)``. +Strings are stored internally as sequences of code points in +range ``0x0``-``0x10FFFF``. (See :pep:`393` for +more details about the implementation.) +Once a string object is used outside of CPU and memory, endianness +and how these arrays are stored as bytes become an issue. As with other +codecs, serialising a string into a sequence of bytes is known as *encoding*, +and recreating the string from the sequence of bytes is known as *decoding*. +There are a variety of different text serialisation codecs, which are +collectivity referred to as :term:`text encodings <text encoding>`. + +The simplest text encoding (called ``'latin-1'`` or ``'iso-8859-1'``) maps +the code points 0-255 to the bytes ``0x0``-``0xff``, which means that a string +object that contains code points above ``U+00FF`` can't be encoded with this +codec. Doing so will raise a :exc:`UnicodeEncodeError` that looks +like the following (although the details of the error message may differ): +``UnicodeEncodeError: 'latin-1' codec can't encode character '\u1234' in +position 3: ordinal not in range(256)``. There's another group of encodings (the so called charmap encodings) that choose -a different subset of all Unicode code points and how these codepoints are +a different subset of all Unicode code points and how these code points are mapped to the bytes ``0x0``-``0xff``. To see how this is done simply open e.g. :file:`encodings/cp1252.py` (which is an encoding that is used primarily on Windows). There's a string constant with 256 characters that shows you which character is mapped to which byte value. -All of these encodings can only encode 256 of the 1114112 codepoints +All of these encodings can only encode 256 of the 1114112 code points defined in Unicode. A simple and straightforward way that can store each Unicode -code point, is to store each codepoint as four consecutive bytes. There are two +code point, is to store each code point as four consecutive bytes. There are two possibilities: store the bytes in big endian or in little endian order. These two encodings are called ``UTF-32-BE`` and ``UTF-32-LE`` respectively. Their disadvantage is that if e.g. you use ``UTF-32-BE`` on a little endian machine you @@ -971,6 +997,10 @@ particular, the following variants typically exist: +-----------------+--------------------------------+--------------------------------+ | cp037 | IBM037, IBM039 | English | +-----------------+--------------------------------+--------------------------------+ +| cp273 | 273, IBM273, csIBM273 | German | +| | | | +| | | .. versionadded:: 3.4 | ++-----------------+--------------------------------+--------------------------------+ | cp424 | EBCDIC-CP-HE, IBM424 | Hebrew | +-----------------+--------------------------------+--------------------------------+ | cp437 | 437, IBM437 | English | @@ -1178,7 +1208,8 @@ particular, the following variants typically exist: .. versionchanged:: 3.4 The utf-16\* and utf-32\* encoders no longer allow surrogate code points - (U+D800--U+DFFF) to be encoded. The utf-32\* decoders no longer decode + (``U+D800``--``U+DFFF``) to be encoded. + The utf-32\* decoders no longer decode byte sequences that correspond to surrogate code points. @@ -1206,7 +1237,9 @@ encodings. +====================+=========+===========================+ | idna | | Implements :rfc:`3490`, | | | | see also | -| | | :mod:`encodings.idna` | +| | | :mod:`encodings.idna`. | +| | | Only ``errors='strict'`` | +| | | is supported. | +--------------------+---------+---------------------------+ | mbcs | dbcs | Windows only: Encode | | | | operand according to the | @@ -1214,31 +1247,44 @@ encodings. +--------------------+---------+---------------------------+ | palmos | | Encoding of PalmOS 3.5 | +--------------------+---------+---------------------------+ -| punycode | | Implements :rfc:`3492` | +| punycode | | Implements :rfc:`3492`. | +| | | Stateful codecs are not | +| | | supported. | +--------------------+---------+---------------------------+ -| raw_unicode_escape | | Produce a string that is | -| | | suitable as raw Unicode | -| | | literal in Python source | -| | | code | +| raw_unicode_escape | | Latin-1 encoding with | +| | | ``\uXXXX`` and | +| | | ``\UXXXXXXXX`` for other | +| | | code points. Existing | +| | | backslashes are not | +| | | escaped in any way. | +| | | It is used in the Python | +| | | pickle protocol. | +--------------------+---------+---------------------------+ | undefined | | Raise an exception for | -| | | all conversions. Can be | -| | | used as the system | -| | | encoding if no automatic | -| | | coercion between byte and | -| | | Unicode strings is | -| | | desired. | +| | | all conversions, even | +| | | empty strings. The error | +| | | handler is ignored. | +--------------------+---------+---------------------------+ -| unicode_escape | | Produce a string that is | -| | | suitable as Unicode | -| | | literal in Python source | -| | | code | +| unicode_escape | | Encoding suitable as the | +| | | contents of a Unicode | +| | | literal in ASCII-encoded | +| | | Python source code, | +| | | except that quotes are | +| | | not escaped. Decodes from | +| | | Latin-1 source code. | +| | | Beware that Python source | +| | | code actually uses UTF-8 | +| | | by default. | +--------------------+---------+---------------------------+ | unicode_internal | | Return the internal | | | | representation of the | -| | | operand | +| | | operand. Stateful codecs | +| | | are not supported. | | | | | | | | .. deprecated:: 3.3 | +| | | This representation is | +| | | obsoleted by | +| | | :pep:`393`. | +--------------------+---------+---------------------------+ .. _binary-transforms: @@ -1247,7 +1293,8 @@ Binary Transforms ^^^^^^^^^^^^^^^^^ The following codecs provide binary transforms: :term:`bytes-like object` -to :class:`bytes` mappings. +to :class:`bytes` mappings. They are not supported by :meth:`bytes.decode` +(which only produces :class:`str` output). .. tabularcolumns:: |l|L|L|L| @@ -1302,7 +1349,8 @@ Text Transforms ^^^^^^^^^^^^^^^ The following codec provides a text transform: a :class:`str` to :class:`str` -mapping. +mapping. It is not supported by :meth:`str.encode` (which only produces +:class:`bytes` output). .. tabularcolumns:: |l|l|L| @@ -1414,4 +1462,3 @@ This module implements a variant of the UTF-8 codec: On encoding a UTF-8 encoded BOM will be prepended to the UTF-8 encoded bytes. For the stateful encoder this is only done once (on the first write to the byte stream). For decoding an optional UTF-8 encoded BOM at the start of the data will be skipped. - diff --git a/Doc/library/collections.abc.rst b/Doc/library/collections.abc.rst index 356f47332f67..99c43113e3d0 100644 --- a/Doc/library/collections.abc.rst +++ b/Doc/library/collections.abc.rst @@ -134,7 +134,7 @@ particular functionality, for example:: Several of the ABCs are also useful as mixins that make it easier to develop classes supporting container APIs. For example, to write a class supporting -the full :class:`Set` API, it only necessary to supply the three underlying +the full :class:`Set` API, it is only necessary to supply the three underlying abstract methods: :meth:`__contains__`, :meth:`__iter__`, and :meth:`__len__`. The ABC supplies the remaining methods such as :meth:`__and__` and :meth:`isdisjoint`:: @@ -173,13 +173,13 @@ Notes on using :class:`Set` and :class:`MutableSet` as a mixin: (2) To override the comparisons (presumably for speed, as the - semantics are fixed), redefine :meth:`__le__` and + semantics are fixed), redefine :meth:`__le__` and :meth:`__ge__`, then the other operations will automatically follow suit. (3) The :class:`Set` mixin provides a :meth:`_hash` method to compute a hash value for the set; however, :meth:`__hash__` is not defined because not all sets - are hashable or immutable. To add set hashabilty using mixins, + are hashable or immutable. To add set hashability using mixins, inherit from both :meth:`Set` and :meth:`Hashable`, then define ``__hash__ = Set._hash``. diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst index 80c6c767c6da..c21f4563b17b 100644 --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -109,7 +109,7 @@ The class can be used to simulate nested scopes and is useful in templating. writing to any mapping in the chain. * Django's `Context class - <http://code.djangoproject.com/browser/django/trunk/django/template/context.py>`_ + <https://github.com/django/django/blob/master/django/template/context.py>`_ for templating is a read-only chain of mappings. It also features pushing and popping of contexts similar to the :meth:`~collections.ChainMap.new_child` method and the @@ -193,7 +193,7 @@ updates keys found deeper in the chain:: return raise KeyError(key) - >>> d = DeepChainMap({'zebra': 'black'}, {'elephant' : 'blue'}, {'lion' : 'yellow'}) + >>> d = DeepChainMap({'zebra': 'black'}, {'elephant': 'blue'}, {'lion': 'yellow'}) >>> d['lion'] = 'orange' # update an existing key two levels down >>> d['snake'] = 'red' # new keys get added to the topmost dict >>> del d['elephant'] # remove an existing key one level down @@ -908,13 +908,17 @@ customize a prototype instance: >>> janes_account = default_account._replace(owner='Jane') Enumerated constants can be implemented with named tuples, but it is simpler -and more efficient to use a simple class declaration: +and more efficient to use a simple :class:`~enum.Enum`: >>> Status = namedtuple('Status', 'open pending closed')._make(range(3)) >>> Status.open, Status.pending, Status.closed (0, 1, 2) - >>> class Status: - open, pending, closed = range(3) + >>> from enum import Enum + >>> class Status(Enum): + ... open, pending, closed = range(3) + + +.. seealso:: * `Recipe for named tuple abstract base class with a metaclass mix-in <http://code.activestate.com/recipes/577629-namedtupleabc-abstract-base-class-mix-in-for-named/>`_ @@ -978,12 +982,15 @@ 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 <view>` of :class:`OrderedDict` now + support reverse iteration using :func:`reversed`. :class:`OrderedDict` Examples and Recipes ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Since an ordered dictionary remembers its insertion order, it can be used -in conjuction with sorting to make a sorted dictionary:: +in conjunction with sorting to make a sorted dictionary:: >>> # regular unsorted dictionary >>> d = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2} @@ -1085,7 +1092,7 @@ to work with because the underlying list is accessible as an attribute. A real :class:`list` object used to store the contents of the :class:`UserList` class. -**Subclassing requirements:** Subclasses of :class:`UserList` are expect to +**Subclassing requirements:** Subclasses of :class:`UserList` are expected to offer a constructor which can be called with either no arguments or one argument. List operations which return a new sequence attempt to create an instance of the actual implementation class. To do so, it assumes that the diff --git a/Doc/library/compileall.rst b/Doc/library/compileall.rst index b12c2173c030..430362ebab35 100644 --- a/Doc/library/compileall.rst +++ b/Doc/library/compileall.rst @@ -4,6 +4,10 @@ .. module:: compileall :synopsis: Tools for byte-compiling all Python source files in a directory tree. +**Source code:** :source:`Lib/compileall.py` + +-------------- + This module provides some utility functions to support installing Python libraries. These functions compile Python source files in a directory tree. @@ -20,7 +24,8 @@ compile Python sources. .. program:: compileall -.. cmdoption:: [directory|file]... +.. cmdoption:: directory ... + file ... Positional arguments are files to compile or directories that contain source files, traversed recursively. If no argument is given, behave as if @@ -37,7 +42,8 @@ compile Python sources. .. cmdoption:: -q - Do not print the list of files compiled, print only error messages. + Do not print the list of files compiled. If passed once, error messages will + still be printed. If passed twice (``-qq``), all output is suppressed. .. cmdoption:: -d destdir @@ -65,9 +71,29 @@ compile Python sources. is to write files to their :pep:`3147` locations and names, which allows byte-code files from multiple versions of Python to coexist. +.. cmdoption:: -r + + Control the maximum recursion level for subdirectories. + If this is given, then ``-l`` option will not be taken into account. + :program:`python -m compileall <directory> -r 0` is equivalent to + :program:`python -m compileall <directory> -l`. + +.. cmdoption:: -j N + + Use *N* workers to compile the files within the given directory. + If ``0`` is used, then the result of :func:`os.cpu_count()` + will be used. + .. versionchanged:: 3.2 Added the ``-i``, ``-b`` and ``-h`` options. +.. versionchanged:: 3.5 + Added the ``-j`` and ``-r`` options. + +.. versionchanged:: 3.5 + ``-q`` option was changed to a multilevel value. + + There is no command-line option to control the optimization level used by the :func:`compile` function, because the Python interpreter itself already provides the option: :program:`python -O -m compileall`. @@ -75,7 +101,7 @@ provides the option: :program:`python -O -m compileall`. Public functions ---------------- -.. function:: compile_dir(dir, maxlevels=10, ddir=None, force=False, rx=None, quiet=False, legacy=False, optimize=-1) +.. function:: compile_dir(dir, maxlevels=10, ddir=None, force=False, rx=None, quiet=0, legacy=False, optimize=-1, workers=1) Recursively descend the directory tree named by *dir*, compiling all :file:`.py` files along the way. @@ -96,8 +122,9 @@ Public functions file considered for compilation, and if it returns a true value, the file is skipped. - If *quiet* is true, nothing is printed to the standard output unless errors - occur. + If *quiet* is ``False`` or ``0`` (the default), the filenames and other + information are printed to standard out. Set to ``1``, only errors are + printed. Set to ``2``, all output is suppressed. If *legacy* is true, byte-code files are written to their legacy locations and names, which may overwrite byte-code files created by another version of @@ -108,11 +135,22 @@ Public functions *optimize* specifies the optimization level for the compiler. It is passed to the built-in :func:`compile` function. + The argument *workers* specifies how many workers are used to + compile files in parallel. The default is to not use multiple workers. + If the platform can't use multiple workers and *workers* argument is given, + then a :exc:`NotImplementedError` will be raised. + If *workers* is lower than ``0``, a :exc:`ValueError` will be raised. + .. versionchanged:: 3.2 Added the *legacy* and *optimize* parameter. + .. versionchanged:: 3.5 + Added the *workers* parameter. + + .. versionchanged:: 3.5 + *quiet* parameter was changed to a multilevel value. -.. function:: compile_file(fullname, ddir=None, force=False, rx=None, quiet=False, legacy=False, optimize=-1) +.. function:: compile_file(fullname, ddir=None, force=False, rx=None, quiet=0, legacy=False, optimize=-1) Compile the file with path *fullname*. @@ -126,8 +164,9 @@ Public functions file being compiled, and if it returns a true value, the file is not compiled and ``True`` is returned. - If *quiet* is true, nothing is printed to the standard output unless errors - occur. + If *quiet* is ``False`` or ``0`` (the default), the filenames and other + information are printed to standard out. Set to ``1``, only errors are + printed. Set to ``2``, all output is suppressed. If *legacy* is true, byte-code files are written to their legacy locations and names, which may overwrite byte-code files created by another version of @@ -140,8 +179,10 @@ Public functions .. versionadded:: 3.2 + .. versionchanged:: 3.5 + *quiet* parameter was changed to a multilevel value. -.. function:: compile_path(skip_curdir=True, maxlevels=0, force=False, legacy=False, optimize=-1) +.. function:: compile_path(skip_curdir=True, maxlevels=0, force=False, quiet=0, legacy=False, optimize=-1) Byte-compile all the :file:`.py` files found along ``sys.path``. If *skip_curdir* is true (the default), the current directory is not included @@ -152,6 +193,8 @@ Public functions .. versionchanged:: 3.2 Added the *legacy* and *optimize* parameter. + .. versionchanged:: 3.5 + *quiet* parameter was changed to a multilevel value. To force a recompile of all the :file:`.py` files in the :file:`Lib/` subdirectory and all its subdirectories:: diff --git a/Doc/library/concurrent.futures.rst b/Doc/library/concurrent.futures.rst index 93538e4a7375..c1773408d924 100644 --- a/Doc/library/concurrent.futures.rst +++ b/Doc/library/concurrent.futures.rst @@ -38,7 +38,7 @@ Executor Objects future = executor.submit(pow, 323, 1235) print(future.result()) - .. method:: map(func, *iterables, timeout=None) + .. method:: map(func, *iterables, timeout=None, chunksize=1) Equivalent to :func:`map(func, *iterables) <map>` except *func* is executed asynchronously and several calls to *func* may be made concurrently. The @@ -48,7 +48,16 @@ Executor Objects *timeout* can be an int or a float. If *timeout* is not specified or ``None``, there is no limit to the wait time. If a call raises an exception, then that exception will be raised when its value is - retrieved from the iterator. + retrieved from the iterator. When using :class:`ProcessPoolExecutor`, this + method chops *iterables* into a number of chunks which it submits to the + pool as separate tasks. The (approximate) size of these chunks can be + specified by setting *chunksize* to a positive integer. For very long + iterables, using a large value for *chunksize* can significantly improve + performance compared to the default size of 1. With :class:`ThreadPoolExecutor`, + *chunksize* has no effect. + + .. versionchanged:: 3.5 + Added the *chunksize* argument. .. method:: shutdown(wait=True) @@ -115,11 +124,19 @@ And:: executor.submit(wait_on_future) -.. class:: ThreadPoolExecutor(max_workers) +.. class:: ThreadPoolExecutor(max_workers=None) An :class:`Executor` subclass that uses a pool of at most *max_workers* threads to execute calls asynchronously. + .. versionchanged:: 3.5 + If *max_workers* is ``None`` or + not given, it will default to the number of processors on the machine, + multiplied by ``5``, assuming that :class:`ThreadPoolExecutor` is often + used to overlap I/O instead of CPU work and the number of workers + should be higher than the number of workers + for :class:`ProcessPoolExecutor`. + .. _threadpoolexecutor-example: @@ -175,6 +192,8 @@ to a :class:`ProcessPoolExecutor` will result in deadlock. An :class:`Executor` subclass that executes calls asynchronously using a pool of at most *max_workers* processes. If *max_workers* is ``None`` or not given, it will default to the number of processors on the machine. + If *max_workers* is lower or equal to ``0``, then a :exc:`ValueError` + will be raised. .. versionchanged:: 3.3 When one of the worker processes terminates abruptly, a @@ -371,7 +390,8 @@ Module Functions Returns an iterator over the :class:`Future` instances (possibly created by different :class:`Executor` instances) given by *fs* that yields futures as - they complete (finished or were cancelled). Any futures that completed + they complete (finished or were cancelled). Any futures given by *fs* that + are duplicated will be returned once. Any futures that completed before :func:`as_completed` is called will be yielded first. The returned iterator raises a :exc:`TimeoutError` if :meth:`~iterator.__next__` is called and the result isn't available after *timeout* seconds from the @@ -390,6 +410,8 @@ Module Functions Exception classes ----------------- +.. currentmodule:: concurrent.futures.process + .. exception:: BrokenProcessPool Derived from :exc:`RuntimeError`, this exception class is raised when diff --git a/Doc/library/configparser.rst b/Doc/library/configparser.rst index 024d27cb84dd..c9187a3441a7 100644 --- a/Doc/library/configparser.rst +++ b/Doc/library/configparser.rst @@ -11,6 +11,8 @@ .. sectionauthor:: Christopher G. Petrilli <petrilli@amber.org> .. sectionauthor:: Åukasz Langa <lukasz@langa.pl> +**Source code:** :source:`Lib/configparser.py` + .. index:: pair: .ini; file pair: configuration; file @@ -142,12 +144,13 @@ datatypes, you should convert on your own: >>> float(topsecret['CompressionLevel']) 9.0 -Extracting Boolean values is not that simple, though. Passing the value -to ``bool()`` would do no good since ``bool('False')`` is still -``True``. This is why config parsers also provide :meth:`getboolean`. -This method is case-insensitive and recognizes Boolean values from -``'yes'``/``'no'``, ``'on'``/``'off'`` and ``'1'``/``'0'`` [1]_. -For example: +Since this task is so common, config parsers provide a range of handy getter +methods to handle integers, floats and booleans. The last one is the most +interesting because simply passing the value to ``bool()`` would do no good +since ``bool('False')`` is still ``True``. This is why config parsers also +provide :meth:`getboolean`. This method is case-insensitive and recognizes +Boolean values from ``'yes'``/``'no'``, ``'on'``/``'off'``, +``'true'``/``'false'`` and ``'1'``/``'0'`` [1]_. For example: .. doctest:: @@ -159,10 +162,8 @@ For example: True Apart from :meth:`getboolean`, config parsers also provide equivalent -:meth:`getint` and :meth:`getfloat` methods, but these are far less -useful since conversion using :func:`int` and :func:`float` is -sufficient for these types. - +:meth:`getint` and :meth:`getfloat` methods. You can register your own +converters and customize the provided ones. [1]_ Fallback Values --------------- @@ -317,11 +318,11 @@ from ``get()`` calls. .. class:: ExtendedInterpolation() An alternative handler for interpolation which implements a more advanced - syntax, used for instance in ``zc.buildout``. Extended interpolation is + syntax, used for instance in ``zc.buildout``. Extended interpolation is using ``${section:option}`` to denote a value from a foreign section. - Interpolation can span multiple levels. For convenience, if the ``section:`` - part is omitted, interpolation defaults to the current section (and possibly - the default values from the special section). + Interpolation can span multiple levels. For convenience, if the + ``section:`` part is omitted, interpolation defaults to the current section + (and possibly the default values from the special section). For example, the configuration specified above with basic interpolation, would look like this with extended interpolation: @@ -386,7 +387,7 @@ However, there are a few differences that should be taken into account: * All sections include ``DEFAULTSECT`` values as well which means that ``.clear()`` on a section may not leave the section visibly empty. This is because default values cannot be deleted from the section (because technically - they are not there). If they are overriden in the section, deleting causes + they are not there). If they are overridden in the section, deleting causes the default value to be visible again. Trying to delete a default value causes a ``KeyError``. @@ -399,13 +400,13 @@ However, there are a few differences that should be taken into account: * ``parser.popitem()`` never returns it. * ``parser.get(section, option, **kwargs)`` - the second argument is **not** - a fallback value. Note however that the section-level ``get()`` methods are + a fallback value. Note however that the section-level ``get()`` methods are compatible both with the mapping protocol and the classic configparser API. * ``parser.items()`` is compatible with the mapping protocol (returns a list of *section_name*, *section_proxy* pairs including the DEFAULTSECT). However, this method can also be invoked with arguments: ``parser.items(section, raw, - vars)``. The latter call returns a list of *option*, *value* pairs for + vars)``. The latter call returns a list of *option*, *value* pairs for a specified ``section``, with all interpolations expanded (unless ``raw=True`` is provided). @@ -539,9 +540,9 @@ the :meth:`__init__` options: * *delimiters*, default value: ``('=', ':')`` - Delimiters are substrings that delimit keys from values within a section. The - first occurrence of a delimiting substring on a line is considered a delimiter. - This means values (but not keys) can contain the delimiters. + Delimiters are substrings that delimit keys from values within a section. + The first occurrence of a delimiting substring on a line is considered + a delimiter. This means values (but not keys) can contain the delimiters. See also the *space_around_delimiters* argument to :meth:`ConfigParser.write`. @@ -553,7 +554,7 @@ the :meth:`__init__` options: Comment prefixes are strings that indicate the start of a valid comment within a config file. *comment_prefixes* are used only on otherwise empty lines (optionally indented) whereas *inline_comment_prefixes* can be used after - every valid value (e.g. section names, options and empty lines as well). By + every valid value (e.g. section names, options and empty lines as well). By default inline comments are disabled and ``'#'`` and ``';'`` are used as prefixes for whole line comments. @@ -563,10 +564,10 @@ the :meth:`__init__` options: Please note that config parsers don't support escaping of comment prefixes so using *inline_comment_prefixes* may prevent users from specifying option - values with characters used as comment prefixes. When in doubt, avoid setting - *inline_comment_prefixes*. In any circumstances, the only way of storing - comment prefix characters at the beginning of a line in multiline values is to - interpolate the prefix, for example:: + values with characters used as comment prefixes. When in doubt, avoid + setting *inline_comment_prefixes*. In any circumstances, the only way of + storing comment prefix characters at the beginning of a line in multiline + values is to interpolate the prefix, for example:: >>> from configparser import ConfigParser, ExtendedInterpolation >>> parser = ConfigParser(interpolation=ExtendedInterpolation()) @@ -611,7 +612,7 @@ the :meth:`__init__` options: When set to ``True``, the parser will not allow for any section or option duplicates while reading from a single source (using :meth:`read_file`, - :meth:`read_string` or :meth:`read_dict`). It is recommended to use strict + :meth:`read_string` or :meth:`read_dict`). It is recommended to use strict parsers in new applications. .. versionchanged:: 3.2 @@ -646,12 +647,12 @@ the :meth:`__init__` options: The convention of allowing a special section of default values for other sections or interpolation purposes is a powerful concept of this library, - letting users create complex declarative configurations. This section is + letting users create complex declarative configurations. This section is normally called ``"DEFAULT"`` but this can be customized to point to any - other valid section name. Some typical values include: ``"general"`` or - ``"common"``. The name provided is used for recognizing default sections when - reading from any source and is used when writing configuration back to - a file. Its current value can be retrieved using the + other valid section name. Some typical values include: ``"general"`` or + ``"common"``. The name provided is used for recognizing default sections + when reading from any source and is used when writing configuration back to + a file. Its current value can be retrieved using the ``parser_instance.default_section`` attribute and may be modified at runtime (i.e. to convert files from one format to another). @@ -660,14 +661,30 @@ the :meth:`__init__` options: Interpolation behaviour may be customized by providing a custom handler through the *interpolation* argument. ``None`` can be used to turn off interpolation completely, ``ExtendedInterpolation()`` provides a more - advanced variant inspired by ``zc.buildout``. More on the subject in the + advanced variant inspired by ``zc.buildout``. More on the subject in the `dedicated documentation section <#interpolation-of-values>`_. :class:`RawConfigParser` has a default value of ``None``. +* *converters*, default value: not set + + Config parsers provide option value getters that perform type conversion. By + default :meth:`getint`, :meth:`getfloat`, and :meth:`getboolean` are + implemented. Should other getters be desirable, users may define them in + a subclass or pass a dictionary where each key is a name of the converter and + each value is a callable implementing said conversion. For instance, passing + ``{'decimal': decimal.Decimal}`` would add :meth:`getdecimal` on both the + parser object and all section proxies. In other words, it will be possible + to write both ``parser_instance.getdecimal('section', 'key', fallback=0)`` + and ``parser_instance['section'].getdecimal('key', 0)``. + + If the converter needs to access the state of the parser, it can be + implemented as a method on a config parser subclass. If the name of this + method starts with ``get``, it will be available on all section proxies, in + the dict-compatible form (see the ``getdecimal()`` example above). More advanced customization may be achieved by overriding default values of -these parser attributes. The defaults are defined on the classes, so they -may be overriden by subclasses or by attribute assignment. +these parser attributes. The defaults are defined on the classes, so they may +be overridden by subclasses or by attribute assignment. .. attribute:: BOOLEAN_STATES @@ -725,10 +742,11 @@ may be overriden by subclasses or by attribute assignment. .. attribute:: SECTCRE - A compiled regular expression used to parse section headers. The default - matches ``[section]`` to the name ``"section"``. Whitespace is considered part - of the section name, thus ``[ larch ]`` will be read as a section of name - ``" larch "``. Override this attribute if that's unsuitable. For example: + A compiled regular expression used to parse section headers. The default + matches ``[section]`` to the name ``"section"``. Whitespace is considered + part of the section name, thus ``[ larch ]`` will be read as a section of + name ``" larch "``. Override this attribute if that's unsuitable. For + example: .. doctest:: @@ -859,7 +877,7 @@ interpolation if an option used is not defined elsewhere. :: ConfigParser Objects -------------------- -.. class:: ConfigParser(defaults=None, dict_type=collections.OrderedDict, allow_no_value=False, delimiters=('=', ':'), comment_prefixes=('#', ';'), inline_comment_prefixes=None, strict=True, empty_lines_in_values=True, default_section=configparser.DEFAULTSECT, interpolation=BasicInterpolation()) +.. class:: ConfigParser(defaults=None, dict_type=collections.OrderedDict, allow_no_value=False, delimiters=('=', ':'), comment_prefixes=('#', ';'), inline_comment_prefixes=None, strict=True, empty_lines_in_values=True, default_section=configparser.DEFAULTSECT, interpolation=BasicInterpolation(), converters={}) The main configuration parser. When *defaults* is given, it is initialized into the dictionary of intrinsic defaults. When *dict_type* is given, it @@ -869,8 +887,8 @@ ConfigParser Objects When *delimiters* is given, it is used as the set of substrings that divide keys from values. When *comment_prefixes* is given, it will be used as the set of substrings that prefix comments in otherwise empty lines. - Comments can be indented. When *inline_comment_prefixes* is given, it will be - used as the set of substrings that prefix comments in non-empty lines. + Comments can be indented. When *inline_comment_prefixes* is given, it will + be used as the set of substrings that prefix comments in non-empty lines. When *strict* is ``True`` (the default), the parser won't allow for any section or option duplicates while reading from a single source (file, @@ -884,13 +902,13 @@ ConfigParser Objects When *default_section* is given, it specifies the name for the special section holding default values for other sections and interpolation purposes - (normally named ``"DEFAULT"``). This value can be retrieved and changed on + (normally named ``"DEFAULT"``). This value can be retrieved and changed on runtime using the ``default_section`` instance attribute. Interpolation behaviour may be customized by providing a custom handler through the *interpolation* argument. ``None`` can be used to turn off interpolation completely, ``ExtendedInterpolation()`` provides a more - advanced variant inspired by ``zc.buildout``. More on the subject in the + advanced variant inspired by ``zc.buildout``. More on the subject in the `dedicated documentation section <#interpolation-of-values>`_. All option names used in interpolation will be passed through the @@ -899,6 +917,12 @@ ConfigParser Objects converts option names to lower case), the values ``foo %(bar)s`` and ``foo %(BAR)s`` are equivalent. + When *converters* is given, it should be a dictionary where each key + represents the name of a type converter and each value is a callable + implementing the conversion from string to the desired datatype. Every + converter gets its own corresponding :meth:`get*()` method on the parser + object and section proxies. + .. versionchanged:: 3.1 The default *dict_type* is :class:`collections.OrderedDict`. @@ -907,6 +931,9 @@ ConfigParser Objects *empty_lines_in_values*, *default_section* and *interpolation* were added. + .. versionchanged:: 3.5 + The *converters* argument was added. + .. method:: defaults() @@ -944,7 +971,7 @@ ConfigParser Objects .. method:: has_option(section, option) If the given *section* exists, and contains the given *option*, return - :const:`True`; otherwise return :const:`False`. If the specified + :const:`True`; otherwise return :const:`False`. If the specified *section* is :const:`None` or an empty string, DEFAULT is assumed. @@ -1069,7 +1096,7 @@ ConfigParser Objects :meth:`get` method. .. versionchanged:: 3.2 - Items present in *vars* no longer appear in the result. The previous + Items present in *vars* no longer appear in the result. The previous behaviour mixed actual parser options with variables provided for interpolation. @@ -1170,7 +1197,7 @@ RawConfigParser Objects .. note:: Consider using :class:`ConfigParser` instead which checks types of - the values to be stored internally. If you don't want interpolation, you + the values to be stored internally. If you don't want interpolation, you can use ``ConfigParser(interpolation=None)``. @@ -1181,7 +1208,7 @@ RawConfigParser Objects *default section* name is passed, :exc:`ValueError` is raised. Type of *section* is not checked which lets users create non-string named - sections. This behaviour is unsupported and may cause internal errors. + sections. This behaviour is unsupported and may cause internal errors. .. method:: set(section, option, value) @@ -1282,3 +1309,4 @@ Exceptions .. [1] Config parsers allow for heavy customization. If you are interested in changing the behaviour outlined by the footnote reference, consult the `Customizing Parser Behaviour`_ section. + diff --git a/Doc/library/constants.rst b/Doc/library/constants.rst index 059a21d5c83e..d5a0f09173b3 100644 --- a/Doc/library/constants.rst +++ b/Doc/library/constants.rst @@ -26,9 +26,23 @@ A small number of constants live in the built-in namespace. They are: .. data:: NotImplemented - Special value which can be returned by the "rich comparison" special methods - (:meth:`__eq__`, :meth:`__lt__`, and friends), to indicate that the comparison - is not implemented with respect to the other type. + Special value which should be returned by the binary special methods + (e.g. :meth:`__eq__`, :meth:`__lt__`, :meth:`__add__`, :meth:`__rsub__`, + etc.) to indicate that the operation is not implemented with respect to + the other type; may be returned by the in-place binary special methods + (e.g. :meth:`__imul__`, :meth:`__iand__`, etc.) for the same purpose. + Its truth value is true. + +.. note:: + + When ``NotImplemented`` is returned, the interpreter will then try the + reflected operation on the other type, or some other fallback, depending + on the operator. If all attempted operations return ``NotImplemented``, the + interpreter will raise an appropriate exception. + + See + :ref:`implementing-the-arithmetic-operations` + for more details. .. data:: Ellipsis diff --git a/Doc/library/contextlib.rst b/Doc/library/contextlib.rst index 82efd0cca151..550b3476bd1a 100644 --- a/Doc/library/contextlib.rst +++ b/Doc/library/contextlib.rst @@ -167,11 +167,21 @@ Functions and classes provided: applications. It also has no effect on the output of subprocesses. However, it is still a useful approach for many utility scripts. - This context manager is :ref:`reusable but not reentrant <reusable-cms>`. + This context manager is :ref:`reentrant <reentrant-cms>`. .. versionadded:: 3.4 +.. function:: redirect_stderr(new_target) + + Similar to :func:`~contextlib.redirect_stdout` but redirecting + :data:`sys.stderr` to another file or file-like object. + + This context manager is :ref:`reentrant <reentrant-cms>`. + + .. versionadded:: 3.5 + + .. class:: ContextDecorator() A base class that enables a context manager to also be used as a decorator. @@ -371,7 +381,7 @@ some of the context managers being optional:: with ExitStack() as stack: for resource in resources: stack.enter_context(resource) - if need_special resource: + if need_special_resource(): special = acquire_special_resource() stack.callback(release_special_resource, special) # Perform operations that use the acquired resources @@ -568,10 +578,10 @@ single definition:: self.name = name def __enter__(self): - logging.info('Entering: {}'.format(name)) + logging.info('Entering: {}'.format(self.name)) def __exit__(self, exc_type, exc, exc_tb): - logging.info('Exiting: {}'.format(name)) + logging.info('Exiting: {}'.format(self.name)) Instances of this class can be used as both a context manager:: diff --git a/Doc/library/copyreg.rst b/Doc/library/copyreg.rst index 50d5879ae529..18306c7f99f0 100644 --- a/Doc/library/copyreg.rst +++ b/Doc/library/copyreg.rst @@ -9,7 +9,7 @@ module: pickle module: copy -The :mod:`copyreg` module offers a way to define fuctions used while pickling +The :mod:`copyreg` module offers a way to define functions used while pickling specific objects. The :mod:`pickle` and :mod:`copy` modules use those functions when pickling/copying those objects. The module provides configuration information about object constructors which are not classes. diff --git a/Doc/library/crypto.rst b/Doc/library/crypto.rst index 469ede4982c8..8ad24c8d4fbf 100644 --- a/Doc/library/crypto.rst +++ b/Doc/library/crypto.rst @@ -25,6 +25,5 @@ Here's an overview: Hardcore cypherpunks will probably find the cryptographic modules written by A.M. Kuchling of further interest; the package contains modules for various encryption algorithms, most notably AES. These modules are not distributed with -Python but available separately. See the URL -http://www.pycrypto.org for more information. - +Python but available separately. See the URL http://www.pycrypto.org/ for more +information. diff --git a/Doc/library/csv.rst b/Doc/library/csv.rst index a20c4be901b0..e7516b67f920 100644 --- a/Doc/library/csv.rst +++ b/Doc/library/csv.rst @@ -5,6 +5,7 @@ :synopsis: Write and read tabular data to and from delimited files. .. sectionauthor:: Skip Montanaro <skip@pobox.com> +**Source code:** :source:`Lib/csv.py` .. index:: single: csv @@ -142,36 +143,68 @@ 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, dialect='excel', *args, **kwds) - - Create an object which operates like a regular reader but maps the information - read into a dict whose keys are given by the optional *fieldnames* parameter. - If the *fieldnames* parameter is omitted, the values in the first row of the - *csvfile* will be used as the fieldnames. If the row read has more fields - than the fieldnames sequence, the remaining data is added as a sequence - keyed by the value of *restkey*. If the row read has fewer fields than the - fieldnames sequence, the remaining keys take the value of the optional - *restval* parameter. Any other optional or keyword arguments are passed to - the underlying :class:`reader` instance. - - -.. class:: DictWriter(csvfile, 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 identifies 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 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 take. If it is set - to ``'raise'`` a :exc:`ValueError` is raised. If it is set to ``'ignore'``, - extra values in the dictionary are ignored. Any other optional or keyword - arguments are passed to the underlying :class:`writer` instance. - - 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*. +.. class:: DictReader(csvfile, fieldnames=None, restkey=None, restval=None, \ + dialect='excel', *args, **kwds) + + Create an object which operates like a regular reader but maps the + information read into a dict whose keys are given by the optional + *fieldnames* parameter. The *fieldnames* parameter is a :mod:`sequence + <collections.abc>` whose elements are associated with the fields of the + input data in order. These elements become the keys of the resulting + dictionary. If the *fieldnames* parameter is omitted, the values in the + first row of the *csvfile* will be used as the fieldnames. If the row read + has more fields than the fieldnames sequence, the remaining data is added as + a sequence keyed by the value of *restkey*. If the row read has fewer + fields than the fieldnames sequence, the remaining keys take the value of + the optional *restval* parameter. Any other optional or keyword arguments + are passed to the underlying :class:`reader` instance. + + A short usage example:: + + >>> import csv + >>> with open('names.csv') as csvfile: + ... reader = csv.DictReader(csvfile) + ... for row in reader: + ... print(row['first_name'], row['last_name']) + ... + Baked Beans + Lovely Spam + Wonderful Spam + + +.. class:: DictWriter(csvfile, 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 + <collections.abc>` 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 + 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 + take. If it is set to ``'raise'`` a :exc:`ValueError` is raised. If it is + set to ``'ignore'``, extra values in the dictionary are ignored. Any other + optional or keyword arguments are passed to the underlying :class:`writer` + instance. + + 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*. + + A short usage example:: + + import csv + + with open('names.csv', 'w') as csvfile: + fieldnames = ['first_name', 'last_name'] + writer = csv.DictWriter(csvfile, fieldnames=fieldnames) + + writer.writeheader() + writer.writerow({'first_name': 'Baked', 'last_name': 'Beans'}) + writer.writerow({'first_name': 'Lovely', 'last_name': 'Spam'}) + writer.writerow({'first_name': 'Wonderful', 'last_name': 'Spam'}) .. class:: Dialect diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst index ccbb8ec563e5..588ac7c16c7b 100644 --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -218,7 +218,7 @@ more about :mod:`ctypes` data types. Fundamental data types ^^^^^^^^^^^^^^^^^^^^^^ -:mod:`ctypes` defines a number of primitive C compatible data types : +:mod:`ctypes` defines a number of primitive C compatible data types: +----------------------+------------------------------------------+----------------------------+ | ctypes type | C type | Python type | @@ -1022,12 +1022,18 @@ As we can easily check, our array is sorted now:: 1 5 7 33 99 >>> -**Important note for callback functions:** +.. note:: -Make sure you keep references to :func:`CFUNCTYPE` objects as long as they are -used from C code. :mod:`ctypes` doesn't, and if you don't, they may be garbage -collected, crashing your program when a callback is made. + Make sure you keep references to :func:`CFUNCTYPE` objects as long as they + are used from C code. :mod:`ctypes` doesn't, and if you don't, they may be + garbage collected, crashing your program when a callback is made. + Also, note that if the callback function is called in a thread created + outside of Python's control (e.g. by the foreign code that calls the + callback), ctypes creates a new dummy Python thread on every invocation. This + behavior is correct for most purposes, but it means that values stored with + :class:`threading.local` will *not* survive across different callbacks, even when + those calls are made from the same C thread. .. _ctypes-accessing-values-exported-from-dlls: @@ -1380,11 +1386,16 @@ copy of the windows error code. The default mode which is used to load shared libraries. On OSX 10.3, this is *RTLD_GLOBAL*, otherwise it is the same as *RTLD_LOCAL*. -Instances of these classes have no public methods, however :meth:`__getattr__` -and :meth:`__getitem__` have special behavior: functions exported by the shared -library can be accessed as attributes of by index. Please note that both -:meth:`__getattr__` and :meth:`__getitem__` cache their result, so calling them -repeatedly returns the same object each time. +Instances of these classes have no public methods. Functions exported by the +shared library can be accessed as attributes or by index. Please note that +accessing the function through an attribute caches the result and therefore +accessing it repeatedly returns the same object each time. On the other hand, +accessing it through an index returns a new object each time: + + >>> libc.time == libc.time + True + >>> libc['time'] == libc['time'] + False The following public attributes are available, their name starts with an underscore to not clash with exported function names: @@ -1651,7 +1662,7 @@ the windows header file is this:: WINUSERAPI int WINAPI MessageBoxA( - HWND hWnd , + HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType); @@ -1822,7 +1833,7 @@ Utility functions .. function:: find_msvcrt() :module: ctypes.util - Windows only: return the filename of the VC runtype library used by Python, + Windows only: return the filename of the VC runtime library used by Python, and by the extension modules. If the name of the library cannot be determined, ``None`` is returned. @@ -2324,11 +2335,6 @@ other data types containing pointer type fields. and so on). Later assignments to the :attr:`_fields_` class variable will raise an AttributeError. - Structure and union subclass constructors accept both positional and named - arguments. Positional arguments are used to initialize the fields in the - same order as they appear in the :attr:`_fields_` definition, named - arguments are used to initialize the fields with the corresponding name. - It is possible to defined sub-subclasses of structure types, they inherit the fields of the base class plus the :attr:`_fields_` defined in the sub-subclass, if any. diff --git a/Doc/library/curses.rst b/Doc/library/curses.rst index 314636e4b48c..f3e60b4be94d 100644 --- a/Doc/library/curses.rst +++ b/Doc/library/curses.rst @@ -12,7 +12,7 @@ The :mod:`curses` module provides an interface to the curses library, the de-facto standard for portable advanced terminal handling. While curses is most widely used in the Unix environment, versions are available -for DOS, OS/2, and possibly other systems as well. This extension module is +for Windows, DOS, and possibly other systems as well. This extension module is designed to match the API of ncurses, an open-source curses library hosted on Linux and the BSD variants of Unix. diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst index e4f1eb230177..7a9f93cd238f 100644 --- a/Doc/library/datetime.rst +++ b/Doc/library/datetime.rst @@ -7,6 +7,8 @@ .. sectionauthor:: Tim Peters <tim@zope.com> .. sectionauthor:: A.M. Kuchling <amk@amk.ca> +**Source code:** :source:`Lib/datetime.py` + .. XXX what order should the types be discussed in? The :mod:`datetime` module supplies classes for manipulating dates and times in @@ -558,7 +560,7 @@ Instance methods: Return a 3-tuple, (ISO year, ISO week number, ISO weekday). The ISO calendar is a widely used variant of the Gregorian calendar. See - http://www.phys.uu.nl/~vgent/calendar/isocalendar.htm for a good + http://www.staff.science.uu.nl/~gent0113/calendar/isocalendar.htm for a good explanation. The ISO year consists of 52 or 53 full weeks, and where a week starts on a @@ -1376,10 +1378,13 @@ Supported operations: * efficient pickling -* in Boolean contexts, a :class:`.time` object is considered to be true if and - only if, after converting it to minutes and subtracting :meth:`utcoffset` (or - ``0`` if that's ``None``), the result is non-zero. +In boolean contexts, a :class:`.time` object is always considered to be true. +.. versionchanged:: 3.5 + Before Python 3.5, a :class:`.time` object was considered to be false if it + represented midnight in UTC. This behavior was considered obscure and + error-prone and has been removed in Python 3.5. See :issue:`13936` for full + details. Instance methods: @@ -1686,12 +1691,12 @@ only EST (fixed offset -5 hours), or only EDT (fixed offset -4 hours)). .. seealso:: - `pytz <http://pypi.python.org/pypi/pytz/>`_ - The standard library has no :class:`tzinfo` instances except for UTC, but - there exists a third-party library which brings the *IANA timezone - database* (also known as the Olson database) to Python: *pytz*. + `pytz <https://pypi.python.org/pypi/pytz/>`_ + The standard library has :class:`timezone` class for handling arbitrary + fixed offsets from UTC and :attr:`timezone.utc` as UTC timezone instance. - *pytz* contains up-to-date information and its usage is recommended. + *pytz* library brings the *IANA timezone database* (also known as the + Olson database) to Python and its usage is recommended. `IANA timezone database <http://www.iana.org/time-zones>`_ The Time Zone Database (often called tz or zoneinfo) contains code and @@ -1728,6 +1733,8 @@ made to civil time. *offset*, HH and MM are two digits of ``offset.hours`` and ``offset.minutes`` respectively. + .. versionadded:: 3.2 + .. method:: timezone.utcoffset(dt) Return the fixed value specified when the :class:`timezone` instance is diff --git a/Doc/library/dbm.rst b/Doc/library/dbm.rst index f5496d5b99c6..3f3c43d4383f 100644 --- a/Doc/library/dbm.rst +++ b/Doc/library/dbm.rst @@ -222,6 +222,9 @@ supported. When the database has been opened in fast mode, this method forces any unwritten data to be written to the disk. + .. method:: gdbm.close() + + Close the ``gdbm`` database. :mod:`dbm.ndbm` --- Interface based on ndbm ------------------------------------------- @@ -253,7 +256,7 @@ to locate the appropriate header file to simplify building this module. .. function:: open(filename[, flag[, mode]]) - Open a dbm database and return a ``dbm`` object. The *filename* argument is the + Open a dbm database and return a ``ndbm`` object. The *filename* argument is the name of the database file (without the :file:`.dir` or :file:`.pag` extensions). The optional *flag* argument must be one of these values: @@ -278,6 +281,12 @@ to locate the appropriate header file to simplify building this module. database has to be created. It defaults to octal ``0o666`` (and will be modified by the prevailing umask). + In addition to the dictionary-like methods, ``ndbm`` objects + provide the following method: + + .. method:: ndbm.close() + + Close the ``ndbm`` database. :mod:`dbm.dumb` --- Portable DBM implementation @@ -316,18 +325,28 @@ The module defines the following: dumbdbm database is created, files with :file:`.dat` and :file:`.dir` extensions are created. - The optional *flag* argument is currently ignored; the database is always opened - for update, and will be created if it does not exist. + The optional *flag* argument supports only the semantics of ``'c'`` + and ``'n'`` values. Other values will default to database being always + opened for update, and will be created if it does not exist. The optional *mode* argument is the Unix mode of the file, used only when the database has to be created. It defaults to octal ``0o666`` (and will be modified by the prevailing umask). + .. versionchanged:: 3.5 + :func:`.open` always creates a new database when the flag has the value + ``'n'``. + In addition to the methods provided by the :class:`collections.abc.MutableMapping` class, :class:`dumbdbm` objects - provide the following method: + provide the following methods: .. method:: dumbdbm.sync() Synchronize the on-disk directory and data files. This method is called by the :meth:`Shelve.sync` method. + + .. method:: dumbdbm.close() + + Close the ``dumbdbm`` database. + diff --git a/Doc/library/decimal.rst b/Doc/library/decimal.rst index 059ae7cb1690..705298536ba5 100644 --- a/Doc/library/decimal.rst +++ b/Doc/library/decimal.rst @@ -12,6 +12,8 @@ .. moduleauthor:: Stefan Krah <skrah at bytereef.org> .. sectionauthor:: Raymond D. Hettinger <python at rcn.com> +**Source code:** :source:`Lib/decimal.py` + .. import modules for testing inline doctests with the Sphinx doctest builder .. testsetup:: * @@ -742,7 +744,7 @@ Decimal objects * ``"NaN"``, indicating that the operand is a quiet NaN (Not a Number). * ``"sNaN"``, indicating that the operand is a signaling NaN. - .. method:: quantize(exp, rounding=None, context=None, watchexp=True) + .. method:: quantize(exp, rounding=None, context=None) Return a value equal to the first operand after rounding and having the exponent of the second operand. @@ -765,14 +767,8 @@ Decimal objects ``context`` argument; if neither argument is given the rounding mode of the current thread's context is used. - If *watchexp* is set (default), then an error is returned whenever the - resulting exponent is greater than :attr:`Emax` or less than - :attr:`Etiny`. - - .. deprecated:: 3.3 - *watchexp* is an implementation detail from the pure Python version - and is not present in the C version. It will be removed in version - 3.4, where it defaults to ``True``. + An error is returned whenever the resulting exponent is greater than + :attr:`Emax` or less than :attr:`Etiny`. .. method:: radix() @@ -2092,4 +2088,3 @@ Alternatively, inputs can be rounded upon creation using the >>> Context(prec=5, rounding=ROUND_DOWN).create_decimal('1.2345678') Decimal('1.2345') - diff --git a/Doc/library/difflib.rst b/Doc/library/difflib.rst index 81dc0f16be3f..329bde0af88c 100644 --- a/Doc/library/difflib.rst +++ b/Doc/library/difflib.rst @@ -7,6 +7,8 @@ .. sectionauthor:: Tim Peters <tim_one@users.sourceforge.net> .. Markup by Fred L. Drake, Jr. <fdrake@acm.org> +**Source code:** :source:`Lib/difflib.py` + .. testsetup:: import sys @@ -25,7 +27,9 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module. little fancier than, an algorithm published in the late 1980's by Ratcliff and Obershelp under the hyperbolic name "gestalt pattern matching." The idea is to find the longest contiguous matching subsequence that contains no "junk" - elements (the Ratcliff and Obershelp algorithm doesn't address junk). The same + elements; these "junk" elements are ones that are uninteresting in some + sense, such as blank lines or whitespace. (Handling junk is an + extension to the Ratcliff and Obershelp algorithm.) The same idea is then applied recursively to the pieces of the sequences to the left and to the right of the matching subsequence. This does not yield minimal edit sequences, but does tend to yield matches that "look right" to people. @@ -208,7 +212,7 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module. Compare *a* and *b* (lists of strings); return a :class:`Differ`\ -style delta (a :term:`generator` generating the delta lines). - Optional keyword parameters *linejunk* and *charjunk* are for filter functions + Optional keyword parameters *linejunk* and *charjunk* are filtering functions (or ``None``): *linejunk*: A function that accepts a single string argument, and returns @@ -222,12 +226,12 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module. *charjunk*: A function that accepts a character (a string of length 1), and returns if the character is junk, or false if not. The default is module-level function :func:`IS_CHARACTER_JUNK`, which filters out whitespace characters (a - blank or tab; note: bad idea to include newline in this!). + blank or tab; it's a bad idea to include newline in this!). :file:`Tools/scripts/ndiff.py` is a command-line front-end to this function. - >>> diff = ndiff('one\ntwo\nthree\n'.splitlines(1), - ... 'ore\ntree\nemu\n'.splitlines(1)) + >>> diff = ndiff('one\ntwo\nthree\n'.splitlines(keepends=True), + ... 'ore\ntree\nemu\n'.splitlines(keepends=True)) >>> print(''.join(diff), end="") - one ? ^ @@ -250,8 +254,8 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module. Example: - >>> diff = ndiff('one\ntwo\nthree\n'.splitlines(1), - ... 'ore\ntree\nemu\n'.splitlines(1)) + >>> diff = ndiff('one\ntwo\nthree\n'.splitlines(keepends=True), + ... 'ore\ntree\nemu\n'.splitlines(keepends=True)) >>> diff = list(diff) # materialize the generated delta into a list >>> print(''.join(restore(diff, 1)), end="") one @@ -323,9 +327,9 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module. .. seealso:: - `Pattern Matching: The Gestalt Approach <http://www.ddj.com/184407970?pgno=5>`_ + `Pattern Matching: The Gestalt Approach <http://www.drdobbs.com/database/pattern-matching-the-gestalt-approach/184407970>`_ Discussion of a similar algorithm by John W. Ratcliff and D. E. Metzener. This - was published in `Dr. Dobb's Journal <http://www.ddj.com/>`_ in July, 1988. + was published in `Dr. Dobb's Journal <http://www.drdobbs.com/>`_ in July, 1988. .. _sequence-matcher: @@ -622,6 +626,12 @@ The :class:`Differ` class has this constructor: length 1), and returns true if the character is junk. The default is ``None``, meaning that no character is considered junk. + These junk-filtering functions speed up matching to find + differences and do not cause any differing lines or characters to + be ignored. Read the description of the + :meth:`~SequenceMatcher.find_longest_match` method's *isjunk* + parameter for an explanation. + :class:`Differ` objects are used (deltas generated) via a single method: @@ -650,7 +660,7 @@ obtained from the :meth:`~io.BaseIO.readlines` method of file-like objects): ... 2. Explicit is better than implicit. ... 3. Simple is better than complex. ... 4. Complex is better than complicated. - ... '''.splitlines(1) + ... '''.splitlines(keepends=True) >>> len(text1) 4 >>> text1[0][-1] @@ -659,7 +669,7 @@ obtained from the :meth:`~io.BaseIO.readlines` method of file-like objects): ... 3. Simple is better than complex. ... 4. Complicated is better than complex. ... 5. Flat is better than nested. - ... '''.splitlines(1) + ... '''.splitlines(keepends=True) Next we instantiate a Differ object: diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index 8293d498a362..3b419e6c8a4d 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -40,14 +40,16 @@ the following command can be used to display the disassembly of Bytecode analysis ----------------- +.. versionadded:: 3.4 + The bytecode analysis API allows pieces of Python code to be wrapped in a :class:`Bytecode` object that provides easy access to details of the compiled code. .. class:: Bytecode(x, *, first_line=None, current_offset=None) - Analyse the bytecode corresponding to a function, method, string of - source code, or a code object (as returned by :func:`compile`). + Analyse the bytecode corresponding to a function, generator, method, + string of source code, or a code object (as returned by :func:`compile`). This is a convenience wrapper around many of the functions listed below, most notably :func:`get_instructions`, as iterating over a @@ -110,7 +112,7 @@ object isn't useful: .. function:: code_info(x) Return a formatted multi-line string with detailed code object information - for the supplied function, method, source code string or code object. + for the supplied function, generator, method, source code string or code object. Note that the exact contents of code info strings are highly implementation dependent and they may change arbitrarily across Python VMs or Python @@ -131,25 +133,25 @@ object isn't useful: .. versionadded:: 3.2 .. versionchanged:: 3.4 - Added ``file`` parameter + Added *file* parameter. .. function:: dis(x=None, *, file=None) Disassemble the *x* object. *x* can denote either a module, a class, a - method, a function, a code object, a string of source code or a byte sequence - of raw bytecode. For a module, it disassembles all functions. For a class, - it disassembles all methods. For a code object or sequence of raw bytecode, - it prints one line per bytecode instruction. Strings are first compiled to - code objects with the :func:`compile` built-in function before being + method, a function, a generator, a code object, a string of source code or + a byte sequence of raw bytecode. For a module, it disassembles all functions. + For a class, it disassembles all methods. For a code object or sequence of + raw bytecode, it prints one line per bytecode instruction. Strings are first + compiled to code objects with the :func:`compile` built-in function before being disassembled. If no object is provided, this function disassembles the last traceback. - The disassembly is written as text to the supplied ``file`` argument if + The disassembly is written as text to the supplied *file* argument if provided and to ``sys.stdout`` otherwise. .. versionchanged:: 3.4 - Added ``file`` parameter + Added *file* parameter. .. function:: distb(tb=None, *, file=None) @@ -158,11 +160,11 @@ object isn't useful: traceback if none was passed. The instruction causing the exception is indicated. - The disassembly is written as text to the supplied ``file`` argument if + The disassembly is written as text to the supplied *file* argument if provided and to ``sys.stdout`` otherwise. .. versionchanged:: 3.4 - Added ``file`` parameter + Added *file* parameter. .. function:: disassemble(code, lasti=-1, *, file=None) @@ -182,11 +184,11 @@ object isn't useful: The parameter interpretation recognizes local and global variable names, constant values, branch targets, and compare operators. - The disassembly is written as text to the supplied ``file`` argument if + The disassembly is written as text to the supplied *file* argument if provided and to ``sys.stdout`` otherwise. .. versionchanged:: 3.4 - Added ``file`` parameter + Added *file* parameter. .. function:: get_instructions(x, *, first_line=None) @@ -362,6 +364,11 @@ result back on the stack. Implements ``TOS = TOS1 * TOS``. +.. opcode:: BINARY_MATRIX_MULTIPLY + + Implements ``TOS = TOS1 @ TOS``. + + .. opcode:: BINARY_FLOOR_DIVIDE Implements ``TOS = TOS1 // TOS``. @@ -434,6 +441,11 @@ the original TOS1. Implements in-place ``TOS = TOS1 * TOS``. +.. opcode:: INPLACE_MATRIX_MULTIPLY + + Implements in-place ``TOS = TOS1 @ TOS``. + + .. opcode:: INPLACE_FLOOR_DIVIDE Implements in-place ``TOS = TOS1 // TOS``. @@ -500,7 +512,7 @@ the original TOS1. Implements the expression statement for the interactive mode. TOS is removed from the stack and printed. In non-interactive mode, an expression statement is - terminated with ``POP_STACK``. + terminated with :opcode:`POP_TOP`. .. opcode:: BREAK_LOOP @@ -511,7 +523,7 @@ the original TOS1. .. opcode:: CONTINUE_LOOP (target) Continues a loop due to a :keyword:`continue` statement. *target* is the - address to jump to (which should be a ``FOR_ITER`` instruction). + address to jump to (which should be a :opcode:`FOR_ITER` instruction). .. opcode:: SET_ADD (i) @@ -529,7 +541,8 @@ the original TOS1. Calls ``dict.setitem(TOS1[-i], TOS, TOS1)``. Used to implement dict comprehensions. -For all of the SET_ADD, LIST_APPEND and MAP_ADD instructions, while the +For all of the :opcode:`SET_ADD`, :opcode:`LIST_APPEND` and :opcode:`MAP_ADD` +instructions, while the added value or key/value pair is popped off, the container object remains on the stack so that it is available for further iterations of the loop. @@ -582,7 +595,7 @@ the stack so that it is available for further iterations of the loop. .. opcode:: LOAD_BUILD_CLASS Pushes :func:`builtins.__build_class__` onto the stack. It is later called - by ``CALL_FUNCTION`` to construct a class. + by :opcode:`CALL_FUNCTION` to construct a class. .. opcode:: SETUP_WITH (delta) @@ -613,7 +626,7 @@ the stack so that it is available for further iterations of the loop. If the stack represents an exception, *and* the function call returns a 'true' value, this information is "zapped" and replaced with a single - ``WHY_SILENCED`` to prevent ``END_FINALLY`` from re-raising the exception. + ``WHY_SILENCED`` to prevent :opcode:`END_FINALLY` from re-raising the exception. (But non-local gotos will still be resumed.) .. XXX explain the WHY stuff! @@ -625,8 +638,8 @@ the more significant byte last. .. opcode:: STORE_NAME (namei) Implements ``name = TOS``. *namei* is the index of *name* in the attribute - :attr:`co_names` of the code object. The compiler tries to use ``STORE_FAST`` - or ``STORE_GLOBAL`` if possible. + :attr:`co_names` of the code object. The compiler tries to use :opcode:`STORE_FAST` + or :opcode:`STORE_GLOBAL` if possible. .. opcode:: DELETE_NAME (namei) @@ -666,12 +679,12 @@ the more significant byte last. .. opcode:: STORE_GLOBAL (namei) - Works as ``STORE_NAME``, but stores the name as a global. + Works as :opcode:`STORE_NAME`, but stores the name as a global. .. opcode:: DELETE_GLOBAL (namei) - Works as ``DELETE_NAME``, but deletes a global name. + Works as :opcode:`DELETE_NAME`, but deletes a global name. .. opcode:: LOAD_CONST (consti) @@ -692,12 +705,12 @@ the more significant byte last. .. opcode:: BUILD_LIST (count) - Works as ``BUILD_TUPLE``, but creates a list. + Works as :opcode:`BUILD_TUPLE`, but creates a list. .. opcode:: BUILD_SET (count) - Works as ``BUILD_TUPLE``, but creates a set. + Works as :opcode:`BUILD_TUPLE`, but creates a set. .. opcode:: BUILD_MAP (count) @@ -722,7 +735,7 @@ the more significant byte last. Imports the module ``co_names[namei]``. TOS and TOS1 are popped and provide the *fromlist* and *level* arguments of :func:`__import__`. The module object is pushed onto the stack. The current namespace is not affected: - for a proper import statement, a subsequent ``STORE_FAST`` instruction + for a proper import statement, a subsequent :opcode:`STORE_FAST` instruction modifies the namespace. @@ -730,7 +743,7 @@ the more significant byte last. Loads the attribute ``co_names[namei]`` from the module found in TOS. The resulting object is pushed onto the stack, to be subsequently stored by a - ``STORE_FAST`` instruction. + :opcode:`STORE_FAST` instruction. .. opcode:: JUMP_FORWARD (delta) @@ -909,21 +922,21 @@ the more significant byte last. .. opcode:: CALL_FUNCTION_VAR (argc) - Calls a function. *argc* is interpreted as in ``CALL_FUNCTION``. The top element + Calls a function. *argc* is interpreted as in :opcode:`CALL_FUNCTION`. The top element on the stack contains the variable argument list, followed by keyword and positional arguments. .. opcode:: CALL_FUNCTION_KW (argc) - Calls a function. *argc* is interpreted as in ``CALL_FUNCTION``. The top element + Calls a function. *argc* is interpreted as in :opcode:`CALL_FUNCTION`. The top element on the stack contains the keyword arguments dictionary, followed by explicit keyword and positional arguments. .. opcode:: CALL_FUNCTION_VAR_KW (argc) - Calls a function. *argc* is interpreted as in ``CALL_FUNCTION``. The top + Calls a function. *argc* is interpreted as in :opcode:`CALL_FUNCTION`. The top element on the stack contains the keyword arguments dictionary, followed by the variable-arguments tuple, followed by explicit keyword and positional arguments. diff --git a/Doc/library/distribution.rst b/Doc/library/distribution.rst index fb3f5df59984..c4954d1b4ade 100644 --- a/Doc/library/distribution.rst +++ b/Doc/library/distribution.rst @@ -4,7 +4,7 @@ Software Packaging and Distribution These libraries help you with publishing and installing Python software. While these modules are designed to work in conjunction with the -`Python Package Index <https://pypi.python.org>`__, they can also be used +`Python Package Index <https://pypi.python.org/pypi>`__, they can also be used with a local index server, or without any index server at all. .. toctree:: diff --git a/Doc/library/distutils.rst b/Doc/library/distutils.rst index 6666a9b7d725..e3d131457255 100644 --- a/Doc/library/distutils.rst +++ b/Doc/library/distutils.rst @@ -12,14 +12,31 @@ additional modules into a Python installation. The new modules may be either 100%-pure Python, or may be extension modules written in C, or may be collections of Python packages which include modules coded in both Python and C. +Most Python users will *not* want to use this module directly, but instead +use the cross-version tools maintained by the Python Packaging Authority. In +particular, +`setuptools <https://setuptools.pypa.io/en/latest/setuptools.html>`__ is an +enhanced alternative to :mod:`distutils` that provides: -User documentation and API reference are provided in another document: +* support for declaring project dependencies +* additional mechanisms for configuring which files to include in source + releases (including plugins for integration with version control systems) +* the ability to declare project "entry points", which can be used as the + basis for application plugin systems +* the ability to automatically generate Windows command line executables at + installation time rather than needing to prebuild them +* consistent behaviour across all supported Python versions -.. seealso:: +The recommended `pip <https://pip.pypa.io/>`__ installer runs all +``setup.py`` scripts with ``setuptools``, even if the script itself only +imports ``distutils``. Refer to the +`Python Packaging User Guide <https://packaging.python.org>`_ for more +information. - :ref:`distutils-index` - The manual for developers and packagers of Python modules. This describes - how to prepare :mod:`distutils`\ -based packages so that they may be - easily installed into an existing Python installation. It also contains - instructions for end-users wanting to install a distutils-based package, - :ref:`install-index`. +For the benefits of packaging tool authors and users seeking a deeper +understanding of the details of the current packaging and distribution +system, the legacy :mod:`distutils` based user documentation and API +reference remain available: + +* :ref:`install-index` +* :ref:`distutils-index` diff --git a/Doc/library/doctest.rst b/Doc/library/doctest.rst index 28df49c70036..9aa9ea6614ae 100644 --- a/Doc/library/doctest.rst +++ b/Doc/library/doctest.rst @@ -502,7 +502,8 @@ or'ed together and passed to various functions. The names can also be used in :ref:`doctest directives <doctest-directives>`, and may be passed to the doctest command line interface via the ``-o`` option. -.. versionadded:: 3.4 the ``-o`` command line option +.. versionadded:: 3.4 + The ``-o`` command line option. The first group of options define test semantics, controlling aspects of how doctest decides whether actual output matches an example's expected output: @@ -864,8 +865,8 @@ 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* or's together option flags. See section - :ref:`doctest-options`. + Optional argument *optionflags* (default value 0) takes the 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 @@ -1057,15 +1058,9 @@ from text files and modules with doctests: This function uses the same search technique as :func:`testmod`. - .. note:: - Unlike :func:`testmod` and :class:`DocTestFinder`, this function raises - a :exc:`ValueError` if *module* contains no docstrings. You can prevent - this error by passing a :class:`DocTestFinder` instance as the - *test_finder* argument with its *exclude_empty* keyword argument set - to ``False``:: - - >>> finder = doctest.DocTestFinder(exclude_empty=False) - >>> suite = doctest.DocTestSuite(test_finder=finder) + .. versionchanged:: 3.5 + :func:`DocTestSuite` returns an empty :class:`unittest.TestSuite` if *module* + contains no docstrings instead of raising :exc:`ValueError`. Under the covers, :func:`DocTestSuite` creates a :class:`unittest.TestSuite` out @@ -1096,7 +1091,7 @@ reporting flags specific to :mod:`unittest` support, via this function: Set the :mod:`doctest` reporting flags to use. - Argument *flags* or's together option flags. See section + Argument *flags* takes the 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 diff --git a/Doc/library/email-examples.rst b/Doc/library/email-examples.rst index 32cecf3486c1..cbbcb78e245c 100644 --- a/Doc/library/email-examples.rst +++ b/Doc/library/email-examples.rst @@ -40,6 +40,36 @@ text version: [2]_ .. literalinclude:: ../includes/email-alternative.py +.. _email-contentmanager-api-examples: + +Examples using the Provisional API +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Here is a reworking of the last example using the provisional API. To make +things a bit more interesting, we include a related image in the html part, and +we save a copy of what we are going to send to disk, as well as sending it. + +This example also shows how easy it is to include non-ASCII, and simplifies the +sending of the message using the :meth:`.send_message` method of the +:mod:`smtplib` module. + +.. literalinclude:: ../includes/email-alternative-new-api.py + +If we were instead sent the message from the last example, here is one +way we could process it: + +.. literalinclude:: ../includes/email-read-alternative-new-api.py + +Up to the prompt, the output from the above is:: + + To: Penelope Pussycat <"penelope@example.com">, Fabrette Pussycat <"fabrette@example.com"> + From: Pepé Le Pew <pepe@example.com> + Subject: Ayons asperges pour le déjeuner + + Salut! + + Cela ressemble à un excellent recipie[1] déjeuner. + + .. rubric:: Footnotes .. [1] Thanks to Matthew Dixon Cowles for the original inspiration and examples. diff --git a/Doc/library/email.contentmanager.rst b/Doc/library/email.contentmanager.rst index 5162da18faab..8f33a146dd87 100644 --- a/Doc/library/email.contentmanager.rst +++ b/Doc/library/email.contentmanager.rst @@ -54,6 +54,7 @@ this module. documented in this module because of the provisional nature of the code, the implementation lives in the :mod:`email.message` module. +.. currentmodule:: email.message .. class:: EmailMessage(policy=default) @@ -69,11 +70,15 @@ this module. the following methods: - .. attribute:: is_attachment + .. method:: is_attachment - Set to ``True`` if there is a :mailheader:`Content-Disposition` header + Return ``True`` if there is a :mailheader:`Content-Disposition` header and its (case insensitive) value is ``attachment``, ``False`` otherwise. + .. versionchanged:: 3.4.2 + is_attachment is now a method instead of a property, for consistency + with :meth:`~email.message.Message.is_multipart`. + .. method:: get_body(preferencelist=('related', 'html', 'plain')) @@ -235,6 +240,16 @@ this module. all other headers intact and in their original order. +.. class:: MIMEPart(policy=default) + + This class represents a subpart of a MIME message. It is identical to + :class:`EmailMessage`, except that no :mailheader:`MIME-Version` headers are + added when :meth:`~EmailMessage.set_content` is called, since sub-parts do + not need their own :mailheader:`MIME-Version` headers. + + +.. currentmodule:: email.contentmanager + .. class:: ContentManager() Base class for content managers. Provides the standard registry mechanisms @@ -305,14 +320,6 @@ this module. values of *typekey*, see :meth:`set_content`. -.. class:: MIMEPart(policy=default) - - This class represents a subpart of a MIME message. It is identical to - :class:`EmailMessage`, except that no :mailheader:`MIME-Version` headers are - added when :meth:`~EmailMessage.set_content` is called, since sub-parts do - not need their own :mailheader:`MIME-Version` headers. - - Content Manager Instances ~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/Doc/library/email.generator.rst b/Doc/library/email.generator.rst index c172acbad305..48d41e1dc78e 100644 --- a/Doc/library/email.generator.rst +++ b/Doc/library/email.generator.rst @@ -112,7 +112,7 @@ formatted string representation of a message object. For more detail, see :mod:`email.message`. .. class:: BytesGenerator(outfp, mangle_from_=True, maxheaderlen=78, *, \ - policy=policy.default) + policy=None) The constructor for the :class:`BytesGenerator` class takes a binary :term:`file-like object` called *outfp* for an argument. *outfp* must @@ -134,9 +134,11 @@ formatted string representation of a message object. For more detail, see wrapping. The default is 78, as recommended (but not required) by :rfc:`2822`. + The *policy* keyword specifies a :mod:`~email.policy` object that controls a - number of aspects of the generator's operation. The default policy - maintains backward compatibility. + number of aspects of the generator's operation. If no *policy* is specified, + then the *policy* attached to the message object passed to :attr:`flatten` + is used. .. versionchanged:: 3.3 Added the *policy* keyword. @@ -174,7 +176,7 @@ formatted string representation of a message object. For more detail, see Optional *linesep* specifies the line separator character used to terminate lines in the output. If specified it overrides the value - specified by the ``Generator``\ 's ``policy``. + specified by the ``Generator``\ or *msg*\ 's ``policy``. .. method:: clone(fp) diff --git a/Doc/library/email.message.rst b/Doc/library/email.message.rst index 84a5f5138ccb..aeea94221d5c 100644 --- a/Doc/library/email.message.rst +++ b/Doc/library/email.message.rst @@ -34,7 +34,7 @@ Here are the methods of the :class:`Message` class: .. class:: Message(policy=compat32) If *policy* is specified (it must be an instance of a :mod:`~email.policy` - class) use the rules it specifies to udpate and serialize the representation + class) use the rules it specifies to update and serialize the representation of the message. If *policy* is not set, use the :class:`compat32 <email.policy.Compat32>` policy, which maintains backward compatibility with the Python 3.2 version of the email package. For more information see the @@ -131,7 +131,11 @@ Here are the methods of the :class:`Message` class: Return ``True`` if the message's payload is a list of sub-\ :class:`Message` objects, otherwise return ``False``. When - :meth:`is_multipart` returns ``False``, the payload should be a string object. + :meth:`is_multipart` returns ``False``, the payload should be a string + object. (Note that :meth:`is_multipart` returning ``True`` does not + necessarily mean that "msg.get_content_maintype() == 'multipart'" will + return the ``True``. For example, ``is_multipart`` will return ``True`` + when the :class:`Message` is of type ``message/rfc822``.) .. method:: set_unixfrom(unixfrom) @@ -466,7 +470,7 @@ Here are the methods of the :class:`Message` class: to ``False``. - .. method:: set_param(param, value, header='Content-Type', requote=True, + .. method:: set_param(param, value, header='Content-Type', requote=True, \ charset=None, language='', replace=False) Set a parameter in the :mailheader:`Content-Type` header. If the @@ -488,7 +492,7 @@ Here are the methods of the :class:`Message` class: end of the list of headers. If *replace* is ``True``, the header will be updated in place. - .. versionchanged: 3.4 ``replace`` keyword was added. + .. versionchanged:: 3.4 ``replace`` keyword was added. .. method:: del_param(param, header='content-type', requote=True) @@ -584,23 +588,56 @@ Here are the methods of the :class:`Message` class: Here's an example that prints the MIME type of every part of a multipart message structure: - .. testsetup:: + .. testsetup:: + + >>> from email import message_from_binary_file + >>> with open('Lib/test/test_email/data/msg_16.txt', 'rb') as f: + ... msg = message_from_binary_file(f) + >>> from email.iterators import _structure + + .. doctest:: + + >>> for part in msg.walk(): + ... print(part.get_content_type()) + multipart/report + text/plain + message/delivery-status + text/plain + text/plain + message/rfc822 + text/plain + + ``walk`` iterates over the subparts of any part where + :meth:`is_multipart` returns ``True``, even though + ``msg.get_content_maintype() == 'multipart'`` may return ``False``. We + can see this in our example by making use of the ``_structure`` debug + helper function: + + .. doctest:: + + >>> for part in msg.walk(): + ... print(part.get_content_maintype() == 'multipart'), + ... part.is_multipart()) + True True + False False + False True + False False + False False + False True + False False + >>> _structure(msg) + multipart/report + text/plain + message/delivery-status + text/plain + text/plain + message/rfc822 + text/plain + + Here the ``message`` parts are not ``multiparts``, but they do contain + subparts. ``is_multipart()`` returns ``True`` and ``walk`` descends + into the subparts. - >>> from email import message_from_binary_file - >>> with open('Lib/test/test_email/data/msg_16.txt', 'rb') as f: - ... msg = message_from_binary_file(f) - - .. doctest:: - - >>> for part in msg.walk(): - ... print(part.get_content_type()) - multipart/report - text/plain - message/delivery-status - text/plain - text/plain - message/rfc822 - text/plain :class:`Message` objects can also optionally contain two instance attributes, which can be used when generating the plain text of a MIME message. diff --git a/Doc/library/email.mime.rst b/Doc/library/email.mime.rst index 4cdb322f4604..67d0a679549c 100644 --- a/Doc/library/email.mime.rst +++ b/Doc/library/email.mime.rst @@ -194,8 +194,9 @@ Here are the classes: minor type and defaults to :mimetype:`plain`. *_charset* is the character set of the text and is passed as an argument to the :class:`~email.mime.nonmultipart.MIMENonMultipart` constructor; it defaults - to ``us-ascii`` if the string contains only ``ascii`` codepoints, and - ``utf-8`` otherwise. + to ``us-ascii`` if the string contains only ``ascii`` code points, and + ``utf-8`` otherwise. The *_charset* parameter accepts either a string or a + :class:`~email.charset.Charset` instance. Unless the *_charset* argument is explicitly set to ``None``, the MIMEText object created will have both a :mailheader:`Content-Type` header @@ -206,3 +207,6 @@ Here are the classes: ``Content-Transfer-Encoding`` header, after which a ``set_payload`` call will automatically encode the new payload (and add a new :mailheader:`Content-Transfer-Encoding` header). + + .. versionchanged:: 3.5 + *_charset* also accepts :class:`~email.charset.Charset` instances. diff --git a/Doc/library/email.parser.rst b/Doc/library/email.parser.rst index ee6af3fb392a..ec74fe028a58 100644 --- a/Doc/library/email.parser.rst +++ b/Doc/library/email.parser.rst @@ -60,15 +60,18 @@ list of defects that it can find. Here is the API for the :class:`FeedParser`: -.. class:: FeedParser(_factory=email.message.Message, *, policy=policy.default) +.. class:: FeedParser(_factory=email.message.Message, *, policy=policy.compat32) Create a :class:`FeedParser` instance. Optional *_factory* is a no-argument callable that will be called whenever a new message object is needed. It defaults to the :class:`email.message.Message` class. - The *policy* keyword specifies a :mod:`~email.policy` object that controls a - number of aspects of the parser's operation. The default policy maintains - backward compatibility. + If *policy* is specified (it must be an instance of a :mod:`~email.policy` + class) use the rules it specifies to update the representation of the + message. If *policy* is not set, use the :class:`compat32 + <email.policy.Compat32>` policy, which maintains backward compatibility with + the Python 3.2 version of the email package. For more information see the + :mod:`~email.policy` documentation. .. versionchanged:: 3.3 Added the *policy* keyword. @@ -113,7 +116,7 @@ have the same API as the :class:`Parser` and :class:`BytesParser` classes. The BytesHeaderParser class. -.. class:: Parser(_class=email.message.Message, *, policy=policy.default) +.. class:: Parser(_class=email.message.Message, *, policy=policy.compat32) The constructor for the :class:`Parser` class takes an optional argument *_class*. This must be a callable factory (such as a function or a class), and @@ -121,9 +124,12 @@ have the same API as the :class:`Parser` and :class:`BytesParser` classes. :class:`~email.message.Message` (see :mod:`email.message`). The factory will be called without arguments. - The *policy* keyword specifies a :mod:`~email.policy` object that controls a - number of aspects of the parser's operation. The default policy maintains - backward compatibility. + If *policy* is specified (it must be an instance of a :mod:`~email.policy` + class) use the rules it specifies to update the representation of the + message. If *policy* is not set, use the :class:`compat32 + <email.policy.Compat32>` policy, which maintains backward compatibility with + the Python 3.2 version of the email package. For more information see the + :mod:`~email.policy` documentation. .. versionchanged:: 3.3 Removed the *strict* argument that was deprecated in 2.4. Added the @@ -159,20 +165,23 @@ have the same API as the :class:`Parser` and :class:`BytesParser` classes. Optional *headersonly* is as with the :meth:`parse` method. -.. class:: BytesParser(_class=email.message.Message, *, policy=policy.default) +.. class:: BytesParser(_class=email.message.Message, *, policy=policy.compat32) This class is exactly parallel to :class:`Parser`, but handles bytes input. The *_class* and *strict* arguments are interpreted in the same way as for the :class:`Parser` constructor. - The *policy* keyword specifies a :mod:`~email.policy` object that - controls a number of aspects of the parser's operation. The default - policy maintains backward compatibility. + If *policy* is specified (it must be an instance of a :mod:`~email.policy` + class) use the rules it specifies to update the representation of the + message. If *policy* is not set, use the :class:`compat32 + <email.policy.Compat32>` policy, which maintains backward compatibility with + the Python 3.2 version of the email package. For more information see the + :mod:`~email.policy` documentation. .. versionchanged:: 3.3 Removed the *strict* argument. Added the *policy* keyword. - .. method:: parse(fp, headeronly=False) + .. method:: parse(fp, headersonly=False) Read all the data from the binary file-like object *fp*, parse the resulting bytes, and return the message object. *fp* must support @@ -209,7 +218,7 @@ in the top-level :mod:`email` package namespace. .. currentmodule:: email .. function:: message_from_string(s, _class=email.message.Message, *, \ - policy=policy.default) + policy=policy.compat32) Return a message object structure from a string. This is exactly equivalent to ``Parser().parsestr(s)``. *_class* and *policy* are interpreted as @@ -219,7 +228,7 @@ in the top-level :mod:`email` package namespace. Removed the *strict* argument. Added the *policy* keyword. .. function:: message_from_bytes(s, _class=email.message.Message, *, \ - policy=policy.default) + policy=policy.compat32) Return a message object structure from a byte string. This is exactly equivalent to ``BytesParser().parsebytes(s)``. Optional *_class* and @@ -231,7 +240,7 @@ in the top-level :mod:`email` package namespace. Removed the *strict* argument. Added the *policy* keyword. .. function:: message_from_file(fp, _class=email.message.Message, *, \ - policy=policy.default) + policy=policy.compat32) Return a message object structure tree from an open :term:`file object`. This is exactly equivalent to ``Parser().parse(fp)``. *_class* @@ -242,7 +251,7 @@ in the top-level :mod:`email` package namespace. Removed the *strict* argument. Added the *policy* keyword. .. function:: message_from_binary_file(fp, _class=email.message.Message, *, \ - policy=policy.default) + policy=policy.compat32) Return a message object structure tree from an open binary :term:`file object`. This is exactly equivalent to ``BytesParser().parse(fp)``. diff --git a/Doc/library/email.policy.rst b/Doc/library/email.policy.rst index c2f9e6a9abd4..d4e3fc186a50 100644 --- a/Doc/library/email.policy.rst +++ b/Doc/library/email.policy.rst @@ -99,7 +99,7 @@ separators. Some email package methods accept a *policy* keyword argument, allowing the policy to be overridden for that method. For example, the following code uses -the :meth:`~email.message.Message.as_string` method of the *msg* object from +the :meth:`~email.message.Message.as_bytes` method of the *msg* object from the previous example and writes the message to a file using the native line separators for the platform on which it is running:: @@ -419,7 +419,7 @@ added matters. To illustrate:: additional arguments. By default ``content_manager`` is set to :data:`~email.contentmanager.raw_data_manager`. - .. versionadded 3.4 + .. versionadded:: 3.4 The class provides the following concrete implementations of the abstract diff --git a/Doc/library/email.rst b/Doc/library/email.rst index 331d2ef0e4b2..95c0a2f4a860 100644 --- a/Doc/library/email.rst +++ b/Doc/library/email.rst @@ -91,15 +91,19 @@ table also describes the Python compatibility of each version of the package. +---------------+------------------------------+-----------------------+ | :const:`2.5` | Python 2.2.2+ and Python 2.3 | Python 2.1 to 2.5 | +---------------+------------------------------+-----------------------+ -| :const:`3.0` | Python 2.4 | Python 2.3 to 2.5 | +| :const:`3.0` | Python 2.4 and Python 2.5 | Python 2.3 to 2.6 | +---------------+------------------------------+-----------------------+ -| :const:`4.0` | Python 2.5 | Python 2.3 to 2.5 | +| :const:`4.0` | Python 2.5 to Python 2.7 | Python 2.3 to 2.7 | +---------------+------------------------------+-----------------------+ | :const:`5.0` | Python 3.0 and Python 3.1 | Python 3.0 to 3.2 | +---------------+------------------------------+-----------------------+ -| :const:`5.1` | Python 3.2 | Python 3.0 to 3.2 | +| :const:`5.1` | Python 3.2 | Python 3.2 | +---------------+------------------------------+-----------------------+ +After Version 5.1 (Python 3.2), the email package no longer has a version that +is separate from the Python version. (See the :ref:`whatsnew-index` documents +for the respective Python versions for details on changes.) + Here are the major differences between :mod:`email` version 5.1 and version 5.0: @@ -258,7 +262,7 @@ Differences from :mod:`mimelib` ------------------------------- The :mod:`email` package was originally prototyped as a separate library called -`mimelib <http://mimelib.sf.net/>`_. Changes have been made so that method names +`mimelib <http://mimelib.sourceforge.net/>`_. Changes have been made so that method names are more consistent, and some methods or modules have either been added or removed. The semantics of some of the methods have also changed. For the most part, any functionality available in :mod:`mimelib` is still available in the diff --git a/Doc/library/email.util.rst b/Doc/library/email.util.rst index f75975eaa922..219e2847ea2d 100644 --- a/Doc/library/email.util.rst +++ b/Doc/library/email.util.rst @@ -98,12 +98,9 @@ There are several useful utilities provided in the :mod:`email.utils` module: .. function:: mktime_tz(tuple) - Turn a 10-tuple as returned by :func:`parsedate_tz` into a UTC timestamp. It - the timezone item in the tuple is ``None``, assume local time. Minor - deficiency: :func:`mktime_tz` interprets the first 8 elements of *tuple* as a - local time and then compensates for the timezone difference. This may yield a - slight error around changes in daylight savings time, though not worth worrying - about for common use. + Turn a 10-tuple as returned by :func:`parsedate_tz` into a UTC + timestamp (seconds since the Epoch). If the timezone item in the + tuple is ``None``, assume local time. .. function:: formatdate(timeval=None, localtime=False, usegmt=False) @@ -210,4 +207,3 @@ There are several useful utilities provided in the :mod:`email.utils` module: .. [#] Note that the sign of the timezone offset is the opposite of the sign of the ``time.timezone`` variable for the same timezone; the latter variable follows the POSIX standard while this module follows :rfc:`2822`. - diff --git a/Doc/library/ensurepip.rst b/Doc/library/ensurepip.rst index 3756d4fbcb75..d589f1cf12f3 100644 --- a/Doc/library/ensurepip.rst +++ b/Doc/library/ensurepip.rst @@ -2,9 +2,11 @@ ======================================================== .. module:: ensurepip - :synopsis: Bootstrapping the ``pip`` installer into an existing Python + :synopsis: Bootstrapping the "pip" installer into an existing Python installation or virtual environment. +.. versionadded:: 3.4 + The :mod:`ensurepip` package provides support for bootstrapping the ``pip`` installer into an existing Python installation or virtual environment. This bootstrapping approach reflects the fact that ``pip`` is an independent @@ -18,8 +20,6 @@ needed if installing ``pip`` was skipped when installing Python (or when creating a virtual environment) or after explicitly uninstalling ``pip``. -.. versionadded:: 3.4 - .. note:: This module *does not* access the internet. All of the components @@ -28,7 +28,7 @@ when creating a virtual environment) or after explicitly uninstalling .. seealso:: - :ref:`install-index` + :ref:`installing-index` The end user guide for installing Python packages :pep:`453`: Explicit bootstrapping of pip in Python installations @@ -117,6 +117,12 @@ Module API *verbosity* controls the level of output to :data:`sys.stdout` from the bootstrapping operation. + .. note:: + + The bootstrapping process has side effects on both ``sys.path`` and + ``os.environ``. Invoking the command line interface in a subprocess + instead allows these side effects to be avoided. + .. note:: The bootstrapping process may install additional modules required by diff --git a/Doc/library/enum.rst b/Doc/library/enum.rst index c2030faf8bbd..d3b838c01c7e 100644 --- a/Doc/library/enum.rst +++ b/Doc/library/enum.rst @@ -9,18 +9,37 @@ .. :sectionauthor:: Eli Bendersky <eliben@gmail.com>, .. :sectionauthor:: Ethan Furman <ethan@stoneleaf.us> +.. versionadded:: 3.4 + **Source code:** :source:`Lib/enum.py` ---------------- -An enumeration is a set of symbolic names (members) bound to unique, constant -values. Within an enumeration, the members can be compared by identity, and -the enumeration itself can be iterated over. +An enumeration is a set of symbolic names (members) bound to unique, +constant values. Within an enumeration, the members can be compared +by identity, and the enumeration itself can be iterated over. + + +Module Contents +--------------- This module defines two enumeration classes that can be used to define unique sets of names and values: :class:`Enum` and :class:`IntEnum`. It also defines -one decorator, :func:`unique`, that ensures only unique member values are -present in an enumeration. +one decorator, :func:`unique`. + +.. class:: Enum + + Base class for creating enumerated constants. See section + `Functional API`_ for an alternate construction syntax. + +.. class:: IntEnum + + Base class for creating enumerated constants that are also + subclasses of :class:`int`. + +.. function:: unique + + Enum class decorator that ensures only one name is bound to any one value. Creating an Enum @@ -120,7 +139,7 @@ If you want to access enum members by *name*, use item access:: >>> Color['green'] <Color.green: 2> -If have an enum member and need its :attr:`name` or :attr:`value`:: +If you have an enum member and need its :attr:`name` or :attr:`value`:: >>> member = Color.red >>> member.name @@ -295,11 +314,11 @@ Then:: >>> str(Mood.funky) 'my custom str! 1' -The rules for what is allowed are as follows: _sunder_ names (starting and -ending with a single underscore) are reserved by enum and cannot be used; -all other attributes defined within an enumeration will become members of this -enumeration, with the exception of *__dunder__* names and descriptors (methods -are also descriptors). +The rules for what is allowed are as follows: names that start and end with a +with a single underscore are reserved by enum and cannot be used; all other +attributes defined within an enumeration will become members of this +enumeration, with the exception of special methods (:meth:`__str__`, +:meth:`__add__`, etc.) and descriptors (methods are also descriptors). Note: if your enumeration defines :meth:`__new__` and/or :meth:`__init__` then whatever value(s) were given to the enum member will be passed into those @@ -350,10 +369,13 @@ The usual restrictions for pickling apply: picklable enums must be defined in the top level of a module, since unpickling requires them to be importable from that module. -.. warning:: +.. note:: + + With pickle protocol version 4 it is possible to easily pickle enums + nested in other classes. - In order to support the singleton nature of enumeration members, pickle - protocol version 2 or higher must be used. +It is possible to modify how Enum members are pickled/unpickled by defining +:meth:`__reduce_ex__` in the enumeration class. Functional API @@ -378,11 +400,12 @@ The second argument is the *source* of enumeration member names. It can be a whitespace-separated string of names, a sequence of names, a sequence of 2-tuples with key/value pairs, or a mapping (e.g. dictionary) of names to values. The last two options enable assigning arbitrary values to -enumerations; the others auto-assign increasing integers starting with 1. A +enumerations; the others auto-assign increasing integers starting with 1 (use +the ``start`` parameter to specify a different starting value). A new class derived from :class:`Enum` is returned. In other words, the above assignment to :class:`Animal` is equivalent to:: - >>> class Animals(Enum): + >>> class Animal(Enum): ... ant = 1 ... bee = 2 ... cat = 3 @@ -399,7 +422,55 @@ enumeration is being created in (e.g. it will fail if you use a utility function in separate module, and also may not work on IronPython or Jython). The solution is to specify the module name explicitly as follows:: - >>> Animals = Enum('Animals', 'ant bee cat dog', module=__name__) + >>> Animal = Enum('Animal', 'ant bee cat dog', module=__name__) + +.. warning:: + + If ``module`` is not supplied, and Enum cannot determine what it is, + the new Enum members will not be unpicklable; to keep errors closer to + the source, pickling will be disabled. + +The new pickle protocol 4 also, in some circumstances, relies on +:attr:`__qualname__` being set to the location where pickle will be able +to find the class. For example, if the class was made available in class +SomeData in the global scope:: + + >>> Animal = Enum('Animal', 'ant bee cat dog', qualname='SomeData.Animal') + +The complete signature is:: + + Enum(value='NewEnumName', names=<...>, *, module='...', qualname='...', type=<mixed-in class>, start=1) + +:value: What the new Enum class will record as its name. + +:names: The Enum members. This can be a whitespace or comma separated string + (values will start at 1 unless otherwise specified):: + + 'red green blue' | 'red,green,blue' | 'red, green, blue' + + or an iterator of names:: + + ['red', 'green', 'blue'] + + or an iterator of (name, value) pairs:: + + [('cyan', 4), ('magenta', 5), ('yellow', 6)] + + or a mapping:: + + {'chartreuse': 7, 'sea_green': 11, 'rosemary': 42} + +:module: name of module where new Enum class can be found. + +:qualname: where in module new Enum class can be found. + +:type: type to mix in to new Enum class. + +:start: number to start counting at if only names are passed in + +.. versionchanged:: 3.5 + The *start* parameter was added. + Derived Enumerations -------------------- @@ -482,7 +553,7 @@ Some rules: add methods and don't specify another data type such as :class:`int` or :class:`str`. 3. When another data type is mixed in, the :attr:`value` attribute is *not the - same* as the enum member itself, although it is equivalant and will compare + same* as the enum member itself, although it is equivalent and will compare equal. 4. %-style formatting: `%s` and `%r` call :class:`Enum`'s :meth:`__str__` and :meth:`__repr__` respectively; other codes (such as `%i` or `%h` for @@ -525,8 +596,7 @@ Avoids having to specify the value for each enumeration member:: The :meth:`__new__` method, if defined, is used during creation of the Enum members; it is then replaced by Enum's :meth:`__new__` which is used after - class creation for lookup of existing members. Due to the way Enums are - supposed to behave, there is no way to customize Enum's :meth:`__new__`. + class creation for lookup of existing members. OrderedEnum @@ -682,7 +752,11 @@ but not of the class:: >>> dir(Planet.EARTH) ['__class__', '__doc__', '__module__', 'name', 'surface_gravity', 'value'] -A :meth:`__new__` method will only be used for the creation of the -:class:`Enum` members -- after that it is replaced. This means if you wish to -change how :class:`Enum` members are looked up you either have to write a -helper function or a :func:`classmethod`. +The :meth:`__new__` method will only be used for the creation of the +:class:`Enum` members -- after that it is replaced. Any custom :meth:`__new__` +method must create the object and set the :attr:`_value_` attribute +appropriately. + +If you wish to change how :class:`Enum` members are looked up you should either +write a helper function or a :func:`classmethod` for the :class:`Enum` +subclass. diff --git a/Doc/library/exceptions.rst b/Doc/library/exceptions.rst index 704abbbf2b82..58921547cad5 100644 --- a/Doc/library/exceptions.rst +++ b/Doc/library/exceptions.rst @@ -28,13 +28,14 @@ handler or to report an error condition "just like" the situation in which the interpreter raises the same exception; but beware that there is nothing to prevent user code from raising an inappropriate error. -The built-in exception classes can be sub-classed to define new exceptions; -programmers are encouraged to at least derive new exceptions from the -:exc:`Exception` class and not :exc:`BaseException`. More information on -defining exceptions is available in the Python Tutorial under +The built-in exception classes can be subclassed to define new exceptions; +programmers are encouraged to derive new exceptions from the :exc:`Exception` +class or one of its subclasses, and not from :exc:`BaseException`. More +information on defining exceptions is available in the Python Tutorial under :ref:`tut-userexceptions`. -When raising (or re-raising) an exception in an :keyword:`except` clause +When raising (or re-raising) an exception in an :keyword:`except` or +:keyword:`finally` clause :attr:`__context__` is automatically set to the last exception caught; if the new exception is not handled the traceback that is eventually displayed will include the originating exception(s) and the final exception. @@ -82,7 +83,7 @@ The following exceptions are used mostly as base classes for other exceptions. .. attribute:: args The tuple of arguments given to the exception constructor. Some built-in - exceptions (like :exc:`IOError`) expect a certain number of arguments and + exceptions (like :exc:`OSError`) expect a certain number of arguments and assign a special meaning to the elements of this tuple, while others are usually called only with a single string giving an error message. @@ -161,7 +162,7 @@ The following exceptions are the exceptions that are usually raised. .. exception:: GeneratorExit - Raise when a :term:`generator`\'s :meth:`close` method is called. It + Raised when a :term:`generator`\'s :meth:`close` method is called. It directly inherits from :exc:`BaseException` instead of :exc:`Exception` since it is technically not an error. @@ -253,6 +254,11 @@ The following exceptions are the exceptions that are usually raised. For exceptions that involve a file system path (such as :func:`open` or :func:`os.unlink`), the exception instance will contain an additional attribute, :attr:`filename`, which is the file name passed to the function. + For functions that involve two file system paths (such as + :func:`os.rename`), the exception instance will contain a second + :attr:`filename2` attribute corresponding to the second file name passed + to the function. + .. versionchanged:: 3.3 :exc:`EnvironmentError`, :exc:`IOError`, :exc:`WindowsError`, @@ -260,19 +266,19 @@ The following exceptions are the exceptions that are usually raised. :exc:`mmap.error` have been merged into :exc:`OSError`. .. versionchanged:: 3.4 - The :attr:`filename` attribute is now the original file name passed to the function, instead of the name encoded to or decoded from the - filesystem encoding. + filesystem encoding. Also, the :attr:`filename2` attribute was added. .. exception:: OverflowError Raised when the result of an arithmetic operation is too large to be represented. This cannot occur for integers (which would rather raise - :exc:`MemoryError` than give up). Because of the lack of standardization of - floating point exception handling in C, most floating point operations also - aren't checked. + :exc:`MemoryError` than give up). However, for historical reasons, + OverflowError is sometimes raised for integers that are outside a required + range. Because of the lack of standardization of floating point exception + handling in C, most floating point operations are not checked. .. exception:: ReferenceError @@ -453,10 +459,6 @@ starting from Python 3.3, they are aliases of :exc:`OSError`. .. exception:: IOError -.. exception:: VMSError - - Only available on VMS. - .. exception:: WindowsError Only available on Windows. diff --git a/Doc/library/faulthandler.rst b/Doc/library/faulthandler.rst index 61bc503d8f36..eb2016a7b9b8 100644 --- a/Doc/library/faulthandler.rst +++ b/Doc/library/faulthandler.rst @@ -4,12 +4,14 @@ .. module:: faulthandler :synopsis: Dump the Python traceback. +.. versionadded:: 3.3 + This module contains functions to dump Python tracebacks explicitly, on a fault, after a timeout, or on a user signal. Call :func:`faulthandler.enable` to install fault handlers for the :const:`SIGSEGV`, :const:`SIGFPE`, :const:`SIGABRT`, :const:`SIGBUS`, and :const:`SIGILL` signals. You can also enable them at startup by setting the :envvar:`PYTHONFAULTHANDLER` environment -variable or by using :option:`-X` ``faulthandler`` command line option. +variable or by using the :option:`-X` ``faulthandler`` command line option. The fault handler is compatible with system fault handlers like Apport or the Windows fault handler. The module uses an alternative stack for signal handlers @@ -36,11 +38,9 @@ alternatively be passed to :func:`faulthandler.enable`. The module is implemented in C, so tracebacks can be dumped on a crash or when Python is deadlocked. -.. versionadded:: 3.3 - -Dump the traceback ------------------- +Dumping the traceback +--------------------- .. function:: dump_traceback(file=sys.stderr, all_threads=True) @@ -69,8 +69,8 @@ Fault handler state Check if the fault handler is enabled. -Dump the tracebacks after a timeout ------------------------------------ +Dumping the tracebacks after a timeout +-------------------------------------- .. function:: dump_traceback_later(timeout, repeat=False, file=sys.stderr, exit=False) @@ -90,8 +90,8 @@ Dump the tracebacks after a timeout Cancel the last call to :func:`dump_traceback_later`. -Dump the traceback on a user signal ------------------------------------ +Dumping the traceback on a user signal +-------------------------------------- .. function:: register(signum, file=sys.stderr, all_threads=True, chain=False) @@ -110,8 +110,8 @@ Dump the traceback on a user signal Not available on Windows. -File descriptor issue ---------------------- +Issue with file descriptors +--------------------------- :func:`enable`, :func:`dump_traceback_later` and :func:`register` keep the file descriptor of their *file* argument. If the file is closed and its file @@ -123,9 +123,15 @@ these functions again each time that the file is replaced. Example ------- -Example of a segmentation fault on Linux: :: +.. highlight:: sh + +Example of a segmentation fault on Linux with and without enabling the fault +handler:: + + $ python3 -c "import ctypes; ctypes.string_at(0)" + Segmentation fault - $ python -q -X faulthandler + $ python3 -q -X faulthandler >>> import ctypes >>> ctypes.string_at(0) Fatal Python error: Segmentation fault diff --git a/Doc/library/filecmp.rst b/Doc/library/filecmp.rst index 8471a7263078..06d3f21300a7 100644 --- a/Doc/library/filecmp.rst +++ b/Doc/library/filecmp.rst @@ -28,8 +28,8 @@ The :mod:`filecmp` module defines the following functions: portability and efficiency. This function uses a cache for past comparisons and the results, - with a cache invalidation mechanism relying on stale signatures - or by explicitly calling :func:`clear_cache`. + with cache entries invalidated if the :func:`os.stat` information for the + file changes. The entire cache may be cleared using :func:`clear_cache`. .. function:: cmpfiles(dir1, dir2, common, shallow=True) @@ -54,12 +54,12 @@ The :mod:`filecmp` module defines the following functions: .. function:: clear_cache() - .. versionadded:: 3.4 - Clear the filecmp cache. This may be useful if a file is compared so quickly after it is modified that it is within the mtime resolution of the underlying filesystem. + .. versionadded:: 3.4 + .. _dircmp-objects: diff --git a/Doc/library/formatter.rst b/Doc/library/formatter.rst index bdc9e7b0e040..a515f74f64b0 100644 --- a/Doc/library/formatter.rst +++ b/Doc/library/formatter.rst @@ -3,8 +3,9 @@ .. module:: formatter :synopsis: Generic output formatter and device interface. + :deprecated: -.. deprecated:: 3.4 +.. deprecated-removed:: 3.4 3.6 Due to lack of usage, the formatter module has been deprecated and is slated for removal in Python 3.6. diff --git a/Doc/library/fractions.rst b/Doc/library/fractions.rst index fba199bf7877..c2c74013f046 100644 --- a/Doc/library/fractions.rst +++ b/Doc/library/fractions.rst @@ -99,7 +99,9 @@ another rational number, or from a string. value of *flt*, which must be a :class:`float`. Beware that ``Fraction.from_float(0.3)`` is not the same value as ``Fraction(3, 10)`` - .. note:: From Python 3.2 onwards, you can also construct a + .. note:: + + From Python 3.2 onwards, you can also construct a :class:`Fraction` instance directly from a :class:`float`. @@ -108,7 +110,9 @@ another rational number, or from a string. This class method constructs a :class:`Fraction` representing the exact value of *dec*, which must be a :class:`decimal.Decimal` instance. - .. note:: From Python 3.2 onwards, you can also construct a + .. note:: + + From Python 3.2 onwards, you can also construct a :class:`Fraction` instance directly from a :class:`decimal.Decimal` instance. diff --git a/Doc/library/ftplib.rst b/Doc/library/ftplib.rst index 7f98d0bd81b0..3b9f50ca49ef 100644 --- a/Doc/library/ftplib.rst +++ b/Doc/library/ftplib.rst @@ -80,14 +80,14 @@ The module defines the following items: :rfc:`4217`. Connect as usual to port 21 implicitly securing the FTP control connection before authenticating. Securing the data connection requires the user to - explicitly ask for it by calling the :meth:`prot_p` method. - *keyfile* and *certfile* are optional -- they can contain a PEM formatted - private key and certificate chain file name for the SSL connection. - *context* parameter is a :class:`ssl.SSLContext` object which allows - bundling SSL configuration options, certificates and private keys into a - single (potentially long-lived) structure. *source_address* is a 2-tuple - ``(host, port)`` for the socket to bind to as its source address before - connecting. + explicitly ask for it by calling the :meth:`prot_p` method. *context* + is a :class:`ssl.SSLContext` object which allows bundling SSL configuration + options, certificates and private keys into a single (potentially + long-lived) structure. Please read :ref:`ssl-security` for best practices. + + *keyfile* and *certfile* are a legacy alternative to *context* -- they + can point to PEM-formatted private key and certificate chain files + (respectively) for the SSL connection. .. versionadded:: 3.2 @@ -96,29 +96,18 @@ The module defines the following items: .. versionchanged:: 3.4 The class now supports hostname check with - :attr:`SSLContext.check_hostname` and *Server Name Indicator* (see - :data:`~ssl.HAS_SNI`). - - Here's a sample session using the :class:`FTP_TLS` class: - - >>> from ftplib import FTP_TLS - >>> ftps = FTP_TLS('ftp.python.org') - >>> ftps.login() # login anonymously before securing control channel - >>> ftps.prot_p() # switch to secure data connection - >>> ftps.retrlines('LIST') # list directory content securely - total 9 - drwxr-xr-x 8 root wheel 1024 Jan 3 1994 . - drwxr-xr-x 8 root wheel 1024 Jan 3 1994 .. - drwxr-xr-x 2 root wheel 1024 Jan 3 1994 bin - drwxr-xr-x 2 root wheel 1024 Jan 3 1994 etc - d-wxrwxr-x 2 ftp wheel 1024 Sep 5 13:43 incoming - drwxr-xr-x 2 root wheel 1024 Nov 17 1993 lib - drwxr-xr-x 6 1094 wheel 1024 Sep 13 19:07 pub - drwxr-xr-x 3 root wheel 1024 Jan 3 1994 usr - -rw-r--r-- 1 root root 312 Aug 1 1994 welcome.msg - '226 Transfer complete.' - >>> ftps.quit() - >>> + :attr:`ssl.SSLContext.check_hostname` and *Server Name Indication* (see + :data:`ssl.HAS_SNI`). + + Here's a sample session using the :class:`FTP_TLS` class:: + + >>> ftps = FTP_TLS('ftp.pureftpd.org') + >>> ftps.login() + '230 Anonymous user logged in' + >>> ftps.prot_p() + '200 Data protection level set to "private"' + >>> ftps.nlst() + ['6jack', 'OpenBSD', 'antilink', 'blogbench', 'bsdcam', 'clockspeed', 'djbdns-jedi', 'docs', 'eaccelerator-jedi', 'favicon.ico', 'francotone', 'fugu', 'ignore', 'libpuzzle', 'metalog', 'minidentd', 'misc', 'mysql-udf-global-user-variables', 'php-jenkins-hash', 'php-skein-hash', 'php-webdav', 'phpaudit', 'phpbench', 'pincaster', 'ping', 'posto', 'pub', 'public', 'public_keys', 'pure-ftpd', 'qscan', 'qtc', 'sharedance', 'skycache', 'sound', 'tmp', 'ucarp'] .. exception:: error_reply @@ -273,10 +262,10 @@ followed by ``lines`` for the text version or ``binary`` for the binary version. Passive mode is on by default. -.. method:: FTP.storbinary(cmd, file, blocksize=8192, callback=None, rest=None) +.. method:: FTP.storbinary(cmd, fp, blocksize=8192, callback=None, rest=None) Store a file in binary transfer mode. *cmd* should be an appropriate - ``STOR`` command: ``"STOR filename"``. *file* is a :term:`file object` + ``STOR`` command: ``"STOR filename"``. *fp* is a :term:`file object` (opened in binary mode) which is read until EOF using its :meth:`~io.IOBase.read` method in blocks of size *blocksize* to provide the data to be stored. The *blocksize* argument defaults to 8192. *callback* is an optional single @@ -287,11 +276,11 @@ followed by ``lines`` for the text version or ``binary`` for the binary version. *rest* parameter added. -.. method:: FTP.storlines(cmd, file, callback=None) +.. method:: FTP.storlines(cmd, fp, callback=None) Store a file in ASCII transfer mode. *cmd* should be an appropriate ``STOR`` command (see :meth:`storbinary`). Lines are read until EOF from the - :term:`file object` *file* (opened in binary mode) using its :meth:`~io.IOBase.readline` + :term:`file object` *fp* (opened in binary mode) using its :meth:`~io.IOBase.readline` method to provide the data to be stored. *callback* is an optional single parameter callable that is called on each line after it is sent. @@ -425,7 +414,7 @@ FTP_TLS Objects .. attribute:: FTP_TLS.ssl_version - The SSL version to use (defaults to *TLSv1*). + The SSL version to use (defaults to :attr:`ssl.PROTOCOL_SSLv23`). .. method:: FTP_TLS.auth() @@ -434,8 +423,8 @@ FTP_TLS Objects .. versionchanged:: 3.4 The method now supports hostname check with - :attr:`SSLContext.check_hostname` and *Server Name Indicator* (see - :data:`~ssl.HAS_SNI`). + :attr:`ssl.SSLContext.check_hostname` and *Server Name Indication* (see + :data:`ssl.HAS_SNI`). .. method:: FTP_TLS.ccc() diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index fb4fc7f350be..eb285133a452 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -85,22 +85,22 @@ are always available. They are listed here in alphabetical order. :meth:`__index__` method that returns an integer. -.. function:: bool([x]) +.. class:: bool([x]) - Convert a value to a Boolean, using the standard :ref:`truth testing - procedure <truth>`. If *x* is false or omitted, this returns ``False``; - otherwise it returns ``True``. :class:`bool` is also a class, which is a - subclass of :class:`int` (see :ref:`typesnumeric`). Class :class:`bool` - cannot be subclassed further. Its only instances are ``False`` and + Return a Boolean value, i.e. one of ``True`` or ``False``. *x* is converted + using the standard :ref:`truth testing procedure <truth>`. If *x* is false + or omitted, this returns ``False``; otherwise it returns ``True``. The + :class:`bool` class is a subclass of :class:`int` (see :ref:`typesnumeric`). + It cannot be subclassed further. Its only instances are ``False`` and ``True`` (see :ref:`bltin-boolean-values`). .. index:: pair: Boolean; type .. _func-bytearray: -.. function:: bytearray([source[, encoding[, errors]]]) +.. class:: bytearray([source[, encoding[, errors]]]) - Return a new array of bytes. The :class:`bytearray` type is a mutable + Return a new array of bytes. The :class:`bytearray` class is a mutable sequence of integers in the range 0 <= x < 256. It has most of the usual methods of mutable sequences, described in :ref:`typesseq-mutable`, as well as most methods that the :class:`bytes` type has, see :ref:`bytes-methods`. @@ -127,7 +127,7 @@ are always available. They are listed here in alphabetical order. .. _func-bytes: -.. function:: bytes([source[, encoding[, errors]]]) +.. class:: bytes([source[, encoding[, errors]]]) Return a new "bytes" object, which is an immutable sequence of integers in the range ``0 <= x < 256``. :class:`bytes` is an immutable version of @@ -156,11 +156,12 @@ are always available. They are listed here in alphabetical order. .. function:: chr(i) - Return the string representing a character whose Unicode codepoint is the integer - *i*. For example, ``chr(97)`` returns the string ``'a'``. This is the - inverse of :func:`ord`. The valid range for the argument is from 0 through - 1,114,111 (0x10FFFF in base 16). :exc:`ValueError` will be raised if *i* is - outside that range. + Return the string representing a character whose Unicode code point is the + integer *i*. For example, ``chr(97)`` returns the string ``'a'``, while + ``chr(931)`` returns the string ``'Σ'``. This is the inverse of :func:`ord`. + + The valid range for the argument is from 0 through 1,114,111 (0x10FFFF in + base 16). :exc:`ValueError` will be raised if *i* is outside that range. .. function:: classmethod(function) @@ -193,9 +194,9 @@ are always available. They are listed here in alphabetical order. .. function:: compile(source, filename, mode, flags=0, dont_inherit=False, optimize=-1) Compile the *source* into a code or AST object. Code objects can be executed - by :func:`exec` or :func:`eval`. *source* can either be a string or an AST - object. Refer to the :mod:`ast` module documentation for information on how - to work with AST objects. + by :func:`exec` or :func:`eval`. *source* can either be a normal string, a + byte string, or an AST object. Refer to the :mod:`ast` module documentation + for information on how to work with AST objects. The *filename* argument should give the file from which the code was read; pass some recognizable value if it wasn't read from a file (``'<string>'`` is @@ -210,7 +211,7 @@ are always available. They are listed here in alphabetical order. The optional arguments *flags* and *dont_inherit* control which future statements (see :pep:`236`) affect the compilation of *source*. If neither is present (or both are zero) the code is compiled with those future - statements that are in effect in the code that is calling compile. If the + statements that are in effect in the code that is calling :func:`compile`. If the *flags* argument is given and *dont_inherit* is not (or is zero) then the future statements specified by the *flags* argument are used in addition to those that would be used anyway. If *dont_inherit* is a non-zero integer then @@ -231,6 +232,9 @@ are always available. They are listed here in alphabetical order. This function raises :exc:`SyntaxError` if the compiled source is invalid, and :exc:`TypeError` if the source contains null bytes. + If you want to parse Python code into its AST representation, see + :func:`ast.parse`. + .. note:: When compiling a string with multi-line code in ``'single'`` or @@ -243,15 +247,16 @@ are always available. They are listed here in alphabetical order. does not have to end in a newline anymore. Added the *optimize* parameter. -.. function:: complex([real[, imag]]) +.. class:: complex([real[, imag]]) - Create a complex number with the value *real* + *imag*\*j or convert a string or - number to a complex number. If the first parameter is a string, it will be - interpreted as a complex number and the function must be called without a second - parameter. The second parameter can never be a string. Each argument may be any - numeric type (including complex). If *imag* is omitted, it defaults to zero and - the function serves as a numeric conversion function like :func:`int` - and :func:`float`. If both arguments are omitted, returns ``0j``. + Return a complex number with the value *real* + *imag*\*j or convert a string + or number to a complex number. If the first parameter is a string, it will + be interpreted as a complex number and the function must be called without a + second parameter. The second parameter can never be a string. Each argument + may be any numeric type (including complex). If *imag* is omitted, it + defaults to zero and the constructor serves as a numeric conversion like + :class:`int` and :class:`float`. If both arguments are omitted, returns + ``0j``. .. note:: @@ -272,14 +277,13 @@ are always available. They are listed here in alphabetical order. .. _func-dict: -.. function:: dict(**kwarg) - dict(mapping, **kwarg) - dict(iterable, **kwarg) +.. class:: dict(**kwarg) + dict(mapping, **kwarg) + dict(iterable, **kwarg) :noindex: Create a new dictionary. The :class:`dict` object is the dictionary class. - See :class:`dict` and :ref:`typesmapping` for documentation about this - class. + See :class:`dict` and :ref:`typesmapping` for documentation about this class. For other containers see the built-in :class:`list`, :class:`set`, and :class:`tuple` classes, as well as the :mod:`collections` module. @@ -410,6 +414,7 @@ are always available. They are listed here in alphabetical order. See :func:`ast.literal_eval` for a function that can safely evaluate strings with expressions containing only literals. +.. index:: builtin: exec .. function:: exec(object[, globals[, locals]]) @@ -469,13 +474,13 @@ are always available. They are listed here in alphabetical order. elements of *iterable* for which *function* returns false. -.. function:: float([x]) +.. class:: float([x]) .. index:: single: NaN single: Infinity - Convert a string or a number to floating point. + Return a floating point number constructed from a number or string *x*. If the argument is a string, it should contain a decimal number, optionally preceded by a sign, and optionally embedded in whitespace. The optional @@ -538,18 +543,19 @@ are always available. They are listed here in alphabetical order. effect as calling :func:`str(value) <str>`. A call to ``format(value, format_spec)`` is translated to - ``type(value).__format__(format_spec)`` which bypasses the instance + ``type(value).__format__(value, format_spec)`` which bypasses the instance dictionary when searching for the value's :meth:`__format__` method. A - :exc:`TypeError` exception is raised if the method is not found or if either - the *format_spec* or the return value are not strings. + :exc:`TypeError` exception is raised if the method search reaches + :mod:`object` and the *format_spec* is non-empty, or if either the + *format_spec* or the return value are not strings. - .. versionadded:: 3.4 + .. versionchanged:: 3.4 ``object().__format__(format_spec)`` raises :exc:`TypeError` - if *format_spec* is not empty string. + if *format_spec* is not an empty string. .. _func-frozenset: -.. function:: frozenset([iterable]) +.. class:: frozenset([iterable]) :noindex: Return a new :class:`frozenset` object, optionally with elements taken from @@ -609,12 +615,26 @@ are always available. They are listed here in alphabetical order. This function is added to the built-in namespace by the :mod:`site` module. + .. versionchanged:: 3.4 + Changes to :mod:`pydoc` and :mod:`inspect` mean that the reported + signatures for callables are now more comprehensive and consistent. + .. function:: hex(x) - Convert an integer number to a hexadecimal string. The result is a valid Python - expression. If *x* is not a Python :class:`int` object, it has to define an - :meth:`__index__` method that returns an integer. + Convert an integer number to a lowercase hexadecimal string + prefixed with "0x", for example: + + >>> hex(255) + '0xff' + >>> hex(-42) + '-0x2a' + + If x is not a Python :class:`int` object, it has to define an __index__() + method that returns an integer. + + See also :func:`int` for converting a hexadecimal string to an + integer using a base of 16. .. note:: @@ -648,12 +668,13 @@ are always available. They are listed here in alphabetical order. to provide elaborate line editing and history features. -.. function:: int(x=0) - int(x, base=10) +.. class:: int(x=0) + int(x, base=10) - Convert a number or string *x* to an integer, or return ``0`` if no - arguments are given. If *x* is a number, return :meth:`x.__int__() - <object.__int__>`. For floating point numbers, this truncates towards zero. + Return an integer object constructed from a number or string *x*, or return + ``0`` if no arguments are given. If *x* is a number, return + :meth:`x.__int__() <object.__int__>`. For floating point numbers, this + truncates towards zero. If *x* is not a number or if *base* is given, then *x* must be a string, :class:`bytes`, or :class:`bytearray` instance representing an :ref:`integer @@ -727,11 +748,12 @@ are always available. They are listed here in alphabetical order. .. function:: len(s) Return the length (the number of items) of an object. The argument may be a - sequence (string, tuple or list) or a mapping (dictionary). + sequence (such as a string, bytes, tuple, list, or range) or a collection + (such as a dictionary, set, or frozen set). .. _func-list: -.. function:: list([iterable]) +.. class:: list([iterable]) :noindex: Rather than being a function, :class:`list` is actually a mutable @@ -758,7 +780,7 @@ are always available. They are listed here in alphabetical order. already arranged into argument tuples, see :func:`itertools.starmap`\. -.. function:: max(iterable, *[, default, key]) +.. function:: max(iterable, *[, key, default]) max(arg1, arg2, *args[, key]) Return the largest item in an iterable or the largest of two or more @@ -766,7 +788,7 @@ are always available. They are listed here in alphabetical order. If one positional argument is provided, it should be an :term:`iterable`. The largest item in the iterable is returned. If two or more positional - arguments are provided, the smallest of the positional arguments is + arguments are provided, the largest of the positional arguments is returned. There are two optional keyword-only arguments. The *key* argument specifies @@ -780,6 +802,9 @@ are always available. They are listed here in alphabetical order. such as ``sorted(iterable, key=keyfunc, reverse=True)[0]`` and ``heapq.nlargest(1, iterable, key=keyfunc)``. + .. versionadded:: 3.4 + The *default* keyword-only argument. + .. _func-memoryview: .. function:: memoryview(obj) @@ -789,7 +814,7 @@ are always available. They are listed here in alphabetical order. :ref:`typememoryview` for more information. -.. function:: min(iterable, *[, default, key]) +.. function:: min(iterable, *[, key, default]) min(arg1, arg2, *args[, key]) Return the smallest item in an iterable or the smallest of two or more @@ -811,6 +836,10 @@ are always available. They are listed here in alphabetical order. such as ``sorted(iterable, key=keyfunc)[0]`` and ``heapq.nsmallest(1, iterable, key=keyfunc)``. + .. versionadded:: 3.4 + The *default* keyword-only argument. + + .. function:: next(iterator[, default]) Retrieve the next item from the *iterator* by calling its @@ -818,7 +847,7 @@ are always available. They are listed here in alphabetical order. if the iterator is exhausted, otherwise :exc:`StopIteration` is raised. -.. function:: object() +.. class:: object() Return a new featureless object. :class:`object` is a base for all classes. It has the methods that are common to all instances of Python classes. This @@ -911,15 +940,17 @@ are always available. They are listed here in alphabetical order. *encoding* is the name of the encoding used to decode or encode the file. This should only be used in text mode. The default encoding is platform dependent (whatever :func:`locale.getpreferredencoding` returns), but any - encoding supported by Python can be used. See the :mod:`codecs` module for + :term:`text encoding` supported by Python + can be used. See the :mod:`codecs` module for the list of supported encodings. *errors* is an optional string that specifies how encoding and decoding errors are to be handled--this cannot be used in binary mode. - A variety of standard error handlers are available, though any + A variety of standard error handlers are available + (listed under :ref:`error-handlers`), though any error handling name that has been registered with :func:`codecs.register_error` is also valid. The standard names - are: + include: * ``'strict'`` to raise a :exc:`ValueError` exception if there is an encoding error. The default value of ``None`` has the same @@ -942,9 +973,11 @@ are always available. They are listed here in alphabetical order. Characters not supported by the encoding are replaced with the appropriate XML character reference ``&#nnn;``. - * ``'backslashreplace'`` (also only supported when writing) - replaces unsupported characters with Python's backslashed escape - sequences. + * ``'backslashreplace'`` replaces malformed data by Python's backslashed + escape sequences. + + * ``'namereplace'`` (also only supported when writing) + replaces unsupported characters with ``\N{...}`` escape sequences. .. index:: single: universal newlines; open() built-in function @@ -969,8 +1002,8 @@ are always available. They are listed here in alphabetical order. If *closefd* is ``False`` and a file descriptor rather than a filename was given, the underlying file descriptor will be kept open when the file is - closed. If a filename is given *closefd* has no effect and must be ``True`` - (the default). + closed. If a filename is given *closefd* must be ``True`` (the default) + otherwise an error will be raised. A custom opener can be used by passing a callable as *opener*. The underlying file descriptor for the file object is then obtained by calling *opener* with @@ -1029,16 +1062,16 @@ are always available. They are listed here in alphabetical order. The file is now non-inheritable. .. deprecated-removed:: 3.4 4.0 + The ``'U'`` mode. -.. XXX works for bytes too, but should it? .. function:: ord(c) Given a string representing one Unicode character, return an integer - representing the Unicode code - point of that character. For example, ``ord('a')`` returns the integer ``97`` - and ``ord('\u2020')`` returns ``8224``. This is the inverse of :func:`chr`. + representing the Unicode code point of that character. For example, + ``ord('a')`` returns the integer ``97`` and ``ord('Σ')`` returns ``931``. + This is the inverse of :func:`chr`. .. function:: pow(x, y[, z]) @@ -1059,8 +1092,8 @@ are always available. They are listed here in alphabetical order. .. function:: print(*objects, sep=' ', end='\\n', file=sys.stdout, flush=False) - Print *objects* to the stream *file*, separated by *sep* and followed by - *end*. *sep*, *end* and *file*, if present, must be given as keyword + Print *objects* to the text stream *file*, separated by *sep* and followed + by *end*. *sep*, *end* and *file*, if present, must be given as keyword arguments. All non-keyword arguments are converted to strings like :func:`str` does and @@ -1070,21 +1103,26 @@ are always available. They are listed here in alphabetical order. *end*. The *file* argument must be an object with a ``write(string)`` method; if it - is not present or ``None``, :data:`sys.stdout` will be used. Whether output - is buffered is usually determined by *file*, but if the *flush* keyword - argument is true, the stream is forcibly flushed. + is not present or ``None``, :data:`sys.stdout` will be used. Since printed + arguments are converted to text strings, :func:`print` cannot be used with + binary mode file objects. For these, use ``file.write(...)`` instead. + + Whether output is buffered is usually determined by *file*, but if the + *flush* keyword argument is true, the stream is forcibly flushed. .. versionchanged:: 3.3 Added the *flush* keyword argument. -.. function:: property(fget=None, fset=None, fdel=None, doc=None) +.. class:: property(fget=None, fset=None, fdel=None, doc=None) Return a property attribute. - *fget* is a function for getting an attribute value, likewise *fset* is a - function for setting, and *fdel* a function for del'ing, an attribute. Typical - use is to define a managed attribute ``x``:: + *fget* is a function for getting an attribute value. *fset* is a function + for setting an attribute value. *fdel* is a function for deleting an attribute + value. And *doc* creates a docstring for the attribute. + + A typical use is to define a managed attribute ``x``:: class C: def __init__(self): @@ -1092,13 +1130,16 @@ are always available. They are listed here in alphabetical order. def getx(self): return self._x + def setx(self, value): self._x = value + def delx(self): del self._x + x = property(getx, setx, delx, "I'm the 'x' property.") - If then *c* is an instance of *C*, ``c.x`` will invoke the getter, + If *c* is an instance of *C*, ``c.x`` will invoke the getter, ``c.x = value`` will invoke the setter and ``del c.x`` the deleter. If given, *doc* will be the docstring of the property attribute. Otherwise, the @@ -1114,8 +1155,9 @@ are always available. They are listed here in alphabetical order. """Get the current voltage.""" return self._voltage - turns the :meth:`voltage` method into a "getter" for a read-only attribute - with the same name. + The ``@property`` decorator turns the :meth:`voltage` method into a "getter" + for a read-only attribute with the same name, and it sets the docstring for + *voltage* to "Get the current voltage." A property object has :attr:`~property.getter`, :attr:`~property.setter`, and :attr:`~property.deleter` methods usable as decorators that create a @@ -1143,7 +1185,7 @@ are always available. They are listed here in alphabetical order. additional functions the same name as the original property (``x`` in this case.) - The returned property also has the attributes ``fget``, ``fset``, and + The returned property object also has the attributes ``fget``, ``fset``, and ``fdel`` corresponding to the constructor arguments. @@ -1198,7 +1240,7 @@ are always available. They are listed here in alphabetical order. .. _func-set: -.. function:: set([iterable]) +.. class:: set([iterable]) :noindex: Return a new :class:`set` object, optionally with elements taken from @@ -1219,8 +1261,8 @@ are always available. They are listed here in alphabetical order. ``x.foobar = 123``. -.. function:: slice(stop) - slice(start, stop[, step]) +.. class:: slice(stop) + slice(start, stop[, step]) .. index:: single: Numerical Python @@ -1251,8 +1293,13 @@ are always available. They are listed here in alphabetical order. Use :func:`functools.cmp_to_key` to convert an old-style *cmp* function to a *key* function. + The built-in :func:`sorted` function is guaranteed to be stable. A sort is + stable if it guarantees not to change the relative order of elements that + compare equal --- this is helpful for sorting in multiple passes (for + example, sort by department, then by salary grade). + For sorting examples and a brief sorting tutorial, see `Sorting HowTo - <http://wiki.python.org/moin/HowTo/Sorting/>`_\. + <https://wiki.python.org/moin/HowTo/Sorting/>`_\. .. function:: staticmethod(function) @@ -1283,8 +1330,8 @@ are always available. They are listed here in alphabetical order. .. _func-str: -.. function:: str(object='') - str(object=b'', encoding='utf-8', errors='strict') +.. class:: str(object='') + str(object=b'', encoding='utf-8', errors='strict') :noindex: Return a :class:`str` version of *object*. See :func:`str` for details. @@ -1371,12 +1418,11 @@ are always available. They are listed here in alphabetical order. sequence type, as documented in :ref:`typesseq-tuple` and :ref:`typesseq`. -.. function:: type(object) - type(name, bases, dict) +.. class:: type(object) + type(name, bases, dict) .. index:: object: type - With one argument, return the type of an *object*. The return value is a type object and generally the same object as returned by :attr:`object.__class__ <instance.__class__>`. diff --git a/Doc/library/functools.rst b/Doc/library/functools.rst index 77cd8384b1ff..46aa88767ea9 100644 --- a/Doc/library/functools.rst +++ b/Doc/library/functools.rst @@ -21,8 +21,8 @@ The :mod:`functools` module defines the following functions: .. function:: cmp_to_key(func) - Transform an old-style comparison function to a key function. Used with - tools that accept key functions (such as :func:`sorted`, :func:`min`, + Transform an old-style comparison function to a :term:`key function`. Used + with tools that accept key functions (such as :func:`sorted`, :func:`min`, :func:`max`, :func:`heapq.nlargest`, :func:`heapq.nsmallest`, :func:`itertools.groupby`). This function is primarily used as a transition tool for programs being converted from Python 2 which supported the use of @@ -31,13 +31,14 @@ The :mod:`functools` module defines the following functions: A comparison function is any callable that accept two arguments, compares them, and returns a negative number for less-than, zero for equality, or a positive number for greater-than. A key function is a callable that accepts one - argument and returns another value indicating the position in the desired - collation sequence. + argument and returns another value to be used as the sort key. Example:: sorted(iterable, key=cmp_to_key(locale.strcoll)) # locale-aware sort order + For sorting examples and a brief sorting tutorial, see :ref:`sortinghowto`. + .. versionadded:: 3.2 @@ -72,7 +73,7 @@ The :mod:`functools` module defines the following functions: bypassing the cache, or for rewrapping the function with a different cache. An `LRU (least recently used) cache - <http://en.wikipedia.org/wiki/Cache_algorithms#Least_Recently_Used>`_ works + <http://en.wikipedia.org/wiki/Cache_algorithms#Examples>`_ works best when the most recent calls are the best predictors of upcoming calls (for example, the most popular articles on a news server tend to change each day). The cache's size limit assures that the cache does not grow without bound on @@ -218,6 +219,8 @@ The :mod:`functools` module defines the following functions: Example:: >>> class Cell(object): + ... def __init__(self): + ... self._alive = False ... @property ... def alive(self): ... return self._alive @@ -247,7 +250,7 @@ The :mod:`functools` module defines the following functions: a default when the sequence is empty. If *initializer* is not given and *sequence* contains only one item, the first item is returned. - Equivalent to:: + Roughly equivalent to:: def reduce(function, iterable, initializer=None): it = iter(iterable) @@ -411,9 +414,10 @@ The :mod:`functools` module defines the following functions: .. decorator:: wraps(wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES) - This is a convenience function for invoking ``partial(update_wrapper, - wrapped=wrapped, assigned=assigned, updated=updated)`` as a function decorator - when defining a wrapper function. For example: + This is a convenience function for invoking :func:`update_wrapper` as a + function decorator when defining a wrapper function. It is equivalent to + ``partial(update_wrapper, wrapped=wrapped, assigned=assigned, updated=updated)``. + For example:: >>> from functools import wraps >>> def my_decorator(f): diff --git a/Doc/library/gc.rst b/Doc/library/gc.rst index 6b95dc564526..d11c2e128273 100644 --- a/Doc/library/gc.rst +++ b/Doc/library/gc.rst @@ -69,9 +69,10 @@ The :mod:`gc` module provides the following functions: .. function:: get_stats() - Return a list of 3 per-generation dictionaries containing collection - statistics since interpreter start. At this moment, each dictionary will - contain the following items: + Return a list of three per-generation dictionaries containing collection + statistics since interpreter start. The number of keys may change + in the future, but currently each dictionary will contain the following + items: * ``collections`` is the number of times this generation was collected; @@ -185,7 +186,7 @@ values but should not rebind them): added to this list rather than freed. .. versionchanged:: 3.2 - If this list is non-empty at interpreter shutdown, a + If this list is non-empty at :term:`interpreter shutdown`, a :exc:`ResourceWarning` is emitted, which is silent by default. If :const:`DEBUG_UNCOLLECTABLE` is set, in addition all uncollectable objects are printed. @@ -251,8 +252,8 @@ The following constants are provided for use with :func:`set_debug`: to the ``garbage`` list. .. versionchanged:: 3.2 - Also print the contents of the :data:`garbage` list at interpreter - shutdown, if it isn't empty. + Also print the contents of the :data:`garbage` list at + :term:`interpreter shutdown`, if it isn't empty. .. data:: DEBUG_SAVEALL diff --git a/Doc/library/getopt.rst b/Doc/library/getopt.rst index b6ab3df02286..f9a1e53e38ba 100644 --- a/Doc/library/getopt.rst +++ b/Doc/library/getopt.rst @@ -10,6 +10,7 @@ -------------- .. note:: + The :mod:`getopt` module is a parser for command line options whose API is designed to be familiar to users of the C :c:func:`getopt` function. Users who are unfamiliar with the C :c:func:`getopt` function or who would like to write diff --git a/Doc/library/getpass.rst b/Doc/library/getpass.rst index ffe2b1256ba5..211563e23e56 100644 --- a/Doc/library/getpass.rst +++ b/Doc/library/getpass.rst @@ -13,10 +13,11 @@ The :mod:`getpass` module provides two functions: .. function:: getpass(prompt='Password: ', stream=None) Prompt the user for a password without echoing. The user is prompted using - the string *prompt*, which defaults to ``'Password: '``. On Unix, the prompt - is written to the file-like object *stream*. *stream* defaults to the - controlling terminal (:file:`/dev/tty`) or if that is unavailable to - ``sys.stderr`` (this argument is ignored on Windows). + the string *prompt*, which defaults to ``'Password: '``. On Unix, the + prompt is written to the file-like object *stream* using the replace error + handler if needed. *stream* defaults to the controlling terminal + (:file:`/dev/tty`) or if that is unavailable to ``sys.stderr`` (this + argument is ignored on Windows). If echo free input is unavailable getpass() falls back to printing a warning message to *stream* and reading from ``sys.stdin`` and diff --git a/Doc/library/gettext.rst b/Doc/library/gettext.rst index 982780fec15b..514cc5a9893f 100644 --- a/Doc/library/gettext.rst +++ b/Doc/library/gettext.rst @@ -344,9 +344,9 @@ will assume message ids as Unicode strings, not byte strings. The entire set of key/value pairs are placed into a dictionary and set as the "protected" :attr:`_info` instance variable. -If the :file:`.mo` file's magic number is invalid, or if other problems occur -while reading the file, instantiating a :class:`GNUTranslations` class can raise -:exc:`OSError`. +If the :file:`.mo` file's magic number is invalid, the major version number is +unexpected, or if other problems occur while reading the file, instantiating a +:class:`GNUTranslations` class can raise :exc:`OSError`. The following methods are overridden from the base class implementation: @@ -460,7 +460,7 @@ translatable. `Babel <http://babel.pocoo.org/>`__ is a Python internationalization library that includes a :file:`pybabel` script to extract and compile message catalogs. François Pinard's program called :program:`xpot` does a similar job and is available as part of -his `po-utils package <http://po-utils.progiciels-bpi.ca/>`__. +his `po-utils package <https://github.com/pinard/po-utils>`__. (Python also includes pure-Python versions of these programs, called :program:`pygettext.py` and :program:`msgfmt.py`; some Python distributions diff --git a/Doc/library/glob.rst b/Doc/library/glob.rst index abcbf380d95e..50f38a4d3656 100644 --- a/Doc/library/glob.rst +++ b/Doc/library/glob.rst @@ -29,7 +29,7 @@ For example, ``'[?]'`` matches the character ``'?'``. The :mod:`pathlib` module offers high-level path objects. -.. function:: glob(pathname) +.. function:: glob(pathname, *, recursive=False) Return a possibly-empty list of path names that match *pathname*, which must be a string containing a path specification. *pathname* can be either absolute @@ -37,8 +37,19 @@ For example, ``'[?]'`` matches the character ``'?'``. :file:`../../Tools/\*/\*.gif`), and can contain shell-style wildcards. Broken symlinks are included in the results (as in the shell). + If *recursive* is true, the pattern "``**``" will match any files and zero or + more directories and subdirectories. If the pattern is followed by a + ``os.sep``, only directories and subdirectories match. -.. function:: iglob(pathname) + .. note:: + Using the "``**``" pattern in large directory trees may consume + an inordinate amount of time. + + .. versionchanged:: 3.5 + Support for recursive globs using "``**``". + + +.. function:: iglob(pathname, recursive=False) Return an :term:`iterator` which yields the same values as :func:`glob` without actually storing them all simultaneously. @@ -55,8 +66,9 @@ For example, ``'[?]'`` matches the character ``'?'``. .. versionadded:: 3.4 -For example, consider a directory containing only the following files: -:file:`1.gif`, :file:`2.txt`, and :file:`card.gif`. :func:`glob` will produce +For example, consider a directory containing the following files: +:file:`1.gif`, :file:`2.txt`, :file:`card.gif` and a subdirectory :file:`sub` +which contains only the file :file:`3.txt`. :func:`glob` will produce the following results. Notice how any leading components of the path are preserved. :: @@ -67,6 +79,10 @@ preserved. :: ['1.gif', 'card.gif'] >>> glob.glob('?.gif') ['1.gif'] + >>> glob.glob('**/*.txt', recursive=True) + ['2.txt', 'sub/3.txt'] + >>> glob.glob('./**/', recursive=True) + ['./', './sub/'] If the directory contains files starting with ``.`` they won't be matched by default. For example, consider a directory containing :file:`card.gif` and diff --git a/Doc/library/gzip.rst b/Doc/library/gzip.rst index de5063a7c7cf..78536fab51d9 100644 --- a/Doc/library/gzip.rst +++ b/Doc/library/gzip.rst @@ -117,6 +117,11 @@ The module defines the following items: the call. The number of bytes returned may be more or less than requested. + .. note:: While calling :meth:`peek` does not change the file position of + the :class:`GzipFile`, it may change the position of the underlying + file object (e.g. if the :class:`GzipFile` was constructed with the + *fileobj* parameter). + .. versionadded:: 3.2 .. versionchanged:: 3.1 diff --git a/Doc/library/hashlib.rst b/Doc/library/hashlib.rst index b1daba124ffb..e0a877a71d0d 100644 --- a/Doc/library/hashlib.rst +++ b/Doc/library/hashlib.rst @@ -33,6 +33,8 @@ digests. The modern term is secure hash. also" section at the end. +.. _hash-algorithms: + Hash algorithms --------------- @@ -58,13 +60,9 @@ concatenation of the data fed to it so far using the :meth:`digest` or Constructors for hash algorithms that are always present in this module are :func:`md5`, :func:`sha1`, :func:`sha224`, :func:`sha256`, :func:`sha384`, -:func:`sha512`, :func:`sha3_224`, :func:`sha3_256`, :func:`sha3_384`, and -:func:`sha3_512`. Additional algorithms may also be available depending upon +and :func:`sha512`. Additional algorithms may also be available depending upon the OpenSSL library that Python uses on your platform. - .. versionchanged:: 3.4 - Add sha3 family of hash algorithms. - For example, to obtain the digest of the byte string ``b'Nobody inspects the spammish repetition'``:: @@ -103,18 +101,18 @@ Hashlib provides the following constant attributes: .. data:: algorithms_guaranteed - Contains the names of the hash algorithms guaranteed to be supported + A set containing the names of the hash algorithms guaranteed to be supported by this module on all platforms. .. versionadded:: 3.2 .. data:: algorithms_available - Contains the names of the hash algorithms that are available - in the running Python interpreter. These names will be recognized - when passed to :func:`new`. :attr:`algorithms_guaranteed` - will always be a subset. Duplicate algorithms with different - name formats may appear in this set (thanks to OpenSSL). + A set containing the names of the hash algorithms that are available in the + running Python interpreter. These names will be recognized when passed to + :func:`new`. :attr:`algorithms_guaranteed` will always be a subset. The + same algorithm may appear multiple times in this set under different names + (thanks to OpenSSL). .. versionadded:: 3.2 @@ -182,9 +180,9 @@ Key Derivation Function ----------------------- Key derivation and key stretching algorithms are designed for secure password -hashing. Naive algorithms such as ``sha1(password)`` are not resistant -against brute-force attacks. A good password hashing function must be tunable, -slow and include a salt. +hashing. Naive algorithms such as ``sha1(password)`` are not resistant against +brute-force attacks. A good password hashing function must be tunable, slow, and +include a `salt <https://en.wikipedia.org/wiki/Salt_%28cryptography%29>`_. .. function:: pbkdf2_hmac(name, password, salt, rounds, dklen=None) @@ -199,8 +197,7 @@ slow and include a salt. a proper source, e.g. :func:`os.urandom`. The number of *rounds* should be chosen based on the hash algorithm and - computing power. As of 2013 a value of at least 100,000 rounds of SHA-256 - have been suggested. + computing power. As of 2013, at least 100,000 rounds of SHA-256 is suggested. *dklen* is the length of the derived key. If *dklen* is ``None`` then the digest size of the hash algorithm *name* is used, e.g. 64 for SHA-512. @@ -212,9 +209,11 @@ slow and include a salt. .. versionadded:: 3.4 - .. note:: A fast implementation of *pbkdf2_hmac* is available with OpenSSL. - The Python implementation uses an inline version of :mod:`hmac`. It is - about three times slower and doesn't release the GIL. + .. note:: + + A fast implementation of *pbkdf2_hmac* is available with OpenSSL. The + Python implementation uses an inline version of :mod:`hmac`. It is about + three times slower and doesn't release the GIL. .. seealso:: diff --git a/Doc/library/heapq.rst b/Doc/library/heapq.rst index 4f1a682a875b..9682b593bd82 100644 --- a/Doc/library/heapq.rst +++ b/Doc/library/heapq.rst @@ -81,7 +81,7 @@ The following functions are provided: The module also offers three general purpose functions based on heaps. -.. function:: merge(*iterables) +.. function:: merge(*iterables, key=None, reverse=False) Merge multiple sorted inputs into a single sorted output (for example, merge timestamped entries from multiple log files). Returns an :term:`iterator` @@ -91,6 +91,18 @@ The module also offers three general purpose functions based on heaps. not pull the data into memory all at once, and assumes that each of the input streams is already sorted (smallest to largest). + Has two optional arguments which must be specified as keyword arguments. + + *key* specifies a :term:`key function` of one argument that is used to + extract a comparison key from each input element. The default value is + ``None`` (compare the elements directly). + + *reverse* is a boolean value. If set to ``True``, then the input elements + are merged as if each comparison were reversed. + + .. versionchanged:: 3.5 + Added the optional *key* and *reverse* parameters. + .. function:: nlargest(n, iterable, key=None) @@ -123,7 +135,6 @@ pushing all values onto a heap and then popping off the smallest values one at a time:: >>> def heapsort(iterable): - ... 'Equivalent to sorted(iterable)' ... h = [] ... for value in iterable: ... heappush(h, value) @@ -132,6 +143,9 @@ time:: >>> heapsort([1, 3, 5, 7, 9, 2, 4, 6, 8, 0]) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] +This is similar to ``sorted(iterable)``, but unlike :func:`sorted`, this +implementation is not stable. + Heap elements can be tuples. This is useful for assigning comparison values (such as task priorities) alongside the main record being tracked:: @@ -258,11 +272,11 @@ However, there are other representations which are more efficient overall, yet the worst cases might be terrible. Heaps are also very useful in big disk sorts. You most probably all know that a -big sort implies producing "runs" (which are pre-sorted sequences, which size is +big sort implies producing "runs" (which are pre-sorted sequences, whose size is usually related to the amount of CPU memory), followed by a merging passes for these runs, which merging is often very cleverly organised [#]_. It is very important that the initial sort produces the longest runs possible. Tournaments -are a good way to that. If, using all the memory available to hold a +are a good way to achieve that. If, using all the memory available to hold a tournament, you replace and percolate items that happen to fit the current run, you'll produce runs which are twice the size of the memory for random input, and much better for input fuzzily ordered. diff --git a/Doc/library/hmac.rst b/Doc/library/hmac.rst index 2e9b0b26a575..b2e377f5eba5 100644 --- a/Doc/library/hmac.rst +++ b/Doc/library/hmac.rst @@ -23,10 +23,9 @@ This module implements the HMAC algorithm as described by :rfc:`2104`. defaults to the :data:`hashlib.md5` constructor. .. versionchanged:: 3.4 - Parameter *key* can be a bytes or bytearray object. Parameter *msg* can - be of any type supported by :mod:`hashlib`. - - Paramter *digestmod* can be the name of a hash algorithm. + Parameter *key* can be a bytes or bytearray object. + Parameter *msg* can be of any type supported by :mod:`hashlib`. + Parameter *digestmod* can be the name of a hash algorithm. .. deprecated:: 3.4 MD5 as implicit default digest for *digestmod* is deprecated. diff --git a/Doc/library/html.entities.rst b/Doc/library/html.entities.rst index 09b0abc83793..e10e46e2b8dd 100644 --- a/Doc/library/html.entities.rst +++ b/Doc/library/html.entities.rst @@ -33,12 +33,12 @@ This module defines four dictionaries, :data:`html5`, .. data:: name2codepoint - A dictionary that maps HTML entity names to the Unicode codepoints. + A dictionary that maps HTML entity names to the Unicode code points. .. data:: codepoint2name - A dictionary that maps Unicode codepoints to HTML entity names. + A dictionary that maps Unicode code points to HTML entity names. .. rubric:: Footnotes diff --git a/Doc/library/html.parser.rst b/Doc/library/html.parser.rst index 44b7d6ea6d28..b84c60b708dd 100644 --- a/Doc/library/html.parser.rst +++ b/Doc/library/html.parser.rst @@ -16,21 +16,13 @@ This module defines a class :class:`HTMLParser` which serves as the basis for parsing text files formatted in HTML (HyperText Mark-up Language) and XHTML. -.. class:: HTMLParser(strict=False, *, convert_charrefs=False) +.. class:: HTMLParser(*, convert_charrefs=True) - Create a parser instance. + Create a parser instance able to parse invalid markup. - If *convert_charrefs* is ``True`` (default: ``False``), all character + If *convert_charrefs* is ``True`` (the default), all character references (except the ones in ``script``/``style`` elements) are automatically converted to the corresponding Unicode characters. - The use of ``convert_charrefs=True`` is encouraged and will become - the default in Python 3.5. - - If *strict* is ``False`` (the default), the parser will accept and parse - invalid markup. If *strict* is ``True`` the parser will raise an - :exc:`~html.parser.HTMLParseError` exception instead [#]_ when it's not - able to parse the markup. The use of ``strict=True`` is discouraged and - the *strict* argument is deprecated. An :class:`.HTMLParser` instance is fed HTML data and calls handler methods when start tags, end tags, text, comments, and other markup elements are @@ -40,31 +32,11 @@ parsing text files formatted in HTML (HyperText Mark-up Language) and XHTML. This parser does not check that end tags match start tags or call the end-tag handler for elements which are closed implicitly by closing an outer element. - .. versionchanged:: 3.2 - *strict* argument added. - - .. deprecated-removed:: 3.3 3.5 - The *strict* argument and the strict mode have been deprecated. - The parser is now able to accept and parse invalid markup too. - .. versionchanged:: 3.4 *convert_charrefs* keyword argument added. -An exception is defined as well: - - -.. exception:: HTMLParseError - - Exception raised by the :class:`HTMLParser` class when it encounters an error - while parsing and *strict* is ``True``. This exception provides three - attributes: :attr:`msg` is a brief message explaining the error, - :attr:`lineno` is the number of the line on which the broken construct was - detected, and :attr:`offset` is the number of characters into the line at - which the construct starts. - - .. deprecated-removed:: 3.3 3.5 - This exception has been deprecated because it's never raised by the parser - (when the default non-strict mode is used). + .. versionchanged:: 3.5 + The default value for argument *convert_charrefs* is now ``True``. Example HTML Parser Application @@ -246,8 +218,7 @@ implementations do nothing (except for :meth:`~HTMLParser.handle_startendtag`): The *data* parameter will be the entire contents of the declaration inside the ``<![...]>`` markup. It is sometimes useful to be overridden by a - derived class. The base class implementation raises an :exc:`HTMLParseError` - when *strict* is ``True``. + derived class. The base class implementation does nothing. .. _htmlparser-examples: @@ -358,9 +329,3 @@ Parsing invalid HTML (e.g. unquoted attributes) also works:: Data : tag soup End tag : p End tag : a - -.. rubric:: Footnotes - -.. [#] For backward compatibility reasons *strict* mode does not raise - exceptions for all non-compliant HTML. That is, some invalid HTML - is tolerated even in *strict* mode. diff --git a/Doc/library/http.client.rst b/Doc/library/http.client.rst index 2dbfa200ea56..5e27a36192b6 100644 --- a/Doc/library/http.client.rst +++ b/Doc/library/http.client.rst @@ -43,17 +43,17 @@ The module provides the following classes: For example, the following calls all create instances that connect to the server at the same host and port:: - >>> h1 = http.client.HTTPConnection('www.cwi.nl') - >>> h2 = http.client.HTTPConnection('www.cwi.nl:80') - >>> h3 = http.client.HTTPConnection('www.cwi.nl', 80) - >>> h3 = http.client.HTTPConnection('www.cwi.nl', 80, timeout=10) + >>> h1 = http.client.HTTPConnection('www.python.org') + >>> h2 = http.client.HTTPConnection('www.python.org:80') + >>> h3 = http.client.HTTPConnection('www.python.org', 80) + >>> h4 = http.client.HTTPConnection('www.python.org', 80, timeout=10) .. versionchanged:: 3.2 *source_address* was added. .. versionchanged:: 3.4 - The *strict* parameter is removed. HTTP 0.9-style "Simple Responses" are - not supported. + The *strict* parameter was removed. HTTP 0.9-style "Simple Responses" are + not longer supported. .. class:: HTTPSConnection(host, port=None, key_file=None, \ @@ -64,23 +64,16 @@ The module provides the following classes: A subclass of :class:`HTTPConnection` that uses SSL for communication with secure servers. Default port is ``443``. If *context* is specified, it must be a :class:`ssl.SSLContext` instance describing the various SSL - options. If *context* is specified and has a :attr:`~ssl.SSLContext.verify_mode` - of either :data:`~ssl.CERT_OPTIONAL` or :data:`~ssl.CERT_REQUIRED`, then - by default *host* is matched against the host name(s) allowed by the - server's certificate. If you want to change that behaviour, you can - explicitly set *check_hostname* to False. + options. *key_file* and *cert_file* are deprecated, please use - :meth:`ssl.SSLContext.load_cert_chain` instead. + :meth:`ssl.SSLContext.load_cert_chain` instead, or let + :func:`ssl.create_default_context` select the system's trusted CA + certificates for you. The *check_hostname* parameter is also deprecated; the + :attr:`ssl.SSLContext.check_hostname` attribute of *context* should be used + instead. - If you access arbitrary hosts on the Internet, it is recommended to - require certificate checking and feed the *context* with a set of - trusted CA certificates:: - - context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) - context.verify_mode = ssl.CERT_REQUIRED - context.load_verify_locations('/etc/pki/tls/certs/ca-bundle.crt') - h = client.HTTPSConnection('svn.python.org', 443, context=context) + Please read :ref:`ssl-security` for more information on best practices. .. versionchanged:: 3.2 *source_address*, *context* and *check_hostname* were added. @@ -90,8 +83,14 @@ The module provides the following classes: if :data:`ssl.HAS_SNI` is true). .. versionchanged:: 3.4 - The *strict* parameter is removed. HTTP 0.9-style "Simple Responses" are - not supported anymore. + The *strict* parameter was removed. HTTP 0.9-style "Simple Responses" are + no longer supported. + + .. versionchanged:: 3.4.3 + This class now performs all the necessary certificate and hostname checks + by default. To revert to the previous, unverified, behavior + :func:`ssl._create_unverified_context` can be passed to the *context* + parameter. .. class:: HTTPResponse(sock, debuglevel=0, method=None, url=None) @@ -100,8 +99,8 @@ The module provides the following classes: instantiated directly by user. .. versionchanged:: 3.4 - The *strict* parameter is removed. HTTP 0.9 style "Simple Responses" are - not supported anymore. + The *strict* parameter was removed. HTTP 0.9 style "Simple Responses" are + no longer supported. The following exceptions are raised as appropriate: @@ -170,6 +169,12 @@ The following exceptions are raised as appropriate: status code that we don't understand. +.. exception:: LineTooLong + + A subclass of :exc:`HTTPException`. Raised if an excessively long line + is received in the HTTP protocol from the server. + + The constants defined in this module are: .. data:: HTTP_PORT @@ -181,221 +186,15 @@ The constants defined in this module are: The default port for the HTTPS protocol (always ``443``). -and also the following constants for integer status codes: - -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| Constant | Value | Definition | -+==========================================+=========+=======================================================================+ -| :const:`CONTINUE` | ``100`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.1.1 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.1.1>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`SWITCHING_PROTOCOLS` | ``101`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.1.2 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.1.2>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`PROCESSING` | ``102`` | WEBDAV, `RFC 2518, Section 10.1 | -| | | <http://www.webdav.org/specs/rfc2518.html#STATUS_102>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`OK` | ``200`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.2.1 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.1>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`CREATED` | ``201`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.2.2 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.2>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`ACCEPTED` | ``202`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.2.3 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.3>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`NON_AUTHORITATIVE_INFORMATION` | ``203`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.2.4 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.4>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`NO_CONTENT` | ``204`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.2.5 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.5>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`RESET_CONTENT` | ``205`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.2.6 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.6>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`PARTIAL_CONTENT` | ``206`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.2.7 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.7>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`MULTI_STATUS` | ``207`` | WEBDAV `RFC 2518, Section 10.2 | -| | | <http://www.webdav.org/specs/rfc2518.html#STATUS_207>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`IM_USED` | ``226`` | Delta encoding in HTTP, | -| | | :rfc:`3229`, Section 10.4.1 | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`MULTIPLE_CHOICES` | ``300`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.3.1 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.1>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`MOVED_PERMANENTLY` | ``301`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.3.2 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.2>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`FOUND` | ``302`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.3.3 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.3>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`SEE_OTHER` | ``303`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.3.4 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.4>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`NOT_MODIFIED` | ``304`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.3.5 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.5>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`USE_PROXY` | ``305`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.3.6 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.6>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`TEMPORARY_REDIRECT` | ``307`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.3.8 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.8>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`BAD_REQUEST` | ``400`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.4.1 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.1>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`UNAUTHORIZED` | ``401`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.4.2 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`PAYMENT_REQUIRED` | ``402`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.4.3 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.3>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`FORBIDDEN` | ``403`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.4.4 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.4>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`NOT_FOUND` | ``404`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.4.5 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.5>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`METHOD_NOT_ALLOWED` | ``405`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.4.6 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.6>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`NOT_ACCEPTABLE` | ``406`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.4.7 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.7>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`PROXY_AUTHENTICATION_REQUIRED` | ``407`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.4.8 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.8>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`REQUEST_TIMEOUT` | ``408`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.4.9 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.9>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`CONFLICT` | ``409`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.4.10 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.10>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`GONE` | ``410`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.4.11 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.11>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`LENGTH_REQUIRED` | ``411`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.4.12 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.12>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`PRECONDITION_FAILED` | ``412`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.4.13 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.13>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`REQUEST_ENTITY_TOO_LARGE` | ``413`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.4.14 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.14>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`REQUEST_URI_TOO_LONG` | ``414`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.4.15 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.15>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`UNSUPPORTED_MEDIA_TYPE` | ``415`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.4.16 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.16>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`REQUESTED_RANGE_NOT_SATISFIABLE` | ``416`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.4.17 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.17>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`EXPECTATION_FAILED` | ``417`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.4.18 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.18>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`UNPROCESSABLE_ENTITY` | ``422`` | WEBDAV, `RFC 2518, Section 10.3 | -| | | <http://www.webdav.org/specs/rfc2518.html#STATUS_422>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`LOCKED` | ``423`` | WEBDAV `RFC 2518, Section 10.4 | -| | | <http://www.webdav.org/specs/rfc2518.html#STATUS_423>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`FAILED_DEPENDENCY` | ``424`` | WEBDAV, `RFC 2518, Section 10.5 | -| | | <http://www.webdav.org/specs/rfc2518.html#STATUS_424>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`UPGRADE_REQUIRED` | ``426`` | HTTP Upgrade to TLS, | -| | | :rfc:`2817`, Section 6 | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`PRECONDITION_REQUIRED` | ``428`` | Additional HTTP Status Codes, | -| | | :rfc:`6585`, Section 3 | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`TOO_MANY_REQUESTS` | ``429`` | Additional HTTP Status Codes, | -| | | :rfc:`6585`, Section 4 | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`REQUEST_HEADER_FIELDS_TOO_LARGE` | ``431`` | Additional HTTP Status Codes, | -| | | :rfc:`6585`, Section 5 | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`INTERNAL_SERVER_ERROR` | ``500`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.5.1 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.1>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`NOT_IMPLEMENTED` | ``501`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.5.2 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.2>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`BAD_GATEWAY` | ``502`` | HTTP/1.1 `RFC 2616, Section | -| | | 10.5.3 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.3>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`SERVICE_UNAVAILABLE` | ``503`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.5.4 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.4>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`GATEWAY_TIMEOUT` | ``504`` | HTTP/1.1 `RFC 2616, Section | -| | | 10.5.5 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.5>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`HTTP_VERSION_NOT_SUPPORTED` | ``505`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.5.6 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.6>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`INSUFFICIENT_STORAGE` | ``507`` | WEBDAV, `RFC 2518, Section 10.6 | -| | | <http://www.webdav.org/specs/rfc2518.html#STATUS_507>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`NOT_EXTENDED` | ``510`` | An HTTP Extension Framework, | -| | | :rfc:`2774`, Section 7 | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`NETWORK_AUTHENTICATION_REQUIRED` | ``511`` | Additional HTTP Status Codes, | -| | | :rfc:`6585`, Section 6 | -+------------------------------------------+---------+-----------------------------------------------------------------------+ - -.. versionchanged:: 3.3 - Added codes ``428``, ``429``, ``431`` and ``511`` from :rfc:`6585`. - - .. data:: responses This dictionary maps the HTTP 1.1 status codes to the W3C names. Example: ``http.client.responses[http.client.NOT_FOUND]`` is ``'Not Found'``. +See :ref:`http-status-codes` for a list of HTTP status codes that are +available in this module as constants. + .. _httpconnection-objects: @@ -451,11 +250,25 @@ HTTPConnection Objects .. method:: HTTPConnection.set_tunnel(host, port=None, headers=None) - Set the host and the port for HTTP Connect Tunnelling. Normally used when it - is required to a HTTPS Connection through a proxy server. + Set the host and the port for HTTP Connect Tunnelling. This allows running + the connection through a proxy server. + + The host and port arguments specify the endpoint of the tunneled connection + (i.e. the address included in the CONNECT request, *not* the address of the + proxy server). + + The headers argument should be a mapping of extra HTTP headers to send with + the CONNECT request. + + For example, to tunnel through a HTTPS proxy server running locally on port + 8080, we would pass the address of the proxy to the :class:`HTTPSConnection` + constructor, and the address of the host that we eventually want to reach to + the :meth:`~HTTPConnection.set_tunnel` method:: - The headers argument should be a mapping of extra HTTP headers to send - with the CONNECT request. + >>> import http.client + >>> conn = http.client.HTTPSConnection("localhost", 8080) + >>> conn.set_tunnel("www.python.org") + >>> conn.request("HEAD","/index.html") .. versionadded:: 3.2 @@ -642,7 +455,7 @@ request using http.client:: >>> # This creates an HTTP message >>> # with the content of BODY as the enclosed representation - >>> # for the resource http://localhost:8080/foobar + >>> # for the resource http://localhost:8080/file ... >>> import http.client >>> BODY = "***filecontents***" diff --git a/Doc/library/http.cookiejar.rst b/Doc/library/http.cookiejar.rst index b50cb226b780..1f6b1badf4bc 100644 --- a/Doc/library/http.cookiejar.rst +++ b/Doc/library/http.cookiejar.rst @@ -115,7 +115,7 @@ The following classes are provided: :mod:`http.cookiejar` and :mod:`http.cookies` modules do not depend on each other. - http://wp.netscape.com/newsref/std/cookie_spec.html + http://curl.haxx.se/rfc/cookie_spec.html The specification of the original Netscape cookie protocol. Though this is still the dominant protocol, the 'Netscape cookie protocol' implemented by all the major browsers (and :mod:`http.cookiejar`) only bears a passing resemblance to @@ -309,7 +309,7 @@ FileCookieJar subclasses and co-operation with web browsers ----------------------------------------------------------- The following :class:`CookieJar` subclasses are provided for reading and -writing . +writing. .. class:: MozillaCookieJar(filename, delayload=None, policy=None) diff --git a/Doc/library/http.rst b/Doc/library/http.rst index a387a37ddd2a..b6f2c582185e 100644 --- a/Doc/library/http.rst +++ b/Doc/library/http.rst @@ -1,7 +1,16 @@ :mod:`http` --- HTTP modules ============================ -``http`` is a package that collects several modules for working with the +.. module:: http + :synopsis: HTTP status codes and messages + +.. index:: + pair: HTTP; protocol + single: HTTP; http (standard module) + +**Source code:** :source:`Lib/http/__init__.py` + +:mod:`http` is a package that collects several modules for working with the HyperText Transfer Protocol: * :mod:`http.client` is a low-level HTTP protocol client; for high-level URL @@ -9,3 +18,105 @@ HyperText Transfer Protocol: * :mod:`http.server` contains basic HTTP server classes based on :mod:`socketserver` * :mod:`http.cookies` has utilities for implementing state management with cookies * :mod:`http.cookiejar` provides persistence of cookies + +:mod:`http` is also a module that defines a number of HTTP status codes and +associated messages through the :class:`http.HTTPStatus` enum: + +.. class:: HTTPStatus + + .. versionadded:: 3.5 + + A subclass of :class:`enum.IntEnum` that defines a set of HTTP status codes, + reason phrases and long descriptions written in English. + + Usage:: + + >>> from http import HTTPStatus + >>> HTTPStatus.OK + <HTTPStatus.OK: 200> + >>> HTTPStatus.OK == 200 + True + >>> http.HTTPStatus.OK.value + 200 + >>> HTTPStatus.OK.phrase + 'OK' + >>> HTTPStatus.OK.description + 'Request fulfilled, document follows' + >>> list(HTTPStatus) + [<HTTPStatus.CONTINUE: 100>, <HTTPStatus.SWITCHING_PROTOCOLS: 101>, ...] + +.. _http-status-codes: + +HTTP status codes +----------------- + +Supported, +`IANA-registered <http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml>`_ +status codes available in :class:`http.HTTPStatus` are: + +======= =================================== ================================================================== +Code Enum Name Details +======= =================================== ================================================================== +``100`` ``CONTINUE`` HTTP/1.1 :rfc:`7231`, Section 6.2.1 +``101`` ``SWITCHING_PROTOCOLS`` HTTP/1.1 :rfc:`7231`, Section 6.2.2 +``102`` ``PROCESSING`` WebDAV :rfc:`2518`, Section 10.1 +``200`` ``OK`` HTTP/1.1 :rfc:`7231`, Section 6.3.1 +``201`` ``CREATED`` HTTP/1.1 :rfc:`7231`, Section 6.3.2 +``202`` ``ACCEPTED`` HTTP/1.1 :rfc:`7231`, Section 6.3.3 +``203`` ``NON_AUTHORITATIVE_INFORMATION`` HTTP/1.1 :rfc:`7231`, Section 6.3.4 +``204`` ``NO_CONTENT`` HTTP/1.1 :rfc:`7231`, Section 6.3.5 +``205`` ``RESET_CONTENT`` HTTP/1.1 :rfc:`7231`, Section 6.3.6 +``206`` ``PARTIAL_CONTENT`` HTTP/1.1 :rfc:`7233`, Section 4.1 +``207`` ``MULTI_STATUS`` WebDAV :rfc:`4918`, Section 11.1 +``208`` ``ALREADY_REPORTED`` WebDAV Binding Extensions :rfc:`5842`, Section 7.1 (Experimental) +``226`` ``IM_USED`` Delta Encoding in HTTP :rfc:`3229`, Section 10.4.1 +``300`` ``MULTIPLE_CHOICES`` HTTP/1.1 :rfc:`7231`, Section 6.4.1 +``301`` ``MOVED_PERMANENTLY`` HTTP/1.1 :rfc:`7231`, Section 6.4.2 +``302`` ``FOUND`` HTTP/1.1 :rfc:`7231`, Section 6.4.3 +``303`` ``SEE_OTHER`` HTTP/1.1 :rfc:`7231`, Section 6.4.4 +``304`` ``NOT_MODIFIED`` HTTP/1.1 :rfc:`7232`, Section 4.1 +``305`` ``USE_PROXY`` HTTP/1.1 :rfc:`7231`, Section 6.4.5 +``307`` ``TEMPORARY_REDIRECT`` HTTP/1.1 :rfc:`7231`, Section 6.4.7 +``308`` ``PERMANENT_REDIRECT`` Permanent Redirect :rfc:`7238`, Section 3 (Experimental) +``400`` ``BAD_REQUEST`` HTTP/1.1 :rfc:`7231`, Section 6.5.1 +``401`` ``UNAUTHORIZED`` HTTP/1.1 Authentication :rfc:`7235`, Section 3.1 +``402`` ``PAYMENT_REQUIRED`` HTTP/1.1 :rfc:`7231`, Section 6.5.2 +``403`` ``FORBIDDEN`` HTTP/1.1 :rfc:`7231`, Section 6.5.3 +``404`` ``NOT_FOUND`` HTTP/1.1 :rfc:`7231`, Section 6.5.4 +``405`` ``METHOD_NOT_ALLOWED`` HTTP/1.1 :rfc:`7231`, Section 6.5.5 +``406`` ``NOT_ACCEPTABLE`` HTTP/1.1 :rfc:`7231`, Section 6.5.6 +``407`` ``PROXY_AUTHENTICATION_REQUIRED`` HTTP/1.1 Authentication :rfc:`7235`, Section 3.2 +``408`` ``REQUEST_TIMEOUT`` HTTP/1.1 :rfc:`7231`, Section 6.5.7 +``409`` ``CONFLICT`` HTTP/1.1 :rfc:`7231`, Section 6.5.8 +``410`` ``GONE`` HTTP/1.1 :rfc:`7231`, Section 6.5.9 +``411`` ``LENGTH_REQUIRED`` HTTP/1.1 :rfc:`7231`, Section 6.5.10 +``412`` ``PRECONDITION_FAILED`` HTTP/1.1 :rfc:`7232`, Section 4.2 +``413`` ``REQUEST_ENTITY_TOO_LARGE`` HTTP/1.1 :rfc:`7231`, Section 6.5.11 +``414`` ``REQUEST_URI_TOO_LONG`` HTTP/1.1 :rfc:`7231`, Section 6.5.12 +``415`` ``UNSUPPORTED_MEDIA_TYPE`` HTTP/1.1 :rfc:`7231`, Section 6.5.13 +``416`` ``REQUEST_RANGE_NOT_SATISFIABLE`` HTTP/1.1 Range Requests :rfc:`7233`, Section 4.4 +``417`` ``EXPECTATION_FAILED`` HTTP/1.1 :rfc:`7231`, Section 6.5.14 +``422`` ``UNPROCESSABLE_ENTITY`` WebDAV :rfc:`4918`, Section 11.2 +``423`` ``LOCKED`` WebDAV :rfc:`4918`, Section 11.3 +``424`` ``FAILED_DEPENDENCY`` WebDAV :rfc:`4918`, Section 11.4 +``426`` ``UPGRADE_REQUIRED`` HTTP/1.1 :rfc:`7231`, Section 6.5.15 +``428`` ``PRECONDITION_REQUIRED`` Additional HTTP Status Codes :rfc:`6585` +``429`` ``TOO_MANY_REQUESTS`` Additional HTTP Status Codes :rfc:`6585` +``431`` ``REQUEST_HEADER_FIELDS_TOO_LARGE`` Additional HTTP Status Codes :rfc:`6585` +``500`` ``INTERNAL_SERVER_ERROR`` HTTP/1.1 :rfc:`7231`, Section 6.6.1 +``501`` ``NOT_IMPLEMENTED`` HTTP/1.1 :rfc:`7231`, Section 6.6.2 +``502`` ``BAD_GATEWAY`` HTTP/1.1 :rfc:`7231`, Section 6.6.3 +``503`` ``SERVICE_UNAVAILABLE`` HTTP/1.1 :rfc:`7231`, Section 6.6.4 +``504`` ``GATEWAY_TIMEOUT`` HTTP/1.1 :rfc:`7231`, Section 6.6.5 +``505`` ``HTTP_VERSION_NOT_SUPPORTED`` HTTP/1.1 :rfc:`7231`, Section 6.6.6 +``506`` ``VARIANT_ALSO_NEGOTIATES`` Transparent Content Negotiation in HTTP :rfc:`2295`, Section 8.1 (Experimental) +``507`` ``INSUFFICIENT_STORAGE`` WebDAV :rfc:`4918`, Section 11.5 +``508`` ``LOOP_DETECTED`` WebDAV Binding Extensions :rfc:`5842`, Section 7.2 (Experimental) +``510`` ``NOT_EXTENDED`` An HTTP Extension Framework :rfc:`2774`, Section 7 (Experimental) +``511`` ``NETWORK_AUTHENTICATION_REQUIRED`` Additional HTTP Status Codes :rfc:`6585`, Section 6 +======= =================================== ================================================================== + +In order to preserve backwards compatibility, enum values are also present +in the :mod:`http.client` module in the form of constants. The enum name is +equal to the constant name (i.e. ``http.HTTPStatus.OK`` is also available as +``http.client.OK``). diff --git a/Doc/library/http.server.rst b/Doc/library/http.server.rst index 113ac4454e0d..1c3e20260936 100644 --- a/Doc/library/http.server.rst +++ b/Doc/library/http.server.rst @@ -64,6 +64,18 @@ of which this module provides three different variants: Contains the server instance. + .. attribute:: close_connection + + Boolean that should be set before :meth:`handle_one_request` returns, + indicating if another request may be expected, or if the connection should + be shut down. + + .. attribute:: requestline + + Contains the string representation of the HTTP request line. The + terminating CRLF is stripped. This attribute should be set by + :meth:`handle_one_request`. If no valid request line was processed, it + should be set to the empty string. .. attribute:: command @@ -81,7 +93,10 @@ of which this module provides three different variants: Holds an instance of the class specified by the :attr:`MessageClass` class variable. This instance parses and manages the headers in the HTTP - request. + request. The :func:`~http.client.parse_headers` function from + :mod:`http.client` is used to parse the headers and it requires that the + HTTP request provide a valid :rfc:`2822` style header. + .. attribute:: rfile @@ -116,7 +131,7 @@ of which this module provides three different variants: HTTP error code value. *message* should be a string containing a (detailed) error message of what occurred, and *explain* should be an explanation of the error code number. Default *message* and *explain* - values can found in the *responses* class variable. + values can found in the :attr:`responses` class variable. .. attribute:: error_content_type @@ -173,11 +188,14 @@ of which this module provides three different variants: .. method:: send_error(code, message=None, explain=None) Sends and logs a complete error reply to the client. The numeric *code* - specifies the HTTP error code, with *message* as optional, more specific - text, usually referring to short message response. The *explain* - argument can be used to send a detailed information about the error in - response content body. A complete set of headers is sent, followed by - text composed using the :attr:`error_message_format` class variable. + specifies the HTTP error code, with *message* as an optional, short, human + readable description of the error. The *explain* argument can be used to + provide more detailed information about the error; it will be formatted + using the :attr:`error_message_format` class variable and emitted, after + a complete set of headers, as the response body. The :attr:`responses` + class variable holds the default values for *message* and *explain* that + will be used if no value is provided; for unknown codes the default value + for both is the string ``???``. .. versionchanged:: 3.4 The error response includes a Content-Length header. @@ -214,7 +232,7 @@ of which this module provides three different variants: .. method:: send_response_only(code, message=None) - Sends the reponse header only, used for the purposes when ``100 + Sends the response header only, used for the purposes when ``100 Continue`` response is sent by the server to the client. The headers not buffered and sent directly the output stream.If the *message* is not specified, the HTTP message corresponding the response *code* is sent. @@ -348,7 +366,7 @@ of which this module provides three different variants: The :class:`SimpleHTTPRequestHandler` class can be used in the following manner in order to create a very basic webserver serving files relative to -the current directory. :: +the current directory:: import http.server import socketserver @@ -362,15 +380,17 @@ the current directory. :: print("serving at port", PORT) httpd.serve_forever() +.. _http-server-cli: + :mod:`http.server` can also be invoked directly using the :option:`-m` switch of the interpreter with a ``port number`` argument. Similar to -the previous example, this serves files relative to the current directory. :: +the previous example, this serves files relative to the current directory:: python -m http.server 8000 -By default, server binds itself to all interfaces. To restrict it to bind to a -particular interface only, ``--bind ADDRESS`` argument can be used. For e.g, to -restrict the server to bind only to localhost. :: +By default, server binds itself to all interfaces. The option ``-b/--bind`` +specifies a specific address to which it should bind. For example, the +following command causes the server to bind to localhost only:: python -m http.server 8000 --bind 127.0.0.1 @@ -419,7 +439,7 @@ restrict the server to bind only to localhost. :: reasons. Problems with the CGI script will be translated to error 403. :class:`CGIHTTPRequestHandler` can be enabled in the command line by passing -the ``--cgi`` option.:: +the ``--cgi`` option:: python -m http.server --cgi 8000 diff --git a/Doc/library/idle.rst b/Doc/library/idle.rst index 2718cef3d5e3..c842b2639cc9 100644 --- a/Doc/library/idle.rst +++ b/Doc/library/idle.rst @@ -3,13 +3,13 @@ IDLE ==== -.. moduleauthor:: Guido van Rossum <guido@Python.org> - .. index:: single: IDLE single: Python Editor single: Integrated Development Environment +.. moduleauthor:: Guido van Rossum <guido@Python.org> + IDLE is the Python IDE built with the :mod:`tkinter` GUI toolkit. IDLE has the following features: @@ -29,136 +29,147 @@ IDLE has the following features: Menus ----- -IDLE has two window types, the Shell window and the Editor window. It is -possible to have multiple editor windows simultaneously. IDLE's -menus dynamically change based on which window is currently selected. Each menu -documented below indicates which window type it is associated with. Click on -the dotted line at the top of a menu to "tear it off": a separate window -containing the menu is created (for Unix and Windows only). +IDLE has two main window types, the Shell window and the Editor window. It is +possible to have multiple editor windows simultaneously. Output windows, such +as used for Edit / Find in Files, are a subtype of edit window. They currently +have the same top menu as Editor windows but a different default title and +context menu. + +IDLE's menus dynamically change based on which window is currently selected. +Each menu documented below indicates which window type it is associated with. +Click on the dotted line at the top of a menu to "tear it off": a separate +window containing the menu is created (for Unix and Windows only). File menu (Shell and Editor) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -New file - Create a new file editing window +New File + Create a new file editing window. Open... - Open an existing file - -Open module... - Open an existing module (searches sys.path) + Open an existing file with an Open dialog. Recent Files - Open a list of recent files + Open a list of recent files. Click one to open it. -Class browser - Show classes and methods in current file - -Path browser - Show sys.path directories, modules, classes and methods +Open Module... + Open an existing module (searches sys.path). .. index:: single: Class browser single: Path browser +Class Browser + Show functions, classes, and methods in the current Editor file in a + tree structure. In the shell, open a module first. + +Path Browser + Show sys.path directories, modules, functions, classes and methods in a + tree structure. + Save - Save current window to the associated file (unsaved windows have a - \* before and after the window title) + Save the current window to the associated file, if there is one. Windows + that have been changed since being opened or last saved have a \* before + and after the window title. If there is no associated file, + do Save As instead. Save As... - Save current window to new file, which becomes the associated file + Save the current window with a Save As dialog. The file saved becomes the + new associated file for the window. Save Copy As... - Save current window to different file without changing the associated file + Save the current window to different file without changing the associated + file. Print Window - Print the current window + Print the current window to the default printer. Close - Close current window (asks to save if unsaved) + Close the current window (ask to save if unsaved). Exit - Close all windows and quit IDLE (asks to save if unsaved) - + Close all windows and quit IDLE (ask to save unsaved windows). Edit menu (Shell and Editor) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undo - Undo last change to current window (a maximum of 1000 changes may be undone) + Undo the last change to the current window. A maximum of 1000 changes may + be undone. Redo - Redo last undone change to current window + Redo the last undone change to the current window. Cut - Copy selection into system-wide clipboard; then delete the selection + Copy selection into the system-wide clipboard; then delete the selection. Copy - Copy selection into system-wide clipboard + Copy selection into the system-wide clipboard. Paste - Insert system-wide clipboard into window + Insert contents of the system-wide clipboard into the current window. + +The clipboard functions are also available in context menus. Select All - Select the entire contents of the edit buffer + Select the entire contents of the current window. Find... - Open a search dialog box with many options + Open a search dialog with many options -Find again - Repeat last search +Find Again + Repeat the last search, if there is one. -Find selection - Search for the string in the selection +Find Selection + Search for the currently selected string, if there is one. Find in Files... - Open a search dialog box for searching files + Open a file search dialog. Put results in an new output window. Replace... - Open a search-and-replace dialog box + Open a search-and-replace dialog. -Go to line - Ask for a line number and show that line +Go to Line + Move cursor to the line number requested and make that line visible. -Expand word - Expand the word you have typed to match another word in the same buffer; - repeat to get a different expansion +Show Completions + Open a scrollable list allowing selection of keywords and attributes. See + Completions in the Tips sections below. + +Expand Word + Expand a prefix you have typed to match a full word in the same window; + repeat to get a different expansion. Show call tip After an unclosed parenthesis for a function, open a small window with - function parameter hints + function parameter hints. Show surrounding parens - Highlight the surrounding parenthesis - -Show Completions - Open a scroll window allowing selection keywords and attributes. See - Completions below. - + Highlight the surrounding parenthesis. Format menu (Editor window only) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Indent region - Shift selected lines right by the indent width (default 4 spaces) +Indent Region + Shift selected lines right by the indent width (default 4 spaces). -Dedent region - Shift selected lines left by the indent width (default 4 spaces) +Dedent Region + Shift selected lines left by the indent width (default 4 spaces). -Comment out region - Insert ## in front of selected lines +Comment Out Region + Insert ## in front of selected lines. -Uncomment region - Remove leading # or ## from selected lines +Uncomment Region + Remove leading # or ## from selected lines. -Tabify region - Turns *leading* stretches of spaces into tabs. (Note: We recommend using +Tabify Region + Turn *leading* stretches of spaces into tabs. (Note: We recommend using 4 space blocks to indent Python code.) -Untabify region - Turn *all* tabs into the correct number of spaces +Untabify Region + Turn *all* tabs into the correct number of spaces. -Toggle tabs +Toggle Tabs Open a dialog to switch between indenting with spaces and tabs. New Indent Width @@ -166,62 +177,67 @@ New Indent Width community is 4 spaces. Format Paragraph - Reformat the current blank-line-separated paragraph. All lines in the - paragraph will be formatted to less than 80 columns. + Reformat the current blank-line-delimited paragraph in comment block or + multiline string or selected line in a string. All lines in the + paragraph will be formatted to less than N columns, where N defaults to 72. Strip trailing whitespace - Removes any space characters after the end of the last non-space character + Remove any space characters after the last non-space character of a line. .. index:: - single: Import module single: Run script - Run menu (Editor window only) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Python Shell - Open or wake up the Python Shell window + Open or wake up the Python Shell window. -Check module +Check Module Check the syntax of the module currently open in the Editor window. If the - module has not been saved IDLE will prompt the user to save the code. + module has not been saved IDLE will either prompt the user to save or + autosave, as selected in the General tab of the Idle Settings dialog. If + there is a syntax error, the approximate location is indicated in the + Editor window. -Run module - Restart the shell to clean the environment, then execute the currently - open module. If the module has not been saved IDLE will prompt the user - to save the code. +Run Module + Do Check Module (above). If no error, restart the shell to clean the + environment, then execute the module. Shell menu (Shell window only) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ View Last Restart - Scroll the shell window to the last Shell restart + Scroll the shell window to the last Shell restart. Restart Shell - Restart the shell to clean the environment + Restart the shell to clean the environment. Debug menu (Shell window only) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Go to file/line - Look around the insert point for a filename and line number, open the file, - and show the line. Useful to view the source lines referenced in an - exception traceback. Available in the context menu of the Shell window. +Go to File/Line + Look on the current line. with the cursor, and the line above for a filename + and line number. If found, open the file if not already open, and show the + line. Use this to view source lines referenced in an exception traceback + and lines found by Find in Files. Also available in the context menu of + the Shell window and Output windows. + +.. index:: + single: debugger + single: stack viewer Debugger (toggle) - This feature is not complete and considered experimental. Run commands in - the shell under the debugger + When actived, code entered in the Shell or run from an Editor will run + under the debugger. In the Editor, breakpoints can be set with the context + menu. This feature is still incomplete and somewhat experimental. -Stack viewer - Show the stack traceback of the last exception +Stack Viewer + Show the stack traceback of the last exception in a tree widget, with + access to locals and globals. Auto-open Stack Viewer - Toggle automatically opening the stack viewer on unhandled exception - -.. index:: - single: stack viewer - single: debugger + Toggle automatically opening the stack viewer on an unhandled exception. Options menu (Shell and Editor) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -229,19 +245,26 @@ Options menu (Shell and Editor) Configure IDLE Open a configuration dialog. Fonts, indentation, keybindings, and color themes may be altered. Startup Preferences may be set, and additional - help sources can be specified. + help sources can be specified. Non-default user setting are saved in a + .idlerc directory in the user's home directory. Problems caused by bad user + configuration files are solved by editing or deleting one or more of the + files in .idlerc. + +Configure Extensions + Open a configuration dialog for setting preferences for extensions + (discussed below). See note above about the location of user settings. Code Context (toggle)(Editor Window only) Open a pane at the top of the edit window which shows the block context - of the section of code which is scrolling off the top of the window. + of the code which has scrolled above the top of the window. -Windows menu (Shell and Editor) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Window menu (Shell and Editor) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Zoom Height - Toggles the window between normal size (40x80 initial setting) and maximum - height. The initial size is in the Configure IDLE dialog under the general - tab. + Toggles the window between normal size and maximum height. The initial size + defaults to 40 lines by 80 chars unless changed on the General tab of the + Configure IDLE dialog. The rest of this menu lists the names of all open windows; select one to bring it to the foreground (deiconifying it if necessary). @@ -250,39 +273,22 @@ Help menu (Shell and Editor) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ About IDLE - Version, copyright, license, credits + Display version, copyright, license, credits, and more. IDLE Help Display a help file for IDLE detailing the menu options, basic editing and navigation, and other tips. Python Docs - Access local Python documentation, if installed. Or will start a web browser + Access local Python documentation, if installed, or start a web browser and open docs.python.org showing the latest Python documentation. +Turtle Demo + Run the turtledemo module with example python code and turtle drawings. + Additional help sources may be added here with the Configure IDLE dialog under the General tab. -Editor Window context menu -^^^^^^^^^^^^^^^^^^^^^^^^^^ - -* Right-click in Editor window (Control-click on OS X) - -Cut - Copy selection into system-wide clipboard; then delete selection - -Copy - Copy selection into system-wide clipboard - -Paste - Insert system-wide clipboard into window - -Set Breakpoint - Sets a breakpoint. Breakpoints are only enabled when the debugger is open. - -Clear Breakpoint - Clears the breakpoint on that line. - .. index:: single: Cut single: Copy @@ -291,20 +297,32 @@ Clear Breakpoint single: Clear Breakpoint single: breakpoints +Context Menus +^^^^^^^^^^^^^^^^^^^^^^^^^^ -Shell Window context menu -^^^^^^^^^^^^^^^^^^^^^^^^^ - -* Right-click in Python Shell window (Control-click on OS X) +Open a context menu by right-clicking in a window (Control-click on OS X). +Context menus have the standard clipboard functions also on the Edit menu. Cut - Copy selection into system-wide clipboard; then delete selection + Copy selection into the system-wide clipboard; then delete the selection. Copy - Copy selection into system-wide clipboard + Copy selection into the system-wide clipboard. Paste - Insert system-wide clipboard into window + Insert contents of the system-wide clipboard into the current window. + +Editor windows also have breakpoint functions. Lines with a breakpoint set are +specially marked. Breakpoints only have an effect when running under the +debugger. Breakpoints for a file are saved in the user's .idlerc directory. + +Set Breakpoint + Set a breakpoint on the current line. + +Clear Breakpoint + Clear the breakpoint on that line. + +Shell and Output windows have the following. Go to file/line Same as in Debug menu. @@ -313,6 +331,9 @@ Go to file/line Editing and navigation ---------------------- +In this section, 'C' refers to the Control key on Windows and Unix and +the Command key on Mac OSX. + * :kbd:`Backspace` deletes to the left; :kbd:`Del` deletes to the right * :kbd:`C-Backspace` delete word left; :kbd:`C-Del` delete word to the right @@ -414,7 +435,6 @@ Python Shell window * :kbd:`C-c` interrupts executing command * :kbd:`C-d` sends end-of-file; closes window if typed at a ``>>>`` prompt - (this is :kbd:`C-z` on Windows). * :kbd:`Alt-/` (Expand word) is also useful to reduce typing @@ -476,8 +496,8 @@ shell, or for executing import statements to import common modules. In addition, ``Tk`` also loads a startup file if it is present. Note that the Tk file is loaded unconditionally. This additional file is ``.Idle.py`` and is looked for in the user's home directory. Statements in this file will be -executed in the Tk namespace, so this file is not useful for importing functions -to be used from IDLE's Python shell. +executed in the Tk namespace, so this file is not useful for importing +functions to be used from IDLE's Python shell. Command line usage @@ -503,13 +523,32 @@ If there are arguments: #. Otherwise, if neither ``-e`` nor ``-c`` is used, the first argument is a script which is executed with the remaining arguments in - ``sys.argv[1:...]`` and ``sys.argv[0]`` set to the script name. If the script - name is '-', no script is executed but an interactive Python session is started; - the arguments are still available in ``sys.argv``. + ``sys.argv[1:...]`` and ``sys.argv[0]`` set to the script name. If the + script name is '-', no script is executed but an interactive Python session + is started; the arguments are still available in ``sys.argv``. + +Running without a subprocess +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +If IDLE is started with the -n command line switch it will run in a +single process and will not create the subprocess which runs the RPC +Python execution server. This can be useful if Python cannot create +the subprocess or the RPC socket interface on your platform. However, +in this mode user code is not isolated from IDLE itself. Also, the +environment is not restarted when Run/Run Module (F5) is selected. If +your code has been modified, you must reload() the affected modules and +re-import any specific items (e.g. from foo import baz) if the changes +are to take effect. For these reasons, it is preferable to run IDLE +with the default subprocess if at all possible. + +.. deprecated:: 3.4 +Help and preferences +-------------------- + Additional help sources ------------------------ +^^^^^^^^^^^^^^^^^^^^^^^ IDLE includes a help menu entry called "Python Docs" that will open the extensive sources of help, including tutorials, available at docs.python.org. @@ -518,21 +557,22 @@ Configure IDLE dialog. See the IDLE help option in the help menu of IDLE for more information. -Other preferences ------------------ +Setting preferences +^^^^^^^^^^^^^^^^^^^ The font preferences, highlighting, keys, and general preferences can be -changed via the Configure IDLE menu option. Be sure to note that -keys can be user defined, IDLE ships with four built in key sets. In -addition a user can create a custom key set in the Configure IDLE dialog -under the keys tab. +changed via Configure IDLE on the Option menu. Keys can be user defined; +IDLE ships with four built in key sets. In addition a user can create a +custom key set in the Configure IDLE dialog under the keys tab. + Extensions ----------- +^^^^^^^^^^ -IDLE contains an extension facility. See the beginning of -config-extensions.def in the idlelib directory for further information. The -default extensions are currently: +IDLE contains an extension facility. Peferences for extensions can be +changed with Configure Extensions. See the beginning of config-extensions.def +in the idlelib directory for further information. The default extensions +are currently: * FormatParagraph @@ -550,3 +590,4 @@ default extensions are currently: * CodeContext +* RstripExtension diff --git a/Doc/library/imaplib.rst b/Doc/library/imaplib.rst index 01236fbb8ea5..f263bab9f02b 100644 --- a/Doc/library/imaplib.rst +++ b/Doc/library/imaplib.rst @@ -37,6 +37,19 @@ base class: initialized. If *host* is not specified, ``''`` (the local host) is used. If *port* is omitted, the standard IMAP4 port (143) is used. + The :class:`IMAP4` class supports the :keyword:`with` statement. When used + like this, the IMAP4 ``LOGOUT`` command is issued automatically when the + :keyword:`with` statement exits. E.g.:: + + >>> from imaplib import IMAP4 + >>> with IMAP4("domain.org") as M: + ... M.noop() + ... + ('OK', [b'Nothing Accomplished. d25if65hy903weo.87']) + + .. versionchanged:: 3.5 + Support for the :keyword:`with` statement was added. + Three exceptions are defined as attributes of the :class:`IMAP4` class: @@ -69,17 +82,25 @@ There's also a subclass for secure connections: This is a subclass derived from :class:`IMAP4` that connects over an SSL encrypted socket (to use this class you need a socket module that was compiled with SSL support). If *host* is not specified, ``''`` (the local host) is used. - If *port* is omitted, the standard IMAP4-over-SSL port (993) is used. *keyfile* - and *certfile* are also optional - they can contain a PEM formatted private key - and certificate chain file for the SSL connection. *ssl_context* parameter is a - :class:`ssl.SSLContext` object which allows bundling SSL configuration - options, certificates and private keys into a single (potentially long-lived) - structure. Note that the *keyfile*/*certfile* parameters are mutually exclusive with *ssl_context*, - a :class:`ValueError` is raised if *keyfile*/*certfile* is provided along with *ssl_context*. + If *port* is omitted, the standard IMAP4-over-SSL port (993) is used. + *ssl_context* is a :class:`ssl.SSLContext` object which allows bundling + SSL configuration options, certificates and private keys into a single + (potentially long-lived) structure. Please read :ref:`ssl-security` for + best practices. + + *keyfile* and *certfile* are a legacy alternative to *ssl_context* - they + can point to PEM-formatted private key and certificate chain files for + the SSL connection. Note that the *keyfile*/*certfile* parameters are + mutually exclusive with *ssl_context*, a :class:`ValueError` is raised + if *keyfile*/*certfile* is provided along with *ssl_context*. .. versionchanged:: 3.3 *ssl_context* parameter added. + .. versionchanged:: 3.4 + The class now supports hostname check with + :attr:`ssl.SSLContext.check_hostname` and *Server Name Indication* (see + :data:`ssl.HAS_SNI`). The second subclass allows for connections created by a child process: @@ -433,10 +454,16 @@ An :class:`IMAP4` instance has the following methods: Send a ``STARTTLS`` command. The *ssl_context* argument is optional and should be a :class:`ssl.SSLContext` object. This will enable - encryption on the IMAP connection. + encryption on the IMAP connection. Please read :ref:`ssl-security` for + best practices. .. versionadded:: 3.2 + .. versionchanged:: 3.4 + The method now supports hostname check with + :attr:`ssl.SSLContext.check_hostname` and *Server Name Indication* (see + :data:`ssl.HAS_SNI`). + .. method:: IMAP4.status(mailbox, names) diff --git a/Doc/library/imghdr.rst b/Doc/library/imghdr.rst index 9e8952339cca..c60df24c5a17 100644 --- a/Doc/library/imghdr.rst +++ b/Doc/library/imghdr.rst @@ -48,6 +48,16 @@ from :func:`what`: +------------+-----------------------------------+ | ``'png'`` | Portable Network Graphics | +------------+-----------------------------------+ +| ``'webp'`` | WebP files | ++------------+-----------------------------------+ +| ``'exr'`` | OpenEXR Files | ++------------+-----------------------------------+ + +.. versionadded:: 3.5 + The *exr* format was added. + +.. versionchanged:: 3.5 + The *webp* type was added. You can extend the list of file types :mod:`imghdr` can recognize by appending to this variable: diff --git a/Doc/library/imp.rst b/Doc/library/imp.rst index ee02c3f29f63..c2dbdc5cf9b9 100644 --- a/Doc/library/imp.rst +++ b/Doc/library/imp.rst @@ -1,12 +1,12 @@ :mod:`imp` --- Access the :ref:`import <importsystem>` internals ================================================================ -.. deprecated:: 3.4 - The :mod:`imp` package is pending deprecation in favor of :mod:`importlib`. - .. module:: imp :synopsis: Access the implementation of the import statement. + :deprecated: +.. deprecated:: 3.4 + The :mod:`imp` package is pending deprecation in favor of :mod:`importlib`. .. index:: statement: import @@ -79,7 +79,9 @@ This module provides an interface to the mechanisms used to implement the When *P* itself has a dotted name, apply this recipe recursively. .. deprecated:: 3.3 - Use :func:`importlib.find_loader` instead. + Use :func:`importlib.util.find_spec` instead unless Python 3.3 + compatibility is required, in which case use + :func:`importlib.find_loader`. .. function:: load_module(name, file, pathname, description) @@ -104,9 +106,11 @@ This module provides an interface to the mechanisms used to implement the .. deprecated:: 3.3 If previously used in conjunction with :func:`imp.find_module` then - call ``load_module()`` on the returned loader. If you wish to load a - module from a specific file, then use one of the file-based loaders found - in :mod:`importlib.machinery`. + consider using :func:`importlib.import_module`, otherwise use the loader + returned by the replacement you chose for :func:`imp.find_module`. If you + called :func:`imp.load_module` and related functions directly then use the + classes in :mod:`importlib.machinery`, e.g. + ``importlib.machinery.SourceFileLoader(name, path).load_module()``. .. function:: new_module(name) @@ -262,12 +266,12 @@ that circular imports work without any deadlocks. exception is made for circular imports, which by construction have to expose an incomplete module object at some point. -.. versionchanged:: 3.3 - The locking scheme has changed to per-module locks for - the most part. A global import lock is kept for some critical tasks, - such as initializing the per-module locks. + .. versionchanged:: 3.3 + The locking scheme has changed to per-module locks for + the most part. A global import lock is kept for some critical tasks, + such as initializing the per-module locks. -.. deprecated:: 3.4 + .. deprecated:: 3.4 .. function:: acquire_lock() @@ -282,12 +286,12 @@ that circular imports work without any deadlocks. On platforms without threads, this function does nothing. -.. versionchanged:: 3.3 - The locking scheme has changed to per-module locks for - the most part. A global import lock is kept for some critical tasks, - such as initializing the per-module locks. + .. versionchanged:: 3.3 + The locking scheme has changed to per-module locks for + the most part. A global import lock is kept for some critical tasks, + such as initializing the per-module locks. -.. deprecated:: 3.4 + .. deprecated:: 3.4 .. function:: release_lock() @@ -295,12 +299,12 @@ that circular imports work without any deadlocks. Release the interpreter's global import lock. On platforms without threads, this function does nothing. -.. versionchanged:: 3.3 - The locking scheme has changed to per-module locks for - the most part. A global import lock is kept for some critical tasks, - such as initializing the per-module locks. + .. versionchanged:: 3.3 + The locking scheme has changed to per-module locks for + the most part. A global import lock is kept for some critical tasks, + such as initializing the per-module locks. -.. deprecated:: 3.4 + .. deprecated:: 3.4 The following constants with integer values, defined in this module, are used diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst index 177f15b86790..e61ac351cddb 100644 --- a/Doc/library/importlib.rst +++ b/Doc/library/importlib.rst @@ -1,8 +1,8 @@ -:mod:`importlib` -- An implementation of :keyword:`import` -========================================================== +:mod:`importlib` -- The implementation of :keyword:`import` +=========================================================== .. module:: importlib - :synopsis: An implementation of the import machinery. + :synopsis: The implementation of the import machinery. .. moduleauthor:: Brett Cannon <brett@python.org> .. sectionauthor:: Brett Cannon <brett@python.org> @@ -13,24 +13,23 @@ Introduction ------------ -The purpose of the :mod:`importlib` package is two-fold. One is to provide an +The purpose of the :mod:`importlib` package is two-fold. One is to provide the implementation of the :keyword:`import` statement (and thus, by extension, the :func:`__import__` function) in Python source code. This provides an implementation of :keyword:`import` which is portable to any Python -interpreter. This also provides a reference implementation which is easier to +interpreter. This also provides an implementation which is easier to comprehend than one implemented in a programming language other than Python. Two, the components to implement :keyword:`import` are exposed in this package, making it easier for users to create their own custom objects (known generically as an :term:`importer`) to participate in the import process. -Details on custom importers can be found in :pep:`302`. .. seealso:: :ref:`import` The language reference for the :keyword:`import` statement. - `Packages specification <http://www.python.org/doc/essays/packages.html>`__ + `Packages specification <http://legacy.python.org/doc/essays/packages.html>`__ Original specification of packages. Some semantics have changed since the writing of this document (e.g. redirecting based on ``None`` in :data:`sys.modules`). @@ -53,6 +52,9 @@ Details on custom importers can be found in :pep:`302`. :pep:`366` Main module explicit relative imports + :pep:`451` + A ModuleSpec Type for the Import System + :pep:`3120` Using UTF-8 as the Default Source Encoding @@ -67,6 +69,10 @@ Functions An implementation of the built-in :func:`__import__` function. + .. note:: + Programmatic importing of modules should use :func:`import_module` + instead of this function. + .. function:: import_module(name, package=None) Import a module. The *name* argument specifies what module to @@ -79,12 +85,18 @@ Functions The :func:`import_module` function acts as a simplifying wrapper around :func:`importlib.__import__`. This means all semantics of the function are - derived from :func:`importlib.__import__`, including requiring the package - from which an import is occurring to have been previously imported - (i.e., *package* must already be imported). The most important difference - is that :func:`import_module` returns the most nested package or module - that was imported (e.g. ``pkg.mod``), while :func:`__import__` returns the - top-level package or module (e.g. ``pkg``). + derived from :func:`importlib.__import__`. The most important difference + between these two functions is that :func:`import_module` returns the + specified package or module (e.g. ``pkg.mod``), while :func:`__import__` + returns the top-level package or module (e.g. ``pkg``). + + If you are dynamically importing a module that was created since the + interpreter began execution (e.g., created a Python source file), you may + need to call :func:`invalidate_caches` in order for the new module to be + noticed by the import system. + + .. versionchanged:: 3.3 + Parent packages are automatically imported. .. function:: find_loader(name, path=None) @@ -105,6 +117,9 @@ Functions If ``__loader__`` is not set, raise :exc:`ValueError`, just like when the attribute is set to ``None``. + .. deprecated:: 3.4 + Use :func:`importlib.util.find_spec` instead. + .. function:: invalidate_caches() Invalidate the internal caches of finders stored at @@ -126,7 +141,7 @@ Functions When :func:`reload` is executed: - * Python modules' code is recompiled and the module-level code re-executed, + * Python module's code is recompiled and the module-level code re-executed, defining a new set of objects which are bound to names in the module's dictionary by reusing the :term:`loader` which originally loaded the module. The ``init`` function of extension modules is not called a second @@ -233,17 +248,36 @@ ABC hierarchy:: .. versionadded:: 3.3 + .. method:: find_spec(fullname, path, target=None) + + An abstract method for finding a :term:`spec <module spec>` for + the specified module. If this is a top-level import, *path* will + be ``None``. Otherwise, this is a search for a subpackage or + module and *path* will be the value of :attr:`__path__` from the + parent package. If a spec cannot be found, ``None`` is returned. + When passed in, ``target`` is a module object that the finder may + use to make a more educated about what spec to return. + + .. versionadded:: 3.4 + .. method:: find_module(fullname, path) - An abstract method for finding a :term:`loader` for the specified + A legacy method for finding a :term:`loader` for the specified module. If this is a top-level import, *path* will be ``None``. Otherwise, this is a search for a subpackage or module and *path* will be the value of :attr:`__path__` from the parent package. If a loader cannot be found, ``None`` is returned. + If :meth:`find_spec` is defined, backwards-compatible functionality is + provided. + .. versionchanged:: 3.4 Returns ``None`` when called instead of raising - :exc:`NotImplementedError`. + :exc:`NotImplementedError`. Can use :meth:`find_spec` to provide + functionality. + + .. deprecated:: 3.4 + Use :meth:`find_spec` instead. .. method:: invalidate_caches() @@ -265,9 +299,20 @@ ABC hierarchy:: .. versionadded:: 3.3 + .. method:: find_spec(fullname, target=None) + + An abstract method for finding a :term:`spec <module spec>` for + the specified module. The finder will search for the module only + within the :term:`path entry` to which it is assigned. If a spec + cannot be found, ``None`` is returned. When passed in, ``target`` + is a module object that the finder may use to make a more educated + about what spec to return. + + .. versionadded:: 3.4 + .. method:: find_loader(fullname) - An abstract method for finding a :term:`loader` for the specified + A legacy method for finding a :term:`loader` for the specified module. Returns a 2-tuple of ``(loader, portion)`` where ``portion`` is a sequence of file system locations contributing to part of a namespace package. The loader may be ``None`` while specifying ``portion`` to @@ -277,14 +322,24 @@ ABC hierarchy:: ``portion`` is the empty list then no loader or location for a namespace package were found (i.e. failure to find anything for the module). + If :meth:`find_spec` is defined then backwards-compatible functionality is + provided. + .. versionchanged:: 3.4 Returns ``(None, [])`` instead of raising :exc:`NotImplementedError`. + Uses :meth:`find_spec` when available to provide functionality. + + .. deprecated:: 3.4 + Use :meth:`find_spec` instead. .. method:: find_module(fullname) A concrete implementation of :meth:`Finder.find_module` which is equivalent to ``self.find_loader(fullname)[0]``. + .. deprecated:: 3.4 + Use :meth:`find_spec` instead. + .. method:: invalidate_caches() An optional method which, when called, should invalidate any internal @@ -297,9 +352,29 @@ ABC hierarchy:: An abstract base class for a :term:`loader`. See :pep:`302` for the exact definition for a loader. + .. method:: create_module(spec) + + A method that returns the module object to use when + importing a module. This method may return ``None``, + indicating that default module creation semantics should take place. + + .. versionadded:: 3.4 + + .. versionchanged:: 3.5 + Starting in Python 3.6, this method will not be optional when + :meth:`exec_module` is defined. + + .. method:: exec_module(module) + + An abstract method that executes the module in its own namespace + when a module is imported or reloaded. The module should already + be initialized when exec_module() is called. + + .. versionadded:: 3.4 + .. method:: load_module(fullname) - An abstract method for loading a module. If the module cannot be + A legacy method for loading a module. If the module cannot be loaded, :exc:`ImportError` is raised, otherwise the loaded module is returned. @@ -342,13 +417,24 @@ ABC hierarchy:: :func:`importlib.util.module_for_loader` decorator can handle the details for :attr:`__package__`. + When :meth:`exec_module` is available then backwards-compatible + functionality is provided. + .. versionchanged:: 3.4 Raise :exc:`ImportError` when called instead of - :exc:`NotImplementedError`. + :exc:`NotImplementedError`. Functionality provided when + :meth:`exec_module` is available. + + .. deprecated:: 3.4 + The recommended API for loading a module is :meth:`exec_module` + (and :meth:`create_module`). Loaders should implement + it instead of load_module(). The import machinery takes care of + all the other responsibilities of load_module() when exec_module() + is implemented. .. method:: module_repr(module) - An optional method which when implemented calculates and returns the + A legacy method which when implemented calculates and returns the given module's repr, as a string. The module type's default repr() will use the result of this method as appropriate. @@ -357,6 +443,9 @@ ABC hierarchy:: .. versionchanged:: 3.4 Made optional instead of an abstractmethod. + .. deprecated:: 3.4 + The import machinery now takes care of this automatically. + .. class:: ResourceLoader @@ -370,12 +459,12 @@ ABC hierarchy:: Loaders that have a file-like storage back-end that allows storing arbitrary data can implement this abstract method to give direct access - to the data stored. :exc:`IOError` is to be raised if the *path* cannot + to the data stored. :exc:`OSError` is to be raised if the *path* cannot be found. The *path* is expected to be constructed using a module's :attr:`__file__` attribute or an item from a package's :attr:`__path__`. .. versionchanged:: 3.4 - Raises :exc:`IOError` instead of :exc:`NotImplementedError`. + Raises :exc:`OSError` instead of :exc:`NotImplementedError`. .. class:: InspectLoader @@ -385,10 +474,10 @@ ABC hierarchy:: .. method:: get_code(fullname) - Return the code object for a module. - ``None`` should be returned if the module does not have a code object - (e.g. built-in module). :exc:`ImportError` is raised if loader cannot - find the requested module. + Return the code object for a module, or ``None`` if the module does not + have a code object (as would be the case, for example, for a built-in + module). Raise an :exc:`ImportError` if loader cannot find the + requested module. .. note:: While the method has a default implementation, it is suggested that @@ -420,7 +509,7 @@ ABC hierarchy:: .. versionchanged:: 3.4 Raises :exc:`ImportError` instead of :exc:`NotImplementedError`. - .. method:: source_to_code(data, path='<string>') + .. staticmethod:: source_to_code(data, path='<string>') Create a code object from Python source. @@ -429,11 +518,26 @@ ABC hierarchy:: the "path" to where the source code originated from, which can be an abstract concept (e.g. location in a zip file). + With the subsequent code object one can execute it in a module by + running ``exec(code, module.__dict__)``. + .. versionadded:: 3.4 + .. versionchanged:: 3.5 + Made the method static. + + .. method:: exec_module(module) + + Implementation of :meth:`Loader.exec_module`. + + .. versionadded:: 3.4 + .. method:: load_module(fullname) - Implementation of :meth:`Loader.load_module`. + Implementation of :meth:`Loader.load_module`. + + .. deprecated:: 3.4 + use :meth:`exec_module` instead. .. class:: ExecutionLoader @@ -479,6 +583,9 @@ ABC hierarchy:: Calls super's ``load_module()``. + .. deprecated:: 3.4 + Use :meth:`Loader.exec_module` instead. + .. method:: get_filename(fullname) Returns :attr:`path`. @@ -518,12 +625,12 @@ ABC hierarchy:: - ``'size'`` (optional): the size in bytes of the source code. Any other keys in the dictionary are ignored, to allow for future - extensions. If the path cannot be handled, :exc:`IOError` is raised. + extensions. If the path cannot be handled, :exc:`OSError` is raised. .. versionadded:: 3.3 .. versionchanged:: 3.4 - Raise :exc:`IOError` instead of :exc:`NotImplementedError`. + Raise :exc:`OSError` instead of :exc:`NotImplementedError`. .. method:: path_mtime(path) @@ -533,10 +640,10 @@ ABC hierarchy:: .. deprecated:: 3.3 This method is deprecated in favour of :meth:`path_stats`. You don't have to implement it, but it is still available for compatibility - purposes. Raise :exc:`IOError` if the path cannot be handled. + purposes. Raise :exc:`OSError` if the path cannot be handled. - .. versionchanged:: 3.4 - Raise :exc:`IOError` instead of :exc:`NotImplementedError`. + .. versionchanged:: 3.4 + Raise :exc:`OSError` instead of :exc:`NotImplementedError`. .. method:: set_data(path, data) @@ -555,9 +662,18 @@ ABC hierarchy:: Concrete implementation of :meth:`InspectLoader.get_code`. + .. method:: exec_module(module) + + Concrete implementation of :meth:`Loader.exec_module`. + + .. versionadded:: 3.4 + .. method:: load_module(fullname) - Concrete implementation of :meth:`Loader.load_module`. + Concrete implementation of :meth:`Loader.load_module`. + + .. deprecated:: 3.4 + Use :meth:`exec_module` instead. .. method:: get_source(fullname) @@ -638,6 +754,10 @@ find and load modules. Only class methods are defined by this class to alleviate the need for instantiation. + .. note:: + Due to limitations in the extension module C-API, for now + BuiltinImporter does not implement :meth:`Loader.exec_module`. + .. class:: FrozenImporter @@ -668,28 +788,42 @@ find and load modules. Only class methods are defined by this class to alleviate the need for instantiation. + .. classmethod:: find_spec(fullname, path=None, target=None) + + Class method that attempts to find a :term:`spec <module spec>` + for the module specified by *fullname* on :data:`sys.path` or, if + defined, on *path*. For each path entry that is searched, + :data:`sys.path_importer_cache` is checked. If a non-false object + is found then it is used as the :term:`path entry finder` to look + for the module being searched for. If no entry is found in + :data:`sys.path_importer_cache`, then :data:`sys.path_hooks` is + searched for a finder for the path entry and, if found, is stored + in :data:`sys.path_importer_cache` along with being queried about + the module. If no finder is ever found then ``None`` is both + stored in the cache and returned. + + .. versionadded:: 3.4 + + .. versionchanged:: 3.5 + If the current working directory -- represented by an empty string -- + is no longer valid then ``None`` is returned but no value is cached + in :data:`sys.path_importer_cache`. + .. classmethod:: find_module(fullname, path=None) - Class method that attempts to find a :term:`loader` for the module - specified by *fullname* on :data:`sys.path` or, if defined, on - *path*. For each path entry that is searched, - :data:`sys.path_importer_cache` is checked. If a non-false object is - found then it is used as the :term:`path entry finder` to look for the - module being searched for. If no entry is found in - :data:`sys.path_importer_cache`, then :data:`sys.path_hooks` is - searched for a finder for the path entry and, if found, is stored in - :data:`sys.path_importer_cache` along with being queried about the - module. If no finder is ever found then ``None`` is both stored in - the cache and returned. + A legacy wrapper around :meth:`find_spec`. + + .. deprecated:: 3.4 + Use :meth:`find_spec` instead. .. classmethod:: invalidate_caches() - Calls :meth:`importlib.abc.PathEntryFinder.invalidate_caches` on all - finders stored in :attr:`sys.path_importer_cache`. + Calls :meth:`importlib.abc.PathEntryFinder.invalidate_caches` on all + finders stored in :attr:`sys.path_importer_cache`. - .. versionchanged:: 3.4 - Calls objects in :data:`sys.path_hooks` with the current working directory - for ``''`` (i.e. the empty string). + .. versionchanged:: 3.4 + Calls objects in :data:`sys.path_hooks` with the current working + directory for ``''`` (i.e. the empty string). .. class:: FileFinder(path, \*loader_details) @@ -721,6 +855,12 @@ find and load modules. The path the finder will search in. + .. method:: find_spec(fullname, target=None) + + Attempt to find the spec to handle *fullname* within :attr:`path`. + + .. versionadded:: 3.4 + .. method:: find_loader(fullname) Attempt to find the loader to handle *fullname* within :attr:`path`. @@ -768,6 +908,11 @@ find and load modules. Concrete implementation of :meth:`importlib.abc.SourceLoader.set_data`. + .. method:: load_module(name=None) + + Concrete implementation of :meth:`importlib.abc.Loader.load_module` where + specifying the name of the module to load is optional. + .. class:: SourcelessFileLoader(fullname, path) @@ -802,6 +947,11 @@ find and load modules. Returns ``None`` as bytecode files have no source when this loader is used. + .. method:: load_module(name=None) + + Concrete implementation of :meth:`importlib.abc.Loader.load_module` where + specifying the name of the module to load is optional. + .. class:: ExtensionFileLoader(fullname, path) @@ -821,11 +971,15 @@ find and load modules. Path to the extension module. - .. method:: load_module(fullname) + .. method:: load_module(name=None) Loads the extension module if and only if *fullname* is the same as :attr:`name` or is ``None``. + .. note:: + Due to limitations in the extension module C-API, for now + ExtensionFileLoader does not implement :meth:`Loader.exec_module`. + .. method:: is_package(fullname) Returns ``True`` if the file path points to a package's ``__init__`` @@ -901,7 +1055,7 @@ find and load modules. .. attribute:: has_location - (Read-only) Boolean indicating whether or not the module's "origin" + Boolean indicating whether or not the module's "origin" attribute refers to a loadable location. :mod:`importlib.util` -- Utility code for importers @@ -974,6 +1128,37 @@ an :term:`importer`. .. versionadded:: 3.3 +.. function:: find_spec(name, package=None) + + Find the :term:`spec <module spec>` for a module, optionally relative to + the specified **package** name. If the module is in :attr:`sys.modules`, + then ``sys.modules[name].__spec__`` is returned (unless the spec would be + ``None`` or is not set, in which case :exc:`ValueError` is raised). + Otherwise a search using :attr:`sys.meta_path` is done. ``None`` is + returned if no spec is found. + + If **name** is for a submodule (contains a dot), the parent module is + automatically imported. + + **name** and **package** work the same as for :func:`import_module`. + + .. versionadded:: 3.4 + +.. function:: module_from_spec(spec) + + Create a new module based on **spec** and ``spec.loader.create_module()``. + + If ``spec.loader.create_module()`` does not return ``None``, then any + pre-existing attributes will not be reset. Also, no :exc:`AttributeError` + will be raised if triggered while accessing **spec** or setting an attribute + on the module. + + This function is preferred over using :class:`types.ModuleType` to create a + new module as **spec** is used to set as many import-controlled attributes on + the module as possible. + + .. versionadded:: 3.5 + .. decorator:: module_for_loader A :term:`decorator` for :meth:`importlib.abc.Loader.load_module` @@ -1023,11 +1208,17 @@ an :term:`importer`. Set ``__loader__`` if set to ``None``, as if the attribute does not exist. + .. deprecated:: 3.4 + The import machinery takes care of this automatically. + .. decorator:: set_package A :term:`decorator` for :meth:`importlib.abc.Loader.load_module` to set the :attr:`__package__` attribute on the returned module. If :attr:`__package__` is set and has a value other than ``None`` it will not be changed. + .. deprecated:: 3.4 + The import machinery takes care of this automatically. + .. function:: spec_from_loader(name, loader, *, origin=None, is_package=None) A factory function for creating a :class:`ModuleSpec` instance based @@ -1046,3 +1237,39 @@ an :term:`importer`. module will be file-based. .. versionadded:: 3.4 + +.. class:: LazyLoader(loader) + + A class which postpones the execution of the loader of a module until the + module has an attribute accessed. + + This class **only** works with loaders that define + :meth:`~importlib.abc.Loader.exec_module` as control over what module type + is used for the module is required. For those same reasons, the loader's + :meth:`~importlib.abc.Loader.create_module` method will be ignored (i.e., the + loader's method should only return ``None``). Finally, + modules which substitute the object placed into :attr:`sys.modules` will + not work as there is no way to properly replace the module references + throughout the interpreter safely; :exc:`ValueError` is raised if such a + substitution is detected. + + .. note:: + For projects where startup time is critical, this class allows for + potentially minimizing the cost of loading a module if it is never used. + For projects where startup time is not essential then use of this class is + **heavily** discouraged due to error messages created during loading being + postponed and thus occurring out of context. + + .. versionadded:: 3.5 + + .. classmethod:: factory(loader) + + A static method which returns a callable that creates a lazy loader. This + is meant to be used in situations where the loader is passed by class + instead of by instance. + :: + + suffixes = importlib.machinery.SOURCE_SUFFIXES + loader = importlib.machinery.SourceFileLoader + lazy_loader = importlib.util.LazyLoader.factory(loader) + finder = importlib.machinery.FileFinder(path, [(lazy_loader, suffixes)]) diff --git a/Doc/library/index.rst b/Doc/library/index.rst index 81289a56c518..ac7ab91a29b3 100644 --- a/Doc/library/index.rst +++ b/Doc/library/index.rst @@ -30,7 +30,7 @@ optional components. In addition to the standard library, there is a growing collection of several thousand components (from individual programs and modules to packages and entire application development frameworks), available from -the `Python Package Index <http://pypi.python.org/pypi>`_. +the `Python Package Index <https://pypi.python.org/pypi>`_. .. toctree:: @@ -73,4 +73,5 @@ the `Python Package Index <http://pypi.python.org/pypi>`_. misc.rst windows.rst unix.rst + superseded.rst undoc.rst diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst index 41c61b79374d..3d2132fd8642 100644 --- a/Doc/library/inspect.rst +++ b/Doc/library/inspect.rst @@ -69,7 +69,12 @@ attributes: | | | :term:`bytecode` | +-----------+-----------------+---------------------------+ | | __defaults__ | tuple of any default | -| | | values for arguments | +| | | values for positional or | +| | | keyword parameters | ++-----------+-----------------+---------------------------+ +| | __kwdefaults__ | mapping of any default | +| | | values for keyword-only | +| | | parameters | +-----------+-----------------+---------------------------+ | | __globals__ | global namespace in which | | | | this function was defined | @@ -154,6 +159,16 @@ attributes: | | | arguments and local | | | | variables | +-----------+-----------------+---------------------------+ +| generator | __name__ | name | ++-----------+-----------------+---------------------------+ +| | __qualname__ | qualified name | ++-----------+-----------------+---------------------------+ +| | gi_frame | frame | ++-----------+-----------------+---------------------------+ +| | gi_running | is the generator running? | ++-----------+-----------------+---------------------------+ +| | gi_code | code | ++-----------+-----------------+---------------------------+ | builtin | __doc__ | documentation string | +-----------+-----------------+---------------------------+ | | __name__ | original name of this | @@ -164,6 +179,12 @@ attributes: | | | ``None`` | +-----------+-----------------+---------------------------+ +.. versionchanged:: 3.5 + + Add ``__qualname__`` attribute to generators. The ``__name__`` attribute of + generators is now set from the function name, instead of the code name, and + it can now be modified. + .. function:: getmembers(object[, predicate]) @@ -429,22 +450,37 @@ function. Accepts a wide range of python callables, from plain functions and classes to :func:`functools.partial` objects. + Raises :exc:`ValueError` if no signature can be provided, and + :exc:`TypeError` if that type of object is not supported. + .. note:: Some callables may not be introspectable in certain implementations of - Python. For example, in CPython, built-in functions defined in C provide - no metadata about their arguments. + Python. For example, in CPython, some built-in functions defined in + C provide no metadata about their arguments. -.. class:: Signature +.. class:: Signature(parameters=None, \*, return_annotation=Signature.empty) A Signature object represents the call signature of a function and its return annotation. For each parameter accepted by the function it stores a :class:`Parameter` object in its :attr:`parameters` collection. + The optional *parameters* argument is a sequence of :class:`Parameter` + objects, which is validated to check that there are no parameters with + duplicate names, and that the parameters are in the right order, i.e. + positional-only first, then positional-or-keyword, and that parameters with + defaults follow parameters without defaults. + + The optional *return_annotation* argument, can be an arbitrary Python object, + is the "return" annotation of the callable. + Signature objects are *immutable*. Use :meth:`Signature.replace` to make a modified copy. + .. versionchanged:: 3.5 + Signature objects are picklable and hashable. + .. attribute:: Signature.empty A special class-level marker to specify absence of a return annotation. @@ -489,12 +525,29 @@ function. >>> str(new_sig) "(a, b) -> 'new return anno'" + .. classmethod:: Signature.from_callable(obj) -.. class:: Parameter + Return a :class:`Signature` (or its subclass) object for a given callable + ``obj``. This method simplifies subclassing of :class:`Signature`: + + :: + + class MySignature(Signature): + pass + sig = MySignature.from_callable(min) + assert isinstance(sig, MySignature) + + .. versionadded:: 3.5 + + +.. class:: Parameter(name, kind, \*, default=Parameter.empty, annotation=Parameter.empty) Parameter objects are *immutable*. Instead of modifying a Parameter object, you can use :meth:`Parameter.replace` to create a modified copy. + .. versionchanged:: 3.5 + Parameter objects are picklable and hashable. + .. attribute:: Parameter.empty A special class-level marker to specify absence of default values and @@ -502,9 +555,8 @@ function. .. attribute:: Parameter.name - The name of the parameter as a string. Must be a valid python identifier - name (with the exception of ``POSITIONAL_ONLY`` parameters, which can have - it set to ``None``). + The name of the parameter as a string. The name must be a valid + Python identifier. .. attribute:: Parameter.default @@ -588,6 +640,10 @@ function. >>> str(param.replace(default=Parameter.empty, annotation='spam')) "foo:'spam'" + .. versionchanged:: 3.4 + In Python 3.3 Parameter objects were allowed to have ``name`` set + to ``None`` if their ``kind`` was set to ``POSITIONAL_ONLY``. + This is no longer permitted. .. class:: BoundArguments @@ -622,7 +678,8 @@ function. ((5,), {}) >>> for param in sig.parameters.values(): - ... if param.name not in ba.arguments: + ... if (param.name not in ba.arguments + ... and param.default is not param.empty): ... ba.arguments[param.name] = param.default >>> ba.args, ba.kwargs @@ -709,6 +766,11 @@ Classes and functions Consider using the new :ref:`Signature Object <inspect-signature-object>` interface, which provides a better way of introspecting functions. + .. versionchanged:: 3.4 + This function is now based on :func:`signature`, but still ignores + ``__wrapped__`` attributes and includes the already bound first + parameter in the signature output for bound methods. + .. function:: getargvalues(frame) @@ -725,17 +787,20 @@ Classes and functions :func:`getargspec` or :func:`getfullargspec`. The first seven arguments are (``args``, ``varargs``, ``varkw``, - ``defaults``, ``kwonlyargs``, ``kwonlydefaults``, ``annotations``). The - other five arguments are the corresponding optional formatting functions - that are called to turn names and values into strings. The last argument - is an optional function to format the sequence of arguments. For example:: + ``defaults``, ``kwonlyargs``, ``kwonlydefaults``, ``annotations``). - >>> from inspect import formatargspec, getfullargspec - >>> def f(a: int, b: float): - ... pass - ... - >>> formatargspec(*getfullargspec(f)) - '(a: int, b: float)' + The other six arguments are functions that are called to turn argument names, + ``*`` argument name, ``**`` argument name, default values, return annotation + and individual annotations into strings, respectively. + + For example: + + >>> from inspect import formatargspec, getfullargspec + >>> def f(a: int, b: float): + ... pass + ... + >>> formatargspec(*getfullargspec(f)) + '(a: int, b: float)' .. function:: formatargvalues(args[, varargs, varkw, locals, formatarg, formatvarargs, formatvarkw, formatvalue]) @@ -753,7 +818,7 @@ Classes and functions metatype is in use, cls will be the first element of the tuple. -.. function:: getcallargs(func[, *args][, **kwds]) +.. function:: getcallargs(func, *args, **kwds) Bind the *args* and *kwds* to the argument names of the Python function or method *func*, as if it was called with them. For bound methods, bind also the @@ -820,11 +885,17 @@ Classes and functions The interpreter stack --------------------- -When the following functions return "frame records," each record is a tuple of -six items: the frame object, the filename, the line number of the current line, +When the following functions return "frame records," each record is a +:term:`named tuple` +``FrameInfo(frame, filename, lineno, function, code_context, index)``. +The tuple contains the frame object, the filename, the line number of the +current line, the function name, a list of lines of context from the source code, and the index of the current line within that list. +.. versionchanged:: 3.5 + Return a named tuple instead of a tuple. + .. note:: Keeping references to frame objects, as found in the first element of the frame diff --git a/Doc/library/intro.rst b/Doc/library/intro.rst index a0f2d6324f65..e3283cac9947 100644 --- a/Doc/library/intro.rst +++ b/Doc/library/intro.rst @@ -30,10 +30,8 @@ requires them; yet others are available only when a particular configuration option was chosen at the time when Python was compiled and installed. This manual is organized "from the inside out:" it first describes the built-in -data types, then the built-in functions and exceptions, and finally the modules, -grouped in chapters of related modules. The ordering of the chapters as well as -the ordering of the modules within each chapter is roughly from most relevant to -least important. +functions, data types and exceptions, and finally the modules, grouped in +chapters of related modules. This means that if you start reading this manual from the start, and skip to the next chapter when you get bored, you will get a reasonable overview of the diff --git a/Doc/library/io.rst b/Doc/library/io.rst index 2b55018550c5..634bf5865452 100644 --- a/Doc/library/io.rst +++ b/Doc/library/io.rst @@ -289,7 +289,7 @@ I/O Base Classes most *size* bytes will be read. The line terminator is always ``b'\n'`` for binary files; for text files, - the *newlines* argument to :func:`open` can be used to select the line + the *newline* argument to :func:`open` can be used to select the line terminator(s) recognized. .. method:: readlines(hint=-1) @@ -353,6 +353,12 @@ I/O Base Classes is usual for each of the lines provided to have a line separator at the end. + .. method:: __del__() + + Prepare for object destruction. :class:`IOBase` provides a default + implementation of this method that calls the instance's + :meth:`~IOBase.close` method. + .. class:: RawIOBase @@ -385,8 +391,8 @@ I/O Base Classes .. method:: readinto(b) Read up to ``len(b)`` bytes into :class:`bytearray` *b* and return the - number of bytes read. If the object is in non-blocking mode and no - bytes are available, ``None`` is returned. + number of bytes read. If the object is in non-blocking mode and no bytes + are available, ``None`` is returned. .. method:: write(b) @@ -459,9 +465,10 @@ I/O Base Classes .. method:: read1(size=-1) - Read and return up to *size* bytes, with at most one call to the underlying - raw stream's :meth:`~RawIOBase.read` method. This can be useful if you - are implementing your own buffering on top of a :class:`BufferedIOBase` + Read and return up to *size* bytes, with at most one call to the + underlying raw stream's :meth:`~RawIOBase.read` (or + :meth:`~RawIOBase.readinto`) method. This can be useful if you are + implementing your own buffering on top of a :class:`BufferedIOBase` object. .. method:: readinto(b) @@ -472,8 +479,19 @@ I/O Base Classes Like :meth:`read`, multiple reads may be issued to the underlying raw stream, unless the latter is interactive. - A :exc:`BlockingIOError` is raised if the underlying raw stream is in - non blocking-mode, and has no data available at the moment. + A :exc:`BlockingIOError` is raised if the underlying raw stream is in non + blocking-mode, and has no data available at the moment. + + .. method:: readinto1(b) + + Read up to ``len(b)`` bytes into bytearray *b*, ,using at most one call to + the underlying raw stream's :meth:`~RawIOBase.read` (or + :meth:`~RawIOBase.readinto`) method. Return the number of bytes read. + + A :exc:`BlockingIOError` is raised if the underlying raw stream is in non + blocking-mode, and has no data available at the moment. + + .. versionadded:: 3.5 .. method:: write(b) @@ -501,9 +519,12 @@ Raw File I/O The *name* can be one of two things: * a character string or :class:`bytes` object representing the path to the - file which will be opened; + file which will be opened. In this case closefd must be True (the default) + otherwise an error will be raised. * an integer representing the number of an existing OS-level file descriptor - to which the resulting :class:`FileIO` object will give access. + to which the resulting :class:`FileIO` object will give access. When the + FileIO object is closed this fd will be closed as well, unless *closefd* + is set to ``False``. The *mode* can be ``'r'``, ``'w'``, ``'x'`` or ``'a'`` for reading (default), writing, exclusive creation or appending. The file will be @@ -557,7 +578,8 @@ than raw I/O does. .. class:: BytesIO([initial_bytes]) A stream implementation using an in-memory bytes buffer. It inherits - :class:`BufferedIOBase`. + :class:`BufferedIOBase`. The buffer is discarded when the + :meth:`~IOBase.close` method is called. The argument *initial_bytes* contains optional initial :class:`bytes` data. @@ -578,7 +600,7 @@ than raw I/O does. .. note:: As long as the view exists, the :class:`BytesIO` object cannot be - resized. + resized or closed. .. versionadded:: 3.2 @@ -586,10 +608,16 @@ than raw I/O does. Return :class:`bytes` containing the entire contents of the buffer. + .. method:: read1() In :class:`BytesIO`, this is the same as :meth:`read`. + .. method:: readinto1() + + In :class:`BytesIO`, this is the same as :meth:`readinto`. + + .. versionadded:: 3.5 .. class:: BufferedReader(raw, buffer_size=DEFAULT_BUFFER_SIZE) @@ -686,6 +714,7 @@ than raw I/O does. :exc:`UnsupportedOperation`. .. warning:: + :class:`BufferedRWPair` does not attempt to synchronize accesses to its underlying raw streams. You should not pass it the same object as reader and writer; use :class:`BufferedRandom` instead. @@ -798,11 +827,13 @@ Text I/O exception if there is an encoding error (the default of ``None`` has the same effect), or pass ``'ignore'`` to ignore errors. (Note that ignoring encoding errors can lead to data loss.) ``'replace'`` causes a replacement marker - (such as ``'?'``) to be inserted where there is malformed data. When - writing, ``'xmlcharrefreplace'`` (replace with the appropriate XML character - reference) or ``'backslashreplace'`` (replace with backslashed escape - sequences) can be used. Any other error handling name that has been - registered with :func:`codecs.register_error` is also valid. + (such as ``'?'``) to be inserted where there is malformed data. + ``'backslashreplace'`` causes malformed data to be replaced by a + backslashed escape sequence. When writing, ``'xmlcharrefreplace'`` + (replace with the appropriate XML character reference) or ``'namereplace'`` + (replace with ``\N{...}`` escape sequences) can be used. Any other error + handling name that has been registered with + :func:`codecs.register_error` is also valid. .. index:: single: universal newlines; io.TextIOWrapper class @@ -849,22 +880,22 @@ Text I/O Whether line buffering is enabled. -.. class:: StringIO(initial_value='', newline=None) +.. class:: StringIO(initial_value='', newline='\\n') - An in-memory stream for text I/O. + An in-memory stream for text I/O. The text buffer is discarded when the + :meth:`~IOBase.close` method is called. The initial value of the buffer (an empty string by default) can be set by providing *initial_value*. The *newline* argument works like that of - :class:`TextIOWrapper`. The default is to do no newline translation. + :class:`TextIOWrapper`. The default is to consider only ``\n`` characters + as end of lines and to do no newline translation. :class:`StringIO` provides this method in addition to those from :class:`TextIOBase` and its parents: .. method:: getvalue() - Return a ``str`` containing the entire contents of the buffer at any - time before the :class:`StringIO` object's :meth:`close` method is - called. + Return a ``str`` containing the entire contents of the buffer. Example usage:: diff --git a/Doc/library/ipaddress.rst b/Doc/library/ipaddress.rst index 826e4aa948f5..7b594408c878 100644 --- a/Doc/library/ipaddress.rst +++ b/Doc/library/ipaddress.rst @@ -9,13 +9,6 @@ -------------- -.. note:: - - The ``ipaddress`` module has been included in the standard library on a - :term:`provisional basis <provisional package>`. Backwards incompatible - changes (up to and including removal of the package) may occur if deemed - necessary by the core developers. - :mod:`ipaddress` provides the capabilities to create, manipulate and operate on IPv4 and IPv6 addresses and networks. @@ -25,8 +18,8 @@ hosts are on the same subnet, iterating over all hosts in a particular subnet, checking whether or not a string represents a valid IP address or network definition, and so on. -This is the full module API reference - for an overview and introduction, -see :ref:`ipaddress-howto`. +This is the full module API reference—for an overview and introduction, see +:ref:`ipaddress-howto`. .. versionadded:: 3.3 @@ -110,7 +103,7 @@ write code that handles both IP versions correctly. 1. A string in decimal-dot notation, consisting of four decimal integers in the inclusive range 0-255, separated by dots (e.g. ``192.168.0.1``). Each integer represents an octet (byte) in the address. Leading zeroes are - tolerated only for values less then 8 (as there is no ambiguity + tolerated only for values less than 8 (as there is no ambiguity between the decimal and octal interpretations of such strings). 2. An integer that fits into 32 bits. 3. An integer packed into a :class:`bytes` object of length 4 (most @@ -153,6 +146,20 @@ write code that handles both IP versions correctly. the appropriate length (most significant octet first). This is 4 bytes for IPv4 and 16 bytes for IPv6. + .. attribute:: reverse_pointer + + The name of the reverse DNS PTR record for the IP address, e.g.:: + + >>> ipaddress.ip_address("127.0.0.1").reverse_pointer + '1.0.0.127.in-addr.arpa' + >>> ipaddress.ip_address("2001:db8::1").reverse_pointer + '1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa' + + This is the name that could be used for performing a PTR lookup, not the + resolved hostname itself. + + .. versionadded:: 3.5 + .. attribute:: is_multicast ``True`` if the address is reserved for multicast use. See @@ -161,20 +168,20 @@ write code that handles both IP versions correctly. .. attribute:: is_private ``True`` if the address is allocated for private networks. See - iana-ipv4-special-registry (for IPv4) or iana-ipv6-special-registry + iana-ipv4-special-registry_ (for IPv4) or iana-ipv6-special-registry_ (for IPv6). .. attribute:: is_global ``True`` if the address is allocated for public networks. See - iana-ipv4-special-registry (for IPv4) or iana-ipv6-special-registry + iana-ipv4-special-registry_ (for IPv4) or iana-ipv6-special-registry_ (for IPv6). - .. versionadded:: 3.4 + .. versionadded:: 3.4 .. attribute:: is_unspecified - ``True`` if the address is unspecified. See :RFC:`5375` (for IPv4) + ``True`` if the address is unspecified. See :RFC:`5735` (for IPv4) or :RFC:`2373` (for IPv6). .. attribute:: is_reserved @@ -191,6 +198,9 @@ write code that handles both IP versions correctly. ``True`` if the address is reserved for link-local usage. See :RFC:`3927`. +.. _iana-ipv4-special-registry: http://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml +.. _iana-ipv6-special-registry: http://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml + .. class:: IPv6Address(address) @@ -225,18 +235,24 @@ write code that handles both IP versions correctly. The long form of the address representation, with all leading zeroes and groups consisting entirely of zeroes included. + + For the following attributes, see the corresponding documention of the + :class:`IPv4Address` class: + .. attribute:: packed + .. attribute:: reverse_pointer .. attribute:: version .. attribute:: max_prefixlen .. attribute:: is_multicast .. attribute:: is_private + .. attribute:: is_global .. attribute:: is_unspecified .. attribute:: is_reserved .. attribute:: is_loopback .. attribute:: is_link_local - Refer to the corresponding attribute documentation in - :class:`IPv4Address` + .. versionadded:: 3.4 + is_global .. attribute:: is_site_local @@ -376,6 +392,12 @@ so to avoid duplication they are only documented for :class:`IPv4Network`. 3. An integer packed into a :class:`bytes` object of length 4, big-endian. The interpretation is similar to an integer *address*. + 4. A two-tuple of an address description and a netmask, where the address + description is either a string, a 32-bits integer, a 4-bytes packed + integer, or an existing IPv4Address object; and the netmask is either + an integer representing the prefix length (e.g. ``24``) or a string + representing the prefix mask (e.g. ``255.255.255.0``). + An :exc:`AddressValueError` is raised if *address* is not a valid IPv4 address. A :exc:`NetmaskValueError` is raised if the mask is not valid for an IPv4 address. @@ -388,6 +410,10 @@ so to avoid duplication they are only documented for :class:`IPv4Network`. objects will raise :exc:`TypeError` if the argument's IP version is incompatible to ``self`` + .. versionchanged:: 3.5 + + Added the two-tuple form for the *address* constructor parameter. + .. attribute:: version .. attribute:: max_prefixlen @@ -414,7 +440,7 @@ so to avoid duplication they are only documented for :class:`IPv4Network`. The broadcast address for the network. Packets sent to the broadcast address should be received by every host on the network. - .. attribute:: host mask + .. attribute:: hostmask The host mask, as a string. @@ -552,6 +578,11 @@ so to avoid duplication they are only documented for :class:`IPv4Network`. 3. An integer packed into a :class:`bytes` object of length 16, bit-endian. The interpretation is similar to an integer *address*. + 4. A two-tuple of an address description and a netmask, where the address + description is either a string, a 128-bits integer, a 16-bytes packed + integer, or an existing IPv4Address object; and the netmask is an + integer representing the prefix length. + An :exc:`AddressValueError` is raised if *address* is not a valid IPv6 address. A :exc:`NetmaskValueError` is raised if the mask is not valid for an IPv6 address. @@ -560,6 +591,10 @@ so to avoid duplication they are only documented for :class:`IPv4Network`. then :exc:`ValueError` is raised. Otherwise, the host bits are masked out to determine the appropriate network address. + .. versionchanged:: 3.5 + + Added the two-tuple form for the *address* constructor parameter. + .. attribute:: version .. attribute:: max_prefixlen .. attribute:: is_multicast @@ -570,7 +605,7 @@ so to avoid duplication they are only documented for :class:`IPv4Network`. .. attribute:: is_link_local .. attribute:: network_address .. attribute:: broadcast_address - .. attribute:: host mask + .. attribute:: hostmask .. attribute:: with_prefixlen .. attribute:: compressed .. attribute:: exploded diff --git a/Doc/library/ipc.rst b/Doc/library/ipc.rst index 2440bd4d6bde..6b1756331ec0 100644 --- a/Doc/library/ipc.rst +++ b/Doc/library/ipc.rst @@ -9,7 +9,7 @@ to communicate. Some modules only work for two processes that are on the same machine, e.g. :mod:`signal` and :mod:`mmap`. Other modules support networking protocols -that two or more processes can used to communicate across machines. +that two or more processes can use to communicate across machines. The list of modules described in this chapter is: diff --git a/Doc/library/itertools.rst b/Doc/library/itertools.rst index 6929192b4fe0..8c7592d17e9e 100644 --- a/Doc/library/itertools.rst +++ b/Doc/library/itertools.rst @@ -43,22 +43,22 @@ Iterator Arguments Results **Iterators terminating on the shortest input sequence:** -==================== ============================ ================================================= ============================================================= -Iterator Arguments Results Example -==================== ============================ ================================================= ============================================================= -:func:`accumulate` p [,func] p0, p0+p1, p0+p1+p2, ... ``accumulate([1,2,3,4,5]) --> 1 3 6 10 15`` -:func:`chain` p, q, ... p0, p1, ... plast, q0, q1, ... ``chain('ABC', 'DEF') --> A B C D E F`` -chain.from_iterable iterable p0, p1, ... plast, q0, q1, ... ``chain.from_iterable(['ABC', 'DEF']) --> A B C D E F`` -:func:`compress` data, selectors (d[0] if s[0]), (d[1] if s[1]), ... ``compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F`` -:func:`dropwhile` pred, seq seq[n], seq[n+1], starting when pred fails ``dropwhile(lambda x: x<5, [1,4,6,4,1]) --> 6 4 1`` -:func:`filterfalse` pred, seq elements of seq where pred(elem) is false ``filterfalse(lambda x: x%2, range(10)) --> 0 2 4 6 8`` -:func:`groupby` iterable[, keyfunc] sub-iterators grouped by value of keyfunc(v) -:func:`islice` seq, [start,] stop [, step] elements from seq[start:stop:step] ``islice('ABCDEFG', 2, None) --> C D E F G`` -:func:`starmap` func, seq func(\*seq[0]), func(\*seq[1]), ... ``starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000`` -:func:`takewhile` pred, seq seq[0], seq[1], until pred fails ``takewhile(lambda x: x<5, [1,4,6,4,1]) --> 1 4`` -:func:`tee` it, n it1, it2 , ... itn splits one iterator into n -:func:`zip_longest` p, q, ... (p[0], q[0]), (p[1], q[1]), ... ``zip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D-`` -==================== ============================ ================================================= ============================================================= +============================ ============================ ================================================= ============================================================= +Iterator Arguments Results Example +============================ ============================ ================================================= ============================================================= +:func:`accumulate` p [,func] p0, p0+p1, p0+p1+p2, ... ``accumulate([1,2,3,4,5]) --> 1 3 6 10 15`` +:func:`chain` p, q, ... p0, p1, ... plast, q0, q1, ... ``chain('ABC', 'DEF') --> A B C D E F`` +:func:`chain.from_iterable` iterable p0, p1, ... plast, q0, q1, ... ``chain.from_iterable(['ABC', 'DEF']) --> A B C D E F`` +:func:`compress` data, selectors (d[0] if s[0]), (d[1] if s[1]), ... ``compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F`` +:func:`dropwhile` pred, seq seq[n], seq[n+1], starting when pred fails ``dropwhile(lambda x: x<5, [1,4,6,4,1]) --> 6 4 1`` +:func:`filterfalse` pred, seq elements of seq where pred(elem) is false ``filterfalse(lambda x: x%2, range(10)) --> 0 2 4 6 8`` +:func:`groupby` iterable[, keyfunc] sub-iterators grouped by value of keyfunc(v) +:func:`islice` seq, [start,] stop [, step] elements from seq[start:stop:step] ``islice('ABCDEFG', 2, None) --> C D E F G`` +:func:`starmap` func, seq func(\*seq[0]), func(\*seq[1]), ... ``starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000`` +:func:`takewhile` pred, seq seq[0], seq[1], until pred fails ``takewhile(lambda x: x<5, [1,4,6,4,1]) --> 1 4`` +:func:`tee` it, n it1, it2, ... itn splits one iterator into n +:func:`zip_longest` p, q, ... (p[0], q[0]), (p[1], q[1]), ... ``zip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D-`` +============================ ============================ ================================================= ============================================================= **Combinatoric generators:** @@ -87,10 +87,15 @@ loops that truncate the stream. .. function:: accumulate(iterable[, func]) - Make an iterator that returns accumulated sums. Elements may be any addable - type including :class:`~decimal.Decimal` or :class:`~fractions.Fraction`. - If the optional *func* argument is supplied, it should be a function of two - arguments and it will be used instead of addition. + Make an iterator that returns accumulated sums, or accumulated + results of other binary functions (specified via the optional + *func* argument). If *func* is supplied, it should be a function + of two arguments. Elements of the input *iterable* may be any type + that can be accepted as arguments to *func*. (For example, with + the default operation of addition, elements may be any addable + type including :class:`~decimal.Decimal` or + :class:`~fractions.Fraction`.) If the input iterable is empty, the + output iterable will also be empty. Equivalent to:: @@ -99,7 +104,10 @@ loops that truncate the stream. # accumulate([1,2,3,4,5]) --> 1 3 6 10 15 # accumulate([1,2,3,4,5], operator.mul) --> 1 2 6 24 120 it = iter(iterable) - total = next(it) + try: + total = next(it) + except StopIteration: + return yield total for element in it: total = func(total, element) @@ -131,7 +139,7 @@ loops that truncate the stream. >>> inputs = repeat(x0, 36) # only the initial value is used >>> [format(x, '.2f') for x in accumulate(inputs, logistic_map)] ['0.40', '0.91', '0.30', '0.81', '0.60', '0.92', '0.29', '0.79', '0.63', - '0.88' ,'0.39', '0.90', '0.33', '0.84', '0.52', '0.95', '0.18', '0.57', + '0.88', '0.39', '0.90', '0.33', '0.84', '0.52', '0.95', '0.18', '0.57', '0.93', '0.25', '0.71', '0.79', '0.63', '0.88', '0.39', '0.91', '0.32', '0.83', '0.54', '0.95', '0.20', '0.60', '0.91', '0.30', '0.80', '0.60'] @@ -400,7 +408,10 @@ loops that truncate the stream. def _grouper(self, tgtkey): while self.currkey == tgtkey: yield self.currvalue - self.currvalue = next(self.it) # Exit on StopIteration + try: + self.currvalue = next(self.it) + except StopIteration: + return self.currkey = self.keyfunc(self.currvalue) @@ -424,7 +435,10 @@ loops that truncate the stream. # islice('ABCDEFG', 0, None, 2) --> A C E G s = slice(*args) it = iter(range(s.start or 0, s.stop or sys.maxsize, s.step or 1)) - nexti = next(it) + try: + nexti = next(it) + except StopIteration: + return for i, element in enumerate(iterable): if i == nexti: yield element @@ -582,7 +596,10 @@ loops that truncate the stream. def gen(mydeque): while True: if not mydeque: # when the local deque is empty - newval = next(it) # fetch a new value and + try: + newval = next(it) # fetch a new value and + except StopIteration: + return for d in deques: # load it to all the deques d.append(newval) yield mydeque.popleft() @@ -657,6 +674,11 @@ which incur interpreter overhead. "Return function(0), function(1), ..." return map(function, count(start)) + def tail(n, iterable): + "Return an iterator over the last n items" + # tail(3, 'ABCDEFG') --> E F G + return iter(collections.deque(iterable, maxlen=n)) + def consume(iterator, n): "Advance the iterator n-steps ahead. If n is none, consume entirely." # Use functions that consume iterators at C speed. @@ -784,6 +806,19 @@ which incur interpreter overhead. except exception: pass + def first_true(iterable, default=False, pred=None): + """Returns the first true value in the iterable. + + If no true value is found, returns *default* + + If *pred* is not None, returns the first item + for which pred(item) is true. + + """ + # first_true([a,b,c], x) --> a or b or c or x + # first_true([a,b], x, f) --> a if f(a) else b if f(b) else x + return next(filter(pred, iterable), default) + def random_product(*args, repeat=1): "Random selection from itertools.product(*args, **kwds)" pools = [tuple(pool) for pool in args] * repeat diff --git a/Doc/library/json.rst b/Doc/library/json.rst index 5d97ee88fc49..49bb0905e01d 100644 --- a/Doc/library/json.rst +++ b/Doc/library/json.rst @@ -7,9 +7,11 @@ .. sectionauthor:: Bob Ippolito <bob@redivi.com> `JSON (JavaScript Object Notation) <http://json.org>`_, specified by -:rfc:`4627`, is a lightweight data interchange format based on a subset of -`JavaScript <http://en.wikipedia.org/wiki/JavaScript>`_ syntax (`ECMA-262 3rd -edition <http://www.ecma-international.org/publications/files/ECMA-ST-ARCH/ECMA-262,%203rd%20edition,%20December%201999.pdf>`_). +:rfc:`7159` (which obsoletes :rfc:`4627`) and by +`ECMA-404 <http://www.ecma-international.org/publications/standards/Ecma-404.htm>`_, +is a lightweight data interchange format inspired by +`JavaScript <http://en.wikipedia.org/wiki/JavaScript>`_ object literal syntax +(although it is not a strict subset of JavaScript [#rfc-errata]_ ). :mod:`json` exposes an API familiar to users of the standard library :mod:`marshal` and :mod:`pickle` modules. @@ -97,13 +99,15 @@ Extending :class:`JSONEncoder`:: Using json.tool from the shell to validate and pretty-print:: - $ echo '{"json":"obj"}' | python -mjson.tool + $ echo '{"json":"obj"}' | python -m json.tool { "json": "obj" } - $ echo '{1.2:3.4}' | python -mjson.tool + $ echo '{1.2:3.4}' | python -m json.tool Expecting property name enclosed in double quotes: line 1 column 2 (char 1) +See :ref:`json-commandline` for detailed documentation. + .. highlight:: python3 .. note:: @@ -246,7 +250,7 @@ Basic Usage will be passed to the constructor of the class. If the data being deserialized is not a valid JSON document, a - :exc:`ValueError` will be raised. + :exc:`JSONDecodeError` will be raised. .. function:: loads(s, encoding=None, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw) @@ -257,7 +261,7 @@ Basic Usage *encoding* which is ignored and deprecated. If the data being deserialized is not a valid JSON document, a - :exc:`ValueError` will be raised. + :exc:`JSONDecodeError` will be raised. Encoders and Decoders --------------------- @@ -330,13 +334,16 @@ Encoders and Decoders ``'\n'``, ``'\r'`` and ``'\0'``. If the data being deserialized is not a valid JSON document, a - :exc:`ValueError` will be raised. + :exc:`JSONDecodeError` will be raised. .. method:: decode(s) Return the Python representation of *s* (a :class:`str` instance containing a JSON document) + :exc:`JSONDecodeError` will be raised if the given JSON document is not + valid. + .. method:: raw_decode(s) Decode a JSON document from *s* (a :class:`str` beginning with a @@ -465,18 +472,48 @@ Encoders and Decoders mysocket.write(chunk) -Standard Compliance -------------------- +Exceptions +---------- + +.. exception:: JSONDecodeError(msg, doc, pos, end=None) + + Subclass of :exc:`ValueError` with the following additional attributes: + + .. attribute:: msg + + The unformatted error message. + + .. attribute:: doc + + The JSON document being parsed. + + .. attribute:: pos + + The start index of *doc* where parsing failed. + + .. attribute:: lineno + + The line corresponding to *pos*. + + .. attribute:: colno + + The column corresponding to *pos*. + + .. versionadded:: 3.5 + -The JSON format is specified by :rfc:`4627`. This section details this -module's level of compliance with the RFC. For simplicity, -:class:`JSONEncoder` and :class:`JSONDecoder` subclasses, and parameters other -than those explicitly mentioned, are not considered. +Standard Compliance and Interoperability +---------------------------------------- + +The JSON format is specified by :rfc:`7159` and by +`ECMA-404 <http://www.ecma-international.org/publications/standards/Ecma-404.htm>`_. +This section details this module's level of compliance with the RFC. +For simplicity, :class:`JSONEncoder` and :class:`JSONDecoder` subclasses, and +parameters other than those explicitly mentioned, are not considered. This module does not comply with the RFC in a strict fashion, implementing some extensions that are valid JavaScript but not valid JSON. In particular: -- Top-level non-object, non-array values are accepted and output; - Infinite and NaN number values are accepted and output; - Repeated names within an object are accepted, and only the value of the last name-value pair is used. @@ -488,8 +525,8 @@ default settings. Character Encodings ^^^^^^^^^^^^^^^^^^^ -The RFC recommends that JSON be represented using either UTF-8, UTF-16, or -UTF-32, with UTF-8 being the default. +The RFC requires that JSON be represented using either UTF-8, UTF-16, or +UTF-32, with UTF-8 being the recommended default for maximum interoperability. As permitted, though not required, by the RFC, this module's serializer sets *ensure_ascii=True* by default, thus escaping the output so that the resulting @@ -497,34 +534,20 @@ strings only contain ASCII characters. Other than the *ensure_ascii* parameter, this module is defined strictly in terms of conversion between Python objects and -:class:`Unicode strings <str>`, and thus does not otherwise address the issue -of character encodings. - - -Top-level Non-Object, Non-Array Values -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The RFC specifies that the top-level value of a JSON text must be either a -JSON object or array (Python :class:`dict` or :class:`list`). This module's -deserializer also accepts input texts consisting solely of a -JSON null, boolean, number, or string value:: - - >>> just_a_json_string = '"spam and eggs"' # Not by itself a valid JSON text - >>> json.loads(just_a_json_string) - 'spam and eggs' - -This module itself does not include a way to request that such input texts be -regarded as illegal. Likewise, this module's serializer also accepts single -Python :data:`None`, :class:`bool`, numeric, and :class:`str` -values as input and will generate output texts consisting solely of a top-level -JSON null, boolean, number, or string value without raising an exception:: +:class:`Unicode strings <str>`, and thus does not otherwise directly address +the issue of character encodings. - >>> neither_a_list_nor_a_dict = "spam and eggs" - >>> json.dumps(neither_a_list_nor_a_dict) # The result is not a valid JSON text - '"spam and eggs"' +The RFC prohibits adding a byte order mark (BOM) to the start of a JSON text, +and this module's serializer does not add a BOM to its output. +The RFC permits, but does not require, JSON deserializers to ignore an initial +BOM in their input. This module's deserializer raises a :exc:`ValueError` +when an initial BOM is present. -This module's serializer does not itself include a way to enforce the -aforementioned constraint. +The RFC does not explicitly forbid JSON strings which contain byte sequences +that don't correspond to valid Unicode characters (e.g. unpaired UTF-16 +surrogates), but it does note that they may cause interoperability problems. +By default, this module accepts and outputs (when present in the original +:class:`str`) code points for such sequences. Infinite and NaN Number Values @@ -554,7 +577,7 @@ Repeated Names Within an Object ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The RFC specifies that the names within a JSON object should be unique, but -does not specify how repeated names in JSON objects should be handled. By +does not mandate how repeated names in JSON objects should be handled. By default, this module does not raise an exception; instead, it ignores all but the last name-value pair for a given name:: @@ -563,3 +586,110 @@ the last name-value pair for a given name:: {'x': 3} The *object_pairs_hook* parameter can be used to alter this behavior. + + +Top-level Non-Object, Non-Array Values +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The old version of JSON specified by the obsolete :rfc:`4627` required that +the top-level value of a JSON text must be either a JSON object or array +(Python :class:`dict` or :class:`list`), and could not be a JSON null, +boolean, number, or string value. :rfc:`7159` removed that restriction, and +this module does not and has never implemented that restriction in either its +serializer or its deserializer. + +Regardless, for maximum interoperability, you may wish to voluntarily adhere +to the restriction yourself. + + +Implementation Limitations +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Some JSON deserializer implementations may set limits on: + +* the size of accepted JSON texts +* the maximum level of nesting of JSON objects and arrays +* the range and precision of JSON numbers +* the content and maximum length of JSON strings + +This module does not impose any such limits beyond those of the relevant +Python datatypes themselves or the Python interpreter itself. + +When serializing to JSON, beware any such limitations in applications that may +consume your JSON. In particular, it is common for JSON numbers to be +deserialized into IEEE 754 double precision numbers and thus subject to that +representation's range and precision limitations. This is especially relevant +when serializing Python :class:`int` values of extremely large magnitude, or +when serializing instances of "exotic" numerical types such as +:class:`decimal.Decimal`. + +.. highlight:: bash +.. module:: json.tool + +.. _json-commandline: + +Command Line Interface +---------------------- + +The :mod:`json.tool` module provides a simple command line interface to validate +and pretty-print JSON objects. + +If the optional ``infile`` and ``outfile`` arguments are not +specified, :attr:`sys.stdin` and :attr:`sys.stdout` will be used respectively:: + + $ echo '{"json": "obj"}' | python -m json.tool + { + "json": "obj" + } + $ echo '{1.2:3.4}' | python -m json.tool + Expecting property name enclosed in double quotes: line 1 column 2 (char 1) + +.. versionchanged:: 3.5 + The output is now in the same order as the input. Use the + :option:`--sort-keys` option to sort the output of dictionaries + alphabetically by key. + +Command line options +^^^^^^^^^^^^^^^^^^^^ + +.. cmdoption:: infile + + The JSON file to be validated or pretty-printed:: + + $ python -m json.tool mp_films.json + [ + { + "title": "And Now for Something Completely Different", + "year": 1971 + }, + { + "title": "Monty Python and the Holy Grail", + "year": 1975 + } + ] + + If *infile* is not specified, read from :attr:`sys.stdin`. + +.. cmdoption:: outfile + + Write the output of the *infile* to the given *outfile*. Otherwise, write it + to :attr:`sys.stdout`. + +.. cmdoption:: --sort-keys + + Sort the output of dictionaries alphabetically by key. + + .. versionadded:: 3.5 + +.. cmdoption:: -h, --help + + Show the help message. + + +.. rubric:: Footnotes + +.. [#rfc-errata] As noted in `the errata for RFC 7159 + <http://www.rfc-editor.org/errata_search.php?rfc=7159>`_, + JSON permits literal U+2028 (LINE SEPARATOR) and + U+2029 (PARAGRAPH SEPARATOR) characters in strings, whereas JavaScript + (as of ECMAScript Edition 5.1) does not. diff --git a/Doc/library/locale.rst b/Doc/library/locale.rst index 9600193547e1..bc7f5f932be8 100644 --- a/Doc/library/locale.rst +++ b/Doc/library/locale.rst @@ -387,6 +387,14 @@ The :mod:`locale` module defines the following exception and functions: ``str(float)``, but takes the decimal point into account. +.. function:: delocalize(string) + + Converts a string into a normalized number string, following the + :const:`LC_NUMERIC` settings. + + .. versionadded:: 3.5 + + .. function:: atof(string) Converts a string to a floating point number, following the :const:`LC_NUMERIC` diff --git a/Doc/library/logging.config.rst b/Doc/library/logging.config.rst index 8c15ee27614c..180569b21083 100644 --- a/Doc/library/logging.config.rst +++ b/Doc/library/logging.config.rst @@ -80,7 +80,9 @@ in :mod:`logging` itself) and defining handlers which are declared either in .. function:: fileConfig(fname, defaults=None, disable_existing_loggers=True) - Reads the logging configuration from a :mod:`configparser`\-format file. + Reads the logging configuration from a :mod:`configparser`\-format file. The + format of the file should be as described in + :ref:`logging-config-fileformat`. This function can be called several times from an application, allowing an end user to select from various pre-canned configurations (if the developer provides a mechanism to present the choices and load the chosen @@ -103,7 +105,7 @@ 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 - alone. The default is ``True`` because this + enabled. The default is ``True`` because this enables old behaviour in a backward- compatible way. This behaviour is to disable any existing loggers unless they or @@ -146,7 +148,9 @@ in :mod:`logging` itself) and defining handlers which are declared either in send it to the socket as a string of bytes preceded by a four-byte length string packed in binary using ``struct.pack('>L', n)``. - .. note:: Because portions of the configuration are passed through + .. note:: + + Because portions of the configuration are passed through :func:`eval`, use of this function may open its users to a security risk. While the function only binds to a socket on ``localhost``, and so does not accept connections from remote machines, there are scenarios where @@ -750,7 +754,9 @@ The ``class`` entry is optional. It indicates the name of the formatter's class :class:`~logging.Formatter` can present exception tracebacks in an expanded or condensed format. -.. note:: Due to the use of :func:`eval` as described above, there are +.. note:: + + Due to the use of :func:`eval` as described above, there are potential security risks which result from using the :func:`listen` to send and receive configurations via sockets. The risks are limited to where multiple users with no mutual trust run code on the same machine; see the diff --git a/Doc/library/logging.handlers.rst b/Doc/library/logging.handlers.rst index 315c168f1ddf..67403a9bc6ed 100644 --- a/Doc/library/logging.handlers.rst +++ b/Doc/library/logging.handlers.rst @@ -269,15 +269,16 @@ 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 *maxBytes* 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`, :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. + 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`, + :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. .. method:: doRollover() @@ -435,7 +436,7 @@ sends logging output to a network socket. The base class uses a TCP socket. .. method:: createSocket() Tries to create a socket; on failure, uses an exponential back-off - algorithm. On intial failure, the handler will drop the message it was + algorithm. On initial failure, the handler will drop the message it was trying to send. When subsequent messages are handled by the same instance, it will not try connecting until some time has passed. The default parameters are such that the initial delay is one second, and if @@ -839,21 +840,43 @@ supports sending logging messages to a Web server, using either ``GET`` or ``POST`` semantics. -.. class:: HTTPHandler(host, url, method='GET', secure=False, credentials=None) +.. class:: HTTPHandler(host, url, method='GET', secure=False, credentials=None, context=None) Returns a new instance of the :class:`HTTPHandler` class. The *host* can be - of the form ``host:port``, should you need to use a specific port number. - If no *method* is specified, ``GET`` is used. If *secure* is true, an HTTPS - connection will be used. If *credentials* is specified, it should be a - 2-tuple consisting of userid and password, which will be placed in an HTTP + of the form ``host:port``, should you need to use a specific port number. If + no *method* is specified, ``GET`` is used. If *secure* is true, a HTTPS + connection will be used. The *context* parameter may be set to a + :class:`ssl.SSLContext` instance to configure the SSL settings used for the + HTTPS connection. If *credentials* is specified, it should be a 2-tuple + consisting of userid and password, which will be placed in a HTTP 'Authorization' header using Basic authentication. If you specify credentials, you should also specify secure=True so that your userid and password are not passed in cleartext across the wire. + .. versionchanged:: 3.5 + The *context* parameter was added. + + .. method:: mapLogRecord(record) + + Provides a dictionary, based on ``record``, which is to be URL-encoded + and sent to the web server. The default implementation just returns + ``record.__dict__``. This method can be overridden if e.g. only a + subset of :class:`~logging.LogRecord` is to be sent to the web server, or + if more specific customization of what's sent to the server is required. .. method:: emit(record) - Sends the record to the Web server as a percent-encoded dictionary. + Sends the record to the Web server as an URL-encoded dictionary. The + :meth:`mapLogRecord` method is used to convert the record to the + dictionary to be sent. + + .. note:: Since preparing a record for sending it to a Web server is not + the same as a generic formatting operation, using + :meth:`~logging.Handler.setFormatter` to specify a + :class:`~logging.Formatter` for a :class:`HTTPHandler` has no effect. + Instead of calling :meth:`~logging.Handler.format`, this handler calls + :meth:`mapLogRecord` and then :func:`urllib.parse.urlencode` to encode the + dictionary in a form suitable for sending to a Web server. .. _queue-handler: @@ -930,13 +953,20 @@ applications where threads servicing clients need to respond as quickly as possible, while any potentially slow operations (such as sending an email via :class:`SMTPHandler`) are done on a separate thread. -.. class:: QueueListener(queue, *handlers) +.. class:: QueueListener(queue, *handlers, respect_handler_level=False) 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 - to know how to get messages from it. + 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 + is as in previous Python versions - to always pass each message to each + handler. + + .. versionchanged:: 3.5 + The ``respect_handler_levels`` argument was added. .. method:: dequeue(block) diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst index 29e9617283e4..7915c277df04 100644 --- a/Doc/library/logging.rst +++ b/Doc/library/logging.rst @@ -113,10 +113,14 @@ is the module's name in the Python package namespace. If the root is reached, and it has a level of NOTSET, then all messages will be processed. Otherwise, the root's level will be used as the effective level. + See :ref:`levels` for a list of levels. + .. versionchanged:: 3.2 The *lvl* parameter now accepts a string representation of the level such as 'INFO' as an alternative to the integer constants - such as :const:`INFO`. + such as :const:`INFO`. Note, however, that levels are internally stored + as integers, and methods such as e.g. :meth:`getEffectiveLevel` and + :meth:`isEnabledFor` will return/expect to be passed integers. .. method:: Logger.isEnabledFor(lvl) @@ -132,7 +136,9 @@ is the module's name in the Python package namespace. Indicates the effective level for this logger. If a value other than :const:`NOTSET` has been set using :meth:`setLevel`, it is returned. Otherwise, the hierarchy is traversed towards the root until a value other than - :const:`NOTSET` is found, and that value is returned. + :const:`NOTSET` is found, and that value is returned. The value returned is + an integer, typically one of :const:`logging.DEBUG`, :const:`logging.INFO` + etc. .. method:: Logger.getChild(suffix) @@ -153,11 +159,13 @@ is the module's name in the Python package namespace. *msg* using the string formatting operator. (Note that this means that you can use keywords in the format string, together with a single dictionary argument.) - There are three keyword arguments in *kwargs* which are inspected: *exc_info* - which, if it does not evaluate as false, causes exception information to be + There are three keyword arguments in *kwargs* which are inspected: + *exc_info*, *stack_info*, and *extra*. + + If *exc_info* does not evaluate as false, it causes exception information to be added to the logging message. If an exception tuple (in the format returned by - :func:`sys.exc_info`) is provided, it is used; otherwise, :func:`sys.exc_info` - is called to get the exception information. + :func:`sys.exc_info`) or an exception instance is provided, it is used; + otherwise, :func:`sys.exc_info` is called to get the exception information. The second optional keyword argument is *stack_info*, which defaults to ``False``. If true, stack information is added to the logging @@ -214,6 +222,9 @@ is the module's name in the Python package namespace. .. versionadded:: 3.2 The *stack_info* parameter was added. + .. versionchanged:: 3.5 + The *exc_info* parameter can now accept exception instances. + .. method:: Logger.info(msg, *args, **kwargs) @@ -248,7 +259,7 @@ is the module's name in the Python package namespace. interpreted as for :meth:`debug`. -.. method:: Logger.exception(msg, *args) +.. method:: Logger.exception(msg, *args, **kwargs) Logs a message with level :const:`ERROR` on this logger. The arguments are interpreted as for :meth:`debug`. Exception info is added to the logging @@ -316,6 +327,34 @@ is the module's name in the Python package namespace. .. versionadded:: 3.2 +.. _levels: + +Logging Levels +-------------- + +The numeric values of logging levels are given in the following table. These are +primarily of interest if you want to define your own levels, and need them to +have specific values relative to the predefined levels. If you define a level +with the same numeric value, it overwrites the predefined value; the predefined +name is lost. + ++--------------+---------------+ +| Level | Numeric value | ++==============+===============+ +| ``CRITICAL`` | 50 | ++--------------+---------------+ +| ``ERROR`` | 40 | ++--------------+---------------+ +| ``WARNING`` | 30 | ++--------------+---------------+ +| ``INFO`` | 20 | ++--------------+---------------+ +| ``DEBUG`` | 10 | ++--------------+---------------+ +| ``NOTSET`` | 0 | ++--------------+---------------+ + + .. _handler: Handler Objects @@ -356,6 +395,8 @@ subclasses. However, the :meth:`__init__` method in subclasses needs to call severe than *lvl* will be ignored. When a handler is created, the level is set to :const:`NOTSET` (which causes all messages to be processed). + See :ref:`levels` for a list of levels. + .. versionchanged:: 3.2 The *lvl* parameter now accepts a string representation of the level such as 'INFO' as an alternative to the integer constants @@ -468,7 +509,8 @@ The useful mapping keys in a :class:`LogRecord` are given in the section on The *style* parameter can be one of '%', '{' or '$' and determines how the format string will be merged with its data: using one of %-formatting, - :meth:`str.format` or :class:`string.Template`. + :meth:`str.format` or :class:`string.Template`. See :ref:`formatting-styles` + for more information on using {- and $-formatting for log messages. .. versionchanged:: 3.2 The *style* parameter was added. @@ -777,7 +819,7 @@ LoggerAdapter Objects --------------------- :class:`LoggerAdapter` instances are used to conveniently pass contextual -information into logging calls. For a usage example , see the section on +information into logging calls. For a usage example, see the section on :ref:`adding contextual information to your logging output <context-info>`. .. class:: LoggerAdapter(logger, extra) @@ -959,7 +1001,7 @@ functions. are interpreted as for :func:`debug`. -.. function:: exception(msg, *args) +.. function:: exception(msg, *args, **kwargs) Logs a message with level :const:`ERROR` on the root logger. The arguments are interpreted as for :func:`debug`. Exception info is added to the logging @@ -970,14 +1012,15 @@ functions. Logs a message with level *level* on the root logger. The other arguments are interpreted as for :func:`debug`. - .. note:: The above module-level functions which delegate to the root - logger should *not* be used in threads, in versions of Python earlier - than 2.7.1 and 3.2, unless at least one handler has been added to the - root logger *before* the threads are started. These convenience functions - call :func:`basicConfig` to ensure that at least one handler is - available; in earlier versions of Python, this can (under rare - circumstances) lead to handlers being added multiple times to the root - logger, which can in turn lead to multiple messages for the same event. + .. note:: The above module-level convenience functions, which delegate to the + root logger, call :func:`basicConfig` to ensure that at least one handler + is available. Because of this, they should *not* be used in threads, + in versions of Python earlier than 2.7.1 and 3.2, unless at least one + handler has been added to the root logger *before* the threads are + started. In earlier versions of Python, due to a thread safety shortcoming + in :func:`basicConfig`, this can (under rare circumstances) lead to + handlers being added multiple times to the root logger, which can in turn + lead to multiple messages for the same event. .. function:: disable(lvl) @@ -1015,6 +1058,16 @@ functions. of the defined levels is passed in, the corresponding string representation is returned. Otherwise, the string 'Level %s' % lvl is returned. + .. note:: Levels are internally integers (as they need to be compared in the + logging logic). This function is used to convert between an integer level + and the level name displayed in the formatted log output by means of the + ``%(levelname)s`` format specifier (see :ref:`logrecord-attributes`). + + .. versionchanged:: 3.4 + In Python versions earlier than 3.4, this function could also be passed a + text level, and would return the corresponding numeric value of the level. + This undocumented behaviour was considered a mistake, and was removed in + Python 3.4, but reinstated in 3.4.2 due to retain backward compatibility. .. function:: makeLogRecord(attrdict) diff --git a/Doc/library/lzma.rst b/Doc/library/lzma.rst index 53fba89f1a66..99f07dcc6489 100644 --- a/Doc/library/lzma.rst +++ b/Doc/library/lzma.rst @@ -102,6 +102,11 @@ Reading and writing compressed files byte of data will be returned, unless EOF has been reached. The exact number of bytes returned is unspecified (the *size* argument is ignored). + .. note:: While calling :meth:`peek` does not change the file position of + the :class:`LZMAFile`, it may change the position of the underlying + file object (e.g. if the :class:`LZMAFile` was constructed by passing a + file object for *filename*). + .. versionchanged:: 3.4 Added support for the ``"x"`` and ``"xb"`` modes. @@ -216,13 +221,32 @@ Compressing and decompressing data in memory decompress a multi-stream input with :class:`LZMADecompressor`, you must create a new decompressor for each stream. - .. method:: decompress(data) + .. method:: decompress(data, max_length=-1) + + Decompress *data* (a :term:`bytes-like object`), returning + uncompressed data as bytes. Some of *data* may be buffered + internally, for use in later calls to :meth:`decompress`. The + returned data should be concatenated with the output of any + previous calls to :meth:`decompress`. + + If *max_length* is nonnegative, returns at most *max_length* + bytes of decompressed data. If this limit is reached and further + output can be produced, the :attr:`~.needs_input` attribute will + be set to ``False``. In this case, the next call to + :meth:`~.decompress` may provide *data* as ``b''`` to obtain + more of the output. + + If all of the input data was decompressed and returned (either + because this was less than *max_length* bytes, or because + *max_length* was negative), the :attr:`~.needs_input` attribute + will be set to ``True``. - Decompress *data* (a :class:`bytes` object), returning a :class:`bytes` - object containing the decompressed data for at least part of the input. - Some of *data* may be buffered internally, for use in later calls to - :meth:`decompress`. The returned data should be concatenated with the - output of any previous calls to :meth:`decompress`. + Attempting to decompress data after the end of stream is reached + raises an `EOFError`. Any data found after the end of the + stream is ignored and saved in the :attr:`~.unused_data` attribute. + + .. versionchanged:: 3.5 + Added the *max_length* parameter. .. attribute:: check @@ -240,6 +264,12 @@ Compressing and decompressing data in memory Before the end of the stream is reached, this will be ``b""``. + .. attribute:: needs_input + + ``False`` if the :meth:`.decompress` method can provide more + decompressed data before requiring new uncompressed input. + + .. versionadded:: 3.5 .. function:: compress(data, format=FORMAT_XZ, check=-1, preset=None, filters=None) diff --git a/Doc/library/mailbox.rst b/Doc/library/mailbox.rst index d668a6eacb3f..6334bd6e9882 100644 --- a/Doc/library/mailbox.rst +++ b/Doc/library/mailbox.rst @@ -202,7 +202,7 @@ Supported mailbox formats are Maildir, mbox, MH, Babyl, and MMDF. .. versionchanged:: 3.2 The file object really is a binary file; previously it was incorrectly returned in text mode. Also, the file-like object now supports the - context manager protocol: you can use a :keyword:`with` statement to + context management protocol: you can use a :keyword:`with` statement to automatically close it. .. note:: @@ -487,7 +487,7 @@ Supported mailbox formats are Maildir, mbox, MH, Babyl, and MMDF. `Configuring Netscape Mail on Unix: Why The Content-Length Format is Bad <http://www.jwz.org/doc/content-length.html>`_ An argument for using the original mbox format rather than a variation. - `"mbox" is a family of several mutually incompatible mailbox formats <http://homepages.tesco.net./~J.deBoynePollard/FGA/mail-mbox-formats.html>`_ + `"mbox" is a family of several mutually incompatible mailbox formats <http://homepage.ntlworld.com/jonathan.deboynepollard/FGA/mail-mbox-formats.html>`_ A history of mbox variations. @@ -1550,7 +1550,7 @@ programs, mail loss due to interruption of the program, or premature termination due to malformed messages in the mailbox:: import mailbox - import email.Errors + import email.errors list_names = ('python-list', 'python-dev', 'python-bugs') @@ -1560,7 +1560,7 @@ due to malformed messages in the mailbox:: for key in inbox.iterkeys(): try: message = inbox[key] - except email.Errors.MessageParseError: + except email.errors.MessageParseError: continue # The message is malformed. Just leave it. for name in list_names: diff --git a/Doc/library/marshal.rst b/Doc/library/marshal.rst index 124eb6168e7e..af43944b2c92 100644 --- a/Doc/library/marshal.rst +++ b/Doc/library/marshal.rst @@ -106,7 +106,7 @@ In addition, the following constants are defined: format, version 1 shares interned strings and version 2 uses a binary format for floating point numbers. Version 3 adds support for object instancing and recursion. - The current version is 3. + The current version is 4. .. rubric:: Footnotes diff --git a/Doc/library/math.rst b/Doc/library/math.rst index 7c3ab596b9b2..eda0056fc94f 100644 --- a/Doc/library/math.rst +++ b/Doc/library/math.rst @@ -36,9 +36,9 @@ Number-theoretic and representation functions .. function:: copysign(x, y) - Return *x* with the sign of *y*. On a platform that supports - signed zeros, ``copysign(1.0, -0.0)`` returns *-1.0*. - + Return a float with the magnitude (absolute value) of *x* but the sign of + *y*. On platforms that support signed zeros, ``copysign(1.0, -0.0)`` + returns *-1.0*. .. function:: fabs(x) @@ -383,6 +383,22 @@ Constants The mathematical constant e = 2.718281..., to available precision. +.. data:: inf + + A floating-point positive infinity. (For negative infinity, use + ``-math.inf``.) Equivalent to the output of ``float('inf')``. + + .. versionadded:: 3.5 + + +.. data:: nan + + A floating-point "not a number" (NaN) value. Equivalent to the output of + ``float('nan')``. + + .. versionadded:: 3.5 + + .. impl-detail:: The :mod:`math` module consists mostly of thin wrappers around the platform C diff --git a/Doc/library/mimetypes.rst b/Doc/library/mimetypes.rst index 12c9eca6e853..f836243e7ad7 100644 --- a/Doc/library/mimetypes.rst +++ b/Doc/library/mimetypes.rst @@ -44,7 +44,7 @@ the information :func:`init` sets up. The optional *strict* argument is a flag specifying whether the list of known MIME types is limited to only the official types `registered with IANA - <http://www.iana.org/assignments/media-types/>`_. + <http://www.iana.org/assignments/media-types/media-types.xhtml>`_. When *strict* is ``True`` (the default), only the IANA types are supported; when *strict* is ``False``, some additional non-standard but commonly used MIME types are also recognized. diff --git a/Doc/library/modules.rst b/Doc/library/modules.rst index d89ef1062812..6b2a40a1b714 100644 --- a/Doc/library/modules.rst +++ b/Doc/library/modules.rst @@ -12,7 +12,6 @@ The full list of modules described in this chapter is: .. toctree:: - imp.rst zipimport.rst pkgutil.rst modulefinder.rst diff --git a/Doc/library/msilib.rst b/Doc/library/msilib.rst index d3451c844bc1..4145c8e7cc04 100644 --- a/Doc/library/msilib.rst +++ b/Doc/library/msilib.rst @@ -120,9 +120,9 @@ structures. .. seealso:: - `FCICreateFile <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/devnotes/winprog/fcicreate.asp>`_ - `UuidCreate <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/rpc/rpc/uuidcreate.asp>`_ - `UuidToString <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/rpc/rpc/uuidtostring.asp>`_ + `FCICreateFile <http://msdn.microsoft.com/library?url=/library/en-us/devnotes/winprog/fcicreate.asp>`_ + `UuidCreate <http://msdn.microsoft.com/library?url=/library/en-us/rpc/rpc/uuidcreate.asp>`_ + `UuidToString <http://msdn.microsoft.com/library?url=/library/en-us/rpc/rpc/uuidtostring.asp>`_ .. _database-objects: @@ -151,9 +151,9 @@ Database Objects .. seealso:: - `MSIDatabaseOpenView <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msidatabaseopenview.asp>`_ - `MSIDatabaseCommit <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msidatabasecommit.asp>`_ - `MSIGetSummaryInformation <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msigetsummaryinformation.asp>`_ + `MSIDatabaseOpenView <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msidatabaseopenview.asp>`_ + `MSIDatabaseCommit <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msidatabasecommit.asp>`_ + `MSIGetSummaryInformation <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msigetsummaryinformation.asp>`_ .. _view-objects: @@ -199,11 +199,11 @@ View Objects .. seealso:: - `MsiViewExecute <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msiviewexecute.asp>`_ - `MSIViewGetColumnInfo <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msiviewgetcolumninfo.asp>`_ - `MsiViewFetch <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msiviewfetch.asp>`_ - `MsiViewModify <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msiviewmodify.asp>`_ - `MsiViewClose <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msiviewclose.asp>`_ + `MsiViewExecute <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msiviewexecute.asp>`_ + `MSIViewGetColumnInfo <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msiviewgetcolumninfo.asp>`_ + `MsiViewFetch <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msiviewfetch.asp>`_ + `MsiViewModify <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msiviewmodify.asp>`_ + `MsiViewClose <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msiviewclose.asp>`_ .. _summary-objects: @@ -243,10 +243,10 @@ Summary Information Objects .. seealso:: - `MsiSummaryInfoGetProperty <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msisummaryinfogetproperty.asp>`_ - `MsiSummaryInfoGetPropertyCount <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msisummaryinfogetpropertycount.asp>`_ - `MsiSummaryInfoSetProperty <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msisummaryinfosetproperty.asp>`_ - `MsiSummaryInfoPersist <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msisummaryinfopersist.asp>`_ + `MsiSummaryInfoGetProperty <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msisummaryinfogetproperty.asp>`_ + `MsiSummaryInfoGetPropertyCount <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msisummaryinfogetpropertycount.asp>`_ + `MsiSummaryInfoSetProperty <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msisummaryinfosetproperty.asp>`_ + `MsiSummaryInfoPersist <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msisummaryinfopersist.asp>`_ .. _record-objects: @@ -297,11 +297,11 @@ Record Objects .. seealso:: - `MsiRecordGetFieldCount <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msirecordgetfieldcount.asp>`_ - `MsiRecordSetString <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msirecordsetstring.asp>`_ - `MsiRecordSetStream <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msirecordsetstream.asp>`_ - `MsiRecordSetInteger <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msirecordsetinteger.asp>`_ - `MsiRecordClear <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msirecordclear.asp>`_ + `MsiRecordGetFieldCount <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msirecordgetfieldcount.asp>`_ + `MsiRecordSetString <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msirecordsetstring.asp>`_ + `MsiRecordSetStream <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msirecordsetstream.asp>`_ + `MsiRecordSetInteger <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msirecordsetinteger.asp>`_ + `MsiRecordClear <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msirecordclear.asp>`_ .. _msi-errors: @@ -393,10 +393,10 @@ Directory Objects .. seealso:: - `Directory Table <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/directory_table.asp>`_ - `File Table <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/file_table.asp>`_ - `Component Table <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/component_table.asp>`_ - `FeatureComponents Table <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/featurecomponents_table.asp>`_ + `Directory Table <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/directory_table.asp>`_ + `File Table <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/file_table.asp>`_ + `Component Table <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/component_table.asp>`_ + `FeatureComponents Table <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/featurecomponents_table.asp>`_ .. _features: @@ -421,7 +421,7 @@ Features .. seealso:: - `Feature Table <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/feature_table.asp>`_ + `Feature Table <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/feature_table.asp>`_ .. _msi-gui: @@ -516,13 +516,13 @@ for installing Python packages. .. seealso:: - `Dialog Table <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/dialog_table.asp>`_ - `Control Table <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/control_table.asp>`_ - `Control Types <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/controls.asp>`_ - `ControlCondition Table <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/controlcondition_table.asp>`_ - `ControlEvent Table <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/controlevent_table.asp>`_ - `EventMapping Table <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/eventmapping_table.asp>`_ - `RadioButton Table <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/radiobutton_table.asp>`_ + `Dialog Table <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/dialog_table.asp>`_ + `Control Table <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/control_table.asp>`_ + `Control Types <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/controls.asp>`_ + `ControlCondition Table <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/controlcondition_table.asp>`_ + `ControlEvent Table <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/controlevent_table.asp>`_ + `EventMapping Table <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/eventmapping_table.asp>`_ + `RadioButton Table <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/radiobutton_table.asp>`_ .. _msi-tables: diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst index 2c44dc923a1d..4b829af1fa5b 100644 --- a/Doc/library/multiprocessing.rst +++ b/Doc/library/multiprocessing.rst @@ -16,41 +16,27 @@ to this, the :mod:`multiprocessing` module allows the programmer to fully leverage multiple processors on a given machine. It runs on both Unix and Windows. -.. note:: +The :mod:`multiprocessing` module also introduces APIs which do not have +analogs in the :mod:`threading` module. A prime example of this is the +:class:`~multiprocessing.pool.Pool` object which offers a convenient means of +parallelizing the execution of a function across multiple input values, +distributing the input data across processes (data parallelism). The following +example demonstrates the common practice of defining such functions in a module +so that child processes can successfully import that module. This basic example +of data parallelism using :class:`~multiprocessing.pool.Pool`, :: - Some of this package's functionality requires a functioning shared semaphore - implementation on the host operating system. Without one, the - :mod:`multiprocessing.synchronize` module will be disabled, and attempts to - import it will result in an :exc:`ImportError`. See - :issue:`3770` for additional information. + from multiprocessing import Pool -.. note:: + def f(x): + return x*x - Functionality within this package requires that the ``__main__`` module be - importable by the children. This is covered in :ref:`multiprocessing-programming` - however it is worth pointing out here. This means that some examples, such - as the :class:`multiprocessing.pool.Pool` examples will not work in the - interactive interpreter. For example:: - - >>> from multiprocessing import Pool - >>> p = Pool(5) - >>> def f(x): - ... return x*x - ... - >>> p.map(f, [1,2,3]) - Process PoolWorker-1: - Process PoolWorker-2: - Process PoolWorker-3: - Traceback (most recent call last): - Traceback (most recent call last): - Traceback (most recent call last): - AttributeError: 'module' object has no attribute 'f' - AttributeError: 'module' object has no attribute 'f' - AttributeError: 'module' object has no attribute 'f' - - (If you try this it will actually output three full tracebacks - interleaved in a semi-random fashion, and then you may have to - stop the master process somehow.) + if __name__ == '__main__': + with Pool(5) as p: + print(p.map(f, [1, 2, 3])) + +will print to standard output :: + + [1, 4, 9] The :class:`Process` class @@ -101,6 +87,8 @@ necessary, see :ref:`multiprocessing-programming`. Contexts and start methods ~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. _multiprocessing-start-methods: + Depending on the platform, :mod:`multiprocessing` supports three ways to start a process. These *start methods* are @@ -134,9 +122,11 @@ to start a process. These *start methods* are Available on Unix platforms which support passing file descriptors over Unix pipes. -Before Python 3.4 *fork* was the only option available on Unix. Also, -prior to Python 3.4, child processes would inherit all the parents -inheritable handles on Windows. +.. versionchanged:: 3.4 + *spawn* added on all unix platforms, and *forkserver* added for + some unix platforms. + Child processes no longer inherit all of the parents inheritable + handles on Windows. On Unix using the *spawn* or *forkserver* start methods will also start a *semaphore tracker* process which tracks the unlinked named @@ -147,7 +137,7 @@ there may some "leaked" semaphores. (Unlinking the named semaphores is a serious matter since the system allows only a limited number, and they will not be automatically unlinked until the next reboot.) -To select the a start method you use the :func:`set_start_method` in +To select a start method you use the :func:`set_start_method` in the ``if __name__ == '__main__'`` clause of the main module. For example:: @@ -258,8 +248,10 @@ that only one process prints to standard output at a time:: def f(l, i): l.acquire() - print('hello world', i) - l.release() + try: + print('hello world', i) + finally: + l.release() if __name__ == '__main__': lock = Lock() @@ -270,6 +262,14 @@ that only one process prints to standard output at a time:: Without using the lock output from the different processes is liable to get all mixed up. +.. note:: + + Some of this package's functionality requires a functioning shared semaphore + implementation on the host operating system. Without one, the + :mod:`multiprocessing.synchronize` module will be disabled, and attempts to + import it will result in an :exc:`ImportError`. See + :issue:`3770` for additional information. + Sharing state between processes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -392,7 +392,7 @@ For example:: print(res.get(timeout=1)) # prints "100" # make worker sleep for 10 secs - res = pool.apply_async(sleep, 10) + res = pool.apply_async(sleep, [10]) print(res.get(timeout=1)) # raises multiprocessing.TimeoutError # exiting the 'with'-block has stopped the pool @@ -400,6 +400,34 @@ For example:: Note that the methods of a pool should only ever be used by the process which created it. +.. note:: + + Functionality within this package requires that the ``__main__`` module be + importable by the children. This is covered in :ref:`multiprocessing-programming` + however it is worth pointing out here. This means that some examples, such + as the :class:`multiprocessing.pool.Pool` examples will not work in the + interactive interpreter. For example:: + + >>> from multiprocessing import Pool + >>> p = Pool(5) + >>> def f(x): + ... return x*x + ... + >>> p.map(f, [1,2,3]) + Process PoolWorker-1: + Process PoolWorker-2: + Process PoolWorker-3: + Traceback (most recent call last): + Traceback (most recent call last): + Traceback (most recent call last): + AttributeError: 'module' object has no attribute 'f' + AttributeError: 'module' object has no attribute 'f' + AttributeError: 'module' object has no attribute 'f' + + (If you try this it will actually output three full tracebacks + interleaved in a semi-random fashion, and then you may have to + stop the master process somehow.) + Reference --------- @@ -836,7 +864,7 @@ Miscellaneous Return list of all live children of the current process. - Calling this has the side affect of "joining" any processes which have + Calling this has the side effect of "joining" any processes which have already finished. .. function:: cpu_count() @@ -1040,7 +1068,7 @@ Connection objects are usually created using :func:`Pipe` -- see also using :meth:`Connection.send` and :meth:`Connection.recv`. .. versionadded:: 3.3 - Connection objects now support the context manager protocol -- see + Connection objects now support the context management protocol -- see :ref:`typecontextmanager`. :meth:`~contextmanager.__enter__` returns the connection object, and :meth:`~contextmanager.__exit__` calls :meth:`close`. @@ -1316,6 +1344,9 @@ processes. Note that accessing the ctypes object through the wrapper can be a lot slower than accessing the raw ctypes object. + .. versionchanged:: 3.5 + Synchronized objects support the :term:`context manager` protocol. + The table below compares the syntax for creating shared ctypes objects from shared memory with the normal ctypes syntax. (In the table ``MyStruct`` is some @@ -1472,7 +1503,7 @@ their parent process exits. The manager classes are defined in the *exposed* is used to specify a sequence of method names which proxies for this typeid should be allowed to access using - :meth:`BaseProxy._callMethod`. (If *exposed* is ``None`` then + :meth:`BaseProxy._callmethod`. (If *exposed* is ``None`` then :attr:`proxytype._exposed_` is used instead if it exists.) In the case where no exposed list is specified, all "public methods" of the shared object will be accessible. (Here a "public method" means any attribute @@ -1497,7 +1528,7 @@ their parent process exits. The manager classes are defined in the The address used by the manager. .. versionchanged:: 3.3 - Manager objects support the context manager protocol -- see + Manager objects support the context management protocol -- see :ref:`typecontextmanager`. :meth:`~contextmanager.__enter__` starts the server process (if it has not already started) and then returns the manager object. :meth:`~contextmanager.__exit__` calls :meth:`shutdown`. @@ -1851,25 +1882,30 @@ with the :class:`Pool` class. callbacks and has a parallel map implementation. *processes* is the number of worker processes to use. If *processes* is - ``None`` then the number returned by :func:`os.cpu_count` is used. If - *initializer* is not ``None`` then each worker process will call + ``None`` then the number returned by :func:`os.cpu_count` is used. + + If *initializer* is not ``None`` then each worker process will call ``initializer(*initargs)`` when it starts. + *maxtasksperchild* is the number of tasks a worker process can complete + before it will exit and be replaced with a fresh worker process, to enable + unused resources to be freed. The default *maxtasksperchild* is None, which + means worker processes will live as long as the pool. + + *context* can be used to specify the context used for starting + the worker processes. Usually a pool is created using the + function :func:`multiprocessing.Pool` or the :meth:`Pool` method + of a context object. In both cases *context* is set + appropriately. + Note that the methods of the pool object should only be called by the process which created the pool. .. versionadded:: 3.2 - *maxtasksperchild* is the number of tasks a worker process can complete - before it will exit and be replaced with a fresh worker process, to enable - unused resources to be freed. The default *maxtasksperchild* is None, which - means worker processes will live as long as the pool. + *maxtasksperchild* .. versionadded:: 3.4 - *context* can be used to specify the context used for starting - the worker processes. Usually a pool is created using the - function :func:`multiprocessing.Pool` or the :meth:`Pool` method - of a context object. In both cases *context* is set - appropriately. + *context* .. note:: @@ -1951,18 +1987,18 @@ with the :class:`Pool` class. .. method:: starmap(func, iterable[, chunksize]) - Like :meth:`map` except that the elements of the `iterable` are expected + Like :meth:`map` except that the elements of the *iterable* are expected to be iterables that are unpacked as arguments. - Hence an `iterable` of `[(1,2), (3, 4)]` results in `[func(1,2), - func(3,4)]`. + Hence an *iterable* of ``[(1,2), (3, 4)]`` results in ``[func(1,2), + func(3,4)]``. .. versionadded:: 3.3 .. method:: starmap_async(func, iterable[, chunksize[, callback[, error_back]]]) A combination of :meth:`starmap` and :meth:`map_async` that iterates over - `iterable` of iterables and calls `func` with the iterables unpacked. + *iterable* of iterables and calls *func* with the iterables unpacked. Returns a result object. .. versionadded:: 3.3 @@ -1984,7 +2020,7 @@ with the :class:`Pool` class. :meth:`terminate` before using :meth:`join`. .. versionadded:: 3.3 - Pool objects now support the context manager protocol -- see + Pool objects now support the context management protocol -- see :ref:`typecontextmanager`. :meth:`~contextmanager.__enter__` returns the pool object, and :meth:`~contextmanager.__exit__` calls :meth:`terminate`. @@ -2157,7 +2193,7 @@ multiple connections at the same time. unavailable then it is ``None``. .. versionadded:: 3.3 - Listener objects now support the context manager protocol -- see + Listener objects now support the context management protocol -- see :ref:`typecontextmanager`. :meth:`~contextmanager.__enter__` returns the listener object, and :meth:`~contextmanager.__exit__` calls :meth:`close`. @@ -2453,7 +2489,7 @@ Joining processes that use queues items which have been put on the queue will eventually be removed before the process is joined. Otherwise you cannot be sure that processes which have put items on the queue will terminate. Remember also that non-daemonic - processes will be automatically be joined. + processes will be joined automatically. An example which will deadlock is the following:: @@ -2469,7 +2505,7 @@ Joining processes that use queues p.join() # this deadlocks obj = queue.get() - A fix here would be to swap the last two lines round (or simply remove the + A fix here would be to swap the last two lines (or simply remove the ``p.join()`` line). Explicitly pass resources to child processes diff --git a/Doc/library/nntplib.rst b/Doc/library/nntplib.rst index 0098041e1d98..3943f2c249dd 100644 --- a/Doc/library/nntplib.rst +++ b/Doc/library/nntplib.rst @@ -94,6 +94,7 @@ The module itself defines the following classes: port *port*. :class:`NNTP_SSL` objects have the same methods as :class:`NNTP` objects. If *port* is omitted, port 563 (NNTPS) is used. *ssl_context* is also optional, and is a :class:`~ssl.SSLContext` object. + Please read :ref:`ssl-security` for best practices. All other parameters behave the same as for :class:`NNTP`. Note that SSL-on-563 is discouraged per :rfc:`4642`, in favor of @@ -102,6 +103,10 @@ The module itself defines the following classes: .. versionadded:: 3.2 + .. versionchanged:: 3.4 + The class now supports hostname check with + :attr:`ssl.SSLContext.check_hostname` and *Server Name Indication* (see + :data:`ssl.HAS_SNI`). .. exception:: NNTPError @@ -230,9 +235,10 @@ tuples or objects that the method normally returns will be empty. .. method:: NNTP.starttls(ssl_context=None) - Send a ``STARTTLS`` command. The *ssl_context* argument is optional - and should be a :class:`ssl.SSLContext` object. This will enable - encryption on the NNTP connection. + Send a ``STARTTLS`` command. This will enable encryption on the NNTP + connection. The *ssl_context* argument is optional and should be a + :class:`ssl.SSLContext` object. Please read :ref:`ssl-security` for best + practices. Note that this may not be done after authentication information has been transmitted, and authentication occurs by default if possible during a @@ -241,6 +247,10 @@ tuples or objects that the method normally returns will be empty. .. versionadded:: 3.2 + .. versionchanged:: 3.4 + The method now supports hostname check with + :attr:`ssl.SSLContext.check_hostname` and *Server Name Indication* (see + :data:`ssl.HAS_SNI`). .. method:: NNTP.newgroups(date, *, file=None) diff --git a/Doc/library/numbers.rst b/Doc/library/numbers.rst index fec04ed722cf..8ab07d0b93d9 100644 --- a/Doc/library/numbers.rst +++ b/Doc/library/numbers.rst @@ -110,6 +110,8 @@ those. You can add ``MyFoo`` between :class:`Complex` and MyFoo.register(Real) +.. _implementing-the-arithmetic-operations: + Implementing the arithmetic operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/Doc/library/operator.rst b/Doc/library/operator.rst index 80bad7142c63..c01e63b77a99 100644 --- a/Doc/library/operator.rst +++ b/Doc/library/operator.rst @@ -138,6 +138,14 @@ The mathematical and bitwise operations are the most numerous: Return ``a * b``, for *a* and *b* numbers. +.. function:: matmul(a, b) + __matmul__(a, b) + + Return ``a @ b``. + + .. versionadded:: 3.5 + + .. function:: neg(obj) __neg__(obj) @@ -228,21 +236,12 @@ Operations which work with sequences (some of them with mappings too) include: Set the value of *a* at index *b* to *c*. -Example: Build a dictionary that maps the ordinals from ``0`` to ``255`` to -their character equivalents. - - >>> d = {} - >>> keys = range(256) - >>> vals = map(chr, keys) - >>> map(operator.setitem, [d]*len(keys), keys, vals) # doctest: +SKIP - -.. XXX: find a better, readable, example .. function:: length_hint(obj, default=0) - Return an estimated length for the object *o*. First trying to return its + Return an estimated length for the object *o*. First try to return its actual length, then an estimate using :meth:`object.__length_hint__`, and - finally returning the default value. + finally return the default value. .. versionadded:: 3.4 @@ -265,7 +264,7 @@ expect a function argument. ``(b.name, b.date)``. * After ``f = attrgetter('name.first', 'name.last')``, the call ``f(b)`` - returns ``(r.name.first, r.name.last)``. + returns ``(b.name.first, b.name.last)``. Equivalent to:: @@ -400,6 +399,8 @@ Python syntax and the functions in the :mod:`operator` module. +-----------------------+-------------------------+---------------------------------------+ | Multiplication | ``a * b`` | ``mul(a, b)`` | +-----------------------+-------------------------+---------------------------------------+ +| Matrix Multiplication | ``a @ b`` | ``matmul(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ | Negation (Arithmetic) | ``- a`` | ``neg(a)`` | +-----------------------+-------------------------+---------------------------------------+ | Negation (Logical) | ``not a`` | ``not_(a)`` | @@ -508,6 +509,14 @@ will perform the update, so no subsequent assignment is necessary: ``a = imul(a, b)`` is equivalent to ``a *= b``. +.. function:: imatmul(a, b) + __imatmul__(a, b) + + ``a = imatmul(a, b)`` is equivalent to ``a @= b``. + + .. versionadded:: 3.5 + + .. function:: ior(a, b) __ior__(a, b) diff --git a/Doc/library/optparse.rst b/Doc/library/optparse.rst index 13395b636d44..72145aa59b5f 100644 --- a/Doc/library/optparse.rst +++ b/Doc/library/optparse.rst @@ -8,8 +8,8 @@ .. sectionauthor:: Greg Ward <gward@python.net> .. deprecated:: 3.2 - The :mod:`optparse` module is deprecated and will not be developed further; - development will continue with the :mod:`argparse` module. + The :mod:`optparse` module is deprecated and will not be developed further; + development will continue with the :mod:`argparse` module. **Source code:** :source:`Lib/optparse.py` diff --git a/Doc/library/os.path.rst b/Doc/library/os.path.rst index 269856c62846..92631b2e416d 100644 --- a/Doc/library/os.path.rst +++ b/Doc/library/os.path.rst @@ -188,29 +188,40 @@ the :mod:`glob` module.) .. function:: islink(path) Return ``True`` if *path* refers to a directory entry that is a symbolic link. - Always ``False`` if symbolic links are not supported. + Always ``False`` if symbolic links are not supported by the python runtime. .. function:: ismount(path) - Return ``True`` if pathname *path* is a :dfn:`mount point`: a point in a file - system where a different file system has been mounted. The function checks - whether *path*'s parent, :file:`path/..`, is on a different device than *path*, - or whether :file:`path/..` and *path* point to the same i-node on the same - device --- this should detect mount points for all Unix and POSIX variants. + Return ``True`` if pathname *path* is a :dfn:`mount point`: a point in a + file system where a different file system has been mounted. On POSIX, the + function checks whether *path*'s parent, :file:`path/..`, is on a different + device than *path*, or whether :file:`path/..` and *path* point to the same + i-node on the same device --- this should detect mount points for all Unix + and POSIX variants. On Windows, a drive letter root and a share UNC are + always mount points, and for any other path ``GetVolumePathName`` is called + to see if it is different from the input path. + .. versionadded:: 3.4 + Support for detecting non-root mount points on Windows. -.. function:: join(path1[, path2[, ...]]) - Join one or more path components intelligently. If any component is an absolute - path, all previous components (on Windows, including the previous drive letter, - if there was one) are thrown away, and joining continues. The return value is - the concatenation of *path1*, and optionally *path2*, etc., with exactly one - directory separator (``os.sep``) following each non-empty part except the last. - (This means that an empty last part will result in a path that ends with a - separator.) Note that on Windows, since there is a current directory for - each drive, ``os.path.join("c:", "foo")`` represents a path relative to the - current directory on drive :file:`C:` (:file:`c:foo`), not :file:`c:\\foo`. +.. function:: join(path, *paths) + + Join one or more path components intelligently. The return value is the + concatenation of *path* and any members of *\*paths* with exactly one + directory separator (``os.sep``) following each non-empty part except the + last, meaning that the result will only end in a separator if the last + part is empty. If a component is an absolute path, all previous + components are thrown away and joining continues from the absolute path + component. + + On Windows, the drive letter is not reset when an absolute path component + (e.g., ``r'\foo'``) is encountered. If a component contains a drive + letter, all previous components are thrown away and the drive letter is + reset. Note that since there is a current directory for each drive, + ``os.path.join("c:", "foo")`` represents a path relative to the current + directory on drive :file:`C:` (:file:`c:foo`), not :file:`c:\\foo`. .. function:: normcase(path) @@ -236,7 +247,7 @@ the :mod:`glob` module.) links encountered in the path (if they are supported by the operating system). -.. function:: relpath(path, start=None) +.. function:: relpath(path, start=os.curdir) Return a relative filepath to *path* either from the current directory or from an optional *start* directory. This is a path computation: the @@ -251,7 +262,7 @@ the :mod:`glob` module.) .. function:: samefile(path1, path2) Return ``True`` if both pathname arguments refer to the same file or directory. - On Unix, this is determined by the device number and i-node number and raises an + This is determined by the device number and i-node number and raises an exception if a :func:`os.stat` call on either pathname fails. Availability: Unix, Windows. diff --git a/Doc/library/os.rst b/Doc/library/os.rst index f5f2e16f2e5e..2467c60daea8 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -53,7 +53,7 @@ Notes on the availability of these functions: .. data:: name The name of the operating system dependent module imported. The following - names have currently been registered: ``'posix'``, ``'nt'``, ``'mac'``, + names have currently been registered: ``'posix'``, ``'nt'``, ``'ce'``, ``'java'``. .. seealso:: @@ -65,6 +65,7 @@ Notes on the availability of these functions: .. _os-filenames: +.. _filesystem-encoding: File Names, Command Line Arguments, and Environment Variables ------------------------------------------------------------- @@ -77,9 +78,10 @@ uses the file system encoding to perform this conversion (see .. versionchanged:: 3.1 On some systems, conversion using the file system encoding may fail. In this - case, Python uses the ``surrogateescape`` encoding error handler, which means - that undecodable bytes are replaced by a Unicode character U+DCxx on - decoding, and these are again translated to the original byte on encoding. + case, Python uses the :ref:`surrogateescape encoding error handler + <surrogateescape>`, which means that undecodable bytes are replaced by a + Unicode character U+DCxx on decoding, and these are again translated to the + original byte on encoding. The file system encoding must guarantee to successfully decode all bytes @@ -260,7 +262,9 @@ process and user. Availability: Unix. - .. note:: On Mac OS X, :func:`getgroups` behavior differs somewhat from + .. note:: + + On Mac OS X, :func:`getgroups` behavior differs somewhat from other Unix platforms. If the Python interpreter was built with a deployment target of :const:`10.5` or earlier, :func:`getgroups` returns the list of effective group ids associated with the current user process; @@ -278,10 +282,10 @@ process and user. .. function:: getlogin() Return the name of the user logged in on the controlling terminal of the - process. For most purposes, it is more useful to use the environment variables - :envvar:`LOGNAME` or :envvar:`USERNAME` to find out who the user is, or - ``pwd.getpwuid(os.getuid())[0]`` to get the login name of the currently - effective user id. + process. For most purposes, it is more useful to use the environment + variables :envvar:`LOGNAME` or :envvar:`USERNAME` to find out who the user + is, or ``pwd.getpwuid(os.getuid())[0]`` to get the login name of the current + real user id. Availability: Unix, Windows. @@ -377,7 +381,7 @@ process and user. .. index:: single: user; id - Return the current process's user id. + Return the current process's real user id. Availability: Unix. @@ -762,8 +766,14 @@ as internal buffering of data. .. function:: fstat(fd) - Return status for file descriptor *fd*, like :func:`~os.stat`. As of Python - 3.3, this is equivalent to ``os.stat(fd)``. + Get the status of the file descriptor *fd*. Return a :class:`stat_result` + object. + + As of Python 3.3, this is equivalent to ``os.stat(fd)``. + + .. seealso:: + + The :func:`stat` function. Availability: Unix, Windows. @@ -798,6 +808,17 @@ as internal buffering of data. Availability: Unix. +.. function:: get_blocking(fd) + + Get the blocking mode of the file descriptor: ``False`` if the + :data:`O_NONBLOCK` flag is set, ``True`` if the flag is cleared. + + See also :func:`set_blocking` and :meth:`socket.socket.setblocking`. + + Availability: Unix. + + .. versionadded:: 3.5 + .. function:: isatty(fd) Return ``True`` if the file descriptor *fd* is open and connected to a @@ -940,8 +961,9 @@ or `the MSDN <http://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Window the C library. .. versionchanged:: 3.4 - Add :data:`O_TMPFILE` constant. It's only available on Linux Kernel 3.11 - or newer. + Add :data:`O_PATH` on systems that support it. + Add :data:`O_TMPFILE`, only available on Linux Kernel 3.11 + or newer. .. function:: openpty() @@ -1034,10 +1056,10 @@ or `the MSDN <http://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Window .. versionadded:: 3.3 -.. function:: pwrite(fd, string, offset) +.. function:: pwrite(fd, str, offset) - Write *string* to a file descriptor, *fd*, from *offset*, leaving the file - offset unchanged. + Write *bytestring* to a file descriptor, *fd*, from *offset*, + leaving the file offset unchanged. Availability: Unix. @@ -1084,11 +1106,31 @@ or `the MSDN <http://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Window All platforms support sockets as *out* file descriptor, and some platforms allow other types (e.g. regular file, pipe) as well. + Cross-platform applications should not use *headers*, *trailers* and *flags* + arguments. + Availability: Unix. + .. note:: + + For a higher-level wrapper of :func:`sendfile`, see + :mod:`socket.socket.sendfile`. + .. versionadded:: 3.3 +.. function:: set_blocking(fd, blocking) + + Set the blocking mode of the specified file descriptor. Set the + :data:`O_NONBLOCK` flag if blocking is ``False``, clear the flag otherwise. + + See also :func:`get_blocking` and :meth:`socket.socket.setblocking`. + + Availability: Unix. + + .. versionadded:: 3.5 + + .. data:: SF_NODISKIO SF_MNOWAIT SF_SYNC @@ -1103,9 +1145,12 @@ or `the MSDN <http://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Window .. function:: readv(fd, buffers) - Read from a file descriptor into a number of writable buffers. *buffers* is - an arbitrary sequence of writable buffers. Returns the total number of bytes - read. + Read from a file descriptor *fd* into a number of mutable :term:`bytes-like + objects <bytes-like object>` *buffers*. :func:`~os.readv` will transfer data + into each buffer until it is full and then move on to the next buffer in the + sequence to hold the rest of the data. :func:`~os.readv` returns the total + number of bytes read (which may be less than the total capacity of all the + objects). Availability: Unix. @@ -1155,9 +1200,10 @@ or `the MSDN <http://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Window .. function:: writev(fd, buffers) - Write the contents of *buffers* to file descriptor *fd*, where *buffers* - is an arbitrary sequence of buffers. - Returns the total number of bytes written. + Write the contents of *buffers* to file descriptor *fd*. *buffers* must be a + sequence of :term:`bytes-like objects <bytes-like object>`. + :func:`~os.writev` writes the contents of each object to the file descriptor + and returns the total number of bytes written. Availability: Unix. @@ -1562,17 +1608,25 @@ features: Added support for specifying an open file descriptor for *path*. -.. function:: lstat(path, *, dir_fd=None) +.. function:: lstat(path, \*, dir_fd=None) Perform the equivalent of an :c:func:`lstat` system call on the given path. - Similar to :func:`~os.stat`, but does not follow symbolic links. On - platforms that do not support symbolic links, this is an alias for - :func:`~os.stat`. As of Python 3.3, this is equivalent to ``os.stat(path, - dir_fd=dir_fd, follow_symlinks=False)``. + Similar to :func:`~os.stat`, but does not follow symbolic links. Return a + :class:`stat_result` object. + + On platforms that do not support symbolic links, this is an alias for + :func:`~os.stat`. + + As of Python 3.3, this is equivalent to ``os.stat(path, dir_fd=dir_fd, + follow_symlinks=False)``. This function can also support :ref:`paths relative to directory descriptors <dir_fd>`. + .. seealso:: + + The :func:`stat` function. + .. versionchanged:: 3.2 Added support for Windows 6.0 (Vista) symbolic links. @@ -1600,7 +1654,7 @@ features: The *dir_fd* argument. -.. function:: makedirs(path, mode=0o777, exist_ok=False) +.. function:: makedirs(name, mode=0o777, exist_ok=False) .. index:: single: directory; creating @@ -1612,11 +1666,8 @@ features: The default *mode* is ``0o777`` (octal). On some systems, *mode* is ignored. Where it is used, the current umask value is first masked out. - If *exist_ok* is ``False`` (the default), an :exc:`OSError` is raised if - the target directory already exists. If *exist_ok* is ``True`` an - :exc:`OSError` is still raised if the umask-masked *mode* is different from - the existing mode, on systems where the mode is used. :exc:`OSError` will - also be raised if the directory creation fails. + If *exist_ok* is ``False`` (the default), an :exc:`OSError` is raised if the + target directory already exists. .. note:: @@ -1628,6 +1679,13 @@ features: .. versionadded:: 3.2 The *exist_ok* parameter. + .. versionchanged:: 3.4.1 + + Before Python 3.4.1, if *exist_ok* was ``True`` and the directory existed, + :func:`makedirs` would still raise an error if *mode* did not match the + mode of the existing directory. Since this behavior was impossible to + implement safely, it was removed in Python 3.4.1. See :issue:`21082`. + .. function:: mkfifo(path, mode=0o666, *, dir_fd=None) @@ -1756,7 +1814,7 @@ features: The *dir_fd* argument. -.. function:: removedirs(path) +.. function:: removedirs(name) .. index:: single: directory; deleting @@ -1835,55 +1893,116 @@ features: The *dir_fd* parameter. -.. function:: stat(path, *, dir_fd=None, follow_symlinks=True) - - Perform the equivalent of a :c:func:`stat` system call on the given path. - *path* may be specified as either a string or as an open file descriptor. - (This function normally follows symlinks; to stat a symlink add the argument - ``follow_symlinks=False``, or use :func:`lstat`.) - - The return value is an object whose attributes correspond roughly - to the members of the :c:type:`stat` structure, namely: - - * :attr:`st_mode` - protection bits, - * :attr:`st_ino` - inode number, - * :attr:`st_dev` - device, - * :attr:`st_nlink` - number of hard links, - * :attr:`st_uid` - user id of owner, - * :attr:`st_gid` - group id of owner, - * :attr:`st_size` - size of file, in bytes, - * :attr:`st_atime` - time of most recent access expressed in seconds, - * :attr:`st_mtime` - time of most recent content modification - expressed in seconds, - * :attr:`st_ctime` - platform dependent; time of most recent metadata - change on Unix, or the time of creation on Windows, expressed in seconds - * :attr:`st_atime_ns` - time of most recent access - expressed in nanoseconds as an integer, - * :attr:`st_mtime_ns` - time of most recent content modification - expressed in nanoseconds as an integer, - * :attr:`st_ctime_ns` - platform dependent; time of most recent metadata - change on Unix, or the time of creation on Windows, - expressed in nanoseconds as an integer +.. function:: stat(path, \*, dir_fd=None, follow_symlinks=True) - On some Unix systems (such as Linux), the following attributes may also be - available: + 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 or as an open file descriptor. Return a :class:`stat_result` + object. - * :attr:`st_blocks` - number of 512-byte blocks allocated for file - * :attr:`st_blksize` - filesystem blocksize for efficient file system I/O - * :attr:`st_rdev` - type of device if an inode device - * :attr:`st_flags` - user defined flags for file + This function normally follows symlinks; to stat a symlink add the argument + ``follow_symlinks=False``, or use :func:`lstat`. - On other Unix systems (such as FreeBSD), the following attributes may be - available (but may be only filled out if root tries to use them): + This function can support :ref:`specifying a file descriptor <path_fd>` and + :ref:`not following symlinks <follow_symlinks>`. - * :attr:`st_gen` - file generation number - * :attr:`st_birthtime` - time of file creation + .. index:: module: stat - On Mac OS systems, the following attributes may also be available: + Example:: + + >>> import os + >>> statinfo = os.stat('somefile.txt') + >>> statinfo + os.stat_result(st_mode=33188, st_ino=7876932, st_dev=234881026, + st_nlink=1, st_uid=501, st_gid=501, st_size=264, st_atime=1297230295, + st_mtime=1297230027, st_ctime=1297230027) + >>> statinfo.st_size + 264 + + Availability: Unix, Windows. + + .. seealso:: + + :func:`fstat` and :func:`lstat` functions. + + .. versionadded:: 3.3 + Added the *dir_fd* and *follow_symlinks* arguments, specifying a file + descriptor instead of a path. + + +.. class:: stat_result + + Object whose attributes correspond roughly to the members of the + :c:type:`stat` structure. It is used for the result of :func:`os.stat`, + :func:`os.fstat` and :func:`os.lstat`. + + Attributes: + + .. attribute:: st_mode + + File mode: file type and file mode bits (permissions). + + .. attribute:: st_ino + + Inode number. + + .. attribute:: st_dev + + Identifier of the device on which this file resides. + + .. attribute:: st_nlink + + Number of hard links. + + .. attribute:: st_uid + + User identifier of the file owner. + + .. attribute:: st_gid + + Group identifier of the file owner. + + .. attribute:: st_size - * :attr:`st_rsize` - * :attr:`st_creator` - * :attr:`st_type` + Size of the file in bytes, if it is a regular file or a symbolic link. + The size of a symbolic link is the length of the pathname it contains, + without a terminating null byte. + + Timestamps: + + .. attribute:: st_atime + + Time of most recent access expressed in seconds. + + .. attribute:: st_mtime + + Time of most recent content modification expressed in seconds. + + .. attribute:: st_ctime + + Platform dependent: + + * the time of most recent metadata change on Unix, + * the time of creation on Windows, expressed in seconds. + + .. attribute:: st_atime_ns + + Time of most recent access expressed in nanoseconds as an integer. + + .. attribute:: st_mtime_ns + + Time of most recent content modification expressed in nanoseconds as an + integer. + + .. attribute:: st_ctime_ns + + Platform dependent: + + * the time of most recent metadata change on Unix, + * the time of creation on Windows, expressed in nanoseconds as an + integer. + + See also the :func:`stat_float_times` function. .. note:: @@ -1893,6 +2012,7 @@ features: or FAT32 file systems, :attr:`st_mtime` has 2-second resolution, and :attr:`st_atime` has only 1-day resolution. See your operating system documentation for details. + Similarly, although :attr:`st_atime_ns`, :attr:`st_mtime_ns`, and :attr:`st_ctime_ns` are always expressed in nanoseconds, many systems do not provide nanosecond precision. On systems that do @@ -1902,41 +2022,80 @@ features: If you need the exact timestamps you should always use :attr:`st_atime_ns`, :attr:`st_mtime_ns`, and :attr:`st_ctime_ns`. - For backward compatibility, the return value of :func:`~os.stat` is also - accessible as a tuple of at least 10 integers giving the most important (and - portable) members of the :c:type:`stat` structure, in the order - :attr:`st_mode`, :attr:`st_ino`, :attr:`st_dev`, :attr:`st_nlink`, - :attr:`st_uid`, :attr:`st_gid`, :attr:`st_size`, :attr:`st_atime`, - :attr:`st_mtime`, :attr:`st_ctime`. More items may be added at the end by - some implementations. + On some Unix systems (such as Linux), the following attributes may also be + available: - This function can support :ref:`specifying a file descriptor <path_fd>` and - :ref:`not following symlinks <follow_symlinks>`. + .. attribute:: st_blocks - .. index:: module: stat + Number of 512-byte blocks allocated for file. + This may be smaller than :attr:`st_size`/512 when the file has holes. - The standard module :mod:`stat` defines functions and constants that are useful - for extracting information from a :c:type:`stat` structure. (On Windows, some - items are filled with dummy values.) + .. attribute:: st_blksize - Example:: + "Preferred" blocksize for efficient file system I/O. Writing to a file in + smaller chunks may cause an inefficient read-modify-rewrite. - >>> import os - >>> statinfo = os.stat('somefile.txt') - >>> statinfo - posix.stat_result(st_mode=33188, st_ino=7876932, st_dev=234881026, - st_nlink=1, st_uid=501, st_gid=501, st_size=264, st_atime=1297230295, - st_mtime=1297230027, st_ctime=1297230027) - >>> statinfo.st_size - 264 + .. attribute:: st_rdev - Availability: Unix, Windows. + Type of device if an inode device. + + .. attribute:: st_flags + + User defined flags for file. + + On other Unix systems (such as FreeBSD), the following attributes may be + available (but may be only filled out if root tries to use them): + + .. attribute:: st_gen + + File generation number. + + .. attribute:: st_birthtime + + Time of file creation. + + On Mac OS systems, the following attributes may also be available: + + .. attribute:: st_rsize + + Real size of the file. + + .. attribute:: st_creator + + Creator of the file. + + .. attribute:: st_type + + File type. + + On Windows systems, the following attribute is also available: + + .. attribute:: st_file_attributes + + Windows file attributes: ``dwFileAttributes`` member of the + ``BY_HANDLE_FILE_INFORMATION`` structure returned by + :c:func:`GetFileInformationByHandle`. See the ``FILE_ATTRIBUTE_*`` + constants in the :mod:`stat` module. + + The standard module :mod:`stat` defines functions and constants that are + useful for extracting information from a :c:type:`stat` structure. (On + Windows, some items are filled with dummy values.) + + For backward compatibility, a :class:`stat_result` instance is also + accessible as a tuple of at least 10 integers giving the most important (and + portable) members of the :c:type:`stat` structure, in the order + :attr:`st_mode`, :attr:`st_ino`, :attr:`st_dev`, :attr:`st_nlink`, + :attr:`st_uid`, :attr:`st_gid`, :attr:`st_size`, :attr:`st_atime`, + :attr:`st_mtime`, :attr:`st_ctime`. More items may be added at the end by + some implementations. For compatibility with older Python versions, + accessing :class:`stat_result` as a tuple always returns integers. .. versionadded:: 3.3 - Added the *dir_fd* and *follow_symlinks* arguments, - specifying a file descriptor instead of a path, - and the :attr:`st_atime_ns`, :attr:`st_mtime_ns`, - and :attr:`st_ctime_ns` members. + Added the :attr:`st_atime_ns`, :attr:`st_mtime_ns`, and + :attr:`st_ctime_ns` members. + + .. versionadded:: 3.5 + Added the :attr:`st_file_attributes` member on Windows. .. function:: stat_float_times([newvalue]) @@ -1980,11 +2139,26 @@ features: read-only, and if :const:`ST_NOSUID` is set, the semantics of setuid/setgid bits are disabled or not supported. + Additional module-level constants are defined for GNU/glibc based systems. + These are :const:`ST_NODEV` (disallow access to device special files), + :const:`ST_NOEXEC` (disallow program execution), :const:`ST_SYNCHRONOUS` + (writes are synced at once), :const:`ST_MANDLOCK` (allow mandatory locks on an FS), + :const:`ST_WRITE` (write on file/directory/symlink), :const:`ST_APPEND` + (append-only file), :const:`ST_IMMUTABLE` (immutable file), :const:`ST_NOATIME` + (do not update access times), :const:`ST_NODIRATIME` (do not update directory access + times), :const:`ST_RELATIME` (update atime relative to mtime/ctime). + This function can support :ref:`specifying a file descriptor <path_fd>`. .. versionchanged:: 3.2 The :const:`ST_RDONLY` and :const:`ST_NOSUID` constants were added. + .. versionchanged:: 3.4 + The :const:`ST_NODEV`, :const:`ST_NOEXEC`, :const:`ST_SYNCHRONOUS`, + :const:`ST_MANDLOCK`, :const:`ST_WRITE`, :const:`ST_APPEND`, + :const:`ST_IMMUTABLE`, :const:`ST_NOATIME`, :const:`ST_NODIRATIME`, + and :const:`ST_RELATIME` constants were added. + Availability: Unix. .. versionadded:: 3.3 @@ -2021,7 +2195,8 @@ features: contain :func:`os.access`, otherwise it will be empty. To check whether you can use the *effective_ids* parameter for - :func:`os.access`, use the ``in`` operator on ``supports_dir_fd``, like so:: + :func:`os.access`, use the ``in`` operator on ``supports_effective_ids``, + like so:: os.access in os.supports_effective_ids @@ -2202,9 +2377,11 @@ features: If optional argument *topdown* is ``True`` or not specified, the triple for a directory is generated before the triples for any of its subdirectories - (directories are generated top-down). If *topdown* is ``False``, the triple for a - directory is generated after the triples for all of its subdirectories - (directories are generated bottom-up). + (directories are generated top-down). If *topdown* is ``False``, the triple + for a directory is generated after the triples for all of its subdirectories + (directories are generated bottom-up). No matter the value of *topdown*, the + list of subdirectories is retrieved before the tuples for the directory and + its subdirectories are generated. When *topdown* is ``True``, the caller can modify the *dirnames* list in-place (perhaps using :keyword:`del` or slice assignment), and :func:`walk` will only @@ -2634,7 +2811,7 @@ written in Python, such as a mail server's external command delivery program. Fork a child process. Return ``0`` in the child and the child's process id in the parent. If an error occurs :exc:`OSError` is raised. - Note that some platforms including FreeBSD <= 6.3, Cygwin and OS/2 EMX have + Note that some platforms including FreeBSD <= 6.3 and Cygwin have known issues when using fork() from a thread. .. warning:: @@ -2704,10 +2881,27 @@ written in Python, such as a mail server's external command delivery program. Availability: Unix. -.. function:: popen(...) +.. function:: popen(command, mode='r', buffering=-1) + + Open a pipe to or from *command*. The return value is an open file object + connected to the pipe, which can be read or written depending on whether *mode* + is ``'r'`` (default) or ``'w'``. The *buffering* argument has the same meaning as + the corresponding argument to the built-in :func:`open` function. The + returned file object reads or writes text strings rather than bytes. - Run child processes, returning opened pipes for communications. These functions - are described in section :ref:`os-newstreams`. + The ``close`` method returns :const:`None` if the subprocess exited + successfully, or the subprocess's return code if there was an + error. On POSIX systems, if the return code is positive it + represents the return value of the process left-shifted by one + byte. If the return code is negative, the process was terminated + by the signal given by the negated value of the return code. (For + example, the return value might be ``- signal.SIGKILL`` if the + subprocess was killed.) On Windows systems, the return value + contains the signed integer return code from the child process. + + This is implemented using :class:`subprocess.Popen`; see that class's + documentation for more powerful ways to manage and communicate with + subprocesses. .. function:: spawnl(mode, path, ...) @@ -2831,6 +3025,10 @@ written in Python, such as a mail server's external command delivery program. doesn't work if it is. Use the :func:`os.path.normpath` function to ensure that the path is properly encoded for Win32. + To reduce interpreter startup overhead, the Win32 :c:func:`ShellExecute` + function is not resolved until this function is first called. If the function + cannot be resolved, :exc:`NotImplementedError` will be raised. + Availability: Windows. @@ -2880,7 +3078,6 @@ written in Python, such as a mail server's external command delivery program. :manpage:`times(2)` or the corresponding Windows Platform API documentation. On Windows, only :attr:`user` and :attr:`system` are known; the other attributes are zero. - On OS/2, only :attr:`elapsed` is known; the other attributes are zero. Availability: Unix, Windows. diff --git a/Doc/library/ossaudiodev.rst b/Doc/library/ossaudiodev.rst index b53e80f93735..bb5081afde8b 100644 --- a/Doc/library/ossaudiodev.rst +++ b/Doc/library/ossaudiodev.rst @@ -49,7 +49,7 @@ the standard audio interface for Linux and recent versions of FreeBSD. the official documentation for the OSS C API The module defines a large number of constants supplied by the OSS device - driver; see ``<sys/soundcard.h>`` on either Linux or FreeBSD for a listing . + driver; see ``<sys/soundcard.h>`` on either Linux or FreeBSD for a listing. :mod:`ossaudiodev` defines the following variables and functions: @@ -165,7 +165,7 @@ and (read-only) attributes: data written is always equal to the amount of data supplied. .. versionchanged:: 3.2 - Audio device objects also support the context manager protocol, i.e. they can + Audio device objects also support the context management protocol, i.e. they can be used in a :keyword:`with` statement. @@ -357,7 +357,7 @@ The mixer object provides two file-like methods: Returns the file handle number of the open mixer device file. .. versionchanged:: 3.2 - Mixer objects also support the context manager protocol. + Mixer objects also support the context management protocol. The remaining methods are specific to audio mixing: @@ -407,7 +407,7 @@ The remaining methods are specific to audio mixing: (silent) to 100 (full volume). If the control is monophonic, a 2-tuple is still returned, but both volumes are the same. - Raises :exc:`OSSAudioError` if an invalid control was is specified, or + Raises :exc:`OSSAudioError` if an invalid control is specified, or :exc:`OSError` if an unsupported control is specified. diff --git a/Doc/library/othergui.rst b/Doc/library/othergui.rst index eb49b994d89e..efb7cff9dc31 100644 --- a/Doc/library/othergui.rst +++ b/Doc/library/othergui.rst @@ -10,7 +10,7 @@ available for Python: `PyGObject <https://live.gnome.org/PyGObject>`_ provides introspection bindings for C libraries using - `GObject <http://developer.gnome.org/gobject/stable/>`_. One of + `GObject <https://developer.gnome.org/gobject/stable/>`_. One of these libraries is the `GTK+ 3 <http://www.gtk.org/>`_ widget set. GTK+ comes with many more widgets than Tkinter provides. An online `Python GTK+ 3 Tutorial <http://python-gtk-3-tutorial.readthedocs.org/en/latest/>`_ @@ -22,7 +22,7 @@ available for Python: `GNOME <http://www.gnome.org>`_. An online `tutorial <http://www.pygtk.org/pygtk2tutorial/index.html>`_ is available. - `PyQt <http://www.riverbankcomputing.co.uk/software/pyqt/>`_ + `PyQt <http://www.riverbankcomputing.co.uk/software/pyqt/intro>`_ PyQt is a :program:`sip`\ -wrapped binding to the Qt toolkit. Qt is an extensive C++ GUI application development framework that is available for Unix, Windows and Mac OS X. :program:`sip` is a tool @@ -34,7 +34,7 @@ available for Python: with Python and Qt <http://www.qtrac.eu/pyqtbook.html>`_, by Mark Summerfield. - `PySide <http://www.pyside.org/>`_ + `PySide <http://qt-project.org/wiki/PySide>`_ is a newer binding to the Qt toolkit, provided by Nokia. Compared to PyQt, its licensing scheme is friendlier to non-open source applications. @@ -56,7 +56,7 @@ available for Python: PyGTK, PyQt, and wxPython, all have a modern look and feel and more widgets than Tkinter. In addition, there are many other GUI toolkits for Python, both cross-platform, and platform-specific. See the `GUI Programming -<http://wiki.python.org/moin/GuiProgramming>`_ page in the Python Wiki for a +<https://wiki.python.org/moin/GuiProgramming>`_ page in the Python Wiki for a much more complete list, and also for links to documents where the different GUI toolkits are compared. diff --git a/Doc/library/pathlib-inheritance.svg b/Doc/library/pathlib-inheritance.svg new file mode 100644 index 000000000000..9f42005e0a12 --- /dev/null +++ b/Doc/library/pathlib-inheritance.svg @@ -0,0 +1,4 @@ +<?xml version="1.0" standalone="yes"?> + +<svg version="1.1" viewBox="0.0 0.0 538.0 496.0" fill="none" stroke="none" stroke-linecap="square" stroke-miterlimit="10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><clipPath id="p.0"><path d="m0 0l538.0 0l0 496.0l-538.0 0l0 -496.0z" clip-rule="nonzero"></path></clipPath><g clip-path="url(#p.0)"><path fill="#000000" fill-opacity="0.0" d="m0 0l538.916 0l0 496.08398l-538.916 0z" fill-rule="nonzero"></path><path fill="#ffffff" d="m176.0 24.0l187.43307 0l0 80.53543l-187.43307 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m176.0 24.0l187.43307 0l0 80.53543l-187.43307 0z" fill-rule="nonzero"></path><path fill="#000000" d="m235.18527 66.877716l0 1.640625l1.625 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-3.46875 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.25 0l0 -6.265625l-0.25 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l3.6875 0.015625q1.625 0 2.5625 0.890625q0.953125 0.875 0.953125 2.15625q0 0.703125 -0.3125 1.328125q-0.25 0.46875 -0.8125 0.921875q-0.5625 0.453125 -1.15625 0.6875q-0.59375 0.234375 -1.5625 0.234375l-1.515625 0zm0 -1.609375l1.484375 0q1.046875 0 1.65625 -0.46875q0.625 -0.46875 0.625 -1.140625q0 -0.5625 -0.5 -0.984375q-0.5 -0.421875 -1.421875 -0.421875l-1.84375 0l0 3.015625zm13.9296875 -2.234375l0 5.484375q0.515625 0 0.75 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-1.515625 0l0 -0.375q-0.6875 0.3125 -1.3125 0.46875q-0.625 0.171875 -1.1875 0.171875q-0.796875 0 -1.375 -0.328125q-0.578125 -0.34375 -0.90625 -0.9375q-0.25 -0.421875 -0.25 -1.046875l0 -3.453125l-0.265625 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l1.875 0l0 4.765625q0 0.5 0.234375 0.75q0.25 0.234375 0.765625 0.234375q0.484375 0 1.03125 -0.1875q0.5625 -0.203125 1.390625 -0.703125l0 -3.265625l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l2.171875 0zm5.8671875 0l0 1.0q1.015625 -0.734375 1.59375 -0.96875q0.578125 -0.25 1.09375 -0.25q0.78125 0 1.515625 0.578125q0.5 0.390625 0.5 0.796875q0 0.34375 -0.25 0.59375q-0.234375 0.234375 -0.5625 0.234375q-0.296875 0 -0.625 -0.296875q-0.328125 -0.296875 -0.59375 -0.296875q-0.328125 0 -1.0 0.421875q-0.671875 0.421875 -1.671875 1.265625l0 2.40625l2.28125 0q0.578125 0 0.828125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-4.828125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.953125 0l0 -3.890625l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l2.171875 0zm13.9609375 4.359375l-6.578125 0q0.25 0.625 0.890625 1.015625q0.640625 0.375 1.71875 0.375q0.890625 0 2.375 -0.390625q0.609375 -0.15625 0.84375 -0.15625q0.3125 0 0.53125 0.234375q0.21875 0.21875 0.21875 0.5625q0 0.3125 -0.234375 0.53125q-0.3125 0.296875 -1.53125 0.5625q-1.203125 0.265625 -2.3125 0.265625q-1.921875 0 -3.078125 -1.09375q-1.15625 -1.09375 -1.15625 -2.671875q0 -1.6875 1.25 -2.75q1.25 -1.0625 2.875 -1.0625q0.96875 0 1.78125 0.34375q0.828125 0.34375 1.21875 0.75q0.5625 0.578125 0.9375 1.421875q0.25 0.59375 0.25 1.375l0 0.6875zm-1.78125 -1.609375q-0.359375 -0.6875 -0.953125 -1.015625q-0.59375 -0.34375 -1.421875 -0.34375q-0.8125 0 -1.40625 0.34375q-0.59375 0.328125 -0.96875 1.015625l4.75 0zm6.4296875 1.09375l0 1.640625l1.625 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-3.46875 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.25 0l0 -6.265625l-0.25 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l3.6875 0.015625q1.625 0 2.5625 0.890625q0.953125 0.875 0.953125 2.15625q0 0.703125 -0.3125 1.328125q-0.25 0.46875 -0.8125 0.921875q-0.5625 0.453125 -1.15625 0.6875q-0.59375 0.234375 -1.5625 0.234375l-1.515625 0zm0 -1.609375l1.484375 0q1.046875 0 1.65625 -0.46875q0.625 -0.46875 0.625 -1.140625q0 -0.5625 -0.5 -0.984375q-0.5 -0.421875 -1.421875 -0.421875l-1.84375 0l0 3.015625zm11.9765625 4.859375l0 -0.375q-0.609375 0.3125 -1.34375 0.46875q-0.71875 0.171875 -1.3125 0.171875q-1.28125 0 -2.09375 -0.6875q-0.796875 -0.6875 -0.796875 -1.515625q0 -1.0 1.015625 -1.859375q1.03125 -0.875 2.84375 -0.875q0.734375 0 1.6875 0.15625l0 -0.375q0 -0.359375 -0.3125 -0.578125q-0.3125 -0.234375 -1.171875 -0.234375q-0.71875 0 -1.84375 0.28125q-0.421875 0.09375 -0.65625 0.09375q-0.328125 0 -0.546875 -0.21875q-0.21875 -0.234375 -0.21875 -0.59375q0 -0.203125 0.078125 -0.34375q0.078125 -0.15625 0.21875 -0.25q0.140625 -0.09375 0.578125 -0.21875q0.59375 -0.15625 1.203125 -0.25q0.625 -0.109375 1.125 -0.109375q1.5 0 2.3125 0.65625q0.828125 0.640625 0.828125 1.75l0 3.296875l0.28125 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.875 0zm0 -2.875q-0.96875 -0.1875 -1.78125 -0.1875q-0.96875 0 -1.671875 0.484375q-0.4375 0.296875 -0.4375 0.609375q0 0.234375 0.203125 0.375q0.390625 0.25 1.078125 0.25q0.578125 0 1.296875 -0.21875q0.734375 -0.234375 1.3125 -0.625l0 -0.6875zm7.7578125 -2.625l0 3.21875q0 0.515625 0.21875 0.671875q0.328125 0.265625 1.171875 0.265625q1.21875 0 2.265625 -0.53125q0.390625 -0.203125 0.625 -0.203125q0.3125 0 0.53125 0.234375q0.234375 0.234375 0.234375 0.578125q0 0.3125 -0.25 0.53125q-0.375 0.375 -1.515625 0.6875q-1.125 0.3125 -1.890625 0.3125q-1.5 0 -2.25 -0.640625q-0.734375 -0.65625 -0.734375 -1.59375l0 -3.53125l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l0.578125 0l0 -1.453125q0 -0.578125 0.21875 -0.8125q0.21875 -0.25 0.578125 -0.25q0.359375 0 0.578125 0.25q0.21875 0.234375 0.21875 0.8125l0 1.453125l2.96875 0q0.578125 0 0.8125 0.21875q0.25 0.21875 0.25 0.578125q0 0.359375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-2.96875 0zm8.3515625 -4.640625l0 3.421875q0.5 -0.296875 1.0 -0.4375q0.515625 -0.15625 1.046875 -0.15625q0.828125 0 1.46875 0.28125q0.65625 0.28125 1.078125 0.890625q0.421875 0.609375 0.421875 1.53125l0 3.0q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.5625 0 -0.8125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.4375 0.375 -0.671875q0.203125 -0.125 0.796875 -0.125l0 -2.890625q0 -0.625 -0.28125 -0.875q-0.359375 -0.328125 -1.078125 -0.328125q-0.53125 0 -0.953125 0.203125q-0.40625 0.203125 -1.09375 0.890625l0 3.0q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.4375 0.375 -0.671875q0.1875 -0.125 0.796875 -0.125l0 -6.921875l-0.265625 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l1.875 0z" fill-rule="nonzero"></path><path fill="#ffffff" d="m16.0 144.0l187.43306 0l0 80.53543l-187.43306 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m16.0 144.0l187.43306 0l0 80.53543l-187.43306 0z" fill-rule="nonzero"></path><path fill="#000000" d="m51.181374 186.87772l0 1.640625l1.625 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-3.46875 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.25 0l0 -6.265625l-0.25 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l3.6875 0.015625q1.625 0 2.5625 0.890625q0.953125 0.875 0.953125 2.15625q0 0.703125 -0.3125 1.328125q-0.25 0.46875 -0.8125 0.921875q-0.5625 0.453125 -1.15625 0.6875q-0.59375 0.234375 -1.5625 0.234375l-1.515625 0zm0 -1.609375l1.484375 0q1.046875 0 1.65625 -0.46875q0.625 -0.46875 0.625 -1.140625q0 -0.5625 -0.5 -0.984375q-0.5 -0.421875 -1.421875 -0.421875l-1.84375 0l0 3.015625zm13.9296875 -2.234375l0 5.484375q0.515625 0 0.75 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-1.515625 0l0 -0.375q-0.6875 0.3125 -1.3125 0.46875q-0.625 0.171875 -1.1875 0.171875q-0.796875 0 -1.375 -0.328125q-0.578125 -0.34375 -0.90625 -0.9375q-0.25 -0.421875 -0.25 -1.046875l0 -3.453125l-0.265625 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l1.875 0l0 4.765625q0 0.5 0.234375 0.75q0.25 0.234375 0.765625 0.234375q0.484375 0 1.03125 -0.1875q0.5625 -0.203125 1.390625 -0.703125l0 -3.265625l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l2.171875 0zm5.8671875 0l0 1.0q1.015625 -0.734375 1.59375 -0.96875q0.578125 -0.25 1.09375 -0.25q0.78125 0 1.515625 0.578125q0.5 0.390625 0.5 0.796875q0 0.34375 -0.25 0.59375q-0.234375 0.234375 -0.5625 0.234375q-0.296875 0 -0.625 -0.296875q-0.328125 -0.296875 -0.59375 -0.296875q-0.328125 0 -1.0 0.421875q-0.671875 0.421875 -1.671875 1.265625l0 2.40625l2.28125 0q0.578125 0 0.828125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-4.828125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.953125 0l0 -3.890625l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l2.171875 0zm13.9609375 4.359375l-6.578125 0q0.25 0.625 0.890625 1.015625q0.640625 0.375 1.71875 0.375q0.890625 0 2.375 -0.390625q0.609375 -0.15625 0.84375 -0.15625q0.3125 0 0.53125 0.234375q0.21875 0.21875 0.21875 0.5625q0 0.3125 -0.234375 0.53125q-0.3125 0.296875 -1.53125 0.5625q-1.203125 0.265625 -2.3125 0.265625q-1.921875 0 -3.078125 -1.09375q-1.15625 -1.09375 -1.15625 -2.671875q0 -1.6875 1.25 -2.75q1.25 -1.0625 2.875 -1.0625q0.96875 0 1.78125 0.34375q0.828125 0.34375 1.21875 0.75q0.5625 0.578125 0.9375 1.421875q0.25 0.59375 0.25 1.375l0 0.6875zm-1.78125 -1.609375q-0.359375 -0.6875 -0.953125 -1.015625q-0.59375 -0.34375 -1.421875 -0.34375q-0.8125 0 -1.40625 0.34375q-0.59375 0.328125 -0.96875 1.015625l4.75 0zm6.4296875 1.09375l0 1.640625l1.625 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-3.46875 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.25 0l0 -6.265625l-0.25 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l3.6875 0.015625q1.625 0 2.5625 0.890625q0.953125 0.875 0.953125 2.15625q0 0.703125 -0.3125 1.328125q-0.25 0.46875 -0.8125 0.921875q-0.5625 0.453125 -1.15625 0.6875q-0.59375 0.234375 -1.5625 0.234375l-1.515625 0zm0 -1.609375l1.484375 0q1.046875 0 1.65625 -0.46875q0.625 -0.46875 0.625 -1.140625q0 -0.5625 -0.5 -0.984375q-0.5 -0.421875 -1.421875 -0.421875l-1.84375 0l0 3.015625zm14.6953125 1.4375q0 0.921875 -0.515625 1.796875q-0.515625 0.859375 -1.53125 1.375q-1.0 0.515625 -2.109375 0.515625q-1.09375 0 -2.09375 -0.5q-1.0 -0.515625 -1.53125 -1.375q-0.515625 -0.875 -0.515625 -1.828125q0 -0.953125 0.53125 -1.875q0.53125 -0.9375 1.53125 -1.46875q1.0 -0.53125 2.078125 -0.53125q1.09375 0 2.109375 0.546875q1.015625 0.546875 1.53125 1.46875q0.515625 0.90625 0.515625 1.875zm-1.609375 0.015625q0 -0.78125 -0.546875 -1.421875q-0.765625 -0.875 -2.0 -0.875q-1.078125 0 -1.8125 0.703125q-0.71875 0.6875 -0.71875 1.59375q0 0.75 0.734375 1.40625q0.734375 0.65625 1.796875 0.65625q1.078125 0 1.8125 -0.65625q0.734375 -0.65625 0.734375 -1.40625zm8.7734375 -1.8125q-0.390625 -0.25 -0.828125 -0.359375q-0.421875 -0.125 -0.890625 -0.125q-0.921875 0 -1.46875 0.296875q-0.25 0.140625 -0.25 0.296875q0 0.171875 0.328125 0.34375q0.25 0.125 1.125 0.25q1.59375 0.21875 2.21875 0.4375q0.8125 0.28125 1.25 0.859375q0.453125 0.5625 0.453125 1.203125q0 0.859375 -0.75 1.4375q-1.09375 0.84375 -2.828125 0.84375q-0.6875 0 -1.28125 -0.125q-0.59375 -0.125 -1.078125 -0.359375q-0.125 0.09375 -0.265625 0.15625q-0.125 0.046875 -0.265625 0.046875q-0.375 0 -0.59375 -0.234375q-0.21875 -0.25 -0.21875 -0.828125l0 -0.546875q0 -0.578125 0.21875 -0.8125q0.21875 -0.25 0.578125 -0.25q0.296875 0 0.484375 0.15625q0.203125 0.15625 0.3125 0.546875q0.359375 0.3125 0.875 0.484375q0.515625 0.15625 1.1875 0.15625q1.109375 0 1.71875 -0.34375q0.28125 -0.171875 0.28125 -0.359375q0 -0.3125 -0.40625 -0.515625q-0.421875 -0.203125 -1.71875 -0.34375q-1.921875 -0.203125 -2.578125 -0.78125q-0.640625 -0.578125 -0.640625 -1.40625q0 -0.859375 0.71875 -1.4375q0.984375 -0.78125 2.578125 -0.78125q0.5625 0 1.0625 0.109375q0.515625 0.109375 0.984375 0.328125q0.15625 -0.109375 0.28125 -0.15625q0.125 -0.0625 0.234375 -0.0625q0.328125 0 0.546875 0.25q0.21875 0.234375 0.21875 0.8125l0 0.390625q0 0.53125 -0.125 0.71875q-0.25 0.359375 -0.671875 0.359375q-0.296875 0 -0.515625 -0.171875q-0.21875 -0.1875 -0.28125 -0.484375zm8.4453125 -4.921875l0 1.703125l-1.90625 0l0 -1.703125l1.90625 0zm0.21875 3.046875l0 5.484375l1.921875 0q0.578125 0 0.828125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-5.4375 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l1.921875 0l0 -3.890625l-1.296875 0q-0.5625 0 -0.8125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.234375 -0.578125q0.25 -0.21875 0.828125 -0.21875l2.890625 0zm10.007805 3.40625l2.4375 2.078125q0.4375 0.03125 0.65625 0.25q0.21875 0.21875 0.21875 0.5625q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-1.8125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.28125 0.171875 -0.5q0.1875 -0.21875 0.484375 -0.296875l-1.1875 -1.03125l-1.2187424 1.03125q0.35936737 0.09375 0.5156174 0.296875q0.171875 0.1875 0.171875 0.5q0 0.359375 -0.25 0.59375q-0.23436737 0.21875 -0.8124924 0.21875l-1.8125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.328125 0.21875 -0.546875q0.21875 -0.21875 0.65625 -0.25l2.375 -2.09375l-2.109375 -1.796875q-0.40625 -0.03125 -0.625 -0.25q-0.21875 -0.21875 -0.21875 -0.546875q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l1.5 0q0.578125 0 0.8124924 0.21875q0.25 0.21875 0.25 0.5625q0 0.46875 -0.43749237 0.75l0.9687424 0.8125l0.953125 -0.828125q-0.421875 -0.296875 -0.421875 -0.703125q0 -0.375 0.234375 -0.59375q0.25 -0.21875 0.828125 -0.21875l1.484375 0q0.578125 0 0.828125 0.21875q0.25 0.21875 0.25 0.578125q0 0.328125 -0.21875 0.546875q-0.21875 0.21875 -0.640625 0.25l-2.109375 1.8125zm7.4765625 0.4375l0 1.640625l1.625 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-3.46875 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.25 0l0 -6.265625l-0.25 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l3.6875 0.015625q1.625 0 2.5625 0.890625q0.953125 0.875 0.953125 2.15625q0 0.703125 -0.3125 1.328125q-0.25 0.46875 -0.8125 0.921875q-0.5625 0.453125 -1.15625 0.6875q-0.59375 0.234375 -1.5625 0.234375l-1.515625 0zm0 -1.609375l1.484375 0q1.046875 0 1.65625 -0.46875q0.625 -0.46875 0.625 -1.140625q0 -0.5625 -0.5 -0.984375q-0.5 -0.421875 -1.421875 -0.421875l-1.84375 0l0 3.015625zm11.9765625 4.859375l0 -0.375q-0.609375 0.3125 -1.34375 0.46875q-0.71875 0.171875 -1.3125 0.171875q-1.28125 0 -2.09375 -0.6875q-0.796875 -0.6875 -0.796875 -1.515625q0 -1.0 1.015625 -1.859375q1.03125 -0.875 2.84375 -0.875q0.734375 0 1.6875 0.15625l0 -0.375q0 -0.359375 -0.3125 -0.578125q-0.3125 -0.234375 -1.171875 -0.234375q-0.71875 0 -1.84375 0.28125q-0.421875 0.09375 -0.65625 0.09375q-0.328125 0 -0.546875 -0.21875q-0.21875 -0.234375 -0.21875 -0.59375q0 -0.203125 0.078125 -0.34375q0.078125 -0.15625 0.21875 -0.25q0.140625 -0.09375 0.578125 -0.21875q0.59375 -0.15625 1.203125 -0.25q0.625 -0.109375 1.125 -0.109375q1.5 0 2.3125 0.65625q0.828125 0.640625 0.828125 1.75l0 3.296875l0.28125 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.875 0zm0 -2.875q-0.96875 -0.1875 -1.78125 -0.1875q-0.96875 0 -1.671875 0.484375q-0.4375 0.296875 -0.4375 0.609375q0 0.234375 0.203125 0.375q0.390625 0.25 1.078125 0.25q0.578125 0 1.296875 -0.21875q0.734375 -0.234375 1.3125 -0.625l0 -0.6875zm7.7578125 -2.625l0 3.21875q0 0.515625 0.21875 0.671875q0.328125 0.265625 1.171875 0.265625q1.21875 0 2.265625 -0.53125q0.390625 -0.203125 0.625 -0.203125q0.3125 0 0.53125 0.234375q0.234375 0.234375 0.234375 0.578125q0 0.3125 -0.25 0.53125q-0.375 0.375 -1.515625 0.6875q-1.125 0.3125 -1.890625 0.3125q-1.5 0 -2.25 -0.640625q-0.734375 -0.65625 -0.734375 -1.59375l0 -3.53125l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l0.578125 0l0 -1.453125q0 -0.578125 0.21875 -0.8125q0.21875 -0.25 0.578125 -0.25q0.359375 0 0.578125 0.25q0.21875 0.234375 0.21875 0.8125l0 1.453125l2.96875 0q0.578125 0 0.8125 0.21875q0.25 0.21875 0.25 0.578125q0 0.359375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-2.96875 0zm8.3515625 -4.640625l0 3.421875q0.5 -0.296875 1.0 -0.4375q0.515625 -0.15625 1.046875 -0.15625q0.828125 0 1.46875 0.28125q0.65625 0.28125 1.078125 0.890625q0.421875 0.609375 0.421875 1.53125l0 3.0q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.5625 0 -0.8125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.4375 0.375 -0.671875q0.203125 -0.125 0.796875 -0.125l0 -2.890625q0 -0.625 -0.28125 -0.875q-0.359375 -0.328125 -1.078125 -0.328125q-0.53125 0 -0.953125 0.203125q-0.40625 0.203125 -1.09375 0.890625l0 3.0q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.4375 0.375 -0.671875q0.1875 -0.125 0.796875 -0.125l0 -6.921875l-0.265625 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l1.875 0z" fill-rule="nonzero"></path><path fill="#ffffff" d="m336.0 143.46457l187.43304 0l0 80.53543l-187.43304 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m336.0 143.46457l187.43304 0l0 80.53543l-187.43304 0z" fill-rule="nonzero"></path><path fill="#000000" d="m361.5798 186.34229l0 1.640625l1.625 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-3.46875 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.25 0l0 -6.265625l-0.25 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l3.6875 0.015625q1.625 0 2.5625 0.890625q0.953125 0.875 0.953125 2.15625q0 0.703125 -0.3125 1.328125q-0.25 0.46875 -0.8125 0.921875q-0.5625 0.453125 -1.15625 0.6875q-0.59375 0.234375 -1.5625 0.234375l-1.515625 0zm0 -1.609375l1.484375 0q1.046875 0 1.65625 -0.46875q0.625 -0.46875 0.625 -1.140625q0 -0.5625 -0.5 -0.984375q-0.5 -0.421875 -1.421875 -0.421875l-1.84375 0l0 3.015625zm13.9296875 -2.234375l0 5.484375q0.515625 0 0.75 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-1.515625 0l0 -0.375q-0.6875 0.3125 -1.3125 0.46875q-0.625 0.171875 -1.1875 0.171875q-0.796875 0 -1.375 -0.328125q-0.578125 -0.34375 -0.90625 -0.9375q-0.25 -0.421875 -0.25 -1.046875l0 -3.453125l-0.265625 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l1.875 0l0 4.765625q0 0.5 0.234375 0.75q0.25 0.234375 0.765625 0.234375q0.484375 0 1.03125 -0.1875q0.5625 -0.203125 1.390625 -0.703125l0 -3.265625l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l2.171875 0zm5.8671875 0l0 1.0q1.015625 -0.734375 1.59375 -0.96875q0.578125 -0.25 1.09375 -0.25q0.78125 0 1.515625 0.578125q0.5 0.390625 0.5 0.796875q0 0.34375 -0.25 0.59375q-0.234375 0.234375 -0.5625 0.234375q-0.296875 0 -0.625 -0.296875q-0.328125 -0.296875 -0.59375 -0.296875q-0.328125 0 -1.0 0.421875q-0.671875 0.421875 -1.671875 1.265625l0 2.40625l2.28125 0q0.578125 0 0.828125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-4.828125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.953125 0l0 -3.890625l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l2.171875 0zm13.9609375 4.359375l-6.578125 0q0.25 0.625 0.890625 1.015625q0.640625 0.375 1.71875 0.375q0.890625 0 2.375 -0.390625q0.609375 -0.15625 0.84375 -0.15625q0.3125 0 0.53125 0.234375q0.21875 0.21875 0.21875 0.5625q0 0.3125 -0.234375 0.53125q-0.3125 0.296875 -1.53125 0.5625q-1.203125 0.265625 -2.3125 0.265625q-1.921875 0 -3.078125 -1.09375q-1.15625 -1.09375 -1.15625 -2.671875q0 -1.6875 1.25 -2.75q1.25 -1.0625 2.875 -1.0625q0.96875 0 1.78125 0.34375q0.828125 0.34375 1.21875 0.75q0.5625 0.578125 0.9375 1.421875q0.25 0.59375 0.25 1.375l0 0.6875zm-1.78125 -1.609375q-0.359375 -0.6875 -0.953125 -1.015625q-0.59375 -0.34375 -1.421875 -0.34375q-0.8125 0 -1.40625 0.34375q-0.59375 0.328125 -0.96875 1.015625l4.75 0zm7.3671875 -0.203125l-1.484375 4.546875l-1.796875 0l-0.953125 -7.875q-0.375 -0.046875 -0.5625 -0.25q-0.1875 -0.203125 -0.1875 -0.53125q0 -0.375 0.25 -0.59375q0.25 -0.234375 0.828125 -0.234375l2.125 0.015625q0.578125 0 0.828125 0.21875q0.25 0.21875 0.25 0.578125q0 0.359375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-0.828125 0l0.53125 4.484375l1.25 -3.734375l1.671875 0l1.25 3.734375l0.53125 -4.484375l-0.84375 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.21875 -0.234375 -0.578125q0 -0.359375 0.234375 -0.578125q0.25 -0.234375 0.828125 -0.234375l2.125 0.015625q0.578125 0 0.828125 0.21875q0.25 0.21875 0.25 0.578125q0 0.296875 -0.203125 0.515625q-0.1875 0.21875 -0.5625 0.28125l-0.921875 7.875l-1.765625 0l-1.53125 -4.546875zm10.1640625 -5.59375l0 1.703125l-1.90625 0l0 -1.703125l1.90625 0zm0.21875 3.046875l0 5.484375l1.921875 0q0.578125 0 0.828125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-5.4375 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l1.921875 0l0 -3.890625l-1.296875 0q-0.5625 0 -0.8125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.234375 -0.578125q0.25 -0.21875 0.828125 -0.21875l2.890625 0zm7.1953125 0l0 0.53125q0.4375 -0.375 0.953125 -0.5625q0.53125 -0.1875 1.15625 -0.1875q1.421875 0 2.25 0.890625q0.65625 0.703125 0.65625 1.84375l0 2.96875q0.5 0 0.734375 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.453125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.34375 0.234375 -0.5625q0.25 -0.234375 0.75 -0.234375l0 -3.015625q0 -0.53125 -0.28125 -0.765625q-0.359375 -0.3125 -1.09375 -0.3125q-0.5625 0 -0.984375 0.21875q-0.40625 0.203125 -1.046875 0.90625l0 2.96875q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.4375 0.375 -0.671875q0.1875 -0.125 0.796875 -0.125l0 -3.890625q-0.5 0 -0.75 -0.21875q-0.234375 -0.234375 -0.234375 -0.578125q0 -0.359375 0.234375 -0.578125q0.25 -0.21875 0.828125 -0.21875l1.53125 0zm14.8984375 -3.046875l0 8.53125l0.265625 0q0.578125 0 0.828125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-1.875 0l0 -0.390625q-0.546875 0.3125 -1.140625 0.484375q-0.59375 0.171875 -1.234375 0.171875q-1.8125 0 -2.921875 -1.046875q-1.09375 -1.046875 -1.09375 -2.609375q0 -1.625 1.15625 -2.765625q1.15625 -1.15625 2.828125 -1.15625q0.625 0 1.21875 0.203125q0.609375 0.1875 1.1875 0.5625l0 -1.984375l-0.265625 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l1.875 0zm-1.609375 6.796875q0 -0.984375 -0.703125 -1.671875q-0.6875 -0.6875 -1.6875 -0.6875q-1.0 0 -1.703125 0.6875q-0.6875 0.6875 -0.6875 1.65625q0 0.875 0.625 1.453125q0.625 0.5625 1.765625 0.5625q1.125 0 1.75 -0.5625q0.640625 -0.578125 0.640625 -1.4375zm11.6953125 -0.078125q0 0.921875 -0.515625 1.796875q-0.515625 0.859375 -1.53125 1.375q-1.0 0.515625 -2.109375 0.515625q-1.09375 0 -2.09375 -0.5q-1.0 -0.515625 -1.53125 -1.375q-0.515625 -0.875 -0.515625 -1.828125q0 -0.953125 0.53125 -1.875q0.53125 -0.9375 1.53125 -1.46875q1.0 -0.53125 2.078125 -0.53125q1.09375 0 2.109375 0.546875q1.015625 0.546875 1.53125 1.46875q0.515625 0.90625 0.515625 1.875zm-1.609375 0.015625q0 -0.78125 -0.546875 -1.421875q-0.765625 -0.875 -2.0 -0.875q-1.078125 0 -1.8125 0.703125q-0.71875 0.6875 -0.71875 1.59375q0 0.75 0.734375 1.40625q0.734375 0.65625 1.796875 0.65625q1.078125 0 1.8125 -0.65625q0.734375 -0.65625 0.734375 -1.40625zm7.0546875 0.453125l-1.109375 2.953125l-1.5 0l-1.34375 -5.5q-0.4375 -0.015625 -0.671875 -0.234375q-0.21875 -0.234375 -0.21875 -0.5625q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l1.484375 0q0.578125 0 0.828125 0.21875q0.25 0.21875 0.25 0.578125q0 0.359375 -0.28125 0.609375q-0.21875 0.1875 -0.828125 0.1875l0.609375 2.546875l0.984375 -2.609375l1.421875 0l1.0 2.609375l0.625 -2.546875q-0.59375 0 -0.78125 -0.109375q-0.375 -0.25 -0.375 -0.6875q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l1.5 0q0.578125 0 0.828125 0.21875q0.25 0.21875 0.25 0.578125q0 0.328125 -0.21875 0.546875q-0.21875 0.21875 -0.640625 0.25l-1.3125 5.5l-1.484375 0l-1.171875 -2.953125zm11.3203125 -2.265625q-0.390625 -0.25 -0.828125 -0.359375q-0.421875 -0.125 -0.890625 -0.125q-0.921875 0 -1.46875 0.296875q-0.25 0.140625 -0.25 0.296875q0 0.171875 0.328125 0.34375q0.25 0.125 1.125 0.25q1.59375 0.21875 2.21875 0.4375q0.8125 0.28125 1.25 0.859375q0.453125 0.5625 0.453125 1.203125q0 0.859375 -0.75 1.4375q-1.09375 0.84375 -2.828125 0.84375q-0.6875 0 -1.28125 -0.125q-0.59375 -0.125 -1.078125 -0.359375q-0.125 0.09375 -0.265625 0.15625q-0.125 0.046875 -0.265625 0.046875q-0.375 0 -0.59375 -0.234375q-0.21875 -0.25 -0.21875 -0.828125l0 -0.546875q0 -0.578125 0.21875 -0.8125q0.21875 -0.25 0.578125 -0.25q0.296875 0 0.484375 0.15625q0.203125 0.15625 0.3125 0.546875q0.359375 0.3125 0.875 0.484375q0.515625 0.15625 1.1875 0.15625q1.109375 0 1.71875 -0.34375q0.28125 -0.171875 0.28125 -0.359375q0 -0.3125 -0.40625 -0.515625q-0.421875 -0.203125 -1.71875 -0.34375q-1.921875 -0.203125 -2.578125 -0.78125q-0.640625 -0.578125 -0.640625 -1.40625q0 -0.859375 0.71875 -1.4375q0.984375 -0.78125 2.578125 -0.78125q0.5625 0 1.0625 0.109375q0.515625 0.109375 0.984375 0.328125q0.15625 -0.109375 0.28125 -0.15625q0.125 -0.0625 0.234375 -0.0625q0.328125 0 0.546875 0.25q0.21875 0.234375 0.21875 0.8125l0 0.390625q0 0.53125 -0.125 0.71875q-0.25 0.359375 -0.671875 0.359375q-0.296875 0 -0.515625 -0.171875q-0.21875 -0.1875 -0.28125 -0.484375zm6.9453125 1.96875l0 1.640625l1.625 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-3.46875 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.25 0l0 -6.265625l-0.25 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l3.6875 0.015625q1.625 0 2.5625 0.890625q0.953125 0.875 0.953125 2.15625q0 0.703125 -0.3125 1.328125q-0.25 0.46875 -0.8125 0.921875q-0.5625 0.453125 -1.15625 0.6875q-0.59375 0.234375 -1.5625 0.234375l-1.515625 0zm0 -1.609375l1.484375 0q1.046875 0 1.65625 -0.46875q0.625 -0.46875 0.625 -1.140625q0 -0.5625 -0.5 -0.984375q-0.5 -0.421875 -1.421875 -0.421875l-1.84375 0l0 3.015625zm11.9765625 4.859375l0 -0.375q-0.609375 0.3125 -1.34375 0.46875q-0.71875 0.171875 -1.3125 0.171875q-1.28125 0 -2.09375 -0.6875q-0.796875 -0.6875 -0.796875 -1.515625q0 -1.0 1.015625 -1.859375q1.03125 -0.875 2.84375 -0.875q0.734375 0 1.6875 0.15625l0 -0.375q0 -0.359375 -0.3125 -0.578125q-0.3125 -0.234375 -1.171875 -0.234375q-0.71875 0 -1.84375 0.28125q-0.421875 0.09375 -0.65625 0.09375q-0.328125 0 -0.546875 -0.21875q-0.21875 -0.234375 -0.21875 -0.59375q0 -0.203125 0.078125 -0.34375q0.078125 -0.15625 0.21875 -0.25q0.140625 -0.09375 0.578125 -0.21875q0.59375 -0.15625 1.203125 -0.25q0.625 -0.109375 1.125 -0.109375q1.5 0 2.3125 0.65625q0.828125 0.640625 0.828125 1.75l0 3.296875l0.28125 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.875 0zm0 -2.875q-0.96875 -0.1875 -1.78125 -0.1875q-0.96875 0 -1.671875 0.484375q-0.4375 0.296875 -0.4375 0.609375q0 0.234375 0.203125 0.375q0.390625 0.25 1.078125 0.25q0.578125 0 1.296875 -0.21875q0.734375 -0.234375 1.3125 -0.625l0 -0.6875zm7.7578125 -2.625l0 3.21875q0 0.515625 0.21875 0.671875q0.328125 0.265625 1.171875 0.265625q1.21875 0 2.265625 -0.53125q0.390625 -0.203125 0.625 -0.203125q0.3125 0 0.53125 0.234375q0.234375 0.234375 0.234375 0.578125q0 0.3125 -0.25 0.53125q-0.375 0.375 -1.515625 0.6875q-1.125 0.3125 -1.890625 0.3125q-1.5 0 -2.25 -0.640625q-0.734375 -0.65625 -0.734375 -1.59375l0 -3.53125l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l0.578125 0l0 -1.453125q0 -0.578125 0.21875 -0.8125q0.21875 -0.25 0.578125 -0.25q0.359375 0 0.578125 0.25q0.21875 0.234375 0.21875 0.8125l0 1.453125l2.96875 0q0.578125 0 0.8125 0.21875q0.25 0.21875 0.25 0.578125q0 0.359375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-2.96875 0zm8.3515625 -4.640625l0 3.421875q0.5 -0.296875 1.0 -0.4375q0.515625 -0.15625 1.046875 -0.15625q0.828125 0 1.46875 0.28125q0.65625 0.28125 1.078125 0.890625q0.421875 0.609375 0.421875 1.53125l0 3.0q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.5625 0 -0.8125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.4375 0.375 -0.671875q0.203125 -0.125 0.796875 -0.125l0 -2.890625q0 -0.625 -0.28125 -0.875q-0.359375 -0.328125 -1.078125 -0.328125q-0.53125 0 -0.953125 0.203125q-0.40625 0.203125 -1.09375 0.890625l0 3.0q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.4375 0.375 -0.671875q0.1875 -0.125 0.796875 -0.125l0 -6.921875l-0.265625 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l1.875 0z" fill-rule="nonzero"></path><path fill="#ffffff" d="m176.0 271.46457l187.43307 0l0 80.53543l-187.43307 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m176.0 271.46457l187.43307 0l0 80.53543l-187.43307 0z" fill-rule="nonzero"></path><path fill="#000000" d="m254.3884 314.3423l0 1.640625l1.625 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-3.46875 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.25 0l0 -6.265625l-0.25 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l3.6875 0.015625q1.625 0 2.5625 0.890625q0.953125 0.875 0.953125 2.15625q0 0.703125 -0.3125 1.328125q-0.25 0.46875 -0.8125 0.921875q-0.5625 0.453125 -1.15625 0.6875q-0.59375 0.234375 -1.5625 0.234375l-1.515625 0zm0 -1.609375l1.484375 0q1.046875 0 1.65625 -0.46875q0.625 -0.46875 0.625 -1.140625q0 -0.5625 -0.5 -0.984375q-0.5 -0.421875 -1.421875 -0.421875l-1.84375 0l0 3.015625zm11.9765625 4.859375l0 -0.375q-0.609375 0.3125 -1.34375 0.46875q-0.71875 0.171875 -1.3125 0.171875q-1.28125 0 -2.09375 -0.6875q-0.796875 -0.6875 -0.796875 -1.515625q0 -1.0 1.015625 -1.859375q1.03125 -0.875 2.84375 -0.875q0.734375 0 1.6875 0.15625l0 -0.375q0 -0.359375 -0.3125 -0.578125q-0.3125 -0.234375 -1.171875 -0.234375q-0.71875 0 -1.84375 0.28125q-0.421875 0.09375 -0.65625 0.09375q-0.328125 0 -0.546875 -0.21875q-0.21875 -0.234375 -0.21875 -0.59375q0 -0.203125 0.078125 -0.34375q0.078125 -0.15625 0.21875 -0.25q0.140625 -0.09375 0.578125 -0.21875q0.59375 -0.15625 1.203125 -0.25q0.625 -0.109375 1.125 -0.109375q1.5 0 2.3125 0.65625q0.828125 0.640625 0.828125 1.75l0 3.296875l0.28125 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.875 0zm0 -2.875q-0.96875 -0.1875 -1.78125 -0.1875q-0.96875 0 -1.671875 0.484375q-0.4375 0.296875 -0.4375 0.609375q0 0.234375 0.203125 0.375q0.390625 0.25 1.078125 0.25q0.578125 0 1.296875 -0.21875q0.734375 -0.234375 1.3125 -0.625l0 -0.6875zm7.7578125 -2.625l0 3.21875q0 0.515625 0.21875 0.671875q0.328125 0.265625 1.171875 0.265625q1.21875 0 2.265625 -0.53125q0.390625 -0.203125 0.625 -0.203125q0.3125 0 0.53125 0.234375q0.234375 0.234375 0.234375 0.578125q0 0.3125 -0.25 0.53125q-0.375 0.375 -1.515625 0.6875q-1.125 0.3125 -1.890625 0.3125q-1.5 0 -2.25 -0.640625q-0.734375 -0.65625 -0.734375 -1.59375l0 -3.53125l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l0.578125 0l0 -1.453125q0 -0.578125 0.21875 -0.8125q0.21875 -0.25 0.578125 -0.25q0.359375 0 0.578125 0.25q0.21875 0.234375 0.21875 0.8125l0 1.453125l2.96875 0q0.578125 0 0.8125 0.21875q0.25 0.21875 0.25 0.578125q0 0.359375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-2.96875 0zm8.3515625 -4.640625l0 3.421875q0.5 -0.296875 1.0 -0.4375q0.515625 -0.15625 1.046875 -0.15625q0.828125 0 1.46875 0.28125q0.65625 0.28125 1.078125 0.890625q0.421875 0.609375 0.421875 1.53125l0 3.0q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.5625 0 -0.8125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.4375 0.375 -0.671875q0.203125 -0.125 0.796875 -0.125l0 -2.890625q0 -0.625 -0.28125 -0.875q-0.359375 -0.328125 -1.078125 -0.328125q-0.53125 0 -0.953125 0.203125q-0.40625 0.203125 -1.09375 0.890625l0 3.0q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.4375 0.375 -0.671875q0.1875 -0.125 0.796875 -0.125l0 -6.921875l-0.265625 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l1.875 0z" fill-rule="nonzero"></path><path fill="#ffffff" d="m16.0 400.0l187.43306 0l0 80.53543l-187.43306 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m16.0 400.0l187.43306 0l0 80.53543l-187.43306 0z" fill-rule="nonzero"></path><path fill="#000000" d="m70.3845 442.87772l0 1.640625l1.625 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-3.46875 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.25 0l0 -6.265625l-0.25 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l3.6875 0.015625q1.625 0 2.5625 0.890625q0.953125 0.875 0.953125 2.15625q0 0.703125 -0.3125 1.328125q-0.25 0.46875 -0.8125 0.921875q-0.5625 0.453125 -1.15625 0.6875q-0.59375 0.234375 -1.5625 0.234375l-1.515625 0zm0 -1.609375l1.484375 0q1.046875 0 1.65625 -0.46875q0.625 -0.46875 0.625 -1.140625q0 -0.5625 -0.5 -0.984375q-0.5 -0.421875 -1.421875 -0.421875l-1.84375 0l0 3.015625zm14.6953125 1.4375q0 0.921875 -0.515625 1.796875q-0.515625 0.859375 -1.53125 1.375q-1.0 0.515625 -2.109375 0.515625q-1.09375 0 -2.09375 -0.5q-1.0 -0.515625 -1.53125 -1.375q-0.515625 -0.875 -0.515625 -1.828125q0 -0.953125 0.53125 -1.875q0.53125 -0.9375 1.53125 -1.46875q1.0 -0.53125 2.078125 -0.53125q1.09375 0 2.109375 0.546875q1.015625 0.546875 1.53125 1.46875q0.515625 0.90625 0.515625 1.875zm-1.609375 0.015625q0 -0.78125 -0.546875 -1.421875q-0.765625 -0.875 -2.0 -0.875q-1.078125 0 -1.8125 0.703125q-0.71875 0.6875 -0.71875 1.59375q0 0.75 0.734375 1.40625q0.734375 0.65625 1.796875 0.65625q1.078125 0 1.8125 -0.65625q0.734375 -0.65625 0.734375 -1.40625zm8.7734375 -1.8125q-0.390625 -0.25 -0.828125 -0.359375q-0.421875 -0.125 -0.890625 -0.125q-0.921875 0 -1.46875 0.296875q-0.25 0.140625 -0.25 0.296875q0 0.171875 0.328125 0.34375q0.25 0.125 1.125 0.25q1.59375 0.21875 2.21875 0.4375q0.8125 0.28125 1.25 0.859375q0.453125 0.5625 0.453125 1.203125q0 0.859375 -0.75 1.4375q-1.09375 0.84375 -2.828125 0.84375q-0.6875 0 -1.28125 -0.125q-0.59375 -0.125 -1.078125 -0.359375q-0.125 0.09375 -0.265625 0.15625q-0.125 0.046875 -0.265625 0.046875q-0.375 0 -0.59375 -0.234375q-0.21875 -0.25 -0.21875 -0.828125l0 -0.546875q0 -0.578125 0.21875 -0.8125q0.21875 -0.25 0.578125 -0.25q0.296875 0 0.484375 0.15625q0.203125 0.15625 0.3125 0.546875q0.359375 0.3125 0.875 0.484375q0.515625 0.15625 1.1875 0.15625q1.109375 0 1.71875 -0.34375q0.28125 -0.171875 0.28125 -0.359375q0 -0.3125 -0.40625 -0.515625q-0.421875 -0.203125 -1.71875 -0.34375q-1.921875 -0.203125 -2.578125 -0.78125q-0.640625 -0.578125 -0.640625 -1.40625q0 -0.859375 0.71875 -1.4375q0.984375 -0.78125 2.578125 -0.78125q0.5625 0 1.0625 0.109375q0.515625 0.109375 0.984375 0.328125q0.15625 -0.109375 0.28125 -0.15625q0.125 -0.0625 0.234375 -0.0625q0.328125 0 0.546875 0.25q0.21875 0.234375 0.21875 0.8125l0 0.390625q0 0.53125 -0.125 0.71875q-0.25 0.359375 -0.671875 0.359375q-0.296875 0 -0.515625 -0.171875q-0.21875 -0.1875 -0.28125 -0.484375zm8.4453125 -4.921875l0 1.703125l-1.90625 0l0 -1.703125l1.90625 0zm0.21875 3.046875l0 5.484375l1.921875 0q0.578125 0 0.828125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-5.4375 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l1.921875 0l0 -3.890625l-1.296875 0q-0.5625 0 -0.8125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.234375 -0.578125q0.25 -0.21875 0.828125 -0.21875l2.890625 0zm10.0078125 3.40625l2.4375 2.078125q0.4375 0.03125 0.65625 0.25q0.21875 0.21875 0.21875 0.5625q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-1.8125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.28125 0.171875 -0.5q0.1875 -0.21875 0.484375 -0.296875l-1.1875 -1.03125l-1.21875 1.03125q0.359375 0.09375 0.515625 0.296875q0.171875 0.1875 0.171875 0.5q0 0.359375 -0.25 0.59375q-0.234375 0.21875 -0.8125 0.21875l-1.8125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.328125 0.21875 -0.546875q0.21875 -0.21875 0.65625 -0.25l2.375 -2.09375l-2.109375 -1.796875q-0.40625 -0.03125 -0.625 -0.25q-0.21875 -0.21875 -0.21875 -0.546875q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l1.5 0q0.578125 0 0.8125 0.21875q0.25 0.21875 0.25 0.5625q0 0.46875 -0.4375 0.75l0.96875 0.8125l0.953125 -0.828125q-0.421875 -0.296875 -0.421875 -0.703125q0 -0.375 0.234375 -0.59375q0.25 -0.21875 0.828125 -0.21875l1.484375 0q0.578125 0 0.828125 0.21875q0.25 0.21875 0.25 0.578125q0 0.328125 -0.21875 0.546875q-0.21875 0.21875 -0.640625 0.25l-2.109375 1.8125zm7.4765625 0.4375l0 1.640625l1.625 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-3.46875 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.25 0l0 -6.265625l-0.25 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l3.6875 0.015625q1.625 0 2.5625 0.890625q0.953125 0.875 0.953125 2.15625q0 0.703125 -0.3125 1.328125q-0.25 0.46875 -0.8125 0.921875q-0.5625 0.453125 -1.15625 0.6875q-0.59375 0.234375 -1.5625 0.234375l-1.515625 0zm0 -1.609375l1.484375 0q1.046875 0 1.65625 -0.46875q0.625 -0.46875 0.625 -1.140625q0 -0.5625 -0.5 -0.984375q-0.5 -0.421875 -1.421875 -0.421875l-1.84375 0l0 3.015625zm11.976555 4.859375l0 -0.375q-0.609375 0.3125 -1.34375 0.46875q-0.71875 0.171875 -1.3124924 0.171875q-1.28125 0 -2.09375 -0.6875q-0.796875 -0.6875 -0.796875 -1.515625q0 -1.0 1.015625 -1.859375q1.03125 -0.875 2.8437424 -0.875q0.734375 0 1.6875 0.15625l0 -0.375q0 -0.359375 -0.3125 -0.578125q-0.3125 -0.234375 -1.171875 -0.234375q-0.71875 0 -1.8437424 0.28125q-0.421875 0.09375 -0.65625 0.09375q-0.328125 0 -0.546875 -0.21875q-0.21875 -0.234375 -0.21875 -0.59375q0 -0.203125 0.078125 -0.34375q0.078125 -0.15625 0.21875 -0.25q0.140625 -0.09375 0.578125 -0.21875q0.59375 -0.15625 1.203125 -0.25q0.6249924 -0.109375 1.1249924 -0.109375q1.5 0 2.3125 0.65625q0.828125 0.640625 0.828125 1.75l0 3.296875l0.28125 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.875 0zm0 -2.875q-0.96875 -0.1875 -1.78125 -0.1875q-0.9687424 0 -1.6718674 0.484375q-0.4375 0.296875 -0.4375 0.609375q0 0.234375 0.203125 0.375q0.390625 0.25 1.078125 0.25q0.5781174 0 1.2968674 -0.21875q0.734375 -0.234375 1.3125 -0.625l0 -0.6875zm7.7578125 -2.625l0 3.21875q0 0.515625 0.21875 0.671875q0.328125 0.265625 1.171875 0.265625q1.21875 0 2.265625 -0.53125q0.390625 -0.203125 0.625 -0.203125q0.3125 0 0.53125 0.234375q0.234375 0.234375 0.234375 0.578125q0 0.3125 -0.25 0.53125q-0.375 0.375 -1.515625 0.6875q-1.125 0.3125 -1.890625 0.3125q-1.5 0 -2.25 -0.640625q-0.734375 -0.65625 -0.734375 -1.59375l0 -3.53125l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l0.578125 0l0 -1.453125q0 -0.578125 0.21875 -0.8125q0.21875 -0.25 0.578125 -0.25q0.359375 0 0.578125 0.25q0.21875 0.234375 0.21875 0.8125l0 1.453125l2.96875 0q0.578125 0 0.8125 0.21875q0.25 0.21875 0.25 0.578125q0 0.359375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-2.96875 0zm8.3515625 -4.640625l0 3.421875q0.5 -0.296875 1.0 -0.4375q0.515625 -0.15625 1.046875 -0.15625q0.828125 0 1.46875 0.28125q0.65625 0.28125 1.078125 0.890625q0.421875 0.609375 0.421875 1.53125l0 3.0q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.5625 0 -0.8125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.4375 0.375 -0.671875q0.203125 -0.125 0.796875 -0.125l0 -2.890625q0 -0.625 -0.28125 -0.875q-0.359375 -0.328125 -1.078125 -0.328125q-0.53125 0 -0.953125 0.203125q-0.40625 0.203125 -1.09375 0.890625l0 3.0q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.4375 0.375 -0.671875q0.1875 -0.125 0.796875 -0.125l0 -6.921875l-0.265625 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l1.875 0z" fill-rule="nonzero"></path><path fill="#ffffff" d="m336.0 400.0l187.43304 0l0 80.53543l-187.43304 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m336.0 400.0l187.43304 0l0 80.53543l-187.43304 0z" fill-rule="nonzero"></path><path fill="#000000" d="m381.72043 441.58084l-1.484375 4.546875l-1.796875 0l-0.953125 -7.875q-0.375 -0.046875 -0.5625 -0.25q-0.1875 -0.203125 -0.1875 -0.53125q0 -0.375 0.25 -0.59375q0.25 -0.234375 0.828125 -0.234375l2.125 0.015625q0.578125 0 0.828125 0.21875q0.25 0.21875 0.25 0.578125q0 0.359375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-0.828125 0l0.53125 4.484375l1.25 -3.734375l1.671875 0l1.25 3.734375l0.53125 -4.484375l-0.84375 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.21875 -0.234375 -0.578125q0 -0.359375 0.234375 -0.578125q0.25 -0.234375 0.828125 -0.234375l2.125 0.015625q0.578125 0 0.828125 0.21875q0.25 0.21875 0.25 0.578125q0 0.296875 -0.203125 0.515625q-0.1875 0.21875 -0.5625 0.28125l-0.921875 7.875l-1.765625 0l-1.53125 -4.546875zm10.1640625 -5.59375l0 1.703125l-1.90625 0l0 -1.703125l1.90625 0zm0.21875 3.046875l0 5.484375l1.921875 0q0.578125 0 0.828125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-5.4375 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l1.921875 0l0 -3.890625l-1.296875 0q-0.5625 0 -0.8125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.234375 -0.578125q0.25 -0.21875 0.828125 -0.21875l2.890625 0zm7.1953125 0l0 0.53125q0.4375 -0.375 0.953125 -0.5625q0.53125 -0.1875 1.15625 -0.1875q1.421875 0 2.25 0.890625q0.65625 0.703125 0.65625 1.84375l0 2.96875q0.5 0 0.734375 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.453125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.34375 0.234375 -0.5625q0.25 -0.234375 0.75 -0.234375l0 -3.015625q0 -0.53125 -0.28125 -0.765625q-0.359375 -0.3125 -1.09375 -0.3125q-0.5625 0 -0.984375 0.21875q-0.40625 0.203125 -1.046875 0.90625l0 2.96875q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.4375 0.375 -0.671875q0.1875 -0.125 0.796875 -0.125l0 -3.890625q-0.5 0 -0.75 -0.21875q-0.234375 -0.234375 -0.234375 -0.578125q0 -0.359375 0.234375 -0.578125q0.25 -0.21875 0.828125 -0.21875l1.53125 0zm14.8984375 -3.046875l0 8.53125l0.265625 0q0.578125 0 0.828125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-1.875 0l0 -0.390625q-0.546875 0.3125 -1.140625 0.484375q-0.59375 0.171875 -1.234375 0.171875q-1.8125 0 -2.921875 -1.046875q-1.09375 -1.046875 -1.09375 -2.609375q0 -1.625 1.15625 -2.765625q1.15625 -1.15625 2.828125 -1.15625q0.625 0 1.21875 0.203125q0.609375 0.1875 1.1875 0.5625l0 -1.984375l-0.265625 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l1.875 0zm-1.609375 6.796875q0 -0.984375 -0.703125 -1.671875q-0.6875 -0.6875 -1.6875 -0.6875q-1.0 0 -1.703125 0.6875q-0.6875 0.6875 -0.6875 1.65625q0 0.875 0.625 1.453125q0.625 0.5625 1.765625 0.5625q1.125 0 1.75 -0.5625q0.640625 -0.578125 0.640625 -1.4375zm11.6953125 -0.078125q0 0.921875 -0.515625 1.796875q-0.515625 0.859375 -1.53125 1.375q-1.0 0.515625 -2.109375 0.515625q-1.09375 0 -2.09375 -0.5q-1.0 -0.515625 -1.53125 -1.375q-0.515625 -0.875 -0.515625 -1.828125q0 -0.953125 0.53125 -1.875q0.53125 -0.9375 1.53125 -1.46875q1.0 -0.53125 2.078125 -0.53125q1.09375 0 2.109375 0.546875q1.015625 0.546875 1.53125 1.46875q0.515625 0.90625 0.515625 1.875zm-1.609375 0.015625q0 -0.78125 -0.546875 -1.421875q-0.765625 -0.875 -2.0 -0.875q-1.078125 0 -1.8125 0.703125q-0.71875 0.6875 -0.71875 1.59375q0 0.75 0.734375 1.40625q0.734375 0.65625 1.796875 0.65625q1.078125 0 1.8125 -0.65625q0.734375 -0.65625 0.734375 -1.40625zm7.0546875 0.453125l-1.109375 2.953125l-1.5 0l-1.34375 -5.5q-0.4375 -0.015625 -0.671875 -0.234375q-0.21875 -0.234375 -0.21875 -0.5625q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l1.484375 0q0.578125 0 0.828125 0.21875q0.25 0.21875 0.25 0.578125q0 0.359375 -0.28125 0.609375q-0.21875 0.1875 -0.828125 0.1875l0.609375 2.546875l0.984375 -2.609375l1.421875 0l1.0 2.609375l0.625 -2.546875q-0.59375 0 -0.78125 -0.109375q-0.375 -0.25 -0.375 -0.6875q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l1.5 0q0.578125 0 0.828125 0.21875q0.25 0.21875 0.25 0.578125q0 0.328125 -0.21875 0.546875q-0.21875 0.21875 -0.640625 0.25l-1.3125 5.5l-1.484375 0l-1.171875 -2.953125zm11.3203125 -2.265625q-0.390625 -0.25 -0.828125 -0.359375q-0.421875 -0.125 -0.890625 -0.125q-0.921875 0 -1.46875 0.296875q-0.25 0.140625 -0.25 0.296875q0 0.171875 0.328125 0.34375q0.25 0.125 1.125 0.25q1.59375 0.21875 2.21875 0.4375q0.8125 0.28125 1.25 0.859375q0.453125 0.5625 0.453125 1.203125q0 0.859375 -0.75 1.4375q-1.09375 0.84375 -2.828125 0.84375q-0.6875 0 -1.28125 -0.125q-0.59375 -0.125 -1.078125 -0.359375q-0.125 0.09375 -0.265625 0.15625q-0.125 0.046875 -0.265625 0.046875q-0.375 0 -0.59375 -0.234375q-0.21875 -0.25 -0.21875 -0.828125l0 -0.546875q0 -0.578125 0.21875 -0.8125q0.21875 -0.25 0.578125 -0.25q0.296875 0 0.484375 0.15625q0.203125 0.15625 0.3125 0.546875q0.359375 0.3125 0.875 0.484375q0.515625 0.15625 1.1875 0.15625q1.109375 0 1.71875 -0.34375q0.28125 -0.171875 0.28125 -0.359375q0 -0.3125 -0.40625 -0.515625q-0.421875 -0.203125 -1.71875 -0.34375q-1.921875 -0.203125 -2.578125 -0.78125q-0.640625 -0.578125 -0.640625 -1.40625q0 -0.859375 0.71875 -1.4375q0.984375 -0.78125 2.578125 -0.78125q0.5625 0 1.0625 0.109375q0.515625 0.109375 0.984375 0.328125q0.15625 -0.109375 0.28125 -0.15625q0.125 -0.0625 0.234375 -0.0625q0.328125 0 0.546875 0.25q0.21875 0.234375 0.21875 0.8125l0 0.390625q0 0.53125 -0.125 0.71875q-0.25 0.359375 -0.671875 0.359375q-0.296875 0 -0.515625 -0.171875q-0.21875 -0.1875 -0.28125 -0.484375zm6.9453125 1.96875l0 1.640625l1.625 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-3.46875 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.25 0l0 -6.265625l-0.25 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l3.6875 0.015625q1.625 0 2.5625 0.890625q0.953125 0.875 0.953125 2.15625q0 0.703125 -0.3125 1.328125q-0.25 0.46875 -0.8125 0.921875q-0.5625 0.453125 -1.15625 0.6875q-0.59375 0.234375 -1.5625 0.234375l-1.515625 0zm0 -1.609375l1.484375 0q1.046875 0 1.65625 -0.46875q0.625 -0.46875 0.625 -1.140625q0 -0.5625 -0.5 -0.984375q-0.5 -0.421875 -1.421875 -0.421875l-1.84375 0l0 3.015625zm11.9765625 4.859375l0 -0.375q-0.609375 0.3125 -1.34375 0.46875q-0.71875 0.171875 -1.3125 0.171875q-1.28125 0 -2.09375 -0.6875q-0.796875 -0.6875 -0.796875 -1.515625q0 -1.0 1.015625 -1.859375q1.03125 -0.875 2.84375 -0.875q0.734375 0 1.6875 0.15625l0 -0.375q0 -0.359375 -0.3125 -0.578125q-0.3125 -0.234375 -1.171875 -0.234375q-0.71875 0 -1.84375 0.28125q-0.421875 0.09375 -0.65625 0.09375q-0.328125 0 -0.546875 -0.21875q-0.21875 -0.234375 -0.21875 -0.59375q0 -0.203125 0.078125 -0.34375q0.078125 -0.15625 0.21875 -0.25q0.140625 -0.09375 0.578125 -0.21875q0.59375 -0.15625 1.203125 -0.25q0.625 -0.109375 1.125 -0.109375q1.5 0 2.3125 0.65625q0.828125 0.640625 0.828125 1.75l0 3.296875l0.28125 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.875 0zm0 -2.875q-0.96875 -0.1875 -1.78125 -0.1875q-0.96875 0 -1.671875 0.484375q-0.4375 0.296875 -0.4375 0.609375q0 0.234375 0.203125 0.375q0.390625 0.25 1.078125 0.25q0.578125 0 1.296875 -0.21875q0.734375 -0.234375 1.3125 -0.625l0 -0.6875zm7.7578125 -2.625l0 3.21875q0 0.515625 0.21875 0.671875q0.328125 0.265625 1.171875 0.265625q1.21875 0 2.265625 -0.53125q0.390625 -0.203125 0.625 -0.203125q0.3125 0 0.53125 0.234375q0.234375 0.234375 0.234375 0.578125q0 0.3125 -0.25 0.53125q-0.375 0.375 -1.515625 0.6875q-1.125 0.3125 -1.890625 0.3125q-1.5 0 -2.25 -0.640625q-0.734375 -0.65625 -0.734375 -1.59375l0 -3.53125l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l0.578125 0l0 -1.453125q0 -0.578125 0.21875 -0.8125q0.21875 -0.25 0.578125 -0.25q0.359375 0 0.578125 0.25q0.21875 0.234375 0.21875 0.8125l0 1.453125l2.96875 0q0.578125 0 0.8125 0.21875q0.25 0.21875 0.25 0.578125q0 0.359375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-2.96875 0zm8.3515625 -4.640625l0 3.421875q0.5 -0.296875 1.0 -0.4375q0.515625 -0.15625 1.046875 -0.15625q0.828125 0 1.46875 0.28125q0.65625 0.28125 1.078125 0.890625q0.421875 0.609375 0.421875 1.53125l0 3.0q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.5625 0 -0.8125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.4375 0.375 -0.671875q0.203125 -0.125 0.796875 -0.125l0 -2.890625q0 -0.625 -0.28125 -0.875q-0.359375 -0.328125 -1.078125 -0.328125q-0.53125 0 -0.953125 0.203125q-0.40625 0.203125 -1.09375 0.890625l0 3.0q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.4375 0.375 -0.671875q0.1875 -0.125 0.796875 -0.125l0 -6.921875l-0.265625 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l1.875 0z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m96.0 144.0l0 -80.0l80.0 0" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m96.0 144.0l0 -80.0l68.0 0" fill-rule="evenodd"></path><path stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m164.0 67.30347l9.076202 -3.3034668l-9.076202 -3.303463z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m431.5013 143.08398l0 -78.99999l-68.0 0" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m431.5013 143.08398l0 -78.99999l-56.0 0" fill-rule="evenodd"></path><path stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m375.5013 60.780525l-9.076202 3.3034668l9.076202 3.3034592z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m269.71652 104.53543l0 166.92914" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m269.71652 116.53543l0 154.92914" fill-rule="evenodd"></path><path stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m273.02 116.53543l-3.3034668 -9.076195l-3.3034668 9.076195z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m65.0 223.08398l-1.0078735 176.91339" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m64.93163 235.08379l-0.93950653 164.91359" fill-rule="evenodd"></path><path stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m68.23505 235.10262l-3.2517014 -9.094864l-3.3551178 9.05722z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m471.0 224.38058l-1.0078735 176.91336" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m470.93164 236.38037l-0.93951416 164.9136" fill-rule="evenodd"></path><path stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m474.23505 236.3992l-3.251709 -9.094864l-3.3551025 9.05722z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m128.50131 400.00266l0 -86.168l47.496002 0" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m128.50131 400.00266l0 -86.168l35.496002 0" fill-rule="evenodd"></path><path stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m163.99731 317.13812l9.076202 -3.3034668l-9.076202 -3.3034668z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m414.71902 400.00266l0 -86.168l-51.216003 0" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m414.71902 400.00266l0 -86.168l-39.216003 0" fill-rule="evenodd"></path><path stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m375.50302 310.5312l-9.076172 3.3034668l9.076172 3.3034668z" fill-rule="evenodd"></path></g></svg> + diff --git a/Doc/library/pathlib.rst b/Doc/library/pathlib.rst index a8c1dc9e8034..0226ce444be6 100644 --- a/Doc/library/pathlib.rst +++ b/Doc/library/pathlib.rst @@ -522,6 +522,36 @@ Pure paths provide the following methods and properties: ValueError: '/etc/passwd' does not start with '/usr' +.. method:: PurePath.with_name(name) + + Return a new path with the :attr:`name` changed. If the original path + doesn't have a name, ValueError is raised:: + + >>> p = PureWindowsPath('c:/Downloads/pathlib.tar.gz') + >>> p.with_name('setup.py') + PureWindowsPath('c:/Downloads/setup.py') + >>> p = PureWindowsPath('c:/') + >>> p.with_name('setup.py') + Traceback (most recent call last): + File "<stdin>", line 1, in <module> + File "/home/antoine/cpython/default/Lib/pathlib.py", line 751, in with_name + raise ValueError("%r has an empty name" % (self,)) + ValueError: PureWindowsPath('c:/') has an empty name + + +.. method:: PurePath.with_suffix(suffix) + + Return a new path with the :attr:`suffix` changed. If the original path + doesn't have a suffix, the new *suffix* is appended instead:: + + >>> p = PureWindowsPath('c:/Downloads/pathlib.tar.gz') + >>> p.with_suffix('.bz2') + PureWindowsPath('c:/Downloads/pathlib.tar.bz2') + >>> p = PureWindowsPath('README') + >>> p.with_suffix('.txt') + PureWindowsPath('README.txt') + + .. _concrete-paths: @@ -598,6 +628,17 @@ call fails (for example because the path doesn't exist): PosixPath('/home/antoine/pathlib') +.. classmethod:: Path.home() + + Return a new path object representing the user's home directory (as + returned by :func:`os.path.expanduser` with ``~`` construct):: + + >>> Path.home() + PosixPath('/home/antoine') + + .. versionadded:: 3.5 + + .. method:: Path.stat() Return information about this path (similarly to :func:`os.stat`). @@ -640,6 +681,18 @@ call fails (for example because the path doesn't exist): symlink *points to* an existing file or directory. +.. method:: Path.expanduser() + + Return a new path with expanded ``~`` and ``~user`` constructs, + as returned by :meth:`os.path.expanduser`:: + + >>> p = PosixPath('~/films/Monty Python') + >>> p.expanduser() + PosixPath('/home/eric/films/Monty Python') + + .. versionadded:: 3.5 + + .. method:: Path.glob(pattern) Glob the given *pattern* in the directory represented by this path, @@ -761,15 +814,29 @@ call fails (for example because the path doesn't exist): the symbolic link's information rather than its target's. -.. method:: Path.mkdir(mode=0o777, parents=False) +.. method:: Path.mkdir(mode=0o777, parents=False, exist_ok=False) Create a new directory at this given path. If *mode* is given, it is combined with the process' ``umask`` value to determine the file mode - and access flags. If the path already exists, :exc:`OSError` is raised. + and access flags. If the path already exists, :exc:`FileExistsError` + is raised. If *parents* is true, any missing parents of this path are created - as needed. If *parents* is false (the default), a missing parent raises - :exc:`OSError`. + as needed; they are created with the default permissions without taking + *mode* into account (mimicking the POSIX ``mkdir -p`` command). + + If *parents* is false (the default), a missing parent raises + :exc:`FileNotFoundError`. + + If *exist_ok* is false (the default), an :exc:`FileExistsError` is + raised if the target directory already exists. + + If *exist_ok* is true, :exc:`FileExistsError` exceptions will be + ignored (same behavior as the POSIX ``mkdir -p`` command), but only if the + last path component is not an existing non-directory file. + + .. versionchanged:: 3.5 + The *exist_ok* parameter was added. .. method:: Path.open(mode='r', buffering=-1, encoding=None, errors=None, newline=None) @@ -790,6 +857,34 @@ call fails (for example because the path doesn't exist): if the file's uid isn't found in the system database. +.. method:: Path.read_bytes() + + Return the binary contents of the pointed-to file as a bytes object:: + + >>> p = Path('my_binary_file') + >>> p.write_bytes(b'Binary file contents') + 20 + >>> p.read_bytes() + b'Binary file contents' + + .. versionadded:: 3.5 + + +.. method:: Path.read_text(encoding=None, errors=None) + + Return the decoded contents of the pointed-to file as a string:: + + >>> p = Path('my_text_file') + >>> p.write_text('Text file contents') + 18 + >>> p.read_text() + 'Text file contents' + + The optional parameters have the same meaning as in :func:`open`. + + .. versionadded:: 3.5 + + .. method:: Path.rename(target) Rename this file or directory to the given *target*. *target* can be @@ -850,6 +945,25 @@ call fails (for example because the path doesn't exist): Remove this directory. The directory must be empty. +.. method:: Path.samefile(other_path) + + Return whether this path points to the same file as *other_path*, which + can be either a Path object, or a string. The semantics are similar + to :func:`os.path.samefile` and :func:`os.path.samestat`. + + An :exc:`OSError` can be raised if either file cannot be accessed for some + reason. + + >>> p = Path('spam') + >>> q = Path('eggs') + >>> p.samefile(q) + False + >>> p.samefile('spam') + True + + .. versionadded:: 3.5 + + .. method:: Path.symlink_to(target, target_is_directory=False) Make this path a symbolic link to *target*. Under Windows, @@ -876,10 +990,40 @@ call fails (for example because the path doesn't exist): with the process' ``umask`` value to determine the file mode and access flags. If the file already exists, the function succeeds if *exist_ok* is true (and its modification time is updated to the current time), - otherwise :exc:`OSError` is raised. + otherwise :exc:`FileExistsError` is raised. .. method:: Path.unlink() Remove this file or symbolic link. If the path points to a directory, use :func:`Path.rmdir` instead. + + +.. method:: Path.write_bytes(data) + + Open the file pointed to in bytes mode, write *data* to it, and close the + file:: + + >>> p = Path('my_binary_file') + >>> p.write_bytes(b'Binary file contents') + 20 + >>> p.read_bytes() + b'Binary file contents' + + An existing file of the same name is overwritten. + + .. versionadded:: 3.5 + + +.. method:: Path.write_text(data, encoding=None, errors=None) + + Open the file pointed to in text mode, write *data* to it, and close the + file:: + + >>> p = Path('my_text_file') + >>> p.write_text('Text file contents') + 18 + >>> p.read_text() + 'Text file contents' + + .. versionadded:: 3.5 diff --git a/Doc/library/pdb.rst b/Doc/library/pdb.rst index 48a8a6b72230..6e526f4302d9 100644 --- a/Doc/library/pdb.rst +++ b/Doc/library/pdb.rst @@ -6,6 +6,9 @@ .. module:: pdb :synopsis: The Python debugger for interactive interpreters. +**Source code:** :source:`Lib/pdb.py` + +-------------- .. index:: single: debugging diff --git a/Doc/library/pickle.rst b/Doc/library/pickle.rst index 14d520696c88..4ce4d345af45 100644 --- a/Doc/library/pickle.rst +++ b/Doc/library/pickle.rst @@ -15,13 +15,14 @@ .. sectionauthor:: Barry Warsaw <barry@python.org> -The :mod:`pickle` module implements a fundamental, but powerful algorithm for -serializing and de-serializing a Python object structure. "Pickling" is the -process whereby a Python object hierarchy is converted into a byte stream, and -"unpickling" is the inverse operation, whereby a byte stream is converted back -into an object hierarchy. Pickling (and unpickling) is alternatively known as -"serialization", "marshalling," [#]_ or "flattening", however, to avoid -confusion, the terms used here are "pickling" and "unpickling".. +The :mod:`pickle` module implements binary protocols for serializing and +de-serializing a Python object structure. *"Pickling"* is the process +whereby a Python object hierarchy is converted into a byte stream, and +*"unpickling"* is the inverse operation, whereby a byte stream +(from a :term:`binary file` or :term:`bytes-like object`) is converted +back into an object hierarchy. Pickling (and unpickling) is alternatively +known as "serialization", "marshalling," [#]_ or "flattening"; however, to +avoid confusion, the terms used here are "pickling" and "unpickling". .. warning:: @@ -33,9 +34,8 @@ confusion, the terms used here are "pickling" and "unpickling".. Relationship to other Python modules ------------------------------------ -The :mod:`pickle` module has an transparent optimizer (:mod:`_pickle`) written -in C. It is used whenever available. Otherwise the pure Python implementation is -used. +Comparison with ``marshal`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^ Python has a more primitive serialization module called :mod:`marshal`, but in general :mod:`pickle` should always be the preferred way to serialize Python @@ -69,17 +69,33 @@ The :mod:`pickle` module differs from :mod:`marshal` in several significant ways The :mod:`pickle` serialization format is guaranteed to be backwards compatible across Python releases. -Note that serialization is a more primitive notion than persistence; although -:mod:`pickle` reads and writes file objects, it does not handle the issue of -naming persistent objects, nor the (even more complicated) issue of concurrent -access to persistent objects. The :mod:`pickle` module can transform a complex -object into a byte stream and it can transform the byte stream into an object -with the same internal structure. Perhaps the most obvious thing to do with -these byte streams is to write them onto a file, but it is also conceivable to -send them across a network or store them in a database. The module -:mod:`shelve` provides a simple interface to pickle and unpickle objects on -DBM-style database files. +Comparison with ``json`` +^^^^^^^^^^^^^^^^^^^^^^^^ +There are fundamental differences between the pickle protocols and +`JSON (JavaScript Object Notation) <http://json.org>`_: + +* JSON is a text serialization format (it outputs unicode text, although + most of the time it is then encoded to ``utf-8``), while pickle is + a binary serialization format; + +* JSON is human-readable, while pickle is not; + +* JSON is interoperable and widely used outside of the Python ecosystem, + while pickle is Python-specific; + +* JSON, by default, can only represent a subset of the Python built-in + types, and no custom classes; pickle can represent an extremely large + number of Python types (many of them automatically, by clever usage + of Python's introspection facilities; complex cases can be tackled by + implementing :ref:`specific object APIs <pickle-inst>`). + +.. seealso:: + The :mod:`json` module: a standard library module allowing JSON + serialization and deserialization. + + +.. _pickle-protocols: Data stream format ------------------ @@ -100,7 +116,9 @@ The module :mod:`pickletools` contains tools for analyzing data streams generated by :mod:`pickle`. :mod:`pickletools` source code has extensive comments about opcodes used by pickle protocols. -There are currently 4 different protocols which can be used for pickling. +There are currently 5 different protocols which can be used for pickling. +The higher the protocol used, the more recent the version of Python needed +to read the pickle produced. * Protocol version 0 is the original "human-readable" protocol and is backwards compatible with earlier versions of Python. @@ -112,10 +130,27 @@ There are currently 4 different protocols which can be used for pickling. efficient pickling of :term:`new-style class`\es. Refer to :pep:`307` for information about improvements brought by protocol 2. -* Protocol version 3 was added in Python 3. It has explicit support for +* Protocol version 3 was added in Python 3.0. It has explicit support for :class:`bytes` objects and cannot be unpickled by Python 2.x. This is - the default as well as the current recommended protocol; use it whenever - possible. + the default protocol, and the recommended protocol when compatibility with + other Python 3 versions is required. + +* Protocol version 4 was added in Python 3.4. It adds support for very large + objects, pickling more kinds of objects, and some data format + optimizations. Refer to :pep:`3154` for information about improvements + brought by protocol 4. + +.. note:: + Serialization is a more primitive notion than persistence; although + :mod:`pickle` reads and writes file objects, it does not handle the issue of + naming persistent objects, nor the (even more complicated) issue of concurrent + access to persistent objects. The :mod:`pickle` module can transform a complex + object into a byte stream and it can transform the byte stream into an object + with the same internal structure. Perhaps the most obvious thing to do with + these byte streams is to write them onto a file, but it is also conceivable to + send them across a network or store them in a database. The :mod:`shelve` + module provides a simple interface to pickle and unpickle objects on + DBM-style database files. Module Interface @@ -131,13 +166,16 @@ The :mod:`pickle` module provides the following constants: .. data:: HIGHEST_PROTOCOL - The highest protocol version available. This value can be passed as a - *protocol* value. + An integer, the highest :ref:`protocol version <pickle-protocols>` + available. This value can be passed as a *protocol* value to functions + :func:`dump` and :func:`dumps` as well as the :class:`Pickler` + constructor. .. data:: DEFAULT_PROTOCOL - The default protocol used for pickling. May be less than HIGHEST_PROTOCOL. - Currently the default protocol is 3, a new protocol designed for Python 3.0. + An integer, the default :ref:`protocol version <pickle-protocols>` used + for pickling. May be less than :data:`HIGHEST_PROTOCOL`. Currently the + default protocol is 3, a new protocol designed for Python 3. The :mod:`pickle` module provides the following functions to make the pickling @@ -148,13 +186,10 @@ process more convenient: Write a pickled representation of *obj* to the open :term:`file object` *file*. This is equivalent to ``Pickler(file, protocol).dump(obj)``. - The optional *protocol* argument tells the pickler to use the given protocol; - supported protocols are 0, 1, 2, 3. The default protocol is 3; a - backward-incompatible protocol designed for Python 3.0. - - Specifying a negative protocol version selects the highest protocol version - supported. The higher the protocol used, the more recent the version of - Python needed to read the pickle produced. + The optional *protocol* argument, an integer, tells the pickler to use + the given protocol; supported protocols are 0 to :data:`HIGHEST_PROTOCOL`. + If not specified, the default is :data:`DEFAULT_PROTOCOL`. If a negative + number is specified, :data:`HIGHEST_PROTOCOL` is selected. The *file* argument must have a write() method that accepts a single bytes argument. It can thus be an on-disk file opened for binary writing, a @@ -162,64 +197,57 @@ process more convenient: interface. If *fix_imports* is true and *protocol* is less than 3, pickle will try to - map the new Python 3.x names to the old module names used in Python 2.x, - so that the pickle data stream is readable with Python 2.x. + map the new Python 3 names to the old module names used in Python 2, so + that the pickle data stream is readable with Python 2. .. function:: dumps(obj, protocol=None, \*, fix_imports=True) - Return the pickled representation of the object as a :class:`bytes` - object, instead of writing it to a file. + Return the pickled representation of the object as a :class:`bytes` object, + instead of writing it to a file. - The optional *protocol* argument tells the pickler to use the given protocol; - supported protocols are 0, 1, 2, 3. The default protocol is 3; a - backward-incompatible protocol designed for Python 3.0. - - Specifying a negative protocol version selects the highest protocol version - supported. The higher the protocol used, the more recent the version of - Python needed to read the pickle produced. - - If *fix_imports* is true and *protocol* is less than 3, pickle will try to - map the new Python 3.x names to the old module names used in Python 2.x, - so that the pickle data stream is readable with Python 2.x. + Arguments *protocol* and *fix_imports* have the same meaning as in + :func:`dump`. .. function:: load(file, \*, fix_imports=True, encoding="ASCII", errors="strict") - Read a pickled object representation from the open :term:`file object` *file* - and return the reconstituted object hierarchy specified therein. This is - equivalent to ``Unpickler(file).load()``. + Read a pickled object representation from the open :term:`file object` + *file* and return the reconstituted object hierarchy specified therein. + This is equivalent to ``Unpickler(file).load()``. - The protocol version of the pickle is detected automatically, so no protocol - argument is needed. Bytes past the pickled object's representation are - ignored. + The protocol version of the pickle is detected automatically, so no + protocol argument is needed. Bytes past the pickled object's + representation are ignored. The argument *file* must have two methods, a read() method that takes an integer argument, and a readline() method that requires no arguments. Both - methods should return bytes. Thus *file* can be an on-disk file opened - for binary reading, a :class:`io.BytesIO` object, or any other custom object + methods should return bytes. Thus *file* can be an on-disk file opened for + binary reading, a :class:`io.BytesIO` object, or any other custom object that meets this interface. Optional keyword arguments are *fix_imports*, *encoding* and *errors*, which are used to control compatibility support for pickle stream generated - by Python 2.x. If *fix_imports* is true, pickle will try to map the old - Python 2.x names to the new names used in Python 3.x. The *encoding* and + by Python 2. If *fix_imports* is true, pickle will try to map the old + Python 2 names to the new names used in Python 3. The *encoding* and *errors* tell pickle how to decode 8-bit string instances pickled by Python - 2.x; these default to 'ASCII' and 'strict', respectively. + 2; these default to 'ASCII' and 'strict', respectively. The *encoding* can + be 'bytes' to read these 8-bit string instances as bytes objects. .. function:: loads(bytes_object, \*, fix_imports=True, encoding="ASCII", errors="strict") Read a pickled object hierarchy from a :class:`bytes` object and return the reconstituted object hierarchy specified therein - The protocol version of the pickle is detected automatically, so no protocol - argument is needed. Bytes past the pickled object's representation are - ignored. + The protocol version of the pickle is detected automatically, so no + protocol argument is needed. Bytes past the pickled object's + representation are ignored. Optional keyword arguments are *fix_imports*, *encoding* and *errors*, which are used to control compatibility support for pickle stream generated - by Python 2.x. If *fix_imports* is true, pickle will try to map the old - Python 2.x names to the new names used in Python 3.x. The *encoding* and + by Python 2. If *fix_imports* is true, pickle will try to map the old + Python 2 names to the new names used in Python 3. The *encoding* and *errors* tell pickle how to decode 8-bit string instances pickled by Python - 2.x; these default to 'ASCII' and 'strict', respectively. + 2; these default to 'ASCII' and 'strict', respectively. The *encoding* can + be 'bytes' to read these 8-bit string instances as bytes objects. The :mod:`pickle` module defines three exceptions: @@ -254,21 +282,19 @@ The :mod:`pickle` module exports two classes, :class:`Pickler` and This takes a binary file for writing a pickle data stream. - The optional *protocol* argument tells the pickler to use the given protocol; - supported protocols are 0, 1, 2, 3. The default protocol is 3; a - backward-incompatible protocol designed for Python 3.0. - - Specifying a negative protocol version selects the highest protocol version - supported. The higher the protocol used, the more recent the version of - Python needed to read the pickle produced. + The optional *protocol* argument, an integer, tells the pickler to use + the given protocol; supported protocols are 0 to :data:`HIGHEST_PROTOCOL`. + If not specified, the default is :data:`DEFAULT_PROTOCOL`. If a negative + number is specified, :data:`HIGHEST_PROTOCOL` is selected. The *file* argument must have a write() method that accepts a single bytes argument. It can thus be an on-disk file opened for binary writing, a - :class:`io.BytesIO` instance, or any other custom object that meets this interface. + :class:`io.BytesIO` instance, or any other custom object that meets this + interface. If *fix_imports* is true and *protocol* is less than 3, pickle will try to - map the new Python 3.x names to the old module names used in Python 2.x, - so that the pickle data stream is readable with Python 2.x. + map the new Python 3 names to the old module names used in Python 2, so + that the pickle data stream is readable with Python 2. .. method:: dump(obj) @@ -330,16 +356,17 @@ The :mod:`pickle` module exports two classes, :class:`Pickler` and The argument *file* must have two methods, a read() method that takes an integer argument, and a readline() method that requires no arguments. Both - methods should return bytes. Thus *file* can be an on-disk file object opened - for binary reading, a :class:`io.BytesIO` object, or any other custom object - that meets this interface. + methods should return bytes. Thus *file* can be an on-disk file object + opened for binary reading, a :class:`io.BytesIO` object, or any other + custom object that meets this interface. Optional keyword arguments are *fix_imports*, *encoding* and *errors*, which are used to control compatibility support for pickle stream generated - by Python 2.x. If *fix_imports* is true, pickle will try to map the old - Python 2.x names to the new names used in Python 3.x. The *encoding* and + by Python 2. If *fix_imports* is true, pickle will try to map the old + Python 2 names to the new names used in Python 3. The *encoding* and *errors* tell pickle how to decode 8-bit string instances pickled by Python - 2.x; these default to 'ASCII' and 'strict', respectively. + 2; these default to 'ASCII' and 'strict', respectively. The *encoding* can + be 'bytes' to read these ß8-bit string instances as bytes objects. .. method:: load() @@ -477,7 +504,7 @@ methods: .. method:: object.__getnewargs__() This method serve a similar purpose as :meth:`__getnewargs_ex__` but - for protocols 2 and newer. It must return a tuple of arguments `args` + for protocols 2 and newer. It must return a tuple of arguments ``args`` which will be passed to the :meth:`__new__` method upon unpickling. In protocols 4 and newer, :meth:`__getnewargs__` will not be called if @@ -811,6 +838,14 @@ alternatives such as the marshalling API in :mod:`xmlrpc.client` or third-party solutions. +Performance +----------- + +Recent versions of the pickle protocol (from protocol 2 and upwards) feature +efficient binary encodings for several common features and built-in types. +Also, the :mod:`pickle` module has a transparent optimizer written in C. + + .. _pickle-example: Examples @@ -824,7 +859,7 @@ For the simplest code, use the :func:`dump` and :func:`load` functions. :: data = { 'a': [1, 2.0, 3, 4+6j], 'b': ("character string", b"byte string"), - 'c': set([None, True, False]) + 'c': {None, True, False} } with open('data.pickle', 'wb') as f: diff --git a/Doc/library/pkgutil.rst b/Doc/library/pkgutil.rst index 22d44eb9bc77..5d3295db7ef8 100644 --- a/Doc/library/pkgutil.rst +++ b/Doc/library/pkgutil.rst @@ -58,7 +58,7 @@ support. .. deprecated:: 3.3 This emulation is no longer needed, as the standard import mechanism - is now fully PEP 302 compliant and available in :mod:`importlib` + is now fully PEP 302 compliant and available in :mod:`importlib`. .. class:: ImpLoader(fullname, file, filename, etc) @@ -67,22 +67,24 @@ support. .. deprecated:: 3.3 This emulation is no longer needed, as the standard import mechanism - is now fully PEP 302 compliant and available in :mod:`importlib` + is now fully PEP 302 compliant and available in :mod:`importlib`. .. function:: find_loader(fullname) Retrieve a :pep:`302` module loader for the given *fullname*. - This is a convenience wrapper around :func:`importlib.find_loader` that - sets the *path* argument correctly when searching for submodules, and - also ensures parent packages (if any) are imported before searching for - submodules. + This is a backwards compatibility wrapper around + :func:`importlib.util.find_spec` that converts most failures to + :exc:`ImportError` and only returns the loader rather than the full + :class:`ModuleSpec`. .. versionchanged:: 3.3 Updated to be based directly on :mod:`importlib` rather than relying on the package internal PEP 302 import emulation. + .. versionchanged:: 3.4 + Updated to be based on :pep:`451` .. function:: get_importer(path_item) @@ -109,14 +111,13 @@ support. not already imported, its containing package (if any) is imported, in order to establish the package ``__path__``. - This function uses :func:`iter_importers`, and is thus subject to the same - limitations regarding platform-specific special import locations such as the - Windows registry. - .. versionchanged:: 3.3 Updated to be based directly on :mod:`importlib` rather than relying on the package internal PEP 302 import emulation. + .. versionchanged:: 3.4 + Updated to be based on :pep:`451` + .. function:: iter_importers(fullname='') @@ -146,6 +147,7 @@ support. *prefix* is a string to output on the front of every module name on output. .. note:: + Only works for a :term:`finder` which defines an ``iter_modules()`` method. This interface is non-standard, so the module also provides implementations for :class:`importlib.machinery.FileFinder` and @@ -184,6 +186,7 @@ support. walk_packages(ctypes.__path__, ctypes.__name__ + '.') .. note:: + Only works for a :term:`finder` which defines an ``iter_modules()`` method. This interface is non-standard, so the module also provides implementations for :class:`importlib.machinery.FileFinder` and diff --git a/Doc/library/plistlib.rst b/Doc/library/plistlib.rst index 3cf8086528c0..416559114b29 100644 --- a/Doc/library/plistlib.rst +++ b/Doc/library/plistlib.rst @@ -32,9 +32,12 @@ Values can be strings, integers, floats, booleans, tuples, lists, dictionaries (but only with string keys), :class:`Data`, :class:`bytes`, :class:`bytesarray` or :class:`datetime.datetime` objects. +.. versionchanged:: 3.4 + New API, old API deprecated. Support for binary format plists added. + .. seealso:: - `PList manual page <http://developer.apple.com/documentation/Darwin/Reference/ManPages/man5/plist.5.html>`_ + `PList manual page <https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man5/plist.5.html>`_ Apple's documentation of the file format. @@ -79,6 +82,8 @@ This module defines the following functions: Load a plist from a bytes object. See :func:`load` for an explanation of the keyword arguments. + .. versionadded:: 3.4 + .. function:: dump(value, fp, \*, fmt=FMT_XML, sort_keys=True, skipkeys=False) @@ -102,8 +107,10 @@ This module defines the following functions: A :exc:`TypeError` will be raised if the object is of an unsupported type or a container that contains objects of unsupported types. - .. versionchanged:: 3.4 - Added the *fmt*, *sort_keys* and *skipkeys* arguments. + An :exc:`OverflowError` will be raised for integer values that cannot + be represented in (binary) plist files. + + .. versionadded:: 3.4 .. function:: dumps(value, \*, fmt=FMT_XML, sort_keys=True, skipkeys=False) @@ -112,6 +119,7 @@ This module defines the following functions: the documentation for :func:`dump` for an explanation of the keyword arguments of this function. + .. versionadded:: 3.4 The following functions are deprecated: @@ -121,7 +129,7 @@ The following functions are deprecated: and binary) file object. Returns the unpacked root object (which usually is a dictionary). - This function calls :func:`load` to do the actual work, the the documentation + This function calls :func:`load` to do the actual work, see the documentation of :func:`that function <load>` for an explanation of the keyword arguments. .. note:: @@ -130,7 +138,7 @@ The following functions are deprecated: to ``__getitem_``. This means that you can use attribute access to access items of these dictionaries. - .. deprecated: 3.4 Use :func:`load` instead. + .. deprecated:: 3.4 Use :func:`load` instead. .. function:: writePlist(rootObject, pathOrFile) @@ -138,7 +146,7 @@ The following functions are deprecated: Write *rootObject* to an XML plist file. *pathOrFile* may be either a file name or a (writable and binary) file object - .. deprecated: 3.4 Use :func:`dump` instead. + .. deprecated:: 3.4 Use :func:`dump` instead. .. function:: readPlistFromBytes(data) @@ -162,9 +170,6 @@ The following functions are deprecated: .. deprecated:: 3.4 Use :func:`dumps` instead. - .. versionchanged:: 3.4 - Added the *fmt*, *sort_keys* and *skipkeys* arguments. - The following classes are available: @@ -192,7 +197,7 @@ The following classes are available: .. deprecated:: 3.4 Use a :class:`bytes` object instead -The following constants are avaiable: +The following constants are available: .. data:: FMT_XML diff --git a/Doc/library/poplib.rst b/Doc/library/poplib.rst index e248d6b834a5..45baad96afa6 100644 --- a/Doc/library/poplib.rst +++ b/Doc/library/poplib.rst @@ -15,7 +15,7 @@ This module defines a class, :class:`POP3`, which encapsulates a connection to a POP3 server and implements the protocol as defined in :rfc:`1939`. The :class:`POP3` class supports both the minimal and optional command sets from -:rfc:`1939`. The :class:`POP3` class also supports the `STLS` command introduced +:rfc:`1939`. The :class:`POP3` class also supports the ``STLS`` command introduced in :rfc:`2595` to enable encrypted communication on an already established connection. Additionally, this module provides a class :class:`POP3_SSL`, which provides @@ -43,16 +43,23 @@ The :mod:`poplib` module provides two classes: This is a subclass of :class:`POP3` that connects to the server over an SSL encrypted socket. If *port* is not specified, 995, the standard POP3-over-SSL - port is used. *keyfile* and *certfile* are also optional - they can contain a - PEM formatted private key and certificate chain file for the SSL connection. - *timeout* works as in the :class:`POP3` constructor. *context* parameter is a - :class:`ssl.SSLContext` object which allows bundling SSL configuration - options, certificates and private keys into a single (potentially long-lived) - structure. + port is used. *timeout* works as in the :class:`POP3` constructor. + *context* is an optional :class:`ssl.SSLContext` object which allows + bundling SSL configuration options, certificates and private keys into a + single (potentially long-lived) structure. Please read :ref:`ssl-security` + for best practices. + + *keyfile* and *certfile* are a legacy alternative to *context* - they can + point to PEM-formatted private key and certificate chain files, + respectively, for the SSL connection. .. versionchanged:: 3.2 *context* parameter added. + .. versionchanged:: 3.4 + The class now supports hostname check with + :attr:`ssl.SSLContext.check_hostname` and *Server Name Indication* (see + :data:`ssl.HAS_SNI`). One exception is defined as an attribute of the :mod:`poplib` module: @@ -194,7 +201,12 @@ An :class:`POP3` instance has the following methods: *context* parameter is a :class:`ssl.SSLContext` object which allows bundling SSL configuration options, certificates and private keys into - a single (potentially long-lived) structure. + a single (potentially long-lived) structure. Please read :ref:`ssl-security` + for best practices. + + This method supports hostname checking via + :attr:`ssl.SSLContext.check_hostname` and *Server Name Indication* (see + :data:`ssl.HAS_SNI`). .. versionadded:: 3.4 diff --git a/Doc/library/pprint.rst b/Doc/library/pprint.rst index 447f8f70606c..c0589a31a90e 100644 --- a/Doc/library/pprint.rst +++ b/Doc/library/pprint.rst @@ -211,7 +211,7 @@ Example ------- To demonstrate several uses of the :func:`pprint` function and its parameters, -let's fetch information about a project from `PyPI <https://pypi.python.org>`_:: +let's fetch information about a project from `PyPI <https://pypi.python.org/pypi>`_:: >>> import json >>> import pprint diff --git a/Doc/library/pydoc.rst b/Doc/library/pydoc.rst index e10086551546..b5e3233619cd 100644 --- a/Doc/library/pydoc.rst +++ b/Doc/library/pydoc.rst @@ -20,6 +20,13 @@ The :mod:`pydoc` module automatically generates documentation from Python modules. The documentation can be presented as pages of text on the console, served to a Web browser, or saved to HTML files. +For modules, classes, functions and methods, the displayed documentation is +derived from the docstring (i.e. the :attr:`__doc__` attribute) of the object, +and recursively of its documentable members. If there is no docstring, +:mod:`pydoc` tries to obtain a description from the block of comment lines just +above the definition of the class, function or method in the source file, or at +the top of the module (see :func:`inspect.getcomments`). + The built-in function :func:`help` invokes the online help system in the interactive interpreter, which uses :mod:`pydoc` to generate its documentation as text on the console. The same text documentation can also be viewed from @@ -44,6 +51,10 @@ produced for that file. executed on that occasion. Use an ``if __name__ == '__main__':`` guard to only execute code when a file is invoked as a script and not just imported. +When printing output to the console, :program:`pydoc` attempts to paginate the +output for easier reading. If the :envvar:`PAGER` environment variable is set, +:program:`pydoc` will use its value as a pagination program. + Specifying a ``-w`` flag before the argument will cause HTML documentation to be written out to a file in the current directory, instead of displaying text on the console. @@ -59,11 +70,6 @@ will start a HTTP server on port 1234, allowing you to browse the documentation at ``http://localhost:1234/`` in your preferred Web browser. Specifying ``0`` as the port number will select an arbitrary unused port. -:program:`pydoc -g` will start the server and additionally bring up a -small :mod:`tkinter`\ -based graphical interface to help you search for -documentation pages. The ``-g`` option is deprecated, since the server can -now be controlled directly from HTTP clients. - :program:`pydoc -b` will start the server and additionally open a web browser to a module index page. Each served page has a navigation bar at the top where you can *Get* help on an individual item, *Search* all modules with a @@ -76,11 +82,19 @@ documents precisely the version of the module you would get if you started the Python interpreter and typed ``import spam``. Module docs for core modules are assumed to reside in -``http://docs.python.org/X.Y/library/`` where ``X`` and ``Y`` are the +``https://docs.python.org/X.Y/library/`` where ``X`` and ``Y`` are the major and minor version numbers of the Python interpreter. This can be overridden by setting the :envvar:`PYTHONDOCS` environment variable to a different URL or to a local directory containing the Library Reference Manual pages. .. versionchanged:: 3.2 - Added the ``-b`` option, deprecated the ``-g`` option. + Added the ``-b`` option. + +.. versionchanged:: 3.3 + The ``-g`` command line option was removed. + +.. versionchanged:: 3.4 + :mod:`pydoc` now uses :func:`inspect.signature` rather than + :func:`inspect.getfullargspec` to extract signature information from + callables. diff --git a/Doc/library/pyexpat.rst b/Doc/library/pyexpat.rst index b1543d8002b4..78aa99c48ee8 100644 --- a/Doc/library/pyexpat.rst +++ b/Doc/library/pyexpat.rst @@ -100,6 +100,11 @@ The :mod:`xml.parsers.expat` module contains two functions: http://www.python.org/ns/ elem1 elem2 + Due to limitations in the ``Expat`` library used by :mod:`pyexpat`, + the :class:`xmlparser` instance returned can only be used to parse a single + XML document. Call ``ParserCreate`` for each document to provide unique + parser instances. + .. seealso:: @@ -119,7 +124,9 @@ XMLParser Objects Parses the contents of the string *data*, calling the appropriate handler functions to process the parsed data. *isfinal* must be true on the final call - to this method. *data* can be the empty string at any time. + to this method; it allows the parsing of a single file in fragments, + not the submission of multiple files. + *data* can be the empty string at any time. .. method:: xmlparser.ParseFile(file) @@ -861,5 +868,5 @@ The ``errors`` module has the following attributes: .. [#] The encoding string included in XML output should conform to the appropriate standards. For example, "UTF-8" is valid, but "UTF8" is not. See http://www.w3.org/TR/2006/REC-xml11-20060816/#NT-EncodingDecl - and http://www.iana.org/assignments/character-sets . + and http://www.iana.org/assignments/character-sets/character-sets.xhtml. diff --git a/Doc/library/quopri.rst b/Doc/library/quopri.rst index 755811adfd84..3a74cf8511b7 100644 --- a/Doc/library/quopri.rst +++ b/Doc/library/quopri.rst @@ -24,9 +24,8 @@ sending a graphics file. .. function:: decode(input, output, header=False) Decode the contents of the *input* file and write the resulting decoded binary - data to the *output* file. *input* and *output* must be :term:`file objects - <file object>`. *input* will be read until ``input.readline()`` returns an - empty string. If the optional argument *header* is present and true, underscore + data to the *output* file. *input* and *output* must be :term:`binary file objects + <file object>`. If the optional argument *header* is present and true, underscore will be decoded as space. This is used to decode "Q"-encoded headers as described in :rfc:`1522`: "MIME (Multipurpose Internet Mail Extensions) Part Two: Message Header Extensions for Non-ASCII Text". @@ -34,27 +33,28 @@ 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 :term:`file objects - <file object>`. *input* will be read until ``input.readline()`` returns an - empty string. *quotetabs* is a flag which controls whether to encode embedded - spaces and tabs; when true it encodes such embedded whitespace, and when - false it leaves them unencoded. Note that spaces and tabs appearing at the - end of lines are always encoded, as per :rfc:`1521`. *header* is a flag - which controls if spaces are encoded as underscores as per :rfc:`1522`. + 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 <file object>`. *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. + Note that spaces and tabs appearing at the end of lines are always encoded, + as per :rfc:`1521`. *header* is a flag which controls if spaces are encoded + as underscores as per :rfc:`1522`. .. function:: decodestring(s, header=False) - Like :func:`decode`, except that it accepts a source string and returns the - corresponding decoded string. + Like :func:`decode`, except that it accepts a source :class:`bytes` and + returns the corresponding decoded :class:`bytes`. .. function:: encodestring(s, quotetabs=False, header=False) - Like :func:`encode`, except that it accepts a source string and returns the - corresponding encoded string. *quotetabs* and *header* are optional - (defaulting to ``False``), and are passed straight through to :func:`encode`. + Like :func:`encode`, except that it accepts a source :class:`bytes` and + returns the corresponding encoded :class:`bytes`. By default, it sends a + False value to *quotetabs* parameter of the :func:`encode` function. + .. seealso:: diff --git a/Doc/library/random.rst b/Doc/library/random.rst index 11dd367f8af0..f8b772749f48 100644 --- a/Doc/library/random.rst +++ b/Doc/library/random.rst @@ -46,8 +46,7 @@ from sources provided by the operating system. .. warning:: The pseudo-random generators of this module should not be used for - security purposes. Use :func:`os.urandom` or :class:`SystemRandom` if - you require a cryptographically secure pseudo-random number generator. + security purposes. Bookkeeping functions: diff --git a/Doc/library/re.rst b/Doc/library/re.rst index fa6a9ce71968..0d305d58c927 100644 --- a/Doc/library/re.rst +++ b/Doc/library/re.rst @@ -38,13 +38,6 @@ module-level functions and methods on that don't require you to compile a regex object first, but miss some fine-tuning parameters. -.. seealso:: - - Mastering Regular Expressions - Book on regular expressions by Jeffrey Friedl, published by O'Reilly. The - second edition of the book no longer covers Python at all, but the first - edition covered writing good regular expression patterns in great detail. - .. _re-syntax: @@ -304,6 +297,9 @@ The special characters are: >>> m.group(0) 'egg' + .. versionchanged: 3.5 + Added support for group references of fixed length. + ``(?<!...)`` Matches if the current position in the string is not preceded by a match for ``...``. This is called a :dfn:`negative lookbehind assertion`. Similar to @@ -317,7 +313,7 @@ The special characters are: optional and can be omitted. For example, ``(<)?(\w+@\w+(?:\.\w+)+)(?(1)>|$)`` is a poor email matching pattern, which will match with ``'<user@host.com>'`` as well as ``'user@host.com'``, but - not with ``'<user@host.com'`` nor ``'user@host.com>'`` . + not with ``'<user@host.com'`` nor ``'user@host.com>'``. The special sequences consist of ``'\'`` and a character from the list below. @@ -443,6 +439,14 @@ three digits in length. The ``'\u'`` and ``'\U'`` escape sequences have been added. +.. seealso:: + + Mastering Regular Expressions + Book on regular expressions by Jeffrey Friedl, published by O'Reilly. The + second edition of the book no longer covers Python at all, but the first + edition covered writing good regular expression patterns in great detail. + + .. _contents-of-module-re: @@ -458,8 +462,8 @@ form. .. function:: compile(pattern, flags=0) Compile a regular expression pattern into a regular expression object, which - can be used for matching using its :func:`match` and :func:`search` methods, - described below. + can be used for matching using its :func:`~regex.match` and + :func:`~regex.search` methods, described below. The expression's behaviour can be modified by specifying a *flags* value. Values can be any of the following variables, combined using bitwise OR (the @@ -520,7 +524,11 @@ form. current locale. The use of this flag is discouraged as the locale mechanism is very unreliable, and it only handles one "culture" at a time anyway; you should use Unicode matching instead, which is the default in Python 3 - for Unicode (str) patterns. + for Unicode (str) patterns. This flag makes sense only with bytes patterns. + + .. deprecated-removed:: 3.5 3.6 + Deprecated the use of :const:`re.LOCALE` with string patterns or + :const:`re.ASCII`. .. data:: M @@ -563,7 +571,7 @@ form. .. function:: search(pattern, string, flags=0) - Scan through *string* looking for a location where the regular expression + Scan through *string* looking for the first location where the regular expression *pattern* produces a match, and return a corresponding :ref:`match object <match-objects>`. Return ``None`` if no position in the string matches the pattern; note that this is different from finding a zero-length match at some @@ -621,17 +629,37 @@ form. That way, separator components are always found at the same relative indices within the result list. - Note that *split* will never split a string on an empty pattern match. - For example: + .. note:: + + :func:`split` doesn't currently split a string on an empty pattern match. + For example: + + >>> re.split('x*', 'axbc') + ['a', 'bc'] + + Even though ``'x*'`` also matches 0 'x' before 'a', between 'b' and 'c', + and after 'c', currently these matches are ignored. The correct behavior + (i.e. splitting on empty matches too and returning ``['', 'a', 'b', 'c', + '']``) will be implemented in future versions of Python, but since this + is a backward incompatible change, a :exc:`FutureWarning` will be raised + in the meanwhile. + + Patterns that can only match empty strings currently never split the + string. Since this doesn't match the expected behavior, a + :exc:`ValueError` will be raised starting from Python 3.5:: - >>> re.split('x*', 'foo') - ['foo'] - >>> re.split("(?m)^$", "foo\n\nbar\n") - ['foo\n\nbar\n'] + >>> re.split("^$", "foo\n\nbar\n", flags=re.M) + Traceback (most recent call last): + File "<stdin>", line 1, in <module> + ... + ValueError: split() requires a non-empty pattern match. .. versionchanged:: 3.1 Added the optional flags argument. + .. versionchanged:: 3.5 + Splitting on a pattern that could match an empty string now raises + a warning. Patterns that can only match empty strings are now rejected. .. function:: findall(pattern, string, flags=0) @@ -701,6 +729,9 @@ form. .. versionchanged:: 3.1 Added the optional flags argument. + .. versionchanged:: 3.5 + Unmatched groups are replaced with an empty string. + .. function:: subn(pattern, repl, string, count=0, flags=0) @@ -710,6 +741,9 @@ form. .. versionchanged:: 3.1 Added the optional flags argument. + .. versionchanged:: 3.5 + Unmatched groups are replaced with an empty string. + .. function:: escape(string) @@ -726,13 +760,36 @@ form. Clear the regular expression cache. -.. exception:: error +.. exception:: error(msg, pattern=None, pos=None) Exception raised when a string passed to one of the functions here is not a valid regular expression (for example, it might contain unmatched parentheses) or when some other error occurs during compilation or matching. It is never an - error if a string contains no match for a pattern. + error if a string contains no match for a pattern. The error instance has + the following additional attributes: + + .. attribute:: msg + + The unformatted error message. + + .. attribute:: pattern + + The regular expression pattern. + + .. attribute:: pos + + The index of *pattern* where compilation failed. + + .. attribute:: lineno + + The line corresponding to *pos*. + + .. attribute:: colno + + The column corresponding to *pos*. + .. versionchanged:: 3.5 + Added additional attributes. .. _re-objects: @@ -801,7 +858,7 @@ attributes: >>> pattern.fullmatch("dog") # No match as "o" is not at the start of "dog". >>> pattern.fullmatch("ogre") # No match as not the full string matches. >>> pattern.fullmatch("doggie", 1, 3) # Matches within given limits. - <_sre.SRE_Match object at ...> + <_sre.SRE_Match object; span=(1, 3), match='og'> .. versionadded:: 3.4 @@ -885,6 +942,8 @@ Match objects support the following methods and attributes: (``\g<1>``, ``\g<name>``) are replaced by the contents of the corresponding group. + .. versionchanged:: 3.5 + Unmatched groups are replaced with an empty string. .. method:: match.group([group1, ...]) @@ -1333,36 +1392,36 @@ successive matches:: Token = collections.namedtuple('Token', ['typ', 'value', 'line', 'column']) - def tokenize(s): + def tokenize(code): keywords = {'IF', 'THEN', 'ENDIF', 'FOR', 'NEXT', 'GOSUB', 'RETURN'} token_specification = [ ('NUMBER', r'\d+(\.\d*)?'), # Integer or decimal number ('ASSIGN', r':='), # Assignment operator ('END', r';'), # Statement terminator ('ID', r'[A-Za-z]+'), # Identifiers - ('OP', r'[+*\/\-]'), # Arithmetic operators + ('OP', r'[+\-*/]'), # Arithmetic operators ('NEWLINE', r'\n'), # Line endings - ('SKIP', r'[ \t]'), # Skip over spaces and tabs + ('SKIP', r'[ \t]+'), # Skip over spaces and tabs + ('MISMATCH',r'.'), # Any other character ] tok_regex = '|'.join('(?P<%s>%s)' % pair for pair in token_specification) - get_token = re.compile(tok_regex).match - line = 1 - pos = line_start = 0 - mo = get_token(s) - while mo is not None: - typ = mo.lastgroup - if typ == 'NEWLINE': - line_start = pos - line += 1 - elif typ != 'SKIP': - val = mo.group(typ) - if typ == 'ID' and val in keywords: - typ = val - yield Token(typ, val, line, mo.start()-line_start) - pos = mo.end() - mo = get_token(s, pos) - if pos != len(s): - raise RuntimeError('Unexpected character %r on line %d' %(s[pos], line)) + line_num = 1 + line_start = 0 + for mo in re.finditer(tok_regex, code): + kind = mo.lastgroup + value = mo.group(kind) + if kind == 'NEWLINE': + line_start = mo.end() + line_num += 1 + elif kind == 'SKIP': + pass + elif kind == 'MISMATCH': + raise RuntimeError('%r unexpected on line %d' % (value, line_num)) + else: + if kind == 'ID' and value in keywords: + kind = value + column = mo.start() - line_start + yield Token(kind, value, line_num, column) statements = ''' IF quantity THEN @@ -1376,22 +1435,22 @@ successive matches:: The tokenizer produces the following output:: - Token(typ='IF', value='IF', line=2, column=5) - Token(typ='ID', value='quantity', line=2, column=8) - Token(typ='THEN', value='THEN', line=2, column=17) - Token(typ='ID', value='total', line=3, column=9) - Token(typ='ASSIGN', value=':=', line=3, column=15) - Token(typ='ID', value='total', line=3, column=18) - Token(typ='OP', value='+', line=3, column=24) - Token(typ='ID', value='price', line=3, column=26) - Token(typ='OP', value='*', line=3, column=32) - Token(typ='ID', value='quantity', line=3, column=34) - Token(typ='END', value=';', line=3, column=42) - Token(typ='ID', value='tax', line=4, column=9) - Token(typ='ASSIGN', value=':=', line=4, column=13) - Token(typ='ID', value='price', line=4, column=16) - Token(typ='OP', value='*', line=4, column=22) - Token(typ='NUMBER', value='0.05', line=4, column=24) - Token(typ='END', value=';', line=4, column=28) - Token(typ='ENDIF', value='ENDIF', line=5, column=5) - Token(typ='END', value=';', line=5, column=10) + Token(typ='IF', value='IF', line=2, column=4) + Token(typ='ID', value='quantity', line=2, column=7) + Token(typ='THEN', value='THEN', line=2, column=16) + Token(typ='ID', value='total', line=3, column=8) + Token(typ='ASSIGN', value=':=', line=3, column=14) + Token(typ='ID', value='total', line=3, column=17) + Token(typ='OP', value='+', line=3, column=23) + Token(typ='ID', value='price', line=3, column=25) + Token(typ='OP', value='*', line=3, column=31) + Token(typ='ID', value='quantity', line=3, column=33) + Token(typ='END', value=';', line=3, column=41) + Token(typ='ID', value='tax', line=4, column=8) + Token(typ='ASSIGN', value=':=', line=4, column=12) + Token(typ='ID', value='price', line=4, column=15) + Token(typ='OP', value='*', line=4, column=21) + Token(typ='NUMBER', value='0.05', line=4, column=23) + Token(typ='END', value=';', line=4, column=27) + Token(typ='ENDIF', value='ENDIF', line=5, column=4) + Token(typ='END', value=';', line=5, column=9) diff --git a/Doc/library/readline.rst b/Doc/library/readline.rst index 692310b941dc..3864f0d22506 100644 --- a/Doc/library/readline.rst +++ b/Doc/library/readline.rst @@ -59,6 +59,14 @@ The :mod:`readline` module defines the following functions: Save a readline history file. The default filename is :file:`~/.history`. +.. function:: append_history_file(nelements[, filename]) + + Append the last *nelements* of history to a file. The default filename is + :file:`~/.history`. The file must already exist. + + .. versionadded:: 3.5 + + .. function:: clear_history() Clear the current history. (Note: this function is not available if the @@ -209,6 +217,26 @@ from the user's :envvar:`PYTHONSTARTUP` file. :: This code is actually automatically run when Python is run in :ref:`interactive mode <tut-interactive>` (see :ref:`rlcompleter-config`). +The following example achieves the same goal but supports concurrent interactive +sessions, by only appending the new history. :: + + import atexit + import os + import realine + histfile = os.path.join(os.path.expanduser("~"), ".python_history") + + try: + readline.read_history_file(histfile) + h_len = readline.get_history_length() + except FileNotFoundError: + open(histfile, 'wb').close() + h_len = 0 + + def save(prev_h_len, histfile): + new_h_len = readline.get_history_length() + readline.append_history_file(new_h_len - prev_h_len, histfile) + atexit.register(save, h_len, histfile) + The following example extends the :class:`code.InteractiveConsole` class to support history save/restore. :: @@ -234,4 +262,3 @@ support history save/restore. :: def save_history(self, histfile): readline.write_history_file(histfile) - diff --git a/Doc/library/reprlib.rst b/Doc/library/reprlib.rst index 24a8e529e7d9..ee9a10d37e36 100644 --- a/Doc/library/reprlib.rst +++ b/Doc/library/reprlib.rst @@ -49,8 +49,8 @@ string instead. >>> class MyList(list): ... @recursive_repr() - ... def __repr__(self): - ... return '<' + '|'.join(map(repr, self)) + '>' + ... def __repr__(self): + ... return '<' + '|'.join(map(repr, self)) + '>' ... >>> m = MyList('abc') >>> m.append(m) @@ -129,9 +129,9 @@ which format specific object types. Formatting methods for specific types are implemented as methods with a name based on the type name. In the method name, **TYPE** is replaced by - ``string.join(string.split(type(obj).__name__, '_'))``. Dispatch to these - methods is handled by :meth:`repr1`. Type-specific methods which need to - recursively format a value should call ``self.repr1(subobj, level - 1)``. + ``'_'.join(type(obj).__name__.split())``. Dispatch to these methods is + handled by :meth:`repr1`. Type-specific methods which need to recursively + format a value should call ``self.repr1(subobj, level - 1)``. .. _subclassing-reprs: @@ -148,12 +148,11 @@ for file objects could be added:: import sys class MyRepr(reprlib.Repr): - def repr_file(self, obj, level): - if obj.name in ['<stdin>', '<stdout>', '<stderr>']: + + def repr_TextIOWrapper(self, obj, level): + if obj.name in {'<stdin>', '<stdout>', '<stderr>'}: return obj.name - else: - return repr(obj) + return repr(obj) aRepr = MyRepr() print(aRepr.repr(sys.stdin)) # prints '<stdin>' - diff --git a/Doc/library/resource.rst b/Doc/library/resource.rst index 9bb5848e3a3c..7c0e4caf75ac 100644 --- a/Doc/library/resource.rst +++ b/Doc/library/resource.rst @@ -45,7 +45,7 @@ this module for those platforms. .. data:: RLIM_INFINITY - Constant used to represent the the limit for an unlimited resource. + Constant used to represent the limit for an unlimited resource. .. function:: getrlimit(resource) @@ -217,6 +217,34 @@ platform. .. versionadded:: 3.4 +.. data:: RLIMIT_SBSIZE + + The maximum size (in bytes) of socket buffer usage for this user. + This limits the amount of network memory, and hence the amount of mbufs, + that this user may hold at any time. + + Availability: FreeBSD 9 or later. + + .. versionadded:: 3.4 + +.. data:: RLIMIT_SWAP + + The maximum size (in bytes) of the swap space that may be reserved or + used by all of this user id's processes. + This limit is enforced only if bit 1 of the vm.overcommit sysctl is set. + Please see :manpage:`tuning(7)` for a complete description of this sysctl. + + Availability: FreeBSD 9 or later. + + .. versionadded:: 3.4 + +.. data:: RLIMIT_NPTS + + The maximum number of pseudo-terminals created by this user id. + + Availability: FreeBSD 9 or later. + + .. versionadded:: 3.4 Resource Usage -------------- diff --git a/Doc/library/runpy.rst b/Doc/library/runpy.rst index 6919bc0c37b7..7293f159e09a 100644 --- a/Doc/library/runpy.rst +++ b/Doc/library/runpy.rst @@ -28,6 +28,9 @@ The :mod:`runpy` module provides two functions: .. function:: run_module(mod_name, init_globals=None, run_name=None, alter_sys=False) + .. index:: + module: __main__ + Execute the code of the specified module and return the resulting module globals dictionary. The module's code is first located using the standard import mechanism (refer to :pep:`302` for details) and then executed in a @@ -44,28 +47,22 @@ The :mod:`runpy` module provides two functions: below are defined in the supplied dictionary, those definitions are overridden by :func:`run_module`. - The special global variables ``__name__``, ``__file__``, ``__cached__``, - ``__loader__`` - and ``__package__`` are set in the globals dictionary before the module - code is executed (Note that this is a minimal set of variables - other - variables may be set implicitly as an interpreter implementation detail). + The special global variables ``__name__``, ``__spec__``, ``__file__``, + ``__cached__``, ``__loader__`` and ``__package__`` are set in the globals + dictionary before the module code is executed (Note that this is a + minimal set of variables - other variables may be set implicitly as an + interpreter implementation detail). ``__name__`` is set to *run_name* if this optional argument is not :const:`None`, to ``mod_name + '.__main__'`` if the named module is a package and to the *mod_name* argument otherwise. - ``__file__`` is set to the name provided by the module loader. If the - loader does not make filename information available, this variable is set - to :const:`None`. - - ``__cached__`` will be set to ``None``. + ``__spec__`` will be set appropriately for the *actually* imported + module (that is, ``__spec__.name`` will always be *mod_name* or + ``mod_name + '.__main__``, never *run_name*). - ``__loader__`` is set to the :pep:`302` module loader used to retrieve the - code for the module (This loader may be a wrapper around the standard - import mechanism). - - ``__package__`` is set to *mod_name* if the named module is a package and - to ``mod_name.rpartition('.')[0]`` otherwise. + ``__file__``, ``__cached__``, ``__loader__`` and ``__package__`` are + :ref:`set as normal <import-mod-attrs>` based on the module spec. If the argument *alter_sys* is supplied and evaluates to :const:`True`, then ``sys.argv[0]`` is updated with the value of ``__file__`` and @@ -78,16 +75,27 @@ The :mod:`runpy` module provides two functions: arguments. It is recommended that the :mod:`sys` module be left alone when invoking this function from threaded code. + .. seealso:: + The :option:`-m` option offering equivalent functionality from the + command line. .. versionchanged:: 3.1 Added ability to execute packages by looking for a ``__main__`` submodule. .. versionchanged:: 3.2 - Added ``__cached__`` global variable (see :PEP:`3147`). + Added ``__cached__`` global variable (see :pep:`3147`). + .. versionchanged:: 3.4 + Updated to take advantage of the module spec feature added by + :pep:`451`. This allows ``__cached__`` to be set correctly for modules + run this way, as well as ensuring the real module name is always + accessible as ``__spec__.name``. .. function:: run_path(file_path, init_globals=None, run_name=None) + .. index:: + module: __main__ + Execute the code at the named filesystem location and return the resulting module globals dictionary. As with a script name supplied to the CPython command line, the supplied path may refer to a Python source file, a @@ -108,23 +116,25 @@ The :mod:`runpy` module provides two functions: below are defined in the supplied dictionary, those definitions are overridden by :func:`run_path`. - The special global variables ``__name__``, ``__file__``, ``__loader__`` - and ``__package__`` are set in the globals dictionary before the module - code is executed (Note that this is a minimal set of variables - other - variables may be set implicitly as an interpreter implementation detail). + The special global variables ``__name__``, ``__spec__``, ``__file__``, + ``__cached__``, ``__loader__`` and ``__package__`` are set in the globals + dictionary before the module code is executed (Note that this is a + minimal set of variables - other variables may be set implicitly as an + interpreter implementation detail). ``__name__`` is set to *run_name* if this optional argument is not :const:`None` and to ``'<run_path>'`` otherwise. - ``__file__`` is set to the name provided by the module loader. If the - loader does not make filename information available, this variable is set - to :const:`None`. For a simple script, this will be set to ``file_path``. + If the supplied path directly references a script file (whether as source + or as precompiled byte code), then ``__file__`` will be set to the + supplied path, and ``__spec__``, ``__cached__``, ``__loader__`` and + ``__package__`` will all be set to :const:`None`. - ``__loader__`` is set to the :pep:`302` module loader used to retrieve the - code for the module (This loader may be a wrapper around the standard - import mechanism). For a simple script, this will be set to :const:`None`. - - ``__package__`` is set to ``__name__.rpartition('.')[0]``. + If the supplied path is a reference to a valid sys.path entry, then + ``__spec__`` will be set appropriately for the imported ``__main__`` + module (that is, ``__spec__.name`` will always be ``__main__``). + ``__file__``, ``__cached__``, ``__loader__`` and ``__package__`` will be + :ref:`set as normal <import-mod-attrs>` based on the module spec. A number of alterations are also made to the :mod:`sys` module. Firstly, ``sys.path`` may be altered as described above. ``sys.argv[0]`` is updated @@ -139,16 +149,29 @@ The :mod:`runpy` module provides two functions: limitations still apply, use of this function in threaded code should be either serialised with the import lock or delegated to a separate process. + .. seealso:: + :ref:`using-on-interface-options` for equivalent functionality on the + command line (``python path/to/script``). + .. versionadded:: 3.2 + .. versionchanged:: 3.4 + Updated to take advantage of the module spec feature added by + :pep:`451`. This allows ``__cached__`` to be set correctly in the + case where ``__main__`` is imported from a valid sys.path entry rather + than being executed directly. + .. seealso:: - :pep:`338` - Executing modules as scripts + :pep:`338` -- Executing modules as scripts PEP written and implemented by Nick Coghlan. - :pep:`366` - Main module explicit relative imports + :pep:`366` -- Main module explicit relative imports PEP written and implemented by Nick Coghlan. + :pep:`451` -- A ModuleSpec Type for the Import System + PEP written and implemented by Eric Snow + :ref:`using-on-general` - CPython command line details The :func:`importlib.import_module` function diff --git a/Doc/library/select.rst b/Doc/library/select.rst index 524e411f2cc3..5334af8ea4ae 100644 --- a/Doc/library/select.rst +++ b/Doc/library/select.rst @@ -58,9 +58,14 @@ The module defines the following: which can be used as Edge or Level Triggered interface for I/O events. *sizehint* is deprecated and completely ignored. *flags* can be set to :const:`EPOLL_CLOEXEC`, which causes the epoll descriptor to be closed - automatically when :func:`os.execve` is called. See section - :ref:`epoll-objects` below for the methods supported by epolling objects. - They also support the :keyword:`with` statement. + automatically when :func:`os.execve` is called. + + See the :ref:`epoll-objects` section below for the methods supported by + epolling objects. + + ``epoll`` objects support the context management protocol: when used in a + :keyword:`with` statement, the new file descriptor is automatically closed + at the end of the block. The new file descriptor is :ref:`non-inheritable <fd_inheritance>`. @@ -155,10 +160,7 @@ The module defines the following: .. _devpoll-objects: ``/dev/poll`` Polling Objects ----------------------------------------------- - - http://developers.sun.com/solaris/articles/using_devpoll.html - http://developers.sun.com/solaris/articles/polling_efficient.html +----------------------------- Solaris and derivatives have ``/dev/poll``. While :c:func:`select` is O(highest file descriptor) and :c:func:`poll` is O(number of file @@ -205,7 +207,7 @@ object. .. warning:: Registering a file descriptor that's already registered is not an - error, but the result is undefined. The appropiate action is to + error, but the result is undefined. The appropriate action is to unregister or modify it first. This is an important difference compared with :c:func:`poll`. @@ -308,7 +310,7 @@ Edge and Level Trigger Polling (epoll) Objects .. method:: epoll.modify(fd, eventmask) - Modify a register file descriptor. + Modify a registered file descriptor. .. method:: epoll.unregister(fd) @@ -372,7 +374,7 @@ linearly scanned again. :c:func:`select` is O(highest file descriptor), while Modifies an already registered fd. This has the same effect as ``register(fd, eventmask)``. Attempting to modify a file descriptor - that was never registered causes an :exc:`IOError` exception with errno + that was never registered causes an :exc:`OSError` exception with errno :const:`ENOENT` to be raised. diff --git a/Doc/library/selectors.rst b/Doc/library/selectors.rst index b0b002f0e182..8bd9e1ce2e2d 100644 --- a/Doc/library/selectors.rst +++ b/Doc/library/selectors.rst @@ -45,6 +45,7 @@ Classes hierarchy:: +-- SelectSelector +-- PollSelector +-- EpollSelector + +-- DevpollSelector +-- KqueueSelector @@ -102,7 +103,8 @@ below: Register a file object for selection, monitoring it for I/O events. - *fileobj* is the file object to monitor. + *fileobj* is the file object to monitor. It may either be an integer + file descriptor or an object with a ``fileno()`` method. *events* is a bitwise mask of events to monitor. *data* is an opaque object. @@ -118,7 +120,9 @@ below: *fileobj* must be a file object previously registered. This returns the associated :class:`SelectorKey` instance, or raises a - :exc:`KeyError` if the file object is not registered. + :exc:`KeyError` if *fileobj* is not registered. It will raise + :exc:`ValueError` if *fileobj* is invalid (e.g. it has no ``fileno()`` + method or its ``fileno()`` method has an invalid return value). .. method:: modify(fileobj, events, data=None) @@ -204,6 +208,16 @@ below: This returns the file descriptor used by the underlying :func:`select.epoll` object. +.. class:: DevpollSelector() + + :func:`select.devpoll`-based selector. + + .. method:: fileno() + + This returns the file descriptor used by the underlying + :func:`select.devpoll` object. + + .. versionadded:: 3.5 .. class:: KqueueSelector() diff --git a/Doc/library/shelve.rst b/Doc/library/shelve.rst index 4ba9ddc47705..22e202dace1a 100644 --- a/Doc/library/shelve.rst +++ b/Doc/library/shelve.rst @@ -121,7 +121,8 @@ Restrictions The *keyencoding* parameter is the encoding used to encode keys before they are used with the underlying dict. - :class:`Shelf` objects can also be used as context managers. + A :class:`Shelf` object can also be used as a context manager, in which + case it will be automatically closed when the :keyword:`with` block ends. .. versionchanged:: 3.2 Added the *keyencoding* parameter; previously, keys were always encoded in diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst index e4f348cd82ce..82974ade2261 100644 --- a/Doc/library/shutil.rst +++ b/Doc/library/shutil.rst @@ -191,7 +191,8 @@ Directory and files operations match one of the glob-style *patterns* provided. See the example below. -.. function:: copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, ignore_dangling_symlinks=False) +.. function:: copytree(src, dst, symlinks=False, ignore=None, \ + copy_function=copy2, ignore_dangling_symlinks=False) Recursively copy an entire directory tree rooted at *src*, returning the destination directory. The destination @@ -282,7 +283,7 @@ Directory and files operations .. versionadded:: 3.3 -.. function:: move(src, dst) +.. function:: move(src, dst, copy_function=copy2) Recursively move a file or directory (*src*) to another location (*dst*) and return the destination. @@ -295,15 +296,26 @@ Directory and files operations :func:`os.rename` semantics. If the destination is on the current filesystem, then :func:`os.rename` is - used. Otherwise, *src* is copied (using :func:`shutil.copy2`) to *dst* and - then removed. In case of symlinks, a new symlink pointing to the target of - *src* will be created in or as *dst* and *src* will be removed. + used. Otherwise, *src* is copied to *dst* using *copy_function* and then + removed. In case of symlinks, a new symlink pointing to the target of *src* + will be created in or as *dst* and *src* will be removed. + + If *copy_function* is given, it must be a callable that takes two arguments + *src* and *dst*, and will be used to copy *src* to *dest* if + :func:`os.rename` cannot be used. If the source is a directory, + :func:`copytree` is called, passing it the :func:`copy_function`. The + default *copy_function* is :func:`copy2`. Using :func:`copy` as the + *copy_function* allows the move to succeed when it is not possible to also + copy the metadata, at the expense of not copying any of the metadata. .. versionchanged:: 3.3 Added explicit symlink handling for foreign filesystems, thus adapting it to the behavior of GNU's :program:`mv`. Now returns *dst*. + .. versionchanged:: 3.5 + Added the *copy_function* keyword argument. + .. function:: disk_usage(path) Return disk usage statistics about the given path as a :term:`named tuple` @@ -341,7 +353,7 @@ Directory and files operations On Windows, the current directory is always prepended to the *path* whether or not you use the default or provide your own, which is the behavior the - command shell uses when finding executables. Additionaly, when finding the + command shell uses when finding executables. Additionally, when finding the *cmd* in the *path*, the ``PATHEXT`` environment variable is checked. For example, if you call ``shutil.which("python")``, :func:`which` will search ``PATHEXT`` to know that it should look for ``python.exe`` within the *path* @@ -421,6 +433,26 @@ Another example that uses the *ignore* argument to add a logging call:: copytree(source, destination, ignore=_logpath) +.. _shutil-rmtree-example: + +rmtree example +~~~~~~~~~~~~~~ + +This example shows how to remove a directory tree on Windows where some +of the files have their read-only bit set. It uses the onerror callback +to clear the readonly bit and reattempt the remove. Any subsequent failure +will propagate. :: + + import os, stat + import shutil + + def remove_readonly(func, path, _): + "Clear the readonly bit and reattempt the removal" + os.chmod(path, stat.S_IWRITE) + func(path) + + shutil.rmtree(directory, onerror=remove_readonly) + .. _archiving-operations: Archiving operations @@ -437,7 +469,8 @@ 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) or "gztar". + "zip", "tar", "bztar" (if the :mod:`bz2` module is available), "xztar" + (if the :mod:`lzma` module is available) or "gztar". *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 @@ -449,12 +482,20 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules. *root_dir* and *base_dir* both default to the current directory. + If *dry_run* is true, no archive is created, but the operations that would be + executed are logged to *logger*. + *owner* and *group* are used when creating a tar archive. By default, uses the current owner and group. *logger* must be an object compatible with :pep:`282`, usually an instance of :class:`logging.Logger`. + The *verbose* argument is unused and deprecated. + + .. versionchanged:: 3.5 + Added support for the *xztar* format. + .. function:: get_archive_formats() @@ -465,6 +506,7 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules. - *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 @@ -474,14 +516,19 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules. .. function:: register_archive_format(name, function, [extra_args, [description]]) - Register an archiver for the format *name*. *function* is a callable that - will be used to invoke the archiver. + Register an archiver for the format *name*. + + *function* is the callable that will be used to unpack archives. The callable + will receive the *base_name* of the file to create, followed by the + *base_dir* (which defaults to :data:`os.curdir`) to start archiving from. + Further arguments are passed as keyword arguments: *owner*, *group*, + *dry_run* and *logger* (as passed in :func:`make_archive`). If given, *extra_args* is a sequence of ``(name, value)`` pairs that will be used as extra keywords arguments when the archiver callable is used. *description* is used by :func:`get_archive_formats` which returns the - list of archivers. Defaults to an empty list. + list of archivers. Defaults to an empty string. .. function:: unregister_archive_format(name) @@ -535,6 +582,7 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules. - *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 diff --git a/Doc/library/signal.rst b/Doc/library/signal.rst index 84e283683d07..ed616b2e95e9 100644 --- a/Doc/library/signal.rst +++ b/Doc/library/signal.rst @@ -65,6 +65,16 @@ Besides, only the main thread is allowed to set a new signal handler. Module contents --------------- +.. versionchanged:: 3.5 + signal (SIG*), handler (:const:`SIG_DFL`, :const:`SIG_IGN`) and sigmask + (:const:`SIG_BLOCK`, :const:`SIG_UNBLOCK`, :const:`SIG_SETMASK`) + related constants listed below were turned into + :class:`enums <enum.IntEnum>`. + :func:`getsignal`, :func:`pthread_sigmask`, :func:`sigpending` and + :func:`sigwait` functions return human-readable + :class:`enums <enum.IntEnum>`. + + The variables defined in the :mod:`signal` module are: @@ -308,6 +318,9 @@ The :mod:`signal` module defines the following functions: attempting to call it from other threads will cause a :exc:`ValueError` exception to be raised. + .. versionchanged:: 3.5 + On Windows, the function now also supports socket handles. + .. function:: siginterrupt(signalnum, flag) diff --git a/Doc/library/site.rst b/Doc/library/site.rst index d93e938b5c90..43daf790b77c 100644 --- a/Doc/library/site.rst +++ b/Doc/library/site.rst @@ -26,24 +26,23 @@ additions, call the :func:`site.main` function. :option:`-S`. .. index:: - pair: site-python; directory pair: site-packages; directory It starts by constructing up to four directories from a head and a tail part. For the head part, it uses ``sys.prefix`` and ``sys.exec_prefix``; empty heads are skipped. For the tail part, it uses the empty string and then :file:`lib/site-packages` (on Windows) or -:file:`lib/python{X.Y}/site-packages` and then :file:`lib/site-python` (on -Unix and Macintosh). For each of the distinct head-tail combinations, it sees -if it refers to an existing directory, and if so, adds it to ``sys.path`` and -also inspects the newly added path for configuration files. +:file:`lib/python{X.Y}/site-packages` (on Unix and Macintosh). For each +of the distinct head-tail combinations, it sees if it refers to an existing +directory, and if so, adds it to ``sys.path`` and also inspects the newly +added path for configuration files. -.. deprecated:: 3.4 - Support for the "site-python" directory will be removed in 3.5. +.. versionchanged:: 3.5 + Support for the "site-python" directory has been removed. If a file named "pyvenv.cfg" exists one directory above sys.executable, sys.prefix and sys.exec_prefix are set to that directory and -it is also checked for site-packages and site-python (sys.base_prefix and +it is also checked for site-packages (sys.base_prefix and sys.base_exec_prefix will always be the "real" prefixes of the Python installation). If "pyvenv.cfg" (a bootstrap configuration file) contains the key "include-system-site-packages" set to anything other than "false" @@ -99,7 +98,11 @@ After these path manipulations, an attempt is made to import a module named :mod:`sitecustomize`, which can perform arbitrary site-specific customizations. It is typically created by a system administrator in the site-packages directory. If this import fails with an :exc:`ImportError` exception, it is -silently ignored. +silently ignored. If Python is started without output streams available, as +with :file:`pythonw.exe` on Windows (which is used by default to start IDLE), +attempted output from :mod:`sitecustomize` is ignored. Any exception other +than :exc:`ImportError` causes a silent and perhaps mysterious failure of the +process. .. index:: module: usercustomize @@ -123,9 +126,13 @@ On systems that support :mod:`readline`, this module will also import and configure the :mod:`rlcompleter` module, if Python is started in :ref:`interactive mode <tut-interactive>` and without the :option:`-S` option. The default behavior is enable tab-completion and to use -:file:`~/.python_history` as the history save file. To disable it, override -the :data:`sys.__interactivehook__` attribute in your :mod:`sitecustomize` -or :mod:`usercustomize` module or your :envvar:`PYTHONSTARTUP` file. +:file:`~/.python_history` as the history save file. To disable it, delete (or +override) the :data:`sys.__interactivehook__` attribute in your +:mod:`sitecustomize` or :mod:`usercustomize` module or your +:envvar:`PYTHONSTARTUP` file. + +.. versionchanged:: 3.4 + Activation of rlcompleter and history was made automatic. Module contents @@ -176,7 +183,7 @@ Module contents unless the Python interpreter was started with the :option:`-S` flag. .. versionchanged:: 3.3 - This function used to be called unconditionnally. + This function used to be called unconditionally. .. function:: addsitedir(sitedir, known_paths=None) @@ -187,8 +194,7 @@ Module contents .. function:: getsitepackages() - Return a list containing all global site-packages directories (and possibly - site-python). + Return a list containing all global site-packages directories. .. versionadded:: 3.2 diff --git a/Doc/library/smtpd.rst b/Doc/library/smtpd.rst index 3ebed0626094..3e0c6fbff515 100644 --- a/Doc/library/smtpd.rst +++ b/Doc/library/smtpd.rst @@ -20,7 +20,8 @@ specific mail-sending strategies. Additionally the SMTPChannel may be extended to implement very specific interaction behaviour with SMTP clients. -The code supports :RFC:`5321`, plus the :rfc:`1870` SIZE extension. +The code supports :RFC:`5321`, plus the :rfc:`1870` SIZE and :rfc:`6531` +SMTPUTF8 extensions. SMTPServer Objects @@ -28,7 +29,7 @@ SMTPServer Objects .. class:: SMTPServer(localaddr, remoteaddr, data_size_limit=33554432,\ - map=None) + map=None, enable_SMTPUTF8=False, decode_data=True) Create a new :class:`SMTPServer` object, which binds to local address *localaddr*. It will treat *remoteaddr* as an upstream SMTP relayer. It @@ -39,18 +40,47 @@ SMTPServer Objects accepted in a ``DATA`` command. A value of ``None`` or ``0`` means no limit. + *enable_SMTPUTF8* determins whether the ``SMTPUTF8`` extension (as defined + in :RFC:`6531`) should be enabled. The default is ``False``. If + *enable_SMTPUTF* is set to ``True``, the :meth:`process_smtputf8_message` + method must be defined. A :exc:`ValueError` is raised if both + *enable_SMTPUTF8* and *decode_data* are set to ``True`` at the same time. + A dictionary can be specified in *map* to avoid using a global socket map. + *decode_data* specifies whether the data portion of the SMTP transaction + should be decoded using UTF-8. The default is ``True`` for backward + compatibility reasons, but will change to ``False`` in Python 3.6. Specify + the keyword value explicitly to avoid the :exc:`DeprecationWarning`. + .. method:: process_message(peer, mailfrom, rcpttos, data) - Raise :exc:`NotImplementedError` exception. Override this in subclasses to + Raise a :exc:`NotImplementedError` exception. Override this in subclasses to do something useful with this message. Whatever was passed in the constructor as *remoteaddr* will be available as the :attr:`_remoteaddr` attribute. *peer* is the remote host's address, *mailfrom* is the envelope originator, *rcpttos* are the envelope recipients and *data* is a string - containing the contents of the e-mail (which should be in :rfc:`2822` + containing the contents of the e-mail (which should be in :rfc:`5321` format). + If the *decode_data* constructor keyword is set to ``True``, the *data* + argument will be a unicode string. If it is set to ``False``, it + will be a bytes object. + + Return ``None`` to request a normal ``250 Ok`` response; otherwise + return the desired response string in :RFC:`5321` format. + + .. method:: process_smtputf8_message(peer, mailfrom, rcpttos, data) + + Raise a :exc:`NotImplementedError` exception. Override this in + subclasses to do something useful with messages when *enable_SMTPUTF8* + has been set to ``True`` and the SMTP client requested ``SMTPUTF8``, + since this method is called rather than :meth:`process_message` when the + client actively requests ``SMTPUTF8``. The *data* argument will always + be a bytes object, and any non-``None`` return value should conform to + :rfc:`6531`; otherwise, the API is the same as for + :meth:`process_message`. + .. attribute:: channel_class Override this in subclasses to use a custom :class:`SMTPChannel` for @@ -59,6 +89,13 @@ SMTPServer Objects .. versionchanged:: 3.4 The *map* argument was added. + .. versionchanged:: 3.5 + *localaddr* and *remoteaddr* may now contain IPv6 addresses. + + .. versionadded:: 3.5 + the *decode_data* and *enable_SMTPUTF8* constructor arguments, and the + :meth:`process_smtputf8_message` method. + DebuggingServer Objects ----------------------- @@ -97,7 +134,7 @@ SMTPChannel Objects ------------------- .. class:: SMTPChannel(server, conn, addr, data_size_limit=33554432,\ - map=None)) + map=None, enable_SMTPUTF8=False, decode_data=True) Create a new :class:`SMTPChannel` object which manages the communication between the server and a single SMTP client. @@ -108,11 +145,24 @@ SMTPChannel Objects accepted in a ``DATA`` command. A value of ``None`` or ``0`` means no limit. + *enable_SMTPUTF8* determins whether the ``SMTPUTF8`` extension (as defined + in :RFC:`6531`) should be enabled. The default is ``False``. A + :exc:`ValueError` is raised if both *enable_SMTPUTF8* and *decode_data* are + set to ``True`` at the same time. + A dictionary can be specified in *map* to avoid using a global socket map. + *decode_data* specifies whether the data portion of the SMTP transaction + should be decoded using UTF-8. The default is ``True`` for backward + compatibility reasons, but will change to ``False`` in Python 3.6. Specify + the keyword value explicitly to avoid the :exc:`DeprecationWarning`. + To use a custom SMTPChannel implementation you need to override the :attr:`SMTPServer.channel_class` of your :class:`SMTPServer`. + .. versionchanged:: 3.5 + the *decode_data* and *enable_SMTPUTF8* arguments were added. + The :class:`SMTPChannel` has the following instance variables: .. attribute:: smtp_server diff --git a/Doc/library/smtplib.rst b/Doc/library/smtplib.rst index a7d15384d09c..74de77b94edd 100644 --- a/Doc/library/smtplib.rst +++ b/Doc/library/smtplib.rst @@ -32,7 +32,8 @@ Protocol) and :rfc:`1869` (SMTP Service Extensions). than a success code, an :exc:`SMTPConnectError` is raised. The optional *timeout* parameter specifies a timeout in seconds for blocking operations like the connection attempt (if not specified, the global default timeout - setting will be used). The optional source_address parameter allows to bind + setting will be used). If the timeout expires, :exc:`socket.timeout` is + raised. The optional source_address parameter allows to bind to some specific source address in a machine with multiple network interfaces, and/or to some specific source TCP port. It takes a 2-tuple (host, port), for the socket to bind to as its source address before @@ -69,20 +70,15 @@ Protocol) and :rfc:`1869` (SMTP Service Extensions). required from the beginning of the connection and using :meth:`starttls` is not appropriate. If *host* is not specified, the local host is used. If *port* is zero, the standard SMTP-over-SSL port (465) is used. The optional - arguments *local_hostname* and *source_address* have the same meaning as - they do in the :class:`SMTP` class. *keyfile* and *certfile* are also - optional, and can contain a PEM formatted private key and certificate chain - file for the SSL connection. *context* also optional, can contain a - SSLContext, and is an alternative to keyfile and certfile; If it is - specified both keyfile and certfile must be None. The optional *timeout* - parameter specifies a timeout in seconds for blocking operations like the - connection attempt (if not specified, the global default timeout setting - will be used). The optional source_address parameter allows to bind to some - specific source address in a machine with multiple network interfaces, - and/or to some specific source tcp port. It takes a 2-tuple (host, port), - for the socket to bind to as its source address before connecting. If - omitted (or if host or port are ``''`` and/or 0 respectively) the OS default - behavior will be used. + arguments *local_hostname*, *timeout* and *source_address* have the same + meaning as they do in the :class:`SMTP` class. *context*, also optional, + can contain a :class:`~ssl.SSLContext` and allows to configure various + aspects of the secure connection. Please read :ref:`ssl-security` for + best practices. + + *keyfile* and *certfile* are a legacy alternative to *context*, and can + point to a PEM formatted private key and certificate chain file for the + SSL connection. .. versionchanged:: 3.3 *context* was added. @@ -90,6 +86,10 @@ Protocol) and :rfc:`1869` (SMTP Service Extensions). .. versionchanged:: 3.3 source_address argument was added. + .. versionchanged:: 3.4 + The class now supports hostname check with + :attr:`ssl.SSLContext.check_hostname` and *Server Name Indication* (see + :data:`ssl.HAS_SNI`). .. class:: LMTP(host='', port=LMTP_PORT, local_hostname=None, source_address=None) @@ -113,6 +113,9 @@ A nice selection of exceptions is defined as well: Subclass of :exc:`OSError` that is the base exception class for all the other exceptions provided by this module. + .. versionchanged:: 3.4 + SMTPException became subclass of :exc:`OSError` + .. exception:: SMTPServerDisconnected @@ -237,8 +240,7 @@ An :class:`SMTP` instance has the following methods: the server is stored as the :attr:`ehlo_resp` attribute, :attr:`does_esmtp` is set to true or false depending on whether the server supports ESMTP, and :attr:`esmtp_features` will be a dictionary containing the names of the - SMTP service extensions this server supports, and their - parameters (if any). + SMTP service extensions this server supports, and their parameters (if any). Unless you wish to use :meth:`has_extn` before sending mail, it should not be necessary to call this method explicitly. It will be implicitly called by @@ -288,6 +290,42 @@ An :class:`SMTP` instance has the following methods: :exc:`SMTPException` No suitable authentication method was found. + Each of the authentication methods supported by :mod:`smtplib` are tried in + turn if they are advertised as supported by the server (see :meth:`auth` + for a list of supported authentication methods). + + +.. method:: SMTP.auth(mechanism, authobject) + + Issue an ``SMTP`` ``AUTH`` command for the specified authentication + *mechanism*, and handle the challenge response via *authobject*. + + *mechanism* specifies which authentication mechanism is to + be used as argument to the ``AUTH`` command; the valid values are + those listed in the ``auth`` element of :attr:`esmtp_features`. + + *authobject* must be a callable object taking a single argument: + + data = authobject(challenge) + + It will be called to process the server's challenge response; the + *challenge* argument it is passed will be a ``bytes``. It should return + ``bytes`` *data* that will be base64 encoded and sent to the server. + + The ``SMTP`` class provides ``authobjects`` for the ``CRAM-MD5``, ``PLAIN``, + and ``LOGIN`` mechanisms; they are named ``SMTP.auth_cram_md5``, + ``SMTP.auth_plain``, and ``SMTP.auth_login`` respectively. They all require + that the ``user`` and ``password`` properties of the ``SMTP`` instance are + set to appropriate values. + + User code does not normally need to call ``auth`` directly, but can instead + call the :meth:`login` method, which will try each of the above mechanisms in + turn, in the order listed. ``auth`` is exposed to facilitate the + implementation of authentication methods not (or not yet) supported directly + by :mod:`smtplib`. + + .. versionadded:: 3.5 + .. method:: SMTP.starttls(keyfile=None, certfile=None, context=None) @@ -316,6 +354,11 @@ An :class:`SMTP` instance has the following methods: .. versionchanged:: 3.3 *context* was added. + .. versionchanged:: 3.4 + The method now supports hostname check with + :attr:`SSLContext.check_hostname` and *Server Name Indicator* (see + :data:`~ssl.HAS_SNI`). + .. method:: SMTP.sendmail(from_addr, to_addrs, msg, mail_options=[], rcpt_options=[]) diff --git a/Doc/library/sndhdr.rst b/Doc/library/sndhdr.rst index f36df6870347..f8b5d8b2460c 100644 --- a/Doc/library/sndhdr.rst +++ b/Doc/library/sndhdr.rst @@ -16,8 +16,9 @@ The :mod:`sndhdr` provides utility functions which attempt to determine the type of sound data which is in a file. When these functions are able to determine -what type of sound data is stored in a file, they return a tuple ``(type, -sampling_rate, channels, frames, bits_per_sample)``. The value for *type* +what type of sound data is stored in a file, they return a +:func:`~collections.namedtuple`, containing five attributes: (``filetype``, +``framerate``, ``nchannels``, ``nframes``, ``sampwidth``). The value for *type* indicates the data type and will be one of the strings ``'aifc'``, ``'aiff'``, ``'au'``, ``'hcom'``, ``'sndr'``, ``'sndt'``, ``'voc'``, ``'wav'``, ``'8svx'``, ``'sb'``, ``'ub'``, or ``'ul'``. The *sampling_rate* will be either the actual @@ -31,13 +32,19 @@ be the sample size in bits or ``'A'`` for A-LAW or ``'U'`` for u-LAW. .. function:: what(filename) Determines the type of sound data stored in the file *filename* using - :func:`whathdr`. If it succeeds, returns a tuple as described above, otherwise + :func:`whathdr`. If it succeeds, returns a namedtuple as described above, otherwise ``None`` is returned. + .. versionchanged:: 3.5 + Result changed from a tuple to a namedtuple. + .. function:: whathdr(filename) Determines the type of sound data stored in a file based on the file header. - The name of the file is given by *filename*. This function returns a tuple as + The name of the file is given by *filename*. This function returns a namedtuple as described above on success, or ``None``. + .. versionchanged:: 3.5 + Result changed from a tuple to a namedtuple. + diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index b01238c29dd4..e330f0add1b2 100644 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -6,8 +6,7 @@ This module provides access to the BSD *socket* interface. It is available on -all modern Unix systems, Windows, MacOS, OS/2, and probably additional -platforms. +all modern Unix systems, Windows, MacOS, and probably additional platforms. .. note:: @@ -91,9 +90,6 @@ created. Socket addresses are represented as follows: If *addr_type* is :const:`TIPC_ADDR_ID`, then *v1* is the node, *v2* is the reference, and *v3* should be set to 0. - If *addr_type* is :const:`TIPC_ADDR_ID`, then *v1* is the node, *v2* is the - reference, and *v3* should be set to 0. - - A tuple ``(interface, )`` is used for the :const:`AF_CAN` address family, where *interface* is a string representing a network interface name like ``'can0'``. The network interface name ``''`` can be used to receive packets @@ -138,9 +134,12 @@ generalization of this based on timeouts is supported through Module contents --------------- -The module :mod:`socket` exports the following constants and functions: +The module :mod:`socket` exports the following elements. +Exceptions +^^^^^^^^^^ + .. exception:: error A deprecated alias of :exc:`OSError`. @@ -186,6 +185,15 @@ The module :mod:`socket` exports the following constants and functions: .. versionchanged:: 3.3 This class was made a subclass of :exc:`OSError`. + +Constants +^^^^^^^^^ + + The AF_* and SOCK_* constants are now :class:`AddressFamily` and + :class:`SocketKind` :class:`.IntEnum` collections. + + .. versionadded:: 3.4 + .. data:: AF_UNIX AF_INET AF_INET6 @@ -305,6 +313,59 @@ The module :mod:`socket` exports the following constants and functions: this platform. +Functions +^^^^^^^^^ + +Creating sockets +'''''''''''''''' + +The following functions all create :ref:`socket objects <socket-objects>`. + + +.. function:: socket(family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None) + + Create a new socket using the given address family, socket type and protocol + number. The address family should be :const:`AF_INET` (the default), + :const:`AF_INET6`, :const:`AF_UNIX`, :const:`AF_CAN` or :const:`AF_RDS`. The + socket type should be :const:`SOCK_STREAM` (the default), + :const:`SOCK_DGRAM`, :const:`SOCK_RAW` or perhaps one of the other ``SOCK_`` + constants. The protocol number is usually zero and may be omitted or in the + case where the address family is :const:`AF_CAN` the protocol should be one + of :const:`CAN_RAW` or :const:`CAN_BCM`. + + The newly created socket is :ref:`non-inheritable <fd_inheritance>`. + + .. versionchanged:: 3.3 + The AF_CAN family was added. + The AF_RDS family was added. + + .. versionchanged:: 3.4 + The CAN_BCM protocol was added. + + .. versionchanged:: 3.4 + The returned socket is now non-inheritable. + + +.. function:: socketpair([family[, type[, proto]]]) + + Build a pair of connected socket objects using the given address family, socket + type, and protocol number. Address family, socket type, and protocol number are + as for the :func:`.socket` function above. The default family is :const:`AF_UNIX` + if defined on the platform; otherwise, the default is :const:`AF_INET`. + + The newly created sockets are :ref:`non-inheritable <fd_inheritance>`. + + .. versionchanged:: 3.2 + The returned socket objects now support the whole socket API, rather + than a subset. + + .. versionchanged:: 3.4 + The returned sockets are now non-inheritable. + + .. versionchanged:: 3.5 + Windows support added. + + .. function:: create_connection(address[, timeout[, source_address]]) Connect to a TCP service listening on the Internet *address* (a 2-tuple @@ -331,6 +392,45 @@ The module :mod:`socket` exports the following constants and functions: support for the :keyword:`with` statement was added. +.. function:: fromfd(fd, family, type, proto=0) + + Duplicate the file descriptor *fd* (an integer as returned by a file object's + :meth:`fileno` method) and build a socket object from the result. Address + family, socket type and protocol number are as for the :func:`.socket` function + above. The file descriptor should refer to a socket, but this is not checked --- + subsequent operations on the object may fail if the file descriptor is invalid. + This function is rarely needed, but can be used to get or set socket options on + a socket passed to a program as standard input or output (such as a server + started by the Unix inet daemon). The socket is assumed to be in blocking mode. + + The newly created socket is :ref:`non-inheritable <fd_inheritance>`. + + .. versionchanged:: 3.4 + The returned socket is now non-inheritable. + + +.. function:: fromshare(data) + + Instantiate a socket from data obtained from the :meth:`socket.share` + method. The socket is assumed to be in blocking mode. + + Availability: Windows. + + .. versionadded:: 3.3 + + +.. data:: SocketType + + This is a Python type object that represents the socket object type. It is the + same as ``type(socket(...))``. + + +Other functions +''''''''''''''' + +The :mod:`socket` module also offers various network-related services: + + .. function:: getaddrinfo(host, port, family=0, type=0, proto=0, flags=0) Translate the *host*/*port* argument into a sequence of 5-tuples that contain @@ -366,12 +466,12 @@ The module :mod:`socket` exports the following constants and functions: connection to ``www.python.org`` on port 80 (results may differ on your system if IPv6 isn't enabled):: - >>> socket.getaddrinfo("www.python.org", 80, proto=socket.SOL_TCP) + >>> socket.getaddrinfo("www.python.org", 80, proto=socket.IPPROTO_TCP) [(2, 1, 6, '', ('82.94.164.162', 80)), (10, 1, 6, '', ('2001:888:2000:d::a2', 80, 0, 0))] .. versionchanged:: 3.2 - parameters can now be passed as single keyword arguments. + parameters can now be passed using keyword arguments. .. function:: getfqdn([name]) @@ -460,65 +560,6 @@ The module :mod:`socket` exports the following constants and functions: ``'udp'``, otherwise any protocol will match. -.. function:: socket(family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None) - - Create a new socket using the given address family, socket type and protocol - number. The address family should be :const:`AF_INET` (the default), - :const:`AF_INET6`, :const:`AF_UNIX`, :const:`AF_CAN` or :const:`AF_RDS`. The - socket type should be :const:`SOCK_STREAM` (the default), - :const:`SOCK_DGRAM`, :const:`SOCK_RAW` or perhaps one of the other ``SOCK_`` - constants. The protocol number is usually zero and may be omitted or in the - case where the address family is :const:`AF_CAN` the protocol should be one - of :const:`CAN_RAW` or :const:`CAN_BCM`. - - The newly created socket is :ref:`non-inheritable <fd_inheritance>`. - - .. versionchanged:: 3.3 - The AF_CAN family was added. - The AF_RDS family was added. - - .. versionchanged:: 3.4 - The CAN_BCM protocol was added. - - .. versionchanged:: 3.4 - The socket is now non-inheritable. - - -.. function:: socketpair([family[, type[, proto]]]) - - Build a pair of connected socket objects using the given address family, socket - type, and protocol number. Address family, socket type, and protocol number are - as for the :func:`.socket` function above. The default family is :const:`AF_UNIX` - if defined on the platform; otherwise, the default is :const:`AF_INET`. - Availability: Unix. - - The newly created sockets are :ref:`non-inheritable <fd_inheritance>`. - - .. versionchanged:: 3.2 - The returned socket objects now support the whole socket API, rather - than a subset. - - .. versionchanged:: 3.4 - The sockets are now non-inheritable. - - -.. function:: fromfd(fd, family, type, proto=0) - - Duplicate the file descriptor *fd* (an integer as returned by a file object's - :meth:`fileno` method) and build a socket object from the result. Address - family, socket type and protocol number are as for the :func:`.socket` function - above. The file descriptor should refer to a socket, but this is not checked --- - subsequent operations on the object may fail if the file descriptor is invalid. - This function is rarely needed, but can be used to get or set socket options on - a socket passed to a program as standard input or output (such as a server - started by the Unix inet daemon). The socket is assumed to be in blocking mode. - - The newly created socket is :ref:`non-inheritable <fd_inheritance>`. - - .. versionchanged:: 3.4 - The socket is now non-inheritable. - - .. function:: ntohl(x) Convert 32-bit positive integers from network to host byte order. On machines @@ -596,6 +637,9 @@ The module :mod:`socket` exports the following constants and functions: Availability: Unix (maybe not all platforms), Windows. + .. versionchanged:: 3.4 + Windows support added + .. function:: inet_ntop(address_family, packed_ip) @@ -612,6 +656,9 @@ The module :mod:`socket` exports the following constants and functions: Availability: Unix (maybe not all platforms), Windows. + .. versionchanged:: 3.4 + Windows support added + .. XXX: Are sendmsg(), recvmsg() and CMSG_*() available on any @@ -714,29 +761,14 @@ The module :mod:`socket` exports the following constants and functions: .. versionadded:: 3.3 -.. function:: fromshare(data) - - Instantiate a socket from data obtained from :meth:`~socket.share`. - The socket is assumed to be in blocking mode. - - Availability: Windows. - - .. versionadded:: 3.3 - - -.. data:: SocketType - - This is a Python type object that represents the socket object type. It is the - same as ``type(socket(...))``. - - .. _socket-objects: Socket Objects -------------- -Socket objects have the following methods. Except for :meth:`makefile` these -correspond to Unix system calls applicable to sockets. +Socket objects have the following methods. Except for +:meth:`~socket.makefile`, these correspond to Unix system calls applicable +to sockets. .. method:: socket.accept() @@ -760,11 +792,18 @@ correspond to Unix system calls applicable to sockets. .. method:: socket.close() - Close the socket. All future operations on the socket object will fail. The - remote end will receive no more data (after queued data is flushed). Sockets are - automatically closed when they are garbage-collected. + Mark the socket closed. The underlying system resource (e.g. a file + descriptor) is also closed when all file objects from :meth:`makefile()` + are closed. Once that happens, all future operations on the socket + object will fail. The remote end will receive no more data (after + queued data is flushed). + + Sockets are automatically closed when they are garbage-collected, but + it is recommended to :meth:`close` them explicitly, or to use a + :keyword:`with` statement around them. .. note:: + :meth:`close()` releases the resource associated with a connection but does not necessarily close the connection immediately. If you want to close the connection in a timely fashion, call :meth:`shutdown()` @@ -871,12 +910,15 @@ correspond to Unix system calls applicable to sockets. On other platforms, the generic :func:`fcntl.fcntl` and :func:`fcntl.ioctl` functions may be used; they accept a socket object as their first argument. -.. method:: socket.listen(backlog) +.. method:: socket.listen([backlog]) - Listen for connections made to the socket. The *backlog* argument specifies the - maximum number of queued connections and should be at least 0; the maximum value - is system-dependent (usually 5), the minimum value is forced to 0. + Enable a server to accept connections. If *backlog* is specified, it must + be at least 0 (if it is lower, it is set to 0); it specifies the number of + unaccepted connections that the system will allow before refusing new + connections. If not specified, a default reasonable value is chosen. + .. versionchanged:: 3.5 + The *backlog* parameter is now optional. .. method:: socket.makefile(mode='r', buffering=None, *, encoding=None, \ errors=None, newline=None) @@ -887,10 +929,13 @@ correspond to Unix system calls applicable to sockets. type depends on the arguments given to :meth:`makefile`. These arguments are interpreted the same way as by the built-in :func:`open` function. - Closing the file object won't close the socket unless there are no remaining - references to the socket. The socket must be in blocking mode; it can have - a timeout, but the file object's internal buffer may end up in a inconsistent - state if a timeout occurs. + The socket must be in blocking mode; it can have a timeout, but the file + object's internal buffer may end up in a inconsistent state if a timeout + occurs. + + Closing the file object returned by :meth:`makefile` won't close the + original socket unless all other file objects have been closed and + :meth:`socket.close` has been called on the socket object. .. note:: @@ -1078,7 +1123,8 @@ correspond to Unix system calls applicable to sockets. Send normal and ancillary data to the socket, gathering the non-ancillary data from a series of buffers and concatenating it into a single message. The *buffers* argument specifies the - non-ancillary data as an iterable of buffer-compatible objects + non-ancillary data as an iterable of + :term:`bytes-like objects <bytes-like object>` (e.g. :class:`bytes` objects); the operating system may set a limit (:func:`~os.sysconf` value ``SC_IOV_MAX``) on the number of buffers that can be used. The *ancdata* argument specifies the ancillary @@ -1086,7 +1132,7 @@ correspond to Unix system calls applicable to sockets. ``(cmsg_level, cmsg_type, cmsg_data)``, where *cmsg_level* and *cmsg_type* are integers specifying the protocol level and protocol-specific type respectively, and *cmsg_data* is a - buffer-compatible object holding the associated data. Note that + bytes-like object holding the associated data. Note that some systems (in particular, systems without :func:`CMSG_SPACE`) might support sending only one control message per call. The *flags* argument defaults to 0 and has the same meaning as for @@ -1107,6 +1153,21 @@ correspond to Unix system calls applicable to sockets. .. versionadded:: 3.3 +.. method:: socket.sendfile(file, offset=0, count=None) + + Send a file until EOF is reached by using high-performance + :mod:`os.sendfile` and return the total number of bytes which were sent. + *file* must be a regular file object opened in binary mode. If + :mod:`os.sendfile` is not available (e.g. Windows) or *file* is not a + regular file :meth:`send` will be used instead. *offset* tells from where to + start reading the file. If specified, *count* is the total number of bytes + 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() <io.IOBase.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. + + .. versionadded:: 3.5 .. method:: socket.set_inheritable(inheritable) @@ -1162,14 +1223,14 @@ correspond to Unix system calls applicable to sockets. .. method:: socket.share(process_id) - :platform: Windows + Duplicate a socket and prepare it for sharing with a target process. The + target process must be provided with *process_id*. The resulting bytes object + can then be passed to the target process using some form of interprocess + communication and the socket can be recreated there using :func:`fromshare`. + Once this method has been called, it is safe to close the socket since + the operating system has already duplicated it for the target process. - Duplacet a socket and prepare it for sharing with a target process. The - target process must be provided with *process_id*. The resulting bytes object - can then be passed to the target process using some form of interprocess - communication and the socket can be recreated there using :func:`fromshare`. - Once this method has been called, it is safe to close the socket since - the operating system has already duplicated it for the target process. + Availability: Windows. .. versionadded:: 3.3 @@ -1406,7 +1467,7 @@ After binding (:const:`CAN_RAW`) or connecting (:const:`CAN_BCM`) the socket, yo can use the :meth:`socket.send`, and the :meth:`socket.recv` operations (and their counterparts) on the socket object as usual. -This example might require special priviledge:: +This example might require special privileges:: import socket import struct @@ -1480,4 +1541,3 @@ the :data:`SO_REUSEADDR` flag tells the kernel to reuse a local socket in details of socket semantics. For Unix, refer to the manual pages; for Windows, see the WinSock (or Winsock 2) specification. For IPv6-ready APIs, readers may want to refer to :rfc:`3493` titled Basic Socket Interface Extensions for IPv6. - diff --git a/Doc/library/socketserver.rst b/Doc/library/socketserver.rst index 1ec44389bf8c..9db36d551056 100644 --- a/Doc/library/socketserver.rst +++ b/Doc/library/socketserver.rst @@ -113,7 +113,7 @@ the request handler class :meth:`handle` method. Another approach to handling multiple simultaneous requests in an environment that supports neither threads nor :func:`~os.fork` (or where these are too expensive or inappropriate for the service) is to maintain an explicit table of -partially finished requests and to use :func:`~select.select` to decide which +partially finished requests and to use :mod:`selectors` to decide which request to work on next (or whether to handle a new incoming request). This is particularly important for stream services where each client can potentially be connected for a long time (if threads or subprocesses cannot be used). See @@ -136,7 +136,7 @@ Server Objects .. method:: BaseServer.fileno() Return an integer file descriptor for the socket on which the server is - listening. This function is most commonly passed to :func:`select.select`, to + listening. This function is most commonly passed to :mod:`selectors`, to allow monitoring multiple servers in the same process. diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index bb4aab78bd0e..6097e7a30d7e 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -13,8 +13,8 @@ SQLite for internal data storage. It's also possible to prototype an application using SQLite and then port the code to a larger database such as PostgreSQL or Oracle. -sqlite3 was written by Gerhard Häring and provides a SQL interface compliant -with the DB-API 2.0 specification described by :pep:`249`. +The sqlite3 module was written by Gerhard Häring. It provides a SQL interface +compliant with the DB-API 2.0 specification described by :pep:`249`. To use the module, you must first create a :class:`Connection` object that represents the database. Here the data will be stored in the @@ -31,23 +31,29 @@ and call its :meth:`~Cursor.execute` method to perform SQL commands:: c = conn.cursor() # Create table - c.execute('''create table stocks - (date text, trans text, symbol text, - qty real, price real)''') + c.execute('''CREATE TABLE stocks + (date text, trans text, symbol text, qty real, price real)''') # Insert a row of data - c.execute("""insert into stocks - values ('2006-01-05','BUY','RHAT',100,35.14)""") + c.execute("INSERT INTO stocks VALUES ('2006-01-05','BUY','RHAT',100,35.14)") # Save (commit) the changes conn.commit() - # We can also close the cursor if we are done with it - c.close() + # We can also close the connection if we are done with it. + # Just be sure any changes have been committed or they will be lost. + conn.close() + +The data you've saved is persistent and is available in subsequent sessions:: + + import sqlite3 + conn = sqlite3.connect('example.db') + c = conn.cursor() Usually your SQL operations will need to use values from Python variables. You shouldn't assemble your query using Python's string operations because doing so -is insecure; it makes your program vulnerable to an SQL injection attack. +is insecure; it makes your program vulnerable to an SQL injection attack +(see http://xkcd.com/327/ for humorous example of what can go wrong). Instead, use the DB-API's parameter substitution. Put ``?`` as a placeholder wherever you want to use a value, and then provide a tuple of values as the @@ -56,19 +62,20 @@ modules may use a different placeholder, such as ``%s`` or ``:1``.) For example:: # Never do this -- insecure! - symbol = 'IBM' - c.execute("select * from stocks where symbol = '%s'" % symbol) + symbol = 'RHAT' + c.execute("SELECT * FROM stocks WHERE symbol = '%s'" % symbol) # Do this instead - t = ('IBM',) - c.execute('select * from stocks where symbol=?', t) + t = ('RHAT',) + c.execute('SELECT * FROM stocks WHERE symbol=?', t) + print(c.fetchone()) - # Larger example - for t in [('2006-03-28', 'BUY', 'IBM', 1000, 45.00), - ('2006-04-05', 'BUY', 'MSFT', 1000, 72.00), - ('2006-04-06', 'SELL', 'IBM', 500, 53.00), - ]: - c.execute('insert into stocks values (?,?,?,?,?)', t) + # Larger example that inserts many records at a time + purchases = [('2006-03-28', 'BUY', 'IBM', 1000, 45.00), + ('2006-04-05', 'BUY', 'MSFT', 1000, 72.00), + ('2006-04-06', 'SELL', 'IBM', 500, 53.00), + ] + c.executemany('INSERT INTO stocks VALUES (?,?,?,?,?)', purchases) To retrieve data after executing a SELECT statement, you can either treat the cursor as an :term:`iterator`, call the cursor's :meth:`~Cursor.fetchone` method to @@ -77,21 +84,18 @@ matching rows. This example uses the iterator form:: - >>> c = conn.cursor() - >>> c.execute('select * from stocks order by price') - >>> for row in c: - ... print(row) - ... + >>> for row in c.execute('SELECT * FROM stocks ORDER BY price'): + print(row) + ('2006-01-05', 'BUY', 'RHAT', 100, 35.14) ('2006-03-28', 'BUY', 'IBM', 1000, 45.0) ('2006-04-06', 'SELL', 'IBM', 500, 53.0) - ('2006-04-05', 'BUY', 'MSOFT', 1000, 72.0) - >>> + ('2006-04-05', 'BUY', 'MSFT', 1000, 72.0) .. seealso:: - http://code.google.com/p/pysqlite/ + https://github.com/ghaering/pysqlite The pysqlite web page -- sqlite3 is developed externally under the name "pysqlite". @@ -99,6 +103,9 @@ This example uses the iterator form:: The SQLite web page; the documentation describes the syntax and the available data types for the supported SQL dialect. + http://www.w3schools.com/sql/ + Tutorial, reference and examples for learning SQL syntax. + :pep:`249` - Database API Specification 2.0 PEP written by Marc-André Lemburg. @@ -517,7 +524,7 @@ Cursor Objects .. method:: execute(sql, [parameters]) - Executes an SQL statement. The SQL statement may be parametrized (i. e. + Executes an SQL statement. The SQL statement may be parameterized (i. e. placeholders instead of SQL literals). The :mod:`sqlite3` module supports two kinds of placeholders: question marks (qmark style) and named placeholders (named style). @@ -639,7 +646,7 @@ Row Objects .. method:: keys - This method returns a tuple of column names. Immediately after a query, + This method returns a list of column names. Immediately after a query, it is the first member of each tuple in :attr:`Cursor.description`. Let's assume we initialize a table as in the example given above:: @@ -714,19 +721,20 @@ The following Python types can thus be sent to SQLite without any problem: This is how SQLite types are converted to Python types by default: -+-------------+---------------------------------------------+ -| SQLite type | Python type | -+=============+=============================================+ -| ``NULL`` | :const:`None` | -+-------------+---------------------------------------------+ -| ``INTEGER`` | :class:`int` | -+-------------+---------------------------------------------+ -| ``REAL`` | :class:`float` | -+-------------+---------------------------------------------+ -| ``TEXT`` | depends on text_factory, str by default | -+-------------+---------------------------------------------+ -| ``BLOB`` | :class:`bytes` | -+-------------+---------------------------------------------+ ++-------------+----------------------------------------------+ +| SQLite type | Python type | ++=============+==============================================+ +| ``NULL`` | :const:`None` | ++-------------+----------------------------------------------+ +| ``INTEGER`` | :class:`int` | ++-------------+----------------------------------------------+ +| ``REAL`` | :class:`float` | ++-------------+----------------------------------------------+ +| ``TEXT`` | depends on :attr:`~Connection.text_factory`, | +| | :class:`str` by default | ++-------------+----------------------------------------------+ +| ``BLOB`` | :class:`bytes` | ++-------------+----------------------------------------------+ The type system of the :mod:`sqlite3` module is extensible in two ways: you can store additional Python types in a SQLite database via object adaptation, and @@ -742,9 +750,6 @@ use other Python types with SQLite, you must **adapt** them to one of the sqlite3 module's supported types for SQLite: one of NoneType, int, float, str, bytes. -The :mod:`sqlite3` module uses Python object adaptation, as described in -:pep:`246` for this. The protocol to use is :class:`PrepareProtocol`. - There are two ways to enable the :mod:`sqlite3` module to adapt a custom Python type to one of the supported ones. @@ -800,8 +805,8 @@ and constructs a :class:`Point` object from it. .. note:: - Converter functions **always** get called with a string, no matter under which - data type you sent the value to SQLite. + Converter functions **always** get called with a :class:`bytes` object, no + matter under which data type you sent the value to SQLite. :: diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst index 30cb73207bbe..254fc1fe18da 100644 --- a/Doc/library/ssl.rst +++ b/Doc/library/ssl.rst @@ -142,13 +142,16 @@ instead. Takes an instance ``sock`` of :class:`socket.socket`, and returns an instance of :class:`ssl.SSLSocket`, a subtype of :class:`socket.socket`, which wraps - the underlying socket in an SSL context. For client-side sockets, the - context construction is lazy; if the underlying socket isn't connected yet, - the context construction will be performed after :meth:`connect` is called on - the socket. For server-side sockets, if the socket has no remote peer, it is - assumed to be a listening socket, and the server-side SSL wrapping is - automatically performed on client connections accepted via the :meth:`accept` - method. :func:`wrap_socket` may raise :exc:`SSLError`. + the underlying socket in an SSL context. ``sock`` must be a + :data:`~socket.SOCK_STREAM` socket; other socket types are unsupported. + + For client-side sockets, the context construction is lazy; if the + underlying socket isn't connected yet, the context construction will be + performed after :meth:`connect` is called on the socket. For + server-side sockets, if the socket has no remote peer, it is assumed + to be a listening socket, and the server-side SSL wrapping is + automatically performed on client connections accepted via the + :meth:`accept` method. :func:`wrap_socket` may raise :exc:`SSLError`. The ``keyfile`` and ``certfile`` parameters specify optional files which contain a certificate to be used to identify the local side of the @@ -189,7 +192,7 @@ instead. ------------------------ --------- --------- ---------- --------- ----------- ----------- *SSLv2* yes no yes no no no *SSLv3* no yes yes no no no - *SSLv23* yes no yes no no no + *SSLv23* no yes yes yes yes yes *TLSv1* no no yes yes no no *TLSv1.1* no no yes no yes no *TLSv1.2* no no yes no no yes @@ -198,13 +201,8 @@ instead. .. note:: Which connections succeed will vary depending on the version of - OpenSSL. For instance, in some older versions of OpenSSL (such - as 0.9.7l on OS X 10.4), an SSLv2 client could not connect to an - SSLv23 server. Another example: beginning with OpenSSL 1.0.0, - an SSLv23 client will not actually attempt SSLv2 connections - unless you explicitly enable SSLv2 ciphers; for example, you - might specify ``"ALL"`` or ``"SSLv2"`` as the *ciphers* parameter - to enable them. + OpenSSL. For example, before OpenSSL 1.0.0, an SSLv23 client + would always attempt SSLv2 connections. The *ciphers* parameter sets the available ciphers for this SSL object. It should be a string in the `OpenSSL cipher list format @@ -247,13 +245,13 @@ purposes. :const:`None`, this function can choose to trust the system's default CA certificates instead. - The settings in Python 3.4 are: :data:`PROTOCOL_TLSv1` with high encryption - cipher suites without RC4 and without unauthenticated cipher suites. - Passing :data:`~Purpose.SERVER_AUTH` as *purpose* sets - :data:`~SSLContext.verify_mode` to :data:`CERT_REQUIRED` and either - loads CA certificates (when at least one of *cafile*, *capath* or *cadata* - is given) or uses :meth:`SSLContext.load_default_certs` to load default - CA certificates. + The settings in Python 3.4 are: :data:`PROTOCOL_SSLv23`, :data:`OP_NO_SSLv2`, + and :data:`OP_NO_SSLv3` with high encryption cipher suites without RC4 and + without unauthenticated cipher suites. Passing :data:`~Purpose.SERVER_AUTH` + as *purpose* sets :data:`~SSLContext.verify_mode` to :data:`CERT_REQUIRED` + and either loads CA certificates (when at least one of *cafile*, *capath* or + *cadata* is given) or uses :meth:`SSLContext.load_default_certs` to load + default CA certificates. .. note:: The protocol, options, cipher and other settings may change to more @@ -263,6 +261,19 @@ purposes. If your application needs specific settings, you should create a :class:`SSLContext` and apply the settings yourself. + .. note:: + If you find that when certain older clients or servers attempt to connect + with a :class:`SSLContext` created by this function that they get an + error stating "Protocol or cipher suite mismatch", it may be that they + only support SSL3.0 which this function excludes using the + :data:`OP_NO_SSLv3`. SSL3.0 has problematic security due to a number of + poor implementations and it's reliance on MD5 within the protocol. If you + wish to continue to use this function but still allow SSL 3.0 connections + you can re-enable them using:: + + ctx = ssl.create_default_context(Purpose.CLIENT_AUTH) + ctx.options &= ~ssl.OP_NO_SSLv3 + .. versionadded:: 3.4 @@ -316,6 +327,8 @@ Random generation See http://egd.sourceforge.net/ or http://prngd.sourceforge.net/ for sources of entropy-gathering daemons. + Availability: not available with LibreSSL. + .. function:: RAND_add(bytes, entropy) Mixes the given *bytes* into the SSL pseudo-random number generator. The @@ -331,10 +344,9 @@ Certificate handling Verify that *cert* (in decoded format as returned by :meth:`SSLSocket.getpeercert`) matches the given *hostname*. The rules applied are those for checking the identity of HTTPS servers as outlined - in :rfc:`2818` and :rfc:`6125`, except that IP addresses are not currently - supported. In addition to HTTPS, this function should be suitable for - checking the identity of servers in various SSL-based protocols such as - FTPS, IMAPS, POPS and others. + in :rfc:`2818` and :rfc:`6125`. In addition to HTTPS, this function + should be suitable for checking the identity of servers in various + SSL-based protocols such as FTPS, IMAPS, POPS and others. :exc:`CertificateError` is raised on failure. On success, the function returns nothing:: @@ -356,22 +368,38 @@ Certificate handling IDN A-labels such as ``www*.xn--pthon-kva.org`` are still supported, but ``x*.python.org`` no longer matches ``xn--tda.python.org``. -.. function:: cert_time_to_seconds(timestring) + .. versionchanged:: 3.5 + Matching of IP addresses, when present in the subjectAltName field + of the certificate, is now supported. + +.. function:: cert_time_to_seconds(cert_time) - Returns a floating-point value containing a normal seconds-after-the-epoch - time value, given the time-string representing the "notBefore" or "notAfter" - date from a certificate. + Return the time in seconds since the Epoch, given the ``cert_time`` + string representing the "notBefore" or "notAfter" date from a + certificate in ``"%b %d %H:%M:%S %Y %Z"`` strptime format (C + locale). - Here's an example:: + Here's an example: - >>> import ssl - >>> ssl.cert_time_to_seconds("May 9 00:00:00 2007 GMT") - 1178694000.0 - >>> import time - >>> time.ctime(ssl.cert_time_to_seconds("May 9 00:00:00 2007 GMT")) - 'Wed May 9 00:00:00 2007' + .. doctest:: newcontext -.. function:: get_server_certificate(addr, ssl_version=PROTOCOL_SSLv3, ca_certs=None) + >>> import ssl + >>> timestamp = ssl.cert_time_to_seconds("Jan 5 09:34:43 2018 GMT") + >>> timestamp + 1515144883 + >>> from datetime import datetime + >>> print(datetime.utcfromtimestamp(timestamp)) + 2018-01-05 09:34:43 + + "notBefore" or "notAfter" dates must use GMT (:rfc:`5280`). + + .. versionchanged:: 3.5 + Interpret the input time as a time in UTC as specified by 'GMT' + timezone in the input string. Local timezone was used + previously. Return an integer (no fractions of a second in the + input format) + +.. function:: get_server_certificate(addr, ssl_version=PROTOCOL_SSLv23, ca_certs=None) Given the address ``addr`` of an SSL-protected server, as a (*hostname*, *port-number*) pair, fetches the server's certificate, and returns it as a @@ -385,6 +413,10 @@ Certificate handling .. versionchanged:: 3.3 This function is now IPv6-compatible. + .. versionchanged:: 3.5 + The default *ssl_version* is changed from :data:`PROTOCOL_SSLv3` to + :data:`PROTOCOL_SSLv23` for maximum compatibility with modern servers. + .. function:: DER_cert_to_PEM_cert(DER_cert_bytes) Given a certificate as a DER-encoded blob of bytes, returns a PEM-encoded @@ -518,28 +550,32 @@ Constants .. versionadded:: 3.4 +.. data:: PROTOCOL_SSLv23 + + Selects the highest protocol version that both the client and server support. + Despite the name, this option can select "TLS" protocols as well as "SSL". + .. data:: PROTOCOL_SSLv2 Selects SSL version 2 as the channel encryption protocol. - This protocol is not available if OpenSSL is compiled with OPENSSL_NO_SSL2 - flag. + This protocol is not available if OpenSSL is compiled with the + ``OPENSSL_NO_SSL2`` flag. .. warning:: SSL version 2 is insecure. Its use is highly discouraged. -.. data:: PROTOCOL_SSLv23 +.. data:: PROTOCOL_SSLv3 - Selects SSL version 2 or 3 as the channel encryption protocol. This is a - setting to use with servers for maximum compatibility with the other end of - an SSL connection, but it may cause the specific ciphers chosen for the - encryption to be of fairly low quality. + Selects SSL version 3 as the channel encryption protocol. -.. data:: PROTOCOL_SSLv3 + This protocol is not be available if OpenSSL is compiled with the + ``OPENSSL_NO_SSLv3`` flag. + + .. warning:: - Selects SSL version 3 as the channel encryption protocol. For clients, this - is the maximally compatible SSL variant. + SSL version 3 is insecure. Its use is highly discouraged. .. data:: PROTOCOL_TLSv1 @@ -547,7 +583,6 @@ Constants .. data:: PROTOCOL_TLSv1_1 - Selects TLS version 1.1 as the channel encryption protocol. Available only with openssl version 1.0.1+. @@ -555,11 +590,9 @@ Constants .. data:: PROTOCOL_TLSv1_2 - - Selects TLS version 1.2 as the channel encryption protocol. This is the most - modern version, and probably the best choice for maximum protection, if both - sides can speak it. - Available only with openssl version 1.0.1+. + Selects TLS version 1.2 as the channel encryption protocol. This is the + most modern version, and probably the best choice for maximum protection, + if both sides can speak it. Available only with openssl version 1.0.1+. .. versionadded:: 3.4 @@ -643,6 +676,13 @@ Constants .. versionadded:: 3.3 +.. data:: HAS_ALPN + + Whether the OpenSSL library has built-in support for the *Application-Layer + Protocol Negotiation* TLS extension as described in :rfc:`7301`. + + .. versionadded:: 3.5 + .. data:: HAS_ECDH Whether the OpenSSL library has built-in support for Elliptic Curve-based @@ -654,9 +694,7 @@ Constants .. data:: HAS_SNI Whether the OpenSSL library has built-in support for the *Server Name - Indication* extension to the SSLv3 and TLSv1 protocols (as defined in - :rfc:`4366`). When true, you can use the *server_hostname* argument to - :meth:`SSLContext.wrap_socket`. + Indication* extension (as defined in :rfc:`4366`). .. versionadded:: 3.2 @@ -742,39 +780,85 @@ Constants SSL Sockets ----------- -SSL sockets provide the following methods of :ref:`socket-objects`: - -- :meth:`~socket.socket.accept()` -- :meth:`~socket.socket.bind()` -- :meth:`~socket.socket.close()` -- :meth:`~socket.socket.connect()` -- :meth:`~socket.socket.detach()` -- :meth:`~socket.socket.fileno()` -- :meth:`~socket.socket.getpeername()`, :meth:`~socket.socket.getsockname()` -- :meth:`~socket.socket.getsockopt()`, :meth:`~socket.socket.setsockopt()` -- :meth:`~socket.socket.gettimeout()`, :meth:`~socket.socket.settimeout()`, - :meth:`~socket.socket.setblocking()` -- :meth:`~socket.socket.listen()` -- :meth:`~socket.socket.makefile()` -- :meth:`~socket.socket.recv()`, :meth:`~socket.socket.recv_into()` - (but passing a non-zero ``flags`` argument is not allowed) -- :meth:`~socket.socket.send()`, :meth:`~socket.socket.sendall()` (with - the same limitation) -- :meth:`~socket.socket.shutdown()` - -However, since the SSL (and TLS) protocol has its own framing atop -of TCP, the SSL sockets abstraction can, in certain respects, diverge from -the specification of normal, OS-level sockets. See especially the -:ref:`notes on non-blocking sockets <ssl-nonblocking>`. +.. class:: SSLSocket(socket.socket) + + SSL sockets provide the following methods of :ref:`socket-objects`: + + - :meth:`~socket.socket.accept()` + - :meth:`~socket.socket.bind()` + - :meth:`~socket.socket.close()` + - :meth:`~socket.socket.connect()` + - :meth:`~socket.socket.detach()` + - :meth:`~socket.socket.fileno()` + - :meth:`~socket.socket.getpeername()`, :meth:`~socket.socket.getsockname()` + - :meth:`~socket.socket.getsockopt()`, :meth:`~socket.socket.setsockopt()` + - :meth:`~socket.socket.gettimeout()`, :meth:`~socket.socket.settimeout()`, + :meth:`~socket.socket.setblocking()` + - :meth:`~socket.socket.listen()` + - :meth:`~socket.socket.makefile()` + - :meth:`~socket.socket.recv()`, :meth:`~socket.socket.recv_into()` + (but passing a non-zero ``flags`` argument is not allowed) + - :meth:`~socket.socket.send()`, :meth:`~socket.socket.sendall()` (with + the same limitation) + - :meth:`~socket.socket.sendfile()` (but :mod:`os.sendfile` will be used + for plain-text sockets only, else :meth:`~socket.socket.send()` will be used) + - :meth:`~socket.socket.shutdown()` + + However, since the SSL (and TLS) protocol has its own framing atop + of TCP, the SSL sockets abstraction can, in certain respects, diverge from + the specification of normal, OS-level sockets. See especially the + :ref:`notes on non-blocking sockets <ssl-nonblocking>`. + + Usually, :class:`SSLSocket` are not created directly, but using the + :func:`wrap_socket` function or the :meth:`SSLContext.wrap_socket` method. + + .. versionchanged:: 3.5 + The :meth:`sendfile` method was added. + SSL sockets also have the following additional methods and attributes: +.. method:: SSLSocket.read(len=0, buffer=None) + + Read up to *len* bytes of data from the SSL socket and return the result as + a ``bytes`` instance. If *buffer* is specified, then read into the buffer + instead, and return the number of bytes read. + + Raise :exc:`SSLWantReadError` or :exc:`SSLWantWriteError` if the socket is + :ref:`non-blocking <ssl-nonblocking>` and the read would block. + + As at any time a re-negotiation is possible, a call to :meth:`read` can also + cause write operations. + +.. method:: SSLSocket.write(buf) + + Write *buf* to the SSL socket and return the number of bytes written. The + *buf* argument must be an object supporting the buffer interface. + + Raise :exc:`SSLWantReadError` or :exc:`SSLWantWriteError` if the socket is + :ref:`non-blocking <ssl-nonblocking>` and the write would block. + + As at any time a re-negotiation is possible, a call to :meth:`write` can + also cause read operations. + +.. note:: + + The :meth:`~SSLSocket.read` and :meth:`~SSLSocket.write` methods are the + low-level methods that read and write unencrypted, application-level data + and and decrypt/encrypt it to encrypted, wire-level data. These methods + require an active SSL connection, i.e. the handshake was completed and + :meth:`SSLSocket.unwrap` was not called. + + Normally you should use the socket API methods like + :meth:`~socket.socket.recv` and :meth:`~socket.socket.send` instead of these + methods. + .. method:: SSLSocket.do_handshake() Perform the SSL setup handshake. .. versionchanged:: 3.4 - The handshake method also performce :func:`match_hostname` when the + The handshake method also performs :func:`match_hostname` when the :attr:`~SSLContext.check_hostname` attribute of the socket's :attr:`~SSLSocket.context` is true. @@ -818,6 +902,7 @@ SSL sockets also have the following additional methods and attributes: 'version': 3} .. note:: + To validate a certificate for a particular service, you can use the :func:`match_hostname` function. @@ -841,10 +926,8 @@ SSL sockets also have the following additional methods and attributes: .. versionchanged:: 3.4 :exc:`ValueError` is raised when the handshake isn't done. - - .. versionchanged:: 3.4 The returned dictionary includes additional X509v3 extension items - such as ``crlDistributionPoints``, ``caIssuers`` and ``OCSP`` URIs. + such as ``crlDistributionPoints``, ``caIssuers`` and ``OCSP`` URIs. .. method:: SSLSocket.cipher() @@ -852,6 +935,17 @@ SSL sockets also have the following additional methods and attributes: version of the SSL protocol that defines its use, and the number of secret bits being used. If no connection has been established, returns ``None``. +.. method:: SSLSocket.shared_ciphers() + + Return the list of ciphers shared by the client during the handshake. Each + entry of the returned list is a three-value tuple containing the name of the + cipher, the version of the SSL protocol that defines its use, and the number + of secret bits the cipher uses. :meth:`~SSLSocket.shared_ciphers` returns + ``None`` if no connection has been established or the socket is a client + socket. + + .. versionadded:: 3.5 + .. method:: SSLSocket.compression() Return the compression algorithm being used as a string, or ``None`` @@ -875,12 +969,22 @@ SSL sockets also have the following additional methods and attributes: .. versionadded:: 3.3 +.. method:: SSLSocket.selected_alpn_protocol() + + Return the protocol that was selected during the TLS handshake. If + :meth:`SSLContext.set_alpn_protocols` was not called, if the other party does + not support ALPN, if this socket does not support any of the client's + proposed protocols, or if the handshake has not happened yet, ``None`` is + returned. + + .. versionadded:: 3.5 + .. method:: SSLSocket.selected_npn_protocol() - Returns the protocol that was selected during the TLS/SSL handshake. If - :meth:`SSLContext.set_npn_protocols` was not called, or if the other party - does not support NPN, or if the handshake has not yet happened, this will - return ``None``. + Return the higher-level protocol that was selected during the TLS/SSL + handshake. If :meth:`SSLContext.set_npn_protocols` was not called, or + if the other party does not support NPN, or if the handshake has not yet + happened, this will return ``None``. .. versionadded:: 3.3 @@ -892,6 +996,21 @@ SSL sockets also have the following additional methods and attributes: returned socket should always be used for further communication with the other side of the connection, rather than the original socket. +.. method:: SSLSocket.version() + + Return the actual SSL protocol version negotiated by the connection + as a string, or ``None`` is no secure connection is established. + As of this writing, possible return values include ``"SSLv2"``, + ``"SSLv3"``, ``"TLSv1"``, ``"TLSv1.1"`` and ``"TLSv1.2"``. + Recent OpenSSL versions may define more return values. + + .. versionadded:: 3.5 + +.. method:: SSLSocket.pending() + + Returns the number of already decrypted bytes available for read, pending on + the connection. + .. attribute:: SSLSocket.context The :class:`SSLContext` object this SSL socket is tied to. If the SSL @@ -901,6 +1020,20 @@ SSL sockets also have the following additional methods and attributes: .. versionadded:: 3.2 +.. attribute:: SSLSocket.server_side + + A boolean which is ``True`` for server-side sockets and ``False`` for + client-side sockets. + + .. versionadded:: 3.2 + +.. attribute:: SSLSocket.server_hostname + + Hostname of the server: :class:`str` type, or ``None`` for server-side + socket or if the hostname was not specified in the constructor. + + .. versionadded:: 3.2 + SSL Contexts ------------ @@ -993,7 +1126,7 @@ to speed up repeated connections from the same clients. :data:`CERT_NONE`. At least one of *cafile* or *capath* must be specified. This method can also load certification revocation lists (CRLs) in PEM or - or DER format. In order to make use of CRLs, :attr:`SSLContext.verify_flags` + DER format. In order to make use of CRLs, :attr:`SSLContext.verify_flags` must be configured properly. The *cafile* string, if present, is the path to a file of concatenated @@ -1007,7 +1140,7 @@ to speed up repeated connections from the same clients. <http://www.openssl.org/docs/ssl/SSL_CTX_load_verify_locations.html>`_. The *cadata* object, if present, is either an ASCII string of one or more - PEM-encoded certificates or a bytes-like object of DER-encoded + PEM-encoded certificates or a :term:`bytes-like object` of DER-encoded certificates. Like with *capath* extra lines around PEM-encoded certificates are ignored but at least one certificate must be present. @@ -1047,6 +1180,20 @@ to speed up repeated connections from the same clients. when connected, the :meth:`SSLSocket.cipher` method of SSL sockets will give the currently selected cipher. +.. method:: SSLContext.set_alpn_protocols(protocols) + + Specify which protocols the socket should advertise during the SSL/TLS + handshake. It should be a list of ASCII strings, like ``['http/1.1', + 'spdy/2']``, ordered by preference. The selection of a protocol will happen + during the handshake, and will play out according to :rfc:`7301`. After a + successful handshake, the :meth:`SSLSocket.selected_alpn_protocol` method will + return the agreed-upon protocol. + + This method will raise :exc:`NotImplementedError` if :data:`HAS_ALPN` is + False. + + .. versionadded:: 3.5 + .. method:: SSLContext.set_npn_protocols(protocols) Specify which protocols the socket should advertise during the SSL/TLS @@ -1087,7 +1234,7 @@ to speed up repeated connections from the same clients. Due to the early negotiation phase of the TLS connection, only limited methods and attributes are usable like - :meth:`SSLSocket.selected_npn_protocol` and :attr:`SSLSocket.context`. + :meth:`SSLSocket.selected_alpn_protocol` and :attr:`SSLSocket.context`. :meth:`SSLSocket.getpeercert`, :meth:`SSLSocket.getpeercert`, :meth:`SSLSocket.cipher` and :meth:`SSLSocket.compress` methods require that the TLS connection has progressed beyond the TLS Client Hello and therefore @@ -1099,7 +1246,7 @@ to speed up repeated connections from the same clients. returned. Other return values will result in a TLS fatal error with :const:`ALERT_DESCRIPTION_INTERNAL_ERROR`. - If there is a IDNA decoding error on the server name, the TLS connection + If there is an IDNA decoding error on the server name, the TLS connection will terminate with an :const:`ALERT_DESCRIPTION_INTERNAL_ERROR` fatal TLS alert message to the client. @@ -1149,7 +1296,10 @@ to speed up repeated connections from the same clients. server_hostname=None) Wrap an existing Python socket *sock* and return an :class:`SSLSocket` - object. The SSL socket is tied to the context, its settings and + object. *sock* must be a :data:`~socket.SOCK_STREAM` socket; other socket + types are unsupported. + + The returned SSL socket is tied to the context, its settings and certificates. The parameters *server_side*, *do_handshake_on_connect* and *suppress_ragged_eofs* have the same meaning as in the top-level :func:`wrap_socket` function. @@ -1157,11 +1307,22 @@ to speed up repeated connections from the same clients. On client connections, the optional parameter *server_hostname* specifies the hostname of the service which we are connecting to. This allows a single server to host multiple SSL-based services with distinct certificates, - quite similarly to HTTP virtual hosts. Specifying *server_hostname* - will raise a :exc:`ValueError` if the OpenSSL library doesn't have support - for it (that is, if :data:`HAS_SNI` is :const:`False`). Specifying - *server_hostname* will also raise a :exc:`ValueError` if *server_side* - is true. + quite similarly to HTTP virtual hosts. Specifying *server_hostname* will + raise a :exc:`ValueError` if *server_side* is true. + + .. versionchanged:: 3.5 + Always allow a server_hostname to be passed, even if OpenSSL does not + have SNI. + +.. method:: SSLContext.wrap_bio(incoming, outgoing, server_side=False, \ + server_hostname=None) + + Create a new :class:`SSLObject` instance by wrapping the BIO objects + *incoming* and *outgoing*. The SSL routines will read input data from the + incoming BIO and write data to the outgoing BIO. + + The *server_side* and *server_hostname* parameters have the same meaning as + in :meth:`SSLContext.wrap_socket`. .. method:: SSLContext.session_stats() @@ -1205,8 +1366,8 @@ to speed up repeated connections from the same clients. context.load_default_certs() s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - ssl_sock = context.wrap_socket(s, server_hostname='www.verisign.com'): - ssl_sock.connect(('www.verisign.com', 443)) + ssl_sock = context.wrap_socket(s, server_hostname='www.verisign.com') + ssl_sock.connect(('www.verisign.com', 443)) .. versionadded:: 3.4 @@ -1324,20 +1485,9 @@ If you are going to require validation of the other side of the connection's certificate, you need to provide a "CA certs" file, filled with the certificate chains for each issuer you are willing to trust. Again, this file just contains these chains concatenated together. For validation, Python will use the first -chain it finds in the file which matches. Some "standard" root certificates are -available from various certification authorities: `CACert.org -<http://www.cacert.org/index.php?id=3>`_, `Thawte -<http://www.thawte.com/roots/>`_, `Verisign -<http://www.verisign.com/support/roots.html>`_, `Positive SSL -<http://www.PositiveSSL.com/ssl-certificate-support/cert_installation/UTN-USERFirst-Hardware.crt>`_ -(used by python.org), `Equifax and GeoTrust -<http://www.geotrust.com/resources/root_certificates/index.asp>`_. - -In general, if you are using SSL3 or TLS1, you don't need to put the full chain -in your "CA certs" file; you only need the root certificates, and the remote -peer is supposed to furnish the other certificates necessary to chain from its -certificate to a root certificate. See :rfc:`4158` for more discussion of the -way in which certification chains can be built. +chain it finds in the file which matches. The platform's certificates file can +be used by calling :meth:`SSLContext.load_default_certs`, this is done +automatically with :func:`.create_default_context`. Combined key and certificate ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -1411,118 +1561,100 @@ should use the following idiom:: Client-side operation ^^^^^^^^^^^^^^^^^^^^^ -This example connects to an SSL server and prints the server's certificate:: - - import socket, ssl, pprint - - s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - # require a certificate from the server - ssl_sock = ssl.wrap_socket(s, - ca_certs="/etc/ca_certs_file", - cert_reqs=ssl.CERT_REQUIRED) - ssl_sock.connect(('www.verisign.com', 443)) - - pprint.pprint(ssl_sock.getpeercert()) - # note that closing the SSLSocket will also close the underlying socket - ssl_sock.close() - -As of January 6, 2012, the certificate printed by this program looks like -this:: - - {'issuer': ((('countryName', 'US'),), - (('organizationName', 'VeriSign, Inc.'),), - (('organizationalUnitName', 'VeriSign Trust Network'),), - (('organizationalUnitName', - 'Terms of use at https://www.verisign.com/rpa (c)06'),), - (('commonName', - 'VeriSign Class 3 Extended Validation SSL SGC CA'),)), - 'notAfter': 'May 25 23:59:59 2012 GMT', - 'notBefore': 'May 26 00:00:00 2010 GMT', - 'serialNumber': '53D2BEF924A7245E83CA01E46CAA2477', - 'subject': ((('1.3.6.1.4.1.311.60.2.1.3', 'US'),), - (('1.3.6.1.4.1.311.60.2.1.2', 'Delaware'),), - (('businessCategory', 'V1.0, Clause 5.(b)'),), - (('serialNumber', '2497886'),), - (('countryName', 'US'),), - (('postalCode', '94043'),), - (('stateOrProvinceName', 'California'),), - (('localityName', 'Mountain View'),), - (('streetAddress', '487 East Middlefield Road'),), - (('organizationName', 'VeriSign, Inc.'),), - (('organizationalUnitName', ' Production Security Services'),), - (('commonName', 'www.verisign.com'),)), - 'subjectAltName': (('DNS', 'www.verisign.com'), - ('DNS', 'verisign.com'), - ('DNS', 'www.verisign.net'), - ('DNS', 'verisign.net'), - ('DNS', 'www.verisign.mobi'), - ('DNS', 'verisign.mobi'), - ('DNS', 'www.verisign.eu'), - ('DNS', 'verisign.eu')), - 'version': 3} +This example creates a SSL context with the recommended security settings +for client sockets, including automatic certificate verification:: + + >>> context = ssl.create_default_context() -This other example first creates an SSL context, instructs it to verify -certificates sent by peers, and feeds it a set of recognized certificate -authorities (CA):: +If you prefer to tune security settings yourself, you might create +a context from scratch (but beware that you might not get the settings +right):: >>> context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) >>> context.verify_mode = ssl.CERT_REQUIRED + >>> context.check_hostname = True >>> context.load_verify_locations("/etc/ssl/certs/ca-bundle.crt") -(it is assumed your operating system places a bundle of all CA certificates -in ``/etc/ssl/certs/ca-bundle.crt``; if not, you'll get an error and have -to adjust the location) +(this snippet assumes your operating system places a bundle of all CA +certificates in ``/etc/ssl/certs/ca-bundle.crt``; if not, you'll get an +error and have to adjust the location) When you use the context to connect to a server, :const:`CERT_REQUIRED` validates the server certificate: it ensures that the server certificate was signed with one of the CA certificates, and checks the signature for correctness:: - >>> conn = context.wrap_socket(socket.socket(socket.AF_INET)) - >>> conn.connect(("linuxfr.org", 443)) + >>> conn = context.wrap_socket(socket.socket(socket.AF_INET), + ... server_hostname="www.python.org") + >>> conn.connect(("www.python.org", 443)) -You should then fetch the certificate and check its fields for conformity:: +You may then fetch the certificate:: >>> cert = conn.getpeercert() - >>> ssl.match_hostname(cert, "linuxfr.org") Visual inspection shows that the certificate does identify the desired service -(that is, the HTTPS host ``linuxfr.org``):: +(that is, the HTTPS host ``www.python.org``):: >>> pprint.pprint(cert) - {'issuer': ((('organizationName', 'CAcert Inc.'),), - (('organizationalUnitName', 'http://www.CAcert.org'),), - (('commonName', 'CAcert Class 3 Root'),)), - 'notAfter': 'Jun 7 21:02:24 2013 GMT', - 'notBefore': 'Jun 8 21:02:24 2011 GMT', - 'serialNumber': 'D3E9', - 'subject': ((('commonName', 'linuxfr.org'),),), - 'subjectAltName': (('DNS', 'linuxfr.org'), - ('othername', '<unsupported>'), - ('DNS', 'linuxfr.org'), - ('othername', '<unsupported>'), - ('DNS', 'dev.linuxfr.org'), - ('othername', '<unsupported>'), - ('DNS', 'prod.linuxfr.org'), - ('othername', '<unsupported>'), - ('DNS', 'alpha.linuxfr.org'), - ('othername', '<unsupported>'), - ('DNS', '*.linuxfr.org'), - ('othername', '<unsupported>')), + {'OCSP': ('http://ocsp.digicert.com',), + 'caIssuers': ('http://cacerts.digicert.com/DigiCertSHA2ExtendedValidationServerCA.crt',), + 'crlDistributionPoints': ('http://crl3.digicert.com/sha2-ev-server-g1.crl', + 'http://crl4.digicert.com/sha2-ev-server-g1.crl'), + 'issuer': ((('countryName', 'US'),), + (('organizationName', 'DigiCert Inc'),), + (('organizationalUnitName', 'www.digicert.com'),), + (('commonName', 'DigiCert SHA2 Extended Validation Server CA'),)), + 'notAfter': 'Sep 9 12:00:00 2016 GMT', + 'notBefore': 'Sep 5 00:00:00 2014 GMT', + 'serialNumber': '01BB6F00122B177F36CAB49CEA8B6B26', + 'subject': ((('businessCategory', 'Private Organization'),), + (('1.3.6.1.4.1.311.60.2.1.3', 'US'),), + (('1.3.6.1.4.1.311.60.2.1.2', 'Delaware'),), + (('serialNumber', '3359300'),), + (('streetAddress', '16 Allen Rd'),), + (('postalCode', '03894-4801'),), + (('countryName', 'US'),), + (('stateOrProvinceName', 'NH'),), + (('localityName', 'Wolfeboro,'),), + (('organizationName', 'Python Software Foundation'),), + (('commonName', 'www.python.org'),)), + 'subjectAltName': (('DNS', 'www.python.org'), + ('DNS', 'python.org'), + ('DNS', 'pypi.python.org'), + ('DNS', 'docs.python.org'), + ('DNS', 'testpypi.python.org'), + ('DNS', 'bugs.python.org'), + ('DNS', 'wiki.python.org'), + ('DNS', 'hg.python.org'), + ('DNS', 'mail.python.org'), + ('DNS', 'packaging.python.org'), + ('DNS', 'pythonhosted.org'), + ('DNS', 'www.pythonhosted.org'), + ('DNS', 'test.pythonhosted.org'), + ('DNS', 'us.pycon.org'), + ('DNS', 'id.python.org')), 'version': 3} -Now that you are assured of its authenticity, you can proceed to talk with -the server:: +Now the SSL channel is established and the certificate verified, you can +proceed to talk with the server:: >>> conn.sendall(b"HEAD / HTTP/1.0\r\nHost: linuxfr.org\r\n\r\n") >>> pprint.pprint(conn.recv(1024).split(b"\r\n")) - [b'HTTP/1.1 302 Found', - b'Date: Sun, 16 May 2010 13:43:28 GMT', - b'Server: Apache/2.2', - b'Location: https://linuxfr.org/pub/', - b'Vary: Accept-Encoding', + [b'HTTP/1.1 200 OK', + b'Date: Sat, 18 Oct 2014 18:27:20 GMT', + b'Server: nginx', + b'Content-Type: text/html; charset=utf-8', + b'X-Frame-Options: SAMEORIGIN', + b'Content-Length: 45679', + b'Accept-Ranges: bytes', + b'Via: 1.1 varnish', + b'Age: 2188', + b'X-Served-By: cache-lcy1134-LCY', + b'X-Cache: HIT', + b'X-Cache-Hits: 11', + b'Vary: Cookie', + b'Strict-Transport-Security: max-age=63072000; includeSubDomains', b'Connection: close', - b'Content-Type: text/html; charset=iso-8859-1', b'', b''] @@ -1540,7 +1672,7 @@ waiting for clients to connect:: import socket, ssl - context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) + context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) context.load_cert_chain(certfile="mycertfile", keyfile="mykeyfile") bindsocket = socket.socket() @@ -1576,7 +1708,7 @@ are finished with the client (or the client is finished with you):: And go back to listening for new client connections (of course, a real server would probably handle each client connection in a separate thread, or put -the sockets in non-blocking mode and use an event loop). +the sockets in :ref:`non-blocking mode <ssl-nonblocking>` and use an event loop). .. _ssl-nonblocking: @@ -1584,8 +1716,25 @@ the sockets in non-blocking mode and use an event loop). Notes on non-blocking sockets ----------------------------- -When working with non-blocking sockets, there are several things you need -to be aware of: +SSL sockets behave slightly different than regular sockets in +non-blocking mode. When working with non-blocking sockets, there are +thus several things you need to be aware of: + +- Most :class:`SSLSocket` methods will raise either + :exc:`SSLWantWriteError` or :exc:`SSLWantReadError` instead of + :exc:`BlockingIOError` if an I/O operation would + block. :exc:`SSLWantReadError` will be raised if a read operation on + the underlying socket is necessary, and :exc:`SSLWantWriteError` for + a write operation on the underlying socket. Note that attempts to + *write* to an SSL socket may require *reading* from the underlying + socket first, and attempts to *read* from the SSL socket may require + a prior *write* to the underlying socket. + + .. versionchanged:: 3.5 + + In earlier Python versions, the :meth:`!SSLSocket.send` method + returned zero instead of raising :exc:`SSLWantWriteError` or + :exc:`SSLWantReadError`. - Calling :func:`~select.select` tells you that the OS-level socket can be read from (or written to), but it does not imply that there is sufficient @@ -1594,8 +1743,14 @@ to be aware of: and :meth:`SSLSocket.send` failures, and retry after another call to :func:`~select.select`. +- Conversely, since the SSL layer has its own framing, a SSL socket may + still have data available for reading without :func:`~select.select` + being aware of it. Therefore, you should first call + :meth:`SSLSocket.recv` to drain any potentially available data, and then + only block on a :func:`~select.select` call if still necessary. + (of course, similar provisions apply when using other primitives such as - :func:`~select.poll`) + :func:`~select.poll`, or those in the :mod:`selectors` module) - The SSL handshake itself will be non-blocking: the :meth:`SSLSocket.do_handshake` method has to be retried until it returns @@ -1611,15 +1766,184 @@ to be aware of: except ssl.SSLWantWriteError: select.select([], [sock], []) +.. seealso:: + + The :mod:`asyncio` module supports :ref:`non-blocking SSL sockets + <ssl-nonblocking>` and provides a + higher level API. It polls for events using the :mod:`selectors` module and + handles :exc:`SSLWantWriteError`, :exc:`SSLWantReadError` and + :exc:`BlockingIOError` exceptions. It runs the SSL handshake asynchronously + as well. + + +Memory BIO Support +------------------ + +.. versionadded:: 3.5 + +Ever since the SSL module was introduced in Python 2.6, the :class:`SSLSocket` +class has provided two related but distinct areas of functionality: + +- SSL protocol handling +- Network IO + +The network IO API is identical to that provided by :class:`socket.socket`, +from which :class:`SSLSocket` also inherits. This allows an SSL socket to be +used as a drop-in replacement for a regular socket, making it very easy to add +SSL support to an existing application. + +Combining SSL protocol handling and network IO usually works well, but there +are some cases where it doesn't. An example is async IO frameworks that want to +use a different IO multiplexing model than the "select/poll on a file +descriptor" (readiness based) model that is assumed by :class:`socket.socket` +and by the internal OpenSSL socket IO routines. This is mostly relevant for +platforms like Windows where this model is not efficient. For this purpose, a +reduced scope variant of :class:`SSLSocket` called :class:`SSLObject` is +provided. + +.. class:: SSLObject + + A reduced-scope variant of :class:`SSLSocket` representing an SSL protocol + instance that does not contain any network IO methods. This class is + typically used by framework authors that want to implement asynchronous IO + for SSL through memory buffers. + + This class implements an interface on top of a low-level SSL object as + implemented by OpenSSL. This object captures the state of an SSL connection + but does not provide any network IO itself. IO needs to be performed through + separate "BIO" objects which are OpenSSL's IO abstraction layer. + + An :class:`SSLObject` instance can be created using the + :meth:`~SSLContext.wrap_bio` method. This method will create the + :class:`SSLObject` instance and bind it to a pair of BIOs. The *incoming* + BIO is used to pass data from Python to the SSL protocol instance, while the + *outgoing* BIO is used to pass data the other way around. + + The following methods are available: + + - :attr:`~SSLSocket.context` + - :attr:`~SSLSocket.server_side` + - :attr:`~SSLSocket.server_hostname` + - :meth:`~SSLSocket.read` + - :meth:`~SSLSocket.write` + - :meth:`~SSLSocket.getpeercert` + - :meth:`~SSLSocket.selected_npn_protocol` + - :meth:`~SSLSocket.cipher` + - :meth:`~SSLSocket.shared_ciphers` + - :meth:`~SSLSocket.compression` + - :meth:`~SSLSocket.pending` + - :meth:`~SSLSocket.do_handshake` + - :meth:`~SSLSocket.unwrap` + - :meth:`~SSLSocket.get_channel_binding` + + When compared to :class:`SSLSocket`, this object lacks the following + features: + + - Any form of network IO incluging methods such as ``recv()`` and + ``send()``. + + - There is no *do_handshake_on_connect* machinery. You must always manually + call :meth:`~SSLSocket.do_handshake` to start the handshake. + + - There is no handling of *suppress_ragged_eofs*. All end-of-file conditions + that are in violation of the protocol are reported via the + :exc:`SSLEOFError` exception. + + - The method :meth:`~SSLSocket.unwrap` call does not return anything, + unlike for an SSL socket where it returns the underlying socket. + + - The *server_name_callback* callback passed to + :meth:`SSLContext.set_servername_callback` will get an :class:`SSLObject` + instance instead of a :class:`SSLSocket` instance as its first parameter. + + Some notes related to the use of :class:`SSLObject`: + + - All IO on an :class:`SSLObject` is :ref:`non-blocking <ssl-nonblocking>`. + This means that for example :meth:`~SSLSocket.read` will raise an + :exc:`SSLWantReadError` if it needs more data than the incoming BIO has + available. + + - There is no module-level ``wrap_bio()`` call like there is for + :meth:`~SSLContext.wrap_socket`. An :class:`SSLObject` is always created + via an :class:`SSLContext`. + +An SSLObject communicates with the outside world using memory buffers. The +class :class:`MemoryBIO` provides a memory buffer that can be used for this +purpose. It wraps an OpenSSL memory BIO (Basic IO) object: + +.. class:: MemoryBIO + + A memory buffer that can be used to pass data between Python and an SSL + protocol instance. + + .. attribute:: MemoryBIO.pending + + Return the number of bytes currently in the memory buffer. + + .. attribute:: MemoryBIO.eof + + A boolean indicating whether the memory BIO is current at the end-of-file + position. + + .. method:: MemoryBIO.read(n=-1) + + Read up to *n* bytes from the memory buffer. If *n* is not specified or + negative, all bytes are returned. + + .. method:: MemoryBIO.write(buf) + + Write the bytes from *buf* to the memory BIO. The *buf* argument must be an + object supporting the buffer protocol. + + The return value is the number of bytes written, which is always equal to + the length of *buf*. + + .. method:: MemoryBIO.write_eof() + + Write an EOF marker to the memory BIO. After this method has been called, it + is illegal to call :meth:`~MemoryBIO.write`. The attribute :attr:`eof` will + become true after all data currently in the buffer has been read. + .. _ssl-security: Security considerations ----------------------- +Best defaults +^^^^^^^^^^^^^ + +For **client use**, if you don't have any special requirements for your +security policy, it is highly recommended that you use the +:func:`create_default_context` function to create your SSL context. +It will load the system's trusted CA certificates, enable certificate +validation and hostname checking, and try to choose reasonably secure +protocol and cipher settings. + +For example, here is how you would use the :class:`smtplib.SMTP` class to +create a trusted, secure connection to a SMTP server:: + + >>> import ssl, smtplib + >>> smtp = smtplib.SMTP("mail.python.org", port=587) + >>> context = ssl.create_default_context() + >>> smtp.starttls(context=context) + (220, b'2.0.0 Ready to start TLS') + +If a client certificate is needed for the connection, it can be added with +:meth:`SSLContext.load_cert_chain`. + +By contrast, if you create the SSL context by calling the :class:`SSLContext` +constructor yourself, it will not have certificate validation nor hostname +checking enabled by default. If you do so, please read the paragraphs below +to achieve a good security level. + +Manual settings +^^^^^^^^^^^^^^^ + Verifying certificates -^^^^^^^^^^^^^^^^^^^^^^ +'''''''''''''''''''''' +When calling the :class:`SSLContext` constructor directly, :const:`CERT_NONE` is the default. Since it does not authenticate the other peer, it can be insecure, especially in client mode where most of time you would like to ensure the authenticity of the server you're talking to. @@ -1643,37 +1967,32 @@ to specify :const:`CERT_REQUIRED` and similarly check the client certificate. by default). Protocol versions -^^^^^^^^^^^^^^^^^ +''''''''''''''''' -SSL version 2 is considered insecure and is therefore dangerous to use. If -you want maximum compatibility between clients and servers, it is recommended -to use :const:`PROTOCOL_SSLv23` as the protocol version and then disable -SSLv2 explicitly using the :data:`SSLContext.options` attribute:: +SSL versions 2 and 3 are considered insecure and are therefore dangerous to +use. If you want maximum compatibility between clients and servers, it is +recommended to use :const:`PROTOCOL_SSLv23` as the protocol version and then +disable SSLv2 and SSLv3 explicitly using the :data:`SSLContext.options` +attribute:: context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) context.options |= ssl.OP_NO_SSLv2 + context.options |= ssl.OP_NO_SSLv3 -The SSL context created above will allow SSLv3 and TLSv1 connections, but -not SSLv2. +The SSL context created above will only allow TLSv1 and later (if +supported by your system) connections. Cipher selection -^^^^^^^^^^^^^^^^ +'''''''''''''''' If you have advanced security requirements, fine-tuning of the ciphers enabled when negotiating a SSL session is possible through the :meth:`SSLContext.set_ciphers` method. Starting from Python 3.2.3, the ssl module disables certain weak ciphers by default, but you may want -to further restrict the cipher choice. For example:: - - context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) - context.set_ciphers('HIGH:!aNULL:!eNULL') - -The ``!aNULL:!eNULL`` part of the cipher spec is necessary to disable ciphers -which don't provide both encryption and authentication. Be sure to read -OpenSSL's documentation about the `cipher list -format <http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT>`_. -If you want to check which ciphers are enabled by a given cipher list, -use the ``openssl ciphers`` command on your system. +to further restrict the cipher choice. Be sure to read OpenSSL's documentation +about the `cipher list format <http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT>`_. +If you want to check which ciphers are enabled by a given cipher list, use the +``openssl ciphers`` command on your system. Multi-processing ^^^^^^^^^^^^^^^^ @@ -1707,10 +2026,10 @@ successful call of :func:`~ssl.RAND_add`, :func:`~ssl.RAND_bytes` or `RFC 4366: Transport Layer Security (TLS) Extensions <http://www.ietf.org/rfc/rfc4366>`_ Blake-Wilson et. al. - `RFC 5246: The Transport Layer Security (TLS) Protocol Version 1.2 <http://www.ietf.org/rfc/rfc5246>`_ + `RFC 5246: The Transport Layer Security (TLS) Protocol Version 1.2 <http://tools.ietf.org/html/rfc5246>`_ T. Dierks et. al. - `RFC 6066: Transport Layer Security (TLS) Extensions <http://www.ietf.org/rfc/rfc6066>`_ + `RFC 6066: Transport Layer Security (TLS) Extensions <http://tools.ietf.org/html/rfc6066>`_ D. Eastlake `IANA TLS: Transport Layer Security (TLS) Parameters <http://www.iana.org/assignments/tls-parameters/tls-parameters.xml>`_ diff --git a/Doc/library/stat.rst b/Doc/library/stat.rst index 24769f689321..845b2ef7daba 100644 --- a/Doc/library/stat.rst +++ b/Doc/library/stat.rst @@ -126,7 +126,7 @@ Example:: if __name__ == '__main__': walktree(sys.argv[1], visitfile) -An additional utility function is provided to covert a file's mode in a human +An additional utility function is provided to convert a file's mode in a human readable string: .. function:: filemode(mode) @@ -399,3 +399,29 @@ The following flags can be used in the *flags* argument of :func:`os.chflags`: The file is a snapshot file. See the \*BSD or Mac OS systems man page :manpage:`chflags(2)` for more information. + +On Windows, the following file attribute constants are available for use when +testing bits in the ``st_file_attributes`` member returned by :func:`os.stat`. +See the `Windows API documentation +<http://msdn.microsoft.com/en-us/library/windows/desktop/gg258117.aspx>`_ +for more detail on the meaning of these constants. + +.. data:: FILE_ATTRIBUTE_ARCHIVE + FILE_ATTRIBUTE_COMPRESSED + FILE_ATTRIBUTE_DEVICE + FILE_ATTRIBUTE_DIRECTORY + FILE_ATTRIBUTE_ENCRYPTED + FILE_ATTRIBUTE_HIDDEN + FILE_ATTRIBUTE_INTEGRITY_STREAM + FILE_ATTRIBUTE_NORMAL + FILE_ATTRIBUTE_NOT_CONTENT_INDEXED + FILE_ATTRIBUTE_NO_SCRUB_DATA + FILE_ATTRIBUTE_OFFLINE + FILE_ATTRIBUTE_READONLY + FILE_ATTRIBUTE_REPARSE_POINT + FILE_ATTRIBUTE_SPARSE_FILE + FILE_ATTRIBUTE_SYSTEM + FILE_ATTRIBUTE_TEMPORARY + FILE_ATTRIBUTE_VIRTUAL + + .. versionadded:: 3.5 diff --git a/Doc/library/statistics.rst b/Doc/library/statistics.rst index e6c5959d2c5d..0c9d88c8de3f 100644 --- a/Doc/library/statistics.rst +++ b/Doc/library/statistics.rst @@ -20,6 +20,16 @@ This module provides functions for calculating mathematical statistics of numeric (:class:`Real`-valued) data. +.. note:: + + Unless explicitly noted otherwise, these functions support :class:`int`, + :class:`float`, :class:`decimal.Decimal` and :class:`fractions.Fraction`. + Behaviour with other types (whether in the numeric tower or not) is + currently unsupported. Mixed types are also undefined and + implementation-dependent. If your input data consists of mixed types, + you may be able to use :func:`map` to ensure a consistent result, e.g. + ``map(float, input_data)``. + Averages and measures of central location ----------------------------------------- @@ -216,7 +226,7 @@ However, for reading convenience, most of the examples show sorted sequences. * Calculating the `median <http://www.ualberta.ca/~opscan/median.html>`_. * The `SSMEDIAN - <https://projects.gnome.org/gnumeric/doc/gnumeric-function-SSMEDIAN.shtml>`_ + <https://help.gnome.org/users/gnumeric/stable/gnumeric.html#gnumeric-function-SSMEDIAN>`_ function in the Gnome Gnumeric spreadsheet, including `this discussion <https://mail.gnome.org/archives/gnumeric-list/2011-April/msg00018.html>`_. diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 24c915523605..55f53513f3b6 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -269,8 +269,8 @@ the same rule. [2]_ The constructors :func:`int`, :func:`float`, and :func:`complex` can be used to produce numbers of a specific type. All numeric types (except complex) support the following operations, sorted by -ascending priority (operations in the same box have the same priority; all -numeric operations have a higher priority than comparison operations): +ascending priority (all numeric operations have a higher priority than +comparison operations): +---------------------+---------------------------------+---------+--------------------+ | Operation | Result | Notes | Full documentation | @@ -354,7 +354,7 @@ Notes: The numeric literals accepted include the digits ``0`` to ``9`` or any Unicode equivalent (code points with the ``Nd`` property). - See http://www.unicode.org/Public/6.0.0/ucd/extracted/DerivedNumericType.txt + See http://www.unicode.org/Public/7.0.0/ucd/extracted/DerivedNumericType.txt for a complete list of code points with the ``Nd`` property. @@ -404,8 +404,7 @@ The priorities of the binary bitwise operations are all lower than the numeric operations and higher than the comparisons; the unary operation ``~`` has the same priority as the other unary numeric operations (``+`` and ``-``). -This table lists the bitwise operations sorted in ascending priority -(operations in the same box have the same priority): +This table lists the bitwise operations sorted in ascending priority: +------------+--------------------------------+----------+ | Operation | Result | Notes | @@ -444,7 +443,7 @@ Additional Methods on Integer Types ----------------------------------- The int type implements the :class:`numbers.Integral` :term:`abstract base -class`. In addition, it provides one more method: +class`. In addition, it provides a few more methods: .. method:: int.bit_length() @@ -820,10 +819,10 @@ both mutable and immutable. The :class:`collections.abc.Sequence` ABC is provided to make it easier to correctly implement these operations on custom sequence types. -This table lists the sequence operations sorted in ascending priority -(operations in the same box have the same priority). In the table, *s* and *t* -are sequences of the same type, *n*, *i*, *j* and *k* are integers and *x* is -an arbitrary object that meets any type and value restrictions imposed by *s*. +This table lists the sequence operations sorted in ascending priority. In the +table, *s* and *t* are sequences of the same type, *n*, *i*, *j* and *k* are +integers and *x* is an arbitrary object that meets any type and value +restrictions imposed by *s*. The ``in`` and ``not in`` operations have the same priorities as the comparison operations. The ``+`` (concatenation) and ``*`` (repetition) @@ -1493,7 +1492,9 @@ expression support in the :mod:`re` module). .. method:: str.center(width[, fillchar]) Return centered in a string of length *width*. Padding is done using the - specified *fillchar* (default is a space). + specified *fillchar* (default is an ASCII space). The original string is + returned if *width* is less than or equal to ``len(s)``. + .. method:: str.count(sub[, start[, end]]) @@ -1511,7 +1512,7 @@ expression support in the :mod:`re` module). a :exc:`UnicodeError`. Other possible values are ``'ignore'``, ``'replace'``, ``'xmlcharrefreplace'``, ``'backslashreplace'`` and any other name registered via - :func:`codecs.register_error`, see section :ref:`codec-base-classes`. For a + :func:`codecs.register_error`, see section :ref:`error-handlers`. For a list of possible encodings, see section :ref:`standard-encodings`. .. versionchanged:: 3.1 @@ -1583,7 +1584,7 @@ expression support in the :mod:`re` module). .. method:: str.format_map(mapping) Similar to ``str.format(**mapping)``, except that ``mapping`` is - used directly and not copied to a :class:`dict` . This is useful + used directly and not copied to a :class:`dict`. This is useful if for example ``mapping`` is a dict subclass: >>> class Default(dict): @@ -1598,7 +1599,8 @@ expression support in the :mod:`re` module). .. method:: str.index(sub[, start[, end]]) - Like :meth:`find`, but raise :exc:`ValueError` when the substring is not found. + Like :meth:`~str.find`, but raise :exc:`ValueError` when the substring is + not found. .. method:: str.isalnum() @@ -1701,9 +1703,9 @@ expression support in the :mod:`re` module). .. method:: str.ljust(width[, fillchar]) - Return the string left justified in a string of length *width*. Padding is done - using the specified *fillchar* (default is a space). The original string is - returned if *width* is less than or equal to ``len(s)``. + Return the string left justified in a string of length *width*. Padding is + done using the specified *fillchar* (default is an ASCII space). The + original string is returned if *width* is less than or equal to ``len(s)``. .. method:: str.lower() @@ -1720,7 +1722,7 @@ expression support in the :mod:`re` module). Return a copy of the string with leading characters removed. The *chars* argument is a string specifying the set of characters to be removed. If omitted or ``None``, the *chars* argument defaults to removing whitespace. The *chars* - argument is not a prefix; rather, all combinations of its values are stripped: + argument is not a prefix; rather, all combinations of its values are stripped:: >>> ' spacious '.lstrip() 'spacious ' @@ -1773,9 +1775,9 @@ expression support in the :mod:`re` module). .. method:: str.rjust(width[, fillchar]) - Return the string right justified in a string of length *width*. Padding is done - using the specified *fillchar* (default is a space). The original string is - returned if *width* is less than or equal to ``len(s)``. + Return the string right justified in a string of length *width*. Padding is + done using the specified *fillchar* (default is an ASCII space). The + original string is returned if *width* is less than or equal to ``len(s)``. .. method:: str.rpartition(sep) @@ -1800,7 +1802,7 @@ expression support in the :mod:`re` module). Return a copy of the string with trailing characters removed. The *chars* argument is a string specifying the set of characters to be removed. If omitted or ``None``, the *chars* argument defaults to removing whitespace. The *chars* - argument is not a suffix; rather, all combinations of its values are stripped: + argument is not a suffix; rather, all combinations of its values are stripped:: >>> ' spacious '.rstrip() ' spacious' @@ -1822,6 +1824,15 @@ expression support in the :mod:`re` module). (for example, ``'1<>2<>3'.split('<>')`` returns ``['1', '2', '3']``). Splitting an empty string with a specified separator returns ``['']``. + For example:: + + >>> '1,2,3'.split(',') + ['1', '2', '3'] + >>> '1,2,3'.split(',', maxsplit=1) + ['1', '2,3'] + >>> '1,2,,3,'.split(',') + ['1', '2', '', '3', ''] + If *sep* is not specified or is ``None``, a different splitting algorithm is applied: runs of consecutive whitespace are regarded as a single separator, and the result will contain no empty strings at the start or end if the @@ -1829,8 +1840,14 @@ expression support in the :mod:`re` module). string or a string consisting of just whitespace with a ``None`` separator returns ``[]``. - For example, ``' 1 2 3 '.split()`` returns ``['1', '2', '3']``, and - ``' 1 2 3 '.split(None, 1)`` returns ``['1', '2 3 ']``. + For example:: + + >>> '1 2 3'.split() + ['1', '2', '3'] + >>> '1 2 3'.split(maxsplit=1) + ['1', '2 3'] + >>> ' 1 2 3 '.split() + ['1', '2', '3'] .. index:: @@ -1843,13 +1860,28 @@ expression support in the :mod:`re` module). Line breaks are not included in the resulting list unless *keepends* is given and true. - For example, ``'ab c\n\nde fg\rkl\r\n'.splitlines()`` returns - ``['ab c', '', 'de fg', 'kl']``, while the same call with ``splitlines(True)`` - returns ``['ab c\n', '\n', 'de fg\r', 'kl\r\n']``. + For example:: + + >>> 'ab c\n\nde fg\rkl\r\n'.splitlines() + ['ab c', '', 'de fg', 'kl'] + >>> 'ab c\n\nde fg\rkl\r\n'.splitlines(keepends=True) + ['ab c\n', '\n', 'de fg\r', 'kl\r\n'] Unlike :meth:`~str.split` when a delimiter string *sep* is given, this method returns an empty list for the empty string, and a terminal line - break does not result in an extra line. + break does not result in an extra line:: + + >>> "".splitlines() + [] + >>> "One line\n".splitlines() + ['One line'] + + For comparison, ``split('\n')`` gives:: + + >>> ''.split('\n') + [''] + >>> 'Two lines\n'.split('\n') + ['Two lines', ''] .. method:: str.startswith(prefix[, start[, end]]) @@ -1866,7 +1898,7 @@ expression support in the :mod:`re` module). The *chars* argument is a string specifying the set of characters to be removed. If omitted or ``None``, the *chars* argument defaults to removing whitespace. The *chars* argument is not a prefix or suffix; rather, all combinations of its - values are stripped: + values are stripped:: >>> ' spacious '.strip() 'spacious' @@ -1886,6 +1918,11 @@ expression support in the :mod:`re` module). Return a titlecased version of the string where words start with an uppercase character and the remaining characters are lowercase. + For example:: + + >>> 'Hello world'.title() + 'Hello World' + The algorithm uses a simple language-independent definition of a word as groups of consecutive letters. The definition works in many contexts but it means that apostrophes in contractions and possessives form word @@ -1938,9 +1975,18 @@ expression support in the :mod:`re` module). .. method:: str.zfill(width) - Return the numeric string left filled with zeros in a string of length - *width*. A sign prefix is handled correctly. The original string is - returned if *width* is less than or equal to ``len(s)``. + Return a copy of the string left filled with ASCII ``'0'`` digits to + make a string of length *width*. A leading sign prefix (``'+'``/``'-'`` + is handled by inserting the padding *after* the sign character rather + than before. The original string is returned if *width* is less than + or equal to ``len(s)``. + + For example:: + + >>> "42".zfill(5) + '00042' + >>> "-42".zfill(5) + '-0042' @@ -2198,16 +2244,28 @@ other ways: Also see the :ref:`bytes <func-bytes>` built-in. -Since bytes objects are sequences of integers, for a bytes object *b*, -``b[0]`` will be an integer, while ``b[0:1]`` will be a bytes object of -length 1. (This contrasts with text strings, where both indexing and -slicing will produce a string of length 1) +Since 2 hexadecimal digits correspond precisely to a single byte, hexadecimal +numbers are a commonly used format for describing binary data. Accordingly, +the bytes type has an additional class method to read data in that format: + +.. classmethod:: bytes.fromhex(string) + + This :class:`bytes` class method returns a bytes object, decoding the + given string object. The string must contain two hexadecimal digits per + byte, with ASCII spaces being ignored. + + >>> bytes.fromhex('2Ef0 F1f2 ') + b'.\xf0\xf1\xf2' + +Since bytes objects are sequences of integers (akin to a tuple), for a bytes +object *b*, ``b[0]`` will be an integer, while ``b[0:1]`` will be a bytes +object of length 1. (This contrasts with text strings, where both indexing +and slicing will produce a string of length 1) The representation of bytes objects uses the literal format (``b'...'``) since it is often more useful than e.g. ``bytes([46, 46, 46])``. You can always convert a bytes object into a list of integers using ``list(b)``. - .. note:: For Python 2.x users: In the Python 2.x series, a variety of implicit conversions between 8-bit strings (the closest thing 2.x offers to a @@ -2241,6 +2299,29 @@ common bytes and bytearray operations described in :ref:`bytes-methods`. Also see the :ref:`bytearray <func-bytearray>` built-in. +Since 2 hexadecimal digits correspond precisely to a single byte, hexadecimal +numbers are a commonly used format for describing binary data. Accordingly, +the bytearray type has an additional class method to read data in that format: + +.. classmethod:: bytearray.fromhex(string) + + This :class:`bytearray` class method returns bytearray object, decoding + the given string object. The string must contain two hexadecimal digits + per byte, with ASCII spaces being ignored. + + >>> bytearray.fromhex('2Ef0 F1f2 ') + bytearray(b'.\xf0\xf1\xf2') + +Since bytearray objects are sequences of integers (akin to a list), for a +bytearray object *b*, ``b[0]`` will be an integer, while ``b[0:1]`` will be +a bytearray object of length 1. (This contrasts with text strings, where +both indexing and slicing will produce a string of length 1) + +The representation of bytearray objects uses the bytes literal format +(``bytearray(b'...')``) since it is often more useful than e.g. +``bytearray([46, 46, 46])``. You can always convert a bytearray object into +a list of integers using ``list(b)``. + .. _bytes-methods: @@ -2252,25 +2333,10 @@ Bytes and Bytearray Operations Both bytes and bytearray objects support the :ref:`common <typesseq-common>` sequence operations. They interoperate not just with operands of the same -type, but with any object that supports the -:ref:`buffer protocol <bufferobjects>`. Due to this flexibility, they can be +type, but with any :term:`bytes-like object`. Due to this flexibility, they can be freely mixed in operations without causing errors. However, the return type of the result may depend on the order of operands. -Due to the common use of ASCII text as the basis for binary protocols, bytes -and bytearray objects provide almost all methods found on text strings, with -the exceptions of: - -* :meth:`str.encode` (which converts text strings to bytes objects) -* :meth:`str.format` and :meth:`str.format_map` (which are used to format - text for display to users) -* :meth:`str.isidentifier`, :meth:`str.isnumeric`, :meth:`str.isdecimal`, - :meth:`str.isprintable` (which are used to check various properties of - text strings which are not typically applicable to binary protocols). - -All other string methods are supported, although sometimes with slight -differences in functionality and semantics (as described below). - .. note:: The methods on bytes and bytearray objects don't accept strings as their @@ -2285,25 +2351,30 @@ differences in functionality and semantics (as described below). a = b"abc" b = a.replace(b"a", b"f") -Whenever a bytes or bytearray method needs to interpret the bytes as -characters (e.g. the :meth:`is...` methods, :meth:`split`, :meth:`strip`), -the ASCII character set is assumed (text strings use Unicode semantics). +Some bytes and bytearray operations assume the use of ASCII compatible +binary formats, and hence should be avoided when working with arbitrary +binary data. These restrictions are covered below. .. note:: - Using these ASCII based methods to manipulate binary data that is not + Using these ASCII based operations to manipulate binary data that is not stored in an ASCII based format may lead to data corruption. -The search operations (:keyword:`in`, :meth:`count`, :meth:`find`, -:meth:`index`, :meth:`rfind` and :meth:`rindex`) all accept both integers -in the range 0 to 255 (inclusive) as well as bytes and byte array sequences. +The following methods on bytes and bytearray objects can be used with +arbitrary binary data. -.. versionchanged:: 3.3 - All of the search methods also accept an integer in the range 0 to 255 - (inclusive) as their first argument. +.. method:: bytes.count(sub[, start[, end]]) + bytearray.count(sub[, start[, end]]) + + Return the number of non-overlapping occurrences of subsequence *sub* in + the range [*start*, *end*]. Optional arguments *start* and *end* are + interpreted as in slice notation. + + The subsequence to search for may be any :term:`bytes-like object` or an + integer in the range 0 to 255. + .. versionchanged:: 3.3 + Also accept an integer in the range 0 to 255 as the subsequence. -Each bytes and bytearray instance provides a :meth:`~bytes.decode` convenience -method that is the inverse of :meth:`str.encode`: .. method:: bytes.decode(encoding="utf-8", errors="strict") bytearray.decode(encoding="utf-8", errors="strict") @@ -2313,40 +2384,178 @@ method that is the inverse of :meth:`str.encode`: error handling scheme. The default for *errors* is ``'strict'``, meaning that encoding errors raise a :exc:`UnicodeError`. Other possible values are ``'ignore'``, ``'replace'`` and any other name registered via - :func:`codecs.register_error`, see section :ref:`codec-base-classes`. For a + :func:`codecs.register_error`, see section :ref:`error-handlers`. For a list of possible encodings, see section :ref:`standard-encodings`. + .. note:: + + Passing the *encoding* argument to :class:`str` allows decoding any + :term:`bytes-like object` directly, without needing to make a temporary + bytes or bytearray object. + .. versionchanged:: 3.1 Added support for keyword arguments. -Since 2 hexadecimal digits correspond precisely to a single byte, hexadecimal -numbers are a commonly used format for describing binary data. Accordingly, -the bytes and bytearray types have an additional class method to read data in -that format: -.. classmethod:: bytes.fromhex(string) - bytearray.fromhex(string) +.. method:: bytes.endswith(suffix[, start[, end]]) + bytearray.endswith(suffix[, start[, end]]) - This :class:`bytes` class method returns a bytes or bytearray object, - decoding the given string object. The string must contain two hexadecimal - digits per byte, spaces are ignored. + Return ``True`` if the binary data ends with the specified *suffix*, + otherwise return ``False``. *suffix* can also be a tuple of suffixes to + look for. With optional *start*, test beginning at that position. With + optional *end*, stop comparing at that position. - >>> bytes.fromhex('2Ef0 F1f2 ') - b'.\xf0\xf1\xf2' + The suffix(es) to search for may be any :term:`bytes-like object`. + + +.. method:: bytes.find(sub[, start[, end]]) + bytearray.find(sub[, start[, end]]) + + Return the lowest index in the data where the subsequence *sub* is found, + such that *sub* is contained in the slice ``s[start:end]``. Optional + arguments *start* and *end* are interpreted as in slice notation. Return + ``-1`` if *sub* is not found. + + The subsequence to search for may be any :term:`bytes-like object` or an + integer in the range 0 to 255. + + .. note:: + + The :meth:`~bytes.find` method should be used only if you need to know the + position of *sub*. To check if *sub* is a substring or not, use the + :keyword:`in` operator:: + + >>> b'Py' in b'Python' + True + + .. versionchanged:: 3.3 + Also accept an integer in the range 0 to 255 as the subsequence. + + +.. method:: bytes.index(sub[, start[, end]]) + bytearray.index(sub[, start[, end]]) + + Like :meth:`~bytes.find`, but raise :exc:`ValueError` when the + subsequence is not found. + + The subsequence to search for may be any :term:`bytes-like object` or an + integer in the range 0 to 255. + + .. versionchanged:: 3.3 + Also accept an integer in the range 0 to 255 as the subsequence. + + +.. method:: bytes.join(iterable) + bytearray.join(iterable) + + Return a bytes or bytearray object which is the concatenation of the + binary data sequences in the :term:`iterable` *iterable*. A + :exc:`TypeError` will be raised if there are any values in *iterable* + that are note :term:`bytes-like objects <bytes-like object>`, including + :class:`str` objects. The separator between elements is the contents + of the bytes or bytearray object providing this method. + + +.. staticmethod:: bytes.maketrans(from, to) + bytearray.maketrans(from, to) + + This static method returns a translation table usable for + :meth:`bytes.translate` that will map each character in *from* into the + character at the same position in *to*; *from* and *to* must both be + :term:`bytes-like objects <bytes-like object>` and have the same length. + + .. versionadded:: 3.1 + + +.. method:: bytes.partition(sep) + bytearray.partition(sep) + + Split the sequence at the first occurrence of *sep*, and return a 3-tuple + containing the part before the separator, the separator, and the part + after the separator. If the separator is not found, return a 3-tuple + containing a copy of the original sequence, followed by two empty bytes or + bytearray objects. + + The separator to search for may be any :term:`bytes-like object`. + + +.. method:: bytes.replace(old, new[, count]) + bytearray.replace(old, new[, count]) + + Return a copy of the sequence with all occurrences of subsequence *old* + replaced by *new*. If the optional argument *count* is given, only the + first *count* occurrences are replaced. + + The subsequence to search for and its replacement may be any + :term:`bytes-like object`. + + .. note:: + + The bytearray version of this method does *not* operate in place - it + always produces a new object, even if no changes were made. + + +.. method:: bytes.rfind(sub[, start[, end]]) + bytearray.rfind(sub[, start[, end]]) + + Return the highest index in the sequence where the subsequence *sub* is + found, such that *sub* is contained within ``s[start:end]``. Optional + arguments *start* and *end* are interpreted as in slice notation. Return + ``-1`` on failure. + + The subsequence to search for may be any :term:`bytes-like object` or an + integer in the range 0 to 255. + + .. versionchanged:: 3.3 + Also accept an integer in the range 0 to 255 as the subsequence. + + +.. method:: bytes.rindex(sub[, start[, end]]) + bytearray.rindex(sub[, start[, end]]) + + Like :meth:`~bytes.rfind` but raises :exc:`ValueError` when the + subsequence *sub* is not found. + + The subsequence to search for may be any :term:`bytes-like object` or an + integer in the range 0 to 255. + + .. versionchanged:: 3.3 + Also accept an integer in the range 0 to 255 as the subsequence. + + +.. method:: bytes.rpartition(sep) + bytearray.rpartition(sep) + + Split the sequence at the last occurrence of *sep*, and return a 3-tuple + containing the part before the separator, the separator, and the part + after the separator. If the separator is not found, return a 3-tuple + containing a copy of the original sequence, followed by two empty bytes or + bytearray objects. + + The separator to search for may be any :term:`bytes-like object`. + + +.. method:: bytes.startswith(prefix[, start[, end]]) + bytearray.startswith(prefix[, start[, end]]) + + Return ``True`` if the binary data starts with the specified *prefix*, + otherwise return ``False``. *prefix* can also be a tuple of prefixes to + look for. With optional *start*, test beginning at that position. With + optional *end*, stop comparing at that position. + The prefix(es) to search for may be any :term:`bytes-like object`. -The maketrans and translate methods differ in semantics from the versions -available on strings: .. method:: bytes.translate(table[, delete]) bytearray.translate(table[, delete]) Return a copy of the bytes or bytearray object where all bytes occurring in - the optional argument *delete* are removed, and the remaining bytes have been - mapped through the given translation table, which must be a bytes object of - length 256. + the optional argument *delete* are removed, and the remaining bytes have + been mapped through the given translation table, which must be a bytes + object of length 256. - You can use the :func:`bytes.maketrans` method to create a translation table. + You can use the :func:`bytes.maketrans` method to create a translation + table. Set the *table* argument to ``None`` for translations that only delete characters:: @@ -2355,16 +2564,689 @@ available on strings: b'rd ths shrt txt' -.. staticmethod:: bytes.maketrans(from, to) - bytearray.maketrans(from, to) +The following methods on bytes and bytearray objects have default behaviours +that assume the use of ASCII compatible binary formats, but can still be used +with arbitrary binary data by passing appropriate arguments. Note that all of +the bytearray methods in this section do *not* operate in place, and instead +produce new objects. - This static method returns a translation table usable for - :meth:`bytes.translate` that will map each character in *from* into the - character at the same position in *to*; *from* and *to* must be bytes objects - and have the same length. +.. method:: bytes.center(width[, fillbyte]) + bytearray.center(width[, fillbyte]) - .. versionadded:: 3.1 + Return a copy of the object centered in a sequence of length *width*. + Padding is done using the specified *fillbyte* (default is an ASCII + space). For :class:`bytes` objects, the original sequence is returned if + *width* is less than or equal to ``len(s)``. + + .. note:: + + The bytearray version of this method does *not* operate in place - + it always produces a new object, even if no changes were made. + + +.. method:: bytes.ljust(width[, fillbyte]) + bytearray.ljust(width[, fillbyte]) + + Return a copy of the object left justified in a sequence of length *width*. + Padding is done using the specified *fillbyte* (default is an ASCII + space). For :class:`bytes` objects, the original sequence is returned if + *width* is less than or equal to ``len(s)``. + + .. note:: + + The bytearray version of this method does *not* operate in place - + it always produces a new object, even if no changes were made. + + +.. method:: bytes.lstrip([chars]) + bytearray.lstrip([chars]) + + Return a copy of the sequence with specified leading bytes removed. The + *chars* argument is a binary sequence specifying the set of byte values to + be removed - the name refers to the fact this method is usually used with + ASCII characters. If omitted or ``None``, the *chars* argument defaults + to removing ASCII whitespace. The *chars* argument is not a prefix; + rather, all combinations of its values are stripped:: + + >>> b' spacious '.lstrip() + b'spacious ' + >>> b'www.example.com'.lstrip(b'cmowz.') + b'example.com' + + The binary sequence of byte values to remove may be any + :term:`bytes-like object`. + + .. note:: + + The bytearray version of this method does *not* operate in place - + it always produces a new object, even if no changes were made. + + +.. method:: bytes.rjust(width[, fillbyte]) + bytearray.rjust(width[, fillbyte]) + + Return a copy of the object right justified in a sequence of length *width*. + Padding is done using the specified *fillbyte* (default is an ASCII + space). For :class:`bytes` objects, the original sequence is returned if + *width* is less than or equal to ``len(s)``. + + .. note:: + + The bytearray version of this method does *not* operate in place - + it always produces a new object, even if no changes were made. + + +.. method:: bytes.rsplit(sep=None, maxsplit=-1) + bytearray.rsplit(sep=None, maxsplit=-1) + + Split the binary sequence into subsequences of the same type, using *sep* + as the delimiter string. If *maxsplit* is given, at most *maxsplit* splits + are done, the *rightmost* ones. If *sep* is not specified or ``None``, + any subsequence consisting solely of ASCII whitespace is a separator. + Except for splitting from the right, :meth:`rsplit` behaves like + :meth:`split` which is described in detail below. + + +.. method:: bytes.rstrip([chars]) + bytearray.rstrip([chars]) + + Return a copy of the sequence with specified trailing bytes removed. The + *chars* argument is a binary sequence specifying the set of byte values to + be removed - the name refers to the fact this method is usually used with + ASCII characters. If omitted or ``None``, the *chars* argument defaults to + removing ASCII whitespace. The *chars* argument is not a suffix; rather, + all combinations of its values are stripped:: + + >>> b' spacious '.rstrip() + b' spacious' + >>> b'mississippi'.rstrip(b'ipz') + b'mississ' + + The binary sequence of byte values to remove may be any + :term:`bytes-like object`. + + .. note:: + + The bytearray version of this method does *not* operate in place - + it always produces a new object, even if no changes were made. + + +.. method:: bytes.split(sep=None, maxsplit=-1) + bytearray.split(sep=None, maxsplit=-1) + + Split the binary sequence into subsequences of the same type, using *sep* + as the delimiter string. If *maxsplit* is given and non-negative, at most + *maxsplit* splits are done (thus, the list will have at most ``maxsplit+1`` + elements). If *maxsplit* is not specified or is ``-1``, then there is no + limit on the number of splits (all possible splits are made). + + If *sep* is given, consecutive delimiters are not grouped together and are + deemed to delimit empty subsequences (for example, ``b'1,,2'.split(b',')`` + returns ``[b'1', b'', b'2']``). The *sep* argument may consist of a + multibyte sequence (for example, ``b'1<>2<>3'.split(b'<>')`` returns + ``[b'1', b'2', b'3']``). Splitting an empty sequence with a specified + separator returns ``[b'']`` or ``[bytearray(b'')]`` depending on the type + of object being split. The *sep* argument may be any + :term:`bytes-like object`. + + For example:: + + >>> b'1,2,3'.split(b',') + [b'1', b'2', b'3'] + >>> b'1,2,3'.split(b',', maxsplit=1) + [b'1', b'2,3'] + >>> b'1,2,,3,'.split(b',') + [b'1', b'2', b'', b'3', b''] + + If *sep* is not specified or is ``None``, a different splitting algorithm + is applied: runs of consecutive ASCII whitespace are regarded as a single + separator, and the result will contain no empty strings at the start or + end if the sequence has leading or trailing whitespace. Consequently, + splitting an empty sequence or a sequence consisting solely of ASCII + whitespace without a specified separator returns ``[]``. + + For example:: + + + >>> b'1 2 3'.split() + [b'1', b'2', b'3'] + >>> b'1 2 3'.split(maxsplit=1) + [b'1', b'2 3'] + >>> b' 1 2 3 '.split() + [b'1', b'2', b'3'] + + +.. method:: bytes.strip([chars]) + bytearray.strip([chars]) + + Return a copy of the sequence with specified leading and trailing bytes + removed. The *chars* argument is a binary sequence specifying the set of + byte values to be removed - the name refers to the fact this method is + usually used with ASCII characters. If omitted or ``None``, the *chars* + argument defaults to removing ASCII whitespace. The *chars* argument is + not a prefix or suffix; rather, all combinations of its values are + stripped:: + + >>> b' spacious '.strip() + b'spacious' + >>> b'www.example.com'.strip(b'cmowz.') + b'example' + + The binary sequence of byte values to remove may be any + :term:`bytes-like object`. + + .. note:: + + The bytearray version of this method does *not* operate in place - + it always produces a new object, even if no changes were made. + + +The following methods on bytes and bytearray objects assume the use of ASCII +compatible binary formats and should not be applied to arbitrary binary data. +Note that all of the bytearray methods in this section do *not* operate in +place, and instead produce new objects. + +.. method:: bytes.capitalize() + bytearray.capitalize() + + Return a copy of the sequence with each byte interpreted as an ASCII + character, and the first byte capitalized and the rest lowercased. + Non-ASCII byte values are passed through unchanged. + + .. note:: + + The bytearray version of this method does *not* operate in place - it + always produces a new object, even if no changes were made. + + +.. method:: bytes.expandtabs(tabsize=8) + bytearray.expandtabs(tabsize=8) + + Return a copy of the sequence where all ASCII tab characters are replaced + by one or more ASCII spaces, depending on the current column and the given + tab size. Tab positions occur every *tabsize* bytes (default is 8, + giving tab positions at columns 0, 8, 16 and so on). To expand the + sequence, the current column is set to zero and the sequence is examined + byte by byte. If the byte is an ASCII tab character (``b'\t'``), one or + more space characters are inserted in the result until the current column + is equal to the next tab position. (The tab character itself is not + copied.) If the current byte is an ASCII newline (``b'\n'``) or + carriage return (``b'\r'``), it is copied and the current column is reset + to zero. Any other byte value is copied unchanged and the current column + is incremented by one regardless of how the byte value is represented when + printed:: + + >>> b'01\t012\t0123\t01234'.expandtabs() + b'01 012 0123 01234' + >>> b'01\t012\t0123\t01234'.expandtabs(4) + b'01 012 0123 01234' + + .. note:: + + The bytearray version of this method does *not* operate in place - it + always produces a new object, even if no changes were made. + + +.. method:: bytes.isalnum() + bytearray.isalnum() + + Return true if all bytes in the sequence are alphabetical ASCII characters + or ASCII decimal digits and the sequence is not empty, false otherwise. + Alphabetic ASCII characters are those byte values in the sequence + ``b'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'``. ASCII decimal + digits are those byte values in the sequence ``b'0123456789'``. + + For example:: + + >>> b'ABCabc1'.isalnum() + True + >>> b'ABC abc1'.isalnum() + False + + +.. method:: bytes.isalpha() + bytearray.isalpha() + + Return true if all bytes in the sequence are alphabetic ASCII characters + and the sequence is not empty, false otherwise. Alphabetic ASCII + characters are those byte values in the sequence + ``b'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'``. + + For example:: + + >>> b'ABCabc'.isalpha() + True + >>> b'ABCabc1'.isalpha() + False + + +.. method:: bytes.isdigit() + bytearray.isdigit() + + Return true if all bytes in the sequence are ASCII decimal digits + and the sequence is not empty, false otherwise. ASCII decimal digits are + those byte values in the sequence ``b'0123456789'``. + + For example:: + + >>> b'1234'.isdigit() + True + >>> b'1.23'.isdigit() + False + + +.. method:: bytes.islower() + bytearray.islower() + + Return true if there is at least one lowercase ASCII character + in the sequence and no uppercase ASCII characters, false otherwise. + + For example:: + + >>> b'hello world'.islower() + True + >>> b'Hello world'.islower() + False + + Lowercase ASCII characters are those byte values in the sequence + ``b'abcdefghijklmnopqrstuvwxyz'``. Uppercase ASCII characters + are those byte values in the sequence ``b'ABCDEFGHIJKLMNOPQRSTUVWXYZ'``. + + +.. method:: bytes.isspace() + bytearray.isspace() + + Return true if all bytes in the sequence are ASCII whitespace and the + sequence is not empty, false otherwise. ASCII whitespace characters are + those byte values in the sequence b' \t\n\r\x0b\f' (space, tab, newline, + carriage return, vertical tab, form feed). + + +.. method:: bytes.istitle() + bytearray.istitle() + + Return true if the sequence is ASCII titlecase and the sequence is not + empty, false otherwise. See :meth:`bytes.title` for more details on the + definition of "titlecase". + + For example:: + + >>> b'Hello World'.istitle() + True + >>> b'Hello world'.istitle() + False + + +.. method:: bytes.isupper() + bytearray.isupper() + + Return true if there is at least one lowercase alphabetic ASCII character + in the sequence and no uppercase ASCII characters, false otherwise. + + For example:: + + >>> b'HELLO WORLD'.isupper() + True + >>> b'Hello world'.isupper() + False + + Lowercase ASCII characters are those byte values in the sequence + ``b'abcdefghijklmnopqrstuvwxyz'``. Uppercase ASCII characters + are those byte values in the sequence ``b'ABCDEFGHIJKLMNOPQRSTUVWXYZ'``. + + +.. method:: bytes.lower() + bytearray.lower() + Return a copy of the sequence with all the uppercase ASCII characters + converted to their corresponding lowercase counterpart. + + For example:: + + >>> b'Hello World'.lower() + b'hello world' + + Lowercase ASCII characters are those byte values in the sequence + ``b'abcdefghijklmnopqrstuvwxyz'``. Uppercase ASCII characters + are those byte values in the sequence ``b'ABCDEFGHIJKLMNOPQRSTUVWXYZ'``. + + .. note:: + + The bytearray version of this method does *not* operate in place - it + always produces a new object, even if no changes were made. + + +.. index:: + single: universal newlines; bytes.splitlines method + single: universal newlines; bytearray.splitlines method + +.. method:: bytes.splitlines(keepends=False) + bytearray.splitlines(keepends=False) + + Return a list of the lines in the binary sequence, breaking at ASCII + line boundaries. This method uses the :term:`universal newlines` approach + to splitting lines. Line breaks are not included in the resulting list + unless *keepends* is given and true. + + For example:: + + >>> b'ab c\n\nde fg\rkl\r\n'.splitlines() + [b'ab c', b'', b'de fg', b'kl'] + >>> b'ab c\n\nde fg\rkl\r\n'.splitlines(keepends=True) + [b'ab c\n', b'\n', b'de fg\r', b'kl\r\n'] + + Unlike :meth:`~bytes.split` when a delimiter string *sep* is given, this + method returns an empty list for the empty string, and a terminal line + break does not result in an extra line:: + + >>> b"".split(b'\n'), b"Two lines\n".split(b'\n') + ([b''], [b'Two lines', b'']) + >>> b"".splitlines(), b"One line\n".splitlines() + ([], [b'One line']) + + +.. method:: bytes.swapcase() + bytearray.swapcase() + + Return a copy of the sequence with all the lowercase ASCII characters + converted to their corresponding uppercase counterpart and vice-versa. + + For example:: + + >>> b'Hello World'.swapcase() + b'hELLO wORLD' + + Lowercase ASCII characters are those byte values in the sequence + ``b'abcdefghijklmnopqrstuvwxyz'``. Uppercase ASCII characters + are those byte values in the sequence ``b'ABCDEFGHIJKLMNOPQRSTUVWXYZ'``. + + Unlike :func:`str.swapcase()`, it is always the case that + ``bin.swapcase().swapcase() == bin`` for the binary versions. Case + conversions are symmetrical in ASCII, even though that is not generally + true for arbitrary Unicode code points. + + .. note:: + + The bytearray version of this method does *not* operate in place - it + always produces a new object, even if no changes were made. + + +.. method:: bytes.title() + bytearray.title() + + Return a titlecased version of the binary sequence where words start with + an uppercase ASCII character and the remaining characters are lowercase. + Uncased byte values are left unmodified. + + For example:: + + >>> b'Hello world'.title() + b'Hello World' + + Lowercase ASCII characters are those byte values in the sequence + ``b'abcdefghijklmnopqrstuvwxyz'``. Uppercase ASCII characters + are those byte values in the sequence ``b'ABCDEFGHIJKLMNOPQRSTUVWXYZ'``. + All other byte values are uncased. + + The algorithm uses a simple language-independent definition of a word as + groups of consecutive letters. The definition works in many contexts but + it means that apostrophes in contractions and possessives form word + boundaries, which may not be the desired result:: + + >>> b"they're bill's friends from the UK".title() + b"They'Re Bill'S Friends From The Uk" + + A workaround for apostrophes can be constructed using regular expressions:: + + >>> import re + >>> def titlecase(s): + ... return re.sub(rb"[A-Za-z]+('[A-Za-z]+)?", + ... lambda mo: mo.group(0)[0:1].upper() + + ... mo.group(0)[1:].lower(), + ... s) + ... + >>> titlecase(b"they're bill's friends.") + b"They're Bill's Friends." + + .. note:: + + The bytearray version of this method does *not* operate in place - it + always produces a new object, even if no changes were made. + + +.. method:: bytes.upper() + bytearray.upper() + + Return a copy of the sequence with all the lowercase ASCII characters + converted to their corresponding uppercase counterpart. + + For example:: + + >>> b'Hello World'.upper() + b'HELLO WORLD' + + Lowercase ASCII characters are those byte values in the sequence + ``b'abcdefghijklmnopqrstuvwxyz'``. Uppercase ASCII characters + are those byte values in the sequence ``b'ABCDEFGHIJKLMNOPQRSTUVWXYZ'``. + + .. note:: + + The bytearray version of this method does *not* operate in place - it + always produces a new object, even if no changes were made. + + +.. method:: bytes.zfill(width) + bytearray.zfill(width) + + Return a copy of the sequence left filled with ASCII ``b'0'`` digits to + make a sequence of length *width*. A leading sign prefix (``b'+'``/ + ``b'-'`` is handled by inserting the padding *after* the sign character + rather than before. For :class:`bytes` objects, the original sequence is + returned if *width* is less than or equal to ``len(seq)``. + + For example:: + + >>> b"42".zfill(5) + b'00042' + >>> b"-42".zfill(5) + b'-0042' + + .. note:: + + The bytearray version of this method does *not* operate in place - it + always produces a new object, even if no changes were made. + + +.. _bytes-formatting: + +``printf``-style Bytes Formatting +---------------------------------- + +.. index:: + single: formatting, bytes (%) + single: formatting, bytearray (%) + single: interpolation, bytes (%) + single: interpolation, bytearray (%) + single: bytes; formatting + single: bytearray; formatting + single: bytes; interpolation + single: bytearray; interpolation + single: printf-style formatting + single: sprintf-style formatting + single: % formatting + single: % interpolation + +.. note:: + + The formatting operations described here exhibit a variety of quirks that + lead to a number of common errors (such as failing to display tuples and + dictionaries correctly). If the value being printed may be a tuple or + dictionary, wrap it in a tuple. + +Bytes objects (``bytes``/``bytearray``) have one unique built-in operation: +the ``%`` operator (modulo). +This is also known as the bytes *formatting* or *interpolation* operator. +Given ``format % values`` (where *format* is a bytes object), ``%`` conversion +specifications in *format* are replaced with zero or more elements of *values*. +The effect is similar to using the :c:func:`sprintf` in the C language. + +If *format* requires a single argument, *values* may be a single non-tuple +object. [5]_ Otherwise, *values* must be a tuple with exactly the number of +items specified by the format bytes object, or a single mapping object (for +example, a dictionary). + +A conversion specifier contains two or more characters and has the following +components, which must occur in this order: + +#. The ``'%'`` character, which marks the start of the specifier. + +#. Mapping key (optional), consisting of a parenthesised sequence of characters + (for example, ``(somename)``). + +#. Conversion flags (optional), which affect the result of some conversion + types. + +#. Minimum field width (optional). If specified as an ``'*'`` (asterisk), the + actual width is read from the next element of the tuple in *values*, and the + object to convert comes after the minimum field width and optional precision. + +#. Precision (optional), given as a ``'.'`` (dot) followed by the precision. If + specified as ``'*'`` (an asterisk), the actual precision is read from the next + element of the tuple in *values*, and the value to convert comes after the + precision. + +#. Length modifier (optional). + +#. Conversion type. + +When the right argument is a dictionary (or other mapping type), then the +formats in the bytes object *must* include a parenthesised mapping key into that +dictionary inserted immediately after the ``'%'`` character. The mapping key +selects the value to be formatted from the mapping. For example: + + >>> print(b'%(language)s has %(number)03d quote types.' % + ... {b'language': b"Python", b"number": 2}) + b'Python has 002 quote types.' + +In this case no ``*`` specifiers may occur in a format (since they require a +sequential parameter list). + +The conversion flag characters are: + ++---------+---------------------------------------------------------------------+ +| Flag | Meaning | ++=========+=====================================================================+ +| ``'#'`` | The value conversion will use the "alternate form" (where defined | +| | below). | ++---------+---------------------------------------------------------------------+ +| ``'0'`` | The conversion will be zero padded for numeric values. | ++---------+---------------------------------------------------------------------+ +| ``'-'`` | The converted value is left adjusted (overrides the ``'0'`` | +| | conversion if both are given). | ++---------+---------------------------------------------------------------------+ +| ``' '`` | (a space) A blank should be left before a positive number (or empty | +| | string) produced by a signed conversion. | ++---------+---------------------------------------------------------------------+ +| ``'+'`` | A sign character (``'+'`` or ``'-'``) will precede the conversion | +| | (overrides a "space" flag). | ++---------+---------------------------------------------------------------------+ + +A length modifier (``h``, ``l``, or ``L``) may be present, but is ignored as it +is not necessary for Python -- so e.g. ``%ld`` is identical to ``%d``. + +The conversion types are: + ++------------+-----------------------------------------------------+-------+ +| Conversion | Meaning | Notes | ++============+=====================================================+=======+ +| ``'d'`` | Signed integer decimal. | | ++------------+-----------------------------------------------------+-------+ +| ``'i'`` | Signed integer decimal. | | ++------------+-----------------------------------------------------+-------+ +| ``'o'`` | Signed octal value. | \(1) | ++------------+-----------------------------------------------------+-------+ +| ``'u'`` | Obsolete type -- it is identical to ``'d'``. | \(7) | ++------------+-----------------------------------------------------+-------+ +| ``'x'`` | Signed hexadecimal (lowercase). | \(2) | ++------------+-----------------------------------------------------+-------+ +| ``'X'`` | Signed hexadecimal (uppercase). | \(2) | ++------------+-----------------------------------------------------+-------+ +| ``'e'`` | Floating point exponential format (lowercase). | \(3) | ++------------+-----------------------------------------------------+-------+ +| ``'E'`` | Floating point exponential format (uppercase). | \(3) | ++------------+-----------------------------------------------------+-------+ +| ``'f'`` | Floating point decimal format. | \(3) | ++------------+-----------------------------------------------------+-------+ +| ``'F'`` | Floating point decimal format. | \(3) | ++------------+-----------------------------------------------------+-------+ +| ``'g'`` | Floating point format. Uses lowercase exponential | \(4) | +| | format if exponent is less than -4 or not less than | | +| | precision, decimal format otherwise. | | ++------------+-----------------------------------------------------+-------+ +| ``'G'`` | Floating point format. Uses uppercase exponential | \(4) | +| | format if exponent is less than -4 or not less than | | +| | precision, decimal format otherwise. | | ++------------+-----------------------------------------------------+-------+ +| ``'c'`` | Single byte (accepts integer or single | | +| | byte objects). | | ++------------+-----------------------------------------------------+-------+ +| ``'b'`` | Bytes (any object that follows the | \(5) | +| | :ref:`buffer protocol <bufferobjects>` or has | | +| | :meth:`__bytes__`). | | ++------------+-----------------------------------------------------+-------+ +| ``'s'`` | ``'s'`` is an alias for ``'b'`` and should only | \(6) | +| | be used for Python2/3 code bases. | | ++------------+-----------------------------------------------------+-------+ +| ``'a'`` | Bytes (converts any Python object using | \(5) | +| | ``repr(obj).encode('ascii','backslashreplace)``). | | ++------------+-----------------------------------------------------+-------+ +| ``'%'`` | No argument is converted, results in a ``'%'`` | | +| | character in the result. | | ++------------+-----------------------------------------------------+-------+ + +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. + +(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. + +(3) + The alternate form causes the result to always contain a decimal point, even if + no digits follow it. + + The precision determines the number of digits after the decimal point and + defaults to 6. + +(4) + The alternate form causes the result to always contain a decimal point, and + trailing zeroes are not removed as they would otherwise be. + + The precision determines the number of significant digits before and after the + decimal point and defaults to 6. + +(5) + If precision is ``N``, the output is truncated to ``N`` characters. + +(6) + ``b'%s'`` is deprecated, but will not be removed during the 3.x series. + +(7) + See :pep:`237`. + +.. note:: + + The bytearray version of this method does *not* operate in place - it + always produces a new object, even if no changes were made. + +.. seealso:: :pep:`461`. +.. versionadded:: 3.5 .. _typememoryview: @@ -3031,8 +3913,8 @@ pairs within braces, for example: ``{'jack': 4098, 'sjoerd': 4127}`` or ``{4098: If no positional argument is given, an empty dictionary is created. If a positional argument is given and it is a mapping object, a dictionary is created with the same key-value pairs as the mapping object. Otherwise, - the positional argument must be an :term:`iterator` object. Each item in - the iterable must itself be an iterator with exactly two objects. The + the positional argument must be an :term:`iterable` object. Each item in + the iterable must itself be an iterable with exactly two objects. The first object of each item becomes a key in the new dictionary, and the second object the corresponding value. If a key occurs more than once, the last value for that key becomes the corresponding value in the new @@ -3070,11 +3952,13 @@ pairs within braces, for example: ``{'jack': 4098, 'sjoerd': 4127}`` or ``{4098: Return the item of *d* with key *key*. Raises a :exc:`KeyError` if *key* is not in the map. - If a subclass of dict defines a method :meth:`__missing__`, if the key *key* + .. index:: __missing__() + + If a subclass of dict defines a method :meth:`__missing__` and *key* is not present, the ``d[key]`` operation calls that method with the key *key* as argument. The ``d[key]`` operation then returns or raises whatever is - returned or raised by the ``__missing__(key)`` call if the key is not - present. No other operations or methods invoke :meth:`__missing__`. If + returned or raised by the ``__missing__(key)`` call. + No other operations or methods invoke :meth:`__missing__`. If :meth:`__missing__` is not defined, :exc:`KeyError` is raised. :meth:`__missing__` must be a method; it cannot be an instance variable:: @@ -3088,8 +3972,9 @@ pairs within braces, for example: ``{'jack': 4098, 'sjoerd': 4127}`` or ``{4098: >>> c['red'] 1 - See :class:`collections.Counter` for a complete implementation including - other methods helpful for accumulating and managing tallies. + The example above shows part of the implementation of + :class:`collections.Counter`. A different ``__missing__`` method is used + by :class:`collections.defaultdict`. .. describe:: d[key] = value @@ -3314,8 +4199,8 @@ before the statement body is executed and exited when the statement ends: The exception passed in should never be reraised explicitly - instead, this method should return a false value to indicate that the method completed successfully and does not want to suppress the raised exception. This allows - context management code (such as ``contextlib.nested``) to easily detect whether - or not an :meth:`__exit__` method has actually failed. + context management code to easily detect whether or not an :meth:`__exit__` + method has actually failed. Python defines several context managers to support easy thread synchronisation, prompt closure of files or other objects, and simpler manipulation of the active diff --git a/Doc/library/string.rst b/Doc/library/string.rst index e5bab684dfbc..f9da5fa7ad85 100644 --- a/Doc/library/string.rst +++ b/Doc/library/string.rst @@ -478,10 +478,12 @@ The available presentation types for floating point and decimal values are: | ``'%'`` | Percentage. Multiplies the number by 100 and displays | | | in fixed (``'f'``) format, followed by a percent sign. | +---------+----------------------------------------------------------+ - | None | Similar to ``'g'``, except with at least one digit past | - | | the decimal point and a default precision of 12. This is | - | | intended to match :func:`str`, except you can add the | - | | other format modifiers. | + | None | Similar to ``'g'``, except that fixed-point notation, | + | | when used, has at least one digit past the decimal point.| + | | The default precision is as high as needed to represent | + | | the particular value. The overall effect is to match the | + | | output of :func:`str` as altered by the other format | + | | modifiers. | +---------+----------------------------------------------------------+ diff --git a/Doc/library/stringprep.rst b/Doc/library/stringprep.rst index 47144a6adf79..fc890cb2326a 100644 --- a/Doc/library/stringprep.rst +++ b/Doc/library/stringprep.rst @@ -3,7 +3,6 @@ .. module:: stringprep :synopsis: String preparation, as per RFC 3453 - :deprecated: .. moduleauthor:: Martin v. Löwis <martin@v.loewis.de> .. sectionauthor:: Martin v. Löwis <martin@v.loewis.de> diff --git a/Doc/library/struct.rst b/Doc/library/struct.rst index ec2e1beb03cd..12d4fbcd52bc 100644 --- a/Doc/library/struct.rst +++ b/Doc/library/struct.rst @@ -24,6 +24,14 @@ structs and the intended conversion to/from Python values. or omit implicit pad bytes, use ``standard`` size and alignment instead of ``native`` size and alignment: see :ref:`struct-alignment` for details. +Several :mod:`struct` functions (and methods of :class:`Struct`) take a *buffer* +argument. This refers to objects that implement the :ref:`bufferobjects` and +provide either a readable or read-writable buffer. The most common types used +for that purpose are :class:`bytes` and :class:`bytearray`, but many other types +that can be viewed as an array of bytes implement the buffer protocol, so that +they can be read/filled without additional copying from a :class:`bytes` object. + + Functions and Exceptions ------------------------ @@ -47,7 +55,7 @@ The module defines the following exception and functions: Pack the values *v1*, *v2*, ... according to the format string *fmt* and write the packed bytes into the writable buffer *buffer* starting at - position *offset*. Note that *offset* is a required argument. + position *offset*. Note that *offset* is a required argument. .. function:: unpack(fmt, buffer) diff --git a/Doc/library/subprocess.rst b/Doc/library/subprocess.rst index 7fbe398442ee..49a82bd92a62 100644 --- a/Doc/library/subprocess.rst +++ b/Doc/library/subprocess.rst @@ -9,7 +9,7 @@ The :mod:`subprocess` module allows you to spawn new processes, connect to their input/output/error pipes, and obtain their return codes. This module intends to -replace several other, older modules and functions, such as:: +replace several older modules and functions:: os.system os.spawn* @@ -54,18 +54,12 @@ use cases, the underlying :class:`Popen` interface can be used directly. >>> subprocess.call("exit 1", shell=True) 1 - .. warning:: - - Invoking the system shell with ``shell=True`` can be a security hazard - if combined with untrusted input. See the warning under - :ref:`frequently-used-arguments` for details. - .. note:: - Do not use ``stdout=PIPE`` or ``stderr=PIPE`` with this function. As - the pipes are not being read in the current process, the child - process may block if it generates enough output to a pipe to fill up - the OS pipe buffer. + Do not use ``stdout=PIPE`` or ``stderr=PIPE`` with this + function. The child process will block if it generates enough + output to a pipe to fill up the OS pipe buffer as the pipes are + not being read from. .. versionchanged:: 3.3 *timeout* was added. @@ -99,18 +93,12 @@ use cases, the underlying :class:`Popen` interface can be used directly. ... subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1 - .. warning:: - - Invoking the system shell with ``shell=True`` can be a security hazard - if combined with untrusted input. See the warning under - :ref:`frequently-used-arguments` for details. - .. note:: - Do not use ``stdout=PIPE`` or ``stderr=PIPE`` with this function. As - the pipes are not being read in the current process, the child - process may block if it generates enough output to a pipe to fill up - the OS pipe buffer. + Do not use ``stdout=PIPE`` or ``stderr=PIPE`` with this + function. The child process will block if it generates enough + output to a pipe to fill up the OS pipe buffer as the pipes are + not being read from. .. versionchanged:: 3.3 *timeout* was added. @@ -177,17 +165,12 @@ use cases, the underlying :class:`Popen` interface can be used directly. ... shell=True) 'ls: non_existent_file: No such file or directory\n' - .. warning:: - - Invoking the system shell with ``shell=True`` can be a security hazard - if combined with untrusted input. See the warning under - :ref:`frequently-used-arguments` for details. - .. note:: - Do not use ``stderr=PIPE`` with this function. As the pipe is not being - read in the current process, the child process may block if it - generates enough output to the pipe to fill up the OS pipe buffer. + Do not use ``stdout=PIPE`` or ``stderr=PIPE`` with this + function. The child process will block if it generates enough + output to a pipe to fill up the OS pipe buffer as the pipes are + not being read from. .. versionadded:: 3.1 @@ -210,7 +193,7 @@ use cases, the underlying :class:`Popen` interface can be used directly. Special value that can be used as the *stdin*, *stdout* or *stderr* argument to :class:`Popen` and indicates that a pipe to the standard stream should be - opened. + opened. Most useful with :meth:`Popen.communicate`. .. data:: STDOUT @@ -336,28 +319,9 @@ default values. The arguments that are most commonly needed are: instead of ``locale.getpreferredencoding()``. See the :class:`io.TextIOWrapper` class for more information on this change. - .. warning:: - - Executing shell commands that incorporate unsanitized input from an - untrusted source makes a program vulnerable to `shell injection - <http://en.wikipedia.org/wiki/Shell_injection#Shell_injection>`_, - a serious security flaw which can result in arbitrary command execution. - For this reason, the use of ``shell=True`` is **strongly discouraged** - in cases where the command string is constructed from external input:: - - >>> from subprocess import call - >>> filename = input("What file would you like to display?\n") - What file would you like to display? - non_existent; rm -rf / # - >>> call("cat " + filename, shell=True) # Uh-oh. This will end badly... - - ``shell=False`` disables all shell based features, but does not suffer - from this vulnerability; see the Note in the :class:`Popen` constructor - documentation for helpful hints in getting ``shell=False`` to work. + .. note:: - When using ``shell=True``, :func:`shlex.quote` can be used to properly - escape whitespace and shell metacharacters in strings that are going to - be used to construct shell commands. + Read the `Security Considerations`_ section before using ``shell=True``. These options, along with all of the other options, are described in more detail in the :class:`Popen` constructor documentation. @@ -378,7 +342,7 @@ functions. startupinfo=None, creationflags=0, restore_signals=True, \ start_new_session=False, pass_fds=()) - Execute a child program in a new process. On Unix, the class uses + Execute a child program in a new process. On POSIX, the class uses :meth:`os.execvp`-like behavior to execute the child program. On Windows, the class uses the Windows ``CreateProcess()`` function. The arguments to :class:`Popen` are as follows. @@ -390,7 +354,7 @@ functions. arguments for additional differences from the default behavior. Unless otherwise stated, it is recommended to pass *args* as a sequence. - On Unix, if *args* is a string, the string is interpreted as the name or + On POSIX, if *args* is a string, the string is interpreted as the name or path of the program to execute. However, this can only be done if not passing arguments to the program. @@ -421,7 +385,7 @@ functions. the shell as the program to execute. If *shell* is *True*, it is recommended to pass *args* as a string rather than as a sequence. - On Unix with ``shell=True``, the shell defaults to :file:`/bin/sh`. If + On POSIX with ``shell=True``, the shell defaults to :file:`/bin/sh`. If *args* is a string, the string specifies the command to execute through the shell. This means that the string must be formatted exactly as it would be when typed at the shell prompt. This @@ -438,18 +402,22 @@ functions. into the shell (e.g. :command:`dir` or :command:`copy`). You do not need ``shell=True`` to run a batch file or console-based executable. - .. warning:: + .. note:: + + Read the `Security Considerations`_ section before using ``shell=True``. - Passing ``shell=True`` can be a security hazard if combined with - untrusted input. See the warning under :ref:`frequently-used-arguments` - for details. + *bufsize* will be supplied as the corresponding argument to the + :func:`open` function when creating the stdin/stdout/stderr pipe + file objects: - *bufsize* will be supplied as the corresponding argument to the :meth:`io.open` - function when creating the stdin/stdout/stderr pipe file objects: - :const:`0` means unbuffered (read and write are one system call and can return short), - :const:`1` means line buffered, any other positive value means use a buffer of - approximately that size. A negative bufsize (the default) means - the system default of io.DEFAULT_BUFFER_SIZE will be used. + - :const:`0` means unbuffered (read and write are one + system call and can return short) + - :const:`1` means line buffered + (only usable if ``universal_newlines=True`` i.e., in a text mode) + - any other positive value means use a buffer of approximately that + size + - negative bufsize (the default) means the system default of + io.DEFAULT_BUFFER_SIZE will be used. .. versionchanged:: 3.3.1 *bufsize* now defaults to -1 to enable buffering by default to match the @@ -463,9 +431,9 @@ functions. program to execute specified by *args*. However, the original *args* is still passed to the program. Most programs treat the program specified by *args* as the command name, which can then be different from the program - actually executed. On Unix, the *args* name + actually executed. On POSIX, the *args* name becomes the display name for the executable in utilities such as - :program:`ps`. If ``shell=True``, on Unix the *executable* argument + :program:`ps`. If ``shell=True``, on POSIX the *executable* argument specifies a replacement shell for the default :file:`/bin/sh`. *stdin*, *stdout* and *stderr* specify the executed program's standard input, @@ -481,7 +449,7 @@ functions. If *preexec_fn* is set to a callable object, this object will be called in the child process just before the child is executed. - (Unix only) + (POSIX only) .. warning:: @@ -499,8 +467,8 @@ functions. common use of *preexec_fn* to call os.setsid() in the child. If *close_fds* is true, all file descriptors except :const:`0`, :const:`1` and - :const:`2` will be closed before the child process is executed. (Unix only). - The default varies by platform: Always true on Unix. On Windows it is + :const:`2` will be closed before the child process is executed. (POSIX only). + The default varies by platform: Always true on POSIX. On Windows it is true when *stdin*/*stdout*/*stderr* are :const:`None`, false otherwise. On Windows, if *close_fds* is true then no handles will be inherited by the child process. Note that on Windows, you cannot set *close_fds* to true and @@ -512,7 +480,7 @@ functions. *pass_fds* is an optional sequence of file descriptors to keep open between the parent and child. Providing any *pass_fds* forces - *close_fds* to be :const:`True`. (Unix only) + *close_fds* to be :const:`True`. (POSIX only) .. versionadded:: 3.2 The *pass_fds* parameter was added. @@ -525,13 +493,13 @@ functions. 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. Currently this includes the SIGPIPE, SIGXFZ and SIGXFSZ signals. - (Unix only) + (POSIX only) .. versionchanged:: 3.2 *restore_signals* was added. If *start_new_session* is true the setsid() system call will be made in the - child process prior to the execution of the subprocess. (Unix only) + child process prior to the execution of the subprocess. (POSIX only) .. versionchanged:: 3.2 *start_new_session* was added. @@ -598,14 +566,21 @@ Exceptions defined in this module all inherit from :exc:`SubprocessError`. The :exc:`SubprocessError` base class was added. -Security -^^^^^^^^ +Security Considerations +----------------------- -Unlike some other popen functions, this implementation will never call a -system shell implicitly. This means that all characters, including shell -metacharacters, can safely be passed to child processes. Obviously, if the -shell is invoked explicitly, then it is the application's responsibility to -ensure that all whitespace and metacharacters are quoted appropriately. +Unlike some other popen functions, this implementation will never +implicitly call a system shell. This means that all characters, +including shell metacharacters, can safely be passed to child processes. +If the shell is invoked explicitly, via ``shell=True``, it is the application's +responsibility to ensure that all whitespace and metacharacters are +quoted appropriately to avoid +`shell injection <http://en.wikipedia.org/wiki/Shell_injection#Shell_injection>`_ +vulnerabilities. + +When using ``shell=True``, the :func:`shlex.quote` function can be +used to properly escape whitespace and shell metacharacters in strings +that are going to be used to construct shell commands. Popen Objects @@ -629,16 +604,27 @@ Instances of the :class:`Popen` class have the following methods: :exc:`TimeoutExpired` exception. It is safe to catch this exception and retry the wait. - .. warning:: + .. note:: - This will deadlock when using ``stdout=PIPE`` and/or - ``stderr=PIPE`` and the child process generates enough output to - a pipe such that it blocks waiting for the OS pipe buffer to - accept more data. Use :meth:`communicate` to avoid that. + This will deadlock when using ``stdout=PIPE`` or ``stderr=PIPE`` + and the child process generates enough output to a pipe such that + it blocks waiting for the OS pipe buffer to accept more data. + Use :meth:`Popen.communicate` when using pipes to avoid that. + + .. note:: + + The function is implemented using a busy loop (non-blocking call and + short sleeps). Use the :mod:`asyncio` module for an asynchronous wait: + see :class:`asyncio.create_subprocess_exec`. .. versionchanged:: 3.3 *timeout* was added. + .. deprecated:: 3.4 + + Do not use the *endtime* parameter. It is was unintentionally + exposed in 3.3 but was left undocumented as it was intended to be + private for internal use. Use *timeout* instead. .. method:: Popen.communicate(input=None, timeout=None) @@ -648,7 +634,8 @@ Instances of the :class:`Popen` class have the following methods: ``None``, if no data should be sent to the child. The type of *input* must be bytes or, if *universal_newlines* was ``True``, a string. - :meth:`communicate` returns a tuple ``(stdoutdata, stderrdata)``. + :meth:`communicate` returns a tuple ``(stdout_data, stderr_data)``. + The data will be bytes or, if *universal_newlines* was ``True``, strings. Note that if you want to send data to the process's stdin, you need to create the Popen object with ``stdin=PIPE``. Similarly, to get anything other than @@ -705,31 +692,45 @@ Instances of the :class:`Popen` class have the following methods: The following attributes are also available: -.. warning:: +.. attribute:: Popen.args - Use :meth:`~Popen.communicate` rather than :attr:`.stdin.write <Popen.stdin>`, - :attr:`.stdout.read <Popen.stdout>` or :attr:`.stderr.read <Popen.stderr>` to avoid - deadlocks due to any of the other OS pipe buffers filling up and blocking the - child process. + The *args* argument as it was passed to :class:`Popen` -- a + sequence of program arguments or else a single string. + .. versionadded:: 3.3 .. attribute:: Popen.stdin - If the *stdin* argument was :data:`PIPE`, this attribute is a :term:`file - object` that provides input to the child process. Otherwise, it is ``None``. + If the *stdin* argument was :data:`PIPE`, this attribute is a writeable + stream object as returned by :func:`open`. If the *universal_newlines* + argument was ``True``, the stream is a text stream, otherwise it is a byte + stream. If the *stdin* argument was not :data:`PIPE`, this attribute is + ``None``. .. attribute:: Popen.stdout - If the *stdout* argument was :data:`PIPE`, this attribute is a :term:`file - object` that provides output from the child process. Otherwise, it is ``None``. + If the *stdout* argument was :data:`PIPE`, this attribute is a readable + stream object as returned by :func:`open`. Reading from the stream provides + output from the child process. If the *universal_newlines* argument was + ``True``, the stream is a text stream, otherwise it is a byte stream. If the + *stdout* argument was not :data:`PIPE`, this attribute is ``None``. .. attribute:: Popen.stderr - If the *stderr* argument was :data:`PIPE`, this attribute is a :term:`file - object` that provides error output from the child process. Otherwise, it is - ``None``. + If the *stderr* argument was :data:`PIPE`, this attribute is a readable + stream object as returned by :func:`open`. Reading from the stream provides + error output from the child process. If the *universal_newlines* argument was + ``True``, the stream is a text stream, otherwise it is a byte stream. If the + *stderr* argument was not :data:`PIPE`, this attribute is ``None``. + +.. warning:: + + Use :meth:`~Popen.communicate` rather than :attr:`.stdin.write <Popen.stdin>`, + :attr:`.stdout.read <Popen.stdout>` or :attr:`.stderr.read <Popen.stderr>` to avoid + deadlocks due to any of the other OS pipe buffers filling up and blocking the + child process. .. attribute:: Popen.pid @@ -747,7 +748,7 @@ The following attributes are also available: hasn't terminated yet. A negative value ``-N`` indicates that the child was terminated by signal - ``N`` (Unix only). + ``N`` (POSIX only). Windows Popen Helpers @@ -1019,7 +1020,7 @@ Replacing functions from the :mod:`popen2` module (child_stdout, child_stdin) = popen2.popen2("somestring", bufsize, mode) ==> - p = Popen(["somestring"], shell=True, bufsize=bufsize, + p = Popen("somestring", shell=True, bufsize=bufsize, stdin=PIPE, stdout=PIPE, close_fds=True) (child_stdout, child_stdin) = (p.stdout, p.stdin) @@ -1072,8 +1073,10 @@ handling consistency are valid for these functions. >>> subprocess.getstatusoutput('/bin/junk') (256, 'sh: /bin/junk: not found') - .. versionchanged:: 3.3 - Availability: Unix & Windows + Availability: POSIX & Windows + + .. versionchanged:: 3.3.4 + Windows support added .. function:: getoutput(cmd) @@ -1086,8 +1089,10 @@ handling consistency are valid for these functions. >>> subprocess.getoutput('ls /bin/ls') '/bin/ls' - .. versionchanged:: 3.3 - Availability: Unix & Windows + Availability: POSIX & Windows + + .. versionchanged:: 3.3.4 + Windows support added Notes diff --git a/Doc/library/sunau.rst b/Doc/library/sunau.rst index 15c06b561abc..a94ae08d831f 100644 --- a/Doc/library/sunau.rst +++ b/Doc/library/sunau.rst @@ -251,7 +251,7 @@ AU_write objects, as returned by :func:`.open` above, have the following methods Write audio frames, without correcting *nframes*. .. versionchanged:: 3.4 - Any :term:`bytes-like object`\ s are now accepted. + Any :term:`bytes-like object` is now accepted. .. method:: AU_write.writeframes(data) @@ -259,7 +259,7 @@ AU_write objects, as returned by :func:`.open` above, have the following methods Write audio frames and make sure *nframes* is correct. .. versionchanged:: 3.4 - Any :term:`bytes-like object`\ s are now accepted. + Any :term:`bytes-like object` is now accepted. .. method:: AU_write.close() diff --git a/Doc/library/superseded.rst b/Doc/library/superseded.rst new file mode 100644 index 000000000000..50a5983236e7 --- /dev/null +++ b/Doc/library/superseded.rst @@ -0,0 +1,14 @@ +.. _superseded: + +****************** +Superseded Modules +****************** + +The modules described in this chapter are deprecated and only kept for +backwards compatibility. They have been superseded by other modules. + + +.. toctree:: + + optparse.rst + imp.rst diff --git a/Doc/library/symtable.rst b/Doc/library/symtable.rst index 472a9d6ad180..c04e22e5d24b 100644 --- a/Doc/library/symtable.rst +++ b/Doc/library/symtable.rst @@ -4,6 +4,10 @@ .. module:: symtable :synopsis: Interface to the compiler's internal symbol tables. +**Source code:** :source:`Lib/symtable.py` + +-------------- + .. moduleauthor:: Jeremy Hylton <jeremy@alum.mit.edu> .. sectionauthor:: Benjamin Peterson <benjamin@python.org> diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index ad447a2c9f0a..fa125a0c9644 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -12,11 +12,12 @@ always available. .. data:: abiflags - On POSIX systems where Python is build with the standard ``configure`` + On POSIX systems where Python was built with the standard ``configure`` script, this contains the ABI flags as specified by :pep:`3149`. .. versionadded:: 3.2 + .. data:: argv The list of command line arguments passed to a Python script. ``argv[0]`` is the @@ -227,7 +228,9 @@ always available. installed in :file:`{exec_prefix}/lib/python{X.Y}/lib-dynload`, where *X.Y* is the version number of Python, for example ``3.2``. - .. note:: If a :ref:`virtual environment <venv-def>` is in effect, this + .. note:: + + If a :ref:`virtual environment <venv-def>` is in effect, this value will be changed in ``site.py`` to point to the virtual environment. The value for the Python installation will still be available, via :data:`base_exec_prefix`. @@ -604,7 +607,7 @@ always available. .. versionadded:: 3.2 - .. versionchanged: 3.4 + .. versionchanged:: 3.4 Added *algorithm*, *hash_bits* and *seed_bits* @@ -664,7 +667,7 @@ always available. an underscore, and are not described here. Regardless of its contents, :data:`sys.implementation` will not change during a run of the interpreter, nor between implementation versions. (It may change between Python - language versions, however.) See `PEP 421` for more information. + language versions, however.) See :pep:`421` for more information. .. versionadded:: 3.3 @@ -692,10 +695,11 @@ always available. .. data:: __interactivehook__ - When present, this function is automatically called (with no arguments) - when the interpreter is launched in :ref:`interactive mode <tut-interactive>`. - This is done after the :envvar:`PYTHONSTARTUP` file is read, so that you - can set this hook there. + When this attribute exists, its value is automatically called (with no + arguments) when the interpreter is launched in :ref:`interactive mode + <tut-interactive>`. This is done after the :envvar:`PYTHONSTARTUP` file is + read, so that you can set this hook there. The :mod:`site` module + :ref:`sets this <rlcompleter-config>`. .. versionadded:: 3.4 @@ -714,6 +718,14 @@ always available. value of :func:`intern` around to benefit from it. +.. function:: is_finalizing() + + Return :const:`True` if the Python interpreter is + :term:`shutting down <interpreter shutdown>`, :const:`False` otherwise. + + .. versionadded:: 3.5 + + .. data:: last_type last_value last_traceback @@ -1062,8 +1074,9 @@ always available. statements and for the prompts of :func:`input`; * The interpreter's own prompts and its error messages go to ``stderr``. - By default, these streams are regular text streams as returned by the - :func:`open` function. Their parameters are chosen as follows: + These streams are regular :term:`text files <text file>` like those + returned by the :func:`open` function. Their parameters are chosen as + follows: * The character encoding is platform-dependent. Under Windows, if the stream is interactive (that is, if its :meth:`isatty` method returns ``True``), the @@ -1071,26 +1084,22 @@ always available. platforms, the locale encoding is used (see :meth:`locale.getpreferredencoding`). Under all platforms though, you can override this value by setting the - :envvar:`PYTHONIOENCODING` environment variable. + :envvar:`PYTHONIOENCODING` environment variable before starting Python. * When interactive, standard streams are line-buffered. Otherwise, they are block-buffered like regular text files. You can override this value with the :option:`-u` command-line option. - To write or read binary data from/to the standard streams, use the - underlying binary :data:`~io.TextIOBase.buffer`. For example, to write - bytes to :data:`stdout`, use ``sys.stdout.buffer.write(b'abc')``. Using - :meth:`io.TextIOBase.detach`, streams can be made binary by default. This - function sets :data:`stdin` and :data:`stdout` to binary:: + .. note:: - def make_streams_binary(): - sys.stdin = sys.stdin.detach() - sys.stdout = sys.stdout.detach() + To write or read binary data from/to the standard streams, use the + underlying binary :data:`~io.TextIOBase.buffer` object. For example, to + write bytes to :data:`stdout`, use ``sys.stdout.buffer.write(b'abc')``. - Note that the streams may be replaced with objects (like :class:`io.StringIO`) - that do not support the :attr:`~io.BufferedIOBase.buffer` attribute or the - :meth:`~io.BufferedIOBase.detach` method and can raise :exc:`AttributeError` - or :exc:`io.UnsupportedOperation`. + However, if you are writing a library (and do not control in which + context its code will be executed), be aware that the standard streams + may be replaced with file-like objects like :class:`io.StringIO` which + do not support the :attr:`~io.BufferedIOBase.buffer` attribute. .. data:: __stdin__ @@ -1221,5 +1230,5 @@ always available. .. rubric:: Citations -.. [C99] ISO/IEC 9899:1999. "Programming languages -- C." A public draft of this standard is available at http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf . +.. [C99] ISO/IEC 9899:1999. "Programming languages -- C." A public draft of this standard is available at http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf\ . diff --git a/Doc/library/tarfile.rst b/Doc/library/tarfile.rst index 59336c9788b9..4fd94fd90d95 100644 --- a/Doc/library/tarfile.rst +++ b/Doc/library/tarfile.rst @@ -19,7 +19,8 @@ higher-level functions in :ref:`shutil <archiving-operations>`. Some facts and figures: -* reads and writes :mod:`gzip`, :mod:`bz2` and :mod:`lzma` compressed archives. +* reads and writes :mod:`gzip`, :mod:`bz2` and :mod:`lzma` compressed archives + if the respective modules are available. * read/write support for the POSIX.1-1988 (ustar) format. @@ -61,6 +62,23 @@ Some facts and figures: +------------------+---------------------------------------------+ | ``'r:xz'`` | Open for reading with lzma compression. | +------------------+---------------------------------------------+ + | ``'x'`` or | Create a tarfile exclusively without | + | ``'x:'`` | compression. | + | | Raise an :exc:`FileExistsError` exception | + | | if it is already exists. | + +------------------+---------------------------------------------+ + | ``'x:gz'`` | Create a tarfile with gzip compression. | + | | Raise an :exc:`FileExistsError` exception | + | | if it is already exists. | + +------------------+---------------------------------------------+ + | ``'x:bz2'`` | Create a tarfile with bzip2 compression. | + | | Raise an :exc:`FileExistsError` exception | + | | if it is already exists. | + +------------------+---------------------------------------------+ + | ``'x:xz'`` | Create a tarfile with lzma compression. | + | | Raise an :exc:`FileExistsError` exception | + | | if it is already exists. | + +------------------+---------------------------------------------+ | ``'a' or 'a:'`` | Open for appending with no compression. The | | | file is created if it does not exist. | +------------------+---------------------------------------------+ @@ -81,6 +99,10 @@ Some facts and figures: If *fileobj* is specified, it is used as an alternative to a :term:`file object` opened in binary mode for *name*. It is supposed to be at position 0. + For modes ``'w:gz'``, ``'r:gz'``, ``'w:bz2'``, ``'r:bz2'``, ``'x:gz'``, + ``'x:bz2'``, :func:`tarfile.open` accepts the keyword argument + *compresslevel* to specify the compression level of the file. + For special purposes, there is a second format for *mode*: ``'filemode|[compression]'``. :func:`tarfile.open` will return a :class:`TarFile` object that processes its data as a stream of blocks. No random seeking will @@ -122,6 +144,8 @@ Some facts and figures: | | writing. | +-------------+--------------------------------------------+ + .. versionchanged:: 3.5 + The ``'x'`` (exclusive creation) mode was added. .. class:: TarFile @@ -172,6 +196,13 @@ The :mod:`tarfile` module defines the following exceptions: Is raised by :meth:`TarInfo.frombuf` if the buffer it gets is invalid. +The following constants are available at the module level: + +.. data:: ENCODING + + The default character encoding: ``'utf-8'`` on Windows, the value returned by + :func:`sys.getfilesystemencoding` otherwise. + Each of the following constants defines a tar archive format that the :mod:`tarfile` module is able to create. See section :ref:`tar-formats` for @@ -198,20 +229,15 @@ details. The default format for creating archives. This is currently :const:`GNU_FORMAT`. -The following variables are available on module level: - - -.. data:: ENCODING - - The default character encoding: ``'utf-8'`` on Windows, - :func:`sys.getfilesystemencoding` otherwise. - - .. seealso:: Module :mod:`zipfile` Documentation of the :mod:`zipfile` standard module. + :ref:`archiving-operations` + Documentation of the higher-level archiving facilities provided by the + standard :mod:`shutil` module. + `GNU tar manual, Basic Tar Format <http://www.gnu.org/software/tar/manual/html_node/Standard.html>`_ Documentation for tar archive files, including GNU tar extensions. @@ -234,7 +260,7 @@ be finalized; only the internally used file object will be closed. See the :ref:`tar-examples` section for a use case. .. versionadded:: 3.2 - Added support for the context manager protocol. + Added support for the context management protocol. .. class:: TarFile(name=None, mode='r', fileobj=None, format=DEFAULT_FORMAT, tarinfo=TarInfo, dereference=False, ignore_zeros=False, encoding=ENCODING, errors='surrogateescape', pax_headers=None, debug=0, errorlevel=0) @@ -245,8 +271,8 @@ be finalized; only the internally used file object will be closed. See the In this case, the file object's :attr:`name` attribute is used if it exists. *mode* is either ``'r'`` to read from an existing archive, ``'a'`` to append - data to an existing file or ``'w'`` to create a new file overwriting an existing - one. + data to an existing file, ``'w'`` to create a new file overwriting an existing + one or ``'x'`` to create a new file only if it's not exists. If *fileobj* is given, it is used for reading or writing data. If it can be determined, *mode* is overridden by *fileobj*'s mode. *fileobj* will be used @@ -285,14 +311,16 @@ be finalized; only the internally used file object will be closed. See the to be handled. The default settings will work for most users. See section :ref:`tar-unicode` for in-depth information. - .. versionchanged:: 3.2 - Use ``'surrogateescape'`` as the default for the *errors* argument. - The *pax_headers* argument is an optional dictionary of strings which will be added as a pax global header if *format* is :const:`PAX_FORMAT`. + .. versionchanged:: 3.2 + Use ``'surrogateescape'`` as the default for the *errors* argument. + + .. versionchanged:: 3.5 + The ``'x'`` (exclusive creation) mode was added. -.. method:: TarFile.open(...) +.. classmethod:: TarFile.open(...) Alternative constructor. The :func:`tarfile.open` function is actually a shortcut to this classmethod. @@ -321,11 +349,15 @@ be finalized; only the internally used file object will be closed. See the returned by :meth:`getmembers`. -.. method:: TarFile.list(verbose=True) +.. method:: TarFile.list(verbose=True, *, members=None) Print a table of contents to ``sys.stdout``. If *verbose* is :const:`False`, only the names of the members are printed. If it is :const:`True`, output - similar to that of :program:`ls -l` is produced. + similar to that of :program:`ls -l` is produced. If optional *members* is + given, it must be a subset of the list returned by :meth:`getmembers`. + + .. versionchanged:: 3.5 + Added the *members* parameter. .. method:: TarFile.next() @@ -509,7 +541,7 @@ A ``TarInfo`` object has the following public data attributes: :const:`AREGTYPE`, :const:`LNKTYPE`, :const:`SYMTYPE`, :const:`DIRTYPE`, :const:`FIFOTYPE`, :const:`CONTTYPE`, :const:`CHRTYPE`, :const:`BLKTYPE`, :const:`GNUTYPE_SPARSE`. To determine the type of a :class:`TarInfo` object - more conveniently, use the ``is_*()`` methods below. + more conveniently, use the ``is*()`` methods below. .. attribute:: TarInfo.linkname @@ -787,7 +819,7 @@ metadata must be either decoded or encoded. If *encoding* is not set appropriately, this conversion may fail. The *errors* argument defines how characters are treated that cannot be -converted. Possible values are listed in section :ref:`codec-base-classes`. +converted. Possible values are listed in section :ref:`error-handlers`. The default scheme is ``'surrogateescape'`` which Python also uses for its file system calls, see :ref:`os-filenames`. diff --git a/Doc/library/telnetlib.rst b/Doc/library/telnetlib.rst index b0e4d1d8d999..31e5dbbd20a6 100644 --- a/Doc/library/telnetlib.rst +++ b/Doc/library/telnetlib.rst @@ -205,7 +205,7 @@ Telnet Objects .. method:: Telnet.set_option_negotiation_callback(callback) Each time a telnet option is read on the input flow, this *callback* (if set) is - called with the following parameters : callback(telnet socket, command + called with the following parameters: callback(telnet socket, command (DO/DONT/WILL/WONT), option). No other action is done afterwards by telnetlib. diff --git a/Doc/library/tempfile.rst b/Doc/library/tempfile.rst index 13b6041d04ff..2c6837744b01 100644 --- a/Doc/library/tempfile.rst +++ b/Doc/library/tempfile.rst @@ -54,6 +54,13 @@ The module defines the following user-callable items: underlying true file object. This file-like object can be used in a :keyword:`with` statement, just like a normal file. + The :py:data:`os.O_TMPFILE` flag is used if it is available and works + (Linux-specific, require Linux kernel 3.11 or later). + + .. versionchanged:: 3.5 + + The :py:data:`os.O_TMPFILE` flag is now used if available. + .. function:: NamedTemporaryFile(mode='w+b', buffering=None, encoding=None, newline=None, suffix='', prefix='tmp', dir=None, delete=True) @@ -97,12 +104,14 @@ The module defines the following user-callable items: This function creates a temporary directory using :func:`mkdtemp` (the supplied arguments are passed directly to the underlying function). The resulting object can be used as a context manager (see - :ref:`context-managers`). On completion of the context (or destruction - of the temporary directory object), the newly created temporary directory + :ref:`context-managers`). On completion of the context or destruction + of the temporary directory object the newly created temporary directory and all its contents are removed from the filesystem. - The directory name can be retrieved from the :attr:`name` attribute - of the returned object. + The directory name can be retrieved from the :attr:`name` attribute of the + returned object. When the returned object is used as a context manager, the + :attr:`name` will be assigned to the target of the :keyword:`as` clause in + the :keyword:`with` statement, if there is one. The directory can be explicitly cleaned up by calling the :func:`cleanup` method. @@ -190,7 +199,7 @@ The module defines the following user-callable items: >>> os.path.exists(f.name) False -The module uses two global variables that tell it how to construct a +The module uses a global variable that tell it how to construct a temporary name. They are initialized at the first call to any of the functions above. The caller may change them, but this is discouraged; use the appropriate function arguments, instead. diff --git a/Doc/library/test.rst b/Doc/library/test.rst index 2c515497ca85..974909e18204 100644 --- a/Doc/library/test.rst +++ b/Doc/library/test.rst @@ -85,7 +85,7 @@ A basic boilerplate is often used:: This code pattern allows the testing suite to be run by :mod:`test.regrtest`, on its own as a script that supports the :mod:`unittest` CLI, or via the -`python -m unittest` CLI. +``python -m unittest`` CLI. The goal for regression testing is to try to break code. This leads to a few guidelines to be followed: @@ -141,9 +141,9 @@ guidelines to be followed: arg = (1, 2, 3) When using this pattern, remember that all classes that inherit from - `unittest.TestCase` are run as tests. The `Mixin` class in the example above + :class:`unittest.TestCase` are run as tests. The :class:`Mixin` class in the example above does not have any data and so can't be run by itself, thus it does not - inherit from `unittest.TestCase`. + inherit from :class:`unittest.TestCase`. .. seealso:: @@ -199,6 +199,7 @@ The :mod:`test.support` module provides support for Python's regression test suite. .. note:: + :mod:`test.support` is not a public module. It is documented here to help Python developers write tests. The API of this module is subject to change without backwards compatibility concerns between releases. @@ -460,7 +461,7 @@ The :mod:`test.support` module defines the following functions: .. function:: make_bad_fd() Create an invalid file descriptor by opening and closing a temporary file, - and returning its descripor. + and returning its descriptor. .. function:: import_module(name, deprecated=False) @@ -553,6 +554,21 @@ The :mod:`test.support` module defines the following functions: run simultaneously, which is a problem for buildbots. +.. function:: load_package_tests(pkg_dir, loader, standard_tests, pattern) + + Generic implementation of the :mod:`unittest` ``load_tests`` protocol for + use in test packages. *pkg_dir* is the root directory of the package; + *loader*, *standard_tests*, and *pattern* are the arguments expected by + ``load_tests``. In simple cases, the test package's ``__init__.py`` + can be the following:: + + import os + from test.support import load_package_tests + + def load_tests(*args): + return load_package_tests(os.path.dirname(__file__), *args) + + The :mod:`test.support` module defines the following classes: .. class:: TransientResource(exc, **kwargs) diff --git a/Doc/library/textwrap.rst b/Doc/library/textwrap.rst index 1ba42a3f0404..9fe7a3589a7b 100644 --- a/Doc/library/textwrap.rst +++ b/Doc/library/textwrap.rst @@ -40,13 +40,14 @@ functions should be good enough; otherwise, you should use an instance of :func:`wrap`. -.. function:: shorten(text, width=70, *, placeholder=" [...]") +.. function:: shorten(text, width, **kwargs) - Collapse and truncate the given text to fit in the given width. + Collapse and truncate the given *text* to fit in the given *width*. - The text first has its whitespace collapsed. If it then fits in - the *width*, it is returned unchanged. Otherwise, as many words - as possible are joined and then the *placeholder* is appended:: + First the whitespace in *text* is collapsed (all whitespace is replaced by + single spaces). If the result fits in the *width*, it is returned. + Otherwise, enough words are dropped from the end so that the remaining words + plus the :attr:`placeholder` fit within :attr:`width`:: >>> textwrap.shorten("Hello world!", width=12) 'Hello world!' @@ -55,6 +56,12 @@ functions should be good enough; otherwise, you should use an instance of >>> textwrap.shorten("Hello world", width=10, placeholder="...") 'Hello...' + Optional keyword arguments correspond to the instance attributes of + :class:`TextWrapper`, documented below. Note that the whitespace is + collapsed before the text is passed to the :class:`TextWrapper` :meth:`fill` + function, so changing the value of :attr:`.tabsize`, :attr:`.expand_tabs`, + :attr:`.drop_whitespace`, and :attr:`.replace_whitespace` will have no effect. + .. versionadded:: 3.4 @@ -106,12 +113,14 @@ functions should be good enough; otherwise, you should use an instance of + + world + .. versionadded:: 3.3 + :func:`wrap`, :func:`fill` and :func:`shorten` work by creating a :class:`TextWrapper` instance and calling a single method on it. That instance is not reused, so for applications that process many text -strings, it may be more efficient to create your own -:class:`TextWrapper` object. +strings using :func:`wrap` and/or :func:`fill`, it may be more efficient to +create your own :class:`TextWrapper` object. Text is preferably wrapped on whitespaces and right after the hyphens in hyphenated words; only then will long words be broken if necessary, unless @@ -252,16 +261,16 @@ hyphenated words; only then will long words be broken if necessary, unless .. attribute:: max_lines - (default: ``None``) If not ``None``, then the text be will truncated to - *max_lines* lines. + (default: ``None``) If not ``None``, then the output will contain at most + *max_lines* lines, with *placeholder* appearing at the end of the output. .. versionadded:: 3.4 .. attribute:: placeholder - (default: ``' [...]'``) String that will be appended to the last line of - text if it will be truncated. + (default: ``' [...]'``) String that will appear at the end of the output + text if it has been truncated. .. versionadded:: 3.4 diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index 4a3b3ea00b21..e7a354484c1b 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -354,7 +354,7 @@ called in the locked state; it changes the state to unlocked and returns immediately. If an attempt is made to release an unlocked lock, a :exc:`RuntimeError` will be raised. -Locks also support the :ref:`context manager protocol <with-locks>`. +Locks also support the :ref:`context management protocol <with-locks>`. When more than one thread is blocked in :meth:`~Lock.acquire` waiting for the state to turn to unlocked, only one thread proceeds when a :meth:`~Lock.release` @@ -433,7 +433,7 @@ call pairs may be nested; only the final :meth:`~Lock.release` (the :meth:`~Lock.release` of the outermost pair) resets the lock to unlocked and allows another thread blocked in :meth:`~Lock.acquire` to proceed. -Reentrant locks also support the :ref:`context manager protocol <with-locks>`. +Reentrant locks also support the :ref:`context management protocol <with-locks>`. .. class:: RLock() @@ -501,7 +501,7 @@ passed in or one will be created by default. Passing one in is useful when several condition variables must share the same lock. The lock is part of the condition object: you don't have to track it separately. -A condition variable obeys the :ref:`context manager protocol <with-locks>`: +A condition variable obeys the :ref:`context management protocol <with-locks>`: using the ``with`` statement acquires the associated lock for the duration of the enclosed block. The :meth:`~Condition.acquire` and :meth:`~Condition.release` methods also call the corresponding methods of @@ -630,7 +630,7 @@ item to the buffer only needs to wake up one consumer thread. cv.wait() Therefore, the same rules apply as with :meth:`wait`: The lock must be - held when called and is re-aquired on return. The predicate is evaluated + held when called and is re-acquired on return. The predicate is evaluated with the lock held. .. versionadded:: 3.2 @@ -677,7 +677,7 @@ call. The counter can never go below zero; when :meth:`~Semaphore.acquire` finds that it is zero, it blocks, waiting until some other thread calls :meth:`~Semaphore.release`. -Semaphores also support the :ref:`context manager protocol <with-locks>`. +Semaphores also support the :ref:`context management protocol <with-locks>`. .. class:: Semaphore(value=1) diff --git a/Doc/library/time.rst b/Doc/library/time.rst index 64b5e0414d3b..6bfd52117688 100644 --- a/Doc/library/time.rst +++ b/Doc/library/time.rst @@ -133,8 +133,7 @@ The module defines the following functions and data items: On Unix, return the current processor time as a floating point number expressed in seconds. The precision, and in fact the very definition of the meaning of - "processor time", depends on that of the C function of the same name, but in any - case, this is the function to use for benchmarking Python or timing algorithms. + "processor time", depends on that of the C function of the same name. On Windows, this function returns wall-clock seconds elapsed since the first call to this function, as a floating point number, based on the Win32 function @@ -315,9 +314,9 @@ The module defines the following functions and data items: processes running for more than 49 days. On more recent versions of Windows and on other operating systems, :func:`monotonic` is system-wide. - Availability: Windows, Mac OS X, Linux, FreeBSD, OpenBSD, Solaris. - .. versionadded:: 3.3 + .. versionchanged:: 3.5 + The function is now always available. .. function:: perf_counter() @@ -343,12 +342,13 @@ The module defines the following functions and data items: .. function:: sleep(secs) - Suspend execution for the given number of seconds. The argument may be a - floating point number to indicate a more precise sleep time. The actual - suspension time may be less than that requested because any caught signal will - terminate the :func:`sleep` following execution of that signal's catching - routine. Also, the suspension time may be longer than requested by an arbitrary - amount because of the scheduling of other activity in the system. + Suspend execution of the calling thread for the given number of seconds. + The argument may be a floating point number to indicate a more precise sleep + time. The actual suspension time may be less than that requested because any + caught signal will terminate the :func:`sleep` following execution of that + signal's catching routine. Also, the suspension time may be longer than + requested by an arbitrary amount because of the scheduling of other activity + in the system. .. function:: strftime(format[, t]) diff --git a/Doc/library/timeit.rst b/Doc/library/timeit.rst index 0cc15868db6a..17588bdc87fe 100644 --- a/Doc/library/timeit.rst +++ b/Doc/library/timeit.rst @@ -28,22 +28,23 @@ can be used to compare three different expressions: .. code-block:: sh - $ python -m timeit '"-".join(str(n) for n in range(100))' - 10000 loops, best of 3: 40.3 usec per loop - $ python -m timeit '"-".join([str(n) for n in range(100)])' - 10000 loops, best of 3: 33.4 usec per loop - $ python -m timeit '"-".join(map(str, range(100)))' - 10000 loops, best of 3: 25.2 usec per loop + $ python3 -m timeit '"-".join(str(n) for n in range(100))' + 10000 loops, best of 3: 30.2 usec per loop + $ python3 -m timeit '"-".join([str(n) for n in range(100)])' + 10000 loops, best of 3: 27.5 usec per loop + $ python3 -m timeit '"-".join(map(str, range(100)))' + 10000 loops, best of 3: 23.2 usec per loop This can be achieved from the :ref:`python-interface` with:: >>> import timeit >>> timeit.timeit('"-".join(str(n) for n in range(100))', number=10000) - 0.8187260627746582 + 0.3018611848820001 >>> timeit.timeit('"-".join([str(n) for n in range(100)])', number=10000) - 0.7288308143615723 + 0.2727368790656328 >>> timeit.timeit('"-".join(map(str, range(100)))', number=10000) - 0.5858950614929199 + 0.23702679807320237 + Note however that :mod:`timeit` will automatically determine the number of repetitions only when the command-line interface is used. In the @@ -58,18 +59,26 @@ Python Interface The module defines three convenience functions and a public class: -.. function:: timeit(stmt='pass', setup='pass', timer=<default timer>, number=1000000) +.. function:: timeit(stmt='pass', setup='pass', timer=<default timer>, number=1000000, globals=None) Create a :class:`Timer` instance with the given statement, *setup* code and *timer* function and run its :meth:`.timeit` method with *number* executions. + The optional *globals* argument specifies a namespace in which to execute the + code. + + .. versionchanged:: 3.5 + The optional *globals* parameter was added. -.. function:: repeat(stmt='pass', setup='pass', timer=<default timer>, repeat=3, number=1000000) +.. function:: repeat(stmt='pass', setup='pass', timer=<default timer>, repeat=3, number=1000000, globals=None) Create a :class:`Timer` instance with the given statement, *setup* code and *timer* function and run its :meth:`.repeat` method with the given *repeat* - count and *number* executions. + count and *number* executions. The optional *globals* argument specifies a + namespace in which to execute the code. + .. versionchanged:: 3.5 + The optional *globals* parameter was added. .. function:: default_timer() @@ -79,7 +88,7 @@ The module defines three convenience functions and a public class: :func:`time.perf_counter` is now the default timer. -.. class:: Timer(stmt='pass', setup='pass', timer=<timer function>) +.. class:: Timer(stmt='pass', setup='pass', timer=<timer function>, globals=None) Class for timing execution speed of small code snippets. @@ -87,7 +96,9 @@ The module defines three convenience functions and a public class: for setup, and a timer function. Both statements default to ``'pass'``; the timer function is platform-dependent (see the module doc string). *stmt* and *setup* may also contain multiple statements separated by ``;`` - or newlines, as long as they don't contain multi-line string literals. + or newlines, as long as they don't contain multi-line string literals. The + statement will by default be executed within timeit's namespace; this behavior + can be controlled by passing a namespace to *globals*. To measure the execution time of the first statement, use the :meth:`.timeit` method. The :meth:`.repeat` method is a convenience to call :meth:`.timeit` @@ -98,6 +109,8 @@ The module defines three convenience functions and a public class: will then be executed by :meth:`.timeit`. Note that the timing overhead is a little larger in this case because of the extra function calls. + .. versionchanged:: 3.5 + The optional *globals* parameter was added. .. method:: Timer.timeit(number=1000000) @@ -317,3 +330,17 @@ To give the :mod:`timeit` module access to functions you define, you can pass a if __name__ == '__main__': import timeit print(timeit.timeit("test()", setup="from __main__ import test")) + +Another option is to pass :func:`globals` to the *globals* parameter, which will cause the code +to be executed within your current global namespace. This can be more convenient +than individually specifying imports:: + + def f(x): + return x**2 + def g(x): + return x**4 + def h(x): + return x**8 + + import timeit + print(timeit.timeit('[func(42) for func in (f,g,h)]', globals=globals())) diff --git a/Doc/library/tkinter.rst b/Doc/library/tkinter.rst index 83f0ed5db18c..40e97bf0f10b 100644 --- a/Doc/library/tkinter.rst +++ b/Doc/library/tkinter.rst @@ -15,14 +15,14 @@ this should open a window demonstrating a simple Tk interface. .. seealso:: - `Python Tkinter Resources <http://www.python.org/topics/tkinter/>`_ + `Python Tkinter Resources <https://wiki.python.org/moin/TkInter>`_ The Python Tkinter Topic Guide provides a great deal of information on using Tk from Python and links to other sources of information on Tk. `TKDocs <http://www.tkdocs.com/>`_ Extensive tutorial plus friendlier widget pages for some of the widgets. - `Tkinter reference: a GUI for Python <http://infohost.nmt.edu/tcc/help/pubs/tkinter/>`_ + `Tkinter reference: a GUI for Python <http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/index.html>`_ On-line reference material. `Tkinter docs from effbot <http://effbot.org/tkinterbook/>`_ @@ -180,7 +180,7 @@ documentation that exists. Here are some hints: The Tk/Tcl development is largely taking place at ActiveState. `Tcl and the Tk Toolkit <http://www.amazon.com/exec/obidos/ASIN/020163337X>`_ - The book by John Ousterhout, the inventor of Tcl . + The book by John Ousterhout, the inventor of Tcl. `Practical Programming in Tcl and Tk <http://www.amazon.com/exec/obidos/ASIN/0130220280>`_ Brent Welch's encyclopedic book. @@ -440,7 +440,7 @@ back will contain the name of the synonym and the "real" option (such as Example:: >>> print(fred.config()) - {'relief' : ('relief', 'relief', 'Relief', 'raised', 'groove')} + {'relief': ('relief', 'relief', 'Relief', 'raised', 'groove')} Of course, the dictionary printed will include all the options available and their values. This is meant only as an example. @@ -613,7 +613,7 @@ bitmap preceded with an ``@``, as in ``"@/usr/contrib/bitmap/gumby.bit"``. boolean - You can pass integers 0 or 1 or the strings ``"yes"`` or ``"no"`` . + You can pass integers 0 or 1 or the strings ``"yes"`` or ``"no"``. callback This is any Python function that takes no arguments. For example:: diff --git a/Doc/library/tkinter.ttk.rst b/Doc/library/tkinter.ttk.rst index 6f8bf1c315da..b0eefcb7024f 100644 --- a/Doc/library/tkinter.ttk.rst +++ b/Doc/library/tkinter.ttk.rst @@ -1167,7 +1167,7 @@ Ttk Styling Each widget in :mod:`ttk` is assigned a style, which specifies the set of elements making up the widget and how they are arranged, along with dynamic and default settings for element options. By default the style name is the -same as the widget's class name, but it may be overriden by the widget's style +same as the widget's class name, but it may be overridden by the widget's style option. If you don't know the class name of a widget, use the method :meth:`Misc.winfo_class` (somewidget.winfo_class()). diff --git a/Doc/library/token.rst b/Doc/library/token.rst index 4cd709814c33..88fb38bc1dd1 100644 --- a/Doc/library/token.rst +++ b/Doc/library/token.rst @@ -93,6 +93,7 @@ The token constants are: DOUBLESLASH DOUBLESLASHEQUAL AT + ATEQUAL RARROW ELLIPSIS OP diff --git a/Doc/library/tokenize.rst b/Doc/library/tokenize.rst index 37d9f41cc1b2..bd6b121f8dad 100644 --- a/Doc/library/tokenize.rst +++ b/Doc/library/tokenize.rst @@ -131,6 +131,24 @@ function it uses to do this is available: .. versionadded:: 3.2 +.. exception:: TokenError + + Raised when either a docstring or expression that may be split over several + lines is not completed anywhere in the file, for example:: + + """Beginning of + docstring + + or:: + + [1, + 2, + 3 + +Note that unclosed single-quoted strings do not cause an error to be +raised. They are tokenized as ``ERRORTOKEN``, followed by the tokenization of +their contents. + .. _tokenize-cli: diff --git a/Doc/library/trace.rst b/Doc/library/trace.rst index 9b52f7d18d31..b0ac81271c5c 100644 --- a/Doc/library/trace.rst +++ b/Doc/library/trace.rst @@ -41,8 +41,8 @@ Main options At least one of the following options must be specified when invoking :mod:`trace`. The :option:`--listfuncs <-l>` option is mutually exclusive with -the :option:`--trace <-t>` and :option:`--counts <-c>` options . When -:option:`--listfuncs <-l>` is provided, neither :option:`--counts <-c>` nor +the :option:`--trace <-t>` and :option:`--count <-c>` options. When +:option:`--listfuncs <-l>` is provided, neither :option:`--count <-c>` nor :option:`--trace <-t>` are accepted, and vice versa. .. program:: trace diff --git a/Doc/library/traceback.rst b/Doc/library/traceback.rst index b68a8f1e1971..15fbedcf33ff 100644 --- a/Doc/library/traceback.rst +++ b/Doc/library/traceback.rst @@ -72,7 +72,7 @@ The module defines the following functions: Return a list of up to *limit* "pre-processed" stack trace entries extracted from the traceback object *traceback*. It is useful for alternate formatting of stack traces. If *limit* is omitted or ``None``, all entries are extracted. A - "pre-processed" stack trace entry is a quadruple (*filename*, *line number*, + "pre-processed" stack trace entry is a 4-tuple (*filename*, *line number*, *function name*, *text*) representing the information that is usually printed for a stack trace. The *text* is a string with leading and trailing whitespace stripped; if the source is not available it is ``None``. diff --git a/Doc/library/tracemalloc.rst b/Doc/library/tracemalloc.rst index d4067825d223..a04a4327167b 100644 --- a/Doc/library/tracemalloc.rst +++ b/Doc/library/tracemalloc.rst @@ -4,6 +4,8 @@ .. module:: tracemalloc :synopsis: Trace memory allocations. +.. versionadded:: 3.4 + The tracemalloc module is a debug tool to trace memory blocks allocated by Python. It provides the following information: @@ -23,14 +25,12 @@ frame (1 frame). To store 25 frames at startup: set the :envvar:`PYTHONTRACEMALLOC` environment variable to ``25``, or use the :option:`-X` ``tracemalloc=25`` command line option. -.. versionadded:: 3.4 - Examples -======== +-------- Display the top 10 ------------------- +^^^^^^^^^^^^^^^^^^ Display the 10 files allocating the most memory:: @@ -70,7 +70,7 @@ See :meth:`Snapshot.statistics` for more options. Compute differences -------------------- +^^^^^^^^^^^^^^^^^^^ Take two snapshots and display the differences:: @@ -114,11 +114,10 @@ the :meth:`Snapshot.dump` method to analyze the snapshot offline. Then use the Get the traceback of a memory block ------------------------------------ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Code to display the traceback of the biggest memory block:: - import linecache import tracemalloc # Store 25 frames @@ -132,12 +131,8 @@ Code to display the traceback of the biggest memory block:: # pick the biggest memory block stat = top_stats[0] print("%s memory blocks: %.1f KiB" % (stat.count, stat.size / 1024)) - for frame in stat.traceback: - print(' File "%s", line %s' % (frame.filename, frame.lineno)) - line = linecache.getline(frame.filename, frame.lineno) - line = line.strip() - if line: - print(' ' + line) + for line in stat.traceback.format(): + print(line) Example of output of the Python test suite (traceback limited to 25 frames):: @@ -184,11 +179,12 @@ loaded. Pretty top ----------- +^^^^^^^^^^ Code to display the 10 lines allocating the most memory with a pretty output, ignoring ``<frozen importlib._bootstrap>`` and ``<unknown>`` files:: + import linecache import os import tracemalloc @@ -205,8 +201,10 @@ ignoring ``<frozen importlib._bootstrap>`` and ``<unknown>`` files:: # replace "/path/to/module/file.py" with "module/file.py" filename = os.sep.join(frame.filename.split(os.sep)[-2:]) print("#%s: %s:%s: %.1f KiB" - % (index, filename, frame.lineno, - stat.size / 1024)) + % (index, filename, frame.lineno, stat.size / 1024)) + line = linecache.getline(frame.filename, frame.lineno).strip() + if line: + print(' %s' % line) other = top_stats[limit:] if other: @@ -220,32 +218,41 @@ ignoring ``<frozen importlib._bootstrap>`` and ``<unknown>`` files:: # ... run your application ... snapshot = tracemalloc.take_snapshot() - display_top(snapshot, 10) + display_top(snapshot) Example of output of the Python test suite:: - 2013-11-08 14:16:58.149320: Top 10 lines - #1: collections/__init__.py:368: 291.9 KiB - #2: Lib/doctest.py:1291: 200.2 KiB - #3: unittest/case.py:571: 160.3 KiB - #4: Lib/abc.py:133: 99.8 KiB - #5: urllib/parse.py:476: 71.8 KiB - #6: <string>:5: 62.7 KiB - #7: Lib/base64.py:140: 59.8 KiB - #8: Lib/_weakrefset.py:37: 51.8 KiB - #9: collections/__init__.py:362: 50.6 KiB - #10: test/test_site.py:56: 48.0 KiB - 7496 other: 4161.9 KiB - Total allocated size: 5258.8 KiB + Top 10 lines + #1: Lib/base64.py:414: 419.8 KiB + _b85chars2 = [(a + b) for a in _b85chars for b in _b85chars] + #2: Lib/base64.py:306: 419.8 KiB + _a85chars2 = [(a + b) for a in _a85chars for b in _a85chars] + #3: collections/__init__.py:368: 293.6 KiB + exec(class_definition, namespace) + #4: Lib/abc.py:133: 115.2 KiB + cls = super().__new__(mcls, name, bases, namespace) + #5: unittest/case.py:574: 103.1 KiB + testMethod() + #6: Lib/linecache.py:127: 95.4 KiB + lines = fp.readlines() + #7: urllib/parse.py:476: 71.8 KiB + for a in _hexdig for b in _hexdig} + #8: <string>:5: 62.0 KiB + #9: Lib/_weakrefset.py:37: 60.0 KiB + self.data = set() + #10: Lib/base64.py:142: 59.8 KiB + _b32tab2 = [a + b for a in _b32tab for b in _b32tab] + 6220 other: 3602.8 KiB + Total allocated size: 5303.1 KiB See :meth:`Snapshot.statistics` for more options. API -=== +--- Functions ---------- +^^^^^^^^^ .. function:: clear_traces() @@ -343,13 +350,13 @@ Functions the *nframe* parameter of the :func:`start` function to store more frames. The :mod:`tracemalloc` module must be tracing memory allocations to take a - snapshot, see the the :func:`start` function. + snapshot, see the :func:`start` function. See also the :func:`get_object_traceback` function. Filter ------- +^^^^^^ .. class:: Filter(inclusive: bool, filename_pattern: str, lineno: int=None, all_frames: bool=False) @@ -397,7 +404,7 @@ Filter Frame ------ +^^^^^ .. class:: Frame @@ -415,7 +422,7 @@ Frame Snapshot --------- +^^^^^^^^ .. class:: Snapshot @@ -428,7 +435,7 @@ Snapshot Compute the differences with an old snapshot. Get statistics as a sorted list of :class:`StatisticDiff` instances grouped by *group_by*. - See the :meth:`statistics` method for *group_by* and *cumulative* + See the :meth:`Snapshot.statistics` method for *group_by* and *cumulative* parameters. The result is sorted from the biggest to the smallest by: absolute value @@ -501,7 +508,7 @@ Snapshot Statistic ---------- +^^^^^^^^^ .. class:: Statistic @@ -526,7 +533,7 @@ Statistic StatisticDiff -------------- +^^^^^^^^^^^^^ .. class:: StatisticDiff @@ -565,7 +572,7 @@ StatisticDiff Trace ------ +^^^^^ .. class:: Trace @@ -585,7 +592,7 @@ Trace Traceback ---------- +^^^^^^^^^ .. class:: Traceback @@ -602,4 +609,26 @@ Traceback The :attr:`Trace.traceback` attribute is an instance of :class:`Traceback` instance. + .. method:: format(limit=None) + + Format the traceback as a list of lines with newlines. Use the + :mod:`linecache` module to retrieve lines from the source code. If + *limit* is set, only format the *limit* most recent frames. + + Similar to the :func:`traceback.format_tb` function, except that + :meth:`format` does not include newlines. + + Example:: + + print("Traceback (most recent call first):") + for line in traceback: + print(line) + + Output:: + + Traceback (most recent call first): + File "test.py", line 9 + obj = Object() + File "test.py", line 12 + tb = tracemalloc.get_object_traceback(f()) diff --git a/Doc/library/tulip_coro.dia b/Doc/library/tulip_coro.dia new file mode 100644 index 000000000000..eccf4fa7f5a5 Binary files /dev/null and b/Doc/library/tulip_coro.dia differ diff --git a/Doc/library/tulip_coro.png b/Doc/library/tulip_coro.png new file mode 100644 index 000000000000..65b6951550e1 Binary files /dev/null and b/Doc/library/tulip_coro.png differ diff --git a/Doc/library/turtle.rst b/Doc/library/turtle.rst index b015530cca5f..157fe9329b37 100644 --- a/Doc/library/turtle.rst +++ b/Doc/library/turtle.rst @@ -1809,7 +1809,7 @@ Input methods Pop up a dialog window for input of a number. title is the title of the dialog window, prompt is a text mostly describing what numerical information - to input. default: default value, minval: minimum value for imput, + to input. default: default value, minval: minimum value for input, maxval: maximum value for input The number input must be in the range minval .. maxval if these are given. If not, a hint is issued and the dialog remains open for @@ -1879,7 +1879,7 @@ Settings and special methods >>> cv = screen.getcanvas() >>> cv - <turtle.ScrolledCanvas object at ...> + <turtle.ScrolledCanvas object ...> .. function:: getshapes() @@ -1981,7 +1981,7 @@ Methods specific to Screen, not inherited from TurtleScreen :param startx: if positive, starting position in pixels from the left edge of the screen, if negative from the right edge, if None, center window horizontally - :param startx: if positive, starting position in pixels from the top + :param starty: if positive, starting position in pixels from the top edge of the screen, if negative from the bottom edge, if None, center window vertically @@ -2274,10 +2274,13 @@ study it as an example and see its effects when running the demos (preferably not from within the demo-viewer). -Demo scripts -============ +:mod:`turtledemo` --- Demo scripts +================================== + +.. module:: turtledemo + :synopsis: A viewer for example turtle scripts -There is a set of demo scripts in the :mod:`turtledemo` package. These +The :mod:`turtledemo` package includes a set of demo scripts. These scripts can be run and viewed using the supplied demo viewer as follows:: python -m turtledemo @@ -2288,16 +2291,13 @@ Alternatively, you can run the demo scripts individually. For example, :: The :mod:`turtledemo` package directory contains: -- a set of 15 demo scripts demonstrating different features of the new module - :mod:`turtle`; -- a demo viewer :file:`__main__.py` which can be used to view the sourcecode - of the scripts and run them at the same time. 14 of the examples can be - accessed via the Examples menu; all of them can also be run standalone. -- The example :mod:`turtledemo.two_canvases` demonstrates the simultaneous - use of two canvases with the turtle module. Therefore it only can be run - standalone. -- There is a :file:`turtle.cfg` file in this directory, which serves as an - example for how to write and use such files. +- A demo viewer :file:`__main__.py` which can be used to view the sourcecode + of the scripts and run them at the same time. +- Multiple scripts demonstrating different features of the :mod:`turtle` + module. Examples can be accessed via the Examples menu. They can also + be run standalone. +- A :file:`turtle.cfg` file which serves as an example of how to write + and use such files. The demo scripts are: @@ -2320,6 +2320,8 @@ The demo scripts are: +----------------+------------------------------+-----------------------+ | colormixer | experiment with r, g, b | :func:`ondrag` | +----------------+------------------------------+-----------------------+ +| forest | 3 breadth-first trees | randomization | ++----------------+------------------------------+-----------------------+ | fractalcurves | Hilbert & Koch curves | recursion | +----------------+------------------------------+-----------------------+ | lindenmayer | ethnomathematics | L-System | @@ -2352,6 +2354,9 @@ The demo scripts are: | tree | a (graphical) breadth | :func:`clone` | | | first tree (using generators)| | +----------------+------------------------------+-----------------------+ +| two_canvases | simple design | turtles on two | +| | | canvases | ++----------------+------------------------------+-----------------------+ | wikipedia | a pattern from the wikipedia | :func:`clone`, | | | article on turtle graphics | :func:`undo` | +----------------+------------------------------+-----------------------+ @@ -2397,7 +2402,7 @@ Changes since Python 3.0 Accordingly the latter has got an alias: :meth:`Screen.onkeyrelease`. - The method :meth:`Screen.mainloop` has been added. So when working only - with Screen and Turtle objects one must not additonally import + with Screen and Turtle objects one must not additionally import :func:`mainloop` anymore. - Two input methods has been added :meth:`Screen.textinput` and diff --git a/Doc/library/types.rst b/Doc/library/types.rst index c4f57e43af31..34fffe686353 100644 --- a/Doc/library/types.rst +++ b/Doc/library/types.rst @@ -15,6 +15,9 @@ It also defines names for some object types that are used by the standard Python interpreter, but not exposed as builtins like :class:`int` or :class:`str` are. +Finally, it provides some additional type-related utility classes and functions +that are not fundamental enough to be builtins. + Dynamic Type Creation --------------------- @@ -112,6 +115,10 @@ Standard names are defined for the following types: The type of :term:`modules <module>`. Constructor takes the name of the module to be created and optionally its :term:`docstring`. + .. note:: + Use :func:`importlib.util.module_from_spec` to create a new module if you + wish to set the various import-controlled attributes. + .. attribute:: __doc__ The :term:`docstring` of the module. Defaults to ``None``. @@ -220,6 +227,9 @@ Standard names are defined for the following types: Return a new view of the underlying mapping's values. +Additional Utility Classes and Functions +---------------------------------------- + .. class:: SimpleNamespace A simple :class:`object` subclass that provides attribute access to its @@ -246,3 +256,18 @@ Standard names are defined for the following types: instead. .. versionadded:: 3.3 + + +.. function:: DynamicClassAttribute(fget=None, fset=None, fdel=None, doc=None) + + Route attribute access on a class to __getattr__. + + This is a descriptor, used to define attributes that act differently when + accessed through an instance and through a class. Instance access remains + normal, but access to an attribute through a class will be routed to the + class's __getattr__ method; this is done by raising AttributeError. + + This allows one to have properties active on an instance, and have virtual + attributes on the class with the same name (see Enum for an example). + + .. versionadded:: 3.4 diff --git a/Doc/library/undoc.rst b/Doc/library/undoc.rst index 80386d240c1e..20830e296396 100644 --- a/Doc/library/undoc.rst +++ b/Doc/library/undoc.rst @@ -20,7 +20,7 @@ These modules are used to implement the :mod:`os.path` module, and are not documented beyond this mention. There's little need to document these. :mod:`ntpath` - --- Implementation of :mod:`os.path` on Win32, Win64, WinCE, and OS/2 platforms. + --- Implementation of :mod:`os.path` on Win32, Win64, and WinCE platforms. :mod:`posixpath` --- Implementation of :mod:`os.path` on POSIX. diff --git a/Doc/library/unicodedata.rst b/Doc/library/unicodedata.rst index 3b3d3a0a8f7d..24ddef8a3233 100644 --- a/Doc/library/unicodedata.rst +++ b/Doc/library/unicodedata.rst @@ -15,8 +15,8 @@ This module provides access to the Unicode Character Database (UCD) which defines character properties for all Unicode characters. The data contained in -this database is compiled from the `UCD version 6.3.0 -<http://www.unicode.org/Public/6.3.0/ucd>`_. +this database is compiled from the `UCD version 7.0.0 +<http://www.unicode.org/Public/7.0.0/ucd>`_. The module uses the same names and symbols as defined by Unicode Standard Annex #44, `"Unicode Character Database" @@ -166,6 +166,6 @@ Examples: .. rubric:: Footnotes -.. [#] http://www.unicode.org/Public/6.3.0/ucd/NameAliases.txt +.. [#] http://www.unicode.org/Public/7.0.0/ucd/NameAliases.txt -.. [#] http://www.unicode.org/Public/6.3.0/ucd/NamedSequences.txt +.. [#] http://www.unicode.org/Public/7.0.0/ucd/NamedSequences.txt diff --git a/Doc/library/unittest.mock-examples.rst b/Doc/library/unittest.mock-examples.rst index 444c20897eea..055abe0de1ce 100644 --- a/Doc/library/unittest.mock-examples.rst +++ b/Doc/library/unittest.mock-examples.rst @@ -28,22 +28,22 @@ it is called with the correct arguments by another part of the system: >>> real.method(3, 4, 5, key='value') <MagicMock name='method()' id='...'> -Once our mock has been used (`real.method` in this example) it has methods +Once our mock has been used (``real.method`` in this example) it has methods and attributes that allow you to make assertions about how it has been used. .. note:: In most of these examples the :class:`Mock` and :class:`MagicMock` classes - are interchangeable. As the `MagicMock` is the more capable class it makes + are interchangeable. As the ``MagicMock`` is the more capable class it makes a sensible one to use by default. Once the mock has been called its :attr:`~Mock.called` attribute is set to -`True`. More importantly we can use the :meth:`~Mock.assert_called_with` or +``True``. More importantly we can use the :meth:`~Mock.assert_called_with` or :meth:`~Mock.assert_called_once_with` method to check that it was called with the correct arguments. -This example tests that calling `ProductionClass().method` results in a call to -the `something` method: +This example tests that calling ``ProductionClass().method`` results in a call to +the ``something`` method: >>> class ProductionClass: ... def method(self): @@ -66,15 +66,15 @@ was called correctly. Another common use case is to pass an object into a method (or some part of the system under test) and then check that it is used in the correct way. -The simple `ProductionClass` below has a `closer` method. If it is called with -an object then it calls `close` on it. +The simple ``ProductionClass`` below has a ``closer`` method. If it is called with +an object then it calls ``close`` on it. >>> class ProductionClass: ... def closer(self, something): ... something.close() ... -So to test it we need to pass in an object with a `close` method and check +So to test it we need to pass in an object with a ``close`` method and check that it was called correctly. >>> real = ProductionClass() @@ -96,9 +96,9 @@ When you patch a class, then that class is replaced with a mock. Instances are created by *calling the class*. This means you access the "mock instance" by looking at the return value of the mocked class. -In the example below we have a function `some_function` that instantiates `Foo` -and calls a method on it. The call to `patch` replaces the class `Foo` with a -mock. The `Foo` instance is the result of calling the mock, so it is configured +In the example below we have a function ``some_function`` that instantiates ``Foo`` +and calls a method on it. The call to :func:`patch` replaces the class ``Foo`` with a +mock. The ``Foo`` instance is the result of calling the mock, so it is configured by modifying the mock :attr:`~Mock.return_value`. >>> def some_function(): @@ -141,13 +141,13 @@ to child attributes of the mock - and also to their children. >>> mock.mock_calls [call.method(), call.attribute.method(10, x=53)] -If you make an assertion about `mock_calls` and any unexpected methods +If you make an assertion about ``mock_calls`` and any unexpected methods have been called, then the assertion will fail. This is useful because as well as asserting that the calls you expected have been made, you are also checking that they were made in the right order and with no additional calls: You use the :data:`call` object to construct lists for comparing with -`mock_calls`: +``mock_calls``: >>> expected = [call.method(), call.attribute.method(10, x=53)] >>> mock.mock_calls == expected @@ -185,7 +185,7 @@ If you need an attribute setting on your mock, just do it: 3 Sometimes you want to mock up a more complex situation, like for example -`mock.connection.cursor().execute("SELECT 1")`. If we wanted this call to +``mock.connection.cursor().execute("SELECT 1")``. If we wanted this call to return a list, then we have to configure the result of the nested call. We can use :data:`call` to construct the set of calls in a "chained call" like @@ -202,7 +202,7 @@ this for easy assertion afterwards: >>> mock.mock_calls == expected True -It is the call to `.call_list()` that turns our call object into a list of +It is the call to ``.call_list()`` that turns our call object into a list of calls representing the chained calls. @@ -223,10 +223,10 @@ is called. Side effect functions and iterables ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -`side_effect` can also be set to a function or an iterable. The use case for -`side_effect` as an iterable is where your mock is going to be called several +``side_effect`` can also be set to a function or an iterable. The use case for +``side_effect`` as an iterable is where your mock is going to be called several times, and you want each call to return a different value. When you set -`side_effect` to an iterable every call to the mock returns the next value +``side_effect`` to an iterable every call to the mock returns the next value from the iterable: >>> mock = MagicMock(side_effect=[4, 5, 6]) @@ -239,7 +239,7 @@ from the iterable: For more advanced use cases, like dynamically varying the return values -depending on what the mock is called with, `side_effect` can be a function. +depending on what the mock is called with, ``side_effect`` can be a function. The function will be called with the same arguments as the mock. Whatever the function returns is what the call returns: @@ -259,13 +259,13 @@ Creating a Mock from an Existing Object One problem with over use of mocking is that it couples your tests to the implementation of your mocks rather than your real code. Suppose you have a -class that implements `some_method`. In a test for another class, you -provide a mock of this object that *also* provides `some_method`. If later -you refactor the first class, so that it no longer has `some_method` - then +class that implements ``some_method``. In a test for another class, you +provide a mock of this object that *also* provides ``some_method``. If later +you refactor the first class, so that it no longer has ``some_method`` - then your tests will continue to pass even though your code is now broken! -`Mock` allows you to provide an object as a specification for the mock, -using the `spec` keyword argument. Accessing methods / attributes on the +:class:`Mock` allows you to provide an object as a specification for the mock, +using the *spec* keyword argument. Accessing methods / attributes on the mock that don't exist on your specification object will immediately raise an attribute error. If you change the implementation of your specification, then tests that use that class will start failing immediately without you having to @@ -293,7 +293,7 @@ you can use :ref:`auto-speccing <auto-speccing>`. If you want a stronger form of specification that prevents the setting of arbitrary attributes as well as the getting of them then you can use -`spec_set` instead of `spec`. +*spec_set* instead of *spec*. @@ -302,8 +302,8 @@ Patch Decorators .. note:: - With `patch` it matters that you patch objects in the namespace where they - are looked up. This is normally straightforward, but for a quick guide + With :func:`patch` it matters that you patch objects in the namespace where + they are looked up. This is normally straightforward, but for a quick guide read :ref:`where to patch <where-to-patch>`. @@ -313,15 +313,15 @@ is instantiated. Modules and classes are effectively global, so patching on them has to be undone after the test or the patch will persist into other tests and cause hard to diagnose problems. -mock provides three convenient decorators for this: `patch`, `patch.object` and -`patch.dict`. `patch` takes a single string, of the form -`package.module.Class.attribute` to specify the attribute you are patching. It +mock provides three convenient decorators for this: :func:`patch`, :func:`patch.object` and +:func:`patch.dict`. ``patch`` takes a single string, of the form +``package.module.Class.attribute`` to specify the attribute you are patching. It also optionally takes a value that you want the attribute (or class or whatever) to be replaced with. 'patch.object' takes an object and the name of the attribute you would like patched, plus optionally the value to patch it with. -`patch.object`: +``patch.object``: >>> original = SomeClass.attribute >>> @patch.object(SomeClass, 'attribute', sentinel.attribute) @@ -338,8 +338,8 @@ with. ... >>> test() -If you are patching a module (including :mod:`builtins`) then use `patch` -instead of `patch.object`: +If you are patching a module (including :mod:`builtins`) then use :func:`patch` +instead of :func:`patch.object`: >>> mock = MagicMock(return_value=sentinel.file_handle) >>> with patch('builtins.open', mock): @@ -348,7 +348,7 @@ instead of `patch.object`: >>> mock.assert_called_with('filename', 'r') >>> assert handle == sentinel.file_handle, "incorrect file handle returned" -The module name can be 'dotted', in the form `package.module` if needed: +The module name can be 'dotted', in the form ``package.module`` if needed: >>> @patch('package.module.ClassName.attribute', sentinel.attribute) ... def test(): @@ -368,8 +368,8 @@ A nice pattern is to actually decorate test methods themselves: >>> MyTest('test_something').test_something() >>> assert SomeClass.attribute == original -If you want to patch with a Mock, you can use `patch` with only one argument -(or `patch.object` with two arguments). The mock will be created for you and +If you want to patch with a Mock, you can use :func:`patch` with only one argument +(or :func:`patch.object` with two arguments). The mock will be created for you and passed into the test function / method: >>> class MyTest(unittest2.TestCase): @@ -394,7 +394,7 @@ You can stack up multiple patch decorators using this pattern: When you nest patch decorators the mocks are passed in to the decorated function in the same order they applied (the normal *python* order that decorators are applied). This means from the bottom up, so in the example -above the mock for `test_module.ClassName2` is passed in first. +above the mock for ``test_module.ClassName2`` is passed in first. There is also :func:`patch.dict` for setting values in a dictionary just during a scope and restoring the dictionary to its original state when the test @@ -407,9 +407,9 @@ ends: ... >>> assert foo == original -`patch`, `patch.object` and `patch.dict` can all be used as context managers. +``patch``, ``patch.object`` and ``patch.dict`` can all be used as context managers. -Where you use `patch` to create a mock for you, you can get a reference to the +Where you use :func:`patch` to create a mock for you, you can get a reference to the mock using the "as" form of the with statement: >>> class ProductionClass: @@ -424,9 +424,9 @@ mock using the "as" form of the with statement: >>> mock_method.assert_called_with(1, 2, 3) -As an alternative `patch`, `patch.object` and `patch.dict` can be used as +As an alternative ``patch``, ``patch.object`` and ``patch.dict`` can be used as class decorators. When used in this way it is the same as applying the -decorator indvidually to every method whose name starts with "test". +decorator individually to every method whose name starts with "test". .. _further-examples: @@ -443,11 +443,11 @@ Mocking chained calls Mocking chained calls is actually straightforward with mock once you understand the :attr:`~Mock.return_value` attribute. When a mock is called for -the first time, or you fetch its `return_value` before it has been called, a -new `Mock` is created. +the first time, or you fetch its ``return_value`` before it has been called, a +new :class:`Mock` is created. This means that you can see how the object returned from a call to a mocked -object has been used by interrogating the `return_value` mock: +object has been used by interrogating the ``return_value`` mock: >>> mock = Mock() >>> mock().foo(a=2, b=3) @@ -467,28 +467,28 @@ So, suppose we have some code that looks a little bit like this: ... response = self.backend.get_endpoint('foobar').create_call('spam', 'eggs').start_call() ... # more code -Assuming that `BackendProvider` is already well tested, how do we test -`method()`? Specifically, we want to test that the code section `# more -code` uses the response object in the correct way. +Assuming that ``BackendProvider`` is already well tested, how do we test +``method()``? Specifically, we want to test that the code section ``# more +code`` uses the response object in the correct way. As this chain of calls is made from an instance attribute we can monkey patch -the `backend` attribute on a `Something` instance. In this particular case +the ``backend`` attribute on a ``Something`` instance. In this particular case we are only interested in the return value from the final call to -`start_call` so we don't have much configuration to do. Let's assume the +``start_call`` so we don't have much configuration to do. Let's assume the object it returns is 'file-like', so we'll ensure that our response object -uses the builtin `file` as its `spec`. +uses the builtin :func:`open` as its ``spec``. To do this we create a mock instance as our mock backend and create a mock response object for it. To set the response as the return value for that final -`start_call` we could do this: +``start_call`` we could do this:: - `mock_backend.get_endpoint.return_value.create_call.return_value.start_call.return_value = mock_response`. + mock_backend.get_endpoint.return_value.create_call.return_value.start_call.return_value = mock_response We can do that in a slightly nicer way using the :meth:`~Mock.configure_mock` method to directly set the return value for us: >>> something = Something() - >>> mock_response = Mock(spec=file) + >>> mock_response = Mock(spec=open) >>> mock_backend = Mock() >>> config = {'get_endpoint.return_value.create_call.return_value.start_call.return_value': mock_response} >>> mock_backend.configure_mock(**config) @@ -501,7 +501,7 @@ call: Using :attr:`~Mock.mock_calls` we can check the chained call with a single assert. A chained call is several calls in one line of code, so there will be -several entries in `mock_calls`. We can use :meth:`call.call_list` to create +several entries in ``mock_calls``. We can use :meth:`call.call_list` to create this list of calls for us: >>> chained = call.get_endpoint('foobar').create_call('spam', 'eggs').start_call() @@ -512,21 +512,20 @@ this list of calls for us: Partial mocking ~~~~~~~~~~~~~~~ -In some tests I wanted to mock out a call to `datetime.date.today() -<http://docs.python.org/library/datetime.html#datetime.date.today>`_ to return -a known date, but I didn't want to prevent the code under test from -creating new date objects. Unfortunately `datetime.date` is written in C, and -so I couldn't just monkey-patch out the static `date.today` method. +In some tests I wanted to mock out a call to :meth:`datetime.date.today` +to return a known date, but I didn't want to prevent the code under test from +creating new date objects. Unfortunately :class:`datetime.date` is written in C, and +so I couldn't just monkey-patch out the static :meth:`date.today` method. I found a simple way of doing this that involved effectively wrapping the date class with a mock, but passing through calls to the constructor to the real class (and returning real instances). The :func:`patch decorator <patch>` is used here to -mock out the `date` class in the module under test. The :attr:`side_effect` +mock out the ``date`` class in the module under test. The :attr:`side_effect` attribute on the mock date class is then set to a lambda function that returns a real date. When the mock date class is called a real date will be -constructed and returned by `side_effect`. +constructed and returned by ``side_effect``. >>> from datetime import date >>> with patch('mymodule.date') as mock_date: @@ -537,34 +536,32 @@ constructed and returned by `side_effect`. ... assert mymodule.date(2009, 6, 8) == date(2009, 6, 8) ... -Note that we don't patch `datetime.date` globally, we patch `date` in the +Note that we don't patch :class:`datetime.date` globally, we patch ``date`` in the module that *uses* it. See :ref:`where to patch <where-to-patch>`. -When `date.today()` is called a known date is returned, but calls to the -`date(...)` constructor still return normal dates. Without this you can find +When ``date.today()`` is called a known date is returned, but calls to the +``date(...)`` constructor still return normal dates. Without this you can find yourself having to calculate an expected result using exactly the same algorithm as the code under test, which is a classic testing anti-pattern. -Calls to the date constructor are recorded in the `mock_date` attributes -(`call_count` and friends) which may also be useful for your tests. +Calls to the date constructor are recorded in the ``mock_date`` attributes +(``call_count`` and friends) which may also be useful for your tests. An alternative way of dealing with mocking dates, or other builtin classes, is discussed in `this blog entry -<http://williamjohnbert.com/2011/07/how-to-unit-testing-in-django-with-mocking-and-patching/>`_. +<http://www.williamjohnbert.com/2011/07/how-to-unit-testing-in-django-with-mocking-and-patching/>`_. Mocking a Generator Method ~~~~~~~~~~~~~~~~~~~~~~~~~~ -A Python generator is a function or method that uses the `yield statement -<http://docs.python.org/reference/simple_stmts.html#the-yield-statement>`_ to -return a series of values when iterated over [#]_. +A Python generator is a function or method that uses the :keyword:`yield` statement +to return a series of values when iterated over [#]_. A generator method / function is called to return the generator object. It is the generator object that is then iterated over. The protocol method for -iteration is `__iter__ -<http://docs.python.org/library/stdtypes.html#container.__iter__>`_, so we can -mock this using a `MagicMock`. +iteration is :meth:`~container.__iter__`, so we can +mock this using a :class:`MagicMock`. Here's an example class with an "iter" method implemented as a generator: @@ -581,7 +578,7 @@ Here's an example class with an "iter" method implemented as a generator: How would we mock this class, and in particular its "iter" method? To configure the values returned from the iteration (implicit in the call to -`list`), we need to configure the object returned by the call to `foo.iter()`. +:class:`list`), we need to configure the object returned by the call to ``foo.iter()``. >>> mock_foo = MagicMock() >>> mock_foo.iter.return_value = iter([1, 2, 3]) @@ -600,10 +597,10 @@ Applying the same patch to every test method If you want several patches in place for multiple test methods the obvious way is to apply the patch decorators to every method. This can feel like unnecessary -repetition. For Python 2.6 or more recent you can use `patch` (in all its +repetition. For Python 2.6 or more recent you can use :func:`patch` (in all its various forms) as a class decorator. This applies the patches to all test methods on the class. A test method is identified by methods whose names start -with `test`: +with ``test``: >>> @patch('mymodule.SomeClass') ... class MyTest(TestCase): @@ -623,7 +620,7 @@ with `test`: 'something' An alternative way of managing patches is to use the :ref:`start-and-stop`. -These allow you to move the patching into your `setUp` and `tearDown` methods. +These allow you to move the patching into your ``setUp`` and ``tearDown`` methods. >>> class MyTest(TestCase): ... def setUp(self): @@ -639,7 +636,7 @@ These allow you to move the patching into your `setUp` and `tearDown` methods. >>> MyTest('test_foo').run() If you use this technique you must ensure that the patching is "undone" by -calling `stop`. This can be fiddlier than you might think, because if an +calling ``stop``. This can be fiddlier than you might think, because if an exception is raised in the setUp then tearDown is not called. :meth:`unittest.TestCase.addCleanup` makes this easier: @@ -669,13 +666,13 @@ function instead. The :func:`patch` decorator makes it so simple to patch out methods with a mock that having to create a real function becomes a nuisance. -If you pass `autospec=True` to patch then it does the patching with a +If you pass ``autospec=True`` to patch then it does the patching with a *real* function object. This function object has the same signature as the one it is replacing, but delegates to a mock under the hood. You still get your mock auto-created in exactly the same way as before. What it means though, is that if you use it to patch out an unbound method on a class the mocked function will be turned into a bound method if it is fetched from an instance. -It will have `self` passed in as the first argument, which is exactly what I +It will have ``self`` passed in as the first argument, which is exactly what I wanted: >>> class Foo: @@ -690,8 +687,8 @@ wanted: 'foo' >>> mock_foo.assert_called_once_with(foo) -If we don't use `autospec=True` then the unbound method is patched out -with a Mock instance instead, and isn't called with `self`. +If we don't use ``autospec=True`` then the unbound method is patched out +with a Mock instance instead, and isn't called with ``self``. Checking multiple calls with mock @@ -715,7 +712,7 @@ If your mock is only being called once you can use the ... AssertionError: Expected to be called once. Called 2 times. -Both `assert_called_with` and `assert_called_once_with` make assertions about +Both ``assert_called_with`` and ``assert_called_once_with`` make assertions about the *most recent* call. If your mock is going to be called several times, and you want to make assertions about *all* those calls you can use :attr:`~Mock.call_args_list`: @@ -728,8 +725,8 @@ you want to make assertions about *all* those calls you can use [call(1, 2, 3), call(4, 5, 6), call()] The :data:`call` helper makes it easy to make assertions about these calls. You -can build up a list of expected calls and compare it to `call_args_list`. This -looks remarkably similar to the repr of the `call_args_list`: +can build up a list of expected calls and compare it to ``call_args_list``. This +looks remarkably similar to the repr of the ``call_args_list``: >>> expected = [call(1, 2, 3), call(4, 5, 6), call()] >>> mock.call_args_list == expected @@ -740,7 +737,7 @@ Coping with mutable arguments ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Another situation is rare, but can bite you, is when your mock is called with -mutable arguments. `call_args` and `call_args_list` store *references* to the +mutable arguments. ``call_args`` and ``call_args_list`` store *references* to the arguments. If the arguments are mutated by the code under test then you can no longer make assertions about what the values were when the mock was called. @@ -755,28 +752,28 @@ defined in 'mymodule':: frob(val) val.clear() -When we try to test that `grob` calls `frob` with the correct argument look +When we try to test that ``grob`` calls ``frob`` with the correct argument look what happens: >>> with patch('mymodule.frob') as mock_frob: - ... val = set([6]) + ... val = {6} ... mymodule.grob(val) ... >>> val - set([]) - >>> mock_frob.assert_called_with(set([6])) + set() + >>> mock_frob.assert_called_with({6}) Traceback (most recent call last): ... - AssertionError: Expected: ((set([6]),), {}) - Called with: ((set([]),), {}) + AssertionError: Expected: (({6},), {}) + Called with: ((set(),), {}) One possibility would be for mock to copy the arguments you pass in. This could then cause problems if you do assertions that rely on object identity for equality. Here's one solution that uses the :attr:`side_effect` -functionality. If you provide a `side_effect` function for a mock then -`side_effect` will be called with the same args as the mock. This gives us an +functionality. If you provide a ``side_effect`` function for a mock then +``side_effect`` will be called with the same args as the mock. This gives us an opportunity to copy the arguments and store them for later assertions. In this example I'm using *another* mock to store the arguments so that I can use the mock methods for doing the assertion. Again a helper function sets this up for @@ -796,35 +793,35 @@ me. ... >>> with patch('mymodule.frob') as mock_frob: ... new_mock = copy_call_args(mock_frob) - ... val = set([6]) + ... val = {6} ... mymodule.grob(val) ... - >>> new_mock.assert_called_with(set([6])) + >>> new_mock.assert_called_with({6}) >>> new_mock.call_args - call(set([6])) + call({6}) -`copy_call_args` is called with the mock that will be called. It returns a new -mock that we do the assertion on. The `side_effect` function makes a copy of -the args and calls our `new_mock` with the copy. +``copy_call_args`` is called with the mock that will be called. It returns a new +mock that we do the assertion on. The ``side_effect`` function makes a copy of +the args and calls our ``new_mock`` with the copy. .. note:: If your mock is only going to be used once there is an easier way of checking arguments at the point they are called. You can simply do the - checking inside a `side_effect` function. + checking inside a ``side_effect`` function. >>> def side_effect(arg): - ... assert arg == set([6]) + ... assert arg == {6} ... >>> mock = Mock(side_effect=side_effect) - >>> mock(set([6])) + >>> mock({6}) >>> mock(set()) Traceback (most recent call last): ... AssertionError -An alternative approach is to create a subclass of `Mock` or `MagicMock` that -copies (using :func:`copy.deepcopy`) the arguments. +An alternative approach is to create a subclass of :class:`Mock` or +:class:`MagicMock` that copies (using :func:`copy.deepcopy`) the arguments. Here's an example implementation: >>> from copy import deepcopy @@ -842,14 +839,14 @@ Here's an example implementation: >>> c.assert_called_with(arg) Traceback (most recent call last): ... - AssertionError: Expected call: mock(set([1])) - Actual call: mock(set([])) + AssertionError: Expected call: mock({1}) + Actual call: mock(set()) >>> c.foo <CopyingMock name='mock.foo' id='...'> -When you subclass `Mock` or `MagicMock` all dynamically created attributes, -and the `return_value` will use your subclass automatically. That means all -children of a `CopyingMock` will also have the type `CopyingMock`. +When you subclass ``Mock`` or ``MagicMock`` all dynamically created attributes, +and the ``return_value`` will use your subclass automatically. That means all +children of a ``CopyingMock`` will also have the type ``CopyingMock``. Nesting Patches @@ -873,9 +870,9 @@ right: >>> MyTest('test_foo').test_foo() >>> assert mymodule.Foo is original -With unittest `cleanup` functions and the :ref:`start-and-stop` we can +With unittest ``cleanup`` functions and the :ref:`start-and-stop` we can achieve the same effect without the nested indentation. A simple helper -method, `create_patch`, puts the patch in place and returns the created mock +method, ``create_patch``, puts the patch in place and returns the created mock for us: >>> class MyTest(TestCase): @@ -910,11 +907,11 @@ We can do this with :class:`MagicMock`, which will behave like a dictionary, and using :data:`~Mock.side_effect` to delegate dictionary access to a real underlying dictionary that is under our control. -When the `__getitem__` and `__setitem__` methods of our `MagicMock` are called -(normal dictionary access) then `side_effect` is called with the key (and in -the case of `__setitem__` the value too). We can also control what is returned. +When the :meth:`__getitem__` and :meth:`__setitem__` methods of our ``MagicMock`` are called +(normal dictionary access) then ``side_effect`` is called with the key (and in +the case of ``__setitem__`` the value too). We can also control what is returned. -After the `MagicMock` has been used we can use attributes like +After the ``MagicMock`` has been used we can use attributes like :data:`~Mock.call_args_list` to assert about how the dictionary was used: >>> my_dict = {'a': 1, 'b': 2, 'c': 3} @@ -930,23 +927,23 @@ After the `MagicMock` has been used we can use attributes like .. note:: - An alternative to using `MagicMock` is to use `Mock` and *only* provide + An alternative to using ``MagicMock`` is to use ``Mock`` and *only* provide the magic methods you specifically want: >>> mock = Mock() - >>> mock.__setitem__ = Mock(side_effect=getitem) - >>> mock.__getitem__ = Mock(side_effect=setitem) + >>> mock.__getitem__ = Mock(side_effect=getitem) + >>> mock.__setitem__ = Mock(side_effect=setitem) - A *third* option is to use `MagicMock` but passing in `dict` as the `spec` - (or `spec_set`) argument so that the `MagicMock` created only has + A *third* option is to use ``MagicMock`` but passing in ``dict`` as the *spec* + (or *spec_set*) argument so that the ``MagicMock`` created only has dictionary magic methods available: >>> mock = MagicMock(spec_set=dict) >>> mock.__getitem__.side_effect = getitem >>> mock.__setitem__.side_effect = setitem -With these side effect functions in place, the `mock` will behave like a normal -dictionary but recording the access. It even raises a `KeyError` if you try +With these side effect functions in place, the ``mock`` will behave like a normal +dictionary but recording the access. It even raises a :exc:`KeyError` if you try to access a key that doesn't exist. >>> mock['a'] @@ -978,8 +975,8 @@ mock methods and attributes: Mock subclasses and their attributes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -There are various reasons why you might want to subclass `Mock`. One reason -might be to add helper methods. Here's a silly example: +There are various reasons why you might want to subclass :class:`Mock`. One +reason might be to add helper methods. Here's a silly example: >>> class MyMock(MagicMock): ... def has_been_called(self): @@ -994,9 +991,9 @@ might be to add helper methods. Here's a silly example: >>> mymock.has_been_called() True -The standard behaviour for `Mock` instances is that attributes and the return +The standard behaviour for ``Mock`` instances is that attributes and the return value mocks are of the same type as the mock they are accessed on. This ensures -that `Mock` attributes are `Mocks` and `MagicMock` attributes are `MagicMocks` +that ``Mock`` attributes are ``Mocks`` and ``MagicMock`` attributes are ``MagicMocks`` [#]_. So if you're subclassing to add helper methods then they'll also be available on the attributes and return value mock of instances of your subclass. @@ -1016,10 +1013,10 @@ created a `Twisted adaptor <http://twistedmatrix.com/documents/11.0.0/api/twisted.python.components.html>`_. Having this applied to attributes too actually causes errors. -`Mock` (in all its flavours) uses a method called `_get_child_mock` to create +``Mock`` (in all its flavours) uses a method called ``_get_child_mock`` to create these "sub-mocks" for attributes and return values. You can prevent your subclass being used for attributes by overriding this method. The signature is -that it takes arbitrary keyword arguments (`**kwargs`) which are then passed +that it takes arbitrary keyword arguments (``**kwargs``) which are then passed onto the mock constructor: >>> class Subclass(MagicMock): @@ -1052,17 +1049,17 @@ import. This can also be solved in better ways than an unconditional local import (store the module as a class or module attribute and only do the import on first use). -That aside there is a way to use `mock` to affect the results of an import. -Importing fetches an *object* from the `sys.modules` dictionary. Note that it +That aside there is a way to use ``mock`` to affect the results of an import. +Importing fetches an *object* from the :data:`sys.modules` dictionary. Note that it fetches an *object*, which need not be a module. Importing a module for the first time results in a module object being put in `sys.modules`, so usually when you import something you get a module back. This need not be the case however. This means you can use :func:`patch.dict` to *temporarily* put a mock in place -in `sys.modules`. Any imports whilst this patch is active will fetch the mock. +in :data:`sys.modules`. Any imports whilst this patch is active will fetch the mock. When the patch is complete (the decorated function exits, the with statement -body is complete or `patcher.stop()` is called) then whatever was there +body is complete or ``patcher.stop()`` is called) then whatever was there previously will be restored safely. Here's an example that mocks out the 'fooble' module. @@ -1076,10 +1073,10 @@ Here's an example that mocks out the 'fooble' module. >>> assert 'fooble' not in sys.modules >>> mock.blob.assert_called_once_with() -As you can see the `import fooble` succeeds, but on exit there is no 'fooble' -left in `sys.modules`. +As you can see the ``import fooble`` succeeds, but on exit there is no 'fooble' +left in :data:`sys.modules`. -This also works for the `from module import name` form: +This also works for the ``from module import name`` form: >>> mock = Mock() >>> with patch.dict('sys.modules', {'fooble': mock}): @@ -1109,10 +1106,10 @@ your mock objects through the :attr:`~Mock.method_calls` attribute. This doesn't allow you to track the order of calls between separate mock objects, however we can use :attr:`~Mock.mock_calls` to achieve the same effect. -Because mocks track calls to child mocks in `mock_calls`, and accessing an +Because mocks track calls to child mocks in ``mock_calls``, and accessing an arbitrary attribute of a mock creates a child mock, we can create our separate mocks from a parent one. Calls to those child mock will then all be recorded, -in order, in the `mock_calls` of the parent: +in order, in the ``mock_calls`` of the parent: >>> manager = Mock() >>> mock_foo = manager.foo @@ -1127,15 +1124,15 @@ in order, in the `mock_calls` of the parent: [call.foo.something(), call.bar.other.thing()] We can then assert about the calls, including the order, by comparing with -the `mock_calls` attribute on the manager mock: +the ``mock_calls`` attribute on the manager mock: >>> expected_calls = [call.foo.something(), call.bar.other.thing()] >>> manager.mock_calls == expected_calls True -If `patch` is creating, and putting in place, your mocks then you can attach +If ``patch`` is creating, and putting in place, your mocks then you can attach them to a manager mock using the :meth:`~Mock.attach_mock` method. After -attaching calls will be recorded in `mock_calls` of the manager. +attaching calls will be recorded in ``mock_calls`` of the manager. >>> manager = MagicMock() >>> with patch('mymodule.Class1') as MockClass1: @@ -1167,12 +1164,12 @@ with the :data:`call` object). If that sequence of calls are in >>> calls = call.one().two().three().call_list() >>> m.assert_has_calls(calls) -Even though the chained call `m.one().two().three()` aren't the only calls that +Even though the chained call ``m.one().two().three()`` aren't the only calls that have been made to the mock, the assert still succeeds. Sometimes a mock may have several calls made to it, and you are only interested in asserting about *some* of those calls. You may not even care about the -order. In this case you can pass `any_order=True` to `assert_has_calls`: +order. In this case you can pass ``any_order=True`` to ``assert_has_calls``: >>> m = MagicMock() >>> m(1), m.two(2, 3), m.seven(7), m.fifty('50') @@ -1194,7 +1191,7 @@ in the exact same object. If we are only interested in some of the attributes of this object then we can create a matcher that will check these attributes for us. -You can see in this example how a 'standard' call to `assert_called_with` isn't +You can see in this example how a 'standard' call to ``assert_called_with`` isn't sufficient: >>> class Foo: @@ -1209,7 +1206,7 @@ sufficient: AssertionError: Expected: call(<__main__.Foo object at 0x...>) Actual call: call(<__main__.Foo object at 0x...>) -A comparison function for our `Foo` class might look something like this: +A comparison function for our ``Foo`` class might look something like this: >>> def compare(self, other): ... if not type(self) == type(other): @@ -1237,11 +1234,11 @@ Putting all this together: >>> match_foo = Matcher(compare, Foo(1, 2)) >>> mock.assert_called_with(match_foo) -The `Matcher` is instantiated with our compare function and the `Foo` object -we want to compare against. In `assert_called_with` the `Matcher` equality +The ``Matcher`` is instantiated with our compare function and the ``Foo`` object +we want to compare against. In ``assert_called_with`` the ``Matcher`` equality method will be called, which compares the object the mock was called with against the one we created our matcher with. If they match then -`assert_called_with` passes, and if they don't an `AssertionError` is raised: +``assert_called_with`` passes, and if they don't an :exc:`AssertionError` is raised: >>> match_wrong = Matcher(compare, Foo(3, 4)) >>> mock.assert_called_with(match_wrong) @@ -1251,10 +1248,10 @@ against the one we created our matcher with. If they match then Called with: ((<Foo object at 0x...>,), {}) With a bit of tweaking you could have the comparison function raise the -`AssertionError` directly and provide a more useful failure message. +:exc:`AssertionError` directly and provide a more useful failure message. As of version 1.5, the Python testing library `PyHamcrest -<http://pypi.python.org/pypi/PyHamcrest>`_ provides similar functionality, +<https://pypi.python.org/pypi/PyHamcrest>`_ provides similar functionality, that may be useful here, in the form of its equality matcher (`hamcrest.library.integration.match_equality -<http://packages.python.org/PyHamcrest/integration.html#hamcrest.library.integration.match_equality>`_). +<http://pythonhosted.org/PyHamcrest/integration.html#hamcrest.library.integration.match_equality.match_equality>`_). diff --git a/Doc/library/unittest.mock.rst b/Doc/library/unittest.mock.rst index 135abeb143b8..c19adf811308 100644 --- a/Doc/library/unittest.mock.rst +++ b/Doc/library/unittest.mock.rst @@ -13,7 +13,7 @@ replace parts of your system under test with mock objects and make assertions about how they have been used. -`unittest.mock` provides a core :class:`Mock` class removing the need to +:mod:`unittest.mock` provides a core :class:`Mock` class removing the need to create a host of stubs throughout your test suite. After performing an action, you can make assertions about which methods / attributes were used and arguments they were called with. You can also specify return values and @@ -26,11 +26,11 @@ some examples of how to use :class:`Mock`, :class:`MagicMock` and :func:`patch`. Mock is very easy to use and is designed for use with :mod:`unittest`. Mock -is based on the 'action -> assertion' pattern instead of `'record -> replay'` +is based on the 'action -> assertion' pattern instead of 'record -> replay' used by many mocking frameworks. -There is a backport of `unittest.mock` for earlier versions of Python, -available as `mock on PyPI <http://pypi.python.org/pypi/mock>`_. +There is a backport of :mod:`unittest.mock` for earlier versions of Python, +available as `mock on PyPI <https://pypi.python.org/pypi/mock>`_. **Source code:** :source:`Lib/unittest/mock.py` @@ -71,9 +71,9 @@ exception when a mock is called: (5, 4, 3) Mock has many other ways you can configure it and control its behaviour. For -example the `spec` argument configures the mock to take its specification +example the *spec* argument configures the mock to take its specification from another object. Attempting to access attributes or methods on the mock -that don't exist on the spec will fail with an `AttributeError`. +that don't exist on the spec will fail with an :exc:`AttributeError`. The :func:`patch` decorator / context manager makes it easy to mock classes or objects in a module under test. The object you specify will be replaced with a @@ -97,13 +97,13 @@ mock (or other object) during the test and restored when the test ends: When you nest patch decorators the mocks are passed in to the decorated function in the same order they applied (the normal *python* order that decorators are applied). This means from the bottom up, so in the example - above the mock for `module.ClassName1` is passed in first. + above the mock for ``module.ClassName1`` is passed in first. - With `patch` it matters that you patch objects in the namespace where they + With :func:`patch` it matters that you patch objects in the namespace where they are looked up. This is normally straightforward, but for a quick guide read :ref:`where to patch <where-to-patch>`. -As well as a decorator `patch` can be used as a context manager in a with +As well as a decorator :func:`patch` can be used as a context manager in a with statement: >>> with patch.object(ProductionClass, 'method', return_value=None) as mock_method: @@ -135,7 +135,7 @@ allows you to do things like: >>> mock.__str__.assert_called_with() Mock allows you to assign functions (or other Mock instances) to magic methods -and they will be called appropriately. The `MagicMock` class is just a Mock +and they will be called appropriately. The :class:`MagicMock` class is just a Mock variant that has all of the magic methods pre-created for you (well, all the useful ones anyway). @@ -149,7 +149,7 @@ class: For ensuring that the mock objects in your tests have the same api as the objects they are replacing, you can use :ref:`auto-speccing <auto-speccing>`. -Auto-speccing can be done through the `autospec` argument to patch, or the +Auto-speccing can be done through the *autospec* argument to patch, or the :func:`create_autospec` function. Auto-speccing creates mock objects that have the same attributes and methods as the objects they are replacing, and any functions and methods (including constructors) have the same call @@ -171,9 +171,9 @@ code if they are used incorrectly: ... TypeError: <lambda>() takes exactly 3 arguments (1 given) -`create_autospec` can also be used on classes, where it copies the signature of -the `__init__` method, and on callable objects where it copies the signature of -the `__call__` method. +:func:`create_autospec` can also be used on classes, where it copies the signature of +the ``__init__`` method, and on callable objects where it copies the signature of +the ``__call__`` method. @@ -181,71 +181,77 @@ The Mock Class -------------- -`Mock` is a flexible mock object intended to replace the use of stubs and +:class:`Mock` is a flexible mock object intended to replace the use of stubs and test doubles throughout your code. Mocks are callable and create attributes as new mocks when you access them [#]_. Accessing the same attribute will always return the same mock. Mocks record how you use them, allowing you to make assertions about what your code has done to them. -:class:`MagicMock` is a subclass of `Mock` with all the magic methods +:class:`MagicMock` is a subclass of :class:`Mock` with all the magic methods pre-created and ready to use. There are also non-callable variants, useful when you are mocking out objects that aren't callable: :class:`NonCallableMock` and :class:`NonCallableMagicMock` The :func:`patch` decorators makes it easy to temporarily replace classes -in a particular module with a `Mock` object. By default `patch` will create -a `MagicMock` for you. You can specify an alternative class of `Mock` using -the `new_callable` argument to `patch`. +in a particular module with a :class:`Mock` object. By default :func:`patch` will create +a :class:`MagicMock` for you. You can specify an alternative class of :class:`Mock` using +the *new_callable* argument to :func:`patch`. -.. class:: Mock(spec=None, side_effect=None, return_value=DEFAULT, wraps=None, name=None, spec_set=None, **kwargs) +.. class:: Mock(spec=None, side_effect=None, return_value=DEFAULT, wraps=None, name=None, spec_set=None, unsafe=False, **kwargs) - Create a new `Mock` object. `Mock` takes several optional arguments + Create a new :class:`Mock` object. :class:`Mock` takes several optional arguments that specify the behaviour of the Mock object: - * `spec`: This can be either a list of strings or an existing object (a + * *spec*: This can be either a list of strings or an existing object (a class or instance) that acts as the specification for the mock object. If you pass in an object then a list of strings is formed by calling dir on the object (excluding unsupported magic attributes and methods). - Accessing any attribute not in this list will raise an `AttributeError`. + Accessing any attribute not in this list will raise an :exc:`AttributeError`. - If `spec` is an object (rather than a list of strings) then + If *spec* is an object (rather than a list of strings) then :attr:`~instance.__class__` returns the class of the spec object. This - allows mocks to pass `isinstance` tests. + allows mocks to pass :func:`isinstance` tests. - * `spec_set`: A stricter variant of `spec`. If used, attempting to *set* + * *spec_set*: A stricter variant of *spec*. If used, attempting to *set* or get an attribute on the mock that isn't on the object passed as - `spec_set` will raise an `AttributeError`. + *spec_set* will raise an :exc:`AttributeError`. - * `side_effect`: A function to be called whenever the Mock is called. See + * *side_effect*: A function to be called whenever the Mock is called. See the :attr:`~Mock.side_effect` attribute. Useful for raising exceptions or dynamically changing return values. The function is called with the same arguments as the mock, and unless it returns :data:`DEFAULT`, the return value of this function is used as the return value. - Alternatively `side_effect` can be an exception class or instance. In + Alternatively *side_effect* can be an exception class or instance. In this case the exception will be raised when the mock is called. - If `side_effect` is an iterable then each call to the mock will return + If *side_effect* is an iterable then each call to the mock will return the next value from the iterable. - A `side_effect` can be cleared by setting it to `None`. + A *side_effect* can be cleared by setting it to ``None``. - * `return_value`: The value returned when the mock is called. By default + * *return_value*: The value returned when the mock is called. By default this is a new Mock (created on first access). See the :attr:`return_value` attribute. - * `wraps`: Item for the mock object to wrap. If `wraps` is not None then + * *unsafe*: By default if any attribute starts with *assert* or + *assret* will raise an :exc:`AttributeError`. Passing ``unsafe=True`` + will allow access to these attributes. + + .. versionadded:: 3.5 + + * *wraps*: Item for the mock object to wrap. If *wraps* is not None then calling the Mock will pass the call through to the wrapped object (returning the real result). Attribute access on the mock will return a Mock object that wraps the corresponding attribute of the wrapped object (so attempting to access an attribute that doesn't exist will - raise an `AttributeError`). + raise an :exc:`AttributeError`). - If the mock has an explicit `return_value` set then calls are not passed - to the wrapped object and the `return_value` is returned instead. + If the mock has an explicit *return_value* set then calls are not passed + to the wrapped object and the *return_value* is returned instead. - * `name`: If the mock has a name then it will be used in the repr of the + * *name*: If the mock has a name then it will be used in the repr of the mock. This can be useful for debugging. The name is propagated to child mocks. @@ -296,13 +302,13 @@ the `new_callable` argument to `patch`. .. method:: assert_has_calls(calls, any_order=False) assert the mock has been called with the specified calls. - The `mock_calls` list is checked for the calls. + The :attr:`mock_calls` list is checked for the calls. - If `any_order` is false (the default) then the calls must be + If *any_order* is false (the default) then the calls must be sequential. There can be extra calls before or after the specified calls. - If `any_order` is true then the calls can be in any order, but + If *any_order* is true then the calls can be in any order, but they must all appear in :attr:`mock_calls`. >>> mock = Mock(return_value=None) @@ -315,6 +321,20 @@ the `new_callable` argument to `patch`. >>> calls = [call(4), call(2), call(3)] >>> mock.assert_has_calls(calls, any_order=True) + .. method:: assert_not_called(*args, **kwargs) + + Assert the mock was never called. + + >>> m = Mock() + >>> m.hello.assert_not_called() + >>> obj = m.hello() + >>> m.hello.assert_not_called() + Traceback (most recent call last): + ... + AssertionError: Expected 'hello' to not have been called. Called 1 times. + + .. versionadded:: 3.5 + .. method:: reset_mock() @@ -329,7 +349,7 @@ the `new_callable` argument to `patch`. False This can be useful where you want to make a series of assertions that - reuse the same object. Note that `reset_mock` *doesn't* clear the + reuse the same object. Note that :meth:`reset_mock` *doesn't* clear the return value, :attr:`side_effect` or any child attributes you have set using normal assignment. Child mocks and the return value mock (if any) are reset as well. @@ -337,11 +357,11 @@ the `new_callable` argument to `patch`. .. method:: mock_add_spec(spec, spec_set=False) - Add a spec to a mock. `spec` can either be an object or a - list of strings. Only attributes on the `spec` can be fetched as + Add a spec to a mock. *spec* can either be an object or a + list of strings. Only attributes on the *spec* can be fetched as attributes from the mock. - If `spec_set` is `True` then only attributes on the spec can be set. + If *spec_set* is true then only attributes on the spec can be set. .. method:: attach_mock(mock, attribute) @@ -382,14 +402,14 @@ the `new_callable` argument to `patch`. ... KeyError - `configure_mock` exists to make it easier to do configuration + :meth:`configure_mock` exists to make it easier to do configuration after the mock has been created. .. method:: __dir__() - `Mock` objects limit the results of `dir(some_mock)` to useful results. - For mocks with a `spec` this includes all the permitted attributes + :class:`Mock` objects limit the results of ``dir(some_mock)`` to useful results. + For mocks with a *spec* this includes all the permitted attributes for the mock. See :data:`FILTER_DIR` for what this filtering does, and how to @@ -449,7 +469,7 @@ the `new_callable` argument to `patch`. <Mock name='mock()()' id='...'> >>> mock.return_value.assert_called_with() - `return_value` can also be set in the constructor: + :attr:`return_value` can also be set in the constructor: >>> mock = Mock(return_value=3) >>> mock.return_value @@ -461,7 +481,7 @@ the `new_callable` argument to `patch`. .. attribute:: side_effect This can either be a function to be called when the mock is called, - or an exception (class or instance) to be raised. + an iterable or an exception (class or instance) to be raised. If you pass in a function it will be called with same arguments as the mock and unless the function returns the :data:`DEFAULT` singleton the @@ -469,6 +489,11 @@ the `new_callable` argument to `patch`. function returns :data:`DEFAULT` then the mock will return its normal value (from the :attr:`return_value`). + If you pass in an iterable, it is used to retrieve an iterator which + must yield a value on every call. This value can either be an exception + instance to be raised, or a value to be returned from the call to the + mock (:data:`DEFAULT` handling is identical to the function case). + An example of a mock that raises an exception (to test exception handling of an API): @@ -479,18 +504,14 @@ the `new_callable` argument to `patch`. ... Exception: Boom! - Using `side_effect` to return a sequence of values: + Using :attr:`side_effect` to return a sequence of values: >>> mock = Mock() >>> mock.side_effect = [3, 2, 1] >>> mock(), mock(), mock() (3, 2, 1) - The `side_effect` function is called with the same arguments as the - mock (so it is wise for it to take arbitrary args and keyword - arguments) and whatever it returns is used as the return value for - the call. The exception is if `side_effect` returns :data:`DEFAULT`, - in which case the normal :attr:`return_value` is used. + Using a callable: >>> mock = Mock(return_value=3) >>> def side_effect(*args, **kwargs): @@ -500,7 +521,7 @@ the `new_callable` argument to `patch`. >>> mock() 3 - `side_effect` can be set in the constructor. Here's an example that + :attr:`side_effect` can be set in the constructor. Here's an example that adds one to the value the mock is called with and returns it: >>> side_effect = lambda value: value + 1 @@ -510,7 +531,7 @@ the `new_callable` argument to `patch`. >>> mock(-8) -7 - Setting `side_effect` to `None` clears it: + Setting :attr:`side_effect` to ``None`` clears it: >>> m = Mock(side_effect=KeyError, return_value=3) >>> m() @@ -524,7 +545,7 @@ the `new_callable` argument to `patch`. .. attribute:: call_args - This is either `None` (if the mock hasn't been called), or the + This is either ``None`` (if the mock hasn't been called), or the arguments that the mock was last called with. This will be in the form of a tuple: the first member is any ordered arguments the mock was called with (or an empty tuple) and the second member is any @@ -547,7 +568,7 @@ the `new_callable` argument to `patch`. >>> mock.call_args call(3, 4, 5, key='fish', next='w00t!') - `call_args`, along with members of the lists :attr:`call_args_list`, + :attr:`call_args`, along with members of the lists :attr:`call_args_list`, :attr:`method_calls` and :attr:`mock_calls` are :data:`call` objects. These are tuples, so they can be unpacked to get at the individual arguments and make more complex assertions. See @@ -560,7 +581,7 @@ the `new_callable` argument to `patch`. (so the length of the list is the number of times it has been called). Before any calls have been made it is an empty list. The :data:`call` object can be used for conveniently constructing lists of - calls to compare with `call_args_list`. + calls to compare with :attr:`call_args_list`. >>> mock = Mock(return_value=None) >>> mock() @@ -572,7 +593,7 @@ the `new_callable` argument to `patch`. >>> mock.call_args_list == expected True - Members of `call_args_list` are :data:`call` objects. These can be + Members of :attr:`call_args_list` are :data:`call` objects. These can be unpacked as tuples to get at the individual arguments. See :ref:`calls as tuples <calls-as-tuples>`. @@ -590,15 +611,15 @@ the `new_callable` argument to `patch`. >>> mock.method_calls [call.method(), call.property.method.attribute()] - Members of `method_calls` are :data:`call` objects. These can be + Members of :attr:`method_calls` are :data:`call` objects. These can be unpacked as tuples to get at the individual arguments. See :ref:`calls as tuples <calls-as-tuples>`. .. attribute:: mock_calls - `mock_calls` records *all* calls to the mock object, its methods, magic - methods *and* return value mocks. + :attr:`mock_calls` records *all* calls to the mock object, its methods, + magic methods *and* return value mocks. >>> mock = MagicMock() >>> result = mock(1, 2, 3) @@ -615,24 +636,24 @@ the `new_callable` argument to `patch`. >>> mock.mock_calls == expected True - Members of `mock_calls` are :data:`call` objects. These can be + Members of :attr:`mock_calls` are :data:`call` objects. These can be unpacked as tuples to get at the individual arguments. See :ref:`calls as tuples <calls-as-tuples>`. .. attribute:: __class__ - Normally the `__class__` attribute of an object will return its type. - For a mock object with a `spec` `__class__` returns the spec class - instead. This allows mock objects to pass `isinstance` tests for the + Normally the :attr:`__class__` attribute of an object will return its type. + For a mock object with a :attr:`spec`, ``__class__`` returns the spec class + instead. This allows mock objects to pass :func:`isinstance` tests for the object they are replacing / masquerading as: >>> mock = Mock(spec=3) >>> isinstance(mock, int) True - `__class__` is assignable to, this allows a mock to pass an - `isinstance` check without forcing you to use a spec: + :attr:`__class__` is assignable to, this allows a mock to pass an + :func:`isinstance` check without forcing you to use a spec: >>> mock = Mock() >>> mock.__class__ = dict @@ -641,12 +662,12 @@ the `new_callable` argument to `patch`. .. class:: NonCallableMock(spec=None, wraps=None, name=None, spec_set=None, **kwargs) - A non-callable version of `Mock`. The constructor parameters have the same - meaning of `Mock`, with the exception of `return_value` and `side_effect` + A non-callable version of :class:`Mock`. The constructor parameters have the same + meaning of :class:`Mock`, with the exception of *return_value* and *side_effect* which have no meaning on a non-callable mock. -Mock objects that use a class or an instance as a `spec` or `spec_set` are able -to pass `isinstance` tests: +Mock objects that use a class or an instance as a :attr:`spec` or +:attr:`spec_set` are able to pass :func:`isinstance` tests: >>> mock = Mock(spec=SomeClass) >>> isinstance(mock, SomeClass) @@ -655,11 +676,11 @@ to pass `isinstance` tests: >>> isinstance(mock, SomeClass) True -The `Mock` classes have support for mocking magic methods. See :ref:`magic +The :class:`Mock` classes have support for mocking magic methods. See :ref:`magic methods <magic-methods>` for the full details. The mock classes and the :func:`patch` decorators all take arbitrary keyword -arguments for configuration. For the `patch` decorators the keywords are +arguments for configuration. For the :func:`patch` decorators the keywords are passed to the constructor of the mock being created. The keyword arguments are for configuring attributes of the mock: @@ -671,7 +692,7 @@ are for configuring attributes of the mock: The return value and side effect of child mocks can be set in the same way, using dotted notation. As you can't use dotted names directly in a call you -have to create a dictionary and unpack it using `**`: +have to create a dictionary and unpack it using ``**``: >>> attrs = {'method.return_value': 3, 'other.side_effect': KeyError} >>> mock = Mock(some_attribute='eggs', **attrs) @@ -709,10 +730,10 @@ apply to method calls on the mock object. .. class:: PropertyMock(*args, **kwargs) A mock intended to be used as a property, or other descriptor, on a class. - `PropertyMock` provides `__get__` and `__set__` methods so you can specify - a return value when it is fetched. + :class:`PropertyMock` provides :meth:`__get__` and :meth:`__set__` methods + so you can specify a return value when it is fetched. - Fetching a `PropertyMock` instance from an object calls the mock, with + Fetching a :class:`PropertyMock` instance from an object calls the mock, with no args. Setting it calls the mock with the value being set. >>> class Foo: @@ -734,7 +755,7 @@ apply to method calls on the mock object. [call(), call(6)] Because of the way mock attributes are stored you can't directly attach a -`PropertyMock` to a mock object. Instead you can attach it to the mock type +:class:`PropertyMock` to a mock object. Instead you can attach it to the mock type object:: >>> m = MagicMock() @@ -758,7 +779,7 @@ Calls made to the object will be recorded in the attributes like :attr:`~Mock.call_args` and :attr:`~Mock.call_args_list`. If :attr:`~Mock.side_effect` is set then it will be called after the call has -been recorded, so if `side_effect` raises an exception the call is still +been recorded, so if :attr:`side_effect` raises an exception the call is still recorded. The simplest way to make a mock raise an exception when called is to make @@ -779,8 +800,8 @@ The simplest way to make a mock raise an exception when called is to make >>> m.mock_calls [call(1, 2, 3), call('two', 'three', 'four')] -If `side_effect` is a function then whatever that function returns is what -calls to the mock return. The `side_effect` function is called with the +If :attr:`side_effect` is a function then whatever that function returns is what +calls to the mock return. The :attr:`side_effect` function is called with the same arguments as the mock. This allows you to vary the return value of the call dynamically, based on the input: @@ -797,7 +818,7 @@ call dynamically, based on the input: If you want the mock to still return the default return value (a new mock), or any set return value, then there are two ways of doing this. Either return -`mock.return_value` from inside `side_effect`, or return :data:`DEFAULT`: +:attr:`mock.return_value` from inside :attr:`side_effect`, or return :data:`DEFAULT`: >>> m = MagicMock() >>> def side_effect(*args, **kwargs): @@ -814,8 +835,8 @@ any set return value, then there are two ways of doing this. Either return >>> m() 3 -To remove a `side_effect`, and return to the default behaviour, set the -`side_effect` to `None`: +To remove a :attr:`side_effect`, and return to the default behaviour, set the +:attr:`side_effect` to ``None``: >>> m = MagicMock(return_value=6) >>> def side_effect(*args, **kwargs): @@ -828,9 +849,9 @@ To remove a `side_effect`, and return to the default behaviour, set the >>> m() 6 -The `side_effect` can also be any iterable object. Repeated calls to the mock +The :attr:`side_effect` can also be any iterable object. Repeated calls to the mock will return values from the iterable (until the iterable is exhausted and -a `StopIteration` is raised): +a :exc:`StopIteration` is raised): >>> m = MagicMock(side_effect=[1, 2, 3]) >>> m() @@ -867,12 +888,12 @@ Deleting Attributes Mock objects create attributes on demand. This allows them to pretend to be objects of any type. -You may want a mock object to return `False` to a `hasattr` call, or raise an -`AttributeError` when an attribute is fetched. You can do this by providing -an object as a `spec` for a mock, but that isn't always convenient. +You may want a mock object to return ``False`` to a :func:`hasattr` call, or raise an +:exc:`AttributeError` when an attribute is fetched. You can do this by providing +an object as a :attr:`spec` for a mock, but that isn't always convenient. You "block" attributes by deleting them. Once deleted, accessing an attribute -will raise an `AttributeError`. +will raise an :exc:`AttributeError`. >>> mock = MagicMock() >>> hasattr(mock, 'm') @@ -958,7 +979,7 @@ method: .. [#] The only exceptions are magic methods and attributes (those that have leading and trailing double underscores). Mock doesn't create these but - instead of raises an ``AttributeError``. This is because the interpreter + instead raises an :exc:`AttributeError`. This is because the interpreter will often implicitly request these methods, and gets *very* confused to get a new Mock object when it expects a magic method. If you need magic method support see :ref:`magic methods <magic-methods>`. @@ -978,78 +999,84 @@ patch .. note:: - `patch` is straightforward to use. The key is to do the patching in the + :func:`patch` is straightforward to use. The key is to do the patching in the right namespace. See the section `where to patch`_. .. function:: patch(target, new=DEFAULT, spec=None, create=False, spec_set=None, autospec=None, new_callable=None, **kwargs) - `patch` acts as a function decorator, class decorator or a context - manager. Inside the body of the function or with statement, the `target` - is patched with a `new` object. When the function/with statement exits + :func:`patch` acts as a function decorator, class decorator or a context + manager. Inside the body of the function or with statement, the *target* + is patched with a *new* object. When the function/with statement exits the patch is undone. - If `new` is omitted, then the target is replaced with a - :class:`MagicMock`. If `patch` is used as a decorator and `new` is + If *new* is omitted, then the target is replaced with a + :class:`MagicMock`. If :func:`patch` is used as a decorator and *new* is omitted, the created mock is passed in as an extra argument to the - decorated function. If `patch` is used as a context manager the created + decorated function. If :func:`patch` is used as a context manager the created mock is returned by the context manager. - `target` should be a string in the form `'package.module.ClassName'`. The - `target` is imported and the specified object replaced with the `new` - object, so the `target` must be importable from the environment you are - calling `patch` from. The target is imported when the decorated function + *target* should be a string in the form ``'package.module.ClassName'``. The + *target* is imported and the specified object replaced with the *new* + object, so the *target* must be importable from the environment you are + calling :func:`patch` from. The target is imported when the decorated function is executed, not at decoration time. - The `spec` and `spec_set` keyword arguments are passed to the `MagicMock` + The *spec* and *spec_set* keyword arguments are passed to the :class:`MagicMock` if patch is creating one for you. - In addition you can pass `spec=True` or `spec_set=True`, which causes + In addition you can pass ``spec=True`` or ``spec_set=True``, which causes patch to pass in the object being mocked as the spec/spec_set object. - `new_callable` allows you to specify a different class, or callable object, - that will be called to create the `new` object. By default `MagicMock` is + *new_callable* allows you to specify a different class, or callable object, + that will be called to create the *new* object. By default :class:`MagicMock` is used. - A more powerful form of `spec` is `autospec`. If you set `autospec=True` - then the mock with be created with a spec from the object being replaced. + A more powerful form of *spec* is *autospec*. If you set ``autospec=True`` + then the mock will be created with a spec from the object being replaced. All attributes of the mock will also have the spec of the corresponding attribute of the object being replaced. Methods and functions being mocked - will have their arguments checked and will raise a `TypeError` if they are + will have their arguments checked and will raise a :exc:`TypeError` if they are called with the wrong signature. For mocks replacing a class, their return value (the 'instance') will have the same spec as the class. See the :func:`create_autospec` function and :ref:`auto-speccing`. - Instead of `autospec=True` you can pass `autospec=some_object` to use an + Instead of ``autospec=True`` you can pass ``autospec=some_object`` to use an arbitrary object as the spec instead of the one being replaced. - By default `patch` will fail to replace attributes that don't exist. If - you pass in `create=True`, and the attribute doesn't exist, patch will + By default :func:`patch` will fail to replace attributes that don't exist. If + you pass in ``create=True``, and the attribute doesn't exist, patch will create the attribute for you when the patched function is called, and delete it again afterwards. This is useful for writing tests against attributes that your production code creates at runtime. It is off by default because it can be dangerous. With it switched on you can write passing tests against APIs that don't actually exist! - Patch can be used as a `TestCase` class decorator. It works by + .. note:: + + .. versionchanged:: 3.5 + If you are patching builtins in a module then you don't + need to pass ``create=True``, it will be added by default. + + Patch can be used as a :class:`TestCase` class decorator. It works by decorating each test method in the class. This reduces the boilerplate - code when your test methods share a common patchings set. `patch` finds - tests by looking for method names that start with `patch.TEST_PREFIX`. - By default this is `test`, which matches the way `unittest` finds tests. - You can specify an alternative prefix by setting `patch.TEST_PREFIX`. + code when your test methods share a common patchings set. :func:`patch` finds + tests by looking for method names that start with ``patch.TEST_PREFIX``. + By default this is ``'test'``, which matches the way :mod:`unittest` finds tests. + You can specify an alternative prefix by setting ``patch.TEST_PREFIX``. Patch can be used as a context manager, with the with statement. Here the patching applies to the indented block after the with statement. If you use "as" then the patched object will be bound to the name after the - "as"; very useful if `patch` is creating a mock object for you. + "as"; very useful if :func:`patch` is creating a mock object for you. - `patch` takes arbitrary keyword arguments. These will be passed to - the `Mock` (or `new_callable`) on construction. + :func:`patch` takes arbitrary keyword arguments. These will be passed to + the :class:`Mock` (or *new_callable*) on construction. - `patch.dict(...)`, `patch.multiple(...)` and `patch.object(...)` are + ``patch.dict(...)``, ``patch.multiple(...)`` and ``patch.object(...)`` are available for alternate use-cases. -`patch` as function decorator, creating the mock for you and passing it into +:func:`patch` as function decorator, creating the mock for you and passing it into the decorated function: >>> @patch('__main__.SomeClass') @@ -1059,16 +1086,16 @@ the decorated function: >>> function(None) True -Patching a class replaces the class with a `MagicMock` *instance*. If the +Patching a class replaces the class with a :class:`MagicMock` *instance*. If the class is instantiated in the code under test then it will be the :attr:`~Mock.return_value` of the mock that will be used. If the class is instantiated multiple times you could use :attr:`~Mock.side_effect` to return a new mock each time. Alternatively you -can set the `return_value` to be anything you want. +can set the *return_value* to be anything you want. To configure return values on methods of *instances* on the patched class -you must do this on the `return_value`. For example: +you must do this on the :attr:`return_value`. For example: >>> class Class: ... def method(self): @@ -1081,7 +1108,7 @@ you must do this on the `return_value`. For example: ... assert Class().method() == 'foo' ... -If you use `spec` or `spec_set` and `patch` is replacing a *class*, then the +If you use *spec* or *spec_set* and :func:`patch` is replacing a *class*, then the return value of the created mock will have the same spec. >>> Original = Class @@ -1091,7 +1118,7 @@ return value of the created mock will have the same spec. >>> assert isinstance(instance, Original) >>> patcher.stop() -The `new_callable` argument is useful where you want to use an alternative +The *new_callable* argument is useful where you want to use an alternative class to the default :class:`MagicMock` for the created mock. For example, if you wanted a :class:`NonCallableMock` to be used: @@ -1104,7 +1131,7 @@ you wanted a :class:`NonCallableMock` to be used: ... TypeError: 'NonCallableMock' object is not callable -Another use case might be to replace an object with a `io.StringIO` instance: +Another use case might be to replace an object with a :class:`io.StringIO` instance: >>> from io import StringIO >>> def foo(): @@ -1117,7 +1144,7 @@ Another use case might be to replace an object with a `io.StringIO` instance: ... >>> test() -When `patch` is creating a mock for you, it is common that the first thing +When :func:`patch` is creating a mock for you, it is common that the first thing you need to do is to configure the mock. Some of that configuration can be done in the call to patch. Any arbitrary keywords you pass into the call will be used to set attributes on the created mock: @@ -1133,7 +1160,7 @@ As well as attributes on the created mock attributes, like the :attr:`~Mock.return_value` and :attr:`~Mock.side_effect`, of child mocks can also be configured. These aren't syntactically valid to pass in directly as keyword arguments, but a dictionary with these as keys can still be expanded -into a `patch` call using `**`: +into a :func:`patch` call using ``**``: >>> config = {'method.return_value': 3, 'other.side_effect': KeyError} >>> patcher = patch('__main__.thing', **config) @@ -1151,19 +1178,19 @@ patch.object .. function:: patch.object(target, attribute, new=DEFAULT, spec=None, create=False, spec_set=None, autospec=None, new_callable=None, **kwargs) - patch the named member (`attribute`) on an object (`target`) with a mock + patch the named member (*attribute*) on an object (*target*) with a mock object. - `patch.object` can be used as a decorator, class decorator or a context - manager. Arguments `new`, `spec`, `create`, `spec_set`, `autospec` and - `new_callable` have the same meaning as for `patch`. Like `patch`, - `patch.object` takes arbitrary keyword arguments for configuring the mock + :func:`patch.object` can be used as a decorator, class decorator or a context + manager. Arguments *new*, *spec*, *create*, *spec_set*, *autospec* and + *new_callable* have the same meaning as for :func:`patch`. Like :func:`patch`, + :func:`patch.object` takes arbitrary keyword arguments for configuring the mock object it creates. - When used as a class decorator `patch.object` honours `patch.TEST_PREFIX` + When used as a class decorator :func:`patch.object` honours ``patch.TEST_PREFIX`` for choosing which methods to wrap. -You can either call `patch.object` with three arguments or two arguments. The +You can either call :func:`patch.object` with three arguments or two arguments. The three argument form takes the object to be patched, the attribute name and the object to replace the attribute with. @@ -1178,8 +1205,8 @@ function: ... >>> test() -`spec`, `create` and the other arguments to `patch.object` have the same -meaning as they do for `patch`. +*spec*, *create* and the other arguments to :func:`patch.object` have the same +meaning as they do for :func:`patch`. patch.dict @@ -1190,27 +1217,27 @@ patch.dict Patch a dictionary, or dictionary like object, and restore the dictionary to its original state after the test. - `in_dict` can be a dictionary or a mapping like container. If it is a + *in_dict* can be a dictionary or a mapping like container. If it is a mapping then it must at least support getting, setting and deleting items plus iterating over keys. - `in_dict` can also be a string specifying the name of the dictionary, which + *in_dict* can also be a string specifying the name of the dictionary, which will then be fetched by importing it. - `values` can be a dictionary of values to set in the dictionary. `values` - can also be an iterable of `(key, value)` pairs. + *values* can be a dictionary of values to set in the dictionary. *values* + can also be an iterable of ``(key, value)`` pairs. - If `clear` is true then the dictionary will be cleared before the new + If *clear* is true then the dictionary will be cleared before the new values are set. - `patch.dict` can also be called with arbitrary keyword arguments to set + :func:`patch.dict` can also be called with arbitrary keyword arguments to set values in the dictionary. - `patch.dict` can be used as a context manager, decorator or class - decorator. When used as a class decorator `patch.dict` honours - `patch.TEST_PREFIX` for choosing which methods to wrap. + :func:`patch.dict` can be used as a context manager, decorator or class + decorator. When used as a class decorator :func:`patch.dict` honours + ``patch.TEST_PREFIX`` for choosing which methods to wrap. -`patch.dict` can be used to add members to a dictionary, or simply let a test +:func:`patch.dict` can be used to add members to a dictionary, or simply let a test change a dictionary, and ensure the dictionary is restored when the test ends. @@ -1227,7 +1254,7 @@ ends. newvalue >>> assert 'newkey' not in os.environ -Keywords can be used in the `patch.dict` call to set values in the dictionary: +Keywords can be used in the :func:`patch.dict` call to set values in the dictionary: >>> mymodule = MagicMock() >>> mymodule.function.return_value = 'fish' @@ -1237,11 +1264,11 @@ Keywords can be used in the `patch.dict` call to set values in the dictionary: ... 'fish' -`patch.dict` can be used with dictionary like objects that aren't actually +:func:`patch.dict` can be used with dictionary like objects that aren't actually dictionaries. At the very minimum they must support item getting, setting, deleting and either iteration or membership test. This corresponds to the -magic methods `__getitem__`, `__setitem__`, `__delitem__` and either -`__iter__` or `__contains__`. +magic methods :meth:`__getitem__`, :meth:`__setitem__`, :meth:`__delitem__` and either +:meth:`__iter__` or :meth:`__contains__`. >>> class Container: ... def __init__(self): @@ -1277,21 +1304,21 @@ patch.multiple with patch.multiple(settings, FIRST_PATCH='one', SECOND_PATCH='two'): ... - Use :data:`DEFAULT` as the value if you want `patch.multiple` to create + Use :data:`DEFAULT` as the value if you want :func:`patch.multiple` to create mocks for you. In this case the created mocks are passed into a decorated - function by keyword, and a dictionary is returned when `patch.multiple` is + function by keyword, and a dictionary is returned when :func:`patch.multiple` is used as a context manager. - `patch.multiple` can be used as a decorator, class decorator or a context - manager. The arguments `spec`, `spec_set`, `create`, `autospec` and - `new_callable` have the same meaning as for `patch`. These arguments will - be applied to *all* patches done by `patch.multiple`. + :func:`patch.multiple` can be used as a decorator, class decorator or a context + manager. The arguments *spec*, *spec_set*, *create*, *autospec* and + *new_callable* have the same meaning as for :func:`patch`. These arguments will + be applied to *all* patches done by :func:`patch.multiple`. - When used as a class decorator `patch.multiple` honours `patch.TEST_PREFIX` + When used as a class decorator :func:`patch.multiple` honours ``patch.TEST_PREFIX`` for choosing which methods to wrap. -If you want `patch.multiple` to create mocks for you, then you can use -:data:`DEFAULT` as the value. If you use `patch.multiple` as a decorator +If you want :func:`patch.multiple` to create mocks for you, then you can use +:data:`DEFAULT` as the value. If you use :func:`patch.multiple` as a decorator then the created mocks are passed into the decorated function by keyword. >>> thing = object() @@ -1304,8 +1331,8 @@ then the created mocks are passed into the decorated function by keyword. ... >>> test_function() -`patch.multiple` can be nested with other `patch` decorators, but put arguments -passed by keyword *after* any of the standard arguments created by `patch`: +:func:`patch.multiple` can be nested with other ``patch`` decorators, but put arguments +passed by keyword *after* any of the standard arguments created by :func:`patch`: >>> @patch('sys.exit') ... @patch.multiple('__main__', thing=DEFAULT, other=DEFAULT) @@ -1316,7 +1343,7 @@ passed by keyword *after* any of the standard arguments created by `patch`: ... >>> test_function() -If `patch.multiple` is used as a context manager, the value returned by the +If :func:`patch.multiple` is used as a context manager, the value returned by the context manger is a dictionary where created mocks are keyed by name: >>> with patch.multiple('__main__', thing=DEFAULT, other=DEFAULT) as values: @@ -1332,16 +1359,16 @@ context manger is a dictionary where created mocks are keyed by name: patch methods: start and stop ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -All the patchers have `start` and `stop` methods. These make it simpler to do -patching in `setUp` methods or where you want to do multiple patches without +All the patchers have :meth:`start` and :meth:`stop` methods. These make it simpler to do +patching in ``setUp`` methods or where you want to do multiple patches without nesting decorators or with statements. -To use them call `patch`, `patch.object` or `patch.dict` as normal and keep a -reference to the returned `patcher` object. You can then call `start` to put -the patch in place and `stop` to undo it. +To use them call :func:`patch`, :func:`patch.object` or :func:`patch.dict` as +normal and keep a reference to the returned ``patcher`` object. You can then +call :meth:`start` to put the patch in place and :meth:`stop` to undo it. -If you are using `patch` to create a mock for you then it will be returned by -the call to `patcher.start`. +If you are using :func:`patch` to create a mock for you then it will be returned by +the call to ``patcher.start``. >>> patcher = patch('package.module.ClassName') >>> from package import module @@ -1354,8 +1381,8 @@ the call to `patcher.start`. >>> assert module.ClassName is not new_mock -A typical use case for this might be for doing multiple patches in the `setUp` -method of a `TestCase`: +A typical use case for this might be for doing multiple patches in the ``setUp`` +method of a :class:`TestCase`: >>> class MyTest(TestCase): ... def setUp(self): @@ -1377,7 +1404,7 @@ method of a `TestCase`: .. caution:: If you use this technique you must ensure that the patching is "undone" by - calling `stop`. This can be fiddlier than you might think, because if an + calling ``stop``. This can be fiddlier than you might think, because if an exception is raised in the ``setUp`` then ``tearDown`` is not called. :meth:`unittest.TestCase.addCleanup` makes this easier: @@ -1391,15 +1418,31 @@ method of a `TestCase`: ... assert package.module.Class is self.MockClass ... - As an added bonus you no longer need to keep a reference to the `patcher` + As an added bonus you no longer need to keep a reference to the ``patcher`` object. It is also possible to stop all patches which have been started by using -`patch.stopall`. +:func:`patch.stopall`. .. function:: patch.stopall - Stop all active patches. Only stops patches started with `start`. + Stop all active patches. Only stops patches started with ``start``. + + +.. _patch-builtins: + +patch builtins +~~~~~~~~~~~~~~ +You can patch any builtins within a module. The following example patches +builtin :func:`ord`: + + >>> @patch('__main__.ord') + ... def test(mock_ord): + ... mock_ord.return_value = 101 + ... print(ord('c')) + ... + >>> test() + 101 TEST_PREFIX @@ -1407,11 +1450,11 @@ TEST_PREFIX All of the patchers can be used as class decorators. When used in this way they wrap every test method on the class. The patchers recognise methods that -start with `test` as being test methods. This is the same way that the +start with ``'test'`` as being test methods. This is the same way that the :class:`unittest.TestLoader` finds test methods by default. It is possible that you want to use a different prefix for your tests. You can -inform the patchers of the different prefix by setting `patch.TEST_PREFIX`: +inform the patchers of the different prefix by setting ``patch.TEST_PREFIX``: >>> patch.TEST_PREFIX = 'foo' >>> value = 3 @@ -1464,7 +1507,7 @@ passed into your test function matches this order. Where to patch ~~~~~~~~~~~~~~ -`patch` works by (temporarily) changing the object that a *name* points to with +:func:`patch` works by (temporarily) changing the object that a *name* points to with another one. There can be many names pointing to any individual object, so for patching to work you must ensure that you patch the name used by the system under test. @@ -1482,23 +1525,23 @@ Imagine we have a project that we want to test with the following structure:: -> from a import SomeClass -> some_function instantiates SomeClass -Now we want to test `some_function` but we want to mock out `SomeClass` using -`patch`. The problem is that when we import module b, which we will have to -do then it imports `SomeClass` from module a. If we use `patch` to mock out -`a.SomeClass` then it will have no effect on our test; module b already has a -reference to the *real* `SomeClass` and it looks like our patching had no +Now we want to test ``some_function`` but we want to mock out ``SomeClass`` using +:func:`patch`. The problem is that when we import module b, which we will have to +do then it imports ``SomeClass`` from module a. If we use :func:`patch` to mock out +``a.SomeClass`` then it will have no effect on our test; module b already has a +reference to the *real* ``SomeClass`` and it looks like our patching had no effect. -The key is to patch out `SomeClass` where it is used (or where it is looked up -). In this case `some_function` will actually look up `SomeClass` in module b, +The key is to patch out ``SomeClass`` where it is used (or where it is looked up +). In this case ``some_function`` will actually look up ``SomeClass`` in module b, where we have imported it. The patching should look like:: @patch('b.SomeClass') -However, consider the alternative scenario where instead of `from a import -SomeClass` module b does `import a` and `some_function` uses `a.SomeClass`. Both +However, consider the alternative scenario where instead of ``from a import +SomeClass`` module b does ``import a`` and ``some_function`` uses ``a.SomeClass``. Both of these import forms are common. In this case the class we want to patch is -being looked up on the a module and so we have to patch `a.SomeClass` instead:: +being looked up in the module and so we have to patch ``a.SomeClass`` instead:: @patch('a.SomeClass') @@ -1509,7 +1552,7 @@ Patching Descriptors and Proxy Objects Both patch_ and patch.object_ correctly patch and restore descriptors: class methods, static methods and properties. You should patch these on the *class* rather than an instance. They also work with *some* objects -that proxy attribute access, like the `django setttings object +that proxy attribute access, like the `django settings object <http://www.voidspace.org.uk/python/weblog/arch_d7_2010_12_04.shtml#e1198>`_. @@ -1554,7 +1597,7 @@ the first argument [#]_. [] One use case for this is for mocking objects used as context managers in a -`with` statement: +:keyword:`with` statement: >>> mock = Mock() >>> mock.__enter__ = Mock(return_value='foo') @@ -1570,8 +1613,8 @@ are recorded in :attr:`~Mock.mock_calls`. .. note:: - If you use the `spec` keyword argument to create a mock then attempting to - set a magic method that isn't in the spec will raise an `AttributeError`. + If you use the *spec* keyword argument to create a mock then attempting to + set a magic method that isn't in the spec will raise an :exc:`AttributeError`. The full list of supported magic methods is: @@ -1607,7 +1650,7 @@ by mock, can't be set dynamically, or can cause problems: Magic Mock ~~~~~~~~~~ -There are two `MagicMock` variants: `MagicMock` and `NonCallableMagicMock`. +There are two ``MagicMock`` variants: :class:`MagicMock` and :class:`NonCallableMagicMock`. .. class:: MagicMock(*args, **kw) @@ -1618,19 +1661,19 @@ There are two `MagicMock` variants: `MagicMock` and `NonCallableMagicMock`. The constructor parameters have the same meaning as for :class:`Mock`. - If you use the `spec` or `spec_set` arguments then *only* magic methods + If you use the *spec* or *spec_set* arguments then *only* magic methods that exist in the spec will be created. .. class:: NonCallableMagicMock(*args, **kw) - A non-callable version of `MagicMock`. + A non-callable version of :class:`MagicMock`. The constructor parameters have the same meaning as for - :class:`MagicMock`, with the exception of `return_value` and - `side_effect` which have no meaning on a non-callable mock. + :class:`MagicMock`, with the exception of *return_value* and + *side_effect* which have no meaning on a non-callable mock. -The magic methods are setup with `MagicMock` objects, so you can configure them +The magic methods are setup with :class:`MagicMock` objects, so you can configure them and use them in the usual way: >>> mock = MagicMock() @@ -1652,17 +1695,17 @@ Methods and their defaults: * ``__gt__``: NotImplemented * ``__le__``: NotImplemented * ``__ge__``: NotImplemented -* ``__int__`` : 1 -* ``__contains__`` : False -* ``__len__`` : 1 -* ``__iter__`` : iter([]) -* ``__exit__`` : False -* ``__complex__`` : 1j -* ``__float__`` : 1.0 -* ``__bool__`` : True -* ``__index__`` : 1 -* ``__hash__`` : default hash for the mock -* ``__str__`` : default str for the mock +* ``__int__``: 1 +* ``__contains__``: False +* ``__len__``: 1 +* ``__iter__``: iter([]) +* ``__exit__``: False +* ``__complex__``: 1j +* ``__float__``: 1.0 +* ``__bool__``: True +* ``__index__``: 1 +* ``__hash__``: default hash for the mock +* ``__str__``: default str for the mock * ``__sizeof__``: default sizeof for the mock For example: @@ -1677,9 +1720,10 @@ For example: >>> object() in mock False -The two equality method, `__eq__` and `__ne__`, are special. -They do the default equality comparison on identity, using a side -effect, unless you change their return value to return something else: +The two equality methods, :meth:`__eq__` and :meth:`__ne__`, are special. +They do the default equality comparison on identity, using the +:attr:`~Mock.side_effect` attribute, unless you change their return value to +return something else:: >>> MagicMock() == 3 False @@ -1690,7 +1734,7 @@ effect, unless you change their return value to return something else: >>> mock == 3 True -The return value of `MagicMock.__iter__` can be any iterable object and isn't +The return value of :meth:`MagicMock.__iter__` can be any iterable object and isn't required to be an iterator: >>> mock = MagicMock() @@ -1750,10 +1794,10 @@ sentinel 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. `sentinel` provides a convenient way of +sentinel objects to test this. :data:`sentinel` provides a convenient way of creating and testing the identity of objects like this. -In this example we monkey patch `method` to return `sentinel.some_object`: +In this example we monkey patch ``method`` to return ``sentinel.some_object``: >>> real = ProductionClass() >>> real.method = Mock(name="method") @@ -1770,8 +1814,8 @@ DEFAULT .. data:: DEFAULT - The `DEFAULT` object is a pre-created sentinel (actually - `sentinel.DEFAULT`). It can be used by :attr:`~Mock.side_effect` + The :data:`DEFAULT` object is a pre-created sentinel (actually + ``sentinel.DEFAULT``). It can be used by :attr:`~Mock.side_effect` functions to indicate that the normal return value should be used. @@ -1780,9 +1824,9 @@ call .. function:: call(*args, **kwargs) - `call` is a helper object for making simpler assertions, for comparing with + :func:`call` is a helper object for making simpler assertions, for comparing with :attr:`~Mock.call_args`, :attr:`~Mock.call_args_list`, - :attr:`~Mock.mock_calls` and :attr:`~Mock.method_calls`. `call` can also be + :attr:`~Mock.mock_calls` and :attr:`~Mock.method_calls`. :func:`call` can also be used with :meth:`~Mock.assert_has_calls`. >>> m = MagicMock(return_value=None) @@ -1793,11 +1837,11 @@ call .. method:: call.call_list() - For a call object that represents multiple calls, `call_list` + For a call object that represents multiple calls, :meth:`call_list` returns a list of all the intermediate calls as well as the final call. -`call_list` is particularly useful for making assertions on "chained calls". A +``call_list`` is particularly useful for making assertions on "chained calls". A chained call is multiple calls on a single line of code. This results in multiple entries in :attr:`~Mock.mock_calls` on a mock. Manually constructing the sequence of calls can be tedious. @@ -1819,15 +1863,15 @@ chained call: .. _calls-as-tuples: -A `call` object is either a tuple of (positional args, keyword args) or +A ``call`` object is either a tuple of (positional args, keyword args) or (name, positional args, keyword args) depending on how it was constructed. When -you construct them yourself this isn't particularly interesting, but the `call` +you construct them yourself this isn't particularly interesting, but the ``call`` objects that are in the :attr:`Mock.call_args`, :attr:`Mock.call_args_list` and :attr:`Mock.mock_calls` attributes can be introspected to get at the individual arguments they contain. -The `call` objects in :attr:`Mock.call_args` and :attr:`Mock.call_args_list` -are two-tuples of (positional args, keyword args) whereas the `call` objects +The ``call`` objects in :attr:`Mock.call_args` and :attr:`Mock.call_args_list` +are two-tuples of (positional args, keyword args) whereas the ``call`` objects in :attr:`Mock.mock_calls`, along with ones you construct yourself, are three-tuples of (name, positional args, keyword args). @@ -1870,25 +1914,25 @@ create_autospec .. function:: create_autospec(spec, spec_set=False, instance=False, **kwargs) Create a mock object using another object as a spec. Attributes on the - mock will use the corresponding attribute on the `spec` object as their + mock will use the corresponding attribute on the *spec* object as their spec. Functions or methods being mocked will have their arguments checked to ensure that they are called with the correct signature. - If `spec_set` is `True` then attempting to set attributes that don't exist - on the spec object will raise an `AttributeError`. + If *spec_set* is ``True`` then attempting to set attributes that don't exist + on the spec object will raise an :exc:`AttributeError`. If a class is used as a spec then the return value of the mock (the instance of the class) will have the same spec. You can use a class as the - spec for an instance object by passing `instance=True`. The returned mock + spec for an instance object by passing ``instance=True``. The returned mock will only be callable if instances of the mock are callable. - `create_autospec` also takes arbitrary keyword arguments that are passed to + :func:`create_autospec` also takes arbitrary keyword arguments that are passed to the constructor of the created mock. See :ref:`auto-speccing` for examples of how to use auto-speccing with -`create_autospec` and the `autospec` argument to :func:`patch`. +:func:`create_autospec` and the *autospec* argument to :func:`patch`. ANY @@ -1910,7 +1954,7 @@ passed in. >>> mock('foo', bar=object()) >>> mock.assert_called_once_with('foo', bar=ANY) -`ANY` can also be used in comparisons with call lists like +:data:`ANY` can also be used in comparisons with call lists like :attr:`~Mock.mock_calls`: >>> m = MagicMock(return_value=None) @@ -1927,15 +1971,15 @@ FILTER_DIR .. data:: FILTER_DIR -`FILTER_DIR` is a module level variable that controls the way mock objects -respond to `dir` (only for Python 2.6 or more recent). The default is `True`, +:data:`FILTER_DIR` is a module level variable that controls the way mock objects +respond to :func:`dir` (only for Python 2.6 or more recent). The default is ``True``, which uses the filtering described below, to only show useful members. If you dislike this filtering, or need to switch it off for diagnostic purposes, then -set `mock.FILTER_DIR = False`. +set ``mock.FILTER_DIR = False``. -With filtering on, `dir(some_mock)` shows only useful attributes and will +With filtering on, ``dir(some_mock)`` shows only useful attributes and will include any dynamically created attributes that wouldn't normally be shown. -If the mock was created with a `spec` (or `autospec` of course) then all the +If the mock was created with a *spec* (or *autospec* of course) then all the attributes from the original are shown, even if they haven't been accessed yet: @@ -1954,11 +1998,11 @@ yet: 'BaseHandler', ... -Many of the not-very-useful (private to `Mock` rather than the thing being +Many of the not-very-useful (private to :class:`Mock` rather than the thing being mocked) underscore and double underscore prefixed attributes have been -filtered from the result of calling `dir` on a `Mock`. If you dislike this +filtered from the result of calling :func:`dir` on a :class:`Mock`. If you dislike this behaviour you can switch it off by setting the module level switch -`FILTER_DIR`: +:data:`FILTER_DIR`: >>> from unittest import mock >>> mock.FILTER_DIR = False @@ -1972,9 +2016,9 @@ behaviour you can switch it off by setting the module level switch '__class__', ... -Alternatively you can just use `vars(my_mock)` (instance members) and -`dir(type(my_mock))` (type members) to bypass the filtering irrespective of -`mock.FILTER_DIR`. +Alternatively you can just use ``vars(my_mock)`` (instance members) and +``dir(type(my_mock))`` (type members) to bypass the filtering irrespective of +:data:`mock.FILTER_DIR`. mock_open @@ -1982,36 +2026,36 @@ mock_open .. function:: mock_open(mock=None, read_data=None) - A helper function to create a mock to replace the use of `open`. It works - for `open` called directly or used as a context manager. + A helper function to create a mock to replace the use of :func:`open`. It works + for :func:`open` called directly or used as a context manager. - The `mock` argument is the mock object to configure. If `None` (the - default) then a `MagicMock` will be created for you, with the API limited + The *mock* argument is the mock object to configure. If ``None`` (the + default) then a :class:`MagicMock` will be created for you, with the API limited to methods or attributes available on standard file handles. - `read_data` is a string for the :meth:`~io.IOBase.read`, + *read_data* is a string for the :meth:`~io.IOBase.read`, :meth:`~io.IOBase.readline`, and :meth:`~io.IOBase.readlines` methods of the file handle to return. Calls to those methods will take data from - `read_data` until it is depleted. The mock of these methods is pretty + *read_data* until it is depleted. The mock of these methods is pretty simplistic. If you need more control over the data that you are feeding to the tested code you will need to customize this mock for yourself. - `read_data` is an empty string by default. + *read_data* is an empty string by default. -Using `open` as a context manager is a great way to ensure your file handles +Using :func:`open` as a context manager is a great way to ensure your file handles are closed properly and is becoming common:: with open('/some/path', 'w') as f: f.write('something') -The issue is that even if you mock out the call to `open` it is the -*returned object* that is used as a context manager (and has `__enter__` and -`__exit__` called). +The issue is that even if you mock out the call to :func:`open` it is the +*returned object* that is used as a context manager (and has :meth:`__enter__` and +:meth:`__exit__` called). Mocking context managers with a :class:`MagicMock` is common enough and fiddly enough that a helper function is useful. >>> m = mock_open() - >>> with patch('__main__.open', m, create=True): + >>> with patch('__main__.open', m): ... with open('foo', 'w') as h: ... h.write('some stuff') ... @@ -2026,7 +2070,7 @@ enough that a helper function is useful. And for reading files: - >>> with patch('__main__.open', mock_open(read_data='bibble'), create=True) as m: + >>> with patch('__main__.open', mock_open(read_data='bibble')) as m: ... with open('foo') as h: ... result = h.read() ... @@ -2039,21 +2083,21 @@ And for reading files: Autospeccing ~~~~~~~~~~~~ -Autospeccing is based on the existing `spec` feature of mock. It limits the +Autospeccing is based on the existing :attr:`spec` feature of mock. It limits the api of mocks to the api of an original object (the spec), but it is recursive (implemented lazily) so that attributes of mocks only have the same api as the attributes of the spec. In addition mocked functions / methods have the -same call signature as the original so they raise a `TypeError` if they are +same call signature as the original so they raise a :exc:`TypeError` if they are called incorrectly. Before I explain how auto-speccing works, here's why it is needed. -`Mock` is a very powerful and flexible object, but it suffers from two flaws +:class:`Mock` is a very powerful and flexible object, but it suffers from two flaws when used to mock out objects from a system under test. One of these flaws is -specific to the `Mock` api and the other is a more general problem with using +specific to the :class:`Mock` api and the other is a more general problem with using mock objects. -First the problem specific to `Mock`. `Mock` has two assert methods that are +First the problem specific to :class:`Mock`. :class:`Mock` has two assert methods that are extremely handy: :meth:`~Mock.assert_called_with` and :meth:`~Mock.assert_called_once_with`. @@ -2088,8 +2132,8 @@ unit tests. Testing everything in isolation is all fine and dandy, but if you don't test how your units are "wired together" there is still lots of room for bugs that tests might have caught. -`mock` already provides a feature to help with this, called speccing. If you -use a class or instance as the `spec` for a mock then you can only access +:mod:`mock` already provides a feature to help with this, called speccing. If you +use a class or instance as the :attr:`spec` for a mock then you can only access attributes on the mock that exist on the real class: >>> from urllib import request @@ -2108,9 +2152,9 @@ with any methods on the mock: <mock.Mock object at 0x...> >>> mock.has_data.assret_called_with() -Auto-speccing solves this problem. You can either pass `autospec=True` to -`patch` / `patch.object` or use the `create_autospec` function to create a -mock with a spec. If you use the `autospec=True` argument to `patch` then the +Auto-speccing solves this problem. You can either pass ``autospec=True`` to +:func:`patch` / :func:`patch.object` or use the :func:`create_autospec` function to create a +mock with a spec. If you use the ``autospec=True`` argument to :func:`patch` then the object that is being replaced will be used as the spec object. Because the speccing is done "lazily" (the spec is created as attributes on the mock are accessed) you can use it with very complex or deeply nested objects (like @@ -2127,8 +2171,8 @@ Here's an example of it in use: >>> mock_request.Request <MagicMock name='request.Request' spec='Request' id='...'> -You can see that `request.Request` has a spec. `request.Request` takes two -arguments in the constructor (one of which is `self`). Here's what happens if +You can see that :class:`request.Request` has a spec. :class:`request.Request` takes two +arguments in the constructor (one of which is *self*). Here's what happens if we try to call it incorrectly: >>> req = request.Request() @@ -2143,8 +2187,8 @@ specced mocks): >>> req <NonCallableMagicMock name='request.Request()' spec='Request' id='...'> -`Request` objects are not callable, so the return value of instantiating our -mocked out `request.Request` is a non-callable mock. With the spec in place +:class:`Request` objects are not callable, so the return value of instantiating our +mocked out :class:`request.Request` is a non-callable mock. With the spec in place any typos in our asserts will raise the correct error: >>> req.add_header('spam', 'eggs') @@ -2155,11 +2199,11 @@ any typos in our asserts will raise the correct error: AttributeError: Mock object has no attribute 'assret_called_with' >>> req.add_header.assert_called_with('spam', 'eggs') -In many cases you will just be able to add `autospec=True` to your existing -`patch` calls and then be protected against bugs due to typos and api +In many cases you will just be able to add ``autospec=True`` to your existing +:func:`patch` calls and then be protected against bugs due to typos and api changes. -As well as using `autospec` through `patch` there is a +As well as using *autospec* through :func:`patch` there is a :func:`create_autospec` for creating autospecced mocks directly: >>> from urllib import request @@ -2177,8 +2221,8 @@ able to use autospec. On the other hand it is much better to design your objects so that introspection is safe [#]_. A more serious problem is that it is common for instance attributes to be -created in the `__init__` method and not to exist on the class at all. -`autospec` can't know about any dynamically created attributes and restricts +created in the :meth:`__init__` method and not to exist on the class at all. +*autospec* can't know about any dynamically created attributes and restricts the api to visible attributes. >>> class Something: @@ -2195,7 +2239,7 @@ the api to visible attributes. There are a few different ways of resolving this problem. The easiest, but not necessarily the least annoying, way is to simply set the required -attributes on the mock after creation. Just because `autospec` doesn't allow +attributes on the mock after creation. Just because *autospec* doesn't allow you to fetch attributes that don't exist on the spec it doesn't prevent you setting them: @@ -2204,7 +2248,7 @@ setting them: ... thing.a = 33 ... -There is a more aggressive version of both `spec` and `autospec` that *does* +There is a more aggressive version of both *spec* and *autospec* that *does* prevent you setting non-existent attributes. This is useful if you want to ensure your code only *sets* valid attributes too, but obviously it prevents this particular scenario: @@ -2218,8 +2262,8 @@ this particular scenario: AttributeError: Mock object has no attribute 'a' Probably the best way of solving the problem is to add class attributes as -default values for instance members initialised in `__init__`. Note that if -you are only setting default attributes in `__init__` then providing them via +default values for instance members initialised in :meth:`__init__`. Note that if +you are only setting default attributes in :meth:`__init__` then providing them via class attributes (shared between instances of course) is faster too. e.g. .. code-block:: python @@ -2228,12 +2272,12 @@ class attributes (shared between instances of course) is faster too. e.g. a = 33 This brings up another issue. It is relatively common to provide a default -value of `None` for members that will later be an object of a different type. -`None` would be useless as a spec because it wouldn't let you access *any* -attributes or methods on it. As `None` is *never* going to be useful as a +value of ``None`` for members that will later be an object of a different type. +``None`` would be useless as a spec because it wouldn't let you access *any* +attributes or methods on it. As ``None`` is *never* going to be useful as a spec, and probably indicates a member that will normally of some other type, -`autospec` doesn't use a spec for members that are set to `None`. These will -just be ordinary mocks (well - `MagicMocks`): +autospec doesn't use a spec for members that are set to ``None``. These will +just be ordinary mocks (well - MagicMocks): >>> class Something: ... member = None @@ -2247,8 +2291,8 @@ then there are more options. One of these is simply to use an instance as the spec rather than the class. The other is to create a subclass of the production class and add the defaults to the subclass without affecting the production class. Both of these require you to use an alternative object as -the spec. Thankfully `patch` supports this - you can simply pass the -alternative object as the `autospec` argument: +the spec. Thankfully :func:`patch` supports this - you can simply pass the +alternative object as the *autospec* argument: >>> class Something: ... def __init__(self): @@ -2265,5 +2309,5 @@ alternative object as the `autospec` argument: .. [#] This only applies to classes or already instantiated objects. Calling a mocked class to create a mock instance *does not* create a real instance. - It is only attribute lookups - along with calls to `dir` - that are done. + It is only attribute lookups - along with calls to :func:`dir` - that are done. diff --git a/Doc/library/unittest.rst b/Doc/library/unittest.rst index 63106242129f..92609ec9cff5 100644 --- a/Doc/library/unittest.rst +++ b/Doc/library/unittest.rst @@ -51,11 +51,11 @@ test runner Kent Beck's original paper on testing frameworks using the pattern shared by :mod:`unittest`. - `Nose <http://code.google.com/p/python-nose/>`_ and `py.test <http://pytest.org>`_ + `Nose <https://nose.readthedocs.org/en/latest/>`_ and `py.test <http://pytest.org>`_ Third-party unittest frameworks with a lighter-weight syntax for writing tests. For example, ``assert func(10) == 42``. - `The Python Testing Tools Taxonomy <http://wiki.python.org/moin/PythonTestingToolsTaxonomy>`_ + `The Python Testing Tools Taxonomy <https://wiki.python.org/moin/PythonTestingToolsTaxonomy>`_ An extensive list of Python testing tools including functional testing frameworks and mock object libraries. @@ -67,7 +67,7 @@ test runner a GUI tool for test discovery and execution. This is intended largely for ease of use for those new to unit testing. For production environments it is recommended that tests be driven by a continuous integration system such as - `Buildbot <http://buildbot.net/trac>`_, `Jenkins <http://jenkins-ci.org>`_ + `Buildbot <http://buildbot.net/>`_, `Jenkins <http://jenkins-ci.org/>`_ or `Hudson <http://hudson-ci.org/>`_. @@ -239,9 +239,10 @@ Test Discovery Unittest supports simple test discovery. In order to be compatible with test discovery, all of the test files must be :ref:`modules <tut-modules>` or -:ref:`packages <tut-packages>` importable from the top-level directory of -the project (this means that their filenames must be valid -:ref:`identifiers <identifiers>`). +:ref:`packages <tut-packages>` (including :term:`namespace packages +<namespace package>`) importable from the top-level directory of +the project (this means that their filenames must be valid :ref:`identifiers +<identifiers>`). Test discovery is implemented in :meth:`TestLoader.discover`, but can also be used from the command line. The basic command-line usage is:: @@ -306,6 +307,9 @@ as the start directory. Test modules and packages can customize test loading and discovery by through the `load_tests protocol`_. +.. versionchanged:: 3.4 + Test discovery supports :term:`namespace packages <namespace package>`. + .. _organizing-tests: @@ -559,8 +563,9 @@ The following decorators implement test skipping and expected failures: Usually you can use :meth:`TestCase.skipTest` or one of the skipping decorators instead of raising this directly. -Skipped tests will not have :meth:`setUp` or :meth:`tearDown` run around them. -Skipped classes will not have :meth:`setUpClass` or :meth:`tearDownClass` run. +Skipped tests will not have :meth:`~TestCase.setUp` or :meth:`~TestCase.tearDown` run around them. +Skipped classes will not have :meth:`~TestCase.setUpClass` or :meth:`~TestCase.tearDownClass` run. +Skipped modules will not have :func:`setUpModule` or :func:`tearDownModule` run. .. _subtests: @@ -669,9 +674,9 @@ Test cases .. method:: setUp() Method called to prepare the test fixture. This is called immediately - before calling the test method; any exception raised by this method will - be considered an error rather than a test failure. The default - implementation does nothing. + before calling the test method; other than :exc:`AssertionError` or :exc:`SkipTest`, + any exception raised by this method will be considered an error rather than + a test failure. The default implementation does nothing. .. method:: tearDown() @@ -679,10 +684,10 @@ Test cases Method called immediately after the test method has been called and the result recorded. This is called even if the test method raised an exception, so the implementation in subclasses may need to be particularly - careful about checking internal state. Any exception raised by this - method will be considered an error rather than a test failure. This - method will only be called if the :meth:`setUp` succeeds, regardless of - the outcome of the test method. The default implementation does nothing. + careful about checking internal state. Any exception, other than :exc:`AssertionError` + or :exc:`SkipTest`, raised by this method will be considered an error rather than a + test failure. This method will only be called if the :meth:`setUp` succeeds, + regardless of the outcome of the test method. The default implementation does nothing. .. method:: setUpClass() @@ -1547,6 +1552,20 @@ Loading and running tests :data:`unittest.defaultTestLoader`. Using a subclass or instance, however, allows customization of some configurable properties. + :class:`TestLoader` objects have the following attributes: + + + .. attribute:: errors + + A list of the non-fatal errors encountered while loading tests. Not reset + by the loader at any point. Fatal errors are signalled by the relevant + a method raising an exception to the caller. Non-fatal errors are also + indicated by a synthetic test that will raise the original error when + run. + + .. versionadded:: 3.5 + + :class:`TestLoader` objects have the following methods: @@ -1556,7 +1575,7 @@ Loading and running tests :class:`testCaseClass`. - .. method:: loadTestsFromModule(module) + .. method:: loadTestsFromModule(module, pattern=None) Return a suite of all tests cases contained in the given module. This method searches *module* for classes derived from :class:`TestCase` and @@ -1573,11 +1592,18 @@ Loading and running tests If a module provides a ``load_tests`` function it will be called to load the tests. This allows modules to customize test loading. - This is the `load_tests protocol`_. + This is the `load_tests protocol`_. The *pattern* argument is passed as + the third argument to ``load_tests``. .. versionchanged:: 3.2 Support for ``load_tests`` added. + .. versionchanged:: 3.5 + The undocumented and unofficial *use_load_tests* default argument is + deprecated and ignored, although it is still accepted for backward + compatibility. The method also now accepts a keyword-only argument + *pattern* which is passed to ``load_tests`` as the third argument. + .. method:: loadTestsFromName(name, module=None) @@ -1603,6 +1629,12 @@ 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. + .. method:: loadTestsFromNames(names, module=None) @@ -1619,28 +1651,32 @@ Loading and running tests .. method:: discover(start_dir, pattern='test*.py', top_level_dir=None) - Find and return all test modules from the specified start directory, - recursing into subdirectories to find them. Only test files that match - *pattern* will be loaded. (Using shell style pattern matching.) Only - module names that are importable (i.e. are valid Python identifiers) will - be loaded. + Find all the test modules by recursing into subdirectories from the + specified start directory, and return a TestSuite object containing them. + Only test files that match *pattern* will be loaded. (Using shell style + pattern matching.) Only module names that are importable (i.e. are valid + Python identifiers) will be loaded. All test modules must be importable from the top level of the project. If the start directory is not the top level directory then the top level directory must be specified separately. - If importing a module fails, for example due to a syntax error, then this - will be recorded as a single error and discovery will continue. If the - import failure is due to :exc:`SkipTest` being raised, it will be recorded - as a skip instead of an error. + If importing a module fails, for example due to a syntax error, then + this will be recorded as a single error and discovery will continue. If + the import failure is due to :exc:`SkipTest` being raised, it will be + recorded as a skip instead of an error. - If a test package name (directory with :file:`__init__.py`) matches the - pattern then the package will be checked for a ``load_tests`` - function. If this exists then it will be called with *loader*, *tests*, - *pattern*. + If a package (a directory containing a file named :file:`__init__.py`) is + found, the package will be checked for a ``load_tests`` function. If this + exists then it will be called + ``package.load_tests(loader, tests, pattern)``. Test discovery takes care + to ensure that a package is only checked for tests once during an + invocation, even if the load_tests function itself calls + ``loader.discover``. - If load_tests exists then discovery does *not* recurse into the package, - ``load_tests`` is responsible for loading all tests in the package. + If ``load_tests`` exists then discovery does *not* recurse into the + package, ``load_tests`` is responsible for loading all tests in the + package. The pattern is deliberately not stored as a loader attribute so that packages can continue discovery themselves. *top_level_dir* is stored so @@ -1653,12 +1689,16 @@ Loading and running tests .. versionchanged:: 3.4 Modules that raise :exc:`SkipTest` on import are recorded as skips, - not errors. + not errors. + Discovery works for :term:`namespace packages <namespace package>`. + Paths are sorted before being imported so that execution order is + the same even if the underlying file system's ordering is not + dependent on file name. - .. versionchanged:: 3.4 - Paths are sorted before being imported to ensure execution order for a - given test suite is the same even if the underlying file system's ordering - is not dependent on file name like in ext3/4. + .. versionchanged:: 3.5 + Found packages are now checked for ``load_tests`` regardless of + whether their path matches *pattern*, because it is impossible for + a package name to match the default pattern. The following attributes of a :class:`TestLoader` can be configured either by @@ -1771,6 +1811,10 @@ Loading and running tests Return ``True`` if all tests run so far have passed, otherwise returns ``False``. + .. versionchanged:: 3.4 + Returns ``False`` if there were any :attr:`unexpectedSuccesses` + from tests marked with the :func:`expectedFailure` decorator. + .. method:: stop() @@ -1799,14 +1843,14 @@ Loading and running tests Called after the test case *test* has been executed, regardless of the outcome. - .. method:: startTestRun(test) + .. method:: startTestRun() Called once before any tests are executed. .. versionadded:: 3.1 - .. method:: stopTestRun(test) + .. method:: stopTestRun() Called once after all tests are executed. @@ -1911,13 +1955,14 @@ Loading and running tests applications which run test suites should provide alternate implementations. By default this runner shows :exc:`DeprecationWarning`, - :exc:`PendingDeprecationWarning`, and :exc:`ImportWarning` even if they are - :ref:`ignored by default <warning-ignored>`. Deprecation warnings caused by - :ref:`deprecated unittest methods <deprecated-aliases>` are also - special-cased and, when the warning filters are ``'default'`` or ``'always'``, - they will appear only once per-module, in order to avoid too many warning - messages. This behavior can be overridden using the :option:`-Wd` or - :option:`-Wa` options and leaving *warnings* to ``None``. + :exc:`PendingDeprecationWarning`, :exc:`ResourceWarning` and + :exc:`ImportWarning` even if they are :ref:`ignored by default + <warning-ignored>`. Deprecation warnings caused by :ref:`deprecated unittest + methods <deprecated-aliases>` are also special-cased and, when the warning + filters are ``'default'`` or ``'always'``, they will appear only once + per-module, in order to avoid too many warning messages. This behavior can + be overridden using the :option:`-Wd` or :option:`-Wa` options and leaving + *warnings* to ``None``. .. versionchanged:: 3.2 Added the ``warnings`` argument. @@ -1939,6 +1984,14 @@ Loading and running tests stream, descriptions, verbosity + .. method:: run(test) + + This method is the main public interface to the `TextTestRunner`. This + method takes a :class:`TestSuite` or :class:`TestCase` instance. A + :class:`TestResult` is created by calling + :func:`_makeResult` and the test(s) are run and the + results printed to stdout. + .. function:: main(module='__main__', defaultTest=None, argv=None, testRunner=None, \ testLoader=unittest.defaultTestLoader, exit=True, verbosity=1, \ @@ -1958,6 +2011,11 @@ Loading and running tests if __name__ == '__main__': unittest.main(verbosity=2) + The *defaultTest* argument is either the name of a single test or an + iterable of test names to run if no test names are specified via *argv*. If + not specified or ``None`` and no test names are provided via *argv*, all + tests found in *module* are run. + The *argv* argument can be a list of options passed to the program, with the first element being the program name. If not specified or ``None``, the values of :data:`sys.argv` are used. @@ -2010,7 +2068,10 @@ test runs or test discovery by implementing a function called ``load_tests``. If a test module defines ``load_tests`` it will be called by :meth:`TestLoader.loadTestsFromModule` with the following arguments:: - load_tests(loader, standard_tests, None) + load_tests(loader, standard_tests, pattern) + +where *pattern* is passed straight through from ``loadTestsFromModule``. It +defaults to ``None``. It should return a :class:`TestSuite`. @@ -2032,21 +2093,12 @@ A typical ``load_tests`` function that loads tests from a specific set of suite.addTests(tests) return suite -If discovery is started, either from the command line or by calling -:meth:`TestLoader.discover`, with a pattern that matches a package -name then the package :file:`__init__.py` will be checked for ``load_tests``. - -.. note:: - - The default pattern is ``'test*.py'``. This matches all Python files - that start with ``'test'`` but *won't* match any test directories. - - A pattern like ``'test*'`` will match test packages as well as - modules. - -If the package :file:`__init__.py` defines ``load_tests`` then it will be -called and discovery not continued into the package. ``load_tests`` -is called with the following arguments:: +If discovery is started in a directory containing a package, either from the +command line or by calling :meth:`TestLoader.discover`, then the package +:file:`__init__.py` will be checked for ``load_tests``. If that function does +not exist, discovery will recurse into the package as though it were just +another directory. Otherwise, discovery of the package's tests will be left up +to ``load_tests`` which is called with the following arguments:: load_tests(loader, standard_tests, pattern) @@ -2065,6 +2117,11 @@ continue (and potentially modify) test discovery. A 'do nothing' standard_tests.addTests(package_tests) return standard_tests +.. versionchanged:: 3.5 + Discovery no longer checks package names for matching *pattern* due to the + impossibility of package names matching the default pattern. + + Class and Module Fixtures ------------------------- diff --git a/Doc/library/urllib.error.rst b/Doc/library/urllib.error.rst index 9fb58f508358..f7f0c9739d8c 100644 --- a/Doc/library/urllib.error.rst +++ b/Doc/library/urllib.error.rst @@ -48,7 +48,7 @@ The following exceptions are raised by :mod:`urllib.error` as appropriate: .. attribute:: headers - The HTTP response headers for the HTTP request that cause the + The HTTP response headers for the HTTP request that caused the :exc:`HTTPError`. .. versionadded:: 3.4 diff --git a/Doc/library/urllib.parse.rst b/Doc/library/urllib.parse.rst index b95142042d87..3ecdda18d78f 100644 --- a/Doc/library/urllib.parse.rst +++ b/Doc/library/urllib.parse.rst @@ -81,7 +81,8 @@ or on combining URL components into a URL string. this argument is the empty string. If the *allow_fragments* argument is false, fragment identifiers are not - allowed. The default value for this argument is :const:`True`. + recognized and parsed as part of the preceding component. The default value + for this argument is :const:`True`. The return value is actually an instance of a subclass of :class:`tuple`. This class has the following additional read-only convenience attributes: @@ -267,6 +268,11 @@ or on combining URL components into a URL string. :func:`urlunsplit`, removing possible *scheme* and *netloc* parts. + .. versionchanged:: 3.5 + + Behaviour updated to match the semantics defined in :rfc:`3986`. + + .. function:: urldefrag(url) If *url* contains a fragment identifier, return a modified version of *url* @@ -516,7 +522,7 @@ task isn't already covered by the URL parsing functions above. .. function:: urlencode(query, doseq=False, safe='', encoding=None, errors=None) Convert a mapping object or a sequence of two-element tuples, which may - either be a :class:`str` or a :class:`bytes`, to a "percent-encoded" + contain :class:`str` or :class:`bytes` objects, to a "percent-encoded" string. If the resultant string is to be used as a *data* for POST operation with :func:`~urllib.request.urlopen` function, then it should be properly encoded to bytes, otherwise it would result in a :exc:`TypeError`. @@ -531,8 +537,9 @@ task isn't already covered by the URL parsing functions above. the value sequence for the key. The order of parameters in the encoded string will match the order of parameter tuples in the sequence. - When *query* parameter is a :class:`str`, the *safe*, *encoding* and *error* - parameters are passed down to :func:`quote_plus` for encoding. + The *safe*, *encoding*, and *errors* parameters are passed down to + :func:`quote_plus` (the *encoding* and *errors* parameters are only passed + when a query element is a :class:`str`). To reverse this encoding process, :func:`parse_qs` and :func:`parse_qsl` are provided in this module to parse query strings into Python data structures. diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst index c4dd7e3b33f0..2400526e3e8a 100644 --- a/Doc/library/urllib.request.rst +++ b/Doc/library/urllib.request.rst @@ -16,7 +16,7 @@ authentication, redirections, cookies and more. The :mod:`urllib.request` module defines the following functions: -.. function:: urlopen(url, data=None[, timeout], *, cafile=None, capath=None, cadefault=False) +.. function:: urlopen(url, data=None[, timeout], *, cafile=None, capath=None, cadefault=False, context=None) Open the URL *url*, which can be either a string or a :class:`Request` object. @@ -47,27 +47,23 @@ The :mod:`urllib.request` module defines the following functions: the global default timeout setting will be used). This actually only works for HTTP, HTTPS and FTP connections. + If *context* is specified, it must be a :class:`ssl.SSLContext` instance + describing the various SSL options. See :class:`~http.client.HTTPSConnection` + for more details. + The optional *cafile* and *capath* parameters specify a set of trusted CA certificates for HTTPS requests. *cafile* should point to a single file containing a bundle of CA certificates, whereas *capath* should point to a directory of hashed certificate files. More information can be found in :meth:`ssl.SSLContext.load_verify_locations`. - The *cadefault* parameter specifies whether to fall back to loading a - default certificate store defined by the underlying OpenSSL library if the - *cafile* and *capath* parameters are omitted. This will only work on - some non-Windows platforms. - - .. warning:: - If neither *cafile* nor *capath* is specified, and *cadefault* is ``False``, - an HTTPS request will not do any verification of the server's - certificate. + The *cadefault* parameter is ignored. For http and https urls, this function returns a :class:`http.client.HTTPResponse` object which has the following :ref:`httpresponse-objects` methods. - For ftp, file, and data urls and requests explicity handled by legacy + For ftp, file, and data urls and requests explicitly handled by legacy :class:`URLopener` and :class:`FancyURLopener` classes, this function returns a :class:`urllib.response.addinfourl` object which can work as :term:`context manager` and has methods such as @@ -111,6 +107,10 @@ The :mod:`urllib.request` module defines the following functions: .. versionchanged:: 3.3 *cadefault* was added. + .. versionchanged:: 3.4.3 + *context* was added. + + .. function:: install_opener(opener) Install an :class:`OpenerDirector` instance as the default global opener. @@ -218,7 +218,7 @@ The following classes are provided: fetching of the image, this should be true. *method* should be a string that indicates the HTTP request method that - will be used (e.g. ``'HEAD'``). Its value is stored in the + will be used (e.g. ``'HEAD'``). If provided, its value is stored in the :attr:`~Request.method` attribute and is used by :meth:`get_method()`. Subclasses may indicate a default method by setting the :attr:`~Request.method` attribute in the class itself. @@ -301,6 +301,17 @@ The following classes are provided: presented with a wrong Authentication scheme. +.. class:: HTTPBasicPriorAuthHandler(password_mgr=None) + + A variant of :class:`HTTPBasicAuthHandler` which automatically sends + authorization credentials with the first request, rather than waiting to + first receive a HTTP 401 "Unauthorised" error response. This allows + authentication to sites that don't provide a 401 response when receiving + a request without an Authorization header. Aside from this difference, + this behaves exactly as :class:`HTTPBasicAuthHandler`. + + .. versionadded:: 3.5 + .. class:: ProxyBasicAuthHandler(password_mgr=None) Handle authentication with the proxy. *password_mgr*, if given, should be @@ -440,13 +451,20 @@ request. .. attribute:: Request.method - The HTTP request method to use. This value is used by - :meth:`~Request.get_method` to override the computed HTTP request - method that would otherwise be returned. This attribute is initialized with - the value of the *method* argument passed to the constructor. + The HTTP request method to use. By default its value is :const:`None`, + which means that :meth:`~Request.get_method` will do its normal computation + of the method to be used. Its value can be set (thus overriding the default + computation in :meth:`~Request.get_method`) either by providing a default + value by setting it at the class level in a :class:`Request` subclass, or by + passing a value in to the :class:`Request` constructor via the *method* + argument. .. versionadded:: 3.3 + .. versionchanged:: 3.4 + A default value can now be set in subclasses; previously it could only + be set via the constructor argument. + .. method:: Request.get_method() @@ -516,9 +534,10 @@ request. Return a list of tuples (header_name, header_value) of the Request headers. .. versionchanged:: 3.4 - Request methods add_data, has_data, get_data, get_type, get_host, - get_selector, get_origin_req_host and is_unverifiable deprecated since 3.3 - have been removed. + The request methods add_data, has_data, get_data, get_type, get_host, + get_selector, get_origin_req_host and is_unverifiable that were deprecated + since 3.3 have been removed. + .. _opener-director-objects: @@ -1055,11 +1074,11 @@ it receives from the http server. In general, a program will decode the returned bytes object to string once it determines or guesses the appropriate encoding. -The following W3C document, http://www.w3.org/International/O-charset , lists +The following W3C document, http://www.w3.org/International/O-charset\ , lists the various ways in which a (X)HTML or a XML document could have specified its encoding information. -As the python.org website uses *utf-8* encoding as specified in it's meta tag, we +As the python.org website uses *utf-8* encoding as specified in its meta tag, we will use the same for decoding the bytes object. :: >>> with urllib.request.urlopen('http://www.python.org/') as f: diff --git a/Doc/library/venv.rst b/Doc/library/venv.rst index 461c9e170e47..e9ede8b415f9 100644 --- a/Doc/library/venv.rst +++ b/Doc/library/venv.rst @@ -40,11 +40,11 @@ Creating virtual environments A venv is a directory tree which contains Python executable files and other files which indicate that it is a venv. - Common installation tools such as ``Distribute`` and ``pip`` work as + Common installation tools such as ``Setuptools`` and ``pip`` work as expected with venvs - i.e. when a venv is active, they install Python packages into the venv without needing to be told to do so explicitly. Of course, you need to install them into the venv first: this could be - done by running ``distribute_setup.py`` with the venv activated, + done by running ``ez_setup.py`` with the venv activated, followed by running ``easy_install pip``. Alternatively, you could download the source tarballs and run ``python setup.py install`` after unpacking, with the venv activated. @@ -76,6 +76,8 @@ Creating virtual environments without there needing to be any reference to its venv in ``PATH``. +.. _venv-api: + API --- @@ -107,7 +109,8 @@ creation according to their needs, the :class:`EnvBuilder` class. upgraded in-place (defaults to ``False``). * ``with_pip`` -- a Boolean value which, if true, ensures pip is - installed in the virtual environment + installed in the virtual environment. This uses :mod:`ensurepip` with + the ``--default-pip`` option. .. versionchanged:: 3.4 Added the ``with_pip`` parameter diff --git a/Doc/library/wave.rst b/Doc/library/wave.rst index c32e1fcd857a..ab64978cfde3 100644 --- a/Doc/library/wave.rst +++ b/Doc/library/wave.rst @@ -150,14 +150,30 @@ them, and is otherwise implementation dependent. Wave_write Objects ------------------ +For seekable output streams, the ``wave`` header will automatically be updated +to reflect the number of frames actually written. For unseekable streams, the +*nframes* value must be accurate when the first frame data is written. An +accurate *nframes* value can be achieved either by calling +:meth:`~Wave_write.setnframes` or :meth:`~Wave_write.setparams` with the number +of frames that will be written before :meth:`~Wave_write.close` is called and +then using :meth:`~Wave_write.writeframesraw` to write the frame data, or by +calling :meth:`~Wave_write.writeframes` with all of the frame data to be +written. In the latter case :meth:`~Wave_write.writeframes` will calculate +the number of frames in the data and set *nframes* accordingly before writing +the frame data. + Wave_write objects, as returned by :func:`.open`, have the following methods: +.. versionchanged:: 3.4 + Added support for unseekable files. + .. method:: Wave_write.close() Make sure *nframes* is correct, and close the file if it was opened by - :mod:`wave`. This method is called upon object collection. Can raise an - exception if *nframes* is not correct and a file is not seekable. + :mod:`wave`. This method is called upon object collection. It will raise + an exception if the output stream is not seekable and *nframes* does not + match the number of frames actually written. .. method:: Wave_write.setnchannels(n) @@ -181,8 +197,9 @@ Wave_write objects, as returned by :func:`.open`, have the following methods: .. method:: Wave_write.setnframes(n) - Set the number of frames to *n*. This will be changed later if more frames are - written. + Set the number of frames to *n*. This will be changed later if the number + of frames actually written is different (this update attempt will + raise an error if the output stream is not seekable). .. method:: Wave_write.setcomptype(type, name) @@ -209,16 +226,18 @@ Wave_write objects, as returned by :func:`.open`, have the following methods: Write audio frames, without correcting *nframes*. .. versionchanged:: 3.4 - Any :term:`bytes-like object`\ s are now accepted. + Any :term:`bytes-like object` is now accepted. .. method:: Wave_write.writeframes(data) - Write audio frames and make sure *nframes* is correct. Can raise an - exception if a file is not seekable. + Write audio frames and make sure *nframes* is correct. It will raise an + error if the output stream is not seekable and the total number of frames + that have been written after *data* has been written does not match the + previously set value for *nframes*. .. versionchanged:: 3.4 - Any :term:`bytes-like object`\ s are now accepted. + Any :term:`bytes-like object` is now accepted. Note that it is invalid to set any parameters after calling :meth:`writeframes` diff --git a/Doc/library/weakref.rst b/Doc/library/weakref.rst index e84ac2bc0a46..2e16077b8a6a 100644 --- a/Doc/library/weakref.rst +++ b/Doc/library/weakref.rst @@ -123,15 +123,6 @@ Extension types can easily be made to support weak references; see weakref. If there is no callback or if the referent of the weakref is no longer alive then this attribute will have value ``None``. - .. note:: - - Like :meth:`__del__` methods, weak reference callbacks can be - called during interpreter shutdown when module globals have been - overwritten with :const:`None`. This can make writing robust - weak reference callbacks a challenge. Callbacks registered - using :class:`finalize` do not have to worry about this issue - because they will not be run after module teardown has begun. - .. versionchanged:: 3.4 Added the :attr:`__callback__` attribute. @@ -247,7 +238,7 @@ These method have the same issues as the and :meth:`keyrefs` method of .. class:: finalize(obj, func, *args, **kwargs) Return a callable finalizer object which will be called when *obj* - is garbage collected. Unlike an ordinary weak reference, a finalizer is + is garbage collected. Unlike an ordinary weak reference, a finalizer will always survive until the reference object is collected, greatly simplifying lifecycle management. @@ -267,7 +258,7 @@ These method have the same issues as the and :meth:`keyrefs` method of are called in reverse order of creation. A finalizer will never invoke its callback during the later part of - the interpreter shutdown when module globals are liable to have + the :term:`interpreter shutdown` when module globals are liable to have been replaced by :const:`None`. .. method:: __call__() @@ -536,8 +527,8 @@ follows:: Starting with Python 3.4, :meth:`__del__` methods no longer prevent reference cycles from being garbage collected, and module globals are -no longer forced to :const:`None` during interpreter shutdown. So this -code should work without any issues on CPython. +no longer forced to :const:`None` during :term:`interpreter shutdown`. +So this code should work without any issues on CPython. However, handling of :meth:`__del__` methods is notoriously implementation specific, since it depends on internal details of the interpreter's garbage @@ -575,8 +566,8 @@ third party, such as running code when a module is unloaded:: .. note:: - If you create a finalizer object in a daemonic thread just as the - the program exits then there is the possibility that the finalizer + If you create a finalizer object in a daemonic thread just as the program + exits then there is the possibility that the finalizer does not get called at exit. However, in a daemonic thread :func:`atexit.register`, ``try: ... finally: ...`` and ``with: ...`` do not guarantee that cleanup occurs either. diff --git a/Doc/library/webbrowser.rst b/Doc/library/webbrowser.rst index 9c2b3abb6923..aa5e4ad15d76 100644 --- a/Doc/library/webbrowser.rst +++ b/Doc/library/webbrowser.rst @@ -19,12 +19,12 @@ will be used if graphical browsers are not available or an X11 display isn't available. If text-mode browsers are used, the calling process will block until the user exits the browser. -If the environment variable :envvar:`BROWSER` exists, it is interpreted to -override the platform default list of browsers, as a :data:`os.pathsep`-separated -list of browsers to try in order. When the value of a list part contains the -string ``%s``, then it is interpreted as a literal browser command line to be -used with the argument URL substituted for ``%s``; if the part does not contain -``%s``, it is simply interpreted as the name of the browser to launch. [1]_ +If the environment variable :envvar:`BROWSER` exists, it is interpreted as the +:data:`os.pathsep`-separated list of browsers to try ahead of the platform +defaults. When the value of a list part contains the string ``%s``, then it is +interpreted as a literal browser command line to be used with the argument URL +substituted for ``%s``; if the part does not contain ``%s``, it is simply +interpreted as the name of the browser to launch. [1]_ For non-Unix platforms, or when a remote browser is available on Unix, the controlling process will not wait for the user to finish with the browser, but diff --git a/Doc/library/winreg.rst b/Doc/library/winreg.rst index 60f3bd91f132..6c920b4882d5 100644 --- a/Doc/library/winreg.rst +++ b/Doc/library/winreg.rst @@ -146,7 +146,7 @@ This module offers the following functions: *reserved* is a reserved integer, and must be zero. The default is zero. *access* is an integer that specifies an access mask that describes the desired - security access for the key. Default is :const:`KEY_ALL_ACCESS`. See + security access for the key. Default is :const:`KEY_WOW64_64KEY`. See :ref:`Access Rights <access-rights>` for other allowed values. *This method can not delete keys with subkeys.* @@ -322,7 +322,7 @@ This module offers the following functions: +-------+---------------------------------------------+ | ``2`` | An integer giving when the key was last | | | modified (if available) as 100's of | - | | nanoseconds since Jan 1, 1600. | + | | nanoseconds since Jan 1, 1601. | +-------+---------------------------------------------+ diff --git a/Doc/library/wsgiref.rst b/Doc/library/wsgiref.rst index 1cef2e9464e2..223814030f12 100644 --- a/Doc/library/wsgiref.rst +++ b/Doc/library/wsgiref.rst @@ -184,10 +184,11 @@ This module provides a single class, :class:`Headers`, for convenient manipulation of WSGI response headers using a mapping-like interface. -.. class:: Headers(headers) +.. class:: Headers([headers]) Create a mapping-like object wrapping *headers*, which must be a list of header - name/value tuples as described in :pep:`3333`. + name/value tuples as described in :pep:`3333`. The default value of *headers* is + an empty list. :class:`Headers` objects support typical mapping operations including :meth:`__getitem__`, :meth:`get`, :meth:`__setitem__`, :meth:`setdefault`, @@ -251,6 +252,10 @@ manipulation of WSGI response headers using a mapping-like interface. Content-Disposition: attachment; filename="bud.gif" + .. versionchanged:: 3.5 + *headers* parameter is optional. + + :mod:`wsgiref.simple_server` -- a simple WSGI HTTP server --------------------------------------------------------- diff --git a/Doc/library/xml.dom.minidom.rst b/Doc/library/xml.dom.minidom.rst index 5d821f17d0b3..ff5c270d9f6d 100644 --- a/Doc/library/xml.dom.minidom.rst +++ b/Doc/library/xml.dom.minidom.rst @@ -252,4 +252,4 @@ utility to most DOM users. "UTF8" is not valid in an XML document's declaration, even though Python accepts it as an encoding name. See http://www.w3.org/TR/2006/REC-xml11-20060816/#NT-EncodingDecl - and http://www.iana.org/assignments/character-sets . + and http://www.iana.org/assignments/character-sets/character-sets.xhtml. diff --git a/Doc/library/xml.dom.rst b/Doc/library/xml.dom.rst index 19512ed3f764..4914738dfc6a 100644 --- a/Doc/library/xml.dom.rst +++ b/Doc/library/xml.dom.rst @@ -412,7 +412,7 @@ objects: .. method:: NodeList.item(i) Return the *i*'th item from the sequence, if there is one, or ``None``. The - index *i* is not allowed to be less then zero or greater than or equal to the + index *i* is not allowed to be less than zero or greater than or equal to the length of the sequence. diff --git a/Doc/library/xml.etree.elementtree.rst b/Doc/library/xml.etree.elementtree.rst index 4c89dc34ea9e..3263dc2a028e 100644 --- a/Doc/library/xml.etree.elementtree.rst +++ b/Doc/library/xml.etree.elementtree.rst @@ -105,12 +105,28 @@ Children are nested, and we can access specific child nodes by index:: >>> root[0][1].text '2008' + +.. note:: + + Not all elements of the XML input will end up as elements of the + parsed tree. Currently, this module skips over any XML comments, + processing instructions, and document type declarations in the + input. Nevertheless, trees built using this module's API rather + than parsing from XML text can have comments and processing + instructions in them; they will be included when generating XML + output. A document type declaration may be accessed by passing a + custom :class:`TreeBuilder` instance to the :class:`XMLParser` + constructor. + + +.. _elementtree-pull-parsing: + Pull API for non-blocking parsing ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Most parsing functions provided by this module require to read the whole -document at once before returning any result. It is possible to use a -:class:`XMLParser` and feed data into it incrementally, but it's a push API that +Most parsing functions provided by this module require the whole document +to be read at once before returning any result. It is possible to use an +:class:`XMLParser` and feed data into it incrementally, but it is a push API that calls methods on a callback target, which is too low-level and inconvenient for most needs. Sometimes what the user really wants is to be able to parse XML incrementally, without blocking operations, while enjoying the convenience of @@ -119,7 +135,7 @@ fully constructed :class:`Element` objects. The most powerful tool for doing this is :class:`XMLPullParser`. It does not require a blocking read to obtain the XML data, and is instead fed with data incrementally with :meth:`XMLPullParser.feed` calls. To get the parsed XML -elements, call :meth:`XMLPullParser.read_events`. Here's an example:: +elements, call :meth:`XMLPullParser.read_events`. Here is an example:: >>> parser = ET.XMLPullParser(['start', 'end']) >>> parser.feed('<mytag>sometext') @@ -322,7 +338,7 @@ Supported XPath syntax +=======================+======================================================+ | ``tag`` | Selects all child elements with the given tag. | | | For example, ``spam`` selects all child elements | -| | named ``spam``, ``spam/egg`` selects all | +| | named ``spam``, and ``spam/egg`` selects all | | | grandchildren named ``egg`` in all children named | | | ``spam``. | +-----------------------+------------------------------------------------------+ @@ -378,6 +394,10 @@ Functions string containing the comment string. Returns an element instance representing a comment. + Note that :class:`XMLParser` skips over comments in the input + instead of creating comment objects for them. An :class:`ElementTree` will + only contain comment nodes if they have been inserted into to + the tree using one of the :class:`Element` methods. .. function:: dump(elem) @@ -458,6 +478,11 @@ Functions containing the PI target. *text* is a string containing the PI contents, if given. Returns an element instance, representing a processing instruction. + Note that :class:`XMLParser` skips over processing instructions + in the input instead of creating comment objects for them. An + :class:`ElementTree` will only contain processing instruction nodes if + they have been inserted into to the tree using one of the + :class:`Element` methods. .. function:: register_namespace(prefix, uri) @@ -508,7 +533,7 @@ Functions *short_empty_elements* has the same meaning as in :meth:`ElementTree.write`. Returns a list of (optionally) encoded strings containing the XML data. It does not guarantee any specific sequence, except that - ``"".join(tostringlist(element)) == tostring(element)``. + ``b"".join(tostringlist(element)) == tostring(element)``. .. versionadded:: 3.2 @@ -831,8 +856,8 @@ ElementTree Objects :term:`file object`; make sure you do not try to write a string to a binary stream and vice versa. - .. versionadded:: 3.4 - The *short_empty_elements* parameter. + .. versionadded:: 3.4 + The *short_empty_elements* parameter. This is the XML file that is going to be manipulated:: @@ -949,7 +974,8 @@ XMLParser Objects specified in the XML file. .. deprecated:: 3.4 - The *html* argument. + The *html* argument. The remaining arguments should be passed via + keywword to prepare for the removal of the *html* argument. .. method:: close() @@ -1038,15 +1064,17 @@ XMLPullParser Objects .. method:: read_events() - Iterate over the events which have been encountered in the data fed to the - parser. This method yields ``(event, elem)`` pairs, where *event* is a + Return an iterator over the events which have been encountered in the + data fed to the + parser. The iterator yields ``(event, elem)`` pairs, where *event* is a string representing the type of event (e.g. ``"end"``) and *elem* is the encountered :class:`Element` object. Events provided in a previous call to :meth:`read_events` will not be - yielded again. As events are consumed from the internal queue only as - they are retrieved from the iterator, multiple readers calling - :meth:`read_events` in parallel will have unpredictable results. + yielded again. Events are consumed from the internal queue only when + they are retrieved from the iterator, so multiple readers iterating in + parallel over iterators obtained from :meth:`read_events` will have + unpredictable results. .. note:: @@ -1084,4 +1112,4 @@ Exceptions .. [#] The encoding string included in XML output should conform to the appropriate standards. For example, "UTF-8" is valid, but "UTF8" is not. See http://www.w3.org/TR/2006/REC-xml11-20060816/#NT-EncodingDecl - and http://www.iana.org/assignments/character-sets. + and http://www.iana.org/assignments/character-sets/character-sets.xhtml. diff --git a/Doc/library/xml.rst b/Doc/library/xml.rst index d796d828ab8d..018821909201 100644 --- a/Doc/library/xml.rst +++ b/Doc/library/xml.rst @@ -14,9 +14,9 @@ Python's interfaces for processing XML are grouped in the ``xml`` package. .. warning:: The XML modules are not secure against erroneous or maliciously - constructed data. If you need to parse untrusted or unauthenticated data see - :ref:`xml-vulnerabilities`. - + constructed data. If you need to parse untrusted or + unauthenticated data see the :ref:`xml-vulnerabilities` and + :ref:`defused-packages` sections. It is important to note that modules in the :mod:`xml` package require that there be at least one SAX-compliant XML parser available. The Expat parser is @@ -29,11 +29,12 @@ definition of the Python bindings for the DOM and SAX interfaces. The XML handling submodules are: * :mod:`xml.etree.ElementTree`: the ElementTree API, a simple and lightweight + XML processor .. * :mod:`xml.dom`: the DOM API definition -* :mod:`xml.dom.minidom`: a lightweight DOM implementation +* :mod:`xml.dom.minidom`: a minimal DOM implementation * :mod:`xml.dom.pulldom`: support for building partial DOM trees .. @@ -45,16 +46,15 @@ The XML handling submodules are: .. _xml-vulnerabilities: XML vulnerabilities -=================== +------------------- The XML processing modules are not secure against maliciously constructed data. -An attacker can abuse vulnerabilities for e.g. denial of service attacks, to -access local files, to generate network connections to other machines, or -to or circumvent firewalls. The attacks on XML abuse unfamiliar features -like inline `DTD`_ (document type definition) with entities. +An attacker can abuse XML features to carry out denial of service attacks, +access local files, generate network connections to other machines, or +circumvent firewalls. -The following table gives an overview of the known attacks and if the various -modules are vulnerable to them. +The following table gives an overview of the known attacks and whether +the various modules are vulnerable to them. ========================= ======== ========= ========= ======== ========= kind sax etree minidom pulldom xmlrpc @@ -67,7 +67,7 @@ decompression bomb No No No No **Yes** ========================= ======== ========= ========= ======== ========= 1. :mod:`xml.etree.ElementTree` doesn't expand external entities and raises a - ParserError when an entity occurs. + :exc:`ParserError` when an entity occurs. 2. :mod:`xml.dom.minidom` doesn't expand external entities and simply returns the unexpanded entity verbatim. 3. :mod:`xmlrpclib` doesn't expand external entities and omits them. @@ -76,55 +76,54 @@ decompression bomb No No No No **Yes** billion laughs / exponential entity expansion The `Billion Laughs`_ attack -- also known as exponential entity expansion -- uses multiple levels of nested entities. Each entity refers to another entity - several times, the final entity definition contains a small string. Eventually - the small string is expanded to several gigabytes. The exponential expansion - consumes lots of CPU time, too. + several times, and the final entity definition contains a small string. + The exponential expansion results in several gigabytes of text and + consumes lots of memory and CPU time. quadratic blowup entity expansion A quadratic blowup attack is similar to a `Billion Laughs`_ attack; it abuses entity expansion, too. Instead of nested entities it repeats one large entity with a couple of thousand chars over and over again. The attack isn't as - efficient as the exponential case but it avoids triggering countermeasures of - parsers against heavily nested entities. + efficient as the exponential case but it avoids triggering parser countermeasures + that forbid deeply-nested entities. external entity expansion Entity declarations can contain more than just text for replacement. They can - also point to external resources by public identifiers or system identifiers. - System identifiers are standard URIs or can refer to local files. The XML - parser retrieves the resource with e.g. HTTP or FTP requests and embeds the - content into the XML document. + also point to external resources or local files. The XML + parser accesses the resource and embeds the content into the XML document. DTD retrieval - Some XML libraries like Python's mod:'xml.dom.pulldom' retrieve document type + Some XML libraries like Python's :mod:`xml.dom.pulldom` retrieve document type definitions from remote or local locations. The feature has similar implications as the external entity expansion issue. decompression bomb - The issue of decompression bombs (aka `ZIP bomb`_) apply to all XML libraries - that can parse compressed XML stream like gzipped HTTP streams or LZMA-ed + Decompression bombs (aka `ZIP bomb`_) apply to all XML libraries + that can parse compressed XML streams such as gzipped HTTP streams or + LZMA-compressed files. For an attacker it can reduce the amount of transmitted data by three magnitudes or more. -The documentation of `defusedxml`_ on PyPI has further information about +The documentation for `defusedxml`_ on PyPI has further information about all known attack vectors with examples and references. -defused packages ----------------- +.. _defused-packages: -`defusedxml`_ is a pure Python package with modified subclasses of all stdlib -XML parsers that prevent any potentially malicious operation. The courses of -action are recommended for any server code that parses untrusted XML data. The -package also ships with example exploits and an extended documentation on more -XML exploits like xpath injection. +The :mod:`defusedxml` and :mod:`defusedexpat` Packages +------------------------------------------------------ -`defusedexpat`_ provides a modified libexpat and patched replacment -:mod:`pyexpat` extension module with countermeasures against entity expansion -DoS attacks. Defusedexpat still allows a sane and configurable amount of entity -expansions. The modifications will be merged into future releases of Python. +`defusedxml`_ is a pure Python package with modified subclasses of all stdlib +XML parsers that prevent any potentially malicious operation. Use of this +package is recommended for any server code that parses untrusted XML data. The +package also ships with example exploits and extended documentation on more +XML exploits such as XPath injection. -The workarounds and modifications are not included in patch releases as they -break backward compatibility. After all inline DTD and entity expansion are -well-definied XML features. +`defusedexpat`_ provides a modified libexpat and a patched +:mod:`pyexpat` module that have countermeasures against entity expansion +DoS attacks. The :mod:`defusedexpat` module still allows a sane and configurable amount of entity +expansions. The modifications may be included in some future release of Python, +but will not be included in any bugfix releases of +Python because they break backward compatibility. .. _defusedxml: https://pypi.python.org/pypi/defusedxml/ @@ -132,4 +131,3 @@ well-definied XML features. .. _Billion Laughs: http://en.wikipedia.org/wiki/Billion_laughs .. _ZIP bomb: http://en.wikipedia.org/wiki/Zip_bomb .. _DTD: http://en.wikipedia.org/wiki/Document_Type_Definition - diff --git a/Doc/library/xmlrpc.client.rst b/Doc/library/xmlrpc.client.rst index 3cb19d186267..e199931b55bd 100644 --- a/Doc/library/xmlrpc.client.rst +++ b/Doc/library/xmlrpc.client.rst @@ -27,10 +27,14 @@ between conformable Python objects and XML on the wire. constructed data. If you need to parse untrusted or unauthenticated data see :ref:`xml-vulnerabilities`. +.. versionchanged:: 3.5 + + For https URIs, :mod:`xmlrpc.client` now performs all the necessary + certificate and hostname checks by default .. class:: ServerProxy(uri, transport=None, encoding=None, verbose=False, \ allow_none=False, use_datetime=False, \ - use_builtin_types=False) + use_builtin_types=False, *, context=None) .. versionchanged:: 3.3 The *use_builtin_types* flag was added. @@ -59,7 +63,9 @@ between conformable Python objects and XML on the wire. portion will be base64-encoded as an HTTP 'Authorization' header, and sent to the remote server as part of the connection process when invoking an XML-RPC method. You only need to use this if the remote server requires a Basic - Authentication user and password. + Authentication user and password. If an HTTPS url is provided, *context* may + be :class:`ssl.SSLContext` and configures the SSL settings of the underlying + HTTPS connection. The returned instance is a proxy object with methods that can be used to invoke corresponding RPC calls on the remote server. If the remote server supports the @@ -123,6 +129,9 @@ between conformable Python objects and XML on the wire. :class:`Server` is retained as an alias for :class:`ServerProxy` for backwards compatibility. New code should use :class:`ServerProxy`. + .. versionchanged:: 3.5 + Added the *context* argument. + .. seealso:: @@ -191,6 +200,11 @@ grouped under the reserved :attr:`system` attribute: no such string is available, an empty string is returned. The documentation string may contain HTML markup. +.. versionchanged:: 3.5 + + Instances of :class:`ServerProxy` support the :term:`context manager` protocol + for closing the underlying transport. + A working example follows. The server code:: @@ -208,9 +222,9 @@ The client code for the preceding server:: import xmlrpc.client - proxy = xmlrpc.client.ServerProxy("http://localhost:8000/") - print("3 is even: %s" % str(proxy.is_even(3))) - print("100 is even: %s" % str(proxy.is_even(100))) + with xmlrpc.client.ServerProxy("http://localhost:8000/") as proxy: + print("3 is even: %s" % str(proxy.is_even(3))) + print("100 is even: %s" % str(proxy.is_even(100))) .. _datetime-objects: @@ -518,14 +532,14 @@ Example of Client Usage from xmlrpc.client import ServerProxy, Error # server = ServerProxy("http://localhost:8000") # local server - server = ServerProxy("http://betty.userland.com") + with ServerProxy("http://betty.userland.com") as proxy: - print(server) + print(proxy) - try: - print(server.examples.getStateName(41)) - except Error as v: - print("ERROR", v) + try: + print(proxy.examples.getStateName(41)) + except Error as v: + print("ERROR", v) To access an XML-RPC server through a proxy, you need to define a custom transport. The following example shows how: diff --git a/Doc/library/xmlrpc.server.rst b/Doc/library/xmlrpc.server.rst index 18fee2fc1d36..37d1393eff03 100644 --- a/Doc/library/xmlrpc.server.rst +++ b/Doc/library/xmlrpc.server.rst @@ -184,6 +184,70 @@ server:: # Print list of available methods print(s.system.listMethods()) +The following example included in the :file:`Lib/xmlrpc/server.py` module shows +a server allowing dotted names and registering a multicall function. + +.. warning:: + + Enabling the *allow_dotted_names* option allows intruders to access your + module's global variables and may allow intruders to execute arbitrary code on + your machine. Only use this example only within a secure, closed network. + +:: + + import datetime + + class ExampleService: + def getData(self): + return '42' + + class currentTime: + @staticmethod + def getCurrentTime(): + return datetime.datetime.now() + + server = SimpleXMLRPCServer(("localhost", 8000)) + server.register_function(pow) + server.register_function(lambda x,y: x+y, 'add') + server.register_instance(ExampleService(), allow_dotted_names=True) + server.register_multicall_functions() + print('Serving XML-RPC on localhost port 8000') + try: + server.serve_forever() + except KeyboardInterrupt: + print("\nKeyboard interrupt received, exiting.") + server.server_close() + sys.exit(0) + +This ExampleService demo can be invoked from the command line:: + + python -m xmlrpc.server + + +The client that interacts with the above server is included in +`Lib/xmlrpc/client.py`:: + + server = ServerProxy("http://localhost:8000") + + try: + print(server.currentTime.getCurrentTime()) + except Error as v: + print("ERROR", v) + + multi = MultiCall(server) + multi.getData() + multi.pow(2,9) + multi.add(1,2) + try: + for response in multi(): + print(response) + except Error as v: + print("ERROR", v) + +This client which interacts with the demo XMLRPC server can be invoked as:: + + python -m xmlrpc.client + CGIXMLRPCRequestHandler ----------------------- diff --git a/Doc/library/zipfile.rst b/Doc/library/zipfile.rst index 969a5363be5a..465d786cbd12 100644 --- a/Doc/library/zipfile.rst +++ b/Doc/library/zipfile.rst @@ -219,14 +219,8 @@ ZipFile Objects .. note:: - If the ZipFile was created by passing in a file-like object as the first - argument to the constructor, then the object returned by :meth:`.open` shares the - ZipFile's file pointer. Under these circumstances, the object returned by - :meth:`.open` should not be used after any additional operations are performed - on the ZipFile object. If the ZipFile was created by passing in a string (the - filename) as the first argument to the constructor, then :meth:`.open` will - create a new file object that will be held by the ZipExtFile, allowing it to - operate independently of the ZipFile. + Objects returned by :meth:`.open` can operate independently of the + ZipFile. .. note:: @@ -401,18 +395,32 @@ The :class:`PyZipFile` constructor takes the same parameters as the ``2``, only files with that optimization level (see :func:`compile`) are added to the archive, compiling if necessary. - If the pathname is a file, the filename must end with :file:`.py`, and + If *pathname* is a file, the filename must end with :file:`.py`, and just the (corresponding :file:`\*.py[co]`) file is added at the top level - (no path information). If the pathname is a file that does not end with + (no path information). If *pathname* is a file that does not end with :file:`.py`, a :exc:`RuntimeError` will be raised. If it is a directory, and the directory is not a package directory, then all the files :file:`\*.py[co]` are added at the top level. If the directory is a package directory, then all :file:`\*.py[co]` are added under the package name as a file path, and if any subdirectories are package directories, - all of these are added recursively. *basename* is intended for internal - use only. When *filterfunc(pathname)* is given, it will be called for every - invocation. When it returns a false value, that path and its subpaths will - be ignored. + all of these are added recursively. + + *basename* is intended for internal use only. + + *filterfunc*, if given, must be a function taking a single string + argument. It will be passed each path (including each individual full + file path) before it is added to the archive. If *filterfunc* returns a + false value, the path will not be added, and if it is a directory its + contents will be ignored. For example, if our test files are all either + in ``test`` directories or start with the string ``test_``, we can use a + *filterfunc* to exclude them:: + + >>> zf = PyZipFile('myprog.zip') + >>> def notests(s): + ... fn = os.path.basename(s) + ... return (not (fn == 'test' or fn.startswith('test_'))) + >>> zf.writepy('myprog', filterfunc=notests) + The :meth:`writepy` method makes archives with file names like this:: diff --git a/Doc/library/zlib.rst b/Doc/library/zlib.rst index d9a29a8814e7..b178fe106a81 100644 --- a/Doc/library/zlib.rst +++ b/Doc/library/zlib.rst @@ -197,7 +197,7 @@ Decompression objects support the following methods and attributes: .. attribute:: Decompress.unused_data A bytes object which contains any bytes past the end of the compressed data. That is, - this remains ``""`` until the last byte that contains compression data is + this remains ``b""`` until the last byte that contains compression data is available. If the whole bytestring turned out to contain compressed data, this is ``b""``, an empty bytes object. diff --git a/Doc/license.rst b/Doc/license.rst index ddc69b839d71..53a1c4d57ec4 100644 --- a/Doc/license.rst +++ b/Doc/license.rst @@ -23,11 +23,11 @@ In May 2000, Guido and the Python core development team moved to BeOpen.com to form the BeOpen PythonLabs team. In October of the same year, the PythonLabs team moved to Digital Creations (now Zope Corporation; see http://www.zope.com/). In 2001, the Python Software Foundation (PSF, see -http://www.python.org/psf/) was formed, a non-profit organization created +https://www.python.org/psf/) was formed, a non-profit organization created specifically to own Python-related Intellectual Property. Zope Corporation is a sponsoring member of the PSF. -All Python releases are Open Source (see http://www.opensource.org/ for the Open +All Python releases are Open Source (see http://opensource.org/ for the Open Source Definition). Historically, most, but not all, Python releases have also been GPL-compatible; the table below summarizes the various releases. @@ -84,9 +84,9 @@ Terms and conditions for accessing or otherwise using Python 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-2013 Python Software Foundation; All Rights - Reserved" are retained in Python |release| alone or in any derivative version - prepared by Licensee. + copyright, i.e., "Copyright © 2001-2015 Python Software Foundation; All + Rights Reserved" are retained in Python |release| alone or in any derivative + version prepared by Licensee. #. In the event Licensee prepares a derivative work that is based on or incorporates Python |release| or any part thereof, and wants to make the @@ -590,25 +590,6 @@ The :mod:`select` and contains the following notice for the kqueue interface:: SUCH DAMAGE. -SHA-3 ------ - -The module :mod:`_sha3` and :mod:`hashlib` are using the reference -implementation of Keccak. The files at :file:`Modules/_sha3/keccak/` contain -the following note:: - - The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, - Michaël Peeters and Gilles Van Assche. For more information, feedback or - questions, please refer to our website: http://keccak.noekeon.org/ - - Implementation by the designers, - hereby denoted as "the implementer". - - To the extent possible under law, the implementer has waived all copyright - and related or neighboring rights to the source code in this file. - http://creativecommons.org/publicdomain/zero/1.0/ - - SipHash24 --------- @@ -673,9 +654,9 @@ OpenSSL The modules :mod:`hashlib`, :mod:`posix`, :mod:`ssl`, :mod:`crypt` use the OpenSSL library for added performance if made available by the -operating system. Additionally, the Windows installers for Python -include a copy of the OpenSSL libraries, so we include a copy of the -OpenSSL license here:: +operating system. Additionally, the Windows and Mac OS X installers for +Python may include a copy of the OpenSSL libraries, so we include a copy +of the OpenSSL license here:: LICENSE ISSUES @@ -897,7 +878,7 @@ used for the build:: cfuhash ------- -The implementtation of the hash table used by the :mod:`tracemalloc` is based +The implementation of the hash table used by the :mod:`tracemalloc` is based on the cfuhash project:: Copyright (c) 2005 Don Owens @@ -934,3 +915,36 @@ on the cfuhash project:: ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +libmpdec +-------- + +The :mod:`_decimal` Module is built using an included copy of the libmpdec +library unless the build is configured ``--with-system-libmpdec``:: + + Copyright (c) 2008-2016 Stefan Krah. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + diff --git a/Doc/make.bat b/Doc/make.bat index 675e79300b06..6aae34a7e281 100644 --- a/Doc/make.bat +++ b/Doc/make.bat @@ -1,59 +1,133 @@ -@@echo off +@echo off setlocal -set SVNROOT=http://svn.python.org/projects -if "%PYTHON%" EQU "" set PYTHON=py -2 -if "%HTMLHELP%" EQU "" set HTMLHELP=%ProgramFiles%\HTML Help Workshop\hhc.exe -if "%DISTVERSION%" EQU "" for /f "usebackq" %%v in (`%PYTHON% tools/sphinxext/patchlevel.py`) do set DISTVERSION=%%v +pushd %~dp0 +set this=%~n0 + +if "%SPHINXBUILD%" EQU "" set SPHINXBUILD=sphinx-build +if "%PYTHON%" EQU "" set PYTHON=py + +if "%1" NEQ "htmlhelp" goto :skiphhcsearch +if exist "%HTMLHELP%" goto :skiphhcsearch + +rem Search for HHC in likely places +set HTMLHELP= +where hhc /q && set HTMLHELP=hhc && goto :skiphhcsearch +where /R ..\externals hhc > "%TEMP%\hhc.loc" 2> nul && set /P HTMLHELP= < "%TEMP%\hhc.loc" & del "%TEMP%\hhc.loc" +if not exist "%HTMLHELP%" where /R "%ProgramFiles(x86)%" hhc > "%TEMP%\hhc.loc" 2> nul && set /P HTMLHELP= < "%TEMP%\hhc.loc" & del "%TEMP%\hhc.loc" +if not exist "%HTMLHELP%" where /R "%ProgramFiles%" hhc > "%TEMP%\hhc.loc" 2> nul && set /P HTMLHELP= < "%TEMP%\hhc.loc" & del "%TEMP%\hhc.loc" +if not exist "%HTMLHELP%" echo Cannot find HHC on PATH or in externals & exit /B 1 +:skiphhcsearch + +if "%DISTVERSION%" EQU "" for /f "usebackq" %%v in (`%PYTHON% tools/extensions/patchlevel.py`) do set DISTVERSION=%%v + +if "%BUILDDIR%" EQU "" set BUILDDIR=build + +rem Targets that don't require sphinx-build if "%1" EQU "" goto help -if "%1" EQU "html" goto build -if "%1" EQU "htmlhelp" goto build -if "%1" EQU "latex" goto build -if "%1" EQU "text" goto build -if "%1" EQU "suspicious" goto build -if "%1" EQU "linkcheck" goto build -if "%1" EQU "changes" goto build -if "%1" EQU "checkout" goto checkout -if "%1" EQU "update" goto update +if "%1" EQU "help" goto help +if "%1" EQU "check" goto check +if "%1" EQU "serve" goto serve +if "%1" == "clean" ( + rmdir /q /s %BUILDDIR% + goto end +) + +%SPHINXBUILD% 2> nul +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + popd + exit /B 1 +) + +rem Targets that do require sphinx-build and have their own label +if "%1" EQU "htmlview" goto htmlview + +rem Everything else +goto build :help -set this=%~n0 -echo HELP +echo.usage: %this% BUILDER [filename ...] echo. -echo %this% checkout -echo %this% update -echo %this% html -echo %this% htmlhelp -echo %this% latex -echo %this% text -echo %this% suspicious -echo %this% linkcheck -echo %this% changes +echo.Call %this% with the desired Sphinx builder as the first argument, e.g. +echo.``%this% html`` or ``%this% doctest``. Interesting targets that are +echo.always available include: echo. +echo. Provided by Sphinx: +echo. html, htmlhelp, latex, text +echo. suspicious, linkcheck, changes, doctest +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.the documentation for your version of Sphinx for more exhaustive lists +echo.of available targets and descriptions of each. +echo. +echo.This script assumes that the SPHINXBUILD environment variable contains +echo.a legitimate command for calling sphinx-build, or that sphinx-build is +echo.on your PATH if SPHINXBUILD is not set. Options for sphinx-build can +echo.be passed by setting the SPHINXOPTS environment variable. goto end -:checkout -svn co %SVNROOT%/external/Sphinx-1.0.7/sphinx tools/sphinx -svn co %SVNROOT%/external/docutils-0.6/docutils tools/docutils -svn co %SVNROOT%/external/Jinja-2.3.1/jinja2 tools/jinja2 -svn co %SVNROOT%/external/Pygments-1.5dev-20120930/pygments tools/pygments +:build +if NOT "%PAPER%" == "" ( + set SPHINXOPTS=-D latex_paper_size=%PAPER% %SPHINXOPTS% +) +cmd /C %SPHINXBUILD% %SPHINXOPTS% -b%1 -dbuild\doctrees . %BUILDDIR%\%* + +if "%1" EQU "htmlhelp" ( + if not exist "%HTMLHELP%" ( + echo. + echo.The HTML Help Workshop was not found. Set the HTMLHELP variable + echo.to the path to hhc.exe or download and install it from + echo.http://msdn.microsoft.com/en-us/library/ms669985 + rem Set errorlevel to 1 and exit + cmd /C exit /b 1 + goto end + ) + cmd /C "%HTMLHELP%" build\htmlhelp\python%DISTVERSION:.=%.hhp + rem hhc.exe seems to always exit with code 1, reset to 0 for less than 2 + if not errorlevel 2 cmd /C exit /b 0 +) + +echo. +if errorlevel 1 ( + echo.Build failed (exit code %ERRORLEVEL%^), check for error messages + echo.above. Any output will be found in %BUILDDIR%\%1 +) else ( + echo.Build succeeded. All output should be in %BUILDDIR%\%1 +) goto end -:update -svn update tools/sphinx -svn update tools/docutils -svn update tools/jinja2 -svn update tools/pygments +:htmlview +if NOT "%2" EQU "" ( + echo.Can't specify filenames to build with htmlview target, ignoring. +) +cmd /C %this% html + +if EXIST %BUILDDIR%\html\index.html ( + echo.Opening %BUILDDIR%\html\index.html in the default web browser... + start %BUILDDIR%\html\index.html +) + goto end -:build -if not exist build mkdir build -if not exist build\%1 mkdir build\%1 -if not exist build\doctrees mkdir build\doctrees -cmd /C %PYTHON% --version -cmd /C %PYTHON% tools\sphinx-build.py -b%1 -dbuild\doctrees . build\%* -if "%1" EQU "htmlhelp" "%HTMLHELP%" build\htmlhelp\python%DISTVERSION:.=%.hhp +:check +cmd /C %PYTHON% tools\rstlint.py -i tools +goto end + +:serve +cmd /C %PYTHON% ..\Tools\scripts\serve.py %BUILDDIR%\html goto end :end +popd diff --git a/Doc/reference/compound_stmts.rst b/Doc/reference/compound_stmts.rst index e35aa9f74058..5dd17eb0305a 100644 --- a/Doc/reference/compound_stmts.rst +++ b/Doc/reference/compound_stmts.rst @@ -22,14 +22,14 @@ also syntactically compound statements. single: clause single: suite -Compound statements consist of one or more 'clauses.' A clause consists of a +A compound statement consists of one or more 'clauses.' A clause consists of a header and a 'suite.' The clause headers of a particular compound statement are all at the same indentation level. Each clause header begins with a uniquely identifying keyword and ends with a colon. A suite is a group of statements controlled by a clause. A suite can be one or more semicolon-separated simple statements on the same line as the header, following the header's colon, or it can be one or more indented statements on subsequent lines. Only the latter -form of suite can contain nested compound statements; the following is illegal, +form of a suite can contain nested compound statements; the following is illegal, mostly because it wouldn't be clear to which :keyword:`if` clause a following :keyword:`else` clause would belong:: @@ -156,8 +156,8 @@ The :keyword:`for` statement is used to iterate over the elements of a sequence The expression list is evaluated once; it should yield an iterable object. An iterator is created for the result of the ``expression_list``. The suite is -then executed once for each item provided by the iterator, in the order of -ascending indices. Each item in turn is assigned to the target list using the +then executed once for each item provided by the iterator, in the order returned +by the iterator. Each item in turn is assigned to the target list using the standard rules for assignments (see :ref:`assignment`), and then the suite is executed. When the items are exhausted (which is immediately when the sequence is empty or an iterator raises a :exc:`StopIteration` exception), the suite in @@ -170,17 +170,25 @@ the :keyword:`else` clause, if present, is executed, and the loop terminates. A :keyword:`break` statement executed in the first suite terminates the loop without executing the :keyword:`else` clause's suite. A :keyword:`continue` statement executed in the first suite skips the rest of the suite and continues -with the next item, or with the :keyword:`else` clause if there was no next +with the next item, or with the :keyword:`else` clause if there is no next item. -The suite may assign to the variable(s) in the target list; this does not affect -the next item assigned to it. +The for-loop makes assignments to the variables(s) in the target list. +This overwrites all previous assignments to those variables including +those made in the suite of the for-loop:: + + for i in range(10): + print(i) + i = 5 # this will not affect the for-loop + # because i will be overwritten with the next + # index in the range + .. index:: builtin: range Names in the target list are not deleted when the loop is finished, but if the -sequence is empty, it will not have been assigned to at all by the loop. Hint: +sequence is empty, they will not have been assigned to at all by the loop. Hint: the built-in function :func:`range` returns an iterator of integers suitable to emulate the effect of Pascal's ``for i := a to b do``; e.g., ``list(range(3))`` returns the list ``[0, 1, 2]``. @@ -226,7 +234,7 @@ for a group of statements: .. productionlist:: try_stmt: try1_stmt | try2_stmt try1_stmt: "try" ":" `suite` - : ("except" [`expression` ["as" `target`]] ":" `suite`)+ + : ("except" [`expression` ["as" `identifier`]] ":" `suite`)+ : ["else" ":" `suite`] : ["finally" ":" `suite`] try2_stmt: "try" ":" `suite` @@ -284,7 +292,7 @@ keeping all locals in that frame alive until the next garbage collection occurs. object: traceback Before an except clause's suite is executed, details about the exception are -stored in the :mod:`sys` module and can be access via :func:`sys.exc_info`. +stored in the :mod:`sys` module and can be accessed via :func:`sys.exc_info`. :func:`sys.exc_info` returns a 3-tuple consisting of the exception class, the exception instance and a traceback object (see section :ref:`types`) identifying the point in the program where the exception occurred. :func:`sys.exc_info` @@ -313,14 +321,14 @@ exception, the saved exception is set as the context of the new exception. If the :keyword:`finally` clause executes a :keyword:`return` or :keyword:`break` statement, the saved exception is discarded:: - def f(): - try: - 1/0 - finally: - return 42 - - >>> f() - 42 + >>> def f(): + ... try: + ... 1/0 + ... finally: + ... return 42 + ... + >>> f() + 42 The exception information is not available to the program during execution of the :keyword:`finally` clause. @@ -337,6 +345,20 @@ statement, the :keyword:`finally` clause is also executed 'on the way out.' A reason is a problem with the current implementation --- this restriction may be lifted in the future). +The return value of a function is determined by the last :keyword:`return` +statement executed. Since the :keyword:`finally` clause always executes, a +:keyword:`return` statement executed in the :keyword:`finally` clause will +always be the last one executed:: + + >>> def foo(): + ... try: + ... return 'try' + ... finally: + ... return 'finally' + ... + >>> foo() + 'finally' + Additional information on exceptions can be found in section :ref:`exceptions`, and information on using the :keyword:`raise` statement to generate exceptions may be found in section :ref:`raise`. @@ -348,7 +370,9 @@ may be found in section :ref:`raise`. The :keyword:`with` statement ============================= -.. index:: statement: with +.. index:: + statement: with + single: as; with statement The :keyword:`with` statement is used to wrap the execution of a block with methods defined by a context manager (see section :ref:`context-managers`). @@ -445,7 +469,7 @@ A function definition defines a user-defined function object (see section decorator: "@" `dotted_name` ["(" [`parameter_list` [","]] ")"] NEWLINE dotted_name: `identifier` ("." `identifier`)* parameter_list: (`defparameter` ",")* - : ( "*" [`parameter`] ("," `defparameter`)* ["," "**" `parameter`] + : | "*" [`parameter`] ("," `defparameter`)* ["," "**" `parameter`] : | "**" `parameter` : | `defparameter` [","] ) parameter: `identifier` [":" `expression`] diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index 0e936c68c02a..5e909a99547d 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -77,7 +77,7 @@ are still reachable. module for information on controlling the collection of cyclic garbage. Other implementations act differently and CPython may change. Do not depend on immediate finalization of objects when they become - unreachable (ex: always close files). + unreachable (so you should always close files explicitly). Note that the use of the implementation's tracing or debugging facilities may keep objects alive that would normally be collectable. Also note that catching @@ -154,11 +154,16 @@ NotImplemented This type has a single value. There is a single object with this value. This object is accessed through the built-in name ``NotImplemented``. Numeric methods - and rich comparison methods may return this value if they do not implement the + and rich comparison methods should return this value if they do not implement the operation for the operands provided. (The interpreter will then try the reflected operation, or some other fallback, depending on the operator.) Its truth value is true. + See + :ref:`implementing-the-arithmetic-operations` + for more details. + + Ellipsis .. index:: object: Ellipsis @@ -222,7 +227,7 @@ Ellipsis at the mercy of the underlying machine architecture (and C or Java implementation) for the accepted range and handling of overflow. Python does not support single-precision floating point numbers; the savings in processor and - memory usage that are usually the reason for using these is dwarfed by the + memory usage that are usually the reason for using these are dwarfed by the overhead of using objects in Python, so there is no reason to complicate the language with two kinds of floating point numbers. @@ -285,16 +290,17 @@ Sequences single: integer single: Unicode - A string is a sequence of values that represent Unicode codepoints. - All the codepoints in range ``U+0000 - U+10FFFF`` can be represented - in a string. Python doesn't have a :c:type:`chr` type, and - every character in the string is represented as a string object - with length ``1``. The built-in function :func:`ord` converts a - character to its codepoint (as an integer); :func:`chr` converts - an integer in range ``0 - 10FFFF`` to the corresponding character. + A string is a sequence of values that represent Unicode code points. + All the code points in the range ``U+0000 - U+10FFFF`` can be + represented in a string. Python doesn't have a :c:type:`char` type; + instead, every code point in the string is represented as a string + object with length ``1``. The built-in function :func:`ord` + converts a code point from its string form to an integer in the + range ``0 - 10FFFF``; :func:`chr` converts an integer in the range + ``0 - 10FFFF`` to the corresponding length ``1`` string object. :meth:`str.encode` can be used to convert a :class:`str` to - :class:`bytes` using the given encoding, and :meth:`bytes.decode` can - be used to achieve the opposite. + :class:`bytes` using the given text encoding, and + :meth:`bytes.decode` can be used to achieve the opposite. Tuples .. index:: @@ -323,8 +329,6 @@ Sequences object: mutable sequence object: mutable pair: assignment; statement - single: delete - statement: del single: subscription single: slicing @@ -455,7 +459,8 @@ Callable types +=========================+===============================+===========+ | :attr:`__doc__` | The function's documentation | Writable | | | string, or ``None`` if | | - | | unavailable | | + | | unavailable; not inherited by | | + | | subclasses | | +-------------------------+-------------------------------+-----------+ | :attr:`__name__` | The function's name | Writable | +-------------------------+-------------------------------+-----------+ @@ -495,7 +500,7 @@ Callable types | :attr:`__annotations__` | A dict containing annotations | Writable | | | of parameters. The keys of | | | | the dict are the parameter | | - | | names, or ``'return'`` for | | + | | names, and ``'return'`` for | | | | the return annotation, if | | | | provided. | | +-------------------------+-------------------------------+-----------+ @@ -709,7 +714,7 @@ Custom classes where there are multiple inheritance paths leading back to a common ancestor. Additional details on the C3 MRO used by Python can be found in the documentation accompanying the 2.3 release at - http://www.python.org/download/releases/2.3/mro/. + https://www.python.org/download/releases/2.3/mro/. .. XXX: Could we add that MRO doc as an appendix to the language ref? @@ -1095,13 +1100,17 @@ Basic customization .. index:: pair: class; constructor - Called when the instance is created. The arguments are those passed to the - class constructor expression. If a base class has an :meth:`__init__` method, - the derived class's :meth:`__init__` method, if any, must explicitly call it to - ensure proper initialization of the base class part of the instance; for - example: ``BaseClass.__init__(self, [args...])``. As a special constraint on - constructors, no value may be returned; doing so will cause a :exc:`TypeError` - to be raised at runtime. + Called after the instance has been created (by :meth:`__new__`), but before + it is returned to the caller. The arguments are those passed to the + class constructor expression. If a base class has an :meth:`__init__` + method, the derived class's :meth:`__init__` method, if any, must explicitly + call it to ensure proper initialization of the base class part of the + instance; for example: ``BaseClass.__init__(self, [args...])``. + + Because :meth:`__new__` and :meth:`__init__` work together in constructing + objects (:meth:`__new__` to create it, and :meth:`__init__` to customise it), + no non-``None`` value may be returned by :meth:`__init__`; doing so will + cause a :exc:`TypeError` to be raised at runtime. .. method:: object.__del__(self) @@ -1133,8 +1142,10 @@ Basic customization reference to the object on the stack frame that raised an unhandled exception in interactive mode (the traceback stored in ``sys.last_traceback`` keeps the stack frame alive). The first situation - can only be remedied by explicitly breaking the cycles; the latter two - situations can be resolved by storing ``None`` in ``sys.last_traceback``. + can only be remedied by explicitly breaking the cycles; the second can be + resolved by freeing the reference to the traceback object when it is no + longer useful, and the third can be resolved by storing ``None`` in + ``sys.last_traceback``. Circular references which are garbage are detected and cleaned up when the cyclic garbage collector is enabled (it's on by default). Refer to the documentation for the :mod:`gc` module for more information about this @@ -1226,6 +1237,10 @@ Basic customization The return value must be a string object. + .. versionchanged:: 3.4 + The __format__ method of ``object`` itself raises a :exc:`TypeError` + if passed any non-empty string. + .. _richcmpfuncs: .. method:: object.__lt__(self, other) @@ -1463,6 +1478,14 @@ class' :attr:`__dict__`. Called to delete the attribute on an instance *instance* of the owner class. +The attribute :attr:`__objclass__` is interpreted by the :mod:`inspect` module +as specifying the class where this object was defined (setting this +appropriately can assist in runtime introspection of dynamic class attributes). +For callables, it may indicate that an instance of the given type (or a +subclass) is expected or required as the first positional argument (for example, +CPython sets this attribute for unbound methods that are implemented in C). + + .. _descriptor-invocation: Invoking Descriptors @@ -1544,9 +1567,9 @@ saved because *__dict__* is not created for each instance. .. data:: object.__slots__ This class variable can be assigned a string, iterable, or sequence of - strings with variable names used by instances. If defined in a - class, *__slots__* reserves space for the declared variables and prevents the - automatic creation of *__dict__* and *__weakref__* for each instance. + strings with variable names used by instances. *__slots__* reserves space + for the declared variables and prevents the automatic creation of *__dict__* + and *__weakref__* for each instance. Notes on using *__slots__* @@ -1583,7 +1606,7 @@ Notes on using *__slots__* program undefined. In the future, a check may be added to prevent this. * Nonempty *__slots__* does not work for classes derived from "variable-length" - built-in types such as :class:`int`, :class:`str` and :class:`tuple`. + built-in types such as :class:`int`, :class:`bytes` and :class:`tuple`. * Any non-string iterable may be assigned to *__slots__*. Mappings may also be used; however, in the future, special meaning may be assigned to the values @@ -1643,6 +1666,8 @@ of these candidate metaclasses. If none of the candidate metaclasses meets that criterion, then the class definition will fail with ``TypeError``. +.. _prepare: + Preparing the class namespace ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -1710,7 +1735,7 @@ property creation, proxies, frameworks, and automatic resource locking/synchronization. Here is an example of a metaclass that uses an :class:`collections.OrderedDict` -to remember the order that class members were defined:: +to remember the order that class variables are defined:: class OrderedClass(type): @@ -1883,6 +1908,12 @@ through the container; for mappings, :meth:`__iter__` should be the same as indexes to allow proper detection of the end of the sequence. +.. method:: object.__missing__(self, key) + + Called by :class:`dict`\ .\ :meth:`__getitem__` to implement ``self[key]`` for dict subclasses + when key is not in the dictionary. + + .. method:: object.__setitem__(self, key, value) Called to implement assignment to ``self[key]``. Same note as for @@ -1905,8 +1936,7 @@ through the container; for mappings, :meth:`__iter__` should be the same as This method is called when an iterator is required for a container. This method should return a new iterator object that can iterate over all the objects in the - container. For mappings, it should iterate over the keys of the container, and - should also be made available as the method :meth:`keys`. + container. For mappings, it should iterate over the keys of the container. Iterator objects also need to implement this method; they are required to return themselves. For more information on iterator objects, see :ref:`typeiter`. @@ -1956,6 +1986,7 @@ left undefined. .. method:: object.__add__(self, other) object.__sub__(self, other) object.__mul__(self, other) + object.__matmul__(self, other) object.__truediv__(self, other) object.__floordiv__(self, other) object.__mod__(self, other) @@ -1972,15 +2003,16 @@ left undefined. builtin: pow builtin: pow - These methods are called to implement the binary arithmetic operations (``+``, - ``-``, ``*``, ``/``, ``//``, ``%``, :func:`divmod`, :func:`pow`, ``**``, ``<<``, - ``>>``, ``&``, ``^``, ``|``). For instance, to evaluate the expression - ``x + y``, where *x* is an instance of a class that has an :meth:`__add__` - method, ``x.__add__(y)`` is called. The :meth:`__divmod__` method should be the - equivalent to using :meth:`__floordiv__` and :meth:`__mod__`; it should not be - related to :meth:`__truediv__`. Note that :meth:`__pow__` should be defined - to accept an optional third argument if the ternary version of the built-in - :func:`pow` function is to be supported. + These methods are called to implement the binary arithmetic operations + (``+``, ``-``, ``*``, ``@``, ``/``, ``//``, ``%``, :func:`divmod`, + :func:`pow`, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``). For instance, to + evaluate the expression ``x + y``, where *x* is an instance of a class that + has an :meth:`__add__` method, ``x.__add__(y)`` is called. The + :meth:`__divmod__` method should be the equivalent to using + :meth:`__floordiv__` and :meth:`__mod__`; it should not be related to + :meth:`__truediv__`. Note that :meth:`__pow__` should be defined to accept + an optional third argument if the ternary version of the built-in :func:`pow` + function is to be supported. If one of those methods does not support the operation with the supplied arguments, it should return ``NotImplemented``. @@ -1989,6 +2021,7 @@ left undefined. .. method:: object.__radd__(self, other) object.__rsub__(self, other) object.__rmul__(self, other) + object.__rmatmul__(self, other) object.__rtruediv__(self, other) object.__rfloordiv__(self, other) object.__rmod__(self, other) @@ -2004,14 +2037,14 @@ left undefined. builtin: divmod builtin: pow - These methods are called to implement the binary arithmetic operations (``+``, - ``-``, ``*``, ``/``, ``//``, ``%``, :func:`divmod`, :func:`pow`, ``**``, - ``<<``, ``>>``, ``&``, ``^``, ``|``) with reflected (swapped) operands. - These functions are only called if the left operand does not support the - corresponding operation and the operands are of different types. [#]_ For - instance, to evaluate the expression ``x - y``, where *y* is an instance of - a class that has an :meth:`__rsub__` method, ``y.__rsub__(x)`` is called if - ``x.__sub__(y)`` returns *NotImplemented*. + These methods are called to implement the binary arithmetic operations + (``+``, ``-``, ``*``, ``@``, ``/``, ``//``, ``%``, :func:`divmod`, + :func:`pow`, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``) with reflected + (swapped) operands. These functions are only called if the left operand does + not support the corresponding operation and the operands are of different + types. [#]_ For instance, to evaluate the expression ``x - y``, where *y* is + an instance of a class that has an :meth:`__rsub__` method, ``y.__rsub__(x)`` + is called if ``x.__sub__(y)`` returns *NotImplemented*. .. index:: builtin: pow @@ -2029,6 +2062,7 @@ left undefined. .. method:: object.__iadd__(self, other) object.__isub__(self, other) object.__imul__(self, other) + object.__imatmul__(self, other) object.__itruediv__(self, other) object.__ifloordiv__(self, other) object.__imod__(self, other) @@ -2040,15 +2074,17 @@ left undefined. object.__ior__(self, other) These methods are called to implement the augmented arithmetic assignments - (``+=``, ``-=``, ``*=``, ``/=``, ``//=``, ``%=``, ``**=``, ``<<=``, ``>>=``, - ``&=``, ``^=``, ``|=``). These methods should attempt to do the operation - in-place (modifying *self*) and return the result (which could be, but does - not have to be, *self*). If a specific method is not defined, the augmented - assignment falls back to the normal methods. For instance, to execute the - statement ``x += y``, where *x* is an instance of a class that has an - :meth:`__iadd__` method, ``x.__iadd__(y)`` is called. If *x* is an instance - of a class that does not define a :meth:`__iadd__` method, ``x.__add__(y)`` - and ``y.__radd__(x)`` are considered, as with the evaluation of ``x + y``. + (``+=``, ``-=``, ``*=``, ``@=``, ``/=``, ``//=``, ``%=``, ``**=``, ``<<=``, + ``>>=``, ``&=``, ``^=``, ``|=``). These methods should attempt to do the + operation in-place (modifying *self*) and return the result (which could be, + but does not have to be, *self*). If a specific method is not defined, the + augmented assignment falls back to the normal methods. For instance, if *x* + is an instance of a class with an :meth:`__iadd__` method, ``x += y`` is + equivalent to ``x = x.__iadd__(y)`` . Otherwise, ``x.__add__(y)`` and + ``y.__radd__(x)`` are considered, as with the evaluation of ``x + y``. In + certain situations, augmented assignment can result in unexpected errors (see + :ref:`faq-augmented-assignment-tuple-error`), but this behavior is in fact + part of the data model. .. method:: object.__neg__(self) @@ -2080,9 +2116,17 @@ left undefined. .. method:: object.__index__(self) - Called to implement :func:`operator.index`. Also called whenever Python needs - an integer object (such as in slicing, or in the built-in :func:`bin`, - :func:`hex` and :func:`oct` functions). Must return an integer. + Called to implement :func:`operator.index`, and whenever Python needs to + losslessly convert the numeric object to an integer object (such as in + slicing, or in the built-in :func:`bin`, :func:`hex` and :func:`oct` + functions). Presence of this method indicates that the numeric object is + an integer type. Must return an integer. + + .. note:: + + In order to have a coherent integer type class, when :meth:`__index__` is + defined :meth:`__int__` should also be defined, and both should return + the same value. .. _context-managers: diff --git a/Doc/reference/executionmodel.rst b/Doc/reference/executionmodel.rst index 82e37a21fab5..a3948e3d9872 100644 --- a/Doc/reference/executionmodel.rst +++ b/Doc/reference/executionmodel.rst @@ -31,11 +31,11 @@ that name established in the innermost function block containing the use. A :dfn:`block` is a piece of Python program text that is executed as a unit. The following are blocks: a module, a function body, and a class definition. Each command typed interactively is a block. A script file (a file given as -standard input to the interpreter or specified on the interpreter command line -the first argument) is a code block. A script command (a command specified on -the interpreter command line with the '**-c**' option) is a code block. The -string argument passed to the built-in functions :func:`eval` and :func:`exec` -is a code block. +standard input to the interpreter or specified as a command line argument to the +interpreter) is a code block. A script command (a command specified on the +interpreter command line with the '**-c**' option) is a code block. The string +argument passed to the built-in functions :func:`eval` and :func:`exec` is a +code block. .. index:: pair: execution; frame @@ -77,7 +77,7 @@ global.) If a variable is used in a code block but not defined there, it is a single: UnboundLocalError When a name is not found at all, a :exc:`NameError` exception is raised. If the -name refers to a local variable that has not been bound, a +name refers to a local variable that has not been bound, an :exc:`UnboundLocalError` exception is raised. :exc:`UnboundLocalError` is a subclass of :exc:`NameError`. @@ -111,8 +111,9 @@ specified in the statement refer to the binding of that name in the top-level namespace. Names are resolved in the top-level namespace by searching the global namespace, i.e. the namespace of the module containing the code block, and the builtins namespace, the namespace of the module :mod:`builtins`. The -global namespace is searched first. If the name is not found there, the builtins -namespace is searched. The global statement must precede all uses of the name. +global namespace is searched first. If the name is not found there, the +builtins namespace is searched. The :keyword:`global` statement must precede +all uses of the name. .. XXX document "nonlocal" semantics here diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst index 66358c877db4..12f9f2f48575 100644 --- a/Doc/reference/expressions.rst +++ b/Doc/reference/expressions.rst @@ -29,7 +29,7 @@ Arithmetic conversions When a description of an arithmetic operator below uses the phrase "the numeric arguments are converted to a common type," this means that the operator -implementation for built-in types works that way: +implementation for built-in types works as follows: * If either argument is a complex number, the other is converted to complex; @@ -38,8 +38,9 @@ implementation for built-in types works that way: * otherwise, both must be integers and no conversion is necessary. -Some additional rules apply for certain operators (e.g., a string left argument -to the '%' operator). Extensions must define their own conversion behavior. +Some additional rules apply for certain operators (e.g., a string as a left +argument to the '%' operator). Extensions must define their own conversion +behavior. .. _atoms: @@ -183,7 +184,7 @@ nesting from left to right, and evaluating the expression to produce an element each time the innermost block is reached. Note that the comprehension is executed in a separate scope, so names assigned -to in the target list don't "leak" in the enclosing scope. +to in the target list don't "leak" into the enclosing scope. .. _lists: @@ -293,7 +294,7 @@ for comprehensions, except that it is enclosed in parentheses instead of brackets or curly braces. Variables used in the generator expression are evaluated lazily when the -:meth:`~generator.__next__` method is called for generator object (in the same +:meth:`~generator.__next__` method is called for the generator object (in the same fashion as normal generators). However, the leftmost :keyword:`for` clause is immediately evaluated, so that an error produced by it can be seen before any other possible error in the code that handles the generator expression. @@ -302,7 +303,7 @@ may depend on the previous :keyword:`for` loop. For example: ``(x*y for x in range(10) for y in bar(x))``. The parentheses can be omitted on calls with only one argument. See section -:ref:`calls` for the detail. +:ref:`calls` for details. .. _yieldexpr: @@ -319,41 +320,40 @@ Yield expressions yield_atom: "(" `yield_expression` ")" yield_expression: "yield" [`expression_list` | "from" `expression`] -The :keyword:`yield` expression is only used when defining a :term:`generator` -function, -and can only be used in the body of a function definition. Using a -:keyword:`yield` expression in a function definition is sufficient to cause that -definition to create a generator function instead of a normal function. +The yield expression is only used when defining a :term:`generator` function and +thus can only be used in the body of a function definition. Using a yield +expression in a function's body causes that function to be a generator. When a generator function is called, it returns an iterator known as a generator. That generator then controls the execution of a generator function. The execution starts when one of the generator's methods is called. At that -time, the execution proceeds to the first :keyword:`yield` expression, where it -is suspended again, returning the value of :token:`expression_list` to -generator's caller. By suspended we mean that all local state is retained, -including the current bindings of local variables, the instruction pointer, and -the internal evaluation stack. When the execution is resumed by calling one of -the generator's methods, the function can proceed exactly as if the -:keyword:`yield` expression was just another external call. The value of the -:keyword:`yield` expression after resuming depends on the method which resumed -the execution. If :meth:`~generator.__next__` is used (typically via either a -:keyword:`for` or the :func:`next` builtin) then the result is :const:`None`, -otherwise, if :meth:`~generator.send` is used, then the result will be the -value passed in to that method. +time, the execution proceeds to the first yield expression, where it is +suspended again, returning the value of :token:`expression_list` to the generator's +caller. By suspended, we mean that all local state is retained, including the +current bindings of local variables, the instruction pointer, the internal +evaluation stack, and the state of any exception handling. When the execution +is resumed by calling one of the +generator's methods, the function can proceed exactly as if the yield expression +were just another external call. The value of the yield expression after +resuming depends on the method which resumed the execution. If +:meth:`~generator.__next__` is used (typically via either a :keyword:`for` or +the :func:`next` builtin) then the result is :const:`None`. Otherwise, if +:meth:`~generator.send` is used, then the result will be the value passed in to +that method. .. index:: single: coroutine All of this makes generator functions quite similar to coroutines; they yield multiple times, they have more than one entry point and their execution can be suspended. The only difference is that a generator function cannot control -where should the execution continue after it yields; the control is always +where the execution should continue after it yields; the control is always transferred to the generator's caller. -:keyword:`yield` expressions are allowed in the :keyword:`try` clause of a -:keyword:`try` ... :keyword:`finally` construct. If the generator is not -resumed before it is finalized (by reaching a zero reference count or by being -garbage collected), the generator-iterator's :meth:`~generator.close` method -will be called, allowing any pending :keyword:`finally` clauses to execute. +Yield expressions are allowed anywhere in a :keyword:`try` construct. If the +generator is not resumed before it is +finalized (by reaching a zero reference count or by being garbage collected), +the generator-iterator's :meth:`~generator.close` method will be called, +allowing any pending :keyword:`finally` clauses to execute. When ``yield from <expr>`` is used, it treats the supplied expression as a subiterator. All values produced by that subiterator are passed directly @@ -373,11 +373,23 @@ the yield expression. It can be either set explicitly when raising .. versionchanged:: 3.3 Added ``yield from <expr>`` to delegate control flow to a subiterator -The parentheses can be omitted when the :keyword:`yield` expression is the -sole expression on the right hand side of an assignment statement. +The parentheses may be omitted when the yield expression is the sole expression +on the right hand side of an assignment statement. -.. index:: object: generator +.. seealso:: + :pep:`0255` - Simple Generators + The proposal for adding generators and the :keyword:`yield` statement to Python. + + :pep:`0342` - Coroutines via Enhanced Generators + The proposal to enhance the API and syntax of generators, making them + usable as simple coroutines. + + :pep:`0380` - Syntax for Delegating to a Subgenerator + The proposal to introduce the :token:`yield_from` syntax, making delegation + to sub-generators easy. + +.. index:: object: generator Generator-iterator methods ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -389,19 +401,17 @@ Note that calling any of the generator methods below when the generator is already executing raises a :exc:`ValueError` exception. .. index:: exception: StopIteration -.. class:: generator .. method:: generator.__next__() Starts the execution of a generator function or resumes it at the last - executed :keyword:`yield` expression. When a generator function is resumed - with a :meth:`~generator.__next__` method, the current :keyword:`yield` - expression always evaluates to :const:`None`. The execution then continues - to the next :keyword:`yield` expression, where the generator is suspended - again, and the value of the :token:`expression_list` is returned to - :meth:`next`'s caller. - If the generator exits without yielding another value, a :exc:`StopIteration` + executed yield expression. When a generator function is resumed with a + :meth:`~generator.__next__` method, the current yield expression always + evaluates to :const:`None`. The execution then continues to the next yield + expression, where the generator is suspended again, and the value of the + :token:`expression_list` is returned to :meth:`__next__`'s caller. If the + generator exits without yielding another value, a :exc:`StopIteration` exception is raised. This method is normally called implicitly, e.g. by a :keyword:`for` loop, or @@ -411,17 +421,17 @@ is already executing raises a :exc:`ValueError` exception. .. method:: generator.send(value) Resumes the execution and "sends" a value into the generator function. The - ``value`` argument becomes the result of the current :keyword:`yield` - expression. The :meth:`send` method returns the next value yielded by the - generator, or raises :exc:`StopIteration` if the generator exits without - yielding another value. When :meth:`send` is called to start the generator, - it must be called with :const:`None` as the argument, because there is no - :keyword:`yield` expression that could receive the value. + *value* argument becomes the result of the current yield expression. The + :meth:`send` method returns the next value yielded by the generator, or + raises :exc:`StopIteration` if the generator exits without yielding another + value. When :meth:`send` is called to start the generator, it must be called + with :const:`None` as the argument, because there is no yield expression that + could receive the value. .. method:: generator.throw(type[, value[, traceback]]) - Raises an exception of type ``type`` at the point where generator was paused, + Raises an exception of type ``type`` at the point where the generator was paused, and returns the next value yielded by the generator function. If the generator exits without yielding another value, a :exc:`StopIteration` exception is raised. If the generator function does not catch the passed-in exception, or @@ -440,8 +450,6 @@ is already executing raises a :exc:`ValueError` exception. other exception, it is propagated to the caller. :meth:`close` does nothing if the generator has already exited due to an exception or normal exit. -.. class:: . - .. index:: single: yield; examples Examples @@ -478,20 +486,6 @@ For examples using ``yield from``, see :ref:`pep-380` in "What's New in Python." -.. seealso:: - - :pep:`0255` - Simple Generators - The proposal for adding generators and the :keyword:`yield` statement to Python. - - :pep:`0342` - Coroutines via Enhanced Generators - The proposal to enhance the API and syntax of generators, making them - usable as simple coroutines. - - :pep:`0380` - Syntax for Delegating to a Subgenerator - The proposal to introduce the :token:`yield_from` syntax, making delegation - to sub-generators easy. - - .. _primaries: Primaries @@ -525,11 +519,11 @@ An attribute reference is a primary followed by a period and a name: The primary must evaluate to an object of a type that supports attribute references, which most objects do. This object is then asked to produce the -attribute whose name is the identifier (which can be customized by overriding -the :meth:`__getattr__` method). If this attribute is not available, the -exception :exc:`AttributeError` is raised. Otherwise, the type and value of the -object produced is determined by the object. Multiple evaluations of the same -attribute reference may yield different objects. +attribute whose name is the identifier. This production can be customized by +overriding the :meth:`__getattr__` method. If this attribute is not available, +the exception :exc:`AttributeError` is raised. Otherwise, the type and value of +the object produced is determined by the object. Multiple evaluations of the +same attribute reference may yield different objects. .. _subscriptions: @@ -554,9 +548,9 @@ A subscription selects an item of a sequence (string, tuple or list) or mapping .. productionlist:: subscription: `primary` "[" `expression_list` "]" -The primary must evaluate to an object that supports subscription, e.g. a list -or dictionary. User-defined objects can support subscription by defining a -:meth:`__getitem__` method. +The primary must evaluate to an object that supports subscription (lists or +dictionaries for example). User-defined objects can support subscription by +defining a :meth:`__getitem__` method. For built-in objects, there are two types of objects that support subscription: @@ -626,8 +620,8 @@ slice list contains no proper slice). single: stop (slice object attribute) single: step (slice object attribute) -The semantics for a slicing are as follows. The primary must evaluate to a -mapping object, and it is indexed (using the same :meth:`__getitem__` method as +The semantics for a slicing are as follows. The primary is indexed (using the +same :meth:`__getitem__` method as normal subscription) with a key that is constructed from the slice list, as follows. If the slice list contains at least one comma, the key is a tuple containing the conversion of the slice items; otherwise, the conversion of the @@ -665,8 +659,8 @@ series of :term:`arguments <argument>`: keyword_arguments: `keyword_item` ("," `keyword_item`)* keyword_item: `identifier` "=" `expression` -A trailing comma may be present after the positional and keyword arguments but -does not affect the semantics. +An optional trailing comma may be present after the positional and keyword arguments +but does not affect the semantics. .. index:: single: parameter; call semantics @@ -897,8 +891,9 @@ from the power operator, there are only two levels, one for multiplicative operators and one for additive operators: .. productionlist:: - m_expr: `u_expr` | `m_expr` "*" `u_expr` | `m_expr` "//" `u_expr` | `m_expr` "/" `u_expr` - : | `m_expr` "%" `u_expr` + m_expr: `u_expr` | `m_expr` "*" `u_expr` | `m_expr` "@" `m_expr` | + : `m_expr` "//" `u_expr`| `m_expr` "/" `u_expr` | + : `m_expr` "%" `u_expr` a_expr: `m_expr` | `a_expr` "+" `m_expr` | `a_expr` "-" `m_expr` .. index:: single: multiplication @@ -909,6 +904,13 @@ the other must be a sequence. In the former case, the numbers are converted to a common type and then multiplied together. In the latter case, sequence repetition is performed; a negative repetition factor yields an empty sequence. +.. index:: single: matrix multiplication + +The ``@`` (at) operator is intended to be used for matrix multiplication. No +builtin Python types implement this operator. + +.. versionadded:: 3.5 + .. index:: exception: ZeroDivisionError single: division @@ -948,9 +950,9 @@ point number using the :func:`abs` function if appropriate. .. index:: single: addition The ``+`` (addition) operator yields the sum of its arguments. The arguments -must either both be numbers or both sequences of the same type. In the former -case, the numbers are converted to a common type and then added together. In -the latter case, the sequences are concatenated. +must either both be numbers or both be sequences of the same type. In the +former case, the numbers are converted to a common type and then added together. +In the latter case, the sequences are concatenated. .. index:: single: subtraction @@ -1073,7 +1075,7 @@ Comparison of objects of the same type depends on the type: * Numbers are compared arithmetically. * The values :const:`float('NaN')` and :const:`Decimal('NaN')` are special. - The are identical to themselves, ``x is x`` but are not equal to themselves, + They are identical to themselves, ``x is x`` but are not equal to themselves, ``x != x``. Additionally, comparing any value to a not-a-number value will return ``False``. For example, both ``3 < float('NaN')`` and ``float('NaN') < 3`` will return ``False``. @@ -1111,7 +1113,7 @@ Comparison of objects of the same type depends on the type: another one is made arbitrarily but consistently within one execution of a program. -Comparison of objects of the differing types depends on whether either of the +Comparison of objects of differing types depends on whether either of the types provide explicit support for the comparison. Most numeric types can be compared with one another. When cross-type comparison is not supported, the comparison method returns ``NotImplemented``. @@ -1121,7 +1123,7 @@ comparison method returns ``NotImplemented``. The operators :keyword:`in` and :keyword:`not in` test for membership. ``x in s`` evaluates to true if *x* is a member of *s*, and false otherwise. ``x not in s`` returns the negation of ``x in s``. All built-in sequences and set types -support this as well as dictionary, for which :keyword:`in` tests whether a the +support this as well as dictionary, for which :keyword:`in` tests whether the dictionary has a given key. For container types such as list, tuple, set, frozenset, dict, or collections.deque, the expression ``x in y`` is equivalent to ``any(x is e or x == e for e in y)``. @@ -1207,9 +1209,9 @@ returned; otherwise, *y* is evaluated and the resulting value is returned. they return to ``False`` and ``True``, but rather return the last evaluated argument. This is sometimes useful, e.g., if ``s`` is a string that should be replaced by a default value if it is empty, the expression ``s or 'foo'`` yields -the desired value. Because :keyword:`not` has to invent a value anyway, it does -not bother to return a value of the same type as its argument, so e.g., ``not -'foo'`` yields ``False``, not ``''``.) +the desired value. Because :keyword:`not` has to create a new value, it +returns a boolean value regardless of the type of its argument +(for example, ``not 'foo'`` produces ``False`` rather than ``''``.) Conditional expressions @@ -1227,8 +1229,8 @@ Conditional expressions Conditional expressions (sometimes called a "ternary operator") have the lowest priority of all Python operations. -The expression ``x if C else y`` first evaluates the condition, *C* (*not* *x*); -if *C* is true, *x* is evaluated and its value is returned; otherwise, *y* is +The expression ``x if C else y`` first evaluates the condition, *C* rather than *x*. +If *C* is true, *x* is evaluated and its value is returned; otherwise, *y* is evaluated and its value is returned. See :pep:`308` for more details about conditional expressions. @@ -1249,10 +1251,9 @@ Lambdas lambda_expr: "lambda" [`parameter_list`]: `expression` lambda_expr_nocond: "lambda" [`parameter_list`]: `expression_nocond` -Lambda expressions (sometimes called lambda forms) have the same syntactic position as -expressions. They are a shorthand to create anonymous functions; the expression -``lambda arguments: expression`` yields a function object. The unnamed object -behaves like a function object defined with :: +Lambda expressions (sometimes called lambda forms) are used to create anonymous +functions. The expression ``lambda arguments: expression`` yields a function +object. The unnamed object behaves like a function object defined with :: def <lambda>(arguments): return expression @@ -1315,13 +1316,15 @@ Operator precedence .. index:: pair: operator; precedence -The following table summarizes the operator precedences in Python, from lowest +The following table summarizes the operator precedence in Python, from lowest precedence (least binding) to highest precedence (most binding). Operators in the same box have the same precedence. Unless the syntax is explicitly given, operators are binary. Operators in the same box group left to right (except for -comparisons, including tests, which all have the same precedence and chain from -left to right --- see section :ref:`comparisons` --- and exponentiation, which -groups from right to left). +exponentiation, which groups from right to left). + +Note that comparisons, membership tests, and identity tests, all have the same +precedence and have a left-to-right chaining feature as described in the +:ref:`comparisons` section. +-----------------------------------------------+-------------------------------------+ @@ -1351,8 +1354,9 @@ groups from right to left). +-----------------------------------------------+-------------------------------------+ | ``+``, ``-`` | Addition and subtraction | +-----------------------------------------------+-------------------------------------+ -| ``*``, ``/``, ``//``, ``%`` | Multiplication, division, remainder | -| | [#]_ | +| ``*``, ``@``, ``/``, ``//``, ``%`` | Multiplication, matrix | +| | multiplication division, | +| | remainder [#]_ | +-----------------------------------------------+-------------------------------------+ | ``+x``, ``-x``, ``~x`` | Positive, negative, bitwise NOT | +-----------------------------------------------+-------------------------------------+ diff --git a/Doc/reference/import.rst b/Doc/reference/import.rst index be79b99ffc13..2d60e62f2b05 100644 --- a/Doc/reference/import.rst +++ b/Doc/reference/import.rst @@ -281,9 +281,10 @@ When the named module is not found in :data:`sys.modules`, Python next searches :data:`sys.meta_path`, which contains a list of meta path finder objects. These finders are queried in order to see if they know how to handle the named module. Meta path finders must implement a method called -:meth:`find_spec()` which takes two arguments, a name and an import path. -The meta path finder can use any strategy it wants to determine whether it can -handle the named module or not. +:meth:`~importlib.abc.MetaPathFinder.find_spec()` which takes three arguments: +a name, an import path, and (optionally) a target module. The meta path +finder can use any strategy it wants to determine whether it can handle +the named module or not. If the meta path finder knows how to handle the named module, it returns a spec object. If it cannot handle the named module, it returns ``None``. If @@ -291,24 +292,26 @@ spec object. If it cannot handle the named module, it returns ``None``. If a spec, then an :exc:`ImportError` is raised. Any other exceptions raised are simply propagated up, aborting the import process. -The :meth:`find_spec()` method of meta path finders is called with two -arguments. The first is the fully qualified name of the module being -imported, for example ``foo.bar.baz``. The second argument is the path -entries to use for the module search. For top-level modules, the second -argument is ``None``, but for submodules or subpackages, the second -argument is the value of the parent package's ``__path__`` attribute. If -the appropriate ``__path__`` attribute cannot be accessed, an -:exc:`ImportError` is raised. +The :meth:`~importlib.abc.MetaPathFinder.find_spec()` method of meta path +finders is called with two or three arguments. The first is the fully +qualified name of the module being imported, for example ``foo.bar.baz``. +The second argument is the path entries to use for the module search. For +top-level modules, the second argument is ``None``, but for submodules or +subpackages, the second argument is the value of the parent package's +``__path__`` attribute. If the appropriate ``__path__`` attribute cannot +be accessed, an :exc:`ImportError` is raised. The third argument is an +existing module object that will be the target of loading later. The +import system passes in a target module only during reload. The meta path may be traversed multiple times for a single import request. For example, assuming none of the modules involved has already been cached, importing ``foo.bar.baz`` will first perform a top level import, calling -``mpf.find_spec("foo", None)`` on each meta path finder (``mpf``). After +``mpf.find_spec("foo", None, None)`` on each meta path finder (``mpf``). After ``foo`` has been imported, ``foo.bar`` will be imported by traversing the meta path a second time, calling -``mpf.find_spec("foo.bar", foo.__path__)``. Once ``foo.bar`` has been +``mpf.find_spec("foo.bar", foo.__path__, None)``. Once ``foo.bar`` has been imported, the final traversal will call -``mpf.find_spec("foo.bar.baz", foo.bar.__path__)``. +``mpf.find_spec("foo.bar.baz", foo.bar.__path__, None)``. Some meta path finders only support top level imports. These importers will always return ``None`` when anything other than ``None`` is passed as the @@ -320,10 +323,11 @@ modules, and one that knows how to import modules from an :term:`import path` (i.e. the :term:`path based finder`). .. versionchanged:: 3.4 - The find_spec() method of meta path finders replaced :meth:`find_module()`. - which is now deprecated. While it will continue to work without change, - the import machinery will try it only if the finder does not implement - find_spec(). + The :meth:`~importlib.abc.MetaPathFinder.find_spec` method of meta path + finders replaced :meth:`~importlib.abc.MetaPathFinder.find_module`, which + is now deprecated. While it will continue to work without change, the + import machinery will try it only if the finder does not implement + ``find_spec()``. Loading @@ -335,6 +339,7 @@ of what happens during the loading portion of import:: module = None if spec.loader is not None and hasattr(spec.loader, 'create_module'): + # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module(spec) if module is None: module = ModuleType(spec.name) @@ -350,6 +355,7 @@ of what happens during the loading portion of import:: raise ImportError elif not hasattr(spec.loader, 'exec_module'): module = spec.loader.load_module(spec.name) + # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: @@ -360,7 +366,7 @@ of what happens during the loading portion of import:: except KeyError: pass raise - module_to_return = sys.modules[spec.name] + return sys.modules[spec.name] Note the following details: @@ -380,8 +386,9 @@ Note the following details: reloading where even the failing module is left in :data:`sys.modules`. * After the module is created but before execution, the import machinery - sets the import-related module attributes ("init_module_attrs"), as - summarized in a :ref:`later section <import-mod-attrs>`. + sets the import-related module attributes ("_init_module_attrs" in + the pseudo-code example above), as summarized in a + :ref:`later section <import-mod-attrs>`. * Module execution is the key moment of loading in which the module's namespace gets populated. Execution is entirely delegated to the @@ -392,16 +399,16 @@ Note the following details: .. versionchanged:: 3.4 The import system has taken over the boilerplate responsibilities of - loaders. These were previously performed by the :meth:`load_module()` - method. + loaders. These were previously performed by the + :meth:`importlib.abc.Loader.load_module` method. Loaders ------- Module loaders provide the critical function of loading: module execution. -The import machinery calls the :meth:`~importlib.abc.Loader.exec_module()` +The import machinery calls the :meth:`importlib.abc.Loader.exec_module` method with a single argument, the module object to execute. Any value -returned from exec_module() is ignored. +returned from :meth:`~importlib.abc.Loader.exec_module` is ignored. Loaders must satisfy the following requirements: @@ -409,41 +416,41 @@ Loaders must satisfy the following requirements: dynamically loaded extension), the loader should execute the module's code in the module's global name space (``module.__dict__``). - * If loader cannot execute the module, it should raise an + * If the loader cannot execute the module, it should raise an :exc:`ImportError`, although any other exception raised during - :meth:`exec_module()` will be propagated. + :meth:`~importlib.abc.Loader.exec_module` will be propagated. In many cases, the finder and loader can be the same object; in such cases the -:meth:`finder.find_spec()` would just return a spec with the loader set -to ``self``. +:meth:`~importlib.abc.MetaPathFinder.find_spec` method would just return a +spec with the loader set to ``self``. Module loaders may opt in to creating the module object during loading -by implementing a :meth:`create_module()` method. It takes one argument, -the module spec, and returns the new module object to use during loading. -create_module() does not need to set any attributes on the module object. -If the loader does not define create_module(), the import machinery will -create the new module itself. +by implementing a :meth:`~importlib.abc.Loader.create_module` method. +It takes one argument, the module spec, and returns the new module object +to use during loading. ``create_module()`` does not need to set any attributes +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. .. versionchanged:: 3.4 - The load_module() method was replaced by exec_module() and the import + The :meth:`~importlib.abc.Loader.load_module` method was replaced by + :meth:`~importlib.abc.Loader.exec_module` and the import machinery assumed all the boilerplate responsibilities of loading. For compatibility with existing loaders, the import machinery will use - the :meth:`~importlib.abc.Loader.load_module()` method of loaders if it - exists and the loader does not also implement exec_module(). However, - load_module() has been deprecated and loaders should implement - exec_module() instead. + the ``load_module()`` method of loaders if it exists and the loader does + not also implement ``exec_module()``. However, ``load_module()`` has been + deprecated and loaders should implement ``exec_module()`` instead. - The load_module() method must implement all the boilerplate loading + The ``load_module()`` method must implement all the boilerplate loading functionality described above in addition to executing the module. All the same constraints apply, with some additional clarification: * If there is an existing module object with the given name in :data:`sys.modules`, the loader must use that existing module. - (Otherwise, :func:`imp.reload` will not work correctly.) If the + (Otherwise, :func:`importlib.reload` will not work correctly.) If the named module does not exist in :data:`sys.modules`, the loader must create a new module object and add it to :data:`sys.modules`. @@ -453,7 +460,13 @@ create the new module itself. * If loading fails, the loader must remove any modules it has inserted into :data:`sys.modules`, but it must remove **only** the failing - module, and only if the loader itself has loaded it explicitly. + module(s), and only if the loader itself has loaded the module(s) + explicitly. + +.. 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. Module spec ----------- @@ -513,7 +526,12 @@ the module. The ``__spec__`` attribute must be set to the module spec that was used when importing the module. This is used primarily for - introspection and during reloading. + introspection and during reloading. Setting ``__spec__`` + appropriately applies equally to :ref:`modules initialized during + interpreter startup <programs>`. The one exception is ``__main__``, + where ``__spec__`` is :ref:`set to None in some cases <main_spec>`. + + .. versionadded:: 3.4 .. attribute:: __path__ @@ -600,13 +618,14 @@ Here are the exact rules used: * Otherwise, just use the module's ``__name__`` in the repr. .. versionchanged:: 3.4 - Use of loader.module_repr() has been deprecated and the module spec - is now used by the import machinery to generate a module repr. + Use of :meth:`loader.module_repr() <importlib.abc.Loader.module_repr>` + has been deprecated and the module spec is now used by the import + machinery to generate a module repr. For backward compatibility with Python 3.3, the module repr will be - generated by calling the loader's :meth:`module_repr()` method, if - defined, before trying either approach described above. However, the - method is deprecated. + generated by calling the loader's + :meth:`~importlib.abc.Loader.module_repr` method, if defined, before + trying either approach described above. However, the method is deprecated. The Path Based Finder @@ -616,8 +635,9 @@ The Path Based Finder single: path based finder As mentioned previously, Python comes with several default meta path finders. -One of these, called the :term:`path based finder`, searches an :term:`import -path`, which contains a list of :term:`path entries <path entry>`. Each path +One of these, called the :term:`path based finder` +(:class:`~importlib.machinery.PathFinder`), searches an :term:`import path`, +which contains a list of :term:`path entries <path entry>`. Each path entry names a location to search for modules. The path based finder itself doesn't know how to import anything. Instead, it @@ -666,15 +686,15 @@ Path entry finders single: sys.path_importer_cache single: PYTHONPATH -The :term:`path based finder` is responsible for finding and loading Python -modules and packages whose location is specified with a string :term:`path -entry`. Most path entries name locations in the file system, but they need -not be limited to this. +The :term:`path based finder` is responsible for finding and loading +Python modules and packages whose location is specified with a string +:term:`path entry`. Most path entries name locations in the file system, +but they need not be limited to this. As a meta path finder, the :term:`path based finder` implements the -:meth:`find_spec()` protocol previously described, however it exposes -additional hooks that can be used to customize how modules are found and -loaded from the :term:`import path`. +:meth:`~importlib.abc.MetaPathFinder.find_spec` protocol previously +described, however it exposes additional hooks that can be used to +customize how modules are found and loaded from the :term:`import path`. Three variables are used by the :term:`path based finder`, :data:`sys.path`, :data:`sys.path_hooks` and :data:`sys.path_importer_cache`. The ``__path__`` @@ -694,14 +714,16 @@ finder>`. The :term:`path based finder` is a :term:`meta path finder`, so the import machinery begins the :term:`import path` search by calling the path -based finder's :meth:`find_spec()` method as described previously. When -the ``path`` argument to :meth:`find_spec()` is given, it will be a +based finder's :meth:`~importlib.machinery.PathFinder.find_spec` method as +described previously. When the ``path`` argument to +:meth:`~importlib.machinery.PathFinder.find_spec` is given, it will be a list of string paths to traverse - typically a package's ``__path__`` -attribute for an import within that package. If the ``path`` argument -is ``None``, this indicates a top level import and :data:`sys.path` is used. +attribute for an import within that package. If the ``path`` argument is +``None``, this indicates a top level import and :data:`sys.path` is used. The path based finder iterates over every entry in the search path, and -for each of these, looks for an appropriate :term:`path entry finder` for the +for each of these, looks for an appropriate :term:`path entry finder` +(:class:`~importlib.abc.PathEntryFinder`) for the path entry. Because this can be an expensive operation (e.g. there may be `stat()` call overheads for this search), the path based finder maintains a cache mapping path entries to path entry finders. This cache is maintained @@ -718,35 +740,46 @@ hooks <path entry hook>` in this list is called with a single argument, the path entry to be searched. This callable may either return a :term:`path entry finder` that can handle the path entry, or it may raise :exc:`ImportError`. An :exc:`ImportError` is used by the path based finder to -signal that the hook cannot find a :term:`path entry finder` for that -:term:`path entry`. The exception is ignored and :term:`import path` -iteration continues. The hook should expect either a string or bytes object; -the encoding of bytes objects is up to the hook (e.g. it may be a file system -encoding, UTF-8, or something else), and if the hook cannot decode the -argument, it should raise :exc:`ImportError`. +signal that the hook cannot find a :term:`path entry finder`. +for that :term:`path entry`. The +exception is ignored and :term:`import path` iteration continues. The hook +should expect either a string or bytes object; the encoding of bytes objects +is up to the hook (e.g. it may be a file system encoding, UTF-8, or something +else), and if the hook cannot decode the argument, it should raise +:exc:`ImportError`. If :data:`sys.path_hooks` iteration ends with no :term:`path entry finder` -being returned, then the path based finder's :meth:`find_spec()` method -will store ``None`` in :data:`sys.path_importer_cache` (to indicate that -there is no finder for this path entry) and return ``None``, indicating that -this :term:`meta path finder` could not find the module. +being returned, then the path based finder's +:meth:`~importlib.machinery.PathFinder.find_spec` method will store ``None`` +in :data:`sys.path_importer_cache` (to indicate that there is no finder for +this path entry) and return ``None``, indicating that this +:term:`meta path finder` could not find the module. If a :term:`path entry finder` *is* returned by one of the :term:`path entry hook` callables on :data:`sys.path_hooks`, then the following protocol is used to ask the finder for a module spec, which is then used when loading the module. +The current working directory -- denoted by an empty string -- is handled +slightly differently from other entries on :data:`sys.path`. First, if the +current working directory is found to not exist, no value is stored in +:data:`sys.path_importer_cache`. Second, the value for the current working +directory is looked up fresh for each module lookup. Third, the path used for +:data:`sys.path_importer_cache` and returned by +:meth:`importlib.machinery.PathFinder.find_spec` will be the actual current +working directory and not the empty string. + Path entry finder protocol -------------------------- In order to support imports of modules and initialized packages and also to contribute portions to namespace packages, path entry finders must implement -the :meth:`find_spec()` method. +the :meth:`~importlib.abc.PathEntryFinder.find_spec` method. -:meth:`find_spec()` takes one argument, the fully qualified name of the -module being imported. :meth:`find_spec()` returns a fully populated -spec for the module. This spec will always have "loader" set (with one -exception). +:meth:`~importlib.abc.PathEntryFinder.find_spec` takes two argument, the +fully qualified name of the module being imported, and the (optional) target +module. ``find_spec()`` returns a fully populated spec for the module. +This spec will always have "loader" set (with one exception). To indicate to the import machinery that the spec represents a namespace :term:`portion`. the path entry finder sets "loader" on the spec to @@ -754,42 +787,44 @@ To indicate to the import machinery that the spec represents a namespace portion. .. versionchanged:: 3.4 - find_spec() replaced find_loader() and find_module(), but of which - are now deprecated, but will be used if find_spec() is not defined. + :meth:`~importlib.abc.PathEntryFinder.find_spec` replaced + :meth:`~importlib.abc.PathEntryFinder.find_loader` and + :meth:`~importlib.abc.PathEntryFinder.find_module`, both of which + are now deprecated, but will be used if ``find_spec()`` is not defined. Older path entry finders may implement one of these two deprecated methods - instead of :meth:`find_spec()`. The methods are still respected for the - sake of backward compatibility. Howevever, if find_spec() is implemented - on the path entry finder, the legacy methods are ignored. - - :meth:`find_loader()` takes one argument, the fully qualified name of the - module being imported. :meth:`find_loader()` returns a 2-tuple where the - first item is the loader and the second item is a namespace :term:`portion`. - When the first item (i.e. the loader) is ``None``, this means that while the - path entry finder does not have a loader for the named module, it knows that - the path entry contributes to a namespace portion for the named module. - This will almost always be the case where Python is asked to import a - namespace package that has no physical presence on the file system. - When a path entry finder returns ``None`` for the loader, the second - item of the 2-tuple return value must be a sequence, although it can be - empty. - - If :meth:`find_loader()` returns a non-``None`` loader value, the portion is + instead of ``find_spec()``. The methods are still respected for the + sake of backward compatibility. Howevever, if ``find_spec()`` is + implemented on the path entry finder, the legacy methods are ignored. + + :meth:`~importlib.abc.PathEntryFinder.find_loader` takes one argument, the + fully qualified name of the module being imported. ``find_loader()`` + returns a 2-tuple where the first item is the loader and the second item + is a namespace :term:`portion`. When the first item (i.e. the loader) is + ``None``, this means that while the path entry finder does not have a + loader for the named module, it knows that the path entry contributes to + a namespace portion for the named module. This will almost always be the + case where Python is asked to import a namespace package that has no + physical presence on the file system. When a path entry finder returns + ``None`` for the loader, the second item of the 2-tuple return value must + be a sequence, although it can be empty. + + If ``find_loader()`` returns a non-``None`` loader value, the portion is ignored and the loader is returned from the path based finder, terminating the search through the path entries. For backwards compatibility with other implementations of the import protocol, many path entry finders also support the same, - traditional :meth:`find_module()` method that meta path finders support. - However path entry finder :meth:`find_module()` methods are never called + traditional ``find_module()`` method that meta path finders support. + However path entry finder ``find_module()`` methods are never called with a ``path`` argument (they are expected to record the appropriate path information from the initial call to the path hook). - The :meth:`find_module()` method on path entry finders is deprecated, + The ``find_module()`` method on path entry finders is deprecated, as it does not allow the path entry finder to contribute portions to - namespace packages. If both :meth:`find_loader()` and :meth:`find_module()` + namespace packages. If both ``find_loader()`` and ``find_module()`` exist on a path entry finder, the import system will always call - :meth:`find_loader()` in preference to :meth:`find_module()`. + ``find_loader()`` in preference to ``find_module()``. Replacing the standard import system @@ -808,9 +843,54 @@ import statements within that module. To selectively prevent import of some modules from a hook early on the meta path (rather than disabling the standard import system entirely), it is sufficient to raise :exc:`ImportError` directly from -:meth:`find_spec` instead of returning ``None``. The latter indicates -that the meta path search should continue. while raising an exception -terminates it immediately. +:meth:`~importlib.abc.MetaPathFinder.find_spec` instead of returning +``None``. The latter indicates that the meta path search should continue, +while raising an exception terminates it immediately. + + +Special considerations for __main__ +=================================== + +The :mod:`__main__` module is a special case relative to Python's import +system. As noted :ref:`elsewhere <programs>`, the ``__main__`` module +is directly initialized at interpreter startup, much like :mod:`sys` and +:mod:`builtins`. However, unlike those two, it doesn't strictly +qualify as a built-in module. This is because the manner in which +``__main__`` is initialized depends on the flags and other options with +which the interpreter is invoked. + +.. _main_spec: + +__main__.__spec__ +----------------- + +Depending on how :mod:`__main__` is initialized, ``__main__.__spec__`` +gets set appropriately or to ``None``. + +When Python is started with the :option:`-m` option, ``__spec__`` is set +to the module spec of the corresponding module or package. ``__spec__`` is +also populated when the ``__main__`` module is loaded as part of executing a +directory, zipfile or other :data:`sys.path` entry. + +In :ref:`the remaining cases <using-on-interface-options>` +``__main__.__spec__`` is set to ``None``, as the code used to populate the +:mod:`__main__` does not correspond directly with an importable module: + +- interactive prompt +- -c switch +- running from stdin +- running directly from a source or bytecode file + +Note that ``__main__.__spec__`` is always ``None`` in the last case, +*even if* the file could technically be imported directly as a module +instead. Use the :option:`-m` switch if valid module metadata is desired +in :mod:`__main__`. + +Note also that even when ``__main__`` corresponds with an importable module +and ``__main__.__spec__`` is set accordingly, they're still considered +*distinct* modules. This is due to the fact that blocks guarded by +``if __name__ == "__main__":`` checks only execute when the module is used +to populate the ``__main__`` namespace, and not during normal import. Open issues @@ -825,13 +905,19 @@ related entries in the data model reference page? XXX runpy, pkgutil, et al in the library manual should all get "See Also" links at the top pointing to the new import system section. +XXX Add more explanation regarding the different ways in which +``__main__`` is initialized? + +XXX Add more info on ``__main__`` quirks/pitfalls (i.e. copy from +:pep:`395`). + References ========== The import machinery has evolved considerably since Python's early days. The original `specification for packages -<http://www.python.org/doc/essays/packages.html>`_ is still available to read, +<http://legacy.python.org/doc/essays/packages.html>`_ is still available to read, although some details have changed since the writing of that document. The original specification for :data:`sys.meta_path` was :pep:`302`, with diff --git a/Doc/reference/introduction.rst b/Doc/reference/introduction.rst index 0ac57945db18..5633ae3eb1cf 100644 --- a/Doc/reference/introduction.rst +++ b/Doc/reference/introduction.rst @@ -66,7 +66,7 @@ IronPython An alternate Python for .NET. Unlike Python.NET, this is a complete Python implementation that generates IL, and compiles Python code directly to .NET assemblies. It was created by Jim Hugunin, the original creator of Jython. For - more information, see `the IronPython website <http://www.ironpython.net/>`_. + more information, see `the IronPython website <http://ironpython.net/>`_. PyPy An implementation of Python written completely in Python. It supports several diff --git a/Doc/reference/lexical_analysis.rst b/Doc/reference/lexical_analysis.rst index 0ed3d3b9a700..c673791895b3 100644 --- a/Doc/reference/lexical_analysis.rst +++ b/Doc/reference/lexical_analysis.rst @@ -76,7 +76,7 @@ are ignored by the syntax; they are not tokens. Encoding declarations --------------------- -.. index:: source character set, encodings +.. index:: source character set, encoding declarations (source file) If a comment in the first or second line of the Python script matches the regular expression ``coding[=:]\s*([-\w.]+)``, this comment is processed as an @@ -310,7 +310,9 @@ The Unicode category codes mentioned above stand for: * *Mc* - spacing combining marks * *Nd* - decimal numbers * *Pc* - connector punctuations -* *Other_ID_Start* - explicit list of characters in `PropList.txt <http://unicode.org/Public/UNIDATA/PropList.txt>`_ to support backwards compatibility +* *Other_ID_Start* - explicit list of characters in `PropList.txt + <http://www.unicode.org/Public/7.0.0/ucd/PropList.txt>`_ to support backwards + compatibility * *Other_ID_Continue* - likewise All identifiers are converted into the normal form NFKC while parsing; comparison @@ -441,7 +443,7 @@ instance of the :class:`bytes` type instead of the :class:`str` type. They may only contain ASCII characters; bytes with a numeric value of 128 or greater must be expressed with escapes. -As of Python 3.3 it is possible again to prefix unicode strings with a +As of Python 3.3 it is possible again to prefix string literals with a ``u`` prefix to simplify maintenance of dual 2.x and 3.x codebases. Both string and bytes literals may optionally be prefixed with a letter ``'r'`` @@ -451,24 +453,24 @@ escapes in raw strings are not treated specially. Given that Python 2.x's raw unicode literals behave differently than Python 3.x's the ``'ur'`` syntax is not supported. - .. versionadded:: 3.3 - The ``'rb'`` prefix of raw bytes literals has been added as a synonym - of ``'br'``. +.. versionadded:: 3.3 + The ``'rb'`` prefix of raw bytes literals has been added as a synonym + of ``'br'``. - .. versionadded:: 3.3 - Support for the unicode legacy literal (``u'value'``) was reintroduced - to simplify the maintenance of dual Python 2.x and 3.x codebases. - See :pep:`414` for more information. +.. versionadded:: 3.3 + Support for the unicode legacy literal (``u'value'``) was reintroduced + to simplify the maintenance of dual Python 2.x and 3.x codebases. + See :pep:`414` for more information. -In triple-quoted strings, unescaped newlines and quotes are allowed (and are -retained), except that three unescaped quotes in a row terminate the string. (A -"quote" is the character used to open the string, i.e. either ``'`` or ``"``.) +In triple-quoted literals, unescaped newlines and quotes are allowed (and are +retained), except that three unescaped quotes in a row terminate the literal. (A +"quote" is the character used to open the literal, i.e. either ``'`` or ``"``.) .. index:: physical line, escape sequence, Standard C, C -Unless an ``'r'`` or ``'R'`` prefix is present, escape sequences in strings are -interpreted according to rules similar to those used by Standard C. The -recognized escape sequences are: +Unless an ``'r'`` or ``'R'`` prefix is present, escape sequences in string and +bytes literals are interpreted according to rules similar to those used by +Standard C. The recognized escape sequences are: +-----------------+---------------------------------+-------+ | Escape Sequence | Meaning | Notes | @@ -545,20 +547,20 @@ Notes: .. index:: unrecognized escape sequence Unlike Standard C, all unrecognized escape sequences are left in the string -unchanged, i.e., *the backslash is left in the string*. (This behavior is +unchanged, i.e., *the backslash is left in the result*. (This behavior is useful when debugging: if an escape sequence is mistyped, the resulting output is more easily recognized as broken.) It is also important to note that the escape sequences only recognized in string literals fall into the category of unrecognized escapes for bytes literals. -Even in a raw string, string quotes can be escaped with a backslash, but the -backslash remains in the string; for example, ``r"\""`` is a valid string +Even in a raw literal, quotes can be escaped with a backslash, but the +backslash remains in the result; for example, ``r"\""`` is a valid string literal consisting of two characters: a backslash and a double quote; ``r"\"`` is not a valid string literal (even a raw string cannot end in an odd number of -backslashes). Specifically, *a raw string cannot end in a single backslash* +backslashes). Specifically, *a raw literal cannot end in a single backslash* (since the backslash would escape the following quote character). Note also that a single backslash followed by a newline is interpreted as those two -characters as part of the string, *not* as a line continuation. +characters as part of the literal, *not* as a line continuation. .. _string-catenation: @@ -689,7 +691,7 @@ Operators The following tokens are operators:: - + - * ** / // % + + - * ** / // % @ << >> & | ^ ~ < > <= >= == != @@ -705,7 +707,7 @@ The following tokens serve as delimiters in the grammar:: ( ) [ ] { } , : . ; @ = -> - += -= *= /= //= %= + += -= *= /= //= %= @= &= |= ^= >>= <<= **= The period can also occur in floating-point and imaginary literals. A sequence @@ -726,4 +728,4 @@ occurrence outside string literals and comments is an unconditional error:: .. rubric:: Footnotes -.. [#] http://www.unicode.org/Public/6.1.0/ucd/NameAliases.txt +.. [#] http://www.unicode.org/Public/7.0.0/ucd/NameAliases.txt diff --git a/Doc/reference/simple_stmts.rst b/Doc/reference/simple_stmts.rst index b9ebaaa554c7..5f605408b7dd 100644 --- a/Doc/reference/simple_stmts.rst +++ b/Doc/reference/simple_stmts.rst @@ -7,7 +7,7 @@ Simple statements .. index:: pair: simple; statement -Simple statements are comprised within a single logical line. Several simple +A simple statement is comprised within a single logical line. Several simple statements may occur on a single line separated by semicolons. The syntax for simple statements is: @@ -70,6 +70,7 @@ Assignment statements ===================== .. index:: + single: =; assignment statement pair: assignment; statement pair: binding; name pair: rebinding; name @@ -90,8 +91,8 @@ attributes or items of mutable objects: : | `slicing` : | "*" `target` -(See section :ref:`primaries` for the syntax definitions for the last three -symbols.) +(See section :ref:`primaries` for the syntax definitions for *attributeref*, +*subscription*, and *slicing*.) An assignment statement evaluates the expression list (remember that this can be a single expression or a comma-separated list, the latter yielding a tuple) and @@ -227,7 +228,7 @@ Assignment of an object to a single target is recursively defined as follows. inclusive. Finally, the sequence object is asked to replace the slice with the items of the assigned sequence. The length of the slice may be different from the length of the assigned sequence, thus changing the length of the - target sequence, if the object allows it. + target sequence, if the target sequence allows it. .. impl-detail:: @@ -235,14 +236,15 @@ Assignment of an object to a single target is recursively defined as follows. as for expressions, and invalid syntax is rejected during the code generation phase, causing less detailed error messages. -WARNING: Although the definition of assignment implies that overlaps between the -left-hand side and the right-hand side are 'safe' (for example ``a, b = b, a`` -swaps two variables), overlaps *within* the collection of assigned-to variables -are not safe! For instance, the following program prints ``[0, 2]``:: +Although the definition of assignment implies that overlaps between the +left-hand side and the right-hand side are 'simultanenous' (for example ``a, b = +b, a`` swaps two variables), overlaps *within* the collection of assigned-to +variables occur left-to-right, sometimes resulting in confusion. For instance, +the following program prints ``[0, 2]``:: x = [0, 1] i = 0 - i, x[i] = 1, 2 + i, x[i] = 1, 2 # i is updated, then x[i] is updated print(x) @@ -260,6 +262,18 @@ Augmented assignment statements .. index:: pair: augmented; assignment single: statement; assignment, augmented + single: +=; augmented assignment + single: -=; augmented assignment + single: *=; augmented assignment + single: /=; augmented assignment + single: %=; augmented assignment + single: &=; augmented assignment + single: ^=; augmented assignment + single: |=; augmented assignment + single: **=; augmented assignment + single: //=; augmented assignment + single: >>=; augmented assignment + single: <<=; augmented assignment Augmented assignment is the combination, in a single statement, of a binary operation and an assignment statement: @@ -267,10 +281,10 @@ operation and an assignment statement: .. productionlist:: augmented_assignment_stmt: `augtarget` `augop` (`expression_list` | `yield_expression`) augtarget: `identifier` | `attributeref` | `subscription` | `slicing` - augop: "+=" | "-=" | "*=" | "/=" | "//=" | "%=" | "**=" + augop: "+=" | "-=" | "*=" | "@=" | "/=" | "//=" | "%=" | "**=" : | ">>=" | "<<=" | "&=" | "^=" | "|=" -(See section :ref:`primaries` for the syntax definitions for the last three +(See section :ref:`primaries` for the syntax definitions of the last three symbols.) An augmented assignment evaluates the target (which, unlike normal assignment @@ -284,6 +298,11 @@ version, ``x`` is only evaluated once. Also, when possible, the actual operation is performed *in-place*, meaning that rather than creating a new object and assigning that to the target, the old object is modified instead. +Unlike normal assignments, augmented assignments evaluate the left-hand side +*before* evaluating the right-hand side. For example, ``a[i] += f(x)`` first +looks-up ``a[i]``, then it evaluates ``f(x)`` and performs the addition, and +lastly, it writes the result back to ``a[i]``. + With the exception of assigning to tuples and multiple targets in a single statement, the assignment done by augmented assignment statements is handled the same way as normal assignments. Similarly, with the exception of the possible @@ -445,53 +464,26 @@ The :keyword:`yield` statement .. productionlist:: yield_stmt: `yield_expression` -The :keyword:`yield` statement is only used when defining a generator function, -and is only used in the body of the generator function. Using a :keyword:`yield` -statement in a function definition is sufficient to cause that definition to -create a generator function instead of a normal function. - -When a generator function is called, it returns an iterator known as a generator -iterator, or more commonly, a generator. The body of the generator function is -executed by calling the :func:`next` function on the generator repeatedly until -it raises an exception. +A :keyword:`yield` statement is semantically equivalent to a :ref:`yield +expression <yieldexpr>`. The yield statement can be used to omit the parentheses +that would otherwise be required in the equivalent yield expression +statement. For example, the yield statements :: -When a :keyword:`yield` statement is executed, the state of the generator is -frozen and the value of :token:`expression_list` is returned to :meth:`next`'s -caller. By "frozen" we mean that all local state is retained, including the -current bindings of local variables, the instruction pointer, and the internal -evaluation stack: enough information is saved so that the next time :func:`next` -is invoked, the function can proceed exactly as if the :keyword:`yield` -statement were just another external call. + yield <expr> + yield from <expr> -The :keyword:`yield` statement is allowed in the :keyword:`try` clause of a -:keyword:`try` ... :keyword:`finally` construct. If the generator is not -resumed before it is finalized (by reaching a zero reference count or by being -garbage collected), the generator-iterator's :meth:`close` method will be -called, allowing any pending :keyword:`finally` clauses to execute. +are equivalent to the yield expression statements :: -When ``yield from <expr>`` is used, it treats the supplied expression as -a subiterator, producing values from it until the underlying iterator is -exhausted. + (yield <expr>) + (yield from <expr>) - .. versionchanged:: 3.3 - Added ``yield from <expr>`` to delegate control flow to a subiterator - -For full details of :keyword:`yield` semantics, refer to the :ref:`yieldexpr` -section. - -.. seealso:: - - :pep:`0255` - Simple Generators - The proposal for adding generators and the :keyword:`yield` statement to Python. - - :pep:`0342` - Coroutines via Enhanced Generators - The proposal to enhance the API and syntax of generators, making them - usable as simple coroutines. - - :pep:`0380` - Syntax for Delegating to a Subgenerator - The proposal to introduce the :token:`yield_from` syntax, making delegation - to sub-generators easy. +Yield expressions and statements are only used when defining a :term:`generator` +function, and are only used in the body of the generator function. Using yield +in a function definition is sufficient to cause that definition to create a +generator function instead of a normal function. +For full details of :keyword:`yield` semantics, refer to the +:ref:`yieldexpr` section. .. _raise: @@ -556,8 +548,8 @@ printed:: RuntimeError: Something bad happened A similar mechanism works implicitly if an exception is raised inside an -exception handler: the previous exception is then attached as the new -exception's :attr:`__context__` attribute:: +exception handler or a :keyword:`finally` clause: the previous exception is then +attached as the new exception's :attr:`__context__` attribute:: >>> try: ... print(1 / 0) @@ -672,7 +664,7 @@ commas) the two steps are carried out separately for each clause, just as though the clauses had been separated out into individiual import statements. -The details of the first step, finding and loading modules is described in +The details of the first step, finding and loading modules are described in greater detail in the section on the :ref:`import system <importsystem>`, which also describes the various types of packages and modules that can be imported, as well as all the hooks that can be used to customize @@ -683,6 +675,8 @@ initializing the module, which includes execution of the module's code. If the requested module is retrieved successfully, it will be made available in the local namespace in one of three ways: +.. index:: single: as; import statement + * If the module name is followed by :keyword:`as`, then the name following :keyword:`as` is bound directly to the imported module. * If no other name is specified, and the module being imported is a top @@ -701,7 +695,7 @@ available in the local namespace in one of three ways: The :keyword:`from` form uses a slightly more complex process: -#. find the module specified in the :keyword:`from` clause loading and +#. find the module specified in the :keyword:`from` clause, loading and initializing it if necessary; #. for each of the identifiers specified in the :keyword:`import` clauses: @@ -709,7 +703,7 @@ The :keyword:`from` form uses a slightly more complex process: #. if not, attempt to import a submodule with that name and then check the imported module again for that attribute #. if the attribute is not found, :exc:`ImportError` is raised. - #. otherwise, a reference to that value is bound in the local namespace, + #. otherwise, a reference to that value is stored in the local namespace, using the name in the :keyword:`as` clause if it is present, otherwise using the attribute name @@ -737,10 +731,9 @@ in the module's namespace which do not begin with an underscore character to avoid accidentally exporting items that are not part of the API (such as library modules which were imported and used within the module). -The :keyword:`from` form with ``*`` may only occur in a module scope. The wild -card form of import --- ``import *`` --- is only allowed at the module level. -Attempting to use it in class or function definitions will raise a -:exc:`SyntaxError`. +The wild card form of import --- ``from module import *`` --- is only allowed at +the module level. Attempting to use it in class or function definitions will +raise a :exc:`SyntaxError`. .. index:: single: relative; import @@ -759,7 +752,7 @@ import mod`` from within ``pkg.subpkg1`` you will import ``pkg.subpkg2.mod``. The specification for relative imports is contained within :pep:`328`. :func:`importlib.import_module` is provided to support applications that -determine which modules need to be loaded dynamically. +determine dynamically the modules to be loaded. .. _future: @@ -771,10 +764,12 @@ Future statements A :dfn:`future statement` is a directive to the compiler that a particular module should be compiled using syntax or semantics that will be available in a -specified future release of Python. The future statement is intended to ease -migration to future versions of Python that introduce incompatible changes to -the language. It allows use of the new features on a per-module basis before -the release in which the feature becomes standard. +specified future release of Python where the feature becomes standard. + +The future statement is intended to ease migration to future versions of Python +that introduce incompatible changes to the language. It allows use of the new +features on a per-module basis before the release in which the feature becomes +standard. .. productionlist:: * future_statement: "from" "__future__" "import" feature ["as" name] @@ -869,7 +864,7 @@ definition, function definition, or :keyword:`import` statement. .. impl-detail:: - The current implementation does not enforce the latter two restrictions, but + The current implementation does not enforce the two restrictions, but programs should not abuse this freedom, as future implementations may enforce them or silently change the meaning of the program. @@ -902,16 +897,16 @@ The :keyword:`nonlocal` statement : | "nonlocal" identifier augop expression_list The :keyword:`nonlocal` statement causes the listed identifiers to refer to -previously bound variables in the nearest enclosing scope. This is important -because the default behavior for binding is to search the local namespace -first. The statement allows encapsulated code to rebind variables outside of -the local scope besides the global (module) scope. +previously bound variables in the nearest enclosing scope excluding globals. +This is important because the default behavior for binding is to search the +local namespace first. The statement allows encapsulated code to rebind +variables outside of the local scope besides the global (module) scope. .. XXX not implemented The :keyword:`nonlocal` statement may prepend an assignment or augmented assignment, but not an expression. -Names listed in a :keyword:`nonlocal` statement, unlike to those listed in a +Names listed in a :keyword:`nonlocal` statement, unlike those listed in a :keyword:`global` statement, must refer to pre-existing bindings in an enclosing scope (the scope in which a new binding should be created cannot be determined unambiguously). diff --git a/Doc/reference/toplevel_components.rst b/Doc/reference/toplevel_components.rst index f4bc71f07b0c..e1687ff04d32 100644 --- a/Doc/reference/toplevel_components.rst +++ b/Doc/reference/toplevel_components.rst @@ -97,20 +97,10 @@ Expression input ================ .. index:: single: input - .. index:: builtin: eval -There are two forms of expression input. Both ignore leading whitespace. The +:func:`eval` is used for expression input. It ignores leading whitespace. The string argument to :func:`eval` must have the following form: .. productionlist:: eval_input: `expression_list` NEWLINE* - -.. index:: - object: file - single: input; raw - single: readline() (file method) - -Note: to read 'raw' input line without interpretation, you can use the -:meth:`readline` method of file objects, including ``sys.stdin``. - diff --git a/Doc/tools/sphinxext/c_annotations.py b/Doc/tools/extensions/c_annotations.py similarity index 93% rename from Doc/tools/sphinxext/c_annotations.py rename to Doc/tools/extensions/c_annotations.py index 8b5167ac906e..baa39f3b4464 100644 --- a/Doc/tools/sphinxext/c_annotations.py +++ b/Doc/tools/extensions/c_annotations.py @@ -13,7 +13,7 @@ Usage: Set the `refcount_file` config value to the path to the reference count data file. - :copyright: Copyright 2007-2013 by Georg Brandl. + :copyright: Copyright 2007-2014 by Georg Brandl. :license: Python license. """ @@ -81,7 +81,10 @@ def add_annotations(self, app, doctree): continue if not par[0].has_key('names') or not par[0]['names']: continue - entry = self.get(par[0]['names'][0]) + name = par[0]['names'][0] + if name.startswith("c."): + name = name[2:] + entry = self.get(name) if not entry: continue elif entry.result_type not in ("PyObject*", "PyVarObject*"): @@ -115,3 +118,4 @@ def new_handle_signature(self, sig, signode): signode.parent['stableabi'] = 'stableabi' in self.options return old_handle_signature(self, sig, signode) CObject.handle_signature = new_handle_signature + return {'version': '1.0', 'parallel_read_safe': True} diff --git a/Doc/tools/sphinxext/patchlevel.py b/Doc/tools/extensions/patchlevel.py similarity index 100% rename from Doc/tools/sphinxext/patchlevel.py rename to Doc/tools/extensions/patchlevel.py diff --git a/Doc/tools/sphinxext/pyspecific.py b/Doc/tools/extensions/pyspecific.py similarity index 81% rename from Doc/tools/sphinxext/pyspecific.py rename to Doc/tools/extensions/pyspecific.py index 2b5de1421e73..9b78184d6745 100644 --- a/Doc/tools/sphinxext/pyspecific.py +++ b/Doc/tools/extensions/pyspecific.py @@ -5,20 +5,36 @@ Sphinx extension with Python doc-specific markup. - :copyright: 2008-2013 by Georg Brandl. + :copyright: 2008-2014 by Georg Brandl. :license: Python license. """ -ISSUE_URI = 'http://bugs.python.org/issue%s' -SOURCE_URI = 'http://hg.python.org/cpython/file/default/%s' +import re +import codecs +from os import path +from time import asctime +from pprint import pformat +from docutils.io import StringOutput +from docutils.utils import new_document from docutils import nodes, utils -import sphinx +from sphinx import addnodes +from sphinx.builders import Builder from sphinx.util.nodes import split_explicit_title +from sphinx.util.compat import Directive from sphinx.writers.html import HTMLTranslator +from sphinx.writers.text import TextWriter from sphinx.writers.latex import LaTeXTranslator -from sphinx.locale import versionlabels +from sphinx.domains.python import PyModulelevel, PyClassmember + +# Support for checking for suspicious markup + +import suspicious + + +ISSUE_URI = 'https://bugs.python.org/issue%s' +SOURCE_URI = 'https://hg.python.org/cpython/file/default/%s' # monkey-patch reST parser to disable alphabetic and roman enumerated lists from docutils.parsers.rst.states import Body @@ -27,21 +43,12 @@ Body.enum.converters['lowerroman'] = \ Body.enum.converters['upperroman'] = lambda x: None -if sphinx.__version__[:3] < '1.2': - # monkey-patch HTML translator to give versionmodified paragraphs a class - def new_visit_versionmodified(self, node): - self.body.append(self.starttag(node, 'p', CLASS=node['type'])) - text = versionlabels[node['type']] % node['version'] - if len(node): - text += ':' - else: - text += '.' - self.body.append('<span class="versionmodified">%s</span> ' % text) - HTMLTranslator.visit_versionmodified = new_visit_versionmodified - # monkey-patch HTML and LaTeX translators to keep doctest blocks in the # doctest docs themselves orig_visit_literal_block = HTMLTranslator.visit_literal_block +orig_depart_literal_block = LaTeXTranslator.depart_literal_block + + def new_visit_literal_block(self, node): meta = self.builder.env.metadata[self.builder.current_docname] old_trim_doctest_flags = self.highlighter.trim_doctest_flags @@ -52,9 +59,7 @@ def new_visit_literal_block(self, node): finally: self.highlighter.trim_doctest_flags = old_trim_doctest_flags -HTMLTranslator.visit_literal_block = new_visit_literal_block -orig_depart_literal_block = LaTeXTranslator.depart_literal_block def new_depart_literal_block(self, node): meta = self.builder.env.metadata[self.curfilestack[-1]] old_trim_doctest_flags = self.highlighter.trim_doctest_flags @@ -65,8 +70,11 @@ def new_depart_literal_block(self, node): finally: self.highlighter.trim_doctest_flags = old_trim_doctest_flags + +HTMLTranslator.visit_literal_block = new_visit_literal_block LaTeXTranslator.depart_literal_block = new_depart_literal_block + # Support for marking up and linking to bugs.python.org issues def issue_role(typ, rawtext, text, lineno, inliner, options={}, content=[]): @@ -88,8 +96,6 @@ def source_role(typ, rawtext, text, lineno, inliner, options={}, content=[]): # Support for marking up implementation details -from sphinx.util.compat import Directive - class ImplementationDetail(Directive): has_content = True @@ -116,9 +122,6 @@ def run(self): # Support for documenting decorators -from sphinx import addnodes -from sphinx.domains.python import PyModulelevel, PyClassmember - class PyDecoratorMixin(object): def handle_signature(self, sig, signode): ret = super(PyDecoratorMixin, self).handle_signature(sig, signode) @@ -128,25 +131,40 @@ def handle_signature(self, sig, signode): def needs_arglist(self): return False + class PyDecoratorFunction(PyDecoratorMixin, PyModulelevel): def run(self): # a decorator function is a function after all self.name = 'py:function' return PyModulelevel.run(self) + class PyDecoratorMethod(PyDecoratorMixin, PyClassmember): def run(self): self.name = 'py:method' return PyClassmember.run(self) -# Support for documenting version of removal in deprecations +class PyCoroutineMixin(object): + def handle_signature(self, sig, signode): + ret = super(PyCoroutineMixin, self).handle_signature(sig, signode) + signode.insert(0, addnodes.desc_annotation('coroutine ', 'coroutine ')) + return ret -from sphinx.locale import versionlabels -from sphinx.util.compat import Directive -versionlabels['deprecated-removed'] = \ - 'Deprecated since version %s, will be removed in version %s' +class PyCoroutineFunction(PyCoroutineMixin, PyModulelevel): + def run(self): + self.name = 'py:function' + return PyModulelevel.run(self) + + +class PyCoroutineMethod(PyCoroutineMixin, PyClassmember): + def run(self): + self.name = 'py:method' + return PyClassmember.run(self) + + +# Support for documenting version of removal in deprecations class DeprecatedRemoved(Directive): has_content = True @@ -155,34 +173,49 @@ class DeprecatedRemoved(Directive): final_argument_whitespace = True option_spec = {} + _label = 'Deprecated since version %s, will be removed in version %s' + def run(self): node = addnodes.versionmodified() node.document = self.state.document node['type'] = 'deprecated-removed' version = (self.arguments[0], self.arguments[1]) node['version'] = version + text = self._label % version if len(self.arguments) == 3: inodes, messages = self.state.inline_text(self.arguments[2], self.lineno+1) - node.extend(inodes) - if self.content: - self.state.nested_parse(self.content, self.content_offset, node) - ret = [node] + messages + para = nodes.paragraph(self.arguments[2], '', *inodes) + node.append(para) + else: + messages = [] + if self.content: + self.state.nested_parse(self.content, self.content_offset, node) + if len(node): + if isinstance(node[0], nodes.paragraph) and node[0].rawsource: + content = nodes.inline(node[0].rawsource, translatable=True) + content.source = node[0].source + content.line = node[0].line + content += node[0].children + node[0].replace_self(nodes.paragraph('', '', content)) + node[0].insert(0, nodes.inline('', '%s: ' % text, + classes=['versionmodified'])) else: - ret = [node] + para = nodes.paragraph('', '', + nodes.inline('', '%s.' % text, + classes=['versionmodified'])) + node.append(para) env = self.state.document.settings.env env.note_versionchange('deprecated', version[0], node, self.lineno) - return ret + return [node] + messages # Support for including Misc/NEWS -import re -import codecs - issue_re = re.compile('([Ii])ssue #([0-9]+)') whatsnew_re = re.compile(r"(?im)^what's new in (.*?)\??$") + class MiscNews(Directive): has_content = False required_arguments = 1 @@ -207,7 +240,7 @@ def run(self): text = 'The NEWS file is not available.' node = nodes.strong(text, text) return [node] - content = issue_re.sub(r'`\1ssue #\2 <http://bugs.python.org/\2>`__', + content = issue_re.sub(r'`\1ssue #\2 <https://bugs.python.org/\2>`__', content) content = whatsnew_re.sub(r'\1', content) # remove first 3 lines as they are the main heading @@ -236,15 +269,6 @@ def run(self): 'typesseq', 'typesseq-mutable', 'unary', 'while', 'with', 'yield' ] -from os import path -from time import asctime -from pprint import pformat -from docutils.io import StringOutput -from docutils.utils import new_document - -from sphinx.builders import Builder -from sphinx.writers.text import TextWriter - class PydocTopicsBuilder(Builder): name = 'pydoc-topics' @@ -272,29 +296,23 @@ def write(self, *ignored): document.append(doctree.ids[labelid]) destination = StringOutput(encoding='utf-8') writer.write(document, destination) - self.topics[label] = writer.output.encode('utf-8') + self.topics[label] = writer.output def finish(self): - f = open(path.join(self.outdir, 'topics.py'), 'w') + f = open(path.join(self.outdir, 'topics.py'), 'wb') try: - f.write('# -*- coding: utf-8 -*-\n') - f.write('# Autogenerated by Sphinx on %s\n' % asctime()) - f.write('topics = ' + pformat(self.topics) + '\n') + f.write('# -*- coding: utf-8 -*-\n'.encode('utf-8')) + f.write(('# Autogenerated by Sphinx on %s\n' % asctime()).encode('utf-8')) + f.write(('topics = ' + pformat(self.topics) + '\n').encode('utf-8')) finally: f.close() -# Support for checking for suspicious markup - -import suspicious - - # Support for documenting Opcodes -import re - opcode_sig_re = re.compile(r'(\w+(?:\+\d)?)(?:\s*\((.*)\))?') + def parse_opcode_signature(env, sig, signode): """Transform an opcode signature into RST nodes.""" m = opcode_sig_re.match(sig) @@ -314,12 +332,13 @@ def parse_opcode_signature(env, sig, signode): pdbcmd_sig_re = re.compile(r'([a-z()!]+)\s*(.*)') # later... -#pdbargs_tokens_re = re.compile(r'''[a-zA-Z]+ | # identifiers +# pdbargs_tokens_re = re.compile(r'''[a-zA-Z]+ | # identifiers # [.,:]+ | # punctuation # [\[\]()] | # parens # \s+ # whitespace # ''', re.X) + def parse_pdb_command(env, sig, signode): """Transform a pdb command signature into RST nodes.""" m = pdbcmd_sig_re.match(sig) @@ -347,4 +366,7 @@ def setup(app): app.add_description_unit('2to3fixer', '2to3fixer', '%s (2to3 fixer)') app.add_directive_to_domain('py', 'decorator', PyDecoratorFunction) app.add_directive_to_domain('py', 'decoratormethod', PyDecoratorMethod) + app.add_directive_to_domain('py', 'coroutinefunction', PyCoroutineFunction) + app.add_directive_to_domain('py', 'coroutinemethod', PyCoroutineMethod) app.add_directive('miscnews', MiscNews) + return {'version': '1.0', 'parallel_read_safe': True} diff --git a/Doc/tools/sphinxext/suspicious.py b/Doc/tools/extensions/suspicious.py similarity index 99% rename from Doc/tools/sphinxext/suspicious.py rename to Doc/tools/extensions/suspicious.py index ee877336f676..d3ed849157f0 100644 --- a/Doc/tools/sphinxext/suspicious.py +++ b/Doc/tools/extensions/suspicious.py @@ -91,7 +91,7 @@ def init(self): self.log_file_name = os.path.join(self.outdir, 'suspicious.csv') open(self.log_file_name, 'w').close() # load database of previously ignored issues - self.load_rules(os.path.join(os.path.dirname(__file__), + self.load_rules(os.path.join(os.path.dirname(__file__), '..', 'susp-ignored.csv')) def get_outdated_docs(self): diff --git a/Doc/tools/sphinxext/pydoctheme/static/pydoctheme.css b/Doc/tools/pydoctheme/static/pydoctheme.css similarity index 92% rename from Doc/tools/sphinxext/pydoctheme/static/pydoctheme.css rename to Doc/tools/pydoctheme/static/pydoctheme.css index 3d995d81b1fe..50835bb92ca6 100644 --- a/Doc/tools/sphinxext/pydoctheme/static/pydoctheme.css +++ b/Doc/tools/pydoctheme/static/pydoctheme.css @@ -94,31 +94,31 @@ div.body div.seealso { } div.body a { - color: #00608f; + color: #0072aa; } div.body a:visited { - color: #30306f; + color: #6363bb; } div.body a:hover { color: #00B0E4; } -tt, pre { +tt, code, pre { font-family: monospace, sans-serif; font-size: 96.5%; } -div.body tt { +div.body tt, div.body code { border-radius: 3px; } -div.body tt.descname { +div.body tt.descname, div.body code.descname { font-size: 120%; } -div.body tt.xref, div.body a tt { +div.body tt.xref, div.body a tt, div.body code.xref, div.body a code { font-weight: normal; } diff --git a/Doc/tools/sphinxext/pydoctheme/theme.conf b/Doc/tools/pydoctheme/theme.conf similarity index 100% rename from Doc/tools/sphinxext/pydoctheme/theme.conf rename to Doc/tools/pydoctheme/theme.conf diff --git a/Doc/tools/roman.py b/Doc/tools/roman.py deleted file mode 100644 index 89ef617e6e71..000000000000 --- a/Doc/tools/roman.py +++ /dev/null @@ -1,80 +0,0 @@ -"""Convert to and from Roman numerals""" - -__author__ = "Mark Pilgrim (f8dy@diveintopython.org)" -__version__ = "1.4" -__date__ = "8 August 2001" -__copyright__ = """Copyright (c) 2001 Mark Pilgrim - -This program is part of "Dive Into Python", a free Python tutorial for -experienced programmers. Visit http://diveintopython.org/ for the -latest version. - -This program is free software; you can redistribute it and/or modify -it under the terms of the Python 2.1.1 license, available at -http://www.python.org/2.1.1/license.html -""" - -import re - -#Define exceptions -class RomanError(Exception): pass -class OutOfRangeError(RomanError): pass -class NotIntegerError(RomanError): pass -class InvalidRomanNumeralError(RomanError): pass - -#Define digit mapping -romanNumeralMap = (('M', 1000), - ('CM', 900), - ('D', 500), - ('CD', 400), - ('C', 100), - ('XC', 90), - ('L', 50), - ('XL', 40), - ('X', 10), - ('IX', 9), - ('V', 5), - ('IV', 4), - ('I', 1)) - -def toRoman(n): - """convert integer to Roman numeral""" - if not (0 < n < 5000): - raise OutOfRangeError("number out of range (must be 1..4999)") - if int(n) != n: - raise NotIntegerError("decimals can not be converted") - - result = "" - for numeral, integer in romanNumeralMap: - while n >= integer: - result += numeral - n -= integer - return result - -#Define pattern to detect valid Roman numerals -romanNumeralPattern = re.compile(""" - ^ # beginning of string - M{0,4} # thousands - 0 to 4 M's - (CM|CD|D?C{0,3}) # hundreds - 900 (CM), 400 (CD), 0-300 (0 to 3 C's), - # or 500-800 (D, followed by 0 to 3 C's) - (XC|XL|L?X{0,3}) # tens - 90 (XC), 40 (XL), 0-30 (0 to 3 X's), - # or 50-80 (L, followed by 0 to 3 X's) - (IX|IV|V?I{0,3}) # ones - 9 (IX), 4 (IV), 0-3 (0 to 3 I's), - # or 5-8 (V, followed by 0 to 3 I's) - $ # end of string - """ ,re.VERBOSE) - -def fromRoman(s): - """convert Roman numeral to integer""" - if not s: - raise InvalidRomanNumeralError('Input can not be blank') - if not romanNumeralPattern.search(s): - raise InvalidRomanNumeralError('Invalid Roman numeral: %s' % s) - - result = 0 - index = 0 - for numeral, integer in romanNumeralMap: - while s[index:index+len(numeral)] == numeral: - result += integer - index += len(numeral) - return result diff --git a/Doc/tools/rstlint.py b/Doc/tools/rstlint.py index 2cc3d1277ca0..be19ec8b377b 100755 --- a/Doc/tools/rstlint.py +++ b/Doc/tools/rstlint.py @@ -15,7 +15,6 @@ import re import sys import getopt -import subprocess from os.path import join, splitext, abspath, exists from collections import defaultdict @@ -28,14 +27,16 @@ 'parsed-literal', 'pull-quote', 'raw', 'replace', 'restructuredtext-test-directive', 'role', 'rubric', 'sectnum', 'sidebar', 'table', 'target-notes', 'tip', 'title', 'topic', 'unicode', 'warning', - # Sphinx custom ones + # Sphinx and Python docs custom ones 'acks', 'attribute', 'autoattribute', 'autoclass', 'autodata', 'autoexception', 'autofunction', 'automethod', 'automodule', 'centered', 'cfunction', 'class', 'classmethod', 'cmacro', 'cmdoption', 'cmember', 'code-block', 'confval', 'cssclass', 'ctype', 'currentmodule', 'cvar', - 'data', 'deprecated', 'describe', 'directive', 'doctest', 'envvar', 'event', - 'exception', 'function', 'glossary', 'highlight', 'highlightlang', 'index', - 'literalinclude', 'method', 'module', 'moduleauthor', 'productionlist', + 'data', 'decorator', 'decoratormethod', 'deprecated-removed', + 'deprecated(?!-removed)', 'describe', 'directive', 'doctest', 'envvar', + 'event', 'exception', 'function', 'glossary', 'highlight', 'highlightlang', + 'impl-detail', 'index', 'literalinclude', 'method', 'miscnews', 'module', + 'moduleauthor', 'opcode', 'pdbcommand', 'productionlist', 'program', 'role', 'sectionauthor', 'seealso', 'sourcecode', 'staticmethod', 'tabularcolumns', 'testcode', 'testoutput', 'testsetup', 'toctree', 'todo', 'todolist', 'versionadded', 'versionchanged' @@ -44,13 +45,14 @@ all_directives = '(' + '|'.join(directives) + ')' seems_directive_re = re.compile(r'\.\. %s([^a-z:]|:(?!:))' % all_directives) default_role_re = re.compile(r'(^| )`\w([^`]*?\w)?`($| )') -leaked_markup_re = re.compile(r'[a-z]::[^=]|:[a-z]+:|`|\.\.\s*\w+:') +leaked_markup_re = re.compile(r'[a-z]::\s|`|\.\.\s*\w+:') checkers = {} checker_props = {'severity': 1, 'falsepositives': False} + def checker(*suffixes, **kwds): """Decorator to register a function as a checker.""" def deco(func): @@ -171,10 +173,6 @@ def main(argv): count = defaultdict(int) for root, dirs, files in os.walk(path): - # ignore subdirs controlled by svn - if '.svn' in dirs: - dirs.remove('.svn') - # ignore subdirs in ignore list if abspath(root) in ignore: del dirs[:] diff --git a/Doc/tools/sphinx-build.py b/Doc/tools/sphinx-build.py deleted file mode 100644 index a446dfa8e18c..000000000000 --- a/Doc/tools/sphinx-build.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8 -*- -""" - Sphinx - Python documentation toolchain - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - :copyright: 2007-2010 by Georg Brandl. - :license: Python license. -""" - -import sys -import warnings - -# Get rid of UserWarnings reported by pkg_resources. -warnings.filterwarnings('ignore', category=UserWarning, module='jinja2') - -if __name__ == '__main__': - - if sys.version_info[:3] < (2, 4, 0) or sys.version_info[:3] > (3, 0, 0): - sys.stderr.write("""\ -Error: Sphinx needs to be executed with Python 2.4 or newer (not 3.0 though). -(If you run this from the Makefile, you can set the PYTHON variable -to the path of an alternative interpreter executable, e.g., -``make html PYTHON=python2.5``). -""") - sys.exit(1) - - from sphinx import main - sys.exit(main(sys.argv)) diff --git a/Doc/tools/sphinxext/indexsidebar.html b/Doc/tools/sphinxext/indexsidebar.html deleted file mode 100644 index ed5da0cd31f4..000000000000 --- a/Doc/tools/sphinxext/indexsidebar.html +++ /dev/null @@ -1,17 +0,0 @@ - <h3>Download</h3> - <p><a href="{{ pathto('download') }}">Download these documents</a></p> - <h3>Docs for other versions</h3> - <ul> - <li><a href="http://docs.python.org/2.7/">Python 2.7 (stable)</a></li> - <li><a href="http://docs.python.org/3.3/">Python 3.3 (stable)</a></li> - <li><a href="http://www.python.org/doc/versions/">Old versions</a></li> - </ul> - - <h3>Other resources</h3> - <ul> - {# XXX: many of these should probably be merged in the main docs #} - <li><a href="http://www.python.org/dev/peps/">PEP Index</a></li> - <li><a href="http://wiki.python.org/moin/BeginnersGuide">Beginner's Guide</a></li> - <li><a href="http://wiki.python.org/moin/PythonBooks">Book List</a></li> - <li><a href="http://www.python.org/doc/av/">Audio/Visual Talks</a></li> - </ul> diff --git a/Doc/tools/sphinxext/opensearch.xml b/Doc/tools/sphinxext/opensearch.xml deleted file mode 100644 index 69cec804cd0e..000000000000 --- a/Doc/tools/sphinxext/opensearch.xml +++ /dev/null @@ -1,4 +0,0 @@ -{% extends "!opensearch.xml" %} -{% block extra -%} -<Image height="16" width="16" type="image/x-icon">http://www.python.org/images/favicon16x16.ico</Image> -{%- endblock %} diff --git a/Doc/tools/sphinxext/static/basic.css b/Doc/tools/sphinxext/static/basic.css deleted file mode 100644 index 2058b05f941e..000000000000 --- a/Doc/tools/sphinxext/static/basic.css +++ /dev/null @@ -1,445 +0,0 @@ -/** - * Sphinx stylesheet -- basic theme - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -/* -- main layout ----------------------------------------------------------- */ - -div.clearer { - clear: both; -} - -/* -- relbar ---------------------------------------------------------------- */ - -div.related { - width: 100%; - font-size: 90%; -} - -div.related h3 { - display: none; -} - -div.related ul { - margin: 0; - padding: 0 0 0 10px; - list-style: none; -} - -div.related li { - display: inline; -} - -div.related li.right { - float: right; - margin-right: 5px; -} - -/* -- sidebar --------------------------------------------------------------- */ - -div.sphinxsidebarwrapper { - position: relative; - top: 0; - padding: 10px 5px 0 10px; - word-wrap: break-word; -} - -div.sphinxsidebar { - float: left; - width: 230px; - margin-left: -100%; - font-size: 90%; -} - -div.sphinxsidebar ul { - list-style: none; -} - -div.sphinxsidebar ul ul, -div.sphinxsidebar ul.want-points { - margin-left: 20px; - list-style: square; -} - -div.sphinxsidebar ul ul { - margin-top: 0; - margin-bottom: 0; -} - -div.sphinxsidebar form { - margin-top: 10px; -} - -div.sphinxsidebar input { - border: 1px solid #98dbcc; - font-family: sans-serif; - font-size: 1em; -} - -img { - border: 0; -} - -/* -- search page ----------------------------------------------------------- */ - -ul.search { - margin: 10px 0 0 20px; - padding: 0; -} - -ul.search li { - padding: 5px 0 5px 20px; - background-image: url(file.png); - background-repeat: no-repeat; - background-position: 0 7px; -} - -ul.search li a { - font-weight: bold; -} - -ul.search li div.context { - color: #888; - margin: 2px 0 0 30px; - text-align: left; -} - -ul.keywordmatches li.goodmatch a { - font-weight: bold; -} - -/* -- index page ------------------------------------------------------------ */ - -table.contentstable { - width: 90%; -} - -table.contentstable p.biglink { - line-height: 150%; -} - -a.biglink { - font-size: 1.3em; -} - -span.linkdescr { - font-style: italic; - padding-top: 5px; - font-size: 90%; -} - -/* -- general index --------------------------------------------------------- */ - -table.indextable td { - text-align: left; - vertical-align: top; -} - -table.indextable dl, table.indextable dd { - margin-top: 0; - margin-bottom: 0; -} - -table.indextable tr.pcap { - height: 10px; -} - -table.indextable tr.cap { - margin-top: 10px; - background-color: #f2f2f2; -} - -img.toggler { - margin-right: 3px; - margin-top: 3px; - cursor: pointer; -} - -/* -- general body styles --------------------------------------------------- */ - -a.headerlink { - visibility: hidden; -} - -h1:hover > a.headerlink, -h2:hover > a.headerlink, -h3:hover > a.headerlink, -h4:hover > a.headerlink, -h5:hover > a.headerlink, -h6:hover > a.headerlink, -dt:hover > a.headerlink { - visibility: visible; -} - -div.body p.caption { - text-align: inherit; -} - -div.body td { - text-align: left; -} - -.field-list ul { - padding-left: 1em; -} - -.first { - margin-top: 0 !important; -} - -p.rubric { - margin-top: 30px; - font-weight: bold; -} - -/* -- sidebars -------------------------------------------------------------- */ - -div.sidebar { - margin: 0 0 0.5em 1em; - border: 1px solid #ddb; - padding: 7px 7px 0 7px; - background-color: #ffe; - width: 40%; - float: right; -} - -p.sidebar-title { - font-weight: bold; -} - -/* -- topics ---------------------------------------------------------------- */ - -div.topic { - border: 1px solid #ccc; - padding: 7px 7px 0 7px; - margin: 10px 0 10px 0; -} - -p.topic-title { - font-size: 1.1em; - font-weight: bold; - margin-top: 10px; -} - -/* -- admonitions ----------------------------------------------------------- */ - -div.admonition { - margin-top: 10px; - margin-bottom: 10px; - padding: 7px; -} - -div.admonition dt { - font-weight: bold; -} - -div.admonition dl { - margin-bottom: 0; -} - -p.admonition-title { - margin: 0px 10px 5px 0px; - font-weight: bold; -} - -div.body p.centered { - text-align: center; - margin-top: 25px; -} - -/* -- tables ---------------------------------------------------------------- */ - -table.docutils { - border: 0 solid #dce; - border-collapse: collapse; -} - -table.docutils td, table.docutils th { - padding: 2px 5px 2px 5px; - border-left: 0; - background-color: #eef; -} - -table.docutils td p.last, table.docutils th p.last { - margin-bottom: 0; -} - -table.field-list td, table.field-list th { - border: 0 !important; -} - -table.footnote td, table.footnote th { - border: 0 !important; -} - -table.docutils th { - border-top: 1px solid #cac; - background-color: #ede; -} - -th { - text-align: left; - padding-right: 5px; -} - -th.head { - text-align: center; -} - -/* -- other body styles ----------------------------------------------------- */ - -dl { - margin-bottom: 15px; -} - -dd p { - margin-top: 0px; -} - -dd ul, dd table { - margin-bottom: 10px; -} - -dd { - margin-top: 3px; - margin-bottom: 10px; - margin-left: 30px; -} - -dt:target, .highlight { - background-color: #fbe54e; -} - -dl.glossary dt { - font-weight: bold; - font-size: 1.1em; -} - -.field-list ul { - margin: 0; - padding-left: 1em; -} - -.field-list p { - margin: 0; -} - -.refcount { - color: #060; -} - -.optional { - font-size: 1.3em; -} - -.versionmodified { - font-style: italic; -} - -.deprecated, .deprecated-removed { - background-color: #ffe4e4; - border: 1px solid #f66; - padding: 7px; -} - -div.deprecated p { - margin-bottom: 0; -} - -.system-message { - background-color: #fda; - padding: 5px; - border: 3px solid red; -} - -.footnote:target { - background-color: #ffa; -} - -.impl-detail { - margin-top: 10px; - margin-bottom: 10px; - padding: 7px; - border: 1px solid #ccc; -} - -.impl-detail .compound-first { - margin-top: 0; -} - -.impl-detail .compound-last { - margin-bottom: 0; -} - -/* -- code displays --------------------------------------------------------- */ - -pre { - overflow: auto; - overflow-y: hidden; -} - -td.linenos pre { - padding: 5px 0px; - border: 0; - background-color: transparent; - color: #aaa; -} - -table.highlighttable { - margin-left: 0.5em; -} - -table.highlighttable td { - padding: 0 0.5em 0 0.5em; -} - -tt.descname { - background-color: transparent; - font-weight: bold; - font-size: 1.2em; -} - -tt.descclassname { - background-color: transparent; -} - -tt.xref, a tt { - background-color: transparent; - font-weight: bold; -} - -h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { - background-color: transparent; -} - -/* -- math display ---------------------------------------------------------- */ - -img.math { - vertical-align: middle; -} - -div.body div.math p { - text-align: center; -} - -span.eqno { - float: right; -} - -/* -- printout stylesheet --------------------------------------------------- */ - -@media print { - div.document, - div.documentwrapper, - div.bodywrapper { - margin: 0 !important; - width: 100%; - } - - div.sphinxsidebar, - div.related, - div.footer, - #top-link { - display: none; - } -} diff --git a/Doc/tools/sphinxext/static/copybutton.js b/Doc/tools/static/copybutton.js similarity index 100% rename from Doc/tools/sphinxext/static/copybutton.js rename to Doc/tools/static/copybutton.js diff --git a/Doc/tools/sphinxext/static/py.png b/Doc/tools/static/py.png similarity index 100% rename from Doc/tools/sphinxext/static/py.png rename to Doc/tools/static/py.png diff --git a/Doc/tools/sphinxext/static/sidebar.js b/Doc/tools/static/sidebar.js similarity index 100% rename from Doc/tools/sphinxext/static/sidebar.js rename to Doc/tools/static/sidebar.js diff --git a/Doc/tools/sphinxext/static/version_switch.js b/Doc/tools/static/version_switch.js similarity index 93% rename from Doc/tools/sphinxext/static/version_switch.js rename to Doc/tools/static/version_switch.js index cc7be1c539d2..edb025b8abae 100644 --- a/Doc/tools/sphinxext/static/version_switch.js +++ b/Doc/tools/static/version_switch.js @@ -2,7 +2,8 @@ 'use strict'; var all_versions = { - '3.4': 'dev (3.4)', + '3.5': 'dev (3.5)', + '3.4': '3.4', '3.3': '3.3', '3.2': '3.2', '2.7': '2.7', @@ -49,7 +50,7 @@ window.location.href = new_url; }, error: function() { - window.location.href = 'http://docs.python.org/' + selected; + window.location.href = 'https://docs.python.org/' + selected; } }); } diff --git a/Doc/tools/sphinxext/susp-ignored.csv b/Doc/tools/susp-ignored.csv similarity index 95% rename from Doc/tools/sphinxext/susp-ignored.csv rename to Doc/tools/susp-ignored.csv index 67ad01f63b2a..9856afd99610 100644 --- a/Doc/tools/sphinxext/susp-ignored.csv +++ b/Doc/tools/susp-ignored.csv @@ -79,9 +79,8 @@ howto/logging,,:Started,INFO:root:Started howto/logging,,:This,DEBUG:root:This message should go to the log file howto/logging,,:This,DEBUG:This message should appear on the console howto/logging,,:Watch,WARNING:root:Watch out! -howto/pyporting,75,::,# make sure to use :: Python *and* :: Python :: 3 so -howto/pyporting,75,::,"'Programming Language :: Python'," -howto/pyporting,75,::,'Programming Language :: Python :: 3' +howto/pyporting,,::,Programming Language :: Python :: 2 +howto/pyporting,,::,Programming Language :: Python :: 3 howto/regex,,::, howto/regex,,:foo,(?:foo) howto/urllib2,,:example,"for example ""joe@password:example.com""" @@ -123,6 +122,8 @@ library/ipaddress,,:db8,>>> ipaddress.IPv6Address('2001:db8::1000') library/ipaddress,,::,>>> ipaddress.IPv6Address('2001:db8::1000') library/ipaddress,,:db8,IPv6Address('2001:db8::1000') library/ipaddress,,::,IPv6Address('2001:db8::1000') +library/ipaddress,,:db8,">>> ipaddress.ip_address(""2001:db8::1"").reverse_pointer" +library/ipaddress,,::,">>> ipaddress.ip_address(""2001:db8::1"").reverse_pointer" library/ipaddress,,::,"""::abc:7:def""" library/ipaddress,,:def,"""::abc:7:def""" library/ipaddress,,::,::FFFF/96 @@ -257,11 +258,11 @@ whatsnew/2.4,,:System, whatsnew/2.5,,:memory,:memory: whatsnew/2.5,,:step,[start:stop:step] whatsnew/2.5,,:stop,[start:stop:step] -whatsnew/2.7,1619,::,"ParseResult(scheme='http', netloc='[1080::8:800:200C:417A]'," -whatsnew/2.7,1619,::,>>> urlparse.urlparse('http://[1080::8:800:200C:417A]/foo') -whatsnew/2.7,735,:Sunday,'2009:4:Sunday' -whatsnew/2.7,862,:Cookie,"export PYTHONWARNINGS=all,error:::Cookie:0" -whatsnew/2.7,862,::,"export PYTHONWARNINGS=all,error:::Cookie:0" +whatsnew/2.7,,::,"ParseResult(scheme='http', netloc='[1080::8:800:200C:417A]'," +whatsnew/2.7,,::,>>> urlparse.urlparse('http://[1080::8:800:200C:417A]/foo') +whatsnew/2.7,,:Sunday,'2009:4:Sunday' +whatsnew/2.7,,:Cookie,"export PYTHONWARNINGS=all,error:::Cookie:0" +whatsnew/2.7,,::,"export PYTHONWARNINGS=all,error:::Cookie:0" whatsnew/3.2,,:affe,"netloc='[dead:beef:cafe:5417:affe:8FA3:deaf:feed]'," whatsnew/3.2,,:affe,>>> urllib.parse.urlparse('http://[dead:beef:cafe:5417:affe:8FA3:deaf:feed]/foo/') whatsnew/3.2,,:beef,"netloc='[dead:beef:cafe:5417:affe:8FA3:deaf:feed]'," @@ -277,8 +278,5 @@ whatsnew/3.2,,:feed,>>> urllib.parse.urlparse('http://[dead:beef:cafe:5417:affe: whatsnew/3.2,,:gz,">>> with tarfile.open(name='myarchive.tar.gz', mode='w:gz') as tf:" whatsnew/3.2,,:location,zope9-location = ${zope9:location} whatsnew/3.2,,:prefix,zope-conf = ${custom:prefix}/etc/zope.conf -whatsnew/changelog,,:platform,:platform: -whatsnew/changelog,,:PythonCmd,"With Tk < 8.5 _tkinter.c:PythonCmd() raised UnicodeDecodeError, caused" -whatsnew/changelog,,::,": Fix FTP tests for IPv6, bind to ""::1"" instead of ""localhost""." +whatsnew/changelog,,:gz,": TarFile opened with external fileobj and ""w:gz"" mode didn't" whatsnew/changelog,,::,": Use ""127.0.0.1"" or ""::1"" instead of ""localhost"" as much as" -whatsnew/changelog,,:password,user:password diff --git a/Doc/tools/sphinxext/download.html b/Doc/tools/templates/download.html similarity index 87% rename from Doc/tools/sphinxext/download.html rename to Doc/tools/templates/download.html index 31a53cfb3996..de84ae3abc81 100644 --- a/Doc/tools/sphinxext/download.html +++ b/Doc/tools/templates/download.html @@ -3,7 +3,7 @@ {% if daily is defined %} {% set dlbase = pathto('archives', 1) %} {% else %} - {% set dlbase = 'http://docs.python.org/ftp/python/doc/' + release %} + {% set dlbase = 'https://docs.python.org/ftp/python/doc/' + release %} {% endif %} {% block body %} @@ -34,15 +34,15 @@ <h1>Download Python {{ release }} Documentation</h1> <td><a href="{{ dlbase }}/python-{{ release }}-docs-text.tar.bz2">Download</a> (ca. 1.5 MB)</td> </tr> <tr><td>EPUB</td> - <td><a href="{{ dlbase }}/python-{{ release }}-docs-epub.zip">Download</a> (ca. 3.5 MB)</td> - <td><a href="{{ dlbase }}/python-{{ release }}-docs-epub.tar.bz2">Download</a> (ca. 3.5 MB)</td> + <td><a href="{{ dlbase }}/python-{{ release }}-docs.epub">Download</a> (ca. 4.5 MB)</td> + <td></td> </tr> </table> <p>These archives contain all the content in the documentation.</p> <p>HTML Help (<tt>.chm</tt>) files are made available in the "Windows" section -on the <a href="http://python.org/download/releases/{{ release[:5] }}/">Python +on the <a href="https://www.python.org/download/releases/{{ release[:5] }}/">Python download page</a>.</p> diff --git a/Doc/tools/sphinxext/indexcontent.html b/Doc/tools/templates/indexcontent.html similarity index 92% rename from Doc/tools/sphinxext/indexcontent.html rename to Doc/tools/templates/indexcontent.html index 7f8547020f1b..969099a00697 100644 --- a/Doc/tools/sphinxext/indexcontent.html +++ b/Doc/tools/templates/indexcontent.html @@ -16,14 +16,14 @@ <p class="biglink"><a class="biglink" href="{{ pathto("howto/index") }}">Python HOWTOs</a><br/> <span class="linkdescr">in-depth documents on specific topics</span></p> </td><td width="50%"> + <p class="biglink"><a class="biglink" href="{{ pathto("installing/index") }}">Installing Python Modules</a><br/> + <span class="linkdescr">installing from the Python Package Index & other sources</span></p> + <p class="biglink"><a class="biglink" href="{{ pathto("distributing/index") }}">Distributing Python Modules</a><br/> + <span class="linkdescr">publishing modules for installation by others</span></p> <p class="biglink"><a class="biglink" href="{{ pathto("extending/index") }}">Extending and Embedding</a><br/> <span class="linkdescr">tutorial for C/C++ programmers</span></p> <p class="biglink"><a class="biglink" href="{{ pathto("c-api/index") }}">Python/C API</a><br/> <span class="linkdescr">reference for C/C++ programmers</span></p> - <p class="biglink"><a class="biglink" href="{{ pathto("install/index") }}">Installing Python Modules</a><br/> - <span class="linkdescr">information for installers & sys-admins</span></p> - <p class="biglink"><a class="biglink" href="{{ pathto("distutils/index") }}">Distributing Python Modules</a><br/> - <span class="linkdescr">sharing modules with others</span></p> <p class="biglink"><a class="biglink" href="{{ pathto("faq/index") }}">FAQs</a><br/> <span class="linkdescr">frequently asked questions (with answers!)</span></p> </td></tr> diff --git a/Doc/tools/templates/indexsidebar.html b/Doc/tools/templates/indexsidebar.html new file mode 100644 index 000000000000..78e9c4f99ef0 --- /dev/null +++ b/Doc/tools/templates/indexsidebar.html @@ -0,0 +1,17 @@ +<h3>Download</h3> +<p><a href="{{ pathto('download') }}">Download these documents</a></p> +<h3>Docs for other versions</h3> +<ul> + <li><a href="https://docs.python.org/2.7/">Python 2.7 (stable)</a></li> + <li><a href="https://docs.python.org/3.4/">Python 3.4 (stable)</a></li> + <li><a href="https://www.python.org/doc/versions/">Old versions</a></li> +</ul> + +<h3>Other resources</h3> +<ul> + {# XXX: many of these should probably be merged in the main docs #} + <li><a href="https://www.python.org/dev/peps/">PEP Index</a></li> + <li><a href="https://wiki.python.org/moin/BeginnersGuide">Beginner's Guide</a></li> + <li><a href="https://wiki.python.org/moin/PythonBooks">Book List</a></li> + <li><a href="https://www.python.org/doc/av/">Audio/Visual Talks</a></li> +</ul> diff --git a/Doc/tools/sphinxext/layout.html b/Doc/tools/templates/layout.html similarity index 92% rename from Doc/tools/sphinxext/layout.html rename to Doc/tools/templates/layout.html index 16a92128d8ec..5abff1b3989f 100644 --- a/Doc/tools/sphinxext/layout.html +++ b/Doc/tools/templates/layout.html @@ -2,7 +2,7 @@ {% block rootrellink %} <li><img src="{{ pathto('_static/py.png', 1) }}" alt="" style="vertical-align: middle; margin-top: -1px"/></li> - <li><a href="http://www.python.org/">Python</a>{{ reldelim1 }}</li> + <li><a href="https://www.python.org/">Python</a>{{ reldelim1 }}</li> <li> {%- if versionswitcher is defined %} <span class="version_switcher_placeholder">{{ release }}</span> @@ -12,6 +12,8 @@ {%- endif %} </li> {% endblock %} +{% block relbar1 %} {% if builder != 'qthelp' %} {{ relbar() }} {% endif %} {% endblock %} +{% block relbar2 %} {% if builder != 'qthelp' %} {{ relbar() }} {% endif %} {% endblock %} {% block extrahead %} <link rel="shortcut icon" type="image/png" href="{{ pathto('_static/py.png', 1) }}" /> {% if not embedded %}<script type="text/javascript" src="{{ pathto('_static/copybutton.js', 1) }}"></script>{% endif %} @@ -80,7 +82,7 @@ © <a href="{{ pathto('copyright') }}">Copyright</a> {{ copyright|e }}. <br /> The Python Software Foundation is a non-profit corporation. - <a href="http://www.python.org/psf/donations/">Please donate.</a> + <a href="https://www.python.org/psf/donations/">Please donate.</a> <br /> Last updated on {{ last_updated|e }}. <a href="{{ pathto('bugs') }}">Found a bug</a>? diff --git a/Doc/tools/templates/opensearch.xml b/Doc/tools/templates/opensearch.xml new file mode 100644 index 000000000000..7a5cdddd2771 --- /dev/null +++ b/Doc/tools/templates/opensearch.xml @@ -0,0 +1,4 @@ +{% extends "!opensearch.xml" %} +{% block extra -%} +<Image height="16" width="16" type="image/x-icon">https://www.python.org/images/favicon16x16.ico</Image> +{%- endblock %} diff --git a/Doc/tutorial/appendix.rst b/Doc/tutorial/appendix.rst new file mode 100644 index 000000000000..67262a1d8053 --- /dev/null +++ b/Doc/tutorial/appendix.rst @@ -0,0 +1,124 @@ +.. _tut-appendix: + +******** +Appendix +******** + + +.. _tut-interac: + +Interactive Mode +================ + +.. _tut-error: + +Error Handling +-------------- + +When an error occurs, the interpreter prints an error message and a stack trace. +In interactive mode, it then returns to the primary prompt; when input came from +a file, it exits with a nonzero exit status after printing the stack trace. +(Exceptions handled by an :keyword:`except` clause in a :keyword:`try` statement +are not errors in this context.) Some errors are unconditionally fatal and +cause an exit with a nonzero exit; this applies to internal inconsistencies and +some cases of running out of memory. All error messages are written to the +standard error stream; normal output from executed commands is written to +standard output. + +Typing the interrupt character (usually Control-C or DEL) to the primary or +secondary prompt cancels the input and returns to the primary prompt. [#]_ +Typing an interrupt while a command is executing raises the +:exc:`KeyboardInterrupt` exception, which may be handled by a :keyword:`try` +statement. + + +.. _tut-scripts: + +Executable Python Scripts +------------------------- + +On BSD'ish Unix systems, Python scripts can be made directly executable, like +shell scripts, by putting the line :: + + #!/usr/bin/env python3.5 + +(assuming that the interpreter is on the user's :envvar:`PATH`) at the beginning +of the script and giving the file an executable mode. The ``#!`` must be the +first two characters of the file. On some platforms, this first line must end +with a Unix-style line ending (``'\n'``), not a Windows (``'\r\n'``) line +ending. Note that the hash, or pound, character, ``'#'``, is used to start a +comment in Python. + +The script can be given an executable mode, or permission, using the +:program:`chmod` command. + +.. code-block:: bash + + $ chmod +x myscript.py + +On Windows systems, there is no notion of an "executable mode". The Python +installer automatically associates ``.py`` files with ``python.exe`` so that +a double-click on a Python file will run it as a script. The extension can +also be ``.pyw``, in that case, the console window that normally appears is +suppressed. + + +.. _tut-startup: + +The Interactive Startup File +---------------------------- + +When you use Python interactively, it is frequently handy to have some standard +commands executed every time the interpreter is started. You can do this by +setting an environment variable named :envvar:`PYTHONSTARTUP` to the name of a +file containing your start-up commands. This is similar to the :file:`.profile` +feature of the Unix shells. + +This file is only read in interactive sessions, not when Python reads commands +from a script, and not when :file:`/dev/tty` is given as the explicit source of +commands (which otherwise behaves like an interactive session). It is executed +in the same namespace where interactive commands are executed, so that objects +that it defines or imports can be used without qualification in the interactive +session. You can also change the prompts ``sys.ps1`` and ``sys.ps2`` in this +file. + +If you want to read an additional start-up file from the current directory, you +can program this in the global start-up file using code like ``if +os.path.isfile('.pythonrc.py'): exec(open('.pythonrc.py').read())``. +If you want to use the startup file in a script, you must do this explicitly +in the script:: + + import os + filename = os.environ.get('PYTHONSTARTUP') + if filename and os.path.isfile(filename): + with open(filename) as fobj: + startup_file = fobj.read() + exec(startup_file) + + +.. _tut-customize: + +The Customization Modules +------------------------- + +Python provides two hooks to let you customize it: :mod:`sitecustomize` and +:mod:`usercustomize`. To see how it works, you need first to find the location +of your user site-packages directory. Start Python and run this code:: + + >>> import site + >>> site.getusersitepackages() + '/home/user/.local/lib/python3.5/site-packages' + +Now you can create a file named :file:`usercustomize.py` in that directory and +put anything you want in it. It will affect every invocation of Python, unless +it is started with the :option:`-s` option to disable the automatic import. + +:mod:`sitecustomize` works in the same way, but is typically created by an +administrator of the computer in the global site-packages directory, and is +imported before :mod:`usercustomize`. See the documentation of the :mod:`site` +module for more details. + + +.. rubric:: Footnotes + +.. [#] A problem with the GNU Readline package may prevent this. diff --git a/Doc/tutorial/classes.rst b/Doc/tutorial/classes.rst index 08072a31a129..7e014eff38f3 100644 --- a/Doc/tutorial/classes.rst +++ b/Doc/tutorial/classes.rst @@ -387,6 +387,77 @@ object and the argument list, and the function object is called with this new argument list. +.. _tut-class-and-instance-variables: + +Class and Instance Variables +---------------------------- + +Generally speaking, instance variables are for data unique to each instance +and class variables are for attributes and methods shared by all instances +of the class:: + + class Dog: + + kind = 'canine' # class variable shared by all instances + + def __init__(self, name): + self.name = name # instance variable unique to each instance + + >>> d = Dog('Fido') + >>> e = Dog('Buddy') + >>> d.kind # shared by all dogs + 'canine' + >>> e.kind # shared by all dogs + 'canine' + >>> d.name # unique to d + 'Fido' + >>> e.name # unique to e + 'Buddy' + +As discussed in :ref:`tut-object`, shared data can have possibly surprising +effects with involving :term:`mutable` objects such as lists and dictionaries. +For example, the *tricks* list in the following code should not be used as a +class variable because just a single list would be shared by all *Dog* +instances:: + + class Dog: + + tricks = [] # mistaken use of a class variable + + def __init__(self, name): + self.name = name + + def add_trick(self, trick): + self.tricks.append(trick) + + >>> d = Dog('Fido') + >>> e = Dog('Buddy') + >>> d.add_trick('roll over') + >>> e.add_trick('play dead') + >>> d.tricks # unexpectedly shared by all dogs + ['roll over', 'play dead'] + +Correct design of the class should use an instance variable instead:: + + class Dog: + + def __init__(self, name): + self.name = name + self.tricks = [] # creates a new empty list for each dog + + def add_trick(self, trick): + self.tricks.append(trick) + + >>> d = Dog('Fido') + >>> e = Dog('Buddy') + >>> d.add_trick('roll over') + >>> e.add_trick('play dead') + >>> d.tricks + ['roll over'] + >>> e.tricks + ['play dead'] + + .. _tut-remarks: Random Remarks @@ -572,7 +643,7 @@ class, that calls each parent only once, and that is monotonic (meaning that a class can be subclassed without affecting the precedence order of its parents). Taken together, these properties make it possible to design reliable and extensible classes with multiple inheritance. For more detail, see -http://www.python.org/download/releases/2.3/mro/. +https://www.python.org/download/releases/2.3/mro/. .. _tut-private: @@ -731,7 +802,7 @@ using a :keyword:`for` statement:: for char in "123": print(char) for line in open("myfile.txt"): - print(line) + print(line, end='') This style of access is clear, concise, and convenient. The use of iterators pervades and unifies Python. Behind the scenes, the :keyword:`for` statement @@ -798,7 +869,7 @@ Generators :term:`Generator`\s are a simple and powerful tool for creating iterators. They are written like regular functions but use the :keyword:`yield` statement whenever they want to return data. Each time :func:`next` is called on it, the -generator resumes where it left-off (it remembers all the data values and which +generator resumes where it left off (it remembers all the data values and which statement was last executed). An example shows that generators can be trivially easy to create:: @@ -816,7 +887,7 @@ easy to create:: o g -Anything that can be done with generators can also be done with class based +Anything that can be done with generators can also be done with class-based iterators as described in the previous section. What makes generators so compact is that the :meth:`__iter__` and :meth:`~generator.__next__` methods are created automatically. diff --git a/Doc/tutorial/controlflow.rst b/Doc/tutorial/controlflow.rst index b1456ae57f9f..ef50731a5b69 100644 --- a/Doc/tutorial/controlflow.rst +++ b/Doc/tutorial/controlflow.rst @@ -370,7 +370,7 @@ defined to allow. For example:: return False retries = retries - 1 if retries < 0: - raise IOError('refusenik user') + raise OSError('uncooperative user') print(complaint) This function can be called in several ways: @@ -756,4 +756,3 @@ extracted for you: .. [#] Actually, *call by object reference* would be a better description, since if a mutable object is passed, the caller will see any changes the callee makes to it (items inserted into a list). - diff --git a/Doc/tutorial/datastructures.rst b/Doc/tutorial/datastructures.rst index 24d2d2ec3aa3..a2031ed8673b 100644 --- a/Doc/tutorial/datastructures.rst +++ b/Doc/tutorial/datastructures.rst @@ -73,10 +73,11 @@ objects: Return the number of times *x* appears in the list. -.. method:: list.sort() +.. method:: list.sort(key=None, reverse=False) :noindex: - Sort the items of the list in place. + Sort the items of the list in place (the arguments can be used for sort + customization, see :func:`sorted` for their explanation). .. method:: list.reverse() @@ -111,10 +112,15 @@ An example that uses most of the list methods:: >>> a.sort() >>> a [-1, 1, 66.25, 333, 333, 1234.5] + >>> a.pop() + 1234.5 + >>> a + [-1, 1, 66.25, 333, 333] You might have noticed that methods like ``insert``, ``remove`` or ``sort`` that -modify the list have no return value printed -- they return ``None``. [1]_ This -is a design principle for all mutable data structures in Python. +only modify the list have no return value printed -- they return the default +``None``. [1]_ This is a design principle for all mutable data structures in +Python. .. _tut-lists-as-stacks: @@ -194,12 +200,17 @@ For example, assume we want to create a list of squares, like:: >>> squares [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] -We can obtain the same result with:: +Note that this creates (or overwrites) a variable named ``x`` that still exists +after the loop completes. We can calculate the list of squares without any +side effects using:: + + squares = list(map(lambda x: x**2, range(10))) + +or, equivalently:: squares = [x**2 for x in range(10)] -This is also equivalent to ``squares = list(map(lambda x: x**2, range(10)))``, -but it's more concise and readable. +which is more concise and readable. A list comprehension consists of brackets containing an expression followed by a :keyword:`for` clause, then zero or more :keyword:`for` or :keyword:`if` @@ -674,7 +685,7 @@ the same type, the lexicographical comparison is carried out recursively. If all items of two sequences compare equal, the sequences are considered equal. If one sequence is an initial sub-sequence of the other, the shorter sequence is the smaller (lesser) one. Lexicographical ordering for strings uses the Unicode -codepoint number to order individual characters. Some examples of comparisons +code point number to order individual characters. Some examples of comparisons between sequences of the same type:: (1, 2, 3) < (1, 2, 4) diff --git a/Doc/tutorial/errors.rst b/Doc/tutorial/errors.rst index 4282151589a0..d048ae9e1090 100644 --- a/Doc/tutorial/errors.rst +++ b/Doc/tutorial/errors.rst @@ -131,8 +131,8 @@ the exception (allowing a caller to handle the exception as well):: f = open('myfile.txt') s = f.readline() i = int(s.strip()) - except IOError as err: - print("I/O error: {0}".format(err)) + except OSError as err: + print("OS error: {0}".format(err)) except ValueError: print("Could not convert data to an integer.") except: diff --git a/Doc/tutorial/index.rst b/Doc/tutorial/index.rst index 604cff8af874..c14b1d6774ca 100644 --- a/Doc/tutorial/index.rst +++ b/Doc/tutorial/index.rst @@ -12,7 +12,7 @@ and rapid application development in many areas on most platforms. The Python interpreter and the extensive standard library are freely available in source or binary form for all major platforms from the Python Web site, -http://www.python.org/, and may be freely distributed. The same site also +https://www.python.org/, and may be freely distributed. The same site also contains distributions of and pointers to many free third party Python modules, programs and tools, and additional documentation. @@ -56,3 +56,4 @@ The :ref:`glossary` is also worth going through. whatnow.rst interactive.rst floatingpoint.rst + appendix.rst diff --git a/Doc/tutorial/inputoutput.rst b/Doc/tutorial/inputoutput.rst index 7daf89b79bf0..6f9c99daf9bb 100644 --- a/Doc/tutorial/inputoutput.rst +++ b/Doc/tutorial/inputoutput.rst @@ -323,8 +323,8 @@ first:: 18 ``f.tell()`` returns an integer giving the file object's current position in the file -represented as number of bytes from the beginning of the file when in `binary mode` and -an opaque number when in `text mode`. +represented as number of bytes from the beginning of the file when in binary mode and +an opaque number when in text mode. To change the file object's position, use ``f.seek(offset, from_what)``. The position is computed from adding *offset* to a reference point; the reference point is selected by @@ -377,47 +377,64 @@ File objects have some additional methods, such as :meth:`~file.isatty` and Reference for a complete guide to file objects. -.. _tut-pickle: +.. _tut-json: -The :mod:`pickle` Module ------------------------- +Saving structured data with :mod:`json` +--------------------------------------- -.. index:: module: pickle +.. index:: module: json -Strings can easily be written to and read from a file. Numbers take a bit more +Strings can easily be written to and read from a file. Numbers take a bit more effort, since the :meth:`read` method only returns strings, which will have to be passed to a function like :func:`int`, which takes a string like ``'123'`` -and returns its numeric value 123. However, when you want to save more complex -data types like lists, dictionaries, or class instances, things get a lot more -complicated. - -Rather than have users be constantly writing and debugging code to save -complicated data types, Python provides a standard module called :mod:`pickle`. -This is an amazing module that can take almost any Python object (even some -forms of Python code!), and convert it to a string representation; this process -is called :dfn:`pickling`. Reconstructing the object from the string -representation is called :dfn:`unpickling`. Between pickling and unpickling, -the string representing the object may have been stored in a file or data, or +and returns its numeric value 123. When you want to save more complex data +types like nested lists and dictionaries, parsing and serializing by hand +becomes complicated. + +Rather than having users constantly writing and debugging code to save +complicated data types to files, Python allows you to use the popular data +interchange format called `JSON (JavaScript Object Notation) +<http://json.org>`_. The standard module called :mod:`json` can take Python +data hierarchies, and convert them to string representations; this process is +called :dfn:`serializing`. Reconstructing the data from the string representation +is called :dfn:`deserializing`. Between serializing and deserializing, the +string representing the object may have been stored in a file or data, or sent over a network connection to some distant machine. -If you have an object ``x``, and a file object ``f`` that's been opened for -writing, the simplest way to pickle the object takes only one line of code:: +.. note:: + The JSON format is commonly used by modern applications to allow for data + exchange. Many programmers are already familiar with it, which makes + it a good choice for interoperability. - pickle.dump(x, f) +If you have an object ``x``, you can view its JSON string representation with a +simple line of code:: -To unpickle the object again, if ``f`` is a file object which has been opened -for reading:: + >>> json.dumps([1, 'simple', 'list']) + '[1, "simple", "list"]' - x = pickle.load(f) +Another variant of the :func:`~json.dumps` function, called :func:`~json.dump`, +simply serializes the object to a :term:`text file`. So if ``f`` is a +:term:`text file` object opened for writing, we can do this:: -(There are other variants of this, used when pickling many objects or when you -don't want to write the pickled data to a file; consult the complete -documentation for :mod:`pickle` in the Python Library Reference.) + json.dump(x, f) -:mod:`pickle` is the standard way to make Python objects which can be stored and -reused by other programs or by a future invocation of the same program; the -technical term for this is a :dfn:`persistent` object. Because :mod:`pickle` is -so widely used, many authors who write Python extensions take care to ensure -that new data types such as matrices can be properly pickled and unpickled. +To decode the object again, if ``f`` is a :term:`text file` object which has +been opened for reading:: + x = json.load(f) + +This simple serialization technique can handle lists and dictionaries, but +serializing arbitrary class instances in JSON requires a bit of extra effort. +The reference for the :mod:`json` module contains an explanation of this. + +.. seealso:: + + :mod:`pickle` - the pickle module + + Contrary to :ref:`JSON <tut-json>`, *pickle* is a protocol which allows + the serialization of arbitrarily complex Python objects. As such, it is + specific to Python and cannot be used to communicate with applications + written in other languages. It is also insecure by default: + deserializing pickle data coming from an untrusted source can execute + arbitrary code, if the data was crafted by a skilled attacker. diff --git a/Doc/tutorial/interpreter.rst b/Doc/tutorial/interpreter.rst index c182511ada3b..d5789a62c90e 100644 --- a/Doc/tutorial/interpreter.rst +++ b/Doc/tutorial/interpreter.rst @@ -10,13 +10,13 @@ Using the Python Interpreter Invoking the Interpreter ======================== -The Python interpreter is usually installed as :file:`/usr/local/bin/python3.4` +The Python interpreter is usually installed as :file:`/usr/local/bin/python3.5` on those machines where it is available; putting :file:`/usr/local/bin` in your Unix shell's search path makes it possible to start it by typing the command: .. code-block:: text - python3.4 + python3.5 to the shell. [#]_ Since the choice of the directory where the interpreter lives is an installation option, other places are possible; check with your local @@ -24,26 +24,25 @@ Python guru or system administrator. (E.g., :file:`/usr/local/python` is a popular alternative location.) On Windows machines, the Python installation is usually placed in -:file:`C:\\Python34`, though you can change this when you're running the +:file:`C:\\Python35`, though you can change this when you're running the installer. To add this directory to your path, you can type the following command into the command prompt in a DOS box:: - set path=%path%;C:\python34 + set path=%path%;C:\python35 Typing an end-of-file character (:kbd:`Control-D` on Unix, :kbd:`Control-Z` on Windows) at the primary prompt causes the interpreter to exit with a zero exit status. If that doesn't work, you can exit the interpreter by typing the following command: ``quit()``. -The interpreter's line-editing features usually aren't very sophisticated. On -Unix, whoever installed the interpreter may have enabled support for the GNU -readline library, which adds more elaborate interactive editing and history -features. Perhaps the quickest check to see whether command line editing is -supported is typing Control-P to the first Python prompt you get. If it beeps, -you have command line editing; see Appendix :ref:`tut-interacting` for an -introduction to the keys. If nothing appears to happen, or if ``^P`` is echoed, -command line editing isn't available; you'll only be able to use backspace to -remove characters from the current line. +The interpreter's line-editing features include interactive editing, history +substitution and code completion on systems that support readline. Perhaps the +quickest check to see whether command line editing is supported is typing +Control-P to the first Python prompt you get. If it beeps, you have command +line editing; see Appendix :ref:`tut-interacting` for an introduction to the +keys. If nothing appears to happen, or if ``^P`` is echoed, command line +editing isn't available; you'll only be able to use backspace to remove +characters from the current line. The interpreter operates somewhat like the Unix shell: when called with standard input connected to a tty device, it reads and executes commands interactively; @@ -64,6 +63,8 @@ When a script file is used, it is sometimes useful to be able to run the script and enter interactive mode afterwards. This can be done by passing :option:`-i` before the script. +All command line options are described in :ref:`using-on-general`. + .. _tut-argpassing: @@ -95,9 +96,9 @@ with the *secondary prompt*, by default three dots (``...``). The interpreter prints a welcome message stating its version number and a copyright notice before printing the first prompt:: - $ python3.4 - Python 3.4 (default, Sep 24 2012, 09:25:04) - [GCC 4.6.3] on linux2 + $ python3.5 + Python 3.5 (default, Sep 16 2015, 09:25:04) + [GCC 4.8.2] on linux Type "help", "copyright", "credits" or "license" for more information. >>> @@ -106,70 +107,22 @@ before printing the first prompt:: Continuation lines are needed when entering a multi-line construct. As an example, take a look at this :keyword:`if` statement:: - >>> the_world_is_flat = 1 + >>> the_world_is_flat = True >>> if the_world_is_flat: ... print("Be careful not to fall off!") ... Be careful not to fall off! +For more on interactive mode, see :ref:`tut-interac`. + + .. _tut-interp: The Interpreter and Its Environment =================================== -.. _tut-error: - -Error Handling --------------- - -When an error occurs, the interpreter prints an error message and a stack trace. -In interactive mode, it then returns to the primary prompt; when input came from -a file, it exits with a nonzero exit status after printing the stack trace. -(Exceptions handled by an :keyword:`except` clause in a :keyword:`try` statement -are not errors in this context.) Some errors are unconditionally fatal and -cause an exit with a nonzero exit; this applies to internal inconsistencies and -some cases of running out of memory. All error messages are written to the -standard error stream; normal output from executed commands is written to -standard output. - -Typing the interrupt character (usually Control-C or DEL) to the primary or -secondary prompt cancels the input and returns to the primary prompt. [#]_ -Typing an interrupt while a command is executing raises the -:exc:`KeyboardInterrupt` exception, which may be handled by a :keyword:`try` -statement. - - -.. _tut-scripts: - -Executable Python Scripts -------------------------- - -On BSD'ish Unix systems, Python scripts can be made directly executable, like -shell scripts, by putting the line :: - - #! /usr/bin/env python3.4 - -(assuming that the interpreter is on the user's :envvar:`PATH`) at the beginning -of the script and giving the file an executable mode. The ``#!`` must be the -first two characters of the file. On some platforms, this first line must end -with a Unix-style line ending (``'\n'``), not a Windows (``'\r\n'``) line -ending. Note that the hash, or pound, character, ``'#'``, is used to start a -comment in Python. - -The script can be given an executable mode, or permission, using the -:program:`chmod` command:: - - $ chmod +x myscript.py - -On Windows systems, there is no notion of an "executable mode". The Python -installer automatically associates ``.py`` files with ``python.exe`` so that -a double-click on a Python file will run it as a script. The extension can -also be ``.pyw``, in that case, the console window that normally appears is -suppressed. - - .. _tut-source-encoding: Source Code Encoding @@ -203,67 +156,8 @@ files. The special encoding comment must be in the *first or second* line within the file. -.. _tut-startup: - -The Interactive Startup File ----------------------------- - -When you use Python interactively, it is frequently handy to have some standard -commands executed every time the interpreter is started. You can do this by -setting an environment variable named :envvar:`PYTHONSTARTUP` to the name of a -file containing your start-up commands. This is similar to the :file:`.profile` -feature of the Unix shells. - -.. XXX This should probably be dumped in an appendix, since most people - don't use Python interactively in non-trivial ways. - -This file is only read in interactive sessions, not when Python reads commands -from a script, and not when :file:`/dev/tty` is given as the explicit source of -commands (which otherwise behaves like an interactive session). It is executed -in the same namespace where interactive commands are executed, so that objects -that it defines or imports can be used without qualification in the interactive -session. You can also change the prompts ``sys.ps1`` and ``sys.ps2`` in this -file. - -If you want to read an additional start-up file from the current directory, you -can program this in the global start-up file using code like ``if -os.path.isfile('.pythonrc.py'): exec(open('.pythonrc.py').read())``. -If you want to use the startup file in a script, you must do this explicitly -in the script:: - - import os - filename = os.environ.get('PYTHONSTARTUP') - if filename and os.path.isfile(filename): - exec(open(filename).read()) - - -.. _tut-customize: - -The Customization Modules -------------------------- - -Python provides two hooks to let you customize it: :mod:`sitecustomize` and -:mod:`usercustomize`. To see how it works, you need first to find the location -of your user site-packages directory. Start Python and run this code: - - >>> import site - >>> site.getusersitepackages() - '/home/user/.local/lib/python3.2/site-packages' - -Now you can create a file named :file:`usercustomize.py` in that directory and -put anything you want in it. It will affect every invocation of Python, unless -it is started with the :option:`-s` option to disable the automatic import. - -:mod:`sitecustomize` works in the same way, but is typically created by an -administrator of the computer in the global site-packages directory, and is -imported before :mod:`usercustomize`. See the documentation of the :mod:`site` -module for more details. - - .. rubric:: Footnotes .. [#] On Unix, the Python 3.x interpreter is by default not installed with the executable named ``python``, so that it does not conflict with a simultaneously installed Python 2.x executable. - -.. [#] A problem with the GNU Readline package may prevent this. diff --git a/Doc/tutorial/introduction.rst b/Doc/tutorial/introduction.rst index 4101cdc777e0..c073816d663e 100644 --- a/Doc/tutorial/introduction.rst +++ b/Doc/tutorial/introduction.rst @@ -58,7 +58,7 @@ For example:: The integer numbers (e.g. ``2``, ``4``, ``20``) have type :class:`int`, the ones with a fractional part (e.g. ``5.0``, ``1.6``) have type -:class:`float`. We will see more about numberic types later in the tutorial. +:class:`float`. We will see more about numeric types later in the tutorial. Division (``/``) always returns a float. To do :term:`floor division` and get an integer result (discarding any fractional result) you can use the ``//`` @@ -74,7 +74,7 @@ operator; to calculate the remainder you can use ``%``:: >>> 5 * 3 + 2 # result * divisor + remainder 17 -With Python is possible to use the ``**`` operator to calculate powers [#]_:: +With Python, it is possible to use the ``**`` operator to calculate powers [#]_:: >>> 5 ** 2 # 5 squared 25 @@ -305,7 +305,7 @@ indices, if both are within bounds. For example, the length of ``word[1:3]`` is Attempting to use a index that is too large will result in an error:: - >>> word[42] # the word only has 7 characters + >>> word[42] # the word only has 6 characters Traceback (most recent call last): File "<stdin>", line 1, in <module> IndexError: string index out of range @@ -371,9 +371,9 @@ values. The most versatile is the *list*, which can be written as a list of comma-separated values (items) between square brackets. Lists might contain items of different types, but usually the items all have the same type. :: - >>> squares = [1, 2, 4, 9, 16, 25] + >>> squares = [1, 4, 9, 16, 25] >>> squares - [1, 2, 4, 9, 16, 25] + [1, 4, 9, 16, 25] Like strings (and all other built-in :term:`sequence` type), lists can be indexed and sliced:: @@ -389,12 +389,12 @@ All slice operations return a new list containing the requested elements. This means that the following slice returns a new (shallow) copy of the list:: >>> squares[:] - [1, 2, 4, 9, 16, 25] + [1, 4, 9, 16, 25] -Lists also supports operations like concatenation:: +Lists also support operations like concatenation:: >>> squares + [36, 49, 64, 81, 100] - [1, 2, 4, 9, 16, 25, 36, 49, 64, 81, 100] + [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] Unlike strings, which are :term:`immutable`, lists are a :term:`mutable` type, i.e. it is possible to change their content:: diff --git a/Doc/tutorial/modules.rst b/Doc/tutorial/modules.rst index 94a66ac698d7..fd361aed695a 100644 --- a/Doc/tutorial/modules.rst +++ b/Doc/tutorial/modules.rst @@ -165,10 +165,16 @@ a built-in module with that name. If not found, it then searches for a file named :file:`spam.py` in a list of directories given by the variable :data:`sys.path`. :data:`sys.path` is initialized from these locations: -* the directory containing the input script (or the current directory). +* The directory containing the input script (or the current directory when no + file is specified). * :envvar:`PYTHONPATH` (a list of directory names, with the same syntax as the shell variable :envvar:`PATH`). -* the installation-dependent default. +* The installation-dependent default. + +.. note:: + On file systems which support symlinks, the directory containing the input + script is calculated after the symlink is followed. In other words the + directory containing the symlink is **not** added to the module search path. After initialization, Python programs can modify :data:`sys.path`. The directory containing the script being run is placed at the beginning of the diff --git a/Doc/tutorial/stdlib.rst b/Doc/tutorial/stdlib.rst index 2e3ed181d0e4..954ef4462ff9 100644 --- a/Doc/tutorial/stdlib.rst +++ b/Doc/tutorial/stdlib.rst @@ -15,7 +15,7 @@ operating system:: >>> import os >>> os.getcwd() # Return the current working directory - 'C:\\Python34' + 'C:\\Python35' >>> os.chdir('/server/accesslogs') # Change current working directory >>> os.system('mkdir today') # Run the command mkdir in the system shell 0 @@ -40,7 +40,9 @@ a higher level interface that is easier to use:: >>> import shutil >>> shutil.copyfile('data.db', 'archive.db') + 'archive.db' >>> shutil.move('/build/executables', 'installdir') + 'installdir' .. _tut-file-wildcards: diff --git a/Doc/tutorial/stdlib2.rst b/Doc/tutorial/stdlib2.rst index c0197ea5ef8c..f7d2a0ac2aa5 100644 --- a/Doc/tutorial/stdlib2.rst +++ b/Doc/tutorial/stdlib2.rst @@ -18,7 +18,7 @@ abbreviated displays of large or deeply nested containers:: >>> import reprlib >>> reprlib.repr(set('supercalifragilisticexpialidocious')) - "set(['a', 'c', 'd', 'e', 'f', 'g', ...])" + "{'a', 'c', 'd', 'e', 'f', 'g', ...}" The :mod:`pprint` module offers more sophisticated control over printing both built-in and user defined objects in a way that is readable by the interpreter. @@ -277,7 +277,7 @@ applications include caching objects that are expensive to create:: Traceback (most recent call last): File "<stdin>", line 1, in <module> d['primary'] # entry was automatically removed - File "C:/python34/lib/weakref.py", line 46, in __getitem__ + File "C:/python35/lib/weakref.py", line 46, in __getitem__ o = self.data[key]() KeyError: 'primary' diff --git a/Doc/tutorial/whatnow.rst b/Doc/tutorial/whatnow.rst index 7fcbdc3f4486..6b03cb5b207c 100644 --- a/Doc/tutorial/whatnow.rst +++ b/Doc/tutorial/whatnow.rst @@ -21,8 +21,8 @@ the set are: and many other tasks. Skimming through the Library Reference will give you an idea of what's available. -* :ref:`install-index` explains how to install external modules written by other - Python users. +* :ref:`installing-index` explains how to install additional modules written + by other Python users. * :ref:`reference-index`: A detailed explanation of Python's syntax and semantics. It's heavy reading, but is useful as a complete guide to the @@ -30,20 +30,20 @@ the set are: More Python resources: -* http://www.python.org: The major Python Web site. It contains code, +* https://www.python.org: The major Python Web site. It contains code, documentation, and pointers to Python-related pages around the Web. This Web site is mirrored in various places around the world, such as Europe, Japan, and Australia; a mirror may be faster than the main site, depending on your geographical location. -* http://docs.python.org: Fast access to Python's documentation. +* https://docs.python.org: Fast access to Python's documentation. -* http://pypi.python.org: The Python Package Index, previously also nicknamed +* https://pypi.python.org/pypi: The Python Package Index, previously also nicknamed the Cheese Shop, is an index of user-created Python modules that are available for download. Once you begin releasing code, you can register it here so that others can find it. -* http://aspn.activestate.com/ASPN/Python/Cookbook/: The Python Cookbook is a +* http://code.activestate.com/recipes/langs/python/: The Python Cookbook is a sizable collection of code examples, larger modules, and useful scripts. Particularly notable contributions are collected in a book also titled Python Cookbook (O'Reilly & Associates, ISBN 0-596-00797-3.) @@ -61,7 +61,7 @@ around 120 postings a day (with peaks up to several hundred), asking (and answering) questions, suggesting new features, and announcing new modules. Before posting, be sure to check the list of :ref:`Frequently Asked Questions <faq-index>` (also called the FAQ). -Mailing list archives are available at http://mail.python.org/pipermail/. +Mailing list archives are available at https://mail.python.org/pipermail/. The FAQ answers many of the questions that come up again and again, and may already contain the solution for your problem. diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index d1822fb2da62..4017ce897c6b 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -1,7 +1,7 @@ -.. highlightlang:: none +.. highlightlang:: sh .. ATTENTION: You probably should update Misc/python.man, too, if you modify -.. this file. + this file. .. _using-on-general: @@ -81,7 +81,8 @@ source. the implementation may not always enforce this (e.g. it may allow you to use a name that includes a hyphen). - Package names are also permitted. When a package name is supplied instead + Package names (including namespace packages) are also permitted. When a + package name is supplied instead of a normal module, the interpreter will execute ``<pkg>.__main__`` as the main module. This behaviour is deliberately similar to the handling of directories and zipfiles that are passed to the interpreter as the @@ -115,6 +116,9 @@ source. .. versionchanged:: 3.1 Supply the package name to run a ``__main__`` submodule. + .. versionchanged:: 3.4 + namespace packages are also supported + .. describe:: - @@ -144,6 +148,10 @@ source. added to the start of :data:`sys.path` and the ``__main__.py`` file in that location is executed as the :mod:`__main__` module. + .. seealso:: + :func:`runpy.run_path` + Equivalent functionality directly available to Python code + If no interface option is given, :option:`-i` is implied, ``sys.argv[0]`` is an empty string (``""``) and the current directory will be added to the @@ -151,11 +159,11 @@ start of :data:`sys.path`. Also, tab-completion and history editing is automatically enabled, if available on your platform (see :ref:`rlcompleter-config`). +.. seealso:: :ref:`tut-invoking` + .. versionchanged:: 3.4 Automatic enabling of tab-completion and history editing. -.. seealso:: :ref:`tut-invoking` - Generic options ~~~~~~~~~~~~~~~ @@ -407,7 +415,7 @@ Options you shouldn't use Reserved for use by Jython_. -.. _Jython: http://jython.org +.. _Jython: http://www.jython.org/ .. _using-on-envvars: @@ -464,14 +472,6 @@ conflict. :data:`sys.ps2` and the hook :data:`sys.__interactivehook__` in this file. -.. envvar:: PYTHONY2K - - Set this to a non-empty string to cause the :mod:`time` module to require - dates specified as strings to include 4-digit years, otherwise 2-digit years - are converted based on rules described in the :mod:`time` module - documentation. - - .. envvar:: PYTHONOPTIMIZE If this is set to a non-empty string it is equivalent to specifying the @@ -610,6 +610,14 @@ conflict. .. versionadded:: 3.4 +.. envvar:: PYTHONASYNCIODEBUG + + If this environment variable is set to a non-empty string, enable the + :ref:`debug mode <asyncio-debug-mode>` of the :mod:`asyncio` module. + + .. versionadded:: 3.4 + + Debug-mode variables ~~~~~~~~~~~~~~~~~~~~ diff --git a/Doc/using/mac.rst b/Doc/using/mac.rst index 5be439f3d615..ede864d7aded 100644 --- a/Doc/using/mac.rst +++ b/Doc/using/mac.rst @@ -19,7 +19,7 @@ Getting and Installing MacPython Mac OS X 10.8 comes with Python 2.7 pre-installed by Apple. If you wish, you are invited to install the most recent version of Python 3 from the Python -website (http://www.python.org). A current "universal binary" build of Python, +website (https://www.python.org). A current "universal binary" build of Python, which runs natively on the Mac's new Intel and legacy PPC CPU's, is available there. @@ -64,7 +64,7 @@ the Finder you first need an editor to create your script. Mac OS X comes with a number of standard Unix command line editors, :program:`vim` and :program:`emacs` among them. If you want a more Mac-like editor, :program:`BBEdit` or :program:`TextWrangler` from Bare Bones Software (see -http://www.barebones.com/products/bbedit/index.shtml) are good choices, as is +http://www.barebones.com/products/bbedit/index.html) are good choices, as is :program:`TextMate` (see http://macromates.com/). Other editors include :program:`Gvim` (http://macvim.org) and :program:`Aquamacs` (http://aquamacs.org/). @@ -116,7 +116,7 @@ The IDE MacPython ships with the standard IDLE development environment. A good introduction to using IDLE can be found at -http://hkn.eecs.berkeley.edu/~dyoo/python/idle_intro/index.html. +https://hkn.eecs.berkeley.edu/~dyoo/python/idle_intro/index.html. .. _mac-package-manager: @@ -130,7 +130,7 @@ There are several methods to install additional Python packages: setup.py install``). * Many packages can also be installed via the :program:`setuptools` extension - or :program:`pip` wrapper, see http://www.pip-installer.org/. + or :program:`pip` wrapper, see https://pip.pypa.io/. GUI Programming on the Mac @@ -140,7 +140,7 @@ There are several options for building GUI applications on the Mac with Python. *PyObjC* is a Python binding to Apple's Objective-C/Cocoa framework, which is the foundation of most modern Mac development. Information on PyObjC is -available from http://pyobjc.sourceforge.net. +available from https://pythonhosted.org/pyobjc/. The standard Python GUI toolkit is :mod:`tkinter`, based on the cross-platform Tk toolkit (http://www.tcl.tk). An Aqua-native version of Tk is bundled with OS @@ -174,9 +174,9 @@ Other Resources The MacPython mailing list is an excellent support resource for Python users and developers on the Mac: -http://www.python.org/community/sigs/current/pythonmac-sig/ +https://www.python.org/community/sigs/current/pythonmac-sig/ Another useful resource is the MacPython wiki: -http://wiki.python.org/moin/MacPython +https://wiki.python.org/moin/MacPython diff --git a/Doc/using/unix.rst b/Doc/using/unix.rst index 40635c6111ca..5da1f233466a 100644 --- a/Doc/using/unix.rst +++ b/Doc/using/unix.rst @@ -55,18 +55,19 @@ On FreeBSD and OpenBSD On OpenSolaris -------------- -To install the newest Python versions on OpenSolaris, install `blastwave -<http://www.blastwave.org/howto.html>`_ and type ``pkg_get -i python`` at the -prompt. +You can get Python from `OpenCSW <http://www.opencsw.org/>`_. Various versions +of Python are available and can be installed with e.g. ``pkgutil -i python27``. +.. _building-python-on-unix: + Building Python =============== If you want to compile CPython yourself, first thing you should do is get the -`source <http://python.org/download/source/>`_. You can download either the +`source <https://www.python.org/download/source/>`_. You can download either the latest release's source or just grab a fresh `clone -<http://docs.python.org/devguide/setup#getting-the-source-code>`_. (If you want +<https://docs.python.org/devguide/setup.html#getting-the-source-code>`_. (If you want to contribute patches, you will need a clone.) The build process consists in the usual :: @@ -144,5 +145,4 @@ Geany is an excellent IDE with support for a lot of languages. For more information, read: http://www.geany.org/ Komodo edit is another extremely good IDE. It also has support for a lot of -languages. For more information, read: -http://www.activestate.com/store/productdetail.aspx?prdGuid=20f4ed15-6684-4118-a78b-d37ff4058c5f +languages. For more information, read http://komodoide.com/. diff --git a/Doc/using/venv-create.inc b/Doc/using/venv-create.inc index 868bbc827be8..02bcbeeb7f2b 100644 --- a/Doc/using/venv-create.inc +++ b/Doc/using/venv-create.inc @@ -11,21 +11,26 @@ containing a copy of the ``python`` binary (or binaries, in the case of Windows). It also creates an (initially empty) ``lib/pythonX.Y/site-packages`` subdirectory (on Windows, this is ``Lib\site-packages``). +.. seealso:: + + `Python Packaging User Guide: Creating and using virtual environments + <https://packaging.python.org/en/latest/installing.html#virtual-environments>`__ + .. highlight:: none On Windows, you may have to invoke the ``pyvenv`` script as follows, if you don't have the relevant PATH and PATHEXT settings:: - c:\Temp>c:\Python33\python c:\Python33\Tools\Scripts\pyvenv.py myenv + c:\Temp>c:\Python35\python c:\Python35\Tools\Scripts\pyvenv.py myenv or equivalently:: - c:\Temp>c:\Python33\python -m venv myenv + c:\Temp>c:\Python35\python -m venv myenv The command, if run with ``-h``, will show the available options:: - usage: pyvenv [-h] [--system-site-packages] [--symlinks] [--clear] - [--upgrade] [--without-pip] ENV_DIR [ENV_DIR ...] + usage: venv [-h] [--system-site-packages] [--symlinks] [--clear] + [--upgrade] [--without-pip] ENV_DIR [ENV_DIR ...] Creates virtual Python environments in one or more target directories. @@ -38,6 +43,8 @@ The command, if run with ``-h``, will show the available options:: virtual environment. --symlinks Try to use symlinks rather than copies, when symlinks are not the default for the platform. + --copies Try to use copies rather than symlinks, even when + symlinks are the default for the platform. --clear Delete the environment directory if it already exists. If not specified and the directory exists, an error is raised. @@ -46,11 +53,18 @@ The command, if run with ``-h``, will show the available options:: --without-pip Skips installing or upgrading pip in the virtual environment (pip is bootstrapped by default) +Depending on how the ``venv`` functionality has been invoked, the usage message +may vary slightly, e.g. referencing ``pyvenv`` rather than ``venv``. + .. versionchanged:: 3.4 - Installs pip by default, added the ``--without-pip`` option + Installs pip by default, added the ``--without-pip`` and ``--copies`` + options -If the target directory already exists an error will be raised, unless -the ``--clear`` or ``--upgrade`` option was provided. +.. versionchanged:: 3.4 + In earlier versions, if the target directory already existed, an error was + raised, unless the ``--clear`` or ``--upgrade`` option was provided. Now, + if an existing directory is specified, its contents are removed and + the directory is processed as if it had been newly created. The created ``pyvenv.cfg`` file also includes the ``include-system-site-packages`` key, set to ``true`` if ``venv`` is @@ -92,3 +106,5 @@ a "deactivate" function, whereas on Windows there are separate scripts called ``deactivate.bat`` and ``Deactivate.ps1`` which are installed when the venv is created. +.. versionadded:: 3.4 + ``fish`` and ``csh`` activation scripts. diff --git a/Doc/using/win_installer.png b/Doc/using/win_installer.png new file mode 100644 index 000000000000..4696bb2a400e Binary files /dev/null and b/Doc/using/win_installer.png differ diff --git a/Doc/using/windows.rst b/Doc/using/windows.rst index 4dfe47b1c43f..af661969d047 100644 --- a/Doc/using/windows.rst +++ b/Doc/using/windows.rst @@ -7,37 +7,199 @@ ************************* .. sectionauthor:: Robert Lehmann <lehmannro@gmail.com> +.. sectionauthor:: Steve Dower <steve.dower@microsoft.com> This document aims to give an overview of Windows-specific behaviour you should know about when using Python on Microsoft Windows. +.. XXX (ncoghlan) + + This looks rather stale to me... + Installing Python ================= -Unlike most Unix systems and services, Windows does not require Python natively -and thus does not pre-install a version of Python. However, the CPython team +Unlike most Unix systems and services, Windows does not include a system +supported installation of Python. To make Python available, the CPython team has compiled Windows installers (MSI packages) with every `release -<http://www.python.org/download/releases/>`_ for many years. +<https://www.python.org/download/releases/>`_ for many years. These installers +are primarily intended to add a system-wide installation of Python, with the +core interpreter and library being shared by all application. Non-shared +layouts of the Python interpreter may also be created with the same installer, +however, the released installer is not intended for embedding in other +installers. + +Installation Steps +------------------ + +Four Python 3.5 installers are available for download - two each for the 32-bit +and 64-bit versions of the interpreter. The *web installer* is a small initial +download, and it will automatically download the required components as +necessary. The *offline installer* includes the components necessary for a +default installation and only requires an internet connection for optional +features. See :ref:`install-layout-option` for other ways to avoid downloading +during installation. + +After starting the installer, one of three options may be selected: + +.. image:: win_installer.png + +If you select "Install for All Users": + +* You may be required to provide administrative credentials or approval +* Python will be installed into your Program Files directory +* The :ref:`launcher` will be installed into your Windows directory +* The standard library, test suite, launcher and pip will be installed +* After installation, the standard library will be pre-compiled to bytecode +* If selected, the install directory will be added to :envvar:`PATH` + +If you select "Install Just for Me": + +* You will *not* need to be an administrator +* Python will be installed into your user directory +* The :ref:`launcher` will *also* be installed into your user directory +* The standard library, test suite, launcher and pip will be installed +* If selected, the install directory will be added to :envvar:`PATH` + +Selecting "Customize installation" will allow you to select the features to +install, the installation location and other options or post-install actions. +To install debugging symbols or binaries, you will need to use this option. + +.. _install-quiet-option: + +Installing Without UI +--------------------- + +All of the options available in the installer UI can also be specified from the +command line, allowing scripted installers to replicate an installation on many +machines without user interaction. These options may also be set without +suppressing the UI in order to change some of the defaults. + +To completely hide the installer UI and install Python silently, pass the +``/quiet`` (``/q``) option. To skip past the user interaction but still display +progress and errors, pass the ``/passive`` (``/p``) option. The ``/uninstall`` +option may be passed to immediately begin removing Python - no prompt will be +displayed. + +All other options are passed as ``name=value``, where the value is usually +``0`` to disable a feature, ``1`` to enable a feature, or a path. The full list +of available options is shown below. + ++---------------------------+--------------------------------------+--------------------------+ +| Name | Description | Default | ++===========================+======================================+==========================+ +| InstallAllUsers | Perform a system-wide installation. | 1 | ++---------------------------+--------------------------------------+--------------------------+ +| TargetDir | The installation directory | Selected based on | +| | | InstallAllUsers | ++---------------------------+--------------------------------------+--------------------------+ +| DefaultAllUsersTargetDir | The default installation directory | :file:`%ProgramFiles%\\\ | +| | for all-user installs | Python X.Y` or :file:`\ | +| | | %ProgramFiles(x86)%\\\ | +| | | Python X.Y` | ++---------------------------+--------------------------------------+--------------------------+ +| DefaultJustForMeTargetDir | The default install directory for | :file:`%LocalAppData%\\\ | +| | just-for-me installs | Programs\\PythonXY` or | +| | | :file:`%LocalAppData%\\\ | +| | | Programs\\PythonXY-32` | ++---------------------------+--------------------------------------+--------------------------+ +| DefaultCustomTargetDir | The default custom install directory | (empty) | +| | displayed in the UI | | ++---------------------------+--------------------------------------+--------------------------+ +| AssociateFiles | Create file associations if the | 1 | +| | launcher is also installed. | | ++---------------------------+--------------------------------------+--------------------------+ +| CompileAll | Compile all ``.py`` files to | 0 | +| | ``.pyc`` and ``.pyo``. | | ++---------------------------+--------------------------------------+--------------------------+ +| PrependPath | Add install and Scripts directories | 0 | +| | tho :envvar:`PATH` and ``.PY`` to | | +| | :envvar:`PATHEXT` | | ++---------------------------+--------------------------------------+--------------------------+ +| Include_doc | Install Python manual | 1 | ++---------------------------+--------------------------------------+--------------------------+ +| Include_debug | Install debug binaries | 0 | ++---------------------------+--------------------------------------+--------------------------+ +| Include_dev | Install developer headers and | 1 | +| | libraries | | ++---------------------------+--------------------------------------+--------------------------+ +| Include_exe | Install :file:`python.exe` and | 1 | +| | related files | | ++---------------------------+--------------------------------------+--------------------------+ +| Include_launcher | Install :ref:`launcher`. | 1 | ++---------------------------+--------------------------------------+--------------------------+ +| Include_lib | Install standard library and | 1 | +| | extension modules | | ++---------------------------+--------------------------------------+--------------------------+ +| Include_pip | Install bundled pip and setuptools | 1 | ++---------------------------+--------------------------------------+--------------------------+ +| Include_symbols | Install debugging symbols (`*`.pdb) | 0 | ++---------------------------+--------------------------------------+--------------------------+ +| Include_tcltk | Install Tcl/Tk support and IDLE | 1 | ++---------------------------+--------------------------------------+--------------------------+ +| Include_test | Install standard library test suite | 1 | ++---------------------------+--------------------------------------+--------------------------+ +| Include_tools | Install utility scripts | 1 | ++---------------------------+--------------------------------------+--------------------------+ +| SimpleInstall | Disable most install UI | 0 | ++---------------------------+--------------------------------------+--------------------------+ + +For example, to silently install a default, system-wide Python installation, +you could use the following command (from an elevated command prompt):: + + python-3.5.0.exe /quiet InstallAllUsers=1 PrependPath=1 Include_test=0 + +To allow users to easily install a personal copy of Python without the test +suite, you could provide a shortcut with the following command:: + + python-3.5.0.exe /passive InstallAllUsers=0 Include_launcher=0 Include_test=0 SimpleInstall=1 + +(Note that omitting the launcher also omits file associations, and is only +recommended for per-user installs when there is also a system-wide installation +that included the launcher.) + +.. _install-layout-option: + +Installing Without Downloading +------------------------------ + +As some features of Python are not included in the initial installer download, +selecting those features may require an internet connection. To avoid this +need, all possible components may be downloaded on-demand to create a complete +*layout* that will no longer require an internet connection regardless of the +selected features. Note that this download may be bigger than required, but +where a large number of installations are going to be performed it is very +useful to have a locally cached copy. + +Execute the following command from Command Prompt to download all possible +required files. Remember to substitute ``python-3.5.0.exe`` for the actual +name of your installer, and to create layouts in their own directories to +avoid collisions between files with the same name. + +:: + + python-3.5.0.exe /layout [optional target directory] + +You may also specify the ``/quiet`` option to hide the progress display. + + +Other Platforms +--------------- With ongoing development of Python, some platforms that used to be supported earlier are no longer supported (due to the lack of users or developers). Check :pep:`11` for details on all unsupported platforms. -* Up to 2.5, Python was still compatible with Windows 95, 98 and ME (but already - raised a deprecation warning on installation). For Python 2.6 (and all - following releases), this support was dropped and new releases are just - expected to work on the Windows NT family. * `Windows CE <http://pythonce.sourceforge.net/>`_ is still supported. -* The `Cygwin <http://cygwin.com/>`_ installer offers to install the `Python - interpreter <http://cygwin.com/packages/python>`_ as well; it is located under - "Interpreters." (cf. `Cygwin package source +* The `Cygwin <http://cygwin.com/>`_ installer offers to install the Python + interpreter as well (cf. `Cygwin package source <ftp://ftp.uni-erlangen.de/pub/pc/gnuwin32/cygwin/mirrors/cygnus/ release/python>`_, `Maintainer releases <http://www.tishler.net/jason/software/python/>`_) -See `Python for Windows (and DOS) <http://www.python.org/download/windows/>`_ -for detailed information about platforms with precompiled installers. +See `Python for Windows <https://www.python.org/download/windows/>`_ +for detailed information about platforms with pre-compiled installers. .. seealso:: @@ -45,15 +207,15 @@ for detailed information about platforms with precompiled installers. "7 Minutes to "Hello World!"" by Richard Dooling, 2006 - `Installing on Windows <http://diveintopython.net/installing_python/windows.html>`_ + `Installing on Windows <http://www.diveintopython.net/installing_python/windows.html>`_ in "`Dive into Python: Python from novice to pro - <http://diveintopython.net/index.html>`_" + <http://www.diveintopython.net/>`_" by Mark Pilgrim, 2004, ISBN 1-59059-356-1 - `For Windows users <http://swaroopch.com/text/Byte_of_Python:Installing_Python#For_Windows_users>`_ + `For Windows users <http://www.swaroopch.com/notes/python/#install_windows>`_ in "Installing Python" - in "`A Byte of Python <http://www.byteofpython.info>`_" + in "`A Byte of Python <http://www.swaroopch.com/notes/python/>`_" by Swaroop C H, 2003 @@ -64,22 +226,34 @@ Besides the standard CPython distribution, there are modified packages including additional functionality. The following is a list of popular versions and their key features: -`ActivePython <http://www.activestate.com/Products/activepython/>`_ +`ActivePython <http://www.activestate.com/activepython/>`_ Installer with multi-platform compatibility, documentation, PyWin32 -`Enthought Python Distribution <http://www.enthought.com/products/epd.php>`_ - Popular modules (such as PyWin32) with their respective documentation, tool - suite for building extensible Python applications +`Anaconda <http://www.continuum.io/downloads/>`_ + Popular scientific modules (such as numpy, scipy and pandas) and the + ``conda`` package manager. + +`Canopy <https://www.enthought.com/products/canopy/>`_ + A "comprehensive Python analysis environment" with editors and other + development tools. -Notice that these packages are likely to install *older* versions of Python. +`WinPython <https://winpython.github.io/>`_ + Windows-specific distribution with prebuilt scientific packages and + tools for building packages. + +Note that these packages may not include the latest versions of Python or +other libraries, and are not maintained or supported by the core Python team. Configuring Python ================== -In order to run Python flawlessly, you might have to change certain environment -settings in Windows. +To run Python conveniently from a command prompt, you might consider changing +some default environment variables in Windows. While the installer provides an +option to configure the PATH and PATHEXT variables for you, this is only +reliable for a single, system-wide installation. If you regularly use multiple +versions of Python, consider using the :ref:`launcher`. .. _setting-envvars: @@ -87,163 +261,86 @@ settings in Windows. Excursus: Setting environment variables --------------------------------------- -Windows has a built-in dialog for changing environment variables (following -guide applies to XP classical view): Right-click the icon for your machine -(usually located on your Desktop and called "My Computer") and choose -:menuselection:`Properties` there. Then, open the :guilabel:`Advanced` tab -and click the :guilabel:`Environment Variables` button. +Windows allows environment variables to be configured permanently at both the +User level and the System level, or temporarily in a command prompt. + +To temporarily set environment variables, open Command Prompt and use the +:command:`set` command:: + + C:\>set PATH=C:\Program Files\Python 3.5;%PATH% + C:\>set PYTHONPATH=%PYTHONPATH%;C:\My_python_lib + C:\>python -In short, your path is: +These changes will apply to any further commands executed in that console, and +will be inherited by any applications started from the console. - :menuselection:`My Computer - --> Properties - --> Advanced - --> Environment Variables` +Including the variable name within percent signs will expand to the existing +value, allowing you to add your new value at either the start or the end. +Modifying :envvar:`PATH` by adding the directory containing +:program:`python.exe` to the start is a common way to ensure the correct version +of Python is launched. +To permanently modify the default environment variables, click Start and search +for 'edit environment variables', or open System properties, :guilabel:`Advanced +system settings` and click the :guilabel:`Environment Variables` button. In this dialog, you can add or modify User and System variables. To change System variables, you need non-restricted access to your machine (i.e. Administrator rights). -Another way of adding variables to your environment is using the :command:`set` -command:: - - set PYTHONPATH=%PYTHONPATH%;C:\My_python_lib - -To make this setting permanent, you could add the corresponding command line to -your :file:`autoexec.bat`. :program:`msconfig` is a graphical interface to this -file. +.. note:: -Viewing environment variables can also be done more straight-forward: The -command prompt will expand strings wrapped into percent signs automatically:: + Windows will concatenate User variables *after* System variables, which may + cause unexpected results when modifying :envvar:`PATH`. - echo %PATH% - -Consult :command:`set /?` for details on this behaviour. + The :envvar:`PYTHONPATH` variable is used by all versions of Python 2 and + Python 3, so you should not permanently configure this variable unless it + only includes code that is compatible all of your installed Python + versions. .. seealso:: - http://support.microsoft.com/kb/100843 + http://support.microsoft.com/kb/100843 Environment variables in Windows NT - http://support.microsoft.com/kb/310519 + http://technet.microsoft.com/en-us/library/cc754250.aspx + The SET command, for temporarily modifying environment variables + + http://technet.microsoft.com/en-us/library/cc755104.aspx + The SETX command, for permanently modifying environment variables + + http://support.microsoft.com/kb/310519 How To Manage Environment Variables in Windows XP - http://www.chem.gla.ac.uk/~louis/software/faq/q1.html + http://www.chem.gla.ac.uk/~louis/software/faq/q1.html Setting Environment variables, Louis J. Farrugia - .. _windows-path-mod: Finding the Python executable ----------------------------- -.. versionchanged:: 3.3 +.. versionchanged:: 3.5 Besides using the automatically created start menu entry for the Python -interpreter, you might want to start Python in the command prompt. As of -Python 3.3, the installer has an option to set that up for you. - -At the "Customize Python 3.3" screen, an option called -"Add python.exe to search path" can be enabled to have the installer place -your installation into the :envvar:`%PATH%`. This allows you to type -:command:`python` to run the interpreter. Thus, you can also execute your +interpreter, you might want to start Python in the command prompt. The +installer for Python 3.5 and later has an option to set that up for you. + +On the first page of the installer, an option labelled "Add Python 3.5 to +PATH" can be selected to have the installer add the install location into the +:envvar:`PATH`. The location of the :file:`Scripts\\` folder is also added. +This allows you to type :command:`python` to run the interpreter, and +:command:`pip` or . Thus, you can also execute your scripts with command line options, see :ref:`using-on-cmdline` documentation. If you don't enable this option at install time, you can always re-run the -installer to choose it. - -The alternative is manually modifying the :envvar:`%PATH%` using the -directions in :ref:`setting-envvars`. You need to set your :envvar:`%PATH%` -environment variable to include the directory of your Python distribution, -delimited by a semicolon from other entries. An example variable could look -like this (assuming the first two entries are Windows' default):: - - C:\WINDOWS\system32;C:\WINDOWS;C:\Python33 - - -Finding modules ---------------- - -Python usually stores its library (and thereby your site-packages folder) in the -installation directory. So, if you had installed Python to -:file:`C:\\Python\\`, the default library would reside in -:file:`C:\\Python\\Lib\\` and third-party modules should be stored in -:file:`C:\\Python\\Lib\\site-packages\\`. - -This is how :data:`sys.path` is populated on Windows: - -* An empty entry is added at the start, which corresponds to the current - directory. - -* If the environment variable :envvar:`PYTHONPATH` exists, as described in - :ref:`using-on-envvars`, its entries are added next. Note that on Windows, - paths in this variable must be separated by semicolons, to distinguish them - from the colon used in drive identifiers (``C:\`` etc.). - -* Additional "application paths" can be added in the registry as subkeys of - :samp:`\\SOFTWARE\\Python\\PythonCore\\{version}\\PythonPath` under both the - ``HKEY_CURRENT_USER`` and ``HKEY_LOCAL_MACHINE`` hives. Subkeys which have - semicolon-delimited path strings as their default value will cause each path - to be added to :data:`sys.path`. (Note that all known installers only use - HKLM, so HKCU is typically empty.) - -* If the environment variable :envvar:`PYTHONHOME` is set, it is assumed as - "Python Home". Otherwise, the path of the main Python executable is used to - locate a "landmark file" (``Lib\os.py``) to deduce the "Python Home". If a - Python home is found, the relevant sub-directories added to :data:`sys.path` - (``Lib``, ``plat-win``, etc) are based on that folder. Otherwise, the core - Python path is constructed from the PythonPath stored in the registry. - -* If the Python Home cannot be located, no :envvar:`PYTHONPATH` is specified in - the environment, and no registry entries can be found, a default path with - relative entries is used (e.g. ``.\Lib;.\plat-win``, etc). - -The end result of all this is: - -* When running :file:`python.exe`, or any other .exe in the main Python - directory (either an installed version, or directly from the PCbuild - directory), the core path is deduced, and the core paths in the registry are - ignored. Other "application paths" in the registry are always read. - -* When Python is hosted in another .exe (different directory, embedded via COM, - etc), the "Python Home" will not be deduced, so the core path from the - registry is used. Other "application paths" in the registry are always read. - -* If Python can't find its home and there is no registry (eg, frozen .exe, some - very strange installation setup) you get a path with some default, but - relative, paths. - - -Executing scripts ------------------ - -As of Python 3.3, Python includes a launcher which facilitates running Python -scripts. See :ref:`launcher` for more information. - -Executing scripts without the Python launcher ---------------------------------------------- - -Without the Python launcher installed, Python scripts (files with the extension -``.py``) will be executed by :program:`python.exe` by default. This executable -opens a terminal, which stays open even if the program uses a GUI. If you do -not want this to happen, use the extension ``.pyw`` which will cause the script -to be executed by :program:`pythonw.exe` by default (both executables are -located in the top-level of your Python installation directory). This -suppresses the terminal window on startup. - -You can also make all ``.py`` scripts execute with :program:`pythonw.exe`, -setting this through the usual facilities, for example (might require -administrative rights): - -#. Launch a command prompt. -#. Associate the correct file group with ``.py`` scripts:: - - assoc .py=Python.File - -#. Redirect all Python files to the new executable:: - - ftype Python.File=C:\Path\to\pythonw.exe "%1" %* +installer, select Modify, and enable it. Alternatively, you can manually +modify the :envvar:`PATH` using the directions in :ref:`setting-envvars`. You +need to set your :envvar:`PATH` environment variable to include the directory +of your Python installation, delimited by a semicolon from other entries. An +example variable could look like this (assuming the first two entries already +existed):: + C:\WINDOWS\system32;C:\WINDOWS;C:\Program Files\Python 3.5 .. _launcher: @@ -252,21 +349,26 @@ Python Launcher for Windows .. versionadded:: 3.3 -The Python launcher for Windows is a utility which aids in the location and -execution of different Python versions. It allows scripts (or the +The Python launcher for Windows is a utility which aids in locating and +executing of different Python versions. It allows scripts (or the command-line) to indicate a preference for a specific Python version, and will locate and execute that version. +Unlike the :envvar:`PATH` variable, the launcher will correctly select the most +appropriate version of Python. It will prefer per-user installations over +system-wide ones, and orders by language version rather than using the most +recently installed version. + Getting started --------------- From the command-line ^^^^^^^^^^^^^^^^^^^^^ -You should ensure the launcher is on your PATH - depending on how it was -installed it may already be there, but check just in case it is not. - -From a command-prompt, execute the following command: +System-wide installations of Python 3.3 and later will put the launcher on your +:envvar:`PATH`. The launcher is compatible with all available versions of +Python, so it does not matter which version is installed. To check that the +launcher is available, execute the following command in Command Prompt: :: @@ -292,6 +394,16 @@ If you have a Python 3.x installed, try the command: You should find the latest version of Python 3.x starts. +If you see the following error, you do not have the launcher installed: + +:: + + 'py' is not recognized as an internal or external command, + operable program or batch file. + +Per-user installations of Python do not add the launcher to :envvar:`PATH` +unless the option was selected on installation. + From a script ^^^^^^^^^^^^^ @@ -384,17 +496,16 @@ Customization Customization via INI files ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Two .ini files will be searched by the launcher - ``py.ini`` in the - current user's "application data" directory (i.e. the directory returned - by calling the Windows function SHGetFolderPath with CSIDL_LOCAL_APPDATA) - and ``py.ini`` in the same directory as the launcher. The same .ini - files are used for both the 'console' version of the launcher (i.e. - py.exe) and for the 'windows' version (i.e. pyw.exe) +Two .ini files will be searched by the launcher - ``py.ini`` in the current +user's "application data" directory (i.e. the directory returned by calling the +Windows function SHGetFolderPath with CSIDL_LOCAL_APPDATA) and ``py.ini`` in the +same directory as the launcher. The same .ini files are used for both the +'console' version of the launcher (i.e. py.exe) and for the 'windows' version +(i.e. pyw.exe) - Customization specified in the "application directory" will have - precedence over the one next to the executable, so a user, who may not - have write access to the .ini file next to the launcher, can override - commands in that global .ini file) +Customization specified in the "application directory" will have precedence over +the one next to the executable, so a user, who may not have write access to the +.ini file next to the launcher, can override commands in that global .ini file) Customizing default Python versions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -489,6 +600,78 @@ particular version was chosen and the exact command-line used to execute the target Python. + +Finding modules +=============== + +Python usually stores its library (and thereby your site-packages folder) in the +installation directory. So, if you had installed Python to +:file:`C:\\Python\\`, the default library would reside in +:file:`C:\\Python\\Lib\\` and third-party modules should be stored in +:file:`C:\\Python\\Lib\\site-packages\\`. + +This is how :data:`sys.path` is populated on Windows: + +* An empty entry is added at the start, which corresponds to the current + directory. + +* If the environment variable :envvar:`PYTHONPATH` exists, as described in + :ref:`using-on-envvars`, its entries are added next. Note that on Windows, + paths in this variable must be separated by semicolons, to distinguish them + from the colon used in drive identifiers (``C:\`` etc.). + +* Additional "application paths" can be added in the registry as subkeys of + :samp:`\\SOFTWARE\\Python\\PythonCore\\{version}\\PythonPath` under both the + ``HKEY_CURRENT_USER`` and ``HKEY_LOCAL_MACHINE`` hives. Subkeys which have + semicolon-delimited path strings as their default value will cause each path + to be added to :data:`sys.path`. (Note that all known installers only use + HKLM, so HKCU is typically empty.) + +* If the environment variable :envvar:`PYTHONHOME` is set, it is assumed as + "Python Home". Otherwise, the path of the main Python executable is used to + locate a "landmark file" (``Lib\os.py``) to deduce the "Python Home". If a + Python home is found, the relevant sub-directories added to :data:`sys.path` + (``Lib``, ``plat-win``, etc) are based on that folder. Otherwise, the core + Python path is constructed from the PythonPath stored in the registry. + +* If the Python Home cannot be located, no :envvar:`PYTHONPATH` is specified in + the environment, and no registry entries can be found, a default path with + relative entries is used (e.g. ``.\Lib;.\plat-win``, etc). + +The end result of all this is: + +* When running :file:`python.exe`, or any other .exe in the main Python + directory (either an installed version, or directly from the PCbuild + directory), the core path is deduced, and the core paths in the registry are + ignored. Other "application paths" in the registry are always read. + +* When Python is hosted in another .exe (different directory, embedded via COM, + etc), the "Python Home" will not be deduced, so the core path from the + registry is used. Other "application paths" in the registry are always read. + +* If Python can't find its home and there is no registry (eg, frozen .exe, some + very strange installation setup) you get a path with some default, but + relative, paths. + +For those who want to bundle Python into their application or distribution, the +following advice will prevent conflicts with other installations: + +* If you are loading :file:`python3.dll` or :file:`python35.dll` in your own + executable, explicitly call :c:func:`Py_SetPath` or (at least) + :c:func:`Py_SetProgramName` before :c:func:`Py_Initialize`. + +* Clear and/or overwrite :envvar:`PYTHONPATH` and set :envvar:`PYTHONHOME` + before launching :file:`python.exe` from your application. + +* If you cannot use the previous suggestions (for example, you are a + distribution that allows people to run :file:`python.exe` directly), ensure + that the landmark file (:file:`Lib\\os.py`) exists in your bundled library. + (Note that it will not be detected inside a ZIP file.) + +These will ensure that the files in a system-wide installation will not take +precedence over the copy of the standard library bundled with your application. +Otherwise, your users may experience problems using your application. + Additional modules ================== @@ -499,7 +682,6 @@ and external, and snippets exist to use these features. The Windows-specific standard modules are documented in :ref:`mswin-specific-services`. - PyWin32 ------- @@ -515,7 +697,7 @@ utilities for: user interfaces `PythonWin <http://web.archive.org/web/20060524042422/ -http://www.python.org/windows/pythonwin/>`_ is a sample MFC application +https://www.python.org/windows/pythonwin/>`_ is a sample MFC application shipped with PyWin32. It is an embeddable IDE with a built-in debugger. .. seealso:: @@ -527,13 +709,14 @@ shipped with PyWin32. It is an embeddable IDE with a built-in debugger. by David and Paul Boddie -Py2exe ------- +cx_Freeze +--------- -`Py2exe <http://www.py2exe.org/>`_ is a :mod:`distutils` extension (see -:ref:`extending-distutils`) which wraps Python scripts into executable Windows -programs (:file:`{*}.exe` files). When you have done this, you can distribute -your application without requiring your users to install Python. +`cx_Freeze <http://cx-freeze.sourceforge.net/>`_ is a :mod:`distutils` +extension (see :ref:`extending-distutils`) which wraps Python scripts into +executable Windows programs (:file:`{*}.exe` files). When you have done this, +you can distribute your application without requiring your users to install +Python. WConio @@ -552,25 +735,13 @@ Compiling Python on Windows =========================== If you want to compile CPython yourself, first thing you should do is get the -`source <http://python.org/download/source/>`_. You can download either the +`source <https://www.python.org/download/source/>`_. You can download either the latest release's source or just grab a fresh `checkout -<http://docs.python.org/devguide/setup#checking-out-the-code>`_. +<https://docs.python.org/devguide/setup.html#getting-the-source-code>`_. The source tree contains a build solution and project files for Microsoft -Visual C++, which is the compiler used to build the official Python releases. -View the :file:`readme.txt` in their respective directories: - -+--------------------+--------------+-----------------------+ -| Directory | MSVC version | Visual Studio version | -+====================+==============+=======================+ -| :file:`PC/VS9.0/` | 9.0 | 2008 | -+--------------------+--------------+-----------------------+ -| :file:`PCbuild/` | 10.0 | 2010 | -+--------------------+--------------+-----------------------+ - -Note that any build directories within the :file:`PC` directory are not -necessarily fully supported. The :file:`PCbuild` directory contains the files -for the compiler used to build the official release. +Visual Studio 2015, which is the compiler used to build the official Python +releases. These files are in the :file:`PCbuild` directory. Check :file:`PCbuild/readme.txt` for general information on the build process. @@ -593,7 +764,7 @@ Other resources .. seealso:: - `Python Programming On Win32 <http://www.oreilly.com/catalog/pythonwin32/>`_ + `Python Programming On Win32 <http://shop.oreilly.com/product/9781565926219.do>`_ "Help for Windows Programmers" by Mark Hammond and Andy Robinson, O'Reilly Media, 2000, ISBN 1-56592-621-8 diff --git a/Doc/whatsnew/2.0.rst b/Doc/whatsnew/2.0.rst index 64b908b6e5dc..2c952acd119d 100644 --- a/Doc/whatsnew/2.0.rst +++ b/Doc/whatsnew/2.0.rst @@ -130,7 +130,7 @@ Guidelines": Read the rest of PEP 1 for the details of the PEP editorial process, style, and format. PEPs are kept in the Python CVS tree on SourceForge, though they're not part of the Python 2.0 distribution, and are also available in HTML form from -http://www.python.org/peps/. As of September 2000, there are 25 PEPS, ranging +https://www.python.org/peps/. As of September 2000, there are 25 PEPS, ranging from PEP 201, "Lockstep Iteration", to PEP 225, "Elementwise/Objectwise Operators". @@ -566,7 +566,7 @@ such as ``cmp(a,b)`` would always produce an answer, even if a user-defined simply be silently swallowed. .. Starting URL: -.. http://www.python.org/pipermail/python-dev/2000-April/004834.html +.. https://www.python.org/pipermail/python-dev/2000-April/004834.html Work has been done on porting Python to 64-bit Windows on the Itanium processor, mostly by Trent Mick of ActiveState. (Confusingly, ``sys.platform`` is still @@ -1003,7 +1003,7 @@ Relationship to PyXML The XML Special Interest Group has been working on XML-related Python code for a while. Its code distribution, called PyXML, is available from the SIG's Web -pages at http://www.python.org/sigs/xml-sig/. The PyXML distribution also used +pages at https://www.python.org/community/sigs/current/xml-sig. The PyXML distribution also used the package name ``xml``. If you've written programs that used PyXML, you're probably wondering about its compatibility with the 2.0 :mod:`xml` package. diff --git a/Doc/whatsnew/2.1.rst b/Doc/whatsnew/2.1.rst index b1ab48e7f4bf..ff1566226d05 100644 --- a/Doc/whatsnew/2.1.rst +++ b/Doc/whatsnew/2.1.rst @@ -219,7 +219,7 @@ comparison. I won't cover the C API here, but will refer you to PEP 207, or to .. seealso:: - :pep:`207` - Rich Comparisions + :pep:`207` - Rich Comparisons Written by Guido van Rossum, heavily based on earlier work by David Ascher, and implemented by Guido van Rossum. @@ -555,14 +555,14 @@ will include metadata, making it possible to build automated cataloguing systems and experiment with them. With the result experience, perhaps it'll be possible to design a really good catalog and then build support for it into Python 2.2. For example, the Distutils :command:`sdist` and :command:`bdist_\*` commands -could support a :option:`upload` option that would automatically upload your +could support a ``upload`` option that would automatically upload your package to a catalog server. You can start creating packages containing :file:`PKG-INFO` even if you're not using Python 2.1, since a new release of the Distutils will be made for users of earlier Python versions. Version 1.0.2 of the Distutils includes the changes described in PEP 241, as well as various bugfixes and enhancements. It will be -available from the Distutils SIG at http://www.python.org/sigs/distutils-sig/. +available from the Distutils SIG at https://www.python.org/sigs/distutils-sig/. .. seealso:: @@ -731,7 +731,7 @@ of the more notable changes are: ... For a fuller discussion of the line I/O changes, see the python-dev summary for - January 1-15, 2001 at http://www.python.org/dev/summary/2001-01-1/. + January 1-15, 2001 at https://www.python.org/dev/summary/2001-01-1/. * A new method, :meth:`popitem`, was added to dictionaries to enable destructively iterating through the contents of a dictionary; this can be faster diff --git a/Doc/whatsnew/2.2.rst b/Doc/whatsnew/2.2.rst index 31b6df439c69..f3c4a9134693 100644 --- a/Doc/whatsnew/2.2.rst +++ b/Doc/whatsnew/2.2.rst @@ -24,8 +24,8 @@ up irregularities and dark corners of the language design. This article doesn't attempt to provide a complete specification of the new features, but instead provides a convenient overview. For full details, you should refer to the documentation for Python 2.2, such as the `Python Library -Reference <http://www.python.org/doc/2.2/lib/lib.html>`_ and the `Python -Reference Manual <http://www.python.org/doc/2.2/ref/ref.html>`_. If you want to +Reference <https://www.python.org/doc/2.2/lib/lib.html>`_ and the `Python +Reference Manual <https://www.python.org/doc/2.2/ref/ref.html>`_. If you want to understand the complete implementation and design rationale for a change, refer to the PEP for a particular new feature. @@ -395,7 +395,7 @@ This section has just been a quick overview of the new features, giving enough of an explanation to start you programming, but many details have been simplified or ignored. Where should you go to get a more complete picture? -http://www.python.org/2.2/descrintro.html is a lengthy tutorial introduction to +https://www.python.org/2.2/descrintro.html is a lengthy tutorial introduction to the descriptor features, written by Guido van Rossum. If my description has whetted your appetite, go read this tutorial next, because it goes into much more detail about the new features while still remaining quite easy to read. diff --git a/Doc/whatsnew/2.3.rst b/Doc/whatsnew/2.3.rst index f0e48d972249..f478c090b135 100644 --- a/Doc/whatsnew/2.3.rst +++ b/Doc/whatsnew/2.3.rst @@ -657,7 +657,7 @@ The heart of the catalog is the new Distutils :command:`register` command. Running ``python setup.py register`` will collect the metadata describing a package, such as its name, version, maintainer, description, &c., and send it to a central catalog server. The resulting catalog is available from -http://www.python.org/pypi. +https://pypi.python.org/pypi. To make the catalog a bit more useful, a new optional *classifiers* keyword argument has been added to the Distutils :func:`setup` function. A list of @@ -1082,9 +1082,9 @@ Here are all of the changes that Python 2.3 makes to the core Python language. C3 algorithm as described in the paper `"A Monotonic Superclass Linearization for Dylan" <http://www.webcom.com/haahr/dylan/linearization-oopsla96.html>`_. To understand the motivation for this change, read Michele Simionato's article - `"Python 2.3 Method Resolution Order" <http://www.python.org/2.3/mro.html>`_, or + `"Python 2.3 Method Resolution Order" <https://www.python.org/2.3/mro.html>`_, or read the thread on python-dev starting with the message at - http://mail.python.org/pipermail/python-dev/2002-October/029035.html. Samuele + https://mail.python.org/pipermail/python-dev/2002-October/029035.html. Samuele Pedroni first pointed out the problem and also implemented the fix by coding the C3 algorithm. @@ -1330,7 +1330,7 @@ complete list of changes, or look through the CVS logs for all the details. (Contributed by Kevin O'Connor.) * The IDLE integrated development environment has been updated using the code - from the IDLEfork project (http://idlefork.sf.net). The most notable feature is + from the IDLEfork project (http://idlefork.sourceforge.net). The most notable feature is that the code being developed is now executed in a subprocess, meaning that there's no longer any need for manual ``reload()`` operations. IDLE's core code has been incorporated into the standard library as the :mod:`idlelib` package. @@ -1564,7 +1564,7 @@ complete list of changes, or look through the CVS logs for all the details. to the correct thread, and waiting for the results. Other interfaces can't be handled automatically but :mod:`Tkinter` will now raise an exception on such an access so that you can at least find out about the problem. See - http://mail.python.org/pipermail/python-dev/2002-December/031107.html for a more + https://mail.python.org/pipermail/python-dev/2002-December/031107.html for a more detailed explanation of this change. (Implemented by Martin von Löwis.) * Calling Tcl methods through :mod:`_tkinter` no longer returns only strings. @@ -1858,7 +1858,7 @@ and bundle it with the source of your extension. .. seealso:: - http://svn.python.org/view/python/trunk/Objects/obmalloc.c + https://svn.python.org/view/python/trunk/Objects/obmalloc.c For the full details of the pymalloc implementation, see the comments at the top of the file :file:`Objects/obmalloc.c` in the Python source code. The above link points to the file within the python.org SVN browser. diff --git a/Doc/whatsnew/2.4.rst b/Doc/whatsnew/2.4.rst index 5a28f891acdb..569e5e925fa9 100644 --- a/Doc/whatsnew/2.4.rst +++ b/Doc/whatsnew/2.4.rst @@ -337,7 +337,7 @@ returned. wrote patches implementing function decorators, but the one that was actually checked in was patch #979728, written by Mark Russell. - http://www.python.org/moin/PythonDecoratorLibrary + https://www.python.org/moin/PythonDecoratorLibrary This Wiki page contains several examples of decorators. .. ====================================================================== @@ -846,7 +846,7 @@ Here are all of the changes that Python 2.4 makes to the core Python language. ['A', 'b', 'c', 'D'] Finally, the *reverse* parameter takes a Boolean value. If the value is true, - the list will be sorted into reverse order. Instead of ``L.sort() ; + the list will be sorted into reverse order. Instead of ``L.sort(); L.reverse()``, you can now write ``L.sort(reverse=True)``. The results of sorting are now guaranteed to be stable. This means that two diff --git a/Doc/whatsnew/2.5.rst b/Doc/whatsnew/2.5.rst index b91e6479e412..f8f7ca04a909 100644 --- a/Doc/whatsnew/2.5.rst +++ b/Doc/whatsnew/2.5.rst @@ -39,7 +39,7 @@ finds there were 353 patches applied and 458 bugs fixed between Python 2.4 and This article doesn't try to be a complete specification of the new features; instead changes are briefly introduced using helpful examples. For full details, you should always refer to the documentation for Python 2.5 at -http://docs.python.org. If you want to understand the complete implementation +https://docs.python.org. If you want to understand the complete implementation and design rationale, refer to the PEP for a particular new feature. Comments, suggestions, and error reports for this document are welcome; please @@ -229,7 +229,7 @@ required packages. :: ) Another new enhancement to the Python package index at -http://cheeseshop.python.org is storing source and binary archives for a +https://pypi.python.org is storing source and binary archives for a package. The new :command:`upload` Distutils command will upload a package to the repository. @@ -286,7 +286,7 @@ Python's standard :mod:`string` module? There's no clean way to ignore :mod:`pkg.string` and look for the standard module; generally you had to look at the contents of ``sys.modules``, which is slightly unclean. Holger Krekel's :mod:`py.std` package provides a tidier way to perform imports from the standard -library, ``import py ; py.std.string.join()``, but that package isn't available +library, ``import py; py.std.string.join()``, but that package isn't available on all Python installations. Reading code which relies on relative imports is also less clear, because a @@ -2130,7 +2130,7 @@ Changes to Python's build process and to the C API include: such as PyCon. .. List of names taken from Jeremy's python-dev post at - .. http://mail.python.org/pipermail/python-dev/2005-October/057500.html + .. https://mail.python.org/pipermail/python-dev/2005-October/057500.html * Evan Jones's patch to obmalloc, first described in a talk at PyCon DC 2005, was applied. Python 2.4 allocated small objects in 256K-sized arenas, but never diff --git a/Doc/whatsnew/2.6.rst b/Doc/whatsnew/2.6.rst index bdd7ff7d8166..e7632652693b 100644 --- a/Doc/whatsnew/2.6.rst +++ b/Doc/whatsnew/2.6.rst @@ -164,7 +164,7 @@ is an open-source project that requires volunteers to administer it and a server to host it. After posting a call for volunteers, a new Roundup installation was -set up at http://bugs.python.org. One installation of Roundup can +set up at https://bugs.python.org. One installation of Roundup can host multiple trackers, and this server now also hosts issue trackers for Jython and for the Python web site. It will surely find other uses in the future. Where possible, @@ -181,7 +181,7 @@ other projects wishing to move from SourceForge to Roundup. .. seealso:: - http://bugs.python.org + https://bugs.python.org The Python bug tracker. http://bugs.jython.org: @@ -227,18 +227,18 @@ the Python community. Sphinx is a standalone package that can be used for writing, and almost two dozen other projects -(`listed on the Sphinx web site <http://sphinx.pocoo.org/examples.html>`__) +(`listed on the Sphinx web site <http://sphinx-doc.org/examples.html>`__) have adopted Sphinx as their documentation tool. .. seealso:: - `Documenting Python <http://docs.python.org/devguide/documenting.html>`__ + `Documenting Python <https://docs.python.org/devguide/documenting.html>`__ Describes how to write for Python's documentation. - `Sphinx <http://sphinx.pocoo.org/>`__ + `Sphinx <http://sphinx-doc.org/>`__ Documentation and code for the Sphinx toolchain. - `Docutils <http://docutils.sf.net>`__ + `Docutils <http://docutils.sourceforge.net>`__ The underlying reStructuredText parser and toolset. @@ -1891,7 +1891,7 @@ changes, or look through the Subversion logs for all the details. >>> dq=deque(maxlen=3) >>> dq deque([], maxlen=3) - >>> dq.append(1) ; dq.append(2) ; dq.append(3) + >>> dq.append(1); dq.append(2); dq.append(3) >>> dq deque([1, 2, 3], maxlen=3) >>> dq.append(4) @@ -2363,7 +2363,7 @@ changes, or look through the Subversion logs for all the details. negotiation itself. (Patch contributed by Bill Fenner; :issue:`829951`.) -* The :mod:`socket` module now supports TIPC (http://tipc.sf.net), +* The :mod:`socket` module now supports TIPC (http://tipc.sourceforge.net/), a high-performance non-IP-based protocol designed for use in clustered environments. TIPC addresses are 4- or 5-tuples. (Contributed by Alberto Bertogli; :issue:`1646`.) @@ -2783,12 +2783,12 @@ http://www.json.org. types. The following example encodes and decodes a dictionary:: >>> import json - >>> data = {"spam" : "foo", "parrot" : 42} + >>> data = {"spam": "foo", "parrot": 42} >>> in_json = json.dumps(data) # Encode the data >>> in_json '{"parrot": 42, "spam": "foo"}' >>> json.loads(in_json) # Decode into a Python object - {"spam" : "foo", "parrot" : 42} + {"spam": "foo", "parrot": 42} It's also possible to write your own decoders and encoders to support more types. Pretty-printing of the JSON strings is also supported. diff --git a/Doc/whatsnew/2.7.rst b/Doc/whatsnew/2.7.rst index b26c9b27bedf..ed1446c25705 100644 --- a/Doc/whatsnew/2.7.rst +++ b/Doc/whatsnew/2.7.rst @@ -7,7 +7,6 @@ .. hyperlink all the methods & functions. .. T_STRING_INPLACE not described in main docs -.. "Format String Syntax" in string.rst could use many more examples. .. $Id$ Rules for maintenance: @@ -50,17 +49,16 @@ This saves the maintainer some effort going through the SVN logs when researching a change. -This article explains the new features in Python 2.7. The final -release of 2.7 is currently scheduled for July 2010; the detailed -schedule is described in :pep:`373`. +This article explains the new features in Python 2.7. Python 2.7 was released +on July 3, 2010. Numeric handling has been improved in many ways, for both -floating-point numbers and for the :class:`Decimal` class. There are -some useful additions to the standard library, such as a greatly -enhanced :mod:`unittest` module, the :mod:`argparse` module for -parsing command-line options, convenient ordered-dictionary and -:class:`Counter` classes in the :mod:`collections` module, and many -other improvements. +floating-point numbers and for the :class:`~decimal.Decimal` class. +There are some useful additions to the standard library, such as a +greatly enhanced :mod:`unittest` module, the :mod:`argparse` module +for parsing command-line options, convenient :class:`~collections.OrderedDict` +and :class:`~collections.Counter` classes in the :mod:`collections` module, +and many other improvements. Python 2.7 is planned to be the last of the 2.x releases, so we worked on making it a good release for the long term. To help with porting @@ -70,9 +68,9 @@ included in 2.7. This article doesn't attempt to provide a complete specification of the new features, but instead provides a convenient overview. For full details, you should refer to the documentation for Python 2.7 at -http://docs.python.org. If you want to understand the rationale for +https://docs.python.org. If you want to understand the rationale for the design and implementation, refer to the PEP for a particular new -feature or the issue on http://bugs.python.org in which a change was +feature or the issue on https://bugs.python.org in which a change was discussed. Whenever possible, "What's New in Python" links to the bug/patch item for each change. @@ -81,45 +79,91 @@ bug/patch item for each change. The Future for Python 2.x ========================= -Python 2.7 is intended to be the last major release in the 2.x series. -The Python maintainers are planning to focus their future efforts on -the Python 3.x series. - -This means that 2.7 will remain in place for a long time, running -production systems that have not been ported to Python 3.x. -Two consequences of the long-term significance of 2.7 are: - -* It's very likely the 2.7 release will have a longer period of - maintenance compared to earlier 2.x versions. Python 2.7 will - continue to be maintained while the transition to 3.x continues, and - the developers are planning to support Python 2.7 with bug-fix - releases beyond the typical two years. - -* A policy decision was made to silence warnings only of interest to - developers. :exc:`DeprecationWarning` and its - descendants are now ignored unless otherwise requested, preventing - users from seeing warnings triggered by an application. This change - was also made in the branch that will become Python 3.2. (Discussed - on stdlib-sig and carried out in :issue:`7319`.) - - In previous releases, :exc:`DeprecationWarning` messages were - enabled by default, providing Python developers with a clear - indication of where their code may break in a future major version - of Python. - - However, there are increasingly many users of Python-based - applications who are not directly involved in the development of - those applications. :exc:`DeprecationWarning` messages are - irrelevant to such users, making them worry about an application - that's actually working correctly and burdening application developers - with responding to these concerns. - - You can re-enable display of :exc:`DeprecationWarning` messages by - running Python with the :option:`-Wdefault` (short form: - :option:`-Wd`) switch, or by setting the :envvar:`PYTHONWARNINGS` - environment variable to ``"default"`` (or ``"d"``) before running - Python. Python code can also re-enable them - by calling ``warnings.simplefilter('default')``. +Python 2.7 is the last major release in the 2.x series, as the Python +maintainers have shifted the focus of their new feature development efforts +to the Python 3.x series. This means that while Python 2 continues to +receive bug fixes, and to be updated to build correctly on new hardware and +versions of supported operated systems, there will be no new full feature +releases for the language or standard library. + +However, while there is a large common subset between Python 2.7 and Python +3, and many of the changes involved in migrating to that common subset, or +directly to Python 3, can be safely automated, some other changes (notably +those associated with Unicode handling) may require careful consideration, +and preferably robust automated regression test suites, to migrate +effectively. + +This means that Python 2.7 will remain in place for a long time, providing a +stable and supported base platform for production systems that have not yet +been ported to Python 3. The full expected lifecycle of the Python 2.7 +series is detailed in :pep:`373`. + +Some key consequences of the long-term significance of 2.7 are: + +* As noted above, the 2.7 release has a much longer period of maintenance + when compared to earlier 2.x versions. Python 2.7 is currently expected to + remain supported by the core development team (receiving security updates + and other bug fixes) until at least 2020 (10 years after its initial + release, compared to the more typical support period of 18-24 months). + +* As the Python 2.7 standard library ages, making effective use of the + Python Package Index (either directly or via a redistributor) becomes + more important for Python 2 users. In addition to a wide variety of third + party packages for various tasks, the available packages include backports + of new modules and features from the Python 3 standard library that are + compatible with Python 2, as well as various tools and libraries that can + make it easier to migrate to Python 3. The `Python Packaging User Guide + <https://packaging.python.org>`__ provides guidance on downloading and + installing software from the Python Package Index. + +* While the preferred approach to enhancing Python 2 is now the publication + of new packages on the Python Package Index, this approach doesn't + necessarily work in all cases, especially those related to network + security. In exceptional cases that cannot be handled adequately by + publishing new or updated packages on PyPI, the Python Enhancement + Proposal process may be used to make the case for adding new features + directly to the Python 2 standard library. Any such additions, and the + maintenance releases where they were added, will be noted in the + :ref:`py27-maintenance-enhancements` section below. + +For projects wishing to migrate from Python 2 to Python 3, or for library +and framework developers wishing to support users on both Python 2 and +Python 3, there are a variety of tools and guides available to help decide +on a suitable approach and manage some of the technical details involved. +The recommended starting point is the :ref:`pyporting-howto` HOWTO guide. + + +Changes to the Handling of Deprecation Warnings +=============================================== + +For Python 2.7, a policy decision was made to silence warnings only of +interest to developers by default. :exc:`DeprecationWarning` and its +descendants are now ignored unless otherwise requested, preventing +users from seeing warnings triggered by an application. This change +was also made in the branch that became Python 3.2. (Discussed +on stdlib-sig and carried out in :issue:`7319`.) + +In previous releases, :exc:`DeprecationWarning` messages were +enabled by default, providing Python developers with a clear +indication of where their code may break in a future major version +of Python. + +However, there are increasingly many users of Python-based +applications who are not directly involved in the development of +those applications. :exc:`DeprecationWarning` messages are +irrelevant to such users, making them worry about an application +that's actually working correctly and burdening application developers +with responding to these concerns. + +You can re-enable display of :exc:`DeprecationWarning` messages by +running Python with the :option:`-Wdefault <-W>` (short form: +:option:`-Wd <-W>`) switch, or by setting the :envvar:`PYTHONWARNINGS` +environment variable to ``"default"`` (or ``"d"``) before running +Python. Python code can also re-enable them +by calling ``warnings.simplefilter('default')``. + +The ``unittest`` module also automatically reenables deprecation warnings +when running tests. Python 3.1 Features @@ -133,7 +177,7 @@ for migrating to the 3.x series. A partial list of 3.1 features that were backported to 2.7: * The syntax for set literals (``{1,2,3}`` is a mutable set). -* Dictionary and set comprehensions (``{ i: i*2 for i in range(3)}``). +* Dictionary and set comprehensions (``{i: i*2 for i in range(3)}``). * Multiple context managers in a single :keyword:`with` statement. * A new version of the :mod:`io` library, rewritten in C for performance. * The ordered-dictionary type described in :ref:`pep-0372`. @@ -155,7 +199,7 @@ Other new Python3-mode warnings include: * :func:`operator.isCallable` and :func:`operator.sequenceIncludes`, which are not supported in 3.x, now trigger warnings. * The :option:`-3` switch now automatically - enables the :option:`-Qwarn` switch that causes warnings + enables the :option:`-Qwarn <-Q>` switch that causes warnings about using classic division with integers and long integers. @@ -390,9 +434,10 @@ standard input or output. .. seealso:: - `argparse module documentation <http://docs.python.org/dev/library/argparse.html>`__ + :mod:`argparse` documentation + The documentation page of the argparse module. - `Upgrading optparse code to use argparse <http://docs.python.org/dev/library/argparse.html#upgrading-optparse-code>`__ + :ref:`upgrading-optparse-code` Part of the Python documentation, describing how to convert code that uses :mod:`optparse`. @@ -402,8 +447,6 @@ standard input or output. PEP 391: Dictionary-Based Configuration For Logging ==================================================== -.. XXX not documented in library reference yet; add link here once it's added. - The :mod:`logging` module is very flexible; applications can define a tree of logging subsystems, and each logger in this tree can filter out certain messages, format them differently, and direct messages to @@ -412,21 +455,21 @@ a varying number of handlers. All this flexibility can require a lot of configuration. You can write Python statements to create objects and set their properties, but a complex set-up requires verbose but boring code. -:mod:`logging` also supports a :func:`~logging.config.fileConfig` +:mod:`logging` also supports a :func:`~logging.fileConfig` function that parses a file, but the file format doesn't support configuring filters, and it's messier to generate programmatically. -Python 2.7 adds a :func:`~logging.config.dictConfig` function that +Python 2.7 adds a :func:`~logging.dictConfig` function that uses a dictionary to configure logging. There are many ways to produce a dictionary from different sources: construct one with code; parse a file containing JSON; or use a YAML parsing library if one is -installed. +installed. For more information see :ref:`logging-config-api`. The following example configures two loggers, the root logger and a -logger named "network". Messages sent to the root logger will be +logger named "network". Messages sent to the root logger will be sent to the system log using the syslog protocol, and messages to the "network" logger will be written to a :file:`network.log` file -that will be rotated once the log reaches 1Mb. +that will be rotated once the log reaches 1MB. :: @@ -445,7 +488,7 @@ that will be rotated once the log reaches 1Mb. 'filename': '/logs/network.log', 'formatter': 'standard', 'level': 'INFO', - 'maxBytes': 1024*1024}, + 'maxBytes': 1000000}, 'syslog': {'class': 'logging.handlers.SysLogHandler', 'formatter': 'standard', 'level': 'ERROR'}}, @@ -483,16 +526,19 @@ implemented by Vinay Sajip, are: for UDP or :const:`socket.SOCK_STREAM` for TCP. The default protocol remains UDP. -* :class:`Logger` instances gained a :meth:`getChild` method that retrieves a - descendant logger using a relative path. For example, - once you retrieve a logger by doing ``log = getLogger('app')``, +* :class:`~logging.Logger` instances gained a :meth:`~logging.Logger.getChild` + method that retrieves a descendant logger using a relative path. + For example, once you retrieve a logger by doing ``log = getLogger('app')``, calling ``log.getChild('network.listen')`` is equivalent to ``getLogger('app.network.listen')``. -* The :class:`LoggerAdapter` class gained a :meth:`isEnabledFor` method - that takes a *level* and returns whether the underlying logger would +* The :class:`~logging.LoggerAdapter` class gained a + :meth:`~logging.LoggerAdapter.isEnabledFor` method that takes a + *level* and returns whether the underlying logger would process a message of that level of importance. +.. XXX: Logger objects don't have a class declaration so the link don't work + .. seealso:: :pep:`391` - Dictionary-Based Configuration For Logging @@ -501,14 +547,15 @@ implemented by Vinay Sajip, are: PEP 3106: Dictionary Views ==================================================== -The dictionary methods :meth:`keys`, :meth:`values`, and :meth:`items` -are different in Python 3.x. They return an object called a :dfn:`view` -instead of a fully materialized list. +The dictionary methods :meth:`~dict.keys`, :meth:`~dict.values`, and +:meth:`~dict.items` are different in Python 3.x. They return an object +called a :dfn:`view` instead of a fully materialized list. -It's not possible to change the return values of :meth:`keys`, -:meth:`values`, and :meth:`items` in Python 2.7 because too much code -would break. Instead the 3.x versions were added under the new names -:meth:`viewkeys`, :meth:`viewvalues`, and :meth:`viewitems`. +It's not possible to change the return values of :meth:`~dict.keys`, +:meth:`~dict.values`, and :meth:`~dict.items` in Python 2.7 because +too much code would break. Instead the 3.x versions were added +under the new names :meth:`~dict.viewkeys`, :meth:`~dict.viewvalues`, +and :meth:`~dict.viewitems`. :: @@ -550,8 +597,8 @@ over the view:: RuntimeError: dictionary changed size during iteration You can use the view methods in Python 2.x code, and the 2to3 -converter will change them to the standard :meth:`keys`, -:meth:`values`, and :meth:`items` methods. +converter will change them to the standard :meth:`~dict.keys`, +:meth:`~dict.values`, and :meth:`~dict.items` methods. .. seealso:: @@ -624,7 +671,7 @@ Some smaller changes made to the core Python language are: ``{}`` continues to represent an empty dictionary; use ``set()`` for an empty set. - >>> {1,2,3,4,5} + >>> {1, 2, 3, 4, 5} set([1, 2, 3, 4, 5]) >>> set() # empty set set([]) @@ -661,7 +708,7 @@ Some smaller changes made to the core Python language are: The :func:`contextlib.nested` function provides a very similar function, so it's no longer necessary and has been deprecated. - (Proposed in http://codereview.appspot.com/53094; implemented by + (Proposed in https://codereview.appspot.com/53094; implemented by Georg Brandl.) * Conversions between floating-point numbers and strings are @@ -794,7 +841,7 @@ Some smaller changes made to the core Python language are: ``None`` as its first argument. (Fixed by Georg Brandl; :issue:`4759`.) - .. bytearray doesn't seem to be documented + .. XXX bytearray doesn't seem to be documented * When using ``@classmethod`` and ``@staticmethod`` to wrap methods as class or static methods, the wrapper object now @@ -867,12 +914,6 @@ Optimizations Several performance enhancements have been added: -.. * A new :program:`configure` option, :option:`--with-computed-gotos`, - compiles the main bytecode interpreter loop using a new dispatch - mechanism that gives speedups of up to 20%, depending on the system - and benchmark. The new mechanism is only supported on certain - compilers, such as gcc, SunPro, and icc. - * A new opcode was added to perform the initial setup for :keyword:`with` statements, looking up the :meth:`__enter__` and :meth:`__exit__` methods. (Contributed by Benjamin Peterson.) @@ -1054,7 +1095,7 @@ changes, or look through the Subversion logs for all the details. :meth:`~collections.deque.count` method that returns the number of contained elements equal to the supplied argument *x*, and a :meth:`~collections.deque.reverse` method that reverses the elements - of the deque in-place. :class:`deque` also exposes its maximum + of the deque in-place. :class:`~collections.deque` also exposes its maximum length as the read-only :attr:`~collections.deque.maxlen` attribute. (Both features added by Raymond Hettinger.) @@ -1135,15 +1176,14 @@ changes, or look through the Subversion logs for all the details. ``Decimal('0.1000000000000000055511151231257827021181583404541015625')``. (Implemented by Raymond Hettinger; :issue:`4796`.) - Comparing instances of :class:`Decimal` with floating-point + Comparing instances of :class:`~decimal.Decimal` with floating-point numbers now produces sensible results based on the numeric values of the operands. Previously such comparisons would fall back to Python's default rules for comparing objects, which produced arbitrary results based on their type. Note that you still cannot combine :class:`Decimal` and floating-point in other operations such as addition, since you should be explicitly choosing how to convert between float and - :class:`Decimal`. - (Fixed by Mark Dickinson; :issue:`2531`.) + :class:`~decimal.Decimal`. (Fixed by Mark Dickinson; :issue:`2531`.) The constructor for :class:`~decimal.Decimal` now accepts floating-point numbers (added by Raymond Hettinger; :issue:`8257`) @@ -1195,8 +1235,8 @@ changes, or look through the Subversion logs for all the details. Ordering comparisons (``<``, ``<=``, ``>``, ``>=``) between fractions and complex numbers now raise a :exc:`TypeError`. - This fixes an oversight, making the :class:`Fraction` match the other - numeric types. + This fixes an oversight, making the :class:`~fractions.Fraction` + match the other numeric types. .. revision 79455 @@ -1210,7 +1250,7 @@ changes, or look through the Subversion logs for all the details. uploads thanks to an added *rest* parameter (patch by Pablo Mouzo; :issue:`6845`.) -* New class decorator: :func:`total_ordering` in the :mod:`functools` +* New class decorator: :func:`~functools.total_ordering` in the :mod:`functools` module takes a class that defines an :meth:`__eq__` method and one of :meth:`__lt__`, :meth:`__le__`, :meth:`__gt__`, or :meth:`__ge__`, and generates the missing comparison methods. Since the @@ -1218,7 +1258,7 @@ changes, or look through the Subversion logs for all the details. this decorator makes it easier to define ordered classes. (Added by Raymond Hettinger; :issue:`5479`.) - New function: :func:`cmp_to_key` will take an old-style comparison + New function: :func:`~functools.cmp_to_key` will take an old-style comparison function that expects two arguments and return a new callable that can be used as the *key* parameter to functions such as :func:`sorted`, :func:`min` and :func:`max`, etc. The primary @@ -1345,7 +1385,7 @@ changes, or look through the Subversion logs for all the details. with any object literal that decodes to a list of pairs. (Contributed by Raymond Hettinger; :issue:`5381`.) -* The :mod:`mailbox` module's :class:`Maildir` class now records the +* The :mod:`mailbox` module's :class:`~mailbox.Maildir` class now records the timestamp on the directories it reads, and only re-reads them if the modification time has subsequently changed. This improves performance by avoiding unneeded directory scans. (Fixed by @@ -1432,7 +1472,7 @@ changes, or look through the Subversion logs for all the details. * The :mod:`signal` module no longer re-installs the signal handler unless this is truly necessary, which fixes a bug that could make it impossible to catch the EINTR signal robustly. (Fixed by - Charles-François Natali; :issue:`8354`.) + Charles-Francois Natali; :issue:`8354`.) * New functions: in the :mod:`site` module, three new functions return various site- and user-specific paths. @@ -1466,10 +1506,10 @@ changes, or look through the Subversion logs for all the details. defaults to False; if overridden to be True, new request connections will have the TCP_NODELAY option set to prevent buffering many small sends into a single TCP packet. - The :attr:`~SocketServer.TCPServer.timeout` class attribute can hold + The :attr:`~SocketServer.BaseServer.timeout` class attribute can hold a timeout in seconds that will be applied to the request socket; if - no request is received within that time, :meth:`handle_timeout` - will be called and :meth:`handle_request` will return. + no request is received within that time, :meth:`~SocketServer.BaseServer.handle_timeout` + will be called and :meth:`~SocketServer.BaseServer.handle_request` will return. (Contributed by Kristján Valur Jónsson; :issue:`6192` and :issue:`6267`.) * Updated module: the :mod:`sqlite3` module has been updated to @@ -1479,7 +1519,7 @@ changes, or look through the Subversion logs for all the details. and then call :meth:`~sqlite3.Connection.load_extension` to load a particular shared library. (Updated by Gerhard Häring.) -* The :mod:`ssl` module's :class:`ssl.SSLSocket` objects now support the +* The :mod:`ssl` module's :class:`~ssl.SSLSocket` objects now support the buffer API, which fixed a test suite failure (fix by Antoine Pitrou; :issue:`7133`) and automatically set OpenSSL's :c:macro:`SSL_MODE_AUTO_RETRY`, which will prevent an error @@ -1535,7 +1575,7 @@ changes, or look through the Subversion logs for all the details. on receiving an :const:`EINTR` signal. (Reported by several people; final patch by Gregory P. Smith in :issue:`1068268`.) -* New function: :func:`~symtable.is_declared_global` in the :mod:`symtable` module +* New function: :func:`~symtable.Symbol.is_declared_global` in the :mod:`symtable` module returns true for variables that are explicitly declared to be global, false for ones that are implicitly global. (Contributed by Jeremy Hylton.) @@ -1572,7 +1612,7 @@ changes, or look through the Subversion logs for all the details. resulting archive. This is more powerful than the existing *exclude* argument, which has therefore been deprecated. (Added by Lars Gustäbel; :issue:`6856`.) - The :class:`~tarfile.TarFile` class also now supports the context manager protocol. + The :class:`~tarfile.TarFile` class also now supports the context management protocol. (Added by Lars Gustäbel; :issue:`7232`.) * The :meth:`~threading.Event.wait` method of the :class:`threading.Event` class @@ -1716,7 +1756,7 @@ Some of the functions in the module are: Makefile and the :file:`pyconfig.h` file. * :func:`~sysconfig.get_config_vars` returns a dictionary containing all of the configuration variables. -* :func:`~sysconfig.getpath` returns the configured path for +* :func:`~sysconfig.get_path` returns the configured path for a particular type of module: the standard library, site-specific modules, platform-specific modules, etc. * :func:`~sysconfig.is_python_build` returns true if you're running a @@ -1727,7 +1767,7 @@ a complete list of functions. The Distutils package and :mod:`sysconfig` are now maintained by Tarek Ziadé, who has also started a Distutils2 package (source repository at -http://hg.python.org/distutils2/) for developing a next-generation +https://hg.python.org/distutils2/) for developing a next-generation version of Distutils. @@ -1764,7 +1804,7 @@ new features were added. Most of these features were implemented by Michael Foord, unless otherwise noted. The enhanced version of the module is downloadable separately for use with Python versions 2.4 to 2.6, packaged as the :mod:`unittest2` package, from -http://pypi.python.org/pypi/unittest2. +https://pypi.python.org/pypi/unittest2. When used from the command line, the module can automatically discover tests. It's not as fancy as `py.test <http://pytest.org>`__ or @@ -1778,7 +1818,7 @@ any importable test files named ``test*.py``:: Consult the :mod:`unittest` module documentation for more details. (Developed in :issue:`6001`.) -The :func:`main` function supports some other new options: +The :func:`~unittest.main` function supports some other new options: * :option:`-b` or :option:`--buffer` will buffer the standard output and standard error streams during each test. If the test passes, @@ -1796,7 +1836,7 @@ The :func:`main` function supports some other new options: being tested or the tests being run have defined a signal handler of their own, by noticing that a signal handler was already set and calling it. If this doesn't work for you, there's a - :func:`removeHandler` decorator that can be used to mark tests that + :func:`~unittest.removeHandler` decorator that can be used to mark tests that should have the control-C handling disabled. * :option:`-f` or :option:`--failfast` makes @@ -1923,7 +1963,7 @@ GvR worked on merging them into Python's version of :mod:`unittest`. :func:`unittest.main` now takes an optional ``exit`` argument. If False, :func:`~unittest.main` doesn't call :func:`sys.exit`, allowing -:func:`main` to be used from the interactive interpreter. +:func:`~unittest.main` to be used from the interactive interpreter. (Contributed by J. Pablo Fernández; :issue:`3379`.) :class:`~unittest.TestResult` has new :meth:`~unittest.TestResult.startTestRun` and @@ -2120,7 +2160,7 @@ Changes to Python's build process and to the C API include: :c:macro:`Py_ISSPACE`, :c:macro:`Py_ISUPPER`, :c:macro:`Py_ISXDIGIT`, - and :c:macro:`Py_TOLOWER`, :c:macro:`Py_TOUPPER`. + :c:macro:`Py_TOLOWER`, and :c:macro:`Py_TOUPPER`. All of these functions are analogous to the C standard macros for classifying characters, but ignore the current locale setting, because in @@ -2266,11 +2306,11 @@ Port-Specific Changes: Windows (Contributed by David Cournapeau; :issue:`4365`.) * The :mod:`_winreg` module for accessing the registry now implements - the :func:`CreateKeyEx` and :func:`DeleteKeyEx` functions, extended - versions of previously-supported functions that take several extra - arguments. The :func:`DisableReflectionKey`, - :func:`EnableReflectionKey`, and :func:`QueryReflectionKey` were also - tested and documented. + the :func:`~_winreg.CreateKeyEx` and :func:`~_winreg.DeleteKeyEx` + functions, extended versions of previously-supported functions that + take several extra arguments. The :func:`~_winreg.DisableReflectionKey`, + :func:`~_winreg.EnableReflectionKey`, and :func:`~_winreg.QueryReflectionKey` + were also tested and documented. (Implemented by Brian Curtin: :issue:`7347`.) * The new :c:func:`_beginthreadex` API is used to start threads, and @@ -2329,7 +2369,7 @@ Other Changes and Fixes attributes of the resulting code objects are overwritten when the original filename is obsolete. This can happen if the file has been renamed, moved, or is accessed through different paths. (Patch by - Žiga Seilnacht and Jean-Paul Calderone; :issue:`1180193`.) + Ziga Seilnacht and Jean-Paul Calderone; :issue:`1180193`.) * The :file:`regrtest.py` script now takes a :option:`--randseed=` switch that takes an integer that will be used as the random seed @@ -2387,20 +2427,20 @@ that may require changes to your code: In the standard library: -* Operations with :class:`datetime` instances that resulted in a year +* Operations with :class:`~datetime.datetime` instances that resulted in a year falling outside the supported range didn't always raise :exc:`OverflowError`. Such errors are now checked more carefully and will now raise the exception. (Reported by Mark Leander, patch by Anand B. Pillai and Alexander Belopolsky; :issue:`7150`.) -* When using :class:`Decimal` instances with a string's +* When using :class:`~decimal.Decimal` instances with a string's :meth:`format` method, the default alignment was previously left-alignment. This has been changed to right-alignment, which might change the output of your programs. (Changed by Mark Dickinson; :issue:`6857`.) Comparisons involving a signaling NaN value (or ``sNAN``) now signal - :const:`InvalidOperation` instead of silently returning a true or + :const:`~decimal.InvalidOperation` instead of silently returning a true or false value depending on the comparison operator. Quiet NaN values (or ``NaN``) are now hashable. (Fixed by Mark Dickinson; :issue:`7279`.) @@ -2411,7 +2451,7 @@ In the standard library: or comment (which looks like `<!-- comment -->`). (Patch by Neil Muller; :issue:`2746`.) -* The :meth:`readline` method of :class:`StringIO` objects now does +* The :meth:`~StringIO.StringIO.readline` method of :class:`~StringIO.StringIO` objects now does nothing when a negative length is requested, as other file-like objects do. (:issue:`7348`). @@ -2470,6 +2510,73 @@ For applications that embed Python: .. ====================================================================== +.. _py27-maintenance-enhancements: + +New Features Added to Python 2.7 Maintenance Releases +===================================================== + +New features may be added to Python 2.7 maintenance releases when the +situation genuinely calls for it. Any such additions must go through +the Python Enhancement Proposal process, and make a compelling case for why +they can't be adequately addressed by either adding the new feature solely to +Python 3, or else by publishing it on the Python Package Index. + +In addition to the specific proposals listed below, there is a general +exemption allowing new ``-3`` warnings to be added in any Python 2.7 +maintenance release. + + +PEP 434: IDLE Enhancement Exception for All Branches +---------------------------------------------------- + +:pep:`434` describes a general exemption for changes made to the IDLE +development environment shipped along with Python. This exemption makes it +possible for the IDLE developers to provide a more consistent user +experience across all supported versions of Python 2 and 3. + +For details of any IDLE changes, refer to the NEWS file for the specific +release. + + +PEP 466: Network Security Enhancements for Python 2.7 +----------------------------------------------------- + +:pep:`466` describes a number of network security enhancement proposals +that have been approved for inclusion in Python 2.7 maintenance releases, +with the first of those changes appearing in the Python 2.7.7 release. + +:pep:`466` related features added in Python 2.7.7: + +* :func:`hmac.compare_digest` was backported from Python 3 to make a timing + attack resistant comparison operation available to Python 2 applications. + (Contributed by Alex Gaynor; :issue:`21306`.) + +* OpenSSL 1.0.1g was upgraded in the official Windows installers published on + python.org. (Contributed by Zachary Ware; :issue:`21462`.) + +:pep:`466` related features added in Python 2.7.8: + +* :func:`hashlib.pbkdf2_hmac` was backported from Python 3 to make a hashing + algorithm suitable for secure password storage broadly available to Python + 2 applications. (Contributed by Alex Gaynor; :issue:`21304`.) + +* OpenSSL 1.0.1h was upgraded for the official Windows installers published on + python.org. (contributed by Zachary Ware in :issue:`21671` for CVE-2014-0224) + +:pep:`466` related features added in Python 2.7.9: + +* Most of Python 3.4's :mod:`ssl` module was backported. This means :mod:`ssl` + now supports Server Name Indication, TLS1.x settings, access to the platform + certificate store, the :class:`~ssl.SSLContext` class, and other + features. (Contributed by Alex Gaynor and David Reid; :issue:`21308`.) + +* :func:`os.urandom` was changed to cache a file descriptor to ``/dev/urandom`` + instead of reopening ``/dev/urandom`` on every call. (Contributed by Alex + Gaynor; :issue:`21305`.) + + +.. ====================================================================== + .. _acks27: Acknowledgements diff --git a/Doc/whatsnew/3.0.rst b/Doc/whatsnew/3.0.rst index 71b87b827e90..99411305a59f 100644 --- a/Doc/whatsnew/3.0.rst +++ b/Doc/whatsnew/3.0.rst @@ -164,7 +164,7 @@ Some well-known APIs no longer return lists: If the input sequences are not of equal length, :func:`map` will stop at the termination of the shortest of the sequences. For full - compatibility with `map` from Python 2.x, also wrap the sequences in + compatibility with :func:`map` from Python 2.x, also wrap the sequences in :func:`itertools.zip_longest`, e.g. ``map(func, *sequences)`` becomes ``list(map(func, itertools.zip_longest(*sequences)))``. diff --git a/Doc/whatsnew/3.1.rst b/Doc/whatsnew/3.1.rst index ab327f5fb1c8..f272da4de961 100644 --- a/Doc/whatsnew/3.1.rst +++ b/Doc/whatsnew/3.1.rst @@ -172,7 +172,7 @@ Some smaller changes made to the core Python language are: needed and is now deprecated. (Contributed by Georg Brandl and Mattias Brändström; - `appspot issue 53094 <http://codereview.appspot.com/53094>`_.) + `appspot issue 53094 <https://codereview.appspot.com/53094>`_.) * ``round(x, n)`` now returns an integer if *x* is an integer. Previously it returned a float:: @@ -238,7 +238,7 @@ New, Improved, and Deprecated Modules (Contributed by Guilherme Polo; :issue:`2983`.) * The :class:`gzip.GzipFile` and :class:`bz2.BZ2File` classes now support - the context manager protocol:: + the context management protocol:: >>> # Automatically close file after writing >>> with gzip.GzipFile(filename, "wb") as f: diff --git a/Doc/whatsnew/3.2.rst b/Doc/whatsnew/3.2.rst index 5059f4830509..5171f3c1a528 100644 --- a/Doc/whatsnew/3.2.rst +++ b/Doc/whatsnew/3.2.rst @@ -50,7 +50,7 @@ This article explains the new features in Python 3.2 as compared to 3.1. It focuses on a few highlights and gives a few examples. For full details, see the -`Misc/NEWS <http://hg.python.org/cpython/file/3.2/Misc/NEWS>`_ file. +`Misc/NEWS <https://hg.python.org/cpython/file/3.2/Misc/NEWS>`_ file. .. seealso:: @@ -522,7 +522,7 @@ Some smaller changes made to the core Python language are: (Proposed and implemented by Mark Dickinson; :issue:`9337`.) * :class:`memoryview` objects now have a :meth:`~memoryview.release()` method - and they also now support the context manager protocol. This allows timely + and they also now support the context management protocol. This allows timely release of any resources that were acquired when requesting a buffer from the original object. @@ -816,7 +816,7 @@ functools >>> sorted(iterable, key=cmp_to_key(locale.strcoll)) For sorting examples and a brief sorting tutorial, see the `Sorting HowTo - <http://wiki.python.org/moin/HowTo/Sorting/>`_ tutorial. + <https://wiki.python.org/moin/HowTo/Sorting/>`_ tutorial. (Contributed by Raymond Hettinger.) @@ -1020,7 +1020,7 @@ datetime and time :issue:`5094`, :issue:`6641`, :issue:`2706`, :issue:`1777412`, :issue:`8013`, and :issue:`10827`.) -.. XXX http://bugs.python.org/issue?%40search_text=datetime&%40sort=-activity +.. XXX https://bugs.python.org/issue?%40search_text=datetime&%40sort=-activity math ---- @@ -1315,7 +1315,7 @@ contexts that correspond to the decimal interchange formats specified in IEEE ftp --- -The :class:`ftplib.FTP` class now supports the context manager protocol to +The :class:`ftplib.FTP` class now supports the context management protocol to unconditionally consume :exc:`socket.error` exceptions and to close the FTP connection when done:: @@ -1595,7 +1595,7 @@ The :mod:`socket` module has two new improvements. descriptor. The latter can then be reused for other purposes. (Added by Antoine Pitrou; :issue:`8524`.) -* :func:`socket.create_connection` now supports the context manager protocol +* :func:`socket.create_connection` now supports the context management protocol to unconditionally consume :exc:`socket.error` exceptions and to close the socket when done. (Contributed by Giampaolo Rodolà; :issue:`9794`.) @@ -2283,7 +2283,7 @@ Multi-threading Additional details about the implementation can be read from a `python-dev mailing-list message - <http://mail.python.org/pipermail/python-dev/2009-October/093321.html>`_ + <https://mail.python.org/pipermail/python-dev/2009-October/093321.html>`_ (however, "priority requests" as exposed in this message have not been kept for inclusion). @@ -2469,7 +2469,7 @@ Code Repository In addition to the existing Subversion code repository at http://svn.python.org there is now a `Mercurial <http://mercurial.selenic.com/>`_ repository at -http://hg.python.org/ . +https://hg.python.org/\ . After the 3.2 release, there are plans to switch to Mercurial as the primary repository. This distributed version control system should make it easier for @@ -2478,7 +2478,7 @@ members of the community to create and share external changesets. See To learn to use the new version control system, see the `tutorial by Joel Spolsky <http://hginit.com>`_ or the `Guide to Mercurial Workflows -<http://mercurial.selenic.com/guide/>`_. +<http://mercurial.selenic.com/guide>`_. Build and C API Changes @@ -2560,7 +2560,7 @@ Also, there were a number of updates to the Mac OS X build, see build, there is a known problem with the default Tcl/Tk on Mac OS X 10.6. Accordingly, we recommend installing an updated alternative such as `ActiveState Tcl/Tk 8.5.9 <http://www.activestate.com/activetcl/downloads>`_\. -See http://www.python.org/download/mac/tcltk/ for additional details. +See https://www.python.org/download/mac/tcltk/ for additional details. Porting to Python 3.2 ===================== @@ -2649,7 +2649,7 @@ require changes to your code: outfile.write(line) (Contributed by Georg Brandl and Mattias Brändström; - `appspot issue 53094 <http://codereview.appspot.com/53094>`_.) + `appspot issue 53094 <https://codereview.appspot.com/53094>`_.) * :func:`struct.pack` now only allows bytes for the ``s`` string pack code. Formerly, it would accept text arguments and implicitly encode them to bytes diff --git a/Doc/whatsnew/3.3.rst b/Doc/whatsnew/3.3.rst index 6e0746adbfd2..1d4ce7236f33 100644 --- a/Doc/whatsnew/3.3.rst +++ b/Doc/whatsnew/3.3.rst @@ -44,7 +44,7 @@ This article explains the new features in Python 3.3, compared to 3.2. Python 3.3 was released on September 29, 2012. For full details, -see the `changelog <http://docs.python.org/3.3/whatsnew/changelog.html>`_. +see the `changelog <https://docs.python.org/3.3/whatsnew/changelog.html>`_. .. seealso:: @@ -171,7 +171,7 @@ Features * Multi-dimensional comparisons are supported for any array type. * One-dimensional memoryviews of hashable (read-only) types with formats B, - b or c are now hashable. (Contributed by Antoine Pitrou in :issue:`13411`) + b or c are now hashable. (Contributed by Antoine Pitrou in :issue:`13411`.) * Arbitrary slicing of any 1-D arrays type is supported. For example, it is now possible to reverse a memoryview in O(1) by using a negative step. @@ -194,9 +194,9 @@ API changes are still permitted, but will always compare as unequal, regardless of view contents. -* For further changes see `Build and C API Changes`_ and `Porting C code`_ . +* For further changes see `Build and C API Changes`_ and `Porting C code`_. -(Contributed by Stefan Krah in :issue:`10181`) +(Contributed by Stefan Krah in :issue:`10181`.) .. seealso:: @@ -228,7 +228,7 @@ Functionality Changes introduced by :pep:`393` are the following: -* Python now always supports the full range of Unicode codepoints, including +* Python now always supports the full range of Unicode code points, including non-BMP ones (i.e. from ``U+0000`` to ``U+10FFFF``). The distinction between narrow and wide builds no longer exists and Python now behaves like a wide build, even under Windows. @@ -246,7 +246,7 @@ Changes introduced by :pep:`393` are the following: so ``'\U0010FFFF'[0]`` now returns ``'\U0010FFFF'`` and not ``'\uDBFF'``; * all other functions in the standard library now correctly handle - non-BMP codepoints. + non-BMP code points. * The value of :data:`sys.maxunicode` is now always ``1114111`` (``0x10FFFF`` in hexadecimal). The :c:func:`PyUnicode_GetMax` function still returns @@ -258,13 +258,13 @@ Changes introduced by :pep:`393` are the following: Performance and resource usage ------------------------------ -The storage of Unicode strings now depends on the highest codepoint in the string: +The storage of Unicode strings now depends on the highest code point in the string: -* pure ASCII and Latin1 strings (``U+0000-U+00FF``) use 1 byte per codepoint; +* pure ASCII and Latin1 strings (``U+0000-U+00FF``) use 1 byte per code point; -* BMP strings (``U+0000-U+FFFF``) use 2 bytes per codepoint; +* BMP strings (``U+0000-U+FFFF``) use 2 bytes per code point; -* non-BMP strings (``U+10000-U+10FFFF``) use 4 bytes per codepoint. +* non-BMP strings (``U+10000-U+10FFFF``) use 4 bytes per code point. The net effect is that for most applications, memory usage of string storage should decrease significantly - especially compared to former @@ -307,8 +307,8 @@ Python 2 is also installed, or ``-2.6`` to specifclly request an earlier Python version when a more recent version is installed). In addition to the launcher, the Windows installer now includes an -option to add the newly installed Python to the system PATH (contributed -by Brian Curtin in :issue:`3561`). +option to add the newly installed Python to the system PATH. (Contributed +by Brian Curtin in :issue:`3561`.) .. seealso:: @@ -781,7 +781,7 @@ Some smaller changes made to the core Python language are: Both :func:`unicodedata.lookup()` and ``'\N{...}'`` now resolve name aliases, and :func:`unicodedata.lookup()` resolves named sequences too. - (Contributed by Ezio Melotti in :issue:`12753`) + (Contributed by Ezio Melotti in :issue:`12753`.) * Unicode database updated to UCD version 6.1.0 @@ -793,7 +793,7 @@ Some smaller changes made to the core Python language are: methods of :class:`bytes` and :class:`bytearray` objects now accept an integer between 0 and 255 as their first argument. - (Contributed by Petri Lehtinen in :issue:`12170`) + (Contributed by Petri Lehtinen in :issue:`12170`.) * The ``rjust()``, ``ljust()``, and ``center()`` methods of :class:`bytes` and :class:`bytearray` now accept a :class:`bytearray` for the ``fill`` @@ -854,7 +854,7 @@ Builtin functions and types * The sequence documentation has been substantially rewritten to better explain the binary/text sequence distinction and to provide specific documentation sections for the individual builtin sequence types - (:issue:`4966`) + (:issue:`4966`). New Modules @@ -891,7 +891,7 @@ The new :mod:`ipaddress` module provides tools for creating and manipulating objects representing IPv4 and IPv6 addresses, networks and interfaces (i.e. an IP address associated with a specific IP subnet). -(Contributed by Google and Peter Moody in :pep:`3144`) +(Contributed by Google and Peter Moody in :pep:`3144`.) lzma ---- @@ -900,7 +900,7 @@ The newly-added :mod:`lzma` module provides data compression and decompression using the LZMA algorithm, including support for the ``.xz`` and ``.lzma`` file formats. -(Contributed by Nadeem Vawda and Per Øyvind Karlsen in :issue:`6715`) +(Contributed by Nadeem Vawda and Per Øyvind Karlsen in :issue:`6715`.) Improved Modules @@ -921,7 +921,7 @@ property. The built-in descriptors have been updated accordingly. * :class:`abc.abstractstaticmethod` has been deprecated, use :class:`staticmethod` with :func:`abc.abstractmethod` instead. -(Contributed by Darren Dale in :issue:`11610`) +(Contributed by Darren Dale in :issue:`11610`.) :meth:`abc.ABCMeta.register` now returns the registered subclass, which means it can now be used as a class decorator (:issue:`10868`). @@ -933,7 +933,7 @@ array The :mod:`array` module supports the :c:type:`long long` type using ``q`` and ``Q`` type codes. -(Contributed by Oren Tirosh and Hirokazu Yamamoto in :issue:`1172711`) +(Contributed by Oren Tirosh and Hirokazu Yamamoto in :issue:`1172711`.) base64 @@ -964,14 +964,14 @@ new features have been added: * :class:`bz2.BZ2File` can now read from and write to arbitrary file-like objects, by means of its constructor's *fileobj* argument. - (Contributed by Nadeem Vawda in :issue:`5863`) + (Contributed by Nadeem Vawda in :issue:`5863`.) * :class:`bz2.BZ2File` and :func:`bz2.decompress` can now decompress multi-stream inputs (such as those produced by the :program:`pbzip2` tool). :class:`bz2.BZ2File` can now also be used to create this type of file, using the ``'a'`` (append) mode. - (Contributed by Nir Aides in :issue:`1625`) + (Contributed by Nir Aides in :issue:`1625`.) * :class:`bz2.BZ2File` now implements all of the :class:`io.BufferedIOBase` API, except for the :meth:`detach` and :meth:`truncate` methods. @@ -1018,7 +1018,7 @@ collections Addition of a new :class:`~collections.ChainMap` class to allow treating a number of mappings as a single unit. (Written by Raymond Hettinger for -:issue:`11089`, made public in :issue:`11297`) +:issue:`11089`, made public in :issue:`11297`.) The abstract base classes have been moved in a new :mod:`collections.abc` module, to better differentiate between the abstract and the concrete @@ -1069,7 +1069,7 @@ curses push a wide character so the next :meth:`~curses.window.get_wch` will return it -(Contributed by Iñigo Serna in :issue:`6755`) +(Contributed by Iñigo Serna in :issue:`6755`.) datetime -------- @@ -1376,11 +1376,11 @@ ftplib :func:`~ftplib.FTP_TLS.ccc` function to revert control channel back to plaintext. This can be useful to take advantage of firewalls that know how to handle NAT with non-secure FTP without opening fixed ports. (Contributed - by Giampaolo Rodolà in :issue:`12139`) + by Giampaolo Rodolà in :issue:`12139`.) * Added :meth:`ftplib.FTP.mlsd` method which provides a parsable directory listing format and deprecates :meth:`ftplib.FTP.nlst` and - :meth:`ftplib.FTP.dir`. (Contributed by Giampaolo Rodolà in :issue:`11072`) + :meth:`ftplib.FTP.dir`. (Contributed by Giampaolo Rodolà in :issue:`11072`.) functools @@ -1404,7 +1404,7 @@ hmac A new :func:`~hmac.compare_digest` function has been added to prevent side channel attacks on digests through timing analysis. (Contributed by Nick -Coghlan and Christian Heimes in :issue:`15061`) +Coghlan and Christian Heimes in :issue:`15061`.) http @@ -1436,13 +1436,13 @@ are also available on the latest bug fix releases of Python 2.7/3.2. (Contributed by Ezio Melotti in :issue:`15114`, and :issue:`14538`, :issue:`13993`, :issue:`13960`, :issue:`13358`, :issue:`1745761`, :issue:`755670`, :issue:`13357`, :issue:`12629`, :issue:`1200313`, -:issue:`670664`, :issue:`13273`, :issue:`12888`, :issue:`7311`) +:issue:`670664`, :issue:`13273`, :issue:`12888`, :issue:`7311`.) A new :data:`~html.entities.html5` dictionary that maps HTML5 named character references to the equivalent Unicode character(s) (e.g. ``html5['gt;'] == '>'``) has been added to the :mod:`html.entities` module. The dictionary is now also used by :class:`~html.parser.HTMLParser`. (Contributed by Ezio -Melotti in :issue:`11113` and :issue:`15156`) +Melotti in :issue:`11113` and :issue:`15156`.) imaplib @@ -1451,7 +1451,7 @@ imaplib The :class:`~imaplib.IMAP4_SSL` constructor now accepts an SSLContext parameter to control parameters of the secure channel. -(Contributed by Sijin Joseph in :issue:`8808`) +(Contributed by Sijin Joseph in :issue:`8808`.) inspect @@ -1462,14 +1462,14 @@ reports the current binding of all names referenced from the function body and where those names were resolved, making it easier to verify correct internal state when testing code that relies on stateful closures. -(Contributed by Meador Inge and Nick Coghlan in :issue:`13062`) +(Contributed by Meador Inge and Nick Coghlan in :issue:`13062`.) A new :func:`~inspect.getgeneratorlocals` function has been added. This function reports the current binding of local variables in the generator's stack frame, making it easier to verify correct internal state when testing generators. -(Contributed by Meador Inge in :issue:`15153`) +(Contributed by Meador Inge in :issue:`15153`.) io -- @@ -1478,7 +1478,7 @@ The :func:`~io.open` function has a new ``'x'`` mode that can be used to exclusively create a new file, and raise a :exc:`FileExistsError` if the file already exists. It is based on the C11 'x' mode to fopen(). -(Contributed by David Townshend in :issue:`12760`) +(Contributed by David Townshend in :issue:`12760`.) The constructor of the :class:`~io.TextIOWrapper` class has a new *write_through* optional argument. If *write_through* is ``True``, calls to @@ -1513,7 +1513,7 @@ math The :mod:`math` module has a new function, :func:`~math.log2`, which returns the base-2 logarithm of *x*. -(Written by Mark Dickinson in :issue:`11888`). +(Written by Mark Dickinson in :issue:`11888`.) mmap @@ -1540,7 +1540,7 @@ multiprocessing connections. to override the default behavior of inheriting the ``daemon`` flag from the parent process (:issue:`6064`). -New attribute attribute :data:`multiprocessing.Process.sentinel` allows a +New attribute :data:`multiprocessing.Process.sentinel` allows a program to wait on multiple :class:`~multiprocessing.Process` objects at one time using the appropriate OS primitives (for example, :mod:`select` on posix systems). @@ -1556,7 +1556,7 @@ Schlawack in :issue:`12708`.) nntplib ------- -The :class:`nntplib.NNTP` class now supports the context manager protocol to +The :class:`nntplib.NNTP` class now supports the context management protocol to unconditionally consume :exc:`socket.error` exceptions and to close the NNTP connection when done:: @@ -1567,7 +1567,7 @@ connection when done:: ('211 1755 1 1755 gmane.comp.python.committers', 1755, 1, 1755, 'gmane.comp.python.committers') >>> -(Contributed by Giampaolo Rodolà in :issue:`9795`) +(Contributed by Giampaolo Rodolà in :issue:`9795`.) os @@ -1579,7 +1579,7 @@ os avoid race conditions in multi-threaded programs. * The :mod:`os` module has a new :func:`~os.sendfile` function which provides - an efficent "zero-copy" way for copying data from one file (or socket) + an efficient "zero-copy" way for copying data from one file (or socket) descriptor to another. The phrase "zero-copy" refers to the fact that all of the copying of data between the two descriptors is done entirely by the kernel, with no copying of data into userspace buffers. :func:`~os.sendfile` @@ -1744,30 +1744,30 @@ sched set to False makes the method execute the scheduled events due to expire soonest (if any) and then return immediately. This is useful in case you want to use the :class:`~sched.scheduler` in - non-blocking applications. (Contributed by Giampaolo Rodolà in :issue:`13449`) + non-blocking applications. (Contributed by Giampaolo Rodolà in :issue:`13449`.) * :class:`~sched.scheduler` class can now be safely used in multi-threaded environments. (Contributed by Josiah Carlson and Giampaolo Rodolà in - :issue:`8684`) + :issue:`8684`.) * *timefunc* and *delayfunct* parameters of :class:`~sched.scheduler` class constructor are now optional and defaults to :func:`time.time` and :func:`time.sleep` respectively. (Contributed by Chris Clark in - :issue:`13245`) + :issue:`13245`.) * :meth:`~sched.scheduler.enter` and :meth:`~sched.scheduler.enterabs` *argument* parameter is now optional. (Contributed by Chris Clark in - :issue:`13245`) + :issue:`13245`.) * :meth:`~sched.scheduler.enter` and :meth:`~sched.scheduler.enterabs` now accept a *kwargs* parameter. (Contributed by Chris Clark in - :issue:`13245`) + :issue:`13245`.) select ------ -Solaris and derivatives platforms have a new class :class:`select.devpoll` +Solaris and derivative platforms have a new class :class:`select.devpoll` for high performance asynchronous sockets via :file:`/dev/poll`. (Contributed by Jesús Cea Avión in :issue:`6397`.) @@ -1787,10 +1787,10 @@ shutil * New functions: * :func:`~shutil.disk_usage`: provides total, used and free disk space - statistics. (Contributed by Giampaolo Rodolà in :issue:`12442`) + statistics. (Contributed by Giampaolo Rodolà in :issue:`12442`.) * :func:`~shutil.chown`: allows one to change user and/or group of the given path also specifying the user/group names and not only their numeric - ids. (Contributed by Sandro Tosi in :issue:`12191`) + ids. (Contributed by Sandro Tosi in :issue:`12191`.) * :func:`shutil.get_terminal_size`: returns the size of the terminal window to which the interpreter is attached. (Contributed by Zbigniew JÄ™drzejewski-Szmek in :issue:`13609`.) @@ -1813,7 +1813,7 @@ shutil * :func:`~shutil.rmtree` is now resistant to symlink attacks on platforms which support the new ``dir_fd`` parameter in :func:`os.open` and - :func:`os.unlink`. (Contributed by Martin von Löwis and Hynek Schlawack + :func:`os.unlink`. (Contributed by Martin von Löwis and Hynek Schlawack in :issue:`4489`.) @@ -1823,12 +1823,12 @@ signal * The :mod:`signal` module has new functions: * :func:`~signal.pthread_sigmask`: fetch and/or change the signal mask of the - calling thread (Contributed by Jean-Paul Calderone in :issue:`8407`) ; - * :func:`~signal.pthread_kill`: send a signal to a thread ; - * :func:`~signal.sigpending`: examine pending functions ; - * :func:`~signal.sigwait`: wait a signal. + calling thread (Contributed by Jean-Paul Calderone in :issue:`8407`); + * :func:`~signal.pthread_kill`: send a signal to a thread; + * :func:`~signal.sigpending`: examine pending functions; + * :func:`~signal.sigwait`: wait a signal; * :func:`~signal.sigwaitinfo`: wait for a signal, returning detailed - information about it. + information about it; * :func:`~signal.sigtimedwait`: like :func:`~signal.sigwaitinfo` but with a timeout. @@ -1861,13 +1861,13 @@ to specify the ``(host, port)`` to use as the source address in the bind call when creating the outgoing socket. (Contributed by Paulo Scardine in :issue:`11281`.) -:class:`~smtplib.SMTP` now supports the context manager protocol, allowing an +:class:`~smtplib.SMTP` now supports the context management protocol, allowing an ``SMTP`` instance to be used in a ``with`` statement. (Contributed by Giampaolo Rodolà in :issue:`11289`.) The :class:`~smtplib.SMTP_SSL` constructor and the :meth:`~smtplib.SMTP.starttls` method now accept an SSLContext parameter to control parameters of the secure -channel. (Contributed by Kasun Herath in :issue:`8809`) +channel. (Contributed by Kasun Herath in :issue:`8809`.) socket @@ -1887,11 +1887,11 @@ socket (http://en.wikipedia.org/wiki/Socketcan), on Linux (http://lwn.net/Articles/253425). - (Contributed by Matthias Fuchs, updated by Tiago Gonçalves in :issue:`10141`) + (Contributed by Matthias Fuchs, updated by Tiago Gonçalves in :issue:`10141`.) * The :class:`~socket.socket` class now supports the PF_RDS protocol family (http://en.wikipedia.org/wiki/Reliable_Datagram_Sockets and - http://oss.oracle.com/projects/rds/). + https://oss.oracle.com/projects/rds/). * The :class:`~socket.socket` class now supports the ``PF_SYSTEM`` protocol family on OS X. (Contributed by Michael Goderbauer in :issue:`13777`.) @@ -1908,7 +1908,7 @@ socketserver :meth:`~socketserver.BaseServer.service_actions` that is called by the :meth:`~socketserver.BaseServer.serve_forever` method in the service loop. :class:`~socketserver.ForkingMixIn` now uses this to clean up zombie -child proceses. (Contributed by Justin Warkentin in :issue:`11109`.) +child processes. (Contributed by Justin Warkentin in :issue:`11109`.) sqlite3 @@ -1929,37 +1929,37 @@ ssl pseudo-random bytes. * :func:`~ssl.RAND_pseudo_bytes`: generate pseudo-random bytes. - (Contributed by Victor Stinner in :issue:`12049`) + (Contributed by Victor Stinner in :issue:`12049`.) * The :mod:`ssl` module now exposes a finer-grained exception hierarchy in order to make it easier to inspect the various kinds of errors. - (Contributed by Antoine Pitrou in :issue:`11183`) + (Contributed by Antoine Pitrou in :issue:`11183`.) * :meth:`~ssl.SSLContext.load_cert_chain` now accepts a *password* argument to be used if the private key is encrypted. - (Contributed by Adam Simpkins in :issue:`12803`) + (Contributed by Adam Simpkins in :issue:`12803`.) * Diffie-Hellman key exchange, both regular and Elliptic Curve-based, is now supported through the :meth:`~ssl.SSLContext.load_dh_params` and :meth:`~ssl.SSLContext.set_ecdh_curve` methods. - (Contributed by Antoine Pitrou in :issue:`13626` and :issue:`13627`) + (Contributed by Antoine Pitrou in :issue:`13626` and :issue:`13627`.) * SSL sockets have a new :meth:`~ssl.SSLSocket.get_channel_binding` method allowing the implementation of certain authentication mechanisms such as - SCRAM-SHA-1-PLUS. (Contributed by Jacek Konieczny in :issue:`12551`) + SCRAM-SHA-1-PLUS. (Contributed by Jacek Konieczny in :issue:`12551`.) * You can query the SSL compression algorithm used by an SSL socket, thanks to its new :meth:`~ssl.SSLSocket.compression` method. The new attribute :attr:`~ssl.OP_NO_COMPRESSION` can be used to disable compression. - (Contributed by Antoine Pitrou in :issue:`13634`) + (Contributed by Antoine Pitrou in :issue:`13634`.) * Support has been added for the Next Procotol Negotiation extension using the :meth:`ssl.SSLContext.set_npn_protocols` method. - (Contributed by Colin Marc in :issue:`14204`) + (Contributed by Colin Marc in :issue:`14204`.) * SSL errors can now be introspected more easily thanks to :attr:`~ssl.SSLError.library` and :attr:`~ssl.SSLError.reason` attributes. - (Contributed by Antoine Pitrou in :issue:`14837`) + (Contributed by Antoine Pitrou in :issue:`14837`.) * The :func:`~ssl.get_server_certificate` function now supports IPv6. (Contributed by Charles-François Natali in :issue:`11811`.) @@ -1976,7 +1976,7 @@ The undocumented tarfile.filemode function has been moved to :func:`stat.filemode`. It can be used to convert a file's mode to a string of the form '-rwxrwxrwx'. -(Contributed by Giampaolo Rodolà in :issue:`14807`) +(Contributed by Giampaolo Rodolà in :issue:`14807`.) struct @@ -2035,8 +2035,8 @@ threading :class:`threading.Condition`, :class:`threading.Semaphore`, :class:`threading.BoundedSemaphore`, :class:`threading.Event`, and :class:`threading.Timer`, all of which used to be factory functions returning a -class instance, are now classes and may be subclassed. (Contributed by Éric -Araujo in :issue:`10968`). +class instance, are now classes and may be subclassed. (Contributed by Éric +Araujo in :issue:`10968`.) The :class:`threading.Thread` constructor now accepts a ``daemon`` keyword argument to override the default behavior of inheriting the ``deamon`` flag @@ -2066,7 +2066,7 @@ Other new functions: * :func:`~time.clock_getres`, :func:`~time.clock_gettime` and :func:`~time.clock_settime` functions with ``CLOCK_xxx`` constants. - (Contributed by Victor Stinner in :issue:`10278`) + (Contributed by Victor Stinner in :issue:`10278`.) To improve cross platform consistency, :func:`~time.sleep` now raises a :exc:`ValueError` when passed a negative sleep value. Previously this was an @@ -2080,7 +2080,7 @@ Add a new :class:`types.MappingProxyType` class: Read-only proxy of a mapping. (:issue:`14386`) -The new functions `types.new_class` and `types.prepare_class` provide support +The new functions :func:`types.new_class` and :func:`types.prepare_class` provide support for PEP 3115 compliant dynamic type creation. (:issue:`14588`) @@ -2090,7 +2090,7 @@ unittest :meth:`.assertRaises`, :meth:`.assertRaisesRegex`, :meth:`.assertWarns`, and :meth:`.assertWarnsRegex` now accept a keyword argument *msg* when used as context managers. (Contributed by Ezio Melotti and Winston Ewert in -:issue:`10775`) +:issue:`10775`.) :meth:`unittest.TestCase.run` now returns the :class:`~unittest.TestResult` object. @@ -2103,7 +2103,7 @@ The :class:`~urllib.request.Request` class, now accepts a *method* argument used by :meth:`~urllib.request.Request.get_method` to determine what HTTP method should be used. For example, this will send a ``'HEAD'`` request:: - >>> urlopen(Request('http://www.python.org', method='HEAD')) + >>> urlopen(Request('https://www.python.org', method='HEAD')) (:issue:`1673007`) @@ -2117,7 +2117,7 @@ The :mod:`webbrowser` module supports more "browsers": Google Chrome (named and the generic launchers :program:`xdg-open`, from the FreeDesktop.org project, and :program:`gvfs-open`, which is the default URI handler for GNOME 3. (The former contributed by Arnaud Calmettes in :issue:`13620`, the latter -by Matthias Klose in :issue:`14493`) +by Matthias Klose in :issue:`14493`.) xml.etree.ElementTree @@ -2160,7 +2160,7 @@ Major performance enhancements have been added: * UTF-8 is now 2x to 4x faster. UTF-16 encoding is now up to 10x faster. - (contributed by Serhiy Storchaka, :issue:`14624`, :issue:`14738` and + (Contributed by Serhiy Storchaka, :issue:`14624`, :issue:`14738` and :issue:`15026`.) @@ -2360,7 +2360,7 @@ Porting Python code bytecode file, make sure to call :func:`importlib.invalidate_caches` to clear out the cache for the finders to notice the new file. -* :exc:`ImportError` now uses the full name of the module that was attemped to +* :exc:`ImportError` now uses the full name of the module that was attempted to be imported. Doctests that check ImportErrors' message will need to be updated to use the full name of the module instead of just the tail of the name. diff --git a/Doc/whatsnew/3.4.rst b/Doc/whatsnew/3.4.rst index 301ab8f1653b..bc3a6cc8adc2 100644 --- a/Doc/whatsnew/3.4.rst +++ b/Doc/whatsnew/3.4.rst @@ -2,8 +2,7 @@ What's New In Python 3.4 **************************** -.. :Author: Someone <email> - (uncomment if there is a principal author) +:Author: R. David Murray <rdmurray@bitdance.com> (Editor) .. Rules for maintenance: @@ -18,7 +17,7 @@ time of the original release will remain largely unknown to the community for years, even if they're added later. We also know from experience that other priorities can arise, and the maintainer will run out of time to do - updates - in such cases, end users will be much better served by partial + updates -- in such cases, end users will be much better served by partial notifications that at least give a hint about new features to investigate. @@ -53,7 +52,7 @@ * It's helpful to add the bug/patch number as a comment: The :ref:`~socket.transmogrify()` function was added to the - :mod:`socket` module. (Contributed by P.Y. Developer in :issue:`12345`.) + :mod:`socket` module. (Contributed by P.Y. Developer in :issue:`12345`.) This saves the maintainer the effort of going through the Mercurial log when researching a change. @@ -62,23 +61,17 @@ while :ref:`~mod.attr` will display as ``attr``. This article explains the new features in Python 3.4, compared to 3.3. - -.. Python 3.4 was released on TBD. - -For full details, see the -`changelog <http://docs.python.org/3.4/whatsnew/changelog.html>`_. - -.. note:: Prerelease users should be aware that this document is currently in - draft form. It will be updated substantially as Python 3.4 moves towards - release, so it's worth checking back even after reading earlier versions. +Python 3.4 was released on March 16, 2014. For full details, see the +`changelog <https://docs.python.org/3.4/whatsnew/changelog.html>`_. .. seealso:: - :pep:`429` - Python 3.4 Release Schedule + :pep:`429` -- Python 3.4 Release Schedule -Summary -- Release highlights + +Summary -- Release Highlights ============================= .. This section singles out the most important changes in Python 3.4. @@ -86,94 +79,196 @@ Summary -- Release highlights New syntax features: -* No new syntax features are planned for Python 3.4. +* No new syntax features were added in Python 3.4. -New library modules: +Other new features: -* :mod:`asyncio`: New provisonal API for asynchronous IO (:pep:`3156`). -* :mod:`enum`: Support for enumeration types (:pep:`435`). -* :mod:`ensurepip`: Bootstrapping the pip installer (:pep:`453`). -* :mod:`pathlib`: Object-oriented filesystem paths (:pep:`428`). -* :mod:`selectors`: High-level and efficient I/O multiplexing, built upon the - :mod:`select` module primitives. -* :mod:`statistics`: A basic numerically stable statistics library (:pep:`450`). -* :mod:`tracemalloc`: Trace Python memory allocations (:pep:`454`). +* :ref:`pip should always be available <whatsnew-pep-453>` (:pep:`453`). +* :ref:`Newly created file descriptors are non-inheritable <whatsnew-pep-446>` + (:pep:`446`). +* command line option for :ref:`isolated mode <whatsnew-isolated-mode>` + (:issue:`16499`). +* :ref:`improvements in the handling of codecs <codec-handling-improvements>` + that are not text encodings (multiple issues). +* :ref:`A ModuleSpec Type <whatsnew-pep-451>` for the Import System + (:pep:`451`). (Affects importer authors.) +* The :mod:`marshal` format has been made :ref:`more compact and efficient + <whatsnew-marshal-3>` (:issue:`16475`). -New expected features for Python implementations: +New library modules: -* :ref:`PEP 446: Make newly created file descriptors non-inheritable <pep-446>`. -* command line option for :ref:`isolated mode <using-on-misc-options>`, +* :mod:`asyncio`: :ref:`New provisional API for asynchronous IO + <whatsnew-asyncio>` (:pep:`3156`). +* :mod:`ensurepip`: :ref:`Bootstrapping the pip installer <whatsnew-ensurepip>` + (:pep:`453`). +* :mod:`enum`: :ref:`Support for enumeration types <whatsnew-enum>` + (:pep:`435`). +* :mod:`pathlib`: :ref:`Object-oriented filesystem paths <whatsnew-pathlib>` + (:pep:`428`). +* :mod:`selectors`: :ref:`High-level and efficient I/O multiplexing + <whatsnew-selectors>`, built upon the :mod:`select` module primitives (part + of :pep:`3156`). +* :mod:`statistics`: A basic :ref:`numerically stable statistics library + <whatsnew-statistics>` (:pep:`450`). +* :mod:`tracemalloc`: :ref:`Trace Python memory allocations + <whatsnew-tracemalloc>` (:pep:`454`). + +Significantly improved library modules: + +* :ref:`Single-dispatch generic functions <whatsnew-singledispatch>` in + :mod:`functools` (:pep:`443`). +* New :mod:`pickle` :ref:`protocol 4 <whatsnew-protocol-4>` (:pep:`3154`). +* :mod:`multiprocessing` now has :ref:`an option to avoid using os.fork + on Unix <whatsnew-multiprocessing-no-fork>` (:issue:`8713`). +* :mod:`email` has a new submodule, :mod:`~email.contentmanager`, and + a new :mod:`~email.message.Message` subclass + (:class:`~email.contentmanager.EmailMessage`) that :ref:`simplify MIME + handling <whatsnew_email_contentmanager>` (:issue:`18891`). +* The :mod:`inspect` and :mod:`pydoc` modules are now capable of + correct introspection of a much wider variety of callable objects, + which improves the output of the Python :func:`help` system. +* The :mod:`ipaddress` module API has been declared stable + +Security improvements: + +* :ref:`Secure and interchangeable hash algorithm <whatsnew-pep-456>` + (:pep:`456`). +* :ref:`Make newly created file descriptors non-inheritable <whatsnew-pep-446>` + (:pep:`446`) to avoid leaking file descriptors to child processes. +* New command line option for :ref:`isolated mode <whatsnew-isolated-mode>`, (:issue:`16499`). -* :ref:`improvements <codec-handling-improvements>` in the handling of - codecs that are not text encodings +* :mod:`multiprocessing` now has :ref:`an option to avoid using os.fork + on Unix <whatsnew-multiprocessing-no-fork>`. *spawn* and *forkserver* are + more secure because they avoid sharing data with child processes. +* :mod:`multiprocessing` child processes on Windows no longer inherit + all of the parent's inheritable handles, only the necessary ones. +* A new :func:`hashlib.pbkdf2_hmac` function provides + the `PKCS#5 password-based key derivation function 2 + <http://en.wikipedia.org/wiki/PBKDF2>`_. +* :ref:`TLSv1.1 and TLSv1.2 support <whatsnew-tls-11-12>` for :mod:`ssl`. +* :ref:`Retrieving certificates from the Windows system cert store support + <whatsnew34-win-cert-store>` for :mod:`ssl`. +* :ref:`Server-side SNI (Server Name Indication) support + <whatsnew34-sni>` for :mod:`ssl`. +* The :class:`ssl.SSLContext` class has a :ref:`lot of improvements + <whatsnew34-sslcontext>`. +* All modules in the standard library that support SSL now support server + certificate verification, including hostname matching + (:func:`ssl.match_hostname`) and CRLs (Certificate Revocation lists, see + :func:`ssl.SSLContext.load_verify_locations`). -Significantly Improved Library Modules: +CPython implementation improvements: -* Single-dispatch generic functions in :mod:`functoools` (:pep:`443`) -* New :mod:`pickle` protocol 4 (:pep:`3154`) -* SHA-3 (Keccak) support for :mod:`hashlib`. -* TLSv1.1 and TLSv1.2 support for :mod:`ssl`. -* :mod:`multiprocessing` now has option to avoid using :func:`os.fork` - on Unix (:issue:`8713`). +* :ref:`Safe object finalization <whatsnew-pep-442>` (:pep:`442`). +* Leveraging :pep:`442`, in most cases :ref:`module globals are no longer set + to None during finalization <whatsnew-pep-442>` (:issue:`18214`). +* :ref:`Configurable memory allocators <whatsnew-pep-445>` (:pep:`445`). +* :ref:`Argument Clinic <whatsnew-pep-436>` (:pep:`436`). -CPython implementation improvements: +Please read on for a comprehensive list of user-facing changes, including many +other smaller improvements, CPython optimizations, deprecations, and potential +porting issues. -* :ref:`PEP 442: Safe object finalization <pep-442>` -* :ref:`PEP 445: Configurable memory allocators <pep-445>` -* :pep:`456` Secure and interchangeable hash algorithm -* Improve finalization of Python modules to avoid setting their globals - to None, in most cases (:issue:`18214`). -* A more efficient :mod:`marshal` format (:issue:`16475`). -* "Argument Clinic", an initial step towards providing improved introspection - support for builtin and standard library extension types implemented in C - (:pep:`436`) -Please read on for a comprehensive list of user-facing changes. +New Features +============ -PEP 453: Explicit bootstrapping of pip in Python installations -============================================================== +.. _whatsnew-pep-453: + +PEP 453: Explicit Bootstrapping of PIP in Python Installations +-------------------------------------------------------------- + +Bootstrapping pip By Default +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The new :mod:`ensurepip` module (defined in :pep:`453`) provides a standard -cross-platform mechanism to boostrap the pip installer into Python -installations and virtual environments. +cross-platform mechanism to bootstrap the pip installer into Python +installations and virtual environments. The version of ``pip`` included +with Python 3.4.0 is ``pip`` 1.5.4, and future 3.4.x maintenance releases +will update the bundled version to the latest version of ``pip`` that is +available at the time of creating the release candidate. + +By default, the commands ``pipX`` and ``pipX.Y`` will be installed on all +platforms (where X.Y stands for the version of the Python installation), +along with the ``pip`` Python package and its dependencies. On Windows and +in virtual environments on all platforms, the unversioned ``pip`` command +will also be installed. On other platforms, the system wide unversioned +``pip`` command typically refers to the separately installed Python 2 +version. + +The :ref:`pyvenv <scripts-pyvenv>` command line utility and the :mod:`venv` +module make use of the :mod:`ensurepip` module to make ``pip`` readily +available in virtual environments. When using the command line utility, +``pip`` is installed by default, while when using the :mod:`venv` module +:ref:`venv-api` installation of ``pip`` must be requested explicitly. + +For CPython :ref:`source builds on POSIX systems <building-python-on-unix>`, +the ``make install`` and ``make altinstall`` commands bootstrap ``pip`` by +default. This behaviour can be controlled through configure options, and +overridden through Makefile options. + +On Windows and Mac OS X, the CPython installers now default to installing +``pip`` along with CPython itself (users may opt out of installing it +during the installation process). Window users will need to opt in to the +automatic ``PATH`` modifications to have ``pip`` available from the command +line by default, otherwise it can still be accessed through the Python +launcher for Windows as ``py -m pip``. + +As `discussed in the PEP`__, platform packagers may choose not to install +these commands by default, as long as, when invoked, they provide clear and +simple directions on how to install them on that platform (usually using +the system package manager). + +__ https://www.python.org/dev/peps/pep-0453/#recommendations-for-downstream-distributors -The :mod:`venv` module and the :command:`pyvenv` utility make use of this -module to make ``pip`` readily available in virtual environments. When -using the command line interface, ``pip`` is installed by default, while -for the module API installation of ``pip`` must be requested explicitly. +.. note:: -For CPython source builds on POSIX systems, the ``make install`` and -``make altinstall`` commands bootstrap ``pip`` by default. This behaviour -can be controlled through configure options, and overridden through -Makefile options. + To avoid conflicts between parallel Python 2 and Python 3 installations, + only the versioned ``pip3`` and ``pip3.4`` commands are bootstrapped by + default when ``ensurepip`` is invoked directly - the ``--default-pip`` + option is needed to also request the unversioned ``pip`` command. + ``pyvenv`` and the Windows installer ensure that the unqualified ``pip`` + command is made available in those environments, and ``pip`` can always be + invoked via the ``-m`` switch rather than directly to avoid ambiguity on + systems with multiple Python installations. -On Windows and Mac OS X, the CPython installers now offer the option to -install ``pip`` along with CPython itself. -.. note:: +Documentation Changes +~~~~~~~~~~~~~~~~~~~~~ - The implementation of PEP 453 is still a work in progress. Refer to - :issue:`19347` for the progress on additional steps: +As part of this change, the :ref:`installing-index` and +:ref:`distributing-index` sections of the documentation have been +completely redesigned as short getting started and FAQ documents. Most +packaging documentation has now been moved out to the Python Packaging +Authority maintained `Python Packaging User Guide +<https://packaging.python.org>`__ and the documentation of the individual +projects. - * Having the binary installers install ``pip`` by default - * Recommending the use of ``pip`` in the "Installing Python Module" - documentation. +However, as this migration is currently still incomplete, the legacy +versions of those guides remaining available as :ref:`install-index` +and :ref:`distutils-index`. .. seealso:: - :pep:`453` - Explicit bootstrapping of pip in Python installations + :pep:`453` -- Explicit bootstrapping of pip in Python installations PEP written by Donald Stufft and Nick Coghlan, implemented by Donald Stufft, Nick Coghlan, Martin von Löwis and Ned Deily. -.. _pep-446: +.. _whatsnew-pep-446: -PEP 446: Make newly created file descriptors non-inheritable -============================================================ +PEP 446: Newly Created File Descriptors Are Non-Inheritable +----------------------------------------------------------- :pep:`446` makes newly created file descriptors :ref:`non-inheritable -<fd_inheritance>`. New functions and methods: +<fd_inheritance>`. In general, this is the behavior an application will +want: when launching a new process, having currently open files also +open in the new process can lead to all sorts of hard to find bugs, +and potentially to security issues. + +However, there are occasions when inheritance is desired. To support +these cases, the following new functions and methods are available: * :func:`os.get_inheritable`, :func:`os.set_inheritable` * :func:`os.get_handle_inheritable`, :func:`os.set_handle_inheritable` @@ -181,14 +276,14 @@ PEP 446: Make newly created file descriptors non-inheritable .. seealso:: - :pep:`446` - Make newly created file descriptors non-inheritable + :pep:`446` -- Make newly created file descriptors non-inheritable PEP written and implemented by Victor Stinner. .. _codec-handling-improvements: -Improvements to codec handling -============================== +Improvements to Codec Handling +------------------------------ Since it was first introduced, the :mod:`codecs` module has always been intended to operate as a type-neutral dynamic encoding and decoding @@ -204,10 +299,10 @@ module (and have been covered by the regression test suite) since Python 2.4, but were previously only discoverable through runtime introspection. Unlike the convenience methods on :class:`str`, :class:`bytes` and -:class:`bytearray`, these convenience functions support arbitrary codecs -in both Python 2 and Python 3, rather than being limited to Unicode text -encodings (in Python 3) or ``basestring`` <-> ``basestring`` conversions -(in Python 2). +:class:`bytearray`, the :mod:`codecs` convenience functions support arbitrary +codecs in both Python 2 and Python 3, rather than being limited to Unicode text +encodings (in Python 3) or ``basestring`` <-> ``basestring`` conversions (in +Python 2). In Python 3.4, the interpreter is able to identify the known non-text encodings provided in the standard library and direct users towards these @@ -223,14 +318,22 @@ general purpose convenience functions when appropriate:: File "<stdin>", line 1, in <module> LookupError: 'rot13' is not a text encoding; use codecs.encode() to handle arbitrary codecs + >>> open("foo.txt", encoding="hex") + Traceback (most recent call last): + File "<stdin>", line 1, in <module> + LookupError: 'hex' is not a text encoding; use codecs.open() to handle arbitrary codecs + In a related change, whenever it is feasible without breaking backwards compatibility, exceptions raised during encoding and decoding operations -will be wrapped in a chained exception of the same type that mentions the +are wrapped in a chained exception of the same type that mentions the name of the codec responsible for producing the error:: >>> import codecs >>> codecs.decode(b"abcdefgh", "hex") + Traceback (most recent call last): + File "/usr/lib/python3.4/encodings/hex_codec.py", line 20, in hex_decode + return (binascii.a2b_hex(input), len(input)) binascii.Error: Non-hexadecimal digit found The above exception was the direct cause of the following exception: @@ -240,6 +343,11 @@ name of the codec responsible for producing the error:: binascii.Error: decoding with 'hex' codec failed (Error: Non-hexadecimal digit found) >>> codecs.encode("hello", "bz2") + Traceback (most recent call last): + File "/usr/lib/python3.4/encodings/bz2_codec.py", line 17, in bz2_encode + return (bz2.compress(input), len(input)) + File "/usr/lib/python3.4/bz2.py", line 498, in compress + return comp.compress(data) + comp.flush() TypeError: 'str' does not support the buffer interface The above exception was the direct cause of the following exception: @@ -263,74 +371,95 @@ as:: The binary and text transforms provided in the standard library are detailed in :ref:`binary-transforms` and :ref:`text-transforms`. -(Contributed by Nick Coghlan in :issue:`7475`, , :issue:`17827`, -:issue:`17828` and :issue:`19619`) +(Contributed by Nick Coghlan in :issue:`7475`, :issue:`17827`, +:issue:`17828` and :issue:`19619`.) + -.. _pep-451: +.. _whatsnew-pep-451: PEP 451: A ModuleSpec Type for the Import System -================================================ +------------------------------------------------ -:pep:`451` provides an encapsulation of the information about a module -that the import machinery will use to load it, (i.e. a module spec). -This helps simplify both the import implementation and several -import-related APIs. The change is also a stepping stone for several -future import-related improvements. +:pep:`451` provides an encapsulation of the information about a module that the +import machinery will use to load it (that is, a module specification). This +helps simplify both the import implementation and several import-related APIs. +The change is also a stepping stone for `several future import-related +improvements`__. -https://mail.python.org/pipermail/python-dev/2013-November/130111.html +__ https://mail.python.org/pipermail/python-dev/2013-November/130111.html The public-facing changes from the PEP are entirely backward-compatible. -Furthermore, they should be transparent to everyone but importer -authors. Key finder and loader methods have been deprecated, but they -will continue working. New importers should use the new methods -described in the PEP. Existing importers should be updated to implement -the new methods. - - -Pickle protocol 4 -================= - -The new :mod:`pickle` protocol addresses a number of issues that were present -in previous protocols, such as the serialization of nested classes, very -large strings and containers, or classes whose :meth:`__new__` method takes -keyword-only arguments. It also brings a couple efficiency improvements. - -.. seealso:: - - :pep:`3154` - Pickle protocol 4 - PEP written by Antoine Pitrou and implemented by Alexandre Vassalotti. +Furthermore, they should be transparent to everyone but importer authors. Key +finder and loader methods have been deprecated, but they will continue working. +New importers should use the new methods described in the PEP. Existing +importers should be updated to implement the new methods. See the +:ref:`deprecated-3.4` section for a list of methods that should be replaced and +their replacements. Other Language Changes -====================== +---------------------- Some smaller changes made to the core Python language are: * Unicode database updated to UCD version 6.3. -* :func:`min` and :func:`max` now accept a *default* argument that can be used - to specify the value they return if the iterable they are evaluating has no - elements. Contributed by Julian Berman in :issue:`18111`. +* :func:`min` and :func:`max` now accept a *default* keyword-only argument that + can be used to specify the value they return if the iterable they are + evaluating has no elements. (Contributed by Julian Berman in + :issue:`18111`.) * Module objects are now :mod:`weakref`'able. * Module ``__file__`` attributes (and related values) should now always contain absolute paths by default, with the sole exception of ``__main__.__file__`` when a script has been executed directly using - a relative path (Contributed by Brett Cannon in :issue:`18416`). + a relative path. (Contributed by Brett Cannon in :issue:`18416`.) -* Now all the UTF-\* codecs (except UTF-7) reject surrogates during both +* All the UTF-\* codecs (except UTF-7) now reject surrogates during both encoding and decoding unless the ``surrogatepass`` error handler is used, - with the exception of the UTF-16 decoder that accepts valid surrogate pairs, - and the UTF-16 encoder that produces them while encoding non-BMP characters. - Contributed by Victor Stinner, Kang-Hao (Kenny) Lu and Serhiy Storchaka in - :issue:`12892`. + with the exception of the UTF-16 decoder (which accepts valid surrogate pairs) + and the UTF-16 encoder (which produces them while encoding non-BMP characters). + (Contributed by Victor Stinner, Kang-Hao (Kenny) Lu and Serhiy Storchaka in + :issue:`12892`.) + +* New German EBCDIC :ref:`codec <standard-encodings>` ``cp273``. (Contributed + by Michael Bierenfeld and Andrew Kuchling in :issue:`1097797`.) + +* New Ukrainian :ref:`codec <standard-encodings>` ``cp1125``. (Contributed by + Serhiy Storchaka in :issue:`19668`.) + +* :class:`bytes`.join() and :class:`bytearray`.join() now accept arbitrary + buffer objects as arguments. (Contributed by Antoine Pitrou in + :issue:`15958`.) + +* The :class:`int` constructor now accepts any object that has an ``__index__`` + method for its *base* argument. (Contributed by Mark Dickinson in + :issue:`16772`.) + +* Frame objects now have a :func:`~frame.clear` method that clears all + references to local variables from the frame. (Contributed by Antoine Pitrou + in :issue:`17934`.) + +* :class:`memoryview` is now registered as a :class:`Sequence <collections.abc>`, + and supports the :func:`reversed` builtin. (Contributed by Nick Coghlan + and Claudiu Popa in :issue:`18690` and :issue:`19078`.) + +* Signatures reported by :func:`help` have been modified and improved in + several cases as a result of the introduction of Argument Clinic and other + changes to the :mod:`inspect` and :mod:`pydoc` modules. + +* :meth:`~object.__length_hint__` is now part of the formal language + specification (see :pep:`424`). (Contributed by Armin Ronacher in + :issue:`16148`.) New Modules =========== +.. _whatsnew-asyncio: + asyncio ------- @@ -343,9 +472,38 @@ For Python 3.4, this module is considered a :term:`provisional API`. .. seealso:: - :pep:`3156` - Asynchronous IO Support Rebooted: the "asyncio" Module + :pep:`3156` -- Asynchronous IO Support Rebooted: the "asyncio" Module PEP written and implementation led by Guido van Rossum. + +.. _whatsnew-ensurepip: + +ensurepip +--------- + +The new :mod:`ensurepip` module is the primary infrastructure for the +:pep:`453` implementation. In the normal course of events end users will not +need to interact with this module, but it can be used to manually bootstrap +``pip`` if the automated bootstrapping into an installation or virtual +environment was declined. + +:mod:`ensurepip` includes a bundled copy of ``pip``, up-to-date as of the first +release candidate of the release of CPython with which it ships (this applies +to both maintenance releases and feature releases). ``ensurepip`` does not +access the internet. If the installation has Internet access, after +``ensurepip`` is run the bundled ``pip`` can be used to upgrade ``pip`` to a +more recent release than the bundled one. (Note that such an upgraded version +of ``pip`` is considered to be a separately installed package and will not be +removed if Python is uninstalled.) + +The module is named *ensure*\ pip because if called when ``pip`` is already +installed, it does nothing. It also has an ``--upgrade`` option that will +cause it to install the bundled copy of ``pip`` if the existing installed +version of ``pip`` is older than the bundled copy. + + +.. _whatsnew-enum: + enum ---- @@ -357,11 +515,13 @@ compatible enumeration values. .. seealso:: - :pep:`435` - Adding an Enum type to the Python standard library + :pep:`435` -- Adding an Enum type to the Python standard library PEP written by Barry Warsaw, Eli Bendersky and Ethan Furman, implemented by Ethan Furman. +.. _whatsnew-pathlib: + pathlib ------- @@ -375,10 +535,12 @@ For Python 3.4, this module is considered a :term:`provisional API`. .. seealso:: - :pep:`428` - The pathlib module -- object-oriented filesystem paths + :pep:`428` -- The pathlib module -- object-oriented filesystem paths PEP written and implemented by Antoine Pitrou. +.. _whatsnew-selectors: + selectors --------- @@ -387,6 +549,8 @@ allows high-level and efficient I/O multiplexing, built upon the :mod:`select` module primitives. +.. _whatsnew-statistics: + statistics ---------- @@ -397,9 +561,11 @@ deviation of a data series. .. seealso:: - :pep:`450` - Adding A Statistics Module To The Standard Library + :pep:`450` -- Adding A Statistics Module To The Standard Library PEP written and implemented by Steven D'Aprano +.. _whatsnew-tracemalloc: + tracemalloc ----------- @@ -407,34 +573,72 @@ tracemalloc The new :mod:`tracemalloc` module (defined in :pep:`454`) is a debug tool to trace memory blocks allocated by Python. It provides the following information: -* Traceback where an object was allocated +* Trace where an object was allocated * Statistics on allocated memory blocks per filename and per line number: total size, number and average size of allocated memory blocks * Compute the differences between two snapshots to detect memory leaks .. seealso:: - :pep:`454` - Add a new tracemalloc module to trace Python memory allocations + :pep:`454` -- Add a new tracemalloc module to trace Python memory allocations PEP written and implemented by Victor Stinner + Improved Modules ================ + +abc +--- + +New function :func:`abc.get_cache_token` can be used to know when to invalidate +caches that are affected by changes in the object graph. (Contributed +by Åukasz Langa in :issue:`16832`.) + +New class :class:`~abc.ABC` has :class:`~abc.ABCMeta` as its meta class. +Using ``ABC`` as a base class has essentially the same effect as specifying +``metaclass=abc.ABCMeta``, but is simpler to type and easier to read. +(Contributed by Bruno Dupuis in :issue:`16049`.) + + aifc ---- -The :meth:`~aifc.getparams` method now returns a namedtuple rather than a +The :meth:`~aifc.aifc.getparams` method now returns a namedtuple rather than a plain tuple. (Contributed by Claudiu Popa in :issue:`17818`.) +:func:`aifc.open` now supports the context management protocol: when used in a +:keyword:`with` block, the :meth:`~aifc.aifc.close` method of the returned +object will be called automatically at the end of the block. (Contributed by +Serhiy Storchacha in :issue:`16486`.) + +The :meth:`~aifc.aifc.writeframesraw` and :meth:`~aifc.aifc.writeframes` +methods now accept any :term:`bytes-like object`. (Contributed by Serhiy +Storchaka in :issue:`8311`.) + + +argparse +-------- + +The :class:`~argparse.FileType` class now accepts *encoding* and +*errors* arguments, which are passed through to :func:`open`. (Contributed +by Lucas Maystre in :issue:`11175`.) + audioop ------- -Added support for 24-bit samples (:issue:`12866`). +:mod:`audioop` now supports 24-bit samples. (Contributed by Serhiy Storchaka +in :issue:`12866`.) + +New :func:`~audioop.byteswap` function converts big-endian samples to +little-endian and vice versa. (Contributed by Serhiy Storchaka in +:issue:`19641`.) -Added the :func:`~audioop.byteswap` function to convert big-endian samples -to little-endian and vice versa (:issue:`19641`). +All :mod:`audioop` functions now accept any :term:`bytes-like object`. Strings +are not accepted: they didn't work before, now they raise an error right away. +(Contributed by Serhiy Storchaka in :issue:`16685`.) base64 @@ -442,7 +646,25 @@ base64 The encoding and decoding functions in :mod:`base64` now accept any :term:`bytes-like object` in cases where it previously required a -:class:`bytes` or :class:`bytearray` instance (:issue:`17839`). +:class:`bytes` or :class:`bytearray` instance. (Contributed by Nick Coghlan in +:issue:`17839`.) + +New functions :func:`~base64.a85encode`, :func:`~base64.a85decode`, +:func:`~base64.b85encode`, and :func:`~base64.b85decode` provide the ability to +encode and decode binary data from and to ``Ascii85`` and the git/mercurial +``Base85`` formats, respectively. The ``a85`` functions have options that can +be used to make them compatible with the variants of the ``Ascii85`` encoding, +including the Adobe variant. (Contributed by Martin Morrison, the Mercurial +project, Serhiy Storchaka, and Antoine Pitrou in :issue:`17618`.) + + +collections +----------- + +The :meth:`.ChainMap.new_child` method now accepts an *m* argument specifying +the child map to add to the chain. This allows an existing mapping and/or a +custom mapping type to be used for the child. (Contributed by Vinay Sajip in +:issue:`16613`.) colorsys @@ -451,6 +673,7 @@ colorsys The number of digits in the coefficients for the RGB --- YIQ conversions have been expanded so that they match the FCC NTSC versions. The change in results should be less than 1% and may better match results found elsewhere. +(Contributed by Brian Landers and Serhiy Storchaka in :issue:`14323`.) contextlib @@ -458,50 +681,112 @@ contextlib The new :class:`contextlib.suppress` context manager helps to clarify the intent of code that deliberately suppresses exceptions from a single -statement. (Contributed by Raymond Hettinger in :issue:`15806` and -Zero Piraeus in :issue:`19266`) +statement. (Contributed by Raymond Hettinger in :issue:`15806` and +Zero Piraeus in :issue:`19266`.) The new :func:`contextlib.redirect_stdout` context manager makes it easier -for utility scripts to handle inflexible APIs that don't provide any -options to retrieve their output as a string or direct it to somewhere -other than :data:`sys.stdout`. In conjunction with :class:`io.StringIO`, -this context manager is also useful for checking expected output from -command line utilities. (Contribute by Raymond Hettinger in :issue:`15805`) +for utility scripts to handle inflexible APIs that write their output to +:data:`sys.stdout` and don't provide any options to redirect it. Using the +context manager, the :data:`sys.stdout` output can be redirected to any +other stream or, in conjunction with :class:`io.StringIO`, to a string. +The latter can be especially useful, for example, to capture output +from a function that was written to implement a command line interface. +It is recommended only for utility scripts because it affects the +global state of :data:`sys.stdout`. (Contributed by Raymond Hettinger +in :issue:`15805`.) The :mod:`contextlib` documentation has also been updated to include a :ref:`discussion <single-use-reusable-and-reentrant-cms>` of the differences between single use, reusable and reentrant context managers. +dbm +--- + +:func:`dbm.open` objects now support the context management protocol. When +used in a :keyword:`with` statement, the ``close`` method of the database +object will be called automatically at the end of the block. (Contributed by +Claudiu Popa and Nick Coghlan in :issue:`19282`.) + + dis --- -The :mod:`dis` module is now built around an :class:`~dis.Instruction` class -that provides details of individual bytecode operations and a -:func:`~dis.get_instructions` iterator that emits the Instruction stream for a -given piece of Python code. The various display tools in the :mod:`dis` -module have been updated to be based on these new components. +Functions :func:`~dis.show_code`, :func:`~dis.dis`, :func:`~dis.distb`, and +:func:`~dis.disassemble` now accept a keyword-only *file* argument that +controls where they write their output. -The new :class:`dis.Bytecode` class provides an object-oriented API for -inspecting bytecode, both in human-readable form and for iterating over -instructions. +The :mod:`dis` module is now built around an :class:`~dis.Instruction` class +that provides object oriented access to the details of each individual bytecode +operation. + +A new method, :func:`~dis.get_instructions`, provides an iterator that emits +the Instruction stream for a given piece of Python code. Thus it is now +possible to write a program that inspects and manipulates a bytecode +object in ways different from those provided by the :mod:`~dis` module +itself. For example:: + + >>> import dis + >>> for instr in dis.get_instructions(lambda x: x + 1): + ... print(instr.opname) + LOAD_FAST + LOAD_CONST + BINARY_ADD + RETURN_VALUE + +The various display tools in the :mod:`dis` module have been rewritten to use +these new components. + +In addition, a new application-friendly class :class:`~dis.Bytecode` provides +an object-oriented API for inspecting bytecode in both in human-readable form +and for iterating over instructions. The :class:`~dis.Bytecode` constructor +takes the same arguments that :func:`~dis.get_instruction` does (plus an +optional *current_offset*), and the resulting object can be iterated to produce +:class:`~dis.Instruction` objects. But it also has a :mod:`~dis.Bytecode.dis` +method, equivalent to calling :mod:`~dis.dis` on the constructor argument, but +returned as a multi-line string:: + + >>> bytecode = dis.Bytecode(lambda x: x +1, current_offset=3) + >>> for instr in bytecode: + ... print('{} ({})'.format(instr.opname, instr.opcode)) + LOAD_FAST (124) + LOAD_CONST (100) + BINARY_ADD (23) + RETURN_VALUE (83) + >>> bytecode.dis().splitlines() # doctest: +NORMALIZE_WHITESPACE + [' 1 0 LOAD_FAST 0 (x)', + ' --> 3 LOAD_CONST 1 (1)', + ' 6 BINARY_ADD', + ' 7 RETURN_VALUE'] + +:class:`~dis.Bytecode` also has a class method, +:meth:`~dis.Bytecode.from_traceback`, that provides the ability to manipulate a +traceback (that is, ``print(Bytecode.from_traceback(tb).dis())`` is equivalent +to ``distb(tb)``). (Contributed by Nick Coghlan, Ryan Kelly and Thomas Kluyver in :issue:`11816` -and Claudiu Popa in :issue:`17916`) +and Claudiu Popa in :issue:`17916`.) + +New function :func:`~dis.stack_effect` computes the effect on the Python stack +of a given opcode and argument, information that is not otherwise available. +(Contributed by Larry Hastings in :issue:`19722`.) doctest ------- -Added :data:`~doctest.FAIL_FAST` flag to halt test running as soon as the first -failure is detected. (Contributed by R. David Murray and Daniel Urban in -:issue:`16522`.) +A new :ref:`option flag <doctest-options>`, :data:`~doctest.FAIL_FAST`, halts +test running as soon as the first failure is detected. (Contributed by R. +David Murray and Daniel Urban in :issue:`16522`.) -Updated the doctest command line interface to use :mod:`argparse`, and added -``-o`` and ``-f`` options to the interface. ``-o`` allows doctest options to -be specified on the command line, and ``-f`` is a shorthand for ``-o -FAIL_FAST`` (to parallel the similar option supported by the :mod:`unittest` -CLI). (Contributed by R. David Murray in :issue:`11390`.) +The :mod:`doctest` command line interface now uses :mod:`argparse`, and has two +new options, ``-o`` and ``-f``. ``-o`` allows :ref:`doctest options +<doctest-options>` to be specified on the command line, and ``-f`` is a +shorthand for ``-o FAIL_FAST`` (to parallel the similar option supported by the +:mod:`unittest` CLI). (Contributed by R. David Murray in :issue:`11390`.) + +:mod:`doctest` will now find doctests in extension module ``__doc__`` strings. +(Contributed by Zachary Ware in :issue:`3158`.) email @@ -511,7 +796,8 @@ email override the default policy of the message when generating a string representation of it. This means that ``as_string`` can now be used in more circumstances, instead of having to create and use a :mod:`~email.generator` in -order to pass formatting parameters to its ``flatten`` method. +order to pass formatting parameters to its ``flatten`` method. (Contributed by +R. David Murray in :issue:`18600`.) New method :meth:`~email.message.Message.as_bytes` added to produce a bytes representation of the message in a fashion similar to how ``as_string`` @@ -519,36 +805,59 @@ produces a string representation. It does not accept the *maxheaderlen* argument, but does accept the *unixfrom* and *policy* arguments. The :class:`~email.message.Message` :meth:`~email.message.Message.__bytes__` method calls it, meaning that ``bytes(mymsg)`` will now produce the intuitive -result: a bytes object containing the fully formatted message. +result: a bytes object containing the fully formatted message. (Contributed +by R. David Murray in :issue:`18600`.) + +The :meth:`.Message.set_param` message now accepts a *replace* keyword argument. +When specified, the associated header will be updated without changing +its location in the list of headers. For backward compatibility, the default +is ``False``. (Contributed by R. David Murray in :issue:`18891`.) + -(Contributed by R. David Murray in :issue:`18600`.) +.. _whatsnew_email_contentmanager: -A pair of new subclasses of :class:`~email.message.Message` have been added, -along with a new sub-module, :mod:`~email.contentmanager`. All documentation -is currently in the new module, which is being added as part of the new -:term:`provisional <provisional package>` email API. These classes provide a -number of new methods that make extracting content from and inserting content -into email messages much easier. See the :mod:`~email.contentmanager` -documentation for details. +A pair of new subclasses of :class:`~email.message.Message` have been added +(:class:`.EmailMessage` and :class:`.MIMEPart`), along with a new sub-module, +:mod:`~email.contentmanager` and a new :mod:`~email.policy` attribute +:attr:`~email.policy.EmailPolicy.content_manager`. All documentation is +currently in the new module, which is being added as part of email's new +:term:`provisional API`. These classes provide a number of new methods that +make extracting content from and inserting content into email messages much +easier. For details, see the :mod:`~email.contentmanager` documentation and +the :ref:`email-contentmanager-api-examples`. These API additions complete the +bulk of the work that was planned as part of the email6 project. The currently +provisional API is scheduled to become final in Python 3.5 (possibly with a few +minor additions in the area of error handling). (Contributed by R. David +Murray in :issue:`18891`.) + + +filecmp +------- -These API additions complete the bulk of the work that was planned as part of -the email6 project. The currently provisional API is scheduled to become final -in Python 3.5 (possibly with a few minor additions in the area of error -handling). +A new :func:`~filecmp.clear_cache` function provides the ability to clear the +:mod:`filecmp` comparison cache, which uses :func:`os.stat` information to +determine if the file has changed since the last compare. This can be used, +for example, if the file might have been changed and re-checked in less time +than the resolution of a particular filesystem's file modification time field. +(Contributed by Mark Levitt in :issue:`18149`.) -(Contributed by R. David Murray in :issue:`18891`.) +New module attribute :data:`~filecmp.DEFAULT_IGNORES` provides the list of +directories that are used as the default value for the *ignore* parameter of +the :func:`~filecmp.dircmp` function. (Contributed by Eli Bendersky in +:issue:`15442`.) functools --------- -The new :func:`~functools.partialmethod` descriptor bring partial argument +The new :func:`~functools.partialmethod` descriptor brings partial argument application to descriptors, just as :func:`~functools.partial` provides for normal callables. The new descriptor also makes it easier to get arbitrary callables (including :func:`~functools.partial` instances) to behave like normal instance methods when included in a class definition. +(Contributed by Alon Horev and Nick Coghlan in :issue:`4331`.) -(Contributed by Alon Horev and Nick Coghlan in :issue:`4331`) +.. _whatsnew-singledispatch: The new :func:`~functools.singledispatch` decorator brings support for single-dispatch generic functions to the Python standard library. Where @@ -559,152 +868,503 @@ multiple implementations of an operation that allows it to work with .. seealso:: - :pep:`443` - Single-dispatch generic functions + :pep:`443` -- Single-dispatch generic functions PEP written and implemented by Åukasz Langa. +:func:`~functools.total_ordering` now supports a return value of +:const:`NotImplemented` from the underlying comparison function. (Contributed +by Katie Miller in :issue:`10042`.) + +A pure-python version of the :func:`~functools.partial` function is now in the +stdlib; in CPython it is overridden by the C accelerated version, but it is +available for other implementations to use. (Contributed by Brian Thorne in +:issue:`12428`.) + + +gc +-- + +New function :func:`~gc.get_stats` returns a list of three per-generation +dictionaries containing the collections statistics since interpreter startup. +(Contributed by Antoine Pitrou in :issue:`16351`.) + + +glob +---- + +A new function :func:`~glob.escape` provides a way to escape special characters +in a filename so that they do not become part of the globbing expansion but are +instead matched literally. (Contributed by Serhiy Storchaka in :issue:`8402`.) + hashlib ------- -New :func:`hashlib.pbkdf2_hmac` function. +A new :func:`hashlib.pbkdf2_hmac` function provides +the `PKCS#5 password-based key derivation function 2 +<http://en.wikipedia.org/wiki/PBKDF2>`_. (Contributed by Christian +Heimes in :issue:`18582`.) -(Contributed by Christian Heimes in :issue:`18582`) +The :attr:`~hashlib.hash.name` attribute of :mod:`hashlib` hash objects is now +a formally supported interface. It has always existed in CPython's +:mod:`hashlib` (although it did not return lower case names for all supported +hashes), but it was not a public interface and so some other Python +implementations have not previously supported it. (Contributed by Jason R. +Coombs in :issue:`18532`.) -html +hmac ---- -Added a new :func:`html.unescape` function that converts HTML5 character -references to the corresponding Unicode characters. +:mod:`hmac` now accepts ``bytearray`` as well as ``bytes`` for the *key* +argument to the :func:`~hmac.new` function, and the *msg* parameter to both the +:func:`~hmac.new` function and the :meth:`~hmac.HMAC.update` method now +accepts any type supported by the :mod:`hashlib` module. (Contributed +by Jonas Borgström in :issue:`18240`.) -(Contributed by Ezio Melotti in :issue:`2927`) +The *digestmod* argument to the :func:`hmac.new` function may now be any hash +digest name recognized by :mod:`hashlib`. In addition, the current behavior in +which the value of *digestmod* defaults to ``MD5`` is deprecated: in a +future version of Python there will be no default value. (Contributed by +Christian Heimes in :issue:`17276`.) -Added a new *convert_charrefs* keyword argument to -:class:`~html.parser.HTMLParser` that, when ``True``, automatically converts -all character references. For backward-compatibility, its value defaults -to ``False``, but it will change to ``True`` in future versions, so you -are invited to set it explicitly and update your code to use this new feature. +With the addition of :attr:`~hmac.HMAC.block_size` and :attr:`~hmac.HMAC.name` +attributes (and the formal documentation of the :attr:`~hmac.HMAC.digest_size` +attribute), the :mod:`hmac` module now conforms fully to the :pep:`247` API. +(Contributed by Christian Heimes in :issue:`18775`.) -(Contributed by Ezio Melotti in :issue:`13633`) + +html +---- + +New function :func:`~html.unescape` function converts HTML5 character references to +the corresponding Unicode characters. (Contributed by Ezio Melotti in +:issue:`2927`.) + +:class:`~html.parser.HTMLParser` accepts a new keyword argument +*convert_charrefs* that, when ``True``, automatically converts all character +references. For backward-compatibility, its value defaults to ``False``, but +it will change to ``True`` in a future version of Python, so you are invited to +set it explicitly and update your code to use this new feature. (Contributed +by Ezio Melotti in :issue:`13633`.) The *strict* argument of :class:`~html.parser.HTMLParser` is now deprecated. +(Contributed by Ezio Melotti in :issue:`15114`.) + + +http +---- + +:meth:`~http.server.BaseHTTPRequestHandler.send_error` now accepts an +optional additional *explain* parameter which can be used to provide an +extended error description, overriding the hardcoded default if there is one. +This extended error description will be formatted using the +:attr:`~http.server.HTTP.error_message_format` attribute and sent as the body +of the error response. (Contributed by Karl Cow in :issue:`12921`.) + +The :mod:`http.server` :ref:`command line interface <http-server-cli>` now has +a ``-b/--bind`` option that causes the server to listen on a specific address. +(Contributed by Malte Swart in :issue:`17764`.) + + +importlib +--------- + +The :class:`~importlib.abc.InspectLoader` ABC defines a new method, +:meth:`~importlib.abc.InspectLoader.source_to_code` that accepts source +data and a path and returns a code object. The default implementation +is equivalent to ``compile(data, path, 'exec', dont_inherit=True)``. +(Contributed by Eric Snow and Brett Cannon in :issue:`15627`.) + +:class:`~importlib.abc.InspectLoader` also now has a default implementation +for the :meth:`~importlib.abc.InspectLoader.get_code` method. However, +it will normally be desirable to override the default implementation +for performance reasons. (Contributed by Brett Cannon in :issue:`18072`.) + +The :func:`~importlib.reload` function has been moved from :mod:`imp` to +:mod:`importlib` as part of the :mod:`imp` module deprecation. (Contributed by +Berker Peksag in :issue:`18193`.) + +:mod:`importlib.util` now has a :data:`~importlib.util.MAGIC_NUMBER` attribute +providing access to the bytecode version number. This replaces the +:func:`~imp.get_magic` function in the deprecated :mod:`imp` module. +(Contributed by Brett Cannon in :issue:`18192`.) + +New :mod:`importlib.util` functions :func:`~importlib.util.cache_from_source` +and :func:`~importlib.util.source_from_cache` replace the same-named functions +in the deprecated :mod:`imp` module. (Contributed by Brett Cannon in +:issue:`18194`.) -(Contributed by Ezio Melotti in :issue:`15114`) +The :mod:`importlib` bootstrap :class:`.NamespaceLoader` now conforms to +the :class:`.InspectLoader` ABC, which means that ``runpy`` and +``python -m`` can now be used with namespace packages. (Contributed +by Brett Cannon in :issue:`18058`.) + +:mod:`importlib.util` has a new function :func:`~importlib.util.decode_source` +that decodes source from bytes using universal newline processing. This is +useful for implementing :meth:`.InspectLoader.get_source` methods. + +:class:`importlib.machinery.ExtensionFileLoader` now has a +:meth:`~importlib.machinery.ExtensionFileLoader.get_filename` method. This was +inadvertently omitted in the original implementation. (Contributed by Eric +Snow in :issue:`19152`.) inspect ------- - -The inspect module now offers a basic :ref:`command line interface +The :mod:`inspect` module now offers a basic :ref:`command line interface <inspect-module-cli>` to quickly display source code and other -information for modules, classes and functions. (Contributed by Claudiu Popa -and Nick Coghlan in :issue:`18626`) +information for modules, classes and functions. (Contributed by Claudiu Popa +and Nick Coghlan in :issue:`18626`.) :func:`~inspect.unwrap` makes it easy to unravel wrapper function chains created by :func:`functools.wraps` (and any other API that sets the -``__wrapped__`` attribute on a wrapper function). (Contributed by -Daniel Urban, Aaron Iles and Nick Coghlan in :issue:`13266`) +``__wrapped__`` attribute on a wrapper function). (Contributed by +Daniel Urban, Aaron Iles and Nick Coghlan in :issue:`13266`.) As part of the implementation of the new :mod:`enum` module, the :mod:`inspect` module now has substantially better support for custom ``__dir__`` methods and dynamic class attributes provided through -metaclasses (Contributed by Ethan Furman in :issue:`18929` and -:issue:`19030`) +metaclasses. (Contributed by Ethan Furman in :issue:`18929` and +:issue:`19030`.) + +:func:`~inspect.getfullargspec` and :func:`~inspect.getargspec` +now use the :func:`~inspect.signature` API. This allows them to +support a much broader range of callables, including those with +``__signature__`` attributes, those with metadata provided by argument +clinic, :func:`functools.partial` objects and more. Note that, unlike +:func:`~inspect.signature`, these functions still ignore ``__wrapped__`` +attributes, and report the already bound first argument for bound methods, +so it is still necessary to update your code to use +:func:`~inspect.signature` directly if those features are desired. +(Contributed by Yury Selivanov in :issue:`17481`.) + +:func:`~inspect.signature` now supports duck types of CPython functions, +which adds support for functions compiled with Cython. (Contributed +by Stefan Behnel and Yury Selivanov in :issue:`17159`.) + + +ipaddress +--------- + +:mod:`ipaddress` was added to the standard library in Python 3.3 as a +:term:`provisional API`. With the release of Python 3.4, this qualification +has been removed: :mod:`ipaddress` is now considered a stable API, covered +by the normal standard library requirements to maintain backwards +compatibility. + +A new :attr:`~ipaddress.IPv4Address.is_global` property is ``True`` if +an address is globally routeable. (Contributed by Peter Moody in +:issue:`17400`.) + + +logging +------- + +The :class:`~logging.handlers.TimedRotatingFileHandler` has a new *atTime* +parameter that can be used to specify the time of day when rollover should +happen. (Contributed by Ronald Oussoren in :issue:`9556`.) + +:class:`~logging.handlers.SocketHandler` and +:class:`~logging.handlers.DatagramHandler` now support Unix domain sockets (by +setting *port* to ``None``). (Contributed by Vinay Sajip in commit +ce46195b56a9.) + +:func:`~logging.config.fileConfig` now accepts a +:class:`configparser.RawConfigParser` subclass instance for the *fname* +parameter. This facilitates using a configuration file when logging +configuration is just a part of the overall application configuration, or where +the application modifies the configuration before passing it to +:func:`~logging.config.fileConfig`. (Contributed by Vinay Sajip in +:issue:`16110`.) + +Logging configuration data received from a socket via the +:func:`logging.config.listen` function can now be validated before being +processed by supplying a verification function as the argument to the new +*verify* keyword argument. (Contributed by Vinay Sajip in :issue:`15452`.) + + +.. _whatsnew-marshal-3: + +marshal +------- + +The default :mod:`marshal` version has been bumped to 3. The code implementing +the new version restores the Python2 behavior of recording only one copy of +interned strings and preserving the interning on deserialization, and extends +this "one copy" ability to any object type (including handling recursive +references). This reduces both the size of ``.pyc`` files and the amount of +memory a module occupies in memory when it is loaded from a ``.pyc`` (or +``.pyo``) file. (Contributed by Kristján Valur Jónsson in :issue:`16475`, +with additional speedups by Antoine Pitrou in :issue:`19219`.) mmap ---- -mmap objects can now be weakref'ed. - -(Contributed by Valerie Lambert in :issue:`4885`.) +mmap objects can now be :mod:`weakref`\ ed. (Contributed by Valerie Lambert in +:issue:`4885`.) multiprocessing --------------- -On Unix two new *start methods* have been added for starting processes -using :mod:`multiprocessing`. These make the mixing of processes with -threads more robust. See :issue:`8713`. +.. _whatsnew-multiprocessing-no-fork: + +On Unix two new :ref:`start methods <multiprocessing-start-methods>`, +(``spawn`` and ``forkserver``, have been added for starting processes using +:mod:`multiprocessing`. These make the mixing of processes with threads more +robust, and the ``spawn`` method matches the semantics that multiprocessing has +always used on Windows. New function +:func:`~multiprocessing.get_all_start_methods` reports all start methods +available on the platform, :func:`~multiprocessing.get_start_method` reports +the current start method, and :func:`~multiprocessing.set_start_method` sets +the start method. (Contributed by Richard Oudkerk in :issue:`8713`.) + +:mod:`multiprocessing` also now has the concept of a ``context``, which +determines how child processes are created. New function +:func:`~multiprocessing.get_context` returns a context that uses a specified +start method. It has the same API as the :mod:`multiprocessing` module itself, +so you can use it to create :class:`~multiprocessing.pool.Pool`\ s and other +objects that will operate within that context. This allows a framework and an +application or different parts of the same application to use multiprocessing +without interfering with each other. (Contributed by Richard Oudkerk in +:issue:`18999`.) + +Except when using the old *fork* start method, child processes no longer +inherit unneeded handles/file descriptors from their parents (part of +:issue:`8713`). + +:mod:`multiprocessing` now relies on :mod:`runpy` (which implements the +``-m`` switch) to initialise ``__main__`` appropriately in child processes +when using the ``spawn`` or ``forkserver`` start methods. This resolves some +edge cases where combining multiprocessing, the ``-m`` command line switch, +and explicit relative imports could cause obscure failures in child +processes. (Contributed by Nick Coghlan in :issue:`19946`.) + + +operator +-------- + +New function :func:`~operator.length_hint` provides an implementation of the +specification for how the :meth:`~object.__length_hint__` special method should +be used, as part of the :pep:`424` formal specification of this language +feature. (Contributed by Armin Ronacher in :issue:`16148`.) -Also, except when using the old *fork* start method, child processes -will no longer inherit unneeded handles/file descriptors from their parents. +There is now a pure-python version of the :mod:`operator` module available for +reference and for use by alternate implementations of Python. (Contributed by +Zachary Ware in :issue:`16694`.) os -- -New functions to get and set the :ref:`inheritable flag <fd_inheritance>` of a file -descriptors or a Windows handle: +There are new functions to get and set the :ref:`inheritable flag +<fd_inheritance>` of a file descriptor (:func:`os.get_inheritable`, +:func:`os.set_inheritable`) or a Windows handle +(:func:`os.get_handle_inheritable`, :func:`os.set_handle_inheritable`). -* :func:`os.get_inheritable`, :func:`os.set_inheritable` -* :func:`os.get_handle_inheritable`, :func:`os.set_handle_inheritable` +New function :func:`~os.cpu_count` reports the number of CPUs available on the +platform on which Python is running (or ``None`` if the count can't be +determined). The :func:`multiprocessing.cpu_count` function is now implemented +in terms of this function). (Contributed by Trent Nelson, Yogesh Chaudhari, +Victor Stinner, and Charles-François Natali in :issue:`17914`.) + +:func:`os.path.samestat` is now available on the Windows platform (and the +:func:`os.path.samefile` implementation is now shared between Unix and +Windows). (Contributed by Brian Curtin in :issue:`11939`.) + +:func:`os.path.ismount` now recognizes volumes mounted below a drive +root on Windows. (Contributed by Tim Golden in :issue:`9035`.) + +:func:`os.open` supports two new flags on platforms that provide them, +:data:`~os.O_PATH` (un-opened file descriptor), and :data:`~os.O_TMPFILE` +(unnamed temporary file; as of 3.4.0 release available only on Linux systems +with a kernel version of 3.11 or newer that have uapi headers). (Contributed +by Christian Heimes in :issue:`18673` and Benjamin Peterson, respectively.) pdb --- -The ``print`` command has been removed from :mod:`pdb`, restoring access to the -``print`` function. +:mod:`pdb` has been enhanced to handle generators, :keyword:`yield`, and +``yield from`` in a more useful fashion. This is especially helpful when +debugging :mod:`asyncio` based programs. (Contributed by Andrew Svetlov and +Xavier de Gaye in :issue:`16596`.) -Rationale: Python2's ``pdb`` did not have a ``print`` command; instead, -entering ``print`` executed the ``print`` statement. In Python3 ``print`` was -mistakenly made an alias for the pdb :pdbcmd:`p` command. ``p``, however, -prints the ``repr`` of its argument, not the ``str`` like the Python2 ``print`` -command did. Worse, the Python3 ``pdb print`` command shadowed the Python3 -``print`` function, making it inaccessible at the ``pdb`` prompt. +The ``print`` command has been removed from :mod:`pdb`, restoring access to the +Python :func:`print` function from the pdb command line. Python2's ``pdb`` did +not have a ``print`` command; instead, entering ``print`` executed the +``print`` statement. In Python3 ``print`` was mistakenly made an alias for the +pdb :pdbcmd:`p` command. ``p``, however, prints the ``repr`` of its argument, +not the ``str`` like the Python2 ``print`` command did. Worse, the Python3 +``pdb print`` command shadowed the Python3 ``print`` function, making it +inaccessible at the ``pdb`` prompt. (Contributed by Connor Osborn in +:issue:`18764`.) -(Contributed by Connor Osborn in :issue:`18764`.) +.. _whatsnew-protocol-4: -poplib +pickle ------ -New :meth:`~poplib.POP3.stls` method to switch a clear-text POP3 session into -an encrypted POP3 session. +:mod:`pickle` now supports (but does not use by default) a new pickle protocol, +protocol 4. This new protocol addresses a number of issues that were present +in previous protocols, such as the serialization of nested classes, very large +strings and containers, and classes whose :meth:`__new__` method takes +keyword-only arguments. It also provides some efficiency improvements. -New :meth:`~poplib.POP3.capa` method to query the capabilities advertised by the -POP3 server. +.. seealso:: + + :pep:`3154` -- Pickle protocol 4 + PEP written by Antoine Pitrou and implemented by Alexandre Vassalotti. + + +plistlib +-------- -(Contributed by Lorenzo Catucci in :issue:`4473`.) +:mod:`plistlib` now has an API that is similar to the standard pattern for +stdlib serialization protocols, with new :func:`~plistlib.load`, +:func:`~plistlib.dump`, :func:`~plistlib.loads`, and :func:`~plistlib.dumps` +functions. (The older API is now deprecated.) In addition to the already +supported XML plist format (:data:`~plistlib.FMT_XML`), it also now supports +the binary plist format (:data:`~plistlib.FMT_BINARY`). (Contributed by Ronald +Oussoren and others in :issue:`14455`.) + + +poplib +------ + +Two new methods have been added to :mod:`poplib`: :meth:`~poplib.POP3.capa`, +which returns the list of capabilities advertised by the POP server, and +:meth:`~poplib.POP3.stls`, which switches a clear-text POP3 session into an +encrypted POP3 session if the POP server supports it. (Contributed by Lorenzo +Catucci in :issue:`4473`.) pprint ------ -The :mod:`pprint` module now supports *compact* mode for formatting long -sequences (:issue:`19132`). +The :mod:`pprint` module's :class:`~pprint.PrettyPrinter` class and its +:func:`~pprint.pformat`, and :func:`~pprint.pprint` functions have a new +option, *compact*, that controls how the output is formatted. Currently +setting *compact* to ``True`` means that sequences will be printed with as many +sequence elements as will fit within *width* on each (indented) line. +(Contributed by Serhiy Storchaka in :issue:`19132`.) + +Long strings are now wrapped using Python's normal line continuation +syntax. (Contributed by Antoine Pitrou in :issue:`17150`.) + + +pty +--- + +:func:`pty.spawn` now returns the status value from :func:`os.waitpid` on +the child process, instead of ``None``. (Contributed by Gregory P. Smith.) pydoc ----- -While significant changes have not been made to :mod:`pydoc` directly, +The :mod:`pydoc` module is now based directly on the :func:`inspect.signature` +introspection API, allowing it to provide signature information for a wider +variety of callable objects. This change also means that ``__wrapped__`` +attributes are now taken into account when displaying help information. +(Contributed by Larry Hastings in :issue:`19674`.) + +The :mod:`pydoc` module no longer displays the ``self`` parameter for +already bound methods. Instead, it aims to always display the exact current +signature of the supplied callable. (Contributed by Larry Hastings in +:issue:`20710`.) + +In addition to the changes that have been made to :mod:`pydoc` directly, its handling of custom ``__dir__`` methods and various descriptor -behaviours has been improved substantially by the underlying changes in +behaviours has also been improved substantially by the underlying changes in the :mod:`inspect` module. +As the :func:`help` builtin is based on :mod:`pydoc`, the above changes also +affect the behaviour of :func:`help`. + re -- -Added :func:`re.fullmatch` function and :meth:`regex.fullmatch` method, -which anchor the pattern at both ends of the string to match. -(Contributed by Matthew Barnett in :issue:`16203`.) +New :func:`~re.fullmatch` function and :meth:`.regex.fullmatch` method anchor +the pattern at both ends of the string to match. This provides a way to be +explicit about the goal of the match, which avoids a class of subtle bugs where +``$`` characters get lost during code changes or the addition of alternatives +to an existing regular expression. (Contributed by Matthew Barnett in +:issue:`16203`.) The repr of :ref:`regex objects <re-objects>` now includes the pattern and the flags; the repr of :ref:`match objects <match-objects>` now -includes the start, end, and the part of the string that matched. - -(Contributed by Serhiy Storchaka in :issue:`13592` and :issue:`17087`.) +includes the start, end, and the part of the string that matched. (Contributed +by Hugo Lopes Tavares and Serhiy Storchaka in :issue:`13592` and +:issue:`17087`.) resource -------- -New :func:`resource.prlimit` function and Linux specific constants. -(Contributed by Christian Heimes in :issue:`16595` and :issue:`19324`.) +New :func:`~resource.prlimit` function, available on Linux platforms with a +kernel version of 2.6.36 or later and glibc of 2.13 or later, provides the +ability to query or set the resource limits for processes other than the one +making the call. (Contributed by Christian Heimes in :issue:`16595`.) + +On Linux kernel version 2.6.36 or later, there are there are also some new +Linux specific constants: :attr:`~resource.RLIMIT_MSGQUEUE`, +:attr:`~resource.RLIMIT_NICE`, :attr:`~resource.RLIMIT_RTPRIO`, +:attr:`~resource.RLIMIT_RTTIME`, and :attr:`~resource.RLIMIT_SIGPENDING`. +(Contributed by Christian Heimes in :issue:`19324`.) + +On FreeBSD version 9 and later, there some new FreeBSD specific constants: +:attr:`~resource.RLIMIT_SBSIZE`, :attr:`~resource.RLIMIT_SWAP`, and +:attr:`~resource.RLIMIT_NPTS`. (Contributed by Claudiu Popa in +:issue:`19343`.) + + +select +------ + +:class:`~select.epoll` objects now support the context management protocol. +When used in a :keyword:`with` statement, the :meth:`~select.epoll.close` +method will be called automatically at the end of the block. (Contributed +by Serhiy Storchaka in :issue:`16488`.) + +:class:`~select.devpoll` objects now have :meth:`~select.devpoll.fileno` and +:meth:`~select.devpoll.close` methods, as well as a new attribute +:attr:`~select.devpoll.closed`. (Contributed by Victor Stinner in +:issue:`18794`.) + + +shelve +------ + +:class:`~shelve.Shelf` instances may now be used in :keyword:`with` statements, +and will be automatically closed at the end of the :keyword:`with` block. +(Contributed by Filip GruszczyÅ„ski in :issue:`13896`.) + + +shutil +------ + +:func:`~shutil.copyfile` now raises a specific :exc:`~shutil.Error` subclass, +:exc:`~shutil.SameFileError`, when the source and destination are the same +file, which allows an application to take appropriate action on this specific +error. (Contributed by Atsuo Ishimoto and Hynek Schlawack in +:issue:`1492704`.) + + +smtpd +----- + +The :class:`~smtpd.SMTPServer` and :class:`~smtpd.SMTPChannel` classes now +accept a *map* keyword argument which, if specified, is passed in to +:class:`asynchat.async_chat` as its *map* argument. This allows an application +to avoid affecting the global socket map. (Contributed by Vinay Sajip in +:issue:`11959`.) + smtplib ------- @@ -712,69 +1372,222 @@ smtplib :exc:`~smtplib.SMTPException` is now a subclass of :exc:`OSError`, which allows both socket level errors and SMTP protocol level errors to be caught in one try/except statement by code that only cares whether or not an error occurred. -(:issue:`2118`). +(Contributed by Ned Jackson Lovely in :issue:`2118`.) socket ------ +The socket module now supports the :data:`~socket.CAN_BCM` protocol on +platforms that support it. (Contributed by Brian Thorne in :issue:`15359`.) + Socket objects have new methods to get or set their :ref:`inheritable flag -<fd_inheritance>`: +<fd_inheritance>`, :meth:`~socket.socket.get_inheritable` and +:meth:`~socket.socket.set_inheritable`. -* :meth:`socket.socket.get_inheritable`, :meth:`socket.socket.set_inheritable` +The ``socket.AF_*`` and ``socket.SOCK_*`` constants are now enumeration values +using the new :mod:`enum` module. This allows meaningful names to be printed +during debugging, instead of integer "magic numbers". -The ``socket.AF_*`` and ``socket.SOCK_*`` constants are enumeration values, -using the new :mod:`enum` module. This allows descriptive reporting during -debugging, instead of seeing integer "magic numbers". +The :data:`~socket.AF_LINK` constant is now available on BSD and OSX. -ssl ---- +:func:`~socket.inet_pton` and :func:`~socket.inet_ntop` are now supported +on Windows. (Contributed by Atsuo Ishimoto in :issue:`7171`.) -TLSv1.1 and TLSv1.2 support. -(Contributed by Michele Orrù and Antoine Pitrou in :issue:`16692`) +sqlite3 +------- -* New diagnostic functions :func:`~ssl.get_default_verify_paths`, - :meth:`~ssl.SSLContext.cert_store_stats` and - :meth:`~ssl.SSLContext.get_ca_certs` +A new boolean parameter to the :func:`~sqlite3.connect` function, *uri*, can be +used to indicate that the *database* parameter is a ``uri`` (see the `SQLite +URI documentation <http://www.sqlite.org/uri.html>`_). (Contributed by poq in +:issue:`13773`.) -* Add :func:`ssl.enum_cert_store` to retrieve certificates and CRL from Windows' - cert store. -(Contributed by Christian Heimes in :issue:`18143`, :issue:`18147` and - :issue:`17134`.) +ssl +--- -Support for server-side SNI using the new +.. _whatsnew-tls-11-12: + +:data:`~ssl.PROTOCOL_TLSv1_1` and :data:`~ssl.PROTOCOL_TLSv1_2` (TLSv1.1 and +TLSv1.2 support) have been added; support for these protocols is only available if +Python is linked with OpenSSL 1.0.1 or later. (Contributed by Michele Orrù and +Antoine Pitrou in :issue:`16692`.) + +.. _whatsnew34-sslcontext: + +New function :func:`~ssl.create_default_context` provides a standard way to +obtain an :class:`~ssl.SSLContext` whose settings are intended to be a +reasonable balance between compatibility and security. These settings are +more stringent than the defaults provided by the :class:`~ssl.SSLContext` +constructor, and may be adjusted in the future, without prior deprecation, if +best-practice security requirements change. The new recommended best +practice for using stdlib libraries that support SSL is to use +:func:`~ssl.create_default_context` to obtain an :class:`~ssl.SSLContext` +object, modify it if needed, and then pass it as the *context* argument +of the appropriate stdlib API. (Contributed by Christian Heimes +in :issue:`19689`.) + +:class:`~ssl.SSLContext` method :meth:`~ssl.SSLContext.load_verify_locations` +accepts a new optional argument *cadata*, which can be used to provide PEM or +DER encoded certificates directly via strings or bytes, respectively. +(Contributed by Christian Heimes in :issue:`18138`.) + +New function :func:`~ssl.get_default_verify_paths` returns +a named tuple of the paths and environment variables that the +:meth:`~ssl.SSLContext.set_default_verify_paths` method uses to set +OpenSSL's default ``cafile`` and ``capath``. This can be an aid in +debugging default verification issues. (Contributed by Christian Heimes +in :issue:`18143`.) + +:class:`~ssl.SSLContext` has a new method, +:meth:`~ssl.SSLContext.cert_store_stats`, that reports the number of loaded +``X.509`` certs, ``X.509 CA`` certs, and certificate revocation lists (``crl``\ +s), as well as a :meth:`~ssl.SSLContext.get_ca_certs` method that returns a +list of the loaded ``CA`` certificates. (Contributed by Christian Heimes in +:issue:`18147`.) + +If OpenSSL 0.9.8 or later is available, :class:`~ssl.SSLContext` has an new +attribute :attr:`~ssl.SSLContext.verify_flags` that can be used to control the +certificate verification process by setting it to some combination of the new +constants :data:`~ssl.VERIFY_DEFAULT`, :data:`~ssl.VERIFY_CRL_CHECK_LEAF`, +:data:`~ssl.VERIFY_CRL_CHECK_CHAIN`, or :data:`~ssl.VERIFY_X509_STRICT`. +OpenSSL does not do any CRL verification by default. (Contributed by +Christien Heimes in :issue:`8813`.) + +New :class:`~ssl.SSLContext` method :meth:`~ssl.SSLContext.load_default_certs` +loads a set of default "certificate authority" (CA) certificates from default +locations, which vary according to the platform. It can be used to load both +TLS web server authentication certificates +(``purpose=``:data:`~ssl.Purpose.SERVER_AUTH`) for a client to use to verify a +server, and certificates for a server to use in verifying client certificates +(``purpose=``:data:`~ssl.Purpose.CLIENT_AUTH`). (Contributed by Christian +Heimes in :issue:`19292`.) + +.. _whatsnew34-win-cert-store: + +Two new windows-only functions, :func:`~ssl.enum_certificates` and +:func:`~ssl.enum_crls` provide the ability to retrieve certificates, +certificate information, and CRLs from the Windows cert store. (Contributed +by Christian Heimes in :issue:`17134`.) + +.. _whatsnew34-sni: + +Support for server-side SNI (Server Name Indication) using the new :meth:`ssl.SSLContext.set_servername_callback` method. - (Contributed by Daniel Black in :issue:`8109`.) +The dictionary returned by :meth:`.SSLSocket.getpeercert` contains additional +``X509v3`` extension items: ``crlDistributionPoints``, ``calIssuers``, and +``OCSP`` URIs. (Contributed by Christian Heimes in :issue:`18379`.) + stat ---- The :mod:`stat` module is now backed by a C implementation in :mod:`_stat`. A C implementation is required as most of the values aren't standardized and -platform-dependent. (Contributed by Christian Heimes in :issue:`11016`.) +are platform-dependent. (Contributed by Christian Heimes in :issue:`11016`.) -The module supports new file types: door, event port and whiteout. +The module supports new :mod:`~stat.ST_MODE` flags, :mod:`~stat.S_IFDOOR`, +:attr:`~stat.S_IFPORT`, and :attr:`~stat.S_IFWHT`. (Contributed by +Christian Hiemes in :issue:`11016`.) struct ------ -Streaming struct unpacking using :func:`struct.iter_unpack`. - +New function :mod:`~struct.iter_unpack` and a new +:meth:`struct.Struct.iter_unpack` method on compiled formats provide streamed +unpacking of a buffer containing repeated instances of a given format of data. (Contributed by Antoine Pitrou in :issue:`17804`.) +subprocess +---------- + +:func:`~subprocess.check_output` now accepts an *input* argument that can +be used to provide the contents of ``stdin`` for the command that is run. +(Contributed by Zack Weinberg in :issue:`16624`.) + +:func:`~subprocess.getstatus` and :func:`~subprocess.getstatusoutput` now +work on Windows. This change was actually inadvertently made in 3.3.4. +(Contributed by Tim Golden in :issue:`10197`.) + + sunau ----- The :meth:`~sunau.getparams` method now returns a namedtuple rather than a plain tuple. (Contributed by Claudiu Popa in :issue:`18901`.) -:meth:`sunau.open` now supports the context manager protocol (:issue:`18878`). +:meth:`sunau.open` now supports the context management protocol: when used in a +:keyword:`with` block, the ``close`` method of the returned object will be +called automatically at the end of the block. (Contributed by Serhiy Storchaka +in :issue:`18878`.) + +:meth:`.AU_write.setsampwidth` now supports 24 bit samples, thus adding +support for writing 24 sample using the module. (Contributed by +Serhiy Storchaka in :issue:`19261`.) + +The :meth:`~sunau.AU_write.writeframesraw` and +:meth:`~sunau.AU_write.writeframes` methods now accept any :term:`bytes-like +object`. (Contributed by Serhiy Storchaka in :issue:`8311`.) + + +sys +--- + +New function :func:`sys.getallocatedblocks` returns the current number of +blocks allocated by the interpreter. (In CPython with the default +``--with-pymalloc`` setting, this is allocations made through the +:c:func:`PyObject_Malloc` API.) This can be useful for tracking memory leaks, +especially if automated via a test suite. (Contributed by Antoine Pitrou +in :issue:`13390`.) + +When the Python interpreter starts in :ref:`interactive mode +<tut-interactive>`, it checks for an :data:`~sys.__interactivehook__` attribute +on the :mod:`sys` module. If the attribute exists, its value is called with no +arguments just before interactive mode is started. The check is made after the +:envvar:`PYTHONSTARTUP` file is read, so it can be set there. The :mod:`site` +module :ref:`sets it <rlcompleter-config>` to a function that enables tab +completion and history saving (in :file:`~/.python-history`) if the platform +supports :mod:`readline`. If you do not want this (new) behavior, you can +override it in :envvar:`PYTHONSTARTUP`, :mod:`sitecustomize`, or +:mod:`usercustomize` by deleting this attribute from :mod:`sys` (or setting it +to some other callable). (Contributed by Éric Araujo and Antoine Pitrou in +:issue:`5845`.) + + +tarfile +------- + +The :mod:`tarfile` module now supports a simple :ref:`tarfile-commandline` when +called as a script directly or via ``-m``. This can be used to create and +extract tarfile archives. (Contributed by Berker Peksag in :issue:`13477`.) + + +textwrap +-------- + +The :class:`~textwrap.TextWrapper` class has two new attributes/constructor +arguments: :attr:`~textwrap.TextWrapper.max_lines`, which limits the number of +lines in the output, and :attr:`~textwrap.TextWrapper.placeholder`, which is a +string that will appear at the end of the output if it has been truncated +because of *max_lines*. Building on these capabilities, a new convenience +function :func:`~textwrap.shorten` collapses all of the whitespace in the input +to single spaces and produces a single line of a given *width* that ends with +the *placeholder* (by default, ``[...]``). (Contributed by Antoine Pitrou and +Serhiy Storchaka in :issue:`18585` and :issue:`18725`.) + + +threading +--------- + +The :class:`~threading.Thread` object representing the main thread can be +obtained from the new :func:`~threading.main_thread` function. In normal +conditions this will be the thread from which the Python interpreter was +started. (Contributed by Andrew Svetlov in :issue:`18882`.) traceback @@ -782,24 +1595,126 @@ traceback A new :func:`traceback.clear_frames` function takes a traceback object and clears the local variables in all of the frames it references, -reducing the amount of memory consumed (:issue:`1565525`). +reducing the amount of memory consumed. (Contributed by Andrew Kuchling in +:issue:`1565525`.) + + +types +----- + +A new :func:`~types.DynamicClassAttribute` descriptor provides a way to define +an attribute that acts normally when looked up through an instance object, but +which is routed to the *class* ``__getattr__`` when looked up through the +class. This allows one to have properties active on a class, and have virtual +attributes on the class with the same name (see :mod:`Enum` for an example). +(Contributed by Ethan Furman in :issue:`19030`.) urllib ------ -Add support.for ``data:`` URLs in :mod:`urllib.request`. - -(Contributed by Mathias Panzenböck in :issue:`16423`.) +:mod:`urllib.request` now supports ``data:`` URLs via the +:class:`~urllib.request.DataHandler` class. (Contributed by Mathias Panzenböck +in :issue:`16423`.) + +The http method that will be used by a :class:`~urllib.request.Request` class +can now be specified by setting a :class:`~urllib.request.Request.method` +class attribute on the subclass. (Contributed by Jason R Coombs in +:issue:`18978`.) + +:class:`~urllib.request.Request` objects are now reusable: if the +:attr:`~urllib.request.Request.full_url` or :attr:`~urllib.request.Request.data` +attributes are modified, all relevant internal properties are updated. This +means, for example, that it is now possible to use the same +:class:`~urllib.request.Request` object in more than one +:meth:`.OpenerDirector.open` call with different *data* arguments, or to +modify a :class:`~urllib.request.Request`\ 's ``url`` rather than recomputing it +from scratch. There is also a new +:meth:`~urllib.request.Request.remove_header` method that can be used to remove +headers from a :class:`~urllib.request.Request`. (Contributed by Alexey +Kachayev in :issue:`16464`, Daniel Wozniak in :issue:`17485`, and Damien Brecht +and Senthil Kumaran in :issue:`17272`.) + +:class:`~urllib.error.HTTPError` objects now have a +:attr:`~urllib.error.HTTPError.headers` attribute that provides access to the +HTTP response headers associated with the error. (Contributed by +Berker Peksag in :issue:`15701`.) unittest -------- -Support for easy dynamically-generated subtests using the -:meth:`~unittest.TestCase.subTest` context manager. +The :class:`~unittest.TestCase` class has a new method, +:meth:`~unittest.TestCase.subTest`, that produces a context manager whose +:keyword:`with` block becomes a "sub-test". This context manager allows a test +method to dynamically generate subtests by, say, calling the ``subTest`` +context manager inside a loop. A single test method can thereby produce an +indefinite number of separately-identified and separately-counted tests, all of +which will run even if one or more of them fail. For example:: + + class NumbersTest(unittest.TestCase): + def test_even(self): + for i in range(6): + with self.subTest(i=i): + self.assertEqual(i % 2, 0) + +will result in six subtests, each identified in the unittest verbose output +with a label consisting of the variable name ``i`` and a particular value for +that variable (``i=0``, ``i=1``, etc). See :ref:`subtests` for the full +version of this example. (Contributed by Antoine Pitrou in :issue:`16997`.) + +:func:`unittest.main` now accepts an iterable of test names for +*defaultTest*, where previously it only accepted a single test name as a +string. (Contributed by Jyrki Pulliainen in :issue:`15132`.) + +If :class:`~unittest.SkipTest` is raised during test discovery (that is, at the +module level in the test file), it is now reported as a skip instead of an +error. (Contributed by Zach Ware in :issue:`16935`.) + +:meth:`~unittest.TestLoader.discover` now sorts the discovered files to provide +consistent test ordering. (Contributed by Martin Melin and Jeff Ramnani in +:issue:`16709`.) + +:class:`~unittest.TestSuite` now drops references to tests as soon as the test +has been run, if the test is successful. On Python interpreters that do +garbage collection, this allows the tests to be garbage collected if nothing +else is holding a reference to the test. It is possible to override this +behavior by creating a :class:`~unittest.TestSuite` subclass that defines a +custom ``_removeTestAtIndex`` method. (Contributed by Tom Wardill, Matt +McClure, and Andrew Svetlov in :issue:`11798`.) + +A new test assertion context-manager, :meth:`~unittest.TestCase.assertLogs`, +will ensure that a given block of code emits a log message using the +:mod:`logging` module. By default the message can come from any logger and +have a priority of ``INFO`` or higher, but both the logger name and an +alternative minimum logging level may be specified. The object returned by the +context manager can be queried for the :class:`~logging.LogRecord`\ s and/or +formatted messages that were logged. (Contributed by Antoine Pitrou in +:issue:`18937`.) + +Test discovery now works with namespace packages (Contributed by Claudiu Popa +in :issue:`17457`.) + +:mod:`unittest.mock` objects now inspect their specification signatures when +matching calls, which means an argument can now be matched by either position +or name, instead of only by position. (Contributed by Antoine Pitrou in +:issue:`17015`.) + +:func:`~mock.mock_open` objects now have ``readline`` and ``readlines`` +methods. (Contributed by Toshio Kuratomi in :issue:`17467`.) + + +venv +---- + +:mod:`venv` now includes activation scripts for the ``csh`` and ``fish`` +shells. (Contributed by Andrew Svetlov in :issue:`15417`.) -(Contributed by Antoine Pitrou in :issue:`16997`.) +:class:`~venv.EnvBuilder` and the :func:`~venv.create` convenience function +take a new keyword argument *with_pip*, which defaults to ``False``, that +controls whether or not :class:`~venv.EnvBuilder` ensures that ``pip`` is +installed in the virtual environment. (Contributed by Nick Coghlan in +:issue:`19552` as part of the :pep:`453` implementation.) wave @@ -808,93 +1723,74 @@ wave The :meth:`~wave.getparams` method now returns a namedtuple rather than a plain tuple. (Contributed by Claudiu Popa in :issue:`17487`.) -:meth:`wave.open` now supports the context manager protocol. (Contributed +:meth:`wave.open` now supports the context management protocol. (Contributed by Claudiu Popa in :issue:`17616`.) +:mod:`wave` can now :ref:`write output to unseekable files +<wave-write-objects>`. (Contributed by David Jones, Guilherme Polo, and Serhiy +Storchaka in :issue:`5202`.) + +The :meth:`~wave.Wave_write.writeframesraw` and +:meth:`~wave.Wave_write.writeframes` methods now accept any :term:`bytes-like +object`. (Contributed by Serhiy Storchaka in :issue:`8311`.) + weakref ------- New :class:`~weakref.WeakMethod` class simulates weak references to bound -methods. (Contributed by Antoine Pitrou in :issue:`14631`.) +methods. (Contributed by Antoine Pitrou in :issue:`14631`.) New :class:`~weakref.finalize` class makes it possible to register a callback to be invoked when an object is garbage collected, without needing to -carefully manage the lifecycle of the weak reference itself. (Contributed by -Richard Oudkerk in :issue:`15528`) +carefully manage the lifecycle of the weak reference itself. (Contributed by +Richard Oudkerk in :issue:`15528`.) + +The callback, if any, associated with a :class:`~weakref.ref` is now +exposed via the :attr:`~weakref.ref.__callback__` attribute. (Contributed +by Mark Dickinson in :issue:`17643`.) xml.etree --------- -Add an event-driven parser for non-blocking applications, -:class:`~xml.etree.ElementTree.XMLPullParser`. - -(Contributed by Antoine Pitrou in :issue:`17741`.) +A new parser, :class:`~xml.etree.ElementTree.XMLPullParser`, allows a +non-blocking applications to parse XML documents. An example can be +seen at :ref:`elementtree-pull-parsing`. (Contributed by Antoine +Pitrou in :issue:`17741`.) +The :mod:`xml.etree.ElementTree` :func:`~xml.etree.ElementTree.tostring` and +:func:`~xml.etree.ElementTree.tostringlist` functions, and the +:class:`~xml.etree.ElementTree.ElementTree` +:meth:`~xml.etree.ElementTree.ElementTree.write` method, now have a +*short_empty_elements* :ref:`keyword-only parameter <keyword-only_parameter>` +providing control over whether elements with no content are written in +abbreviated (``<tag />``) or expanded (``<tag></tag>``) form. (Contributed by +Ariel Poliak and Serhiy Storchaka in :issue:`14377`.) -zipfile.PyZipfile ------------------ -Add a filter function to ignore some packages (tests for instance), -:meth:`~zipfile.PyZipFile.writepy`. +zipfile +------- +The :meth:`~zipfile.PyZipFile.writepy` method of the +:class:`~zipfile.PyZipFile` class has a new *filterfunc* option that can be +used to control which directories and files are added to the archive. For +example, this could be used to exclude test files from the archive. (Contributed by Christian Tismer in :issue:`19274`.) +The *allowZip64* parameter to :class:`~zipfile.ZipFile` and +:class:`~zipfile.PyZipfile` is now ``True`` by default. (Contributed by +William Mallard in :issue:`17201`.) -Other improvements -================== - -Tab-completion is now enabled by default in the interactive interpreter. - -(Contributed by Antoine Pitrou and Éric Araujo in :issue:`5845`.) - -Python invocation changes -========================= - -Invoking the Python interpreter with ``--version`` now outputs the version to -standard output instead of standard error (:issue:`18338`). Similar changes -were made to :mod:`argparse` (:issue:`18920`) and other modules that have -script-like invocation capabilities (:issue:`18922`). - -Optimizations -============= - -Major performance enhancements have been added: - -* The UTF-32 decoder is now 3x to 4x faster. - -* The cost of hash collisions for sets is now reduced. Each hash table - probe now checks a series of consecutive, adjacent key/hash pairs before - continuing to make random probes through the hash table. This exploits - cache locality to make collision resolution less expensive. - - The collision resolution scheme can be described as a hybrid of linear - probing and open addressing. The number of additional linear probes - defaults to nine. This can be changed at compile-time by defining - LINEAR_PROBES to be any value. Set LINEAR_PROBES=0 to turn-off - linear probing entirely. - - (Contributed by Raymond Hettinger in :issue:`18771`.) - -* The interpreter starts about 30% faster. A couple of measures lead to the - speedup. The interpreter loads fewer modules on startup, e.g. the :mod:`re`, - :mod:`collections` and :mod:`locale` modules and their dependencies are no - longer imported by default. The marshal module has been improved to load - compiled Python code faster. - - (Contributed by Antoine Pitrou, Christian Heimes and Victor Stinner in - :issue:`19219`, :issue:`19218`, :issue:`19209`, :issue:`19205` and - :issue:`9548`) CPython Implementation Changes ============================== -.. _pep-445: +.. _whatsnew-pep-445: -PEP 445: Customization of CPython memory allocators +PEP 445: Customization of CPython Memory Allocators --------------------------------------------------- :pep:`445` adds new C level interfaces to customize memory allocation in @@ -902,13 +1798,13 @@ the CPython interpreter. .. seealso:: - :pep:`445` - Add new APIs to customize Python memory allocators + :pep:`445` -- Add new APIs to customize Python memory allocators PEP written and implemented by Victor Stinner. -.. _pep-442: +.. _whatsnew-pep-442: -PEP 442: Safe object finalization +PEP 442: Safe Object Finalization --------------------------------- :pep:`442` removes the current limitations and quirks of object finalization @@ -918,61 +1814,282 @@ part of a reference cycle. As part of this change, module globals are no longer forcibly set to :const:`None` during interpreter shutdown in most cases, instead relying -on the normal operation of the cyclic garbage collector. +on the normal operation of the cyclic garbage collector. This avoids a +whole class of interpreter-shutdown-time errors, usually involving +``__del__`` methods, that have plagued Python since the cyclic GC +was first introduced. .. seealso:: - :pep:`442` - Safe object finalization + :pep:`442` -- Safe object finalization PEP written and implemented by Antoine Pitrou. -Other build and C API changes +.. _whatsnew-pep-456: + +PEP 456: Secure and Interchangeable Hash Algorithm +-------------------------------------------------- + +:pep:`456` follows up on earlier security fix work done on Python's hash +algorithm to address certain DOS attacks to which public facing APIs backed by +dictionary lookups may be subject. (See :issue:`14621` for the start of the +current round of improvements.) The PEP unifies CPython's hash code to make it +easier for a packager to substitute a different hash algorithm, and switches +Python's default implementation to a SipHash implementation on platforms that +have a 64 bit data type. Any performance differences in comparison with the +older FNV algorithm are trivial. + +The PEP adds additional fields to the :attr:`sys.hash_info` struct sequence to +describe the hash algorithm in use by the currently executing binary. Otherwise, +the PEP does not alter any existing CPython APIs. + + +.. _whatsnew-pep-436: + +PEP 436: Argument Clinic +------------------------ + +"Argument Clinic" (:pep:`436`) is now part of the CPython build process +and can be used to simplify the process of defining and maintaining +accurate signatures for builtins and standard library extension modules +implemented in C. + +Some standard library extension modules have been converted to use Argument +Clinic in Python 3.4, and :mod:`pydoc` and :mod:`inspect` have been updated +accordingly. + +It is expected that signature metadata for programmatic introspection will +be added to additional callables implemented in C as part of Python 3.4 +maintenance releases. + +.. note:: + The Argument Clinic PEP is not fully up to date with the state of the + implementation. This has been deemed acceptable by the release manager + and core development team in this case, as Argument Clinic will not + be made available as a public API for third party use in Python 3.4. + +.. seealso:: + + :pep:`436` -- The Argument Clinic DSL + PEP written and implemented by Larry Hastings. + + +Other Build and C API Changes ----------------------------- -Changes to Python's build process and to the C API include: +* The new :c:func:`PyType_GetSlot` function has been added to the stable ABI, + allowing retrieval of function pointers from named type slots when using + the limited API. (Contributed by Martin von Löwis in :issue:`17162`.) * The new :c:func:`Py_SetStandardStreamEncoding` pre-initialization API allows applications embedding the CPython interpreter to reliably force - a particular encoding and error handler for the standard streams - (Contributed by Bastien Montagne and Nick Coghlan in :issue:`16129`) + a particular encoding and error handler for the standard streams. + (Contributed by Bastien Montagne and Nick Coghlan in :issue:`16129`.) * Most Python C APIs that don't mutate string arguments are now correctly - marked as accepting ``const char *`` rather than ``char *`` (Contributed - by Serhiy Storchaka in :issue:`1772673`). + marked as accepting ``const char *`` rather than ``char *``. (Contributed + by Serhiy Storchaka in :issue:`1772673`.) + +* A new shell version of ``python-config`` can be used even when a python + interpreter is not available (for example, in cross compilation scenarios). + +* :c:func:`PyUnicode_FromFormat` now supports width and precision + specifications for ``%s``, ``%A``, ``%U``, ``%V``, ``%S``, and ``%R``. + (Contributed by Ysj Ray and Victor Stinner in :issue:`7330`.) + +* New function :c:func:`PyStructSequence_InitType2` supplements the + existing :c:func:`PyStructSequence_InitType` function. The difference + is that it returns ``0`` on success and ``-1`` on failure. -* "Argument Clinic" (:pep:`436`) is now part of the CPython build process - and can be used to simplify the process of defining and maintaining - accurate signatures for builtins and standard library extension modules - implemented in C. +* The CPython source can now be compiled using the address sanity checking + features of recent versions of GCC and clang: the false alarms in the small + object allocator have been silenced. (Contributed by Dhiru Kholia in + :issue:`18596`.) - .. note:: - The Argument Clinic PEP is not fully up to date with the state of the - implementation. This has been deemed acceptable by the release manager - and core development team in this case, as Argument Clinic will not - be made available as a public API for third party use in Python 3.4. +* The Windows build now uses `Address Space Layout Randomization + <http://en.wikipedia.org/wiki/ASLR>`_ and `Data Execution Prevention + <http://en.wikipedia.org/wiki/Data_Execution_Prevention>`_. (Contributed by + Christian Heimes in :issue:`16632`.) +* New function :c:func:`PyObject_LengthHint` is the C API equivalent + of :func:`operator.length_hint`. (Contributed by Armin Ronacher in + :issue:`16148`.) -Deprecated -========== -Unsupported Operating Systems ------------------------------ +.. _other-improvements-3.4: -* OS/2 -* Windows 2000 +Other Improvements +------------------ +.. _whatsnew-isolated-mode: -Deprecated Python modules, functions and methods ------------------------------------------------- +* The :ref:`python <using-on-cmdline>` command has a new :ref:`option + <using-on-misc-options>`, ``-I``, which causes it to run in "isolated mode", + which means that :data:`sys.path` contains neither the script's directory nor + the user's ``site-packages`` directory, and all :envvar:`PYTHON*` environment + variables are ignored (it implies both ``-s`` and ``-E``). Other + restrictions may also be applied in the future, with the goal being to + isolate the execution of a script from the user's environment. This is + appropriate, for example, when Python is used to run a system script. On + most POSIX systems it can and should be used in the ``#!`` line of system + scripts. (Contributed by Christian Heimes in :issue:`16499`.) -* :meth:`difflib.SequenceMatcher.isbjunk` and - :meth:`difflib.SequenceMatcher.isbpopular` were removed: use ``x in sm.bjunk`` and - ``x in sm.bpopular``, where *sm* is a :class:`~difflib.SequenceMatcher` object. +* Tab-completion is now enabled by default in the interactive interpreter + on systems that support :mod:`readline`. History is also enabled by default, + and is written to (and read from) the file :file:`~/.python-history`. + (Contributed by Antoine Pitrou and Éric Araujo in :issue:`5845`.) + +* Invoking the Python interpreter with ``--version`` now outputs the version to + standard output instead of standard error (:issue:`18338`). Similar changes + were made to :mod:`argparse` (:issue:`18920`) and other modules that have + script-like invocation capabilities (:issue:`18922`). + +* The CPython Windows installer now adds ``.py`` to the :envvar:`PATHEXT` + variable when extensions are registered, allowing users to run a python + script at the windows command prompt by just typing its name without the + ``.py`` extension. (Contributed by Paul Moore in :issue:`18569`.) + +* A new ``make`` target `coverage-report + <https://docs.python.org/devguide/coverage.html#measuring-coverage-of-c-code-with-gcov-and-lcov>`_ + will build python, run the test suite, and generate an HTML coverage report + for the C codebase using ``gcov`` and `lcov + <http://ltp.sourceforge.net/coverage/lcov.php>`_. + +* The ``-R`` option to the :ref:`python regression test suite <regrtest>` now + also checks for memory allocation leaks, using + :func:`sys.getallocatedblocks()`. (Contributed by Antoine Pitrou in + :issue:`13390`.) + +* ``python -m`` now works with namespace packages. + +* The :mod:`stat` module is now implemented in C, which means it gets the + values for its constants from the C header files, instead of having the + values hard-coded in the python module as was previously the case. + +* Loading multiple python modules from a single OS module (``.so``, ``.dll``) + now works correctly (previously it silently returned the first python + module in the file). (Contributed by Václav Å milauer in :issue:`16421`.) + +* A new opcode, :opcode:`LOAD_CLASSDEREF`, has been added to fix a bug in the + loading of free variables in class bodies that could be triggered by certain + uses of :ref:`__prepare__ <prepare>`. (Contributed by Benjamin Peterson in + :issue:`17853`.) + +* A number of MemoryError-related crashes were identified and fixed by Victor + Stinner using his :pep:`445`-based ``pyfailmalloc`` tool (:issue:`18408`, + :issue:`18520`). + +* The :ref:`pyvenv <scripts-pyvenv>` command now accepts a ``--copies`` option + to use copies rather than symlinks even on systems where symlinks are the + default. (Contributed by Vinay Sajip in :issue:`18807`.) + +* The :ref:`pyvenv <scripts-pyvenv>` command also accepts a ``--without-pip`` + option to suppress the otherwise-automatic bootstrapping of pip into + the virtual environment. (Contributed by Nick Coghlan in :issue:`19552` + as part of the :pep:`453` implementation.) + +* The encoding name is now optional in the value set for the + :envvar:`PYTHONIOENCODING` environment variable. This makes it possible to + set just the error handler, without changing the default encoding. + (Contributed by Serhiy Storchaka in :issue:`18818`.) + +* The :mod:`bz2`, :mod:`lzma`, and :mod:`gzip` module ``open`` functions now + support ``x`` (exclusive creation) mode. (Contributed by Tim Heaney and + Vajrasky Kok in :issue:`19201`, :issue:`19222`, and :issue:`19223`.) -* :func:`importlib.util.module_for_loader` is pending deprecation. Using - :func:`importlib.util.module_to_load` and - :meth:`importlib.abc.Loader.init_module_attrs` allows subclasses of a loader - to more easily customize module loading. + +Significant Optimizations +------------------------- + +* The UTF-32 decoder is now 3x to 4x faster. (Contributed by Serhiy Storchaka + in :issue:`14625`.) + +* The cost of hash collisions for sets is now reduced. Each hash table + probe now checks a series of consecutive, adjacent key/hash pairs before + continuing to make random probes through the hash table. This exploits + cache locality to make collision resolution less expensive. + The collision resolution scheme can be described as a hybrid of linear + probing and open addressing. The number of additional linear probes + defaults to nine. This can be changed at compile-time by defining + LINEAR_PROBES to be any value. Set LINEAR_PROBES=0 to turn-off + linear probing entirely. (Contributed by Raymond Hettinger in + :issue:`18771`.) + +* The interpreter starts about 30% faster. A couple of measures lead to the + speedup. The interpreter loads fewer modules on startup, e.g. the :mod:`re`, + :mod:`collections` and :mod:`locale` modules and their dependencies are no + longer imported by default. The marshal module has been improved to load + compiled Python code faster. (Contributed by Antoine Pitrou, Christian + Heimes and Victor Stinner in :issue:`19219`, :issue:`19218`, :issue:`19209`, + :issue:`19205` and :issue:`9548`.) + +* :class:`bz2.BZ2File` is now as fast or faster than the Python2 version for + most cases. :class:`lzma.LZMAFile` has also been optimized. (Contributed by + Serhiy Storchaka and Nadeem Vawda in :issue:`16034`.) + +* :func:`random.getrandbits` is 20%-40% faster for small integers (the most + common use case). (Contributed by Serhiy Storchaka in :issue:`16674`.) + +* By taking advantage of the new storage format for strings, pickling of + strings is now significantly faster. (Contributed by Victor Stinner and + Antoine Pitrou in :issue:`15596`.) + +* A performance issue in :meth:`io.FileIO.readall` has been solved. This + particularly affects Windows, and significantly speeds up the case of piping + significant amounts of data through :mod:`subprocess`. (Contributed + by Richard Oudkerk in :issue:`15758`.) + +* :func:`html.escape` is now 10x faster. (Contributed by Matt Bryant in + :issue:`18020`.) + +* On Windows, the native ``VirtualAlloc`` is now used instead of the CRT + ``malloc`` in ``obmalloc``. Artificial benchmarks show about a 3% memory + savings. + +* :func:`os.urandom` now uses a lazily-opened persistent file descriptor + so as to avoid using many file descriptors when run in parallel from + multiple threads. (Contributed by Antoine Pitrou in :issue:`18756`.) + + +.. _deprecated-3.4: + +Deprecated +========== + +This section covers various APIs and other features that have been deprecated +in Python 3.4, and will be removed in Python 3.5 or later. In most (but not +all) cases, using the deprecated APIs will produce a :exc:`DeprecationWarning` +when the interpreter is run with deprecation warnings enabled (for example, by +using ``-Wd``). + + +Deprecations in the Python API +------------------------------ + +* As mentioned in :ref:`whatsnew-pep-451`, a number of :mod:`importilb` + methods and functions are deprecated: :meth:`importlib.find_loader` is + replaced by :func:`importlib.util.find_spec`; + :meth:`importlib.machinery.PathFinder.find_module` is replaced by + :meth:`importlib.machinery.PathFinder.find_spec`; + :meth:`importlib.abc.MetaPathFinder.find_module` is replaced by + :meth:`importlib.abc.MetaPathFinder.find_spec`; + :meth:`importlib.abc.PathEntryFinder.find_loader` and + :meth:`~importlib.abc.PathEntryFinder.find_module` are replaced by + :meth:`importlib.abc.PathEntryFinder.find_spec`; all of the ``xxxLoader`` ABC + ``load_module`` methods (:meth:`importlib.abc.Loader.load_module`, + :meth:`importlib.abc.InspectLoader.load_module`, + :meth:`importlib.abc.FileLoader.load_module`, + :meth:`importlib.abc.SourceLoader.load_module`) should no longer be + implemented, instead loaders should implement an + ``exec_module`` method + (:meth:`importlib.abc.Loader.exec_module`, + :meth:`importlib.abc.InspectLoader.exec_module` + :meth:`importlib.abc.SourceLoader.exec_module`) and let the import system + take care of the rest; and + :meth:`importlib.abc.Loader.module_repr`, + :meth:`importlib.util.module_for_loader`, :meth:`importlib.util.set_loader`, + and :meth:`importlib.util.set_package` are no longer needed because their + functions are now handled automatically by the import system. * The :mod:`imp` module is pending deprecation. To keep compatibility with Python 2/3 code bases, the module's removal is currently not scheduled. @@ -980,30 +2097,165 @@ Deprecated Python modules, functions and methods * The :mod:`formatter` module is pending deprecation and is slated for removal in Python 3.6. -* MD5 as default digestmod for :mod:`hmac` is deprecated. Python 3.6 will - require an explicit digest name or constructor as *digestmod* argument. +* ``MD5`` as the default *digestmod* for the :func:`hmac.new` function is + deprecated. Python 3.6 will require an explicit digest name or constructor as + *digestmod* argument. + +* The internal ``Netrc`` class in the :mod:`ftplib` module has been documented + as deprecated in its docstring for quite some time. It now emits a + :exc:`DeprecationWarning` and will be removed completely in Python 3.5. +* The undocumented *endtime* argument to :meth:`subprocess.Popen.wait` should + not have been exposed and is hopefully not in use; it is deprecated and + will mostly likely be removed in Python 3.5. -Deprecated functions and types of the C API -------------------------------------------- +* The *strict* argument of :class:`~html.parser.HTMLParser` is deprecated. -* The ``PyThreadState.tick_counter`` field has been removed: its value was - meaningless since Python 3.2 ("new GIL"). +* The :mod:`plistlib` :func:`~plistlib.readPlist`, + :func:`~plistlib.writePlist`, :func:`~plistlib.readPlistFromBytes`, and + :func:`~plistlib.writePlistToBytes` functions are deprecated in favor of the + corresponding new functions :func:`~plistlib.load`, :func:`~plistlib.dump`, + :func:`~plistlib.loads`, and :func:`~plistlib.dumps`. :func:`~plistlib.Data` + is deprecated in favor of just using the :class:`bytes` constructor. +* The :mod:`sysconfig` key ``SO`` is deprecated, it has been replaced by + ``EXT_SUFFIX``. -Deprecated features +* The ``U`` mode accepted by various ``open`` functions is deprecated. + In Python3 it does not do anything useful, and should be replaced by + appropriate uses of :class:`io.TextIOWrapper` (if needed) and its *newline* + argument. + +* The *parser* argument of :func:`xml.etree.ElementTree.iterparse` has + been deprecated, as has the *html* argument of + :func:`~xml.etree.ElementTree.XMLParser`. To prepare for the removal of the + latter, all arguments to ``XMLParser`` should be passed by keyword. + + +Deprecated Features ------------------- +* Running :ref:`idle` with the ``-n`` flag (no subprocess) is deprecated. + However, the feature will not be removed until :issue:`18823` is resolved. + * The site module adding a "site-python" directory to sys.path, if it exists, is deprecated (:issue:`19375`). + +Removed +======= + + +Operating Systems No Longer Supported +------------------------------------- + +Support for the following operating systems has been removed from the source +and build tools: + +* OS/2 (:issue:`16135`). +* Windows 2000 (changeset e52df05b496a). +* Windows systems where ``COMSPEC`` points to ``command.com`` (:issue:`14470`). +* VMS (:issue:`16136`). + + +API and Feature Removals +------------------------ + +The following obsolete and previously deprecated APIs and features have been +removed: + +* The unmaintained ``Misc/TextMate`` and ``Misc/vim`` directories have been + removed (see the `devguide <https://docs.python.org/devguide>`_ + for suggestions on what to use instead). + +* The ``SO`` makefile macro is removed (it was replaced by the + ``SHLIB_SUFFIX`` and ``EXT_SUFFIX`` macros) (:issue:`16754`). + +* The ``PyThreadState.tick_counter`` field has been removed; its value has + been meaningless since Python 3.2, when the "new GIL" was introduced + (:issue:`19199`). + +* ``PyLoader`` and ``PyPycLoader`` have been removed from :mod:`importlib`. + (Contributed by Taras Lyapun in :issue:`15641`.) + +* The *strict* argument to :class:`~http.client.HTTPConnection` and + :class:`~http.client.HTTPSConnection` has been removed. HTTP 0.9-style + "Simple Responses" are no longer supported. + +* The deprecated :mod:`urllib.request.Request` getter and setter methods + ``add_data``, ``has_data``, ``get_data``, ``get_type``, ``get_host``, + ``get_selector``, ``set_proxy``, ``get_origin_req_host``, and + ``is_unverifiable`` have been removed (use direct attribute access instead). + +* Support for loading the deprecated ``TYPE_INT64`` has been removed from + :mod:`marshal`. (Contributed by Dan Riti in :issue:`15480`.) + +* :class:`inspect.Signature`: positional-only parameters are now required + to have a valid name. + +* :meth:`object.__format__` no longer accepts non-empty format strings, it now + raises a :exc:`TypeError` instead. Using a non-empty string has been + deprecated since Python 3.2. This change has been made to prevent a + situation where previously working (but incorrect) code would start failing + if an object gained a __format__ method, which means that your code may now + raise a :exc:`TypeError` if you are using an ``'s'`` format code with objects + that do not have a __format__ method that handles it. See :issue:`7994` for + background. + +* :meth:`difflib.SequenceMatcher.isbjunk` and + :meth:`difflib.SequenceMatcher.isbpopular` were deprecated in 3.2, and have + now been removed: use ``x in sm.bjunk`` and + ``x in sm.bpopular``, where *sm* is a :class:`~difflib.SequenceMatcher` object + (:issue:`13248`). + + +Code Cleanups +------------- + +* The unused and undocumented internal ``Scanner`` class has been removed from + the :mod:`pydoc` module. + +* The private and effectively unused ``_gestalt`` module has been removed, + along with the private :mod:`platform` functions ``_mac_ver_lookup``, + ``_mac_ver_gstalt``, and ``_bcd2str``, which would only have ever been called + on badly broken OSX systems (see :issue:`18393`). + +* The hardcoded copies of certain :mod:`stat` constants that were included in + the :mod:`tarfile` module namespace have been removed. + + + Porting to Python 3.4 ===================== This section lists previously described changes and other bugfixes that may require changes to your code. + +Changes in 'python' Command Behavior +------------------------------------ + +* In a posix shell, setting the :envvar:`PATH` environment variable to + an empty value is equivalent to not setting it at all. However, setting + :envvar:`PYTHONPATH` to an empty value was *not* equivalent to not setting it + at all: setting :envvar:`PYTHONPATH` to an empty value was equivalent to + setting it to ``.``, which leads to confusion when reasoning by analogy to + how :envvar:`PATH` works. The behavior now conforms to the posix convention + for :envvar:`PATH`. + +* The [X refs, Y blocks] output of a debug (``--with-pydebug``) build of the + CPython interpreter is now off by default. It can be re-enabled using the + ``-X showrefcount`` option. (Contributed by Ezio Melotti in :issue:`17323`.) + +* The python command and most stdlib scripts (as well as :mod:`argparse`) now + output ``--version`` information to ``stdout`` instead of ``stderr`` (for + issue list see :ref:`other-improvements-3.4` above). + + +Changes in the Python API +------------------------- + * The ABCs defined in :mod:`importlib.abc` now either raise the appropriate exception or return a default value instead of raising :exc:`NotImplementedError` blindly. This will only affect code calling @@ -1013,7 +2265,7 @@ that may require changes to your code. * The module type now initializes the :attr:`__package__` and :attr:`__loader__` attributes to ``None`` by default. To determine if these attributes were set in a backwards-compatible fashion, use e.g. - ``getattr(module, '__loader__', None) is not None``. + ``getattr(module, '__loader__', None) is not None``. (:issue:`17115`.) * :meth:`importlib.util.module_for_loader` now sets ``__loader__`` and ``__package__`` unconditionally to properly support reloading. If this is not @@ -1022,14 +2274,23 @@ that may require changes to your code. * Import now resets relevant attributes (e.g. ``__name__``, ``__loader__``, ``__package__``, ``__file__``, ``__cached__``) unconditionally when reloading. + Note that this restores a pre-3.3 behavior in that it means a module is + re-found when re-loaded (:issue:`19413`). * Frozen packages no longer set ``__path__`` to a list containing the package - name but an empty list instead. Determing if a module is a package should be - done using ``hasattr(module, '__path__')``. - -* :c:func:`PyErr_SetImportError` now sets :exc:`TypeError` when its **msg** - argument is not set. Previously only ``NULL`` was returned with no exception - set. + name, they now set it to an empty list. The previous behavior could cause + the import system to do the wrong thing on submodule imports if there was + also a directory with the same name as the frozen package. The correct way + to determine if a module is a package or not is to use ``hasattr(module, + '__path__')`` (:issue:`18065`). + +* Frozen modules no longer define a ``__file__`` attribute. It's semantically + incorrect for frozen modules to set the attribute as they are not loaded from + any explicit location. If you must know that a module comes from frozen code + then you can see if the module's ``__spec__.location`` is set to ``'frozen'``, + check if the loader is a subclass of + :class:`importlib.machinery.FrozenImporter`, + or if Python 2 compatibility is necessary you can use :func:`imp.is_frozen`. * :func:`py_compile.compile` now raises :exc:`FileExistsError` if the file path it would write to is a symlink or a non-regular file. This is to act as a @@ -1046,7 +2307,7 @@ that may require changes to your code. exceptions now. * :func:`functools.update_wrapper` and :func:`functools.wraps` now correctly - set the ``__wrapped__`` attribute to the function being wrapper, even if + set the ``__wrapped__`` attribute to the function being wrapped, even if that function also had its ``__wrapped__`` attribute set. This means ``__wrapped__`` attributes now correctly link a stack of decorated functions rather than every ``__wrapped__`` attribute in the chain @@ -1055,10 +2316,13 @@ that may require changes to your code. :func:`inspect.unwrap` to access the first function in the chain that has no ``__wrapped__`` attribute. -* (C API) The result of the :c:data:`PyOS_ReadlineFunctionPointer` callback must - now be a string allocated by :c:func:`PyMem_RawMalloc` or - :c:func:`PyMem_RawRealloc`, or *NULL* if an error occurred, instead of a - string allocated by :c:func:`PyMem_Malloc` or :c:func:`PyMem_Realloc`. +* :func:`inspect.getfullargspec` has been reimplemented on top of + :func:`inspect.signature` and hence handles a much wider variety of callable + objects than it did in the past. It is expected that additional builtin and + extension module callables will gain signature metadata over the course of + the Python 3.4 series. Code that assumes that + :func:`inspect.getfullargspec` will fail on non-Python callables may need + to be adjusted accordingly. * :class:`importlib.machinery.PathFinder` now passes on the current working directory to objects in :data:`sys.path_hooks` for the empty string. This @@ -1066,5 +2330,206 @@ that may require changes to your code. iterating through :data:`sys.path_importer_cache` based on :data:`sys.path` will not find all keys. A module's ``__file__`` when imported in the current working directory will also now have an absolute path, including when using - ``-m`` with the interpreter (this does not influence when the path to a file - is specified on the command-line). + ``-m`` with the interpreter (except for ``__main__.__file__`` when a script + has been executed directly using a relative path) (Contributed by Brett + Cannon in :issue:`18416`). is specified on the command-line) + (:issue:`18416`). + +* The removal of the *strict* argument to :class:`~http.client.HTTPConnection` + and :class:`~http.client.HTTPSConnection` changes the meaning of the + remaining arguments if you are specifying them positionally rather than by + keyword. If you've been paying attention to deprecation warnings your code + should already be specifying any additional arguments via keywords. + +* Strings between ``from __future__ import ...`` statements now *always* raise + a :exc:`SyntaxError`. Previously if there was no leading docstring, an + interstitial string would sometimes be ignored. This brings CPython into + compliance with the language spec; Jython and PyPy already were. + (:issue:`17434`). + +* :meth:`ssl.SSLSocket.getpeercert` and :meth:`ssl.SSLSocket.do_handshake` + now raise an :exc:`OSError` with ``ENOTCONN`` when the ``SSLSocket`` is not + connected, instead of the previous behavior of raising an + :exc:`AttributeError`. In addition, :meth:`~ssl.SSLSocket.getpeercert` + will raise a :exc:`ValueError` if the handshake has not yet been done. + +* :func:`base64.b32decode` now raises a :exc:`binascii.Error` when the + input string contains non-b32-alphabet characters, instead of a + :exc:`TypeError`. This particular :exc:`TypeError` was missed when the other + :exc:`TypeError`\ s were converted. (Contributed by Serhiy Storchaka in + :issue:`18011`.) Note: this change was also inadvertently applied in Python + 3.3.3. + +* The :attr:`~cgi.FieldStorage.file` attribute is now automatically closed when + the creating :class:`cgi.FieldStorage` instance is garbage collected. If you + were pulling the file object out separately from the :class:`cgi.FieldStorage` + instance and not keeping the instance alive, then you should either store the + entire :class:`cgi.FieldStorage` instance or read the contents of the file + before the :class:`cgi.FieldStorage` instance is garbage collected. + +* Calling ``read`` or ``write`` on a closed SSL socket now raises an + informative :exc:`ValueError` rather than the previous more mysterious + :exc:`AttributeError` (:issue:`9177`). + +* :meth:`slice.indices` no longer produces an :exc:`OverflowError` for huge + values. As a consequence of this fix, :meth:`slice.indices` now raises a + :exc:`ValueError` if given a negative length; previously it returned nonsense + values (:issue:`14794`). + +* The :class:`complex` constructor, unlike the :mod:`cmath` functions, was + incorrectly accepting :class:`float` values if an object's ``__complex__`` + special method returned one. This now raises a :exc:`TypeError`. + (:issue:`16290`.) + +* The :class:`int` constructor in 3.2 and 3.3 erroneously accepts :class:`float` + values for the *base* parameter. It is unlikely anyone was doing this, but + if so, it will now raise a :exc:`TypeError` (:issue:`16772`). + +* Defaults for keyword-only arguments are now evaluated *after* defaults for + regular keyword arguments, instead of before. Hopefully no one wrote any + code that depends on the previous buggy behavior (:issue:`16967`). + +* Stale thread states are now cleared after :func:`~os.fork`. This may cause + some system resources to be released that previously were incorrectly kept + perpetually alive (for example, database connections kept in thread-local + storage). (:issue:`17094`.) + +* Parameter names in ``__annotations__`` dicts are now mangled properly, + similarly to ``__kwdefaults__``. (Contributed by Yury Selivanov in + :issue:`20625`.) + +* :attr:`hashlib.hash.name` now always returns the identifier in lower case. + Previously some builtin hashes had uppercase names, but now that it is a + formal public interface the naming has been made consistent (:issue:`18532`). + +* Because :mod:`unittest.TestSuite` now drops references to tests after they + are run, test harnesses that re-use a :class:`~unittest.TestSuite` to re-run + a set of tests may fail. Test suites should not be re-used in this fashion + since it means state is retained between test runs, breaking the test + isolation that :mod:`unittest` is designed to provide. However, if the lack + of isolation is considered acceptable, the old behavior can be restored by + creating a :mod:`~unittest.TestSuite` subclass that defines a + ``_removeTestAtIndex`` method that does nothing (see + :meth:`.TestSuite.__iter__`) (:issue:`11798`). + +* :mod:`unittest` now uses :mod:`argparse` for command line parsing. There are + certain invalid command forms that used to work that are no longer allowed; + in theory this should not cause backward compatibility issues since the + disallowed command forms didn't make any sense and are unlikely to be in use. + +* The :func:`re.split`, :func:`re.findall`, and :func:`re.sub` functions, and + the :meth:`~re.match.group` and :meth:`~re.match.groups` methods of + ``match`` objects now always return a *bytes* object when the string + to be matched is a :term:`bytes-like object`. Previously the return type + matched the input type, so if your code was depending on the return value + being, say, a ``bytearray``, you will need to change your code. + +* :mod:`audioop` functions now raise an error immediately if passed string + input, instead of failing randomly later on (:issue:`16685`). + +* The new *convert_charrefs* argument to :class:`~html.parser.HTMLParser` + currently defaults to ``False`` for backward compatibility, but will + eventually be changed to default to ``True``. It is recommended that you add + this keyword, with the appropriate value, to any + :class:`~html.parser.HTMLParser` calls in your code (:issue:`13633`). + +* Since the *digestmod* argument to the :func:`hmac.new` function will in the + future have no default, all calls to :func:`hmac.new` should be changed to + explicitly specify a *digestmod* (:issue:`17276`). + +* Calling :func:`sysconfig.get_config_var` with the ``SO`` key, or looking + ``SO`` up in the results of a call to :func:`sysconfig.get_config_vars` + is deprecated. This key should be replaced by ``EXT_SUFFIX`` or + ``SHLIB_SUFFIX``, depending on the context (:issue:`19555`). + +* Any calls to ``open`` functions that specify ``U`` should be modified. + ``U`` is ineffective in Python3 and will eventually raise an error if used. + Depending on the function, the equivalent of its old Python2 behavior can be + achieved using either a *newline* argument, or if necessary by wrapping the + stream in :mod:`~io.TextIOWrapper` to use its *newline* argument + (:issue:`15204`). + +* If you use :ref:`pyvenv <scripts-pyvenv>` in a script and desire that pip + *not* be installed, you must add ``--without-pip`` to your command + invocation. + +* The default behavior of :func:`json.dump` and :func:`json.dumps` when + an indent is specified has changed: it no longer produces trailing + spaces after the item separating commas at the ends of lines. This + will matter only if you have tests that are doing white-space-sensitive + comparisons of such output (:issue:`16333`). + +* :mod:`doctest` now looks for doctests in extension module ``__doc__`` + strings, so if your doctest test discovery includes extension modules that + have things that look like doctests in them you may see test failures you've + never seen before when running your tests (:issue:`3158`). + +* The :mod:`collections.abc` module has been slightly refactored as + part of the Python startup improvements. As a consequence of this, it is no + longer the case that importing :mod:`collections` automatically imports + :mod:`collections.abc`. If your program depended on the (undocumented) + implicit import, you will need to add an explicit ``import collections.abc`` + (:issue:`20784`). + + +Changes in the C API +-------------------- + +* :c:func:`PyEval_EvalFrameEx`, :c:func:`PyObject_Repr`, and + :c:func:`PyObject_Str`, along with some other internal C APIs, now include + a debugging assertion that ensures they are not used in situations where + they may silently discard a currently active exception. In cases where + discarding the active exception is expected and desired (for example, + because it has already been saved locally with :c:func:`PyErr_Fetch` or + is being deliberately replaced with a different exception), an explicit + :c:func:`PyErr_Clear` call will be needed to avoid triggering the + assertion when invoking these operations (directly or indirectly) and + running against a version of Python that is compiled with assertions + enabled. + +* :c:func:`PyErr_SetImportError` now sets :exc:`TypeError` when its **msg** + argument is not set. Previously only ``NULL`` was returned with no exception + set. + +* The result of the :c:data:`PyOS_ReadlineFunctionPointer` callback must + now be a string allocated by :c:func:`PyMem_RawMalloc` or + :c:func:`PyMem_RawRealloc`, or *NULL* if an error occurred, instead of a + string allocated by :c:func:`PyMem_Malloc` or :c:func:`PyMem_Realloc` + (:issue:`16742`) + +* :c:func:`PyThread_set_key_value` now always set the value. In Python + 3.3, the function did nothing if the key already exists (if the current + value is a non-NULL pointer). + +* The ``f_tstate`` (thread state) field of the :c:type:`PyFrameObject` + structure has been removed to fix a bug: see :issue:`14432` for the + rationale. + +Changed in 3.4.3 +================ + +.. _pep-476: + +PEP 476: Enabling certificate verification by default for stdlib http clients +----------------------------------------------------------------------------- + +:mod:`http.client` and modules which use it, such as :mod:`urllib.request` and +:mod:`xmlrpc.client`, will now verify that the server presents a certificate +which is signed by a CA in the platform trust store and whose hostname matches +the hostname being requested by default, significantly improving security for +many applications. + +For applications which require the old previous behavior, they can pass an +alternate context:: + + import urllib.request + import ssl + + # This disables all verification + context = ssl._create_unverified_context() + + # This allows using a specific certificate for the host, which doesn't need + # to be in the trust store + context = ssl.create_default_context(cafile="/path/to/file.crt") + + urllib.request.urlopen("https://invalid-cert", context=context) diff --git a/Doc/whatsnew/3.5.rst b/Doc/whatsnew/3.5.rst new file mode 100644 index 000000000000..7c4e530c2478 --- /dev/null +++ b/Doc/whatsnew/3.5.rst @@ -0,0 +1,551 @@ +**************************** + What's New In Python 3.5 +**************************** + +:Release: |release| +:Date: |today| + +.. Rules for maintenance: + + * Anyone can add text to this document. Do not spend very much time + on the wording of your changes, because your text will probably + get rewritten to some degree. + + * The maintainer will go through Misc/NEWS periodically and add + changes; it's therefore more important to add your changes to + Misc/NEWS than to this file. + + * This is not a complete list of every single change; completeness + is the purpose of Misc/NEWS. Some changes I consider too small + or esoteric to include. If such a change is added to the text, + I'll just remove it. (This is another reason you shouldn't spend + too much time on writing your addition.) + + * If you want to draw your new text to the attention of the + maintainer, add 'XXX' to the beginning of the paragraph or + section. + + * It's OK to just add a fragmentary note about a change. For + example: "XXX Describe the transmogrify() function added to the + socket module." The maintainer will research the change and + write the necessary text. + + * You can comment out your additions if you like, but it's not + necessary (especially when a final release is some months away). + + * Credit the author of a patch or bugfix. Just the name is + sufficient; the e-mail address isn't necessary. + + * It's helpful to add the bug/patch number as a comment: + + XXX Describe the transmogrify() function added to the socket + module. + (Contributed by P.Y. Developer in :issue:`12345`.) + + This saves the maintainer the effort of going through the Mercurial log + when researching a change. + +This article explains the new features in Python 3.5, compared to 3.4. + +For full details, see the :source:`Misc/NEWS` file. + +.. note:: Prerelease users should be aware that this document is currently in + draft form. It will be updated substantially as Python 3.5 moves towards + release, so it's worth checking back even after reading earlier versions. + + +.. seealso:: + + :pep:`478` - Python 3.5 Release Schedule + + +Summary -- Release highlights +============================= + +.. This section singles out the most important changes in Python 3.3. + Brevity is key. + +New syntax features: + +* None yet. + +New library modules: + +* None yet. + +New built-in features: + +* None yet. + +Implementation improvements: + +* When the ``LC_TYPE`` locale is the POSIX locale (``C`` locale), + :py:data:`sys.stdin` and :py:data:`sys.stdout` are now using the + ``surrogateescape`` error handler, instead of the ``strict`` error handler + (:issue:`19977`). + +Significantly Improved Library Modules: + +* None yet. + +Security improvements: + +* None yet. + +Please read on for a comprehensive list of user-facing changes. + + +.. PEP-sized items next. + +.. _pep-4XX: + +.. PEP 4XX: Virtual Environments +.. ============================= + + +.. (Implemented by Foo Bar.) + +.. .. seealso:: + + :pep:`4XX` - Python Virtual Environments + PEP written by Carl Meyer + + +PEP 475: Retry system calls failing with EINTR +---------------------------------------------- + +:pep:`475` adds support for automatic retry of system calls failing with EINTR: +this means that user code doesn't have to deal with EINTR or InterruptedError +manually, and should make it more robust against asynchronous signal reception. + +.. seealso:: + + :pep:`475` -- Retry system calls failing with EINTR + + +Other Language Changes +====================== + +Some smaller changes made to the core Python language are: + +* Added the ``'namereplace'`` error handlers. The ``'backslashreplace'`` + error handlers now works with decoding and translating. + (Contributed by Serhiy Storchaka in :issue:`19676` and :issue:`22286`.) + + + +New Modules +=========== + +.. module name +.. ----------- + +* None yet. + + +Improved Modules +================ + +argparse +-------- + +* :class:`~argparse.ArgumentParser` now allows to disable + :ref:`abbreviated usage <prefix-matching>` of long options by setting + :ref:`allow_abbrev` to ``False``. + (Contributed by Jonathan Paugh, Steven Bethard, paul j3 and Daniel Eriksson.) + +cgi +--- + +* :class:`~cgi.FieldStorage` now supports the context management protocol. + (Contributed by Berker Peksag in :issue:`20289`.) + +code +---- + +* The :func:`code.InteractiveInterpreter.showtraceback` method now prints + the full chained traceback, just like the interactive interpreter. + (Contributed by Claudiu Popa in :issue:`17442`.) + +compileall +---------- + +* :func:`compileall.compile_dir` and :mod:`compileall`'s command-line interface + can now do parallel bytecode compilation. + (Contributed by Claudiu Popa in :issue:`16104`.) + +contextlib +---------- + +* The new :func:`contextlib.redirect_stderr` context manager(similar to + :func:`contextlib.redirect_stdout`) makes it easier for utility scripts to + handle inflexible APIs that write their output to :data:`sys.stderr` and + don't provide any options to redirect it. + (Contributed by Berker Peksag in :issue:`22389`.) + +distutils +--------- + +* The ``build`` and ``build_ext`` commands now accept a ``-j`` + option to enable parallel building of extension modules. + (Contributed by Antoine Pitrou in :issue:`5309`.) + +doctest +------- + +* :func:`doctest.DocTestSuite` returns an empty :class:`unittest.TestSuite` if + *module* contains no docstrings instead of raising :exc:`ValueError`. + (Contributed by Glenn Jones in :issue:`15916`.) + +glob +---- + +* :func:`~glob.iglob` and :func:`~glob.glob` now support recursive search in + subdirectories using the "``**``" pattern. + (Contributed by Serhiy Storchaka in :issue:`13968`.) + +imaplib +------- + +* :class:`IMAP4` now supports the context management protocol. When used in a + :keyword:`with` statement, the IMAP4 ``LOGOUT`` command will be called + automatically at the end of the block. (Contributed by Tarek Ziadé and + Serhiy Storchaka in :issue:`4972`.) + +imghdr +------ + +* :func:`~imghdr.what` now recognizes the `OpenEXR <http://www.openexr.com>`_ + format. (Contributed by Martin Vignali and Claudiu Popa in :issue:`20295`.) + +importlib +--------- + +* :class:`importlib.util.LazyLoader` allows for the lazy loading of modules in + applications where startup time is paramount. + (Contributed by Brett Cannon in :issue:`17621`.) + +* :func:`importlib.abc.InspectLoader.source_to_code` is now a + static method to make it easier to work with source code in a string. + With a module object that you want to initialize you can then use + ``exec(code, module.__dict__)`` to execute the code in the module. + +* :func:`importlib.util.module_from_spec` is now the preferred way to create a + new module. Compared to :class:`types.ModuleType`, this new function will set + the various import-controlled attributes based on the passed-in spec object. + +inspect +------- + +* :class:`inspect.Signature` and :class:`inspect.Parameter` are now + picklable and hashable. (Contributed by Yury Selivanov in :issue:`20726` + and :issue:`20334`.) + +* New class method :meth:`inspect.Signature.from_callable`, which makes + subclassing of :class:`~inspect.Signature` easier. (Contributed + by Yury Selivanov and Eric Snow in :issue:`17373`.) + +ipaddress +--------- + +* :class:`ipaddress.IPv4Network` and :class:`ipaddress.IPv6Network` now + accept an ``(address, netmask)`` tuple argument, so as to easily construct + network objects from existing addresses. (Contributed by Peter Moody + and Antoine Pitrou in :issue:`16531`.) + +json +---- + +* The output of :mod:`json.tool` command line interface is now in the same + order as the input. Use the :option:`--sort-keys` option to sort the output + of dictionaries alphabetically by key. (Contributed by Berker Peksag in + :issue:`21650`.) + +* JSON decoder now raises :exc:`json.JSONDecodeError` instead of + :exc:`ValueError`. (Contributed by Serhiy Storchaka in :issue:`19361`.) + +os +-- + +* :class:`os.stat_result` now has a :attr:`~os.stat_result.st_file_attributes` + attribute on Windows. (Contributed by Ben Hoyt in :issue:`21719`.) + +re +-- + +* Number of capturing groups in regular expression is no longer limited by 100. + (Contributed by Serhiy Storchaka in :issue:`22437`.) + +* Now unmatched groups are replaced with empty strings in :func:`re.sub` + and :func:`re.subn`. (Contributed by Serhiy Storchaka in :issue:`1519638`.) + +math +---- + +* :data:`math.inf` and :data:`math.nan` constants added. (Contributed by Mark + Dickinson in :issue:`23185`.) + +shutil +------ + +* :func:`~shutil.move` now accepts a *copy_function* argument, allowing, + for example, :func:`~shutil.copy` to be used instead of the default + :func:`~shutil.copy2` if there is a need to ignore metadata. (Contributed by + Claudiu Popa in :issue:`19840`.) + +signal +------ + +* Different constants of :mod:`signal` module are now enumeration values using + the :mod:`enum` module. This allows meaningful names to be printed during + debugging, instead of integer “magic numbersâ€. (Contributed by Giampaolo + Rodola' in :issue:`21076`.) + +smtpd +----- + +* Both :class:`~smtpd.SMTPServer` and :class:`smtpd.SMTPChannel` now accept a + *decode_data* keyword to determine if the DATA portion of the SMTP + transaction is decoded using the ``utf-8`` codec or is instead provided to + :meth:`~smtpd.SMTPServer.process_message` as a byte string. The default + is ``True`` for backward compatibility reasons, but will change to ``False`` + in Python 3.6. (Contributed by Maciej Szulik in :issue:`19662`.) + +* It is now possible to provide, directly or via name resolution, IPv6 + addresses in the :class:`~smtpd.SMTPServer` constructor, and have it + successfully connect. (Contributed by Milan Oberkirch in :issue:`14758`.) + +* :mod:`~smtpd.SMTPServer` now supports :rfc:`6531` via the *enable_SMTPUTF8* + constructor argument and a user-provided + :meth:`~smtpd.SMTPServer.process_smtputf8_message` method. + +smtplib +------- + +* A new :meth:`~smtplib.SMTP.auth` method provides a convenient way to + implement custom authentication mechanisms. + (Contributed by Milan Oberkirch in :issue:`15014`.) + +sndhdr +------ + +* :func:`~sndhdr.what` and :func:`~sndhdr.whathdr` now return + :func:`~collections.namedtuple`. + (Contributed by Claudiu Popa in :issue:`18615`.) + +socket +------ + +* New :meth:`socket.socket.sendfile` method allows to send a file over a socket + by using high-performance :func:`os.sendfile` function on UNIX resulting in + uploads being from 2x to 3x faster than when using plain + :meth:`socket.socket.send`. + (Contributed by Giampaolo Rodola' in :issue:`17552`.) + +sysconfig +--------- + +* The user scripts directory on Windows is now versioned. + (Contributed by Paul Moore in :issue:`23437`.) + + +tarfile +------- + +* The :func:`tarfile.open` function now supports ``'x'`` (exclusive creation) + mode. (Contributed by Berker Peksag in :issue:`21717`.) + +time +---- + +* The :func:`time.monotonic` function is now always available. (Contributed by + Victor Stinner in :issue:`22043`.) + +urllib +------ + +* A new :class:`urllib.request.HTTPBasicPriorAuthHandler` allows HTTP Basic + Authentication credentials to be sent unconditionally with the first HTTP + request, rather than waiting for a HTTP 401 Unauthorized response from the + server. + (Contributed by Matej Cepl in :issue:`19494`.) + +wsgiref +------- + +* *headers* parameter of :class:`wsgiref.headers.Headers` is now optional. + (Contributed by Pablo Torres Navarrete and SilentGhost in :issue:`5800`.) + +xmlrpc +------ + +* :class:`xmlrpc.client.ServerProxy` is now a :term:`context manager`. + (Contributed by Claudiu Popa in :issue:`20627`.) + + +Optimizations +============= + +The following performance enhancements have been added: + +* Construction of ``bytes(int)`` (filled by zero bytes) is faster and use less + memory for large objects. ``calloc()`` is used instead of ``malloc()`` to + allocate memory for these objects. + +* Some operations on :class:`~ipaddress.IPv4Network` and + :class:`~ipaddress.IPv6Network` have been massively sped up, such as + :meth:`~ipaddress.IPv4Network.subnets`, :meth:`~ipaddress.IPv4Network.supernet`, + :func:`~ipaddress.summarize_address_range`, :func:`~ipaddress.collapse_addresses`. + The speed up can range from 3x to 15x. + (:issue:`21486`, :issue:`21487`, :issue:`20826`) + +* Many operations on :class:`io.BytesIO` are now 50% to 100% faster. + (Contributed by Serhiy Storchaka in :issue:`15381` and David Wilson in + :issue:`22003`.) + +* :func:`marshal.dumps` is now faster (65%-85% with versions 3--4, 20-25% with + versions 0--2 on typical data, and up to 5x in best cases). + (Contributed by Serhiy Storchaka in :issue:`20416` and :issue:`23344`.) + + +Build and C API Changes +======================= + +Changes to Python's build process and to the C API include: + +* New ``calloc`` functions: + + * :c:func:`PyMem_RawCalloc` + * :c:func:`PyMem_Calloc` + * :c:func:`PyObject_Calloc` + * :c:func:`_PyObject_GC_Calloc` + + +Deprecated +========== + +Unsupported Operating Systems +----------------------------- + +* None yet. + + +Deprecated Python modules, functions and methods +------------------------------------------------ + +* The :mod:`formatter` module has now graduated to full deprecation and is still + slated for removal in Python 3.6. + +* :mod:`smtpd` has in the past always decoded the DATA portion of email + messages using the ``utf-8`` codec. This can now be controlled by the new + *decode_data* keyword to :class:`~smtpd.SMTPServer`. The default value is + ``True``, but this default is deprecated. Specify the *decode_data* keyword + with an appropriate value to avoid the deprecation warning. + + +Deprecated functions and types of the C API +------------------------------------------- + +* None yet. + + +Deprecated features +------------------- + +* None yet. + + +Removed +======= + +API and Feature Removals +------------------------ + +The following obsolete and previously deprecated APIs and features have been +removed: + +* The ``__version__`` attribute has been dropped from the email package. The + email code hasn't been shipped separately from the stdlib for a long time, + and the ``__version__`` string was not updated in the last few releases. + +* The internal ``Netrc`` class in the :mod:`ftplib` module was deprecated in + 3.4, and has now been removed. + (Contributed by Matt Chaput in :issue:`6623`.) + +Porting to Python 3.5 +===================== + +This section lists previously described changes and other bugfixes +that may require changes to your code. + +Changes in the Python API +------------------------- + +* Before Python 3.5, a :class:`datetime.time` object was considered to be false + if it represented midnight in UTC. This behavior was considered obscure and + error-prone and has been removed in Python 3.5. See :issue:`13936` for full + details. + +* :meth:`ssl.SSLSocket.send()` now raises either :exc:`ssl.SSLWantReadError` + or :exc:`ssl.SSLWantWriteError` on a non-blocking socket if the operation + would block. Previously, it would return 0. See :issue:`20951`. + +* The ``__name__`` attribute of generator is now set from the function name, + instead of being set from the code name. Use ``gen.gi_code.co_name`` to + retrieve the code name. Generators also have a new ``__qualname__`` + attribute, the qualified name, which is now used for the representation + of a generator (``repr(gen)``). See :issue:`21205`. + +* The deprecated "strict" mode and argument of :class:`~html.parser.HTMLParser`, + :meth:`HTMLParser.error`, and the :exc:`HTMLParserError` exception have been + removed. (Contributed by Ezio Melotti in :issue:`15114`.) + The *convert_charrefs* argument of :class:`~html.parser.HTMLParser` is + now ``True`` by default. (Contributed by Berker Peksag in :issue:`21047`.) + +* Although it is not formally part of the API, it is worth noting for porting + purposes (ie: fixing tests) that error messages that were previously of the + form "'sometype' does not support the buffer protocol" are now of the form "a + bytes-like object is required, not 'sometype'". (Contributed by Ezio Melotti + in :issue:`16518`.) + +* If the current directory is set to a directory that no longer exists then + :exc:`FileNotFoundError` will no longer be raised and instead + :meth:`~importlib.machinery.FileFinder.find_spec` will return ``None`` + **without** caching ``None`` in :data:`sys.path_importer_cache` which is + different than the typical case (:issue:`22834`). + +* HTTP status code and messages from :mod:`http.client` and :mod:`http.server` + were refactored into a common :class:`~http.HTTPStatus` enum. The values in + :mod:`http.client` and :mod:`http.server` remain available for backwards + compatibility. (Contributed by Demian Brecht in :issue:`21793`.) + +* When an import loader defines :meth:`~importlib.machinery.Loader.exec_module` + it is now expected to also define + :meth:`~importlib.machinery.Loader.create_module` (raises a + :exc:`DeprecationWarning` now, will be an error in Python 3.6). If the loader + inherits from :class:`importlib.abc.Loader` then there is nothing to do, else + simply define :meth:`~importlib.machinery.Loader.create_module` to return + ``None`` (:issue:`23014`). + +* :func:`re.split` always ignored empty pattern matches, so the ``'x*'`` + pattern worked the same as ``'x+'``, and the ``'\b'`` pattern never worked. + Now :func:`re.split` raises a warning if the pattern could match + an empty string. For compatibility use patterns that never match an empty + string (e.g. ``'x+'`` instead of ``'x*'``). Patterns that could only match + an empty string (such as ``'\b'``) now raise an error. + +Changes in the C API +-------------------- + +* The undocumented :c:member:`~PyMemoryViewObject.format` member of the + (non-public) :c:type:`PyMemoryViewObject` structure has been removed. + + All extensions relying on the relevant parts in ``memoryobject.h`` + must be rebuilt. + +* The :c:type:`PyMemAllocator` structure was renamed to + :c:type:`PyMemAllocatorEx` and a new ``calloc`` field was added. + +* Removed non-documented macro :c:macro:`PyObject_REPR` which leaked references. + Use format character ``%R`` in :c:func:`PyUnicode_FromFormat`-like functions + to format the :func:`repr` of the object. diff --git a/Doc/whatsnew/changelog.rst b/Doc/whatsnew/changelog.rst index 57e2dabffaa3..07f90948bd0a 100644 --- a/Doc/whatsnew/changelog.rst +++ b/Doc/whatsnew/changelog.rst @@ -3,4 +3,3 @@ Changelog +++++++++ .. miscnews:: ../../Misc/NEWS - diff --git a/Doc/whatsnew/index.rst b/Doc/whatsnew/index.rst index 29902e407c8f..edb55022bdf1 100644 --- a/Doc/whatsnew/index.rst +++ b/Doc/whatsnew/index.rst @@ -11,6 +11,7 @@ anyone wishing to stay up-to-date after a new release. .. toctree:: :maxdepth: 2 + 3.5.rst 3.4.rst 3.3.rst 3.2.rst diff --git a/Grammar/Grammar b/Grammar/Grammar index d7aaffd60e14..6c012c06ee44 100644 --- a/Grammar/Grammar +++ b/Grammar/Grammar @@ -40,7 +40,7 @@ small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt | expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) | ('=' (yield_expr|testlist_star_expr))*) testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [','] -augassign: ('+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' | +augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' | '<<=' | '>>=' | '**=' | '//=') # For normal assignments, additional restrictions enforced by the interpreter del_stmt: 'del' exprlist @@ -89,7 +89,7 @@ and_test: not_test ('and' not_test)* not_test: 'not' not_test | comparison comparison: expr (comp_op expr)* # <> isn't actually a valid comparison operator in Python. It's here for the -# sake of a __future__ import described in PEP 401 +# sake of a __future__ import described in PEP 401 (which really works :-) comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not' star_expr: '*' expr expr: xor_expr ('|' xor_expr)* @@ -97,7 +97,7 @@ xor_expr: and_expr ('^' and_expr)* and_expr: shift_expr ('&' shift_expr)* shift_expr: arith_expr (('<<'|'>>') arith_expr)* arith_expr: term (('+'|'-') term)* -term: factor (('*'|'/'|'%'|'//') factor)* +term: factor (('*'|'@'|'/'|'%'|'//') factor)* factor: ('+'|'-'|'~') factor | power power: atom trailer* ['**' factor] atom: ('(' [yield_expr|testlist_comp] ')' | diff --git a/Include/Python-ast.h b/Include/Python-ast.h index 67d677b233b8..37e9a606c271 100644 --- a/Include/Python-ast.h +++ b/Include/Python-ast.h @@ -15,9 +15,9 @@ typedef struct _slice *slice_ty; typedef enum _boolop { And=1, Or=2 } boolop_ty; -typedef enum _operator { Add=1, Sub=2, Mult=3, Div=4, Mod=5, Pow=6, LShift=7, - RShift=8, BitOr=9, BitXor=10, BitAnd=11, FloorDiv=12 } - operator_ty; +typedef enum _operator { Add=1, Sub=2, Mult=3, MatMult=4, Div=5, Mod=6, Pow=7, + LShift=8, RShift=9, BitOr=10, BitXor=11, BitAnd=12, + FloorDiv=13 } operator_ty; typedef enum _unaryop { Invert=1, Not=2, UAdd=3, USub=4 } unaryop_ty; diff --git a/Include/Python.h b/Include/Python.h index 2dd82903bcda..46d2eced9297 100644 --- a/Include/Python.h +++ b/Include/Python.h @@ -112,6 +112,7 @@ #include "pyarena.h" #include "modsupport.h" #include "pythonrun.h" +#include "pylifecycle.h" #include "ceval.h" #include "sysmodule.h" #include "intrcheck.h" diff --git a/Include/abstract.h b/Include/abstract.h index d258ad556875..db70f213bc6e 100644 --- a/Include/abstract.h +++ b/Include/abstract.h @@ -409,8 +409,8 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/ #ifndef Py_LIMITED_API PyAPI_FUNC(int) _PyObject_HasLen(PyObject *o); + PyAPI_FUNC(Py_ssize_t) PyObject_LengthHint(PyObject *o, Py_ssize_t); #endif -PyAPI_FUNC(Py_ssize_t) PyObject_LengthHint(PyObject *o, Py_ssize_t); /* Guess the size of object o using len(o) or o.__length_hint__(). @@ -658,6 +658,12 @@ PyAPI_FUNC(Py_ssize_t) PyObject_LengthHint(PyObject *o, Py_ssize_t); o1*o2. */ + PyAPI_FUNC(PyObject *) PyNumber_MatrixMultiply(PyObject *o1, PyObject *o2); + + /* + This is the equivalent of the Python expression: o1 @ o2. + */ + PyAPI_FUNC(PyObject *) PyNumber_FloorDivide(PyObject *o1, PyObject *o2); /* @@ -832,6 +838,12 @@ PyAPI_FUNC(Py_ssize_t) PyObject_LengthHint(PyObject *o, Py_ssize_t); o1 *= o2. */ + PyAPI_FUNC(PyObject *) PyNumber_InPlaceMatrixMultiply(PyObject *o1, PyObject *o2); + + /* + This is the equivalent of the Python expression: o1 @= o2. + */ + PyAPI_FUNC(PyObject *) PyNumber_InPlaceFloorDivide(PyObject *o1, PyObject *o2); @@ -1021,7 +1033,7 @@ PyAPI_FUNC(Py_ssize_t) PyObject_LengthHint(PyObject *o, Py_ssize_t); PyAPI_FUNC(PyObject *) PySequence_Fast(PyObject *o, const char* m); /* - Returns the sequence, o, as a list, unless it's already a + Return the sequence, o, as a list, unless it's already a tuple or list. Use PySequence_Fast_GET_ITEM to access the members of this list, and PySequence_Fast_GET_SIZE to get its length. diff --git a/Include/bytes_methods.h b/Include/bytes_methods.h index 1498b8f83c2b..11d5f4275231 100644 --- a/Include/bytes_methods.h +++ b/Include/bytes_methods.h @@ -21,8 +21,8 @@ extern void _Py_bytes_title(char *result, char *s, Py_ssize_t len); extern void _Py_bytes_capitalize(char *result, char *s, Py_ssize_t len); extern void _Py_bytes_swapcase(char *result, char *s, Py_ssize_t len); -/* This one gets the raw argument list. */ -extern PyObject* _Py_bytes_maketrans(PyObject *args); +/* The maketrans() static method. */ +extern PyObject* _Py_bytes_maketrans(Py_buffer *frm, Py_buffer *to); /* Shared __doc__ strings. */ extern const char _Py_isspace__doc__[]; diff --git a/Include/bytesobject.h b/Include/bytesobject.h index 0ee8d366d4ab..e379bace37e8 100644 --- a/Include/bytesobject.h +++ b/Include/bytesobject.h @@ -62,6 +62,7 @@ PyAPI_FUNC(void) PyBytes_Concat(PyObject **, PyObject *); PyAPI_FUNC(void) PyBytes_ConcatAndDel(PyObject **, PyObject *); #ifndef Py_LIMITED_API PyAPI_FUNC(int) _PyBytes_Resize(PyObject **, Py_ssize_t); +PyAPI_FUNC(PyObject *) _PyBytes_Format(PyObject *, PyObject *); #endif PyAPI_FUNC(PyObject *) PyBytes_DecodeEscape(const char *, Py_ssize_t, const char *, Py_ssize_t, diff --git a/Include/code.h b/Include/code.h index 7c7e5bf8dc73..ff2b97efe927 100644 --- a/Include/code.h +++ b/Include/code.h @@ -21,7 +21,12 @@ typedef struct { PyObject *co_varnames; /* tuple of strings (local variable names) */ PyObject *co_freevars; /* tuple of strings (free variable names) */ PyObject *co_cellvars; /* tuple of strings (cell variable names) */ - /* The rest doesn't count for hash or comparisons */ + /* The rest aren't used in either hash or comparisons, except for + co_name (used in both) and co_firstlineno (used only in + comparisons). This is done to preserve the name and line number + for tracebacks and debuggers; otherwise, constant de-duplication + would collapse identical functions/lambdas defined on different lines. + */ unsigned char *co_cell2arg; /* Maps cell vars which are arguments. */ PyObject *co_filename; /* unicode (where it was loaded from) */ PyObject *co_name; /* unicode (name, for reference) */ diff --git a/Include/codecs.h b/Include/codecs.h index 5ca505fbd5ec..466913540fd4 100644 --- a/Include/codecs.h +++ b/Include/codecs.h @@ -49,6 +49,10 @@ PyAPI_FUNC(int) PyCodec_Register( PyAPI_FUNC(PyObject *) _PyCodec_Lookup( const char *encoding ); + +PyAPI_FUNC(int) _PyCodec_Forget( + const char *encoding + ); #endif /* Codec registry encoding check API. @@ -94,7 +98,7 @@ PyAPI_FUNC(PyObject *) PyCodec_Decode( const char *errors ); -#ifndef PY_LIMITED_API +#ifndef Py_LIMITED_API /* Text codec specific encoding and decoding API. Checks the encoding against a list of codecs which do not @@ -104,7 +108,14 @@ PyAPI_FUNC(PyObject *) PyCodec_Decode( Please note that these APIs are internal and should not be used in Python C extensions. + XXX (ncoghlan): should we make these, or something like them, public + in Python 3.5+? + */ +PyAPI_FUNC(PyObject *) _PyCodec_LookupTextEncoding( + const char *encoding, + const char *alternate_command + ); PyAPI_FUNC(PyObject *) _PyCodec_EncodeText( PyObject *object, @@ -117,6 +128,19 @@ PyAPI_FUNC(PyObject *) _PyCodec_DecodeText( const char *encoding, const char *errors ); + +/* These two aren't actually text encoding specific, but _io.TextIOWrapper + * is the only current API consumer. + */ +PyAPI_FUNC(PyObject *) _PyCodecInfo_GetIncrementalDecoder( + PyObject *codec_info, + const char *errors + ); + +PyAPI_FUNC(PyObject *) _PyCodecInfo_GetIncrementalEncoder( + PyObject *codec_info, + const char *errors + ); #endif @@ -201,6 +225,9 @@ 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); +/* replace the unicode encode error with backslash escapes (\N, \x, \u and \U) */ +PyAPI_FUNC(PyObject *) PyCodec_NameReplaceErrors(PyObject *exc); + PyAPI_DATA(const char *) Py_hexdigits; #ifdef __cplusplus diff --git a/Include/complexobject.h b/Include/complexobject.h index 1934f3b38078..cb8c52c58008 100644 --- a/Include/complexobject.h +++ b/Include/complexobject.h @@ -14,21 +14,13 @@ typedef struct { /* Operations on complex numbers from complexmodule.c */ -#define c_sum _Py_c_sum -#define c_diff _Py_c_diff -#define c_neg _Py_c_neg -#define c_prod _Py_c_prod -#define c_quot _Py_c_quot -#define c_pow _Py_c_pow -#define c_abs _Py_c_abs - -PyAPI_FUNC(Py_complex) c_sum(Py_complex, Py_complex); -PyAPI_FUNC(Py_complex) c_diff(Py_complex, Py_complex); -PyAPI_FUNC(Py_complex) c_neg(Py_complex); -PyAPI_FUNC(Py_complex) c_prod(Py_complex, Py_complex); -PyAPI_FUNC(Py_complex) c_quot(Py_complex, Py_complex); -PyAPI_FUNC(Py_complex) c_pow(Py_complex, Py_complex); -PyAPI_FUNC(double) c_abs(Py_complex); +PyAPI_FUNC(Py_complex) _Py_c_sum(Py_complex, Py_complex); +PyAPI_FUNC(Py_complex) _Py_c_diff(Py_complex, Py_complex); +PyAPI_FUNC(Py_complex) _Py_c_neg(Py_complex); +PyAPI_FUNC(Py_complex) _Py_c_prod(Py_complex, Py_complex); +PyAPI_FUNC(Py_complex) _Py_c_quot(Py_complex, Py_complex); +PyAPI_FUNC(Py_complex) _Py_c_pow(Py_complex, Py_complex); +PyAPI_FUNC(double) _Py_c_abs(Py_complex); #endif /* Complex object interface */ diff --git a/Include/dictobject.h b/Include/dictobject.h index 285966963c3e..09dff5919128 100644 --- a/Include/dictobject.h +++ b/Include/dictobject.h @@ -50,12 +50,22 @@ PyAPI_DATA(PyTypeObject) PyDictValues_Type; PyAPI_FUNC(PyObject *) PyDict_New(void); PyAPI_FUNC(PyObject *) PyDict_GetItem(PyObject *mp, PyObject *key); +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) _PyDict_GetItem_KnownHash(PyObject *mp, PyObject *key, + Py_hash_t hash); +#endif PyAPI_FUNC(PyObject *) PyDict_GetItemWithError(PyObject *mp, PyObject *key); PyAPI_FUNC(PyObject *) _PyDict_GetItemIdWithError(PyObject *dp, struct _Py_Identifier *key); +#ifndef Py_LIMITED_API PyAPI_FUNC(PyObject *) PyDict_SetDefault( PyObject *mp, PyObject *key, PyObject *defaultobj); +#endif PyAPI_FUNC(int) PyDict_SetItem(PyObject *mp, PyObject *key, PyObject *item); +#ifndef Py_LIMITED_API +PyAPI_FUNC(int) _PyDict_SetItem_KnownHash(PyObject *mp, PyObject *key, + PyObject *item, Py_hash_t hash); +#endif PyAPI_FUNC(int) PyDict_DelItem(PyObject *mp, PyObject *key); PyAPI_FUNC(void) PyDict_Clear(PyObject *mp); PyAPI_FUNC(int) PyDict_Next( diff --git a/Include/dynamic_annotations.h b/Include/dynamic_annotations.h index d63c5db08576..0bd1a833c2e5 100644 --- a/Include/dynamic_annotations.h +++ b/Include/dynamic_annotations.h @@ -150,7 +150,7 @@ /* Report that a new memory at "address" of size "size" has been allocated. This might be used when the memory has been retrieved from a free list and - is about to be reused, or when a the locking discipline for a variable + is about to be reused, or when the locking discipline for a variable changes. */ #define _Py_ANNOTATE_NEW_MEMORY(address, size) \ AnnotateNewMemory(__FILE__, __LINE__, address, size) diff --git a/Include/fileutils.h b/Include/fileutils.h index 5466e3c7e0d7..6effd88f3d69 100644 --- a/Include/fileutils.h +++ b/Include/fileutils.h @@ -7,11 +7,11 @@ extern "C" { PyAPI_FUNC(PyObject *) _Py_device_encoding(int); -PyAPI_FUNC(wchar_t *) _Py_char2wchar( +PyAPI_FUNC(wchar_t *) Py_DecodeLocale( const char *arg, size_t *size); -PyAPI_FUNC(char*) _Py_wchar2char( +PyAPI_FUNC(char*) Py_EncodeLocale( const wchar_t *text, size_t *error_pos); @@ -21,15 +21,46 @@ PyAPI_FUNC(int) _Py_wstat( struct stat *buf); #endif +#if defined(HAVE_FSTAT) || defined(MS_WINDOWS) + +#ifdef MS_WINDOWS +struct _Py_stat_struct { + unsigned long st_dev; + __int64 st_ino; + unsigned short st_mode; + int st_nlink; + int st_uid; + int st_gid; + unsigned long st_rdev; + __int64 st_size; + time_t st_atime; + int st_atime_nsec; + time_t st_mtime; + int st_mtime_nsec; + time_t st_ctime; + int st_ctime_nsec; + unsigned long st_file_attributes; +}; +#else +# define _Py_stat_struct stat +#endif + +PyAPI_FUNC(int) _Py_fstat( + int fd, + struct _Py_stat_struct *stat); +#endif /* HAVE_FSTAT || MS_WINDOWS */ + #ifdef HAVE_STAT PyAPI_FUNC(int) _Py_stat( PyObject *path, struct stat *statbuf); -#endif +#endif /* HAVE_STAT */ +#ifndef Py_LIMITED_API PyAPI_FUNC(int) _Py_open( const char *pathname, int flags); +#endif PyAPI_FUNC(FILE *) _Py_wfopen( const wchar_t *path, @@ -61,6 +92,7 @@ PyAPI_FUNC(wchar_t*) _Py_wgetcwd( wchar_t *buf, size_t size); +#ifndef Py_LIMITED_API PyAPI_FUNC(int) _Py_get_inheritable(int fd); PyAPI_FUNC(int) _Py_set_inheritable(int fd, int inheritable, @@ -68,6 +100,14 @@ PyAPI_FUNC(int) _Py_set_inheritable(int fd, int inheritable, PyAPI_FUNC(int) _Py_dup(int fd); +#ifndef MS_WINDOWS +PyAPI_FUNC(int) _Py_get_blocking(int fd); + +PyAPI_FUNC(int) _Py_set_blocking(int fd, int blocking); +#endif /* !MS_WINDOWS */ + +#endif /* Py_LIMITED_API */ + #ifdef __cplusplus } #endif diff --git a/Include/frameobject.h b/Include/frameobject.h index b41bea684a5f..966ff1f6e6e3 100644 --- a/Include/frameobject.h +++ b/Include/frameobject.h @@ -39,7 +39,6 @@ typedef struct _frame { /* Borrowed reference to a generator, or NULL */ PyObject *f_gen; - PyThreadState *f_tstate; int f_lasti; /* Last instruction if called */ /* Call PyFrame_GetLineNumber() instead of reading this field directly. As of 2.3 f_lineno is only valid when tracing is diff --git a/Include/genobject.h b/Include/genobject.h index 65f1ecfd5495..23571e663bc6 100644 --- a/Include/genobject.h +++ b/Include/genobject.h @@ -25,6 +25,12 @@ typedef struct { /* List of weak reference. */ PyObject *gi_weakreflist; + + /* Name of the generator. */ + PyObject *gi_name; + + /* Qualified name of the generator. */ + PyObject *gi_qualname; } PyGenObject; PyAPI_DATA(PyTypeObject) PyGen_Type; @@ -33,6 +39,8 @@ PyAPI_DATA(PyTypeObject) PyGen_Type; #define PyGen_CheckExact(op) (Py_TYPE(op) == &PyGen_Type) PyAPI_FUNC(PyObject *) PyGen_New(struct _frame *); +PyAPI_FUNC(PyObject *) PyGen_NewWithQualName(struct _frame *, + PyObject *name, PyObject *qualname); PyAPI_FUNC(int) PyGen_NeedsFinalizing(PyGenObject *); PyAPI_FUNC(int) _PyGen_FetchStopIterationValue(PyObject **); PyObject *_PyGen_Send(PyGenObject *, PyObject *); diff --git a/Include/import.h b/Include/import.h index 4a515d5b6be9..afdfac2a938f 100644 --- a/Include/import.h +++ b/Include/import.h @@ -86,15 +86,15 @@ PyAPI_FUNC(int) _PyImport_ReleaseLock(void); PyAPI_FUNC(void) _PyImport_ReInitLock(void); -PyAPI_FUNC(PyObject *)_PyImport_FindBuiltin( +PyAPI_FUNC(PyObject *) _PyImport_FindBuiltin( const char *name /* UTF-8 encoded string */ ); -PyAPI_FUNC(PyObject *)_PyImport_FindExtensionObject(PyObject *, PyObject *); -PyAPI_FUNC(int)_PyImport_FixupBuiltin( +PyAPI_FUNC(PyObject *) _PyImport_FindExtensionObject(PyObject *, PyObject *); +PyAPI_FUNC(int) _PyImport_FixupBuiltin( PyObject *mod, const char *name /* UTF-8 encoded string */ ); -PyAPI_FUNC(int)_PyImport_FixupExtensionObject(PyObject*, PyObject *, PyObject *); +PyAPI_FUNC(int) _PyImport_FixupExtensionObject(PyObject*, PyObject *, PyObject *); struct _inittab { const char *name; /* ASCII encoded string */ diff --git a/Include/listobject.h b/Include/listobject.h index dc62aee91a59..74cf46f4f9b6 100644 --- a/Include/listobject.h +++ b/Include/listobject.h @@ -46,7 +46,7 @@ PyAPI_DATA(PyTypeObject) PyListRevIter_Type; PyAPI_DATA(PyTypeObject) PySortWrapper_Type; #define PyList_Check(op) \ - PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_LIST_SUBCLASS) + PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_LIST_SUBCLASS) #define PyList_CheckExact(op) (Py_TYPE(op) == &PyList_Type) PyAPI_FUNC(PyObject *) PyList_New(Py_ssize_t size); diff --git a/Include/longobject.h b/Include/longobject.h index 7c3f6d02d5c7..ff43309c7689 100644 --- a/Include/longobject.h +++ b/Include/longobject.h @@ -165,6 +165,12 @@ PyAPI_FUNC(int) _PyLong_AsByteArray(PyLongObject* v, unsigned char* bytes, size_t n, int little_endian, int is_signed); +/* _PyLong_FromNbInt: Convert the given object to a PyLongObject + using the nb_int slot, if available. Raise TypeError if either the + nb_int slot is not available or the result of the call to nb_int + returns something not of type int. +*/ +PyAPI_FUNC(PyLongObject *)_PyLong_FromNbInt(PyObject *); /* _PyLong_Format: Convert the long to a string object with given base, appending a base prefix of 0[box] if base is 2, 8 or 16. */ diff --git a/Include/memoryobject.h b/Include/memoryobject.h index c2e11944467b..ab5ee0956c6e 100644 --- a/Include/memoryobject.h +++ b/Include/memoryobject.h @@ -45,9 +45,6 @@ typedef struct { } _PyManagedBufferObject; -/* static storage used for casting between formats */ -#define _Py_MEMORYVIEW_MAX_FORMAT 3 /* must be >= 3 */ - /* memoryview state flags */ #define _Py_MEMORYVIEW_RELEASED 0x001 /* access to master buffer blocked */ #define _Py_MEMORYVIEW_C 0x002 /* C-contiguous layout */ @@ -62,7 +59,6 @@ typedef struct { int flags; /* state flags */ Py_ssize_t exports; /* number of buffer re-exports */ Py_buffer view; /* private copy of the exporter's view */ - char format[_Py_MEMORYVIEW_MAX_FORMAT]; /* used for casting */ PyObject *weakreflist; Py_ssize_t ob_array[1]; /* shape, strides, suboffsets */ } PyMemoryViewObject; diff --git a/Include/methodobject.h b/Include/methodobject.h index 3cc2ea9308f5..0236228617e4 100644 --- a/Include/methodobject.h +++ b/Include/methodobject.h @@ -77,6 +77,7 @@ typedef struct { PyMethodDef *m_ml; /* Description of the C function to call */ PyObject *m_self; /* Passed as 'self' arg to the C func, can be NULL */ PyObject *m_module; /* The __module__ attribute, can be anything */ + PyObject *m_weakreflist; /* List of weak references */ } PyCFunctionObject; #endif diff --git a/Include/modsupport.h b/Include/modsupport.h index ab725f612aca..5de0458245d9 100644 --- a/Include/modsupport.h +++ b/Include/modsupport.h @@ -36,6 +36,7 @@ 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 *, diff --git a/Include/moduleobject.h b/Include/moduleobject.h index 8013dd9b484a..f119364b8893 100644 --- a/Include/moduleobject.h +++ b/Include/moduleobject.h @@ -25,6 +25,7 @@ PyAPI_FUNC(const char *) PyModule_GetFilename(PyObject *); PyAPI_FUNC(PyObject *) PyModule_GetFilenameObject(PyObject *); #ifndef Py_LIMITED_API PyAPI_FUNC(void) _PyModule_Clear(PyObject *); +PyAPI_FUNC(void) _PyModule_ClearDict(PyObject *); #endif PyAPI_FUNC(struct PyModuleDef*) PyModule_GetDef(PyObject*); PyAPI_FUNC(void*) PyModule_GetState(PyObject*); diff --git a/Include/node.h b/Include/node.h index 99c13f7dc906..2e4e2bada7f2 100644 --- a/Include/node.h +++ b/Include/node.h @@ -21,7 +21,7 @@ PyAPI_FUNC(int) PyNode_AddChild(node *n, int type, char *str, int lineno, int col_offset); PyAPI_FUNC(void) PyNode_Free(node *n); #ifndef Py_LIMITED_API -Py_ssize_t _PyNode_SizeOf(node *n); +PyAPI_FUNC(Py_ssize_t) _PyNode_SizeOf(node *n); #endif /* Node access functions */ diff --git a/Include/object.h b/Include/object.h index f5396524c00f..e29608aed616 100644 --- a/Include/object.h +++ b/Include/object.h @@ -65,6 +65,7 @@ whose size is determined when the object is allocated. #error Py_LIMITED_API is incompatible with Py_DEBUG, Py_TRACE_REFS, and Py_REF_DEBUG #endif + #ifdef Py_TRACE_REFS /* Define pointers to support a doubly-linked list of all live heap objects. */ #define _PyObject_HEAD_EXTRA \ @@ -275,6 +276,9 @@ typedef struct { binaryfunc nb_inplace_true_divide; unaryfunc nb_index; + + binaryfunc nb_matrix_multiply; + binaryfunc nb_inplace_matrix_multiply; } PyNumberMethods; typedef struct { @@ -439,6 +443,9 @@ PyAPI_FUNC(PyObject*) PyType_FromSpec(PyType_Spec*); #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 PyAPI_FUNC(PyObject*) PyType_FromSpecWithBases(PyType_Spec*, PyObject*); #endif +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03040000 +PyAPI_FUNC(void*) PyType_GetSlot(PyTypeObject*, int); +#endif #ifndef Py_LIMITED_API /* The *real* layout of a type object when allocated on the heap */ @@ -492,6 +499,11 @@ PyAPI_FUNC(PyTypeObject *) _PyType_CalculateMetaclass(PyTypeObject *, PyObject * PyAPI_FUNC(unsigned int) PyType_ClearCache(void); PyAPI_FUNC(void) PyType_Modified(PyTypeObject *); +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) _PyType_GetDocFromInternalDoc(const char *, const char *); +PyAPI_FUNC(PyObject *) _PyType_GetTextSignatureFromInternalDoc(const char *, const char *); +#endif + /* Generic operations on objects */ struct _Py_Identifier; #ifndef Py_LIMITED_API @@ -533,8 +545,10 @@ PyAPI_FUNC(int) PyObject_Not(PyObject *); PyAPI_FUNC(int) PyCallable_Check(PyObject *); PyAPI_FUNC(void) PyObject_ClearWeakRefs(PyObject *); +#ifndef Py_LIMITED_API PyAPI_FUNC(void) PyObject_CallFinalizer(PyObject *); PyAPI_FUNC(int) PyObject_CallFinalizerFromDealloc(PyObject *); +#endif /* Same as PyObject_Generic{Get,Set}Attr, but passing the attributes dict as the last parameter. */ @@ -562,9 +576,6 @@ PyAPI_FUNC(PyObject *) PyObject_Dir(PyObject *); PyAPI_FUNC(int) Py_ReprEnter(PyObject *); PyAPI_FUNC(void) Py_ReprLeave(PyObject *); -/* Helper for passing objects to printf and the like */ -#define PyObject_REPR(obj) _PyUnicode_AsString(PyObject_Repr(obj)) - /* Flag bits for printing: */ #define Py_PRINT_RAW 1 /* No string quotes etc. */ @@ -700,11 +711,17 @@ PyAPI_FUNC(Py_ssize_t) _Py_GetRefTotal(void); _Py_NegativeRefcount(__FILE__, __LINE__, \ (PyObject *)(OP)); \ } +/* Py_REF_DEBUG also controls the display of refcounts and memory block + * allocations at the interactive prompt and at interpreter shutdown + */ +PyAPI_FUNC(void) _PyDebug_PrintTotalRefs(void); +#define _PY_DEBUG_PRINT_TOTAL_REFS() _PyDebug_PrintTotalRefs() #else #define _Py_INC_REFTOTAL #define _Py_DEC_REFTOTAL #define _Py_REF_DEBUG_COMMA #define _Py_CHECK_REFCNT(OP) /* a semicolon */; +#define _PY_DEBUG_PRINT_TOTAL_REFS() #endif /* Py_REF_DEBUG */ #ifdef COUNT_ALLOCS diff --git a/Include/objimpl.h b/Include/objimpl.h index 9a27ec384f9f..65b6d91c36ca 100644 --- a/Include/objimpl.h +++ b/Include/objimpl.h @@ -95,6 +95,7 @@ PyObject_{New, NewVar, Del}. the raw memory. */ PyAPI_FUNC(void *) PyObject_Malloc(size_t size); +PyAPI_FUNC(void *) PyObject_Calloc(size_t nelem, size_t elsize); PyAPI_FUNC(void *) PyObject_Realloc(void *ptr, size_t new_size); PyAPI_FUNC(void) PyObject_Free(void *ptr); @@ -265,7 +266,7 @@ extern PyGC_Head *_PyGC_generation0; #define _PyGCHead_REFS(g) ((g)->gc.gc_refs >> _PyGC_REFS_SHIFT) #define _PyGCHead_SET_REFS(g, v) do { \ (g)->gc.gc_refs = ((g)->gc.gc_refs & ~_PyGC_REFS_MASK) \ - | (v << _PyGC_REFS_SHIFT); \ + | (((size_t)(v)) << _PyGC_REFS_SHIFT); \ } while (0) #define _PyGCHead_DECREF(g) ((g)->gc.gc_refs -= 1 << _PyGC_REFS_SHIFT) @@ -321,7 +322,8 @@ extern PyGC_Head *_PyGC_generation0; (!PyTuple_CheckExact(obj) || _PyObject_GC_IS_TRACKED(obj))) #endif /* Py_LIMITED_API */ -PyAPI_FUNC(PyObject *) _PyObject_GC_Malloc(size_t); +PyAPI_FUNC(PyObject *) _PyObject_GC_Malloc(size_t size); +PyAPI_FUNC(PyObject *) _PyObject_GC_Calloc(size_t size); PyAPI_FUNC(PyObject *) _PyObject_GC_New(PyTypeObject *); PyAPI_FUNC(PyVarObject *) _PyObject_GC_NewVar(PyTypeObject *, Py_ssize_t); PyAPI_FUNC(void) PyObject_GC_Track(void *); diff --git a/Include/opcode.h b/Include/opcode.h index 0936f2d9f421..0638b5468c2d 100644 --- a/Include/opcode.h +++ b/Include/opcode.h @@ -1,3 +1,4 @@ +/* Auto-generated by Tools/scripts/generate_opcode_h.py */ #ifndef Py_OPCODE_H #define Py_OPCODE_H #ifdef __cplusplus @@ -5,141 +6,111 @@ extern "C" { #endif -/* Instruction opcodes for compiled code */ - -#define POP_TOP 1 -#define ROT_TWO 2 -#define ROT_THREE 3 -#define DUP_TOP 4 -#define DUP_TOP_TWO 5 -#define NOP 9 - -#define UNARY_POSITIVE 10 -#define UNARY_NEGATIVE 11 -#define UNARY_NOT 12 - -#define UNARY_INVERT 15 - -#define BINARY_POWER 19 - -#define BINARY_MULTIPLY 20 - -#define BINARY_MODULO 22 -#define BINARY_ADD 23 -#define BINARY_SUBTRACT 24 -#define BINARY_SUBSCR 25 -#define BINARY_FLOOR_DIVIDE 26 -#define BINARY_TRUE_DIVIDE 27 -#define INPLACE_FLOOR_DIVIDE 28 -#define INPLACE_TRUE_DIVIDE 29 - -#define STORE_MAP 54 -#define INPLACE_ADD 55 -#define INPLACE_SUBTRACT 56 -#define INPLACE_MULTIPLY 57 - -#define INPLACE_MODULO 59 -#define STORE_SUBSCR 60 -#define DELETE_SUBSCR 61 - -#define BINARY_LSHIFT 62 -#define BINARY_RSHIFT 63 -#define BINARY_AND 64 -#define BINARY_XOR 65 -#define BINARY_OR 66 -#define INPLACE_POWER 67 -#define GET_ITER 68 -#define PRINT_EXPR 70 -#define LOAD_BUILD_CLASS 71 -#define YIELD_FROM 72 - -#define INPLACE_LSHIFT 75 -#define INPLACE_RSHIFT 76 -#define INPLACE_AND 77 -#define INPLACE_XOR 78 -#define INPLACE_OR 79 -#define BREAK_LOOP 80 -#define WITH_CLEANUP 81 - -#define RETURN_VALUE 83 -#define IMPORT_STAR 84 - -#define YIELD_VALUE 86 -#define POP_BLOCK 87 -#define END_FINALLY 88 -#define POP_EXCEPT 89 - -#define HAVE_ARGUMENT 90 /* Opcodes from here have an argument: */ - -#define STORE_NAME 90 /* Index in name list */ -#define DELETE_NAME 91 /* "" */ -#define UNPACK_SEQUENCE 92 /* Number of sequence items */ -#define FOR_ITER 93 -#define UNPACK_EX 94 /* Num items before variable part + - (Num items after variable part << 8) */ - -#define STORE_ATTR 95 /* Index in name list */ -#define DELETE_ATTR 96 /* "" */ -#define STORE_GLOBAL 97 /* "" */ -#define DELETE_GLOBAL 98 /* "" */ - -#define LOAD_CONST 100 /* Index in const list */ -#define LOAD_NAME 101 /* Index in name list */ -#define BUILD_TUPLE 102 /* Number of tuple items */ -#define BUILD_LIST 103 /* Number of list items */ -#define BUILD_SET 104 /* Number of set items */ -#define BUILD_MAP 105 /* Always zero for now */ -#define LOAD_ATTR 106 /* Index in name list */ -#define COMPARE_OP 107 /* Comparison operator */ -#define IMPORT_NAME 108 /* Index in name list */ -#define IMPORT_FROM 109 /* Index in name list */ - -#define JUMP_FORWARD 110 /* Number of bytes to skip */ -#define JUMP_IF_FALSE_OR_POP 111 /* Target byte offset from beginning of code */ -#define JUMP_IF_TRUE_OR_POP 112 /* "" */ -#define JUMP_ABSOLUTE 113 /* "" */ -#define POP_JUMP_IF_FALSE 114 /* "" */ -#define POP_JUMP_IF_TRUE 115 /* "" */ - -#define LOAD_GLOBAL 116 /* Index in name list */ - -#define CONTINUE_LOOP 119 /* Start of loop (absolute) */ -#define SETUP_LOOP 120 /* Target address (relative) */ -#define SETUP_EXCEPT 121 /* "" */ -#define SETUP_FINALLY 122 /* "" */ - -#define LOAD_FAST 124 /* Local variable number */ -#define STORE_FAST 125 /* Local variable number */ -#define DELETE_FAST 126 /* Local variable number */ - -#define RAISE_VARARGS 130 /* Number of raise arguments (1, 2 or 3) */ -/* CALL_FUNCTION_XXX opcodes defined below depend on this definition */ -#define CALL_FUNCTION 131 /* #args + (#kwargs<<8) */ -#define MAKE_FUNCTION 132 /* #defaults + #kwdefaults<<8 + #annotations<<16 */ -#define BUILD_SLICE 133 /* Number of items */ - -#define MAKE_CLOSURE 134 /* same as MAKE_FUNCTION */ -#define LOAD_CLOSURE 135 /* Load free variable from closure */ -#define LOAD_DEREF 136 /* Load and dereference from closure cell */ -#define STORE_DEREF 137 /* Store into cell */ -#define DELETE_DEREF 138 /* Delete closure cell */ - -/* The next 3 opcodes must be contiguous and satisfy - (CALL_FUNCTION_VAR - CALL_FUNCTION) & 3 == 1 */ -#define CALL_FUNCTION_VAR 140 /* #args + (#kwargs<<8) */ -#define CALL_FUNCTION_KW 141 /* #args + (#kwargs<<8) */ -#define CALL_FUNCTION_VAR_KW 142 /* #args + (#kwargs<<8) */ - -#define SETUP_WITH 143 - -/* Support for opargs more than 16 bits long */ -#define EXTENDED_ARG 144 - -#define LIST_APPEND 145 -#define SET_ADD 146 -#define MAP_ADD 147 - -#define LOAD_CLASSDEREF 148 + /* Instruction opcodes for compiled code */ +#define POP_TOP 1 +#define ROT_TWO 2 +#define ROT_THREE 3 +#define DUP_TOP 4 +#define DUP_TOP_TWO 5 +#define NOP 9 +#define UNARY_POSITIVE 10 +#define UNARY_NEGATIVE 11 +#define UNARY_NOT 12 +#define UNARY_INVERT 15 +#define BINARY_MATRIX_MULTIPLY 16 +#define INPLACE_MATRIX_MULTIPLY 17 +#define BINARY_POWER 19 +#define BINARY_MULTIPLY 20 +#define BINARY_MODULO 22 +#define BINARY_ADD 23 +#define BINARY_SUBTRACT 24 +#define BINARY_SUBSCR 25 +#define BINARY_FLOOR_DIVIDE 26 +#define BINARY_TRUE_DIVIDE 27 +#define INPLACE_FLOOR_DIVIDE 28 +#define INPLACE_TRUE_DIVIDE 29 +#define STORE_MAP 54 +#define INPLACE_ADD 55 +#define INPLACE_SUBTRACT 56 +#define INPLACE_MULTIPLY 57 +#define INPLACE_MODULO 59 +#define STORE_SUBSCR 60 +#define DELETE_SUBSCR 61 +#define BINARY_LSHIFT 62 +#define BINARY_RSHIFT 63 +#define BINARY_AND 64 +#define BINARY_XOR 65 +#define BINARY_OR 66 +#define INPLACE_POWER 67 +#define GET_ITER 68 +#define PRINT_EXPR 70 +#define LOAD_BUILD_CLASS 71 +#define YIELD_FROM 72 +#define INPLACE_LSHIFT 75 +#define INPLACE_RSHIFT 76 +#define INPLACE_AND 77 +#define INPLACE_XOR 78 +#define INPLACE_OR 79 +#define BREAK_LOOP 80 +#define WITH_CLEANUP 81 +#define RETURN_VALUE 83 +#define IMPORT_STAR 84 +#define YIELD_VALUE 86 +#define POP_BLOCK 87 +#define END_FINALLY 88 +#define POP_EXCEPT 89 +#define HAVE_ARGUMENT 90 +#define STORE_NAME 90 +#define DELETE_NAME 91 +#define UNPACK_SEQUENCE 92 +#define FOR_ITER 93 +#define UNPACK_EX 94 +#define STORE_ATTR 95 +#define DELETE_ATTR 96 +#define STORE_GLOBAL 97 +#define DELETE_GLOBAL 98 +#define LOAD_CONST 100 +#define LOAD_NAME 101 +#define BUILD_TUPLE 102 +#define BUILD_LIST 103 +#define BUILD_SET 104 +#define BUILD_MAP 105 +#define LOAD_ATTR 106 +#define COMPARE_OP 107 +#define IMPORT_NAME 108 +#define IMPORT_FROM 109 +#define JUMP_FORWARD 110 +#define JUMP_IF_FALSE_OR_POP 111 +#define JUMP_IF_TRUE_OR_POP 112 +#define JUMP_ABSOLUTE 113 +#define POP_JUMP_IF_FALSE 114 +#define POP_JUMP_IF_TRUE 115 +#define LOAD_GLOBAL 116 +#define CONTINUE_LOOP 119 +#define SETUP_LOOP 120 +#define SETUP_EXCEPT 121 +#define SETUP_FINALLY 122 +#define LOAD_FAST 124 +#define STORE_FAST 125 +#define DELETE_FAST 126 +#define RAISE_VARARGS 130 +#define CALL_FUNCTION 131 +#define MAKE_FUNCTION 132 +#define BUILD_SLICE 133 +#define MAKE_CLOSURE 134 +#define LOAD_CLOSURE 135 +#define LOAD_DEREF 136 +#define STORE_DEREF 137 +#define DELETE_DEREF 138 +#define CALL_FUNCTION_VAR 140 +#define CALL_FUNCTION_KW 141 +#define CALL_FUNCTION_VAR_KW 142 +#define SETUP_WITH 143 +#define EXTENDED_ARG 144 +#define LIST_APPEND 145 +#define SET_ADD 146 +#define MAP_ADD 147 +#define LOAD_CLASSDEREF 148 /* EXCEPT_HANDLER is a special, implicit block type which is created when entering an except handler. It is not an opcode but we define it here @@ -148,8 +119,9 @@ extern "C" { #define EXCEPT_HANDLER 257 -enum cmp_op {PyCmp_LT=Py_LT, PyCmp_LE=Py_LE, PyCmp_EQ=Py_EQ, PyCmp_NE=Py_NE, PyCmp_GT=Py_GT, PyCmp_GE=Py_GE, - PyCmp_IN, PyCmp_NOT_IN, PyCmp_IS, PyCmp_IS_NOT, PyCmp_EXC_MATCH, PyCmp_BAD}; +enum cmp_op {PyCmp_LT=Py_LT, PyCmp_LE=Py_LE, PyCmp_EQ=Py_EQ, PyCmp_NE=Py_NE, + PyCmp_GT=Py_GT, PyCmp_GE=Py_GE, PyCmp_IN, PyCmp_NOT_IN, + PyCmp_IS, PyCmp_IS_NOT, PyCmp_EXC_MATCH, PyCmp_BAD}; #define HAS_ARG(op) ((op) >= HAVE_ARGUMENT) diff --git a/Include/osdefs.h b/Include/osdefs.h index 0c2e34b87957..bd84c1c12c19 100644 --- a/Include/osdefs.h +++ b/Include/osdefs.h @@ -7,15 +7,12 @@ extern "C" { /* Operating system dependencies */ -/* Mod by chrish: QNX has WATCOM, but isn't DOS */ -#if !defined(__QNX__) -#if defined(MS_WINDOWS) || defined(__BORLANDC__) || defined(__WATCOMC__) || defined(__DJGPP__) +#ifdef MS_WINDOWS #define SEP L'\\' #define ALTSEP L'/' #define MAXPATHLEN 256 #define DELIM L';' #endif -#endif /* Filename separator */ #ifndef SEP diff --git a/Include/patchlevel.h b/Include/patchlevel.h index e6c98e4ae5d2..ea0c042bfb41 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -17,13 +17,13 @@ /* Version parsed out into numeric values */ /*--start constants--*/ #define PY_MAJOR_VERSION 3 -#define PY_MINOR_VERSION 4 +#define PY_MINOR_VERSION 5 #define PY_MICRO_VERSION 0 -#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_BETA +#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_ALPHA #define PY_RELEASE_SERIAL 1 /* Version as a string */ -#define PY_VERSION "3.4.0b1" +#define PY_VERSION "3.5.0a1+" /*--end constants--*/ /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. diff --git a/Include/pyatomic.h b/Include/pyatomic.h index d4e19e0070be..80bd825bd751 100644 --- a/Include/pyatomic.h +++ b/Include/pyatomic.h @@ -1,12 +1,15 @@ #ifndef Py_LIMITED_API #ifndef Py_ATOMIC_H #define Py_ATOMIC_H -/* XXX: When compilers start offering a stdatomic.h with lock-free - atomic_int and atomic_address types, include that here and rewrite - the atomic operations in terms of it. */ #include "dynamic_annotations.h" +#include "pyconfig.h" + +#if defined(HAVE_STD_ATOMIC) +#include <stdatomic.h> +#endif + #ifdef __cplusplus extern "C" { #endif @@ -20,6 +23,76 @@ extern "C" { * Beware, the implementations here are deep magic. */ +#if defined(HAVE_STD_ATOMIC) + +typedef enum _Py_memory_order { + _Py_memory_order_relaxed = memory_order_relaxed, + _Py_memory_order_acquire = memory_order_acquire, + _Py_memory_order_release = memory_order_release, + _Py_memory_order_acq_rel = memory_order_acq_rel, + _Py_memory_order_seq_cst = memory_order_seq_cst +} _Py_memory_order; + +typedef struct _Py_atomic_address { + _Atomic void *_value; +} _Py_atomic_address; + +typedef struct _Py_atomic_int { + atomic_int _value; +} _Py_atomic_int; + +#define _Py_atomic_signal_fence(/*memory_order*/ ORDER) \ + atomic_signal_fence(ORDER) + +#define _Py_atomic_thread_fence(/*memory_order*/ ORDER) \ + atomic_thread_fence(ORDER) + +#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \ + atomic_store_explicit(&(ATOMIC_VAL)->_value, NEW_VAL, ORDER) + +#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \ + atomic_load_explicit(&(ATOMIC_VAL)->_value, ORDER) + +/* Use builtin atomic operations in GCC >= 4.7 */ +#elif defined(HAVE_BUILTIN_ATOMIC) + +typedef enum _Py_memory_order { + _Py_memory_order_relaxed = __ATOMIC_RELAXED, + _Py_memory_order_acquire = __ATOMIC_ACQUIRE, + _Py_memory_order_release = __ATOMIC_RELEASE, + _Py_memory_order_acq_rel = __ATOMIC_ACQ_REL, + _Py_memory_order_seq_cst = __ATOMIC_SEQ_CST +} _Py_memory_order; + +typedef struct _Py_atomic_address { + void *_value; +} _Py_atomic_address; + +typedef struct _Py_atomic_int { + int _value; +} _Py_atomic_int; + +#define _Py_atomic_signal_fence(/*memory_order*/ ORDER) \ + __atomic_signal_fence(ORDER) + +#define _Py_atomic_thread_fence(/*memory_order*/ ORDER) \ + __atomic_thread_fence(ORDER) + +#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \ + (assert((ORDER) == __ATOMIC_RELAXED \ + || (ORDER) == __ATOMIC_SEQ_CST \ + || (ORDER) == __ATOMIC_RELEASE), \ + __atomic_store_n(&(ATOMIC_VAL)->_value, NEW_VAL, ORDER)) + +#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \ + (assert((ORDER) == __ATOMIC_RELAXED \ + || (ORDER) == __ATOMIC_SEQ_CST \ + || (ORDER) == __ATOMIC_ACQUIRE \ + || (ORDER) == __ATOMIC_CONSUME), \ + __atomic_load_n(&(ATOMIC_VAL)->_value, ORDER)) + +#else + typedef enum _Py_memory_order { _Py_memory_order_relaxed, _Py_memory_order_acquire, @@ -162,6 +235,7 @@ _Py_ANNOTATE_MEMORY_ORDER(const volatile void *address, _Py_memory_order order) ((ATOMIC_VAL)->_value) #endif /* !gcc x86 */ +#endif /* Standardized shortcuts. */ #define _Py_atomic_store(ATOMIC_VAL, NEW_VAL) \ diff --git a/Include/pydebug.h b/Include/pydebug.h index 8fe98183f9ef..19bec2bd81bc 100644 --- a/Include/pydebug.h +++ b/Include/pydebug.h @@ -5,6 +5,8 @@ extern "C" { #endif +/* These global variable are defined in pylifecycle.c */ +/* XXX (ncoghlan): move these declarations to pylifecycle.h? */ PyAPI_DATA(int) Py_DebugFlag; PyAPI_DATA(int) Py_VerboseFlag; PyAPI_DATA(int) Py_QuietFlag; diff --git a/Include/pyerrors.h b/Include/pyerrors.h index 6a8e0e810e36..8a7e4f419ceb 100644 --- a/Include/pyerrors.h +++ b/Include/pyerrors.h @@ -53,6 +53,7 @@ typedef struct { PyObject *myerrno; PyObject *strerror; PyObject *filename; + PyObject *filename2; #ifdef MS_WINDOWS PyObject *winerror; #endif @@ -75,7 +76,9 @@ typedef PyOSErrorObject PyWindowsErrorObject; PyAPI_FUNC(void) PyErr_SetNone(PyObject *); PyAPI_FUNC(void) PyErr_SetObject(PyObject *, PyObject *); +#ifndef Py_LIMITED_API PyAPI_FUNC(void) _PyErr_SetKeyError(PyObject *); +#endif PyAPI_FUNC(void) PyErr_SetString( PyObject *exception, const char *string /* decoded from utf-8 */ @@ -96,6 +99,7 @@ PyAPI_FUNC(void) PyErr_SetExcInfo(PyObject *, PyObject *, PyObject *); #define _Py_NO_RETURN #endif +/* Defined in Python/pylifecycle.c */ PyAPI_FUNC(void) Py_FatalError(const char *message) _Py_NO_RETURN; #if defined(Py_DEBUG) || defined(Py_LIMITED_API) @@ -120,7 +124,9 @@ PyAPI_FUNC(void) PyException_SetCause(PyObject *, PyObject *); /* Context manipulation (PEP 3134) */ PyAPI_FUNC(PyObject *) PyException_GetContext(PyObject *); PyAPI_FUNC(void) PyException_SetContext(PyObject *, PyObject *); - +#ifndef Py_LIMITED_API +PyAPI_FUNC(void) _PyErr_ChainExceptions(PyObject *, PyObject *, PyObject *); +#endif /* */ @@ -199,9 +205,6 @@ PyAPI_DATA(PyObject *) PyExc_IOError; #ifdef MS_WINDOWS PyAPI_DATA(PyObject *) PyExc_WindowsError; #endif -#ifdef __VMS -PyAPI_DATA(PyObject *) PyExc_VMSError; -#endif PyAPI_DATA(PyObject *) PyExc_RecursionErrorInst; @@ -226,6 +229,8 @@ PyAPI_FUNC(PyObject *) PyErr_NoMemory(void); PyAPI_FUNC(PyObject *) PyErr_SetFromErrno(PyObject *); PyAPI_FUNC(PyObject *) PyErr_SetFromErrnoWithFilenameObject( PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) PyErr_SetFromErrnoWithFilenameObjects( + PyObject *, PyObject *, PyObject *); PyAPI_FUNC(PyObject *) PyErr_SetFromErrnoWithFilename( PyObject *exc, const char *filename /* decoded from the filesystem encoding */ @@ -240,6 +245,12 @@ PyAPI_FUNC(PyObject *) PyErr_Format( const char *format, /* ASCII-encoded string */ ... ); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 +PyAPI_FUNC(PyObject *) PyErr_FormatV( + PyObject *exception, + const char *format, + va_list vargs); +#endif #ifdef MS_WINDOWS PyAPI_FUNC(PyObject *) PyErr_SetFromWindowsErrWithFilename( @@ -254,6 +265,8 @@ PyAPI_FUNC(PyObject *) PyErr_SetFromWindowsErrWithUnicodeFilename( PyAPI_FUNC(PyObject *) PyErr_SetFromWindowsErr(int); PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErrWithFilenameObject( PyObject *,int, PyObject *); +PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErrWithFilenameObjects( + PyObject *,int, PyObject *, PyObject *); PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErrWithFilename( PyObject *exc, int ierr, @@ -324,16 +337,20 @@ PyAPI_FUNC(void) PyErr_SyntaxLocationEx( const char *filename, /* decoded from the filesystem encoding */ int lineno, int col_offset); +#ifndef Py_LIMITED_API PyAPI_FUNC(void) PyErr_SyntaxLocationObject( PyObject *filename, int lineno, int col_offset); +#endif PyAPI_FUNC(PyObject *) PyErr_ProgramText( const char *filename, /* decoded from the filesystem encoding */ int lineno); +#ifndef Py_LIMITED_API PyAPI_FUNC(PyObject *) PyErr_ProgramTextObject( PyObject *filename, int lineno); +#endif /* The following functions are used to create and modify unicode exceptions from C */ diff --git a/Include/pyhash.h b/Include/pyhash.h index 83c928137baf..a7ca93758c35 100644 --- a/Include/pyhash.h +++ b/Include/pyhash.h @@ -50,6 +50,7 @@ PyAPI_FUNC(Py_hash_t) _Py_HashBytes(const void*, Py_ssize_t); * (*) The siphash member may not be available on 32 bit platforms without * an unsigned int64 data type. */ +#ifndef Py_LIMITED_API typedef union { /* ensure 24 bytes */ unsigned char uc[24]; @@ -76,6 +77,7 @@ typedef union { } expat; } _Py_HashSecret_t; PyAPI_DATA(_Py_HashSecret_t) _Py_HashSecret; +#endif #ifdef Py_DEBUG PyAPI_DATA(int) _Py_HashSecret_Initialized; diff --git a/Include/pylifecycle.h b/Include/pylifecycle.h new file mode 100644 index 000000000000..ccdebe26a488 --- /dev/null +++ b/Include/pylifecycle.h @@ -0,0 +1,124 @@ + +/* Interfaces to configure, query, create & destroy the Python runtime */ + +#ifndef Py_PYLIFECYCLE_H +#define Py_PYLIFECYCLE_H +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_FUNC(void) Py_SetProgramName(wchar_t *); +PyAPI_FUNC(wchar_t *) Py_GetProgramName(void); + +PyAPI_FUNC(void) Py_SetPythonHome(wchar_t *); +PyAPI_FUNC(wchar_t *) Py_GetPythonHome(void); + +#ifndef Py_LIMITED_API +/* Only used by applications that embed the interpreter and need to + * override the standard encoding determination mechanism + */ +PyAPI_FUNC(int) Py_SetStandardStreamEncoding(const char *encoding, + const char *errors); +#endif + +PyAPI_FUNC(void) Py_Initialize(void); +PyAPI_FUNC(void) Py_InitializeEx(int); +#ifndef Py_LIMITED_API +PyAPI_FUNC(void) _Py_InitializeEx_Private(int, int); +#endif +PyAPI_FUNC(void) Py_Finalize(void); +PyAPI_FUNC(int) Py_IsInitialized(void); +PyAPI_FUNC(PyThreadState *) Py_NewInterpreter(void); +PyAPI_FUNC(void) Py_EndInterpreter(PyThreadState *); + + +/* Py_PyAtExit is for the atexit module, Py_AtExit is for low-level + * exit functions. + */ +#ifndef Py_LIMITED_API +PyAPI_FUNC(void) _Py_PyAtExit(void (*func)(void)); +#endif +PyAPI_FUNC(int) Py_AtExit(void (*func)(void)); + +PyAPI_FUNC(void) Py_Exit(int); + +/* Restore signals that the interpreter has called SIG_IGN on to SIG_DFL. */ +#ifndef Py_LIMITED_API +PyAPI_FUNC(void) _Py_RestoreSignals(void); + +PyAPI_FUNC(int) Py_FdIsInteractive(FILE *, const char *); +#endif + +/* Bootstrap __main__ (defined in Modules/main.c) */ +PyAPI_FUNC(int) Py_Main(int argc, wchar_t **argv); + +/* In getpath.c */ +PyAPI_FUNC(wchar_t *) Py_GetProgramFullPath(void); +PyAPI_FUNC(wchar_t *) Py_GetPrefix(void); +PyAPI_FUNC(wchar_t *) Py_GetExecPrefix(void); +PyAPI_FUNC(wchar_t *) Py_GetPath(void); +PyAPI_FUNC(void) Py_SetPath(const wchar_t *); +#ifdef MS_WINDOWS +int _Py_CheckPython3(); +#endif + +/* In their own files */ +PyAPI_FUNC(const char *) Py_GetVersion(void); +PyAPI_FUNC(const char *) Py_GetPlatform(void); +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); +#endif + +/* Internal -- various one-time initializations */ +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) _PyBuiltin_Init(void); +PyAPI_FUNC(PyObject *) _PySys_Init(void); +PyAPI_FUNC(void) _PyImport_Init(void); +PyAPI_FUNC(void) _PyExc_Init(PyObject * bltinmod); +PyAPI_FUNC(void) _PyImportHooks_Init(void); +PyAPI_FUNC(int) _PyFrame_Init(void); +PyAPI_FUNC(int) _PyFloat_Init(void); +PyAPI_FUNC(int) PyByteArray_Init(void); +PyAPI_FUNC(void) _PyRandom_Init(void); +#endif + +/* Various internal finalizers */ +#ifndef Py_LIMITED_API +PyAPI_FUNC(void) _PyExc_Fini(void); +PyAPI_FUNC(void) _PyImport_Fini(void); +PyAPI_FUNC(void) PyMethod_Fini(void); +PyAPI_FUNC(void) PyFrame_Fini(void); +PyAPI_FUNC(void) PyCFunction_Fini(void); +PyAPI_FUNC(void) PyDict_Fini(void); +PyAPI_FUNC(void) PyTuple_Fini(void); +PyAPI_FUNC(void) PyList_Fini(void); +PyAPI_FUNC(void) PySet_Fini(void); +PyAPI_FUNC(void) PyBytes_Fini(void); +PyAPI_FUNC(void) PyByteArray_Fini(void); +PyAPI_FUNC(void) PyFloat_Fini(void); +PyAPI_FUNC(void) PyOS_FiniInterrupts(void); +PyAPI_FUNC(void) _PyGC_DumpShutdownStats(void); +PyAPI_FUNC(void) _PyGC_Fini(void); +PyAPI_FUNC(void) PySlice_Fini(void); +PyAPI_FUNC(void) _PyType_Fini(void); +PyAPI_FUNC(void) _PyRandom_Fini(void); + +PyAPI_DATA(PyThreadState *) _Py_Finalizing; +#endif + +/* Signals */ +typedef void (*PyOS_sighandler_t)(int); +PyAPI_FUNC(PyOS_sighandler_t) PyOS_getsig(int); +PyAPI_FUNC(PyOS_sighandler_t) PyOS_setsig(int, PyOS_sighandler_t); + +/* Random */ +PyAPI_FUNC(int) _PyOS_URandom (void *buffer, Py_ssize_t size); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_PYLIFECYCLE_H */ diff --git a/Include/pymacro.h b/Include/pymacro.h index 793f67dce9c6..3f6f5dce6128 100644 --- a/Include/pymacro.h +++ b/Include/pymacro.h @@ -1,13 +1,26 @@ #ifndef Py_PYMACRO_H #define Py_PYMACRO_H +/* Minimum value between x and y */ #define Py_MIN(x, y) (((x) > (y)) ? (y) : (x)) + +/* Maximum value between x and y */ #define Py_MAX(x, y) (((x) > (y)) ? (x) : (y)) +/* Absolute value of the number x */ +#define Py_ABS(x) ((x) < 0 ? -(x) : (x)) + +#define _Py_XSTRINGIFY(x) #x + +/* Convert the argument to a string. For example, Py_STRINGIFY(123) is replaced + with "123" by the preprocessor. Defines are also replaced by their value. + For example Py_STRINGIFY(__LINE__) is replaced by the line number, not + by "__LINE__". */ +#define Py_STRINGIFY(x) _Py_XSTRINGIFY(x) + /* Argument must be a char or an int in [-128, 127] or [0, 255]. */ #define Py_CHARMASK(c) ((unsigned char)((c) & 0xff)) - /* Assert a build-time dependency, as an expression. Your compile will fail if the condition isn't true, or can't be evaluated @@ -69,4 +82,10 @@ /* Check if pointer "p" is aligned to "a"-bytes boundary. */ #define _Py_IS_ALIGNED(p, a) (!((Py_uintptr_t)(p) & (Py_uintptr_t)((a) - 1))) +#ifdef __GNUC__ +#define Py_UNUSED(name) _unused_ ## name __attribute__((unused)) +#else +#define Py_UNUSED(name) _unused_ ## name +#endif + #endif /* Py_PYMACRO_H */ diff --git a/Include/pymem.h b/Include/pymem.h index 83f1537f3f55..043db64deb89 100644 --- a/Include/pymem.h +++ b/Include/pymem.h @@ -11,9 +11,12 @@ extern "C" { #endif +#ifndef Py_LIMITED_API PyAPI_FUNC(void *) PyMem_RawMalloc(size_t size); +PyAPI_FUNC(void *) PyMem_RawCalloc(size_t nelem, size_t elsize); PyAPI_FUNC(void *) PyMem_RawRealloc(void *ptr, size_t new_size); PyAPI_FUNC(void) PyMem_RawFree(void *ptr); +#endif /* BEWARE: @@ -55,11 +58,14 @@ PyAPI_FUNC(void) PyMem_RawFree(void *ptr); */ PyAPI_FUNC(void *) PyMem_Malloc(size_t size); +PyAPI_FUNC(void *) PyMem_Calloc(size_t nelem, size_t elsize); PyAPI_FUNC(void *) PyMem_Realloc(void *ptr, size_t new_size); PyAPI_FUNC(void) PyMem_Free(void *ptr); +#ifndef Py_LIMITED_API PyAPI_FUNC(char *) _PyMem_RawStrdup(const char *str); PyAPI_FUNC(char *) _PyMem_Strdup(const char *str); +#endif /* Macros. */ @@ -122,22 +128,25 @@ typedef enum { } PyMemAllocatorDomain; typedef struct { - /* user context passed as the first argument to the 3 functions */ + /* user context passed as the first argument to the 4 functions */ void *ctx; /* allocate a memory block */ void* (*malloc) (void *ctx, size_t size); + /* allocate a memory block initialized by zeros */ + void* (*calloc) (void *ctx, size_t nelem, size_t elsize); + /* allocate or resize a memory block */ void* (*realloc) (void *ctx, void *ptr, size_t new_size); /* release a memory block */ void (*free) (void *ctx, void *ptr); -} PyMemAllocator; +} PyMemAllocatorEx; /* Get the memory block allocator of the specified domain. */ PyAPI_FUNC(void) PyMem_GetAllocator(PyMemAllocatorDomain domain, - PyMemAllocator *allocator); + PyMemAllocatorEx *allocator); /* Set the memory block allocator of the specified domain. @@ -151,7 +160,7 @@ PyAPI_FUNC(void) PyMem_GetAllocator(PyMemAllocatorDomain domain, PyMem_SetupDebugHooks() function must be called to reinstall the debug hooks on top on the new allocator. */ PyAPI_FUNC(void) PyMem_SetAllocator(PyMemAllocatorDomain domain, - PyMemAllocator *allocator); + PyMemAllocatorEx *allocator); /* Setup hooks to detect bugs in the following Python memory allocator functions: diff --git a/Include/pyport.h b/Include/pyport.h index c706213c87c5..69deb9f8bf70 100644 --- a/Include/pyport.h +++ b/Include/pyport.h @@ -588,6 +588,25 @@ extern "C" { } while (0) #endif +#ifdef HAVE_GCC_ASM_FOR_MC68881 +#define HAVE_PY_SET_53BIT_PRECISION 1 +#define _Py_SET_53BIT_PRECISION_HEADER \ + unsigned int old_fpcr, new_fpcr +#define _Py_SET_53BIT_PRECISION_START \ + do { \ + __asm__ ("fmove.l %%fpcr,%0" : "=g" (old_fpcr)); \ + /* Set double precision / round to nearest. */ \ + new_fpcr = (old_fpcr & ~0xf0) | 0x80; \ + if (new_fpcr != old_fpcr) \ + __asm__ volatile ("fmove.l %0,%%fpcr" : : "g" (new_fpcr)); \ + } while (0) +#define _Py_SET_53BIT_PRECISION_END \ + do { \ + if (new_fpcr != old_fpcr) \ + __asm__ volatile ("fmove.l %0,%%fpcr" : : "g" (old_fpcr)); \ + } while (0) +#endif + /* default definitions are empty */ #ifndef HAVE_PY_SET_53BIT_PRECISION #define _Py_SET_53BIT_PRECISION_HEADER diff --git a/Include/pystate.h b/Include/pystate.h index 06af80844437..4992c22684fe 100644 --- a/Include/pystate.h +++ b/Include/pystate.h @@ -33,7 +33,6 @@ typedef struct _is { int codecs_initialized; int fscodec_initialized; - #ifdef HAVE_DLOPEN int dlopenflags; #endif @@ -41,6 +40,7 @@ typedef struct _is { int tscdump; #endif + PyObject *builtins_copy; } PyInterpreterState; #endif @@ -236,7 +236,9 @@ PyAPI_FUNC(PyThreadState *) PyGILState_GetThisThreadState(void); /* Helper/diagnostic function - return 1 if the current thread * currently holds the GIL, 0 otherwise */ +#ifndef Py_LIMITED_API PyAPI_FUNC(int) PyGILState_Check(void); +#endif #endif /* #ifdef WITH_THREAD */ diff --git a/Include/pythonrun.h b/Include/pythonrun.h index c36494768517..1d9b71beaa97 100644 --- a/Include/pythonrun.h +++ b/Include/pythonrun.h @@ -22,30 +22,6 @@ typedef struct { } PyCompilerFlags; #endif -PyAPI_FUNC(void) Py_SetProgramName(wchar_t *); -PyAPI_FUNC(wchar_t *) Py_GetProgramName(void); - -PyAPI_FUNC(void) Py_SetPythonHome(wchar_t *); -PyAPI_FUNC(wchar_t *) Py_GetPythonHome(void); - -#ifndef Py_LIMITED_API -/* Only used by applications that embed the interpreter and need to - * override the standard encoding determination mechanism - */ -PyAPI_FUNC(int) Py_SetStandardStreamEncoding(const char *encoding, - const char *errors); -#endif - -PyAPI_FUNC(void) Py_Initialize(void); -PyAPI_FUNC(void) Py_InitializeEx(int); -#ifndef Py_LIMITED_API -PyAPI_FUNC(void) _Py_InitializeEx_Private(int, int); -#endif -PyAPI_FUNC(void) Py_Finalize(void); -PyAPI_FUNC(int) Py_IsInitialized(void); -PyAPI_FUNC(PyThreadState *) Py_NewInterpreter(void); -PyAPI_FUNC(void) Py_EndInterpreter(PyThreadState *); - #ifndef Py_LIMITED_API PyAPI_FUNC(int) PyRun_SimpleStringFlags(const char *, PyCompilerFlags *); PyAPI_FUNC(int) PyRun_AnyFileFlags(FILE *, const char *, PyCompilerFlags *); @@ -155,35 +131,17 @@ PyAPI_FUNC(struct symtable *) Py_SymtableString( const char *str, const char *filename, /* decoded from the filesystem encoding */ int start); +#ifndef Py_LIMITED_API PyAPI_FUNC(struct symtable *) Py_SymtableStringObject( const char *str, PyObject *filename, int start); +#endif PyAPI_FUNC(void) PyErr_Print(void); PyAPI_FUNC(void) PyErr_PrintEx(int); PyAPI_FUNC(void) PyErr_Display(PyObject *, PyObject *, PyObject *); -/* Py_PyAtExit is for the atexit module, Py_AtExit is for low-level - * exit functions. - */ -#ifndef Py_LIMITED_API -PyAPI_FUNC(void) _Py_PyAtExit(void (*func)(void)); -#endif -PyAPI_FUNC(int) Py_AtExit(void (*func)(void)); - -PyAPI_FUNC(void) Py_Exit(int); - -/* Restore signals that the interpreter has called SIG_IGN on to SIG_DFL. */ -#ifndef Py_LIMITED_API -PyAPI_FUNC(void) _Py_RestoreSignals(void); - -PyAPI_FUNC(int) Py_FdIsInteractive(FILE *, const char *); -#endif - -/* Bootstrap */ -PyAPI_FUNC(int) Py_Main(int argc, wchar_t **argv); - #ifndef Py_LIMITED_API /* Use macros for a bunch of old variants */ #define PyRun_String(str, s, g, l) PyRun_StringFlags(str, s, g, l, NULL) @@ -205,64 +163,6 @@ PyAPI_FUNC(int) Py_Main(int argc, wchar_t **argv); PyRun_FileExFlags(fp, p, s, g, l, 0, flags) #endif -/* In getpath.c */ -PyAPI_FUNC(wchar_t *) Py_GetProgramFullPath(void); -PyAPI_FUNC(wchar_t *) Py_GetPrefix(void); -PyAPI_FUNC(wchar_t *) Py_GetExecPrefix(void); -PyAPI_FUNC(wchar_t *) Py_GetPath(void); -PyAPI_FUNC(void) Py_SetPath(const wchar_t *); -#ifdef MS_WINDOWS -int _Py_CheckPython3(); -#endif - -/* In their own files */ -PyAPI_FUNC(const char *) Py_GetVersion(void); -PyAPI_FUNC(const char *) Py_GetPlatform(void); -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); -#endif - -/* Internal -- various one-time initializations */ -#ifndef Py_LIMITED_API -PyAPI_FUNC(PyObject *) _PyBuiltin_Init(void); -PyAPI_FUNC(PyObject *) _PySys_Init(void); -PyAPI_FUNC(void) _PyImport_Init(void); -PyAPI_FUNC(void) _PyExc_Init(PyObject * bltinmod); -PyAPI_FUNC(void) _PyImportHooks_Init(void); -PyAPI_FUNC(int) _PyFrame_Init(void); -PyAPI_FUNC(int) _PyFloat_Init(void); -PyAPI_FUNC(int) PyByteArray_Init(void); -PyAPI_FUNC(void) _PyRandom_Init(void); -#endif - -/* Various internal finalizers */ -#ifndef Py_LIMITED_API -PyAPI_FUNC(void) _PyExc_Fini(void); -PyAPI_FUNC(void) _PyImport_Fini(void); -PyAPI_FUNC(void) PyMethod_Fini(void); -PyAPI_FUNC(void) PyFrame_Fini(void); -PyAPI_FUNC(void) PyCFunction_Fini(void); -PyAPI_FUNC(void) PyDict_Fini(void); -PyAPI_FUNC(void) PyTuple_Fini(void); -PyAPI_FUNC(void) PyList_Fini(void); -PyAPI_FUNC(void) PySet_Fini(void); -PyAPI_FUNC(void) PyBytes_Fini(void); -PyAPI_FUNC(void) PyByteArray_Fini(void); -PyAPI_FUNC(void) PyFloat_Fini(void); -PyAPI_FUNC(void) PyOS_FiniInterrupts(void); -PyAPI_FUNC(void) _PyGC_DumpShutdownStats(void); -PyAPI_FUNC(void) _PyGC_Fini(void); -PyAPI_FUNC(void) PySlice_Fini(void); -PyAPI_FUNC(void) _PyType_Fini(void); -PyAPI_FUNC(void) _PyRandom_Fini(void); - -PyAPI_DATA(PyThreadState *) _Py_Finalizing; -#endif - /* Stuff with no proper home (yet) */ #ifndef Py_LIMITED_API PyAPI_FUNC(char *) PyOS_Readline(FILE *, FILE *, const char *); @@ -288,14 +188,6 @@ PyAPI_DATA(PyThreadState*) _PyOS_ReadlineTState; PyAPI_FUNC(int) PyOS_CheckStack(void); #endif -/* Signals */ -typedef void (*PyOS_sighandler_t)(int); -PyAPI_FUNC(PyOS_sighandler_t) PyOS_getsig(int); -PyAPI_FUNC(PyOS_sighandler_t) PyOS_setsig(int, PyOS_sighandler_t); - -/* Random */ -PyAPI_FUNC(int) _PyOS_URandom (void *buffer, Py_ssize_t size); - #ifdef __cplusplus } #endif diff --git a/Include/pytime.h b/Include/pytime.h index 52902f5e3ac2..7a14456d3f59 100644 --- a/Include/pytime.h +++ b/Include/pytime.h @@ -37,7 +37,7 @@ PyAPI_FUNC(void) _PyTime_gettimeofday(_PyTime_timeval *tp); /* Similar to _PyTime_gettimeofday() but retrieve also information on the * clock used to get the current time. */ -PyAPI_FUNC(void) _PyTime_gettimeofday_info( +PyAPI_FUNC(int) _PyTime_gettimeofday_info( _PyTime_timeval *tp, _Py_clock_info_t *info); @@ -52,11 +52,18 @@ do { \ ((tv_end.tv_sec - tv_start.tv_sec) + \ (tv_end.tv_usec - tv_start.tv_usec) * 0.000001) -#ifndef Py_LIMITED_API +typedef enum { + /* Round towards zero. */ + _PyTime_ROUND_DOWN=0, + /* Round away from zero. */ + _PyTime_ROUND_UP +} _PyTime_round_t; + /* Convert a number of seconds, int or float, to time_t. */ PyAPI_FUNC(int) _PyTime_ObjectToTime_t( PyObject *obj, - time_t *sec); + time_t *sec, + _PyTime_round_t); /* Convert a time_t to a PyLong. */ PyAPI_FUNC(PyObject *) _PyLong_FromTime_t( @@ -72,7 +79,8 @@ PyAPI_FUNC(time_t) _PyLong_AsTime_t( PyAPI_FUNC(int) _PyTime_ObjectToTimeval( PyObject *obj, time_t *sec, - long *usec); + long *usec, + _PyTime_round_t); /* Convert a number of seconds, int or float, to a timespec structure. nsec is in the range [0; 999999999] and rounded towards zero. @@ -80,11 +88,30 @@ PyAPI_FUNC(int) _PyTime_ObjectToTimeval( PyAPI_FUNC(int) _PyTime_ObjectToTimespec( PyObject *obj, time_t *sec, - long *nsec); -#endif + long *nsec, + _PyTime_round_t); + +/* Get the time of a monotonic clock, i.e. a clock that cannot go backwards. + The clock is not affected by system clock updates. The reference point of + the returned value is undefined, so that only the difference between the + results of consecutive calls is valid. + + The function never fails. _PyTime_Init() ensures that a monotonic clock + is available and works. */ +PyAPI_FUNC(void) _PyTime_monotonic( + _PyTime_timeval *tp); + +/* Similar to _PyTime_monotonic(), fill also info (if set) with information of + the function used to get the time. + + Return 0 on success, raise an exception and return -1 on error. */ +PyAPI_FUNC(int) _PyTime_monotonic_info( + _PyTime_timeval *tp, + _Py_clock_info_t *info); -/* Dummy to force linking. */ -PyAPI_FUNC(void) _PyTime_Init(void); +/* Initialize time. + Return 0 on success, raise an exception and return -1 on error. */ +PyAPI_FUNC(int) _PyTime_Init(void); #ifdef __cplusplus } diff --git a/Include/setobject.h b/Include/setobject.h index ae3f556365dd..f17bc1b03545 100644 --- a/Include/setobject.h +++ b/Include/setobject.h @@ -6,38 +6,43 @@ extern "C" { #endif +#ifndef Py_LIMITED_API -/* -There are three kinds of slots in the table: +/* There are three kinds of entries in the table: 1. Unused: key == NULL 2. Active: key != NULL and key != dummy 3. Dummy: key == dummy -Note: .pop() abuses the hash field of an Unused or Dummy slot to -hold a search finger. The hash field of Unused or Dummy slots has -no meaning otherwise. +The hash field of Unused slots have no meaning. +The hash field of Dummny slots are set to -1 +meaning that dummy entries can be detected by +either entry->key==dummy or by entry->hash==-1. */ -#ifndef Py_LIMITED_API + #define PySet_MINSIZE 8 typedef struct { - /* Cached hash code of the key. */ PyObject *key; - Py_hash_t hash; + Py_hash_t hash; /* Cached hash code of the key */ } setentry; +/* The SetObject data structure is shared by set and frozenset objects. + +Invariant for sets: + - hash is -1 + +Invariants for frozensets: + - data is immutable. + - hash is the hash of the frozenset or -1 if not computed yet. -/* -This data structure is shared by set and frozenset objects. */ -typedef struct _setobject PySetObject; -struct _setobject { +typedef struct { PyObject_HEAD - Py_ssize_t fill; /* # Active + # Dummy */ - Py_ssize_t used; /* # Active */ + Py_ssize_t fill; /* Number active and dummy entries*/ + Py_ssize_t used; /* Number active entries */ /* The table contains mask + 1 slots, and that's a power of 2. * We store the mask instead of the size because the mask is more @@ -45,33 +50,42 @@ struct _setobject { */ Py_ssize_t mask; - /* table points to smalltable for small tables, else to - * additional malloc'ed memory. table is never NULL! This rule - * saves repeated runtime null-tests. + /* The table points to a fixed-size smalltable for small tables + * or to additional malloc'ed memory for bigger tables. + * The table pointer is never NULL which saves us from repeated + * runtime null-tests. */ setentry *table; - setentry *(*lookup)(PySetObject *so, PyObject *key, Py_hash_t hash); - Py_hash_t hash; /* only used by frozenset objects */ - setentry smalltable[PySet_MINSIZE]; + Py_hash_t hash; /* Only used by frozenset objects */ + Py_ssize_t finger; /* Search finger for pop() */ + setentry smalltable[PySet_MINSIZE]; PyObject *weakreflist; /* List of weak references */ -}; -#endif /* Py_LIMITED_API */ +} PySetObject; + +#define PySet_GET_SIZE(so) (((PySetObject *)(so))->used) + +PyAPI_DATA(PyObject *) _PySet_Dummy; + +PyAPI_FUNC(int) _PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash); +PyAPI_FUNC(int) _PySet_Update(PyObject *set, PyObject *iterable); +PyAPI_FUNC(int) PySet_ClearFreeList(void); + +#endif /* Section excluded by Py_LIMITED_API */ PyAPI_DATA(PyTypeObject) PySet_Type; PyAPI_DATA(PyTypeObject) PyFrozenSet_Type; PyAPI_DATA(PyTypeObject) PySetIter_Type; -#ifndef Py_LIMITED_API -PyAPI_DATA(PyObject *) _PySet_Dummy; -#endif +PyAPI_FUNC(PyObject *) PySet_New(PyObject *); +PyAPI_FUNC(PyObject *) PyFrozenSet_New(PyObject *); -/* Invariants for frozensets: - * data is immutable. - * hash is the hash of the frozenset or -1 if not computed yet. - * Invariants for sets: - * hash is -1 - */ +PyAPI_FUNC(int) PySet_Add(PyObject *set, PyObject *key); +PyAPI_FUNC(int) PySet_Clear(PyObject *set); +PyAPI_FUNC(int) PySet_Contains(PyObject *anyset, PyObject *key); +PyAPI_FUNC(int) PySet_Discard(PyObject *set, PyObject *key); +PyAPI_FUNC(PyObject *) PySet_Pop(PyObject *set); +PyAPI_FUNC(Py_ssize_t) PySet_Size(PyObject *anyset); #define PyFrozenSet_CheckExact(ob) (Py_TYPE(ob) == &PyFrozenSet_Type) #define PyAnySet_CheckExact(ob) \ @@ -87,26 +101,6 @@ PyAPI_DATA(PyObject *) _PySet_Dummy; (Py_TYPE(ob) == &PyFrozenSet_Type || \ PyType_IsSubtype(Py_TYPE(ob), &PyFrozenSet_Type)) -PyAPI_FUNC(PyObject *) PySet_New(PyObject *); -PyAPI_FUNC(PyObject *) PyFrozenSet_New(PyObject *); -PyAPI_FUNC(Py_ssize_t) PySet_Size(PyObject *anyset); -#ifndef Py_LIMITED_API -#define PySet_GET_SIZE(so) (((PySetObject *)(so))->used) -#endif -PyAPI_FUNC(int) PySet_Clear(PyObject *set); -PyAPI_FUNC(int) PySet_Contains(PyObject *anyset, PyObject *key); -PyAPI_FUNC(int) PySet_Discard(PyObject *set, PyObject *key); -PyAPI_FUNC(int) PySet_Add(PyObject *set, PyObject *key); -#ifndef Py_LIMITED_API -PyAPI_FUNC(int) _PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash); -#endif -PyAPI_FUNC(PyObject *) PySet_Pop(PyObject *set); -#ifndef Py_LIMITED_API -PyAPI_FUNC(int) _PySet_Update(PyObject *set, PyObject *iterable); - -PyAPI_FUNC(int) PySet_ClearFreeList(void); -#endif - #ifdef __cplusplus } #endif diff --git a/Include/sysmodule.h b/Include/sysmodule.h index 925c2a34f476..cde10ac4cafa 100644 --- a/Include/sysmodule.h +++ b/Include/sysmodule.h @@ -8,7 +8,9 @@ extern "C" { #endif PyAPI_FUNC(PyObject *) PySys_GetObject(const char *); +#ifndef Py_LIMITED_API PyAPI_FUNC(PyObject *) _PySys_GetObjectId(_Py_Identifier *key); +#endif PyAPI_FUNC(int) PySys_SetObject(const char *, PyObject *); PyAPI_FUNC(int) _PySys_SetObjectId(_Py_Identifier *key, PyObject *); @@ -31,6 +33,10 @@ PyAPI_FUNC(int) PySys_HasWarnOptions(void); PyAPI_FUNC(void) PySys_AddXOption(const wchar_t *); PyAPI_FUNC(PyObject *) PySys_GetXOptions(void); +#ifndef Py_LIMITED_API +PyAPI_FUNC(size_t) _PySys_GetSizeOf(PyObject *); +#endif + #ifdef __cplusplus } #endif diff --git a/Include/token.h b/Include/token.h index 905022b8d2c7..2b213eeb32fa 100644 --- a/Include/token.h +++ b/Include/token.h @@ -58,13 +58,14 @@ extern "C" { #define DOUBLESTAREQUAL 46 #define DOUBLESLASH 47 #define DOUBLESLASHEQUAL 48 -#define AT 49 -#define RARROW 50 -#define ELLIPSIS 51 +#define AT 49 +#define ATEQUAL 50 +#define RARROW 51 +#define ELLIPSIS 52 /* Don't forget to update the table _PyParser_TokenNames in tokenizer.c! */ -#define OP 52 -#define ERRORTOKEN 53 -#define N_TOKENS 54 +#define OP 53 +#define ERRORTOKEN 54 +#define N_TOKENS 55 /* Special definitions for cooperation with parser */ diff --git a/Include/traceback.h b/Include/traceback.h index 77347077e91a..12d467a08df1 100644 --- a/Include/traceback.h +++ b/Include/traceback.h @@ -24,6 +24,7 @@ PyAPI_FUNC(int) PyTraceBack_Here(struct _frame *); PyAPI_FUNC(int) PyTraceBack_Print(PyObject *, PyObject *); #ifndef Py_LIMITED_API PyAPI_FUNC(int) _Py_DisplaySourceLine(PyObject *, PyObject *, int, int); +PyAPI_FUNC(void) _PyTraceback_Add(char *, char *, int); #endif /* Reveal traceback type so we can typecheck traceback objects */ diff --git a/Include/typeslots.h b/Include/typeslots.h index ad3cdfb19ad4..da2e87cb719e 100644 --- a/Include/typeslots.h +++ b/Include/typeslots.h @@ -74,3 +74,5 @@ #define Py_tp_members 72 #define Py_tp_getset 73 #define Py_tp_free 74 +#define Py_nb_matrix_multiply 75 +#define Py_nb_inplace_matrix_multiply 76 diff --git a/Include/unicodeobject.h b/Include/unicodeobject.h index b6d331bb8d3d..814d7c0cf639 100644 --- a/Include/unicodeobject.h +++ b/Include/unicodeobject.h @@ -343,6 +343,9 @@ typedef struct { the data pointer is filled out. The bit is redundant, and helps to minimize the test in PyUnicode_IS_READY(). */ unsigned int ready:1; + /* Padding to ensure that PyUnicode_DATA() is always aligned to + 4 bytes (see issue #19537 on m68k). */ + unsigned int :24; } state; wchar_t *wstr; /* wchar_t representation (null-terminated) */ } PyASCIIObject; @@ -602,7 +605,7 @@ PyAPI_FUNC(PyObject*) PyUnicode_New( ); #endif -/* Initializes the canonical string representation from a the deprecated +/* Initializes the canonical string representation from the deprecated wstr/Py_UNICODE representation. This function is used to convert Unicode objects which were created using the old API to the new flexible format introduced with PEP 393. @@ -846,7 +849,7 @@ PyAPI_FUNC(int) PyUnicode_Resize( Coercion is done in the following way: - 1. bytes, bytearray and other char buffer compatible objects are decoded + 1. bytes, bytearray and other bytes-like objects are decoded under the assumptions that they contain data using the UTF-8 encoding. Decoding is done in "strict" mode. @@ -1049,7 +1052,7 @@ PyAPI_FUNC(Py_ssize_t) PyUnicode_AsWideChar( always ends with a nul character. If size is not NULL, write the number of wide characters (excluding the null character) into *size. - Returns a buffer allocated by PyMem_Alloc() (use PyMem_Free() to free it) + Returns a buffer allocated by PyMem_Malloc() (use PyMem_Free() to free it) on success. On error, returns NULL, *size is undefined and raises a MemoryError. */ @@ -2004,10 +2007,12 @@ PyAPI_FUNC(int) PyUnicode_Compare( PyObject *right /* Right string */ ); +#ifndef Py_LIMITED_API PyAPI_FUNC(int) _PyUnicode_CompareWithId( PyObject *left, /* Left string */ _Py_Identifier *right /* Right identifier */ ); +#endif PyAPI_FUNC(int) PyUnicode_CompareWithASCIIString( PyObject *left, @@ -2240,6 +2245,8 @@ PyAPI_FUNC(Py_UNICODE*) Py_UNICODE_strrchr( Py_UNICODE c ); +PyAPI_FUNC(PyObject*) _PyUnicode_FormatLong(PyObject *, int, int, int); + /* Create a copy of a unicode string ending with a nul character. Return NULL and raise a MemoryError exception on memory allocation failure, otherwise return a new allocated buffer (use PyMem_Free() to free the buffer). */ diff --git a/Include/warnings.h b/Include/warnings.h index 217c06a66567..effb9fad7196 100644 --- a/Include/warnings.h +++ b/Include/warnings.h @@ -17,6 +17,7 @@ PyAPI_FUNC(int) PyErr_WarnFormat( Py_ssize_t stack_level, const char *format, /* ASCII-encoded string */ ...); +#ifndef Py_LIMITED_API PyAPI_FUNC(int) PyErr_WarnExplicitObject( PyObject *category, PyObject *message, @@ -24,6 +25,7 @@ PyAPI_FUNC(int) PyErr_WarnExplicitObject( int lineno, PyObject *module, PyObject *registry); +#endif PyAPI_FUNC(int) PyErr_WarnExplicit( PyObject *category, const char *message, /* UTF-8 encoded string */ @@ -32,11 +34,13 @@ PyAPI_FUNC(int) PyErr_WarnExplicit( const char *module, /* UTF-8 encoded string */ PyObject *registry); +#ifndef Py_LIMITED_API PyAPI_FUNC(int) PyErr_WarnExplicitFormat(PyObject *category, const char *filename, int lineno, const char *module, PyObject *registry, const char *format, ...); +#endif /* DEPRECATED: Use PyErr_WarnEx() instead. */ #ifndef Py_LIMITED_API diff --git a/LICENSE b/LICENSE index 56a5d5cc7f13..88251f5b6e8b 100644 --- a/LICENSE +++ b/LICENSE @@ -74,8 +74,8 @@ 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 Python Software Foundation; All Rights Reserved" are retained -in Python alone or in any derivative version prepared by Licensee. +2011, 2012, 2013, 2014, 2015 Python Software Foundation; All Rights Reserved" +are retained in Python alone or in any derivative version prepared by Licensee. 3. In the event Licensee prepares a derivative work that is based on or incorporates Python or any part thereof, and wants to make diff --git a/Lib/_collections_abc.py b/Lib/_collections_abc.py index faa1ff22ff40..3d3f07b92ef3 100644 --- a/Lib/_collections_abc.py +++ b/Lib/_collections_abc.py @@ -183,7 +183,7 @@ class Set(Sized, Iterable, Container): methods except for __contains__, __iter__ and __len__. To override the comparisons (presumably for speed, as the - semantics are fixed), all you have to do is redefine __le__ and + semantics are fixed), redefine __le__ and __ge__, then the other operations will automatically follow suit. """ @@ -207,21 +207,23 @@ def __lt__(self, other): def __gt__(self, other): if not isinstance(other, Set): return NotImplemented - return other.__lt__(self) + return len(self) > len(other) and self.__ge__(other) def __ge__(self, other): if not isinstance(other, Set): return NotImplemented - return other.__le__(self) + if len(self) < len(other): + return False + for elem in other: + if elem not in self: + return False + return True def __eq__(self, other): if not isinstance(other, Set): return NotImplemented return len(self) == len(other) and self.__le__(other) - def __ne__(self, other): - return not (self == other) - @classmethod def _from_iterable(cls, it): '''Construct an instance of the class from any iterable input. @@ -236,6 +238,8 @@ def __and__(self, other): return NotImplemented return self._from_iterable(value for value in other if value in self) + __rand__ = __and__ + def isdisjoint(self, other): 'Return True if two sets have a null intersection.' for value in other: @@ -249,6 +253,8 @@ def __or__(self, other): chain = (e for s in (self, other) for e in s) return self._from_iterable(chain) + __ror__ = __or__ + def __sub__(self, other): if not isinstance(other, Set): if not isinstance(other, Iterable): @@ -257,6 +263,14 @@ def __sub__(self, other): return self._from_iterable(value for value in self if value not in other) + def __rsub__(self, other): + if not isinstance(other, Set): + if not isinstance(other, Iterable): + return NotImplemented + other = self._from_iterable(other) + return self._from_iterable(value for value in other + if value not in self) + def __xor__(self, other): if not isinstance(other, Set): if not isinstance(other, Iterable): @@ -264,6 +278,8 @@ def __xor__(self, other): other = self._from_iterable(other) return (self - other) | (other - self) + __rxor__ = __xor__ + def _hash(self): """Compute the hash value of a set. @@ -432,14 +448,13 @@ def __eq__(self, other): return NotImplemented return dict(self.items()) == dict(other.items()) - def __ne__(self, other): - return not (self == other) - Mapping.register(mappingproxy) class MappingView(Sized): + __slots__ = '_mapping', + def __init__(self, mapping): self._mapping = mapping @@ -452,6 +467,8 @@ def __repr__(self): class KeysView(MappingView, Set): + __slots__ = () + @classmethod def _from_iterable(self, it): return set(it) @@ -467,6 +484,8 @@ def __iter__(self): class ItemsView(MappingView, Set): + __slots__ = () + @classmethod def _from_iterable(self, it): return set(it) @@ -489,6 +508,8 @@ def __iter__(self): class ValuesView(MappingView): + __slots__ = () + def __contains__(self, value): for key in self._mapping: if value == self._mapping[key]: @@ -565,23 +586,24 @@ def update(*args, **kwds): If E present and lacks .keys() method, does: for (k, v) in E: D[k] = v In either case, this is followed by: for k, v in F.items(): D[k] = v ''' - if len(args) > 2: - raise TypeError("update() takes at most 2 positional " - "arguments ({} given)".format(len(args))) - elif not args: - raise TypeError("update() takes at least 1 argument (0 given)") - self = args[0] - other = args[1] if len(args) >= 2 else () - - if isinstance(other, Mapping): - for key in other: - self[key] = other[key] - elif hasattr(other, "keys"): - for key in other.keys(): - self[key] = other[key] - else: - for key, value in other: - self[key] = value + if not args: + raise TypeError("descriptor 'update' of 'MutableMapping' object " + "needs an argument") + self, *args = args + if len(args) > 1: + raise TypeError('update expected at most 1 arguments, got %d' % + len(args)) + if args: + other = args[0] + if isinstance(other, Mapping): + for key in other: + self[key] = other[key] + elif hasattr(other, "keys"): + for key in other.keys(): + self[key] = other[key] + else: + for key, value in other: + self[key] = value for key, value in kwds.items(): self[key] = value diff --git a/Lib/_dummy_thread.py b/Lib/_dummy_thread.py index b67cfb95be8e..36e5f38ae0e8 100644 --- a/Lib/_dummy_thread.py +++ b/Lib/_dummy_thread.py @@ -140,6 +140,14 @@ def release(self): def locked(self): return self.locked_status + def __repr__(self): + return "<%s %s.%s object at %s>" % ( + "locked" if self.locked_status else "unlocked", + self.__class__.__module__, + self.__class__.__qualname__, + hex(id(self)) + ) + # Used to signal that interrupt_main was called in a "thread" _interrupt = False # True when not executing in a "thread" diff --git a/Lib/_osx_support.py b/Lib/_osx_support.py index 40fc78b6984b..b07e75d0e8cb 100644 --- a/Lib/_osx_support.py +++ b/Lib/_osx_support.py @@ -182,7 +182,7 @@ def _find_appropriate_compiler(_config_vars): # Compiler is GCC, check if it is LLVM-GCC data = _read_output("'%s' --version" % (cc.replace("'", "'\"'\"'"),)) - if 'llvm-gcc' in data: + if data and 'llvm-gcc' in data: # Found LLVM-GCC, fall back to clang cc = _find_build_tool('clang') @@ -450,8 +450,16 @@ def get_platform_osx(_config_vars, osname, release, machine): # case and disallow installs. cflags = _config_vars.get(_INITPRE+'CFLAGS', _config_vars.get('CFLAGS', '')) - if ((macrelease + '.') >= '10.4.' and - '-arch' in cflags.strip()): + if macrelease: + try: + macrelease = tuple(int(i) for i in macrelease.split('.')[0:2]) + except ValueError: + macrelease = (10, 0) + else: + # assume no universal support + macrelease = (10, 0) + + if (macrelease >= (10, 4)) and '-arch' in cflags.strip(): # The universal build will build fat binaries, but not on # systems before 10.4 diff --git a/Lib/_pydecimal.py b/Lib/_pydecimal.py new file mode 100644 index 000000000000..ca6c4bd98d41 --- /dev/null +++ b/Lib/_pydecimal.py @@ -0,0 +1,6381 @@ +# Copyright (c) 2004 Python Software Foundation. +# All rights reserved. + +# Written by Eric Price <eprice at tjhsst.edu> +# and Facundo Batista <facundo at taniquetil.com.ar> +# and Raymond Hettinger <python at rcn.com> +# and Aahz <aahz at pobox.com> +# and Tim Peters + +# This module should be kept in sync with the latest updates of the +# IBM specification as it evolves. Those updates will be treated +# as bug fixes (deviation from the spec is a compatibility, usability +# bug) and will be backported. At this point the spec is stabilizing +# and the updates are becoming fewer, smaller, and less significant. + +""" +This is an implementation of decimal floating point arithmetic based on +the General Decimal Arithmetic Specification: + + http://speleotrove.com/decimal/decarith.html + +and IEEE standard 854-1987: + + http://en.wikipedia.org/wiki/IEEE_854-1987 + +Decimal floating point has finite precision with arbitrarily large bounds. + +The purpose of this module is to support arithmetic using familiar +"schoolhouse" rules and to avoid some of the tricky representation +issues associated with binary floating point. The package is especially +useful for financial applications or for contexts where users have +expectations that are at odds with binary floating point (for instance, +in binary floating point, 1.00 % 0.1 gives 0.09999999999999995 instead +of 0.0; Decimal('1.00') % Decimal('0.1') returns the expected +Decimal('0.00')). + +Here are some examples of using the decimal module: + +>>> from decimal import * +>>> setcontext(ExtendedContext) +>>> Decimal(0) +Decimal('0') +>>> Decimal('1') +Decimal('1') +>>> Decimal('-.0123') +Decimal('-0.0123') +>>> Decimal(123456) +Decimal('123456') +>>> Decimal('123.45e12345678') +Decimal('1.2345E+12345680') +>>> Decimal('1.33') + Decimal('1.27') +Decimal('2.60') +>>> Decimal('12.34') + Decimal('3.87') - Decimal('18.41') +Decimal('-2.20') +>>> dig = Decimal(1) +>>> print(dig / Decimal(3)) +0.333333333 +>>> getcontext().prec = 18 +>>> print(dig / Decimal(3)) +0.333333333333333333 +>>> print(dig.sqrt()) +1 +>>> print(Decimal(3).sqrt()) +1.73205080756887729 +>>> print(Decimal(3) ** 123) +4.85192780976896427E+58 +>>> inf = Decimal(1) / Decimal(0) +>>> print(inf) +Infinity +>>> neginf = Decimal(-1) / Decimal(0) +>>> print(neginf) +-Infinity +>>> print(neginf + inf) +NaN +>>> print(neginf * inf) +-Infinity +>>> print(dig / 0) +Infinity +>>> getcontext().traps[DivisionByZero] = 1 +>>> print(dig / 0) +Traceback (most recent call last): + ... + ... + ... +decimal.DivisionByZero: x / 0 +>>> c = Context() +>>> c.traps[InvalidOperation] = 0 +>>> print(c.flags[InvalidOperation]) +0 +>>> c.divide(Decimal(0), Decimal(0)) +Decimal('NaN') +>>> c.traps[InvalidOperation] = 1 +>>> print(c.flags[InvalidOperation]) +1 +>>> c.flags[InvalidOperation] = 0 +>>> print(c.flags[InvalidOperation]) +0 +>>> print(c.divide(Decimal(0), Decimal(0))) +Traceback (most recent call last): + ... + ... + ... +decimal.InvalidOperation: 0 / 0 +>>> print(c.flags[InvalidOperation]) +1 +>>> c.flags[InvalidOperation] = 0 +>>> c.traps[InvalidOperation] = 0 +>>> print(c.divide(Decimal(0), Decimal(0))) +NaN +>>> print(c.flags[InvalidOperation]) +1 +>>> +""" + +__all__ = [ + # Two major classes + 'Decimal', 'Context', + + # Named tuple representation + 'DecimalTuple', + + # Contexts + 'DefaultContext', 'BasicContext', 'ExtendedContext', + + # Exceptions + 'DecimalException', 'Clamped', 'InvalidOperation', 'DivisionByZero', + 'Inexact', 'Rounded', 'Subnormal', 'Overflow', 'Underflow', + 'FloatOperation', + + # Exceptional conditions that trigger InvalidOperation + 'DivisionImpossible', 'InvalidContext', 'ConversionSyntax', 'DivisionUndefined', + + # Constants for use in setting up contexts + 'ROUND_DOWN', 'ROUND_HALF_UP', 'ROUND_HALF_EVEN', 'ROUND_CEILING', + 'ROUND_FLOOR', 'ROUND_UP', 'ROUND_HALF_DOWN', 'ROUND_05UP', + + # Functions for manipulating contexts + 'setcontext', 'getcontext', 'localcontext', + + # Limits for the C version for compatibility + 'MAX_PREC', 'MAX_EMAX', 'MIN_EMIN', 'MIN_ETINY', + + # C version: compile time choice that enables the thread local context + 'HAVE_THREADS' +] + +__xname__ = __name__ # sys.modules lookup (--without-threads) +__name__ = 'decimal' # For pickling +__version__ = '1.70' # Highest version of the spec this complies with + # See http://speleotrove.com/decimal/ +__libmpdec_version__ = "2.4.1" # compatible libmpdec version + +import math as _math +import numbers as _numbers +import sys + +try: + from collections import namedtuple as _namedtuple + DecimalTuple = _namedtuple('DecimalTuple', 'sign digits exponent') +except ImportError: + DecimalTuple = lambda *args: args + +# Rounding +ROUND_DOWN = 'ROUND_DOWN' +ROUND_HALF_UP = 'ROUND_HALF_UP' +ROUND_HALF_EVEN = 'ROUND_HALF_EVEN' +ROUND_CEILING = 'ROUND_CEILING' +ROUND_FLOOR = 'ROUND_FLOOR' +ROUND_UP = 'ROUND_UP' +ROUND_HALF_DOWN = 'ROUND_HALF_DOWN' +ROUND_05UP = 'ROUND_05UP' + +# Compatibility with the C version +HAVE_THREADS = True +if sys.maxsize == 2**63-1: + MAX_PREC = 999999999999999999 + MAX_EMAX = 999999999999999999 + MIN_EMIN = -999999999999999999 +else: + MAX_PREC = 425000000 + MAX_EMAX = 425000000 + MIN_EMIN = -425000000 + +MIN_ETINY = MIN_EMIN - (MAX_PREC-1) + +# Errors + +class DecimalException(ArithmeticError): + """Base exception class. + + Used exceptions derive from this. + If an exception derives from another exception besides this (such as + Underflow (Inexact, Rounded, Subnormal) that indicates that it is only + called if the others are present. This isn't actually used for + anything, though. + + handle -- Called when context._raise_error is called and the + trap_enabler is not set. First argument is self, second is the + context. More arguments can be given, those being after + the explanation in _raise_error (For example, + context._raise_error(NewError, '(-x)!', self._sign) would + call NewError().handle(context, self._sign).) + + To define a new exception, it should be sufficient to have it derive + from DecimalException. + """ + def handle(self, context, *args): + pass + + +class Clamped(DecimalException): + """Exponent of a 0 changed to fit bounds. + + This occurs and signals clamped if the exponent of a result has been + altered in order to fit the constraints of a specific concrete + representation. This may occur when the exponent of a zero result would + be outside the bounds of a representation, or when a large normal + number would have an encoded exponent that cannot be represented. In + this latter case, the exponent is reduced to fit and the corresponding + number of zero digits are appended to the coefficient ("fold-down"). + """ + +class InvalidOperation(DecimalException): + """An invalid operation was performed. + + Various bad things cause this: + + Something creates a signaling NaN + -INF + INF + 0 * (+-)INF + (+-)INF / (+-)INF + x % 0 + (+-)INF % x + x._rescale( non-integer ) + sqrt(-x) , x > 0 + 0 ** 0 + x ** (non-integer) + x ** (+-)INF + An operand is invalid + + The result of the operation after these is a quiet positive NaN, + except when the cause is a signaling NaN, in which case the result is + also a quiet NaN, but with the original sign, and an optional + diagnostic information. + """ + def handle(self, context, *args): + if args: + ans = _dec_from_triple(args[0]._sign, args[0]._int, 'n', True) + return ans._fix_nan(context) + return _NaN + +class ConversionSyntax(InvalidOperation): + """Trying to convert badly formed string. + + This occurs and signals invalid-operation if an string is being + converted to a number and it does not conform to the numeric string + syntax. The result is [0,qNaN]. + """ + def handle(self, context, *args): + return _NaN + +class DivisionByZero(DecimalException, ZeroDivisionError): + """Division by 0. + + This occurs and signals division-by-zero if division of a finite number + by zero was attempted (during a divide-integer or divide operation, or a + power operation with negative right-hand operand), and the dividend was + not zero. + + The result of the operation is [sign,inf], where sign is the exclusive + or of the signs of the operands for divide, or is 1 for an odd power of + -0, for power. + """ + + def handle(self, context, sign, *args): + return _SignedInfinity[sign] + +class DivisionImpossible(InvalidOperation): + """Cannot perform the division adequately. + + This occurs and signals invalid-operation if the integer result of a + divide-integer or remainder operation had too many digits (would be + longer than precision). The result is [0,qNaN]. + """ + + def handle(self, context, *args): + return _NaN + +class DivisionUndefined(InvalidOperation, ZeroDivisionError): + """Undefined result of division. + + This occurs and signals invalid-operation if division by zero was + attempted (during a divide-integer, divide, or remainder operation), and + the dividend is also zero. The result is [0,qNaN]. + """ + + def handle(self, context, *args): + return _NaN + +class Inexact(DecimalException): + """Had to round, losing information. + + This occurs and signals inexact whenever the result of an operation is + not exact (that is, it needed to be rounded and any discarded digits + were non-zero), or if an overflow or underflow condition occurs. The + result in all cases is unchanged. + + The inexact signal may be tested (or trapped) to determine if a given + operation (or sequence of operations) was inexact. + """ + +class InvalidContext(InvalidOperation): + """Invalid context. Unknown rounding, for example. + + This occurs and signals invalid-operation if an invalid context was + detected during an operation. This can occur if contexts are not checked + on creation and either the precision exceeds the capability of the + underlying concrete representation or an unknown or unsupported rounding + was specified. These aspects of the context need only be checked when + the values are required to be used. The result is [0,qNaN]. + """ + + def handle(self, context, *args): + return _NaN + +class Rounded(DecimalException): + """Number got rounded (not necessarily changed during rounding). + + This occurs and signals rounded whenever the result of an operation is + rounded (that is, some zero or non-zero digits were discarded from the + coefficient), or if an overflow or underflow condition occurs. The + result in all cases is unchanged. + + The rounded signal may be tested (or trapped) to determine if a given + operation (or sequence of operations) caused a loss of precision. + """ + +class Subnormal(DecimalException): + """Exponent < Emin before rounding. + + This occurs and signals subnormal whenever the result of a conversion or + operation is subnormal (that is, its adjusted exponent is less than + Emin, before any rounding). The result in all cases is unchanged. + + The subnormal signal may be tested (or trapped) to determine if a given + or operation (or sequence of operations) yielded a subnormal result. + """ + +class Overflow(Inexact, Rounded): + """Numerical overflow. + + This occurs and signals overflow if the adjusted exponent of a result + (from a conversion or from an operation that is not an attempt to divide + by zero), after rounding, would be greater than the largest value that + can be handled by the implementation (the value Emax). + + The result depends on the rounding mode: + + For round-half-up and round-half-even (and for round-half-down and + round-up, if implemented), the result of the operation is [sign,inf], + where sign is the sign of the intermediate result. For round-down, the + result is the largest finite number that can be represented in the + current precision, with the sign of the intermediate result. For + round-ceiling, the result is the same as for round-down if the sign of + the intermediate result is 1, or is [0,inf] otherwise. For round-floor, + the result is the same as for round-down if the sign of the intermediate + result is 0, or is [1,inf] otherwise. In all cases, Inexact and Rounded + will also be raised. + """ + + def handle(self, context, sign, *args): + if context.rounding in (ROUND_HALF_UP, ROUND_HALF_EVEN, + ROUND_HALF_DOWN, ROUND_UP): + return _SignedInfinity[sign] + if sign == 0: + if context.rounding == ROUND_CEILING: + return _SignedInfinity[sign] + return _dec_from_triple(sign, '9'*context.prec, + context.Emax-context.prec+1) + if sign == 1: + if context.rounding == ROUND_FLOOR: + return _SignedInfinity[sign] + return _dec_from_triple(sign, '9'*context.prec, + context.Emax-context.prec+1) + + +class Underflow(Inexact, Rounded, Subnormal): + """Numerical underflow with result rounded to 0. + + This occurs and signals underflow if a result is inexact and the + adjusted exponent of the result would be smaller (more negative) than + the smallest value that can be handled by the implementation (the value + Emin). That is, the result is both inexact and subnormal. + + The result after an underflow will be a subnormal number rounded, if + necessary, so that its exponent is not less than Etiny. This may result + in 0 with the sign of the intermediate result and an exponent of Etiny. + + In all cases, Inexact, Rounded, and Subnormal will also be raised. + """ + +class FloatOperation(DecimalException, TypeError): + """Enable stricter semantics for mixing floats and Decimals. + + If the signal is not trapped (default), mixing floats and Decimals is + permitted in the Decimal() constructor, context.create_decimal() and + all comparison operators. Both conversion and comparisons are exact. + Any occurrence of a mixed operation is silently recorded by setting + FloatOperation in the context flags. Explicit conversions with + Decimal.from_float() or context.create_decimal_from_float() do not + set the flag. + + Otherwise (the signal is trapped), only equality comparisons and explicit + conversions are silent. All other mixed operations raise FloatOperation. + """ + +# List of public traps and flags +_signals = [Clamped, DivisionByZero, Inexact, Overflow, Rounded, + Underflow, InvalidOperation, Subnormal, FloatOperation] + +# Map conditions (per the spec) to signals +_condition_map = {ConversionSyntax:InvalidOperation, + DivisionImpossible:InvalidOperation, + DivisionUndefined:InvalidOperation, + InvalidContext:InvalidOperation} + +# Valid rounding modes +_rounding_modes = (ROUND_DOWN, ROUND_HALF_UP, ROUND_HALF_EVEN, ROUND_CEILING, + ROUND_FLOOR, ROUND_UP, ROUND_HALF_DOWN, ROUND_05UP) + +##### Context Functions ################################################## + +# The getcontext() and setcontext() function manage access to a thread-local +# current context. Py2.4 offers direct support for thread locals. If that +# is not available, use threading.current_thread() which is slower but will +# work for older Pythons. If threads are not part of the build, create a +# mock threading object with threading.local() returning the module namespace. + +try: + import threading +except ImportError: + # Python was compiled without threads; create a mock object instead + class MockThreading(object): + def local(self, sys=sys): + return sys.modules[__xname__] + threading = MockThreading() + del MockThreading + +try: + threading.local + +except AttributeError: + + # To fix reloading, force it to create a new context + # Old contexts have different exceptions in their dicts, making problems. + if hasattr(threading.current_thread(), '__decimal_context__'): + del threading.current_thread().__decimal_context__ + + def setcontext(context): + """Set this thread's context to context.""" + if context in (DefaultContext, BasicContext, ExtendedContext): + context = context.copy() + context.clear_flags() + threading.current_thread().__decimal_context__ = context + + def getcontext(): + """Returns this thread's context. + + If this thread does not yet have a context, returns + a new context and sets this thread's context. + New contexts are copies of DefaultContext. + """ + try: + return threading.current_thread().__decimal_context__ + except AttributeError: + context = Context() + threading.current_thread().__decimal_context__ = context + return context + +else: + + local = threading.local() + if hasattr(local, '__decimal_context__'): + del local.__decimal_context__ + + def getcontext(_local=local): + """Returns this thread's context. + + If this thread does not yet have a context, returns + a new context and sets this thread's context. + New contexts are copies of DefaultContext. + """ + try: + return _local.__decimal_context__ + except AttributeError: + context = Context() + _local.__decimal_context__ = context + return context + + def setcontext(context, _local=local): + """Set this thread's context to context.""" + if context in (DefaultContext, BasicContext, ExtendedContext): + context = context.copy() + context.clear_flags() + _local.__decimal_context__ = context + + del threading, local # Don't contaminate the namespace + +def localcontext(ctx=None): + """Return a context manager for a copy of the supplied context + + Uses a copy of the current context if no context is specified + The returned context manager creates a local decimal context + in a with statement: + def sin(x): + with localcontext() as ctx: + ctx.prec += 2 + # Rest of sin calculation algorithm + # uses a precision 2 greater than normal + return +s # Convert result to normal precision + + def sin(x): + with localcontext(ExtendedContext): + # Rest of sin calculation algorithm + # uses the Extended Context from the + # General Decimal Arithmetic Specification + return +s # Convert result to normal context + + >>> setcontext(DefaultContext) + >>> print(getcontext().prec) + 28 + >>> with localcontext(): + ... ctx = getcontext() + ... ctx.prec += 2 + ... print(ctx.prec) + ... + 30 + >>> with localcontext(ExtendedContext): + ... print(getcontext().prec) + ... + 9 + >>> print(getcontext().prec) + 28 + """ + if ctx is None: ctx = getcontext() + return _ContextManager(ctx) + + +##### Decimal class ####################################################### + +# Do not subclass Decimal from numbers.Real and do not register it as such +# (because Decimals are not interoperable with floats). See the notes in +# numbers.py for more detail. + +class Decimal(object): + """Floating point class for decimal arithmetic.""" + + __slots__ = ('_exp','_int','_sign', '_is_special') + # Generally, the value of the Decimal instance is given by + # (-1)**_sign * _int * 10**_exp + # Special values are signified by _is_special == True + + # We're immutable, so use __new__ not __init__ + def __new__(cls, value="0", context=None): + """Create a decimal point instance. + + >>> Decimal('3.14') # string input + Decimal('3.14') + >>> Decimal((0, (3, 1, 4), -2)) # tuple (sign, digit_tuple, exponent) + Decimal('3.14') + >>> Decimal(314) # int + Decimal('314') + >>> Decimal(Decimal(314)) # another decimal instance + Decimal('314') + >>> Decimal(' 3.14 \\n') # leading and trailing whitespace okay + Decimal('3.14') + """ + + # Note that the coefficient, self._int, is actually stored as + # a string rather than as a tuple of digits. This speeds up + # the "digits to integer" and "integer to digits" conversions + # that are used in almost every arithmetic operation on + # Decimals. This is an internal detail: the as_tuple function + # and the Decimal constructor still deal with tuples of + # digits. + + self = object.__new__(cls) + + # From a string + # REs insist on real strings, so we can too. + if isinstance(value, str): + m = _parser(value.strip()) + if m is None: + if context is None: + context = getcontext() + return context._raise_error(ConversionSyntax, + "Invalid literal for Decimal: %r" % value) + + if m.group('sign') == "-": + self._sign = 1 + else: + self._sign = 0 + intpart = m.group('int') + if intpart is not None: + # finite number + fracpart = m.group('frac') or '' + exp = int(m.group('exp') or '0') + self._int = str(int(intpart+fracpart)) + self._exp = exp - len(fracpart) + self._is_special = False + else: + diag = m.group('diag') + if diag is not None: + # NaN + self._int = str(int(diag or '0')).lstrip('0') + if m.group('signal'): + self._exp = 'N' + else: + self._exp = 'n' + else: + # infinity + self._int = '0' + self._exp = 'F' + self._is_special = True + return self + + # From an integer + if isinstance(value, int): + if value >= 0: + self._sign = 0 + else: + self._sign = 1 + self._exp = 0 + self._int = str(abs(value)) + self._is_special = False + return self + + # From another decimal + if isinstance(value, Decimal): + self._exp = value._exp + self._sign = value._sign + self._int = value._int + self._is_special = value._is_special + return self + + # From an internal working value + if isinstance(value, _WorkRep): + self._sign = value.sign + self._int = str(value.int) + self._exp = int(value.exp) + self._is_special = False + return self + + # tuple/list conversion (possibly from as_tuple()) + if isinstance(value, (list,tuple)): + if len(value) != 3: + raise ValueError('Invalid tuple size in creation of Decimal ' + 'from list or tuple. The list or tuple ' + 'should have exactly three elements.') + # process sign. The isinstance test rejects floats + if not (isinstance(value[0], int) and value[0] in (0,1)): + raise ValueError("Invalid sign. The first value in the tuple " + "should be an integer; either 0 for a " + "positive number or 1 for a negative number.") + self._sign = value[0] + if value[2] == 'F': + # infinity: value[1] is ignored + self._int = '0' + self._exp = value[2] + self._is_special = True + else: + # process and validate the digits in value[1] + digits = [] + for digit in value[1]: + if isinstance(digit, int) and 0 <= digit <= 9: + # skip leading zeros + if digits or digit != 0: + digits.append(digit) + else: + raise ValueError("The second value in the tuple must " + "be composed of integers in the range " + "0 through 9.") + if value[2] in ('n', 'N'): + # NaN: digits form the diagnostic + self._int = ''.join(map(str, digits)) + self._exp = value[2] + self._is_special = True + elif isinstance(value[2], int): + # finite number: digits give the coefficient + self._int = ''.join(map(str, digits or [0])) + self._exp = value[2] + self._is_special = False + else: + raise ValueError("The third value in the tuple must " + "be an integer, or one of the " + "strings 'F', 'n', 'N'.") + return self + + if isinstance(value, float): + if context is None: + context = getcontext() + context._raise_error(FloatOperation, + "strict semantics for mixing floats and Decimals are " + "enabled") + value = Decimal.from_float(value) + self._exp = value._exp + self._sign = value._sign + self._int = value._int + self._is_special = value._is_special + return self + + raise TypeError("Cannot convert %r to Decimal" % value) + + @classmethod + def from_float(cls, f): + """Converts a float to a decimal number, exactly. + + Note that Decimal.from_float(0.1) is not the same as Decimal('0.1'). + Since 0.1 is not exactly representable in binary floating point, the + value is stored as the nearest representable value which is + 0x1.999999999999ap-4. The exact equivalent of the value in decimal + is 0.1000000000000000055511151231257827021181583404541015625. + + >>> Decimal.from_float(0.1) + Decimal('0.1000000000000000055511151231257827021181583404541015625') + >>> Decimal.from_float(float('nan')) + Decimal('NaN') + >>> Decimal.from_float(float('inf')) + Decimal('Infinity') + >>> Decimal.from_float(-float('inf')) + Decimal('-Infinity') + >>> Decimal.from_float(-0.0) + Decimal('-0') + + """ + if isinstance(f, int): # handle integer inputs + return cls(f) + if not isinstance(f, float): + raise TypeError("argument must be int or float.") + if _math.isinf(f) or _math.isnan(f): + return cls(repr(f)) + if _math.copysign(1.0, f) == 1.0: + sign = 0 + else: + sign = 1 + n, d = abs(f).as_integer_ratio() + k = d.bit_length() - 1 + result = _dec_from_triple(sign, str(n*5**k), -k) + if cls is Decimal: + return result + else: + return cls(result) + + def _isnan(self): + """Returns whether the number is not actually one. + + 0 if a number + 1 if NaN + 2 if sNaN + """ + if self._is_special: + exp = self._exp + if exp == 'n': + return 1 + elif exp == 'N': + return 2 + return 0 + + def _isinfinity(self): + """Returns whether the number is infinite + + 0 if finite or not a number + 1 if +INF + -1 if -INF + """ + if self._exp == 'F': + if self._sign: + return -1 + return 1 + return 0 + + def _check_nans(self, other=None, context=None): + """Returns whether the number is not actually one. + + if self, other are sNaN, signal + if self, other are NaN return nan + return 0 + + Done before operations. + """ + + self_is_nan = self._isnan() + if other is None: + other_is_nan = False + else: + other_is_nan = other._isnan() + + if self_is_nan or other_is_nan: + if context is None: + context = getcontext() + + if self_is_nan == 2: + return context._raise_error(InvalidOperation, 'sNaN', + self) + if other_is_nan == 2: + return context._raise_error(InvalidOperation, 'sNaN', + other) + if self_is_nan: + return self._fix_nan(context) + + return other._fix_nan(context) + return 0 + + def _compare_check_nans(self, other, context): + """Version of _check_nans used for the signaling comparisons + compare_signal, __le__, __lt__, __ge__, __gt__. + + Signal InvalidOperation if either self or other is a (quiet + or signaling) NaN. Signaling NaNs take precedence over quiet + NaNs. + + Return 0 if neither operand is a NaN. + + """ + if context is None: + context = getcontext() + + if self._is_special or other._is_special: + if self.is_snan(): + return context._raise_error(InvalidOperation, + 'comparison involving sNaN', + self) + elif other.is_snan(): + return context._raise_error(InvalidOperation, + 'comparison involving sNaN', + other) + elif self.is_qnan(): + return context._raise_error(InvalidOperation, + 'comparison involving NaN', + self) + elif other.is_qnan(): + return context._raise_error(InvalidOperation, + 'comparison involving NaN', + other) + return 0 + + def __bool__(self): + """Return True if self is nonzero; otherwise return False. + + NaNs and infinities are considered nonzero. + """ + return self._is_special or self._int != '0' + + def _cmp(self, other): + """Compare the two non-NaN decimal instances self and other. + + Returns -1 if self < other, 0 if self == other and 1 + if self > other. This routine is for internal use only.""" + + if self._is_special or other._is_special: + self_inf = self._isinfinity() + other_inf = other._isinfinity() + if self_inf == other_inf: + return 0 + elif self_inf < other_inf: + return -1 + else: + return 1 + + # check for zeros; Decimal('0') == Decimal('-0') + if not self: + if not other: + return 0 + else: + return -((-1)**other._sign) + if not other: + return (-1)**self._sign + + # If different signs, neg one is less + if other._sign < self._sign: + return -1 + if self._sign < other._sign: + return 1 + + self_adjusted = self.adjusted() + other_adjusted = other.adjusted() + if self_adjusted == other_adjusted: + self_padded = self._int + '0'*(self._exp - other._exp) + other_padded = other._int + '0'*(other._exp - self._exp) + if self_padded == other_padded: + return 0 + elif self_padded < other_padded: + return -(-1)**self._sign + else: + return (-1)**self._sign + elif self_adjusted > other_adjusted: + return (-1)**self._sign + else: # self_adjusted < other_adjusted + return -((-1)**self._sign) + + # Note: The Decimal standard doesn't cover rich comparisons for + # Decimals. In particular, the specification is silent on the + # subject of what should happen for a comparison involving a NaN. + # We take the following approach: + # + # == comparisons involving a quiet NaN always return False + # != comparisons involving a quiet NaN always return True + # == or != comparisons involving a signaling NaN signal + # InvalidOperation, and return False or True as above if the + # InvalidOperation is not trapped. + # <, >, <= and >= comparisons involving a (quiet or signaling) + # NaN signal InvalidOperation, and return False if the + # InvalidOperation is not trapped. + # + # This behavior is designed to conform as closely as possible to + # that specified by IEEE 754. + + def __eq__(self, other, context=None): + self, other = _convert_for_comparison(self, other, equality_op=True) + if other is NotImplemented: + return other + if self._check_nans(other, context): + return False + return self._cmp(other) == 0 + + def __lt__(self, other, context=None): + self, other = _convert_for_comparison(self, other) + if other is NotImplemented: + return other + ans = self._compare_check_nans(other, context) + if ans: + return False + return self._cmp(other) < 0 + + def __le__(self, other, context=None): + self, other = _convert_for_comparison(self, other) + if other is NotImplemented: + return other + ans = self._compare_check_nans(other, context) + if ans: + return False + return self._cmp(other) <= 0 + + def __gt__(self, other, context=None): + self, other = _convert_for_comparison(self, other) + if other is NotImplemented: + return other + ans = self._compare_check_nans(other, context) + if ans: + return False + return self._cmp(other) > 0 + + def __ge__(self, other, context=None): + self, other = _convert_for_comparison(self, other) + if other is NotImplemented: + return other + ans = self._compare_check_nans(other, context) + if ans: + return False + return self._cmp(other) >= 0 + + def compare(self, other, context=None): + """Compares one to another. + + -1 => a < b + 0 => a = b + 1 => a > b + NaN => one is NaN + Like __cmp__, but returns Decimal instances. + """ + other = _convert_other(other, raiseit=True) + + # Compare(NaN, NaN) = NaN + if (self._is_special or other and other._is_special): + ans = self._check_nans(other, context) + if ans: + return ans + + return Decimal(self._cmp(other)) + + def __hash__(self): + """x.__hash__() <==> hash(x)""" + + # In order to make sure that the hash of a Decimal instance + # agrees with the hash of a numerically equal integer, float + # or Fraction, we follow the rules for numeric hashes outlined + # in the documentation. (See library docs, 'Built-in Types'). + if self._is_special: + if self.is_snan(): + raise TypeError('Cannot hash a signaling NaN value.') + elif self.is_nan(): + return _PyHASH_NAN + else: + if self._sign: + return -_PyHASH_INF + else: + return _PyHASH_INF + + if self._exp >= 0: + exp_hash = pow(10, self._exp, _PyHASH_MODULUS) + else: + exp_hash = pow(_PyHASH_10INV, -self._exp, _PyHASH_MODULUS) + hash_ = int(self._int) * exp_hash % _PyHASH_MODULUS + ans = hash_ if self >= 0 else -hash_ + return -2 if ans == -1 else ans + + def as_tuple(self): + """Represents the number as a triple tuple. + + To show the internals exactly as they are. + """ + return DecimalTuple(self._sign, tuple(map(int, self._int)), self._exp) + + def __repr__(self): + """Represents the number as an instance of Decimal.""" + # Invariant: eval(repr(d)) == d + return "Decimal('%s')" % str(self) + + def __str__(self, eng=False, context=None): + """Return string representation of the number in scientific notation. + + Captures all of the information in the underlying representation. + """ + + sign = ['', '-'][self._sign] + if self._is_special: + if self._exp == 'F': + return sign + 'Infinity' + elif self._exp == 'n': + return sign + 'NaN' + self._int + else: # self._exp == 'N' + return sign + 'sNaN' + self._int + + # number of digits of self._int to left of decimal point + leftdigits = self._exp + len(self._int) + + # dotplace is number of digits of self._int to the left of the + # decimal point in the mantissa of the output string (that is, + # after adjusting the exponent) + if self._exp <= 0 and leftdigits > -6: + # no exponent required + dotplace = leftdigits + elif not eng: + # usual scientific notation: 1 digit on left of the point + dotplace = 1 + elif self._int == '0': + # engineering notation, zero + dotplace = (leftdigits + 1) % 3 - 1 + else: + # engineering notation, nonzero + dotplace = (leftdigits - 1) % 3 + 1 + + if dotplace <= 0: + intpart = '0' + fracpart = '.' + '0'*(-dotplace) + self._int + elif dotplace >= len(self._int): + intpart = self._int+'0'*(dotplace-len(self._int)) + fracpart = '' + else: + intpart = self._int[:dotplace] + fracpart = '.' + self._int[dotplace:] + if leftdigits == dotplace: + exp = '' + else: + if context is None: + context = getcontext() + exp = ['e', 'E'][context.capitals] + "%+d" % (leftdigits-dotplace) + + return sign + intpart + fracpart + exp + + def to_eng_string(self, context=None): + """Convert to engineering-type string. + + Engineering notation has an exponent which is a multiple of 3, so there + are up to 3 digits left of the decimal place. + + Same rules for when in exponential and when as a value as in __str__. + """ + return self.__str__(eng=True, context=context) + + def __neg__(self, context=None): + """Returns a copy with the sign switched. + + Rounds, if it has reason. + """ + if self._is_special: + ans = self._check_nans(context=context) + if ans: + return ans + + if context is None: + context = getcontext() + + if not self and context.rounding != ROUND_FLOOR: + # -Decimal('0') is Decimal('0'), not Decimal('-0'), except + # in ROUND_FLOOR rounding mode. + ans = self.copy_abs() + else: + ans = self.copy_negate() + + return ans._fix(context) + + def __pos__(self, context=None): + """Returns a copy, unless it is a sNaN. + + Rounds the number (if more then precision digits) + """ + if self._is_special: + ans = self._check_nans(context=context) + if ans: + return ans + + if context is None: + context = getcontext() + + if not self and context.rounding != ROUND_FLOOR: + # + (-0) = 0, except in ROUND_FLOOR rounding mode. + ans = self.copy_abs() + else: + ans = Decimal(self) + + return ans._fix(context) + + def __abs__(self, round=True, context=None): + """Returns the absolute value of self. + + If the keyword argument 'round' is false, do not round. The + expression self.__abs__(round=False) is equivalent to + self.copy_abs(). + """ + if not round: + return self.copy_abs() + + if self._is_special: + ans = self._check_nans(context=context) + if ans: + return ans + + if self._sign: + ans = self.__neg__(context=context) + else: + ans = self.__pos__(context=context) + + return ans + + def __add__(self, other, context=None): + """Returns self + other. + + -INF + INF (or the reverse) cause InvalidOperation errors. + """ + other = _convert_other(other) + if other is NotImplemented: + return other + + if context is None: + context = getcontext() + + if self._is_special or other._is_special: + ans = self._check_nans(other, context) + if ans: + return ans + + if self._isinfinity(): + # If both INF, same sign => same as both, opposite => error. + if self._sign != other._sign and other._isinfinity(): + return context._raise_error(InvalidOperation, '-INF + INF') + return Decimal(self) + if other._isinfinity(): + return Decimal(other) # Can't both be infinity here + + exp = min(self._exp, other._exp) + negativezero = 0 + if context.rounding == ROUND_FLOOR and self._sign != other._sign: + # If the answer is 0, the sign should be negative, in this case. + negativezero = 1 + + if not self and not other: + sign = min(self._sign, other._sign) + if negativezero: + sign = 1 + ans = _dec_from_triple(sign, '0', exp) + ans = ans._fix(context) + return ans + if not self: + exp = max(exp, other._exp - context.prec-1) + ans = other._rescale(exp, context.rounding) + ans = ans._fix(context) + return ans + if not other: + exp = max(exp, self._exp - context.prec-1) + ans = self._rescale(exp, context.rounding) + ans = ans._fix(context) + return ans + + op1 = _WorkRep(self) + op2 = _WorkRep(other) + op1, op2 = _normalize(op1, op2, context.prec) + + result = _WorkRep() + if op1.sign != op2.sign: + # Equal and opposite + if op1.int == op2.int: + ans = _dec_from_triple(negativezero, '0', exp) + ans = ans._fix(context) + return ans + if op1.int < op2.int: + op1, op2 = op2, op1 + # OK, now abs(op1) > abs(op2) + if op1.sign == 1: + result.sign = 1 + op1.sign, op2.sign = op2.sign, op1.sign + else: + result.sign = 0 + # So we know the sign, and op1 > 0. + elif op1.sign == 1: + result.sign = 1 + op1.sign, op2.sign = (0, 0) + else: + result.sign = 0 + # Now, op1 > abs(op2) > 0 + + if op2.sign == 0: + result.int = op1.int + op2.int + else: + result.int = op1.int - op2.int + + result.exp = op1.exp + ans = Decimal(result) + ans = ans._fix(context) + return ans + + __radd__ = __add__ + + def __sub__(self, other, context=None): + """Return self - other""" + other = _convert_other(other) + if other is NotImplemented: + return other + + if self._is_special or other._is_special: + ans = self._check_nans(other, context=context) + if ans: + return ans + + # self - other is computed as self + other.copy_negate() + return self.__add__(other.copy_negate(), context=context) + + def __rsub__(self, other, context=None): + """Return other - self""" + other = _convert_other(other) + if other is NotImplemented: + return other + + return other.__sub__(self, context=context) + + def __mul__(self, other, context=None): + """Return self * other. + + (+-) INF * 0 (or its reverse) raise InvalidOperation. + """ + other = _convert_other(other) + if other is NotImplemented: + return other + + if context is None: + context = getcontext() + + resultsign = self._sign ^ other._sign + + if self._is_special or other._is_special: + ans = self._check_nans(other, context) + if ans: + return ans + + if self._isinfinity(): + if not other: + return context._raise_error(InvalidOperation, '(+-)INF * 0') + return _SignedInfinity[resultsign] + + if other._isinfinity(): + if not self: + return context._raise_error(InvalidOperation, '0 * (+-)INF') + return _SignedInfinity[resultsign] + + resultexp = self._exp + other._exp + + # Special case for multiplying by zero + if not self or not other: + ans = _dec_from_triple(resultsign, '0', resultexp) + # Fixing in case the exponent is out of bounds + ans = ans._fix(context) + return ans + + # Special case for multiplying by power of 10 + if self._int == '1': + ans = _dec_from_triple(resultsign, other._int, resultexp) + ans = ans._fix(context) + return ans + if other._int == '1': + ans = _dec_from_triple(resultsign, self._int, resultexp) + ans = ans._fix(context) + return ans + + op1 = _WorkRep(self) + op2 = _WorkRep(other) + + ans = _dec_from_triple(resultsign, str(op1.int * op2.int), resultexp) + ans = ans._fix(context) + + return ans + __rmul__ = __mul__ + + def __truediv__(self, other, context=None): + """Return self / other.""" + other = _convert_other(other) + if other is NotImplemented: + return NotImplemented + + if context is None: + context = getcontext() + + sign = self._sign ^ other._sign + + if self._is_special or other._is_special: + ans = self._check_nans(other, context) + if ans: + return ans + + if self._isinfinity() and other._isinfinity(): + return context._raise_error(InvalidOperation, '(+-)INF/(+-)INF') + + if self._isinfinity(): + return _SignedInfinity[sign] + + if other._isinfinity(): + context._raise_error(Clamped, 'Division by infinity') + return _dec_from_triple(sign, '0', context.Etiny()) + + # Special cases for zeroes + if not other: + if not self: + return context._raise_error(DivisionUndefined, '0 / 0') + return context._raise_error(DivisionByZero, 'x / 0', sign) + + if not self: + exp = self._exp - other._exp + coeff = 0 + else: + # OK, so neither = 0, INF or NaN + shift = len(other._int) - len(self._int) + context.prec + 1 + exp = self._exp - other._exp - shift + op1 = _WorkRep(self) + op2 = _WorkRep(other) + if shift >= 0: + coeff, remainder = divmod(op1.int * 10**shift, op2.int) + else: + coeff, remainder = divmod(op1.int, op2.int * 10**-shift) + if remainder: + # result is not exact; adjust to ensure correct rounding + if coeff % 5 == 0: + coeff += 1 + else: + # result is exact; get as close to ideal exponent as possible + ideal_exp = self._exp - other._exp + while exp < ideal_exp and coeff % 10 == 0: + coeff //= 10 + exp += 1 + + ans = _dec_from_triple(sign, str(coeff), exp) + return ans._fix(context) + + def _divide(self, other, context): + """Return (self // other, self % other), to context.prec precision. + + Assumes that neither self nor other is a NaN, that self is not + infinite and that other is nonzero. + """ + sign = self._sign ^ other._sign + if other._isinfinity(): + ideal_exp = self._exp + else: + ideal_exp = min(self._exp, other._exp) + + expdiff = self.adjusted() - other.adjusted() + if not self or other._isinfinity() or expdiff <= -2: + return (_dec_from_triple(sign, '0', 0), + self._rescale(ideal_exp, context.rounding)) + if expdiff <= context.prec: + op1 = _WorkRep(self) + op2 = _WorkRep(other) + if op1.exp >= op2.exp: + op1.int *= 10**(op1.exp - op2.exp) + else: + op2.int *= 10**(op2.exp - op1.exp) + q, r = divmod(op1.int, op2.int) + if q < 10**context.prec: + return (_dec_from_triple(sign, str(q), 0), + _dec_from_triple(self._sign, str(r), ideal_exp)) + + # Here the quotient is too large to be representable + ans = context._raise_error(DivisionImpossible, + 'quotient too large in //, % or divmod') + return ans, ans + + def __rtruediv__(self, other, context=None): + """Swaps self/other and returns __truediv__.""" + other = _convert_other(other) + if other is NotImplemented: + return other + return other.__truediv__(self, context=context) + + def __divmod__(self, other, context=None): + """ + Return (self // other, self % other) + """ + other = _convert_other(other) + if other is NotImplemented: + return other + + if context is None: + context = getcontext() + + ans = self._check_nans(other, context) + if ans: + return (ans, ans) + + sign = self._sign ^ other._sign + if self._isinfinity(): + if other._isinfinity(): + ans = context._raise_error(InvalidOperation, 'divmod(INF, INF)') + return ans, ans + else: + return (_SignedInfinity[sign], + context._raise_error(InvalidOperation, 'INF % x')) + + if not other: + if not self: + ans = context._raise_error(DivisionUndefined, 'divmod(0, 0)') + return ans, ans + else: + return (context._raise_error(DivisionByZero, 'x // 0', sign), + context._raise_error(InvalidOperation, 'x % 0')) + + quotient, remainder = self._divide(other, context) + remainder = remainder._fix(context) + return quotient, remainder + + def __rdivmod__(self, other, context=None): + """Swaps self/other and returns __divmod__.""" + other = _convert_other(other) + if other is NotImplemented: + return other + return other.__divmod__(self, context=context) + + def __mod__(self, other, context=None): + """ + self % other + """ + other = _convert_other(other) + if other is NotImplemented: + return other + + if context is None: + context = getcontext() + + ans = self._check_nans(other, context) + if ans: + return ans + + if self._isinfinity(): + return context._raise_error(InvalidOperation, 'INF % x') + elif not other: + if self: + return context._raise_error(InvalidOperation, 'x % 0') + else: + return context._raise_error(DivisionUndefined, '0 % 0') + + remainder = self._divide(other, context)[1] + remainder = remainder._fix(context) + return remainder + + def __rmod__(self, other, context=None): + """Swaps self/other and returns __mod__.""" + other = _convert_other(other) + if other is NotImplemented: + return other + return other.__mod__(self, context=context) + + def remainder_near(self, other, context=None): + """ + Remainder nearest to 0- abs(remainder-near) <= other/2 + """ + if context is None: + context = getcontext() + + other = _convert_other(other, raiseit=True) + + ans = self._check_nans(other, context) + if ans: + return ans + + # self == +/-infinity -> InvalidOperation + if self._isinfinity(): + return context._raise_error(InvalidOperation, + 'remainder_near(infinity, x)') + + # other == 0 -> either InvalidOperation or DivisionUndefined + if not other: + if self: + return context._raise_error(InvalidOperation, + 'remainder_near(x, 0)') + else: + return context._raise_error(DivisionUndefined, + 'remainder_near(0, 0)') + + # other = +/-infinity -> remainder = self + if other._isinfinity(): + ans = Decimal(self) + return ans._fix(context) + + # self = 0 -> remainder = self, with ideal exponent + ideal_exponent = min(self._exp, other._exp) + if not self: + ans = _dec_from_triple(self._sign, '0', ideal_exponent) + return ans._fix(context) + + # catch most cases of large or small quotient + expdiff = self.adjusted() - other.adjusted() + if expdiff >= context.prec + 1: + # expdiff >= prec+1 => abs(self/other) > 10**prec + return context._raise_error(DivisionImpossible) + if expdiff <= -2: + # expdiff <= -2 => abs(self/other) < 0.1 + ans = self._rescale(ideal_exponent, context.rounding) + return ans._fix(context) + + # adjust both arguments to have the same exponent, then divide + op1 = _WorkRep(self) + op2 = _WorkRep(other) + if op1.exp >= op2.exp: + op1.int *= 10**(op1.exp - op2.exp) + else: + op2.int *= 10**(op2.exp - op1.exp) + q, r = divmod(op1.int, op2.int) + # remainder is r*10**ideal_exponent; other is +/-op2.int * + # 10**ideal_exponent. Apply correction to ensure that + # abs(remainder) <= abs(other)/2 + if 2*r + (q&1) > op2.int: + r -= op2.int + q += 1 + + if q >= 10**context.prec: + return context._raise_error(DivisionImpossible) + + # result has same sign as self unless r is negative + sign = self._sign + if r < 0: + sign = 1-sign + r = -r + + ans = _dec_from_triple(sign, str(r), ideal_exponent) + return ans._fix(context) + + def __floordiv__(self, other, context=None): + """self // other""" + other = _convert_other(other) + if other is NotImplemented: + return other + + if context is None: + context = getcontext() + + ans = self._check_nans(other, context) + if ans: + return ans + + if self._isinfinity(): + if other._isinfinity(): + return context._raise_error(InvalidOperation, 'INF // INF') + else: + return _SignedInfinity[self._sign ^ other._sign] + + if not other: + if self: + return context._raise_error(DivisionByZero, 'x // 0', + self._sign ^ other._sign) + else: + return context._raise_error(DivisionUndefined, '0 // 0') + + return self._divide(other, context)[0] + + def __rfloordiv__(self, other, context=None): + """Swaps self/other and returns __floordiv__.""" + other = _convert_other(other) + if other is NotImplemented: + return other + return other.__floordiv__(self, context=context) + + def __float__(self): + """Float representation.""" + if self._isnan(): + if self.is_snan(): + raise ValueError("Cannot convert signaling NaN to float") + s = "-nan" if self._sign else "nan" + else: + s = str(self) + return float(s) + + def __int__(self): + """Converts self to an int, truncating if necessary.""" + if self._is_special: + if self._isnan(): + raise ValueError("Cannot convert NaN to integer") + elif self._isinfinity(): + raise OverflowError("Cannot convert infinity to integer") + s = (-1)**self._sign + if self._exp >= 0: + return s*int(self._int)*10**self._exp + else: + return s*int(self._int[:self._exp] or '0') + + __trunc__ = __int__ + + def real(self): + return self + real = property(real) + + def imag(self): + return Decimal(0) + imag = property(imag) + + def conjugate(self): + return self + + def __complex__(self): + return complex(float(self)) + + def _fix_nan(self, context): + """Decapitate the payload of a NaN to fit the context""" + payload = self._int + + # maximum length of payload is precision if clamp=0, + # precision-1 if clamp=1. + max_payload_len = context.prec - context.clamp + if len(payload) > max_payload_len: + payload = payload[len(payload)-max_payload_len:].lstrip('0') + return _dec_from_triple(self._sign, payload, self._exp, True) + return Decimal(self) + + def _fix(self, context): + """Round if it is necessary to keep self within prec precision. + + Rounds and fixes the exponent. Does not raise on a sNaN. + + Arguments: + self - Decimal instance + context - context used. + """ + + if self._is_special: + if self._isnan(): + # decapitate payload if necessary + return self._fix_nan(context) + else: + # self is +/-Infinity; return unaltered + return Decimal(self) + + # if self is zero then exponent should be between Etiny and + # Emax if clamp==0, and between Etiny and Etop if clamp==1. + Etiny = context.Etiny() + Etop = context.Etop() + if not self: + exp_max = [context.Emax, Etop][context.clamp] + new_exp = min(max(self._exp, Etiny), exp_max) + if new_exp != self._exp: + context._raise_error(Clamped) + return _dec_from_triple(self._sign, '0', new_exp) + else: + return Decimal(self) + + # exp_min is the smallest allowable exponent of the result, + # equal to max(self.adjusted()-context.prec+1, Etiny) + exp_min = len(self._int) + self._exp - context.prec + if exp_min > Etop: + # overflow: exp_min > Etop iff self.adjusted() > Emax + ans = context._raise_error(Overflow, 'above Emax', self._sign) + context._raise_error(Inexact) + context._raise_error(Rounded) + return ans + + self_is_subnormal = exp_min < Etiny + if self_is_subnormal: + exp_min = Etiny + + # round if self has too many digits + if self._exp < exp_min: + digits = len(self._int) + self._exp - exp_min + if digits < 0: + self = _dec_from_triple(self._sign, '1', exp_min-1) + digits = 0 + rounding_method = self._pick_rounding_function[context.rounding] + changed = rounding_method(self, digits) + coeff = self._int[:digits] or '0' + if changed > 0: + coeff = str(int(coeff)+1) + if len(coeff) > context.prec: + coeff = coeff[:-1] + exp_min += 1 + + # check whether the rounding pushed the exponent out of range + if exp_min > Etop: + ans = context._raise_error(Overflow, 'above Emax', self._sign) + else: + ans = _dec_from_triple(self._sign, coeff, exp_min) + + # raise the appropriate signals, taking care to respect + # the precedence described in the specification + if changed and self_is_subnormal: + context._raise_error(Underflow) + if self_is_subnormal: + context._raise_error(Subnormal) + if changed: + context._raise_error(Inexact) + context._raise_error(Rounded) + if not ans: + # raise Clamped on underflow to 0 + context._raise_error(Clamped) + return ans + + if self_is_subnormal: + context._raise_error(Subnormal) + + # fold down if clamp == 1 and self has too few digits + if context.clamp == 1 and self._exp > Etop: + context._raise_error(Clamped) + self_padded = self._int + '0'*(self._exp - Etop) + return _dec_from_triple(self._sign, self_padded, Etop) + + # here self was representable to begin with; return unchanged + return Decimal(self) + + # for each of the rounding functions below: + # self is a finite, nonzero Decimal + # prec is an integer satisfying 0 <= prec < len(self._int) + # + # each function returns either -1, 0, or 1, as follows: + # 1 indicates that self should be rounded up (away from zero) + # 0 indicates that self should be truncated, and that all the + # digits to be truncated are zeros (so the value is unchanged) + # -1 indicates that there are nonzero digits to be truncated + + def _round_down(self, prec): + """Also known as round-towards-0, truncate.""" + if _all_zeros(self._int, prec): + return 0 + else: + return -1 + + def _round_up(self, prec): + """Rounds away from 0.""" + return -self._round_down(prec) + + def _round_half_up(self, prec): + """Rounds 5 up (away from 0)""" + if self._int[prec] in '56789': + return 1 + elif _all_zeros(self._int, prec): + return 0 + else: + return -1 + + def _round_half_down(self, prec): + """Round 5 down""" + if _exact_half(self._int, prec): + return -1 + else: + return self._round_half_up(prec) + + def _round_half_even(self, prec): + """Round 5 to even, rest to nearest.""" + if _exact_half(self._int, prec) and \ + (prec == 0 or self._int[prec-1] in '02468'): + return -1 + else: + return self._round_half_up(prec) + + def _round_ceiling(self, prec): + """Rounds up (not away from 0 if negative.)""" + if self._sign: + return self._round_down(prec) + else: + return -self._round_down(prec) + + def _round_floor(self, prec): + """Rounds down (not towards 0 if negative)""" + if not self._sign: + return self._round_down(prec) + else: + return -self._round_down(prec) + + def _round_05up(self, prec): + """Round down unless digit prec-1 is 0 or 5.""" + if prec and self._int[prec-1] not in '05': + return self._round_down(prec) + else: + return -self._round_down(prec) + + _pick_rounding_function = dict( + ROUND_DOWN = _round_down, + ROUND_UP = _round_up, + ROUND_HALF_UP = _round_half_up, + ROUND_HALF_DOWN = _round_half_down, + ROUND_HALF_EVEN = _round_half_even, + ROUND_CEILING = _round_ceiling, + ROUND_FLOOR = _round_floor, + ROUND_05UP = _round_05up, + ) + + def __round__(self, n=None): + """Round self to the nearest integer, or to a given precision. + + If only one argument is supplied, round a finite Decimal + instance self to the nearest integer. If self is infinite or + a NaN then a Python exception is raised. If self is finite + and lies exactly halfway between two integers then it is + rounded to the integer with even last digit. + + >>> round(Decimal('123.456')) + 123 + >>> round(Decimal('-456.789')) + -457 + >>> round(Decimal('-3.0')) + -3 + >>> round(Decimal('2.5')) + 2 + >>> round(Decimal('3.5')) + 4 + >>> round(Decimal('Inf')) + Traceback (most recent call last): + ... + OverflowError: cannot round an infinity + >>> round(Decimal('NaN')) + Traceback (most recent call last): + ... + ValueError: cannot round a NaN + + If a second argument n is supplied, self is rounded to n + decimal places using the rounding mode for the current + context. + + For an integer n, round(self, -n) is exactly equivalent to + self.quantize(Decimal('1En')). + + >>> round(Decimal('123.456'), 0) + Decimal('123') + >>> round(Decimal('123.456'), 2) + Decimal('123.46') + >>> round(Decimal('123.456'), -2) + Decimal('1E+2') + >>> round(Decimal('-Infinity'), 37) + Decimal('NaN') + >>> round(Decimal('sNaN123'), 0) + Decimal('NaN123') + + """ + if n is not None: + # two-argument form: use the equivalent quantize call + if not isinstance(n, int): + raise TypeError('Second argument to round should be integral') + exp = _dec_from_triple(0, '1', -n) + return self.quantize(exp) + + # one-argument form + if self._is_special: + if self.is_nan(): + raise ValueError("cannot round a NaN") + else: + raise OverflowError("cannot round an infinity") + return int(self._rescale(0, ROUND_HALF_EVEN)) + + def __floor__(self): + """Return the floor of self, as an integer. + + For a finite Decimal instance self, return the greatest + integer n such that n <= self. If self is infinite or a NaN + then a Python exception is raised. + + """ + if self._is_special: + if self.is_nan(): + raise ValueError("cannot round a NaN") + else: + raise OverflowError("cannot round an infinity") + return int(self._rescale(0, ROUND_FLOOR)) + + def __ceil__(self): + """Return the ceiling of self, as an integer. + + For a finite Decimal instance self, return the least integer n + such that n >= self. If self is infinite or a NaN then a + Python exception is raised. + + """ + if self._is_special: + if self.is_nan(): + raise ValueError("cannot round a NaN") + else: + raise OverflowError("cannot round an infinity") + return int(self._rescale(0, ROUND_CEILING)) + + def fma(self, other, third, context=None): + """Fused multiply-add. + + Returns self*other+third with no rounding of the intermediate + product self*other. + + self and other are multiplied together, with no rounding of + the result. The third operand is then added to the result, + and a single final rounding is performed. + """ + + other = _convert_other(other, raiseit=True) + third = _convert_other(third, raiseit=True) + + # compute product; raise InvalidOperation if either operand is + # a signaling NaN or if the product is zero times infinity. + if self._is_special or other._is_special: + if context is None: + context = getcontext() + if self._exp == 'N': + return context._raise_error(InvalidOperation, 'sNaN', self) + if other._exp == 'N': + return context._raise_error(InvalidOperation, 'sNaN', other) + if self._exp == 'n': + product = self + elif other._exp == 'n': + product = other + elif self._exp == 'F': + if not other: + return context._raise_error(InvalidOperation, + 'INF * 0 in fma') + product = _SignedInfinity[self._sign ^ other._sign] + elif other._exp == 'F': + if not self: + return context._raise_error(InvalidOperation, + '0 * INF in fma') + product = _SignedInfinity[self._sign ^ other._sign] + else: + product = _dec_from_triple(self._sign ^ other._sign, + str(int(self._int) * int(other._int)), + self._exp + other._exp) + + return product.__add__(third, context) + + def _power_modulo(self, other, modulo, context=None): + """Three argument version of __pow__""" + + other = _convert_other(other) + if other is NotImplemented: + return other + modulo = _convert_other(modulo) + if modulo is NotImplemented: + return modulo + + if context is None: + context = getcontext() + + # deal with NaNs: if there are any sNaNs then first one wins, + # (i.e. behaviour for NaNs is identical to that of fma) + self_is_nan = self._isnan() + other_is_nan = other._isnan() + modulo_is_nan = modulo._isnan() + if self_is_nan or other_is_nan or modulo_is_nan: + if self_is_nan == 2: + return context._raise_error(InvalidOperation, 'sNaN', + self) + if other_is_nan == 2: + return context._raise_error(InvalidOperation, 'sNaN', + other) + if modulo_is_nan == 2: + return context._raise_error(InvalidOperation, 'sNaN', + modulo) + if self_is_nan: + return self._fix_nan(context) + if other_is_nan: + return other._fix_nan(context) + return modulo._fix_nan(context) + + # check inputs: we apply same restrictions as Python's pow() + if not (self._isinteger() and + other._isinteger() and + modulo._isinteger()): + return context._raise_error(InvalidOperation, + 'pow() 3rd argument not allowed ' + 'unless all arguments are integers') + if other < 0: + return context._raise_error(InvalidOperation, + 'pow() 2nd argument cannot be ' + 'negative when 3rd argument specified') + if not modulo: + return context._raise_error(InvalidOperation, + 'pow() 3rd argument cannot be 0') + + # additional restriction for decimal: the modulus must be less + # than 10**prec in absolute value + if modulo.adjusted() >= context.prec: + return context._raise_error(InvalidOperation, + 'insufficient precision: pow() 3rd ' + 'argument must not have more than ' + 'precision digits') + + # define 0**0 == NaN, for consistency with two-argument pow + # (even though it hurts!) + if not other and not self: + return context._raise_error(InvalidOperation, + 'at least one of pow() 1st argument ' + 'and 2nd argument must be nonzero ;' + '0**0 is not defined') + + # compute sign of result + if other._iseven(): + sign = 0 + else: + sign = self._sign + + # convert modulo to a Python integer, and self and other to + # Decimal integers (i.e. force their exponents to be >= 0) + modulo = abs(int(modulo)) + base = _WorkRep(self.to_integral_value()) + exponent = _WorkRep(other.to_integral_value()) + + # compute result using integer pow() + base = (base.int % modulo * pow(10, base.exp, modulo)) % modulo + for i in range(exponent.exp): + base = pow(base, 10, modulo) + base = pow(base, exponent.int, modulo) + + return _dec_from_triple(sign, str(base), 0) + + def _power_exact(self, other, p): + """Attempt to compute self**other exactly. + + Given Decimals self and other and an integer p, attempt to + compute an exact result for the power self**other, with p + digits of precision. Return None if self**other is not + exactly representable in p digits. + + Assumes that elimination of special cases has already been + performed: self and other must both be nonspecial; self must + be positive and not numerically equal to 1; other must be + nonzero. For efficiency, other._exp should not be too large, + so that 10**abs(other._exp) is a feasible calculation.""" + + # In the comments below, we write x for the value of self and y for the + # value of other. Write x = xc*10**xe and abs(y) = yc*10**ye, with xc + # and yc positive integers not divisible by 10. + + # The main purpose of this method is to identify the *failure* + # of x**y to be exactly representable with as little effort as + # possible. So we look for cheap and easy tests that + # eliminate the possibility of x**y being exact. Only if all + # these tests are passed do we go on to actually compute x**y. + + # Here's the main idea. Express y as a rational number m/n, with m and + # n relatively prime and n>0. Then for x**y to be exactly + # representable (at *any* precision), xc must be the nth power of a + # positive integer and xe must be divisible by n. If y is negative + # then additionally xc must be a power of either 2 or 5, hence a power + # of 2**n or 5**n. + # + # There's a limit to how small |y| can be: if y=m/n as above + # then: + # + # (1) if xc != 1 then for the result to be representable we + # need xc**(1/n) >= 2, and hence also xc**|y| >= 2. So + # if |y| <= 1/nbits(xc) then xc < 2**nbits(xc) <= + # 2**(1/|y|), hence xc**|y| < 2 and the result is not + # representable. + # + # (2) if xe != 0, |xe|*(1/n) >= 1, so |xe|*|y| >= 1. Hence if + # |y| < 1/|xe| then the result is not representable. + # + # Note that since x is not equal to 1, at least one of (1) and + # (2) must apply. Now |y| < 1/nbits(xc) iff |yc|*nbits(xc) < + # 10**-ye iff len(str(|yc|*nbits(xc)) <= -ye. + # + # There's also a limit to how large y can be, at least if it's + # positive: the normalized result will have coefficient xc**y, + # so if it's representable then xc**y < 10**p, and y < + # p/log10(xc). Hence if y*log10(xc) >= p then the result is + # not exactly representable. + + # if len(str(abs(yc*xe)) <= -ye then abs(yc*xe) < 10**-ye, + # so |y| < 1/xe and the result is not representable. + # Similarly, len(str(abs(yc)*xc_bits)) <= -ye implies |y| + # < 1/nbits(xc). + + x = _WorkRep(self) + xc, xe = x.int, x.exp + while xc % 10 == 0: + xc //= 10 + xe += 1 + + y = _WorkRep(other) + yc, ye = y.int, y.exp + while yc % 10 == 0: + yc //= 10 + ye += 1 + + # case where xc == 1: result is 10**(xe*y), with xe*y + # required to be an integer + if xc == 1: + xe *= yc + # result is now 10**(xe * 10**ye); xe * 10**ye must be integral + while xe % 10 == 0: + xe //= 10 + ye += 1 + if ye < 0: + return None + exponent = xe * 10**ye + if y.sign == 1: + exponent = -exponent + # if other is a nonnegative integer, use ideal exponent + if other._isinteger() and other._sign == 0: + ideal_exponent = self._exp*int(other) + zeros = min(exponent-ideal_exponent, p-1) + else: + zeros = 0 + return _dec_from_triple(0, '1' + '0'*zeros, exponent-zeros) + + # case where y is negative: xc must be either a power + # of 2 or a power of 5. + if y.sign == 1: + last_digit = xc % 10 + if last_digit in (2,4,6,8): + # quick test for power of 2 + if xc & -xc != xc: + return None + # now xc is a power of 2; e is its exponent + e = _nbits(xc)-1 + + # We now have: + # + # x = 2**e * 10**xe, e > 0, and y < 0. + # + # The exact result is: + # + # x**y = 5**(-e*y) * 10**(e*y + xe*y) + # + # provided that both e*y and xe*y are integers. Note that if + # 5**(-e*y) >= 10**p, then the result can't be expressed + # exactly with p digits of precision. + # + # Using the above, we can guard against large values of ye. + # 93/65 is an upper bound for log(10)/log(5), so if + # + # ye >= len(str(93*p//65)) + # + # then + # + # -e*y >= -y >= 10**ye > 93*p/65 > p*log(10)/log(5), + # + # so 5**(-e*y) >= 10**p, and the coefficient of the result + # can't be expressed in p digits. + + # emax >= largest e such that 5**e < 10**p. + emax = p*93//65 + if ye >= len(str(emax)): + return None + + # Find -e*y and -xe*y; both must be integers + e = _decimal_lshift_exact(e * yc, ye) + xe = _decimal_lshift_exact(xe * yc, ye) + if e is None or xe is None: + return None + + if e > emax: + return None + xc = 5**e + + elif last_digit == 5: + # e >= log_5(xc) if xc is a power of 5; we have + # equality all the way up to xc=5**2658 + e = _nbits(xc)*28//65 + xc, remainder = divmod(5**e, xc) + if remainder: + return None + while xc % 5 == 0: + xc //= 5 + e -= 1 + + # Guard against large values of ye, using the same logic as in + # the 'xc is a power of 2' branch. 10/3 is an upper bound for + # log(10)/log(2). + emax = p*10//3 + if ye >= len(str(emax)): + return None + + e = _decimal_lshift_exact(e * yc, ye) + xe = _decimal_lshift_exact(xe * yc, ye) + if e is None or xe is None: + return None + + if e > emax: + return None + xc = 2**e + else: + return None + + if xc >= 10**p: + return None + xe = -e-xe + return _dec_from_triple(0, str(xc), xe) + + # now y is positive; find m and n such that y = m/n + if ye >= 0: + m, n = yc*10**ye, 1 + else: + if xe != 0 and len(str(abs(yc*xe))) <= -ye: + return None + xc_bits = _nbits(xc) + if xc != 1 and len(str(abs(yc)*xc_bits)) <= -ye: + return None + m, n = yc, 10**(-ye) + while m % 2 == n % 2 == 0: + m //= 2 + n //= 2 + while m % 5 == n % 5 == 0: + m //= 5 + n //= 5 + + # compute nth root of xc*10**xe + if n > 1: + # if 1 < xc < 2**n then xc isn't an nth power + if xc != 1 and xc_bits <= n: + return None + + xe, rem = divmod(xe, n) + if rem != 0: + return None + + # compute nth root of xc using Newton's method + a = 1 << -(-_nbits(xc)//n) # initial estimate + while True: + q, r = divmod(xc, a**(n-1)) + if a <= q: + break + else: + a = (a*(n-1) + q)//n + if not (a == q and r == 0): + return None + xc = a + + # now xc*10**xe is the nth root of the original xc*10**xe + # compute mth power of xc*10**xe + + # if m > p*100//_log10_lb(xc) then m > p/log10(xc), hence xc**m > + # 10**p and the result is not representable. + if xc > 1 and m > p*100//_log10_lb(xc): + return None + xc = xc**m + xe *= m + if xc > 10**p: + return None + + # by this point the result *is* exactly representable + # adjust the exponent to get as close as possible to the ideal + # exponent, if necessary + str_xc = str(xc) + if other._isinteger() and other._sign == 0: + ideal_exponent = self._exp*int(other) + zeros = min(xe-ideal_exponent, p-len(str_xc)) + else: + zeros = 0 + return _dec_from_triple(0, str_xc+'0'*zeros, xe-zeros) + + def __pow__(self, other, modulo=None, context=None): + """Return self ** other [ % modulo]. + + With two arguments, compute self**other. + + With three arguments, compute (self**other) % modulo. For the + three argument form, the following restrictions on the + arguments hold: + + - all three arguments must be integral + - other must be nonnegative + - either self or other (or both) must be nonzero + - modulo must be nonzero and must have at most p digits, + where p is the context precision. + + If any of these restrictions is violated the InvalidOperation + flag is raised. + + The result of pow(self, other, modulo) is identical to the + result that would be obtained by computing (self**other) % + modulo with unbounded precision, but is computed more + efficiently. It is always exact. + """ + + if modulo is not None: + return self._power_modulo(other, modulo, context) + + other = _convert_other(other) + if other is NotImplemented: + return other + + if context is None: + context = getcontext() + + # either argument is a NaN => result is NaN + ans = self._check_nans(other, context) + if ans: + return ans + + # 0**0 = NaN (!), x**0 = 1 for nonzero x (including +/-Infinity) + if not other: + if not self: + return context._raise_error(InvalidOperation, '0 ** 0') + else: + return _One + + # result has sign 1 iff self._sign is 1 and other is an odd integer + result_sign = 0 + if self._sign == 1: + if other._isinteger(): + if not other._iseven(): + result_sign = 1 + else: + # -ve**noninteger = NaN + # (-0)**noninteger = 0**noninteger + if self: + return context._raise_error(InvalidOperation, + 'x ** y with x negative and y not an integer') + # negate self, without doing any unwanted rounding + self = self.copy_negate() + + # 0**(+ve or Inf)= 0; 0**(-ve or -Inf) = Infinity + if not self: + if other._sign == 0: + return _dec_from_triple(result_sign, '0', 0) + else: + return _SignedInfinity[result_sign] + + # Inf**(+ve or Inf) = Inf; Inf**(-ve or -Inf) = 0 + if self._isinfinity(): + if other._sign == 0: + return _SignedInfinity[result_sign] + else: + return _dec_from_triple(result_sign, '0', 0) + + # 1**other = 1, but the choice of exponent and the flags + # depend on the exponent of self, and on whether other is a + # positive integer, a negative integer, or neither + if self == _One: + if other._isinteger(): + # exp = max(self._exp*max(int(other), 0), + # 1-context.prec) but evaluating int(other) directly + # is dangerous until we know other is small (other + # could be 1e999999999) + if other._sign == 1: + multiplier = 0 + elif other > context.prec: + multiplier = context.prec + else: + multiplier = int(other) + + exp = self._exp * multiplier + if exp < 1-context.prec: + exp = 1-context.prec + context._raise_error(Rounded) + else: + context._raise_error(Inexact) + context._raise_error(Rounded) + exp = 1-context.prec + + return _dec_from_triple(result_sign, '1'+'0'*-exp, exp) + + # compute adjusted exponent of self + self_adj = self.adjusted() + + # self ** infinity is infinity if self > 1, 0 if self < 1 + # self ** -infinity is infinity if self < 1, 0 if self > 1 + if other._isinfinity(): + if (other._sign == 0) == (self_adj < 0): + return _dec_from_triple(result_sign, '0', 0) + else: + return _SignedInfinity[result_sign] + + # from here on, the result always goes through the call + # to _fix at the end of this function. + ans = None + exact = False + + # crude test to catch cases of extreme overflow/underflow. If + # log10(self)*other >= 10**bound and bound >= len(str(Emax)) + # then 10**bound >= 10**len(str(Emax)) >= Emax+1 and hence + # self**other >= 10**(Emax+1), so overflow occurs. The test + # for underflow is similar. + bound = self._log10_exp_bound() + other.adjusted() + if (self_adj >= 0) == (other._sign == 0): + # self > 1 and other +ve, or self < 1 and other -ve + # possibility of overflow + if bound >= len(str(context.Emax)): + ans = _dec_from_triple(result_sign, '1', context.Emax+1) + else: + # self > 1 and other -ve, or self < 1 and other +ve + # possibility of underflow to 0 + Etiny = context.Etiny() + if bound >= len(str(-Etiny)): + ans = _dec_from_triple(result_sign, '1', Etiny-1) + + # try for an exact result with precision +1 + if ans is None: + ans = self._power_exact(other, context.prec + 1) + if ans is not None: + if result_sign == 1: + ans = _dec_from_triple(1, ans._int, ans._exp) + exact = True + + # usual case: inexact result, x**y computed directly as exp(y*log(x)) + if ans is None: + p = context.prec + x = _WorkRep(self) + xc, xe = x.int, x.exp + y = _WorkRep(other) + yc, ye = y.int, y.exp + if y.sign == 1: + yc = -yc + + # compute correctly rounded result: start with precision +3, + # then increase precision until result is unambiguously roundable + extra = 3 + while True: + coeff, exp = _dpower(xc, xe, yc, ye, p+extra) + if coeff % (5*10**(len(str(coeff))-p-1)): + break + extra += 3 + + ans = _dec_from_triple(result_sign, str(coeff), exp) + + # unlike exp, ln and log10, the power function respects the + # rounding mode; no need to switch to ROUND_HALF_EVEN here + + # There's a difficulty here when 'other' is not an integer and + # the result is exact. In this case, the specification + # requires that the Inexact flag be raised (in spite of + # exactness), but since the result is exact _fix won't do this + # for us. (Correspondingly, the Underflow signal should also + # be raised for subnormal results.) We can't directly raise + # these signals either before or after calling _fix, since + # that would violate the precedence for signals. So we wrap + # the ._fix call in a temporary context, and reraise + # afterwards. + if exact and not other._isinteger(): + # pad with zeros up to length context.prec+1 if necessary; this + # ensures that the Rounded signal will be raised. + if len(ans._int) <= context.prec: + expdiff = context.prec + 1 - len(ans._int) + ans = _dec_from_triple(ans._sign, ans._int+'0'*expdiff, + ans._exp-expdiff) + + # create a copy of the current context, with cleared flags/traps + newcontext = context.copy() + newcontext.clear_flags() + for exception in _signals: + newcontext.traps[exception] = 0 + + # round in the new context + ans = ans._fix(newcontext) + + # raise Inexact, and if necessary, Underflow + newcontext._raise_error(Inexact) + if newcontext.flags[Subnormal]: + newcontext._raise_error(Underflow) + + # propagate signals to the original context; _fix could + # have raised any of Overflow, Underflow, Subnormal, + # Inexact, Rounded, Clamped. Overflow needs the correct + # arguments. Note that the order of the exceptions is + # important here. + if newcontext.flags[Overflow]: + context._raise_error(Overflow, 'above Emax', ans._sign) + for exception in Underflow, Subnormal, Inexact, Rounded, Clamped: + if newcontext.flags[exception]: + context._raise_error(exception) + + else: + ans = ans._fix(context) + + return ans + + def __rpow__(self, other, context=None): + """Swaps self/other and returns __pow__.""" + other = _convert_other(other) + if other is NotImplemented: + return other + return other.__pow__(self, context=context) + + def normalize(self, context=None): + """Normalize- strip trailing 0s, change anything equal to 0 to 0e0""" + + if context is None: + context = getcontext() + + if self._is_special: + ans = self._check_nans(context=context) + if ans: + return ans + + dup = self._fix(context) + if dup._isinfinity(): + return dup + + if not dup: + return _dec_from_triple(dup._sign, '0', 0) + exp_max = [context.Emax, context.Etop()][context.clamp] + end = len(dup._int) + exp = dup._exp + while dup._int[end-1] == '0' and exp < exp_max: + exp += 1 + end -= 1 + return _dec_from_triple(dup._sign, dup._int[:end], exp) + + def quantize(self, exp, rounding=None, context=None): + """Quantize self so its exponent is the same as that of exp. + + Similar to self._rescale(exp._exp) but with error checking. + """ + exp = _convert_other(exp, raiseit=True) + + if context is None: + context = getcontext() + if rounding is None: + rounding = context.rounding + + if self._is_special or exp._is_special: + ans = self._check_nans(exp, context) + if ans: + return ans + + if exp._isinfinity() or self._isinfinity(): + if exp._isinfinity() and self._isinfinity(): + return Decimal(self) # if both are inf, it is OK + return context._raise_error(InvalidOperation, + 'quantize with one INF') + + # exp._exp should be between Etiny and Emax + if not (context.Etiny() <= exp._exp <= context.Emax): + return context._raise_error(InvalidOperation, + 'target exponent out of bounds in quantize') + + if not self: + ans = _dec_from_triple(self._sign, '0', exp._exp) + return ans._fix(context) + + self_adjusted = self.adjusted() + if self_adjusted > context.Emax: + return context._raise_error(InvalidOperation, + 'exponent of quantize result too large for current context') + if self_adjusted - exp._exp + 1 > context.prec: + return context._raise_error(InvalidOperation, + 'quantize result has too many digits for current context') + + ans = self._rescale(exp._exp, rounding) + if ans.adjusted() > context.Emax: + return context._raise_error(InvalidOperation, + 'exponent of quantize result too large for current context') + if len(ans._int) > context.prec: + return context._raise_error(InvalidOperation, + 'quantize result has too many digits for current context') + + # raise appropriate flags + if ans and ans.adjusted() < context.Emin: + context._raise_error(Subnormal) + if ans._exp > self._exp: + if ans != self: + context._raise_error(Inexact) + context._raise_error(Rounded) + + # call to fix takes care of any necessary folddown, and + # signals Clamped if necessary + ans = ans._fix(context) + return ans + + def same_quantum(self, other, context=None): + """Return True if self and other have the same exponent; otherwise + return False. + + If either operand is a special value, the following rules are used: + * return True if both operands are infinities + * return True if both operands are NaNs + * otherwise, return False. + """ + other = _convert_other(other, raiseit=True) + if self._is_special or other._is_special: + return (self.is_nan() and other.is_nan() or + self.is_infinite() and other.is_infinite()) + return self._exp == other._exp + + def _rescale(self, exp, rounding): + """Rescale self so that the exponent is exp, either by padding with zeros + or by truncating digits, using the given rounding mode. + + Specials are returned without change. This operation is + quiet: it raises no flags, and uses no information from the + context. + + exp = exp to scale to (an integer) + rounding = rounding mode + """ + if self._is_special: + return Decimal(self) + if not self: + return _dec_from_triple(self._sign, '0', exp) + + if self._exp >= exp: + # pad answer with zeros if necessary + return _dec_from_triple(self._sign, + self._int + '0'*(self._exp - exp), exp) + + # too many digits; round and lose data. If self.adjusted() < + # exp-1, replace self by 10**(exp-1) before rounding + digits = len(self._int) + self._exp - exp + if digits < 0: + self = _dec_from_triple(self._sign, '1', exp-1) + digits = 0 + this_function = self._pick_rounding_function[rounding] + changed = this_function(self, digits) + coeff = self._int[:digits] or '0' + if changed == 1: + coeff = str(int(coeff)+1) + return _dec_from_triple(self._sign, coeff, exp) + + def _round(self, places, rounding): + """Round a nonzero, nonspecial Decimal to a fixed number of + significant figures, using the given rounding mode. + + Infinities, NaNs and zeros are returned unaltered. + + This operation is quiet: it raises no flags, and uses no + information from the context. + + """ + if places <= 0: + raise ValueError("argument should be at least 1 in _round") + if self._is_special or not self: + return Decimal(self) + ans = self._rescale(self.adjusted()+1-places, rounding) + # it can happen that the rescale alters the adjusted exponent; + # for example when rounding 99.97 to 3 significant figures. + # When this happens we end up with an extra 0 at the end of + # the number; a second rescale fixes this. + if ans.adjusted() != self.adjusted(): + ans = ans._rescale(ans.adjusted()+1-places, rounding) + return ans + + def to_integral_exact(self, rounding=None, context=None): + """Rounds to a nearby integer. + + If no rounding mode is specified, take the rounding mode from + the context. This method raises the Rounded and Inexact flags + when appropriate. + + See also: to_integral_value, which does exactly the same as + this method except that it doesn't raise Inexact or Rounded. + """ + if self._is_special: + ans = self._check_nans(context=context) + if ans: + return ans + return Decimal(self) + if self._exp >= 0: + return Decimal(self) + if not self: + return _dec_from_triple(self._sign, '0', 0) + if context is None: + context = getcontext() + if rounding is None: + rounding = context.rounding + ans = self._rescale(0, rounding) + if ans != self: + context._raise_error(Inexact) + context._raise_error(Rounded) + return ans + + def to_integral_value(self, rounding=None, context=None): + """Rounds to the nearest integer, without raising inexact, rounded.""" + if context is None: + context = getcontext() + if rounding is None: + rounding = context.rounding + if self._is_special: + ans = self._check_nans(context=context) + if ans: + return ans + return Decimal(self) + if self._exp >= 0: + return Decimal(self) + else: + return self._rescale(0, rounding) + + # the method name changed, but we provide also the old one, for compatibility + to_integral = to_integral_value + + def sqrt(self, context=None): + """Return the square root of self.""" + if context is None: + context = getcontext() + + if self._is_special: + ans = self._check_nans(context=context) + if ans: + return ans + + if self._isinfinity() and self._sign == 0: + return Decimal(self) + + if not self: + # exponent = self._exp // 2. sqrt(-0) = -0 + ans = _dec_from_triple(self._sign, '0', self._exp // 2) + return ans._fix(context) + + if self._sign == 1: + return context._raise_error(InvalidOperation, 'sqrt(-x), x > 0') + + # At this point self represents a positive number. Let p be + # the desired precision and express self in the form c*100**e + # with c a positive real number and e an integer, c and e + # being chosen so that 100**(p-1) <= c < 100**p. Then the + # (exact) square root of self is sqrt(c)*10**e, and 10**(p-1) + # <= sqrt(c) < 10**p, so the closest representable Decimal at + # precision p is n*10**e where n = round_half_even(sqrt(c)), + # the closest integer to sqrt(c) with the even integer chosen + # in the case of a tie. + # + # To ensure correct rounding in all cases, we use the + # following trick: we compute the square root to an extra + # place (precision p+1 instead of precision p), rounding down. + # Then, if the result is inexact and its last digit is 0 or 5, + # we increase the last digit to 1 or 6 respectively; if it's + # exact we leave the last digit alone. Now the final round to + # p places (or fewer in the case of underflow) will round + # correctly and raise the appropriate flags. + + # use an extra digit of precision + prec = context.prec+1 + + # write argument in the form c*100**e where e = self._exp//2 + # is the 'ideal' exponent, to be used if the square root is + # exactly representable. l is the number of 'digits' of c in + # base 100, so that 100**(l-1) <= c < 100**l. + op = _WorkRep(self) + e = op.exp >> 1 + if op.exp & 1: + c = op.int * 10 + l = (len(self._int) >> 1) + 1 + else: + c = op.int + l = len(self._int)+1 >> 1 + + # rescale so that c has exactly prec base 100 'digits' + shift = prec-l + if shift >= 0: + c *= 100**shift + exact = True + else: + c, remainder = divmod(c, 100**-shift) + exact = not remainder + e -= shift + + # find n = floor(sqrt(c)) using Newton's method + n = 10**prec + while True: + q = c//n + if n <= q: + break + else: + n = n + q >> 1 + exact = exact and n*n == c + + if exact: + # result is exact; rescale to use ideal exponent e + if shift >= 0: + # assert n % 10**shift == 0 + n //= 10**shift + else: + n *= 10**-shift + e += shift + else: + # result is not exact; fix last digit as described above + if n % 5 == 0: + n += 1 + + ans = _dec_from_triple(0, str(n), e) + + # round, and fit to current context + context = context._shallow_copy() + rounding = context._set_rounding(ROUND_HALF_EVEN) + ans = ans._fix(context) + context.rounding = rounding + + return ans + + def max(self, other, context=None): + """Returns the larger value. + + Like max(self, other) except if one is not a number, returns + NaN (and signals if one is sNaN). Also rounds. + """ + other = _convert_other(other, raiseit=True) + + if context is None: + context = getcontext() + + if self._is_special or other._is_special: + # If one operand is a quiet NaN and the other is number, then the + # number is always returned + sn = self._isnan() + on = other._isnan() + if sn or on: + if on == 1 and sn == 0: + return self._fix(context) + if sn == 1 and on == 0: + return other._fix(context) + return self._check_nans(other, context) + + c = self._cmp(other) + if c == 0: + # If both operands are finite and equal in numerical value + # then an ordering is applied: + # + # If the signs differ then max returns the operand with the + # positive sign and min returns the operand with the negative sign + # + # If the signs are the same then the exponent is used to select + # the result. This is exactly the ordering used in compare_total. + c = self.compare_total(other) + + if c == -1: + ans = other + else: + ans = self + + return ans._fix(context) + + def min(self, other, context=None): + """Returns the smaller value. + + Like min(self, other) except if one is not a number, returns + NaN (and signals if one is sNaN). Also rounds. + """ + other = _convert_other(other, raiseit=True) + + if context is None: + context = getcontext() + + if self._is_special or other._is_special: + # If one operand is a quiet NaN and the other is number, then the + # number is always returned + sn = self._isnan() + on = other._isnan() + if sn or on: + if on == 1 and sn == 0: + return self._fix(context) + if sn == 1 and on == 0: + return other._fix(context) + return self._check_nans(other, context) + + c = self._cmp(other) + if c == 0: + c = self.compare_total(other) + + if c == -1: + ans = self + else: + ans = other + + return ans._fix(context) + + def _isinteger(self): + """Returns whether self is an integer""" + if self._is_special: + return False + if self._exp >= 0: + return True + rest = self._int[self._exp:] + return rest == '0'*len(rest) + + def _iseven(self): + """Returns True if self is even. Assumes self is an integer.""" + if not self or self._exp > 0: + return True + return self._int[-1+self._exp] in '02468' + + def adjusted(self): + """Return the adjusted exponent of self""" + try: + return self._exp + len(self._int) - 1 + # If NaN or Infinity, self._exp is string + except TypeError: + return 0 + + def canonical(self): + """Returns the same Decimal object. + + As we do not have different encodings for the same number, the + received object already is in its canonical form. + """ + return self + + def compare_signal(self, other, context=None): + """Compares self to the other operand numerically. + + It's pretty much like compare(), but all NaNs signal, with signaling + NaNs taking precedence over quiet NaNs. + """ + other = _convert_other(other, raiseit = True) + ans = self._compare_check_nans(other, context) + if ans: + return ans + return self.compare(other, context=context) + + def compare_total(self, other, context=None): + """Compares self to other using the abstract representations. + + This is not like the standard compare, which use their numerical + value. Note that a total ordering is defined for all possible abstract + representations. + """ + other = _convert_other(other, raiseit=True) + + # if one is negative and the other is positive, it's easy + if self._sign and not other._sign: + return _NegativeOne + if not self._sign and other._sign: + return _One + sign = self._sign + + # let's handle both NaN types + self_nan = self._isnan() + other_nan = other._isnan() + if self_nan or other_nan: + if self_nan == other_nan: + # compare payloads as though they're integers + self_key = len(self._int), self._int + other_key = len(other._int), other._int + if self_key < other_key: + if sign: + return _One + else: + return _NegativeOne + if self_key > other_key: + if sign: + return _NegativeOne + else: + return _One + return _Zero + + if sign: + if self_nan == 1: + return _NegativeOne + if other_nan == 1: + return _One + if self_nan == 2: + return _NegativeOne + if other_nan == 2: + return _One + else: + if self_nan == 1: + return _One + if other_nan == 1: + return _NegativeOne + if self_nan == 2: + return _One + if other_nan == 2: + return _NegativeOne + + if self < other: + return _NegativeOne + if self > other: + return _One + + if self._exp < other._exp: + if sign: + return _One + else: + return _NegativeOne + if self._exp > other._exp: + if sign: + return _NegativeOne + else: + return _One + return _Zero + + + def compare_total_mag(self, other, context=None): + """Compares self to other using abstract repr., ignoring sign. + + Like compare_total, but with operand's sign ignored and assumed to be 0. + """ + other = _convert_other(other, raiseit=True) + + s = self.copy_abs() + o = other.copy_abs() + return s.compare_total(o) + + def copy_abs(self): + """Returns a copy with the sign set to 0. """ + return _dec_from_triple(0, self._int, self._exp, self._is_special) + + def copy_negate(self): + """Returns a copy with the sign inverted.""" + if self._sign: + return _dec_from_triple(0, self._int, self._exp, self._is_special) + else: + return _dec_from_triple(1, self._int, self._exp, self._is_special) + + def copy_sign(self, other, context=None): + """Returns self with the sign of other.""" + other = _convert_other(other, raiseit=True) + return _dec_from_triple(other._sign, self._int, + self._exp, self._is_special) + + def exp(self, context=None): + """Returns e ** self.""" + + if context is None: + context = getcontext() + + # exp(NaN) = NaN + ans = self._check_nans(context=context) + if ans: + return ans + + # exp(-Infinity) = 0 + if self._isinfinity() == -1: + return _Zero + + # exp(0) = 1 + if not self: + return _One + + # exp(Infinity) = Infinity + if self._isinfinity() == 1: + return Decimal(self) + + # the result is now guaranteed to be inexact (the true + # mathematical result is transcendental). There's no need to + # raise Rounded and Inexact here---they'll always be raised as + # a result of the call to _fix. + p = context.prec + adj = self.adjusted() + + # we only need to do any computation for quite a small range + # of adjusted exponents---for example, -29 <= adj <= 10 for + # the default context. For smaller exponent the result is + # indistinguishable from 1 at the given precision, while for + # larger exponent the result either overflows or underflows. + if self._sign == 0 and adj > len(str((context.Emax+1)*3)): + # overflow + ans = _dec_from_triple(0, '1', context.Emax+1) + elif self._sign == 1 and adj > len(str((-context.Etiny()+1)*3)): + # underflow to 0 + ans = _dec_from_triple(0, '1', context.Etiny()-1) + elif self._sign == 0 and adj < -p: + # p+1 digits; final round will raise correct flags + ans = _dec_from_triple(0, '1' + '0'*(p-1) + '1', -p) + elif self._sign == 1 and adj < -p-1: + # p+1 digits; final round will raise correct flags + ans = _dec_from_triple(0, '9'*(p+1), -p-1) + # general case + else: + op = _WorkRep(self) + c, e = op.int, op.exp + if op.sign == 1: + c = -c + + # compute correctly rounded result: increase precision by + # 3 digits at a time until we get an unambiguously + # roundable result + extra = 3 + while True: + coeff, exp = _dexp(c, e, p+extra) + if coeff % (5*10**(len(str(coeff))-p-1)): + break + extra += 3 + + ans = _dec_from_triple(0, str(coeff), exp) + + # at this stage, ans should round correctly with *any* + # rounding mode, not just with ROUND_HALF_EVEN + context = context._shallow_copy() + rounding = context._set_rounding(ROUND_HALF_EVEN) + ans = ans._fix(context) + context.rounding = rounding + + return ans + + def is_canonical(self): + """Return True if self is canonical; otherwise return False. + + Currently, the encoding of a Decimal instance is always + canonical, so this method returns True for any Decimal. + """ + return True + + def is_finite(self): + """Return True if self is finite; otherwise return False. + + A Decimal instance is considered finite if it is neither + infinite nor a NaN. + """ + return not self._is_special + + def is_infinite(self): + """Return True if self is infinite; otherwise return False.""" + return self._exp == 'F' + + def is_nan(self): + """Return True if self is a qNaN or sNaN; otherwise return False.""" + return self._exp in ('n', 'N') + + def is_normal(self, context=None): + """Return True if self is a normal number; otherwise return False.""" + if self._is_special or not self: + return False + if context is None: + context = getcontext() + return context.Emin <= self.adjusted() + + def is_qnan(self): + """Return True if self is a quiet NaN; otherwise return False.""" + return self._exp == 'n' + + def is_signed(self): + """Return True if self is negative; otherwise return False.""" + return self._sign == 1 + + def is_snan(self): + """Return True if self is a signaling NaN; otherwise return False.""" + return self._exp == 'N' + + def is_subnormal(self, context=None): + """Return True if self is subnormal; otherwise return False.""" + if self._is_special or not self: + return False + if context is None: + context = getcontext() + return self.adjusted() < context.Emin + + def is_zero(self): + """Return True if self is a zero; otherwise return False.""" + return not self._is_special and self._int == '0' + + def _ln_exp_bound(self): + """Compute a lower bound for the adjusted exponent of self.ln(). + In other words, compute r such that self.ln() >= 10**r. Assumes + that self is finite and positive and that self != 1. + """ + + # for 0.1 <= x <= 10 we use the inequalities 1-1/x <= ln(x) <= x-1 + adj = self._exp + len(self._int) - 1 + if adj >= 1: + # argument >= 10; we use 23/10 = 2.3 as a lower bound for ln(10) + return len(str(adj*23//10)) - 1 + if adj <= -2: + # argument <= 0.1 + return len(str((-1-adj)*23//10)) - 1 + op = _WorkRep(self) + c, e = op.int, op.exp + if adj == 0: + # 1 < self < 10 + num = str(c-10**-e) + den = str(c) + return len(num) - len(den) - (num < den) + # adj == -1, 0.1 <= self < 1 + return e + len(str(10**-e - c)) - 1 + + + def ln(self, context=None): + """Returns the natural (base e) logarithm of self.""" + + if context is None: + context = getcontext() + + # ln(NaN) = NaN + ans = self._check_nans(context=context) + if ans: + return ans + + # ln(0.0) == -Infinity + if not self: + return _NegativeInfinity + + # ln(Infinity) = Infinity + if self._isinfinity() == 1: + return _Infinity + + # ln(1.0) == 0.0 + if self == _One: + return _Zero + + # ln(negative) raises InvalidOperation + if self._sign == 1: + return context._raise_error(InvalidOperation, + 'ln of a negative value') + + # result is irrational, so necessarily inexact + op = _WorkRep(self) + c, e = op.int, op.exp + p = context.prec + + # correctly rounded result: repeatedly increase precision by 3 + # until we get an unambiguously roundable result + places = p - self._ln_exp_bound() + 2 # at least p+3 places + while True: + coeff = _dlog(c, e, places) + # assert len(str(abs(coeff)))-p >= 1 + if coeff % (5*10**(len(str(abs(coeff)))-p-1)): + break + places += 3 + ans = _dec_from_triple(int(coeff<0), str(abs(coeff)), -places) + + context = context._shallow_copy() + rounding = context._set_rounding(ROUND_HALF_EVEN) + ans = ans._fix(context) + context.rounding = rounding + return ans + + def _log10_exp_bound(self): + """Compute a lower bound for the adjusted exponent of self.log10(). + In other words, find r such that self.log10() >= 10**r. + Assumes that self is finite and positive and that self != 1. + """ + + # For x >= 10 or x < 0.1 we only need a bound on the integer + # part of log10(self), and this comes directly from the + # exponent of x. For 0.1 <= x <= 10 we use the inequalities + # 1-1/x <= log(x) <= x-1. If x > 1 we have |log10(x)| > + # (1-1/x)/2.31 > 0. If x < 1 then |log10(x)| > (1-x)/2.31 > 0 + + adj = self._exp + len(self._int) - 1 + if adj >= 1: + # self >= 10 + return len(str(adj))-1 + if adj <= -2: + # self < 0.1 + return len(str(-1-adj))-1 + op = _WorkRep(self) + c, e = op.int, op.exp + if adj == 0: + # 1 < self < 10 + num = str(c-10**-e) + den = str(231*c) + return len(num) - len(den) - (num < den) + 2 + # adj == -1, 0.1 <= self < 1 + num = str(10**-e-c) + return len(num) + e - (num < "231") - 1 + + def log10(self, context=None): + """Returns the base 10 logarithm of self.""" + + if context is None: + context = getcontext() + + # log10(NaN) = NaN + ans = self._check_nans(context=context) + if ans: + return ans + + # log10(0.0) == -Infinity + if not self: + return _NegativeInfinity + + # log10(Infinity) = Infinity + if self._isinfinity() == 1: + return _Infinity + + # log10(negative or -Infinity) raises InvalidOperation + if self._sign == 1: + return context._raise_error(InvalidOperation, + 'log10 of a negative value') + + # log10(10**n) = n + if self._int[0] == '1' and self._int[1:] == '0'*(len(self._int) - 1): + # answer may need rounding + ans = Decimal(self._exp + len(self._int) - 1) + else: + # result is irrational, so necessarily inexact + op = _WorkRep(self) + c, e = op.int, op.exp + p = context.prec + + # correctly rounded result: repeatedly increase precision + # until result is unambiguously roundable + places = p-self._log10_exp_bound()+2 + while True: + coeff = _dlog10(c, e, places) + # assert len(str(abs(coeff)))-p >= 1 + if coeff % (5*10**(len(str(abs(coeff)))-p-1)): + break + places += 3 + ans = _dec_from_triple(int(coeff<0), str(abs(coeff)), -places) + + context = context._shallow_copy() + rounding = context._set_rounding(ROUND_HALF_EVEN) + ans = ans._fix(context) + context.rounding = rounding + return ans + + def logb(self, context=None): + """ Returns the exponent of the magnitude of self's MSD. + + The result is the integer which is the exponent of the magnitude + of the most significant digit of self (as though it were truncated + to a single digit while maintaining the value of that digit and + without limiting the resulting exponent). + """ + # logb(NaN) = NaN + ans = self._check_nans(context=context) + if ans: + return ans + + if context is None: + context = getcontext() + + # logb(+/-Inf) = +Inf + if self._isinfinity(): + return _Infinity + + # logb(0) = -Inf, DivisionByZero + if not self: + return context._raise_error(DivisionByZero, 'logb(0)', 1) + + # otherwise, simply return the adjusted exponent of self, as a + # Decimal. Note that no attempt is made to fit the result + # into the current context. + ans = Decimal(self.adjusted()) + return ans._fix(context) + + def _islogical(self): + """Return True if self is a logical operand. + + For being logical, it must be a finite number with a sign of 0, + an exponent of 0, and a coefficient whose digits must all be + either 0 or 1. + """ + if self._sign != 0 or self._exp != 0: + return False + for dig in self._int: + if dig not in '01': + return False + return True + + def _fill_logical(self, context, opa, opb): + dif = context.prec - len(opa) + if dif > 0: + opa = '0'*dif + opa + elif dif < 0: + opa = opa[-context.prec:] + dif = context.prec - len(opb) + if dif > 0: + opb = '0'*dif + opb + elif dif < 0: + opb = opb[-context.prec:] + return opa, opb + + def logical_and(self, other, context=None): + """Applies an 'and' operation between self and other's digits.""" + if context is None: + context = getcontext() + + other = _convert_other(other, raiseit=True) + + if not self._islogical() or not other._islogical(): + return context._raise_error(InvalidOperation) + + # fill to context.prec + (opa, opb) = self._fill_logical(context, self._int, other._int) + + # make the operation, and clean starting zeroes + result = "".join([str(int(a)&int(b)) for a,b in zip(opa,opb)]) + return _dec_from_triple(0, result.lstrip('0') or '0', 0) + + def logical_invert(self, context=None): + """Invert all its digits.""" + if context is None: + context = getcontext() + return self.logical_xor(_dec_from_triple(0,'1'*context.prec,0), + context) + + def logical_or(self, other, context=None): + """Applies an 'or' operation between self and other's digits.""" + if context is None: + context = getcontext() + + other = _convert_other(other, raiseit=True) + + if not self._islogical() or not other._islogical(): + return context._raise_error(InvalidOperation) + + # fill to context.prec + (opa, opb) = self._fill_logical(context, self._int, other._int) + + # make the operation, and clean starting zeroes + result = "".join([str(int(a)|int(b)) for a,b in zip(opa,opb)]) + return _dec_from_triple(0, result.lstrip('0') or '0', 0) + + def logical_xor(self, other, context=None): + """Applies an 'xor' operation between self and other's digits.""" + if context is None: + context = getcontext() + + other = _convert_other(other, raiseit=True) + + if not self._islogical() or not other._islogical(): + return context._raise_error(InvalidOperation) + + # fill to context.prec + (opa, opb) = self._fill_logical(context, self._int, other._int) + + # make the operation, and clean starting zeroes + result = "".join([str(int(a)^int(b)) for a,b in zip(opa,opb)]) + return _dec_from_triple(0, result.lstrip('0') or '0', 0) + + def max_mag(self, other, context=None): + """Compares the values numerically with their sign ignored.""" + other = _convert_other(other, raiseit=True) + + if context is None: + context = getcontext() + + if self._is_special or other._is_special: + # If one operand is a quiet NaN and the other is number, then the + # number is always returned + sn = self._isnan() + on = other._isnan() + if sn or on: + if on == 1 and sn == 0: + return self._fix(context) + if sn == 1 and on == 0: + return other._fix(context) + return self._check_nans(other, context) + + c = self.copy_abs()._cmp(other.copy_abs()) + if c == 0: + c = self.compare_total(other) + + if c == -1: + ans = other + else: + ans = self + + return ans._fix(context) + + def min_mag(self, other, context=None): + """Compares the values numerically with their sign ignored.""" + other = _convert_other(other, raiseit=True) + + if context is None: + context = getcontext() + + if self._is_special or other._is_special: + # If one operand is a quiet NaN and the other is number, then the + # number is always returned + sn = self._isnan() + on = other._isnan() + if sn or on: + if on == 1 and sn == 0: + return self._fix(context) + if sn == 1 and on == 0: + return other._fix(context) + return self._check_nans(other, context) + + c = self.copy_abs()._cmp(other.copy_abs()) + if c == 0: + c = self.compare_total(other) + + if c == -1: + ans = self + else: + ans = other + + return ans._fix(context) + + def next_minus(self, context=None): + """Returns the largest representable number smaller than itself.""" + if context is None: + context = getcontext() + + ans = self._check_nans(context=context) + if ans: + return ans + + if self._isinfinity() == -1: + return _NegativeInfinity + if self._isinfinity() == 1: + return _dec_from_triple(0, '9'*context.prec, context.Etop()) + + context = context.copy() + context._set_rounding(ROUND_FLOOR) + context._ignore_all_flags() + new_self = self._fix(context) + if new_self != self: + return new_self + return self.__sub__(_dec_from_triple(0, '1', context.Etiny()-1), + context) + + def next_plus(self, context=None): + """Returns the smallest representable number larger than itself.""" + if context is None: + context = getcontext() + + ans = self._check_nans(context=context) + if ans: + return ans + + if self._isinfinity() == 1: + return _Infinity + if self._isinfinity() == -1: + return _dec_from_triple(1, '9'*context.prec, context.Etop()) + + context = context.copy() + context._set_rounding(ROUND_CEILING) + context._ignore_all_flags() + new_self = self._fix(context) + if new_self != self: + return new_self + return self.__add__(_dec_from_triple(0, '1', context.Etiny()-1), + context) + + def next_toward(self, other, context=None): + """Returns the number closest to self, in the direction towards other. + + The result is the closest representable number to self + (excluding self) that is in the direction towards other, + unless both have the same value. If the two operands are + numerically equal, then the result is a copy of self with the + sign set to be the same as the sign of other. + """ + other = _convert_other(other, raiseit=True) + + if context is None: + context = getcontext() + + ans = self._check_nans(other, context) + if ans: + return ans + + comparison = self._cmp(other) + if comparison == 0: + return self.copy_sign(other) + + if comparison == -1: + ans = self.next_plus(context) + else: # comparison == 1 + ans = self.next_minus(context) + + # decide which flags to raise using value of ans + if ans._isinfinity(): + context._raise_error(Overflow, + 'Infinite result from next_toward', + ans._sign) + context._raise_error(Inexact) + context._raise_error(Rounded) + elif ans.adjusted() < context.Emin: + context._raise_error(Underflow) + context._raise_error(Subnormal) + context._raise_error(Inexact) + context._raise_error(Rounded) + # if precision == 1 then we don't raise Clamped for a + # result 0E-Etiny. + if not ans: + context._raise_error(Clamped) + + return ans + + def number_class(self, context=None): + """Returns an indication of the class of self. + + The class is one of the following strings: + sNaN + NaN + -Infinity + -Normal + -Subnormal + -Zero + +Zero + +Subnormal + +Normal + +Infinity + """ + if self.is_snan(): + return "sNaN" + if self.is_qnan(): + return "NaN" + inf = self._isinfinity() + if inf == 1: + return "+Infinity" + if inf == -1: + return "-Infinity" + if self.is_zero(): + if self._sign: + return "-Zero" + else: + return "+Zero" + if context is None: + context = getcontext() + if self.is_subnormal(context=context): + if self._sign: + return "-Subnormal" + else: + return "+Subnormal" + # just a normal, regular, boring number, :) + if self._sign: + return "-Normal" + else: + return "+Normal" + + def radix(self): + """Just returns 10, as this is Decimal, :)""" + return Decimal(10) + + def rotate(self, other, context=None): + """Returns a rotated copy of self, value-of-other times.""" + if context is None: + context = getcontext() + + other = _convert_other(other, raiseit=True) + + ans = self._check_nans(other, context) + if ans: + return ans + + if other._exp != 0: + return context._raise_error(InvalidOperation) + if not (-context.prec <= int(other) <= context.prec): + return context._raise_error(InvalidOperation) + + if self._isinfinity(): + return Decimal(self) + + # get values, pad if necessary + torot = int(other) + rotdig = self._int + topad = context.prec - len(rotdig) + if topad > 0: + rotdig = '0'*topad + rotdig + elif topad < 0: + rotdig = rotdig[-topad:] + + # let's rotate! + rotated = rotdig[torot:] + rotdig[:torot] + return _dec_from_triple(self._sign, + rotated.lstrip('0') or '0', self._exp) + + def scaleb(self, other, context=None): + """Returns self operand after adding the second value to its exp.""" + if context is None: + context = getcontext() + + other = _convert_other(other, raiseit=True) + + ans = self._check_nans(other, context) + if ans: + return ans + + if other._exp != 0: + return context._raise_error(InvalidOperation) + liminf = -2 * (context.Emax + context.prec) + limsup = 2 * (context.Emax + context.prec) + if not (liminf <= int(other) <= limsup): + return context._raise_error(InvalidOperation) + + if self._isinfinity(): + return Decimal(self) + + d = _dec_from_triple(self._sign, self._int, self._exp + int(other)) + d = d._fix(context) + return d + + def shift(self, other, context=None): + """Returns a shifted copy of self, value-of-other times.""" + if context is None: + context = getcontext() + + other = _convert_other(other, raiseit=True) + + ans = self._check_nans(other, context) + if ans: + return ans + + if other._exp != 0: + return context._raise_error(InvalidOperation) + if not (-context.prec <= int(other) <= context.prec): + return context._raise_error(InvalidOperation) + + if self._isinfinity(): + return Decimal(self) + + # get values, pad if necessary + torot = int(other) + rotdig = self._int + topad = context.prec - len(rotdig) + if topad > 0: + rotdig = '0'*topad + rotdig + elif topad < 0: + rotdig = rotdig[-topad:] + + # let's shift! + if torot < 0: + shifted = rotdig[:torot] + else: + shifted = rotdig + '0'*torot + shifted = shifted[-context.prec:] + + return _dec_from_triple(self._sign, + shifted.lstrip('0') or '0', self._exp) + + # Support for pickling, copy, and deepcopy + def __reduce__(self): + return (self.__class__, (str(self),)) + + def __copy__(self): + if type(self) is Decimal: + return self # I'm immutable; therefore I am my own clone + return self.__class__(str(self)) + + def __deepcopy__(self, memo): + if type(self) is Decimal: + return self # My components are also immutable + return self.__class__(str(self)) + + # PEP 3101 support. the _localeconv keyword argument should be + # considered private: it's provided for ease of testing only. + def __format__(self, specifier, context=None, _localeconv=None): + """Format a Decimal instance according to the given specifier. + + The specifier should be a standard format specifier, with the + form described in PEP 3101. Formatting types 'e', 'E', 'f', + 'F', 'g', 'G', 'n' and '%' are supported. If the formatting + type is omitted it defaults to 'g' or 'G', depending on the + value of context.capitals. + """ + + # Note: PEP 3101 says that if the type is not present then + # there should be at least one digit after the decimal point. + # We take the liberty of ignoring this requirement for + # Decimal---it's presumably there to make sure that + # format(float, '') behaves similarly to str(float). + if context is None: + context = getcontext() + + spec = _parse_format_specifier(specifier, _localeconv=_localeconv) + + # special values don't care about the type or precision + if self._is_special: + sign = _format_sign(self._sign, spec) + body = str(self.copy_abs()) + if spec['type'] == '%': + body += '%' + return _format_align(sign, body, spec) + + # a type of None defaults to 'g' or 'G', depending on context + if spec['type'] is None: + spec['type'] = ['g', 'G'][context.capitals] + + # if type is '%', adjust exponent of self accordingly + if spec['type'] == '%': + self = _dec_from_triple(self._sign, self._int, self._exp+2) + + # round if necessary, taking rounding mode from the context + rounding = context.rounding + precision = spec['precision'] + if precision is not None: + if spec['type'] in 'eE': + self = self._round(precision+1, rounding) + elif spec['type'] in 'fF%': + self = self._rescale(-precision, rounding) + elif spec['type'] in 'gG' and len(self._int) > precision: + self = self._round(precision, rounding) + # special case: zeros with a positive exponent can't be + # represented in fixed point; rescale them to 0e0. + if not self and self._exp > 0 and spec['type'] in 'fF%': + self = self._rescale(0, rounding) + + # figure out placement of the decimal point + leftdigits = self._exp + len(self._int) + if spec['type'] in 'eE': + if not self and precision is not None: + dotplace = 1 - precision + else: + dotplace = 1 + elif spec['type'] in 'fF%': + dotplace = leftdigits + elif spec['type'] in 'gG': + if self._exp <= 0 and leftdigits > -6: + dotplace = leftdigits + else: + dotplace = 1 + + # find digits before and after decimal point, and get exponent + if dotplace < 0: + intpart = '0' + fracpart = '0'*(-dotplace) + self._int + elif dotplace > len(self._int): + intpart = self._int + '0'*(dotplace-len(self._int)) + fracpart = '' + else: + intpart = self._int[:dotplace] or '0' + fracpart = self._int[dotplace:] + exp = leftdigits-dotplace + + # done with the decimal-specific stuff; hand over the rest + # of the formatting to the _format_number function + return _format_number(self._sign, intpart, fracpart, exp, spec) + +def _dec_from_triple(sign, coefficient, exponent, special=False): + """Create a decimal instance directly, without any validation, + normalization (e.g. removal of leading zeros) or argument + conversion. + + This function is for *internal use only*. + """ + + self = object.__new__(Decimal) + self._sign = sign + self._int = coefficient + self._exp = exponent + self._is_special = special + + return self + +# Register Decimal as a kind of Number (an abstract base class). +# However, do not register it as Real (because Decimals are not +# interoperable with floats). +_numbers.Number.register(Decimal) + + +##### Context class ####################################################### + +class _ContextManager(object): + """Context manager class to support localcontext(). + + Sets a copy of the supplied context in __enter__() and restores + the previous decimal context in __exit__() + """ + def __init__(self, new_context): + self.new_context = new_context.copy() + def __enter__(self): + self.saved_context = getcontext() + setcontext(self.new_context) + return self.new_context + def __exit__(self, t, v, tb): + setcontext(self.saved_context) + +class Context(object): + """Contains the context for a Decimal instance. + + Contains: + prec - precision (for use in rounding, division, square roots..) + rounding - rounding type (how you round) + traps - If traps[exception] = 1, then the exception is + raised when it is caused. Otherwise, a value is + substituted in. + flags - When an exception is caused, flags[exception] is set. + (Whether or not the trap_enabler is set) + Should be reset by user of Decimal instance. + Emin - Minimum exponent + Emax - Maximum exponent + capitals - If 1, 1*10^1 is printed as 1E+1. + If 0, printed as 1e1 + clamp - If 1, change exponents if too high (Default 0) + """ + + def __init__(self, prec=None, rounding=None, Emin=None, Emax=None, + capitals=None, clamp=None, flags=None, traps=None, + _ignored_flags=None): + # Set defaults; for everything except flags and _ignored_flags, + # inherit from DefaultContext. + try: + dc = DefaultContext + except NameError: + pass + + self.prec = prec if prec is not None else dc.prec + self.rounding = rounding if rounding is not None else dc.rounding + self.Emin = Emin if Emin is not None else dc.Emin + self.Emax = Emax if Emax is not None else dc.Emax + self.capitals = capitals if capitals is not None else dc.capitals + self.clamp = clamp if clamp is not None else dc.clamp + + if _ignored_flags is None: + self._ignored_flags = [] + else: + self._ignored_flags = _ignored_flags + + if traps is None: + self.traps = dc.traps.copy() + elif not isinstance(traps, dict): + self.traps = dict((s, int(s in traps)) for s in _signals + traps) + else: + self.traps = traps + + if flags is None: + self.flags = dict.fromkeys(_signals, 0) + elif not isinstance(flags, dict): + self.flags = dict((s, int(s in flags)) for s in _signals + flags) + else: + self.flags = flags + + def _set_integer_check(self, name, value, vmin, vmax): + if not isinstance(value, int): + raise TypeError("%s must be an integer" % name) + if vmin == '-inf': + if value > vmax: + raise ValueError("%s must be in [%s, %d]. got: %s" % (name, vmin, vmax, value)) + elif vmax == 'inf': + if value < vmin: + raise ValueError("%s must be in [%d, %s]. got: %s" % (name, vmin, vmax, value)) + else: + if value < vmin or value > vmax: + raise ValueError("%s must be in [%d, %d]. got %s" % (name, vmin, vmax, value)) + return object.__setattr__(self, name, value) + + def _set_signal_dict(self, name, d): + if not isinstance(d, dict): + raise TypeError("%s must be a signal dict" % d) + for key in d: + if not key in _signals: + raise KeyError("%s is not a valid signal dict" % d) + for key in _signals: + if not key in d: + raise KeyError("%s is not a valid signal dict" % d) + return object.__setattr__(self, name, d) + + def __setattr__(self, name, value): + if name == 'prec': + return self._set_integer_check(name, value, 1, 'inf') + elif name == 'Emin': + return self._set_integer_check(name, value, '-inf', 0) + elif name == 'Emax': + return self._set_integer_check(name, value, 0, 'inf') + elif name == 'capitals': + return self._set_integer_check(name, value, 0, 1) + elif name == 'clamp': + return self._set_integer_check(name, value, 0, 1) + elif name == 'rounding': + if not value in _rounding_modes: + # raise TypeError even for strings to have consistency + # among various implementations. + raise TypeError("%s: invalid rounding mode" % value) + return object.__setattr__(self, name, value) + elif name == 'flags' or name == 'traps': + return self._set_signal_dict(name, value) + elif name == '_ignored_flags': + return object.__setattr__(self, name, value) + else: + raise AttributeError( + "'decimal.Context' object has no attribute '%s'" % name) + + def __delattr__(self, name): + raise AttributeError("%s cannot be deleted" % name) + + # Support for pickling, copy, and deepcopy + def __reduce__(self): + flags = [sig for sig, v in self.flags.items() if v] + traps = [sig for sig, v in self.traps.items() if v] + return (self.__class__, + (self.prec, self.rounding, self.Emin, self.Emax, + self.capitals, self.clamp, flags, traps)) + + def __repr__(self): + """Show the current context.""" + s = [] + s.append('Context(prec=%(prec)d, rounding=%(rounding)s, ' + 'Emin=%(Emin)d, Emax=%(Emax)d, capitals=%(capitals)d, ' + 'clamp=%(clamp)d' + % vars(self)) + names = [f.__name__ for f, v in self.flags.items() if v] + s.append('flags=[' + ', '.join(names) + ']') + names = [t.__name__ for t, v in self.traps.items() if v] + s.append('traps=[' + ', '.join(names) + ']') + return ', '.join(s) + ')' + + def clear_flags(self): + """Reset all flags to zero""" + for flag in self.flags: + self.flags[flag] = 0 + + def clear_traps(self): + """Reset all traps to zero""" + for flag in self.traps: + self.traps[flag] = 0 + + def _shallow_copy(self): + """Returns a shallow copy from self.""" + nc = Context(self.prec, self.rounding, self.Emin, self.Emax, + self.capitals, self.clamp, self.flags, self.traps, + self._ignored_flags) + return nc + + def copy(self): + """Returns a deep copy from self.""" + nc = Context(self.prec, self.rounding, self.Emin, self.Emax, + self.capitals, self.clamp, + self.flags.copy(), self.traps.copy(), + self._ignored_flags) + return nc + __copy__ = copy + + def _raise_error(self, condition, explanation = None, *args): + """Handles an error + + If the flag is in _ignored_flags, returns the default response. + Otherwise, it sets the flag, then, if the corresponding + trap_enabler is set, it reraises the exception. Otherwise, it returns + the default value after setting the flag. + """ + error = _condition_map.get(condition, condition) + if error in self._ignored_flags: + # Don't touch the flag + return error().handle(self, *args) + + self.flags[error] = 1 + if not self.traps[error]: + # The errors define how to handle themselves. + return condition().handle(self, *args) + + # Errors should only be risked on copies of the context + # self._ignored_flags = [] + raise error(explanation) + + def _ignore_all_flags(self): + """Ignore all flags, if they are raised""" + return self._ignore_flags(*_signals) + + def _ignore_flags(self, *flags): + """Ignore the flags, if they are raised""" + # Do not mutate-- This way, copies of a context leave the original + # alone. + self._ignored_flags = (self._ignored_flags + list(flags)) + return list(flags) + + def _regard_flags(self, *flags): + """Stop ignoring the flags, if they are raised""" + if flags and isinstance(flags[0], (tuple,list)): + flags = flags[0] + for flag in flags: + self._ignored_flags.remove(flag) + + # We inherit object.__hash__, so we must deny this explicitly + __hash__ = None + + def Etiny(self): + """Returns Etiny (= Emin - prec + 1)""" + return int(self.Emin - self.prec + 1) + + def Etop(self): + """Returns maximum exponent (= Emax - prec + 1)""" + return int(self.Emax - self.prec + 1) + + def _set_rounding(self, type): + """Sets the rounding type. + + Sets the rounding type, and returns the current (previous) + rounding type. Often used like: + + context = context.copy() + # so you don't change the calling context + # if an error occurs in the middle. + rounding = context._set_rounding(ROUND_UP) + val = self.__sub__(other, context=context) + context._set_rounding(rounding) + + This will make it round up for that operation. + """ + rounding = self.rounding + self.rounding= type + return rounding + + def create_decimal(self, num='0'): + """Creates a new Decimal instance but using self as context. + + This method implements the to-number operation of the + IBM Decimal specification.""" + + if isinstance(num, str) and num != num.strip(): + return self._raise_error(ConversionSyntax, + "no trailing or leading whitespace is " + "permitted.") + + d = Decimal(num, context=self) + if d._isnan() and len(d._int) > self.prec - self.clamp: + return self._raise_error(ConversionSyntax, + "diagnostic info too long in NaN") + return d._fix(self) + + def create_decimal_from_float(self, f): + """Creates a new Decimal instance from a float but rounding using self + as the context. + + >>> context = Context(prec=5, rounding=ROUND_DOWN) + >>> context.create_decimal_from_float(3.1415926535897932) + Decimal('3.1415') + >>> context = Context(prec=5, traps=[Inexact]) + >>> context.create_decimal_from_float(3.1415926535897932) + Traceback (most recent call last): + ... + decimal.Inexact: None + + """ + d = Decimal.from_float(f) # An exact conversion + return d._fix(self) # Apply the context rounding + + # Methods + def abs(self, a): + """Returns the absolute value of the operand. + + If the operand is negative, the result is the same as using the minus + operation on the operand. Otherwise, the result is the same as using + the plus operation on the operand. + + >>> ExtendedContext.abs(Decimal('2.1')) + Decimal('2.1') + >>> ExtendedContext.abs(Decimal('-100')) + Decimal('100') + >>> ExtendedContext.abs(Decimal('101.5')) + Decimal('101.5') + >>> ExtendedContext.abs(Decimal('-101.5')) + Decimal('101.5') + >>> ExtendedContext.abs(-1) + Decimal('1') + """ + a = _convert_other(a, raiseit=True) + return a.__abs__(context=self) + + def add(self, a, b): + """Return the sum of the two operands. + + >>> ExtendedContext.add(Decimal('12'), Decimal('7.00')) + Decimal('19.00') + >>> ExtendedContext.add(Decimal('1E+2'), Decimal('1.01E+4')) + Decimal('1.02E+4') + >>> ExtendedContext.add(1, Decimal(2)) + Decimal('3') + >>> ExtendedContext.add(Decimal(8), 5) + Decimal('13') + >>> ExtendedContext.add(5, 5) + Decimal('10') + """ + a = _convert_other(a, raiseit=True) + r = a.__add__(b, context=self) + if r is NotImplemented: + raise TypeError("Unable to convert %s to Decimal" % b) + else: + return r + + def _apply(self, a): + return str(a._fix(self)) + + def canonical(self, a): + """Returns the same Decimal object. + + As we do not have different encodings for the same number, the + received object already is in its canonical form. + + >>> ExtendedContext.canonical(Decimal('2.50')) + Decimal('2.50') + """ + if not isinstance(a, Decimal): + raise TypeError("canonical requires a Decimal as an argument.") + return a.canonical() + + def compare(self, a, b): + """Compares values numerically. + + If the signs of the operands differ, a value representing each operand + ('-1' if the operand is less than zero, '0' if the operand is zero or + negative zero, or '1' if the operand is greater than zero) is used in + place of that operand for the comparison instead of the actual + operand. + + The comparison is then effected by subtracting the second operand from + the first and then returning a value according to the result of the + subtraction: '-1' if the result is less than zero, '0' if the result is + zero or negative zero, or '1' if the result is greater than zero. + + >>> ExtendedContext.compare(Decimal('2.1'), Decimal('3')) + Decimal('-1') + >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.1')) + Decimal('0') + >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.10')) + Decimal('0') + >>> ExtendedContext.compare(Decimal('3'), Decimal('2.1')) + Decimal('1') + >>> ExtendedContext.compare(Decimal('2.1'), Decimal('-3')) + Decimal('1') + >>> ExtendedContext.compare(Decimal('-3'), Decimal('2.1')) + Decimal('-1') + >>> ExtendedContext.compare(1, 2) + Decimal('-1') + >>> ExtendedContext.compare(Decimal(1), 2) + Decimal('-1') + >>> ExtendedContext.compare(1, Decimal(2)) + Decimal('-1') + """ + a = _convert_other(a, raiseit=True) + return a.compare(b, context=self) + + def compare_signal(self, a, b): + """Compares the values of the two operands numerically. + + It's pretty much like compare(), but all NaNs signal, with signaling + NaNs taking precedence over quiet NaNs. + + >>> c = ExtendedContext + >>> c.compare_signal(Decimal('2.1'), Decimal('3')) + Decimal('-1') + >>> c.compare_signal(Decimal('2.1'), Decimal('2.1')) + Decimal('0') + >>> c.flags[InvalidOperation] = 0 + >>> print(c.flags[InvalidOperation]) + 0 + >>> c.compare_signal(Decimal('NaN'), Decimal('2.1')) + Decimal('NaN') + >>> print(c.flags[InvalidOperation]) + 1 + >>> c.flags[InvalidOperation] = 0 + >>> print(c.flags[InvalidOperation]) + 0 + >>> c.compare_signal(Decimal('sNaN'), Decimal('2.1')) + Decimal('NaN') + >>> print(c.flags[InvalidOperation]) + 1 + >>> c.compare_signal(-1, 2) + Decimal('-1') + >>> c.compare_signal(Decimal(-1), 2) + Decimal('-1') + >>> c.compare_signal(-1, Decimal(2)) + Decimal('-1') + """ + a = _convert_other(a, raiseit=True) + return a.compare_signal(b, context=self) + + def compare_total(self, a, b): + """Compares two operands using their abstract representation. + + This is not like the standard compare, which use their numerical + value. Note that a total ordering is defined for all possible abstract + representations. + + >>> ExtendedContext.compare_total(Decimal('12.73'), Decimal('127.9')) + Decimal('-1') + >>> ExtendedContext.compare_total(Decimal('-127'), Decimal('12')) + Decimal('-1') + >>> ExtendedContext.compare_total(Decimal('12.30'), Decimal('12.3')) + Decimal('-1') + >>> ExtendedContext.compare_total(Decimal('12.30'), Decimal('12.30')) + Decimal('0') + >>> ExtendedContext.compare_total(Decimal('12.3'), Decimal('12.300')) + Decimal('1') + >>> ExtendedContext.compare_total(Decimal('12.3'), Decimal('NaN')) + Decimal('-1') + >>> ExtendedContext.compare_total(1, 2) + Decimal('-1') + >>> ExtendedContext.compare_total(Decimal(1), 2) + Decimal('-1') + >>> ExtendedContext.compare_total(1, Decimal(2)) + Decimal('-1') + """ + a = _convert_other(a, raiseit=True) + return a.compare_total(b) + + def compare_total_mag(self, a, b): + """Compares two operands using their abstract representation ignoring sign. + + Like compare_total, but with operand's sign ignored and assumed to be 0. + """ + a = _convert_other(a, raiseit=True) + return a.compare_total_mag(b) + + def copy_abs(self, a): + """Returns a copy of the operand with the sign set to 0. + + >>> ExtendedContext.copy_abs(Decimal('2.1')) + Decimal('2.1') + >>> ExtendedContext.copy_abs(Decimal('-100')) + Decimal('100') + >>> ExtendedContext.copy_abs(-1) + Decimal('1') + """ + a = _convert_other(a, raiseit=True) + return a.copy_abs() + + def copy_decimal(self, a): + """Returns a copy of the decimal object. + + >>> ExtendedContext.copy_decimal(Decimal('2.1')) + Decimal('2.1') + >>> ExtendedContext.copy_decimal(Decimal('-1.00')) + Decimal('-1.00') + >>> ExtendedContext.copy_decimal(1) + Decimal('1') + """ + a = _convert_other(a, raiseit=True) + return Decimal(a) + + def copy_negate(self, a): + """Returns a copy of the operand with the sign inverted. + + >>> ExtendedContext.copy_negate(Decimal('101.5')) + Decimal('-101.5') + >>> ExtendedContext.copy_negate(Decimal('-101.5')) + Decimal('101.5') + >>> ExtendedContext.copy_negate(1) + Decimal('-1') + """ + a = _convert_other(a, raiseit=True) + return a.copy_negate() + + def copy_sign(self, a, b): + """Copies the second operand's sign to the first one. + + In detail, it returns a copy of the first operand with the sign + equal to the sign of the second operand. + + >>> ExtendedContext.copy_sign(Decimal( '1.50'), Decimal('7.33')) + Decimal('1.50') + >>> ExtendedContext.copy_sign(Decimal('-1.50'), Decimal('7.33')) + Decimal('1.50') + >>> ExtendedContext.copy_sign(Decimal( '1.50'), Decimal('-7.33')) + Decimal('-1.50') + >>> ExtendedContext.copy_sign(Decimal('-1.50'), Decimal('-7.33')) + Decimal('-1.50') + >>> ExtendedContext.copy_sign(1, -2) + Decimal('-1') + >>> ExtendedContext.copy_sign(Decimal(1), -2) + Decimal('-1') + >>> ExtendedContext.copy_sign(1, Decimal(-2)) + Decimal('-1') + """ + a = _convert_other(a, raiseit=True) + return a.copy_sign(b) + + def divide(self, a, b): + """Decimal division in a specified context. + + >>> ExtendedContext.divide(Decimal('1'), Decimal('3')) + Decimal('0.333333333') + >>> ExtendedContext.divide(Decimal('2'), Decimal('3')) + Decimal('0.666666667') + >>> ExtendedContext.divide(Decimal('5'), Decimal('2')) + Decimal('2.5') + >>> ExtendedContext.divide(Decimal('1'), Decimal('10')) + Decimal('0.1') + >>> ExtendedContext.divide(Decimal('12'), Decimal('12')) + Decimal('1') + >>> ExtendedContext.divide(Decimal('8.00'), Decimal('2')) + Decimal('4.00') + >>> ExtendedContext.divide(Decimal('2.400'), Decimal('2.0')) + Decimal('1.20') + >>> ExtendedContext.divide(Decimal('1000'), Decimal('100')) + Decimal('10') + >>> ExtendedContext.divide(Decimal('1000'), Decimal('1')) + Decimal('1000') + >>> ExtendedContext.divide(Decimal('2.40E+6'), Decimal('2')) + Decimal('1.20E+6') + >>> ExtendedContext.divide(5, 5) + Decimal('1') + >>> ExtendedContext.divide(Decimal(5), 5) + Decimal('1') + >>> ExtendedContext.divide(5, Decimal(5)) + Decimal('1') + """ + a = _convert_other(a, raiseit=True) + r = a.__truediv__(b, context=self) + if r is NotImplemented: + raise TypeError("Unable to convert %s to Decimal" % b) + else: + return r + + def divide_int(self, a, b): + """Divides two numbers and returns the integer part of the result. + + >>> ExtendedContext.divide_int(Decimal('2'), Decimal('3')) + Decimal('0') + >>> ExtendedContext.divide_int(Decimal('10'), Decimal('3')) + Decimal('3') + >>> ExtendedContext.divide_int(Decimal('1'), Decimal('0.3')) + Decimal('3') + >>> ExtendedContext.divide_int(10, 3) + Decimal('3') + >>> ExtendedContext.divide_int(Decimal(10), 3) + Decimal('3') + >>> ExtendedContext.divide_int(10, Decimal(3)) + Decimal('3') + """ + a = _convert_other(a, raiseit=True) + r = a.__floordiv__(b, context=self) + if r is NotImplemented: + raise TypeError("Unable to convert %s to Decimal" % b) + else: + return r + + def divmod(self, a, b): + """Return (a // b, a % b). + + >>> ExtendedContext.divmod(Decimal(8), Decimal(3)) + (Decimal('2'), Decimal('2')) + >>> ExtendedContext.divmod(Decimal(8), Decimal(4)) + (Decimal('2'), Decimal('0')) + >>> ExtendedContext.divmod(8, 4) + (Decimal('2'), Decimal('0')) + >>> ExtendedContext.divmod(Decimal(8), 4) + (Decimal('2'), Decimal('0')) + >>> ExtendedContext.divmod(8, Decimal(4)) + (Decimal('2'), Decimal('0')) + """ + a = _convert_other(a, raiseit=True) + r = a.__divmod__(b, context=self) + if r is NotImplemented: + raise TypeError("Unable to convert %s to Decimal" % b) + else: + return r + + def exp(self, a): + """Returns e ** a. + + >>> c = ExtendedContext.copy() + >>> c.Emin = -999 + >>> c.Emax = 999 + >>> c.exp(Decimal('-Infinity')) + Decimal('0') + >>> c.exp(Decimal('-1')) + Decimal('0.367879441') + >>> c.exp(Decimal('0')) + Decimal('1') + >>> c.exp(Decimal('1')) + Decimal('2.71828183') + >>> c.exp(Decimal('0.693147181')) + Decimal('2.00000000') + >>> c.exp(Decimal('+Infinity')) + Decimal('Infinity') + >>> c.exp(10) + Decimal('22026.4658') + """ + a =_convert_other(a, raiseit=True) + return a.exp(context=self) + + def fma(self, a, b, c): + """Returns a multiplied by b, plus c. + + The first two operands are multiplied together, using multiply, + the third operand is then added to the result of that + multiplication, using add, all with only one final rounding. + + >>> ExtendedContext.fma(Decimal('3'), Decimal('5'), Decimal('7')) + Decimal('22') + >>> ExtendedContext.fma(Decimal('3'), Decimal('-5'), Decimal('7')) + Decimal('-8') + >>> ExtendedContext.fma(Decimal('888565290'), Decimal('1557.96930'), Decimal('-86087.7578')) + Decimal('1.38435736E+12') + >>> ExtendedContext.fma(1, 3, 4) + Decimal('7') + >>> ExtendedContext.fma(1, Decimal(3), 4) + Decimal('7') + >>> ExtendedContext.fma(1, 3, Decimal(4)) + Decimal('7') + """ + a = _convert_other(a, raiseit=True) + return a.fma(b, c, context=self) + + def is_canonical(self, a): + """Return True if the operand is canonical; otherwise return False. + + Currently, the encoding of a Decimal instance is always + canonical, so this method returns True for any Decimal. + + >>> ExtendedContext.is_canonical(Decimal('2.50')) + True + """ + if not isinstance(a, Decimal): + raise TypeError("is_canonical requires a Decimal as an argument.") + return a.is_canonical() + + def is_finite(self, a): + """Return True if the operand is finite; otherwise return False. + + A Decimal instance is considered finite if it is neither + infinite nor a NaN. + + >>> ExtendedContext.is_finite(Decimal('2.50')) + True + >>> ExtendedContext.is_finite(Decimal('-0.3')) + True + >>> ExtendedContext.is_finite(Decimal('0')) + True + >>> ExtendedContext.is_finite(Decimal('Inf')) + False + >>> ExtendedContext.is_finite(Decimal('NaN')) + False + >>> ExtendedContext.is_finite(1) + True + """ + a = _convert_other(a, raiseit=True) + return a.is_finite() + + def is_infinite(self, a): + """Return True if the operand is infinite; otherwise return False. + + >>> ExtendedContext.is_infinite(Decimal('2.50')) + False + >>> ExtendedContext.is_infinite(Decimal('-Inf')) + True + >>> ExtendedContext.is_infinite(Decimal('NaN')) + False + >>> ExtendedContext.is_infinite(1) + False + """ + a = _convert_other(a, raiseit=True) + return a.is_infinite() + + def is_nan(self, a): + """Return True if the operand is a qNaN or sNaN; + otherwise return False. + + >>> ExtendedContext.is_nan(Decimal('2.50')) + False + >>> ExtendedContext.is_nan(Decimal('NaN')) + True + >>> ExtendedContext.is_nan(Decimal('-sNaN')) + True + >>> ExtendedContext.is_nan(1) + False + """ + a = _convert_other(a, raiseit=True) + return a.is_nan() + + def is_normal(self, a): + """Return True if the operand is a normal number; + otherwise return False. + + >>> c = ExtendedContext.copy() + >>> c.Emin = -999 + >>> c.Emax = 999 + >>> c.is_normal(Decimal('2.50')) + True + >>> c.is_normal(Decimal('0.1E-999')) + False + >>> c.is_normal(Decimal('0.00')) + False + >>> c.is_normal(Decimal('-Inf')) + False + >>> c.is_normal(Decimal('NaN')) + False + >>> c.is_normal(1) + True + """ + a = _convert_other(a, raiseit=True) + return a.is_normal(context=self) + + def is_qnan(self, a): + """Return True if the operand is a quiet NaN; otherwise return False. + + >>> ExtendedContext.is_qnan(Decimal('2.50')) + False + >>> ExtendedContext.is_qnan(Decimal('NaN')) + True + >>> ExtendedContext.is_qnan(Decimal('sNaN')) + False + >>> ExtendedContext.is_qnan(1) + False + """ + a = _convert_other(a, raiseit=True) + return a.is_qnan() + + def is_signed(self, a): + """Return True if the operand is negative; otherwise return False. + + >>> ExtendedContext.is_signed(Decimal('2.50')) + False + >>> ExtendedContext.is_signed(Decimal('-12')) + True + >>> ExtendedContext.is_signed(Decimal('-0')) + True + >>> ExtendedContext.is_signed(8) + False + >>> ExtendedContext.is_signed(-8) + True + """ + a = _convert_other(a, raiseit=True) + return a.is_signed() + + def is_snan(self, a): + """Return True if the operand is a signaling NaN; + otherwise return False. + + >>> ExtendedContext.is_snan(Decimal('2.50')) + False + >>> ExtendedContext.is_snan(Decimal('NaN')) + False + >>> ExtendedContext.is_snan(Decimal('sNaN')) + True + >>> ExtendedContext.is_snan(1) + False + """ + a = _convert_other(a, raiseit=True) + return a.is_snan() + + def is_subnormal(self, a): + """Return True if the operand is subnormal; otherwise return False. + + >>> c = ExtendedContext.copy() + >>> c.Emin = -999 + >>> c.Emax = 999 + >>> c.is_subnormal(Decimal('2.50')) + False + >>> c.is_subnormal(Decimal('0.1E-999')) + True + >>> c.is_subnormal(Decimal('0.00')) + False + >>> c.is_subnormal(Decimal('-Inf')) + False + >>> c.is_subnormal(Decimal('NaN')) + False + >>> c.is_subnormal(1) + False + """ + a = _convert_other(a, raiseit=True) + return a.is_subnormal(context=self) + + def is_zero(self, a): + """Return True if the operand is a zero; otherwise return False. + + >>> ExtendedContext.is_zero(Decimal('0')) + True + >>> ExtendedContext.is_zero(Decimal('2.50')) + False + >>> ExtendedContext.is_zero(Decimal('-0E+2')) + True + >>> ExtendedContext.is_zero(1) + False + >>> ExtendedContext.is_zero(0) + True + """ + a = _convert_other(a, raiseit=True) + return a.is_zero() + + def ln(self, a): + """Returns the natural (base e) logarithm of the operand. + + >>> c = ExtendedContext.copy() + >>> c.Emin = -999 + >>> c.Emax = 999 + >>> c.ln(Decimal('0')) + Decimal('-Infinity') + >>> c.ln(Decimal('1.000')) + Decimal('0') + >>> c.ln(Decimal('2.71828183')) + Decimal('1.00000000') + >>> c.ln(Decimal('10')) + Decimal('2.30258509') + >>> c.ln(Decimal('+Infinity')) + Decimal('Infinity') + >>> c.ln(1) + Decimal('0') + """ + a = _convert_other(a, raiseit=True) + return a.ln(context=self) + + def log10(self, a): + """Returns the base 10 logarithm of the operand. + + >>> c = ExtendedContext.copy() + >>> c.Emin = -999 + >>> c.Emax = 999 + >>> c.log10(Decimal('0')) + Decimal('-Infinity') + >>> c.log10(Decimal('0.001')) + Decimal('-3') + >>> c.log10(Decimal('1.000')) + Decimal('0') + >>> c.log10(Decimal('2')) + Decimal('0.301029996') + >>> c.log10(Decimal('10')) + Decimal('1') + >>> c.log10(Decimal('70')) + Decimal('1.84509804') + >>> c.log10(Decimal('+Infinity')) + Decimal('Infinity') + >>> c.log10(0) + Decimal('-Infinity') + >>> c.log10(1) + Decimal('0') + """ + a = _convert_other(a, raiseit=True) + return a.log10(context=self) + + def logb(self, a): + """ Returns the exponent of the magnitude of the operand's MSD. + + The result is the integer which is the exponent of the magnitude + of the most significant digit of the operand (as though the + operand were truncated to a single digit while maintaining the + value of that digit and without limiting the resulting exponent). + + >>> ExtendedContext.logb(Decimal('250')) + Decimal('2') + >>> ExtendedContext.logb(Decimal('2.50')) + Decimal('0') + >>> ExtendedContext.logb(Decimal('0.03')) + Decimal('-2') + >>> ExtendedContext.logb(Decimal('0')) + Decimal('-Infinity') + >>> ExtendedContext.logb(1) + Decimal('0') + >>> ExtendedContext.logb(10) + Decimal('1') + >>> ExtendedContext.logb(100) + Decimal('2') + """ + a = _convert_other(a, raiseit=True) + return a.logb(context=self) + + def logical_and(self, a, b): + """Applies the logical operation 'and' between each operand's digits. + + The operands must be both logical numbers. + + >>> ExtendedContext.logical_and(Decimal('0'), Decimal('0')) + Decimal('0') + >>> ExtendedContext.logical_and(Decimal('0'), Decimal('1')) + Decimal('0') + >>> ExtendedContext.logical_and(Decimal('1'), Decimal('0')) + Decimal('0') + >>> ExtendedContext.logical_and(Decimal('1'), Decimal('1')) + Decimal('1') + >>> ExtendedContext.logical_and(Decimal('1100'), Decimal('1010')) + Decimal('1000') + >>> ExtendedContext.logical_and(Decimal('1111'), Decimal('10')) + Decimal('10') + >>> ExtendedContext.logical_and(110, 1101) + Decimal('100') + >>> ExtendedContext.logical_and(Decimal(110), 1101) + Decimal('100') + >>> ExtendedContext.logical_and(110, Decimal(1101)) + Decimal('100') + """ + a = _convert_other(a, raiseit=True) + return a.logical_and(b, context=self) + + def logical_invert(self, a): + """Invert all the digits in the operand. + + The operand must be a logical number. + + >>> ExtendedContext.logical_invert(Decimal('0')) + Decimal('111111111') + >>> ExtendedContext.logical_invert(Decimal('1')) + Decimal('111111110') + >>> ExtendedContext.logical_invert(Decimal('111111111')) + Decimal('0') + >>> ExtendedContext.logical_invert(Decimal('101010101')) + Decimal('10101010') + >>> ExtendedContext.logical_invert(1101) + Decimal('111110010') + """ + a = _convert_other(a, raiseit=True) + return a.logical_invert(context=self) + + def logical_or(self, a, b): + """Applies the logical operation 'or' between each operand's digits. + + The operands must be both logical numbers. + + >>> ExtendedContext.logical_or(Decimal('0'), Decimal('0')) + Decimal('0') + >>> ExtendedContext.logical_or(Decimal('0'), Decimal('1')) + Decimal('1') + >>> ExtendedContext.logical_or(Decimal('1'), Decimal('0')) + Decimal('1') + >>> ExtendedContext.logical_or(Decimal('1'), Decimal('1')) + Decimal('1') + >>> ExtendedContext.logical_or(Decimal('1100'), Decimal('1010')) + Decimal('1110') + >>> ExtendedContext.logical_or(Decimal('1110'), Decimal('10')) + Decimal('1110') + >>> ExtendedContext.logical_or(110, 1101) + Decimal('1111') + >>> ExtendedContext.logical_or(Decimal(110), 1101) + Decimal('1111') + >>> ExtendedContext.logical_or(110, Decimal(1101)) + Decimal('1111') + """ + a = _convert_other(a, raiseit=True) + return a.logical_or(b, context=self) + + def logical_xor(self, a, b): + """Applies the logical operation 'xor' between each operand's digits. + + The operands must be both logical numbers. + + >>> ExtendedContext.logical_xor(Decimal('0'), Decimal('0')) + Decimal('0') + >>> ExtendedContext.logical_xor(Decimal('0'), Decimal('1')) + Decimal('1') + >>> ExtendedContext.logical_xor(Decimal('1'), Decimal('0')) + Decimal('1') + >>> ExtendedContext.logical_xor(Decimal('1'), Decimal('1')) + Decimal('0') + >>> ExtendedContext.logical_xor(Decimal('1100'), Decimal('1010')) + Decimal('110') + >>> ExtendedContext.logical_xor(Decimal('1111'), Decimal('10')) + Decimal('1101') + >>> ExtendedContext.logical_xor(110, 1101) + Decimal('1011') + >>> ExtendedContext.logical_xor(Decimal(110), 1101) + Decimal('1011') + >>> ExtendedContext.logical_xor(110, Decimal(1101)) + Decimal('1011') + """ + a = _convert_other(a, raiseit=True) + return a.logical_xor(b, context=self) + + def max(self, a, b): + """max compares two values numerically and returns the maximum. + + If either operand is a NaN then the general rules apply. + Otherwise, the operands are compared as though by the compare + operation. If they are numerically equal then the left-hand operand + is chosen as the result. Otherwise the maximum (closer to positive + infinity) of the two operands is chosen as the result. + + >>> ExtendedContext.max(Decimal('3'), Decimal('2')) + Decimal('3') + >>> ExtendedContext.max(Decimal('-10'), Decimal('3')) + Decimal('3') + >>> ExtendedContext.max(Decimal('1.0'), Decimal('1')) + Decimal('1') + >>> ExtendedContext.max(Decimal('7'), Decimal('NaN')) + Decimal('7') + >>> ExtendedContext.max(1, 2) + Decimal('2') + >>> ExtendedContext.max(Decimal(1), 2) + Decimal('2') + >>> ExtendedContext.max(1, Decimal(2)) + Decimal('2') + """ + a = _convert_other(a, raiseit=True) + return a.max(b, context=self) + + def max_mag(self, a, b): + """Compares the values numerically with their sign ignored. + + >>> ExtendedContext.max_mag(Decimal('7'), Decimal('NaN')) + Decimal('7') + >>> ExtendedContext.max_mag(Decimal('7'), Decimal('-10')) + Decimal('-10') + >>> ExtendedContext.max_mag(1, -2) + Decimal('-2') + >>> ExtendedContext.max_mag(Decimal(1), -2) + Decimal('-2') + >>> ExtendedContext.max_mag(1, Decimal(-2)) + Decimal('-2') + """ + a = _convert_other(a, raiseit=True) + return a.max_mag(b, context=self) + + def min(self, a, b): + """min compares two values numerically and returns the minimum. + + If either operand is a NaN then the general rules apply. + Otherwise, the operands are compared as though by the compare + operation. If they are numerically equal then the left-hand operand + is chosen as the result. Otherwise the minimum (closer to negative + infinity) of the two operands is chosen as the result. + + >>> ExtendedContext.min(Decimal('3'), Decimal('2')) + Decimal('2') + >>> ExtendedContext.min(Decimal('-10'), Decimal('3')) + Decimal('-10') + >>> ExtendedContext.min(Decimal('1.0'), Decimal('1')) + Decimal('1.0') + >>> ExtendedContext.min(Decimal('7'), Decimal('NaN')) + Decimal('7') + >>> ExtendedContext.min(1, 2) + Decimal('1') + >>> ExtendedContext.min(Decimal(1), 2) + Decimal('1') + >>> ExtendedContext.min(1, Decimal(29)) + Decimal('1') + """ + a = _convert_other(a, raiseit=True) + return a.min(b, context=self) + + def min_mag(self, a, b): + """Compares the values numerically with their sign ignored. + + >>> ExtendedContext.min_mag(Decimal('3'), Decimal('-2')) + Decimal('-2') + >>> ExtendedContext.min_mag(Decimal('-3'), Decimal('NaN')) + Decimal('-3') + >>> ExtendedContext.min_mag(1, -2) + Decimal('1') + >>> ExtendedContext.min_mag(Decimal(1), -2) + Decimal('1') + >>> ExtendedContext.min_mag(1, Decimal(-2)) + Decimal('1') + """ + a = _convert_other(a, raiseit=True) + return a.min_mag(b, context=self) + + def minus(self, a): + """Minus corresponds to unary prefix minus in Python. + + The operation is evaluated using the same rules as subtract; the + operation minus(a) is calculated as subtract('0', a) where the '0' + has the same exponent as the operand. + + >>> ExtendedContext.minus(Decimal('1.3')) + Decimal('-1.3') + >>> ExtendedContext.minus(Decimal('-1.3')) + Decimal('1.3') + >>> ExtendedContext.minus(1) + Decimal('-1') + """ + a = _convert_other(a, raiseit=True) + return a.__neg__(context=self) + + def multiply(self, a, b): + """multiply multiplies two operands. + + If either operand is a special value then the general rules apply. + Otherwise, the operands are multiplied together + ('long multiplication'), resulting in a number which may be as long as + the sum of the lengths of the two operands. + + >>> ExtendedContext.multiply(Decimal('1.20'), Decimal('3')) + Decimal('3.60') + >>> ExtendedContext.multiply(Decimal('7'), Decimal('3')) + Decimal('21') + >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('0.8')) + Decimal('0.72') + >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('-0')) + Decimal('-0.0') + >>> ExtendedContext.multiply(Decimal('654321'), Decimal('654321')) + Decimal('4.28135971E+11') + >>> ExtendedContext.multiply(7, 7) + Decimal('49') + >>> ExtendedContext.multiply(Decimal(7), 7) + Decimal('49') + >>> ExtendedContext.multiply(7, Decimal(7)) + Decimal('49') + """ + a = _convert_other(a, raiseit=True) + r = a.__mul__(b, context=self) + if r is NotImplemented: + raise TypeError("Unable to convert %s to Decimal" % b) + else: + return r + + def next_minus(self, a): + """Returns the largest representable number smaller than a. + + >>> c = ExtendedContext.copy() + >>> c.Emin = -999 + >>> c.Emax = 999 + >>> ExtendedContext.next_minus(Decimal('1')) + Decimal('0.999999999') + >>> c.next_minus(Decimal('1E-1007')) + Decimal('0E-1007') + >>> ExtendedContext.next_minus(Decimal('-1.00000003')) + Decimal('-1.00000004') + >>> c.next_minus(Decimal('Infinity')) + Decimal('9.99999999E+999') + >>> c.next_minus(1) + Decimal('0.999999999') + """ + a = _convert_other(a, raiseit=True) + return a.next_minus(context=self) + + def next_plus(self, a): + """Returns the smallest representable number larger than a. + + >>> c = ExtendedContext.copy() + >>> c.Emin = -999 + >>> c.Emax = 999 + >>> ExtendedContext.next_plus(Decimal('1')) + Decimal('1.00000001') + >>> c.next_plus(Decimal('-1E-1007')) + Decimal('-0E-1007') + >>> ExtendedContext.next_plus(Decimal('-1.00000003')) + Decimal('-1.00000002') + >>> c.next_plus(Decimal('-Infinity')) + Decimal('-9.99999999E+999') + >>> c.next_plus(1) + Decimal('1.00000001') + """ + a = _convert_other(a, raiseit=True) + return a.next_plus(context=self) + + def next_toward(self, a, b): + """Returns the number closest to a, in direction towards b. + + The result is the closest representable number from the first + operand (but not the first operand) that is in the direction + towards the second operand, unless the operands have the same + value. + + >>> c = ExtendedContext.copy() + >>> c.Emin = -999 + >>> c.Emax = 999 + >>> c.next_toward(Decimal('1'), Decimal('2')) + Decimal('1.00000001') + >>> c.next_toward(Decimal('-1E-1007'), Decimal('1')) + Decimal('-0E-1007') + >>> c.next_toward(Decimal('-1.00000003'), Decimal('0')) + Decimal('-1.00000002') + >>> c.next_toward(Decimal('1'), Decimal('0')) + Decimal('0.999999999') + >>> c.next_toward(Decimal('1E-1007'), Decimal('-100')) + Decimal('0E-1007') + >>> c.next_toward(Decimal('-1.00000003'), Decimal('-10')) + Decimal('-1.00000004') + >>> c.next_toward(Decimal('0.00'), Decimal('-0.0000')) + Decimal('-0.00') + >>> c.next_toward(0, 1) + Decimal('1E-1007') + >>> c.next_toward(Decimal(0), 1) + Decimal('1E-1007') + >>> c.next_toward(0, Decimal(1)) + Decimal('1E-1007') + """ + a = _convert_other(a, raiseit=True) + return a.next_toward(b, context=self) + + def normalize(self, a): + """normalize reduces an operand to its simplest form. + + Essentially a plus operation with all trailing zeros removed from the + result. + + >>> ExtendedContext.normalize(Decimal('2.1')) + Decimal('2.1') + >>> ExtendedContext.normalize(Decimal('-2.0')) + Decimal('-2') + >>> ExtendedContext.normalize(Decimal('1.200')) + Decimal('1.2') + >>> ExtendedContext.normalize(Decimal('-120')) + Decimal('-1.2E+2') + >>> ExtendedContext.normalize(Decimal('120.00')) + Decimal('1.2E+2') + >>> ExtendedContext.normalize(Decimal('0.00')) + Decimal('0') + >>> ExtendedContext.normalize(6) + Decimal('6') + """ + a = _convert_other(a, raiseit=True) + return a.normalize(context=self) + + def number_class(self, a): + """Returns an indication of the class of the operand. + + The class is one of the following strings: + -sNaN + -NaN + -Infinity + -Normal + -Subnormal + -Zero + +Zero + +Subnormal + +Normal + +Infinity + + >>> c = ExtendedContext.copy() + >>> c.Emin = -999 + >>> c.Emax = 999 + >>> c.number_class(Decimal('Infinity')) + '+Infinity' + >>> c.number_class(Decimal('1E-10')) + '+Normal' + >>> c.number_class(Decimal('2.50')) + '+Normal' + >>> c.number_class(Decimal('0.1E-999')) + '+Subnormal' + >>> c.number_class(Decimal('0')) + '+Zero' + >>> c.number_class(Decimal('-0')) + '-Zero' + >>> c.number_class(Decimal('-0.1E-999')) + '-Subnormal' + >>> c.number_class(Decimal('-1E-10')) + '-Normal' + >>> c.number_class(Decimal('-2.50')) + '-Normal' + >>> c.number_class(Decimal('-Infinity')) + '-Infinity' + >>> c.number_class(Decimal('NaN')) + 'NaN' + >>> c.number_class(Decimal('-NaN')) + 'NaN' + >>> c.number_class(Decimal('sNaN')) + 'sNaN' + >>> c.number_class(123) + '+Normal' + """ + a = _convert_other(a, raiseit=True) + return a.number_class(context=self) + + def plus(self, a): + """Plus corresponds to unary prefix plus in Python. + + The operation is evaluated using the same rules as add; the + operation plus(a) is calculated as add('0', a) where the '0' + has the same exponent as the operand. + + >>> ExtendedContext.plus(Decimal('1.3')) + Decimal('1.3') + >>> ExtendedContext.plus(Decimal('-1.3')) + Decimal('-1.3') + >>> ExtendedContext.plus(-1) + Decimal('-1') + """ + a = _convert_other(a, raiseit=True) + return a.__pos__(context=self) + + def power(self, a, b, modulo=None): + """Raises a to the power of b, to modulo if given. + + With two arguments, compute a**b. If a is negative then b + must be integral. The result will be inexact unless b is + integral and the result is finite and can be expressed exactly + in 'precision' digits. + + With three arguments, compute (a**b) % modulo. For the + three argument form, the following restrictions on the + arguments hold: + + - all three arguments must be integral + - b must be nonnegative + - at least one of a or b must be nonzero + - modulo must be nonzero and have at most 'precision' digits + + The result of pow(a, b, modulo) is identical to the result + that would be obtained by computing (a**b) % modulo with + unbounded precision, but is computed more efficiently. It is + always exact. + + >>> c = ExtendedContext.copy() + >>> c.Emin = -999 + >>> c.Emax = 999 + >>> c.power(Decimal('2'), Decimal('3')) + Decimal('8') + >>> c.power(Decimal('-2'), Decimal('3')) + Decimal('-8') + >>> c.power(Decimal('2'), Decimal('-3')) + Decimal('0.125') + >>> c.power(Decimal('1.7'), Decimal('8')) + Decimal('69.7575744') + >>> c.power(Decimal('10'), Decimal('0.301029996')) + Decimal('2.00000000') + >>> c.power(Decimal('Infinity'), Decimal('-1')) + Decimal('0') + >>> c.power(Decimal('Infinity'), Decimal('0')) + Decimal('1') + >>> c.power(Decimal('Infinity'), Decimal('1')) + Decimal('Infinity') + >>> c.power(Decimal('-Infinity'), Decimal('-1')) + Decimal('-0') + >>> c.power(Decimal('-Infinity'), Decimal('0')) + Decimal('1') + >>> c.power(Decimal('-Infinity'), Decimal('1')) + Decimal('-Infinity') + >>> c.power(Decimal('-Infinity'), Decimal('2')) + Decimal('Infinity') + >>> c.power(Decimal('0'), Decimal('0')) + Decimal('NaN') + + >>> c.power(Decimal('3'), Decimal('7'), Decimal('16')) + Decimal('11') + >>> c.power(Decimal('-3'), Decimal('7'), Decimal('16')) + Decimal('-11') + >>> c.power(Decimal('-3'), Decimal('8'), Decimal('16')) + Decimal('1') + >>> c.power(Decimal('3'), Decimal('7'), Decimal('-16')) + Decimal('11') + >>> c.power(Decimal('23E12345'), Decimal('67E189'), Decimal('123456789')) + Decimal('11729830') + >>> c.power(Decimal('-0'), Decimal('17'), Decimal('1729')) + Decimal('-0') + >>> c.power(Decimal('-23'), Decimal('0'), Decimal('65537')) + Decimal('1') + >>> ExtendedContext.power(7, 7) + Decimal('823543') + >>> ExtendedContext.power(Decimal(7), 7) + Decimal('823543') + >>> ExtendedContext.power(7, Decimal(7), 2) + Decimal('1') + """ + a = _convert_other(a, raiseit=True) + r = a.__pow__(b, modulo, context=self) + if r is NotImplemented: + raise TypeError("Unable to convert %s to Decimal" % b) + else: + return r + + def quantize(self, a, b): + """Returns a value equal to 'a' (rounded), having the exponent of 'b'. + + The coefficient of the result is derived from that of the left-hand + operand. It may be rounded using the current rounding setting (if the + exponent is being increased), multiplied by a positive power of ten (if + the exponent is being decreased), or is unchanged (if the exponent is + already equal to that of the right-hand operand). + + Unlike other operations, if the length of the coefficient after the + quantize operation would be greater than precision then an Invalid + operation condition is raised. This guarantees that, unless there is + an error condition, the exponent of the result of a quantize is always + equal to that of the right-hand operand. + + Also unlike other operations, quantize will never raise Underflow, even + if the result is subnormal and inexact. + + >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.001')) + Decimal('2.170') + >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.01')) + Decimal('2.17') + >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.1')) + Decimal('2.2') + >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+0')) + Decimal('2') + >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+1')) + Decimal('0E+1') + >>> ExtendedContext.quantize(Decimal('-Inf'), Decimal('Infinity')) + Decimal('-Infinity') + >>> ExtendedContext.quantize(Decimal('2'), Decimal('Infinity')) + Decimal('NaN') + >>> ExtendedContext.quantize(Decimal('-0.1'), Decimal('1')) + Decimal('-0') + >>> ExtendedContext.quantize(Decimal('-0'), Decimal('1e+5')) + Decimal('-0E+5') + >>> ExtendedContext.quantize(Decimal('+35236450.6'), Decimal('1e-2')) + Decimal('NaN') + >>> ExtendedContext.quantize(Decimal('-35236450.6'), Decimal('1e-2')) + Decimal('NaN') + >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-1')) + Decimal('217.0') + >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-0')) + Decimal('217') + >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+1')) + Decimal('2.2E+2') + >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+2')) + Decimal('2E+2') + >>> ExtendedContext.quantize(1, 2) + Decimal('1') + >>> ExtendedContext.quantize(Decimal(1), 2) + Decimal('1') + >>> ExtendedContext.quantize(1, Decimal(2)) + Decimal('1') + """ + a = _convert_other(a, raiseit=True) + return a.quantize(b, context=self) + + def radix(self): + """Just returns 10, as this is Decimal, :) + + >>> ExtendedContext.radix() + Decimal('10') + """ + return Decimal(10) + + def remainder(self, a, b): + """Returns the remainder from integer division. + + The result is the residue of the dividend after the operation of + calculating integer division as described for divide-integer, rounded + to precision digits if necessary. The sign of the result, if + non-zero, is the same as that of the original dividend. + + This operation will fail under the same conditions as integer division + (that is, if integer division on the same two operands would fail, the + remainder cannot be calculated). + + >>> ExtendedContext.remainder(Decimal('2.1'), Decimal('3')) + Decimal('2.1') + >>> ExtendedContext.remainder(Decimal('10'), Decimal('3')) + Decimal('1') + >>> ExtendedContext.remainder(Decimal('-10'), Decimal('3')) + Decimal('-1') + >>> ExtendedContext.remainder(Decimal('10.2'), Decimal('1')) + Decimal('0.2') + >>> ExtendedContext.remainder(Decimal('10'), Decimal('0.3')) + Decimal('0.1') + >>> ExtendedContext.remainder(Decimal('3.6'), Decimal('1.3')) + Decimal('1.0') + >>> ExtendedContext.remainder(22, 6) + Decimal('4') + >>> ExtendedContext.remainder(Decimal(22), 6) + Decimal('4') + >>> ExtendedContext.remainder(22, Decimal(6)) + Decimal('4') + """ + a = _convert_other(a, raiseit=True) + r = a.__mod__(b, context=self) + if r is NotImplemented: + raise TypeError("Unable to convert %s to Decimal" % b) + else: + return r + + def remainder_near(self, a, b): + """Returns to be "a - b * n", where n is the integer nearest the exact + value of "x / b" (if two integers are equally near then the even one + is chosen). If the result is equal to 0 then its sign will be the + sign of a. + + This operation will fail under the same conditions as integer division + (that is, if integer division on the same two operands would fail, the + remainder cannot be calculated). + + >>> ExtendedContext.remainder_near(Decimal('2.1'), Decimal('3')) + Decimal('-0.9') + >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('6')) + Decimal('-2') + >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('3')) + Decimal('1') + >>> ExtendedContext.remainder_near(Decimal('-10'), Decimal('3')) + Decimal('-1') + >>> ExtendedContext.remainder_near(Decimal('10.2'), Decimal('1')) + Decimal('0.2') + >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('0.3')) + Decimal('0.1') + >>> ExtendedContext.remainder_near(Decimal('3.6'), Decimal('1.3')) + Decimal('-0.3') + >>> ExtendedContext.remainder_near(3, 11) + Decimal('3') + >>> ExtendedContext.remainder_near(Decimal(3), 11) + Decimal('3') + >>> ExtendedContext.remainder_near(3, Decimal(11)) + Decimal('3') + """ + a = _convert_other(a, raiseit=True) + return a.remainder_near(b, context=self) + + def rotate(self, a, b): + """Returns a rotated copy of a, b times. + + The coefficient of the result is a rotated copy of the digits in + the coefficient of the first operand. The number of places of + rotation is taken from the absolute value of the second operand, + with the rotation being to the left if the second operand is + positive or to the right otherwise. + + >>> ExtendedContext.rotate(Decimal('34'), Decimal('8')) + Decimal('400000003') + >>> ExtendedContext.rotate(Decimal('12'), Decimal('9')) + Decimal('12') + >>> ExtendedContext.rotate(Decimal('123456789'), Decimal('-2')) + Decimal('891234567') + >>> ExtendedContext.rotate(Decimal('123456789'), Decimal('0')) + Decimal('123456789') + >>> ExtendedContext.rotate(Decimal('123456789'), Decimal('+2')) + Decimal('345678912') + >>> ExtendedContext.rotate(1333333, 1) + Decimal('13333330') + >>> ExtendedContext.rotate(Decimal(1333333), 1) + Decimal('13333330') + >>> ExtendedContext.rotate(1333333, Decimal(1)) + Decimal('13333330') + """ + a = _convert_other(a, raiseit=True) + return a.rotate(b, context=self) + + def same_quantum(self, a, b): + """Returns True if the two operands have the same exponent. + + The result is never affected by either the sign or the coefficient of + either operand. + + >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.001')) + False + >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.01')) + True + >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('1')) + False + >>> ExtendedContext.same_quantum(Decimal('Inf'), Decimal('-Inf')) + True + >>> ExtendedContext.same_quantum(10000, -1) + True + >>> ExtendedContext.same_quantum(Decimal(10000), -1) + True + >>> ExtendedContext.same_quantum(10000, Decimal(-1)) + True + """ + a = _convert_other(a, raiseit=True) + return a.same_quantum(b) + + def scaleb (self, a, b): + """Returns the first operand after adding the second value its exp. + + >>> ExtendedContext.scaleb(Decimal('7.50'), Decimal('-2')) + Decimal('0.0750') + >>> ExtendedContext.scaleb(Decimal('7.50'), Decimal('0')) + Decimal('7.50') + >>> ExtendedContext.scaleb(Decimal('7.50'), Decimal('3')) + Decimal('7.50E+3') + >>> ExtendedContext.scaleb(1, 4) + Decimal('1E+4') + >>> ExtendedContext.scaleb(Decimal(1), 4) + Decimal('1E+4') + >>> ExtendedContext.scaleb(1, Decimal(4)) + Decimal('1E+4') + """ + a = _convert_other(a, raiseit=True) + return a.scaleb(b, context=self) + + def shift(self, a, b): + """Returns a shifted copy of a, b times. + + The coefficient of the result is a shifted copy of the digits + in the coefficient of the first operand. The number of places + to shift is taken from the absolute value of the second operand, + with the shift being to the left if the second operand is + positive or to the right otherwise. Digits shifted into the + coefficient are zeros. + + >>> ExtendedContext.shift(Decimal('34'), Decimal('8')) + Decimal('400000000') + >>> ExtendedContext.shift(Decimal('12'), Decimal('9')) + Decimal('0') + >>> ExtendedContext.shift(Decimal('123456789'), Decimal('-2')) + Decimal('1234567') + >>> ExtendedContext.shift(Decimal('123456789'), Decimal('0')) + Decimal('123456789') + >>> ExtendedContext.shift(Decimal('123456789'), Decimal('+2')) + Decimal('345678900') + >>> ExtendedContext.shift(88888888, 2) + Decimal('888888800') + >>> ExtendedContext.shift(Decimal(88888888), 2) + Decimal('888888800') + >>> ExtendedContext.shift(88888888, Decimal(2)) + Decimal('888888800') + """ + a = _convert_other(a, raiseit=True) + return a.shift(b, context=self) + + def sqrt(self, a): + """Square root of a non-negative number to context precision. + + If the result must be inexact, it is rounded using the round-half-even + algorithm. + + >>> ExtendedContext.sqrt(Decimal('0')) + Decimal('0') + >>> ExtendedContext.sqrt(Decimal('-0')) + Decimal('-0') + >>> ExtendedContext.sqrt(Decimal('0.39')) + Decimal('0.624499800') + >>> ExtendedContext.sqrt(Decimal('100')) + Decimal('10') + >>> ExtendedContext.sqrt(Decimal('1')) + Decimal('1') + >>> ExtendedContext.sqrt(Decimal('1.0')) + Decimal('1.0') + >>> ExtendedContext.sqrt(Decimal('1.00')) + Decimal('1.0') + >>> ExtendedContext.sqrt(Decimal('7')) + Decimal('2.64575131') + >>> ExtendedContext.sqrt(Decimal('10')) + Decimal('3.16227766') + >>> ExtendedContext.sqrt(2) + Decimal('1.41421356') + >>> ExtendedContext.prec + 9 + """ + a = _convert_other(a, raiseit=True) + return a.sqrt(context=self) + + def subtract(self, a, b): + """Return the difference between the two operands. + + >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.07')) + Decimal('0.23') + >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.30')) + Decimal('0.00') + >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('2.07')) + Decimal('-0.77') + >>> ExtendedContext.subtract(8, 5) + Decimal('3') + >>> ExtendedContext.subtract(Decimal(8), 5) + Decimal('3') + >>> ExtendedContext.subtract(8, Decimal(5)) + Decimal('3') + """ + a = _convert_other(a, raiseit=True) + r = a.__sub__(b, context=self) + if r is NotImplemented: + raise TypeError("Unable to convert %s to Decimal" % b) + else: + return r + + def to_eng_string(self, a): + """Converts a number to a string, using scientific notation. + + The operation is not affected by the context. + """ + a = _convert_other(a, raiseit=True) + return a.to_eng_string(context=self) + + def to_sci_string(self, a): + """Converts a number to a string, using scientific notation. + + The operation is not affected by the context. + """ + a = _convert_other(a, raiseit=True) + return a.__str__(context=self) + + def to_integral_exact(self, a): + """Rounds to an integer. + + When the operand has a negative exponent, the result is the same + as using the quantize() operation using the given operand as the + left-hand-operand, 1E+0 as the right-hand-operand, and the precision + of the operand as the precision setting; Inexact and Rounded flags + are allowed in this operation. The rounding mode is taken from the + context. + + >>> ExtendedContext.to_integral_exact(Decimal('2.1')) + Decimal('2') + >>> ExtendedContext.to_integral_exact(Decimal('100')) + Decimal('100') + >>> ExtendedContext.to_integral_exact(Decimal('100.0')) + Decimal('100') + >>> ExtendedContext.to_integral_exact(Decimal('101.5')) + Decimal('102') + >>> ExtendedContext.to_integral_exact(Decimal('-101.5')) + Decimal('-102') + >>> ExtendedContext.to_integral_exact(Decimal('10E+5')) + Decimal('1.0E+6') + >>> ExtendedContext.to_integral_exact(Decimal('7.89E+77')) + Decimal('7.89E+77') + >>> ExtendedContext.to_integral_exact(Decimal('-Inf')) + Decimal('-Infinity') + """ + a = _convert_other(a, raiseit=True) + return a.to_integral_exact(context=self) + + def to_integral_value(self, a): + """Rounds to an integer. + + When the operand has a negative exponent, the result is the same + as using the quantize() operation using the given operand as the + left-hand-operand, 1E+0 as the right-hand-operand, and the precision + of the operand as the precision setting, except that no flags will + be set. The rounding mode is taken from the context. + + >>> ExtendedContext.to_integral_value(Decimal('2.1')) + Decimal('2') + >>> ExtendedContext.to_integral_value(Decimal('100')) + Decimal('100') + >>> ExtendedContext.to_integral_value(Decimal('100.0')) + Decimal('100') + >>> ExtendedContext.to_integral_value(Decimal('101.5')) + Decimal('102') + >>> ExtendedContext.to_integral_value(Decimal('-101.5')) + Decimal('-102') + >>> ExtendedContext.to_integral_value(Decimal('10E+5')) + Decimal('1.0E+6') + >>> ExtendedContext.to_integral_value(Decimal('7.89E+77')) + Decimal('7.89E+77') + >>> ExtendedContext.to_integral_value(Decimal('-Inf')) + Decimal('-Infinity') + """ + a = _convert_other(a, raiseit=True) + return a.to_integral_value(context=self) + + # the method name changed, but we provide also the old one, for compatibility + to_integral = to_integral_value + +class _WorkRep(object): + __slots__ = ('sign','int','exp') + # sign: 0 or 1 + # int: int + # exp: None, int, or string + + def __init__(self, value=None): + if value is None: + self.sign = None + self.int = 0 + self.exp = None + elif isinstance(value, Decimal): + self.sign = value._sign + self.int = int(value._int) + self.exp = value._exp + else: + # assert isinstance(value, tuple) + self.sign = value[0] + self.int = value[1] + self.exp = value[2] + + def __repr__(self): + return "(%r, %r, %r)" % (self.sign, self.int, self.exp) + + __str__ = __repr__ + + + +def _normalize(op1, op2, prec = 0): + """Normalizes op1, op2 to have the same exp and length of coefficient. + + Done during addition. + """ + if op1.exp < op2.exp: + tmp = op2 + other = op1 + else: + tmp = op1 + other = op2 + + # Let exp = min(tmp.exp - 1, tmp.adjusted() - precision - 1). + # Then adding 10**exp to tmp has the same effect (after rounding) + # as adding any positive quantity smaller than 10**exp; similarly + # for subtraction. So if other is smaller than 10**exp we replace + # it with 10**exp. This avoids tmp.exp - other.exp getting too large. + tmp_len = len(str(tmp.int)) + other_len = len(str(other.int)) + exp = tmp.exp + min(-1, tmp_len - prec - 2) + if other_len + other.exp - 1 < exp: + other.int = 1 + other.exp = exp + + tmp.int *= 10 ** (tmp.exp - other.exp) + tmp.exp = other.exp + return op1, op2 + +##### Integer arithmetic functions used by ln, log10, exp and __pow__ ##### + +_nbits = int.bit_length + +def _decimal_lshift_exact(n, e): + """ Given integers n and e, return n * 10**e if it's an integer, else None. + + The computation is designed to avoid computing large powers of 10 + unnecessarily. + + >>> _decimal_lshift_exact(3, 4) + 30000 + >>> _decimal_lshift_exact(300, -999999999) # returns None + + """ + if n == 0: + return 0 + elif e >= 0: + return n * 10**e + else: + # val_n = largest power of 10 dividing n. + str_n = str(abs(n)) + val_n = len(str_n) - len(str_n.rstrip('0')) + return None if val_n < -e else n // 10**-e + +def _sqrt_nearest(n, a): + """Closest integer to the square root of the positive integer n. a is + an initial approximation to the square root. Any positive integer + will do for a, but the closer a is to the square root of n the + faster convergence will be. + + """ + if n <= 0 or a <= 0: + raise ValueError("Both arguments to _sqrt_nearest should be positive.") + + b=0 + while a != b: + b, a = a, a--n//a>>1 + return a + +def _rshift_nearest(x, shift): + """Given an integer x and a nonnegative integer shift, return closest + integer to x / 2**shift; use round-to-even in case of a tie. + + """ + b, q = 1 << shift, x >> shift + return q + (2*(x & (b-1)) + (q&1) > b) + +def _div_nearest(a, b): + """Closest integer to a/b, a and b positive integers; rounds to even + in the case of a tie. + + """ + q, r = divmod(a, b) + return q + (2*r + (q&1) > b) + +def _ilog(x, M, L = 8): + """Integer approximation to M*log(x/M), with absolute error boundable + in terms only of x/M. + + Given positive integers x and M, return an integer approximation to + M * log(x/M). For L = 8 and 0.1 <= x/M <= 10 the difference + between the approximation and the exact result is at most 22. For + L = 8 and 1.0 <= x/M <= 10.0 the difference is at most 15. In + both cases these are upper bounds on the error; it will usually be + much smaller.""" + + # The basic algorithm is the following: let log1p be the function + # log1p(x) = log(1+x). Then log(x/M) = log1p((x-M)/M). We use + # the reduction + # + # log1p(y) = 2*log1p(y/(1+sqrt(1+y))) + # + # repeatedly until the argument to log1p is small (< 2**-L in + # absolute value). For small y we can use the Taylor series + # expansion + # + # log1p(y) ~ y - y**2/2 + y**3/3 - ... - (-y)**T/T + # + # truncating at T such that y**T is small enough. The whole + # computation is carried out in a form of fixed-point arithmetic, + # with a real number z being represented by an integer + # approximation to z*M. To avoid loss of precision, the y below + # is actually an integer approximation to 2**R*y*M, where R is the + # number of reductions performed so far. + + y = x-M + # argument reduction; R = number of reductions performed + R = 0 + while (R <= L and abs(y) << L-R >= M or + R > L and abs(y) >> R-L >= M): + y = _div_nearest((M*y) << 1, + M + _sqrt_nearest(M*(M+_rshift_nearest(y, R)), M)) + R += 1 + + # Taylor series with T terms + T = -int(-10*len(str(M))//(3*L)) + yshift = _rshift_nearest(y, R) + w = _div_nearest(M, T) + for k in range(T-1, 0, -1): + w = _div_nearest(M, k) - _div_nearest(yshift*w, M) + + return _div_nearest(w*y, M) + +def _dlog10(c, e, p): + """Given integers c, e and p with c > 0, p >= 0, compute an integer + approximation to 10**p * log10(c*10**e), with an absolute error of + at most 1. Assumes that c*10**e is not exactly 1.""" + + # increase precision by 2; compensate for this by dividing + # final result by 100 + p += 2 + + # write c*10**e as d*10**f with either: + # f >= 0 and 1 <= d <= 10, or + # f <= 0 and 0.1 <= d <= 1. + # Thus for c*10**e close to 1, f = 0 + l = len(str(c)) + f = e+l - (e+l >= 1) + + if p > 0: + M = 10**p + k = e+p-f + if k >= 0: + c *= 10**k + else: + c = _div_nearest(c, 10**-k) + + log_d = _ilog(c, M) # error < 5 + 22 = 27 + log_10 = _log10_digits(p) # error < 1 + log_d = _div_nearest(log_d*M, log_10) + log_tenpower = f*M # exact + else: + log_d = 0 # error < 2.31 + log_tenpower = _div_nearest(f, 10**-p) # error < 0.5 + + return _div_nearest(log_tenpower+log_d, 100) + +def _dlog(c, e, p): + """Given integers c, e and p with c > 0, compute an integer + approximation to 10**p * log(c*10**e), with an absolute error of + at most 1. Assumes that c*10**e is not exactly 1.""" + + # Increase precision by 2. The precision increase is compensated + # for at the end with a division by 100. + p += 2 + + # rewrite c*10**e as d*10**f with either f >= 0 and 1 <= d <= 10, + # or f <= 0 and 0.1 <= d <= 1. Then we can compute 10**p * log(c*10**e) + # as 10**p * log(d) + 10**p*f * log(10). + l = len(str(c)) + f = e+l - (e+l >= 1) + + # compute approximation to 10**p*log(d), with error < 27 + if p > 0: + k = e+p-f + if k >= 0: + c *= 10**k + else: + c = _div_nearest(c, 10**-k) # error of <= 0.5 in c + + # _ilog magnifies existing error in c by a factor of at most 10 + log_d = _ilog(c, 10**p) # error < 5 + 22 = 27 + else: + # p <= 0: just approximate the whole thing by 0; error < 2.31 + log_d = 0 + + # compute approximation to f*10**p*log(10), with error < 11. + if f: + extra = len(str(abs(f)))-1 + if p + extra >= 0: + # error in f * _log10_digits(p+extra) < |f| * 1 = |f| + # after division, error < |f|/10**extra + 0.5 < 10 + 0.5 < 11 + f_log_ten = _div_nearest(f*_log10_digits(p+extra), 10**extra) + else: + f_log_ten = 0 + else: + f_log_ten = 0 + + # error in sum < 11+27 = 38; error after division < 0.38 + 0.5 < 1 + return _div_nearest(f_log_ten + log_d, 100) + +class _Log10Memoize(object): + """Class to compute, store, and allow retrieval of, digits of the + constant log(10) = 2.302585.... This constant is needed by + Decimal.ln, Decimal.log10, Decimal.exp and Decimal.__pow__.""" + def __init__(self): + self.digits = "23025850929940456840179914546843642076011014886" + + def getdigits(self, p): + """Given an integer p >= 0, return floor(10**p)*log(10). + + For example, self.getdigits(3) returns 2302. + """ + # digits are stored as a string, for quick conversion to + # integer in the case that we've already computed enough + # digits; the stored digits should always be correct + # (truncated, not rounded to nearest). + if p < 0: + raise ValueError("p should be nonnegative") + + if p >= len(self.digits): + # compute p+3, p+6, p+9, ... digits; continue until at + # least one of the extra digits is nonzero + extra = 3 + while True: + # compute p+extra digits, correct to within 1ulp + M = 10**(p+extra+2) + digits = str(_div_nearest(_ilog(10*M, M), 100)) + if digits[-extra:] != '0'*extra: + break + extra += 3 + # keep all reliable digits so far; remove trailing zeros + # and next nonzero digit + self.digits = digits.rstrip('0')[:-1] + return int(self.digits[:p+1]) + +_log10_digits = _Log10Memoize().getdigits + +def _iexp(x, M, L=8): + """Given integers x and M, M > 0, such that x/M is small in absolute + value, compute an integer approximation to M*exp(x/M). For 0 <= + x/M <= 2.4, the absolute error in the result is bounded by 60 (and + is usually much smaller).""" + + # Algorithm: to compute exp(z) for a real number z, first divide z + # by a suitable power R of 2 so that |z/2**R| < 2**-L. Then + # compute expm1(z/2**R) = exp(z/2**R) - 1 using the usual Taylor + # series + # + # expm1(x) = x + x**2/2! + x**3/3! + ... + # + # Now use the identity + # + # expm1(2x) = expm1(x)*(expm1(x)+2) + # + # R times to compute the sequence expm1(z/2**R), + # expm1(z/2**(R-1)), ... , exp(z/2), exp(z). + + # Find R such that x/2**R/M <= 2**-L + R = _nbits((x<<L)//M) + + # Taylor series. (2**L)**T > M + T = -int(-10*len(str(M))//(3*L)) + y = _div_nearest(x, T) + Mshift = M<<R + for i in range(T-1, 0, -1): + y = _div_nearest(x*(Mshift + y), Mshift * i) + + # Expansion + for k in range(R-1, -1, -1): + Mshift = M<<(k+2) + y = _div_nearest(y*(y+Mshift), Mshift) + + return M+y + +def _dexp(c, e, p): + """Compute an approximation to exp(c*10**e), with p decimal places of + precision. + + Returns integers d, f such that: + + 10**(p-1) <= d <= 10**p, and + (d-1)*10**f < exp(c*10**e) < (d+1)*10**f + + In other words, d*10**f is an approximation to exp(c*10**e) with p + digits of precision, and with an error in d of at most 1. This is + almost, but not quite, the same as the error being < 1ulp: when d + = 10**(p-1) the error could be up to 10 ulp.""" + + # we'll call iexp with M = 10**(p+2), giving p+3 digits of precision + p += 2 + + # compute log(10) with extra precision = adjusted exponent of c*10**e + extra = max(0, e + len(str(c)) - 1) + q = p + extra + + # compute quotient c*10**e/(log(10)) = c*10**(e+q)/(log(10)*10**q), + # rounding down + shift = e+q + if shift >= 0: + cshift = c*10**shift + else: + cshift = c//10**-shift + quot, rem = divmod(cshift, _log10_digits(q)) + + # reduce remainder back to original precision + rem = _div_nearest(rem, 10**extra) + + # error in result of _iexp < 120; error after division < 0.62 + return _div_nearest(_iexp(rem, 10**p), 1000), quot - p + 3 + +def _dpower(xc, xe, yc, ye, p): + """Given integers xc, xe, yc and ye representing Decimals x = xc*10**xe and + y = yc*10**ye, compute x**y. Returns a pair of integers (c, e) such that: + + 10**(p-1) <= c <= 10**p, and + (c-1)*10**e < x**y < (c+1)*10**e + + in other words, c*10**e is an approximation to x**y with p digits + of precision, and with an error in c of at most 1. (This is + almost, but not quite, the same as the error being < 1ulp: when c + == 10**(p-1) we can only guarantee error < 10ulp.) + + We assume that: x is positive and not equal to 1, and y is nonzero. + """ + + # Find b such that 10**(b-1) <= |y| <= 10**b + b = len(str(abs(yc))) + ye + + # log(x) = lxc*10**(-p-b-1), to p+b+1 places after the decimal point + lxc = _dlog(xc, xe, p+b+1) + + # compute product y*log(x) = yc*lxc*10**(-p-b-1+ye) = pc*10**(-p-1) + shift = ye-b + if shift >= 0: + pc = lxc*yc*10**shift + else: + pc = _div_nearest(lxc*yc, 10**-shift) + + if pc == 0: + # we prefer a result that isn't exactly 1; this makes it + # easier to compute a correctly rounded result in __pow__ + if ((len(str(xc)) + xe >= 1) == (yc > 0)): # if x**y > 1: + coeff, exp = 10**(p-1)+1, 1-p + else: + coeff, exp = 10**p-1, -p + else: + coeff, exp = _dexp(pc, -(p+1), p+1) + coeff = _div_nearest(coeff, 10) + exp += 1 + + return coeff, exp + +def _log10_lb(c, correction = { + '1': 100, '2': 70, '3': 53, '4': 40, '5': 31, + '6': 23, '7': 16, '8': 10, '9': 5}): + """Compute a lower bound for 100*log10(c) for a positive integer c.""" + if c <= 0: + raise ValueError("The argument to _log10_lb should be nonnegative.") + str_c = str(c) + return 100*len(str_c) - correction[str_c[0]] + +##### Helper Functions #################################################### + +def _convert_other(other, raiseit=False, allow_float=False): + """Convert other to Decimal. + + Verifies that it's ok to use in an implicit construction. + If allow_float is true, allow conversion from float; this + is used in the comparison methods (__eq__ and friends). + + """ + if isinstance(other, Decimal): + return other + if isinstance(other, int): + return Decimal(other) + if allow_float and isinstance(other, float): + return Decimal.from_float(other) + + if raiseit: + raise TypeError("Unable to convert %s to Decimal" % other) + return NotImplemented + +def _convert_for_comparison(self, other, equality_op=False): + """Given a Decimal instance self and a Python object other, return + a pair (s, o) of Decimal instances such that "s op o" is + equivalent to "self op other" for any of the 6 comparison + operators "op". + + """ + if isinstance(other, Decimal): + return self, other + + # Comparison with a Rational instance (also includes integers): + # self op n/d <=> self*d op n (for n and d integers, d positive). + # A NaN or infinity can be left unchanged without affecting the + # comparison result. + if isinstance(other, _numbers.Rational): + if not self._is_special: + self = _dec_from_triple(self._sign, + str(int(self._int) * other.denominator), + self._exp) + return self, Decimal(other.numerator) + + # Comparisons with float and complex types. == and != comparisons + # with complex numbers should succeed, returning either True or False + # as appropriate. Other comparisons return NotImplemented. + if equality_op and isinstance(other, _numbers.Complex) and other.imag == 0: + other = other.real + if isinstance(other, float): + context = getcontext() + if equality_op: + context.flags[FloatOperation] = 1 + else: + context._raise_error(FloatOperation, + "strict semantics for mixing floats and Decimals are enabled") + return self, Decimal.from_float(other) + return NotImplemented, NotImplemented + + +##### Setup Specific Contexts ############################################ + +# The default context prototype used by Context() +# Is mutable, so that new contexts can have different default values + +DefaultContext = Context( + prec=28, rounding=ROUND_HALF_EVEN, + traps=[DivisionByZero, Overflow, InvalidOperation], + flags=[], + Emax=999999, + Emin=-999999, + capitals=1, + clamp=0 +) + +# Pre-made alternate contexts offered by the specification +# Don't change these; the user should be able to select these +# contexts and be able to reproduce results from other implementations +# of the spec. + +BasicContext = Context( + prec=9, rounding=ROUND_HALF_UP, + traps=[DivisionByZero, Overflow, InvalidOperation, Clamped, Underflow], + flags=[], +) + +ExtendedContext = Context( + prec=9, rounding=ROUND_HALF_EVEN, + traps=[], + flags=[], +) + + +##### crud for parsing strings ############################################# +# +# Regular expression used for parsing numeric strings. Additional +# comments: +# +# 1. Uncomment the two '\s*' lines to allow leading and/or trailing +# whitespace. But note that the specification disallows whitespace in +# a numeric string. +# +# 2. For finite numbers (not infinities and NaNs) the body of the +# number between the optional sign and the optional exponent must have +# at least one decimal digit, possibly after the decimal point. The +# lookahead expression '(?=\d|\.\d)' checks this. + +import re +_parser = re.compile(r""" # A numeric string consists of: +# \s* + (?P<sign>[-+])? # an optional sign, followed by either... + ( + (?=\d|\.\d) # ...a number (with at least one digit) + (?P<int>\d*) # having a (possibly empty) integer part + (\.(?P<frac>\d*))? # followed by an optional fractional part + (E(?P<exp>[-+]?\d+))? # followed by an optional exponent, or... + | + Inf(inity)? # ...an infinity, or... + | + (?P<signal>s)? # ...an (optionally signaling) + NaN # NaN + (?P<diag>\d*) # with (possibly empty) diagnostic info. + ) +# \s* + \Z +""", re.VERBOSE | re.IGNORECASE).match + +_all_zeros = re.compile('0*$').match +_exact_half = re.compile('50*$').match + +##### PEP3101 support functions ############################################## +# The functions in this section have little to do with the Decimal +# class, and could potentially be reused or adapted for other pure +# Python numeric classes that want to implement __format__ +# +# A format specifier for Decimal looks like: +# +# [[fill]align][sign][#][0][minimumwidth][,][.precision][type] + +_parse_format_specifier_regex = re.compile(r"""\A +(?: + (?P<fill>.)? + (?P<align>[<>=^]) +)? +(?P<sign>[-+ ])? +(?P<alt>\#)? +(?P<zeropad>0)? +(?P<minimumwidth>(?!0)\d+)? +(?P<thousands_sep>,)? +(?:\.(?P<precision>0|(?!0)\d+))? +(?P<type>[eEfFgGn%])? +\Z +""", re.VERBOSE|re.DOTALL) + +del re + +# The locale module is only needed for the 'n' format specifier. The +# rest of the PEP 3101 code functions quite happily without it, so we +# don't care too much if locale isn't present. +try: + import locale as _locale +except ImportError: + pass + +def _parse_format_specifier(format_spec, _localeconv=None): + """Parse and validate a format specifier. + + Turns a standard numeric format specifier into a dict, with the + following entries: + + fill: fill character to pad field to minimum width + align: alignment type, either '<', '>', '=' or '^' + sign: either '+', '-' or ' ' + minimumwidth: nonnegative integer giving minimum width + zeropad: boolean, indicating whether to pad with zeros + thousands_sep: string to use as thousands separator, or '' + grouping: grouping for thousands separators, in format + used by localeconv + decimal_point: string to use for decimal point + precision: nonnegative integer giving precision, or None + type: one of the characters 'eEfFgG%', or None + + """ + m = _parse_format_specifier_regex.match(format_spec) + if m is None: + raise ValueError("Invalid format specifier: " + format_spec) + + # get the dictionary + format_dict = m.groupdict() + + # zeropad; defaults for fill and alignment. If zero padding + # is requested, the fill and align fields should be absent. + fill = format_dict['fill'] + align = format_dict['align'] + format_dict['zeropad'] = (format_dict['zeropad'] is not None) + if format_dict['zeropad']: + if fill is not None: + raise ValueError("Fill character conflicts with '0'" + " in format specifier: " + format_spec) + if align is not None: + raise ValueError("Alignment conflicts with '0' in " + "format specifier: " + format_spec) + format_dict['fill'] = fill or ' ' + # PEP 3101 originally specified that the default alignment should + # be left; it was later agreed that right-aligned makes more sense + # for numeric types. See http://bugs.python.org/issue6857. + format_dict['align'] = align or '>' + + # default sign handling: '-' for negative, '' for positive + if format_dict['sign'] is None: + format_dict['sign'] = '-' + + # minimumwidth defaults to 0; precision remains None if not given + format_dict['minimumwidth'] = int(format_dict['minimumwidth'] or '0') + if format_dict['precision'] is not None: + format_dict['precision'] = int(format_dict['precision']) + + # if format type is 'g' or 'G' then a precision of 0 makes little + # sense; convert it to 1. Same if format type is unspecified. + if format_dict['precision'] == 0: + if format_dict['type'] is None or format_dict['type'] in 'gGn': + format_dict['precision'] = 1 + + # determine thousands separator, grouping, and decimal separator, and + # add appropriate entries to format_dict + if format_dict['type'] == 'n': + # apart from separators, 'n' behaves just like 'g' + format_dict['type'] = 'g' + if _localeconv is None: + _localeconv = _locale.localeconv() + if format_dict['thousands_sep'] is not None: + raise ValueError("Explicit thousands separator conflicts with " + "'n' type in format specifier: " + format_spec) + format_dict['thousands_sep'] = _localeconv['thousands_sep'] + format_dict['grouping'] = _localeconv['grouping'] + format_dict['decimal_point'] = _localeconv['decimal_point'] + else: + if format_dict['thousands_sep'] is None: + format_dict['thousands_sep'] = '' + format_dict['grouping'] = [3, 0] + format_dict['decimal_point'] = '.' + + return format_dict + +def _format_align(sign, body, spec): + """Given an unpadded, non-aligned numeric string 'body' and sign + string 'sign', add padding and alignment conforming to the given + format specifier dictionary 'spec' (as produced by + parse_format_specifier). + + """ + # how much extra space do we have to play with? + minimumwidth = spec['minimumwidth'] + fill = spec['fill'] + padding = fill*(minimumwidth - len(sign) - len(body)) + + align = spec['align'] + if align == '<': + result = sign + body + padding + elif align == '>': + result = padding + sign + body + elif align == '=': + result = sign + padding + body + elif align == '^': + half = len(padding)//2 + result = padding[:half] + sign + body + padding[half:] + else: + raise ValueError('Unrecognised alignment field') + + return result + +def _group_lengths(grouping): + """Convert a localeconv-style grouping into a (possibly infinite) + iterable of integers representing group lengths. + + """ + # The result from localeconv()['grouping'], and the input to this + # function, should be a list of integers in one of the + # following three forms: + # + # (1) an empty list, or + # (2) nonempty list of positive integers + [0] + # (3) list of positive integers + [locale.CHAR_MAX], or + + from itertools import chain, repeat + if not grouping: + return [] + elif grouping[-1] == 0 and len(grouping) >= 2: + return chain(grouping[:-1], repeat(grouping[-2])) + elif grouping[-1] == _locale.CHAR_MAX: + return grouping[:-1] + else: + raise ValueError('unrecognised format for grouping') + +def _insert_thousands_sep(digits, spec, min_width=1): + """Insert thousands separators into a digit string. + + spec is a dictionary whose keys should include 'thousands_sep' and + 'grouping'; typically it's the result of parsing the format + specifier using _parse_format_specifier. + + The min_width keyword argument gives the minimum length of the + result, which will be padded on the left with zeros if necessary. + + If necessary, the zero padding adds an extra '0' on the left to + avoid a leading thousands separator. For example, inserting + commas every three digits in '123456', with min_width=8, gives + '0,123,456', even though that has length 9. + + """ + + sep = spec['thousands_sep'] + grouping = spec['grouping'] + + groups = [] + for l in _group_lengths(grouping): + if l <= 0: + raise ValueError("group length should be positive") + # max(..., 1) forces at least 1 digit to the left of a separator + l = min(max(len(digits), min_width, 1), l) + groups.append('0'*(l - len(digits)) + digits[-l:]) + digits = digits[:-l] + min_width -= l + if not digits and min_width <= 0: + break + min_width -= len(sep) + else: + l = max(len(digits), min_width, 1) + groups.append('0'*(l - len(digits)) + digits[-l:]) + return sep.join(reversed(groups)) + +def _format_sign(is_negative, spec): + """Determine sign character.""" + + if is_negative: + return '-' + elif spec['sign'] in ' +': + return spec['sign'] + else: + return '' + +def _format_number(is_negative, intpart, fracpart, exp, spec): + """Format a number, given the following data: + + is_negative: true if the number is negative, else false + intpart: string of digits that must appear before the decimal point + fracpart: string of digits that must come after the point + exp: exponent, as an integer + spec: dictionary resulting from parsing the format specifier + + This function uses the information in spec to: + insert separators (decimal separator and thousands separators) + format the sign + format the exponent + add trailing '%' for the '%' type + zero-pad if necessary + fill and align if necessary + """ + + sign = _format_sign(is_negative, spec) + + if fracpart or spec['alt']: + fracpart = spec['decimal_point'] + fracpart + + if exp != 0 or spec['type'] in 'eE': + echar = {'E': 'E', 'e': 'e', 'G': 'E', 'g': 'e'}[spec['type']] + fracpart += "{0}{1:+}".format(echar, exp) + if spec['type'] == '%': + fracpart += '%' + + if spec['zeropad']: + min_width = spec['minimumwidth'] - len(fracpart) - len(sign) + else: + min_width = 0 + intpart = _insert_thousands_sep(intpart, spec, min_width) + + return _format_align(sign, intpart+fracpart, spec) + + +##### Useful Constants (internal use only) ################################ + +# Reusable defaults +_Infinity = Decimal('Inf') +_NegativeInfinity = Decimal('-Inf') +_NaN = Decimal('NaN') +_Zero = Decimal(0) +_One = Decimal(1) +_NegativeOne = Decimal(-1) + +# _SignedInfinity[sign] is infinity w/ that sign +_SignedInfinity = (_Infinity, _NegativeInfinity) + +# Constants related to the hash implementation; hash(x) is based +# on the reduction of x modulo _PyHASH_MODULUS +_PyHASH_MODULUS = sys.hash_info.modulus +# hash values to use for positive and negative infinities, and nans +_PyHASH_INF = sys.hash_info.inf +_PyHASH_NAN = sys.hash_info.nan + +# _PyHASH_10INV is the inverse of 10 modulo the prime _PyHASH_MODULUS +_PyHASH_10INV = pow(10, _PyHASH_MODULUS - 2, _PyHASH_MODULUS) +del sys diff --git a/Lib/_pyio.py b/Lib/_pyio.py index d6eee79e016b..b0f011499940 100644 --- a/Lib/_pyio.py +++ b/Lib/_pyio.py @@ -6,6 +6,7 @@ import abc import codecs import errno +import array # Import _thread instead of threading to reduce startup cost try: from _thread import allocate_lock as Lock @@ -200,38 +201,45 @@ def open(file, mode="r", buffering=-1, encoding=None, errors=None, (appending and "a" or "") + (updating and "+" or ""), closefd, opener=opener) - line_buffering = False - if buffering == 1 or buffering < 0 and raw.isatty(): - buffering = -1 - line_buffering = True - if buffering < 0: - buffering = DEFAULT_BUFFER_SIZE - try: - bs = os.fstat(raw.fileno()).st_blksize - except (OSError, AttributeError): - pass + result = raw + try: + line_buffering = False + if buffering == 1 or buffering < 0 and raw.isatty(): + buffering = -1 + line_buffering = True + if buffering < 0: + buffering = DEFAULT_BUFFER_SIZE + try: + bs = os.fstat(raw.fileno()).st_blksize + except (OSError, AttributeError): + pass + else: + if bs > 1: + buffering = bs + if buffering < 0: + raise ValueError("invalid buffering size") + if buffering == 0: + if binary: + return result + raise ValueError("can't have unbuffered text I/O") + if updating: + buffer = BufferedRandom(raw, buffering) + elif creating or writing or appending: + buffer = BufferedWriter(raw, buffering) + elif reading: + buffer = BufferedReader(raw, buffering) else: - if bs > 1: - buffering = bs - if buffering < 0: - raise ValueError("invalid buffering size") - if buffering == 0: + raise ValueError("unknown mode: %r" % mode) + result = buffer if binary: - return raw - raise ValueError("can't have unbuffered text I/O") - if updating: - buffer = BufferedRandom(raw, buffering) - elif creating or writing or appending: - buffer = BufferedWriter(raw, buffering) - elif reading: - buffer = BufferedReader(raw, buffering) - else: - raise ValueError("unknown mode: %r" % mode) - if binary: - return buffer - text = TextIOWrapper(buffer, encoding, errors, newline, line_buffering) - text.mode = mode - return text + return result + text = TextIOWrapper(buffer, encoding, errors, newline, line_buffering) + result = text + text.mode = mode + return result + except: + result.close() + raise class DocDescriptor: @@ -249,7 +257,7 @@ class OpenWrapper: Trick so that open won't become a bound method when stored as a class variable (as dbm.dumb does). - See initstdio() in Python/pythonrun.c. + See initstdio() in Python/pylifecycle.c. """ __doc__ = DocDescriptor() @@ -655,16 +663,33 @@ def readinto(self, b): Raises BlockingIOError if the underlying raw stream has no data at the moment. """ - # XXX This ought to work with anything that supports the buffer API - data = self.read(len(b)) + + return self._readinto(b, read1=False) + + def readinto1(self, b): + """Read up to len(b) bytes into *b*, using at most one system call + + Returns an int representing the number of bytes read (0 for EOF). + + Raises BlockingIOError if the underlying raw stream has no + data at the moment. + """ + + return self._readinto(b, read1=True) + + def _readinto(self, b, read1): + if not isinstance(b, memoryview): + b = memoryview(b) + b = b.cast('B') + + if read1: + data = self.read1(len(b)) + else: + data = self.read(len(b)) n = len(data) - try: - b[:n] = data - except TypeError as err: - import array - if not isinstance(b, array.array): - raise err - b[:n] = array.array('b', data) + + b[:n] = data + return n def write(self, b): @@ -783,13 +808,14 @@ def __getstate__(self): .format(self.__class__.__name__)) def __repr__(self): - clsname = self.__class__.__name__ + modname = self.__class__.__module__ + clsname = self.__class__.__qualname__ try: name = self.name - except AttributeError: - return "<_pyio.{0}>".format(clsname) + except Exception: + return "<{}.{}>".format(modname, clsname) else: - return "<_pyio.{0} name={1!r}>".format(clsname, name) + return "<{}.{} name={!r}>".format(modname, clsname, name) ### Lower-level APIs ### @@ -826,8 +852,14 @@ def getvalue(self): def getbuffer(self): """Return a readable and writable view of the buffer. """ + if self.closed: + raise ValueError("getbuffer on closed file") return memoryview(self._buffer) + def close(self): + self._buffer.clear() + super().close() + def read(self, size=None): if self.closed: raise ValueError("read from closed file") @@ -980,10 +1012,7 @@ def _read_unlocked(self, n=None): current_size = 0 while True: # Read until EOF or until read() would block. - try: - chunk = self.raw.read() - except InterruptedError: - continue + chunk = self.raw.read() if chunk in empty_values: nodata_val = chunk break @@ -1002,10 +1031,7 @@ def _read_unlocked(self, n=None): chunks = [buf[pos:]] wanted = max(self.buffer_size, n) while avail < n: - try: - chunk = self.raw.read(wanted) - except InterruptedError: - continue + chunk = self.raw.read(wanted) if chunk in empty_values: nodata_val = chunk break @@ -1034,12 +1060,7 @@ def _peek_unlocked(self, n=0): have = len(self._read_buf) - self._read_pos if have < want or have <= 0: to_read = self.buffer_size - have - while True: - try: - current = self.raw.read(to_read) - except InterruptedError: - continue - break + current = self.raw.read(to_read) if current: self._read_buf = self._read_buf[self._read_pos:] + current self._read_pos = 0 @@ -1058,6 +1079,58 @@ def read1(self, size): return self._read_unlocked( min(size, len(self._read_buf) - self._read_pos)) + # Implementing readinto() and readinto1() is not strictly necessary (we + # could rely on the base class that provides an implementation in terms of + # read() and read1()). We do it anyway to keep the _pyio implementation + # similar to the io implementation (which implements the methods for + # performance reasons). + def _readinto(self, buf, read1): + """Read data into *buf* with at most one system call.""" + + if len(buf) == 0: + return 0 + + # Need to create a memoryview object of type 'b', otherwise + # we may not be able to assign bytes to it, and slicing it + # would create a new object. + if not isinstance(buf, memoryview): + buf = memoryview(buf) + buf = buf.cast('B') + + written = 0 + with self._read_lock: + while written < len(buf): + + # First try to read from internal buffer + avail = min(len(self._read_buf) - self._read_pos, len(buf)) + if avail: + buf[written:written+avail] = \ + self._read_buf[self._read_pos:self._read_pos+avail] + self._read_pos += avail + written += avail + if written == len(buf): + break + + # If remaining space in callers buffer is larger than + # internal buffer, read directly into callers buffer + if len(buf) - written > self.buffer_size: + n = self.raw.readinto(buf[written:]) + if not n: + break # eof + written += n + + # Otherwise refill internal buffer - unless we're + # in read1 mode and already got some data + elif not (read1 and written): + if not self._peek_unlocked(1): + break # eof + + # In readinto1 mode, return as soon as we have some data + if read1 and written: + break + + return written + def tell(self): return _BufferedIOMixin.tell(self) - len(self._read_buf) + self._read_pos @@ -1136,8 +1209,6 @@ def _flush_unlocked(self): while self._write_buf: try: n = self.raw.write(self._write_buf) - except InterruptedError: - continue except BlockingIOError: raise RuntimeError("self.raw should implement RawIOBase: it " "should not raise BlockingIOError") @@ -1207,6 +1278,9 @@ def peek(self, size=0): def read1(self, size): return self.reader.read1(size) + def readinto1(self, b): + return self.reader.readinto1(b) + def readable(self): return self.reader.readable() @@ -1289,6 +1363,10 @@ def read1(self, size): self.flush() return BufferedReader.read1(self, size) + def readinto1(self, b): + self.flush() + return BufferedReader.readinto1(self, b) + def write(self, b): if self._read_buf: # Undo readahead @@ -1503,6 +1581,11 @@ def __init__(self, buffer, encoding=None, errors=None, newline=None, if not isinstance(encoding, str): raise ValueError("invalid encoding: %r" % encoding) + if not codecs.lookup(encoding)._is_text_encoding: + msg = ("%r is not a text encoding; " + "use codecs.open() to handle arbitrary codecs") + raise LookupError(msg % encoding) + if errors is None: errors = "strict" else: @@ -1546,16 +1629,17 @@ def __init__(self, buffer, encoding=None, errors=None, newline=None, # - "chars_..." for integer variables that count decoded characters def __repr__(self): - result = "<_pyio.TextIOWrapper" + result = "<{}.{}".format(self.__class__.__module__, + self.__class__.__qualname__) try: name = self.name - except AttributeError: + except Exception: pass else: result += " name={0!r}".format(name) try: mode = self.mode - except AttributeError: + except Exception: pass else: result += " mode={0!r}".format(mode) @@ -2052,7 +2136,7 @@ class StringIO(TextIOWrapper): def __init__(self, initial_value="", newline="\n"): super(StringIO, self).__init__(BytesIO(), encoding="utf-8", - errors="strict", + errors="surrogatepass", newline=newline) # Issue #5645: make universal newlines semantics the same as in the # C version, even under Windows. @@ -2067,7 +2151,13 @@ def __init__(self, initial_value="", newline="\n"): def getvalue(self): self.flush() - return self.buffer.getvalue().decode(self._encoding, self._errors) + decoder = self._decoder or self._get_decoder() + old_state = decoder.getstate() + decoder.reset() + try: + return decoder.decode(self.buffer.getvalue(), final=True) + finally: + decoder.setstate(old_state) def __repr__(self): # TextIOWrapper tells the encoding in its repr. In StringIO, diff --git a/Lib/_sitebuiltins.py b/Lib/_sitebuiltins.py index 1f21358e2685..c29cf4bf8fe4 100644 --- a/Lib/_sitebuiltins.py +++ b/Lib/_sitebuiltins.py @@ -87,8 +87,12 @@ def __call__(self): class _Helper(object): """Define the builtin 'help'. - This is a wrapper around pydoc.help (with a twist). + This is a wrapper around pydoc.help that provides a helpful message + when 'help' is typed at the Python interactive prompt. + + Calling help() at the Python prompt starts an interactive help session. + Calling help(thing) prints help for the python object 'thing'. """ def __repr__(self): diff --git a/Lib/_strptime.py b/Lib/_strptime.py index d101c6de05db..42f23d3d54b9 100644 --- a/Lib/_strptime.py +++ b/Lib/_strptime.py @@ -14,7 +14,7 @@ import locale import calendar from re import compile as re_compile -from re import IGNORECASE, ASCII +from re import IGNORECASE from re import escape as re_escape from datetime import (date as datetime_date, timedelta as datetime_timedelta, @@ -167,9 +167,9 @@ def __calc_timezone(self): time.tzset() except AttributeError: pass - no_saving = frozenset(["utc", "gmt", time.tzname[0].lower()]) + no_saving = frozenset({"utc", "gmt", time.tzname[0].lower()}) if time.daylight: - has_saving = frozenset([time.tzname[1].lower()]) + has_saving = frozenset({time.tzname[1].lower()}) else: has_saving = frozenset() self.timezone = (no_saving, has_saving) diff --git a/Lib/_weakrefset.py b/Lib/_weakrefset.py index 6a98b88e3355..7f9923c6341a 100644 --- a/Lib/_weakrefset.py +++ b/Lib/_weakrefset.py @@ -60,6 +60,8 @@ def __iter__(self): for itemref in self.data: item = itemref() if item is not None: + # Caveat: the iterator will keep a strong reference to + # `item` until it is resumed or closed. yield item def __len__(self): diff --git a/Lib/abc.py b/Lib/abc.py index 264c60c428b4..1cbf96a61f23 100644 --- a/Lib/abc.py +++ b/Lib/abc.py @@ -168,7 +168,7 @@ def register(cls, subclass): def _dump_registry(cls, file=None): """Debug helper to print the ABC registry.""" - print("Class: %s.%s" % (cls.__module__, cls.__name__), file=file) + print("Class: %s.%s" % (cls.__module__, cls.__qualname__), file=file) print("Inv.counter: %s" % ABCMeta._abc_invalidation_counter, file=file) for name in sorted(cls.__dict__.keys()): if name.startswith("_abc_"): @@ -241,8 +241,8 @@ class ABC(metaclass=ABCMeta): def get_cache_token(): """Returns the current ABC cache token. - The token is an opaque integer identifying the current version of - the ABC cache for virtual subclasses. This number changes with - every call to ``register()`` on any ABC. + The token is an opaque object (supporting equality testing) identifying the + current version of the ABC cache for virtual subclasses. The token changes + with every call to ``register()`` on any ABC. """ return ABCMeta._abc_invalidation_counter diff --git a/Lib/aifc.py b/Lib/aifc.py index c1c8ea705570..9e64de9c441f 100644 --- a/Lib/aifc.py +++ b/Lib/aifc.py @@ -790,7 +790,10 @@ def _write_header(self, initlength): self._datalength = (self._datalength + 3) // 4 if self._datalength & 1: self._datalength = self._datalength + 1 - self._form_length_pos = self._file.tell() + try: + self._form_length_pos = self._file.tell() + except (AttributeError, OSError): + self._form_length_pos = None commlength = self._write_form_length(self._datalength) if self._aifc: self._file.write(b'AIFC') @@ -802,7 +805,8 @@ def _write_header(self, initlength): self._file.write(b'COMM') _write_ulong(self._file, commlength) _write_short(self._file, self._nchannels) - self._nframes_pos = self._file.tell() + if self._form_length_pos is not None: + self._nframes_pos = self._file.tell() _write_ulong(self._file, self._nframes) if self._comptype in (b'ULAW', b'ulaw', b'ALAW', b'alaw', b'G722'): _write_short(self._file, 8) @@ -813,7 +817,8 @@ def _write_header(self, initlength): self._file.write(self._comptype) _write_string(self._file, self._compname) self._file.write(b'SSND') - self._ssnd_length_pos = self._file.tell() + if self._form_length_pos is not None: + self._ssnd_length_pos = self._file.tell() _write_ulong(self._file, self._datalength + 8) _write_ulong(self._file, 0) _write_ulong(self._file, 0) diff --git a/Lib/argparse.py b/Lib/argparse.py index 9520e0ea7c67..9a067196dac3 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -165,6 +165,8 @@ def __init__(self, self._prog = prog self._indent_increment = indent_increment self._max_help_position = max_help_position + self._max_help_position = min(max_help_position, + max(width - 20, indent_increment * 2)) self._width = width self._current_indent = 0 @@ -336,7 +338,7 @@ def get_lines(parts, indent, prefix=None): else: line_len = len(indent) - 1 for part in parts: - if line_len + 1 + len(part) > text_width: + if line_len + 1 + len(part) > text_width and line: lines.append(indent + ' '.join(line)) line = [] line_len = len(indent) - 1 @@ -476,7 +478,7 @@ def _format_actions_usage(self, actions, groups): def _format_text(self, text): if '%(prog)' in text: text = text % dict(prog=self._prog) - text_width = self._width - self._current_indent + text_width = max(self._width - self._current_indent, 11) indent = ' ' * self._current_indent return self._fill_text(text, text_width, indent) + '\n\n' @@ -484,11 +486,11 @@ def _format_action(self, action): # determine the required width and the entry label help_position = min(self._action_max_length + 2, self._max_help_position) - help_width = self._width - help_position + help_width = max(self._width - help_position, 11) action_width = help_position - self._current_indent - 2 action_header = self._format_action_invocation(action) - # ho nelp; start on same line and add a final newline + # no help; start on same line and add a final newline if not action.help: tup = self._current_indent, '', action_header action_header = '%*s%s\n' % tup @@ -1120,7 +1122,14 @@ def __call__(self, parser, namespace, values, option_string=None): # parse all the remaining options into the namespace # store any unrecognized options on the object, so that the top # level parser can decide what to do with them - namespace, arg_strings = parser.parse_known_args(arg_strings, namespace) + + # In case this subparser defines new defaults, we parse them + # in a new namespace object and then update the original + # namespace for the relevant parts. + subnamespace, arg_strings = parser.parse_known_args(arg_strings, None) + for key, value in vars(subnamespace).items(): + setattr(namespace, key, value) + if arg_strings: vars(namespace).setdefault(_UNRECOGNIZED_ARGS_ATTR, []) getattr(namespace, _UNRECOGNIZED_ARGS_ATTR).extend(arg_strings) @@ -1196,11 +1205,10 @@ def __init__(self, **kwargs): setattr(self, name, kwargs[name]) def __eq__(self, other): + if not isinstance(other, Namespace): + return NotImplemented return vars(self) == vars(other) - def __ne__(self, other): - return not (self == other) - def __contains__(self, key): return key in self.__dict__ @@ -1582,6 +1590,7 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): - argument_default -- The default value for all arguments - conflict_handler -- String indicating how to handle conflicts - add_help -- Add a -h/-help option + - allow_abbrev -- Allow long options to be abbreviated unambiguously """ def __init__(self, @@ -1595,7 +1604,8 @@ def __init__(self, fromfile_prefix_chars=None, argument_default=None, conflict_handler='error', - add_help=True): + add_help=True, + allow_abbrev=True): superinit = super(ArgumentParser, self).__init__ superinit(description=description, @@ -1613,6 +1623,7 @@ def __init__(self, self.formatter_class = formatter_class self.fromfile_prefix_chars = fromfile_prefix_chars self.add_help = add_help + self.allow_abbrev = allow_abbrev add_group = self.add_argument_group self._positionals = add_group(_('positional arguments')) @@ -2090,23 +2101,24 @@ def _parse_optional(self, arg_string): action = self._option_string_actions[option_string] return action, option_string, explicit_arg - # search through all possible prefixes of the option string - # and all actions in the parser for possible interpretations - option_tuples = self._get_option_tuples(arg_string) - - # if multiple actions match, the option string was ambiguous - if len(option_tuples) > 1: - options = ', '.join([option_string - for action, option_string, explicit_arg in option_tuples]) - args = {'option': arg_string, 'matches': options} - msg = _('ambiguous option: %(option)s could match %(matches)s') - self.error(msg % args) - - # if exactly one action matched, this segmentation is good, - # so return the parsed action - elif len(option_tuples) == 1: - option_tuple, = option_tuples - return option_tuple + if self.allow_abbrev: + # search through all possible prefixes of the option string + # and all actions in the parser for possible interpretations + option_tuples = self._get_option_tuples(arg_string) + + # if multiple actions match, the option string was ambiguous + if len(option_tuples) > 1: + options = ', '.join([option_string + for action, option_string, explicit_arg in option_tuples]) + args = {'option': arg_string, 'matches': options} + msg = _('ambiguous option: %(option)s could match %(matches)s') + self.error(msg % args) + + # if exactly one action matched, this segmentation is good, + # so return the parsed action + elif len(option_tuples) == 1: + option_tuple, = option_tuples + return option_tuple # if it was not found as an option, but it looks like a negative # number, it was meant to be positional diff --git a/Lib/asynchat.py b/Lib/asynchat.py index 0378fa70697a..f728d1b47053 100644 --- a/Lib/asynchat.py +++ b/Lib/asynchat.py @@ -45,27 +45,26 @@ method) up to the terminator, and then control will be returned to you - by calling your self.found_terminator() method. """ -import socket import asyncore from collections import deque -class async_chat (asyncore.dispatcher): +class async_chat(asyncore.dispatcher): """This is an abstract class. You must derive from this class, and add the two methods collect_incoming_data() and found_terminator()""" # these are overridable defaults - ac_in_buffer_size = 65536 - ac_out_buffer_size = 65536 + ac_in_buffer_size = 65536 + ac_out_buffer_size = 65536 # we don't want to enable the use of encoding by default, because that is a # sign of an application bug that we don't want to pass silently - use_encoding = 0 - encoding = 'latin-1' + use_encoding = 0 + encoding = 'latin-1' - def __init__ (self, sock=None, map=None): + def __init__(self, sock=None, map=None): # for string terminator matching self.ac_in_buffer = b'' @@ -77,7 +76,7 @@ def __init__ (self, sock=None, map=None): # we toss the use of the "simple producer" and replace it with # a pure deque, which the original fifo was a wrapping of self.producer_fifo = deque() - asyncore.dispatcher.__init__ (self, sock, map) + asyncore.dispatcher.__init__(self, sock, map) def collect_incoming_data(self, data): raise NotImplementedError("must be implemented in subclass") @@ -93,13 +92,18 @@ def _get_data(self): def found_terminator(self): raise NotImplementedError("must be implemented in subclass") - def set_terminator (self, term): - "Set the input delimiter. Can be a fixed string of any length, an integer, or None" + def set_terminator(self, term): + """Set the input delimiter. + + Can be a fixed string of any length, an integer, or None. + """ if isinstance(term, str) and self.use_encoding: term = bytes(term, self.encoding) + elif isinstance(term, int) and term < 0: + raise ValueError('the number of received bytes must be positive') self.terminator = term - def get_terminator (self): + def get_terminator(self): return self.terminator # grab some more data from the socket, @@ -107,10 +111,12 @@ def get_terminator (self): # check for the terminator, # if found, transition to the next state. - def handle_read (self): + def handle_read(self): try: - data = self.recv (self.ac_in_buffer_size) + data = self.recv(self.ac_in_buffer_size) + except BlockingIOError: + return except OSError as why: self.handle_error() return @@ -129,17 +135,17 @@ def handle_read (self): terminator = self.get_terminator() if not terminator: # no terminator, collect it all - self.collect_incoming_data (self.ac_in_buffer) + self.collect_incoming_data(self.ac_in_buffer) self.ac_in_buffer = b'' elif isinstance(terminator, int): # numeric terminator n = terminator if lb < n: - self.collect_incoming_data (self.ac_in_buffer) + self.collect_incoming_data(self.ac_in_buffer) self.ac_in_buffer = b'' self.terminator = self.terminator - lb else: - self.collect_incoming_data (self.ac_in_buffer[:n]) + self.collect_incoming_data(self.ac_in_buffer[:n]) self.ac_in_buffer = self.ac_in_buffer[n:] self.terminator = 0 self.found_terminator() @@ -156,32 +162,37 @@ def handle_read (self): if index != -1: # we found the terminator if index > 0: - # don't bother reporting the empty string (source of subtle bugs) - self.collect_incoming_data (self.ac_in_buffer[:index]) + # don't bother reporting the empty string + # (source of subtle bugs) + self.collect_incoming_data(self.ac_in_buffer[:index]) self.ac_in_buffer = self.ac_in_buffer[index+terminator_len:] - # This does the Right Thing if the terminator is changed here. + # This does the Right Thing if the terminator + # is changed here. self.found_terminator() else: # check for a prefix of the terminator - index = find_prefix_at_end (self.ac_in_buffer, terminator) + index = find_prefix_at_end(self.ac_in_buffer, terminator) if index: if index != lb: # we found a prefix, collect up to the prefix - self.collect_incoming_data (self.ac_in_buffer[:-index]) + self.collect_incoming_data(self.ac_in_buffer[:-index]) self.ac_in_buffer = self.ac_in_buffer[-index:] break else: # no prefix, collect it all - self.collect_incoming_data (self.ac_in_buffer) + self.collect_incoming_data(self.ac_in_buffer) self.ac_in_buffer = b'' - def handle_write (self): + def handle_write(self): self.initiate_send() - def handle_close (self): + def handle_close(self): self.close() - def push (self, data): + def push(self, data): + if not isinstance(data, (bytes, bytearray, memoryview)): + raise TypeError('data argument must be byte-ish (%r)', + type(data)) sabs = self.ac_out_buffer_size if len(data) > sabs: for i in range(0, len(data), sabs): @@ -190,11 +201,11 @@ def push (self, data): self.producer_fifo.append(data) self.initiate_send() - def push_with_producer (self, producer): + def push_with_producer(self, producer): self.producer_fifo.append(producer) self.initiate_send() - def readable (self): + def readable(self): "predicate for inclusion in the readable for select()" # cannot use the old predicate, it violates the claim of the # set_terminator method. @@ -202,11 +213,11 @@ def readable (self): # return (len(self.ac_in_buffer) <= self.ac_in_buffer_size) return 1 - def writable (self): + def writable(self): "predicate for inclusion in the writable for select()" return self.producer_fifo or (not self.connected) - def close_when_done (self): + def close_when_done(self): "automatically close this channel once the outgoing queue is empty" self.producer_fifo.append(None) @@ -217,10 +228,8 @@ def initiate_send(self): if not first: del self.producer_fifo[0] if first is None: - ## print("first is None") self.handle_close() return - ## print("first is not None") # handle classic producer behavior obs = self.ac_out_buffer_size @@ -252,20 +261,21 @@ def initiate_send(self): # we tried to send some actual data return - def discard_buffers (self): + def discard_buffers(self): # Emergencies only! self.ac_in_buffer = b'' del self.incoming[:] self.producer_fifo.clear() + class simple_producer: - def __init__ (self, data, buffer_size=512): + def __init__(self, data, buffer_size=512): self.data = data self.buffer_size = buffer_size - def more (self): - if len (self.data) > self.buffer_size: + def more(self): + if len(self.data) > self.buffer_size: result = self.data[:self.buffer_size] self.data = self.data[self.buffer_size:] return result @@ -274,38 +284,43 @@ def more (self): self.data = b'' return result + class fifo: - def __init__ (self, list=None): + def __init__(self, list=None): + import warnings + warnings.warn('fifo class will be removed in Python 3.6', + DeprecationWarning, stacklevel=2) if not list: self.list = deque() else: self.list = deque(list) - def __len__ (self): + def __len__(self): return len(self.list) - def is_empty (self): + def is_empty(self): return not self.list - def first (self): + def first(self): return self.list[0] - def push (self, data): + def push(self, data): self.list.append(data) - def pop (self): + def pop(self): if self.list: return (1, self.list.popleft()) else: return (0, None) + # Given 'haystack', see if any prefix of 'needle' is at its end. This # assumes an exact match has already been checked. Return the number of # characters matched. # for example: -# f_p_a_e ("qwerty\r", "\r\n") => 1 -# f_p_a_e ("qwertydkjf", "\r\n") => 0 -# f_p_a_e ("qwerty\r\n", "\r\n") => <undefined> +# f_p_a_e("qwerty\r", "\r\n") => 1 +# f_p_a_e("qwertydkjf", "\r\n") => 0 +# f_p_a_e("qwerty\r\n", "\r\n") => <undefined> # this could maybe be made faster with a computed regex? # [answer: no; circa Python-2.0, Jan 2001] @@ -314,7 +329,7 @@ def pop (self): # re: 12820/s # regex: 14035/s -def find_prefix_at_end (haystack, needle): +def find_prefix_at_end(haystack, needle): l = len(needle) - 1 while l and not haystack.endswith(needle[:l]): l -= 1 diff --git a/Lib/asyncio/__init__.py b/Lib/asyncio/__init__.py index 0d288d5a0202..011466b3e0dc 100644 --- a/Lib/asyncio/__init__.py +++ b/Lib/asyncio/__init__.py @@ -18,24 +18,33 @@ import _overlapped # Will also be exported. # This relies on each of the submodules having an __all__ variable. -from .futures import * +from .base_events import * +from .coroutines import * from .events import * +from .futures import * from .locks import * -from .transports import * from .protocols import * +from .queues import * from .streams import * +from .subprocess import * from .tasks import * +from .transports import * -if sys.platform == 'win32': # pragma: no cover - from .windows_events import * -else: - from .unix_events import * # pragma: no cover - - -__all__ = (futures.__all__ + +__all__ = (base_events.__all__ + + coroutines.__all__ + events.__all__ + + futures.__all__ + locks.__all__ + - transports.__all__ + protocols.__all__ + + queues.__all__ + streams.__all__ + - tasks.__all__) + subprocess.__all__ + + tasks.__all__ + + transports.__all__) + +if sys.platform == 'win32': # pragma: no cover + from .windows_events import * + __all__ += windows_events.__all__ +else: + from .unix_events import * # pragma: no cover + __all__ += unix_events.__all__ diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index f2d117bdbd2a..eb867cd5061c 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -1,7 +1,7 @@ """Base implementation of event loop. The event loop can be broken up into a multiplexer (the part -responsible for notifying us of IO events) and the event loop proper, +responsible for notifying us of I/O events) and the event loop proper, which wraps a multiplexer with functionality for scheduling callbacks, immediately or at a given time in the future. @@ -17,99 +17,216 @@ import collections import concurrent.futures import heapq +import inspect import logging +import os import socket import subprocess +import threading import time -import os +import traceback import sys +import warnings +from . import coroutines from . import events from . import futures from . import tasks +from .coroutines import coroutine from .log import logger -__all__ = ['BaseEventLoop', 'Server'] +__all__ = ['BaseEventLoop'] # Argument for default thread pool executor creation. _MAX_WORKERS = 5 +# Minimum number of _scheduled timer handles before cleanup of +# cancelled handles is performed. +_MIN_SCHEDULED_TIMER_HANDLES = 100 + +# Minimum fraction of _scheduled timer handles that are cancelled +# before cleanup of cancelled handles is performed. +_MIN_CANCELLED_TIMER_HANDLES_FRACTION = 0.5 + +def _format_handle(handle): + cb = handle._callback + if inspect.ismethod(cb) and isinstance(cb.__self__, tasks.Task): + # format the task + return repr(cb.__self__) + else: + return str(handle) + + +def _format_pipe(fd): + if fd == subprocess.PIPE: + return '<pipe>' + elif fd == subprocess.STDOUT: + return '<stdout>' + else: + return repr(fd) + class _StopError(BaseException): """Raised to stop the event loop.""" +def _check_resolved_address(sock, address): + # Ensure that the address is already resolved to avoid the trap of hanging + # the entire event loop when the address requires doing a DNS lookup. + # + # getaddrinfo() is slow (around 10 us per call): this function should only + # be called in debug mode + family = sock.family + + if family == socket.AF_INET: + host, port = address + elif family == socket.AF_INET6: + host, port = address[:2] + else: + return + + # On Windows, socket.inet_pton() is only available since Python 3.4 + if hasattr(socket, 'inet_pton'): + # getaddrinfo() is slow and has known issue: prefer inet_pton() + # if available + try: + socket.inet_pton(family, host) + except OSError as exc: + raise ValueError("address must be resolved (IP address), " + "got host %r: %s" + % (host, exc)) + else: + # Use getaddrinfo(flags=AI_NUMERICHOST) to ensure that the address is + # already resolved. + type_mask = 0 + if hasattr(socket, 'SOCK_NONBLOCK'): + type_mask |= socket.SOCK_NONBLOCK + if hasattr(socket, 'SOCK_CLOEXEC'): + type_mask |= socket.SOCK_CLOEXEC + try: + socket.getaddrinfo(host, port, + family=family, + type=(sock.type & ~type_mask), + proto=sock.proto, + flags=socket.AI_NUMERICHOST) + except socket.gaierror as err: + raise ValueError("address must be resolved (IP address), " + "got host %r: %s" + % (host, err)) + def _raise_stop_error(*args): raise _StopError +def _run_until_complete_cb(fut): + exc = fut._exception + if (isinstance(exc, BaseException) + and not isinstance(exc, Exception)): + # Issue #22429: run_forever() already finished, no need to + # stop it. + return + _raise_stop_error() + + class Server(events.AbstractServer): def __init__(self, loop, sockets): - self.loop = loop + self._loop = loop self.sockets = sockets - self.active_count = 0 - self.waiters = [] + self._active_count = 0 + self._waiters = [] - def attach(self, transport): + def __repr__(self): + return '<%s sockets=%r>' % (self.__class__.__name__, self.sockets) + + def _attach(self): assert self.sockets is not None - self.active_count += 1 + self._active_count += 1 - def detach(self, transport): - assert self.active_count > 0 - self.active_count -= 1 - if self.active_count == 0 and self.sockets is None: + def _detach(self): + assert self._active_count > 0 + self._active_count -= 1 + if self._active_count == 0 and self.sockets is None: self._wakeup() def close(self): sockets = self.sockets - if sockets is not None: - self.sockets = None - for sock in sockets: - self.loop._stop_serving(sock) - if self.active_count == 0: - self._wakeup() + if sockets is None: + return + self.sockets = None + for sock in sockets: + self._loop._stop_serving(sock) + if self._active_count == 0: + self._wakeup() def _wakeup(self): - waiters = self.waiters - self.waiters = None + waiters = self._waiters + self._waiters = None for waiter in waiters: if not waiter.done(): waiter.set_result(waiter) - @tasks.coroutine + @coroutine def wait_closed(self): - if self.sockets is None or self.waiters is None: + if self.sockets is None or self._waiters is None: return - waiter = futures.Future(loop=self.loop) - self.waiters.append(waiter) + waiter = futures.Future(loop=self._loop) + self._waiters.append(waiter) yield from waiter class BaseEventLoop(events.AbstractEventLoop): def __init__(self): + self._timer_cancelled_count = 0 + self._closed = False self._ready = collections.deque() self._scheduled = [] self._default_executor = None self._internal_fds = 0 - self._running = False + # Identifier of the thread running the event loop, or None if the + # event loop is not running + self._thread_id = None + self._clock_resolution = time.get_clock_info('monotonic').resolution + self._exception_handler = None + self._debug = (not sys.flags.ignore_environment + and bool(os.environ.get('PYTHONASYNCIODEBUG'))) + # In debug mode, if the execution of a callback or a step of a task + # exceed this duration in seconds, the slow callback/task is logged. + self.slow_callback_duration = 0.1 + self._current_handle = None + + def __repr__(self): + return ('<%s running=%s closed=%s debug=%s>' + % (self.__class__.__name__, self.is_running(), + self.is_closed(), self.get_debug())) + + def create_task(self, coro): + """Schedule a coroutine object. + + Return a task object. + """ + self._check_closed() + task = tasks.Task(coro, loop=self) + if task._source_traceback: + del task._source_traceback[-1] + return task def _make_socket_transport(self, sock, protocol, waiter=None, *, extra=None, server=None): """Create socket transport.""" raise NotImplementedError - def _make_ssl_transport(self, rawsock, protocol, sslcontext, waiter, *, - server_side=False, server_hostname=None, + def _make_ssl_transport(self, rawsock, protocol, sslcontext, waiter=None, + *, server_side=False, server_hostname=None, extra=None, server=None): """Create SSL transport.""" raise NotImplementedError def _make_datagram_transport(self, sock, protocol, - address=None, extra=None): + address=None, waiter=None, extra=None): """Create datagram transport.""" raise NotImplementedError @@ -123,30 +240,36 @@ def _make_write_pipe_transport(self, pipe, protocol, waiter=None, """Create write pipe transport.""" raise NotImplementedError - @tasks.coroutine + @coroutine def _make_subprocess_transport(self, protocol, args, shell, stdin, stdout, stderr, bufsize, extra=None, **kwargs): """Create subprocess transport.""" raise NotImplementedError - def _read_from_self(self): - """XXX""" - raise NotImplementedError - def _write_to_self(self): - """XXX""" + """Write a byte to self-pipe, to wake up the event loop. + + This may be called from a different thread. + + The subclass is responsible for implementing the self-pipe. + """ raise NotImplementedError def _process_events(self, event_list): """Process selector events.""" raise NotImplementedError + def _check_closed(self): + if self._closed: + raise RuntimeError('Event loop is closed') + def run_forever(self): """Run until stop() is called.""" - if self._running: + self._check_closed() + if self.is_running(): raise RuntimeError('Event loop is running.') - self._running = True + self._thread_id = threading.get_ident() try: while True: try: @@ -154,23 +277,39 @@ def run_forever(self): except _StopError: break finally: - self._running = False + self._thread_id = None def run_until_complete(self, future): """Run until the Future is done. If the argument is a coroutine, it is wrapped in a Task. - XXX TBD: It would be disastrous to call run_until_complete() + WARNING: It would be disastrous to call run_until_complete() with the same coroutine twice -- it would wrap it in two different Tasks and that can't be good. Return the Future's result, or raise its exception. """ + self._check_closed() + + new_task = not isinstance(future, futures.Future) future = tasks.async(future, loop=self) - future.add_done_callback(_raise_stop_error) - self.run_forever() - future.remove_done_callback(_raise_stop_error) + if new_task: + # An exception is raised if the future didn't complete, so there + # is no need to log the "destroy pending task" message + future._log_destroy_pending = False + + future.add_done_callback(_run_until_complete_cb) + try: + self.run_forever() + except: + if new_task and future.done() and not future.cancelled(): + # The coroutine raised a BaseException. Consume the exception + # to not log a warning, the caller doesn't have access to the + # local task. + future.exception() + raise + future.remove_done_callback(_run_until_complete_cb) if not future.done(): raise RuntimeError('Event loop stopped before Future completed.') @@ -179,9 +318,9 @@ def run_until_complete(self, future): def stop(self): """Stop running the event loop. - Every callback scheduled before stop() is called will run. - Callback scheduled after stop() is called won't. However, - those callbacks will run if run() is called again later. + Every callback scheduled before stop() is called will run. Callbacks + scheduled after stop() is called will not run. However, those callbacks + will run if run_forever is called again later. """ self.call_soon(_raise_stop_error) @@ -190,7 +329,16 @@ def close(self): This clears the queues and shuts down the executor, but does not wait for the executor to finish. + + The event loop must not be running. """ + if self.is_running(): + raise RuntimeError("Cannot close a running event loop") + if self._closed: + return + if self._debug: + logger.debug("Close %r", self) + self._closed = True self._ready.clear() self._scheduled.clear() executor = self._default_executor @@ -198,12 +346,31 @@ def close(self): self._default_executor = None executor.shutdown(wait=False) + def is_closed(self): + """Returns True if the event loop was closed.""" + return self._closed + + # On Python 3.3 and older, objects with a destructor part of a reference + # cycle are never destroyed. It's not more the case on Python 3.4 thanks + # to the PEP 442. + if sys.version_info >= (3, 4): + def __del__(self): + if not self.is_closed(): + warnings.warn("unclosed event loop %r" % self, ResourceWarning) + if not self.is_running(): + self.close() + def is_running(self): - """Returns running status of event loop.""" - return self._running + """Returns True if the event loop is running.""" + return (self._thread_id is not None) def time(self): - """Return the time according to the event loop's clock.""" + """Return the time according to the event loop's clock. + + This is a float expressed in seconds since an epoch, but the + epoch, precision, accuracy and drift are unspecified and may + differ per event loop. + """ return time.monotonic() def call_later(self, delay, callback, *args): @@ -213,7 +380,7 @@ def call_later(self, delay, callback, *args): can be used to cancel the call. The delay can be an int or float, expressed in seconds. It is - always a relative time. + always relative to the current time. Each callback will be called exactly once. If two callbacks are scheduled for exactly the same time, it undefined which @@ -222,35 +389,87 @@ def call_later(self, delay, callback, *args): Any positional arguments after the callback will be passed to the callback when it is called. """ - return self.call_at(self.time() + delay, callback, *args) + timer = self.call_at(self.time() + delay, callback, *args) + if timer._source_traceback: + del timer._source_traceback[-1] + return timer def call_at(self, when, callback, *args): - """Like call_later(), but uses an absolute time.""" - timer = events.TimerHandle(when, callback, args) + """Like call_later(), but uses an absolute time. + + Absolute time corresponds to the event loop's time() method. + """ + if (coroutines.iscoroutine(callback) + or coroutines.iscoroutinefunction(callback)): + raise TypeError("coroutines cannot be used with call_at()") + self._check_closed() + if self._debug: + self._check_thread() + timer = events.TimerHandle(when, callback, args, self) + if timer._source_traceback: + del timer._source_traceback[-1] heapq.heappush(self._scheduled, timer) + timer._scheduled = True return timer def call_soon(self, callback, *args): """Arrange for a callback to be called as soon as possible. - This operates as a FIFO queue, callbacks are called in the + This operates as a FIFO queue: callbacks are called in the order in which they are registered. Each callback will be called exactly once. Any positional arguments after the callback will be passed to the callback when it is called. """ - handle = events.make_handle(callback, args) + if self._debug: + self._check_thread() + handle = self._call_soon(callback, args) + if handle._source_traceback: + del handle._source_traceback[-1] + return handle + + def _call_soon(self, callback, args): + if (coroutines.iscoroutine(callback) + or coroutines.iscoroutinefunction(callback)): + raise TypeError("coroutines cannot be used with call_soon()") + self._check_closed() + handle = events.Handle(callback, args, self) + if handle._source_traceback: + del handle._source_traceback[-1] self._ready.append(handle) return handle + def _check_thread(self): + """Check that the current thread is the thread running the event loop. + + Non-thread-safe methods of this class make this assumption and will + likely behave incorrectly when the assumption is violated. + + Should only be called when (self._debug == True). The caller is + responsible for checking this condition for performance reasons. + """ + if self._thread_id is None: + return + thread_id = threading.get_ident() + if thread_id != self._thread_id: + raise RuntimeError( + "Non-thread-safe operation invoked on an event loop other " + "than the current one") + def call_soon_threadsafe(self, callback, *args): - """XXX""" - handle = self.call_soon(callback, *args) + """Like call_soon(), but thread-safe.""" + handle = self._call_soon(callback, args) + if handle._source_traceback: + del handle._source_traceback[-1] self._write_to_self() return handle def run_in_executor(self, executor, callback, *args): + if (coroutines.iscoroutine(callback) + or coroutines.iscoroutinefunction(callback)): + raise TypeError("coroutines cannot be used with run_in_executor()") + self._check_closed() if isinstance(callback, events.Handle): assert not args assert not isinstance(callback, events.TimerHandle) @@ -269,19 +488,58 @@ def run_in_executor(self, executor, callback, *args): def set_default_executor(self, executor): self._default_executor = executor + def _getaddrinfo_debug(self, host, port, family, type, proto, flags): + msg = ["%s:%r" % (host, port)] + if family: + msg.append('family=%r' % family) + if type: + msg.append('type=%r' % type) + if proto: + msg.append('proto=%r' % proto) + if flags: + msg.append('flags=%r' % flags) + msg = ', '.join(msg) + logger.debug('Get address info %s', msg) + + t0 = self.time() + addrinfo = socket.getaddrinfo(host, port, family, type, proto, flags) + dt = self.time() - t0 + + msg = ('Getting address info %s took %.3f ms: %r' + % (msg, dt * 1e3, addrinfo)) + if dt >= self.slow_callback_duration: + logger.info(msg) + else: + logger.debug(msg) + return addrinfo + def getaddrinfo(self, host, port, *, family=0, type=0, proto=0, flags=0): - return self.run_in_executor(None, socket.getaddrinfo, - host, port, family, type, proto, flags) + if self._debug: + return self.run_in_executor(None, self._getaddrinfo_debug, + host, port, family, type, proto, flags) + else: + return self.run_in_executor(None, socket.getaddrinfo, + host, port, family, type, proto, flags) def getnameinfo(self, sockaddr, flags=0): return self.run_in_executor(None, socket.getnameinfo, sockaddr, flags) - @tasks.coroutine + @coroutine def create_connection(self, protocol_factory, host=None, port=None, *, ssl=None, family=0, proto=0, flags=0, sock=None, local_addr=None, server_hostname=None): - """XXX""" + """Connect to a TCP server. + + Create a streaming transport connection to a given Internet host and + port: socket family AF_INET or socket.AF_INET6 depending on host (or + family if specified), socket type SOCK_STREAM. protocol_factory must be + a callable returning a protocol instance. + + This method is a coroutine which will try to establish the connection + in the background. When successful, the coroutine returns a + (transport, protocol) pair. + """ if server_hostname is not None and not ssl: raise ValueError('server_hostname is only meaningful with ssl') @@ -349,11 +607,17 @@ def create_connection(self, protocol_factory, host=None, port=None, *, sock.close() sock = None continue + if self._debug: + logger.debug("connect %r to %r", sock, address) yield from self.sock_connect(sock, address) except OSError as exc: if sock is not None: sock.close() exceptions.append(exc) + except: + if sock is not None: + sock.close() + raise else: break else: @@ -375,6 +639,19 @@ def create_connection(self, protocol_factory, host=None, port=None, *, sock.setblocking(False) + transport, protocol = yield from self._create_connection_transport( + sock, protocol_factory, ssl, server_hostname) + if self._debug: + # Get the socket from the transport because SSL transport closes + # the old socket and creates a new SSL socket + sock = transport.get_extra_info('socket') + logger.debug("%r connected to %s:%r: (%r, %r)", + sock, host, port, transport, protocol) + return transport, protocol + + @coroutine + def _create_connection_transport(self, sock, protocol_factory, ssl, + server_hostname): protocol = protocol_factory() waiter = futures.Future(loop=self) if ssl: @@ -385,10 +662,15 @@ def create_connection(self, protocol_factory, host=None, port=None, *, else: transport = self._make_socket_transport(sock, protocol, waiter) - yield from waiter + try: + yield from waiter + except: + transport.close() + raise + return transport, protocol - @tasks.coroutine + @coroutine def create_datagram_endpoint(self, protocol_factory, local_addr=None, remote_addr=None, *, family=0, proto=0, flags=0): @@ -398,7 +680,7 @@ def create_datagram_endpoint(self, protocol_factory, raise ValueError('unexpected address family') addr_pairs_info = (((family, proto), (None, None)),) else: - # join addresss by (family, protocol) + # join address by (family, protocol) addr_infos = collections.OrderedDict() for idx, addr in ((0, local_addr), (1, remote_addr)): if addr is not None: @@ -447,16 +729,38 @@ def create_datagram_endpoint(self, protocol_factory, if sock is not None: sock.close() exceptions.append(exc) + except: + if sock is not None: + sock.close() + raise else: break else: raise exceptions[0] protocol = protocol_factory() - transport = self._make_datagram_transport(sock, protocol, r_addr) + waiter = futures.Future(loop=self) + transport = self._make_datagram_transport(sock, protocol, r_addr, + waiter) + if self._debug: + if local_addr: + logger.info("Datagram endpoint local_addr=%r remote_addr=%r " + "created: (%r, %r)", + local_addr, remote_addr, transport, protocol) + else: + logger.debug("Datagram endpoint remote_addr=%r created: " + "(%r, %r)", + remote_addr, transport, protocol) + + try: + yield from waiter + except: + transport.close() + raise + return transport, protocol - @tasks.coroutine + @coroutine def create_server(self, protocol_factory, host=None, port=None, *, family=socket.AF_UNSPEC, @@ -465,7 +769,12 @@ def create_server(self, protocol_factory, host=None, port=None, backlog=100, ssl=None, reuse_address=None): - """XXX""" + """Create a TCP server bound to host and port. + + Return a Server object which can be used to stop the service. + + This method is a coroutine. + """ if isinstance(ssl, bool): raise TypeError('ssl argument must be an SSLContext or None') if host is not None or port is not None: @@ -494,6 +803,10 @@ def create_server(self, protocol_factory, host=None, port=None, sock = socket.socket(af, socktype, proto) except socket.error: # Assume it's a bad family/type/protocol combination. + if self._debug: + logger.warning('create_server() failed to create ' + 'socket.socket(%r, %r, %r)', + af, socktype, proto, exc_info=True) continue sockets.append(sock) if reuse_address: @@ -519,8 +832,7 @@ def create_server(self, protocol_factory, host=None, port=None, sock.close() else: if sock is None: - raise ValueError( - 'host and port was not specified and no sock specified') + raise ValueError('Neither host/port nor sock were specified') sockets = [sock] server = Server(self, sockets) @@ -528,64 +840,239 @@ def create_server(self, protocol_factory, host=None, port=None, sock.listen(backlog) sock.setblocking(False) self._start_serving(protocol_factory, sock, ssl, server) + if self._debug: + logger.info("%r is serving", server) return server - @tasks.coroutine + @coroutine def connect_read_pipe(self, protocol_factory, pipe): protocol = protocol_factory() waiter = futures.Future(loop=self) transport = self._make_read_pipe_transport(pipe, protocol, waiter) - yield from waiter + + try: + yield from waiter + except: + transport.close() + raise + + if self._debug: + logger.debug('Read pipe %r connected: (%r, %r)', + pipe.fileno(), transport, protocol) return transport, protocol - @tasks.coroutine + @coroutine def connect_write_pipe(self, protocol_factory, pipe): protocol = protocol_factory() waiter = futures.Future(loop=self) transport = self._make_write_pipe_transport(pipe, protocol, waiter) - yield from waiter + + try: + yield from waiter + except: + transport.close() + raise + + if self._debug: + logger.debug('Write pipe %r connected: (%r, %r)', + pipe.fileno(), transport, protocol) return transport, protocol - @tasks.coroutine + def _log_subprocess(self, msg, stdin, stdout, stderr): + info = [msg] + if stdin is not None: + info.append('stdin=%s' % _format_pipe(stdin)) + if stdout is not None and stderr == subprocess.STDOUT: + info.append('stdout=stderr=%s' % _format_pipe(stdout)) + else: + if stdout is not None: + info.append('stdout=%s' % _format_pipe(stdout)) + if stderr is not None: + info.append('stderr=%s' % _format_pipe(stderr)) + logger.debug(' '.join(info)) + + @coroutine def subprocess_shell(self, protocol_factory, cmd, *, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=False, shell=True, bufsize=0, **kwargs): - assert not universal_newlines, "universal_newlines must be False" - assert shell, "shell must be True" - assert isinstance(cmd, str), cmd + if not isinstance(cmd, (bytes, str)): + raise ValueError("cmd must be a string") + if universal_newlines: + raise ValueError("universal_newlines must be False") + if not shell: + raise ValueError("shell must be True") + if bufsize != 0: + raise ValueError("bufsize must be 0") protocol = protocol_factory() + if self._debug: + # don't log parameters: they may contain sensitive information + # (password) and may be too long + debug_log = 'run shell command %r' % cmd + self._log_subprocess(debug_log, stdin, stdout, stderr) transport = yield from self._make_subprocess_transport( protocol, cmd, True, stdin, stdout, stderr, bufsize, **kwargs) + if self._debug: + logger.info('%s: %r' % (debug_log, transport)) return transport, protocol - @tasks.coroutine - def subprocess_exec(self, protocol_factory, *args, stdin=subprocess.PIPE, - stdout=subprocess.PIPE, stderr=subprocess.PIPE, - universal_newlines=False, shell=False, bufsize=0, - **kwargs): - assert not universal_newlines, "universal_newlines must be False" - assert not shell, "shell must be False" + @coroutine + def subprocess_exec(self, protocol_factory, program, *args, + stdin=subprocess.PIPE, stdout=subprocess.PIPE, + stderr=subprocess.PIPE, universal_newlines=False, + shell=False, bufsize=0, **kwargs): + if universal_newlines: + raise ValueError("universal_newlines must be False") + if shell: + raise ValueError("shell must be False") + if bufsize != 0: + raise ValueError("bufsize must be 0") + popen_args = (program,) + args + for arg in popen_args: + if not isinstance(arg, (str, bytes)): + raise TypeError("program arguments must be " + "a bytes or text string, not %s" + % type(arg).__name__) protocol = protocol_factory() + if self._debug: + # don't log parameters: they may contain sensitive information + # (password) and may be too long + debug_log = 'execute program %r' % program + self._log_subprocess(debug_log, stdin, stdout, stderr) transport = yield from self._make_subprocess_transport( - protocol, args, False, stdin, stdout, stderr, bufsize, **kwargs) + protocol, popen_args, False, stdin, stdout, stderr, + bufsize, **kwargs) + if self._debug: + logger.info('%s: %r' % (debug_log, transport)) return transport, protocol + def set_exception_handler(self, handler): + """Set handler as the new event loop exception handler. + + If handler is None, the default exception handler will + be set. + + If handler is a callable object, it should have a + signature matching '(loop, context)', where 'loop' + will be a reference to the active event loop, 'context' + will be a dict object (see `call_exception_handler()` + documentation for details about context). + """ + if handler is not None and not callable(handler): + raise TypeError('A callable object or None is expected, ' + 'got {!r}'.format(handler)) + self._exception_handler = handler + + def default_exception_handler(self, context): + """Default exception handler. + + This is called when an exception occurs and no exception + handler is set, and can be called by a custom exception + handler that wants to defer to the default behavior. + + The context parameter has the same meaning as in + `call_exception_handler()`. + """ + message = context.get('message') + if not message: + message = 'Unhandled exception in event loop' + + exception = context.get('exception') + if exception is not None: + exc_info = (type(exception), exception, exception.__traceback__) + else: + exc_info = False + + if ('source_traceback' not in context + and self._current_handle is not None + and self._current_handle._source_traceback): + context['handle_traceback'] = self._current_handle._source_traceback + + log_lines = [message] + for key in sorted(context): + if key in {'message', 'exception'}: + continue + value = context[key] + if key == 'source_traceback': + tb = ''.join(traceback.format_list(value)) + value = 'Object created at (most recent call last):\n' + value += tb.rstrip() + elif key == 'handle_traceback': + tb = ''.join(traceback.format_list(value)) + value = 'Handle created at (most recent call last):\n' + value += tb.rstrip() + else: + value = repr(value) + log_lines.append('{}: {}'.format(key, value)) + + logger.error('\n'.join(log_lines), exc_info=exc_info) + + def call_exception_handler(self, context): + """Call the current event loop's exception handler. + + The context argument is a dict containing the following keys: + + - 'message': Error message; + - 'exception' (optional): Exception object; + - 'future' (optional): Future instance; + - 'handle' (optional): Handle instance; + - 'protocol' (optional): Protocol instance; + - 'transport' (optional): Transport instance; + - 'socket' (optional): Socket instance. + + New keys maybe introduced in the future. + + Note: do not overload this method in an event loop subclass. + For custom exception handling, use the + `set_exception_handler()` method. + """ + if self._exception_handler is None: + try: + self.default_exception_handler(context) + except Exception: + # Second protection layer for unexpected errors + # in the default implementation, as well as for subclassed + # event loops with overloaded "default_exception_handler". + logger.error('Exception in default exception handler', + exc_info=True) + else: + try: + self._exception_handler(self, context) + except Exception as exc: + # Exception in the user set custom exception handler. + try: + # Let's try default handler. + self.default_exception_handler({ + 'message': 'Unhandled error in exception handler', + 'exception': exc, + 'context': context, + }) + except Exception: + # Guard 'default_exception_handler' in case it is + # overloaded. + logger.error('Exception in default exception handler ' + 'while handling an unexpected error ' + 'in custom exception handler', + exc_info=True) + def _add_callback(self, handle): - """Add a Handle to ready or scheduled.""" + """Add a Handle to _scheduled (TimerHandle) or _ready.""" assert isinstance(handle, events.Handle), 'A Handle is required here' if handle._cancelled: return - if isinstance(handle, events.TimerHandle): - heapq.heappush(self._scheduled, handle) - else: - self._ready.append(handle) + assert not isinstance(handle, events.TimerHandle) + self._ready.append(handle) def _add_callback_signalsafe(self, handle): """Like _add_callback() but called from a signal handler.""" self._add_callback(handle) self._write_to_self() + def _timer_handle_cancelled(self, handle): + """Notification that a TimerHandle has been cancelled.""" + if handle._scheduled: + self._timer_cancelled_count += 1 + def _run_once(self): """Run one full iteration of the event loop. @@ -593,9 +1080,29 @@ def _run_once(self): schedules the resulting callbacks, and finally schedules 'call_later' callbacks. """ - # Remove delayed calls that were cancelled from head of queue. - while self._scheduled and self._scheduled[0]._cancelled: - heapq.heappop(self._scheduled) + + sched_count = len(self._scheduled) + if (sched_count > _MIN_SCHEDULED_TIMER_HANDLES and + self._timer_cancelled_count / sched_count > + _MIN_CANCELLED_TIMER_HANDLES_FRACTION): + # Remove delayed calls that were cancelled if their number + # is too high + new_scheduled = [] + for handle in self._scheduled: + if handle._cancelled: + handle._scheduled = False + else: + new_scheduled.append(handle) + + heapq.heapify(new_scheduled) + self._scheduled = new_scheduled + self._timer_cancelled_count = 0 + else: + # Remove delayed calls that were cancelled from head of queue. + while self._scheduled and self._scheduled[0]._cancelled: + self._timer_cancelled_count -= 1 + handle = heapq.heappop(self._scheduled) + handle._scheduled = False timeout = None if self._ready: @@ -603,31 +1110,40 @@ def _run_once(self): elif self._scheduled: # Compute the desired timeout. when = self._scheduled[0]._when - deadline = max(0, when - self.time()) - if timeout is None: - timeout = deadline + timeout = max(0, when - self.time()) + + if self._debug and timeout != 0: + t0 = self.time() + event_list = self._selector.select(timeout) + dt = self.time() - t0 + if dt >= 1.0: + level = logging.INFO else: - timeout = min(timeout, deadline) - - # TODO: Instrumentation only in debug mode? - t0 = self.time() - event_list = self._selector.select(timeout) - t1 = self.time() - argstr = '' if timeout is None else '{:.3f}'.format(timeout) - if t1-t0 >= 1: - level = logging.INFO + level = logging.DEBUG + nevent = len(event_list) + if timeout is None: + logger.log(level, 'poll took %.3f ms: %s events', + dt * 1e3, nevent) + elif nevent: + logger.log(level, + 'poll %.3f ms took %.3f ms: %s events', + timeout * 1e3, dt * 1e3, nevent) + elif dt >= 1.0: + logger.log(level, + 'poll %.3f ms took %.3f ms: timeout', + timeout * 1e3, dt * 1e3) else: - level = logging.DEBUG - logger.log(level, 'poll%s took %.3f seconds', argstr, t1-t0) + event_list = self._selector.select(timeout) self._process_events(event_list) # Handle 'later' callbacks that are ready. - now = self.time() + end_time = self.time() + self._clock_resolution while self._scheduled: handle = self._scheduled[0] - if handle._when > now: + if handle._when >= end_time: break handle = heapq.heappop(self._scheduled) + handle._scheduled = False self._ready.append(handle) # This is the only place where callbacks are actually *called*. @@ -635,10 +1151,29 @@ def _run_once(self): # Note: We run all currently scheduled callbacks, but not any # callbacks scheduled by callbacks run this time around -- # they will be run the next time (after another I/O poll). - # Use an idiom that is threadsafe without using locks. + # Use an idiom that is thread-safe without using locks. ntodo = len(self._ready) for i in range(ntodo): handle = self._ready.popleft() - if not handle._cancelled: + if handle._cancelled: + continue + if self._debug: + try: + self._current_handle = handle + t0 = self.time() + handle._run() + dt = self.time() - t0 + if dt >= self.slow_callback_duration: + logger.warning('Executing %s took %.3f seconds', + _format_handle(handle), dt) + finally: + self._current_handle = None + else: handle._run() handle = None # Needed to break cycles when an exception occurs. + + def get_debug(self): + return self._debug + + def set_debug(self, enabled): + self._debug = enabled diff --git a/Lib/asyncio/base_subprocess.py b/Lib/asyncio/base_subprocess.py index d15fb159d90a..f56873fbeade 100644 --- a/Lib/asyncio/base_subprocess.py +++ b/Lib/asyncio/base_subprocess.py @@ -1,39 +1,81 @@ import collections import subprocess +import sys +import warnings +from . import futures from . import protocols -from . import tasks from . import transports - - -STDIN = 0 -STDOUT = 1 -STDERR = 2 +from .coroutines import coroutine +from .log import logger class BaseSubprocessTransport(transports.SubprocessTransport): def __init__(self, loop, protocol, args, shell, stdin, stdout, stderr, bufsize, - extra=None, **kwargs): + waiter=None, extra=None, **kwargs): super().__init__(extra) + self._closed = False self._protocol = protocol self._loop = loop - + self._proc = None + self._pid = None + self._returncode = None + self._exit_waiters = [] + self._pending_calls = collections.deque() self._pipes = {} + self._finished = False + if stdin == subprocess.PIPE: - self._pipes[STDIN] = None + self._pipes[0] = None if stdout == subprocess.PIPE: - self._pipes[STDOUT] = None + self._pipes[1] = None if stderr == subprocess.PIPE: - self._pipes[STDERR] = None - self._pending_calls = collections.deque() - self._finished = False - self._returncode = None + self._pipes[2] = None + + # Create the child process: set the _proc attribute self._start(args=args, shell=shell, stdin=stdin, stdout=stdout, stderr=stderr, bufsize=bufsize, **kwargs) + self._pid = self._proc.pid self._extra['subprocess'] = self._proc + if self._loop.get_debug(): + if isinstance(args, (bytes, str)): + program = args + else: + program = args[0] + logger.debug('process %r created: pid %s', + program, self._pid) + + self._loop.create_task(self._connect_pipes(waiter)) + + def __repr__(self): + info = [self.__class__.__name__] + if self._closed: + info.append('closed') + info.append('pid=%s' % self._pid) + if self._returncode is not None: + info.append('returncode=%s' % self._returncode) + else: + info.append('running') + + stdin = self._pipes.get(0) + if stdin is not None: + info.append('stdin=%s' % stdin.pipe) + + stdout = self._pipes.get(1) + stderr = self._pipes.get(2) + if stdout is not None and stderr is stdout: + info.append('stdout=stderr=%s' % stdout.pipe) + else: + if stdout is not None: + info.append('stdout=%s' % stdout.pipe) + if stderr is not None: + info.append('stderr=%s' % stderr.pipe) + + return '<%s>' % ' '.join(info) + def _start(self, args, shell, stdin, stdout, stderr, bufsize, **kwargs): raise NotImplementedError @@ -44,13 +86,42 @@ def _make_read_subprocess_pipe_proto(self, fd): raise NotImplementedError def close(self): + if self._closed: + return + self._closed = True + for proto in self._pipes.values(): + if proto is None: + continue proto.pipe.close() - if self._returncode is None: - self.terminate() + + if (self._proc is not None + # the child process finished? + and self._returncode is None + # the child process finished but the transport was not notified yet? + and self._proc.poll() is None + ): + if self._loop.get_debug(): + logger.warning('Close running child process: kill %r', self) + + try: + self._proc.kill() + except ProcessLookupError: + pass + + # Don't clear the _proc reference yet: _post_init() may still run + + # On Python 3.3 and older, objects with a destructor part of a reference + # cycle are never destroyed. It's not more the case on Python 3.4 thanks + # to the PEP 442. + if sys.version_info >= (3, 4): + def __del__(self): + if not self._closed: + warnings.warn("unclosed transport %r" % self, ResourceWarning) + self.close() def get_pid(self): - return self._proc.pid + return self._pid def get_returncode(self): return self._returncode @@ -61,33 +132,58 @@ def get_pipe_transport(self, fd): else: return None + def _check_proc(self): + if self._proc is None: + raise ProcessLookupError() + def send_signal(self, signal): + self._check_proc() self._proc.send_signal(signal) def terminate(self): + self._check_proc() self._proc.terminate() def kill(self): + self._check_proc() self._proc.kill() - @tasks.coroutine - def _post_init(self): - proc = self._proc - loop = self._loop - if proc.stdin is not None: - transp, proto = yield from loop.connect_write_pipe( - lambda: WriteSubprocessPipeProto(self, STDIN), - proc.stdin) - if proc.stdout is not None: - transp, proto = yield from loop.connect_read_pipe( - lambda: ReadSubprocessPipeProto(self, STDOUT), - proc.stdout) - if proc.stderr is not None: - transp, proto = yield from loop.connect_read_pipe( - lambda: ReadSubprocessPipeProto(self, STDERR), - proc.stderr) - if not self._pipes: - self._try_connected() + @coroutine + def _connect_pipes(self, waiter): + try: + proc = self._proc + loop = self._loop + + if proc.stdin is not None: + _, pipe = yield from loop.connect_write_pipe( + lambda: WriteSubprocessPipeProto(self, 0), + proc.stdin) + self._pipes[0] = pipe + + if proc.stdout is not None: + _, pipe = yield from loop.connect_read_pipe( + lambda: ReadSubprocessPipeProto(self, 1), + proc.stdout) + self._pipes[1] = pipe + + if proc.stderr is not None: + _, pipe = yield from loop.connect_read_pipe( + lambda: ReadSubprocessPipeProto(self, 2), + proc.stderr) + self._pipes[2] = pipe + + assert self._pending_calls is not None + + loop.call_soon(self._protocol.connection_made, self) + for callback, data in self._pending_calls: + loop.call_soon(callback, *data) + self._pending_calls = None + except Exception as exc: + if waiter is not None and not waiter.cancelled(): + waiter.set_exception(exc) + else: + if waiter is not None and not waiter.cancelled(): + waiter.set_result(None) def _call(self, cb, *data): if self._pending_calls is not None: @@ -95,14 +191,6 @@ def _call(self, cb, *data): else: self._loop.call_soon(cb, *data) - def _try_connected(self): - assert self._pending_calls is not None - if all(p is not None and p.connected for p in self._pipes.values()): - self._loop.call_soon(self._protocol.connection_made, self) - for callback, data in self._pending_calls: - self._loop.call_soon(callback, *data) - self._pending_calls = None - def _pipe_connection_lost(self, fd, exc): self._call(self._protocol.pipe_connection_lost, fd, exc) self._try_finish() @@ -113,11 +201,30 @@ def _pipe_data_received(self, fd, data): def _process_exited(self, returncode): assert returncode is not None, returncode assert self._returncode is None, self._returncode + if self._loop.get_debug(): + logger.info('%r exited with return code %r', + self, returncode) self._returncode = returncode - self._loop._subprocess_closed(self) self._call(self._protocol.process_exited) self._try_finish() + # wake up futures waiting for wait() + for waiter in self._exit_waiters: + if not waiter.cancelled(): + waiter.set_result(returncode) + self._exit_waiters = None + + def _wait(self): + """Wait until the process exit and return the process return code. + + This method is a coroutine.""" + if self._returncode is not None: + return self._returncode + + waiter = futures.Future(loop=self._loop) + self._exit_waiters.append(waiter) + return (yield from waiter) + def _try_finish(self): assert not self._finished if self._returncode is None: @@ -125,38 +232,42 @@ def _try_finish(self): if all(p is not None and p.disconnected for p in self._pipes.values()): self._finished = True - self._loop.call_soon(self._call_connection_lost, None) + self._call(self._call_connection_lost, None) def _call_connection_lost(self, exc): try: self._protocol.connection_lost(exc) finally: + self._loop = None self._proc = None self._protocol = None - self._loop = None class WriteSubprocessPipeProto(protocols.BaseProtocol): - pipe = None def __init__(self, proc, fd): self.proc = proc self.fd = fd - self.connected = False + self.pipe = None self.disconnected = False - proc._pipes[fd] = self def connection_made(self, transport): - self.connected = True self.pipe = transport - self.proc._try_connected() + + def __repr__(self): + return ('<%s fd=%s pipe=%r>' + % (self.__class__.__name__, self.fd, self.pipe)) def connection_lost(self, exc): self.disconnected = True self.proc._pipe_connection_lost(self.fd, exc) + self.proc = None + + def pause_writing(self): + self.proc._protocol.pause_writing() - def eof_received(self): - pass + def resume_writing(self): + self.proc._protocol.resume_writing() class ReadSubprocessPipeProto(WriteSubprocessPipeProto, diff --git a/Lib/asyncio/coroutines.py b/Lib/asyncio/coroutines.py new file mode 100644 index 000000000000..a1b28751f700 --- /dev/null +++ b/Lib/asyncio/coroutines.py @@ -0,0 +1,199 @@ +__all__ = ['coroutine', + 'iscoroutinefunction', 'iscoroutine'] + +import functools +import inspect +import opcode +import os +import sys +import traceback +import types + +from . import events +from . import futures +from .log import logger + + +# Opcode of "yield from" instruction +_YIELD_FROM = opcode.opmap['YIELD_FROM'] + +# If you set _DEBUG to true, @coroutine will wrap the resulting +# generator objects in a CoroWrapper instance (defined below). That +# instance will log a message when the generator is never iterated +# over, which may happen when you forget to use "yield from" with a +# coroutine call. Note that the value of the _DEBUG flag is taken +# when the decorator is used, so to be of any use it must be set +# before you define your coroutines. A downside of using this feature +# is that tracebacks show entries for the CoroWrapper.__next__ method +# when _DEBUG is true. +_DEBUG = (not sys.flags.ignore_environment + and bool(os.environ.get('PYTHONASYNCIODEBUG'))) + + +# Check for CPython issue #21209 +def has_yield_from_bug(): + class MyGen: + def __init__(self): + self.send_args = None + def __iter__(self): + return self + def __next__(self): + return 42 + def send(self, *what): + self.send_args = what + return None + def yield_from_gen(gen): + yield from gen + value = (1, 2, 3) + gen = MyGen() + coro = yield_from_gen(gen) + next(coro) + coro.send(value) + return gen.send_args != (value,) +_YIELD_FROM_BUG = has_yield_from_bug() +del has_yield_from_bug + + +class CoroWrapper: + # Wrapper for coroutine object in _DEBUG mode. + + def __init__(self, gen, func): + assert inspect.isgenerator(gen), gen + self.gen = gen + self.func = func + self._source_traceback = traceback.extract_stack(sys._getframe(1)) + # __name__, __qualname__, __doc__ attributes are set by the coroutine() + # decorator + + def __repr__(self): + coro_repr = _format_coroutine(self) + if self._source_traceback: + frame = self._source_traceback[-1] + coro_repr += ', created at %s:%s' % (frame[0], frame[1]) + return '<%s %s>' % (self.__class__.__name__, coro_repr) + + def __iter__(self): + return self + + def __next__(self): + return next(self.gen) + + if _YIELD_FROM_BUG: + # For for CPython issue #21209: using "yield from" and a custom + # generator, generator.send(tuple) unpacks the tuple instead of passing + # the tuple unchanged. Check if the caller is a generator using "yield + # from" to decide if the parameter should be unpacked or not. + def send(self, *value): + frame = sys._getframe() + caller = frame.f_back + assert caller.f_lasti >= 0 + if caller.f_code.co_code[caller.f_lasti] != _YIELD_FROM: + value = value[0] + return self.gen.send(value) + else: + def send(self, value): + return self.gen.send(value) + + def throw(self, exc): + return self.gen.throw(exc) + + def close(self): + return self.gen.close() + + @property + def gi_frame(self): + return self.gen.gi_frame + + @property + def gi_running(self): + return self.gen.gi_running + + @property + def gi_code(self): + return self.gen.gi_code + + def __del__(self): + # Be careful accessing self.gen.frame -- self.gen might not exist. + gen = getattr(self, 'gen', None) + frame = getattr(gen, 'gi_frame', None) + if frame is not None and frame.f_lasti == -1: + msg = '%r was never yielded from' % self + tb = getattr(self, '_source_traceback', ()) + if tb: + tb = ''.join(traceback.format_list(tb)) + msg += ('\nCoroutine object created at ' + '(most recent call last):\n') + msg += tb.rstrip() + logger.error(msg) + + +def coroutine(func): + """Decorator to mark coroutines. + + If the coroutine is not yielded from before it is destroyed, + an error message is logged. + """ + if inspect.isgeneratorfunction(func): + coro = func + else: + @functools.wraps(func) + def coro(*args, **kw): + res = func(*args, **kw) + if isinstance(res, futures.Future) or inspect.isgenerator(res): + res = yield from res + return res + + if not _DEBUG: + wrapper = coro + else: + @functools.wraps(func) + def wrapper(*args, **kwds): + w = CoroWrapper(coro(*args, **kwds), func) + if w._source_traceback: + del w._source_traceback[-1] + w.__name__ = func.__name__ + if hasattr(func, '__qualname__'): + w.__qualname__ = func.__qualname__ + w.__doc__ = func.__doc__ + return w + + wrapper._is_coroutine = True # For iscoroutinefunction(). + return wrapper + + +def iscoroutinefunction(func): + """Return True if func is a decorated coroutine function.""" + return getattr(func, '_is_coroutine', False) + + +_COROUTINE_TYPES = (types.GeneratorType, CoroWrapper) + +def iscoroutine(obj): + """Return True if obj is a coroutine object.""" + return isinstance(obj, _COROUTINE_TYPES) + + +def _format_coroutine(coro): + assert iscoroutine(coro) + coro_name = getattr(coro, '__qualname__', coro.__name__) + + filename = coro.gi_code.co_filename + if (isinstance(coro, CoroWrapper) + and not inspect.isgeneratorfunction(coro.func)): + filename, lineno = events._get_function_source(coro.func) + if coro.gi_frame is None: + coro_repr = ('%s() done, defined at %s:%s' + % (coro_name, filename, lineno)) + else: + coro_repr = ('%s() running, defined at %s:%s' + % (coro_name, filename, lineno)) + elif coro.gi_frame is not None: + lineno = coro.gi_frame.f_lineno + coro_repr = ('%s() running at %s:%s' + % (coro_name, filename, lineno)) + else: + lineno = coro.gi_code.co_firstlineno + coro_repr = ('%s() done, defined at %s:%s' + % (coro_name, filename, lineno)) + + return coro_repr diff --git a/Lib/asyncio/events.py b/Lib/asyncio/events.py index c10faa75b066..01320cdf62bf 100644 --- a/Lib/asyncio/events.py +++ b/Lib/asyncio/events.py @@ -8,63 +8,148 @@ 'get_child_watcher', 'set_child_watcher', ] +import functools +import inspect +import reprlib +import socket import subprocess import sys import threading -import socket +import traceback + + +_PY34 = sys.version_info >= (3, 4) + -from .log import logger +def _get_function_source(func): + if _PY34: + func = inspect.unwrap(func) + elif hasattr(func, '__wrapped__'): + func = func.__wrapped__ + if inspect.isfunction(func): + code = func.__code__ + return (code.co_filename, code.co_firstlineno) + if isinstance(func, functools.partial): + return _get_function_source(func.func) + if _PY34 and isinstance(func, functools.partialmethod): + return _get_function_source(func.func) + return None + + +def _format_args(args): + """Format function arguments. + + Special case for a single parameter: ('hello',) is formatted as ('hello'). + """ + # use reprlib to limit the length of the output + args_repr = reprlib.repr(args) + if len(args) == 1 and args_repr.endswith(',)'): + args_repr = args_repr[:-2] + ')' + return args_repr + + +def _format_callback(func, args, suffix=''): + if isinstance(func, functools.partial): + if args is not None: + suffix = _format_args(args) + suffix + return _format_callback(func.func, func.args, suffix) + + func_repr = getattr(func, '__qualname__', None) + if not func_repr: + func_repr = repr(func) + + if args is not None: + func_repr += _format_args(args) + if suffix: + func_repr += suffix + + source = _get_function_source(func) + if source: + func_repr += ' at %s:%s' % source + return func_repr class Handle: """Object returned by callback registration methods.""" - def __init__(self, callback, args): + __slots__ = ('_callback', '_args', '_cancelled', '_loop', + '_source_traceback', '_repr', '__weakref__') + + def __init__(self, callback, args, loop): + assert not isinstance(callback, Handle), 'A Handle is not a callback' + self._loop = loop self._callback = callback self._args = args self._cancelled = False + self._repr = None + if self._loop.get_debug(): + self._source_traceback = traceback.extract_stack(sys._getframe(1)) + else: + self._source_traceback = None + + def _repr_info(self): + info = [self.__class__.__name__] + if self._cancelled: + info.append('cancelled') + if self._callback is not None: + info.append(_format_callback(self._callback, self._args)) + if self._source_traceback: + frame = self._source_traceback[-1] + info.append('created at %s:%s' % (frame[0], frame[1])) + return info def __repr__(self): - res = 'Handle({}, {})'.format(self._callback, self._args) - if self._cancelled: - res += '<cancelled>' - return res + if self._repr is not None: + return self._repr + info = self._repr_info() + return '<%s>' % ' '.join(info) def cancel(self): - self._cancelled = True + if not self._cancelled: + self._cancelled = True + if self._loop.get_debug(): + # Keep a representation in debug mode to keep callback and + # parameters. For example, to log the warning + # "Executing <Handle...> took 2.5 second" + self._repr = repr(self) + self._callback = None + self._args = None def _run(self): try: self._callback(*self._args) - except Exception: - logger.exception('Exception in callback %s %r', - self._callback, self._args) + except Exception as exc: + cb = _format_callback(self._callback, self._args) + msg = 'Exception in callback {}'.format(cb) + context = { + 'message': msg, + 'exception': exc, + 'handle': self, + } + if self._source_traceback: + context['source_traceback'] = self._source_traceback + self._loop.call_exception_handler(context) self = None # Needed to break cycles when an exception occurs. -def make_handle(callback, args): - # TODO: Inline this? Or make it a private EventLoop method? - assert not isinstance(callback, Handle), 'A Handle is not a callback' - return Handle(callback, args) - - class TimerHandle(Handle): """Object returned by timed callback registration methods.""" - def __init__(self, when, callback, args): - assert when is not None - super().__init__(callback, args) + __slots__ = ['_scheduled', '_when'] + def __init__(self, when, callback, args, loop): + assert when is not None + super().__init__(callback, args, loop) + if self._source_traceback: + del self._source_traceback[-1] self._when = when + self._scheduled = False - def __repr__(self): - res = 'TimerHandle({}, {}, {})'.format(self._when, - self._callback, - self._args) - if self._cancelled: - res += '<cancelled>' - - return res + def _repr_info(self): + info = super()._repr_info() + pos = 2 if self._cancelled else 1 + info.insert(pos, 'when=%s' % self._when) + return info def __hash__(self): return hash(self._when) @@ -93,13 +178,14 @@ def __eq__(self, other): self._cancelled == other._cancelled) return NotImplemented - def __ne__(self, other): - equal = self.__eq__(other) - return NotImplemented if equal is NotImplemented else not equal + def cancel(self): + if not self._cancelled: + self._loop._timer_handle_cancelled(self) + super().cancel() class AbstractServer: - """Abstract server returned by create_service().""" + """Abstract server returned by create_server().""" def close(self): """Stop serving. This leaves existing connections open.""" @@ -138,6 +224,10 @@ def is_running(self): """Return whether the event loop is currently running.""" raise NotImplementedError + def is_closed(self): + """Returns True if the event loop was closed.""" + raise NotImplementedError + def close(self): """Close the loop. @@ -151,6 +241,10 @@ def close(self): # Methods scheduling callbacks. All these return Handles. + def _timer_handle_cancelled(self, handle): + """Notification that a TimerHandle has been cancelled.""" + raise NotImplementedError + def call_soon(self, callback, *args): return self.call_later(0, callback, *args) @@ -163,6 +257,11 @@ def call_at(self, when, callback, *args): def time(self): raise NotImplementedError + # Method scheduling a coroutine object: create a task. + + def create_task(self, coro): + raise NotImplementedError + # Methods for interacting with threads. def call_soon_threadsafe(self, callback, *args): @@ -221,6 +320,32 @@ def create_server(self, protocol_factory, host=None, port=None, *, """ raise NotImplementedError + def create_unix_connection(self, protocol_factory, path, *, + ssl=None, sock=None, + server_hostname=None): + raise NotImplementedError + + def create_unix_server(self, protocol_factory, path, *, + sock=None, backlog=100, ssl=None): + """A coroutine which creates a UNIX Domain Socket server. + + The return value is a Server object, which can be used to stop + the service. + + path is a str, representing a file systsem path to bind the + server socket to. + + sock can optionally be specified in order to use a preexisting + socket object. + + backlog is the maximum number of queued connections passed to + listen() (defaults to 100). + + ssl can be set to an SSLContext to enable SSL over the + accepted connections. + """ + raise NotImplementedError + def create_datagram_endpoint(self, protocol_factory, local_addr=None, remote_addr=None, *, family=0, proto=0, flags=0): @@ -229,11 +354,11 @@ def create_datagram_endpoint(self, protocol_factory, # Pipes and subprocesses. def connect_read_pipe(self, protocol_factory, pipe): - """Register read pipe in eventloop. + """Register read pipe in event loop. Set the pipe to non-blocking mode. protocol_factory should instantiate object with Protocol interface. - pipe is file-like object already switched to nonblocking. - Return pair (transport, protocol), where transport support + pipe is a file-like object. + Return pair (transport, protocol), where transport supports the ReadTransport interface.""" # The reason to accept file-like object instead of just file descriptor # is: we need to own pipe and close it at transport finishing @@ -242,7 +367,7 @@ def connect_read_pipe(self, protocol_factory, pipe): raise NotImplementedError def connect_write_pipe(self, protocol_factory, pipe): - """Register write pipe in eventloop. + """Register write pipe in event loop. protocol_factory should instantiate object with BaseProtocol interface. Pipe is file-like object already switched to nonblocking. @@ -303,30 +428,57 @@ def add_signal_handler(self, sig, callback, *args): def remove_signal_handler(self, sig): raise NotImplementedError + # Error handlers. + + def set_exception_handler(self, handler): + raise NotImplementedError + + def default_exception_handler(self, context): + raise NotImplementedError + + def call_exception_handler(self, context): + raise NotImplementedError + + # Debug flag management. + + def get_debug(self): + raise NotImplementedError + + def set_debug(self, enabled): + raise NotImplementedError + class AbstractEventLoopPolicy: """Abstract policy for accessing the event loop.""" def get_event_loop(self): - """XXX""" + """Get the event loop for the current context. + + Returns an event loop object implementing the BaseEventLoop interface, + or raises an exception in case no event loop has been set for the + current context and the current policy does not specify to create one. + + It should never return None.""" raise NotImplementedError def set_event_loop(self, loop): - """XXX""" + """Set the event loop for the current context to loop.""" raise NotImplementedError def new_event_loop(self): - """XXX""" + """Create and return a new event loop object according to this + policy's rules. If there's need to set this loop as the event loop for + the current context, set_event_loop must be called explicitly.""" raise NotImplementedError # Child processes handling (Unix only). def get_child_watcher(self): - """XXX""" + "Get the watcher for child processes." raise NotImplementedError def set_child_watcher(self, watcher): - """XXX""" + """Set the watcher for child processes.""" raise NotImplementedError @@ -361,9 +513,9 @@ def get_event_loop(self): not self._local._set_called and isinstance(threading.current_thread(), threading._MainThread)): self.set_event_loop(self.new_event_loop()) - assert self._local._loop is not None, \ - ('There is no current event loop in thread %r.' % - threading.current_thread().name) + if self._local._loop is None: + raise RuntimeError('There is no current event loop in thread %r.' + % threading.current_thread().name) return self._local._loop def set_event_loop(self, loop): @@ -400,39 +552,42 @@ def _init_event_loop_policy(): def get_event_loop_policy(): - """XXX""" + """Get the current event loop policy.""" if _event_loop_policy is None: _init_event_loop_policy() return _event_loop_policy def set_event_loop_policy(policy): - """XXX""" + """Set the current event loop policy. + + If policy is None, the default policy is restored.""" global _event_loop_policy assert policy is None or isinstance(policy, AbstractEventLoopPolicy) _event_loop_policy = policy def get_event_loop(): - """XXX""" + """Equivalent to calling get_event_loop_policy().get_event_loop().""" return get_event_loop_policy().get_event_loop() def set_event_loop(loop): - """XXX""" + """Equivalent to calling get_event_loop_policy().set_event_loop(loop).""" get_event_loop_policy().set_event_loop(loop) def new_event_loop(): - """XXX""" + """Equivalent to calling get_event_loop_policy().new_event_loop().""" return get_event_loop_policy().new_event_loop() def get_child_watcher(): - """XXX""" + """Equivalent to calling get_event_loop_policy().get_child_watcher().""" return get_event_loop_policy().get_child_watcher() def set_child_watcher(watcher): - """XXX""" + """Equivalent to calling + get_event_loop_policy().set_child_watcher(watcher).""" return get_event_loop_policy().set_child_watcher(watcher) diff --git a/Lib/asyncio/futures.py b/Lib/asyncio/futures.py index dd3e718d9a50..2c741fd42269 100644 --- a/Lib/asyncio/futures.py +++ b/Lib/asyncio/futures.py @@ -7,17 +7,19 @@ import concurrent.futures._base import logging +import reprlib +import sys import traceback from . import events -from .log import logger # States for Future. _PENDING = 'PENDING' _CANCELLED = 'CANCELLED' _FINISHED = 'FINISHED' -# TODO: Do we really want to depend on concurrent.futures internals? +_PY34 = sys.version_info >= (3, 4) + Error = concurrent.futures._base.Error CancelledError = concurrent.futures.CancelledError TimeoutError = concurrent.futures.TimeoutError @@ -27,7 +29,6 @@ class InvalidStateError(Error): """The operation is not allowed in this state.""" - # TODO: Show the future, its state, the method, and the required state. class _TracebackLogger: @@ -58,7 +59,7 @@ class itself, but instead to have a reference to a helper object the Future is collected, and the helper is present, the helper object is also collected, and its __del__() method will log the traceback. When the Future's result() or exception() method is - called (and a helper object is present), it removes the the helper + called (and a helper object is present), it removes the helper object, after calling its clear() method to prevent it from logging. @@ -80,9 +81,11 @@ class itself, but instead to have a reference to a helper object in a discussion about closing files when they are collected. """ - __slots__ = ['exc', 'tb'] + __slots__ = ('loop', 'source_traceback', 'exc', 'tb') - def __init__(self, exc): + def __init__(self, future, exc): + self.loop = future._loop + self.source_traceback = future._source_traceback self.exc = exc self.tb = None @@ -99,8 +102,13 @@ def clear(self): def __del__(self): if self.tb: - logger.error('Future/Task exception was never retrieved:\n%s', - ''.join(self.tb)) + msg = 'Future/Task exception was never retrieved\n' + if self.source_traceback: + src = ''.join(traceback.format_list(self.source_traceback)) + msg += 'Future/Task created at (most recent call last):\n' + msg += '%s\n' % src.rstrip() + msg += ''.join(self.tb).rstrip() + self.loop.call_exception_handler({'message': msg}) class Future: @@ -125,10 +133,12 @@ class Future: _result = None _exception = None _loop = None + _source_traceback = None _blocking = False # proper use of future (yield vs yield from) - _tb_logger = None + _log_traceback = False # Used for Python 3.4 and later + _tb_logger = None # Used for Python 3.3 only def __init__(self, *, loop=None): """Initialize the future. @@ -142,25 +152,68 @@ def __init__(self, *, loop=None): else: self._loop = loop self._callbacks = [] - - def __repr__(self): - res = self.__class__.__name__ + if self._loop.get_debug(): + self._source_traceback = traceback.extract_stack(sys._getframe(1)) + + def _format_callbacks(self): + cb = self._callbacks + size = len(cb) + if not size: + cb = '' + + def format_cb(callback): + return events._format_callback(callback, ()) + + if size == 1: + cb = format_cb(cb[0]) + elif size == 2: + cb = '{}, {}'.format(format_cb(cb[0]), format_cb(cb[1])) + elif size > 2: + cb = '{}, <{} more>, {}'.format(format_cb(cb[0]), + size-2, + format_cb(cb[-1])) + return 'cb=[%s]' % cb + + def _repr_info(self): + info = [self._state.lower()] if self._state == _FINISHED: if self._exception is not None: - res += '<exception={!r}>'.format(self._exception) + info.append('exception={!r}'.format(self._exception)) else: - res += '<result={!r}>'.format(self._result) - elif self._callbacks: - size = len(self._callbacks) - if size > 2: - res += '<{}, [{}, <{} more>, {}]>'.format( - self._state, self._callbacks[0], - size-2, self._callbacks[-1]) - else: - res += '<{}, {}>'.format(self._state, self._callbacks) - else: - res += '<{}>'.format(self._state) - return res + # use reprlib to limit the length of the output, especially + # for very long strings + result = reprlib.repr(self._result) + info.append('result={}'.format(result)) + if self._callbacks: + info.append(self._format_callbacks()) + if self._source_traceback: + frame = self._source_traceback[-1] + info.append('created at %s:%s' % (frame[0], frame[1])) + return info + + def __repr__(self): + info = self._repr_info() + return '<%s %s>' % (self.__class__.__name__, ' '.join(info)) + + # On Python 3.3 and older, objects with a destructor part of a reference + # cycle are never destroyed. It's not more the case on Python 3.4 thanks + # to the PEP 442. + if _PY34: + def __del__(self): + if not self._log_traceback: + # set_exception() was not called, or result() or exception() + # has consumed the exception + return + exc = self._exception + context = { + 'message': ('%s exception was never retrieved' + % self.__class__.__name__), + 'exception': exc, + 'future': self, + } + if self._source_traceback: + context['source_traceback'] = self._source_traceback + self._loop.call_exception_handler(context) def cancel(self): """Cancel the future and schedule callbacks. @@ -214,6 +267,7 @@ def result(self): raise CancelledError if self._state != _FINISHED: raise InvalidStateError('Result is not ready.') + self._log_traceback = False if self._tb_logger is not None: self._tb_logger.clear() self._tb_logger = None @@ -233,6 +287,7 @@ def exception(self): raise CancelledError if self._state != _FINISHED: raise InvalidStateError('Exception is not set.') + self._log_traceback = False if self._tb_logger is not None: self._tb_logger.clear() self._tb_logger = None @@ -265,6 +320,12 @@ def remove_done_callback(self, fn): # So-called internal methods (note: no set_running_or_notify_cancel()). + def _set_result_unless_cancelled(self, result): + """Helper setting the result only if the future was not cancelled.""" + if self.cancelled(): + return + self.set_result(result) + def set_result(self, result): """Mark the future done and set its result. @@ -285,13 +346,18 @@ def set_exception(self, exception): """ if self._state != _PENDING: raise InvalidStateError('{}: {!r}'.format(self._state, self)) + if isinstance(exception, type): + exception = exception() self._exception = exception - self._tb_logger = _TracebackLogger(exception) self._state = _FINISHED self._schedule_callbacks() - # Arrange for the logger to be activated after all callbacks - # have had a chance to call result() or exception(). - self._loop.call_soon(self._tb_logger.activate) + if _PY34: + self._log_traceback = True + else: + self._tb_logger = _TracebackLogger(self, exception) + # Arrange for the logger to be activated after all callbacks + # have had a chance to call result() or exception(). + self._loop.call_soon(self._tb_logger.activate) # Truly internal methods. @@ -339,5 +405,5 @@ def _check_cancel_other(f): new_future.add_done_callback(_check_cancel_other) fut.add_done_callback( lambda future: loop.call_soon_threadsafe( - new_future._copy_state, fut)) + new_future._copy_state, future)) return new_future diff --git a/Lib/asyncio/locks.py b/Lib/asyncio/locks.py index 6cd6779e48f4..b943e9dd4f97 100644 --- a/Lib/asyncio/locks.py +++ b/Lib/asyncio/locks.py @@ -6,7 +6,37 @@ from . import events from . import futures -from . import tasks +from .coroutines import coroutine + + +class _ContextManager: + """Context manager. + + This enables the following idiom for acquiring and releasing a + lock around a block: + + with (yield from lock): + <block> + + while failing loudly when accidentally using: + + with lock: + <block> + """ + + def __init__(self, lock): + self._lock = lock + + def __enter__(self): + # We have no use for the "as ..." clause in the with + # statement for locks. + return None + + def __exit__(self, *args): + try: + self._lock.release() + finally: + self._lock = None # Crudely prevent reuse. class Lock: @@ -33,7 +63,7 @@ class Lock: acquire() is a coroutine and should be called with 'yield from'. - Locks also support the context manager protocol. '(yield from lock)' + Locks also support the context management protocol. '(yield from lock)' should be used as context manager expression. Usage: @@ -82,7 +112,7 @@ def locked(self): """Return True if lock is acquired.""" return self._locked - @tasks.coroutine + @coroutine def acquire(self): """Acquire a lock. @@ -124,21 +154,33 @@ def release(self): raise RuntimeError('Lock is not acquired.') def __enter__(self): - if not self._locked: - raise RuntimeError( - '"yield from" should be used as context manager expression') - return True + raise RuntimeError( + '"yield from" should be used as context manager expression') def __exit__(self, *args): - self.release() + # This must exist because __enter__ exists, even though that + # always raises; that's how the with-statement works. + pass def __iter__(self): + # This is not a coroutine. It is meant to enable the idiom: + # + # with (yield from lock): + # <block> + # + # as an alternative to: + # + # yield from lock.acquire() + # try: + # <block> + # finally: + # lock.release() yield from self.acquire() - return self + return _ContextManager(self) class Event: - """An Event implementation, asynchronous equivalent to threading.Event. + """Asynchronous equivalent to threading.Event. Class implementing event objects. An event manages a flag that can be set to true with the set() method and reset to false with the clear() method. @@ -183,7 +225,7 @@ def clear(self): to true again.""" self._value = False - @tasks.coroutine + @coroutine def wait(self): """Block until the internal flag is true. @@ -204,7 +246,7 @@ def wait(self): class Condition: - """A Condition implementation, asynchronous equivalent to threading.Condition. + """Asynchronous equivalent to threading.Condition. This class implements condition variable objects. A condition variable allows one or more coroutines to wait until they are notified by another @@ -213,14 +255,17 @@ class Condition: A new Lock object is created and used as the underlying lock. """ - def __init__(self, *, loop=None): + def __init__(self, lock=None, *, loop=None): if loop is not None: self._loop = loop else: self._loop = events.get_event_loop() - # Lock as an attribute as in threading.Condition. - lock = Lock(loop=self._loop) + if lock is None: + lock = Lock(loop=self._loop) + elif lock._loop is not self._loop: + raise ValueError("loop argument must agree with lock") + self._lock = lock # Export the lock's locked(), acquire() and release() methods. self.locked = lock.locked @@ -236,7 +281,7 @@ def __repr__(self): extra = '{},waiters:{}'.format(extra, len(self._waiters)) return '<{} [{}]>'.format(res[1:-1], extra) - @tasks.coroutine + @coroutine def wait(self): """Wait until notified. @@ -251,7 +296,6 @@ def wait(self): if not self.locked(): raise RuntimeError('cannot wait on un-acquired lock') - keep_lock = True self.release() try: fut = futures.Future(loop=self._loop) @@ -262,14 +306,10 @@ def wait(self): finally: self._waiters.remove(fut) - except GeneratorExit: - keep_lock = False # Prevent yield in finally clause. - raise finally: - if keep_lock: - yield from self.acquire() + yield from self.acquire() - @tasks.coroutine + @coroutine def wait_for(self, predicate): """Wait until a predicate becomes true. @@ -316,14 +356,16 @@ def notify_all(self): self.notify(len(self._waiters)) def __enter__(self): - return self._lock.__enter__() + raise RuntimeError( + '"yield from" should be used as context manager expression') def __exit__(self, *args): - return self._lock.__exit__(*args) + pass def __iter__(self): + # See comment in Lock.__iter__(). yield from self.acquire() - return self + return _ContextManager(self) class Semaphore: @@ -334,7 +376,7 @@ class Semaphore: can never go below zero; when acquire() finds that it is zero, it blocks, waiting until some other thread calls release(). - Semaphores also support the context manager protocol. + Semaphores also support the context management protocol. The optional argument gives the initial value for the internal counter; it defaults to 1. If the value given is less than 0, @@ -346,7 +388,6 @@ def __init__(self, value=1, *, loop=None): raise ValueError("Semaphore initial value must be >= 0") self._value = value self._waiters = collections.deque() - self._locked = (value == 0) if loop is not None: self._loop = loop else: @@ -354,7 +395,7 @@ def __init__(self, value=1, *, loop=None): def __repr__(self): res = super().__repr__() - extra = 'locked' if self._locked else 'unlocked,value:{}'.format( + extra = 'locked' if self.locked() else 'unlocked,value:{}'.format( self._value) if self._waiters: extra = '{},waiters:{}'.format(extra, len(self._waiters)) @@ -362,9 +403,9 @@ def __repr__(self): def locked(self): """Returns True if semaphore can not be acquired immediately.""" - return self._locked + return self._value == 0 - @tasks.coroutine + @coroutine def acquire(self): """Acquire a semaphore. @@ -376,8 +417,6 @@ def acquire(self): """ if not self._waiters and self._value > 0: self._value -= 1 - if self._value == 0: - self._locked = True return True fut = futures.Future(loop=self._loop) @@ -385,8 +424,6 @@ def acquire(self): try: yield from fut self._value -= 1 - if self._value == 0: - self._locked = True return True finally: self._waiters.remove(fut) @@ -397,23 +434,22 @@ def release(self): become larger than zero again, wake up that coroutine. """ self._value += 1 - self._locked = False for waiter in self._waiters: if not waiter.done(): waiter.set_result(True) break def __enter__(self): - # TODO: This is questionable. How do we know the user actually - # wrote "with (yield from sema)" instead of "with sema"? - return True + raise RuntimeError( + '"yield from" should be used as context manager expression') def __exit__(self, *args): - self.release() + pass def __iter__(self): + # See comment in Lock.__iter__(). yield from self.acquire() - return self + return _ContextManager(self) class BoundedSemaphore(Semaphore): diff --git a/Lib/asyncio/proactor_events.py b/Lib/asyncio/proactor_events.py index ce226b9ba50d..9c2b8f155a73 100644 --- a/Lib/asyncio/proactor_events.py +++ b/Lib/asyncio/proactor_events.py @@ -4,37 +4,63 @@ proactor is only implemented on Windows with IOCP. """ +__all__ = ['BaseProactorEventLoop'] + import socket +import sys +import warnings from . import base_events from . import constants from . import futures +from . import sslproto from . import transports from .log import logger -class _ProactorBasePipeTransport(transports.BaseTransport): +class _ProactorBasePipeTransport(transports._FlowControlMixin, + transports.BaseTransport): """Base class for pipe and socket transports.""" def __init__(self, loop, sock, protocol, waiter=None, extra=None, server=None): - super().__init__(extra) + super().__init__(extra, loop) self._set_extra(sock) - self._loop = loop self._sock = sock self._protocol = protocol self._server = server - self._buffer = [] + self._buffer = None # None or bytearray. self._read_fut = None self._write_fut = None + self._pending_write = 0 self._conn_lost = 0 self._closing = False # Set when close() called. self._eof_written = False if self._server is not None: - self._server.attach(self) + self._server._attach() self._loop.call_soon(self._protocol.connection_made, self) if waiter is not None: - self._loop.call_soon(waiter.set_result, None) + # only wake up the waiter when connection_made() has been called + self._loop.call_soon(waiter._set_result_unless_cancelled, None) + + def __repr__(self): + info = [self.__class__.__name__] + if self._sock is None: + info.append('closed') + elif self._closing: + info.append('closing') + if self._sock is not None: + info.append('fd=%s' % self._sock.fileno()) + if self._read_fut is not None: + info.append('read=%s' % self._read_fut) + if self._write_fut is not None: + info.append("write=%r" % self._write_fut) + if self._buffer: + bufsize = len(self._buffer) + info.append('write_bufsize=%s' % bufsize) + if self._eof_written: + info.append('EOF written') + return '<%s>' % ' '.join(info) def _set_extra(self, sock): self._extra['pipe'] = sock @@ -48,9 +74,28 @@ def close(self): self._loop.call_soon(self._call_connection_lost, None) if self._read_fut is not None: self._read_fut.cancel() - - def _fatal_error(self, exc): - logger.exception('Fatal error for %s', self) + self._read_fut = None + + # On Python 3.3 and older, objects with a destructor part of a reference + # cycle are never destroyed. It's not more the case on Python 3.4 thanks + # to the PEP 442. + if sys.version_info >= (3, 4): + def __del__(self): + if self._sock is not None: + warnings.warn("unclosed transport %r" % self, ResourceWarning) + self.close() + + def _fatal_error(self, exc, message='Fatal error on pipe transport'): + if isinstance(exc, (BrokenPipeError, ConnectionResetError)): + if self._loop.get_debug(): + logger.debug("%r: %s", self, message, exc_info=True) + else: + self._loop.call_exception_handler({ + 'message': message, + 'exception': exc, + 'transport': self, + 'protocol': self._protocol, + }) self._force_close(exc) def _force_close(self, exc): @@ -60,10 +105,12 @@ def _force_close(self, exc): self._conn_lost += 1 if self._write_fut: self._write_fut.cancel() + self._write_fut = None if self._read_fut: self._read_fut.cancel() - self._write_fut = self._read_fut = None - self._buffer = [] + self._read_fut = None + self._pending_write = 0 + self._buffer = None self._loop.call_soon(self._call_connection_lost, exc) def _call_connection_lost(self, exc): @@ -77,11 +124,18 @@ def _call_connection_lost(self, exc): if hasattr(self._sock, 'shutdown'): self._sock.shutdown(socket.SHUT_RDWR) self._sock.close() + self._sock = None server = self._server if server is not None: - server.detach(self) + server._detach() self._server = None + def get_write_buffer_size(self): + size = self._pending_write + if self._buffer is not None: + size += len(self._buffer) + return size + class _ProactorReadPipeTransport(_ProactorBasePipeTransport, transports.ReadTransport): @@ -90,21 +144,27 @@ class _ProactorReadPipeTransport(_ProactorBasePipeTransport, def __init__(self, loop, sock, protocol, waiter=None, extra=None, server=None): super().__init__(loop, sock, protocol, waiter, extra, server) - self._read_fut = None self._paused = False self._loop.call_soon(self._loop_reading) def pause_reading(self): - assert not self._closing, 'Cannot pause_reading() when closing' - assert not self._paused, 'Already paused' + if self._closing: + raise RuntimeError('Cannot pause_reading() when closing') + if self._paused: + raise RuntimeError('Already paused') self._paused = True + if self._loop.get_debug(): + logger.debug("%r pauses reading", self) def resume_reading(self): - assert self._paused, 'Not paused' + if not self._paused: + raise RuntimeError('Not paused') self._paused = False if self._closing: return self._loop.call_soon(self._loop_reading, self._read_fut) + if self._loop.get_debug(): + logger.debug("%r resumes reading", self) def _loop_reading(self, fut=None): if self._paused: @@ -131,11 +191,14 @@ def _loop_reading(self, fut=None): self._read_fut = self._loop._proactor.recv(self._sock, 4096) except ConnectionAbortedError as exc: if not self._closing: - self._fatal_error(exc) + self._fatal_error(exc, 'Fatal read error on pipe transport') + elif self._loop.get_debug(): + logger.debug("Read error on pipe transport while closing", + exc_info=True) except ConnectionResetError as exc: self._force_close(exc) except OSError as exc: - self._fatal_error(exc) + self._fatal_error(exc, 'Fatal read error on pipe transport') except futures.CancelledError: if not self._closing: raise @@ -145,19 +208,23 @@ def _loop_reading(self, fut=None): if data: self._protocol.data_received(data) elif data is not None: + if self._loop.get_debug(): + logger.debug("%r received EOF", self) keep_open = self._protocol.eof_received() if not keep_open: self.close() -class _ProactorWritePipeTransport(_ProactorBasePipeTransport, - transports.WriteTransport): +class _ProactorBaseWritePipeTransport(_ProactorBasePipeTransport, + transports.WriteTransport): """Transport for write pipes.""" def write(self, data): - assert isinstance(data, bytes), repr(data) + if not isinstance(data, (bytes, bytearray, memoryview)): + raise TypeError('data argument must be byte-ish (%r)', + type(data)) if self._eof_written: - raise IOError('write_eof() already called') + raise RuntimeError('write_eof() already called') if not data: return @@ -167,30 +234,60 @@ def write(self, data): logger.warning('socket.send() raised exception.') self._conn_lost += 1 return - self._buffer.append(data) - if self._write_fut is None: - self._loop_writing() - def _loop_writing(self, f=None): + # Observable states: + # 1. IDLE: _write_fut and _buffer both None + # 2. WRITING: _write_fut set; _buffer None + # 3. BACKED UP: _write_fut set; _buffer a bytearray + # We always copy the data, so the caller can't modify it + # while we're still waiting for the I/O to happen. + if self._write_fut is None: # IDLE -> WRITING + assert self._buffer is None + # Pass a copy, except if it's already immutable. + self._loop_writing(data=bytes(data)) + elif not self._buffer: # WRITING -> BACKED UP + # Make a mutable copy which we can extend. + self._buffer = bytearray(data) + self._maybe_pause_protocol() + else: # BACKED UP + # Append to buffer (also copies). + self._buffer.extend(data) + self._maybe_pause_protocol() + + def _loop_writing(self, f=None, data=None): try: assert f is self._write_fut self._write_fut = None + self._pending_write = 0 if f: f.result() - data = b''.join(self._buffer) - self._buffer = [] + if data is None: + data = self._buffer + self._buffer = None if not data: if self._closing: self._loop.call_soon(self._call_connection_lost, None) if self._eof_written: self._sock.shutdown(socket.SHUT_WR) - return - self._write_fut = self._loop._proactor.send(self._sock, data) - self._write_fut.add_done_callback(self._loop_writing) + # Now that we've reduced the buffer size, tell the + # protocol to resume writing if it was paused. Note that + # we do this last since the callback is called immediately + # and it may add more data to the buffer (even causing the + # protocol to be paused again). + self._maybe_resume_protocol() + else: + self._write_fut = self._loop._proactor.send(self._sock, data) + if not self._write_fut.done(): + assert self._pending_write == 0 + self._pending_write = len(data) + self._write_fut.add_done_callback(self._loop_writing) + self._maybe_pause_protocol() + else: + self._write_fut.add_done_callback(self._loop_writing) except ConnectionResetError as exc: self._force_close(exc) except OSError as exc: - self._fatal_error(exc) + self._fatal_error(exc, 'Fatal write error on pipe transport') def can_write_eof(self): return True @@ -202,8 +299,30 @@ def abort(self): self._force_close(None) +class _ProactorWritePipeTransport(_ProactorBaseWritePipeTransport): + def __init__(self, *args, **kw): + super().__init__(*args, **kw) + self._read_fut = self._loop._proactor.recv(self._sock, 16) + self._read_fut.add_done_callback(self._pipe_closed) + + def _pipe_closed(self, fut): + if fut.cancelled(): + # the transport has been closed + return + assert fut.result() == b'' + if self._closing: + assert self._read_fut is None + return + assert fut is self._read_fut, (fut, self._read_fut) + self._read_fut = None + if self._write_fut is not None: + self._force_close(BrokenPipeError()) + else: + self.close() + + class _ProactorDuplexPipeTransport(_ProactorReadPipeTransport, - _ProactorWritePipeTransport, + _ProactorBaseWritePipeTransport, transports.Transport): """Transport for duplex pipes.""" @@ -215,7 +334,7 @@ def write_eof(self): class _ProactorSocketTransport(_ProactorReadPipeTransport, - _ProactorWritePipeTransport, + _ProactorBaseWritePipeTransport, transports.Transport): """Transport for connected sockets.""" @@ -224,12 +343,16 @@ def _set_extra(self, sock): try: self._extra['sockname'] = sock.getsockname() except (socket.error, AttributeError): - pass + if self._loop.get_debug(): + logger.warning("getsockname() failed on %r", + sock, exc_info=True) if 'peername' not in self._extra: try: self._extra['peername'] = sock.getpeername() except (socket.error, AttributeError): - pass + if self._loop.get_debug(): + logger.warning("getpeername() failed on %r", + sock, exc_info=True) def can_write_eof(self): return True @@ -249,6 +372,8 @@ def __init__(self, proactor): logger.debug('Using proactor: %s', proactor.__class__.__name__) self._proactor = proactor self._selector = proactor # convenient alias + self._self_reading_future = None + self._accept_futures = {} # socket file descriptor => Future proactor.set_loop(self) self._make_self_pipe() @@ -257,6 +382,20 @@ def _make_socket_transport(self, sock, protocol, waiter=None, return _ProactorSocketTransport(self, sock, protocol, waiter, extra, server) + def _make_ssl_transport(self, rawsock, protocol, sslcontext, waiter=None, + *, server_side=False, server_hostname=None, + extra=None, server=None): + if not sslproto._is_sslproto_available(): + raise NotImplementedError("Proactor event loop requires Python 3.5" + " or newer (ssl.MemoryBIO) to support " + "SSL") + + ssl_protocol = sslproto.SSLProtocol(self, protocol, sslcontext, waiter, + server_side, server_hostname) + _ProactorSocketTransport(self, rawsock, ssl_protocol, + extra=extra, server=server) + return ssl_protocol._app_transport + def _make_duplex_pipe_transport(self, sock, protocol, waiter=None, extra=None): return _ProactorDuplexPipeTransport(self, @@ -267,23 +406,28 @@ def _make_read_pipe_transport(self, sock, protocol, waiter=None, return _ProactorReadPipeTransport(self, sock, protocol, waiter, extra) def _make_write_pipe_transport(self, sock, protocol, waiter=None, - extra=None, check_for_hangup=True): - if check_for_hangup: - # We want connection_lost() to be called when other end closes - return _ProactorDuplexPipeTransport(self, - sock, protocol, waiter, extra) - else: - # If other end closes we may not notice for a long time - return _ProactorWritePipeTransport(self, sock, protocol, waiter, - extra) + extra=None): + # We want connection_lost() to be called when other end closes + return _ProactorWritePipeTransport(self, + sock, protocol, waiter, extra) def close(self): - if self._proactor is not None: - self._close_self_pipe() - self._proactor.close() - self._proactor = None - self._selector = None - super().close() + if self.is_running(): + raise RuntimeError("Cannot close a running event loop") + if self.is_closed(): + return + + # Call these methods before closing the event loop (before calling + # BaseEventLoop.close), because they can schedule callbacks with + # call_soon(), which is forbidden when the event loop is closed. + self._stop_accept_futures() + self._close_self_pipe() + self._proactor.close() + self._proactor = None + self._selector = None + + # Close the event loop + super().close() def sock_recv(self, sock, n): return self._proactor.recv(sock, n) @@ -292,7 +436,15 @@ def sock_sendall(self, sock, data): return self._proactor.send(sock, data) def sock_connect(self, sock, address): - return self._proactor.connect(sock, address) + try: + if self._debug: + base_events._check_resolved_address(sock, address) + except ValueError as err: + fut = futures.Future(loop=self) + fut.set_exception(err) + return fut + else: + return self._proactor.connect(sock, address) def sock_accept(self, sock): return self._proactor.accept(sock) @@ -301,6 +453,9 @@ def _socketpair(self): raise NotImplementedError def _close_self_pipe(self): + if self._self_reading_future is not None: + self._self_reading_future.cancel() + self._self_reading_future = None self._ssock.close() self._ssock = None self._csock.close() @@ -320,41 +475,73 @@ def _loop_self_reading(self, f=None): if f is not None: f.result() # may raise f = self._proactor.recv(self._ssock, 4096) - except: - self.close() - raise + except futures.CancelledError: + # _close_self_pipe() has been called, stop waiting for data + return + except Exception as exc: + self.call_exception_handler({ + 'message': 'Error on reading from the event loop self pipe', + 'exception': exc, + 'loop': self, + }) else: + self._self_reading_future = f f.add_done_callback(self._loop_self_reading) def _write_to_self(self): - self._csock.send(b'x') + self._csock.send(b'\0') - def _start_serving(self, protocol_factory, sock, ssl=None, server=None): - assert not ssl, 'IocpEventLoop is incompatible with SSL.' + def _start_serving(self, protocol_factory, sock, + sslcontext=None, server=None): def loop(f=None): try: if f is not None: conn, addr = f.result() + if self._debug: + logger.debug("%r got a new connection from %r: %r", + server, addr, conn) protocol = protocol_factory() - self._make_socket_transport( - conn, protocol, - extra={'peername': addr}, server=server) + if sslcontext is not None: + self._make_ssl_transport( + conn, protocol, sslcontext, server_side=True, + extra={'peername': addr}, server=server) + else: + self._make_socket_transport( + conn, protocol, + extra={'peername': addr}, server=server) + if self.is_closed(): + return f = self._proactor.accept(sock) - except OSError: + except OSError as exc: if sock.fileno() != -1: - logger.exception('Accept failed') + self.call_exception_handler({ + 'message': 'Accept failed on a socket', + 'exception': exc, + 'socket': sock, + }) sock.close() + elif self._debug: + logger.debug("Accept failed on socket %r", + sock, exc_info=True) except futures.CancelledError: sock.close() else: + self._accept_futures[sock.fileno()] = f f.add_done_callback(loop) self.call_soon(loop) def _process_events(self, event_list): - pass # XXX hard work currently done in poll + # Events are processed in the IocpProactor._poll() method + pass + + def _stop_accept_futures(self): + for future in self._accept_futures.values(): + future.cancel() + self._accept_futures.clear() def _stop_serving(self, sock): + self._stop_accept_futures() self._proactor._stop_serving(sock) sock.close() diff --git a/Lib/asyncio/protocols.py b/Lib/asyncio/protocols.py index 1b8870c6d551..80fcac9a82df 100644 --- a/Lib/asyncio/protocols.py +++ b/Lib/asyncio/protocols.py @@ -1,6 +1,7 @@ """Abstract Protocol class.""" -__all__ = ['Protocol', 'DatagramProtocol'] +__all__ = ['BaseProtocol', 'Protocol', 'DatagramProtocol', + 'SubprocessProtocol'] class BaseProtocol: @@ -77,6 +78,11 @@ class Protocol(BaseProtocol): State machine of calls: start -> CM [-> DR*] [-> ER?] -> CL -> end + + * CM: connection_made() + * DR: data_received() + * ER: eof_received() + * CL: connection_lost() """ def data_received(self, data): @@ -113,7 +119,7 @@ class SubprocessProtocol(BaseProtocol): def pipe_data_received(self, fd, data): """Called when the subprocess writes data into stdout/stderr pipe. - fd is int file dascriptor. + fd is int file descriptor. data is bytes object. """ diff --git a/Lib/asyncio/queues.py b/Lib/asyncio/queues.py index 3f5bf4479e60..84cdabcf54fb 100644 --- a/Lib/asyncio/queues.py +++ b/Lib/asyncio/queues.py @@ -1,11 +1,10 @@ """Queues""" -__all__ = ['Queue', 'PriorityQueue', 'LifoQueue', 'JoinableQueue', - 'Full', 'Empty'] +__all__ = ['Queue', 'PriorityQueue', 'LifoQueue', 'QueueFull', 'QueueEmpty', + 'JoinableQueue'] import collections import heapq -import queue from . import events from . import futures @@ -13,9 +12,18 @@ from .tasks import coroutine -# Re-export queue.Full and .Empty exceptions. -Full = queue.Full -Empty = queue.Empty +class QueueEmpty(Exception): + """Exception raised when Queue.get_nowait() is called on a Queue object + which is empty. + """ + pass + + +class QueueFull(Exception): + """Exception raised when the Queue.put_nowait() method is called on a Queue + object which is full. + """ + pass class Queue: @@ -26,7 +34,7 @@ class Queue: queue reaches maxsize, until an item is removed by get(). Unlike the standard library Queue, you can reliably know this Queue's size - with qsize(), since your single-threaded Tulip application won't be + with qsize(), since your single-threaded asyncio application won't be interrupted between calling qsize() and doing an operation on the Queue. """ @@ -41,6 +49,9 @@ def __init__(self, maxsize=0, *, loop=None): self._getters = collections.deque() # Pairs of (item, Future). self._putters = collections.deque() + self._unfinished_tasks = 0 + self._finished = locks.Event(loop=self._loop) + self._finished.set() self._init(maxsize) def _init(self, maxsize): @@ -51,6 +62,8 @@ def _get(self): def _put(self, item): self._queue.append(item) + self._unfinished_tasks += 1 + self._finished.clear() def __repr__(self): return '<{} at {:#x} {}>'.format( @@ -67,6 +80,8 @@ def _format(self): result += ' _getters[{}]'.format(len(self._getters)) if self._putters: result += ' _putters[{}]'.format(len(self._putters)) + if self._unfinished_tasks: + result += ' tasks={}'.format(self._unfinished_tasks) return result def _consume_done_getters(self): @@ -101,14 +116,16 @@ def full(self): if self._maxsize <= 0: return False else: - return self.qsize() == self._maxsize + return self.qsize() >= self._maxsize @coroutine def put(self, item): """Put an item into the queue. - If you yield from put(), wait until a free slot is available - before adding item. + Put an item into the queue. If the queue is full, wait until a free + slot is available before adding item. + + This method is a coroutine. """ self._consume_done_getters() if self._getters: @@ -116,13 +133,12 @@ def put(self, item): 'queue non-empty, why are getters waiting?') getter = self._getters.popleft() - - # Use _put and _get instead of passing item straight to getter, in - # case a subclass has logic that must run (e.g. JoinableQueue). self._put(item) + + # getter cannot be cancelled, we just removed done getters getter.set_result(self._get()) - elif self._maxsize > 0 and self._maxsize == self.qsize(): + elif self._maxsize > 0 and self._maxsize <= self.qsize(): waiter = futures.Future(loop=self._loop) self._putters.append((item, waiter)) @@ -134,7 +150,7 @@ def put(self, item): def put_nowait(self, item): """Put an item into the queue without blocking. - If no free slot is immediately available, raise Full. + If no free slot is immediately available, raise QueueFull. """ self._consume_done_getters() if self._getters: @@ -142,14 +158,13 @@ def put_nowait(self, item): 'queue non-empty, why are getters waiting?') getter = self._getters.popleft() - - # Use _put and _get instead of passing item straight to getter, in - # case a subclass has logic that must run (e.g. JoinableQueue). self._put(item) + + # getter cannot be cancelled, we just removed done getters getter.set_result(self._get()) - elif self._maxsize > 0 and self._maxsize == self.qsize(): - raise Full + elif self._maxsize > 0 and self._maxsize <= self.qsize(): + raise QueueFull else: self._put(item) @@ -157,7 +172,9 @@ def put_nowait(self, item): def get(self): """Remove and return an item from the queue. - If you yield from get(), wait until a item is available. + If queue is empty, wait until an item is available. + + This method is a coroutine. """ self._consume_done_putters() if self._putters: @@ -169,7 +186,7 @@ def get(self): # run, we need to defer the put for a tick to ensure that # getters and putters alternate perfectly. See # ChannelTest.test_wait. - self._loop.call_soon(putter.set_result, None) + self._loop.call_soon(putter._set_result_unless_cancelled, None) return self._get() @@ -184,7 +201,7 @@ def get(self): def get_nowait(self): """Remove and return an item from the queue. - Return an item if one is immediately available, else raise Empty. + Return an item if one is immediately available, else raise QueueEmpty. """ self._consume_done_putters() if self._putters: @@ -192,6 +209,8 @@ def get_nowait(self): item, putter = self._putters.popleft() self._put(item) # Wake putter on next tick. + + # getter cannot be cancelled, we just removed done putters putter.set_result(None) return self._get() @@ -199,7 +218,39 @@ def get_nowait(self): elif self.qsize(): return self._get() else: - raise Empty + raise QueueEmpty + + def task_done(self): + """Indicate that a formerly enqueued task is complete. + + Used by queue consumers. For each get() used to fetch a task, + a subsequent call to task_done() tells the queue that the processing + on the task is complete. + + If a join() is currently blocking, it will resume when all items have + been processed (meaning that a task_done() call was received for every + item that had been put() into the queue). + + Raises ValueError if called more times than there were items placed in + the queue. + """ + if self._unfinished_tasks <= 0: + raise ValueError('task_done() called too many times') + self._unfinished_tasks -= 1 + if self._unfinished_tasks == 0: + self._finished.set() + + @coroutine + def join(self): + """Block until all items in the queue have been gotten and processed. + + The count of unfinished tasks goes up whenever an item is added to the + queue. The count goes down whenever a consumer calls task_done() to + indicate that the item was retrieved and all work on it is complete. + When the count of unfinished tasks drops to zero, join() unblocks. + """ + if self._unfinished_tasks > 0: + yield from self._finished.wait() class PriorityQueue(Queue): @@ -231,54 +282,5 @@ def _get(self): return self._queue.pop() -class JoinableQueue(Queue): - """A subclass of Queue with task_done() and join() methods.""" - - def __init__(self, maxsize=0, *, loop=None): - super().__init__(maxsize=maxsize, loop=loop) - self._unfinished_tasks = 0 - self._finished = locks.Event(loop=self._loop) - self._finished.set() - - def _format(self): - result = Queue._format(self) - if self._unfinished_tasks: - result += ' tasks={}'.format(self._unfinished_tasks) - return result - - def _put(self, item): - super()._put(item) - self._unfinished_tasks += 1 - self._finished.clear() - - def task_done(self): - """Indicate that a formerly enqueued task is complete. - - Used by queue consumers. For each get() used to fetch a task, - a subsequent call to task_done() tells the queue that the processing - on the task is complete. - - If a join() is currently blocking, it will resume when all items have - been processed (meaning that a task_done() call was received for every - item that had been put() into the queue). - - Raises ValueError if called more times than there were items placed in - the queue. - """ - if self._unfinished_tasks <= 0: - raise ValueError('task_done() called too many times') - self._unfinished_tasks -= 1 - if self._unfinished_tasks == 0: - self._finished.set() - - @coroutine - def join(self): - """Block until all items in the queue have been gotten and processed. - - The count of unfinished tasks goes up whenever an item is added to the - queue. The count goes down whenever a consumer thread calls task_done() - to indicate that the item was retrieved and all work on it is complete. - When the count of unfinished tasks drops to zero, join() unblocks. - """ - if self._unfinished_tasks > 0: - yield from self._finished.wait() +JoinableQueue = Queue +"""Deprecated alias for Queue.""" diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py index 93efddc95a39..a38ed1cee3ba 100644 --- a/Lib/asyncio/selector_events.py +++ b/Lib/asyncio/selector_events.py @@ -4,9 +4,14 @@ also includes support for signal handling, see the unix_events sub-module. """ +__all__ = ['BaseSelectorEventLoop'] + import collections import errno +import functools import socket +import sys +import warnings try: import ssl except ImportError: # pragma: no cover @@ -18,9 +23,22 @@ from . import futures from . import selectors from . import transports +from . import sslproto +from .coroutines import coroutine from .log import logger +def _test_selector_event(selector, fd, event): + # Test if the selector is monitoring 'event' events + # for the file descriptor 'fd'. + try: + key = selector.get_key(fd) + except KeyError: + return False + else: + return bool(key.events & event) + + class BaseSelectorEventLoop(base_events.BaseEventLoop): """Selector event loop. @@ -41,23 +59,46 @@ def _make_socket_transport(self, sock, protocol, waiter=None, *, return _SelectorSocketTransport(self, sock, protocol, waiter, extra, server) - def _make_ssl_transport(self, rawsock, protocol, sslcontext, waiter, *, - server_side=False, server_hostname=None, + def _make_ssl_transport(self, rawsock, protocol, sslcontext, waiter=None, + *, server_side=False, server_hostname=None, extra=None, server=None): + if not sslproto._is_sslproto_available(): + return self._make_legacy_ssl_transport( + rawsock, protocol, sslcontext, waiter, + server_side=server_side, server_hostname=server_hostname, + extra=extra, server=server) + + ssl_protocol = sslproto.SSLProtocol(self, protocol, sslcontext, waiter, + server_side, server_hostname) + _SelectorSocketTransport(self, rawsock, ssl_protocol, + extra=extra, server=server) + return ssl_protocol._app_transport + + def _make_legacy_ssl_transport(self, rawsock, protocol, sslcontext, + waiter, *, + server_side=False, server_hostname=None, + extra=None, server=None): + # Use the legacy API: SSL_write, SSL_read, etc. The legacy API is used + # on Python 3.4 and older, when ssl.MemoryBIO is not available. return _SelectorSslTransport( self, rawsock, protocol, sslcontext, waiter, server_side, server_hostname, extra, server) def _make_datagram_transport(self, sock, protocol, - address=None, extra=None): - return _SelectorDatagramTransport(self, sock, protocol, address, extra) + address=None, waiter=None, extra=None): + return _SelectorDatagramTransport(self, sock, protocol, + address, waiter, extra) def close(self): + if self.is_running(): + raise RuntimeError("Cannot close a running event loop") + if self.is_closed(): + return + self._close_self_pipe() + super().close() if self._selector is not None: - self._close_self_pipe() self._selector.close() self._selector = None - super().close() def _socketpair(self): raise NotImplementedError @@ -78,17 +119,36 @@ def _make_self_pipe(self): self._internal_fds += 1 self.add_reader(self._ssock.fileno(), self._read_from_self) + def _process_self_data(self, data): + pass + def _read_from_self(self): - try: - self._ssock.recv(1) - except (BlockingIOError, InterruptedError): - pass + while True: + try: + data = self._ssock.recv(4096) + if not data: + break + self._process_self_data(data) + except InterruptedError: + continue + except BlockingIOError: + break def _write_to_self(self): - try: - self._csock.send(b'x') - except (BlockingIOError, InterruptedError): - pass + # This may be called from a different thread, possibly after + # _close_self_pipe() has been called or even while it is + # running. Guard for self._csock being None or closed. When + # a socket is closed, send() raises OSError (with errno set to + # EBADF, but let's not rely on the exact error code). + csock = self._csock + if csock is not None: + try: + csock.send(b'\0') + except OSError: + if self._debug: + logger.debug("Fail to write a null byte into the " + "self-pipe socket", + exc_info=True) def _start_serving(self, protocol_factory, sock, sslcontext=None, server=None): @@ -99,18 +159,24 @@ def _accept_connection(self, protocol_factory, sock, sslcontext=None, server=None): try: conn, addr = sock.accept() + if self._debug: + logger.debug("%r got a new connection from %r: %r", + server, addr, conn) conn.setblocking(False) except (BlockingIOError, InterruptedError, ConnectionAbortedError): pass # False alarm. except OSError as exc: # There's nowhere to send the error, so just log it. - # TODO: Someone will want an error handler for this. if exc.errno in (errno.EMFILE, errno.ENFILE, errno.ENOBUFS, errno.ENOMEM): # Some platforms (e.g. Linux keep reporting the FD as # ready, so we remove the read handler temporarily. # We'll try again in a while. - logger.exception('Accept out of system resource (%s)', exc) + self.call_exception_handler({ + 'message': 'socket.accept() out of system resource', + 'exception': exc, + 'socket': sock, + }) self.remove_reader(sock.fileno()) self.call_later(constants.ACCEPT_RETRY_DELAY, self._start_serving, @@ -118,19 +184,52 @@ def _accept_connection(self, protocol_factory, sock, else: raise # The event loop will catch, log and ignore it. else: + extra = {'peername': addr} + accept = self._accept_connection2(protocol_factory, conn, extra, + sslcontext, server) + self.create_task(accept) + + @coroutine + def _accept_connection2(self, protocol_factory, conn, extra, + sslcontext=None, server=None): + protocol = None + transport = None + try: + protocol = protocol_factory() + waiter = futures.Future(loop=self) if sslcontext: - self._make_ssl_transport( - conn, protocol_factory(), sslcontext, None, - server_side=True, extra={'peername': addr}, server=server) + transport = self._make_ssl_transport( + conn, protocol, sslcontext, waiter=waiter, + server_side=True, extra=extra, server=server) else: - self._make_socket_transport( - conn, protocol_factory(), extra={'peername': addr}, + transport = self._make_socket_transport( + conn, protocol, waiter=waiter, extra=extra, server=server) - # It's now up to the protocol to handle the connection. + + try: + yield from waiter + except: + transport.close() + raise + + # It's now up to the protocol to handle the connection. + except Exception as exc: + if self._debug: + context = { + 'message': ('Error on transport creation ' + 'for incoming connection'), + 'exception': exc, + } + if protocol is not None: + context['protocol'] = protocol + if transport is not None: + context['transport'] = transport + self.call_exception_handler(context) def add_reader(self, fd, callback, *args): """Add a reader callback.""" - handle = events.make_handle(callback, args) + self._check_closed() + handle = events.Handle(callback, args, self) try: key = self._selector.get_key(fd) except KeyError: @@ -145,6 +244,8 @@ def add_reader(self, fd, callback, *args): def remove_reader(self, fd): """Remove a reader callback.""" + if self.is_closed(): + return False try: key = self._selector.get_key(fd) except KeyError: @@ -165,7 +266,8 @@ def remove_reader(self, fd): def add_writer(self, fd, callback, *args): """Add a writer callback..""" - handle = events.make_handle(callback, args) + self._check_closed() + handle = events.Handle(callback, args, self) try: key = self._selector.get_key(fd) except KeyError: @@ -180,6 +282,8 @@ def add_writer(self, fd, callback, *args): def remove_writer(self, fd): """Remove a writer callback.""" + if self.is_closed(): + return False try: key = self._selector.get_key(fd) except KeyError: @@ -200,12 +304,23 @@ def remove_writer(self, fd): return False def sock_recv(self, sock, n): - """XXX""" + """Receive data from the socket. + + The return value is a bytes object representing the data received. + The maximum amount of data to be received at once is specified by + nbytes. + + This method is a coroutine. + """ + if self._debug and sock.gettimeout() != 0: + raise ValueError("the socket must be non-blocking") fut = futures.Future(loop=self) self._sock_recv(fut, False, sock, n) return fut def _sock_recv(self, fut, registered, sock, n): + # _sock_recv() can add itself as an I/O callback if the operation can't + # be done immediately. Don't use it directly, call sock_recv(). fd = sock.fileno() if registered: # Remove the callback early. It should be rare that the @@ -225,7 +340,18 @@ def _sock_recv(self, fut, registered, sock, n): fut.set_result(data) def sock_sendall(self, sock, data): - """XXX""" + """Send data to the socket. + + The socket must be connected to a remote socket. This method continues + to send data from data until either all data has been sent or an + error occurs. None is returned on success. On error, an exception is + raised, and there is no way to determine how much data, if any, was + successfully processed by the receiving end of the connection. + + This method is a coroutine. + """ + if self._debug and sock.gettimeout() != 0: + raise ValueError("the socket must be non-blocking") fut = futures.Future(loop=self) if data: self._sock_sendall(fut, False, sock, data) @@ -257,46 +383,79 @@ def _sock_sendall(self, fut, registered, sock, data): self.add_writer(fd, self._sock_sendall, fut, True, sock, data) def sock_connect(self, sock, address): - """XXX""" - # That address better not require a lookup! We're not calling - # self.getaddrinfo() for you here. But verifying this is - # complicated; the socket module doesn't have a pattern for - # IPv6 addresses (there are too many forms, apparently). + """Connect to a remote socket at address. + + The address must be already resolved to avoid the trap of hanging the + entire event loop when the address requires doing a DNS lookup. For + example, it must be an IP address, not an hostname, for AF_INET and + AF_INET6 address families. Use getaddrinfo() to resolve the hostname + asynchronously. + + This method is a coroutine. + """ + if self._debug and sock.gettimeout() != 0: + raise ValueError("the socket must be non-blocking") fut = futures.Future(loop=self) - self._sock_connect(fut, False, sock, address) + try: + if self._debug: + base_events._check_resolved_address(sock, address) + except ValueError as err: + fut.set_exception(err) + else: + self._sock_connect(fut, sock, address) return fut - def _sock_connect(self, fut, registered, sock, address): - # TODO: Use getaddrinfo() to look up the address, to avoid the - # trap of hanging the entire event loop when the address - # requires doing a DNS lookup. (OTOH, the caller should - # already have done this, so it would be nice if we could - # easily tell whether the address needs looking up or not. I - # know how to do this for IPv4, but IPv6 addresses have many - # syntaxes.) + def _sock_connect(self, fut, sock, address): fd = sock.fileno() - if registered: - self.remove_writer(fd) + try: + while True: + try: + sock.connect(address) + except InterruptedError: + continue + else: + break + except BlockingIOError: + fut.add_done_callback(functools.partial(self._sock_connect_done, + fd)) + self.add_writer(fd, self._sock_connect_cb, fut, sock, address) + except Exception as exc: + fut.set_exception(exc) + else: + fut.set_result(None) + + def _sock_connect_done(self, fd, fut): + self.remove_writer(fd) + + def _sock_connect_cb(self, fut, sock, address): if fut.cancelled(): return + try: - if not registered: - # First time around. - sock.connect(address) - else: - err = sock.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR) - if err != 0: - # Jump to the except clause below. - raise OSError(err, 'Connect call failed %s' % (address,)) + err = sock.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR) + if err != 0: + # Jump to any except clause below. + raise OSError(err, 'Connect call failed %s' % (address,)) except (BlockingIOError, InterruptedError): - self.add_writer(fd, self._sock_connect, fut, True, sock, address) + # socket is still registered, the callback will be retried later + pass except Exception as exc: fut.set_exception(exc) else: fut.set_result(None) def sock_accept(self, sock): - """XXX""" + """Accept a connection. + + The socket must be bound to an address and listening for connections. + The return value is a pair (conn, address) where conn is a new socket + object usable to send and receive data on the connection, and address + is the address bound to the socket on the other end of the connection. + + This method is a coroutine. + """ + if self._debug and sock.gettimeout() != 0: + raise ValueError("the socket must be non-blocking") fut = futures.Future(loop=self) self._sock_accept(fut, False, sock) return fut @@ -336,14 +495,20 @@ def _stop_serving(self, sock): sock.close() -class _SelectorTransport(transports.Transport): +class _SelectorTransport(transports._FlowControlMixin, + transports.Transport): max_size = 256 * 1024 # Buffer size passed to recv(). _buffer_factory = bytearray # Constructs initial value for self._buffer. - def __init__(self, loop, sock, protocol, extra, server=None): - super().__init__(extra) + # Attribute used in the destructor: it must be set even if the constructor + # is not called (see _SelectorSslTransport which may start by raising an + # exception) + _sock = None + + def __init__(self, loop, sock, protocol, extra=None, server=None): + super().__init__(extra, loop) self._extra['socket'] = sock self._extra['sockname'] = sock.getsockname() if 'peername' not in self._extra: @@ -351,18 +516,44 @@ def __init__(self, loop, sock, protocol, extra, server=None): self._extra['peername'] = sock.getpeername() except socket.error: self._extra['peername'] = None - self._loop = loop self._sock = sock self._sock_fd = sock.fileno() self._protocol = protocol + self._protocol_connected = True self._server = server self._buffer = self._buffer_factory() self._conn_lost = 0 # Set when call to connection_lost scheduled. self._closing = False # Set when close() called. - self._protocol_paused = False - self.set_write_buffer_limits() if self._server is not None: - self._server.attach(self) + self._server._attach() + + def __repr__(self): + info = [self.__class__.__name__] + if self._sock is None: + info.append('closed') + elif self._closing: + info.append('closing') + info.append('fd=%s' % self._sock_fd) + # test if the transport was closed + if self._loop is not None: + polling = _test_selector_event(self._loop._selector, + self._sock_fd, selectors.EVENT_READ) + if polling: + info.append('read=polling') + else: + info.append('read=idle') + + polling = _test_selector_event(self._loop._selector, + self._sock_fd, + selectors.EVENT_WRITE) + if polling: + state = 'polling' + else: + state = 'idle' + + bufsize = self.get_write_buffer_size() + info.append('write=<%s, bufsize=%s>' % (state, bufsize)) + return '<%s>' % ' '.join(info) def abort(self): self._force_close(None) @@ -376,10 +567,28 @@ def close(self): self._conn_lost += 1 self._loop.call_soon(self._call_connection_lost, None) - def _fatal_error(self, exc): + # On Python 3.3 and older, objects with a destructor part of a reference + # cycle are never destroyed. It's not more the case on Python 3.4 thanks + # to the PEP 442. + if sys.version_info >= (3, 4): + def __del__(self): + if self._sock is not None: + warnings.warn("unclosed transport %r" % self, ResourceWarning) + self._sock.close() + + def _fatal_error(self, exc, message='Fatal error on transport'): # Should be called from exception handler only. - if not isinstance(exc, (BrokenPipeError, ConnectionResetError)): - logger.exception('Fatal error for %s', self) + if isinstance(exc, (BrokenPipeError, + ConnectionResetError, ConnectionAbortedError)): + if self._loop.get_debug(): + logger.debug("%r: %s", self, message, exc_info=True) + else: + self._loop.call_exception_handler({ + 'message': message, + 'exception': exc, + 'transport': self, + 'protocol': self._protocol, + }) self._force_close(exc) def _force_close(self, exc): @@ -396,7 +605,8 @@ def _force_close(self, exc): def _call_connection_lost(self, exc): try: - self._protocol.connection_lost(exc) + if self._protocol_connected: + self._protocol.connection_lost(exc) finally: self._sock.close() self._sock = None @@ -404,43 +614,9 @@ def _call_connection_lost(self, exc): self._loop = None server = self._server if server is not None: - server.detach(self) + server._detach() self._server = None - def _maybe_pause_protocol(self): - size = self.get_write_buffer_size() - if size <= self._high_water: - return - if not self._protocol_paused: - self._protocol_paused = True - try: - self._protocol.pause_writing() - except Exception: - logger.exception('pause_writing() failed') - - def _maybe_resume_protocol(self): - if (self._protocol_paused and - self.get_write_buffer_size() <= self._low_water): - self._protocol_paused = False - try: - self._protocol.resume_writing() - except Exception: - logger.exception('resume_writing() failed') - - def set_write_buffer_limits(self, high=None, low=None): - if high is None: - if low is None: - high = 64*1024 - else: - high = 4*low - if low is None: - low = high // 4 - if not high >= low >= 0: - raise ValueError('high (%r) must be >= low (%r) must be >= 0' % - (high, low)) - self._high_water = high - self._low_water = low - def get_write_buffer_size(self): return len(self._buffer) @@ -453,10 +629,13 @@ def __init__(self, loop, sock, protocol, waiter=None, self._eof = False self._paused = False - self._loop.add_reader(self._sock_fd, self._read_ready) self._loop.call_soon(self._protocol.connection_made, self) + # only start reading when connection_made() has been called + self._loop.call_soon(self._loop.add_reader, + self._sock_fd, self._read_ready) if waiter is not None: - self._loop.call_soon(waiter.set_result, None) + # only wake up the waiter when connection_made() has been called + self._loop.call_soon(waiter._set_result_unless_cancelled, None) def pause_reading(self): if self._closing: @@ -465,6 +644,8 @@ def pause_reading(self): raise RuntimeError('Already paused') self._paused = True self._loop.remove_reader(self._sock_fd) + if self._loop.get_debug(): + logger.debug("%r pauses reading", self) def resume_reading(self): if not self._paused: @@ -473,6 +654,8 @@ def resume_reading(self): if self._closing: return self._loop.add_reader(self._sock_fd, self._read_ready) + if self._loop.get_debug(): + logger.debug("%r resumes reading", self) def _read_ready(self): try: @@ -480,11 +663,13 @@ def _read_ready(self): except (BlockingIOError, InterruptedError): pass except Exception as exc: - self._fatal_error(exc) + self._fatal_error(exc, 'Fatal read error on socket transport') else: if data: self._protocol.data_received(data) else: + if self._loop.get_debug(): + logger.debug("%r received EOF", self) keep_open = self._protocol.eof_received() if keep_open: # We're keeping the connection open so the @@ -516,7 +701,7 @@ def write(self, data): except (BlockingIOError, InterruptedError): pass except Exception as exc: - self._fatal_error(exc) + self._fatal_error(exc, 'Fatal write error on socket transport') return else: data = data[n:] @@ -539,7 +724,7 @@ def _write_ready(self): except Exception as exc: self._loop.remove_writer(self._sock_fd) self._buffer.clear() - self._fatal_error(exc) + self._fatal_error(exc, 'Fatal write error on socket transport') else: if n: del self._buffer[:n] @@ -572,84 +757,89 @@ def __init__(self, loop, rawsock, protocol, sslcontext, waiter=None, if ssl is None: raise RuntimeError('stdlib ssl module not available') - if server_side: - if not sslcontext: - raise ValueError('Server side ssl needs a valid SSLContext') - else: - if not sslcontext: - # Client side may pass ssl=True to use a default - # context; in that case the sslcontext passed is None. - # The default is the same as used by urllib with - # cadefault=True. - if hasattr(ssl, '_create_stdlib_context'): - sslcontext = ssl._create_stdlib_context( - cert_reqs=ssl.CERT_REQUIRED) - else: - # Fallback for Python 3.3. - sslcontext = ssl.SSLContext(ssl.PROTOCOL_SSLv23) - sslcontext.options |= ssl.OP_NO_SSLv2 - sslcontext.set_default_verify_paths() - sslcontext.verify_mode = ssl.CERT_REQUIRED + if not sslcontext: + sslcontext = sslproto._create_transport_context(server_side, server_hostname) wrap_kwargs = { 'server_side': server_side, 'do_handshake_on_connect': False, } - if server_hostname and not server_side and ssl.HAS_SNI: + if server_hostname and not server_side: wrap_kwargs['server_hostname'] = server_hostname sslsock = sslcontext.wrap_socket(rawsock, **wrap_kwargs) super().__init__(loop, sslsock, protocol, extra, server) + # the protocol connection is only made after the SSL handshake + self._protocol_connected = False self._server_hostname = server_hostname self._waiter = waiter - self._rawsock = rawsock self._sslcontext = sslcontext self._paused = False # SSL-specific extra info. (peercert is set later) self._extra.update(sslcontext=sslcontext) - self._on_handshake() + if self._loop.get_debug(): + logger.debug("%r starts SSL handshake", self) + start_time = self._loop.time() + else: + start_time = None + self._on_handshake(start_time) - def _on_handshake(self): + def _wakeup_waiter(self, exc=None): + if self._waiter is None: + return + if not self._waiter.cancelled(): + if exc is not None: + self._waiter.set_exception(exc) + else: + self._waiter.set_result(None) + self._waiter = None + + def _on_handshake(self, start_time): try: self._sock.do_handshake() except ssl.SSLWantReadError: - self._loop.add_reader(self._sock_fd, self._on_handshake) + self._loop.add_reader(self._sock_fd, + self._on_handshake, start_time) return except ssl.SSLWantWriteError: - self._loop.add_writer(self._sock_fd, self._on_handshake) - return - except Exception as exc: - self._loop.remove_reader(self._sock_fd) - self._loop.remove_writer(self._sock_fd) - self._sock.close() - if self._waiter is not None: - self._waiter.set_exception(exc) + self._loop.add_writer(self._sock_fd, + self._on_handshake, start_time) return except BaseException as exc: + if self._loop.get_debug(): + logger.warning("%r: SSL handshake failed", + self, exc_info=True) self._loop.remove_reader(self._sock_fd) self._loop.remove_writer(self._sock_fd) self._sock.close() - if self._waiter is not None: - self._waiter.set_exception(exc) - raise + self._wakeup_waiter(exc) + if isinstance(exc, Exception): + return + else: + raise self._loop.remove_reader(self._sock_fd) self._loop.remove_writer(self._sock_fd) - # Verify hostname if requested. peercert = self._sock.getpeercert() - if (self._server_hostname and - self._sslcontext.verify_mode != ssl.CERT_NONE): - try: - ssl.match_hostname(peercert, self._server_hostname) - except Exception as exc: - self._sock.close() - if self._waiter is not None: - self._waiter.set_exception(exc) - return + if not hasattr(self._sslcontext, 'check_hostname'): + # Verify hostname if requested, Python 3.4+ uses check_hostname + # and checks the hostname in do_handshake() + if (self._server_hostname and + self._sslcontext.verify_mode != ssl.CERT_NONE): + try: + ssl.match_hostname(peercert, self._server_hostname) + except Exception as exc: + if self._loop.get_debug(): + logger.warning("%r: SSL handshake failed " + "on matching the hostname", + self, exc_info=True) + self._sock.close() + self._wakeup_waiter(exc) + return # Add extra info that becomes available after handshake. self._extra.update(peercert=peercert, @@ -660,9 +850,14 @@ def _on_handshake(self): self._read_wants_write = False self._write_wants_read = False self._loop.add_reader(self._sock_fd, self._read_ready) + self._protocol_connected = True self._loop.call_soon(self._protocol.connection_made, self) - if self._waiter is not None: - self._loop.call_soon(self._waiter.set_result, None) + # only wake up the waiter when connection_made() has been called + self._loop.call_soon(self._wakeup_waiter) + + if self._loop.get_debug(): + dt = self._loop.time() - start_time + logger.debug("%r: SSL handshake took %.1f ms", self, dt * 1e3) def pause_reading(self): # XXX This is a bit icky, given the comment at the top of @@ -677,14 +872,18 @@ def pause_reading(self): raise RuntimeError('Already paused') self._paused = True self._loop.remove_reader(self._sock_fd) + if self._loop.get_debug(): + logger.debug("%r pauses reading", self) def resume_reading(self): if not self._paused: - raise ('Not paused') + raise RuntimeError('Not paused') self._paused = False if self._closing: return self._loop.add_reader(self._sock_fd, self._read_ready) + if self._loop.get_debug(): + logger.debug("%r resumes reading", self) def _read_ready(self): if self._write_wants_read: @@ -703,12 +902,14 @@ def _read_ready(self): self._loop.remove_reader(self._sock_fd) self._loop.add_writer(self._sock_fd, self._write_ready) except Exception as exc: - self._fatal_error(exc) + self._fatal_error(exc, 'Fatal read error on SSL transport') else: if data: self._protocol.data_received(data) else: try: + if self._loop.get_debug(): + logger.debug("%r received EOF", self) keep_open = self._protocol.eof_received() if keep_open: logger.warning('returning true from eof_received() ' @@ -727,8 +928,7 @@ def _write_ready(self): if self._buffer: try: n = self._sock.send(self._buffer) - except (BlockingIOError, InterruptedError, - ssl.SSLWantWriteError): + except (BlockingIOError, InterruptedError, ssl.SSLWantWriteError): n = 0 except ssl.SSLWantReadError: n = 0 @@ -737,7 +937,7 @@ def _write_ready(self): except Exception as exc: self._loop.remove_writer(self._sock_fd) self._buffer.clear() - self._fatal_error(exc) + self._fatal_error(exc, 'Fatal write error on SSL transport') return if n: @@ -778,11 +978,17 @@ class _SelectorDatagramTransport(_SelectorTransport): _buffer_factory = collections.deque - def __init__(self, loop, sock, protocol, address=None, extra=None): + def __init__(self, loop, sock, protocol, address=None, + waiter=None, extra=None): super().__init__(loop, sock, protocol, extra) self._address = address - self._loop.add_reader(self._sock_fd, self._read_ready) self._loop.call_soon(self._protocol.connection_made, self) + # only start reading when connection_made() has been called + self._loop.call_soon(self._loop.add_reader, + self._sock_fd, self._read_ready) + if waiter is not None: + # only wake up the waiter when connection_made() has been called + self._loop.call_soon(waiter._set_result_unless_cancelled, None) def get_write_buffer_size(self): return sum(len(data) for data, _ in self._buffer) @@ -795,7 +1001,7 @@ def _read_ready(self): except OSError as exc: self._protocol.error_received(exc) except Exception as exc: - self._fatal_error(exc) + self._fatal_error(exc, 'Fatal read error on datagram transport') else: self._protocol.datagram_received(data, addr) @@ -830,7 +1036,8 @@ def sendto(self, data, addr=None): self._protocol.error_received(exc) return except Exception as exc: - self._fatal_error(exc) + self._fatal_error(exc, + 'Fatal write error on datagram transport') return # Ensure that what we buffer is immutable. @@ -852,7 +1059,8 @@ def _sendto_ready(self): self._protocol.error_received(exc) return except Exception as exc: - self._fatal_error(exc) + self._fatal_error(exc, + 'Fatal write error on datagram transport') return self._maybe_resume_protocol() # May append to buffer. diff --git a/Lib/asyncio/sslproto.py b/Lib/asyncio/sslproto.py new file mode 100644 index 000000000000..235855e21e1c --- /dev/null +++ b/Lib/asyncio/sslproto.py @@ -0,0 +1,668 @@ +import collections +import sys +import warnings +try: + import ssl +except ImportError: # pragma: no cover + ssl = None + +from . import protocols +from . import transports +from .log import logger + + +def _create_transport_context(server_side, server_hostname): + if server_side: + raise ValueError('Server side SSL needs a valid SSLContext') + + # Client side may pass ssl=True to use a default + # context; in that case the sslcontext passed is None. + # The default is secure for client connections. + if hasattr(ssl, 'create_default_context'): + # Python 3.4+: use up-to-date strong settings. + sslcontext = ssl.create_default_context() + if not server_hostname: + sslcontext.check_hostname = False + else: + # Fallback for Python 3.3. + sslcontext = ssl.SSLContext(ssl.PROTOCOL_SSLv23) + sslcontext.options |= ssl.OP_NO_SSLv2 + sslcontext.options |= ssl.OP_NO_SSLv3 + sslcontext.set_default_verify_paths() + sslcontext.verify_mode = ssl.CERT_REQUIRED + return sslcontext + + +def _is_sslproto_available(): + return hasattr(ssl, "MemoryBIO") + + +# States of an _SSLPipe. +_UNWRAPPED = "UNWRAPPED" +_DO_HANDSHAKE = "DO_HANDSHAKE" +_WRAPPED = "WRAPPED" +_SHUTDOWN = "SHUTDOWN" + + +class _SSLPipe(object): + """An SSL "Pipe". + + An SSL pipe allows you to communicate with an SSL/TLS protocol instance + through memory buffers. It can be used to implement a security layer for an + existing connection where you don't have access to the connection's file + descriptor, or for some reason you don't want to use it. + + An SSL pipe can be in "wrapped" and "unwrapped" mode. In unwrapped mode, + data is passed through untransformed. In wrapped mode, application level + data is encrypted to SSL record level data and vice versa. The SSL record + level is the lowest level in the SSL protocol suite and is what travels + as-is over the wire. + + An SslPipe initially is in "unwrapped" mode. To start SSL, call + do_handshake(). To shutdown SSL again, call unwrap(). + """ + + max_size = 256 * 1024 # Buffer size passed to read() + + def __init__(self, context, server_side, server_hostname=None): + """ + The *context* argument specifies the ssl.SSLContext to use. + + The *server_side* argument indicates whether this is a server side or + client side transport. + + The optional *server_hostname* argument can be used to specify the + hostname you are connecting to. You may only specify this parameter if + the _ssl module supports Server Name Indication (SNI). + """ + self._context = context + self._server_side = server_side + self._server_hostname = server_hostname + self._state = _UNWRAPPED + self._incoming = ssl.MemoryBIO() + self._outgoing = ssl.MemoryBIO() + self._sslobj = None + self._need_ssldata = False + self._handshake_cb = None + self._shutdown_cb = None + + @property + def context(self): + """The SSL context passed to the constructor.""" + return self._context + + @property + def ssl_object(self): + """The internal ssl.SSLObject instance. + + Return None if the pipe is not wrapped. + """ + return self._sslobj + + @property + def need_ssldata(self): + """Whether more record level data is needed to complete a handshake + that is currently in progress.""" + return self._need_ssldata + + @property + def wrapped(self): + """ + Whether a security layer is currently in effect. + + Return False during handshake. + """ + return self._state == _WRAPPED + + def do_handshake(self, callback=None): + """Start the SSL handshake. + + Return a list of ssldata. A ssldata element is a list of buffers + + The optional *callback* argument can be used to install a callback that + will be called when the handshake is complete. The callback will be + called with None if successful, else an exception instance. + """ + if self._state != _UNWRAPPED: + raise RuntimeError('handshake in progress or completed') + self._sslobj = self._context.wrap_bio( + self._incoming, self._outgoing, + server_side=self._server_side, + server_hostname=self._server_hostname) + self._state = _DO_HANDSHAKE + self._handshake_cb = callback + ssldata, appdata = self.feed_ssldata(b'', only_handshake=True) + assert len(appdata) == 0 + return ssldata + + def shutdown(self, callback=None): + """Start the SSL shutdown sequence. + + Return a list of ssldata. A ssldata element is a list of buffers + + The optional *callback* argument can be used to install a callback that + will be called when the shutdown is complete. The callback will be + called without arguments. + """ + if self._state == _UNWRAPPED: + raise RuntimeError('no security layer present') + if self._state == _SHUTDOWN: + raise RuntimeError('shutdown in progress') + assert self._state in (_WRAPPED, _DO_HANDSHAKE) + self._state = _SHUTDOWN + self._shutdown_cb = callback + ssldata, appdata = self.feed_ssldata(b'') + assert appdata == [] or appdata == [b''] + return ssldata + + def feed_eof(self): + """Send a potentially "ragged" EOF. + + This method will raise an SSL_ERROR_EOF exception if the EOF is + unexpected. + """ + self._incoming.write_eof() + ssldata, appdata = self.feed_ssldata(b'') + assert appdata == [] or appdata == [b''] + + def feed_ssldata(self, data, only_handshake=False): + """Feed SSL record level data into the pipe. + + The data must be a bytes instance. It is OK to send an empty bytes + instance. This can be used to get ssldata for a handshake initiated by + this endpoint. + + Return a (ssldata, appdata) tuple. The ssldata element is a list of + buffers containing SSL data that needs to be sent to the remote SSL. + + The appdata element is a list of buffers containing plaintext data that + needs to be forwarded to the application. The appdata list may contain + an empty buffer indicating an SSL "close_notify" alert. This alert must + be acknowledged by calling shutdown(). + """ + if self._state == _UNWRAPPED: + # If unwrapped, pass plaintext data straight through. + if data: + appdata = [data] + else: + appdata = [] + return ([], appdata) + + self._need_ssldata = False + if data: + self._incoming.write(data) + + ssldata = [] + appdata = [] + try: + if self._state == _DO_HANDSHAKE: + # Call do_handshake() until it doesn't raise anymore. + self._sslobj.do_handshake() + self._state = _WRAPPED + if self._handshake_cb: + self._handshake_cb(None) + if only_handshake: + return (ssldata, appdata) + # Handshake done: execute the wrapped block + + if self._state == _WRAPPED: + # Main state: read data from SSL until close_notify + while True: + chunk = self._sslobj.read(self.max_size) + appdata.append(chunk) + if not chunk: # close_notify + break + + elif self._state == _SHUTDOWN: + # Call shutdown() until it doesn't raise anymore. + self._sslobj.unwrap() + self._sslobj = None + self._state = _UNWRAPPED + if self._shutdown_cb: + self._shutdown_cb() + + elif self._state == _UNWRAPPED: + # Drain possible plaintext data after close_notify. + appdata.append(self._incoming.read()) + except (ssl.SSLError, ssl.CertificateError) as exc: + if getattr(exc, 'errno', None) not in ( + ssl.SSL_ERROR_WANT_READ, ssl.SSL_ERROR_WANT_WRITE, + ssl.SSL_ERROR_SYSCALL): + if self._state == _DO_HANDSHAKE and self._handshake_cb: + self._handshake_cb(exc) + raise + self._need_ssldata = (exc.errno == ssl.SSL_ERROR_WANT_READ) + + # Check for record level data that needs to be sent back. + # Happens for the initial handshake and renegotiations. + if self._outgoing.pending: + ssldata.append(self._outgoing.read()) + return (ssldata, appdata) + + def feed_appdata(self, data, offset=0): + """Feed plaintext data into the pipe. + + Return an (ssldata, offset) tuple. The ssldata element is a list of + buffers containing record level data that needs to be sent to the + remote SSL instance. The offset is the number of plaintext bytes that + were processed, which may be less than the length of data. + + NOTE: In case of short writes, this call MUST be retried with the SAME + buffer passed into the *data* argument (i.e. the id() must be the + same). This is an OpenSSL requirement. A further particularity is that + a short write will always have offset == 0, because the _ssl module + does not enable partial writes. And even though the offset is zero, + there will still be encrypted data in ssldata. + """ + assert 0 <= offset <= len(data) + if self._state == _UNWRAPPED: + # pass through data in unwrapped mode + if offset < len(data): + ssldata = [data[offset:]] + else: + ssldata = [] + return (ssldata, len(data)) + + ssldata = [] + view = memoryview(data) + while True: + self._need_ssldata = False + try: + if offset < len(view): + offset += self._sslobj.write(view[offset:]) + except ssl.SSLError as exc: + # It is not allowed to call write() after unwrap() until the + # close_notify is acknowledged. We return the condition to the + # caller as a short write. + if exc.reason == 'PROTOCOL_IS_SHUTDOWN': + exc.errno = ssl.SSL_ERROR_WANT_READ + if exc.errno not in (ssl.SSL_ERROR_WANT_READ, + ssl.SSL_ERROR_WANT_WRITE, + ssl.SSL_ERROR_SYSCALL): + raise + self._need_ssldata = (exc.errno == ssl.SSL_ERROR_WANT_READ) + + # See if there's any record level data back for us. + if self._outgoing.pending: + ssldata.append(self._outgoing.read()) + if offset == len(view) or self._need_ssldata: + break + return (ssldata, offset) + + +class _SSLProtocolTransport(transports._FlowControlMixin, + transports.Transport): + + def __init__(self, loop, ssl_protocol, app_protocol): + self._loop = loop + self._ssl_protocol = ssl_protocol + self._app_protocol = app_protocol + self._closed = False + + def get_extra_info(self, name, default=None): + """Get optional transport information.""" + return self._ssl_protocol._get_extra_info(name, default) + + def close(self): + """Close the transport. + + Buffered data will be flushed asynchronously. No more data + will be received. After all buffered data is flushed, the + protocol's connection_lost() method will (eventually) called + with None as its argument. + """ + self._closed = True + self._ssl_protocol._start_shutdown() + + # On Python 3.3 and older, objects with a destructor part of a reference + # cycle are never destroyed. It's not more the case on Python 3.4 thanks + # to the PEP 442. + if sys.version_info >= (3, 4): + def __del__(self): + if not self._closed: + warnings.warn("unclosed transport %r" % self, ResourceWarning) + self.close() + + def pause_reading(self): + """Pause the receiving end. + + No data will be passed to the protocol's data_received() + method until resume_reading() is called. + """ + self._ssl_protocol._transport.pause_reading() + + def resume_reading(self): + """Resume the receiving end. + + Data received will once again be passed to the protocol's + data_received() method. + """ + self._ssl_protocol._transport.resume_reading() + + def set_write_buffer_limits(self, high=None, low=None): + """Set the high- and low-water limits for write flow control. + + These two values control when to call the protocol's + pause_writing() and resume_writing() methods. If specified, + the low-water limit must be less than or equal to the + high-water limit. Neither value can be negative. + + The defaults are implementation-specific. If only the + high-water limit is given, the low-water limit defaults to a + implementation-specific value less than or equal to the + high-water limit. Setting high to zero forces low to zero as + well, and causes pause_writing() to be called whenever the + buffer becomes non-empty. Setting low to zero causes + resume_writing() to be called only once the buffer is empty. + Use of zero for either limit is generally sub-optimal as it + reduces opportunities for doing I/O and computation + concurrently. + """ + self._ssl_protocol._transport.set_write_buffer_limits(high, low) + + def get_write_buffer_size(self): + """Return the current size of the write buffer.""" + return self._ssl_protocol._transport.get_write_buffer_size() + + def write(self, data): + """Write some data bytes to the transport. + + This does not block; it buffers the data and arranges for it + to be sent out asynchronously. + """ + if not isinstance(data, (bytes, bytearray, memoryview)): + raise TypeError("data: expecting a bytes-like instance, got {!r}" + .format(type(data).__name__)) + if not data: + return + self._ssl_protocol._write_appdata(data) + + def can_write_eof(self): + """Return True if this transport supports write_eof(), False if not.""" + return False + + def abort(self): + """Close the transport immediately. + + Buffered data will be lost. No more data will be received. + The protocol's connection_lost() method will (eventually) be + called with None as its argument. + """ + self._ssl_protocol._abort() + + +class SSLProtocol(protocols.Protocol): + """SSL protocol. + + Implementation of SSL on top of a socket using incoming and outgoing + buffers which are ssl.MemoryBIO objects. + """ + + def __init__(self, loop, app_protocol, sslcontext, waiter, + server_side=False, server_hostname=None): + if ssl is None: + raise RuntimeError('stdlib ssl module not available') + + if not sslcontext: + sslcontext = _create_transport_context(server_side, server_hostname) + + self._server_side = server_side + if server_hostname and not server_side: + self._server_hostname = server_hostname + else: + self._server_hostname = None + self._sslcontext = sslcontext + # SSL-specific extra info. More info are set when the handshake + # completes. + self._extra = dict(sslcontext=sslcontext) + + # App data write buffering + self._write_backlog = collections.deque() + self._write_buffer_size = 0 + + self._waiter = waiter + self._loop = loop + self._app_protocol = app_protocol + self._app_transport = _SSLProtocolTransport(self._loop, + self, self._app_protocol) + self._sslpipe = None + self._session_established = False + self._in_handshake = False + self._in_shutdown = False + self._transport = None + + def _wakeup_waiter(self, exc=None): + if self._waiter is None: + return + if not self._waiter.cancelled(): + if exc is not None: + self._waiter.set_exception(exc) + else: + self._waiter.set_result(None) + self._waiter = None + + def connection_made(self, transport): + """Called when the low-level connection is made. + + Start the SSL handshake. + """ + self._transport = transport + self._sslpipe = _SSLPipe(self._sslcontext, + self._server_side, + self._server_hostname) + self._start_handshake() + + def connection_lost(self, exc): + """Called when the low-level connection is lost or closed. + + The argument is an exception object or None (the latter + meaning a regular EOF is received or the connection was + aborted or closed). + """ + if self._session_established: + self._session_established = False + self._loop.call_soon(self._app_protocol.connection_lost, exc) + self._transport = None + self._app_transport = None + + def pause_writing(self): + """Called when the low-level transport's buffer goes over + the high-water mark. + """ + self._app_protocol.pause_writing() + + def resume_writing(self): + """Called when the low-level transport's buffer drains below + the low-water mark. + """ + self._app_protocol.resume_writing() + + def data_received(self, data): + """Called when some SSL data is received. + + The argument is a bytes object. + """ + try: + ssldata, appdata = self._sslpipe.feed_ssldata(data) + except ssl.SSLError as e: + if self._loop.get_debug(): + logger.warning('%r: SSL error %s (reason %s)', + self, e.errno, e.reason) + self._abort() + return + + for chunk in ssldata: + self._transport.write(chunk) + + for chunk in appdata: + if chunk: + self._app_protocol.data_received(chunk) + else: + self._start_shutdown() + break + + def eof_received(self): + """Called when the other end of the low-level stream + is half-closed. + + If this returns a false value (including None), the transport + will close itself. If it returns a true value, closing the + transport is up to the protocol. + """ + try: + if self._loop.get_debug(): + logger.debug("%r received EOF", self) + + self._wakeup_waiter(ConnectionResetError) + + if not self._in_handshake: + keep_open = self._app_protocol.eof_received() + if keep_open: + logger.warning('returning true from eof_received() ' + 'has no effect when using ssl') + finally: + self._transport.close() + + def _get_extra_info(self, name, default=None): + if name in self._extra: + return self._extra[name] + else: + return self._transport.get_extra_info(name, default) + + def _start_shutdown(self): + if self._in_shutdown: + return + self._in_shutdown = True + self._write_appdata(b'') + + def _write_appdata(self, data): + self._write_backlog.append((data, 0)) + self._write_buffer_size += len(data) + self._process_write_backlog() + + def _start_handshake(self): + if self._loop.get_debug(): + logger.debug("%r starts SSL handshake", self) + self._handshake_start_time = self._loop.time() + else: + self._handshake_start_time = None + self._in_handshake = True + # (b'', 1) is a special value in _process_write_backlog() to do + # the SSL handshake + self._write_backlog.append((b'', 1)) + self._loop.call_soon(self._process_write_backlog) + + def _on_handshake_complete(self, handshake_exc): + self._in_handshake = False + + sslobj = self._sslpipe.ssl_object + try: + if handshake_exc is not None: + raise handshake_exc + + peercert = sslobj.getpeercert() + if not hasattr(self._sslcontext, 'check_hostname'): + # Verify hostname if requested, Python 3.4+ uses check_hostname + # and checks the hostname in do_handshake() + if (self._server_hostname + and self._sslcontext.verify_mode != ssl.CERT_NONE): + ssl.match_hostname(peercert, self._server_hostname) + except BaseException as exc: + if self._loop.get_debug(): + if isinstance(exc, ssl.CertificateError): + logger.warning("%r: SSL handshake failed " + "on verifying the certificate", + self, exc_info=True) + else: + logger.warning("%r: SSL handshake failed", + self, exc_info=True) + self._transport.close() + if isinstance(exc, Exception): + self._wakeup_waiter(exc) + return + else: + raise + + if self._loop.get_debug(): + dt = self._loop.time() - self._handshake_start_time + logger.debug("%r: SSL handshake took %.1f ms", self, dt * 1e3) + + # Add extra info that becomes available after handshake. + self._extra.update(peercert=peercert, + cipher=sslobj.cipher(), + compression=sslobj.compression(), + ) + self._app_protocol.connection_made(self._app_transport) + self._wakeup_waiter() + self._session_established = True + # In case transport.write() was already called. Don't call + # immediatly _process_write_backlog(), but schedule it: + # _on_handshake_complete() can be called indirectly from + # _process_write_backlog(), and _process_write_backlog() is not + # reentrant. + self._loop.call_soon(self._process_write_backlog) + + def _process_write_backlog(self): + # Try to make progress on the write backlog. + if self._transport is None: + return + + try: + for i in range(len(self._write_backlog)): + data, offset = self._write_backlog[0] + if data: + ssldata, offset = self._sslpipe.feed_appdata(data, offset) + elif offset: + ssldata = self._sslpipe.do_handshake(self._on_handshake_complete) + offset = 1 + else: + ssldata = self._sslpipe.shutdown(self._finalize) + offset = 1 + + for chunk in ssldata: + self._transport.write(chunk) + + if offset < len(data): + self._write_backlog[0] = (data, offset) + # A short write means that a write is blocked on a read + # We need to enable reading if it is paused! + assert self._sslpipe.need_ssldata + if self._transport._paused: + self._transport.resume_reading() + break + + # An entire chunk from the backlog was processed. We can + # delete it and reduce the outstanding buffer size. + del self._write_backlog[0] + self._write_buffer_size -= len(data) + except BaseException as exc: + if self._in_handshake: + self._on_handshake_complete(exc) + else: + self._fatal_error(exc, 'Fatal error on SSL transport') + + def _fatal_error(self, exc, message='Fatal error on transport'): + # Should be called from exception handler only. + if isinstance(exc, (BrokenPipeError, ConnectionResetError)): + if self._loop.get_debug(): + logger.debug("%r: %s", self, message, exc_info=True) + else: + self._loop.call_exception_handler({ + 'message': message, + 'exception': exc, + 'transport': self._transport, + 'protocol': self, + }) + if self._transport: + self._transport._force_close(exc) + + def _finalize(self): + if self._transport is not None: + self._transport.close() + + def _abort(self): + if self._transport is not None: + try: + self._transport.abort() + finally: + self._finalize() diff --git a/Lib/asyncio/streams.py b/Lib/asyncio/streams.py index 50c4c5d1c2ec..7ff16a488f9e 100644 --- a/Lib/asyncio/streams.py +++ b/Lib/asyncio/streams.py @@ -2,26 +2,46 @@ __all__ = ['StreamReader', 'StreamWriter', 'StreamReaderProtocol', 'open_connection', 'start_server', + 'IncompleteReadError', ] -import collections +import socket +if hasattr(socket, 'AF_UNIX'): + __all__.extend(['open_unix_connection', 'start_unix_server']) + +from . import coroutines from . import events from . import futures from . import protocols -from . import tasks +from .coroutines import coroutine +from .log import logger _DEFAULT_LIMIT = 2**16 -@tasks.coroutine +class IncompleteReadError(EOFError): + """ + Incomplete read error. Attributes: + + - partial: read bytes string before the end of stream was reached + - expected: total number of expected bytes + """ + def __init__(self, partial, expected): + EOFError.__init__(self, "%s bytes read on a total of %s expected bytes" + % (len(partial), expected)) + self.partial = partial + self.expected = expected + + +@coroutine def open_connection(host=None, port=None, *, loop=None, limit=_DEFAULT_LIMIT, **kwds): """A wrapper for create_connection() returning a (reader, writer) pair. The reader returned is a StreamReader instance; the writer is a - Transport. + StreamWriter instance. The arguments are all the usual arguments to create_connection() except protocol_factory; most common are positional host and port, @@ -38,14 +58,14 @@ def open_connection(host=None, port=None, *, if loop is None: loop = events.get_event_loop() reader = StreamReader(limit=limit, loop=loop) - protocol = StreamReaderProtocol(reader) + protocol = StreamReaderProtocol(reader, loop=loop) transport, _ = yield from loop.create_connection( lambda: protocol, host, port, **kwds) writer = StreamWriter(transport, protocol, reader, loop) return reader, writer -@tasks.coroutine +@coroutine def start_server(client_connected_cb, host=None, port=None, *, loop=None, limit=_DEFAULT_LIMIT, **kwds): """Start a socket server, call back for each client connected. @@ -81,8 +101,107 @@ def factory(): return (yield from loop.create_server(factory, host, port, **kwds)) -class StreamReaderProtocol(protocols.Protocol): - """Trivial helper class to adapt between Protocol and StreamReader. +if hasattr(socket, 'AF_UNIX'): + # UNIX Domain Sockets are supported on this platform + + @coroutine + def open_unix_connection(path=None, *, + loop=None, limit=_DEFAULT_LIMIT, **kwds): + """Similar to `open_connection` but works with UNIX Domain Sockets.""" + if loop is None: + loop = events.get_event_loop() + reader = StreamReader(limit=limit, loop=loop) + protocol = StreamReaderProtocol(reader, loop=loop) + transport, _ = yield from loop.create_unix_connection( + lambda: protocol, path, **kwds) + writer = StreamWriter(transport, protocol, reader, loop) + return reader, writer + + + @coroutine + def start_unix_server(client_connected_cb, path=None, *, + loop=None, limit=_DEFAULT_LIMIT, **kwds): + """Similar to `start_server` but works with UNIX Domain Sockets.""" + if loop is None: + loop = events.get_event_loop() + + def factory(): + reader = StreamReader(limit=limit, loop=loop) + protocol = StreamReaderProtocol(reader, client_connected_cb, + loop=loop) + return protocol + + return (yield from loop.create_unix_server(factory, path, **kwds)) + + +class FlowControlMixin(protocols.Protocol): + """Reusable flow control logic for StreamWriter.drain(). + + This implements the protocol methods pause_writing(), + resume_reading() and connection_lost(). If the subclass overrides + these it must call the super methods. + + StreamWriter.drain() must wait for _drain_helper() coroutine. + """ + + def __init__(self, loop=None): + if loop is None: + self._loop = events.get_event_loop() + else: + self._loop = loop + self._paused = False + self._drain_waiter = None + self._connection_lost = False + + def pause_writing(self): + assert not self._paused + self._paused = True + if self._loop.get_debug(): + logger.debug("%r pauses writing", self) + + def resume_writing(self): + assert self._paused + self._paused = False + if self._loop.get_debug(): + logger.debug("%r resumes writing", self) + + waiter = self._drain_waiter + if waiter is not None: + self._drain_waiter = None + if not waiter.done(): + waiter.set_result(None) + + def connection_lost(self, exc): + self._connection_lost = True + # Wake up the writer if currently paused. + if not self._paused: + return + waiter = self._drain_waiter + if waiter is None: + return + self._drain_waiter = None + if waiter.done(): + return + if exc is None: + waiter.set_result(None) + else: + waiter.set_exception(exc) + + @coroutine + def _drain_helper(self): + if self._connection_lost: + raise ConnectionResetError('Connection lost') + if not self._paused: + return + waiter = self._drain_waiter + assert waiter is None or waiter.cancelled() + waiter = futures.Future(loop=self._loop) + self._drain_waiter = waiter + yield from waiter + + +class StreamReaderProtocol(FlowControlMixin, protocols.Protocol): + """Helper class to adapt between Protocol and StreamReader. (This is a helper class instead of making StreamReader itself a Protocol subclass, because the StreamReader has other potential @@ -91,12 +210,10 @@ class StreamReaderProtocol(protocols.Protocol): """ def __init__(self, stream_reader, client_connected_cb=None, loop=None): + super().__init__(loop=loop) self._stream_reader = stream_reader self._stream_writer = None - self._drain_waiter = None - self._paused = False self._client_connected_cb = client_connected_cb - self._loop = loop # May be None; we may never need it. def connection_made(self, transport): self._stream_reader.set_transport(transport) @@ -106,24 +223,15 @@ def connection_made(self, transport): self._loop) res = self._client_connected_cb(self._stream_reader, self._stream_writer) - if tasks.iscoroutine(res): - tasks.Task(res, loop=self._loop) + if coroutines.iscoroutine(res): + self._loop.create_task(res) def connection_lost(self, exc): if exc is None: self._stream_reader.feed_eof() else: self._stream_reader.set_exception(exc) - # Also wake up the writing side. - if self._paused: - waiter = self._drain_waiter - if waiter is not None: - self._drain_waiter = None - if not waiter.done(): - if exc is None: - waiter.set_result(None) - else: - waiter.set_exception(exc) + super().connection_lost(exc) def data_received(self, data): self._stream_reader.feed_data(data) @@ -131,19 +239,6 @@ def data_received(self, data): def eof_received(self): self._stream_reader.feed_eof() - def pause_writing(self): - assert not self._paused - self._paused = True - - def resume_writing(self): - assert self._paused - self._paused = False - waiter = self._drain_waiter - if waiter is not None: - self._drain_waiter = None - if not waiter.done(): - waiter.set_result(None) - class StreamWriter: """Wraps a Transport. @@ -151,16 +246,24 @@ class StreamWriter: This exposes write(), writelines(), [can_]write_eof(), get_extra_info() and close(). It adds drain() which returns an optional Future on which you can wait for flow control. It also - adds a transport attribute which references the Transport + adds a transport property which references the Transport directly. """ def __init__(self, transport, protocol, reader, loop): self._transport = transport self._protocol = protocol + # drain() expects that the reader has a exception() method + assert reader is None or isinstance(reader, StreamReader) self._reader = reader self._loop = loop + def __repr__(self): + info = [self.__class__.__name__, 'transport=%r' % self._transport] + if self._reader is not None: + info.append('reader=%r' % self._reader) + return '<%s>' % ' '.join(info) + @property def transport(self): return self._transport @@ -183,32 +286,20 @@ def close(self): def get_extra_info(self, name, default=None): return self._transport.get_extra_info(name, default) + @coroutine def drain(self): - """This method has an unusual return value. + """Flush the write buffer. The intended use is to write w.write(data) yield from w.drain() - - When there's nothing to wait for, drain() returns (), and the - yield-from continues immediately. When the transport buffer - is full (the protocol is paused), drain() creates and returns - a Future and the yield-from will block until that Future is - completed, which will happen when the buffer is (partially) - drained and the protocol is resumed. """ - if self._reader._exception is not None: - raise self._writer._exception - if self._transport._conn_lost: # Uses private variable. - raise ConnectionResetError('Connection lost') - if not self._protocol._paused: - return () - waiter = self._protocol._drain_waiter - assert waiter is None or waiter.cancelled() - waiter = futures.Future(loop=self._loop) - self._protocol._drain_waiter = waiter - return waiter + if self._reader is not None: + exc = self._reader.exception() + if exc is not None: + raise exc + yield from self._protocol._drain_helper() class StreamReader: @@ -218,12 +309,12 @@ def __init__(self, limit=_DEFAULT_LIMIT, loop=None): # it also doubles as half the buffer limit. self._limit = limit if loop is None: - loop = events.get_event_loop() - self._loop = loop - self._buffer = collections.deque() # Deque of bytes objects. - self._byte_count = 0 # Bytes in buffer. - self._eof = False # Whether we're done. - self._waiter = None # A future. + self._loop = events.get_event_loop() + else: + self._loop = loop + self._buffer = bytearray() + self._eof = False # Whether we're done. + self._waiter = None # A future used by _wait_for_data() self._exception = None self._transport = None self._paused = False @@ -240,39 +331,43 @@ def set_exception(self, exc): if not waiter.cancelled(): waiter.set_exception(exc) + def _wakeup_waiter(self): + """Wakeup read() or readline() function waiting for data or EOF.""" + waiter = self._waiter + if waiter is not None: + self._waiter = None + if not waiter.cancelled(): + waiter.set_result(None) + def set_transport(self, transport): assert self._transport is None, 'Transport already set' self._transport = transport def _maybe_resume_transport(self): - if self._paused and self._byte_count <= self._limit: + if self._paused and len(self._buffer) <= self._limit: self._paused = False self._transport.resume_reading() def feed_eof(self): self._eof = True - waiter = self._waiter - if waiter is not None: - self._waiter = None - if not waiter.cancelled(): - waiter.set_result(True) + self._wakeup_waiter() + + def at_eof(self): + """Return True if the buffer is empty and 'feed_eof' was called.""" + return self._eof and not self._buffer def feed_data(self, data): + assert not self._eof, 'feed_data after feed_eof' + if not data: return - self._buffer.append(data) - self._byte_count += len(data) - - waiter = self._waiter - if waiter is not None: - self._waiter = None - if not waiter.cancelled(): - waiter.set_result(False) + self._buffer.extend(data) + self._wakeup_waiter() if (self._transport is not None and not self._paused and - self._byte_count > 2*self._limit): + len(self._buffer) > 2*self._limit): try: self._transport.pause_reading() except NotImplementedError: @@ -283,33 +378,43 @@ def feed_data(self, data): else: self._paused = True - @tasks.coroutine + def _wait_for_data(self, func_name): + """Wait until feed_data() or feed_eof() is called.""" + # StreamReader uses a future to link the protocol feed_data() method + # to a read coroutine. Running two read coroutines at the same time + # would have an unexpected behaviour. It would not possible to know + # which coroutine would get the next data. + if self._waiter is not None: + raise RuntimeError('%s() called while another coroutine is ' + 'already waiting for incoming data' % func_name) + + self._waiter = futures.Future(loop=self._loop) + try: + yield from self._waiter + finally: + self._waiter = None + + @coroutine def readline(self): if self._exception is not None: raise self._exception - parts = [] - parts_size = 0 + line = bytearray() not_enough = True while not_enough: while self._buffer and not_enough: - data = self._buffer.popleft() - ichar = data.find(b'\n') + ichar = self._buffer.find(b'\n') if ichar < 0: - parts.append(data) - parts_size += len(data) + line.extend(self._buffer) + self._buffer.clear() else: ichar += 1 - head, tail = data[:ichar], data[ichar:] - if tail: - self._buffer.appendleft(tail) + line.extend(self._buffer[:ichar]) + del self._buffer[:ichar] not_enough = False - parts.append(head) - parts_size += len(head) - if parts_size > self._limit: - self._byte_count -= parts_size + if len(line) > self._limit: self._maybe_resume_transport() raise ValueError('Line is too long') @@ -317,20 +422,12 @@ def readline(self): break if not_enough: - assert self._waiter is None - self._waiter = futures.Future(loop=self._loop) - try: - yield from self._waiter - finally: - self._waiter = None - - line = b''.join(parts) - self._byte_count -= parts_size - self._maybe_resume_transport() + yield from self._wait_for_data('readline') - return line + self._maybe_resume_transport() + return bytes(line) - @tasks.coroutine + @coroutine def read(self, n=-1): if self._exception is not None: raise self._exception @@ -339,60 +436,51 @@ def read(self, n=-1): return b'' if n < 0: - while not self._eof: - assert not self._waiter - self._waiter = futures.Future(loop=self._loop) - try: - yield from self._waiter - finally: - self._waiter = None + # This used to just loop creating a new waiter hoping to + # collect everything in self._buffer, but that would + # deadlock if the subprocess sends more than self.limit + # bytes. So just call self.read(self._limit) until EOF. + blocks = [] + while True: + block = yield from self.read(self._limit) + if not block: + break + blocks.append(block) + return b''.join(blocks) else: - if not self._byte_count and not self._eof: - assert not self._waiter - self._waiter = futures.Future(loop=self._loop) - try: - yield from self._waiter - finally: - self._waiter = None - - if n < 0 or self._byte_count <= n: - data = b''.join(self._buffer) + if not self._buffer and not self._eof: + yield from self._wait_for_data('read') + + if n < 0 or len(self._buffer) <= n: + data = bytes(self._buffer) self._buffer.clear() - self._byte_count = 0 - self._maybe_resume_transport() - return data - - parts = [] - parts_bytes = 0 - while self._buffer and parts_bytes < n: - data = self._buffer.popleft() - data_bytes = len(data) - if n < parts_bytes + data_bytes: - data_bytes = n - parts_bytes - data, rest = data[:data_bytes], data[data_bytes:] - self._buffer.appendleft(rest) - - parts.append(data) - parts_bytes += data_bytes - self._byte_count -= data_bytes - self._maybe_resume_transport() - - return b''.join(parts) - - @tasks.coroutine + else: + # n > 0 and len(self._buffer) > n + data = bytes(self._buffer[:n]) + del self._buffer[:n] + + self._maybe_resume_transport() + return data + + @coroutine def readexactly(self, n): if self._exception is not None: raise self._exception - if n <= 0: - return b'' - - while self._byte_count < n and not self._eof: - assert not self._waiter - self._waiter = futures.Future(loop=self._loop) - try: - yield from self._waiter - finally: - self._waiter = None - - return (yield from self.read(n)) + # There used to be "optimized" code here. It created its own + # Future and waited until self._buffer had at least the n + # bytes, then called read(n). Unfortunately, this could pause + # the transport if the argument was larger than the pause + # limit (which is twice self._limit). So now we just read() + # into a local buffer. + + blocks = [] + while n > 0: + block = yield from self.read(n) + if not block: + partial = b''.join(blocks) + raise IncompleteReadError(partial, len(partial) + n) + blocks.append(block) + n -= len(block) + + return b''.join(blocks) diff --git a/Lib/asyncio/subprocess.py b/Lib/asyncio/subprocess.py new file mode 100644 index 000000000000..4600a9f417da --- /dev/null +++ b/Lib/asyncio/subprocess.py @@ -0,0 +1,215 @@ +__all__ = ['create_subprocess_exec', 'create_subprocess_shell'] + +import collections +import subprocess + +from . import events +from . import futures +from . import protocols +from . import streams +from . import tasks +from .coroutines import coroutine +from .log import logger + + +PIPE = subprocess.PIPE +STDOUT = subprocess.STDOUT +DEVNULL = subprocess.DEVNULL + + +class SubprocessStreamProtocol(streams.FlowControlMixin, + protocols.SubprocessProtocol): + """Like StreamReaderProtocol, but for a subprocess.""" + + def __init__(self, limit, loop): + super().__init__(loop=loop) + self._limit = limit + self.stdin = self.stdout = self.stderr = None + self._transport = None + + def __repr__(self): + info = [self.__class__.__name__] + if self.stdin is not None: + info.append('stdin=%r' % self.stdin) + if self.stdout is not None: + info.append('stdout=%r' % self.stdout) + if self.stderr is not None: + info.append('stderr=%r' % self.stderr) + return '<%s>' % ' '.join(info) + + def connection_made(self, transport): + self._transport = transport + + stdout_transport = transport.get_pipe_transport(1) + if stdout_transport is not None: + self.stdout = streams.StreamReader(limit=self._limit, + loop=self._loop) + self.stdout.set_transport(stdout_transport) + + 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) + + stdin_transport = transport.get_pipe_transport(0) + if stdin_transport is not None: + self.stdin = streams.StreamWriter(stdin_transport, + protocol=self, + reader=None, + loop=self._loop) + + def pipe_data_received(self, fd, data): + if fd == 1: + reader = self.stdout + elif fd == 2: + reader = self.stderr + else: + reader = None + if reader is not None: + reader.feed_data(data) + + def pipe_connection_lost(self, fd, exc): + if fd == 0: + pipe = self.stdin + if pipe is not None: + pipe.close() + self.connection_lost(exc) + return + if fd == 1: + reader = self.stdout + elif fd == 2: + reader = self.stderr + else: + reader = None + if reader != None: + if exc is None: + reader.feed_eof() + else: + reader.set_exception(exc) + + def process_exited(self): + self._transport.close() + self._transport = None + + +class Process: + def __init__(self, transport, protocol, loop): + self._transport = transport + self._protocol = protocol + self._loop = loop + self.stdin = protocol.stdin + self.stdout = protocol.stdout + self.stderr = protocol.stderr + self.pid = transport.get_pid() + + def __repr__(self): + return '<%s %s>' % (self.__class__.__name__, self.pid) + + @property + def returncode(self): + return self._transport.get_returncode() + + @coroutine + def wait(self): + """Wait until the process exit and return the process return code. + + This method is a coroutine.""" + return (yield from self._transport._wait()) + + def send_signal(self, signal): + self._transport.send_signal(signal) + + def terminate(self): + self._transport.terminate() + + def kill(self): + self._transport.kill() + + @coroutine + def _feed_stdin(self, input): + debug = self._loop.get_debug() + self.stdin.write(input) + if debug: + logger.debug('%r communicate: feed stdin (%s bytes)', + self, len(input)) + try: + yield from self.stdin.drain() + except (BrokenPipeError, ConnectionResetError) as exc: + # communicate() ignores BrokenPipeError and ConnectionResetError + if debug: + logger.debug('%r communicate: stdin got %r', self, exc) + + if debug: + logger.debug('%r communicate: close stdin', self) + self.stdin.close() + + @coroutine + def _noop(self): + return None + + @coroutine + def _read_stream(self, fd): + transport = self._transport.get_pipe_transport(fd) + if fd == 2: + stream = self.stderr + else: + assert fd == 1 + stream = self.stdout + if self._loop.get_debug(): + name = 'stdout' if fd == 1 else 'stderr' + logger.debug('%r communicate: read %s', self, name) + output = yield from stream.read() + if self._loop.get_debug(): + name = 'stdout' if fd == 1 else 'stderr' + logger.debug('%r communicate: close %s', self, name) + transport.close() + return output + + @coroutine + def communicate(self, input=None): + if input: + stdin = self._feed_stdin(input) + else: + stdin = self._noop() + if self.stdout is not None: + stdout = self._read_stream(1) + else: + stdout = self._noop() + if self.stderr is not None: + stderr = self._read_stream(2) + else: + stderr = self._noop() + stdin, stdout, stderr = yield from tasks.gather(stdin, stdout, stderr, + loop=self._loop) + yield from self.wait() + return (stdout, stderr) + + +@coroutine +def create_subprocess_shell(cmd, stdin=None, stdout=None, stderr=None, + loop=None, limit=streams._DEFAULT_LIMIT, **kwds): + if loop is None: + loop = events.get_event_loop() + protocol_factory = lambda: SubprocessStreamProtocol(limit=limit, + loop=loop) + transport, protocol = yield from loop.subprocess_shell( + protocol_factory, + cmd, stdin=stdin, stdout=stdout, + stderr=stderr, **kwds) + return Process(transport, protocol, loop) + +@coroutine +def create_subprocess_exec(program, *args, stdin=None, stdout=None, + stderr=None, loop=None, + limit=streams._DEFAULT_LIMIT, **kwds): + if loop is None: + loop = events.get_event_loop() + protocol_factory = lambda: SubprocessStreamProtocol(limit=limit, + loop=loop) + transport, protocol = yield from loop.subprocess_exec( + protocol_factory, + program, *args, + stdin=stdin, stdout=stdout, + stderr=stderr, **kwds) + return Process(transport, protocol, loop) diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py index 999e9629bc69..4f19a252ff63 100644 --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -1,110 +1,25 @@ """Support for tasks, coroutines and the scheduler.""" -__all__ = ['coroutine', 'Task', +__all__ = ['Task', 'FIRST_COMPLETED', 'FIRST_EXCEPTION', 'ALL_COMPLETED', 'wait', 'wait_for', 'as_completed', 'sleep', 'async', 'gather', 'shield', ] -import collections import concurrent.futures import functools import inspect import linecache +import sys import traceback import weakref +from . import coroutines from . import events from . import futures -from .log import logger +from .coroutines import coroutine -# If you set _DEBUG to true, @coroutine will wrap the resulting -# generator objects in a CoroWrapper instance (defined below). That -# instance will log a message when the generator is never iterated -# over, which may happen when you forget to use "yield from" with a -# coroutine call. Note that the value of the _DEBUG flag is taken -# when the decorator is used, so to be of any use it must be set -# before you define your coroutines. A downside of using this feature -# is that tracebacks show entries for the CoroWrapper.__next__ method -# when _DEBUG is true. -_DEBUG = False - - -class CoroWrapper: - """Wrapper for coroutine in _DEBUG mode.""" - - __slot__ = ['gen', 'func'] - - def __init__(self, gen, func): - assert inspect.isgenerator(gen), gen - self.gen = gen - self.func = func - - def __iter__(self): - return self - - def __next__(self): - return next(self.gen) - - def send(self, value): - return self.gen.send(value) - - def throw(self, exc): - return self.gen.throw(exc) - - def close(self): - return self.gen.close() - - def __del__(self): - frame = self.gen.gi_frame - if frame is not None and frame.f_lasti == -1: - func = self.func - code = func.__code__ - filename = code.co_filename - lineno = code.co_firstlineno - logger.error( - 'Coroutine %r defined at %s:%s was never yielded from', - func.__name__, filename, lineno) - - -def coroutine(func): - """Decorator to mark coroutines. - - If the coroutine is not yielded from before it is destroyed, - an error message is logged. - """ - if inspect.isgeneratorfunction(func): - coro = func - else: - @functools.wraps(func) - def coro(*args, **kw): - res = func(*args, **kw) - if isinstance(res, futures.Future) or inspect.isgenerator(res): - res = yield from res - return res - - if not _DEBUG: - wrapper = coro - else: - @functools.wraps(func) - def wrapper(*args, **kwds): - w = CoroWrapper(coro(*args, **kwds), func) - w.__name__ = coro.__name__ - w.__doc__ = coro.__doc__ - return w - - wrapper._is_coroutine = True # For iscoroutinefunction(). - return wrapper - - -def iscoroutinefunction(func): - """Return True if func is a decorated coroutine function.""" - return getattr(func, '_is_coroutine', False) - - -def iscoroutine(obj): - """Return True if obj is a coroutine object.""" - return isinstance(obj, CoroWrapper) or inspect.isgenerator(obj) +_PY34 = (sys.version_info >= (3, 4)) class Task(futures.Future): @@ -122,6 +37,26 @@ class Task(futures.Future): # Weak set containing all tasks alive. _all_tasks = weakref.WeakSet() + # Dictionary containing tasks that are currently active in + # all running event loops. {EventLoop: Task} + _current_tasks = {} + + # If False, don't log a message if the task is destroyed whereas its + # status is still pending + _log_destroy_pending = True + + @classmethod + def current_task(cls, loop=None): + """Return the currently running task in an event loop or None. + + By default the current task for the current event loop is returned. + + None is returned when called not in the context of a Task. + """ + if loop is None: + loop = events.get_event_loop() + return cls._current_tasks.get(loop) + @classmethod def all_tasks(cls, loop=None): """Return a set of all tasks for an event loop. @@ -133,30 +68,49 @@ def all_tasks(cls, loop=None): return {t for t in cls._all_tasks if t._loop is loop} def __init__(self, coro, *, loop=None): - assert iscoroutine(coro), repr(coro) # Not a coroutine function! + assert coroutines.iscoroutine(coro), repr(coro) super().__init__(loop=loop) + if self._source_traceback: + del self._source_traceback[-1] self._coro = iter(coro) # Use the iterator just in case. self._fut_waiter = None self._must_cancel = False self._loop.call_soon(self._step) self.__class__._all_tasks.add(self) - def __repr__(self): - res = super().__repr__() - if (self._must_cancel and - self._state == futures._PENDING and - '<PENDING' in res): - res = res.replace('<PENDING', '<CANCELLING', 1) - i = res.find('<') - if i < 0: - i = len(res) - res = res[:i] + '(<{}>)'.format(self._coro.__name__) + res[i:] - return res + # On Python 3.3 or older, objects with a destructor that are part of a + # reference cycle are never destroyed. That's not the case any more on + # Python 3.4 thanks to the PEP 442. + if _PY34: + def __del__(self): + if self._state == futures._PENDING and self._log_destroy_pending: + context = { + 'task': self, + 'message': 'Task was destroyed but it is pending!', + } + if self._source_traceback: + context['source_traceback'] = self._source_traceback + self._loop.call_exception_handler(context) + futures.Future.__del__(self) + + def _repr_info(self): + info = super()._repr_info() + + if self._must_cancel: + # replace status + info[0] = 'cancelling' + + coro = coroutines._format_coroutine(self._coro) + info.insert(1, 'coro=<%s>' % coro) + + if self._fut_waiter is not None: + info.insert(2, 'wait_for=%r' % self._fut_waiter) + return info def get_stack(self, *, limit=None): """Return the list of stack frames for this task's coroutine. - If the coroutine is active, this returns the stack where it is + If the coroutine is not done, this returns the stack where it is suspended. If the coroutine has completed successfully or was cancelled, this returns an empty list. If the coroutine was terminated by an exception, this returns the list of traceback @@ -164,7 +118,7 @@ def get_stack(self, *, limit=None): The frames are always ordered from oldest to newest. - The optional limit gives the maximum nummber of frames to + The optional limit gives the maximum number of frames to return; by default all available frames are returned. Its meaning differs depending on whether a stack or a traceback is returned: the newest frames of a stack are returned, but the @@ -202,7 +156,8 @@ def print_stack(self, *, limit=None, file=None): This produces output similar to that of the traceback module, for the frames retrieved by get_stack(). The limit argument is passed to get_stack(). The file argument is an I/O stream - to which the output goes; by default it goes to sys.stderr. + to which the output is written; by default output is written + to sys.stderr. """ extracted_list = [] checked = set() @@ -231,6 +186,25 @@ def print_stack(self, *, limit=None, file=None): print(line, file=file, end='') def cancel(self): + """Request that this task cancel itself. + + This arranges for a CancelledError to be thrown into the + wrapped coroutine on the next cycle through the event loop. + The coroutine then has a chance to clean up or even deny + the request using try/except/finally. + + Unlike Future.cancel, this does not guarantee that the + task will be cancelled: the exception might be caught and + acted upon, delaying cancellation of the task or preventing + cancellation completely. The task may also return a value or + raise a different exception. + + Immediately after this method is called, Task.cancelled() will + not return True (unless the task was already cancelled). A + task will be marked as cancelled when the wrapped coroutine + terminates with a CancelledError exception (even if cancel() + was not called). + """ if self.done(): return False if self._fut_waiter is not None: @@ -252,6 +226,8 @@ def _step(self, value=None, exc=None): self._must_cancel = False coro = self._coro self._fut_waiter = None + + self.__class__._current_tasks[self._loop] = self # Call either coro.throw(exc) or coro.send(value). try: if exc is not None: @@ -302,7 +278,9 @@ def _step(self, value=None, exc=None): self._step, None, RuntimeError( 'Task got bad yield: {!r}'.format(result))) - self = None + finally: + self.__class__._current_tasks.pop(self._loop) + self = None # Needed to break cycles when an exception occurs. def _wakeup(self, future): try: @@ -326,6 +304,8 @@ def _wakeup(self, future): def wait(fs, *, loop=None, timeout=None, return_when=ALL_COMPLETED): """Wait for the Futures and coroutines given by fs to complete. + The sequence futures must not be empty. + Coroutines will be wrapped in Tasks. Returns two sets of Future: (done, pending). @@ -337,22 +317,24 @@ def wait(fs, *, loop=None, timeout=None, return_when=ALL_COMPLETED): Note: This does not raise TimeoutError! Futures that aren't done when the timeout occurs are returned in the second set. """ + if isinstance(fs, futures.Future) or coroutines.iscoroutine(fs): + raise TypeError("expect a list of futures, not %s" % type(fs).__name__) if not fs: raise ValueError('Set of coroutines/Futures is empty.') + if return_when not in (FIRST_COMPLETED, FIRST_EXCEPTION, ALL_COMPLETED): + raise ValueError('Invalid return_when value: {}'.format(return_when)) if loop is None: loop = events.get_event_loop() - fs = set(async(f, loop=loop) for f in fs) + fs = {async(f, loop=loop) for f in set(fs)} - if return_when not in (FIRST_COMPLETED, FIRST_EXCEPTION, ALL_COMPLETED): - raise ValueError('Invalid return_when value: {}'.format(return_when)) return (yield from _wait(fs, timeout, return_when, loop)) -def _release_waiter(waiter, value=True, *args): +def _release_waiter(waiter, *args): if not waiter.done(): - waiter.set_result(value) + waiter.set_result(None) @coroutine @@ -361,29 +343,41 @@ def wait_for(fut, timeout, *, loop=None): Coroutine will be wrapped in Task. - Returns result of the Future or coroutine. Raises TimeoutError when - timeout occurs. - - Usage: + Returns result of the Future or coroutine. When a timeout occurs, + it cancels the task and raises TimeoutError. To avoid the task + cancellation, wrap it in shield(). - result = yield from asyncio.wait_for(fut, 10.0) + If the wait is cancelled, the task is also cancelled. + This function is a coroutine. """ if loop is None: loop = events.get_event_loop() + if timeout is None: + return (yield from fut) + waiter = futures.Future(loop=loop) - timeout_handle = loop.call_later(timeout, _release_waiter, waiter, False) - cb = functools.partial(_release_waiter, waiter, True) + timeout_handle = loop.call_later(timeout, _release_waiter, waiter) + cb = functools.partial(_release_waiter, waiter) fut = async(fut, loop=loop) fut.add_done_callback(cb) try: - if (yield from waiter): + # wait until the future completes or the timeout + try: + yield from waiter + except futures.CancelledError: + fut.remove_done_callback(cb) + fut.cancel() + raise + + if fut.done(): return fut.result() else: fut.remove_done_callback(cb) + fut.cancel() raise futures.TimeoutError() finally: timeout_handle.cancel() @@ -412,7 +406,7 @@ def _on_completion(f): if timeout_handle is not None: timeout_handle.cancel() if not waiter.done(): - waiter.set_result(False) + waiter.set_result(None) for f in fs: f.add_done_callback(_on_completion) @@ -435,7 +429,11 @@ def _on_completion(f): # This is *not* a @coroutine! It is just an iterator (yielding Futures). def as_completed(fs, *, loop=None, timeout=None): - """Return an iterator whose values, when waited for, are Futures. + """Return an iterator whose values are coroutines. + + When waiting for the yielded coroutines you'll get the results (or + exceptions!) of the original Futures (or coroutines), in the order + in which and as soon as they complete. This differs from PEP 3148; the proper way to use this is: @@ -443,35 +441,45 @@ def as_completed(fs, *, loop=None, timeout=None): result = yield from f # The 'yield from' may raise. # Use result. - Raises TimeoutError if the timeout occurs before all Futures are - done. + If a timeout is specified, the 'yield from' will raise + TimeoutError when the timeout occurs before all Futures are done. Note: The futures 'f' are not necessarily members of fs. """ + if isinstance(fs, futures.Future) or coroutines.iscoroutine(fs): + raise TypeError("expect a list of futures, not %s" % type(fs).__name__) loop = loop if loop is not None else events.get_event_loop() - deadline = None if timeout is None else loop.time() + timeout - todo = set(async(f, loop=loop) for f in fs) - completed = collections.deque() + todo = {async(f, loop=loop) for f in set(fs)} + from .queues import Queue # Import here to avoid circular import problem. + done = Queue(loop=loop) + timeout_handle = None + + def _on_timeout(): + for f in todo: + f.remove_done_callback(_on_completion) + done.put_nowait(None) # Queue a dummy value for _wait_for_one(). + todo.clear() # Can't do todo.remove(f) in the loop. + + def _on_completion(f): + if not todo: + return # _on_timeout() was here first. + todo.remove(f) + done.put_nowait(f) + if not todo and timeout_handle is not None: + timeout_handle.cancel() @coroutine def _wait_for_one(): - while not completed: - timeout = None - if deadline is not None: - timeout = deadline - loop.time() - if timeout < 0: - raise futures.TimeoutError() - done, pending = yield from _wait( - todo, timeout, FIRST_COMPLETED, loop) - # Multiple callers might be waiting for the same events - # and getting the same outcome. Dedupe by updating todo. - for f in done: - if f in todo: - todo.remove(f) - completed.append(f) - f = completed.popleft() - return f.result() # May raise. + f = yield from done.get() + if f is None: + # Dummy value from _on_timeout(). + raise futures.TimeoutError + return f.result() # May raise f.exception(). + for f in todo: + f.add_done_callback(_on_completion) + if todo and timeout is not None: + timeout_handle = loop.call_later(timeout, _on_timeout) for _ in range(len(todo)): yield _wait_for_one() @@ -480,7 +488,8 @@ def _wait_for_one(): def sleep(delay, result=None, *, loop=None): """Coroutine that completes after a given time (in seconds).""" future = futures.Future(loop=loop) - h = future._loop.call_later(delay, future.set_result, result) + h = future._loop.call_later(delay, + future._set_result_unless_cancelled, result) try: return (yield from future) finally: @@ -496,8 +505,13 @@ def async(coro_or_future, *, loop=None): if loop is not None and loop is not coro_or_future._loop: raise ValueError('loop argument must agree with Future') return coro_or_future - elif iscoroutine(coro_or_future): - return Task(coro_or_future, loop=loop) + elif coroutines.iscoroutine(coro_or_future): + if loop is None: + loop = events.get_event_loop() + task = loop.create_task(coro_or_future) + if task._source_traceback: + del task._source_traceback[-1] + return task else: raise TypeError('A Future or coroutine is required') @@ -529,7 +543,7 @@ def gather(*coros_or_futures, loop=None, return_exceptions=False): All futures must share the same event loop. If all the tasks are done successfully, the returned future's result is the list of results (in the order of the original sequence, not necessarily - the order of results arrival). If *result_exception* is True, + the order of results arrival). If *return_exceptions* is True, exceptions in the tasks are treated the same as successful results, and gathered in the result list; otherwise, the first raised exception will be immediately propagated to the returned @@ -542,29 +556,43 @@ def gather(*coros_or_futures, loop=None, return_exceptions=False): prevent the cancellation of one child to cause other children to be cancelled.) """ - children = [async(fut, loop=loop) for fut in coros_or_futures] - n = len(children) - if n == 0: + if not coros_or_futures: outer = futures.Future(loop=loop) outer.set_result([]) return outer - if loop is None: - loop = children[0]._loop - for fut in children: - if fut._loop is not loop: - raise ValueError("futures are tied to different event loops") + + arg_to_fut = {} + for arg in set(coros_or_futures): + if not isinstance(arg, futures.Future): + fut = async(arg, loop=loop) + if loop is None: + loop = fut._loop + # The caller cannot control this future, the "destroy pending task" + # warning should not be emitted. + fut._log_destroy_pending = False + else: + fut = arg + if loop is None: + loop = fut._loop + elif fut._loop is not loop: + raise ValueError("futures are tied to different event loops") + arg_to_fut[arg] = fut + + children = [arg_to_fut[arg] for arg in coros_or_futures] + nchildren = len(children) outer = _GatheringFuture(children, loop=loop) nfinished = 0 - results = [None] * n + results = [None] * nchildren def _done_callback(i, fut): nonlocal nfinished - if outer._state != futures._PENDING: - if fut._exception is not None: + if outer.done(): + if not fut.cancelled(): # Mark exception retrieved. fut.exception() return - if fut._state == futures._CANCELLED: + + if fut.cancelled(): res = futures.CancelledError() if not return_exceptions: outer.set_exception(res) @@ -578,7 +606,7 @@ def _done_callback(i, fut): res = fut._result results[i] = res nfinished += 1 - if nfinished == n: + if nfinished == nchildren: outer.set_result(results) for i, fut in enumerate(children): @@ -621,9 +649,11 @@ def shield(arg, *, loop=None): def _done_callback(inner): if outer.cancelled(): - # Mark inner's result as retrieved. - inner.cancelled() or inner.exception() + if not inner.cancelled(): + # Mark inner's result as retrieved. + inner.exception() return + if inner.cancelled(): outer.cancel() else: diff --git a/Lib/asyncio/test_utils.py b/Lib/asyncio/test_utils.py index d7d844249c4f..8cee95b84f95 100644 --- a/Lib/asyncio/test_utils.py +++ b/Lib/asyncio/test_utils.py @@ -3,23 +3,33 @@ import collections import contextlib import io -import unittest.mock +import logging import os +import re +import socket +import socketserver import sys +import tempfile import threading import time import unittest -import unittest.mock -from wsgiref.simple_server import make_server, WSGIRequestHandler, WSGIServer +from unittest import mock + +from http.server import HTTPServer +from wsgiref.simple_server import WSGIRequestHandler, WSGIServer + try: import ssl except ImportError: # pragma: no cover ssl = None -from . import tasks from . import base_events from . import events +from . import futures from . import selectors +from . import tasks +from .coroutines import coroutine +from .log import logger if sys.platform == 'win32': # pragma: no cover @@ -36,29 +46,28 @@ def dummy_ssl_context(): def run_briefly(loop): - @tasks.coroutine + @coroutine def once(): pass gen = once() - t = tasks.Task(gen, loop=loop) + t = loop.create_task(gen) + # Don't log a warning if the task is not done after run_until_complete(). + # It occurs if the loop is stopped or if a task raises a BaseException. + t._log_destroy_pending = False try: loop.run_until_complete(t) finally: gen.close() -def run_until(loop, pred, timeout=None): - if timeout is not None: - deadline = time.time() + timeout +def run_until(loop, pred, timeout=30): + deadline = time.time() + timeout while not pred(): if timeout is not None: timeout = deadline - time.time() if timeout <= 0: - return False - loop.run_until_complete(tasks.sleep(timeout, loop=loop)) - else: - run_briefly(loop) - return True + raise futures.TimeoutError() + loop.run_until_complete(tasks.sleep(0.001, loop=loop)) def run_once(loop): @@ -71,42 +80,58 @@ def run_once(loop): loop.run_forever() -@contextlib.contextmanager -def run_test_server(*, host='127.0.0.1', port=0, use_ssl=False): +class SilentWSGIRequestHandler(WSGIRequestHandler): - class SilentWSGIRequestHandler(WSGIRequestHandler): - def get_stderr(self): - return io.StringIO() + def get_stderr(self): + return io.StringIO() - def log_message(self, format, *args): - pass + def log_message(self, format, *args): + pass - class SilentWSGIServer(WSGIServer): - def handle_error(self, request, client_address): + +class SilentWSGIServer(WSGIServer): + + request_timeout = 2 + + def get_request(self): + request, client_addr = super().get_request() + request.settimeout(self.request_timeout) + return request, client_addr + + def handle_error(self, request, client_address): + pass + + +class SSLWSGIServerMixin: + + def finish_request(self, request, client_address): + # The relative location of our test directory (which + # contains the ssl key and certificate files) differs + # between the stdlib and stand-alone asyncio. + # Prefer our own if we can find it. + here = os.path.join(os.path.dirname(__file__), '..', 'tests') + if not os.path.isdir(here): + here = os.path.join(os.path.dirname(os.__file__), + 'test', 'test_asyncio') + keyfile = os.path.join(here, 'ssl_key.pem') + certfile = os.path.join(here, 'ssl_cert.pem') + ssock = ssl.wrap_socket(request, + keyfile=keyfile, + certfile=certfile, + server_side=True) + try: + self.RequestHandlerClass(ssock, client_address, self) + ssock.close() + except OSError: + # maybe socket has been closed by peer pass - class SSLWSGIServer(SilentWSGIServer): - def finish_request(self, request, client_address): - # The relative location of our test directory (which - # contains the sample key and certificate files) differs - # between the stdlib and stand-alone Tulip/asyncio. - # Prefer our own if we can find it. - here = os.path.join(os.path.dirname(__file__), '..', 'tests') - if not os.path.isdir(here): - here = os.path.join(os.path.dirname(os.__file__), - 'test', 'test_asyncio') - keyfile = os.path.join(here, 'sample.key') - certfile = os.path.join(here, 'sample.crt') - ssock = ssl.wrap_socket(request, - keyfile=keyfile, - certfile=certfile, - server_side=True) - try: - self.RequestHandlerClass(ssock, client_address, self) - ssock.close() - except OSError: - # maybe socket has been closed by peer - pass + +class SSLWSGIServer(SSLWSGIServerMixin, SilentWSGIServer): + pass + + +def _run_test_server(*, address, use_ssl=False, server_cls, server_ssl_cls): def app(environ, start_response): status = '200 OK' @@ -116,11 +141,12 @@ def app(environ, start_response): # Run the test WSGI server in a separate thread in order not to # interfere with event handling in the main thread - server_class = SSLWSGIServer if use_ssl else SilentWSGIServer - httpd = make_server(host, port, app, - server_class, SilentWSGIRequestHandler) + server_class = server_ssl_cls if use_ssl else server_cls + httpd = server_class(address, SilentWSGIRequestHandler) + httpd.set_app(app) httpd.address = httpd.server_address - server_thread = threading.Thread(target=httpd.serve_forever) + server_thread = threading.Thread( + target=lambda: httpd.serve_forever(poll_interval=0.05)) server_thread.start() try: yield httpd @@ -130,13 +156,85 @@ def app(environ, start_response): server_thread.join() +if hasattr(socket, 'AF_UNIX'): + + class UnixHTTPServer(socketserver.UnixStreamServer, HTTPServer): + + def server_bind(self): + socketserver.UnixStreamServer.server_bind(self) + self.server_name = '127.0.0.1' + self.server_port = 80 + + + class UnixWSGIServer(UnixHTTPServer, WSGIServer): + + request_timeout = 2 + + def server_bind(self): + UnixHTTPServer.server_bind(self) + self.setup_environ() + + def get_request(self): + request, client_addr = super().get_request() + request.settimeout(self.request_timeout) + # Code in the stdlib expects that get_request + # will return a socket and a tuple (host, port). + # However, this isn't true for UNIX sockets, + # as the second return value will be a path; + # hence we return some fake data sufficient + # to get the tests going + return request, ('127.0.0.1', '') + + + class SilentUnixWSGIServer(UnixWSGIServer): + + def handle_error(self, request, client_address): + pass + + + class UnixSSLWSGIServer(SSLWSGIServerMixin, SilentUnixWSGIServer): + pass + + + def gen_unix_socket_path(): + with tempfile.NamedTemporaryFile() as file: + return file.name + + + @contextlib.contextmanager + def unix_socket_path(): + path = gen_unix_socket_path() + try: + yield path + finally: + try: + os.unlink(path) + except OSError: + pass + + + @contextlib.contextmanager + def run_test_unix_server(*, use_ssl=False): + with unix_socket_path() as path: + yield from _run_test_server(address=path, use_ssl=use_ssl, + server_cls=SilentUnixWSGIServer, + server_ssl_cls=UnixSSLWSGIServer) + + +@contextlib.contextmanager +def run_test_server(*, host='127.0.0.1', port=0, use_ssl=False): + yield from _run_test_server(address=(host, port), use_ssl=use_ssl, + server_cls=SilentWSGIServer, + server_ssl_cls=SSLWSGIServer) + + def make_test_protocol(base): dct = {} for name in dir(base): if name.startswith('__') and name.endswith('__'): # skip magic names continue - dct[name] = unittest.mock.Mock(return_value=None) + dct[name] = MockCallback(return_value=None) return type('TestProtocol', (base,) + base.__bases__, dct)() @@ -175,7 +273,7 @@ def gen(): when = yield ... ... = yield time_advance - Value retuned by yield is absolute time of next scheduled handler. + Value returned by yield is absolute time of next scheduled handler. Value passed to yield is time advance to move loop's time forward. """ @@ -192,6 +290,7 @@ def gen(): self._gen = gen() next(self._gen) self._time = 0 + self._clock_resolution = 1e-9 self._timers = [] self._selector = TestSelector() @@ -208,6 +307,7 @@ def advance_time(self, advance): self._time += advance def close(self): + super().close() if self._check_on_close: try: self._gen.send(0) @@ -217,7 +317,7 @@ def close(self): raise AssertionError("Time generator is not finished") def add_reader(self, fd, callback, *args): - self.readers[fd] = events.make_handle(callback, args) + self.readers[fd] = events.Handle(callback, args, self) def remove_reader(self, fd): self.remove_reader_count[fd] += 1 @@ -236,7 +336,7 @@ def assert_reader(self, fd, callback, *args): handle._args, args) def add_writer(self, fd, callback, *args): - self.writers[fd] = events.make_handle(callback, args) + self.writers[fd] = events.Handle(callback, args, self) def remove_writer(self, fd): self.remove_writer_count[fd] += 1 @@ -274,3 +374,73 @@ def _process_events(self, event_list): def _write_to_self(self): pass + + +def MockCallback(**kwargs): + return mock.Mock(spec=['__call__'], **kwargs) + + +class MockPattern(str): + """A regex based str with a fuzzy __eq__. + + Use this helper with 'mock.assert_called_with', or anywhere + where a regex comparison between strings is needed. + + For instance: + mock_call.assert_called_with(MockPattern('spam.*ham')) + """ + def __eq__(self, other): + return bool(re.search(str(self), other, re.S)) + + +def get_function_source(func): + source = events._get_function_source(func) + if source is None: + raise ValueError("unable to get the source of %r" % (func,)) + return source + + +class TestCase(unittest.TestCase): + def set_event_loop(self, loop, *, cleanup=True): + assert loop is not None + # ensure that the event loop is passed explicitly in asyncio + events.set_event_loop(None) + if cleanup: + self.addCleanup(loop.close) + + def new_test_loop(self, gen=None): + loop = TestLoop(gen) + self.set_event_loop(loop) + return loop + + def tearDown(self): + events.set_event_loop(None) + + # Detect CPython bug #23353: ensure that yield/yield-from is not used + # in an except block of a generator + self.assertEqual(sys.exc_info(), (None, None, None)) + + +@contextlib.contextmanager +def disable_logger(): + """Context manager to disable asyncio logger. + + For example, it can be used to ignore warnings in debug mode. + """ + old_level = logger.level + try: + logger.setLevel(logging.CRITICAL+1) + yield + finally: + logger.setLevel(old_level) + +def mock_nonblocking_socket(): + """Create a mock of a non-blocking socket.""" + sock = mock.Mock(socket.socket) + sock.gettimeout.return_value = 0.0 + return sock + + +def force_legacy_ssl_support(): + return mock.patch('asyncio.sslproto._is_sslproto_available', + return_value=False) diff --git a/Lib/asyncio/transports.py b/Lib/asyncio/transports.py index 86b850e918a9..22df3c7aede7 100644 --- a/Lib/asyncio/transports.py +++ b/Lib/asyncio/transports.py @@ -1,6 +1,12 @@ """Abstract Transport class.""" -__all__ = ['ReadTransport', 'WriteTransport', 'Transport'] +import sys + +_PY34 = sys.version_info >= (3, 4) + +__all__ = ['BaseTransport', 'ReadTransport', 'WriteTransport', + 'Transport', 'DatagramTransport', 'SubprocessTransport', + ] class BaseTransport: @@ -85,11 +91,15 @@ def write(self, data): def writelines(self, list_of_data): """Write a list (or any iterable) of data bytes to the transport. - The default implementation just calls write() for each item in - the list/iterable. + The default implementation concatenates the arguments and + calls write() on the result. """ - for data in list_of_data: - self.write(data) + if not _PY34: + # In Python 3.3, bytes.join() doesn't handle memoryview. + list_of_data = ( + bytes(data) if isinstance(data, memoryview) else data + for data in list_of_data) + self.write(b''.join(list_of_data)) def write_eof(self): """Close the write end after flushing buffered data. @@ -209,3 +219,82 @@ def kill(self): http://docs.python.org/3/library/subprocess#subprocess.Popen.kill """ raise NotImplementedError + + +class _FlowControlMixin(Transport): + """All the logic for (write) flow control in a mix-in base class. + + The subclass must implement get_write_buffer_size(). It must call + _maybe_pause_protocol() whenever the write buffer size increases, + and _maybe_resume_protocol() whenever it decreases. It may also + override set_write_buffer_limits() (e.g. to specify different + defaults). + + The subclass constructor must call super().__init__(extra). This + will call set_write_buffer_limits(). + + The user may call set_write_buffer_limits() and + get_write_buffer_size(), and their protocol's pause_writing() and + resume_writing() may be called. + """ + + def __init__(self, extra=None, loop=None): + super().__init__(extra) + assert loop is not None + self._loop = loop + self._protocol_paused = False + self._set_write_buffer_limits() + + def _maybe_pause_protocol(self): + size = self.get_write_buffer_size() + if size <= self._high_water: + return + if not self._protocol_paused: + self._protocol_paused = True + try: + self._protocol.pause_writing() + except Exception as exc: + self._loop.call_exception_handler({ + 'message': 'protocol.pause_writing() failed', + 'exception': exc, + 'transport': self, + 'protocol': self._protocol, + }) + + def _maybe_resume_protocol(self): + if (self._protocol_paused and + self.get_write_buffer_size() <= self._low_water): + self._protocol_paused = False + try: + self._protocol.resume_writing() + except Exception as exc: + self._loop.call_exception_handler({ + 'message': 'protocol.resume_writing() failed', + 'exception': exc, + 'transport': self, + 'protocol': self._protocol, + }) + + def get_write_buffer_limits(self): + return (self._low_water, self._high_water) + + def _set_write_buffer_limits(self, high=None, low=None): + if high is None: + if low is None: + high = 64*1024 + else: + high = 4*low + if low is None: + low = high // 4 + if not high >= low >= 0: + raise ValueError('high (%r) must be >= low (%r) must be >= 0' % + (high, low)) + self._high_water = high + self._low_water = low + + def set_write_buffer_limits(self, high=None, low=None): + self._set_write_buffer_limits(high=high, low=low) + self._maybe_pause_protocol() + + def get_write_buffer_size(self): + raise NotImplementedError diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py index b611efd17d14..75e7c9ccadd0 100644 --- a/Lib/asyncio/unix_events.py +++ b/Lib/asyncio/unix_events.py @@ -1,7 +1,6 @@ -"""Selector eventloop for Unix with signal handling.""" +"""Selector event loop for Unix with signal handling.""" import errno -import fcntl import os import signal import socket @@ -9,36 +8,40 @@ import subprocess import sys import threading +import warnings +from . import base_events from . import base_subprocess from . import constants +from . import coroutines from . import events -from . import protocols +from . import futures from . import selector_events -from . import tasks +from . import selectors from . import transports +from .coroutines import coroutine from .log import logger -__all__ = ['SelectorEventLoop', 'STDIN', 'STDOUT', 'STDERR', +__all__ = ['SelectorEventLoop', 'AbstractChildWatcher', 'SafeChildWatcher', 'FastChildWatcher', 'DefaultEventLoopPolicy', ] -STDIN = 0 -STDOUT = 1 -STDERR = 2 - - if sys.platform == 'win32': # pragma: no cover raise ImportError('Signals are not really supported on Windows') +def _sighandler_noop(signum, frame): + """Dummy signal handler.""" + pass + + class _UnixSelectorEventLoop(selector_events.BaseSelectorEventLoop): - """Unix event loop + """Unix event loop. - Adds signal handling to SelectorEventLoop + Adds signal handling and UNIX Domain Socket support to SelectorEventLoop. """ def __init__(self, selector=None): @@ -49,9 +52,16 @@ def _socketpair(self): return socket.socketpair() def close(self): + super().close() for sig in list(self._signal_handlers): self.remove_signal_handler(sig) - super().close() + + def _process_self_data(self, data): + for signum in data: + if not signum: + # ignore null bytes written by _write_to_self() + continue + self._handle_signal(signum) def add_signal_handler(self, sig, callback, *args): """Add a handler for a signal. UNIX only. @@ -59,27 +69,38 @@ def add_signal_handler(self, sig, callback, *args): Raise ValueError if the signal number is invalid or uncatchable. Raise RuntimeError if there is a problem setting up the handler. """ + if (coroutines.iscoroutine(callback) + or coroutines.iscoroutinefunction(callback)): + raise TypeError("coroutines cannot be used " + "with add_signal_handler()") self._check_signal(sig) + self._check_closed() try: # set_wakeup_fd() raises ValueError if this is not the # main thread. By calling it early we ensure that an # event loop running in another thread cannot add a signal # handler. signal.set_wakeup_fd(self._csock.fileno()) - except ValueError as exc: + except (ValueError, OSError) as exc: raise RuntimeError(str(exc)) - handle = events.make_handle(callback, args) + handle = events.Handle(callback, args, self) self._signal_handlers[sig] = handle try: - signal.signal(sig, self._handle_signal) + # Register a dummy signal handler to ask Python to write the signal + # number in the wakup file descriptor. _process_self_data() will + # read signal numbers from this file descriptor to handle signals. + signal.signal(sig, _sighandler_noop) + + # Set SA_RESTART to limit EINTR occurrences. + signal.siginterrupt(sig, False) except OSError as exc: del self._signal_handlers[sig] if not self._signal_handlers: try: signal.set_wakeup_fd(-1) - except ValueError as nexc: + except (ValueError, OSError) as nexc: logger.info('set_wakeup_fd(-1) failed: %s', nexc) if exc.errno == errno.EINVAL: @@ -87,7 +108,7 @@ def add_signal_handler(self, sig, callback, *args): else: raise - def _handle_signal(self, sig, arg): + def _handle_signal(self, sig): """Internal helper that is the actual signal handler.""" handle = self._signal_handlers.get(sig) if handle is None: @@ -124,7 +145,7 @@ def remove_signal_handler(self, sig): if not self._signal_handlers: try: signal.set_wakeup_fd(-1) - except ValueError as exc: + except (ValueError, OSError) as exc: logger.info('set_wakeup_fd(-1) failed: %s', exc) return True @@ -150,35 +171,132 @@ def _make_write_pipe_transport(self, pipe, protocol, waiter=None, extra=None): return _UnixWritePipeTransport(self, pipe, protocol, waiter, extra) - @tasks.coroutine + @coroutine def _make_subprocess_transport(self, protocol, args, shell, stdin, stdout, stderr, bufsize, extra=None, **kwargs): with events.get_child_watcher() as watcher: + waiter = futures.Future(loop=self) transp = _UnixSubprocessTransport(self, protocol, args, shell, stdin, stdout, stderr, bufsize, - extra=None, **kwargs) + waiter=waiter, extra=extra, + **kwargs) + watcher.add_child_handler(transp.get_pid(), self._child_watcher_callback, transp) - yield from transp._post_init() + try: + yield from waiter + except Exception as exc: + # Workaround CPython bug #23353: using yield/yield-from in an + # except block of a generator doesn't clear properly + # sys.exc_info() + err = exc + else: + err = None + + if err is not None: + transp.close() + yield from transp._wait() + raise err + return transp def _child_watcher_callback(self, pid, returncode, transp): self.call_soon_threadsafe(transp._process_exited, returncode) - def _subprocess_closed(self, transp): - pass + @coroutine + def create_unix_connection(self, protocol_factory, path, *, + ssl=None, sock=None, + server_hostname=None): + assert server_hostname is None or isinstance(server_hostname, str) + if ssl: + if server_hostname is None: + raise ValueError( + 'you have to pass server_hostname when using ssl') + else: + if server_hostname is not None: + raise ValueError('server_hostname is only meaningful with ssl') + if path is not None: + if sock is not None: + raise ValueError( + 'path and sock can not be specified at the same time') -def _set_nonblocking(fd): - flags = fcntl.fcntl(fd, fcntl.F_GETFL) - flags = flags | os.O_NONBLOCK - fcntl.fcntl(fd, fcntl.F_SETFL, flags) + sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM, 0) + try: + sock.setblocking(False) + yield from self.sock_connect(sock, path) + except: + sock.close() + raise + + else: + if sock is None: + raise ValueError('no path and sock were specified') + sock.setblocking(False) + + transport, protocol = yield from self._create_connection_transport( + sock, protocol_factory, ssl, server_hostname) + return transport, protocol + + @coroutine + def create_unix_server(self, protocol_factory, path=None, *, + sock=None, backlog=100, ssl=None): + if isinstance(ssl, bool): + raise TypeError('ssl argument must be an SSLContext or None') + + if path is not None: + if sock is not None: + raise ValueError( + 'path and sock can not be specified at the same time') + + sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + + try: + sock.bind(path) + except OSError as exc: + sock.close() + if exc.errno == errno.EADDRINUSE: + # Let's improve the error message by adding + # with what exact address it occurs. + msg = 'Address {!r} is already in use'.format(path) + raise OSError(errno.EADDRINUSE, msg) from None + else: + raise + except: + sock.close() + raise + else: + if sock is None: + raise ValueError( + 'path was not specified, and no sock specified') + + if sock.family != socket.AF_UNIX: + raise ValueError( + 'A UNIX Domain Socket was expected, got {!r}'.format(sock)) + + server = base_events.Server(self, [sock]) + sock.listen(backlog) + sock.setblocking(False) + self._start_serving(protocol_factory, sock, ssl, server) + return server + + +if hasattr(os, 'set_blocking'): + def _set_nonblocking(fd): + os.set_blocking(fd, False) +else: + import fcntl + + def _set_nonblocking(fd): + flags = fcntl.fcntl(fd, fcntl.F_GETFL) + flags = flags | os.O_NONBLOCK + fcntl.fcntl(fd, fcntl.F_SETFL, flags) class _UnixReadPipeTransport(transports.ReadTransport): - max_size = 256 * 1024 # max bytes we read in one eventloop iteration + max_size = 256 * 1024 # max bytes we read in one event loop iteration def __init__(self, loop, pipe, protocol, waiter=None, extra=None): super().__init__(extra) @@ -187,15 +305,39 @@ def __init__(self, loop, pipe, protocol, waiter=None, extra=None): self._pipe = pipe self._fileno = pipe.fileno() mode = os.fstat(self._fileno).st_mode - if not (stat.S_ISFIFO(mode) or stat.S_ISSOCK(mode)): + if not (stat.S_ISFIFO(mode) or + stat.S_ISSOCK(mode) or + stat.S_ISCHR(mode)): raise ValueError("Pipe transport is for pipes/sockets only.") _set_nonblocking(self._fileno) self._protocol = protocol self._closing = False - self._loop.add_reader(self._fileno, self._read_ready) self._loop.call_soon(self._protocol.connection_made, self) + # only start reading when connection_made() has been called + self._loop.call_soon(self._loop.add_reader, + self._fileno, self._read_ready) if waiter is not None: - self._loop.call_soon(waiter.set_result, None) + # only wake up the waiter when connection_made() has been called + self._loop.call_soon(waiter._set_result_unless_cancelled, None) + + def __repr__(self): + info = [self.__class__.__name__] + if self._pipe is None: + info.append('closed') + elif self._closing: + info.append('closing') + info.append('fd=%s' % self._fileno) + if self._pipe is not None: + polling = selector_events._test_selector_event( + self._loop._selector, + self._fileno, selectors.EVENT_READ) + if polling: + info.append('polling') + else: + info.append('idle') + else: + info.append('closed') + return '<%s>' % ' '.join(info) def _read_ready(self): try: @@ -203,11 +345,13 @@ def _read_ready(self): except (BlockingIOError, InterruptedError): pass except OSError as exc: - self._fatal_error(exc) + self._fatal_error(exc, 'Fatal read error on pipe transport') else: if data: self._protocol.data_received(data) else: + if self._loop.get_debug(): + logger.info("%r was closed by peer", self) self._closing = True self._loop.remove_reader(self._fileno) self._loop.call_soon(self._protocol.eof_received) @@ -223,9 +367,27 @@ def close(self): if not self._closing: self._close(None) - def _fatal_error(self, exc): + # On Python 3.3 and older, objects with a destructor part of a reference + # cycle are never destroyed. It's not more the case on Python 3.4 thanks + # to the PEP 442. + if sys.version_info >= (3, 4): + def __del__(self): + if self._pipe is not None: + warnings.warn("unclosed transport %r" % self, ResourceWarning) + self._pipe.close() + + def _fatal_error(self, exc, message='Fatal error on pipe transport'): # should be called by exception handler only - logger.exception('Fatal error for %s', self) + if (isinstance(exc, OSError) and exc.errno == errno.EIO): + if self._loop.get_debug(): + logger.debug("%r: %s", self, message, exc_info=True) + else: + self._loop.call_exception_handler({ + 'message': message, + 'exception': exc, + 'transport': self, + 'protocol': self._protocol, + }) self._close(exc) def _close(self, exc): @@ -243,41 +405,79 @@ def _call_connection_lost(self, exc): self._loop = None -class _UnixWritePipeTransport(transports.WriteTransport): +class _UnixWritePipeTransport(transports._FlowControlMixin, + transports.WriteTransport): def __init__(self, loop, pipe, protocol, waiter=None, extra=None): - super().__init__(extra) + super().__init__(extra, loop) self._extra['pipe'] = pipe - self._loop = loop self._pipe = pipe self._fileno = pipe.fileno() mode = os.fstat(self._fileno).st_mode is_socket = stat.S_ISSOCK(mode) - is_pipe = stat.S_ISFIFO(mode) - if not (is_socket or is_pipe): - raise ValueError("Pipe transport is for pipes/sockets only.") + if not (is_socket or + stat.S_ISFIFO(mode) or + stat.S_ISCHR(mode)): + raise ValueError("Pipe transport is only for " + "pipes, sockets and character devices") _set_nonblocking(self._fileno) self._protocol = protocol self._buffer = [] self._conn_lost = 0 self._closing = False # Set when close() or write_eof() called. - # On AIX, the reader trick only works for sockets. - # On other platforms it works for pipes and sockets. - # (Exception: OS X 10.4? Issue #19294.) + self._loop.call_soon(self._protocol.connection_made, self) + + # On AIX, the reader trick (to be notified when the read end of the + # socket is closed) only works for sockets. On other platforms it + # works for pipes and sockets. (Exception: OS X 10.4? Issue #19294.) if is_socket or not sys.platform.startswith("aix"): - self._loop.add_reader(self._fileno, self._read_ready) + # only start reading when connection_made() has been called + self._loop.call_soon(self._loop.add_reader, + self._fileno, self._read_ready) - self._loop.call_soon(self._protocol.connection_made, self) if waiter is not None: - self._loop.call_soon(waiter.set_result, None) + # only wake up the waiter when connection_made() has been called + self._loop.call_soon(waiter._set_result_unless_cancelled, None) + + def __repr__(self): + info = [self.__class__.__name__] + if self._pipe is None: + info.append('closed') + elif self._closing: + info.append('closing') + info.append('fd=%s' % self._fileno) + if self._pipe is not None: + polling = selector_events._test_selector_event( + self._loop._selector, + self._fileno, selectors.EVENT_WRITE) + if polling: + info.append('polling') + else: + info.append('idle') + + bufsize = self.get_write_buffer_size() + info.append('bufsize=%s' % bufsize) + else: + info.append('closed') + return '<%s>' % ' '.join(info) + + def get_write_buffer_size(self): + return sum(len(data) for data in self._buffer) def _read_ready(self): # Pipe was closed by peer. - self._close() + if self._loop.get_debug(): + logger.info("%r was closed by peer", self) + if self._buffer: + self._close(BrokenPipeError()) + else: + self._close() def write(self, data): - assert isinstance(data, bytes), repr(data) + assert isinstance(data, (bytes, bytearray, memoryview)), repr(data) + if isinstance(data, bytearray): + data = memoryview(data) if not data: return @@ -296,7 +496,7 @@ def write(self, data): n = 0 except Exception as exc: self._conn_lost += 1 - self._fatal_error(exc) + self._fatal_error(exc, 'Fatal write error on pipe transport') return if n == len(data): return @@ -305,6 +505,7 @@ def write(self, data): self._loop.add_writer(self._fileno, self._write_ready) self._buffer.append(data) + self._maybe_pause_protocol() def _write_ready(self): data = b''.join(self._buffer) @@ -320,11 +521,12 @@ def _write_ready(self): # Remove writer here, _fatal_error() doesn't it # because _buffer is empty. self._loop.remove_writer(self._fileno) - self._fatal_error(exc) + self._fatal_error(exc, 'Fatal write error on pipe transport') else: if n == len(data): self._loop.remove_writer(self._fileno) - if self._closing: + self._maybe_resume_protocol() # May append to buffer. + if not self._buffer and self._closing: self._loop.remove_reader(self._fileno) self._call_connection_lost(None) return @@ -336,9 +538,6 @@ def _write_ready(self): def can_write_eof(self): return True - # TODO: Make the relationships between write_eof(), close(), - # abort(), _fatal_error() and _close() more straightforward. - def write_eof(self): if self._closing: return @@ -349,16 +548,34 @@ def write_eof(self): self._loop.call_soon(self._call_connection_lost, None) def close(self): - if not self._closing: + if self._pipe is not None and not self._closing: # write_eof is all what we needed to close the write pipe self.write_eof() + # On Python 3.3 and older, objects with a destructor part of a reference + # cycle are never destroyed. It's not more the case on Python 3.4 thanks + # to the PEP 442. + if sys.version_info >= (3, 4): + def __del__(self): + if self._pipe is not None: + warnings.warn("unclosed transport %r" % self, ResourceWarning) + self._pipe.close() + def abort(self): self._close(None) - def _fatal_error(self, exc): + def _fatal_error(self, exc, message='Fatal error on pipe transport'): # should be called by exception handler only - logger.exception('Fatal error for %s', self) + if isinstance(exc, (BrokenPipeError, ConnectionResetError)): + if self._loop.get_debug(): + logger.debug("%r: %s", self, message, exc_info=True) + else: + self._loop.call_exception_handler({ + 'message': message, + 'exception': exc, + 'transport': self, + 'protocol': self._protocol, + }) self._close(exc) def _close(self, exc=None): @@ -379,6 +596,22 @@ def _call_connection_lost(self, exc): self._loop = None +if hasattr(os, 'set_inheritable'): + # Python 3.4 and newer + _set_inheritable = os.set_inheritable +else: + import fcntl + + def _set_inheritable(fd, inheritable): + cloexec_flag = getattr(fcntl, 'FD_CLOEXEC', 1) + + old = fcntl.fcntl(fd, fcntl.F_GETFD) + if not inheritable: + fcntl.fcntl(fd, fcntl.F_SETFD, old | cloexec_flag) + else: + fcntl.fcntl(fd, fcntl.F_SETFD, old & ~cloexec_flag) + + class _UnixSubprocessTransport(base_subprocess.BaseSubprocessTransport): def _start(self, args, shell, stdin, stdout, stderr, bufsize, **kwargs): @@ -390,12 +623,18 @@ def _start(self, args, shell, stdin, stdout, stderr, bufsize, **kwargs): # other end). Notably this is needed on AIX, and works # just fine on other platforms. stdin, stdin_w = self._loop._socketpair() + + # Mark the write end of the stdin pipe as non-inheritable, + # needed by close_fds=False on Python 3.3 and older + # (Python 3.4 implements the PEP 446, socketpair returns + # non-inheritable sockets) + _set_inheritable(stdin_w.fileno(), False) self._proc = subprocess.Popen( args, shell=shell, stdin=stdin, stdout=stdout, stderr=stderr, universal_newlines=False, bufsize=bufsize, **kwargs) if stdin_w is not None: stdin.close() - self._proc.stdin = open(stdin_w.detach(), 'rb', buffering=bufsize) + self._proc.stdin = open(stdin_w.detach(), 'wb', buffering=bufsize) class AbstractChildWatcher: @@ -428,7 +667,7 @@ def add_child_handler(self, pid, callback, *args): process 'pid' terminates. Specifying another callback for the same process replaces the previous handler. - Note: callback() must be thread-safe + Note: callback() must be thread-safe. """ raise NotImplementedError() @@ -499,8 +738,14 @@ def attach_loop(self, loop): def _sig_chld(self): try: self._do_waitpid_all() - except Exception: - logger.exception('Unknown exception in SIGCHLD handler') + except Exception as exc: + # self._loop should always be available here + # as '_sig_chld' is added as a signal handler + # in 'attach_loop' + self._loop.call_exception_handler({ + 'message': 'Unknown exception in SIGCHLD handler', + 'exception': exc, + }) def _compute_returncode(self, status): if os.WIFSIGNALED(status): @@ -542,7 +787,7 @@ def __exit__(self, a, b, c): pass def add_child_handler(self, pid, callback, *args): - self._callbacks[pid] = callback, args + self._callbacks[pid] = (callback, args) # Prevent a race condition in case the child is already terminated. self._do_waitpid(pid) @@ -578,13 +823,18 @@ def _do_waitpid(self, expected_pid): return returncode = self._compute_returncode(status) + if self._loop.get_debug(): + logger.debug('process %s exited with returncode %s', + expected_pid, returncode) try: callback, args = self._callbacks.pop(pid) except KeyError: # pragma: no cover # May happen if .remove_child_handler() is called # after os.waitpid() returns. - pass + if self._loop.get_debug(): + logger.warning("Child watcher got an unexpected pid: %r", + pid, exc_info=True) else: callback(pid, returncode, *args) @@ -633,22 +883,16 @@ def __exit__(self, a, b, c): def add_child_handler(self, pid, callback, *args): assert self._forks, "Must use the context manager" + with self._lock: + try: + returncode = self._zombies.pop(pid) + except KeyError: + # The child is running. + self._callbacks[pid] = callback, args + return - self._callbacks[pid] = callback, args - - try: - # Ensure that the child is not already terminated. - # (raise KeyError if still alive) - returncode = self._zombies.pop(pid) - - # Child is dead, therefore we can fire the callback immediately. - # First we remove it from the dict. - # (raise KeyError if .remove_child_handler() was called in-between) - del self._callbacks[pid] - except KeyError: - pass - else: - callback(pid, returncode, *args) + # The child is dead already. We can fire the callback. + callback(pid, returncode, *args) def remove_child_handler(self, pid): try: @@ -673,16 +917,26 @@ def _do_waitpid_all(self): returncode = self._compute_returncode(status) - try: - callback, args = self._callbacks.pop(pid) - except KeyError: - # unknown child - with self._lock: + with self._lock: + try: + callback, args = self._callbacks.pop(pid) + except KeyError: + # unknown child if self._forks: # It may not be registered yet. self._zombies[pid] = returncode + if self._loop.get_debug(): + logger.debug('unknown process %s exited ' + 'with returncode %s', + pid, returncode) continue + callback = None + else: + if self._loop.get_debug(): + logger.debug('process %s exited with returncode %s', + pid, returncode) + if callback is None: logger.warning( "Caught subprocess termination from unknown pid: " "%d -> %d", pid, returncode) @@ -691,7 +945,7 @@ def _do_waitpid_all(self): class _UnixDefaultEventLoopPolicy(events.BaseDefaultEventLoopPolicy): - """XXX""" + """UNIX event loop policy with a watcher for child processes.""" _loop_factory = _UnixSelectorEventLoop def __init__(self): @@ -721,7 +975,7 @@ def set_event_loop(self, loop): self._watcher.attach_loop(loop) def get_child_watcher(self): - """Get the child watcher + """Get the watcher for child processes. If not yet set, a SafeChildWatcher object is automatically created. """ @@ -731,7 +985,7 @@ def get_child_watcher(self): return self._watcher def set_child_watcher(self, watcher): - """Set the child watcher""" + """Set the watcher for child processes.""" assert watcher is None or isinstance(watcher, AbstractChildWatcher) diff --git a/Lib/asyncio/windows_events.py b/Lib/asyncio/windows_events.py index b2ed2415e4ba..f311e4631558 100644 --- a/Lib/asyncio/windows_events.py +++ b/Lib/asyncio/windows_events.py @@ -1,11 +1,11 @@ -"""Selector and proactor eventloops for Windows.""" +"""Selector and proactor event loops for Windows.""" +import _winapi import errno +import math import socket -import subprocess -import weakref import struct -import _winapi +import weakref from . import events from . import base_subprocess @@ -14,8 +14,9 @@ from . import selector_events from . import tasks from . import windows_utils -from .log import logger from . import _overlapped +from .coroutines import coroutine +from .log import logger __all__ = ['SelectorEventLoop', 'ProactorEventLoop', 'IocpProactor', @@ -28,6 +29,12 @@ ERROR_CONNECTION_REFUSED = 1225 ERROR_CONNECTION_ABORTED = 1236 +# Initial delay in seconds for connect_pipe() before retrying to connect +CONNECT_PIPE_INIT_DELAY = 0.001 + +# Maximum delay in seconds for connect_pipe() before retrying to connect +CONNECT_PIPE_MAX_DELAY = 0.100 + class _OverlappedFuture(futures.Future): """Subclass of Future which represents an overlapped operation. @@ -37,30 +44,189 @@ class _OverlappedFuture(futures.Future): def __init__(self, ov, *, loop=None): super().__init__(loop=loop) - self.ov = ov + if self._source_traceback: + del self._source_traceback[-1] + self._ov = ov + + def _repr_info(self): + info = super()._repr_info() + if self._ov is not None: + state = 'pending' if self._ov.pending else 'completed' + info.insert(1, 'overlapped=<%s, %#x>' % (state, self._ov.address)) + return info + + def _cancel_overlapped(self): + if self._ov is None: + return + try: + self._ov.cancel() + except OSError as exc: + context = { + 'message': 'Cancelling an overlapped future failed', + 'exception': exc, + 'future': self, + } + if self._source_traceback: + context['source_traceback'] = self._source_traceback + self._loop.call_exception_handler(context) + self._ov = None def cancel(self): - try: - self.ov.cancel() - except OSError: - pass + self._cancel_overlapped() return super().cancel() + def set_exception(self, exception): + super().set_exception(exception) + self._cancel_overlapped() -class _WaitHandleFuture(futures.Future): + def set_result(self, result): + super().set_result(result) + self._ov = None + + +class _BaseWaitHandleFuture(futures.Future): """Subclass of Future which represents a wait handle.""" - def __init__(self, wait_handle, *, loop=None): + def __init__(self, ov, handle, wait_handle, *, loop=None): super().__init__(loop=loop) + if self._source_traceback: + del self._source_traceback[-1] + # Keep a reference to the Overlapped object to keep it alive until the + # wait is unregistered + self._ov = ov + self._handle = handle self._wait_handle = wait_handle + # Should we call UnregisterWaitEx() if the wait completes + # or is cancelled? + self._registered = True + + def _poll(self): + # non-blocking wait: use a timeout of 0 millisecond + return (_winapi.WaitForSingleObject(self._handle, 0) == + _winapi.WAIT_OBJECT_0) + + def _repr_info(self): + info = super()._repr_info() + info.append('handle=%#x' % self._handle) + if self._handle is not None: + state = 'signaled' if self._poll() else 'waiting' + info.append(state) + if self._wait_handle is not None: + info.append('wait_handle=%#x' % self._wait_handle) + return info + + def _unregister_wait_cb(self, fut): + # The wait was unregistered: it's not safe to destroy the Overlapped + # object + self._ov = None + + def _unregister_wait(self): + if not self._registered: + return + self._registered = False + + wait_handle = self._wait_handle + self._wait_handle = None + try: + _overlapped.UnregisterWait(wait_handle) + except OSError as exc: + if exc.winerror != _overlapped.ERROR_IO_PENDING: + context = { + 'message': 'Failed to unregister the wait handle', + 'exception': exc, + 'future': self, + } + if self._source_traceback: + context['source_traceback'] = self._source_traceback + self._loop.call_exception_handler(context) + return + # ERROR_IO_PENDING means that the unregister is pending + + self._unregister_wait_cb(None) + def cancel(self): - super().cancel() + self._unregister_wait() + return super().cancel() + + def set_exception(self, exception): + self._unregister_wait() + super().set_exception(exception) + + def set_result(self, result): + self._unregister_wait() + super().set_result(result) + + +class _WaitCancelFuture(_BaseWaitHandleFuture): + """Subclass of Future which represents a wait for the cancellation of a + _WaitHandleFuture using an event. + """ + + def __init__(self, ov, event, wait_handle, *, loop=None): + super().__init__(ov, event, wait_handle, loop=loop) + + self._done_callback = None + + def cancel(self): + raise RuntimeError("_WaitCancelFuture must not be cancelled") + + def _schedule_callbacks(self): + super(_WaitCancelFuture, self)._schedule_callbacks() + if self._done_callback is not None: + self._done_callback(self) + + +class _WaitHandleFuture(_BaseWaitHandleFuture): + def __init__(self, ov, handle, wait_handle, proactor, *, loop=None): + super().__init__(ov, handle, wait_handle, loop=loop) + self._proactor = proactor + self._unregister_proactor = True + self._event = _overlapped.CreateEvent(None, True, False, None) + self._event_fut = None + + def _unregister_wait_cb(self, fut): + if self._event is not None: + _winapi.CloseHandle(self._event) + self._event = None + self._event_fut = None + + # If the wait was cancelled, the wait may never be signalled, so + # it's required to unregister it. Otherwise, IocpProactor.close() will + # wait forever for an event which will never come. + # + # If the IocpProactor already received the event, it's safe to call + # _unregister() because we kept a reference to the Overlapped object + # which is used as an unique key. + self._proactor._unregister(self._ov) + self._proactor = None + + super()._unregister_wait_cb(fut) + + def _unregister_wait(self): + if not self._registered: + return + self._registered = False + + wait_handle = self._wait_handle + self._wait_handle = None try: - _overlapped.UnregisterWait(self._wait_handle) - except OSError as e: - if e.winerror != _overlapped.ERROR_IO_PENDING: - raise + _overlapped.UnregisterWaitEx(wait_handle, self._event) + except OSError as exc: + if exc.winerror != _overlapped.ERROR_IO_PENDING: + context = { + 'message': 'Failed to unregister the wait handle', + 'exception': exc, + 'future': self, + } + if self._source_traceback: + context['source_traceback'] = self._source_traceback + self._loop.call_exception_handler(context) + return + # ERROR_IO_PENDING is not an error, the wait was unregistered + + self._event_fut = self._proactor._wait_cancel(self._event, + self._unregister_wait_cb) class PipeServer(object): @@ -71,6 +237,11 @@ class PipeServer(object): def __init__(self, address): self._address = address self._free_instances = weakref.WeakSet() + # initialize the pipe attribute before calling _server_pipe_handle() + # because this function can raise an exception and the destructor calls + # the close() method + self._pipe = None + self._accept_pipe_future = None self._pipe = self._server_pipe_handle(True) def _get_unconnected_pipe(self): @@ -83,7 +254,7 @@ def _get_unconnected_pipe(self): def _server_pipe_handle(self, first): # Return a wrapper for a new pipe handle. - if self._address is None: + if self.closed(): return None flags = _winapi.PIPE_ACCESS_DUPLEX | _winapi.FILE_FLAG_OVERLAPPED if first: @@ -99,7 +270,13 @@ def _server_pipe_handle(self, first): self._free_instances.add(pipe) return pipe + def closed(self): + return (self._address is None) + def close(self): + if self._accept_pipe_future is not None: + self._accept_pipe_future.cancel() + self._accept_pipe_future = None # Close all instances which have not been connected to by a client. if self._address is not None: for pipe in self._free_instances: @@ -129,7 +306,7 @@ def __init__(self, proactor=None): def _socketpair(self): return windows_utils.socketpair() - @tasks.coroutine + @coroutine def create_pipe_connection(self, protocol_factory, address): f = self._proactor.connect_pipe(address) pipe = yield from f @@ -138,51 +315,77 @@ def create_pipe_connection(self, protocol_factory, address): extra={'addr': address}) return trans, protocol - @tasks.coroutine + @coroutine def start_serving_pipe(self, protocol_factory, address): server = PipeServer(address) - def loop(f=None): + def loop_accept_pipe(f=None): pipe = None try: if f: pipe = f.result() server._free_instances.discard(pipe) + + if server.closed(): + # A client connected before the server was closed: + # drop the client (close the pipe) and exit + pipe.close() + return + protocol = protocol_factory() self._make_duplex_pipe_transport( pipe, protocol, extra={'addr': address}) + pipe = server._get_unconnected_pipe() if pipe is None: return + f = self._proactor.accept_pipe(pipe) - except OSError: + except OSError as exc: if pipe and pipe.fileno() != -1: - logger.exception('Pipe accept failed') + self.call_exception_handler({ + 'message': 'Pipe accept failed', + 'exception': exc, + 'pipe': pipe, + }) pipe.close() + elif self._debug: + logger.warning("Accept pipe failed on pipe %r", + pipe, exc_info=True) except futures.CancelledError: if pipe: pipe.close() else: - f.add_done_callback(loop) + server._accept_pipe_future = f + f.add_done_callback(loop_accept_pipe) - self.call_soon(loop) + self.call_soon(loop_accept_pipe) return [server] - def _stop_serving(self, server): - server.close() - - @tasks.coroutine + @coroutine def _make_subprocess_transport(self, protocol, args, shell, stdin, stdout, stderr, bufsize, extra=None, **kwargs): + waiter = futures.Future(loop=self) transp = _WindowsSubprocessTransport(self, protocol, args, shell, stdin, stdout, stderr, bufsize, - extra=None, **kwargs) - yield from transp._post_init() - return transp + waiter=waiter, extra=extra, + **kwargs) + try: + yield from waiter + except Exception as exc: + # Workaround CPython bug #23353: using yield/yield-from in an + # except block of a generator doesn't clear properly sys.exc_info() + err = exc + else: + err = None + + if err is not None: + transp.close() + yield from transp._wait() + raise err - def _subprocess_closed(self, transport): - pass + return transp class IocpProactor: @@ -195,8 +398,14 @@ def __init__(self, concurrency=0xffffffff): _overlapped.INVALID_HANDLE_VALUE, NULL, 0, concurrency) self._cache = {} self._registered = weakref.WeakSet() + self._unregistered = [] self._stopped_serving = weakref.WeakSet() + def __repr__(self): + return ('<%s overlapped#=%s result#=%s>' + % (self.__class__.__name__, len(self._cache), + len(self._results))) + def set_loop(self, loop): self._loop = loop @@ -207,15 +416,23 @@ def select(self, timeout=None): self._results = [] return tmp + def _result(self, value): + fut = futures.Future(loop=self._loop) + fut.set_result(value) + return fut + def recv(self, conn, nbytes, flags=0): self._register_with_iocp(conn) ov = _overlapped.Overlapped(NULL) - if isinstance(conn, socket.socket): - ov.WSARecv(conn.fileno(), nbytes, flags) - else: - ov.ReadFile(conn.fileno(), nbytes) + try: + if isinstance(conn, socket.socket): + ov.WSARecv(conn.fileno(), nbytes, flags) + else: + ov.ReadFile(conn.fileno(), nbytes) + except BrokenPipeError: + return self._result(b'') - def finish(trans, key, ov): + def finish_recv(trans, key, ov): try: return ov.getresult() except OSError as exc: @@ -224,7 +441,7 @@ def finish(trans, key, ov): else: raise - return self._register(ov, conn, finish) + return self._register(ov, conn, finish_recv) def send(self, conn, buf, flags=0): self._register_with_iocp(conn) @@ -234,7 +451,7 @@ def send(self, conn, buf, flags=0): else: ov.WriteFile(conn.fileno(), buf) - def finish(trans, key, ov): + def finish_send(trans, key, ov): try: return ov.getresult() except OSError as exc: @@ -243,7 +460,7 @@ def finish(trans, key, ov): else: raise - return self._register(ov, conn, finish) + return self._register(ov, conn, finish_send) def accept(self, listener): self._register_with_iocp(listener) @@ -260,7 +477,19 @@ def finish_accept(trans, key, ov): conn.settimeout(listener.gettimeout()) return conn, conn.getpeername() - return self._register(ov, listener, finish_accept) + @coroutine + def accept_coro(future, conn): + # Coroutine closing the accept socket if the future is cancelled + try: + yield from future + except futures.CancelledError: + conn.close() + raise + + future = self._register(ov, listener, finish_accept) + coro = accept_coro(future, conn) + tasks.async(coro, loop=self._loop) + return future def connect(self, conn, address): self._register_with_iocp(conn) @@ -288,62 +517,85 @@ def finish_connect(trans, key, ov): def accept_pipe(self, pipe): self._register_with_iocp(pipe) ov = _overlapped.Overlapped(NULL) - ov.ConnectNamedPipe(pipe.fileno()) + connected = ov.ConnectNamedPipe(pipe.fileno()) - def finish(trans, key, ov): + if connected: + # ConnectNamePipe() failed with ERROR_PIPE_CONNECTED which means + # that the pipe is connected. There is no need to wait for the + # completion of the connection. + return self._result(pipe) + + def finish_accept_pipe(trans, key, ov): ov.getresult() return pipe - return self._register(ov, pipe, finish) + return self._register(ov, pipe, finish_accept_pipe) + @coroutine def connect_pipe(self, address): - ov = _overlapped.Overlapped(NULL) - ov.WaitNamedPipeAndConnect(address, self._iocp, ov.address) - - def finish(err, handle, ov): - # err, handle were arguments passed to PostQueuedCompletionStatus() - # in a function run in a thread pool. - if err == _overlapped.ERROR_SEM_TIMEOUT: - # Connection did not succeed within time limit. - msg = _overlapped.FormatMessage(err) - raise ConnectionRefusedError(0, msg, None, err) - elif err != 0: - msg = _overlapped.FormatMessage(err) - raise OSError(0, msg, None, err) - else: - return windows_utils.PipeHandle(handle) + delay = CONNECT_PIPE_INIT_DELAY + while True: + # Unfortunately there is no way to do an overlapped connect to a pipe. + # Call CreateFile() in a loop until it doesn't fail with + # ERROR_PIPE_BUSY + try: + handle = _overlapped.ConnectPipe(address) + break + except OSError as exc: + if exc.winerror != _overlapped.ERROR_PIPE_BUSY: + raise - return self._register(ov, None, finish, wait_for_post=True) + # ConnectPipe() failed with ERROR_PIPE_BUSY: retry later + delay = min(delay * 2, CONNECT_PIPE_MAX_DELAY) + yield from tasks.sleep(delay, loop=self._loop) + + return windows_utils.PipeHandle(handle) def wait_for_handle(self, handle, timeout=None): + """Wait for a handle. + + Return a Future object. The result of the future is True if the wait + completed, or False if the wait did not complete (on timeout). + """ + return self._wait_for_handle(handle, timeout, False) + + def _wait_cancel(self, event, done_callback): + fut = self._wait_for_handle(event, None, True) + # add_done_callback() cannot be used because the wait may only complete + # in IocpProactor.close(), while the event loop is not running. + fut._done_callback = done_callback + return fut + + def _wait_for_handle(self, handle, timeout, _is_cancel): if timeout is None: ms = _winapi.INFINITE else: - ms = int(timeout * 1000 + 0.5) + # RegisterWaitForSingleObject() has a resolution of 1 millisecond, + # round away from zero to wait *at least* timeout seconds. + ms = math.ceil(timeout * 1e3) # We only create ov so we can use ov.address as a key for the cache. ov = _overlapped.Overlapped(NULL) - wh = _overlapped.RegisterWaitWithQueue( + wait_handle = _overlapped.RegisterWaitWithQueue( handle, self._iocp, ov.address, ms) - f = _WaitHandleFuture(wh, loop=self._loop) + if _is_cancel: + f = _WaitCancelFuture(ov, handle, wait_handle, loop=self._loop) + else: + f = _WaitHandleFuture(ov, handle, wait_handle, self, + loop=self._loop) + if f._source_traceback: + del f._source_traceback[-1] - def finish(trans, key, ov): - if not f.cancelled(): - try: - _overlapped.UnregisterWait(wh) - except OSError as e: - if e.winerror != _overlapped.ERROR_IO_PENDING: - raise + def finish_wait_for_handle(trans, key, ov): # Note that this second wait means that we should only use # this with handles types where a successful wait has no # effect. So events or processes are all right, but locks # or semaphores are not. Also note if the handle is # signalled and then quickly reset, then we may return # False even though we have not timed out. - return (_winapi.WaitForSingleObject(handle, 0) == - _winapi.WAIT_OBJECT_0) + return f._poll() - self._cache[ov.address] = (f, ov, None, finish) + self._cache[ov.address] = (f, ov, 0, finish_wait_for_handle) return f def _register_with_iocp(self, obj): @@ -356,17 +608,14 @@ def _register_with_iocp(self, obj): # to avoid sending notifications to completion port of ops # that succeed immediately. - def _register(self, ov, obj, callback, wait_for_post=False): + def _register(self, ov, obj, callback): # Return a future which will be set with the result of the # operation when it completes. The future's value is actually # the value returned by callback(). f = _OverlappedFuture(ov, loop=self._loop) - if ov.pending or wait_for_post: - # Register the overlapped operation for later. Note that - # we only store obj to prevent it from being garbage - # collected too early. - self._cache[ov.address] = (f, ov, obj, callback) - else: + if f._source_traceback: + del f._source_traceback[-1] + if not ov.pending: # The operation has completed, so no need to postpone the # work. We cannot take this short cut if we need the # NumberOfBytes, CompletionKey values returned by @@ -377,8 +626,27 @@ def _register(self, ov, obj, callback, wait_for_post=False): f.set_exception(e) else: f.set_result(value) + # Even if GetOverlappedResult() was called, we have to wait for the + # notification of the completion in GetQueuedCompletionStatus(). + # Register the overlapped operation to keep a reference to the + # OVERLAPPED object, otherwise the memory is freed and Windows may + # read uninitialized memory. + + # Register the overlapped operation for later. Note that + # we only store obj to prevent it from being garbage + # collected too early. + self._cache[ov.address] = (f, ov, obj, callback) return f + def _unregister(self, ov): + """Unregister an overlapped object. + + Call this method when its future has been cancelled. The event can + already be signalled (pending in the proactor event queue). It is also + safe if the event is never signalled (because it was cancelled). + """ + self._unregistered.append(ov) + def _get_accept_socket(self, family): s = socket.socket(family) s.settimeout(0) @@ -390,26 +658,41 @@ def _poll(self, timeout=None): elif timeout < 0: raise ValueError("negative timeout") else: - ms = int(timeout * 1000 + 0.5) + # GetQueuedCompletionStatus() has a resolution of 1 millisecond, + # round away from zero to wait *at least* timeout seconds. + ms = math.ceil(timeout * 1e3) if ms >= INFINITE: raise ValueError("timeout too big") + while True: status = _overlapped.GetQueuedCompletionStatus(self._iocp, ms) if status is None: - return + break + ms = 0 + err, transferred, key, address = status try: f, ov, obj, callback = self._cache.pop(address) except KeyError: + if self._loop.get_debug(): + self._loop.call_exception_handler({ + 'message': ('GetQueuedCompletionStatus() returned an ' + 'unexpected event'), + 'status': ('err=%s transferred=%s key=%#x address=%#x' + % (err, transferred, key, address)), + }) + # key is either zero, or it is used to return a pipe # handle which should be closed to avoid a leak. if key not in (0, _overlapped.INVALID_HANDLE_VALUE): _winapi.CloseHandle(key) - ms = 0 continue + if obj in self._stopped_serving: f.cancel() - elif not f.cancelled(): + # Don't call the callback if _register() already read the result or + # if the overlapped has been cancelled + elif not f.done(): try: value = callback(transferred, key, ov) except OSError as e: @@ -418,7 +701,11 @@ def _poll(self, timeout=None): else: f.set_result(value) self._results.append(f) - ms = 0 + + # Remove unregisted futures + for ov in self._unregistered: + self._cache.pop(ov.address, None) + self._unregistered.clear() def _stop_serving(self, obj): # obj is a socket or pipe handle. It will be closed in @@ -428,17 +715,26 @@ def _stop_serving(self, obj): def close(self): # Cancel remaining registered operations. - for address, (f, ov, obj, callback) in list(self._cache.items()): - if obj is None: - # The operation was started with connect_pipe() which - # queues a task to Windows' thread pool. This cannot - # be cancelled, so just forget it. - del self._cache[address] + for address, (fut, ov, obj, callback) in list(self._cache.items()): + if fut.cancelled(): + # Nothing to do with cancelled futures + pass + elif isinstance(fut, _WaitCancelFuture): + # _WaitCancelFuture must not be cancelled + pass else: try: - ov.cancel() - except OSError: - pass + fut.cancel() + except OSError as exc: + if self._loop is not None: + context = { + 'message': 'Cancelling a future failed', + 'exception': exc, + 'future': fut, + } + if fut._source_traceback: + context['source_traceback'] = fut._source_traceback + self._loop.call_exception_handler(context) while self._cache: if not self._poll(1): @@ -449,6 +745,9 @@ def close(self): _winapi.CloseHandle(self._iocp) self._iocp = None + def __del__(self): + self.close() + class _WindowsSubprocessTransport(base_subprocess.BaseSubprocessTransport): diff --git a/Lib/asyncio/windows_utils.py b/Lib/asyncio/windows_utils.py index aa1c06480673..870cd13abe6c 100644 --- a/Lib/asyncio/windows_utils.py +++ b/Lib/asyncio/windows_utils.py @@ -7,13 +7,14 @@ if sys.platform != 'win32': # pragma: no cover raise ImportError('win32 only') -import socket +import _winapi import itertools import msvcrt import os +import socket import subprocess import tempfile -import _winapi +import warnings __all__ = ['socketpair', 'pipe', 'Popen', 'PIPE', 'PipeHandle'] @@ -28,34 +29,52 @@ _mmap_counter = itertools.count() -# Replacement for socket.socketpair() - - -def socketpair(family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0): - """A socket pair usable as a self-pipe, for Windows. - - Origin: https://gist.github.com/4325783, by Geert Jansen. Public domain. - """ - # We create a connected TCP socket. Note the trick with setblocking(0) - # that prevents us from having to create a thread. - lsock = socket.socket(family, type, proto) - lsock.bind(('localhost', 0)) - lsock.listen(1) - addr, port = lsock.getsockname() - csock = socket.socket(family, type, proto) - csock.setblocking(False) - try: - csock.connect((addr, port)) - except (BlockingIOError, InterruptedError): - pass - except Exception: - lsock.close() - csock.close() - raise - ssock, _ = lsock.accept() - csock.setblocking(True) - lsock.close() - return (ssock, csock) +if hasattr(socket, 'socketpair'): + # Since Python 3.5, socket.socketpair() is now also available on Windows + socketpair = socket.socketpair +else: + # Replacement for socket.socketpair() + def socketpair(family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0): + """A socket pair usable as a self-pipe, for Windows. + + Origin: https://gist.github.com/4325783, by Geert Jansen. + Public domain. + """ + if family == socket.AF_INET: + host = '127.0.0.1' + elif family == socket.AF_INET6: + host = '::1' + else: + raise ValueError("Only AF_INET and AF_INET6 socket address " + "families are supported") + if type != socket.SOCK_STREAM: + raise ValueError("Only SOCK_STREAM socket type is supported") + if proto != 0: + raise ValueError("Only protocol zero is supported") + + # We create a connected TCP socket. Note the trick with setblocking(0) + # that prevents us from having to create a thread. + lsock = socket.socket(family, type, proto) + try: + lsock.bind((host, 0)) + lsock.listen(1) + # On IPv6, ignore flow_info and scope_id + addr, port = lsock.getsockname()[:2] + csock = socket.socket(family, type, proto) + try: + csock.setblocking(False) + try: + csock.connect((addr, port)) + except (BlockingIOError, InterruptedError): + pass + csock.setblocking(True) + ssock, _ = lsock.accept() + except: + csock.close() + raise + finally: + lsock.close() + return (ssock, csock) # Replacement for os.pipe() using handles instead of fds @@ -117,19 +136,31 @@ class PipeHandle: def __init__(self, handle): self._handle = handle + def __repr__(self): + if self._handle is not None: + handle = 'handle=%r' % self._handle + else: + handle = 'closed' + return '<%s %s>' % (self.__class__.__name__, handle) + @property def handle(self): return self._handle def fileno(self): + if self._handle is None: + raise ValueError("I/O operatioon on closed pipe") return self._handle def close(self, *, CloseHandle=_winapi.CloseHandle): - if self._handle != -1: + if self._handle is not None: CloseHandle(self._handle) - self._handle = -1 + self._handle = None - __del__ = close + def __del__(self): + if self._handle is not None: + warnings.warn("unclosed %r" % self, ResourceWarning) + self.close() def __enter__(self): return self diff --git a/Lib/asyncore.py b/Lib/asyncore.py index 75481ddde059..68efd45f858a 100644 --- a/Lib/asyncore.py +++ b/Lib/asyncore.py @@ -57,8 +57,8 @@ ENOTCONN, ESHUTDOWN, EISCONN, EBADF, ECONNABORTED, EPIPE, EAGAIN, \ errorcode -_DISCONNECTED = frozenset((ECONNRESET, ENOTCONN, ESHUTDOWN, ECONNABORTED, EPIPE, - EBADF)) +_DISCONNECTED = frozenset({ECONNRESET, ENOTCONN, ESHUTDOWN, ECONNABORTED, EPIPE, + EBADF}) try: socket_map @@ -220,7 +220,7 @@ class dispatcher: connecting = False closing = False addr = None - ignore_log_types = frozenset(['warning']) + ignore_log_types = frozenset({'warning'}) def __init__(self, sock=None, map=None): if map is None: @@ -255,7 +255,7 @@ def __init__(self, sock=None, map=None): self.socket = None def __repr__(self): - status = [self.__class__.__module__+"."+self.__class__.__name__] + status = [self.__class__.__module__+"."+self.__class__.__qualname__] if self.accepting and self.addr: status.append('listening') elif self.connected: @@ -404,20 +404,6 @@ def close(self): if why.args[0] not in (ENOTCONN, EBADF): raise - # cheap inheritance, used to pass all other attribute - # references to the underlying socket object. - def __getattr__(self, attr): - try: - retattr = getattr(self.socket, attr) - except AttributeError: - raise AttributeError("%s instance has no attribute '%s'" - %(self.__class__.__name__, attr)) - else: - msg = "%(me)s.%(attr)s is deprecated; use %(me)s.socket.%(attr)s " \ - "instead" % {'me' : self.__class__.__name__, 'attr' : attr} - warnings.warn(msg, DeprecationWarning, stacklevel=2) - return retattr - # log and log_info may be overridden to provide more sophisticated # logging and warning methods. In general, log is for 'hit' logging # and 'log_info' is for informational, warning and error logging. @@ -604,8 +590,6 @@ def close_all(map=None, ignore_all=False): # Regardless, this is useful for pipes, and stdin/stdout... if os.name == 'posix': - import fcntl - class file_wrapper: # Here we override just enough to make a file # look like a socket for the purposes of asyncore. @@ -614,6 +598,11 @@ class file_wrapper: def __init__(self, fd): self.fd = os.dup(fd) + def __del__(self): + if self.fd >= 0: + warnings.warn("unclosed file %r" % self, ResourceWarning) + self.close() + def recv(self, *args): return os.read(self.fd, *args) @@ -632,7 +621,10 @@ def getsockopt(self, level, optname, buflen=None): write = send def close(self): + if self.fd < 0: + return os.close(self.fd) + self.fd = -1 def fileno(self): return self.fd @@ -648,9 +640,7 @@ def __init__(self, fd, map=None): pass self.set_file(fd) # set it to non-blocking mode - flags = fcntl.fcntl(fd, fcntl.F_GETFL, 0) - flags = flags | os.O_NONBLOCK - fcntl.fcntl(fd, fcntl.F_SETFL, flags) + os.set_blocking(fd, False) def set_file(self, fd): self.socket = file_wrapper(fd) diff --git a/Lib/base64.py b/Lib/base64.py index 84818cf078bc..36c68a6862e1 100755 --- a/Lib/base64.py +++ b/Lib/base64.py @@ -9,7 +9,6 @@ import re import struct import binascii -import itertools __all__ = [ @@ -139,15 +138,22 @@ def urlsafe_b64decode(s): # Base32 encoding/decoding must be done in Python _b32alphabet = b'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567' -_b32tab = [bytes([i]) for i in _b32alphabet] -_b32tab2 = [a + b for a in _b32tab for b in _b32tab] -_b32rev = {v: k for k, v in enumerate(_b32alphabet)} +_b32tab2 = None +_b32rev = None def b32encode(s): """Encode a byte string using Base32. s is the byte string to encode. The encoded byte string is returned. """ + global _b32tab2 + # Delay the initialization of the table to not waste memory + # if the function is never called + if _b32tab2 is None: + b32tab = [bytes((i,)) for i in _b32alphabet] + _b32tab2 = [a + b for a in b32tab for b in b32tab] + b32tab = None + if not isinstance(s, bytes_types): s = memoryview(s).tobytes() leftover = len(s) % 5 @@ -194,6 +200,11 @@ def b32decode(s, casefold=False, map01=None): the input is incorrectly padded or if there are non-alphabet characters present in the input. """ + global _b32rev + # Delay the initialization of the table to not waste memory + # if the function is never called + if _b32rev is None: + _b32rev = {v: k for k, v in enumerate(_b32alphabet)} s = _bytes_from_decode_data(s) if len(s) % 8: raise binascii.Error('Incorrect padding') @@ -275,6 +286,11 @@ def b16decode(s, casefold=False): # Ascii85 encoding/decoding # +_a85chars = None +_a85chars2 = None +_A85START = b"<~" +_A85END = b"~>" + def _85encode(b, chars, chars2, pad=False, foldnuls=False, foldspaces=False): # Helper function for a85encode and b85encode if not isinstance(b, bytes_types): @@ -285,8 +301,6 @@ def _85encode(b, chars, chars2, pad=False, foldnuls=False, foldspaces=False): b = b + b'\0' * padding words = struct.Struct('!%dI' % (len(b) // 4)).unpack(b) - a85chars2 = _a85chars2 - a85chars = _a85chars chunks = [b'z' if foldnuls and not word else b'y' if foldspaces and word == 0x20202020 else (chars2[word // 614125] + @@ -301,11 +315,6 @@ def _85encode(b, chars, chars2, pad=False, foldnuls=False, foldspaces=False): return b''.join(chunks) -_A85START = b"<~" -_A85END = b"~>" -_a85chars = [bytes([i]) for i in range(33, 118)] -_a85chars2 = [(a + b) for a in _a85chars for b in _a85chars] - def a85encode(b, *, foldspaces=False, wrapcol=0, pad=False, adobe=False): """Encode a byte string using Ascii85. @@ -325,6 +334,13 @@ def a85encode(b, *, foldspaces=False, wrapcol=0, pad=False, adobe=False): adobe controls whether the encoded byte sequence is framed with <~ and ~>, which is used by the Adobe implementation. """ + global _a85chars, _a85chars2 + # Delay the initialization of tables to not waste memory + # if the function is never called + if _a85chars is None: + _a85chars = [bytes((i,)) for i in range(33, 118)] + _a85chars2 = [(a + b) for a in _a85chars for b in _a85chars] + result = _85encode(b, _a85chars, _a85chars2, pad, True, foldspaces) if adobe: @@ -362,7 +378,7 @@ def a85decode(b, *, foldspaces=False, adobe=False, ignorechars=b' \t\n\r\v'): if adobe: if not (b.startswith(_A85START) and b.endswith(_A85END)): raise ValueError("Ascii85 encoded byte sequences must be bracketed " - "by {} and {}".format(_A85START, _A85END)) + "by {!r} and {!r}".format(_A85START, _A85END)) b = b[2:-2] # Strip off start/end markers # # We have to go through this stepwise, so as to ignore spaces and handle @@ -409,10 +425,10 @@ def a85decode(b, *, foldspaces=False, adobe=False, ignorechars=b' \t\n\r\v'): # The following code is originally taken (with permission) from Mercurial -_b85chars = b"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ - b"abcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~" -_b85chars = [bytes([i]) for i in _b85chars] -_b85chars2 = [(a + b) for a in _b85chars for b in _b85chars] +_b85alphabet = (b"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" + b"abcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~") +_b85chars = None +_b85chars2 = None _b85dec = None def b85encode(b, pad=False): @@ -421,17 +437,25 @@ def b85encode(b, pad=False): If pad is true, the input is padded with "\0" so its length is a multiple of 4 characters before encoding. """ + global _b85chars, _b85chars2 + # Delay the initialization of tables to not waste memory + # if the function is never called + if _b85chars is None: + _b85chars = [bytes((i,)) for i in _b85alphabet] + _b85chars2 = [(a + b) for a in _b85chars for b in _b85chars] return _85encode(b, _b85chars, _b85chars2, pad) def b85decode(b): """Decode base85-encoded byte array""" - b = _bytes_from_decode_data(b) global _b85dec + # Delay the initialization of tables to not waste memory + # if the function is never called if _b85dec is None: _b85dec = [None] * 256 - for i, c in enumerate(_b85chars): - _b85dec[c[0]] = i + for i, c in enumerate(_b85alphabet): + _b85dec[c] = i + b = _bytes_from_decode_data(b) padding = (-len(b)) % 5 b = b + b'~' * padding out = [] diff --git a/Lib/bz2.py b/Lib/bz2.py index 6bc611e71fc7..6f47bfaf6cae 100644 --- a/Lib/bz2.py +++ b/Lib/bz2.py @@ -207,8 +207,15 @@ def _fill_buffer(self): if self._decompressor.eof: # Continue to next stream. self._decompressor = BZ2Decompressor() - - self._buffer = self._decompressor.decompress(rawblock) + try: + self._buffer = self._decompressor.decompress(rawblock) + except OSError: + # Trailing data isn't a valid bzip2 stream. We're done here. + self._mode = _MODE_READ_EOF + self._size = self._pos + return False + else: + self._buffer = self._decompressor.decompress(rawblock) self._buffer_offset = 0 return True @@ -496,17 +503,19 @@ def decompress(data): For incremental decompression, use a BZ2Decompressor object instead. """ - if len(data) == 0: - return b"" - results = [] - while True: + while data: decomp = BZ2Decompressor() - results.append(decomp.decompress(data)) + try: + res = decomp.decompress(data) + except OSError: + if results: + break # Leftover data is not a valid bzip2 stream; ignore it. + else: + raise # Error on the first iteration; bail out. + results.append(res) if not decomp.eof: raise ValueError("Compressed data ended before the " "end-of-stream marker was reached") - if not decomp.unused_data: - return b"".join(results) - # There is unused data left over. Proceed to next stream. data = decomp.unused_data + return b"".join(results) diff --git a/Lib/cgi.py b/Lib/cgi.py index 1d8040cc7ab9..a55232eb62d5 100755 --- a/Lib/cgi.py +++ b/Lib/cgi.py @@ -32,10 +32,12 @@ # ======= from io import StringIO, BytesIO, TextIOWrapper +from collections import Mapping import sys import os import urllib.parse from email.parser import FeedParser +from email.message import Message from warnings import warn import html import locale @@ -472,18 +474,24 @@ def __init__(self, fp=None, headers=None, outerboundary=b'', self.qs_on_post = environ['QUERY_STRING'] if 'CONTENT_LENGTH' in environ: headers['content-length'] = environ['CONTENT_LENGTH'] + else: + if not (isinstance(headers, (Mapping, Message))): + raise TypeError("headers must be mapping or an instance of " + "email.message.Message") + self.headers = headers if fp is None: self.fp = sys.stdin.buffer # self.fp.read() must return bytes elif isinstance(fp, TextIOWrapper): self.fp = fp.buffer else: + if not (hasattr(fp, 'read') and hasattr(fp, 'readline')): + raise TypeError("fp must be file pointer") self.fp = fp self.encoding = encoding self.errors = errors - self.headers = headers if not isinstance(outerboundary, bytes): raise TypeError('outerboundary must be bytes, not %s' % type(outerboundary).__name__) @@ -558,6 +566,12 @@ def __del__(self): except AttributeError: pass + def __enter__(self): + return self + + def __exit__(self, *args): + self.file.close() + def __repr__(self): """Return a printable representation.""" return "FieldStorage(%r, %r, %r)" % ( @@ -642,7 +656,9 @@ def __len__(self): """Dictionary style len(x) support.""" return len(self.keys()) - def __nonzero__(self): + def __bool__(self): + if self.list is None: + raise TypeError("Cannot be converted to bool.") return bool(self.list) def read_urlencoded(self): @@ -1035,7 +1051,7 @@ def escape(s, quote=None): return s -def valid_boundary(s, _vb_pattern=None): +def valid_boundary(s): import re if isinstance(s, bytes): _vb_pattern = b"^[ -~]{0,200}[!-~]$" diff --git a/Lib/code.py b/Lib/code.py index f8184b6c22e5..86e1f0326078 100644 --- a/Lib/code.py +++ b/Lib/code.py @@ -7,6 +7,7 @@ import sys import traceback +import argparse from codeop import CommandCompiler, compile_command __all__ = ["InteractiveInterpreter", "InteractiveConsole", "interact", @@ -136,25 +137,35 @@ def showtraceback(self): The output is written by self.write(), below. """ + sys.last_type, sys.last_value, last_tb = ei = sys.exc_info() + sys.last_traceback = last_tb try: - type, value, tb = sys.exc_info() - sys.last_type = type - sys.last_value = value - sys.last_traceback = tb - tblist = traceback.extract_tb(tb) - del tblist[:1] - lines = traceback.format_list(tblist) - if lines: - lines.insert(0, "Traceback (most recent call last):\n") - lines.extend(traceback.format_exception_only(type, value)) + lines = [] + for value, tb in traceback._iter_chain(*ei[1:]): + if isinstance(value, str): + lines.append(value) + lines.append('\n') + continue + if tb: + tblist = traceback.extract_tb(tb) + if tb is last_tb: + # The last traceback includes the frame we + # exec'd in + del tblist[:1] + tblines = traceback.format_list(tblist) + if tblines: + lines.append("Traceback (most recent call last):\n") + lines.extend(tblines) + lines.extend(traceback.format_exception_only(type(value), + value)) finally: - tblist = tb = None + tblist = last_tb = ei = None if sys.excepthook is sys.__excepthook__: self.write(''.join(lines)) else: # If someone has set sys.excepthook, we let that take precedence # over self.write - sys.excepthook(type, value, tb) + sys.excepthook(type, value, last_tb) def write(self, data): """Write a string. @@ -299,4 +310,12 @@ def interact(banner=None, readfunc=None, local=None): if __name__ == "__main__": - interact() + parser = argparse.ArgumentParser() + parser.add_argument('-q', action='store_true', + help="don't print version and copyright messages") + args = parser.parse_args() + if args.q or sys.flags.quiet: + banner = '' + else: + banner = None + interact(banner) diff --git a/Lib/codecs.py b/Lib/codecs.py index 2e2e7555a482..c2b5d6c35c6f 100644 --- a/Lib/codecs.py +++ b/Lib/codecs.py @@ -20,8 +20,15 @@ "BOM_LE", "BOM32_BE", "BOM32_LE", "BOM64_BE", "BOM64_LE", "BOM_UTF8", "BOM_UTF16", "BOM_UTF16_LE", "BOM_UTF16_BE", "BOM_UTF32", "BOM_UTF32_LE", "BOM_UTF32_BE", + "CodecInfo", "Codec", "IncrementalEncoder", "IncrementalDecoder", + "StreamReader", "StreamWriter", + "StreamReaderWriter", "StreamRecoder", + "getencoder", "getdecoder", "getincrementalencoder", + "getincrementaldecoder", "getreader", "getwriter", + "encode", "decode", "iterencode", "iterdecode", "strict_errors", "ignore_errors", "replace_errors", "xmlcharrefreplace_errors", + "backslashreplace_errors", "namereplace_errors", "register_error", "lookup_error"] ### Constants @@ -99,8 +106,8 @@ def __new__(cls, encode, decode, streamreader=None, streamwriter=None, return self def __repr__(self): - return "<%s.%s object for encoding %s at 0x%x>" % \ - (self.__class__.__module__, self.__class__.__name__, + return "<%s.%s object for encoding %s at %#x>" % \ + (self.__class__.__module__, self.__class__.__qualname__, self.name, id(self)) class Codec: @@ -117,10 +124,11 @@ class Codec: Python will use the official U+FFFD REPLACEMENT CHARACTER for the builtin Unicode codecs on decoding and '?' on encoding. - 'surrogateescape' - replace with private codepoints U+DCnn. + 'surrogateescape' - replace with private code points U+DCnn. 'xmlcharrefreplace' - Replace with the appropriate XML character reference (only for encoding). - 'backslashreplace' - Replace with backslashed escape sequences + 'backslashreplace' - Replace with backslashed escape sequences. + 'namereplace' - Replace with \\N{...} escape sequences (only for encoding). The set of allowed values can be extended via register_error. @@ -340,8 +348,7 @@ def __init__(self, stream, errors='strict'): """ Creates a StreamWriter instance. - stream must be a file-like object open for writing - (binary) data. + stream must be a file-like object open for writing. The StreamWriter may use different error handling schemes by providing the errors keyword argument. These @@ -353,7 +360,8 @@ def __init__(self, stream, errors='strict'): 'xmlcharrefreplace' - Replace with the appropriate XML character reference. 'backslashreplace' - Replace with backslashed escape - sequences (only for encoding). + sequences. + 'namereplace' - Replace with \\N{...} escape sequences. The set of allowed parameter values can be extended via register_error. @@ -415,8 +423,7 @@ def __init__(self, stream, errors='strict'): """ Creates a StreamReader instance. - stream must be a file-like object open for reading - (binary) data. + stream must be a file-like object open for reading. The StreamReader may use different error handling schemes by providing the errors keyword argument. These @@ -424,7 +431,8 @@ def __init__(self, stream, errors='strict'): 'strict' - raise a ValueError (or a subclass) 'ignore' - ignore the character and continue with the next - 'replace'- replace with a suitable replacement character; + 'replace'- replace with a suitable replacement character + 'backslashreplace' - Replace with backslashed escape sequences; The set of allowed parameter values can be extended via register_error. @@ -444,13 +452,12 @@ def read(self, size=-1, chars=-1, firstline=False): """ Decodes data from the stream self.stream and returns the resulting object. - chars indicates the number of characters to read from the - stream. read() will never return more than chars - characters, but it might return less, if there are not enough - characters available. + chars indicates the number of decoded code points or bytes to + return. read() will never return more data than requested, + but it might return less, if there is not enough available. - size indicates the approximate maximum number of bytes to - read from the stream for decoding purposes. The decoder + size indicates the approximate maximum number of decoded + bytes or code points to read for decoding. The decoder can modify this setting as appropriate. The default value -1 indicates to read and decode as much as possible. size is intended to prevent having to decode huge files in one @@ -461,7 +468,7 @@ def read(self, size=-1, chars=-1, firstline=False): will be returned, the rest of the input will be kept until the next call to read(). - The method should use a greedy read strategy meaning that + The method should use a greedy read strategy, meaning that it should read as much data as is allowed within the definition of the encoding and the given size, e.g. if optional encoding endings or state markers are available @@ -475,15 +482,12 @@ def read(self, size=-1, chars=-1, firstline=False): # read until we get the required number of characters (if available) while True: # can the request be satisfied from the character buffer? - if chars < 0: - if size < 0: - if self.charbuffer: - break - elif len(self.charbuffer) >= size: - break - else: + if chars >= 0: if len(self.charbuffer) >= chars: break + elif size >= 0: + if len(self.charbuffer) >= size: + break # we need more data if size < 0: newdata = self.stream.read() @@ -491,6 +495,8 @@ def read(self, size=-1, chars=-1, firstline=False): newdata = self.stream.read(size) # decode bytes (those remaining from the last call included) data = self.bytebuffer + newdata + if not data: + break try: newchars, decodedbytes = self.decode(data, self.errors) except UnicodeDecodeError as exc: @@ -597,7 +603,7 @@ def readline(self, size=None, keepends=True): def readlines(self, sizehint=None, keepends=True): """ Read all lines available on the input stream - and return them as list of lines. + and return them as a list. Line breaks are implemented using the codec's decoder method and are included in the list entries. @@ -745,19 +751,18 @@ def __exit__(self, type, value, tb): class StreamRecoder: - """ StreamRecoder instances provide a frontend - backend - view of encoding data. + """ StreamRecoder instances translate data from one encoding to another. They use the complete set of APIs returned by the codecs.lookup() function to implement their task. - Data written to the stream is first decoded into an - intermediate format (which is dependent on the given codec - combination) and then written to the stream using an instance - of the provided Writer class. + Data written to the StreamRecoder is first decoded into an + intermediate format (depending on the "decode" codec) and then + written to the underlying stream using an instance of the provided + Writer class. - In the other direction, data is read from the stream using a - Reader instance and then return encoded data to the caller. + In the other direction, data is read from the underlying stream using + a Reader instance and then encoded and returned to the caller. """ # Optional attributes set by the file wrappers below @@ -769,22 +774,17 @@ def __init__(self, stream, encode, decode, Reader, Writer, """ Creates a StreamRecoder instance which implements a two-way conversion: encode and decode work on the frontend (the - input to .read() and output of .write()) while - Reader and Writer work on the backend (reading and - writing to the stream). + data visible to .read() and .write()) while Reader and Writer + work on the backend (the data in stream). - You can use these objects to do transparent direct - recodings from e.g. latin-1 to utf-8 and back. + You can use these objects to do transparent + transcodings from e.g. latin-1 to utf-8 and back. stream must be a file-like object. - encode, decode must adhere to the Codec interface, Reader, + encode and decode must adhere to the Codec interface; Reader and Writer must be factory functions or classes providing the - StreamReader, StreamWriter interface resp. - - encode and decode are needed for the frontend translation, - Reader and Writer for the backend translation. Unicode is - used as intermediate encoding. + StreamReader and StreamWriter interfaces resp. Error handling is done in the same way as defined for the StreamWriter/Readers. @@ -859,7 +859,7 @@ def __exit__(self, type, value, tb): ### Shortcuts -def open(filename, mode='rb', encoding=None, errors='strict', buffering=1): +def open(filename, mode='r', encoding=None, errors='strict', buffering=1): """ Open an encoded file using the given mode and return a wrapped version providing transparent encoding/decoding. @@ -869,10 +869,8 @@ def open(filename, mode='rb', encoding=None, errors='strict', buffering=1): codecs. Output is also codec dependent and will usually be Unicode as well. - Files are always opened in binary mode, even if no binary mode - was specified. This is done to avoid data loss due to encodings - using 8-bit values. The default file mode is 'rb' meaning to - open the file in binary read mode. + Underlying encoded files are always opened in binary mode. + The default file mode is 'r', meaning to open the file in read mode. encoding specifies the encoding which is to be used for the file. @@ -908,13 +906,13 @@ def EncodedFile(file, data_encoding, file_encoding=None, errors='strict'): """ Return a wrapped version of file which provides transparent encoding translation. - Strings written to the wrapped file are interpreted according - to the given data_encoding and then written to the original - file as string using file_encoding. The intermediate encoding + Data written to the wrapped file is decoded according + to the given data_encoding and then encoded to the underlying + file using file_encoding. The intermediate data type will usually be Unicode but depends on the specified codecs. - Strings are read from the file using file_encoding and then - passed back to the caller as string using data_encoding. + Bytes read from the file are decoded using file_encoding and then + passed back to the caller encoded using data_encoding. If file_encoding is not given, it defaults to data_encoding. @@ -1086,6 +1084,7 @@ def make_encoding_map(decoding_map): replace_errors = lookup_error("replace") xmlcharrefreplace_errors = lookup_error("xmlcharrefreplace") backslashreplace_errors = lookup_error("backslashreplace") + namereplace_errors = lookup_error("namereplace") except LookupError: # In --disable-unicode builds, these error handler are missing strict_errors = None @@ -1093,6 +1092,7 @@ def make_encoding_map(decoding_map): replace_errors = None xmlcharrefreplace_errors = None backslashreplace_errors = None + namereplace_errors = None # Tell modulefinder that using codecs probably needs the encodings # package diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py index 02bdc57c9fee..ce67f0b31250 100644 --- a/Lib/collections/__init__.py +++ b/Lib/collections/__init__.py @@ -20,6 +20,23 @@ ### OrderedDict ################################################################################ +class _OrderedDictKeysView(KeysView): + + def __reversed__(self): + yield from reversed(self._mapping) + +class _OrderedDictItemsView(ItemsView): + + def __reversed__(self): + for key in reversed(self._mapping): + yield (key, self._mapping[key]) + +class _OrderedDictValuesView(ValuesView): + + def __reversed__(self): + for key in reversed(self._mapping): + yield self._mapping[key] + class _Link(object): __slots__ = 'prev', 'next', 'key', '__weakref__' @@ -38,12 +55,16 @@ class OrderedDict(dict): # Individual links are kept alive by the hard reference in self.__map. # Those hard references disappear when a key is deleted from an OrderedDict. - def __init__(self, *args, **kwds): + def __init__(*args, **kwds): '''Initialize an ordered dictionary. The signature is the same as regular dictionaries, but keyword arguments are not recommended because their insertion order is arbitrary. ''' + if not args: + raise TypeError("descriptor '__init__' of 'OrderedDict' object " + "needs an argument") + self, *args = args if len(args) > 1: raise TypeError('expected at most 1 arguments, got %d' % len(args)) try: @@ -79,6 +100,8 @@ def __delitem__(self, key, dict_delitem=dict.__delitem__): link_next = link.next link_prev.next = link_next link_next.prev = link_prev + link.prev = None + link.next = None def __iter__(self): 'od.__iter__() <==> iter(od)' @@ -162,9 +185,19 @@ def __sizeof__(self): return size update = __update = MutableMapping.update - keys = MutableMapping.keys - values = MutableMapping.values - items = MutableMapping.items + + def keys(self): + "D.keys() -> a set-like object providing a view on D's keys" + return _OrderedDictKeysView(self) + + def items(self): + "D.items() -> a set-like object providing a view on D's items" + return _OrderedDictItemsView(self) + + def values(self): + "D.values() -> an object providing a view on D's values" + return _OrderedDictValuesView(self) + __ne__ = MutableMapping.__ne__ __marker = object() @@ -274,9 +307,7 @@ def __dict__(self): return OrderedDict(zip(self._fields, self)) def _asdict(self): - '''Return a new OrderedDict which maps field names to their values. - This method is obsolete. Use vars(nt) or nt.__dict__ instead. - ''' + 'Return a new OrderedDict which maps field names to their values.' return self.__dict__ def __getnewargs__(self): @@ -325,6 +356,7 @@ def namedtuple(typename, field_names, verbose=False, rename=False): if isinstance(field_names, str): field_names = field_names.replace(',', ' ').split() field_names = list(map(str, field_names)) + typename = str(typename) if rename: seen = set() for index, name in enumerate(field_names): @@ -335,6 +367,8 @@ def namedtuple(typename, field_names, verbose=False, rename=False): field_names[index] = '_%d' % index seen.add(name) for name in [typename] + field_names: + if type(name) != str: + raise TypeError('Type names and field names must be strings') if not name.isidentifier(): raise ValueError('Type names and field names must be valid ' 'identifiers: %r' % name) @@ -449,7 +483,7 @@ class Counter(dict): # http://code.activestate.com/recipes/259174/ # Knuth, TAOCP Vol. II section 4.6.3 - def __init__(self, iterable=None, **kwds): + def __init__(*args, **kwds): '''Create a new, empty Counter object. And if given, count elements from an input iterable. Or, initialize the count from another mapping of elements to their counts. @@ -460,8 +494,14 @@ def __init__(self, iterable=None, **kwds): >>> c = Counter(a=4, b=2) # a new counter from keyword args ''' - super().__init__() - self.update(iterable, **kwds) + if not args: + raise TypeError("descriptor '__init__' of 'Counter' object " + "needs an argument") + self, *args = args + if len(args) > 1: + raise TypeError('expected at most 1 arguments, got %d' % len(args)) + super(Counter, self).__init__() + self.update(*args, **kwds) def __missing__(self, key): 'The count of elements not in the Counter is zero.' @@ -512,7 +552,7 @@ def fromkeys(cls, iterable, v=None): raise NotImplementedError( 'Counter.fromkeys() is undefined. Use Counter(iterable) instead.') - def update(self, iterable=None, **kwds): + def update(*args, **kwds): '''Like dict.update() but add counts instead of replacing them. Source can be an iterable, a dictionary, or another Counter instance. @@ -532,6 +572,13 @@ def update(self, iterable=None, **kwds): # contexts. Instead, we implement straight-addition. Both the inputs # and outputs are allowed to contain zero and negative counts. + if not args: + raise TypeError("descriptor 'update' of 'Counter' object " + "needs an argument") + self, *args = args + if len(args) > 1: + raise TypeError('expected at most 1 arguments, got %d' % len(args)) + iterable = args[0] if args else None if iterable is not None: if isinstance(iterable, Mapping): if self: @@ -539,13 +586,13 @@ def update(self, iterable=None, **kwds): for elem, count in iterable.items(): self[elem] = count + self_get(elem, 0) else: - super().update(iterable) # fast path when counter is empty + super(Counter, self).update(iterable) # fast path when counter is empty else: _count_elements(self, iterable) if kwds: self.update(kwds) - def subtract(self, iterable=None, **kwds): + def subtract(*args, **kwds): '''Like dict.update() but subtracts counts instead of replacing them. Counts can be reduced below zero. Both the inputs and outputs are allowed to contain zero and negative counts. @@ -561,6 +608,13 @@ def subtract(self, iterable=None, **kwds): -1 ''' + if not args: + raise TypeError("descriptor 'subtract' of 'Counter' object " + "needs an argument") + self, *args = args + if len(args) > 1: + raise TypeError('expected at most 1 arguments, got %d' % len(args)) + iterable = args[0] if args else None if iterable is not None: self_get = self.get if isinstance(iterable, Mapping): @@ -933,7 +987,6 @@ def __repr__(self): return repr(self.data) def __lt__(self, other): return self.data < self.__cast(other) def __le__(self, other): return self.data <= self.__cast(other) def __eq__(self, other): return self.data == self.__cast(other) - def __ne__(self, other): return self.data != self.__cast(other) def __gt__(self, other): return self.data > self.__cast(other) def __ge__(self, other): return self.data >= self.__cast(other) def __cast(self, other): @@ -1010,10 +1063,6 @@ def __eq__(self, string): if isinstance(string, UserString): return self.data == string.data return self.data == string - def __ne__(self, string): - if isinstance(string, UserString): - return self.data != string.data - return self.data != string def __lt__(self, string): if isinstance(string, UserString): return self.data < string.data diff --git a/Lib/compileall.py b/Lib/compileall.py index 475dc1c8a0ad..4f46920a1b57 100644 --- a/Lib/compileall.py +++ b/Lib/compileall.py @@ -12,37 +12,28 @@ """ import os import sys -import errno import importlib.util import py_compile import struct -__all__ = ["compile_dir","compile_file","compile_path"] - -def compile_dir(dir, maxlevels=10, ddir=None, force=False, rx=None, - quiet=False, legacy=False, optimize=-1): - """Byte-compile all modules in the given directory tree. +try: + from concurrent.futures import ProcessPoolExecutor +except ImportError: + ProcessPoolExecutor = None +from functools import partial - Arguments (only dir is required): +__all__ = ["compile_dir","compile_file","compile_path"] - dir: the directory to byte-compile - maxlevels: maximum recursion level (default 10) - ddir: the directory that will be prepended to the path to the - file as it is compiled into each byte-code file. - force: if True, force compilation, even if timestamps are up-to-date - quiet: if True, be quiet during compilation - legacy: if True, produce legacy pyc paths instead of PEP 3147 paths - optimize: optimization level or -1 for level of the interpreter - """ +def _walk_dir(dir, ddir=None, maxlevels=10, quiet=0): if not quiet: print('Listing {!r}...'.format(dir)) try: names = os.listdir(dir) except OSError: - print("Can't list {!r}".format(dir)) + if quiet < 2: + print("Can't list {!r}".format(dir)) names = [] names.sort() - success = 1 for name in names: if name == '__pycache__': continue @@ -52,17 +43,55 @@ def compile_dir(dir, maxlevels=10, ddir=None, force=False, rx=None, else: dfile = None if not os.path.isdir(fullname): - if not compile_file(fullname, ddir, force, rx, quiet, - legacy, optimize): - success = 0 + yield fullname elif (maxlevels > 0 and name != os.curdir and name != os.pardir and os.path.isdir(fullname) and not os.path.islink(fullname)): - if not compile_dir(fullname, maxlevels - 1, dfile, force, rx, - quiet, legacy, optimize): + yield from _walk_dir(fullname, ddir=dfile, + maxlevels=maxlevels - 1, quiet=quiet) + +def compile_dir(dir, maxlevels=10, ddir=None, force=False, rx=None, + quiet=0, legacy=False, optimize=-1, workers=1): + """Byte-compile all modules in the given directory tree. + + Arguments (only dir is required): + + dir: the directory to byte-compile + maxlevels: maximum recursion level (default 10) + ddir: the directory that will be prepended to the path to the + file as it is compiled into each byte-code file. + force: if True, force compilation, even if timestamps are up-to-date + quiet: full output with False or 0, errors only with 1, + no output with 2 + legacy: if True, produce legacy pyc paths instead of PEP 3147 paths + optimize: optimization level or -1 for level of the interpreter + workers: maximum number of parallel workers + """ + files = _walk_dir(dir, quiet=quiet, maxlevels=maxlevels, + ddir=ddir) + success = 1 + if workers is not None and workers != 1: + if workers < 0: + raise ValueError('workers must be greater or equal to 0') + if ProcessPoolExecutor is None: + raise NotImplementedError('multiprocessing support not available') + + workers = workers or None + with ProcessPoolExecutor(max_workers=workers) as executor: + results = executor.map(partial(compile_file, + ddir=ddir, force=force, + rx=rx, quiet=quiet, + legacy=legacy, + optimize=optimize), + files) + success = min(results, default=1) + else: + for file in files: + if not compile_file(file, ddir, force, rx, quiet, + legacy, optimize): success = 0 return success -def compile_file(fullname, ddir=None, force=False, rx=None, quiet=False, +def compile_file(fullname, ddir=None, force=False, rx=None, quiet=0, legacy=False, optimize=-1): """Byte-compile one file. @@ -72,7 +101,8 @@ def compile_file(fullname, ddir=None, force=False, rx=None, quiet=False, ddir: if given, the directory name compiled in to the byte-code file. force: if True, force compilation, even if timestamps are up-to-date - quiet: if True, be quiet during compilation + quiet: full output with False or 0, errors only with 1, + no output with 2 legacy: if True, produce legacy pyc paths instead of PEP 3147 paths optimize: optimization level or -1 for level of the interpreter """ @@ -115,7 +145,10 @@ def compile_file(fullname, ddir=None, force=False, rx=None, quiet=False, ok = py_compile.compile(fullname, cfile, dfile, True, optimize=optimize) except py_compile.PyCompileError as err: - if quiet: + success = 0 + if quiet >= 2: + return success + elif quiet: print('*** Error compiling {!r}...'.format(fullname)) else: print('*** ', end='') @@ -124,20 +157,21 @@ def compile_file(fullname, ddir=None, force=False, rx=None, quiet=False, errors='backslashreplace') msg = msg.decode(sys.stdout.encoding) print(msg) - success = 0 except (SyntaxError, UnicodeError, OSError) as e: - if quiet: + success = 0 + if quiet >= 2: + return success + elif quiet: print('*** Error compiling {!r}...'.format(fullname)) else: print('*** ', end='') print(e.__class__.__name__ + ':', e) - success = 0 else: if ok == 0: success = 0 return success -def compile_path(skip_curdir=1, maxlevels=0, force=False, quiet=False, +def compile_path(skip_curdir=1, maxlevels=0, force=False, quiet=0, legacy=False, optimize=-1): """Byte-compile all module on sys.path. @@ -146,14 +180,15 @@ def compile_path(skip_curdir=1, maxlevels=0, force=False, quiet=False, skip_curdir: if true, skip current directory (default True) maxlevels: max recursion level (default 0) force: as for compile_dir() (default False) - quiet: as for compile_dir() (default False) + quiet: as for compile_dir() (default 0) legacy: as for compile_dir() (default False) optimize: as for compile_dir() (default -1) """ success = 1 for dir in sys.path: if (not dir or dir == os.curdir) and skip_curdir: - print('Skipping current directory') + if quiet < 2: + print('Skipping current directory') else: success = success and compile_dir(dir, maxlevels, None, force, quiet=quiet, @@ -170,10 +205,15 @@ def main(): parser.add_argument('-l', action='store_const', const=0, default=10, dest='maxlevels', help="don't recurse into subdirectories") + parser.add_argument('-r', type=int, dest='recursion', + help=('control the maximum recursion level. ' + 'if `-l` and `-r` options are specified, ' + 'then `-r` takes precedence.')) parser.add_argument('-f', action='store_true', dest='force', help='force rebuild even if timestamps are up to date') - parser.add_argument('-q', action='store_true', dest='quiet', - help='output only error messages') + parser.add_argument('-q', action='count', dest='quiet', default=0, + help='output only error messages; -qq will suppress ' + 'the error messages as well.') parser.add_argument('-b', action='store_true', dest='legacy', help='use legacy (pre-PEP3147) compiled file locations') parser.add_argument('-d', metavar='DESTDIR', dest='ddir', default=None, @@ -193,8 +233,10 @@ def main(): help=('zero or more file and directory names ' 'to compile; if no arguments given, defaults ' 'to the equivalent of -l sys.path')) - args = parser.parse_args() + parser.add_argument('-j', '--workers', default=1, + type=int, help='Run compileall concurrently') + args = parser.parse_args() compile_dests = args.compile_dest if (args.ddir and (len(compile_dests) != 1 @@ -204,6 +246,12 @@ def main(): import re args.rx = re.compile(args.rx) + + if args.recursion is not None: + maxlevels = args.recursion + else: + maxlevels = args.maxlevels + # if flist is provided then load it if args.flist: try: @@ -211,9 +259,13 @@ def main(): for line in f: compile_dests.append(line.strip()) except OSError: - print("Error reading file list {}".format(args.flist)) + if args.quiet < 2: + print("Error reading file list {}".format(args.flist)) return False + if args.workers is not None: + args.workers = args.workers or None + success = True try: if compile_dests: @@ -223,15 +275,17 @@ def main(): args.quiet, args.legacy): success = False else: - if not compile_dir(dest, args.maxlevels, args.ddir, + if not compile_dir(dest, maxlevels, args.ddir, args.force, args.rx, args.quiet, - args.legacy): + args.legacy, workers=args.workers): success = False return success else: - return compile_path(legacy=args.legacy) + return compile_path(legacy=args.legacy, force=args.force, + quiet=args.quiet) except KeyboardInterrupt: - print("\n[interrupted]") + if args.quiet < 2: + print("\n[interrupted]") return False return True diff --git a/Lib/concurrent/futures/_base.py b/Lib/concurrent/futures/_base.py index 3d0328049fef..9e447137adce 100644 --- a/Lib/concurrent/futures/_base.py +++ b/Lib/concurrent/futures/_base.py @@ -181,7 +181,8 @@ def as_completed(fs, timeout=None): Returns: An iterator that yields the given Futures as they complete (finished or - cancelled). + cancelled). If any given Futures are duplicated, they will be returned + once. Raises: TimeoutError: If the entire result iterator could not be generated @@ -190,11 +191,12 @@ def as_completed(fs, timeout=None): if timeout is not None: end_time = timeout + time.time() + fs = set(fs) with _AcquireFutures(fs): finished = set( f for f in fs if f._state in [CANCELLED_AND_NOTIFIED, FINISHED]) - pending = set(fs) - finished + pending = fs - finished waiter = _create_and_install_waiters(fs, _AS_COMPLETED) try: @@ -223,7 +225,8 @@ def as_completed(fs, timeout=None): finally: for f in fs: - f._waiters.remove(waiter) + with f._condition: + f._waiters.remove(waiter) DoneAndNotDoneFutures = collections.namedtuple( 'DoneAndNotDoneFutures', 'done not_done') @@ -270,7 +273,8 @@ def wait(fs, timeout=None, return_when=ALL_COMPLETED): waiter.event.wait(timeout) for f in fs: - f._waiters.remove(waiter) + with f._condition: + f._waiters.remove(waiter) done.update(waiter.finished_futures) return DoneAndNotDoneFutures(done, set(fs) - done) @@ -298,17 +302,20 @@ def __repr__(self): with self._condition: if self._state == FINISHED: if self._exception: - return '<Future at %s state=%s raised %s>' % ( - hex(id(self)), + return '<%s at %#x state=%s raised %s>' % ( + self.__class__.__name__, + id(self), _STATE_TO_DESCRIPTION_MAP[self._state], self._exception.__class__.__name__) else: - return '<Future at %s state=%s returned %s>' % ( - hex(id(self)), + return '<%s at %#x state=%s returned %s>' % ( + self.__class__.__name__, + id(self), _STATE_TO_DESCRIPTION_MAP[self._state], self._result.__class__.__name__) - return '<Future at %s state=%s>' % ( - hex(id(self)), + return '<%s at %#x state=%s>' % ( + self.__class__.__name__, + id(self), _STATE_TO_DESCRIPTION_MAP[self._state]) def cancel(self): @@ -513,7 +520,7 @@ def submit(self, fn, *args, **kwargs): """ raise NotImplementedError() - def map(self, fn, *iterables, timeout=None): + def map(self, fn, *iterables, timeout=None, chunksize=1): """Returns a iterator equivalent to map(fn, iter). Args: @@ -521,6 +528,10 @@ def map(self, fn, *iterables, timeout=None): passed iterables. timeout: The maximum number of seconds to wait. If None, then there is no limit on the wait time. + chunksize: The size of the chunks the iterable will be broken into + before being passed to a child process. This argument is only + used by ProcessPoolExecutor; it is ignored by + ThreadPoolExecutor. Returns: An iterator equivalent to: map(func, *iterables) but the calls may diff --git a/Lib/concurrent/futures/process.py b/Lib/concurrent/futures/process.py index 07b5225d1dab..3dd6da1f0c11 100644 --- a/Lib/concurrent/futures/process.py +++ b/Lib/concurrent/futures/process.py @@ -55,6 +55,9 @@ from multiprocessing.connection import wait import threading import weakref +from functools import partial +import itertools +import traceback # Workers are created as daemon threads and processes. This is done to allow the # interpreter to exit when there are still idle processes in a @@ -88,6 +91,27 @@ def _python_exit(): # (Futures in the call queue cannot be cancelled). EXTRA_QUEUED_CALLS = 1 +# Hack to embed stringification of remote traceback in local traceback + +class _RemoteTraceback(Exception): + def __init__(self, tb): + self.tb = tb + def __str__(self): + return self.tb + +class _ExceptionWithTraceback: + def __init__(self, exc, tb): + tb = traceback.format_exception(type(exc), exc, tb) + tb = ''.join(tb) + self.exc = exc + self.tb = '\n"""\n%s"""' % tb + def __reduce__(self): + return _rebuild_exc, (self.exc, self.tb) + +def _rebuild_exc(exc, tb): + exc.__cause__ = _RemoteTraceback(tb) + return exc + class _WorkItem(object): def __init__(self, future, fn, args, kwargs): self.future = future @@ -108,6 +132,26 @@ def __init__(self, work_id, fn, args, kwargs): self.args = args self.kwargs = kwargs +def _get_chunks(*iterables, chunksize): + """ Iterates over zip()ed iterables in chunks. """ + it = zip(*iterables) + while True: + chunk = tuple(itertools.islice(it, chunksize)) + if not chunk: + return + yield chunk + +def _process_chunk(fn, chunk): + """ Processes a chunk of an iterable passed to map. + + Runs the function passed to map() on a chunk of the + iterable passed to map. + + This function is run in a separate process. + + """ + return [fn(*args) for args in chunk] + def _process_worker(call_queue, result_queue): """Evaluates calls from call_queue and places the results in result_queue. @@ -130,8 +174,8 @@ def _process_worker(call_queue, result_queue): try: r = call_item.fn(*call_item.args, **call_item.kwargs) except BaseException as e: - result_queue.put(_ResultItem(call_item.work_id, - exception=e)) + exc = _ExceptionWithTraceback(e, e.__traceback__) + result_queue.put(_ResultItem(call_item.work_id, exception=exc)) else: result_queue.put(_ResultItem(call_item.work_id, result=r)) @@ -334,6 +378,9 @@ def __init__(self, max_workers=None): if max_workers is None: self._max_workers = os.cpu_count() or 1 else: + if max_workers <= 0: + raise ValueError("max_workers must be greater than 0") + self._max_workers = max_workers # Make the call queue slightly larger than the number of processes to @@ -408,6 +455,35 @@ def submit(self, fn, *args, **kwargs): return f submit.__doc__ = _base.Executor.submit.__doc__ + def map(self, fn, *iterables, timeout=None, chunksize=1): + """Returns a iterator equivalent to map(fn, iter). + + Args: + fn: A callable that will take as many arguments as there are + passed iterables. + timeout: The maximum number of seconds to wait. If None, then there + is no limit on the wait time. + chunksize: If greater than one, the iterables will be chopped into + chunks of size chunksize and submitted to the process pool. + If set to one, the items in the list will be sent one at a time. + + Returns: + An iterator equivalent to: map(func, *iterables) but the calls may + be evaluated out-of-order. + + Raises: + TimeoutError: If the entire result iterator could not be generated + before the given timeout. + Exception: If fn(*args) raises for any values. + """ + if chunksize < 1: + raise ValueError("chunksize must be >= 1.") + + results = super().map(partial(_process_chunk, fn), + _get_chunks(*iterables, chunksize=chunksize), + timeout=timeout) + return itertools.chain.from_iterable(results) + def shutdown(self, wait=True): with self._shutdown_lock: self._shutdown_thread = True diff --git a/Lib/concurrent/futures/thread.py b/Lib/concurrent/futures/thread.py index f9beb0f7f7ed..3ae442d98703 100644 --- a/Lib/concurrent/futures/thread.py +++ b/Lib/concurrent/futures/thread.py @@ -10,6 +10,7 @@ import queue import threading import weakref +import os # Workers are created as daemon threads. This is done to allow the interpreter # to exit when there are still idle threads in a ThreadPoolExecutor's thread @@ -80,13 +81,20 @@ def _worker(executor_reference, work_queue): _base.LOGGER.critical('Exception in worker', exc_info=True) class ThreadPoolExecutor(_base.Executor): - def __init__(self, max_workers): + def __init__(self, max_workers=None): """Initializes a new ThreadPoolExecutor instance. Args: max_workers: The maximum number of threads that can be used to execute the given calls. """ + if max_workers is None: + # Use this number because ThreadPoolExecutor is often + # used to overlap I/O instead of CPU work. + max_workers = (os.cpu_count() or 1) * 5 + if max_workers <= 0: + raise ValueError("max_workers must be greater than 0") + self._max_workers = max_workers self._work_queue = queue.Queue() self._threads = set() diff --git a/Lib/configparser.py b/Lib/configparser.py index 794f857c3f6e..ecd06600b127 100644 --- a/Lib/configparser.py +++ b/Lib/configparser.py @@ -17,7 +17,8 @@ __init__(defaults=None, dict_type=_default_dict, allow_no_value=False, delimiters=('=', ':'), comment_prefixes=('#', ';'), inline_comment_prefixes=None, strict=True, - empty_lines_in_values=True): + empty_lines_in_values=True, default_section='DEFAULT', + interpolation=<unset>, converters=<unset>): Create the parser. When `defaults' is given, it is initialized into the dictionary or intrinsic defaults. The keys must be strings, the values must be appropriate for %()s string interpolation. @@ -47,6 +48,25 @@ When `allow_no_value' is True (default: False), options without values are accepted; the value presented for these is None. + When `default_section' is given, the name of the special section is + named accordingly. By default it is called ``"DEFAULT"`` but this can + be customized to point to any other valid section name. Its current + value can be retrieved using the ``parser_instance.default_section`` + attribute and may be modified at runtime. + + When `interpolation` is given, it should be an Interpolation subclass + instance. It will be used as the handler for option value + pre-processing when using getters. RawConfigParser object s don't do + any sort of interpolation, whereas ConfigParser uses an instance of + BasicInterpolation. The library also provides a ``zc.buildbot`` + inspired ExtendedInterpolation implementation. + + When `converters` is given, it should be a dictionary where each key + represents the name of a type converter and each value is a callable + implementing the conversion from string to the desired datatype. Every + converter gets its corresponding get*() method on the parser object and + section proxies. + sections() Return all the configuration section names, sans DEFAULT. @@ -129,9 +149,11 @@ __all__ = ["NoSectionError", "DuplicateOptionError", "DuplicateSectionError", "NoOptionError", "InterpolationError", "InterpolationDepthError", - "InterpolationSyntaxError", "ParsingError", - "MissingSectionHeaderError", + "InterpolationMissingOptionError", "InterpolationSyntaxError", + "ParsingError", "MissingSectionHeaderError", "ConfigParser", "SafeConfigParser", "RawConfigParser", + "Interpolation", "BasicInterpolation", "ExtendedInterpolation", + "LegacyInterpolation", "SectionProxy", "ConverterMapping", "DEFAULTSECT", "MAX_INTERPOLATION_DEPTH"] DEFAULTSECT = "DEFAULT" @@ -144,23 +166,6 @@ class Error(Exception): """Base class for ConfigParser exceptions.""" - def _get_message(self): - """Getter for 'message'; needed only to override deprecation in - BaseException. - """ - return self.__message - - def _set_message(self, value): - """Setter for 'message'; needed only to override deprecation in - BaseException. - """ - self.__message = value - - # BaseException.message has been deprecated since Python 2.6. To prevent - # DeprecationWarning from popping up over this pre-existing attribute, use - # a new property that takes lookup precedence. - message = property(_get_message, _set_message) - def __init__(self, msg=''): self.message = msg Exception.__init__(self, msg) @@ -303,7 +308,7 @@ def __init__(self, source=None, filename=None): raise ValueError("Required argument `source' not given.") elif filename: source = filename - Error.__init__(self, 'Source contains parsing errors: %s' % source) + Error.__init__(self, 'Source contains parsing errors: %r' % source) self.source = source self.errors = [] self.args = (source, ) @@ -339,7 +344,7 @@ class MissingSectionHeaderError(ParsingError): def __init__(self, filename, lineno, line): Error.__init__( self, - 'File contains no section headers.\nfile: %s, line: %d\n%r' % + 'File contains no section headers.\nfile: %r, line: %d\n%r' % (filename, lineno, line)) self.source = filename self.lineno = lineno @@ -427,7 +432,7 @@ def _interpolate_some(self, parser, option, accum, rest, section, map, v = map[var] except KeyError: raise InterpolationMissingOptionError( - option, section, rest, var) + option, section, rest, var) from None if "%" in v: self._interpolate_some(parser, option, accum, v, section, map, depth + 1) @@ -499,7 +504,7 @@ def _interpolate_some(self, parser, option, accum, rest, section, map, "More than one ':' found: %r" % (rest,)) except (KeyError, NoSectionError, NoOptionError): raise InterpolationMissingOptionError( - option, section, rest, ":".join(path)) + option, section, rest, ":".join(path)) from None if "$" in v: self._interpolate_some(parser, opt, accum, v, sect, dict(parser.items(sect, raw=True)), @@ -532,7 +537,7 @@ def before_get(self, parser, section, option, value, vars): value = value % vars except KeyError as e: raise InterpolationMissingOptionError( - option, section, rawval, e.args[0]) + option, section, rawval, e.args[0]) from None else: break if value and "%(" in value: @@ -597,11 +602,12 @@ def __init__(self, defaults=None, dict_type=_default_dict, comment_prefixes=('#', ';'), inline_comment_prefixes=None, strict=True, empty_lines_in_values=True, default_section=DEFAULTSECT, - interpolation=_UNSET): + interpolation=_UNSET, converters=_UNSET): self._dict = dict_type self._sections = self._dict() self._defaults = self._dict() + self._converters = ConverterMapping(self) self._proxies = self._dict() self._proxies[default_section] = SectionProxy(self, default_section) if defaults: @@ -629,6 +635,8 @@ def __init__(self, defaults=None, dict_type=_default_dict, self._interpolation = self._DEFAULT_INTERPOLATION if self._interpolation is None: self._interpolation = Interpolation() + if converters is not _UNSET: + self._converters.update(converters) def defaults(self): return self._defaults @@ -664,7 +672,7 @@ def options(self, section): try: opts = self._sections[section].copy() except KeyError: - raise NoSectionError(section) + raise NoSectionError(section) from None opts.update(self._defaults) return list(opts.keys()) @@ -792,36 +800,31 @@ def get(self, section, option, *, raw=False, vars=None, fallback=_UNSET): def _get(self, section, conv, option, **kwargs): return conv(self.get(section, option, **kwargs)) - def getint(self, section, option, *, raw=False, vars=None, - fallback=_UNSET): + def _get_conv(self, section, option, conv, *, raw=False, vars=None, + fallback=_UNSET, **kwargs): try: - return self._get(section, int, option, raw=raw, vars=vars) + return self._get(section, conv, option, raw=raw, vars=vars, + **kwargs) except (NoSectionError, NoOptionError): if fallback is _UNSET: raise - else: - return fallback + return fallback + + # getint, getfloat and getboolean provided directly for backwards compat + def getint(self, section, option, *, raw=False, vars=None, + fallback=_UNSET, **kwargs): + return self._get_conv(section, option, int, raw=raw, vars=vars, + fallback=fallback, **kwargs) def getfloat(self, section, option, *, raw=False, vars=None, - fallback=_UNSET): - try: - return self._get(section, float, option, raw=raw, vars=vars) - except (NoSectionError, NoOptionError): - if fallback is _UNSET: - raise - else: - return fallback + fallback=_UNSET, **kwargs): + return self._get_conv(section, option, float, raw=raw, vars=vars, + fallback=fallback, **kwargs) def getboolean(self, section, option, *, raw=False, vars=None, - fallback=_UNSET): - try: - return self._get(section, self._convert_to_boolean, option, - raw=raw, vars=vars) - except (NoSectionError, NoOptionError): - if fallback is _UNSET: - raise - else: - return fallback + fallback=_UNSET, **kwargs): + return self._get_conv(section, option, self._convert_to_boolean, + raw=raw, vars=vars, fallback=fallback, **kwargs) def items(self, section=_UNSET, raw=False, vars=None): """Return a list of (name, value) tuples for each option in a section. @@ -893,7 +896,7 @@ def set(self, section, option, value=None): try: sectdict = self._sections[section] except KeyError: - raise NoSectionError(section) + raise NoSectionError(section) from None sectdict[self.optionxform(option)] = value def write(self, fp, space_around_delimiters=True): @@ -934,7 +937,7 @@ def remove_option(self, section, option): try: sectdict = self._sections[section] except KeyError: - raise NoSectionError(section) + raise NoSectionError(section) from None option = self.optionxform(option) existed = option in sectdict if existed: @@ -1171,6 +1174,10 @@ def _validate_value_types(self, *, section="", option="", value=""): if not isinstance(value, str): raise TypeError("option values must be strings") + @property + def converters(self): + return self._converters + class ConfigParser(RawConfigParser): """ConfigParser implementing interpolation.""" @@ -1211,6 +1218,10 @@ def __init__(self, parser, name): """Creates a view on a section of the specified `name` in `parser`.""" self._parser = parser self._name = name + for conv in parser.converters: + key = 'get' + conv + getter = functools.partial(self.get, _impl=getattr(parser, key)) + setattr(self, key, getter) def __repr__(self): return '<Section: {}>'.format(self._name) @@ -1244,22 +1255,6 @@ def _options(self): else: return self._parser.defaults() - def get(self, option, fallback=None, *, raw=False, vars=None): - return self._parser.get(self._name, option, raw=raw, vars=vars, - fallback=fallback) - - def getint(self, option, fallback=None, *, raw=False, vars=None): - return self._parser.getint(self._name, option, raw=raw, vars=vars, - fallback=fallback) - - def getfloat(self, option, fallback=None, *, raw=False, vars=None): - return self._parser.getfloat(self._name, option, raw=raw, vars=vars, - fallback=fallback) - - def getboolean(self, option, fallback=None, *, raw=False, vars=None): - return self._parser.getboolean(self._name, option, raw=raw, vars=vars, - fallback=fallback) - @property def parser(self): # The parser object of the proxy is read-only. @@ -1269,3 +1264,77 @@ def parser(self): def name(self): # The name of the section on a proxy is read-only. return self._name + + def get(self, option, fallback=None, *, raw=False, vars=None, + _impl=None, **kwargs): + """Get an option value. + + Unless `fallback` is provided, `None` will be returned if the option + is not found. + + """ + # If `_impl` is provided, it should be a getter method on the parser + # object that provides the desired type conversion. + if not _impl: + _impl = self._parser.get + return _impl(self._name, option, raw=raw, vars=vars, + fallback=fallback, **kwargs) + + +class ConverterMapping(MutableMapping): + """Enables reuse of get*() methods between the parser and section proxies. + + If a parser class implements a getter directly, the value for the given + key will be ``None``. The presence of the converter name here enables + section proxies to find and use the implementation on the parser class. + """ + + GETTERCRE = re.compile(r"^get(?P<name>.+)$") + + def __init__(self, parser): + self._parser = parser + self._data = {} + for getter in dir(self._parser): + m = self.GETTERCRE.match(getter) + if not m or not callable(getattr(self._parser, getter)): + continue + self._data[m.group('name')] = None # See class docstring. + + def __getitem__(self, key): + return self._data[key] + + def __setitem__(self, key, value): + try: + k = 'get' + key + except TypeError: + raise ValueError('Incompatible key: {} (type: {})' + ''.format(key, type(key))) + if k == 'get': + raise ValueError('Incompatible key: cannot use "" as a name') + self._data[key] = value + func = functools.partial(self._parser._get_conv, conv=value) + func.converter = value + setattr(self._parser, k, func) + for proxy in self._parser.values(): + getter = functools.partial(proxy.get, _impl=func) + setattr(proxy, k, getter) + + def __delitem__(self, key): + try: + k = 'get' + (key or None) + except TypeError: + raise KeyError(key) + del self._data[key] + for inst in itertools.chain((self._parser,), self._parser.values()): + try: + delattr(inst, k) + except AttributeError: + # don't raise since the entry was present in _data, silently + # clean up + continue + + def __iter__(self): + return iter(self._data) + + def __len__(self): + return len(self._data) diff --git a/Lib/contextlib.py b/Lib/contextlib.py index d3219f6c1502..2fbc90cdc8ca 100644 --- a/Lib/contextlib.py +++ b/Lib/contextlib.py @@ -5,7 +5,7 @@ from functools import wraps __all__ = ["contextmanager", "closing", "ContextDecorator", "ExitStack", - "redirect_stdout", "suppress"] + "redirect_stdout", "redirect_stderr", "suppress"] class ContextDecorator(object): @@ -151,8 +151,27 @@ def __enter__(self): def __exit__(self, *exc_info): self.thing.close() -class redirect_stdout: - """Context manager for temporarily redirecting stdout to another file + +class _RedirectStream: + + _stream = None + + def __init__(self, new_target): + self._new_target = new_target + # We use a list of old targets to make this CM re-entrant + self._old_targets = [] + + def __enter__(self): + self._old_targets.append(getattr(sys, self._stream)) + setattr(sys, self._stream, self._new_target) + return self._new_target + + def __exit__(self, exctype, excinst, exctb): + setattr(sys, self._stream, self._old_targets.pop()) + + +class redirect_stdout(_RedirectStream): + """Context manager for temporarily redirecting stdout to another file. # How to send help() to stderr with redirect_stdout(sys.stderr): @@ -164,18 +183,13 @@ class redirect_stdout: help(pow) """ - def __init__(self, new_target): - self._new_target = new_target - # We use a list of old targets to make this CM re-entrant - self._old_targets = [] + _stream = "stdout" - def __enter__(self): - self._old_targets.append(sys.stdout) - sys.stdout = self._new_target - return self._new_target - def __exit__(self, exctype, excinst, exctb): - sys.stdout = self._old_targets.pop() +class redirect_stderr(_RedirectStream): + """Context manager for temporarily redirecting stderr to another file.""" + + _stream = "stderr" class suppress: @@ -298,11 +312,17 @@ def __exit__(self, *exc_details): # we were actually nesting multiple with statements frame_exc = sys.exc_info()[1] def _fix_exception_context(new_exc, old_exc): + # Context may not be correct, so find the end of the chain while 1: exc_context = new_exc.__context__ - if exc_context in (None, frame_exc): + if exc_context is old_exc: + # Context is already set correctly (see issue 20317) + return + if exc_context is None or exc_context is frame_exc: break new_exc = exc_context + # Change the end of the chain to point to the exception + # we expect it to reference new_exc.__context__ = old_exc # Callbacks are invoked in LIFO order to match the behaviour of diff --git a/Lib/copy.py b/Lib/copy.py index d26bcdbff6ae..383609bc648f 100644 --- a/Lib/copy.py +++ b/Lib/copy.py @@ -110,7 +110,7 @@ def copy(x): def _copy_immutable(x): return x for t in (type(None), int, float, bool, str, tuple, - frozenset, type, range, + bytes, frozenset, type, range, types.BuiltinFunctionType, type(Ellipsis), types.FunctionType, weakref.ref): d[t] = _copy_immutable @@ -221,17 +221,15 @@ def _deepcopy_list(x, memo): d[list] = _deepcopy_list def _deepcopy_tuple(x, memo): - y = [] - for a in x: - y.append(deepcopy(a, memo)) + y = [deepcopy(a, memo) for a in x] # We're not going to put the tuple in the memo, but it's still important we # check for it, in case the tuple contains recursive mutable structures. try: return memo[id(x)] except KeyError: pass - for i in range(len(x)): - if x[i] is not y[i]: + for k, j in zip(x, y): + if k is not j: y = tuple(y) break else: diff --git a/Lib/ctypes/__init__.py b/Lib/ctypes/__init__.py index e34c646e2d11..055294c414f0 100644 --- a/Lib/ctypes/__init__.py +++ b/Lib/ctypes/__init__.py @@ -49,7 +49,7 @@ def create_string_buffer(init, size=None): create_string_buffer(anInteger) -> character array create_string_buffer(aString, anInteger) -> character array """ - if isinstance(init, (str, bytes)): + if isinstance(init, bytes): if size is None: size = len(init)+1 buftype = c_char * size @@ -284,7 +284,7 @@ def create_unicode_buffer(init, size=None): create_unicode_buffer(anInteger) -> character array create_unicode_buffer(aString, anInteger) -> character array """ - if isinstance(init, (str, bytes)): + if isinstance(init, str): if size is None: size = len(init)+1 buftype = c_wchar * size @@ -353,7 +353,7 @@ class _FuncPtr(_CFuncPtr): self._handle = handle def __repr__(self): - return "<%s '%s', handle %x at %x>" % \ + return "<%s '%s', handle %x at %#x>" % \ (self.__class__.__name__, self._name, (self._handle & (_sys.maxsize*2 + 1)), id(self) & (_sys.maxsize*2 + 1)) diff --git a/Lib/ctypes/_endian.py b/Lib/ctypes/_endian.py index dae65fc2152d..37444bd6a7dd 100644 --- a/Lib/ctypes/_endian.py +++ b/Lib/ctypes/_endian.py @@ -45,6 +45,7 @@ def __setattr__(self, attrname, value): class BigEndianStructure(Structure, metaclass=_swapped_meta): """Structure with big endian byte order""" + __slots__ = () _swappedbytes_ = None elif sys.byteorder == "big": @@ -53,6 +54,7 @@ class BigEndianStructure(Structure, metaclass=_swapped_meta): BigEndianStructure = Structure class LittleEndianStructure(Structure, metaclass=_swapped_meta): """Structure with little endian byte order""" + __slots__ = () _swappedbytes_ = None else: diff --git a/Lib/ctypes/test/__init__.py b/Lib/ctypes/test/__init__.py index 7c72210496e4..26a70b769634 100644 --- a/Lib/ctypes/test/__init__.py +++ b/Lib/ctypes/test/__init__.py @@ -1,208 +1,14 @@ -import os, sys, unittest, getopt, time +import os +import unittest +from test import support -use_resources = [] +# skip tests if _ctypes was not built +ctypes = support.import_module('ctypes') +ctypes_symbols = dir(ctypes) -class ResourceDenied(Exception): - """Test skipped because it requested a disallowed resource. +def need_symbol(name): + return unittest.skipUnless(name in ctypes_symbols, + '{!r} is required'.format(name)) - This is raised when a test calls requires() for a resource that - has not be enabled. Resources are defined by test modules. - """ - -def is_resource_enabled(resource): - """Test whether a resource is enabled. - - If the caller's module is __main__ then automatically return True.""" - if sys._getframe().f_back.f_globals.get("__name__") == "__main__": - return True - result = use_resources is not None and \ - (resource in use_resources or "*" in use_resources) - if not result: - _unavail[resource] = None - return result - -_unavail = {} -def requires(resource, msg=None): - """Raise ResourceDenied if the specified resource is not available. - - If the caller's module is __main__ then automatically return True.""" - # see if the caller's module is __main__ - if so, treat as if - # the resource was set - if sys._getframe().f_back.f_globals.get("__name__") == "__main__": - return - if not is_resource_enabled(resource): - if msg is None: - msg = "Use of the `%s' resource not enabled" % resource - raise ResourceDenied(msg) - -def find_package_modules(package, mask): - import fnmatch - if (package.__loader__ is not None and - hasattr(package.__loader__, '_files')): - path = package.__name__.replace(".", os.path.sep) - mask = os.path.join(path, mask) - for fnm in package.__loader__._files.keys(): - if fnmatch.fnmatchcase(fnm, mask): - yield os.path.splitext(fnm)[0].replace(os.path.sep, ".") - else: - path = package.__path__[0] - for fnm in os.listdir(path): - if fnmatch.fnmatchcase(fnm, mask): - yield "%s.%s" % (package.__name__, os.path.splitext(fnm)[0]) - -def get_tests(package, mask, verbosity, exclude=()): - """Return a list of skipped test modules, and a list of test cases.""" - tests = [] - skipped = [] - for modname in find_package_modules(package, mask): - if modname.split(".")[-1] in exclude: - skipped.append(modname) - if verbosity > 1: - print("Skipped %s: excluded" % modname, file=sys.stderr) - continue - try: - mod = __import__(modname, globals(), locals(), ['*']) - except (ResourceDenied, unittest.SkipTest) as detail: - skipped.append(modname) - if verbosity > 1: - print("Skipped %s: %s" % (modname, detail), file=sys.stderr) - continue - for name in dir(mod): - if name.startswith("_"): - continue - o = getattr(mod, name) - if type(o) is type(unittest.TestCase) and issubclass(o, unittest.TestCase): - tests.append(o) - return skipped, tests - -def usage(): - print(__doc__) - return 1 - -def test_with_refcounts(runner, verbosity, testcase): - """Run testcase several times, tracking reference counts.""" - import gc - import ctypes - ptc = ctypes._pointer_type_cache.copy() - cfc = ctypes._c_functype_cache.copy() - wfc = ctypes._win_functype_cache.copy() - - # when searching for refcount leaks, we have to manually reset any - # caches that ctypes has. - def cleanup(): - ctypes._pointer_type_cache = ptc.copy() - ctypes._c_functype_cache = cfc.copy() - ctypes._win_functype_cache = wfc.copy() - gc.collect() - - test = unittest.makeSuite(testcase) - for i in range(5): - rc = sys.gettotalrefcount() - runner.run(test) - cleanup() - COUNT = 5 - refcounts = [None] * COUNT - for i in range(COUNT): - rc = sys.gettotalrefcount() - runner.run(test) - cleanup() - refcounts[i] = sys.gettotalrefcount() - rc - if filter(None, refcounts): - print("%s leaks:\n\t" % testcase, refcounts) - elif verbosity: - print("%s: ok." % testcase) - -class TestRunner(unittest.TextTestRunner): - def run(self, test, skipped): - "Run the given test case or test suite." - # Same as unittest.TextTestRunner.run, except that it reports - # skipped tests. - result = self._makeResult() - startTime = time.time() - test(result) - stopTime = time.time() - timeTaken = stopTime - startTime - result.printErrors() - self.stream.writeln(result.separator2) - run = result.testsRun - if _unavail: #skipped: - requested = list(_unavail.keys()) - requested.sort() - self.stream.writeln("Ran %d test%s in %.3fs (%s module%s skipped)" % - (run, run != 1 and "s" or "", timeTaken, - len(skipped), - len(skipped) != 1 and "s" or "")) - self.stream.writeln("Unavailable resources: %s" % ", ".join(requested)) - else: - self.stream.writeln("Ran %d test%s in %.3fs" % - (run, run != 1 and "s" or "", timeTaken)) - self.stream.writeln() - if not result.wasSuccessful(): - self.stream.write("FAILED (") - failed, errored = map(len, (result.failures, result.errors)) - if failed: - self.stream.write("failures=%d" % failed) - if errored: - if failed: self.stream.write(", ") - self.stream.write("errors=%d" % errored) - self.stream.writeln(")") - else: - self.stream.writeln("OK") - return result - - -def main(*packages): - try: - opts, args = getopt.getopt(sys.argv[1:], "rqvu:x:") - except getopt.error: - return usage() - - verbosity = 1 - search_leaks = False - exclude = [] - for flag, value in opts: - if flag == "-q": - verbosity -= 1 - elif flag == "-v": - verbosity += 1 - elif flag == "-r": - try: - sys.gettotalrefcount - except AttributeError: - print("-r flag requires Python debug build", file=sys.stderr) - return -1 - search_leaks = True - elif flag == "-u": - use_resources.extend(value.split(",")) - elif flag == "-x": - exclude.extend(value.split(",")) - - mask = "test_*.py" - if args: - mask = args[0] - - for package in packages: - run_tests(package, mask, verbosity, search_leaks, exclude) - - -def run_tests(package, mask, verbosity, search_leaks, exclude): - skipped, testcases = get_tests(package, mask, verbosity, exclude) - runner = TestRunner(verbosity=verbosity) - - suites = [unittest.makeSuite(o) for o in testcases] - suite = unittest.TestSuite(suites) - result = runner.run(suite, skipped) - - if search_leaks: - # hunt for refcount leaks - runner = BasicTestRunner() - for t in testcases: - test_with_refcounts(runner, verbosity, t) - - return bool(result.errors) - -class BasicTestRunner: - def run(self, test): - result = unittest.TestResult() - test(result) - return result +def load_tests(*args): + return support.load_package_tests(os.path.dirname(__file__), *args) diff --git a/Lib/ctypes/test/__main__.py b/Lib/ctypes/test/__main__.py new file mode 100644 index 000000000000..362a9ec8cff6 --- /dev/null +++ b/Lib/ctypes/test/__main__.py @@ -0,0 +1,4 @@ +from ctypes.test import load_tests +import unittest + +unittest.main() diff --git a/Lib/ctypes/test/runtests.py b/Lib/ctypes/test/runtests.py deleted file mode 100644 index b7a2b264721e..000000000000 --- a/Lib/ctypes/test/runtests.py +++ /dev/null @@ -1,19 +0,0 @@ -"""Usage: runtests.py [-q] [-r] [-v] [-u resources] [mask] - -Run all tests found in this directory, and print a summary of the results. -Command line flags: - -q quiet mode: don't print anything while the tests are running - -r run tests repeatedly, look for refcount leaks - -u<resources> - Add resources to the lits of allowed resources. '*' allows all - resources. - -v verbose mode: print the test currently executed - -x<test1[,test2...]> - Exclude specified tests. - mask mask to select filenames containing testcases, wildcards allowed -""" -import sys -import ctypes.test - -if __name__ == "__main__": - sys.exit(ctypes.test.main(ctypes.test)) diff --git a/Lib/ctypes/test/test_arrays.py b/Lib/ctypes/test/test_arrays.py index 99b97aa7d8a1..8ca77e0f308a 100644 --- a/Lib/ctypes/test/test_arrays.py +++ b/Lib/ctypes/test/test_arrays.py @@ -1,6 +1,8 @@ import unittest from ctypes import * +from ctypes.test import need_symbol + formats = "bBhHiIlLqQfd" formats = c_byte, c_ubyte, c_short, c_ushort, c_int, c_uint, \ @@ -98,20 +100,16 @@ def test_from_address(self): self.assertEqual(sz[1:4:2], b"o") self.assertEqual(sz.value, b"foo") - try: - create_unicode_buffer - except NameError: - pass - else: - def test_from_addressW(self): - p = create_unicode_buffer("foo") - sz = (c_wchar * 3).from_address(addressof(p)) - self.assertEqual(sz[:], "foo") - self.assertEqual(sz[::], "foo") - self.assertEqual(sz[::-1], "oof") - self.assertEqual(sz[::3], "f") - self.assertEqual(sz[1:4:2], "o") - self.assertEqual(sz.value, "foo") + @need_symbol('create_unicode_buffer') + def test_from_addressW(self): + p = create_unicode_buffer("foo") + sz = (c_wchar * 3).from_address(addressof(p)) + self.assertEqual(sz[:], "foo") + self.assertEqual(sz[::], "foo") + self.assertEqual(sz[::-1], "oof") + self.assertEqual(sz[::3], "f") + self.assertEqual(sz[1:4:2], "o") + self.assertEqual(sz.value, "foo") def test_cache(self): # Array types are cached internally in the _ctypes extension, diff --git a/Lib/ctypes/test/test_as_parameter.py b/Lib/ctypes/test/test_as_parameter.py index 43703e3b6ea3..948b4632154d 100644 --- a/Lib/ctypes/test/test_as_parameter.py +++ b/Lib/ctypes/test/test_as_parameter.py @@ -1,5 +1,6 @@ import unittest from ctypes import * +from ctypes.test import need_symbol import _ctypes_test dll = CDLL(_ctypes_test.__file__) @@ -17,11 +18,8 @@ class BasicWrapTestCase(unittest.TestCase): def wrap(self, param): return param + @need_symbol('c_wchar') def test_wchar_parm(self): - try: - c_wchar - except NameError: - return f = dll._testfunc_i_bhilfd f.argtypes = [c_byte, c_wchar, c_int, c_long, c_float, c_double] result = f(self.wrap(1), self.wrap("x"), self.wrap(3), self.wrap(4), self.wrap(5.0), self.wrap(6.0)) diff --git a/Lib/ctypes/test/test_bitfields.py b/Lib/ctypes/test/test_bitfields.py index c89ee345ee8f..9ca053d20157 100644 --- a/Lib/ctypes/test/test_bitfields.py +++ b/Lib/ctypes/test/test_bitfields.py @@ -1,4 +1,5 @@ from ctypes import * +from ctypes.test import need_symbol import unittest import os @@ -127,20 +128,18 @@ def test_nonint_types(self): result = self.fail_fields(("a", c_char, 1)) self.assertEqual(result, (TypeError, 'bit fields not allowed for type c_char')) - try: - c_wchar - except NameError: - pass - else: - result = self.fail_fields(("a", c_wchar, 1)) - self.assertEqual(result, (TypeError, 'bit fields not allowed for type c_wchar')) - class Dummy(Structure): _fields_ = [] result = self.fail_fields(("a", Dummy, 1)) self.assertEqual(result, (TypeError, 'bit fields not allowed for type Dummy')) + @need_symbol('c_wchar') + def test_c_wchar(self): + result = self.fail_fields(("a", c_wchar, 1)) + self.assertEqual(result, + (TypeError, 'bit fields not allowed for type c_wchar')) + def test_single_bitfield_size(self): for c_typ in int_types: result = self.fail_fields(("a", c_typ, -1)) @@ -207,7 +206,7 @@ def test_mixed_2(self): class X(Structure): _fields_ = [("a", c_byte, 4), ("b", c_int, 32)] - self.assertEqual(sizeof(X), sizeof(c_int)*2) + self.assertEqual(sizeof(X), alignment(c_int)+sizeof(c_int)) def test_mixed_3(self): class X(Structure): @@ -240,7 +239,7 @@ class Y(Structure): _anonymous_ = ["_"] _fields_ = [("_", X)] - @unittest.skipUnless(hasattr(ctypes, "c_uint32"), "c_int32 is required") + @need_symbol('c_uint32') def test_uint32(self): class X(Structure): _fields_ = [("a", c_uint32, 32)] @@ -250,7 +249,7 @@ class X(Structure): x.a = 0xFDCBA987 self.assertEqual(x.a, 0xFDCBA987) - @unittest.skipUnless(hasattr(ctypes, "c_uint64"), "c_int64 is required") + @need_symbol('c_uint64') def test_uint64(self): class X(Structure): _fields_ = [("a", c_uint64, 64)] diff --git a/Lib/ctypes/test/test_buffers.py b/Lib/ctypes/test/test_buffers.py index 0d12f47afef1..166faaf4e4b8 100644 --- a/Lib/ctypes/test/test_buffers.py +++ b/Lib/ctypes/test/test_buffers.py @@ -1,4 +1,5 @@ from ctypes import * +from ctypes.test import need_symbol import unittest class StringBufferTestCase(unittest.TestCase): @@ -20,43 +21,44 @@ def test_buffer(self): self.assertEqual(b[::2], b"ac") self.assertEqual(b[::5], b"a") + self.assertRaises(TypeError, create_string_buffer, "abc") + def test_buffer_interface(self): self.assertEqual(len(bytearray(create_string_buffer(0))), 0) self.assertEqual(len(bytearray(create_string_buffer(1))), 1) - try: - c_wchar - except NameError: - pass - else: - def test_unicode_buffer(self): - b = create_unicode_buffer(32) - self.assertEqual(len(b), 32) - self.assertEqual(sizeof(b), 32 * sizeof(c_wchar)) - self.assertIs(type(b[0]), str) - - b = create_unicode_buffer("abc") - self.assertEqual(len(b), 4) # trailing nul char - self.assertEqual(sizeof(b), 4 * sizeof(c_wchar)) - self.assertIs(type(b[0]), str) - self.assertEqual(b[0], "a") - self.assertEqual(b[:], "abc\0") - self.assertEqual(b[::], "abc\0") - self.assertEqual(b[::-1], "\0cba") - self.assertEqual(b[::2], "ac") - self.assertEqual(b[::5], "a") - - def test_unicode_conversion(self): - b = create_unicode_buffer("abc") - self.assertEqual(len(b), 4) # trailing nul char - self.assertEqual(sizeof(b), 4 * sizeof(c_wchar)) - self.assertIs(type(b[0]), str) - self.assertEqual(b[0], "a") - self.assertEqual(b[:], "abc\0") - self.assertEqual(b[::], "abc\0") - self.assertEqual(b[::-1], "\0cba") - self.assertEqual(b[::2], "ac") - self.assertEqual(b[::5], "a") + @need_symbol('c_wchar') + def test_unicode_buffer(self): + b = create_unicode_buffer(32) + self.assertEqual(len(b), 32) + self.assertEqual(sizeof(b), 32 * sizeof(c_wchar)) + self.assertIs(type(b[0]), str) + + b = create_unicode_buffer("abc") + self.assertEqual(len(b), 4) # trailing nul char + self.assertEqual(sizeof(b), 4 * sizeof(c_wchar)) + self.assertIs(type(b[0]), str) + self.assertEqual(b[0], "a") + self.assertEqual(b[:], "abc\0") + self.assertEqual(b[::], "abc\0") + self.assertEqual(b[::-1], "\0cba") + self.assertEqual(b[::2], "ac") + self.assertEqual(b[::5], "a") + + self.assertRaises(TypeError, create_unicode_buffer, b"abc") + + @need_symbol('c_wchar') + def test_unicode_conversion(self): + b = create_unicode_buffer("abc") + self.assertEqual(len(b), 4) # trailing nul char + self.assertEqual(sizeof(b), 4 * sizeof(c_wchar)) + self.assertIs(type(b[0]), str) + self.assertEqual(b[0], "a") + self.assertEqual(b[:], "abc\0") + self.assertEqual(b[::], "abc\0") + self.assertEqual(b[::-1], "\0cba") + self.assertEqual(b[::2], "ac") + self.assertEqual(b[::5], "a") if __name__ == "__main__": unittest.main() diff --git a/Lib/ctypes/test/test_bytes.py b/Lib/ctypes/test/test_bytes.py index ee49c456e8ed..20fa05650340 100644 --- a/Lib/ctypes/test/test_bytes.py +++ b/Lib/ctypes/test/test_bytes.py @@ -6,27 +6,40 @@ class BytesTest(unittest.TestCase): def test_c_char(self): x = c_char(b"x") + self.assertRaises(TypeError, c_char, "x") x.value = b"y" + with self.assertRaises(TypeError): + x.value = "y" c_char.from_param(b"x") + self.assertRaises(TypeError, c_char.from_param, "x") (c_char * 3)(b"a", b"b", b"c") + self.assertRaises(TypeError, c_char * 3, "a", "b", "c") def test_c_wchar(self): x = c_wchar("x") + self.assertRaises(TypeError, c_wchar, b"x") x.value = "y" + with self.assertRaises(TypeError): + x.value = b"y" c_wchar.from_param("x") + self.assertRaises(TypeError, c_wchar.from_param, b"x") (c_wchar * 3)("a", "b", "c") + self.assertRaises(TypeError, c_wchar * 3, b"a", b"b", b"c") def test_c_char_p(self): c_char_p(b"foo bar") + self.assertRaises(TypeError, c_char_p, "foo bar") def test_c_wchar_p(self): c_wchar_p("foo bar") + self.assertRaises(TypeError, c_wchar_p, b"foo bar") def test_struct(self): class X(Structure): _fields_ = [("a", c_char * 3)] x = X(b"abc") + self.assertRaises(TypeError, X, "abc") self.assertEqual(x.a, b"abc") self.assertEqual(type(x.a), bytes) @@ -35,16 +48,18 @@ class X(Structure): _fields_ = [("a", c_wchar * 3)] x = X("abc") + self.assertRaises(TypeError, X, b"abc") self.assertEqual(x.a, "abc") self.assertEqual(type(x.a), str) - if sys.platform == "win32": - def test_BSTR(self): - from _ctypes import _SimpleCData - class BSTR(_SimpleCData): - _type_ = "X" + @unittest.skipUnless(sys.platform == "win32", 'Windows-specific test') + def test_BSTR(self): + from _ctypes import _SimpleCData + class BSTR(_SimpleCData): + _type_ = "X" + + BSTR("abc") - BSTR("abc") if __name__ == '__main__': unittest.main() diff --git a/Lib/ctypes/test/test_byteswap.py b/Lib/ctypes/test/test_byteswap.py index 63dde135192d..01c97e83ca7a 100644 --- a/Lib/ctypes/test/test_byteswap.py +++ b/Lib/ctypes/test/test_byteswap.py @@ -14,13 +14,34 @@ def bin(s): # For Structures and Unions, these types are created on demand. class Test(unittest.TestCase): - def X_test(self): + @unittest.skip('test disabled') + def test_X(self): print(sys.byteorder, file=sys.stderr) for i in range(32): bits = BITS() setattr(bits, "i%s" % i, 1) dump(bits) + def test_slots(self): + class BigPoint(BigEndianStructure): + __slots__ = () + _fields_ = [("x", c_int), ("y", c_int)] + + class LowPoint(LittleEndianStructure): + __slots__ = () + _fields_ = [("x", c_int), ("y", c_int)] + + big = BigPoint() + little = LowPoint() + big.x = 4 + big.y = 2 + little.x = 2 + little.y = 4 + with self.assertRaises(AttributeError): + big.z = 42 + with self.assertRaises(AttributeError): + little.z = 24 + def test_endian_short(self): if sys.byteorder == "little": self.assertIs(c_short.__ctype_le__, c_short) diff --git a/Lib/ctypes/test/test_callbacks.py b/Lib/ctypes/test/test_callbacks.py index 5600b437c1f5..3824f7c9fd9e 100644 --- a/Lib/ctypes/test/test_callbacks.py +++ b/Lib/ctypes/test/test_callbacks.py @@ -1,5 +1,6 @@ import unittest from ctypes import * +from ctypes.test import need_symbol import _ctypes_test class Callbacks(unittest.TestCase): @@ -88,9 +89,10 @@ def test_char(self): # disabled: would now (correctly) raise a RuntimeWarning about # a memory leak. A callback function cannot return a non-integral # C type without causing a memory leak. -## def test_char_p(self): -## self.check_type(c_char_p, "abc") -## self.check_type(c_char_p, "def") + @unittest.skip('test disabled') + def test_char_p(self): + self.check_type(c_char_p, "abc") + self.check_type(c_char_p, "def") def test_pyobject(self): o = () @@ -142,13 +144,12 @@ def __del__(self): CFUNCTYPE(None)(lambda x=Nasty(): None) -try: - WINFUNCTYPE -except NameError: - pass -else: - class StdcallCallbacks(Callbacks): +@need_symbol('WINFUNCTYPE') +class StdcallCallbacks(Callbacks): + try: functype = WINFUNCTYPE + except NameError: + pass ################################################################ @@ -178,7 +179,7 @@ def test_issue_8959_a(self): from ctypes.util import find_library libc_path = find_library("c") if not libc_path: - return # cannot test + self.skipTest('could not find libc') libc = CDLL(libc_path) @CFUNCTYPE(c_int, POINTER(c_int), POINTER(c_int)) @@ -190,23 +191,19 @@ def cmp_func(a, b): libc.qsort(array, len(array), sizeof(c_int), cmp_func) self.assertEqual(array[:], [1, 5, 7, 33, 99]) - try: - WINFUNCTYPE - except NameError: - pass - else: - def test_issue_8959_b(self): - from ctypes.wintypes import BOOL, HWND, LPARAM - global windowCount - windowCount = 0 + @need_symbol('WINFUNCTYPE') + def test_issue_8959_b(self): + from ctypes.wintypes import BOOL, HWND, LPARAM + global windowCount + windowCount = 0 - @WINFUNCTYPE(BOOL, HWND, LPARAM) - def EnumWindowsCallbackFunc(hwnd, lParam): - global windowCount - windowCount += 1 - return True #Allow windows to keep enumerating + @WINFUNCTYPE(BOOL, HWND, LPARAM) + def EnumWindowsCallbackFunc(hwnd, lParam): + global windowCount + windowCount += 1 + return True #Allow windows to keep enumerating - windll.user32.EnumWindows(EnumWindowsCallbackFunc, 0) + windll.user32.EnumWindows(EnumWindowsCallbackFunc, 0) def test_callback_register_int(self): # Issue #8275: buggy handling of callback args under Win64 diff --git a/Lib/ctypes/test/test_cast.py b/Lib/ctypes/test/test_cast.py index 32496f686365..187d2bde143d 100644 --- a/Lib/ctypes/test/test_cast.py +++ b/Lib/ctypes/test/test_cast.py @@ -1,4 +1,5 @@ from ctypes import * +from ctypes.test import need_symbol import unittest import sys @@ -75,15 +76,11 @@ def test_char_p(self): self.assertEqual(cast(cast(s, c_void_p), c_char_p).value, b"hiho") - try: - c_wchar_p - except NameError: - pass - else: - def test_wchar_p(self): - s = c_wchar_p("hiho") - self.assertEqual(cast(cast(s, c_void_p), c_wchar_p).value, - "hiho") + @need_symbol('c_wchar_p') + def test_wchar_p(self): + s = c_wchar_p("hiho") + self.assertEqual(cast(cast(s, c_void_p), c_wchar_p).value, + "hiho") if __name__ == "__main__": unittest.main() diff --git a/Lib/ctypes/test/test_cfuncs.py b/Lib/ctypes/test/test_cfuncs.py index a080496713ab..ac2240fa197d 100644 --- a/Lib/ctypes/test/test_cfuncs.py +++ b/Lib/ctypes/test/test_cfuncs.py @@ -3,6 +3,7 @@ import unittest from ctypes import * +from ctypes.test import need_symbol import _ctypes_test @@ -193,7 +194,7 @@ def test_void(self): try: WinDLL except NameError: - pass + def stdcall_dll(*_): pass else: class stdcall_dll(WinDLL): def __getattr__(self, name): @@ -203,9 +204,9 @@ def __getattr__(self, name): setattr(self, name, func) return func - class stdcallCFunctions(CFunctions): - _dll = stdcall_dll(_ctypes_test.__file__) - pass +@need_symbol('WinDLL') +class stdcallCFunctions(CFunctions): + _dll = stdcall_dll(_ctypes_test.__file__) if __name__ == '__main__': unittest.main() diff --git a/Lib/ctypes/test/test_checkretval.py b/Lib/ctypes/test/test_checkretval.py index 19bb8135b3b6..e9567dc39125 100644 --- a/Lib/ctypes/test/test_checkretval.py +++ b/Lib/ctypes/test/test_checkretval.py @@ -1,6 +1,7 @@ import unittest from ctypes import * +from ctypes.test import need_symbol class CHECKED(c_int): def _check_retval_(value): @@ -25,15 +26,11 @@ def test_checkretval(self): del dll._testfunc_p_p.restype self.assertEqual(42, dll._testfunc_p_p(42)) - try: - oledll - except NameError: - pass - else: - def test_oledll(self): - self.assertRaises(OSError, - oledll.oleaut32.CreateTypeLib2, - 0, None, None) + @need_symbol('oledll') + def test_oledll(self): + self.assertRaises(OSError, + oledll.oleaut32.CreateTypeLib2, + 0, None, None) if __name__ == "__main__": unittest.main() diff --git a/Lib/ctypes/test/test_errcheck.py b/Lib/ctypes/test/test_errcheck.py deleted file mode 100644 index a4913f920ddc..000000000000 --- a/Lib/ctypes/test/test_errcheck.py +++ /dev/null @@ -1,19 +0,0 @@ -import sys -from ctypes import * - -##class HMODULE(Structure): -## _fields_ = [("value", c_void_p)] - -## def __repr__(self): -## return "<HMODULE %s>" % self.value - -##windll.kernel32.GetModuleHandleA.restype = HMODULE - -##print windll.kernel32.GetModuleHandleA("python23.dll") -##print hex(sys.dllhandle) - -##def nonzero(handle): -## return (GetLastError(), handle) - -##windll.kernel32.GetModuleHandleA.errcheck = nonzero -##print windll.kernel32.GetModuleHandleA("spam") diff --git a/Lib/ctypes/test/test_find.py b/Lib/ctypes/test/test_find.py index c54b69bbc3fb..d8cd8ad60e90 100644 --- a/Lib/ctypes/test/test_find.py +++ b/Lib/ctypes/test/test_find.py @@ -1,82 +1,81 @@ import unittest +import os import sys +import test.support from ctypes import * from ctypes.util import find_library -from ctypes.test import is_resource_enabled - -if sys.platform == "win32": - lib_gl = find_library("OpenGL32") - lib_glu = find_library("Glu32") - lib_gle = None -elif sys.platform == "darwin": - lib_gl = lib_glu = find_library("OpenGL") - lib_gle = None -else: - lib_gl = find_library("GL") - lib_glu = find_library("GLU") - lib_gle = find_library("gle") - -## print, for debugging -if is_resource_enabled("printing"): - if lib_gl or lib_glu or lib_gle: - print("OpenGL libraries:") - for item in (("GL", lib_gl), - ("GLU", lib_glu), - ("gle", lib_gle)): - print("\t", item) - # On some systems, loading the OpenGL libraries needs the RTLD_GLOBAL mode. class Test_OpenGL_libs(unittest.TestCase): - def setUp(self): - self.gl = self.glu = self.gle = None + @classmethod + def setUpClass(cls): + lib_gl = lib_glu = lib_gle = None + if sys.platform == "win32": + lib_gl = find_library("OpenGL32") + lib_glu = find_library("Glu32") + elif sys.platform == "darwin": + lib_gl = lib_glu = find_library("OpenGL") + else: + lib_gl = find_library("GL") + lib_glu = find_library("GLU") + lib_gle = find_library("gle") + + ## print, for debugging + if test.support.verbose: + print("OpenGL libraries:") + for item in (("GL", lib_gl), + ("GLU", lib_glu), + ("gle", lib_gle)): + print("\t", item) + + cls.gl = cls.glu = cls.gle = None if lib_gl: - self.gl = CDLL(lib_gl, mode=RTLD_GLOBAL) + cls.gl = CDLL(lib_gl, mode=RTLD_GLOBAL) if lib_glu: - self.glu = CDLL(lib_glu, RTLD_GLOBAL) + cls.glu = CDLL(lib_glu, RTLD_GLOBAL) if lib_gle: try: - self.gle = CDLL(lib_gle) + cls.gle = CDLL(lib_gle) except OSError: pass - if lib_gl: - def test_gl(self): - if self.gl: - self.gl.glClearIndex - - if lib_glu: - def test_glu(self): - if self.glu: - self.glu.gluBeginCurve - - if lib_gle: - def test_gle(self): - if self.gle: - self.gle.gleGetJoinStyle + def test_gl(self): + if self.gl is None: + self.skipTest('lib_gl not available') + self.gl.glClearIndex -##if os.name == "posix" and sys.platform != "darwin": + def test_glu(self): + if self.glu is None: + self.skipTest('lib_glu not available') + self.glu.gluBeginCurve -## # On platforms where the default shared library suffix is '.so', -## # at least some libraries can be loaded as attributes of the cdll -## # object, since ctypes now tries loading the lib again -## # with '.so' appended of the first try fails. -## # -## # Won't work for libc, unfortunately. OTOH, it isn't -## # needed for libc since this is already mapped into the current -## # process (?) -## # -## # On MAC OSX, it won't work either, because dlopen() needs a full path, -## # and the default suffix is either none or '.dylib'. + def test_gle(self): + if self.gle is None: + self.skipTest('lib_gle not available') + self.gle.gleGetJoinStyle -## class LoadLibs(unittest.TestCase): -## def test_libm(self): -## import math -## libm = cdll.libm -## sqrt = libm.sqrt -## sqrt.argtypes = (c_double,) -## sqrt.restype = c_double -## self.assertEqual(sqrt(2), math.sqrt(2)) +# On platforms where the default shared library suffix is '.so', +# at least some libraries can be loaded as attributes of the cdll +# object, since ctypes now tries loading the lib again +# with '.so' appended of the first try fails. +# +# Won't work for libc, unfortunately. OTOH, it isn't +# needed for libc since this is already mapped into the current +# process (?) +# +# On MAC OSX, it won't work either, because dlopen() needs a full path, +# and the default suffix is either none or '.dylib'. +@unittest.skip('test disabled') +@unittest.skipUnless(os.name=="posix" and sys.platform != "darwin", + 'test not suitable for this platform') +class LoadLibs(unittest.TestCase): + def test_libm(self): + import math + libm = cdll.libm + sqrt = libm.sqrt + sqrt.argtypes = (c_double,) + sqrt.restype = c_double + self.assertEqual(sqrt(2), math.sqrt(2)) if __name__ == "__main__": unittest.main() diff --git a/Lib/ctypes/test/test_frombuffer.py b/Lib/ctypes/test/test_frombuffer.py index ffb27a6ea3d7..6aa2d1c5917b 100644 --- a/Lib/ctypes/test/test_frombuffer.py +++ b/Lib/ctypes/test/test_frombuffer.py @@ -10,7 +10,7 @@ def __init__(self): self._init_called = True class Test(unittest.TestCase): - def test_fom_buffer(self): + def test_from_buffer(self): a = array.array("i", range(16)) x = (c_int * 16).from_buffer(a) @@ -23,25 +23,37 @@ def test_fom_buffer(self): a[0], a[-1] = 200, -200 self.assertEqual(x[:], a.tolist()) - self.assertIn(a, x._objects.values()) + self.assertRaises(BufferError, a.append, 100) + self.assertRaises(BufferError, a.pop) - self.assertRaises(ValueError, - c_int.from_buffer, a, -1) + del x; del y; gc.collect(); gc.collect(); gc.collect() + a.append(100) + a.pop() + x = (c_int * 16).from_buffer(a) + + self.assertIn(a, [obj.obj if isinstance(obj, memoryview) else obj + for obj in x._objects.values()]) expected = x[:] del a; gc.collect(); gc.collect(); gc.collect() self.assertEqual(x[:], expected) - self.assertRaises(TypeError, - (c_char * 16).from_buffer, "a" * 16) + with self.assertRaises(TypeError): + (c_char * 16).from_buffer(b"a" * 16) + with self.assertRaises(TypeError): + (c_char * 16).from_buffer("a" * 16) - def test_fom_buffer_with_offset(self): + def test_from_buffer_with_offset(self): a = array.array("i", range(16)) x = (c_int * 15).from_buffer(a, sizeof(c_int)) self.assertEqual(x[:], a.tolist()[1:]) - self.assertRaises(ValueError, lambda: (c_int * 16).from_buffer(a, sizeof(c_int))) - self.assertRaises(ValueError, lambda: (c_int * 1).from_buffer(a, 16 * sizeof(c_int))) + with self.assertRaises(ValueError): + c_int.from_buffer(a, -1) + with self.assertRaises(ValueError): + (c_int * 16).from_buffer(a, sizeof(c_int)) + with self.assertRaises(ValueError): + (c_int * 1).from_buffer(a, 16 * sizeof(c_int)) def test_from_buffer_copy(self): a = array.array("i", range(16)) @@ -56,26 +68,30 @@ def test_from_buffer_copy(self): a[0], a[-1] = 200, -200 self.assertEqual(x[:], list(range(16))) - self.assertEqual(x._objects, None) + a.append(100) + self.assertEqual(x[:], list(range(16))) - self.assertRaises(ValueError, - c_int.from_buffer, a, -1) + self.assertEqual(x._objects, None) del a; gc.collect(); gc.collect(); gc.collect() self.assertEqual(x[:], list(range(16))) x = (c_char * 16).from_buffer_copy(b"a" * 16) self.assertEqual(x[:], b"a" * 16) + with self.assertRaises(TypeError): + (c_char * 16).from_buffer_copy("a" * 16) - def test_fom_buffer_copy_with_offset(self): + def test_from_buffer_copy_with_offset(self): a = array.array("i", range(16)) x = (c_int * 15).from_buffer_copy(a, sizeof(c_int)) self.assertEqual(x[:], a.tolist()[1:]) - self.assertRaises(ValueError, - (c_int * 16).from_buffer_copy, a, sizeof(c_int)) - self.assertRaises(ValueError, - (c_int * 1).from_buffer_copy, a, 16 * sizeof(c_int)) + with self.assertRaises(ValueError): + c_int.from_buffer_copy(a, -1) + with self.assertRaises(ValueError): + (c_int * 16).from_buffer_copy(a, sizeof(c_int)) + with self.assertRaises(ValueError): + (c_int * 1).from_buffer_copy(a, 16 * sizeof(c_int)) if __name__ == '__main__': unittest.main() diff --git a/Lib/ctypes/test/test_functions.py b/Lib/ctypes/test/test_functions.py index 07eeb6892461..75628924206b 100644 --- a/Lib/ctypes/test/test_functions.py +++ b/Lib/ctypes/test/test_functions.py @@ -6,6 +6,7 @@ """ from ctypes import * +from ctypes.test import need_symbol import sys, unittest try: @@ -63,22 +64,16 @@ class X(object, Structure): pass + @need_symbol('c_wchar') def test_wchar_parm(self): - try: - c_wchar - except NameError: - return f = dll._testfunc_i_bhilfd f.argtypes = [c_byte, c_wchar, c_int, c_long, c_float, c_double] result = f(1, "x", 3, 4, 5.0, 6.0) self.assertEqual(result, 139) self.assertEqual(type(result), int) + @need_symbol('c_wchar') def test_wchar_result(self): - try: - c_wchar - except NameError: - return f = dll._testfunc_i_bhilfd f.argtypes = [c_byte, c_short, c_int, c_long, c_float, c_double] f.restype = c_wchar @@ -155,11 +150,8 @@ def test_longdoubleresult(self): self.assertEqual(result, -21) self.assertEqual(type(result), float) + @need_symbol('c_longlong') def test_longlongresult(self): - try: - c_longlong - except NameError: - return f = dll._testfunc_q_bhilfd f.restype = c_longlong f.argtypes = [c_byte, c_short, c_int, c_long, c_float, c_double] @@ -296,6 +288,7 @@ def callback(value): result = f(-10, cb) self.assertEqual(result, -18) + @need_symbol('c_longlong') def test_longlong_callbacks(self): f = dll._testfunc_callback_q_qf @@ -348,16 +341,16 @@ class S2H(Structure): s2h = dll.ret_2h_func(inp) self.assertEqual((s2h.x, s2h.y), (99*2, 88*3)) - if sys.platform == "win32": - def test_struct_return_2H_stdcall(self): - class S2H(Structure): - _fields_ = [("x", c_short), - ("y", c_short)] + @unittest.skipUnless(sys.platform == "win32", 'Windows-specific test') + def test_struct_return_2H_stdcall(self): + class S2H(Structure): + _fields_ = [("x", c_short), + ("y", c_short)] - windll.s_ret_2h_func.restype = S2H - windll.s_ret_2h_func.argtypes = [S2H] - s2h = windll.s_ret_2h_func(S2H(99, 88)) - self.assertEqual((s2h.x, s2h.y), (99*2, 88*3)) + windll.s_ret_2h_func.restype = S2H + windll.s_ret_2h_func.argtypes = [S2H] + s2h = windll.s_ret_2h_func(S2H(99, 88)) + self.assertEqual((s2h.x, s2h.y), (99*2, 88*3)) def test_struct_return_8H(self): class S8I(Structure): @@ -376,23 +369,24 @@ class S8I(Structure): self.assertEqual((s8i.a, s8i.b, s8i.c, s8i.d, s8i.e, s8i.f, s8i.g, s8i.h), (9*2, 8*3, 7*4, 6*5, 5*6, 4*7, 3*8, 2*9)) - if sys.platform == "win32": - def test_struct_return_8H_stdcall(self): - class S8I(Structure): - _fields_ = [("a", c_int), - ("b", c_int), - ("c", c_int), - ("d", c_int), - ("e", c_int), - ("f", c_int), - ("g", c_int), - ("h", c_int)] - windll.s_ret_8i_func.restype = S8I - windll.s_ret_8i_func.argtypes = [S8I] - inp = S8I(9, 8, 7, 6, 5, 4, 3, 2) - s8i = windll.s_ret_8i_func(inp) - self.assertEqual((s8i.a, s8i.b, s8i.c, s8i.d, s8i.e, s8i.f, s8i.g, s8i.h), - (9*2, 8*3, 7*4, 6*5, 5*6, 4*7, 3*8, 2*9)) + @unittest.skipUnless(sys.platform == "win32", 'Windows-specific test') + def test_struct_return_8H_stdcall(self): + class S8I(Structure): + _fields_ = [("a", c_int), + ("b", c_int), + ("c", c_int), + ("d", c_int), + ("e", c_int), + ("f", c_int), + ("g", c_int), + ("h", c_int)] + windll.s_ret_8i_func.restype = S8I + windll.s_ret_8i_func.argtypes = [S8I] + inp = S8I(9, 8, 7, 6, 5, 4, 3, 2) + s8i = windll.s_ret_8i_func(inp) + self.assertEqual( + (s8i.a, s8i.b, s8i.c, s8i.d, s8i.e, s8i.f, s8i.g, s8i.h), + (9*2, 8*3, 7*4, 6*5, 5*6, 4*7, 3*8, 2*9)) def test_sf1651235(self): # see http://www.python.org/sf/1651235 diff --git a/Lib/ctypes/test/test_integers.py b/Lib/ctypes/test/test_integers.py deleted file mode 100644 index 62e4b08a2b64..000000000000 --- a/Lib/ctypes/test/test_integers.py +++ /dev/null @@ -1,5 +0,0 @@ -# superseded by test_numbers.py -import unittest - -if __name__ == '__main__': - unittest.main() diff --git a/Lib/ctypes/test/test_keeprefs.py b/Lib/ctypes/test/test_keeprefs.py index db8adfb4cac0..94c02573fa19 100644 --- a/Lib/ctypes/test/test_keeprefs.py +++ b/Lib/ctypes/test/test_keeprefs.py @@ -94,7 +94,8 @@ def test_p_cint(self): self.assertEqual(x._objects, {'1': i}) class DeletePointerTestCase(unittest.TestCase): - def X_test(self): + @unittest.skip('test disabled') + def test_X(self): class X(Structure): _fields_ = [("p", POINTER(c_char_p))] x = X() diff --git a/Lib/ctypes/test/test_loading.py b/Lib/ctypes/test/test_loading.py index 414363d8c82f..4fb89642e12a 100644 --- a/Lib/ctypes/test/test_loading.py +++ b/Lib/ctypes/test/test_loading.py @@ -1,38 +1,46 @@ from ctypes import * -import sys, unittest import os +import sys +import unittest +import test.support from ctypes.util import find_library -from ctypes.test import is_resource_enabled libc_name = None -if os.name == "nt": - libc_name = find_library("c") -elif os.name == "ce": - libc_name = "coredll" -elif sys.platform == "cygwin": - libc_name = "cygwin1.dll" -else: - libc_name = find_library("c") - -if is_resource_enabled("printing"): - print("libc_name is", libc_name) + +def setUpModule(): + global libc_name + if os.name == "nt": + libc_name = find_library("c") + elif os.name == "ce": + libc_name = "coredll" + elif sys.platform == "cygwin": + libc_name = "cygwin1.dll" + else: + libc_name = find_library("c") + + if test.support.verbose: + print("libc_name is", libc_name) class LoaderTest(unittest.TestCase): unknowndll = "xxrandomnamexx" - if libc_name is not None: - def test_load(self): - CDLL(libc_name) - CDLL(os.path.basename(libc_name)) - self.assertRaises(OSError, CDLL, self.unknowndll) + def test_load(self): + if libc_name is None: + self.skipTest('could not find libc') + CDLL(libc_name) + CDLL(os.path.basename(libc_name)) + self.assertRaises(OSError, CDLL, self.unknowndll) - if libc_name is not None and os.path.basename(libc_name) == "libc.so.6": - def test_load_version(self): - cdll.LoadLibrary("libc.so.6") - # linux uses version, libc 9 should not exist - self.assertRaises(OSError, cdll.LoadLibrary, "libc.so.9") - self.assertRaises(OSError, cdll.LoadLibrary, self.unknowndll) + def test_load_version(self): + if libc_name is None: + self.skipTest('could not find libc') + if os.path.basename(libc_name) != 'libc.so.6': + self.skipTest('wrong libc path for test') + cdll.LoadLibrary("libc.so.6") + # linux uses version, libc 9 should not exist + self.assertRaises(OSError, cdll.LoadLibrary, "libc.so.9") + self.assertRaises(OSError, cdll.LoadLibrary, self.unknowndll) def test_find(self): for name in ("c", "m"): @@ -41,66 +49,71 @@ def test_find(self): cdll.LoadLibrary(lib) CDLL(lib) - if os.name in ("nt", "ce"): - def test_load_library(self): - self.assertIsNotNone(libc_name) - if is_resource_enabled("printing"): - print(find_library("kernel32")) - print(find_library("user32")) - - if os.name == "nt": - windll.kernel32.GetModuleHandleW - windll["kernel32"].GetModuleHandleW - windll.LoadLibrary("kernel32").GetModuleHandleW - WinDLL("kernel32").GetModuleHandleW - elif os.name == "ce": - windll.coredll.GetModuleHandleW - windll["coredll"].GetModuleHandleW - windll.LoadLibrary("coredll").GetModuleHandleW - WinDLL("coredll").GetModuleHandleW - - def test_load_ordinal_functions(self): - import _ctypes_test - dll = WinDLL(_ctypes_test.__file__) - # We load the same function both via ordinal and name - func_ord = dll[2] - func_name = dll.GetString - # addressof gets the address where the function pointer is stored - a_ord = addressof(func_ord) - a_name = addressof(func_name) - f_ord_addr = c_void_p.from_address(a_ord).value - f_name_addr = c_void_p.from_address(a_name).value - self.assertEqual(hex(f_ord_addr), hex(f_name_addr)) - - self.assertRaises(AttributeError, dll.__getitem__, 1234) + @unittest.skipUnless(os.name in ("nt", "ce"), + 'test specific to Windows (NT/CE)') + def test_load_library(self): + self.assertIsNotNone(libc_name) + if test.support.verbose: + print(find_library("kernel32")) + print(find_library("user32")) - if os.name == "nt": - def test_1703286_A(self): - from _ctypes import LoadLibrary, FreeLibrary - # On winXP 64-bit, advapi32 loads at an address that does - # NOT fit into a 32-bit integer. FreeLibrary must be able - # to accept this address. - - # These are tests for http://www.python.org/sf/1703286 - handle = LoadLibrary("advapi32") - FreeLibrary(handle) - - def test_1703286_B(self): - # Since on winXP 64-bit advapi32 loads like described - # above, the (arbitrarily selected) CloseEventLog function - # also has a high address. 'call_function' should accept - # addresses so large. - from _ctypes import call_function - advapi32 = windll.advapi32 - # Calling CloseEventLog with a NULL argument should fail, - # but the call should not segfault or so. - self.assertEqual(0, advapi32.CloseEventLog(None)) - windll.kernel32.GetProcAddress.argtypes = c_void_p, c_char_p - windll.kernel32.GetProcAddress.restype = c_void_p - proc = windll.kernel32.GetProcAddress(advapi32._handle, b"CloseEventLog") - self.assertTrue(proc) - # This is the real test: call the function via 'call_function' - self.assertEqual(0, call_function(proc, (None,))) + if os.name == "nt": + windll.kernel32.GetModuleHandleW + windll["kernel32"].GetModuleHandleW + windll.LoadLibrary("kernel32").GetModuleHandleW + WinDLL("kernel32").GetModuleHandleW + elif os.name == "ce": + windll.coredll.GetModuleHandleW + windll["coredll"].GetModuleHandleW + windll.LoadLibrary("coredll").GetModuleHandleW + WinDLL("coredll").GetModuleHandleW + + @unittest.skipUnless(os.name in ("nt", "ce"), + 'test specific to Windows (NT/CE)') + def test_load_ordinal_functions(self): + import _ctypes_test + dll = WinDLL(_ctypes_test.__file__) + # We load the same function both via ordinal and name + func_ord = dll[2] + func_name = dll.GetString + # addressof gets the address where the function pointer is stored + a_ord = addressof(func_ord) + a_name = addressof(func_name) + f_ord_addr = c_void_p.from_address(a_ord).value + f_name_addr = c_void_p.from_address(a_name).value + self.assertEqual(hex(f_ord_addr), hex(f_name_addr)) + + self.assertRaises(AttributeError, dll.__getitem__, 1234) + + @unittest.skipUnless(os.name == "nt", 'Windows-specific test') + def test_1703286_A(self): + from _ctypes import LoadLibrary, FreeLibrary + # On winXP 64-bit, advapi32 loads at an address that does + # NOT fit into a 32-bit integer. FreeLibrary must be able + # to accept this address. + + # These are tests for http://www.python.org/sf/1703286 + handle = LoadLibrary("advapi32") + FreeLibrary(handle) + + @unittest.skipUnless(os.name == "nt", 'Windows-specific test') + def test_1703286_B(self): + # Since on winXP 64-bit advapi32 loads like described + # above, the (arbitrarily selected) CloseEventLog function + # also has a high address. 'call_function' should accept + # addresses so large. + from _ctypes import call_function + advapi32 = windll.advapi32 + # Calling CloseEventLog with a NULL argument should fail, + # but the call should not segfault or so. + self.assertEqual(0, advapi32.CloseEventLog(None)) + windll.kernel32.GetProcAddress.argtypes = c_void_p, c_char_p + windll.kernel32.GetProcAddress.restype = c_void_p + proc = windll.kernel32.GetProcAddress(advapi32._handle, + b"CloseEventLog") + self.assertTrue(proc) + # This is the real test: call the function via 'call_function' + self.assertEqual(0, call_function(proc, (None,))) if __name__ == "__main__": unittest.main() diff --git a/Lib/ctypes/test/test_macholib.py b/Lib/ctypes/test/test_macholib.py index fd2683764c79..6b3526951acf 100644 --- a/Lib/ctypes/test/test_macholib.py +++ b/Lib/ctypes/test/test_macholib.py @@ -43,18 +43,21 @@ def find_lib(name): raise ValueError("%s not found" % (name,)) class MachOTest(unittest.TestCase): - if sys.platform == "darwin": - def test_find(self): + @unittest.skipUnless(sys.platform == "darwin", 'OSX-specific test') + def test_find(self): - self.assertEqual(find_lib('pthread'), - '/usr/lib/libSystem.B.dylib') + self.assertEqual(find_lib('pthread'), + '/usr/lib/libSystem.B.dylib') - result = find_lib('z') - self.assertTrue(result.startswith('/usr/lib/libz.1')) - self.assertTrue(result.endswith('.dylib')) + result = find_lib('z') + # Issue #21093: dyld default search path includes $HOME/lib and + # /usr/local/lib before /usr/lib, which caused test failures if + # a local copy of libz exists in one of them. Now ignore the head + # of the path. + self.assertRegex(result, r".*/lib/libz\..*.*\.dylib") - self.assertEqual(find_lib('IOKit'), - '/System/Library/Frameworks/IOKit.framework/Versions/A/IOKit') + self.assertEqual(find_lib('IOKit'), + '/System/Library/Frameworks/IOKit.framework/Versions/A/IOKit') if __name__ == "__main__": unittest.main() diff --git a/Lib/ctypes/test/test_memfunctions.py b/Lib/ctypes/test/test_memfunctions.py index aec4aaadac11..e784b9a70684 100644 --- a/Lib/ctypes/test/test_memfunctions.py +++ b/Lib/ctypes/test/test_memfunctions.py @@ -2,17 +2,19 @@ from test import support import unittest from ctypes import * +from ctypes.test import need_symbol class MemFunctionsTest(unittest.TestCase): -## def test_overflow(self): -## # string_at and wstring_at must use the Python calling -## # convention (which acquires the GIL and checks the Python -## # error flag). Provoke an error and catch it; see also issue -## # #3554: <http://bugs.python.org/issue3554> -## self.assertRaises((OverflowError, MemoryError, SystemError), -## lambda: wstring_at(u"foo", sys.maxint - 1)) -## self.assertRaises((OverflowError, MemoryError, SystemError), -## lambda: string_at("foo", sys.maxint - 1)) + @unittest.skip('test disabled') + def test_overflow(self): + # string_at and wstring_at must use the Python calling + # convention (which acquires the GIL and checks the Python + # error flag). Provoke an error and catch it; see also issue + # #3554: <http://bugs.python.org/issue3554> + self.assertRaises((OverflowError, MemoryError, SystemError), + lambda: wstring_at(u"foo", sys.maxint - 1)) + self.assertRaises((OverflowError, MemoryError, SystemError), + lambda: string_at("foo", sys.maxint - 1)) def test_memmove(self): # large buffers apparently increase the chance that the memory @@ -61,21 +63,17 @@ def test_string_at(self): self.assertEqual(string_at(b"foo bar", 7), b"foo bar") self.assertEqual(string_at(b"foo bar", 3), b"foo") - try: - create_unicode_buffer - except NameError: - pass - else: - def test_wstring_at(self): - p = create_unicode_buffer("Hello, World") - a = create_unicode_buffer(1000000) - result = memmove(a, p, len(p) * sizeof(c_wchar)) - self.assertEqual(a.value, "Hello, World") + @need_symbol('create_unicode_buffer') + def test_wstring_at(self): + p = create_unicode_buffer("Hello, World") + a = create_unicode_buffer(1000000) + result = memmove(a, p, len(p) * sizeof(c_wchar)) + self.assertEqual(a.value, "Hello, World") - self.assertEqual(wstring_at(a), "Hello, World") - self.assertEqual(wstring_at(a, 5), "Hello") - self.assertEqual(wstring_at(a, 16), "Hello, World\0\0\0\0") - self.assertEqual(wstring_at(a, 0), "") + self.assertEqual(wstring_at(a), "Hello, World") + self.assertEqual(wstring_at(a, 5), "Hello") + self.assertEqual(wstring_at(a, 16), "Hello, World\0\0\0\0") + self.assertEqual(wstring_at(a, 0), "") if __name__ == "__main__": unittest.main() diff --git a/Lib/ctypes/test/test_numbers.py b/Lib/ctypes/test/test_numbers.py index 3b7194f31c23..2afca2662f42 100644 --- a/Lib/ctypes/test/test_numbers.py +++ b/Lib/ctypes/test/test_numbers.py @@ -82,12 +82,13 @@ def test_typeerror(self): self.assertRaises(TypeError, t, "") self.assertRaises(TypeError, t, None) -## def test_valid_ranges(self): -## # invalid values of the correct type -## # raise ValueError (not OverflowError) -## for t, (l, h) in zip(unsigned_types, unsigned_ranges): -## self.assertRaises(ValueError, t, l-1) -## self.assertRaises(ValueError, t, h+1) + @unittest.skip('test disabled') + def test_valid_ranges(self): + # invalid values of the correct type + # raise ValueError (not OverflowError) + for t, (l, h) in zip(unsigned_types, unsigned_ranges): + self.assertRaises(ValueError, t, l-1) + self.assertRaises(ValueError, t, h+1) def test_from_param(self): # the from_param class method attribute always @@ -200,16 +201,17 @@ def test_char_from_address(self): self.assertEqual(v.value, b'?') # array does not support c_bool / 't' - # def test_bool_from_address(self): - # from ctypes import c_bool - # from array import array - # a = array(c_bool._type_, [True]) - # v = t.from_address(a.buffer_info()[0]) - # self.assertEqual(v.value, a[0]) - # self.assertEqual(type(v) is t) - # a[0] = False - # self.assertEqual(v.value, a[0]) - # self.assertEqual(type(v) is t) + @unittest.skip('test disabled') + def test_bool_from_address(self): + from ctypes import c_bool + from array import array + a = array(c_bool._type_, [True]) + v = t.from_address(a.buffer_info()[0]) + self.assertEqual(v.value, a[0]) + self.assertEqual(type(v) is t) + a[0] = False + self.assertEqual(v.value, a[0]) + self.assertEqual(type(v) is t) def test_init(self): # c_int() can be initialized from Python's int, and c_int. @@ -227,8 +229,9 @@ def test_float_overflow(self): if (hasattr(t, "__ctype_le__")): self.assertRaises(OverflowError, t.__ctype_le__, big_int) -## def test_perf(self): -## check_perf() + @unittest.skip('test disabled') + def test_perf(self): + check_perf() from ctypes import _SimpleCData class c_int_S(_SimpleCData): diff --git a/Lib/ctypes/test/test_objects.py b/Lib/ctypes/test/test_objects.py index f075c2089396..ef7b20b000d4 100644 --- a/Lib/ctypes/test/test_objects.py +++ b/Lib/ctypes/test/test_objects.py @@ -59,12 +59,9 @@ import ctypes.test.test_objects class TestCase(unittest.TestCase): - if sys.hexversion > 0x02040000: - # Python 2.3 has no ELLIPSIS flag, so we don't test with this - # version: - def test(self): - doctest.testmod(ctypes.test.test_objects) + def test(self): + failures, tests = doctest.testmod(ctypes.test.test_objects) + self.assertFalse(failures, 'doctests failed, see output above') if __name__ == '__main__': - if sys.hexversion > 0x02040000: - doctest.testmod(ctypes.test.test_objects) + doctest.testmod(ctypes.test.test_objects) diff --git a/Lib/ctypes/test/test_parameters.py b/Lib/ctypes/test/test_parameters.py index 12b5bd5fba1f..e56bccf999be 100644 --- a/Lib/ctypes/test/test_parameters.py +++ b/Lib/ctypes/test/test_parameters.py @@ -1,4 +1,5 @@ import unittest, sys +from ctypes.test import need_symbol class SimpleTypesTestCase(unittest.TestCase): @@ -35,10 +36,9 @@ def from_param(cls, value): self.assertEqual(CVOIDP.from_param("abc"), "abcabc") self.assertEqual(CCHARP.from_param("abc"), "abcabcabcabc") - try: - from ctypes import c_wchar_p - except ImportError: - return + @need_symbol('c_wchar_p') + def test_subclasses_c_wchar_p(self): + from ctypes import c_wchar_p class CWCHARP(c_wchar_p): def from_param(cls, value): @@ -66,13 +66,9 @@ def test_cstrings(self): a = c_char_p(b"123") self.assertIs(c_char_p.from_param(a), a) + @need_symbol('c_wchar_p') def test_cw_strings(self): - from ctypes import byref - try: - from ctypes import c_wchar_p - except ImportError: -## print "(No c_wchar_p)" - return + from ctypes import byref, c_wchar_p c_wchar_p.from_param("123") @@ -139,9 +135,6 @@ def test_array_pointers(self): self.assertRaises(TypeError, LPINT.from_param, c_long*3) self.assertRaises(TypeError, LPINT.from_param, c_uint*3) -## def test_performance(self): -## check_perf() - def test_noctypes_argtype(self): import _ctypes_test from ctypes import CDLL, c_void_p, ArgumentError diff --git a/Lib/ctypes/test/test_pep3118.py b/Lib/ctypes/test/test_pep3118.py index ad13b016e762..32f802c86158 100644 --- a/Lib/ctypes/test/test_pep3118.py +++ b/Lib/ctypes/test/test_pep3118.py @@ -96,6 +96,9 @@ class EmptyStruct(Structure): class aUnion(Union): _fields_ = [("a", c_int)] +class StructWithArrays(Structure): + _fields_ = [("x", c_long * 3 * 2), ("y", Point * 4)] + class Incomplete(Structure): pass @@ -145,10 +148,10 @@ class Complete(Structure): ## arrays and pointers - (c_double * 4, "(4)<d", (4,), c_double), - (c_float * 4 * 3 * 2, "(2,3,4)<f", (2,3,4), c_float), - (POINTER(c_short) * 2, "(2)&<h", (2,), POINTER(c_short)), - (POINTER(c_short) * 2 * 3, "(3,2)&<h", (3,2,), POINTER(c_short)), + (c_double * 4, "<d", (4,), c_double), + (c_float * 4 * 3 * 2, "<f", (2,3,4), c_float), + (POINTER(c_short) * 2, "&<h", (2,), POINTER(c_short)), + (POINTER(c_short) * 2 * 3, "&<h", (3,2,), POINTER(c_short)), (POINTER(c_short * 2), "&(2)<h", (), POINTER(c_short)), ## structures and unions @@ -160,6 +163,9 @@ class Complete(Structure): (EmptyStruct, "T{}", (), EmptyStruct), # the pep does't support unions (aUnion, "B", (), aUnion), + # structure with sub-arrays + (StructWithArrays, "T{(2,3)<l:x:(4)T{<l:x:<l:y:}:y:}", (), StructWithArrays), + (StructWithArrays * 3, "T{(2,3)<l:x:(4)T{<l:x:<l:y:}:y:}", (3,), StructWithArrays), ## pointer to incomplete structure (Incomplete, "B", (), Incomplete), diff --git a/Lib/ctypes/test/test_pickling.py b/Lib/ctypes/test/test_pickling.py index 8c9122269447..c4a79b977931 100644 --- a/Lib/ctypes/test/test_pickling.py +++ b/Lib/ctypes/test/test_pickling.py @@ -14,9 +14,9 @@ def __init__(self, *args, **kw): class Y(X): _fields_ = [("str", c_char_p)] -class PickleTest(unittest.TestCase): +class PickleTest: def dumps(self, item): - return pickle.dumps(item) + return pickle.dumps(item, self.proto) def loads(self, item): return pickle.loads(item) @@ -67,17 +67,15 @@ def test_unpickable(self): self.assertRaises(ValueError, lambda: self.dumps(item)) def test_wchar(self): - pickle.dumps(c_char(b"x")) + self.dumps(c_char(b"x")) # Issue 5049 - pickle.dumps(c_wchar("x")) + self.dumps(c_wchar("x")) -class PickleTest_1(PickleTest): - def dumps(self, item): - return pickle.dumps(item, 1) - -class PickleTest_2(PickleTest): - def dumps(self, item): - return pickle.dumps(item, 2) +for proto in range(pickle.HIGHEST_PROTOCOL + 1): + name = 'PickleTest_%s' % proto + globals()[name] = type(name, + (PickleTest, unittest.TestCase), + {'proto': proto}) if __name__ == "__main__": unittest.main() diff --git a/Lib/ctypes/test/test_pointers.py b/Lib/ctypes/test/test_pointers.py index f8ef0ab830c4..78e33571343f 100644 --- a/Lib/ctypes/test/test_pointers.py +++ b/Lib/ctypes/test/test_pointers.py @@ -7,6 +7,8 @@ c_long, c_ulong, c_longlong, c_ulonglong, c_double, c_float] python_types = [int, int, int, int, int, int, int, int, int, int, float, float] +LargeNamedType = type('T' * 2 ** 25, (Structure,), {}) +large_string = 'T' * 2 ** 25 class PointersTestCase(unittest.TestCase): @@ -22,7 +24,10 @@ class A(POINTER(c_ulong)): def test_pass_pointers(self): dll = CDLL(_ctypes_test.__file__) func = dll._testfunc_p_p - func.restype = c_long + if sizeof(c_longlong) == sizeof(c_void_p): + func.restype = c_longlong + else: + func.restype = c_long i = c_int(12345678) ## func.argtypes = (POINTER(c_int),) @@ -188,5 +193,11 @@ def test_pointers_bool(self): mth = WINFUNCTYPE(None)(42, "name", (), None) self.assertEqual(bool(mth), True) + def test_pointer_type_name(self): + self.assertTrue(POINTER(LargeNamedType)) + + def test_pointer_type_str_name(self): + self.assertTrue(POINTER(large_string)) + if __name__ == '__main__': unittest.main() diff --git a/Lib/ctypes/test/test_prototypes.py b/Lib/ctypes/test/test_prototypes.py index 6ef1b1bcaff8..cd0c649de3e3 100644 --- a/Lib/ctypes/test/test_prototypes.py +++ b/Lib/ctypes/test/test_prototypes.py @@ -1,4 +1,5 @@ from ctypes import * +from ctypes.test import need_symbol import unittest # IMPORTANT INFO: @@ -68,7 +69,10 @@ def test_paramflags(self): def test_int_pointer_arg(self): func = testdll._testfunc_p_p - func.restype = c_long + if sizeof(c_longlong) == sizeof(c_void_p): + func.restype = c_longlong + else: + func.restype = c_long self.assertEqual(0, func(0)) ci = c_int(0) @@ -135,13 +139,14 @@ def test_c_void_p_arg(self): func(pointer(c_int())) func((c_int * 3)()) - try: - func.restype = c_wchar_p - except NameError: - pass - else: - self.assertEqual(None, func(c_wchar_p(None))) - self.assertEqual("123", func(c_wchar_p("123"))) + @need_symbol('c_wchar_p') + def test_c_void_p_arg_with_c_wchar_p(self): + func = testdll._testfunc_p_p + func.restype = c_wchar_p + func.argtypes = c_void_p, + + self.assertEqual(None, func(c_wchar_p(None))) + self.assertEqual("123", func(c_wchar_p("123"))) def test_instance(self): func = testdll._testfunc_p_p @@ -156,51 +161,47 @@ class X: func.argtypes = None self.assertEqual(None, func(X())) -try: - c_wchar -except NameError: - pass -else: - class WCharPointersTestCase(unittest.TestCase): - - def setUp(self): - func = testdll._testfunc_p_p - func.restype = c_int - func.argtypes = None - - - def test_POINTER_c_wchar_arg(self): - func = testdll._testfunc_p_p - func.restype = c_wchar_p - func.argtypes = POINTER(c_wchar), - - self.assertEqual(None, func(None)) - self.assertEqual("123", func("123")) - self.assertEqual(None, func(c_wchar_p(None))) - self.assertEqual("123", func(c_wchar_p("123"))) - - self.assertEqual("123", func(c_wbuffer("123"))) - ca = c_wchar("a") - self.assertEqual("a", func(pointer(ca))[0]) - self.assertEqual("a", func(byref(ca))[0]) - - def test_c_wchar_p_arg(self): - func = testdll._testfunc_p_p - func.restype = c_wchar_p - func.argtypes = c_wchar_p, - - c_wchar_p.from_param("123") - - self.assertEqual(None, func(None)) - self.assertEqual("123", func("123")) - self.assertEqual(None, func(c_wchar_p(None))) - self.assertEqual("123", func(c_wchar_p("123"))) - - # XXX Currently, these raise TypeErrors, although they shouldn't: - self.assertEqual("123", func(c_wbuffer("123"))) - ca = c_wchar("a") - self.assertEqual("a", func(pointer(ca))[0]) - self.assertEqual("a", func(byref(ca))[0]) +@need_symbol('c_wchar') +class WCharPointersTestCase(unittest.TestCase): + + def setUp(self): + func = testdll._testfunc_p_p + func.restype = c_int + func.argtypes = None + + + def test_POINTER_c_wchar_arg(self): + func = testdll._testfunc_p_p + func.restype = c_wchar_p + func.argtypes = POINTER(c_wchar), + + self.assertEqual(None, func(None)) + self.assertEqual("123", func("123")) + self.assertEqual(None, func(c_wchar_p(None))) + self.assertEqual("123", func(c_wchar_p("123"))) + + self.assertEqual("123", func(c_wbuffer("123"))) + ca = c_wchar("a") + self.assertEqual("a", func(pointer(ca))[0]) + self.assertEqual("a", func(byref(ca))[0]) + + def test_c_wchar_p_arg(self): + func = testdll._testfunc_p_p + func.restype = c_wchar_p + func.argtypes = c_wchar_p, + + c_wchar_p.from_param("123") + + self.assertEqual(None, func(None)) + self.assertEqual("123", func("123")) + self.assertEqual(None, func(c_wchar_p(None))) + self.assertEqual("123", func(c_wchar_p("123"))) + + # XXX Currently, these raise TypeErrors, although they shouldn't: + self.assertEqual("123", func(c_wbuffer("123"))) + ca = c_wchar("a") + self.assertEqual("a", func(pointer(ca))[0]) + self.assertEqual("a", func(byref(ca))[0]) class ArrayTest(unittest.TestCase): def test(self): diff --git a/Lib/ctypes/test/test_python_api.py b/Lib/ctypes/test/test_python_api.py index 5eb882af5eb1..9c137469c3b5 100644 --- a/Lib/ctypes/test/test_python_api.py +++ b/Lib/ctypes/test/test_python_api.py @@ -1,7 +1,6 @@ from ctypes import * import unittest, sys from test import support -from ctypes.test import is_resource_enabled ################################################################ # This section should be moved into ctypes\__init__.py, when it's ready. @@ -39,24 +38,21 @@ def test_PyString_FromString(self): del pyob self.assertEqual(grc(s), refcnt) - if is_resource_enabled("refcount"): - # This test is unreliable, because it is possible that code in - # unittest changes the refcount of the '42' integer. So, it - # is disabled by default. - def test_PyLong_Long(self): - ref42 = grc(42) - pythonapi.PyLong_FromLong.restype = py_object - self.assertEqual(pythonapi.PyLong_FromLong(42), 42) + @support.refcount_test + def test_PyLong_Long(self): + ref42 = grc(42) + pythonapi.PyLong_FromLong.restype = py_object + self.assertEqual(pythonapi.PyLong_FromLong(42), 42) - self.assertEqual(grc(42), ref42) + self.assertEqual(grc(42), ref42) - pythonapi.PyLong_AsLong.argtypes = (py_object,) - pythonapi.PyLong_AsLong.restype = c_long + pythonapi.PyLong_AsLong.argtypes = (py_object,) + pythonapi.PyLong_AsLong.restype = c_long - res = pythonapi.PyLong_AsLong(42) - self.assertEqual(grc(res), ref42 + 1) - del res - self.assertEqual(grc(42), ref42) + res = pythonapi.PyLong_AsLong(42) + self.assertEqual(grc(res), ref42 + 1) + del res + self.assertEqual(grc(42), ref42) @support.refcount_test def test_PyObj_FromPtr(self): diff --git a/Lib/ctypes/test/test_random_things.py b/Lib/ctypes/test/test_random_things.py index 515acf509a66..4555ecd8b8a6 100644 --- a/Lib/ctypes/test/test_random_things.py +++ b/Lib/ctypes/test/test_random_things.py @@ -5,23 +5,22 @@ def callback_func(arg): 42 / arg raise ValueError(arg) -if sys.platform == "win32": +@unittest.skipUnless(sys.platform == "win32", 'Windows-specific test') +class call_function_TestCase(unittest.TestCase): + # _ctypes.call_function is deprecated and private, but used by + # Gary Bishp's readline module. If we have it, we must test it as well. - class call_function_TestCase(unittest.TestCase): - # _ctypes.call_function is deprecated and private, but used by - # Gary Bishp's readline module. If we have it, we must test it as well. + def test(self): + from _ctypes import call_function + windll.kernel32.LoadLibraryA.restype = c_void_p + windll.kernel32.GetProcAddress.argtypes = c_void_p, c_char_p + windll.kernel32.GetProcAddress.restype = c_void_p - def test(self): - from _ctypes import call_function - windll.kernel32.LoadLibraryA.restype = c_void_p - windll.kernel32.GetProcAddress.argtypes = c_void_p, c_char_p - windll.kernel32.GetProcAddress.restype = c_void_p + hdll = windll.kernel32.LoadLibraryA(b"kernel32") + funcaddr = windll.kernel32.GetProcAddress(hdll, b"GetModuleHandleA") - hdll = windll.kernel32.LoadLibraryA(b"kernel32") - funcaddr = windll.kernel32.GetProcAddress(hdll, b"GetModuleHandleA") - - self.assertEqual(call_function(funcaddr, (None,)), - windll.kernel32.GetModuleHandleA(None)) + self.assertEqual(call_function(funcaddr, (None,)), + windll.kernel32.GetModuleHandleA(None)) class CallbackTracbackTestCase(unittest.TestCase): # When an exception is raised in a ctypes callback function, the C diff --git a/Lib/ctypes/test/test_slicing.py b/Lib/ctypes/test/test_slicing.py index 82fee96823f9..240dc0cdda24 100644 --- a/Lib/ctypes/test/test_slicing.py +++ b/Lib/ctypes/test/test_slicing.py @@ -1,5 +1,6 @@ import unittest from ctypes import * +from ctypes.test import need_symbol import _ctypes_test @@ -125,44 +126,40 @@ def test_char_array(self): self.assertEqual(p[2:5:-3], s[2:5:-3]) - try: - c_wchar - except NameError: - pass - else: - def test_wchar_ptr(self): - s = "abcdefghijklmnopqrstuvwxyz\0" - - dll = CDLL(_ctypes_test.__file__) - dll.my_wcsdup.restype = POINTER(c_wchar) - dll.my_wcsdup.argtypes = POINTER(c_wchar), - dll.my_free.restype = None - res = dll.my_wcsdup(s) - self.assertEqual(res[:len(s)], s) - self.assertEqual(res[:len(s):], s) - self.assertEqual(res[len(s)-1:-1:-1], s[::-1]) - self.assertEqual(res[len(s)-1:5:-7], s[:5:-7]) - - import operator - self.assertRaises(TypeError, operator.setitem, - res, slice(0, 5), "abcde") - dll.my_free(res) - - if sizeof(c_wchar) == sizeof(c_short): - dll.my_wcsdup.restype = POINTER(c_short) - elif sizeof(c_wchar) == sizeof(c_int): - dll.my_wcsdup.restype = POINTER(c_int) - elif sizeof(c_wchar) == sizeof(c_long): - dll.my_wcsdup.restype = POINTER(c_long) - else: - return - res = dll.my_wcsdup(s) - tmpl = list(range(ord("a"), ord("z")+1)) - self.assertEqual(res[:len(s)-1], tmpl) - self.assertEqual(res[:len(s)-1:], tmpl) - self.assertEqual(res[len(s)-2:-1:-1], tmpl[::-1]) - self.assertEqual(res[len(s)-2:5:-7], tmpl[:5:-7]) - dll.my_free(res) + @need_symbol('c_wchar') + def test_wchar_ptr(self): + s = "abcdefghijklmnopqrstuvwxyz\0" + + dll = CDLL(_ctypes_test.__file__) + dll.my_wcsdup.restype = POINTER(c_wchar) + dll.my_wcsdup.argtypes = POINTER(c_wchar), + dll.my_free.restype = None + res = dll.my_wcsdup(s) + self.assertEqual(res[:len(s)], s) + self.assertEqual(res[:len(s):], s) + self.assertEqual(res[len(s)-1:-1:-1], s[::-1]) + self.assertEqual(res[len(s)-1:5:-7], s[:5:-7]) + + import operator + self.assertRaises(TypeError, operator.setitem, + res, slice(0, 5), "abcde") + dll.my_free(res) + + if sizeof(c_wchar) == sizeof(c_short): + dll.my_wcsdup.restype = POINTER(c_short) + elif sizeof(c_wchar) == sizeof(c_int): + dll.my_wcsdup.restype = POINTER(c_int) + elif sizeof(c_wchar) == sizeof(c_long): + dll.my_wcsdup.restype = POINTER(c_long) + else: + self.skipTest('Pointers to c_wchar are not supported') + res = dll.my_wcsdup(s) + tmpl = list(range(ord("a"), ord("z")+1)) + self.assertEqual(res[:len(s)-1], tmpl) + self.assertEqual(res[:len(s)-1:], tmpl) + self.assertEqual(res[len(s)-2:-1:-1], tmpl[::-1]) + self.assertEqual(res[len(s)-2:5:-7], tmpl[:5:-7]) + dll.my_free(res) ################################################################ diff --git a/Lib/ctypes/test/test_strings.py b/Lib/ctypes/test/test_strings.py index 9dc2a291a7df..c7bfbda73d54 100644 --- a/Lib/ctypes/test/test_strings.py +++ b/Lib/ctypes/test/test_strings.py @@ -1,5 +1,6 @@ import unittest from ctypes import * +from ctypes.test import need_symbol class StringArrayTestCase(unittest.TestCase): def test(self): @@ -53,36 +54,33 @@ def test_param_2(self): ## print BUF.from_param(c_char_p("python")) ## print BUF.from_param(BUF(*"pyth")) -try: - c_wchar -except NameError: - pass -else: - class WStringArrayTestCase(unittest.TestCase): - def test(self): - BUF = c_wchar * 4 +@need_symbol('c_wchar') +class WStringArrayTestCase(unittest.TestCase): + def test(self): + BUF = c_wchar * 4 - buf = BUF("a", "b", "c") - self.assertEqual(buf.value, "abc") + buf = BUF("a", "b", "c") + self.assertEqual(buf.value, "abc") - buf.value = "ABCD" - self.assertEqual(buf.value, "ABCD") + buf.value = "ABCD" + self.assertEqual(buf.value, "ABCD") - buf.value = "x" - self.assertEqual(buf.value, "x") + buf.value = "x" + self.assertEqual(buf.value, "x") - buf[1] = "Z" - self.assertEqual(buf.value, "xZCD") + buf[1] = "Z" + self.assertEqual(buf.value, "xZCD") - @unittest.skipIf(sizeof(c_wchar) < 4, - "sizeof(wchar_t) is smaller than 4 bytes") - def test_nonbmp(self): - u = chr(0x10ffff) - w = c_wchar(u) - self.assertEqual(w.value, u) + @unittest.skipIf(sizeof(c_wchar) < 4, + "sizeof(wchar_t) is smaller than 4 bytes") + def test_nonbmp(self): + u = chr(0x10ffff) + w = c_wchar(u) + self.assertEqual(w.value, u) class StringTestCase(unittest.TestCase): - def XX_test_basic_strings(self): + @unittest.skip('test disabled') + def test_basic_strings(self): cs = c_string("abcdef") # Cannot call len on a c_string any longer @@ -108,7 +106,8 @@ def XX_test_basic_strings(self): self.assertRaises(TypeError, c_string, "123") - def XX_test_sized_strings(self): + @unittest.skip('test disabled') + def test_sized_strings(self): # New in releases later than 0.4.0: self.assertRaises(TypeError, c_string, None) @@ -125,7 +124,8 @@ def XX_test_sized_strings(self): self.assertEqual(c_string(2).raw[-1], "\000") self.assertEqual(len(c_string(2).raw), 2) - def XX_test_initialized_strings(self): + @unittest.skip('test disabled') + def test_initialized_strings(self): self.assertEqual(c_string("ab", 4).raw[:2], "ab") self.assertEqual(c_string("ab", 4).raw[:2:], "ab") @@ -134,7 +134,8 @@ def XX_test_initialized_strings(self): self.assertEqual(c_string("ab", 4).raw[-1], "\000") self.assertEqual(c_string("ab", 2).raw, "a\000") - def XX_test_toolong(self): + @unittest.skip('test disabled') + def test_toolong(self): cs = c_string("abcdef") # Much too long string: self.assertRaises(ValueError, setattr, cs, "value", "123456789012345") @@ -142,54 +143,53 @@ def XX_test_toolong(self): # One char too long values: self.assertRaises(ValueError, setattr, cs, "value", "1234567") -## def test_perf(self): -## check_perf() + @unittest.skip('test disabled') + def test_perf(self): + check_perf() -try: - c_wchar -except NameError: - pass -else: - class WStringTestCase(unittest.TestCase): - def test_wchar(self): - c_wchar("x") - repr(byref(c_wchar("x"))) - c_wchar("x") +@need_symbol('c_wchar') +class WStringTestCase(unittest.TestCase): + def test_wchar(self): + c_wchar("x") + repr(byref(c_wchar("x"))) + c_wchar("x") - def X_test_basic_wstrings(self): - cs = c_wstring("abcdef") + @unittest.skip('test disabled') + def test_basic_wstrings(self): + cs = c_wstring("abcdef") - # XXX This behaviour is about to change: - # len returns the size of the internal buffer in bytes. - # This includes the terminating NUL character. - self.assertEqual(sizeof(cs), 14) + # XXX This behaviour is about to change: + # len returns the size of the internal buffer in bytes. + # This includes the terminating NUL character. + self.assertEqual(sizeof(cs), 14) - # The value property is the string up to the first terminating NUL. - self.assertEqual(cs.value, "abcdef") - self.assertEqual(c_wstring("abc\000def").value, "abc") + # The value property is the string up to the first terminating NUL. + self.assertEqual(cs.value, "abcdef") + self.assertEqual(c_wstring("abc\000def").value, "abc") - self.assertEqual(c_wstring("abc\000def").value, "abc") + self.assertEqual(c_wstring("abc\000def").value, "abc") - # The raw property is the total buffer contents: - self.assertEqual(cs.raw, "abcdef\000") - self.assertEqual(c_wstring("abc\000def").raw, "abc\000def\000") + # The raw property is the total buffer contents: + self.assertEqual(cs.raw, "abcdef\000") + self.assertEqual(c_wstring("abc\000def").raw, "abc\000def\000") - # We can change the value: - cs.value = "ab" - self.assertEqual(cs.value, "ab") - self.assertEqual(cs.raw, "ab\000\000\000\000\000") + # We can change the value: + cs.value = "ab" + self.assertEqual(cs.value, "ab") + self.assertEqual(cs.raw, "ab\000\000\000\000\000") - self.assertRaises(TypeError, c_wstring, "123") - self.assertRaises(ValueError, c_wstring, 0) + self.assertRaises(TypeError, c_wstring, "123") + self.assertRaises(ValueError, c_wstring, 0) - def X_test_toolong(self): - cs = c_wstring("abcdef") - # Much too long string: - self.assertRaises(ValueError, setattr, cs, "value", "123456789012345") + @unittest.skip('test disabled') + def test_toolong(self): + cs = c_wstring("abcdef") + # Much too long string: + self.assertRaises(ValueError, setattr, cs, "value", "123456789012345") - # One char too long values: - self.assertRaises(ValueError, setattr, cs, "value", "1234567") + # One char too long values: + self.assertRaises(ValueError, setattr, cs, "value", "1234567") def run_test(rep, msg, func, arg): diff --git a/Lib/ctypes/test/test_structures.py b/Lib/ctypes/test/test_structures.py index 61b9fe7c1813..84d456c3cc38 100644 --- a/Lib/ctypes/test/test_structures.py +++ b/Lib/ctypes/test/test_structures.py @@ -1,5 +1,6 @@ import unittest from ctypes import * +from ctypes.test import need_symbol from struct import calcsize import _testcapi @@ -83,7 +84,7 @@ class X(Structure): class Y(Structure): _fields_ = [("x", c_char * 3), ("y", c_int)] - self.assertEqual(alignment(Y), calcsize("i")) + self.assertEqual(alignment(Y), alignment(c_int)) self.assertEqual(sizeof(Y), calcsize("3si")) class SI(Structure): @@ -175,23 +176,23 @@ class X(Structure): self.assertEqual(sizeof(X), 10) self.assertEqual(X.b.offset, 2) + import struct + longlong_size = struct.calcsize("q") + longlong_align = struct.calcsize("bq") - longlong_size + class X(Structure): _fields_ = [("a", c_byte), ("b", c_longlong)] _pack_ = 4 - self.assertEqual(sizeof(X), 12) - self.assertEqual(X.b.offset, 4) - - import struct - longlong_size = struct.calcsize("q") - longlong_align = struct.calcsize("bq") - longlong_size + self.assertEqual(sizeof(X), min(4, longlong_align) + longlong_size) + self.assertEqual(X.b.offset, min(4, longlong_align)) class X(Structure): _fields_ = [("a", c_byte), ("b", c_longlong)] _pack_ = 8 - self.assertEqual(sizeof(X), longlong_align + longlong_size) + self.assertEqual(sizeof(X), min(8, longlong_align) + longlong_size) self.assertEqual(X.b.offset, min(8, longlong_align)) @@ -291,12 +292,8 @@ class Person(Structure): self.assertEqual(p.phone.number, b"5678") self.assertEqual(p.age, 5) + @need_symbol('c_wchar') def test_structures_with_wchar(self): - try: - c_wchar - except NameError: - return # no unicode - class PersonW(Structure): _fields_ = [("name", c_wchar * 12), ("age", c_int)] @@ -325,7 +322,7 @@ class Person(Structure): self.assertEqual(cls, RuntimeError) self.assertEqual(msg, "(Phone) <class 'TypeError'>: " - "expected string, int found") + "expected bytes, int found") cls, msg = self.get_except(Person, b"Someone", (b"a", b"b", b"c")) self.assertEqual(cls, RuntimeError) @@ -354,14 +351,14 @@ def get_except(self, func, *args): except Exception as detail: return detail.__class__, str(detail) - -## def test_subclass_creation(self): -## meta = type(Structure) -## # same as 'class X(Structure): pass' -## # fails, since we need either a _fields_ or a _abstract_ attribute -## cls, msg = self.get_except(meta, "X", (Structure,), {}) -## self.assertEqual((cls, msg), -## (AttributeError, "class must define a '_fields_' attribute")) + @unittest.skip('test disabled') + def test_subclass_creation(self): + meta = type(Structure) + # same as 'class X(Structure): pass' + # fails, since we need either a _fields_ or a _abstract_ attribute + cls, msg = self.get_except(meta, "X", (Structure,), {}) + self.assertEqual((cls, msg), + (AttributeError, "class must define a '_fields_' attribute")) def test_abstract_class(self): class X(Structure): diff --git a/Lib/ctypes/test/test_unicode.py b/Lib/ctypes/test/test_unicode.py index c3b2d4877121..c200af7b6506 100644 --- a/Lib/ctypes/test/test_unicode.py +++ b/Lib/ctypes/test/test_unicode.py @@ -1,58 +1,55 @@ import unittest import ctypes - -try: - ctypes.c_wchar -except AttributeError: - pass -else: - import _ctypes_test - - class UnicodeTestCase(unittest.TestCase): - def test_wcslen(self): - dll = ctypes.CDLL(_ctypes_test.__file__) - wcslen = dll.my_wcslen - wcslen.argtypes = [ctypes.c_wchar_p] - - self.assertEqual(wcslen("abc"), 3) - self.assertEqual(wcslen("ab\u2070"), 3) - self.assertRaises(ctypes.ArgumentError, wcslen, b"ab\xe4") - - def test_buffers(self): - buf = ctypes.create_unicode_buffer("abc") - self.assertEqual(len(buf), 3+1) - - buf = ctypes.create_unicode_buffer("ab\xe4\xf6\xfc") - self.assertEqual(buf[:], "ab\xe4\xf6\xfc\0") - self.assertEqual(buf[::], "ab\xe4\xf6\xfc\0") - self.assertEqual(buf[::-1], '\x00\xfc\xf6\xe4ba') - self.assertEqual(buf[::2], 'a\xe4\xfc') - self.assertEqual(buf[6:5:-1], "") - - func = ctypes.CDLL(_ctypes_test.__file__)._testfunc_p_p - - class StringTestCase(UnicodeTestCase): - def setUp(self): - func.argtypes = [ctypes.c_char_p] - func.restype = ctypes.c_char_p - - def tearDown(self): - func.argtypes = None - func.restype = ctypes.c_int - - def test_func(self): - self.assertEqual(func(b"abc\xe4"), b"abc\xe4") - - def test_buffers(self): - buf = ctypes.create_string_buffer(b"abc") - self.assertEqual(len(buf), 3+1) - - buf = ctypes.create_string_buffer(b"ab\xe4\xf6\xfc") - self.assertEqual(buf[:], b"ab\xe4\xf6\xfc\0") - self.assertEqual(buf[::], b"ab\xe4\xf6\xfc\0") - self.assertEqual(buf[::-1], b'\x00\xfc\xf6\xe4ba') - self.assertEqual(buf[::2], b'a\xe4\xfc') - self.assertEqual(buf[6:5:-1], b"") +from ctypes.test import need_symbol + +import _ctypes_test + +@need_symbol('c_wchar') +class UnicodeTestCase(unittest.TestCase): + def test_wcslen(self): + dll = ctypes.CDLL(_ctypes_test.__file__) + wcslen = dll.my_wcslen + wcslen.argtypes = [ctypes.c_wchar_p] + + self.assertEqual(wcslen("abc"), 3) + self.assertEqual(wcslen("ab\u2070"), 3) + self.assertRaises(ctypes.ArgumentError, wcslen, b"ab\xe4") + + def test_buffers(self): + buf = ctypes.create_unicode_buffer("abc") + self.assertEqual(len(buf), 3+1) + + buf = ctypes.create_unicode_buffer("ab\xe4\xf6\xfc") + self.assertEqual(buf[:], "ab\xe4\xf6\xfc\0") + self.assertEqual(buf[::], "ab\xe4\xf6\xfc\0") + self.assertEqual(buf[::-1], '\x00\xfc\xf6\xe4ba') + self.assertEqual(buf[::2], 'a\xe4\xfc') + self.assertEqual(buf[6:5:-1], "") + +func = ctypes.CDLL(_ctypes_test.__file__)._testfunc_p_p + +class StringTestCase(UnicodeTestCase): + def setUp(self): + func.argtypes = [ctypes.c_char_p] + func.restype = ctypes.c_char_p + + def tearDown(self): + func.argtypes = None + func.restype = ctypes.c_int + + def test_func(self): + self.assertEqual(func(b"abc\xe4"), b"abc\xe4") + + def test_buffers(self): + buf = ctypes.create_string_buffer(b"abc") + self.assertEqual(len(buf), 3+1) + + buf = ctypes.create_string_buffer(b"ab\xe4\xf6\xfc") + self.assertEqual(buf[:], b"ab\xe4\xf6\xfc\0") + self.assertEqual(buf[::], b"ab\xe4\xf6\xfc\0") + self.assertEqual(buf[::-1], b'\x00\xfc\xf6\xe4ba') + self.assertEqual(buf[::2], b'a\xe4\xfc') + self.assertEqual(buf[6:5:-1], b"") if __name__ == '__main__': diff --git a/Lib/ctypes/test/test_values.py b/Lib/ctypes/test/test_values.py index e46410208f79..1c1fd7dbb61f 100644 --- a/Lib/ctypes/test/test_values.py +++ b/Lib/ctypes/test/test_values.py @@ -3,6 +3,7 @@ """ import unittest +import sys from ctypes import * import _ctypes_test @@ -27,62 +28,68 @@ def test_undefined(self): ctdll = CDLL(_ctypes_test.__file__) self.assertRaises(ValueError, c_int.in_dll, ctdll, "Undefined_Symbol") - class Win_ValuesTestCase(unittest.TestCase): - """This test only works when python itself is a dll/shared library""" - - def test_optimizeflag(self): - # This test accesses the Py_OptimizeFlag intger, which is - # exported by the Python dll. - - # It's value is set depending on the -O and -OO flags: - # if not given, it is 0 and __debug__ is 1. - # If -O is given, the flag is 1, for -OO it is 2. - # docstrings are also removed in the latter case. - opt = c_int.in_dll(pydll, "Py_OptimizeFlag").value - if __debug__: - self.assertEqual(opt, 0) - elif ValuesTestCase.__doc__ is not None: - self.assertEqual(opt, 1) - else: - self.assertEqual(opt, 2) - - def test_frozentable(self): - # Python exports a PyImport_FrozenModules symbol. This is a - # pointer to an array of struct _frozen entries. The end of the - # array is marked by an entry containing a NULL name and zero - # size. - - # In standard Python, this table contains a __hello__ - # module, and a __phello__ package containing a spam - # module. - class struct_frozen(Structure): - _fields_ = [("name", c_char_p), - ("code", POINTER(c_ubyte)), - ("size", c_int)] - FrozenTable = POINTER(struct_frozen) - - ft = FrozenTable.in_dll(pydll, "PyImport_FrozenModules") - # ft is a pointer to the struct_frozen entries: - items = [] - for entry in ft: - # This is dangerous. We *can* iterate over a pointer, but - # the loop will not terminate (maybe with an access - # violation;-) because the pointer instance has no size. - if entry.name is None: - break - items.append((entry.name, entry.size)) - import sys - if sys.version_info[:2] >= (2, 3): - expected = [("__hello__", 104), ("__phello__", -104), ("__phello__.spam", 104)] - else: - expected = [("__hello__", 100), ("__phello__", -100), ("__phello__.spam", 100)] - self.assertEqual(items, expected) - - from ctypes import _pointer_type_cache - del _pointer_type_cache[struct_frozen] - - def test_undefined(self): - self.assertRaises(ValueError, c_int.in_dll, pydll, "Undefined_Symbol") +@unittest.skipUnless(sys.platform == 'win32', 'Windows-specific test') +class Win_ValuesTestCase(unittest.TestCase): + """This test only works when python itself is a dll/shared library""" + + def test_optimizeflag(self): + # This test accesses the Py_OptimizeFlag integer, which is + # exported by the Python dll and should match the sys.flags value + + opt = c_int.in_dll(pythonapi, "Py_OptimizeFlag").value + self.assertEqual(opt, sys.flags.optimize) + + def test_frozentable(self): + # Python exports a PyImport_FrozenModules symbol. This is a + # pointer to an array of struct _frozen entries. The end of the + # array is marked by an entry containing a NULL name and zero + # size. + + # In standard Python, this table contains a __hello__ + # module, and a __phello__ package containing a spam + # module. + class struct_frozen(Structure): + _fields_ = [("name", c_char_p), + ("code", POINTER(c_ubyte)), + ("size", c_int)] + FrozenTable = POINTER(struct_frozen) + + ft = FrozenTable.in_dll(pythonapi, "PyImport_FrozenModules") + # ft is a pointer to the struct_frozen entries: + items = [] + # _frozen_importlib changes size whenever importlib._bootstrap + # changes, so it gets a special case. We should make sure it's + # found, but don't worry about its size too much. + _fzn_implib_seen = False + for entry in ft: + # This is dangerous. We *can* iterate over a pointer, but + # the loop will not terminate (maybe with an access + # violation;-) because the pointer instance has no size. + if entry.name is None: + break + + if entry.name == b'_frozen_importlib': + _fzn_implib_seen = True + self.assertTrue(entry.size, + "_frozen_importlib was reported as having no size") + continue + items.append((entry.name, entry.size)) + + expected = [(b"__hello__", 161), + (b"__phello__", -161), + (b"__phello__.spam", 161), + ] + self.assertEqual(items, expected) + + self.assertTrue(_fzn_implib_seen, + "_frozen_importlib wasn't found in PyImport_FrozenModules") + + from ctypes import _pointer_type_cache + del _pointer_type_cache[struct_frozen] + + def test_undefined(self): + self.assertRaises(ValueError, c_int.in_dll, pythonapi, + "Undefined_Symbol") if __name__ == '__main__': unittest.main() diff --git a/Lib/ctypes/test/test_win32.py b/Lib/ctypes/test/test_win32.py index 91ad3149a775..5867b0592924 100644 --- a/Lib/ctypes/test/test_win32.py +++ b/Lib/ctypes/test/test_win32.py @@ -1,99 +1,103 @@ # Windows specific tests from ctypes import * -from ctypes.test import is_resource_enabled import unittest, sys from test import support import _ctypes_test -if sys.platform == "win32" and sizeof(c_void_p) == sizeof(c_int): - # Only windows 32-bit has different calling conventions. - - class WindowsTestCase(unittest.TestCase): - def test_callconv_1(self): - # Testing stdcall function - - IsWindow = windll.user32.IsWindow - # ValueError: Procedure probably called with not enough arguments (4 bytes missing) - self.assertRaises(ValueError, IsWindow) - - # This one should succeed... - self.assertEqual(0, IsWindow(0)) - - # ValueError: Procedure probably called with too many arguments (8 bytes in excess) - self.assertRaises(ValueError, IsWindow, 0, 0, 0) - - def test_callconv_2(self): - # Calling stdcall function as cdecl - - IsWindow = cdll.user32.IsWindow - - # ValueError: Procedure called with not enough arguments (4 bytes missing) - # or wrong calling convention - self.assertRaises(ValueError, IsWindow, None) - -if sys.platform == "win32": - class FunctionCallTestCase(unittest.TestCase): - - if is_resource_enabled("SEH"): - def test_SEH(self): - # Call functions with invalid arguments, and make sure - # that access violations are trapped and raise an - # exception. - self.assertRaises(OSError, windll.kernel32.GetModuleHandleA, 32) - - def test_noargs(self): - # This is a special case on win32 x64 - windll.user32.GetDesktopWindow() - - class TestWintypes(unittest.TestCase): - def test_HWND(self): - from ctypes import wintypes - self.assertEqual(sizeof(wintypes.HWND), sizeof(c_void_p)) - - def test_PARAM(self): - from ctypes import wintypes - self.assertEqual(sizeof(wintypes.WPARAM), - sizeof(c_void_p)) - self.assertEqual(sizeof(wintypes.LPARAM), - sizeof(c_void_p)) - - def test_COMError(self): - from _ctypes import COMError - if support.HAVE_DOCSTRINGS: - self.assertEqual(COMError.__doc__, - "Raised when a COM method call failed.") - - ex = COMError(-1, "text", ("details",)) - self.assertEqual(ex.hresult, -1) - self.assertEqual(ex.text, "text") - self.assertEqual(ex.details, ("details",)) - - class TestWinError(unittest.TestCase): - def test_winerror(self): - # see Issue 16169 - import errno - ERROR_INVALID_PARAMETER = 87 - msg = FormatError(ERROR_INVALID_PARAMETER).strip() - args = (errno.EINVAL, msg, None, ERROR_INVALID_PARAMETER) - - e = WinError(ERROR_INVALID_PARAMETER) - self.assertEqual(e.args, args) - self.assertEqual(e.errno, errno.EINVAL) - self.assertEqual(e.winerror, ERROR_INVALID_PARAMETER) - - windll.kernel32.SetLastError(ERROR_INVALID_PARAMETER) - try: - raise WinError() - except OSError as exc: - e = exc - self.assertEqual(e.args, args) - self.assertEqual(e.errno, errno.EINVAL) - self.assertEqual(e.winerror, ERROR_INVALID_PARAMETER) +# Only windows 32-bit has different calling conventions. +@unittest.skipUnless(sys.platform == "win32", 'Windows-specific test') +@unittest.skipUnless(sizeof(c_void_p) == sizeof(c_int), + "sizeof c_void_p and c_int differ") +class WindowsTestCase(unittest.TestCase): + def test_callconv_1(self): + # Testing stdcall function + + IsWindow = windll.user32.IsWindow + # ValueError: Procedure probably called with not enough arguments + # (4 bytes missing) + self.assertRaises(ValueError, IsWindow) + + # This one should succeed... + self.assertEqual(0, IsWindow(0)) + + # ValueError: Procedure probably called with too many arguments + # (8 bytes in excess) + self.assertRaises(ValueError, IsWindow, 0, 0, 0) + + def test_callconv_2(self): + # Calling stdcall function as cdecl + + IsWindow = cdll.user32.IsWindow + + # ValueError: Procedure called with not enough arguments + # (4 bytes missing) or wrong calling convention + self.assertRaises(ValueError, IsWindow, None) + +@unittest.skipUnless(sys.platform == "win32", 'Windows-specific test') +class FunctionCallTestCase(unittest.TestCase): + @unittest.skipUnless('MSC' in sys.version, "SEH only supported by MSC") + @unittest.skipIf(sys.executable.lower().endswith('_d.exe'), + "SEH not enabled in debug builds") + def test_SEH(self): + # Call functions with invalid arguments, and make sure + # that access violations are trapped and raise an + # exception. + self.assertRaises(OSError, windll.kernel32.GetModuleHandleA, 32) + + def test_noargs(self): + # This is a special case on win32 x64 + windll.user32.GetDesktopWindow() + +@unittest.skipUnless(sys.platform == "win32", 'Windows-specific test') +class TestWintypes(unittest.TestCase): + def test_HWND(self): + from ctypes import wintypes + self.assertEqual(sizeof(wintypes.HWND), sizeof(c_void_p)) + + def test_PARAM(self): + from ctypes import wintypes + self.assertEqual(sizeof(wintypes.WPARAM), + sizeof(c_void_p)) + self.assertEqual(sizeof(wintypes.LPARAM), + sizeof(c_void_p)) + + def test_COMError(self): + from _ctypes import COMError + if support.HAVE_DOCSTRINGS: + self.assertEqual(COMError.__doc__, + "Raised when a COM method call failed.") + + ex = COMError(-1, "text", ("details",)) + self.assertEqual(ex.hresult, -1) + self.assertEqual(ex.text, "text") + self.assertEqual(ex.details, ("details",)) + +@unittest.skipUnless(sys.platform == "win32", 'Windows-specific test') +class TestWinError(unittest.TestCase): + def test_winerror(self): + # see Issue 16169 + import errno + ERROR_INVALID_PARAMETER = 87 + msg = FormatError(ERROR_INVALID_PARAMETER).strip() + args = (errno.EINVAL, msg, None, ERROR_INVALID_PARAMETER) + + e = WinError(ERROR_INVALID_PARAMETER) + self.assertEqual(e.args, args) + self.assertEqual(e.errno, errno.EINVAL) + self.assertEqual(e.winerror, ERROR_INVALID_PARAMETER) + + windll.kernel32.SetLastError(ERROR_INVALID_PARAMETER) + try: + raise WinError() + except OSError as exc: + e = exc + self.assertEqual(e.args, args) + self.assertEqual(e.errno, errno.EINVAL) + self.assertEqual(e.winerror, ERROR_INVALID_PARAMETER) class Structures(unittest.TestCase): - def test_struct_by_value(self): class POINT(Structure): _fields_ = [("x", c_long), @@ -107,9 +111,29 @@ class RECT(Structure): dll = CDLL(_ctypes_test.__file__) - pt = POINT(10, 10) - rect = RECT(0, 0, 20, 20) - self.assertEqual(1, dll.PointInRect(byref(rect), pt)) + pt = POINT(15, 25) + left = c_long.in_dll(dll, 'left') + top = c_long.in_dll(dll, 'top') + right = c_long.in_dll(dll, 'right') + bottom = c_long.in_dll(dll, 'bottom') + rect = RECT(left, top, right, bottom) + PointInRect = dll.PointInRect + PointInRect.argtypes = [POINTER(RECT), POINT] + self.assertEqual(1, PointInRect(byref(rect), pt)) + + ReturnRect = dll.ReturnRect + ReturnRect.argtypes = [c_int, RECT, POINTER(RECT), POINT, RECT, + POINTER(RECT), POINT, RECT] + ReturnRect.restype = RECT + for i in range(4): + ret = ReturnRect(i, rect, pointer(rect), pt, rect, + byref(rect), pt, rect) + # the c function will check and modify ret if something is + # passed in improperly + self.assertEqual(ret.left, left.value) + self.assertEqual(ret.right, right.value) + self.assertEqual(ret.top, top.value) + self.assertEqual(ret.bottom, bottom.value) if __name__ == '__main__': unittest.main() diff --git a/Lib/ctypes/test/test_wintypes.py b/Lib/ctypes/test/test_wintypes.py index 806fccef812f..71442df8301a 100644 --- a/Lib/ctypes/test/test_wintypes.py +++ b/Lib/ctypes/test/test_wintypes.py @@ -1,14 +1,12 @@ import sys import unittest -if not sys.platform.startswith('win'): - raise unittest.SkipTest('Windows-only test') - from ctypes import * -from ctypes import wintypes +@unittest.skipUnless(sys.platform.startswith('win'), 'Windows-only test') class WinTypesTest(unittest.TestCase): def test_variant_bool(self): + from ctypes import wintypes # reads 16-bits from memory, anything non-zero is True for true_value in (1, 32767, 32768, 65535, 65537): true = POINTER(c_int16)(c_int16(true_value)) diff --git a/Lib/ctypes/util.py b/Lib/ctypes/util.py index 0cf20766ccac..9c19899da570 100644 --- a/Lib/ctypes/util.py +++ b/Lib/ctypes/util.py @@ -19,6 +19,8 @@ def _get_build_version(): i = i + len(prefix) s, rest = sys.version[i:].split(" ", 1) majorVersion = int(s[:-2]) - 6 + if majorVersion >= 13: + majorVersion += 1 minorVersion = int(s[2:3]) / 10.0 # I don't think paths are affected by minor version in version 6 if majorVersion == 6: @@ -36,8 +38,10 @@ def find_msvcrt(): return None if version <= 6: clibname = 'msvcrt' - else: + elif version <= 13: clibname = 'msvcr%d' % (version * 10) + else: + clibname = 'appcrt%d' % (version * 10) # If python was built with in debug mode import importlib.machinery @@ -85,7 +89,7 @@ def find_library(name): elif os.name == "posix": # Andreas Degert's find functions, using gcc, /sbin/ldconfig, objdump - import re, tempfile, errno + import re, tempfile def _findLib_gcc(name): expr = r'[^\(\)\s]*lib%s\.[^\(\)\s]*' % re.escape(name) diff --git a/Lib/datetime.py b/Lib/datetime.py index 1789714034c9..4afe9a53814d 100644 --- a/Lib/datetime.py +++ b/Lib/datetime.py @@ -12,7 +12,7 @@ def _cmp(x, y): MINYEAR = 1 MAXYEAR = 9999 -_MAXORDINAL = 3652059 # date.max.toordinal() +_MAXORDINAL = 3652059 # date.max.toordinal() # Utility functions, adapted from Python's Demo/classes/Dates.py, which # also assumes the current Gregorian calendar indefinitely extended in @@ -26,7 +26,7 @@ def _cmp(x, y): # -1 is a placeholder for indexing purposes. _DAYS_IN_MONTH = [-1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] -_DAYS_BEFORE_MONTH = [-1] # -1 is a placeholder for indexing purposes. +_DAYS_BEFORE_MONTH = [-1] # -1 is a placeholder for indexing purposes. dbm = 0 for dim in _DAYS_IN_MONTH[1:]: _DAYS_BEFORE_MONTH.append(dbm) @@ -162,9 +162,9 @@ def _format_time(hh, mm, ss, us): # Correctly substitute for %z and %Z escapes in strftime formats. def _wrap_strftime(object, format, timetuple): # Don't call utcoffset() or tzname() unless actually needed. - freplace = None # the string to use for %f - zreplace = None # the string to use for %z - Zreplace = None # the string to use for %Z + freplace = None # the string to use for %f + zreplace = None # the string to use for %z + Zreplace = None # the string to use for %Z # Scan format for %z and %Z escapes, replacing as needed. newformat = [] @@ -217,11 +217,6 @@ def _wrap_strftime(object, format, timetuple): newformat = "".join(newformat) return _time.strftime(newformat, timetuple) -def _call_tzinfo_method(tzinfo, methname, tzinfoarg): - if tzinfo is None: - return None - return getattr(tzinfo, methname)(tzinfoarg) - # Just raise TypeError if the arg isn't None or a string. def _check_tzname(name): if name is not None and not isinstance(name, str): @@ -245,13 +240,31 @@ def _check_utc_offset(name, offset): raise ValueError("tzinfo.%s() must return a whole number " "of minutes, got %s" % (name, offset)) if not -timedelta(1) < offset < timedelta(1): - raise ValueError("%s()=%s, must be must be strictly between" - " -timedelta(hours=24) and timedelta(hours=24)" - % (name, offset)) + raise ValueError("%s()=%s, must be must be strictly between " + "-timedelta(hours=24) and timedelta(hours=24)" % + (name, offset)) + +def _check_int_field(value): + if isinstance(value, int): + return value + if not isinstance(value, float): + try: + value = value.__int__() + except AttributeError: + pass + else: + if isinstance(value, int): + return value + raise TypeError('__int__ returned non-int (type %s)' % + type(value).__name__) + raise TypeError('an integer is required (got type %s)' % + type(value).__name__) + raise TypeError('integer argument expected, got float') def _check_date_fields(year, month, day): - if not isinstance(year, int): - raise TypeError('int expected') + year = _check_int_field(year) + month = _check_int_field(month) + day = _check_int_field(day) if not MINYEAR <= year <= MAXYEAR: raise ValueError('year must be in %d..%d' % (MINYEAR, MAXYEAR), year) if not 1 <= month <= 12: @@ -259,10 +272,13 @@ def _check_date_fields(year, month, day): dim = _days_in_month(year, month) if not 1 <= day <= dim: raise ValueError('day must be in 1..%d' % dim, day) + return year, month, day def _check_time_fields(hour, minute, second, microsecond): - if not isinstance(hour, int): - raise TypeError('int expected') + hour = _check_int_field(hour) + minute = _check_int_field(minute) + second = _check_int_field(second) + microsecond = _check_int_field(microsecond) if not 0 <= hour <= 23: raise ValueError('hour must be in 0..23', hour) if not 0 <= minute <= 59: @@ -271,6 +287,7 @@ def _check_time_fields(hour, minute, second, microsecond): raise ValueError('second must be in 0..59', second) if not 0 <= microsecond <= 999999: raise ValueError('microsecond must be in 0..999999', microsecond) + return hour, minute, second, microsecond def _check_tzinfo_arg(tz): if tz is not None and not isinstance(tz, tzinfo): @@ -297,7 +314,7 @@ class timedelta: Representation: (days, seconds, microseconds). Why? Because I felt like it. """ - __slots__ = '_days', '_seconds', '_microseconds' + __slots__ = '_days', '_seconds', '_microseconds', '_hashcode' def __new__(cls, days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0): @@ -363,38 +380,26 @@ def __new__(cls, days=0, seconds=0, microseconds=0, # secondsfrac isn't referenced again if isinstance(microseconds, float): - microseconds += usdouble - microseconds = round(microseconds, 0) - seconds, microseconds = divmod(microseconds, 1e6) - assert microseconds == int(microseconds) - assert seconds == int(seconds) - days, seconds = divmod(seconds, 24.*3600.) - assert days == int(days) - assert seconds == int(seconds) - d += int(days) - s += int(seconds) # can't overflow - assert isinstance(s, int) - assert abs(s) <= 3 * 24 * 3600 + microseconds = round(microseconds + usdouble) + seconds, microseconds = divmod(microseconds, 1000000) + days, seconds = divmod(seconds, 24*3600) + d += days + s += seconds else: + microseconds = int(microseconds) seconds, microseconds = divmod(microseconds, 1000000) days, seconds = divmod(seconds, 24*3600) d += days - s += int(seconds) # can't overflow - assert isinstance(s, int) - assert abs(s) <= 3 * 24 * 3600 - microseconds = float(microseconds) - microseconds += usdouble - microseconds = round(microseconds, 0) + s += seconds + microseconds = round(microseconds + usdouble) + assert isinstance(s, int) + assert isinstance(microseconds, int) assert abs(s) <= 3 * 24 * 3600 assert abs(microseconds) < 3.1e6 # Just a little bit of carrying possible for microseconds and seconds. - assert isinstance(microseconds, float) - assert int(microseconds) == microseconds - us = int(microseconds) - seconds, us = divmod(us, 1000000) - s += seconds # cant't overflow - assert isinstance(s, int) + seconds, us = divmod(microseconds, 1000000) + s += seconds days, s = divmod(s, 24*3600) d += days @@ -402,27 +407,31 @@ def __new__(cls, days=0, seconds=0, microseconds=0, assert isinstance(s, int) and 0 <= s < 24*3600 assert isinstance(us, int) and 0 <= us < 1000000 - self = object.__new__(cls) + if abs(d) > 999999999: + raise OverflowError("timedelta # of days is too large: %d" % d) + self = object.__new__(cls) self._days = d self._seconds = s self._microseconds = us - if abs(d) > 999999999: - raise OverflowError("timedelta # of days is too large: %d" % d) - + self._hashcode = -1 return self def __repr__(self): if self._microseconds: - return "%s(%d, %d, %d)" % ('datetime.' + self.__class__.__name__, - self._days, - self._seconds, - self._microseconds) + return "%s.%s(%d, %d, %d)" % (self.__class__.__module__, + self.__class__.__qualname__, + self._days, + self._seconds, + self._microseconds) if self._seconds: - return "%s(%d, %d)" % ('datetime.' + self.__class__.__name__, - self._days, - self._seconds) - return "%s(%d)" % ('datetime.' + self.__class__.__name__, self._days) + return "%s.%s(%d, %d)" % (self.__class__.__module__, + self.__class__.__qualname__, + self._days, + self._seconds) + return "%s.%s(%d)" % (self.__class__.__module__, + self.__class__.__qualname__, + self._days) def __str__(self): mm, ss = divmod(self._seconds, 60) @@ -438,7 +447,7 @@ def plural(n): def total_seconds(self): """Total seconds in the duration.""" - return ((self.days * 86400 + self.seconds)*10**6 + + return ((self.days * 86400 + self.seconds) * 10**6 + self.microseconds) / 10**6 # Read-only field accessors @@ -558,12 +567,6 @@ def __eq__(self, other): else: return False - def __ne__(self, other): - if isinstance(other, timedelta): - return self._cmp(other) != 0 - else: - return True - def __le__(self, other): if isinstance(other, timedelta): return self._cmp(other) <= 0 @@ -593,7 +596,9 @@ def _cmp(self, other): return _cmp(self._getstate(), other._getstate()) def __hash__(self): - return hash(self._getstate()) + if self._hashcode == -1: + self._hashcode = hash(self._getstate()) + return self._hashcode def __bool__(self): return (self._days != 0 or @@ -641,7 +646,7 @@ class date: Properties (readonly): year, month, day """ - __slots__ = '_year', '_month', '_day' + __slots__ = '_year', '_month', '_day', '_hashcode' def __new__(cls, year, month=None, day=None): """Constructor. @@ -650,17 +655,19 @@ def __new__(cls, year, month=None, day=None): year, month, day (required, base 1) """ - if (isinstance(year, bytes) and len(year) == 4 and - 1 <= year[2] <= 12 and month is None): # Month is sane + if month is None and isinstance(year, bytes) and len(year) == 4 and \ + 1 <= year[2] <= 12: # Pickle support self = object.__new__(cls) self.__setstate(year) + self._hashcode = -1 return self - _check_date_fields(year, month, day) + year, month, day = _check_date_fields(year, month, day) self = object.__new__(cls) self._year = year self._month = month self._day = day + self._hashcode = -1 return self # Additional constructors @@ -700,10 +707,11 @@ def __repr__(self): >>> repr(dt) 'datetime.datetime(2010, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)' """ - return "%s(%d, %d, %d)" % ('datetime.' + self.__class__.__name__, - self._year, - self._month, - self._day) + return "%s.%s(%d, %d, %d)" % (self.__class__.__module__, + self.__class__.__qualname__, + self._year, + self._month, + self._day) # XXX These shouldn't depend on time.localtime(), because that # clips the usable dates to [1970 .. 2038). At least ctime() is # easily done without using strftime() -- that's better too because @@ -723,6 +731,8 @@ def strftime(self, fmt): return _wrap_strftime(self, fmt, self.timetuple()) def __format__(self, fmt): + if not isinstance(fmt, str): + raise TypeError("must be str, not %s" % type(fmt).__name__) if len(fmt) != 0: return self.strftime(fmt) return str(self) @@ -779,7 +789,6 @@ def replace(self, year=None, month=None, day=None): month = self._month if day is None: day = self._day - _check_date_fields(year, month, day) return date(year, month, day) # Comparisons of date objects with other. @@ -789,11 +798,6 @@ def __eq__(self, other): return self._cmp(other) == 0 return NotImplemented - def __ne__(self, other): - if isinstance(other, date): - return self._cmp(other) != 0 - return NotImplemented - def __le__(self, other): if isinstance(other, date): return self._cmp(other) <= 0 @@ -822,7 +826,9 @@ def _cmp(self, other): def __hash__(self): "Hash." - return hash(self._getstate()) + if self._hashcode == -1: + self._hashcode = hash(self._getstate()) + return self._hashcode # Computations @@ -892,8 +898,6 @@ def _getstate(self): return bytes([yhi, ylo, self._month, self._day]), def __setstate(self, string): - if len(string) != 4 or not (1 <= string[2] <= 12): - raise TypeError("not enough arguments") yhi, ylo, self._month, self._day = string self._year = yhi * 256 + ylo @@ -912,6 +916,7 @@ class tzinfo: Subclasses must override the name(), utcoffset() and dst() methods. """ __slots__ = () + def tzname(self, dt): "datetime -> string name of time zone." raise NotImplementedError("tzinfo subclass must override tzname()") @@ -998,6 +1003,7 @@ class time: Properties (readonly): hour, minute, second, microsecond, tzinfo """ + __slots__ = '_hour', '_minute', '_second', '_microsecond', '_tzinfo', '_hashcode' def __new__(cls, hour=0, minute=0, second=0, microsecond=0, tzinfo=None): """Constructor. @@ -1008,18 +1014,22 @@ def __new__(cls, hour=0, minute=0, second=0, microsecond=0, tzinfo=None): second, microsecond (default to zero) tzinfo (default to None) """ - self = object.__new__(cls) - if isinstance(hour, bytes) and len(hour) == 6: + if isinstance(hour, bytes) and len(hour) == 6 and hour[0] < 24: # Pickle support + self = object.__new__(cls) self.__setstate(hour, minute or None) + self._hashcode = -1 return self + hour, minute, second, microsecond = _check_time_fields( + hour, minute, second, microsecond) _check_tzinfo_arg(tzinfo) - _check_time_fields(hour, minute, second, microsecond) + self = object.__new__(cls) self._hour = hour self._minute = minute self._second = second self._microsecond = microsecond self._tzinfo = tzinfo + self._hashcode = -1 return self # Read-only field accessors @@ -1058,12 +1068,6 @@ def __eq__(self, other): else: return False - def __ne__(self, other): - if isinstance(other, time): - return self._cmp(other, allow_mixed=True) != 0 - else: - return True - def __le__(self, other): if isinstance(other, time): return self._cmp(other) <= 0 @@ -1104,8 +1108,8 @@ def _cmp(self, other, allow_mixed=False): if base_compare: return _cmp((self._hour, self._minute, self._second, self._microsecond), - (other._hour, other._minute, other._second, - other._microsecond)) + (other._hour, other._minute, other._second, + other._microsecond)) if myoff is None or otoff is None: if allow_mixed: return 2 # arbitrary non-zero value @@ -1118,16 +1122,20 @@ def _cmp(self, other, allow_mixed=False): def __hash__(self): """Hash.""" - tzoff = self.utcoffset() - if not tzoff: # zero or None - return hash(self._getstate()[0]) - h, m = divmod(timedelta(hours=self.hour, minutes=self.minute) - tzoff, - timedelta(hours=1)) - assert not m % timedelta(minutes=1), "whole minute" - m //= timedelta(minutes=1) - if 0 <= h < 24: - return hash(time(h, m, self.second, self.microsecond)) - return hash((h, m, self.second, self.microsecond)) + if self._hashcode == -1: + tzoff = self.utcoffset() + if not tzoff: # zero or None + self._hashcode = hash(self._getstate()[0]) + else: + h, m = divmod(timedelta(hours=self.hour, minutes=self.minute) - tzoff, + timedelta(hours=1)) + assert not m % timedelta(minutes=1), "whole minute" + m //= timedelta(minutes=1) + if 0 <= h < 24: + self._hashcode = hash(time(h, m, self.second, self.microsecond)) + else: + self._hashcode = hash((h, m, self.second, self.microsecond)) + return self._hashcode # Conversion to string @@ -1155,8 +1163,9 @@ def __repr__(self): s = ", %d" % self._second else: s = "" - s= "%s(%d, %d%s)" % ('datetime.' + self.__class__.__name__, - self._hour, self._minute, s) + s= "%s.%s(%d, %d%s)" % (self.__class__.__module__, + self.__class__.__qualname__, + self._hour, self._minute, s) if self._tzinfo is not None: assert s[-1:] == ")" s = s[:-1] + ", tzinfo=%r" % self._tzinfo + ")" @@ -1189,6 +1198,8 @@ def strftime(self, fmt): return _wrap_strftime(self, fmt, timetuple) def __format__(self, fmt): + if not isinstance(fmt, str): + raise TypeError("must be str, not %s" % type(fmt).__name__) if len(fmt) != 0: return self.strftime(fmt) return str(self) @@ -1245,16 +1256,8 @@ def replace(self, hour=None, minute=None, second=None, microsecond=None, microsecond = self.microsecond if tzinfo is True: tzinfo = self.tzinfo - _check_time_fields(hour, minute, second, microsecond) - _check_tzinfo_arg(tzinfo) return time(hour, minute, second, microsecond, tzinfo) - def __bool__(self): - if self.second or self.microsecond: - return True - offset = self.utcoffset() or timedelta(0) - return timedelta(hours=self.hour, minutes=self.minute) != offset - # Pickle support. def _getstate(self): @@ -1268,15 +1271,11 @@ def _getstate(self): return (basestate, self._tzinfo) def __setstate(self, string, tzinfo): - if len(string) != 6 or string[0] >= 24: - raise TypeError("an integer is required") - (self._hour, self._minute, self._second, - us1, us2, us3) = string + if tzinfo is not None and not isinstance(tzinfo, _tzinfo_class): + raise TypeError("bad tzinfo state arg") + self._hour, self._minute, self._second, us1, us2, us3 = string self._microsecond = (((us1 << 8) | us2) << 8) | us3 - if tzinfo is None or isinstance(tzinfo, _tzinfo_class): - self._tzinfo = tzinfo - else: - raise TypeError("bad tzinfo state arg %r" % tzinfo) + self._tzinfo = tzinfo def __reduce__(self): return (time, self._getstate()) @@ -1293,25 +1292,30 @@ class datetime(date): The year, month and day arguments are required. tzinfo may be None, or an instance of a tzinfo subclass. The remaining arguments may be ints. """ + __slots__ = date.__slots__ + time.__slots__ - __slots__ = date.__slots__ + ( - '_hour', '_minute', '_second', - '_microsecond', '_tzinfo') def __new__(cls, year, month=None, day=None, hour=0, minute=0, second=0, microsecond=0, tzinfo=None): - if isinstance(year, bytes) and len(year) == 10: + if isinstance(year, bytes) and len(year) == 10 and 1 <= year[2] <= 12: # Pickle support - self = date.__new__(cls, year[:4]) + self = object.__new__(cls) self.__setstate(year, month) + self._hashcode = -1 return self + year, month, day = _check_date_fields(year, month, day) + hour, minute, second, microsecond = _check_time_fields( + hour, minute, second, microsecond) _check_tzinfo_arg(tzinfo) - _check_time_fields(hour, minute, second, microsecond) - self = date.__new__(cls, year, month, day) + self = object.__new__(cls) + self._year = year + self._month = month + self._day = day self._hour = hour self._minute = minute self._second = second self._microsecond = microsecond self._tzinfo = tzinfo + self._hashcode = -1 return self # Read-only field accessors @@ -1346,7 +1350,6 @@ def fromtimestamp(cls, t, tz=None): A timezone info object may be passed in as well. """ - _check_tzinfo_arg(tz) converter = _time.localtime if tz is None else _time.gmtime @@ -1385,11 +1388,6 @@ def utcfromtimestamp(cls, t): ss = min(ss, 59) # clamp out leap seconds if the platform has them return cls(y, m, d, hh, mm, ss, us) - # XXX This is supposed to do better than we *can* do by using time.time(), - # XXX if the platform supports a more accurate way. The C implementation - # XXX uses gettimeofday on platforms that have it, but that isn't - # XXX available from Python. So now() may return different results - # XXX across the implementations. @classmethod def now(cls, tz=None): "Construct a datetime from time.time() and optional time zone info." @@ -1476,11 +1474,8 @@ def replace(self, year=None, month=None, day=None, hour=None, microsecond = self.microsecond if tzinfo is True: tzinfo = self.tzinfo - _check_date_fields(year, month, day) - _check_time_fields(hour, minute, second, microsecond) - _check_tzinfo_arg(tzinfo) - return datetime(year, month, day, hour, minute, second, - microsecond, tzinfo) + return datetime(year, month, day, hour, minute, second, microsecond, + tzinfo) def astimezone(self, tz=None): if tz is None: @@ -1550,10 +1545,9 @@ def isoformat(self, sep='T'): Optional argument sep specifies the separator between date and time, default 'T'. """ - s = ("%04d-%02d-%02d%c" % (self._year, self._month, self._day, - sep) + - _format_time(self._hour, self._minute, self._second, - self._microsecond)) + s = ("%04d-%02d-%02d%c" % (self._year, self._month, self._day, sep) + + _format_time(self._hour, self._minute, self._second, + self._microsecond)) off = self.utcoffset() if off is not None: if off.days < 0: @@ -1569,14 +1563,15 @@ def isoformat(self, sep='T'): def __repr__(self): """Convert to formal string, for repr().""" - L = [self._year, self._month, self._day, # These are never zero + L = [self._year, self._month, self._day, # These are never zero self._hour, self._minute, self._second, self._microsecond] if L[-1] == 0: del L[-1] if L[-1] == 0: del L[-1] - s = ", ".join(map(str, L)) - s = "%s(%s)" % ('datetime.' + self.__class__.__name__, s) + s = "%s.%s(%s)" % (self.__class__.__module__, + self.__class__.__qualname__, + ", ".join(map(str, L))) if self._tzinfo is not None: assert s[-1:] == ")" s = s[:-1] + ", tzinfo=%r" % self._tzinfo + ")" @@ -1608,7 +1603,9 @@ def tzname(self): it mean anything in particular. For example, "GMT", "UTC", "-500", "-5:00", "EDT", "US/Eastern", "America/New York" are all valid replies. """ - name = _call_tzinfo_method(self._tzinfo, "tzname", self) + if self._tzinfo is None: + return None + name = self._tzinfo.tzname(self) _check_tzname(name) return name @@ -1637,14 +1634,6 @@ def __eq__(self, other): else: return False - def __ne__(self, other): - if isinstance(other, datetime): - return self._cmp(other, allow_mixed=True) != 0 - elif not isinstance(other, date): - return NotImplemented - else: - return True - def __le__(self, other): if isinstance(other, datetime): return self._cmp(other) <= 0 @@ -1694,9 +1683,9 @@ def _cmp(self, other, allow_mixed=False): return _cmp((self._year, self._month, self._day, self._hour, self._minute, self._second, self._microsecond), - (other._year, other._month, other._day, - other._hour, other._minute, other._second, - other._microsecond)) + (other._year, other._month, other._day, + other._hour, other._minute, other._second, + other._microsecond)) if myoff is None or otoff is None: if allow_mixed: return 2 # arbitrary non-zero value @@ -1754,12 +1743,15 @@ def __sub__(self, other): return base + otoff - myoff def __hash__(self): - tzoff = self.utcoffset() - if tzoff is None: - return hash(self._getstate()[0]) - days = _ymd2ord(self.year, self.month, self.day) - seconds = self.hour * 3600 + self.minute * 60 + self.second - return hash(timedelta(days, seconds, self.microsecond) - tzoff) + if self._hashcode == -1: + tzoff = self.utcoffset() + if tzoff is None: + self._hashcode = hash(self._getstate()[0]) + else: + days = _ymd2ord(self.year, self.month, self.day) + seconds = self.hour * 3600 + self.minute * 60 + self.second + self._hashcode = hash(timedelta(days, seconds, self.microsecond) - tzoff) + return self._hashcode # Pickle support. @@ -1776,14 +1768,13 @@ def _getstate(self): return (basestate, self._tzinfo) def __setstate(self, string, tzinfo): + if tzinfo is not None and not isinstance(tzinfo, _tzinfo_class): + raise TypeError("bad tzinfo state arg") (yhi, ylo, self._month, self._day, self._hour, self._minute, self._second, us1, us2, us3) = string self._year = yhi * 256 + ylo self._microsecond = (((us1 << 8) | us2) << 8) | us3 - if tzinfo is None or isinstance(tzinfo, _tzinfo_class): - self._tzinfo = tzinfo - else: - raise TypeError("bad tzinfo state arg %r" % tzinfo) + self._tzinfo = tzinfo def __reduce__(self): return (self.__class__, self._getstate()) @@ -1799,7 +1790,7 @@ def _isoweek1monday(year): # XXX This could be done more efficiently THURSDAY = 3 firstday = _ymd2ord(year, 1, 1) - firstweekday = (firstday + 6) % 7 # See weekday() above + firstweekday = (firstday + 6) % 7 # See weekday() above week1monday = firstday - firstweekday if firstweekday > THURSDAY: week1monday += 7 @@ -1820,13 +1811,12 @@ def __new__(cls, offset, name=_Omitted): elif not isinstance(name, str): raise TypeError("name must be a string") if not cls._minoffset <= offset <= cls._maxoffset: - raise ValueError("offset must be a timedelta" - " strictly between -timedelta(hours=24) and" - " timedelta(hours=24).") - if (offset.microseconds != 0 or - offset.seconds % 60 != 0): - raise ValueError("offset must be a timedelta" - " representing a whole number of minutes") + raise ValueError("offset must be a timedelta " + "strictly between -timedelta(hours=24) and " + "timedelta(hours=24).") + if (offset.microseconds != 0 or offset.seconds % 60 != 0): + raise ValueError("offset must be a timedelta " + "representing a whole number of minutes") return cls._create(offset, name) @classmethod @@ -1863,10 +1853,12 @@ def __repr__(self): if self is self.utc: return 'datetime.timezone.utc' if self._name is None: - return "%s(%r)" % ('datetime.' + self.__class__.__name__, - self._offset) - return "%s(%r, %r)" % ('datetime.' + self.__class__.__name__, - self._offset, self._name) + return "%s.%s(%r)" % (self.__class__.__module__, + self.__class__.__qualname__, + self._offset) + return "%s.%s(%r, %r)" % (self.__class__.__module__, + self.__class__.__qualname__, + self._offset, self._name) def __str__(self): return self.tzname(None) @@ -2121,14 +2113,13 @@ def _name_from_offset(delta): pass else: # Clean up unused names - del (_DAYNAMES, _DAYS_BEFORE_MONTH, _DAYS_IN_MONTH, - _DI100Y, _DI400Y, _DI4Y, _MAXORDINAL, _MONTHNAMES, - _build_struct_time, _call_tzinfo_method, _check_date_fields, - _check_time_fields, _check_tzinfo_arg, _check_tzname, - _check_utc_offset, _cmp, _cmperror, _date_class, _days_before_month, - _days_before_year, _days_in_month, _format_time, _is_leap, - _isoweek1monday, _math, _ord2ymd, _time, _time_class, _tzinfo_class, - _wrap_strftime, _ymd2ord) + del (_DAYNAMES, _DAYS_BEFORE_MONTH, _DAYS_IN_MONTH, _DI100Y, _DI400Y, + _DI4Y, _EPOCH, _MAXORDINAL, _MONTHNAMES, _build_struct_time, + _check_date_fields, _check_int_field, _check_time_fields, + _check_tzinfo_arg, _check_tzname, _check_utc_offset, _cmp, _cmperror, + _date_class, _days_before_month, _days_before_year, _days_in_month, + _format_time, _is_leap, _isoweek1monday, _math, _ord2ymd, + _time, _time_class, _tzinfo_class, _wrap_strftime, _ymd2ord) # XXX Since import * above excludes names that start with _, # docstring does not get overwritten. In the future, it may be # appropriate to maintain a single module level docstring and diff --git a/Lib/dbm/dumb.py b/Lib/dbm/dumb.py index ba6a20d0c9ac..34240968e727 100644 --- a/Lib/dbm/dumb.py +++ b/Lib/dbm/dumb.py @@ -21,6 +21,7 @@ """ +import ast as _ast import io as _io import os as _os import collections @@ -44,7 +45,7 @@ class _Database(collections.MutableMapping): _os = _os # for _commit() _io = _io # for _commit() - def __init__(self, filebasename, mode): + def __init__(self, filebasename, mode, flag='c'): self._mode = mode # The directory file is a text file. Each line looks like @@ -64,14 +65,25 @@ def __init__(self, filebasename, mode): # The index is an in-memory dict, mirroring the directory file. self._index = None # maps keys to (pos, siz) pairs + # Handle the creation + self._create(flag) + self._update() + + def _create(self, flag): + if flag == 'n': + for filename in (self._datfile, self._bakfile, self._dirfile): + try: + _os.remove(filename) + except OSError: + pass # Mod by Jack: create data file if needed try: f = _io.open(self._datfile, 'r', encoding="Latin-1") except OSError: - f = _io.open(self._datfile, 'w', encoding="Latin-1") - self._chmod(self._datfile) - f.close() - self._update() + with _io.open(self._datfile, 'w', encoding="Latin-1") as f: + self._chmod(self._datfile) + else: + f.close() # Read directory file into the in-memory index dict. def _update(self): @@ -81,12 +93,12 @@ def _update(self): except OSError: pass else: - for line in f: - line = line.rstrip() - key, pos_and_siz_pair = eval(line) - key = key.encode('Latin-1') - self._index[key] = pos_and_siz_pair - f.close() + with f: + for line in f: + line = line.rstrip() + key, pos_and_siz_pair = _ast.literal_eval(line) + key = key.encode('Latin-1') + self._index[key] = pos_and_siz_pair # Write the index dict to the directory file. The original directory # file (if any) is renamed with a .bak extension first. If a .bak @@ -108,24 +120,28 @@ def _commit(self): except OSError: pass - f = self._io.open(self._dirfile, 'w', encoding="Latin-1") - self._chmod(self._dirfile) - for key, pos_and_siz_pair in self._index.items(): - # Use Latin-1 since it has no qualms with any value in any - # position; UTF-8, though, does care sometimes. - f.write("%r, %r\n" % (key.decode('Latin-1'), pos_and_siz_pair)) - f.close() + with self._io.open(self._dirfile, 'w', encoding="Latin-1") as f: + self._chmod(self._dirfile) + for key, pos_and_siz_pair in self._index.items(): + # Use Latin-1 since it has no qualms with any value in any + # position; UTF-8, though, does care sometimes. + entry = "%r, %r\n" % (key.decode('Latin-1'), pos_and_siz_pair) + f.write(entry) sync = _commit + def _verify_open(self): + if self._index is None: + raise error('DBM object has already been closed') + def __getitem__(self, key): if isinstance(key, str): key = key.encode('utf-8') + self._verify_open() pos, siz = self._index[key] # may raise KeyError - f = _io.open(self._datfile, 'rb') - f.seek(pos) - dat = f.read(siz) - f.close() + with _io.open(self._datfile, 'rb') as f: + f.seek(pos) + dat = f.read(siz) return dat # Append val to the data file, starting at a _BLOCKSIZE-aligned @@ -133,14 +149,13 @@ def __getitem__(self, key): # to get to an aligned offset. Return pair # (starting offset of val, len(val)) def _addval(self, val): - f = _io.open(self._datfile, 'rb+') - f.seek(0, 2) - pos = int(f.tell()) - npos = ((pos + _BLOCKSIZE - 1) // _BLOCKSIZE) * _BLOCKSIZE - f.write(b'\0'*(npos-pos)) - pos = npos - f.write(val) - f.close() + with _io.open(self._datfile, 'rb+') as f: + f.seek(0, 2) + pos = int(f.tell()) + npos = ((pos + _BLOCKSIZE - 1) // _BLOCKSIZE) * _BLOCKSIZE + f.write(b'\0'*(npos-pos)) + pos = npos + f.write(val) return (pos, len(val)) # Write val to the data file, starting at offset pos. The caller @@ -148,10 +163,9 @@ def _addval(self, val): # pos to hold val, without overwriting some other value. Return # pair (pos, len(val)). def _setval(self, pos, val): - f = _io.open(self._datfile, 'rb+') - f.seek(pos) - f.write(val) - f.close() + with _io.open(self._datfile, 'rb+') as f: + f.seek(pos) + f.write(val) return (pos, len(val)) # key is a new key whose associated value starts in the data file @@ -159,10 +173,9 @@ def _setval(self, pos, val): # the in-memory index dict, and append one to the directory file. def _addkey(self, key, pos_and_siz_pair): self._index[key] = pos_and_siz_pair - f = _io.open(self._dirfile, 'a', encoding="Latin-1") - self._chmod(self._dirfile) - f.write("%r, %r\n" % (key.decode("Latin-1"), pos_and_siz_pair)) - f.close() + with _io.open(self._dirfile, 'a', encoding="Latin-1") as f: + self._chmod(self._dirfile) + f.write("%r, %r\n" % (key.decode("Latin-1"), pos_and_siz_pair)) def __setitem__(self, key, val): if isinstance(key, str): @@ -173,6 +186,7 @@ def __setitem__(self, key, val): val = val.encode('utf-8') elif not isinstance(val, (bytes, bytearray)): raise TypeError("values must be bytes or strings") + self._verify_open() if key not in self._index: self._addkey(key, self._addval(val)) else: @@ -200,6 +214,7 @@ def __setitem__(self, key, val): def __delitem__(self, key): if isinstance(key, str): key = key.encode('utf-8') + self._verify_open() # 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 @@ -209,22 +224,38 @@ def __delitem__(self, key): self._commit() def keys(self): - return list(self._index.keys()) + try: + return list(self._index) + except TypeError: + raise error('DBM object has already been closed') from None def items(self): + self._verify_open() return [(key, self[key]) for key in self._index.keys()] def __contains__(self, key): if isinstance(key, str): key = key.encode('utf-8') - return key in self._index + try: + return key in self._index + except TypeError: + if self._index is None: + raise error('DBM object has already been closed') from None + else: + raise def iterkeys(self): - return iter(self._index.keys()) + try: + return iter(self._index) + except TypeError: + raise error('DBM object has already been closed') from None __iter__ = iterkeys def __len__(self): - return len(self._index) + try: + return len(self._index) + except TypeError: + raise error('DBM object has already been closed') from None def close(self): self._commit() @@ -243,20 +274,20 @@ def __exit__(self, *args): self.close() -def open(file, flag=None, mode=0o666): +def open(file, flag='c', mode=0o666): """Open the database file, filename, and return corresponding object. The flag argument, used to control how the database is opened in the - other DBM implementations, is ignored in the dbm.dumb module; the - database is always opened for update, and will be created if it does - not exist. + other DBM implementations, supports only the semantics of 'c' and 'n' + values. Other values will default to the semantics of 'c' value: + the database will always opened for update and will be created if it + does not exist. The optional mode argument is the UNIX mode of the file, used only when the database has to be created. It defaults to octal code 0o666 (and will be modified by the prevailing umask). """ - # flag argument is currently ignored # Modify mode depending on the umask try: @@ -267,5 +298,4 @@ def open(file, flag=None, mode=0o666): else: # Turn off any bits that are set in the umask mode = mode & (~um) - - return _Database(file, mode) + return _Database(file, mode, flag=flag) diff --git a/Lib/decimal.py b/Lib/decimal.py index 7bc1c943b5b0..7746ea260102 100644 --- a/Lib/decimal.py +++ b/Lib/decimal.py @@ -1,6407 +1,11 @@ -# Copyright (c) 2004 Python Software Foundation. -# All rights reserved. - -# Written by Eric Price <eprice at tjhsst.edu> -# and Facundo Batista <facundo at taniquetil.com.ar> -# and Raymond Hettinger <python at rcn.com> -# and Aahz <aahz at pobox.com> -# and Tim Peters - -# This module should be kept in sync with the latest updates of the -# IBM specification as it evolves. Those updates will be treated -# as bug fixes (deviation from the spec is a compatibility, usability -# bug) and will be backported. At this point the spec is stabilizing -# and the updates are becoming fewer, smaller, and less significant. - -""" -This is an implementation of decimal floating point arithmetic based on -the General Decimal Arithmetic Specification: - - http://speleotrove.com/decimal/decarith.html - -and IEEE standard 854-1987: - - http://en.wikipedia.org/wiki/IEEE_854-1987 - -Decimal floating point has finite precision with arbitrarily large bounds. - -The purpose of this module is to support arithmetic using familiar -"schoolhouse" rules and to avoid some of the tricky representation -issues associated with binary floating point. The package is especially -useful for financial applications or for contexts where users have -expectations that are at odds with binary floating point (for instance, -in binary floating point, 1.00 % 0.1 gives 0.09999999999999995 instead -of 0.0; Decimal('1.00') % Decimal('0.1') returns the expected -Decimal('0.00')). - -Here are some examples of using the decimal module: - ->>> from decimal import * ->>> setcontext(ExtendedContext) ->>> Decimal(0) -Decimal('0') ->>> Decimal('1') -Decimal('1') ->>> Decimal('-.0123') -Decimal('-0.0123') ->>> Decimal(123456) -Decimal('123456') ->>> Decimal('123.45e12345678') -Decimal('1.2345E+12345680') ->>> Decimal('1.33') + Decimal('1.27') -Decimal('2.60') ->>> Decimal('12.34') + Decimal('3.87') - Decimal('18.41') -Decimal('-2.20') ->>> dig = Decimal(1) ->>> print(dig / Decimal(3)) -0.333333333 ->>> getcontext().prec = 18 ->>> print(dig / Decimal(3)) -0.333333333333333333 ->>> print(dig.sqrt()) -1 ->>> print(Decimal(3).sqrt()) -1.73205080756887729 ->>> print(Decimal(3) ** 123) -4.85192780976896427E+58 ->>> inf = Decimal(1) / Decimal(0) ->>> print(inf) -Infinity ->>> neginf = Decimal(-1) / Decimal(0) ->>> print(neginf) --Infinity ->>> print(neginf + inf) -NaN ->>> print(neginf * inf) --Infinity ->>> print(dig / 0) -Infinity ->>> getcontext().traps[DivisionByZero] = 1 ->>> print(dig / 0) -Traceback (most recent call last): - ... - ... - ... -decimal.DivisionByZero: x / 0 ->>> c = Context() ->>> c.traps[InvalidOperation] = 0 ->>> print(c.flags[InvalidOperation]) -0 ->>> c.divide(Decimal(0), Decimal(0)) -Decimal('NaN') ->>> c.traps[InvalidOperation] = 1 ->>> print(c.flags[InvalidOperation]) -1 ->>> c.flags[InvalidOperation] = 0 ->>> print(c.flags[InvalidOperation]) -0 ->>> print(c.divide(Decimal(0), Decimal(0))) -Traceback (most recent call last): - ... - ... - ... -decimal.InvalidOperation: 0 / 0 ->>> print(c.flags[InvalidOperation]) -1 ->>> c.flags[InvalidOperation] = 0 ->>> c.traps[InvalidOperation] = 0 ->>> print(c.divide(Decimal(0), Decimal(0))) -NaN ->>> print(c.flags[InvalidOperation]) -1 ->>> -""" - -__all__ = [ - # Two major classes - 'Decimal', 'Context', - - # Contexts - 'DefaultContext', 'BasicContext', 'ExtendedContext', - - # Exceptions - 'DecimalException', 'Clamped', 'InvalidOperation', 'DivisionByZero', - 'Inexact', 'Rounded', 'Subnormal', 'Overflow', 'Underflow', - 'FloatOperation', - - # Constants for use in setting up contexts - 'ROUND_DOWN', 'ROUND_HALF_UP', 'ROUND_HALF_EVEN', 'ROUND_CEILING', - 'ROUND_FLOOR', 'ROUND_UP', 'ROUND_HALF_DOWN', 'ROUND_05UP', - - # Functions for manipulating contexts - 'setcontext', 'getcontext', 'localcontext', - - # Limits for the C version for compatibility - 'MAX_PREC', 'MAX_EMAX', 'MIN_EMIN', 'MIN_ETINY', - - # C version: compile time choice that enables the thread local context - 'HAVE_THREADS' -] - -__version__ = '1.70' # Highest version of the spec this complies with - # See http://speleotrove.com/decimal/ -__libmpdec_version__ = "2.4.0" # compatible libmpdec version - -import copy as _copy -import math as _math -import numbers as _numbers -import sys - -try: - from collections import namedtuple as _namedtuple - DecimalTuple = _namedtuple('DecimalTuple', 'sign digits exponent') -except ImportError: - DecimalTuple = lambda *args: args - -# Rounding -ROUND_DOWN = 'ROUND_DOWN' -ROUND_HALF_UP = 'ROUND_HALF_UP' -ROUND_HALF_EVEN = 'ROUND_HALF_EVEN' -ROUND_CEILING = 'ROUND_CEILING' -ROUND_FLOOR = 'ROUND_FLOOR' -ROUND_UP = 'ROUND_UP' -ROUND_HALF_DOWN = 'ROUND_HALF_DOWN' -ROUND_05UP = 'ROUND_05UP' - -# Compatibility with the C version -HAVE_THREADS = True -if sys.maxsize == 2**63-1: - MAX_PREC = 999999999999999999 - MAX_EMAX = 999999999999999999 - MIN_EMIN = -999999999999999999 -else: - MAX_PREC = 425000000 - MAX_EMAX = 425000000 - MIN_EMIN = -425000000 - -MIN_ETINY = MIN_EMIN - (MAX_PREC-1) - -# Errors - -class DecimalException(ArithmeticError): - """Base exception class. - - Used exceptions derive from this. - If an exception derives from another exception besides this (such as - Underflow (Inexact, Rounded, Subnormal) that indicates that it is only - called if the others are present. This isn't actually used for - anything, though. - - handle -- Called when context._raise_error is called and the - trap_enabler is not set. First argument is self, second is the - context. More arguments can be given, those being after - the explanation in _raise_error (For example, - context._raise_error(NewError, '(-x)!', self._sign) would - call NewError().handle(context, self._sign).) - - To define a new exception, it should be sufficient to have it derive - from DecimalException. - """ - def handle(self, context, *args): - pass - - -class Clamped(DecimalException): - """Exponent of a 0 changed to fit bounds. - - This occurs and signals clamped if the exponent of a result has been - altered in order to fit the constraints of a specific concrete - representation. This may occur when the exponent of a zero result would - be outside the bounds of a representation, or when a large normal - number would have an encoded exponent that cannot be represented. In - this latter case, the exponent is reduced to fit and the corresponding - number of zero digits are appended to the coefficient ("fold-down"). - """ - -class InvalidOperation(DecimalException): - """An invalid operation was performed. - - Various bad things cause this: - - Something creates a signaling NaN - -INF + INF - 0 * (+-)INF - (+-)INF / (+-)INF - x % 0 - (+-)INF % x - x._rescale( non-integer ) - sqrt(-x) , x > 0 - 0 ** 0 - x ** (non-integer) - x ** (+-)INF - An operand is invalid - - The result of the operation after these is a quiet positive NaN, - except when the cause is a signaling NaN, in which case the result is - also a quiet NaN, but with the original sign, and an optional - diagnostic information. - """ - def handle(self, context, *args): - if args: - ans = _dec_from_triple(args[0]._sign, args[0]._int, 'n', True) - return ans._fix_nan(context) - return _NaN - -class ConversionSyntax(InvalidOperation): - """Trying to convert badly formed string. - - This occurs and signals invalid-operation if an string is being - converted to a number and it does not conform to the numeric string - syntax. The result is [0,qNaN]. - """ - def handle(self, context, *args): - return _NaN - -class DivisionByZero(DecimalException, ZeroDivisionError): - """Division by 0. - - This occurs and signals division-by-zero if division of a finite number - by zero was attempted (during a divide-integer or divide operation, or a - power operation with negative right-hand operand), and the dividend was - not zero. - - The result of the operation is [sign,inf], where sign is the exclusive - or of the signs of the operands for divide, or is 1 for an odd power of - -0, for power. - """ - - def handle(self, context, sign, *args): - return _SignedInfinity[sign] - -class DivisionImpossible(InvalidOperation): - """Cannot perform the division adequately. - - This occurs and signals invalid-operation if the integer result of a - divide-integer or remainder operation had too many digits (would be - longer than precision). The result is [0,qNaN]. - """ - - def handle(self, context, *args): - return _NaN - -class DivisionUndefined(InvalidOperation, ZeroDivisionError): - """Undefined result of division. - - This occurs and signals invalid-operation if division by zero was - attempted (during a divide-integer, divide, or remainder operation), and - the dividend is also zero. The result is [0,qNaN]. - """ - - def handle(self, context, *args): - return _NaN - -class Inexact(DecimalException): - """Had to round, losing information. - - This occurs and signals inexact whenever the result of an operation is - not exact (that is, it needed to be rounded and any discarded digits - were non-zero), or if an overflow or underflow condition occurs. The - result in all cases is unchanged. - - The inexact signal may be tested (or trapped) to determine if a given - operation (or sequence of operations) was inexact. - """ - -class InvalidContext(InvalidOperation): - """Invalid context. Unknown rounding, for example. - - This occurs and signals invalid-operation if an invalid context was - detected during an operation. This can occur if contexts are not checked - on creation and either the precision exceeds the capability of the - underlying concrete representation or an unknown or unsupported rounding - was specified. These aspects of the context need only be checked when - the values are required to be used. The result is [0,qNaN]. - """ - - def handle(self, context, *args): - return _NaN - -class Rounded(DecimalException): - """Number got rounded (not necessarily changed during rounding). - - This occurs and signals rounded whenever the result of an operation is - rounded (that is, some zero or non-zero digits were discarded from the - coefficient), or if an overflow or underflow condition occurs. The - result in all cases is unchanged. - - The rounded signal may be tested (or trapped) to determine if a given - operation (or sequence of operations) caused a loss of precision. - """ - -class Subnormal(DecimalException): - """Exponent < Emin before rounding. - - This occurs and signals subnormal whenever the result of a conversion or - operation is subnormal (that is, its adjusted exponent is less than - Emin, before any rounding). The result in all cases is unchanged. - - The subnormal signal may be tested (or trapped) to determine if a given - or operation (or sequence of operations) yielded a subnormal result. - """ - -class Overflow(Inexact, Rounded): - """Numerical overflow. - - This occurs and signals overflow if the adjusted exponent of a result - (from a conversion or from an operation that is not an attempt to divide - by zero), after rounding, would be greater than the largest value that - can be handled by the implementation (the value Emax). - - The result depends on the rounding mode: - - For round-half-up and round-half-even (and for round-half-down and - round-up, if implemented), the result of the operation is [sign,inf], - where sign is the sign of the intermediate result. For round-down, the - result is the largest finite number that can be represented in the - current precision, with the sign of the intermediate result. For - round-ceiling, the result is the same as for round-down if the sign of - the intermediate result is 1, or is [0,inf] otherwise. For round-floor, - the result is the same as for round-down if the sign of the intermediate - result is 0, or is [1,inf] otherwise. In all cases, Inexact and Rounded - will also be raised. - """ - - def handle(self, context, sign, *args): - if context.rounding in (ROUND_HALF_UP, ROUND_HALF_EVEN, - ROUND_HALF_DOWN, ROUND_UP): - return _SignedInfinity[sign] - if sign == 0: - if context.rounding == ROUND_CEILING: - return _SignedInfinity[sign] - return _dec_from_triple(sign, '9'*context.prec, - context.Emax-context.prec+1) - if sign == 1: - if context.rounding == ROUND_FLOOR: - return _SignedInfinity[sign] - return _dec_from_triple(sign, '9'*context.prec, - context.Emax-context.prec+1) - - -class Underflow(Inexact, Rounded, Subnormal): - """Numerical underflow with result rounded to 0. - - This occurs and signals underflow if a result is inexact and the - adjusted exponent of the result would be smaller (more negative) than - the smallest value that can be handled by the implementation (the value - Emin). That is, the result is both inexact and subnormal. - - The result after an underflow will be a subnormal number rounded, if - necessary, so that its exponent is not less than Etiny. This may result - in 0 with the sign of the intermediate result and an exponent of Etiny. - - In all cases, Inexact, Rounded, and Subnormal will also be raised. - """ - -class FloatOperation(DecimalException, TypeError): - """Enable stricter semantics for mixing floats and Decimals. - - If the signal is not trapped (default), mixing floats and Decimals is - permitted in the Decimal() constructor, context.create_decimal() and - all comparison operators. Both conversion and comparisons are exact. - Any occurrence of a mixed operation is silently recorded by setting - FloatOperation in the context flags. Explicit conversions with - Decimal.from_float() or context.create_decimal_from_float() do not - set the flag. - - Otherwise (the signal is trapped), only equality comparisons and explicit - conversions are silent. All other mixed operations raise FloatOperation. - """ - -# List of public traps and flags -_signals = [Clamped, DivisionByZero, Inexact, Overflow, Rounded, - Underflow, InvalidOperation, Subnormal, FloatOperation] - -# Map conditions (per the spec) to signals -_condition_map = {ConversionSyntax:InvalidOperation, - DivisionImpossible:InvalidOperation, - DivisionUndefined:InvalidOperation, - InvalidContext:InvalidOperation} - -# Valid rounding modes -_rounding_modes = (ROUND_DOWN, ROUND_HALF_UP, ROUND_HALF_EVEN, ROUND_CEILING, - ROUND_FLOOR, ROUND_UP, ROUND_HALF_DOWN, ROUND_05UP) - -##### Context Functions ################################################## - -# The getcontext() and setcontext() function manage access to a thread-local -# current context. Py2.4 offers direct support for thread locals. If that -# is not available, use threading.current_thread() which is slower but will -# work for older Pythons. If threads are not part of the build, create a -# mock threading object with threading.local() returning the module namespace. - -try: - import threading -except ImportError: - # Python was compiled without threads; create a mock object instead - class MockThreading(object): - def local(self, sys=sys): - return sys.modules[__name__] - threading = MockThreading() - del MockThreading - -try: - threading.local - -except AttributeError: - - # To fix reloading, force it to create a new context - # Old contexts have different exceptions in their dicts, making problems. - if hasattr(threading.current_thread(), '__decimal_context__'): - del threading.current_thread().__decimal_context__ - - def setcontext(context): - """Set this thread's context to context.""" - if context in (DefaultContext, BasicContext, ExtendedContext): - context = context.copy() - context.clear_flags() - threading.current_thread().__decimal_context__ = context - - def getcontext(): - """Returns this thread's context. - - If this thread does not yet have a context, returns - a new context and sets this thread's context. - New contexts are copies of DefaultContext. - """ - try: - return threading.current_thread().__decimal_context__ - except AttributeError: - context = Context() - threading.current_thread().__decimal_context__ = context - return context - -else: - - local = threading.local() - if hasattr(local, '__decimal_context__'): - del local.__decimal_context__ - - def getcontext(_local=local): - """Returns this thread's context. - - If this thread does not yet have a context, returns - a new context and sets this thread's context. - New contexts are copies of DefaultContext. - """ - try: - return _local.__decimal_context__ - except AttributeError: - context = Context() - _local.__decimal_context__ = context - return context - - def setcontext(context, _local=local): - """Set this thread's context to context.""" - if context in (DefaultContext, BasicContext, ExtendedContext): - context = context.copy() - context.clear_flags() - _local.__decimal_context__ = context - - del threading, local # Don't contaminate the namespace - -def localcontext(ctx=None): - """Return a context manager for a copy of the supplied context - - Uses a copy of the current context if no context is specified - The returned context manager creates a local decimal context - in a with statement: - def sin(x): - with localcontext() as ctx: - ctx.prec += 2 - # Rest of sin calculation algorithm - # uses a precision 2 greater than normal - return +s # Convert result to normal precision - - def sin(x): - with localcontext(ExtendedContext): - # Rest of sin calculation algorithm - # uses the Extended Context from the - # General Decimal Arithmetic Specification - return +s # Convert result to normal context - - >>> setcontext(DefaultContext) - >>> print(getcontext().prec) - 28 - >>> with localcontext(): - ... ctx = getcontext() - ... ctx.prec += 2 - ... print(ctx.prec) - ... - 30 - >>> with localcontext(ExtendedContext): - ... print(getcontext().prec) - ... - 9 - >>> print(getcontext().prec) - 28 - """ - if ctx is None: ctx = getcontext() - return _ContextManager(ctx) - - -##### Decimal class ####################################################### - -# Do not subclass Decimal from numbers.Real and do not register it as such -# (because Decimals are not interoperable with floats). See the notes in -# numbers.py for more detail. - -class Decimal(object): - """Floating point class for decimal arithmetic.""" - - __slots__ = ('_exp','_int','_sign', '_is_special') - # Generally, the value of the Decimal instance is given by - # (-1)**_sign * _int * 10**_exp - # Special values are signified by _is_special == True - - # We're immutable, so use __new__ not __init__ - def __new__(cls, value="0", context=None): - """Create a decimal point instance. - - >>> Decimal('3.14') # string input - Decimal('3.14') - >>> Decimal((0, (3, 1, 4), -2)) # tuple (sign, digit_tuple, exponent) - Decimal('3.14') - >>> Decimal(314) # int - Decimal('314') - >>> Decimal(Decimal(314)) # another decimal instance - Decimal('314') - >>> Decimal(' 3.14 \\n') # leading and trailing whitespace okay - Decimal('3.14') - """ - - # Note that the coefficient, self._int, is actually stored as - # a string rather than as a tuple of digits. This speeds up - # the "digits to integer" and "integer to digits" conversions - # that are used in almost every arithmetic operation on - # Decimals. This is an internal detail: the as_tuple function - # and the Decimal constructor still deal with tuples of - # digits. - - self = object.__new__(cls) - - # From a string - # REs insist on real strings, so we can too. - if isinstance(value, str): - m = _parser(value.strip()) - if m is None: - if context is None: - context = getcontext() - return context._raise_error(ConversionSyntax, - "Invalid literal for Decimal: %r" % value) - - if m.group('sign') == "-": - self._sign = 1 - else: - self._sign = 0 - intpart = m.group('int') - if intpart is not None: - # finite number - fracpart = m.group('frac') or '' - exp = int(m.group('exp') or '0') - self._int = str(int(intpart+fracpart)) - self._exp = exp - len(fracpart) - self._is_special = False - else: - diag = m.group('diag') - if diag is not None: - # NaN - self._int = str(int(diag or '0')).lstrip('0') - if m.group('signal'): - self._exp = 'N' - else: - self._exp = 'n' - else: - # infinity - self._int = '0' - self._exp = 'F' - self._is_special = True - return self - - # From an integer - if isinstance(value, int): - if value >= 0: - self._sign = 0 - else: - self._sign = 1 - self._exp = 0 - self._int = str(abs(value)) - self._is_special = False - return self - - # From another decimal - if isinstance(value, Decimal): - self._exp = value._exp - self._sign = value._sign - self._int = value._int - self._is_special = value._is_special - return self - - # From an internal working value - if isinstance(value, _WorkRep): - self._sign = value.sign - self._int = str(value.int) - self._exp = int(value.exp) - self._is_special = False - return self - - # tuple/list conversion (possibly from as_tuple()) - if isinstance(value, (list,tuple)): - if len(value) != 3: - raise ValueError('Invalid tuple size in creation of Decimal ' - 'from list or tuple. The list or tuple ' - 'should have exactly three elements.') - # process sign. The isinstance test rejects floats - if not (isinstance(value[0], int) and value[0] in (0,1)): - raise ValueError("Invalid sign. The first value in the tuple " - "should be an integer; either 0 for a " - "positive number or 1 for a negative number.") - self._sign = value[0] - if value[2] == 'F': - # infinity: value[1] is ignored - self._int = '0' - self._exp = value[2] - self._is_special = True - else: - # process and validate the digits in value[1] - digits = [] - for digit in value[1]: - if isinstance(digit, int) and 0 <= digit <= 9: - # skip leading zeros - if digits or digit != 0: - digits.append(digit) - else: - raise ValueError("The second value in the tuple must " - "be composed of integers in the range " - "0 through 9.") - if value[2] in ('n', 'N'): - # NaN: digits form the diagnostic - self._int = ''.join(map(str, digits)) - self._exp = value[2] - self._is_special = True - elif isinstance(value[2], int): - # finite number: digits give the coefficient - self._int = ''.join(map(str, digits or [0])) - self._exp = value[2] - self._is_special = False - else: - raise ValueError("The third value in the tuple must " - "be an integer, or one of the " - "strings 'F', 'n', 'N'.") - return self - - if isinstance(value, float): - if context is None: - context = getcontext() - context._raise_error(FloatOperation, - "strict semantics for mixing floats and Decimals are " - "enabled") - value = Decimal.from_float(value) - self._exp = value._exp - self._sign = value._sign - self._int = value._int - self._is_special = value._is_special - return self - - raise TypeError("Cannot convert %r to Decimal" % value) - - @classmethod - def from_float(cls, f): - """Converts a float to a decimal number, exactly. - - Note that Decimal.from_float(0.1) is not the same as Decimal('0.1'). - Since 0.1 is not exactly representable in binary floating point, the - value is stored as the nearest representable value which is - 0x1.999999999999ap-4. The exact equivalent of the value in decimal - is 0.1000000000000000055511151231257827021181583404541015625. - - >>> Decimal.from_float(0.1) - Decimal('0.1000000000000000055511151231257827021181583404541015625') - >>> Decimal.from_float(float('nan')) - Decimal('NaN') - >>> Decimal.from_float(float('inf')) - Decimal('Infinity') - >>> Decimal.from_float(-float('inf')) - Decimal('-Infinity') - >>> Decimal.from_float(-0.0) - Decimal('-0') - - """ - if isinstance(f, int): # handle integer inputs - return cls(f) - if not isinstance(f, float): - raise TypeError("argument must be int or float.") - if _math.isinf(f) or _math.isnan(f): - return cls(repr(f)) - if _math.copysign(1.0, f) == 1.0: - sign = 0 - else: - sign = 1 - n, d = abs(f).as_integer_ratio() - k = d.bit_length() - 1 - result = _dec_from_triple(sign, str(n*5**k), -k) - if cls is Decimal: - return result - else: - return cls(result) - - def _isnan(self): - """Returns whether the number is not actually one. - - 0 if a number - 1 if NaN - 2 if sNaN - """ - if self._is_special: - exp = self._exp - if exp == 'n': - return 1 - elif exp == 'N': - return 2 - return 0 - - def _isinfinity(self): - """Returns whether the number is infinite - - 0 if finite or not a number - 1 if +INF - -1 if -INF - """ - if self._exp == 'F': - if self._sign: - return -1 - return 1 - return 0 - - def _check_nans(self, other=None, context=None): - """Returns whether the number is not actually one. - - if self, other are sNaN, signal - if self, other are NaN return nan - return 0 - - Done before operations. - """ - - self_is_nan = self._isnan() - if other is None: - other_is_nan = False - else: - other_is_nan = other._isnan() - - if self_is_nan or other_is_nan: - if context is None: - context = getcontext() - - if self_is_nan == 2: - return context._raise_error(InvalidOperation, 'sNaN', - self) - if other_is_nan == 2: - return context._raise_error(InvalidOperation, 'sNaN', - other) - if self_is_nan: - return self._fix_nan(context) - - return other._fix_nan(context) - return 0 - - def _compare_check_nans(self, other, context): - """Version of _check_nans used for the signaling comparisons - compare_signal, __le__, __lt__, __ge__, __gt__. - - Signal InvalidOperation if either self or other is a (quiet - or signaling) NaN. Signaling NaNs take precedence over quiet - NaNs. - - Return 0 if neither operand is a NaN. - - """ - if context is None: - context = getcontext() - - if self._is_special or other._is_special: - if self.is_snan(): - return context._raise_error(InvalidOperation, - 'comparison involving sNaN', - self) - elif other.is_snan(): - return context._raise_error(InvalidOperation, - 'comparison involving sNaN', - other) - elif self.is_qnan(): - return context._raise_error(InvalidOperation, - 'comparison involving NaN', - self) - elif other.is_qnan(): - return context._raise_error(InvalidOperation, - 'comparison involving NaN', - other) - return 0 - - def __bool__(self): - """Return True if self is nonzero; otherwise return False. - - NaNs and infinities are considered nonzero. - """ - return self._is_special or self._int != '0' - - def _cmp(self, other): - """Compare the two non-NaN decimal instances self and other. - - Returns -1 if self < other, 0 if self == other and 1 - if self > other. This routine is for internal use only.""" - - if self._is_special or other._is_special: - self_inf = self._isinfinity() - other_inf = other._isinfinity() - if self_inf == other_inf: - return 0 - elif self_inf < other_inf: - return -1 - else: - return 1 - - # check for zeros; Decimal('0') == Decimal('-0') - if not self: - if not other: - return 0 - else: - return -((-1)**other._sign) - if not other: - return (-1)**self._sign - - # If different signs, neg one is less - if other._sign < self._sign: - return -1 - if self._sign < other._sign: - return 1 - - self_adjusted = self.adjusted() - other_adjusted = other.adjusted() - if self_adjusted == other_adjusted: - self_padded = self._int + '0'*(self._exp - other._exp) - other_padded = other._int + '0'*(other._exp - self._exp) - if self_padded == other_padded: - return 0 - elif self_padded < other_padded: - return -(-1)**self._sign - else: - return (-1)**self._sign - elif self_adjusted > other_adjusted: - return (-1)**self._sign - else: # self_adjusted < other_adjusted - return -((-1)**self._sign) - - # Note: The Decimal standard doesn't cover rich comparisons for - # Decimals. In particular, the specification is silent on the - # subject of what should happen for a comparison involving a NaN. - # We take the following approach: - # - # == comparisons involving a quiet NaN always return False - # != comparisons involving a quiet NaN always return True - # == or != comparisons involving a signaling NaN signal - # InvalidOperation, and return False or True as above if the - # InvalidOperation is not trapped. - # <, >, <= and >= comparisons involving a (quiet or signaling) - # NaN signal InvalidOperation, and return False if the - # InvalidOperation is not trapped. - # - # This behavior is designed to conform as closely as possible to - # that specified by IEEE 754. - - def __eq__(self, other, context=None): - self, other = _convert_for_comparison(self, other, equality_op=True) - if other is NotImplemented: - return other - if self._check_nans(other, context): - return False - return self._cmp(other) == 0 - - def __ne__(self, other, context=None): - self, other = _convert_for_comparison(self, other, equality_op=True) - if other is NotImplemented: - return other - if self._check_nans(other, context): - return True - return self._cmp(other) != 0 - - - def __lt__(self, other, context=None): - self, other = _convert_for_comparison(self, other) - if other is NotImplemented: - return other - ans = self._compare_check_nans(other, context) - if ans: - return False - return self._cmp(other) < 0 - - def __le__(self, other, context=None): - self, other = _convert_for_comparison(self, other) - if other is NotImplemented: - return other - ans = self._compare_check_nans(other, context) - if ans: - return False - return self._cmp(other) <= 0 - - def __gt__(self, other, context=None): - self, other = _convert_for_comparison(self, other) - if other is NotImplemented: - return other - ans = self._compare_check_nans(other, context) - if ans: - return False - return self._cmp(other) > 0 - - def __ge__(self, other, context=None): - self, other = _convert_for_comparison(self, other) - if other is NotImplemented: - return other - ans = self._compare_check_nans(other, context) - if ans: - return False - return self._cmp(other) >= 0 - - def compare(self, other, context=None): - """Compares one to another. - - -1 => a < b - 0 => a = b - 1 => a > b - NaN => one is NaN - Like __cmp__, but returns Decimal instances. - """ - other = _convert_other(other, raiseit=True) - - # Compare(NaN, NaN) = NaN - if (self._is_special or other and other._is_special): - ans = self._check_nans(other, context) - if ans: - return ans - - return Decimal(self._cmp(other)) - - def __hash__(self): - """x.__hash__() <==> hash(x)""" - - # In order to make sure that the hash of a Decimal instance - # agrees with the hash of a numerically equal integer, float - # or Fraction, we follow the rules for numeric hashes outlined - # in the documentation. (See library docs, 'Built-in Types'). - if self._is_special: - if self.is_snan(): - raise TypeError('Cannot hash a signaling NaN value.') - elif self.is_nan(): - return _PyHASH_NAN - else: - if self._sign: - return -_PyHASH_INF - else: - return _PyHASH_INF - - if self._exp >= 0: - exp_hash = pow(10, self._exp, _PyHASH_MODULUS) - else: - exp_hash = pow(_PyHASH_10INV, -self._exp, _PyHASH_MODULUS) - hash_ = int(self._int) * exp_hash % _PyHASH_MODULUS - ans = hash_ if self >= 0 else -hash_ - return -2 if ans == -1 else ans - - def as_tuple(self): - """Represents the number as a triple tuple. - - To show the internals exactly as they are. - """ - return DecimalTuple(self._sign, tuple(map(int, self._int)), self._exp) - - def __repr__(self): - """Represents the number as an instance of Decimal.""" - # Invariant: eval(repr(d)) == d - return "Decimal('%s')" % str(self) - - def __str__(self, eng=False, context=None): - """Return string representation of the number in scientific notation. - - Captures all of the information in the underlying representation. - """ - - sign = ['', '-'][self._sign] - if self._is_special: - if self._exp == 'F': - return sign + 'Infinity' - elif self._exp == 'n': - return sign + 'NaN' + self._int - else: # self._exp == 'N' - return sign + 'sNaN' + self._int - - # number of digits of self._int to left of decimal point - leftdigits = self._exp + len(self._int) - - # dotplace is number of digits of self._int to the left of the - # decimal point in the mantissa of the output string (that is, - # after adjusting the exponent) - if self._exp <= 0 and leftdigits > -6: - # no exponent required - dotplace = leftdigits - elif not eng: - # usual scientific notation: 1 digit on left of the point - dotplace = 1 - elif self._int == '0': - # engineering notation, zero - dotplace = (leftdigits + 1) % 3 - 1 - else: - # engineering notation, nonzero - dotplace = (leftdigits - 1) % 3 + 1 - - if dotplace <= 0: - intpart = '0' - fracpart = '.' + '0'*(-dotplace) + self._int - elif dotplace >= len(self._int): - intpart = self._int+'0'*(dotplace-len(self._int)) - fracpart = '' - else: - intpart = self._int[:dotplace] - fracpart = '.' + self._int[dotplace:] - if leftdigits == dotplace: - exp = '' - else: - if context is None: - context = getcontext() - exp = ['e', 'E'][context.capitals] + "%+d" % (leftdigits-dotplace) - - return sign + intpart + fracpart + exp - - def to_eng_string(self, context=None): - """Convert to engineering-type string. - - Engineering notation has an exponent which is a multiple of 3, so there - are up to 3 digits left of the decimal place. - - Same rules for when in exponential and when as a value as in __str__. - """ - return self.__str__(eng=True, context=context) - - def __neg__(self, context=None): - """Returns a copy with the sign switched. - - Rounds, if it has reason. - """ - if self._is_special: - ans = self._check_nans(context=context) - if ans: - return ans - - if context is None: - context = getcontext() - - if not self and context.rounding != ROUND_FLOOR: - # -Decimal('0') is Decimal('0'), not Decimal('-0'), except - # in ROUND_FLOOR rounding mode. - ans = self.copy_abs() - else: - ans = self.copy_negate() - - return ans._fix(context) - - def __pos__(self, context=None): - """Returns a copy, unless it is a sNaN. - - Rounds the number (if more then precision digits) - """ - if self._is_special: - ans = self._check_nans(context=context) - if ans: - return ans - - if context is None: - context = getcontext() - - if not self and context.rounding != ROUND_FLOOR: - # + (-0) = 0, except in ROUND_FLOOR rounding mode. - ans = self.copy_abs() - else: - ans = Decimal(self) - - return ans._fix(context) - - def __abs__(self, round=True, context=None): - """Returns the absolute value of self. - - If the keyword argument 'round' is false, do not round. The - expression self.__abs__(round=False) is equivalent to - self.copy_abs(). - """ - if not round: - return self.copy_abs() - - if self._is_special: - ans = self._check_nans(context=context) - if ans: - return ans - - if self._sign: - ans = self.__neg__(context=context) - else: - ans = self.__pos__(context=context) - - return ans - - def __add__(self, other, context=None): - """Returns self + other. - - -INF + INF (or the reverse) cause InvalidOperation errors. - """ - other = _convert_other(other) - if other is NotImplemented: - return other - - if context is None: - context = getcontext() - - if self._is_special or other._is_special: - ans = self._check_nans(other, context) - if ans: - return ans - - if self._isinfinity(): - # If both INF, same sign => same as both, opposite => error. - if self._sign != other._sign and other._isinfinity(): - return context._raise_error(InvalidOperation, '-INF + INF') - return Decimal(self) - if other._isinfinity(): - return Decimal(other) # Can't both be infinity here - - exp = min(self._exp, other._exp) - negativezero = 0 - if context.rounding == ROUND_FLOOR and self._sign != other._sign: - # If the answer is 0, the sign should be negative, in this case. - negativezero = 1 - - if not self and not other: - sign = min(self._sign, other._sign) - if negativezero: - sign = 1 - ans = _dec_from_triple(sign, '0', exp) - ans = ans._fix(context) - return ans - if not self: - exp = max(exp, other._exp - context.prec-1) - ans = other._rescale(exp, context.rounding) - ans = ans._fix(context) - return ans - if not other: - exp = max(exp, self._exp - context.prec-1) - ans = self._rescale(exp, context.rounding) - ans = ans._fix(context) - return ans - - op1 = _WorkRep(self) - op2 = _WorkRep(other) - op1, op2 = _normalize(op1, op2, context.prec) - - result = _WorkRep() - if op1.sign != op2.sign: - # Equal and opposite - if op1.int == op2.int: - ans = _dec_from_triple(negativezero, '0', exp) - ans = ans._fix(context) - return ans - if op1.int < op2.int: - op1, op2 = op2, op1 - # OK, now abs(op1) > abs(op2) - if op1.sign == 1: - result.sign = 1 - op1.sign, op2.sign = op2.sign, op1.sign - else: - result.sign = 0 - # So we know the sign, and op1 > 0. - elif op1.sign == 1: - result.sign = 1 - op1.sign, op2.sign = (0, 0) - else: - result.sign = 0 - # Now, op1 > abs(op2) > 0 - - if op2.sign == 0: - result.int = op1.int + op2.int - else: - result.int = op1.int - op2.int - - result.exp = op1.exp - ans = Decimal(result) - ans = ans._fix(context) - return ans - - __radd__ = __add__ - - def __sub__(self, other, context=None): - """Return self - other""" - other = _convert_other(other) - if other is NotImplemented: - return other - - if self._is_special or other._is_special: - ans = self._check_nans(other, context=context) - if ans: - return ans - - # self - other is computed as self + other.copy_negate() - return self.__add__(other.copy_negate(), context=context) - - def __rsub__(self, other, context=None): - """Return other - self""" - other = _convert_other(other) - if other is NotImplemented: - return other - - return other.__sub__(self, context=context) - - def __mul__(self, other, context=None): - """Return self * other. - - (+-) INF * 0 (or its reverse) raise InvalidOperation. - """ - other = _convert_other(other) - if other is NotImplemented: - return other - - if context is None: - context = getcontext() - - resultsign = self._sign ^ other._sign - - if self._is_special or other._is_special: - ans = self._check_nans(other, context) - if ans: - return ans - - if self._isinfinity(): - if not other: - return context._raise_error(InvalidOperation, '(+-)INF * 0') - return _SignedInfinity[resultsign] - - if other._isinfinity(): - if not self: - return context._raise_error(InvalidOperation, '0 * (+-)INF') - return _SignedInfinity[resultsign] - - resultexp = self._exp + other._exp - - # Special case for multiplying by zero - if not self or not other: - ans = _dec_from_triple(resultsign, '0', resultexp) - # Fixing in case the exponent is out of bounds - ans = ans._fix(context) - return ans - - # Special case for multiplying by power of 10 - if self._int == '1': - ans = _dec_from_triple(resultsign, other._int, resultexp) - ans = ans._fix(context) - return ans - if other._int == '1': - ans = _dec_from_triple(resultsign, self._int, resultexp) - ans = ans._fix(context) - return ans - - op1 = _WorkRep(self) - op2 = _WorkRep(other) - - ans = _dec_from_triple(resultsign, str(op1.int * op2.int), resultexp) - ans = ans._fix(context) - - return ans - __rmul__ = __mul__ - - def __truediv__(self, other, context=None): - """Return self / other.""" - other = _convert_other(other) - if other is NotImplemented: - return NotImplemented - - if context is None: - context = getcontext() - - sign = self._sign ^ other._sign - - if self._is_special or other._is_special: - ans = self._check_nans(other, context) - if ans: - return ans - - if self._isinfinity() and other._isinfinity(): - return context._raise_error(InvalidOperation, '(+-)INF/(+-)INF') - - if self._isinfinity(): - return _SignedInfinity[sign] - - if other._isinfinity(): - context._raise_error(Clamped, 'Division by infinity') - return _dec_from_triple(sign, '0', context.Etiny()) - - # Special cases for zeroes - if not other: - if not self: - return context._raise_error(DivisionUndefined, '0 / 0') - return context._raise_error(DivisionByZero, 'x / 0', sign) - - if not self: - exp = self._exp - other._exp - coeff = 0 - else: - # OK, so neither = 0, INF or NaN - shift = len(other._int) - len(self._int) + context.prec + 1 - exp = self._exp - other._exp - shift - op1 = _WorkRep(self) - op2 = _WorkRep(other) - if shift >= 0: - coeff, remainder = divmod(op1.int * 10**shift, op2.int) - else: - coeff, remainder = divmod(op1.int, op2.int * 10**-shift) - if remainder: - # result is not exact; adjust to ensure correct rounding - if coeff % 5 == 0: - coeff += 1 - else: - # result is exact; get as close to ideal exponent as possible - ideal_exp = self._exp - other._exp - while exp < ideal_exp and coeff % 10 == 0: - coeff //= 10 - exp += 1 - - ans = _dec_from_triple(sign, str(coeff), exp) - return ans._fix(context) - - def _divide(self, other, context): - """Return (self // other, self % other), to context.prec precision. - - Assumes that neither self nor other is a NaN, that self is not - infinite and that other is nonzero. - """ - sign = self._sign ^ other._sign - if other._isinfinity(): - ideal_exp = self._exp - else: - ideal_exp = min(self._exp, other._exp) - - expdiff = self.adjusted() - other.adjusted() - if not self or other._isinfinity() or expdiff <= -2: - return (_dec_from_triple(sign, '0', 0), - self._rescale(ideal_exp, context.rounding)) - if expdiff <= context.prec: - op1 = _WorkRep(self) - op2 = _WorkRep(other) - if op1.exp >= op2.exp: - op1.int *= 10**(op1.exp - op2.exp) - else: - op2.int *= 10**(op2.exp - op1.exp) - q, r = divmod(op1.int, op2.int) - if q < 10**context.prec: - return (_dec_from_triple(sign, str(q), 0), - _dec_from_triple(self._sign, str(r), ideal_exp)) - - # Here the quotient is too large to be representable - ans = context._raise_error(DivisionImpossible, - 'quotient too large in //, % or divmod') - return ans, ans - - def __rtruediv__(self, other, context=None): - """Swaps self/other and returns __truediv__.""" - other = _convert_other(other) - if other is NotImplemented: - return other - return other.__truediv__(self, context=context) - - def __divmod__(self, other, context=None): - """ - Return (self // other, self % other) - """ - other = _convert_other(other) - if other is NotImplemented: - return other - - if context is None: - context = getcontext() - - ans = self._check_nans(other, context) - if ans: - return (ans, ans) - - sign = self._sign ^ other._sign - if self._isinfinity(): - if other._isinfinity(): - ans = context._raise_error(InvalidOperation, 'divmod(INF, INF)') - return ans, ans - else: - return (_SignedInfinity[sign], - context._raise_error(InvalidOperation, 'INF % x')) - - if not other: - if not self: - ans = context._raise_error(DivisionUndefined, 'divmod(0, 0)') - return ans, ans - else: - return (context._raise_error(DivisionByZero, 'x // 0', sign), - context._raise_error(InvalidOperation, 'x % 0')) - - quotient, remainder = self._divide(other, context) - remainder = remainder._fix(context) - return quotient, remainder - - def __rdivmod__(self, other, context=None): - """Swaps self/other and returns __divmod__.""" - other = _convert_other(other) - if other is NotImplemented: - return other - return other.__divmod__(self, context=context) - - def __mod__(self, other, context=None): - """ - self % other - """ - other = _convert_other(other) - if other is NotImplemented: - return other - - if context is None: - context = getcontext() - - ans = self._check_nans(other, context) - if ans: - return ans - - if self._isinfinity(): - return context._raise_error(InvalidOperation, 'INF % x') - elif not other: - if self: - return context._raise_error(InvalidOperation, 'x % 0') - else: - return context._raise_error(DivisionUndefined, '0 % 0') - - remainder = self._divide(other, context)[1] - remainder = remainder._fix(context) - return remainder - - def __rmod__(self, other, context=None): - """Swaps self/other and returns __mod__.""" - other = _convert_other(other) - if other is NotImplemented: - return other - return other.__mod__(self, context=context) - - def remainder_near(self, other, context=None): - """ - Remainder nearest to 0- abs(remainder-near) <= other/2 - """ - if context is None: - context = getcontext() - - other = _convert_other(other, raiseit=True) - - ans = self._check_nans(other, context) - if ans: - return ans - - # self == +/-infinity -> InvalidOperation - if self._isinfinity(): - return context._raise_error(InvalidOperation, - 'remainder_near(infinity, x)') - - # other == 0 -> either InvalidOperation or DivisionUndefined - if not other: - if self: - return context._raise_error(InvalidOperation, - 'remainder_near(x, 0)') - else: - return context._raise_error(DivisionUndefined, - 'remainder_near(0, 0)') - - # other = +/-infinity -> remainder = self - if other._isinfinity(): - ans = Decimal(self) - return ans._fix(context) - - # self = 0 -> remainder = self, with ideal exponent - ideal_exponent = min(self._exp, other._exp) - if not self: - ans = _dec_from_triple(self._sign, '0', ideal_exponent) - return ans._fix(context) - - # catch most cases of large or small quotient - expdiff = self.adjusted() - other.adjusted() - if expdiff >= context.prec + 1: - # expdiff >= prec+1 => abs(self/other) > 10**prec - return context._raise_error(DivisionImpossible) - if expdiff <= -2: - # expdiff <= -2 => abs(self/other) < 0.1 - ans = self._rescale(ideal_exponent, context.rounding) - return ans._fix(context) - - # adjust both arguments to have the same exponent, then divide - op1 = _WorkRep(self) - op2 = _WorkRep(other) - if op1.exp >= op2.exp: - op1.int *= 10**(op1.exp - op2.exp) - else: - op2.int *= 10**(op2.exp - op1.exp) - q, r = divmod(op1.int, op2.int) - # remainder is r*10**ideal_exponent; other is +/-op2.int * - # 10**ideal_exponent. Apply correction to ensure that - # abs(remainder) <= abs(other)/2 - if 2*r + (q&1) > op2.int: - r -= op2.int - q += 1 - - if q >= 10**context.prec: - return context._raise_error(DivisionImpossible) - - # result has same sign as self unless r is negative - sign = self._sign - if r < 0: - sign = 1-sign - r = -r - - ans = _dec_from_triple(sign, str(r), ideal_exponent) - return ans._fix(context) - - def __floordiv__(self, other, context=None): - """self // other""" - other = _convert_other(other) - if other is NotImplemented: - return other - - if context is None: - context = getcontext() - - ans = self._check_nans(other, context) - if ans: - return ans - - if self._isinfinity(): - if other._isinfinity(): - return context._raise_error(InvalidOperation, 'INF // INF') - else: - return _SignedInfinity[self._sign ^ other._sign] - - if not other: - if self: - return context._raise_error(DivisionByZero, 'x // 0', - self._sign ^ other._sign) - else: - return context._raise_error(DivisionUndefined, '0 // 0') - - return self._divide(other, context)[0] - - def __rfloordiv__(self, other, context=None): - """Swaps self/other and returns __floordiv__.""" - other = _convert_other(other) - if other is NotImplemented: - return other - return other.__floordiv__(self, context=context) - - def __float__(self): - """Float representation.""" - if self._isnan(): - if self.is_snan(): - raise ValueError("Cannot convert signaling NaN to float") - s = "-nan" if self._sign else "nan" - else: - s = str(self) - return float(s) - - def __int__(self): - """Converts self to an int, truncating if necessary.""" - if self._is_special: - if self._isnan(): - raise ValueError("Cannot convert NaN to integer") - elif self._isinfinity(): - raise OverflowError("Cannot convert infinity to integer") - s = (-1)**self._sign - if self._exp >= 0: - return s*int(self._int)*10**self._exp - else: - return s*int(self._int[:self._exp] or '0') - - __trunc__ = __int__ - - def real(self): - return self - real = property(real) - - def imag(self): - return Decimal(0) - imag = property(imag) - - def conjugate(self): - return self - - def __complex__(self): - return complex(float(self)) - - def _fix_nan(self, context): - """Decapitate the payload of a NaN to fit the context""" - payload = self._int - - # maximum length of payload is precision if clamp=0, - # precision-1 if clamp=1. - max_payload_len = context.prec - context.clamp - if len(payload) > max_payload_len: - payload = payload[len(payload)-max_payload_len:].lstrip('0') - return _dec_from_triple(self._sign, payload, self._exp, True) - return Decimal(self) - - def _fix(self, context): - """Round if it is necessary to keep self within prec precision. - - Rounds and fixes the exponent. Does not raise on a sNaN. - - Arguments: - self - Decimal instance - context - context used. - """ - - if self._is_special: - if self._isnan(): - # decapitate payload if necessary - return self._fix_nan(context) - else: - # self is +/-Infinity; return unaltered - return Decimal(self) - - # if self is zero then exponent should be between Etiny and - # Emax if clamp==0, and between Etiny and Etop if clamp==1. - Etiny = context.Etiny() - Etop = context.Etop() - if not self: - exp_max = [context.Emax, Etop][context.clamp] - new_exp = min(max(self._exp, Etiny), exp_max) - if new_exp != self._exp: - context._raise_error(Clamped) - return _dec_from_triple(self._sign, '0', new_exp) - else: - return Decimal(self) - - # exp_min is the smallest allowable exponent of the result, - # equal to max(self.adjusted()-context.prec+1, Etiny) - exp_min = len(self._int) + self._exp - context.prec - if exp_min > Etop: - # overflow: exp_min > Etop iff self.adjusted() > Emax - ans = context._raise_error(Overflow, 'above Emax', self._sign) - context._raise_error(Inexact) - context._raise_error(Rounded) - return ans - - self_is_subnormal = exp_min < Etiny - if self_is_subnormal: - exp_min = Etiny - - # round if self has too many digits - if self._exp < exp_min: - digits = len(self._int) + self._exp - exp_min - if digits < 0: - self = _dec_from_triple(self._sign, '1', exp_min-1) - digits = 0 - rounding_method = self._pick_rounding_function[context.rounding] - changed = rounding_method(self, digits) - coeff = self._int[:digits] or '0' - if changed > 0: - coeff = str(int(coeff)+1) - if len(coeff) > context.prec: - coeff = coeff[:-1] - exp_min += 1 - - # check whether the rounding pushed the exponent out of range - if exp_min > Etop: - ans = context._raise_error(Overflow, 'above Emax', self._sign) - else: - ans = _dec_from_triple(self._sign, coeff, exp_min) - - # raise the appropriate signals, taking care to respect - # the precedence described in the specification - if changed and self_is_subnormal: - context._raise_error(Underflow) - if self_is_subnormal: - context._raise_error(Subnormal) - if changed: - context._raise_error(Inexact) - context._raise_error(Rounded) - if not ans: - # raise Clamped on underflow to 0 - context._raise_error(Clamped) - return ans - - if self_is_subnormal: - context._raise_error(Subnormal) - - # fold down if clamp == 1 and self has too few digits - if context.clamp == 1 and self._exp > Etop: - context._raise_error(Clamped) - self_padded = self._int + '0'*(self._exp - Etop) - return _dec_from_triple(self._sign, self_padded, Etop) - - # here self was representable to begin with; return unchanged - return Decimal(self) - - # for each of the rounding functions below: - # self is a finite, nonzero Decimal - # prec is an integer satisfying 0 <= prec < len(self._int) - # - # each function returns either -1, 0, or 1, as follows: - # 1 indicates that self should be rounded up (away from zero) - # 0 indicates that self should be truncated, and that all the - # digits to be truncated are zeros (so the value is unchanged) - # -1 indicates that there are nonzero digits to be truncated - - def _round_down(self, prec): - """Also known as round-towards-0, truncate.""" - if _all_zeros(self._int, prec): - return 0 - else: - return -1 - - def _round_up(self, prec): - """Rounds away from 0.""" - return -self._round_down(prec) - - def _round_half_up(self, prec): - """Rounds 5 up (away from 0)""" - if self._int[prec] in '56789': - return 1 - elif _all_zeros(self._int, prec): - return 0 - else: - return -1 - - def _round_half_down(self, prec): - """Round 5 down""" - if _exact_half(self._int, prec): - return -1 - else: - return self._round_half_up(prec) - - def _round_half_even(self, prec): - """Round 5 to even, rest to nearest.""" - if _exact_half(self._int, prec) and \ - (prec == 0 or self._int[prec-1] in '02468'): - return -1 - else: - return self._round_half_up(prec) - - def _round_ceiling(self, prec): - """Rounds up (not away from 0 if negative.)""" - if self._sign: - return self._round_down(prec) - else: - return -self._round_down(prec) - - def _round_floor(self, prec): - """Rounds down (not towards 0 if negative)""" - if not self._sign: - return self._round_down(prec) - else: - return -self._round_down(prec) - - def _round_05up(self, prec): - """Round down unless digit prec-1 is 0 or 5.""" - if prec and self._int[prec-1] not in '05': - return self._round_down(prec) - else: - return -self._round_down(prec) - - _pick_rounding_function = dict( - ROUND_DOWN = _round_down, - ROUND_UP = _round_up, - ROUND_HALF_UP = _round_half_up, - ROUND_HALF_DOWN = _round_half_down, - ROUND_HALF_EVEN = _round_half_even, - ROUND_CEILING = _round_ceiling, - ROUND_FLOOR = _round_floor, - ROUND_05UP = _round_05up, - ) - - def __round__(self, n=None): - """Round self to the nearest integer, or to a given precision. - - If only one argument is supplied, round a finite Decimal - instance self to the nearest integer. If self is infinite or - a NaN then a Python exception is raised. If self is finite - and lies exactly halfway between two integers then it is - rounded to the integer with even last digit. - - >>> round(Decimal('123.456')) - 123 - >>> round(Decimal('-456.789')) - -457 - >>> round(Decimal('-3.0')) - -3 - >>> round(Decimal('2.5')) - 2 - >>> round(Decimal('3.5')) - 4 - >>> round(Decimal('Inf')) - Traceback (most recent call last): - ... - OverflowError: cannot round an infinity - >>> round(Decimal('NaN')) - Traceback (most recent call last): - ... - ValueError: cannot round a NaN - - If a second argument n is supplied, self is rounded to n - decimal places using the rounding mode for the current - context. - - For an integer n, round(self, -n) is exactly equivalent to - self.quantize(Decimal('1En')). - - >>> round(Decimal('123.456'), 0) - Decimal('123') - >>> round(Decimal('123.456'), 2) - Decimal('123.46') - >>> round(Decimal('123.456'), -2) - Decimal('1E+2') - >>> round(Decimal('-Infinity'), 37) - Decimal('NaN') - >>> round(Decimal('sNaN123'), 0) - Decimal('NaN123') - - """ - if n is not None: - # two-argument form: use the equivalent quantize call - if not isinstance(n, int): - raise TypeError('Second argument to round should be integral') - exp = _dec_from_triple(0, '1', -n) - return self.quantize(exp) - - # one-argument form - if self._is_special: - if self.is_nan(): - raise ValueError("cannot round a NaN") - else: - raise OverflowError("cannot round an infinity") - return int(self._rescale(0, ROUND_HALF_EVEN)) - - def __floor__(self): - """Return the floor of self, as an integer. - - For a finite Decimal instance self, return the greatest - integer n such that n <= self. If self is infinite or a NaN - then a Python exception is raised. - - """ - if self._is_special: - if self.is_nan(): - raise ValueError("cannot round a NaN") - else: - raise OverflowError("cannot round an infinity") - return int(self._rescale(0, ROUND_FLOOR)) - - def __ceil__(self): - """Return the ceiling of self, as an integer. - - For a finite Decimal instance self, return the least integer n - such that n >= self. If self is infinite or a NaN then a - Python exception is raised. - - """ - if self._is_special: - if self.is_nan(): - raise ValueError("cannot round a NaN") - else: - raise OverflowError("cannot round an infinity") - return int(self._rescale(0, ROUND_CEILING)) - - def fma(self, other, third, context=None): - """Fused multiply-add. - - Returns self*other+third with no rounding of the intermediate - product self*other. - - self and other are multiplied together, with no rounding of - the result. The third operand is then added to the result, - and a single final rounding is performed. - """ - - other = _convert_other(other, raiseit=True) - third = _convert_other(third, raiseit=True) - - # compute product; raise InvalidOperation if either operand is - # a signaling NaN or if the product is zero times infinity. - if self._is_special or other._is_special: - if context is None: - context = getcontext() - if self._exp == 'N': - return context._raise_error(InvalidOperation, 'sNaN', self) - if other._exp == 'N': - return context._raise_error(InvalidOperation, 'sNaN', other) - if self._exp == 'n': - product = self - elif other._exp == 'n': - product = other - elif self._exp == 'F': - if not other: - return context._raise_error(InvalidOperation, - 'INF * 0 in fma') - product = _SignedInfinity[self._sign ^ other._sign] - elif other._exp == 'F': - if not self: - return context._raise_error(InvalidOperation, - '0 * INF in fma') - product = _SignedInfinity[self._sign ^ other._sign] - else: - product = _dec_from_triple(self._sign ^ other._sign, - str(int(self._int) * int(other._int)), - self._exp + other._exp) - - return product.__add__(third, context) - - def _power_modulo(self, other, modulo, context=None): - """Three argument version of __pow__""" - - other = _convert_other(other) - if other is NotImplemented: - return other - modulo = _convert_other(modulo) - if modulo is NotImplemented: - return modulo - - if context is None: - context = getcontext() - - # deal with NaNs: if there are any sNaNs then first one wins, - # (i.e. behaviour for NaNs is identical to that of fma) - self_is_nan = self._isnan() - other_is_nan = other._isnan() - modulo_is_nan = modulo._isnan() - if self_is_nan or other_is_nan or modulo_is_nan: - if self_is_nan == 2: - return context._raise_error(InvalidOperation, 'sNaN', - self) - if other_is_nan == 2: - return context._raise_error(InvalidOperation, 'sNaN', - other) - if modulo_is_nan == 2: - return context._raise_error(InvalidOperation, 'sNaN', - modulo) - if self_is_nan: - return self._fix_nan(context) - if other_is_nan: - return other._fix_nan(context) - return modulo._fix_nan(context) - - # check inputs: we apply same restrictions as Python's pow() - if not (self._isinteger() and - other._isinteger() and - modulo._isinteger()): - return context._raise_error(InvalidOperation, - 'pow() 3rd argument not allowed ' - 'unless all arguments are integers') - if other < 0: - return context._raise_error(InvalidOperation, - 'pow() 2nd argument cannot be ' - 'negative when 3rd argument specified') - if not modulo: - return context._raise_error(InvalidOperation, - 'pow() 3rd argument cannot be 0') - - # additional restriction for decimal: the modulus must be less - # than 10**prec in absolute value - if modulo.adjusted() >= context.prec: - return context._raise_error(InvalidOperation, - 'insufficient precision: pow() 3rd ' - 'argument must not have more than ' - 'precision digits') - - # define 0**0 == NaN, for consistency with two-argument pow - # (even though it hurts!) - if not other and not self: - return context._raise_error(InvalidOperation, - 'at least one of pow() 1st argument ' - 'and 2nd argument must be nonzero ;' - '0**0 is not defined') - - # compute sign of result - if other._iseven(): - sign = 0 - else: - sign = self._sign - - # convert modulo to a Python integer, and self and other to - # Decimal integers (i.e. force their exponents to be >= 0) - modulo = abs(int(modulo)) - base = _WorkRep(self.to_integral_value()) - exponent = _WorkRep(other.to_integral_value()) - - # compute result using integer pow() - base = (base.int % modulo * pow(10, base.exp, modulo)) % modulo - for i in range(exponent.exp): - base = pow(base, 10, modulo) - base = pow(base, exponent.int, modulo) - - return _dec_from_triple(sign, str(base), 0) - - def _power_exact(self, other, p): - """Attempt to compute self**other exactly. - - Given Decimals self and other and an integer p, attempt to - compute an exact result for the power self**other, with p - digits of precision. Return None if self**other is not - exactly representable in p digits. - - Assumes that elimination of special cases has already been - performed: self and other must both be nonspecial; self must - be positive and not numerically equal to 1; other must be - nonzero. For efficiency, other._exp should not be too large, - so that 10**abs(other._exp) is a feasible calculation.""" - - # In the comments below, we write x for the value of self and y for the - # value of other. Write x = xc*10**xe and abs(y) = yc*10**ye, with xc - # and yc positive integers not divisible by 10. - - # The main purpose of this method is to identify the *failure* - # of x**y to be exactly representable with as little effort as - # possible. So we look for cheap and easy tests that - # eliminate the possibility of x**y being exact. Only if all - # these tests are passed do we go on to actually compute x**y. - - # Here's the main idea. Express y as a rational number m/n, with m and - # n relatively prime and n>0. Then for x**y to be exactly - # representable (at *any* precision), xc must be the nth power of a - # positive integer and xe must be divisible by n. If y is negative - # then additionally xc must be a power of either 2 or 5, hence a power - # of 2**n or 5**n. - # - # There's a limit to how small |y| can be: if y=m/n as above - # then: - # - # (1) if xc != 1 then for the result to be representable we - # need xc**(1/n) >= 2, and hence also xc**|y| >= 2. So - # if |y| <= 1/nbits(xc) then xc < 2**nbits(xc) <= - # 2**(1/|y|), hence xc**|y| < 2 and the result is not - # representable. - # - # (2) if xe != 0, |xe|*(1/n) >= 1, so |xe|*|y| >= 1. Hence if - # |y| < 1/|xe| then the result is not representable. - # - # Note that since x is not equal to 1, at least one of (1) and - # (2) must apply. Now |y| < 1/nbits(xc) iff |yc|*nbits(xc) < - # 10**-ye iff len(str(|yc|*nbits(xc)) <= -ye. - # - # There's also a limit to how large y can be, at least if it's - # positive: the normalized result will have coefficient xc**y, - # so if it's representable then xc**y < 10**p, and y < - # p/log10(xc). Hence if y*log10(xc) >= p then the result is - # not exactly representable. - - # if len(str(abs(yc*xe)) <= -ye then abs(yc*xe) < 10**-ye, - # so |y| < 1/xe and the result is not representable. - # Similarly, len(str(abs(yc)*xc_bits)) <= -ye implies |y| - # < 1/nbits(xc). - - x = _WorkRep(self) - xc, xe = x.int, x.exp - while xc % 10 == 0: - xc //= 10 - xe += 1 - - y = _WorkRep(other) - yc, ye = y.int, y.exp - while yc % 10 == 0: - yc //= 10 - ye += 1 - - # case where xc == 1: result is 10**(xe*y), with xe*y - # required to be an integer - if xc == 1: - xe *= yc - # result is now 10**(xe * 10**ye); xe * 10**ye must be integral - while xe % 10 == 0: - xe //= 10 - ye += 1 - if ye < 0: - return None - exponent = xe * 10**ye - if y.sign == 1: - exponent = -exponent - # if other is a nonnegative integer, use ideal exponent - if other._isinteger() and other._sign == 0: - ideal_exponent = self._exp*int(other) - zeros = min(exponent-ideal_exponent, p-1) - else: - zeros = 0 - return _dec_from_triple(0, '1' + '0'*zeros, exponent-zeros) - - # case where y is negative: xc must be either a power - # of 2 or a power of 5. - if y.sign == 1: - last_digit = xc % 10 - if last_digit in (2,4,6,8): - # quick test for power of 2 - if xc & -xc != xc: - return None - # now xc is a power of 2; e is its exponent - e = _nbits(xc)-1 - - # We now have: - # - # x = 2**e * 10**xe, e > 0, and y < 0. - # - # The exact result is: - # - # x**y = 5**(-e*y) * 10**(e*y + xe*y) - # - # provided that both e*y and xe*y are integers. Note that if - # 5**(-e*y) >= 10**p, then the result can't be expressed - # exactly with p digits of precision. - # - # Using the above, we can guard against large values of ye. - # 93/65 is an upper bound for log(10)/log(5), so if - # - # ye >= len(str(93*p//65)) - # - # then - # - # -e*y >= -y >= 10**ye > 93*p/65 > p*log(10)/log(5), - # - # so 5**(-e*y) >= 10**p, and the coefficient of the result - # can't be expressed in p digits. - - # emax >= largest e such that 5**e < 10**p. - emax = p*93//65 - if ye >= len(str(emax)): - return None - - # Find -e*y and -xe*y; both must be integers - e = _decimal_lshift_exact(e * yc, ye) - xe = _decimal_lshift_exact(xe * yc, ye) - if e is None or xe is None: - return None - - if e > emax: - return None - xc = 5**e - - elif last_digit == 5: - # e >= log_5(xc) if xc is a power of 5; we have - # equality all the way up to xc=5**2658 - e = _nbits(xc)*28//65 - xc, remainder = divmod(5**e, xc) - if remainder: - return None - while xc % 5 == 0: - xc //= 5 - e -= 1 - - # Guard against large values of ye, using the same logic as in - # the 'xc is a power of 2' branch. 10/3 is an upper bound for - # log(10)/log(2). - emax = p*10//3 - if ye >= len(str(emax)): - return None - - e = _decimal_lshift_exact(e * yc, ye) - xe = _decimal_lshift_exact(xe * yc, ye) - if e is None or xe is None: - return None - - if e > emax: - return None - xc = 2**e - else: - return None - - if xc >= 10**p: - return None - xe = -e-xe - return _dec_from_triple(0, str(xc), xe) - - # now y is positive; find m and n such that y = m/n - if ye >= 0: - m, n = yc*10**ye, 1 - else: - if xe != 0 and len(str(abs(yc*xe))) <= -ye: - return None - xc_bits = _nbits(xc) - if xc != 1 and len(str(abs(yc)*xc_bits)) <= -ye: - return None - m, n = yc, 10**(-ye) - while m % 2 == n % 2 == 0: - m //= 2 - n //= 2 - while m % 5 == n % 5 == 0: - m //= 5 - n //= 5 - - # compute nth root of xc*10**xe - if n > 1: - # if 1 < xc < 2**n then xc isn't an nth power - if xc != 1 and xc_bits <= n: - return None - - xe, rem = divmod(xe, n) - if rem != 0: - return None - - # compute nth root of xc using Newton's method - a = 1 << -(-_nbits(xc)//n) # initial estimate - while True: - q, r = divmod(xc, a**(n-1)) - if a <= q: - break - else: - a = (a*(n-1) + q)//n - if not (a == q and r == 0): - return None - xc = a - - # now xc*10**xe is the nth root of the original xc*10**xe - # compute mth power of xc*10**xe - - # if m > p*100//_log10_lb(xc) then m > p/log10(xc), hence xc**m > - # 10**p and the result is not representable. - if xc > 1 and m > p*100//_log10_lb(xc): - return None - xc = xc**m - xe *= m - if xc > 10**p: - return None - - # by this point the result *is* exactly representable - # adjust the exponent to get as close as possible to the ideal - # exponent, if necessary - str_xc = str(xc) - if other._isinteger() and other._sign == 0: - ideal_exponent = self._exp*int(other) - zeros = min(xe-ideal_exponent, p-len(str_xc)) - else: - zeros = 0 - return _dec_from_triple(0, str_xc+'0'*zeros, xe-zeros) - - def __pow__(self, other, modulo=None, context=None): - """Return self ** other [ % modulo]. - - With two arguments, compute self**other. - - With three arguments, compute (self**other) % modulo. For the - three argument form, the following restrictions on the - arguments hold: - - - all three arguments must be integral - - other must be nonnegative - - either self or other (or both) must be nonzero - - modulo must be nonzero and must have at most p digits, - where p is the context precision. - - If any of these restrictions is violated the InvalidOperation - flag is raised. - - The result of pow(self, other, modulo) is identical to the - result that would be obtained by computing (self**other) % - modulo with unbounded precision, but is computed more - efficiently. It is always exact. - """ - - if modulo is not None: - return self._power_modulo(other, modulo, context) - - other = _convert_other(other) - if other is NotImplemented: - return other - - if context is None: - context = getcontext() - - # either argument is a NaN => result is NaN - ans = self._check_nans(other, context) - if ans: - return ans - - # 0**0 = NaN (!), x**0 = 1 for nonzero x (including +/-Infinity) - if not other: - if not self: - return context._raise_error(InvalidOperation, '0 ** 0') - else: - return _One - - # result has sign 1 iff self._sign is 1 and other is an odd integer - result_sign = 0 - if self._sign == 1: - if other._isinteger(): - if not other._iseven(): - result_sign = 1 - else: - # -ve**noninteger = NaN - # (-0)**noninteger = 0**noninteger - if self: - return context._raise_error(InvalidOperation, - 'x ** y with x negative and y not an integer') - # negate self, without doing any unwanted rounding - self = self.copy_negate() - - # 0**(+ve or Inf)= 0; 0**(-ve or -Inf) = Infinity - if not self: - if other._sign == 0: - return _dec_from_triple(result_sign, '0', 0) - else: - return _SignedInfinity[result_sign] - - # Inf**(+ve or Inf) = Inf; Inf**(-ve or -Inf) = 0 - if self._isinfinity(): - if other._sign == 0: - return _SignedInfinity[result_sign] - else: - return _dec_from_triple(result_sign, '0', 0) - - # 1**other = 1, but the choice of exponent and the flags - # depend on the exponent of self, and on whether other is a - # positive integer, a negative integer, or neither - if self == _One: - if other._isinteger(): - # exp = max(self._exp*max(int(other), 0), - # 1-context.prec) but evaluating int(other) directly - # is dangerous until we know other is small (other - # could be 1e999999999) - if other._sign == 1: - multiplier = 0 - elif other > context.prec: - multiplier = context.prec - else: - multiplier = int(other) - - exp = self._exp * multiplier - if exp < 1-context.prec: - exp = 1-context.prec - context._raise_error(Rounded) - else: - context._raise_error(Inexact) - context._raise_error(Rounded) - exp = 1-context.prec - - return _dec_from_triple(result_sign, '1'+'0'*-exp, exp) - - # compute adjusted exponent of self - self_adj = self.adjusted() - - # self ** infinity is infinity if self > 1, 0 if self < 1 - # self ** -infinity is infinity if self < 1, 0 if self > 1 - if other._isinfinity(): - if (other._sign == 0) == (self_adj < 0): - return _dec_from_triple(result_sign, '0', 0) - else: - return _SignedInfinity[result_sign] - - # from here on, the result always goes through the call - # to _fix at the end of this function. - ans = None - exact = False - - # crude test to catch cases of extreme overflow/underflow. If - # log10(self)*other >= 10**bound and bound >= len(str(Emax)) - # then 10**bound >= 10**len(str(Emax)) >= Emax+1 and hence - # self**other >= 10**(Emax+1), so overflow occurs. The test - # for underflow is similar. - bound = self._log10_exp_bound() + other.adjusted() - if (self_adj >= 0) == (other._sign == 0): - # self > 1 and other +ve, or self < 1 and other -ve - # possibility of overflow - if bound >= len(str(context.Emax)): - ans = _dec_from_triple(result_sign, '1', context.Emax+1) - else: - # self > 1 and other -ve, or self < 1 and other +ve - # possibility of underflow to 0 - Etiny = context.Etiny() - if bound >= len(str(-Etiny)): - ans = _dec_from_triple(result_sign, '1', Etiny-1) - - # try for an exact result with precision +1 - if ans is None: - ans = self._power_exact(other, context.prec + 1) - if ans is not None: - if result_sign == 1: - ans = _dec_from_triple(1, ans._int, ans._exp) - exact = True - - # usual case: inexact result, x**y computed directly as exp(y*log(x)) - if ans is None: - p = context.prec - x = _WorkRep(self) - xc, xe = x.int, x.exp - y = _WorkRep(other) - yc, ye = y.int, y.exp - if y.sign == 1: - yc = -yc - - # compute correctly rounded result: start with precision +3, - # then increase precision until result is unambiguously roundable - extra = 3 - while True: - coeff, exp = _dpower(xc, xe, yc, ye, p+extra) - if coeff % (5*10**(len(str(coeff))-p-1)): - break - extra += 3 - - ans = _dec_from_triple(result_sign, str(coeff), exp) - - # unlike exp, ln and log10, the power function respects the - # rounding mode; no need to switch to ROUND_HALF_EVEN here - - # There's a difficulty here when 'other' is not an integer and - # the result is exact. In this case, the specification - # requires that the Inexact flag be raised (in spite of - # exactness), but since the result is exact _fix won't do this - # for us. (Correspondingly, the Underflow signal should also - # be raised for subnormal results.) We can't directly raise - # these signals either before or after calling _fix, since - # that would violate the precedence for signals. So we wrap - # the ._fix call in a temporary context, and reraise - # afterwards. - if exact and not other._isinteger(): - # pad with zeros up to length context.prec+1 if necessary; this - # ensures that the Rounded signal will be raised. - if len(ans._int) <= context.prec: - expdiff = context.prec + 1 - len(ans._int) - ans = _dec_from_triple(ans._sign, ans._int+'0'*expdiff, - ans._exp-expdiff) - - # create a copy of the current context, with cleared flags/traps - newcontext = context.copy() - newcontext.clear_flags() - for exception in _signals: - newcontext.traps[exception] = 0 - - # round in the new context - ans = ans._fix(newcontext) - - # raise Inexact, and if necessary, Underflow - newcontext._raise_error(Inexact) - if newcontext.flags[Subnormal]: - newcontext._raise_error(Underflow) - - # propagate signals to the original context; _fix could - # have raised any of Overflow, Underflow, Subnormal, - # Inexact, Rounded, Clamped. Overflow needs the correct - # arguments. Note that the order of the exceptions is - # important here. - if newcontext.flags[Overflow]: - context._raise_error(Overflow, 'above Emax', ans._sign) - for exception in Underflow, Subnormal, Inexact, Rounded, Clamped: - if newcontext.flags[exception]: - context._raise_error(exception) - - else: - ans = ans._fix(context) - - return ans - - def __rpow__(self, other, context=None): - """Swaps self/other and returns __pow__.""" - other = _convert_other(other) - if other is NotImplemented: - return other - return other.__pow__(self, context=context) - - def normalize(self, context=None): - """Normalize- strip trailing 0s, change anything equal to 0 to 0e0""" - - if context is None: - context = getcontext() - - if self._is_special: - ans = self._check_nans(context=context) - if ans: - return ans - - dup = self._fix(context) - if dup._isinfinity(): - return dup - - if not dup: - return _dec_from_triple(dup._sign, '0', 0) - exp_max = [context.Emax, context.Etop()][context.clamp] - end = len(dup._int) - exp = dup._exp - while dup._int[end-1] == '0' and exp < exp_max: - exp += 1 - end -= 1 - return _dec_from_triple(dup._sign, dup._int[:end], exp) - - def quantize(self, exp, rounding=None, context=None, watchexp=True): - """Quantize self so its exponent is the same as that of exp. - - Similar to self._rescale(exp._exp) but with error checking. - """ - exp = _convert_other(exp, raiseit=True) - - if context is None: - context = getcontext() - if rounding is None: - rounding = context.rounding - - if self._is_special or exp._is_special: - ans = self._check_nans(exp, context) - if ans: - return ans - - if exp._isinfinity() or self._isinfinity(): - if exp._isinfinity() and self._isinfinity(): - return Decimal(self) # if both are inf, it is OK - return context._raise_error(InvalidOperation, - 'quantize with one INF') - - # if we're not watching exponents, do a simple rescale - if not watchexp: - ans = self._rescale(exp._exp, rounding) - # raise Inexact and Rounded where appropriate - if ans._exp > self._exp: - context._raise_error(Rounded) - if ans != self: - context._raise_error(Inexact) - return ans - - # exp._exp should be between Etiny and Emax - if not (context.Etiny() <= exp._exp <= context.Emax): - return context._raise_error(InvalidOperation, - 'target exponent out of bounds in quantize') - - if not self: - ans = _dec_from_triple(self._sign, '0', exp._exp) - return ans._fix(context) - - self_adjusted = self.adjusted() - if self_adjusted > context.Emax: - return context._raise_error(InvalidOperation, - 'exponent of quantize result too large for current context') - if self_adjusted - exp._exp + 1 > context.prec: - return context._raise_error(InvalidOperation, - 'quantize result has too many digits for current context') - - ans = self._rescale(exp._exp, rounding) - if ans.adjusted() > context.Emax: - return context._raise_error(InvalidOperation, - 'exponent of quantize result too large for current context') - if len(ans._int) > context.prec: - return context._raise_error(InvalidOperation, - 'quantize result has too many digits for current context') - - # raise appropriate flags - if ans and ans.adjusted() < context.Emin: - context._raise_error(Subnormal) - if ans._exp > self._exp: - if ans != self: - context._raise_error(Inexact) - context._raise_error(Rounded) - - # call to fix takes care of any necessary folddown, and - # signals Clamped if necessary - ans = ans._fix(context) - return ans - - def same_quantum(self, other, context=None): - """Return True if self and other have the same exponent; otherwise - return False. - - If either operand is a special value, the following rules are used: - * return True if both operands are infinities - * return True if both operands are NaNs - * otherwise, return False. - """ - other = _convert_other(other, raiseit=True) - if self._is_special or other._is_special: - return (self.is_nan() and other.is_nan() or - self.is_infinite() and other.is_infinite()) - return self._exp == other._exp - - def _rescale(self, exp, rounding): - """Rescale self so that the exponent is exp, either by padding with zeros - or by truncating digits, using the given rounding mode. - - Specials are returned without change. This operation is - quiet: it raises no flags, and uses no information from the - context. - - exp = exp to scale to (an integer) - rounding = rounding mode - """ - if self._is_special: - return Decimal(self) - if not self: - return _dec_from_triple(self._sign, '0', exp) - - if self._exp >= exp: - # pad answer with zeros if necessary - return _dec_from_triple(self._sign, - self._int + '0'*(self._exp - exp), exp) - - # too many digits; round and lose data. If self.adjusted() < - # exp-1, replace self by 10**(exp-1) before rounding - digits = len(self._int) + self._exp - exp - if digits < 0: - self = _dec_from_triple(self._sign, '1', exp-1) - digits = 0 - this_function = self._pick_rounding_function[rounding] - changed = this_function(self, digits) - coeff = self._int[:digits] or '0' - if changed == 1: - coeff = str(int(coeff)+1) - return _dec_from_triple(self._sign, coeff, exp) - - def _round(self, places, rounding): - """Round a nonzero, nonspecial Decimal to a fixed number of - significant figures, using the given rounding mode. - - Infinities, NaNs and zeros are returned unaltered. - - This operation is quiet: it raises no flags, and uses no - information from the context. - - """ - if places <= 0: - raise ValueError("argument should be at least 1 in _round") - if self._is_special or not self: - return Decimal(self) - ans = self._rescale(self.adjusted()+1-places, rounding) - # it can happen that the rescale alters the adjusted exponent; - # for example when rounding 99.97 to 3 significant figures. - # When this happens we end up with an extra 0 at the end of - # the number; a second rescale fixes this. - if ans.adjusted() != self.adjusted(): - ans = ans._rescale(ans.adjusted()+1-places, rounding) - return ans - - def to_integral_exact(self, rounding=None, context=None): - """Rounds to a nearby integer. - - If no rounding mode is specified, take the rounding mode from - the context. This method raises the Rounded and Inexact flags - when appropriate. - - See also: to_integral_value, which does exactly the same as - this method except that it doesn't raise Inexact or Rounded. - """ - if self._is_special: - ans = self._check_nans(context=context) - if ans: - return ans - return Decimal(self) - if self._exp >= 0: - return Decimal(self) - if not self: - return _dec_from_triple(self._sign, '0', 0) - if context is None: - context = getcontext() - if rounding is None: - rounding = context.rounding - ans = self._rescale(0, rounding) - if ans != self: - context._raise_error(Inexact) - context._raise_error(Rounded) - return ans - - def to_integral_value(self, rounding=None, context=None): - """Rounds to the nearest integer, without raising inexact, rounded.""" - if context is None: - context = getcontext() - if rounding is None: - rounding = context.rounding - if self._is_special: - ans = self._check_nans(context=context) - if ans: - return ans - return Decimal(self) - if self._exp >= 0: - return Decimal(self) - else: - return self._rescale(0, rounding) - - # the method name changed, but we provide also the old one, for compatibility - to_integral = to_integral_value - - def sqrt(self, context=None): - """Return the square root of self.""" - if context is None: - context = getcontext() - - if self._is_special: - ans = self._check_nans(context=context) - if ans: - return ans - - if self._isinfinity() and self._sign == 0: - return Decimal(self) - - if not self: - # exponent = self._exp // 2. sqrt(-0) = -0 - ans = _dec_from_triple(self._sign, '0', self._exp // 2) - return ans._fix(context) - - if self._sign == 1: - return context._raise_error(InvalidOperation, 'sqrt(-x), x > 0') - - # At this point self represents a positive number. Let p be - # the desired precision and express self in the form c*100**e - # with c a positive real number and e an integer, c and e - # being chosen so that 100**(p-1) <= c < 100**p. Then the - # (exact) square root of self is sqrt(c)*10**e, and 10**(p-1) - # <= sqrt(c) < 10**p, so the closest representable Decimal at - # precision p is n*10**e where n = round_half_even(sqrt(c)), - # the closest integer to sqrt(c) with the even integer chosen - # in the case of a tie. - # - # To ensure correct rounding in all cases, we use the - # following trick: we compute the square root to an extra - # place (precision p+1 instead of precision p), rounding down. - # Then, if the result is inexact and its last digit is 0 or 5, - # we increase the last digit to 1 or 6 respectively; if it's - # exact we leave the last digit alone. Now the final round to - # p places (or fewer in the case of underflow) will round - # correctly and raise the appropriate flags. - - # use an extra digit of precision - prec = context.prec+1 - - # write argument in the form c*100**e where e = self._exp//2 - # is the 'ideal' exponent, to be used if the square root is - # exactly representable. l is the number of 'digits' of c in - # base 100, so that 100**(l-1) <= c < 100**l. - op = _WorkRep(self) - e = op.exp >> 1 - if op.exp & 1: - c = op.int * 10 - l = (len(self._int) >> 1) + 1 - else: - c = op.int - l = len(self._int)+1 >> 1 - - # rescale so that c has exactly prec base 100 'digits' - shift = prec-l - if shift >= 0: - c *= 100**shift - exact = True - else: - c, remainder = divmod(c, 100**-shift) - exact = not remainder - e -= shift - - # find n = floor(sqrt(c)) using Newton's method - n = 10**prec - while True: - q = c//n - if n <= q: - break - else: - n = n + q >> 1 - exact = exact and n*n == c - - if exact: - # result is exact; rescale to use ideal exponent e - if shift >= 0: - # assert n % 10**shift == 0 - n //= 10**shift - else: - n *= 10**-shift - e += shift - else: - # result is not exact; fix last digit as described above - if n % 5 == 0: - n += 1 - - ans = _dec_from_triple(0, str(n), e) - - # round, and fit to current context - context = context._shallow_copy() - rounding = context._set_rounding(ROUND_HALF_EVEN) - ans = ans._fix(context) - context.rounding = rounding - - return ans - - def max(self, other, context=None): - """Returns the larger value. - - Like max(self, other) except if one is not a number, returns - NaN (and signals if one is sNaN). Also rounds. - """ - other = _convert_other(other, raiseit=True) - - if context is None: - context = getcontext() - - if self._is_special or other._is_special: - # If one operand is a quiet NaN and the other is number, then the - # number is always returned - sn = self._isnan() - on = other._isnan() - if sn or on: - if on == 1 and sn == 0: - return self._fix(context) - if sn == 1 and on == 0: - return other._fix(context) - return self._check_nans(other, context) - - c = self._cmp(other) - if c == 0: - # If both operands are finite and equal in numerical value - # then an ordering is applied: - # - # If the signs differ then max returns the operand with the - # positive sign and min returns the operand with the negative sign - # - # If the signs are the same then the exponent is used to select - # the result. This is exactly the ordering used in compare_total. - c = self.compare_total(other) - - if c == -1: - ans = other - else: - ans = self - - return ans._fix(context) - - def min(self, other, context=None): - """Returns the smaller value. - - Like min(self, other) except if one is not a number, returns - NaN (and signals if one is sNaN). Also rounds. - """ - other = _convert_other(other, raiseit=True) - - if context is None: - context = getcontext() - - if self._is_special or other._is_special: - # If one operand is a quiet NaN and the other is number, then the - # number is always returned - sn = self._isnan() - on = other._isnan() - if sn or on: - if on == 1 and sn == 0: - return self._fix(context) - if sn == 1 and on == 0: - return other._fix(context) - return self._check_nans(other, context) - - c = self._cmp(other) - if c == 0: - c = self.compare_total(other) - - if c == -1: - ans = self - else: - ans = other - - return ans._fix(context) - - def _isinteger(self): - """Returns whether self is an integer""" - if self._is_special: - return False - if self._exp >= 0: - return True - rest = self._int[self._exp:] - return rest == '0'*len(rest) - - def _iseven(self): - """Returns True if self is even. Assumes self is an integer.""" - if not self or self._exp > 0: - return True - return self._int[-1+self._exp] in '02468' - - def adjusted(self): - """Return the adjusted exponent of self""" - try: - return self._exp + len(self._int) - 1 - # If NaN or Infinity, self._exp is string - except TypeError: - return 0 - - def canonical(self): - """Returns the same Decimal object. - - As we do not have different encodings for the same number, the - received object already is in its canonical form. - """ - return self - - def compare_signal(self, other, context=None): - """Compares self to the other operand numerically. - - It's pretty much like compare(), but all NaNs signal, with signaling - NaNs taking precedence over quiet NaNs. - """ - other = _convert_other(other, raiseit = True) - ans = self._compare_check_nans(other, context) - if ans: - return ans - return self.compare(other, context=context) - - def compare_total(self, other, context=None): - """Compares self to other using the abstract representations. - - This is not like the standard compare, which use their numerical - value. Note that a total ordering is defined for all possible abstract - representations. - """ - other = _convert_other(other, raiseit=True) - - # if one is negative and the other is positive, it's easy - if self._sign and not other._sign: - return _NegativeOne - if not self._sign and other._sign: - return _One - sign = self._sign - - # let's handle both NaN types - self_nan = self._isnan() - other_nan = other._isnan() - if self_nan or other_nan: - if self_nan == other_nan: - # compare payloads as though they're integers - self_key = len(self._int), self._int - other_key = len(other._int), other._int - if self_key < other_key: - if sign: - return _One - else: - return _NegativeOne - if self_key > other_key: - if sign: - return _NegativeOne - else: - return _One - return _Zero - - if sign: - if self_nan == 1: - return _NegativeOne - if other_nan == 1: - return _One - if self_nan == 2: - return _NegativeOne - if other_nan == 2: - return _One - else: - if self_nan == 1: - return _One - if other_nan == 1: - return _NegativeOne - if self_nan == 2: - return _One - if other_nan == 2: - return _NegativeOne - - if self < other: - return _NegativeOne - if self > other: - return _One - - if self._exp < other._exp: - if sign: - return _One - else: - return _NegativeOne - if self._exp > other._exp: - if sign: - return _NegativeOne - else: - return _One - return _Zero - - - def compare_total_mag(self, other, context=None): - """Compares self to other using abstract repr., ignoring sign. - - Like compare_total, but with operand's sign ignored and assumed to be 0. - """ - other = _convert_other(other, raiseit=True) - - s = self.copy_abs() - o = other.copy_abs() - return s.compare_total(o) - - def copy_abs(self): - """Returns a copy with the sign set to 0. """ - return _dec_from_triple(0, self._int, self._exp, self._is_special) - - def copy_negate(self): - """Returns a copy with the sign inverted.""" - if self._sign: - return _dec_from_triple(0, self._int, self._exp, self._is_special) - else: - return _dec_from_triple(1, self._int, self._exp, self._is_special) - - def copy_sign(self, other, context=None): - """Returns self with the sign of other.""" - other = _convert_other(other, raiseit=True) - return _dec_from_triple(other._sign, self._int, - self._exp, self._is_special) - - def exp(self, context=None): - """Returns e ** self.""" - - if context is None: - context = getcontext() - - # exp(NaN) = NaN - ans = self._check_nans(context=context) - if ans: - return ans - - # exp(-Infinity) = 0 - if self._isinfinity() == -1: - return _Zero - - # exp(0) = 1 - if not self: - return _One - - # exp(Infinity) = Infinity - if self._isinfinity() == 1: - return Decimal(self) - - # the result is now guaranteed to be inexact (the true - # mathematical result is transcendental). There's no need to - # raise Rounded and Inexact here---they'll always be raised as - # a result of the call to _fix. - p = context.prec - adj = self.adjusted() - - # we only need to do any computation for quite a small range - # of adjusted exponents---for example, -29 <= adj <= 10 for - # the default context. For smaller exponent the result is - # indistinguishable from 1 at the given precision, while for - # larger exponent the result either overflows or underflows. - if self._sign == 0 and adj > len(str((context.Emax+1)*3)): - # overflow - ans = _dec_from_triple(0, '1', context.Emax+1) - elif self._sign == 1 and adj > len(str((-context.Etiny()+1)*3)): - # underflow to 0 - ans = _dec_from_triple(0, '1', context.Etiny()-1) - elif self._sign == 0 and adj < -p: - # p+1 digits; final round will raise correct flags - ans = _dec_from_triple(0, '1' + '0'*(p-1) + '1', -p) - elif self._sign == 1 and adj < -p-1: - # p+1 digits; final round will raise correct flags - ans = _dec_from_triple(0, '9'*(p+1), -p-1) - # general case - else: - op = _WorkRep(self) - c, e = op.int, op.exp - if op.sign == 1: - c = -c - - # compute correctly rounded result: increase precision by - # 3 digits at a time until we get an unambiguously - # roundable result - extra = 3 - while True: - coeff, exp = _dexp(c, e, p+extra) - if coeff % (5*10**(len(str(coeff))-p-1)): - break - extra += 3 - - ans = _dec_from_triple(0, str(coeff), exp) - - # at this stage, ans should round correctly with *any* - # rounding mode, not just with ROUND_HALF_EVEN - context = context._shallow_copy() - rounding = context._set_rounding(ROUND_HALF_EVEN) - ans = ans._fix(context) - context.rounding = rounding - - return ans - - def is_canonical(self): - """Return True if self is canonical; otherwise return False. - - Currently, the encoding of a Decimal instance is always - canonical, so this method returns True for any Decimal. - """ - return True - - def is_finite(self): - """Return True if self is finite; otherwise return False. - - A Decimal instance is considered finite if it is neither - infinite nor a NaN. - """ - return not self._is_special - - def is_infinite(self): - """Return True if self is infinite; otherwise return False.""" - return self._exp == 'F' - - def is_nan(self): - """Return True if self is a qNaN or sNaN; otherwise return False.""" - return self._exp in ('n', 'N') - - def is_normal(self, context=None): - """Return True if self is a normal number; otherwise return False.""" - if self._is_special or not self: - return False - if context is None: - context = getcontext() - return context.Emin <= self.adjusted() - - def is_qnan(self): - """Return True if self is a quiet NaN; otherwise return False.""" - return self._exp == 'n' - - def is_signed(self): - """Return True if self is negative; otherwise return False.""" - return self._sign == 1 - - def is_snan(self): - """Return True if self is a signaling NaN; otherwise return False.""" - return self._exp == 'N' - - def is_subnormal(self, context=None): - """Return True if self is subnormal; otherwise return False.""" - if self._is_special or not self: - return False - if context is None: - context = getcontext() - return self.adjusted() < context.Emin - - def is_zero(self): - """Return True if self is a zero; otherwise return False.""" - return not self._is_special and self._int == '0' - - def _ln_exp_bound(self): - """Compute a lower bound for the adjusted exponent of self.ln(). - In other words, compute r such that self.ln() >= 10**r. Assumes - that self is finite and positive and that self != 1. - """ - - # for 0.1 <= x <= 10 we use the inequalities 1-1/x <= ln(x) <= x-1 - adj = self._exp + len(self._int) - 1 - if adj >= 1: - # argument >= 10; we use 23/10 = 2.3 as a lower bound for ln(10) - return len(str(adj*23//10)) - 1 - if adj <= -2: - # argument <= 0.1 - return len(str((-1-adj)*23//10)) - 1 - op = _WorkRep(self) - c, e = op.int, op.exp - if adj == 0: - # 1 < self < 10 - num = str(c-10**-e) - den = str(c) - return len(num) - len(den) - (num < den) - # adj == -1, 0.1 <= self < 1 - return e + len(str(10**-e - c)) - 1 - - - def ln(self, context=None): - """Returns the natural (base e) logarithm of self.""" - - if context is None: - context = getcontext() - - # ln(NaN) = NaN - ans = self._check_nans(context=context) - if ans: - return ans - - # ln(0.0) == -Infinity - if not self: - return _NegativeInfinity - - # ln(Infinity) = Infinity - if self._isinfinity() == 1: - return _Infinity - - # ln(1.0) == 0.0 - if self == _One: - return _Zero - - # ln(negative) raises InvalidOperation - if self._sign == 1: - return context._raise_error(InvalidOperation, - 'ln of a negative value') - - # result is irrational, so necessarily inexact - op = _WorkRep(self) - c, e = op.int, op.exp - p = context.prec - - # correctly rounded result: repeatedly increase precision by 3 - # until we get an unambiguously roundable result - places = p - self._ln_exp_bound() + 2 # at least p+3 places - while True: - coeff = _dlog(c, e, places) - # assert len(str(abs(coeff)))-p >= 1 - if coeff % (5*10**(len(str(abs(coeff)))-p-1)): - break - places += 3 - ans = _dec_from_triple(int(coeff<0), str(abs(coeff)), -places) - - context = context._shallow_copy() - rounding = context._set_rounding(ROUND_HALF_EVEN) - ans = ans._fix(context) - context.rounding = rounding - return ans - - def _log10_exp_bound(self): - """Compute a lower bound for the adjusted exponent of self.log10(). - In other words, find r such that self.log10() >= 10**r. - Assumes that self is finite and positive and that self != 1. - """ - - # For x >= 10 or x < 0.1 we only need a bound on the integer - # part of log10(self), and this comes directly from the - # exponent of x. For 0.1 <= x <= 10 we use the inequalities - # 1-1/x <= log(x) <= x-1. If x > 1 we have |log10(x)| > - # (1-1/x)/2.31 > 0. If x < 1 then |log10(x)| > (1-x)/2.31 > 0 - - adj = self._exp + len(self._int) - 1 - if adj >= 1: - # self >= 10 - return len(str(adj))-1 - if adj <= -2: - # self < 0.1 - return len(str(-1-adj))-1 - op = _WorkRep(self) - c, e = op.int, op.exp - if adj == 0: - # 1 < self < 10 - num = str(c-10**-e) - den = str(231*c) - return len(num) - len(den) - (num < den) + 2 - # adj == -1, 0.1 <= self < 1 - num = str(10**-e-c) - return len(num) + e - (num < "231") - 1 - - def log10(self, context=None): - """Returns the base 10 logarithm of self.""" - - if context is None: - context = getcontext() - - # log10(NaN) = NaN - ans = self._check_nans(context=context) - if ans: - return ans - - # log10(0.0) == -Infinity - if not self: - return _NegativeInfinity - - # log10(Infinity) = Infinity - if self._isinfinity() == 1: - return _Infinity - - # log10(negative or -Infinity) raises InvalidOperation - if self._sign == 1: - return context._raise_error(InvalidOperation, - 'log10 of a negative value') - - # log10(10**n) = n - if self._int[0] == '1' and self._int[1:] == '0'*(len(self._int) - 1): - # answer may need rounding - ans = Decimal(self._exp + len(self._int) - 1) - else: - # result is irrational, so necessarily inexact - op = _WorkRep(self) - c, e = op.int, op.exp - p = context.prec - - # correctly rounded result: repeatedly increase precision - # until result is unambiguously roundable - places = p-self._log10_exp_bound()+2 - while True: - coeff = _dlog10(c, e, places) - # assert len(str(abs(coeff)))-p >= 1 - if coeff % (5*10**(len(str(abs(coeff)))-p-1)): - break - places += 3 - ans = _dec_from_triple(int(coeff<0), str(abs(coeff)), -places) - - context = context._shallow_copy() - rounding = context._set_rounding(ROUND_HALF_EVEN) - ans = ans._fix(context) - context.rounding = rounding - return ans - - def logb(self, context=None): - """ Returns the exponent of the magnitude of self's MSD. - - The result is the integer which is the exponent of the magnitude - of the most significant digit of self (as though it were truncated - to a single digit while maintaining the value of that digit and - without limiting the resulting exponent). - """ - # logb(NaN) = NaN - ans = self._check_nans(context=context) - if ans: - return ans - - if context is None: - context = getcontext() - - # logb(+/-Inf) = +Inf - if self._isinfinity(): - return _Infinity - - # logb(0) = -Inf, DivisionByZero - if not self: - return context._raise_error(DivisionByZero, 'logb(0)', 1) - - # otherwise, simply return the adjusted exponent of self, as a - # Decimal. Note that no attempt is made to fit the result - # into the current context. - ans = Decimal(self.adjusted()) - return ans._fix(context) - - def _islogical(self): - """Return True if self is a logical operand. - - For being logical, it must be a finite number with a sign of 0, - an exponent of 0, and a coefficient whose digits must all be - either 0 or 1. - """ - if self._sign != 0 or self._exp != 0: - return False - for dig in self._int: - if dig not in '01': - return False - return True - - def _fill_logical(self, context, opa, opb): - dif = context.prec - len(opa) - if dif > 0: - opa = '0'*dif + opa - elif dif < 0: - opa = opa[-context.prec:] - dif = context.prec - len(opb) - if dif > 0: - opb = '0'*dif + opb - elif dif < 0: - opb = opb[-context.prec:] - return opa, opb - - def logical_and(self, other, context=None): - """Applies an 'and' operation between self and other's digits.""" - if context is None: - context = getcontext() - - other = _convert_other(other, raiseit=True) - - if not self._islogical() or not other._islogical(): - return context._raise_error(InvalidOperation) - - # fill to context.prec - (opa, opb) = self._fill_logical(context, self._int, other._int) - - # make the operation, and clean starting zeroes - result = "".join([str(int(a)&int(b)) for a,b in zip(opa,opb)]) - return _dec_from_triple(0, result.lstrip('0') or '0', 0) - - def logical_invert(self, context=None): - """Invert all its digits.""" - if context is None: - context = getcontext() - return self.logical_xor(_dec_from_triple(0,'1'*context.prec,0), - context) - - def logical_or(self, other, context=None): - """Applies an 'or' operation between self and other's digits.""" - if context is None: - context = getcontext() - - other = _convert_other(other, raiseit=True) - - if not self._islogical() or not other._islogical(): - return context._raise_error(InvalidOperation) - - # fill to context.prec - (opa, opb) = self._fill_logical(context, self._int, other._int) - - # make the operation, and clean starting zeroes - result = "".join([str(int(a)|int(b)) for a,b in zip(opa,opb)]) - return _dec_from_triple(0, result.lstrip('0') or '0', 0) - - def logical_xor(self, other, context=None): - """Applies an 'xor' operation between self and other's digits.""" - if context is None: - context = getcontext() - - other = _convert_other(other, raiseit=True) - - if not self._islogical() or not other._islogical(): - return context._raise_error(InvalidOperation) - - # fill to context.prec - (opa, opb) = self._fill_logical(context, self._int, other._int) - - # make the operation, and clean starting zeroes - result = "".join([str(int(a)^int(b)) for a,b in zip(opa,opb)]) - return _dec_from_triple(0, result.lstrip('0') or '0', 0) - - def max_mag(self, other, context=None): - """Compares the values numerically with their sign ignored.""" - other = _convert_other(other, raiseit=True) - - if context is None: - context = getcontext() - - if self._is_special or other._is_special: - # If one operand is a quiet NaN and the other is number, then the - # number is always returned - sn = self._isnan() - on = other._isnan() - if sn or on: - if on == 1 and sn == 0: - return self._fix(context) - if sn == 1 and on == 0: - return other._fix(context) - return self._check_nans(other, context) - - c = self.copy_abs()._cmp(other.copy_abs()) - if c == 0: - c = self.compare_total(other) - - if c == -1: - ans = other - else: - ans = self - - return ans._fix(context) - - def min_mag(self, other, context=None): - """Compares the values numerically with their sign ignored.""" - other = _convert_other(other, raiseit=True) - - if context is None: - context = getcontext() - - if self._is_special or other._is_special: - # If one operand is a quiet NaN and the other is number, then the - # number is always returned - sn = self._isnan() - on = other._isnan() - if sn or on: - if on == 1 and sn == 0: - return self._fix(context) - if sn == 1 and on == 0: - return other._fix(context) - return self._check_nans(other, context) - - c = self.copy_abs()._cmp(other.copy_abs()) - if c == 0: - c = self.compare_total(other) - - if c == -1: - ans = self - else: - ans = other - - return ans._fix(context) - - def next_minus(self, context=None): - """Returns the largest representable number smaller than itself.""" - if context is None: - context = getcontext() - - ans = self._check_nans(context=context) - if ans: - return ans - - if self._isinfinity() == -1: - return _NegativeInfinity - if self._isinfinity() == 1: - return _dec_from_triple(0, '9'*context.prec, context.Etop()) - - context = context.copy() - context._set_rounding(ROUND_FLOOR) - context._ignore_all_flags() - new_self = self._fix(context) - if new_self != self: - return new_self - return self.__sub__(_dec_from_triple(0, '1', context.Etiny()-1), - context) - - def next_plus(self, context=None): - """Returns the smallest representable number larger than itself.""" - if context is None: - context = getcontext() - - ans = self._check_nans(context=context) - if ans: - return ans - - if self._isinfinity() == 1: - return _Infinity - if self._isinfinity() == -1: - return _dec_from_triple(1, '9'*context.prec, context.Etop()) - - context = context.copy() - context._set_rounding(ROUND_CEILING) - context._ignore_all_flags() - new_self = self._fix(context) - if new_self != self: - return new_self - return self.__add__(_dec_from_triple(0, '1', context.Etiny()-1), - context) - - def next_toward(self, other, context=None): - """Returns the number closest to self, in the direction towards other. - - The result is the closest representable number to self - (excluding self) that is in the direction towards other, - unless both have the same value. If the two operands are - numerically equal, then the result is a copy of self with the - sign set to be the same as the sign of other. - """ - other = _convert_other(other, raiseit=True) - - if context is None: - context = getcontext() - - ans = self._check_nans(other, context) - if ans: - return ans - - comparison = self._cmp(other) - if comparison == 0: - return self.copy_sign(other) - - if comparison == -1: - ans = self.next_plus(context) - else: # comparison == 1 - ans = self.next_minus(context) - - # decide which flags to raise using value of ans - if ans._isinfinity(): - context._raise_error(Overflow, - 'Infinite result from next_toward', - ans._sign) - context._raise_error(Inexact) - context._raise_error(Rounded) - elif ans.adjusted() < context.Emin: - context._raise_error(Underflow) - context._raise_error(Subnormal) - context._raise_error(Inexact) - context._raise_error(Rounded) - # if precision == 1 then we don't raise Clamped for a - # result 0E-Etiny. - if not ans: - context._raise_error(Clamped) - - return ans - - def number_class(self, context=None): - """Returns an indication of the class of self. - - The class is one of the following strings: - sNaN - NaN - -Infinity - -Normal - -Subnormal - -Zero - +Zero - +Subnormal - +Normal - +Infinity - """ - if self.is_snan(): - return "sNaN" - if self.is_qnan(): - return "NaN" - inf = self._isinfinity() - if inf == 1: - return "+Infinity" - if inf == -1: - return "-Infinity" - if self.is_zero(): - if self._sign: - return "-Zero" - else: - return "+Zero" - if context is None: - context = getcontext() - if self.is_subnormal(context=context): - if self._sign: - return "-Subnormal" - else: - return "+Subnormal" - # just a normal, regular, boring number, :) - if self._sign: - return "-Normal" - else: - return "+Normal" - - def radix(self): - """Just returns 10, as this is Decimal, :)""" - return Decimal(10) - - def rotate(self, other, context=None): - """Returns a rotated copy of self, value-of-other times.""" - if context is None: - context = getcontext() - - other = _convert_other(other, raiseit=True) - - ans = self._check_nans(other, context) - if ans: - return ans - - if other._exp != 0: - return context._raise_error(InvalidOperation) - if not (-context.prec <= int(other) <= context.prec): - return context._raise_error(InvalidOperation) - - if self._isinfinity(): - return Decimal(self) - - # get values, pad if necessary - torot = int(other) - rotdig = self._int - topad = context.prec - len(rotdig) - if topad > 0: - rotdig = '0'*topad + rotdig - elif topad < 0: - rotdig = rotdig[-topad:] - - # let's rotate! - rotated = rotdig[torot:] + rotdig[:torot] - return _dec_from_triple(self._sign, - rotated.lstrip('0') or '0', self._exp) - - def scaleb(self, other, context=None): - """Returns self operand after adding the second value to its exp.""" - if context is None: - context = getcontext() - - other = _convert_other(other, raiseit=True) - - ans = self._check_nans(other, context) - if ans: - return ans - - if other._exp != 0: - return context._raise_error(InvalidOperation) - liminf = -2 * (context.Emax + context.prec) - limsup = 2 * (context.Emax + context.prec) - if not (liminf <= int(other) <= limsup): - return context._raise_error(InvalidOperation) - - if self._isinfinity(): - return Decimal(self) - - d = _dec_from_triple(self._sign, self._int, self._exp + int(other)) - d = d._fix(context) - return d - - def shift(self, other, context=None): - """Returns a shifted copy of self, value-of-other times.""" - if context is None: - context = getcontext() - - other = _convert_other(other, raiseit=True) - - ans = self._check_nans(other, context) - if ans: - return ans - - if other._exp != 0: - return context._raise_error(InvalidOperation) - if not (-context.prec <= int(other) <= context.prec): - return context._raise_error(InvalidOperation) - - if self._isinfinity(): - return Decimal(self) - - # get values, pad if necessary - torot = int(other) - rotdig = self._int - topad = context.prec - len(rotdig) - if topad > 0: - rotdig = '0'*topad + rotdig - elif topad < 0: - rotdig = rotdig[-topad:] - - # let's shift! - if torot < 0: - shifted = rotdig[:torot] - else: - shifted = rotdig + '0'*torot - shifted = shifted[-context.prec:] - - return _dec_from_triple(self._sign, - shifted.lstrip('0') or '0', self._exp) - - # Support for pickling, copy, and deepcopy - def __reduce__(self): - return (self.__class__, (str(self),)) - - def __copy__(self): - if type(self) is Decimal: - return self # I'm immutable; therefore I am my own clone - return self.__class__(str(self)) - - def __deepcopy__(self, memo): - if type(self) is Decimal: - return self # My components are also immutable - return self.__class__(str(self)) - - # PEP 3101 support. the _localeconv keyword argument should be - # considered private: it's provided for ease of testing only. - def __format__(self, specifier, context=None, _localeconv=None): - """Format a Decimal instance according to the given specifier. - - The specifier should be a standard format specifier, with the - form described in PEP 3101. Formatting types 'e', 'E', 'f', - 'F', 'g', 'G', 'n' and '%' are supported. If the formatting - type is omitted it defaults to 'g' or 'G', depending on the - value of context.capitals. - """ - - # Note: PEP 3101 says that if the type is not present then - # there should be at least one digit after the decimal point. - # We take the liberty of ignoring this requirement for - # Decimal---it's presumably there to make sure that - # format(float, '') behaves similarly to str(float). - if context is None: - context = getcontext() - - spec = _parse_format_specifier(specifier, _localeconv=_localeconv) - - # special values don't care about the type or precision - if self._is_special: - sign = _format_sign(self._sign, spec) - body = str(self.copy_abs()) - return _format_align(sign, body, spec) - - # a type of None defaults to 'g' or 'G', depending on context - if spec['type'] is None: - spec['type'] = ['g', 'G'][context.capitals] - - # if type is '%', adjust exponent of self accordingly - if spec['type'] == '%': - self = _dec_from_triple(self._sign, self._int, self._exp+2) - - # round if necessary, taking rounding mode from the context - rounding = context.rounding - precision = spec['precision'] - if precision is not None: - if spec['type'] in 'eE': - self = self._round(precision+1, rounding) - elif spec['type'] in 'fF%': - self = self._rescale(-precision, rounding) - elif spec['type'] in 'gG' and len(self._int) > precision: - self = self._round(precision, rounding) - # special case: zeros with a positive exponent can't be - # represented in fixed point; rescale them to 0e0. - if not self and self._exp > 0 and spec['type'] in 'fF%': - self = self._rescale(0, rounding) - - # figure out placement of the decimal point - leftdigits = self._exp + len(self._int) - if spec['type'] in 'eE': - if not self and precision is not None: - dotplace = 1 - precision - else: - dotplace = 1 - elif spec['type'] in 'fF%': - dotplace = leftdigits - elif spec['type'] in 'gG': - if self._exp <= 0 and leftdigits > -6: - dotplace = leftdigits - else: - dotplace = 1 - - # find digits before and after decimal point, and get exponent - if dotplace < 0: - intpart = '0' - fracpart = '0'*(-dotplace) + self._int - elif dotplace > len(self._int): - intpart = self._int + '0'*(dotplace-len(self._int)) - fracpart = '' - else: - intpart = self._int[:dotplace] or '0' - fracpart = self._int[dotplace:] - exp = leftdigits-dotplace - - # done with the decimal-specific stuff; hand over the rest - # of the formatting to the _format_number function - return _format_number(self._sign, intpart, fracpart, exp, spec) - -def _dec_from_triple(sign, coefficient, exponent, special=False): - """Create a decimal instance directly, without any validation, - normalization (e.g. removal of leading zeros) or argument - conversion. - - This function is for *internal use only*. - """ - - self = object.__new__(Decimal) - self._sign = sign - self._int = coefficient - self._exp = exponent - self._is_special = special - - return self - -# Register Decimal as a kind of Number (an abstract base class). -# However, do not register it as Real (because Decimals are not -# interoperable with floats). -_numbers.Number.register(Decimal) - - -##### Context class ####################################################### - -class _ContextManager(object): - """Context manager class to support localcontext(). - - Sets a copy of the supplied context in __enter__() and restores - the previous decimal context in __exit__() - """ - def __init__(self, new_context): - self.new_context = new_context.copy() - def __enter__(self): - self.saved_context = getcontext() - setcontext(self.new_context) - return self.new_context - def __exit__(self, t, v, tb): - setcontext(self.saved_context) - -class Context(object): - """Contains the context for a Decimal instance. - - Contains: - prec - precision (for use in rounding, division, square roots..) - rounding - rounding type (how you round) - traps - If traps[exception] = 1, then the exception is - raised when it is caused. Otherwise, a value is - substituted in. - flags - When an exception is caused, flags[exception] is set. - (Whether or not the trap_enabler is set) - Should be reset by user of Decimal instance. - Emin - Minimum exponent - Emax - Maximum exponent - capitals - If 1, 1*10^1 is printed as 1E+1. - If 0, printed as 1e1 - clamp - If 1, change exponents if too high (Default 0) - """ - - def __init__(self, prec=None, rounding=None, Emin=None, Emax=None, - capitals=None, clamp=None, flags=None, traps=None, - _ignored_flags=None): - # Set defaults; for everything except flags and _ignored_flags, - # inherit from DefaultContext. - try: - dc = DefaultContext - except NameError: - pass - - self.prec = prec if prec is not None else dc.prec - self.rounding = rounding if rounding is not None else dc.rounding - self.Emin = Emin if Emin is not None else dc.Emin - self.Emax = Emax if Emax is not None else dc.Emax - self.capitals = capitals if capitals is not None else dc.capitals - self.clamp = clamp if clamp is not None else dc.clamp - - if _ignored_flags is None: - self._ignored_flags = [] - else: - self._ignored_flags = _ignored_flags - - if traps is None: - self.traps = dc.traps.copy() - elif not isinstance(traps, dict): - self.traps = dict((s, int(s in traps)) for s in _signals + traps) - else: - self.traps = traps - - if flags is None: - self.flags = dict.fromkeys(_signals, 0) - elif not isinstance(flags, dict): - self.flags = dict((s, int(s in flags)) for s in _signals + flags) - else: - self.flags = flags - - def _set_integer_check(self, name, value, vmin, vmax): - if not isinstance(value, int): - raise TypeError("%s must be an integer" % name) - if vmin == '-inf': - if value > vmax: - raise ValueError("%s must be in [%s, %d]. got: %s" % (name, vmin, vmax, value)) - elif vmax == 'inf': - if value < vmin: - raise ValueError("%s must be in [%d, %s]. got: %s" % (name, vmin, vmax, value)) - else: - if value < vmin or value > vmax: - raise ValueError("%s must be in [%d, %d]. got %s" % (name, vmin, vmax, value)) - return object.__setattr__(self, name, value) - - def _set_signal_dict(self, name, d): - if not isinstance(d, dict): - raise TypeError("%s must be a signal dict" % d) - for key in d: - if not key in _signals: - raise KeyError("%s is not a valid signal dict" % d) - for key in _signals: - if not key in d: - raise KeyError("%s is not a valid signal dict" % d) - return object.__setattr__(self, name, d) - - def __setattr__(self, name, value): - if name == 'prec': - return self._set_integer_check(name, value, 1, 'inf') - elif name == 'Emin': - return self._set_integer_check(name, value, '-inf', 0) - elif name == 'Emax': - return self._set_integer_check(name, value, 0, 'inf') - elif name == 'capitals': - return self._set_integer_check(name, value, 0, 1) - elif name == 'clamp': - return self._set_integer_check(name, value, 0, 1) - elif name == 'rounding': - if not value in _rounding_modes: - # raise TypeError even for strings to have consistency - # among various implementations. - raise TypeError("%s: invalid rounding mode" % value) - return object.__setattr__(self, name, value) - elif name == 'flags' or name == 'traps': - return self._set_signal_dict(name, value) - elif name == '_ignored_flags': - return object.__setattr__(self, name, value) - else: - raise AttributeError( - "'decimal.Context' object has no attribute '%s'" % name) - - def __delattr__(self, name): - raise AttributeError("%s cannot be deleted" % name) - - # Support for pickling, copy, and deepcopy - def __reduce__(self): - flags = [sig for sig, v in self.flags.items() if v] - traps = [sig for sig, v in self.traps.items() if v] - return (self.__class__, - (self.prec, self.rounding, self.Emin, self.Emax, - self.capitals, self.clamp, flags, traps)) - - def __repr__(self): - """Show the current context.""" - s = [] - s.append('Context(prec=%(prec)d, rounding=%(rounding)s, ' - 'Emin=%(Emin)d, Emax=%(Emax)d, capitals=%(capitals)d, ' - 'clamp=%(clamp)d' - % vars(self)) - names = [f.__name__ for f, v in self.flags.items() if v] - s.append('flags=[' + ', '.join(names) + ']') - names = [t.__name__ for t, v in self.traps.items() if v] - s.append('traps=[' + ', '.join(names) + ']') - return ', '.join(s) + ')' - - def clear_flags(self): - """Reset all flags to zero""" - for flag in self.flags: - self.flags[flag] = 0 - - def clear_traps(self): - """Reset all traps to zero""" - for flag in self.traps: - self.traps[flag] = 0 - - def _shallow_copy(self): - """Returns a shallow copy from self.""" - nc = Context(self.prec, self.rounding, self.Emin, self.Emax, - self.capitals, self.clamp, self.flags, self.traps, - self._ignored_flags) - return nc - - def copy(self): - """Returns a deep copy from self.""" - nc = Context(self.prec, self.rounding, self.Emin, self.Emax, - self.capitals, self.clamp, - self.flags.copy(), self.traps.copy(), - self._ignored_flags) - return nc - __copy__ = copy - - def _raise_error(self, condition, explanation = None, *args): - """Handles an error - - If the flag is in _ignored_flags, returns the default response. - Otherwise, it sets the flag, then, if the corresponding - trap_enabler is set, it reraises the exception. Otherwise, it returns - the default value after setting the flag. - """ - error = _condition_map.get(condition, condition) - if error in self._ignored_flags: - # Don't touch the flag - return error().handle(self, *args) - - self.flags[error] = 1 - if not self.traps[error]: - # The errors define how to handle themselves. - return condition().handle(self, *args) - - # Errors should only be risked on copies of the context - # self._ignored_flags = [] - raise error(explanation) - - def _ignore_all_flags(self): - """Ignore all flags, if they are raised""" - return self._ignore_flags(*_signals) - - def _ignore_flags(self, *flags): - """Ignore the flags, if they are raised""" - # Do not mutate-- This way, copies of a context leave the original - # alone. - self._ignored_flags = (self._ignored_flags + list(flags)) - return list(flags) - - def _regard_flags(self, *flags): - """Stop ignoring the flags, if they are raised""" - if flags and isinstance(flags[0], (tuple,list)): - flags = flags[0] - for flag in flags: - self._ignored_flags.remove(flag) - - # We inherit object.__hash__, so we must deny this explicitly - __hash__ = None - - def Etiny(self): - """Returns Etiny (= Emin - prec + 1)""" - return int(self.Emin - self.prec + 1) - - def Etop(self): - """Returns maximum exponent (= Emax - prec + 1)""" - return int(self.Emax - self.prec + 1) - - def _set_rounding(self, type): - """Sets the rounding type. - - Sets the rounding type, and returns the current (previous) - rounding type. Often used like: - - context = context.copy() - # so you don't change the calling context - # if an error occurs in the middle. - rounding = context._set_rounding(ROUND_UP) - val = self.__sub__(other, context=context) - context._set_rounding(rounding) - - This will make it round up for that operation. - """ - rounding = self.rounding - self.rounding= type - return rounding - - def create_decimal(self, num='0'): - """Creates a new Decimal instance but using self as context. - - This method implements the to-number operation of the - IBM Decimal specification.""" - - if isinstance(num, str) and num != num.strip(): - return self._raise_error(ConversionSyntax, - "no trailing or leading whitespace is " - "permitted.") - - d = Decimal(num, context=self) - if d._isnan() and len(d._int) > self.prec - self.clamp: - return self._raise_error(ConversionSyntax, - "diagnostic info too long in NaN") - return d._fix(self) - - def create_decimal_from_float(self, f): - """Creates a new Decimal instance from a float but rounding using self - as the context. - - >>> context = Context(prec=5, rounding=ROUND_DOWN) - >>> context.create_decimal_from_float(3.1415926535897932) - Decimal('3.1415') - >>> context = Context(prec=5, traps=[Inexact]) - >>> context.create_decimal_from_float(3.1415926535897932) - Traceback (most recent call last): - ... - decimal.Inexact: None - - """ - d = Decimal.from_float(f) # An exact conversion - return d._fix(self) # Apply the context rounding - - # Methods - def abs(self, a): - """Returns the absolute value of the operand. - - If the operand is negative, the result is the same as using the minus - operation on the operand. Otherwise, the result is the same as using - the plus operation on the operand. - - >>> ExtendedContext.abs(Decimal('2.1')) - Decimal('2.1') - >>> ExtendedContext.abs(Decimal('-100')) - Decimal('100') - >>> ExtendedContext.abs(Decimal('101.5')) - Decimal('101.5') - >>> ExtendedContext.abs(Decimal('-101.5')) - Decimal('101.5') - >>> ExtendedContext.abs(-1) - Decimal('1') - """ - a = _convert_other(a, raiseit=True) - return a.__abs__(context=self) - - def add(self, a, b): - """Return the sum of the two operands. - - >>> ExtendedContext.add(Decimal('12'), Decimal('7.00')) - Decimal('19.00') - >>> ExtendedContext.add(Decimal('1E+2'), Decimal('1.01E+4')) - Decimal('1.02E+4') - >>> ExtendedContext.add(1, Decimal(2)) - Decimal('3') - >>> ExtendedContext.add(Decimal(8), 5) - Decimal('13') - >>> ExtendedContext.add(5, 5) - Decimal('10') - """ - a = _convert_other(a, raiseit=True) - r = a.__add__(b, context=self) - if r is NotImplemented: - raise TypeError("Unable to convert %s to Decimal" % b) - else: - return r - - def _apply(self, a): - return str(a._fix(self)) - - def canonical(self, a): - """Returns the same Decimal object. - - As we do not have different encodings for the same number, the - received object already is in its canonical form. - - >>> ExtendedContext.canonical(Decimal('2.50')) - Decimal('2.50') - """ - if not isinstance(a, Decimal): - raise TypeError("canonical requires a Decimal as an argument.") - return a.canonical() - - def compare(self, a, b): - """Compares values numerically. - - If the signs of the operands differ, a value representing each operand - ('-1' if the operand is less than zero, '0' if the operand is zero or - negative zero, or '1' if the operand is greater than zero) is used in - place of that operand for the comparison instead of the actual - operand. - - The comparison is then effected by subtracting the second operand from - the first and then returning a value according to the result of the - subtraction: '-1' if the result is less than zero, '0' if the result is - zero or negative zero, or '1' if the result is greater than zero. - - >>> ExtendedContext.compare(Decimal('2.1'), Decimal('3')) - Decimal('-1') - >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.1')) - Decimal('0') - >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.10')) - Decimal('0') - >>> ExtendedContext.compare(Decimal('3'), Decimal('2.1')) - Decimal('1') - >>> ExtendedContext.compare(Decimal('2.1'), Decimal('-3')) - Decimal('1') - >>> ExtendedContext.compare(Decimal('-3'), Decimal('2.1')) - Decimal('-1') - >>> ExtendedContext.compare(1, 2) - Decimal('-1') - >>> ExtendedContext.compare(Decimal(1), 2) - Decimal('-1') - >>> ExtendedContext.compare(1, Decimal(2)) - Decimal('-1') - """ - a = _convert_other(a, raiseit=True) - return a.compare(b, context=self) - - def compare_signal(self, a, b): - """Compares the values of the two operands numerically. - - It's pretty much like compare(), but all NaNs signal, with signaling - NaNs taking precedence over quiet NaNs. - - >>> c = ExtendedContext - >>> c.compare_signal(Decimal('2.1'), Decimal('3')) - Decimal('-1') - >>> c.compare_signal(Decimal('2.1'), Decimal('2.1')) - Decimal('0') - >>> c.flags[InvalidOperation] = 0 - >>> print(c.flags[InvalidOperation]) - 0 - >>> c.compare_signal(Decimal('NaN'), Decimal('2.1')) - Decimal('NaN') - >>> print(c.flags[InvalidOperation]) - 1 - >>> c.flags[InvalidOperation] = 0 - >>> print(c.flags[InvalidOperation]) - 0 - >>> c.compare_signal(Decimal('sNaN'), Decimal('2.1')) - Decimal('NaN') - >>> print(c.flags[InvalidOperation]) - 1 - >>> c.compare_signal(-1, 2) - Decimal('-1') - >>> c.compare_signal(Decimal(-1), 2) - Decimal('-1') - >>> c.compare_signal(-1, Decimal(2)) - Decimal('-1') - """ - a = _convert_other(a, raiseit=True) - return a.compare_signal(b, context=self) - - def compare_total(self, a, b): - """Compares two operands using their abstract representation. - - This is not like the standard compare, which use their numerical - value. Note that a total ordering is defined for all possible abstract - representations. - - >>> ExtendedContext.compare_total(Decimal('12.73'), Decimal('127.9')) - Decimal('-1') - >>> ExtendedContext.compare_total(Decimal('-127'), Decimal('12')) - Decimal('-1') - >>> ExtendedContext.compare_total(Decimal('12.30'), Decimal('12.3')) - Decimal('-1') - >>> ExtendedContext.compare_total(Decimal('12.30'), Decimal('12.30')) - Decimal('0') - >>> ExtendedContext.compare_total(Decimal('12.3'), Decimal('12.300')) - Decimal('1') - >>> ExtendedContext.compare_total(Decimal('12.3'), Decimal('NaN')) - Decimal('-1') - >>> ExtendedContext.compare_total(1, 2) - Decimal('-1') - >>> ExtendedContext.compare_total(Decimal(1), 2) - Decimal('-1') - >>> ExtendedContext.compare_total(1, Decimal(2)) - Decimal('-1') - """ - a = _convert_other(a, raiseit=True) - return a.compare_total(b) - - def compare_total_mag(self, a, b): - """Compares two operands using their abstract representation ignoring sign. - - Like compare_total, but with operand's sign ignored and assumed to be 0. - """ - a = _convert_other(a, raiseit=True) - return a.compare_total_mag(b) - - def copy_abs(self, a): - """Returns a copy of the operand with the sign set to 0. - - >>> ExtendedContext.copy_abs(Decimal('2.1')) - Decimal('2.1') - >>> ExtendedContext.copy_abs(Decimal('-100')) - Decimal('100') - >>> ExtendedContext.copy_abs(-1) - Decimal('1') - """ - a = _convert_other(a, raiseit=True) - return a.copy_abs() - - def copy_decimal(self, a): - """Returns a copy of the decimal object. - - >>> ExtendedContext.copy_decimal(Decimal('2.1')) - Decimal('2.1') - >>> ExtendedContext.copy_decimal(Decimal('-1.00')) - Decimal('-1.00') - >>> ExtendedContext.copy_decimal(1) - Decimal('1') - """ - a = _convert_other(a, raiseit=True) - return Decimal(a) - - def copy_negate(self, a): - """Returns a copy of the operand with the sign inverted. - - >>> ExtendedContext.copy_negate(Decimal('101.5')) - Decimal('-101.5') - >>> ExtendedContext.copy_negate(Decimal('-101.5')) - Decimal('101.5') - >>> ExtendedContext.copy_negate(1) - Decimal('-1') - """ - a = _convert_other(a, raiseit=True) - return a.copy_negate() - - def copy_sign(self, a, b): - """Copies the second operand's sign to the first one. - - In detail, it returns a copy of the first operand with the sign - equal to the sign of the second operand. - - >>> ExtendedContext.copy_sign(Decimal( '1.50'), Decimal('7.33')) - Decimal('1.50') - >>> ExtendedContext.copy_sign(Decimal('-1.50'), Decimal('7.33')) - Decimal('1.50') - >>> ExtendedContext.copy_sign(Decimal( '1.50'), Decimal('-7.33')) - Decimal('-1.50') - >>> ExtendedContext.copy_sign(Decimal('-1.50'), Decimal('-7.33')) - Decimal('-1.50') - >>> ExtendedContext.copy_sign(1, -2) - Decimal('-1') - >>> ExtendedContext.copy_sign(Decimal(1), -2) - Decimal('-1') - >>> ExtendedContext.copy_sign(1, Decimal(-2)) - Decimal('-1') - """ - a = _convert_other(a, raiseit=True) - return a.copy_sign(b) - - def divide(self, a, b): - """Decimal division in a specified context. - - >>> ExtendedContext.divide(Decimal('1'), Decimal('3')) - Decimal('0.333333333') - >>> ExtendedContext.divide(Decimal('2'), Decimal('3')) - Decimal('0.666666667') - >>> ExtendedContext.divide(Decimal('5'), Decimal('2')) - Decimal('2.5') - >>> ExtendedContext.divide(Decimal('1'), Decimal('10')) - Decimal('0.1') - >>> ExtendedContext.divide(Decimal('12'), Decimal('12')) - Decimal('1') - >>> ExtendedContext.divide(Decimal('8.00'), Decimal('2')) - Decimal('4.00') - >>> ExtendedContext.divide(Decimal('2.400'), Decimal('2.0')) - Decimal('1.20') - >>> ExtendedContext.divide(Decimal('1000'), Decimal('100')) - Decimal('10') - >>> ExtendedContext.divide(Decimal('1000'), Decimal('1')) - Decimal('1000') - >>> ExtendedContext.divide(Decimal('2.40E+6'), Decimal('2')) - Decimal('1.20E+6') - >>> ExtendedContext.divide(5, 5) - Decimal('1') - >>> ExtendedContext.divide(Decimal(5), 5) - Decimal('1') - >>> ExtendedContext.divide(5, Decimal(5)) - Decimal('1') - """ - a = _convert_other(a, raiseit=True) - r = a.__truediv__(b, context=self) - if r is NotImplemented: - raise TypeError("Unable to convert %s to Decimal" % b) - else: - return r - - def divide_int(self, a, b): - """Divides two numbers and returns the integer part of the result. - - >>> ExtendedContext.divide_int(Decimal('2'), Decimal('3')) - Decimal('0') - >>> ExtendedContext.divide_int(Decimal('10'), Decimal('3')) - Decimal('3') - >>> ExtendedContext.divide_int(Decimal('1'), Decimal('0.3')) - Decimal('3') - >>> ExtendedContext.divide_int(10, 3) - Decimal('3') - >>> ExtendedContext.divide_int(Decimal(10), 3) - Decimal('3') - >>> ExtendedContext.divide_int(10, Decimal(3)) - Decimal('3') - """ - a = _convert_other(a, raiseit=True) - r = a.__floordiv__(b, context=self) - if r is NotImplemented: - raise TypeError("Unable to convert %s to Decimal" % b) - else: - return r - - def divmod(self, a, b): - """Return (a // b, a % b). - - >>> ExtendedContext.divmod(Decimal(8), Decimal(3)) - (Decimal('2'), Decimal('2')) - >>> ExtendedContext.divmod(Decimal(8), Decimal(4)) - (Decimal('2'), Decimal('0')) - >>> ExtendedContext.divmod(8, 4) - (Decimal('2'), Decimal('0')) - >>> ExtendedContext.divmod(Decimal(8), 4) - (Decimal('2'), Decimal('0')) - >>> ExtendedContext.divmod(8, Decimal(4)) - (Decimal('2'), Decimal('0')) - """ - a = _convert_other(a, raiseit=True) - r = a.__divmod__(b, context=self) - if r is NotImplemented: - raise TypeError("Unable to convert %s to Decimal" % b) - else: - return r - - def exp(self, a): - """Returns e ** a. - - >>> c = ExtendedContext.copy() - >>> c.Emin = -999 - >>> c.Emax = 999 - >>> c.exp(Decimal('-Infinity')) - Decimal('0') - >>> c.exp(Decimal('-1')) - Decimal('0.367879441') - >>> c.exp(Decimal('0')) - Decimal('1') - >>> c.exp(Decimal('1')) - Decimal('2.71828183') - >>> c.exp(Decimal('0.693147181')) - Decimal('2.00000000') - >>> c.exp(Decimal('+Infinity')) - Decimal('Infinity') - >>> c.exp(10) - Decimal('22026.4658') - """ - a =_convert_other(a, raiseit=True) - return a.exp(context=self) - - def fma(self, a, b, c): - """Returns a multiplied by b, plus c. - - The first two operands are multiplied together, using multiply, - the third operand is then added to the result of that - multiplication, using add, all with only one final rounding. - - >>> ExtendedContext.fma(Decimal('3'), Decimal('5'), Decimal('7')) - Decimal('22') - >>> ExtendedContext.fma(Decimal('3'), Decimal('-5'), Decimal('7')) - Decimal('-8') - >>> ExtendedContext.fma(Decimal('888565290'), Decimal('1557.96930'), Decimal('-86087.7578')) - Decimal('1.38435736E+12') - >>> ExtendedContext.fma(1, 3, 4) - Decimal('7') - >>> ExtendedContext.fma(1, Decimal(3), 4) - Decimal('7') - >>> ExtendedContext.fma(1, 3, Decimal(4)) - Decimal('7') - """ - a = _convert_other(a, raiseit=True) - return a.fma(b, c, context=self) - - def is_canonical(self, a): - """Return True if the operand is canonical; otherwise return False. - - Currently, the encoding of a Decimal instance is always - canonical, so this method returns True for any Decimal. - - >>> ExtendedContext.is_canonical(Decimal('2.50')) - True - """ - if not isinstance(a, Decimal): - raise TypeError("is_canonical requires a Decimal as an argument.") - return a.is_canonical() - - def is_finite(self, a): - """Return True if the operand is finite; otherwise return False. - - A Decimal instance is considered finite if it is neither - infinite nor a NaN. - - >>> ExtendedContext.is_finite(Decimal('2.50')) - True - >>> ExtendedContext.is_finite(Decimal('-0.3')) - True - >>> ExtendedContext.is_finite(Decimal('0')) - True - >>> ExtendedContext.is_finite(Decimal('Inf')) - False - >>> ExtendedContext.is_finite(Decimal('NaN')) - False - >>> ExtendedContext.is_finite(1) - True - """ - a = _convert_other(a, raiseit=True) - return a.is_finite() - - def is_infinite(self, a): - """Return True if the operand is infinite; otherwise return False. - - >>> ExtendedContext.is_infinite(Decimal('2.50')) - False - >>> ExtendedContext.is_infinite(Decimal('-Inf')) - True - >>> ExtendedContext.is_infinite(Decimal('NaN')) - False - >>> ExtendedContext.is_infinite(1) - False - """ - a = _convert_other(a, raiseit=True) - return a.is_infinite() - - def is_nan(self, a): - """Return True if the operand is a qNaN or sNaN; - otherwise return False. - - >>> ExtendedContext.is_nan(Decimal('2.50')) - False - >>> ExtendedContext.is_nan(Decimal('NaN')) - True - >>> ExtendedContext.is_nan(Decimal('-sNaN')) - True - >>> ExtendedContext.is_nan(1) - False - """ - a = _convert_other(a, raiseit=True) - return a.is_nan() - - def is_normal(self, a): - """Return True if the operand is a normal number; - otherwise return False. - - >>> c = ExtendedContext.copy() - >>> c.Emin = -999 - >>> c.Emax = 999 - >>> c.is_normal(Decimal('2.50')) - True - >>> c.is_normal(Decimal('0.1E-999')) - False - >>> c.is_normal(Decimal('0.00')) - False - >>> c.is_normal(Decimal('-Inf')) - False - >>> c.is_normal(Decimal('NaN')) - False - >>> c.is_normal(1) - True - """ - a = _convert_other(a, raiseit=True) - return a.is_normal(context=self) - - def is_qnan(self, a): - """Return True if the operand is a quiet NaN; otherwise return False. - - >>> ExtendedContext.is_qnan(Decimal('2.50')) - False - >>> ExtendedContext.is_qnan(Decimal('NaN')) - True - >>> ExtendedContext.is_qnan(Decimal('sNaN')) - False - >>> ExtendedContext.is_qnan(1) - False - """ - a = _convert_other(a, raiseit=True) - return a.is_qnan() - - def is_signed(self, a): - """Return True if the operand is negative; otherwise return False. - - >>> ExtendedContext.is_signed(Decimal('2.50')) - False - >>> ExtendedContext.is_signed(Decimal('-12')) - True - >>> ExtendedContext.is_signed(Decimal('-0')) - True - >>> ExtendedContext.is_signed(8) - False - >>> ExtendedContext.is_signed(-8) - True - """ - a = _convert_other(a, raiseit=True) - return a.is_signed() - - def is_snan(self, a): - """Return True if the operand is a signaling NaN; - otherwise return False. - - >>> ExtendedContext.is_snan(Decimal('2.50')) - False - >>> ExtendedContext.is_snan(Decimal('NaN')) - False - >>> ExtendedContext.is_snan(Decimal('sNaN')) - True - >>> ExtendedContext.is_snan(1) - False - """ - a = _convert_other(a, raiseit=True) - return a.is_snan() - - def is_subnormal(self, a): - """Return True if the operand is subnormal; otherwise return False. - - >>> c = ExtendedContext.copy() - >>> c.Emin = -999 - >>> c.Emax = 999 - >>> c.is_subnormal(Decimal('2.50')) - False - >>> c.is_subnormal(Decimal('0.1E-999')) - True - >>> c.is_subnormal(Decimal('0.00')) - False - >>> c.is_subnormal(Decimal('-Inf')) - False - >>> c.is_subnormal(Decimal('NaN')) - False - >>> c.is_subnormal(1) - False - """ - a = _convert_other(a, raiseit=True) - return a.is_subnormal(context=self) - - def is_zero(self, a): - """Return True if the operand is a zero; otherwise return False. - - >>> ExtendedContext.is_zero(Decimal('0')) - True - >>> ExtendedContext.is_zero(Decimal('2.50')) - False - >>> ExtendedContext.is_zero(Decimal('-0E+2')) - True - >>> ExtendedContext.is_zero(1) - False - >>> ExtendedContext.is_zero(0) - True - """ - a = _convert_other(a, raiseit=True) - return a.is_zero() - - def ln(self, a): - """Returns the natural (base e) logarithm of the operand. - - >>> c = ExtendedContext.copy() - >>> c.Emin = -999 - >>> c.Emax = 999 - >>> c.ln(Decimal('0')) - Decimal('-Infinity') - >>> c.ln(Decimal('1.000')) - Decimal('0') - >>> c.ln(Decimal('2.71828183')) - Decimal('1.00000000') - >>> c.ln(Decimal('10')) - Decimal('2.30258509') - >>> c.ln(Decimal('+Infinity')) - Decimal('Infinity') - >>> c.ln(1) - Decimal('0') - """ - a = _convert_other(a, raiseit=True) - return a.ln(context=self) - - def log10(self, a): - """Returns the base 10 logarithm of the operand. - - >>> c = ExtendedContext.copy() - >>> c.Emin = -999 - >>> c.Emax = 999 - >>> c.log10(Decimal('0')) - Decimal('-Infinity') - >>> c.log10(Decimal('0.001')) - Decimal('-3') - >>> c.log10(Decimal('1.000')) - Decimal('0') - >>> c.log10(Decimal('2')) - Decimal('0.301029996') - >>> c.log10(Decimal('10')) - Decimal('1') - >>> c.log10(Decimal('70')) - Decimal('1.84509804') - >>> c.log10(Decimal('+Infinity')) - Decimal('Infinity') - >>> c.log10(0) - Decimal('-Infinity') - >>> c.log10(1) - Decimal('0') - """ - a = _convert_other(a, raiseit=True) - return a.log10(context=self) - - def logb(self, a): - """ Returns the exponent of the magnitude of the operand's MSD. - - The result is the integer which is the exponent of the magnitude - of the most significant digit of the operand (as though the - operand were truncated to a single digit while maintaining the - value of that digit and without limiting the resulting exponent). - - >>> ExtendedContext.logb(Decimal('250')) - Decimal('2') - >>> ExtendedContext.logb(Decimal('2.50')) - Decimal('0') - >>> ExtendedContext.logb(Decimal('0.03')) - Decimal('-2') - >>> ExtendedContext.logb(Decimal('0')) - Decimal('-Infinity') - >>> ExtendedContext.logb(1) - Decimal('0') - >>> ExtendedContext.logb(10) - Decimal('1') - >>> ExtendedContext.logb(100) - Decimal('2') - """ - a = _convert_other(a, raiseit=True) - return a.logb(context=self) - - def logical_and(self, a, b): - """Applies the logical operation 'and' between each operand's digits. - - The operands must be both logical numbers. - - >>> ExtendedContext.logical_and(Decimal('0'), Decimal('0')) - Decimal('0') - >>> ExtendedContext.logical_and(Decimal('0'), Decimal('1')) - Decimal('0') - >>> ExtendedContext.logical_and(Decimal('1'), Decimal('0')) - Decimal('0') - >>> ExtendedContext.logical_and(Decimal('1'), Decimal('1')) - Decimal('1') - >>> ExtendedContext.logical_and(Decimal('1100'), Decimal('1010')) - Decimal('1000') - >>> ExtendedContext.logical_and(Decimal('1111'), Decimal('10')) - Decimal('10') - >>> ExtendedContext.logical_and(110, 1101) - Decimal('100') - >>> ExtendedContext.logical_and(Decimal(110), 1101) - Decimal('100') - >>> ExtendedContext.logical_and(110, Decimal(1101)) - Decimal('100') - """ - a = _convert_other(a, raiseit=True) - return a.logical_and(b, context=self) - - def logical_invert(self, a): - """Invert all the digits in the operand. - - The operand must be a logical number. - - >>> ExtendedContext.logical_invert(Decimal('0')) - Decimal('111111111') - >>> ExtendedContext.logical_invert(Decimal('1')) - Decimal('111111110') - >>> ExtendedContext.logical_invert(Decimal('111111111')) - Decimal('0') - >>> ExtendedContext.logical_invert(Decimal('101010101')) - Decimal('10101010') - >>> ExtendedContext.logical_invert(1101) - Decimal('111110010') - """ - a = _convert_other(a, raiseit=True) - return a.logical_invert(context=self) - - def logical_or(self, a, b): - """Applies the logical operation 'or' between each operand's digits. - - The operands must be both logical numbers. - - >>> ExtendedContext.logical_or(Decimal('0'), Decimal('0')) - Decimal('0') - >>> ExtendedContext.logical_or(Decimal('0'), Decimal('1')) - Decimal('1') - >>> ExtendedContext.logical_or(Decimal('1'), Decimal('0')) - Decimal('1') - >>> ExtendedContext.logical_or(Decimal('1'), Decimal('1')) - Decimal('1') - >>> ExtendedContext.logical_or(Decimal('1100'), Decimal('1010')) - Decimal('1110') - >>> ExtendedContext.logical_or(Decimal('1110'), Decimal('10')) - Decimal('1110') - >>> ExtendedContext.logical_or(110, 1101) - Decimal('1111') - >>> ExtendedContext.logical_or(Decimal(110), 1101) - Decimal('1111') - >>> ExtendedContext.logical_or(110, Decimal(1101)) - Decimal('1111') - """ - a = _convert_other(a, raiseit=True) - return a.logical_or(b, context=self) - - def logical_xor(self, a, b): - """Applies the logical operation 'xor' between each operand's digits. - - The operands must be both logical numbers. - - >>> ExtendedContext.logical_xor(Decimal('0'), Decimal('0')) - Decimal('0') - >>> ExtendedContext.logical_xor(Decimal('0'), Decimal('1')) - Decimal('1') - >>> ExtendedContext.logical_xor(Decimal('1'), Decimal('0')) - Decimal('1') - >>> ExtendedContext.logical_xor(Decimal('1'), Decimal('1')) - Decimal('0') - >>> ExtendedContext.logical_xor(Decimal('1100'), Decimal('1010')) - Decimal('110') - >>> ExtendedContext.logical_xor(Decimal('1111'), Decimal('10')) - Decimal('1101') - >>> ExtendedContext.logical_xor(110, 1101) - Decimal('1011') - >>> ExtendedContext.logical_xor(Decimal(110), 1101) - Decimal('1011') - >>> ExtendedContext.logical_xor(110, Decimal(1101)) - Decimal('1011') - """ - a = _convert_other(a, raiseit=True) - return a.logical_xor(b, context=self) - - def max(self, a, b): - """max compares two values numerically and returns the maximum. - - If either operand is a NaN then the general rules apply. - Otherwise, the operands are compared as though by the compare - operation. If they are numerically equal then the left-hand operand - is chosen as the result. Otherwise the maximum (closer to positive - infinity) of the two operands is chosen as the result. - - >>> ExtendedContext.max(Decimal('3'), Decimal('2')) - Decimal('3') - >>> ExtendedContext.max(Decimal('-10'), Decimal('3')) - Decimal('3') - >>> ExtendedContext.max(Decimal('1.0'), Decimal('1')) - Decimal('1') - >>> ExtendedContext.max(Decimal('7'), Decimal('NaN')) - Decimal('7') - >>> ExtendedContext.max(1, 2) - Decimal('2') - >>> ExtendedContext.max(Decimal(1), 2) - Decimal('2') - >>> ExtendedContext.max(1, Decimal(2)) - Decimal('2') - """ - a = _convert_other(a, raiseit=True) - return a.max(b, context=self) - - def max_mag(self, a, b): - """Compares the values numerically with their sign ignored. - - >>> ExtendedContext.max_mag(Decimal('7'), Decimal('NaN')) - Decimal('7') - >>> ExtendedContext.max_mag(Decimal('7'), Decimal('-10')) - Decimal('-10') - >>> ExtendedContext.max_mag(1, -2) - Decimal('-2') - >>> ExtendedContext.max_mag(Decimal(1), -2) - Decimal('-2') - >>> ExtendedContext.max_mag(1, Decimal(-2)) - Decimal('-2') - """ - a = _convert_other(a, raiseit=True) - return a.max_mag(b, context=self) - - def min(self, a, b): - """min compares two values numerically and returns the minimum. - - If either operand is a NaN then the general rules apply. - Otherwise, the operands are compared as though by the compare - operation. If they are numerically equal then the left-hand operand - is chosen as the result. Otherwise the minimum (closer to negative - infinity) of the two operands is chosen as the result. - - >>> ExtendedContext.min(Decimal('3'), Decimal('2')) - Decimal('2') - >>> ExtendedContext.min(Decimal('-10'), Decimal('3')) - Decimal('-10') - >>> ExtendedContext.min(Decimal('1.0'), Decimal('1')) - Decimal('1.0') - >>> ExtendedContext.min(Decimal('7'), Decimal('NaN')) - Decimal('7') - >>> ExtendedContext.min(1, 2) - Decimal('1') - >>> ExtendedContext.min(Decimal(1), 2) - Decimal('1') - >>> ExtendedContext.min(1, Decimal(29)) - Decimal('1') - """ - a = _convert_other(a, raiseit=True) - return a.min(b, context=self) - - def min_mag(self, a, b): - """Compares the values numerically with their sign ignored. - - >>> ExtendedContext.min_mag(Decimal('3'), Decimal('-2')) - Decimal('-2') - >>> ExtendedContext.min_mag(Decimal('-3'), Decimal('NaN')) - Decimal('-3') - >>> ExtendedContext.min_mag(1, -2) - Decimal('1') - >>> ExtendedContext.min_mag(Decimal(1), -2) - Decimal('1') - >>> ExtendedContext.min_mag(1, Decimal(-2)) - Decimal('1') - """ - a = _convert_other(a, raiseit=True) - return a.min_mag(b, context=self) - - def minus(self, a): - """Minus corresponds to unary prefix minus in Python. - - The operation is evaluated using the same rules as subtract; the - operation minus(a) is calculated as subtract('0', a) where the '0' - has the same exponent as the operand. - - >>> ExtendedContext.minus(Decimal('1.3')) - Decimal('-1.3') - >>> ExtendedContext.minus(Decimal('-1.3')) - Decimal('1.3') - >>> ExtendedContext.minus(1) - Decimal('-1') - """ - a = _convert_other(a, raiseit=True) - return a.__neg__(context=self) - - def multiply(self, a, b): - """multiply multiplies two operands. - - If either operand is a special value then the general rules apply. - Otherwise, the operands are multiplied together - ('long multiplication'), resulting in a number which may be as long as - the sum of the lengths of the two operands. - - >>> ExtendedContext.multiply(Decimal('1.20'), Decimal('3')) - Decimal('3.60') - >>> ExtendedContext.multiply(Decimal('7'), Decimal('3')) - Decimal('21') - >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('0.8')) - Decimal('0.72') - >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('-0')) - Decimal('-0.0') - >>> ExtendedContext.multiply(Decimal('654321'), Decimal('654321')) - Decimal('4.28135971E+11') - >>> ExtendedContext.multiply(7, 7) - Decimal('49') - >>> ExtendedContext.multiply(Decimal(7), 7) - Decimal('49') - >>> ExtendedContext.multiply(7, Decimal(7)) - Decimal('49') - """ - a = _convert_other(a, raiseit=True) - r = a.__mul__(b, context=self) - if r is NotImplemented: - raise TypeError("Unable to convert %s to Decimal" % b) - else: - return r - - def next_minus(self, a): - """Returns the largest representable number smaller than a. - - >>> c = ExtendedContext.copy() - >>> c.Emin = -999 - >>> c.Emax = 999 - >>> ExtendedContext.next_minus(Decimal('1')) - Decimal('0.999999999') - >>> c.next_minus(Decimal('1E-1007')) - Decimal('0E-1007') - >>> ExtendedContext.next_minus(Decimal('-1.00000003')) - Decimal('-1.00000004') - >>> c.next_minus(Decimal('Infinity')) - Decimal('9.99999999E+999') - >>> c.next_minus(1) - Decimal('0.999999999') - """ - a = _convert_other(a, raiseit=True) - return a.next_minus(context=self) - - def next_plus(self, a): - """Returns the smallest representable number larger than a. - - >>> c = ExtendedContext.copy() - >>> c.Emin = -999 - >>> c.Emax = 999 - >>> ExtendedContext.next_plus(Decimal('1')) - Decimal('1.00000001') - >>> c.next_plus(Decimal('-1E-1007')) - Decimal('-0E-1007') - >>> ExtendedContext.next_plus(Decimal('-1.00000003')) - Decimal('-1.00000002') - >>> c.next_plus(Decimal('-Infinity')) - Decimal('-9.99999999E+999') - >>> c.next_plus(1) - Decimal('1.00000001') - """ - a = _convert_other(a, raiseit=True) - return a.next_plus(context=self) - - def next_toward(self, a, b): - """Returns the number closest to a, in direction towards b. - - The result is the closest representable number from the first - operand (but not the first operand) that is in the direction - towards the second operand, unless the operands have the same - value. - - >>> c = ExtendedContext.copy() - >>> c.Emin = -999 - >>> c.Emax = 999 - >>> c.next_toward(Decimal('1'), Decimal('2')) - Decimal('1.00000001') - >>> c.next_toward(Decimal('-1E-1007'), Decimal('1')) - Decimal('-0E-1007') - >>> c.next_toward(Decimal('-1.00000003'), Decimal('0')) - Decimal('-1.00000002') - >>> c.next_toward(Decimal('1'), Decimal('0')) - Decimal('0.999999999') - >>> c.next_toward(Decimal('1E-1007'), Decimal('-100')) - Decimal('0E-1007') - >>> c.next_toward(Decimal('-1.00000003'), Decimal('-10')) - Decimal('-1.00000004') - >>> c.next_toward(Decimal('0.00'), Decimal('-0.0000')) - Decimal('-0.00') - >>> c.next_toward(0, 1) - Decimal('1E-1007') - >>> c.next_toward(Decimal(0), 1) - Decimal('1E-1007') - >>> c.next_toward(0, Decimal(1)) - Decimal('1E-1007') - """ - a = _convert_other(a, raiseit=True) - return a.next_toward(b, context=self) - - def normalize(self, a): - """normalize reduces an operand to its simplest form. - - Essentially a plus operation with all trailing zeros removed from the - result. - - >>> ExtendedContext.normalize(Decimal('2.1')) - Decimal('2.1') - >>> ExtendedContext.normalize(Decimal('-2.0')) - Decimal('-2') - >>> ExtendedContext.normalize(Decimal('1.200')) - Decimal('1.2') - >>> ExtendedContext.normalize(Decimal('-120')) - Decimal('-1.2E+2') - >>> ExtendedContext.normalize(Decimal('120.00')) - Decimal('1.2E+2') - >>> ExtendedContext.normalize(Decimal('0.00')) - Decimal('0') - >>> ExtendedContext.normalize(6) - Decimal('6') - """ - a = _convert_other(a, raiseit=True) - return a.normalize(context=self) - - def number_class(self, a): - """Returns an indication of the class of the operand. - - The class is one of the following strings: - -sNaN - -NaN - -Infinity - -Normal - -Subnormal - -Zero - +Zero - +Subnormal - +Normal - +Infinity - - >>> c = ExtendedContext.copy() - >>> c.Emin = -999 - >>> c.Emax = 999 - >>> c.number_class(Decimal('Infinity')) - '+Infinity' - >>> c.number_class(Decimal('1E-10')) - '+Normal' - >>> c.number_class(Decimal('2.50')) - '+Normal' - >>> c.number_class(Decimal('0.1E-999')) - '+Subnormal' - >>> c.number_class(Decimal('0')) - '+Zero' - >>> c.number_class(Decimal('-0')) - '-Zero' - >>> c.number_class(Decimal('-0.1E-999')) - '-Subnormal' - >>> c.number_class(Decimal('-1E-10')) - '-Normal' - >>> c.number_class(Decimal('-2.50')) - '-Normal' - >>> c.number_class(Decimal('-Infinity')) - '-Infinity' - >>> c.number_class(Decimal('NaN')) - 'NaN' - >>> c.number_class(Decimal('-NaN')) - 'NaN' - >>> c.number_class(Decimal('sNaN')) - 'sNaN' - >>> c.number_class(123) - '+Normal' - """ - a = _convert_other(a, raiseit=True) - return a.number_class(context=self) - - def plus(self, a): - """Plus corresponds to unary prefix plus in Python. - - The operation is evaluated using the same rules as add; the - operation plus(a) is calculated as add('0', a) where the '0' - has the same exponent as the operand. - - >>> ExtendedContext.plus(Decimal('1.3')) - Decimal('1.3') - >>> ExtendedContext.plus(Decimal('-1.3')) - Decimal('-1.3') - >>> ExtendedContext.plus(-1) - Decimal('-1') - """ - a = _convert_other(a, raiseit=True) - return a.__pos__(context=self) - - def power(self, a, b, modulo=None): - """Raises a to the power of b, to modulo if given. - - With two arguments, compute a**b. If a is negative then b - must be integral. The result will be inexact unless b is - integral and the result is finite and can be expressed exactly - in 'precision' digits. - - With three arguments, compute (a**b) % modulo. For the - three argument form, the following restrictions on the - arguments hold: - - - all three arguments must be integral - - b must be nonnegative - - at least one of a or b must be nonzero - - modulo must be nonzero and have at most 'precision' digits - - The result of pow(a, b, modulo) is identical to the result - that would be obtained by computing (a**b) % modulo with - unbounded precision, but is computed more efficiently. It is - always exact. - - >>> c = ExtendedContext.copy() - >>> c.Emin = -999 - >>> c.Emax = 999 - >>> c.power(Decimal('2'), Decimal('3')) - Decimal('8') - >>> c.power(Decimal('-2'), Decimal('3')) - Decimal('-8') - >>> c.power(Decimal('2'), Decimal('-3')) - Decimal('0.125') - >>> c.power(Decimal('1.7'), Decimal('8')) - Decimal('69.7575744') - >>> c.power(Decimal('10'), Decimal('0.301029996')) - Decimal('2.00000000') - >>> c.power(Decimal('Infinity'), Decimal('-1')) - Decimal('0') - >>> c.power(Decimal('Infinity'), Decimal('0')) - Decimal('1') - >>> c.power(Decimal('Infinity'), Decimal('1')) - Decimal('Infinity') - >>> c.power(Decimal('-Infinity'), Decimal('-1')) - Decimal('-0') - >>> c.power(Decimal('-Infinity'), Decimal('0')) - Decimal('1') - >>> c.power(Decimal('-Infinity'), Decimal('1')) - Decimal('-Infinity') - >>> c.power(Decimal('-Infinity'), Decimal('2')) - Decimal('Infinity') - >>> c.power(Decimal('0'), Decimal('0')) - Decimal('NaN') - - >>> c.power(Decimal('3'), Decimal('7'), Decimal('16')) - Decimal('11') - >>> c.power(Decimal('-3'), Decimal('7'), Decimal('16')) - Decimal('-11') - >>> c.power(Decimal('-3'), Decimal('8'), Decimal('16')) - Decimal('1') - >>> c.power(Decimal('3'), Decimal('7'), Decimal('-16')) - Decimal('11') - >>> c.power(Decimal('23E12345'), Decimal('67E189'), Decimal('123456789')) - Decimal('11729830') - >>> c.power(Decimal('-0'), Decimal('17'), Decimal('1729')) - Decimal('-0') - >>> c.power(Decimal('-23'), Decimal('0'), Decimal('65537')) - Decimal('1') - >>> ExtendedContext.power(7, 7) - Decimal('823543') - >>> ExtendedContext.power(Decimal(7), 7) - Decimal('823543') - >>> ExtendedContext.power(7, Decimal(7), 2) - Decimal('1') - """ - a = _convert_other(a, raiseit=True) - r = a.__pow__(b, modulo, context=self) - if r is NotImplemented: - raise TypeError("Unable to convert %s to Decimal" % b) - else: - return r - - def quantize(self, a, b): - """Returns a value equal to 'a' (rounded), having the exponent of 'b'. - - The coefficient of the result is derived from that of the left-hand - operand. It may be rounded using the current rounding setting (if the - exponent is being increased), multiplied by a positive power of ten (if - the exponent is being decreased), or is unchanged (if the exponent is - already equal to that of the right-hand operand). - - Unlike other operations, if the length of the coefficient after the - quantize operation would be greater than precision then an Invalid - operation condition is raised. This guarantees that, unless there is - an error condition, the exponent of the result of a quantize is always - equal to that of the right-hand operand. - - Also unlike other operations, quantize will never raise Underflow, even - if the result is subnormal and inexact. - - >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.001')) - Decimal('2.170') - >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.01')) - Decimal('2.17') - >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.1')) - Decimal('2.2') - >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+0')) - Decimal('2') - >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+1')) - Decimal('0E+1') - >>> ExtendedContext.quantize(Decimal('-Inf'), Decimal('Infinity')) - Decimal('-Infinity') - >>> ExtendedContext.quantize(Decimal('2'), Decimal('Infinity')) - Decimal('NaN') - >>> ExtendedContext.quantize(Decimal('-0.1'), Decimal('1')) - Decimal('-0') - >>> ExtendedContext.quantize(Decimal('-0'), Decimal('1e+5')) - Decimal('-0E+5') - >>> ExtendedContext.quantize(Decimal('+35236450.6'), Decimal('1e-2')) - Decimal('NaN') - >>> ExtendedContext.quantize(Decimal('-35236450.6'), Decimal('1e-2')) - Decimal('NaN') - >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-1')) - Decimal('217.0') - >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-0')) - Decimal('217') - >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+1')) - Decimal('2.2E+2') - >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+2')) - Decimal('2E+2') - >>> ExtendedContext.quantize(1, 2) - Decimal('1') - >>> ExtendedContext.quantize(Decimal(1), 2) - Decimal('1') - >>> ExtendedContext.quantize(1, Decimal(2)) - Decimal('1') - """ - a = _convert_other(a, raiseit=True) - return a.quantize(b, context=self) - - def radix(self): - """Just returns 10, as this is Decimal, :) - - >>> ExtendedContext.radix() - Decimal('10') - """ - return Decimal(10) - - def remainder(self, a, b): - """Returns the remainder from integer division. - - The result is the residue of the dividend after the operation of - calculating integer division as described for divide-integer, rounded - to precision digits if necessary. The sign of the result, if - non-zero, is the same as that of the original dividend. - - This operation will fail under the same conditions as integer division - (that is, if integer division on the same two operands would fail, the - remainder cannot be calculated). - - >>> ExtendedContext.remainder(Decimal('2.1'), Decimal('3')) - Decimal('2.1') - >>> ExtendedContext.remainder(Decimal('10'), Decimal('3')) - Decimal('1') - >>> ExtendedContext.remainder(Decimal('-10'), Decimal('3')) - Decimal('-1') - >>> ExtendedContext.remainder(Decimal('10.2'), Decimal('1')) - Decimal('0.2') - >>> ExtendedContext.remainder(Decimal('10'), Decimal('0.3')) - Decimal('0.1') - >>> ExtendedContext.remainder(Decimal('3.6'), Decimal('1.3')) - Decimal('1.0') - >>> ExtendedContext.remainder(22, 6) - Decimal('4') - >>> ExtendedContext.remainder(Decimal(22), 6) - Decimal('4') - >>> ExtendedContext.remainder(22, Decimal(6)) - Decimal('4') - """ - a = _convert_other(a, raiseit=True) - r = a.__mod__(b, context=self) - if r is NotImplemented: - raise TypeError("Unable to convert %s to Decimal" % b) - else: - return r - - def remainder_near(self, a, b): - """Returns to be "a - b * n", where n is the integer nearest the exact - value of "x / b" (if two integers are equally near then the even one - is chosen). If the result is equal to 0 then its sign will be the - sign of a. - - This operation will fail under the same conditions as integer division - (that is, if integer division on the same two operands would fail, the - remainder cannot be calculated). - - >>> ExtendedContext.remainder_near(Decimal('2.1'), Decimal('3')) - Decimal('-0.9') - >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('6')) - Decimal('-2') - >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('3')) - Decimal('1') - >>> ExtendedContext.remainder_near(Decimal('-10'), Decimal('3')) - Decimal('-1') - >>> ExtendedContext.remainder_near(Decimal('10.2'), Decimal('1')) - Decimal('0.2') - >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('0.3')) - Decimal('0.1') - >>> ExtendedContext.remainder_near(Decimal('3.6'), Decimal('1.3')) - Decimal('-0.3') - >>> ExtendedContext.remainder_near(3, 11) - Decimal('3') - >>> ExtendedContext.remainder_near(Decimal(3), 11) - Decimal('3') - >>> ExtendedContext.remainder_near(3, Decimal(11)) - Decimal('3') - """ - a = _convert_other(a, raiseit=True) - return a.remainder_near(b, context=self) - - def rotate(self, a, b): - """Returns a rotated copy of a, b times. - - The coefficient of the result is a rotated copy of the digits in - the coefficient of the first operand. The number of places of - rotation is taken from the absolute value of the second operand, - with the rotation being to the left if the second operand is - positive or to the right otherwise. - - >>> ExtendedContext.rotate(Decimal('34'), Decimal('8')) - Decimal('400000003') - >>> ExtendedContext.rotate(Decimal('12'), Decimal('9')) - Decimal('12') - >>> ExtendedContext.rotate(Decimal('123456789'), Decimal('-2')) - Decimal('891234567') - >>> ExtendedContext.rotate(Decimal('123456789'), Decimal('0')) - Decimal('123456789') - >>> ExtendedContext.rotate(Decimal('123456789'), Decimal('+2')) - Decimal('345678912') - >>> ExtendedContext.rotate(1333333, 1) - Decimal('13333330') - >>> ExtendedContext.rotate(Decimal(1333333), 1) - Decimal('13333330') - >>> ExtendedContext.rotate(1333333, Decimal(1)) - Decimal('13333330') - """ - a = _convert_other(a, raiseit=True) - return a.rotate(b, context=self) - - def same_quantum(self, a, b): - """Returns True if the two operands have the same exponent. - - The result is never affected by either the sign or the coefficient of - either operand. - - >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.001')) - False - >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.01')) - True - >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('1')) - False - >>> ExtendedContext.same_quantum(Decimal('Inf'), Decimal('-Inf')) - True - >>> ExtendedContext.same_quantum(10000, -1) - True - >>> ExtendedContext.same_quantum(Decimal(10000), -1) - True - >>> ExtendedContext.same_quantum(10000, Decimal(-1)) - True - """ - a = _convert_other(a, raiseit=True) - return a.same_quantum(b) - - def scaleb (self, a, b): - """Returns the first operand after adding the second value its exp. - - >>> ExtendedContext.scaleb(Decimal('7.50'), Decimal('-2')) - Decimal('0.0750') - >>> ExtendedContext.scaleb(Decimal('7.50'), Decimal('0')) - Decimal('7.50') - >>> ExtendedContext.scaleb(Decimal('7.50'), Decimal('3')) - Decimal('7.50E+3') - >>> ExtendedContext.scaleb(1, 4) - Decimal('1E+4') - >>> ExtendedContext.scaleb(Decimal(1), 4) - Decimal('1E+4') - >>> ExtendedContext.scaleb(1, Decimal(4)) - Decimal('1E+4') - """ - a = _convert_other(a, raiseit=True) - return a.scaleb(b, context=self) - - def shift(self, a, b): - """Returns a shifted copy of a, b times. - - The coefficient of the result is a shifted copy of the digits - in the coefficient of the first operand. The number of places - to shift is taken from the absolute value of the second operand, - with the shift being to the left if the second operand is - positive or to the right otherwise. Digits shifted into the - coefficient are zeros. - - >>> ExtendedContext.shift(Decimal('34'), Decimal('8')) - Decimal('400000000') - >>> ExtendedContext.shift(Decimal('12'), Decimal('9')) - Decimal('0') - >>> ExtendedContext.shift(Decimal('123456789'), Decimal('-2')) - Decimal('1234567') - >>> ExtendedContext.shift(Decimal('123456789'), Decimal('0')) - Decimal('123456789') - >>> ExtendedContext.shift(Decimal('123456789'), Decimal('+2')) - Decimal('345678900') - >>> ExtendedContext.shift(88888888, 2) - Decimal('888888800') - >>> ExtendedContext.shift(Decimal(88888888), 2) - Decimal('888888800') - >>> ExtendedContext.shift(88888888, Decimal(2)) - Decimal('888888800') - """ - a = _convert_other(a, raiseit=True) - return a.shift(b, context=self) - - def sqrt(self, a): - """Square root of a non-negative number to context precision. - - If the result must be inexact, it is rounded using the round-half-even - algorithm. - - >>> ExtendedContext.sqrt(Decimal('0')) - Decimal('0') - >>> ExtendedContext.sqrt(Decimal('-0')) - Decimal('-0') - >>> ExtendedContext.sqrt(Decimal('0.39')) - Decimal('0.624499800') - >>> ExtendedContext.sqrt(Decimal('100')) - Decimal('10') - >>> ExtendedContext.sqrt(Decimal('1')) - Decimal('1') - >>> ExtendedContext.sqrt(Decimal('1.0')) - Decimal('1.0') - >>> ExtendedContext.sqrt(Decimal('1.00')) - Decimal('1.0') - >>> ExtendedContext.sqrt(Decimal('7')) - Decimal('2.64575131') - >>> ExtendedContext.sqrt(Decimal('10')) - Decimal('3.16227766') - >>> ExtendedContext.sqrt(2) - Decimal('1.41421356') - >>> ExtendedContext.prec - 9 - """ - a = _convert_other(a, raiseit=True) - return a.sqrt(context=self) - - def subtract(self, a, b): - """Return the difference between the two operands. - - >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.07')) - Decimal('0.23') - >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.30')) - Decimal('0.00') - >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('2.07')) - Decimal('-0.77') - >>> ExtendedContext.subtract(8, 5) - Decimal('3') - >>> ExtendedContext.subtract(Decimal(8), 5) - Decimal('3') - >>> ExtendedContext.subtract(8, Decimal(5)) - Decimal('3') - """ - a = _convert_other(a, raiseit=True) - r = a.__sub__(b, context=self) - if r is NotImplemented: - raise TypeError("Unable to convert %s to Decimal" % b) - else: - return r - - def to_eng_string(self, a): - """Converts a number to a string, using scientific notation. - - The operation is not affected by the context. - """ - a = _convert_other(a, raiseit=True) - return a.to_eng_string(context=self) - - def to_sci_string(self, a): - """Converts a number to a string, using scientific notation. - - The operation is not affected by the context. - """ - a = _convert_other(a, raiseit=True) - return a.__str__(context=self) - - def to_integral_exact(self, a): - """Rounds to an integer. - - When the operand has a negative exponent, the result is the same - as using the quantize() operation using the given operand as the - left-hand-operand, 1E+0 as the right-hand-operand, and the precision - of the operand as the precision setting; Inexact and Rounded flags - are allowed in this operation. The rounding mode is taken from the - context. - - >>> ExtendedContext.to_integral_exact(Decimal('2.1')) - Decimal('2') - >>> ExtendedContext.to_integral_exact(Decimal('100')) - Decimal('100') - >>> ExtendedContext.to_integral_exact(Decimal('100.0')) - Decimal('100') - >>> ExtendedContext.to_integral_exact(Decimal('101.5')) - Decimal('102') - >>> ExtendedContext.to_integral_exact(Decimal('-101.5')) - Decimal('-102') - >>> ExtendedContext.to_integral_exact(Decimal('10E+5')) - Decimal('1.0E+6') - >>> ExtendedContext.to_integral_exact(Decimal('7.89E+77')) - Decimal('7.89E+77') - >>> ExtendedContext.to_integral_exact(Decimal('-Inf')) - Decimal('-Infinity') - """ - a = _convert_other(a, raiseit=True) - return a.to_integral_exact(context=self) - - def to_integral_value(self, a): - """Rounds to an integer. - - When the operand has a negative exponent, the result is the same - as using the quantize() operation using the given operand as the - left-hand-operand, 1E+0 as the right-hand-operand, and the precision - of the operand as the precision setting, except that no flags will - be set. The rounding mode is taken from the context. - - >>> ExtendedContext.to_integral_value(Decimal('2.1')) - Decimal('2') - >>> ExtendedContext.to_integral_value(Decimal('100')) - Decimal('100') - >>> ExtendedContext.to_integral_value(Decimal('100.0')) - Decimal('100') - >>> ExtendedContext.to_integral_value(Decimal('101.5')) - Decimal('102') - >>> ExtendedContext.to_integral_value(Decimal('-101.5')) - Decimal('-102') - >>> ExtendedContext.to_integral_value(Decimal('10E+5')) - Decimal('1.0E+6') - >>> ExtendedContext.to_integral_value(Decimal('7.89E+77')) - Decimal('7.89E+77') - >>> ExtendedContext.to_integral_value(Decimal('-Inf')) - Decimal('-Infinity') - """ - a = _convert_other(a, raiseit=True) - return a.to_integral_value(context=self) - - # the method name changed, but we provide also the old one, for compatibility - to_integral = to_integral_value - -class _WorkRep(object): - __slots__ = ('sign','int','exp') - # sign: 0 or 1 - # int: int - # exp: None, int, or string - - def __init__(self, value=None): - if value is None: - self.sign = None - self.int = 0 - self.exp = None - elif isinstance(value, Decimal): - self.sign = value._sign - self.int = int(value._int) - self.exp = value._exp - else: - # assert isinstance(value, tuple) - self.sign = value[0] - self.int = value[1] - self.exp = value[2] - - def __repr__(self): - return "(%r, %r, %r)" % (self.sign, self.int, self.exp) - - __str__ = __repr__ - - - -def _normalize(op1, op2, prec = 0): - """Normalizes op1, op2 to have the same exp and length of coefficient. - - Done during addition. - """ - if op1.exp < op2.exp: - tmp = op2 - other = op1 - else: - tmp = op1 - other = op2 - - # Let exp = min(tmp.exp - 1, tmp.adjusted() - precision - 1). - # Then adding 10**exp to tmp has the same effect (after rounding) - # as adding any positive quantity smaller than 10**exp; similarly - # for subtraction. So if other is smaller than 10**exp we replace - # it with 10**exp. This avoids tmp.exp - other.exp getting too large. - tmp_len = len(str(tmp.int)) - other_len = len(str(other.int)) - exp = tmp.exp + min(-1, tmp_len - prec - 2) - if other_len + other.exp - 1 < exp: - other.int = 1 - other.exp = exp - - tmp.int *= 10 ** (tmp.exp - other.exp) - tmp.exp = other.exp - return op1, op2 - -##### Integer arithmetic functions used by ln, log10, exp and __pow__ ##### - -_nbits = int.bit_length - -def _decimal_lshift_exact(n, e): - """ Given integers n and e, return n * 10**e if it's an integer, else None. - - The computation is designed to avoid computing large powers of 10 - unnecessarily. - - >>> _decimal_lshift_exact(3, 4) - 30000 - >>> _decimal_lshift_exact(300, -999999999) # returns None - - """ - if n == 0: - return 0 - elif e >= 0: - return n * 10**e - else: - # val_n = largest power of 10 dividing n. - str_n = str(abs(n)) - val_n = len(str_n) - len(str_n.rstrip('0')) - return None if val_n < -e else n // 10**-e - -def _sqrt_nearest(n, a): - """Closest integer to the square root of the positive integer n. a is - an initial approximation to the square root. Any positive integer - will do for a, but the closer a is to the square root of n the - faster convergence will be. - - """ - if n <= 0 or a <= 0: - raise ValueError("Both arguments to _sqrt_nearest should be positive.") - - b=0 - while a != b: - b, a = a, a--n//a>>1 - return a - -def _rshift_nearest(x, shift): - """Given an integer x and a nonnegative integer shift, return closest - integer to x / 2**shift; use round-to-even in case of a tie. - - """ - b, q = 1 << shift, x >> shift - return q + (2*(x & (b-1)) + (q&1) > b) - -def _div_nearest(a, b): - """Closest integer to a/b, a and b positive integers; rounds to even - in the case of a tie. - - """ - q, r = divmod(a, b) - return q + (2*r + (q&1) > b) - -def _ilog(x, M, L = 8): - """Integer approximation to M*log(x/M), with absolute error boundable - in terms only of x/M. - - Given positive integers x and M, return an integer approximation to - M * log(x/M). For L = 8 and 0.1 <= x/M <= 10 the difference - between the approximation and the exact result is at most 22. For - L = 8 and 1.0 <= x/M <= 10.0 the difference is at most 15. In - both cases these are upper bounds on the error; it will usually be - much smaller.""" - - # The basic algorithm is the following: let log1p be the function - # log1p(x) = log(1+x). Then log(x/M) = log1p((x-M)/M). We use - # the reduction - # - # log1p(y) = 2*log1p(y/(1+sqrt(1+y))) - # - # repeatedly until the argument to log1p is small (< 2**-L in - # absolute value). For small y we can use the Taylor series - # expansion - # - # log1p(y) ~ y - y**2/2 + y**3/3 - ... - (-y)**T/T - # - # truncating at T such that y**T is small enough. The whole - # computation is carried out in a form of fixed-point arithmetic, - # with a real number z being represented by an integer - # approximation to z*M. To avoid loss of precision, the y below - # is actually an integer approximation to 2**R*y*M, where R is the - # number of reductions performed so far. - - y = x-M - # argument reduction; R = number of reductions performed - R = 0 - while (R <= L and abs(y) << L-R >= M or - R > L and abs(y) >> R-L >= M): - y = _div_nearest((M*y) << 1, - M + _sqrt_nearest(M*(M+_rshift_nearest(y, R)), M)) - R += 1 - - # Taylor series with T terms - T = -int(-10*len(str(M))//(3*L)) - yshift = _rshift_nearest(y, R) - w = _div_nearest(M, T) - for k in range(T-1, 0, -1): - w = _div_nearest(M, k) - _div_nearest(yshift*w, M) - - return _div_nearest(w*y, M) - -def _dlog10(c, e, p): - """Given integers c, e and p with c > 0, p >= 0, compute an integer - approximation to 10**p * log10(c*10**e), with an absolute error of - at most 1. Assumes that c*10**e is not exactly 1.""" - - # increase precision by 2; compensate for this by dividing - # final result by 100 - p += 2 - - # write c*10**e as d*10**f with either: - # f >= 0 and 1 <= d <= 10, or - # f <= 0 and 0.1 <= d <= 1. - # Thus for c*10**e close to 1, f = 0 - l = len(str(c)) - f = e+l - (e+l >= 1) - - if p > 0: - M = 10**p - k = e+p-f - if k >= 0: - c *= 10**k - else: - c = _div_nearest(c, 10**-k) - - log_d = _ilog(c, M) # error < 5 + 22 = 27 - log_10 = _log10_digits(p) # error < 1 - log_d = _div_nearest(log_d*M, log_10) - log_tenpower = f*M # exact - else: - log_d = 0 # error < 2.31 - log_tenpower = _div_nearest(f, 10**-p) # error < 0.5 - - return _div_nearest(log_tenpower+log_d, 100) - -def _dlog(c, e, p): - """Given integers c, e and p with c > 0, compute an integer - approximation to 10**p * log(c*10**e), with an absolute error of - at most 1. Assumes that c*10**e is not exactly 1.""" - - # Increase precision by 2. The precision increase is compensated - # for at the end with a division by 100. - p += 2 - - # rewrite c*10**e as d*10**f with either f >= 0 and 1 <= d <= 10, - # or f <= 0 and 0.1 <= d <= 1. Then we can compute 10**p * log(c*10**e) - # as 10**p * log(d) + 10**p*f * log(10). - l = len(str(c)) - f = e+l - (e+l >= 1) - - # compute approximation to 10**p*log(d), with error < 27 - if p > 0: - k = e+p-f - if k >= 0: - c *= 10**k - else: - c = _div_nearest(c, 10**-k) # error of <= 0.5 in c - - # _ilog magnifies existing error in c by a factor of at most 10 - log_d = _ilog(c, 10**p) # error < 5 + 22 = 27 - else: - # p <= 0: just approximate the whole thing by 0; error < 2.31 - log_d = 0 - - # compute approximation to f*10**p*log(10), with error < 11. - if f: - extra = len(str(abs(f)))-1 - if p + extra >= 0: - # error in f * _log10_digits(p+extra) < |f| * 1 = |f| - # after division, error < |f|/10**extra + 0.5 < 10 + 0.5 < 11 - f_log_ten = _div_nearest(f*_log10_digits(p+extra), 10**extra) - else: - f_log_ten = 0 - else: - f_log_ten = 0 - - # error in sum < 11+27 = 38; error after division < 0.38 + 0.5 < 1 - return _div_nearest(f_log_ten + log_d, 100) - -class _Log10Memoize(object): - """Class to compute, store, and allow retrieval of, digits of the - constant log(10) = 2.302585.... This constant is needed by - Decimal.ln, Decimal.log10, Decimal.exp and Decimal.__pow__.""" - def __init__(self): - self.digits = "23025850929940456840179914546843642076011014886" - - def getdigits(self, p): - """Given an integer p >= 0, return floor(10**p)*log(10). - - For example, self.getdigits(3) returns 2302. - """ - # digits are stored as a string, for quick conversion to - # integer in the case that we've already computed enough - # digits; the stored digits should always be correct - # (truncated, not rounded to nearest). - if p < 0: - raise ValueError("p should be nonnegative") - - if p >= len(self.digits): - # compute p+3, p+6, p+9, ... digits; continue until at - # least one of the extra digits is nonzero - extra = 3 - while True: - # compute p+extra digits, correct to within 1ulp - M = 10**(p+extra+2) - digits = str(_div_nearest(_ilog(10*M, M), 100)) - if digits[-extra:] != '0'*extra: - break - extra += 3 - # keep all reliable digits so far; remove trailing zeros - # and next nonzero digit - self.digits = digits.rstrip('0')[:-1] - return int(self.digits[:p+1]) - -_log10_digits = _Log10Memoize().getdigits - -def _iexp(x, M, L=8): - """Given integers x and M, M > 0, such that x/M is small in absolute - value, compute an integer approximation to M*exp(x/M). For 0 <= - x/M <= 2.4, the absolute error in the result is bounded by 60 (and - is usually much smaller).""" - - # Algorithm: to compute exp(z) for a real number z, first divide z - # by a suitable power R of 2 so that |z/2**R| < 2**-L. Then - # compute expm1(z/2**R) = exp(z/2**R) - 1 using the usual Taylor - # series - # - # expm1(x) = x + x**2/2! + x**3/3! + ... - # - # Now use the identity - # - # expm1(2x) = expm1(x)*(expm1(x)+2) - # - # R times to compute the sequence expm1(z/2**R), - # expm1(z/2**(R-1)), ... , exp(z/2), exp(z). - - # Find R such that x/2**R/M <= 2**-L - R = _nbits((x<<L)//M) - - # Taylor series. (2**L)**T > M - T = -int(-10*len(str(M))//(3*L)) - y = _div_nearest(x, T) - Mshift = M<<R - for i in range(T-1, 0, -1): - y = _div_nearest(x*(Mshift + y), Mshift * i) - - # Expansion - for k in range(R-1, -1, -1): - Mshift = M<<(k+2) - y = _div_nearest(y*(y+Mshift), Mshift) - - return M+y - -def _dexp(c, e, p): - """Compute an approximation to exp(c*10**e), with p decimal places of - precision. - - Returns integers d, f such that: - - 10**(p-1) <= d <= 10**p, and - (d-1)*10**f < exp(c*10**e) < (d+1)*10**f - - In other words, d*10**f is an approximation to exp(c*10**e) with p - digits of precision, and with an error in d of at most 1. This is - almost, but not quite, the same as the error being < 1ulp: when d - = 10**(p-1) the error could be up to 10 ulp.""" - - # we'll call iexp with M = 10**(p+2), giving p+3 digits of precision - p += 2 - - # compute log(10) with extra precision = adjusted exponent of c*10**e - extra = max(0, e + len(str(c)) - 1) - q = p + extra - - # compute quotient c*10**e/(log(10)) = c*10**(e+q)/(log(10)*10**q), - # rounding down - shift = e+q - if shift >= 0: - cshift = c*10**shift - else: - cshift = c//10**-shift - quot, rem = divmod(cshift, _log10_digits(q)) - - # reduce remainder back to original precision - rem = _div_nearest(rem, 10**extra) - - # error in result of _iexp < 120; error after division < 0.62 - return _div_nearest(_iexp(rem, 10**p), 1000), quot - p + 3 - -def _dpower(xc, xe, yc, ye, p): - """Given integers xc, xe, yc and ye representing Decimals x = xc*10**xe and - y = yc*10**ye, compute x**y. Returns a pair of integers (c, e) such that: - - 10**(p-1) <= c <= 10**p, and - (c-1)*10**e < x**y < (c+1)*10**e - - in other words, c*10**e is an approximation to x**y with p digits - of precision, and with an error in c of at most 1. (This is - almost, but not quite, the same as the error being < 1ulp: when c - == 10**(p-1) we can only guarantee error < 10ulp.) - - We assume that: x is positive and not equal to 1, and y is nonzero. - """ - - # Find b such that 10**(b-1) <= |y| <= 10**b - b = len(str(abs(yc))) + ye - - # log(x) = lxc*10**(-p-b-1), to p+b+1 places after the decimal point - lxc = _dlog(xc, xe, p+b+1) - - # compute product y*log(x) = yc*lxc*10**(-p-b-1+ye) = pc*10**(-p-1) - shift = ye-b - if shift >= 0: - pc = lxc*yc*10**shift - else: - pc = _div_nearest(lxc*yc, 10**-shift) - - if pc == 0: - # we prefer a result that isn't exactly 1; this makes it - # easier to compute a correctly rounded result in __pow__ - if ((len(str(xc)) + xe >= 1) == (yc > 0)): # if x**y > 1: - coeff, exp = 10**(p-1)+1, 1-p - else: - coeff, exp = 10**p-1, -p - else: - coeff, exp = _dexp(pc, -(p+1), p+1) - coeff = _div_nearest(coeff, 10) - exp += 1 - - return coeff, exp - -def _log10_lb(c, correction = { - '1': 100, '2': 70, '3': 53, '4': 40, '5': 31, - '6': 23, '7': 16, '8': 10, '9': 5}): - """Compute a lower bound for 100*log10(c) for a positive integer c.""" - if c <= 0: - raise ValueError("The argument to _log10_lb should be nonnegative.") - str_c = str(c) - return 100*len(str_c) - correction[str_c[0]] - -##### Helper Functions #################################################### - -def _convert_other(other, raiseit=False, allow_float=False): - """Convert other to Decimal. - - Verifies that it's ok to use in an implicit construction. - If allow_float is true, allow conversion from float; this - is used in the comparison methods (__eq__ and friends). - - """ - if isinstance(other, Decimal): - return other - if isinstance(other, int): - return Decimal(other) - if allow_float and isinstance(other, float): - return Decimal.from_float(other) - - if raiseit: - raise TypeError("Unable to convert %s to Decimal" % other) - return NotImplemented - -def _convert_for_comparison(self, other, equality_op=False): - """Given a Decimal instance self and a Python object other, return - a pair (s, o) of Decimal instances such that "s op o" is - equivalent to "self op other" for any of the 6 comparison - operators "op". - - """ - if isinstance(other, Decimal): - return self, other - - # Comparison with a Rational instance (also includes integers): - # self op n/d <=> self*d op n (for n and d integers, d positive). - # A NaN or infinity can be left unchanged without affecting the - # comparison result. - if isinstance(other, _numbers.Rational): - if not self._is_special: - self = _dec_from_triple(self._sign, - str(int(self._int) * other.denominator), - self._exp) - return self, Decimal(other.numerator) - - # Comparisons with float and complex types. == and != comparisons - # with complex numbers should succeed, returning either True or False - # as appropriate. Other comparisons return NotImplemented. - if equality_op and isinstance(other, _numbers.Complex) and other.imag == 0: - other = other.real - if isinstance(other, float): - context = getcontext() - if equality_op: - context.flags[FloatOperation] = 1 - else: - context._raise_error(FloatOperation, - "strict semantics for mixing floats and Decimals are enabled") - return self, Decimal.from_float(other) - return NotImplemented, NotImplemented - - -##### Setup Specific Contexts ############################################ - -# The default context prototype used by Context() -# Is mutable, so that new contexts can have different default values - -DefaultContext = Context( - prec=28, rounding=ROUND_HALF_EVEN, - traps=[DivisionByZero, Overflow, InvalidOperation], - flags=[], - Emax=999999, - Emin=-999999, - capitals=1, - clamp=0 -) - -# Pre-made alternate contexts offered by the specification -# Don't change these; the user should be able to select these -# contexts and be able to reproduce results from other implementations -# of the spec. - -BasicContext = Context( - prec=9, rounding=ROUND_HALF_UP, - traps=[DivisionByZero, Overflow, InvalidOperation, Clamped, Underflow], - flags=[], -) - -ExtendedContext = Context( - prec=9, rounding=ROUND_HALF_EVEN, - traps=[], - flags=[], -) - - -##### crud for parsing strings ############################################# -# -# Regular expression used for parsing numeric strings. Additional -# comments: -# -# 1. Uncomment the two '\s*' lines to allow leading and/or trailing -# whitespace. But note that the specification disallows whitespace in -# a numeric string. -# -# 2. For finite numbers (not infinities and NaNs) the body of the -# number between the optional sign and the optional exponent must have -# at least one decimal digit, possibly after the decimal point. The -# lookahead expression '(?=\d|\.\d)' checks this. - -import re -_parser = re.compile(r""" # A numeric string consists of: -# \s* - (?P<sign>[-+])? # an optional sign, followed by either... - ( - (?=\d|\.\d) # ...a number (with at least one digit) - (?P<int>\d*) # having a (possibly empty) integer part - (\.(?P<frac>\d*))? # followed by an optional fractional part - (E(?P<exp>[-+]?\d+))? # followed by an optional exponent, or... - | - Inf(inity)? # ...an infinity, or... - | - (?P<signal>s)? # ...an (optionally signaling) - NaN # NaN - (?P<diag>\d*) # with (possibly empty) diagnostic info. - ) -# \s* - \Z -""", re.VERBOSE | re.IGNORECASE).match - -_all_zeros = re.compile('0*$').match -_exact_half = re.compile('50*$').match - -##### PEP3101 support functions ############################################## -# The functions in this section have little to do with the Decimal -# class, and could potentially be reused or adapted for other pure -# Python numeric classes that want to implement __format__ -# -# A format specifier for Decimal looks like: -# -# [[fill]align][sign][#][0][minimumwidth][,][.precision][type] - -_parse_format_specifier_regex = re.compile(r"""\A -(?: - (?P<fill>.)? - (?P<align>[<>=^]) -)? -(?P<sign>[-+ ])? -(?P<alt>\#)? -(?P<zeropad>0)? -(?P<minimumwidth>(?!0)\d+)? -(?P<thousands_sep>,)? -(?:\.(?P<precision>0|(?!0)\d+))? -(?P<type>[eEfFgGn%])? -\Z -""", re.VERBOSE|re.DOTALL) - -del re - -# The locale module is only needed for the 'n' format specifier. The -# rest of the PEP 3101 code functions quite happily without it, so we -# don't care too much if locale isn't present. -try: - import locale as _locale -except ImportError: - pass - -def _parse_format_specifier(format_spec, _localeconv=None): - """Parse and validate a format specifier. - - Turns a standard numeric format specifier into a dict, with the - following entries: - - fill: fill character to pad field to minimum width - align: alignment type, either '<', '>', '=' or '^' - sign: either '+', '-' or ' ' - minimumwidth: nonnegative integer giving minimum width - zeropad: boolean, indicating whether to pad with zeros - thousands_sep: string to use as thousands separator, or '' - grouping: grouping for thousands separators, in format - used by localeconv - decimal_point: string to use for decimal point - precision: nonnegative integer giving precision, or None - type: one of the characters 'eEfFgG%', or None - - """ - m = _parse_format_specifier_regex.match(format_spec) - if m is None: - raise ValueError("Invalid format specifier: " + format_spec) - - # get the dictionary - format_dict = m.groupdict() - - # zeropad; defaults for fill and alignment. If zero padding - # is requested, the fill and align fields should be absent. - fill = format_dict['fill'] - align = format_dict['align'] - format_dict['zeropad'] = (format_dict['zeropad'] is not None) - if format_dict['zeropad']: - if fill is not None: - raise ValueError("Fill character conflicts with '0'" - " in format specifier: " + format_spec) - if align is not None: - raise ValueError("Alignment conflicts with '0' in " - "format specifier: " + format_spec) - format_dict['fill'] = fill or ' ' - # PEP 3101 originally specified that the default alignment should - # be left; it was later agreed that right-aligned makes more sense - # for numeric types. See http://bugs.python.org/issue6857. - format_dict['align'] = align or '>' - - # default sign handling: '-' for negative, '' for positive - if format_dict['sign'] is None: - format_dict['sign'] = '-' - - # minimumwidth defaults to 0; precision remains None if not given - format_dict['minimumwidth'] = int(format_dict['minimumwidth'] or '0') - if format_dict['precision'] is not None: - format_dict['precision'] = int(format_dict['precision']) - - # if format type is 'g' or 'G' then a precision of 0 makes little - # sense; convert it to 1. Same if format type is unspecified. - if format_dict['precision'] == 0: - if format_dict['type'] is None or format_dict['type'] in 'gGn': - format_dict['precision'] = 1 - - # determine thousands separator, grouping, and decimal separator, and - # add appropriate entries to format_dict - if format_dict['type'] == 'n': - # apart from separators, 'n' behaves just like 'g' - format_dict['type'] = 'g' - if _localeconv is None: - _localeconv = _locale.localeconv() - if format_dict['thousands_sep'] is not None: - raise ValueError("Explicit thousands separator conflicts with " - "'n' type in format specifier: " + format_spec) - format_dict['thousands_sep'] = _localeconv['thousands_sep'] - format_dict['grouping'] = _localeconv['grouping'] - format_dict['decimal_point'] = _localeconv['decimal_point'] - else: - if format_dict['thousands_sep'] is None: - format_dict['thousands_sep'] = '' - format_dict['grouping'] = [3, 0] - format_dict['decimal_point'] = '.' - - return format_dict - -def _format_align(sign, body, spec): - """Given an unpadded, non-aligned numeric string 'body' and sign - string 'sign', add padding and alignment conforming to the given - format specifier dictionary 'spec' (as produced by - parse_format_specifier). - - """ - # how much extra space do we have to play with? - minimumwidth = spec['minimumwidth'] - fill = spec['fill'] - padding = fill*(minimumwidth - len(sign) - len(body)) - - align = spec['align'] - if align == '<': - result = sign + body + padding - elif align == '>': - result = padding + sign + body - elif align == '=': - result = sign + padding + body - elif align == '^': - half = len(padding)//2 - result = padding[:half] + sign + body + padding[half:] - else: - raise ValueError('Unrecognised alignment field') - - return result - -def _group_lengths(grouping): - """Convert a localeconv-style grouping into a (possibly infinite) - iterable of integers representing group lengths. - - """ - # The result from localeconv()['grouping'], and the input to this - # function, should be a list of integers in one of the - # following three forms: - # - # (1) an empty list, or - # (2) nonempty list of positive integers + [0] - # (3) list of positive integers + [locale.CHAR_MAX], or - - from itertools import chain, repeat - if not grouping: - return [] - elif grouping[-1] == 0 and len(grouping) >= 2: - return chain(grouping[:-1], repeat(grouping[-2])) - elif grouping[-1] == _locale.CHAR_MAX: - return grouping[:-1] - else: - raise ValueError('unrecognised format for grouping') - -def _insert_thousands_sep(digits, spec, min_width=1): - """Insert thousands separators into a digit string. - - spec is a dictionary whose keys should include 'thousands_sep' and - 'grouping'; typically it's the result of parsing the format - specifier using _parse_format_specifier. - - The min_width keyword argument gives the minimum length of the - result, which will be padded on the left with zeros if necessary. - - If necessary, the zero padding adds an extra '0' on the left to - avoid a leading thousands separator. For example, inserting - commas every three digits in '123456', with min_width=8, gives - '0,123,456', even though that has length 9. - - """ - - sep = spec['thousands_sep'] - grouping = spec['grouping'] - - groups = [] - for l in _group_lengths(grouping): - if l <= 0: - raise ValueError("group length should be positive") - # max(..., 1) forces at least 1 digit to the left of a separator - l = min(max(len(digits), min_width, 1), l) - groups.append('0'*(l - len(digits)) + digits[-l:]) - digits = digits[:-l] - min_width -= l - if not digits and min_width <= 0: - break - min_width -= len(sep) - else: - l = max(len(digits), min_width, 1) - groups.append('0'*(l - len(digits)) + digits[-l:]) - return sep.join(reversed(groups)) - -def _format_sign(is_negative, spec): - """Determine sign character.""" - - if is_negative: - return '-' - elif spec['sign'] in ' +': - return spec['sign'] - else: - return '' - -def _format_number(is_negative, intpart, fracpart, exp, spec): - """Format a number, given the following data: - - is_negative: true if the number is negative, else false - intpart: string of digits that must appear before the decimal point - fracpart: string of digits that must come after the point - exp: exponent, as an integer - spec: dictionary resulting from parsing the format specifier - - This function uses the information in spec to: - insert separators (decimal separator and thousands separators) - format the sign - format the exponent - add trailing '%' for the '%' type - zero-pad if necessary - fill and align if necessary - """ - - sign = _format_sign(is_negative, spec) - - if fracpart or spec['alt']: - fracpart = spec['decimal_point'] + fracpart - - if exp != 0 or spec['type'] in 'eE': - echar = {'E': 'E', 'e': 'e', 'G': 'E', 'g': 'e'}[spec['type']] - fracpart += "{0}{1:+}".format(echar, exp) - if spec['type'] == '%': - fracpart += '%' - - if spec['zeropad']: - min_width = spec['minimumwidth'] - len(fracpart) - len(sign) - else: - min_width = 0 - intpart = _insert_thousands_sep(intpart, spec, min_width) - - return _format_align(sign, intpart+fracpart, spec) - - -##### Useful Constants (internal use only) ################################ - -# Reusable defaults -_Infinity = Decimal('Inf') -_NegativeInfinity = Decimal('-Inf') -_NaN = Decimal('NaN') -_Zero = Decimal(0) -_One = Decimal(1) -_NegativeOne = Decimal(-1) - -# _SignedInfinity[sign] is infinity w/ that sign -_SignedInfinity = (_Infinity, _NegativeInfinity) - -# Constants related to the hash implementation; hash(x) is based -# on the reduction of x modulo _PyHASH_MODULUS -_PyHASH_MODULUS = sys.hash_info.modulus -# hash values to use for positive and negative infinities, and nans -_PyHASH_INF = sys.hash_info.inf -_PyHASH_NAN = sys.hash_info.nan - -# _PyHASH_10INV is the inverse of 10 modulo the prime _PyHASH_MODULUS -_PyHASH_10INV = pow(10, _PyHASH_MODULUS - 2, _PyHASH_MODULUS) -del sys try: - import _decimal -except ImportError: - pass -else: - s1 = set(dir()) - s2 = set(dir(_decimal)) - for name in s1 - s2: - del globals()[name] - del s1, s2, name from _decimal import * - -if __name__ == '__main__': - import doctest, decimal - doctest.testmod(decimal) + from _decimal import __doc__ + from _decimal import __version__ + from _decimal import __libmpdec_version__ +except ImportError: + from _pydecimal import * + from _pydecimal import __doc__ + from _pydecimal import __version__ + from _pydecimal import __libmpdec_version__ diff --git a/Lib/difflib.py b/Lib/difflib.py index 159cbe4dfdd9..ae3479d3d85e 100644 --- a/Lib/difflib.py +++ b/Lib/difflib.py @@ -1,5 +1,3 @@ -#! /usr/bin/env python3 - """ Module difflib -- helpers for computing deltas between objects. @@ -32,8 +30,7 @@ 'Differ','IS_CHARACTER_JUNK', 'IS_LINE_JUNK', 'context_diff', 'unified_diff', 'HtmlDiff', 'Match'] -import warnings -import heapq +from heapq import nlargest as _nlargest from collections import namedtuple as _namedtuple Match = _namedtuple('Match', 'a b size') @@ -514,8 +511,8 @@ def get_matching_blocks(self): non_adjacent.append((i1, j1, k1)) non_adjacent.append( (la, lb, 0) ) - self.matching_blocks = non_adjacent - return map(Match._make, self.matching_blocks) + self.matching_blocks = list(map(Match._make, non_adjacent)) + return self.matching_blocks def get_opcodes(self): """Return list of 5-tuples describing how to turn a into b. @@ -732,7 +729,7 @@ def get_close_matches(word, possibilities, n=3, cutoff=0.6): result.append((s.ratio(), x)) # Move the best scorers to head of list - result = heapq.nlargest(n, result) + result = _nlargest(n, result) # Strip scores for the best n matches return [x for score, x in result] @@ -855,10 +852,9 @@ def __init__(self, linejunk=None, charjunk=None): and return true iff the string is junk. The module-level function `IS_LINE_JUNK` may be used to filter out lines without visible characters, except for at most one splat ('#'). It is recommended - to leave linejunk None; as of Python 2.3, the underlying - SequenceMatcher class has grown an adaptive notion of "noise" lines - that's better than any static definition the author has ever been - able to craft. + to leave linejunk None; the underlying SequenceMatcher class has + an adaptive notion of "noise" lines that's better than any static + definition the author has ever been able to craft. - `charjunk`: A function that should accept a string of length 1. The module-level function `IS_CHARACTER_JUNK` may be used to filter out @@ -1301,17 +1297,18 @@ def ndiff(a, b, linejunk=None, charjunk=IS_CHARACTER_JUNK): Compare `a` and `b` (lists of strings); return a `Differ`-style delta. Optional keyword parameters `linejunk` and `charjunk` are for filter - functions (or None): + functions, or can be None: - - linejunk: A function that should accept a single string argument, and + - linejunk: A function that should accept a single string argument and return true iff the string is junk. The default is None, and is - recommended; as of Python 2.3, an adaptive notion of "noise" lines is - used that does a good job on its own. + recommended; the underlying SequenceMatcher class has an adaptive + notion of "noise" lines. - - charjunk: A function that should accept a string of length 1. The - default is module-level function IS_CHARACTER_JUNK, which filters out - whitespace characters (a blank or tab; note: bad idea to include newline - in this!). + - charjunk: A function that accepts a character (string of length + 1), and returns true iff the character is junk. The default is + the module-level function IS_CHARACTER_JUNK, which filters out + whitespace characters (a blank or tab; note: it's a bad idea to + include newline in this!). Tools/scripts/ndiff.py is a command-line front-end to this function. @@ -1413,7 +1410,7 @@ def record_sub_info(match_object,sub_info=sub_info): change_re.sub(record_sub_info,markers) # process each tuple inserting our special marks that won't be # noticed by an xml/html escaper. - for key,(begin,end) in sub_info[::-1]: + for key,(begin,end) in reversed(sub_info): text = text[0:begin]+'\0'+key+text[begin:end]+'\1'+text[end:] text = text[2:] # Handle case of add/delete entire line @@ -1451,10 +1448,7 @@ def _line_iterator(): # are a concatenation of the first character of each of the 4 lines # so we can do some very readable comparisons. while len(lines) < 4: - try: - lines.append(next(diff_lines_iterator)) - except StopIteration: - lines.append('X') + lines.append(next(diff_lines_iterator, 'X')) s = ''.join([line[0] for line in lines]) if s.startswith('X'): # When no more lines, pump out any remaining blank lines so the @@ -1517,7 +1511,7 @@ def _line_iterator(): num_blanks_to_yield -= 1 yield ('','\n'),None,True if s.startswith('X'): - raise StopIteration + return else: yield from_line,to_line,True @@ -1682,7 +1676,7 @@ def __init__(self,tabsize=8,wrapcolumn=None,linejunk=None, tabsize -- tab stop spacing, defaults to 8. wrapcolumn -- column number where lines are broken and wrapped, defaults to None where lines are not wrapped. - linejunk,charjunk -- keyword arguments passed into ndiff() (used to by + linejunk,charjunk -- keyword arguments passed into ndiff() (used by HtmlDiff() to generate the side by side HTML differences). See ndiff() documentation for argument default values and descriptions. """ diff --git a/Lib/dis.py b/Lib/dis.py index 81cbe7f4f993..d215bc59e4a8 100644 --- a/Lib/dis.py +++ b/Lib/dis.py @@ -29,7 +29,7 @@ def _try_compile(source, name): return c def dis(x=None, *, file=None): - """Disassemble classes, methods, functions, or code. + """Disassemble classes, methods, functions, generators, or code. With no argument, disassemble the last traceback. @@ -41,6 +41,8 @@ def dis(x=None, *, file=None): x = x.__func__ if hasattr(x, '__code__'): # Function x = x.__code__ + if hasattr(x, 'gi_code'): # Generator + x = x.gi_code if hasattr(x, '__dict__'): # Class or module items = sorted(x.__dict__.items()) for name, x1 in items: @@ -99,11 +101,13 @@ def pretty_flags(flags): return ", ".join(names) def _get_code_object(x): - """Helper to handle methods, functions, strings and raw code objects""" + """Helper to handle methods, functions, generators, strings and raw code objects""" if hasattr(x, '__func__'): # Method x = x.__func__ if hasattr(x, '__code__'): # Function x = x.__code__ + if hasattr(x, 'gi_code'): # Generator + x = x.gi_code if isinstance(x, str): # Source code x = _try_compile(x, "<disassembly>") if hasattr(x, 'co_code'): # Code object diff --git a/Lib/distutils/__init__.py b/Lib/distutils/__init__.py index 38a50869ea6e..67ec78b295d2 100644 --- a/Lib/distutils/__init__.py +++ b/Lib/distutils/__init__.py @@ -13,5 +13,5 @@ # Updated automatically by the Python release process. # #--start constants-- -__version__ = "3.4.0b1" +__version__ = "3.5.0a1" #--end constants-- diff --git a/Lib/distutils/command/build.py b/Lib/distutils/command/build.py index cfc15cf0ddc5..337dd0bfc1e2 100644 --- a/Lib/distutils/command/build.py +++ b/Lib/distutils/command/build.py @@ -36,6 +36,8 @@ class build(Command): "(default: %s)" % get_platform()), ('compiler=', 'c', "specify the compiler type"), + ('parallel=', 'j', + "number of parallel build jobs"), ('debug', 'g', "compile extensions and libraries with debugging information"), ('force', 'f', @@ -65,6 +67,7 @@ def initialize_options(self): self.debug = None self.force = 0 self.executable = None + self.parallel = None def finalize_options(self): if self.plat_name is None: @@ -116,6 +119,12 @@ def finalize_options(self): if self.executable is None: self.executable = os.path.normpath(sys.executable) + if isinstance(self.parallel, str): + try: + self.parallel = int(self.parallel) + except ValueError: + raise DistutilsOptionError("parallel should be an integer") + def run(self): # Run all relevant sub-commands. This will be some subset of: # - build_py - pure Python modules diff --git a/Lib/distutils/command/build_ext.py b/Lib/distutils/command/build_ext.py index 80689b63578d..c5a3ce1915db 100644 --- a/Lib/distutils/command/build_ext.py +++ b/Lib/distutils/command/build_ext.py @@ -4,7 +4,10 @@ modules (currently limited to C extensions, should accommodate C++ extensions ASAP).""" -import sys, os, re +import contextlib +import os +import re +import sys from distutils.core import Command from distutils.errors import * from distutils.sysconfig import customize_compiler, get_python_version @@ -14,13 +17,7 @@ from distutils.util import get_platform from distutils import log -# this keeps compatibility from 2.3 to 2.5 -if sys.version < "2.6": - USER_BASE = None - HAS_USER_SITE = False -else: - from site import USER_BASE - HAS_USER_SITE = True +from site import USER_BASE if os.name == 'nt': from distutils.msvccompiler import get_build_version @@ -91,20 +88,19 @@ class build_ext(Command): "forcibly build everything (ignore file timestamps)"), ('compiler=', 'c', "specify the compiler type"), + ('parallel=', 'j', + "number of parallel build jobs"), ('swig-cpp', None, "make SWIG create C++ files (default is C)"), ('swig-opts=', None, "list of SWIG command line options"), ('swig=', None, "path to the SWIG executable"), + ('user', None, + "add user include, library and rpath") ] - boolean_options = ['inplace', 'debug', 'force', 'swig-cpp'] - - if HAS_USER_SITE: - user_options.append(('user', None, - "add user include, library and rpath")) - boolean_options.append('user') + boolean_options = ['inplace', 'debug', 'force', 'swig-cpp', 'user'] help_options = [ ('help-compiler', None, @@ -133,6 +129,7 @@ def initialize_options(self): self.swig_cpp = None self.swig_opts = None self.user = None + self.parallel = None def finalize_options(self): from distutils import sysconfig @@ -143,6 +140,7 @@ def finalize_options(self): ('compiler', 'compiler'), ('debug', 'debug'), ('force', 'force'), + ('parallel', 'parallel'), ('plat_name', 'plat_name'), ) @@ -211,7 +209,7 @@ def finalize_options(self): if MSVC_VERSION >= 9: # Use the .lib files for the correct architecture if self.plat_name == 'win32': - suffix = '' + suffix = 'win32' else: # win-amd64 or win-ia64 suffix = self.plat_name[4:] @@ -246,7 +244,7 @@ def finalize_options(self): # Python's library directory must be appended to library_dirs # See Issues: #1600860, #4366 if (sysconfig.get_config_var('Py_ENABLE_SHARED')): - if sys.executable.startswith(os.path.join(sys.exec_prefix, "bin")): + if not sysconfig.python_build: # building third party extensions self.library_dirs.append(sysconfig.get_config_var('LIBDIR')) else: @@ -283,6 +281,12 @@ def finalize_options(self): self.library_dirs.append(user_lib) self.rpath.append(user_lib) + if isinstance(self.parallel, str): + try: + self.parallel = int(self.parallel) + except ValueError: + raise DistutilsOptionError("parallel should be an integer") + def run(self): from distutils.ccompiler import new_compiler @@ -451,15 +455,45 @@ def get_outputs(self): def build_extensions(self): # First, sanity-check the 'extensions' list self.check_extensions_list(self.extensions) + if self.parallel: + self._build_extensions_parallel() + else: + self._build_extensions_serial() + + def _build_extensions_parallel(self): + workers = self.parallel + if self.parallel is True: + workers = os.cpu_count() # may return None + try: + from concurrent.futures import ThreadPoolExecutor + except ImportError: + workers = None + + if workers is None: + self._build_extensions_serial() + return + with ThreadPoolExecutor(max_workers=workers) as executor: + futures = [executor.submit(self.build_extension, ext) + for ext in self.extensions] + for ext, fut in zip(self.extensions, futures): + with self._filter_build_errors(ext): + fut.result() + + def _build_extensions_serial(self): for ext in self.extensions: - try: + with self._filter_build_errors(ext): self.build_extension(ext) - except (CCompilerError, DistutilsError, CompileError) as e: - if not ext.optional: - raise - self.warn('building extension "%s" failed: %s' % - (ext.name, e)) + + @contextlib.contextmanager + def _filter_build_errors(self, ext): + try: + yield + except (CCompilerError, DistutilsError, CompileError) as e: + if not ext.optional: + raise + self.warn('building extension "%s" failed: %s' % + (ext.name, e)) def build_extension(self, ext): sources = ext.sources @@ -511,15 +545,8 @@ def build_extension(self, ext): extra_postargs=extra_args, depends=ext.depends) - # XXX -- this is a Vile HACK! - # - # The setup.py script for Python on Unix needs to be able to - # get this list so it can perform all the clean up needed to - # avoid keeping object files around when cleaning out a failed - # build of an extension module. Since Distutils does not - # track dependencies, we have to get rid of intermediates to - # ensure all the intermediates will be properly re-built. - # + # XXX outdated variable, kept here in case third-part code + # needs it. self._built_objects = objects[:] # Now link the object files together into a "shared object" -- @@ -664,10 +691,7 @@ def get_ext_filename(self, ext_name): """ from distutils.sysconfig import get_config_var ext_path = ext_name.split('.') - # extensions in debug_mode are named 'module_d.pyd' under windows ext_suffix = get_config_var('EXT_SUFFIX') - if os.name == 'nt' and self.debug: - return os.path.join(*ext_path) + '_d' + ext_suffix return os.path.join(*ext_path) + ext_suffix def get_export_symbols(self, ext): diff --git a/Lib/distutils/command/check.py b/Lib/distutils/command/check.py index 22b9349dd605..7ebe707cff49 100644 --- a/Lib/distutils/command/check.py +++ b/Lib/distutils/command/check.py @@ -122,7 +122,7 @@ def _check_rst_data(self, data): """Returns warnings when the provided data doesn't compile.""" source_path = StringIO() parser = Parser() - settings = frontend.OptionParser().get_default_values() + settings = frontend.OptionParser(components=(Parser,)).get_default_values() settings.tab_width = 4 settings.pep_references = None settings.rfc_references = None @@ -138,8 +138,8 @@ def _check_rst_data(self, data): document.note_source(source_path, -1) try: parser.parse(data, document) - except AttributeError: - reporter.messages.append((-1, 'Could not finish the parsing.', - '', {})) + except AttributeError as e: + reporter.messages.append( + (-1, 'Could not finish the parsing: %s.' % e, '', {})) return reporter.messages diff --git a/Lib/distutils/command/install.py b/Lib/distutils/command/install.py index 456511cdfbc4..67db007a0247 100644 --- a/Lib/distutils/command/install.py +++ b/Lib/distutils/command/install.py @@ -15,32 +15,17 @@ from distutils.util import get_platform from distutils.errors import DistutilsOptionError -# this keeps compatibility from 2.3 to 2.5 -if sys.version < "2.6": - USER_BASE = None - USER_SITE = None - HAS_USER_SITE = False -else: - from site import USER_BASE - from site import USER_SITE - HAS_USER_SITE = True - -if sys.version < "2.2": - WINDOWS_SCHEME = { - 'purelib': '$base', - 'platlib': '$base', - 'headers': '$base/Include/$dist_name', - 'scripts': '$base/Scripts', - 'data' : '$base', - } -else: - WINDOWS_SCHEME = { - 'purelib': '$base/Lib/site-packages', - 'platlib': '$base/Lib/site-packages', - 'headers': '$base/Include/$dist_name', - 'scripts': '$base/Scripts', - 'data' : '$base', - } +from site import USER_BASE +from site import USER_SITE +HAS_USER_SITE = True + +WINDOWS_SCHEME = { + 'purelib': '$base/Lib/site-packages', + 'platlib': '$base/Lib/site-packages', + 'headers': '$base/Include/$dist_name', + 'scripts': '$base/Scripts', + 'data' : '$base', +} INSTALL_SCHEMES = { 'unix_prefix': { @@ -66,7 +51,7 @@ 'purelib': '$usersite', 'platlib': '$usersite', 'headers': '$userbase/Python$py_version_nodot/Include/$dist_name', - 'scripts': '$userbase/Scripts', + 'scripts': '$userbase/Python$py_version_nodot/Scripts', 'data' : '$userbase', } diff --git a/Lib/distutils/command/register.py b/Lib/distutils/command/register.py index 99545affa4a8..b49f86fe5814 100644 --- a/Lib/distutils/command/register.py +++ b/Lib/distutils/command/register.py @@ -87,7 +87,7 @@ def classifiers(self): ''' url = self.repository+'?:action=list_classifiers' response = urllib.request.urlopen(url) - log.info(response.read()) + log.info(self._read_pypi_response(response)) def verify_metadata(self): ''' Send the metadata to the package index server to be checked. @@ -300,5 +300,5 @@ def post_to_server(self, data, auth=None): result = 200, 'OK' if self.show_response: dashes = '-' * 75 - self.announce('%s%s%s' % (dashes, data, dashes)) + self.announce('%s%r%s' % (dashes, data, dashes)) return result diff --git a/Lib/distutils/command/upload.py b/Lib/distutils/command/upload.py index 287158343b8b..1c4fc48a1293 100644 --- a/Lib/distutils/command/upload.py +++ b/Lib/distutils/command/upload.py @@ -1,24 +1,21 @@ -"""distutils.command.upload +""" +distutils.command.upload -Implements the Distutils 'upload' subcommand (upload package to PyPI).""" +Implements the Distutils 'upload' subcommand (upload package to a package +index). +""" -from distutils.errors import * -from distutils.core import PyPIRCCommand -from distutils.spawn import spawn -from distutils import log -import sys -import os, io -import socket +import os +import io import platform +import hashlib from base64 import standard_b64encode from urllib.request import urlopen, Request, HTTPError from urllib.parse import urlparse - -# this keeps compatibility for 2.3 and 2.4 -if sys.version < "2.5": - from md5 import md5 -else: - from hashlib import md5 +from distutils.errors import DistutilsError, DistutilsOptionError +from distutils.core import PyPIRCCommand +from distutils.spawn import spawn +from distutils import log class upload(PyPIRCCommand): @@ -60,7 +57,8 @@ def finalize_options(self): def run(self): if not self.distribution.dist_files: - raise DistutilsOptionError("No dist file created in earlier command") + msg = "No dist file created in earlier command" + raise DistutilsOptionError(msg) for command, pyversion, filename in self.distribution.dist_files: self.upload_file(command, pyversion, filename) @@ -103,10 +101,10 @@ def upload_file(self, command, pyversion, filename): 'content': (os.path.basename(filename),content), 'filetype': command, 'pyversion': pyversion, - 'md5_digest': md5(content).hexdigest(), + 'md5_digest': hashlib.md5(content).hexdigest(), # additional meta-data - 'metadata_version' : '1.0', + 'metadata_version': '1.0', 'summary': meta.get_description(), 'home_page': meta.get_url(), 'author': meta.get_contact(), @@ -143,13 +141,13 @@ def upload_file(self, command, pyversion, filename): # Build up the MIME payload for the POST data boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254' - sep_boundary = b'\n--' + boundary.encode('ascii') - end_boundary = sep_boundary + b'--' + sep_boundary = b'\r\n--' + boundary.encode('ascii') + end_boundary = sep_boundary + b'--\r\n' body = io.BytesIO() for key, value in data.items(): - title = '\nContent-Disposition: form-data; name="%s"' % key + title = '\r\nContent-Disposition: form-data; name="%s"' % key # handle multiple entries for the same name - if type(value) != type([]): + if not isinstance(value, list): value = [value] for value in value: if type(value) is tuple: @@ -159,21 +157,22 @@ def upload_file(self, command, pyversion, filename): value = str(value).encode('utf-8') body.write(sep_boundary) body.write(title.encode('utf-8')) - body.write(b"\n\n") + body.write(b"\r\n\r\n") body.write(value) if value and value[-1:] == b'\r': body.write(b'\n') # write an extra newline (lurve Macs) body.write(end_boundary) - body.write(b"\n") body = body.getvalue() - self.announce("Submitting %s to %s" % (filename, self.repository), log.INFO) + msg = "Submitting %s to %s" % (filename, self.repository) + self.announce(msg, log.INFO) # build the Request - headers = {'Content-type': - 'multipart/form-data; boundary=%s' % boundary, - 'Content-length': str(len(body)), - 'Authorization': auth} + headers = { + 'Content-type': 'multipart/form-data; boundary=%s' % boundary, + 'Content-length': str(len(body)), + 'Authorization': auth, + } request = Request(self.repository, data=body, headers=headers) @@ -184,7 +183,7 @@ def upload_file(self, command, pyversion, filename): reason = result.msg except OSError as e: self.announce(str(e), log.ERROR) - return + raise except HTTPError as e: status = e.code reason = e.msg @@ -193,8 +192,10 @@ def upload_file(self, command, pyversion, filename): self.announce('Server response (%s): %s' % (status, reason), log.INFO) else: - self.announce('Upload failed (%s): %s' % (status, reason), - log.ERROR) + msg = 'Upload failed (%s): %s' % (status, reason) + self.announce(msg, log.ERROR) + raise DistutilsError(msg) if self.show_response: - msg = '\n'.join(('-' * 75, result.read(), '-' * 75)) + text = self._read_pypi_response(result) + msg = '\n'.join(('-' * 75, text, '-' * 75)) self.announce(msg, log.INFO) diff --git a/Lib/distutils/command/wininst-14.0-amd64.exe b/Lib/distutils/command/wininst-14.0-amd64.exe new file mode 100644 index 000000000000..43b85b6d4f2d Binary files /dev/null and b/Lib/distutils/command/wininst-14.0-amd64.exe differ diff --git a/Lib/distutils/command/wininst-14.0.exe b/Lib/distutils/command/wininst-14.0.exe new file mode 100644 index 000000000000..764524d746b3 Binary files /dev/null and b/Lib/distutils/command/wininst-14.0.exe differ diff --git a/Lib/distutils/config.py b/Lib/distutils/config.py index 7439a83a4f0d..382aca8fc12e 100644 --- a/Lib/distutils/config.py +++ b/Lib/distutils/config.py @@ -110,6 +110,13 @@ def _read_pypirc(self): return {} + def _read_pypi_response(self, response): + """Read and decode a PyPI HTTP response.""" + import cgi + content_type = response.getheader('content-type', 'text/plain') + encoding = cgi.parse_header(content_type)[1].get('charset', 'ascii') + return response.read().decode(encoding) + def initialize_options(self): """Initialize options.""" self.repository = None diff --git a/Lib/distutils/core.py b/Lib/distutils/core.py index c811d5bd9c46..2bfe66aa2f49 100644 --- a/Lib/distutils/core.py +++ b/Lib/distutils/core.py @@ -11,7 +11,6 @@ from distutils.debug import DEBUG from distutils.errors import * -from distutils.util import grok_environment_error # Mainly import these so setup scripts can "from distutils.core import" them. from distutils.dist import Distribution @@ -150,13 +149,11 @@ class found in 'cmdclass' is used in place of the default, which is except KeyboardInterrupt: raise SystemExit("interrupted") except OSError as exc: - error = grok_environment_error(exc) - if DEBUG: - sys.stderr.write(error + "\n") + sys.stderr.write("error: %s\n" % (exc,)) raise else: - raise SystemExit(error) + raise SystemExit("error: %s" % (exc,)) except (DistutilsError, CCompilerError) as msg: diff --git a/Lib/distutils/dir_util.py b/Lib/distutils/dir_util.py index 2b35aa318e05..d5cd8e3e24f4 100644 --- a/Lib/distutils/dir_util.py +++ b/Lib/distutils/dir_util.py @@ -2,7 +2,7 @@ Utility functions for manipulating directories and directory trees.""" -import os, sys +import os import errno from distutils.errors import DistutilsFileError, DistutilsInternalError from distutils import log @@ -81,7 +81,7 @@ def create_tree(base_dir, files, mode=0o777, verbose=1, dry_run=0): """Create all the empty directories under 'base_dir' needed to put 'files' there. - 'base_dir' is just the a name of a directory which doesn't necessarily + 'base_dir' is just the name of a directory which doesn't necessarily exist yet; 'files' is a list of filenames to be interpreted relative to 'base_dir'. 'base_dir' + the directory portion of every file in 'files' will be created if it doesn't already exist. 'mode', 'verbose' and @@ -125,12 +125,11 @@ def copy_tree(src, dst, preserve_mode=1, preserve_times=1, try: names = os.listdir(src) except OSError as e: - (errno, errstr) = e if dry_run: names = [] else: raise DistutilsFileError( - "error listing files in '%s': %s" % (src, errstr)) + "error listing files in '%s': %s" % (src, e.strerror)) if not dry_run: mkpath(dst, verbose=verbose) @@ -182,7 +181,6 @@ def remove_tree(directory, verbose=1, dry_run=0): Any errors are ignored (apart from being reported to stdout if 'verbose' is true). """ - from distutils.util import grok_environment_error global _path_created if verbose >= 1: @@ -199,8 +197,7 @@ def remove_tree(directory, verbose=1, dry_run=0): if abspath in _path_created: del _path_created[abspath] except OSError as exc: - log.warn(grok_environment_error( - exc, "error removing %s: " % directory)) + log.warn("error removing %s: %s", directory, exc) def ensure_relative(path): """Take the full path 'path', and make it a relative path. diff --git a/Lib/distutils/dist.py b/Lib/distutils/dist.py index 7eb04bc3f598..ffb33ff645a8 100644 --- a/Lib/distutils/dist.py +++ b/Lib/distutils/dist.py @@ -4,7 +4,9 @@ being built/installed/distributed. """ -import sys, os, re +import sys +import os +import re from email import message_from_file try: @@ -22,7 +24,7 @@ # the same as a Python NAME -- I don't allow leading underscores. The fact # that they're very similar is no coincidence; the default naming scheme is # to look for a Python module named after the command. -command_re = re.compile (r'^[a-zA-Z]([a-zA-Z0-9_]*)$') +command_re = re.compile(r'^[a-zA-Z]([a-zA-Z0-9_]*)$') class Distribution: @@ -39,7 +41,6 @@ class Distribution: See the code for 'setup()', in core.py, for details. """ - # 'global_options' describes the command-line options that may be # supplied to the setup script prior to any actual commands. # Eg. "./setup.py -n" or "./setup.py --quiet" both take advantage of @@ -48,12 +49,13 @@ class Distribution: # don't want to pollute the commands with too many options that they # have minimal control over. # The fourth entry for verbose means that it can be repeated. - global_options = [('verbose', 'v', "run verbosely (default)", 1), - ('quiet', 'q', "run quietly (turns verbosity off)"), - ('dry-run', 'n', "don't actually do anything"), - ('help', 'h', "show detailed help message"), - ('no-user-cfg', None, - 'ignore pydistutils.cfg in your home directory'), + global_options = [ + ('verbose', 'v', "run verbosely (default)", 1), + ('quiet', 'q', "run quietly (turns verbosity off)"), + ('dry-run', 'n', "don't actually do anything"), + ('help', 'h', "show detailed help message"), + ('no-user-cfg', None, + 'ignore pydistutils.cfg in your home directory'), ] # 'common_usage' is a short (2-3 line) string describing the common @@ -115,10 +117,9 @@ class Distribution: # negative options are options that exclude other options negative_opt = {'quiet': 'verbose'} - # -- Creation/initialization methods ------------------------------- - def __init__ (self, attrs=None): + def __init__(self, attrs=None): """Construct a new Distribution instance: initialize all the attributes of a Distribution, and then use 'attrs' (a dictionary mapping attribute names to values) to assign some of those @@ -532,15 +533,15 @@ def _parse_command_opts(self, parser, args): # to be sure that the basic "command" interface is implemented. if not issubclass(cmd_class, Command): raise DistutilsClassError( - "command class %s must subclass Command" % cmd_class) + "command class %s must subclass Command" % cmd_class) # Also make sure that the command object provides a list of its # known options. if not (hasattr(cmd_class, 'user_options') and isinstance(cmd_class.user_options, list)): - raise DistutilsClassError(("command class %s must provide " + - "'user_options' attribute (a list of tuples)") % \ - cmd_class) + msg = ("command class %s must provide " + "'user_options' attribute (a list of tuples)") + raise DistutilsClassError(msg % cmd_class) # If the command class has a list of negative alias options, # merge it in with the global negative aliases. @@ -552,12 +553,11 @@ def _parse_command_opts(self, parser, args): # Check for help_options in command class. They have a different # format (tuple of four) so we need to preprocess them here. if (hasattr(cmd_class, 'help_options') and - isinstance(cmd_class.help_options, list)): + isinstance(cmd_class.help_options, list)): help_options = fix_help_options(cmd_class.help_options) else: help_options = [] - # All commands support the global options too, just by adding # in 'global_options'. parser.set_option_table(self.global_options + @@ -570,7 +570,7 @@ def _parse_command_opts(self, parser, args): return if (hasattr(cmd_class, 'help_options') and - isinstance(cmd_class.help_options, list)): + isinstance(cmd_class.help_options, list)): help_option_found=0 for (help_option, short, desc, func) in cmd_class.help_options: if hasattr(opts, parser.get_attr_name(help_option)): @@ -647,7 +647,7 @@ def _show_help(self, parser, global_options=1, display_options=1, else: klass = self.get_command_class(command) if (hasattr(klass, 'help_options') and - isinstance(klass.help_options, list)): + isinstance(klass.help_options, list)): parser.set_option_table(klass.user_options + fix_help_options(klass.help_options)) else: @@ -814,7 +814,7 @@ def get_command_class(self, command): klass_name = command try: - __import__ (module_name) + __import__(module_name) module = sys.modules[module_name] except ImportError: continue @@ -823,8 +823,8 @@ def get_command_class(self, command): klass = getattr(module, klass_name) except AttributeError: raise DistutilsModuleError( - "invalid command '%s' (no class '%s' in module '%s')" - % (command, klass_name, module_name)) + "invalid command '%s' (no class '%s' in module '%s')" + % (command, klass_name, module_name)) self.cmdclass[command] = klass return klass @@ -840,7 +840,7 @@ def get_command_obj(self, command, create=1): cmd_obj = self.command_obj.get(command) if not cmd_obj and create: if DEBUG: - self.announce("Distribution.get_command_obj(): " \ + self.announce("Distribution.get_command_obj(): " "creating '%s' command object" % command) klass = self.get_command_class(command) @@ -897,8 +897,8 @@ def _set_command_options(self, command_obj, option_dict=None): setattr(command_obj, option, value) else: raise DistutilsOptionError( - "error in %s: command '%s' has no such option '%s'" - % (source, command_name, option)) + "error in %s: command '%s' has no such option '%s'" + % (source, command_name, option)) except ValueError as msg: raise DistutilsOptionError(msg) @@ -974,7 +974,6 @@ def run_command(self, command): cmd_obj.run() self.have_run[command] = 1 - # -- Distribution query methods ------------------------------------ def has_pure_modules(self): @@ -1112,17 +1111,17 @@ def write_pkg_file(self, file): """ version = '1.0' if (self.provides or self.requires or self.obsoletes or - self.classifiers or self.download_url): + self.classifiers or self.download_url): version = '1.1' file.write('Metadata-Version: %s\n' % version) - file.write('Name: %s\n' % self.get_name() ) - file.write('Version: %s\n' % self.get_version() ) - file.write('Summary: %s\n' % self.get_description() ) - file.write('Home-page: %s\n' % self.get_url() ) - file.write('Author: %s\n' % self.get_contact() ) - file.write('Author-email: %s\n' % self.get_contact_email() ) - file.write('License: %s\n' % self.get_license() ) + file.write('Name: %s\n' % self.get_name()) + file.write('Version: %s\n' % self.get_version()) + file.write('Summary: %s\n' % self.get_description()) + file.write('Home-page: %s\n' % self.get_url()) + file.write('Author: %s\n' % self.get_contact()) + file.write('Author-email: %s\n' % self.get_contact_email()) + file.write('License: %s\n' % self.get_license()) if self.download_url: file.write('Download-URL: %s\n' % self.download_url) @@ -1131,7 +1130,7 @@ def write_pkg_file(self, file): keywords = ','.join(self.get_keywords()) if keywords: - file.write('Keywords: %s\n' % keywords ) + file.write('Keywords: %s\n' % keywords) self._write_list(file, 'Platform', self.get_platforms()) self._write_list(file, 'Classifier', self.get_classifiers()) diff --git a/Lib/distutils/extension.py b/Lib/distutils/extension.py index a93655af2cf8..7efbb74f8953 100644 --- a/Lib/distutils/extension.py +++ b/Lib/distutils/extension.py @@ -131,6 +131,14 @@ def __init__(self, name, sources, msg = "Unknown Extension options: %s" % options warnings.warn(msg) + def __repr__(self): + return '<%s.%s(%r) at %#x>' % ( + self.__class__.__module__, + self.__class__.__qualname__, + self.name, + id(self)) + + def read_setup_file(filename): """Reads a Setup file and returns Extension instances.""" from distutils.sysconfig import (parse_makefile, expand_makefile_vars, diff --git a/Lib/distutils/file_util.py b/Lib/distutils/file_util.py index f6ed290f137d..b3fee35a6cce 100644 --- a/Lib/distutils/file_util.py +++ b/Lib/distutils/file_util.py @@ -80,7 +80,8 @@ def copy_file(src, dst, preserve_mode=1, preserve_times=1, update=0, (os.symlink) instead of copying: set it to "hard" or "sym"; if it is None (the default), files are copied. Don't set 'link' on systems that don't support it: 'copy_file()' doesn't check if hard or symbolic - linking is available. + linking is available. If hardlink fails, falls back to + _copy_file_contents(). Under Mac OS, uses the native file copy function in macostools; on other systems, uses '_copy_file_contents()' to copy file contents. @@ -132,24 +133,31 @@ def copy_file(src, dst, preserve_mode=1, preserve_times=1, update=0, # (Unix only, of course, but that's the caller's responsibility) elif link == 'hard': if not (os.path.exists(dst) and os.path.samefile(src, dst)): - os.link(src, dst) + try: + os.link(src, dst) + return (dst, 1) + except OSError: + # If hard linking fails, fall back on copying file + # (some special filesystems don't support hard linking + # even under Unix, see issue #8876). + pass elif link == 'sym': if not (os.path.exists(dst) and os.path.samefile(src, dst)): os.symlink(src, dst) + return (dst, 1) # Otherwise (non-Mac, not linking), copy the file contents and # (optionally) copy the times and mode. - else: - _copy_file_contents(src, dst) - if preserve_mode or preserve_times: - st = os.stat(src) + _copy_file_contents(src, dst) + if preserve_mode or preserve_times: + st = os.stat(src) - # According to David Ascher <da@ski.org>, utime() should be done - # before chmod() (at least under NT). - if preserve_times: - os.utime(dst, (st[ST_ATIME], st[ST_MTIME])) - if preserve_mode: - os.chmod(dst, S_IMODE(st[ST_MODE])) + # According to David Ascher <da@ski.org>, utime() should be done + # before chmod() (at least under NT). + if preserve_times: + os.utime(dst, (st[ST_ATIME], st[ST_MTIME])) + if preserve_mode: + os.chmod(dst, S_IMODE(st[ST_MODE])) return (dst, 1) @@ -194,7 +202,7 @@ def move_file (src, dst, try: os.rename(src, dst) except OSError as e: - (num, msg) = e + (num, msg) = e.args if num == errno.EXDEV: copy_it = True else: @@ -206,7 +214,7 @@ def move_file (src, dst, try: os.unlink(src) except OSError as e: - (num, msg) = e + (num, msg) = e.args try: os.unlink(dst) except OSError: diff --git a/Lib/distutils/msvc9compiler.py b/Lib/distutils/msvc9compiler.py index 9688f20019c8..d1374efe1391 100644 --- a/Lib/distutils/msvc9compiler.py +++ b/Lib/distutils/msvc9compiler.py @@ -179,6 +179,9 @@ def get_build_version(): i = i + len(prefix) s, rest = sys.version[i:].split(" ", 1) majorVersion = int(s[:-2]) - 6 + if majorVersion >= 13: + # v13 was skipped and should be v14 + majorVersion += 1 minorVersion = int(s[2:3]) / 10.0 # I don't think paths are affected by minor version in version 6 if majorVersion == 6: diff --git a/Lib/distutils/msvccompiler.py b/Lib/distutils/msvccompiler.py index 81166569619b..1048cd415939 100644 --- a/Lib/distutils/msvccompiler.py +++ b/Lib/distutils/msvccompiler.py @@ -157,6 +157,9 @@ def get_build_version(): i = i + len(prefix) s, rest = sys.version[i:].split(" ", 1) majorVersion = int(s[:-2]) - 6 + if majorVersion >= 13: + # v13 was skipped and should be v14 + majorVersion += 1 minorVersion = int(s[2:3]) / 10.0 # I don't think paths are affected by minor version in version 6 if majorVersion == 6: diff --git a/Lib/distutils/spawn.py b/Lib/distutils/spawn.py index b1c5a442a5da..5dd415a283d1 100644 --- a/Lib/distutils/spawn.py +++ b/Lib/distutils/spawn.py @@ -10,6 +10,7 @@ import os from distutils.errors import DistutilsPlatformError, DistutilsExecError +from distutils.debug import DEBUG from distutils import log def spawn(cmd, search_path=1, verbose=0, dry_run=0): @@ -28,6 +29,9 @@ def spawn(cmd, search_path=1, verbose=0, dry_run=0): Raise DistutilsExecError if running the program fails in any way; just return on success. """ + # cmd is documented as a list, but just in case some code passes a tuple + # in, protect our %-formatting code against horrible death + cmd = list(cmd) if os.name == 'posix': _spawn_posix(cmd, search_path, dry_run=dry_run) elif os.name == 'nt': @@ -65,12 +69,16 @@ def _spawn_nt(cmd, search_path=1, verbose=0, dry_run=0): rc = os.spawnv(os.P_WAIT, executable, cmd) except OSError as exc: # this seems to happen when the command isn't found + if not DEBUG: + cmd = executable raise DistutilsExecError( - "command '%s' failed: %s" % (cmd[0], exc.args[-1])) + "command %r failed: %s" % (cmd, exc.args[-1])) if rc != 0: # and this reflects the command running but failing + if not DEBUG: + cmd = executable raise DistutilsExecError( - "command '%s' failed with exit status %d" % (cmd[0], rc)) + "command %r failed with exit status %d" % (cmd, rc)) if sys.platform == 'darwin': from distutils import sysconfig @@ -81,8 +89,9 @@ def _spawn_posix(cmd, search_path=1, verbose=0, dry_run=0): log.info(' '.join(cmd)) if dry_run: return + executable = cmd[0] exec_fn = search_path and os.execvp or os.execv - exec_args = [cmd[0], cmd] + env = None if sys.platform == 'darwin': global _cfg_target, _cfg_target_split if _cfg_target is None: @@ -103,17 +112,23 @@ def _spawn_posix(cmd, search_path=1, verbose=0, dry_run=0): env = dict(os.environ, MACOSX_DEPLOYMENT_TARGET=cur_target) exec_fn = search_path and os.execvpe or os.execve - exec_args.append(env) pid = os.fork() if pid == 0: # in the child try: - exec_fn(*exec_args) + if env is None: + exec_fn(executable, cmd) + else: + exec_fn(executable, cmd, env) except OSError as e: - sys.stderr.write("unable to execute %s: %s\n" - % (cmd[0], e.strerror)) + if not DEBUG: + cmd = executable + sys.stderr.write("unable to execute %r: %s\n" + % (cmd, e.strerror)) os._exit(1) - sys.stderr.write("unable to execute %s for unknown reasons" % cmd[0]) + if not DEBUG: + cmd = executable + sys.stderr.write("unable to execute %r for unknown reasons" % cmd) os._exit(1) else: # in the parent # Loop until the child either exits or is terminated by a signal @@ -122,29 +137,34 @@ def _spawn_posix(cmd, search_path=1, verbose=0, dry_run=0): try: pid, status = os.waitpid(pid, 0) except OSError as exc: - import errno - if exc.errno == errno.EINTR: - continue + if not DEBUG: + cmd = executable raise DistutilsExecError( - "command '%s' failed: %s" % (cmd[0], exc.args[-1])) + "command %r failed: %s" % (cmd, exc.args[-1])) if os.WIFSIGNALED(status): + if not DEBUG: + cmd = executable raise DistutilsExecError( - "command '%s' terminated by signal %d" - % (cmd[0], os.WTERMSIG(status))) + "command %r terminated by signal %d" + % (cmd, os.WTERMSIG(status))) elif os.WIFEXITED(status): exit_status = os.WEXITSTATUS(status) if exit_status == 0: return # hey, it succeeded! else: + if not DEBUG: + cmd = executable raise DistutilsExecError( - "command '%s' failed with exit status %d" - % (cmd[0], exit_status)) + "command %r failed with exit status %d" + % (cmd, exit_status)) elif os.WIFSTOPPED(status): continue else: + if not DEBUG: + cmd = executable raise DistutilsExecError( - "unknown error executing '%s': termination status %d" - % (cmd[0], status)) + "unknown error executing %r: termination status %d" + % (cmd, status)) def find_executable(executable, path=None): """Tries to find 'executable' in the directories listed in 'path'. diff --git a/Lib/distutils/sysconfig.py b/Lib/distutils/sysconfig.py index 75537db8d06d..573724ddd778 100644 --- a/Lib/distutils/sysconfig.py +++ b/Lib/distutils/sysconfig.py @@ -9,6 +9,7 @@ Email: <fdrake@acm.org> """ +import _imp import os import re import sys @@ -22,23 +23,15 @@ BASE_EXEC_PREFIX = os.path.normpath(sys.base_exec_prefix) # Path to the base directory of the project. On Windows the binary may -# live in project/PCBuild9. If we're dealing with an x64 Windows build, -# it'll live in project/PCbuild/amd64. +# live in project/PCBuild/win32 or project/PCBuild/amd64. # set for cross builds if "_PYTHON_PROJECT_BASE" in os.environ: project_base = os.path.abspath(os.environ["_PYTHON_PROJECT_BASE"]) else: project_base = os.path.dirname(os.path.abspath(sys.executable)) -if os.name == "nt" and "pcbuild" in project_base[-8:].lower(): - project_base = os.path.abspath(os.path.join(project_base, os.path.pardir)) -# PC/VS7.1 -if os.name == "nt" and "\\pc\\v" in project_base[-10:].lower(): - project_base = os.path.abspath(os.path.join(project_base, os.path.pardir, - os.path.pardir)) -# PC/AMD64 -if os.name == "nt" and "\\pcbuild\\amd64" in project_base[-14:].lower(): - project_base = os.path.abspath(os.path.join(project_base, os.path.pardir, - os.path.pardir)) +if (os.name == 'nt' and + project_base.lower().endswith(('\\pcbuild\\win32', '\\pcbuild\\amd64'))): + project_base = os.path.dirname(os.path.dirname(project_base)) # python_build: (Boolean) if true, we're either building Python or # building an extension with an un-installed Python, so we use @@ -51,11 +44,9 @@ def _is_python_source_dir(d): return True return False _sys_home = getattr(sys, '_home', None) -if _sys_home and os.name == 'nt' and \ - _sys_home.lower().endswith(('pcbuild', 'pcbuild\\amd64')): - _sys_home = os.path.dirname(_sys_home) - if _sys_home.endswith('pcbuild'): # must be amd64 - _sys_home = os.path.dirname(_sys_home) +if (_sys_home and os.name == 'nt' and + _sys_home.lower().endswith(('\\pcbuild\\win32', '\\pcbuild\\amd64'))): + _sys_home = os.path.dirname(os.path.dirname(_sys_home)) def _python_build(): if _sys_home: return _is_python_source_dir(_sys_home) @@ -151,10 +142,7 @@ def get_python_lib(plat_specific=0, standard_lib=0, prefix=None): if standard_lib: return os.path.join(prefix, "Lib") else: - if get_python_version() < "2.2": - return prefix - else: - return os.path.join(prefix, "Lib", "site-packages") + return os.path.join(prefix, "Lib", "site-packages") else: raise DistutilsPlatformError( "I don't know where Python installs its library " @@ -179,7 +167,8 @@ def customize_compiler(compiler): # version and build tools may not support the same set # of CPU architectures for universal builds. global _config_vars - if not _config_vars.get('CUSTOMIZED_OSX_COMPILER', ''): + # Use get_config_var() to ensure _config_vars is initialized. + if not get_config_var('CUSTOMIZED_OSX_COMPILER'): import _osx_support _osx_support.customize_compiler(_config_vars) _config_vars['CUSTOMIZED_OSX_COMPILER'] = 'True' @@ -243,12 +232,8 @@ def get_config_h_filename(): inc_dir = _sys_home or project_base else: inc_dir = get_python_inc(plat_specific=1) - if get_python_version() < '2.2': - config_h = 'config.h' - else: - # The name of the config.h file changed in 2.2 - config_h = 'pyconfig.h' - return os.path.join(inc_dir, config_h) + + return os.path.join(inc_dir, 'pyconfig.h') def get_makefile_filename(): @@ -460,17 +445,6 @@ def _init_posix(): if python_build: g['LDSHARED'] = g['BLDSHARED'] - elif get_python_version() < '2.1': - # The following two branches are for 1.5.2 compatibility. - if sys.platform == 'aix4': # what about AIX 3.x ? - # Linker script is in the config directory, not in Modules as the - # Makefile says. - python_lib = get_python_lib(standard_lib=1) - ld_so_aix = os.path.join(python_lib, 'config', 'ld_so_aix') - python_exp = os.path.join(python_lib, 'config', 'python.exp') - - g['LDSHARED'] = "%s %s -bI:%s" % (ld_so_aix, g['CC'], python_exp) - global _config_vars _config_vars = g @@ -485,7 +459,7 @@ def _init_nt(): # XXX hmmm.. a normal install puts include files here g['INCLUDEPY'] = get_python_inc(plat_specific=0) - g['EXT_SUFFIX'] = '.pyd' + g['EXT_SUFFIX'] = _imp.extension_suffixes()[0] g['EXE'] = ".exe" g['VERSION'] = get_python_version().replace(".", "") g['BINDIR'] = os.path.dirname(os.path.abspath(sys.executable)) diff --git a/Lib/distutils/tests/support.py b/Lib/distutils/tests/support.py index 84d92323284f..7385c6bbf671 100644 --- a/Lib/distutils/tests/support.py +++ b/Lib/distutils/tests/support.py @@ -32,14 +32,15 @@ def tearDown(self): def _log(self, level, msg, args): if level not in (DEBUG, INFO, WARN, ERROR, FATAL): raise ValueError('%s wrong log level' % str(level)) + if not isinstance(msg, str): + raise TypeError("msg should be str, not '%.200s'" + % (type(msg).__name__)) self.logs.append((level, msg, args)) def get_logs(self, *levels): def _format(msg, args): - if len(args) == 0: - return msg return msg % args - return [_format(msg, args) for level, msg, args + return [msg % args for level, msg, args in self.logs if level in levels] def clear_logs(self): @@ -206,4 +207,4 @@ def fixup_build_ext(cmd): cmd.library_dirs = [] else: name, equals, value = runshared.partition('=') - cmd.library_dirs = value.split(os.pathsep) + cmd.library_dirs = [d for d in value.split(os.pathsep) if d] diff --git a/Lib/distutils/tests/test_archive_util.py b/Lib/distutils/tests/test_archive_util.py index 6b42c5a213a5..2d72af4aa6f4 100644 --- a/Lib/distutils/tests/test_archive_util.py +++ b/Lib/distutils/tests/test_archive_util.py @@ -308,7 +308,7 @@ def test_make_archive_owner_group(self): owner='kjhkjhkjg', group='oihohoh') self.assertTrue(os.path.exists(res)) - @unittest.skipUnless(zlib, "Requires zlib") + @unittest.skipUnless(ZLIB_SUPPORT, "Requires zlib") @unittest.skipUnless(UID_GID_SUPPORT, "Requires grp and pwd support") def test_tarfile_root_owner(self): tmpdir, tmpdir2, base_name = self._create_files() diff --git a/Lib/distutils/tests/test_bdist_rpm.py b/Lib/distutils/tests/test_bdist_rpm.py index aa1445d10aa5..25c14abd322c 100644 --- a/Lib/distutils/tests/test_bdist_rpm.py +++ b/Lib/distutils/tests/test_bdist_rpm.py @@ -24,6 +24,7 @@ """ class BuildRpmTestCase(support.TempdirManager, + support.EnvironGuard, support.LoggingSilencer, unittest.TestCase): @@ -43,20 +44,18 @@ def tearDown(self): sys.argv[:] = self.old_sys_argv[1] super(BuildRpmTestCase, self).tearDown() + # XXX I am unable yet to make this test work without + # spurious sdtout/stderr output under Mac OS X + @unittest.skipUnless(sys.platform.startswith('linux'), + 'spurious sdtout/stderr output under Mac OS X') + @unittest.skipIf(find_executable('rpm') is None, + 'the rpm command is not found') + @unittest.skipIf(find_executable('rpmbuild') is None, + 'the rpmbuild command is not found') def test_quiet(self): - - # XXX I am unable yet to make this test work without - # spurious sdtout/stderr output under Mac OS X - if not sys.platform.startswith('linux'): - return - - # this test will run only if the rpm commands are found - if (find_executable('rpm') is None or - find_executable('rpmbuild') is None): - return - # let's create a package tmp_dir = self.mkdtemp() + os.environ['HOME'] = tmp_dir # to confine dir '.rpmdb' creation pkg_dir = os.path.join(tmp_dir, 'foo') os.mkdir(pkg_dir) self.write_file((pkg_dir, 'setup.py'), SETUP_PY) @@ -87,21 +86,19 @@ def test_quiet(self): self.assertIn(('bdist_rpm', 'any', 'dist/foo-0.1-1.src.rpm'), dist.dist_files) self.assertIn(('bdist_rpm', 'any', 'dist/foo-0.1-1.noarch.rpm'), dist.dist_files) + # XXX I am unable yet to make this test work without + # spurious sdtout/stderr output under Mac OS X + @unittest.skipUnless(sys.platform.startswith('linux'), + 'spurious sdtout/stderr output under Mac OS X') + # http://bugs.python.org/issue1533164 + @unittest.skipIf(find_executable('rpm') is None, + 'the rpm command is not found') + @unittest.skipIf(find_executable('rpmbuild') is None, + 'the rpmbuild command is not found') def test_no_optimize_flag(self): - - # XXX I am unable yet to make this test work without - # spurious sdtout/stderr output under Mac OS X - if not sys.platform.startswith('linux'): - return - - # http://bugs.python.org/issue1533164 - # this test will run only if the rpm command is found - if (find_executable('rpm') is None or - find_executable('rpmbuild') is None): - return - # let's create a package that brakes bdist_rpm tmp_dir = self.mkdtemp() + os.environ['HOME'] = tmp_dir # to confine dir '.rpmdb' creation pkg_dir = os.path.join(tmp_dir, 'foo') os.mkdir(pkg_dir) self.write_file((pkg_dir, 'setup.py'), SETUP_PY) diff --git a/Lib/distutils/tests/test_build_clib.py b/Lib/distutils/tests/test_build_clib.py index c2b981f20eb9..acc99e78c18f 100644 --- a/Lib/distutils/tests/test_build_clib.py +++ b/Lib/distutils/tests/test_build_clib.py @@ -102,11 +102,8 @@ def test_finalize_options(self): cmd.distribution.libraries = 'WONTWORK' self.assertRaises(DistutilsSetupError, cmd.finalize_options) + @unittest.skipIf(sys.platform == 'win32', "can't test on Windows") def test_run(self): - # can't test on windows - if sys.platform == 'win32': - return - pkg_dir, dist = self.create_dist() cmd = build_clib(dist) @@ -131,7 +128,7 @@ def test_run(self): if ccmd is None: continue if find_executable(ccmd[0]) is None: - return # can't test + self.skipTest('The %r command is not found' % ccmd[0]) # this should work cmd.run() diff --git a/Lib/distutils/tests/test_build_ext.py b/Lib/distutils/tests/test_build_ext.py index 3cfaa2c6928d..366ffbec9f81 100644 --- a/Lib/distutils/tests/test_build_ext.py +++ b/Lib/distutils/tests/test_build_ext.py @@ -31,12 +31,14 @@ def setUp(self): self.tmp_dir = self.mkdtemp() self.sys_path = sys.path, sys.path[:] sys.path.append(self.tmp_dir) - if sys.version > "2.6": - import site - self.old_user_base = site.USER_BASE - site.USER_BASE = self.mkdtemp() - from distutils.command import build_ext - build_ext.USER_BASE = site.USER_BASE + import site + self.old_user_base = site.USER_BASE + site.USER_BASE = self.mkdtemp() + from distutils.command import build_ext + build_ext.USER_BASE = site.USER_BASE + + def build_ext(self, *args, **kwargs): + return build_ext(*args, **kwargs) def test_build_ext(self): global ALREADY_TESTED @@ -45,7 +47,7 @@ def test_build_ext(self): xx_ext = Extension('xx', [xx_c]) dist = Distribution({'name': 'xx', 'ext_modules': [xx_ext]}) dist.package_dir = self.tmp_dir - cmd = build_ext(dist) + cmd = self.build_ext(dist) fixup_build_ext(cmd) cmd.build_lib = self.tmp_dir cmd.build_temp = self.tmp_dir @@ -61,9 +63,9 @@ def test_build_ext(self): sys.stdout = old_stdout if ALREADY_TESTED: - return + self.skipTest('Already tested in %s' % ALREADY_TESTED) else: - ALREADY_TESTED = True + ALREADY_TESTED = type(self).__name__ import xx @@ -84,16 +86,15 @@ def tearDown(self): support.unload('xx') sys.path = self.sys_path[0] sys.path[:] = self.sys_path[1] - if sys.version > "2.6": - import site - site.USER_BASE = self.old_user_base - from distutils.command import build_ext - build_ext.USER_BASE = self.old_user_base + import site + site.USER_BASE = self.old_user_base + from distutils.command import build_ext + build_ext.USER_BASE = self.old_user_base super(BuildExtTestCase, self).tearDown() def test_solaris_enable_shared(self): dist = Distribution({'name': 'xx'}) - cmd = build_ext(dist) + cmd = self.build_ext(dist) old = sys.platform sys.platform = 'sunos' # fooling finalize_options @@ -113,13 +114,9 @@ def test_solaris_enable_shared(self): self.assertGreater(len(cmd.library_dirs), 0) def test_user_site(self): - # site.USER_SITE was introduced in 2.6 - if sys.version < '2.6': - return - import site dist = Distribution({'name': 'xx'}) - cmd = build_ext(dist) + cmd = self.build_ext(dist) # making sure the user option is there options = [name for name, short, lable in @@ -150,14 +147,14 @@ def test_optional_extension(self): # with the optional argument. modules = [Extension('foo', ['xxx'], optional=False)] dist = Distribution({'name': 'xx', 'ext_modules': modules}) - cmd = build_ext(dist) + cmd = self.build_ext(dist) cmd.ensure_finalized() self.assertRaises((UnknownFileError, CompileError), cmd.run) # should raise an error modules = [Extension('foo', ['xxx'], optional=True)] dist = Distribution({'name': 'xx', 'ext_modules': modules}) - cmd = build_ext(dist) + cmd = self.build_ext(dist) cmd.ensure_finalized() cmd.run() # should pass @@ -166,7 +163,7 @@ def test_finalize_options(self): # etc.) are in the include search path. modules = [Extension('foo', ['xxx'], optional=False)] dist = Distribution({'name': 'xx', 'ext_modules': modules}) - cmd = build_ext(dist) + cmd = self.build_ext(dist) cmd.finalize_options() from distutils import sysconfig @@ -178,14 +175,14 @@ def test_finalize_options(self): # make sure cmd.libraries is turned into a list # if it's a string - cmd = build_ext(dist) + cmd = self.build_ext(dist) cmd.libraries = 'my_lib, other_lib lastlib' cmd.finalize_options() self.assertEqual(cmd.libraries, ['my_lib', 'other_lib', 'lastlib']) # make sure cmd.library_dirs is turned into a list # if it's a string - cmd = build_ext(dist) + cmd = self.build_ext(dist) cmd.library_dirs = 'my_lib_dir%sother_lib_dir' % os.pathsep cmd.finalize_options() self.assertIn('my_lib_dir', cmd.library_dirs) @@ -193,7 +190,7 @@ def test_finalize_options(self): # make sure rpath is turned into a list # if it's a string - cmd = build_ext(dist) + cmd = self.build_ext(dist) cmd.rpath = 'one%stwo' % os.pathsep cmd.finalize_options() self.assertEqual(cmd.rpath, ['one', 'two']) @@ -202,32 +199,32 @@ def test_finalize_options(self): # make sure define is turned into 2-tuples # strings if they are ','-separated strings - cmd = build_ext(dist) + cmd = self.build_ext(dist) cmd.define = 'one,two' cmd.finalize_options() self.assertEqual(cmd.define, [('one', '1'), ('two', '1')]) # make sure undef is turned into a list of # strings if they are ','-separated strings - cmd = build_ext(dist) + cmd = self.build_ext(dist) cmd.undef = 'one,two' cmd.finalize_options() self.assertEqual(cmd.undef, ['one', 'two']) # make sure swig_opts is turned into a list - cmd = build_ext(dist) + cmd = self.build_ext(dist) cmd.swig_opts = None cmd.finalize_options() self.assertEqual(cmd.swig_opts, []) - cmd = build_ext(dist) + cmd = self.build_ext(dist) cmd.swig_opts = '1 2' cmd.finalize_options() self.assertEqual(cmd.swig_opts, ['1', '2']) def test_check_extensions_list(self): dist = Distribution() - cmd = build_ext(dist) + cmd = self.build_ext(dist) cmd.finalize_options() #'extensions' option must be a list of Extension instances @@ -276,7 +273,7 @@ def test_check_extensions_list(self): def test_get_source_files(self): modules = [Extension('foo', ['xxx'], optional=False)] dist = Distribution({'name': 'xx', 'ext_modules': modules}) - cmd = build_ext(dist) + cmd = self.build_ext(dist) cmd.ensure_finalized() self.assertEqual(cmd.get_source_files(), ['xxx']) @@ -285,7 +282,7 @@ def test_compiler_option(self): # should not be overriden by a compiler instance # when the command is run dist = Distribution() - cmd = build_ext(dist) + cmd = self.build_ext(dist) cmd.compiler = 'unix' cmd.ensure_finalized() cmd.run() @@ -298,7 +295,7 @@ def test_get_outputs(self): ext = Extension('foo', [c_file], optional=False) dist = Distribution({'name': 'xx', 'ext_modules': [ext]}) - cmd = build_ext(dist) + cmd = self.build_ext(dist) fixup_build_ext(cmd) cmd.ensure_finalized() self.assertEqual(len(cmd.get_outputs()), 1) @@ -361,7 +358,7 @@ def test_ext_fullpath(self): #etree_ext = Extension('lxml.etree', [etree_c]) #dist = Distribution({'name': 'lxml', 'ext_modules': [etree_ext]}) dist = Distribution() - cmd = build_ext(dist) + cmd = self.build_ext(dist) cmd.inplace = 1 cmd.distribution.package_dir = {'': 'src'} cmd.distribution.packages = ['lxml', 'lxml.html'] @@ -448,8 +445,16 @@ def _try_compile_deployment_target(self, operator, target): # get the deployment target that the interpreter was built with target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') - target = tuple(map(int, target.split('.'))) - target = '%02d%01d0' % target + target = tuple(map(int, target.split('.')[0:2])) + # format the target value as defined in the Apple + # Availability Macros. We can't use the macro names since + # at least one value we test with will not exist yet. + if target[1] < 10: + # for 10.1 through 10.9.x -> "10n0" + target = '%02d%01d0' % target + else: + # for 10.10 and beyond -> "10nn00" + target = '%02d%02d00' % target deptarget_ext = Extension( 'deptarget', [deptarget_c], @@ -460,7 +465,7 @@ def _try_compile_deployment_target(self, operator, target): 'ext_modules': [deptarget_ext] }) dist.package_dir = self.tmp_dir - cmd = build_ext(dist) + cmd = self.build_ext(dist) cmd.build_lib = self.tmp_dir cmd.build_temp = self.tmp_dir @@ -479,8 +484,19 @@ def _try_compile_deployment_target(self, operator, target): self.fail("Wrong deployment target during compilation") +class ParallelBuildExtTestCase(BuildExtTestCase): + + def build_ext(self, *args, **kwargs): + build_ext = super().build_ext(*args, **kwargs) + build_ext.parallel = True + return build_ext + + def test_suite(): - return unittest.makeSuite(BuildExtTestCase) + suite = unittest.TestSuite() + suite.addTest(unittest.makeSuite(BuildExtTestCase)) + suite.addTest(unittest.makeSuite(ParallelBuildExtTestCase)) + return suite if __name__ == '__main__': - support.run_unittest(test_suite()) + support.run_unittest(__name__) diff --git a/Lib/distutils/tests/test_check.py b/Lib/distutils/tests/test_check.py index 4de64734c4c7..959fa9085cf5 100644 --- a/Lib/distutils/tests/test_check.py +++ b/Lib/distutils/tests/test_check.py @@ -1,4 +1,5 @@ """Tests for distutils.command.check.""" +import textwrap import unittest from test.support import run_unittest @@ -55,9 +56,8 @@ def test_check_metadata(self): cmd = self._run(metadata) self.assertEqual(cmd._warnings, 0) + @unittest.skipUnless(HAS_DOCUTILS, "won't test without docutils") def test_check_document(self): - if not HAS_DOCUTILS: # won't test without docutils - return pkg_info, dist = self.create_dist() cmd = check(dist) @@ -71,9 +71,8 @@ def test_check_document(self): msgs = cmd._check_rst_data(rest) self.assertEqual(len(msgs), 0) + @unittest.skipUnless(HAS_DOCUTILS, "won't test without docutils") def test_check_restructuredtext(self): - if not HAS_DOCUTILS: # won't test without docutils - return # let's see if it detects broken rest in long_description broken_rest = 'title\n===\n\ntest' pkg_info, dist = self.create_dist(long_description=broken_rest) @@ -94,6 +93,36 @@ def test_check_restructuredtext(self): cmd = self._run(metadata, strict=1, restructuredtext=1) self.assertEqual(cmd._warnings, 0) + @unittest.skipUnless(HAS_DOCUTILS, "won't test without docutils") + def test_check_restructuredtext_with_syntax_highlight(self): + # Don't fail if there is a `code` or `code-block` directive + + example_rst_docs = [] + example_rst_docs.append(textwrap.dedent("""\ + Here's some code: + + .. code:: python + + def foo(): + pass + """)) + example_rst_docs.append(textwrap.dedent("""\ + Here's some code: + + .. code-block:: python + + def foo(): + pass + """)) + + for rest_with_code in example_rst_docs: + pkg_info, dist = self.create_dist(long_description=rest_with_code) + cmd = check(dist) + cmd.check_restructuredtext() + self.assertEqual(cmd._warnings, 0) + msgs = cmd._check_rst_data(rest_with_code) + self.assertEqual(len(msgs), 0) + def test_check_all(self): metadata = {'url': 'xxx', 'author': 'xxx'} diff --git a/Lib/distutils/tests/test_config_cmd.py b/Lib/distutils/tests/test_config_cmd.py index 79894c78d35a..0c8dbd8269be 100644 --- a/Lib/distutils/tests/test_config_cmd.py +++ b/Lib/distutils/tests/test_config_cmd.py @@ -37,9 +37,8 @@ def test_dump_file(self): dump_file(this_file, 'I am the header') self.assertEqual(len(self._logs), numlines+1) + @unittest.skipIf(sys.platform == 'win32', "can't test on Windows") def test_search_cpp(self): - if sys.platform == 'win32': - return pkg_dir, dist = self.create_dist() cmd = config(dist) diff --git a/Lib/distutils/tests/test_dir_util.py b/Lib/distutils/tests/test_dir_util.py index 1589f1297db2..d436cf831917 100644 --- a/Lib/distutils/tests/test_dir_util.py +++ b/Lib/distutils/tests/test_dir_util.py @@ -2,9 +2,10 @@ import unittest import os import stat -import shutil import sys +from unittest.mock import patch +from distutils import dir_util, errors from distutils.dir_util import (mkpath, remove_tree, create_tree, copy_tree, ensure_relative) @@ -12,6 +13,7 @@ from distutils.tests import support from test.support import run_unittest + class DirUtilTestCase(support.TempdirManager, unittest.TestCase): def _log(self, msg, *args): @@ -52,7 +54,7 @@ def test_mkpath_remove_tree_verbosity(self): self.assertEqual(self._logs, wanted) @unittest.skipIf(sys.platform.startswith('win'), - "This test is only appropriate for POSIX-like systems.") + "This test is only appropriate for POSIX-like systems.") def test_mkpath_with_custom_mode(self): # Get and set the current umask value for testing mode bits. umask = os.umask(0o002) @@ -120,6 +122,16 @@ def test_ensure_relative(self): self.assertEqual(ensure_relative('c:\\home\\foo'), 'c:home\\foo') self.assertEqual(ensure_relative('home\\foo'), 'home\\foo') + def test_copy_tree_exception_in_listdir(self): + """ + An exception in listdir should raise a DistutilsFileError + """ + with patch("os.listdir", side_effect=OSError()), \ + self.assertRaises(errors.DistutilsFileError): + src = self.tempdirs[-1] + dir_util.copy_tree(src, None) + + def test_suite(): return unittest.makeSuite(DirUtilTestCase) diff --git a/Lib/distutils/tests/test_file_util.py b/Lib/distutils/tests/test_file_util.py index 3c3e3dcb3bff..a6d04f065d98 100644 --- a/Lib/distutils/tests/test_file_util.py +++ b/Lib/distutils/tests/test_file_util.py @@ -2,10 +2,13 @@ import unittest import os import shutil +import errno +from unittest.mock import patch -from distutils.file_util import move_file +from distutils.file_util import move_file, copy_file from distutils import log from distutils.tests import support +from distutils.errors import DistutilsFileError from test.support import run_unittest class FileUtilTestCase(support.TempdirManager, unittest.TestCase): @@ -58,6 +61,52 @@ def test_move_file_verbosity(self): wanted = ['moving %s -> %s' % (self.source, self.target_dir)] self.assertEqual(self._logs, wanted) + def test_move_file_exception_unpacking_rename(self): + # see issue 22182 + with patch("os.rename", side_effect=OSError("wrong", 1)), \ + self.assertRaises(DistutilsFileError): + with open(self.source, 'w') as fobj: + fobj.write('spam eggs') + move_file(self.source, self.target, verbose=0) + + def test_move_file_exception_unpacking_unlink(self): + # see issue 22182 + with patch("os.rename", side_effect=OSError(errno.EXDEV, "wrong")), \ + patch("os.unlink", side_effect=OSError("wrong", 1)), \ + self.assertRaises(DistutilsFileError): + with open(self.source, 'w') as fobj: + fobj.write('spam eggs') + move_file(self.source, self.target, verbose=0) + + def test_copy_file_hard_link(self): + with open(self.source, 'w') as f: + f.write('some content') + st = os.stat(self.source) + copy_file(self.source, self.target, link='hard') + st2 = os.stat(self.source) + st3 = os.stat(self.target) + self.assertTrue(os.path.samestat(st, st2), (st, st2)) + self.assertTrue(os.path.samestat(st2, st3), (st2, st3)) + with open(self.source, 'r') as f: + self.assertEqual(f.read(), 'some content') + + def test_copy_file_hard_link_failure(self): + # If hard linking fails, copy_file() falls back on copying file + # (some special filesystems don't support hard linking even under + # Unix, see issue #8876). + with open(self.source, 'w') as f: + f.write('some content') + st = os.stat(self.source) + with patch("os.link", side_effect=OSError(0, "linking unsupported")): + copy_file(self.source, self.target, link='hard') + st2 = os.stat(self.source) + st3 = os.stat(self.target) + self.assertTrue(os.path.samestat(st, st2), (st, st2)) + self.assertFalse(os.path.samestat(st2, st3), (st2, st3)) + for fn in (self.source, self.target): + with open(fn, 'r') as f: + self.assertEqual(f.read(), 'some content') + def test_suite(): return unittest.makeSuite(FileUtilTestCase) diff --git a/Lib/distutils/tests/test_install.py b/Lib/distutils/tests/test_install.py index 18e1e575054f..9313330e2b72 100644 --- a/Lib/distutils/tests/test_install.py +++ b/Lib/distutils/tests/test_install.py @@ -20,8 +20,6 @@ def _make_ext_name(modname): - if os.name == 'nt' and sys.executable.endswith('_d.exe'): - modname += '_d' return modname + sysconfig.get_config_var('EXT_SUFFIX') diff --git a/Lib/distutils/tests/test_register.py b/Lib/distutils/tests/test_register.py index f4efa13d789d..6180133994f8 100644 --- a/Lib/distutils/tests/test_register.py +++ b/Lib/distutils/tests/test_register.py @@ -10,6 +10,7 @@ from distutils.command import register as register_module from distutils.command.register import register from distutils.errors import DistutilsSetupError +from distutils.log import INFO from distutils.tests.test_config import PyPIRCCommandTestCase @@ -58,12 +59,18 @@ def __init__(self): def __call__(self, *args): return self - def open(self, req): + def open(self, req, data=None, timeout=None): self.reqs.append(req) return self def read(self): - return 'xxx' + return b'xxx' + + def getheader(self, name, default=None): + return { + 'content-type': 'text/plain; charset=utf-8', + }.get(name.lower(), default) + class RegisterTestCase(PyPIRCCommandTestCase): @@ -74,11 +81,13 @@ def setUp(self): def _getpass(prompt): return 'password' getpass.getpass = _getpass + urllib.request._opener = None self.old_opener = urllib.request.build_opener self.conn = urllib.request.build_opener = FakeOpener() def tearDown(self): getpass.getpass = self._old_getpass + urllib.request._opener = None urllib.request.build_opener = self.old_opener super(RegisterTestCase, self).tearDown() @@ -285,6 +294,14 @@ def test_check_metadata_deprecated(self): cmd.check_metadata() self.assertEqual(len(w.warnings), 1) + def test_list_classifiers(self): + cmd = self._get_cmd() + cmd.list_classifiers = 1 + cmd.run() + results = self.get_logs(INFO) + self.assertEqual(results, ['running check', 'xxx']) + + def test_suite(): return unittest.makeSuite(RegisterTestCase) diff --git a/Lib/distutils/tests/test_sdist.py b/Lib/distutils/tests/test_sdist.py index 164586b7846c..5a04e0ddd0fd 100644 --- a/Lib/distutils/tests/test_sdist.py +++ b/Lib/distutils/tests/test_sdist.py @@ -131,13 +131,11 @@ def test_prune_file_list(self): self.assertEqual(len(content), 4) @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run') + @unittest.skipIf(find_executable('tar') is None, + "The tar command is not found") + @unittest.skipIf(find_executable('gzip') is None, + "The gzip command is not found") def test_make_distribution(self): - - # check if tar and gzip are installed - if (find_executable('tar') is None or - find_executable('gzip') is None): - return - # now building a sdist dist, cmd = self.get_cmd() @@ -431,15 +429,13 @@ def test_manual_manifest(self): self.assertEqual(sorted(filenames), ['fake-1.0', 'fake-1.0/PKG-INFO', 'fake-1.0/README.manual']) - @unittest.skipUnless(zlib, "requires zlib") + @unittest.skipUnless(ZLIB_SUPPORT, "requires zlib") @unittest.skipUnless(UID_GID_SUPPORT, "Requires grp and pwd support") + @unittest.skipIf(find_executable('tar') is None, + "The tar command is not found") + @unittest.skipIf(find_executable('gzip') is None, + "The gzip command is not found") def test_make_distribution_owner_group(self): - - # check if tar and gzip are installed - if (find_executable('tar') is None or - find_executable('gzip') is None): - return - # now building a sdist dist, cmd = self.get_cmd() diff --git a/Lib/distutils/tests/test_sysconfig.py b/Lib/distutils/tests/test_sysconfig.py index b5fdc98dc97f..fc4d1de185cf 100644 --- a/Lib/distutils/tests/test_sysconfig.py +++ b/Lib/distutils/tests/test_sysconfig.py @@ -1,6 +1,9 @@ """Tests for distutils.sysconfig.""" import os import shutil +import subprocess +import sys +import textwrap import unittest from distutils import sysconfig @@ -80,12 +83,9 @@ def test_srcdir_independent_of_cwd(self): os.chdir(cwd) self.assertEqual(srcdir, srcdir2) + @unittest.skipUnless(get_default_compiler() == 'unix', + 'not testing if default compiler is not unix') def test_customize_compiler(self): - - # not testing if default compiler is not unix - if get_default_compiler() != 'unix': - return - os.environ['AR'] = 'my_ar' os.environ['ARFLAGS'] = '-arflags' @@ -151,7 +151,7 @@ def test_sysconfig_compiler_vars(self): import sysconfig as global_sysconfig if sysconfig.get_config_var('CUSTOMIZED_OSX_COMPILER'): - return + self.skipTest('compiler flags customized') self.assertEqual(global_sysconfig.get_config_var('LDSHARED'), sysconfig.get_config_var('LDSHARED')) self.assertEqual(global_sysconfig.get_config_var('CC'), @@ -177,6 +177,25 @@ def test_SO_in_vars(self): self.assertIsNotNone(vars['SO']) self.assertEqual(vars['SO'], vars['EXT_SUFFIX']) + def test_customize_compiler_before_get_config_vars(self): + # Issue #21923: test that a Distribution compiler + # instance can be called without an explicit call to + # get_config_vars(). + with open(TESTFN, 'w') as f: + f.writelines(textwrap.dedent('''\ + from distutils.core import Distribution + config = Distribution().get_command_obj('config') + # try_compile may pass or it may fail if no compiler + # is found but it should not raise an exception. + rc = config.try_compile('int x;') + ''')) + p = subprocess.Popen([str(sys.executable), TESTFN], + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + universal_newlines=True) + outs, errs = p.communicate() + self.assertEqual(0, p.returncode, "Subprocess failed: " + outs) + def test_suite(): suite = unittest.TestSuite() diff --git a/Lib/distutils/tests/test_unixccompiler.py b/Lib/distutils/tests/test_unixccompiler.py index a5a63fdde336..3d14e12aa9f6 100644 --- a/Lib/distutils/tests/test_unixccompiler.py +++ b/Lib/distutils/tests/test_unixccompiler.py @@ -21,12 +21,8 @@ def tearDown(self): sys.platform = self._backup_platform sysconfig.get_config_var = self._backup_get_config_var + @unittest.skipIf(sys.platform == 'win32', "can't test on Windows") def test_runtime_libdir_option(self): - - # not tested under windows - if sys.platform == 'win32': - return - # Issue#5900 # # Ensure RUNPATH is added to extension modules with RPATH if diff --git a/Lib/distutils/tests/test_upload.py b/Lib/distutils/tests/test_upload.py index 1fcba889b29c..dccaf77e3e18 100644 --- a/Lib/distutils/tests/test_upload.py +++ b/Lib/distutils/tests/test_upload.py @@ -6,6 +6,8 @@ from distutils.command import upload as upload_mod from distutils.command.upload import upload from distutils.core import Distribution +from distutils.errors import DistutilsError +from distutils.log import INFO from distutils.tests.test_config import PYPIRC, PyPIRCCommandTestCase @@ -40,16 +42,25 @@ class FakeOpen(object): - def __init__(self, url): + def __init__(self, url, msg=None, code=None): self.url = url if not isinstance(url, str): self.req = url else: self.req = None - self.msg = 'OK' + self.msg = msg or 'OK' + self.code = code or 200 + + def getheader(self, name, default=None): + return { + 'content-type': 'text/plain; charset=utf-8', + }.get(name.lower(), default) + + def read(self): + return b'xyzzy' def getcode(self): - return 200 + return self.code class uploadTestCase(PyPIRCCommandTestCase): @@ -59,13 +70,15 @@ def setUp(self): self.old_open = upload_mod.urlopen upload_mod.urlopen = self._urlopen self.last_open = None + self.next_msg = None + self.next_code = None def tearDown(self): upload_mod.urlopen = self.old_open super(uploadTestCase, self).tearDown() def _urlopen(self, url): - self.last_open = FakeOpen(url) + self.last_open = FakeOpen(url, msg=self.next_msg, code=self.next_code) return self.last_open def test_finalize_options(self): @@ -108,12 +121,13 @@ def test_upload(self): # lets run it pkg_dir, dist = self.create_dist(dist_files=dist_files) cmd = upload(dist) + cmd.show_response = 1 cmd.ensure_finalized() cmd.run() - # what did we send ? + # what did we send ? headers = dict(self.last_open.req.headers) - self.assertEqual(headers['Content-length'], '2087') + self.assertEqual(headers['Content-length'], '2161') content_type = headers['Content-type'] self.assertTrue(content_type.startswith('multipart/form-data')) self.assertEqual(self.last_open.req.get_method(), 'POST') @@ -121,6 +135,15 @@ def test_upload(self): self.assertEqual(self.last_open.req.get_full_url(), expected_url) self.assertTrue(b'xxx' in self.last_open.req.data) + # The PyPI response body was echoed + results = self.get_logs(INFO) + self.assertIn('xyzzy\n', results[-1]) + + def test_upload_fails(self): + self.next_msg = "Not Found" + self.next_code = 404 + self.assertRaises(DistutilsError, self.test_upload) + def test_suite(): return unittest.makeSuite(uploadTestCase) diff --git a/Lib/distutils/tests/test_util.py b/Lib/distutils/tests/test_util.py index 548865c02b24..4e9d79b7c6cb 100644 --- a/Lib/distutils/tests/test_util.py +++ b/Lib/distutils/tests/test_util.py @@ -8,7 +8,8 @@ from distutils.errors import DistutilsPlatformError, DistutilsByteCompileError from distutils.util import (get_platform, convert_path, change_root, check_environ, split_quoted, strtobool, - rfc822_escape, byte_compile) + rfc822_escape, byte_compile, + grok_environment_error) from distutils import util # used to patch _environ_checked from distutils.sysconfig import get_config_vars from distutils import sysconfig @@ -285,6 +286,13 @@ def test_dont_write_bytecode(self): finally: sys.dont_write_bytecode = old_dont_write_bytecode + def test_grok_environment_error(self): + # test obsolete function to ensure backward compat (#4931) + exc = IOError("Unable to find batch file") + msg = grok_environment_error(exc) + self.assertEqual(msg, "error: Unable to find batch file") + + def test_suite(): return unittest.makeSuite(UtilTestCase) diff --git a/Lib/distutils/util.py b/Lib/distutils/util.py index efb3834cf53b..5adcac5a9549 100644 --- a/Lib/distutils/util.py +++ b/Lib/distutils/util.py @@ -207,25 +207,10 @@ def _subst (match, local_vars=local_vars): def grok_environment_error (exc, prefix="error: "): - """Generate a useful error message from an OSError - exception object. Handles Python 1.5.1 and 1.5.2 styles, and - does what it can to deal with exception objects that don't have a - filename (which happens when the error is due to a two-file operation, - such as 'rename()' or 'link()'. Returns the error message as a string - prefixed with 'prefix'. - """ - # check for Python 1.5.2-style {IO,OS}Error exception objects - if hasattr(exc, 'filename') and hasattr(exc, 'strerror'): - if exc.filename: - error = prefix + "%s: %s" % (exc.filename, exc.strerror) - else: - # two-argument functions in posix module don't - # include the filename in the exception object! - error = prefix + "%s" % exc.strerror - else: - error = prefix + str(exc.args[-1]) - - return error + # Function kept for backward compatibility. + # Used to try clever things with EnvironmentErrors, + # but nowadays str(exception) produces good messages. + return prefix + str(exc) # Needed by 'split_quoted()' diff --git a/Lib/distutils/version.py b/Lib/distutils/version.py index ebcab84e4e23..af14cc134814 100644 --- a/Lib/distutils/version.py +++ b/Lib/distutils/version.py @@ -48,12 +48,6 @@ def __eq__(self, other): return c return c == 0 - def __ne__(self, other): - c = self._cmp(other) - if c is NotImplemented: - return c - return c != 0 - def __lt__(self, other): c = self._cmp(other) if c is NotImplemented: diff --git a/Lib/doctest.py b/Lib/doctest.py index ee4e0687844a..7d5bcf48f577 100644 --- a/Lib/doctest.py +++ b/Lib/doctest.py @@ -318,6 +318,32 @@ def _comment_line(line): else: return '#' +def _strip_exception_details(msg): + # Support for IGNORE_EXCEPTION_DETAIL. + # Get rid of everything except the exception name; in particular, drop + # the possibly dotted module path (if any) and the exception message (if + # any). We assume that a colon is never part of a dotted name, or of an + # exception name. + # E.g., given + # "foo.bar.MyError: la di da" + # return "MyError" + # Or for "abc.def" or "abc.def:\n" return "def". + + start, end = 0, len(msg) + # The exception name must appear on the first line. + i = msg.find("\n") + if i >= 0: + end = i + # retain up to the first colon (if any) + i = msg.find(':', 0, end) + if i >= 0: + end = i + # retain just the exception name + i = msg.rfind('.', 0, end) + if i >= 0: + start = i+1 + return msg[start: end] + class _OutputRedirectingPdb(pdb.Pdb): """ A specialized version of the python debugger that redirects stdout @@ -455,9 +481,6 @@ def __eq__(self, other): self.options == other.options and \ self.exc_msg == other.exc_msg - def __ne__(self, other): - return not self == other - def __hash__(self): return hash((self.source, self.want, self.lineno, self.indent, self.exc_msg)) @@ -507,8 +530,9 @@ def __repr__(self): examples = '1 example' else: examples = '%d examples' % len(self.examples) - return ('<DocTest %s from %s:%s (%s)>' % - (self.name, self.filename, self.lineno, examples)) + return ('<%s %s from %s:%s (%s)>' % + (self.__class__.__name__, + self.name, self.filename, self.lineno, examples)) def __eq__(self, other): if type(self) is not type(other): @@ -521,9 +545,6 @@ def __eq__(self, other): self.filename == other.filename and \ self.lineno == other.lineno - def __ne__(self, other): - return not self == other - def __hash__(self): return hash((self.docstring, self.name, self.filename, self.lineno)) @@ -919,7 +940,13 @@ def _from_module(self, module, object): elif inspect.isfunction(object): return module.__dict__ is object.__globals__ elif inspect.ismethoddescriptor(object): - return module.__name__ == object.__objclass__.__module__ + if hasattr(object, '__objclass__'): + obj_mod = object.__objclass__.__module__ + elif hasattr(object, '__module__'): + obj_mod = object.__module__ + else: + return True # [XX] no easy way to tell otherwise + return module.__name__ == obj_mod elif inspect.isclass(object): return module.__name__ == object.__module__ elif hasattr(object, '__module__'): @@ -952,7 +979,8 @@ def _find(self, tests, obj, name, module, source_lines, globs, seen): for valname, val in obj.__dict__.items(): valname = '%s.%s' % (name, valname) # Recurse to functions & classes. - if ((inspect.isroutine(val) or inspect.isclass(val)) and + if ((inspect.isroutine(inspect.unwrap(val)) + or inspect.isclass(val)) and self._from_module(module, val)): self._find(tests, val, valname, module, source_lines, globs, seen) @@ -1325,10 +1353,9 @@ def __run(self, test, compileflags, out): # Another chance if they didn't care about the detail. elif self.optionflags & IGNORE_EXCEPTION_DETAIL: - m1 = re.match(r'(?:[^:]*\.)?([^:]*:)', example.exc_msg) - m2 = re.match(r'(?:[^:]*\.)?([^:]*:)', exc_msg) - if m1 and m2 and check(m1.group(1), m2.group(1), - self.optionflags): + if check(_strip_exception_details(example.exc_msg), + _strip_exception_details(exc_msg), + self.optionflags): outcome = SUCCESS # Report the outcome. @@ -2258,9 +2285,6 @@ def __eq__(self, other): self._dt_tearDown == other._dt_tearDown and \ self._dt_checker == other._dt_checker - def __ne__(self, other): - return not self == other - def __hash__(self): return hash((self._dt_optionflags, self._dt_setUp, self._dt_tearDown, self._dt_checker)) @@ -2345,15 +2369,6 @@ def DocTestSuite(module=None, globs=None, extraglobs=None, test_finder=None, suite = _DocTestSuite() suite.addTest(SkipDocTestCase(module)) return suite - elif not tests: - # Why do we want to do this? Because it reveals a bug that might - # otherwise be hidden. - # It is probably a bug that this exception is not also raised if the - # number of doctest examples in tests is zero (i.e. if no doctest - # examples were found). However, we should probably not be raising - # an exception at all here, though it is too late to make this change - # for a maintenance release. See also issue #14649. - raise ValueError(module, "has no docstrings") tests.sort() suite = _DocTestSuite() diff --git a/Lib/email/__init__.py b/Lib/email/__init__.py index ff16f6af3f35..fae872439edc 100644 --- a/Lib/email/__init__.py +++ b/Lib/email/__init__.py @@ -4,8 +4,6 @@ """A package for parsing, handling, and generating email messages.""" -__version__ = '5.1.0' - __all__ = [ 'base64mime', 'charset', diff --git a/Lib/email/_header_value_parser.py b/Lib/email/_header_value_parser.py index 039237936c6b..1806cac9053a 100644 --- a/Lib/email/_header_value_parser.py +++ b/Lib/email/_header_value_parser.py @@ -70,7 +70,7 @@ import re import urllib # For urllib.parse.unquote from string import hexdigits -from collections import namedtuple, OrderedDict +from collections import OrderedDict from email import _encoded_words as _ew from email import errors from email import utils @@ -1556,6 +1556,13 @@ def get_bare_quoted_string(value): while value and value[0] != '"': if value[0] in WSP: token, value = get_fws(value) + elif value[:2] == '=?': + try: + token, value = get_encoded_word(value) + bare_quoted_string.defects.append(errors.InvalidHeaderDefect( + "encoded word inside quoted string")) + except errors.HeaderParseError: + token, value = get_qcontent(value) else: token, value = get_qcontent(value) bare_quoted_string.append(token) @@ -2890,7 +2897,7 @@ def parse_content_disposition_header(value): try: token, value = get_token(value) except errors.HeaderParseError: - ctype.defects.append(errors.InvalidHeaderDefect( + disp_header.defects.append(errors.InvalidHeaderDefect( "Expected content disposition but found {!r}".format(value))) _find_mime_parameters(disp_header, value) return disp_header @@ -2921,8 +2928,8 @@ def parse_content_transfer_encoding_header(value): try: token, value = get_token(value) except errors.HeaderParseError: - ctype.defects.append(errors.InvalidHeaderDefect( - "Expected content trnasfer encoding but found {!r}".format(value))) + cte_header.defects.append(errors.InvalidHeaderDefect( + "Expected content transfer encoding but found {!r}".format(value))) else: cte_header.append(token) cte_header.cte = token.value.strip().lower() diff --git a/Lib/email/charset.py b/Lib/email/charset.py index 892bab54a485..ee564040c68f 100644 --- a/Lib/email/charset.py +++ b/Lib/email/charset.py @@ -249,9 +249,6 @@ def __str__(self): def __eq__(self, other): return str(self) == str(other).lower() - def __ne__(self, other): - return not self.__eq__(other) - def get_body_encoding(self): """Return the content-transfer-encoding used for body encoding. @@ -386,7 +383,8 @@ def body_encode(self, string): string using the ascii codec produces the correct string version of the content. """ - # 7bit/8bit encodings return the string unchanged (module conversions) + if not string: + return string if self.body_encoding is BASE64: if isinstance(string, str): string = string.encode(self.output_charset) @@ -398,13 +396,9 @@ def body_encode(self, string): # character set, then, we must turn it into pseudo bytes via the # latin1 charset, which will encode any byte as a single code point # between 0 and 255, which is what body_encode is expecting. - # - # Note that this clause doesn't handle the case of a _payload that - # is already bytes. It never did, and the semantics of _payload - # being bytes has never been nailed down, so fixing that is a - # longer term TODO. if isinstance(string, str): - string = string.encode(self.output_charset).decode('latin1') + string = string.encode(self.output_charset) + string = string.decode('latin1') return email.quoprimime.body_encode(string) else: if isinstance(string, str): diff --git a/Lib/email/encoders.py b/Lib/email/encoders.py index f9657f0a255d..0a66acb6240b 100644 --- a/Lib/email/encoders.py +++ b/Lib/email/encoders.py @@ -54,21 +54,12 @@ def encode_7or8bit(msg): # There's no payload. For backwards compatibility we use 7bit msg['Content-Transfer-Encoding'] = '7bit' return - # We play a trick to make this go fast. If encoding/decode to ASCII - # succeeds, we know the data must be 7bit, otherwise treat it as 8bit. + # We play a trick to make this go fast. If decoding from ASCII succeeds, + # we know the data must be 7bit, otherwise treat it as 8bit. try: - if isinstance(orig, str): - orig.encode('ascii') - else: - orig.decode('ascii') + orig.decode('ascii') except UnicodeError: - charset = msg.get_charset() - output_cset = charset and charset.output_charset - # iso-2022-* is non-ASCII but encodes to a 7-bit representation - if output_cset and output_cset.lower().startswith('iso-2022-'): - msg['Content-Transfer-Encoding'] = '7bit' - else: - msg['Content-Transfer-Encoding'] = '8bit' + msg['Content-Transfer-Encoding'] = '8bit' else: msg['Content-Transfer-Encoding'] = '7bit' diff --git a/Lib/email/feedparser.py b/Lib/email/feedparser.py index eb75fe35793a..c95b27f12f31 100644 --- a/Lib/email/feedparser.py +++ b/Lib/email/feedparser.py @@ -33,7 +33,7 @@ NLCRE_crack = re.compile('(\r\n|\r|\n)') # RFC 2822 $3.6.8 Optional fields. ftext is %d33-57 / %d59-126, Any character # except controls, SP, and ":". -headerRE = re.compile(r'^(From |[\041-\071\073-\176]{1,}:|[\t ])') +headerRE = re.compile(r'^(From |[\041-\071\073-\176]*:|[\t ])') EMPTYSTRING = '' NL = '\n' @@ -50,8 +50,8 @@ class BufferedSubFile(object): simple abstraction -- it parses until EOF closes the current message. """ def __init__(self): - # The last partial line pushed into this object. - self._partial = '' + # Chunks of the last partial line pushed into this object. + self._partial = [] # The list of full, pushed lines, in reverse order self._lines = [] # The stack of false-EOF checking predicates. @@ -67,8 +67,8 @@ def pop_eof_matcher(self): def close(self): # Don't forget any trailing partial line. - self._lines.append(self._partial) - self._partial = '' + self.pushlines(''.join(self._partial).splitlines(True)) + self._partial = [] self._closed = True def readline(self): @@ -96,16 +96,26 @@ def unreadline(self, line): def push(self, data): """Push some new data into this object.""" - # Handle any previous leftovers - data, self._partial = self._partial + data, '' # Crack into lines, but preserve the linesep characters on the end of each parts = data.splitlines(True) + + if not parts or not parts[0].endswith(('\n', '\r')): + # No new complete lines, so just accumulate partials + self._partial += parts + return + + if self._partial: + # If there are previous leftovers, complete them now + self._partial.append(parts[0]) + parts[0:1] = ''.join(self._partial).splitlines(True) + del self._partial[:] + # If the last element of the list does not end in a newline, then treat # it as a partial line. We only check for '\n' here because a line # ending with '\r' might be a line that was split in the middle of a # '\r\n' sequence (see bugs 1555570 and 1721862). - if parts and not parts[-1].endswith('\n'): - self._partial = parts.pop() + if not parts[-1].endswith('\n'): + self._partial = [parts.pop()] self.pushlines(parts) def pushlines(self, lines): @@ -126,7 +136,7 @@ def __next__(self): class FeedParser: """A feed-style parser of email.""" - def __init__(self, _factory=message.Message, *, policy=compat32): + def __init__(self, _factory=None, *, policy=compat32): """_factory is called with no arguments to create a new message obj The policy keyword specifies a policy object that controls a number of @@ -134,14 +144,23 @@ def __init__(self, _factory=message.Message, *, policy=compat32): backward compatibility. """ - self._factory = _factory self.policy = policy - try: - _factory(policy=self.policy) - self._factory_kwds = lambda: {'policy': self.policy} - except TypeError: - # Assume this is an old-style factory - self._factory_kwds = lambda: {} + self._factory_kwds = lambda: {'policy': self.policy} + if _factory is None: + # What this should be: + #self._factory = policy.default_message_factory + # but, because we are post 3.4 feature freeze, fix with temp hack: + if self.policy is compat32: + self._factory = message.Message + else: + self._factory = message.EmailMessage + else: + self._factory = _factory + try: + _factory(policy=self.policy) + except TypeError: + # Assume this is an old-style factory + self._factory_kwds = lambda: {} self._input = BufferedSubFile() self._msgstack = [] self._parse = self._parsegen().__next__ @@ -492,6 +511,15 @@ def _parse_headers(self, lines): # There will always be a colon, because if there wasn't the part of # the parser that calls us would have started parsing the body. i = line.find(':') + + # If the colon is on the start of the line the header is clearly + # malformed, but we might be able to salvage the rest of the + # message. Track the error but keep going. + if i == 0: + defect = errors.InvalidHeaderDefect("Missing header name.") + self._cur.defects.append(defect) + continue + assert i>0, "_parse_headers fed line with no : and no leading WS" lastheader = line[:i] lastvalue = [line] diff --git a/Lib/email/generator.py b/Lib/email/generator.py index 4ea0b559b997..4735721bb0be 100644 --- a/Lib/email/generator.py +++ b/Lib/email/generator.py @@ -10,13 +10,10 @@ import sys import time import random -import warnings +from copy import deepcopy from io import StringIO, BytesIO -from email._policybase import compat32 -from email.header import Header from email.utils import _has_surrogates -import email.charset as _charset UNDERSCORE = '_' NL = '\n' # XXX: no longer used by the code below. @@ -54,8 +51,9 @@ def __init__(self, outfp, mangle_from_=True, maxheaderlen=None, *, by RFC 2822. The policy keyword specifies a policy object that controls a number of - aspects of the generator's operation. The default policy maintains - backward compatibility. + aspects of the generator's operation. If no policy is specified, + the policy associated with the Message object passed to the + flatten method is used. """ self._fp = outfp @@ -79,7 +77,9 @@ def flatten(self, msg, unixfrom=False, linesep=None): Note that for subobjects, no From_ line is printed. linesep specifies the characters used to indicate a new line in - the output. The default value is determined by the policy. + the output. The default value is determined by the policy specified + when the Generator instance was created or, if none was specified, + from the policy associated with the msg. """ # We use the _XXX constants for operating on data that comes directly @@ -173,10 +173,18 @@ def _write(self, msg): # necessary. oldfp = self._fp try: + self._munge_cte = None self._fp = sfp = self._new_buffer() self._dispatch(msg) finally: self._fp = oldfp + munge_cte = self._munge_cte + del self._munge_cte + # If we munged the cte, copy the message again and re-fix the CTE. + if munge_cte: + msg = deepcopy(msg) + msg.replace_header('content-transfer-encoding', munge_cte[0]) + msg.replace_header('content-type', munge_cte[1]) # Write the headers. First we see if the message object wants to # handle that itself. If not, we'll do it generically. meth = getattr(msg, '_write_headers', None) @@ -225,9 +233,14 @@ def _handle_text(self, msg): if _has_surrogates(msg._payload): charset = msg.get_param('charset') if charset is not None: + # XXX: This copy stuff is an ugly hack to avoid modifying the + # existing message. + msg = deepcopy(msg) del msg['content-transfer-encoding'] msg.set_payload(payload, charset) payload = msg.get_payload() + self._munge_cte = (msg['content-transfer-encoding'], + msg['content-type']) if self._mangle_from_: payload = fcre.sub('>From ', payload) self._write_lines(payload) @@ -285,9 +298,8 @@ def _handle_multipart(self, msg): # body-part self._fp.write(body_part) # close-delimiter transport-padding - self.write(self._NL + '--' + boundary + '--') + self.write(self._NL + '--' + boundary + '--' + self._NL) if msg.epilogue is not None: - self.write(self._NL) if self._mangle_from_: epilogue = fcre.sub('>From ', msg.epilogue) else: diff --git a/Lib/email/header.py b/Lib/email/header.py index 5bd06380ceef..6820ea16baf3 100644 --- a/Lib/email/header.py +++ b/Lib/email/header.py @@ -100,7 +100,6 @@ def decode_header(header): words.append((encoded, encoding, charset)) # Now loop over words and remove words that consist of whitespace # between two encoded strings. - import sys droplist = [] for n, w in enumerate(words): if n>1 and w[1] and words[n-2][1] and words[n-1][0].isspace(): @@ -263,9 +262,6 @@ def __eq__(self, other): # args and do another comparison. return other == str(self) - def __ne__(self, other): - return not self == other - def append(self, s, charset=None, errors='strict'): """Append a string to the MIME header. @@ -362,7 +358,6 @@ def encode(self, splitchars=';, \t', maxlinelen=None, linesep='\n'): for string, charset in self._chunks: if hasspace is not None: hasspace = string and self._nonctext(string[0]) - import sys if lastcs not in (None, 'us-ascii'): if not hasspace or charset not in (None, 'us-ascii'): formatter.add_transition() diff --git a/Lib/email/headerregistry.py b/Lib/email/headerregistry.py index 1fae950820a7..468ca9e3a068 100644 --- a/Lib/email/headerregistry.py +++ b/Lib/email/headerregistry.py @@ -7,6 +7,7 @@ and will probably change some before that happens. """ +from types import MappingProxyType from email import utils from email import errors @@ -80,7 +81,8 @@ def addr_spec(self): return lp def __repr__(self): - return "Address(display_name={!r}, username={!r}, domain={!r})".format( + return "{}(display_name={!r}, username={!r}, domain={!r})".format( + self.__class__.__name__, self.display_name, self.username, self.domain) def __str__(self): @@ -131,7 +133,8 @@ def addresses(self): return self._addresses def __repr__(self): - return "Group(display_name={!r}, addresses={!r}".format( + return "{}(display_name={!r}, addresses={!r}".format( + self.__class__.__name__, self.display_name, self.addresses) def __str__(self): @@ -454,7 +457,7 @@ def init(self, *args, **kw): @property def params(self): - return self._params.copy() + return MappingProxyType(self._params) class ContentTypeHeader(ParameterizedMIMEHeader): diff --git a/Lib/email/message.py b/Lib/email/message.py index ce673b0b92f0..3d3138fe27e6 100644 --- a/Lib/email/message.py +++ b/Lib/email/message.py @@ -8,6 +8,8 @@ import re import uu +import quopri +import warnings from io import BytesIO, StringIO # Intrapackage imports @@ -203,7 +205,11 @@ def attach(self, payload): if self._payload is None: self._payload = [payload] else: - self._payload.append(payload) + try: + self._payload.append(payload) + except AttributeError: + raise TypeError("Attach is not valid on a message with a" + " non-multipart payload") def get_payload(self, i=None, decode=False): """Return a reference to the payload. @@ -267,14 +273,14 @@ def get_payload(self, i=None, decode=False): bpayload = payload.encode('ascii') except UnicodeError: # This won't happen for RFC compliant messages (messages - # containing only ASCII codepoints in the unicode input). + # containing only ASCII code points in the unicode input). # If it does happen, turn the string into bytes in a way # guaranteed not to fail. bpayload = payload.encode('raw-unicode-escape') if not decode: return payload if cte == 'quoted-printable': - return utils._qdecode(bpayload) + return quopri.decodestring(bpayload) elif cte == 'base64': # XXX: this is a bit of a hack; decode_b should probably be factored # out somewhere, but I haven't figured out where yet. @@ -301,9 +307,17 @@ def set_payload(self, payload, charset=None): Optional charset sets the message's default character set. See set_charset() for details. """ - if isinstance(payload, bytes): - payload = payload.decode('ascii', 'surrogateescape') - self._payload = payload + if hasattr(payload, 'encode'): + if charset is None: + self._payload = payload + return + if not isinstance(charset, Charset): + charset = Charset(charset) + payload = payload.encode(charset.output_charset) + if hasattr(payload, 'decode'): + self._payload = payload.decode('ascii', 'surrogateescape') + else: + self._payload = payload if charset is not None: self.set_charset(charset) @@ -342,7 +356,16 @@ def set_charset(self, charset): try: cte(self) except TypeError: - self._payload = charset.body_encode(self._payload) + # This 'if' is for backward compatibility, it allows unicode + # through even though that won't work correctly if the + # message is serialized. + payload = self._payload + if payload: + try: + payload = payload.encode('ascii', 'surrogateescape') + except UnicodeError: + payload = payload.encode(charset.output_charset) + self._payload = charset.body_encode(payload) self.add_header('Content-Transfer-Encoding', cte) def get_charset(self): @@ -916,15 +939,12 @@ def __init__(self, policy=None): policy = default Message.__init__(self, policy) - @property def is_attachment(self): c_d = self.get('content-disposition') - if c_d is None: - return False - return c_d.lower() == 'attachment' + return False if c_d is None else c_d.content_disposition == 'attachment' def _find_body(self, part, preferencelist): - if part.is_attachment: + if part.is_attachment(): return maintype, subtype = part.get_content_type().split('/') if maintype == 'text': @@ -1017,7 +1037,7 @@ def iter_attachments(self): for part in parts: maintype, subtype = part.get_content_type().split('/') if ((maintype, subtype) in self._body_types and - not part.is_attachment and subtype not in seen): + not part.is_attachment() and subtype not in seen): seen.append(subtype) continue yield part diff --git a/Lib/email/mime/nonmultipart.py b/Lib/email/mime/nonmultipart.py index fc3b9eb4dcfb..e1f51968b59e 100644 --- a/Lib/email/mime/nonmultipart.py +++ b/Lib/email/mime/nonmultipart.py @@ -12,7 +12,7 @@ class MIMENonMultipart(MIMEBase): - """Base class for MIME multipart/* type messages.""" + """Base class for MIME non-multipart type messages.""" def attach(self, payload): # The public API prohibits attaching multiple subparts to MIMEBase diff --git a/Lib/email/mime/text.py b/Lib/email/mime/text.py index 3b5b09f1907f..479928ec945d 100644 --- a/Lib/email/mime/text.py +++ b/Lib/email/mime/text.py @@ -6,7 +6,7 @@ __all__ = ['MIMEText'] -from email.encoders import encode_7or8bit +from email.charset import Charset from email.mime.nonmultipart import MIMENonMultipart @@ -35,6 +35,8 @@ def __init__(self, _text, _subtype='plain', _charset=None): _charset = 'us-ascii' except UnicodeEncodeError: _charset = 'utf-8' + if isinstance(_charset, Charset): + _charset = str(_charset) MIMENonMultipart.__init__(self, 'text', _subtype, **{'charset': _charset}) diff --git a/Lib/email/parser.py b/Lib/email/parser.py index f49d31d43dfc..8c9bc9e44e24 100644 --- a/Lib/email/parser.py +++ b/Lib/email/parser.py @@ -7,17 +7,15 @@ __all__ = ['Parser', 'HeaderParser', 'BytesParser', 'BytesHeaderParser', 'FeedParser', 'BytesFeedParser'] -import warnings from io import StringIO, TextIOWrapper from email.feedparser import FeedParser, BytesFeedParser -from email.message import Message from email._policybase import compat32 class Parser: - def __init__(self, _class=Message, *, policy=compat32): + def __init__(self, _class=None, *, policy=compat32): """Parser of RFC 2822 and MIME email messages. Creates an in-memory object tree representing the email message, which @@ -108,8 +106,10 @@ def parse(self, fp, headersonly=False): meaning it parses the entire contents of the file. """ fp = TextIOWrapper(fp, encoding='ascii', errors='surrogateescape') - with fp: + try: return self.parser.parse(fp, headersonly) + finally: + fp.detach() def parsebytes(self, text, headersonly=False): diff --git a/Lib/email/quoprimime.py b/Lib/email/quoprimime.py index bc02281b1d7f..c1fe2b469400 100644 --- a/Lib/email/quoprimime.py +++ b/Lib/email/quoprimime.py @@ -40,7 +40,6 @@ ] import re -import io from string import ascii_letters, digits, hexdigits @@ -53,8 +52,9 @@ # space-wise. Remember that headers and bodies have different sets of safe # characters. Initialize both maps with the full expansion, and then override # the safe bytes with the more compact form. -_QUOPRI_HEADER_MAP = dict((c, '=%02X' % c) for c in range(256)) -_QUOPRI_BODY_MAP = _QUOPRI_HEADER_MAP.copy() +_QUOPRI_MAP = ['=%02X' % c for c in range(256)] +_QUOPRI_HEADER_MAP = _QUOPRI_MAP[:] +_QUOPRI_BODY_MAP = _QUOPRI_MAP[:] # Safe header bytes which need no encoding. for c in b'-!*+/' + ascii_letters.encode('ascii') + digits.encode('ascii'): @@ -121,8 +121,7 @@ def unquote(s): def quote(c): - return '=%02X' % ord(c) - + return _QUOPRI_MAP[ord(c)] def header_encode(header_bytes, charset='iso-8859-1'): @@ -140,68 +139,16 @@ def header_encode(header_bytes, charset='iso-8859-1'): if not header_bytes: return '' # Iterate over every byte, encoding if necessary. - encoded = [] - for octet in header_bytes: - encoded.append(_QUOPRI_HEADER_MAP[octet]) + encoded = header_bytes.decode('latin1').translate(_QUOPRI_HEADER_MAP) # Now add the RFC chrome to each encoded chunk and glue the chunks # together. - return '=?%s?q?%s?=' % (charset, EMPTYSTRING.join(encoded)) - - -class _body_accumulator(io.StringIO): - - def __init__(self, maxlinelen, eol, *args, **kw): - super().__init__(*args, **kw) - self.eol = eol - self.maxlinelen = self.room = maxlinelen - - def write_str(self, s): - """Add string s to the accumulated body.""" - self.write(s) - self.room -= len(s) - - def newline(self): - """Write eol, then start new line.""" - self.write_str(self.eol) - self.room = self.maxlinelen - - def write_soft_break(self): - """Write a soft break, then start a new line.""" - self.write_str('=') - self.newline() - - def write_wrapped(self, s, extra_room=0): - """Add a soft line break if needed, then write s.""" - if self.room < len(s) + extra_room: - self.write_soft_break() - self.write_str(s) - - def write_char(self, c, is_last_char): - if not is_last_char: - # Another character follows on this line, so we must leave - # extra room, either for it or a soft break, and whitespace - # need not be quoted. - self.write_wrapped(c, extra_room=1) - elif c not in ' \t': - # For this and remaining cases, no more characters follow, - # so there is no need to reserve extra room (since a hard - # break will immediately follow). - self.write_wrapped(c) - elif self.room >= 3: - # It's a whitespace character at end-of-line, and we have room - # for the three-character quoted encoding. - self.write(quote(c)) - elif self.room == 2: - # There's room for the whitespace character and a soft break. - self.write(c) - self.write_soft_break() - else: - # There's room only for a soft break. The quoted whitespace - # will be the only content on the subsequent line. - self.write_soft_break() - self.write(quote(c)) + return '=?%s?q?%s?=' % (charset, encoded) +_QUOPRI_BODY_ENCODE_MAP = _QUOPRI_BODY_MAP[:] +for c in b'\r\n': + _QUOPRI_BODY_ENCODE_MAP[c] = chr(c) + def body_encode(body, maxlinelen=76, eol=NL): """Encode with quoted-printable, wrapping at maxlinelen characters. @@ -226,26 +173,56 @@ def body_encode(body, maxlinelen=76, eol=NL): if not body: return body - # The last line may or may not end in eol, but all other lines do. - last_has_eol = (body[-1] in '\r\n') - - # This accumulator will make it easier to build the encoded body. - encoded_body = _body_accumulator(maxlinelen, eol) - - lines = body.splitlines() - last_line_no = len(lines) - 1 - for line_no, line in enumerate(lines): - last_char_index = len(line) - 1 - for i, c in enumerate(line): - if body_check(ord(c)): - c = quote(c) - encoded_body.write_char(c, i==last_char_index) - # Add an eol if input line had eol. All input lines have eol except - # possibly the last one. - if line_no < last_line_no or last_has_eol: - encoded_body.newline() - - return encoded_body.getvalue() + # quote speacial characters + body = body.translate(_QUOPRI_BODY_ENCODE_MAP) + + soft_break = '=' + eol + # leave space for the '=' at the end of a line + maxlinelen1 = maxlinelen - 1 + + encoded_body = [] + append = encoded_body.append + + for line in body.splitlines(): + # break up the line into pieces no longer than maxlinelen - 1 + start = 0 + laststart = len(line) - 1 - maxlinelen + while start <= laststart: + stop = start + maxlinelen1 + # make sure we don't break up an escape sequence + if line[stop - 2] == '=': + append(line[start:stop - 1]) + start = stop - 2 + elif line[stop - 1] == '=': + append(line[start:stop]) + start = stop - 1 + else: + append(line[start:stop] + '=') + start = stop + + # handle rest of line, special case if line ends in whitespace + if line and line[-1] in ' \t': + room = start - laststart + if room >= 3: + # It's a whitespace character at end-of-line, and we have room + # for the three-character quoted encoding. + q = quote(line[-1]) + elif room == 2: + # There's room for the whitespace character and a soft break. + q = line[-1] + soft_break + else: + # There's room only for a soft break. The quoted whitespace + # will be the only content on the subsequent line. + q = soft_break + quote(line[-1]) + append(line[start:-1] + q) + else: + append(line[start:]) + + # add back final newline if present + if body[-1] in CRLF: + append('') + + return eol.join(encoded_body) diff --git a/Lib/email/utils.py b/Lib/email/utils.py index 25b0d561f49b..cacb9b105aad 100644 --- a/Lib/email/utils.py +++ b/Lib/email/utils.py @@ -25,13 +25,10 @@ import os import re import time -import base64 import random import socket import datetime import urllib.parse -import warnings -from io import StringIO from email._parseaddr import quote from email._parseaddr import AddressList as _AddressList @@ -39,10 +36,7 @@ from email._parseaddr import parsedate, parsedate_tz, _parsedate_tz -from quopri import decodestring as _qdecode - # Intrapackage imports -from email.encoders import _bencode, _qencode from email.charset import Charset COMMASPACE = ', ' @@ -347,6 +341,10 @@ def collapse_rfc2231_value(value, errors='replace', # object. We do not want bytes() normal utf-8 decoder, we want a straight # interpretation of the string as character bytes. charset, language, text = value + if charset is None: + # Issue 17369: if charset/lang is None, decode_rfc2231 couldn't parse + # the value, so use the fallback_charset. + charset = fallback_charset rawbytes = bytes(text, 'raw-unicode-escape') try: return str(rawbytes, charset, errors) diff --git a/Lib/encodings/aliases.py b/Lib/encodings/aliases.py index 5461aa053a4a..4cbaadea3ee6 100644 --- a/Lib/encodings/aliases.py +++ b/Lib/encodings/aliases.py @@ -109,6 +109,11 @@ '1258' : 'cp1258', 'windows_1258' : 'cp1258', + # cp273 codec + '273' : 'cp273', + 'ibm273' : 'cp273', + 'csibm273' : 'cp273', + # cp424 codec '424' : 'cp424', 'csibm424' : 'cp424', diff --git a/Lib/encodings/base64_codec.py b/Lib/encodings/base64_codec.py index 881d1ba0beeb..8e7703b3b607 100644 --- a/Lib/encodings/base64_codec.py +++ b/Lib/encodings/base64_codec.py @@ -1,7 +1,6 @@ """Python 'base64_codec' Codec - base64 content transfer encoding. -This codec de/encodes from bytes to bytes and is therefore usable with -bytes.transform() and bytes.untransform(). +This codec de/encodes from bytes to bytes. Written by Marc-Andre Lemburg (mal@lemburg.com). """ diff --git a/Lib/encodings/cp65001.py b/Lib/encodings/cp65001.py index 287eb877feff..95cb2aecf0cc 100644 --- a/Lib/encodings/cp65001.py +++ b/Lib/encodings/cp65001.py @@ -11,20 +11,23 @@ ### Codec APIs encode = functools.partial(codecs.code_page_encode, 65001) -decode = functools.partial(codecs.code_page_decode, 65001) +_decode = functools.partial(codecs.code_page_decode, 65001) + +def decode(input, errors='strict'): + return codecs.code_page_decode(65001, input, errors, True) class IncrementalEncoder(codecs.IncrementalEncoder): def encode(self, input, final=False): return encode(input, self.errors)[0] class IncrementalDecoder(codecs.BufferedIncrementalDecoder): - _buffer_decode = decode + _buffer_decode = _decode class StreamWriter(codecs.StreamWriter): encode = encode class StreamReader(codecs.StreamReader): - decode = decode + decode = _decode ### encodings module API diff --git a/Lib/encodings/hex_codec.py b/Lib/encodings/hex_codec.py index f2ed0a7658e2..9fb107280445 100644 --- a/Lib/encodings/hex_codec.py +++ b/Lib/encodings/hex_codec.py @@ -1,7 +1,6 @@ """Python 'hex_codec' Codec - 2-digit hex content transfer encoding. -This codec de/encodes from bytes to bytes and is therefore usable with -bytes.transform() and bytes.untransform(). +This codec de/encodes from bytes to bytes. Written by Marc-Andre Lemburg (mal@lemburg.com). """ diff --git a/Lib/encodings/quopri_codec.py b/Lib/encodings/quopri_codec.py index 70f708379381..0533dbe4e7b2 100644 --- a/Lib/encodings/quopri_codec.py +++ b/Lib/encodings/quopri_codec.py @@ -1,7 +1,6 @@ """Codec for quoted-printable encoding. -This codec de/encodes from bytes to bytes and is therefore usable with -bytes.transform() and bytes.untransform(). +This codec de/encodes from bytes to bytes. """ import codecs diff --git a/Lib/encodings/rot_13.py b/Lib/encodings/rot_13.py index fff9153b4c63..f0b4186dc877 100755 --- a/Lib/encodings/rot_13.py +++ b/Lib/encodings/rot_13.py @@ -1,8 +1,7 @@ #!/usr/bin/env python """ Python Character Mapping Codec for ROT13. -This codec de/encodes from str to str and is therefore usable with -str.transform() and str.untransform(). +This codec de/encodes from str to str. Written by Marc-Andre Lemburg (mal@lemburg.com). """ @@ -107,7 +106,7 @@ def getregentry(): ### Filter API def rot13(infile, outfile): - outfile.write(infile.read().encode('rot-13')) + outfile.write(codecs.encode(infile.read(), 'rot-13')) if __name__ == '__main__': import sys diff --git a/Lib/encodings/uu_codec.py b/Lib/encodings/uu_codec.py index e3269e40cd30..2a5728fb5b74 100644 --- a/Lib/encodings/uu_codec.py +++ b/Lib/encodings/uu_codec.py @@ -1,7 +1,6 @@ """Python 'uu_codec' Codec - UU content transfer encoding. -This codec de/encodes from bytes to bytes and is therefore usable with -bytes.transform() and bytes.untransform(). +This codec de/encodes from bytes to bytes. Written by Marc-Andre Lemburg (mal@lemburg.com). Some details were adapted from uu.py which was written by Lance Ellinghouse and @@ -55,7 +54,7 @@ def uu_decode(input, errors='strict'): data = binascii.a2b_uu(s) except binascii.Error as v: # Workaround for broken uuencoders by /Fredrik Lundh - nbytes = (((ord(s[0])-32) & 63) * 4 + 5) / 3 + nbytes = (((s[0]-32) & 63) * 4 + 5) // 3 data = binascii.a2b_uu(s[:nbytes]) #sys.stderr.write("Warning: %s\n" % str(v)) write(data) diff --git a/Lib/encodings/zlib_codec.py b/Lib/encodings/zlib_codec.py index 4c81ca115a7b..95908a4b4a13 100644 --- a/Lib/encodings/zlib_codec.py +++ b/Lib/encodings/zlib_codec.py @@ -1,7 +1,6 @@ """Python 'zlib_codec' Codec - zlib compression encoding. -This codec de/encodes from bytes to bytes and is therefore usable with -bytes.transform() and bytes.untransform(). +This codec de/encodes from bytes to bytes. Written by Marc-Andre Lemburg (mal@lemburg.com). """ diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py index 63013aec3db2..9766247bcb8f 100644 --- a/Lib/ensurepip/__init__.py +++ b/Lib/ensurepip/__init__.py @@ -4,15 +4,26 @@ import sys import tempfile -# TODO: Remove the --pre flag when a pip 1.5 final copy is available - __all__ = ["version", "bootstrap"] -_SETUPTOOLS_VERSION = "1.3.2" +_SETUPTOOLS_VERSION = "12.0.5" + +_PIP_VERSION = "6.0.8" -_PIP_VERSION = "1.5rc1" +# pip currently requires ssl support, so we try to provide a nicer +# error message when that is missing (http://bugs.python.org/issue19744) +_MISSING_SSL_MESSAGE = ("pip {} requires SSL/TLS".format(_PIP_VERSION)) +try: + import ssl +except ImportError: + ssl = None + def _require_ssl_for_pip(): + raise RuntimeError(_MISSING_SSL_MESSAGE) +else: + def _require_ssl_for_pip(): + pass _PROJECTS = [ ("setuptools", _SETUPTOOLS_VERSION), @@ -36,6 +47,17 @@ def version(): """ return _PIP_VERSION +def _disable_pip_configuration_settings(): + # We deliberately ignore all pip environment variables + # when invoking pip + # See http://bugs.python.org/issue19734 for details + keys_to_remove = [k for k in os.environ if k.startswith("PIP_")] + for k in keys_to_remove: + del os.environ[k] + # We also ignore the settings in the default pip configuration file + # See http://bugs.python.org/issue20053 for details + os.environ['PIP_CONFIG_FILE'] = os.devnull + def bootstrap(*, root=None, upgrade=False, user=False, altinstall=False, default_pip=False, @@ -43,10 +65,15 @@ def bootstrap(*, root=None, upgrade=False, user=False, """ Bootstrap pip into the current Python installation (or the given root directory). + + Note that calling this function will alter both sys.path and os.environ. """ if altinstall and default_pip: raise ValueError("Cannot use altinstall and default_pip together") + _require_ssl_for_pip() + _disable_pip_configuration_settings() + # By default, installing pip and setuptools installs all of the # following scripts (X.Y == running Python version): # @@ -76,11 +103,7 @@ def bootstrap(*, root=None, upgrade=False, user=False, additional_paths.append(os.path.join(tmpdir, wheel_name)) # Construct the arguments to be passed to the pip command - args = [ - "install", "--no-index", "--find-links", tmpdir, - # Temporary until pip 1.5 is final - "--pre", - ] + args = ["install", "--no-index", "--find-links", tmpdir] if root: args += ["--root", root] if upgrade: @@ -92,8 +115,11 @@ def bootstrap(*, root=None, upgrade=False, user=False, _run_pip(args + [p[0] for p in _PROJECTS], additional_paths) -def _uninstall(*, verbosity=0): - """Helper to support a clean default uninstall process on Windows""" +def _uninstall_helper(*, verbosity=0): + """Helper to support a clean default uninstall process on Windows + + Note that calling this function may alter os.environ. + """ # Nothing to do if pip was never installed, or has been removed try: import pip @@ -102,9 +128,13 @@ def _uninstall(*, verbosity=0): # If the pip version doesn't match the bundled one, leave it alone if pip.__version__ != _PIP_VERSION: - msg = ("ensurepip will only uninstall a matching pip " + msg = ("ensurepip will only uninstall a matching version " "({!r} installed, {!r} bundled)") - raise RuntimeError(msg.format(pip.__version__, _PIP_VERSION)) + print(msg.format(pip.__version__, _PIP_VERSION), file=sys.stderr) + return + + _require_ssl_for_pip() + _disable_pip_configuration_settings() # Construct the arguments to be passed to the pip command args = ["uninstall", "-y"] @@ -112,3 +142,69 @@ def _uninstall(*, verbosity=0): args += ["-" + "v" * verbosity] _run_pip(args + [p[0] for p in reversed(_PROJECTS)]) + + +def _main(argv=None): + if ssl is None: + print("Ignoring ensurepip failure: {}".format(_MISSING_SSL_MESSAGE), + file=sys.stderr) + return + + import argparse + parser = argparse.ArgumentParser(prog="python -m ensurepip") + parser.add_argument( + "--version", + action="version", + version="pip {}".format(version()), + help="Show the version of pip that is bundled with this Python.", + ) + parser.add_argument( + "-v", "--verbose", + action="count", + default=0, + dest="verbosity", + help=("Give more output. Option is additive, and can be used up to 3 " + "times."), + ) + parser.add_argument( + "-U", "--upgrade", + action="store_true", + default=False, + help="Upgrade pip and dependencies, even if already installed.", + ) + parser.add_argument( + "--user", + action="store_true", + default=False, + help="Install using the user scheme.", + ) + parser.add_argument( + "--root", + default=None, + help="Install everything relative to this alternate root directory.", + ) + parser.add_argument( + "--altinstall", + action="store_true", + default=False, + help=("Make an alternate install, installing only the X.Y versioned" + "scripts (Default: pipX, pipX.Y, easy_install-X.Y)"), + ) + parser.add_argument( + "--default-pip", + action="store_true", + default=False, + help=("Make a default pip install, installing the unqualified pip " + "and easy_install in addition to the versioned scripts"), + ) + + args = parser.parse_args(argv) + + bootstrap( + root=args.root, + upgrade=args.upgrade, + user=args.user, + verbosity=args.verbosity, + altinstall=args.altinstall, + default_pip=args.default_pip, + ) diff --git a/Lib/ensurepip/__main__.py b/Lib/ensurepip/__main__.py index 53e84595b38c..77527d7a3513 100644 --- a/Lib/ensurepip/__main__.py +++ b/Lib/ensurepip/__main__.py @@ -1,66 +1,4 @@ -import argparse import ensurepip - -def main(): - parser = argparse.ArgumentParser(prog="python -m ensurepip") - parser.add_argument( - "--version", - action="version", - version="pip {}".format(ensurepip.version()), - help="Show the version of pip that is bundled with this Python.", - ) - parser.add_argument( - "-v", "--verbose", - action="count", - default=0, - dest="verbosity", - help=("Give more output. Option is additive, and can be used up to 3 " - "times."), - ) - parser.add_argument( - "-U", "--upgrade", - action="store_true", - default=False, - help="Upgrade pip and dependencies, even if already installed.", - ) - parser.add_argument( - "--user", - action="store_true", - default=False, - help="Install using the user scheme.", - ) - parser.add_argument( - "--root", - default=None, - help="Install everything relative to this alternate root directory.", - ) - parser.add_argument( - "--altinstall", - action="store_true", - default=False, - help=("Make an alternate install, installing only the X.Y versioned" - "scripts (Default: pipX, pipX.Y, easy_install-X.Y)"), - ) - parser.add_argument( - "--default-pip", - action="store_true", - default=False, - help=("Make a default pip install, installing the unqualified pip " - "and easy_install in addition to the versioned scripts"), - ) - - args = parser.parse_args() - - ensurepip.bootstrap( - root=args.root, - upgrade=args.upgrade, - user=args.user, - verbosity=args.verbosity, - altinstall=args.altinstall, - default_pip=args.default_pip, - ) - - if __name__ == "__main__": - main() + ensurepip._main() diff --git a/Lib/ensurepip/_bundled/pip-1.5rc1-py2.py3-none-any.whl b/Lib/ensurepip/_bundled/pip-1.5rc1-py2.py3-none-any.whl deleted file mode 100644 index 6418895a582a..000000000000 Binary files a/Lib/ensurepip/_bundled/pip-1.5rc1-py2.py3-none-any.whl and /dev/null differ diff --git a/Lib/ensurepip/_bundled/pip-6.0.8-py2.py3-none-any.whl b/Lib/ensurepip/_bundled/pip-6.0.8-py2.py3-none-any.whl new file mode 100644 index 000000000000..be9238d94c10 Binary files /dev/null and b/Lib/ensurepip/_bundled/pip-6.0.8-py2.py3-none-any.whl differ diff --git a/Lib/ensurepip/_bundled/setuptools-1.3.2-py2.py3-none-any.whl b/Lib/ensurepip/_bundled/setuptools-12.0.5-py2.py3-none-any.whl similarity index 55% rename from Lib/ensurepip/_bundled/setuptools-1.3.2-py2.py3-none-any.whl rename to Lib/ensurepip/_bundled/setuptools-12.0.5-py2.py3-none-any.whl index 81962b10814b..978cf6c43442 100644 Binary files a/Lib/ensurepip/_bundled/setuptools-1.3.2-py2.py3-none-any.whl and b/Lib/ensurepip/_bundled/setuptools-12.0.5-py2.py3-none-any.whl differ diff --git a/Lib/ensurepip/_uninstall.py b/Lib/ensurepip/_uninstall.py index 38c486b0a2a1..750365ec4d04 100644 --- a/Lib/ensurepip/_uninstall.py +++ b/Lib/ensurepip/_uninstall.py @@ -4,7 +4,7 @@ import ensurepip -def main(): +def _main(argv=None): parser = argparse.ArgumentParser(prog="python -m ensurepip._uninstall") parser.add_argument( "--version", @@ -21,10 +21,10 @@ def main(): "times."), ) - args = parser.parse_args() + args = parser.parse_args(argv) - ensurepip._uninstall(verbosity=args.verbosity) + ensurepip._uninstall_helper(verbosity=args.verbosity) if __name__ == "__main__": - main() + _main() diff --git a/Lib/enum.py b/Lib/enum.py index 7d58f8d17a6e..d744f8f4d5da 100644 --- a/Lib/enum.py +++ b/Lib/enum.py @@ -31,9 +31,9 @@ def _is_sunder(name): def _make_class_unpicklable(cls): """Make the given class un-picklable.""" - def _break_on_call_reduce(self): + def _break_on_call_reduce(self, proto): raise TypeError('%r cannot be pickled' % self) - cls.__reduce__ = _break_on_call_reduce + cls.__reduce_ex__ = _break_on_call_reduce cls.__module__ = '<unknown>' @@ -115,12 +115,22 @@ def __new__(metacls, cls, bases, classdict): # Reverse value->name map for hashable values. enum_class._value2member_map_ = {} - # check for a __getnewargs__, and if not present sabotage - # pickling, since it won't work anyway - if (member_type is not object and - member_type.__dict__.get('__getnewargs__') is None - ): - _make_class_unpicklable(enum_class) + # If a custom type is mixed into the Enum, and it does not know how + # to pickle itself, pickle.dumps will succeed but pickle.loads will + # fail. Rather than have the error show up later and possibly far + # from the source, sabotage the pickle protocol for this class so + # that pickle.dumps also fails. + # + # However, if the new class implements its own __reduce_ex__, do not + # sabotage -- it's on them to make sure it works correctly. We use + # __reduce_ex__ instead of any of the others as it is preferred by + # pickle over __reduce__, and it handles all pickle protocols. + if '__reduce_ex__' not in classdict: + if member_type is not object: + methods = ('__getnewargs_ex__', '__getnewargs__', + '__reduce_ex__', '__reduce__') + if not any(m in member_type.__dict__ for m in methods): + _make_class_unpicklable(enum_class) # instantiate them, checking for duplicates as we go # we instantiate first instead of checking for duplicates first in case @@ -149,7 +159,7 @@ def __new__(metacls, cls, bases, classdict): # If another member with the same value was already defined, the # new member becomes an alias to the existing one. for name, canonical_member in enum_class._member_map_.items(): - if canonical_member.value == enum_member._value_: + if canonical_member._value_ == enum_member._value_: enum_member = canonical_member break else: @@ -166,7 +176,7 @@ def __new__(metacls, cls, bases, classdict): # double check that repr and friends are not the mixin's or various # things break (such as pickle) - for name in ('__repr__', '__str__', '__format__', '__getnewargs__'): + for name in ('__repr__', '__str__', '__format__', '__reduce_ex__'): class_method = getattr(enum_class, name) obj_method = getattr(member_type, name, None) enum_method = getattr(first_enum, name, None) @@ -183,29 +193,38 @@ def __new__(metacls, cls, bases, classdict): enum_class.__new__ = Enum.__new__ return enum_class - def __call__(cls, value, names=None, *, module=None, type=None): + def __call__(cls, value, names=None, *, module=None, qualname=None, type=None, start=1): """Either returns an existing member, or creates a new enum class. This method is used both when an enum class is given a value to match to an enumeration member (i.e. Color(3)) and for the functional API (i.e. Color = Enum('Color', names='red green blue')). - When used for the functional API: `module`, if set, will be stored in - the new class' __module__ attribute; `type`, if set, will be mixed in - as the first base class. + When used for the functional API: + + `value` will be the name of the new class. + + `names` should be either a string of white-space/comma delimited names + (values will start at `start`), or an iterator/mapping of name, value pairs. + + `module` should be set to the module this class is being created in; + if it is not set, an attempt to find that module will be made, but if + it fails the class will not be picklable. - Note: if `module` is not set this routine will attempt to discover the - calling module by walking the frame stack; if this is unsuccessful - the resulting class will not be pickleable. + `qualname` should be set to the actual location this class can be found + at in its module; by default it is set to the global scope. If this is + not correct, unpickling will fail in some circumstances. + + `type`, if set, will be mixed in as the first base class. """ if names is None: # simple value lookup return cls.__new__(cls, value) # otherwise, functional API: we're creating a new Enum type - return cls._create_(value, names, module=module, type=type) + return cls._create_(value, names, module=module, qualname=qualname, type=type, start=start) def __contains__(cls, member): - return isinstance(member, cls) and member.name in cls._member_map_ + return isinstance(member, cls) and member._name_ in cls._member_map_ def __delattr__(cls, attr): # nicer error message when someone tries to delete an attribute @@ -273,16 +292,16 @@ def __setattr__(cls, name, value): raise AttributeError('Cannot reassign members.') super().__setattr__(name, value) - def _create_(cls, class_name, names=None, *, module=None, type=None): + def _create_(cls, class_name, names=None, *, module=None, qualname=None, type=None, start=1): """Convenience method to create a new Enum class. `names` can be: * A string containing member names, separated either with spaces or - commas. Values are auto-numbered from 1. - * An iterable of member names. Values are auto-numbered from 1. + commas. Values are incremented by 1 from `start`. + * An iterable of member names. Values are incremented by 1 from `start`. * An iterable of (member name, value) pairs. - * A mapping of member name -> value. + * A mapping of member name -> value pairs. """ metacls = cls.__class__ @@ -293,7 +312,7 @@ def _create_(cls, class_name, names=None, *, module=None, type=None): if isinstance(names, str): names = names.replace(',', ' ').split() if isinstance(names, (tuple, list)) and isinstance(names[0], str): - names = [(e, i) for (i, e) in enumerate(names, 1)] + names = [(e, i) for (i, e) in enumerate(names, start)] # Here, names is either an iterable of (name, value) or a mapping. for item in names: @@ -315,6 +334,8 @@ def _create_(cls, class_name, names=None, *, module=None, type=None): _make_class_unpicklable(enum_class) else: enum_class.__module__ = module + if qualname is not None: + enum_class.__qualname__ = qualname return enum_class @@ -431,9 +452,9 @@ def __new__(cls, value): except TypeError: # not there, now do long search -- O(n) behavior for member in cls._member_map_.values(): - if member.value == value: + if member._value_ == value: return member - raise ValueError("%s is not a valid %s" % (value, cls.__name__)) + raise ValueError("%r is not a valid %s" % (value, cls.__name__)) def __repr__(self): return "<%s.%s: %r>" % ( @@ -443,9 +464,13 @@ def __str__(self): return "%s.%s" % (self.__class__.__name__, self._name_) def __dir__(self): - added_behavior = [m for m in self.__class__.__dict__ if m[0] != '_'] - return (['__class__', '__doc__', '__module__', 'name', 'value'] + - added_behavior) + added_behavior = [ + m + for cls in self.__class__.mro() + for m in cls.__dict__ + if m[0] != '_' + ] + return (['__class__', '__doc__', '__module__'] + added_behavior) def __format__(self, format_spec): # mixed-in Enums should use the mixed-in type's __format__, otherwise @@ -459,15 +484,15 @@ def __format__(self, format_spec): # mix-in branch else: cls = self._member_type_ - val = self.value + val = self._value_ return cls.__format__(val, format_spec) - def __getnewargs__(self): - return (self._value_, ) - def __hash__(self): return hash(self._name_) + def __reduce_ex__(self, proto): + return self.__class__, (self._value_, ) + # DynamicClassAttribute is used to provide access to the `name` and # `value` properties of enum members while keeping some measure of # protection from modification, while still allowing for an enumeration diff --git a/Lib/filecmp.py b/Lib/filecmp.py index 328528871ade..e5ad8397e4c5 100644 --- a/Lib/filecmp.py +++ b/Lib/filecmp.py @@ -36,15 +36,15 @@ def cmp(f1, f2, shallow=True): f2 -- Second file name shallow -- Just check stat signature (do not read the files). - defaults to 1. + defaults to True. Return value: True if the files are the same, False otherwise. This function uses a cache for past comparisons and the results, - with a cache invalidation mechanism relying on stale signatures - or by explicitly calling clear_cache(). + with cache entries invalidated if their stat information + changes. The cache may be cleared by calling clear_cache(). """ diff --git a/Lib/fileinput.py b/Lib/fileinput.py index de2951844aef..87758ad82b30 100644 --- a/Lib/fileinput.py +++ b/Lib/fileinput.py @@ -320,7 +320,10 @@ def readline(self): self._backupfilename = 0 if self._filename == '-': self._filename = '<stdin>' - self._file = sys.stdin + if 'b' in self._mode: + self._file = sys.stdin.buffer + else: + self._file = sys.stdin self._isstdin = True else: if self._inplace: diff --git a/Lib/formatter.py b/Lib/formatter.py index d8cca52e307f..cc2f4ad18b10 100644 --- a/Lib/formatter.py +++ b/Lib/formatter.py @@ -21,7 +21,7 @@ import sys import warnings warnings.warn('the formatter module is deprecated and will be removed in ' - 'Python 3.6', PendingDeprecationWarning) + 'Python 3.6', DeprecationWarning) AS_IS = None @@ -436,11 +436,15 @@ def test(file = None): fp = open(sys.argv[1]) else: fp = sys.stdin - for line in fp: - if line == '\n': - f.end_paragraph(1) - else: - f.add_flowing_data(line) + try: + for line in fp: + if line == '\n': + f.end_paragraph(1) + else: + f.add_flowing_data(line) + finally: + if fp is not sys.stdin: + fp.close() f.end_paragraph(0) diff --git a/Lib/fractions.py b/Lib/fractions.py index 79e83ff2c00d..5ddc84c1a595 100644 --- a/Lib/fractions.py +++ b/Lib/fractions.py @@ -70,7 +70,7 @@ class Fraction(numbers.Rational): __slots__ = ('_numerator', '_denominator') # We're immutable, so use __new__ not __init__ - def __new__(cls, numerator=0, denominator=None): + def __new__(cls, numerator=0, denominator=None, _normalize=True): """Constructs a Rational. Takes a string like '3/2' or '1.5', another Rational instance, a @@ -104,7 +104,12 @@ def __new__(cls, numerator=0, denominator=None): self = super(Fraction, cls).__new__(cls) if denominator is None: - if isinstance(numerator, numbers.Rational): + if type(numerator) is int: + self._numerator = numerator + self._denominator = 1 + return self + + elif isinstance(numerator, numbers.Rational): self._numerator = numerator.numerator self._denominator = numerator.denominator return self @@ -153,6 +158,9 @@ def __new__(cls, numerator=0, denominator=None): raise TypeError("argument should be a string " "or a Rational instance") + elif type(numerator) is int is type(denominator): + pass # *very* normal case + elif (isinstance(numerator, numbers.Rational) and isinstance(denominator, numbers.Rational)): numerator, denominator = ( @@ -165,9 +173,12 @@ def __new__(cls, numerator=0, denominator=None): if denominator == 0: raise ZeroDivisionError('Fraction(%s, 0)' % numerator) - g = gcd(numerator, denominator) - self._numerator = numerator // g - self._denominator = denominator // g + if _normalize: + g = gcd(numerator, denominator) + numerator //= g + denominator //= g + self._numerator = numerator + self._denominator = denominator return self @classmethod @@ -277,7 +288,8 @@ def denominator(a): def __repr__(self): """repr(self)""" - return ('Fraction(%s, %s)' % (self._numerator, self._denominator)) + return '%s(%s, %s)' % (self.__class__.__name__, + self._numerator, self._denominator) def __str__(self): """str(self)""" @@ -395,17 +407,17 @@ def reverse(b, a): def _add(a, b): """a + b""" - return Fraction(a.numerator * b.denominator + - b.numerator * a.denominator, - a.denominator * b.denominator) + da, db = a.denominator, b.denominator + return Fraction(a.numerator * db + b.numerator * da, + da * db) __add__, __radd__ = _operator_fallbacks(_add, operator.add) def _sub(a, b): """a - b""" - return Fraction(a.numerator * b.denominator - - b.numerator * a.denominator, - a.denominator * b.denominator) + da, db = a.denominator, b.denominator + return Fraction(a.numerator * db - b.numerator * da, + da * db) __sub__, __rsub__ = _operator_fallbacks(_sub, operator.sub) @@ -453,10 +465,12 @@ def __pow__(a, b): power = b.numerator if power >= 0: return Fraction(a._numerator ** power, - a._denominator ** power) + a._denominator ** power, + _normalize=False) else: return Fraction(a._denominator ** -power, - a._numerator ** -power) + a._numerator ** -power, + _normalize=False) else: # A fractional power will generally produce an # irrational number. @@ -480,15 +494,15 @@ def __rpow__(b, a): def __pos__(a): """+a: Coerces a subclass instance to Fraction""" - return Fraction(a._numerator, a._denominator) + return Fraction(a._numerator, a._denominator, _normalize=False) def __neg__(a): """-a""" - return Fraction(-a._numerator, a._denominator) + return Fraction(-a._numerator, a._denominator, _normalize=False) def __abs__(a): """abs(a)""" - return Fraction(abs(a._numerator), a._denominator) + return Fraction(abs(a._numerator), a._denominator, _normalize=False) def __trunc__(a): """trunc(a)""" @@ -555,6 +569,8 @@ def __hash__(self): def __eq__(a, b): """a == b""" + if type(b) is int: + return a._numerator == b and a._denominator == 1 if isinstance(b, numbers.Rational): return (a._numerator == b.numerator and a._denominator == b.denominator) diff --git a/Lib/ftplib.py b/Lib/ftplib.py index 2cc470258e18..135ec9c1dff6 100644 --- a/Lib/ftplib.py +++ b/Lib/ftplib.py @@ -42,7 +42,7 @@ import warnings from socket import _GLOBAL_DEFAULT_TIMEOUT -__all__ = ["FTP", "Netrc"] +__all__ = ["FTP"] # Magic number from <socket.h> MSG_OOB = 0x1 # Process data out of band @@ -320,7 +320,6 @@ def makeport(self): raise err else: raise OSError("getaddrinfo returns an empty list") - raise OSError(msg) sock.listen(1) port = sock.getsockname()[1] # Get proper port host = self.sock.getsockname()[0] # Get proper host @@ -714,7 +713,7 @@ class FTP_TLS(FTP): '221 Goodbye.' >>> ''' - ssl_version = ssl.PROTOCOL_TLSv1 + ssl_version = ssl.PROTOCOL_SSLv23 def __init__(self, host='', user='', passwd='', acct='', keyfile=None, certfile=None, context=None, @@ -744,13 +743,12 @@ def auth(self): '''Set up secure control connection by using TLS/SSL.''' if isinstance(self.sock, ssl.SSLSocket): raise ValueError("Already using TLS") - if self.ssl_version == ssl.PROTOCOL_TLSv1: + if self.ssl_version >= ssl.PROTOCOL_SSLv23: resp = self.voidcmd('AUTH TLS') else: resp = self.voidcmd('AUTH SSL') - server_hostname = self.host if ssl.HAS_SNI else None self.sock = self.context.wrap_socket(self.sock, - server_hostname=server_hostname) + server_hostname=self.host) self.file = self.sock.makefile(mode='r', encoding=self.encoding) return resp @@ -789,9 +787,8 @@ def prot_c(self): def ntransfercmd(self, cmd, rest=None): conn, size = FTP.ntransfercmd(self, cmd, rest) if self._prot_p: - server_hostname = self.host if ssl.HAS_SNI else None conn = self.context.wrap_socket(conn, - server_hostname=server_hostname) + server_hostname=self.host) return conn, size def abort(self): @@ -921,115 +918,6 @@ def ftpcp(source, sourcename, target, targetname = '', type = 'I'): target.voidresp() -class Netrc: - """Class to parse & provide access to 'netrc' format files. - - See the netrc(4) man page for information on the file format. - - WARNING: This class is obsolete -- use module netrc instead. - - """ - __defuser = None - __defpasswd = None - __defacct = None - - def __init__(self, filename=None): - warnings.warn("This class is deprecated, use the netrc module instead", - DeprecationWarning, 2) - if filename is None: - if "HOME" in os.environ: - filename = os.path.join(os.environ["HOME"], - ".netrc") - else: - raise OSError("specify file to load or set $HOME") - self.__hosts = {} - self.__macros = {} - fp = open(filename, "r") - in_macro = 0 - while 1: - line = fp.readline() - if not line: - break - if in_macro and line.strip(): - macro_lines.append(line) - continue - elif in_macro: - self.__macros[macro_name] = tuple(macro_lines) - in_macro = 0 - words = line.split() - host = user = passwd = acct = None - default = 0 - i = 0 - while i < len(words): - w1 = words[i] - if i+1 < len(words): - w2 = words[i + 1] - else: - w2 = None - if w1 == 'default': - default = 1 - elif w1 == 'machine' and w2: - host = w2.lower() - i = i + 1 - elif w1 == 'login' and w2: - user = w2 - i = i + 1 - elif w1 == 'password' and w2: - passwd = w2 - i = i + 1 - elif w1 == 'account' and w2: - acct = w2 - i = i + 1 - elif w1 == 'macdef' and w2: - macro_name = w2 - macro_lines = [] - in_macro = 1 - break - i = i + 1 - if default: - self.__defuser = user or self.__defuser - self.__defpasswd = passwd or self.__defpasswd - self.__defacct = acct or self.__defacct - if host: - if host in self.__hosts: - ouser, opasswd, oacct = \ - self.__hosts[host] - user = user or ouser - passwd = passwd or opasswd - acct = acct or oacct - self.__hosts[host] = user, passwd, acct - fp.close() - - def get_hosts(self): - """Return a list of hosts mentioned in the .netrc file.""" - return self.__hosts.keys() - - def get_account(self, host): - """Returns login information for the named host. - - The return value is a triple containing userid, - password, and the accounting field. - - """ - host = host.lower() - user = passwd = acct = None - if host in self.__hosts: - user, passwd, acct = self.__hosts[host] - user = user or self.__defuser - passwd = passwd or self.__defpasswd - acct = acct or self.__defacct - return user, passwd, acct - - def get_macros(self): - """Return a list of all defined macro names.""" - return self.__macros.keys() - - def get_macro(self, macro): - """Return a sequence of lines which define a named macro.""" - return self.__macros[macro] - - - def test(): '''Test program. Usage: ftp [-d] [-r[file]] host [-l[dir]] [-d[dir]] [-p] [file] ... @@ -1043,6 +931,8 @@ def test(): print(test.__doc__) sys.exit(0) + import netrc + debugging = 0 rcfile = None while sys.argv[1] == '-d': @@ -1057,14 +947,14 @@ def test(): ftp.set_debuglevel(debugging) userid = passwd = acct = '' try: - netrc = Netrc(rcfile) + netrcobj = netrc.netrc(rcfile) except OSError: if rcfile is not None: sys.stderr.write("Could not open account file" " -- using anonymous login.") else: try: - userid, passwd, acct = netrc.get_account(host) + userid, acct, passwd = netrcobj.authenticators(host) except KeyError: # no account for host sys.stderr.write( diff --git a/Lib/functools.py b/Lib/functools.py index 1e79b31140b9..20a26f9a2c75 100644 --- a/Lib/functools.py +++ b/Lib/functools.py @@ -19,7 +19,7 @@ pass from abc import get_cache_token from collections import namedtuple -from types import MappingProxyType, MethodType +from types import MappingProxyType from weakref import WeakKeyDictionary try: from _thread import RLock @@ -89,101 +89,116 @@ def wraps(wrapped, ### total_ordering class decorator ################################################################################ -# The correct way to indicate that a comparison operation doesn't -# recognise the other type is to return NotImplemented and let the -# interpreter handle raising TypeError if both operands return -# NotImplemented from their respective comparison methods -# -# This makes the implementation of total_ordering more complicated, since -# we need to be careful not to trigger infinite recursion when two -# different types that both use this decorator encounter each other. -# -# For example, if a type implements __lt__, it's natural to define -# __gt__ as something like: -# -# lambda self, other: not self < other and not self == other -# -# However, using the operator syntax like that ends up invoking the full -# type checking machinery again and means we can end up bouncing back and -# forth between the two operands until we run out of stack space. -# -# The solution is to define helper functions that invoke the appropriate -# magic methods directly, ensuring we only try each operand once, and -# return NotImplemented immediately if it is returned from the -# underlying user provided method. Using this scheme, the __gt__ derived -# from a user provided __lt__ becomes: -# -# lambda self, other: _not_op_and_not_eq(self.__lt__, self, other)) - -def _not_op(op, other): - # "not a < b" handles "a >= b" - # "not a <= b" handles "a > b" - # "not a >= b" handles "a < b" - # "not a > b" handles "a <= b" - op_result = op(other) +# The total ordering functions all invoke the root magic method directly +# rather than using the corresponding operator. This avoids possible +# infinite recursion that could occur when the operator dispatch logic +# detects a NotImplemented result and then calls a reflected method. + +def _gt_from_lt(self, other): + 'Return a > b. Computed by @total_ordering from (not a < b) and (a != b).' + op_result = self.__lt__(other) + if op_result is NotImplemented: + return op_result + return not op_result and self != other + +def _le_from_lt(self, other): + 'Return a <= b. Computed by @total_ordering from (a < b) or (a == b).' + op_result = self.__lt__(other) + return op_result or self == other + +def _ge_from_lt(self, other): + 'Return a >= b. Computed by @total_ordering from (not a < b).' + op_result = self.__lt__(other) if op_result is NotImplemented: - return NotImplemented + return op_result return not op_result -def _op_or_eq(op, self, other): - # "a < b or a == b" handles "a <= b" - # "a > b or a == b" handles "a >= b" - op_result = op(other) +def _ge_from_le(self, other): + 'Return a >= b. Computed by @total_ordering from (not a <= b) or (a == b).' + op_result = self.__le__(other) if op_result is NotImplemented: - return NotImplemented - return op_result or self == other + return op_result + return not op_result or self == other + +def _lt_from_le(self, other): + 'Return a < b. Computed by @total_ordering from (a <= b) and (a != b).' + op_result = self.__le__(other) + if op_result is NotImplemented: + return op_result + return op_result and self != other + +def _gt_from_le(self, other): + 'Return a > b. Computed by @total_ordering from (not a <= b).' + op_result = self.__le__(other) + if op_result is NotImplemented: + return op_result + return not op_result -def _not_op_and_not_eq(op, self, other): - # "not (a < b or a == b)" handles "a > b" - # "not a < b and a != b" is equivalent - # "not (a > b or a == b)" handles "a < b" - # "not a > b and a != b" is equivalent - op_result = op(other) +def _lt_from_gt(self, other): + 'Return a < b. Computed by @total_ordering from (not a > b) and (a != b).' + op_result = self.__gt__(other) if op_result is NotImplemented: - return NotImplemented + return op_result return not op_result and self != other -def _not_op_or_eq(op, self, other): - # "not a <= b or a == b" handles "a >= b" - # "not a >= b or a == b" handles "a <= b" - op_result = op(other) +def _ge_from_gt(self, other): + 'Return a >= b. Computed by @total_ordering from (a > b) or (a == b).' + op_result = self.__gt__(other) + return op_result or self == other + +def _le_from_gt(self, other): + 'Return a <= b. Computed by @total_ordering from (not a > b).' + op_result = self.__gt__(other) + if op_result is NotImplemented: + return op_result + return not op_result + +def _le_from_ge(self, other): + 'Return a <= b. Computed by @total_ordering from (not a >= b) or (a == b).' + op_result = self.__ge__(other) if op_result is NotImplemented: - return NotImplemented + return op_result return not op_result or self == other -def _op_and_not_eq(op, self, other): - # "a <= b and not a == b" handles "a < b" - # "a >= b and not a == b" handles "a > b" - op_result = op(other) +def _gt_from_ge(self, other): + 'Return a > b. Computed by @total_ordering from (a >= b) and (a != b).' + op_result = self.__ge__(other) if op_result is NotImplemented: - return NotImplemented + return op_result return op_result and self != other +def _lt_from_ge(self, other): + 'Return a < b. Computed by @total_ordering from (not a >= b).' + op_result = self.__ge__(other) + if op_result is NotImplemented: + return op_result + return not op_result + +_convert = { + '__lt__': [('__gt__', _gt_from_lt), + ('__le__', _le_from_lt), + ('__ge__', _ge_from_lt)], + '__le__': [('__ge__', _ge_from_le), + ('__lt__', _lt_from_le), + ('__gt__', _gt_from_le)], + '__gt__': [('__lt__', _lt_from_gt), + ('__ge__', _ge_from_gt), + ('__le__', _le_from_gt)], + '__ge__': [('__le__', _le_from_ge), + ('__gt__', _gt_from_ge), + ('__lt__', _lt_from_ge)] +} + def total_ordering(cls): """Class decorator that fills in missing ordering methods""" - convert = { - '__lt__': [('__gt__', lambda self, other: _not_op_and_not_eq(self.__lt__, self, other)), - ('__le__', lambda self, other: _op_or_eq(self.__lt__, self, other)), - ('__ge__', lambda self, other: _not_op(self.__lt__, other))], - '__le__': [('__ge__', lambda self, other: _not_op_or_eq(self.__le__, self, other)), - ('__lt__', lambda self, other: _op_and_not_eq(self.__le__, self, other)), - ('__gt__', lambda self, other: _not_op(self.__le__, other))], - '__gt__': [('__lt__', lambda self, other: _not_op_and_not_eq(self.__gt__, self, other)), - ('__ge__', lambda self, other: _op_or_eq(self.__gt__, self, other)), - ('__le__', lambda self, other: _not_op(self.__gt__, other))], - '__ge__': [('__le__', lambda self, other: _not_op_or_eq(self.__ge__, self, other)), - ('__gt__', lambda self, other: _op_and_not_eq(self.__ge__, self, other)), - ('__lt__', lambda self, other: _not_op(self.__ge__, other))] - } # Find user-defined comparisons (not those inherited from object). - roots = [op for op in convert if getattr(cls, op, None) is not getattr(object, op, None)] + roots = [op for op in _convert if getattr(cls, op, None) is not getattr(object, op, None)] if not roots: raise ValueError('must define at least one ordering operation: < > <= >=') root = max(roots) # prefer __lt__ to __le__ to __gt__ to __ge__ - for opname, opfunc in convert[root]: + for opname, opfunc in _convert[root]: if opname not in roots: opfunc.__name__ = opname - opfunc.__doc__ = getattr(int, opname).__doc__ setattr(cls, opname, opfunc) return cls @@ -208,8 +223,6 @@ def __le__(self, other): return mycmp(self.obj, other.obj) <= 0 def __ge__(self, other): return mycmp(self.obj, other.obj) >= 0 - def __ne__(self, other): - return mycmp(self.obj, other.obj) != 0 __hash__ = None return K @@ -277,7 +290,7 @@ def __repr__(self): for k, v in self.keywords.items()) format_string = "{module}.{cls}({func}, {args}, {keywords})" return format_string.format(module=self.__class__.__module__, - cls=self.__class__.__name__, + cls=self.__class__.__qualname__, func=self.func, args=args, keywords=keywords) @@ -290,6 +303,7 @@ def _method(*args, **keywords): call_args = (cls_or_self,) + self.args + tuple(rest) return self.func(*call_args, **call_keywords) _method.__isabstractmethod__ = self.__isabstractmethod__ + _method._partialmethod = self return _method def __get__(self, obj, cls): @@ -391,6 +405,12 @@ def lru_cache(maxsize=128, typed=False): # The internals of the lru_cache are encapsulated for thread safety and # to allow the implementation to change (including a possible C version). + # Early detection of an erroneous call to @lru_cache without any arguments + # resulting in the inner function being passed to maxsize instead of an + # integer or None. + if maxsize is not None and not isinstance(maxsize, int): + raise TypeError('Expected maxsize to be an integer or None') + # Constants shared by all lru cache instances: sentinel = object() # unique object used to signal cache misses make_key = _make_key # build a key from the function arguments diff --git a/Lib/genericpath.py b/Lib/genericpath.py index ca4a5108fd42..671406197a7f 100644 --- a/Lib/genericpath.py +++ b/Lib/genericpath.py @@ -130,3 +130,16 @@ def _splitext(p, sep, altsep, extsep): filenameIndex += 1 return p, p[:0] + +def _check_arg_types(funcname, *args): + hasstr = hasbytes = False + for s in args: + if isinstance(s, str): + hasstr = True + elif isinstance(s, bytes): + hasbytes = True + else: + raise TypeError('%s() argument must be str or bytes, not %r' % + (funcname, s.__class__.__name__)) from None + if hasstr and hasbytes: + raise TypeError("Can't mix strings and bytes in path components") from None diff --git a/Lib/getpass.py b/Lib/getpass.py index 53c38b889756..7c4e976174ab 100644 --- a/Lib/getpass.py +++ b/Lib/getpass.py @@ -135,7 +135,13 @@ def _raw_input(prompt="", stream=None, input=None): input = sys.stdin prompt = str(prompt) if prompt: - stream.write(prompt) + try: + stream.write(prompt) + except UnicodeEncodeError: + # Use replace error handler to get as much as possible printed. + prompt = prompt.encode(stream.encoding, 'replace') + prompt = prompt.decode(stream.encoding) + stream.write(prompt) stream.flush() # NOTE: The Python C API calls flockfile() (and unlock) during readline. line = input.readline() diff --git a/Lib/gettext.py b/Lib/gettext.py index 05d9c1e5a3dd..15378bccf81f 100644 --- a/Lib/gettext.py +++ b/Lib/gettext.py @@ -225,6 +225,13 @@ class GNUTranslations(NullTranslations): LE_MAGIC = 0x950412de BE_MAGIC = 0xde120495 + # Acceptable .mo versions + VERSIONS = (0, 1) + + def _get_versions(self, version): + """Returns a tuple of major version, minor version""" + return (version >> 16, version & 0xffff) + def _parse(self, fp): """Override this method to support alternative .mo formats.""" unpack = struct.unpack @@ -245,6 +252,12 @@ def _parse(self, fp): ii = '>II' else: raise OSError(0, 'Bad magic number', filename) + + major_version, minor_version = self._get_versions(version) + + if major_version not in self.VERSIONS: + raise OSError(0, 'Bad version number ' + str(major_version), filename) + # Now put all messages from the .mo file buffer into the catalog # dictionary. for i in range(0, msgcount): diff --git a/Lib/glob.py b/Lib/glob.py index e388b5f9c0dd..56d670419a68 100644 --- a/Lib/glob.py +++ b/Lib/glob.py @@ -6,7 +6,7 @@ __all__ = ["glob", "iglob"] -def glob(pathname): +def glob(pathname, *, recursive=False): """Return a list of paths matching a pathname pattern. The pattern may contain simple shell-style wildcards a la @@ -14,10 +14,12 @@ def glob(pathname): dot are special cases that are not matched by '*' and '?' patterns. + If recursive is true, the pattern '**' will match any files and + zero or more directories and subdirectories. """ - return list(iglob(pathname)) + return list(iglob(pathname, recursive=recursive)) -def iglob(pathname): +def iglob(pathname, *, recursive=False): """Return an iterator which yields the paths matching a pathname pattern. The pattern may contain simple shell-style wildcards a la @@ -25,24 +27,37 @@ def iglob(pathname): dot are special cases that are not matched by '*' and '?' patterns. + If recursive is true, the pattern '**' will match any files and + zero or more directories and subdirectories. """ + dirname, basename = os.path.split(pathname) if not has_magic(pathname): - if os.path.lexists(pathname): - yield pathname + if basename: + if os.path.lexists(pathname): + yield pathname + else: + # Patterns ending with a slash should match only directories + if os.path.isdir(dirname): + yield pathname return - dirname, basename = os.path.split(pathname) if not dirname: - yield from glob1(None, basename) + if recursive and _isrecursive(basename): + yield from glob2(dirname, basename) + else: + yield from glob1(dirname, basename) return # `os.path.split()` returns the argument itself as a dirname if it is a # drive or UNC path. Prevent an infinite recursion if a drive or UNC path # contains magic characters (i.e. r'\\?\C:'). if dirname != pathname and has_magic(dirname): - dirs = iglob(dirname) + dirs = iglob(dirname, recursive=recursive) else: dirs = [dirname] if has_magic(basename): - glob_in_dir = glob1 + if recursive and _isrecursive(basename): + glob_in_dir = glob2 + else: + glob_in_dir = glob1 else: glob_in_dir = glob0 for dirname in dirs: @@ -78,6 +93,34 @@ def glob0(dirname, basename): return [basename] return [] +# This helper function recursively yields relative pathnames inside a literal +# directory. + +def glob2(dirname, pattern): + assert _isrecursive(pattern) + if dirname: + yield pattern[:0] + yield from _rlistdir(dirname) + +# Recursively yields relative pathnames inside a literal directory. + +def _rlistdir(dirname): + if not dirname: + if isinstance(dirname, bytes): + dirname = bytes(os.curdir, 'ASCII') + else: + dirname = os.curdir + try: + names = os.listdir(dirname) + except os.error: + return + for x in names: + if not _ishidden(x): + yield x + path = os.path.join(dirname, x) if dirname else x + for y in _rlistdir(path): + yield os.path.join(x, y) + magic_check = re.compile('([*?[])') magic_check_bytes = re.compile(b'([*?[])') @@ -92,6 +135,12 @@ def has_magic(s): def _ishidden(path): return path[0] in ('.', b'.'[0]) +def _isrecursive(pattern): + if isinstance(pattern, bytes): + return pattern == b'**' + else: + return pattern == '**' + def escape(pathname): """Escape all special characters. """ diff --git a/Lib/gzip.py b/Lib/gzip.py index 8d21fe4bc24e..f934d4f1c2b3 100644 --- a/Lib/gzip.py +++ b/Lib/gzip.py @@ -96,7 +96,7 @@ def prepend(self, prepend=b'', readprevious=False): self._read -= len(prepend) return else: - self._buffer = self._buffer[read:] + prepend + self._buffer = self._buffer[self._read:] + prepend self._length = len(self._buffer) self._read = 0 diff --git a/Lib/hashlib.py b/Lib/hashlib.py index 77673f06eb2c..316cecedc209 100644 --- a/Lib/hashlib.py +++ b/Lib/hashlib.py @@ -54,8 +54,7 @@ # This tuple and __get_builtin_constructor() must be modified if a new # always available algorithm is added. -__always_supported = ('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512', - 'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512') +__always_supported = ('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512') algorithms_guaranteed = set(__always_supported) algorithms_available = set(__always_supported) @@ -86,13 +85,6 @@ def __get_builtin_constructor(name): import _sha512 cache['SHA384'] = cache['sha384'] = _sha512.sha384 cache['SHA512'] = cache['sha512'] = _sha512.sha512 - elif name in {'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512', - 'SHA3_224', 'SHA3_256', 'SHA3_384', 'SHA3_512'}: - import _sha3 - cache['SHA3_224'] = cache['sha3_224'] = _sha3.sha3_224 - cache['SHA3_256'] = cache['sha3_256'] = _sha3.sha3_256 - cache['SHA3_384'] = cache['sha3_384'] = _sha3.sha3_384 - cache['SHA3_512'] = cache['sha3_512'] = _sha3.sha3_512 except ImportError: pass # no extension module, this hash is unsupported. @@ -180,7 +172,7 @@ def pbkdf2_hmac(hash_name, password, salt, iterations, dklen=None): def prf(msg, inner=inner, outer=outer): # PBKDF2_HMAC uses the password as key. We can re-use the same - # digest objects and and just update copies to skip initialization. + # digest objects and just update copies to skip initialization. icpy = inner.copy() ocpy = outer.copy() icpy.update(msg) diff --git a/Lib/heapq.py b/Lib/heapq.py index d615239b9460..07af37e717e4 100644 --- a/Lib/heapq.py +++ b/Lib/heapq.py @@ -127,8 +127,6 @@ __all__ = ['heappush', 'heappop', 'heapify', 'heapreplace', 'merge', 'nlargest', 'nsmallest', 'heappushpop'] -from itertools import islice, count, tee, chain - def heappush(heap, item): """Push item onto heap, maintaining the heap invariant.""" heap.append(item) @@ -141,9 +139,8 @@ def heappop(heap): returnitem = heap[0] heap[0] = lastelt _siftup(heap, 0) - else: - returnitem = lastelt - return returnitem + return returnitem + return lastelt def heapreplace(heap, item): """Pop and return the current smallest value, and add the new item. @@ -179,12 +176,22 @@ def heapify(x): for i in reversed(range(n//2)): _siftup(x, i) -def _heappushpop_max(heap, item): - """Maxheap version of a heappush followed by a heappop.""" - if heap and item < heap[0]: - item, heap[0] = heap[0], item +def _heappop_max(heap): + """Maxheap version of a heappop.""" + lastelt = heap.pop() # raises appropriate IndexError if heap is empty + if heap: + returnitem = heap[0] + heap[0] = lastelt _siftup_max(heap, 0) - return item + return returnitem + return lastelt + +def _heapreplace_max(heap, item): + """Maxheap version of a heappop followed by a heappush.""" + returnitem = heap[0] # raises appropriate IndexError if heap is empty + heap[0] = item + _siftup_max(heap, 0) + return returnitem def _heapify_max(x): """Transform list into a maxheap, in-place, in O(len(x)) time.""" @@ -192,42 +199,6 @@ def _heapify_max(x): for i in reversed(range(n//2)): _siftup_max(x, i) -def nlargest(n, iterable): - """Find the n largest elements in a dataset. - - Equivalent to: sorted(iterable, reverse=True)[:n] - """ - if n < 0: - return [] - it = iter(iterable) - result = list(islice(it, n)) - if not result: - return result - heapify(result) - _heappushpop = heappushpop - for elem in it: - _heappushpop(result, elem) - result.sort(reverse=True) - return result - -def nsmallest(n, iterable): - """Find the n smallest elements in a dataset. - - Equivalent to: sorted(iterable)[:n] - """ - if n < 0: - return [] - it = iter(iterable) - result = list(islice(it, n)) - if not result: - return result - _heapify_max(result) - _heappushpop = _heappushpop_max - for elem in it: - _heappushpop(result, elem) - result.sort() - return result - # 'heap' is a heap at all indices >= startpos, except possibly for pos. pos # is the index of a leaf with a possibly out-of-order value. Restore the # heap invariant. @@ -340,13 +311,7 @@ def _siftup_max(heap, pos): heap[pos] = newitem _siftdown_max(heap, startpos, pos) -# If available, use C implementation -try: - from _heapq import * -except ImportError: - pass - -def merge(*iterables): +def merge(*iterables, key=None, reverse=False): '''Merge multiple sorted inputs into a single sorted output. Similar to sorted(itertools.chain(*iterables)) but returns a generator, @@ -356,51 +321,158 @@ def merge(*iterables): >>> list(merge([1,3,5,7], [0,2,4,8], [5,10,15,20], [], [25])) [0, 1, 2, 3, 4, 5, 5, 7, 8, 10, 15, 20, 25] + If *key* is not None, applies a key function to each element to determine + its sort order. + + >>> list(merge(['dog', 'horse'], ['cat', 'fish', 'kangaroo'], key=len)) + ['dog', 'cat', 'fish', 'horse', 'kangaroo'] + ''' - _heappop, _heapreplace, _StopIteration = heappop, heapreplace, StopIteration - _len = len h = [] h_append = h.append - for itnum, it in enumerate(map(iter, iterables)): + + if reverse: + _heapify = _heapify_max + _heappop = _heappop_max + _heapreplace = _heapreplace_max + direction = -1 + else: + _heapify = heapify + _heappop = heappop + _heapreplace = heapreplace + direction = 1 + + if key is None: + for order, it in enumerate(map(iter, iterables)): + try: + next = it.__next__ + h_append([next(), order * direction, next]) + except StopIteration: + pass + _heapify(h) + while len(h) > 1: + try: + while True: + value, order, next = s = h[0] + yield value + s[0] = next() # raises StopIteration when exhausted + _heapreplace(h, s) # restore heap condition + except StopIteration: + _heappop(h) # remove empty iterator + if h: + # fast case when only a single iterator remains + value, order, next = h[0] + yield value + yield from next.__self__ + return + + for order, it in enumerate(map(iter, iterables)): try: next = it.__next__ - h_append([next(), itnum, next]) - except _StopIteration: + value = next() + h_append([key(value), order * direction, value, next]) + except StopIteration: pass - heapify(h) - - while _len(h) > 1: + _heapify(h) + while len(h) > 1: try: while True: - v, itnum, next = s = h[0] - yield v - s[0] = next() # raises StopIteration when exhausted - _heapreplace(h, s) # restore heap condition - except _StopIteration: - _heappop(h) # remove empty iterator + key_value, order, value, next = s = h[0] + yield value + value = next() + s[0] = key(value) + s[2] = value + _heapreplace(h, s) + except StopIteration: + _heappop(h) if h: - # fast case when only a single iterator remains - v, itnum, next = h[0] - yield v + key_value, order, value, next = h[0] + yield value yield from next.__self__ -# Extend the implementations of nsmallest and nlargest to use a key= argument -_nsmallest = nsmallest + +# Algorithm notes for nlargest() and nsmallest() +# ============================================== +# +# Make a single pass over the data while keeping the k most extreme values +# in a heap. Memory consumption is limited to keeping k values in a list. +# +# Measured performance for random inputs: +# +# number of comparisons +# n inputs k-extreme values (average of 5 trials) % more than min() +# ------------- ---------------- --------------------- ----------------- +# 1,000 100 3,317 231.7% +# 10,000 100 14,046 40.5% +# 100,000 100 105,749 5.7% +# 1,000,000 100 1,007,751 0.8% +# 10,000,000 100 10,009,401 0.1% +# +# Theoretical number of comparisons for k smallest of n random inputs: +# +# Step Comparisons Action +# ---- -------------------------- --------------------------- +# 1 1.66 * k heapify the first k-inputs +# 2 n - k compare remaining elements to top of heap +# 3 k * (1 + lg2(k)) * ln(n/k) replace the topmost value on the heap +# 4 k * lg2(k) - (k/2) final sort of the k most extreme values +# +# Combining and simplifying for a rough estimate gives: +# +# comparisons = n + k * (log(k, 2) * log(n/k) + log(k, 2) + log(n/k)) +# +# Computing the number of comparisons for step 3: +# ----------------------------------------------- +# * For the i-th new value from the iterable, the probability of being in the +# k most extreme values is k/i. For example, the probability of the 101st +# value seen being in the 100 most extreme values is 100/101. +# * If the value is a new extreme value, the cost of inserting it into the +# heap is 1 + log(k, 2). +# * The probability times the cost gives: +# (k/i) * (1 + log(k, 2)) +# * Summing across the remaining n-k elements gives: +# sum((k/i) * (1 + log(k, 2)) for i in range(k+1, n+1)) +# * This reduces to: +# (H(n) - H(k)) * k * (1 + log(k, 2)) +# * Where H(n) is the n-th harmonic number estimated by: +# gamma = 0.5772156649 +# H(n) = log(n, e) + gamma + 1 / (2 * n) +# http://en.wikipedia.org/wiki/Harmonic_series_(mathematics)#Rate_of_divergence +# * Substituting the H(n) formula: +# comparisons = k * (1 + log(k, 2)) * (log(n/k, e) + (1/n - 1/k) / 2) +# +# Worst-case for step 3: +# ---------------------- +# In the worst case, the input data is reversed sorted so that every new element +# must be inserted in the heap: +# +# comparisons = 1.66 * k + log(k, 2) * (n - k) +# +# Alternative Algorithms +# ---------------------- +# Other algorithms were not used because they: +# 1) Took much more auxiliary memory, +# 2) Made multiple passes over the data. +# 3) Made more comparisons in common cases (small k, large n, semi-random input). +# See the more detailed comparison of approach at: +# http://code.activestate.com/recipes/577573-compare-algorithms-for-heapqsmallest + def nsmallest(n, iterable, key=None): """Find the n smallest elements in a dataset. Equivalent to: sorted(iterable, key=key)[:n] """ - # Short-cut for n==1 is to use min() when len(iterable)>0 + + # Short-cut for n==1 is to use min() if n == 1: it = iter(iterable) - head = list(islice(it, 1)) - if not head: - return [] + sentinel = object() if key is None: - return [min(chain(head, it))] - return [min(chain(head, it), key=key)] + result = min(it, default=sentinel) + else: + result = min(it, default=sentinel, key=key) + return [] if result is sentinel else [result] # When n>=size, it's faster to use sorted() try: @@ -413,32 +485,57 @@ def nsmallest(n, iterable, key=None): # When key is none, use simpler decoration if key is None: - it = zip(iterable, count()) # decorate - result = _nsmallest(n, it) - return [r[0] for r in result] # undecorate + it = iter(iterable) + # put the range(n) first so that zip() doesn't + # consume one too many elements from the iterator + result = [(elem, i) for i, elem in zip(range(n), it)] + if not result: + return result + _heapify_max(result) + top = result[0][0] + order = n + _heapreplace = _heapreplace_max + for elem in it: + if elem < top: + _heapreplace(result, (elem, order)) + top = result[0][0] + order += 1 + result.sort() + return [r[0] for r in result] # General case, slowest method - in1, in2 = tee(iterable) - it = zip(map(key, in1), count(), in2) # decorate - result = _nsmallest(n, it) - return [r[2] for r in result] # undecorate + it = iter(iterable) + result = [(key(elem), i, elem) for i, elem in zip(range(n), it)] + if not result: + return result + _heapify_max(result) + top = result[0][0] + order = n + _heapreplace = _heapreplace_max + for elem in it: + k = key(elem) + if k < top: + _heapreplace(result, (k, order, elem)) + top = result[0][0] + order += 1 + result.sort() + return [r[2] for r in result] -_nlargest = nlargest def nlargest(n, iterable, key=None): """Find the n largest elements in a dataset. Equivalent to: sorted(iterable, key=key, reverse=True)[:n] """ - # Short-cut for n==1 is to use max() when len(iterable)>0 + # Short-cut for n==1 is to use max() if n == 1: it = iter(iterable) - head = list(islice(it, 1)) - if not head: - return [] + sentinel = object() if key is None: - return [max(chain(head, it))] - return [max(chain(head, it), key=key)] + result = max(it, default=sentinel) + else: + result = max(it, default=sentinel, key=key) + return [] if result is sentinel else [result] # When n>=size, it's faster to use sorted() try: @@ -451,26 +548,60 @@ def nlargest(n, iterable, key=None): # When key is none, use simpler decoration if key is None: - it = zip(iterable, count(0,-1)) # decorate - result = _nlargest(n, it) - return [r[0] for r in result] # undecorate + it = iter(iterable) + result = [(elem, i) for i, elem in zip(range(0, -n, -1), it)] + if not result: + return result + heapify(result) + top = result[0][0] + order = -n + _heapreplace = heapreplace + for elem in it: + if top < elem: + _heapreplace(result, (elem, order)) + top = result[0][0] + order -= 1 + result.sort(reverse=True) + return [r[0] for r in result] # General case, slowest method - in1, in2 = tee(iterable) - it = zip(map(key, in1), count(0,-1), in2) # decorate - result = _nlargest(n, it) - return [r[2] for r in result] # undecorate + it = iter(iterable) + result = [(key(elem), i, elem) for i, elem in zip(range(0, -n, -1), it)] + if not result: + return result + heapify(result) + top = result[0][0] + order = -n + _heapreplace = heapreplace + for elem in it: + k = key(elem) + if top < k: + _heapreplace(result, (k, order, elem)) + top = result[0][0] + order -= 1 + result.sort(reverse=True) + return [r[2] for r in result] + +# If available, use C implementation +try: + from _heapq import * +except ImportError: + pass +try: + from _heapq import _heapreplace_max +except ImportError: + pass +try: + from _heapq import _heapify_max +except ImportError: + pass +try: + from _heapq import _heappop_max +except ImportError: + pass + if __name__ == "__main__": - # Simple sanity test - heap = [] - data = [1, 3, 5, 7, 9, 2, 4, 6, 8, 0] - for item in data: - heappush(heap, item) - sort = [] - while heap: - sort.append(heappop(heap)) - print(sort) import doctest - doctest.testmod() + print(doctest.testmod()) diff --git a/Lib/html/entities.py b/Lib/html/entities.py index e891ad659901..3e1778b768ce 100644 --- a/Lib/html/entities.py +++ b/Lib/html/entities.py @@ -1,6 +1,9 @@ """HTML character entity references.""" -# maps the HTML entity name to the Unicode codepoint +__all__ = ['html5', 'name2codepoint', 'codepoint2name', 'entitydefs'] + + +# maps the HTML entity name to the Unicode code point name2codepoint = { 'AElig': 0x00c6, # latin capital letter AE = latin capital ligature AE, U+00C6 ISOlat1 'Aacute': 0x00c1, # latin capital letter A with acute, U+00C1 ISOlat1 @@ -2492,7 +2495,7 @@ 'zwnj;': '\u200c', } -# maps the Unicode codepoint to the HTML entity name +# maps the Unicode code point to the HTML entity name codepoint2name = {} # maps the HTML entity name to the character diff --git a/Lib/html/parser.py b/Lib/html/parser.py index 12c28b8339ff..390d4ccc488b 100644 --- a/Lib/html/parser.py +++ b/Lib/html/parser.py @@ -29,35 +29,15 @@ piclose = re.compile('>') commentclose = re.compile(r'--\s*>') # Note: -# 1) the strict attrfind isn't really strict, but we can't make it -# correctly strict without breaking backward compatibility; -# 2) if you change tagfind/attrfind remember to update locatestarttagend too; -# 3) if you change tagfind/attrfind and/or locatestarttagend the parser will +# 1) if you change tagfind/attrfind remember to update locatestarttagend too; +# 2) if you change tagfind/attrfind and/or locatestarttagend the parser will # explode, so don't do it. -tagfind = re.compile('([a-zA-Z][-.a-zA-Z0-9:_]*)(?:\s|/(?!>))*') # see http://www.w3.org/TR/html5/tokenization.html#tag-open-state # and http://www.w3.org/TR/html5/tokenization.html#tag-name-state tagfind_tolerant = re.compile('([a-zA-Z][^\t\n\r\f />\x00]*)(?:\s|/(?!>))*') -attrfind = re.compile( - r'\s*([a-zA-Z_][-.:a-zA-Z_0-9]*)(\s*=\s*' - r'(\'[^\']*\'|"[^"]*"|[^\s"\'=<>`]*))?') attrfind_tolerant = re.compile( r'((?<=[\'"\s/])[^\s/>][^\s/=>]*)(\s*=+\s*' r'(\'[^\']*\'|"[^"]*"|(?![\'"])[^>\s]*))?(?:\s|/(?!>))*') -locatestarttagend = re.compile(r""" - <[a-zA-Z][-.a-zA-Z0-9:_]* # tag name - (?:\s+ # whitespace before attribute name - (?:[a-zA-Z_][-.:a-zA-Z0-9_]* # attribute name - (?:\s*=\s* # value indicator - (?:'[^']*' # LITA-enclosed value - |\"[^\"]*\" # LIT-enclosed value - |[^'\">\s]+ # bare value - ) - )? - ) - )* - \s* # trailing whitespace -""", re.VERBOSE) locatestarttagend_tolerant = re.compile(r""" <[a-zA-Z][^\t\n\r\f />\x00]* # tag name (?:[\s/]* # optional whitespace before attribute name @@ -79,25 +59,6 @@ endtagfind = re.compile('</\s*([a-zA-Z][-.a-zA-Z0-9:_]*)\s*>') -class HTMLParseError(Exception): - """Exception raised for all parse errors.""" - - def __init__(self, msg, position=(None, None)): - assert msg - self.msg = msg - self.lineno = position[0] - self.offset = position[1] - - def __str__(self): - result = self.msg - if self.lineno is not None: - result = result + ", at line %d" % self.lineno - if self.offset is not None: - result = result + ", column %d" % (self.offset + 1) - return result - - -_default_sentinel = object() class HTMLParser(_markupbase.ParserBase): """Find tags and other markup and call handler functions. @@ -123,27 +84,12 @@ class HTMLParser(_markupbase.ParserBase): CDATA_CONTENT_ELEMENTS = ("script", "style") - def __init__(self, strict=_default_sentinel, *, - convert_charrefs=_default_sentinel): + def __init__(self, *, convert_charrefs=True): """Initialize and reset this instance. - If convert_charrefs is True (default: False), all character references + If convert_charrefs is True (the default), all character references are automatically converted to the corresponding Unicode characters. - If strict is set to False (the default) the parser will parse invalid - markup, otherwise it will raise an error. Note that the strict mode - and argument are deprecated. """ - if strict is not _default_sentinel: - warnings.warn("The strict argument and mode are deprecated.", - DeprecationWarning, stacklevel=2) - else: - strict = False # default - self.strict = strict - if convert_charrefs is _default_sentinel: - convert_charrefs = False # default - warnings.warn("The value of convert_charrefs will become True in " - "3.5. You are encouraged to set the value explicitly.", - DeprecationWarning, stacklevel=2) self.convert_charrefs = convert_charrefs self.reset() @@ -168,11 +114,6 @@ def close(self): """Handle any buffered data.""" self.goahead(1) - def error(self, message): - warnings.warn("The 'error' method is deprecated.", - DeprecationWarning, stacklevel=2) - raise HTMLParseError(message, self.getpos()) - __starttag_text = None def get_starttag_text(self): @@ -227,10 +168,7 @@ def goahead(self, end): elif startswith("<?", i): k = self.parse_pi(i) elif startswith("<!", i): - if self.strict: - k = self.parse_declaration(i) - else: - k = self.parse_html_declaration(i) + k = self.parse_html_declaration(i) elif (i + 1) < n: self.handle_data("<") k = i + 1 @@ -239,8 +177,6 @@ def goahead(self, end): if k < 0: if not end: break - if self.strict: - self.error("EOF in middle of construct") k = rawdata.find('>', i + 1) if k < 0: k = rawdata.find('<', i + 1) @@ -264,9 +200,9 @@ def goahead(self, end): i = self.updatepos(i, k) continue else: - if ";" in rawdata[i:]: #bail by consuming &# - self.handle_data(rawdata[0:2]) - i = self.updatepos(i, 2) + if ";" in rawdata[i:]: # bail by consuming &# + self.handle_data(rawdata[i:i+2]) + i = self.updatepos(i, i+2) break elif startswith('&', i): match = entityref.match(rawdata, i) @@ -282,13 +218,10 @@ def goahead(self, end): if match: # match.group() will contain at least 2 chars if end and match.group() == rawdata[i:]: - if self.strict: - self.error("EOF in middle of entity or char ref") - else: - k = match.end() - if k <= i: - k = n - i = self.updatepos(i, i + 1) + k = match.end() + if k <= i: + k = n + i = self.updatepos(i, i + 1) # incomplete break elif (i + 1) < n: @@ -367,18 +300,12 @@ def parse_starttag(self, i): # Now parse the data between i+1 and j into a tag and attrs attrs = [] - if self.strict: - match = tagfind.match(rawdata, i+1) - else: - match = tagfind_tolerant.match(rawdata, i+1) + match = tagfind_tolerant.match(rawdata, i+1) assert match, 'unexpected call to parse_starttag()' k = match.end() self.lasttag = tag = match.group(1).lower() while k < endpos: - if self.strict: - m = attrfind.match(rawdata, k) - else: - m = attrfind_tolerant.match(rawdata, k) + m = attrfind_tolerant.match(rawdata, k) if not m: break attrname, rest, attrvalue = m.group(1, 2, 3) @@ -401,9 +328,6 @@ def parse_starttag(self, i): - self.__starttag_text.rfind("\n") else: offset = offset + len(self.__starttag_text) - if self.strict: - self.error("junk characters in start tag: %r" - % (rawdata[k:endpos][:20],)) self.handle_data(rawdata[i:endpos]) return endpos if end.endswith('/>'): @@ -419,10 +343,7 @@ def parse_starttag(self, i): # or -1 if incomplete. def check_for_whole_start_tag(self, i): rawdata = self.rawdata - if self.strict: - m = locatestarttagend.match(rawdata, i) - else: - m = locatestarttagend_tolerant.match(rawdata, i) + m = locatestarttagend_tolerant.match(rawdata, i) if m: j = m.end() next = rawdata[j:j+1] @@ -435,9 +356,6 @@ def check_for_whole_start_tag(self, i): # buffer boundary return -1 # else bogus input - if self.strict: - self.updatepos(i, j + 1) - self.error("malformed empty start tag") if j > i: return j else: @@ -450,9 +368,6 @@ def check_for_whole_start_tag(self, i): # end of input in or before attribute value, or we have the # '/' from a '/>' ending return -1 - if self.strict: - self.updatepos(i, j) - self.error("malformed start tag") if j > i: return j else: @@ -472,8 +387,6 @@ def parse_endtag(self, i): if self.cdata_elem is not None: self.handle_data(rawdata[i:gtpos]) return gtpos - if self.strict: - self.error("bad end tag: %r" % (rawdata[i:gtpos],)) # find the name: w3.org/TR/html5/tokenization.html#tag-name-state namematch = tagfind_tolerant.match(rawdata, i+2) if not namematch: @@ -539,8 +452,7 @@ def handle_pi(self, data): pass def unknown_decl(self, data): - if self.strict: - self.error("unknown declaration: %r" % (data,)) + pass # Internal -- helper to remove special character quoting def unescape(self, s): diff --git a/Lib/http/__init__.py b/Lib/http/__init__.py index 196d37885759..d4334cc88f9f 100644 --- a/Lib/http/__init__.py +++ b/Lib/http/__init__.py @@ -1 +1,134 @@ -# This directory is a Python package. +from enum import IntEnum + +__all__ = ['HTTPStatus'] + +class HTTPStatus(IntEnum): + """HTTP status codes and reason phrases + + Status codes from the following RFCs are all observed: + + * RFC 7231: Hypertext Transfer Protocol (HTTP/1.1), obsoletes 2616 + * RFC 6585: Additional HTTP Status Codes + * RFC 3229: Delta encoding in HTTP + * RFC 4918: HTTP Extensions for WebDAV, obsoletes 2518 + * RFC 5842: Binding Extensions to WebDAV + * RFC 7238: Permanent Redirect + * RFC 2295: Transparent Content Negotiation in HTTP + * RFC 2774: An HTTP Extension Framework + """ + def __new__(cls, value, phrase, description=''): + obj = int.__new__(cls, value) + obj._value_ = value + + obj.phrase = phrase + obj.description = description + return obj + + # informational + CONTINUE = 100, 'Continue', 'Request received, please continue' + SWITCHING_PROTOCOLS = (101, 'Switching Protocols', + 'Switching to new protocol; obey Upgrade header') + PROCESSING = 102, 'Processing' + + # success + OK = 200, 'OK', 'Request fulfilled, document follows' + CREATED = 201, 'Created', 'Document created, URL follows' + ACCEPTED = (202, 'Accepted', + 'Request accepted, processing continues off-line') + NON_AUTHORITATIVE_INFORMATION = (203, + 'Non-Authoritative Information', 'Request fulfilled from cache') + NO_CONTENT = 204, 'No Content', 'Request fulfilled, nothing follows' + RESET_CONTENT = 205, 'Reset Content', 'Clear input form for further input' + PARTIAL_CONTENT = 206, 'Partial Content', 'Partial content follows' + MULTI_STATUS = 207, 'Multi-Status' + ALREADY_REPORTED = 208, 'Already Reported' + IM_USED = 226, 'IM Used' + + # redirection + MULTIPLE_CHOICES = (300, 'Multiple Choices', + 'Object has several resources -- see URI list') + MOVED_PERMANENTLY = (301, 'Moved Permanently', + 'Object moved permanently -- see URI list') + FOUND = 302, 'Found', 'Object moved temporarily -- see URI list' + SEE_OTHER = 303, 'See Other', 'Object moved -- see Method and URL list' + NOT_MODIFIED = (304, 'Not Modified', + 'Document has not changed since given time') + USE_PROXY = (305, 'Use Proxy', + 'You must use proxy specified in Location to access this resource') + TEMPORARY_REDIRECT = (307, 'Temporary Redirect', + 'Object moved temporarily -- see URI list') + PERMANENT_REDIRECT = (308, 'Permanent Redirect', + 'Object moved temporarily -- see URI list') + + # client error + BAD_REQUEST = (400, 'Bad Request', + 'Bad request syntax or unsupported method') + UNAUTHORIZED = (401, 'Unauthorized', + 'No permission -- see authorization schemes') + PAYMENT_REQUIRED = (402, 'Payment Required', + 'No payment -- see charging schemes') + FORBIDDEN = (403, 'Forbidden', + 'Request forbidden -- authorization will not help') + NOT_FOUND = (404, 'Not Found', + 'Nothing matches the given URI') + METHOD_NOT_ALLOWED = (405, 'Method Not Allowed', + 'Specified method is invalid for this resource') + NOT_ACCEPTABLE = (406, 'Not Acceptable', + 'URI not available in preferred format') + PROXY_AUTHENTICATION_REQUIRED = (407, + 'Proxy Authentication Required', + 'You must authenticate with this proxy before proceeding') + REQUEST_TIMEOUT = (408, 'Request Timeout', + 'Request timed out; try again later') + CONFLICT = 409, 'Conflict', 'Request conflict' + GONE = (410, 'Gone', + 'URI no longer exists and has been permanently removed') + LENGTH_REQUIRED = (411, 'Length Required', + 'Client must specify Content-Length') + PRECONDITION_FAILED = (412, 'Precondition Failed', + 'Precondition in headers is false') + REQUEST_ENTITY_TOO_LARGE = (413, 'Request Entity Too Large', + 'Entity is too large') + REQUEST_URI_TOO_LONG = (414, 'Request-URI Too Long', + 'URI is too long') + UNSUPPORTED_MEDIA_TYPE = (415, 'Unsupported Media Type', + 'Entity body in unsupported format') + REQUESTED_RANGE_NOT_SATISFIABLE = (416, + 'Requested Range Not Satisfiable', + 'Cannot satisfy request range') + EXPECTATION_FAILED = (417, 'Expectation Failed', + 'Expect condition could not be satisfied') + UNPROCESSABLE_ENTITY = 422, 'Unprocessable Entity' + LOCKED = 423, 'Locked' + FAILED_DEPENDENCY = 424, 'Failed Dependency' + UPGRADE_REQUIRED = 426, 'Upgrade Required' + PRECONDITION_REQUIRED = (428, 'Precondition Required', + 'The origin server requires the request to be conditional') + TOO_MANY_REQUESTS = (429, 'Too Many Requests', + 'The user has sent too many requests in ' + 'a given amount of time ("rate limiting")') + REQUEST_HEADER_FIELDS_TOO_LARGE = (431, + 'Request Header Fields Too Large', + 'The server is unwilling to process the request because its header ' + 'fields are too large') + + # server errors + INTERNAL_SERVER_ERROR = (500, 'Internal Server Error', + 'Server got itself in trouble') + NOT_IMPLEMENTED = (501, 'Not Implemented', + 'Server does not support this operation') + BAD_GATEWAY = (502, 'Bad Gateway', + 'Invalid responses from another server/proxy') + SERVICE_UNAVAILABLE = (503, 'Service Unavailable', + 'The server cannot process the request due to a high load') + GATEWAY_TIMEOUT = (504, 'Gateway Timeout', + 'The gateway server did not receive a timely response') + HTTP_VERSION_NOT_SUPPORTED = (505, 'HTTP Version Not Supported', + 'Cannot fulfill request') + VARIANT_ALSO_NEGOTIATES = 506, 'Variant Also Negotiates' + INSUFFICIENT_STORAGE = 507, 'Insufficient Storage' + LOOP_DETECTED = 508, 'Loop Detected' + NOT_EXTENDED = 510, 'Not Extended' + NETWORK_AUTHENTICATION_REQUIRED = (511, + 'Network Authentication Required', + 'The client needs to authenticate to gain network access') diff --git a/Lib/http/client.py b/Lib/http/client.py index 5c52ba349ac0..5e12a858d85f 100644 --- a/Lib/http/client.py +++ b/Lib/http/client.py @@ -68,19 +68,21 @@ import email.parser import email.message +import http import io import os import socket import collections from urllib.parse import urlsplit -import warnings +# HTTPMessage, parse_headers(), and the HTTP status code constants are +# intentionally omitted for simplicity __all__ = ["HTTPResponse", "HTTPConnection", "HTTPException", "NotConnected", "UnknownProtocol", "UnknownTransferEncoding", "UnimplementedFileMode", "IncompleteRead", "InvalidURL", "ImproperConnectionState", "CannotSendRequest", "CannotSendHeader", "ResponseNotReady", - "BadStatusLine", "error", "responses"] + "BadStatusLine", "LineTooLong", "error", "responses"] HTTP_PORT = 80 HTTPS_PORT = 443 @@ -92,122 +94,13 @@ _CS_REQ_STARTED = 'Request-started' _CS_REQ_SENT = 'Request-sent' -# status codes -# informational -CONTINUE = 100 -SWITCHING_PROTOCOLS = 101 -PROCESSING = 102 - -# successful -OK = 200 -CREATED = 201 -ACCEPTED = 202 -NON_AUTHORITATIVE_INFORMATION = 203 -NO_CONTENT = 204 -RESET_CONTENT = 205 -PARTIAL_CONTENT = 206 -MULTI_STATUS = 207 -IM_USED = 226 - -# redirection -MULTIPLE_CHOICES = 300 -MOVED_PERMANENTLY = 301 -FOUND = 302 -SEE_OTHER = 303 -NOT_MODIFIED = 304 -USE_PROXY = 305 -TEMPORARY_REDIRECT = 307 - -# client error -BAD_REQUEST = 400 -UNAUTHORIZED = 401 -PAYMENT_REQUIRED = 402 -FORBIDDEN = 403 -NOT_FOUND = 404 -METHOD_NOT_ALLOWED = 405 -NOT_ACCEPTABLE = 406 -PROXY_AUTHENTICATION_REQUIRED = 407 -REQUEST_TIMEOUT = 408 -CONFLICT = 409 -GONE = 410 -LENGTH_REQUIRED = 411 -PRECONDITION_FAILED = 412 -REQUEST_ENTITY_TOO_LARGE = 413 -REQUEST_URI_TOO_LONG = 414 -UNSUPPORTED_MEDIA_TYPE = 415 -REQUESTED_RANGE_NOT_SATISFIABLE = 416 -EXPECTATION_FAILED = 417 -UNPROCESSABLE_ENTITY = 422 -LOCKED = 423 -FAILED_DEPENDENCY = 424 -UPGRADE_REQUIRED = 426 -PRECONDITION_REQUIRED = 428 -TOO_MANY_REQUESTS = 429 -REQUEST_HEADER_FIELDS_TOO_LARGE = 431 - -# server error -INTERNAL_SERVER_ERROR = 500 -NOT_IMPLEMENTED = 501 -BAD_GATEWAY = 502 -SERVICE_UNAVAILABLE = 503 -GATEWAY_TIMEOUT = 504 -HTTP_VERSION_NOT_SUPPORTED = 505 -INSUFFICIENT_STORAGE = 507 -NOT_EXTENDED = 510 -NETWORK_AUTHENTICATION_REQUIRED = 511 +# hack to maintain backwards compatibility +globals().update(http.HTTPStatus.__members__) + +# another hack to maintain backwards compatibility # Mapping status codes to official W3C names -responses = { - 100: 'Continue', - 101: 'Switching Protocols', - - 200: 'OK', - 201: 'Created', - 202: 'Accepted', - 203: 'Non-Authoritative Information', - 204: 'No Content', - 205: 'Reset Content', - 206: 'Partial Content', - - 300: 'Multiple Choices', - 301: 'Moved Permanently', - 302: 'Found', - 303: 'See Other', - 304: 'Not Modified', - 305: 'Use Proxy', - 306: '(Unused)', - 307: 'Temporary Redirect', - - 400: 'Bad Request', - 401: 'Unauthorized', - 402: 'Payment Required', - 403: 'Forbidden', - 404: 'Not Found', - 405: 'Method Not Allowed', - 406: 'Not Acceptable', - 407: 'Proxy Authentication Required', - 408: 'Request Timeout', - 409: 'Conflict', - 410: 'Gone', - 411: 'Length Required', - 412: 'Precondition Failed', - 413: 'Request Entity Too Large', - 414: 'Request-URI Too Long', - 415: 'Unsupported Media Type', - 416: 'Requested Range Not Satisfiable', - 417: 'Expectation Failed', - 428: 'Precondition Required', - 429: 'Too Many Requests', - 431: 'Request Header Fields Too Large', - - 500: 'Internal Server Error', - 501: 'Not Implemented', - 502: 'Bad Gateway', - 503: 'Service Unavailable', - 504: 'Gateway Timeout', - 505: 'HTTP Version Not Supported', - 511: 'Network Authentication Required', -} +responses = {v: v.phrase for v in http.HTTPStatus.__members__.values()} # maximal amount of data to read at one time in _safe_read MAXAMOUNT = 1048576 @@ -271,7 +164,7 @@ def parse_headers(fp, _class=HTTPMessage): return email.parser.Parser(_class=_class).parsestr(hstring) -class HTTPResponse(io.RawIOBase): +class HTTPResponse(io.BufferedIOBase): # See RFC 2616 sec 19.6 and RFC 1945 sec 6 for details. @@ -496,9 +389,10 @@ def read(self, amt=None): return b"" if amt is not None: - # Amount is given, so call base class version - # (which is implemented in terms of self.readinto) - return super(HTTPResponse, self).read(amt) + # Amount is given, implement using readinto + b = bytearray(amt) + n = self.readinto(b) + return memoryview(b)[:n].tobytes() else: # Amount is not given (unbounded read) so we must check self.length # and self.chunked @@ -538,7 +432,7 @@ def readinto(self, b): # connection, and the user is reading more bytes than will be provided # (for example, reading in 1k chunks) n = self.fp.readinto(b) - if not n: + if not n and b: # Ideally, we would raise IncompleteRead if the content-length # wasn't satisfied, but it might break compatibility. self._close_conn() @@ -578,71 +472,67 @@ def _read_and_discard_trailer(self): if line in (b'\r\n', b'\n', b''): break + def _get_chunk_left(self): + # return self.chunk_left, reading a new chunk if necessary. + # chunk_left == 0: at the end of the current chunk, need to close it + # chunk_left == None: No current chunk, should read next. + # This function returns non-zero or None if the last chunk has + # been read. + chunk_left = self.chunk_left + if not chunk_left: # Can be 0 or None + if chunk_left is not None: + # We are at the end of chunk. dicard chunk end + self._safe_read(2) # toss the CRLF at the end of the chunk + try: + chunk_left = self._read_next_chunk_size() + except ValueError: + raise IncompleteRead(b'') + if chunk_left == 0: + # last chunk: 1*("0") [ chunk-extension ] CRLF + self._read_and_discard_trailer() + # we read everything; close the "file" + self._close_conn() + chunk_left = None + self.chunk_left = chunk_left + return chunk_left + def _readall_chunked(self): assert self.chunked != _UNKNOWN - chunk_left = self.chunk_left value = [] - while True: - if chunk_left is None: - try: - chunk_left = self._read_next_chunk_size() - if chunk_left == 0: - break - except ValueError: - raise IncompleteRead(b''.join(value)) - value.append(self._safe_read(chunk_left)) - - # we read the whole chunk, get another - self._safe_read(2) # toss the CRLF at the end of the chunk - chunk_left = None - - self._read_and_discard_trailer() - - # we read everything; close the "file" - self._close_conn() - - return b''.join(value) + try: + while True: + chunk_left = self._get_chunk_left() + if chunk_left is None: + break + value.append(self._safe_read(chunk_left)) + self.chunk_left = 0 + return b''.join(value) + except IncompleteRead: + raise IncompleteRead(b''.join(value)) def _readinto_chunked(self, b): assert self.chunked != _UNKNOWN - chunk_left = self.chunk_left - total_bytes = 0 mvb = memoryview(b) - while True: - if chunk_left is None: - try: - chunk_left = self._read_next_chunk_size() - if chunk_left == 0: - break - except ValueError: - raise IncompleteRead(bytes(b[0:total_bytes])) - - if len(mvb) < chunk_left: - n = self._safe_readinto(mvb) - self.chunk_left = chunk_left - n - return total_bytes + n - elif len(mvb) == chunk_left: - n = self._safe_readinto(mvb) - self._safe_read(2) # toss the CRLF at the end of the chunk - self.chunk_left = None - return total_bytes + n - else: - temp_mvb = mvb[0:chunk_left] + try: + while True: + chunk_left = self._get_chunk_left() + if chunk_left is None: + return total_bytes + + if len(mvb) <= chunk_left: + n = self._safe_readinto(mvb) + self.chunk_left = chunk_left - n + return total_bytes + n + + temp_mvb = mvb[:chunk_left] n = self._safe_readinto(temp_mvb) mvb = mvb[n:] total_bytes += n + self.chunk_left = 0 - # we read the whole chunk, get another - self._safe_read(2) # toss the CRLF at the end of the chunk - chunk_left = None - - self._read_and_discard_trailer() - - # we read everything; close the "file" - self._close_conn() - - return total_bytes + except IncompleteRead: + raise IncompleteRead(bytes(b[0:total_bytes])) def _safe_read(self, amt): """Read the number of bytes requested, compensating for partial reads. @@ -683,6 +573,73 @@ def _safe_readinto(self, b): total_bytes += n return total_bytes + def read1(self, n=-1): + """Read with at most one underlying system call. If at least one + byte is buffered, return that instead. + """ + if self.fp is None or self._method == "HEAD": + return b"" + if self.chunked: + return self._read1_chunked(n) + try: + result = self.fp.read1(n) + except ValueError: + if n >= 0: + raise + # some implementations, like BufferedReader, don't support -1 + # Read an arbitrarily selected largeish chunk. + result = self.fp.read1(16*1024) + if not result and n: + self._close_conn() + return result + + def peek(self, n=-1): + # Having this enables IOBase.readline() to read more than one + # byte at a time + if self.fp is None or self._method == "HEAD": + return b"" + if self.chunked: + return self._peek_chunked(n) + return self.fp.peek(n) + + def readline(self, limit=-1): + if self.fp is None or self._method == "HEAD": + return b"" + if self.chunked: + # Fallback to IOBase readline which uses peek() and read() + return super().readline(limit) + result = self.fp.readline(limit) + if not result and limit: + self._close_conn() + return result + + def _read1_chunked(self, n): + # Strictly speaking, _get_chunk_left() may cause more than one read, + # but that is ok, since that is to satisfy the chunked protocol. + chunk_left = self._get_chunk_left() + if chunk_left is None or n == 0: + return b'' + if not (0 <= n <= chunk_left): + n = chunk_left # if n is negative or larger than chunk_left + read = self.fp.read1(n) + self.chunk_left -= len(read) + if not read: + raise IncompleteRead(b"") + return read + + def _peek_chunked(self, n): + # Strictly speaking, _get_chunk_left() may cause more than one read, + # but that is ok, since that is to satisfy the chunked protocol. + try: + chunk_left = self._get_chunk_left() + except IncompleteRead: + return b'' # peek doesn't worry about protocol + if chunk_left is None: + return b'' # eof + # peek is allowed to return more than requested. Just request the + # entire chunk, and truncate what we get. + return self.fp.peek(chunk_left)[:chunk_left] + def fileno(self): return self.fp.fileno() @@ -726,14 +683,6 @@ class HTTPConnection: default_port = HTTP_PORT auto_open = 1 debuglevel = 0 - # TCP Maximum Segment Size (MSS) is determined by the TCP stack on - # a per-connection basis. There is no simple and efficient - # platform independent mechanism for determining the MSS, so - # instead a reasonable estimate is chosen. The getsockopt() - # interface using the TCP_MAXSEG parameter may be a suitable - # approach on some operating systems. A value of 16KiB is chosen - # as a reasonable estimate of the maximum MSS. - mss = 16384 def __init__(self, host, port=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, source_address=None): @@ -748,22 +697,37 @@ def __init__(self, host, port=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, self._tunnel_port = None self._tunnel_headers = {} - self._set_hostport(host, port) + (self.host, self.port) = self._get_hostport(host, port) + + # This is stored as an instance variable to allow unit + # tests to replace it with a suitable mockup + self._create_connection = socket.create_connection def set_tunnel(self, host, port=None, headers=None): - """ Sets up the host and the port for the HTTP CONNECT Tunnelling. + """Set up host and port for HTTP CONNECT tunnelling. + + In a connection that uses HTTP CONNECT tunneling, the host passed to the + constructor is used as a proxy server that relays all communication to + the endpoint passed to `set_tunnel`. This done by sending an HTTP + CONNECT request to the proxy server when the connection is established. - The headers argument should be a mapping of extra HTTP headers - to send with the CONNECT request. + This method must be called before the HTML connection has been + established. + + The headers argument should be a mapping of extra HTTP headers to send + with the CONNECT request. """ - self._tunnel_host = host - self._tunnel_port = port + + if self.sock: + raise RuntimeError("Can't set up tunnel for established connection") + + self._tunnel_host, self._tunnel_port = self._get_hostport(host, port) if headers: self._tunnel_headers = headers else: self._tunnel_headers.clear() - def _set_hostport(self, host, port): + def _get_hostport(self, host, port): if port is None: i = host.rfind(':') j = host.rfind(']') # ipv6 addresses have [...] @@ -780,15 +744,15 @@ def _set_hostport(self, host, port): port = self.default_port if host and host[0] == '[' and host[-1] == ']': host = host[1:-1] - self.host = host - self.port = port + + return (host, port) def set_debuglevel(self, level): self.debuglevel = level def _tunnel(self): - self._set_hostport(self._tunnel_host, self._tunnel_port) - connect_str = "CONNECT %s:%d HTTP/1.0\r\n" % (self.host, self.port) + connect_str = "CONNECT %s:%d HTTP/1.0\r\n" % (self._tunnel_host, + self._tunnel_port) connect_bytes = connect_str.encode("ascii") self.send(connect_bytes) for header, value in self._tunnel_headers.items(): @@ -800,7 +764,7 @@ def _tunnel(self): response = self.response_class(self.sock, method=self._method) (version, code, message) = response._read_status() - if code != 200: + if code != http.HTTPStatus.OK: self.close() raise OSError("Tunnel connection failed: %d %s" % (code, message.strip())) @@ -814,10 +778,15 @@ def _tunnel(self): if line in (b'\r\n', b'\n', b''): break + if self.debuglevel > 0: + print('header:', line.decode()) + def connect(self): """Connect to the host and port specified in __init__.""" - self.sock = socket.create_connection((self.host,self.port), - self.timeout, self.source_address) + self.sock = self._create_connection( + (self.host,self.port), self.timeout, self.source_address) + self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) + if self._tunnel_host: self._tunnel() @@ -895,19 +864,9 @@ def _send_output(self, message_body=None): self._buffer.extend((b"", b"")) msg = b"\r\n".join(self._buffer) del self._buffer[:] - # If msg and message_body are sent in a single send() call, - # it will avoid performance problems caused by the interaction - # between delayed ack and the Nagle algorithm. However, - # there is no performance gain if the message is larger - # than MSS (and there is a memory penalty for the message - # copy). - if isinstance(message_body, bytes) and len(message_body) < self.mss: - msg += message_body - message_body = None + self.send(msg) if message_body is not None: - # message_body was not a string (i.e. it is a file), and - # we must run the risk of Nagle. self.send(message_body) def putrequest(self, method, url, skip_host=0, skip_accept_encoding=0): @@ -986,22 +945,29 @@ def putrequest(self, method, url, skip_host=0, skip_accept_encoding=0): netloc_enc = netloc.encode("idna") self.putheader('Host', netloc_enc) else: + if self._tunnel_host: + host = self._tunnel_host + port = self._tunnel_port + else: + host = self.host + port = self.port + try: - host_enc = self.host.encode("ascii") + host_enc = host.encode("ascii") except UnicodeEncodeError: - host_enc = self.host.encode("idna") + host_enc = host.encode("idna") # As per RFC 273, IPv6 address should be wrapped with [] # when used as Host header - if self.host.find(':') >= 0: + if host.find(':') >= 0: host_enc = b'[' + host_enc + b']' - if self.port == self.default_port: + if port == self.default_port: self.putheader('Host', host_enc) else: host_enc = host_enc.decode("ascii") - self.putheader('Host', "%s:%s" % (host_enc, self.port)) + self.putheader('Host', "%s:%s" % (host_enc, port)) # note: we are assuming that clients will not attempt to set these # headers since *this* library must deal with the @@ -1145,18 +1111,22 @@ class the response_class variable. else: response = self.response_class(self.sock, method=self._method) - response.begin() - assert response.will_close != _UNKNOWN - self.__state = _CS_IDLE + try: + response.begin() + assert response.will_close != _UNKNOWN + self.__state = _CS_IDLE - if response.will_close: - # this effectively passes the connection to the response - self.close() - else: - # remember this, so we can tell when it is complete - self.__response = response + if response.will_close: + # this effectively passes the connection to the response + self.close() + else: + # remember this, so we can tell when it is complete + self.__response = response - return response + return response + except: + response.close() + raise try: import ssl @@ -1179,11 +1149,11 @@ def __init__(self, host, port=None, key_file=None, cert_file=None, self.key_file = key_file self.cert_file = cert_file if context is None: - context = ssl._create_stdlib_context() + context = ssl._create_default_https_context() will_verify = context.verify_mode != ssl.CERT_NONE if check_hostname is None: - check_hostname = will_verify - elif check_hostname and not will_verify: + check_hostname = context.check_hostname + if check_hostname and not will_verify: raise ValueError("check_hostname needs a SSL context with " "either CERT_OPTIONAL or CERT_REQUIRED") if key_file or cert_file: @@ -1194,23 +1164,22 @@ def __init__(self, host, port=None, key_file=None, cert_file=None, def connect(self): "Connect to a host on a given (SSL) port." - sock = socket.create_connection((self.host, self.port), - self.timeout, self.source_address) + super().connect() if self._tunnel_host: - self.sock = sock - self._tunnel() + server_hostname = self._tunnel_host + else: + server_hostname = self.host - server_hostname = self.host if ssl.HAS_SNI else None - self.sock = self._context.wrap_socket(sock, + self.sock = self._context.wrap_socket(self.sock, server_hostname=server_hostname) - try: - if self._check_hostname: - ssl.match_hostname(self.sock.getpeercert(), self.host) - except Exception: - self.sock.shutdown(socket.SHUT_RDWR) - self.sock.close() - raise + if not self._context.check_hostname and self._check_hostname: + try: + ssl.match_hostname(self.sock.getpeercert(), server_hostname) + except Exception: + self.sock.shutdown(socket.SHUT_RDWR) + self.sock.close() + raise __all__.append("HTTPSConnection") @@ -1246,7 +1215,8 @@ def __repr__(self): e = ', %i more expected' % self.expected else: e = '' - return 'IncompleteRead(%i bytes read%s)' % (len(self.partial), e) + return '%s(%i bytes read%s)' % (self.__class__.__name__, + len(self.partial), e) def __str__(self): return repr(self) diff --git a/Lib/http/cookiejar.py b/Lib/http/cookiejar.py index be828eba6987..22f283372ef8 100644 --- a/Lib/http/cookiejar.py +++ b/Lib/http/cookiejar.py @@ -478,7 +478,7 @@ def parse_ns_headers(ns_headers): if "=" not in param: k, v = param, None else: - k, v = re.split(r"\s*=\s*", param, 1) + k, v = re.split(r"\s*=\s*", param, maxsplit=1) k = k.lstrip() if ii != 0: lc = k.lower() @@ -805,7 +805,7 @@ def __repr__(self): args.append("%s=%s" % (name, repr(attr))) args.append("rest=%s" % repr(self._rest)) args.append("rfc2109=%s" % repr(self.rfc2109)) - return "Cookie(%s)" % ", ".join(args) + return "%s(%s)" % (self.__class__.__name__, ", ".join(args)) class CookiePolicy: @@ -1722,12 +1722,12 @@ def __len__(self): def __repr__(self): r = [] for cookie in self: r.append(repr(cookie)) - return "<%s[%s]>" % (self.__class__, ", ".join(r)) + return "<%s[%s]>" % (self.__class__.__name__, ", ".join(r)) def __str__(self): r = [] for cookie in self: r.append(str(cookie)) - return "<%s[%s]>" % (self.__class__, ", ".join(r)) + return "<%s[%s]>" % (self.__class__.__name__, ", ".join(r)) # derives from OSError for backwards-compatibility with Python 2.4.0 @@ -1792,7 +1792,7 @@ def revert(self, filename=None, def lwp_cookie_str(cookie): - """Return string representation of Cookie in an the LWP cookie file format. + """Return string representation of Cookie in the LWP cookie file format. Actually, the format is extended a bit -- see module docstring. @@ -1973,7 +1973,7 @@ class MozillaCookieJar(FileCookieJar): magic_re = re.compile("#( Netscape)? HTTP Cookie File") header = """\ # Netscape HTTP Cookie File -# http://www.netscape.com/newsref/std/cookie_spec.html +# http://curl.haxx.se/rfc/cookie_spec.html # This is a generated file! Do not edit. """ diff --git a/Lib/http/cookies.py b/Lib/http/cookies.py index dc3c74a8db24..73acbc718a1f 100644 --- a/Lib/http/cookies.py +++ b/Lib/http/cookies.py @@ -1,6 +1,3 @@ -#!/usr/bin/env python3 -# - #### # Copyright 2000 by Timothy O'Malley <timo@alum.mit.edu> # @@ -333,8 +330,8 @@ class Morsel(dict): "comment" : "Comment", "domain" : "Domain", "max-age" : "Max-Age", - "secure" : "secure", - "httponly" : "httponly", + "secure" : "Secure", + "httponly" : "HttpOnly", "version" : "Version", } @@ -434,6 +431,7 @@ def OutputString(self, attrs=None): _LegalCharsPatt = r"[\w\d!#%&'~_`><@,:/\$\*\+\-\.\^\|\)\(\?\}\{\=]" _CookiePattern = re.compile(r""" (?x) # This is a verbose pattern + \s* # Optional whitespace at start of cookie (?P<key> # Start of group 'key' """ + _LegalCharsPatt + r"""+? # Any word of at least one letter ) # End of group 'key' @@ -488,8 +486,12 @@ def __set(self, key, real_value, coded_value): def __setitem__(self, key, value): """Dictionary style assignment.""" - rval, cval = self.value_encode(value) - self.__set(key, rval, cval) + if isinstance(value, Morsel): + # allow assignment of constructed Morsels (e.g. for pickling) + dict.__setitem__(self, key, value) + else: + rval, cval = self.value_encode(value) + self.__set(key, rval, cval) def output(self, attrs=None, header="Set-Cookie:", sep="\015\012"): """Return a string suitable for HTTP.""" @@ -531,13 +533,20 @@ def load(self, rawdata): return def __parse_string(self, str, patt=_CookiePattern): - i = 0 # Our starting point - n = len(str) # Length of string - M = None # current morsel + i = 0 # Our starting point + n = len(str) # Length of string + parsed_items = [] # Parsed (type, key, value) triples + morsel_seen = False # A key=value pair was previously encountered + + TYPE_ATTRIBUTE = 1 + TYPE_KEYVALUE = 2 + # We first parse the whole cookie string and reject it if it's + # syntactically invalid (this helps avoid some classes of injection + # attacks). while 0 <= i < n: # Start looking for a cookie - match = patt.search(str, i) + match = patt.match(str, i) if not match: # No more cookies break @@ -545,22 +554,41 @@ def __parse_string(self, str, patt=_CookiePattern): key, value = match.group("key"), match.group("val") i = match.end(0) - # Parse the key, value in case it's metainfo if key[0] == "$": - # We ignore attributes which pertain to the cookie - # mechanism as a whole. See RFC 2109. - # (Does anyone care?) - if M: - M[key[1:]] = value + if not morsel_seen: + # We ignore attributes which pertain to the cookie + # mechanism as a whole, such as "$Version". + # See RFC 2965. (Does anyone care?) + continue + parsed_items.append((TYPE_ATTRIBUTE, key[1:], value)) elif key.lower() in Morsel._reserved: - if M: - if value is None: - if key.lower() in Morsel._flags: - M[key] = True + if not morsel_seen: + # Invalid cookie string + return + if value is None: + if key.lower() in Morsel._flags: + parsed_items.append((TYPE_ATTRIBUTE, key, True)) else: - M[key] = _unquote(value) + # Invalid cookie string + return + else: + parsed_items.append((TYPE_ATTRIBUTE, key, _unquote(value))) elif value is not None: - rval, cval = self.value_decode(value) + parsed_items.append((TYPE_KEYVALUE, key, self.value_decode(value))) + morsel_seen = True + else: + # Invalid cookie string + return + + # The cookie string is valid, apply it. + M = None # current morsel + for tp, key, value in parsed_items: + if tp == TYPE_ATTRIBUTE: + assert M is not None + M[key] = value + else: + assert tp == TYPE_KEYVALUE + rval, cval = value self.__set(key, rval, cval) M = self[key] diff --git a/Lib/http/server.py b/Lib/http/server.py index 7b577b49ac10..4704d5141a62 100644 --- a/Lib/http/server.py +++ b/Lib/http/server.py @@ -82,11 +82,12 @@ __version__ = "0.6" -__all__ = ["HTTPServer", "BaseHTTPRequestHandler"] +__all__ = [ + "HTTPServer", "BaseHTTPRequestHandler", + "SimpleHTTPRequestHandler", "CGIHTTPRequestHandler", +] import html -import email.message -import email.parser import http.client import io import mimetypes @@ -102,6 +103,8 @@ import copy import argparse +from http import HTTPStatus + # Default error message template DEFAULT_ERROR_MESSAGE = """\ @@ -272,7 +275,7 @@ def parse_request(self): """ self.command = None # set in case of error on the first line self.request_version = version = self.default_request_version - self.close_connection = 1 + self.close_connection = True requestline = str(self.raw_requestline, 'iso-8859-1') requestline = requestline.rstrip('\r\n') self.requestline = requestline @@ -280,7 +283,9 @@ def parse_request(self): if len(words) == 3: command, path, version = words if version[:5] != 'HTTP/': - self.send_error(400, "Bad request version (%r)" % version) + self.send_error( + HTTPStatus.BAD_REQUEST, + "Bad request version (%r)" % version) return False try: base_version_number = version.split('/', 1)[1] @@ -295,25 +300,31 @@ def parse_request(self): raise ValueError version_number = int(version_number[0]), int(version_number[1]) except (ValueError, IndexError): - self.send_error(400, "Bad request version (%r)" % version) + self.send_error( + HTTPStatus.BAD_REQUEST, + "Bad request version (%r)" % version) return False if version_number >= (1, 1) and self.protocol_version >= "HTTP/1.1": - self.close_connection = 0 + self.close_connection = False if version_number >= (2, 0): - self.send_error(505, - "Invalid HTTP Version (%s)" % base_version_number) + self.send_error( + HTTPStatus.HTTP_VERSION_NOT_SUPPORTED, + "Invalid HTTP Version (%s)" % base_version_number) return False elif len(words) == 2: command, path = words - self.close_connection = 1 + self.close_connection = True if command != 'GET': - self.send_error(400, - "Bad HTTP/0.9 request type (%r)" % command) + self.send_error( + HTTPStatus.BAD_REQUEST, + "Bad HTTP/0.9 request type (%r)" % command) return False elif not words: return False else: - self.send_error(400, "Bad request syntax (%r)" % requestline) + self.send_error( + HTTPStatus.BAD_REQUEST, + "Bad request syntax (%r)" % requestline) return False self.command, self.path, self.request_version = command, path, version @@ -322,15 +333,17 @@ def parse_request(self): self.headers = http.client.parse_headers(self.rfile, _class=self.MessageClass) except http.client.LineTooLong: - self.send_error(400, "Line too long") + self.send_error( + HTTPStatus.BAD_REQUEST, + "Line too long") return False conntype = self.headers.get('Connection', "") if conntype.lower() == 'close': - self.close_connection = 1 + self.close_connection = True elif (conntype.lower() == 'keep-alive' and self.protocol_version >= "HTTP/1.1"): - self.close_connection = 0 + self.close_connection = False # Examine the headers and look for an Expect directive expect = self.headers.get('Expect', "") if (expect.lower() == "100-continue" and @@ -354,8 +367,8 @@ def handle_expect_100(self): False. """ - self.send_response_only(100) - self.flush_headers() + self.send_response_only(HTTPStatus.CONTINUE) + self.end_headers() return True def handle_one_request(self): @@ -372,17 +385,19 @@ def handle_one_request(self): self.requestline = '' self.request_version = '' self.command = '' - self.send_error(414) + self.send_error(HTTPStatus.REQUEST_URI_TOO_LONG) return if not self.raw_requestline: - self.close_connection = 1 + self.close_connection = True return if not self.parse_request(): # An error code has been sent, just exit return mname = 'do_' + self.command if not hasattr(self, mname): - self.send_error(501, "Unsupported method (%r)" % self.command) + self.send_error( + HTTPStatus.NOT_IMPLEMENTED, + "Unsupported method (%r)" % self.command) return method = getattr(self, mname) method() @@ -390,12 +405,12 @@ def handle_one_request(self): except socket.timeout as e: #a read or a write timed out. Discard this connection self.log_error("Request timed out: %r", e) - self.close_connection = 1 + self.close_connection = True return def handle(self): """Handle multiple requests if necessary.""" - self.close_connection = 1 + self.close_connection = True self.handle_one_request() while not self.close_connection: @@ -437,7 +452,11 @@ def send_error(self, code, message=None, explain=None): self.send_header('Connection', 'close') self.send_header('Content-Length', int(len(body))) self.end_headers() - if self.command != 'HEAD' and code >= 200 and code not in (204, 304): + + if (self.command != 'HEAD' and + code >= 200 and + code not in ( + HTTPStatus.NO_CONTENT, HTTPStatus.NOT_MODIFIED)): self.wfile.write(body) def send_response(self, code, message=None): @@ -477,9 +496,9 @@ def send_header(self, keyword, value): if keyword.lower() == 'connection': if value.lower() == 'close': - self.close_connection = 1 + self.close_connection = True elif value.lower() == 'keep-alive': - self.close_connection = 0 + self.close_connection = False def end_headers(self): """Send the blank line ending the MIME headers.""" @@ -581,82 +600,11 @@ def address_string(self): # MessageClass used to parse headers MessageClass = http.client.HTTPMessage - # Table mapping response codes to messages; entries have the - # form {code: (shortmessage, longmessage)}. - # See RFC 2616 and 6585. + # hack to maintain backwards compatibility responses = { - 100: ('Continue', 'Request received, please continue'), - 101: ('Switching Protocols', - 'Switching to new protocol; obey Upgrade header'), - - 200: ('OK', 'Request fulfilled, document follows'), - 201: ('Created', 'Document created, URL follows'), - 202: ('Accepted', - 'Request accepted, processing continues off-line'), - 203: ('Non-Authoritative Information', 'Request fulfilled from cache'), - 204: ('No Content', 'Request fulfilled, nothing follows'), - 205: ('Reset Content', 'Clear input form for further input.'), - 206: ('Partial Content', 'Partial content follows.'), - - 300: ('Multiple Choices', - 'Object has several resources -- see URI list'), - 301: ('Moved Permanently', 'Object moved permanently -- see URI list'), - 302: ('Found', 'Object moved temporarily -- see URI list'), - 303: ('See Other', 'Object moved -- see Method and URL list'), - 304: ('Not Modified', - 'Document has not changed since given time'), - 305: ('Use Proxy', - 'You must use proxy specified in Location to access this ' - 'resource.'), - 307: ('Temporary Redirect', - 'Object moved temporarily -- see URI list'), - - 400: ('Bad Request', - 'Bad request syntax or unsupported method'), - 401: ('Unauthorized', - 'No permission -- see authorization schemes'), - 402: ('Payment Required', - 'No payment -- see charging schemes'), - 403: ('Forbidden', - 'Request forbidden -- authorization will not help'), - 404: ('Not Found', 'Nothing matches the given URI'), - 405: ('Method Not Allowed', - 'Specified method is invalid for this resource.'), - 406: ('Not Acceptable', 'URI not available in preferred format.'), - 407: ('Proxy Authentication Required', 'You must authenticate with ' - 'this proxy before proceeding.'), - 408: ('Request Timeout', 'Request timed out; try again later.'), - 409: ('Conflict', 'Request conflict.'), - 410: ('Gone', - 'URI no longer exists and has been permanently removed.'), - 411: ('Length Required', 'Client must specify Content-Length.'), - 412: ('Precondition Failed', 'Precondition in headers is false.'), - 413: ('Request Entity Too Large', 'Entity is too large.'), - 414: ('Request-URI Too Long', 'URI is too long.'), - 415: ('Unsupported Media Type', 'Entity body in unsupported format.'), - 416: ('Requested Range Not Satisfiable', - 'Cannot satisfy request range.'), - 417: ('Expectation Failed', - 'Expect condition could not be satisfied.'), - 428: ('Precondition Required', - 'The origin server requires the request to be conditional.'), - 429: ('Too Many Requests', 'The user has sent too many requests ' - 'in a given amount of time ("rate limiting").'), - 431: ('Request Header Fields Too Large', 'The server is unwilling to ' - 'process the request because its header fields are too large.'), - - 500: ('Internal Server Error', 'Server got itself in trouble'), - 501: ('Not Implemented', - 'Server does not support this operation'), - 502: ('Bad Gateway', 'Invalid responses from another server/proxy.'), - 503: ('Service Unavailable', - 'The server cannot process the request due to a high load'), - 504: ('Gateway Timeout', - 'The gateway server did not receive a timely response'), - 505: ('HTTP Version Not Supported', 'Cannot fulfill request.'), - 511: ('Network Authentication Required', - 'The client needs to authenticate to gain network access.'), - } + v: (v.phrase, v.description) + for v in HTTPStatus.__members__.values() + } class SimpleHTTPRequestHandler(BaseHTTPRequestHandler): @@ -678,8 +626,10 @@ def do_GET(self): """Serve a GET request.""" f = self.send_head() if f: - self.copyfile(f, self.wfile) - f.close() + try: + self.copyfile(f, self.wfile) + finally: + f.close() def do_HEAD(self): """Serve a HEAD request.""" @@ -701,10 +651,14 @@ def send_head(self): path = self.translate_path(self.path) f = None if os.path.isdir(path): - if not self.path.endswith('/'): + parts = urllib.parse.urlsplit(self.path) + if not parts.path.endswith('/'): # redirect browser - doing basically what apache does - self.send_response(301) - self.send_header("Location", self.path + "/") + self.send_response(HTTPStatus.MOVED_PERMANENTLY) + new_parts = (parts[0], parts[1], parts[2] + '/', + parts[3], parts[4]) + new_url = urllib.parse.urlunsplit(new_parts) + self.send_header("Location", new_url) self.end_headers() return None for index in "index.html", "index.htm": @@ -718,15 +672,19 @@ def send_head(self): try: f = open(path, 'rb') except OSError: - self.send_error(404, "File not found") + self.send_error(HTTPStatus.NOT_FOUND, "File not found") return None - self.send_response(200) - self.send_header("Content-type", ctype) - fs = os.fstat(f.fileno()) - self.send_header("Content-Length", str(fs[6])) - self.send_header("Last-Modified", self.date_time_string(fs.st_mtime)) - self.end_headers() - return f + try: + self.send_response(HTTPStatus.OK) + self.send_header("Content-type", ctype) + fs = os.fstat(f.fileno()) + self.send_header("Content-Length", str(fs[6])) + self.send_header("Last-Modified", self.date_time_string(fs.st_mtime)) + self.end_headers() + return f + except: + f.close() + raise def list_directory(self, path): """Helper to produce a directory listing (absent index.html). @@ -739,11 +697,18 @@ def list_directory(self, path): try: list = os.listdir(path) except OSError: - self.send_error(404, "No permission to list directory") + self.send_error( + HTTPStatus.NOT_FOUND, + "No permission to list directory") return None list.sort(key=lambda a: a.lower()) r = [] - displaypath = html.escape(urllib.parse.unquote(self.path)) + try: + displaypath = urllib.parse.unquote(self.path, + errors='surrogatepass') + except UnicodeDecodeError: + displaypath = urllib.parse.unquote(path) + displaypath = html.escape(displaypath) enc = sys.getfilesystemencoding() title = 'Directory listing for %s' % displaypath r.append('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" ' @@ -765,13 +730,15 @@ def list_directory(self, path): displayname = name + "@" # Note: a link to a directory displays with @ and links with / r.append('<li><a href="%s">%s</a></li>' - % (urllib.parse.quote(linkname), html.escape(displayname))) + % (urllib.parse.quote(linkname, + errors='surrogatepass'), + html.escape(displayname))) r.append('</ul>\n<hr>\n</body>\n</html>\n') - encoded = '\n'.join(r).encode(enc) + encoded = '\n'.join(r).encode(enc, 'surrogateescape') f = io.BytesIO() f.write(encoded) f.seek(0) - self.send_response(200) + self.send_response(HTTPStatus.OK) self.send_header("Content-type", "text/html; charset=%s" % enc) self.send_header("Content-Length", str(len(encoded))) self.end_headers() @@ -790,7 +757,11 @@ def translate_path(self, path): path = path.split('#',1)[0] # Don't forget explicit trailing slash when normalizing. Issue17324 trailing_slash = path.rstrip().endswith('/') - path = posixpath.normpath(urllib.parse.unquote(path)) + try: + path = urllib.parse.unquote(path, errors='surrogatepass') + except UnicodeDecodeError: + path = urllib.parse.unquote(path) + path = posixpath.normpath(path) words = path.split('/') words = filter(None, words) path = os.getcwd() @@ -949,7 +920,9 @@ def do_POST(self): if self.is_cgi(): self.run_cgi() else: - self.send_error(501, "Can only POST to CGI scripts") + self.send_error( + HTTPStatus.NOT_IMPLEMENTED, + "Can only POST to CGI scripts") def send_head(self): """Version of send_head that support CGI scripts""" @@ -973,7 +946,7 @@ def is_cgi(self): (and the next character is a '/' or the end of the string). """ - collapsed_path = _url_collapse_path(self.path) + collapsed_path = _url_collapse_path(urllib.parse.unquote(self.path)) dir_sep = collapsed_path.find('/', 1) head, tail = collapsed_path[:dir_sep], collapsed_path[dir_sep+1:] if head in self.cgi_directories: @@ -996,16 +969,16 @@ def is_python(self, path): def run_cgi(self): """Execute a CGI script.""" dir, rest = self.cgi_info - - i = rest.find('/') + path = dir + '/' + rest + i = path.find('/', len(dir)+1) while i >= 0: - nextdir = rest[:i] - nextrest = rest[i+1:] + nextdir = path[:i] + nextrest = path[i+1:] scriptdir = self.translate_path(nextdir) if os.path.isdir(scriptdir): dir, rest = nextdir, nextrest - i = rest.find('/') + i = path.find('/', len(dir)+1) else: break @@ -1027,17 +1000,21 @@ def run_cgi(self): scriptname = dir + '/' + script scriptfile = self.translate_path(scriptname) if not os.path.exists(scriptfile): - self.send_error(404, "No such CGI script (%r)" % scriptname) + self.send_error( + HTTPStatus.NOT_FOUND, + "No such CGI script (%r)" % scriptname) return if not os.path.isfile(scriptfile): - self.send_error(403, "CGI script is not a plain file (%r)" % - scriptname) + self.send_error( + HTTPStatus.FORBIDDEN, + "CGI script is not a plain file (%r)" % scriptname) return ispy = self.is_python(scriptname) if self.have_fork or not ispy: if not self.is_executable(scriptfile): - self.send_error(403, "CGI script is not executable (%r)" % - scriptname) + self.send_error( + HTTPStatus.FORBIDDEN, + "CGI script is not executable (%r)" % scriptname) return # Reference: http://hoohoo.ncsa.uiuc.edu/cgi/env.html @@ -1105,7 +1082,7 @@ def run_cgi(self): 'HTTP_USER_AGENT', 'HTTP_COOKIE', 'HTTP_REFERER'): env.setdefault(k, "") - self.send_response(200, "Script output follows") + self.send_response(HTTPStatus.OK, "Script output follows") self.flush_headers() decoded_query = query.replace('+', ' ') diff --git a/Lib/idlelib/AutoComplete.py b/Lib/idlelib/AutoComplete.py index f3660307d35d..b20512dfa0f3 100644 --- a/Lib/idlelib/AutoComplete.py +++ b/Lib/idlelib/AutoComplete.py @@ -226,3 +226,8 @@ def get_entity(self, name): namespace = sys.modules.copy() namespace.update(__main__.__dict__) return eval(name, namespace) + + +if __name__ == '__main__': + from unittest import main + main('idlelib.idle_test.test_autocomplete', verbosity=2) diff --git a/Lib/idlelib/AutoExpand.py b/Lib/idlelib/AutoExpand.py index 9e93d57d6520..705905428181 100644 --- a/Lib/idlelib/AutoExpand.py +++ b/Lib/idlelib/AutoExpand.py @@ -1,3 +1,17 @@ +'''Complete the current word before the cursor with words in the editor. + +Each menu selection or shortcut key selection replaces the word with a +different word with the same prefix. The search for matches begins +before the target and moves toward the top of the editor. It then starts +after the cursor and moves down. It then returns to the original word and +the cycle starts again. + +Changing the current text line or leaving the cursor in a different +place before requesting the next selection causes AutoExpand to reset +its state. + +This is an extension file and there is only one instance of AutoExpand. +''' import string import re @@ -20,6 +34,7 @@ def __init__(self, editwin): self.state = None def expand_word_event(self, event): + "Replace the current word with the next expansion." curinsert = self.text.index("insert") curline = self.text.get("insert linestart", "insert lineend") if not self.state: @@ -46,6 +61,7 @@ def expand_word_event(self, event): return "break" def getwords(self): + "Return a list of words that match the prefix before the cursor." word = self.getprevword() if not word: return [] @@ -76,8 +92,13 @@ def getwords(self): return words def getprevword(self): + "Return the word prefix before the cursor." line = self.text.get("insert linestart", "insert") i = len(line) while i > 0 and line[i-1] in self.wordchars: i = i-1 return line[i:] + +if __name__ == '__main__': + import unittest + unittest.main('idlelib.idle_test.test_autoexpand', verbosity=2) diff --git a/Lib/idlelib/Bindings.py b/Lib/idlelib/Bindings.py index 65c0317e60cc..226671ccdb08 100644 --- a/Lib/idlelib/Bindings.py +++ b/Lib/idlelib/Bindings.py @@ -8,9 +8,16 @@ windows. """ -import sys +from importlib.util import find_spec + from idlelib.configHandler import idleConf -from idlelib import macosxSupport + +# Warning: menudefs is altered in macosxSupport.overrideRootMenu() +# after it is determined that an OS X Aqua Tk is in use, +# which cannot be done until after Tk() is first called. +# Do not alter the 'file', 'options', or 'help' cascades here +# without altering overrideRootMenu() as well. +# TODO: Make this more robust menudefs = [ # underscore prefixes character to underscore @@ -70,7 +77,8 @@ ('!_Auto-open Stack Viewer', '<<toggle-jit-stack-viewer>>'), ]), ('options', [ - ('_Configure IDLE...', '<<open-config-dialog>>'), + ('Configure _IDLE', '<<open-config-dialog>>'), + ('Configure _Extensions', '<<open-config-extensions-dialog>>'), None, ]), ('help', [ @@ -81,27 +89,7 @@ ]), ] -if macosxSupport.runningAsOSXApp(): - # Running as a proper MacOS application bundle. This block restructures - # the menus a little to make them conform better to the HIG. - - quitItem = menudefs[0][1][-1] - closeItem = menudefs[0][1][-2] - - # Remove the last 3 items of the file menu: a separator, close window and - # quit. Close window will be reinserted just above the save item, where - # it should be according to the HIG. Quit is in the application menu. - del menudefs[0][1][-3:] - menudefs[0][1].insert(6, closeItem) - - # Remove the 'About' entry from the help menu, it is in the application - # menu - del menudefs[-1][1][0:2] - - # Remove the 'Configure' entry from the options menu, it is in the - # application menu as 'Preferences' - del menudefs[-2][1][0:2] +if find_spec('turtledemo'): + menudefs[-1][1].append(('Turtle Demo', '<<open-turtle-demo>>')) default_keydefs = idleConf.GetCurrentKeySet() - -del sys diff --git a/Lib/idlelib/CallTipWindow.py b/Lib/idlelib/CallTipWindow.py index a2431f8eff30..170d14653a26 100644 --- a/Lib/idlelib/CallTipWindow.py +++ b/Lib/idlelib/CallTipWindow.py @@ -2,9 +2,8 @@ After ToolTip.py, which uses ideas gleaned from PySol Used by the CallTips IDLE extension. - """ -from tkinter import * +from tkinter import Toplevel, Label, LEFT, SOLID, TclError HIDE_VIRTUAL_EVENT_NAME = "<<calltipwindow-hide>>" HIDE_SEQUENCES = ("<Key-Escape>", "<FocusOut>") @@ -48,13 +47,7 @@ def position_window(self): def showtip(self, text, parenleft, parenright): """Show the calltip, bind events which will close it and reposition it. """ - # truncate overly long calltip - if len(text) >= 79: - textlines = text.splitlines() - for i, line in enumerate(textlines): - if len(line) > 79: - textlines[i] = line[:75] + ' ...' - text = '\n'.join(textlines) + # Only called in CallTips, where lines are truncated self.text = text if self.tipwindow or not self.text: return @@ -139,37 +132,29 @@ def is_active(self): return bool(self.tipwindow) - -############################### -# -# Test Code -# -class container: # Conceptually an editor_window - def __init__(self): - root = Tk() - text = self.text = Text(root) - text.pack(side=LEFT, fill=BOTH, expand=1) - text.insert("insert", "string.split") - root.update() - self.calltip = CallTip(text) - - text.event_add("<<calltip-show>>", "(") - text.event_add("<<calltip-hide>>", ")") - text.bind("<<calltip-show>>", self.calltip_show) - text.bind("<<calltip-hide>>", self.calltip_hide) - - text.focus_set() - root.mainloop() - - def calltip_show(self, event): - self.calltip.showtip("Hello world") - - def calltip_hide(self, event): - self.calltip.hidetip() - -def main(): - # Test code - c=container() +def _calltip_window(parent): # htest # + from tkinter import Toplevel, Text, LEFT, BOTH + + top = Toplevel(parent) + top.title("Test calltips") + top.geometry("200x100+%d+%d" % (parent.winfo_rootx() + 200, + parent.winfo_rooty() + 150)) + text = Text(top) + text.pack(side=LEFT, fill=BOTH, expand=1) + text.insert("insert", "string.split") + top.update() + calltip = CallTip(text) + + def calltip_show(event): + calltip.showtip("(s=Hello world)", "insert", "end") + def calltip_hide(event): + calltip.hidetip() + text.event_add("<<calltip-show>>", "(") + text.event_add("<<calltip-hide>>", ")") + text.bind("<<calltip-show>>", calltip_show) + text.bind("<<calltip-hide>>", calltip_hide) + text.focus_set() if __name__=='__main__': - main() + from idlelib.idle_test.htest import run + run(_calltip_window) diff --git a/Lib/idlelib/CallTips.py b/Lib/idlelib/CallTips.py index 41de756fa560..81bd5f1890e0 100644 --- a/Lib/idlelib/CallTips.py +++ b/Lib/idlelib/CallTips.py @@ -5,16 +5,16 @@ which disappear when you type a closing parenthesis. """ +import __main__ +import inspect import re import sys +import textwrap import types -import inspect from idlelib import CallTipWindow from idlelib.HyperParser import HyperParser -import __main__ - class CallTips: menudefs = [ @@ -116,154 +116,60 @@ def get_entity(expression): # exception, especially if user classes are involved. return None -# The following are used in both get_argspec and tests +# The following are used in get_argspec and some in tests +_MAX_COLS = 85 +_MAX_LINES = 5 # enough for bytes +_INDENT = ' '*4 # for wrapped signatures _first_param = re.compile('(?<=\()\w*\,?\s*') -_default_callable_argspec = "No docstring, see docs." +_default_callable_argspec = "See source or doc" + def get_argspec(ob): - '''Return a string describing the arguments and return of a callable object. + '''Return a string describing the signature of a callable object, or ''. For Python-coded functions and methods, the first line is introspected. Delete 'self' parameter for classes (.__init__) and bound methods. - The last line is the first line of the doc string. For builtins, this typically - includes the arguments in addition to the return value. - + The next lines are the first lines of the doc string up to the first + empty line or _MAX_LINES. For builtins, this typically includes + the arguments in addition to the return value. ''' argspec = "" - if hasattr(ob, '__call__'): - if isinstance(ob, type): - fob = getattr(ob, '__init__', None) - elif isinstance(ob.__call__, types.MethodType): - fob = ob.__call__ - else: - fob = ob - if isinstance(fob, (types.FunctionType, types.MethodType)): - argspec = inspect.formatargspec(*inspect.getfullargspec(fob)) - if (isinstance(ob, (type, types.MethodType)) or - isinstance(ob.__call__, types.MethodType)): - argspec = _first_param.sub("", argspec) - - if isinstance(ob.__call__, types.MethodType): - doc = ob.__call__.__doc__ - else: - doc = getattr(ob, "__doc__", "") - if doc: - doc = doc.lstrip() - pos = doc.find("\n") - if pos < 0 or pos > 70: - pos = 70 - if argspec: - argspec += "\n" - argspec += doc[:pos] - if not argspec: - argspec = _default_callable_argspec + try: + ob_call = ob.__call__ + except BaseException: + return argspec + if isinstance(ob, type): + fob = ob.__init__ + elif isinstance(ob_call, types.MethodType): + fob = ob_call + else: + fob = ob + if isinstance(fob, (types.FunctionType, types.MethodType)): + argspec = inspect.formatargspec(*inspect.getfullargspec(fob)) + if (isinstance(ob, (type, types.MethodType)) or + isinstance(ob_call, types.MethodType)): + argspec = _first_param.sub("", argspec) + + lines = (textwrap.wrap(argspec, _MAX_COLS, subsequent_indent=_INDENT) + if len(argspec) > _MAX_COLS else [argspec] if argspec else []) + + if isinstance(ob_call, types.MethodType): + doc = ob_call.__doc__ + else: + doc = getattr(ob, "__doc__", "") + if doc: + for line in doc.split('\n', _MAX_LINES)[:_MAX_LINES]: + line = line.strip() + if not line: + break + if len(line) > _MAX_COLS: + line = line[: _MAX_COLS - 3] + '...' + lines.append(line) + argspec = '\n'.join(lines) + if not argspec: + argspec = _default_callable_argspec return argspec -################################################# -# -# Test code tests CallTips.fetch_tip, get_entity, and get_argspec - -def main(): - # Putting expected in docstrings results in doubled tips for test - def t1(): "()" - def t2(a, b=None): "(a, b=None)" - def t3(a, *args): "(a, *args)" - def t4(*args): "(*args)" - def t5(a, b=None, *args, **kw): "(a, b=None, *args, **kw)" - - class TC(object): - "(ai=None, *b)" - def __init__(self, ai=None, *b): "(self, ai=None, *b)" - def t1(self): "(self)" - def t2(self, ai, b=None): "(self, ai, b=None)" - def t3(self, ai, *args): "(self, ai, *args)" - def t4(self, *args): "(self, *args)" - def t5(self, ai, b=None, *args, **kw): "(self, ai, b=None, *args, **kw)" - def t6(no, self): "(no, self)" - @classmethod - def cm(cls, a): "(cls, a)" - @staticmethod - def sm(b): "(b)" - def __call__(self, ci): "(self, ci)" - - tc = TC() - - # Python classes that inherit builtin methods - class Int(int): "Int(x[, base]) -> integer" - class List(list): "List() -> new empty list" - # Simulate builtin with no docstring for default argspec test - class SB: __call__ = None - - __main__.__dict__.update(locals()) # required for get_entity eval() - - num_tests = num_fail = 0 - tip = CallTips().fetch_tip - - def test(expression, expected): - nonlocal num_tests, num_fail - num_tests += 1 - argspec = tip(expression) - if argspec != expected: - num_fail += 1 - fmt = "%s - expected\n%r\n - but got\n%r" - print(fmt % (expression, expected, argspec)) - - def test_builtins(): - # if first line of a possibly multiline compiled docstring changes, - # must change corresponding test string - test('int', "int(x=0) -> integer") - test('Int', Int.__doc__) - test('types.MethodType', "method(function, instance)") - test('list', "list() -> new empty list") - test('List', List.__doc__) - test('list.__new__', - 'T.__new__(S, ...) -> a new object with type S, a subtype of T') - test('list.__init__', - 'x.__init__(...) initializes x; see help(type(x)) for signature') - append_doc = "L.append(object) -> None -- append object to end" - test('list.append', append_doc) - test('[].append', append_doc) - test('List.append', append_doc) - test('SB()', _default_callable_argspec) - - def test_funcs(): - for func in (t1, t2, t3, t4, t5, TC,): - fdoc = func.__doc__ - test(func.__name__, fdoc + "\n" + fdoc) - for func in (TC.t1, TC.t2, TC.t3, TC.t4, TC.t5, TC.t6, TC.sm, - TC.__call__): - fdoc = func.__doc__ - test('TC.'+func.__name__, fdoc + "\n" + fdoc) - fdoc = TC.cm.__func__.__doc__ - test('TC.cm.__func__', fdoc + "\n" + fdoc) - - def test_methods(): - # test that first parameter is correctly removed from argspec - # using _first_param re to calculate expected masks re errors - for meth, mdoc in ((tc.t1, "()"), (tc.t4, "(*args)"), (tc.t6, "(self)"), - (TC.cm, "(a)"),): - test('tc.'+meth.__name__, mdoc + "\n" + meth.__doc__) - test('tc', "(ci)" + "\n" + tc.__call__.__doc__) - # directly test that re works to delete unicode parameter name - uni = "(A\u0391\u0410\u05d0\u0627\u0905\u1e00\u3042, a)" # various As - assert _first_param.sub('', uni) == '(a)' - - def test_non_callables(): - # expression evaluates, but not to a callable - for expr in ('0', '0.0' 'num_tests', b'num_tests', '[]', '{}'): - test(expr, '') - # expression does not evaluate, but raises an exception - for expr in ('1a', 'xyx', 'num_tests.xyz', '[int][1]', '{0:int}[1]'): - test(expr, '') - - test_builtins() - test_funcs() - test_non_callables() - test_methods() - - print("%d of %d tests failed" % (num_fail, num_tests)) - if __name__ == '__main__': - #main() from unittest import main - main('idlelib.idle_test.test_calltips', verbosity=2, exit=False) + main('idlelib.idle_test.test_calltips', verbosity=2) diff --git a/Lib/idlelib/ClassBrowser.py b/Lib/idlelib/ClassBrowser.py index 71176cd70154..5be65efb9bc0 100644 --- a/Lib/idlelib/ClassBrowser.py +++ b/Lib/idlelib/ClassBrowser.py @@ -19,13 +19,23 @@ from idlelib.TreeWidget import TreeNode, TreeItem, ScrolledCanvas from idlelib.configHandler import idleConf +file_open = None # Method...Item and Class...Item use this. +# Normally PyShell.flist.open, but there is no PyShell.flist for htest. + class ClassBrowser: - def __init__(self, flist, name, path): + def __init__(self, flist, name, path, _htest=False): # XXX This API should change, if the file doesn't end in ".py" # XXX the code here is bogus! + """ + _htest - bool, change box when location running htest. + """ + global file_open + if not _htest: + file_open = PyShell.flist.open self.name = name self.file = os.path.join(path[0], self.name + ".py") + self._htest = _htest self.init(flist) def close(self, event=None): @@ -40,6 +50,9 @@ def init(self, flist): self.top = top = ListedToplevel(flist.root) top.protocol("WM_DELETE_WINDOW", self.close) top.bind("<Escape>", self.close) + if self._htest: # place dialog below parent if running htest + top.geometry("+%d+%d" % + (flist.root.winfo_rootx(), flist.root.winfo_rooty() + 200)) self.settitle() top.focus_set() # create scrolled canvas @@ -94,7 +107,7 @@ def listclasses(self): return [] try: dict = pyclbr.readmodule_ex(name, [dir] + sys.path) - except ImportError as msg: + except ImportError: return [] items = [] self.classes = {} @@ -163,7 +176,7 @@ def GetSubList(self): def OnDoubleClick(self): if not os.path.exists(self.file): return - edit = PyShell.flist.open(self.file) + edit = file_open(self.file) if hasattr(self.cl, 'lineno'): lineno = self.cl.lineno edit.gotoline(lineno) @@ -199,10 +212,10 @@ def IsExpandable(self): def OnDoubleClick(self): if not os.path.exists(self.file): return - edit = PyShell.flist.open(self.file) + edit = file_open(self.file) edit.gotoline(self.cl.methods[self.name]) -def main(): +def _class_browser(parent): #Wrapper for htest try: file = __file__ except NameError: @@ -213,9 +226,11 @@ def main(): file = sys.argv[0] dir, file = os.path.split(file) name = os.path.splitext(file)[0] - ClassBrowser(PyShell.flist, name, [dir]) - if sys.stdin is sys.__stdin__: - mainloop() + flist = PyShell.PyShellFileList(parent) + global file_open + file_open = flist.open + ClassBrowser(flist, name, [dir], _htest=True) if __name__ == "__main__": - main() + from idlelib.idle_test.htest import run + run(_class_browser) diff --git a/Lib/idlelib/CodeContext.py b/Lib/idlelib/CodeContext.py index 84491d5a9d1e..44783b69d0b6 100644 --- a/Lib/idlelib/CodeContext.py +++ b/Lib/idlelib/CodeContext.py @@ -15,8 +15,8 @@ from sys import maxsize as INFINITY from idlelib.configHandler import idleConf -BLOCKOPENERS = set(["class", "def", "elif", "else", "except", "finally", "for", - "if", "try", "while", "with"]) +BLOCKOPENERS = {"class", "def", "elif", "else", "except", "finally", "for", + "if", "try", "while", "with"} UPDATEINTERVAL = 100 # millisec FONTUPDATEINTERVAL = 1000 # millisec diff --git a/Lib/idlelib/ColorDelegator.py b/Lib/idlelib/ColorDelegator.py index 61e2be47c7e7..13a90103134d 100644 --- a/Lib/idlelib/ColorDelegator.py +++ b/Lib/idlelib/ColorDelegator.py @@ -2,7 +2,6 @@ import re import keyword import builtins -from tkinter import * from idlelib.Delegator import Delegator from idlelib.configHandler import idleConf @@ -32,7 +31,6 @@ def make_pat(): prog = re.compile(make_pat(), re.S) idprog = re.compile(r"\s+(\w+)", re.S) -asprog = re.compile(r".*?\b(as)\b") class ColorDelegator(Delegator): @@ -40,7 +38,6 @@ def __init__(self): Delegator.__init__(self) self.prog = prog self.idprog = idprog - self.asprog = asprog self.LoadTagDefs() def setdelegate(self, delegate): @@ -72,7 +69,6 @@ def LoadTagDefs(self): "DEFINITION": idleConf.GetHighlight(theme, "definition"), "SYNC": {'background':None,'foreground':None}, "TODO": {'background':None,'foreground':None}, - "BREAK": idleConf.GetHighlight(theme, "break"), "ERROR": idleConf.GetHighlight(theme, "error"), # The following is used by ReplaceDialog: "hit": idleConf.GetHighlight(theme, "hit"), @@ -214,22 +210,6 @@ def recolorize_main(self): self.tag_add("DEFINITION", head + "+%dc" % a, head + "+%dc" % b) - elif value == "import": - # color all the "as" words on same line, except - # if in a comment; cheap approximation to the - # truth - if '#' in chars: - endpos = chars.index('#') - else: - endpos = len(chars) - while True: - m1 = self.asprog.match(chars, b, endpos) - if not m1: - break - a, b = m1.span(1) - self.tag_add("KEYWORD", - head + "+%dc" % a, - head + "+%dc" % b) m = self.prog.search(chars, m.end()) if "SYNC" in self.tag_names(next + "-1c"): head = next @@ -253,17 +233,24 @@ def removecolors(self): for tag in self.tagdefs: self.tag_remove(tag, "1.0", "end") -def main(): +def _color_delegator(parent): # htest # + from tkinter import Toplevel, Text from idlelib.Percolator import Percolator - root = Tk() - root.wm_protocol("WM_DELETE_WINDOW", root.quit) - text = Text(background="white") + + top = Toplevel(parent) + top.title("Test ColorDelegator") + top.geometry("200x100+%d+%d" % (parent.winfo_rootx() + 200, + parent.winfo_rooty() + 150)) + source = "if somename: x = 'abc' # comment\nprint\n" + text = Text(top, background="white") text.pack(expand=1, fill="both") + text.insert("insert", source) text.focus_set() + p = Percolator(text) d = ColorDelegator() p.insertfilter(d) - root.mainloop() if __name__ == "__main__": - main() + from idlelib.idle_test.htest import run + run(_color_delegator) diff --git a/Lib/idlelib/Debugger.py b/Lib/idlelib/Debugger.py index ed66084e91c6..6875197874eb 100644 --- a/Lib/idlelib/Debugger.py +++ b/Lib/idlelib/Debugger.py @@ -1,6 +1,5 @@ import os import bdb -import types from tkinter import * from idlelib.WindowList import ListedToplevel from idlelib.ScrolledList import ScrolledList @@ -254,8 +253,7 @@ def show_source(self): self.sync_source_line() def show_frame(self, stackitem): - frame, lineno = stackitem - self.frame = frame + self.frame = stackitem[0] # lineno is stackitem[1] self.show_variables() localsviewer = None @@ -323,7 +321,7 @@ def load_breakpoints(self): class StackViewer(ScrolledList): def __init__(self, master, flist, gui): - if macosxSupport.runningAsOSXApp(): + if macosxSupport.isAquaTk(): # At least on with the stock AquaTk version on OSX 10.4 you'll # get an shaking GUI that eventually kills IDLE if the width # argument is specified. diff --git a/Lib/idlelib/EditorWindow.py b/Lib/idlelib/EditorWindow.py index eaf68cb75411..1520ad023114 100644 --- a/Lib/idlelib/EditorWindow.py +++ b/Lib/idlelib/EditorWindow.py @@ -1,6 +1,8 @@ import importlib import importlib.abc +import importlib.util import os +import platform import re import string import sys @@ -24,6 +26,8 @@ # The default tab setting for a Text widget, in average-width characters. TK_TABWIDTH_DEFAULT = 8 +_py_version = ' (%s)' % platform.python_version() + def _sphinx_version(): "Format sys.version_info to produce the Sphinx version string used to install the chm docs" major, minor, micro, level, serial = sys.version_info @@ -77,6 +81,8 @@ def destroy(self, ev=None): self.parent = None helpDialog = HelpDialog() # singleton instance +def _help_dialog(parent): # wrapper for htest + helpDialog.show_dialog(parent) class EditorWindow(object): @@ -107,8 +113,8 @@ def __init__(self, flist=None, filename=None, key=None, root=None): 'Python%s.chm' % _sphinx_version()) if os.path.isfile(chmfile): dochome = chmfile - elif macosxSupport.runningAsOSXApp(): - # documentation is stored inside the python framework + elif sys.platform == 'darwin': + # documentation may be stored inside a python framework dochome = os.path.join(sys.base_prefix, 'Resources/English.lproj/Documentation/index.html') dochome = os.path.normpath(dochome) @@ -118,7 +124,7 @@ def __init__(self, flist=None, filename=None, key=None, root=None): # Safari requires real file:-URLs EditorWindow.help_url = 'file://' + EditorWindow.help_url else: - EditorWindow.help_url = "http://docs.python.org/%d.%d" % sys.version_info[:2] + EditorWindow.help_url = "https://docs.python.org/%d.%d/" % sys.version_info[:2] currentTheme=idleConf.CurrentTheme() self.flist = flist root = root or flist.root @@ -164,7 +170,7 @@ def __init__(self, flist=None, filename=None, key=None, root=None): self.top.protocol("WM_DELETE_WINDOW", self.close) self.top.bind("<<close-window>>", self.close_event) - if macosxSupport.runningAsOSXApp(): + if macosxSupport.isAquaTk(): # Command-W on editorwindows doesn't work without this. text.bind('<<close-window>>', self.close_event) # Some OS X systems have only one mouse button, @@ -183,6 +189,8 @@ def __init__(self, flist=None, filename=None, key=None, root=None): text.bind("<<python-docs>>", self.python_docs) text.bind("<<about-idle>>", self.about_dialog) text.bind("<<open-config-dialog>>", self.config_dialog) + text.bind("<<open-config-extensions-dialog>>", + self.config_extensions_dialog) text.bind("<<open-module>>", self.open_module) text.bind("<<do-nothing>>", lambda event: "break") text.bind("<<select-all>>", self.select_all) @@ -218,6 +226,7 @@ def __init__(self, flist=None, filename=None, key=None, root=None): text.bind("<<close-all-windows>>", self.flist.close_all_callback) text.bind("<<open-class-browser>>", self.open_class_browser) text.bind("<<open-path-browser>>", self.open_path_browser) + text.bind("<<open-turtle-demo>>", self.open_turtle_demo) self.set_status_bar() vbar['command'] = text.yview @@ -407,7 +416,7 @@ def home_callback(self, event): def set_status_bar(self): self.status_bar = self.MultiStatusBar(self.top) - if macosxSupport.runningAsOSXApp(): + if sys.platform == "darwin": # Insert some padding to avoid obscuring some of the statusbar # by the resize widget. self.status_bar.set_label('_padding1', ' ', side=RIGHT) @@ -430,13 +439,10 @@ def set_line_and_column(self, event=None): ("format", "F_ormat"), ("run", "_Run"), ("options", "_Options"), - ("windows", "_Windows"), + ("windows", "_Window"), ("help", "_Help"), ] - if macosxSupport.runningAsOSXApp(): - menu_specs[-2] = ("windows", "_Window") - def createmenubar(self): mbar = self.menubar @@ -445,7 +451,7 @@ def createmenubar(self): underline, label = prepstr(label) menudict[name] = menu = Menu(mbar, name=name) mbar.add_cascade(label=label, menu=menu, underline=underline) - if macosxSupport.isCarbonAquaTk(self.root): + if macosxSupport.isCarbonTk(): # Insert the application menu menudict['application'] = menu = Menu(mbar, name='apple') mbar.add_cascade(label='IDLE', menu=menu) @@ -536,6 +542,8 @@ def about_dialog(self, event=None): def config_dialog(self, event=None): configDialog.ConfigDialog(self.top,'Settings') + def config_extensions_dialog(self, event=None): + configDialog.ConfigExtensionsDialog(self.top) def help_dialog(self, event=None): if self.root: @@ -659,20 +667,20 @@ def open_module(self, event=None): return # XXX Ought to insert current file's directory in front of path try: - loader = importlib.find_loader(name) + spec = importlib.util.find_spec(name) except (ValueError, ImportError) as msg: tkMessageBox.showerror("Import error", str(msg), parent=self.text) return - if loader is None: + if spec is None: tkMessageBox.showerror("Import error", "module not found", parent=self.text) return - if not isinstance(loader, importlib.abc.SourceLoader): + if not isinstance(spec.loader, importlib.abc.SourceLoader): tkMessageBox.showerror("Import error", "not a source-based module", parent=self.text) return try: - file_path = loader.get_filename(name) + file_path = spec.loader.get_filename(name) except AttributeError: tkMessageBox.showerror("Import error", "loader does not support get_filename", @@ -682,16 +690,15 @@ def open_module(self, event=None): self.flist.open(file_path) else: self.io.loadfile(file_path) + return file_path def open_class_browser(self, event=None): filename = self.io.filename - if not filename: - tkMessageBox.showerror( - "No filename", - "This buffer has no associated filename", - master=self.text) - self.text.focus_set() - return None + if not (self.__class__.__name__ == 'PyShellEditorWindow' + and filename): + filename = self.open_module() + if filename is None: + return head, tail = os.path.split(filename) base, ext = os.path.splitext(tail) from idlelib import ClassBrowser @@ -701,6 +708,14 @@ def open_path_browser(self, event=None): from idlelib import PathBrowser PathBrowser.PathBrowser(self.flist) + def open_turtle_demo(self, event = None): + import subprocess + + cmd = [sys.executable, + '-c', + 'from turtledemo.__main__ import main; main()'] + p = subprocess.Popen(cmd, shell=False) + def gotoline(self, lineno): if lineno is not None and lineno > 0: self.text.mark_set("insert", "%d.0" % lineno) @@ -751,7 +766,7 @@ def _rmcolorizer(self): self.color = None def ResetColorizer(self): - "Update the colour theme" + "Update the color theme" # Called from self.filename_change_hook and from configDialog.py self._rmcolorizer() self._addcolorizer() @@ -931,7 +946,7 @@ def saved_change_hook(self): short = self.short_title() long = self.long_title() if short and long: - title = short + " - " + long + title = short + " - " + long + _py_version elif short: title = short elif long: @@ -958,6 +973,8 @@ def short_title(self): filename = self.io.filename if filename: filename = os.path.basename(filename) + else: + filename = "Untitled" # return unicode string to display non-ASCII chars correctly return self._filename_to_unicode(filename) @@ -1059,7 +1076,7 @@ def load_extension(self, name): try: try: mod = importlib.import_module('.' + name, package=__package__) - except ImportError: + except (ImportError, TypeError): mod = importlib.import_module(name) except ImportError: print("\nFailed to import extension: ", name) @@ -1668,7 +1685,7 @@ def get_accelerator(keydefs, eventname): keylist = keydefs.get(eventname) # issue10940: temporary workaround to prevent hang with OS X Cocoa Tk 8.5 # if not keylist: - if (not keylist) or (macosxSupport.runningAsOSXApp() and eventname in { + if (not keylist) or (macosxSupport.isCocoaTk() and eventname in { "<<open-module>>", "<<goto-line>>", "<<change-indentwidth>>"}): @@ -1695,19 +1712,20 @@ def fixwordbreaks(root): tk.call('set', 'tcl_nonwordchars', '[^a-zA-Z0-9_]') -def test(): - root = Tk() +def _editor_window(parent): # htest # + # error if close master window first - timer event, after script + root = parent fixwordbreaks(root) - root.withdraw() if sys.argv[1:]: filename = sys.argv[1] else: filename = None + macosxSupport.setupApp(root, None) edit = EditorWindow(root=root, filename=filename) - edit.set_close_hook(root.quit) edit.text.bind("<<close-all-windows>>", edit.close_event) - root.mainloop() - root.destroy() + # Does not stop error, neither does following + # edit.text.bind("<<close-window>>", edit.close_event) if __name__ == '__main__': - test() + from idlelib.idle_test.htest import run + run(_help_dialog, _editor_window) diff --git a/Lib/idlelib/FormatParagraph.py b/Lib/idlelib/FormatParagraph.py index ae4e6e7b9115..7a9d185042e6 100644 --- a/Lib/idlelib/FormatParagraph.py +++ b/Lib/idlelib/FormatParagraph.py @@ -32,7 +32,7 @@ def __init__(self, editwin): def close(self): self.editwin = None - def format_paragraph_event(self, event): + def format_paragraph_event(self, event, limit=None): """Formats paragraph to a max width specified in idleConf. If text is selected, format_paragraph_event will start breaking lines @@ -41,9 +41,14 @@ def format_paragraph_event(self, event): If no text is selected, format_paragraph_event uses the current cursor location to determine the paragraph (lines of text surrounded by blank lines) and formats it. + + The length limit parameter is for testing with a known value. """ - maxformatwidth = idleConf.GetOption( - 'main', 'FormatParagraph', 'paragraph', type='int') + if limit is None: + # The default length limit is that defined by pep8 + limit = idleConf.GetOption( + 'extensions', 'FormatParagraph', 'max-width', + type='int', default=72) text = self.editwin.text first, last = self.editwin.get_selection_indices() if first and last: @@ -53,9 +58,9 @@ def format_paragraph_event(self, event): first, last, comment_header, data = \ find_paragraph(text, text.index("insert")) if comment_header: - newdata = reformat_comment(data, maxformatwidth, comment_header) + newdata = reformat_comment(data, limit, comment_header) else: - newdata = reformat_paragraph(data, maxformatwidth) + newdata = reformat_paragraph(data, limit) text.tag_remove("sel", "1.0", "end") if newdata != data: @@ -185,7 +190,6 @@ def get_comment_header(line): return m.group(1) if __name__ == "__main__": - from test import support; support.use_resources = ['gui'] import unittest unittest.main('idlelib.idle_test.test_formatparagraph', verbosity=2, exit=False) diff --git a/Lib/idlelib/GrepDialog.py b/Lib/idlelib/GrepDialog.py index c0074e24f68e..aa866d0b7529 100644 --- a/Lib/idlelib/GrepDialog.py +++ b/Lib/idlelib/GrepDialog.py @@ -1,9 +1,14 @@ import os import fnmatch +import re # for htest import sys -from tkinter import * +from tkinter import StringVar, BooleanVar, Checkbutton # for GrepDialog +from tkinter import Tk, Text, Button, SEL, END # for htest from idlelib import SearchEngine +import itertools from idlelib.SearchDialogBase import SearchDialogBase +# Importing OutputWindow fails due to import loop +# EditorWindow -> GrepDialop -> OutputWindow -> EditorWindow def grep(text, io=None, flist=None): root = text._root() @@ -40,10 +45,10 @@ def open(self, text, searchphrase, io=None): def create_entries(self): SearchDialogBase.create_entries(self) - self.globent = self.make_entry("In files:", self.globvar) + self.globent = self.make_entry("In files:", self.globvar)[0] def create_other_buttons(self): - f = self.make_frame() + f = self.make_frame()[0] btn = Checkbutton(f, anchor="w", variable=self.recvar, @@ -63,7 +68,7 @@ def default_command(self, event=None): if not path: self.top.bell() return - from idlelib.OutputWindow import OutputWindow + from idlelib.OutputWindow import OutputWindow # leave here! save = sys.stdout try: sys.stdout = OutputWindow(self.flist) @@ -79,26 +84,31 @@ def grep_it(self, prog, path): pat = self.engine.getpat() print("Searching %r in %s ..." % (pat, path)) hits = 0 - for fn in list: - try: - with open(fn, errors='replace') as f: - for lineno, line in enumerate(f, 1): - if line[-1:] == '\n': - line = line[:-1] - if prog.search(line): - sys.stdout.write("%s: %s: %s\n" % - (fn, lineno, line)) - hits += 1 - except OSError as msg: - print(msg) - print(("Hits found: %s\n" - "(Hint: right-click to open locations.)" - % hits) if hits else "No hits.") + try: + for fn in list: + try: + with open(fn, errors='replace') as f: + for lineno, line in enumerate(f, 1): + if line[-1:] == '\n': + line = line[:-1] + if prog.search(line): + sys.stdout.write("%s: %s: %s\n" % + (fn, lineno, line)) + hits += 1 + except OSError as msg: + print(msg) + print(("Hits found: %s\n" + "(Hint: right-click to open locations.)" + % hits) if hits else "No hits.") + except AttributeError: + # Tk window has been closed, OutputWindow.text = None, + # so in OW.write, OW.text.insert fails. + pass def findfiles(self, dir, base, rec): try: names = os.listdir(dir or os.curdir) - except OSerror as msg: + except OSError as msg: print(msg) return [] list = [] @@ -120,8 +130,30 @@ def close(self, event=None): self.top.grab_release() self.top.withdraw() + +def _grep_dialog(parent): # htest # + from idlelib.PyShell import PyShellFileList + root = Tk() + root.title("Test GrepDialog") + width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) + root.geometry("+%d+%d"%(x, y + 150)) + + flist = PyShellFileList(root) + text = Text(root, height=5) + text.pack() + + def show_grep_dialog(): + text.tag_add(SEL, "1.0", END) + grep(text, flist=flist) + text.tag_remove(SEL, "1.0", END) + + button = Button(root, text="Show GrepDialog", command=show_grep_dialog) + button.pack() + root.mainloop() + if __name__ == "__main__": - # A human test is a bit tricky since EditorWindow() imports this module. - # Hence Idle must be restarted after editing this file for a live test. import unittest unittest.main('idlelib.idle_test.test_grep', verbosity=2, exit=False) + + from idlelib.idle_test.htest import run + run(_grep_dialog) diff --git a/Lib/idlelib/HyperParser.py b/Lib/idlelib/HyperParser.py index 4af4b085c7c0..77cb057ce21f 100644 --- a/Lib/idlelib/HyperParser.py +++ b/Lib/idlelib/HyperParser.py @@ -1,23 +1,31 @@ -""" -HyperParser -=========== -This module defines the HyperParser class, which provides advanced parsing -abilities for the ParenMatch and other extensions. -The HyperParser uses PyParser. PyParser is intended mostly to give information -on the proper indentation of code. HyperParser gives some information on the -structure of code, used by extensions to help the user. +"""Provide advanced parsing abilities for ParenMatch and other extensions. + +HyperParser uses PyParser. PyParser mostly gives information on the +proper indentation of code. HyperParser gives additional information on +the structure of code. """ import string -import keyword +from keyword import iskeyword from idlelib import PyParse -class HyperParser: +# all ASCII chars that may be in an identifier +_ASCII_ID_CHARS = frozenset(string.ascii_letters + string.digits + "_") +# all ASCII chars that may be the first char of an identifier +_ASCII_ID_FIRST_CHARS = frozenset(string.ascii_letters + "_") + +# lookup table for whether 7-bit ASCII chars are valid in a Python identifier +_IS_ASCII_ID_CHAR = [(chr(x) in _ASCII_ID_CHARS) for x in range(128)] +# lookup table for whether 7-bit ASCII chars are valid as the first +# char in a Python identifier +_IS_ASCII_ID_FIRST_CHAR = \ + [(chr(x) in _ASCII_ID_FIRST_CHARS) for x in range(128)] + + +class HyperParser: def __init__(self, editwin, index): - """Initialize the HyperParser to analyze the surroundings of the given - index. - """ + "To initialize, analyze the surroundings of the given index." self.editwin = editwin self.text = text = editwin.text @@ -33,9 +41,10 @@ def index2line(index): startat = max(lno - context, 1) startatindex = repr(startat) + ".0" stopatindex = "%d.end" % lno - # We add the newline because PyParse requires a newline at end. - # We add a space so that index won't be at end of line, so that - # its status will be the same as the char before it, if should. + # We add the newline because PyParse requires a newline + # at end. We add a space so that index won't be at end + # of line, so that its status will be the same as the + # char before it, if should. parser.set_str(text.get(startatindex, stopatindex)+' \n') bod = parser.find_good_parse_start( editwin._build_char_in_string_func(startatindex)) @@ -49,122 +58,175 @@ def index2line(index): else: startatindex = "1.0" stopatindex = "%d.end" % lno - # We add the newline because PyParse requires a newline at end. - # We add a space so that index won't be at end of line, so that - # its status will be the same as the char before it, if should. + # We add the newline because PyParse requires it. We add a + # space so that index won't be at end of line, so that its + # status will be the same as the char before it, if should. parser.set_str(text.get(startatindex, stopatindex)+' \n') parser.set_lo(0) - # We want what the parser has, except for the last newline and space. + # We want what the parser has, minus the last newline and space. self.rawtext = parser.str[:-2] - # As far as I can see, parser.str preserves the statement we are in, - # so that stopatindex can be used to synchronize the string with the - # text box indices. + # Parser.str apparently preserves the statement we are in, so + # that stopatindex can be used to synchronize the string with + # the text box indices. self.stopatindex = stopatindex self.bracketing = parser.get_last_stmt_bracketing() - # find which pairs of bracketing are openers. These always correspond - # to a character of rawtext. - self.isopener = [i>0 and self.bracketing[i][1] > self.bracketing[i-1][1] + # find which pairs of bracketing are openers. These always + # correspond to a character of rawtext. + self.isopener = [i>0 and self.bracketing[i][1] > + self.bracketing[i-1][1] for i in range(len(self.bracketing))] self.set_index(index) def set_index(self, index): - """Set the index to which the functions relate. Note that it must be - in the same statement. + """Set the index to which the functions relate. + + The index must be in the same statement. """ - indexinrawtext = \ - len(self.rawtext) - len(self.text.get(index, self.stopatindex)) + indexinrawtext = (len(self.rawtext) - + len(self.text.get(index, self.stopatindex))) if indexinrawtext < 0: - raise ValueError("The index given is before the analyzed statement") + raise ValueError("Index %s precedes the analyzed statement" + % index) self.indexinrawtext = indexinrawtext # find the rightmost bracket to which index belongs self.indexbracket = 0 - while self.indexbracket < len(self.bracketing)-1 and \ - self.bracketing[self.indexbracket+1][0] < self.indexinrawtext: + while (self.indexbracket < len(self.bracketing)-1 and + self.bracketing[self.indexbracket+1][0] < self.indexinrawtext): self.indexbracket += 1 - if self.indexbracket < len(self.bracketing)-1 and \ - self.bracketing[self.indexbracket+1][0] == self.indexinrawtext and \ - not self.isopener[self.indexbracket+1]: + if (self.indexbracket < len(self.bracketing)-1 and + self.bracketing[self.indexbracket+1][0] == self.indexinrawtext and + not self.isopener[self.indexbracket+1]): self.indexbracket += 1 def is_in_string(self): - """Is the index given to the HyperParser is in a string?""" + """Is the index given to the HyperParser in a string?""" # The bracket to which we belong should be an opener. # If it's an opener, it has to have a character. - return self.isopener[self.indexbracket] and \ - self.rawtext[self.bracketing[self.indexbracket][0]] in ('"', "'") + return (self.isopener[self.indexbracket] and + self.rawtext[self.bracketing[self.indexbracket][0]] + in ('"', "'")) def is_in_code(self): - """Is the index given to the HyperParser is in a normal code?""" - return not self.isopener[self.indexbracket] or \ - self.rawtext[self.bracketing[self.indexbracket][0]] not in \ - ('#', '"', "'") + """Is the index given to the HyperParser in normal code?""" + return (not self.isopener[self.indexbracket] or + self.rawtext[self.bracketing[self.indexbracket][0]] + not in ('#', '"', "'")) def get_surrounding_brackets(self, openers='([{', mustclose=False): - """If the index given to the HyperParser is surrounded by a bracket - defined in openers (or at least has one before it), return the - indices of the opening bracket and the closing bracket (or the - end of line, whichever comes first). - If it is not surrounded by brackets, or the end of line comes before - the closing bracket and mustclose is True, returns None. + """Return bracket indexes or None. + + If the index given to the HyperParser is surrounded by a + bracket defined in openers (or at least has one before it), + return the indices of the opening bracket and the closing + bracket (or the end of line, whichever comes first). + + If it is not surrounded by brackets, or the end of line comes + before the closing bracket and mustclose is True, returns None. """ + bracketinglevel = self.bracketing[self.indexbracket][1] before = self.indexbracket - while not self.isopener[before] or \ - self.rawtext[self.bracketing[before][0]] not in openers or \ - self.bracketing[before][1] > bracketinglevel: + while (not self.isopener[before] or + self.rawtext[self.bracketing[before][0]] not in openers or + self.bracketing[before][1] > bracketinglevel): before -= 1 if before < 0: return None bracketinglevel = min(bracketinglevel, self.bracketing[before][1]) after = self.indexbracket + 1 - while after < len(self.bracketing) and \ - self.bracketing[after][1] >= bracketinglevel: + while (after < len(self.bracketing) and + self.bracketing[after][1] >= bracketinglevel): after += 1 beforeindex = self.text.index("%s-%dc" % (self.stopatindex, len(self.rawtext)-self.bracketing[before][0])) - if after >= len(self.bracketing) or \ - self.bracketing[after][0] > len(self.rawtext): + if (after >= len(self.bracketing) or + self.bracketing[after][0] > len(self.rawtext)): if mustclose: return None afterindex = self.stopatindex else: - # We are after a real char, so it is a ')' and we give the index - # before it. - afterindex = self.text.index("%s-%dc" % - (self.stopatindex, + # We are after a real char, so it is a ')' and we give the + # index before it. + afterindex = self.text.index( + "%s-%dc" % (self.stopatindex, len(self.rawtext)-(self.bracketing[after][0]-1))) return beforeindex, afterindex - # This string includes all chars that may be in a white space - _whitespace_chars = " \t\n\\" - # This string includes all chars that may be in an identifier - _id_chars = string.ascii_letters + string.digits + "_" - # This string includes all chars that may be the first char of an identifier - _id_first_chars = string.ascii_letters + "_" - - # Given a string and pos, return the number of chars in the identifier - # which ends at pos, or 0 if there is no such one. Saved words are not - # identifiers. - def _eat_identifier(self, str, limit, pos): + # the set of built-in identifiers which are also keywords, + # i.e. keyword.iskeyword() returns True for them + _ID_KEYWORDS = frozenset({"True", "False", "None"}) + + @classmethod + def _eat_identifier(cls, str, limit, pos): + """Given a string and pos, return the number of chars in the + identifier which ends at pos, or 0 if there is no such one. + + This ignores non-identifier eywords are not identifiers. + """ + is_ascii_id_char = _IS_ASCII_ID_CHAR + + # Start at the end (pos) and work backwards. i = pos - while i > limit and str[i-1] in self._id_chars: + + # Go backwards as long as the characters are valid ASCII + # identifier characters. This is an optimization, since it + # is faster in the common case where most of the characters + # are ASCII. + while i > limit and ( + ord(str[i - 1]) < 128 and + is_ascii_id_char[ord(str[i - 1])] + ): i -= 1 - if i < pos and (str[i] not in self._id_first_chars or \ - keyword.iskeyword(str[i:pos])): - i = pos + + # If the above loop ended due to reaching a non-ASCII + # character, continue going backwards using the most generic + # test for whether a string contains only valid identifier + # characters. + if i > limit and ord(str[i - 1]) >= 128: + while i - 4 >= limit and ('a' + str[i - 4:pos]).isidentifier(): + i -= 4 + if i - 2 >= limit and ('a' + str[i - 2:pos]).isidentifier(): + i -= 2 + if i - 1 >= limit and ('a' + str[i - 1:pos]).isidentifier(): + i -= 1 + + # The identifier candidate starts here. If it isn't a valid + # identifier, don't eat anything. At this point that is only + # possible if the first character isn't a valid first + # character for an identifier. + if not str[i:pos].isidentifier(): + return 0 + elif i < pos: + # All characters in str[i:pos] are valid ASCII identifier + # characters, so it is enough to check that the first is + # valid as the first character of an identifier. + if not _IS_ASCII_ID_FIRST_CHAR[ord(str[i])]: + return 0 + + # All keywords are valid identifiers, but should not be + # considered identifiers here, except for True, False and None. + if i < pos and ( + iskeyword(str[i:pos]) and + str[i:pos] not in cls._ID_KEYWORDS + ): + return 0 + return pos - i + # This string includes all chars that may be in a white space + _whitespace_chars = " \t\n\\" + def get_expression(self): - """Return a string with the Python expression which ends at the given - index, which is empty if there is no real one. + """Return a string with the Python expression which ends at the + given index, which is empty if there is no real one. """ if not self.is_in_code(): - raise ValueError("get_expression should only be called if index "\ - "is inside a code.") + raise ValueError("get_expression should only be called" + "if index is inside a code.") rawtext = self.rawtext bracketing = self.bracketing @@ -177,20 +239,20 @@ def get_expression(self): postdot_phase = True while 1: - # Eat whitespaces, comments, and if postdot_phase is False - one dot + # Eat whitespaces, comments, and if postdot_phase is False - a dot while 1: if pos>brck_limit and rawtext[pos-1] in self._whitespace_chars: # Eat a whitespace pos -= 1 - elif not postdot_phase and \ - pos > brck_limit and rawtext[pos-1] == '.': + elif (not postdot_phase and + pos > brck_limit and rawtext[pos-1] == '.'): # Eat a dot pos -= 1 postdot_phase = True - # The next line will fail if we are *inside* a comment, but we - # shouldn't be. - elif pos == brck_limit and brck_index > 0 and \ - rawtext[bracketing[brck_index-1][0]] == '#': + # The next line will fail if we are *inside* a comment, + # but we shouldn't be. + elif (pos == brck_limit and brck_index > 0 and + rawtext[bracketing[brck_index-1][0]] == '#'): # Eat a comment brck_index -= 2 brck_limit = bracketing[brck_index][0] @@ -200,8 +262,8 @@ def get_expression(self): break if not postdot_phase: - # We didn't find a dot, so the expression end at the last - # identifier pos. + # We didn't find a dot, so the expression end at the + # last identifier pos. break ret = self._eat_identifier(rawtext, brck_limit, pos) @@ -209,13 +271,13 @@ def get_expression(self): # There is an identifier to eat pos = pos - ret last_identifier_pos = pos - # Now, in order to continue the search, we must find a dot. + # Now, to continue the search, we must find a dot. postdot_phase = False # (the loop continues now) elif pos == brck_limit: - # We are at a bracketing limit. If it is a closing bracket, - # eat the bracket, otherwise, stop the search. + # We are at a bracketing limit. If it is a closing + # bracket, eat the bracket, otherwise, stop the search. level = bracketing[brck_index][1] while brck_index > 0 and bracketing[brck_index-1][1] > level: brck_index -= 1 @@ -244,3 +306,8 @@ def get_expression(self): break return rawtext[last_identifier_pos:self.indexinrawtext] + + +if __name__ == '__main__': + import unittest + unittest.main('idlelib.idle_test.test_hyperparser', verbosity=2) diff --git a/Lib/idlelib/IOBinding.py b/Lib/idlelib/IOBinding.py index 7589ab805a7e..841a30810aab 100644 --- a/Lib/idlelib/IOBinding.py +++ b/Lib/idlelib/IOBinding.py @@ -64,6 +64,7 @@ ### 'encoding' is used below in encode(), check! coding_re = re.compile(r'^[ \t\f]*#.*coding[:=][ \t]*([-\w.]+)', re.ASCII) +blank_re = re.compile(r'^[ \t\f]*(?:[#\r\n]|$)', re.ASCII) def coding_spec(data): """Return the encoding declaration according to PEP 263. @@ -93,6 +94,8 @@ def coding_spec(data): match = coding_re.match(line) if match is not None: break + if not blank_re.match(line): + return None else: return None name = match.group(1) @@ -522,16 +525,17 @@ def updaterecentfileslist(self,filename): if self.editwin.flist: self.editwin.update_recent_files_list(filename) -def test(): +def _io_binding(parent): root = Tk() + root.title("Test IOBinding") + width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) + root.geometry("+%d+%d"%(x, y + 150)) class MyEditWin: def __init__(self, text): self.text = text self.flist = None self.text.bind("<Control-o>", self.open) self.text.bind("<Control-s>", self.save) - self.text.bind("<Alt-s>", self.save_as) - self.text.bind("<Alt-z>", self.save_a_copy) def get_saved(self): return 0 def set_saved(self, flag): pass def reset_undo(self): pass @@ -539,16 +543,13 @@ def open(self, event): self.text.event_generate("<<open-window-from-file>>") def save(self, event): self.text.event_generate("<<save-window>>") - def save_as(self, event): - self.text.event_generate("<<save-window-as-file>>") - def save_a_copy(self, event): - self.text.event_generate("<<save-copy-of-window-as-file>>") + text = Text(root) text.pack() text.focus_set() editwin = MyEditWin(text) io = IOBinding(editwin) - root.mainloop() if __name__ == "__main__": - test() + from idlelib.idle_test.htest import run + run(_io_binding) diff --git a/Lib/idlelib/Icons/idle.ico b/Lib/idlelib/Icons/idle.ico new file mode 100644 index 000000000000..3357aef14888 Binary files /dev/null and b/Lib/idlelib/Icons/idle.ico differ diff --git a/Lib/idlelib/Icons/idle_16.gif b/Lib/idlelib/Icons/idle_16.gif new file mode 100644 index 000000000000..9f001b1d79cf Binary files /dev/null and b/Lib/idlelib/Icons/idle_16.gif differ diff --git a/Lib/idlelib/Icons/idle_16.png b/Lib/idlelib/Icons/idle_16.png new file mode 100644 index 000000000000..6abde0af90cb Binary files /dev/null and b/Lib/idlelib/Icons/idle_16.png differ diff --git a/Lib/idlelib/Icons/idle_32.gif b/Lib/idlelib/Icons/idle_32.gif new file mode 100644 index 000000000000..af5b2d52cce8 Binary files /dev/null and b/Lib/idlelib/Icons/idle_32.gif differ diff --git a/Lib/idlelib/Icons/idle_32.png b/Lib/idlelib/Icons/idle_32.png new file mode 100644 index 000000000000..41b70dbc3776 Binary files /dev/null and b/Lib/idlelib/Icons/idle_32.png differ diff --git a/Lib/idlelib/Icons/idle_48.gif b/Lib/idlelib/Icons/idle_48.gif new file mode 100644 index 000000000000..fc5304f31eed Binary files /dev/null and b/Lib/idlelib/Icons/idle_48.gif differ diff --git a/Lib/idlelib/Icons/idle_48.png b/Lib/idlelib/Icons/idle_48.png new file mode 100644 index 000000000000..e5fa9280e21f Binary files /dev/null and b/Lib/idlelib/Icons/idle_48.png differ diff --git a/Lib/idlelib/Icons/python.gif b/Lib/idlelib/Icons/python.gif index 58271edec493..b189c2c2d22c 100644 Binary files a/Lib/idlelib/Icons/python.gif and b/Lib/idlelib/Icons/python.gif differ diff --git a/Lib/idlelib/IdleHistory.py b/Lib/idlelib/IdleHistory.py index d6cb16272bc2..078af2905325 100644 --- a/Lib/idlelib/IdleHistory.py +++ b/Lib/idlelib/IdleHistory.py @@ -100,7 +100,5 @@ def store(self, source): self.prefix = None if __name__ == "__main__": - from test import support - support.use_resources = ['gui'] from unittest import main main('idlelib.idle_test.test_idlehistory', verbosity=2, exit=False) diff --git a/Lib/idlelib/MultiCall.py b/Lib/idlelib/MultiCall.py index 64729eab8ca4..251a84d083f6 100644 --- a/Lib/idlelib/MultiCall.py +++ b/Lib/idlelib/MultiCall.py @@ -32,7 +32,6 @@ import sys import re import tkinter -from idlelib import macosxSupport # the event type constants, which define the meaning of mc_type MC_KEYPRESS=0; MC_KEYRELEASE=1; MC_BUTTONPRESS=2; MC_BUTTONRELEASE=3; @@ -45,7 +44,7 @@ MC_OPTION = 1<<6; MC_COMMAND = 1<<7 # define the list of modifiers, to be used in complex event types. -if macosxSupport.runningAsOSXApp(): +if sys.platform == "darwin": _modifiers = (("Shift",), ("Control",), ("Option",), ("Command",)) _modifier_masks = (MC_SHIFT, MC_CONTROL, MC_OPTION, MC_COMMAND) else: @@ -57,6 +56,12 @@ for number in range(len(_modifiers)) for name in _modifiers[number]]) +# In 3.4, if no shell window is ever open, the underlying Tk widget is +# destroyed before .__del__ methods here are called. The following +# is used to selectively ignore shutdown exceptions to avoid +# 'Exception ignored' messages. See http://bugs.python.org/issue20167 +APPLICATION_GONE = "application has been destroyed" + # A binder is a class which binds functions to one type of event. It has two # methods: bind and unbind, which get a function and a parsed sequence, as # returned by _parse_sequence(). There are two types of binders: @@ -98,7 +103,12 @@ def unbind(self, triplet, func): def __del__(self): if self.handlerid: - self.widget.unbind(self.widgetinst, self.sequence, self.handlerid) + try: + self.widget.unbind(self.widgetinst, self.sequence, + self.handlerid) + except tkinter.TclError as e: + if not APPLICATION_GONE in e.args[0]: + raise # An int in range(1 << len(_modifiers)) represents a combination of modifiers # (if the least significent bit is on, _modifiers[0] is on, and so on). @@ -227,7 +237,11 @@ def unbind(self, triplet, func): def __del__(self): for seq, id in self.handlerids: - self.widget.unbind(self.widgetinst, seq, id) + try: + self.widget.unbind(self.widgetinst, seq, id) + except tkinter.TclError as e: + if not APPLICATION_GONE in e.args[0]: + raise # define the list of event types to be handled by MultiEvent. the order is # compatible with the definition of event type constants. @@ -390,15 +404,21 @@ def __del__(self): func, triplets = self.__eventinfo[virtual] if func: for triplet in triplets: - self.__binders[triplet[1]].unbind(triplet, func) - + try: + self.__binders[triplet[1]].unbind(triplet, func) + except tkinter.TclError as e: + if not APPLICATION_GONE in e.args[0]: + raise _multicall_dict[widget] = MultiCall return MultiCall -if __name__ == "__main__": - # Test + +def _multi_call(parent): root = tkinter.Tk() + root.title("Test MultiCall") + width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) + root.geometry("+%d+%d"%(x, y + 150)) text = MultiCallCreator(tkinter.Text)(root) text.pack() def bindseq(seq, n=[0]): @@ -414,8 +434,13 @@ def handler(event): bindseq("<Alt-Control-Key-a>") bindseq("<Key-b>") bindseq("<Control-Button-1>") + bindseq("<Button-2>") bindseq("<Alt-Button-1>") bindseq("<FocusOut>") bindseq("<Enter>") bindseq("<Leave>") root.mainloop() + +if __name__ == "__main__": + from idlelib.idle_test.htest import run + run(_multi_call) diff --git a/Lib/idlelib/MultiStatusBar.py b/Lib/idlelib/MultiStatusBar.py index 4fc8dcf94ba3..f44b6a860221 100644 --- a/Lib/idlelib/MultiStatusBar.py +++ b/Lib/idlelib/MultiStatusBar.py @@ -17,16 +17,29 @@ def set_label(self, name, text='', side=LEFT): label = self.labels[name] label.config(text=text) -def _test(): - b = Frame() - c = Text(b) - c.pack(side=TOP) - a = MultiStatusBar(b) - a.set_label("one", "hello") - a.set_label("two", "world") - a.pack(side=BOTTOM, fill=X) - b.pack() - b.mainloop() +def _multistatus_bar(parent): + root = Tk() + width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) + root.geometry("+%d+%d" %(x, y + 150)) + root.title("Test multistatus bar") + frame = Frame(root) + text = Text(frame) + text.pack() + msb = MultiStatusBar(frame) + msb.set_label("one", "hello") + msb.set_label("two", "world") + msb.pack(side=BOTTOM, fill=X) + + def change(): + msb.set_label("one", "foo") + msb.set_label("two", "bar") + + button = Button(root, text="Update status", command=change) + button.pack(side=BOTTOM) + frame.pack() + frame.mainloop() + root.mainloop() if __name__ == '__main__': - _test() + from idlelib.idle_test.htest import run + run(_multistatus_bar) diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index 478c18337ee5..828142c5b488 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -1,3 +1,75 @@ +What's New in IDLE 3.5.0? +========================= + +- 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 a + 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 #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. + +- Issue #21477: htest.py - Improve framework, complete set of tests. + Patches by Saimadhav Heblikar + +- 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. + +- 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. + + What's New in IDLE 3.4.0? ========================= @@ -875,4 +947,3 @@ What's New in IDLEfork 0.9 Alpha 1? -------------------------------------------------------------------- Refer to HISTORY.txt for additional information on earlier releases. -------------------------------------------------------------------- - diff --git a/Lib/idlelib/ObjectBrowser.py b/Lib/idlelib/ObjectBrowser.py index b359efc1b4ee..7b57aa4c684b 100644 --- a/Lib/idlelib/ObjectBrowser.py +++ b/Lib/idlelib/ObjectBrowser.py @@ -9,6 +9,8 @@ # XXX TO DO: # - for classes/modules, add "open source" to object browser +import re + from idlelib.TreeWidget import TreeItem, TreeNode, ScrolledCanvas from reprlib import Repr @@ -119,12 +121,14 @@ def make_objecttreeitem(labeltext, object, setfunction=None): c = ObjectTreeItem return c(labeltext, object, setfunction) -# Test script -def _test(): +def _object_browser(parent): import sys from tkinter import Tk root = Tk() + root.title("Test ObjectBrowser") + width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) + root.geometry("+%d+%d"%(x, y + 150)) root.configure(bd=0, bg="yellow") root.focus_set() sc = ScrolledCanvas(root, bg="white", highlightthickness=0, takefocus=1) @@ -135,4 +139,5 @@ def _test(): root.mainloop() if __name__ == '__main__': - _test() + from idlelib.idle_test.htest import run + run(_object_browser) diff --git a/Lib/idlelib/ParenMatch.py b/Lib/idlelib/ParenMatch.py index 6d91b390d16a..19bad8ce3856 100644 --- a/Lib/idlelib/ParenMatch.py +++ b/Lib/idlelib/ParenMatch.py @@ -90,7 +90,8 @@ def set_style(self, style): self.set_timeout = self.set_timeout_none def flash_paren_event(self, event): - indices = HyperParser(self.editwin, "insert").get_surrounding_brackets() + indices = (HyperParser(self.editwin, "insert") + .get_surrounding_brackets()) if indices is None: self.warn_mismatched() return @@ -167,6 +168,11 @@ def set_timeout_last(self): # associate a counter with an event; only disable the "paren" # tag if the event is for the most recent timer. self.counter += 1 - self.editwin.text_frame.after(self.FLASH_DELAY, - lambda self=self, c=self.counter: \ - self.handle_restore_timer(c)) + self.editwin.text_frame.after( + self.FLASH_DELAY, + lambda self=self, c=self.counter: self.handle_restore_timer(c)) + + +if __name__ == '__main__': + import unittest + unittest.main('idlelib.idle_test.test_parenmatch', verbosity=2) diff --git a/Lib/idlelib/PathBrowser.py b/Lib/idlelib/PathBrowser.py index 5e5c6be98d29..58ff830b437e 100644 --- a/Lib/idlelib/PathBrowser.py +++ b/Lib/idlelib/PathBrowser.py @@ -4,10 +4,16 @@ from idlelib.TreeWidget import TreeItem from idlelib.ClassBrowser import ClassBrowser, ModuleBrowserTreeItem +from idlelib.PyShell import PyShellFileList + class PathBrowser(ClassBrowser): - def __init__(self, flist): + def __init__(self, flist, _htest=False): + """ + _htest - bool, change box location when running htest + """ + self._htest = _htest self.init(flist) def settitle(self): @@ -87,12 +93,14 @@ def listmodules(self, allnames): sorted.sort() return sorted -def main(): - from idlelib import PyShell - PathBrowser(PyShell.flist) - if sys.stdin is sys.__stdin__: - mainloop() +def _path_browser(parent): + flist = PyShellFileList(parent) + PathBrowser(flist, _htest=True) + parent.mainloop() if __name__ == "__main__": from unittest import main main('idlelib.idle_test.test_pathbrowser', verbosity=2, exit=False) + + from idlelib.idle_test.htest import run + run(_path_browser) diff --git a/Lib/idlelib/Percolator.py b/Lib/idlelib/Percolator.py index c91de3812962..9e9331940f72 100644 --- a/Lib/idlelib/Percolator.py +++ b/Lib/idlelib/Percolator.py @@ -51,8 +51,9 @@ def removefilter(self, filter): f.setdelegate(filter.delegate) filter.setdelegate(None) -def main(): - import tkinter as Tk +def _percolator(parent): + import tkinter as tk + import re class Tracer(Delegator): def __init__(self, name): self.name = name @@ -63,22 +64,41 @@ def insert(self, *args): def delete(self, *args): print(self.name, ": delete", args) self.delegate.delete(*args) - root = Tk.Tk() - root.wm_protocol("WM_DELETE_WINDOW", root.quit) - text = Tk.Text() - text.pack() - text.focus_set() + root = tk.Tk() + root.title("Test Percolator") + width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) + root.geometry("+%d+%d"%(x, y + 150)) + text = tk.Text(root) p = Percolator(text) t1 = Tracer("t1") t2 = Tracer("t2") - p.insertfilter(t1) - p.insertfilter(t2) - root.mainloop() # click close widget to continue... - p.removefilter(t2) - root.mainloop() - p.insertfilter(t2) - p.removefilter(t1) + + def toggle1(): + if var1.get() == 0: + var1.set(1) + p.insertfilter(t1) + elif var1.get() == 1: + var1.set(0) + p.removefilter(t1) + + def toggle2(): + if var2.get() == 0: + var2.set(1) + p.insertfilter(t2) + elif var2.get() == 1: + var2.set(0) + p.removefilter(t2) + + text.pack() + var1 = tk.IntVar() + cb1 = tk.Checkbutton(root, text="Tracer1", command=toggle1, variable=var1) + cb1.pack() + var2 = tk.IntVar() + cb2 = tk.Checkbutton(root, text="Tracer2", command=toggle2, variable=var2) + cb2.pack() + root.mainloop() if __name__ == "__main__": - main() + from idlelib.idle_test.htest import run + run(_percolator) diff --git a/Lib/idlelib/PyParse.py b/Lib/idlelib/PyParse.py index 61a0003ce5ae..3e501ca1a191 100644 --- a/Lib/idlelib/PyParse.py +++ b/Lib/idlelib/PyParse.py @@ -1,5 +1,7 @@ import re import sys +from collections import Mapping +from functools import partial # Reason last stmt is continued (or C_NONE if it's not). (C_NONE, C_BACKSLASH, C_STRING_FIRST_LINE, @@ -91,19 +93,48 @@ def dump(*stuff): [^[\](){}#'"\\]+ """, re.VERBOSE).match -# Build translation table to map uninteresting chars to "x", open -# brackets to "(", and close brackets to ")". -_tran = {} -for i in range(256): - _tran[i] = 'x' -for ch in "({[": - _tran[ord(ch)] = '(' -for ch in ")}]": - _tran[ord(ch)] = ')' -for ch in "\"'\\\n#": - _tran[ord(ch)] = ch -del i, ch +class StringTranslatePseudoMapping(Mapping): + r"""Utility class to be used with str.translate() + + This Mapping class wraps a given dict. When a value for a key is + requested via __getitem__() or get(), the key is looked up in the + given dict. If found there, the value from the dict is returned. + Otherwise, the default value given upon initialization is returned. + + This allows using str.translate() to make some replacements, and to + replace all characters for which no replacement was specified with + a given character instead of leaving them as-is. + + For example, to replace everything except whitespace with 'x': + + >>> whitespace_chars = ' \t\n\r' + >>> preserve_dict = {ord(c): ord(c) for c in whitespace_chars} + >>> mapping = StringTranslatePseudoMapping(preserve_dict, ord('x')) + >>> text = "a + b\tc\nd" + >>> text.translate(mapping) + 'x x x\tx\nx' + """ + def __init__(self, non_defaults, default_value): + self._non_defaults = non_defaults + self._default_value = default_value + + def _get(key, _get=non_defaults.get, _default=default_value): + return _get(key, _default) + self._get = _get + + def __getitem__(self, item): + return self._get(item) + + def __len__(self): + return len(self._non_defaults) + + def __iter__(self): + return iter(self._non_defaults) + + def get(self, key, default=None): + return self._get(key) + class Parser: @@ -113,19 +144,6 @@ def __init__(self, indentwidth, tabwidth): def set_str(self, s): assert len(s) == 0 or s[-1] == '\n' - if isinstance(s, str): - # The parse functions have no idea what to do with Unicode, so - # replace all Unicode characters with "x". This is "safe" - # so long as the only characters germane to parsing the structure - # of Python are 7-bit ASCII. It's *necessary* because Unicode - # strings don't have a .translate() method that supports - # deletechars. - uniphooey = s - s = [] - push = s.append - for raw in map(ord, uniphooey): - push(raw < 127 and chr(raw) or "x") - s = "".join(s) self.str = s self.study_level = 0 @@ -197,6 +215,16 @@ def set_lo(self, lo): if lo > 0: self.str = self.str[lo:] + # Build a translation table to map uninteresting chars to 'x', open + # brackets to '(', close brackets to ')' while preserving quotes, + # backslashes, newlines and hashes. This is to be passed to + # str.translate() in _study1(). + _tran = {} + _tran.update((ord(c), ord('(')) for c in "({[") + _tran.update((ord(c), ord(')')) for c in ")}]") + _tran.update((ord(c), ord(c)) for c in "\"'\\\n#") + _tran = StringTranslatePseudoMapping(_tran, default_value=ord('x')) + # As quickly as humanly possible <wink>, find the line numbers (0- # based) of the non-continuation lines. # Creates self.{goodlines, continuation}. @@ -211,7 +239,7 @@ def _study1(self): # uninteresting characters. This can cut the number of chars # by a factor of 10-40, and so greatly speed the following loop. str = self.str - str = str.translate(_tran) + str = str.translate(self._tran) str = str.replace('xxxxxxxx', 'x') str = str.replace('xxxx', 'x') str = str.replace('xx', 'x') diff --git a/Lib/idlelib/PyShell.py b/Lib/idlelib/PyShell.py old mode 100644 new mode 100755 index 36aff92d2c47..51aa3f46b883 --- a/Lib/idlelib/PyShell.py +++ b/Lib/idlelib/PyShell.py @@ -16,12 +16,12 @@ import linecache from code import InteractiveInterpreter -from platform import python_version +from platform import python_version, system try: from tkinter import * except ImportError: - print("** IDLE can't import Tkinter. " \ + print("** IDLE can't import Tkinter.\n" "Your Python may not be configured for Tk. **", file=sys.__stderr__) sys.exit(1) import tkinter.messagebox as tkMessageBox @@ -138,6 +138,7 @@ def filename_changed_hook(old_hook=self.io.filename_change_hook, self.io.set_filename_change_hook(filename_changed_hook) if self.io.filename: self.restore_file_breaks() + self.color_breakpoint_text() rmenu_specs = [ ("Cut", "<<cut>>", "rmenu_check_cut"), @@ -148,6 +149,18 @@ def filename_changed_hook(old_hook=self.io.filename_change_hook, ("Clear Breakpoint", "<<clear-breakpoint-here>>", None) ] + def color_breakpoint_text(self, color=True): + "Turn colorizing of breakpoint text on or off" + if self.io is None: + # possible due to update in restore_file_breaks + return + if color: + theme = idleConf.GetOption('main','Theme','name') + cfg = idleConf.GetHighlight(theme, "break") + else: + cfg = {'foreground': '', 'background': ''} + self.text.tag_config('BREAK', cfg) + def set_breakpoint(self, lineno): text = self.text filename = self.io.filename @@ -217,13 +230,8 @@ def store_file_breaks(self): # This is necessary to keep the saved breaks synched with the # saved file. # - # Breakpoints are set as tagged ranges in the text. Certain - # kinds of edits cause these ranges to be deleted: Inserting - # or deleting a line just before a breakpoint, and certain - # deletions prior to a breakpoint. These issues need to be - # investigated and understood. It's not clear if they are - # Tk issues or IDLE issues, or whether they can actually - # be fixed. Since a modified file has to be saved before it is + # Breakpoints are set as tagged ranges in the text. + # Since a modified file has to be saved before it is # run, and since self.breakpoints (from which the subprocess # debugger is loaded) is updated during the save, the visible # breaks stay synched with the subprocess even if one of these @@ -641,9 +649,9 @@ def execfile(self, filename, source=None): code = compile(source, filename, "exec") except (OverflowError, SyntaxError): self.tkconsole.resetoutput() - tkerr = self.tkconsole.stderr - print('*** Error in script or command!\n', file=tkerr) - print('Traceback (most recent call last):', file=tkerr) + print('*** Error in script or command!\n' + 'Traceback (most recent call last):', + file=self.tkconsole.stderr) InteractiveInterpreter.showsyntaxerror(self, filename) self.tkconsole.showprompt() else: @@ -840,13 +848,10 @@ class PyShell(OutputWindow): ("edit", "_Edit"), ("debug", "_Debug"), ("options", "_Options"), - ("windows", "_Windows"), + ("windows", "_Window"), ("help", "_Help"), ] - if macosxSupport.runningAsOSXApp(): - menu_specs[-2] = ("windows", "_Window") - # New classes from idlelib.IdleHistory import History @@ -1334,8 +1339,11 @@ def writable(self): def write(self, s): if self.closed: raise ValueError("write to closed file") - if not isinstance(s, str): - raise TypeError('must be str, not ' + type(s).__name__) + if type(s) is not str: + if not isinstance(s, str): + raise TypeError('must be str, not ' + type(s).__name__) + # See issue #19481 + s = str.__str__(s) return self.shell.write(s, self.tags) @@ -1381,6 +1389,9 @@ def readline(self, size=-1): line = self._line_buffer or self.shell.readline() if size < 0: size = len(line) + eol = line.find('\n', 0, size) + if eol >= 0: + size = eol + 1 self._line_buffer = line[size:] return line[:size] @@ -1456,8 +1467,7 @@ def main(): try: opts, args = getopt.getopt(sys.argv[1:], "c:deihnr:st:") except getopt.error as msg: - sys.stderr.write("Error: %s\n" % str(msg)) - sys.stderr.write(usage_msg) + print("Error: %s\n%s" % (msg, usage_msg), file=sys.stderr) sys.exit(2) for o, a in opts: if o == '-c': @@ -1524,6 +1534,18 @@ def main(): # start editor and/or shell windows: root = Tk(className="Idle") + # set application icon + icondir = os.path.join(os.path.dirname(__file__), 'Icons') + if system() == 'Windows': + iconfile = os.path.join(icondir, 'idle.ico') + root.wm_iconbitmap(default=iconfile) + elif TkVersion >= 8.5: + ext = '.png' if TkVersion >= 8.6 else '.gif' + iconfiles = [os.path.join(icondir, 'idle_%d%s' % (size, ext)) + for size in (16, 32, 48)] + icons = [PhotoImage(file=iconfile) for iconfile in iconfiles] + root.wm_iconphoto(True, *icons) + fixwordbreaks(root) root.withdraw() flist = PyShellFileList(root) @@ -1537,20 +1559,22 @@ def main(): args.remove(filename) if not args: flist.new() + if enable_shell: shell = flist.open_shell() if not shell: return # couldn't open shell - - if macosxSupport.runningAsOSXApp() and flist.dict: + if macosxSupport.isAquaTk() and flist.dict: # On OSX: when the user has double-clicked on a file that causes # IDLE to be launched the shell window will open just in front of # the file she wants to see. Lower the interpreter window when # there are open files. shell.top.lower() + else: + shell = flist.pyshell - shell = flist.pyshell - # handle remaining options: + # Handle remaining options. If any of these are set, enable_shell + # was set also, so shell must be true to reach here. if debug: shell.open_debugger() if startup: @@ -1558,7 +1582,7 @@ def main(): os.environ.get("PYTHONSTARTUP") if filename and os.path.isfile(filename): shell.interp.execfile(filename) - if shell and cmd or script: + if cmd or script: shell.interp.runcommand("""if 1: import sys as _sys _sys.argv = %r @@ -1569,13 +1593,14 @@ def main(): elif script: shell.interp.prepend_syspath(script) shell.interp.execfile(script) - - # Check for problematic OS X Tk versions and print a warning message - # in the IDLE shell window; this is less intrusive than always opening - # a separate window. - tkversionwarning = macosxSupport.tkVersionWarning(root) - if tkversionwarning: - shell.interp.runcommand(''.join(("print('", tkversionwarning, "')"))) + elif shell: + # If there is a shell window and no cmd or script in progress, + # check for problematic OS X Tk versions and print a warning + # message in the IDLE shell window; this is less intrusive + # than always opening a separate window. + tkversionwarning = macosxSupport.tkVersionWarning(root) + if tkversionwarning: + shell.interp.runcommand("print('%s')" % tkversionwarning) while flist.inversedict: # keep IDLE running while files are open. root.mainloop() diff --git a/Lib/idlelib/ReplaceDialog.py b/Lib/idlelib/ReplaceDialog.py index e73f2c503965..fc8b80f171e9 100644 --- a/Lib/idlelib/ReplaceDialog.py +++ b/Lib/idlelib/ReplaceDialog.py @@ -40,7 +40,7 @@ def open(self, text): def create_entries(self): SearchDialogBase.create_entries(self) - self.replent = self.make_entry("Replace with:", self.replvar) + self.replent = self.make_entry("Replace with:", self.replvar)[0] def create_command_buttons(self): SearchDialogBase.create_command_buttons(self) @@ -188,3 +188,34 @@ def show_hit(self, first, last): def close(self, event=None): SearchDialogBase.close(self, event) self.text.tag_remove("hit", "1.0", "end") + +def _replace_dialog(parent): + root = Tk() + root.title("Test ReplaceDialog") + width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) + root.geometry("+%d+%d"%(x, y + 150)) + + # mock undo delegator methods + def undo_block_start(): + pass + + def undo_block_stop(): + pass + + text = Text(root) + text.undo_block_start = undo_block_start + text.undo_block_stop = undo_block_stop + text.pack() + text.insert("insert","This is a sample string.\n"*10) + + def show_replace(): + text.tag_add(SEL, "1.0", END) + replace(text) + text.tag_remove(SEL, "1.0", END) + + button = Button(root, text="Replace", command=show_replace) + button.pack() + +if __name__ == '__main__': + from idlelib.idle_test.htest import run + run(_replace_dialog) diff --git a/Lib/idlelib/ScriptBinding.py b/Lib/idlelib/ScriptBinding.py index 6bfe128e3ce8..b78363708f8b 100644 --- a/Lib/idlelib/ScriptBinding.py +++ b/Lib/idlelib/ScriptBinding.py @@ -53,7 +53,7 @@ def __init__(self, editwin): self.flist = self.editwin.flist self.root = self.editwin.root - if macosxSupport.runningAsOSXApp(): + if macosxSupport.isCocoaTk(): self.editwin.text_frame.bind('<<run-module-event-2>>', self._run_module_event) def check_module_event(self, event): @@ -114,7 +114,7 @@ def checksyntax(self, filename): shell.set_warning_stream(saved_stream) def run_module_event(self, event): - if macosxSupport.runningAsOSXApp(): + if macosxSupport.isCocoaTk(): # Tk-Cocoa in MacOSX is broken until at least # Tk 8.5.9, and without this rather # crude workaround IDLE would hang when a user diff --git a/Lib/idlelib/ScrolledList.py b/Lib/idlelib/ScrolledList.py index 0255a0a23f9a..71ec5470b4a5 100644 --- a/Lib/idlelib/ScrolledList.py +++ b/Lib/idlelib/ScrolledList.py @@ -119,21 +119,22 @@ def on_double(self, index): pass -def test(): +def _scrolled_list(parent): root = Tk() - root.protocol("WM_DELETE_WINDOW", root.destroy) + root.title("Test ScrolledList") + width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) + root.geometry("+%d+%d"%(x, y + 150)) class MyScrolledList(ScrolledList): - def fill_menu(self): self.menu.add_command(label="pass") + def fill_menu(self): self.menu.add_command(label="right click") def on_select(self, index): print("select", self.get(index)) def on_double(self, index): print("double", self.get(index)) - s = MyScrolledList(root) + + scrolled_list = MyScrolledList(root) for i in range(30): - s.append("item %02d" % i) - return root + scrolled_list.append("Item %02d" % i) -def main(): - root = test() root.mainloop() if __name__ == '__main__': - main() + from idlelib.idle_test.htest import run + run(_scrolled_list) diff --git a/Lib/idlelib/SearchDialog.py b/Lib/idlelib/SearchDialog.py index bf76c419ac33..38408b8dea28 100644 --- a/Lib/idlelib/SearchDialog.py +++ b/Lib/idlelib/SearchDialog.py @@ -65,3 +65,25 @@ def find_selection(self, text): if pat: self.engine.setcookedpat(pat) return self.find_again(text) + +def _search_dialog(parent): + root = Tk() + root.title("Test SearchDialog") + width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) + root.geometry("+%d+%d"%(x, y + 150)) + text = Text(root) + text.pack() + text.insert("insert","This is a sample string.\n"*10) + + def show_find(): + text.tag_add(SEL, "1.0", END) + s = _setup(text) + s.open(text) + text.tag_remove(SEL, "1.0", END) + + button = Button(root, text="Search", command=show_find) + button.pack() + +if __name__ == '__main__': + from idlelib.idle_test.htest import run + run(_search_dialog) diff --git a/Lib/idlelib/SearchDialogBase.py b/Lib/idlelib/SearchDialogBase.py index b8b49b2a1e3d..5fa84e238b16 100644 --- a/Lib/idlelib/SearchDialogBase.py +++ b/Lib/idlelib/SearchDialogBase.py @@ -1,34 +1,51 @@ '''Define SearchDialogBase used by Search, Replace, and Grep dialogs.''' -from tkinter import * + +from tkinter import (Toplevel, Frame, Entry, Label, Button, + Checkbutton, Radiobutton) class SearchDialogBase: - '''Create most of a modal search dialog (make_frame, create_widgets). + '''Create most of a 3 or 4 row, 3 column search dialog. - The wide left column contains: - 1 or 2 text entry lines (create_entries, make_entry); - a row of standard radiobuttons (create_option_buttons); - a row of dialog specific radiobuttons (create_other_buttons). + The left and wide middle column contain: + 1 or 2 labeled text entry lines (make_entry, create_entries); + a row of standard Checkbuttons (make_frame, create_option_buttons), + each of which corresponds to a search engine Variable; + a row of dialog-specific Check/Radiobuttons (create_other_buttons). The narrow right column contains command buttons - (create_command_buttons, make_button). + (make_button, create_command_buttons). These are bound to functions that execute the command. - Except for command buttons, this base class is not limited to - items common to all three subclasses. Rather, it is the Find dialog - minus the "Find Next" command and its execution function. - The other dialogs override methods to replace and add widgets. + Except for command buttons, this base class is not limited to items + common to all three subclasses. Rather, it is the Find dialog minus + the "Find Next" command, its execution function, and the + default_command attribute needed in create_widgets. The other + dialogs override attributes and methods, the latter to replace and + add widgets. ''' - title = "Search Dialog" + title = "Search Dialog" # replace in subclasses icon = "Search" - needwrapbutton = 1 + needwrapbutton = 1 # not in Find in Files def __init__(self, root, engine): + '''Initialize root, engine, and top attributes. + + top (level widget): set in create_widgets() called from open(). + text (Text searched): set in open(), only used in subclasses(). + ent (ry): created in make_entry() called from create_entry(). + row (of grid): 0 in create_widgets(), +1 in make_entry/frame(). + default_command: set in subclasses, used in create_widgers(). + + title (of dialog): class attribute, override in subclasses. + icon (of dialog): ditto, use unclear if cannot minimize dialog. + ''' self.root = root self.engine = engine self.top = None def open(self, text, searchphrase=None): + "Make dialog visible on top of others and ready to use." self.text = text if not self.top: self.create_widgets() @@ -44,11 +61,17 @@ def open(self, text, searchphrase=None): self.top.grab_set() def close(self, event=None): + "Put dialog away for later use." if self.top: self.top.grab_release() self.top.withdraw() def create_widgets(self): + '''Create basic 3 row x 3 col search (find) dialog. + + Other dialogs override subsidiary create_x methods as needed. + Replace and Find-in-Files add another entry row. + ''' top = Toplevel(self.root) top.bind("<Return>", self.default_command) top.bind("<Escape>", self.close) @@ -61,29 +84,84 @@ def create_widgets(self): self.top.grid_columnconfigure(0, pad=2, weight=0) self.top.grid_columnconfigure(1, pad=2, minsize=100, weight=100) - self.create_entries() - self.create_option_buttons() - self.create_other_buttons() - return self.create_command_buttons() - - def make_entry(self, label, var): - l = Label(self.top, text=label) - l.grid(row=self.row, column=0, sticky="nw") - e = Entry(self.top, textvariable=var, exportselection=0) - e.grid(row=self.row, column=1, sticky="nwe") + self.create_entries() # row 0 (and maybe 1), cols 0, 1 + self.create_option_buttons() # next row, cols 0, 1 + self.create_other_buttons() # next row, cols 0, 1 + self.create_command_buttons() # col 2, all rows + + def make_entry(self, label_text, var): + '''Return (entry, label), . + + entry - gridded labeled Entry for text entry. + label - Label widget, returned for testing. + ''' + label = Label(self.top, text=label_text) + label.grid(row=self.row, column=0, sticky="nw") + entry = Entry(self.top, textvariable=var, exportselection=0) + entry.grid(row=self.row, column=1, sticky="nwe") self.row = self.row + 1 - return e + return entry, label + + def create_entries(self): + "Create one or more entry lines with make_entry." + self.ent = self.make_entry("Find:", self.engine.patvar)[0] def make_frame(self,labeltext=None): + '''Return (frame, label). + + frame - gridded labeled Frame for option or other buttons. + label - Label widget, returned for testing. + ''' if labeltext: - l = Label(self.top, text=labeltext) - l.grid(row=self.row, column=0, sticky="nw") - f = Frame(self.top) - f.grid(row=self.row, column=1, columnspan=1, sticky="nwe") + label = Label(self.top, text=labeltext) + label.grid(row=self.row, column=0, sticky="nw") + else: + label = '' + frame = Frame(self.top) + frame.grid(row=self.row, column=1, columnspan=1, sticky="nwe") self.row = self.row + 1 - return f + return frame, label + + def create_option_buttons(self): + '''Return (filled frame, options) for testing. + + Options is a list of SearchEngine booleanvar, label pairs. + A gridded frame from make_frame is filled with a Checkbutton + for each pair, bound to the var, with the corresponding label. + ''' + frame = self.make_frame("Options")[0] + engine = self.engine + options = [(engine.revar, "Regular expression"), + (engine.casevar, "Match case"), + (engine.wordvar, "Whole word")] + if self.needwrapbutton: + options.append((engine.wrapvar, "Wrap around")) + for var, label in options: + btn = Checkbutton(frame, anchor="w", variable=var, text=label) + btn.pack(side="left", fill="both") + if var.get(): + btn.select() + return frame, options + + def create_other_buttons(self): + '''Return (frame, others) for testing. + + Others is a list of value, label pairs. + A gridded frame from make_frame is filled with radio buttons. + ''' + frame = self.make_frame("Direction")[0] + var = self.engine.backvar + others = [(1, 'Up'), (0, 'Down')] + for val, label in others: + btn = Radiobutton(frame, anchor="w", + variable=var, value=val, text=label) + btn.pack(side="left", fill="both") + if var.get() == val: + btn.select() + return frame, others def make_button(self, label, command, isdef=0): + "Return command button gridded in command frame." b = Button(self.buttonframe, text=label, command=command, default=isdef and "active" or "normal") @@ -92,66 +170,15 @@ def make_button(self, label, command, isdef=0): self.buttonframe.grid(rowspan=rows+1) return b - def create_entries(self): - self.ent = self.make_entry("Find:", self.engine.patvar) - - def create_option_buttons(self): - f = self.make_frame("Options") - - btn = Checkbutton(f, anchor="w", - variable=self.engine.revar, - text="Regular expression") - btn.pack(side="left", fill="both") - if self.engine.isre(): - btn.select() - - btn = Checkbutton(f, anchor="w", - variable=self.engine.casevar, - text="Match case") - btn.pack(side="left", fill="both") - if self.engine.iscase(): - btn.select() - - btn = Checkbutton(f, anchor="w", - variable=self.engine.wordvar, - text="Whole word") - btn.pack(side="left", fill="both") - if self.engine.isword(): - btn.select() - - if self.needwrapbutton: - btn = Checkbutton(f, anchor="w", - variable=self.engine.wrapvar, - text="Wrap around") - btn.pack(side="left", fill="both") - if self.engine.iswrap(): - btn.select() - - def create_other_buttons(self): - f = self.make_frame("Direction") - - #lbl = Label(f, text="Direction: ") - #lbl.pack(side="left") - - btn = Radiobutton(f, anchor="w", - variable=self.engine.backvar, value=1, - text="Up") - btn.pack(side="left", fill="both") - if self.engine.isback(): - btn.select() - - btn = Radiobutton(f, anchor="w", - variable=self.engine.backvar, value=0, - text="Down") - btn.pack(side="left", fill="both") - if not self.engine.isback(): - btn.select() - def create_command_buttons(self): - # - # place button frame on the right + "Place buttons in vertical command frame gridded on right." f = self.buttonframe = Frame(self.top) f.grid(row=0,column=2,padx=2,pady=2,ipadx=2,ipady=2) b = self.make_button("close", self.close) b.lower() + +if __name__ == '__main__': + import unittest + unittest.main( + 'idlelib.idle_test.test_searchdialogbase', verbosity=2) diff --git a/Lib/idlelib/SearchEngine.py b/Lib/idlelib/SearchEngine.py index bbd221dec224..099cb09dd5f3 100644 --- a/Lib/idlelib/SearchEngine.py +++ b/Lib/idlelib/SearchEngine.py @@ -83,11 +83,9 @@ def getprog(self): try: prog = re.compile(pat, flags) except re.error as what: - try: - msg, col = what - except: - msg = str(what) - col = -1 + args = what.args + msg = args[0] + col = args[1] if len(args) >= 2 else -1 self.report_error(pat, msg, col) return None return prog @@ -231,6 +229,5 @@ def get_line_col(index): return line, col if __name__ == "__main__": - from test import support; support.use_resources = ['gui'] import unittest unittest.main('idlelib.idle_test.test_searchengine', verbosity=2, exit=False) diff --git a/Lib/idlelib/StackViewer.py b/Lib/idlelib/StackViewer.py index 4ef2d31699eb..b1e5e2674275 100644 --- a/Lib/idlelib/StackViewer.py +++ b/Lib/idlelib/StackViewer.py @@ -1,9 +1,12 @@ import os import sys import linecache +import re +import tkinter as tk from idlelib.TreeWidget import TreeNode, TreeItem, ScrolledCanvas from idlelib.ObjectBrowser import ObjectTreeItem, make_objecttreeitem +from idlelib.PyShell import PyShellFileList def StackBrowser(root, flist=None, tb=None, top=None): if top is None: @@ -120,3 +123,30 @@ def setfunction(value, key=key, object=self.object): item = make_objecttreeitem(key + " =", value, setfunction) sublist.append(item) return sublist + +def _stack_viewer(parent): + root = tk.Tk() + root.title("Test StackViewer") + width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) + root.geometry("+%d+%d"%(x, y + 150)) + flist = PyShellFileList(root) + try: # to obtain a traceback object + intentional_name_error + except NameError: + exc_type, exc_value, exc_tb = sys.exc_info() + + # inject stack trace to sys + sys.last_type = exc_type + sys.last_value = exc_value + sys.last_traceback = exc_tb + + StackBrowser(root, flist=flist, top=root, tb=exc_tb) + + # restore sys to original state + del sys.last_type + del sys.last_value + del sys.last_traceback + +if __name__ == '__main__': + from idlelib.idle_test.htest import run + run(_stack_viewer) diff --git a/Lib/idlelib/ToolTip.py b/Lib/idlelib/ToolTip.py index b178803b02fe..964107e1176d 100644 --- a/Lib/idlelib/ToolTip.py +++ b/Lib/idlelib/ToolTip.py @@ -76,14 +76,22 @@ def showcontents(self): for item in self.items: listbox.insert(END, item) -def main(): - # Test code +def _tooltip(parent): root = Tk() - b = Button(root, text="Hello", command=root.destroy) - b.pack() - root.update() - tip = ListboxToolTip(b, ["Hello", "world"]) + root.title("Test tooltip") + width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) + root.geometry("+%d+%d"%(x, y + 150)) + label = Label(root, text="Place your mouse over buttons") + label.pack() + button1 = Button(root, text="Button 1") + button2 = Button(root, text="Button 2") + button1.pack() + button2.pack() + ToolTip(button1, "This is tooltip text for button1.") + ListboxToolTip(button2, ["This is","multiple line", + "tooltip text","for button2"]) root.mainloop() if __name__ == '__main__': - main() + from idlelib.idle_test.htest import run + run(_tooltip) diff --git a/Lib/idlelib/TreeWidget.py b/Lib/idlelib/TreeWidget.py index 1f4854ddc42d..860f60c12169 100644 --- a/Lib/idlelib/TreeWidget.py +++ b/Lib/idlelib/TreeWidget.py @@ -173,11 +173,12 @@ def update(self): def draw(self, x, y): # XXX This hard-codes too many geometry constants! + dy = 20 self.x, self.y = x, y self.drawicon() self.drawtext() if self.state != 'expanded': - return y+17 + return y + dy # draw children if not self.children: sublist = self.item._GetSubList() @@ -188,7 +189,7 @@ def draw(self, x, y): child = self.__class__(self.canvas, self, item) self.children.append(child) cx = x+20 - cy = y+17 + cy = y + dy cylast = 0 for child in self.children: cylast = cy @@ -227,7 +228,7 @@ def drawicon(self): def drawtext(self): textx = self.x+20-1 - texty = self.y-1 + texty = self.y-4 labeltext = self.item.GetLabelText() if labeltext: id = self.canvas.create_text(textx, texty, anchor="nw", @@ -448,29 +449,18 @@ def zoom_height(self, event): return "break" -# Testing functions - -def test(): - from idlelib import PyShell - root = Toplevel(PyShell.root) - root.configure(bd=0, bg="yellow") - root.focus_set() +def _tree_widget(parent): + root = Tk() + root.title("Test TreeWidget") + width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) + root.geometry("+%d+%d"%(x, y + 150)) sc = ScrolledCanvas(root, bg="white", highlightthickness=0, takefocus=1) - sc.frame.pack(expand=1, fill="both") - item = FileTreeItem("C:/windows/desktop") + sc.frame.pack(expand=1, fill="both", side=LEFT) + item = FileTreeItem(os.getcwd()) node = TreeNode(sc.canvas, None, item) node.expand() - -def test2(): - # test w/o scrolling canvas - root = Tk() - root.configure(bd=0) - canvas = Canvas(root, bg="white", highlightthickness=0) - canvas.pack(expand=1, fill="both") - item = FileTreeItem(os.curdir) - node = TreeNode(canvas, None, item) - node.update() - canvas.focus_set() + root.mainloop() if __name__ == '__main__': - test() + from idlelib.idle_test.htest import run + run(_tree_widget) diff --git a/Lib/idlelib/UndoDelegator.py b/Lib/idlelib/UndoDelegator.py index d2ef638ad244..04c1cf5a2738 100644 --- a/Lib/idlelib/UndoDelegator.py +++ b/Lib/idlelib/UndoDelegator.py @@ -336,17 +336,30 @@ def bump_depth(self, incr=1): self.depth = self.depth + incr return self.depth -def main(): +def _undo_delegator(parent): from idlelib.Percolator import Percolator root = Tk() - root.wm_protocol("WM_DELETE_WINDOW", root.quit) - text = Text() + root.title("Test UndoDelegator") + width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) + root.geometry("+%d+%d"%(x, y + 150)) + + text = Text(root) + text.config(height=10) text.pack() text.focus_set() p = Percolator(text) d = UndoDelegator() p.insertfilter(d) + + undo = Button(root, text="Undo", command=lambda:d.undo_event(None)) + undo.pack(side='left') + redo = Button(root, text="Redo", command=lambda:d.redo_event(None)) + redo.pack(side='left') + dump = Button(root, text="Dump", command=lambda:d.dump_event(None)) + dump.pack(side='left') + root.mainloop() if __name__ == "__main__": - main() + from idlelib.idle_test.htest import run + run(_undo_delegator) diff --git a/Lib/idlelib/WidgetRedirector.py b/Lib/idlelib/WidgetRedirector.py index ba5251ff71f4..67d7f61e623b 100644 --- a/Lib/idlelib/WidgetRedirector.py +++ b/Lib/idlelib/WidgetRedirector.py @@ -1,29 +1,40 @@ -from tkinter import * +from tkinter import TclError class WidgetRedirector: - """Support for redirecting arbitrary widget subcommands. - Some Tk operations don't normally pass through Tkinter. For example, if a + Some Tk operations don't normally pass through tkinter. For example, if a character is inserted into a Text widget by pressing a key, a default Tk binding to the widget's 'insert' operation is activated, and the Tk library - processes the insert without calling back into Tkinter. + processes the insert without calling back into tkinter. - Although a binding to <Key> could be made via Tkinter, what we really want - to do is to hook the Tk 'insert' operation itself. + Although a binding to <Key> could be made via tkinter, what we really want + to do is to hook the Tk 'insert' operation itself. For one thing, we want + a text.insert call in idle code to have the same effect as a key press. When a widget is instantiated, a Tcl command is created whose name is the same as the pathname widget._w. This command is used to invoke the various widget operations, e.g. insert (for a Text widget). We are going to hook this command and provide a facility ('register') to intercept the widget - operation. - - In IDLE, the function being registered provides access to the top of a - Percolator chain. At the bottom of the chain is a call to the original - Tk widget operation. + operation. We will also intercept method calls on the tkinter class + instance that represents the tk widget. + In IDLE, WidgetRedirector is used in Percolator to intercept Text + commands. The function being registered provides access to the top + of a Percolator chain. At the bottom of the chain is a call to the + original Tk widget operation. """ def __init__(self, widget): + '''Initialize attributes and setup redirection. + + _operations: dict mapping operation name to new function. + widget: the widget whose tcl command is to be intercepted. + tk: widget.tk, a convenience attribute, probably not needed. + orig: new name of the original tcl command. + + Since renaming to orig fails with TclError when orig already + exists, only one WidgetDirector can exist for a given widget. + ''' self._operations = {} self.widget = widget # widget instance self.tk = tk = widget.tk # widget's root @@ -36,31 +47,50 @@ def __init__(self, widget): tk.createcommand(w, self.dispatch) def __repr__(self): - return "WidgetRedirector(%s<%s>)" % (self.widget.__class__.__name__, - self.widget._w) + return "%s(%s<%s>)" % (self.__class__.__name__, + self.widget.__class__.__name__, + self.widget._w) def close(self): + "Unregister operations and revert redirection created by .__init__." for operation in list(self._operations): self.unregister(operation) - widget = self.widget; del self.widget - orig = self.orig; del self.orig + widget = self.widget tk = widget.tk w = widget._w + # Restore the original widget Tcl command. tk.deletecommand(w) - # restore the original widget Tcl command: - tk.call("rename", orig, w) + tk.call("rename", self.orig, w) + del self.widget, self.tk # Should not be needed + # if instance is deleted after close, as in Percolator. def register(self, operation, function): + '''Return OriginalCommand(operation) after registering function. + + Registration adds an operation: function pair to ._operations. + It also adds an widget function attribute that masks the tkinter + class instance method. Method masking operates independently + from command dispatch. + + If a second function is registered for the same operation, the + first function is replaced in both places. + ''' self._operations[operation] = function setattr(self.widget, operation, function) return OriginalCommand(self, operation) def unregister(self, operation): + '''Return the function for the operation, or None. + + Deleting the instance attribute unmasks the class attribute. + ''' if operation in self._operations: function = self._operations[operation] del self._operations[operation] - if hasattr(self.widget, operation): + try: delattr(self.widget, operation) + except AttributeError: + pass return function else: return None @@ -88,39 +118,59 @@ def dispatch(self, operation, *args): class OriginalCommand: + '''Callable for original tk command that has been redirected. + + Returned by .register; can be used in the function registered. + redir = WidgetRedirector(text) + def my_insert(*args): + print("insert", args) + original_insert(*args) + original_insert = redir.register("insert", my_insert) + ''' def __init__(self, redir, operation): + '''Create .tk_call and .orig_and_operation for .__call__ method. + + .redir and .operation store the input args for __repr__. + .tk and .orig copy attributes of .redir (probably not needed). + ''' self.redir = redir self.operation = operation - self.tk = redir.tk - self.orig = redir.orig - self.tk_call = self.tk.call - self.orig_and_operation = (self.orig, self.operation) + self.tk = redir.tk # redundant with self.redir + self.orig = redir.orig # redundant with self.redir + # These two could be deleted after checking recipient code. + self.tk_call = redir.tk.call + self.orig_and_operation = (redir.orig, operation) def __repr__(self): - return "OriginalCommand(%r, %r)" % (self.redir, self.operation) + return "%s(%r, %r)" % (self.__class__.__name__, + self.redir, self.operation) def __call__(self, *args): return self.tk_call(self.orig_and_operation + args) -def main(): +def _widget_redirector(parent): # htest # + from tkinter import Tk, Text + import re + root = Tk() - root.wm_protocol("WM_DELETE_WINDOW", root.quit) - text = Text() + root.title("Test WidgetRedirector") + width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) + root.geometry("+%d+%d"%(x, y + 150)) + text = Text(root) text.pack() text.focus_set() redir = WidgetRedirector(text) - global previous_tcl_fcn def my_insert(*args): print("insert", args) - previous_tcl_fcn(*args) - previous_tcl_fcn = redir.register("insert", my_insert) - root.mainloop() - redir.unregister("insert") # runs after first 'close window' - redir.close() + original_insert(*args) + original_insert = redir.register("insert", my_insert) root.mainloop() - root.destroy() if __name__ == "__main__": - main() + import unittest + unittest.main('idlelib.idle_test.test_widgetredir', + verbosity=2, exit=False) + from idlelib.idle_test.htest import run + run(_widget_redirector) diff --git a/Lib/idlelib/ZoomHeight.py b/Lib/idlelib/ZoomHeight.py index e8d171075106..a5d679e49912 100644 --- a/Lib/idlelib/ZoomHeight.py +++ b/Lib/idlelib/ZoomHeight.py @@ -32,7 +32,7 @@ def zoom_height(top): newy = 0 newheight = newheight - 72 - elif macosxSupport.runningAsOSXApp(): + elif macosxSupport.isAquaTk(): # The '88' below is a magic number that avoids placing the bottom # of the window below the panel on my machine. I don't know how # to calculate the correct value for this with tkinter. diff --git a/Lib/idlelib/aboutDialog.py b/Lib/idlelib/aboutDialog.py index 7fe1ab81ee53..942562a70756 100644 --- a/Lib/idlelib/aboutDialog.py +++ b/Lib/idlelib/aboutDialog.py @@ -4,6 +4,7 @@ from tkinter import * import os +import sys from idlelib import textView from idlelib import idlever @@ -12,11 +13,16 @@ class AboutDialog(Toplevel): """Modal about dialog for idle """ - def __init__(self,parent,title): + def __init__(self, parent, title, _htest=False): + """ + _htest - bool, change box location when running htest + """ Toplevel.__init__(self, parent) self.configure(borderwidth=5) - self.geometry("+%d+%d" % (parent.winfo_rootx()+30, - parent.winfo_rooty()+30)) + # place dialog below parent if running htest + self.geometry("+%d+%d" % ( + parent.winfo_rootx()+30, + parent.winfo_rooty()+(30 if not _htest else 100))) self.bg = "#707070" self.fg = "#ffffff" self.CreateWidgets() @@ -57,7 +63,8 @@ def CreateWidgets(self): justify=LEFT, fg=self.fg, bg=self.bg) labelEmail.grid(row=6, column=0, columnspan=2, sticky=W, padx=10, pady=0) - labelWWW = Label(frameBg, text='www: http://www.python.org/idle/', + labelWWW = Label(frameBg, text='https://docs.python.org/' + + sys.version[:3] + '/library/idle.html', justify=LEFT, fg=self.fg, bg=self.bg) labelWWW.grid(row=7, column=0, columnspan=2, sticky=W, padx=10, pady=0) Frame(frameBg, borderwidth=1, relief=SUNKEN, @@ -136,10 +143,5 @@ def Ok(self, event=None): self.destroy() if __name__ == '__main__': - # test the dialog - root = Tk() - def run(): - from idlelib import aboutDialog - aboutDialog.AboutDialog(root, 'About') - Button(root, text='Dialog', command=run).pack() - root.mainloop() + from idlelib.idle_test.htest import run + run(AboutDialog) diff --git a/Lib/idlelib/config-extensions.def b/Lib/idlelib/config-extensions.def index 39e69ce20d4f..a24b8c9316ba 100644 --- a/Lib/idlelib/config-extensions.def +++ b/Lib/idlelib/config-extensions.def @@ -3,94 +3,97 @@ # IDLE reads several config files to determine user preferences. This # file is the default configuration file for IDLE extensions settings. # -# Each extension must have at least one section, named after the extension -# module. This section must contain an 'enable' item (=1 to enable the -# extension, =0 to disable it), it may contain 'enable_editor' or 'enable_shell' -# items, to apply it only to editor/shell windows, and may also contain any -# other general configuration items for the extension. +# Each extension must have at least one section, named after the +# extension module. This section must contain an 'enable' item (=True to +# enable the extension, =False to disable it), it may contain +# 'enable_editor' or 'enable_shell' items, to apply it only to editor ir +# shell windows, and may also contain any other general configuration +# items for the extension. Other True/False values will also be +# recognized as boolean by the Extension Configuration dialog. # -# Each extension must define at least one section named ExtensionName_bindings -# or ExtensionName_cfgBindings. If present, ExtensionName_bindings defines -# virtual event bindings for the extension that are not user re-configurable. -# If present, ExtensionName_cfgBindings defines virtual event bindings for the +# Each extension must define at least one section named +# ExtensionName_bindings or ExtensionName_cfgBindings. If present, +# ExtensionName_bindings defines virtual event bindings for the +# extension that are not user re-configurable. If present, +# ExtensionName_cfgBindings defines virtual event bindings for the # extension that may be sensibly re-configured. # -# If there are no keybindings for a menus' virtual events, include lines like -# <<toggle-code-context>>= (See [CodeContext], below.) +# If there are no keybindings for a menus' virtual events, include lines +# like <<toggle-code-context>>= (See [CodeContext], below.) # -# Currently it is necessary to manually modify this file to change extension -# key bindings and default values. To customize, create +# Currently it is necessary to manually modify this file to change +# extension key bindings and default values. To customize, create # ~/.idlerc/config-extensions.cfg and append the appropriate customized # section(s). Those sections will override the defaults in this file. # -# Note: If a keybinding is already in use when the extension is -# loaded, the extension's virtual event's keybinding will be set to ''. +# Note: If a keybinding is already in use when the extension is loaded, +# the extension's virtual event's keybinding will be set to ''. # # See config-keys.def for notes on specifying keys and extend.txt for # information on creating IDLE extensions. -[FormatParagraph] -enable=1 -[FormatParagraph_cfgBindings] -format-paragraph=<Alt-Key-q> +[AutoComplete] +enable=True +popupwait=2000 +[AutoComplete_cfgBindings] +force-open-completions=<Control-Key-space> +[AutoComplete_bindings] +autocomplete=<Key-Tab> +try-open-completions=<KeyRelease-period> <KeyRelease-slash> <KeyRelease-backslash> [AutoExpand] -enable=1 +enable=True [AutoExpand_cfgBindings] expand-word=<Alt-Key-slash> -[ZoomHeight] -enable=1 -[ZoomHeight_cfgBindings] -zoom-height=<Alt-Key-2> - -[ScriptBinding] -enable=1 -enable_shell=0 -enable_editor=1 -[ScriptBinding_cfgBindings] -run-module=<Key-F5> -check-module=<Alt-Key-x> - [CallTips] -enable=1 +enable=True [CallTips_cfgBindings] force-open-calltip=<Control-Key-backslash> [CallTips_bindings] try-open-calltip=<KeyRelease-parenleft> refresh-calltip=<KeyRelease-parenright> <KeyRelease-0> +[CodeContext] +enable=True +enable_shell=False +numlines=3 +visible=False +bgcolor=LightGray +fgcolor=Black +[CodeContext_bindings] +toggle-code-context= + +[FormatParagraph] +enable=True +max-width=72 +[FormatParagraph_cfgBindings] +format-paragraph=<Alt-Key-q> + [ParenMatch] -enable=1 +enable=True style= expression flash-delay= 500 -bell= 1 +bell=True [ParenMatch_cfgBindings] flash-paren=<Control-Key-0> [ParenMatch_bindings] paren-closed=<KeyRelease-parenright> <KeyRelease-bracketright> <KeyRelease-braceright> -[AutoComplete] -enable=1 -popupwait=2000 -[AutoComplete_cfgBindings] -force-open-completions=<Control-Key-space> -[AutoComplete_bindings] -autocomplete=<Key-Tab> -try-open-completions=<KeyRelease-period> <KeyRelease-slash> <KeyRelease-backslash> - -[CodeContext] -enable=1 -enable_shell=0 -numlines=3 -visible=0 -bgcolor=LightGray -fgcolor=Black -[CodeContext_bindings] -toggle-code-context= - [RstripExtension] -enable=1 -enable_shell=0 -enable_editor=1 +enable=True +enable_shell=False +enable_editor=True +[ScriptBinding] +enable=True +enable_shell=False +enable_editor=True +[ScriptBinding_cfgBindings] +run-module=<Key-F5> +check-module=<Alt-Key-x> + +[ZoomHeight] +enable=True +[ZoomHeight_cfgBindings] +zoom-height=<Alt-Key-2> diff --git a/Lib/idlelib/config-keys.def b/Lib/idlelib/config-keys.def index fdc35ba7b5ac..3bfcb690153c 100644 --- a/Lib/idlelib/config-keys.def +++ b/Lib/idlelib/config-keys.def @@ -13,37 +13,37 @@ cut=<Control-Key-x> <Control-Key-X> paste=<Control-Key-v> <Control-Key-V> beginning-of-line= <Key-Home> center-insert=<Control-Key-l> <Control-Key-L> -close-all-windows=<Control-Key-q> +close-all-windows=<Control-Key-q> <Control-Key-Q> close-window=<Alt-Key-F4> <Meta-Key-F4> do-nothing=<Control-Key-F12> end-of-file=<Control-Key-d> <Control-Key-D> python-docs=<Key-F1> python-context-help=<Shift-Key-F1> -history-next=<Alt-Key-n> <Meta-Key-n> -history-previous=<Alt-Key-p> <Meta-Key-p> +history-next=<Alt-Key-n> <Meta-Key-n> <Alt-Key-N> <Meta-Key-N> +history-previous=<Alt-Key-p> <Meta-Key-p> <Alt-Key-P> <Meta-Key-P> interrupt-execution=<Control-Key-c> <Control-Key-C> view-restart=<Key-F6> restart-shell=<Control-Key-F6> -open-class-browser=<Alt-Key-c> <Meta-Key-c> <Alt-Key-C> -open-module=<Alt-Key-m> <Meta-Key-m> <Alt-Key-M> +open-class-browser=<Alt-Key-c> <Meta-Key-c> <Alt-Key-C> <Meta-Key-C> +open-module=<Alt-Key-m> <Meta-Key-m> <Alt-Key-M> <Meta-Key-M> open-new-window=<Control-Key-n> <Control-Key-N> open-window-from-file=<Control-Key-o> <Control-Key-O> plain-newline-and-indent=<Control-Key-j> <Control-Key-J> print-window=<Control-Key-p> <Control-Key-P> -redo=<Control-Shift-Key-Z> +redo=<Control-Shift-Key-Z> <Control-Shift-Key-z> remove-selection=<Key-Escape> -save-copy-of-window-as-file=<Alt-Shift-Key-S> -save-window-as-file=<Control-Shift-Key-S> -save-window=<Control-Key-s> -select-all=<Control-Key-a> +save-copy-of-window-as-file=<Alt-Shift-Key-S> <Alt-Shift-Key-s> +save-window-as-file=<Control-Shift-Key-S> <Control-Shift-Key-s> +save-window=<Control-Key-s> <Control-Key-S> +select-all=<Control-Key-a> <Control-Key-A> toggle-auto-coloring=<Control-Key-slash> undo=<Control-Key-z> <Control-Key-Z> find=<Control-Key-f> <Control-Key-F> -find-again=<Control-Key-g> <Key-F3> +find-again=<Control-Key-g> <Key-F3> <Control-Key-G> find-in-files=<Alt-Key-F3> <Meta-Key-F3> find-selection=<Control-Key-F3> replace=<Control-Key-h> <Control-Key-H> -goto-line=<Alt-Key-g> <Meta-Key-g> +goto-line=<Alt-Key-g> <Meta-Key-g> <Alt-Key-G> <Meta-Key-G> smart-backspace=<Key-BackSpace> newline-and-indent=<Key-Return> <Key-KP_Enter> smart-indent=<Key-Tab> @@ -53,8 +53,8 @@ comment-region=<Alt-Key-3> <Meta-Key-3> uncomment-region=<Alt-Key-4> <Meta-Key-4> tabify-region=<Alt-Key-5> <Meta-Key-5> untabify-region=<Alt-Key-6> <Meta-Key-6> -toggle-tabs=<Alt-Key-t> <Meta-Key-t> <Alt-Key-T> -change-indentwidth=<Alt-Key-u> <Meta-Key-u> <Alt-Key-U> +toggle-tabs=<Alt-Key-t> <Meta-Key-t> <Alt-Key-T> <Meta-Key-T> +change-indentwidth=<Alt-Key-u> <Meta-Key-u> <Alt-Key-U> <Meta-Key-U> del-word-left=<Control-Key-BackSpace> del-word-right=<Control-Key-Delete> diff --git a/Lib/idlelib/config-main.def b/Lib/idlelib/config-main.def index 9546e2bf1287..0d203cb81ceb 100644 --- a/Lib/idlelib/config-main.def +++ b/Lib/idlelib/config-main.def @@ -58,9 +58,6 @@ font-size= 10 font-bold= 0 encoding= none -[FormatParagraph] -paragraph=70 - [Indent] use-spaces= 1 num-spaces= 4 diff --git a/Lib/idlelib/configDialog.py b/Lib/idlelib/configDialog.py index 1f4a3a576891..ec1de6cc05f9 100644 --- a/Lib/idlelib/configDialog.py +++ b/Lib/idlelib/configDialog.py @@ -13,7 +13,6 @@ import tkinter.messagebox as tkMessageBox import tkinter.colorchooser as tkColorChooser import tkinter.font as tkFont -import copy from idlelib.configHandler import idleConf from idlelib.dynOptionMenuWidget import DynOptionMenu @@ -21,525 +20,562 @@ from idlelib.keybindingDialog import GetKeysDialog from idlelib.configSectionNameDialog import GetCfgSectionNameDialog from idlelib.configHelpSourceEdit import GetHelpSourceDialog +from idlelib.tabbedpages import TabbedPageSet from idlelib import macosxSupport - class ConfigDialog(Toplevel): - def __init__(self,parent,title): + def __init__(self, parent, title='', _htest=False, _utest=False): + """ + _htest - bool, change box location when running htest + _utest - bool, don't wait_window when running unittest + """ Toplevel.__init__(self, parent) + self.parent = parent + if _htest: + parent.instance_dict = {} self.wm_withdraw() self.configure(borderwidth=5) - self.title('IDLE Preferences') - self.geometry("+%d+%d" % (parent.winfo_rootx()+20, - parent.winfo_rooty()+30)) + self.title(title or 'IDLE Preferences') + self.geometry( + "+%d+%d" % (parent.winfo_rootx() + 20, + parent.winfo_rooty() + (30 if not _htest else 150))) #Theme Elements. Each theme element key is its display name. #The first value of the tuple is the sample area tag name. #The second value is the display name list sort index. - self.themeElements={'Normal Text':('normal','00'), - 'Python Keywords':('keyword','01'), - 'Python Definitions':('definition','02'), + self.themeElements={ + 'Normal Text':('normal', '00'), + 'Python Keywords':('keyword', '01'), + 'Python Definitions':('definition', '02'), 'Python Builtins':('builtin', '03'), - 'Python Comments':('comment','04'), - 'Python Strings':('string','05'), - 'Selected Text':('hilite','06'), - 'Found Text':('hit','07'), - 'Cursor':('cursor','08'), - 'Error Text':('error','09'), - 'Shell Normal Text':('console','10'), - 'Shell Stdout Text':('stdout','11'), - 'Shell Stderr Text':('stderr','12'), + 'Python Comments':('comment', '04'), + 'Python Strings':('string', '05'), + 'Selected Text':('hilite', '06'), + 'Found Text':('hit', '07'), + 'Cursor':('cursor', '08'), + 'Error Text':('error', '09'), + 'Shell Normal Text':('console', '10'), + 'Shell Stdout Text':('stdout', '11'), + 'Shell Stderr Text':('stderr', '12'), } self.ResetChangedItems() #load initial values in changed items dict self.CreateWidgets() - self.resizable(height=FALSE,width=FALSE) + self.resizable(height=FALSE, width=FALSE) self.transient(parent) self.grab_set() self.protocol("WM_DELETE_WINDOW", self.Cancel) - self.parent = parent self.tabPages.focus_set() #key bindings for this dialog - #self.bind('<Escape>',self.Cancel) #dismiss dialog, no save - #self.bind('<Alt-a>',self.Apply) #apply changes, save - #self.bind('<F1>',self.Help) #context help + #self.bind('<Escape>', self.Cancel) #dismiss dialog, no save + #self.bind('<Alt-a>', self.Apply) #apply changes, save + #self.bind('<F1>', self.Help) #context help self.LoadConfigs() self.AttachVarCallbacks() #avoid callbacks during LoadConfigs - self.wm_deiconify() - self.wait_window() + if not _utest: + self.wm_deiconify() + self.wait_window() def CreateWidgets(self): self.tabPages = TabbedPageSet(self, - page_names=['Fonts/Tabs','Highlighting','Keys','General']) - frameActionButtons = Frame(self,pady=2) - #action buttons - - if macosxSupport.runningAsOSXApp(): - # Surpress the padx and pady arguments when - # running as IDLE.app, otherwise the text - # on these buttons will not be readable. - extraKwds={} - else: - extraKwds=dict(padx=6, pady=3) - - self.buttonHelp = Button(frameActionButtons,text='Help', - command=self.Help,takefocus=FALSE, - **extraKwds) - self.buttonOk = Button(frameActionButtons,text='Ok', - command=self.Ok,takefocus=FALSE, - **extraKwds) - self.buttonApply = Button(frameActionButtons,text='Apply', - command=self.Apply,takefocus=FALSE, - **extraKwds) - self.buttonCancel = Button(frameActionButtons,text='Cancel', - command=self.Cancel,takefocus=FALSE, - **extraKwds) + page_names=['Fonts/Tabs', 'Highlighting', 'Keys', 'General']) + self.tabPages.pack(side=TOP, expand=TRUE, fill=BOTH) self.CreatePageFontTab() self.CreatePageHighlight() self.CreatePageKeys() self.CreatePageGeneral() - self.buttonHelp.pack(side=RIGHT,padx=5) - self.buttonOk.pack(side=LEFT,padx=5) - self.buttonApply.pack(side=LEFT,padx=5) - self.buttonCancel.pack(side=LEFT,padx=5) - frameActionButtons.pack(side=BOTTOM) - Frame(self, height=2, borderwidth=0).pack(side=BOTTOM) - self.tabPages.pack(side=TOP,expand=TRUE,fill=BOTH) - + self.create_action_buttons().pack(side=BOTTOM) + def create_action_buttons(self): + if macosxSupport.isAquaTk(): + # Changing the default padding on OSX results in unreadable + # text in the buttons + paddingArgs = {} + else: + paddingArgs = {'padx':6, 'pady':3} + outer = Frame(self, pady=2) + buttons = Frame(outer, pady=2) + self.buttonOk = Button( + buttons, text='Ok', command=self.Ok, + takefocus=FALSE, **paddingArgs) + self.buttonApply = Button( + buttons, text='Apply', command=self.Apply, + takefocus=FALSE, **paddingArgs) + self.buttonCancel = Button( + buttons, text='Cancel', command=self.Cancel, + takefocus=FALSE, **paddingArgs) + self.buttonOk.pack(side=LEFT, padx=5) + self.buttonApply.pack(side=LEFT, padx=5) + self.buttonCancel.pack(side=LEFT, padx=5) +# Comment out Help button creation and packing until implement self.Help +## self.buttonHelp = Button( +## buttons, text='Help', command=self.Help, +## takefocus=FALSE, **paddingArgs) +## self.buttonHelp.pack(side=RIGHT, padx=5) + + # add space above buttons + Frame(outer, height=2, borderwidth=0).pack(side=TOP) + buttons.pack(side=BOTTOM) + return outer def CreatePageFontTab(self): - #tkVars - self.fontSize=StringVar(self) - self.fontBold=BooleanVar(self) - self.fontName=StringVar(self) - self.spaceNum=IntVar(self) - self.editFont=tkFont.Font(self,('courier',10,'normal')) + parent = self.parent + self.fontSize = StringVar(parent) + self.fontBold = BooleanVar(parent) + self.fontName = StringVar(parent) + self.spaceNum = IntVar(parent) + self.editFont = tkFont.Font(parent, ('courier', 10, 'normal')) + ##widget creation #body frame - frame=self.tabPages.pages['Fonts/Tabs'].frame + frame = self.tabPages.pages['Fonts/Tabs'].frame #body section frames - frameFont=LabelFrame(frame,borderwidth=2,relief=GROOVE, - text=' Base Editor Font ') - frameIndent=LabelFrame(frame,borderwidth=2,relief=GROOVE, - text=' Indentation Width ') + frameFont = LabelFrame( + frame, borderwidth=2, relief=GROOVE, text=' Base Editor Font ') + frameIndent = LabelFrame( + frame, borderwidth=2, relief=GROOVE, text=' Indentation Width ') #frameFont - frameFontName=Frame(frameFont) - frameFontParam=Frame(frameFont) - labelFontNameTitle=Label(frameFontName,justify=LEFT, - text='Font Face :') - self.listFontName=Listbox(frameFontName,height=5,takefocus=FALSE, - exportselection=FALSE) - self.listFontName.bind('<ButtonRelease-1>',self.OnListFontButtonRelease) - scrollFont=Scrollbar(frameFontName) + frameFontName = Frame(frameFont) + frameFontParam = Frame(frameFont) + labelFontNameTitle = Label( + frameFontName, justify=LEFT, text='Font Face :') + self.listFontName = Listbox( + frameFontName, height=5, takefocus=FALSE, exportselection=FALSE) + self.listFontName.bind( + '<ButtonRelease-1>', self.OnListFontButtonRelease) + scrollFont = Scrollbar(frameFontName) scrollFont.config(command=self.listFontName.yview) self.listFontName.config(yscrollcommand=scrollFont.set) - labelFontSizeTitle=Label(frameFontParam,text='Size :') - self.optMenuFontSize=DynOptionMenu(frameFontParam,self.fontSize,None, - command=self.SetFontSample) - checkFontBold=Checkbutton(frameFontParam,variable=self.fontBold, - onvalue=1,offvalue=0,text='Bold',command=self.SetFontSample) - frameFontSample=Frame(frameFont,relief=SOLID,borderwidth=1) - self.labelFontSample=Label(frameFontSample, - text='AaBbCcDdEe\nFfGgHhIiJjK\n1234567890\n#:+=(){}[]', - justify=LEFT,font=self.editFont) + labelFontSizeTitle = Label(frameFontParam, text='Size :') + self.optMenuFontSize = DynOptionMenu( + frameFontParam, self.fontSize, None, command=self.SetFontSample) + checkFontBold = Checkbutton( + frameFontParam, variable=self.fontBold, onvalue=1, + offvalue=0, text='Bold', command=self.SetFontSample) + frameFontSample = Frame(frameFont, relief=SOLID, borderwidth=1) + self.labelFontSample = Label( + frameFontSample, justify=LEFT, font=self.editFont, + text='AaBbCcDdEe\nFfGgHhIiJjK\n1234567890\n#:+=(){}[]') #frameIndent - frameIndentSize=Frame(frameIndent) - labelSpaceNumTitle=Label(frameIndentSize, justify=LEFT, - text='Python Standard: 4 Spaces!') - self.scaleSpaceNum=Scale(frameIndentSize, variable=self.spaceNum, - orient='horizontal', - tickinterval=2, from_=2, to=16) + frameIndentSize = Frame(frameIndent) + labelSpaceNumTitle = Label( + frameIndentSize, justify=LEFT, + text='Python Standard: 4 Spaces!') + self.scaleSpaceNum = Scale( + frameIndentSize, variable=self.spaceNum, + orient='horizontal', tickinterval=2, from_=2, to=16) + #widget packing #body - frameFont.pack(side=LEFT,padx=5,pady=5,expand=TRUE,fill=BOTH) - frameIndent.pack(side=LEFT,padx=5,pady=5,fill=Y) + frameFont.pack(side=LEFT, padx=5, pady=5, expand=TRUE, fill=BOTH) + frameIndent.pack(side=LEFT, padx=5, pady=5, fill=Y) #frameFont - frameFontName.pack(side=TOP,padx=5,pady=5,fill=X) - frameFontParam.pack(side=TOP,padx=5,pady=5,fill=X) - labelFontNameTitle.pack(side=TOP,anchor=W) - self.listFontName.pack(side=LEFT,expand=TRUE,fill=X) - scrollFont.pack(side=LEFT,fill=Y) - labelFontSizeTitle.pack(side=LEFT,anchor=W) - self.optMenuFontSize.pack(side=LEFT,anchor=W) - checkFontBold.pack(side=LEFT,anchor=W,padx=20) - frameFontSample.pack(side=TOP,padx=5,pady=5,expand=TRUE,fill=BOTH) - self.labelFontSample.pack(expand=TRUE,fill=BOTH) + frameFontName.pack(side=TOP, padx=5, pady=5, fill=X) + frameFontParam.pack(side=TOP, padx=5, pady=5, fill=X) + labelFontNameTitle.pack(side=TOP, anchor=W) + self.listFontName.pack(side=LEFT, expand=TRUE, fill=X) + scrollFont.pack(side=LEFT, fill=Y) + labelFontSizeTitle.pack(side=LEFT, anchor=W) + self.optMenuFontSize.pack(side=LEFT, anchor=W) + checkFontBold.pack(side=LEFT, anchor=W, padx=20) + frameFontSample.pack(side=TOP, padx=5, pady=5, expand=TRUE, fill=BOTH) + self.labelFontSample.pack(expand=TRUE, fill=BOTH) #frameIndent - frameIndentSize.pack(side=TOP,fill=X) - labelSpaceNumTitle.pack(side=TOP,anchor=W,padx=5) - self.scaleSpaceNum.pack(side=TOP,padx=5,fill=X) + frameIndentSize.pack(side=TOP, fill=X) + labelSpaceNumTitle.pack(side=TOP, anchor=W, padx=5) + self.scaleSpaceNum.pack(side=TOP, padx=5, fill=X) return frame def CreatePageHighlight(self): - self.builtinTheme=StringVar(self) - self.customTheme=StringVar(self) - self.fgHilite=BooleanVar(self) - self.colour=StringVar(self) - self.fontName=StringVar(self) - self.themeIsBuiltin=BooleanVar(self) - self.highlightTarget=StringVar(self) + parent = self.parent + self.builtinTheme = StringVar(parent) + self.customTheme = StringVar(parent) + self.fgHilite = BooleanVar(parent) + self.colour = StringVar(parent) + self.fontName = StringVar(parent) + self.themeIsBuiltin = BooleanVar(parent) + self.highlightTarget = StringVar(parent) + ##widget creation #body frame - frame=self.tabPages.pages['Highlighting'].frame + frame = self.tabPages.pages['Highlighting'].frame #body section frames - frameCustom=LabelFrame(frame,borderwidth=2,relief=GROOVE, - text=' Custom Highlighting ') - frameTheme=LabelFrame(frame,borderwidth=2,relief=GROOVE, - text=' Highlighting Theme ') + frameCustom = LabelFrame(frame, borderwidth=2, relief=GROOVE, + text=' Custom Highlighting ') + frameTheme = LabelFrame(frame, borderwidth=2, relief=GROOVE, + text=' Highlighting Theme ') #frameCustom - self.textHighlightSample=Text(frameCustom,relief=SOLID,borderwidth=1, - font=('courier',12,''),cursor='hand2',width=21,height=11, - takefocus=FALSE,highlightthickness=0,wrap=NONE) + self.textHighlightSample=Text( + frameCustom, relief=SOLID, borderwidth=1, + font=('courier', 12, ''), cursor='hand2', width=21, height=11, + takefocus=FALSE, highlightthickness=0, wrap=NONE) text=self.textHighlightSample - text.bind('<Double-Button-1>',lambda e: 'break') - text.bind('<B1-Motion>',lambda e: 'break') - textAndTags=(('#you can click here','comment'),('\n','normal'), - ('#to choose items','comment'),('\n','normal'),('def','keyword'), - (' ','normal'),('func','definition'),('(param):','normal'), - ('\n ','normal'),('"""string"""','string'),('\n var0 = ','normal'), - ("'string'",'string'),('\n var1 = ','normal'),("'selected'",'hilite'), - ('\n var2 = ','normal'),("'found'",'hit'), - ('\n var3 = ','normal'),('list', 'builtin'), ('(','normal'), - ('None', 'keyword'),(')\n\n','normal'), - (' error ','error'),(' ','normal'),('cursor |','cursor'), - ('\n ','normal'),('shell','console'),(' ','normal'),('stdout','stdout'), - (' ','normal'),('stderr','stderr'),('\n','normal')) + text.bind('<Double-Button-1>', lambda e: 'break') + text.bind('<B1-Motion>', lambda e: 'break') + textAndTags=( + ('#you can click here', 'comment'), ('\n', 'normal'), + ('#to choose items', 'comment'), ('\n', 'normal'), + ('def', 'keyword'), (' ', 'normal'), + ('func', 'definition'), ('(param):\n ', 'normal'), + ('"""string"""', 'string'), ('\n var0 = ', 'normal'), + ("'string'", 'string'), ('\n var1 = ', 'normal'), + ("'selected'", 'hilite'), ('\n var2 = ', 'normal'), + ("'found'", 'hit'), ('\n var3 = ', 'normal'), + ('list', 'builtin'), ('(', 'normal'), + ('None', 'keyword'), (')\n\n', 'normal'), + (' error ', 'error'), (' ', 'normal'), + ('cursor |', 'cursor'), ('\n ', 'normal'), + ('shell', 'console'), (' ', 'normal'), + ('stdout', 'stdout'), (' ', 'normal'), + ('stderr', 'stderr'), ('\n', 'normal')) for txTa in textAndTags: - text.insert(END,txTa[0],txTa[1]) + text.insert(END, txTa[0], txTa[1]) for element in self.themeElements: - text.tag_bind(self.themeElements[element][0],'<ButtonPress-1>', - lambda event,elem=element: event.widget.winfo_toplevel() - .highlightTarget.set(elem)) + def tem(event, elem=element): + event.widget.winfo_toplevel().highlightTarget.set(elem) + text.tag_bind( + self.themeElements[element][0], '<ButtonPress-1>', tem) text.config(state=DISABLED) - self.frameColourSet=Frame(frameCustom,relief=SOLID,borderwidth=1) - frameFgBg=Frame(frameCustom) - buttonSetColour=Button(self.frameColourSet,text='Choose Colour for :', - command=self.GetColour,highlightthickness=0) - self.optMenuHighlightTarget=DynOptionMenu(self.frameColourSet, - self.highlightTarget,None,highlightthickness=0)#,command=self.SetHighlightTargetBinding - self.radioFg=Radiobutton(frameFgBg,variable=self.fgHilite, - value=1,text='Foreground',command=self.SetColourSampleBinding) - self.radioBg=Radiobutton(frameFgBg,variable=self.fgHilite, - value=0,text='Background',command=self.SetColourSampleBinding) + self.frameColourSet = Frame(frameCustom, relief=SOLID, borderwidth=1) + frameFgBg = Frame(frameCustom) + buttonSetColour = Button( + self.frameColourSet, text='Choose Colour for :', + command=self.GetColour, highlightthickness=0) + self.optMenuHighlightTarget = DynOptionMenu( + self.frameColourSet, self.highlightTarget, None, + highlightthickness=0) #, command=self.SetHighlightTargetBinding + self.radioFg = Radiobutton( + frameFgBg, variable=self.fgHilite, value=1, + text='Foreground', command=self.SetColourSampleBinding) + self.radioBg=Radiobutton( + frameFgBg, variable=self.fgHilite, value=0, + text='Background', command=self.SetColourSampleBinding) self.fgHilite.set(1) - buttonSaveCustomTheme=Button(frameCustom, - text='Save as New Custom Theme',command=self.SaveAsNewTheme) + buttonSaveCustomTheme = Button( + frameCustom, text='Save as New Custom Theme', + command=self.SaveAsNewTheme) #frameTheme - labelTypeTitle=Label(frameTheme,text='Select : ') - self.radioThemeBuiltin=Radiobutton(frameTheme,variable=self.themeIsBuiltin, - value=1,command=self.SetThemeType,text='a Built-in Theme') - self.radioThemeCustom=Radiobutton(frameTheme,variable=self.themeIsBuiltin, - value=0,command=self.SetThemeType,text='a Custom Theme') - self.optMenuThemeBuiltin=DynOptionMenu(frameTheme, - self.builtinTheme,None,command=None) - self.optMenuThemeCustom=DynOptionMenu(frameTheme, - self.customTheme,None,command=None) - self.buttonDeleteCustomTheme=Button(frameTheme,text='Delete Custom Theme', + labelTypeTitle = Label(frameTheme, text='Select : ') + self.radioThemeBuiltin = Radiobutton( + frameTheme, variable=self.themeIsBuiltin, value=1, + command=self.SetThemeType, text='a Built-in Theme') + self.radioThemeCustom = Radiobutton( + frameTheme, variable=self.themeIsBuiltin, value=0, + command=self.SetThemeType, text='a Custom Theme') + self.optMenuThemeBuiltin = DynOptionMenu( + frameTheme, self.builtinTheme, None, command=None) + self.optMenuThemeCustom=DynOptionMenu( + frameTheme, self.customTheme, None, command=None) + self.buttonDeleteCustomTheme=Button( + frameTheme, text='Delete Custom Theme', command=self.DeleteCustomTheme) + ##widget packing #body - frameCustom.pack(side=LEFT,padx=5,pady=5,expand=TRUE,fill=BOTH) - frameTheme.pack(side=LEFT,padx=5,pady=5,fill=Y) + frameCustom.pack(side=LEFT, padx=5, pady=5, expand=TRUE, fill=BOTH) + frameTheme.pack(side=LEFT, padx=5, pady=5, fill=Y) #frameCustom - self.frameColourSet.pack(side=TOP,padx=5,pady=5,expand=TRUE,fill=X) - frameFgBg.pack(side=TOP,padx=5,pady=0) - self.textHighlightSample.pack(side=TOP,padx=5,pady=5,expand=TRUE, - fill=BOTH) - buttonSetColour.pack(side=TOP,expand=TRUE,fill=X,padx=8,pady=4) - self.optMenuHighlightTarget.pack(side=TOP,expand=TRUE,fill=X,padx=8,pady=3) - self.radioFg.pack(side=LEFT,anchor=E) - self.radioBg.pack(side=RIGHT,anchor=W) - buttonSaveCustomTheme.pack(side=BOTTOM,fill=X,padx=5,pady=5) + self.frameColourSet.pack(side=TOP, padx=5, pady=5, expand=TRUE, fill=X) + frameFgBg.pack(side=TOP, padx=5, pady=0) + self.textHighlightSample.pack( + side=TOP, padx=5, pady=5, expand=TRUE, fill=BOTH) + buttonSetColour.pack(side=TOP, expand=TRUE, fill=X, padx=8, pady=4) + self.optMenuHighlightTarget.pack( + side=TOP, expand=TRUE, fill=X, padx=8, pady=3) + self.radioFg.pack(side=LEFT, anchor=E) + self.radioBg.pack(side=RIGHT, anchor=W) + buttonSaveCustomTheme.pack(side=BOTTOM, fill=X, padx=5, pady=5) #frameTheme - labelTypeTitle.pack(side=TOP,anchor=W,padx=5,pady=5) - self.radioThemeBuiltin.pack(side=TOP,anchor=W,padx=5) - self.radioThemeCustom.pack(side=TOP,anchor=W,padx=5,pady=2) - self.optMenuThemeBuiltin.pack(side=TOP,fill=X,padx=5,pady=5) - self.optMenuThemeCustom.pack(side=TOP,fill=X,anchor=W,padx=5,pady=5) - self.buttonDeleteCustomTheme.pack(side=TOP,fill=X,padx=5,pady=5) + labelTypeTitle.pack(side=TOP, anchor=W, padx=5, pady=5) + self.radioThemeBuiltin.pack(side=TOP, anchor=W, padx=5) + self.radioThemeCustom.pack(side=TOP, anchor=W, padx=5, pady=2) + self.optMenuThemeBuiltin.pack(side=TOP, fill=X, padx=5, pady=5) + self.optMenuThemeCustom.pack(side=TOP, fill=X, anchor=W, padx=5, pady=5) + self.buttonDeleteCustomTheme.pack(side=TOP, fill=X, padx=5, pady=5) return frame def CreatePageKeys(self): - #tkVars - self.bindingTarget=StringVar(self) - self.builtinKeys=StringVar(self) - self.customKeys=StringVar(self) - self.keysAreBuiltin=BooleanVar(self) - self.keyBinding=StringVar(self) + parent = self.parent + self.bindingTarget = StringVar(parent) + self.builtinKeys = StringVar(parent) + self.customKeys = StringVar(parent) + self.keysAreBuiltin = BooleanVar(parent) + self.keyBinding = StringVar(parent) + ##widget creation #body frame - frame=self.tabPages.pages['Keys'].frame + frame = self.tabPages.pages['Keys'].frame #body section frames - frameCustom=LabelFrame(frame,borderwidth=2,relief=GROOVE, - text=' Custom Key Bindings ') - frameKeySets=LabelFrame(frame,borderwidth=2,relief=GROOVE, - text=' Key Set ') + frameCustom = LabelFrame( + frame, borderwidth=2, relief=GROOVE, + text=' Custom Key Bindings ') + frameKeySets = LabelFrame( + frame, borderwidth=2, relief=GROOVE, text=' Key Set ') #frameCustom - frameTarget=Frame(frameCustom) - labelTargetTitle=Label(frameTarget,text='Action - Key(s)') - scrollTargetY=Scrollbar(frameTarget) - scrollTargetX=Scrollbar(frameTarget,orient=HORIZONTAL) - self.listBindings=Listbox(frameTarget,takefocus=FALSE, - exportselection=FALSE) - self.listBindings.bind('<ButtonRelease-1>',self.KeyBindingSelected) + frameTarget = Frame(frameCustom) + labelTargetTitle = Label(frameTarget, text='Action - Key(s)') + scrollTargetY = Scrollbar(frameTarget) + scrollTargetX = Scrollbar(frameTarget, orient=HORIZONTAL) + self.listBindings = Listbox( + frameTarget, takefocus=FALSE, exportselection=FALSE) + self.listBindings.bind('<ButtonRelease-1>', self.KeyBindingSelected) scrollTargetY.config(command=self.listBindings.yview) scrollTargetX.config(command=self.listBindings.xview) self.listBindings.config(yscrollcommand=scrollTargetY.set) self.listBindings.config(xscrollcommand=scrollTargetX.set) - self.buttonNewKeys=Button(frameCustom,text='Get New Keys for Selection', - command=self.GetNewKeys,state=DISABLED) + self.buttonNewKeys = Button( + frameCustom, text='Get New Keys for Selection', + command=self.GetNewKeys, state=DISABLED) #frameKeySets frames = [Frame(frameKeySets, padx=2, pady=2, borderwidth=0) for i in range(2)] - self.radioKeysBuiltin=Radiobutton(frames[0],variable=self.keysAreBuiltin, - value=1,command=self.SetKeysType,text='Use a Built-in Key Set') - self.radioKeysCustom=Radiobutton(frames[0],variable=self.keysAreBuiltin, - value=0,command=self.SetKeysType,text='Use a Custom Key Set') - self.optMenuKeysBuiltin=DynOptionMenu(frames[0], - self.builtinKeys,None,command=None) - self.optMenuKeysCustom=DynOptionMenu(frames[0], - self.customKeys,None,command=None) - self.buttonDeleteCustomKeys=Button(frames[1],text='Delete Custom Key Set', + self.radioKeysBuiltin = Radiobutton( + frames[0], variable=self.keysAreBuiltin, value=1, + command=self.SetKeysType, text='Use a Built-in Key Set') + self.radioKeysCustom = Radiobutton( + frames[0], variable=self.keysAreBuiltin, value=0, + command=self.SetKeysType, text='Use a Custom Key Set') + self.optMenuKeysBuiltin = DynOptionMenu( + frames[0], self.builtinKeys, None, command=None) + self.optMenuKeysCustom = DynOptionMenu( + frames[0], self.customKeys, None, command=None) + self.buttonDeleteCustomKeys = Button( + frames[1], text='Delete Custom Key Set', command=self.DeleteCustomKeys) - buttonSaveCustomKeys=Button(frames[1], - text='Save as New Custom Key Set',command=self.SaveAsNewKeySet) + buttonSaveCustomKeys = Button( + frames[1], text='Save as New Custom Key Set', + command=self.SaveAsNewKeySet) + ##widget packing #body - frameCustom.pack(side=BOTTOM,padx=5,pady=5,expand=TRUE,fill=BOTH) - frameKeySets.pack(side=BOTTOM,padx=5,pady=5,fill=BOTH) + frameCustom.pack(side=BOTTOM, padx=5, pady=5, expand=TRUE, fill=BOTH) + frameKeySets.pack(side=BOTTOM, padx=5, pady=5, fill=BOTH) #frameCustom - self.buttonNewKeys.pack(side=BOTTOM,fill=X,padx=5,pady=5) - frameTarget.pack(side=LEFT,padx=5,pady=5,expand=TRUE,fill=BOTH) + self.buttonNewKeys.pack(side=BOTTOM, fill=X, padx=5, pady=5) + frameTarget.pack(side=LEFT, padx=5, pady=5, expand=TRUE, fill=BOTH) #frame target - frameTarget.columnconfigure(0,weight=1) - frameTarget.rowconfigure(1,weight=1) - labelTargetTitle.grid(row=0,column=0,columnspan=2,sticky=W) - self.listBindings.grid(row=1,column=0,sticky=NSEW) - scrollTargetY.grid(row=1,column=1,sticky=NS) - scrollTargetX.grid(row=2,column=0,sticky=EW) + frameTarget.columnconfigure(0, weight=1) + frameTarget.rowconfigure(1, weight=1) + labelTargetTitle.grid(row=0, column=0, columnspan=2, sticky=W) + self.listBindings.grid(row=1, column=0, sticky=NSEW) + scrollTargetY.grid(row=1, column=1, sticky=NS) + scrollTargetX.grid(row=2, column=0, sticky=EW) #frameKeySets self.radioKeysBuiltin.grid(row=0, column=0, sticky=W+NS) self.radioKeysCustom.grid(row=1, column=0, sticky=W+NS) self.optMenuKeysBuiltin.grid(row=0, column=1, sticky=NSEW) self.optMenuKeysCustom.grid(row=1, column=1, sticky=NSEW) - self.buttonDeleteCustomKeys.pack(side=LEFT,fill=X,expand=True,padx=2) - buttonSaveCustomKeys.pack(side=LEFT,fill=X,expand=True,padx=2) + self.buttonDeleteCustomKeys.pack(side=LEFT, fill=X, expand=True, padx=2) + buttonSaveCustomKeys.pack(side=LEFT, fill=X, expand=True, padx=2) frames[0].pack(side=TOP, fill=BOTH, expand=True) frames[1].pack(side=TOP, fill=X, expand=True, pady=2) return frame def CreatePageGeneral(self): - #tkVars - self.winWidth=StringVar(self) - self.winHeight=StringVar(self) - self.paraWidth=StringVar(self) - self.startupEdit=IntVar(self) - self.autoSave=IntVar(self) - self.encoding=StringVar(self) - self.userHelpBrowser=BooleanVar(self) - self.helpBrowser=StringVar(self) + parent = self.parent + self.winWidth = StringVar(parent) + self.winHeight = StringVar(parent) + self.startupEdit = IntVar(parent) + self.autoSave = IntVar(parent) + self.encoding = StringVar(parent) + self.userHelpBrowser = BooleanVar(parent) + self.helpBrowser = StringVar(parent) + #widget creation #body - frame=self.tabPages.pages['General'].frame + frame = self.tabPages.pages['General'].frame #body section frames - frameRun=LabelFrame(frame,borderwidth=2,relief=GROOVE, - text=' Startup Preferences ') - frameSave=LabelFrame(frame,borderwidth=2,relief=GROOVE, - text=' Autosave Preferences ') - frameWinSize=Frame(frame,borderwidth=2,relief=GROOVE) - frameParaSize=Frame(frame,borderwidth=2,relief=GROOVE) - frameHelp=LabelFrame(frame,borderwidth=2,relief=GROOVE, - text=' Additional Help Sources ') + frameRun = LabelFrame(frame, borderwidth=2, relief=GROOVE, + text=' Startup Preferences ') + frameSave = LabelFrame(frame, borderwidth=2, relief=GROOVE, + text=' Autosave Preferences ') + frameWinSize = Frame(frame, borderwidth=2, relief=GROOVE) + frameHelp = LabelFrame(frame, borderwidth=2, relief=GROOVE, + text=' Additional Help Sources ') #frameRun - labelRunChoiceTitle=Label(frameRun,text='At Startup') - radioStartupEdit=Radiobutton(frameRun,variable=self.startupEdit, - value=1,command=self.SetKeysType,text="Open Edit Window") - radioStartupShell=Radiobutton(frameRun,variable=self.startupEdit, - value=0,command=self.SetKeysType,text='Open Shell Window') + labelRunChoiceTitle = Label(frameRun, text='At Startup') + radioStartupEdit = Radiobutton( + frameRun, variable=self.startupEdit, value=1, + command=self.SetKeysType, text="Open Edit Window") + radioStartupShell = Radiobutton( + frameRun, variable=self.startupEdit, value=0, + command=self.SetKeysType, text='Open Shell Window') #frameSave - labelRunSaveTitle=Label(frameSave,text='At Start of Run (F5) ') - radioSaveAsk=Radiobutton(frameSave,variable=self.autoSave, - value=0,command=self.SetKeysType,text="Prompt to Save") - radioSaveAuto=Radiobutton(frameSave,variable=self.autoSave, - value=1,command=self.SetKeysType,text='No Prompt') + labelRunSaveTitle = Label(frameSave, text='At Start of Run (F5) ') + radioSaveAsk = Radiobutton( + frameSave, variable=self.autoSave, value=0, + command=self.SetKeysType, text="Prompt to Save") + radioSaveAuto = Radiobutton( + frameSave, variable=self.autoSave, value=1, + command=self.SetKeysType, text='No Prompt') #frameWinSize - labelWinSizeTitle=Label(frameWinSize,text='Initial Window Size'+ - ' (in characters)') - labelWinWidthTitle=Label(frameWinSize,text='Width') - entryWinWidth=Entry(frameWinSize,textvariable=self.winWidth, - width=3) - labelWinHeightTitle=Label(frameWinSize,text='Height') - entryWinHeight=Entry(frameWinSize,textvariable=self.winHeight, - width=3) - #paragraphFormatWidth - labelParaWidthTitle=Label(frameParaSize,text='Paragraph reformat'+ - ' width (in characters)') - entryParaWidth=Entry(frameParaSize,textvariable=self.paraWidth, - width=3) + labelWinSizeTitle = Label( + frameWinSize, text='Initial Window Size (in characters)') + labelWinWidthTitle = Label(frameWinSize, text='Width') + entryWinWidth = Entry( + frameWinSize, textvariable=self.winWidth, width=3) + labelWinHeightTitle = Label(frameWinSize, text='Height') + entryWinHeight = Entry( + frameWinSize, textvariable=self.winHeight, width=3) #frameHelp - frameHelpList=Frame(frameHelp) - frameHelpListButtons=Frame(frameHelpList) - scrollHelpList=Scrollbar(frameHelpList) - self.listHelp=Listbox(frameHelpList,height=5,takefocus=FALSE, + frameHelpList = Frame(frameHelp) + frameHelpListButtons = Frame(frameHelpList) + scrollHelpList = Scrollbar(frameHelpList) + self.listHelp = Listbox( + frameHelpList, height=5, takefocus=FALSE, exportselection=FALSE) scrollHelpList.config(command=self.listHelp.yview) self.listHelp.config(yscrollcommand=scrollHelpList.set) - self.listHelp.bind('<ButtonRelease-1>',self.HelpSourceSelected) - self.buttonHelpListEdit=Button(frameHelpListButtons,text='Edit', - state=DISABLED,width=8,command=self.HelpListItemEdit) - self.buttonHelpListAdd=Button(frameHelpListButtons,text='Add', - width=8,command=self.HelpListItemAdd) - self.buttonHelpListRemove=Button(frameHelpListButtons,text='Remove', - state=DISABLED,width=8,command=self.HelpListItemRemove) + self.listHelp.bind('<ButtonRelease-1>', self.HelpSourceSelected) + self.buttonHelpListEdit = Button( + frameHelpListButtons, text='Edit', state=DISABLED, + width=8, command=self.HelpListItemEdit) + self.buttonHelpListAdd = Button( + frameHelpListButtons, text='Add', + width=8, command=self.HelpListItemAdd) + self.buttonHelpListRemove = Button( + frameHelpListButtons, text='Remove', state=DISABLED, + width=8, command=self.HelpListItemRemove) + #widget packing #body - frameRun.pack(side=TOP,padx=5,pady=5,fill=X) - frameSave.pack(side=TOP,padx=5,pady=5,fill=X) - frameWinSize.pack(side=TOP,padx=5,pady=5,fill=X) - frameParaSize.pack(side=TOP,padx=5,pady=5,fill=X) - frameHelp.pack(side=TOP,padx=5,pady=5,expand=TRUE,fill=BOTH) + frameRun.pack(side=TOP, padx=5, pady=5, fill=X) + frameSave.pack(side=TOP, padx=5, pady=5, fill=X) + frameWinSize.pack(side=TOP, padx=5, pady=5, fill=X) + frameHelp.pack(side=TOP, padx=5, pady=5, expand=TRUE, fill=BOTH) #frameRun - labelRunChoiceTitle.pack(side=LEFT,anchor=W,padx=5,pady=5) - radioStartupShell.pack(side=RIGHT,anchor=W,padx=5,pady=5) - radioStartupEdit.pack(side=RIGHT,anchor=W,padx=5,pady=5) + labelRunChoiceTitle.pack(side=LEFT, anchor=W, padx=5, pady=5) + radioStartupShell.pack(side=RIGHT, anchor=W, padx=5, pady=5) + radioStartupEdit.pack(side=RIGHT, anchor=W, padx=5, pady=5) #frameSave - labelRunSaveTitle.pack(side=LEFT,anchor=W,padx=5,pady=5) - radioSaveAuto.pack(side=RIGHT,anchor=W,padx=5,pady=5) - radioSaveAsk.pack(side=RIGHT,anchor=W,padx=5,pady=5) + labelRunSaveTitle.pack(side=LEFT, anchor=W, padx=5, pady=5) + radioSaveAuto.pack(side=RIGHT, anchor=W, padx=5, pady=5) + radioSaveAsk.pack(side=RIGHT, anchor=W, padx=5, pady=5) #frameWinSize - labelWinSizeTitle.pack(side=LEFT,anchor=W,padx=5,pady=5) - entryWinHeight.pack(side=RIGHT,anchor=E,padx=10,pady=5) - labelWinHeightTitle.pack(side=RIGHT,anchor=E,pady=5) - entryWinWidth.pack(side=RIGHT,anchor=E,padx=10,pady=5) - labelWinWidthTitle.pack(side=RIGHT,anchor=E,pady=5) - #paragraphFormatWidth - labelParaWidthTitle.pack(side=LEFT,anchor=W,padx=5,pady=5) - entryParaWidth.pack(side=RIGHT,anchor=E,padx=10,pady=5) + labelWinSizeTitle.pack(side=LEFT, anchor=W, padx=5, pady=5) + entryWinHeight.pack(side=RIGHT, anchor=E, padx=10, pady=5) + labelWinHeightTitle.pack(side=RIGHT, anchor=E, pady=5) + entryWinWidth.pack(side=RIGHT, anchor=E, padx=10, pady=5) + labelWinWidthTitle.pack(side=RIGHT, anchor=E, pady=5) #frameHelp - frameHelpListButtons.pack(side=RIGHT,padx=5,pady=5,fill=Y) - frameHelpList.pack(side=TOP,padx=5,pady=5,expand=TRUE,fill=BOTH) - scrollHelpList.pack(side=RIGHT,anchor=W,fill=Y) - self.listHelp.pack(side=LEFT,anchor=E,expand=TRUE,fill=BOTH) - self.buttonHelpListEdit.pack(side=TOP,anchor=W,pady=5) - self.buttonHelpListAdd.pack(side=TOP,anchor=W) - self.buttonHelpListRemove.pack(side=TOP,anchor=W,pady=5) + frameHelpListButtons.pack(side=RIGHT, padx=5, pady=5, fill=Y) + frameHelpList.pack(side=TOP, padx=5, pady=5, expand=TRUE, fill=BOTH) + scrollHelpList.pack(side=RIGHT, anchor=W, fill=Y) + self.listHelp.pack(side=LEFT, anchor=E, expand=TRUE, fill=BOTH) + self.buttonHelpListEdit.pack(side=TOP, anchor=W, pady=5) + self.buttonHelpListAdd.pack(side=TOP, anchor=W) + self.buttonHelpListRemove.pack(side=TOP, anchor=W, pady=5) return frame def AttachVarCallbacks(self): - self.fontSize.trace_variable('w',self.VarChanged_fontSize) - self.fontName.trace_variable('w',self.VarChanged_fontName) - self.fontBold.trace_variable('w',self.VarChanged_fontBold) - self.spaceNum.trace_variable('w',self.VarChanged_spaceNum) - self.colour.trace_variable('w',self.VarChanged_colour) - self.builtinTheme.trace_variable('w',self.VarChanged_builtinTheme) - self.customTheme.trace_variable('w',self.VarChanged_customTheme) - self.themeIsBuiltin.trace_variable('w',self.VarChanged_themeIsBuiltin) - self.highlightTarget.trace_variable('w',self.VarChanged_highlightTarget) - self.keyBinding.trace_variable('w',self.VarChanged_keyBinding) - self.builtinKeys.trace_variable('w',self.VarChanged_builtinKeys) - self.customKeys.trace_variable('w',self.VarChanged_customKeys) - self.keysAreBuiltin.trace_variable('w',self.VarChanged_keysAreBuiltin) - self.winWidth.trace_variable('w',self.VarChanged_winWidth) - self.winHeight.trace_variable('w',self.VarChanged_winHeight) - self.paraWidth.trace_variable('w',self.VarChanged_paraWidth) - self.startupEdit.trace_variable('w',self.VarChanged_startupEdit) - self.autoSave.trace_variable('w',self.VarChanged_autoSave) - self.encoding.trace_variable('w',self.VarChanged_encoding) - - def VarChanged_fontSize(self,*params): - value=self.fontSize.get() - self.AddChangedItem('main','EditorWindow','font-size',value) - - def VarChanged_fontName(self,*params): - value=self.fontName.get() - self.AddChangedItem('main','EditorWindow','font',value) - - def VarChanged_fontBold(self,*params): - value=self.fontBold.get() - self.AddChangedItem('main','EditorWindow','font-bold',value) - - def VarChanged_spaceNum(self,*params): - value=self.spaceNum.get() - self.AddChangedItem('main','Indent','num-spaces',value) - - def VarChanged_colour(self,*params): + self.fontSize.trace_variable('w', self.VarChanged_fontSize) + self.fontName.trace_variable('w', self.VarChanged_fontName) + self.fontBold.trace_variable('w', self.VarChanged_fontBold) + self.spaceNum.trace_variable('w', self.VarChanged_spaceNum) + self.colour.trace_variable('w', self.VarChanged_colour) + self.builtinTheme.trace_variable('w', self.VarChanged_builtinTheme) + self.customTheme.trace_variable('w', self.VarChanged_customTheme) + self.themeIsBuiltin.trace_variable('w', self.VarChanged_themeIsBuiltin) + self.highlightTarget.trace_variable('w', self.VarChanged_highlightTarget) + self.keyBinding.trace_variable('w', self.VarChanged_keyBinding) + self.builtinKeys.trace_variable('w', self.VarChanged_builtinKeys) + self.customKeys.trace_variable('w', self.VarChanged_customKeys) + self.keysAreBuiltin.trace_variable('w', self.VarChanged_keysAreBuiltin) + self.winWidth.trace_variable('w', self.VarChanged_winWidth) + self.winHeight.trace_variable('w', self.VarChanged_winHeight) + self.startupEdit.trace_variable('w', self.VarChanged_startupEdit) + self.autoSave.trace_variable('w', self.VarChanged_autoSave) + self.encoding.trace_variable('w', self.VarChanged_encoding) + + def VarChanged_fontSize(self, *params): + value = self.fontSize.get() + self.AddChangedItem('main', 'EditorWindow', 'font-size', value) + + def VarChanged_fontName(self, *params): + value = self.fontName.get() + self.AddChangedItem('main', 'EditorWindow', 'font', value) + + def VarChanged_fontBold(self, *params): + value = self.fontBold.get() + self.AddChangedItem('main', 'EditorWindow', 'font-bold', value) + + def VarChanged_spaceNum(self, *params): + value = self.spaceNum.get() + self.AddChangedItem('main', 'Indent', 'num-spaces', value) + + def VarChanged_colour(self, *params): self.OnNewColourSet() - def VarChanged_builtinTheme(self,*params): - value=self.builtinTheme.get() - self.AddChangedItem('main','Theme','name',value) + def VarChanged_builtinTheme(self, *params): + value = self.builtinTheme.get() + self.AddChangedItem('main', 'Theme', 'name', value) self.PaintThemeSample() - def VarChanged_customTheme(self,*params): - value=self.customTheme.get() + def VarChanged_customTheme(self, *params): + value = self.customTheme.get() if value != '- no custom themes -': - self.AddChangedItem('main','Theme','name',value) + self.AddChangedItem('main', 'Theme', 'name', value) self.PaintThemeSample() - def VarChanged_themeIsBuiltin(self,*params): - value=self.themeIsBuiltin.get() - self.AddChangedItem('main','Theme','default',value) + def VarChanged_themeIsBuiltin(self, *params): + value = self.themeIsBuiltin.get() + self.AddChangedItem('main', 'Theme', 'default', value) if value: self.VarChanged_builtinTheme() else: self.VarChanged_customTheme() - def VarChanged_highlightTarget(self,*params): + def VarChanged_highlightTarget(self, *params): self.SetHighlightTarget() - def VarChanged_keyBinding(self,*params): - value=self.keyBinding.get() - keySet=self.customKeys.get() - event=self.listBindings.get(ANCHOR).split()[0] + def VarChanged_keyBinding(self, *params): + value = self.keyBinding.get() + keySet = self.customKeys.get() + event = self.listBindings.get(ANCHOR).split()[0] if idleConf.IsCoreBinding(event): #this is a core keybinding - self.AddChangedItem('keys',keySet,event,value) + self.AddChangedItem('keys', keySet, event, value) else: #this is an extension key binding - extName=idleConf.GetExtnNameForEvent(event) - extKeybindSection=extName+'_cfgBindings' - self.AddChangedItem('extensions',extKeybindSection,event,value) + extName = idleConf.GetExtnNameForEvent(event) + extKeybindSection = extName + '_cfgBindings' + self.AddChangedItem('extensions', extKeybindSection, event, value) - def VarChanged_builtinKeys(self,*params): - value=self.builtinKeys.get() - self.AddChangedItem('main','Keys','name',value) + def VarChanged_builtinKeys(self, *params): + value = self.builtinKeys.get() + self.AddChangedItem('main', 'Keys', 'name', value) self.LoadKeysList(value) - def VarChanged_customKeys(self,*params): - value=self.customKeys.get() + def VarChanged_customKeys(self, *params): + value = self.customKeys.get() if value != '- no custom keys -': - self.AddChangedItem('main','Keys','name',value) + self.AddChangedItem('main', 'Keys', 'name', value) self.LoadKeysList(value) - def VarChanged_keysAreBuiltin(self,*params): - value=self.keysAreBuiltin.get() - self.AddChangedItem('main','Keys','default',value) + def VarChanged_keysAreBuiltin(self, *params): + value = self.keysAreBuiltin.get() + self.AddChangedItem('main', 'Keys', 'default', value) if value: self.VarChanged_builtinKeys() else: self.VarChanged_customKeys() - def VarChanged_winWidth(self,*params): - value=self.winWidth.get() - self.AddChangedItem('main','EditorWindow','width',value) + def VarChanged_winWidth(self, *params): + value = self.winWidth.get() + self.AddChangedItem('main', 'EditorWindow', 'width', value) - def VarChanged_winHeight(self,*params): - value=self.winHeight.get() - self.AddChangedItem('main','EditorWindow','height',value) + def VarChanged_winHeight(self, *params): + value = self.winHeight.get() + self.AddChangedItem('main', 'EditorWindow', 'height', value) - def VarChanged_paraWidth(self,*params): - value=self.paraWidth.get() - self.AddChangedItem('main','FormatParagraph','paragraph',value) + def VarChanged_startupEdit(self, *params): + value = self.startupEdit.get() + self.AddChangedItem('main', 'General', 'editor-on-startup', value) - def VarChanged_startupEdit(self,*params): - value=self.startupEdit.get() - self.AddChangedItem('main','General','editor-on-startup',value) + def VarChanged_autoSave(self, *params): + value = self.autoSave.get() + self.AddChangedItem('main', 'General', 'autosave', value) - def VarChanged_autoSave(self,*params): - value=self.autoSave.get() - self.AddChangedItem('main','General','autosave',value) - - def VarChanged_encoding(self,*params): - value=self.encoding.get() - self.AddChangedItem('main','EditorWindow','encoding',value) + def VarChanged_encoding(self, *params): + value = self.encoding.get() + self.AddChangedItem('main', 'EditorWindow', 'encoding', value) def ResetChangedItems(self): #When any config item is changed in this dialog, an entry @@ -547,24 +583,25 @@ def ResetChangedItems(self): #dictionary. The key should be the config file section name and the #value a dictionary, whose key:value pairs are item=value pairs for #that config file section. - self.changedItems={'main':{},'highlight':{},'keys':{},'extensions':{}} + self.changedItems = {'main':{}, 'highlight':{}, 'keys':{}, + 'extensions':{}} - def AddChangedItem(self,type,section,item,value): - value=str(value) #make sure we use a string - if section not in self.changedItems[type]: - self.changedItems[type][section]={} - self.changedItems[type][section][item]=value + def AddChangedItem(self, typ, section, item, value): + value = str(value) #make sure we use a string + if section not in self.changedItems[typ]: + self.changedItems[typ][section] = {} + self.changedItems[typ][section][item] = value def GetDefaultItems(self): - dItems={'main':{},'highlight':{},'keys':{},'extensions':{}} + dItems={'main':{}, 'highlight':{}, 'keys':{}, 'extensions':{}} for configType in dItems: - sections=idleConf.GetSectionList('default',configType) + sections = idleConf.GetSectionList('default', configType) for section in sections: - dItems[configType][section]={} - options=idleConf.defaultCfg[configType].GetOptionList(section) + dItems[configType][section] = {} + options = idleConf.defaultCfg[configType].GetOptionList(section) for option in options: - dItems[configType][section][option]=( - idleConf.defaultCfg[configType].Get(section,option)) + dItems[configType][section][option] = ( + idleConf.defaultCfg[configType].Get(section, option)) return dItems def SetThemeType(self): @@ -590,26 +627,26 @@ def SetKeysType(self): self.buttonDeleteCustomKeys.config(state=NORMAL) def GetNewKeys(self): - listIndex=self.listBindings.index(ANCHOR) - binding=self.listBindings.get(listIndex) - bindName=binding.split()[0] #first part, up to first space + listIndex = self.listBindings.index(ANCHOR) + binding = self.listBindings.get(listIndex) + bindName = binding.split()[0] #first part, up to first space if self.keysAreBuiltin.get(): - currentKeySetName=self.builtinKeys.get() + currentKeySetName = self.builtinKeys.get() else: - currentKeySetName=self.customKeys.get() - currentBindings=idleConf.GetCurrentKeySet() + currentKeySetName = self.customKeys.get() + currentBindings = idleConf.GetCurrentKeySet() if currentKeySetName in self.changedItems['keys']: #unsaved changes - keySetChanges=self.changedItems['keys'][currentKeySetName] + keySetChanges = self.changedItems['keys'][currentKeySetName] for event in keySetChanges: - currentBindings[event]=keySetChanges[event].split() + currentBindings[event] = keySetChanges[event].split() currentKeySequences = list(currentBindings.values()) - newKeys=GetKeysDialog(self,'Get New Keys',bindName, + newKeys = GetKeysDialog(self, 'Get New Keys', bindName, currentKeySequences).result if newKeys: #new keys were specified if self.keysAreBuiltin.get(): #current key set is a built-in - message=('Your changes will be saved as a new Custom Key Set. '+ - 'Enter a name for your new Custom Key Set below.') - newKeySet=self.GetNewKeysName(message) + message = ('Your changes will be saved as a new Custom Key Set.' + ' Enter a name for your new Custom Key Set below.') + newKeySet = self.GetNewKeysName(message) if not newKeySet: #user cancelled custom key set creation self.listBindings.select_set(listIndex) self.listBindings.select_anchor(listIndex) @@ -617,7 +654,7 @@ def GetNewKeys(self): else: #create new custom key set based on previously active key set self.CreateNewKeySet(newKeySet) self.listBindings.delete(listIndex) - self.listBindings.insert(listIndex,bindName+' - '+newKeys) + self.listBindings.insert(listIndex, bindName+' - '+newKeys) self.listBindings.select_set(listIndex) self.listBindings.select_anchor(listIndex) self.keyBinding.set(newKeys) @@ -625,65 +662,65 @@ def GetNewKeys(self): self.listBindings.select_set(listIndex) self.listBindings.select_anchor(listIndex) - def GetNewKeysName(self,message): - usedNames=(idleConf.GetSectionList('user','keys')+ - idleConf.GetSectionList('default','keys')) - newKeySet=GetCfgSectionNameDialog(self,'New Custom Key Set', - message,usedNames).result + def GetNewKeysName(self, message): + usedNames = (idleConf.GetSectionList('user', 'keys') + + idleConf.GetSectionList('default', 'keys')) + newKeySet = GetCfgSectionNameDialog( + self, 'New Custom Key Set', message, usedNames).result return newKeySet def SaveAsNewKeySet(self): - newKeysName=self.GetNewKeysName('New Key Set Name:') + newKeysName = self.GetNewKeysName('New Key Set Name:') if newKeysName: self.CreateNewKeySet(newKeysName) - def KeyBindingSelected(self,event): + def KeyBindingSelected(self, event): self.buttonNewKeys.config(state=NORMAL) - def CreateNewKeySet(self,newKeySetName): + def CreateNewKeySet(self, newKeySetName): #creates new custom key set based on the previously active key set, #and makes the new key set active if self.keysAreBuiltin.get(): - prevKeySetName=self.builtinKeys.get() + prevKeySetName = self.builtinKeys.get() else: - prevKeySetName=self.customKeys.get() - prevKeys=idleConf.GetCoreKeys(prevKeySetName) - newKeys={} + prevKeySetName = self.customKeys.get() + prevKeys = idleConf.GetCoreKeys(prevKeySetName) + newKeys = {} for event in prevKeys: #add key set to changed items - eventName=event[2:-2] #trim off the angle brackets - binding=' '.join(prevKeys[event]) - newKeys[eventName]=binding + eventName = event[2:-2] #trim off the angle brackets + binding = ' '.join(prevKeys[event]) + newKeys[eventName] = binding #handle any unsaved changes to prev key set if prevKeySetName in self.changedItems['keys']: - keySetChanges=self.changedItems['keys'][prevKeySetName] + keySetChanges = self.changedItems['keys'][prevKeySetName] for event in keySetChanges: - newKeys[event]=keySetChanges[event] + newKeys[event] = keySetChanges[event] #save the new theme - self.SaveNewKeySet(newKeySetName,newKeys) + self.SaveNewKeySet(newKeySetName, newKeys) #change gui over to the new key set - customKeyList=idleConf.GetSectionList('user','keys') + customKeyList = idleConf.GetSectionList('user', 'keys') customKeyList.sort() - self.optMenuKeysCustom.SetMenu(customKeyList,newKeySetName) + self.optMenuKeysCustom.SetMenu(customKeyList, newKeySetName) self.keysAreBuiltin.set(0) self.SetKeysType() - def LoadKeysList(self,keySetName): - reselect=0 - newKeySet=0 + def LoadKeysList(self, keySetName): + reselect = 0 + newKeySet = 0 if self.listBindings.curselection(): - reselect=1 - listIndex=self.listBindings.index(ANCHOR) - keySet=idleConf.GetKeySet(keySetName) + reselect = 1 + listIndex = self.listBindings.index(ANCHOR) + keySet = idleConf.GetKeySet(keySetName) bindNames = list(keySet.keys()) bindNames.sort() - self.listBindings.delete(0,END) + self.listBindings.delete(0, END) for bindName in bindNames: - key=' '.join(keySet[bindName]) #make key(s) into a string - bindName=bindName[2:-2] #trim off the angle brackets + key = ' '.join(keySet[bindName]) #make key(s) into a string + bindName = bindName[2:-2] #trim off the angle brackets if keySetName in self.changedItems['keys']: #handle any unsaved changes to this key set if bindName in self.changedItems['keys'][keySetName]: - key=self.changedItems['keys'][keySetName][bindName] + key = self.changedItems['keys'][keySetName][bindName] self.listBindings.insert(END, bindName+' - '+key) if reselect: self.listBindings.see(listIndex) @@ -692,9 +729,9 @@ def LoadKeysList(self,keySetName): def DeleteCustomKeys(self): keySetName=self.customKeys.get() - if not tkMessageBox.askyesno('Delete Key Set','Are you sure you wish '+ - 'to delete the key set %r ?' % (keySetName), - parent=self): + delmsg = 'Are you sure you wish to delete the key set %r ?' + if not tkMessageBox.askyesno( + 'Delete Key Set', delmsg % keySetName, parent=self): return #remove key set from config idleConf.userCfg['keys'].remove_section(keySetName) @@ -703,25 +740,25 @@ def DeleteCustomKeys(self): #write changes idleConf.userCfg['keys'].Save() #reload user key set list - itemList=idleConf.GetSectionList('user','keys') + itemList = idleConf.GetSectionList('user', 'keys') itemList.sort() if not itemList: self.radioKeysCustom.config(state=DISABLED) - self.optMenuKeysCustom.SetMenu(itemList,'- no custom keys -') + self.optMenuKeysCustom.SetMenu(itemList, '- no custom keys -') else: - self.optMenuKeysCustom.SetMenu(itemList,itemList[0]) + self.optMenuKeysCustom.SetMenu(itemList, itemList[0]) #revert to default key set - self.keysAreBuiltin.set(idleConf.defaultCfg['main'].Get('Keys','default')) - self.builtinKeys.set(idleConf.defaultCfg['main'].Get('Keys','name')) + self.keysAreBuiltin.set(idleConf.defaultCfg['main'].Get('Keys', 'default')) + self.builtinKeys.set(idleConf.defaultCfg['main'].Get('Keys', 'name')) #user can't back out of these changes, they must be applied now self.Apply() self.SetKeysType() def DeleteCustomTheme(self): - themeName=self.customTheme.get() - if not tkMessageBox.askyesno('Delete Theme','Are you sure you wish '+ - 'to delete the theme %r ?' % (themeName,), - parent=self): + themeName = self.customTheme.get() + delmsg = 'Are you sure you wish to delete the theme %r ?' + if not tkMessageBox.askyesno( + 'Delete Theme', delmsg % themeName, parent=self): return #remove theme from config idleConf.userCfg['highlight'].remove_section(themeName) @@ -730,153 +767,149 @@ def DeleteCustomTheme(self): #write changes idleConf.userCfg['highlight'].Save() #reload user theme list - itemList=idleConf.GetSectionList('user','highlight') + itemList = idleConf.GetSectionList('user', 'highlight') itemList.sort() if not itemList: self.radioThemeCustom.config(state=DISABLED) - self.optMenuThemeCustom.SetMenu(itemList,'- no custom themes -') + self.optMenuThemeCustom.SetMenu(itemList, '- no custom themes -') else: - self.optMenuThemeCustom.SetMenu(itemList,itemList[0]) + self.optMenuThemeCustom.SetMenu(itemList, itemList[0]) #revert to default theme - self.themeIsBuiltin.set(idleConf.defaultCfg['main'].Get('Theme','default')) - self.builtinTheme.set(idleConf.defaultCfg['main'].Get('Theme','name')) + self.themeIsBuiltin.set(idleConf.defaultCfg['main'].Get('Theme', 'default')) + self.builtinTheme.set(idleConf.defaultCfg['main'].Get('Theme', 'name')) #user can't back out of these changes, they must be applied now self.Apply() self.SetThemeType() def GetColour(self): - target=self.highlightTarget.get() - prevColour=self.frameColourSet.cget('bg') - rgbTuplet, colourString = tkColorChooser.askcolor(parent=self, - title='Pick new colour for : '+target,initialcolor=prevColour) - if colourString and (colourString!=prevColour): + target = self.highlightTarget.get() + prevColour = self.frameColourSet.cget('bg') + rgbTuplet, colourString = tkColorChooser.askcolor( + parent=self, title='Pick new colour for : '+target, + initialcolor=prevColour) + if colourString and (colourString != prevColour): #user didn't cancel, and they chose a new colour - if self.themeIsBuiltin.get(): #current theme is a built-in - message=('Your changes will be saved as a new Custom Theme. '+ - 'Enter a name for your new Custom Theme below.') - newTheme=self.GetNewThemeName(message) - if not newTheme: #user cancelled custom theme creation + if self.themeIsBuiltin.get(): #current theme is a built-in + message = ('Your changes will be saved as a new Custom Theme. ' + 'Enter a name for your new Custom Theme below.') + newTheme = self.GetNewThemeName(message) + if not newTheme: #user cancelled custom theme creation return - else: #create new custom theme based on previously active theme + else: #create new custom theme based on previously active theme self.CreateNewTheme(newTheme) self.colour.set(colourString) - else: #current theme is user defined + else: #current theme is user defined self.colour.set(colourString) def OnNewColourSet(self): newColour=self.colour.get() - self.frameColourSet.config(bg=newColour)#set sample - if self.fgHilite.get(): plane='foreground' - else: plane='background' - sampleElement=self.themeElements[self.highlightTarget.get()][0] + self.frameColourSet.config(bg=newColour) #set sample + plane ='foreground' if self.fgHilite.get() else 'background' + sampleElement = self.themeElements[self.highlightTarget.get()][0] self.textHighlightSample.tag_config(sampleElement, **{plane:newColour}) - theme=self.customTheme.get() - themeElement=sampleElement+'-'+plane - self.AddChangedItem('highlight',theme,themeElement,newColour) - - def GetNewThemeName(self,message): - usedNames=(idleConf.GetSectionList('user','highlight')+ - idleConf.GetSectionList('default','highlight')) - newTheme=GetCfgSectionNameDialog(self,'New Custom Theme', - message,usedNames).result + theme = self.customTheme.get() + themeElement = sampleElement + '-' + plane + self.AddChangedItem('highlight', theme, themeElement, newColour) + + def GetNewThemeName(self, message): + usedNames = (idleConf.GetSectionList('user', 'highlight') + + idleConf.GetSectionList('default', 'highlight')) + newTheme = GetCfgSectionNameDialog( + self, 'New Custom Theme', message, usedNames).result return newTheme def SaveAsNewTheme(self): - newThemeName=self.GetNewThemeName('New Theme Name:') + newThemeName = self.GetNewThemeName('New Theme Name:') if newThemeName: self.CreateNewTheme(newThemeName) - def CreateNewTheme(self,newThemeName): + def CreateNewTheme(self, newThemeName): #creates new custom theme based on the previously active theme, #and makes the new theme active if self.themeIsBuiltin.get(): - themeType='default' - themeName=self.builtinTheme.get() + themeType = 'default' + themeName = self.builtinTheme.get() else: - themeType='user' - themeName=self.customTheme.get() - newTheme=idleConf.GetThemeDict(themeType,themeName) + themeType = 'user' + themeName = self.customTheme.get() + newTheme = idleConf.GetThemeDict(themeType, themeName) #apply any of the old theme's unsaved changes to the new theme if themeName in self.changedItems['highlight']: - themeChanges=self.changedItems['highlight'][themeName] + themeChanges = self.changedItems['highlight'][themeName] for element in themeChanges: - newTheme[element]=themeChanges[element] + newTheme[element] = themeChanges[element] #save the new theme - self.SaveNewTheme(newThemeName,newTheme) + self.SaveNewTheme(newThemeName, newTheme) #change gui over to the new theme - customThemeList=idleConf.GetSectionList('user','highlight') + customThemeList = idleConf.GetSectionList('user', 'highlight') customThemeList.sort() - self.optMenuThemeCustom.SetMenu(customThemeList,newThemeName) + self.optMenuThemeCustom.SetMenu(customThemeList, newThemeName) self.themeIsBuiltin.set(0) self.SetThemeType() - def OnListFontButtonRelease(self,event): + def OnListFontButtonRelease(self, event): font = self.listFontName.get(ANCHOR) self.fontName.set(font.lower()) self.SetFontSample() - def SetFontSample(self,event=None): - fontName=self.fontName.get() - if self.fontBold.get(): - fontWeight=tkFont.BOLD - else: - fontWeight=tkFont.NORMAL + def SetFontSample(self, event=None): + fontName = self.fontName.get() + fontWeight = tkFont.BOLD if self.fontBold.get() else tkFont.NORMAL newFont = (fontName, self.fontSize.get(), fontWeight) self.labelFontSample.config(font=newFont) self.textHighlightSample.configure(font=newFont) def SetHighlightTarget(self): - if self.highlightTarget.get()=='Cursor': #bg not possible + if self.highlightTarget.get() == 'Cursor': #bg not possible self.radioFg.config(state=DISABLED) self.radioBg.config(state=DISABLED) self.fgHilite.set(1) - else: #both fg and bg can be set + else: #both fg and bg can be set self.radioFg.config(state=NORMAL) self.radioBg.config(state=NORMAL) self.fgHilite.set(1) self.SetColourSample() - def SetColourSampleBinding(self,*args): + def SetColourSampleBinding(self, *args): self.SetColourSample() def SetColourSample(self): #set the colour smaple area - tag=self.themeElements[self.highlightTarget.get()][0] - if self.fgHilite.get(): plane='foreground' - else: plane='background' - colour=self.textHighlightSample.tag_cget(tag,plane) + tag = self.themeElements[self.highlightTarget.get()][0] + plane = 'foreground' if self.fgHilite.get() else 'background' + colour = self.textHighlightSample.tag_cget(tag, plane) self.frameColourSet.config(bg=colour) def PaintThemeSample(self): - if self.themeIsBuiltin.get(): #a default theme - theme=self.builtinTheme.get() - else: #a user theme - theme=self.customTheme.get() + if self.themeIsBuiltin.get(): #a default theme + theme = self.builtinTheme.get() + else: #a user theme + theme = self.customTheme.get() for elementTitle in self.themeElements: - element=self.themeElements[elementTitle][0] - colours=idleConf.GetHighlight(theme,element) - if element=='cursor': #cursor sample needs special painting - colours['background']=idleConf.GetHighlight(theme, - 'normal', fgBg='bg') + element = self.themeElements[elementTitle][0] + colours = idleConf.GetHighlight(theme, element) + if element == 'cursor': #cursor sample needs special painting + colours['background'] = idleConf.GetHighlight( + theme, 'normal', fgBg='bg') #handle any unsaved changes to this theme if theme in self.changedItems['highlight']: - themeDict=self.changedItems['highlight'][theme] - if element+'-foreground' in themeDict: - colours['foreground']=themeDict[element+'-foreground'] - if element+'-background' in themeDict: - colours['background']=themeDict[element+'-background'] + themeDict = self.changedItems['highlight'][theme] + if element + '-foreground' in themeDict: + colours['foreground'] = themeDict[element + '-foreground'] + if element + '-background' in themeDict: + colours['background'] = themeDict[element + '-background'] self.textHighlightSample.tag_config(element, **colours) self.SetColourSample() - def HelpSourceSelected(self,event): + def HelpSourceSelected(self, event): self.SetHelpListButtonStates() def SetHelpListButtonStates(self): - if self.listHelp.size()<1: #no entries in list + if self.listHelp.size() < 1: #no entries in list self.buttonHelpListEdit.config(state=DISABLED) self.buttonHelpListRemove.config(state=DISABLED) else: #there are some entries - if self.listHelp.curselection(): #there currently is a selection + if self.listHelp.curselection(): #there currently is a selection self.buttonHelpListEdit.config(state=NORMAL) self.buttonHelpListRemove.config(state=NORMAL) else: #there currently is not a selection @@ -884,28 +917,29 @@ def SetHelpListButtonStates(self): self.buttonHelpListRemove.config(state=DISABLED) def HelpListItemAdd(self): - helpSource=GetHelpSourceDialog(self,'New Help Source').result + helpSource = GetHelpSourceDialog(self, 'New Help Source').result if helpSource: - self.userHelpList.append( (helpSource[0],helpSource[1]) ) - self.listHelp.insert(END,helpSource[0]) + self.userHelpList.append((helpSource[0], helpSource[1])) + self.listHelp.insert(END, helpSource[0]) self.UpdateUserHelpChangedItems() self.SetHelpListButtonStates() def HelpListItemEdit(self): - itemIndex=self.listHelp.index(ANCHOR) - helpSource=self.userHelpList[itemIndex] - newHelpSource=GetHelpSourceDialog(self,'Edit Help Source', - menuItem=helpSource[0],filePath=helpSource[1]).result - if (not newHelpSource) or (newHelpSource==helpSource): + itemIndex = self.listHelp.index(ANCHOR) + helpSource = self.userHelpList[itemIndex] + newHelpSource = GetHelpSourceDialog( + self, 'Edit Help Source', menuItem=helpSource[0], + filePath=helpSource[1]).result + if (not newHelpSource) or (newHelpSource == helpSource): return #no changes - self.userHelpList[itemIndex]=newHelpSource + self.userHelpList[itemIndex] = newHelpSource self.listHelp.delete(itemIndex) - self.listHelp.insert(itemIndex,newHelpSource[0]) + self.listHelp.insert(itemIndex, newHelpSource[0]) self.UpdateUserHelpChangedItems() self.SetHelpListButtonStates() def HelpListItemRemove(self): - itemIndex=self.listHelp.index(ANCHOR) + itemIndex = self.listHelp.index(ANCHOR) del(self.userHelpList[itemIndex]) self.listHelp.delete(itemIndex) self.UpdateUserHelpChangedItems() @@ -914,18 +948,19 @@ def HelpListItemRemove(self): def UpdateUserHelpChangedItems(self): "Clear and rebuild the HelpFiles section in self.changedItems" self.changedItems['main']['HelpFiles'] = {} - for num in range(1,len(self.userHelpList)+1): - self.AddChangedItem('main','HelpFiles',str(num), + for num in range(1, len(self.userHelpList) + 1): + self.AddChangedItem( + 'main', 'HelpFiles', str(num), ';'.join(self.userHelpList[num-1][:2])) def LoadFontCfg(self): ##base editor font selection list - fonts=list(tkFont.families(self)) + fonts = list(tkFont.families(self)) fonts.sort() for font in fonts: - self.listFontName.insert(END,font) - configuredFont=idleConf.GetOption('main','EditorWindow','font', - default='courier') + self.listFontName.insert(END, font) + configuredFont = idleConf.GetOption( + 'main', 'EditorWindow', 'font', default='courier') lc_configuredFont = configuredFont.lower() self.fontName.set(lc_configuredFont) lc_fonts = [s.lower() for s in fonts] @@ -935,107 +970,104 @@ def LoadFontCfg(self): self.listFontName.select_set(currentFontIndex) self.listFontName.select_anchor(currentFontIndex) ##font size dropdown - fontSize=idleConf.GetOption('main', 'EditorWindow', 'font-size', - type='int', default='10') - self.optMenuFontSize.SetMenu(('7','8','9','10','11','12','13','14', - '16','18','20','22'), fontSize ) + fontSize = idleConf.GetOption( + 'main', 'EditorWindow', 'font-size', type='int', default='10') + self.optMenuFontSize.SetMenu(('7', '8', '9', '10', '11', '12', '13', + '14', '16', '18', '20', '22'), fontSize ) ##fontWeight - self.fontBold.set(idleConf.GetOption('main','EditorWindow', - 'font-bold',default=0,type='bool')) + self.fontBold.set(idleConf.GetOption( + 'main', 'EditorWindow', 'font-bold', default=0, type='bool')) ##font sample self.SetFontSample() def LoadTabCfg(self): ##indent sizes - spaceNum=idleConf.GetOption('main','Indent','num-spaces', - default=4,type='int') + spaceNum = idleConf.GetOption( + 'main', 'Indent', 'num-spaces', default=4, type='int') self.spaceNum.set(spaceNum) def LoadThemeCfg(self): ##current theme type radiobutton - self.themeIsBuiltin.set(idleConf.GetOption('main','Theme','default', - type='bool',default=1)) + self.themeIsBuiltin.set(idleConf.GetOption( + 'main', 'Theme', 'default', type='bool', default=1)) ##currently set theme - currentOption=idleConf.CurrentTheme() + currentOption = idleConf.CurrentTheme() ##load available theme option menus if self.themeIsBuiltin.get(): #default theme selected - itemList=idleConf.GetSectionList('default','highlight') + itemList = idleConf.GetSectionList('default', 'highlight') itemList.sort() - self.optMenuThemeBuiltin.SetMenu(itemList,currentOption) - itemList=idleConf.GetSectionList('user','highlight') + self.optMenuThemeBuiltin.SetMenu(itemList, currentOption) + itemList = idleConf.GetSectionList('user', 'highlight') itemList.sort() if not itemList: self.radioThemeCustom.config(state=DISABLED) self.customTheme.set('- no custom themes -') else: - self.optMenuThemeCustom.SetMenu(itemList,itemList[0]) + self.optMenuThemeCustom.SetMenu(itemList, itemList[0]) else: #user theme selected - itemList=idleConf.GetSectionList('user','highlight') + itemList = idleConf.GetSectionList('user', 'highlight') itemList.sort() - self.optMenuThemeCustom.SetMenu(itemList,currentOption) - itemList=idleConf.GetSectionList('default','highlight') + self.optMenuThemeCustom.SetMenu(itemList, currentOption) + itemList = idleConf.GetSectionList('default', 'highlight') itemList.sort() - self.optMenuThemeBuiltin.SetMenu(itemList,itemList[0]) + self.optMenuThemeBuiltin.SetMenu(itemList, itemList[0]) self.SetThemeType() ##load theme element option menu themeNames = list(self.themeElements.keys()) themeNames.sort(key=lambda x: self.themeElements[x][1]) - self.optMenuHighlightTarget.SetMenu(themeNames,themeNames[0]) + self.optMenuHighlightTarget.SetMenu(themeNames, themeNames[0]) self.PaintThemeSample() self.SetHighlightTarget() def LoadKeyCfg(self): ##current keys type radiobutton - self.keysAreBuiltin.set(idleConf.GetOption('main','Keys','default', - type='bool',default=1)) + self.keysAreBuiltin.set(idleConf.GetOption( + 'main', 'Keys', 'default', type='bool', default=1)) ##currently set keys - currentOption=idleConf.CurrentKeys() + currentOption = idleConf.CurrentKeys() ##load available keyset option menus if self.keysAreBuiltin.get(): #default theme selected - itemList=idleConf.GetSectionList('default','keys') + itemList = idleConf.GetSectionList('default', 'keys') itemList.sort() - self.optMenuKeysBuiltin.SetMenu(itemList,currentOption) - itemList=idleConf.GetSectionList('user','keys') + self.optMenuKeysBuiltin.SetMenu(itemList, currentOption) + itemList = idleConf.GetSectionList('user', 'keys') itemList.sort() if not itemList: self.radioKeysCustom.config(state=DISABLED) self.customKeys.set('- no custom keys -') else: - self.optMenuKeysCustom.SetMenu(itemList,itemList[0]) + self.optMenuKeysCustom.SetMenu(itemList, itemList[0]) else: #user key set selected - itemList=idleConf.GetSectionList('user','keys') + itemList = idleConf.GetSectionList('user', 'keys') itemList.sort() - self.optMenuKeysCustom.SetMenu(itemList,currentOption) - itemList=idleConf.GetSectionList('default','keys') + self.optMenuKeysCustom.SetMenu(itemList, currentOption) + itemList = idleConf.GetSectionList('default', 'keys') itemList.sort() - self.optMenuKeysBuiltin.SetMenu(itemList,itemList[0]) + self.optMenuKeysBuiltin.SetMenu(itemList, itemList[0]) self.SetKeysType() ##load keyset element list - keySetName=idleConf.CurrentKeys() + keySetName = idleConf.CurrentKeys() self.LoadKeysList(keySetName) def LoadGeneralCfg(self): #startup state - self.startupEdit.set(idleConf.GetOption('main','General', - 'editor-on-startup',default=1,type='bool')) + self.startupEdit.set(idleConf.GetOption( + 'main', 'General', 'editor-on-startup', default=1, type='bool')) #autosave state - self.autoSave.set(idleConf.GetOption('main', 'General', 'autosave', - default=0, type='bool')) + self.autoSave.set(idleConf.GetOption( + 'main', 'General', 'autosave', default=0, type='bool')) #initial window size - self.winWidth.set(idleConf.GetOption('main','EditorWindow','width', - type='int')) - self.winHeight.set(idleConf.GetOption('main','EditorWindow','height', - type='int')) - #initial paragraph reformat size - self.paraWidth.set(idleConf.GetOption('main','FormatParagraph','paragraph', - type='int')) + self.winWidth.set(idleConf.GetOption( + 'main', 'EditorWindow', 'width', type='int')) + self.winHeight.set(idleConf.GetOption( + 'main', 'EditorWindow', 'height', type='int')) # default source encoding - self.encoding.set(idleConf.GetOption('main', 'EditorWindow', - 'encoding', default='none')) + self.encoding.set(idleConf.GetOption( + 'main', 'EditorWindow', 'encoding', default='none')) # additional help sources self.userHelpList = idleConf.GetAllExtraHelpSourcesList() for helpItem in self.userHelpList: - self.listHelp.insert(END,helpItem[0]) + self.listHelp.insert(END, helpItem[0]) self.SetHelpListButtonStates() def LoadConfigs(self): @@ -1053,7 +1085,7 @@ def LoadConfigs(self): ### general page self.LoadGeneralCfg() - def SaveNewKeySet(self,keySetName,keySet): + def SaveNewKeySet(self, keySetName, keySet): """ save a newly created core key set. keySetName - string, the name of the new key set @@ -1062,10 +1094,10 @@ def SaveNewKeySet(self,keySetName,keySet): if not idleConf.userCfg['keys'].has_section(keySetName): idleConf.userCfg['keys'].add_section(keySetName) for event in keySet: - value=keySet[event] - idleConf.userCfg['keys'].SetOption(keySetName,event,value) + value = keySet[event] + idleConf.userCfg['keys'].SetOption(keySetName, event, value) - def SaveNewTheme(self,themeName,theme): + def SaveNewTheme(self, themeName, theme): """ save a newly created theme. themeName - string, the name of the new theme @@ -1074,16 +1106,16 @@ def SaveNewTheme(self,themeName,theme): if not idleConf.userCfg['highlight'].has_section(themeName): idleConf.userCfg['highlight'].add_section(themeName) for element in theme: - value=theme[element] - idleConf.userCfg['highlight'].SetOption(themeName,element,value) + value = theme[element] + idleConf.userCfg['highlight'].SetOption(themeName, element, value) - def SetUserValue(self,configType,section,item,value): - if idleConf.defaultCfg[configType].has_option(section,item): - if idleConf.defaultCfg[configType].Get(section,item)==value: + def SetUserValue(self, configType, section, item, value): + if idleConf.defaultCfg[configType].has_option(section, item): + if idleConf.defaultCfg[configType].Get(section, item) == value: #the setting equals a default setting, remove it from user cfg - return idleConf.userCfg[configType].RemoveOption(section,item) + return idleConf.userCfg[configType].RemoveOption(section, item) #if we got here set the option - return idleConf.userCfg[configType].SetOption(section,item,value) + return idleConf.userCfg[configType].SetOption(section, item, value) def SaveAllChangedConfigs(self): "Save configuration changes to the user config file." @@ -1097,7 +1129,7 @@ def SaveAllChangedConfigs(self): cfgTypeHasChanges = True for item in self.changedItems[configType][section]: value = self.changedItems[configType][section][item] - if self.SetUserValue(configType,section,item,value): + if self.SetUserValue(configType, section, item, value): cfgTypeHasChanges = True if cfgTypeHasChanges: idleConf.userCfg[configType].Save() @@ -1138,10 +1170,252 @@ def Apply(self): def Help(self): pass +class VerticalScrolledFrame(Frame): + """A pure Tkinter vertically scrollable frame. + + * Use the 'interior' attribute to place widgets inside the scrollable frame + * Construct and pack/place/grid normally + * This frame only allows vertical scrolling + """ + def __init__(self, parent, *args, **kw): + Frame.__init__(self, parent, *args, **kw) + + # create a canvas object and a vertical scrollbar for scrolling it + vscrollbar = Scrollbar(self, orient=VERTICAL) + vscrollbar.pack(fill=Y, side=RIGHT, expand=FALSE) + canvas = Canvas(self, bd=0, highlightthickness=0, + yscrollcommand=vscrollbar.set) + canvas.pack(side=LEFT, fill=BOTH, expand=TRUE) + vscrollbar.config(command=canvas.yview) + + # reset the view + canvas.xview_moveto(0) + canvas.yview_moveto(0) + + # create a frame inside the canvas which will be scrolled with it + self.interior = interior = Frame(canvas) + interior_id = canvas.create_window(0, 0, window=interior, anchor=NW) + + # track changes to the canvas and frame width and sync them, + # also updating the scrollbar + def _configure_interior(event): + # update the scrollbars to match the size of the inner frame + size = (interior.winfo_reqwidth(), interior.winfo_reqheight()) + canvas.config(scrollregion="0 0 %s %s" % size) + if interior.winfo_reqwidth() != canvas.winfo_width(): + # update the canvas's width to fit the inner frame + canvas.config(width=interior.winfo_reqwidth()) + interior.bind('<Configure>', _configure_interior) + + def _configure_canvas(event): + if interior.winfo_reqwidth() != canvas.winfo_width(): + # update the inner frame's width to fill the canvas + canvas.itemconfigure(interior_id, width=canvas.winfo_width()) + canvas.bind('<Configure>', _configure_canvas) + + return + +def is_int(s): + "Return 's is blank or represents an int'" + if not s: + return True + try: + int(s) + return True + except ValueError: + return False + +# TODO: +# * Revert to default(s)? Per option or per extension? +# * List options in their original order (possible??) +class ConfigExtensionsDialog(Toplevel): + """A dialog for configuring IDLE extensions. + + This dialog is generic - it works for any and all IDLE extensions. + + IDLE extensions save their configuration options using idleConf. + ConfigExtensionsDialog reads the current configuration using idleConf, + supplies a GUI interface to change the configuration values, and saves the + changes using idleConf. + + Not all changes take effect immediately - some may require restarting IDLE. + This depends on each extension's implementation. + + All values are treated as text, and it is up to the user to supply + reasonable values. The only exception to this are the 'enable*' options, + which are boolean, and can be toggled with an True/False button. + """ + def __init__(self, parent, title=None, _htest=False): + Toplevel.__init__(self, parent) + self.wm_withdraw() + + self.configure(borderwidth=5) + self.geometry( + "+%d+%d" % (parent.winfo_rootx() + 20, + parent.winfo_rooty() + (30 if not _htest else 150))) + self.wm_title(title or 'IDLE Extensions Configuration') + + self.defaultCfg = idleConf.defaultCfg['extensions'] + self.userCfg = idleConf.userCfg['extensions'] + self.is_int = self.register(is_int) + self.load_extensions() + self.create_widgets() + + self.resizable(height=FALSE, width=FALSE) # don't allow resizing yet + self.transient(parent) + self.protocol("WM_DELETE_WINDOW", self.Cancel) + self.tabbed_page_set.focus_set() + # wait for window to be generated + self.update() + # set current width as the minimum width + self.wm_minsize(self.winfo_width(), 1) + # now allow resizing + self.resizable(height=TRUE, width=TRUE) + + self.wm_deiconify() + if not _htest: + self.grab_set() + self.wait_window() + + def load_extensions(self): + "Fill self.extensions with data from the default and user configs." + self.extensions = {} + for ext_name in idleConf.GetExtensions(active_only=False): + self.extensions[ext_name] = [] + + for ext_name in self.extensions: + opt_list = sorted(self.defaultCfg.GetOptionList(ext_name)) + + # bring 'enable' options to the beginning of the list + enables = [opt_name for opt_name in opt_list + if opt_name.startswith('enable')] + for opt_name in enables: + opt_list.remove(opt_name) + opt_list = enables + opt_list + + for opt_name in opt_list: + def_str = self.defaultCfg.Get( + ext_name, opt_name, raw=True) + try: + def_obj = {'True':True, 'False':False}[def_str] + opt_type = 'bool' + except KeyError: + try: + def_obj = int(def_str) + opt_type = 'int' + except ValueError: + def_obj = def_str + opt_type = None + try: + value = self.userCfg.Get( + ext_name, opt_name, type=opt_type, raw=True, + default=def_obj) + except ValueError: # Need this until .Get fixed + value = def_obj # bad values overwritten by entry + var = StringVar(self) + var.set(str(value)) + + self.extensions[ext_name].append({'name': opt_name, + 'type': opt_type, + 'default': def_str, + 'value': value, + 'var': var, + }) + + def create_widgets(self): + """Create the dialog's widgets.""" + self.rowconfigure(0, weight=1) + self.rowconfigure(1, weight=0) + self.columnconfigure(0, weight=1) + + # create the tabbed pages + self.tabbed_page_set = TabbedPageSet( + self, page_names=self.extensions.keys(), + n_rows=None, max_tabs_per_row=5, + page_class=TabbedPageSet.PageRemove) + self.tabbed_page_set.grid(row=0, column=0, sticky=NSEW) + for ext_name in self.extensions: + self.create_tab_page(ext_name) + + self.create_action_buttons().grid(row=1) + + create_action_buttons = ConfigDialog.create_action_buttons + + def create_tab_page(self, ext_name): + """Create the page for an extension.""" + + page = LabelFrame(self.tabbed_page_set.pages[ext_name].frame, + border=2, padx=2, relief=GROOVE, + text=' %s ' % ext_name) + page.pack(fill=BOTH, expand=True, padx=12, pady=2) + + # create the scrollable frame which will contain the entries + scrolled_frame = VerticalScrolledFrame(page, pady=2, height=250) + scrolled_frame.pack(side=BOTTOM, fill=BOTH, expand=TRUE) + entry_area = scrolled_frame.interior + entry_area.columnconfigure(0, weight=0) + entry_area.columnconfigure(1, weight=1) + + # create an entry for each configuration option + for row, opt in enumerate(self.extensions[ext_name]): + # create a row with a label and entry/checkbutton + label = Label(entry_area, text=opt['name']) + label.grid(row=row, column=0, sticky=NW) + var = opt['var'] + if opt['type'] == 'bool': + Checkbutton(entry_area, textvariable=var, variable=var, + onvalue='True', offvalue='False', + indicatoron=FALSE, selectcolor='', width=8 + ).grid(row=row, column=1, sticky=W, padx=7) + elif opt['type'] == 'int': + Entry(entry_area, textvariable=var, validate='key', + validatecommand=(self.is_int, '%P') + ).grid(row=row, column=1, sticky=NSEW, padx=7) + + else: + Entry(entry_area, textvariable=var + ).grid(row=row, column=1, sticky=NSEW, padx=7) + return + + + Ok = ConfigDialog.Ok + + def Apply(self): + self.save_all_changed_configs() + pass + + Cancel = ConfigDialog.Cancel + + def Help(self): + pass + + def set_user_value(self, section, opt): + name = opt['name'] + default = opt['default'] + value = opt['var'].get().strip() or default + opt['var'].set(value) + # if self.defaultCfg.has_section(section): + # Currently, always true; if not, indent to return + if (value == default): + return self.userCfg.RemoveOption(section, name) + # set the option + return self.userCfg.SetOption(section, name, value) + + def save_all_changed_configs(self): + """Save configuration changes to the user config file.""" + has_changes = False + for ext_name in self.extensions: + options = self.extensions[ext_name] + for opt in options: + if self.set_user_value(ext_name, opt): + has_changes = True + if has_changes: + self.userCfg.Save() + + if __name__ == '__main__': - #test the dialog - root=Tk() - Button(root,text='Dialog', - command=lambda:ConfigDialog(root,'Settings')).pack() - root.instance_dict={} - root.mainloop() + import unittest + unittest.main('idlelib.idle_test.test_configdialog', + verbosity=2, exit=False) + from idlelib.idle_test.htest import run + run(ConfigDialog, ConfigExtensionsDialog) diff --git a/Lib/idlelib/configHandler.py b/Lib/idlelib/configHandler.py index ea2010edeca2..b94b8f180850 100644 --- a/Lib/idlelib/configHandler.py +++ b/Lib/idlelib/configHandler.py @@ -15,13 +15,13 @@ the retrieval of config information. When a default is returned instead of a requested config value, a message is printed to stderr to aid in configuration problem notification and resolution. - """ +# TODOs added Oct 2014, tjr + import os import sys -from idlelib import macosxSupport -from configparser import ConfigParser, NoOptionError, NoSectionError +from configparser import ConfigParser class InvalidConfigType(Exception): pass class InvalidConfigSet(Exception): pass @@ -36,7 +36,7 @@ def __init__(self, cfgFile, cfgDefaults=None): """ cfgFile - string, fully specified configuration file name """ - self.file=cfgFile + self.file = cfgFile ConfigParser.__init__(self, defaults=cfgDefaults, strict=False) def Get(self, section, option, type=None, default=None, raw=False): @@ -44,28 +44,27 @@ def Get(self, section, option, type=None, default=None, raw=False): Get an option value for given section/option or return default. If type is specified, return as type. """ + # TODO Use default as fallback, at least if not None + # Should also print Warning(file, section, option). + # Currently may raise ValueError if not self.has_option(section, option): return default - if type=='bool': + if type == 'bool': return self.getboolean(section, option) - elif type=='int': + elif type == 'int': return self.getint(section, option) else: return self.get(section, option, raw=raw) - def GetOptionList(self,section): - """ - Get an option list for given section - """ + def GetOptionList(self, section): + "Return a list of options for given section, else []." if self.has_section(section): return self.options(section) else: #return a default value return [] def Load(self): - """ - Load the configuration file from disk - """ + "Load the configuration file from disk." self.read(self.file) class IdleUserConfParser(IdleConfParser): @@ -73,61 +72,50 @@ class IdleUserConfParser(IdleConfParser): IdleConfigParser specialised for user configuration handling. """ - def AddSection(self,section): - """ - if section doesn't exist, add it - """ + def AddSection(self, section): + "If section doesn't exist, add it." if not self.has_section(section): self.add_section(section) def RemoveEmptySections(self): - """ - remove any sections that have no options - """ + "Remove any sections that have no options." for section in self.sections(): if not self.GetOptionList(section): self.remove_section(section) def IsEmpty(self): - """ - Remove empty sections and then return 1 if parser has no sections - left, else return 0. - """ + "Return True if no sections after removing empty sections." self.RemoveEmptySections() - if self.sections(): - return 0 - else: - return 1 + return not self.sections() - def RemoveOption(self,section,option): - """ - If section/option exists, remove it. - Returns 1 if option was removed, 0 otherwise. + def RemoveOption(self, section, option): + """Return True if option is removed from section, else False. + + False if either section does not exist or did not have option. """ if self.has_section(section): - return self.remove_option(section,option) + return self.remove_option(section, option) + return False - def SetOption(self,section,option,value): - """ - Sets option to value, adding section if required. - Returns 1 if option was added or changed, otherwise 0. + def SetOption(self, section, option, value): + """Return True if option is added or changed to value, else False. + + Add section if required. False means option already had value. """ - if self.has_option(section,option): - if self.get(section,option)==value: - return 0 + if self.has_option(section, option): + if self.get(section, option) == value: + return False else: - self.set(section,option,value) - return 1 + self.set(section, option, value) + return True else: if not self.has_section(section): self.add_section(section) - self.set(section,option,value) - return 1 + self.set(section, option, value) + return True def RemoveFile(self): - """ - Removes the user config file from disk if it exists. - """ + "Remove user config file self.file from disk if it exists." if os.path.exists(self.file): os.remove(self.file) @@ -151,62 +139,59 @@ def Save(self): self.RemoveFile() class IdleConf: - """ - holds config parsers for all idle config files: - default config files - (idle install dir)/config-main.def - (idle install dir)/config-extensions.def - (idle install dir)/config-highlight.def - (idle install dir)/config-keys.def - user config files - (user home dir)/.idlerc/config-main.cfg - (user home dir)/.idlerc/config-extensions.cfg - (user home dir)/.idlerc/config-highlight.cfg - (user home dir)/.idlerc/config-keys.cfg + """Hold config parsers for all idle config files in singleton instance. + + Default config files, self.defaultCfg -- + for config_type in self.config_types: + (idle install dir)/config-{config-type}.def + + User config files, self.userCfg -- + for config_type in self.config_types: + (user home dir)/.idlerc/config-{config-type}.cfg """ def __init__(self): - self.defaultCfg={} - self.userCfg={} - self.cfg={} + self.config_types = ('main', 'extensions', 'highlight', 'keys') + self.defaultCfg = {} + self.userCfg = {} + self.cfg = {} # TODO use to select userCfg vs defaultCfg self.CreateConfigHandlers() self.LoadCfgFiles() - #self.LoadCfg() + def CreateConfigHandlers(self): - """ - set up a dictionary of config parsers for default and user - configurations respectively - """ + "Populate default and user config parser dictionaries." #build idle install path if __name__ != '__main__': # we were imported idleDir=os.path.dirname(__file__) else: # we were exec'ed (for testing only) idleDir=os.path.abspath(sys.path[0]) userDir=self.GetUserCfgDir() - configTypes=('main','extensions','highlight','keys') - defCfgFiles={} - usrCfgFiles={} - for cfgType in configTypes: #build config file names - defCfgFiles[cfgType]=os.path.join(idleDir,'config-'+cfgType+'.def') - usrCfgFiles[cfgType]=os.path.join(userDir,'config-'+cfgType+'.cfg') - for cfgType in configTypes: #create config parsers - self.defaultCfg[cfgType]=IdleConfParser(defCfgFiles[cfgType]) - self.userCfg[cfgType]=IdleUserConfParser(usrCfgFiles[cfgType]) + + defCfgFiles = {} + usrCfgFiles = {} + # TODO eliminate these temporaries by combining loops + for cfgType in self.config_types: #build config file names + defCfgFiles[cfgType] = os.path.join( + idleDir, 'config-' + cfgType + '.def') + usrCfgFiles[cfgType] = os.path.join( + userDir, 'config-' + cfgType + '.cfg') + for cfgType in self.config_types: #create config parsers + self.defaultCfg[cfgType] = IdleConfParser(defCfgFiles[cfgType]) + self.userCfg[cfgType] = IdleUserConfParser(usrCfgFiles[cfgType]) def GetUserCfgDir(self): - """ - Creates (if required) and returns a filesystem directory for storing - user config files. + """Return a filesystem directory for storing user config files. + Creates it if required. """ cfgDir = '.idlerc' userDir = os.path.expanduser('~') if userDir != '~': # expanduser() found user home dir if not os.path.exists(userDir): - warn = ('\n Warning: os.path.expanduser("~") points to\n '+ - userDir+',\n but the path does not exist.\n') + warn = ('\n Warning: os.path.expanduser("~") points to\n ' + + userDir + ',\n but the path does not exist.') try: - sys.stderr.write(warn) + print(warn, file=sys.stderr) except OSError: pass userDir = '~' @@ -218,45 +203,44 @@ def GetUserCfgDir(self): try: os.mkdir(userDir) except OSError: - warn = ('\n Warning: unable to create user config directory\n'+ - userDir+'\n Check path and permissions.\n Exiting!\n\n') - sys.stderr.write(warn) + warn = ('\n Warning: unable to create user config directory\n' + + userDir + '\n Check path and permissions.\n Exiting!\n') + print(warn, file=sys.stderr) raise SystemExit + # TODO continue without userDIr instead of exit return userDir def GetOption(self, configType, section, option, default=None, type=None, warn_on_default=True, raw=False): - """ - Get an option value for given config type and given general - configuration section/option or return a default. If type is specified, - return as type. Firstly the user configuration is checked, with a - fallback to the default configuration, and a final 'catch all' - fallback to a useable passed-in default if the option isn't present in - either the user or the default configuration. - configType must be one of ('main','extensions','highlight','keys') - If a default is returned, and warn_on_default is True, a warning is - printed to stderr. + """Return a value for configType section option, or default. + + If type is not None, return a value of that type. Also pass raw + to the config parser. First try to return a valid value + (including type) from a user configuration. If that fails, try + the default configuration. If that fails, return default, with a + default of None. + Warn if either user or default configurations have an invalid value. + Warn if default is returned and warn_on_default is True. """ try: - if self.userCfg[configType].has_option(section,option): + if self.userCfg[configType].has_option(section, option): return self.userCfg[configType].Get(section, option, type=type, raw=raw) except ValueError: warning = ('\n Warning: configHandler.py - IdleConf.GetOption -\n' ' invalid %r value for configuration option %r\n' - ' from section %r: %r\n' % + ' from section %r: %r' % (type, option, section, - self.userCfg[configType].Get(section, option, - raw=raw))) + self.userCfg[configType].Get(section, option, raw=raw))) try: - sys.stderr.write(warning) + print(warning, file=sys.stderr) except OSError: pass try: if self.defaultCfg[configType].has_option(section,option): - return self.defaultCfg[configType].Get(section, option, - type=type, raw=raw) + return self.defaultCfg[configType].Get( + section, option, type=type, raw=raw) except ValueError: pass #returning default, print warning @@ -264,31 +248,28 @@ def GetOption(self, configType, section, option, default=None, type=None, warning = ('\n Warning: configHandler.py - IdleConf.GetOption -\n' ' problem retrieving configuration option %r\n' ' from section %r.\n' - ' returning default value: %r\n' % + ' returning default value: %r' % (option, section, default)) try: - sys.stderr.write(warning) + print(warning, file=sys.stderr) except OSError: pass return default def SetOption(self, configType, section, option, value): - """In user's config file, set section's option to value. - - """ + """Set section option to value in user config file.""" self.userCfg[configType].SetOption(section, option, value) def GetSectionList(self, configSet, configType): - """ - Get a list of sections from either the user or default config for - the given config type. + """Return sections for configSet configType configuration. + configSet must be either 'user' or 'default' - configType must be one of ('main','extensions','highlight','keys') + configType must be in self.config_types. """ - if not (configType in ('main','extensions','highlight','keys')): + if not (configType in self.config_types): raise InvalidConfigType('Invalid configType specified') if configSet == 'user': - cfgParser=self.userCfg[configType] + cfgParser = self.userCfg[configType] elif configSet == 'default': cfgParser=self.defaultCfg[configType] else: @@ -296,25 +277,27 @@ def GetSectionList(self, configSet, configType): return cfgParser.sections() def GetHighlight(self, theme, element, fgBg=None): - """ - return individual highlighting theme elements. - fgBg - string ('fg'or'bg') or None, if None return a dictionary - containing fg and bg colours (appropriate for passing to Tkinter in, - e.g., a tag_config call), otherwise fg or bg colour only as specified. + """Return individual theme element highlight color(s). + + fgBg - string ('fg' or 'bg') or None. + If None, return a dictionary containing fg and bg colors with + keys 'foreground' and 'background'. Otherwise, only return + fg or bg color, as specified. Colors are intended to be + appropriate for passing to Tkinter in, e.g., a tag_config call). """ if self.defaultCfg['highlight'].has_section(theme): - themeDict=self.GetThemeDict('default',theme) + themeDict = self.GetThemeDict('default', theme) else: - themeDict=self.GetThemeDict('user',theme) - fore=themeDict[element+'-foreground'] - if element=='cursor': #there is no config value for cursor bg - back=themeDict['normal-background'] + themeDict = self.GetThemeDict('user', theme) + fore = themeDict[element + '-foreground'] + if element == 'cursor': # There is no config value for cursor bg + back = themeDict['normal-background'] else: - back=themeDict[element+'-background'] - highlight={"foreground": fore,"background": back} - if not fgBg: #return dict of both colours + back = themeDict[element + '-background'] + highlight = {"foreground": fore, "background": back} + if not fgBg: # Return dict of both colors return highlight - else: #return specified colour only + else: # Return specified color only if fgBg == 'fg': return highlight["foreground"] if fgBg == 'bg': @@ -322,26 +305,26 @@ def GetHighlight(self, theme, element, fgBg=None): else: raise InvalidFgBg('Invalid fgBg specified') - def GetThemeDict(self,type,themeName): - """ + def GetThemeDict(self, type, themeName): + """Return {option:value} dict for elements in themeName. + type - string, 'default' or 'user' theme type themeName - string, theme name - Returns a dictionary which holds {option:value} for each element - in the specified theme. Values are loaded over a set of ultimate last - fallback defaults to guarantee that all theme elements are present in - a newly created theme. + Values are loaded over ultimate fallback defaults to guarantee + that all theme elements are present in a newly created theme. """ if type == 'user': - cfgParser=self.userCfg['highlight'] + cfgParser = self.userCfg['highlight'] elif type == 'default': - cfgParser=self.defaultCfg['highlight'] + cfgParser = self.defaultCfg['highlight'] else: raise InvalidTheme('Invalid theme type specified') - #foreground and background values are provded for each theme element - #(apart from cursor) even though all these values are not yet used - #by idle, to allow for their use in the future. Default values are - #generally black and white. - theme={ 'normal-foreground':'#000000', + # Provide foreground and background colors for each theme + # element (other than cursor) even though some values are not + # yet used by idle, to allow for their use in the future. + # Default values are generally black and white. + # TODO copy theme from a class attribute. + theme ={'normal-foreground':'#000000', 'normal-background':'#ffffff', 'keyword-foreground':'#000000', 'keyword-background':'#ffffff', @@ -371,52 +354,50 @@ def GetThemeDict(self,type,themeName): 'console-foreground':'#000000', 'console-background':'#ffffff' } for element in theme: - if not cfgParser.has_option(themeName,element): - #we are going to return a default, print warning - warning=('\n Warning: configHandler.py - IdleConf.GetThemeDict' + if not cfgParser.has_option(themeName, element): + # Print warning that will return a default color + warning = ('\n Warning: configHandler.IdleConf.GetThemeDict' ' -\n problem retrieving theme element %r' '\n from theme %r.\n' - ' returning default value: %r\n' % + ' returning default color: %r' % (element, themeName, theme[element])) try: - sys.stderr.write(warning) + print(warning, file=sys.stderr) except OSError: pass - colour=cfgParser.Get(themeName,element,default=theme[element]) - theme[element]=colour + theme[element] = cfgParser.Get( + themeName, element, default=theme[element]) return theme def CurrentTheme(self): - """ - Returns the name of the currently active theme - """ - return self.GetOption('main','Theme','name',default='') + "Return the name of the currently active theme." + return self.GetOption('main', 'Theme', 'name', default='') def CurrentKeys(self): - """ - Returns the name of the currently active key set - """ - return self.GetOption('main','Keys','name',default='') + "Return the name of the currently active key set." + return self.GetOption('main', 'Keys', 'name', default='') def GetExtensions(self, active_only=True, editor_only=False, shell_only=False): + """Return extensions in default and user config-extensions files. + + If active_only True, only return active (enabled) extensions + and optionally only editor or shell extensions. + If active_only False, return all extensions. """ - Gets a list of all idle extensions declared in the config files. - active_only - boolean, if true only return active (enabled) extensions - """ - extns=self.RemoveKeyBindNames( - self.GetSectionList('default','extensions')) - userExtns=self.RemoveKeyBindNames( - self.GetSectionList('user','extensions')) + extns = self.RemoveKeyBindNames( + self.GetSectionList('default', 'extensions')) + userExtns = self.RemoveKeyBindNames( + self.GetSectionList('user', 'extensions')) for extn in userExtns: if extn not in extns: #user has added own extension extns.append(extn) if active_only: - activeExtns=[] + activeExtns = [] for extn in extns: if self.GetOption('extensions', extn, 'enable', default=True, type='bool'): #the extension is enabled - if editor_only or shell_only: + if editor_only or shell_only: # TODO if both, contradictory if editor_only: option = "enable_editor" else: @@ -431,106 +412,110 @@ def GetExtensions(self, active_only=True, editor_only=False, shell_only=False): else: return extns - def RemoveKeyBindNames(self,extnNameList): - #get rid of keybinding section names - names=extnNameList - kbNameIndicies=[] + def RemoveKeyBindNames(self, extnNameList): + "Return extnNameList with keybinding section names removed." + # TODO Easier to return filtered copy with list comp + names = extnNameList + kbNameIndicies = [] for name in names: if name.endswith(('_bindings', '_cfgBindings')): kbNameIndicies.append(names.index(name)) - kbNameIndicies.sort() - kbNameIndicies.reverse() + kbNameIndicies.sort(reverse=True) for index in kbNameIndicies: #delete each keybinding section name del(names[index]) return names - def GetExtnNameForEvent(self,virtualEvent): - """ - Returns the name of the extension that virtualEvent is bound in, or - None if not bound in any extension. - virtualEvent - string, name of the virtual event to test for, without - the enclosing '<< >>' + def GetExtnNameForEvent(self, virtualEvent): + """Return the name of the extension binding virtualEvent, or None. + + virtualEvent - string, name of the virtual event to test for, + without the enclosing '<< >>' """ - extName=None - vEvent='<<'+virtualEvent+'>>' + extName = None + vEvent = '<<' + virtualEvent + '>>' for extn in self.GetExtensions(active_only=0): for event in self.GetExtensionKeys(extn): if event == vEvent: - extName=extn + extName = extn # TODO return here? return extName - def GetExtensionKeys(self,extensionName): - """ - returns a dictionary of the configurable keybindings for a particular - extension,as they exist in the dictionary returned by GetCurrentKeySet; - that is, where previously used bindings are disabled. + def GetExtensionKeys(self, extensionName): + """Return dict: {configurable extensionName event : active keybinding}. + + Events come from default config extension_cfgBindings section. + Keybindings come from GetCurrentKeySet() active key dict, + where previously used bindings are disabled. """ - keysName=extensionName+'_cfgBindings' - activeKeys=self.GetCurrentKeySet() - extKeys={} + keysName = extensionName + '_cfgBindings' + activeKeys = self.GetCurrentKeySet() + extKeys = {} if self.defaultCfg['extensions'].has_section(keysName): - eventNames=self.defaultCfg['extensions'].GetOptionList(keysName) + eventNames = self.defaultCfg['extensions'].GetOptionList(keysName) for eventName in eventNames: - event='<<'+eventName+'>>' - binding=activeKeys[event] - extKeys[event]=binding + event = '<<' + eventName + '>>' + binding = activeKeys[event] + extKeys[event] = binding return extKeys def __GetRawExtensionKeys(self,extensionName): + """Return dict {configurable extensionName event : keybinding list}. + + Events come from default config extension_cfgBindings section. + Keybindings list come from the splitting of GetOption, which + tries user config before default config. """ - returns a dictionary of the configurable keybindings for a particular - extension, as defined in the configuration files, or an empty dictionary - if no bindings are found - """ - keysName=extensionName+'_cfgBindings' - extKeys={} + keysName = extensionName+'_cfgBindings' + extKeys = {} if self.defaultCfg['extensions'].has_section(keysName): - eventNames=self.defaultCfg['extensions'].GetOptionList(keysName) + eventNames = self.defaultCfg['extensions'].GetOptionList(keysName) for eventName in eventNames: - binding=self.GetOption('extensions',keysName, - eventName,default='').split() - event='<<'+eventName+'>>' - extKeys[event]=binding + binding = self.GetOption( + 'extensions', keysName, eventName, default='').split() + event = '<<' + eventName + '>>' + extKeys[event] = binding return extKeys - def GetExtensionBindings(self,extensionName): - """ - Returns a dictionary of all the event bindings for a particular - extension. The configurable keybindings are returned as they exist in - the dictionary returned by GetCurrentKeySet; that is, where re-used - keybindings are disabled. + def GetExtensionBindings(self, extensionName): + """Return dict {extensionName event : active or defined keybinding}. + + Augment self.GetExtensionKeys(extensionName) with mapping of non- + configurable events (from default config) to GetOption splits, + as in self.__GetRawExtensionKeys. """ - bindsName=extensionName+'_bindings' - extBinds=self.GetExtensionKeys(extensionName) + bindsName = extensionName + '_bindings' + extBinds = self.GetExtensionKeys(extensionName) #add the non-configurable bindings if self.defaultCfg['extensions'].has_section(bindsName): - eventNames=self.defaultCfg['extensions'].GetOptionList(bindsName) + eventNames = self.defaultCfg['extensions'].GetOptionList(bindsName) for eventName in eventNames: - binding=self.GetOption('extensions',bindsName, - eventName,default='').split() - event='<<'+eventName+'>>' - extBinds[event]=binding + binding = self.GetOption( + 'extensions', bindsName, eventName, default='').split() + event = '<<' + eventName + '>>' + extBinds[event] = binding return extBinds def GetKeyBinding(self, keySetName, eventStr): + """Return the keybinding list for keySetName eventStr. + + keySetName - name of key binding set (config-keys section). + eventStr - virtual event, including brackets, as in '<<event>>'. """ - returns the keybinding for a specific event. - keySetName - string, name of key binding set - eventStr - string, the virtual event we want the binding for, - represented as a string, eg. '<<event>>' - """ - eventName=eventStr[2:-2] #trim off the angle brackets - binding=self.GetOption('keys',keySetName,eventName,default='').split() + eventName = eventStr[2:-2] #trim off the angle brackets + binding = self.GetOption('keys', keySetName, eventName, default='').split() return binding def GetCurrentKeySet(self): + "Return CurrentKeys with 'darwin' modifications." result = self.GetKeySet(self.CurrentKeys()) - if macosxSupport.runningAsOSXApp(): - # We're using AquaTk, replace all keybingings that use the - # Alt key by ones that use the Option key because the former - # don't work reliably. + if sys.platform == "darwin": + # OS X Tk variants do not support the "Alt" keyboard modifier. + # So replace all keybingings that use "Alt" with ones that + # use the "Option" keyboard modifier. + # TODO (Ned?): the "Option" modifier does not work properly for + # Cocoa Tk and XQuartz Tk so we should not use it + # in default OS X KeySets. for k, v in result.items(): v2 = [ x.replace('<Alt-', '<Option-') for x in v ] if v != v2: @@ -538,40 +523,43 @@ def GetCurrentKeySet(self): return result - def GetKeySet(self,keySetName): - """ - Returns a dictionary of: all requested core keybindings, plus the - keybindings for all currently active extensions. If a binding defined - in an extension is already in use, that binding is disabled. + def GetKeySet(self, keySetName): + """Return event-key dict for keySetName core plus active extensions. + + If a binding defined in an extension is already in use, the + extension binding is disabled by being set to '' """ - keySet=self.GetCoreKeys(keySetName) - activeExtns=self.GetExtensions(active_only=1) + keySet = self.GetCoreKeys(keySetName) + activeExtns = self.GetExtensions(active_only=1) for extn in activeExtns: - extKeys=self.__GetRawExtensionKeys(extn) + extKeys = self.__GetRawExtensionKeys(extn) if extKeys: #the extension defines keybindings for event in extKeys: if extKeys[event] in keySet.values(): #the binding is already in use - extKeys[event]='' #disable this binding - keySet[event]=extKeys[event] #add binding + extKeys[event] = '' #disable this binding + keySet[event] = extKeys[event] #add binding return keySet - def IsCoreBinding(self,virtualEvent): - """ - returns true if the virtual event is bound in the core idle keybindings. - virtualEvent - string, name of the virtual event to test for, without - the enclosing '<< >>' + def IsCoreBinding(self, virtualEvent): + """Return True if the virtual event is one of the core idle key events. + + virtualEvent - string, name of the virtual event to test for, + without the enclosing '<< >>' """ return ('<<'+virtualEvent+'>>') in self.GetCoreKeys() +# TODO make keyBindins a file or class attribute used for test above +# and copied in function below + def GetCoreKeys(self, keySetName=None): - """ - returns the requested set of core keybindings, with fallbacks if - required. - Keybindings loaded from the config file(s) are loaded _over_ these - defaults, so if there is a problem getting any core binding there will - be an 'ultimate last resort fallback' to the CUA-ish bindings - defined here. + """Return dict of core virtual-key keybindings for keySetName. + + The default keySetName None corresponds to the keyBindings base + dict. If keySetName is not None, bindings from the config + file(s) are loaded _over_ these defaults, so if there is a + problem getting any core binding there will be an 'ultimate last + resort fallback' to the CUA-ish bindings defined here. """ keyBindings={ '<<copy>>': ['<Control-c>', '<Control-C>'], @@ -626,23 +614,23 @@ def GetCoreKeys(self, keySetName=None): } if keySetName: for event in keyBindings: - binding=self.GetKeyBinding(keySetName,event) + binding = self.GetKeyBinding(keySetName, event) if binding: - keyBindings[event]=binding + keyBindings[event] = binding else: #we are going to return a default, print warning warning=('\n Warning: configHandler.py - IdleConf.GetCoreKeys' ' -\n problem retrieving key binding for event %r' '\n from key set %r.\n' - ' returning default value: %r\n' % + ' returning default value: %r' % (event, keySetName, keyBindings[event])) try: - sys.stderr.write(warning) + print(warning, file=sys.stderr) except OSError: pass return keyBindings - def GetExtraHelpSourceList(self,configSet): - """Fetch list of extra help sources from a given configSet. + def GetExtraHelpSourceList(self, configSet): + """Return list of extra help sources from a given configSet. Valid configSets are 'user' or 'default'. Return a list of tuples of the form (menu_item , path_to_help_file , option), or return the empty @@ -651,19 +639,19 @@ def GetExtraHelpSourceList(self,configSet): therefore the returned list must be sorted by 'option'. """ - helpSources=[] - if configSet=='user': - cfgParser=self.userCfg['main'] - elif configSet=='default': - cfgParser=self.defaultCfg['main'] + helpSources = [] + if configSet == 'user': + cfgParser = self.userCfg['main'] + elif configSet == 'default': + cfgParser = self.defaultCfg['main'] else: raise InvalidConfigSet('Invalid configSet specified') options=cfgParser.GetOptionList('HelpFiles') for option in options: - value=cfgParser.Get('HelpFiles',option,default=';') - if value.find(';')==-1: #malformed config entry with no ';' - menuItem='' #make these empty - helpPath='' #so value won't be added to list + value=cfgParser.Get('HelpFiles', option, default=';') + if value.find(';') == -1: #malformed config entry with no ';' + menuItem = '' #make these empty + helpPath = '' #so value won't be added to list else: #config entry contains ';' as expected value=value.split(';') menuItem=value[0].strip() @@ -674,47 +662,44 @@ def GetExtraHelpSourceList(self,configSet): return helpSources def GetAllExtraHelpSourcesList(self): + """Return a list of the details of all additional help sources. + + Tuples in the list are those of GetExtraHelpSourceList. """ - Returns a list of tuples containing the details of all additional help - sources configured, or an empty list if there are none. Tuples are of - the format returned by GetExtraHelpSourceList. - """ - allHelpSources=( self.GetExtraHelpSourceList('default')+ + allHelpSources = (self.GetExtraHelpSourceList('default') + self.GetExtraHelpSourceList('user') ) return allHelpSources def LoadCfgFiles(self): - """ - load all configuration files. - """ + "Load all configuration files." for key in self.defaultCfg: self.defaultCfg[key].Load() self.userCfg[key].Load() #same keys def SaveUserCfgFiles(self): - """ - write all loaded user configuration files back to disk - """ + "Write all loaded user configuration files to disk." for key in self.userCfg: self.userCfg[key].Save() -idleConf=IdleConf() +idleConf = IdleConf() + +# TODO Revise test output, write expanded unittest ### module test if __name__ == '__main__': def dumpCfg(cfg): - print('\n',cfg,'\n') + print('\n', cfg, '\n') for key in cfg: - sections=cfg[key].sections() + sections = cfg[key].sections() print(key) print(sections) for section in sections: - options=cfg[key].options(section) + options = cfg[key].options(section) print(section) print(options) for option in options: - print(option, '=', cfg[key].Get(section,option)) + print(option, '=', cfg[key].Get(section, option)) dumpCfg(idleConf.defaultCfg) dumpCfg(idleConf.userCfg) - print(idleConf.userCfg['main'].Get('Theme','name')) + print(idleConf.userCfg['main'].Get('Theme', 'name')) #print idleConf.userCfg['highlight'].GetDefHighlight('Foo','normal') diff --git a/Lib/idlelib/configHelpSourceEdit.py b/Lib/idlelib/configHelpSourceEdit.py index 2ccb40057500..242b08db56ad 100644 --- a/Lib/idlelib/configHelpSourceEdit.py +++ b/Lib/idlelib/configHelpSourceEdit.py @@ -8,13 +8,14 @@ import tkinter.filedialog as tkFileDialog class GetHelpSourceDialog(Toplevel): - def __init__(self, parent, title, menuItem='', filePath=''): + def __init__(self, parent, title, menuItem='', filePath='', _htest=False): """Get menu entry and url/ local file location for Additional Help User selects a name for the Help resource and provides a web url or a local file as its source. The user can enter a url or browse for the file. + _htest - bool, change box location when running htest """ Toplevel.__init__(self, parent) self.configure(borderwidth=5) @@ -31,12 +32,14 @@ def __init__(self, parent, title, menuItem='', filePath=''): self.withdraw() #hide while setting geometry #needs to be done here so that the winfo_reqwidth is valid self.update_idletasks() - #centre dialog over parent: - self.geometry("+%d+%d" % - ((parent.winfo_rootx() + ((parent.winfo_width()/2) - -(self.winfo_reqwidth()/2)), - parent.winfo_rooty() + ((parent.winfo_height()/2) - -(self.winfo_reqheight()/2))))) + #centre dialog over parent. below parent if running htest. + self.geometry( + "+%d+%d" % ( + parent.winfo_rootx() + + (parent.winfo_width()/2 - self.winfo_reqwidth()/2), + parent.winfo_rooty() + + ((parent.winfo_height()/2 - self.winfo_reqheight()/2) + if not _htest else 150))) self.deiconify() #geometry set, unhide self.bind('<Return>', self.Ok) self.wait_window() @@ -159,11 +162,5 @@ def Cancel(self, event=None): self.destroy() if __name__ == '__main__': - #test the dialog - root = Tk() - def run(): - keySeq = '' - dlg = GetHelpSourceDialog(root, 'Get Help Source') - print(dlg.result) - Button(root,text='Dialog', command=run).pack() - root.mainloop() + from idlelib.idle_test.htest import run + run(GetHelpSourceDialog) diff --git a/Lib/idlelib/configSectionNameDialog.py b/Lib/idlelib/configSectionNameDialog.py index b05e38e9d345..5137836981ec 100644 --- a/Lib/idlelib/configSectionNameDialog.py +++ b/Lib/idlelib/configSectionNameDialog.py @@ -8,10 +8,11 @@ import tkinter.messagebox as tkMessageBox class GetCfgSectionNameDialog(Toplevel): - def __init__(self, parent, title, message, used_names): + def __init__(self, parent, title, message, used_names, _htest=False): """ message - string, informational message to display used_names - string collection, names already in use for validity check + _htest - bool, change box location when running htest """ Toplevel.__init__(self, parent) self.configure(borderwidth=5) @@ -30,11 +31,12 @@ def __init__(self, parent, title, message, used_names): self.messageInfo.config(width=self.frameMain.winfo_reqwidth()) self.geometry( "+%d+%d" % ( - parent.winfo_rootx() + - (parent.winfo_width()/2 - self.winfo_reqwidth()/2), - parent.winfo_rooty() + - (parent.winfo_height()/2 - self.winfo_reqheight()/2) - ) ) #centre dialog over parent + parent.winfo_rootx() + + (parent.winfo_width()/2 - self.winfo_reqwidth()/2), + parent.winfo_rooty() + + ((parent.winfo_height()/2 - self.winfo_reqheight()/2) + if not _htest else 100) + ) ) #centre dialog over parent (or below htest box) self.deiconify() #geometry set, unhide self.wait_window() @@ -92,15 +94,5 @@ def Cancel(self, event=None): import unittest unittest.main('idlelib.idle_test.test_config_name', verbosity=2, exit=False) - # also human test the dialog - root = Tk() - def run(): - dlg=GetCfgSectionNameDialog(root,'Get Name', - "After the text entered with [Ok] is stripped, <nothing>, " - "'abc', or more that 30 chars are errors. " - "Close with a valid entry (printed), [Cancel], or [X]", - {'abc'}) - print(dlg.result) - Message(root, text='').pack() # will be needed for oher dialog tests - Button(root, text='Click to begin dialog test', command=run).pack() - root.mainloop() + from idlelib.idle_test.htest import run + run(GetCfgSectionNameDialog) diff --git a/Lib/idlelib/dynOptionMenuWidget.py b/Lib/idlelib/dynOptionMenuWidget.py index 922de96ceac6..515b4bafc2c4 100644 --- a/Lib/idlelib/dynOptionMenuWidget.py +++ b/Lib/idlelib/dynOptionMenuWidget.py @@ -2,16 +2,15 @@ OptionMenu widget modified to allow dynamic menu reconfiguration and setting of highlightthickness """ -from tkinter import OptionMenu -from tkinter import _setit import copy +from tkinter import OptionMenu, _setit, StringVar, Button class DynOptionMenu(OptionMenu): """ unlike OptionMenu, our kwargs can include highlightthickness """ def __init__(self, master, variable, value, *values, **kwargs): - #get a copy of kwargs before OptionMenu.__init__ munges them + # TODO copy value instead of whole dict kwargsCopy=copy.copy(kwargs) if 'highlightthickness' in list(kwargs.keys()): del(kwargs['highlightthickness']) @@ -33,3 +32,26 @@ def SetMenu(self,valueList,value=None): command=_setit(self.variable,item,self.command)) if value: self.variable.set(value) + +def _dyn_option_menu(parent): # htest # + from tkinter import Toplevel + + top = Toplevel() + top.title("Tets dynamic option menu") + top.geometry("200x100+%d+%d" % (parent.winfo_rootx() + 200, + parent.winfo_rooty() + 150)) + top.focus_set() + + var = StringVar(top) + var.set("Old option set") #Set the default value + dyn = DynOptionMenu(top,var, "old1","old2","old3","old4") + dyn.pack() + + def update(): + dyn.SetMenu(["new1","new2","new3","new4"], value="new option set") + button = Button(top, text="Change option set", command=update) + button.pack() + +if __name__ == '__main__': + from idlelib.idle_test.htest import run + run(_dyn_option_menu) diff --git a/Lib/idlelib/help.txt b/Lib/idlelib/help.txt index 6378a2e7226b..7eff37004054 100644 --- a/Lib/idlelib/help.txt +++ b/Lib/idlelib/help.txt @@ -138,7 +138,7 @@ Options Menu (Shell and Editor): window. This is not present in the Shell window only the Editor window. -Windows Menu (Shell and Editor): +Window Menu (Shell and Editor): Zoom Height -- Toggles the window between normal size (40x80 initial setting) and maximum height. The initial size is in the Configure diff --git a/Lib/idlelib/idle_test/README.txt b/Lib/idlelib/idle_test/README.txt index a8d4dcb9922a..f6b6a21ad5aa 100644 --- a/Lib/idlelib/idle_test/README.txt +++ b/Lib/idlelib/idle_test/README.txt @@ -26,7 +26,6 @@ Once test_xyy is written, the following should go at the end of xyy.py, with xyz (lowercased) added after 'test_'. --- if __name__ == "__main__": - from test import support; support.use_resources = ['gui'] import unittest unittest.main('idlelib.idle_test.test_', verbosity=2, exit=False) --- @@ -34,16 +33,17 @@ if __name__ == "__main__": 2. Gui Tests -Gui tests need 'requires' and 'use_resources' from test.support -(test.test_support in 2.7). A test is a gui test if it creates a Tk root or -master object either directly or indirectly by instantiating a tkinter or -idle class. For the benefit of buildbot machines that do not have a graphics -screen, gui tests must be 'guarded' by "requires('gui')" in a setUp -function or method. This will typically be setUpClass. - -All gui objects must be destroyed by the end of the test, perhaps in a tearDown -function. Creating the Tk root directly in a setUp allows a reference to be saved -so it can be properly destroyed in the corresponding tearDown. +Gui tests need 'requires' from test.support (test.test_support in 2.7). A +test is a gui test if it creates a Tk root or master object either directly +or indirectly by instantiating a tkinter or idle class. For the benefit of +test processes that either have no graphical environment available or are not +allowed to use it, gui tests must be 'guarded' by "requires('gui')" in a +setUp function or method. This will typically be setUpClass. + +To avoid interfering with other gui tests, all gui objects must be destroyed +and deleted by the end of the test. If a widget, such as a Tk root, is created +in a setUpX function, destroy it in the corresponding tearDownX. For module +and class attributes, also delete the widget. --- @classmethod def setUpClass(cls): @@ -53,13 +53,20 @@ so it can be properly destroyed in the corresponding tearDown. @classmethod def tearDownClass(cls): cls.root.destroy() + del cls.root --- -Support.requires('gui') returns true if it is either called in a main module -(which never happens on buildbots) or if use_resources contains 'gui'. -Use_resources is set by test.regrtest but not by unittest. So when running -tests in another module with unittest, we set it ourselves, as in the xyz.py -template above. +Support.requires('gui') causes the test(s) it guards to be skipped if any of +a few conditions are met: + - The tests are being run by regrtest.py, and it was started without + enabling the "gui" resource with the "-u" command line option. + - The tests are being run on Windows by a service that is not allowed to + interact with the graphical environment. + - The tests are being run on Mac OSX in a process that cannot make a window + manager connection. + - tkinter.Tk cannot be successfully instantiated for some reason. + - test.support.use_resources has been set by something other than + regrtest.py and does not contain "gui". Since non-gui tests always run, but gui tests only sometimes, tests of non-gui operations should best avoid needing a gui. Methods that make incidental use of @@ -86,8 +93,8 @@ python -m idlelib.idle_test.test_xyz To run all idle_test/test_*.py tests, either interactively ('>>>', with unittest imported) or from a command line, use one of the -following. (Notes: unittest does not run gui tests; in 2.7, 'test ' (with the -space) is 'test.regrtest '; where present, -v and -ugui can be omitted.) +following. (Notes: in 2.7, 'test ' (with the space) is 'test.regrtest '; +where present, -v and -ugui can be omitted.) >>> unittest.main('idlelib.idle_test', verbosity=2, exit=False) python -m unittest -v idlelib.idle_test @@ -96,13 +103,13 @@ python -m test.test_idle The idle tests are 'discovered' by idlelib.idle_test.__init__.load_tests, which is also imported into test.test_idle. Normally, neither file should be -changed when working on individual test modules. The third command runs runs +changed when working on individual test modules. The third command runs unittest indirectly through regrtest. The same happens when the entire test suite is run with 'python -m test'. So that command must work for buildbots to stay green. Idle tests must not disturb the environment in a way that makes other tests fail (issue 18081). To run an individual Testcase or test method, extend the dotted name given to -unittest on the command line. (But gui tests will not this way.) +unittest on the command line. -python -m unittest -v idlelib.idle_test.text_xyz.Test_case.test_meth +python -m unittest -v idlelib.idle_test.test_xyz.Test_case.test_meth diff --git a/Lib/idlelib/idle_test/htest.py b/Lib/idlelib/idle_test/htest.py new file mode 100644 index 000000000000..aa7f2e8f0884 --- /dev/null +++ b/Lib/idlelib/idle_test/htest.py @@ -0,0 +1,407 @@ +'''Run human tests of Idle's window, dialog, and popup widgets. + +run(*tests) +Create a master Tk window. Within that, run each callable in tests +after finding the matching test spec in this file. If tests is empty, +run an htest for each spec dict in this file after finding the matching +callable in the module named in the spec. Close the window to skip or +end the test. + +In a tested module, let X be a global name bound to a callable (class +or function) whose .__name__ attrubute is also X (the usual situation). +The first parameter of X must be 'parent'. When called, the parent +argument will be the root window. X must create a child Toplevel +window (or subclass thereof). The Toplevel may be a test widget or +dialog, in which case the callable is the corresonding class. Or the +Toplevel may contain the widget to be tested or set up a context in +which a test widget is invoked. In this latter case, the callable is a +wrapper function that sets up the Toplevel and other objects. Wrapper +function names, such as _editor_window', should start with '_'. + + +End the module with + +if __name__ == '__main__': + <unittest, if there is one> + from idlelib.idle_test.htest import run + run(X) + +To have wrapper functions and test invocation code ignored by coveragepy +reports, put '# htest #' on the def statement header line. + +def _wrapper(parent): # htest # + +Also make sure that the 'if __name__' line matches the above. Then have +make sure that .coveragerc includes the following. + +[report] +exclude_lines = + .*# htest # + if __name__ == .__main__.: + +(The "." instead of "'" is intentional and necessary.) + + +To run any X, this file must contain a matching instance of the +following template, with X.__name__ prepended to '_spec'. +When all tests are run, the prefix is use to get X. + +_spec = { + 'file': '', + 'kwds': {'title': ''}, + 'msg': "" + } + +file (no .py): run() imports file.py. +kwds: augmented with {'parent':root} and passed to X as **kwds. +title: an example kwd; some widgets need this, delete if not. +msg: master window hints about testing the widget. + + +Modules and classes not being tested at the moment: +PyShell.PyShellEditorWindow +Debugger.Debugger +AutoCompleteWindow.AutoCompleteWindow +OutputWindow.OutputWindow (indirectly being tested with grep test) +''' + +from importlib import import_module +from idlelib.macosxSupport import _initializeTkVariantTests +import tkinter as tk + +AboutDialog_spec = { + 'file': 'aboutDialog', + 'kwds': {'title': 'aboutDialog test', + '_htest': True, + }, + 'msg': "Test every button. Ensure Python, TK and IDLE versions " + "are correctly displayed.\n [Close] to exit.", + } + +_calltip_window_spec = { + 'file': 'CallTipWindow', + 'kwds': {}, + 'msg': "Typing '(' should display a calltip.\n" + "Typing ') should hide the calltip.\n" + } + +_class_browser_spec = { + 'file': 'ClassBrowser', + 'kwds': {}, + 'msg': "Inspect names of module, class(with superclass if " + "applicable), methods and functions.\nToggle nested items.\n" + "Double clicking on items prints a traceback for an exception " + "that is ignored." + } +ConfigExtensionsDialog_spec = { + 'file': 'configDialog', + 'kwds': {'title': 'Test Extension Configuration', + '_htest': True,}, + 'msg': "IDLE extensions dialog.\n" + "\n[Ok] to close the dialog.[Apply] to apply the settings and " + "and [Cancel] to revert all changes.\nRe-run the test to ensure " + "changes made have persisted." + } + +_color_delegator_spec = { + 'file': 'ColorDelegator', + 'kwds': {}, + 'msg': "The text is sample Python code.\n" + "Ensure components like comments, keywords, builtins,\n" + "string, definitions, and break are correctly colored.\n" + "The default color scheme is in idlelib/config-highlight.def" + } + +ConfigDialog_spec = { + 'file': 'configDialog', + 'kwds': {'title': 'ConfigDialogTest', + '_htest': True,}, + 'msg': "IDLE preferences dialog.\n" + "In the 'Fonts/Tabs' tab, changing font face, should update the " + "font face of the text in the area below it.\nIn the " + "'Highlighting' tab, try different color schemes. Clicking " + "items in the sample program should update the choices above it." + "\nIn the 'Keys' and 'General' tab, test settings of interest." + "\n[Ok] to close the dialog.[Apply] to apply the settings and " + "and [Cancel] to revert all changes.\nRe-run the test to ensure " + "changes made have persisted." + } + +# TODO Improve message +_dyn_option_menu_spec = { + 'file': 'dynOptionMenuWidget', + 'kwds': {}, + 'msg': "Select one of the many options in the 'old option set'.\n" + "Click the button to change the option set.\n" + "Select one of the many options in the 'new option set'." + } + +# TODO edit wrapper +_editor_window_spec = { + 'file': 'EditorWindow', + 'kwds': {}, + 'msg': "Test editor functions of interest.\n" + "Best to close editor first." + } + +GetCfgSectionNameDialog_spec = { + 'file': 'configSectionNameDialog', + 'kwds': {'title':'Get Name', + 'message':'Enter something', + 'used_names': {'abc'}, + '_htest': True}, + 'msg': "After the text entered with [Ok] is stripped, <nothing>, " + "'abc', or more that 30 chars are errors.\n" + "Close 'Get Name' with a valid entry (printed to Shell), " + "[Cancel], or [X]", + } + +GetHelpSourceDialog_spec = { + 'file': 'configHelpSourceEdit', + 'kwds': {'title': 'Get helpsource', + '_htest': True}, + 'msg': "Enter menu item name and help file path\n " + "<nothing> and more than 30 chars are invalid menu item names.\n" + "<nothing>, file does not exist are invalid path items.\n" + "Test for incomplete web address for help file path.\n" + "A valid entry will be printed to shell with [0k].\n" + "[Cancel] will print None to shell", + } + +# Update once issue21519 is resolved. +GetKeysDialog_spec = { + 'file': 'keybindingDialog', + 'kwds': {'title': 'Test keybindings', + 'action': 'find-again', + 'currentKeySequences': [''] , + '_htest': True, + }, + 'msg': "Test for different key modifier sequences.\n" + "<nothing> is invalid.\n" + "No modifier key is invalid.\n" + "Shift key with [a-z],[0-9], function key, move key, tab, space" + "is invalid.\nNo validity checking if advanced key binding " + "entry is used." + } + +_grep_dialog_spec = { + 'file': 'GrepDialog', + 'kwds': {}, + 'msg': "Click the 'Show GrepDialog' button.\n" + "Test the various 'Find-in-files' functions.\n" + "The results should be displayed in a new '*Output*' window.\n" + "'Right-click'->'Goto file/line' anywhere in the search results " + "should open that file \nin a new EditorWindow." + } + +_help_dialog_spec = { + 'file': 'EditorWindow', + 'kwds': {}, + 'msg': "If the help text displays, this works.\n" + "Text is selectable. Window is scrollable." + } + +_io_binding_spec = { + 'file': 'IOBinding', + 'kwds': {}, + 'msg': "Test the following bindings\n" + "<Control-o> to display open window from file dialog.\n" + "<Control-s> to save the file\n" + } + +_multi_call_spec = { + 'file': 'MultiCall', + 'kwds': {}, + 'msg': "The following actions should trigger a print to console or IDLE" + " Shell.\nEntering and leaving the text area, key entry, " + "<Control-Key>,\n<Alt-Key-a>, <Control-Key-a>, " + "<Alt-Control-Key-a>, \n<Control-Button-1>, <Alt-Button-1> and " + "focusing out of the window\nare sequences to be tested." + } + +_multistatus_bar_spec = { + 'file': 'MultiStatusBar', + 'kwds': {}, + 'msg': "Ensure presence of multi-status bar below text area.\n" + "Click 'Update Status' to change the multi-status text" + } + +_object_browser_spec = { + 'file': 'ObjectBrowser', + 'kwds': {}, + 'msg': "Double click on items upto the lowest level.\n" + "Attributes of the objects and related information " + "will be displayed side-by-side at each level." + } + +_path_browser_spec = { + 'file': 'PathBrowser', + 'kwds': {}, + 'msg': "Test for correct display of all paths in sys.path.\n" + "Toggle nested items upto the lowest level.\n" + "Double clicking on an item prints a traceback\n" + "for an exception that is ignored." + } + +_percolator_spec = { + 'file': 'Percolator', + 'kwds': {}, + 'msg': "There are two tracers which can be toggled using a checkbox.\n" + "Toggling a tracer 'on' by checking it should print tracer" + "output to the console or to the IDLE shell.\n" + "If both the tracers are 'on', the output from the tracer which " + "was switched 'on' later, should be printed first\n" + "Test for actions like text entry, and removal." + } + +_replace_dialog_spec = { + 'file': 'ReplaceDialog', + 'kwds': {}, + 'msg': "Click the 'Replace' button.\n" + "Test various replace options in the 'Replace dialog'.\n" + "Click [Close] or [X] to close the 'Replace Dialog'." + } + +_search_dialog_spec = { + 'file': 'SearchDialog', + 'kwds': {}, + 'msg': "Click the 'Search' button.\n" + "Test various search options in the 'Search dialog'.\n" + "Click [Close] or [X] to close the 'Search Dialog'." + } + +_scrolled_list_spec = { + 'file': 'ScrolledList', + 'kwds': {}, + 'msg': "You should see a scrollable list of items\n" + "Selecting (clicking) or double clicking an item " + "prints the name to the console or Idle shell.\n" + "Right clicking an item will display a popup." + } + +_stack_viewer_spec = { + 'file': 'StackViewer', + 'kwds': {}, + 'msg': "A stacktrace for a NameError exception.\n" + "Expand 'idlelib ...' and '<locals>'.\n" + "Check that exc_value, exc_tb, and exc_type are correct.\n" + } + +_tabbed_pages_spec = { + 'file': 'tabbedpages', + 'kwds': {}, + 'msg': "Toggle between the two tabs 'foo' and 'bar'\n" + "Add a tab by entering a suitable name for it.\n" + "Remove an existing tab by entering its name.\n" + "Remove all existing tabs.\n" + "<nothing> is an invalid add page and remove page name.\n" + } + +TextViewer_spec = { + 'file': 'textView', + 'kwds': {'title': 'Test textView', + 'text':'The quick brown fox jumps over the lazy dog.\n'*35, + '_htest': True}, + 'msg': "Test for read-only property of text.\n" + "Text is selectable. Window is scrollable.", + } + +_tooltip_spec = { + 'file': 'ToolTip', + 'kwds': {}, + 'msg': "Place mouse cursor over both the buttons\n" + "A tooltip should appear with some text." + } + +_tree_widget_spec = { + 'file': 'TreeWidget', + 'kwds': {}, + 'msg': "The canvas is scrollable.\n" + "Click on folders upto to the lowest level." + } + +_undo_delegator_spec = { + 'file': 'UndoDelegator', + 'kwds': {}, + 'msg': "Click [Undo] to undo any action.\n" + "Click [Redo] to redo any action.\n" + "Click [Dump] to dump the current state " + "by printing to the console or the IDLE shell.\n" + } + +_widget_redirector_spec = { + 'file': 'WidgetRedirector', + 'kwds': {}, + 'msg': "Every text insert should be printed to the console." + "or the IDLE shell." + } + +def run(*tests): + root = tk.Tk() + root.title('IDLE htest') + root.resizable(0, 0) + _initializeTkVariantTests(root) + + # a scrollable Label like constant width text widget. + frameLabel = tk.Frame(root, padx=10) + frameLabel.pack() + text = tk.Text(frameLabel, wrap='word') + text.configure(bg=root.cget('bg'), relief='flat', height=4, width=70) + scrollbar = tk.Scrollbar(frameLabel, command=text.yview) + text.config(yscrollcommand=scrollbar.set) + scrollbar.pack(side='right', fill='y', expand=False) + text.pack(side='left', fill='both', expand=True) + + test_list = [] # List of tuples of the form (spec, callable widget) + if tests: + for test in tests: + test_spec = globals()[test.__name__ + '_spec'] + test_spec['name'] = test.__name__ + test_list.append((test_spec, test)) + else: + for k, d in globals().items(): + if k.endswith('_spec'): + test_name = k[:-5] + test_spec = d + test_spec['name'] = test_name + mod = import_module('idlelib.' + test_spec['file']) + test = getattr(mod, test_name) + test_list.append((test_spec, test)) + + test_name = tk.StringVar('') + callable_object = None + test_kwds = None + + def next(): + + nonlocal test_name, callable_object, test_kwds + if len(test_list) == 1: + next_button.pack_forget() + test_spec, callable_object = test_list.pop() + test_kwds = test_spec['kwds'] + test_kwds['parent'] = root + test_name.set('Test ' + test_spec['name']) + + text.configure(state='normal') # enable text editing + text.delete('1.0','end') + text.insert("1.0",test_spec['msg']) + text.configure(state='disabled') # preserve read-only property + + def run_test(): + widget = callable_object(**test_kwds) + try: + print(widget.result) + except AttributeError: + pass + + button = tk.Button(root, textvariable=test_name, command=run_test) + button.pack() + next_button = tk.Button(root, text="Next", command=next) + next_button.pack() + + next() + + root.mainloop() + +if __name__ == '__main__': + run() diff --git a/Lib/idlelib/idle_test/mock_idle.py b/Lib/idlelib/idle_test/mock_idle.py index c364a24dacbf..1672a3413e78 100644 --- a/Lib/idlelib/idle_test/mock_idle.py +++ b/Lib/idlelib/idle_test/mock_idle.py @@ -5,6 +5,33 @@ from idlelib.idle_test.mock_tk import Text +class Func: + '''Mock function captures args and returns result set by test. + + Attributes: + self.called - records call even if no args, kwds passed. + self.result - set by init, returned by call. + self.args - captures positional arguments. + self.kwds - captures keyword arguments. + + Most common use will probably be to mock methods. + Mock_tk.Var and Mbox_func are special variants of this. + ''' + def __init__(self, result=None): + self.called = False + self.result = result + self.args = None + self.kwds = None + def __call__(self, *args, **kwds): + self.called = True + self.args = args + self.kwds = kwds + if isinstance(self.result, BaseException): + raise self.result + else: + return self.result + + class Editor: '''Minimally imitate EditorWindow.EditorWindow class. ''' @@ -17,6 +44,7 @@ def get_selection_indices(self): last = self.text.index('end') return first, last + class UndoDelegator: '''Minimally imitate UndoDelegator,UndoDelegator class. ''' diff --git a/Lib/idlelib/idle_test/mock_tk.py b/Lib/idlelib/idle_test/mock_tk.py index 762bbc905db9..a8030f4f5ca4 100644 --- a/Lib/idlelib/idle_test/mock_tk.py +++ b/Lib/idlelib/idle_test/mock_tk.py @@ -1,9 +1,27 @@ """Classes that replace tkinter gui objects used by an object being tested. -A gui object is anything with a master or parent paramenter, which is typically -required in spite of what the doc strings say. +A gui object is anything with a master or parent paramenter, which is +typically required in spite of what the doc strings say. """ +class Event: + '''Minimal mock with attributes for testing event handlers. + + This is not a gui object, but is used as an argument for callbacks + that access attributes of the event passed. If a callback ignores + the event, other than the fact that is happened, pass 'event'. + + Keyboard, mouse, window, and other sources generate Event instances. + Event instances have the following attributes: serial (number of + event), time (of event), type (of event as number), widget (in which + event occurred), and x,y (position of mouse). There are other + attributes for specific events, such as keycode for key events. + tkinter.Event.__doc__ has more but is still not complete. + ''' + def __init__(self, **kwds): + "Create event with attributes needed for test" + self.__dict__.update(kwds) + class Var: "Use for String/Int/BooleanVar: incomplete" def __init__(self, master=None, value=None, name=None): @@ -20,9 +38,10 @@ class Mbox_func: Instead of displaying a message box, the mock's call method saves the arguments as instance attributes, which test functions can then examime. + The test can set the result returned to ask function """ - def __init__(self): - self.result = None # The return for all show funcs + def __init__(self, result=None): + self.result = result # Return None for all show funcs def __call__(self, title, message, *args, **kwds): # Save all args for possible examination by tester self.title = title @@ -97,7 +116,7 @@ def _decode(self, index, endflag=0): """Return a (line, char) tuple of int indexes into self.data. This implements .index without converting the result back to a string. - The result is contrained by the number of lines and linelengths of + The result is constrained by the number of lines and linelengths of self.data. For many indexes, the result is initially (1, 0). The input index may have any of several possible forms: diff --git a/Lib/idlelib/idle_test/test_autocomplete.py b/Lib/idlelib/idle_test/test_autocomplete.py new file mode 100644 index 000000000000..bcc853c9f29d --- /dev/null +++ b/Lib/idlelib/idle_test/test_autocomplete.py @@ -0,0 +1,143 @@ +import unittest +from test.support import requires +from tkinter import Tk, Text, TclError + +import idlelib.AutoComplete as ac +import idlelib.AutoCompleteWindow as acw +import idlelib.macosxSupport as mac +from idlelib.idle_test.mock_idle import Func +from idlelib.idle_test.mock_tk import Event + +class AutoCompleteWindow: + def complete(): + return + +class DummyEditwin: + def __init__(self, root, text): + self.root = root + self.text = text + self.indentwidth = 8 + self.tabwidth = 8 + self.context_use_ps1 = True + + +class AutoCompleteTest(unittest.TestCase): + + @classmethod + def setUpClass(cls): + requires('gui') + cls.root = Tk() + mac.setupApp(cls.root, None) + cls.text = Text(cls.root) + cls.editor = DummyEditwin(cls.root, cls.text) + + @classmethod + def tearDownClass(cls): + cls.root.destroy() + del cls.text + del cls.editor + del cls.root + + def setUp(self): + self.editor.text.delete('1.0', 'end') + self.autocomplete = ac.AutoComplete(self.editor) + + def test_init(self): + self.assertEqual(self.autocomplete.editwin, self.editor) + + def test_make_autocomplete_window(self): + testwin = self.autocomplete._make_autocomplete_window() + self.assertIsInstance(testwin, acw.AutoCompleteWindow) + + def test_remove_autocomplete_window(self): + self.autocomplete.autocompletewindow = ( + self.autocomplete._make_autocomplete_window()) + self.autocomplete._remove_autocomplete_window() + self.assertIsNone(self.autocomplete.autocompletewindow) + + def test_force_open_completions_event(self): + # Test that force_open_completions_event calls _open_completions + o_cs = Func() + self.autocomplete.open_completions = o_cs + self.autocomplete.force_open_completions_event('event') + self.assertEqual(o_cs.args, (True, False, True)) + + def test_try_open_completions_event(self): + Equal = self.assertEqual + autocomplete = self.autocomplete + trycompletions = self.autocomplete.try_open_completions_event + o_c_l = Func() + autocomplete._open_completions_later = o_c_l + + # _open_completions_later should not be called with no text in editor + trycompletions('event') + Equal(o_c_l.args, None) + + # _open_completions_later should be called with COMPLETE_ATTRIBUTES (1) + self.text.insert('1.0', 're.') + trycompletions('event') + Equal(o_c_l.args, (False, False, False, 1)) + + # _open_completions_later should be called with COMPLETE_FILES (2) + self.text.delete('1.0', 'end') + self.text.insert('1.0', '"./Lib/') + trycompletions('event') + Equal(o_c_l.args, (False, False, False, 2)) + + def test_autocomplete_event(self): + Equal = self.assertEqual + autocomplete = self.autocomplete + + # Test that the autocomplete event is ignored if user is pressing a + # modifier key in addition to the tab key + ev = Event(mc_state=True) + self.assertIsNone(autocomplete.autocomplete_event(ev)) + del ev.mc_state + + # If autocomplete window is open, complete() method is called + testwin = self.autocomplete._make_autocomplete_window() + self.text.insert('1.0', 're.') + Equal(self.autocomplete.autocomplete_event(ev), 'break') + + # If autocomplete window is not active or does not exist, + # open_completions is called. Return depends on its return. + autocomplete._remove_autocomplete_window() + o_cs = Func() # .result = None + autocomplete.open_completions = o_cs + Equal(self.autocomplete.autocomplete_event(ev), None) + Equal(o_cs.args, (False, True, True)) + o_cs.result = True + Equal(self.autocomplete.autocomplete_event(ev), 'break') + Equal(o_cs.args, (False, True, True)) + + def test_open_completions_later(self): + # Test that autocomplete._delayed_completion_id is set + pass + + def test_delayed_open_completions(self): + # Test that autocomplete._delayed_completion_id set to None and that + # open_completions only called if insertion index is the same as + # _delayed_completion_index + pass + + def test_open_completions(self): + # Test completions of files and attributes as well as non-completion + # of errors + pass + + def test_fetch_completions(self): + # Test that fetch_completions returns 2 lists: + # For attribute completion, a large list containing all variables, and + # a small list containing non-private variables. + # For file completion, a large list containing all files in the path, + # and a small list containing files that do not start with '.' + pass + + def test_get_entity(self): + # Test that a name is in the namespace of sys.modules and + # __main__.__dict__ + pass + + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_autoexpand.py b/Lib/idlelib/idle_test/test_autoexpand.py new file mode 100644 index 000000000000..7ca941ec2902 --- /dev/null +++ b/Lib/idlelib/idle_test/test_autoexpand.py @@ -0,0 +1,141 @@ +"""Unit tests for idlelib.AutoExpand""" +import unittest +from test.support import requires +from tkinter import Text, Tk +#from idlelib.idle_test.mock_tk import Text +from idlelib.AutoExpand import AutoExpand + + +class Dummy_Editwin: + # AutoExpand.__init__ only needs .text + def __init__(self, text): + self.text = text + +class AutoExpandTest(unittest.TestCase): + + @classmethod + def setUpClass(cls): + if 'tkinter' in str(Text): + requires('gui') + cls.tk = Tk() + cls.text = Text(cls.tk) + else: + cls.text = Text() + cls.auto_expand = AutoExpand(Dummy_Editwin(cls.text)) + + @classmethod + def tearDownClass(cls): + if hasattr(cls, 'tk'): + cls.tk.destroy() + del cls.tk + del cls.text, cls.auto_expand + + def tearDown(self): + self.text.delete('1.0', 'end') + + def test_get_prevword(self): + text = self.text + previous = self.auto_expand.getprevword + equal = self.assertEqual + + equal(previous(), '') + + text.insert('insert', 't') + equal(previous(), 't') + + text.insert('insert', 'his') + equal(previous(), 'this') + + text.insert('insert', ' ') + equal(previous(), '') + + text.insert('insert', 'is') + equal(previous(), 'is') + + text.insert('insert', '\nsample\nstring') + equal(previous(), 'string') + + text.delete('3.0', 'insert') + equal(previous(), '') + + text.delete('1.0', 'end') + equal(previous(), '') + + def test_before_only(self): + previous = self.auto_expand.getprevword + expand = self.auto_expand.expand_word_event + equal = self.assertEqual + + self.text.insert('insert', 'ab ac bx ad ab a') + equal(self.auto_expand.getwords(), ['ab', 'ad', 'ac', 'a']) + expand('event') + equal(previous(), 'ab') + expand('event') + equal(previous(), 'ad') + expand('event') + equal(previous(), 'ac') + expand('event') + equal(previous(), 'a') + + def test_after_only(self): + # Also add punctuation 'noise' that should be ignored. + text = self.text + previous = self.auto_expand.getprevword + expand = self.auto_expand.expand_word_event + equal = self.assertEqual + + text.insert('insert', 'a, [ab] ac: () bx"" cd ac= ad ya') + text.mark_set('insert', '1.1') + equal(self.auto_expand.getwords(), ['ab', 'ac', 'ad', 'a']) + expand('event') + equal(previous(), 'ab') + expand('event') + equal(previous(), 'ac') + expand('event') + equal(previous(), 'ad') + expand('event') + equal(previous(), 'a') + + def test_both_before_after(self): + text = self.text + previous = self.auto_expand.getprevword + expand = self.auto_expand.expand_word_event + equal = self.assertEqual + + text.insert('insert', 'ab xy yz\n') + text.insert('insert', 'a ac by ac') + + text.mark_set('insert', '2.1') + equal(self.auto_expand.getwords(), ['ab', 'ac', 'a']) + expand('event') + equal(previous(), 'ab') + expand('event') + equal(previous(), 'ac') + expand('event') + equal(previous(), 'a') + + def test_other_expand_cases(self): + text = self.text + expand = self.auto_expand.expand_word_event + equal = self.assertEqual + + # no expansion candidate found + equal(self.auto_expand.getwords(), []) + equal(expand('event'), 'break') + + text.insert('insert', 'bx cy dz a') + equal(self.auto_expand.getwords(), []) + + # reset state by successfully expanding once + # move cursor to another position and expand again + text.insert('insert', 'ac xy a ac ad a') + text.mark_set('insert', '1.7') + expand('event') + initial_state = self.auto_expand.state + text.mark_set('insert', '1.end') + expand('event') + new_state = self.auto_expand.state + self.assertNotEqual(initial_state, new_state) + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_calltips.py b/Lib/idlelib/idle_test/test_calltips.py index ed28a21abb49..4ee15aef76bf 100644 --- a/Lib/idlelib/idle_test/test_calltips.py +++ b/Lib/idlelib/idle_test/test_calltips.py @@ -1,5 +1,166 @@ import unittest import idlelib.CallTips as ct +import textwrap +import types + +default_tip = ct._default_callable_argspec + +# Test Class TC is used in multiple get_argspec test methods +class TC(): + 'doc' + tip = "(ai=None, *b)" + def __init__(self, ai=None, *b): 'doc' + __init__.tip = "(self, ai=None, *b)" + def t1(self): 'doc' + t1.tip = "(self)" + def t2(self, ai, b=None): 'doc' + t2.tip = "(self, ai, b=None)" + def t3(self, ai, *args): 'doc' + t3.tip = "(self, ai, *args)" + def t4(self, *args): 'doc' + t4.tip = "(self, *args)" + def t5(self, ai, b=None, *args, **kw): 'doc' + t5.tip = "(self, ai, b=None, *args, **kw)" + def t6(no, self): 'doc' + t6.tip = "(no, self)" + def __call__(self, ci): 'doc' + __call__.tip = "(self, ci)" + # attaching .tip to wrapped methods does not work + @classmethod + def cm(cls, a): 'doc' + @staticmethod + def sm(b): 'doc' + +tc = TC() + +signature = ct.get_argspec # 2.7 and 3.x use different functions +class Get_signatureTest(unittest.TestCase): + # The signature function must return a string, even if blank. + # Test a variety of objects to be sure that none cause it to raise + # (quite aside from getting as correct an answer as possible). + # The tests of builtins may break if inspect or the docstrings change, + # but a red buildbot is better than a user crash (as has happened). + # For a simple mismatch, change the expected output to the actual. + + def test_builtins(self): + + # Python class that inherits builtin methods + class List(list): "List() doc" + # Simulate builtin with no docstring for default tip test + class SB: __call__ = None + + def gtest(obj, out): + self.assertEqual(signature(obj), out) + + gtest(List, List.__doc__) + gtest(list.__new__, + 'Create and return a new object. See help(type) for accurate signature.') + gtest(list.__init__, + 'Initialize self. See help(type(self)) for accurate signature.') + append_doc = "L.append(object) -> None -- append object to end" + gtest(list.append, append_doc) + gtest([].append, append_doc) + gtest(List.append, append_doc) + + gtest(types.MethodType, "method(function, instance)") + gtest(SB(), default_tip) + + def test_signature_wrap(self): + self.assertEqual(signature(textwrap.TextWrapper), '''\ +(width=70, initial_indent='', subsequent_indent='', expand_tabs=True, + replace_whitespace=True, fix_sentence_endings=False, break_long_words=True, + drop_whitespace=True, break_on_hyphens=True, tabsize=8, *, max_lines=None, + placeholder=' [...]')''') + + def test_docline_truncation(self): + def f(): pass + f.__doc__ = 'a'*300 + self.assertEqual(signature(f), '()\n' + 'a' * (ct._MAX_COLS-3) + '...') + + def test_multiline_docstring(self): + # Test fewer lines than max. + self.assertEqual(signature(list), + "list() -> new empty list\n" + "list(iterable) -> new list initialized from iterable's items") + + # Test max lines + self.assertEqual(signature(bytes), '''\ +bytes(iterable_of_ints) -> bytes +bytes(string, encoding[, errors]) -> bytes +bytes(bytes_or_buffer) -> immutable copy of bytes_or_buffer +bytes(int) -> bytes object of size given by the parameter initialized with null bytes +bytes() -> empty bytes object''') + + # Test more than max lines + def f(): pass + f.__doc__ = 'a\n' * 15 + self.assertEqual(signature(f), '()' + '\na' * ct._MAX_LINES) + + def test_functions(self): + def t1(): 'doc' + t1.tip = "()" + def t2(a, b=None): 'doc' + t2.tip = "(a, b=None)" + def t3(a, *args): 'doc' + t3.tip = "(a, *args)" + def t4(*args): 'doc' + t4.tip = "(*args)" + def t5(a, b=None, *args, **kw): 'doc' + t5.tip = "(a, b=None, *args, **kw)" + + for func in (t1, t2, t3, t4, t5, TC): + self.assertEqual(signature(func), func.tip + '\ndoc') + + def test_methods(self): + for meth in (TC.t1, TC.t2, TC.t3, TC.t4, TC.t5, TC.t6, TC.__call__): + self.assertEqual(signature(meth), meth.tip + "\ndoc") + self.assertEqual(signature(TC.cm), "(a)\ndoc") + self.assertEqual(signature(TC.sm), "(b)\ndoc") + + def test_bound_methods(self): + # test that first parameter is correctly removed from argspec + for meth, mtip in ((tc.t1, "()"), (tc.t4, "(*args)"), (tc.t6, "(self)"), + (tc.__call__, '(ci)'), (tc, '(ci)'), (TC.cm, "(a)"),): + self.assertEqual(signature(meth), mtip + "\ndoc") + + def test_starred_parameter(self): + # test that starred first parameter is *not* removed from argspec + class C: + def m1(*args): pass + def m2(**kwds): pass + c = C() + for meth, mtip in ((C.m1, '(*args)'), (c.m1, "(*args)"), + (C.m2, "(**kwds)"), (c.m2, "(**kwds)"),): + self.assertEqual(signature(meth), mtip) + + def test_non_ascii_name(self): + # test that re works to delete a first parameter name that + # includes non-ascii chars, such as various forms of A. + uni = "(A\u0391\u0410\u05d0\u0627\u0905\u1e00\u3042, a)" + assert ct._first_param.sub('', uni) == '(a)' + + def test_no_docstring(self): + def nd(s): + pass + TC.nd = nd + self.assertEqual(signature(nd), "(s)") + self.assertEqual(signature(TC.nd), "(s)") + self.assertEqual(signature(tc.nd), "()") + + def test_attribute_exception(self): + class NoCall: + def __getattr__(self, name): + raise BaseException + class Call(NoCall): + def __call__(self, ci): + pass + for meth, mtip in ((NoCall, default_tip), (Call, default_tip), + (NoCall(), ''), (Call(), '(ci)')): + self.assertEqual(signature(meth), mtip) + + def test_non_callables(self): + for obj in (0, 0.0, '0', b'0', [], {}): + self.assertEqual(signature(obj), '') class Get_entityTest(unittest.TestCase): def test_bad_entity(self): diff --git a/Lib/idlelib/idle_test/test_configdialog.py b/Lib/idlelib/idle_test/test_configdialog.py new file mode 100644 index 000000000000..68831236b76b --- /dev/null +++ b/Lib/idlelib/idle_test/test_configdialog.py @@ -0,0 +1,32 @@ +'''Unittests for idlelib/configHandler.py + +Coverage: 46% just by creating dialog. The other half is change code. + +''' +import unittest +from test.support import requires +from tkinter import Tk +from idlelib.configDialog import ConfigDialog +from idlelib.macosxSupport import _initializeTkVariantTests + + +class ConfigDialogTest(unittest.TestCase): + + @classmethod + def setUpClass(cls): + requires('gui') + cls.root = Tk() + _initializeTkVariantTests(cls.root) + + @classmethod + def tearDownClass(cls): + cls.root.destroy() + del cls.root + + def test_dialog(self): + d=ConfigDialog(self.root, 'Test', _utest=True) + d.destroy() + + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_formatparagraph.py b/Lib/idlelib/idle_test/test_formatparagraph.py index 818c9d4b674b..690c9361454e 100644 --- a/Lib/idlelib/idle_test/test_formatparagraph.py +++ b/Lib/idlelib/idle_test/test_formatparagraph.py @@ -277,6 +277,9 @@ def setUpClass(cls): @classmethod def tearDownClass(cls): cls.root.destroy() + del cls.root + del cls.text + del cls.formatter def test_short_line(self): self.text.insert('1.0', "Short line\n") @@ -290,7 +293,7 @@ def test_long_line(self): # Set cursor ('insert' mark) to '1.0', within text. text.insert('1.0', self.test_string) text.mark_set('insert', '1.0') - self.formatter('ParameterDoesNothing') + self.formatter('ParameterDoesNothing', limit=70) result = text.get('1.0', 'insert') # find function includes \n expected = ( @@ -302,7 +305,7 @@ def test_long_line(self): # Select from 1.11 to line end. text.insert('1.0', self.test_string) text.tag_add('sel', '1.11', '1.end') - self.formatter('ParameterDoesNothing') + self.formatter('ParameterDoesNothing', limit=70) result = text.get('1.0', 'insert') # selection excludes \n expected = ( @@ -316,7 +319,7 @@ def test_multiple_lines(self): # Select 2 long lines. text.insert('1.0', self.multiline_test_string) text.tag_add('sel', '2.0', '4.0') - self.formatter('ParameterDoesNothing') + self.formatter('ParameterDoesNothing', limit=70) result = text.get('2.0', 'insert') expected = ( " The second line's length is way over the max width. It goes on and\n" @@ -331,7 +334,7 @@ def test_comment_block(self): # Set cursor ('insert') to '1.0', within block. text.insert('1.0', self.multiline_test_comment) - self.formatter('ParameterDoesNothing') + self.formatter('ParameterDoesNothing', limit=70) result = text.get('1.0', 'insert') expected = ( "# The first line is under the max width. The second line's length is\n" @@ -345,7 +348,7 @@ def test_comment_block(self): # Select line 2, verify line 1 unaffected. text.insert('1.0', self.multiline_test_comment) text.tag_add('sel', '2.0', '3.0') - self.formatter('ParameterDoesNothing') + self.formatter('ParameterDoesNothing', limit=70) result = text.get('1.0', 'insert') expected = ( "# The first line is under the max width.\n" diff --git a/Lib/idlelib/idle_test/test_hyperparser.py b/Lib/idlelib/idle_test/test_hyperparser.py new file mode 100644 index 000000000000..edfc783fe8da --- /dev/null +++ b/Lib/idlelib/idle_test/test_hyperparser.py @@ -0,0 +1,273 @@ +"""Unittest for idlelib.HyperParser""" +import unittest +from test.support import requires +from tkinter import Tk, Text +from idlelib.EditorWindow import EditorWindow +from idlelib.HyperParser import HyperParser + +class DummyEditwin: + def __init__(self, text): + self.text = text + self.indentwidth = 8 + self.tabwidth = 8 + self.context_use_ps1 = True + self.num_context_lines = 50, 500, 1000 + + _build_char_in_string_func = EditorWindow._build_char_in_string_func + is_char_in_string = EditorWindow.is_char_in_string + + +class HyperParserTest(unittest.TestCase): + code = ( + '"""This is a module docstring"""\n' + '# this line is a comment\n' + 'x = "this is a string"\n' + "y = 'this is also a string'\n" + 'l = [i for i in range(10)]\n' + 'm = [py*py for # comment\n' + ' py in l]\n' + 'x.__len__\n' + "z = ((r'asdf')+('a')))\n" + '[x for x in\n' + 'for = False\n' + 'cliché = "this is a string with unicode, what a cliché"' + ) + + @classmethod + def setUpClass(cls): + requires('gui') + cls.root = Tk() + cls.text = Text(cls.root) + cls.editwin = DummyEditwin(cls.text) + + @classmethod + def tearDownClass(cls): + del cls.text, cls.editwin + cls.root.destroy() + del cls.root + + def setUp(self): + self.text.insert('insert', self.code) + + def tearDown(self): + self.text.delete('1.0', 'end') + self.editwin.context_use_ps1 = True + + def get_parser(self, index): + """ + Return a parser object with index at 'index' + """ + return HyperParser(self.editwin, index) + + def test_init(self): + """ + test corner cases in the init method + """ + with self.assertRaises(ValueError) as ve: + self.text.tag_add('console', '1.0', '1.end') + p = self.get_parser('1.5') + self.assertIn('precedes', str(ve.exception)) + + # test without ps1 + self.editwin.context_use_ps1 = False + + # number of lines lesser than 50 + p = self.get_parser('end') + self.assertEqual(p.rawtext, self.text.get('1.0', 'end')) + + # number of lines greater than 50 + self.text.insert('end', self.text.get('1.0', 'end')*4) + p = self.get_parser('54.5') + + def test_is_in_string(self): + get = self.get_parser + + p = get('1.0') + self.assertFalse(p.is_in_string()) + p = get('1.4') + self.assertTrue(p.is_in_string()) + p = get('2.3') + self.assertFalse(p.is_in_string()) + p = get('3.3') + self.assertFalse(p.is_in_string()) + p = get('3.7') + self.assertTrue(p.is_in_string()) + p = get('4.6') + self.assertTrue(p.is_in_string()) + p = get('12.54') + self.assertTrue(p.is_in_string()) + + def test_is_in_code(self): + get = self.get_parser + + p = get('1.0') + self.assertTrue(p.is_in_code()) + p = get('1.1') + self.assertFalse(p.is_in_code()) + p = get('2.5') + self.assertFalse(p.is_in_code()) + p = get('3.4') + self.assertTrue(p.is_in_code()) + p = get('3.6') + self.assertFalse(p.is_in_code()) + p = get('4.14') + self.assertFalse(p.is_in_code()) + + def test_get_surrounding_bracket(self): + get = self.get_parser + + def without_mustclose(parser): + # a utility function to get surrounding bracket + # with mustclose=False + return parser.get_surrounding_brackets(mustclose=False) + + def with_mustclose(parser): + # a utility function to get surrounding bracket + # with mustclose=True + return parser.get_surrounding_brackets(mustclose=True) + + p = get('3.2') + self.assertIsNone(with_mustclose(p)) + self.assertIsNone(without_mustclose(p)) + + p = get('5.6') + self.assertTupleEqual(without_mustclose(p), ('5.4', '5.25')) + self.assertTupleEqual(without_mustclose(p), with_mustclose(p)) + + p = get('5.23') + self.assertTupleEqual(without_mustclose(p), ('5.21', '5.24')) + self.assertTupleEqual(without_mustclose(p), with_mustclose(p)) + + p = get('6.15') + self.assertTupleEqual(without_mustclose(p), ('6.4', '6.end')) + self.assertIsNone(with_mustclose(p)) + + p = get('9.end') + self.assertIsNone(with_mustclose(p)) + self.assertIsNone(without_mustclose(p)) + + def test_get_expression(self): + get = self.get_parser + + p = get('4.2') + self.assertEqual(p.get_expression(), 'y ') + + p = get('4.7') + with self.assertRaises(ValueError) as ve: + p.get_expression() + self.assertIn('is inside a code', str(ve.exception)) + + p = get('5.25') + self.assertEqual(p.get_expression(), 'range(10)') + + p = get('6.7') + self.assertEqual(p.get_expression(), 'py') + + p = get('6.8') + self.assertEqual(p.get_expression(), '') + + p = get('7.9') + self.assertEqual(p.get_expression(), 'py') + + p = get('8.end') + self.assertEqual(p.get_expression(), 'x.__len__') + + p = get('9.13') + self.assertEqual(p.get_expression(), "r'asdf'") + + p = get('9.17') + with self.assertRaises(ValueError) as ve: + p.get_expression() + self.assertIn('is inside a code', str(ve.exception)) + + p = get('10.0') + self.assertEqual(p.get_expression(), '') + + p = get('10.6') + self.assertEqual(p.get_expression(), '') + + p = get('10.11') + self.assertEqual(p.get_expression(), '') + + p = get('11.3') + self.assertEqual(p.get_expression(), '') + + p = get('11.11') + self.assertEqual(p.get_expression(), 'False') + + p = get('12.6') + self.assertEqual(p.get_expression(), 'cliché') + + def test_eat_identifier(self): + def is_valid_id(candidate): + result = HyperParser._eat_identifier(candidate, 0, len(candidate)) + if result == len(candidate): + return True + elif result == 0: + return False + else: + err_msg = "Unexpected result: {} (expected 0 or {}".format( + result, len(candidate) + ) + raise Exception(err_msg) + + # invalid first character which is valid elsewhere in an identifier + self.assertFalse(is_valid_id('2notid')) + + # ASCII-only valid identifiers + self.assertTrue(is_valid_id('valid_id')) + self.assertTrue(is_valid_id('_valid_id')) + self.assertTrue(is_valid_id('valid_id_')) + self.assertTrue(is_valid_id('_2valid_id')) + + # keywords which should be "eaten" + self.assertTrue(is_valid_id('True')) + self.assertTrue(is_valid_id('False')) + self.assertTrue(is_valid_id('None')) + + # keywords which should not be "eaten" + self.assertFalse(is_valid_id('for')) + self.assertFalse(is_valid_id('import')) + self.assertFalse(is_valid_id('return')) + + # valid unicode identifiers + self.assertTrue(is_valid_id('cliche')) + self.assertTrue(is_valid_id('cliché')) + self.assertTrue(is_valid_id('a٢')) + + # invalid unicode identifiers + self.assertFalse(is_valid_id('2a')) + self.assertFalse(is_valid_id('٢a')) + self.assertFalse(is_valid_id('a²')) + + # valid identifier after "punctuation" + self.assertEqual(HyperParser._eat_identifier('+ var', 0, 5), len('var')) + self.assertEqual(HyperParser._eat_identifier('+var', 0, 4), len('var')) + self.assertEqual(HyperParser._eat_identifier('.var', 0, 4), len('var')) + + # invalid identifiers + self.assertFalse(is_valid_id('+')) + self.assertFalse(is_valid_id(' ')) + self.assertFalse(is_valid_id(':')) + self.assertFalse(is_valid_id('?')) + self.assertFalse(is_valid_id('^')) + self.assertFalse(is_valid_id('\\')) + self.assertFalse(is_valid_id('"')) + self.assertFalse(is_valid_id('"a string"')) + + def test_eat_identifier_various_lengths(self): + eat_id = HyperParser._eat_identifier + + for length in range(1, 21): + self.assertEqual(eat_id('a' * length, 0, length), length) + self.assertEqual(eat_id('é' * length, 0, length), length) + self.assertEqual(eat_id('a' + '2' * (length - 1), 0, length), length) + self.assertEqual(eat_id('é' + '2' * (length - 1), 0, length), length) + self.assertEqual(eat_id('é' + 'a' * (length - 1), 0, length), length) + self.assertEqual(eat_id('é' * (length - 1) + 'a', 0, length), length) + self.assertEqual(eat_id('+' * length, 0, length), 0) + self.assertEqual(eat_id('2' + 'a' * (length - 1), 0, length), 0) + self.assertEqual(eat_id('2' + 'é' * (length - 1), 0, length), 0) + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_idlehistory.py b/Lib/idlelib/idle_test/test_idlehistory.py index b27db9191d0b..d7c3d7039388 100644 --- a/Lib/idlelib/idle_test/test_idlehistory.py +++ b/Lib/idlelib/idle_test/test_idlehistory.py @@ -80,6 +80,7 @@ def setUp(self): @classmethod def tearDownClass(cls): cls.root.destroy() + del cls.root def fetch_test(self, reverse, line, prefix, index, *, bell=False): # Perform one fetch as invoked by Alt-N or Alt-P diff --git a/Lib/idlelib/idle_test/test_parenmatch.py b/Lib/idlelib/idle_test/test_parenmatch.py new file mode 100644 index 000000000000..9aba4bec9366 --- /dev/null +++ b/Lib/idlelib/idle_test/test_parenmatch.py @@ -0,0 +1,109 @@ +"""Test idlelib.ParenMatch.""" +# This must currently be a gui test because ParenMatch methods use +# several text methods not defined on idlelib.idle_test.mock_tk.Text. + +import unittest +from unittest.mock import Mock +from test.support import requires +from tkinter import Tk, Text +from idlelib.ParenMatch import ParenMatch + +class DummyEditwin: + def __init__(self, text): + self.text = text + self.indentwidth = 8 + self.tabwidth = 8 + self.context_use_ps1 = True + + +class ParenMatchTest(unittest.TestCase): + + @classmethod + def setUpClass(cls): + requires('gui') + cls.root = Tk() + cls.text = Text(cls.root) + cls.editwin = DummyEditwin(cls.text) + cls.editwin.text_frame = Mock() + + @classmethod + def tearDownClass(cls): + del cls.text, cls.editwin + cls.root.destroy() + del cls.root + + def tearDown(self): + self.text.delete('1.0', 'end') + + def test_paren_expression(self): + """ + Test ParenMatch with 'expression' style. + """ + text = self.text + pm = ParenMatch(self.editwin) + pm.set_style('expression') + + text.insert('insert', 'def foobar(a, b') + pm.flash_paren_event('event') + self.assertIn('<<parenmatch-check-restore>>', text.event_info()) + self.assertTupleEqual(text.tag_prevrange('paren', 'end'), + ('1.10', '1.15')) + text.insert('insert', ')') + pm.restore_event() + self.assertNotIn('<<parenmatch-check-restore>>', text.event_info()) + self.assertEqual(text.tag_prevrange('paren', 'end'), ()) + + # paren_closed_event can only be tested as below + pm.paren_closed_event('event') + self.assertTupleEqual(text.tag_prevrange('paren', 'end'), + ('1.10', '1.16')) + + def test_paren_default(self): + """ + Test ParenMatch with 'default' style. + """ + text = self.text + pm = ParenMatch(self.editwin) + pm.set_style('default') + + text.insert('insert', 'def foobar(a, b') + pm.flash_paren_event('event') + self.assertIn('<<parenmatch-check-restore>>', text.event_info()) + self.assertTupleEqual(text.tag_prevrange('paren', 'end'), + ('1.10', '1.11')) + text.insert('insert', ')') + pm.restore_event() + self.assertNotIn('<<parenmatch-check-restore>>', text.event_info()) + self.assertEqual(text.tag_prevrange('paren', 'end'), ()) + + def test_paren_corner(self): + """ + Test corner cases in flash_paren_event and paren_closed_event. + + These cases force conditional expression and alternate paths. + """ + text = self.text + pm = ParenMatch(self.editwin) + + text.insert('insert', '# this is a commen)') + self.assertIsNone(pm.paren_closed_event('event')) + + text.insert('insert', '\ndef') + self.assertIsNone(pm.flash_paren_event('event')) + self.assertIsNone(pm.paren_closed_event('event')) + + text.insert('insert', ' a, *arg)') + self.assertIsNone(pm.paren_closed_event('event')) + + def test_handle_restore_timer(self): + pm = ParenMatch(self.editwin) + pm.restore_event = Mock() + pm.handle_restore_timer(0) + self.assertTrue(pm.restore_event.called) + pm.restore_event.reset_mock() + pm.handle_restore_timer(1) + self.assertFalse(pm.restore_event.called) + + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_searchdialogbase.py b/Lib/idlelib/idle_test/test_searchdialogbase.py new file mode 100644 index 000000000000..eccdd47d292d --- /dev/null +++ b/Lib/idlelib/idle_test/test_searchdialogbase.py @@ -0,0 +1,165 @@ +'''Unittests for idlelib/SearchDialogBase.py + +Coverage: 99%. The only thing not covered is inconsequential -- +testing skipping of suite when self.needwrapbutton is false. + +''' +import unittest +from test.support import requires +from tkinter import Tk, Toplevel, Frame, Label, BooleanVar, StringVar +from idlelib import SearchEngine as se +from idlelib import SearchDialogBase as sdb +from idlelib.idle_test.mock_idle import Func +from idlelib.idle_test.mock_tk import Var, Mbox + +# The following could help make some tests gui-free. +# However, they currently make radiobutton tests fail. +##def setUpModule(): +## # Replace tk objects used to initialize se.SearchEngine. +## se.BooleanVar = Var +## se.StringVar = Var +## +##def tearDownModule(): +## se.BooleanVar = BooleanVar +## se.StringVar = StringVar + +class SearchDialogBaseTest(unittest.TestCase): + + @classmethod + def setUpClass(cls): + requires('gui') + cls.root = Tk() + + @classmethod + def tearDownClass(cls): + cls.root.destroy() + del cls.root + + def setUp(self): + self.engine = se.SearchEngine(self.root) # None also seems to work + self.dialog = sdb.SearchDialogBase(root=self.root, engine=self.engine) + + def tearDown(self): + self.dialog.close() + + def test_open_and_close(self): + # open calls create_widgets, which needs default_command + self.dialog.default_command = None + + # Since text parameter of .open is not used in base class, + # pass dummy 'text' instead of tk.Text(). + self.dialog.open('text') + self.assertEqual(self.dialog.top.state(), 'normal') + self.dialog.close() + self.assertEqual(self.dialog.top.state(), 'withdrawn') + + self.dialog.open('text', searchphrase="hello") + self.assertEqual(self.dialog.ent.get(), 'hello') + self.dialog.close() + + def test_create_widgets(self): + self.dialog.create_entries = Func() + self.dialog.create_option_buttons = Func() + self.dialog.create_other_buttons = Func() + self.dialog.create_command_buttons = Func() + + self.dialog.default_command = None + self.dialog.create_widgets() + + self.assertTrue(self.dialog.create_entries.called) + self.assertTrue(self.dialog.create_option_buttons.called) + self.assertTrue(self.dialog.create_other_buttons.called) + self.assertTrue(self.dialog.create_command_buttons.called) + + def test_make_entry(self): + equal = self.assertEqual + self.dialog.row = 0 + self.dialog.top = Toplevel(self.root) + entry, label = self.dialog.make_entry("Test:", 'hello') + equal(label['text'], 'Test:') + + self.assertIn(entry.get(), 'hello') + egi = entry.grid_info() + equal(int(egi['row']), 0) + equal(int(egi['column']), 1) + equal(int(egi['rowspan']), 1) + equal(int(egi['columnspan']), 1) + equal(self.dialog.row, 1) + + def test_create_entries(self): + self.dialog.row = 0 + self.engine.setpat('hello') + self.dialog.create_entries() + self.assertIn(self.dialog.ent.get(), 'hello') + + def test_make_frame(self): + self.dialog.row = 0 + self.dialog.top = Toplevel(self.root) + frame, label = self.dialog.make_frame() + self.assertEqual(label, '') + self.assertIsInstance(frame, Frame) + + frame, label = self.dialog.make_frame('testlabel') + self.assertEqual(label['text'], 'testlabel') + self.assertIsInstance(frame, Frame) + + def btn_test_setup(self, meth): + self.dialog.top = Toplevel(self.root) + self.dialog.row = 0 + return meth() + + def test_create_option_buttons(self): + e = self.engine + for state in (0, 1): + for var in (e.revar, e.casevar, e.wordvar, e.wrapvar): + var.set(state) + frame, options = self.btn_test_setup( + self.dialog.create_option_buttons) + for spec, button in zip (options, frame.pack_slaves()): + var, label = spec + self.assertEqual(button['text'], label) + self.assertEqual(var.get(), state) + if state == 1: + button.deselect() + else: + button.select() + self.assertEqual(var.get(), 1 - state) + + def test_create_other_buttons(self): + for state in (False, True): + var = self.engine.backvar + var.set(state) + frame, others = self.btn_test_setup( + self.dialog.create_other_buttons) + buttons = frame.pack_slaves() + for spec, button in zip(others, buttons): + val, label = spec + self.assertEqual(button['text'], label) + if val == state: + # hit other button, then this one + # indexes depend on button order + self.assertEqual(var.get(), state) + buttons[val].select() + self.assertEqual(var.get(), 1 - state) + buttons[1-val].select() + self.assertEqual(var.get(), state) + + def test_make_button(self): + self.dialog.top = Toplevel(self.root) + self.dialog.buttonframe = Frame(self.dialog.top) + btn = self.dialog.make_button('Test', self.dialog.close) + self.assertEqual(btn['text'], 'Test') + + def test_create_command_buttons(self): + self.dialog.create_command_buttons() + # Look for close button command in buttonframe + closebuttoncommand = '' + for child in self.dialog.buttonframe.winfo_children(): + if child['text'] == 'close': + closebuttoncommand = child['command'] + self.assertIn('close', closebuttoncommand) + + + +if __name__ == '__main__': + unittest.main(verbosity=2, exit=2) diff --git a/Lib/idlelib/idle_test/test_searchengine.py b/Lib/idlelib/idle_test/test_searchengine.py index fdf38bd0ba2a..2c104611b4c1 100644 --- a/Lib/idlelib/idle_test/test_searchengine.py +++ b/Lib/idlelib/idle_test/test_searchengine.py @@ -64,6 +64,7 @@ class GetSelectionTest(unittest.TestCase): ## @classmethod ## def tearDownClass(cls): ## cls.root.destroy() +## del cls.root def test_get_selection(self): # text = Text(master=self.root) @@ -177,7 +178,7 @@ def test_getprog(self): engine.revar.set(1) Equal(engine.getprog(), None) self.assertEqual(Mbox.showerror.message, - 'Error: nothing to repeat\nPattern: +') + 'Error: nothing to repeat at position 0\nPattern: +') def test_report_error(self): showerror = Mbox.showerror @@ -219,6 +220,7 @@ def setUpClass(cls): ## @classmethod ## def tearDownClass(cls): ## cls.root.destroy() +## del cls.root def test_search(self): Equal = self.assertEqual @@ -261,6 +263,7 @@ class ForwardBackwardTest(unittest.TestCase): ## @classmethod ## def tearDownClass(cls): ## cls.root.destroy() +## del cls.root @classmethod def setUpClass(cls): diff --git a/Lib/idlelib/idle_test/test_text.py b/Lib/idlelib/idle_test/test_text.py index 367bf3849863..5ac2fd74e3e9 100644 --- a/Lib/idlelib/idle_test/test_text.py +++ b/Lib/idlelib/idle_test/test_text.py @@ -221,6 +221,7 @@ def setUpClass(cls): @classmethod def tearDownClass(cls): cls.root.destroy() + del cls.root if __name__ == '__main__': diff --git a/Lib/idlelib/idle_test/test_textview.py b/Lib/idlelib/idle_test/test_textview.py new file mode 100644 index 000000000000..68e5b82ad912 --- /dev/null +++ b/Lib/idlelib/idle_test/test_textview.py @@ -0,0 +1,97 @@ +'''Test the functions and main class method of textView.py. + +Since all methods and functions create (or destroy) a TextViewer, which +is a widget containing multiple widgets, all tests must be gui tests. +Using mock Text would not change this. Other mocks are used to retrieve +information about calls. + +The coverage is essentially 100%. +''' +from test.support import requires +requires('gui') + +import unittest +import os +from tkinter import Tk +from idlelib import textView as tv +from idlelib.idle_test.mock_idle import Func +from idlelib.idle_test.mock_tk import Mbox + +def setUpModule(): + global root + root = Tk() + +def tearDownModule(): + global root + root.destroy() # pyflakes falsely sees root as undefined + del root + + +class TV(tv.TextViewer): # used by TextViewTest + transient = Func() + grab_set = Func() + wait_window = Func() + +class TextViewTest(unittest.TestCase): + + def setUp(self): + TV.transient.__init__() + TV.grab_set.__init__() + TV.wait_window.__init__() + + def test_init_modal(self): + view = TV(root, 'Title', 'test text') + self.assertTrue(TV.transient.called) + self.assertTrue(TV.grab_set.called) + self.assertTrue(TV.wait_window.called) + view.Ok() + + def test_init_nonmodal(self): + view = TV(root, 'Title', 'test text', modal=False) + self.assertFalse(TV.transient.called) + self.assertFalse(TV.grab_set.called) + self.assertFalse(TV.wait_window.called) + view.Ok() + + def test_ok(self): + view = TV(root, 'Title', 'test text', modal=False) + view.destroy = Func() + view.Ok() + self.assertTrue(view.destroy.called) + del view.destroy # unmask real function + view.destroy + + +class textviewTest(unittest.TestCase): + + @classmethod + def setUpClass(cls): + cls.orig_mbox = tv.tkMessageBox + tv.tkMessageBox = Mbox + + @classmethod + def tearDownClass(cls): + tv.tkMessageBox = cls.orig_mbox + del cls.orig_mbox + + def test_view_text(self): + # If modal True, tkinter will error with 'can't invoke "event" command' + view = tv.view_text(root, 'Title', 'test text', modal=False) + self.assertIsInstance(view, tv.TextViewer) + + def test_view_file(self): + test_dir = os.path.dirname(__file__) + testfile = os.path.join(test_dir, 'test_textview.py') + view = tv.view_file(root, 'Title', testfile, modal=False) + self.assertIsInstance(view, tv.TextViewer) + self.assertIn('Test', view.textView.get('1.0', '1.end')) + view.Ok() + + # Mock messagebox will be used and view_file will not return anything + testfile = os.path.join(test_dir, '../notthere.py') + view = tv.view_file(root, 'Title', testfile, modal=False) + self.assertIsNone(view) + + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_widgetredir.py b/Lib/idlelib/idle_test/test_widgetredir.py new file mode 100644 index 000000000000..64405615a0c9 --- /dev/null +++ b/Lib/idlelib/idle_test/test_widgetredir.py @@ -0,0 +1,122 @@ +"""Unittest for idlelib.WidgetRedirector + +100% coverage +""" +from test.support import requires +import unittest +from idlelib.idle_test.mock_idle import Func +from tkinter import Tk, Text, TclError +from idlelib.WidgetRedirector import WidgetRedirector + + +class InitCloseTest(unittest.TestCase): + + @classmethod + def setUpClass(cls): + requires('gui') + cls.tk = Tk() + cls.text = Text(cls.tk) + + @classmethod + def tearDownClass(cls): + cls.text.destroy() + cls.tk.destroy() + del cls.text, cls.tk + + def test_init(self): + redir = WidgetRedirector(self.text) + self.assertEqual(redir.widget, self.text) + self.assertEqual(redir.tk, self.text.tk) + self.assertRaises(TclError, WidgetRedirector, self.text) + redir.close() # restore self.tk, self.text + + def test_close(self): + redir = WidgetRedirector(self.text) + redir.register('insert', Func) + redir.close() + self.assertEqual(redir._operations, {}) + self.assertFalse(hasattr(self.text, 'widget')) + + +class WidgetRedirectorTest(unittest.TestCase): + + @classmethod + def setUpClass(cls): + requires('gui') + cls.tk = Tk() + cls.text = Text(cls.tk) + + @classmethod + def tearDownClass(cls): + cls.text.destroy() + cls.tk.destroy() + del cls.text, cls.tk + + def setUp(self): + self.redir = WidgetRedirector(self.text) + self.func = Func() + self.orig_insert = self.redir.register('insert', self.func) + self.text.insert('insert', 'asdf') # leaves self.text empty + + def tearDown(self): + self.text.delete('1.0', 'end') + self.redir.close() + + def test_repr(self): # partly for 100% coverage + self.assertIn('Redirector', repr(self.redir)) + self.assertIn('Original', repr(self.orig_insert)) + + def test_register(self): + self.assertEqual(self.text.get('1.0', 'end'), '\n') + self.assertEqual(self.func.args, ('insert', 'asdf')) + self.assertIn('insert', self.redir._operations) + self.assertIn('insert', self.text.__dict__) + self.assertEqual(self.text.insert, self.func) + + def test_original_command(self): + self.assertEqual(self.orig_insert.operation, 'insert') + self.assertEqual(self.orig_insert.tk_call, self.text.tk.call) + self.orig_insert('insert', 'asdf') + self.assertEqual(self.text.get('1.0', 'end'), 'asdf\n') + + def test_unregister(self): + self.assertIsNone(self.redir.unregister('invalid operation name')) + self.assertEqual(self.redir.unregister('insert'), self.func) + self.assertNotIn('insert', self.redir._operations) + self.assertNotIn('insert', self.text.__dict__) + + def test_unregister_no_attribute(self): + del self.text.insert + self.assertEqual(self.redir.unregister('insert'), self.func) + + def test_dispatch_intercept(self): + self.func.__init__(True) + self.assertTrue(self.redir.dispatch('insert', False)) + self.assertFalse(self.func.args[0]) + + def test_dispatch_bypass(self): + self.orig_insert('insert', 'asdf') + # tk.call returns '' where Python would return None + self.assertEqual(self.redir.dispatch('delete', '1.0', 'end'), '') + self.assertEqual(self.text.get('1.0', 'end'), '\n') + + def test_dispatch_error(self): + self.func.__init__(TclError()) + self.assertEqual(self.redir.dispatch('insert', False), '') + self.assertEqual(self.redir.dispatch('invalid'), '') + + def test_command_dispatch(self): + # Test that .__init__ causes redirection of tk calls + # through redir.dispatch + self.tk.call(self.text._w, 'insert', 'hello') + self.assertEqual(self.func.args, ('hello',)) + self.assertEqual(self.text.get('1.0', 'end'), '\n') + # Ensure that called through redir .dispatch and not through + # self.text.insert by having mock raise TclError. + self.func.__init__(TclError()) + self.assertEqual(self.tk.call(self.text._w, 'insert', 'boo'), '') + + + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/Lib/idlelib/idlever.py b/Lib/idlelib/idlever.py index cd2c8bfc3958..1ffbc76d462c 100644 --- a/Lib/idlelib/idlever.py +++ b/Lib/idlelib/idlever.py @@ -1 +1 @@ -IDLE_VERSION = "3.4.0b1" +IDLE_VERSION = "3.5.0a1" diff --git a/Lib/idlelib/keybindingDialog.py b/Lib/idlelib/keybindingDialog.py index 0f0da8c7e930..e6438bfc39cb 100644 --- a/Lib/idlelib/keybindingDialog.py +++ b/Lib/idlelib/keybindingDialog.py @@ -4,15 +4,16 @@ from tkinter import * import tkinter.messagebox as tkMessageBox import string -from idlelib import macosxSupport +import sys class GetKeysDialog(Toplevel): - def __init__(self,parent,title,action,currentKeySequences): + def __init__(self,parent,title,action,currentKeySequences,_htest=False): """ action - string, the name of the virtual event these keys will be mapped to currentKeys - list, a list of all key sequence lists currently mapped to virtual events, for overlap checking + _htest - bool, change box location when running htest """ Toplevel.__init__(self, parent) self.configure(borderwidth=5) @@ -38,11 +39,14 @@ def __init__(self,parent,title,action,currentKeySequences): self.LoadFinalKeyList() self.withdraw() #hide while setting geometry self.update_idletasks() - self.geometry("+%d+%d" % - ((parent.winfo_rootx()+((parent.winfo_width()/2) - -(self.winfo_reqwidth()/2)), - parent.winfo_rooty()+((parent.winfo_height()/2) - -(self.winfo_reqheight()/2)) )) ) #centre dialog over parent + self.geometry( + "+%d+%d" % ( + parent.winfo_rootx() + + (parent.winfo_width()/2 - self.winfo_reqwidth()/2), + parent.winfo_rooty() + + ((parent.winfo_height()/2 - self.winfo_reqheight()/2) + if not _htest else 150) + ) ) #centre dialog over parent (or below htest box) self.deiconify() #geometry set, unhide self.wait_window() @@ -133,8 +137,7 @@ def SetModifiersForPlatform(self): order is also important: key binding equality depends on it, so config-keys.def must use the same ordering. """ - import sys - if macosxSupport.runningAsOSXApp(): + if sys.platform == "darwin": self.modifiers = ['Shift', 'Control', 'Option', 'Command'] else: self.modifiers = ['Control', 'Alt', 'Shift'] @@ -259,11 +262,5 @@ def KeysOK(self): return keysOK if __name__ == '__main__': - #test the dialog - root=Tk() - def run(): - keySeq='' - dlg=GetKeysDialog(root,'Get Keys','find-again',[]) - print(dlg.result) - Button(root,text='Dialog',command=run).pack() - root.mainloop() + from idlelib.idle_test.htest import run + run(GetKeysDialog) diff --git a/Lib/idlelib/macosxSupport.py b/Lib/idlelib/macosxSupport.py index 67069fa0f393..65bd68885ac2 100644 --- a/Lib/idlelib/macosxSupport.py +++ b/Lib/idlelib/macosxSupport.py @@ -1,48 +1,70 @@ """ -A number of function that enhance IDLE on MacOSX when it used as a normal -GUI application (as opposed to an X11 application). +A number of functions that enhance IDLE on Mac OSX. """ import sys import tkinter from os import path +import warnings +def runningAsOSXApp(): + warnings.warn("runningAsOSXApp() is deprecated, use isAquaTk()", + DeprecationWarning, stacklevel=2) + return isAquaTk() -_appbundle = None +def isCarbonAquaTk(root): + warnings.warn("isCarbonAquaTk(root) is deprecated, use isCarbonTk()", + DeprecationWarning, stacklevel=2) + return isCarbonTk() -def runningAsOSXApp(): +_tk_type = None + +def _initializeTkVariantTests(root): + """ + Initializes OS X Tk variant values for + isAquaTk(), isCarbonTk(), isCocoaTk(), and isXQuartz(). """ - Returns True if Python is running from within an app on OSX. - If so, the various OS X customizations will be triggered later (menu - fixup, et al). (Originally, this test was supposed to condition - behavior on whether IDLE was running under Aqua Tk rather than - under X11 Tk but that does not work since a framework build - could be linked with X11. For several releases, this test actually - differentiates between whether IDLE is running from a framework or - not. As a future enhancement, it should be considered whether there - should be a difference based on framework and any needed X11 adaptions - should be made dependent on a new function that actually tests for X11.) - """ - global _appbundle - if _appbundle is None: - _appbundle = sys.platform == 'darwin' - if _appbundle: - import sysconfig - _appbundle = bool(sysconfig.get_config_var('PYTHONFRAMEWORK')) - return _appbundle - -_carbonaquatk = None + global _tk_type + if sys.platform == 'darwin': + ws = root.tk.call('tk', 'windowingsystem') + if 'x11' in ws: + _tk_type = "xquartz" + elif 'aqua' not in ws: + _tk_type = "other" + elif 'AppKit' in root.tk.call('winfo', 'server', '.'): + _tk_type = "cocoa" + else: + _tk_type = "carbon" + else: + _tk_type = "other" -def isCarbonAquaTk(root): +def isAquaTk(): + """ + Returns True if IDLE is using a native OS X Tk (Cocoa or Carbon). + """ + assert _tk_type is not None + return _tk_type == "cocoa" or _tk_type == "carbon" + +def isCarbonTk(): """ Returns True if IDLE is using a Carbon Aqua Tk (instead of the newer Cocoa Aqua Tk). """ - global _carbonaquatk - if _carbonaquatk is None: - _carbonaquatk = (runningAsOSXApp() and - 'aqua' in root.tk.call('tk', 'windowingsystem') and - 'AppKit' not in root.tk.call('winfo', 'server', '.')) - return _carbonaquatk + assert _tk_type is not None + return _tk_type == "carbon" + +def isCocoaTk(): + """ + Returns True if IDLE is using a Cocoa Aqua Tk. + """ + assert _tk_type is not None + return _tk_type == "cocoa" + +def isXQuartz(): + """ + Returns True if IDLE is using an OS X X11 Tk. + """ + assert _tk_type is not None + return _tk_type == "xquartz" def tkVersionWarning(root): """ @@ -53,8 +75,7 @@ def tkVersionWarning(root): can still crash unexpectedly. """ - if (runningAsOSXApp() and - ('AppKit' in root.tk.call('winfo', 'server', '.')) ): + if isCocoaTk(): patchlevel = root.tk.call('info', 'patchlevel') if patchlevel not in ('8.5.7', '8.5.9'): return False @@ -88,8 +109,8 @@ def hideTkConsole(root): def overrideRootMenu(root, flist): """ - Replace the Tk root menu by something that's more appropriate for - IDLE. + Replace the Tk root menu by something that is more appropriate for + IDLE with an Aqua Tk. """ # The menu that is attached to the Tk root (".") is also used by AquaTk for # all windows that don't specify a menu of their own. The default menubar @@ -108,6 +129,20 @@ def overrideRootMenu(root, flist): from idlelib import WindowList from idlelib.MultiCall import MultiCallCreator + closeItem = Bindings.menudefs[0][1][-2] + + # Remove the last 3 items of the file menu: a separator, close window and + # quit. Close window will be reinserted just above the save item, where + # it should be according to the HIG. Quit is in the application menu. + del Bindings.menudefs[0][1][-3:] + Bindings.menudefs[0][1].insert(6, closeItem) + + # Remove the 'About' entry from the help menu, it is in the application + # menu + del Bindings.menudefs[-1][1][0:2] + # Remove the 'Configure Idle' entry from the options menu, it is in the + # application menu as 'Preferences' + del Bindings.menudefs[-2][1][0] menubar = Menu(root) root.configure(menu=menubar) menudict = {} @@ -156,7 +191,7 @@ def help_dialog(event=None): # right thing for now. root.createcommand('exit', flist.close_all_callback) - if isCarbonAquaTk(root): + if isCarbonTk(): # for Carbon AquaTk, replace the default Tk apple menu menudict['application'] = menu = Menu(menubar, name='apple') menubar.add_cascade(label='IDLE', menu=menu) @@ -171,8 +206,7 @@ def help_dialog(event=None): Bindings.menudefs[0][1].append( ('_Preferences....', '<<open-config-dialog>>'), ) - else: - # assume Cocoa AquaTk + if isCocoaTk(): # replace default About dialog with About IDLE one root.createcommand('tkAboutDialog', about_dialog) # replace default "Help" item in Help menu @@ -182,10 +216,22 @@ def help_dialog(event=None): def setupApp(root, flist): """ - Perform setup for the OSX application bundle. + Perform initial OS X customizations if needed. + Called from PyShell.main() after initial calls to Tk() + + There are currently three major versions of Tk in use on OS X: + 1. Aqua Cocoa Tk (native default since OS X 10.6) + 2. Aqua Carbon Tk (original native, 32-bit only, deprecated) + 3. X11 (supported by some third-party distributors, deprecated) + There are various differences among the three that affect IDLE + behavior, primarily with menus, mouse key events, and accelerators. + Some one-time customizations are performed here. + Others are dynamically tested throughout idlelib by calls to the + isAquaTk(), isCarbonTk(), isCocoaTk(), isXQuartz() functions which + are initialized here as well. """ - if not runningAsOSXApp(): return - - hideTkConsole(root) - overrideRootMenu(root, flist) - addOpenEventSupport(root, flist) + _initializeTkVariantTests(root) + if isAquaTk(): + hideTkConsole(root) + overrideRootMenu(root, flist) + addOpenEventSupport(root, flist) diff --git a/Lib/idlelib/rpc.py b/Lib/idlelib/rpc.py index 9c51b8f6b521..f2aae516c837 100644 --- a/Lib/idlelib/rpc.py +++ b/Lib/idlelib/rpc.py @@ -29,6 +29,7 @@ import sys import os +import io import socket import select import socketserver @@ -53,16 +54,15 @@ def pickle_code(co): ms = marshal.dumps(co) return unpickle_code, (ms,) -# XXX KBK 24Aug02 function pickling capability not used in Idle -# def unpickle_function(ms): -# return ms +def dumps(obj, protocol=None): + f = io.BytesIO() + p = CodePickler(f, protocol) + p.dump(obj) + return f.getvalue() -# def pickle_function(fn): -# assert isinstance(fn, type.FunctionType) -# return repr(fn) - -copyreg.pickle(types.CodeType, pickle_code, unpickle_code) -# copyreg.pickle(types.FunctionType, pickle_function, unpickle_function) +class CodePickler(pickle.Pickler): + dispatch_table = {types.CodeType: pickle_code} + dispatch_table.update(copyreg.dispatch_table) BUFSIZE = 8*1024 LOCALHOST = '127.0.0.1' @@ -329,7 +329,7 @@ def newseq(self): def putmessage(self, message): self.debug("putmessage:%d:" % message[0]) try: - s = pickle.dumps(message) + s = dumps(message) except pickle.PicklingError: print("Cannot pickle:", repr(message), file=sys.__stderr__) raise diff --git a/Lib/idlelib/tabbedpages.py b/Lib/idlelib/tabbedpages.py index 255773275586..965f9f8593dc 100644 --- a/Lib/idlelib/tabbedpages.py +++ b/Lib/idlelib/tabbedpages.py @@ -467,9 +467,12 @@ def change_page(self, page_name): self._tab_set.set_selected_tab(page_name) -if __name__ == '__main__': +def _tabbed_pages(parent): # test dialog root=Tk() + width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) + root.geometry("+%d+%d"%(x, y + 175)) + root.title("Test tabbed pages") tabPage=TabbedPageSet(root, page_names=['Foobar','Baz'], n_rows=0, expand_tabs=False, ) @@ -488,3 +491,8 @@ def change_page(self, page_name): labelPgName.pack(padx=5) entryPgName.pack(padx=5) root.mainloop() + + +if __name__ == '__main__': + from idlelib.idle_test.htest import run + run(_tabbed_pages) diff --git a/Lib/idlelib/testcode.py b/Lib/idlelib/testcode.py deleted file mode 100644 index 05eaa562cd1b..000000000000 --- a/Lib/idlelib/testcode.py +++ /dev/null @@ -1,31 +0,0 @@ -import string - -def f(): - a = 0 - b = 1 - c = 2 - d = 3 - e = 4 - g() - -def g(): - h() - -def h(): - i() - -def i(): - j() - -def j(): - k() - -def k(): - l() - -l = lambda: test() - -def test(): - string.capwords(1) - -f() diff --git a/Lib/idlelib/textView.py b/Lib/idlelib/textView.py index dd50544c41a1..4257eeabaee7 100644 --- a/Lib/idlelib/textView.py +++ b/Lib/idlelib/textView.py @@ -9,15 +9,21 @@ class TextViewer(Toplevel): """A simple text viewer dialog for IDLE """ - def __init__(self, parent, title, text, modal=True): + def __init__(self, parent, title, text, modal=True, _htest=False): """Show the given text in a scrollable window with a 'close' button + If modal option set to False, user can interact with other windows, + otherwise they will be unable to interact with other windows until + the textview window is closed. + + _htest - bool; change box location when running htest. """ Toplevel.__init__(self, parent) self.configure(borderwidth=5) + # place dialog below parent if running htest self.geometry("=%dx%d+%d+%d" % (625, 500, - parent.winfo_rootx() + 10, - parent.winfo_rooty() + 10)) + parent.winfo_rootx() + 10, + parent.winfo_rooty() + (10 if not _htest else 100))) #elguavas - config placeholders til config stuff completed self.bg = '#ffffff' self.fg = '#000000' @@ -66,32 +72,15 @@ def view_file(parent, title, filename, encoding=None, modal=True): try: with open(filename, 'r', encoding=encoding) as file: contents = file.read() - except OSError: - import tkinter.messagebox as tkMessageBox + except IOError: tkMessageBox.showerror(title='File Load Error', message='Unable to load file %r .' % filename, parent=parent) else: return view_text(parent, title, contents, modal) - if __name__ == '__main__': - #test the dialog - root=Tk() - root.title('textView test') - filename = './textView.py' - with open(filename, 'r') as f: - text = f.read() - btn1 = Button(root, text='view_text', - command=lambda:view_text(root, 'view_text', text)) - btn1.pack(side=LEFT) - btn2 = Button(root, text='view_file', - command=lambda:view_file(root, 'view_file', filename)) - btn2.pack(side=LEFT) - btn3 = Button(root, text='nonmodal view_text', - command=lambda:view_text(root, 'nonmodal view_text', text, - modal=False)) - btn3.pack(side=LEFT) - close = Button(root, text='Close', command=root.destroy) - close.pack(side=RIGHT) - root.mainloop() + import unittest + unittest.main('idlelib.idle_test.test_textview', verbosity=2, exit=False) + from idlelib.idle_test.htest import run + run(TextViewer) diff --git a/Lib/imaplib.py b/Lib/imaplib.py index dabf161b87aa..49ee39def13f 100644 --- a/Lib/imaplib.py +++ b/Lib/imaplib.py @@ -238,6 +238,14 @@ def __getattr__(self, attr): return getattr(self, attr.lower()) raise AttributeError("Unknown IMAP4 command: '%s'" % attr) + def __enter__(self): + return self + + def __exit__(self, *args): + try: + self.logout() + except OSError: + pass # Overridable methods @@ -745,7 +753,8 @@ def starttls(self, ssl_context=None): ssl_context = ssl._create_stdlib_context() typ, dat = self._simple_command(name) if typ == 'OK': - self.sock = ssl_context.wrap_socket(self.sock) + self.sock = ssl_context.wrap_socket(self.sock, + server_hostname=self.host) self.file = self.sock.makefile('rb') self._tls_established = True self._get_capabilities() @@ -1061,6 +1070,11 @@ def _get_tagged_response(self, tag): del self.tagged_commands[tag] return result + # If we've seen a BYE at this point, the socket will be + # closed, so report the BYE now. + + self._check_bye() + # Some have reported "unexpected response" exceptions. # Note that ignoring them here causes loops. # Instead, send me details of the unexpected response and @@ -1216,7 +1230,8 @@ def __init__(self, host='', port=IMAP4_SSL_PORT, keyfile=None, certfile=None, ss def _create_socket(self): sock = IMAP4._create_socket(self) - return self.ssl_context.wrap_socket(sock) + return self.ssl_context.wrap_socket(sock, + server_hostname=self.host) def open(self, host='', port=IMAP4_SSL_PORT): """Setup connection to remote server on "host:port". diff --git a/Lib/imghdr.py b/Lib/imghdr.py index 0cba063a9c32..b26792539d5b 100644 --- a/Lib/imghdr.py +++ b/Lib/imghdr.py @@ -7,18 +7,16 @@ #-------------------------# def what(file, h=None): - if h is None: - if isinstance(file, str): - f = open(file, 'rb') - h = f.read(32) - else: - location = file.tell() - h = file.read(32) - file.seek(location) - f = None - else: - f = None + f = None try: + if h is None: + if isinstance(file, str): + f = open(file, 'rb') + h = f.read(32) + else: + location = file.tell() + h = file.read(32) + file.seek(location) for tf in tests: res = tf(h, f) if res: @@ -112,6 +110,18 @@ def test_bmp(h, f): tests.append(test_bmp) +def test_webp(h, f): + if h.startswith(b'RIFF') and h[8:12] == b'WEBP': + return 'webp' + +tests.append(test_webp) + +def test_exr(h, f): + if h.startswith(b'\x76\x2f\x31\x01'): + return 'exr' + +tests.append(test_exr) + #--------------------# # Small test program # #--------------------# diff --git a/Lib/imp.py b/Lib/imp.py index c8449c615549..59ce41cc0a2d 100644 --- a/Lib/imp.py +++ b/Lib/imp.py @@ -16,7 +16,7 @@ # Platform doesn't support dynamic loading. load_dynamic = None -from importlib._bootstrap import SourcelessFileLoader, _ERR_MSG, _SpecMethods +from importlib._bootstrap import SourcelessFileLoader, _ERR_MSG, _exec, _load from importlib import machinery from importlib import util @@ -164,11 +164,10 @@ class _LoadSourceCompatibility(_HackedGetData, machinery.SourceFileLoader): def load_source(name, pathname, file=None): loader = _LoadSourceCompatibility(name, pathname, file) spec = util.spec_from_file_location(name, pathname, loader=loader) - methods = _SpecMethods(spec) if name in sys.modules: - module = methods.exec(sys.modules[name]) + module = _exec(spec, sys.modules[name]) else: - module = methods.load() + module = _load(spec) # To allow reloading to potentially work, use a non-hacked loader which # won't rely on a now-closed file object. module.__loader__ = machinery.SourceFileLoader(name, pathname) @@ -185,11 +184,10 @@ def load_compiled(name, pathname, file=None): """**DEPRECATED**""" loader = _LoadCompiledCompatibility(name, pathname, file) spec = util.spec_from_file_location(name, pathname, loader=loader) - methods = _SpecMethods(spec) if name in sys.modules: - module = methods.exec(sys.modules[name]) + module = _exec(spec, sys.modules[name]) else: - module = methods.load() + module = _load(spec) # To allow reloading to potentially work, use a non-hacked loader which # won't rely on a now-closed file object. module.__loader__ = SourcelessFileLoader(name, pathname) @@ -210,11 +208,10 @@ def load_package(name, path): raise ValueError('{!r} is not a package'.format(path)) spec = util.spec_from_file_location(name, path, submodule_search_locations=[]) - methods = _SpecMethods(spec) if name in sys.modules: - return methods.exec(sys.modules[name]) + return _exec(spec, sys.modules[name]) else: - return methods.load() + return _load(spec) def load_module(name, file, filename, details): diff --git a/Lib/importlib/__init__.py b/Lib/importlib/__init__.py index 3e969bbead97..e99f50e0f167 100644 --- a/Lib/importlib/__init__.py +++ b/Lib/importlib/__init__.py @@ -11,7 +11,6 @@ # initialised below if the frozen one is not available). import _imp # Just the builtin component, NOT the full Python module import sys -import types try: import _frozen_importlib as _bootstrap @@ -23,7 +22,12 @@ # a second copy of the module. _bootstrap.__name__ = 'importlib._bootstrap' _bootstrap.__package__ = 'importlib' - _bootstrap.__file__ = __file__.replace('__init__.py', '_bootstrap.py') + try: + _bootstrap.__file__ = __file__.replace('__init__.py', '_bootstrap.py') + except NameError: + # __file__ is not guaranteed to be defined, e.g. if this code gets + # frozen by a tool like cx_Freeze. + pass sys.modules['importlib._bootstrap'] = _bootstrap # To simplify imports in test code @@ -33,6 +37,10 @@ # Fully bootstrapped at this point, import whatever you like, circular # dependencies and startup overhead minimisation permitting :) +import types +import warnings + + # Public API ######################################################### from ._bootstrap import __import__ @@ -46,44 +54,16 @@ def invalidate_caches(): finder.invalidate_caches() -def find_spec(name, path=None): - """Return the spec for the specified module. - - First, sys.modules is checked to see if the module was already imported. If - so, then sys.modules[name].__spec__ is returned. If that happens to be - set to None, then ValueError is raised. If the module is not in - sys.modules, then sys.meta_path is searched for a suitable spec with the - value of 'path' given to the finders. None is returned if no spec could - be found. - - Dotted names do not have their parent packages implicitly imported. You will - most likely need to explicitly import all parent packages in the proper - order for a submodule to get the correct spec. - - """ - if name not in sys.modules: - return _bootstrap._find_spec(name, path) - else: - module = sys.modules[name] - if module is None: - return None - try: - spec = module.__spec__ - except AttributeError: - raise ValueError('{}.__spec__ is not set'.format(name)) - else: - if spec is None: - raise ValueError('{}.__spec__ is None'.format(name)) - return spec - - -# XXX Deprecate... def find_loader(name, path=None): """Return the loader for the specified module. This is a backward-compatible wrapper around find_spec(). + This function is deprecated in favor of importlib.util.find_spec(). + """ + warnings.warn('Use importlib.util.find_spec() instead.', + DeprecationWarning, stacklevel=2) try: loader = sys.modules[name].__loader__ if loader is None: @@ -93,7 +73,7 @@ def find_loader(name, path=None): except KeyError: pass except AttributeError: - raise ValueError('{}.__loader__ is not set'.format(name)) + raise ValueError('{}.__loader__ is not set'.format(name)) from None spec = _bootstrap._find_spec(name, path) # We won't worry about malformed specs (missing attributes). @@ -153,12 +133,20 @@ def reload(module): _RELOADING[name] = module try: parent_name = name.rpartition('.')[0] - if parent_name and parent_name not in sys.modules: - msg = "parent {!r} not in sys.modules" - raise ImportError(msg.format(parent_name), name=parent_name) - spec = module.__spec__ = _bootstrap._find_spec(name, None, module) - methods = _bootstrap._SpecMethods(spec) - methods.exec(module) + if parent_name: + try: + parent = sys.modules[parent_name] + except KeyError: + msg = "parent {!r} not in sys.modules" + raise ImportError(msg.format(parent_name), + name=parent_name) from None + else: + pkgpath = parent.__path__ + else: + pkgpath = None + target = module + spec = module.__spec__ = _bootstrap._find_spec(name, pkgpath, target) + _bootstrap._exec(spec, module) # The module may have replaced itself in sys.modules! return sys.modules[name] finally: diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py index 6b8f979b8b6d..0ed7cc67dcb1 100644 --- a/Lib/importlib/_bootstrap.py +++ b/Lib/importlib/_bootstrap.py @@ -9,7 +9,7 @@ # # IMPORTANT: Whenever making changes to this module, be sure to run # a top-level make in order to get the frozen version of the module -# update. Not doing so will result in the Makefile to fail for +# updated. Not doing so will result in the Makefile to fail for # all others who don't have a ./python around to freeze the module # in the early stages of compilation. # @@ -418,12 +418,14 @@ def _call_with_frames_removed(f, *args, **kwds): # Python 3.4a1 3280 (remove implicit class argument) # Python 3.4a4 3290 (changes to __qualname__ computation) # Python 3.4a4 3300 (more changes to __qualname__ computation) +# Python 3.4rc2 3310 (alter __qualname__ computation) +# Python 3.5a0 3320 (matrix multiplication operator) # # MAGIC must change whenever the bytecode emitted by the compiler may no # longer be understood by older implementations of the eval loop (usually # due to the addition of new opcodes). -MAGIC_NUMBER = (3300).to_bytes(2, 'little') + b'\r\n' +MAGIC_NUMBER = (3320).to_bytes(2, 'little') + b'\r\n' _RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c _PYCACHE = '__pycache__' @@ -452,11 +454,11 @@ def cache_from_source(path, debug_override=None): else: suffixes = OPTIMIZED_BYTECODE_SUFFIXES head, tail = _path_split(path) - base_filename, sep, _ = tail.partition('.') + base, sep, rest = tail.rpartition('.') tag = sys.implementation.cache_tag if tag is None: raise NotImplementedError('sys.implementation.cache_tag is None') - filename = ''.join([base_filename, sep, tag, suffixes[0]]) + filename = ''.join([(base if base else rest), sep, tag, suffixes[0]]) return _path_join(head, _PYCACHE, filename) @@ -564,7 +566,11 @@ def _requires_frozen_wrapper(self, fullname): def _find_module_shim(self, fullname): """Try to find a loader for the specified module by delegating to - self.find_loader().""" + self.find_loader(). + + This method is deprecated in favor of finder.find_spec(). + + """ # Call find_loader(). If it returns a string (indicating this # is a namespace package portion), generate a warning and # return None. @@ -575,17 +581,20 @@ def _find_module_shim(self, fullname): return loader +# Typically used by loader classes as a method replacement. def _load_module_shim(self, fullname): - """Load the specified module into sys.modules and return it.""" - # XXX Deprecation Warning here... + """Load the specified module into sys.modules and return it. + + This method is deprecated. Use loader.exec_module instead. + + """ spec = spec_from_loader(fullname, self) - methods = _SpecMethods(spec) if fullname in sys.modules: module = sys.modules[fullname] - methods.exec(module) + _exec(spec, module) return sys.modules[fullname] else: - return methods.load() + return _load(spec) def _validate_bytecode_header(data, source_stats=None, name=None, path=None): @@ -683,7 +692,9 @@ def _module_repr(module): # The implementation of ModuleType__repr__(). loader = getattr(module, '__loader__', None) if hasattr(loader, 'module_repr'): - # XXX Deprecation Warning here... + # As soon as BuiltinImporter, FrozenImporter, and NamespaceLoader + # drop their implementations for module_repr. we can add a + # deprecation warning here. try: return loader.module_repr(module) except Exception: @@ -694,7 +705,7 @@ def _module_repr(module): pass else: if spec is not None: - return _SpecMethods(spec).module_repr() + return _module_repr_from_spec(spec) # We could use module.__class__.__name__ instead of 'module' in the # various repr permutations. @@ -841,6 +852,10 @@ def parent(self): def has_location(self): return self._set_fileattr + @has_location.setter + def has_location(self, value): + self._set_fileattr = bool(value) + def spec_from_loader(name, loader, *, origin=None, is_package=None): """Return a module spec based on various loader methods.""" @@ -976,253 +991,209 @@ def _spec_from_module(module, loader=None, origin=None): return spec -class _SpecMethods: - - """Convenience wrapper around spec objects to provide spec-specific - methods.""" - - def __init__(self, spec): - self.spec = spec - - @classmethod - def from_module(cls, module): - """Create a spec from a module's attributes.""" +def _init_module_attrs(spec, module, *, override=False): + # The passed-in module may be not support attribute assignment, + # in which case we simply don't set the attributes. + # __name__ + if (override or getattr(module, '__name__', None) is None): try: - spec = module.__spec__ + module.__name__ = spec.name except AttributeError: + pass + # __loader__ + if override or getattr(module, '__loader__', None) is None: + loader = spec.loader + if loader is None: + # A backward compatibility hack. + if spec.submodule_search_locations is not None: + loader = _NamespaceLoader.__new__(_NamespaceLoader) + loader._path = spec.submodule_search_locations + try: + module.__loader__ = loader + except AttributeError: + pass + # __package__ + if override or getattr(module, '__package__', None) is None: + try: + module.__package__ = spec.parent + except AttributeError: + pass + # __spec__ + try: + module.__spec__ = spec + except AttributeError: + pass + # __path__ + if override or getattr(module, '__path__', None) is None: + if spec.submodule_search_locations is not None: try: - loader = spec.__loader__ - except AttributeError: - spec = _find_spec(module.__name__) - if spec is None: - spec = spec_from_loader(module.__name__, loader) - else: - spec = spec_from_loader(module.__name__, loader) - return cls(spec) - - def module_repr(self): - """Return the repr to use for the module.""" - # We mostly replicate _module_repr() using the spec attributes. - spec = self.spec - name = '?' if spec.name is None else spec.name - if spec.origin is None: - if spec.loader is None: - return '<module {!r}>'.format(name) - else: - return '<module {!r} ({!r})>'.format(name, spec.loader) - else: - if spec.has_location: - return '<module {!r} from {!r}>'.format(name, spec.origin) - else: - return '<module {!r} ({})>'.format(spec.name, spec.origin) - - def init_module_attrs(self, module, *, _override=False, _force_name=True): - """Set the module's attributes. - - All missing import-related module attributes will be set. Here - is how the spec attributes map onto the module: - - spec.name -> module.__name__ - spec.loader -> module.__loader__ - spec.parent -> module.__package__ - spec -> module.__spec__ - - Optional: - spec.origin -> module.__file__ (if spec.set_fileattr is true) - spec.cached -> module.__cached__ (if __file__ also set) - spec.submodule_search_locations -> module.__path__ (if set) - - """ - spec = self.spec - - # The passed in module may be not support attribute assignment, - # in which case we simply don't set the attributes. - - # __name__ - if (_override or _force_name or - getattr(module, '__name__', None) is None): - try: - module.__name__ = spec.name - except AttributeError: - pass - - # __loader__ - if _override or getattr(module, '__loader__', None) is None: - loader = spec.loader - if loader is None: - # A backward compatibility hack. - if spec.submodule_search_locations is not None: - loader = _NamespaceLoader.__new__(_NamespaceLoader) - loader._path = spec.submodule_search_locations - try: - module.__loader__ = loader + module.__path__ = spec.submodule_search_locations except AttributeError: pass - - # __package__ - if _override or getattr(module, '__package__', None) is None: + # __file__/__cached__ + if spec.has_location: + if override or getattr(module, '__file__', None) is None: try: - module.__package__ = spec.parent + module.__file__ = spec.origin except AttributeError: pass - # __spec__ - try: - module.__spec__ = spec - except AttributeError: - pass - - # __path__ - if _override or getattr(module, '__path__', None) is None: - if spec.submodule_search_locations is not None: + if override or getattr(module, '__cached__', None) is None: + if spec.cached is not None: try: - module.__path__ = spec.submodule_search_locations - except AttributeError: - pass - - if spec.has_location: - # __file__ - if _override or getattr(module, '__file__', None) is None: - try: - module.__file__ = spec.origin + module.__cached__ = spec.cached except AttributeError: pass + return module - # __cached__ - if _override or getattr(module, '__cached__', None) is None: - if spec.cached is not None: - try: - module.__cached__ = spec.cached - except AttributeError: - pass - def create(self): - """Return a new module to be loaded. +def module_from_spec(spec): + """Create a module based on the provided spec.""" + # Typically loaders will not implement create_module(). + module = None + if hasattr(spec.loader, 'create_module'): + # If create_module() returns `None` then it means default + # module creation should be used. + module = spec.loader.create_module(spec) + elif hasattr(spec.loader, 'exec_module'): + _warnings.warn('starting in Python 3.6, loaders defining exec_module() ' + 'must also define create_module()', + DeprecationWarning, stacklevel=2) + if module is None: + module = _new_module(spec.name) + _init_module_attrs(spec, module) + return module - The import-related module attributes are also set with the - appropriate values from the spec. - """ - spec = self.spec - # Typically loaders will not implement create_module(). - if hasattr(spec.loader, 'create_module'): - # If create_module() returns `None` it means the default - # module creation should be used. - module = spec.loader.create_module(spec) +def _module_repr_from_spec(spec): + """Return the repr to use for the module.""" + # We mostly replicate _module_repr() using the spec attributes. + name = '?' if spec.name is None else spec.name + if spec.origin is None: + if spec.loader is None: + return '<module {!r}>'.format(name) else: - module = None - if module is None: - # This must be done before open() is ever called as the 'io' - # module implicitly imports 'locale' and would otherwise - # trigger an infinite loop. - module = _new_module(spec.name) - self.init_module_attrs(module) - return module + return '<module {!r} ({!r})>'.format(name, spec.loader) + else: + if spec.has_location: + return '<module {!r} from {!r}>'.format(name, spec.origin) + else: + return '<module {!r} ({})>'.format(spec.name, spec.origin) - def _exec(self, module): - """Do everything necessary to execute the module. - The namespace of `module` is used as the target of execution. - This method uses the loader's `exec_module()` method. +# Used by importlib.reload() and _load_module_shim(). +def _exec(spec, module): + """Execute the spec in an existing module's namespace.""" + name = spec.name + _imp.acquire_lock() + with _ModuleLockManager(name): + if sys.modules.get(name) is not module: + msg = 'module {!r} not in sys.modules'.format(name) + raise ImportError(msg, name=name) + if spec.loader is None: + if spec.submodule_search_locations is None: + raise ImportError('missing loader', name=spec.name) + # namespace package + _init_module_attrs(spec, module, override=True) + return module + _init_module_attrs(spec, module, override=True) + if not hasattr(spec.loader, 'exec_module'): + # (issue19713) Once BuiltinImporter and ExtensionFileLoader + # have exec_module() implemented, we can add a deprecation + # warning here. + spec.loader.load_module(name) + else: + spec.loader.exec_module(module) + return sys.modules[name] + + +def _load_backward_compatible(spec): + # (issue19713) Once BuiltinImporter and ExtensionFileLoader + # have exec_module() implemented, we can add a deprecation + # warning here. + spec.loader.load_module(spec.name) + # The module must be in sys.modules at this point! + module = sys.modules[spec.name] + if getattr(module, '__loader__', None) is None: + try: + module.__loader__ = spec.loader + except AttributeError: + pass + if getattr(module, '__package__', None) is None: + try: + # Since module.__path__ may not line up with + # spec.submodule_search_paths, we can't necessarily rely + # on spec.parent here. + module.__package__ = module.__name__ + if not hasattr(module, '__path__'): + module.__package__ = spec.name.rpartition('.')[0] + except AttributeError: + pass + if getattr(module, '__spec__', None) is None: + try: + module.__spec__ = spec + except AttributeError: + pass + return module - """ - self.spec.loader.exec_module(module) +def _load_unlocked(spec): + # A helper for direct use by the import system. + if spec.loader is not None: + # not a namespace package + if not hasattr(spec.loader, 'exec_module'): + return _load_backward_compatible(spec) + + module = module_from_spec(spec) + with _installed_safely(module): + if spec.loader is None: + if spec.submodule_search_locations is None: + raise ImportError('missing loader', name=spec.name) + # A namespace package so do nothing. + else: + spec.loader.exec_module(module) - # Used by importlib.reload() and _load_module_shim(). - def exec(self, module): - """Execute the spec in an existing module's namespace.""" - name = self.spec.name - _imp.acquire_lock() - with _ModuleLockManager(name): - if sys.modules.get(name) is not module: - msg = 'module {!r} not in sys.modules'.format(name) - raise ImportError(msg, name=name) - if self.spec.loader is None: - if self.spec.submodule_search_locations is None: - raise ImportError('missing loader', name=self.spec.name) - # namespace package - self.init_module_attrs(module, _override=True) - return module - self.init_module_attrs(module, _override=True) - if not hasattr(self.spec.loader, 'exec_module'): - # XXX DeprecationWarning goes here... - self.spec.loader.load_module(name) - else: - self._exec(module) - return sys.modules[name] - - def _load_backward_compatible(self): - # XXX DeprecationWarning goes here... - spec = self.spec - # The module must be in sys.modules! - spec.loader.load_module(spec.name) - module = sys.modules[spec.name] - if getattr(module, '__loader__', None) is None: - try: - module.__loader__ = spec.loader - except AttributeError: - pass - if getattr(module, '__package__', None) is None: - try: - # Since module.__path__ may not line up with - # spec.submodule_search_paths, we can't necessarily rely - # on spec.parent here. - module.__package__ = module.__name__ - if not hasattr(module, '__path__'): - module.__package__ = spec.name.rpartition('.')[0] - except AttributeError: - pass - if getattr(module, '__spec__', None) is None: - try: - module.__spec__ = spec - except AttributeError: - pass - return module + # We don't ensure that the import-related module attributes get + # set in the sys.modules replacement case. Such modules are on + # their own. + return sys.modules[spec.name] - # XXX If we don't end up using this for pythonrun.c/runpy, we should - # get rid of it. - def _load_existing(self, module): - """Exec the spec'ed module into an existing module's namespace.""" - # For use by runpy. - with _installed_safely(module): - loaded = self.exec(module) - return loaded - - def _load_unlocked(self): - # A helper for direct use by the import system. - if self.spec.loader is not None: - # not a namespace package - if not hasattr(self.spec.loader, 'exec_module'): - return self._load_backward_compatible() - - module = self.create() - with _installed_safely(module): - if self.spec.loader is None: - if self.spec.submodule_search_locations is None: - raise ImportError('missing loader', name=self.spec.name) - # A namespace package so do nothing. - else: - self._exec(module) +# A method used during testing of _load_unlocked() and by +# _load_module_shim(). +def _load(spec): + """Return a new module object, loaded by the spec's loader. - # We don't ensure that the import-related module attributes get - # set in the sys.modules replacement case. Such modules are on - # their own. - return sys.modules[self.spec.name] + The module is not added to its parent. - # A method used during testing of _load_unlocked() and by - # _load_module_shim(). - def load(self): - """Return a new module object, loaded by the spec's loader. + If a module is already in sys.modules, that existing module gets + clobbered. - The module is not added to its parent. + """ + _imp.acquire_lock() + with _ModuleLockManager(spec.name): + return _load_unlocked(spec) - If a module is already in sys.modules, that existing module gets - clobbered. - """ - _imp.acquire_lock() - with _ModuleLockManager(self.spec.name): - return self._load_unlocked() +def _fix_up_module(ns, name, pathname, cpathname=None): + # This function is used by PyImport_ExecCodeModuleObject(). + loader = ns.get('__loader__') + spec = ns.get('__spec__') + if not loader: + if spec: + loader = spec.loader + elif pathname == cpathname: + loader = SourcelessFileLoader(name, pathname) + else: + loader = SourceFileLoader(name, pathname) + if not spec: + spec = spec_from_file_location(name, pathname, loader=loader) + try: + ns['__spec__'] = spec + ns['__loader__'] = loader + ns['__file__'] = pathname + ns['__cached__'] = cpathname + except Exception: + # Not important enough to report. + pass # Loaders ##################################################################### @@ -1238,7 +1209,11 @@ class BuiltinImporter: @staticmethod def module_repr(module): - # XXX deprecate + """Return repr for the module. + + The method is deprecated. The import machinery does the job itself. + + """ return '<module {!r} (built-in)>'.format(module.__name__) @classmethod @@ -1256,6 +1231,8 @@ def find_module(cls, fullname, path=None): If 'path' is ever specified then the search is considered a failure. + This method is deprecated. Use find_spec() instead. + """ spec = cls.find_spec(fullname, path) return spec.loader if spec is not None else None @@ -1264,6 +1241,8 @@ def find_module(cls, fullname, path=None): @_requires_builtin def load_module(cls, fullname): """Load a built-in module.""" + # Once an exec_module() implementation is added we can also + # add a deprecation warning here. with _ManageReload(fullname): module = _call_with_frames_removed(_imp.init_builtin, fullname) module.__loader__ = cls @@ -1286,7 +1265,6 @@ def get_source(cls, fullname): @_requires_builtin def is_package(cls, fullname): """Return False as built-in modules are never packages.""" - # XXX DeprecationWarning here... return False @@ -1301,7 +1279,11 @@ class FrozenImporter: @staticmethod def module_repr(m): - # XXX deprecate + """Return repr for the module. + + The method is deprecated. The import machinery does the job itself. + + """ return '<module {!r} (frozen)>'.format(m.__name__) @classmethod @@ -1313,9 +1295,17 @@ def find_spec(cls, fullname, path=None, target=None): @classmethod def find_module(cls, fullname, path=None): - """Find a frozen module.""" + """Find a frozen module. + + This method is deprecated. Use find_spec() instead. + + """ return cls if _imp.is_frozen(fullname) else None + @classmethod + def create_module(cls, spec): + """Use default semantics for module creation.""" + @staticmethod def exec_module(module): name = module.__spec__.name @@ -1327,7 +1317,11 @@ def exec_module(module): @classmethod def load_module(cls, fullname): - """Load a frozen module.""" + """Load a frozen module. + + This method is deprecated. Use exec_module() instead. + + """ return _load_module_shim(cls, fullname) @classmethod @@ -1385,7 +1379,6 @@ def _search_registry(cls, fullname): @classmethod def find_spec(cls, fullname, path=None, target=None): - # XXX untested! Need a Windows person to write tests (otherwise mock out appropriately) filepath = cls._search_registry(fullname) if filepath is None: return None @@ -1401,8 +1394,12 @@ def find_spec(cls, fullname, path=None, target=None): @classmethod def find_module(cls, fullname, path=None): - """Find module named in the registry.""" - spec = self.find_spec(fullname, path) + """Find module named in the registry. + + This method is deprecated. Use exec_module() instead. + + """ + spec = cls.find_spec(fullname, path) if spec is not None: return spec.loader else: @@ -1414,7 +1411,6 @@ class _LoaderBasics: """Base class of common code needed by both SourceLoader and SourcelessFileLoader.""" - # XXX deprecate? def is_package(self, fullname): """Concrete implementation of InspectLoader.is_package by checking if the path returned by get_filename has a filename of '__init__.py'.""" @@ -1423,6 +1419,9 @@ def is_package(self, fullname): tail_name = fullname.rpartition('.')[2] return filename_base == '__init__' and tail_name != '__init__' + def create_module(self, spec): + """Use default semantics for module creation.""" + def exec_module(self, module): """Execute the module.""" code = self.get_code(module.__name__) @@ -1555,11 +1554,21 @@ def __init__(self, fullname, path): self.name = fullname self.path = path + def __eq__(self, other): + return (self.__class__ == other.__class__ and + self.__dict__ == other.__dict__) + + def __hash__(self): + return hash(self.name) ^ hash(self.path) + @_check_name def load_module(self, fullname): - """Load a module from a file.""" - # The only reason for this method is for the name check. + """Load a module from a file. + This method is deprecated. Use exec_module() instead. + + """ + # The only reason for this method is for the name check. # Issue #14857: Avoid the zero-argument form of super so the implementation # of that form can be updated without breaking the frozen module return super(FileLoader, self).load_module(fullname) @@ -1649,9 +1658,18 @@ def __init__(self, name, path): self.name = name self.path = path + def __eq__(self, other): + return (self.__class__ == other.__class__ and + self.__dict__ == other.__dict__) + + def __hash__(self): + return hash(self.name) ^ hash(self.path) + @_check_name def load_module(self, fullname): """Load an extension module.""" + # Once an exec_module() implementation is added we can also + # add a deprecation warning here. with _ManageReload(fullname): module = _call_with_frames_removed(_imp.load_dynamic, fullname, self.path) @@ -1741,14 +1759,18 @@ def append(self, item): self._path.append(item) -# We use this exclusively in init_module_attrs() for backward-compatibility. +# We use this exclusively in module_from_spec() for backward-compatibility. class _NamespaceLoader: def __init__(self, name, path, path_finder): self._path = _NamespacePath(name, path, path_finder) - # XXX Deprecate @classmethod def module_repr(cls, module): + """Return repr for the module. + + The method is deprecated. The import machinery does the job itself. + + """ return '<module {!r} (namespace)>'.format(module.__name__) def is_package(self, fullname): @@ -1760,9 +1782,19 @@ def get_source(self, fullname): def get_code(self, fullname): return compile('', '<string>', 'exec', dont_inherit=True) - # XXX Deprecate + def create_module(self, spec): + """Use default semantics for module creation.""" + + def exec_module(self, module): + pass + def load_module(self, fullname): - """Load a namespace module.""" + """Load a namespace module. + + This method is deprecated. Use exec_module() instead. + + """ + # The import system never calls this method. _verbose_message('namespace module loaded with path {!r}', self._path) return _load_module_shim(self, fullname) @@ -1788,7 +1820,7 @@ def _path_hooks(cls, path): If 'hooks' is false then use sys.path_hooks. """ - if not sys.path_hooks: + if sys.path_hooks is not None and not sys.path_hooks: _warnings.warn('sys.path_hooks is empty', ImportWarning) for hook in sys.path_hooks: try: @@ -1807,7 +1839,12 @@ def _path_importer_cache(cls, path): """ if path == '': - path = _os.getcwd() + try: + path = _os.getcwd() + except FileNotFoundError: + # Don't cache the failure as the cwd can easily change to + # a valid directory later on. + return None try: finder = sys.path_importer_cache[path] except KeyError: @@ -1817,11 +1854,13 @@ def _path_importer_cache(cls, path): @classmethod def _legacy_get_spec(cls, fullname, finder): + # This would be a good place for a DeprecationWarning if + # we ended up going that route. if hasattr(finder, 'find_loader'): loader, portions = finder.find_loader(fullname) else: loader = finder.find_module(fullname) - portions = None + portions = [] if loader is not None: return spec_from_loader(fullname, loader) spec = ModuleSpec(fullname, None) @@ -1885,8 +1924,11 @@ def find_spec(cls, fullname, path=None, target=None): @classmethod def find_module(cls, fullname, path=None): """find the module on sys.path or 'path' based on sys.path_hooks and - sys.path_importer_cache.""" - # XXX Deprecation warning here. + sys.path_importer_cache. + + This method is deprecated. Use find_spec() instead. + + """ spec = cls.find_spec(fullname, path) if spec is None: return None @@ -1924,21 +1966,20 @@ def invalidate_caches(self): def find_loader(self, fullname): """Try to find a loader for the specified module, or the namespace - package portions. Returns (loader, list-of-portions).""" + package portions. Returns (loader, list-of-portions). + + This method is deprecated. Use find_spec() instead. + + """ spec = self.find_spec(fullname) if spec is None: return None, [] return spec.loader, spec.submodule_search_locations or [] - def _get_spec(self, loader_class, fullname, path, submodule_search_locations, target): + def _get_spec(self, loader_class, fullname, path, smsl, target): loader = loader_class(fullname, path) - try: - get_spec = loader._get_spec - except AttributeError: - return spec_from_file_location(fullname, path, loader=loader, - submodule_search_locations=submodule_search_locations) - else: - return get_spec(fullname, path, submodule_search_locations, target) + return spec_from_file_location(fullname, path, loader=loader, + submodule_search_locations=smsl) def find_spec(self, fullname, target=None): """Try to find a loader for the specified module, or the namespace @@ -2062,9 +2103,18 @@ def _resolve_name(name, package, level): return '{}.{}'.format(base, name) if name else base +def _find_spec_legacy(finder, name, path): + # This would be a good place for a DeprecationWarning if + # we ended up going that route. + loader = finder.find_module(name, path) + if loader is None: + return None + return spec_from_loader(name, loader) + + def _find_spec(name, path, target=None): """Find a module's loader.""" - if not sys.meta_path: + if sys.meta_path is not None and not sys.meta_path: _warnings.warn('sys.meta_path is empty', ImportWarning) # We check sys.modules here for the reload case. While a passed-in # target will usually indicate a reload there is no guarantee, whereas @@ -2075,10 +2125,9 @@ def _find_spec(name, path, target=None): try: find_spec = finder.find_spec except AttributeError: - loader = finder.find_module(name, path) - if loader is None: + spec = _find_spec_legacy(finder, name, path) + if spec is None: continue - spec = spec_from_loader(name, loader) else: spec = find_spec(name, path, target) if spec is not None: @@ -2137,12 +2186,12 @@ def _find_and_load_unlocked(name, import_): path = parent_module.__path__ except AttributeError: msg = (_ERR_MSG + '; {!r} is not a package').format(name, parent) - raise ImportError(msg, name=name) + raise ImportError(msg, name=name) from None spec = _find_spec(name, path) if spec is None: raise ImportError(_ERR_MSG.format(name), name=name) else: - module = _SpecMethods(spec)._load_unlocked() + module = _load_unlocked(spec) if parent: # Set the module as an attribute on its parent. parent_module = sys.modules[parent] @@ -2277,8 +2326,7 @@ def _builtin_from_name(name): spec = BuiltinImporter.find_spec(name) if spec is None: raise ImportError('no built-in module named ' + name) - methods = _SpecMethods(spec) - return methods._load_unlocked() + return _load_unlocked(spec) def _setup(sys_module, _imp_module): @@ -2309,8 +2357,7 @@ def _setup(sys_module, _imp_module): else: continue spec = _spec_from_module(module, loader) - methods = _SpecMethods(spec) - methods.init_module_attrs(module) + _init_module_attrs(spec, module) # Directly load built-in modules needed during bootstrap. self_module = sys.modules[__name__] diff --git a/Lib/importlib/abc.py b/Lib/importlib/abc.py index 3995ff2a6867..287848847bd2 100644 --- a/Lib/importlib/abc.py +++ b/Lib/importlib/abc.py @@ -43,15 +43,21 @@ class MetaPathFinder(Finder): # We don't define find_spec() here since that would break # hasattr checks we do to support backward compatibility. - # XXX Deprecate def find_module(self, fullname, path): """Return a loader for the module. If no module is found, return None. The fullname is a str and the path is a list of strings or None. + This method is deprecated in favor of finder.find_spec(). If find_spec() + exists then backwards-compatible functionality is provided for this + method. + """ - return None + if not hasattr(self, 'find_spec'): + return None + found = self.find_spec(fullname, path) + return found.loader if found is not None else None def invalidate_caches(self): """An optional method for clearing the finder's cache, if any. @@ -69,7 +75,6 @@ class PathEntryFinder(Finder): # We don't define find_spec() here since that would break # hasattr checks we do to support backward compatibility. - # XXX Deprecate. def find_loader(self, fullname): """Return (loader, namespace portion) for the path entry. @@ -81,10 +86,22 @@ def find_loader(self, fullname): The portion will be discarded if another path entry finder locates the module as a normal module or package. + This method is deprecated in favor of finder.find_spec(). If find_spec() + is provided than backwards-compatible functionality is provided. + """ - return None, [] + if not hasattr(self, 'find_spec'): + return None, [] + found = self.find_spec(fullname) + if found is not None: + if not found.submodule_search_locations: + portions = [] + else: + portions = found.submodule_search_locations + return found.loader, portions + else: + return None, [] - # XXX Deprecate. find_module = _bootstrap._find_module_shim def invalidate_caches(self): @@ -105,17 +122,13 @@ def create_module(self, spec): This method should raise ImportError if anything prevents it from creating a new module. It may return None to indicate that the spec should create the new module. - - create_module() is optional. - """ - # By default, defer to _SpecMethods.create() for the new module. + # By default, defer to default semantics for the new module. return None # We don't define exec_module() here since that would break # hasattr checks we do to support backward compatibility. - # XXX Deprecate. def load_module(self, fullname): """Return the loaded module. @@ -124,16 +137,23 @@ def load_module(self, fullname): ImportError is raised on failure. + This method is deprecated in favor of loader.exec_module(). If + exec_module() exists then it is used to provide a backwards-compatible + functionality for this method. + """ - raise ImportError + if not hasattr(self, 'exec_module'): + raise ImportError + return _bootstrap._load_module_shim(self, fullname) - # XXX Deprecate. def module_repr(self, module): """Return a module's repr. Used by the module type when the method does not raise NotImplementedError. + This method is deprecated. + """ # The exception will cause ModuleType.__repr__ to ignore this method. raise NotImplementedError @@ -194,7 +214,8 @@ def get_source(self, fullname): """ raise ImportError - def source_to_code(self, data, path='<string>'): + @staticmethod + def source_to_code(data, path='<string>'): """Compile 'data' into a code object. The 'data' argument can be anything that compile() can handle. The'path' diff --git a/Lib/importlib/util.py b/Lib/importlib/util.py index 04b19515fd0e..c42ef14c5d51 100644 --- a/Lib/importlib/util.py +++ b/Lib/importlib/util.py @@ -1,16 +1,19 @@ """Utility code for constructing importers, etc.""" - +from . import abc from ._bootstrap import MAGIC_NUMBER from ._bootstrap import cache_from_source from ._bootstrap import decode_source +from ._bootstrap import module_from_spec from ._bootstrap import source_from_cache from ._bootstrap import spec_from_loader from ._bootstrap import spec_from_file_location from ._bootstrap import _resolve_name +from ._bootstrap import _find_spec from contextlib import contextmanager import functools import sys +import types import warnings @@ -29,6 +32,77 @@ def resolve_name(name, package): return _resolve_name(name[level:], package, level) +def _find_spec_from_path(name, path=None): + """Return the spec for the specified module. + + First, sys.modules is checked to see if the module was already imported. If + so, then sys.modules[name].__spec__ is returned. If that happens to be + set to None, then ValueError is raised. If the module is not in + sys.modules, then sys.meta_path is searched for a suitable spec with the + value of 'path' given to the finders. None is returned if no spec could + be found. + + Dotted names do not have their parent packages implicitly imported. You will + most likely need to explicitly import all parent packages in the proper + order for a submodule to get the correct spec. + + """ + if name not in sys.modules: + return _find_spec(name, path) + else: + module = sys.modules[name] + if module is None: + return None + try: + spec = module.__spec__ + except AttributeError: + raise ValueError('{}.__spec__ is not set'.format(name)) from None + else: + if spec is None: + raise ValueError('{}.__spec__ is None'.format(name)) + return spec + + +def find_spec(name, package=None): + """Return the spec for the specified module. + + First, sys.modules is checked to see if the module was already imported. If + so, then sys.modules[name].__spec__ is returned. If that happens to be + set to None, then ValueError is raised. If the module is not in + sys.modules, then sys.meta_path is searched for a suitable spec with the + value of 'path' given to the finders. None is returned if no spec could + be found. + + If the name is for submodule (contains a dot), the parent module is + automatically imported. + + The name and package arguments work the same as importlib.import_module(). + In other words, relative module names (with leading dots) work. + + """ + fullname = resolve_name(name, package) if name.startswith('.') else name + if fullname not in sys.modules: + parent_name = fullname.rpartition('.')[0] + if parent_name: + # Use builtins.__import__() in case someone replaced it. + parent = __import__(parent_name, fromlist=['__path__']) + return _find_spec(fullname, parent.__path__) + else: + return _find_spec(fullname, None) + else: + module = sys.modules[fullname] + if module is None: + return None + try: + spec = module.__spec__ + except AttributeError: + raise ValueError('{}.__spec__ is not set'.format(name)) from None + else: + if spec is None: + raise ValueError('{}.__spec__ is None'.format(name)) + return spec + + @contextmanager def _module_to_load(name): is_reload = name in sys.modules @@ -55,11 +129,16 @@ def _module_to_load(name): module.__initializing__ = False -# XXX deprecate def set_package(fxn): - """Set __package__ on the returned module.""" + """Set __package__ on the returned module. + + This function is deprecated. + + """ @functools.wraps(fxn) def set_package_wrapper(*args, **kwargs): + warnings.warn('The import system now takes care of this automatically.', + DeprecationWarning, stacklevel=2) module = fxn(*args, **kwargs) if getattr(module, '__package__', None) is None: module.__package__ = module.__name__ @@ -69,11 +148,16 @@ def set_package_wrapper(*args, **kwargs): return set_package_wrapper -# XXX deprecate def set_loader(fxn): - """Set __loader__ on the returned module.""" + """Set __loader__ on the returned module. + + This function is deprecated. + + """ @functools.wraps(fxn) def set_loader_wrapper(self, *args, **kwargs): + warnings.warn('The import system now takes care of this automatically.', + DeprecationWarning, stacklevel=2) module = fxn(self, *args, **kwargs) if getattr(module, '__loader__', None) is None: module.__loader__ = self @@ -100,7 +184,7 @@ def module_for_loader(fxn): """ warnings.warn('The import system now takes care of this automatically.', - PendingDeprecationWarning, stacklevel=2) + DeprecationWarning, stacklevel=2) @functools.wraps(fxn) def module_for_loader_wrapper(self, fullname, *args, **kwargs): with _module_to_load(fullname) as module: @@ -118,3 +202,94 @@ def module_for_loader_wrapper(self, fullname, *args, **kwargs): return fxn(self, module, *args, **kwargs) return module_for_loader_wrapper + + +class _Module(types.ModuleType): + + """A subclass of the module type to allow __class__ manipulation.""" + + +class _LazyModule(types.ModuleType): + + """A subclass of the module type which triggers loading upon attribute access.""" + + def __getattribute__(self, attr): + """Trigger the load of the module and return the attribute.""" + # All module metadata must be garnered from __spec__ in order to avoid + # using mutated values. + # Stop triggering this method. + self.__class__ = _Module + # Get the original name to make sure no object substitution occurred + # in sys.modules. + original_name = self.__spec__.name + # Figure out exactly what attributes were mutated between the creation + # of the module and now. + attrs_then = self.__spec__.loader_state + attrs_now = self.__dict__ + attrs_updated = {} + for key, value in attrs_now.items(): + # Code that set the attribute may have kept a reference to the + # assigned object, making identity more important than equality. + if key not in attrs_then: + attrs_updated[key] = value + elif id(attrs_now[key]) != id(attrs_then[key]): + attrs_updated[key] = value + self.__spec__.loader.exec_module(self) + # If exec_module() was used directly there is no guarantee the module + # object was put into sys.modules. + if original_name in sys.modules: + if id(self) != id(sys.modules[original_name]): + msg = ('module object for {!r} substituted in sys.modules ' + 'during a lazy load') + raise ValueError(msg.format(original_name)) + # Update after loading since that's what would happen in an eager + # loading situation. + self.__dict__.update(attrs_updated) + return getattr(self, attr) + + def __delattr__(self, attr): + """Trigger the load and then perform the deletion.""" + # To trigger the load and raise an exception if the attribute + # doesn't exist. + self.__getattribute__(attr) + delattr(self, attr) + + +class LazyLoader(abc.Loader): + + """A loader that creates a module which defers loading until attribute access.""" + + @staticmethod + def __check_eager_loader(loader): + if not hasattr(loader, 'exec_module'): + raise TypeError('loader must define exec_module()') + elif hasattr(loader.__class__, 'create_module'): + if abc.Loader.create_module != loader.__class__.create_module: + # Only care if create_module() is overridden in a subclass of + # importlib.abc.Loader. + raise TypeError('loader cannot define create_module()') + + @classmethod + def factory(cls, loader): + """Construct a callable which returns the eager loader made lazy.""" + cls.__check_eager_loader(loader) + return lambda *args, **kwargs: cls(loader(*args, **kwargs)) + + def __init__(self, loader): + self.__check_eager_loader(loader) + self.loader = loader + + def create_module(self, spec): + """Create a module which can have its __class__ manipulated.""" + return _Module(spec.name) + + def exec_module(self, module): + """Make the module load lazily.""" + module.__spec__.loader = self.loader + module.__loader__ = self.loader + # Don't need to worry about deep-copying as trying to set an attribute + # on an object would have triggered the load, + # e.g. ``module.__spec__.loader = None`` would trigger a load from + # trying to access module.__spec__. + module.__spec__.loader_state = module.__dict__.copy() + module.__class__ = _LazyModule diff --git a/Lib/inspect.py b/Lib/inspect.py index dc94e44b296d..98d665dd45f7 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -17,7 +17,7 @@ getclasstree() - arrange classes so as to represent their hierarchy getargspec(), getargvalues(), getcallargs() - get info about function arguments - getfullargspec() - same, with support for Python-3000 features + getfullargspec() - same, with support for Python 3 features formatargspec(), formatargvalues() - format an argument spec getouterframes(), getinnerframes() - get info about frames currentframe() - get the current stack frame @@ -32,6 +32,7 @@ 'Yury Selivanov <yselivanov@sprymix.com>') import ast +import enum import importlib.machinery import itertools import linecache @@ -39,6 +40,7 @@ import re import sys import tokenize +import token import types import warnings import functools @@ -48,7 +50,7 @@ # Create constants for the compiler flags in Include/code.h # We try to get them from dis to avoid duplication, but fall -# back to hardcoding so the dependency is optional +# back to hard-coding so the dependency is optional try: from dis import COMPILER_FLAG_NAMES as _flag_names except ImportError: @@ -412,7 +414,7 @@ def classify_class_attrs(cls): elif isinstance(dict_obj, property): kind = "property" obj = dict_obj - elif isfunction(obj) or ismethoddescriptor(obj): + elif isroutine(obj): kind = "method" else: kind = "data" @@ -516,9 +518,10 @@ def getfile(object): return object.__file__ raise TypeError('{!r} is a built-in module'.format(object)) if isclass(object): - object = sys.modules.get(object.__module__) - if hasattr(object, '__file__'): - return object.__file__ + if hasattr(object, '__module__'): + object = sys.modules.get(object.__module__) + if hasattr(object, '__file__'): + return object.__file__ raise TypeError('{!r} is a built-in class'.format(object)) if ismethod(object): object = object.__func__ @@ -650,11 +653,17 @@ def findsource(object): in the file and the line number indexes a line in that list. An OSError is raised if the source code cannot be retrieved.""" - file = getfile(object) - sourcefile = getsourcefile(object) - if not sourcefile and file[:1] + file[-1:] != '<>': - raise OSError('source code not available') - file = sourcefile if sourcefile else file + file = getsourcefile(object) + if file: + # Invalidate cache if needed. + linecache.checkcache(file) + else: + file = getfile(object) + # Allow filenames in form of "<something>" to pass through. + # `doctest` monkeypatches `linecache` module to enable + # inspection, so let `linecache.getlines` to be called. + if not (file.startswith('<') and file.endswith('>')): + raise OSError('source code not available') module = getmodule(object, file) if module: @@ -814,6 +823,7 @@ def getsourcelines(object): corresponding to the object and the line number indicates where in the original source file the first line of code was found. An OSError is raised if the source code cannot be retrieved.""" + object = unwrap(object) lines, lnum = findsource(object) if ismodule(object): return lines, 0 @@ -911,13 +921,12 @@ def _getfullargs(co): def getargspec(func): """Get the names and default values of a function's arguments. - A tuple of four things is returned: (args, varargs, varkw, defaults). - 'args' is a list of the argument names. - 'args' will include keyword-only argument names. - 'varargs' and 'varkw' are the names of the * and ** arguments or None. + A tuple of four things is returned: (args, varargs, keywords, defaults). + 'args' is a list of the argument names, including keyword-only argument names. + 'varargs' and 'keywords' are the names of the * and ** arguments or None. 'defaults' is an n-tuple of the default values of the last n arguments. - Use the getfullargspec() API for Python-3000 code, as annotations + Use the getfullargspec() API for Python 3 code, as annotations and keyword arguments are supported. getargspec() will raise ValueError if the func has either annotations or keyword arguments. """ @@ -933,7 +942,7 @@ def getargspec(func): 'args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations') def getfullargspec(func): - """Get the names and default values of a function's arguments. + """Get the names and default values of a callable object's arguments. A tuple of seven things is returned: (args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults annotations). @@ -947,13 +956,79 @@ def getfullargspec(func): The first four items in the tuple correspond to getargspec(). """ - if ismethod(func): - func = func.__func__ - if not isfunction(func): - raise TypeError('{!r} is not a Python function'.format(func)) - args, varargs, kwonlyargs, varkw = _getfullargs(func.__code__) - return FullArgSpec(args, varargs, varkw, func.__defaults__, - kwonlyargs, func.__kwdefaults__, func.__annotations__) + try: + # Re: `skip_bound_arg=False` + # + # There is a notable difference in behaviour between getfullargspec + # and Signature: the former always returns 'self' parameter for bound + # methods, whereas the Signature always shows the actual calling + # signature of the passed object. + # + # To simulate this behaviour, we "unbind" bound methods, to trick + # inspect.signature to always return their first parameter ("self", + # usually) + + # Re: `follow_wrapper_chains=False` + # + # getfullargspec() historically ignored __wrapped__ attributes, + # so we ensure that remains the case in 3.3+ + + sig = _signature_from_callable(func, + follow_wrapper_chains=False, + skip_bound_arg=False, + sigcls=Signature) + except Exception as ex: + # Most of the times 'signature' will raise ValueError. + # But, it can also raise AttributeError, and, maybe something + # else. So to be fully backwards compatible, we catch all + # possible exceptions here, and reraise a TypeError. + raise TypeError('unsupported callable') from ex + + args = [] + varargs = None + varkw = None + kwonlyargs = [] + defaults = () + annotations = {} + defaults = () + kwdefaults = {} + + if sig.return_annotation is not sig.empty: + annotations['return'] = sig.return_annotation + + for param in sig.parameters.values(): + kind = param.kind + name = param.name + + if kind is _POSITIONAL_ONLY: + args.append(name) + elif kind is _POSITIONAL_OR_KEYWORD: + args.append(name) + if param.default is not param.empty: + defaults += (param.default,) + elif kind is _VAR_POSITIONAL: + varargs = name + elif kind is _KEYWORD_ONLY: + kwonlyargs.append(name) + if param.default is not param.empty: + kwdefaults[name] = param.default + elif kind is _VAR_KEYWORD: + varkw = name + + if param.annotation is not param.empty: + annotations[name] = param.annotation + + if not kwdefaults: + # compatibility with 'func.__kwdefaults__' + kwdefaults = None + + if not defaults: + # compatibility with 'func.__defaults__' + defaults = None + + return FullArgSpec(args, varargs, varkw, defaults, + kwonlyargs, kwdefaults, annotations) + ArgInfo = namedtuple('ArgInfo', 'args varargs keywords locals') @@ -970,8 +1045,8 @@ def getargvalues(frame): def formatannotation(annotation, base_module=None): if isinstance(annotation, type): if annotation.__module__ in ('builtins', base_module): - return annotation.__name__ - return annotation.__module__+'.'+annotation.__name__ + return annotation.__qualname__ + return annotation.__module__+'.'+annotation.__qualname__ return repr(annotation) def formatannotationrelativeto(object): @@ -1058,7 +1133,7 @@ def _missing_arguments(f_name, argnames, pos, values): elif missing == 2: s = "{} and {}".format(*names) else: - tail = ", {} and {}".format(names[-2:]) + tail = ", {} and {}".format(*names[-2:]) del names[-2:] s = ", ".join(names) + tail raise TypeError("%s() missing %i required %s argument%s: %s" % @@ -1087,12 +1162,14 @@ def _too_many(f_name, args, kwonly, varargs, defcount, given, values): (f_name, sig, "s" if plural else "", given, kwonly_sig, "was" if given == 1 and not kwonly_given else "were")) -def getcallargs(func, *positional, **named): +def getcallargs(*func_and_positional, **named): """Get the mapping of arguments to values. A dict is returned, with keys the function argument names (including the names of the * and ** arguments, if any), and values the respective bound values from 'positional' and 'named'.""" + func = func_and_positional[0] + positional = func_and_positional[1:] spec = getfullargspec(func) args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = spec f_name = func.__name__ @@ -1139,7 +1216,7 @@ def getcallargs(func, *positional, **named): missing = 0 for kwarg in kwonlyargs: if kwarg not in arg2value: - if kwarg in kwonlydefaults: + if kwonlydefaults and kwarg in kwonlydefaults: arg2value[kwarg] = kwonlydefaults[kwarg] else: missing += 1 @@ -1242,6 +1319,8 @@ def getlineno(frame): # FrameType.f_lineno is now a descriptor that grovels co_lnotab return frame.f_lineno +FrameInfo = namedtuple('FrameInfo', ('frame',) + Traceback._fields) + def getouterframes(frame, context=1): """Get a list of records for a frame and all higher (calling) frames. @@ -1249,7 +1328,8 @@ def getouterframes(frame, context=1): name, a list of lines of context, and index within the context.""" framelist = [] while frame: - framelist.append((frame,) + getframeinfo(frame, context)) + frameinfo = (frame,) + getframeinfo(frame, context) + framelist.append(FrameInfo(*frameinfo)) frame = frame.f_back return framelist @@ -1260,7 +1340,8 @@ def getinnerframes(tb, context=1): name, a list of lines of context, and index within the context.""" framelist = [] while tb: - framelist.append((tb.tb_frame,) + getframeinfo(tb, context)) + frameinfo = (tb.tb_frame,) + getframeinfo(tb, context) + framelist.append(FrameInfo(*frameinfo)) tb = tb.tb_next return framelist @@ -1417,13 +1498,19 @@ def getgeneratorlocals(generator): _WrapperDescriptor = type(type.__call__) _MethodWrapper = type(all.__call__) +_ClassMethodWrapper = type(int.__dict__['from_bytes']) _NonUserDefinedCallables = (_WrapperDescriptor, _MethodWrapper, + _ClassMethodWrapper, types.BuiltinFunctionType) -def _get_user_defined_method(cls, method_name): +def _signature_get_user_defined_method(cls, method_name): + """Private helper. Checks if ``cls`` has an attribute + named ``method_name`` and returns it only if it is a + pure python function. + """ try: meth = getattr(cls, method_name) except AttributeError: @@ -1435,8 +1522,405 @@ def _get_user_defined_method(cls, method_name): return meth -def signature(obj): - '''Get a signature object for the passed callable.''' +def _signature_get_partial(wrapped_sig, partial, extra_args=()): + """Private helper to calculate how 'wrapped_sig' signature will + look like after applying a 'functools.partial' object (or alike) + on it. + """ + + old_params = wrapped_sig.parameters + new_params = OrderedDict(old_params.items()) + + partial_args = partial.args or () + partial_keywords = partial.keywords or {} + + if extra_args: + partial_args = extra_args + partial_args + + try: + ba = wrapped_sig.bind_partial(*partial_args, **partial_keywords) + except TypeError as ex: + msg = 'partial object {!r} has incorrect arguments'.format(partial) + raise ValueError(msg) from ex + + + transform_to_kwonly = False + for param_name, param in old_params.items(): + try: + arg_value = ba.arguments[param_name] + except KeyError: + pass + else: + if param.kind is _POSITIONAL_ONLY: + # If positional-only parameter is bound by partial, + # it effectively disappears from the signature + new_params.pop(param_name) + continue + + if param.kind is _POSITIONAL_OR_KEYWORD: + if param_name in partial_keywords: + # This means that this parameter, and all parameters + # after it should be keyword-only (and var-positional + # should be removed). Here's why. Consider the following + # function: + # foo(a, b, *args, c): + # pass + # + # "partial(foo, a='spam')" will have the following + # signature: "(*, a='spam', b, c)". Because attempting + # to call that partial with "(10, 20)" arguments will + # raise a TypeError, saying that "a" argument received + # multiple values. + transform_to_kwonly = True + # Set the new default value + new_params[param_name] = param.replace(default=arg_value) + else: + # was passed as a positional argument + new_params.pop(param.name) + continue + + if param.kind is _KEYWORD_ONLY: + # Set the new default value + new_params[param_name] = param.replace(default=arg_value) + + if transform_to_kwonly: + assert param.kind is not _POSITIONAL_ONLY + + if param.kind is _POSITIONAL_OR_KEYWORD: + new_param = new_params[param_name].replace(kind=_KEYWORD_ONLY) + new_params[param_name] = new_param + new_params.move_to_end(param_name) + elif param.kind in (_KEYWORD_ONLY, _VAR_KEYWORD): + new_params.move_to_end(param_name) + elif param.kind is _VAR_POSITIONAL: + new_params.pop(param.name) + + return wrapped_sig.replace(parameters=new_params.values()) + + +def _signature_bound_method(sig): + """Private helper to transform signatures for unbound + functions to bound methods. + """ + + params = tuple(sig.parameters.values()) + + if not params or params[0].kind in (_VAR_KEYWORD, _KEYWORD_ONLY): + raise ValueError('invalid method signature') + + kind = params[0].kind + if kind in (_POSITIONAL_OR_KEYWORD, _POSITIONAL_ONLY): + # Drop first parameter: + # '(p1, p2[, ...])' -> '(p2[, ...])' + params = params[1:] + else: + if kind is not _VAR_POSITIONAL: + # Unless we add a new parameter type we never + # get here + raise ValueError('invalid argument type') + # It's a var-positional parameter. + # Do nothing. '(*args[, ...])' -> '(*args[, ...])' + + return sig.replace(parameters=params) + + +def _signature_is_builtin(obj): + """Private helper to test if `obj` is a callable that might + support Argument Clinic's __text_signature__ protocol. + """ + return (isbuiltin(obj) or + ismethoddescriptor(obj) or + isinstance(obj, _NonUserDefinedCallables) or + # Can't test 'isinstance(type)' here, as it would + # also be True for regular python classes + obj in (type, object)) + + +def _signature_is_functionlike(obj): + """Private helper to test if `obj` is a duck type of FunctionType. + A good example of such objects are functions compiled with + Cython, which have all attributes that a pure Python function + would have, but have their code statically compiled. + """ + + if not callable(obj) or isclass(obj): + # All function-like objects are obviously callables, + # and not classes. + return False + + name = getattr(obj, '__name__', None) + code = getattr(obj, '__code__', None) + defaults = getattr(obj, '__defaults__', _void) # Important to use _void ... + kwdefaults = getattr(obj, '__kwdefaults__', _void) # ... and not None here + annotations = getattr(obj, '__annotations__', None) + + return (isinstance(code, types.CodeType) and + isinstance(name, str) and + (defaults is None or isinstance(defaults, tuple)) and + (kwdefaults is None or isinstance(kwdefaults, dict)) and + isinstance(annotations, dict)) + + +def _signature_get_bound_param(spec): + """ Private helper to get first parameter name from a + __text_signature__ of a builtin method, which should + be in the following format: '($param1, ...)'. + Assumptions are that the first argument won't have + a default value or an annotation. + """ + + assert spec.startswith('($') + + pos = spec.find(',') + if pos == -1: + pos = spec.find(')') + + cpos = spec.find(':') + assert cpos == -1 or cpos > pos + + cpos = spec.find('=') + assert cpos == -1 or cpos > pos + + return spec[2:pos] + + +def _signature_strip_non_python_syntax(signature): + """ + Private helper function. Takes a signature in Argument Clinic's + extended signature format. + + Returns a tuple of three things: + * that signature re-rendered in standard Python syntax, + * the index of the "self" parameter (generally 0), or None if + the function does not have a "self" parameter, and + * the index of the last "positional only" parameter, + or None if the signature has no positional-only parameters. + """ + + if not signature: + return signature, None, None + + self_parameter = None + last_positional_only = None + + lines = [l.encode('ascii') for l in signature.split('\n')] + generator = iter(lines).__next__ + token_stream = tokenize.tokenize(generator) + + delayed_comma = False + skip_next_comma = False + text = [] + add = text.append + + current_parameter = 0 + OP = token.OP + ERRORTOKEN = token.ERRORTOKEN + + # token stream always starts with ENCODING token, skip it + t = next(token_stream) + assert t.type == tokenize.ENCODING + + for t in token_stream: + type, string = t.type, t.string + + if type == OP: + if string == ',': + if skip_next_comma: + skip_next_comma = False + else: + assert not delayed_comma + delayed_comma = True + current_parameter += 1 + continue + + if string == '/': + assert not skip_next_comma + assert last_positional_only is None + skip_next_comma = True + last_positional_only = current_parameter - 1 + continue + + if (type == ERRORTOKEN) and (string == '$'): + assert self_parameter is None + self_parameter = current_parameter + continue + + if delayed_comma: + delayed_comma = False + if not ((type == OP) and (string == ')')): + add(', ') + add(string) + if (string == ','): + add(' ') + clean_signature = ''.join(text) + return clean_signature, self_parameter, last_positional_only + + +def _signature_fromstr(cls, obj, s, skip_bound_arg=True): + """Private helper to parse content of '__text_signature__' + and return a Signature based on it. + """ + + Parameter = cls._parameter_cls + + clean_signature, self_parameter, last_positional_only = \ + _signature_strip_non_python_syntax(s) + + program = "def foo" + clean_signature + ": pass" + + try: + module = ast.parse(program) + except SyntaxError: + module = None + + if not isinstance(module, ast.Module): + raise ValueError("{!r} builtin has invalid signature".format(obj)) + + f = module.body[0] + + parameters = [] + empty = Parameter.empty + invalid = object() + + module = None + module_dict = {} + module_name = getattr(obj, '__module__', None) + if module_name: + module = sys.modules.get(module_name, None) + if module: + module_dict = module.__dict__ + sys_module_dict = sys.modules + + def parse_name(node): + assert isinstance(node, ast.arg) + if node.annotation != None: + raise ValueError("Annotations are not currently supported") + return node.arg + + def wrap_value(s): + try: + value = eval(s, module_dict) + except NameError: + try: + value = eval(s, sys_module_dict) + except NameError: + raise RuntimeError() + + if isinstance(value, str): + return ast.Str(value) + if isinstance(value, (int, float)): + return ast.Num(value) + if isinstance(value, bytes): + return ast.Bytes(value) + if value in (True, False, None): + return ast.NameConstant(value) + raise RuntimeError() + + class RewriteSymbolics(ast.NodeTransformer): + def visit_Attribute(self, node): + a = [] + n = node + while isinstance(n, ast.Attribute): + a.append(n.attr) + n = n.value + if not isinstance(n, ast.Name): + raise RuntimeError() + a.append(n.id) + value = ".".join(reversed(a)) + return wrap_value(value) + + def visit_Name(self, node): + if not isinstance(node.ctx, ast.Load): + raise ValueError() + return wrap_value(node.id) + + def p(name_node, default_node, default=empty): + name = parse_name(name_node) + if name is invalid: + return None + if default_node and default_node is not _empty: + try: + default_node = RewriteSymbolics().visit(default_node) + o = ast.literal_eval(default_node) + except ValueError: + o = invalid + if o is invalid: + return None + default = o if o is not invalid else default + parameters.append(Parameter(name, kind, default=default, annotation=empty)) + + # non-keyword-only parameters + args = reversed(f.args.args) + defaults = reversed(f.args.defaults) + iter = itertools.zip_longest(args, defaults, fillvalue=None) + if last_positional_only is not None: + kind = Parameter.POSITIONAL_ONLY + else: + kind = Parameter.POSITIONAL_OR_KEYWORD + for i, (name, default) in enumerate(reversed(list(iter))): + p(name, default) + if i == last_positional_only: + kind = Parameter.POSITIONAL_OR_KEYWORD + + # *args + if f.args.vararg: + kind = Parameter.VAR_POSITIONAL + p(f.args.vararg, empty) + + # keyword-only arguments + kind = Parameter.KEYWORD_ONLY + for name, default in zip(f.args.kwonlyargs, f.args.kw_defaults): + p(name, default) + + # **kwargs + if f.args.kwarg: + kind = Parameter.VAR_KEYWORD + p(f.args.kwarg, empty) + + if self_parameter is not None: + # Possibly strip the bound argument: + # - We *always* strip first bound argument if + # it is a module. + # - We don't strip first bound argument if + # skip_bound_arg is False. + assert parameters + _self = getattr(obj, '__self__', None) + self_isbound = _self is not None + self_ismodule = ismodule(_self) + if self_isbound and (self_ismodule or skip_bound_arg): + parameters.pop(0) + else: + # for builtins, self parameter is always positional-only! + p = parameters[0].replace(kind=Parameter.POSITIONAL_ONLY) + parameters[0] = p + + return cls(parameters, return_annotation=cls.empty) + + +def _signature_from_builtin(cls, func, skip_bound_arg=True): + """Private helper function to get signature for + builtin callables. + """ + + if not _signature_is_builtin(func): + raise TypeError("{!r} is not a Python builtin " + "function".format(func)) + + s = getattr(func, "__text_signature__", None) + if not s: + raise ValueError("no signature found for builtin {!r}".format(func)) + + return _signature_fromstr(cls, func, s, skip_bound_arg) + + +def _signature_from_callable(obj, *, + follow_wrapper_chains=True, + skip_bound_arg=True, + sigcls): + + """Private helper function to get signature for arbitrary + callable objects. + """ if not callable(obj): raise TypeError('{!r} is not a callable object'.format(obj)) @@ -1444,11 +1928,20 @@ def signature(obj): if isinstance(obj, types.MethodType): # In this case we skip the first parameter of the underlying # function (usually `self` or `cls`). - sig = signature(obj.__func__) - return sig.replace(parameters=tuple(sig.parameters.values())[1:]) + sig = _signature_from_callable( + obj.__func__, + follow_wrapper_chains=follow_wrapper_chains, + skip_bound_arg=skip_bound_arg, + sigcls=sigcls) + + if skip_bound_arg: + return _signature_bound_method(sig) + else: + return sig # Was this function wrapped by a decorator? - obj = unwrap(obj, stop=(lambda f: hasattr(f, "__signature__"))) + if follow_wrapper_chains: + obj = unwrap(obj, stop=(lambda f: hasattr(f, "__signature__"))) try: sig = obj.__signature__ @@ -1456,56 +1949,54 @@ def signature(obj): pass else: if sig is not None: + if not isinstance(sig, Signature): + raise TypeError( + 'unexpected object {!r} in __signature__ ' + 'attribute'.format(sig)) return sig + try: + partialmethod = obj._partialmethod + except AttributeError: + pass + else: + if isinstance(partialmethod, functools.partialmethod): + # Unbound partialmethod (see functools.partialmethod) + # This means, that we need to calculate the signature + # as if it's a regular partial object, but taking into + # account that the first positional argument + # (usually `self`, or `cls`) will not be passed + # automatically (as for boundmethods) - if isinstance(obj, types.FunctionType): - return Signature.from_function(obj) + wrapped_sig = _signature_from_callable( + partialmethod.func, + follow_wrapper_chains=follow_wrapper_chains, + skip_bound_arg=skip_bound_arg, + sigcls=sigcls) - if isinstance(obj, types.BuiltinFunctionType): - return Signature.from_builtin(obj) + sig = _signature_get_partial(wrapped_sig, partialmethod, (None,)) - if isinstance(obj, functools.partial): - sig = signature(obj.func) + first_wrapped_param = tuple(wrapped_sig.parameters.values())[0] + new_params = (first_wrapped_param,) + tuple(sig.parameters.values()) - new_params = OrderedDict(sig.parameters.items()) + return sig.replace(parameters=new_params) - partial_args = obj.args or () - partial_keywords = obj.keywords or {} - try: - ba = sig.bind_partial(*partial_args, **partial_keywords) - except TypeError as ex: - msg = 'partial object {!r} has incorrect arguments'.format(obj) - raise ValueError(msg) from ex - - for arg_name, arg_value in ba.arguments.items(): - param = new_params[arg_name] - if arg_name in partial_keywords: - # We set a new default value, because the following code - # is correct: - # - # >>> def foo(a): print(a) - # >>> print(partial(partial(foo, a=10), a=20)()) - # 20 - # >>> print(partial(partial(foo, a=10), a=20)(a=30)) - # 30 - # - # So, with 'partial' objects, passing a keyword argument is - # like setting a new default value for the corresponding - # parameter - # - # We also mark this parameter with '_partial_kwarg' - # flag. Later, in '_bind', the 'default' value of this - # parameter will be added to 'kwargs', to simulate - # the 'functools.partial' real call. - new_params[arg_name] = param.replace(default=arg_value, - _partial_kwarg=True) - - elif (param.kind not in (_VAR_KEYWORD, _VAR_POSITIONAL) and - not param._partial_kwarg): - new_params.pop(arg_name) - - return sig.replace(parameters=new_params.values()) + if isfunction(obj) or _signature_is_functionlike(obj): + # If it's a pure Python function, or an object that is duck type + # of a Python function (Cython functions, for instance), then: + return sigcls.from_function(obj) + + if _signature_is_builtin(obj): + return _signature_from_builtin(sigcls, obj, + skip_bound_arg=skip_bound_arg) + + if isinstance(obj, functools.partial): + wrapped_sig = _signature_from_callable( + obj.func, + follow_wrapper_chains=follow_wrapper_chains, + skip_bound_arg=skip_bound_arg, + sigcls=sigcls) + return _signature_get_partial(wrapped_sig, obj) sig = None if isinstance(obj, type): @@ -1513,32 +2004,88 @@ def signature(obj): # First, let's see if it has an overloaded __call__ defined # in its metaclass - call = _get_user_defined_method(type(obj), '__call__') + call = _signature_get_user_defined_method(type(obj), '__call__') if call is not None: - sig = signature(call) + sig = _signature_from_callable( + call, + follow_wrapper_chains=follow_wrapper_chains, + skip_bound_arg=skip_bound_arg, + sigcls=sigcls) else: # Now we check if the 'obj' class has a '__new__' method - new = _get_user_defined_method(obj, '__new__') + new = _signature_get_user_defined_method(obj, '__new__') if new is not None: - sig = signature(new) + sig = _signature_from_callable( + new, + follow_wrapper_chains=follow_wrapper_chains, + skip_bound_arg=skip_bound_arg, + sigcls=sigcls) else: # Finally, we should have at least __init__ implemented - init = _get_user_defined_method(obj, '__init__') + init = _signature_get_user_defined_method(obj, '__init__') if init is not None: - sig = signature(init) + sig = _signature_from_callable( + init, + follow_wrapper_chains=follow_wrapper_chains, + skip_bound_arg=skip_bound_arg, + sigcls=sigcls) + + if sig is None: + # At this point we know, that `obj` is a class, with no user- + # defined '__init__', '__new__', or class-level '__call__' + + for base in obj.__mro__[:-1]: + # Since '__text_signature__' is implemented as a + # descriptor that extracts text signature from the + # class docstring, if 'obj' is derived from a builtin + # class, its own '__text_signature__' may be 'None'. + # Therefore, we go through the MRO (except the last + # class in there, which is 'object') to find the first + # class with non-empty text signature. + try: + text_sig = base.__text_signature__ + except AttributeError: + pass + else: + if text_sig: + # If 'obj' class has a __text_signature__ attribute: + # return a signature based on it + return _signature_fromstr(sigcls, obj, text_sig) + + # No '__text_signature__' was found for the 'obj' class. + # Last option is to check if its '__init__' is + # object.__init__ or type.__init__. + if type not in obj.__mro__: + # We have a class (not metaclass), but no user-defined + # __init__ or __new__ for it + if obj.__init__ is object.__init__: + # Return a signature of 'object' builtin. + return signature(object) + elif not isinstance(obj, _NonUserDefinedCallables): # An object with __call__ # We also check that the 'obj' is not an instance of # _WrapperDescriptor or _MethodWrapper to avoid # infinite recursion (and even potential segfault) - call = _get_user_defined_method(type(obj), '__call__') + call = _signature_get_user_defined_method(type(obj), '__call__') if call is not None: - sig = signature(call) + try: + sig = _signature_from_callable( + call, + follow_wrapper_chains=follow_wrapper_chains, + skip_bound_arg=skip_bound_arg, + sigcls=sigcls) + except ValueError as ex: + msg = 'no signature found for {!r}'.format(obj) + raise ValueError(msg) from ex if sig is not None: # For classes and objects we skip the first parameter of their # __call__, __new__, or __init__ methods - return sig.replace(parameters=tuple(sig.parameters.values())[1:]) + if skip_bound_arg: + return _signature_bound_method(sig) + else: + return sig if isinstance(obj, types.BuiltinFunctionType): # Raise a nicer error message for builtins @@ -1549,35 +2096,33 @@ def signature(obj): class _void: - '''A private marker - used in Parameter & Signature''' + """A private marker - used in Parameter & Signature.""" class _empty: - pass + """Marker object for Signature.empty and Parameter.empty.""" -class _ParameterKind(int): - def __new__(self, *args, name): - obj = int.__new__(self, *args) - obj._name = name - return obj +class _ParameterKind(enum.IntEnum): + POSITIONAL_ONLY = 0 + POSITIONAL_OR_KEYWORD = 1 + VAR_POSITIONAL = 2 + KEYWORD_ONLY = 3 + VAR_KEYWORD = 4 def __str__(self): - return self._name - - def __repr__(self): - return '<_ParameterKind: {!r}>'.format(self._name) + return self._name_ -_POSITIONAL_ONLY = _ParameterKind(0, name='POSITIONAL_ONLY') -_POSITIONAL_OR_KEYWORD = _ParameterKind(1, name='POSITIONAL_OR_KEYWORD') -_VAR_POSITIONAL = _ParameterKind(2, name='VAR_POSITIONAL') -_KEYWORD_ONLY = _ParameterKind(3, name='KEYWORD_ONLY') -_VAR_KEYWORD = _ParameterKind(4, name='VAR_KEYWORD') +_POSITIONAL_ONLY = _ParameterKind.POSITIONAL_ONLY +_POSITIONAL_OR_KEYWORD = _ParameterKind.POSITIONAL_OR_KEYWORD +_VAR_POSITIONAL = _ParameterKind.VAR_POSITIONAL +_KEYWORD_ONLY = _ParameterKind.KEYWORD_ONLY +_VAR_KEYWORD = _ParameterKind.VAR_KEYWORD class Parameter: - '''Represents a parameter in a function signature. + """Represents a parameter in a function signature. Has the following public attributes: @@ -1585,18 +2130,20 @@ class Parameter: The name of the parameter as a string. * default : object The default value for the parameter if specified. If the - parameter has no default value, this attribute is not set. + parameter has no default value, this attribute is set to + `Parameter.empty`. * annotation The annotation for the parameter if specified. If the - parameter has no annotation, this attribute is not set. + parameter has no annotation, this attribute is set to + `Parameter.empty`. * kind : str Describes how argument values are bound to the parameter. Possible values: `Parameter.POSITIONAL_ONLY`, `Parameter.POSITIONAL_OR_KEYWORD`, `Parameter.VAR_POSITIONAL`, `Parameter.KEYWORD_ONLY`, `Parameter.VAR_KEYWORD`. - ''' + """ - __slots__ = ('_name', '_kind', '_default', '_annotation', '_partial_kwarg') + __slots__ = ('_name', '_kind', '_default', '_annotation') POSITIONAL_ONLY = _POSITIONAL_ONLY POSITIONAL_OR_KEYWORD = _POSITIONAL_OR_KEYWORD @@ -1606,8 +2153,7 @@ class Parameter: empty = _empty - def __init__(self, name, kind, *, default=_empty, annotation=_empty, - _partial_kwarg=False): + def __init__(self, name, kind, *, default=_empty, annotation=_empty): if kind not in (_POSITIONAL_ONLY, _POSITIONAL_OR_KEYWORD, _VAR_POSITIONAL, _KEYWORD_ONLY, _VAR_KEYWORD): @@ -1621,19 +2167,26 @@ def __init__(self, name, kind, *, default=_empty, annotation=_empty, self._default = default self._annotation = annotation - if name is None: - if kind != _POSITIONAL_ONLY: - raise ValueError("None is not a valid name for a " - "non-positional-only parameter") - self._name = name - else: - name = str(name) - if kind != _POSITIONAL_ONLY and not name.isidentifier(): - msg = '{!r} is not a valid parameter name'.format(name) - raise ValueError(msg) - self._name = name + if name is _empty: + raise ValueError('name is a required attribute for Parameter') + + if not isinstance(name, str): + raise TypeError("name must be a str, not a {!r}".format(name)) + + if not name.isidentifier(): + raise ValueError('{!r} is not a valid parameter name'.format(name)) + + self._name = name + + def __reduce__(self): + return (type(self), + (self._name, self._kind), + {'_default': self._default, + '_annotation': self._annotation}) - self._partial_kwarg = _partial_kwarg + def __setstate__(self, state): + self._default = state['_default'] + self._annotation = state['_annotation'] @property def name(self): @@ -1651,9 +2204,9 @@ def annotation(self): def kind(self): return self._kind - def replace(self, *, name=_void, kind=_void, annotation=_void, - default=_void, _partial_kwarg=_void): - '''Creates a customized copy of the Parameter.''' + def replace(self, *, name=_void, kind=_void, + annotation=_void, default=_void): + """Creates a customized copy of the Parameter.""" if name is _void: name = self._name @@ -1667,20 +2220,11 @@ def replace(self, *, name=_void, kind=_void, annotation=_void, if default is _void: default = self._default - if _partial_kwarg is _void: - _partial_kwarg = self._partial_kwarg - - return type(self)(name, kind, default=default, annotation=annotation, - _partial_kwarg=_partial_kwarg) + return type(self)(name, kind, default=default, annotation=annotation) def __str__(self): kind = self.kind - formatted = self._name - if kind == _POSITIONAL_ONLY: - if formatted is None: - formatted = '' - formatted = '<{}>'.format(formatted) # Add annotation and default value if self._annotation is not _empty: @@ -1698,8 +2242,11 @@ def __str__(self): return formatted def __repr__(self): - return '<{} at {:#x} {!r}>'.format(self.__class__.__name__, - id(self), self.name) + return '<{} at {:#x} "{}">'.format(self.__class__.__name__, + id(self), self) + + def __hash__(self): + return hash((self.name, self.kind, self.annotation, self.default)) def __eq__(self, other): return (issubclass(other.__class__, Parameter) and @@ -1708,12 +2255,9 @@ def __eq__(self, other): self._default == other._default and self._annotation == other._annotation) - def __ne__(self, other): - return not self.__eq__(other) - class BoundArguments: - '''Result of `Signature.bind` call. Holds the mapping of arguments + """Result of `Signature.bind` call. Holds the mapping of arguments to the function's parameters. Has the following public attributes: @@ -1727,7 +2271,7 @@ class BoundArguments: Tuple of positional arguments values. * kwargs : dict Dict of keyword arguments values. - ''' + """ def __init__(self, signature, arguments): self.arguments = arguments @@ -1741,12 +2285,7 @@ def signature(self): def args(self): args = [] for param_name, param in self._signature.parameters.items(): - if (param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY) or - param._partial_kwarg): - # Keyword arguments mapped by 'functools.partial' - # (Parameter._partial_kwarg is True) are mapped - # in 'BoundArguments.kwargs', along with VAR_KEYWORD & - # KEYWORD_ONLY + if param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY): break try: @@ -1771,8 +2310,7 @@ def kwargs(self): kwargs_started = False for param_name, param in self._signature.parameters.items(): if not kwargs_started: - if (param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY) or - param._partial_kwarg): + if param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY): kwargs_started = True else: if param_name not in self.arguments: @@ -1801,12 +2339,9 @@ def __eq__(self, other): self.signature == other.signature and self.arguments == other.arguments) - def __ne__(self, other): - return not self.__eq__(other) - class Signature: - '''A Signature object represents the overall signature of a function. + """A Signature object represents the overall signature of a function. It stores a Parameter object for each parameter accepted by the function, as well as information specific to the function itself. @@ -1819,14 +2354,14 @@ class Signature: * return_annotation : object The annotation for the return type of the function if specified. If the function has no annotation for its return type, this - attribute is not set. + attribute is set to `Signature.empty`. * bind(*args, **kwargs) -> BoundArguments Creates a mapping from positional and keyword arguments to parameters. * bind_partial(*args, **kwargs) -> BoundArguments Creates a partial mapping from positional and keyword arguments to parameters (simulating 'functools.partial' behavior.) - ''' + """ __slots__ = ('_return_annotation', '_parameters') @@ -1837,9 +2372,9 @@ class Signature: def __init__(self, parameters=None, *, return_annotation=_empty, __validate_parameters__=True): - '''Constructs Signature from the given list of Parameter + """Constructs Signature from the given list of Parameter objects and 'return_annotation'. All arguments are optional. - ''' + """ if parameters is None: params = OrderedDict() @@ -1847,24 +2382,37 @@ def __init__(self, parameters=None, *, return_annotation=_empty, if __validate_parameters__: params = OrderedDict() top_kind = _POSITIONAL_ONLY + kind_defaults = False for idx, param in enumerate(parameters): kind = param.kind + name = param.name + if kind < top_kind: - msg = 'wrong parameter order: {} before {}' - msg = msg.format(top_kind, param.kind) + msg = 'wrong parameter order: {!r} before {!r}' + msg = msg.format(top_kind, kind) raise ValueError(msg) - else: + elif kind > top_kind: + kind_defaults = False top_kind = kind - name = param.name - if name is None: - name = str(idx) - param = param.replace(name=name) + if kind in (_POSITIONAL_ONLY, _POSITIONAL_OR_KEYWORD): + if param.default is _empty: + if kind_defaults: + # No default for this parameter, but the + # previous parameter of the same kind had + # a default + msg = 'non-default argument follows default ' \ + 'argument' + raise ValueError(msg) + else: + # There is a default for this parameter. + kind_defaults = True if name in params: msg = 'duplicate parameter name: {!r}'.format(name) raise ValueError(msg) + params[name] = param else: params = OrderedDict(((param.name, param) @@ -1875,10 +2423,16 @@ def __init__(self, parameters=None, *, return_annotation=_empty, @classmethod def from_function(cls, func): - '''Constructs Signature for the given python function''' + """Constructs Signature for the given python function.""" - if not isinstance(func, types.FunctionType): - raise TypeError('{!r} is not a Python function'.format(func)) + is_duck_function = False + if not isfunction(func): + if _signature_is_functionlike(func): + is_duck_function = True + else: + # If it's not a pure Python function, and not a duck type + # of pure function: + raise TypeError('{!r} is not a Python function'.format(func)) Parameter = cls._parameter_cls @@ -1915,7 +2469,7 @@ def from_function(cls, func): default=defaults[offset])) # *args - if func_code.co_flags & 0x04: + if func_code.co_flags & CO_VARARGS: name = arg_names[pos_count + keyword_only_count] annotation = annotations.get(name, _empty) parameters.append(Parameter(name, annotation=annotation, @@ -1932,9 +2486,9 @@ def from_function(cls, func): kind=_KEYWORD_ONLY, default=default)) # **kwargs - if func_code.co_flags & 0x08: + if func_code.co_flags & CO_VARKEYWORDS: index = pos_count + keyword_only_count - if func_code.co_flags & 0x04: + if func_code.co_flags & CO_VARARGS: index += 1 name = arg_names[index] @@ -1942,67 +2496,21 @@ def from_function(cls, func): parameters.append(Parameter(name, annotation=annotation, kind=_VAR_KEYWORD)) + # Is 'func' is a pure Python function - don't validate the + # parameters list (for correct order and defaults), it should be OK. return cls(parameters, return_annotation=annotations.get('return', _empty), - __validate_parameters__=False) + __validate_parameters__=is_duck_function) @classmethod def from_builtin(cls, func): - s = getattr(func, "__text_signature__", None) - if not s: - return None - - if s.endswith("/)"): - kind = Parameter.POSITIONAL_ONLY - s = s[:-2] + ')' - else: - kind = Parameter.POSITIONAL_OR_KEYWORD - - s = "def foo" + s + ": pass" - - try: - module = ast.parse(s) - except SyntaxError: - return None - if not isinstance(module, ast.Module): - return None - - # ast.FunctionDef - f = module.body[0] - - parameters = [] - empty = Parameter.empty - - def p(name_node, default_node, default=empty): - name = name_node.arg - - if isinstance(default_node, ast.Num): - default = default.n - elif isinstance(default_node, ast.NameConstant): - default = default_node.value - parameters.append(Parameter(name, kind, default=default, annotation=empty)) - - # non-keyword-only parameters - for name, default in reversed(list(itertools.zip_longest(reversed(f.args.args), reversed(f.args.defaults), fillvalue=None))): - p(name, default) - - # *args - if f.args.vararg: - kind = Parameter.VAR_POSITIONAL - p(f.args.vararg, empty) - - # keyword-only arguments - kind = Parameter.KEYWORD_ONLY - for name, default in zip(f.args.kwonlyargs, f.args.kw_defaults): - p(name, default) - - # **kwargs - if f.args.kwarg: - kind = Parameter.VAR_KEYWORD - p(f.args.kwarg, empty) - - return cls(parameters, return_annotation=cls.empty) + """Constructs Signature for the given builtin function.""" + return _signature_from_builtin(cls, func) + @classmethod + def from_callable(cls, obj): + """Constructs Signature for the given callable object.""" + return _signature_from_callable(obj, sigcls=cls) @property def parameters(self): @@ -2013,10 +2521,10 @@ def return_annotation(self): return self._return_annotation def replace(self, *, parameters=_void, return_annotation=_void): - '''Creates a customized copy of the Signature. + """Creates a customized copy of the Signature. Pass 'parameters' and/or 'return_annotation' arguments to override them in the new copy. - ''' + """ if parameters is _void: parameters = self.parameters.values() @@ -2027,41 +2535,26 @@ def replace(self, *, parameters=_void, return_annotation=_void): return type(self)(parameters, return_annotation=return_annotation) - def __eq__(self, other): - if (not issubclass(type(other), Signature) or - self.return_annotation != other.return_annotation or - len(self.parameters) != len(other.parameters)): - return False + def _hash_basis(self): + params = tuple(param for param in self.parameters.values() + if param.kind != _KEYWORD_ONLY) - other_positions = {param: idx - for idx, param in enumerate(other.parameters.keys())} + kwo_params = {param.name: param for param in self.parameters.values() + if param.kind == _KEYWORD_ONLY} - for idx, (param_name, param) in enumerate(self.parameters.items()): - if param.kind == _KEYWORD_ONLY: - try: - other_param = other.parameters[param_name] - except KeyError: - return False - else: - if param != other_param: - return False - else: - try: - other_idx = other_positions[param_name] - except KeyError: - return False - else: - if (idx != other_idx or - param != other.parameters[param_name]): - return False + return params, kwo_params, self.return_annotation - return True + def __hash__(self): + params, kwo_params, return_annotation = self._hash_basis() + kwo_params = frozenset(kwo_params.values()) + return hash((params, kwo_params, return_annotation)) - def __ne__(self, other): - return not self.__eq__(other) + def __eq__(self, other): + return (isinstance(other, Signature) and + self._hash_basis() == other._hash_basis()) def _bind(self, args, kwargs, *, partial=False): - '''Private method. Don't use directly.''' + """Private method. Don't use directly.""" arguments = OrderedDict() @@ -2069,15 +2562,6 @@ def _bind(self, args, kwargs, *, partial=False): parameters_ex = () arg_vals = iter(args) - if partial: - # Support for binding arguments to 'functools.partial' objects. - # See 'functools.partial' case in 'signature()' implementation - # for details. - for param_name, param in self.parameters.items(): - if (param._partial_kwarg and param_name not in kwargs): - # Simulating 'functools.partial' behavior - kwargs[param_name] = param.default - while True: # Let's iterate through the positional arguments and corresponding # parameters @@ -2112,6 +2596,8 @@ def _bind(self, args, kwargs, *, partial=False): parameters_ex = (param,) break else: + # No default, not VAR_KEYWORD, not VAR_POSITIONAL, + # not in `kwargs` if partial: parameters_ex = (param,) break @@ -2150,19 +2636,17 @@ def _bind(self, args, kwargs, *, partial=False): # keyword arguments kwargs_param = None for param in itertools.chain(parameters_ex, parameters): - if param.kind == _POSITIONAL_ONLY: - # This should never happen in case of a properly built - # Signature object (but let's have this check here - # to ensure correct behaviour just in case) - raise TypeError('{arg!r} parameter is positional only, ' - 'but was passed as a keyword'. \ - format(arg=param.name)) - if param.kind == _VAR_KEYWORD: # Memorize that we have a '**kwargs'-like parameter kwargs_param = param continue + if param.kind == _VAR_POSITIONAL: + # Named arguments don't refer to '*args'-like parameters. + # We only arrive here if the positional arguments ended + # before reaching the last parameter before *args. + continue + param_name = param.name try: arg_val = kwargs.pop(param_name) @@ -2177,6 +2661,14 @@ def _bind(self, args, kwargs, *, partial=False): format(arg=param_name)) from None else: + if param.kind == _POSITIONAL_ONLY: + # This should never happen in case of a properly built + # Signature object (but let's have this check here + # to ensure correct behaviour just in case) + raise TypeError('{arg!r} parameter is positional only, ' + 'but was passed as a keyword'. \ + format(arg=param.name)) + arguments[param_name] = arg_val if kwargs: @@ -2188,27 +2680,49 @@ def _bind(self, args, kwargs, *, partial=False): return self._bound_arguments_cls(self, arguments) - def bind(__bind_self, *args, **kwargs): - '''Get a BoundArguments object, that maps the passed `args` + def bind(*args, **kwargs): + """Get a BoundArguments object, that maps the passed `args` and `kwargs` to the function's signature. Raises `TypeError` if the passed arguments can not be bound. - ''' - return __bind_self._bind(args, kwargs) + """ + return args[0]._bind(args[1:], kwargs) - def bind_partial(__bind_self, *args, **kwargs): - '''Get a BoundArguments object, that partially maps the + def bind_partial(*args, **kwargs): + """Get a BoundArguments object, that partially maps the passed `args` and `kwargs` to the function's signature. Raises `TypeError` if the passed arguments can not be bound. - ''' - return __bind_self._bind(args, kwargs, partial=True) + """ + return args[0]._bind(args[1:], kwargs, partial=True) + + def __reduce__(self): + return (type(self), + (tuple(self._parameters.values()),), + {'_return_annotation': self._return_annotation}) + + def __setstate__(self, state): + self._return_annotation = state['_return_annotation'] + + def __repr__(self): + return '<{} at {:#x} "{}">'.format(self.__class__.__name__, + id(self), self) def __str__(self): result = [] + render_pos_only_separator = False render_kw_only_separator = True - for idx, param in enumerate(self.parameters.values()): + for param in self.parameters.values(): formatted = str(param) kind = param.kind + + if kind == _POSITIONAL_ONLY: + render_pos_only_separator = True + elif render_pos_only_separator: + # It's not a positional-only parameter, and the flag + # is set to 'True' (there were pos-only params before.) + result.append('/') + render_pos_only_separator = False + if kind == _VAR_POSITIONAL: # OK, we have an '*args'-like parameter, so we won't need # a '*' to separate keyword-only arguments @@ -2224,6 +2738,11 @@ def __str__(self): result.append(formatted) + if render_pos_only_separator: + # There were only positional-only parameters, hence the + # flag was not reset to 'False' + result.append('/') + rendered = '({})'.format(', '.join(result)) if self.return_annotation is not _empty: @@ -2232,6 +2751,12 @@ def __str__(self): return rendered + +def signature(obj): + """Get a signature object for the passed callable.""" + return Signature.from_callable(obj) + + def _main(): """ Logic for inspecting an object given at command line """ import argparse diff --git a/Lib/io.py b/Lib/io.py index 39878b83374b..8d68f1e42409 100644 --- a/Lib/io.py +++ b/Lib/io.py @@ -70,16 +70,16 @@ # Method descriptions and default implementations are inherited from the C # version however. class IOBase(_io._IOBase, metaclass=abc.ABCMeta): - pass + __doc__ = _io._IOBase.__doc__ class RawIOBase(_io._RawIOBase, IOBase): - pass + __doc__ = _io._RawIOBase.__doc__ class BufferedIOBase(_io._BufferedIOBase, IOBase): - pass + __doc__ = _io._BufferedIOBase.__doc__ class TextIOBase(_io._TextIOBase, IOBase): - pass + __doc__ = _io._TextIOBase.__doc__ RawIOBase.register(FileIO) diff --git a/Lib/ipaddress.py b/Lib/ipaddress.py index 97ff13dfd0a0..6c225f303709 100644 --- a/Lib/ipaddress.py +++ b/Lib/ipaddress.py @@ -164,22 +164,23 @@ def _split_optional_netmask(address): def _find_address_range(addresses): - """Find a sequence of IPv#Address. + """Find a sequence of sorted deduplicated IPv#Address. Args: addresses: a list of IPv#Address objects. - Returns: + Yields: A tuple containing the first and last IP addresses in the sequence. """ - first = last = addresses[0] - for ip in addresses[1:]: - if ip._ip == last._ip + 1: - last = ip - else: - break - return (first, last) + it = iter(addresses) + first = last = next(it) + for ip in it: + if ip._ip != last._ip + 1: + yield first, last + first = ip + last = ip + yield first, last def _count_righthand_zero_bits(number, bits): @@ -195,11 +196,7 @@ def _count_righthand_zero_bits(number, bits): """ if number == 0: return bits - for i in range(bits): - if (number >> i) & 1: - return i - # All bits of interest were zero, even if there are more in the number - return bits + return min(bits, (~number & (number-1)).bit_length()) def summarize_address_range(first, last): @@ -250,15 +247,14 @@ def summarize_address_range(first, last): while first_int <= last_int: nbits = min(_count_righthand_zero_bits(first_int, ip_bits), (last_int - first_int + 1).bit_length() - 1) - net = ip('%s/%d' % (first, ip_bits - nbits)) + net = ip((first_int, ip_bits - nbits)) yield net first_int += 1 << nbits if first_int - 1 == ip._ALL_ONES: break - first = first.__class__(first_int) -def _collapse_addresses_recursive(addresses): +def _collapse_addresses_internal(addresses): """Loops through the addresses, collapsing concurrent netblocks. Example: @@ -268,7 +264,7 @@ def _collapse_addresses_recursive(addresses): ip3 = IPv4Network('192.0.2.128/26') ip4 = IPv4Network('192.0.2.192/26') - _collapse_addresses_recursive([ip1, ip2, ip3, ip4]) -> + _collapse_addresses_internal([ip1, ip2, ip3, ip4]) -> [IPv4Network('192.0.2.0/24')] This shouldn't be called directly; it is called via @@ -282,28 +278,29 @@ def _collapse_addresses_recursive(addresses): passed. """ - while True: - last_addr = None - ret_array = [] - optimized = False - - for cur_addr in addresses: - if not ret_array: - last_addr = cur_addr - ret_array.append(cur_addr) - elif (cur_addr.network_address >= last_addr.network_address and - cur_addr.broadcast_address <= last_addr.broadcast_address): - optimized = True - elif cur_addr == list(last_addr.supernet().subnets())[1]: - ret_array[-1] = last_addr = last_addr.supernet() - optimized = True - else: - last_addr = cur_addr - ret_array.append(cur_addr) - - addresses = ret_array - if not optimized: - return addresses + # First merge + to_merge = list(addresses) + subnets = {} + while to_merge: + net = to_merge.pop() + supernet = net.supernet() + existing = subnets.get(supernet) + if existing is None: + subnets[supernet] = net + elif existing != net: + # Merge consecutive subnets + del subnets[supernet] + to_merge.append(supernet) + # Then iterate over resulting networks, skipping subsumed subnets + last = None + for net in sorted(subnets.values()): + if last is not None: + # Since they are sorted, last.network_address <= net.network_address + # is a given. + if last.broadcast_address >= net.broadcast_address: + continue + yield net + last = net def collapse_addresses(addresses): @@ -324,7 +321,6 @@ def collapse_addresses(addresses): TypeError: If passed a list of mixed version objects. """ - i = 0 addrs = [] ips = [] nets = [] @@ -352,15 +348,13 @@ def collapse_addresses(addresses): # sort and dedup ips = sorted(set(ips)) - nets = sorted(set(nets)) - while i < len(ips): - (first, last) = _find_address_range(ips[i:]) - i = ips.index(last) + 1 - addrs.extend(summarize_address_range(first, last)) + # find consecutive address ranges in the sorted sequence and summarize them + if ips: + for first, last in _find_address_range(ips): + addrs.extend(summarize_address_range(first, last)) - return iter(_collapse_addresses_recursive(sorted( - addrs + nets, key=_BaseNetwork._get_networks_key))) + return _collapse_addresses_internal(addrs + nets) def get_mixed_type_key(obj): @@ -388,40 +382,7 @@ def get_mixed_type_key(obj): return NotImplemented -class _TotalOrderingMixin: - # Helper that derives the other comparison operations from - # __lt__ and __eq__ - # We avoid functools.total_ordering because it doesn't handle - # NotImplemented correctly yet (http://bugs.python.org/issue10042) - def __eq__(self, other): - raise NotImplementedError - def __ne__(self, other): - equal = self.__eq__(other) - if equal is NotImplemented: - return NotImplemented - return not equal - def __lt__(self, other): - raise NotImplementedError - def __le__(self, other): - less = self.__lt__(other) - if less is NotImplemented or not less: - return self.__eq__(other) - return less - def __gt__(self, other): - less = self.__lt__(other) - if less is NotImplemented: - return NotImplemented - equal = self.__eq__(other) - if equal is NotImplemented: - return NotImplemented - return not (less or equal) - def __ge__(self, other): - less = self.__lt__(other) - if less is NotImplemented: - return NotImplemented - return not less - -class _IPAddressBase(_TotalOrderingMixin): +class _IPAddressBase: """The mother class.""" @@ -435,6 +396,17 @@ def compressed(self): """Return the shorthand version of the IP address as a string.""" return str(self) + @property + def reverse_pointer(self): + """The name of the reverse DNS pointer for the IP address, e.g.: + >>> ipaddress.ip_address("127.0.0.1").reverse_pointer + '1.0.0.127.in-addr.arpa' + >>> ipaddress.ip_address("2001:db8::1").reverse_pointer + '1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa' + + """ + return self._reverse_pointer() + @property def version(self): msg = '%200s has no version specified' % (type(self),) @@ -456,8 +428,9 @@ def _check_packed_address(self, address, expected_len): raise AddressValueError(msg % (address, address_len, expected_len, self._version)) - def _ip_int_from_prefix(self, prefixlen=None): - """Turn the prefix length netmask into a int for comparison. + @classmethod + def _ip_int_from_prefix(cls, prefixlen): + """Turn the prefix length into a bitwise netmask Args: prefixlen: An integer, the prefix length. @@ -466,52 +439,110 @@ def _ip_int_from_prefix(self, prefixlen=None): An integer. """ - if prefixlen is None: - prefixlen = self._prefixlen - return self._ALL_ONES ^ (self._ALL_ONES >> prefixlen) + return cls._ALL_ONES ^ (cls._ALL_ONES >> prefixlen) - def _prefix_from_ip_int(self, ip_int, mask=32): - """Return prefix length from the decimal netmask. + @classmethod + def _prefix_from_ip_int(cls, ip_int): + """Return prefix length from the bitwise netmask. Args: - ip_int: An integer, the IP address. - mask: The netmask. Defaults to 32. + ip_int: An integer, the netmask in expanded bitwise format Returns: An integer, the prefix length. + Raises: + ValueError: If the input intermingles zeroes & ones + """ + trailing_zeroes = _count_righthand_zero_bits(ip_int, + cls._max_prefixlen) + prefixlen = cls._max_prefixlen - trailing_zeroes + leading_ones = ip_int >> trailing_zeroes + all_ones = (1 << prefixlen) - 1 + if leading_ones != all_ones: + byteslen = cls._max_prefixlen // 8 + details = ip_int.to_bytes(byteslen, 'big') + msg = 'Netmask pattern %r mixes zeroes & ones' + raise ValueError(msg % details) + return prefixlen + + @classmethod + def _report_invalid_netmask(cls, netmask_str): + msg = '%r is not a valid netmask' % netmask_str + raise NetmaskValueError(msg) from None + + @classmethod + def _prefix_from_prefix_string(cls, prefixlen_str): + """Return prefix length from a numeric string + + Args: + prefixlen_str: The string to be converted + + Returns: + An integer, the prefix length. + + Raises: + NetmaskValueError: If the input is not a valid netmask """ - return mask - _count_righthand_zero_bits(ip_int, mask) + # int allows a leading +/- as well as surrounding whitespace, + # so we ensure that isn't the case + if not _BaseV4._DECIMAL_DIGITS.issuperset(prefixlen_str): + cls._report_invalid_netmask(prefixlen_str) + try: + prefixlen = int(prefixlen_str) + except ValueError: + cls._report_invalid_netmask(prefixlen_str) + if not (0 <= prefixlen <= cls._max_prefixlen): + cls._report_invalid_netmask(prefixlen_str) + return prefixlen - def _ip_string_from_prefix(self, prefixlen=None): - """Turn a prefix length into a dotted decimal string. + @classmethod + def _prefix_from_ip_string(cls, ip_str): + """Turn a netmask/hostmask string into a prefix length Args: - prefixlen: An integer, the netmask prefix length. + ip_str: The netmask/hostmask to be converted Returns: - A string, the dotted decimal netmask string. + An integer, the prefix length. + Raises: + NetmaskValueError: If the input is not a valid netmask/hostmask """ - if not prefixlen: - prefixlen = self._prefixlen - return self._string_from_ip_int(self._ip_int_from_prefix(prefixlen)) + # Parse the netmask/hostmask like an IP address. + try: + ip_int = cls._ip_int_from_string(ip_str) + except AddressValueError: + cls._report_invalid_netmask(ip_str) + # Try matching a netmask (this would be /1*0*/ as a bitwise regexp). + # Note that the two ambiguous cases (all-ones and all-zeroes) are + # treated as netmasks. + try: + return cls._prefix_from_ip_int(ip_int) + except ValueError: + pass + # Invert the bits, and try matching a /0+1+/ hostmask instead. + ip_int ^= cls._ALL_ONES + try: + return cls._prefix_from_ip_int(ip_int) + except ValueError: + cls._report_invalid_netmask(ip_str) + + def __reduce__(self): + return self.__class__, (str(self),) + + +@functools.total_ordering class _BaseAddress(_IPAddressBase): """A generic IP object. This IP class contains the version independent methods which are used by single IP addresses. - """ - def __init__(self, address): - if (not isinstance(address, bytes) - and '/' in str(address)): - raise AddressValueError("Unexpected '/' in %r" % address) - def __int__(self): return self._ip @@ -523,12 +554,11 @@ def __eq__(self, other): return NotImplemented def __lt__(self, other): + if not isinstance(other, _BaseAddress): + return NotImplemented if self._version != other._version: raise TypeError('%s and %s are not of the same version' % ( self, other)) - if not isinstance(other, _BaseAddress): - raise TypeError('%s and %s are not of the same type' % ( - self, other)) if self._ip != other._ip: return self._ip < other._ip return False @@ -557,7 +587,11 @@ def __hash__(self): def _get_address_key(self): return (self._version, self) + def __reduce__(self): + return self.__class__, (self._ip,) + +@functools.total_ordering class _BaseNetwork(_IPAddressBase): """A generic IP network object. @@ -607,12 +641,11 @@ def __getitem__(self, n): return self._address_class(broadcast + n) def __lt__(self, other): + if not isinstance(other, _BaseNetwork): + return NotImplemented if self._version != other._version: raise TypeError('%s and %s are not of the same version' % ( self, other)) - if not isinstance(other, _BaseNetwork): - raise TypeError('%s and %s are not of the same type' % ( - self, other)) if self.network_address != other.network_address: return self.network_address < other.network_address if self.netmask != other.netmask: @@ -743,7 +776,7 @@ def address_exclude(self, other): other.broadcast_address <= self.broadcast_address): raise ValueError('%s not contained in %s' % (other, self)) if other == self: - raise StopIteration + return # Make sure we're comparing the network of other. other = other.__class__('%s/%s' % (other.network_address, @@ -873,25 +906,16 @@ def subnets(self, prefixlen_diff=1, new_prefix=None): raise ValueError('prefix length diff must be > 0') new_prefixlen = self._prefixlen + prefixlen_diff - if not self._is_valid_netmask(str(new_prefixlen)): + if new_prefixlen > self._max_prefixlen: raise ValueError( 'prefix length diff %d is invalid for netblock %s' % ( new_prefixlen, self)) - first = self.__class__('%s/%s' % - (self.network_address, - self._prefixlen + prefixlen_diff)) - - yield first - current = first - while True: - broadcast = current.broadcast_address - if broadcast == self.broadcast_address: - return - new_addr = self._address_class(int(broadcast) + 1) - current = self.__class__('%s/%s' % (new_addr, - new_prefixlen)) - + start = int(self.network_address) + end = int(self.broadcast_address) + step = (int(self.hostmask) + 1) >> prefixlen_diff + for new_addr in range(start, end, step): + current = self.__class__((new_addr, new_prefixlen)) yield current def supernet(self, prefixlen_diff=1, new_prefix=None): @@ -925,15 +949,15 @@ def supernet(self, prefixlen_diff=1, new_prefix=None): raise ValueError('cannot set prefixlen_diff and new_prefix') prefixlen_diff = self._prefixlen - new_prefix - if self.prefixlen - prefixlen_diff < 0: + new_prefixlen = self.prefixlen - prefixlen_diff + if new_prefixlen < 0: raise ValueError( 'current prefixlen is %d, cannot have a prefixlen_diff of %d' % (self.prefixlen, prefixlen_diff)) - # TODO (pmoody): optimize this. - t = self.__class__('%s/%d' % (self.network_address, - self.prefixlen - prefixlen_diff), - strict=False) - return t.__class__('%s/%d' % (t.network_address, t.prefixlen)) + return self.__class__(( + int(self.network_address) & (int(self.netmask) << prefixlen_diff), + new_prefixlen + )) @property def is_multicast(self): @@ -1032,16 +1056,45 @@ class _BaseV4: _DECIMAL_DIGITS = frozenset('0123456789') # the valid octets for host and netmasks. only useful for IPv4. - _valid_mask_octets = frozenset((255, 254, 252, 248, 240, 224, 192, 128, 0)) + _valid_mask_octets = frozenset({255, 254, 252, 248, 240, 224, 192, 128, 0}) + + _max_prefixlen = IPV4LENGTH + # There are only a handful of valid v4 netmasks, so we cache them all + # when constructed (see _make_netmask()). + _netmask_cache = {} def __init__(self, address): self._version = 4 - self._max_prefixlen = IPV4LENGTH def _explode_shorthand_ip_string(self): return str(self) - def _ip_int_from_string(self, ip_str): + @classmethod + def _make_netmask(cls, arg): + """Make a (netmask, prefix_len) tuple from the given argument. + + Argument can be: + - an integer (the prefix length) + - a string representing the prefix length (e.g. "24") + - a string representing the prefix netmask (e.g. "255.255.255.0") + """ + if arg not in cls._netmask_cache: + if isinstance(arg, int): + prefixlen = arg + else: + try: + # Check for a netmask in prefix length form + prefixlen = cls._prefix_from_prefix_string(arg) + except NetmaskValueError: + # Check for a netmask or hostmask in dotted-quad form. + # This may raise NetmaskValueError. + prefixlen = cls._prefix_from_ip_string(arg) + netmask = IPv4Address(cls._ip_int_from_prefix(prefixlen)) + cls._netmask_cache[arg] = netmask, prefixlen + return cls._netmask_cache[arg] + + @classmethod + def _ip_int_from_string(cls, ip_str): """Turn the given IP string into an integer for comparison. Args: @@ -1062,11 +1115,12 @@ def _ip_int_from_string(self, ip_str): raise AddressValueError("Expected 4 octets in %r" % ip_str) try: - return int.from_bytes(map(self._parse_octet, octets), 'big') + return int.from_bytes(map(cls._parse_octet, octets), 'big') except ValueError as exc: raise AddressValueError("%s in %r" % (exc, ip_str)) from None - def _parse_octet(self, octet_str): + @classmethod + def _parse_octet(cls, octet_str): """Convert a decimal octet into an integer. Args: @@ -1082,7 +1136,7 @@ def _parse_octet(self, octet_str): if not octet_str: raise ValueError("Empty octet not permitted") # Whitelist the characters, since int() allows a lot of bizarre stuff. - if not self._DECIMAL_DIGITS.issuperset(octet_str): + if not cls._DECIMAL_DIGITS.issuperset(octet_str): msg = "Only decimal digits permitted in %r" raise ValueError(msg % octet_str) # We do the length check second, since the invalid character error @@ -1102,7 +1156,8 @@ def _parse_octet(self, octet_str): raise ValueError("Octet %d (> 255) not permitted" % octet_int) return octet_int - def _string_from_ip_int(self, ip_int): + @classmethod + def _string_from_ip_int(cls, ip_int): """Turns a 32-bit integer into dotted decimal notation. Args: @@ -1166,6 +1221,15 @@ def _is_hostmask(self, ip_str): return True return False + def _reverse_pointer(self): + """Return the reverse DNS pointer name for the IPv4 address. + + This implements the method described in RFC1035 3.5. + + """ + reverse_octets = str(self).split('.')[::-1] + return '.'.join(reverse_octets) + '.in-addr.arpa' + @property def max_prefixlen(self): return self._max_prefixlen @@ -1195,7 +1259,6 @@ def __init__(self, address): AddressValueError: If ipaddress isn't a valid IPv4 address. """ - _BaseAddress.__init__(self, address) _BaseV4.__init__(self, address) # Efficient constructor from integer. @@ -1213,6 +1276,8 @@ def __init__(self, address): # Assume input argument to be string or any object representation # which converts into a formatted IP string. addr_str = str(address) + if '/' in addr_str: + raise AddressValueError("Unexpected '/' in %r" % address) self._ip = self._ip_int_from_string(addr_str) @property @@ -1229,8 +1294,7 @@ def is_reserved(self): reserved IPv4 Network range. """ - reserved_network = IPv4Network('240.0.0.0/4') - return self in reserved_network + return self in self._constants._reserved_network @property @functools.lru_cache() @@ -1242,21 +1306,7 @@ def is_private(self): iana-ipv4-special-registry. """ - return (self in IPv4Network('0.0.0.0/8') or - self in IPv4Network('10.0.0.0/8') or - self in IPv4Network('127.0.0.0/8') or - self in IPv4Network('169.254.0.0/16') or - self in IPv4Network('172.16.0.0/12') or - self in IPv4Network('192.0.0.0/29') or - self in IPv4Network('192.0.0.170/31') or - self in IPv4Network('192.0.2.0/24') or - self in IPv4Network('192.168.0.0/16') or - self in IPv4Network('198.18.0.0/15') or - self in IPv4Network('198.51.100.0/24') or - self in IPv4Network('203.0.113.0/24') or - self in IPv4Network('240.0.0.0/4') or - self in IPv4Network('255.255.255.255/32')) - + return any(self in net for net in self._constants._private_networks) @property def is_multicast(self): @@ -1267,8 +1317,7 @@ def is_multicast(self): See RFC 3171 for details. """ - multicast_network = IPv4Network('224.0.0.0/4') - return self in multicast_network + return self in self._constants._multicast_network @property def is_unspecified(self): @@ -1279,8 +1328,7 @@ def is_unspecified(self): RFC 5735 3. """ - unspecified_address = IPv4Address('0.0.0.0') - return self == unspecified_address + return self == self._constants._unspecified_address @property def is_loopback(self): @@ -1290,8 +1338,7 @@ def is_loopback(self): A boolean, True if the address is a loopback per RFC 3330. """ - loopback_network = IPv4Network('127.0.0.0/8') - return self in loopback_network + return self in self._constants._loopback_network @property def is_link_local(self): @@ -1301,8 +1348,7 @@ def is_link_local(self): A boolean, True if the address is link-local per RFC 3927. """ - linklocal_network = IPv4Network('169.254.0.0/16') - return self in linklocal_network + return self in self._constants._linklocal_network class IPv4Interface(IPv4Address): @@ -1314,6 +1360,18 @@ def __init__(self, address): self._prefixlen = self._max_prefixlen return + if isinstance(address, tuple): + IPv4Address.__init__(self, address[0]) + if len(address) > 1: + self._prefixlen = int(address[1]) + else: + self._prefixlen = self._max_prefixlen + + self.network = IPv4Network(address, strict=False) + self.netmask = self.network.netmask + self.hostmask = self.network.hostmask + return + addr = _split_optional_netmask(address) IPv4Address.__init__(self, addr[0]) @@ -1353,6 +1411,8 @@ def __lt__(self, other): def __hash__(self): return self._ip ^ self._prefixlen ^ int(self.network.network_address) + __reduce__ = _IPAddressBase.__reduce__ + @property def ip(self): return IPv4Address(self._ip) @@ -1429,20 +1489,28 @@ def __init__(self, address, strict=True): _BaseV4.__init__(self, address) _BaseNetwork.__init__(self, address) - # Constructing from a packed address - if isinstance(address, bytes): + # Constructing from a packed address or integer + if isinstance(address, (int, bytes)): self.network_address = IPv4Address(address) - self._prefixlen = self._max_prefixlen - self.netmask = IPv4Address(self._ALL_ONES) - #fixme: address/network test here + self.netmask, self._prefixlen = self._make_netmask(self._max_prefixlen) + #fixme: address/network test here. return - # Efficient constructor from integer. - if isinstance(address, int): - self.network_address = IPv4Address(address) - self._prefixlen = self._max_prefixlen - self.netmask = IPv4Address(self._ALL_ONES) - #fixme: address/network test here. + if isinstance(address, tuple): + if len(address) > 1: + arg = address[1] + else: + # We weren't given an address[1] + arg = self._max_prefixlen + self.network_address = IPv4Address(address[0]) + self.netmask, self._prefixlen = self._make_netmask(arg) + packed = int(self.network_address) + if packed & int(self.netmask) != packed: + if strict: + raise ValueError('%s has host bits set' % self) + else: + self.network_address = IPv4Address(packed & + int(self.netmask)) return # Assume input argument to be string or any object representation @@ -1451,33 +1519,10 @@ def __init__(self, address, strict=True): self.network_address = IPv4Address(self._ip_int_from_string(addr[0])) if len(addr) == 2: - mask = addr[1].split('.') - - if len(mask) == 4: - # We have dotted decimal netmask. - if self._is_valid_netmask(addr[1]): - self.netmask = IPv4Address(self._ip_int_from_string( - addr[1])) - elif self._is_hostmask(addr[1]): - self.netmask = IPv4Address( - self._ip_int_from_string(addr[1]) ^ self._ALL_ONES) - else: - raise NetmaskValueError('%r is not a valid netmask' - % addr[1]) - - self._prefixlen = self._prefix_from_ip_int(int(self.netmask)) - else: - # We have a netmask in prefix length form. - if not self._is_valid_netmask(addr[1]): - raise NetmaskValueError('%r is not a valid netmask' - % addr[1]) - self._prefixlen = int(addr[1]) - self.netmask = IPv4Address(self._ip_int_from_prefix( - self._prefixlen)) + arg = addr[1] else: - self._prefixlen = self._max_prefixlen - self.netmask = IPv4Address(self._ip_int_from_prefix( - self._prefixlen)) + arg = self._max_prefixlen + self.netmask, self._prefixlen = self._make_netmask(arg) if strict: if (IPv4Address(int(self.network_address) & int(self.netmask)) != @@ -1504,6 +1549,37 @@ def is_global(self): not self.is_private) +class _IPv4Constants: + _linklocal_network = IPv4Network('169.254.0.0/16') + + _loopback_network = IPv4Network('127.0.0.0/8') + + _multicast_network = IPv4Network('224.0.0.0/4') + + _private_networks = [ + IPv4Network('0.0.0.0/8'), + IPv4Network('10.0.0.0/8'), + IPv4Network('127.0.0.0/8'), + IPv4Network('169.254.0.0/16'), + IPv4Network('172.16.0.0/12'), + IPv4Network('192.0.0.0/29'), + IPv4Network('192.0.0.170/31'), + IPv4Network('192.0.2.0/24'), + IPv4Network('192.168.0.0/16'), + IPv4Network('198.18.0.0/15'), + IPv4Network('198.51.100.0/24'), + IPv4Network('203.0.113.0/24'), + IPv4Network('240.0.0.0/4'), + IPv4Network('255.255.255.255/32'), + ] + + _reserved_network = IPv4Network('240.0.0.0/4') + + _unspecified_address = IPv4Address('0.0.0.0') + + +IPv4Address._constants = _IPv4Constants + class _BaseV6: @@ -1517,12 +1593,35 @@ class _BaseV6: _ALL_ONES = (2**IPV6LENGTH) - 1 _HEXTET_COUNT = 8 _HEX_DIGITS = frozenset('0123456789ABCDEFabcdef') + _max_prefixlen = IPV6LENGTH + + # There are only a bunch of valid v6 netmasks, so we cache them all + # when constructed (see _make_netmask()). + _netmask_cache = {} def __init__(self, address): self._version = 6 - self._max_prefixlen = IPV6LENGTH - def _ip_int_from_string(self, ip_str): + @classmethod + def _make_netmask(cls, arg): + """Make a (netmask, prefix_len) tuple from the given argument. + + Argument can be: + - an integer (the prefix length) + - a string representing the prefix length (e.g. "24") + - a string representing the prefix netmask (e.g. "255.255.255.0") + """ + if arg not in cls._netmask_cache: + if isinstance(arg, int): + prefixlen = arg + else: + prefixlen = cls._prefix_from_prefix_string(arg) + netmask = IPv6Address(cls._ip_int_from_prefix(prefixlen)) + cls._netmask_cache[arg] = netmask, prefixlen + return cls._netmask_cache[arg] + + @classmethod + def _ip_int_from_string(cls, ip_str): """Turn an IPv6 ip_str into an integer. Args: @@ -1558,7 +1657,7 @@ def _ip_int_from_string(self, ip_str): # An IPv6 address can't have more than 8 colons (9 parts). # The extra colon comes from using the "::" notation for a single # leading or trailing zero part. - _max_parts = self._HEXTET_COUNT + 1 + _max_parts = cls._HEXTET_COUNT + 1 if len(parts) > _max_parts: msg = "At most %d colons permitted in %r" % (_max_parts-1, ip_str) raise AddressValueError(msg) @@ -1590,17 +1689,17 @@ def _ip_int_from_string(self, ip_str): if parts_lo: msg = "Trailing ':' only permitted as part of '::' in %r" raise AddressValueError(msg % ip_str) # :$ requires ::$ - parts_skipped = self._HEXTET_COUNT - (parts_hi + parts_lo) + parts_skipped = cls._HEXTET_COUNT - (parts_hi + parts_lo) if parts_skipped < 1: msg = "Expected at most %d other parts with '::' in %r" - raise AddressValueError(msg % (self._HEXTET_COUNT-1, ip_str)) + raise AddressValueError(msg % (cls._HEXTET_COUNT-1, ip_str)) else: # Otherwise, allocate the entire address to parts_hi. The # endpoints could still be empty, but _parse_hextet() will check # for that. - if len(parts) != self._HEXTET_COUNT: + if len(parts) != cls._HEXTET_COUNT: msg = "Exactly %d parts expected without '::' in %r" - raise AddressValueError(msg % (self._HEXTET_COUNT, ip_str)) + raise AddressValueError(msg % (cls._HEXTET_COUNT, ip_str)) if not parts[0]: msg = "Leading ':' only permitted as part of '::' in %r" raise AddressValueError(msg % ip_str) # ^: requires ^:: @@ -1616,16 +1715,17 @@ def _ip_int_from_string(self, ip_str): ip_int = 0 for i in range(parts_hi): ip_int <<= 16 - ip_int |= self._parse_hextet(parts[i]) + ip_int |= cls._parse_hextet(parts[i]) ip_int <<= 16 * parts_skipped for i in range(-parts_lo, 0): ip_int <<= 16 - ip_int |= self._parse_hextet(parts[i]) + ip_int |= cls._parse_hextet(parts[i]) return ip_int except ValueError as exc: raise AddressValueError("%s in %r" % (exc, ip_str)) from None - def _parse_hextet(self, hextet_str): + @classmethod + def _parse_hextet(cls, hextet_str): """Convert an IPv6 hextet string into an integer. Args: @@ -1640,7 +1740,7 @@ def _parse_hextet(self, hextet_str): """ # Whitelist the characters, since int() allows a lot of bizarre stuff. - if not self._HEX_DIGITS.issuperset(hextet_str): + if not cls._HEX_DIGITS.issuperset(hextet_str): raise ValueError("Only hex digits permitted in %r" % hextet_str) # We do the length check second, since the invalid character error # is likely to be more informative for the user @@ -1650,7 +1750,8 @@ def _parse_hextet(self, hextet_str): # Length check means we can skip checking the integer value return int(hextet_str, 16) - def _compress_hextets(self, hextets): + @classmethod + def _compress_hextets(cls, hextets): """Compresses a list of hextets. Compresses a list of strings, replacing the longest continuous @@ -1697,7 +1798,8 @@ def _compress_hextets(self, hextets): return hextets - def _string_from_ip_int(self, ip_int=None): + @classmethod + def _string_from_ip_int(cls, ip_int=None): """Turns a 128-bit integer into hexadecimal notation. Args: @@ -1711,15 +1813,15 @@ def _string_from_ip_int(self, ip_int=None): """ if ip_int is None: - ip_int = int(self._ip) + ip_int = int(cls._ip) - if ip_int > self._ALL_ONES: + if ip_int > cls._ALL_ONES: raise ValueError('IPv6 address is too large') hex_str = '%032x' % ip_int hextets = ['%x' % int(hex_str[x:x+4], 16) for x in range(0, 32, 4)] - hextets = self._compress_hextets(hextets) + hextets = cls._compress_hextets(hextets) return ':'.join(hextets) def _explode_shorthand_ip_string(self): @@ -1746,6 +1848,15 @@ def _explode_shorthand_ip_string(self): return '%s/%d' % (':'.join(parts), self._prefixlen) return ':'.join(parts) + def _reverse_pointer(self): + """Return the reverse DNS pointer name for the IPv6 address. + + This implements the method described in RFC3596 2.5. + + """ + reverse_chars = self.exploded[::-1].replace(':', '') + return '.'.join(reverse_chars) + '.ip6.arpa' + @property def max_prefixlen(self): return self._max_prefixlen @@ -1776,7 +1887,6 @@ def __init__(self, address): AddressValueError: If address isn't a valid IPv6 address. """ - _BaseAddress.__init__(self, address) _BaseV6.__init__(self, address) # Efficient constructor from integer. @@ -1794,6 +1904,8 @@ def __init__(self, address): # Assume input argument to be string or any object representation # which converts into a formatted IP string. addr_str = str(address) + if '/' in addr_str: + raise AddressValueError("Unexpected '/' in %r" % address) self._ip = self._ip_int_from_string(addr_str) @property @@ -1810,8 +1922,7 @@ def is_multicast(self): See RFC 2373 2.7 for details. """ - multicast_network = IPv6Network('ff00::/8') - return self in multicast_network + return self in self._constants._multicast_network @property def is_reserved(self): @@ -1822,16 +1933,7 @@ def is_reserved(self): reserved IPv6 Network ranges. """ - reserved_networks = [IPv6Network('::/8'), IPv6Network('100::/8'), - IPv6Network('200::/7'), IPv6Network('400::/6'), - IPv6Network('800::/5'), IPv6Network('1000::/4'), - IPv6Network('4000::/3'), IPv6Network('6000::/3'), - IPv6Network('8000::/3'), IPv6Network('A000::/3'), - IPv6Network('C000::/3'), IPv6Network('E000::/4'), - IPv6Network('F000::/5'), IPv6Network('F800::/6'), - IPv6Network('FE00::/9')] - - return any(self in x for x in reserved_networks) + return any(self in x for x in self._constants._reserved_networks) @property def is_link_local(self): @@ -1841,8 +1943,7 @@ def is_link_local(self): A boolean, True if the address is reserved per RFC 4291. """ - linklocal_network = IPv6Network('fe80::/10') - return self in linklocal_network + return self in self._constants._linklocal_network @property def is_site_local(self): @@ -1856,8 +1957,7 @@ def is_site_local(self): A boolean, True if the address is reserved per RFC 3513 2.5.6. """ - sitelocal_network = IPv6Network('fec0::/10') - return self in sitelocal_network + return self in self._constants._sitelocal_network @property @functools.lru_cache() @@ -1869,16 +1969,7 @@ def is_private(self): iana-ipv6-special-registry. """ - return (self in IPv6Network('::1/128') or - self in IPv6Network('::/128') or - self in IPv6Network('::ffff:0:0/96') or - self in IPv6Network('100::/64') or - self in IPv6Network('2001::/23') or - self in IPv6Network('2001:2::/48') or - self in IPv6Network('2001:db8::/32') or - self in IPv6Network('2001:10::/28') or - self in IPv6Network('fc00::/7') or - self in IPv6Network('fe80::/10')) + return any(self in net for net in self._constants._private_networks) @property def is_global(self): @@ -1963,6 +2054,16 @@ def __init__(self, address): self.network = IPv6Network(self._ip) self._prefixlen = self._max_prefixlen return + if isinstance(address, tuple): + IPv6Address.__init__(self, address[0]) + if len(address) > 1: + self._prefixlen = int(address[1]) + else: + self._prefixlen = self._max_prefixlen + self.network = IPv6Network(address, strict=False) + self.netmask = self.network.netmask + self.hostmask = self.network.hostmask + return addr = _split_optional_netmask(address) IPv6Address.__init__(self, addr[0]) @@ -2001,6 +2102,8 @@ def __lt__(self, other): def __hash__(self): return self._ip ^ self._prefixlen ^ int(self.network.network_address) + __reduce__ = _IPAddressBase.__reduce__ + @property def ip(self): return IPv6Address(self._ip) @@ -2080,18 +2183,26 @@ def __init__(self, address, strict=True): _BaseV6.__init__(self, address) _BaseNetwork.__init__(self, address) - # Efficient constructor from integer. - if isinstance(address, int): + # Efficient constructor from integer or packed address + if isinstance(address, (bytes, int)): self.network_address = IPv6Address(address) - self._prefixlen = self._max_prefixlen - self.netmask = IPv6Address(self._ALL_ONES) + self.netmask, self._prefixlen = self._make_netmask(self._max_prefixlen) return - # Constructing from a packed address - if isinstance(address, bytes): - self.network_address = IPv6Address(address) - self._prefixlen = self._max_prefixlen - self.netmask = IPv6Address(self._ALL_ONES) + if isinstance(address, tuple): + if len(address) > 1: + arg = address[1] + else: + arg = self._max_prefixlen + self.netmask, self._prefixlen = self._make_netmask(arg) + self.network_address = IPv6Address(address[0]) + packed = int(self.network_address) + if packed & int(self.netmask) != packed: + if strict: + raise ValueError('%s has host bits set' % self) + else: + self.network_address = IPv6Address(packed & + int(self.netmask)) return # Assume input argument to be string or any object representation @@ -2101,15 +2212,11 @@ def __init__(self, address, strict=True): self.network_address = IPv6Address(self._ip_int_from_string(addr[0])) if len(addr) == 2: - if self._is_valid_netmask(addr[1]): - self._prefixlen = int(addr[1]) - else: - raise NetmaskValueError('%r is not a valid netmask' - % addr[1]) + arg = addr[1] else: - self._prefixlen = self._max_prefixlen + arg = self._max_prefixlen + self.netmask, self._prefixlen = self._make_netmask(arg) - self.netmask = IPv6Address(self._ip_int_from_prefix(self._prefixlen)) if strict: if (IPv6Address(int(self.network_address) & int(self.netmask)) != self.network_address): @@ -2120,22 +2227,17 @@ def __init__(self, address, strict=True): if self._prefixlen == (self._max_prefixlen - 1): self.hosts = self.__iter__ - def _is_valid_netmask(self, prefixlen): - """Verify that the netmask/prefixlen is valid. + def hosts(self): + """Generate Iterator over usable hosts in a network. - Args: - prefixlen: A string, the netmask in prefix length format. - - Returns: - A boolean, True if the prefix represents a valid IPv6 - netmask. + This is like __iter__ except it doesn't return the + Subnet-Router anycast address. """ - try: - prefixlen = int(prefixlen) - except ValueError: - return False - return 0 <= prefixlen <= self._max_prefixlen + network = int(self.network_address) + broadcast = int(self.broadcast_address) + for x in range(network + 1, broadcast + 1): + yield self._address_class(x) @property def is_site_local(self): @@ -2151,3 +2253,39 @@ def is_site_local(self): """ return (self.network_address.is_site_local and self.broadcast_address.is_site_local) + + +class _IPv6Constants: + + _linklocal_network = IPv6Network('fe80::/10') + + _multicast_network = IPv6Network('ff00::/8') + + _private_networks = [ + IPv6Network('::1/128'), + IPv6Network('::/128'), + IPv6Network('::ffff:0:0/96'), + IPv6Network('100::/64'), + IPv6Network('2001::/23'), + IPv6Network('2001:2::/48'), + IPv6Network('2001:db8::/32'), + IPv6Network('2001:10::/28'), + IPv6Network('fc00::/7'), + IPv6Network('fe80::/10'), + ] + + _reserved_networks = [ + IPv6Network('::/8'), IPv6Network('100::/8'), + IPv6Network('200::/7'), IPv6Network('400::/6'), + IPv6Network('800::/5'), IPv6Network('1000::/4'), + IPv6Network('4000::/3'), IPv6Network('6000::/3'), + IPv6Network('8000::/3'), IPv6Network('A000::/3'), + IPv6Network('C000::/3'), IPv6Network('E000::/4'), + IPv6Network('F000::/5'), IPv6Network('F800::/6'), + IPv6Network('FE00::/9'), + ] + + _sitelocal_network = IPv6Network('fec0::/10') + + +IPv6Address._constants = _IPv6Constants diff --git a/Lib/json/__init__.py b/Lib/json/__init__.py index a459f77a7b4d..6ce9880b2621 100644 --- a/Lib/json/__init__.py +++ b/Lib/json/__init__.py @@ -3,11 +3,8 @@ interchange format. :mod:`json` exposes an API familiar to users of the standard library -:mod:`marshal` and :mod:`pickle` modules. It is the externally maintained -version of the :mod:`json` library contained in Python 2.6, but maintains -compatibility with Python 2.4 and Python 2.5 and (currently) has -significant performance advantages, even without using the optional C -extension for speedups. +:mod:`marshal` and :mod:`pickle` modules. It is derived from a +version of the externally maintained simplejson library. Encoding basic Python object hierarchies:: @@ -101,12 +98,12 @@ __version__ = '2.0.9' __all__ = [ 'dump', 'dumps', 'load', 'loads', - 'JSONDecoder', 'JSONEncoder', + 'JSONDecoder', 'JSONDecodeError', 'JSONEncoder', ] __author__ = 'Bob Ippolito <bob@redivi.com>' -from .decoder import JSONDecoder +from .decoder import JSONDecoder, JSONDecodeError from .encoder import JSONEncoder _default_encoder = JSONEncoder( @@ -314,7 +311,8 @@ def loads(s, encoding=None, cls=None, object_hook=None, parse_float=None, raise TypeError('the JSON object must be str, not {!r}'.format( s.__class__.__name__)) if s.startswith(u'\ufeff'): - raise ValueError("Unexpected UTF-8 BOM (decode using utf-8-sig)") + raise JSONDecodeError("Unexpected UTF-8 BOM (decode using utf-8-sig)", + s, 0) if (cls is None and object_hook is None and parse_int is None and parse_float is None and parse_constant is None and object_pairs_hook is None and not kw): diff --git a/Lib/json/decoder.py b/Lib/json/decoder.py index 59e5f41f4dc1..0f03f20042b8 100644 --- a/Lib/json/decoder.py +++ b/Lib/json/decoder.py @@ -8,7 +8,7 @@ except ImportError: c_scanstring = None -__all__ = ['JSONDecoder'] +__all__ = ['JSONDecoder', 'JSONDecodeError'] FLAGS = re.VERBOSE | re.MULTILINE | re.DOTALL @@ -17,32 +17,30 @@ NegInf = float('-inf') -def linecol(doc, pos): - if isinstance(doc, bytes): - newline = b'\n' - else: - newline = '\n' - lineno = doc.count(newline, 0, pos) + 1 - if lineno == 1: - colno = pos + 1 - else: - colno = pos - doc.rindex(newline, 0, pos) - return lineno, colno - - -def errmsg(msg, doc, pos, end=None): - # Note that this function is called from _json - lineno, colno = linecol(doc, pos) - if end is None: - fmt = '{0}: line {1} column {2} (char {3})' - return fmt.format(msg, lineno, colno, pos) - #fmt = '%s: line %d column %d (char %d)' - #return fmt % (msg, lineno, colno, pos) - endlineno, endcolno = linecol(doc, end) - fmt = '{0}: line {1} column {2} - line {3} column {4} (char {5} - {6})' - return fmt.format(msg, lineno, colno, endlineno, endcolno, pos, end) - #fmt = '%s: line %d column %d - line %d column %d (char %d - %d)' - #return fmt % (msg, lineno, colno, endlineno, endcolno, pos, end) +class JSONDecodeError(ValueError): + """Subclass of ValueError with the following additional properties: + + msg: The unformatted error message + doc: The JSON document being parsed + pos: The start index of doc where parsing failed + lineno: The line corresponding to pos + colno: The column corresponding to pos + + """ + # Note that this exception is used from _json + def __init__(self, msg, doc, pos): + lineno = doc.count('\n', 0, pos) + 1 + colno = pos - doc.rfind('\n', 0, pos) + errmsg = '%s: line %d column %d (char %d)' % (msg, lineno, colno, pos) + ValueError.__init__(self, errmsg) + self.msg = msg + self.doc = doc + self.pos = pos + self.lineno = lineno + self.colno = colno + + def __reduce__(self): + return self.__class__, (self.msg, self.doc, self.pos) _CONSTANTS = { @@ -66,7 +64,7 @@ def _decode_uXXXX(s, pos): except ValueError: pass msg = "Invalid \\uXXXX escape" - raise ValueError(errmsg(msg, s, pos)) + raise JSONDecodeError(msg, s, pos) def py_scanstring(s, end, strict=True, _b=BACKSLASH, _m=STRINGCHUNK.match): @@ -84,8 +82,7 @@ def py_scanstring(s, end, strict=True, while 1: chunk = _m(s, end) if chunk is None: - raise ValueError( - errmsg("Unterminated string starting at", s, begin)) + raise JSONDecodeError("Unterminated string starting at", s, begin) end = chunk.end() content, terminator = chunk.groups() # Content is contains zero or more unescaped string characters @@ -99,22 +96,21 @@ def py_scanstring(s, end, strict=True, if strict: #msg = "Invalid control character %r at" % (terminator,) msg = "Invalid control character {0!r} at".format(terminator) - raise ValueError(errmsg(msg, s, end)) + raise JSONDecodeError(msg, s, end) else: _append(terminator) continue try: esc = s[end] except IndexError: - raise ValueError( - errmsg("Unterminated string starting at", s, begin)) + raise JSONDecodeError("Unterminated string starting at", s, begin) # If not a unicode escape sequence, must be in the lookup table if esc != 'u': try: char = _b[esc] except KeyError: msg = "Invalid \\escape: {0!r}".format(esc) - raise ValueError(errmsg(msg, s, end)) + raise JSONDecodeError(msg, s, end) end += 1 else: uni = _decode_uXXXX(s, end) @@ -163,8 +159,8 @@ def JSONObject(s_and_end, strict, scan_once, object_hook, object_pairs_hook, pairs = object_hook(pairs) return pairs, end + 1 elif nextchar != '"': - raise ValueError(errmsg( - "Expecting property name enclosed in double quotes", s, end)) + raise JSONDecodeError( + "Expecting property name enclosed in double quotes", s, end) end += 1 while True: key, end = scanstring(s, end, strict) @@ -174,7 +170,7 @@ def JSONObject(s_and_end, strict, scan_once, object_hook, object_pairs_hook, if s[end:end + 1] != ':': end = _w(s, end).end() if s[end:end + 1] != ':': - raise ValueError(errmsg("Expecting ':' delimiter", s, end)) + raise JSONDecodeError("Expecting ':' delimiter", s, end) end += 1 try: @@ -188,7 +184,7 @@ def JSONObject(s_and_end, strict, scan_once, object_hook, object_pairs_hook, try: value, end = scan_once(s, end) except StopIteration as err: - raise ValueError(errmsg("Expecting value", s, err.value)) from None + raise JSONDecodeError("Expecting value", s, err.value) from None pairs_append((key, value)) try: nextchar = s[end] @@ -202,13 +198,13 @@ def JSONObject(s_and_end, strict, scan_once, object_hook, object_pairs_hook, if nextchar == '}': break elif nextchar != ',': - raise ValueError(errmsg("Expecting ',' delimiter", s, end - 1)) + raise JSONDecodeError("Expecting ',' delimiter", s, end - 1) end = _w(s, end).end() nextchar = s[end:end + 1] end += 1 if nextchar != '"': - raise ValueError(errmsg( - "Expecting property name enclosed in double quotes", s, end - 1)) + raise JSONDecodeError( + "Expecting property name enclosed in double quotes", s, end - 1) if object_pairs_hook is not None: result = object_pairs_hook(pairs) return result, end @@ -232,7 +228,7 @@ def JSONArray(s_and_end, scan_once, _w=WHITESPACE.match, _ws=WHITESPACE_STR): try: value, end = scan_once(s, end) except StopIteration as err: - raise ValueError(errmsg("Expecting value", s, err.value)) from None + raise JSONDecodeError("Expecting value", s, err.value) from None _append(value) nextchar = s[end:end + 1] if nextchar in _ws: @@ -242,7 +238,7 @@ def JSONArray(s_and_end, scan_once, _w=WHITESPACE.match, _ws=WHITESPACE_STR): if nextchar == ']': break elif nextchar != ',': - raise ValueError(errmsg("Expecting ',' delimiter", s, end - 1)) + raise JSONDecodeError("Expecting ',' delimiter", s, end - 1) try: if s[end] in _ws: end += 1 @@ -343,7 +339,7 @@ def decode(self, s, _w=WHITESPACE.match): obj, end = self.raw_decode(s, idx=_w(s, 0).end()) end = _w(s, end).end() if end != len(s): - raise ValueError(errmsg("Extra data", s, end, len(s))) + raise JSONDecodeError("Extra data", s, end) return obj def raw_decode(self, s, idx=0): @@ -358,5 +354,5 @@ def raw_decode(self, s, idx=0): try: obj, end = self.scan_once(s, idx) except StopIteration as err: - raise ValueError(errmsg("Expecting value", s, err.value)) from None + raise JSONDecodeError("Expecting value", s, err.value) from None return obj, end diff --git a/Lib/json/encoder.py b/Lib/json/encoder.py index 05138383bccf..26e9eb2bc692 100644 --- a/Lib/json/encoder.py +++ b/Lib/json/encoder.py @@ -6,6 +6,10 @@ from _json import encode_basestring_ascii as c_encode_basestring_ascii except ImportError: c_encode_basestring_ascii = None +try: + from _json import encode_basestring as c_encode_basestring +except ImportError: + c_encode_basestring = None try: from _json import make_encoder as c_make_encoder except ImportError: @@ -30,7 +34,7 @@ INFINITY = float('inf') FLOAT_REPR = repr -def encode_basestring(s): +def py_encode_basestring(s): """Return a JSON representation of a Python string """ @@ -39,6 +43,9 @@ def replace(match): return '"' + ESCAPE.sub(replace, s) + '"' +encode_basestring = (c_encode_basestring or py_encode_basestring) + + def py_encode_basestring_ascii(s): """Return an ASCII-only JSON representation of a Python string diff --git a/Lib/json/tool.py b/Lib/json/tool.py index 7db45285713b..4f3182c0c1e7 100644 --- a/Lib/json/tool.py +++ b/Lib/json/tool.py @@ -10,28 +10,39 @@ Expecting property name enclosed in double quotes: line 1 column 3 (char 2) """ -import sys +import argparse +import collections import json +import sys + def main(): - if len(sys.argv) == 1: - infile = sys.stdin - outfile = sys.stdout - elif len(sys.argv) == 2: - infile = open(sys.argv[1], 'r') - outfile = sys.stdout - elif len(sys.argv) == 3: - infile = open(sys.argv[1], 'r') - outfile = open(sys.argv[2], 'w') - else: - raise SystemExit(sys.argv[0] + " [infile [outfile]]") + prog = 'python -m json.tool' + description = ('A simple command line interface for json module ' + 'to validate and pretty-print JSON objects.') + parser = argparse.ArgumentParser(prog=prog, description=description) + parser.add_argument('infile', nargs='?', type=argparse.FileType(), + help='a JSON file to be validated or pretty-printed') + parser.add_argument('outfile', nargs='?', type=argparse.FileType('w'), + help='write the output of infile to outfile') + parser.add_argument('--sort-keys', action='store_true', default=False, + help='sort the output of dictionaries alphabetically by key') + options = parser.parse_args() + + infile = options.infile or sys.stdin + outfile = options.outfile or sys.stdout + sort_keys = options.sort_keys with infile: try: - obj = json.load(infile) + if sort_keys: + obj = json.load(infile) + else: + obj = json.load(infile, + object_pairs_hook=collections.OrderedDict) except ValueError as e: raise SystemExit(e) with outfile: - json.dump(obj, outfile, sort_keys=True, indent=4) + json.dump(obj, outfile, sort_keys=sort_keys, indent=4) outfile.write('\n') diff --git a/Lib/lib2to3/Grammar.txt b/Lib/lib2to3/Grammar.txt index 1e1f24cfbc76..e667bcde69d0 100644 --- a/Lib/lib2to3/Grammar.txt +++ b/Lib/lib2to3/Grammar.txt @@ -56,7 +56,7 @@ small_stmt: (expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt | expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) | ('=' (yield_expr|testlist_star_expr))*) testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [','] -augassign: ('+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' | +augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' | '<<=' | '>>=' | '**=' | '//=') # For normal assignments, additional restrictions enforced by the interpreter print_stmt: 'print' ( [ test (',' test)* [','] ] | @@ -119,7 +119,7 @@ xor_expr: and_expr ('^' and_expr)* and_expr: shift_expr ('&' shift_expr)* shift_expr: arith_expr (('<<'|'>>') arith_expr)* arith_expr: term (('+'|'-') term)* -term: factor (('*'|'/'|'%'|'//') factor)* +term: factor (('*'|'@'|'/'|'%'|'//') factor)* factor: ('+'|'-'|'~') factor | power power: atom trailer* ['**' factor] atom: ('(' [yield_expr|testlist_gexp] ')' | @@ -155,4 +155,5 @@ testlist1: test (',' test)* # not used in grammar, but may appear in "node" passed from Parser to Compiler encoding_decl: NAME -yield_expr: 'yield' [testlist] +yield_expr: 'yield' [yield_arg] +yield_arg: 'from' test | testlist diff --git a/Lib/lib2to3/fixer_util.py b/Lib/lib2to3/fixer_util.py index 6e259c54ac47..44502bf7bdbd 100644 --- a/Lib/lib2to3/fixer_util.py +++ b/Lib/lib2to3/fixer_util.py @@ -187,8 +187,8 @@ def parenthesize(node): return Node(syms.atom, [LParen(), node, RParen()]) -consuming_calls = set(["sorted", "list", "set", "any", "all", "tuple", "sum", - "min", "max", "enumerate"]) +consuming_calls = {"sorted", "list", "set", "any", "all", "tuple", "sum", + "min", "max", "enumerate"} def attr_chain(obj, attr): """Follow an attribute chain. @@ -359,7 +359,7 @@ def is_import_stmt(node): root.insert_child(insert_pos, Node(syms.simple_stmt, children)) -_def_syms = set([syms.classdef, syms.funcdef]) +_def_syms = {syms.classdef, syms.funcdef} def find_binding(name, node, package=None): """ Returns the node which binds variable name, otherwise None. If optional argument package is supplied, only imports will @@ -402,7 +402,7 @@ def find_binding(name, node, package=None): return ret return None -_block_syms = set([syms.funcdef, syms.classdef, syms.trailer]) +_block_syms = {syms.funcdef, syms.classdef, syms.trailer} def _find(name, node): nodes = [node] while nodes: diff --git a/Lib/lib2to3/fixes/fix_dict.py b/Lib/lib2to3/fixes/fix_dict.py index 4cc37174cb7f..963f952e0b04 100644 --- a/Lib/lib2to3/fixes/fix_dict.py +++ b/Lib/lib2to3/fixes/fix_dict.py @@ -36,7 +36,7 @@ from .. import fixer_util -iter_exempt = fixer_util.consuming_calls | set(["iter"]) +iter_exempt = fixer_util.consuming_calls | {"iter"} class FixDict(fixer_base.BaseFix): diff --git a/Lib/lib2to3/fixes/fix_exitfunc.py b/Lib/lib2to3/fixes/fix_exitfunc.py index 9afc2fac18a3..2e47887afead 100644 --- a/Lib/lib2to3/fixes/fix_exitfunc.py +++ b/Lib/lib2to3/fixes/fix_exitfunc.py @@ -35,7 +35,7 @@ def start_tree(self, tree, filename): self.sys_import = None def transform(self, node, results): - # First, find a the sys import. We'll just hope it's global scope. + # First, find the sys import. We'll just hope it's global scope. if "sys_import" in results: if self.sys_import is None: self.sys_import = results["sys_import"] diff --git a/Lib/lib2to3/fixes/fix_import.py b/Lib/lib2to3/fixes/fix_import.py index e978fce43fcc..734ca294699c 100644 --- a/Lib/lib2to3/fixes/fix_import.py +++ b/Lib/lib2to3/fixes/fix_import.py @@ -32,7 +32,7 @@ def traverse_imports(names): elif node.type == syms.dotted_as_names: pending.extend(node.children[::-2]) else: - raise AssertionError("unkown node type") + raise AssertionError("unknown node type") class FixImport(fixer_base.BaseFix): diff --git a/Lib/lib2to3/main.py b/Lib/lib2to3/main.py index 93bae9021a49..1a1df013ade3 100644 --- a/Lib/lib2to3/main.py +++ b/Lib/lib2to3/main.py @@ -2,7 +2,7 @@ Main program for 2to3. """ -from __future__ import with_statement +from __future__ import with_statement, print_function import sys import os diff --git a/Lib/lib2to3/patcomp.py b/Lib/lib2to3/patcomp.py index 0a259e90afd8..2012ec4855f1 100644 --- a/Lib/lib2to3/patcomp.py +++ b/Lib/lib2to3/patcomp.py @@ -32,7 +32,7 @@ class PatternSyntaxError(Exception): def tokenize_wrapper(input): """Tokenizes a string suppressing significant whitespace.""" - skip = set((token.NEWLINE, token.INDENT, token.DEDENT)) + skip = {token.NEWLINE, token.INDENT, token.DEDENT} tokens = tokenize.generate_tokens(io.StringIO(input).readline) for quintuple in tokens: type, value, start, end, line_text = quintuple diff --git a/Lib/lib2to3/pgen2/grammar.py b/Lib/lib2to3/pgen2/grammar.py index 7f1c5648e264..b4481d1891a2 100644 --- a/Lib/lib2to3/pgen2/grammar.py +++ b/Lib/lib2to3/pgen2/grammar.py @@ -149,6 +149,7 @@ def report(self): { LBRACE } RBRACE @ AT +@= ATEQUAL == EQEQUAL != NOTEQUAL <> NOTEQUAL diff --git a/Lib/lib2to3/pgen2/token.py b/Lib/lib2to3/pgen2/token.py index 6a6d0b6b6502..7599396611b2 100755 --- a/Lib/lib2to3/pgen2/token.py +++ b/Lib/lib2to3/pgen2/token.py @@ -57,12 +57,13 @@ DOUBLESLASH = 48 DOUBLESLASHEQUAL = 49 AT = 50 -OP = 51 -COMMENT = 52 -NL = 53 -RARROW = 54 -ERRORTOKEN = 55 -N_TOKENS = 56 +ATEQUAL = 51 +OP = 52 +COMMENT = 53 +NL = 54 +RARROW = 55 +ERRORTOKEN = 56 +N_TOKENS = 57 NT_OFFSET = 256 #--end constants-- diff --git a/Lib/lib2to3/pgen2/tokenize.py b/Lib/lib2to3/pgen2/tokenize.py index b7c646129cd1..3dd1ee99680a 100644 --- a/Lib/lib2to3/pgen2/tokenize.py +++ b/Lib/lib2to3/pgen2/tokenize.py @@ -84,7 +84,7 @@ def maybe(*choices): return group(*choices) + '?' # recognized as two instances of =). Operator = group(r"\*\*=?", r">>=?", r"<<=?", r"<>", r"!=", r"//=?", r"->", - r"[+\-*/%&|^=<>]=?", + r"[+\-*/%&@|^=<>]=?", r"~") Bracket = '[][(){}]' @@ -237,6 +237,7 @@ def compat(self, token, iterable): toks_append(tokval) cookie_re = re.compile(r'^[ \t\f]*#.*coding[:=][ \t]*([-\w.]+)', re.ASCII) +blank_re = re.compile(br'^[ \t\f]*(?:[#\r\n]|$)', re.ASCII) def _get_normal_name(orig_enc): """Imitates get_normal_name in tokenizer.c.""" @@ -309,6 +310,8 @@ def find_cookie(line): encoding = find_cookie(first) if encoding: return encoding, [first] + if not blank_re.match(first): + return default, [first] second = read_or_stop() if not second: diff --git a/Lib/lib2to3/pytree.py b/Lib/lib2to3/pytree.py index c4a1be3500b5..ad3592c05f7e 100644 --- a/Lib/lib2to3/pytree.py +++ b/Lib/lib2to3/pytree.py @@ -64,16 +64,6 @@ def __eq__(self, other): __hash__ = None # For Py3 compatibility. - def __ne__(self, other): - """ - Compare two nodes for inequality. - - This calls the method _eq(). - """ - if self.__class__ is not other.__class__: - return NotImplemented - return not self._eq(other) - def _eq(self, other): """ Compare two nodes for equality. diff --git a/Lib/lib2to3/refactor.py b/Lib/lib2to3/refactor.py index 810031787150..c24be14867f0 100644 --- a/Lib/lib2to3/refactor.py +++ b/Lib/lib2to3/refactor.py @@ -57,7 +57,7 @@ def _get_head_types(pat): # Always return leafs if pat.type is None: raise _EveryNode - return set([pat.type]) + return {pat.type} if isinstance(pat, pytree.NegatedPattern): if pat.content: @@ -133,7 +133,7 @@ def _detect_future_features(source): def advance(): tok = next(gen) return tok[0], tok[1] - ignore = frozenset((token.NEWLINE, tokenize.NL, token.COMMENT)) + ignore = frozenset({token.NEWLINE, tokenize.NL, token.COMMENT}) features = set() try: while True: diff --git a/Lib/lib2to3/tests/__init__.py b/Lib/lib2to3/tests/__init__.py index cfaea0de747d..c5166fc94c47 100644 --- a/Lib/lib2to3/tests/__init__.py +++ b/Lib/lib2to3/tests/__init__.py @@ -1,24 +1,9 @@ -"""Make tests/ into a package. This allows us to "import tests" and -have tests.all_tests be a TestSuite representing all test cases -from all test_*.py files in tests/.""" # Author: Collin Winter import os -import os.path import unittest -import types -from . import support +from test.support import load_package_tests -all_tests = unittest.TestSuite() - -tests_dir = os.path.join(os.path.dirname(__file__), '..', 'tests') -tests = [t[0:-3] for t in os.listdir(tests_dir) - if t.startswith('test_') and t.endswith('.py')] - -loader = unittest.TestLoader() - -for t in tests: - __import__("",globals(),locals(),[t],level=1) - mod = globals()[t] - all_tests.addTests(loader.loadTestsFromModule(mod)) +def load_tests(*args): + return load_package_tests(os.path.dirname(__file__), *args) diff --git a/Lib/lib2to3/tests/__main__.py b/Lib/lib2to3/tests/__main__.py new file mode 100644 index 000000000000..40a23a297ec2 --- /dev/null +++ b/Lib/lib2to3/tests/__main__.py @@ -0,0 +1,4 @@ +from . import load_tests +import unittest + +unittest.main() diff --git a/Lib/lib2to3/tests/data/false_encoding.py b/Lib/lib2to3/tests/data/false_encoding.py old mode 100644 new mode 100755 diff --git a/Lib/lib2to3/tests/pytree_idempotency.py b/Lib/lib2to3/tests/pytree_idempotency.py index 731c4031208f..c6359bf18a1b 100755 --- a/Lib/lib2to3/tests/pytree_idempotency.py +++ b/Lib/lib2to3/tests/pytree_idempotency.py @@ -4,6 +4,8 @@ """Main program for testing the infrastructure.""" +from __future__ import print_function + __author__ = "Guido van Rossum <guido@python.org>" # Support imports (need to be imported first) diff --git a/Lib/lib2to3/tests/test_all_fixers.py b/Lib/lib2to3/tests/test_all_fixers.py index f64b3d942af2..15079fe0285c 100644 --- a/Lib/lib2to3/tests/test_all_fixers.py +++ b/Lib/lib2to3/tests/test_all_fixers.py @@ -7,12 +7,14 @@ # Python imports import unittest +import test.support # Local imports from lib2to3 import refactor from . import support +@test.support.requires_resource('cpu') class Test_all(support.TestCase): def setUp(self): @@ -21,3 +23,6 @@ def setUp(self): def test_all_project_files(self): for filepath in support.all_project_files(): self.refactor.refactor_file(filepath) + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/lib2to3/tests/test_parser.py b/Lib/lib2to3/tests/test_parser.py index a383a14e30ed..5bb9d2becb71 100644 --- a/Lib/lib2to3/tests/test_parser.py +++ b/Lib/lib2to3/tests/test_parser.py @@ -48,6 +48,19 @@ def invalid_syntax(self, code): raise AssertionError("Syntax shouldn't have been valid") +class TestMatrixMultiplication(GrammarTest): + def test_matrix_multiplication_operator(self): + self.validate("a @ b") + self.validate("a @= b") + + +class TestYieldFrom(GrammarTest): + def test_matrix_multiplication_operator(self): + self.validate("yield from x") + self.validate("(yield from x) + y") + self.invalid_syntax("yield from") + + class TestRaiseChanges(GrammarTest): def test_2x_style_1(self): self.validate("raise") @@ -77,7 +90,7 @@ def test_3x_style_invalid_4(self): self.invalid_syntax("raise E from") -# Adaptated from Python 3's Lib/test/test_grammar.py:GrammarTests.testFuncdef +# Adapted from Python 3's Lib/test/test_grammar.py:GrammarTests.testFuncdef class TestFunctionAnnotations(GrammarTest): def test_1(self): self.validate("""def f(x) -> list: pass""") diff --git a/Lib/locale.py b/Lib/locale.py index 2e82c952aceb..6b9eb3a09bc7 100644 --- a/Lib/locale.py +++ b/Lib/locale.py @@ -301,8 +301,8 @@ def str(val): """Convert float to integer, taking the locale into account.""" return format("%.12g", val) -def atof(string, func=float): - "Parses a string as a float according to the locale settings." +def delocalize(string): + "Parses a string as a normalized number according to the locale settings." #First, get rid of the grouping ts = localeconv()['thousands_sep'] if ts: @@ -311,12 +311,15 @@ def atof(string, func=float): dd = localeconv()['decimal_point'] if dd: string = string.replace(dd, '.') - #finally, parse the string - return func(string) + return string -def atoi(str): +def atof(string, func=float): + "Parses a string as a float according to the locale settings." + return func(delocalize(string)) + +def atoi(string): "Converts a string to an integer according to the locale settings." - return atof(str, int) + return int(delocalize(string)) def _test(): setlocale(LC_ALL, "") @@ -336,6 +339,40 @@ def _test(): # overridden below) _setlocale = setlocale +def _replace_encoding(code, encoding): + if '.' in code: + langname = code[:code.index('.')] + else: + langname = code + # Convert the encoding to a C lib compatible encoding string + norm_encoding = encodings.normalize_encoding(encoding) + #print('norm encoding: %r' % norm_encoding) + norm_encoding = encodings.aliases.aliases.get(norm_encoding.lower(), + norm_encoding) + #print('aliased encoding: %r' % norm_encoding) + encoding = norm_encoding + norm_encoding = norm_encoding.lower() + if norm_encoding in locale_encoding_alias: + encoding = locale_encoding_alias[norm_encoding] + else: + norm_encoding = norm_encoding.replace('_', '') + norm_encoding = norm_encoding.replace('-', '') + if norm_encoding in locale_encoding_alias: + encoding = locale_encoding_alias[norm_encoding] + #print('found encoding %r' % encoding) + return langname + '.' + encoding + +def _append_modifier(code, modifier): + if modifier == 'euro': + if '.' not in code: + return code + '.ISO8859-15' + _, _, encoding = code.partition('.') + if encoding in ('ISO8859-15', 'UTF-8'): + return code + if encoding == 'ISO8859-1': + return _replace_encoding(code, 'ISO8859-15') + return code + '@' + modifier + def normalize(localename): """ Returns a normalized locale code for the given locale @@ -352,55 +389,72 @@ def normalize(localename): does. """ - # Normalize the locale name and extract the encoding - fullname = localename.lower() - if ':' in fullname: + # Normalize the locale name and extract the encoding and modifier + code = localename.lower() + if ':' in code: # ':' is sometimes used as encoding delimiter. - fullname = fullname.replace(':', '.') - if '.' in fullname: - langname, encoding = fullname.split('.')[:2] - fullname = langname + '.' + encoding + code = code.replace(':', '.') + if '@' in code: + code, modifier = code.split('@', 1) else: - langname = fullname + modifier = '' + if '.' in code: + langname, encoding = code.split('.')[:2] + else: + langname = code encoding = '' - # First lookup: fullname (possibly with encoding) - norm_encoding = encoding.replace('-', '') - norm_encoding = norm_encoding.replace('_', '') - lookup_name = langname + '.' + encoding + # First lookup: fullname (possibly with encoding and modifier) + lang_enc = langname + if encoding: + norm_encoding = encoding.replace('-', '') + norm_encoding = norm_encoding.replace('_', '') + lang_enc += '.' + norm_encoding + lookup_name = lang_enc + if modifier: + lookup_name += '@' + modifier code = locale_alias.get(lookup_name, None) if code is not None: return code - #print 'first lookup failed' - - # Second try: langname (without encoding) - code = locale_alias.get(langname, None) - if code is not None: - #print 'langname lookup succeeded' - if '.' in code: - langname, defenc = code.split('.') - else: - langname = code - defenc = '' - if encoding: - # Convert the encoding to a C lib compatible encoding string - norm_encoding = encodings.normalize_encoding(encoding) - #print 'norm encoding: %r' % norm_encoding - norm_encoding = encodings.aliases.aliases.get(norm_encoding, - norm_encoding) - #print 'aliased encoding: %r' % norm_encoding - encoding = locale_encoding_alias.get(norm_encoding, - norm_encoding) - else: - encoding = defenc - #print 'found encoding %r' % encoding - if encoding: - return langname + '.' + encoding - else: - return langname - - else: - return localename + #print('first lookup failed') + + if modifier: + # Second try: fullname without modifier (possibly with encoding) + code = locale_alias.get(lang_enc, None) + if code is not None: + #print('lookup without modifier succeeded') + if '@' not in code: + return _append_modifier(code, modifier) + if code.split('@', 1)[1].lower() == modifier: + return code + #print('second lookup failed') + + if encoding: + # Third try: langname (without encoding, possibly with modifier) + lookup_name = langname + if modifier: + lookup_name += '@' + modifier + code = locale_alias.get(lookup_name, None) + if code is not None: + #print('lookup without encoding succeeded') + if '@' not in code: + return _replace_encoding(code, encoding) + code, modifier = code.split('@', 1) + return _replace_encoding(code, encoding) + '@' + modifier + + if modifier: + # Fourth try: langname (without encoding and modifier) + code = locale_alias.get(langname, None) + if code is not None: + #print('lookup without modifier and encoding succeeded') + if '@' not in code: + code = _replace_encoding(code, encoding) + return _append_modifier(code, modifier) + code, defmod = code.split('@', 1) + if defmod.lower() == modifier: + return _replace_encoding(code, encoding) + '@' + defmod + + return localename def _parse_localename(localename): @@ -419,7 +473,7 @@ def _parse_localename(localename): code = normalize(localename) if '@' in code: # Deal with locale modifiers - code, modifier = code.split('@') + code, modifier = code.split('@', 1) if modifier == 'euro' and '.' not in code: # Assume Latin-9 for @euro locales. This is bogus, # since some systems may use other encodings for these @@ -611,6 +665,14 @@ def getpreferredencoding(do_setlocale = True): 'jis': 'JIS7', 'jis7': 'JIS7', 'ajec': 'eucJP', + 'koi8c': 'KOI8-C', + 'microsoftcp1251': 'CP1251', + 'microsoftcp1255': 'CP1255', + 'microsoftcp1256': 'CP1256', + '88591': 'ISO8859-1', + '88592': 'ISO8859-2', + '88595': 'ISO8859-5', + '885915': 'ISO8859-15', # Mappings from Python codec names to C lib encoding names 'ascii': 'ISO8859-1', @@ -638,10 +700,18 @@ def getpreferredencoding(do_setlocale = True): 'utf_8': 'UTF-8', 'koi8_r': 'KOI8-R', 'koi8_u': 'KOI8-U', + 'cp1251': 'CP1251', + 'cp1255': 'CP1255', + 'cp1256': 'CP1256', + # XXX This list is still incomplete. If you know more # mappings, please file a bug report. Thanks. } +for k, v in sorted(locale_encoding_alias.items()): + k = k.replace('_', '') + locale_encoding_alias.setdefault(k, v) + # # The locale_alias table maps lowercase alias names to C locale names # (case-sensitive). Encodings are always separated from the locale @@ -732,458 +802,281 @@ def getpreferredencoding(do_setlocale = True): # updated 'sr_yu.utf8@cyrillic' -> 'sr_CS.UTF-8' to 'sr_RS.UTF-8' # updated 'sr_yu@cyrillic' -> 'sr_CS.ISO8859-5' to 'sr_RS.UTF-8' # +# SS 2013-12-20: +# Updated alias mapping to most recent locale.alias file +# from X.org distribution using makelocalealias.py. +# +# These are the differences compared to the old mapping (Python 3.3.3 +# and older): +# +# updated 'a3' -> 'a3_AZ.KOI8-C' to 'az_AZ.KOI8-C' +# updated 'a3_az' -> 'a3_AZ.KOI8-C' to 'az_AZ.KOI8-C' +# updated 'a3_az.koi8c' -> 'a3_AZ.KOI8-C' to 'az_AZ.KOI8-C' +# updated 'cs_cs.iso88592' -> 'cs_CS.ISO8859-2' to 'cs_CZ.ISO8859-2' +# updated 'hebrew' -> 'iw_IL.ISO8859-8' to 'he_IL.ISO8859-8' +# updated 'hebrew.iso88598' -> 'iw_IL.ISO8859-8' to 'he_IL.ISO8859-8' +# updated 'sd' -> 'sd_IN@devanagari.UTF-8' to 'sd_IN.UTF-8' +# updated 'sr@latn' -> 'sr_RS.UTF-8@latin' to 'sr_CS.UTF-8@latin' +# updated 'sr_cs' -> 'sr_RS.UTF-8' to 'sr_CS.UTF-8' +# updated 'sr_cs.utf8@latn' -> 'sr_RS.UTF-8@latin' to 'sr_CS.UTF-8@latin' +# updated 'sr_cs@latn' -> 'sr_RS.UTF-8@latin' to 'sr_CS.UTF-8@latin' +# +# SS 2014-10-01: +# Updated alias mapping with glibc 2.19 supported locales. locale_alias = { - 'a3': 'a3_AZ.KOI8-C', - 'a3_az': 'a3_AZ.KOI8-C', - 'a3_az.koi8c': 'a3_AZ.KOI8-C', + 'a3': 'az_AZ.KOI8-C', + 'a3_az': 'az_AZ.KOI8-C', + 'a3_az.koic': 'az_AZ.KOI8-C', + 'aa_dj': 'aa_DJ.ISO8859-1', + 'aa_er': 'aa_ER.UTF-8', + 'aa_et': 'aa_ET.UTF-8', 'af': 'af_ZA.ISO8859-1', 'af_za': 'af_ZA.ISO8859-1', - 'af_za.iso88591': 'af_ZA.ISO8859-1', 'am': 'am_ET.UTF-8', 'am_et': 'am_ET.UTF-8', 'american': 'en_US.ISO8859-1', - 'american.iso88591': 'en_US.ISO8859-1', + 'an_es': 'an_ES.ISO8859-15', 'ar': 'ar_AA.ISO8859-6', 'ar_aa': 'ar_AA.ISO8859-6', - 'ar_aa.iso88596': 'ar_AA.ISO8859-6', 'ar_ae': 'ar_AE.ISO8859-6', - 'ar_ae.iso88596': 'ar_AE.ISO8859-6', 'ar_bh': 'ar_BH.ISO8859-6', - 'ar_bh.iso88596': 'ar_BH.ISO8859-6', 'ar_dz': 'ar_DZ.ISO8859-6', - 'ar_dz.iso88596': 'ar_DZ.ISO8859-6', 'ar_eg': 'ar_EG.ISO8859-6', - 'ar_eg.iso88596': 'ar_EG.ISO8859-6', + 'ar_in': 'ar_IN.UTF-8', 'ar_iq': 'ar_IQ.ISO8859-6', - 'ar_iq.iso88596': 'ar_IQ.ISO8859-6', 'ar_jo': 'ar_JO.ISO8859-6', - 'ar_jo.iso88596': 'ar_JO.ISO8859-6', 'ar_kw': 'ar_KW.ISO8859-6', - 'ar_kw.iso88596': 'ar_KW.ISO8859-6', 'ar_lb': 'ar_LB.ISO8859-6', - 'ar_lb.iso88596': 'ar_LB.ISO8859-6', 'ar_ly': 'ar_LY.ISO8859-6', - 'ar_ly.iso88596': 'ar_LY.ISO8859-6', 'ar_ma': 'ar_MA.ISO8859-6', - 'ar_ma.iso88596': 'ar_MA.ISO8859-6', 'ar_om': 'ar_OM.ISO8859-6', - 'ar_om.iso88596': 'ar_OM.ISO8859-6', 'ar_qa': 'ar_QA.ISO8859-6', - 'ar_qa.iso88596': 'ar_QA.ISO8859-6', 'ar_sa': 'ar_SA.ISO8859-6', - 'ar_sa.iso88596': 'ar_SA.ISO8859-6', 'ar_sd': 'ar_SD.ISO8859-6', - 'ar_sd.iso88596': 'ar_SD.ISO8859-6', 'ar_sy': 'ar_SY.ISO8859-6', - 'ar_sy.iso88596': 'ar_SY.ISO8859-6', 'ar_tn': 'ar_TN.ISO8859-6', - 'ar_tn.iso88596': 'ar_TN.ISO8859-6', 'ar_ye': 'ar_YE.ISO8859-6', - 'ar_ye.iso88596': 'ar_YE.ISO8859-6', 'arabic': 'ar_AA.ISO8859-6', - 'arabic.iso88596': 'ar_AA.ISO8859-6', 'as': 'as_IN.UTF-8', + 'as_in': 'as_IN.UTF-8', + 'ast_es': 'ast_ES.ISO8859-15', + 'ayc_pe': 'ayc_PE.UTF-8', 'az': 'az_AZ.ISO8859-9E', 'az_az': 'az_AZ.ISO8859-9E', 'az_az.iso88599e': 'az_AZ.ISO8859-9E', 'be': 'be_BY.CP1251', 'be@latin': 'be_BY.UTF-8@latin', + 'be_bg.utf8': 'bg_BG.UTF-8', 'be_by': 'be_BY.CP1251', - 'be_by.cp1251': 'be_BY.CP1251', - 'be_by.microsoftcp1251': 'be_BY.CP1251', - 'be_by.utf8@latin': 'be_BY.UTF-8@latin', 'be_by@latin': 'be_BY.UTF-8@latin', + 'bem_zm': 'bem_ZM.UTF-8', + 'ber_dz': 'ber_DZ.UTF-8', + 'ber_ma': 'ber_MA.UTF-8', 'bg': 'bg_BG.CP1251', 'bg_bg': 'bg_BG.CP1251', - 'bg_bg.cp1251': 'bg_BG.CP1251', - 'bg_bg.iso88595': 'bg_BG.ISO8859-5', - 'bg_bg.koi8r': 'bg_BG.KOI8-R', - 'bg_bg.microsoftcp1251': 'bg_BG.CP1251', + 'bho_in': 'bho_IN.UTF-8', + 'bn_bd': 'bn_BD.UTF-8', 'bn_in': 'bn_IN.UTF-8', + 'bo_cn': 'bo_CN.UTF-8', + 'bo_in': 'bo_IN.UTF-8', 'bokmal': 'nb_NO.ISO8859-1', 'bokm\xe5l': 'nb_NO.ISO8859-1', 'br': 'br_FR.ISO8859-1', 'br_fr': 'br_FR.ISO8859-1', - 'br_fr.iso88591': 'br_FR.ISO8859-1', - 'br_fr.iso885914': 'br_FR.ISO8859-14', - 'br_fr.iso885915': 'br_FR.ISO8859-15', - 'br_fr.iso885915@euro': 'br_FR.ISO8859-15', - 'br_fr.utf8@euro': 'br_FR.UTF-8', - 'br_fr@euro': 'br_FR.ISO8859-15', + 'brx_in': 'brx_IN.UTF-8', 'bs': 'bs_BA.ISO8859-2', 'bs_ba': 'bs_BA.ISO8859-2', - 'bs_ba.iso88592': 'bs_BA.ISO8859-2', 'bulgarian': 'bg_BG.CP1251', + 'byn_er': 'byn_ER.UTF-8', 'c': 'C', 'c-french': 'fr_CA.ISO8859-1', - 'c-french.iso88591': 'fr_CA.ISO8859-1', + 'c.ascii': 'C', 'c.en': 'C', 'c.iso88591': 'en_US.ISO8859-1', + 'c.utf8': 'en_US.UTF-8', 'c_c': 'C', 'c_c.c': 'C', 'ca': 'ca_ES.ISO8859-1', 'ca_ad': 'ca_AD.ISO8859-1', - 'ca_ad.iso88591': 'ca_AD.ISO8859-1', - 'ca_ad.iso885915': 'ca_AD.ISO8859-15', - 'ca_ad.iso885915@euro': 'ca_AD.ISO8859-15', - 'ca_ad.utf8@euro': 'ca_AD.UTF-8', - 'ca_ad@euro': 'ca_AD.ISO8859-15', 'ca_es': 'ca_ES.ISO8859-1', - 'ca_es.iso88591': 'ca_ES.ISO8859-1', - 'ca_es.iso885915': 'ca_ES.ISO8859-15', - 'ca_es.iso885915@euro': 'ca_ES.ISO8859-15', - 'ca_es.utf8@euro': 'ca_ES.UTF-8', - 'ca_es@euro': 'ca_ES.ISO8859-15', + 'ca_es@valencia': 'ca_ES.ISO8859-15@valencia', 'ca_fr': 'ca_FR.ISO8859-1', - 'ca_fr.iso88591': 'ca_FR.ISO8859-1', - 'ca_fr.iso885915': 'ca_FR.ISO8859-15', - 'ca_fr.iso885915@euro': 'ca_FR.ISO8859-15', - 'ca_fr.utf8@euro': 'ca_FR.UTF-8', - 'ca_fr@euro': 'ca_FR.ISO8859-15', 'ca_it': 'ca_IT.ISO8859-1', - 'ca_it.iso88591': 'ca_IT.ISO8859-1', - 'ca_it.iso885915': 'ca_IT.ISO8859-15', - 'ca_it.iso885915@euro': 'ca_IT.ISO8859-15', - 'ca_it.utf8@euro': 'ca_IT.UTF-8', - 'ca_it@euro': 'ca_IT.ISO8859-15', 'catalan': 'ca_ES.ISO8859-1', 'cextend': 'en_US.ISO8859-1', - 'cextend.en': 'en_US.ISO8859-1', 'chinese-s': 'zh_CN.eucCN', 'chinese-t': 'zh_TW.eucTW', + 'crh_ua': 'crh_UA.UTF-8', 'croatian': 'hr_HR.ISO8859-2', 'cs': 'cs_CZ.ISO8859-2', 'cs_cs': 'cs_CZ.ISO8859-2', - 'cs_cs.iso88592': 'cs_CS.ISO8859-2', 'cs_cz': 'cs_CZ.ISO8859-2', - 'cs_cz.iso88592': 'cs_CZ.ISO8859-2', + 'csb_pl': 'csb_PL.UTF-8', + 'cv_ru': 'cv_RU.UTF-8', 'cy': 'cy_GB.ISO8859-1', 'cy_gb': 'cy_GB.ISO8859-1', - 'cy_gb.iso88591': 'cy_GB.ISO8859-1', - 'cy_gb.iso885914': 'cy_GB.ISO8859-14', - 'cy_gb.iso885915': 'cy_GB.ISO8859-15', - 'cy_gb@euro': 'cy_GB.ISO8859-15', 'cz': 'cs_CZ.ISO8859-2', 'cz_cz': 'cs_CZ.ISO8859-2', 'czech': 'cs_CZ.ISO8859-2', 'da': 'da_DK.ISO8859-1', - 'da.iso885915': 'da_DK.ISO8859-15', 'da_dk': 'da_DK.ISO8859-1', - 'da_dk.88591': 'da_DK.ISO8859-1', - 'da_dk.885915': 'da_DK.ISO8859-15', - 'da_dk.iso88591': 'da_DK.ISO8859-1', - 'da_dk.iso885915': 'da_DK.ISO8859-15', - 'da_dk@euro': 'da_DK.ISO8859-15', 'danish': 'da_DK.ISO8859-1', - 'danish.iso88591': 'da_DK.ISO8859-1', 'dansk': 'da_DK.ISO8859-1', 'de': 'de_DE.ISO8859-1', - 'de.iso885915': 'de_DE.ISO8859-15', 'de_at': 'de_AT.ISO8859-1', - 'de_at.iso88591': 'de_AT.ISO8859-1', - 'de_at.iso885915': 'de_AT.ISO8859-15', - 'de_at.iso885915@euro': 'de_AT.ISO8859-15', - 'de_at.utf8@euro': 'de_AT.UTF-8', - 'de_at@euro': 'de_AT.ISO8859-15', 'de_be': 'de_BE.ISO8859-1', - 'de_be.iso88591': 'de_BE.ISO8859-1', - 'de_be.iso885915': 'de_BE.ISO8859-15', - 'de_be.iso885915@euro': 'de_BE.ISO8859-15', - 'de_be.utf8@euro': 'de_BE.UTF-8', - 'de_be@euro': 'de_BE.ISO8859-15', 'de_ch': 'de_CH.ISO8859-1', - 'de_ch.iso88591': 'de_CH.ISO8859-1', - 'de_ch.iso885915': 'de_CH.ISO8859-15', - 'de_ch@euro': 'de_CH.ISO8859-15', 'de_de': 'de_DE.ISO8859-1', - 'de_de.88591': 'de_DE.ISO8859-1', - 'de_de.885915': 'de_DE.ISO8859-15', - 'de_de.885915@euro': 'de_DE.ISO8859-15', - 'de_de.iso88591': 'de_DE.ISO8859-1', - 'de_de.iso885915': 'de_DE.ISO8859-15', - 'de_de.iso885915@euro': 'de_DE.ISO8859-15', - 'de_de.utf8@euro': 'de_DE.UTF-8', - 'de_de@euro': 'de_DE.ISO8859-15', + 'de_li.utf8': 'de_LI.UTF-8', 'de_lu': 'de_LU.ISO8859-1', - 'de_lu.iso88591': 'de_LU.ISO8859-1', - 'de_lu.iso885915': 'de_LU.ISO8859-15', - 'de_lu.iso885915@euro': 'de_LU.ISO8859-15', - 'de_lu.utf8@euro': 'de_LU.UTF-8', - 'de_lu@euro': 'de_LU.ISO8859-15', 'deutsch': 'de_DE.ISO8859-1', + 'doi_in': 'doi_IN.UTF-8', 'dutch': 'nl_NL.ISO8859-1', 'dutch.iso88591': 'nl_BE.ISO8859-1', + 'dv_mv': 'dv_MV.UTF-8', + 'dz_bt': 'dz_BT.UTF-8', 'ee': 'ee_EE.ISO8859-4', 'ee_ee': 'ee_EE.ISO8859-4', - 'ee_ee.iso88594': 'ee_EE.ISO8859-4', 'eesti': 'et_EE.ISO8859-1', 'el': 'el_GR.ISO8859-7', + 'el_cy': 'el_CY.ISO8859-7', 'el_gr': 'el_GR.ISO8859-7', - 'el_gr.iso88597': 'el_GR.ISO8859-7', 'el_gr@euro': 'el_GR.ISO8859-15', 'en': 'en_US.ISO8859-1', - 'en.iso88591': 'en_US.ISO8859-1', + 'en_ag': 'en_AG.UTF-8', 'en_au': 'en_AU.ISO8859-1', - 'en_au.iso88591': 'en_AU.ISO8859-1', 'en_be': 'en_BE.ISO8859-1', - 'en_be@euro': 'en_BE.ISO8859-15', 'en_bw': 'en_BW.ISO8859-1', - 'en_bw.iso88591': 'en_BW.ISO8859-1', 'en_ca': 'en_CA.ISO8859-1', - 'en_ca.iso88591': 'en_CA.ISO8859-1', + 'en_dk': 'en_DK.ISO8859-1', + 'en_dl.utf8': 'en_DL.UTF-8', 'en_gb': 'en_GB.ISO8859-1', - 'en_gb.88591': 'en_GB.ISO8859-1', - 'en_gb.iso88591': 'en_GB.ISO8859-1', - 'en_gb.iso885915': 'en_GB.ISO8859-15', - 'en_gb@euro': 'en_GB.ISO8859-15', 'en_hk': 'en_HK.ISO8859-1', - 'en_hk.iso88591': 'en_HK.ISO8859-1', 'en_ie': 'en_IE.ISO8859-1', - 'en_ie.iso88591': 'en_IE.ISO8859-1', - 'en_ie.iso885915': 'en_IE.ISO8859-15', - 'en_ie.iso885915@euro': 'en_IE.ISO8859-15', - 'en_ie.utf8@euro': 'en_IE.UTF-8', - 'en_ie@euro': 'en_IE.ISO8859-15', 'en_in': 'en_IN.ISO8859-1', + 'en_ng': 'en_NG.UTF-8', 'en_nz': 'en_NZ.ISO8859-1', - 'en_nz.iso88591': 'en_NZ.ISO8859-1', 'en_ph': 'en_PH.ISO8859-1', - 'en_ph.iso88591': 'en_PH.ISO8859-1', 'en_sg': 'en_SG.ISO8859-1', - 'en_sg.iso88591': 'en_SG.ISO8859-1', 'en_uk': 'en_GB.ISO8859-1', 'en_us': 'en_US.ISO8859-1', - 'en_us.88591': 'en_US.ISO8859-1', - 'en_us.885915': 'en_US.ISO8859-15', - 'en_us.iso88591': 'en_US.ISO8859-1', - 'en_us.iso885915': 'en_US.ISO8859-15', - 'en_us.iso885915@euro': 'en_US.ISO8859-15', - 'en_us@euro': 'en_US.ISO8859-15', 'en_us@euro@euro': 'en_US.ISO8859-15', 'en_za': 'en_ZA.ISO8859-1', - 'en_za.88591': 'en_ZA.ISO8859-1', - 'en_za.iso88591': 'en_ZA.ISO8859-1', - 'en_za.iso885915': 'en_ZA.ISO8859-15', - 'en_za@euro': 'en_ZA.ISO8859-15', + 'en_zm': 'en_ZM.UTF-8', 'en_zw': 'en_ZW.ISO8859-1', - 'en_zw.iso88591': 'en_ZW.ISO8859-1', + 'en_zw.utf8': 'en_ZS.UTF-8', 'eng_gb': 'en_GB.ISO8859-1', - 'eng_gb.8859': 'en_GB.ISO8859-1', 'english': 'en_EN.ISO8859-1', - 'english.iso88591': 'en_EN.ISO8859-1', 'english_uk': 'en_GB.ISO8859-1', - 'english_uk.8859': 'en_GB.ISO8859-1', 'english_united-states': 'en_US.ISO8859-1', 'english_united-states.437': 'C', 'english_us': 'en_US.ISO8859-1', - 'english_us.8859': 'en_US.ISO8859-1', - 'english_us.ascii': 'en_US.ISO8859-1', 'eo': 'eo_XX.ISO8859-3', + 'eo.utf8': 'eo.UTF-8', 'eo_eo': 'eo_EO.ISO8859-3', - 'eo_eo.iso88593': 'eo_EO.ISO8859-3', + 'eo_us.utf8': 'eo_US.UTF-8', 'eo_xx': 'eo_XX.ISO8859-3', - 'eo_xx.iso88593': 'eo_XX.ISO8859-3', 'es': 'es_ES.ISO8859-1', 'es_ar': 'es_AR.ISO8859-1', - 'es_ar.iso88591': 'es_AR.ISO8859-1', 'es_bo': 'es_BO.ISO8859-1', - 'es_bo.iso88591': 'es_BO.ISO8859-1', 'es_cl': 'es_CL.ISO8859-1', - 'es_cl.iso88591': 'es_CL.ISO8859-1', 'es_co': 'es_CO.ISO8859-1', - 'es_co.iso88591': 'es_CO.ISO8859-1', 'es_cr': 'es_CR.ISO8859-1', - 'es_cr.iso88591': 'es_CR.ISO8859-1', + 'es_cu': 'es_CU.UTF-8', 'es_do': 'es_DO.ISO8859-1', - 'es_do.iso88591': 'es_DO.ISO8859-1', 'es_ec': 'es_EC.ISO8859-1', - 'es_ec.iso88591': 'es_EC.ISO8859-1', 'es_es': 'es_ES.ISO8859-1', - 'es_es.88591': 'es_ES.ISO8859-1', - 'es_es.iso88591': 'es_ES.ISO8859-1', - 'es_es.iso885915': 'es_ES.ISO8859-15', - 'es_es.iso885915@euro': 'es_ES.ISO8859-15', - 'es_es.utf8@euro': 'es_ES.UTF-8', - 'es_es@euro': 'es_ES.ISO8859-15', 'es_gt': 'es_GT.ISO8859-1', - 'es_gt.iso88591': 'es_GT.ISO8859-1', 'es_hn': 'es_HN.ISO8859-1', - 'es_hn.iso88591': 'es_HN.ISO8859-1', 'es_mx': 'es_MX.ISO8859-1', - 'es_mx.iso88591': 'es_MX.ISO8859-1', 'es_ni': 'es_NI.ISO8859-1', - 'es_ni.iso88591': 'es_NI.ISO8859-1', 'es_pa': 'es_PA.ISO8859-1', - 'es_pa.iso88591': 'es_PA.ISO8859-1', - 'es_pa.iso885915': 'es_PA.ISO8859-15', - 'es_pa@euro': 'es_PA.ISO8859-15', 'es_pe': 'es_PE.ISO8859-1', - 'es_pe.iso88591': 'es_PE.ISO8859-1', - 'es_pe.iso885915': 'es_PE.ISO8859-15', - 'es_pe@euro': 'es_PE.ISO8859-15', 'es_pr': 'es_PR.ISO8859-1', - 'es_pr.iso88591': 'es_PR.ISO8859-1', 'es_py': 'es_PY.ISO8859-1', - 'es_py.iso88591': 'es_PY.ISO8859-1', - 'es_py.iso885915': 'es_PY.ISO8859-15', - 'es_py@euro': 'es_PY.ISO8859-15', 'es_sv': 'es_SV.ISO8859-1', - 'es_sv.iso88591': 'es_SV.ISO8859-1', - 'es_sv.iso885915': 'es_SV.ISO8859-15', - 'es_sv@euro': 'es_SV.ISO8859-15', 'es_us': 'es_US.ISO8859-1', - 'es_us.iso88591': 'es_US.ISO8859-1', 'es_uy': 'es_UY.ISO8859-1', - 'es_uy.iso88591': 'es_UY.ISO8859-1', - 'es_uy.iso885915': 'es_UY.ISO8859-15', - 'es_uy@euro': 'es_UY.ISO8859-15', 'es_ve': 'es_VE.ISO8859-1', - 'es_ve.iso88591': 'es_VE.ISO8859-1', - 'es_ve.iso885915': 'es_VE.ISO8859-15', - 'es_ve@euro': 'es_VE.ISO8859-15', 'estonian': 'et_EE.ISO8859-1', 'et': 'et_EE.ISO8859-15', 'et_ee': 'et_EE.ISO8859-15', - 'et_ee.iso88591': 'et_EE.ISO8859-1', - 'et_ee.iso885913': 'et_EE.ISO8859-13', - 'et_ee.iso885915': 'et_EE.ISO8859-15', - 'et_ee.iso88594': 'et_EE.ISO8859-4', - 'et_ee@euro': 'et_EE.ISO8859-15', 'eu': 'eu_ES.ISO8859-1', 'eu_es': 'eu_ES.ISO8859-1', - 'eu_es.iso88591': 'eu_ES.ISO8859-1', - 'eu_es.iso885915': 'eu_ES.ISO8859-15', - 'eu_es.iso885915@euro': 'eu_ES.ISO8859-15', - 'eu_es.utf8@euro': 'eu_ES.UTF-8', - 'eu_es@euro': 'eu_ES.ISO8859-15', + 'eu_fr': 'eu_FR.ISO8859-1', 'fa': 'fa_IR.UTF-8', 'fa_ir': 'fa_IR.UTF-8', 'fa_ir.isiri3342': 'fa_IR.ISIRI-3342', + 'ff_sn': 'ff_SN.UTF-8', 'fi': 'fi_FI.ISO8859-15', - 'fi.iso885915': 'fi_FI.ISO8859-15', 'fi_fi': 'fi_FI.ISO8859-15', - 'fi_fi.88591': 'fi_FI.ISO8859-1', - 'fi_fi.iso88591': 'fi_FI.ISO8859-1', - 'fi_fi.iso885915': 'fi_FI.ISO8859-15', - 'fi_fi.iso885915@euro': 'fi_FI.ISO8859-15', - 'fi_fi.utf8@euro': 'fi_FI.UTF-8', - 'fi_fi@euro': 'fi_FI.ISO8859-15', + 'fil_ph': 'fil_PH.UTF-8', 'finnish': 'fi_FI.ISO8859-1', - 'finnish.iso88591': 'fi_FI.ISO8859-1', 'fo': 'fo_FO.ISO8859-1', 'fo_fo': 'fo_FO.ISO8859-1', - 'fo_fo.iso88591': 'fo_FO.ISO8859-1', - 'fo_fo.iso885915': 'fo_FO.ISO8859-15', - 'fo_fo@euro': 'fo_FO.ISO8859-15', 'fr': 'fr_FR.ISO8859-1', - 'fr.iso885915': 'fr_FR.ISO8859-15', 'fr_be': 'fr_BE.ISO8859-1', - 'fr_be.88591': 'fr_BE.ISO8859-1', - 'fr_be.iso88591': 'fr_BE.ISO8859-1', - 'fr_be.iso885915': 'fr_BE.ISO8859-15', - 'fr_be.iso885915@euro': 'fr_BE.ISO8859-15', - 'fr_be.utf8@euro': 'fr_BE.UTF-8', - 'fr_be@euro': 'fr_BE.ISO8859-15', 'fr_ca': 'fr_CA.ISO8859-1', - 'fr_ca.88591': 'fr_CA.ISO8859-1', - 'fr_ca.iso88591': 'fr_CA.ISO8859-1', - 'fr_ca.iso885915': 'fr_CA.ISO8859-15', - 'fr_ca@euro': 'fr_CA.ISO8859-15', 'fr_ch': 'fr_CH.ISO8859-1', - 'fr_ch.88591': 'fr_CH.ISO8859-1', - 'fr_ch.iso88591': 'fr_CH.ISO8859-1', - 'fr_ch.iso885915': 'fr_CH.ISO8859-15', - 'fr_ch@euro': 'fr_CH.ISO8859-15', 'fr_fr': 'fr_FR.ISO8859-1', - 'fr_fr.88591': 'fr_FR.ISO8859-1', - 'fr_fr.iso88591': 'fr_FR.ISO8859-1', - 'fr_fr.iso885915': 'fr_FR.ISO8859-15', - 'fr_fr.iso885915@euro': 'fr_FR.ISO8859-15', - 'fr_fr.utf8@euro': 'fr_FR.UTF-8', - 'fr_fr@euro': 'fr_FR.ISO8859-15', 'fr_lu': 'fr_LU.ISO8859-1', - 'fr_lu.88591': 'fr_LU.ISO8859-1', - 'fr_lu.iso88591': 'fr_LU.ISO8859-1', - 'fr_lu.iso885915': 'fr_LU.ISO8859-15', - 'fr_lu.iso885915@euro': 'fr_LU.ISO8859-15', - 'fr_lu.utf8@euro': 'fr_LU.UTF-8', - 'fr_lu@euro': 'fr_LU.ISO8859-15', 'fran\xe7ais': 'fr_FR.ISO8859-1', 'fre_fr': 'fr_FR.ISO8859-1', - 'fre_fr.8859': 'fr_FR.ISO8859-1', 'french': 'fr_FR.ISO8859-1', 'french.iso88591': 'fr_CH.ISO8859-1', 'french_france': 'fr_FR.ISO8859-1', - 'french_france.8859': 'fr_FR.ISO8859-1', + 'fur_it': 'fur_IT.UTF-8', + 'fy_de': 'fy_DE.UTF-8', + 'fy_nl': 'fy_NL.UTF-8', 'ga': 'ga_IE.ISO8859-1', 'ga_ie': 'ga_IE.ISO8859-1', - 'ga_ie.iso88591': 'ga_IE.ISO8859-1', - 'ga_ie.iso885914': 'ga_IE.ISO8859-14', - 'ga_ie.iso885915': 'ga_IE.ISO8859-15', - 'ga_ie.iso885915@euro': 'ga_IE.ISO8859-15', - 'ga_ie.utf8@euro': 'ga_IE.UTF-8', - 'ga_ie@euro': 'ga_IE.ISO8859-15', 'galego': 'gl_ES.ISO8859-1', 'galician': 'gl_ES.ISO8859-1', 'gd': 'gd_GB.ISO8859-1', 'gd_gb': 'gd_GB.ISO8859-1', - 'gd_gb.iso88591': 'gd_GB.ISO8859-1', - 'gd_gb.iso885914': 'gd_GB.ISO8859-14', - 'gd_gb.iso885915': 'gd_GB.ISO8859-15', - 'gd_gb@euro': 'gd_GB.ISO8859-15', 'ger_de': 'de_DE.ISO8859-1', - 'ger_de.8859': 'de_DE.ISO8859-1', 'german': 'de_DE.ISO8859-1', 'german.iso88591': 'de_CH.ISO8859-1', 'german_germany': 'de_DE.ISO8859-1', - 'german_germany.8859': 'de_DE.ISO8859-1', + 'gez_er': 'gez_ER.UTF-8', + 'gez_et': 'gez_ET.UTF-8', 'gl': 'gl_ES.ISO8859-1', 'gl_es': 'gl_ES.ISO8859-1', - 'gl_es.iso88591': 'gl_ES.ISO8859-1', - 'gl_es.iso885915': 'gl_ES.ISO8859-15', - 'gl_es.iso885915@euro': 'gl_ES.ISO8859-15', - 'gl_es.utf8@euro': 'gl_ES.UTF-8', - 'gl_es@euro': 'gl_ES.ISO8859-15', 'greek': 'el_GR.ISO8859-7', - 'greek.iso88597': 'el_GR.ISO8859-7', 'gu_in': 'gu_IN.UTF-8', 'gv': 'gv_GB.ISO8859-1', 'gv_gb': 'gv_GB.ISO8859-1', - 'gv_gb.iso88591': 'gv_GB.ISO8859-1', - 'gv_gb.iso885914': 'gv_GB.ISO8859-14', - 'gv_gb.iso885915': 'gv_GB.ISO8859-15', - 'gv_gb@euro': 'gv_GB.ISO8859-15', + 'ha_ng': 'ha_NG.UTF-8', 'he': 'he_IL.ISO8859-8', 'he_il': 'he_IL.ISO8859-8', - 'he_il.cp1255': 'he_IL.CP1255', - 'he_il.iso88598': 'he_IL.ISO8859-8', - 'he_il.microsoftcp1255': 'he_IL.CP1255', - 'hebrew': 'iw_IL.ISO8859-8', - 'hebrew.iso88598': 'iw_IL.ISO8859-8', + 'hebrew': 'he_IL.ISO8859-8', 'hi': 'hi_IN.ISCII-DEV', 'hi_in': 'hi_IN.ISCII-DEV', 'hi_in.isciidev': 'hi_IN.ISCII-DEV', 'hne': 'hne_IN.UTF-8', + 'hne_in': 'hne_IN.UTF-8', 'hr': 'hr_HR.ISO8859-2', 'hr_hr': 'hr_HR.ISO8859-2', - 'hr_hr.iso88592': 'hr_HR.ISO8859-2', 'hrvatski': 'hr_HR.ISO8859-2', + 'hsb_de': 'hsb_DE.ISO8859-2', + 'ht_ht': 'ht_HT.UTF-8', 'hu': 'hu_HU.ISO8859-2', 'hu_hu': 'hu_HU.ISO8859-2', - 'hu_hu.iso88592': 'hu_HU.ISO8859-2', 'hungarian': 'hu_HU.ISO8859-2', + 'hy_am': 'hy_AM.UTF-8', + 'hy_am.armscii8': 'hy_AM.ARMSCII_8', + 'ia': 'ia.UTF-8', + 'ia_fr': 'ia_FR.UTF-8', 'icelandic': 'is_IS.ISO8859-1', - 'icelandic.iso88591': 'is_IS.ISO8859-1', 'id': 'id_ID.ISO8859-1', 'id_id': 'id_ID.ISO8859-1', + 'ig_ng': 'ig_NG.UTF-8', + 'ik_ca': 'ik_CA.UTF-8', 'in': 'id_ID.ISO8859-1', 'in_id': 'id_ID.ISO8859-1', 'is': 'is_IS.ISO8859-1', 'is_is': 'is_IS.ISO8859-1', - 'is_is.iso88591': 'is_IS.ISO8859-1', - 'is_is.iso885915': 'is_IS.ISO8859-15', - 'is_is@euro': 'is_IS.ISO8859-15', 'iso-8859-1': 'en_US.ISO8859-1', 'iso-8859-15': 'en_US.ISO8859-15', 'iso8859-1': 'en_US.ISO8859-1', @@ -1191,76 +1084,55 @@ def getpreferredencoding(do_setlocale = True): 'iso_8859_1': 'en_US.ISO8859-1', 'iso_8859_15': 'en_US.ISO8859-15', 'it': 'it_IT.ISO8859-1', - 'it.iso885915': 'it_IT.ISO8859-15', 'it_ch': 'it_CH.ISO8859-1', - 'it_ch.iso88591': 'it_CH.ISO8859-1', - 'it_ch.iso885915': 'it_CH.ISO8859-15', - 'it_ch@euro': 'it_CH.ISO8859-15', 'it_it': 'it_IT.ISO8859-1', - 'it_it.88591': 'it_IT.ISO8859-1', - 'it_it.iso88591': 'it_IT.ISO8859-1', - 'it_it.iso885915': 'it_IT.ISO8859-15', - 'it_it.iso885915@euro': 'it_IT.ISO8859-15', - 'it_it.utf8@euro': 'it_IT.UTF-8', - 'it_it@euro': 'it_IT.ISO8859-15', 'italian': 'it_IT.ISO8859-1', - 'italian.iso88591': 'it_IT.ISO8859-1', 'iu': 'iu_CA.NUNACOM-8', 'iu_ca': 'iu_CA.NUNACOM-8', 'iu_ca.nunacom8': 'iu_CA.NUNACOM-8', 'iw': 'he_IL.ISO8859-8', 'iw_il': 'he_IL.ISO8859-8', - 'iw_il.iso88598': 'he_IL.ISO8859-8', + 'iw_il.utf8': 'iw_IL.UTF-8', 'ja': 'ja_JP.eucJP', - 'ja.jis': 'ja_JP.JIS7', - 'ja.sjis': 'ja_JP.SJIS', 'ja_jp': 'ja_JP.eucJP', - 'ja_jp.ajec': 'ja_JP.eucJP', 'ja_jp.euc': 'ja_JP.eucJP', - 'ja_jp.eucjp': 'ja_JP.eucJP', - 'ja_jp.iso-2022-jp': 'ja_JP.JIS7', - 'ja_jp.iso2022jp': 'ja_JP.JIS7', - 'ja_jp.jis': 'ja_JP.JIS7', - 'ja_jp.jis7': 'ja_JP.JIS7', 'ja_jp.mscode': 'ja_JP.SJIS', 'ja_jp.pck': 'ja_JP.SJIS', - 'ja_jp.sjis': 'ja_JP.SJIS', - 'ja_jp.ujis': 'ja_JP.eucJP', 'japan': 'ja_JP.eucJP', 'japanese': 'ja_JP.eucJP', 'japanese-euc': 'ja_JP.eucJP', 'japanese.euc': 'ja_JP.eucJP', - 'japanese.sjis': 'ja_JP.SJIS', 'jp_jp': 'ja_JP.eucJP', 'ka': 'ka_GE.GEORGIAN-ACADEMY', 'ka_ge': 'ka_GE.GEORGIAN-ACADEMY', 'ka_ge.georgianacademy': 'ka_GE.GEORGIAN-ACADEMY', 'ka_ge.georgianps': 'ka_GE.GEORGIAN-PS', 'ka_ge.georgianrs': 'ka_GE.GEORGIAN-ACADEMY', + 'kk_kz': 'kk_KZ.RK1048', 'kl': 'kl_GL.ISO8859-1', 'kl_gl': 'kl_GL.ISO8859-1', - 'kl_gl.iso88591': 'kl_GL.ISO8859-1', - 'kl_gl.iso885915': 'kl_GL.ISO8859-15', - 'kl_gl@euro': 'kl_GL.ISO8859-15', 'km_kh': 'km_KH.UTF-8', 'kn': 'kn_IN.UTF-8', 'kn_in': 'kn_IN.UTF-8', 'ko': 'ko_KR.eucKR', 'ko_kr': 'ko_KR.eucKR', 'ko_kr.euc': 'ko_KR.eucKR', - 'ko_kr.euckr': 'ko_KR.eucKR', + 'kok_in': 'kok_IN.UTF-8', 'korean': 'ko_KR.eucKR', 'korean.euc': 'ko_KR.eucKR', 'ks': 'ks_IN.UTF-8', - 'ks_in@devanagari': 'ks_IN@devanagari.UTF-8', + 'ks_in': 'ks_IN.UTF-8', + 'ks_in@devanagari.utf8': 'ks_IN.UTF-8@devanagari', + 'ku_tr': 'ku_TR.ISO8859-9', 'kw': 'kw_GB.ISO8859-1', 'kw_gb': 'kw_GB.ISO8859-1', - 'kw_gb.iso88591': 'kw_GB.ISO8859-1', - 'kw_gb.iso885914': 'kw_GB.ISO8859-14', - 'kw_gb.iso885915': 'kw_GB.ISO8859-15', - 'kw_gb@euro': 'kw_GB.ISO8859-15', 'ky': 'ky_KG.UTF-8', 'ky_kg': 'ky_KG.UTF-8', + 'lb_lu': 'lb_LU.UTF-8', + 'lg_ug': 'lg_UG.ISO8859-10', + 'li_be': 'li_BE.UTF-8', + 'li_nl': 'li_NL.UTF-8', + 'lij_it': 'lij_IT.UTF-8', 'lithuanian': 'lt_LT.ISO8859-13', 'lo': 'lo_LA.MULELAO-1', 'lo_la': 'lo_LA.MULELAO-1', @@ -1269,150 +1141,102 @@ def getpreferredencoding(do_setlocale = True): 'lo_la.mulelao1': 'lo_LA.MULELAO-1', 'lt': 'lt_LT.ISO8859-13', 'lt_lt': 'lt_LT.ISO8859-13', - 'lt_lt.iso885913': 'lt_LT.ISO8859-13', - 'lt_lt.iso88594': 'lt_LT.ISO8859-4', 'lv': 'lv_LV.ISO8859-13', 'lv_lv': 'lv_LV.ISO8859-13', - 'lv_lv.iso885913': 'lv_LV.ISO8859-13', - 'lv_lv.iso88594': 'lv_LV.ISO8859-4', + 'mag_in': 'mag_IN.UTF-8', 'mai': 'mai_IN.UTF-8', + 'mai_in': 'mai_IN.UTF-8', + 'mg_mg': 'mg_MG.ISO8859-15', + 'mhr_ru': 'mhr_RU.UTF-8', 'mi': 'mi_NZ.ISO8859-1', 'mi_nz': 'mi_NZ.ISO8859-1', - 'mi_nz.iso88591': 'mi_NZ.ISO8859-1', 'mk': 'mk_MK.ISO8859-5', 'mk_mk': 'mk_MK.ISO8859-5', - 'mk_mk.cp1251': 'mk_MK.CP1251', - 'mk_mk.iso88595': 'mk_MK.ISO8859-5', - 'mk_mk.microsoftcp1251': 'mk_MK.CP1251', 'ml': 'ml_IN.UTF-8', + 'ml_in': 'ml_IN.UTF-8', + 'mn_mn': 'mn_MN.UTF-8', + 'mni_in': 'mni_IN.UTF-8', 'mr': 'mr_IN.UTF-8', 'mr_in': 'mr_IN.UTF-8', 'ms': 'ms_MY.ISO8859-1', 'ms_my': 'ms_MY.ISO8859-1', - 'ms_my.iso88591': 'ms_MY.ISO8859-1', 'mt': 'mt_MT.ISO8859-3', 'mt_mt': 'mt_MT.ISO8859-3', - 'mt_mt.iso88593': 'mt_MT.ISO8859-3', + 'my_mm': 'my_MM.UTF-8', + 'nan_tw@latin': 'nan_TW.UTF-8@latin', 'nb': 'nb_NO.ISO8859-1', 'nb_no': 'nb_NO.ISO8859-1', - 'nb_no.88591': 'nb_NO.ISO8859-1', - 'nb_no.iso88591': 'nb_NO.ISO8859-1', - 'nb_no.iso885915': 'nb_NO.ISO8859-15', - 'nb_no@euro': 'nb_NO.ISO8859-15', + 'nds_de': 'nds_DE.UTF-8', + 'nds_nl': 'nds_NL.UTF-8', + 'ne_np': 'ne_NP.UTF-8', + 'nhn_mx': 'nhn_MX.UTF-8', + 'niu_nu': 'niu_NU.UTF-8', + 'niu_nz': 'niu_NZ.UTF-8', 'nl': 'nl_NL.ISO8859-1', - 'nl.iso885915': 'nl_NL.ISO8859-15', + 'nl_aw': 'nl_AW.UTF-8', 'nl_be': 'nl_BE.ISO8859-1', - 'nl_be.88591': 'nl_BE.ISO8859-1', - 'nl_be.iso88591': 'nl_BE.ISO8859-1', - 'nl_be.iso885915': 'nl_BE.ISO8859-15', - 'nl_be.iso885915@euro': 'nl_BE.ISO8859-15', - 'nl_be.utf8@euro': 'nl_BE.UTF-8', - 'nl_be@euro': 'nl_BE.ISO8859-15', 'nl_nl': 'nl_NL.ISO8859-1', - 'nl_nl.88591': 'nl_NL.ISO8859-1', - 'nl_nl.iso88591': 'nl_NL.ISO8859-1', - 'nl_nl.iso885915': 'nl_NL.ISO8859-15', - 'nl_nl.iso885915@euro': 'nl_NL.ISO8859-15', - 'nl_nl.utf8@euro': 'nl_NL.UTF-8', - 'nl_nl@euro': 'nl_NL.ISO8859-15', 'nn': 'nn_NO.ISO8859-1', 'nn_no': 'nn_NO.ISO8859-1', - 'nn_no.88591': 'nn_NO.ISO8859-1', - 'nn_no.iso88591': 'nn_NO.ISO8859-1', - 'nn_no.iso885915': 'nn_NO.ISO8859-15', - 'nn_no@euro': 'nn_NO.ISO8859-15', 'no': 'no_NO.ISO8859-1', 'no@nynorsk': 'ny_NO.ISO8859-1', 'no_no': 'no_NO.ISO8859-1', - 'no_no.88591': 'no_NO.ISO8859-1', - 'no_no.iso88591': 'no_NO.ISO8859-1', - 'no_no.iso885915': 'no_NO.ISO8859-15', 'no_no.iso88591@bokmal': 'no_NO.ISO8859-1', 'no_no.iso88591@nynorsk': 'no_NO.ISO8859-1', - 'no_no@euro': 'no_NO.ISO8859-15', 'norwegian': 'no_NO.ISO8859-1', - 'norwegian.iso88591': 'no_NO.ISO8859-1', 'nr': 'nr_ZA.ISO8859-1', 'nr_za': 'nr_ZA.ISO8859-1', - 'nr_za.iso88591': 'nr_ZA.ISO8859-1', 'nso': 'nso_ZA.ISO8859-15', 'nso_za': 'nso_ZA.ISO8859-15', - 'nso_za.iso885915': 'nso_ZA.ISO8859-15', 'ny': 'ny_NO.ISO8859-1', 'ny_no': 'ny_NO.ISO8859-1', - 'ny_no.88591': 'ny_NO.ISO8859-1', - 'ny_no.iso88591': 'ny_NO.ISO8859-1', - 'ny_no.iso885915': 'ny_NO.ISO8859-15', - 'ny_no@euro': 'ny_NO.ISO8859-15', 'nynorsk': 'nn_NO.ISO8859-1', 'oc': 'oc_FR.ISO8859-1', 'oc_fr': 'oc_FR.ISO8859-1', - 'oc_fr.iso88591': 'oc_FR.ISO8859-1', - 'oc_fr.iso885915': 'oc_FR.ISO8859-15', - 'oc_fr@euro': 'oc_FR.ISO8859-15', + 'om_et': 'om_ET.UTF-8', + 'om_ke': 'om_KE.ISO8859-1', 'or': 'or_IN.UTF-8', + 'or_in': 'or_IN.UTF-8', + 'os_ru': 'os_RU.UTF-8', 'pa': 'pa_IN.UTF-8', 'pa_in': 'pa_IN.UTF-8', + 'pa_pk': 'pa_PK.UTF-8', + 'pap_an': 'pap_AN.UTF-8', 'pd': 'pd_US.ISO8859-1', 'pd_de': 'pd_DE.ISO8859-1', - 'pd_de.iso88591': 'pd_DE.ISO8859-1', - 'pd_de.iso885915': 'pd_DE.ISO8859-15', - 'pd_de@euro': 'pd_DE.ISO8859-15', 'pd_us': 'pd_US.ISO8859-1', - 'pd_us.iso88591': 'pd_US.ISO8859-1', - 'pd_us.iso885915': 'pd_US.ISO8859-15', - 'pd_us@euro': 'pd_US.ISO8859-15', 'ph': 'ph_PH.ISO8859-1', 'ph_ph': 'ph_PH.ISO8859-1', - 'ph_ph.iso88591': 'ph_PH.ISO8859-1', 'pl': 'pl_PL.ISO8859-2', 'pl_pl': 'pl_PL.ISO8859-2', - 'pl_pl.iso88592': 'pl_PL.ISO8859-2', 'polish': 'pl_PL.ISO8859-2', 'portuguese': 'pt_PT.ISO8859-1', - 'portuguese.iso88591': 'pt_PT.ISO8859-1', 'portuguese_brazil': 'pt_BR.ISO8859-1', - 'portuguese_brazil.8859': 'pt_BR.ISO8859-1', 'posix': 'C', 'posix-utf2': 'C', 'pp': 'pp_AN.ISO8859-1', 'pp_an': 'pp_AN.ISO8859-1', - 'pp_an.iso88591': 'pp_AN.ISO8859-1', + 'ps_af': 'ps_AF.UTF-8', 'pt': 'pt_PT.ISO8859-1', - 'pt.iso885915': 'pt_PT.ISO8859-15', 'pt_br': 'pt_BR.ISO8859-1', - 'pt_br.88591': 'pt_BR.ISO8859-1', - 'pt_br.iso88591': 'pt_BR.ISO8859-1', - 'pt_br.iso885915': 'pt_BR.ISO8859-15', - 'pt_br@euro': 'pt_BR.ISO8859-15', 'pt_pt': 'pt_PT.ISO8859-1', - 'pt_pt.88591': 'pt_PT.ISO8859-1', - 'pt_pt.iso88591': 'pt_PT.ISO8859-1', - 'pt_pt.iso885915': 'pt_PT.ISO8859-15', - 'pt_pt.iso885915@euro': 'pt_PT.ISO8859-15', - 'pt_pt.utf8@euro': 'pt_PT.UTF-8', - 'pt_pt@euro': 'pt_PT.ISO8859-15', 'ro': 'ro_RO.ISO8859-2', 'ro_ro': 'ro_RO.ISO8859-2', - 'ro_ro.iso88592': 'ro_RO.ISO8859-2', 'romanian': 'ro_RO.ISO8859-2', 'ru': 'ru_RU.UTF-8', - 'ru.koi8r': 'ru_RU.KOI8-R', 'ru_ru': 'ru_RU.UTF-8', - 'ru_ru.cp1251': 'ru_RU.CP1251', - 'ru_ru.iso88595': 'ru_RU.ISO8859-5', - 'ru_ru.koi8r': 'ru_RU.KOI8-R', - 'ru_ru.microsoftcp1251': 'ru_RU.CP1251', 'ru_ua': 'ru_UA.KOI8-U', - 'ru_ua.cp1251': 'ru_UA.CP1251', - 'ru_ua.koi8u': 'ru_UA.KOI8-U', - 'ru_ua.microsoftcp1251': 'ru_UA.CP1251', 'rumanian': 'ro_RO.ISO8859-2', 'russian': 'ru_RU.ISO8859-5', 'rw': 'rw_RW.ISO8859-1', 'rw_rw': 'rw_RW.ISO8859-1', - 'rw_rw.iso88591': 'rw_RW.ISO8859-1', - 'sd': 'sd_IN@devanagari.UTF-8', + 'sa_in': 'sa_IN.UTF-8', + 'sat_in': 'sat_IN.UTF-8', + 'sc_it': 'sc_IT.UTF-8', + 'sd': 'sd_IN.UTF-8', + 'sd_in': 'sd_IN.UTF-8', + 'sd_in@devanagari.utf8': 'sd_IN.UTF-8@devanagari', + 'sd_pk': 'sd_PK.UTF-8', 'se_no': 'se_NO.UTF-8', 'serbocroatian': 'sr_RS.UTF-8@latin', 'sh': 'sr_RS.UTF-8@latin', @@ -1421,42 +1245,38 @@ def getpreferredencoding(do_setlocale = True): 'sh_hr.iso88592': 'hr_HR.ISO8859-2', 'sh_sp': 'sr_CS.ISO8859-2', 'sh_yu': 'sr_RS.UTF-8@latin', + 'shs_ca': 'shs_CA.UTF-8', 'si': 'si_LK.UTF-8', 'si_lk': 'si_LK.UTF-8', + 'sid_et': 'sid_ET.UTF-8', 'sinhala': 'si_LK.UTF-8', 'sk': 'sk_SK.ISO8859-2', 'sk_sk': 'sk_SK.ISO8859-2', - 'sk_sk.iso88592': 'sk_SK.ISO8859-2', 'sl': 'sl_SI.ISO8859-2', 'sl_cs': 'sl_CS.ISO8859-2', 'sl_si': 'sl_SI.ISO8859-2', - 'sl_si.iso88592': 'sl_SI.ISO8859-2', 'slovak': 'sk_SK.ISO8859-2', 'slovene': 'sl_SI.ISO8859-2', 'slovenian': 'sl_SI.ISO8859-2', + 'so_dj': 'so_DJ.ISO8859-1', + 'so_et': 'so_ET.UTF-8', + 'so_ke': 'so_KE.ISO8859-1', + 'so_so': 'so_SO.ISO8859-1', 'sp': 'sr_CS.ISO8859-5', 'sp_yu': 'sr_CS.ISO8859-5', 'spanish': 'es_ES.ISO8859-1', - 'spanish.iso88591': 'es_ES.ISO8859-1', 'spanish_spain': 'es_ES.ISO8859-1', - 'spanish_spain.8859': 'es_ES.ISO8859-1', 'sq': 'sq_AL.ISO8859-2', 'sq_al': 'sq_AL.ISO8859-2', - 'sq_al.iso88592': 'sq_AL.ISO8859-2', + 'sq_mk': 'sq_MK.UTF-8', 'sr': 'sr_RS.UTF-8', 'sr@cyrillic': 'sr_RS.UTF-8', - 'sr@latin': 'sr_RS.UTF-8@latin', - 'sr@latn': 'sr_RS.UTF-8@latin', - 'sr_cs': 'sr_RS.UTF-8', - 'sr_cs.iso88592': 'sr_CS.ISO8859-2', + 'sr@latn': 'sr_CS.UTF-8@latin', + 'sr_cs': 'sr_CS.UTF-8', 'sr_cs.iso88592@latn': 'sr_CS.ISO8859-2', - 'sr_cs.iso88595': 'sr_CS.ISO8859-5', - 'sr_cs.utf8@latn': 'sr_RS.UTF-8@latin', - 'sr_cs@latn': 'sr_RS.UTF-8@latin', + 'sr_cs@latn': 'sr_CS.UTF-8@latin', 'sr_me': 'sr_ME.UTF-8', 'sr_rs': 'sr_RS.UTF-8', - 'sr_rs.utf8@latn': 'sr_RS.UTF-8@latin', - 'sr_rs@latin': 'sr_RS.UTF-8@latin', 'sr_rs@latn': 'sr_RS.UTF-8@latin', 'sr_sp': 'sr_CS.ISO8859-2', 'sr_yu': 'sr_RS.UTF-8@latin', @@ -1465,78 +1285,64 @@ def getpreferredencoding(do_setlocale = True): 'sr_yu.iso88595': 'sr_CS.ISO8859-5', 'sr_yu.iso88595@cyrillic': 'sr_CS.ISO8859-5', 'sr_yu.microsoftcp1251@cyrillic': 'sr_CS.CP1251', + 'sr_yu.utf8': 'sr_RS.UTF-8', 'sr_yu.utf8@cyrillic': 'sr_RS.UTF-8', 'sr_yu@cyrillic': 'sr_RS.UTF-8', 'ss': 'ss_ZA.ISO8859-1', 'ss_za': 'ss_ZA.ISO8859-1', - 'ss_za.iso88591': 'ss_ZA.ISO8859-1', 'st': 'st_ZA.ISO8859-1', 'st_za': 'st_ZA.ISO8859-1', - 'st_za.iso88591': 'st_ZA.ISO8859-1', 'sv': 'sv_SE.ISO8859-1', - 'sv.iso885915': 'sv_SE.ISO8859-15', 'sv_fi': 'sv_FI.ISO8859-1', - 'sv_fi.iso88591': 'sv_FI.ISO8859-1', - 'sv_fi.iso885915': 'sv_FI.ISO8859-15', - 'sv_fi.iso885915@euro': 'sv_FI.ISO8859-15', - 'sv_fi.utf8@euro': 'sv_FI.UTF-8', - 'sv_fi@euro': 'sv_FI.ISO8859-15', 'sv_se': 'sv_SE.ISO8859-1', - 'sv_se.88591': 'sv_SE.ISO8859-1', - 'sv_se.iso88591': 'sv_SE.ISO8859-1', - 'sv_se.iso885915': 'sv_SE.ISO8859-15', - 'sv_se@euro': 'sv_SE.ISO8859-15', + 'sw_ke': 'sw_KE.UTF-8', + 'sw_tz': 'sw_TZ.UTF-8', 'swedish': 'sv_SE.ISO8859-1', - 'swedish.iso88591': 'sv_SE.ISO8859-1', + 'szl_pl': 'szl_PL.UTF-8', 'ta': 'ta_IN.TSCII-0', 'ta_in': 'ta_IN.TSCII-0', 'ta_in.tscii': 'ta_IN.TSCII-0', 'ta_in.tscii0': 'ta_IN.TSCII-0', + 'ta_lk': 'ta_LK.UTF-8', 'te': 'te_IN.UTF-8', + 'te_in': 'te_IN.UTF-8', 'tg': 'tg_TJ.KOI8-C', 'tg_tj': 'tg_TJ.KOI8-C', - 'tg_tj.koi8c': 'tg_TJ.KOI8-C', 'th': 'th_TH.ISO8859-11', 'th_th': 'th_TH.ISO8859-11', - 'th_th.iso885911': 'th_TH.ISO8859-11', 'th_th.tactis': 'th_TH.TIS620', 'th_th.tis620': 'th_TH.TIS620', 'thai': 'th_TH.ISO8859-11', + 'ti_er': 'ti_ER.UTF-8', + 'ti_et': 'ti_ET.UTF-8', + 'tig_er': 'tig_ER.UTF-8', + 'tk_tm': 'tk_TM.UTF-8', 'tl': 'tl_PH.ISO8859-1', 'tl_ph': 'tl_PH.ISO8859-1', - 'tl_ph.iso88591': 'tl_PH.ISO8859-1', 'tn': 'tn_ZA.ISO8859-15', 'tn_za': 'tn_ZA.ISO8859-15', - 'tn_za.iso885915': 'tn_ZA.ISO8859-15', 'tr': 'tr_TR.ISO8859-9', + 'tr_cy': 'tr_CY.ISO8859-9', 'tr_tr': 'tr_TR.ISO8859-9', - 'tr_tr.iso88599': 'tr_TR.ISO8859-9', 'ts': 'ts_ZA.ISO8859-1', 'ts_za': 'ts_ZA.ISO8859-1', - 'ts_za.iso88591': 'ts_ZA.ISO8859-1', 'tt': 'tt_RU.TATAR-CYR', 'tt_ru': 'tt_RU.TATAR-CYR', - 'tt_ru.koi8c': 'tt_RU.KOI8-C', 'tt_ru.tatarcyr': 'tt_RU.TATAR-CYR', + 'tt_ru@iqtelif': 'tt_RU.UTF-8@iqtelif', 'turkish': 'tr_TR.ISO8859-9', - 'turkish.iso88599': 'tr_TR.ISO8859-9', + 'ug_cn': 'ug_CN.UTF-8', 'uk': 'uk_UA.KOI8-U', 'uk_ua': 'uk_UA.KOI8-U', - 'uk_ua.cp1251': 'uk_UA.CP1251', - 'uk_ua.iso88595': 'uk_UA.ISO8859-5', - 'uk_ua.koi8u': 'uk_UA.KOI8-U', - 'uk_ua.microsoftcp1251': 'uk_UA.CP1251', 'univ': 'en_US.utf', 'universal': 'en_US.utf', 'universal.utf8@ucs4': 'en_US.UTF-8', + 'unm_us': 'unm_US.UTF-8', 'ur': 'ur_PK.CP1256', + 'ur_in': 'ur_IN.UTF-8', 'ur_pk': 'ur_PK.CP1256', - 'ur_pk.cp1256': 'ur_PK.CP1256', - 'ur_pk.microsoftcp1256': 'ur_PK.CP1256', 'uz': 'uz_UZ.UTF-8', 'uz_uz': 'uz_UZ.UTF-8', - 'uz_uz.iso88591': 'uz_UZ.ISO8859-1', - 'uz_uz.utf8@cyrillic': 'uz_UZ.UTF-8', 'uz_uz@cyrillic': 'uz_UZ.UTF-8', 've': 've_ZA.UTF-8', 've_za': 've_ZA.UTF-8', @@ -1548,35 +1354,28 @@ def getpreferredencoding(do_setlocale = True): 'vi_vn.viscii111': 'vi_VN.VISCII', 'wa': 'wa_BE.ISO8859-1', 'wa_be': 'wa_BE.ISO8859-1', - 'wa_be.iso88591': 'wa_BE.ISO8859-1', - 'wa_be.iso885915': 'wa_BE.ISO8859-15', - 'wa_be.iso885915@euro': 'wa_BE.ISO8859-15', - 'wa_be@euro': 'wa_BE.ISO8859-15', + 'wae_ch': 'wae_CH.UTF-8', + 'wal_et': 'wal_ET.UTF-8', + 'wo_sn': 'wo_SN.UTF-8', 'xh': 'xh_ZA.ISO8859-1', 'xh_za': 'xh_ZA.ISO8859-1', - 'xh_za.iso88591': 'xh_ZA.ISO8859-1', 'yi': 'yi_US.CP1255', 'yi_us': 'yi_US.CP1255', - 'yi_us.cp1255': 'yi_US.CP1255', - 'yi_us.microsoftcp1255': 'yi_US.CP1255', + 'yo_ng': 'yo_NG.UTF-8', + 'yue_hk': 'yue_HK.UTF-8', 'zh': 'zh_CN.eucCN', 'zh_cn': 'zh_CN.gb2312', 'zh_cn.big5': 'zh_TW.big5', 'zh_cn.euc': 'zh_CN.eucCN', - 'zh_cn.gb18030': 'zh_CN.gb18030', - 'zh_cn.gb2312': 'zh_CN.gb2312', - 'zh_cn.gbk': 'zh_CN.gbk', 'zh_hk': 'zh_HK.big5hkscs', - 'zh_hk.big5': 'zh_HK.big5', 'zh_hk.big5hk': 'zh_HK.big5hkscs', - 'zh_hk.big5hkscs': 'zh_HK.big5hkscs', + 'zh_sg': 'zh_SG.GB2312', + 'zh_sg.gbk': 'zh_SG.GBK', 'zh_tw': 'zh_TW.big5', - 'zh_tw.big5': 'zh_TW.big5', 'zh_tw.euc': 'zh_TW.eucTW', 'zh_tw.euctw': 'zh_TW.eucTW', 'zu': 'zu_ZA.ISO8859-1', 'zu_za': 'zu_ZA.ISO8859-1', - 'zu_za.iso88591': 'zu_ZA.ISO8859-1', } # diff --git a/Lib/logging/__init__.py b/Lib/logging/__init__.py index 9b41b9d2779e..b1dc31962820 100644 --- a/Lib/logging/__init__.py +++ b/Lib/logging/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2001-2013 by Vinay Sajip. All Rights Reserved. +# Copyright 2001-2015 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, @@ -18,12 +18,13 @@ Logging package for Python. Based on PEP 282 and comments thereto in comp.lang.python. -Copyright (C) 2001-2013 Vinay Sajip. All Rights Reserved. +Copyright (C) 2001-2015 Vinay Sajip. All Rights Reserved. To use, simply 'import logging' and log away! """ -import sys, os, time, io, traceback, warnings, weakref +import sys, os, time, io, traceback, warnings, weakref, collections + from string import Template __all__ = ['BASIC_FORMAT', 'BufferingFormatter', 'CRITICAL', 'DEBUG', 'ERROR', @@ -42,6 +43,7 @@ __author__ = "Vinay Sajip <vinay_sajip@red-dove.com>" __status__ = "production" +# The following module attributes are no longer updated. __version__ = "0.5.1.2" __date__ = "07 February 2010" @@ -49,34 +51,6 @@ # Miscellaneous module data #--------------------------------------------------------------------------- -# -# _srcfile is used when walking the stack to check when we've got the first -# caller stack frame. -# -if hasattr(sys, 'frozen'): #support for py2exe - _srcfile = "logging%s__init__%s" % (os.sep, __file__[-4:]) -else: - _srcfile = __file__ -_srcfile = os.path.normcase(_srcfile) - - -if hasattr(sys, '_getframe'): - currentframe = lambda: sys._getframe(3) -else: #pragma: no cover - def currentframe(): - """Return the frame object for the caller's stack frame.""" - try: - raise Exception - except Exception: - return sys.exc_info()[2].tb_frame.f_back - -# _srcfile is only used in conjunction with sys._getframe(). -# To provide compatibility with older versions of Python, set _srcfile -# to None if _getframe() is not available; this value will prevent -# findCaller() from being called. -#if not hasattr(sys, "_getframe"): -# _srcfile = None - # #_startTime is used as the base when calculating the relative time of events # @@ -155,7 +129,8 @@ def getLevelName(level): Otherwise, the string "Level %s" % level is returned. """ - return _levelToName.get(level, ("Level %s" % level)) + # See Issue #22386 for the reason for this convoluted expression + return _levelToName.get(level, _nameToLevel.get(level, ("Level %s" % level))) def addLevelName(level, levelName): """ @@ -170,6 +145,40 @@ def addLevelName(level, levelName): finally: _releaseLock() +if hasattr(sys, '_getframe'): + currentframe = lambda: sys._getframe(3) +else: #pragma: no cover + def currentframe(): + """Return the frame object for the caller's stack frame.""" + try: + raise Exception + except Exception: + return sys.exc_info()[2].tb_frame.f_back + +# +# _srcfile is used when walking the stack to check when we've got the first +# caller stack frame, by skipping frames whose filename is that of this +# module's source. It therefore should contain the filename of this module's +# source file. +# +# Ordinarily we would use __file__ for this, but frozen modules don't always +# have __file__ set, for some reason (see Issue #21736). Thus, we get the +# filename from a handy code object from a function defined in this module. +# (There's no particular reason for picking addLevelName.) +# + +_srcfile = os.path.normcase(addLevelName.__code__.co_filename) + +# _srcfile is only used in conjunction with sys._getframe(). +# To provide compatibility with older versions of Python, set _srcfile +# to None if _getframe() is not available; this value will prevent +# findCaller() from being called. You can also do this if you want to avoid +# the overhead of fetching caller information, even when _getframe() is +# available. +#if not hasattr(sys, '_getframe'): +# _srcfile = None + + def _checkLevel(level): if isinstance(level, int): rv = level @@ -252,7 +261,13 @@ def __init__(self, name, level, pathname, lineno, # 'Value is %d' instead of 'Value is 0'. # For the use case of passing a dictionary, this should not be a # problem. - if args and len(args) == 1 and isinstance(args[0], dict) and args[0]: + # Issue #21172: a request was made to relax the isinstance check + # to hasattr(args[0], '__getitem__'). However, the docs on string + # formatting still seem to suggest a mapping object is required. + # Thus, while not removing the isinstance check, it does now look + # for collections.Mapping rather than, as before, dict. + if (args and len(args) == 1 and isinstance(args[0], collections.Mapping) + and args[0]): args = args[0] self.args = args self.levelname = getLevelName(level) @@ -301,6 +316,8 @@ def __str__(self): return '<LogRecord: %s, %s, %s, %s, "%s">'%(self.name, self.levelno, self.pathname, self.lineno, self.msg) + __repr__ = __str__ + def getMessage(self): """ Return the message for this LogRecord. @@ -390,10 +407,12 @@ def usesTime(self): def format(self, record): return self._tpl.substitute(**record.__dict__) +BASIC_FORMAT = "%(levelname)s:%(name)s:%(message)s" + _STYLES = { - '%': PercentStyle, - '{': StrFormatStyle, - '$': StringTemplateStyle + '%': (PercentStyle, BASIC_FORMAT), + '{': (StrFormatStyle, '{levelname}:{name}:{message}'), + '$': (StringTemplateStyle, '${levelname}:${name}:${message}'), } class Formatter(object): @@ -458,7 +477,7 @@ def __init__(self, fmt=None, datefmt=None, style='%'): if style not in _STYLES: raise ValueError('Style must be one of: %s' % ','.join( _STYLES.keys())) - self._style = _STYLES[style](fmt) + self._style = _STYLES[style][0](fmt) self._fmt = self._style._fmt self.datefmt = datefmt @@ -708,16 +727,17 @@ def _removeHandlerRef(wr): Remove a handler reference from the internal cleanup list. """ # This function can be called during module teardown, when globals are - # set to None. If _acquireLock is None, assume this is the case and do - # nothing. - if (_acquireLock is not None and _handlerList is not None and - _releaseLock is not None): - _acquireLock() + # set to None. It can also be called from another thread. So we need to + # pre-emptively grab the necessary globals and check if they're None, + # to prevent race conditions and failures during interpreter shutdown. + acquire, release, handlers = _acquireLock, _releaseLock, _handlerList + if acquire and release and handlers: + acquire() try: - if wr in _handlerList: - _handlerList.remove(wr) + if wr in handlers: + handlers.remove(wr) finally: - _releaseLock() + release() def _addHandlerRef(handler): """ @@ -900,8 +920,15 @@ def handleError(self, record): sys.stderr.write('Logged from file %s, line %s\n' % ( record.filename, record.lineno)) # Issue 18671: output logging message and arguments - sys.stderr.write('Message: %r\n' - 'Arguments: %s\n' % (record.msg, record.args)) + try: + sys.stderr.write('Message: %r\n' + 'Arguments: %s\n' % (record.msg, + record.args)) + except Exception: + sys.stderr.write('Unable to print the message and arguments' + ' - possible formatting error.\nUse the' + ' traceback above to help find the error.\n' + ) except OSError: #pragma: no cover pass # see issue 5971 finally: @@ -1061,7 +1088,6 @@ def append(self, alogger): # # Determine which class to use when instantiating loggers. # -_loggerClass = None def setLoggerClass(klass): """ @@ -1080,7 +1106,6 @@ def getLoggerClass(): """ Return the class to be used when instantiating a logger. """ - return _loggerClass class Manager(object): @@ -1277,12 +1302,11 @@ def error(self, msg, *args, **kwargs): if self.isEnabledFor(ERROR): self._log(ERROR, msg, args, **kwargs) - def exception(self, msg, *args, **kwargs): + def exception(self, msg, *args, exc_info=True, **kwargs): """ Convenience method for logging an ERROR with exception information. """ - kwargs['exc_info'] = True - self.error(msg, *args, **kwargs) + self.error(msg, *args, exc_info=exc_info, **kwargs) def critical(self, msg, *args, **kwargs): """ @@ -1377,7 +1401,9 @@ def _log(self, level, msg, args, exc_info=None, extra=None, stack_info=False): else: # pragma: no cover fn, lno, func = "(unknown file)", 0, "(unknown function)" if exc_info: - if not isinstance(exc_info, tuple): + if isinstance(exc_info, BaseException): + exc_info = (type(exc_info), exc_info, exc_info.__traceback__) + elif not isinstance(exc_info, tuple): exc_info = sys.exc_info() record = self.makeRecord(self.name, level, fn, lno, msg, args, exc_info, func, extra, sinfo) @@ -1587,12 +1613,11 @@ def error(self, msg, *args, **kwargs): """ self.log(ERROR, msg, *args, **kwargs) - def exception(self, msg, *args, **kwargs): + def exception(self, msg, *args, exc_info=True, **kwargs): """ Delegate an exception call to the underlying logger. """ - kwargs["exc_info"] = True - self.log(ERROR, msg, *args, **kwargs) + self.log(ERROR, msg, *args, exc_info=exc_info, **kwargs) def critical(self, msg, *args, **kwargs): """ @@ -1643,8 +1668,6 @@ def hasHandlers(self): # Configuration classes and functions #--------------------------------------------------------------------------- -BASIC_FORMAT = "%(levelname)s:%(name)s:%(message)s" - def basicConfig(**kwargs): """ Do basic configuration for the logging system. @@ -1700,7 +1723,7 @@ def basicConfig(**kwargs): _acquireLock() try: if len(root.handlers) == 0: - handlers = kwargs.get("handlers") + handlers = kwargs.pop("handlers", None) if handlers is None: if "stream" in kwargs and "filename" in kwargs: raise ValueError("'stream' and 'filename' should not be " @@ -1710,25 +1733,31 @@ def basicConfig(**kwargs): raise ValueError("'stream' or 'filename' should not be " "specified together with 'handlers'") if handlers is None: - filename = kwargs.get("filename") + filename = kwargs.pop("filename", None) if filename: - mode = kwargs.get("filemode", 'a') + mode = kwargs.pop("filemode", 'a') h = FileHandler(filename, mode) else: - stream = kwargs.get("stream") + stream = kwargs.pop("stream", None) h = StreamHandler(stream) handlers = [h] - fs = kwargs.get("format", BASIC_FORMAT) - dfs = kwargs.get("datefmt", None) - style = kwargs.get("style", '%') + dfs = kwargs.pop("datefmt", None) + style = kwargs.pop("style", '%') + if style not in _STYLES: + raise ValueError('Style must be one of: %s' % ','.join( + _STYLES.keys())) + fs = kwargs.pop("format", _STYLES[style][1]) fmt = Formatter(fs, dfs, style) for h in handlers: if h.formatter is None: h.setFormatter(fmt) root.addHandler(h) - level = kwargs.get("level") + level = kwargs.pop("level", None) if level is not None: root.setLevel(level) + if kwargs: + keys = ', '.join(kwargs.keys()) + raise ValueError('Unrecognised argument(s): %s' % keys) finally: _releaseLock() @@ -1770,14 +1799,13 @@ def error(msg, *args, **kwargs): basicConfig() root.error(msg, *args, **kwargs) -def exception(msg, *args, **kwargs): +def exception(msg, *args, exc_info=True, **kwargs): """ Log a message with severity 'ERROR' on the root logger, with exception information. If the logger has no handlers, basicConfig() is called to add a console handler with a pre-defined format. """ - kwargs['exc_info'] = True - error(msg, *args, **kwargs) + error(msg, *args, exc_info=exc_info, **kwargs) def warning(msg, *args, **kwargs): """ diff --git a/Lib/logging/config.py b/Lib/logging/config.py index b882a62ab3e6..8a99923bf31e 100644 --- a/Lib/logging/config.py +++ b/Lib/logging/config.py @@ -1,4 +1,4 @@ -# Copyright 2001-2013 by Vinay Sajip. All Rights Reserved. +# Copyright 2001-2014 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, @@ -19,13 +19,19 @@ is based on PEP 282 and comments thereto in comp.lang.python, and influenced by Apache's log4j system. -Copyright (C) 2001-2013 Vinay Sajip. All Rights Reserved. +Copyright (C) 2001-2014 Vinay Sajip. All Rights Reserved. To use, simply 'import logging' and log away! """ -import sys, logging, logging.handlers, socket, struct, traceback, re +import errno import io +import logging +import logging.handlers +import re +import struct +import sys +import traceback try: import _thread as thread @@ -38,10 +44,7 @@ DEFAULT_LOGGING_CONFIG_PORT = 9030 -if sys.platform == "win32": - RESET_ERROR = 10054 #WSAECONNRESET -else: - RESET_ERROR = 104 #ECONNRESET +RESET_ERROR = errno.ECONNRESET # # The following code implements a socket listener for on-the-fly @@ -113,11 +116,12 @@ def _create_formatters(cp): sectname = "formatter_%s" % form fs = cp.get(sectname, "format", raw=True, fallback=None) dfs = cp.get(sectname, "datefmt", raw=True, fallback=None) + stl = cp.get(sectname, "style", raw=True, fallback='%') c = logging.Formatter class_name = cp[sectname].get("class") if class_name: c = _resolve(class_name) - f = c(fs, dfs) + f = c(fs, dfs, stl) formatters[form] = f return formatters @@ -274,6 +278,30 @@ def valid_ident(s): return True +class ConvertingMixin(object): + """For ConvertingXXX's, this mixin class provides common functions""" + + def convert_with_key(self, key, value, replace=True): + result = self.configurator.convert(value) + #If the converted value is different, save for next time + if value is not result: + if replace: + self[key] = result + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + result.key = key + return result + + def convert(self, value): + result = self.configurator.convert(value) + if value is not result: + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + return result + + # The ConvertingXXX classes are wrappers around standard Python containers, # and they serve to convert any suitable values in the container. The # conversion converts base dicts, lists and tuples to their wrapped @@ -283,77 +311,37 @@ def valid_ident(s): # Each wrapper should have a configurator attribute holding the actual # configurator to use for conversion. -class ConvertingDict(dict): +class ConvertingDict(dict, ConvertingMixin): """A converting dictionary wrapper.""" def __getitem__(self, key): value = dict.__getitem__(self, key) - result = self.configurator.convert(value) - #If the converted value is different, save for next time - if value is not result: - self[key] = result - if type(result) in (ConvertingDict, ConvertingList, - ConvertingTuple): - result.parent = self - result.key = key - return result + return self.convert_with_key(key, value) def get(self, key, default=None): value = dict.get(self, key, default) - result = self.configurator.convert(value) - #If the converted value is different, save for next time - if value is not result: - self[key] = result - if type(result) in (ConvertingDict, ConvertingList, - ConvertingTuple): - result.parent = self - result.key = key - return result + return self.convert_with_key(key, value) def pop(self, key, default=None): value = dict.pop(self, key, default) - result = self.configurator.convert(value) - if value is not result: - if type(result) in (ConvertingDict, ConvertingList, - ConvertingTuple): - result.parent = self - result.key = key - return result + return self.convert_with_key(key, value, replace=False) -class ConvertingList(list): +class ConvertingList(list, ConvertingMixin): """A converting list wrapper.""" def __getitem__(self, key): value = list.__getitem__(self, key) - result = self.configurator.convert(value) - #If the converted value is different, save for next time - if value is not result: - self[key] = result - if type(result) in (ConvertingDict, ConvertingList, - ConvertingTuple): - result.parent = self - result.key = key - return result + return self.convert_with_key(key, value) def pop(self, idx=-1): value = list.pop(self, idx) - result = self.configurator.convert(value) - if value is not result: - if type(result) in (ConvertingDict, ConvertingList, - ConvertingTuple): - result.parent = self - return result + return self.convert(value) -class ConvertingTuple(tuple): +class ConvertingTuple(tuple, ConvertingMixin): """A converting tuple wrapper.""" def __getitem__(self, key): value = tuple.__getitem__(self, key) - result = self.configurator.convert(value) - if value is not result: - if type(result) in (ConvertingDict, ConvertingList, - ConvertingTuple): - result.parent = self - result.key = key - return result + # Can't replace a tuple entry. + return self.convert_with_key(key, value, replace=False) class BaseConfigurator(object): """ @@ -673,7 +661,12 @@ def configure_formatter(self, config): fmt = config.get('format', None) dfmt = config.get('datefmt', None) style = config.get('style', '%') - result = logging.Formatter(fmt, dfmt, style) + cname = config.get('class', None) + if not cname: + c = logging.Formatter + else: + c = _resolve(cname) + result = c(fmt, dfmt, style) return result def configure_filter(self, config): @@ -867,12 +860,8 @@ def handle(self): if self.server.ready: self.server.ready.set() except OSError as e: - if not isinstance(e.args, tuple): + if e.errno != RESET_ERROR: raise - else: - errcode = e.args[0] - if errcode != RESET_ERROR: - raise class ConfigSocketReceiver(ThreadingTCPServer): """ diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py index b2e7d445cf9a..d4f8aef6e707 100644 --- a/Lib/logging/handlers.py +++ b/Lib/logging/handlers.py @@ -1,4 +1,4 @@ -# Copyright 2001-2013 by Vinay Sajip. All Rights Reserved. +# Copyright 2001-2015 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, @@ -18,13 +18,12 @@ Additional handlers for the logging package for Python. The core package is based on PEP 282 and comments thereto in comp.lang.python. -Copyright (C) 2001-2013 Vinay Sajip. All Rights Reserved. +Copyright (C) 2001-2015 Vinay Sajip. All Rights Reserved. To use, simply 'import logging.handlers' and log away! """ -import errno, logging, socket, os, pickle, struct, time, re -from codecs import BOM_UTF8 +import logging, socket, os, pickle, struct, time, re from stat import ST_DEV, ST_INO, ST_MTIME import queue try: @@ -464,6 +463,7 @@ def emit(self, record): # we have an open file handle, clean it up self.stream.flush() self.stream.close() + self.stream = None # See Issue #21742: _open () might fail. # open a new file handle and get new stat info from that fd self.stream = self._open() self._statstream() @@ -879,21 +879,21 @@ def emit(self, record): The record is formatted, and then sent to the syslog server. If exception information is present, it is NOT sent to the server. """ - msg = self.format(record) - if self.ident: - msg = self.ident + msg - if self.append_nul: - msg += '\000' - - # We need to convert record level to lowercase, maybe this will - # change in the future. - prio = '<%d>' % self.encodePriority(self.facility, - self.mapPriority(record.levelname)) - prio = prio.encode('utf-8') - # Message is a string. Convert to bytes as required by RFC 5424 - msg = msg.encode('utf-8') - msg = prio + msg try: + msg = self.format(record) + if self.ident: + msg = self.ident + msg + if self.append_nul: + msg += '\000' + + # We need to convert record level to lowercase, maybe this will + # change in the future. + prio = '<%d>' % self.encodePriority(self.facility, + self.mapPriority(record.levelname)) + prio = prio.encode('utf-8') + # Message is a string. Convert to bytes as required by RFC 5424 + msg = msg.encode('utf-8') + msg = prio + msg if self.unixsocket: try: self.socket.send(msg) @@ -931,11 +931,11 @@ def __init__(self, mailhost, fromaddr, toaddrs, subject, default is one second). """ logging.Handler.__init__(self) - if isinstance(mailhost, tuple): + if isinstance(mailhost, (list, tuple)): self.mailhost, self.mailport = mailhost else: self.mailhost, self.mailport = mailhost, None - if isinstance(credentials, tuple): + if isinstance(credentials, (list, tuple)): self.username, self.password = credentials else: self.username = None @@ -1089,7 +1089,8 @@ class HTTPHandler(logging.Handler): A class which sends records to a Web server, using either GET or POST semantics. """ - def __init__(self, host, url, method="GET", secure=False, credentials=None): + def __init__(self, host, url, method="GET", secure=False, credentials=None, + context=None): """ Initialize the instance with the host, the request URL, and the method ("GET" or "POST") @@ -1098,11 +1099,15 @@ def __init__(self, host, url, method="GET", secure=False, credentials=None): method = method.upper() if method not in ["GET", "POST"]: raise ValueError("method must be GET or POST") + if not secure and context is not None: + raise ValueError("context parameter only makes sense " + "with secure=True") self.host = host self.url = url self.method = method self.secure = secure self.credentials = credentials + self.context = context def mapLogRecord(self, record): """ @@ -1122,7 +1127,7 @@ def emit(self, record): import http.client, urllib.parse host = self.host if self.secure: - h = http.client.HTTPSConnection(host) + h = http.client.HTTPSConnection(host, context=self.context) else: h = http.client.HTTPConnection(host) url = self.url @@ -1345,7 +1350,7 @@ class QueueListener(object): """ _sentinel = None - def __init__(self, queue, *handlers): + def __init__(self, queue, *handlers, respect_handler_level=False): """ Initialise an instance with the specified queue and handlers. @@ -1354,6 +1359,7 @@ def __init__(self, queue, *handlers): self.handlers = handlers self._stop = threading.Event() self._thread = None + self.respect_handler_level = respect_handler_level def dequeue(self, block): """ @@ -1394,7 +1400,12 @@ def handle(self, record): """ record = self.prepare(record) for handler in self.handlers: - handler.handle(record) + if not self.respect_handler_level: + process = True + else: + process = record.levelno >= handler.level + if process: + handler.handle(record) def _monitor(self): """ diff --git a/Lib/lzma.py b/Lib/lzma.py index 011ad271fbb0..f1d395817973 100644 --- a/Lib/lzma.py +++ b/Lib/lzma.py @@ -225,11 +225,18 @@ def _fill_buffer(self): raise EOFError("Compressed file ended before the " "end-of-stream marker was reached") - # Continue to next stream. if self._decompressor.eof: + # Continue to next stream. self._decompressor = LZMADecompressor(**self._init_args) - - self._buffer = self._decompressor.decompress(rawblock) + try: + self._buffer = self._decompressor.decompress(rawblock) + except LZMAError: + # Trailing data isn't a valid compressed stream; ignore it. + self._mode = _MODE_READ_EOF + self._size = self._pos + return False + else: + self._buffer = self._decompressor.decompress(rawblock) self._buffer_offset = 0 return True @@ -487,11 +494,18 @@ def decompress(data, format=FORMAT_AUTO, memlimit=None, filters=None): results = [] while True: decomp = LZMADecompressor(format, memlimit, filters) - results.append(decomp.decompress(data)) + try: + res = decomp.decompress(data) + except LZMAError: + if results: + break # Leftover data is not a valid LZMA/XZ stream; ignore it. + else: + raise # Error on the first iteration; bail out. + results.append(res) if not decomp.eof: raise LZMAError("Compressed data ended before the " "end-of-stream marker was reached") - if not decomp.unused_data: - return b"".join(results) - # There is unused data left over. Proceed to next stream. data = decomp.unused_data + if not data: + break + return b"".join(results) diff --git a/Lib/macpath.py b/Lib/macpath.py index d34f9e944cc8..dbcf3684684e 100644 --- a/Lib/macpath.py +++ b/Lib/macpath.py @@ -50,20 +50,24 @@ def isabs(s): def join(s, *p): - colon = _get_colon(s) - path = s - for t in p: - if (not s) or isabs(t): - path = t - continue - if t[:1] == colon: - t = t[1:] - if colon not in path: - path = colon + path - if path[-1:] != colon: - path = path + colon - path = path + t - return path + try: + colon = _get_colon(s) + path = s + for t in p: + if (not path) or isabs(t): + path = t + continue + if t[:1] == colon: + t = t[1:] + if colon not in path: + path = colon + path + if path[-1:] != colon: + path = path + colon + path = path + t + return path + except (TypeError, AttributeError, BytesWarning): + genericpath._check_arg_types('join', s, *p) + raise def split(s): diff --git a/Lib/mailbox.py b/Lib/mailbox.py index 5f591bc3491c..e7f31df1e539 100644 --- a/Lib/mailbox.py +++ b/Lib/mailbox.py @@ -1,5 +1,3 @@ -#! /usr/bin/env python3 - """Read/write support for Maildir, mbox, MH, Babyl, and MMDF mailboxes.""" # Notes for authors of new mailbox subclasses: @@ -8,7 +6,6 @@ # or returning from a flush() method. See functions _sync_flush() and # _sync_close(). -import sys import os import time import calendar @@ -106,7 +103,7 @@ def keys(self): def itervalues(self): """Return an iterator over all messages.""" - for key in self.keys(): + for key in self.iterkeys(): try: value = self[key] except KeyError: @@ -122,7 +119,7 @@ def values(self): def iteritems(self): """Return an iterator over (key, message) tuples.""" - for key in self.keys(): + for key in self.iterkeys(): try: value = self[key] except KeyError: @@ -157,7 +154,7 @@ def pop(self, key, default=None): def popitem(self): """Delete an arbitrary (key, message) pair and return it.""" - for key in self.keys(): + for key in self.iterkeys(): return (key, self.pop(key)) # This is only run once. else: raise KeyError('No messages in mailbox') @@ -165,7 +162,7 @@ def popitem(self): def update(self, arg=None): """Change the messages that correspond to certain keys.""" if hasattr(arg, 'iteritems'): - source = arg.items() + source = arg.iteritems() elif hasattr(arg, 'items'): source = arg.items() else: @@ -562,7 +559,7 @@ def _lookup(self, key): def next(self): """Return the next message in a one-time iteration.""" if not hasattr(self, '_onetime_keys'): - self._onetime_keys = iter(self.keys()) + self._onetime_keys = self.iterkeys() while True: try: return self[next(self._onetime_keys)] @@ -1081,7 +1078,7 @@ def __contains__(self, key): def __len__(self): """Return a count of messages in the mailbox.""" - return len(list(self.keys())) + return len(list(self.iterkeys())) def lock(self): """Lock the mailbox.""" @@ -1195,7 +1192,7 @@ def pack(self): sequences = self.get_sequences() prev = 0 changes = [] - for key in self.keys(): + for key in self.iterkeys(): if key - 1 != prev: changes.append((key, prev + 1)) if hasattr(os, 'link'): @@ -1233,8 +1230,8 @@ def _dump_sequences(self, message, key): class Babyl(_singlefileMailbox): """An Rmail-style Babyl mailbox.""" - _special_labels = frozenset(('unseen', 'deleted', 'filed', 'answered', - 'forwarded', 'edited', 'resent')) + _special_labels = frozenset({'unseen', 'deleted', 'filed', 'answered', + 'forwarded', 'edited', 'resent'}) def __init__(self, path, factory=None, create=True): """Initialize a Babyl mailbox.""" @@ -1952,7 +1949,7 @@ def __iter__(self): while True: line = self.readline() if not line: - raise StopIteration + return yield line def tell(self): @@ -1983,7 +1980,7 @@ def _read(self, size, read_method): return result def __enter__(self): - """Context manager protocol support.""" + """Context management protocol support.""" return self def __exit__(self, *exc): diff --git a/Lib/mailcap.py b/Lib/mailcap.py index bd61b0b0ae94..97e303522cae 100644 --- a/Lib/mailcap.py +++ b/Lib/mailcap.py @@ -22,8 +22,8 @@ def getcaps(): fp = open(mailcap, 'r') except OSError: continue - morecaps = readmailcapfile(fp) - fp.close() + with fp: + morecaps = readmailcapfile(fp) for key, value in morecaps.items(): if not key in caps: caps[key] = value diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py index d7161f81343f..b98c8749f632 100644 --- a/Lib/mimetypes.py +++ b/Lib/mimetypes.py @@ -363,9 +363,10 @@ def read_mime_types(file): f = open(file) except OSError: return None - db = MimeTypes() - db.readfp(f, True) - return db.types_map[True] + with f: + db = MimeTypes() + db.readfp(f, True) + return db.types_map[True] def _default_mime_types(): diff --git a/Lib/modulefinder.py b/Lib/modulefinder.py index ebd068aaa240..b778e6094dd4 100644 --- a/Lib/modulefinder.py +++ b/Lib/modulefinder.py @@ -1,6 +1,7 @@ """Find modules used by a script, using introspection.""" import dis +import importlib._bootstrap import importlib.machinery import marshal import os @@ -287,11 +288,12 @@ def load_module(self, fqname, fp, pathname, file_info): if type == imp.PY_SOURCE: co = compile(fp.read()+'\n', pathname, 'exec') elif type == imp.PY_COMPILED: - if fp.read(4) != imp.get_magic(): - self.msgout(2, "raise ImportError: Bad magic number", pathname) - raise ImportError("Bad magic number in %s" % pathname) - fp.read(4) - co = marshal.load(fp) + try: + marshal_data = importlib._bootstrap._validate_bytecode_header(fp.read()) + except ImportError as exc: + self.msgout(2, "raise ImportError: " + str(exc), pathname) + raise + co = marshal.loads(marshal_data) else: co = None m = self.add_module(fqname) @@ -335,30 +337,6 @@ def _safe_import_hook(self, name, caller, fromlist, level=-1): fullname = name + "." + sub self._add_badmodule(fullname, caller) - def scan_opcodes(self, co, - unpack = struct.unpack): - # Scan the code, and yield 'interesting' opcode combinations - # Version for Python 2.4 and older - code = co.co_code - names = co.co_names - consts = co.co_consts - while code: - c = code[0] - if c in STORE_OPS: - oparg, = unpack('<H', code[1:3]) - yield "store", (names[oparg],) - code = code[3:] - continue - if c == LOAD_CONST and code[3] == IMPORT_NAME: - oparg_1, oparg_2 = unpack('<xHxH', code[:6]) - yield "import", (consts[oparg_1], names[oparg_2]) - code = code[6:] - continue - if c >= HAVE_ARGUMENT: - code = code[3:] - else: - code = code[1:] - def scan_opcodes_25(self, co, unpack = struct.unpack): # Scan the code, and yield 'interesting' opcode combinations @@ -390,10 +368,7 @@ def scan_opcodes_25(self, co, def scan_code(self, co, m): code = co.co_code - if sys.version_info >= (2, 5): - scanner = self.scan_opcodes_25 - else: - scanner = self.scan_opcodes + scanner = self.scan_opcodes_25 for what, args in scanner(co): if what == "store": name, = args @@ -593,11 +568,12 @@ def replace_paths_in_code(self, co): if isinstance(consts[i], type(co)): consts[i] = self.replace_paths_in_code(consts[i]) - return types.CodeType(co.co_argcount, co.co_nlocals, co.co_stacksize, - co.co_flags, co.co_code, tuple(consts), co.co_names, - co.co_varnames, new_filename, co.co_name, - co.co_firstlineno, co.co_lnotab, - co.co_freevars, co.co_cellvars) + return types.CodeType(co.co_argcount, co.co_kwonlyargcount, + co.co_nlocals, co.co_stacksize, co.co_flags, + co.co_code, tuple(consts), co.co_names, + co.co_varnames, new_filename, co.co_name, + co.co_firstlineno, co.co_lnotab, co.co_freevars, + co.co_cellvars) def test(): diff --git a/Lib/multiprocessing/connection.py b/Lib/multiprocessing/connection.py index 8ad6fd5f3e5c..9a8ae29a9ef8 100644 --- a/Lib/multiprocessing/connection.py +++ b/Lib/multiprocessing/connection.py @@ -14,7 +14,6 @@ import sys import socket import struct -import errno import time import tempfile import itertools @@ -29,7 +28,7 @@ try: import _winapi - from _winapi import WAIT_OBJECT_0, WAIT_TIMEOUT, INFINITE + from _winapi import WAIT_OBJECT_0, WAIT_ABANDONED_0, WAIT_TIMEOUT, INFINITE except ImportError: if sys.platform == 'win32': raise @@ -77,7 +76,7 @@ def arbitrary_address(family): return tempfile.mktemp(prefix='listener-', dir=util.get_temp_dir()) elif family == 'AF_PIPE': return tempfile.mktemp(prefix=r'\\.\pipe\pyc-%d-%d-' % - (os.getpid(), next(_mmap_counter))) + (os.getpid(), next(_mmap_counter)), dir="") else: raise ValueError('unrecognized family') @@ -221,7 +220,7 @@ def recv_bytes(self, maxlength=None): def recv_bytes_into(self, buf, offset=0): """ - Receive bytes data into a writeable buffer-like object. + Receive bytes data into a writeable bytes-like object. Return the number of bytes read. """ self._check_closed() @@ -366,10 +365,7 @@ def _close(self, _close=os.close): def _send(self, buf, write=_write): remaining = len(buf) while True: - try: - n = write(self._handle, buf) - except InterruptedError: - continue + n = write(self._handle, buf) remaining -= n if remaining == 0: break @@ -380,10 +376,7 @@ def _recv(self, size, read=_read): handle = self._handle remaining = size while remaining > 0: - try: - chunk = read(handle, remaining) - except InterruptedError: - continue + chunk = read(handle, remaining) n = len(chunk) if n == 0: if remaining == size: @@ -395,13 +388,20 @@ def _recv(self, size, read=_read): return buf def _send_bytes(self, buf): - # For wire compatibility with 3.2 and lower n = len(buf) - self._send(struct.pack("!i", n)) - # The condition is necessary to avoid "broken pipe" errors - # when sending a 0-length buffer if the other end closed the pipe. - if n > 0: + # For wire compatibility with 3.2 and lower + header = struct.pack("!i", n) + if n > 16384: + # The payload is large so Nagle's algorithm won't be triggered + # and we'd better avoid the cost of concatenation. + self._send(header) self._send(buf) + else: + # Issue # 20540: concatenate before sending, to avoid delays due + # to Nagle's algorithm on a TCP socket. + # Also note we want to avoid sending a 0-length buffer separately, + # to avoid "broken pipe" errors if the other end closed the pipe. + self._send(header + buf) def _recv_bytes(self, maxsize=None): buf = self._recv(4) @@ -589,13 +589,7 @@ def __init__(self, address, family, backlog=1): self._unlink = None def accept(self): - while True: - try: - s, self._last_accepted = self._socket.accept() - except InterruptedError: - pass - else: - break + s, self._last_accepted = self._socket.accept() s.setblocking(True) return Connection(s.detach()) diff --git a/Lib/multiprocessing/dummy/__init__.py b/Lib/multiprocessing/dummy/__init__.py index 97f7af737ea2..1abea64419b2 100644 --- a/Lib/multiprocessing/dummy/__init__.py +++ b/Lib/multiprocessing/dummy/__init__.py @@ -86,7 +86,7 @@ def __repr__(self): if not name.startswith('_'): temp.append('%s=%r' % (name, value)) temp.sort() - return 'Namespace(%s)' % str.join(', ', temp) + return '%s(%s)' % (self.__class__.__name__, ', '.join(temp)) dict = dict list = list @@ -104,7 +104,7 @@ def _set(self, value): self._value = value value = property(_get, _set) def __repr__(self): - return '<%r(%r, %r)>'%(type(self).__name__,self._typecode,self._value) + return '<%s(%r, %r)>'%(type(self).__name__,self._typecode,self._value) def Manager(): return sys.modules[__name__] diff --git a/Lib/multiprocessing/dummy/connection.py b/Lib/multiprocessing/dummy/connection.py index 694ef9621500..19843751c0c6 100644 --- a/Lib/multiprocessing/dummy/connection.py +++ b/Lib/multiprocessing/dummy/connection.py @@ -59,9 +59,8 @@ def poll(self, timeout=0.0): return True if timeout <= 0.0: return False - self._in.not_empty.acquire() - self._in.not_empty.wait(timeout) - self._in.not_empty.release() + with self._in.not_empty: + self._in.not_empty.wait(timeout) return self._in.qsize() > 0 def close(self): diff --git a/Lib/multiprocessing/forkserver.py b/Lib/multiprocessing/forkserver.py index 387517ebdca8..b27cba52e003 100644 --- a/Lib/multiprocessing/forkserver.py +++ b/Lib/multiprocessing/forkserver.py @@ -107,7 +107,7 @@ def ensure_running(self): address = connection.arbitrary_address('AF_UNIX') listener.bind(address) os.chmod(address, 0o600) - listener.listen(100) + listener.listen() # all client processes own the write end of the "alive" pipe; # when they all terminate the read end becomes ready. @@ -188,8 +188,6 @@ def main(listener_fd, alive_r, preload, main_path=None, sys_path=None): finally: os._exit(code) - except InterruptedError: - pass except OSError as e: if e.errno != errno.ECONNABORTED: raise @@ -230,13 +228,7 @@ def read_unsigned(fd): data = b'' length = UNSIGNED_STRUCT.size while len(data) < length: - while True: - try: - s = os.read(fd, length - len(data)) - except InterruptedError: - pass - else: - break + s = os.read(fd, length - len(data)) if not s: raise EOFError('unexpected EOF') data += s @@ -245,13 +237,7 @@ def read_unsigned(fd): def write_unsigned(fd, n): msg = UNSIGNED_STRUCT.pack(n) while msg: - while True: - try: - nbytes = os.write(fd, msg) - except InterruptedError: - pass - else: - break + nbytes = os.write(fd, msg) if nbytes == 0: raise RuntimeError('should not get here') msg = msg[nbytes:] diff --git a/Lib/multiprocessing/heap.py b/Lib/multiprocessing/heap.py index 98bfdc8ee195..333b3baf20f4 100644 --- a/Lib/multiprocessing/heap.py +++ b/Lib/multiprocessing/heap.py @@ -8,13 +8,11 @@ # import bisect -import itertools import mmap import os import sys import tempfile import threading -import _multiprocessing from . import context from . import reduction @@ -56,7 +54,9 @@ def __getstate__(self): def __setstate__(self, state): self.size, self.name = self._state = state self.buffer = mmap.mmap(-1, self.size, tagname=self.name) - assert _winapi.GetLastError() == _winapi.ERROR_ALREADY_EXISTS + # XXX Temporarily preventing buildbot failures while determining + # XXX the correct long-term fix. See issue 23060 + #assert _winapi.GetLastError() == _winapi.ERROR_ALREADY_EXISTS else: @@ -218,9 +218,8 @@ def malloc(self, size): assert 0 <= size < sys.maxsize if os.getpid() != self._lastpid: self.__init__() # reinitialize after fork - self._lock.acquire() - self._free_pending_blocks() - try: + with self._lock: + self._free_pending_blocks() size = self._roundup(max(size,1), self._alignment) (arena, start, stop) = self._malloc(size) new_stop = start + size @@ -229,8 +228,6 @@ def malloc(self, size): block = (arena, start, new_stop) self._allocated_blocks.add(block) return block - finally: - self._lock.release() # # Class representing a chunk of an mmap -- can be inherited by child process diff --git a/Lib/multiprocessing/managers.py b/Lib/multiprocessing/managers.py index cc87d36612d6..776656ea176a 100644 --- a/Lib/multiprocessing/managers.py +++ b/Lib/multiprocessing/managers.py @@ -65,8 +65,8 @@ def __setstate__(self, state): (self.typeid, self.address, self.id) = state def __repr__(self): - return 'Token(typeid=%r, address=%r, id=%r)' % \ - (self.typeid, self.address, self.id) + return '%s(typeid=%r, address=%r, id=%r)' % \ + (self.__class__.__name__, self.typeid, self.address, self.id) # # Function for communication with a manager's server process @@ -306,8 +306,7 @@ def debug_info(self, c): ''' Return some info --- useful to spot problems with refcounting ''' - self.mutex.acquire() - try: + with self.mutex: result = [] keys = list(self.id_to_obj.keys()) keys.sort() @@ -317,8 +316,6 @@ def debug_info(self, c): (ident, self.id_to_refcount[ident], str(self.id_to_obj[ident][0])[:75])) return '\n'.join(result) - finally: - self.mutex.release() def number_of_objects(self, c): ''' @@ -343,8 +340,7 @@ def create(self, c, typeid, *args, **kwds): ''' Create a new shared object and return its id ''' - self.mutex.acquire() - try: + with self.mutex: callable, exposed, method_to_typeid, proxytype = \ self.registry[typeid] @@ -374,8 +370,6 @@ def create(self, c, typeid, *args, **kwds): # has been created. self.incref(c, ident) return ident, tuple(exposed) - finally: - self.mutex.release() def get_methods(self, c, token): ''' @@ -392,22 +386,16 @@ def accept_connection(self, c, name): self.serve_client(c) def incref(self, c, ident): - self.mutex.acquire() - try: + with self.mutex: self.id_to_refcount[ident] += 1 - finally: - self.mutex.release() def decref(self, c, ident): - self.mutex.acquire() - try: + with self.mutex: assert self.id_to_refcount[ident] >= 1 self.id_to_refcount[ident] -= 1 if self.id_to_refcount[ident] == 0: del self.id_to_obj[ident], self.id_to_refcount[ident] util.debug('disposing of obj with id %r', ident) - finally: - self.mutex.release() # # Class to represent state of a manager @@ -671,14 +659,11 @@ class BaseProxy(object): def __init__(self, token, serializer, manager=None, authkey=None, exposed=None, incref=True): - BaseProxy._mutex.acquire() - try: + with BaseProxy._mutex: tls_idset = BaseProxy._address_to_local.get(token.address, None) if tls_idset is None: tls_idset = util.ForkAwareLocal(), ProcessLocalSet() BaseProxy._address_to_local[token.address] = tls_idset - finally: - BaseProxy._mutex.release() # self._tls is used to record the connection used by this # thread to communicate with the manager at token.address @@ -818,8 +803,8 @@ def __deepcopy__(self, memo): return self._getvalue() def __repr__(self): - return '<%s object, typeid %r at %s>' % \ - (type(self).__name__, self._token.typeid, '0x%x' % id(self)) + return '<%s object, typeid %r at %#x>' % \ + (type(self).__name__, self._token.typeid, id(self)) def __str__(self): ''' @@ -916,7 +901,7 @@ def __repr__(self): if not name.startswith('_'): temp.append('%s=%r' % (name, value)) temp.sort() - return 'Namespace(%s)' % str.join(', ', temp) + return '%s(%s)' % (self.__class__.__name__, ', '.join(temp)) class Value(object): def __init__(self, typecode, value, lock=True): @@ -1077,17 +1062,22 @@ def __imul__(self, value): )) -PoolProxy = MakeProxyType('PoolProxy', ( +BasePoolProxy = MakeProxyType('PoolProxy', ( 'apply', 'apply_async', 'close', 'imap', 'imap_unordered', 'join', - 'map', 'map_async', 'starmap', 'starmap_async', 'terminate' + 'map', 'map_async', 'starmap', 'starmap_async', 'terminate', )) -PoolProxy._method_to_typeid_ = { +BasePoolProxy._method_to_typeid_ = { 'apply_async': 'AsyncResult', 'map_async': 'AsyncResult', 'starmap_async': 'AsyncResult', 'imap': 'Iterator', 'imap_unordered': 'Iterator' } +class PoolProxy(BasePoolProxy): + def __enter__(self): + return self + def __exit__(self, exc_type, exc_val, exc_tb): + self.terminate() # # Definition of SyncManager diff --git a/Lib/multiprocessing/pool.py b/Lib/multiprocessing/pool.py index 1cb2d9567885..75a76a467907 100644 --- a/Lib/multiprocessing/pool.py +++ b/Lib/multiprocessing/pool.py @@ -24,7 +24,7 @@ # If threading is available then ThreadPool should be provided. Therefore # we avoid top-level imports which are liable to fail on some systems. from . import util -from . import get_context, cpu_count, TimeoutError +from . import get_context, TimeoutError # # Constants representing the state of a pool @@ -87,10 +87,11 @@ def __str__(self): self.exc) def __repr__(self): - return "<MaybeEncodingError: %s>" % str(self) + return "<%s: %s>" % (self.__class__.__name__, self) -def worker(inqueue, outqueue, initializer=None, initargs=(), maxtasks=None): +def worker(inqueue, outqueue, initializer=None, initargs=(), maxtasks=None, + wrap_exception=False): assert maxtasks is None or (type(maxtasks) == int and maxtasks > 0) put = outqueue.put get = inqueue.get @@ -117,7 +118,8 @@ def worker(inqueue, outqueue, initializer=None, initargs=(), maxtasks=None): try: result = (True, func(*args, **kwds)) except Exception as e: - e = ExceptionWithTraceback(e, e.__traceback__) + if wrap_exception: + e = ExceptionWithTraceback(e, e.__traceback__) result = (False, e) try: put((job, i, result)) @@ -137,6 +139,8 @@ class Pool(object): ''' Class which supports an async version of applying functions to arguments. ''' + _wrap_exception = True + def Process(self, *args, **kwds): return self._ctx.Process(*args, **kwds) @@ -220,7 +224,8 @@ def _repopulate_pool(self): w = self.Process(target=worker, args=(self._inqueue, self._outqueue, self._initializer, - self._initargs, self._maxtasksperchild) + self._initargs, self._maxtasksperchild, + self._wrap_exception) ) self._pool.append(w) w.name = w.name.replace('Process', 'PoolWorker') @@ -661,8 +666,7 @@ def __iter__(self): return self def next(self, timeout=None): - self._cond.acquire() - try: + with self._cond: try: item = self._items.popleft() except IndexError: @@ -675,8 +679,6 @@ def next(self, timeout=None): if self._index == self._length: raise StopIteration raise TimeoutError - finally: - self._cond.release() success, value = item if success: @@ -686,8 +688,7 @@ def next(self, timeout=None): __next__ = next # XXX def _set(self, i, obj): - self._cond.acquire() - try: + with self._cond: if self._index == i: self._items.append(obj) self._index += 1 @@ -701,18 +702,13 @@ def _set(self, i, obj): if self._index == self._length: del self._cache[self._job] - finally: - self._cond.release() def _set_length(self, length): - self._cond.acquire() - try: + with self._cond: self._length = length if self._index == self._length: self._cond.notify() del self._cache[self._job] - finally: - self._cond.release() # # Class whose instances are returned by `Pool.imap_unordered()` @@ -721,21 +717,19 @@ def _set_length(self, length): class IMapUnorderedIterator(IMapIterator): def _set(self, i, obj): - self._cond.acquire() - try: + with self._cond: self._items.append(obj) self._index += 1 self._cond.notify() if self._index == self._length: del self._cache[self._job] - finally: - self._cond.release() # # # class ThreadPool(Pool): + _wrap_exception = False @staticmethod def Process(*args, **kwds): @@ -754,10 +748,7 @@ def _setup_queues(self): @staticmethod def _help_stuff_finish(inqueue, task_handler, size): # put sentinels at head of inqueue to make workers finish - inqueue.not_empty.acquire() - try: + with inqueue.not_empty: inqueue.queue.clear() inqueue.queue.extend([None] * size) inqueue.not_empty.notify_all() - finally: - inqueue.not_empty.release() diff --git a/Lib/multiprocessing/popen_fork.py b/Lib/multiprocessing/popen_fork.py index 463cc18aa397..d2ebd7cfbe1e 100644 --- a/Lib/multiprocessing/popen_fork.py +++ b/Lib/multiprocessing/popen_fork.py @@ -1,7 +1,6 @@ import os import sys import signal -import errno from . import util @@ -29,8 +28,6 @@ def poll(self, flag=os.WNOHANG): try: pid, sts = os.waitpid(self.pid, flag) except OSError as e: - if e.errno == errno.EINTR: - continue # Child process not yet created. See #1731717 # e.errno == errno.ECHILD == 10 return None @@ -47,7 +44,7 @@ def poll(self, flag=os.WNOHANG): def wait(self, timeout=None): if self.returncode is None: if timeout is not None: - from .connection import wait + from multiprocessing.connection import wait if not wait([self.sentinel], timeout): return None # This shouldn't block if wait() returned successfully. diff --git a/Lib/multiprocessing/popen_forkserver.py b/Lib/multiprocessing/popen_forkserver.py index b115f8123cea..e792194f44ce 100644 --- a/Lib/multiprocessing/popen_forkserver.py +++ b/Lib/multiprocessing/popen_forkserver.py @@ -57,7 +57,7 @@ def _launch(self, process_obj): def poll(self, flag=os.WNOHANG): if self.returncode is None: - from .connection import wait + from multiprocessing.connection import wait timeout = 0 if flag == os.WNOHANG else None if not wait([self.sentinel], timeout): return None diff --git a/Lib/multiprocessing/popen_spawn_posix.py b/Lib/multiprocessing/popen_spawn_posix.py index 8b5dc42aa11a..6b0a8d635fea 100644 --- a/Lib/multiprocessing/popen_spawn_posix.py +++ b/Lib/multiprocessing/popen_spawn_posix.py @@ -1,4 +1,3 @@ -import fcntl import io import os @@ -8,8 +7,6 @@ from . import spawn from . import util -from . import current_process - __all__ = ['Popen'] diff --git a/Lib/multiprocessing/queues.py b/Lib/multiprocessing/queues.py index f6507710922b..c07ad40cbcd9 100644 --- a/Lib/multiprocessing/queues.py +++ b/Lib/multiprocessing/queues.py @@ -81,14 +81,11 @@ def put(self, obj, block=True, timeout=None): if not self._sem.acquire(block, timeout): raise Full - self._notempty.acquire() - try: + with self._notempty: if self._thread is None: self._start_thread() self._buffer.append(obj) self._notempty.notify() - finally: - self._notempty.release() def get(self, block=True, timeout=None): if block and timeout is None: @@ -201,12 +198,9 @@ def _finalize_join(twr): @staticmethod def _finalize_close(buffer, notempty): debug('telling queue thread to quit') - notempty.acquire() - try: + with notempty: buffer.append(_sentinel) notempty.notify() - finally: - notempty.release() @staticmethod def _feed(buffer, notempty, send_bytes, writelock, close, ignore_epipe): @@ -295,35 +289,24 @@ def put(self, obj, block=True, timeout=None): if not self._sem.acquire(block, timeout): raise Full - self._notempty.acquire() - self._cond.acquire() - try: + with self._notempty, self._cond: if self._thread is None: self._start_thread() self._buffer.append(obj) self._unfinished_tasks.release() self._notempty.notify() - finally: - self._cond.release() - self._notempty.release() def task_done(self): - self._cond.acquire() - try: + with self._cond: if not self._unfinished_tasks.acquire(False): raise ValueError('task_done() called too many times') if self._unfinished_tasks._semlock._is_zero(): self._cond.notify_all() - finally: - self._cond.release() def join(self): - self._cond.acquire() - try: + with self._cond: if not self._unfinished_tasks._semlock._is_zero(): self._cond.wait() - finally: - self._cond.release() # # Simplified Queue type -- really just a locked pipe diff --git a/Lib/multiprocessing/reduction.py b/Lib/multiprocessing/reduction.py index 01e6de2f96ba..8f209b47dab7 100644 --- a/Lib/multiprocessing/reduction.py +++ b/Lib/multiprocessing/reduction.py @@ -16,7 +16,6 @@ import sys from . import context -from . import util __all__ = ['send_handle', 'recv_handle', 'ForkingPickler', 'register', 'dump'] diff --git a/Lib/multiprocessing/semaphore_tracker.py b/Lib/multiprocessing/semaphore_tracker.py index ddb2b520f56f..de7738eeee8a 100644 --- a/Lib/multiprocessing/semaphore_tracker.py +++ b/Lib/multiprocessing/semaphore_tracker.py @@ -11,7 +11,6 @@ # python" would probably leave unlinked semaphores. # -import errno import os import signal import sys @@ -21,7 +20,6 @@ from . import spawn from . import util -from . import current_process __all__ = ['ensure_running', 'register', 'unregister'] diff --git a/Lib/multiprocessing/sharedctypes.py b/Lib/multiprocessing/sharedctypes.py index 0c178252d508..4258f591c4ca 100644 --- a/Lib/multiprocessing/sharedctypes.py +++ b/Lib/multiprocessing/sharedctypes.py @@ -188,6 +188,12 @@ def __init__(self, obj, lock=None, ctx=None): self.acquire = self._lock.acquire self.release = self._lock.release + def __enter__(self): + return self._lock.__enter__() + + def __exit__(self, *args): + return self._lock.__exit__(*args) + def __reduce__(self): assert_spawning(self) return synchronized, (self._obj, self._lock) @@ -212,32 +218,20 @@ def __len__(self): return len(self._obj) def __getitem__(self, i): - self.acquire() - try: + with self: return self._obj[i] - finally: - self.release() def __setitem__(self, i, value): - self.acquire() - try: + with self: self._obj[i] = value - finally: - self.release() def __getslice__(self, start, stop): - self.acquire() - try: + with self: return self._obj[start:stop] - finally: - self.release() def __setslice__(self, start, stop, values): - self.acquire() - try: + with self: self._obj[start:stop] = values - finally: - self.release() class SynchronizedString(SynchronizedArray): diff --git a/Lib/multiprocessing/spawn.py b/Lib/multiprocessing/spawn.py index 364b53f499c4..336e47990f83 100644 --- a/Lib/multiprocessing/spawn.py +++ b/Lib/multiprocessing/spawn.py @@ -11,6 +11,8 @@ import os import pickle import sys +import runpy +import types from . import get_start_method, set_start_method from . import process @@ -62,7 +64,14 @@ def freeze_support(): Run code for process object if this in not the main process ''' if is_forking(sys.argv): - main() + kwds = {} + for arg in sys.argv[2:]: + name, value = arg.split('=') + if value == 'None': + kwds[name] = None + else: + kwds[name] = int(value) + spawn_main(**kwds) sys.exit() @@ -71,7 +80,8 @@ def get_command_line(**kwds): Returns prefix of command line used for spawning a child process ''' if getattr(sys, 'frozen', False): - return [sys.executable, '--multiprocessing-fork'] + return ([sys.executable, '--multiprocessing-fork'] + + ['%s=%r' % item for item in kwds.items()]) else: prog = 'from multiprocessing.spawn import spawn_main; spawn_main(%s)' prog %= ', '.join('%s=%r' % item for item in kwds.items()) @@ -157,15 +167,19 @@ def get_preparation_data(name): start_method=get_start_method(), ) - if sys.platform != 'win32' or (not WINEXE and not WINSERVICE): - main_path = getattr(sys.modules['__main__'], '__file__', None) - if not main_path and sys.argv[0] not in ('', '-c'): - main_path = sys.argv[0] + # Figure out whether to initialise main in the subprocess as a module + # or through direct execution (or to leave it alone entirely) + main_module = sys.modules['__main__'] + main_mod_name = getattr(main_module.__spec__, "name", None) + if main_mod_name is not None: + d['init_main_from_name'] = main_mod_name + elif sys.platform != 'win32' or (not WINEXE and not WINSERVICE): + main_path = getattr(main_module, '__file__', None) if main_path is not None: if (not os.path.isabs(main_path) and process.ORIGINAL_DIR is not None): main_path = os.path.join(process.ORIGINAL_DIR, main_path) - d['main_path'] = os.path.normpath(main_path) + d['init_main_from_path'] = os.path.normpath(main_path) return d @@ -206,53 +220,68 @@ def prepare(data): if 'start_method' in data: set_start_method(data['start_method']) - if 'main_path' in data: - import_main_path(data['main_path']) + if 'init_main_from_name' in data: + _fixup_main_from_name(data['init_main_from_name']) + elif 'init_main_from_path' in data: + _fixup_main_from_path(data['init_main_from_path']) + +# Multiprocessing module helpers to fix up the main module in +# spawned subprocesses +def _fixup_main_from_name(mod_name): + # __main__.py files for packages, directories, zip archives, etc, run + # their "main only" code unconditionally, so we don't even try to + # populate anything in __main__, nor do we make any changes to + # __main__ attributes + current_main = sys.modules['__main__'] + if mod_name == "__main__" or mod_name.endswith(".__main__"): + return + + # If this process was forked, __main__ may already be populated + if getattr(current_main.__spec__, "name", None) == mod_name: + return + + # Otherwise, __main__ may contain some non-main code where we need to + # support unpickling it properly. We rerun it as __mp_main__ and make + # the normal __main__ an alias to that + old_main_modules.append(current_main) + main_module = types.ModuleType("__mp_main__") + main_content = runpy.run_module(mod_name, + run_name="__mp_main__", + alter_sys=True) + main_module.__dict__.update(main_content) + sys.modules['__main__'] = sys.modules['__mp_main__'] = main_module + + +def _fixup_main_from_path(main_path): + # If this process was forked, __main__ may already be populated + current_main = sys.modules['__main__'] + + # Unfortunately, the main ipython launch script historically had no + # "if __name__ == '__main__'" guard, so we work around that + # by treating it like a __main__.py file + # See https://github.com/ipython/ipython/issues/4698 + main_name = os.path.splitext(os.path.basename(main_path))[0] + if main_name == 'ipython': + return + + # Otherwise, if __file__ already has the setting we expect, + # there's nothing more to do + if getattr(current_main, '__file__', None) == main_path: + return + + # If the parent process has sent a path through rather than a module + # name we assume it is an executable script that may contain + # non-main code that needs to be executed + old_main_modules.append(current_main) + main_module = types.ModuleType("__mp_main__") + main_content = runpy.run_path(main_path, + run_name="__mp_main__") + main_module.__dict__.update(main_content) + sys.modules['__main__'] = sys.modules['__mp_main__'] = main_module def import_main_path(main_path): ''' Set sys.modules['__main__'] to module at main_path ''' - # XXX (ncoghlan): The following code makes several bogus - # assumptions regarding the relationship between __file__ - # and a module's real name. See PEP 302 and issue #10845 - if getattr(sys.modules['__main__'], '__file__', None) == main_path: - return - - main_name = os.path.splitext(os.path.basename(main_path))[0] - if main_name == '__init__': - main_name = os.path.basename(os.path.dirname(main_path)) - - if main_name == '__main__': - main_module = sys.modules['__main__'] - main_module.__file__ = main_path - elif main_name != 'ipython': - # Main modules not actually called __main__.py may - # contain additional code that should still be executed - import importlib - import types - - if main_path is None: - dirs = None - elif os.path.basename(main_path).startswith('__init__.py'): - dirs = [os.path.dirname(os.path.dirname(main_path))] - else: - dirs = [os.path.dirname(main_path)] - - assert main_name not in sys.modules, main_name - sys.modules.pop('__mp_main__', None) - # We should not try to load __main__ - # since that would execute 'if __name__ == "__main__"' - # clauses, potentially causing a psuedo fork bomb. - main_module = types.ModuleType(main_name) - # XXX Use a target of main_module? - spec = importlib.find_spec(main_name, path=dirs) - methods = importlib._bootstrap._SpecMethods(spec) - methods.init_module_attrs(main_module) - main_module.__name__ = '__mp_main__' - code = spec.loader.get_code(main_name) - exec(code, main_module.__dict__) - - old_main_modules.append(sys.modules['__main__']) - sys.modules['__main__'] = sys.modules['__mp_main__'] = main_module + _fixup_main_from_path(main_path) diff --git a/Lib/multiprocessing/synchronize.py b/Lib/multiprocessing/synchronize.py index 9d8e2824772e..d4bdf0e8b173 100644 --- a/Lib/multiprocessing/synchronize.py +++ b/Lib/multiprocessing/synchronize.py @@ -11,10 +11,8 @@ 'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Condition', 'Event' ] -import os import threading import sys -import itertools import tempfile import _multiprocessing @@ -51,9 +49,10 @@ class SemLock(object): _rand = tempfile._RandomNameSequence() def __init__(self, kind, value, maxvalue, *, ctx): - ctx = ctx or get_context() - ctx = ctx.get_context() - unlink_now = sys.platform == 'win32' or ctx._name == 'fork' + if ctx is None: + ctx = context._default_context.get_context() + name = ctx.get_start_method() + unlink_now = sys.platform == 'win32' or name == 'fork' for i in range(100): try: sl = self._semlock = _multiprocessing.SemLock( @@ -135,7 +134,7 @@ def __repr__(self): value = self._semlock._get_value() except Exception: value = 'unknown' - return '<Semaphore(value=%s)>' % value + return '<%s(value=%s)>' % (self.__class__.__name__, value) # # Bounded semaphore @@ -151,8 +150,8 @@ def __repr__(self): value = self._semlock._get_value() except Exception: value = 'unknown' - return '<BoundedSemaphore(value=%s, maxvalue=%s)>' % \ - (value, self._semlock.maxvalue) + return '<%s(value=%s, maxvalue=%s)>' % \ + (self.__class__.__name__, value, self._semlock.maxvalue) # # Non-recursive lock @@ -177,7 +176,7 @@ def __repr__(self): name = 'SomeOtherProcess' except Exception: name = 'unknown' - return '<Lock(owner=%s)>' % name + return '<%s(owner=%s)>' % (self.__class__.__name__, name) # # Recursive lock @@ -203,7 +202,7 @@ def __repr__(self): name, count = 'SomeOtherProcess', 'nonzero' except Exception: name, count = 'unknown', 'unknown' - return '<RLock(%s, %s)>' % (name, count) + return '<%s(%s, %s)>' % (self.__class__.__name__, name, count) # # Condition variable @@ -244,7 +243,7 @@ def __repr__(self): self._woken_count._semlock._get_value()) except Exception: num_waiters = 'unknown' - return '<Condition(%s, %s)>' % (self._lock, num_waiters) + return '<%s(%s, %s)>' % (self.__class__.__name__, self._lock, num_waiters) def wait(self, timeout=None): assert self._lock._semlock._is_mine(), \ @@ -338,34 +337,24 @@ def __init__(self, *, ctx): self._flag = ctx.Semaphore(0) def is_set(self): - self._cond.acquire() - try: + with self._cond: if self._flag.acquire(False): self._flag.release() return True return False - finally: - self._cond.release() def set(self): - self._cond.acquire() - try: + with self._cond: self._flag.acquire(False) self._flag.release() self._cond.notify_all() - finally: - self._cond.release() def clear(self): - self._cond.acquire() - try: + with self._cond: self._flag.acquire(False) - finally: - self._cond.release() def wait(self, timeout=None): - self._cond.acquire() - try: + with self._cond: if self._flag.acquire(False): self._flag.release() else: @@ -375,8 +364,6 @@ def wait(self, timeout=None): self._flag.release() return True return False - finally: - self._cond.release() # # Barrier diff --git a/Lib/multiprocessing/util.py b/Lib/multiprocessing/util.py index e476e853823e..ea5443d63220 100644 --- a/Lib/multiprocessing/util.py +++ b/Lib/multiprocessing/util.py @@ -7,8 +7,6 @@ # Licensed to PSF under a Contributor Agreement. # -import sys -import functools import os import itertools import weakref @@ -214,10 +212,11 @@ def __repr__(self): obj = None if obj is None: - return '<Finalize object, dead>' + return '<%s object, dead>' % self.__class__.__name__ - x = '<Finalize object, callback=%s' % \ - getattr(self._callback, '__name__', self._callback) + x = '<%s object, callback=%s' % ( + self.__class__.__name__, + getattr(self._callback, '__name__', self._callback)) if self._args: x += ', args=' + str(self._args) if self._kwargs: @@ -329,6 +328,13 @@ def _reset(self): self.acquire = self._lock.acquire self.release = self._lock.release + def __enter__(self): + return self._lock.__enter__() + + def __exit__(self, *args): + return self._lock.__exit__(*args) + + class ForkAwareLocal(threading.local): def __init__(self): register_after_fork(self, lambda obj : obj.__dict__.clear()) diff --git a/Lib/nntplib.py b/Lib/nntplib.py index 046f48343d64..bcf7d1bd3363 100644 --- a/Lib/nntplib.py +++ b/Lib/nntplib.py @@ -80,13 +80,13 @@ from socket import _GLOBAL_DEFAULT_TIMEOUT __all__ = ["NNTP", - "NNTPReplyError", "NNTPTemporaryError", "NNTPPermanentError", - "NNTPProtocolError", "NNTPDataError", + "NNTPError", "NNTPReplyError", "NNTPTemporaryError", + "NNTPPermanentError", "NNTPProtocolError", "NNTPDataError", "decode_header", ] # maximal line length when calling readline(). This is to prevent -# reading arbitrary lenght lines. RFC 3977 limits NNTP line length to +# reading arbitrary length lines. RFC 3977 limits NNTP line length to # 512 characters, including CRLF. We have selected 2048 just to be on # the safe side. _MAXLINE = 2048 @@ -279,7 +279,7 @@ def _unparse_datetime(dt, legacy=False): if _have_ssl: - def _encrypt_on(sock, context): + def _encrypt_on(sock, context, hostname): """Wrap a socket in SSL/TLS. Arguments: - sock: Socket to wrap - context: SSL context to use for the encrypted connection @@ -289,7 +289,7 @@ def _encrypt_on(sock, context): # Generate a default SSL context if none was passed. if context is None: context = ssl._create_stdlib_context() - return context.wrap_socket(sock) + return context.wrap_socket(sock, server_hostname=hostname) # The classes themselves @@ -1005,7 +1005,7 @@ def starttls(self, context=None): resp = self._shortcmd('STARTTLS') if resp.startswith('382'): self.file.close() - self.sock = _encrypt_on(self.sock, context) + self.sock = _encrypt_on(self.sock, context, self.host) self.file = self.sock.makefile("rwb") self.tls_on = True # Capabilities may change after TLS starts up, so ask for them @@ -1065,7 +1065,7 @@ def __init__(self, host, port=NNTP_SSL_PORT, in default port and the `ssl_context` argument for SSL connections. """ self.sock = socket.create_connection((host, port), timeout) - self.sock = _encrypt_on(self.sock, ssl_context) + self.sock = _encrypt_on(self.sock, ssl_context, host) file = self.sock.makefile("rwb") _NNTPBase.__init__(self, file, host, readermode=readermode, timeout=timeout) @@ -1084,7 +1084,6 @@ def _close(self): # Test retrieval when run as a script. if __name__ == '__main__': import argparse - from email.utils import parsedate parser = argparse.ArgumentParser(description="""\ nntplib built-in demo - display the latest articles in a newsgroup""") diff --git a/Lib/ntpath.py b/Lib/ntpath.py index 6b656976a485..ee1a2157a142 100644 --- a/Lib/ntpath.py +++ b/Lib/ntpath.py @@ -32,48 +32,12 @@ defpath = '\\Windows' devnull = 'nul' -def _get_empty(path): - if isinstance(path, bytes): - return b'' - else: - return '' - -def _get_sep(path): - if isinstance(path, bytes): - return b'\\' - else: - return '\\' - -def _get_altsep(path): - if isinstance(path, bytes): - return b'/' - else: - return '/' - def _get_bothseps(path): if isinstance(path, bytes): return b'\\/' else: return '\\/' -def _get_dot(path): - if isinstance(path, bytes): - return b'.' - else: - return '.' - -def _get_colon(path): - if isinstance(path, bytes): - return b':' - else: - return ':' - -def _get_special(path): - if isinstance(path, bytes): - return (b'\\\\.\\', b'\\\\?\\') - else: - return ('\\\\.\\', '\\\\?\\') - # Normalize the case of a pathname and map slashes to backslashes. # Other normalizations (such as optimizing '../' away) are not done # (this is done by normpath). @@ -82,10 +46,16 @@ def normcase(s): """Normalize case of pathname. Makes all characters lowercase and all slashes into backslashes.""" - if not isinstance(s, (bytes, str)): - raise TypeError("normcase() argument must be str or bytes, " - "not '{}'".format(s.__class__.__name__)) - return s.replace(_get_altsep(s), _get_sep(s)).lower() + try: + if isinstance(s, bytes): + return s.replace(b'/', b'\\').lower() + else: + return s.replace('/', '\\').lower() + except (TypeError, AttributeError): + if not isinstance(s, (bytes, str)): + raise TypeError("normcase() argument must be str or bytes, " + "not %r" % s.__class__.__name__) from None + raise # Return whether a path is absolute. @@ -97,86 +67,49 @@ def normcase(s): def isabs(s): """Test whether a path is absolute""" s = splitdrive(s)[1] - return len(s) > 0 and s[:1] in _get_bothseps(s) + return len(s) > 0 and s[0] in _get_bothseps(s) # Join two (or more) paths. - -def join(a, *p): - """Join two or more pathname components, inserting "\\" as needed. - If any component is an absolute path, all previous path components - will be discarded.""" - sep = _get_sep(a) - seps = _get_bothseps(a) - colon = _get_colon(a) - path = a - for b in p: - b_wins = 0 # set to 1 iff b makes path irrelevant - if not path: - b_wins = 1 - - elif isabs(b): - # This probably wipes out path so far. However, it's more - # complicated if path begins with a drive letter. You get a+b - # (minus redundant slashes) in these four cases: - # 1. join('c:', '/a') == 'c:/a' - # 2. join('//computer/share', '/a') == '//computer/share/a' - # 3. join('c:/', '/a') == 'c:/a' - # 4. join('//computer/share/', '/a') == '//computer/share/a' - # But b wins in all of these cases: - # 5. join('c:/a', '/b') == '/b' - # 6. join('//computer/share/a', '/b') == '/b' - # 7. join('c:', 'd:/') == 'd:/' - # 8. join('c:', '//computer/share/') == '//computer/share/' - # 9. join('//computer/share', 'd:/') == 'd:/' - # 10. join('//computer/share', '//computer/share/') == '//computer/share/' - # 11. join('c:/', 'd:/') == 'd:/' - # 12. join('c:/', '//computer/share/') == '//computer/share/' - # 13. join('//computer/share/', 'd:/') == 'd:/' - # 14. join('//computer/share/', '//computer/share/') == '//computer/share/' - b_prefix, b_rest = splitdrive(b) - - # if b has a prefix, it always wins. - if b_prefix: - b_wins = 1 - else: - # b doesn't have a prefix. - # but isabs(b) returned true. - # and therefore b_rest[0] must be a slash. - # (but let's check that.) - assert(b_rest and b_rest[0] in seps) - - # so, b still wins if path has a rest that's more than a sep. - # you get a+b if path_rest is empty or only has a sep. - # (see cases 1-4 for times when b loses.) - path_rest = splitdrive(path)[1] - b_wins = path_rest and path_rest not in seps - - if b_wins: - path = b - else: - # Join, and ensure there's a separator. - assert len(path) > 0 - if path[-1:] in seps: - if b and b[:1] in seps: - path += b[1:] - else: - path += b - elif path[-1:] == colon: - path += b - elif b: - if b[:1] in seps: - path += b - else: - path += sep + b - else: - # path is not empty and does not end with a backslash, - # but b is empty; since, e.g., split('a/') produces - # ('a', ''), it's best if join() adds a backslash in - # this case. - path += sep - - return path +def join(path, *paths): + if isinstance(path, bytes): + sep = b'\\' + seps = b'\\/' + colon = b':' + else: + sep = '\\' + seps = '\\/' + colon = ':' + try: + result_drive, result_path = splitdrive(path) + for p in paths: + p_drive, p_path = splitdrive(p) + if p_path and p_path[0] in seps: + # Second path is absolute + if p_drive or not result_drive: + result_drive = p_drive + result_path = p_path + continue + elif p_drive and p_drive != result_drive: + if p_drive.lower() != result_drive.lower(): + # Different drives => ignore the first path entirely + result_drive = p_drive + result_path = p_path + continue + # Same drive in different case + result_drive = p_drive + # Second path is relative to the first + if result_path and result_path[-1] not in seps: + result_path = result_path + sep + result_path = result_path + p_path + ## add separator between UNC and non-absolute path + if (result_path and result_path[0] not in seps and + result_drive and result_drive[-1:] != colon): + return result_drive + sep + result_path + return result_drive + result_path + except (TypeError, AttributeError, BytesWarning): + genericpath._check_arg_types('join', path, *paths) + raise # Split a path in a drive specification (a drive letter followed by a @@ -201,10 +134,16 @@ def splitdrive(p): Paths cannot contain both a drive letter and a UNC path. """ - empty = _get_empty(p) - if len(p) > 1: - sep = _get_sep(p) - normp = normcase(p) + if len(p) >= 2: + if isinstance(p, bytes): + sep = b'\\' + altsep = b'/' + colon = b':' + else: + sep = '\\' + altsep = '/' + colon = ':' + normp = p.replace(altsep, sep) if (normp[0:2] == sep*2) and (normp[2:3] != sep): # is a UNC path: # vvvvvvvvvvvvvvvvvvvv drive letter or UNC path @@ -212,18 +151,18 @@ def splitdrive(p): # directory ^^^^^^^^^^^^^^^ index = normp.find(sep, 2) if index == -1: - return empty, p + return p[:0], p index2 = normp.find(sep, index + 1) # a UNC path can't have two slashes in a row # (after the initial two) if index2 == index + 1: - return empty, p + return p[:0], p if index2 == -1: index2 = len(p) return p[:index2], p[index2:] - if normp[1:2] == _get_colon(p): + if normp[1:2] == colon: return p[:2], p[2:] - return empty, p + return p[:0], p # Parse UNC paths @@ -240,26 +179,12 @@ def splitunc(p): """ import warnings warnings.warn("ntpath.splitunc is deprecated, use ntpath.splitdrive instead", - DeprecationWarning) - sep = _get_sep(p) - if not p[1:2]: - return p[:0], p # Drive letter present - firstTwo = p[0:2] - if normcase(firstTwo) == sep + sep: - # is a UNC path: - # vvvvvvvvvvvvvvvvvvvv equivalent to drive letter - # \\machine\mountpoint\directories... - # directory ^^^^^^^^^^^^^^^ - normp = normcase(p) - index = normp.find(sep, 2) - if index == -1: - ##raise RuntimeError, 'illegal UNC path: "' + p + '"' - return (p[:0], p) - index = normp.find(sep, index + 1) - if index == -1: - index = len(p) - return p[:index], p[index:] - return p[:0], p + DeprecationWarning, 2) + drive, path = splitdrive(p) + if len(drive) == 2: + # Drive letter present + return p[:0], p + return drive, path # Split a path in head (everything up to the last '/') and tail (the @@ -281,10 +206,7 @@ def split(p): i -= 1 head, tail = p[:i], p[i:] # now tail has no slashes # remove trailing slashes from head, unless it's all slashes - head2 = head - while head2 and head2[-1:] in seps: - head2 = head2[:-1] - head = head2 or head + head = head.rstrip(seps) or head return d + head, tail @@ -294,8 +216,10 @@ def split(p): # It is always true that root + ext == p. def splitext(p): - return genericpath._splitext(p, _get_sep(p), _get_altsep(p), - _get_dot(p)) + if isinstance(p, bytes): + return genericpath._splitext(p, b'\\', b'/', b'.') + else: + return genericpath._splitext(p, '\\', '/', '.') splitext.__doc__ = genericpath._splitext.__doc__ @@ -403,7 +327,7 @@ def expanduser(path): userhome = join(drive, os.environ['HOMEPATH']) if isinstance(path, bytes): - userhome = userhome.encode(sys.getfilesystemencoding()) + userhome = os.fsencode(userhome) if i != 1: #~user userhome = join(dirname(userhome), path[1:i]) @@ -429,14 +353,16 @@ def expandvars(path): Unknown variables are left unchanged.""" if isinstance(path, bytes): - if ord('$') not in path and ord('%') not in path: + if b'$' not in path and b'%' not in path: return path import string varchars = bytes(string.ascii_letters + string.digits + '_-', 'ascii') quote = b'\'' percent = b'%' brace = b'{' + rbrace = b'}' dollar = b'$' + environ = getattr(os, 'environb', None) else: if '$' not in path and '%' not in path: return path @@ -445,7 +371,9 @@ def expandvars(path): quote = '\'' percent = '%' brace = '{' + rbrace = '}' dollar = '$' + environ = os.environ res = path[:0] index = 0 pathlen = len(path) @@ -474,14 +402,13 @@ def expandvars(path): index = pathlen - 1 else: var = path[:index] - if isinstance(path, bytes): - var = var.decode('ascii') - if var in os.environ: - value = os.environ[var] - else: - value = '%' + var + '%' - if isinstance(path, bytes): - value = value.encode('ascii') + try: + if environ is None: + value = os.fsencode(os.environ[os.fsdecode(var)]) + else: + value = environ[var] + except KeyError: + value = percent + var + percent res += value elif c == dollar: # variable or '$$' if path[index + 1:index + 2] == dollar: @@ -491,43 +418,35 @@ def expandvars(path): path = path[index+2:] pathlen = len(path) try: - if isinstance(path, bytes): - index = path.index(b'}') - else: - index = path.index('}') - var = path[:index] - if isinstance(path, bytes): - var = var.decode('ascii') - if var in os.environ: - value = os.environ[var] - else: - value = '${' + var + '}' - if isinstance(path, bytes): - value = value.encode('ascii') - res += value + index = path.index(rbrace) except ValueError: - if isinstance(path, bytes): - res += b'${' + path - else: - res += '${' + path + res += dollar + brace + path index = pathlen - 1 + else: + var = path[:index] + try: + if environ is None: + value = os.fsencode(os.environ[os.fsdecode(var)]) + else: + value = environ[var] + except KeyError: + value = dollar + brace + var + rbrace + res += value else: - var = '' + var = path[:0] index += 1 c = path[index:index + 1] while c and c in varchars: - if isinstance(path, bytes): - var += c.decode('ascii') - else: - var += c + var += c index += 1 c = path[index:index + 1] - if var in os.environ: - value = os.environ[var] - else: - value = '$' + var - if isinstance(path, bytes): - value = value.encode('ascii') + try: + if environ is None: + value = os.fsencode(os.environ[os.fsdecode(var)]) + else: + value = environ[var] + except KeyError: + value = dollar + var res += value if c: index -= 1 @@ -543,16 +462,25 @@ def expandvars(path): def normpath(path): """Normalize path, eliminating double slashes, etc.""" - sep = _get_sep(path) - dotdot = _get_dot(path) * 2 - special_prefixes = _get_special(path) + if isinstance(path, bytes): + sep = b'\\' + altsep = b'/' + curdir = b'.' + pardir = b'..' + special_prefixes = (b'\\\\.\\', b'\\\\?\\') + else: + sep = '\\' + altsep = '/' + curdir = '.' + pardir = '..' + special_prefixes = ('\\\\.\\', '\\\\?\\') if path.startswith(special_prefixes): # in the case of paths with these prefixes: # \\.\ -> device names # \\?\ -> literal paths # do not do any normalization, but return the path unchanged return path - path = path.replace(_get_altsep(path), sep) + path = path.replace(altsep, sep) prefix, path = splitdrive(path) # collapse initial backslashes @@ -563,13 +491,13 @@ def normpath(path): comps = path.split(sep) i = 0 while i < len(comps): - if not comps[i] or comps[i] == _get_dot(path): + if not comps[i] or comps[i] == curdir: del comps[i] - elif comps[i] == dotdot: - if i > 0 and comps[i-1] != dotdot: + elif comps[i] == pardir: + if i > 0 and comps[i-1] != pardir: del comps[i-1:i+1] i -= 1 - elif i == 0 and prefix.endswith(_get_sep(path)): + elif i == 0 and prefix.endswith(sep): del comps[i] else: i += 1 @@ -577,7 +505,7 @@ def normpath(path): i += 1 # If the path is now empty, substitute '.' if not prefix and not comps: - comps.append(_get_dot(path)) + comps.append(curdir) return prefix + sep.join(comps) @@ -617,42 +545,48 @@ def abspath(path): supports_unicode_filenames = (hasattr(sys, "getwindowsversion") and sys.getwindowsversion()[3] >= 2) -def relpath(path, start=curdir): +def relpath(path, start=None): """Return a relative version of a path""" - sep = _get_sep(path) + if isinstance(path, bytes): + sep = b'\\' + curdir = b'.' + pardir = b'..' + else: + sep = '\\' + curdir = '.' + pardir = '..' - if start is curdir: - start = _get_dot(path) + if start is None: + start = curdir if not path: raise ValueError("no path specified") - start_abs = abspath(normpath(start)) - path_abs = abspath(normpath(path)) - start_drive, start_rest = splitdrive(start_abs) - path_drive, path_rest = splitdrive(path_abs) - if normcase(start_drive) != normcase(path_drive): - error = "path is on mount '{0}', start on mount '{1}'".format( - path_drive, start_drive) - raise ValueError(error) - - start_list = [x for x in start_rest.split(sep) if x] - path_list = [x for x in path_rest.split(sep) if x] - # Work out how much of the filepath is shared by start and path. - i = 0 - for e1, e2 in zip(start_list, path_list): - if normcase(e1) != normcase(e2): - break - i += 1 + try: + start_abs = abspath(normpath(start)) + path_abs = abspath(normpath(path)) + start_drive, start_rest = splitdrive(start_abs) + path_drive, path_rest = splitdrive(path_abs) + if normcase(start_drive) != normcase(path_drive): + raise ValueError("path is on mount %r, start on mount %r" % ( + path_drive, start_drive)) + + start_list = [x for x in start_rest.split(sep) if x] + path_list = [x for x in path_rest.split(sep) if x] + # Work out how much of the filepath is shared by start and path. + i = 0 + for e1, e2 in zip(start_list, path_list): + if normcase(e1) != normcase(e2): + break + i += 1 - if isinstance(path, bytes): - pardir = b'..' - else: - pardir = '..' - rel_list = [pardir] * (len(start_list)-i) + path_list[i:] - if not rel_list: - return _get_dot(path) - return join(*rel_list) + rel_list = [pardir] * (len(start_list)-i) + path_list[i:] + if not rel_list: + return curdir + return join(*rel_list) + except (TypeError, ValueError, AttributeError, BytesWarning, DeprecationWarning): + genericpath._check_arg_types('relpath', path, start) + raise # determine if two files are in fact the same file diff --git a/Lib/numbers.py b/Lib/numbers.py index b206457dfc04..7eedc63ec05d 100644 --- a/Lib/numbers.py +++ b/Lib/numbers.py @@ -141,11 +141,6 @@ def __eq__(self, other): """self == other""" raise NotImplementedError - def __ne__(self, other): - """self != other""" - # The default __ne__ doesn't negate __eq__ until 3.0. - return not (self == other) - Complex.register(complex) diff --git a/Lib/opcode.py b/Lib/opcode.py index 0bd1ee679cfd..bfd3c4d8dd4b 100644 --- a/Lib/opcode.py +++ b/Lib/opcode.py @@ -70,6 +70,9 @@ def jabs_op(name, op): def_op('UNARY_INVERT', 15) +def_op('BINARY_MATRIX_MULTIPLY', 16) +def_op('INPLACE_MATRIX_MULTIPLY', 17) + def_op('BINARY_POWER', 19) def_op('BINARY_MULTIPLY', 20) diff --git a/Lib/operator.py b/Lib/operator.py index d31a9a453797..856036ddf12c 100644 --- a/Lib/operator.py +++ b/Lib/operator.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 """ Operator Interface @@ -106,6 +105,10 @@ def mul(a, b): "Same as a * b." return a * b +def matmul(a, b): + "Same as a @ b." + return a @ b + def neg(a): "Same as -a." return -a @@ -327,6 +330,11 @@ def imul(a, b): a *= b return a +def imatmul(a, b): + "Same as a @= b." + a @= b + return a + def ior(a, b): "Same as a |= b." a |= b @@ -384,6 +392,7 @@ def ixor(a, b): __lshift__ = lshift __mod__ = mod __mul__ = mul +__matmul__ = matmul __neg__ = neg __or__ = or_ __pos__ = pos @@ -404,6 +413,7 @@ def ixor(a, b): __ilshift__ = ilshift __imod__ = imod __imul__ = imul +__imatmul__ = imatmul __ior__ = ior __ipow__ = ipow __irshift__ = irshift diff --git a/Lib/optparse.py b/Lib/optparse.py index 22405d5eb8be..432a2eb9b66b 100644 --- a/Lib/optparse.py +++ b/Lib/optparse.py @@ -209,7 +209,6 @@ def __init__(self, short_first): self.parser = None self.indent_increment = indent_increment - self.help_position = self.max_help_position = max_help_position if width is None: try: width = int(os.environ['COLUMNS']) @@ -217,6 +216,8 @@ def __init__(self, width = 80 width -= 2 self.width = width + self.help_position = self.max_help_position = \ + min(max_help_position, max(width - 20, indent_increment * 2)) self.current_indent = 0 self.level = 0 self.help_width = None # computed later @@ -261,7 +262,7 @@ def _format_text(self, text): Format a paragraph of free-form text for inclusion in the help output at the current indentation level. """ - text_width = self.width - self.current_indent + text_width = max(self.width - self.current_indent, 11) indent = " "*self.current_indent return textwrap.fill(text, text_width, @@ -342,7 +343,7 @@ def store_option_strings(self, parser): self.dedent() self.dedent() self.help_position = min(max_len + 2, self.max_help_position) - self.help_width = self.width - self.help_position + self.help_width = max(self.width - self.help_position, 11) def format_option_strings(self, option): """Return a comma-separated list of option strings & metavariables.""" @@ -644,14 +645,8 @@ def _check_type(self): self.type = "string" else: # Allow type objects or builtin type conversion functions - # (int, str, etc.) as an alternative to their names. (The - # complicated check of builtins is only necessary for - # Python 2.1 and earlier, and is short-circuited by the - # first check on modern Pythons.) - import builtins - if ( isinstance(self.type, type) or - (hasattr(self.type, "__name__") and - getattr(builtins, self.type.__name__, None) is self.type) ): + # (int, str, etc.) as an alternative to their names. + if isinstance(self.type, type): self.type = self.type.__name__ if self.type == "str": diff --git a/Lib/os.py b/Lib/os.py index e9880a1e4c7a..3bb0f4e25031 100644 --- a/Lib/os.py +++ b/Lib/os.py @@ -1,4 +1,4 @@ -r"""OS routines for Mac, NT, or Posix depending on what system we're on. +r"""OS routines for NT or Posix depending on what system we're on. This exports: - all functions from posix, nt or ce, e.g. unlink, stat, etc. @@ -61,6 +61,10 @@ def _get_exports_list(module): except ImportError: pass + import posix + __all__.extend(_get_exports_list(posix)) + del posix + elif 'nt' in _names: name = 'nt' linesep = '\r\n' @@ -206,23 +210,16 @@ def _add(str, fn): SEEK_CUR = 1 SEEK_END = 2 - -def _get_masked_mode(mode): - mask = umask(0) - umask(mask) - return mode & ~mask - # Super directory utilities. # (Inspired by Eric Raymond; the doc strings are mostly his) def makedirs(name, mode=0o777, exist_ok=False): - """makedirs(path [, mode=0o777][, exist_ok=False]) + """makedirs(name [, mode=0o777][, exist_ok=False]) - Super-mkdir; create a leaf directory and all intermediate ones. - Works like mkdir, except that any intermediate path segment (not - just the rightmost) will be created if it does not exist. If the - target directory with the same mode as we specified already exists, - raises an OSError if exist_ok is False, otherwise no exception is + Super-mkdir; create a leaf directory and all intermediate ones. Works like + mkdir, except that any intermediate path segment (not just the rightmost) + will be created if it does not exist. If the target directory already + exists, raise an OSError if exist_ok is False. Otherwise no exception is raised. This is recursive. """ @@ -243,24 +240,11 @@ def makedirs(name, mode=0o777, exist_ok=False): try: mkdir(name, mode) except OSError as e: - dir_exists = path.isdir(name) - expected_mode = _get_masked_mode(mode) - if dir_exists: - # S_ISGID is automatically copied by the OS from parent to child - # directories on mkdir. Don't consider it being set to be a mode - # mismatch as mkdir does not unset it when not specified in mode. - actual_mode = st.S_IMODE(lstat(name).st_mode) & ~st.S_ISGID - else: - actual_mode = -1 - if not (e.errno == errno.EEXIST and exist_ok and dir_exists and - actual_mode == expected_mode): - if dir_exists and actual_mode != expected_mode: - e.strerror += ' (mode %o != expected mode %o)' % ( - actual_mode, expected_mode) + if not exist_ok or e.errno != errno.EEXIST or not path.isdir(name): raise def removedirs(name): - """removedirs(path) + """removedirs(name) Super-rmdir; remove a leaf directory and all empty intermediate ones. Works like rmdir except that, if the leaf directory is @@ -332,11 +316,12 @@ def walk(top, topdown=True, onerror=None, followlinks=False): When topdown is true, the caller can modify the dirnames list in-place (e.g., via del or slice assignment), and walk will only recurse into the - subdirectories whose names remain in dirnames; this can be used to prune - the search, or to impose a specific order of visiting. Modifying - dirnames when topdown is false is ineffective, since the directories in - dirnames have already been generated by the time dirnames itself is - generated. + subdirectories whose names remain in dirnames; this can be used to prune the + search, or to impose a specific order of visiting. Modifying dirnames when + topdown is false is ineffective, since the directories in dirnames have + already been generated by the time dirnames itself is generated. No matter + the value of topdown, the list of subdirectories is retrieved before the + tuples for the directory and its subdirectories are generated. By default errors from the os.listdir() call are ignored. If optional arg 'onerror' is specified, it should be a function; it @@ -364,6 +349,7 @@ def walk(top, topdown=True, onerror=None, followlinks=False): print("bytes in", len(files), "non-directory files") if 'CVS' in dirs: dirs.remove('CVS') # don't visit CVS directories + """ islink, join, isdir = path.islink, path.join, path.isdir diff --git a/Lib/pathlib.py b/Lib/pathlib.py index e73eca7ec9f0..01e66a0970b0 100644 --- a/Lib/pathlib.py +++ b/Lib/pathlib.py @@ -6,32 +6,24 @@ import posixpath import re import sys -import weakref -try: - import threading -except ImportError: - import dummy_threading as threading - -from collections import Sequence, defaultdict +from collections import Sequence from contextlib import contextmanager -from errno import EINVAL, ENOENT -from itertools import chain, count +from errno import EINVAL, ENOENT, ENOTDIR from operator import attrgetter from stat import S_ISDIR, S_ISLNK, S_ISREG, S_ISSOCK, S_ISBLK, S_ISCHR, S_ISFIFO -from urllib.parse import quote as urlquote, quote_from_bytes as urlquote_from_bytes +from urllib.parse import quote_from_bytes as urlquote_from_bytes supports_symlinks = True -try: +if os.name == 'nt': import nt -except ImportError: - nt = None -else: if sys.getwindowsversion()[:2] >= (6, 0): from nt import _getfinalpathname else: supports_symlinks = False _getfinalpathname = None +else: + nt = None __all__ = [ @@ -81,6 +73,10 @@ def parse_parts(self, parts): # parts. This makes the result of parsing e.g. # ("C:", "/", "a") reasonably intuitive. for part in it: + if not part: + continue + if altsep: + part = part.replace(altsep, sep) drv = self.splitroot(part)[0] if drv: break @@ -96,12 +92,16 @@ def join_parsed_parts(self, drv, root, parts, drv2, root2, parts2): (drive, root, parts) tuples. Return a new (drive, root, parts) tuple. """ if root2: - parts = parts2 - root = root2 + if not drv2 and drv: + return drv, root2, [drv + root2] + parts2[1:] + elif drv2: + if drv2 == drv or self.casefold(drv2) == self.casefold(drv): + # Same drive => second path is relative to the first + return drv, root, parts + parts2[1:] else: - parts = parts + parts2 - # XXX raise error if drv and drv2 are different? - return drv2 or drv, root, parts + # Second path is non-anchored (common case) + return drv, root, parts + parts2 + return drv2, root2, parts2 class _WindowsFlavour(_Flavour): @@ -113,7 +113,7 @@ class _WindowsFlavour(_Flavour): has_drv = True pathmod = ntpath - is_supported = (nt is not None) + is_supported = (os.name == 'nt') drive_letters = ( set(chr(x) for x in range(ord('a'), ord('z') + 1)) | @@ -225,6 +225,36 @@ def make_uri(self, path): # It's a path on a network drive => 'file://host/share/a/b' return 'file:' + urlquote_from_bytes(path.as_posix().encode('utf-8')) + def gethomedir(self, username): + if 'HOME' in os.environ: + userhome = os.environ['HOME'] + elif 'USERPROFILE' in os.environ: + userhome = os.environ['USERPROFILE'] + elif 'HOMEPATH' in os.environ: + try: + drv = os.environ['HOMEDRIVE'] + except KeyError: + drv = '' + userhome = drv + os.environ['HOMEPATH'] + else: + raise RuntimeError("Can't determine home directory") + + if username: + # Try to guess user home directory. By default all users + # directories are located in the same place and are named by + # corresponding usernames. If current user home directory points + # to nonstandard place, this guess is likely wrong. + if os.environ['USERNAME'] != username: + drv, root, parts = self.parse_parts((userhome,)) + if parts[-1] != os.environ['USERNAME']: + raise RuntimeError("Can't determine home directory " + "for %r" % username) + parts[-1] = username + if drv or root: + userhome = drv + root + self.join(parts[1:]) + else: + userhome = self.join(parts) + return userhome class _PosixFlavour(_Flavour): sep = '/' @@ -257,42 +287,47 @@ def casefold_parts(self, parts): def resolve(self, path): sep = self.sep - def split(p): - return [x for x in p.split(sep) if x] - def absparts(p): - # Our own abspath(), since the posixpath one makes - # the mistake of "normalizing" the path without resolving the - # symlinks first. - if not p.startswith(sep): - return split(os.getcwd()) + split(p) - else: - return split(p) - parts = absparts(str(path))[::-1] accessor = path._accessor - resolved = cur = "" - symlinks = {} - while parts: - part = parts.pop() - cur = resolved + sep + part - if cur in symlinks and symlinks[cur] <= len(parts): - # We've already seen the symlink and there's not less - # work to do than the last time. - raise RuntimeError("Symlink loop from %r" % cur) - try: - target = accessor.readlink(cur) - except OSError as e: - if e.errno != EINVAL: - raise - # Not a symlink - resolved = cur - else: - # Take note of remaining work from this symlink - symlinks[cur] = len(parts) - if target.startswith(sep): - # Symlink points to absolute path - resolved = "" - parts.extend(split(target)[::-1]) - return resolved or sep + seen = {} + def _resolve(path, rest): + if rest.startswith(sep): + path = '' + + for name in rest.split(sep): + if not name or name == '.': + # current dir + continue + if name == '..': + # parent dir + path, _, _ = path.rpartition(sep) + continue + newpath = path + sep + name + if newpath in seen: + # Already seen this path + path = seen[newpath] + if path is not None: + # use cached value + continue + # The symlink is not resolved, so we must have a symlink loop. + raise RuntimeError("Symlink loop from %r" % newpath) + # Resolve the symbolic link + try: + target = accessor.readlink(newpath) + except OSError as e: + if e.errno != EINVAL: + raise + # Not a symlink + path = newpath + else: + seen[newpath] = None # not resolved symlink + path = _resolve(path, target) + seen[newpath] = path # resolved symlink + + return path + # NOTE: according to POSIX, getcwd() cannot contain path components + # which are symlinks. + base = '' if path.is_absolute() else os.getcwd() + return _resolve(base, str(path)) or sep def is_reserved(self, parts): return False @@ -303,6 +338,21 @@ def make_uri(self, path): bpath = bytes(path) return 'file://' + urlquote_from_bytes(bpath) + def gethomedir(self, username): + if not username: + try: + return os.environ['HOME'] + except KeyError: + import pwd + return pwd.getpwuid(os.getuid()).pw_dir + else: + import pwd + try: + return pwd.getpwnam(username).pw_dir + except KeyError: + raise RuntimeError("Can't determine home directory " + "for %r" % username) + _windows_flavour = _WindowsFlavour() _posix_flavour = _PosixFlavour() @@ -572,8 +622,8 @@ def _parse_args(cls, args): if isinstance(a, PurePath): parts += a._parts elif isinstance(a, str): - # Assuming a str - parts.append(a) + # Force-cast str subclasses to str (issue #21127) + parts.append(str(a)) else: raise TypeError( "argument should be a path or str object, not %r" @@ -664,9 +714,6 @@ def __eq__(self, other): return NotImplemented return self._cparts == other._cparts and self._flavour is other._flavour - def __ne__(self, other): - return not self == other - def __hash__(self): try: return self._hash @@ -747,12 +794,21 @@ def with_name(self, name): """Return a new path with the file name changed.""" if not self.name: raise ValueError("%r has an empty name" % (self,)) + drv, root, parts = self._flavour.parse_parts((name,)) + if (not name or name[-1] in [self._flavour.sep, self._flavour.altsep] + or drv or root or len(parts) != 1): + raise ValueError("Invalid name %r" % (name)) return self._from_parsed_parts(self._drv, self._root, self._parts[:-1] + [name]) def with_suffix(self, suffix): """Return a new path with the file suffix changed (or added, if none).""" # XXX if suffix is None, should the current suffix be removed? + f = self._flavour + if f.sep in suffix or f.altsep and f.altsep in suffix: + raise ValueError("Invalid suffix %r" % (suffix)) + if suffix and not suffix.startswith('.') or suffix == '.': + raise ValueError("Invalid suffix %r" % (suffix)) name = self.name if not name: raise ValueError("%r has an empty name" % (self,)) @@ -778,27 +834,23 @@ def relative_to(self, *other): parts = self._parts drv = self._drv root = self._root - if drv or root: - if root: - abs_parts = [drv, root] + parts[1:] - else: - abs_parts = [drv] + parts[1:] + if root: + abs_parts = [drv, root] + parts[1:] else: abs_parts = parts to_drv, to_root, to_parts = self._parse_args(other) - if to_drv or to_root: - if to_root: - to_abs_parts = [to_drv, to_root] + to_parts[1:] - else: - to_abs_parts = [to_drv] + to_parts[1:] + if to_root: + to_abs_parts = [to_drv, to_root] + to_parts[1:] else: to_abs_parts = to_parts n = len(to_abs_parts) - if n == 0 and (drv or root) or abs_parts[:n] != to_abs_parts: + cf = self._flavour.casefold_parts + if (root or drv) if n == 0 else cf(abs_parts[:n]) != cf(to_abs_parts): formatted = self._format_parsed_parts(to_drv, to_root, to_parts) raise ValueError("{!r} does not start with {!r}" .format(str(self), str(formatted))) - return self._from_parsed_parts('', '', abs_parts[n:]) + return self._from_parsed_parts('', root if n == 1 else '', + abs_parts[n:]) @property def parts(self): @@ -939,6 +991,15 @@ def _opener(self, name, flags, mode=0o666): # A stub for the opener argument to built-in open() return self._accessor.open(self, flags, mode) + def _raw_open(self, flags, mode=0o777): + """ + Open the file pointed by this path and return a file descriptor, + as os.open() does. + """ + if self._closed: + self._raise_closed() + return self._accessor.open(self, flags, mode) + # Public API @classmethod @@ -948,6 +1009,24 @@ def cwd(cls): """ return cls(os.getcwd()) + @classmethod + def home(cls): + """Return a new path pointing to the user's home directory (as + returned by os.path.expanduser('~')). + """ + return cls(cls()._flavour.gethomedir(None)) + + def samefile(self, other_path): + """Return whether `other_file` is the same or not as this file. + (as returned by os.path.samefile(file, other_file)). + """ + st = self.stat() + try: + other_st = other_path.stat() + except AttributeError: + other_st = os.stat(other_path) + return os.path.samestat(st, other_st) + def iterdir(self): """Iterate over the files in this directory. Does not yield any result for the special paths '.' and '..'. @@ -1045,15 +1124,6 @@ def group(self): import grp return grp.getgrgid(self.stat().st_gid).gr_name - def _raw_open(self, flags, mode=0o777): - """ - Open the file pointed by this path and return a file descriptor, - as os.open() does. - """ - if self._closed: - self._raise_closed() - return self._accessor.open(self, flags, mode) - def open(self, mode='r', buffering=-1, encoding=None, errors=None, newline=None): """ @@ -1065,6 +1135,39 @@ def open(self, mode='r', buffering=-1, encoding=None, return io.open(str(self), mode, buffering, encoding, errors, newline, opener=self._opener) + def read_bytes(self): + """ + Open the file in bytes mode, read it, and close the file. + """ + with self.open(mode='rb') as f: + return f.read() + + def read_text(self, encoding=None, errors=None): + """ + Open the file in text mode, read it, and close the file. + """ + with self.open(mode='r', encoding=encoding, errors=errors) as f: + return f.read() + + def write_bytes(self, data): + """ + Open the file in bytes mode, write to it, and close the file. + """ + # type-check for the buffer interface before truncating the file + view = memoryview(data) + with self.open(mode='wb') as f: + return f.write(view) + + def write_text(self, data, encoding=None, errors=None): + """ + Open the file in text mode, write to it, and close the file. + """ + if not isinstance(data, str): + raise TypeError('data must be str, not %s' % + data.__class__.__name__) + with self.open(mode='w', encoding=encoding, errors=errors) as f: + return f.write(data) + def touch(self, mode=0o666, exist_ok=True): """ Create this file with the given access mode, if it doesn't exist. @@ -1088,18 +1191,25 @@ def touch(self, mode=0o666, exist_ok=True): fd = self._raw_open(flags, mode) os.close(fd) - def mkdir(self, mode=0o777, parents=False): + def mkdir(self, mode=0o777, parents=False, exist_ok=False): if self._closed: self._raise_closed() if not parents: - self._accessor.mkdir(self, mode) + try: + self._accessor.mkdir(self, mode) + except FileExistsError: + if not exist_ok or not self.is_dir(): + raise else: try: self._accessor.mkdir(self, mode) + except FileExistsError: + if not exist_ok or not self.is_dir(): + raise except OSError as e: if e.errno != ENOENT: raise - self.parent.mkdir(mode, True) + self.parent.mkdir(parents=True) self._accessor.mkdir(self, mode) def chmod(self, mode): @@ -1180,7 +1290,7 @@ def exists(self): try: self.stat() except OSError as e: - if e.errno != ENOENT: + if e.errno not in (ENOENT, ENOTDIR): raise return False return True @@ -1192,7 +1302,7 @@ def is_dir(self): try: return S_ISDIR(self.stat().st_mode) except OSError as e: - if e.errno != ENOENT: + if e.errno not in (ENOENT, ENOTDIR): raise # Path doesn't exist or is a broken symlink # (see https://bitbucket.org/pitrou/pathlib/issue/12/) @@ -1206,7 +1316,7 @@ def is_file(self): try: return S_ISREG(self.stat().st_mode) except OSError as e: - if e.errno != ENOENT: + if e.errno not in (ENOENT, ENOTDIR): raise # Path doesn't exist or is a broken symlink # (see https://bitbucket.org/pitrou/pathlib/issue/12/) @@ -1219,7 +1329,7 @@ def is_symlink(self): try: return S_ISLNK(self.lstat().st_mode) except OSError as e: - if e.errno != ENOENT: + if e.errno not in (ENOENT, ENOTDIR): raise # Path doesn't exist return False @@ -1231,7 +1341,7 @@ def is_block_device(self): try: return S_ISBLK(self.stat().st_mode) except OSError as e: - if e.errno != ENOENT: + if e.errno not in (ENOENT, ENOTDIR): raise # Path doesn't exist or is a broken symlink # (see https://bitbucket.org/pitrou/pathlib/issue/12/) @@ -1244,7 +1354,7 @@ def is_char_device(self): try: return S_ISCHR(self.stat().st_mode) except OSError as e: - if e.errno != ENOENT: + if e.errno not in (ENOENT, ENOTDIR): raise # Path doesn't exist or is a broken symlink # (see https://bitbucket.org/pitrou/pathlib/issue/12/) @@ -1257,7 +1367,7 @@ def is_fifo(self): try: return S_ISFIFO(self.stat().st_mode) except OSError as e: - if e.errno != ENOENT: + if e.errno not in (ENOENT, ENOTDIR): raise # Path doesn't exist or is a broken symlink # (see https://bitbucket.org/pitrou/pathlib/issue/12/) @@ -1270,12 +1380,23 @@ def is_socket(self): try: return S_ISSOCK(self.stat().st_mode) except OSError as e: - if e.errno != ENOENT: + if e.errno not in (ENOENT, ENOTDIR): raise # Path doesn't exist or is a broken symlink # (see https://bitbucket.org/pitrou/pathlib/issue/12/) return False + def expanduser(self): + """ Return a new path with expanded ~ and ~user constructs + (as returned by os.path.expanduser) + """ + if (not (self._drv or self._root) and + self._parts and self._parts[0][:1] == '~'): + homedir = self._flavour.gethomedir(self._parts[0][1:]) + return self._from_parts([homedir] + self._parts[1:]) + + return self + class PosixPath(Path, PurePosixPath): __slots__ = () diff --git a/Lib/pdb.py b/Lib/pdb.py index dd7ceb8927dc..cf2edbf89858 100755 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -301,7 +301,7 @@ def user_exception(self, frame, exc_info): # An 'Internal StopIteration' exception is an exception debug event # issued by the interpreter when handling a subgenerator run with # 'yield from' or a generator controled by a for loop. No exception has - # actually occured in this case. The debugger uses this debug event to + # actually occurred in this case. The debugger uses this debug event to # stop when the debuggee is returning from such generators. prefix = 'Internal ' if (not exc_traceback and exc_type is StopIteration) else '' @@ -673,7 +673,7 @@ def do_break(self, arg, temporary = 0): # now set the break point err = self.set_break(filename, line, temporary, cond, funcname) if err: - self.error(err, file=self.stdout) + self.error(err) else: bp = self.get_breaks(filename, line)[-1] self.message("Breakpoint %d at %s:%d" % @@ -1316,7 +1316,7 @@ def do_whatis(self, arg): return # Is it a class? if value.__class__ is type: - self.message('Class %s.%s' % (value.__module__, value.__name__)) + self.message('Class %s.%s' % (value.__module__, value.__qualname__)) return # None of the above... self.message(type(value)) diff --git a/Lib/pickle.py b/Lib/pickle.py index c57149a39356..e38ecac8249e 100644 --- a/Lib/pickle.py +++ b/Lib/pickle.py @@ -23,7 +23,7 @@ """ -from types import FunctionType, ModuleType +from types import FunctionType from copyreg import dispatch_table from copyreg import _extension_registry, _inverted_registry, _extension_cache from itertools import islice @@ -242,7 +242,7 @@ def readline(self): if not data: self.current_frame = None return self.file_readline() - if data[-1] != b'\n': + if data[-1] != b'\n'[0]: raise UnpicklingError( "pickle exhausted before end of frame") return data @@ -280,7 +280,9 @@ def whichmodule(obj, name, allow_qualname=False): module_name = getattr(obj, '__module__', None) if module_name is not None: return module_name - for module_name, module in sys.modules.items(): + # Protect the iteration by using a list copy of sys.modules against dynamic + # modules that trigger imports of other modules upon calls to getattr. + for module_name, module in list(sys.modules.items()): if module_name == '__main__' or module is None: continue try: @@ -348,24 +350,25 @@ class _Pickler: def __init__(self, file, protocol=None, *, fix_imports=True): """This takes a binary file for writing a pickle data stream. - The optional protocol argument tells the pickler to use the + The optional *protocol* argument tells the pickler to use the given protocol; supported protocols are 0, 1, 2, 3 and 4. The - default protocol is 3; a backward-incompatible protocol designed for - Python 3. + default protocol is 3; a backward-incompatible protocol designed + for Python 3. Specifying a negative protocol version selects the highest protocol version supported. The higher the protocol used, the more recent the version of Python needed to read the pickle produced. - The file argument must have a write() method that accepts a single - bytes argument. It can thus be a file object opened for binary - writing, a io.BytesIO instance, or any other custom object that - meets this interface. + The *file* argument must have a write() method that accepts a + single bytes argument. It can thus be a file object opened for + binary writing, a io.BytesIO instance, or any other custom + object that meets this interface. - If fix_imports is True and protocol is less than 3, pickle will try to - map the new Python 3 names to the old module names used in Python 2, - so that the pickle data stream is readable with Python 2. + If *fix_imports* is True and *protocol* is less than 3, pickle + will try to map the new Python 3 names to the old module names + used in Python 2, so that the pickle data stream is readable + with Python 2. """ if protocol is None: protocol = DEFAULT_PROTOCOL @@ -389,10 +392,9 @@ def clear_memo(self): """Clears the pickler's "memo". The memo is the data structure that remembers which objects the - pickler has already seen, so that shared or recursive objects are - pickled by reference and not by value. This method is useful when - re-using picklers. - + pickler has already seen, so that shared or recursive objects + are pickled by reference and not by value. This method is + useful when re-using picklers. """ self.memo.clear() @@ -975,8 +977,14 @@ def __init__(self, file, *, fix_imports=True, encoding="ASCII", errors="strict"): """This takes a binary file for reading a pickle data stream. - The protocol version of the pickle is detected automatically, so no - proto argument is needed. + The protocol version of the pickle is detected automatically, so + no proto argument is needed. + + The argument *file* must have two methods, a read() method that + takes an integer argument, and a readline() method that requires + no arguments. Both methods should return bytes. Thus *file* + can be a binary file object opened for reading, a io.BytesIO + object, or any other custom object that meets this interface. The file-like object must have two methods, a read() method that takes an integer argument, and a readline() method that @@ -985,13 +993,14 @@ def __init__(self, file, *, fix_imports=True, reading, a BytesIO object, or any other custom object that meets this interface. - Optional keyword arguments are *fix_imports*, *encoding* and *errors*, - which are used to control compatiblity support for pickle stream - generated by Python 2.x. If *fix_imports* is True, pickle will try to - map the old Python 2.x names to the new names used in Python 3.x. The - *encoding* and *errors* tell pickle how to decode 8-bit string - instances pickled by Python 2.x; these default to 'ASCII' and - 'strict', respectively. + Optional keyword arguments are *fix_imports*, *encoding* and + *errors*, which are used to control compatiblity support for + pickle stream generated by Python 2. If *fix_imports* is True, + pickle will try to map the old Python 2 names to the new names + used in Python 3. The *encoding* and *errors* tell pickle how + to decode 8-bit string instances pickled by Python 2; these + default to 'ASCII' and 'strict', respectively. *encoding* can be + 'bytes' to read theses 8-bit string instances as bytes objects. """ self._file_readline = file.readline self._file_read = file.read @@ -1139,6 +1148,15 @@ def load_binfloat(self): self.append(unpack('>d', self.read(8))[0]) dispatch[BINFLOAT[0]] = load_binfloat + def _decode_string(self, value): + # Used to allow strings from Python 2 to be decoded either as + # bytes or Unicode strings. This should be used only with the + # STRING, BINSTRING and SHORT_BINSTRING opcodes. + if self.encoding == "bytes": + return value + else: + return value.decode(self.encoding, self.errors) + def load_string(self): data = self.readline()[:-1] # Strip outermost quotes @@ -1146,8 +1164,7 @@ def load_string(self): data = data[1:-1] else: raise UnpicklingError("the STRING opcode argument must be quoted") - self.append(codecs.escape_decode(data)[0] - .decode(self.encoding, self.errors)) + self.append(self._decode_string(codecs.escape_decode(data)[0])) dispatch[STRING[0]] = load_string def load_binstring(self): @@ -1156,8 +1173,7 @@ def load_binstring(self): if len < 0: raise UnpicklingError("BINSTRING pickle has negative byte count") data = self.read(len) - value = str(data, self.encoding, self.errors) - self.append(value) + self.append(self._decode_string(data)) dispatch[BINSTRING[0]] = load_binstring def load_binbytes(self): @@ -1191,8 +1207,7 @@ def load_binunicode8(self): def load_short_binstring(self): len = self.read(1)[0] data = self.read(len) - value = str(data, self.encoding, self.errors) - self.append(value) + self.append(self._decode_string(data)) dispatch[SHORT_BINSTRING[0]] = load_short_binstring def load_short_binbytes(self): diff --git a/Lib/pickletools.py b/Lib/pickletools.py index a2480f6510ab..6b86723a4c0d 100644 --- a/Lib/pickletools.py +++ b/Lib/pickletools.py @@ -969,113 +969,107 @@ def __repr__(self): return self.name -pyint = StackObject( - name='int', - obtype=int, - doc="A short (as opposed to long) Python integer object.") - -pylong = StackObject( - name='long', - obtype=int, - doc="A long (as opposed to short) Python integer object.") +pyint = pylong = StackObject( + name='int', + obtype=int, + doc="A Python integer object.") pyinteger_or_bool = StackObject( - name='int_or_bool', - obtype=(int, bool), - doc="A Python integer object (short or long), or " - "a Python bool.") + name='int_or_bool', + obtype=(int, bool), + doc="A Python integer or boolean object.") pybool = StackObject( - name='bool', - obtype=(bool,), - doc="A Python bool object.") + name='bool', + obtype=bool, + doc="A Python boolean object.") pyfloat = StackObject( - name='float', - obtype=float, - doc="A Python float object.") + name='float', + obtype=float, + doc="A Python float object.") -pystring = StackObject( - name='string', - obtype=bytes, - doc="A Python (8-bit) string object.") +pybytes_or_str = pystring = StackObject( + name='bytes_or_str', + obtype=(bytes, str), + doc="A Python bytes or (Unicode) string object.") pybytes = StackObject( - name='bytes', - obtype=bytes, - doc="A Python bytes object.") + name='bytes', + obtype=bytes, + doc="A Python bytes object.") pyunicode = StackObject( - name='str', - obtype=str, - doc="A Python (Unicode) string object.") + name='str', + obtype=str, + doc="A Python (Unicode) string object.") pynone = StackObject( - name="None", - obtype=type(None), - doc="The Python None object.") + name="None", + obtype=type(None), + doc="The Python None object.") pytuple = StackObject( - name="tuple", - obtype=tuple, - doc="A Python tuple object.") + name="tuple", + obtype=tuple, + doc="A Python tuple object.") pylist = StackObject( - name="list", - obtype=list, - doc="A Python list object.") + name="list", + obtype=list, + doc="A Python list object.") pydict = StackObject( - name="dict", - obtype=dict, - doc="A Python dict object.") + name="dict", + obtype=dict, + doc="A Python dict object.") pyset = StackObject( - name="set", - obtype=set, - doc="A Python set object.") + name="set", + obtype=set, + doc="A Python set object.") pyfrozenset = StackObject( - name="frozenset", - obtype=set, - doc="A Python frozenset object.") + name="frozenset", + obtype=set, + doc="A Python frozenset object.") anyobject = StackObject( - name='any', - obtype=object, - doc="Any kind of object whatsoever.") + name='any', + obtype=object, + doc="Any kind of object whatsoever.") markobject = StackObject( - name="mark", - obtype=StackObject, - doc="""'The mark' is a unique object. - - Opcodes that operate on a variable number of objects - generally don't embed the count of objects in the opcode, - or pull it off the stack. Instead the MARK opcode is used - to push a special marker object on the stack, and then - some other opcodes grab all the objects from the top of - the stack down to (but not including) the topmost marker - object. - """) + name="mark", + obtype=StackObject, + doc="""'The mark' is a unique object. + +Opcodes that operate on a variable number of objects +generally don't embed the count of objects in the opcode, +or pull it off the stack. Instead the MARK opcode is used +to push a special marker object on the stack, and then +some other opcodes grab all the objects from the top of +the stack down to (but not including) the topmost marker +object. +""") stackslice = StackObject( - name="stackslice", - obtype=StackObject, - doc="""An object representing a contiguous slice of the stack. + name="stackslice", + obtype=StackObject, + doc="""An object representing a contiguous slice of the stack. - This is used in conjunction with markobject, to represent all - of the stack following the topmost markobject. For example, - the POP_MARK opcode changes the stack from +This is used in conjunction with markobject, to represent all +of the stack following the topmost markobject. For example, +the POP_MARK opcode changes the stack from - [..., markobject, stackslice] - to - [...] + [..., markobject, stackslice] +to + [...] - No matter how many object are on the stack after the topmost - markobject, POP_MARK gets rid of all of them (including the - topmost markobject too). - """) +No matter how many object are on the stack after the topmost +markobject, POP_MARK gets rid of all of them (including the +topmost markobject too). +""") ############################################################################## # Descriptors for pickle opcodes. @@ -1212,7 +1206,7 @@ def __init__(self, name, code, arg, code='L', arg=decimalnl_long, stack_before=[], - stack_after=[pylong], + stack_after=[pyint], proto=0, doc="""Push a long integer. @@ -1230,7 +1224,7 @@ def __init__(self, name, code, arg, code='\x8a', arg=long1, stack_before=[], - stack_after=[pylong], + stack_after=[pyint], proto=2, doc="""Long integer using one-byte length. @@ -1241,7 +1235,7 @@ def __init__(self, name, code, arg, code='\x8b', arg=long4, stack_before=[], - stack_after=[pylong], + stack_after=[pyint], proto=2, doc="""Long integer using found-byte length. @@ -1254,45 +1248,50 @@ def __init__(self, name, code, arg, code='S', arg=stringnl, stack_before=[], - stack_after=[pystring], + stack_after=[pybytes_or_str], proto=0, doc="""Push a Python string object. The argument is a repr-style string, with bracketing quote characters, and perhaps embedded escapes. The argument extends until the next - newline character. (Actually, they are decoded into a str instance + newline character. These are usually decoded into a str instance using the encoding given to the Unpickler constructor. or the default, - 'ASCII'.) + 'ASCII'. If the encoding given was 'bytes' however, they will be + decoded as bytes object instead. """), I(name='BINSTRING', code='T', arg=string4, stack_before=[], - stack_after=[pystring], + stack_after=[pybytes_or_str], proto=1, doc="""Push a Python string object. - There are two arguments: the first is a 4-byte little-endian signed int - giving the number of bytes in the string, and the second is that many - bytes, which are taken literally as the string content. (Actually, - they are decoded into a str instance using the encoding given to the - Unpickler constructor. or the default, 'ASCII'.) + There are two arguments: the first is a 4-byte little-endian + signed int giving the number of bytes in the string, and the + second is that many bytes, which are taken literally as the string + content. These are usually decoded into a str instance using the + encoding given to the Unpickler constructor. or the default, + 'ASCII'. If the encoding given was 'bytes' however, they will be + decoded as bytes object instead. """), I(name='SHORT_BINSTRING', code='U', arg=string1, stack_before=[], - stack_after=[pystring], + stack_after=[pybytes_or_str], proto=1, doc="""Push a Python string object. - There are two arguments: the first is a 1-byte unsigned int giving - the number of bytes in the string, and the second is that many bytes, - which are taken literally as the string content. (Actually, they - are decoded into a str instance using the encoding given to the - Unpickler constructor. or the default, 'ASCII'.) + There are two arguments: the first is a 1-byte unsigned int giving + the number of bytes in the string, and the second is that many + bytes, which are taken literally as the string content. These are + usually decoded into a str instance using the encoding given to + the Unpickler constructor. or the default, 'ASCII'. If the + encoding given was 'bytes' however, they will be decoded as bytes + object instead. """), # Bytes (protocol 3 only; older protocols don't support bytes at all) @@ -2283,40 +2282,61 @@ def genops(pickle): def optimize(p): 'Optimize a pickle string by removing unused PUT opcodes' - not_a_put = object() - gets = { not_a_put } # set of args used by a GET opcode - opcodes = [] # (startpos, stoppos, putid) + put = 'PUT' + get = 'GET' + oldids = set() # set of all PUT ids + newids = {} # set of ids used by a GET opcode + opcodes = [] # (op, idx) or (pos, end_pos) proto = 0 + protoheader = b'' for opcode, arg, pos, end_pos in _genops(p, yield_end_pos=True): if 'PUT' in opcode.name: - opcodes.append((pos, end_pos, arg)) + oldids.add(arg) + opcodes.append((put, arg)) + elif opcode.name == 'MEMOIZE': + idx = len(oldids) + oldids.add(idx) + opcodes.append((put, idx)) elif 'FRAME' in opcode.name: pass - else: - if 'GET' in opcode.name: - gets.add(arg) - elif opcode.name == 'PROTO': - assert pos == 0, pos + elif 'GET' in opcode.name: + if opcode.proto > proto: + proto = opcode.proto + newids[arg] = None + opcodes.append((get, arg)) + elif opcode.name == 'PROTO': + if arg > proto: proto = arg - opcodes.append((pos, end_pos, not_a_put)) - prevpos, prevarg = pos, None + if pos == 0: + protoheader = p[pos: end_pos] + else: + opcodes.append((pos, end_pos)) + else: + opcodes.append((pos, end_pos)) + del oldids # Copy the opcodes except for PUTS without a corresponding GET out = io.BytesIO() - opcodes = iter(opcodes) - if proto >= 2: - # Write the PROTO header before any framing - start, stop, _ = next(opcodes) - out.write(p[start:stop]) - buf = pickle._Framer(out.write) + # Write the PROTO header before any framing + out.write(protoheader) + pickler = pickle._Pickler(out, proto) if proto >= 4: - buf.start_framing() - for start, stop, putid in opcodes: - if putid in gets: - buf.commit_frame() - buf.write(p[start:stop]) - if proto >= 4: - buf.end_framing() + pickler.framer.start_framing() + idx = 0 + for op, arg in opcodes: + if op is put: + if arg not in newids: + continue + data = pickler.put(idx) + newids[arg] = idx + idx += 1 + elif op is get: + data = pickler.get(newids[arg]) + else: + data = p[op:arg] + pickler.framer.commit_frame() + pickler.write(data) + pickler.framer.end_framing() return out.getvalue() ############################################################################## diff --git a/Lib/pkgutil.py b/Lib/pkgutil.py index 4682d22366c4..fc4a074f5b87 100644 --- a/Lib/pkgutil.py +++ b/Lib/pkgutil.py @@ -16,6 +16,21 @@ 'ImpImporter', 'ImpLoader', 'read_code', 'extend_path', ] + +def _get_spec(finder, name): + """Return the finder-specific module spec.""" + # Works with legacy finders. + try: + find_spec = finder.find_spec + except AttributeError: + loader = finder.find_module(name) + if loader is None: + return None + return importlib.util.spec_from_loader(name, loader) + else: + return find_spec(name) + + def read_code(stream): # This helper is needed in order for the PEP 302 emulation to # correctly handle compiled files @@ -326,9 +341,10 @@ def get_source(self, fullname=None): self.source = self._get_delegate().get_source() return self.source - def _get_delegate(self): - return ImpImporter(self.filename).find_module('__init__') + finder = ImpImporter(self.filename) + spec = _get_spec(finder, '__init__') + return spec.loader def get_filename(self, fullname=None): fullname = self._fix_name(fullname) @@ -440,11 +456,15 @@ def get_loader(module_or_name): """ if module_or_name in sys.modules: module_or_name = sys.modules[module_or_name] + if module_or_name is None: + return None if isinstance(module_or_name, ModuleType): module = module_or_name loader = getattr(module, '__loader__', None) if loader is not None: return loader + if getattr(module, '__spec__', None) is None: + return None fullname = module.__name__ else: fullname = module_or_name @@ -454,29 +474,22 @@ def get_loader(module_or_name): def find_loader(fullname): """Find a PEP 302 "loader" object for fullname - This is s convenience wrapper around :func:`importlib.find_loader` that - sets the *path* argument correctly when searching for submodules, and - also ensures parent packages (if any) are imported before searching for - submodules. + This is a backwards compatibility wrapper around + importlib.util.find_spec that converts most failures to ImportError + and only returns the loader rather than the full spec """ if fullname.startswith('.'): msg = "Relative module name {!r} not supported".format(fullname) raise ImportError(msg) - path = None - pkg_name = fullname.rpartition(".")[0] - if pkg_name: - pkg = importlib.import_module(pkg_name) - path = getattr(pkg, "__path__", None) - if path is None: - return None try: - return importlib.find_loader(fullname, path) + spec = importlib.util.find_spec(fullname) except (ImportError, AttributeError, TypeError, ValueError) as ex: # This hack fixes an impedance mismatch between pkgutil and # importlib, where the latter raises other errors for cases where # pkgutil previously raised ImportError msg = "Error while finding loader for {!r} ({}: {})" raise ImportError(msg.format(fullname, type(ex), ex)) from ex + return spec.loader if spec is not None else None def extend_path(path, name): @@ -538,13 +551,14 @@ def extend_path(path, name): finder = get_importer(dir) if finder is not None: + portions = [] + if hasattr(finder, 'find_spec'): + spec = finder.find_spec(final_name) + if spec is not None: + portions = spec.submodule_search_locations or [] # Is this finder PEP 420 compliant? - if hasattr(finder, 'find_loader'): - loader, portions = finder.find_loader(final_name) - else: - # No, no need to call it - loader = None - portions = [] + elif hasattr(finder, 'find_loader'): + _, portions = finder.find_loader(final_name) for portion in portions: # XXX This may still add duplicate entries to path on @@ -594,7 +608,7 @@ def get_data(package, resource): which does not support get_data(), then None is returned. """ - spec = importlib.find_spec(package) + spec = importlib.util.find_spec(package) if spec is None: return None loader = spec.loader @@ -602,7 +616,7 @@ def get_data(package, resource): return None # XXX needs test mod = (sys.modules.get(package) or - importlib._bootstrap._SpecMethods(spec).load()) + importlib._bootstrap._load(spec)) if mod is None or not hasattr(mod, '__file__'): return None diff --git a/Lib/platform.py b/Lib/platform.py index c3c4b328e110..c4ffe95bca3d 100755 --- a/Lib/platform.py +++ b/Lib/platform.py @@ -122,13 +122,17 @@ except AttributeError: # os.devnull was added in Python 2.4, so emulate it for earlier # Python versions - if sys.platform in ('dos','win32','win16'): + if sys.platform in ('dos', 'win32', 'win16'): # Use the old CP/M NUL as device name DEV_NULL = 'NUL' else: # Standard Unix uses /dev/null DEV_NULL = '/dev/null' +# Directory to search for configuration information on Unix. +# Constant used by test_platform to test linux_distribution(). +_UNIXCONFDIR = '/etc' + ### Platform specific APIs _libc_search = re.compile(b'(__libc_init)' @@ -137,7 +141,7 @@ b'|' br'(libc(_\w+)?\.so(?:\.(\d[0-9.]*))?)', re.ASCII) -def libc_ver(executable=sys.executable,lib='',version='', +def libc_ver(executable=sys.executable, lib='', version='', chunksize=16384): @@ -159,12 +163,12 @@ def libc_ver(executable=sys.executable,lib='',version='', # here to work around problems with Cygwin not being # able to open symlinks for reading executable = os.path.realpath(executable) - f = open(executable,'rb') + f = open(executable, 'rb') binary = f.read(chunksize) pos = 0 while 1: if b'libc' in binary or b'GLIBC' in binary: - m = _libc_search.search(binary,pos) + m = _libc_search.search(binary, pos) else: m = None if not m: @@ -173,7 +177,7 @@ def libc_ver(executable=sys.executable,lib='',version='', break pos = 0 continue - libcinit,glibc,glibcversion,so,threads,soversion = [ + libcinit, glibc, glibcversion, so, threads, soversion = [ s.decode('latin1') if s is not None else s for s in m.groups()] if libcinit and not lib: @@ -193,9 +197,9 @@ def libc_ver(executable=sys.executable,lib='',version='', version = version + threads pos = m.end() f.close() - return lib,version + return lib, version -def _dist_try_harder(distname,version,id): +def _dist_try_harder(distname, version, id): """ Tries some special tricks to get the distribution information in case the default method fails. @@ -210,7 +214,7 @@ def _dist_try_harder(distname,version,id): for line in open('/var/adm/inst-log/info'): tv = line.split() if len(tv) == 2: - tag,value = tv + tag, value = tv else: continue if tag == 'MIN_DIST_VERSION': @@ -218,7 +222,7 @@ def _dist_try_harder(distname,version,id): elif tag == 'DIST_IDENT': values = value.split('-') id = values[2] - return distname,version,id + return distname, version, id if os.path.exists('/etc/.installed'): # Caldera OpenLinux has some infos in that file (thanks to Colin Kong) @@ -227,7 +231,7 @@ def _dist_try_harder(distname,version,id): if len(pkg) >= 2 and pkg[0] == 'OpenLinux': # XXX does Caldera support non Intel platforms ? If yes, # where can we find the needed id ? - return 'OpenLinux',pkg[1],id + return 'OpenLinux', pkg[1], id if os.path.isdir('/usr/lib/setup'): # Check for slackware version tag file (thanks to Greg Andruk) @@ -239,9 +243,9 @@ def _dist_try_harder(distname,version,id): verfiles.sort() distname = 'slackware' version = verfiles[-1][14:] - return distname,version,id + return distname, version, id - return distname,version,id + return distname, version, id _release_filename = re.compile(r'(\w+)[-_](release|version)', re.ASCII) _lsb_release_version = re.compile(r'(.+)' @@ -310,28 +314,29 @@ def linux_distribution(distname='', version='', id='', distribution read from the OS is returned. Otherwise the short name taken from supported_dists is used. - Returns a tuple (distname,version,id) which default to the + Returns a tuple (distname, version, id) which default to the args given as parameters. """ try: - etc = os.listdir('/etc') + etc = os.listdir(_UNIXCONFDIR) except OSError: # Probably not a Unix system - return distname,version,id + return distname, version, id etc.sort() for file in etc: m = _release_filename.match(file) if m is not None: - _distname,dummy = m.groups() + _distname, dummy = m.groups() if _distname in supported_dists: distname = _distname break else: - return _dist_try_harder(distname,version,id) + return _dist_try_harder(distname, version, id) # Read the first line - with open('/etc/'+file, 'r') as f: + with open(os.path.join(_UNIXCONFDIR, file), 'r', + encoding='utf-8', errors='surrogateescape') as f: firstline = f.readline() _distname, _version, _id = _parse_release_file(firstline) @@ -345,7 +350,7 @@ def linux_distribution(distname='', version='', id='', # To maintain backwards compatibility: -def dist(distname='',version='',id='', +def dist(distname='', version='', id='', supported_dists=_supported_dists): @@ -355,7 +360,7 @@ def dist(distname='',version='',id='', /etc and then reverts to _dist_try_harder() in case no suitable files are found. - Returns a tuple (distname,version,id) which default to the + Returns a tuple (distname, version, id) which default to the args given as parameters. """ @@ -380,11 +385,11 @@ def _norm_version(version, build=''): if build: l.append(build) try: - ints = map(int,l) + ints = map(int, l) except ValueError: strings = l else: - strings = list(map(str,ints)) + strings = list(map(str, ints)) version = '.'.join(strings[:3]) return version @@ -403,10 +408,10 @@ def _norm_version(version, build=''): def _syscmd_ver(system='', release='', version='', - supported_platforms=('win32','win16','dos')): + supported_platforms=('win32', 'win16', 'dos')): """ Tries to figure out the OS version used and returns - a tuple (system,release,version). + a tuple (system, release, version). It uses the "ver" shell command for this which is known to exists on Windows, DOS. XXX Others too ? @@ -416,10 +421,10 @@ def _syscmd_ver(system='', release='', version='', """ if sys.platform not in supported_platforms: - return system,release,version + return system, release, version # Try some common cmd strings - for cmd in ('ver','command /c ver','cmd /c ver'): + for cmd in ('ver', 'command /c ver', 'cmd /c ver'): try: pipe = popen(cmd) info = pipe.read() @@ -428,18 +433,18 @@ def _syscmd_ver(system='', release='', version='', # XXX How can I suppress shell errors from being written # to stderr ? except OSError as why: - #print 'Command %s failed: %s' % (cmd,why) + #print 'Command %s failed: %s' % (cmd, why) continue else: break else: - return system,release,version + return system, release, version # Parse the output info = info.strip() m = _ver_output.match(info) if m is not None: - system,release,version = m.groups() + system, release, version = m.groups() # Strip trailing dots from version and release if release[-1] == '.': release = release[:-1] @@ -448,9 +453,9 @@ def _syscmd_ver(system='', release='', version='', # Normalize the version and build strings (eliminating additional # zeros) version = _norm_version(version) - return system,release,version + return system, release, version -def _win32_getvalue(key,name,default=''): +def _win32_getvalue(key, name, default=''): """ Read a value for name from the registry key. @@ -465,14 +470,14 @@ def _win32_getvalue(key,name,default=''): import winreg RegQueryValueEx = winreg.QueryValueEx try: - return RegQueryValueEx(key,name) + return RegQueryValueEx(key, name) except: return default -def win32_ver(release='',version='',csd='',ptype=''): +def win32_ver(release='', version='', csd='', ptype=''): """ Get additional version information from the Windows Registry - and return a tuple (version,csd,ptype) referring to version + and return a tuple (version, csd, ptype) referring to version number, CSD level (service pack), and OS type (multi/single processor). @@ -498,7 +503,6 @@ def win32_ver(release='',version='',csd='',ptype=''): # Import the needed APIs try: - import win32api from win32api import RegQueryValueEx, RegOpenKeyEx, \ RegCloseKey, GetVersionEx from win32con import HKEY_LOCAL_MACHINE, VER_PLATFORM_WIN32_NT, \ @@ -509,7 +513,7 @@ def win32_ver(release='',version='',csd='',ptype=''): sys.getwindowsversion except AttributeError: # No emulation possible, so return the defaults... - return release,version,csd,ptype + return release, version, csd, ptype else: # Emulation using winreg (added in Python 2.0) and # sys.getwindowsversion() (added in Python 2.3) @@ -527,8 +531,8 @@ def win32_ver(release='',version='',csd='',ptype=''): # Find out the registry key and some general version infos winver = GetVersionEx() - maj,min,buildno,plat,csd = winver - version = '%i.%i.%i' % (maj,min,buildno & 0xFFFF) + maj, min, buildno, plat, csd = winver + version = '%i.%i.%i' % (maj, min, buildno & 0xFFFF) if hasattr(winver, "service_pack"): if winver.service_pack != "": csd = 'SP%s' % winver.service_pack_major @@ -603,8 +607,8 @@ def win32_ver(release='',version='',csd='',ptype=''): else: if not release: # E.g. Win3.1 with win32s - release = '%i.%i' % (maj,min) - return release,version,csd,ptype + release = '%i.%i' % (maj, min) + return release, version, csd, ptype # Open the registry key try: @@ -612,7 +616,7 @@ def win32_ver(release='',version='',csd='',ptype=''): # Get a value to make sure the key exists... RegQueryValueEx(keyCurVer, 'SystemRoot') except: - return release,version,csd,ptype + return release, version, csd, ptype # Parse values #subversion = _win32_getvalue(keyCurVer, @@ -622,17 +626,17 @@ def win32_ver(release='',version='',csd='',ptype=''): # release = release + subversion # 95a, 95b, etc. build = _win32_getvalue(keyCurVer, 'CurrentBuildNumber', - ('',1))[0] + ('', 1))[0] ptype = _win32_getvalue(keyCurVer, 'CurrentType', - (ptype,1))[0] + (ptype, 1))[0] # Normalize version - version = _norm_version(version,build) + version = _norm_version(version, build) # Close key RegCloseKey(keyCurVer) - return release,version,csd,ptype + return release, version, csd, ptype def _mac_ver_xml(): fn = '/System/Library/CoreServices/SystemVersion.plist' @@ -644,18 +648,19 @@ def _mac_ver_xml(): except ImportError: return None - pl = plistlib.readPlist(fn) + with open(fn, 'rb') as f: + pl = plistlib.load(f) release = pl['ProductVersion'] - versioninfo=('', '', '') + versioninfo = ('', '', '') machine = os.uname().machine if machine in ('ppc', 'Power Macintosh'): # Canonical name machine = 'PowerPC' - return release,versioninfo,machine + return release, versioninfo, machine -def mac_ver(release='',versioninfo=('','',''),machine=''): +def mac_ver(release='', versioninfo=('', '', ''), machine=''): """ Get MacOS version information and return it as tuple (release, versioninfo, machine) with versioninfo being a tuple (version, @@ -672,9 +677,9 @@ def mac_ver(release='',versioninfo=('','',''),machine=''): return info # If that also doesn't work return the default values - return release,versioninfo,machine + return release, versioninfo, machine -def _java_getprop(name,default): +def _java_getprop(name, default): from java.lang import System try: @@ -685,13 +690,13 @@ def _java_getprop(name,default): except AttributeError: return default -def java_ver(release='',vendor='',vminfo=('','',''),osinfo=('','','')): +def java_ver(release='', vendor='', vminfo=('', '', ''), osinfo=('', '', '')): """ Version interface for Jython. - Returns a tuple (release,vendor,vminfo,osinfo) with vminfo being - a tuple (vm_name,vm_release,vm_vendor) and osinfo being a - tuple (os_name,os_version,os_arch). + Returns a tuple (release, vendor, vminfo, osinfo) with vminfo being + a tuple (vm_name, vm_release, vm_vendor) and osinfo being a + tuple (os_name, os_version, os_arch). Values which cannot be determined are set to the defaults given as parameters (which all default to ''). @@ -701,7 +706,7 @@ def java_ver(release='',vendor='',vminfo=('','',''),osinfo=('','','')): try: import java.lang except ImportError: - return release,vendor,vminfo,osinfo + return release, vendor, vminfo, osinfo vendor = _java_getprop('java.vendor', vendor) release = _java_getprop('java.version', release) @@ -720,9 +725,9 @@ def java_ver(release='',vendor='',vminfo=('','',''),osinfo=('','','')): ### System name aliasing -def system_alias(system,release,version): +def system_alias(system, release, version): - """ Returns (system,release,version) aliased to common + """ Returns (system, release, version) aliased to common marketing names used for some systems. It also does some reordering of the information in some cases @@ -732,13 +737,13 @@ def system_alias(system,release,version): if system == 'Rhapsody': # Apple's BSD derivative # XXX How can we determine the marketing release number ? - return 'MacOS X Server',system+release,version + return 'MacOS X Server', system+release, version elif system == 'SunOS': # Sun's OS if release < '5': # These releases use the old name SunOS - return system,release,version + return system, release, version # Modify release (marketing release = SunOS release - 3) l = release.split('.') if l: @@ -766,11 +771,11 @@ def system_alias(system,release,version): else: version = '64bit' - elif system in ('win32','win16'): + elif system in ('win32', 'win16'): # In case one of the other tricks system = 'Windows' - return system,release,version + return system, release, version ### Various internal helpers @@ -783,21 +788,21 @@ def _platform(*args): platform = '-'.join(x.strip() for x in filter(len, args)) # Cleanup some possible filename obstacles... - platform = platform.replace(' ','_') - platform = platform.replace('/','-') - platform = platform.replace('\\','-') - platform = platform.replace(':','-') - platform = platform.replace(';','-') - platform = platform.replace('"','-') - platform = platform.replace('(','-') - platform = platform.replace(')','-') + platform = platform.replace(' ', '_') + platform = platform.replace('/', '-') + platform = platform.replace('\\', '-') + platform = platform.replace(':', '-') + platform = platform.replace(';', '-') + platform = platform.replace('"', '-') + platform = platform.replace('(', '-') + platform = platform.replace(')', '-') # No need to report 'unknown' information... - platform = platform.replace('unknown','') + platform = platform.replace('unknown', '') # Fold '--'s and remove trailing '-' while 1: - cleaned = platform.replace('--','-') + cleaned = platform.replace('--', '-') if cleaned == platform: break platform = cleaned @@ -829,14 +834,14 @@ def _follow_symlinks(filepath): filepath = os.path.abspath(filepath) while os.path.islink(filepath): filepath = os.path.normpath( - os.path.join(os.path.dirname(filepath),os.readlink(filepath))) + os.path.join(os.path.dirname(filepath), os.readlink(filepath))) return filepath -def _syscmd_uname(option,default=''): +def _syscmd_uname(option, default=''): """ Interface to the system's uname command. """ - if sys.platform in ('dos','win32','win16'): + if sys.platform in ('dos', 'win32', 'win16'): # XXX Others too ? return default try: @@ -850,7 +855,7 @@ def _syscmd_uname(option,default=''): else: return output -def _syscmd_file(target,default=''): +def _syscmd_file(target, default=''): """ Interface to the system's file command. @@ -859,7 +864,7 @@ def _syscmd_file(target,default=''): default in case the command should fail. """ - if sys.platform in ('dos','win32','win16'): + if sys.platform in ('dos', 'win32', 'win16'): # XXX Others too ? return default target = _follow_symlinks(target) @@ -881,17 +886,17 @@ def _syscmd_file(target,default=''): # Default values for architecture; non-empty strings override the # defaults given as parameters _default_architecture = { - 'win32': ('','WindowsPE'), - 'win16': ('','Windows'), - 'dos': ('','MSDOS'), + 'win32': ('', 'WindowsPE'), + 'win16': ('', 'Windows'), + 'dos': ('', 'MSDOS'), } -def architecture(executable=sys.executable,bits='',linkage=''): +def architecture(executable=sys.executable, bits='', linkage=''): """ Queries the given executable (defaults to the Python interpreter binary) for various architecture information. - Returns a tuple (bits,linkage) which contains information about + Returns a tuple (bits, linkage) which contains information about the bit architecture and the linkage format used for the executable. Both values are returned as strings. @@ -929,16 +934,16 @@ def architecture(executable=sys.executable,bits='',linkage=''): # "file" command did not return anything; we'll try to provide # some sensible defaults then... if sys.platform in _default_architecture: - b,l = _default_architecture[sys.platform] + b, l = _default_architecture[sys.platform] if b: bits = b if l: linkage = l - return bits,linkage + return bits, linkage if 'executable' not in fileout: # Format not supported - return bits,linkage + return bits, linkage # Bits if '32-bit' in fileout: @@ -966,7 +971,7 @@ def architecture(executable=sys.executable,bits='',linkage=''): # XXX the A.OUT format also falls under this class... pass - return bits,linkage + return bits, linkage ### Portable uname() interface @@ -978,7 +983,7 @@ def architecture(executable=sys.executable,bits='',linkage=''): def uname(): """ Fairly portable uname interface. Returns a tuple - of strings (system,node,release,version,machine,processor) + of strings (system, node, release, version, machine, processor) identifying the underlying platform. Note that unlike the os.uname function this also returns @@ -997,7 +1002,7 @@ def uname(): # Get some infos from the builtin os.uname API... try: - system,node,release,version,machine = os.uname() + system, node, release, version, machine = os.uname() except AttributeError: no_os_uname = 1 @@ -1015,7 +1020,7 @@ def uname(): # Try win32_ver() on win32 platforms if system == 'win32': - release,version,csd,ptype = win32_ver() + release, version, csd, ptype = win32_ver() if release and version: use_syscmd_ver = 0 # Try to use the PROCESSOR_* environment variables @@ -1034,7 +1039,7 @@ def uname(): # Try the 'ver' system command available on some # platforms if use_syscmd_ver: - system,release,version = _syscmd_ver(system) + system, release, version = _syscmd_ver(system) # Normalize system to what win32_ver() normally returns # (_syscmd_ver() tends to return the vendor name as well) if system == 'Microsoft Windows': @@ -1052,7 +1057,7 @@ def uname(): # In case we still don't know anything useful, we'll try to # help ourselves - if system in ('win32','win16'): + if system in ('win32', 'win16'): if not version: if system == 'win32': version = '32bit' @@ -1061,7 +1066,7 @@ def uname(): system = 'Windows' elif system[:4] == 'java': - release,vendor,vminfo,osinfo = java_ver() + release, vendor, vminfo, osinfo = java_ver() system = 'Java' version = ', '.join(vminfo) if not version: @@ -1079,14 +1084,14 @@ def uname(): except ImportError: pass else: - csid, cpu_number = vms_lib.getsyi('SYI$_CPU',0) + csid, cpu_number = vms_lib.getsyi('SYI$_CPU', 0) if (cpu_number >= 128): processor = 'Alpha' else: processor = 'VAX' if not processor: # Get processor information from the uname system command - processor = _syscmd_uname('-p','') + processor = _syscmd_uname('-p', '') #If any unknowns still exist, replace them with ''s, which are more portable if system == 'unknown': @@ -1107,7 +1112,8 @@ def uname(): system = 'Windows' release = 'Vista' - _uname_cache = uname_result(system,node,release,version,machine,processor) + _uname_cache = uname_result(system, node, release, version, + machine, processor) return _uname_cache ### Direct interfaces to some of the uname() return values @@ -1404,57 +1410,58 @@ def platform(aliased=0, terse=0): # Get uname information and then apply platform specific cosmetics # to it... - system,node,release,version,machine,processor = uname() + system, node, release, version, machine, processor = uname() if machine == processor: processor = '' if aliased: - system,release,version = system_alias(system,release,version) + system, release, version = system_alias(system, release, version) if system == 'Windows': # MS platforms - rel,vers,csd,ptype = win32_ver(version) + rel, vers, csd, ptype = win32_ver(version) if terse: - platform = _platform(system,release) + platform = _platform(system, release) else: - platform = _platform(system,release,version,csd) + platform = _platform(system, release, version, csd) elif system in ('Linux',): # Linux based systems - distname,distversion,distid = dist('') + distname, distversion, distid = dist('') if distname and not terse: - platform = _platform(system,release,machine,processor, + platform = _platform(system, release, machine, processor, 'with', - distname,distversion,distid) + distname, distversion, distid) else: # If the distribution name is unknown check for libc vs. glibc - libcname,libcversion = libc_ver(sys.executable) - platform = _platform(system,release,machine,processor, + libcname, libcversion = libc_ver(sys.executable) + platform = _platform(system, release, machine, processor, 'with', libcname+libcversion) elif system == 'Java': # Java platforms - r,v,vminfo,(os_name,os_version,os_arch) = java_ver() + r, v, vminfo, (os_name, os_version, os_arch) = java_ver() if terse or not os_name: - platform = _platform(system,release,version) + platform = _platform(system, release, version) else: - platform = _platform(system,release,version, + platform = _platform(system, release, version, 'on', - os_name,os_version,os_arch) + os_name, os_version, os_arch) elif system == 'MacOS': # MacOS platforms if terse: - platform = _platform(system,release) + platform = _platform(system, release) else: - platform = _platform(system,release,machine) + platform = _platform(system, release, machine) else: # Generic handler if terse: - platform = _platform(system,release) + platform = _platform(system, release) else: - bits,linkage = architecture(sys.executable) - platform = _platform(system,release,machine,processor,bits,linkage) + bits, linkage = architecture(sys.executable) + platform = _platform(system, release, machine, + processor, bits, linkage) _platform_cache[(aliased, terse)] = platform return platform @@ -1465,5 +1472,5 @@ def platform(aliased=0, terse=0): # Default is to print the aliased verbose platform string terse = ('terse' in sys.argv or '--terse' in sys.argv) aliased = (not 'nonaliased' in sys.argv and not '--nonaliased' in sys.argv) - print(platform(aliased,terse)) + print(platform(aliased, terse)) sys.exit(0) diff --git a/Lib/plistlib.py b/Lib/plistlib.py index 277ce622d001..b9946fd313af 100644 --- a/Lib/plistlib.py +++ b/Lib/plistlib.py @@ -478,7 +478,10 @@ def write_value(self, value): self.simple_element("false") elif isinstance(value, int): - self.simple_element("integer", "%d" % value) + if -1 << 63 <= value < 1 << 64: + self.simple_element("integer", "%d" % value) + else: + raise OverflowError(value) elif isinstance(value, float): self.simple_element("real", repr(value)) @@ -616,10 +619,7 @@ def parse(self, fp): offset_table_offset ) = struct.unpack('>6xBBQQQ', trailer) self._fp.seek(offset_table_offset) - offset_format = '>' + _BINARY_FORMAT[offset_size] * num_objects - self._ref_format = _BINARY_FORMAT[self._ref_size] - self._object_offsets = struct.unpack( - offset_format, self._fp.read(offset_size * num_objects)) + self._object_offsets = self._read_ints(num_objects, offset_size) return self._read_object(self._object_offsets[top_object]) except (OSError, IndexError, struct.error): @@ -635,9 +635,16 @@ def _get_size(self, tokenL): return tokenL + def _read_ints(self, n, size): + data = self._fp.read(size * n) + if size in _BINARY_FORMAT: + return struct.unpack('>' + _BINARY_FORMAT[size] * n, data) + else: + return tuple(int.from_bytes(data[i: i + size], 'big') + for i in range(0, size * n, size)) + def _read_refs(self, n): - return struct.unpack( - '>' + self._ref_format * n, self._fp.read(n * self._ref_size)) + return self._read_ints(n, self._ref_size) def _read_object(self, offset): """ @@ -665,7 +672,8 @@ def _read_object(self, offset): return b'' elif tokenH == 0x10: # int - return int.from_bytes(self._fp.read(1 << tokenL), 'big') + return int.from_bytes(self._fp.read(1 << tokenL), + 'big', signed=tokenL >= 3) elif token == 0x22: # real return struct.unpack('>f', self._fp.read(4))[0] @@ -871,14 +879,23 @@ def _write_object(self, value): self._fp.write(b'\x09') elif isinstance(value, int): - if value < 1 << 8: + if value < 0: + try: + self._fp.write(struct.pack('>Bq', 0x13, value)) + except struct.error: + raise OverflowError(value) from None + elif value < 1 << 8: self._fp.write(struct.pack('>BB', 0x10, value)) elif value < 1 << 16: self._fp.write(struct.pack('>BH', 0x11, value)) elif value < 1 << 32: self._fp.write(struct.pack('>BL', 0x12, value)) - else: + elif value < 1 << 63: self._fp.write(struct.pack('>BQ', 0x13, value)) + elif value < 1 << 64: + self._fp.write(b'\x14' + value.to_bytes(16, 'big', signed=True)) + else: + raise OverflowError(value) elif isinstance(value, float): self._fp.write(struct.pack('>Bd', 0x23, value)) @@ -933,7 +950,7 @@ def _write_object(self, value): self._fp.write(struct.pack('>' + self._ref_format * s, *valRefs)) else: - raise InvalidFileException() + raise TypeError(value) def _is_fmt_binary(header): @@ -967,18 +984,16 @@ def load(fp, *, fmt=None, use_builtin_types=True, dict_type=dict): fp.seek(0) for info in _FORMATS.values(): if info['detect'](header): - p = info['parser']( - use_builtin_types=use_builtin_types, - dict_type=dict_type, - ) + P = info['parser'] break else: raise InvalidFileException() else: - p = _FORMATS[fmt]['parser'](use_builtin_types=use_builtin_types) + P = _FORMATS[fmt]['parser'] + p = P(use_builtin_types=use_builtin_types, dict_type=dict_type) return p.parse(fp) diff --git a/Lib/poplib.py b/Lib/poplib.py index 00ffbcb166ba..8ad9cb77db75 100644 --- a/Lib/poplib.py +++ b/Lib/poplib.py @@ -41,7 +41,7 @@ class error_proto(Exception): pass CRLF = CR+LF # maximal line length when calling readline(). This is to prevent -# reading arbitrary lenght lines. RFC 1939 limits POP3 line length to +# reading arbitrary length lines. RFC 1939 limits POP3 line length to # 512 characters, including CRLF. We have selected 2048 just to be on # the safe side. _MAXLINE = 2048 @@ -387,7 +387,8 @@ def stls(self, context=None): if context is None: context = ssl._create_stdlib_context() resp = self._shortcmd('STLS') - self.sock = context.wrap_socket(self.sock) + self.sock = context.wrap_socket(self.sock, + server_hostname=self.host) self.file = self.sock.makefile('rb') self._tls_established = True return resp @@ -428,7 +429,8 @@ def __init__(self, host, port=POP3_SSL_PORT, keyfile=None, certfile=None, def _create_socket(self, timeout): sock = POP3._create_socket(self, timeout) - sock = self.context.wrap_socket(sock) + sock = self.context.wrap_socket(sock, + server_hostname=self.host) return sock def stls(self, keyfile=None, certfile=None, context=None): diff --git a/Lib/posixpath.py b/Lib/posixpath.py index 492c415aa5da..44ed8383f2e4 100644 --- a/Lib/posixpath.py +++ b/Lib/posixpath.py @@ -48,7 +48,6 @@ def _get_sep(path): def normcase(s): """Normalize case of pathname. Has no effect under Posix""" - # TODO: on Mac OS X, this should really return s.lower(). if not isinstance(s, (bytes, str)): raise TypeError("normcase() argument must be str or bytes, " "not '{}'".format(s.__class__.__name__)) @@ -83,13 +82,8 @@ def join(a, *p): path += b else: path += sep + b - except TypeError: - valid_types = all(isinstance(s, (str, bytes, bytearray)) - for s in (a, ) + p) - if valid_types: - # Must have a mixture of text and binary data - raise TypeError("Can't mix strings and bytes in path " - "components.") from None + except (TypeError, AttributeError, BytesWarning): + genericpath._check_arg_types('join', a, *p) raise return path @@ -279,6 +273,7 @@ def expandvars(path): search = _varprogb.search start = b'{' end = b'}' + environ = getattr(os, 'environb', None) else: if '$' not in path: return path @@ -288,6 +283,7 @@ def expandvars(path): search = _varprog.search start = '{' end = '}' + environ = os.environ i = 0 while True: m = search(path, i) @@ -297,18 +293,18 @@ def expandvars(path): name = m.group(1) if name.startswith(start) and name.endswith(end): name = name[1:-1] - if isinstance(name, bytes): - name = str(name, 'ASCII') - if name in os.environ: + try: + if environ is None: + value = os.fsencode(os.environ[os.fsdecode(name)]) + else: + value = environ[name] + except KeyError: + i = j + else: tail = path[j:] - value = os.environ[name] - if isinstance(path, bytes): - value = value.encode('ASCII') path = path[:i] + value i = len(path) path += tail - else: - i = j return path @@ -446,13 +442,16 @@ def relpath(path, start=None): if start is None: start = curdir - start_list = [x for x in abspath(start).split(sep) if x] - path_list = [x for x in abspath(path).split(sep) if x] - - # Work out how much of the filepath is shared by start and path. - i = len(commonprefix([start_list, path_list])) - - rel_list = [pardir] * (len(start_list)-i) + path_list[i:] - if not rel_list: - return curdir - return join(*rel_list) + try: + start_list = [x for x in abspath(start).split(sep) if x] + path_list = [x for x in abspath(path).split(sep) if x] + # Work out how much of the filepath is shared by start and path. + i = len(commonprefix([start_list, path_list])) + + rel_list = [pardir] * (len(start_list)-i) + path_list[i:] + if not rel_list: + return curdir + return join(*rel_list) + except (TypeError, AttributeError, BytesWarning, DeprecationWarning): + genericpath._check_arg_types('relpath', path, start) + raise diff --git a/Lib/pprint.py b/Lib/pprint.py index 3be9c3625401..0091e6925ba5 100644 --- a/Lib/pprint.py +++ b/Lib/pprint.py @@ -161,7 +161,7 @@ def _format(self, object, stream, indent, allowance, context, level): return rep = self._repr(object, context, level - 1) typ = type(object) - max_width = self._width - 1 - indent - allowance + max_width = self._width - indent - allowance sepLines = len(rep) > max_width write = stream.write @@ -174,24 +174,14 @@ def _format(self, object, stream, indent, allowance, context, level): length = len(object) if length: context[objid] = 1 - indent = indent + self._indent_per_level if issubclass(typ, _OrderedDict): items = list(object.items()) else: items = sorted(object.items(), key=_safe_tuple) - key, ent = items[0] - rep = self._repr(key, context, level) - write(rep) - write(': ') - self._format(ent, stream, indent + len(rep) + 2, - allowance + 1, context, level) - if length > 1: - for key, ent in items[1:]: - rep = self._repr(key, context, level) - write(',\n%s%s: ' % (' '*indent, rep)) - self._format(ent, stream, indent + len(rep) + 2, - allowance + 1, context, level) - indent = indent - self._indent_per_level + self._format_dict_items(items, stream, + indent + self._indent_per_level, + allowance + 1, + context, level) del context[objid] write('}') return @@ -207,7 +197,10 @@ def _format(self, object, stream, indent, allowance, context, level): endchar = ']' elif issubclass(typ, tuple): write('(') - endchar = ')' + if length == 1: + endchar = ',)' + else: + endchar = ')' else: if not length: write(rep) @@ -227,52 +220,94 @@ def _format(self, object, stream, indent, allowance, context, level): context[objid] = 1 self._format_items(object, stream, indent + self._indent_per_level, - allowance + 1, context, level) + allowance + len(endchar), + context, level) del context[objid] - if issubclass(typ, tuple) and length == 1: - write(',') write(endchar) return if issubclass(typ, str) and len(object) > 0 and r is str.__repr__: - def _str_parts(s): - """ - Return a list of string literals comprising the repr() - of the given string using literal concatenation. - """ - lines = s.splitlines(True) - for i, line in enumerate(lines): - rep = repr(line) - if len(rep) <= max_width: - yield rep - else: - # A list of alternating (non-space, space) strings - parts = re.split(r'(\s+)', line) + [''] - current = '' - for i in range(0, len(parts), 2): - part = parts[i] + parts[i+1] - candidate = current + part - if len(repr(candidate)) > max_width: - if current: - yield repr(current) - current = part - else: - current = candidate - if current: - yield repr(current) - for i, rep in enumerate(_str_parts(object)): + chunks = [] + lines = object.splitlines(True) + if level == 1: + indent += 1 + allowance += 1 + max_width1 = max_width = self._width - indent + for i, line in enumerate(lines): + rep = repr(line) + if i == len(lines) - 1: + max_width1 -= allowance + if len(rep) <= max_width1: + chunks.append(rep) + else: + # A list of alternating (non-space, space) strings + parts = re.findall(r'\S*\s*', line) + assert parts + assert not parts[-1] + parts.pop() # drop empty last part + max_width2 = max_width + current = '' + for j, part in enumerate(parts): + candidate = current + part + if j == len(parts) - 1 and i == len(lines) - 1: + max_width2 -= allowance + if len(repr(candidate)) > max_width2: + if current: + chunks.append(repr(current)) + current = part + else: + current = candidate + if current: + chunks.append(repr(current)) + if len(chunks) == 1: + write(rep) + return + if level == 1: + write('(') + for i, rep in enumerate(chunks): if i > 0: write('\n' + ' '*indent) write(rep) + if level == 1: + write(')') return write(rep) + def _format_dict_items(self, items, stream, indent, allowance, context, + level): + write = stream.write + delimnl = ',\n' + ' ' * indent + last_index = len(items) - 1 + for i, (key, ent) in enumerate(items): + last = i == last_index + rep = self._repr(key, context, level) + write(rep) + write(': ') + self._format(ent, stream, indent + len(rep) + 2, + allowance if last else 1, + context, level) + if not last: + write(delimnl) + def _format_items(self, items, stream, indent, allowance, context, level): write = stream.write delimnl = ',\n' + ' ' * indent delim = '' - width = max_width = self._width - indent - allowance + 2 - for ent in items: + width = max_width = self._width - indent + 1 + it = iter(items) + try: + next_ent = next(it) + except StopIteration: + return + last = False + while not last: + ent = next_ent + try: + next_ent = next(it) + except StopIteration: + last = True + max_width -= allowance + width -= allowance if self._compact: rep = self._repr(ent, context, level) w = len(rep) + 2 @@ -288,7 +323,9 @@ def _format_items(self, items, stream, indent, allowance, context, level): continue write(delim) delim = delimnl - self._format(ent, stream, indent, allowance, context, level) + self._format(ent, stream, indent, + allowance if last else 1, + context, level) def _repr(self, object, context, level): repr, readable, recursive = self.format(object, context.copy(), diff --git a/Lib/pyclbr.py b/Lib/pyclbr.py index 9ec05ee80b27..dd58ada0aa52 100644 --- a/Lib/pyclbr.py +++ b/Lib/pyclbr.py @@ -42,7 +42,7 @@ import io import os import sys -import importlib +import importlib.util import tokenize from token import NAME, DEDENT, OP from operator import itemgetter @@ -140,13 +140,14 @@ def _readmodule(module, path, inpackage=None): search_path = path else: search_path = path + sys.path - loader = importlib.find_loader(fullmodule, search_path) - fname = loader.get_filename(fullmodule) + # XXX This will change once issue19944 lands. + spec = importlib.util._find_spec_from_path(fullmodule, search_path) + fname = spec.loader.get_filename(fullmodule) _modules[fullmodule] = dict - if loader.is_package(fullmodule): + if spec.loader.is_package(fullmodule): dict['__path__'] = [os.path.dirname(fname)] try: - source = loader.get_source(fullmodule) + source = spec.loader.get_source(fullmodule) if source is None: return dict except (AttributeError, ImportError): diff --git a/Lib/pydoc.py b/Lib/pydoc.py index 2e632266eb6f..b762389cf3a6 100755 --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -1,8 +1,9 @@ #!/usr/bin/env python3 """Generate Python documentation in HTML or text for interactive use. -In the Python interpreter, do "from pydoc import help" to provide -help. Calling help(thing) on a Python object documents the object. +At the Python interactive prompt, calling help(thing) on a Python object +documents the object, and calling help() starts up an interactive +help session. Or, at the shell command line outside of Python: @@ -63,10 +64,11 @@ class or function within a module or module in a package. If the import sys import time import tokenize +import urllib.parse import warnings from collections import deque from reprlib import Repr -from traceback import extract_tb, format_exception_only +from traceback import format_exception_only # --------------------------------------------------------- common routines @@ -137,6 +139,19 @@ def _is_some_method(obj): inspect.isbuiltin(obj) or inspect.ismethoddescriptor(obj)) +def _is_bound_method(fn): + """ + Returns True if fn is a bound method, regardless of whether + fn was implemented in Python or in C. + """ + if inspect.ismethod(fn): + return True + if inspect.isbuiltin(fn): + self = getattr(fn, '__self__', None) + return not (inspect.ismodule(self) or (self is None)) + return False + + def allmethods(cl): methods = {} for key, value in inspect.getmembers(cl, _is_some_method): @@ -225,34 +240,37 @@ def synopsis(filename, cache={}): mtime = os.stat(filename).st_mtime lastupdate, result = cache.get(filename, (None, None)) if lastupdate is None or lastupdate < mtime: - try: - file = tokenize.open(filename) - except OSError: - # module can't be opened, so skip it - return None - binary_suffixes = importlib.machinery.BYTECODE_SUFFIXES[:] - binary_suffixes += importlib.machinery.EXTENSION_SUFFIXES[:] - if any(filename.endswith(x) for x in binary_suffixes): - # binary modules have to be imported - file.close() - if any(filename.endswith(x) for x in - importlib.machinery.BYTECODE_SUFFIXES): - loader = importlib.machinery.SourcelessFileLoader('__temp__', - filename) - else: - loader = importlib.machinery.ExtensionFileLoader('__temp__', - filename) + # Look for binary suffixes first, falling back to source. + if filename.endswith(tuple(importlib.machinery.BYTECODE_SUFFIXES)): + loader_cls = importlib.machinery.SourcelessFileLoader + elif filename.endswith(tuple(importlib.machinery.EXTENSION_SUFFIXES)): + loader_cls = importlib.machinery.ExtensionFileLoader + else: + loader_cls = None + # Now handle the choice. + if loader_cls is None: + # Must be a source file. + try: + file = tokenize.open(filename) + except OSError: + # module can't be opened, so skip it + return None + # text modules can be directly examined + with file: + result = source_synopsis(file) + else: + # Must be a binary module, which has to be imported. + loader = loader_cls('__temp__', filename) + # XXX We probably don't need to pass in the loader here. + spec = importlib.util.spec_from_file_location('__temp__', filename, + loader=loader) try: - module = loader.load_module('__temp__') + module = importlib._bootstrap._load(spec) except: return None - result = (module.__doc__ or '').splitlines()[0] del sys.modules['__temp__'] - else: - # text modules can be directly examined - result = source_synopsis(file) - file.close() - + result = module.__doc__.splitlines()[0] if module.__doc__ else None + # Cache the result. cache[filename] = (mtime, result) return result @@ -277,8 +295,10 @@ def importfile(path): loader = importlib._bootstrap.SourcelessFileLoader(name, path) else: loader = importlib._bootstrap.SourceFileLoader(name, path) + # XXX We probably don't need to pass in the loader here. + spec = importlib.util.spec_from_file_location(name, path, loader=loader) try: - return loader.load_module(name) + return importlib._bootstrap._load(spec) except: raise ErrorDuringImport(path, sys.exc_info()) @@ -574,10 +594,15 @@ def markup(self, text, escape=None, funcs={}, classes={}, methods={}): elif pep: url = 'http://www.python.org/dev/peps/pep-%04d/' % int(pep) results.append('<a href="%s">%s</a>' % (url, escape(all))) + elif selfdot: + # Create a link for methods like 'self.method(...)' + # and use <strong> for attributes like 'self.attr' + if text[end:end+1] == '(': + results.append('self.' + self.namelink(name, methods)) + else: + results.append('self.<strong>%s</strong>' % name) elif text[end:end+1] == '(': results.append(self.namelink(name, methods, funcs, classes)) - elif selfdot: - results.append('self.<strong>%s</strong>' % name) else: results.append(self.namelink(name, classes)) here = end @@ -622,10 +647,7 @@ def docmodule(self, object, name=None, mod=None, *ignored): head = '<big><big><strong>%s</strong></big></big>' % linkedname try: path = inspect.getabsfile(object) - url = path - if sys.platform == 'win32': - import nturl2path - url = nturl2path.pathname2url(path) + url = urllib.parse.quote(path) filelink = self.filelink(url, path) except TypeError: filelink = '(built-in)' @@ -891,7 +913,7 @@ def docroutine(self, object, name=None, mod=None, anchor = (cl and cl.__name__ or '') + '-' + name note = '' skipdocs = 0 - if inspect.ismethod(object): + if _is_bound_method(object): imclass = object.__self__.__class__ if cl: if imclass is not cl: @@ -902,7 +924,6 @@ def docroutine(self, object, name=None, mod=None, object.__self__.__class__, mod) else: note = ' unbound %s method' % self.classlink(imclass,mod) - object = object.__func__ if name == realname: title = '<a name="%s"><strong>%s</strong></a>' % (anchor, realname) @@ -917,8 +938,11 @@ def docroutine(self, object, name=None, mod=None, title = '<a name="%s"><strong>%s</strong></a> = %s' % ( anchor, name, reallink) argspec = None - if inspect.isfunction(object) or inspect.isbuiltin(object): - signature = inspect.signature(object) + if inspect.isroutine(object): + try: + signature = inspect.signature(object) + except (ValueError, TypeError): + signature = None if signature: argspec = str(signature) if realname == '<lambda>': @@ -930,7 +954,7 @@ def docroutine(self, object, name=None, mod=None, if not argspec: argspec = '(...)' - decl = title + argspec + (note and self.grey( + decl = title + self.escape(argspec) + (note and self.grey( '<font face="helvetica, arial">%s</font>' % note)) if skipdocs: @@ -1234,9 +1258,12 @@ def spilldata(msg, attrs, predicate): doc = getdoc(value) else: doc = None - push(self.docother( - getattr(object, name, None) or homecls.__dict__[name], - name, mod, maxlen=70, doc=doc) + '\n') + try: + obj = getattr(object, name) + except AttributeError: + obj = homecls.__dict__[name] + push(self.docother(obj, name, mod, maxlen=70, doc=doc) + + '\n') return attrs attrs = [(name, kind, cls, value) @@ -1291,7 +1318,7 @@ def docroutine(self, object, name=None, mod=None, cl=None): name = name or realname note = '' skipdocs = 0 - if inspect.ismethod(object): + if _is_bound_method(object): imclass = object.__self__.__class__ if cl: if imclass is not cl: @@ -1302,7 +1329,6 @@ def docroutine(self, object, name=None, mod=None, cl=None): object.__self__.__class__, mod) else: note = ' unbound %s method' % classname(imclass,mod) - object = object.__func__ if name == realname: title = self.bold(realname) @@ -1312,8 +1338,12 @@ def docroutine(self, object, name=None, mod=None, cl=None): skipdocs = 1 title = self.bold(name) + ' = ' + realname argspec = None - if inspect.isfunction(object) or inspect.isbuiltin(object): - signature = inspect.signature(object) + + if inspect.isroutine(object): + try: + signature = inspect.signature(object) + except (ValueError, TypeError): + signature = None if signature: argspec = str(signature) if realname == '<lambda>': @@ -1380,6 +1410,8 @@ def pager(text): def getpager(): """Decide what method to use for paging through text.""" + if not hasattr(sys.stdin, "isatty"): + return plainpager if not hasattr(sys.stdout, "isatty"): return plainpager if not sys.stdin.isatty() or not sys.stdout.isatty(): @@ -1415,10 +1447,12 @@ def plain(text): def pipepager(text, cmd): """Page through text by feeding it to another program.""" - pipe = os.popen(cmd, 'w') + import subprocess + proc = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE) try: - pipe.write(text) - pipe.close() + with proc: + with io.TextIOWrapper(proc.stdin, errors='backslashreplace') as pipe: + pipe.write(text) except OSError: pass # Ignore broken pipes caused by quitting the pager program. @@ -1426,28 +1460,39 @@ def tempfilepager(text, cmd): """Page through text by invoking a program on a temporary file.""" import tempfile filename = tempfile.mktemp() - with open(filename, 'w') as file: + with open(filename, 'w', errors='backslashreplace') as file: file.write(text) try: os.system(cmd + ' "' + filename + '"') finally: os.unlink(filename) +def _escape_stdout(text): + # Escape non-encodable characters to avoid encoding errors later + encoding = getattr(sys.stdout, 'encoding', None) or 'utf-8' + return text.encode(encoding, 'backslashreplace').decode(encoding) + def ttypager(text): """Page through text on a text terminal.""" - lines = plain(text).split('\n') + lines = plain(_escape_stdout(text)).split('\n') try: import tty fd = sys.stdin.fileno() old = tty.tcgetattr(fd) tty.setcbreak(fd) getchar = lambda: sys.stdin.read(1) - except (ImportError, AttributeError): + except (ImportError, AttributeError, io.UnsupportedOperation): tty = None getchar = lambda: sys.stdin.readline()[:-1][:1] try: - r = inc = os.environ.get('LINES', 25) - 1 + try: + h = int(os.environ.get('LINES', 0)) + except ValueError: + h = 0 + if h <= 1: + h = 25 + r = inc = h - 1 sys.stdout.write('\n'.join(lines[:inc]) + '\n') while lines[r:]: sys.stdout.write('-- more --') @@ -1473,7 +1518,7 @@ def ttypager(text): def plainpager(text): """Simply print unformatted text. This is the ultimate fallback.""" - sys.stdout.write(plain(text)) + sys.stdout.write(plain(_escape_stdout(text))) def describe(thing): """Produce a short description of the given thing.""" @@ -1601,7 +1646,7 @@ class Helper: # in pydoc_data/topics.py. # # CAUTION: if you change one of these dictionaries, be sure to adapt the - # list of needed labels in Doc/tools/sphinxext/pyspecific.py and + # list of needed labels in Doc/tools/pyspecific.py and # regenerate the pydoc_data/topics.py file by running # make pydoc-topics # in Doc/ and copying the output file into the Lib/ directory. @@ -1701,7 +1746,6 @@ class Helper: 'TRACEBACKS': 'TYPES', 'NONE': ('bltin-null-object', ''), 'ELLIPSIS': ('bltin-ellipsis-object', 'SLICINGS'), - 'FILES': ('bltin-file-objects', ''), 'SPECIALATTRIBUTES': ('specialattrs', ''), 'CLASSES': ('types', 'class SPECIALMETHODS PRIVATENAMES'), 'MODULES': ('typesmodules', 'import'), @@ -1777,7 +1821,8 @@ def __repr__(self): if inspect.stack()[1][3] == '?': self() return '' - return '<pydoc.Helper instance>' + return '<%s.%s instance>' % (self.__class__.__module__, + self.__class__.__qualname__) _GoInteractive = object() def __call__(self, request=_GoInteractive): @@ -1837,7 +1882,7 @@ def help(self, request): def intro(self): self.output.write(''' -Welcome to Python %s! This is the interactive help utility. +Welcome to Python %s's help utility! If this is your first time using Python, you should definitely check out the tutorial on the Internet at http://docs.python.org/%s/tutorial/. @@ -2008,10 +2053,11 @@ def run(self, callback, key=None, completer=None, onerror=None): callback(None, modname, '') else: try: - loader = importer.find_module(modname) + spec = pkgutil._get_spec(importer, modname) except SyntaxError: # raised by tests for bad coding cookies or BOM continue + loader = spec.loader if hasattr(loader, 'get_source'): try: source = loader.get_source(modname) @@ -2026,12 +2072,12 @@ def run(self, callback, key=None, completer=None, onerror=None): path = None else: try: - module = loader.load_module(modname) + module = importlib._bootstrap._load(spec) except ImportError: if onerror: onerror(modname) continue - desc = (module.__doc__ or '').splitlines()[0] + desc = module.__doc__.splitlines()[0] if module.__doc__ else '' path = getattr(module,'__file__',None) name = modname + ' - ' + desc if name.lower().find(key) >= 0: @@ -2140,8 +2186,8 @@ def log_message(self, *args): class DocServer(http.server.HTTPServer): def __init__(self, port, callback): - self.host = (sys.platform == 'mac') and '127.0.0.1' or 'localhost' - self.address = ('', port) + self.host = 'localhost' + self.address = (self.host, port) self.callback = callback self.base.__init__(self, self.address, self.handler) self.quit = False @@ -2313,7 +2359,7 @@ def bltinlink(name): def html_getfile(path): """Get and display a source file listing safely.""" - path = path.replace('%20', ' ') + path = urllib.parse.unquote(path) with tokenize.open(path) as fp: lines = html.escape(fp.read()) body = '<pre>%s</pre>' % lines diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py index 4dfa3238fe99..489259e88ce7 100644 --- a/Lib/pydoc_data/topics.py +++ b/Lib/pydoc_data/topics.py @@ -1,79 +1,79 @@ # -*- coding: utf-8 -*- -# Autogenerated by Sphinx on Sun Nov 24 06:50:34 2013 -topics = {'assert': '\nThe ``assert`` statement\n************************\n\nAssert statements are a convenient way to insert debugging assertions\ninto a program:\n\n assert_stmt ::= "assert" expression ["," expression]\n\nThe simple form, ``assert expression``, is equivalent to\n\n if __debug__:\n if not expression: raise AssertionError\n\nThe extended form, ``assert expression1, expression2``, is equivalent\nto\n\n if __debug__:\n if not expression1: raise AssertionError(expression2)\n\nThese equivalences assume that ``__debug__`` and ``AssertionError``\nrefer to the built-in variables with those names. In the current\nimplementation, the built-in variable ``__debug__`` is ``True`` under\nnormal circumstances, ``False`` when optimization is requested\n(command line option -O). The current code generator emits no code\nfor an assert statement when optimization is requested at compile\ntime. Note that it is unnecessary to include the source code for the\nexpression that failed in the error message; it will be displayed as\npart of the stack trace.\n\nAssignments to ``__debug__`` are illegal. The value for the built-in\nvariable is determined when the interpreter starts.\n', - 'assignment': '\nAssignment statements\n*********************\n\nAssignment statements are used to (re)bind names to values and to\nmodify attributes or items of mutable objects:\n\n assignment_stmt ::= (target_list "=")+ (expression_list | yield_expression)\n target_list ::= target ("," target)* [","]\n target ::= identifier\n | "(" target_list ")"\n | "[" target_list "]"\n | attributeref\n | subscription\n | slicing\n | "*" target\n\n(See section *Primaries* for the syntax definitions for the last three\nsymbols.)\n\nAn assignment statement evaluates the expression list (remember that\nthis can be a single expression or a comma-separated list, the latter\nyielding a tuple) and assigns the single resulting object to each of\nthe target lists, from left to right.\n\nAssignment is defined recursively depending on the form of the target\n(list). When a target is part of a mutable object (an attribute\nreference, subscription or slicing), the mutable object must\nultimately perform the assignment and decide about its validity, and\nmay raise an exception if the assignment is unacceptable. The rules\nobserved by various types and the exceptions raised are given with the\ndefinition of the object types (see section *The standard type\nhierarchy*).\n\nAssignment of an object to a target list, optionally enclosed in\nparentheses or square brackets, is recursively defined as follows.\n\n* If the target list is a single target: The object is assigned to\n that target.\n\n* If the target list is a comma-separated list of targets: The object\n must be an iterable with the same number of items as there are\n targets in the target list, and the items are assigned, from left to\n right, to the corresponding targets.\n\n * If the target list contains one target prefixed with an asterisk,\n called a "starred" target: The object must be a sequence with at\n least as many items as there are targets in the target list, minus\n one. The first items of the sequence are assigned, from left to\n right, to the targets before the starred target. The final items\n of the sequence are assigned to the targets after the starred\n target. A list of the remaining items in the sequence is then\n assigned to the starred target (the list can be empty).\n\n * Else: The object must be a sequence with the same number of items\n as there are targets in the target list, and the items are\n assigned, from left to right, to the corresponding targets.\n\nAssignment of an object to a single target is recursively defined as\nfollows.\n\n* If the target is an identifier (name):\n\n * If the name does not occur in a ``global`` or ``nonlocal``\n statement in the current code block: the name is bound to the\n object in the current local namespace.\n\n * Otherwise: the name is bound to the object in the global namespace\n or the outer namespace determined by ``nonlocal``, respectively.\n\n The name is rebound if it was already bound. This may cause the\n reference count for the object previously bound to the name to reach\n zero, causing the object to be deallocated and its destructor (if it\n has one) to be called.\n\n* If the target is a target list enclosed in parentheses or in square\n brackets: The object must be an iterable with the same number of\n items as there are targets in the target list, and its items are\n assigned, from left to right, to the corresponding targets.\n\n* If the target is an attribute reference: The primary expression in\n the reference is evaluated. It should yield an object with\n assignable attributes; if this is not the case, ``TypeError`` is\n raised. That object is then asked to assign the assigned object to\n the given attribute; if it cannot perform the assignment, it raises\n an exception (usually but not necessarily ``AttributeError``).\n\n Note: If the object is a class instance and the attribute reference\n occurs on both sides of the assignment operator, the RHS expression,\n ``a.x`` can access either an instance attribute or (if no instance\n attribute exists) a class attribute. The LHS target ``a.x`` is\n always set as an instance attribute, creating it if necessary.\n Thus, the two occurrences of ``a.x`` do not necessarily refer to the\n same attribute: if the RHS expression refers to a class attribute,\n the LHS creates a new instance attribute as the target of the\n assignment:\n\n class Cls:\n x = 3 # class variable\n inst = Cls()\n inst.x = inst.x + 1 # writes inst.x as 4 leaving Cls.x as 3\n\n This description does not necessarily apply to descriptor\n attributes, such as properties created with ``property()``.\n\n* If the target is a subscription: The primary expression in the\n reference is evaluated. It should yield either a mutable sequence\n object (such as a list) or a mapping object (such as a dictionary).\n Next, the subscript expression is evaluated.\n\n If the primary is a mutable sequence object (such as a list), the\n subscript must yield an integer. If it is negative, the sequence\'s\n length is added to it. The resulting value must be a nonnegative\n integer less than the sequence\'s length, and the sequence is asked\n to assign the assigned object to its item with that index. If the\n index is out of range, ``IndexError`` is raised (assignment to a\n subscripted sequence cannot add new items to a list).\n\n If the primary is a mapping object (such as a dictionary), the\n subscript must have a type compatible with the mapping\'s key type,\n and the mapping is then asked to create a key/datum pair which maps\n the subscript to the assigned object. This can either replace an\n existing key/value pair with the same key value, or insert a new\n key/value pair (if no key with the same value existed).\n\n For user-defined objects, the ``__setitem__()`` method is called\n with appropriate arguments.\n\n* If the target is a slicing: The primary expression in the reference\n is evaluated. It should yield a mutable sequence object (such as a\n list). The assigned object should be a sequence object of the same\n type. Next, the lower and upper bound expressions are evaluated,\n insofar they are present; defaults are zero and the sequence\'s\n length. The bounds should evaluate to integers. If either bound is\n negative, the sequence\'s length is added to it. The resulting\n bounds are clipped to lie between zero and the sequence\'s length,\n inclusive. Finally, the sequence object is asked to replace the\n slice with the items of the assigned sequence. The length of the\n slice may be different from the length of the assigned sequence,\n thus changing the length of the target sequence, if the object\n allows it.\n\n**CPython implementation detail:** In the current implementation, the\nsyntax for targets is taken to be the same as for expressions, and\ninvalid syntax is rejected during the code generation phase, causing\nless detailed error messages.\n\nWARNING: Although the definition of assignment implies that overlaps\nbetween the left-hand side and the right-hand side are \'safe\' (for\nexample ``a, b = b, a`` swaps two variables), overlaps *within* the\ncollection of assigned-to variables are not safe! For instance, the\nfollowing program prints ``[0, 2]``:\n\n x = [0, 1]\n i = 0\n i, x[i] = 1, 2\n print(x)\n\nSee also:\n\n **PEP 3132** - Extended Iterable Unpacking\n The specification for the ``*target`` feature.\n\n\nAugmented assignment statements\n===============================\n\nAugmented assignment is the combination, in a single statement, of a\nbinary operation and an assignment statement:\n\n augmented_assignment_stmt ::= augtarget augop (expression_list | yield_expression)\n augtarget ::= identifier | attributeref | subscription | slicing\n augop ::= "+=" | "-=" | "*=" | "/=" | "//=" | "%=" | "**="\n | ">>=" | "<<=" | "&=" | "^=" | "|="\n\n(See section *Primaries* for the syntax definitions for the last three\nsymbols.)\n\nAn augmented assignment evaluates the target (which, unlike normal\nassignment statements, cannot be an unpacking) and the expression\nlist, performs the binary operation specific to the type of assignment\non the two operands, and assigns the result to the original target.\nThe target is only evaluated once.\n\nAn augmented assignment expression like ``x += 1`` can be rewritten as\n``x = x + 1`` to achieve a similar, but not exactly equal effect. In\nthe augmented version, ``x`` is only evaluated once. Also, when\npossible, the actual operation is performed *in-place*, meaning that\nrather than creating a new object and assigning that to the target,\nthe old object is modified instead.\n\nWith the exception of assigning to tuples and multiple targets in a\nsingle statement, the assignment done by augmented assignment\nstatements is handled the same way as normal assignments. Similarly,\nwith the exception of the possible *in-place* behavior, the binary\noperation performed by augmented assignment is the same as the normal\nbinary operations.\n\nFor targets which are attribute references, the same *caveat about\nclass and instance attributes* applies as for regular assignments.\n', - 'atom-identifiers': '\nIdentifiers (Names)\n*******************\n\nAn identifier occurring as an atom is a name. See section\n*Identifiers and keywords* for lexical definition and section *Naming\nand binding* for documentation of naming and binding.\n\nWhen the name is bound to an object, evaluation of the atom yields\nthat object. When a name is not bound, an attempt to evaluate it\nraises a ``NameError`` exception.\n\n**Private name mangling:** When an identifier that textually occurs in\na class definition begins with two or more underscore characters and\ndoes not end in two or more underscores, it is considered a *private\nname* of that class. Private names are transformed to a longer form\nbefore code is generated for them. The transformation inserts the\nclass name, with leading underscores removed and a single underscore\ninserted, in front of the name. For example, the identifier\n``__spam`` occurring in a class named ``Ham`` will be transformed to\n``_Ham__spam``. This transformation is independent of the syntactical\ncontext in which the identifier is used. If the transformed name is\nextremely long (longer than 255 characters), implementation defined\ntruncation may happen. If the class name consists only of underscores,\nno transformation is done.\n', - 'atom-literals': "\nLiterals\n********\n\nPython supports string and bytes literals and various numeric\nliterals:\n\n literal ::= stringliteral | bytesliteral\n | integer | floatnumber | imagnumber\n\nEvaluation of a literal yields an object of the given type (string,\nbytes, integer, floating point number, complex number) with the given\nvalue. The value may be approximated in the case of floating point\nand imaginary (complex) literals. See section *Literals* for details.\n\nAll literals correspond to immutable data types, and hence the\nobject's identity is less important than its value. Multiple\nevaluations of literals with the same value (either the same\noccurrence in the program text or a different occurrence) may obtain\nthe same object or a different object with the same value.\n", - 'attribute-access': '\nCustomizing attribute access\n****************************\n\nThe following methods can be defined to customize the meaning of\nattribute access (use of, assignment to, or deletion of ``x.name``)\nfor class instances.\n\nobject.__getattr__(self, name)\n\n Called when an attribute lookup has not found the attribute in the\n usual places (i.e. it is not an instance attribute nor is it found\n in the class tree for ``self``). ``name`` is the attribute name.\n This method should return the (computed) attribute value or raise\n an ``AttributeError`` exception.\n\n Note that if the attribute is found through the normal mechanism,\n ``__getattr__()`` is not called. (This is an intentional asymmetry\n between ``__getattr__()`` and ``__setattr__()``.) This is done both\n for efficiency reasons and because otherwise ``__getattr__()``\n would have no way to access other attributes of the instance. Note\n that at least for instance variables, you can fake total control by\n not inserting any values in the instance attribute dictionary (but\n instead inserting them in another object). See the\n ``__getattribute__()`` method below for a way to actually get total\n control over attribute access.\n\nobject.__getattribute__(self, name)\n\n Called unconditionally to implement attribute accesses for\n instances of the class. If the class also defines\n ``__getattr__()``, the latter will not be called unless\n ``__getattribute__()`` either calls it explicitly or raises an\n ``AttributeError``. This method should return the (computed)\n attribute value or raise an ``AttributeError`` exception. In order\n to avoid infinite recursion in this method, its implementation\n should always call the base class method with the same name to\n access any attributes it needs, for example,\n ``object.__getattribute__(self, name)``.\n\n Note: This method may still be bypassed when looking up special methods\n as the result of implicit invocation via language syntax or\n built-in functions. See *Special method lookup*.\n\nobject.__setattr__(self, name, value)\n\n Called when an attribute assignment is attempted. This is called\n instead of the normal mechanism (i.e. store the value in the\n instance dictionary). *name* is the attribute name, *value* is the\n value to be assigned to it.\n\n If ``__setattr__()`` wants to assign to an instance attribute, it\n should call the base class method with the same name, for example,\n ``object.__setattr__(self, name, value)``.\n\nobject.__delattr__(self, name)\n\n Like ``__setattr__()`` but for attribute deletion instead of\n assignment. This should only be implemented if ``del obj.name`` is\n meaningful for the object.\n\nobject.__dir__(self)\n\n Called when ``dir()`` is called on the object. A sequence must be\n returned. ``dir()`` converts the returned sequence to a list and\n sorts it.\n\n\nImplementing Descriptors\n========================\n\nThe following methods only apply when an instance of the class\ncontaining the method (a so-called *descriptor* class) appears in an\n*owner* class (the descriptor must be in either the owner\'s class\ndictionary or in the class dictionary for one of its parents). In the\nexamples below, "the attribute" refers to the attribute whose name is\nthe key of the property in the owner class\' ``__dict__``.\n\nobject.__get__(self, instance, owner)\n\n Called to get the attribute of the owner class (class attribute\n access) or of an instance of that class (instance attribute\n access). *owner* is always the owner class, while *instance* is the\n instance that the attribute was accessed through, or ``None`` when\n the attribute is accessed through the *owner*. This method should\n return the (computed) attribute value or raise an\n ``AttributeError`` exception.\n\nobject.__set__(self, instance, value)\n\n Called to set the attribute on an instance *instance* of the owner\n class to a new value, *value*.\n\nobject.__delete__(self, instance)\n\n Called to delete the attribute on an instance *instance* of the\n owner class.\n\n\nInvoking Descriptors\n====================\n\nIn general, a descriptor is an object attribute with "binding\nbehavior", one whose attribute access has been overridden by methods\nin the descriptor protocol: ``__get__()``, ``__set__()``, and\n``__delete__()``. If any of those methods are defined for an object,\nit is said to be a descriptor.\n\nThe default behavior for attribute access is to get, set, or delete\nthe attribute from an object\'s dictionary. For instance, ``a.x`` has a\nlookup chain starting with ``a.__dict__[\'x\']``, then\n``type(a).__dict__[\'x\']``, and continuing through the base classes of\n``type(a)`` excluding metaclasses.\n\nHowever, if the looked-up value is an object defining one of the\ndescriptor methods, then Python may override the default behavior and\ninvoke the descriptor method instead. Where this occurs in the\nprecedence chain depends on which descriptor methods were defined and\nhow they were called.\n\nThe starting point for descriptor invocation is a binding, ``a.x``.\nHow the arguments are assembled depends on ``a``:\n\nDirect Call\n The simplest and least common call is when user code directly\n invokes a descriptor method: ``x.__get__(a)``.\n\nInstance Binding\n If binding to an object instance, ``a.x`` is transformed into the\n call: ``type(a).__dict__[\'x\'].__get__(a, type(a))``.\n\nClass Binding\n If binding to a class, ``A.x`` is transformed into the call:\n ``A.__dict__[\'x\'].__get__(None, A)``.\n\nSuper Binding\n If ``a`` is an instance of ``super``, then the binding ``super(B,\n obj).m()`` searches ``obj.__class__.__mro__`` for the base class\n ``A`` immediately preceding ``B`` and then invokes the descriptor\n with the call: ``A.__dict__[\'m\'].__get__(obj, obj.__class__)``.\n\nFor instance bindings, the precedence of descriptor invocation depends\non the which descriptor methods are defined. A descriptor can define\nany combination of ``__get__()``, ``__set__()`` and ``__delete__()``.\nIf it does not define ``__get__()``, then accessing the attribute will\nreturn the descriptor object itself unless there is a value in the\nobject\'s instance dictionary. If the descriptor defines ``__set__()``\nand/or ``__delete__()``, it is a data descriptor; if it defines\nneither, it is a non-data descriptor. Normally, data descriptors\ndefine both ``__get__()`` and ``__set__()``, while non-data\ndescriptors have just the ``__get__()`` method. Data descriptors with\n``__set__()`` and ``__get__()`` defined always override a redefinition\nin an instance dictionary. In contrast, non-data descriptors can be\noverridden by instances.\n\nPython methods (including ``staticmethod()`` and ``classmethod()``)\nare implemented as non-data descriptors. Accordingly, instances can\nredefine and override methods. This allows individual instances to\nacquire behaviors that differ from other instances of the same class.\n\nThe ``property()`` function is implemented as a data descriptor.\nAccordingly, instances cannot override the behavior of a property.\n\n\n__slots__\n=========\n\nBy default, instances of classes have a dictionary for attribute\nstorage. This wastes space for objects having very few instance\nvariables. The space consumption can become acute when creating large\nnumbers of instances.\n\nThe default can be overridden by defining *__slots__* in a class\ndefinition. The *__slots__* declaration takes a sequence of instance\nvariables and reserves just enough space in each instance to hold a\nvalue for each variable. Space is saved because *__dict__* is not\ncreated for each instance.\n\nobject.__slots__\n\n This class variable can be assigned a string, iterable, or sequence\n of strings with variable names used by instances. If defined in a\n class, *__slots__* reserves space for the declared variables and\n prevents the automatic creation of *__dict__* and *__weakref__* for\n each instance.\n\n\nNotes on using *__slots__*\n--------------------------\n\n* When inheriting from a class without *__slots__*, the *__dict__*\n attribute of that class will always be accessible, so a *__slots__*\n definition in the subclass is meaningless.\n\n* Without a *__dict__* variable, instances cannot be assigned new\n variables not listed in the *__slots__* definition. Attempts to\n assign to an unlisted variable name raises ``AttributeError``. If\n dynamic assignment of new variables is desired, then add\n ``\'__dict__\'`` to the sequence of strings in the *__slots__*\n declaration.\n\n* Without a *__weakref__* variable for each instance, classes defining\n *__slots__* do not support weak references to its instances. If weak\n reference support is needed, then add ``\'__weakref__\'`` to the\n sequence of strings in the *__slots__* declaration.\n\n* *__slots__* are implemented at the class level by creating\n descriptors (*Implementing Descriptors*) for each variable name. As\n a result, class attributes cannot be used to set default values for\n instance variables defined by *__slots__*; otherwise, the class\n attribute would overwrite the descriptor assignment.\n\n* The action of a *__slots__* declaration is limited to the class\n where it is defined. As a result, subclasses will have a *__dict__*\n unless they also define *__slots__* (which must only contain names\n of any *additional* slots).\n\n* If a class defines a slot also defined in a base class, the instance\n variable defined by the base class slot is inaccessible (except by\n retrieving its descriptor directly from the base class). This\n renders the meaning of the program undefined. In the future, a\n check may be added to prevent this.\n\n* Nonempty *__slots__* does not work for classes derived from\n "variable-length" built-in types such as ``int``, ``str`` and\n ``tuple``.\n\n* Any non-string iterable may be assigned to *__slots__*. Mappings may\n also be used; however, in the future, special meaning may be\n assigned to the values corresponding to each key.\n\n* *__class__* assignment works only if both classes have the same\n *__slots__*.\n', - 'attribute-references': '\nAttribute references\n********************\n\nAn attribute reference is a primary followed by a period and a name:\n\n attributeref ::= primary "." identifier\n\nThe primary must evaluate to an object of a type that supports\nattribute references, which most objects do. This object is then\nasked to produce the attribute whose name is the identifier (which can\nbe customized by overriding the ``__getattr__()`` method). If this\nattribute is not available, the exception ``AttributeError`` is\nraised. Otherwise, the type and value of the object produced is\ndetermined by the object. Multiple evaluations of the same attribute\nreference may yield different objects.\n', - 'augassign': '\nAugmented assignment statements\n*******************************\n\nAugmented assignment is the combination, in a single statement, of a\nbinary operation and an assignment statement:\n\n augmented_assignment_stmt ::= augtarget augop (expression_list | yield_expression)\n augtarget ::= identifier | attributeref | subscription | slicing\n augop ::= "+=" | "-=" | "*=" | "/=" | "//=" | "%=" | "**="\n | ">>=" | "<<=" | "&=" | "^=" | "|="\n\n(See section *Primaries* for the syntax definitions for the last three\nsymbols.)\n\nAn augmented assignment evaluates the target (which, unlike normal\nassignment statements, cannot be an unpacking) and the expression\nlist, performs the binary operation specific to the type of assignment\non the two operands, and assigns the result to the original target.\nThe target is only evaluated once.\n\nAn augmented assignment expression like ``x += 1`` can be rewritten as\n``x = x + 1`` to achieve a similar, but not exactly equal effect. In\nthe augmented version, ``x`` is only evaluated once. Also, when\npossible, the actual operation is performed *in-place*, meaning that\nrather than creating a new object and assigning that to the target,\nthe old object is modified instead.\n\nWith the exception of assigning to tuples and multiple targets in a\nsingle statement, the assignment done by augmented assignment\nstatements is handled the same way as normal assignments. Similarly,\nwith the exception of the possible *in-place* behavior, the binary\noperation performed by augmented assignment is the same as the normal\nbinary operations.\n\nFor targets which are attribute references, the same *caveat about\nclass and instance attributes* applies as for regular assignments.\n', - 'binary': '\nBinary arithmetic operations\n****************************\n\nThe binary arithmetic operations have the conventional priority\nlevels. Note that some of these operations also apply to certain non-\nnumeric types. Apart from the power operator, there are only two\nlevels, one for multiplicative operators and one for additive\noperators:\n\n m_expr ::= u_expr | m_expr "*" u_expr | m_expr "//" u_expr | m_expr "/" u_expr\n | m_expr "%" u_expr\n a_expr ::= m_expr | a_expr "+" m_expr | a_expr "-" m_expr\n\nThe ``*`` (multiplication) operator yields the product of its\narguments. The arguments must either both be numbers, or one argument\nmust be an integer and the other must be a sequence. In the former\ncase, the numbers are converted to a common type and then multiplied\ntogether. In the latter case, sequence repetition is performed; a\nnegative repetition factor yields an empty sequence.\n\nThe ``/`` (division) and ``//`` (floor division) operators yield the\nquotient of their arguments. The numeric arguments are first\nconverted to a common type. Division of integers yields a float, while\nfloor division of integers results in an integer; the result is that\nof mathematical division with the \'floor\' function applied to the\nresult. Division by zero raises the ``ZeroDivisionError`` exception.\n\nThe ``%`` (modulo) operator yields the remainder from the division of\nthe first argument by the second. The numeric arguments are first\nconverted to a common type. A zero right argument raises the\n``ZeroDivisionError`` exception. The arguments may be floating point\nnumbers, e.g., ``3.14%0.7`` equals ``0.34`` (since ``3.14`` equals\n``4*0.7 + 0.34``.) The modulo operator always yields a result with\nthe same sign as its second operand (or zero); the absolute value of\nthe result is strictly smaller than the absolute value of the second\noperand [1].\n\nThe floor division and modulo operators are connected by the following\nidentity: ``x == (x//y)*y + (x%y)``. Floor division and modulo are\nalso connected with the built-in function ``divmod()``: ``divmod(x, y)\n== (x//y, x%y)``. [2].\n\nIn addition to performing the modulo operation on numbers, the ``%``\noperator is also overloaded by string objects to perform old-style\nstring formatting (also known as interpolation). The syntax for\nstring formatting is described in the Python Library Reference,\nsection *printf-style String Formatting*.\n\nThe floor division operator, the modulo operator, and the ``divmod()``\nfunction are not defined for complex numbers. Instead, convert to a\nfloating point number using the ``abs()`` function if appropriate.\n\nThe ``+`` (addition) operator yields the sum of its arguments. The\narguments must either both be numbers or both sequences of the same\ntype. In the former case, the numbers are converted to a common type\nand then added together. In the latter case, the sequences are\nconcatenated.\n\nThe ``-`` (subtraction) operator yields the difference of its\narguments. The numeric arguments are first converted to a common\ntype.\n', - 'bitwise': '\nBinary bitwise operations\n*************************\n\nEach of the three bitwise operations has a different priority level:\n\n and_expr ::= shift_expr | and_expr "&" shift_expr\n xor_expr ::= and_expr | xor_expr "^" and_expr\n or_expr ::= xor_expr | or_expr "|" xor_expr\n\nThe ``&`` operator yields the bitwise AND of its arguments, which must\nbe integers.\n\nThe ``^`` operator yields the bitwise XOR (exclusive OR) of its\narguments, which must be integers.\n\nThe ``|`` operator yields the bitwise (inclusive) OR of its arguments,\nwhich must be integers.\n', - 'bltin-code-objects': '\nCode Objects\n************\n\nCode objects are used by the implementation to represent "pseudo-\ncompiled" executable Python code such as a function body. They differ\nfrom function objects because they don\'t contain a reference to their\nglobal execution environment. Code objects are returned by the built-\nin ``compile()`` function and can be extracted from function objects\nthrough their ``__code__`` attribute. See also the ``code`` module.\n\nA code object can be executed or evaluated by passing it (instead of a\nsource string) to the ``exec()`` or ``eval()`` built-in functions.\n\nSee *The standard type hierarchy* for more information.\n', - 'bltin-ellipsis-object': '\nThe Ellipsis Object\n*******************\n\nThis object is commonly used by slicing (see *Slicings*). It supports\nno special operations. There is exactly one ellipsis object, named\n``Ellipsis`` (a built-in name). ``type(Ellipsis)()`` produces the\n``Ellipsis`` singleton.\n\nIt is written as ``Ellipsis`` or ``...``.\n', - 'bltin-null-object': "\nThe Null Object\n***************\n\nThis object is returned by functions that don't explicitly return a\nvalue. It supports no special operations. There is exactly one null\nobject, named ``None`` (a built-in name). ``type(None)()`` produces\nthe same singleton.\n\nIt is written as ``None``.\n", - 'bltin-type-objects': "\nType Objects\n************\n\nType objects represent the various object types. An object's type is\naccessed by the built-in function ``type()``. There are no special\noperations on types. The standard module ``types`` defines names for\nall standard built-in types.\n\nTypes are written like this: ``<class 'int'>``.\n", - 'booleans': '\nBoolean operations\n******************\n\n or_test ::= and_test | or_test "or" and_test\n and_test ::= not_test | and_test "and" not_test\n not_test ::= comparison | "not" not_test\n\nIn the context of Boolean operations, and also when expressions are\nused by control flow statements, the following values are interpreted\nas false: ``False``, ``None``, numeric zero of all types, and empty\nstrings and containers (including strings, tuples, lists,\ndictionaries, sets and frozensets). All other values are interpreted\nas true. User-defined objects can customize their truth value by\nproviding a ``__bool__()`` method.\n\nThe operator ``not`` yields ``True`` if its argument is false,\n``False`` otherwise.\n\nThe expression ``x and y`` first evaluates *x*; if *x* is false, its\nvalue is returned; otherwise, *y* is evaluated and the resulting value\nis returned.\n\nThe expression ``x or y`` first evaluates *x*; if *x* is true, its\nvalue is returned; otherwise, *y* is evaluated and the resulting value\nis returned.\n\n(Note that neither ``and`` nor ``or`` restrict the value and type they\nreturn to ``False`` and ``True``, but rather return the last evaluated\nargument. This is sometimes useful, e.g., if ``s`` is a string that\nshould be replaced by a default value if it is empty, the expression\n``s or \'foo\'`` yields the desired value. Because ``not`` has to\ninvent a value anyway, it does not bother to return a value of the\nsame type as its argument, so e.g., ``not \'foo\'`` yields ``False``,\nnot ``\'\'``.)\n', - 'break': '\nThe ``break`` statement\n***********************\n\n break_stmt ::= "break"\n\n``break`` may only occur syntactically nested in a ``for`` or\n``while`` loop, but not nested in a function or class definition\nwithin that loop.\n\nIt terminates the nearest enclosing loop, skipping the optional\n``else`` clause if the loop has one.\n\nIf a ``for`` loop is terminated by ``break``, the loop control target\nkeeps its current value.\n\nWhen ``break`` passes control out of a ``try`` statement with a\n``finally`` clause, that ``finally`` clause is executed before really\nleaving the loop.\n', - 'callable-types': '\nEmulating callable objects\n**************************\n\nobject.__call__(self[, args...])\n\n Called when the instance is "called" as a function; if this method\n is defined, ``x(arg1, arg2, ...)`` is a shorthand for\n ``x.__call__(arg1, arg2, ...)``.\n', - 'calls': '\nCalls\n*****\n\nA call calls a callable object (e.g., a *function*) with a possibly\nempty series of *arguments*:\n\n call ::= primary "(" [argument_list [","] | comprehension] ")"\n argument_list ::= positional_arguments ["," keyword_arguments]\n ["," "*" expression] ["," keyword_arguments]\n ["," "**" expression]\n | keyword_arguments ["," "*" expression]\n ["," keyword_arguments] ["," "**" expression]\n | "*" expression ["," keyword_arguments] ["," "**" expression]\n | "**" expression\n positional_arguments ::= expression ("," expression)*\n keyword_arguments ::= keyword_item ("," keyword_item)*\n keyword_item ::= identifier "=" expression\n\nA trailing comma may be present after the positional and keyword\narguments but does not affect the semantics.\n\nThe primary must evaluate to a callable object (user-defined\nfunctions, built-in functions, methods of built-in objects, class\nobjects, methods of class instances, and all objects having a\n``__call__()`` method are callable). All argument expressions are\nevaluated before the call is attempted. Please refer to section\n*Function definitions* for the syntax of formal *parameter* lists.\n\nIf keyword arguments are present, they are first converted to\npositional arguments, as follows. First, a list of unfilled slots is\ncreated for the formal parameters. If there are N positional\narguments, they are placed in the first N slots. Next, for each\nkeyword argument, the identifier is used to determine the\ncorresponding slot (if the identifier is the same as the first formal\nparameter name, the first slot is used, and so on). If the slot is\nalready filled, a ``TypeError`` exception is raised. Otherwise, the\nvalue of the argument is placed in the slot, filling it (even if the\nexpression is ``None``, it fills the slot). When all arguments have\nbeen processed, the slots that are still unfilled are filled with the\ncorresponding default value from the function definition. (Default\nvalues are calculated, once, when the function is defined; thus, a\nmutable object such as a list or dictionary used as default value will\nbe shared by all calls that don\'t specify an argument value for the\ncorresponding slot; this should usually be avoided.) If there are any\nunfilled slots for which no default value is specified, a\n``TypeError`` exception is raised. Otherwise, the list of filled\nslots is used as the argument list for the call.\n\n**CPython implementation detail:** An implementation may provide\nbuilt-in functions whose positional parameters do not have names, even\nif they are \'named\' for the purpose of documentation, and which\ntherefore cannot be supplied by keyword. In CPython, this is the case\nfor functions implemented in C that use ``PyArg_ParseTuple()`` to\nparse their arguments.\n\nIf there are more positional arguments than there are formal parameter\nslots, a ``TypeError`` exception is raised, unless a formal parameter\nusing the syntax ``*identifier`` is present; in this case, that formal\nparameter receives a tuple containing the excess positional arguments\n(or an empty tuple if there were no excess positional arguments).\n\nIf any keyword argument does not correspond to a formal parameter\nname, a ``TypeError`` exception is raised, unless a formal parameter\nusing the syntax ``**identifier`` is present; in this case, that\nformal parameter receives a dictionary containing the excess keyword\narguments (using the keywords as keys and the argument values as\ncorresponding values), or a (new) empty dictionary if there were no\nexcess keyword arguments.\n\nIf the syntax ``*expression`` appears in the function call,\n``expression`` must evaluate to an iterable. Elements from this\niterable are treated as if they were additional positional arguments;\nif there are positional arguments *x1*, ..., *xN*, and ``expression``\nevaluates to a sequence *y1*, ..., *yM*, this is equivalent to a call\nwith M+N positional arguments *x1*, ..., *xN*, *y1*, ..., *yM*.\n\nA consequence of this is that although the ``*expression`` syntax may\nappear *after* some keyword arguments, it is processed *before* the\nkeyword arguments (and the ``**expression`` argument, if any -- see\nbelow). So:\n\n >>> def f(a, b):\n ... print(a, b)\n ...\n >>> f(b=1, *(2,))\n 2 1\n >>> f(a=1, *(2,))\n Traceback (most recent call last):\n File "<stdin>", line 1, in ?\n TypeError: f() got multiple values for keyword argument \'a\'\n >>> f(1, *(2,))\n 1 2\n\nIt is unusual for both keyword arguments and the ``*expression``\nsyntax to be used in the same call, so in practice this confusion does\nnot arise.\n\nIf the syntax ``**expression`` appears in the function call,\n``expression`` must evaluate to a mapping, the contents of which are\ntreated as additional keyword arguments. In the case of a keyword\nappearing in both ``expression`` and as an explicit keyword argument,\na ``TypeError`` exception is raised.\n\nFormal parameters using the syntax ``*identifier`` or ``**identifier``\ncannot be used as positional argument slots or as keyword argument\nnames.\n\nA call always returns some value, possibly ``None``, unless it raises\nan exception. How this value is computed depends on the type of the\ncallable object.\n\nIf it is---\n\na user-defined function:\n The code block for the function is executed, passing it the\n argument list. The first thing the code block will do is bind the\n formal parameters to the arguments; this is described in section\n *Function definitions*. When the code block executes a ``return``\n statement, this specifies the return value of the function call.\n\na built-in function or method:\n The result is up to the interpreter; see *Built-in Functions* for\n the descriptions of built-in functions and methods.\n\na class object:\n A new instance of that class is returned.\n\na class instance method:\n The corresponding user-defined function is called, with an argument\n list that is one longer than the argument list of the call: the\n instance becomes the first argument.\n\na class instance:\n The class must define a ``__call__()`` method; the effect is then\n the same as if that method was called.\n', - 'class': '\nClass definitions\n*****************\n\nA class definition defines a class object (see section *The standard\ntype hierarchy*):\n\n classdef ::= [decorators] "class" classname [inheritance] ":" suite\n inheritance ::= "(" [parameter_list] ")"\n classname ::= identifier\n\nA class definition is an executable statement. The inheritance list\nusually gives a list of base classes (see *Customizing class creation*\nfor more advanced uses), so each item in the list should evaluate to a\nclass object which allows subclassing. Classes without an inheritance\nlist inherit, by default, from the base class ``object``; hence,\n\n class Foo:\n pass\n\nis equivalent to\n\n class Foo(object):\n pass\n\nThe class\'s suite is then executed in a new execution frame (see\n*Naming and binding*), using a newly created local namespace and the\noriginal global namespace. (Usually, the suite contains mostly\nfunction definitions.) When the class\'s suite finishes execution, its\nexecution frame is discarded but its local namespace is saved. [4] A\nclass object is then created using the inheritance list for the base\nclasses and the saved local namespace for the attribute dictionary.\nThe class name is bound to this class object in the original local\nnamespace.\n\nClass creation can be customized heavily using *metaclasses*.\n\nClasses can also be decorated: just like when decorating functions,\n\n @f1(arg)\n @f2\n class Foo: pass\n\nis equivalent to\n\n class Foo: pass\n Foo = f1(arg)(f2(Foo))\n\nThe evaluation rules for the decorator expressions are the same as for\nfunction decorators. The result must be a class object, which is then\nbound to the class name.\n\n**Programmer\'s note:** Variables defined in the class definition are\nclass attributes; they are shared by instances. Instance attributes\ncan be set in a method with ``self.name = value``. Both class and\ninstance attributes are accessible through the notation\n"``self.name``", and an instance attribute hides a class attribute\nwith the same name when accessed in this way. Class attributes can be\nused as defaults for instance attributes, but using mutable values\nthere can lead to unexpected results. *Descriptors* can be used to\ncreate instance variables with different implementation details.\n\nSee also:\n\n **PEP 3115** - Metaclasses in Python 3 **PEP 3129** - Class\n Decorators\n\n-[ Footnotes ]-\n\n[1] The exception is propagated to the invocation stack unless there\n is a ``finally`` clause which happens to raise another exception.\n That new exception causes the old one to be lost.\n\n[2] Currently, control "flows off the end" except in the case of an\n exception or the execution of a ``return``, ``continue``, or\n ``break`` statement.\n\n[3] A string literal appearing as the first statement in the function\n body is transformed into the function\'s ``__doc__`` attribute and\n therefore the function\'s *docstring*.\n\n[4] A string literal appearing as the first statement in the class\n body is transformed into the namespace\'s ``__doc__`` item and\n therefore the class\'s *docstring*.\n', - 'comparisons': '\nComparisons\n***********\n\nUnlike C, all comparison operations in Python have the same priority,\nwhich is lower than that of any arithmetic, shifting or bitwise\noperation. Also unlike C, expressions like ``a < b < c`` have the\ninterpretation that is conventional in mathematics:\n\n comparison ::= or_expr ( comp_operator or_expr )*\n comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "!="\n | "is" ["not"] | ["not"] "in"\n\nComparisons yield boolean values: ``True`` or ``False``.\n\nComparisons can be chained arbitrarily, e.g., ``x < y <= z`` is\nequivalent to ``x < y and y <= z``, except that ``y`` is evaluated\nonly once (but in both cases ``z`` is not evaluated at all when ``x <\ny`` is found to be false).\n\nFormally, if *a*, *b*, *c*, ..., *y*, *z* are expressions and *op1*,\n*op2*, ..., *opN* are comparison operators, then ``a op1 b op2 c ... y\nopN z`` is equivalent to ``a op1 b and b op2 c and ... y opN z``,\nexcept that each expression is evaluated at most once.\n\nNote that ``a op1 b op2 c`` doesn\'t imply any kind of comparison\nbetween *a* and *c*, so that, e.g., ``x < y > z`` is perfectly legal\n(though perhaps not pretty).\n\nThe operators ``<``, ``>``, ``==``, ``>=``, ``<=``, and ``!=`` compare\nthe values of two objects. The objects need not have the same type.\nIf both are numbers, they are converted to a common type. Otherwise,\nthe ``==`` and ``!=`` operators *always* consider objects of different\ntypes to be unequal, while the ``<``, ``>``, ``>=`` and ``<=``\noperators raise a ``TypeError`` when comparing objects of different\ntypes that do not implement these operators for the given pair of\ntypes. You can control comparison behavior of objects of non-built-in\ntypes by defining rich comparison methods like ``__gt__()``, described\nin section *Basic customization*.\n\nComparison of objects of the same type depends on the type:\n\n* Numbers are compared arithmetically.\n\n* The values ``float(\'NaN\')`` and ``Decimal(\'NaN\')`` are special. The\n are identical to themselves, ``x is x`` but are not equal to\n themselves, ``x != x``. Additionally, comparing any value to a\n not-a-number value will return ``False``. For example, both ``3 <\n float(\'NaN\')`` and ``float(\'NaN\') < 3`` will return ``False``.\n\n* Bytes objects are compared lexicographically using the numeric\n values of their elements.\n\n* Strings are compared lexicographically using the numeric equivalents\n (the result of the built-in function ``ord()``) of their characters.\n [3] String and bytes object can\'t be compared!\n\n* Tuples and lists are compared lexicographically using comparison of\n corresponding elements. This means that to compare equal, each\n element must compare equal and the two sequences must be of the same\n type and have the same length.\n\n If not equal, the sequences are ordered the same as their first\n differing elements. For example, ``[1,2,x] <= [1,2,y]`` has the\n same value as ``x <= y``. If the corresponding element does not\n exist, the shorter sequence is ordered first (for example, ``[1,2] <\n [1,2,3]``).\n\n* Mappings (dictionaries) compare equal if and only if they have the\n same ``(key, value)`` pairs. Order comparisons ``(\'<\', \'<=\', \'>=\',\n \'>\')`` raise ``TypeError``.\n\n* Sets and frozensets define comparison operators to mean subset and\n superset tests. Those relations do not define total orderings (the\n two sets ``{1,2}`` and {2,3} are not equal, nor subsets of one\n another, nor supersets of one another). Accordingly, sets are not\n appropriate arguments for functions which depend on total ordering.\n For example, ``min()``, ``max()``, and ``sorted()`` produce\n undefined results given a list of sets as inputs.\n\n* Most other objects of built-in types compare unequal unless they are\n the same object; the choice whether one object is considered smaller\n or larger than another one is made arbitrarily but consistently\n within one execution of a program.\n\nComparison of objects of the differing types depends on whether either\nof the types provide explicit support for the comparison. Most\nnumeric types can be compared with one another. When cross-type\ncomparison is not supported, the comparison method returns\n``NotImplemented``.\n\nThe operators ``in`` and ``not in`` test for membership. ``x in s``\nevaluates to true if *x* is a member of *s*, and false otherwise. ``x\nnot in s`` returns the negation of ``x in s``. All built-in sequences\nand set types support this as well as dictionary, for which ``in``\ntests whether a the dictionary has a given key. For container types\nsuch as list, tuple, set, frozenset, dict, or collections.deque, the\nexpression ``x in y`` is equivalent to ``any(x is e or x == e for e in\ny)``.\n\nFor the string and bytes types, ``x in y`` is true if and only if *x*\nis a substring of *y*. An equivalent test is ``y.find(x) != -1``.\nEmpty strings are always considered to be a substring of any other\nstring, so ``"" in "abc"`` will return ``True``.\n\nFor user-defined classes which define the ``__contains__()`` method,\n``x in y`` is true if and only if ``y.__contains__(x)`` is true.\n\nFor user-defined classes which do not define ``__contains__()`` but do\ndefine ``__iter__()``, ``x in y`` is true if some value ``z`` with ``x\n== z`` is produced while iterating over ``y``. If an exception is\nraised during the iteration, it is as if ``in`` raised that exception.\n\nLastly, the old-style iteration protocol is tried: if a class defines\n``__getitem__()``, ``x in y`` is true if and only if there is a non-\nnegative integer index *i* such that ``x == y[i]``, and all lower\ninteger indices do not raise ``IndexError`` exception. (If any other\nexception is raised, it is as if ``in`` raised that exception).\n\nThe operator ``not in`` is defined to have the inverse true value of\n``in``.\n\nThe operators ``is`` and ``is not`` test for object identity: ``x is\ny`` is true if and only if *x* and *y* are the same object. ``x is\nnot y`` yields the inverse truth value. [4]\n', - 'compound': '\nCompound statements\n*******************\n\nCompound statements contain (groups of) other statements; they affect\nor control the execution of those other statements in some way. In\ngeneral, compound statements span multiple lines, although in simple\nincarnations a whole compound statement may be contained in one line.\n\nThe ``if``, ``while`` and ``for`` statements implement traditional\ncontrol flow constructs. ``try`` specifies exception handlers and/or\ncleanup code for a group of statements, while the ``with`` statement\nallows the execution of initialization and finalization code around a\nblock of code. Function and class definitions are also syntactically\ncompound statements.\n\nCompound statements consist of one or more \'clauses.\' A clause\nconsists of a header and a \'suite.\' The clause headers of a\nparticular compound statement are all at the same indentation level.\nEach clause header begins with a uniquely identifying keyword and ends\nwith a colon. A suite is a group of statements controlled by a\nclause. A suite can be one or more semicolon-separated simple\nstatements on the same line as the header, following the header\'s\ncolon, or it can be one or more indented statements on subsequent\nlines. Only the latter form of suite can contain nested compound\nstatements; the following is illegal, mostly because it wouldn\'t be\nclear to which ``if`` clause a following ``else`` clause would belong:\n\n if test1: if test2: print(x)\n\nAlso note that the semicolon binds tighter than the colon in this\ncontext, so that in the following example, either all or none of the\n``print()`` calls are executed:\n\n if x < y < z: print(x); print(y); print(z)\n\nSummarizing:\n\n compound_stmt ::= if_stmt\n | while_stmt\n | for_stmt\n | try_stmt\n | with_stmt\n | funcdef\n | classdef\n suite ::= stmt_list NEWLINE | NEWLINE INDENT statement+ DEDENT\n statement ::= stmt_list NEWLINE | compound_stmt\n stmt_list ::= simple_stmt (";" simple_stmt)* [";"]\n\nNote that statements always end in a ``NEWLINE`` possibly followed by\na ``DEDENT``. Also note that optional continuation clauses always\nbegin with a keyword that cannot start a statement, thus there are no\nambiguities (the \'dangling ``else``\' problem is solved in Python by\nrequiring nested ``if`` statements to be indented).\n\nThe formatting of the grammar rules in the following sections places\neach clause on a separate line for clarity.\n\n\nThe ``if`` statement\n====================\n\nThe ``if`` statement is used for conditional execution:\n\n if_stmt ::= "if" expression ":" suite\n ( "elif" expression ":" suite )*\n ["else" ":" suite]\n\nIt selects exactly one of the suites by evaluating the expressions one\nby one until one is found to be true (see section *Boolean operations*\nfor the definition of true and false); then that suite is executed\n(and no other part of the ``if`` statement is executed or evaluated).\nIf all expressions are false, the suite of the ``else`` clause, if\npresent, is executed.\n\n\nThe ``while`` statement\n=======================\n\nThe ``while`` statement is used for repeated execution as long as an\nexpression is true:\n\n while_stmt ::= "while" expression ":" suite\n ["else" ":" suite]\n\nThis repeatedly tests the expression and, if it is true, executes the\nfirst suite; if the expression is false (which may be the first time\nit is tested) the suite of the ``else`` clause, if present, is\nexecuted and the loop terminates.\n\nA ``break`` statement executed in the first suite terminates the loop\nwithout executing the ``else`` clause\'s suite. A ``continue``\nstatement executed in the first suite skips the rest of the suite and\ngoes back to testing the expression.\n\n\nThe ``for`` statement\n=====================\n\nThe ``for`` statement is used to iterate over the elements of a\nsequence (such as a string, tuple or list) or other iterable object:\n\n for_stmt ::= "for" target_list "in" expression_list ":" suite\n ["else" ":" suite]\n\nThe expression list is evaluated once; it should yield an iterable\nobject. An iterator is created for the result of the\n``expression_list``. The suite is then executed once for each item\nprovided by the iterator, in the order of ascending indices. Each\nitem in turn is assigned to the target list using the standard rules\nfor assignments (see *Assignment statements*), and then the suite is\nexecuted. When the items are exhausted (which is immediately when the\nsequence is empty or an iterator raises a ``StopIteration``\nexception), the suite in the ``else`` clause, if present, is executed,\nand the loop terminates.\n\nA ``break`` statement executed in the first suite terminates the loop\nwithout executing the ``else`` clause\'s suite. A ``continue``\nstatement executed in the first suite skips the rest of the suite and\ncontinues with the next item, or with the ``else`` clause if there was\nno next item.\n\nThe suite may assign to the variable(s) in the target list; this does\nnot affect the next item assigned to it.\n\nNames in the target list are not deleted when the loop is finished,\nbut if the sequence is empty, it will not have been assigned to at all\nby the loop. Hint: the built-in function ``range()`` returns an\niterator of integers suitable to emulate the effect of Pascal\'s ``for\ni := a to b do``; e.g., ``list(range(3))`` returns the list ``[0, 1,\n2]``.\n\nNote: There is a subtlety when the sequence is being modified by the loop\n (this can only occur for mutable sequences, i.e. lists). An\n internal counter is used to keep track of which item is used next,\n and this is incremented on each iteration. When this counter has\n reached the length of the sequence the loop terminates. This means\n that if the suite deletes the current (or a previous) item from the\n sequence, the next item will be skipped (since it gets the index of\n the current item which has already been treated). Likewise, if the\n suite inserts an item in the sequence before the current item, the\n current item will be treated again the next time through the loop.\n This can lead to nasty bugs that can be avoided by making a\n temporary copy using a slice of the whole sequence, e.g.,\n\n for x in a[:]:\n if x < 0: a.remove(x)\n\n\nThe ``try`` statement\n=====================\n\nThe ``try`` statement specifies exception handlers and/or cleanup code\nfor a group of statements:\n\n try_stmt ::= try1_stmt | try2_stmt\n try1_stmt ::= "try" ":" suite\n ("except" [expression ["as" target]] ":" suite)+\n ["else" ":" suite]\n ["finally" ":" suite]\n try2_stmt ::= "try" ":" suite\n "finally" ":" suite\n\nThe ``except`` clause(s) specify one or more exception handlers. When\nno exception occurs in the ``try`` clause, no exception handler is\nexecuted. When an exception occurs in the ``try`` suite, a search for\nan exception handler is started. This search inspects the except\nclauses in turn until one is found that matches the exception. An\nexpression-less except clause, if present, must be last; it matches\nany exception. For an except clause with an expression, that\nexpression is evaluated, and the clause matches the exception if the\nresulting object is "compatible" with the exception. An object is\ncompatible with an exception if it is the class or a base class of the\nexception object or a tuple containing an item compatible with the\nexception.\n\nIf no except clause matches the exception, the search for an exception\nhandler continues in the surrounding code and on the invocation stack.\n[1]\n\nIf the evaluation of an expression in the header of an except clause\nraises an exception, the original search for a handler is canceled and\na search starts for the new exception in the surrounding code and on\nthe call stack (it is treated as if the entire ``try`` statement\nraised the exception).\n\nWhen a matching except clause is found, the exception is assigned to\nthe target specified after the ``as`` keyword in that except clause,\nif present, and the except clause\'s suite is executed. All except\nclauses must have an executable block. When the end of this block is\nreached, execution continues normally after the entire try statement.\n(This means that if two nested handlers exist for the same exception,\nand the exception occurs in the try clause of the inner handler, the\nouter handler will not handle the exception.)\n\nWhen an exception has been assigned using ``as target``, it is cleared\nat the end of the except clause. This is as if\n\n except E as N:\n foo\n\nwas translated to\n\n except E as N:\n try:\n foo\n finally:\n del N\n\nThis means the exception must be assigned to a different name to be\nable to refer to it after the except clause. Exceptions are cleared\nbecause with the traceback attached to them, they form a reference\ncycle with the stack frame, keeping all locals in that frame alive\nuntil the next garbage collection occurs.\n\nBefore an except clause\'s suite is executed, details about the\nexception are stored in the ``sys`` module and can be access via\n``sys.exc_info()``. ``sys.exc_info()`` returns a 3-tuple consisting of\nthe exception class, the exception instance and a traceback object\n(see section *The standard type hierarchy*) identifying the point in\nthe program where the exception occurred. ``sys.exc_info()`` values\nare restored to their previous values (before the call) when returning\nfrom a function that handled an exception.\n\nThe optional ``else`` clause is executed if and when control flows off\nthe end of the ``try`` clause. [2] Exceptions in the ``else`` clause\nare not handled by the preceding ``except`` clauses.\n\nIf ``finally`` is present, it specifies a \'cleanup\' handler. The\n``try`` clause is executed, including any ``except`` and ``else``\nclauses. If an exception occurs in any of the clauses and is not\nhandled, the exception is temporarily saved. The ``finally`` clause is\nexecuted. If there is a saved exception it is re-raised at the end of\nthe ``finally`` clause. If the ``finally`` clause raises another\nexception, the saved exception is set as the context of the new\nexception. If the ``finally`` clause executes a ``return`` or\n``break`` statement, the saved exception is discarded:\n\n def f():\n try:\n 1/0\n finally:\n return 42\n\n >>> f()\n 42\n\nThe exception information is not available to the program during\nexecution of the ``finally`` clause.\n\nWhen a ``return``, ``break`` or ``continue`` statement is executed in\nthe ``try`` suite of a ``try``...``finally`` statement, the\n``finally`` clause is also executed \'on the way out.\' A ``continue``\nstatement is illegal in the ``finally`` clause. (The reason is a\nproblem with the current implementation --- this restriction may be\nlifted in the future).\n\nAdditional information on exceptions can be found in section\n*Exceptions*, and information on using the ``raise`` statement to\ngenerate exceptions may be found in section *The raise statement*.\n\n\nThe ``with`` statement\n======================\n\nThe ``with`` statement is used to wrap the execution of a block with\nmethods defined by a context manager (see section *With Statement\nContext Managers*). This allows common\n``try``...``except``...``finally`` usage patterns to be encapsulated\nfor convenient reuse.\n\n with_stmt ::= "with" with_item ("," with_item)* ":" suite\n with_item ::= expression ["as" target]\n\nThe execution of the ``with`` statement with one "item" proceeds as\nfollows:\n\n1. The context expression (the expression given in the ``with_item``)\n is evaluated to obtain a context manager.\n\n2. The context manager\'s ``__exit__()`` is loaded for later use.\n\n3. The context manager\'s ``__enter__()`` method is invoked.\n\n4. If a target was included in the ``with`` statement, the return\n value from ``__enter__()`` is assigned to it.\n\n Note: The ``with`` statement guarantees that if the ``__enter__()``\n method returns without an error, then ``__exit__()`` will always\n be called. Thus, if an error occurs during the assignment to the\n target list, it will be treated the same as an error occurring\n within the suite would be. See step 6 below.\n\n5. The suite is executed.\n\n6. The context manager\'s ``__exit__()`` method is invoked. If an\n exception caused the suite to be exited, its type, value, and\n traceback are passed as arguments to ``__exit__()``. Otherwise,\n three ``None`` arguments are supplied.\n\n If the suite was exited due to an exception, and the return value\n from the ``__exit__()`` method was false, the exception is\n reraised. If the return value was true, the exception is\n suppressed, and execution continues with the statement following\n the ``with`` statement.\n\n If the suite was exited for any reason other than an exception, the\n return value from ``__exit__()`` is ignored, and execution proceeds\n at the normal location for the kind of exit that was taken.\n\nWith more than one item, the context managers are processed as if\nmultiple ``with`` statements were nested:\n\n with A() as a, B() as b:\n suite\n\nis equivalent to\n\n with A() as a:\n with B() as b:\n suite\n\nChanged in version 3.1: Support for multiple context expressions.\n\nSee also:\n\n **PEP 0343** - The "with" statement\n The specification, background, and examples for the Python\n ``with`` statement.\n\n\nFunction definitions\n====================\n\nA function definition defines a user-defined function object (see\nsection *The standard type hierarchy*):\n\n funcdef ::= [decorators] "def" funcname "(" [parameter_list] ")" ["->" expression] ":" suite\n decorators ::= decorator+\n decorator ::= "@" dotted_name ["(" [parameter_list [","]] ")"] NEWLINE\n dotted_name ::= identifier ("." identifier)*\n parameter_list ::= (defparameter ",")*\n ( "*" [parameter] ("," defparameter)* ["," "**" parameter]\n | "**" parameter\n | defparameter [","] )\n parameter ::= identifier [":" expression]\n defparameter ::= parameter ["=" expression]\n funcname ::= identifier\n\nA function definition is an executable statement. Its execution binds\nthe function name in the current local namespace to a function object\n(a wrapper around the executable code for the function). This\nfunction object contains a reference to the current global namespace\nas the global namespace to be used when the function is called.\n\nThe function definition does not execute the function body; this gets\nexecuted only when the function is called. [3]\n\nA function definition may be wrapped by one or more *decorator*\nexpressions. Decorator expressions are evaluated when the function is\ndefined, in the scope that contains the function definition. The\nresult must be a callable, which is invoked with the function object\nas the only argument. The returned value is bound to the function name\ninstead of the function object. Multiple decorators are applied in\nnested fashion. For example, the following code\n\n @f1(arg)\n @f2\n def func(): pass\n\nis equivalent to\n\n def func(): pass\n func = f1(arg)(f2(func))\n\nWhen one or more *parameters* have the form *parameter* ``=``\n*expression*, the function is said to have "default parameter values."\nFor a parameter with a default value, the corresponding *argument* may\nbe omitted from a call, in which case the parameter\'s default value is\nsubstituted. If a parameter has a default value, all following\nparameters up until the "``*``" must also have a default value ---\nthis is a syntactic restriction that is not expressed by the grammar.\n\n**Default parameter values are evaluated from left to right when the\nfunction definition is executed.** This means that the expression is\nevaluated once, when the function is defined, and that the same "pre-\ncomputed" value is used for each call. This is especially important\nto understand when a default parameter is a mutable object, such as a\nlist or a dictionary: if the function modifies the object (e.g. by\nappending an item to a list), the default value is in effect modified.\nThis is generally not what was intended. A way around this is to use\n``None`` as the default, and explicitly test for it in the body of the\nfunction, e.g.:\n\n def whats_on_the_telly(penguin=None):\n if penguin is None:\n penguin = []\n penguin.append("property of the zoo")\n return penguin\n\nFunction call semantics are described in more detail in section\n*Calls*. A function call always assigns values to all parameters\nmentioned in the parameter list, either from position arguments, from\nkeyword arguments, or from default values. If the form\n"``*identifier``" is present, it is initialized to a tuple receiving\nany excess positional parameters, defaulting to the empty tuple. If\nthe form "``**identifier``" is present, it is initialized to a new\ndictionary receiving any excess keyword arguments, defaulting to a new\nempty dictionary. Parameters after "``*``" or "``*identifier``" are\nkeyword-only parameters and may only be passed used keyword arguments.\n\nParameters may have annotations of the form "``: expression``"\nfollowing the parameter name. Any parameter may have an annotation\neven those of the form ``*identifier`` or ``**identifier``. Functions\nmay have "return" annotation of the form "``-> expression``" after the\nparameter list. These annotations can be any valid Python expression\nand are evaluated when the function definition is executed.\nAnnotations may be evaluated in a different order than they appear in\nthe source code. The presence of annotations does not change the\nsemantics of a function. The annotation values are available as\nvalues of a dictionary keyed by the parameters\' names in the\n``__annotations__`` attribute of the function object.\n\nIt is also possible to create anonymous functions (functions not bound\nto a name), for immediate use in expressions. This uses lambda\nexpressions, described in section *Lambdas*. Note that the lambda\nexpression is merely a shorthand for a simplified function definition;\na function defined in a "``def``" statement can be passed around or\nassigned to another name just like a function defined by a lambda\nexpression. The "``def``" form is actually more powerful since it\nallows the execution of multiple statements and annotations.\n\n**Programmer\'s note:** Functions are first-class objects. A "``def``"\nstatement executed inside a function definition defines a local\nfunction that can be returned or passed around. Free variables used\nin the nested function can access the local variables of the function\ncontaining the def. See section *Naming and binding* for details.\n\nSee also:\n\n **PEP 3107** - Function Annotations\n The original specification for function annotations.\n\n\nClass definitions\n=================\n\nA class definition defines a class object (see section *The standard\ntype hierarchy*):\n\n classdef ::= [decorators] "class" classname [inheritance] ":" suite\n inheritance ::= "(" [parameter_list] ")"\n classname ::= identifier\n\nA class definition is an executable statement. The inheritance list\nusually gives a list of base classes (see *Customizing class creation*\nfor more advanced uses), so each item in the list should evaluate to a\nclass object which allows subclassing. Classes without an inheritance\nlist inherit, by default, from the base class ``object``; hence,\n\n class Foo:\n pass\n\nis equivalent to\n\n class Foo(object):\n pass\n\nThe class\'s suite is then executed in a new execution frame (see\n*Naming and binding*), using a newly created local namespace and the\noriginal global namespace. (Usually, the suite contains mostly\nfunction definitions.) When the class\'s suite finishes execution, its\nexecution frame is discarded but its local namespace is saved. [4] A\nclass object is then created using the inheritance list for the base\nclasses and the saved local namespace for the attribute dictionary.\nThe class name is bound to this class object in the original local\nnamespace.\n\nClass creation can be customized heavily using *metaclasses*.\n\nClasses can also be decorated: just like when decorating functions,\n\n @f1(arg)\n @f2\n class Foo: pass\n\nis equivalent to\n\n class Foo: pass\n Foo = f1(arg)(f2(Foo))\n\nThe evaluation rules for the decorator expressions are the same as for\nfunction decorators. The result must be a class object, which is then\nbound to the class name.\n\n**Programmer\'s note:** Variables defined in the class definition are\nclass attributes; they are shared by instances. Instance attributes\ncan be set in a method with ``self.name = value``. Both class and\ninstance attributes are accessible through the notation\n"``self.name``", and an instance attribute hides a class attribute\nwith the same name when accessed in this way. Class attributes can be\nused as defaults for instance attributes, but using mutable values\nthere can lead to unexpected results. *Descriptors* can be used to\ncreate instance variables with different implementation details.\n\nSee also:\n\n **PEP 3115** - Metaclasses in Python 3 **PEP 3129** - Class\n Decorators\n\n-[ Footnotes ]-\n\n[1] The exception is propagated to the invocation stack unless there\n is a ``finally`` clause which happens to raise another exception.\n That new exception causes the old one to be lost.\n\n[2] Currently, control "flows off the end" except in the case of an\n exception or the execution of a ``return``, ``continue``, or\n ``break`` statement.\n\n[3] A string literal appearing as the first statement in the function\n body is transformed into the function\'s ``__doc__`` attribute and\n therefore the function\'s *docstring*.\n\n[4] A string literal appearing as the first statement in the class\n body is transformed into the namespace\'s ``__doc__`` item and\n therefore the class\'s *docstring*.\n', - 'context-managers': '\nWith Statement Context Managers\n*******************************\n\nA *context manager* is an object that defines the runtime context to\nbe established when executing a ``with`` statement. The context\nmanager handles the entry into, and the exit from, the desired runtime\ncontext for the execution of the block of code. Context managers are\nnormally invoked using the ``with`` statement (described in section\n*The with statement*), but can also be used by directly invoking their\nmethods.\n\nTypical uses of context managers include saving and restoring various\nkinds of global state, locking and unlocking resources, closing opened\nfiles, etc.\n\nFor more information on context managers, see *Context Manager Types*.\n\nobject.__enter__(self)\n\n Enter the runtime context related to this object. The ``with``\n statement will bind this method\'s return value to the target(s)\n specified in the ``as`` clause of the statement, if any.\n\nobject.__exit__(self, exc_type, exc_value, traceback)\n\n Exit the runtime context related to this object. The parameters\n describe the exception that caused the context to be exited. If the\n context was exited without an exception, all three arguments will\n be ``None``.\n\n If an exception is supplied, and the method wishes to suppress the\n exception (i.e., prevent it from being propagated), it should\n return a true value. Otherwise, the exception will be processed\n normally upon exit from this method.\n\n Note that ``__exit__()`` methods should not reraise the passed-in\n exception; this is the caller\'s responsibility.\n\nSee also:\n\n **PEP 0343** - The "with" statement\n The specification, background, and examples for the Python\n ``with`` statement.\n', - 'continue': '\nThe ``continue`` statement\n**************************\n\n continue_stmt ::= "continue"\n\n``continue`` may only occur syntactically nested in a ``for`` or\n``while`` loop, but not nested in a function or class definition or\n``finally`` clause within that loop. It continues with the next cycle\nof the nearest enclosing loop.\n\nWhen ``continue`` passes control out of a ``try`` statement with a\n``finally`` clause, that ``finally`` clause is executed before really\nstarting the next loop cycle.\n', - 'conversions': '\nArithmetic conversions\n**********************\n\nWhen a description of an arithmetic operator below uses the phrase\n"the numeric arguments are converted to a common type," this means\nthat the operator implementation for built-in types works that way:\n\n* If either argument is a complex number, the other is converted to\n complex;\n\n* otherwise, if either argument is a floating point number, the other\n is converted to floating point;\n\n* otherwise, both must be integers and no conversion is necessary.\n\nSome additional rules apply for certain operators (e.g., a string left\nargument to the \'%\' operator). Extensions must define their own\nconversion behavior.\n', - 'customization': '\nBasic customization\n*******************\n\nobject.__new__(cls[, ...])\n\n Called to create a new instance of class *cls*. ``__new__()`` is a\n static method (special-cased so you need not declare it as such)\n that takes the class of which an instance was requested as its\n first argument. The remaining arguments are those passed to the\n object constructor expression (the call to the class). The return\n value of ``__new__()`` should be the new object instance (usually\n an instance of *cls*).\n\n Typical implementations create a new instance of the class by\n invoking the superclass\'s ``__new__()`` method using\n ``super(currentclass, cls).__new__(cls[, ...])`` with appropriate\n arguments and then modifying the newly-created instance as\n necessary before returning it.\n\n If ``__new__()`` returns an instance of *cls*, then the new\n instance\'s ``__init__()`` method will be invoked like\n ``__init__(self[, ...])``, where *self* is the new instance and the\n remaining arguments are the same as were passed to ``__new__()``.\n\n If ``__new__()`` does not return an instance of *cls*, then the new\n instance\'s ``__init__()`` method will not be invoked.\n\n ``__new__()`` is intended mainly to allow subclasses of immutable\n types (like int, str, or tuple) to customize instance creation. It\n is also commonly overridden in custom metaclasses in order to\n customize class creation.\n\nobject.__init__(self[, ...])\n\n Called when the instance is created. The arguments are those\n passed to the class constructor expression. If a base class has an\n ``__init__()`` method, the derived class\'s ``__init__()`` method,\n if any, must explicitly call it to ensure proper initialization of\n the base class part of the instance; for example:\n ``BaseClass.__init__(self, [args...])``. As a special constraint\n on constructors, no value may be returned; doing so will cause a\n ``TypeError`` to be raised at runtime.\n\nobject.__del__(self)\n\n Called when the instance is about to be destroyed. This is also\n called a destructor. If a base class has a ``__del__()`` method,\n the derived class\'s ``__del__()`` method, if any, must explicitly\n call it to ensure proper deletion of the base class part of the\n instance. Note that it is possible (though not recommended!) for\n the ``__del__()`` method to postpone destruction of the instance by\n creating a new reference to it. It may then be called at a later\n time when this new reference is deleted. It is not guaranteed that\n ``__del__()`` methods are called for objects that still exist when\n the interpreter exits.\n\n Note: ``del x`` doesn\'t directly call ``x.__del__()`` --- the former\n decrements the reference count for ``x`` by one, and the latter\n is only called when ``x``\'s reference count reaches zero. Some\n common situations that may prevent the reference count of an\n object from going to zero include: circular references between\n objects (e.g., a doubly-linked list or a tree data structure with\n parent and child pointers); a reference to the object on the\n stack frame of a function that caught an exception (the traceback\n stored in ``sys.exc_info()[2]`` keeps the stack frame alive); or\n a reference to the object on the stack frame that raised an\n unhandled exception in interactive mode (the traceback stored in\n ``sys.last_traceback`` keeps the stack frame alive). The first\n situation can only be remedied by explicitly breaking the cycles;\n the latter two situations can be resolved by storing ``None`` in\n ``sys.last_traceback``. Circular references which are garbage are\n detected and cleaned up when the cyclic garbage collector is\n enabled (it\'s on by default). Refer to the documentation for the\n ``gc`` module for more information about this topic.\n\n Warning: Due to the precarious circumstances under which ``__del__()``\n methods are invoked, exceptions that occur during their execution\n are ignored, and a warning is printed to ``sys.stderr`` instead.\n Also, when ``__del__()`` is invoked in response to a module being\n deleted (e.g., when execution of the program is done), other\n globals referenced by the ``__del__()`` method may already have\n been deleted or in the process of being torn down (e.g. the\n import machinery shutting down). For this reason, ``__del__()``\n methods should do the absolute minimum needed to maintain\n external invariants. Starting with version 1.5, Python\n guarantees that globals whose name begins with a single\n underscore are deleted from their module before other globals are\n deleted; if no other references to such globals exist, this may\n help in assuring that imported modules are still available at the\n time when the ``__del__()`` method is called.\n\nobject.__repr__(self)\n\n Called by the ``repr()`` built-in function to compute the\n "official" string representation of an object. If at all possible,\n this should look like a valid Python expression that could be used\n to recreate an object with the same value (given an appropriate\n environment). If this is not possible, a string of the form\n ``<...some useful description...>`` should be returned. The return\n value must be a string object. If a class defines ``__repr__()``\n but not ``__str__()``, then ``__repr__()`` is also used when an\n "informal" string representation of instances of that class is\n required.\n\n This is typically used for debugging, so it is important that the\n representation is information-rich and unambiguous.\n\nobject.__str__(self)\n\n Called by ``str(object)`` and the built-in functions ``format()``\n and ``print()`` to compute the "informal" or nicely printable\n string representation of an object. The return value must be a\n *string* object.\n\n This method differs from ``object.__repr__()`` in that there is no\n expectation that ``__str__()`` return a valid Python expression: a\n more convenient or concise representation can be used.\n\n The default implementation defined by the built-in type ``object``\n calls ``object.__repr__()``.\n\nobject.__bytes__(self)\n\n Called by ``bytes()`` to compute a byte-string representation of an\n object. This should return a ``bytes`` object.\n\nobject.__format__(self, format_spec)\n\n Called by the ``format()`` built-in function (and by extension, the\n ``str.format()`` method of class ``str``) to produce a "formatted"\n string representation of an object. The ``format_spec`` argument is\n a string that contains a description of the formatting options\n desired. The interpretation of the ``format_spec`` argument is up\n to the type implementing ``__format__()``, however most classes\n will either delegate formatting to one of the built-in types, or\n use a similar formatting option syntax.\n\n See *Format Specification Mini-Language* for a description of the\n standard formatting syntax.\n\n The return value must be a string object.\n\nobject.__lt__(self, other)\nobject.__le__(self, other)\nobject.__eq__(self, other)\nobject.__ne__(self, other)\nobject.__gt__(self, other)\nobject.__ge__(self, other)\n\n These are the so-called "rich comparison" methods. The\n correspondence between operator symbols and method names is as\n follows: ``x<y`` calls ``x.__lt__(y)``, ``x<=y`` calls\n ``x.__le__(y)``, ``x==y`` calls ``x.__eq__(y)``, ``x!=y`` calls\n ``x.__ne__(y)``, ``x>y`` calls ``x.__gt__(y)``, and ``x>=y`` calls\n ``x.__ge__(y)``.\n\n A rich comparison method may return the singleton\n ``NotImplemented`` if it does not implement the operation for a\n given pair of arguments. By convention, ``False`` and ``True`` are\n returned for a successful comparison. However, these methods can\n return any value, so if the comparison operator is used in a\n Boolean context (e.g., in the condition of an ``if`` statement),\n Python will call ``bool()`` on the value to determine if the result\n is true or false.\n\n There are no implied relationships among the comparison operators.\n The truth of ``x==y`` does not imply that ``x!=y`` is false.\n Accordingly, when defining ``__eq__()``, one should also define\n ``__ne__()`` so that the operators will behave as expected. See\n the paragraph on ``__hash__()`` for some important notes on\n creating *hashable* objects which support custom comparison\n operations and are usable as dictionary keys.\n\n There are no swapped-argument versions of these methods (to be used\n when the left argument does not support the operation but the right\n argument does); rather, ``__lt__()`` and ``__gt__()`` are each\n other\'s reflection, ``__le__()`` and ``__ge__()`` are each other\'s\n reflection, and ``__eq__()`` and ``__ne__()`` are their own\n reflection.\n\n Arguments to rich comparison methods are never coerced.\n\n To automatically generate ordering operations from a single root\n operation, see ``functools.total_ordering()``.\n\nobject.__hash__(self)\n\n Called by built-in function ``hash()`` and for operations on\n members of hashed collections including ``set``, ``frozenset``, and\n ``dict``. ``__hash__()`` should return an integer. The only\n required property is that objects which compare equal have the same\n hash value; it is advised to somehow mix together (e.g. using\n exclusive or) the hash values for the components of the object that\n also play a part in comparison of objects.\n\n Note: ``hash()`` truncates the value returned from an object\'s custom\n ``__hash__()`` method to the size of a ``Py_ssize_t``. This is\n typically 8 bytes on 64-bit builds and 4 bytes on 32-bit builds.\n If an object\'s ``__hash__()`` must interoperate on builds of\n different bit sizes, be sure to check the width on all supported\n builds. An easy way to do this is with ``python -c "import sys;\n print(sys.hash_info.width)"``\n\n If a class does not define an ``__eq__()`` method it should not\n define a ``__hash__()`` operation either; if it defines\n ``__eq__()`` but not ``__hash__()``, its instances will not be\n usable as items in hashable collections. If a class defines\n mutable objects and implements an ``__eq__()`` method, it should\n not implement ``__hash__()``, since the implementation of hashable\n collections requires that a key\'s hash value is immutable (if the\n object\'s hash value changes, it will be in the wrong hash bucket).\n\n User-defined classes have ``__eq__()`` and ``__hash__()`` methods\n by default; with them, all objects compare unequal (except with\n themselves) and ``x.__hash__()`` returns an appropriate value such\n that ``x == y`` implies both that ``x is y`` and ``hash(x) ==\n hash(y)``.\n\n A class that overrides ``__eq__()`` and does not define\n ``__hash__()`` will have its ``__hash__()`` implicitly set to\n ``None``. When the ``__hash__()`` method of a class is ``None``,\n instances of the class will raise an appropriate ``TypeError`` when\n a program attempts to retrieve their hash value, and will also be\n correctly identified as unhashable when checking ``isinstance(obj,\n collections.Hashable``).\n\n If a class that overrides ``__eq__()`` needs to retain the\n implementation of ``__hash__()`` from a parent class, the\n interpreter must be told this explicitly by setting ``__hash__ =\n <ParentClass>.__hash__``.\n\n If a class that does not override ``__eq__()`` wishes to suppress\n hash support, it should include ``__hash__ = None`` in the class\n definition. A class which defines its own ``__hash__()`` that\n explicitly raises a ``TypeError`` would be incorrectly identified\n as hashable by an ``isinstance(obj, collections.Hashable)`` call.\n\n Note: By default, the ``__hash__()`` values of str, bytes and datetime\n objects are "salted" with an unpredictable random value.\n Although they remain constant within an individual Python\n process, they are not predictable between repeated invocations of\n Python.This is intended to provide protection against a denial-\n of-service caused by carefully-chosen inputs that exploit the\n worst case performance of a dict insertion, O(n^2) complexity.\n See http://www.ocert.org/advisories/ocert-2011-003.html for\n details.Changing hash values affects the iteration order of\n dicts, sets and other mappings. Python has never made guarantees\n about this ordering (and it typically varies between 32-bit and\n 64-bit builds).See also ``PYTHONHASHSEED``.\n\n Changed in version 3.3: Hash randomization is enabled by default.\n\nobject.__bool__(self)\n\n Called to implement truth value testing and the built-in operation\n ``bool()``; should return ``False`` or ``True``. When this method\n is not defined, ``__len__()`` is called, if it is defined, and the\n object is considered true if its result is nonzero. If a class\n defines neither ``__len__()`` nor ``__bool__()``, all its instances\n are considered true.\n', - 'debugger': '\n``pdb`` --- The Python Debugger\n*******************************\n\nThe module ``pdb`` defines an interactive source code debugger for\nPython programs. It supports setting (conditional) breakpoints and\nsingle stepping at the source line level, inspection of stack frames,\nsource code listing, and evaluation of arbitrary Python code in the\ncontext of any stack frame. It also supports post-mortem debugging\nand can be called under program control.\n\nThe debugger is extensible -- it is actually defined as the class\n``Pdb``. This is currently undocumented but easily understood by\nreading the source. The extension interface uses the modules ``bdb``\nand ``cmd``.\n\nThe debugger\'s prompt is ``(Pdb)``. Typical usage to run a program\nunder control of the debugger is:\n\n >>> import pdb\n >>> import mymodule\n >>> pdb.run(\'mymodule.test()\')\n > <string>(0)?()\n (Pdb) continue\n > <string>(1)?()\n (Pdb) continue\n NameError: \'spam\'\n > <string>(1)?()\n (Pdb)\n\nChanged in version 3.3: Tab-completion via the ``readline`` module is\navailable for commands and command arguments, e.g. the current global\nand local names are offered as arguments of the ``p`` command.\n\n``pdb.py`` can also be invoked as a script to debug other scripts.\nFor example:\n\n python3 -m pdb myscript.py\n\nWhen invoked as a script, pdb will automatically enter post-mortem\ndebugging if the program being debugged exits abnormally. After post-\nmortem debugging (or after normal exit of the program), pdb will\nrestart the program. Automatic restarting preserves pdb\'s state (such\nas breakpoints) and in most cases is more useful than quitting the\ndebugger upon program\'s exit.\n\nNew in version 3.2: ``pdb.py`` now accepts a ``-c`` option that\nexecutes commands as if given in a ``.pdbrc`` file, see *Debugger\nCommands*.\n\nThe typical usage to break into the debugger from a running program is\nto insert\n\n import pdb; pdb.set_trace()\n\nat the location you want to break into the debugger. You can then\nstep through the code following this statement, and continue running\nwithout the debugger using the ``continue`` command.\n\nThe typical usage to inspect a crashed program is:\n\n >>> import pdb\n >>> import mymodule\n >>> mymodule.test()\n Traceback (most recent call last):\n File "<stdin>", line 1, in ?\n File "./mymodule.py", line 4, in test\n test2()\n File "./mymodule.py", line 3, in test2\n print(spam)\n NameError: spam\n >>> pdb.pm()\n > ./mymodule.py(3)test2()\n -> print(spam)\n (Pdb)\n\nThe module defines the following functions; each enters the debugger\nin a slightly different way:\n\npdb.run(statement, globals=None, locals=None)\n\n Execute the *statement* (given as a string or a code object) under\n debugger control. The debugger prompt appears before any code is\n executed; you can set breakpoints and type ``continue``, or you can\n step through the statement using ``step`` or ``next`` (all these\n commands are explained below). The optional *globals* and *locals*\n arguments specify the environment in which the code is executed; by\n default the dictionary of the module ``__main__`` is used. (See\n the explanation of the built-in ``exec()`` or ``eval()``\n functions.)\n\npdb.runeval(expression, globals=None, locals=None)\n\n Evaluate the *expression* (given as a string or a code object)\n under debugger control. When ``runeval()`` returns, it returns the\n value of the expression. Otherwise this function is similar to\n ``run()``.\n\npdb.runcall(function, *args, **kwds)\n\n Call the *function* (a function or method object, not a string)\n with the given arguments. When ``runcall()`` returns, it returns\n whatever the function call returned. The debugger prompt appears\n as soon as the function is entered.\n\npdb.set_trace()\n\n Enter the debugger at the calling stack frame. This is useful to\n hard-code a breakpoint at a given point in a program, even if the\n code is not otherwise being debugged (e.g. when an assertion\n fails).\n\npdb.post_mortem(traceback=None)\n\n Enter post-mortem debugging of the given *traceback* object. If no\n *traceback* is given, it uses the one of the exception that is\n currently being handled (an exception must be being handled if the\n default is to be used).\n\npdb.pm()\n\n Enter post-mortem debugging of the traceback found in\n ``sys.last_traceback``.\n\nThe ``run*`` functions and ``set_trace()`` are aliases for\ninstantiating the ``Pdb`` class and calling the method of the same\nname. If you want to access further features, you have to do this\nyourself:\n\nclass class pdb.Pdb(completekey=\'tab\', stdin=None, stdout=None, skip=None, nosigint=False)\n\n ``Pdb`` is the debugger class.\n\n The *completekey*, *stdin* and *stdout* arguments are passed to the\n underlying ``cmd.Cmd`` class; see the description there.\n\n The *skip* argument, if given, must be an iterable of glob-style\n module name patterns. The debugger will not step into frames that\n originate in a module that matches one of these patterns. [1]\n\n By default, Pdb sets a handler for the SIGINT signal (which is sent\n when the user presses Ctrl-C on the console) when you give a\n ``continue`` command. This allows you to break into the debugger\n again by pressing Ctrl-C. If you want Pdb not to touch the SIGINT\n handler, set *nosigint* tot true.\n\n Example call to enable tracing with *skip*:\n\n import pdb; pdb.Pdb(skip=[\'django.*\']).set_trace()\n\n New in version 3.1: The *skip* argument.\n\n New in version 3.2: The *nosigint* argument. Previously, a SIGINT\n handler was never set by Pdb.\n\n run(statement, globals=None, locals=None)\n runeval(expression, globals=None, locals=None)\n runcall(function, *args, **kwds)\n set_trace()\n\n See the documentation for the functions explained above.\n\n\nDebugger Commands\n=================\n\nThe commands recognized by the debugger are listed below. Most\ncommands can be abbreviated to one or two letters as indicated; e.g.\n``h(elp)`` means that either ``h`` or ``help`` can be used to enter\nthe help command (but not ``he`` or ``hel``, nor ``H`` or ``Help`` or\n``HELP``). Arguments to commands must be separated by whitespace\n(spaces or tabs). Optional arguments are enclosed in square brackets\n(``[]``) in the command syntax; the square brackets must not be typed.\nAlternatives in the command syntax are separated by a vertical bar\n(``|``).\n\nEntering a blank line repeats the last command entered. Exception: if\nthe last command was a ``list`` command, the next 11 lines are listed.\n\nCommands that the debugger doesn\'t recognize are assumed to be Python\nstatements and are executed in the context of the program being\ndebugged. Python statements can also be prefixed with an exclamation\npoint (``!``). This is a powerful way to inspect the program being\ndebugged; it is even possible to change a variable or call a function.\nWhen an exception occurs in such a statement, the exception name is\nprinted but the debugger\'s state is not changed.\n\nThe debugger supports *aliases*. Aliases can have parameters which\nallows one a certain level of adaptability to the context under\nexamination.\n\nMultiple commands may be entered on a single line, separated by\n``;;``. (A single ``;`` is not used as it is the separator for\nmultiple commands in a line that is passed to the Python parser.) No\nintelligence is applied to separating the commands; the input is split\nat the first ``;;`` pair, even if it is in the middle of a quoted\nstring.\n\nIf a file ``.pdbrc`` exists in the user\'s home directory or in the\ncurrent directory, it is read in and executed as if it had been typed\nat the debugger prompt. This is particularly useful for aliases. If\nboth files exist, the one in the home directory is read first and\naliases defined there can be overridden by the local file.\n\nChanged in version 3.2: ``.pdbrc`` can now contain commands that\ncontinue debugging, such as ``continue`` or ``next``. Previously,\nthese commands had no effect.\n\nh(elp) [command]\n\n Without argument, print the list of available commands. With a\n *command* as argument, print help about that command. ``help pdb``\n displays the full documentation (the docstring of the ``pdb``\n module). Since the *command* argument must be an identifier,\n ``help exec`` must be entered to get help on the ``!`` command.\n\nw(here)\n\n Print a stack trace, with the most recent frame at the bottom. An\n arrow indicates the current frame, which determines the context of\n most commands.\n\nd(own) [count]\n\n Move the current frame *count* (default one) levels down in the\n stack trace (to a newer frame).\n\nu(p) [count]\n\n Move the current frame *count* (default one) levels up in the stack\n trace (to an older frame).\n\nb(reak) [([filename:]lineno | function) [, condition]]\n\n With a *lineno* argument, set a break there in the current file.\n With a *function* argument, set a break at the first executable\n statement within that function. The line number may be prefixed\n with a filename and a colon, to specify a breakpoint in another\n file (probably one that hasn\'t been loaded yet). The file is\n searched on ``sys.path``. Note that each breakpoint is assigned a\n number to which all the other breakpoint commands refer.\n\n If a second argument is present, it is an expression which must\n evaluate to true before the breakpoint is honored.\n\n Without argument, list all breaks, including for each breakpoint,\n the number of times that breakpoint has been hit, the current\n ignore count, and the associated condition if any.\n\ntbreak [([filename:]lineno | function) [, condition]]\n\n Temporary breakpoint, which is removed automatically when it is\n first hit. The arguments are the same as for ``break``.\n\ncl(ear) [filename:lineno | bpnumber [bpnumber ...]]\n\n With a *filename:lineno* argument, clear all the breakpoints at\n this line. With a space separated list of breakpoint numbers, clear\n those breakpoints. Without argument, clear all breaks (but first\n ask confirmation).\n\ndisable [bpnumber [bpnumber ...]]\n\n Disable the breakpoints given as a space separated list of\n breakpoint numbers. Disabling a breakpoint means it cannot cause\n the program to stop execution, but unlike clearing a breakpoint, it\n remains in the list of breakpoints and can be (re-)enabled.\n\nenable [bpnumber [bpnumber ...]]\n\n Enable the breakpoints specified.\n\nignore bpnumber [count]\n\n Set the ignore count for the given breakpoint number. If count is\n omitted, the ignore count is set to 0. A breakpoint becomes active\n when the ignore count is zero. When non-zero, the count is\n decremented each time the breakpoint is reached and the breakpoint\n is not disabled and any associated condition evaluates to true.\n\ncondition bpnumber [condition]\n\n Set a new *condition* for the breakpoint, an expression which must\n evaluate to true before the breakpoint is honored. If *condition*\n is absent, any existing condition is removed; i.e., the breakpoint\n is made unconditional.\n\ncommands [bpnumber]\n\n Specify a list of commands for breakpoint number *bpnumber*. The\n commands themselves appear on the following lines. Type a line\n containing just ``end`` to terminate the commands. An example:\n\n (Pdb) commands 1\n (com) p some_variable\n (com) end\n (Pdb)\n\n To remove all commands from a breakpoint, type commands and follow\n it immediately with ``end``; that is, give no commands.\n\n With no *bpnumber* argument, commands refers to the last breakpoint\n set.\n\n You can use breakpoint commands to start your program up again.\n Simply use the continue command, or step, or any other command that\n resumes execution.\n\n Specifying any command resuming execution (currently continue,\n step, next, return, jump, quit and their abbreviations) terminates\n the command list (as if that command was immediately followed by\n end). This is because any time you resume execution (even with a\n simple next or step), you may encounter another breakpoint--which\n could have its own command list, leading to ambiguities about which\n list to execute.\n\n If you use the \'silent\' command in the command list, the usual\n message about stopping at a breakpoint is not printed. This may be\n desirable for breakpoints that are to print a specific message and\n then continue. If none of the other commands print anything, you\n see no sign that the breakpoint was reached.\n\ns(tep)\n\n Execute the current line, stop at the first possible occasion\n (either in a function that is called or on the next line in the\n current function).\n\nn(ext)\n\n Continue execution until the next line in the current function is\n reached or it returns. (The difference between ``next`` and\n ``step`` is that ``step`` stops inside a called function, while\n ``next`` executes called functions at (nearly) full speed, only\n stopping at the next line in the current function.)\n\nunt(il) [lineno]\n\n Without argument, continue execution until the line with a number\n greater than the current one is reached.\n\n With a line number, continue execution until a line with a number\n greater or equal to that is reached. In both cases, also stop when\n the current frame returns.\n\n Changed in version 3.2: Allow giving an explicit line number.\n\nr(eturn)\n\n Continue execution until the current function returns.\n\nc(ont(inue))\n\n Continue execution, only stop when a breakpoint is encountered.\n\nj(ump) lineno\n\n Set the next line that will be executed. Only available in the\n bottom-most frame. This lets you jump back and execute code again,\n or jump forward to skip code that you don\'t want to run.\n\n It should be noted that not all jumps are allowed -- for instance\n it is not possible to jump into the middle of a ``for`` loop or out\n of a ``finally`` clause.\n\nl(ist) [first[, last]]\n\n List source code for the current file. Without arguments, list 11\n lines around the current line or continue the previous listing.\n With ``.`` as argument, list 11 lines around the current line.\n With one argument, list 11 lines around at that line. With two\n arguments, list the given range; if the second argument is less\n than the first, it is interpreted as a count.\n\n The current line in the current frame is indicated by ``->``. If\n an exception is being debugged, the line where the exception was\n originally raised or propagated is indicated by ``>>``, if it\n differs from the current line.\n\n New in version 3.2: The ``>>`` marker.\n\nll | longlist\n\n List all source code for the current function or frame.\n Interesting lines are marked as for ``list``.\n\n New in version 3.2.\n\na(rgs)\n\n Print the argument list of the current function.\n\np expression\n\n Evaluate the *expression* in the current context and print its\n value.\n\n Note: ``print()`` can also be used, but is not a debugger command ---\n this executes the Python ``print()`` function.\n\npp expression\n\n Like the ``p`` command, except the value of the expression is\n pretty-printed using the ``pprint`` module.\n\nwhatis expression\n\n Print the type of the *expression*.\n\nsource expression\n\n Try to get source code for the given object and display it.\n\n New in version 3.2.\n\ndisplay [expression]\n\n Display the value of the expression if it changed, each time\n execution stops in the current frame.\n\n Without expression, list all display expressions for the current\n frame.\n\n New in version 3.2.\n\nundisplay [expression]\n\n Do not display the expression any more in the current frame.\n Without expression, clear all display expressions for the current\n frame.\n\n New in version 3.2.\n\ninteract\n\n Start an interative interpreter (using the ``code`` module) whose\n global namespace contains all the (global and local) names found in\n the current scope.\n\n New in version 3.2.\n\nalias [name [command]]\n\n Create an alias called *name* that executes *command*. The command\n must *not* be enclosed in quotes. Replaceable parameters can be\n indicated by ``%1``, ``%2``, and so on, while ``%*`` is replaced by\n all the parameters. If no command is given, the current alias for\n *name* is shown. If no arguments are given, all aliases are listed.\n\n Aliases may be nested and can contain anything that can be legally\n typed at the pdb prompt. Note that internal pdb commands *can* be\n overridden by aliases. Such a command is then hidden until the\n alias is removed. Aliasing is recursively applied to the first\n word of the command line; all other words in the line are left\n alone.\n\n As an example, here are two useful aliases (especially when placed\n in the ``.pdbrc`` file):\n\n # Print instance variables (usage "pi classInst")\n alias pi for k in %1.__dict__.keys(): print("%1.",k,"=",%1.__dict__[k])\n # Print instance variables in self\n alias ps pi self\n\nunalias name\n\n Delete the specified alias.\n\n! statement\n\n Execute the (one-line) *statement* in the context of the current\n stack frame. The exclamation point can be omitted unless the first\n word of the statement resembles a debugger command. To set a\n global variable, you can prefix the assignment command with a\n ``global`` statement on the same line, e.g.:\n\n (Pdb) global list_options; list_options = [\'-l\']\n (Pdb)\n\nrun [args ...]\nrestart [args ...]\n\n Restart the debugged Python program. If an argument is supplied,\n it is split with ``shlex`` and the result is used as the new\n ``sys.argv``. History, breakpoints, actions and debugger options\n are preserved. ``restart`` is an alias for ``run``.\n\nq(uit)\n\n Quit from the debugger. The program being executed is aborted.\n\n-[ Footnotes ]-\n\n[1] Whether a frame is considered to originate in a certain module is\n determined by the ``__name__`` in the frame globals.\n', - 'del': '\nThe ``del`` statement\n*********************\n\n del_stmt ::= "del" target_list\n\nDeletion is recursively defined very similar to the way assignment is\ndefined. Rather than spelling it out in full details, here are some\nhints.\n\nDeletion of a target list recursively deletes each target, from left\nto right.\n\nDeletion of a name removes the binding of that name from the local or\nglobal namespace, depending on whether the name occurs in a ``global``\nstatement in the same code block. If the name is unbound, a\n``NameError`` exception will be raised.\n\nDeletion of attribute references, subscriptions and slicings is passed\nto the primary object involved; deletion of a slicing is in general\nequivalent to assignment of an empty slice of the right type (but even\nthis is determined by the sliced object).\n\nChanged in version 3.2: Previously it was illegal to delete a name\nfrom the local namespace if it occurs as a free variable in a nested\nblock.\n', - 'dict': '\nDictionary displays\n*******************\n\nA dictionary display is a possibly empty series of key/datum pairs\nenclosed in curly braces:\n\n dict_display ::= "{" [key_datum_list | dict_comprehension] "}"\n key_datum_list ::= key_datum ("," key_datum)* [","]\n key_datum ::= expression ":" expression\n dict_comprehension ::= expression ":" expression comp_for\n\nA dictionary display yields a new dictionary object.\n\nIf a comma-separated sequence of key/datum pairs is given, they are\nevaluated from left to right to define the entries of the dictionary:\neach key object is used as a key into the dictionary to store the\ncorresponding datum. This means that you can specify the same key\nmultiple times in the key/datum list, and the final dictionary\'s value\nfor that key will be the last one given.\n\nA dict comprehension, in contrast to list and set comprehensions,\nneeds two expressions separated with a colon followed by the usual\n"for" and "if" clauses. When the comprehension is run, the resulting\nkey and value elements are inserted in the new dictionary in the order\nthey are produced.\n\nRestrictions on the types of the key values are listed earlier in\nsection *The standard type hierarchy*. (To summarize, the key type\nshould be *hashable*, which excludes all mutable objects.) Clashes\nbetween duplicate keys are not detected; the last datum (textually\nrightmost in the display) stored for a given key value prevails.\n', - 'dynamic-features': '\nInteraction with dynamic features\n*********************************\n\nThere are several cases where Python statements are illegal when used\nin conjunction with nested scopes that contain free variables.\n\nIf a variable is referenced in an enclosing scope, it is illegal to\ndelete the name. An error will be reported at compile time.\n\nIf the wild card form of import --- ``import *`` --- is used in a\nfunction and the function contains or is a nested block with free\nvariables, the compiler will raise a ``SyntaxError``.\n\nThe ``eval()`` and ``exec()`` functions do not have access to the full\nenvironment for resolving names. Names may be resolved in the local\nand global namespaces of the caller. Free variables are not resolved\nin the nearest enclosing namespace, but in the global namespace. [1]\nThe ``exec()`` and ``eval()`` functions have optional arguments to\noverride the global and local namespace. If only one namespace is\nspecified, it is used for both.\n', - 'else': '\nThe ``if`` statement\n********************\n\nThe ``if`` statement is used for conditional execution:\n\n if_stmt ::= "if" expression ":" suite\n ( "elif" expression ":" suite )*\n ["else" ":" suite]\n\nIt selects exactly one of the suites by evaluating the expressions one\nby one until one is found to be true (see section *Boolean operations*\nfor the definition of true and false); then that suite is executed\n(and no other part of the ``if`` statement is executed or evaluated).\nIf all expressions are false, the suite of the ``else`` clause, if\npresent, is executed.\n', - 'exceptions': '\nExceptions\n**********\n\nExceptions are a means of breaking out of the normal flow of control\nof a code block in order to handle errors or other exceptional\nconditions. An exception is *raised* at the point where the error is\ndetected; it may be *handled* by the surrounding code block or by any\ncode block that directly or indirectly invoked the code block where\nthe error occurred.\n\nThe Python interpreter raises an exception when it detects a run-time\nerror (such as division by zero). A Python program can also\nexplicitly raise an exception with the ``raise`` statement. Exception\nhandlers are specified with the ``try`` ... ``except`` statement. The\n``finally`` clause of such a statement can be used to specify cleanup\ncode which does not handle the exception, but is executed whether an\nexception occurred or not in the preceding code.\n\nPython uses the "termination" model of error handling: an exception\nhandler can find out what happened and continue execution at an outer\nlevel, but it cannot repair the cause of the error and retry the\nfailing operation (except by re-entering the offending piece of code\nfrom the top).\n\nWhen an exception is not handled at all, the interpreter terminates\nexecution of the program, or returns to its interactive main loop. In\neither case, it prints a stack backtrace, except when the exception is\n``SystemExit``.\n\nExceptions are identified by class instances. The ``except`` clause\nis selected depending on the class of the instance: it must reference\nthe class of the instance or a base class thereof. The instance can\nbe received by the handler and can carry additional information about\nthe exceptional condition.\n\nNote: Exception messages are not part of the Python API. Their contents\n may change from one version of Python to the next without warning\n and should not be relied on by code which will run under multiple\n versions of the interpreter.\n\nSee also the description of the ``try`` statement in section *The try\nstatement* and ``raise`` statement in section *The raise statement*.\n\n-[ Footnotes ]-\n\n[1] This limitation occurs because the code that is executed by these\n operations is not available at the time the module is compiled.\n', - 'execmodel': '\nExecution model\n***************\n\n\nNaming and binding\n==================\n\n*Names* refer to objects. Names are introduced by name binding\noperations. Each occurrence of a name in the program text refers to\nthe *binding* of that name established in the innermost function block\ncontaining the use.\n\nA *block* is a piece of Python program text that is executed as a\nunit. The following are blocks: a module, a function body, and a class\ndefinition. Each command typed interactively is a block. A script\nfile (a file given as standard input to the interpreter or specified\non the interpreter command line the first argument) is a code block.\nA script command (a command specified on the interpreter command line\nwith the \'**-c**\' option) is a code block. The string argument passed\nto the built-in functions ``eval()`` and ``exec()`` is a code block.\n\nA code block is executed in an *execution frame*. A frame contains\nsome administrative information (used for debugging) and determines\nwhere and how execution continues after the code block\'s execution has\ncompleted.\n\nA *scope* defines the visibility of a name within a block. If a local\nvariable is defined in a block, its scope includes that block. If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name. The scope of names defined in a\nclass block is limited to the class block; it does not extend to the\ncode blocks of methods -- this includes comprehensions and generator\nexpressions since they are implemented using a function scope. This\nmeans that the following will fail:\n\n class A:\n a = 42\n b = list(a + i for i in range(10))\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope. The set of all such scopes visible to a code block\nis called the block\'s *environment*.\n\nIf a name is bound in a block, it is a local variable of that block,\nunless declared as ``nonlocal``. If a name is bound at the module\nlevel, it is a global variable. (The variables of the module code\nblock are local and global.) If a variable is used in a code block\nbut not defined there, it is a *free variable*.\n\nWhen a name is not found at all, a ``NameError`` exception is raised.\nIf the name refers to a local variable that has not been bound, a\n``UnboundLocalError`` exception is raised. ``UnboundLocalError`` is a\nsubclass of ``NameError``.\n\nThe following constructs bind names: formal parameters to functions,\n``import`` statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, ``for`` loop header, or\nafter ``as`` in a ``with`` statement or ``except`` clause. The\n``import`` statement of the form ``from ... import *`` binds all names\ndefined in the imported module, except those beginning with an\nunderscore. This form may only be used at the module level.\n\nA target occurring in a ``del`` statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name).\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block. This can lead to errors when a name is used within a\nblock before it is bound. This rule is subtle. Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block. The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the ``global`` statement occurs within a block, all uses of the\nname specified in the statement refer to the binding of that name in\nthe top-level namespace. Names are resolved in the top-level\nnamespace by searching the global namespace, i.e. the namespace of the\nmodule containing the code block, and the builtins namespace, the\nnamespace of the module ``builtins``. The global namespace is\nsearched first. If the name is not found there, the builtins\nnamespace is searched. The global statement must precede all uses of\nthe name.\n\nThe builtins namespace associated with the execution of a code block\nis actually found by looking up the name ``__builtins__`` in its\nglobal namespace; this should be a dictionary or a module (in the\nlatter case the module\'s dictionary is used). By default, when in the\n``__main__`` module, ``__builtins__`` is the built-in module\n``builtins``; when in any other module, ``__builtins__`` is an alias\nfor the dictionary of the ``builtins`` module itself.\n``__builtins__`` can be set to a user-created dictionary to create a\nweak form of restricted execution.\n\n**CPython implementation detail:** Users should not touch\n``__builtins__``; it is strictly an implementation detail. Users\nwanting to override values in the builtins namespace should ``import``\nthe ``builtins`` module and modify its attributes appropriately.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported. The main module for a script is always called\n``__main__``.\n\nThe ``global`` statement has the same scope as a name binding\noperation in the same block. If the nearest enclosing scope for a\nfree variable contains a global statement, the free variable is\ntreated as a global.\n\nA class definition is an executable statement that may use and define\nnames. These references follow the normal rules for name resolution.\nThe namespace of the class definition becomes the attribute dictionary\nof the class. Names defined at the class scope are not visible in\nmethods.\n\n\nInteraction with dynamic features\n---------------------------------\n\nThere are several cases where Python statements are illegal when used\nin conjunction with nested scopes that contain free variables.\n\nIf a variable is referenced in an enclosing scope, it is illegal to\ndelete the name. An error will be reported at compile time.\n\nIf the wild card form of import --- ``import *`` --- is used in a\nfunction and the function contains or is a nested block with free\nvariables, the compiler will raise a ``SyntaxError``.\n\nThe ``eval()`` and ``exec()`` functions do not have access to the full\nenvironment for resolving names. Names may be resolved in the local\nand global namespaces of the caller. Free variables are not resolved\nin the nearest enclosing namespace, but in the global namespace. [1]\nThe ``exec()`` and ``eval()`` functions have optional arguments to\noverride the global and local namespace. If only one namespace is\nspecified, it is used for both.\n\n\nExceptions\n==========\n\nExceptions are a means of breaking out of the normal flow of control\nof a code block in order to handle errors or other exceptional\nconditions. An exception is *raised* at the point where the error is\ndetected; it may be *handled* by the surrounding code block or by any\ncode block that directly or indirectly invoked the code block where\nthe error occurred.\n\nThe Python interpreter raises an exception when it detects a run-time\nerror (such as division by zero). A Python program can also\nexplicitly raise an exception with the ``raise`` statement. Exception\nhandlers are specified with the ``try`` ... ``except`` statement. The\n``finally`` clause of such a statement can be used to specify cleanup\ncode which does not handle the exception, but is executed whether an\nexception occurred or not in the preceding code.\n\nPython uses the "termination" model of error handling: an exception\nhandler can find out what happened and continue execution at an outer\nlevel, but it cannot repair the cause of the error and retry the\nfailing operation (except by re-entering the offending piece of code\nfrom the top).\n\nWhen an exception is not handled at all, the interpreter terminates\nexecution of the program, or returns to its interactive main loop. In\neither case, it prints a stack backtrace, except when the exception is\n``SystemExit``.\n\nExceptions are identified by class instances. The ``except`` clause\nis selected depending on the class of the instance: it must reference\nthe class of the instance or a base class thereof. The instance can\nbe received by the handler and can carry additional information about\nthe exceptional condition.\n\nNote: Exception messages are not part of the Python API. Their contents\n may change from one version of Python to the next without warning\n and should not be relied on by code which will run under multiple\n versions of the interpreter.\n\nSee also the description of the ``try`` statement in section *The try\nstatement* and ``raise`` statement in section *The raise statement*.\n\n-[ Footnotes ]-\n\n[1] This limitation occurs because the code that is executed by these\n operations is not available at the time the module is compiled.\n', - 'exprlists': '\nExpression lists\n****************\n\n expression_list ::= expression ( "," expression )* [","]\n\nAn expression list containing at least one comma yields a tuple. The\nlength of the tuple is the number of expressions in the list. The\nexpressions are evaluated from left to right.\n\nThe trailing comma is required only to create a single tuple (a.k.a. a\n*singleton*); it is optional in all other cases. A single expression\nwithout a trailing comma doesn\'t create a tuple, but rather yields the\nvalue of that expression. (To create an empty tuple, use an empty pair\nof parentheses: ``()``.)\n', - 'floating': '\nFloating point literals\n***********************\n\nFloating point literals are described by the following lexical\ndefinitions:\n\n floatnumber ::= pointfloat | exponentfloat\n pointfloat ::= [intpart] fraction | intpart "."\n exponentfloat ::= (intpart | pointfloat) exponent\n intpart ::= digit+\n fraction ::= "." digit+\n exponent ::= ("e" | "E") ["+" | "-"] digit+\n\nNote that the integer and exponent parts are always interpreted using\nradix 10. For example, ``077e010`` is legal, and denotes the same\nnumber as ``77e10``. The allowed range of floating point literals is\nimplementation-dependent. Some examples of floating point literals:\n\n 3.14 10. .001 1e100 3.14e-10 0e0\n\nNote that numeric literals do not include a sign; a phrase like ``-1``\nis actually an expression composed of the unary operator ``-`` and the\nliteral ``1``.\n', - 'for': '\nThe ``for`` statement\n*********************\n\nThe ``for`` statement is used to iterate over the elements of a\nsequence (such as a string, tuple or list) or other iterable object:\n\n for_stmt ::= "for" target_list "in" expression_list ":" suite\n ["else" ":" suite]\n\nThe expression list is evaluated once; it should yield an iterable\nobject. An iterator is created for the result of the\n``expression_list``. The suite is then executed once for each item\nprovided by the iterator, in the order of ascending indices. Each\nitem in turn is assigned to the target list using the standard rules\nfor assignments (see *Assignment statements*), and then the suite is\nexecuted. When the items are exhausted (which is immediately when the\nsequence is empty or an iterator raises a ``StopIteration``\nexception), the suite in the ``else`` clause, if present, is executed,\nand the loop terminates.\n\nA ``break`` statement executed in the first suite terminates the loop\nwithout executing the ``else`` clause\'s suite. A ``continue``\nstatement executed in the first suite skips the rest of the suite and\ncontinues with the next item, or with the ``else`` clause if there was\nno next item.\n\nThe suite may assign to the variable(s) in the target list; this does\nnot affect the next item assigned to it.\n\nNames in the target list are not deleted when the loop is finished,\nbut if the sequence is empty, it will not have been assigned to at all\nby the loop. Hint: the built-in function ``range()`` returns an\niterator of integers suitable to emulate the effect of Pascal\'s ``for\ni := a to b do``; e.g., ``list(range(3))`` returns the list ``[0, 1,\n2]``.\n\nNote: There is a subtlety when the sequence is being modified by the loop\n (this can only occur for mutable sequences, i.e. lists). An\n internal counter is used to keep track of which item is used next,\n and this is incremented on each iteration. When this counter has\n reached the length of the sequence the loop terminates. This means\n that if the suite deletes the current (or a previous) item from the\n sequence, the next item will be skipped (since it gets the index of\n the current item which has already been treated). Likewise, if the\n suite inserts an item in the sequence before the current item, the\n current item will be treated again the next time through the loop.\n This can lead to nasty bugs that can be avoided by making a\n temporary copy using a slice of the whole sequence, e.g.,\n\n for x in a[:]:\n if x < 0: a.remove(x)\n', - 'formatstrings': '\nFormat String Syntax\n********************\n\nThe ``str.format()`` method and the ``Formatter`` class share the same\nsyntax for format strings (although in the case of ``Formatter``,\nsubclasses can define their own format string syntax).\n\nFormat strings contain "replacement fields" surrounded by curly braces\n``{}``. Anything that is not contained in braces is considered literal\ntext, which is copied unchanged to the output. If you need to include\na brace character in the literal text, it can be escaped by doubling:\n``{{`` and ``}}``.\n\nThe grammar for a replacement field is as follows:\n\n replacement_field ::= "{" [field_name] ["!" conversion] [":" format_spec] "}"\n field_name ::= arg_name ("." attribute_name | "[" element_index "]")*\n arg_name ::= [identifier | integer]\n attribute_name ::= identifier\n element_index ::= integer | index_string\n index_string ::= <any source character except "]"> +\n conversion ::= "r" | "s" | "a"\n format_spec ::= <described in the next section>\n\nIn less formal terms, the replacement field can start with a\n*field_name* that specifies the object whose value is to be formatted\nand inserted into the output instead of the replacement field. The\n*field_name* is optionally followed by a *conversion* field, which is\npreceded by an exclamation point ``\'!\'``, and a *format_spec*, which\nis preceded by a colon ``\':\'``. These specify a non-default format\nfor the replacement value.\n\nSee also the *Format Specification Mini-Language* section.\n\nThe *field_name* itself begins with an *arg_name* that is either a\nnumber or a keyword. If it\'s a number, it refers to a positional\nargument, and if it\'s a keyword, it refers to a named keyword\nargument. If the numerical arg_names in a format string are 0, 1, 2,\n... in sequence, they can all be omitted (not just some) and the\nnumbers 0, 1, 2, ... will be automatically inserted in that order.\nBecause *arg_name* is not quote-delimited, it is not possible to\nspecify arbitrary dictionary keys (e.g., the strings ``\'10\'`` or\n``\':-]\'``) within a format string. The *arg_name* can be followed by\nany number of index or attribute expressions. An expression of the\nform ``\'.name\'`` selects the named attribute using ``getattr()``,\nwhile an expression of the form ``\'[index]\'`` does an index lookup\nusing ``__getitem__()``.\n\nChanged in version 3.1: The positional argument specifiers can be\nomitted, so ``\'{} {}\'`` is equivalent to ``\'{0} {1}\'``.\n\nSome simple format string examples:\n\n "First, thou shalt count to {0}" # References first positional argument\n "Bring me a {}" # Implicitly references the first positional argument\n "From {} to {}" # Same as "From {0} to {1}"\n "My quest is {name}" # References keyword argument \'name\'\n "Weight in tons {0.weight}" # \'weight\' attribute of first positional arg\n "Units destroyed: {players[0]}" # First element of keyword argument \'players\'.\n\nThe *conversion* field causes a type coercion before formatting.\nNormally, the job of formatting a value is done by the\n``__format__()`` method of the value itself. However, in some cases\nit is desirable to force a type to be formatted as a string,\noverriding its own definition of formatting. By converting the value\nto a string before calling ``__format__()``, the normal formatting\nlogic is bypassed.\n\nThree conversion flags are currently supported: ``\'!s\'`` which calls\n``str()`` on the value, ``\'!r\'`` which calls ``repr()`` and ``\'!a\'``\nwhich calls ``ascii()``.\n\nSome examples:\n\n "Harold\'s a clever {0!s}" # Calls str() on the argument first\n "Bring out the holy {name!r}" # Calls repr() on the argument first\n "More {!a}" # Calls ascii() on the argument first\n\nThe *format_spec* field contains a specification of how the value\nshould be presented, including such details as field width, alignment,\npadding, decimal precision and so on. Each value type can define its\nown "formatting mini-language" or interpretation of the *format_spec*.\n\nMost built-in types support a common formatting mini-language, which\nis described in the next section.\n\nA *format_spec* field can also include nested replacement fields\nwithin it. These nested replacement fields can contain only a field\nname; conversion flags and format specifications are not allowed. The\nreplacement fields within the format_spec are substituted before the\n*format_spec* string is interpreted. This allows the formatting of a\nvalue to be dynamically specified.\n\nSee the *Format examples* section for some examples.\n\n\nFormat Specification Mini-Language\n==================================\n\n"Format specifications" are used within replacement fields contained\nwithin a format string to define how individual values are presented\n(see *Format String Syntax*). They can also be passed directly to the\nbuilt-in ``format()`` function. Each formattable type may define how\nthe format specification is to be interpreted.\n\nMost built-in types implement the following options for format\nspecifications, although some of the formatting options are only\nsupported by the numeric types.\n\nA general convention is that an empty format string (``""``) produces\nthe same result as if you had called ``str()`` on the value. A non-\nempty format string typically modifies the result.\n\nThe general form of a *standard format specifier* is:\n\n format_spec ::= [[fill]align][sign][#][0][width][,][.precision][type]\n fill ::= <any character>\n align ::= "<" | ">" | "=" | "^"\n sign ::= "+" | "-" | " "\n width ::= integer\n precision ::= integer\n type ::= "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"\n\nIf a valid *align* value is specified, it can be preceded by a *fill*\ncharacter that can be any character and defaults to a space if\nomitted. Note that it is not possible to use ``{`` and ``}`` as *fill*\nchar while using the ``str.format()`` method; this limitation however\ndoesn\'t affect the ``format()`` function.\n\nThe meaning of the various alignment options is as follows:\n\n +-----------+------------------------------------------------------------+\n | Option | Meaning |\n +===========+============================================================+\n | ``\'<\'`` | Forces the field to be left-aligned within the available |\n | | space (this is the default for most objects). |\n +-----------+------------------------------------------------------------+\n | ``\'>\'`` | Forces the field to be right-aligned within the available |\n | | space (this is the default for numbers). |\n +-----------+------------------------------------------------------------+\n | ``\'=\'`` | Forces the padding to be placed after the sign (if any) |\n | | but before the digits. This is used for printing fields |\n | | in the form \'+000000120\'. This alignment option is only |\n | | valid for numeric types. |\n +-----------+------------------------------------------------------------+\n | ``\'^\'`` | Forces the field to be centered within the available |\n | | space. |\n +-----------+------------------------------------------------------------+\n\nNote that unless a minimum field width is defined, the field width\nwill always be the same size as the data to fill it, so that the\nalignment option has no meaning in this case.\n\nThe *sign* option is only valid for number types, and can be one of\nthe following:\n\n +-----------+------------------------------------------------------------+\n | Option | Meaning |\n +===========+============================================================+\n | ``\'+\'`` | indicates that a sign should be used for both positive as |\n | | well as negative numbers. |\n +-----------+------------------------------------------------------------+\n | ``\'-\'`` | indicates that a sign should be used only for negative |\n | | numbers (this is the default behavior). |\n +-----------+------------------------------------------------------------+\n | space | indicates that a leading space should be used on positive |\n | | numbers, and a minus sign on negative numbers. |\n +-----------+------------------------------------------------------------+\n\nThe ``\'#\'`` option causes the "alternate form" to be used for the\nconversion. The alternate form is defined differently for different\ntypes. This option is only valid for integer, float, complex and\nDecimal types. For integers, when binary, octal, or hexadecimal output\nis used, this option adds the prefix respective ``\'0b\'``, ``\'0o\'``, or\n``\'0x\'`` to the output value. For floats, complex and Decimal the\nalternate form causes the result of the conversion to always contain a\ndecimal-point character, even if no digits follow it. Normally, a\ndecimal-point character appears in the result of these conversions\nonly if a digit follows it. In addition, for ``\'g\'`` and ``\'G\'``\nconversions, trailing zeros are not removed from the result.\n\nThe ``\',\'`` option signals the use of a comma for a thousands\nseparator. For a locale aware separator, use the ``\'n\'`` integer\npresentation type instead.\n\nChanged in version 3.1: Added the ``\',\'`` option (see also **PEP\n378**).\n\n*width* is a decimal integer defining the minimum field width. If not\nspecified, then the field width will be determined by the content.\n\nPreceding the *width* field by a zero (``\'0\'``) character enables\nsign-aware zero-padding for numeric types. This is equivalent to a\n*fill* character of ``\'0\'`` with an *alignment* type of ``\'=\'``.\n\nThe *precision* is a decimal number indicating how many digits should\nbe displayed after the decimal point for a floating point value\nformatted with ``\'f\'`` and ``\'F\'``, or before and after the decimal\npoint for a floating point value formatted with ``\'g\'`` or ``\'G\'``.\nFor non-number types the field indicates the maximum field size - in\nother words, how many characters will be used from the field content.\nThe *precision* is not allowed for integer values.\n\nFinally, the *type* determines how the data should be presented.\n\nThe available string presentation types are:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | ``\'s\'`` | String format. This is the default type for strings and |\n | | may be omitted. |\n +-----------+------------------------------------------------------------+\n | None | The same as ``\'s\'``. |\n +-----------+------------------------------------------------------------+\n\nThe available integer presentation types are:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | ``\'b\'`` | Binary format. Outputs the number in base 2. |\n +-----------+------------------------------------------------------------+\n | ``\'c\'`` | Character. Converts the integer to the corresponding |\n | | unicode character before printing. |\n +-----------+------------------------------------------------------------+\n | ``\'d\'`` | Decimal Integer. Outputs the number in base 10. |\n +-----------+------------------------------------------------------------+\n | ``\'o\'`` | Octal format. Outputs the number in base 8. |\n +-----------+------------------------------------------------------------+\n | ``\'x\'`` | Hex format. Outputs the number in base 16, using lower- |\n | | case letters for the digits above 9. |\n +-----------+------------------------------------------------------------+\n | ``\'X\'`` | Hex format. Outputs the number in base 16, using upper- |\n | | case letters for the digits above 9. |\n +-----------+------------------------------------------------------------+\n | ``\'n\'`` | Number. This is the same as ``\'d\'``, except that it uses |\n | | the current locale setting to insert the appropriate |\n | | number separator characters. |\n +-----------+------------------------------------------------------------+\n | None | The same as ``\'d\'``. |\n +-----------+------------------------------------------------------------+\n\nIn addition to the above presentation types, integers can be formatted\nwith the floating point presentation types listed below (except\n``\'n\'`` and None). When doing so, ``float()`` is used to convert the\ninteger to a floating point number before formatting.\n\nThe available presentation types for floating point and decimal values\nare:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | ``\'e\'`` | Exponent notation. Prints the number in scientific |\n | | notation using the letter \'e\' to indicate the exponent. |\n | | The default precision is ``6``. |\n +-----------+------------------------------------------------------------+\n | ``\'E\'`` | Exponent notation. Same as ``\'e\'`` except it uses an upper |\n | | case \'E\' as the separator character. |\n +-----------+------------------------------------------------------------+\n | ``\'f\'`` | Fixed point. Displays the number as a fixed-point number. |\n | | The default precision is ``6``. |\n +-----------+------------------------------------------------------------+\n | ``\'F\'`` | Fixed point. Same as ``\'f\'``, but converts ``nan`` to |\n | | ``NAN`` and ``inf`` to ``INF``. |\n +-----------+------------------------------------------------------------+\n | ``\'g\'`` | General format. For a given precision ``p >= 1``, this |\n | | rounds the number to ``p`` significant digits and then |\n | | formats the result in either fixed-point format or in |\n | | scientific notation, depending on its magnitude. The |\n | | precise rules are as follows: suppose that the result |\n | | formatted with presentation type ``\'e\'`` and precision |\n | | ``p-1`` would have exponent ``exp``. Then if ``-4 <= exp |\n | | < p``, the number is formatted with presentation type |\n | | ``\'f\'`` and precision ``p-1-exp``. Otherwise, the number |\n | | is formatted with presentation type ``\'e\'`` and precision |\n | | ``p-1``. In both cases insignificant trailing zeros are |\n | | removed from the significand, and the decimal point is |\n | | also removed if there are no remaining digits following |\n | | it. Positive and negative infinity, positive and negative |\n | | zero, and nans, are formatted as ``inf``, ``-inf``, ``0``, |\n | | ``-0`` and ``nan`` respectively, regardless of the |\n | | precision. A precision of ``0`` is treated as equivalent |\n | | to a precision of ``1``. The default precision is ``6``. |\n +-----------+------------------------------------------------------------+\n | ``\'G\'`` | General format. Same as ``\'g\'`` except switches to ``\'E\'`` |\n | | if the number gets too large. The representations of |\n | | infinity and NaN are uppercased, too. |\n +-----------+------------------------------------------------------------+\n | ``\'n\'`` | Number. This is the same as ``\'g\'``, except that it uses |\n | | the current locale setting to insert the appropriate |\n | | number separator characters. |\n +-----------+------------------------------------------------------------+\n | ``\'%\'`` | Percentage. Multiplies the number by 100 and displays in |\n | | fixed (``\'f\'``) format, followed by a percent sign. |\n +-----------+------------------------------------------------------------+\n | None | Similar to ``\'g\'``, except with at least one digit past |\n | | the decimal point and a default precision of 12. This is |\n | | intended to match ``str()``, except you can add the other |\n | | format modifiers. |\n +-----------+------------------------------------------------------------+\n\n\nFormat examples\n===============\n\nThis section contains examples of the new format syntax and comparison\nwith the old ``%``-formatting.\n\nIn most of the cases the syntax is similar to the old\n``%``-formatting, with the addition of the ``{}`` and with ``:`` used\ninstead of ``%``. For example, ``\'%03.2f\'`` can be translated to\n``\'{:03.2f}\'``.\n\nThe new format syntax also supports new and different options, shown\nin the follow examples.\n\nAccessing arguments by position:\n\n >>> \'{0}, {1}, {2}\'.format(\'a\', \'b\', \'c\')\n \'a, b, c\'\n >>> \'{}, {}, {}\'.format(\'a\', \'b\', \'c\') # 3.1+ only\n \'a, b, c\'\n >>> \'{2}, {1}, {0}\'.format(\'a\', \'b\', \'c\')\n \'c, b, a\'\n >>> \'{2}, {1}, {0}\'.format(*\'abc\') # unpacking argument sequence\n \'c, b, a\'\n >>> \'{0}{1}{0}\'.format(\'abra\', \'cad\') # arguments\' indices can be repeated\n \'abracadabra\'\n\nAccessing arguments by name:\n\n >>> \'Coordinates: {latitude}, {longitude}\'.format(latitude=\'37.24N\', longitude=\'-115.81W\')\n \'Coordinates: 37.24N, -115.81W\'\n >>> coord = {\'latitude\': \'37.24N\', \'longitude\': \'-115.81W\'}\n >>> \'Coordinates: {latitude}, {longitude}\'.format(**coord)\n \'Coordinates: 37.24N, -115.81W\'\n\nAccessing arguments\' attributes:\n\n >>> c = 3-5j\n >>> (\'The complex number {0} is formed from the real part {0.real} \'\n ... \'and the imaginary part {0.imag}.\').format(c)\n \'The complex number (3-5j) is formed from the real part 3.0 and the imaginary part -5.0.\'\n >>> class Point:\n ... def __init__(self, x, y):\n ... self.x, self.y = x, y\n ... def __str__(self):\n ... return \'Point({self.x}, {self.y})\'.format(self=self)\n ...\n >>> str(Point(4, 2))\n \'Point(4, 2)\'\n\nAccessing arguments\' items:\n\n >>> coord = (3, 5)\n >>> \'X: {0[0]}; Y: {0[1]}\'.format(coord)\n \'X: 3; Y: 5\'\n\nReplacing ``%s`` and ``%r``:\n\n >>> "repr() shows quotes: {!r}; str() doesn\'t: {!s}".format(\'test1\', \'test2\')\n "repr() shows quotes: \'test1\'; str() doesn\'t: test2"\n\nAligning the text and specifying a width:\n\n >>> \'{:<30}\'.format(\'left aligned\')\n \'left aligned \'\n >>> \'{:>30}\'.format(\'right aligned\')\n \' right aligned\'\n >>> \'{:^30}\'.format(\'centered\')\n \' centered \'\n >>> \'{:*^30}\'.format(\'centered\') # use \'*\' as a fill char\n \'***********centered***********\'\n\nReplacing ``%+f``, ``%-f``, and ``% f`` and specifying a sign:\n\n >>> \'{:+f}; {:+f}\'.format(3.14, -3.14) # show it always\n \'+3.140000; -3.140000\'\n >>> \'{: f}; {: f}\'.format(3.14, -3.14) # show a space for positive numbers\n \' 3.140000; -3.140000\'\n >>> \'{:-f}; {:-f}\'.format(3.14, -3.14) # show only the minus -- same as \'{:f}; {:f}\'\n \'3.140000; -3.140000\'\n\nReplacing ``%x`` and ``%o`` and converting the value to different\nbases:\n\n >>> # format also supports binary numbers\n >>> "int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}".format(42)\n \'int: 42; hex: 2a; oct: 52; bin: 101010\'\n >>> # with 0x, 0o, or 0b as prefix:\n >>> "int: {0:d}; hex: {0:#x}; oct: {0:#o}; bin: {0:#b}".format(42)\n \'int: 42; hex: 0x2a; oct: 0o52; bin: 0b101010\'\n\nUsing the comma as a thousands separator:\n\n >>> \'{:,}\'.format(1234567890)\n \'1,234,567,890\'\n\nExpressing a percentage:\n\n >>> points = 19\n >>> total = 22\n >>> \'Correct answers: {:.2%}\'.format(points/total)\n \'Correct answers: 86.36%\'\n\nUsing type-specific formatting:\n\n >>> import datetime\n >>> d = datetime.datetime(2010, 7, 4, 12, 15, 58)\n >>> \'{:%Y-%m-%d %H:%M:%S}\'.format(d)\n \'2010-07-04 12:15:58\'\n\nNesting arguments and more complex examples:\n\n >>> for align, text in zip(\'<^>\', [\'left\', \'center\', \'right\']):\n ... \'{0:{fill}{align}16}\'.format(text, fill=align, align=align)\n ...\n \'left<<<<<<<<<<<<\'\n \'^^^^^center^^^^^\'\n \'>>>>>>>>>>>right\'\n >>>\n >>> octets = [192, 168, 0, 1]\n >>> \'{:02X}{:02X}{:02X}{:02X}\'.format(*octets)\n \'C0A80001\'\n >>> int(_, 16)\n 3232235521\n >>>\n >>> width = 5\n >>> for num in range(5,12): #doctest: +NORMALIZE_WHITESPACE\n ... for base in \'dXob\':\n ... print(\'{0:{width}{base}}\'.format(num, base=base, width=width), end=\' \')\n ... print()\n ...\n 5 5 5 101\n 6 6 6 110\n 7 7 7 111\n 8 8 10 1000\n 9 9 11 1001\n 10 A 12 1010\n 11 B 13 1011\n', - 'function': '\nFunction definitions\n********************\n\nA function definition defines a user-defined function object (see\nsection *The standard type hierarchy*):\n\n funcdef ::= [decorators] "def" funcname "(" [parameter_list] ")" ["->" expression] ":" suite\n decorators ::= decorator+\n decorator ::= "@" dotted_name ["(" [parameter_list [","]] ")"] NEWLINE\n dotted_name ::= identifier ("." identifier)*\n parameter_list ::= (defparameter ",")*\n ( "*" [parameter] ("," defparameter)* ["," "**" parameter]\n | "**" parameter\n | defparameter [","] )\n parameter ::= identifier [":" expression]\n defparameter ::= parameter ["=" expression]\n funcname ::= identifier\n\nA function definition is an executable statement. Its execution binds\nthe function name in the current local namespace to a function object\n(a wrapper around the executable code for the function). This\nfunction object contains a reference to the current global namespace\nas the global namespace to be used when the function is called.\n\nThe function definition does not execute the function body; this gets\nexecuted only when the function is called. [3]\n\nA function definition may be wrapped by one or more *decorator*\nexpressions. Decorator expressions are evaluated when the function is\ndefined, in the scope that contains the function definition. The\nresult must be a callable, which is invoked with the function object\nas the only argument. The returned value is bound to the function name\ninstead of the function object. Multiple decorators are applied in\nnested fashion. For example, the following code\n\n @f1(arg)\n @f2\n def func(): pass\n\nis equivalent to\n\n def func(): pass\n func = f1(arg)(f2(func))\n\nWhen one or more *parameters* have the form *parameter* ``=``\n*expression*, the function is said to have "default parameter values."\nFor a parameter with a default value, the corresponding *argument* may\nbe omitted from a call, in which case the parameter\'s default value is\nsubstituted. If a parameter has a default value, all following\nparameters up until the "``*``" must also have a default value ---\nthis is a syntactic restriction that is not expressed by the grammar.\n\n**Default parameter values are evaluated from left to right when the\nfunction definition is executed.** This means that the expression is\nevaluated once, when the function is defined, and that the same "pre-\ncomputed" value is used for each call. This is especially important\nto understand when a default parameter is a mutable object, such as a\nlist or a dictionary: if the function modifies the object (e.g. by\nappending an item to a list), the default value is in effect modified.\nThis is generally not what was intended. A way around this is to use\n``None`` as the default, and explicitly test for it in the body of the\nfunction, e.g.:\n\n def whats_on_the_telly(penguin=None):\n if penguin is None:\n penguin = []\n penguin.append("property of the zoo")\n return penguin\n\nFunction call semantics are described in more detail in section\n*Calls*. A function call always assigns values to all parameters\nmentioned in the parameter list, either from position arguments, from\nkeyword arguments, or from default values. If the form\n"``*identifier``" is present, it is initialized to a tuple receiving\nany excess positional parameters, defaulting to the empty tuple. If\nthe form "``**identifier``" is present, it is initialized to a new\ndictionary receiving any excess keyword arguments, defaulting to a new\nempty dictionary. Parameters after "``*``" or "``*identifier``" are\nkeyword-only parameters and may only be passed used keyword arguments.\n\nParameters may have annotations of the form "``: expression``"\nfollowing the parameter name. Any parameter may have an annotation\neven those of the form ``*identifier`` or ``**identifier``. Functions\nmay have "return" annotation of the form "``-> expression``" after the\nparameter list. These annotations can be any valid Python expression\nand are evaluated when the function definition is executed.\nAnnotations may be evaluated in a different order than they appear in\nthe source code. The presence of annotations does not change the\nsemantics of a function. The annotation values are available as\nvalues of a dictionary keyed by the parameters\' names in the\n``__annotations__`` attribute of the function object.\n\nIt is also possible to create anonymous functions (functions not bound\nto a name), for immediate use in expressions. This uses lambda\nexpressions, described in section *Lambdas*. Note that the lambda\nexpression is merely a shorthand for a simplified function definition;\na function defined in a "``def``" statement can be passed around or\nassigned to another name just like a function defined by a lambda\nexpression. The "``def``" form is actually more powerful since it\nallows the execution of multiple statements and annotations.\n\n**Programmer\'s note:** Functions are first-class objects. A "``def``"\nstatement executed inside a function definition defines a local\nfunction that can be returned or passed around. Free variables used\nin the nested function can access the local variables of the function\ncontaining the def. See section *Naming and binding* for details.\n\nSee also:\n\n **PEP 3107** - Function Annotations\n The original specification for function annotations.\n', - 'global': '\nThe ``global`` statement\n************************\n\n global_stmt ::= "global" identifier ("," identifier)*\n\nThe ``global`` statement is a declaration which holds for the entire\ncurrent code block. It means that the listed identifiers are to be\ninterpreted as globals. It would be impossible to assign to a global\nvariable without ``global``, although free variables may refer to\nglobals without being declared global.\n\nNames listed in a ``global`` statement must not be used in the same\ncode block textually preceding that ``global`` statement.\n\nNames listed in a ``global`` statement must not be defined as formal\nparameters or in a ``for`` loop control target, ``class`` definition,\nfunction definition, or ``import`` statement.\n\n**CPython implementation detail:** The current implementation does not\nenforce the latter two restrictions, but programs should not abuse\nthis freedom, as future implementations may enforce them or silently\nchange the meaning of the program.\n\n**Programmer\'s note:** the ``global`` is a directive to the parser.\nIt applies only to code parsed at the same time as the ``global``\nstatement. In particular, a ``global`` statement contained in a string\nor code object supplied to the built-in ``exec()`` function does not\naffect the code block *containing* the function call, and code\ncontained in such a string is unaffected by ``global`` statements in\nthe code containing the function call. The same applies to the\n``eval()`` and ``compile()`` functions.\n', - 'id-classes': '\nReserved classes of identifiers\n*******************************\n\nCertain classes of identifiers (besides keywords) have special\nmeanings. These classes are identified by the patterns of leading and\ntrailing underscore characters:\n\n``_*``\n Not imported by ``from module import *``. The special identifier\n ``_`` is used in the interactive interpreter to store the result of\n the last evaluation; it is stored in the ``builtins`` module. When\n not in interactive mode, ``_`` has no special meaning and is not\n defined. See section *The import statement*.\n\n Note: The name ``_`` is often used in conjunction with\n internationalization; refer to the documentation for the\n ``gettext`` module for more information on this convention.\n\n``__*__``\n System-defined names. These names are defined by the interpreter\n and its implementation (including the standard library). Current\n system names are discussed in the *Special method names* section\n and elsewhere. More will likely be defined in future versions of\n Python. *Any* use of ``__*__`` names, in any context, that does\n not follow explicitly documented use, is subject to breakage\n without warning.\n\n``__*``\n Class-private names. Names in this category, when used within the\n context of a class definition, are re-written to use a mangled form\n to help avoid name clashes between "private" attributes of base and\n derived classes. See section *Identifiers (Names)*.\n', - 'identifiers': '\nIdentifiers and keywords\n************************\n\nIdentifiers (also referred to as *names*) are described by the\nfollowing lexical definitions.\n\nThe syntax of identifiers in Python is based on the Unicode standard\nannex UAX-31, with elaboration and changes as defined below; see also\n**PEP 3131** for further details.\n\nWithin the ASCII range (U+0001..U+007F), the valid characters for\nidentifiers are the same as in Python 2.x: the uppercase and lowercase\nletters ``A`` through ``Z``, the underscore ``_`` and, except for the\nfirst character, the digits ``0`` through ``9``.\n\nPython 3.0 introduces additional characters from outside the ASCII\nrange (see **PEP 3131**). For these characters, the classification\nuses the version of the Unicode Character Database as included in the\n``unicodedata`` module.\n\nIdentifiers are unlimited in length. Case is significant.\n\n identifier ::= xid_start xid_continue*\n id_start ::= <all characters in general categories Lu, Ll, Lt, Lm, Lo, Nl, the underscore, and characters with the Other_ID_Start property>\n id_continue ::= <all characters in id_start, plus characters in the categories Mn, Mc, Nd, Pc and others with the Other_ID_Continue property>\n xid_start ::= <all characters in id_start whose NFKC normalization is in "id_start xid_continue*">\n xid_continue ::= <all characters in id_continue whose NFKC normalization is in "id_continue*">\n\nThe Unicode category codes mentioned above stand for:\n\n* *Lu* - uppercase letters\n\n* *Ll* - lowercase letters\n\n* *Lt* - titlecase letters\n\n* *Lm* - modifier letters\n\n* *Lo* - other letters\n\n* *Nl* - letter numbers\n\n* *Mn* - nonspacing marks\n\n* *Mc* - spacing combining marks\n\n* *Nd* - decimal numbers\n\n* *Pc* - connector punctuations\n\n* *Other_ID_Start* - explicit list of characters in PropList.txt to\n support backwards compatibility\n\n* *Other_ID_Continue* - likewise\n\nAll identifiers are converted into the normal form NFKC while parsing;\ncomparison of identifiers is based on NFKC.\n\nA non-normative HTML file listing all valid identifier characters for\nUnicode 4.1 can be found at http://www.dcl.hpi.uni-\npotsdam.de/home/loewis/table-3131.html.\n\n\nKeywords\n========\n\nThe following identifiers are used as reserved words, or *keywords* of\nthe language, and cannot be used as ordinary identifiers. They must\nbe spelled exactly as written here:\n\n False class finally is return\n None continue for lambda try\n True def from nonlocal while\n and del global not with\n as elif if or yield\n assert else import pass\n break except in raise\n\n\nReserved classes of identifiers\n===============================\n\nCertain classes of identifiers (besides keywords) have special\nmeanings. These classes are identified by the patterns of leading and\ntrailing underscore characters:\n\n``_*``\n Not imported by ``from module import *``. The special identifier\n ``_`` is used in the interactive interpreter to store the result of\n the last evaluation; it is stored in the ``builtins`` module. When\n not in interactive mode, ``_`` has no special meaning and is not\n defined. See section *The import statement*.\n\n Note: The name ``_`` is often used in conjunction with\n internationalization; refer to the documentation for the\n ``gettext`` module for more information on this convention.\n\n``__*__``\n System-defined names. These names are defined by the interpreter\n and its implementation (including the standard library). Current\n system names are discussed in the *Special method names* section\n and elsewhere. More will likely be defined in future versions of\n Python. *Any* use of ``__*__`` names, in any context, that does\n not follow explicitly documented use, is subject to breakage\n without warning.\n\n``__*``\n Class-private names. Names in this category, when used within the\n context of a class definition, are re-written to use a mangled form\n to help avoid name clashes between "private" attributes of base and\n derived classes. See section *Identifiers (Names)*.\n', - 'if': '\nThe ``if`` statement\n********************\n\nThe ``if`` statement is used for conditional execution:\n\n if_stmt ::= "if" expression ":" suite\n ( "elif" expression ":" suite )*\n ["else" ":" suite]\n\nIt selects exactly one of the suites by evaluating the expressions one\nby one until one is found to be true (see section *Boolean operations*\nfor the definition of true and false); then that suite is executed\n(and no other part of the ``if`` statement is executed or evaluated).\nIf all expressions are false, the suite of the ``else`` clause, if\npresent, is executed.\n', - 'imaginary': '\nImaginary literals\n******************\n\nImaginary literals are described by the following lexical definitions:\n\n imagnumber ::= (floatnumber | intpart) ("j" | "J")\n\nAn imaginary literal yields a complex number with a real part of 0.0.\nComplex numbers are represented as a pair of floating point numbers\nand have the same restrictions on their range. To create a complex\nnumber with a nonzero real part, add a floating point number to it,\ne.g., ``(3+4j)``. Some examples of imaginary literals:\n\n 3.14j 10.j 10j .001j 1e100j 3.14e-10j\n', - 'import': '\nThe ``import`` statement\n************************\n\n import_stmt ::= "import" module ["as" name] ( "," module ["as" name] )*\n | "from" relative_module "import" identifier ["as" name]\n ( "," identifier ["as" name] )*\n | "from" relative_module "import" "(" identifier ["as" name]\n ( "," identifier ["as" name] )* [","] ")"\n | "from" module "import" "*"\n module ::= (identifier ".")* identifier\n relative_module ::= "."* module | "."+\n name ::= identifier\n\nThe basic import statement (no ``from`` clause) is executed in two\nsteps:\n\n1. find a module, loading and initializing it if necessary\n\n2. define a name or names in the local namespace for the scope where\n the ``import`` statement occurs.\n\nWhen the statement contains multiple clauses (separated by commas) the\ntwo steps are carried out separately for each clause, just as though\nthe clauses had been separated out into individiual import statements.\n\nThe details of the first step, finding and loading modules is\ndescribed in greater detail in the section on the *import system*,\nwhich also describes the various types of packages and modules that\ncan be imported, as well as all the hooks that can be used to\ncustomize the import system. Note that failures in this step may\nindicate either that the module could not be located, *or* that an\nerror occurred while initializing the module, which includes execution\nof the module\'s code.\n\nIf the requested module is retrieved successfully, it will be made\navailable in the local namespace in one of three ways:\n\n* If the module name is followed by ``as``, then the name following\n ``as`` is bound directly to the imported module.\n\n* If no other name is specified, and the module being imported is a\n top level module, the module\'s name is bound in the local namespace\n as a reference to the imported module\n\n* If the module being imported is *not* a top level module, then the\n name of the top level package that contains the module is bound in\n the local namespace as a reference to the top level package. The\n imported module must be accessed using its full qualified name\n rather than directly\n\nThe ``from`` form uses a slightly more complex process:\n\n1. find the module specified in the ``from`` clause loading and\n initializing it if necessary;\n\n2. for each of the identifiers specified in the ``import`` clauses:\n\n 1. check if the imported module has an attribute by that name\n\n 2. if not, attempt to import a submodule with that name and then\n check the imported module again for that attribute\n\n 3. if the attribute is not found, ``ImportError`` is raised.\n\n 4. otherwise, a reference to that value is bound in the local\n namespace, using the name in the ``as`` clause if it is present,\n otherwise using the attribute name\n\nExamples:\n\n import foo # foo imported and bound locally\n import foo.bar.baz # foo.bar.baz imported, foo bound locally\n import foo.bar.baz as fbb # foo.bar.baz imported and bound as fbb\n from foo.bar import baz # foo.bar.baz imported and bound as baz\n from foo import attr # foo imported and foo.attr bound as attr\n\nIf the list of identifiers is replaced by a star (``\'*\'``), all public\nnames defined in the module are bound in the local namespace for the\nscope where the ``import`` statement occurs.\n\nThe *public names* defined by a module are determined by checking the\nmodule\'s namespace for a variable named ``__all__``; if defined, it\nmust be a sequence of strings which are names defined or imported by\nthat module. The names given in ``__all__`` are all considered public\nand are required to exist. If ``__all__`` is not defined, the set of\npublic names includes all names found in the module\'s namespace which\ndo not begin with an underscore character (``\'_\'``). ``__all__``\nshould contain the entire public API. It is intended to avoid\naccidentally exporting items that are not part of the API (such as\nlibrary modules which were imported and used within the module).\n\nThe ``from`` form with ``*`` may only occur in a module scope. The\nwild card form of import --- ``import *`` --- is only allowed at the\nmodule level. Attempting to use it in class or function definitions\nwill raise a ``SyntaxError``.\n\nWhen specifying what module to import you do not have to specify the\nabsolute name of the module. When a module or package is contained\nwithin another package it is possible to make a relative import within\nthe same top package without having to mention the package name. By\nusing leading dots in the specified module or package after ``from``\nyou can specify how high to traverse up the current package hierarchy\nwithout specifying exact names. One leading dot means the current\npackage where the module making the import exists. Two dots means up\none package level. Three dots is up two levels, etc. So if you execute\n``from . import mod`` from a module in the ``pkg`` package then you\nwill end up importing ``pkg.mod``. If you execute ``from ..subpkg2\nimport mod`` from within ``pkg.subpkg1`` you will import\n``pkg.subpkg2.mod``. The specification for relative imports is\ncontained within **PEP 328**.\n\n``importlib.import_module()`` is provided to support applications that\ndetermine which modules need to be loaded dynamically.\n\n\nFuture statements\n=================\n\nA *future statement* is a directive to the compiler that a particular\nmodule should be compiled using syntax or semantics that will be\navailable in a specified future release of Python. The future\nstatement is intended to ease migration to future versions of Python\nthat introduce incompatible changes to the language. It allows use of\nthe new features on a per-module basis before the release in which the\nfeature becomes standard.\n\n future_statement ::= "from" "__future__" "import" feature ["as" name]\n ("," feature ["as" name])*\n | "from" "__future__" "import" "(" feature ["as" name]\n ("," feature ["as" name])* [","] ")"\n feature ::= identifier\n name ::= identifier\n\nA future statement must appear near the top of the module. The only\nlines that can appear before a future statement are:\n\n* the module docstring (if any),\n\n* comments,\n\n* blank lines, and\n\n* other future statements.\n\nThe features recognized by Python 3.0 are ``absolute_import``,\n``division``, ``generators``, ``unicode_literals``,\n``print_function``, ``nested_scopes`` and ``with_statement``. They\nare all redundant because they are always enabled, and only kept for\nbackwards compatibility.\n\nA future statement is recognized and treated specially at compile\ntime: Changes to the semantics of core constructs are often\nimplemented by generating different code. It may even be the case\nthat a new feature introduces new incompatible syntax (such as a new\nreserved word), in which case the compiler may need to parse the\nmodule differently. Such decisions cannot be pushed off until\nruntime.\n\nFor any given release, the compiler knows which feature names have\nbeen defined, and raises a compile-time error if a future statement\ncontains a feature not known to it.\n\nThe direct runtime semantics are the same as for any import statement:\nthere is a standard module ``__future__``, described later, and it\nwill be imported in the usual way at the time the future statement is\nexecuted.\n\nThe interesting runtime semantics depend on the specific feature\nenabled by the future statement.\n\nNote that there is nothing special about the statement:\n\n import __future__ [as name]\n\nThat is not a future statement; it\'s an ordinary import statement with\nno special semantics or syntax restrictions.\n\nCode compiled by calls to the built-in functions ``exec()`` and\n``compile()`` that occur in a module ``M`` containing a future\nstatement will, by default, use the new syntax or semantics associated\nwith the future statement. This can be controlled by optional\narguments to ``compile()`` --- see the documentation of that function\nfor details.\n\nA future statement typed at an interactive interpreter prompt will\ntake effect for the rest of the interpreter session. If an\ninterpreter is started with the *-i* option, is passed a script name\nto execute, and the script includes a future statement, it will be in\neffect in the interactive session started after the script is\nexecuted.\n\nSee also:\n\n **PEP 236** - Back to the __future__\n The original proposal for the __future__ mechanism.\n', - 'in': '\nComparisons\n***********\n\nUnlike C, all comparison operations in Python have the same priority,\nwhich is lower than that of any arithmetic, shifting or bitwise\noperation. Also unlike C, expressions like ``a < b < c`` have the\ninterpretation that is conventional in mathematics:\n\n comparison ::= or_expr ( comp_operator or_expr )*\n comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "!="\n | "is" ["not"] | ["not"] "in"\n\nComparisons yield boolean values: ``True`` or ``False``.\n\nComparisons can be chained arbitrarily, e.g., ``x < y <= z`` is\nequivalent to ``x < y and y <= z``, except that ``y`` is evaluated\nonly once (but in both cases ``z`` is not evaluated at all when ``x <\ny`` is found to be false).\n\nFormally, if *a*, *b*, *c*, ..., *y*, *z* are expressions and *op1*,\n*op2*, ..., *opN* are comparison operators, then ``a op1 b op2 c ... y\nopN z`` is equivalent to ``a op1 b and b op2 c and ... y opN z``,\nexcept that each expression is evaluated at most once.\n\nNote that ``a op1 b op2 c`` doesn\'t imply any kind of comparison\nbetween *a* and *c*, so that, e.g., ``x < y > z`` is perfectly legal\n(though perhaps not pretty).\n\nThe operators ``<``, ``>``, ``==``, ``>=``, ``<=``, and ``!=`` compare\nthe values of two objects. The objects need not have the same type.\nIf both are numbers, they are converted to a common type. Otherwise,\nthe ``==`` and ``!=`` operators *always* consider objects of different\ntypes to be unequal, while the ``<``, ``>``, ``>=`` and ``<=``\noperators raise a ``TypeError`` when comparing objects of different\ntypes that do not implement these operators for the given pair of\ntypes. You can control comparison behavior of objects of non-built-in\ntypes by defining rich comparison methods like ``__gt__()``, described\nin section *Basic customization*.\n\nComparison of objects of the same type depends on the type:\n\n* Numbers are compared arithmetically.\n\n* The values ``float(\'NaN\')`` and ``Decimal(\'NaN\')`` are special. The\n are identical to themselves, ``x is x`` but are not equal to\n themselves, ``x != x``. Additionally, comparing any value to a\n not-a-number value will return ``False``. For example, both ``3 <\n float(\'NaN\')`` and ``float(\'NaN\') < 3`` will return ``False``.\n\n* Bytes objects are compared lexicographically using the numeric\n values of their elements.\n\n* Strings are compared lexicographically using the numeric equivalents\n (the result of the built-in function ``ord()``) of their characters.\n [3] String and bytes object can\'t be compared!\n\n* Tuples and lists are compared lexicographically using comparison of\n corresponding elements. This means that to compare equal, each\n element must compare equal and the two sequences must be of the same\n type and have the same length.\n\n If not equal, the sequences are ordered the same as their first\n differing elements. For example, ``[1,2,x] <= [1,2,y]`` has the\n same value as ``x <= y``. If the corresponding element does not\n exist, the shorter sequence is ordered first (for example, ``[1,2] <\n [1,2,3]``).\n\n* Mappings (dictionaries) compare equal if and only if they have the\n same ``(key, value)`` pairs. Order comparisons ``(\'<\', \'<=\', \'>=\',\n \'>\')`` raise ``TypeError``.\n\n* Sets and frozensets define comparison operators to mean subset and\n superset tests. Those relations do not define total orderings (the\n two sets ``{1,2}`` and {2,3} are not equal, nor subsets of one\n another, nor supersets of one another). Accordingly, sets are not\n appropriate arguments for functions which depend on total ordering.\n For example, ``min()``, ``max()``, and ``sorted()`` produce\n undefined results given a list of sets as inputs.\n\n* Most other objects of built-in types compare unequal unless they are\n the same object; the choice whether one object is considered smaller\n or larger than another one is made arbitrarily but consistently\n within one execution of a program.\n\nComparison of objects of the differing types depends on whether either\nof the types provide explicit support for the comparison. Most\nnumeric types can be compared with one another. When cross-type\ncomparison is not supported, the comparison method returns\n``NotImplemented``.\n\nThe operators ``in`` and ``not in`` test for membership. ``x in s``\nevaluates to true if *x* is a member of *s*, and false otherwise. ``x\nnot in s`` returns the negation of ``x in s``. All built-in sequences\nand set types support this as well as dictionary, for which ``in``\ntests whether a the dictionary has a given key. For container types\nsuch as list, tuple, set, frozenset, dict, or collections.deque, the\nexpression ``x in y`` is equivalent to ``any(x is e or x == e for e in\ny)``.\n\nFor the string and bytes types, ``x in y`` is true if and only if *x*\nis a substring of *y*. An equivalent test is ``y.find(x) != -1``.\nEmpty strings are always considered to be a substring of any other\nstring, so ``"" in "abc"`` will return ``True``.\n\nFor user-defined classes which define the ``__contains__()`` method,\n``x in y`` is true if and only if ``y.__contains__(x)`` is true.\n\nFor user-defined classes which do not define ``__contains__()`` but do\ndefine ``__iter__()``, ``x in y`` is true if some value ``z`` with ``x\n== z`` is produced while iterating over ``y``. If an exception is\nraised during the iteration, it is as if ``in`` raised that exception.\n\nLastly, the old-style iteration protocol is tried: if a class defines\n``__getitem__()``, ``x in y`` is true if and only if there is a non-\nnegative integer index *i* such that ``x == y[i]``, and all lower\ninteger indices do not raise ``IndexError`` exception. (If any other\nexception is raised, it is as if ``in`` raised that exception).\n\nThe operator ``not in`` is defined to have the inverse true value of\n``in``.\n\nThe operators ``is`` and ``is not`` test for object identity: ``x is\ny`` is true if and only if *x* and *y* are the same object. ``x is\nnot y`` yields the inverse truth value. [4]\n', - 'integers': '\nInteger literals\n****************\n\nInteger literals are described by the following lexical definitions:\n\n integer ::= decimalinteger | octinteger | hexinteger | bininteger\n decimalinteger ::= nonzerodigit digit* | "0"+\n nonzerodigit ::= "1"..."9"\n digit ::= "0"..."9"\n octinteger ::= "0" ("o" | "O") octdigit+\n hexinteger ::= "0" ("x" | "X") hexdigit+\n bininteger ::= "0" ("b" | "B") bindigit+\n octdigit ::= "0"..."7"\n hexdigit ::= digit | "a"..."f" | "A"..."F"\n bindigit ::= "0" | "1"\n\nThere is no limit for the length of integer literals apart from what\ncan be stored in available memory.\n\nNote that leading zeros in a non-zero decimal number are not allowed.\nThis is for disambiguation with C-style octal literals, which Python\nused before version 3.0.\n\nSome examples of integer literals:\n\n 7 2147483647 0o177 0b100110111\n 3 79228162514264337593543950336 0o377 0x100000000\n 79228162514264337593543950336 0xdeadbeef\n', - 'lambda': '\nLambdas\n*******\n\n lambda_expr ::= "lambda" [parameter_list]: expression\n lambda_expr_nocond ::= "lambda" [parameter_list]: expression_nocond\n\nLambda expressions (sometimes called lambda forms) have the same\nsyntactic position as expressions. They are a shorthand to create\nanonymous functions; the expression ``lambda arguments: expression``\nyields a function object. The unnamed object behaves like a function\nobject defined with\n\n def <lambda>(arguments):\n return expression\n\nSee section *Function definitions* for the syntax of parameter lists.\nNote that functions created with lambda expressions cannot contain\nstatements or annotations.\n', - 'lists': '\nList displays\n*************\n\nA list display is a possibly empty series of expressions enclosed in\nsquare brackets:\n\n list_display ::= "[" [expression_list | comprehension] "]"\n\nA list display yields a new list object, the contents being specified\nby either a list of expressions or a comprehension. When a comma-\nseparated list of expressions is supplied, its elements are evaluated\nfrom left to right and placed into the list object in that order.\nWhen a comprehension is supplied, the list is constructed from the\nelements resulting from the comprehension.\n', - 'naming': "\nNaming and binding\n******************\n\n*Names* refer to objects. Names are introduced by name binding\noperations. Each occurrence of a name in the program text refers to\nthe *binding* of that name established in the innermost function block\ncontaining the use.\n\nA *block* is a piece of Python program text that is executed as a\nunit. The following are blocks: a module, a function body, and a class\ndefinition. Each command typed interactively is a block. A script\nfile (a file given as standard input to the interpreter or specified\non the interpreter command line the first argument) is a code block.\nA script command (a command specified on the interpreter command line\nwith the '**-c**' option) is a code block. The string argument passed\nto the built-in functions ``eval()`` and ``exec()`` is a code block.\n\nA code block is executed in an *execution frame*. A frame contains\nsome administrative information (used for debugging) and determines\nwhere and how execution continues after the code block's execution has\ncompleted.\n\nA *scope* defines the visibility of a name within a block. If a local\nvariable is defined in a block, its scope includes that block. If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name. The scope of names defined in a\nclass block is limited to the class block; it does not extend to the\ncode blocks of methods -- this includes comprehensions and generator\nexpressions since they are implemented using a function scope. This\nmeans that the following will fail:\n\n class A:\n a = 42\n b = list(a + i for i in range(10))\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope. The set of all such scopes visible to a code block\nis called the block's *environment*.\n\nIf a name is bound in a block, it is a local variable of that block,\nunless declared as ``nonlocal``. If a name is bound at the module\nlevel, it is a global variable. (The variables of the module code\nblock are local and global.) If a variable is used in a code block\nbut not defined there, it is a *free variable*.\n\nWhen a name is not found at all, a ``NameError`` exception is raised.\nIf the name refers to a local variable that has not been bound, a\n``UnboundLocalError`` exception is raised. ``UnboundLocalError`` is a\nsubclass of ``NameError``.\n\nThe following constructs bind names: formal parameters to functions,\n``import`` statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, ``for`` loop header, or\nafter ``as`` in a ``with`` statement or ``except`` clause. The\n``import`` statement of the form ``from ... import *`` binds all names\ndefined in the imported module, except those beginning with an\nunderscore. This form may only be used at the module level.\n\nA target occurring in a ``del`` statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name).\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block. This can lead to errors when a name is used within a\nblock before it is bound. This rule is subtle. Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block. The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the ``global`` statement occurs within a block, all uses of the\nname specified in the statement refer to the binding of that name in\nthe top-level namespace. Names are resolved in the top-level\nnamespace by searching the global namespace, i.e. the namespace of the\nmodule containing the code block, and the builtins namespace, the\nnamespace of the module ``builtins``. The global namespace is\nsearched first. If the name is not found there, the builtins\nnamespace is searched. The global statement must precede all uses of\nthe name.\n\nThe builtins namespace associated with the execution of a code block\nis actually found by looking up the name ``__builtins__`` in its\nglobal namespace; this should be a dictionary or a module (in the\nlatter case the module's dictionary is used). By default, when in the\n``__main__`` module, ``__builtins__`` is the built-in module\n``builtins``; when in any other module, ``__builtins__`` is an alias\nfor the dictionary of the ``builtins`` module itself.\n``__builtins__`` can be set to a user-created dictionary to create a\nweak form of restricted execution.\n\n**CPython implementation detail:** Users should not touch\n``__builtins__``; it is strictly an implementation detail. Users\nwanting to override values in the builtins namespace should ``import``\nthe ``builtins`` module and modify its attributes appropriately.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported. The main module for a script is always called\n``__main__``.\n\nThe ``global`` statement has the same scope as a name binding\noperation in the same block. If the nearest enclosing scope for a\nfree variable contains a global statement, the free variable is\ntreated as a global.\n\nA class definition is an executable statement that may use and define\nnames. These references follow the normal rules for name resolution.\nThe namespace of the class definition becomes the attribute dictionary\nof the class. Names defined at the class scope are not visible in\nmethods.\n\n\nInteraction with dynamic features\n=================================\n\nThere are several cases where Python statements are illegal when used\nin conjunction with nested scopes that contain free variables.\n\nIf a variable is referenced in an enclosing scope, it is illegal to\ndelete the name. An error will be reported at compile time.\n\nIf the wild card form of import --- ``import *`` --- is used in a\nfunction and the function contains or is a nested block with free\nvariables, the compiler will raise a ``SyntaxError``.\n\nThe ``eval()`` and ``exec()`` functions do not have access to the full\nenvironment for resolving names. Names may be resolved in the local\nand global namespaces of the caller. Free variables are not resolved\nin the nearest enclosing namespace, but in the global namespace. [1]\nThe ``exec()`` and ``eval()`` functions have optional arguments to\noverride the global and local namespace. If only one namespace is\nspecified, it is used for both.\n", - 'nonlocal': '\nThe ``nonlocal`` statement\n**************************\n\n nonlocal_stmt ::= "nonlocal" identifier ("," identifier)*\n\nThe ``nonlocal`` statement causes the listed identifiers to refer to\npreviously bound variables in the nearest enclosing scope. This is\nimportant because the default behavior for binding is to search the\nlocal namespace first. The statement allows encapsulated code to\nrebind variables outside of the local scope besides the global\n(module) scope.\n\nNames listed in a ``nonlocal`` statement, unlike to those listed in a\n``global`` statement, must refer to pre-existing bindings in an\nenclosing scope (the scope in which a new binding should be created\ncannot be determined unambiguously).\n\nNames listed in a ``nonlocal`` statement must not collide with pre-\nexisting bindings in the local scope.\n\nSee also:\n\n **PEP 3104** - Access to Names in Outer Scopes\n The specification for the ``nonlocal`` statement.\n', - 'numbers': "\nNumeric literals\n****************\n\nThere are three types of numeric literals: integers, floating point\nnumbers, and imaginary numbers. There are no complex literals\n(complex numbers can be formed by adding a real number and an\nimaginary number).\n\nNote that numeric literals do not include a sign; a phrase like ``-1``\nis actually an expression composed of the unary operator '``-``' and\nthe literal ``1``.\n", - 'numeric-types': "\nEmulating numeric types\n***********************\n\nThe following methods can be defined to emulate numeric objects.\nMethods corresponding to operations that are not supported by the\nparticular kind of number implemented (e.g., bitwise operations for\nnon-integral numbers) should be left undefined.\n\nobject.__add__(self, other)\nobject.__sub__(self, other)\nobject.__mul__(self, other)\nobject.__truediv__(self, other)\nobject.__floordiv__(self, other)\nobject.__mod__(self, other)\nobject.__divmod__(self, other)\nobject.__pow__(self, other[, modulo])\nobject.__lshift__(self, other)\nobject.__rshift__(self, other)\nobject.__and__(self, other)\nobject.__xor__(self, other)\nobject.__or__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations (``+``, ``-``, ``*``, ``/``, ``//``, ``%``,\n ``divmod()``, ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``,\n ``|``). For instance, to evaluate the expression ``x + y``, where\n *x* is an instance of a class that has an ``__add__()`` method,\n ``x.__add__(y)`` is called. The ``__divmod__()`` method should be\n the equivalent to using ``__floordiv__()`` and ``__mod__()``; it\n should not be related to ``__truediv__()``. Note that\n ``__pow__()`` should be defined to accept an optional third\n argument if the ternary version of the built-in ``pow()`` function\n is to be supported.\n\n If one of those methods does not support the operation with the\n supplied arguments, it should return ``NotImplemented``.\n\nobject.__radd__(self, other)\nobject.__rsub__(self, other)\nobject.__rmul__(self, other)\nobject.__rtruediv__(self, other)\nobject.__rfloordiv__(self, other)\nobject.__rmod__(self, other)\nobject.__rdivmod__(self, other)\nobject.__rpow__(self, other)\nobject.__rlshift__(self, other)\nobject.__rrshift__(self, other)\nobject.__rand__(self, other)\nobject.__rxor__(self, other)\nobject.__ror__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations (``+``, ``-``, ``*``, ``/``, ``//``, ``%``,\n ``divmod()``, ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``,\n ``|``) with reflected (swapped) operands. These functions are only\n called if the left operand does not support the corresponding\n operation and the operands are of different types. [2] For\n instance, to evaluate the expression ``x - y``, where *y* is an\n instance of a class that has an ``__rsub__()`` method,\n ``y.__rsub__(x)`` is called if ``x.__sub__(y)`` returns\n *NotImplemented*.\n\n Note that ternary ``pow()`` will not try calling ``__rpow__()``\n (the coercion rules would become too complicated).\n\n Note: If the right operand's type is a subclass of the left operand's\n type and that subclass provides the reflected method for the\n operation, this method will be called before the left operand's\n non-reflected method. This behavior allows subclasses to\n override their ancestors' operations.\n\nobject.__iadd__(self, other)\nobject.__isub__(self, other)\nobject.__imul__(self, other)\nobject.__itruediv__(self, other)\nobject.__ifloordiv__(self, other)\nobject.__imod__(self, other)\nobject.__ipow__(self, other[, modulo])\nobject.__ilshift__(self, other)\nobject.__irshift__(self, other)\nobject.__iand__(self, other)\nobject.__ixor__(self, other)\nobject.__ior__(self, other)\n\n These methods are called to implement the augmented arithmetic\n assignments (``+=``, ``-=``, ``*=``, ``/=``, ``//=``, ``%=``,\n ``**=``, ``<<=``, ``>>=``, ``&=``, ``^=``, ``|=``). These methods\n should attempt to do the operation in-place (modifying *self*) and\n return the result (which could be, but does not have to be,\n *self*). If a specific method is not defined, the augmented\n assignment falls back to the normal methods. For instance, to\n execute the statement ``x += y``, where *x* is an instance of a\n class that has an ``__iadd__()`` method, ``x.__iadd__(y)`` is\n called. If *x* is an instance of a class that does not define a\n ``__iadd__()`` method, ``x.__add__(y)`` and ``y.__radd__(x)`` are\n considered, as with the evaluation of ``x + y``.\n\nobject.__neg__(self)\nobject.__pos__(self)\nobject.__abs__(self)\nobject.__invert__(self)\n\n Called to implement the unary arithmetic operations (``-``, ``+``,\n ``abs()`` and ``~``).\n\nobject.__complex__(self)\nobject.__int__(self)\nobject.__float__(self)\nobject.__round__(self[, n])\n\n Called to implement the built-in functions ``complex()``,\n ``int()``, ``float()`` and ``round()``. Should return a value of\n the appropriate type.\n\nobject.__index__(self)\n\n Called to implement ``operator.index()``. Also called whenever\n Python needs an integer object (such as in slicing, or in the\n built-in ``bin()``, ``hex()`` and ``oct()`` functions). Must return\n an integer.\n", - 'objects': '\nObjects, values and types\n*************************\n\n*Objects* are Python\'s abstraction for data. All data in a Python\nprogram is represented by objects or by relations between objects. (In\na sense, and in conformance to Von Neumann\'s model of a "stored\nprogram computer," code is also represented by objects.)\n\nEvery object has an identity, a type and a value. An object\'s\n*identity* never changes once it has been created; you may think of it\nas the object\'s address in memory. The \'``is``\' operator compares the\nidentity of two objects; the ``id()`` function returns an integer\nrepresenting its identity.\n\n**CPython implementation detail:** For CPython, ``id(x)`` is the\nmemory address where ``x`` is stored.\n\nAn object\'s type determines the operations that the object supports\n(e.g., "does it have a length?") and also defines the possible values\nfor objects of that type. The ``type()`` function returns an object\'s\ntype (which is an object itself). Like its identity, an object\'s\n*type* is also unchangeable. [1]\n\nThe *value* of some objects can change. Objects whose value can\nchange are said to be *mutable*; objects whose value is unchangeable\nonce they are created are called *immutable*. (The value of an\nimmutable container object that contains a reference to a mutable\nobject can change when the latter\'s value is changed; however the\ncontainer is still considered immutable, because the collection of\nobjects it contains cannot be changed. So, immutability is not\nstrictly the same as having an unchangeable value, it is more subtle.)\nAn object\'s mutability is determined by its type; for instance,\nnumbers, strings and tuples are immutable, while dictionaries and\nlists are mutable.\n\nObjects are never explicitly destroyed; however, when they become\nunreachable they may be garbage-collected. An implementation is\nallowed to postpone garbage collection or omit it altogether --- it is\na matter of implementation quality how garbage collection is\nimplemented, as long as no objects are collected that are still\nreachable.\n\n**CPython implementation detail:** CPython currently uses a reference-\ncounting scheme with (optional) delayed detection of cyclically linked\ngarbage, which collects most objects as soon as they become\nunreachable, but is not guaranteed to collect garbage containing\ncircular references. See the documentation of the ``gc`` module for\ninformation on controlling the collection of cyclic garbage. Other\nimplementations act differently and CPython may change. Do not depend\non immediate finalization of objects when they become unreachable (ex:\nalways close files).\n\nNote that the use of the implementation\'s tracing or debugging\nfacilities may keep objects alive that would normally be collectable.\nAlso note that catching an exception with a \'``try``...``except``\'\nstatement may keep objects alive.\n\nSome objects contain references to "external" resources such as open\nfiles or windows. It is understood that these resources are freed\nwhen the object is garbage-collected, but since garbage collection is\nnot guaranteed to happen, such objects also provide an explicit way to\nrelease the external resource, usually a ``close()`` method. Programs\nare strongly recommended to explicitly close such objects. The\n\'``try``...``finally``\' statement and the \'``with``\' statement provide\nconvenient ways to do this.\n\nSome objects contain references to other objects; these are called\n*containers*. Examples of containers are tuples, lists and\ndictionaries. The references are part of a container\'s value. In\nmost cases, when we talk about the value of a container, we imply the\nvalues, not the identities of the contained objects; however, when we\ntalk about the mutability of a container, only the identities of the\nimmediately contained objects are implied. So, if an immutable\ncontainer (like a tuple) contains a reference to a mutable object, its\nvalue changes if that mutable object is changed.\n\nTypes affect almost all aspects of object behavior. Even the\nimportance of object identity is affected in some sense: for immutable\ntypes, operations that compute new values may actually return a\nreference to any existing object with the same type and value, while\nfor mutable objects this is not allowed. E.g., after ``a = 1; b =\n1``, ``a`` and ``b`` may or may not refer to the same object with the\nvalue one, depending on the implementation, but after ``c = []; d =\n[]``, ``c`` and ``d`` are guaranteed to refer to two different,\nunique, newly created empty lists. (Note that ``c = d = []`` assigns\nthe same object to both ``c`` and ``d``.)\n', - 'operator-summary': '\nOperator precedence\n*******************\n\nThe following table summarizes the operator precedences in Python,\nfrom lowest precedence (least binding) to highest precedence (most\nbinding). Operators in the same box have the same precedence. Unless\nthe syntax is explicitly given, operators are binary. Operators in\nthe same box group left to right (except for comparisons, including\ntests, which all have the same precedence and chain from left to right\n--- see section *Comparisons* --- and exponentiation, which groups\nfrom right to left).\n\n+-------------------------------------------------+---------------------------------------+\n| Operator | Description |\n+=================================================+=======================================+\n| ``lambda`` | Lambda expression |\n+-------------------------------------------------+---------------------------------------+\n| ``if`` -- ``else`` | Conditional expression |\n+-------------------------------------------------+---------------------------------------+\n| ``or`` | Boolean OR |\n+-------------------------------------------------+---------------------------------------+\n| ``and`` | Boolean AND |\n+-------------------------------------------------+---------------------------------------+\n| ``not`` ``x`` | Boolean NOT |\n+-------------------------------------------------+---------------------------------------+\n| ``in``, ``not in``, ``is``, ``is not``, ``<``, | Comparisons, including membership |\n| ``<=``, ``>``, ``>=``, ``!=``, ``==`` | tests and identity tests |\n+-------------------------------------------------+---------------------------------------+\n| ``|`` | Bitwise OR |\n+-------------------------------------------------+---------------------------------------+\n| ``^`` | Bitwise XOR |\n+-------------------------------------------------+---------------------------------------+\n| ``&`` | Bitwise AND |\n+-------------------------------------------------+---------------------------------------+\n| ``<<``, ``>>`` | Shifts |\n+-------------------------------------------------+---------------------------------------+\n| ``+``, ``-`` | Addition and subtraction |\n+-------------------------------------------------+---------------------------------------+\n| ``*``, ``/``, ``//``, ``%`` | Multiplication, division, remainder |\n| | [5] |\n+-------------------------------------------------+---------------------------------------+\n| ``+x``, ``-x``, ``~x`` | Positive, negative, bitwise NOT |\n+-------------------------------------------------+---------------------------------------+\n| ``**`` | Exponentiation [6] |\n+-------------------------------------------------+---------------------------------------+\n| ``x[index]``, ``x[index:index]``, | Subscription, slicing, call, |\n| ``x(arguments...)``, ``x.attribute`` | attribute reference |\n+-------------------------------------------------+---------------------------------------+\n| ``(expressions...)``, ``[expressions...]``, | Binding or tuple display, list |\n| ``{key: value...}``, ``{expressions...}`` | display, dictionary display, set |\n| | display |\n+-------------------------------------------------+---------------------------------------+\n\n-[ Footnotes ]-\n\n[1] While ``abs(x%y) < abs(y)`` is true mathematically, for floats it\n may not be true numerically due to roundoff. For example, and\n assuming a platform on which a Python float is an IEEE 754 double-\n precision number, in order that ``-1e-100 % 1e100`` have the same\n sign as ``1e100``, the computed result is ``-1e-100 + 1e100``,\n which is numerically exactly equal to ``1e100``. The function\n ``math.fmod()`` returns a result whose sign matches the sign of\n the first argument instead, and so returns ``-1e-100`` in this\n case. Which approach is more appropriate depends on the\n application.\n\n[2] If x is very close to an exact integer multiple of y, it\'s\n possible for ``x//y`` to be one larger than ``(x-x%y)//y`` due to\n rounding. In such cases, Python returns the latter result, in\n order to preserve that ``divmod(x,y)[0] * y + x % y`` be very\n close to ``x``.\n\n[3] While comparisons between strings make sense at the byte level,\n they may be counter-intuitive to users. For example, the strings\n ``"\\u00C7"`` and ``"\\u0327\\u0043"`` compare differently, even\n though they both represent the same unicode character (LATIN\n CAPITAL LETTER C WITH CEDILLA). To compare strings in a human\n recognizable way, compare using ``unicodedata.normalize()``.\n\n[4] Due to automatic garbage-collection, free lists, and the dynamic\n nature of descriptors, you may notice seemingly unusual behaviour\n in certain uses of the ``is`` operator, like those involving\n comparisons between instance methods, or constants. Check their\n documentation for more info.\n\n[5] The ``%`` operator is also used for string formatting; the same\n precedence applies.\n\n[6] The power operator ``**`` binds less tightly than an arithmetic or\n bitwise unary operator on its right, that is, ``2**-1`` is\n ``0.5``.\n', - 'pass': '\nThe ``pass`` statement\n**********************\n\n pass_stmt ::= "pass"\n\n``pass`` is a null operation --- when it is executed, nothing happens.\nIt is useful as a placeholder when a statement is required\nsyntactically, but no code needs to be executed, for example:\n\n def f(arg): pass # a function that does nothing (yet)\n\n class C: pass # a class with no methods (yet)\n', - 'power': '\nThe power operator\n******************\n\nThe power operator binds more tightly than unary operators on its\nleft; it binds less tightly than unary operators on its right. The\nsyntax is:\n\n power ::= primary ["**" u_expr]\n\nThus, in an unparenthesized sequence of power and unary operators, the\noperators are evaluated from right to left (this does not constrain\nthe evaluation order for the operands): ``-1**2`` results in ``-1``.\n\nThe power operator has the same semantics as the built-in ``pow()``\nfunction, when called with two arguments: it yields its left argument\nraised to the power of its right argument. The numeric arguments are\nfirst converted to a common type, and the result is of that type.\n\nFor int operands, the result has the same type as the operands unless\nthe second argument is negative; in that case, all arguments are\nconverted to float and a float result is delivered. For example,\n``10**2`` returns ``100``, but ``10**-2`` returns ``0.01``.\n\nRaising ``0.0`` to a negative power results in a\n``ZeroDivisionError``. Raising a negative number to a fractional power\nresults in a ``complex`` number. (In earlier versions it raised a\n``ValueError``.)\n', - 'raise': '\nThe ``raise`` statement\n***********************\n\n raise_stmt ::= "raise" [expression ["from" expression]]\n\nIf no expressions are present, ``raise`` re-raises the last exception\nthat was active in the current scope. If no exception is active in\nthe current scope, a ``RuntimeError`` exception is raised indicating\nthat this is an error.\n\nOtherwise, ``raise`` evaluates the first expression as the exception\nobject. It must be either a subclass or an instance of\n``BaseException``. If it is a class, the exception instance will be\nobtained when needed by instantiating the class with no arguments.\n\nThe *type* of the exception is the exception instance\'s class, the\n*value* is the instance itself.\n\nA traceback object is normally created automatically when an exception\nis raised and attached to it as the ``__traceback__`` attribute, which\nis writable. You can create an exception and set your own traceback in\none step using the ``with_traceback()`` exception method (which\nreturns the same exception instance, with its traceback set to its\nargument), like so:\n\n raise Exception("foo occurred").with_traceback(tracebackobj)\n\nThe ``from`` clause is used for exception chaining: if given, the\nsecond *expression* must be another exception class or instance, which\nwill then be attached to the raised exception as the ``__cause__``\nattribute (which is writable). If the raised exception is not\nhandled, both exceptions will be printed:\n\n >>> try:\n ... print(1 / 0)\n ... except Exception as exc:\n ... raise RuntimeError("Something bad happened") from exc\n ...\n Traceback (most recent call last):\n File "<stdin>", line 2, in <module>\n ZeroDivisionError: int division or modulo by zero\n\n The above exception was the direct cause of the following exception:\n\n Traceback (most recent call last):\n File "<stdin>", line 4, in <module>\n RuntimeError: Something bad happened\n\nA similar mechanism works implicitly if an exception is raised inside\nan exception handler: the previous exception is then attached as the\nnew exception\'s ``__context__`` attribute:\n\n >>> try:\n ... print(1 / 0)\n ... except:\n ... raise RuntimeError("Something bad happened")\n ...\n Traceback (most recent call last):\n File "<stdin>", line 2, in <module>\n ZeroDivisionError: int division or modulo by zero\n\n During handling of the above exception, another exception occurred:\n\n Traceback (most recent call last):\n File "<stdin>", line 4, in <module>\n RuntimeError: Something bad happened\n\nAdditional information on exceptions can be found in section\n*Exceptions*, and information about handling exceptions is in section\n*The try statement*.\n', - 'return': '\nThe ``return`` statement\n************************\n\n return_stmt ::= "return" [expression_list]\n\n``return`` may only occur syntactically nested in a function\ndefinition, not within a nested class definition.\n\nIf an expression list is present, it is evaluated, else ``None`` is\nsubstituted.\n\n``return`` leaves the current function call with the expression list\n(or ``None``) as return value.\n\nWhen ``return`` passes control out of a ``try`` statement with a\n``finally`` clause, that ``finally`` clause is executed before really\nleaving the function.\n\nIn a generator function, the ``return`` statement indicates that the\ngenerator is done and will cause ``StopIteration`` to be raised. The\nreturned value (if any) is used as an argument to construct\n``StopIteration`` and becomes the ``StopIteration.value`` attribute.\n', - 'sequence-types': "\nEmulating container types\n*************************\n\nThe following methods can be defined to implement container objects.\nContainers usually are sequences (such as lists or tuples) or mappings\n(like dictionaries), but can represent other containers as well. The\nfirst set of methods is used either to emulate a sequence or to\nemulate a mapping; the difference is that for a sequence, the\nallowable keys should be the integers *k* for which ``0 <= k < N``\nwhere *N* is the length of the sequence, or slice objects, which\ndefine a range of items. It is also recommended that mappings provide\nthe methods ``keys()``, ``values()``, ``items()``, ``get()``,\n``clear()``, ``setdefault()``, ``pop()``, ``popitem()``, ``copy()``,\nand ``update()`` behaving similar to those for Python's standard\ndictionary objects. The ``collections`` module provides a\n``MutableMapping`` abstract base class to help create those methods\nfrom a base set of ``__getitem__()``, ``__setitem__()``,\n``__delitem__()``, and ``keys()``. Mutable sequences should provide\nmethods ``append()``, ``count()``, ``index()``, ``extend()``,\n``insert()``, ``pop()``, ``remove()``, ``reverse()`` and ``sort()``,\nlike Python standard list objects. Finally, sequence types should\nimplement addition (meaning concatenation) and multiplication (meaning\nrepetition) by defining the methods ``__add__()``, ``__radd__()``,\n``__iadd__()``, ``__mul__()``, ``__rmul__()`` and ``__imul__()``\ndescribed below; they should not define other numerical operators. It\nis recommended that both mappings and sequences implement the\n``__contains__()`` method to allow efficient use of the ``in``\noperator; for mappings, ``in`` should search the mapping's keys; for\nsequences, it should search through the values. It is further\nrecommended that both mappings and sequences implement the\n``__iter__()`` method to allow efficient iteration through the\ncontainer; for mappings, ``__iter__()`` should be the same as\n``keys()``; for sequences, it should iterate through the values.\n\nobject.__len__(self)\n\n Called to implement the built-in function ``len()``. Should return\n the length of the object, an integer ``>=`` 0. Also, an object\n that doesn't define a ``__bool__()`` method and whose ``__len__()``\n method returns zero is considered to be false in a Boolean context.\n\nobject.__length_hint__(self)\n\n Called to implement ``operator.length_hint()``. Should return an\n estimated length for the object (which may be greater or less than\n the actual length). The length must be an integer ``>=`` 0. This\n method is purely an optimization and is never required for\n correctness.\n\n New in version 3.4.\n\nNote: Slicing is done exclusively with the following three methods. A\n call like\n\n a[1:2] = b\n\n is translated to\n\n a[slice(1, 2, None)] = b\n\n and so forth. Missing slice items are always filled in with\n ``None``.\n\nobject.__getitem__(self, key)\n\n Called to implement evaluation of ``self[key]``. For sequence\n types, the accepted keys should be integers and slice objects.\n Note that the special interpretation of negative indexes (if the\n class wishes to emulate a sequence type) is up to the\n ``__getitem__()`` method. If *key* is of an inappropriate type,\n ``TypeError`` may be raised; if of a value outside the set of\n indexes for the sequence (after any special interpretation of\n negative values), ``IndexError`` should be raised. For mapping\n types, if *key* is missing (not in the container), ``KeyError``\n should be raised.\n\n Note: ``for`` loops expect that an ``IndexError`` will be raised for\n illegal indexes to allow proper detection of the end of the\n sequence.\n\nobject.__setitem__(self, key, value)\n\n Called to implement assignment to ``self[key]``. Same note as for\n ``__getitem__()``. This should only be implemented for mappings if\n the objects support changes to the values for keys, or if new keys\n can be added, or for sequences if elements can be replaced. The\n same exceptions should be raised for improper *key* values as for\n the ``__getitem__()`` method.\n\nobject.__delitem__(self, key)\n\n Called to implement deletion of ``self[key]``. Same note as for\n ``__getitem__()``. This should only be implemented for mappings if\n the objects support removal of keys, or for sequences if elements\n can be removed from the sequence. The same exceptions should be\n raised for improper *key* values as for the ``__getitem__()``\n method.\n\nobject.__iter__(self)\n\n This method is called when an iterator is required for a container.\n This method should return a new iterator object that can iterate\n over all the objects in the container. For mappings, it should\n iterate over the keys of the container, and should also be made\n available as the method ``keys()``.\n\n Iterator objects also need to implement this method; they are\n required to return themselves. For more information on iterator\n objects, see *Iterator Types*.\n\nobject.__reversed__(self)\n\n Called (if present) by the ``reversed()`` built-in to implement\n reverse iteration. It should return a new iterator object that\n iterates over all the objects in the container in reverse order.\n\n If the ``__reversed__()`` method is not provided, the\n ``reversed()`` built-in will fall back to using the sequence\n protocol (``__len__()`` and ``__getitem__()``). Objects that\n support the sequence protocol should only provide\n ``__reversed__()`` if they can provide an implementation that is\n more efficient than the one provided by ``reversed()``.\n\nThe membership test operators (``in`` and ``not in``) are normally\nimplemented as an iteration through a sequence. However, container\nobjects can supply the following special method with a more efficient\nimplementation, which also does not require the object be a sequence.\n\nobject.__contains__(self, item)\n\n Called to implement membership test operators. Should return true\n if *item* is in *self*, false otherwise. For mapping objects, this\n should consider the keys of the mapping rather than the values or\n the key-item pairs.\n\n For objects that don't define ``__contains__()``, the membership\n test first tries iteration via ``__iter__()``, then the old\n sequence iteration protocol via ``__getitem__()``, see *this\n section in the language reference*.\n", - 'shifting': '\nShifting operations\n*******************\n\nThe shifting operations have lower priority than the arithmetic\noperations:\n\n shift_expr ::= a_expr | shift_expr ( "<<" | ">>" ) a_expr\n\nThese operators accept integers as arguments. They shift the first\nargument to the left or right by the number of bits given by the\nsecond argument.\n\nA right shift by *n* bits is defined as floor division by\n``pow(2,n)``. A left shift by *n* bits is defined as multiplication\nwith ``pow(2,n)``.\n\nNote: In the current implementation, the right-hand operand is required to\n be at most ``sys.maxsize``. If the right-hand operand is larger\n than ``sys.maxsize`` an ``OverflowError`` exception is raised.\n', - 'slicings': '\nSlicings\n********\n\nA slicing selects a range of items in a sequence object (e.g., a\nstring, tuple or list). Slicings may be used as expressions or as\ntargets in assignment or ``del`` statements. The syntax for a\nslicing:\n\n slicing ::= primary "[" slice_list "]"\n slice_list ::= slice_item ("," slice_item)* [","]\n slice_item ::= expression | proper_slice\n proper_slice ::= [lower_bound] ":" [upper_bound] [ ":" [stride] ]\n lower_bound ::= expression\n upper_bound ::= expression\n stride ::= expression\n\nThere is ambiguity in the formal syntax here: anything that looks like\nan expression list also looks like a slice list, so any subscription\ncan be interpreted as a slicing. Rather than further complicating the\nsyntax, this is disambiguated by defining that in this case the\ninterpretation as a subscription takes priority over the\ninterpretation as a slicing (this is the case if the slice list\ncontains no proper slice).\n\nThe semantics for a slicing are as follows. The primary must evaluate\nto a mapping object, and it is indexed (using the same\n``__getitem__()`` method as normal subscription) with a key that is\nconstructed from the slice list, as follows. If the slice list\ncontains at least one comma, the key is a tuple containing the\nconversion of the slice items; otherwise, the conversion of the lone\nslice item is the key. The conversion of a slice item that is an\nexpression is that expression. The conversion of a proper slice is a\nslice object (see section *The standard type hierarchy*) whose\n``start``, ``stop`` and ``step`` attributes are the values of the\nexpressions given as lower bound, upper bound and stride,\nrespectively, substituting ``None`` for missing expressions.\n', - 'specialattrs': '\nSpecial Attributes\n******************\n\nThe implementation adds a few special read-only attributes to several\nobject types, where they are relevant. Some of these are not reported\nby the ``dir()`` built-in function.\n\nobject.__dict__\n\n A dictionary or other mapping object used to store an object\'s\n (writable) attributes.\n\ninstance.__class__\n\n The class to which a class instance belongs.\n\nclass.__bases__\n\n The tuple of base classes of a class object.\n\nclass.__name__\n\n The name of the class or type.\n\nclass.__qualname__\n\n The *qualified name* of the class or type.\n\n New in version 3.3.\n\nclass.__mro__\n\n This attribute is a tuple of classes that are considered when\n looking for base classes during method resolution.\n\nclass.mro()\n\n This method can be overridden by a metaclass to customize the\n method resolution order for its instances. It is called at class\n instantiation, and its result is stored in ``__mro__``.\n\nclass.__subclasses__()\n\n Each class keeps a list of weak references to its immediate\n subclasses. This method returns a list of all those references\n still alive. Example:\n\n >>> int.__subclasses__()\n [<class \'bool\'>]\n\n-[ Footnotes ]-\n\n[1] Additional information on these special methods may be found in\n the Python Reference Manual (*Basic customization*).\n\n[2] As a consequence, the list ``[1, 2]`` is considered equal to\n ``[1.0, 2.0]``, and similarly for tuples.\n\n[3] They must have since the parser can\'t tell the type of the\n operands.\n\n[4] Cased characters are those with general category property being\n one of "Lu" (Letter, uppercase), "Ll" (Letter, lowercase), or "Lt"\n (Letter, titlecase).\n\n[5] To format only a tuple you should therefore provide a singleton\n tuple whose only element is the tuple to be formatted.\n', - 'specialnames': '\nSpecial method names\n********************\n\nA class can implement certain operations that are invoked by special\nsyntax (such as arithmetic operations or subscripting and slicing) by\ndefining methods with special names. This is Python\'s approach to\n*operator overloading*, allowing classes to define their own behavior\nwith respect to language operators. For instance, if a class defines\na method named ``__getitem__()``, and ``x`` is an instance of this\nclass, then ``x[i]`` is roughly equivalent to ``type(x).__getitem__(x,\ni)``. Except where mentioned, attempts to execute an operation raise\nan exception when no appropriate method is defined (typically\n``AttributeError`` or ``TypeError``).\n\nWhen implementing a class that emulates any built-in type, it is\nimportant that the emulation only be implemented to the degree that it\nmakes sense for the object being modelled. For example, some\nsequences may work well with retrieval of individual elements, but\nextracting a slice may not make sense. (One example of this is the\n``NodeList`` interface in the W3C\'s Document Object Model.)\n\n\nBasic customization\n===================\n\nobject.__new__(cls[, ...])\n\n Called to create a new instance of class *cls*. ``__new__()`` is a\n static method (special-cased so you need not declare it as such)\n that takes the class of which an instance was requested as its\n first argument. The remaining arguments are those passed to the\n object constructor expression (the call to the class). The return\n value of ``__new__()`` should be the new object instance (usually\n an instance of *cls*).\n\n Typical implementations create a new instance of the class by\n invoking the superclass\'s ``__new__()`` method using\n ``super(currentclass, cls).__new__(cls[, ...])`` with appropriate\n arguments and then modifying the newly-created instance as\n necessary before returning it.\n\n If ``__new__()`` returns an instance of *cls*, then the new\n instance\'s ``__init__()`` method will be invoked like\n ``__init__(self[, ...])``, where *self* is the new instance and the\n remaining arguments are the same as were passed to ``__new__()``.\n\n If ``__new__()`` does not return an instance of *cls*, then the new\n instance\'s ``__init__()`` method will not be invoked.\n\n ``__new__()`` is intended mainly to allow subclasses of immutable\n types (like int, str, or tuple) to customize instance creation. It\n is also commonly overridden in custom metaclasses in order to\n customize class creation.\n\nobject.__init__(self[, ...])\n\n Called when the instance is created. The arguments are those\n passed to the class constructor expression. If a base class has an\n ``__init__()`` method, the derived class\'s ``__init__()`` method,\n if any, must explicitly call it to ensure proper initialization of\n the base class part of the instance; for example:\n ``BaseClass.__init__(self, [args...])``. As a special constraint\n on constructors, no value may be returned; doing so will cause a\n ``TypeError`` to be raised at runtime.\n\nobject.__del__(self)\n\n Called when the instance is about to be destroyed. This is also\n called a destructor. If a base class has a ``__del__()`` method,\n the derived class\'s ``__del__()`` method, if any, must explicitly\n call it to ensure proper deletion of the base class part of the\n instance. Note that it is possible (though not recommended!) for\n the ``__del__()`` method to postpone destruction of the instance by\n creating a new reference to it. It may then be called at a later\n time when this new reference is deleted. It is not guaranteed that\n ``__del__()`` methods are called for objects that still exist when\n the interpreter exits.\n\n Note: ``del x`` doesn\'t directly call ``x.__del__()`` --- the former\n decrements the reference count for ``x`` by one, and the latter\n is only called when ``x``\'s reference count reaches zero. Some\n common situations that may prevent the reference count of an\n object from going to zero include: circular references between\n objects (e.g., a doubly-linked list or a tree data structure with\n parent and child pointers); a reference to the object on the\n stack frame of a function that caught an exception (the traceback\n stored in ``sys.exc_info()[2]`` keeps the stack frame alive); or\n a reference to the object on the stack frame that raised an\n unhandled exception in interactive mode (the traceback stored in\n ``sys.last_traceback`` keeps the stack frame alive). The first\n situation can only be remedied by explicitly breaking the cycles;\n the latter two situations can be resolved by storing ``None`` in\n ``sys.last_traceback``. Circular references which are garbage are\n detected and cleaned up when the cyclic garbage collector is\n enabled (it\'s on by default). Refer to the documentation for the\n ``gc`` module for more information about this topic.\n\n Warning: Due to the precarious circumstances under which ``__del__()``\n methods are invoked, exceptions that occur during their execution\n are ignored, and a warning is printed to ``sys.stderr`` instead.\n Also, when ``__del__()`` is invoked in response to a module being\n deleted (e.g., when execution of the program is done), other\n globals referenced by the ``__del__()`` method may already have\n been deleted or in the process of being torn down (e.g. the\n import machinery shutting down). For this reason, ``__del__()``\n methods should do the absolute minimum needed to maintain\n external invariants. Starting with version 1.5, Python\n guarantees that globals whose name begins with a single\n underscore are deleted from their module before other globals are\n deleted; if no other references to such globals exist, this may\n help in assuring that imported modules are still available at the\n time when the ``__del__()`` method is called.\n\nobject.__repr__(self)\n\n Called by the ``repr()`` built-in function to compute the\n "official" string representation of an object. If at all possible,\n this should look like a valid Python expression that could be used\n to recreate an object with the same value (given an appropriate\n environment). If this is not possible, a string of the form\n ``<...some useful description...>`` should be returned. The return\n value must be a string object. If a class defines ``__repr__()``\n but not ``__str__()``, then ``__repr__()`` is also used when an\n "informal" string representation of instances of that class is\n required.\n\n This is typically used for debugging, so it is important that the\n representation is information-rich and unambiguous.\n\nobject.__str__(self)\n\n Called by ``str(object)`` and the built-in functions ``format()``\n and ``print()`` to compute the "informal" or nicely printable\n string representation of an object. The return value must be a\n *string* object.\n\n This method differs from ``object.__repr__()`` in that there is no\n expectation that ``__str__()`` return a valid Python expression: a\n more convenient or concise representation can be used.\n\n The default implementation defined by the built-in type ``object``\n calls ``object.__repr__()``.\n\nobject.__bytes__(self)\n\n Called by ``bytes()`` to compute a byte-string representation of an\n object. This should return a ``bytes`` object.\n\nobject.__format__(self, format_spec)\n\n Called by the ``format()`` built-in function (and by extension, the\n ``str.format()`` method of class ``str``) to produce a "formatted"\n string representation of an object. The ``format_spec`` argument is\n a string that contains a description of the formatting options\n desired. The interpretation of the ``format_spec`` argument is up\n to the type implementing ``__format__()``, however most classes\n will either delegate formatting to one of the built-in types, or\n use a similar formatting option syntax.\n\n See *Format Specification Mini-Language* for a description of the\n standard formatting syntax.\n\n The return value must be a string object.\n\nobject.__lt__(self, other)\nobject.__le__(self, other)\nobject.__eq__(self, other)\nobject.__ne__(self, other)\nobject.__gt__(self, other)\nobject.__ge__(self, other)\n\n These are the so-called "rich comparison" methods. The\n correspondence between operator symbols and method names is as\n follows: ``x<y`` calls ``x.__lt__(y)``, ``x<=y`` calls\n ``x.__le__(y)``, ``x==y`` calls ``x.__eq__(y)``, ``x!=y`` calls\n ``x.__ne__(y)``, ``x>y`` calls ``x.__gt__(y)``, and ``x>=y`` calls\n ``x.__ge__(y)``.\n\n A rich comparison method may return the singleton\n ``NotImplemented`` if it does not implement the operation for a\n given pair of arguments. By convention, ``False`` and ``True`` are\n returned for a successful comparison. However, these methods can\n return any value, so if the comparison operator is used in a\n Boolean context (e.g., in the condition of an ``if`` statement),\n Python will call ``bool()`` on the value to determine if the result\n is true or false.\n\n There are no implied relationships among the comparison operators.\n The truth of ``x==y`` does not imply that ``x!=y`` is false.\n Accordingly, when defining ``__eq__()``, one should also define\n ``__ne__()`` so that the operators will behave as expected. See\n the paragraph on ``__hash__()`` for some important notes on\n creating *hashable* objects which support custom comparison\n operations and are usable as dictionary keys.\n\n There are no swapped-argument versions of these methods (to be used\n when the left argument does not support the operation but the right\n argument does); rather, ``__lt__()`` and ``__gt__()`` are each\n other\'s reflection, ``__le__()`` and ``__ge__()`` are each other\'s\n reflection, and ``__eq__()`` and ``__ne__()`` are their own\n reflection.\n\n Arguments to rich comparison methods are never coerced.\n\n To automatically generate ordering operations from a single root\n operation, see ``functools.total_ordering()``.\n\nobject.__hash__(self)\n\n Called by built-in function ``hash()`` and for operations on\n members of hashed collections including ``set``, ``frozenset``, and\n ``dict``. ``__hash__()`` should return an integer. The only\n required property is that objects which compare equal have the same\n hash value; it is advised to somehow mix together (e.g. using\n exclusive or) the hash values for the components of the object that\n also play a part in comparison of objects.\n\n Note: ``hash()`` truncates the value returned from an object\'s custom\n ``__hash__()`` method to the size of a ``Py_ssize_t``. This is\n typically 8 bytes on 64-bit builds and 4 bytes on 32-bit builds.\n If an object\'s ``__hash__()`` must interoperate on builds of\n different bit sizes, be sure to check the width on all supported\n builds. An easy way to do this is with ``python -c "import sys;\n print(sys.hash_info.width)"``\n\n If a class does not define an ``__eq__()`` method it should not\n define a ``__hash__()`` operation either; if it defines\n ``__eq__()`` but not ``__hash__()``, its instances will not be\n usable as items in hashable collections. If a class defines\n mutable objects and implements an ``__eq__()`` method, it should\n not implement ``__hash__()``, since the implementation of hashable\n collections requires that a key\'s hash value is immutable (if the\n object\'s hash value changes, it will be in the wrong hash bucket).\n\n User-defined classes have ``__eq__()`` and ``__hash__()`` methods\n by default; with them, all objects compare unequal (except with\n themselves) and ``x.__hash__()`` returns an appropriate value such\n that ``x == y`` implies both that ``x is y`` and ``hash(x) ==\n hash(y)``.\n\n A class that overrides ``__eq__()`` and does not define\n ``__hash__()`` will have its ``__hash__()`` implicitly set to\n ``None``. When the ``__hash__()`` method of a class is ``None``,\n instances of the class will raise an appropriate ``TypeError`` when\n a program attempts to retrieve their hash value, and will also be\n correctly identified as unhashable when checking ``isinstance(obj,\n collections.Hashable``).\n\n If a class that overrides ``__eq__()`` needs to retain the\n implementation of ``__hash__()`` from a parent class, the\n interpreter must be told this explicitly by setting ``__hash__ =\n <ParentClass>.__hash__``.\n\n If a class that does not override ``__eq__()`` wishes to suppress\n hash support, it should include ``__hash__ = None`` in the class\n definition. A class which defines its own ``__hash__()`` that\n explicitly raises a ``TypeError`` would be incorrectly identified\n as hashable by an ``isinstance(obj, collections.Hashable)`` call.\n\n Note: By default, the ``__hash__()`` values of str, bytes and datetime\n objects are "salted" with an unpredictable random value.\n Although they remain constant within an individual Python\n process, they are not predictable between repeated invocations of\n Python.This is intended to provide protection against a denial-\n of-service caused by carefully-chosen inputs that exploit the\n worst case performance of a dict insertion, O(n^2) complexity.\n See http://www.ocert.org/advisories/ocert-2011-003.html for\n details.Changing hash values affects the iteration order of\n dicts, sets and other mappings. Python has never made guarantees\n about this ordering (and it typically varies between 32-bit and\n 64-bit builds).See also ``PYTHONHASHSEED``.\n\n Changed in version 3.3: Hash randomization is enabled by default.\n\nobject.__bool__(self)\n\n Called to implement truth value testing and the built-in operation\n ``bool()``; should return ``False`` or ``True``. When this method\n is not defined, ``__len__()`` is called, if it is defined, and the\n object is considered true if its result is nonzero. If a class\n defines neither ``__len__()`` nor ``__bool__()``, all its instances\n are considered true.\n\n\nCustomizing attribute access\n============================\n\nThe following methods can be defined to customize the meaning of\nattribute access (use of, assignment to, or deletion of ``x.name``)\nfor class instances.\n\nobject.__getattr__(self, name)\n\n Called when an attribute lookup has not found the attribute in the\n usual places (i.e. it is not an instance attribute nor is it found\n in the class tree for ``self``). ``name`` is the attribute name.\n This method should return the (computed) attribute value or raise\n an ``AttributeError`` exception.\n\n Note that if the attribute is found through the normal mechanism,\n ``__getattr__()`` is not called. (This is an intentional asymmetry\n between ``__getattr__()`` and ``__setattr__()``.) This is done both\n for efficiency reasons and because otherwise ``__getattr__()``\n would have no way to access other attributes of the instance. Note\n that at least for instance variables, you can fake total control by\n not inserting any values in the instance attribute dictionary (but\n instead inserting them in another object). See the\n ``__getattribute__()`` method below for a way to actually get total\n control over attribute access.\n\nobject.__getattribute__(self, name)\n\n Called unconditionally to implement attribute accesses for\n instances of the class. If the class also defines\n ``__getattr__()``, the latter will not be called unless\n ``__getattribute__()`` either calls it explicitly or raises an\n ``AttributeError``. This method should return the (computed)\n attribute value or raise an ``AttributeError`` exception. In order\n to avoid infinite recursion in this method, its implementation\n should always call the base class method with the same name to\n access any attributes it needs, for example,\n ``object.__getattribute__(self, name)``.\n\n Note: This method may still be bypassed when looking up special methods\n as the result of implicit invocation via language syntax or\n built-in functions. See *Special method lookup*.\n\nobject.__setattr__(self, name, value)\n\n Called when an attribute assignment is attempted. This is called\n instead of the normal mechanism (i.e. store the value in the\n instance dictionary). *name* is the attribute name, *value* is the\n value to be assigned to it.\n\n If ``__setattr__()`` wants to assign to an instance attribute, it\n should call the base class method with the same name, for example,\n ``object.__setattr__(self, name, value)``.\n\nobject.__delattr__(self, name)\n\n Like ``__setattr__()`` but for attribute deletion instead of\n assignment. This should only be implemented if ``del obj.name`` is\n meaningful for the object.\n\nobject.__dir__(self)\n\n Called when ``dir()`` is called on the object. A sequence must be\n returned. ``dir()`` converts the returned sequence to a list and\n sorts it.\n\n\nImplementing Descriptors\n------------------------\n\nThe following methods only apply when an instance of the class\ncontaining the method (a so-called *descriptor* class) appears in an\n*owner* class (the descriptor must be in either the owner\'s class\ndictionary or in the class dictionary for one of its parents). In the\nexamples below, "the attribute" refers to the attribute whose name is\nthe key of the property in the owner class\' ``__dict__``.\n\nobject.__get__(self, instance, owner)\n\n Called to get the attribute of the owner class (class attribute\n access) or of an instance of that class (instance attribute\n access). *owner* is always the owner class, while *instance* is the\n instance that the attribute was accessed through, or ``None`` when\n the attribute is accessed through the *owner*. This method should\n return the (computed) attribute value or raise an\n ``AttributeError`` exception.\n\nobject.__set__(self, instance, value)\n\n Called to set the attribute on an instance *instance* of the owner\n class to a new value, *value*.\n\nobject.__delete__(self, instance)\n\n Called to delete the attribute on an instance *instance* of the\n owner class.\n\n\nInvoking Descriptors\n--------------------\n\nIn general, a descriptor is an object attribute with "binding\nbehavior", one whose attribute access has been overridden by methods\nin the descriptor protocol: ``__get__()``, ``__set__()``, and\n``__delete__()``. If any of those methods are defined for an object,\nit is said to be a descriptor.\n\nThe default behavior for attribute access is to get, set, or delete\nthe attribute from an object\'s dictionary. For instance, ``a.x`` has a\nlookup chain starting with ``a.__dict__[\'x\']``, then\n``type(a).__dict__[\'x\']``, and continuing through the base classes of\n``type(a)`` excluding metaclasses.\n\nHowever, if the looked-up value is an object defining one of the\ndescriptor methods, then Python may override the default behavior and\ninvoke the descriptor method instead. Where this occurs in the\nprecedence chain depends on which descriptor methods were defined and\nhow they were called.\n\nThe starting point for descriptor invocation is a binding, ``a.x``.\nHow the arguments are assembled depends on ``a``:\n\nDirect Call\n The simplest and least common call is when user code directly\n invokes a descriptor method: ``x.__get__(a)``.\n\nInstance Binding\n If binding to an object instance, ``a.x`` is transformed into the\n call: ``type(a).__dict__[\'x\'].__get__(a, type(a))``.\n\nClass Binding\n If binding to a class, ``A.x`` is transformed into the call:\n ``A.__dict__[\'x\'].__get__(None, A)``.\n\nSuper Binding\n If ``a`` is an instance of ``super``, then the binding ``super(B,\n obj).m()`` searches ``obj.__class__.__mro__`` for the base class\n ``A`` immediately preceding ``B`` and then invokes the descriptor\n with the call: ``A.__dict__[\'m\'].__get__(obj, obj.__class__)``.\n\nFor instance bindings, the precedence of descriptor invocation depends\non the which descriptor methods are defined. A descriptor can define\nany combination of ``__get__()``, ``__set__()`` and ``__delete__()``.\nIf it does not define ``__get__()``, then accessing the attribute will\nreturn the descriptor object itself unless there is a value in the\nobject\'s instance dictionary. If the descriptor defines ``__set__()``\nand/or ``__delete__()``, it is a data descriptor; if it defines\nneither, it is a non-data descriptor. Normally, data descriptors\ndefine both ``__get__()`` and ``__set__()``, while non-data\ndescriptors have just the ``__get__()`` method. Data descriptors with\n``__set__()`` and ``__get__()`` defined always override a redefinition\nin an instance dictionary. In contrast, non-data descriptors can be\noverridden by instances.\n\nPython methods (including ``staticmethod()`` and ``classmethod()``)\nare implemented as non-data descriptors. Accordingly, instances can\nredefine and override methods. This allows individual instances to\nacquire behaviors that differ from other instances of the same class.\n\nThe ``property()`` function is implemented as a data descriptor.\nAccordingly, instances cannot override the behavior of a property.\n\n\n__slots__\n---------\n\nBy default, instances of classes have a dictionary for attribute\nstorage. This wastes space for objects having very few instance\nvariables. The space consumption can become acute when creating large\nnumbers of instances.\n\nThe default can be overridden by defining *__slots__* in a class\ndefinition. The *__slots__* declaration takes a sequence of instance\nvariables and reserves just enough space in each instance to hold a\nvalue for each variable. Space is saved because *__dict__* is not\ncreated for each instance.\n\nobject.__slots__\n\n This class variable can be assigned a string, iterable, or sequence\n of strings with variable names used by instances. If defined in a\n class, *__slots__* reserves space for the declared variables and\n prevents the automatic creation of *__dict__* and *__weakref__* for\n each instance.\n\n\nNotes on using *__slots__*\n~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n* When inheriting from a class without *__slots__*, the *__dict__*\n attribute of that class will always be accessible, so a *__slots__*\n definition in the subclass is meaningless.\n\n* Without a *__dict__* variable, instances cannot be assigned new\n variables not listed in the *__slots__* definition. Attempts to\n assign to an unlisted variable name raises ``AttributeError``. If\n dynamic assignment of new variables is desired, then add\n ``\'__dict__\'`` to the sequence of strings in the *__slots__*\n declaration.\n\n* Without a *__weakref__* variable for each instance, classes defining\n *__slots__* do not support weak references to its instances. If weak\n reference support is needed, then add ``\'__weakref__\'`` to the\n sequence of strings in the *__slots__* declaration.\n\n* *__slots__* are implemented at the class level by creating\n descriptors (*Implementing Descriptors*) for each variable name. As\n a result, class attributes cannot be used to set default values for\n instance variables defined by *__slots__*; otherwise, the class\n attribute would overwrite the descriptor assignment.\n\n* The action of a *__slots__* declaration is limited to the class\n where it is defined. As a result, subclasses will have a *__dict__*\n unless they also define *__slots__* (which must only contain names\n of any *additional* slots).\n\n* If a class defines a slot also defined in a base class, the instance\n variable defined by the base class slot is inaccessible (except by\n retrieving its descriptor directly from the base class). This\n renders the meaning of the program undefined. In the future, a\n check may be added to prevent this.\n\n* Nonempty *__slots__* does not work for classes derived from\n "variable-length" built-in types such as ``int``, ``str`` and\n ``tuple``.\n\n* Any non-string iterable may be assigned to *__slots__*. Mappings may\n also be used; however, in the future, special meaning may be\n assigned to the values corresponding to each key.\n\n* *__class__* assignment works only if both classes have the same\n *__slots__*.\n\n\nCustomizing class creation\n==========================\n\nBy default, classes are constructed using ``type()``. The class body\nis executed in a new namespace and the class name is bound locally to\nthe result of ``type(name, bases, namespace)``.\n\nThe class creation process can be customised by passing the\n``metaclass`` keyword argument in the class definition line, or by\ninheriting from an existing class that included such an argument. In\nthe following example, both ``MyClass`` and ``MySubclass`` are\ninstances of ``Meta``:\n\n class Meta(type):\n pass\n\n class MyClass(metaclass=Meta):\n pass\n\n class MySubclass(MyClass):\n pass\n\nAny other keyword arguments that are specified in the class definition\nare passed through to all metaclass operations described below.\n\nWhen a class definition is executed, the following steps occur:\n\n* the appropriate metaclass is determined\n\n* the class namespace is prepared\n\n* the class body is executed\n\n* the class object is created\n\n\nDetermining the appropriate metaclass\n-------------------------------------\n\nThe appropriate metaclass for a class definition is determined as\nfollows:\n\n* if no bases and no explicit metaclass are given, then ``type()`` is\n used\n\n* if an explicit metaclass is given and it is *not* an instance of\n ``type()``, then it is used directly as the metaclass\n\n* if an instance of ``type()`` is given as the explicit metaclass, or\n bases are defined, then the most derived metaclass is used\n\nThe most derived metaclass is selected from the explicitly specified\nmetaclass (if any) and the metaclasses (i.e. ``type(cls)``) of all\nspecified base classes. The most derived metaclass is one which is a\nsubtype of *all* of these candidate metaclasses. If none of the\ncandidate metaclasses meets that criterion, then the class definition\nwill fail with ``TypeError``.\n\n\nPreparing the class namespace\n-----------------------------\n\nOnce the appropriate metaclass has been identified, then the class\nnamespace is prepared. If the metaclass has a ``__prepare__``\nattribute, it is called as ``namespace = metaclass.__prepare__(name,\nbases, **kwds)`` (where the additional keyword arguments, if any, come\nfrom the class definition).\n\nIf the metaclass has no ``__prepare__`` attribute, then the class\nnamespace is initialised as an empty ``dict()`` instance.\n\nSee also:\n\n **PEP 3115** - Metaclasses in Python 3000\n Introduced the ``__prepare__`` namespace hook\n\n\nExecuting the class body\n------------------------\n\nThe class body is executed (approximately) as ``exec(body, globals(),\nnamespace)``. The key difference from a normal call to ``exec()`` is\nthat lexical scoping allows the class body (including any methods) to\nreference names from the current and outer scopes when the class\ndefinition occurs inside a function.\n\nHowever, even when the class definition occurs inside the function,\nmethods defined inside the class still cannot see names defined at the\nclass scope. Class variables must be accessed through the first\nparameter of instance or class methods, and cannot be accessed at all\nfrom static methods.\n\n\nCreating the class object\n-------------------------\n\nOnce the class namespace has been populated by executing the class\nbody, the class object is created by calling ``metaclass(name, bases,\nnamespace, **kwds)`` (the additional keywords passed here are the same\nas those passed to ``__prepare__``).\n\nThis class object is the one that will be referenced by the zero-\nargument form of ``super()``. ``__class__`` is an implicit closure\nreference created by the compiler if any methods in a class body refer\nto either ``__class__`` or ``super``. This allows the zero argument\nform of ``super()`` to correctly identify the class being defined\nbased on lexical scoping, while the class or instance that was used to\nmake the current call is identified based on the first argument passed\nto the method.\n\nAfter the class object is created, it is passed to the class\ndecorators included in the class definition (if any) and the resulting\nobject is bound in the local namespace as the defined class.\n\nSee also:\n\n **PEP 3135** - New super\n Describes the implicit ``__class__`` closure reference\n\n\nMetaclass example\n-----------------\n\nThe potential uses for metaclasses are boundless. Some ideas that have\nbeen explored include logging, interface checking, automatic\ndelegation, automatic property creation, proxies, frameworks, and\nautomatic resource locking/synchronization.\n\nHere is an example of a metaclass that uses an\n``collections.OrderedDict`` to remember the order that class members\nwere defined:\n\n class OrderedClass(type):\n\n @classmethod\n def __prepare__(metacls, name, bases, **kwds):\n return collections.OrderedDict()\n\n def __new__(cls, name, bases, namespace, **kwds):\n result = type.__new__(cls, name, bases, dict(namespace))\n result.members = tuple(namespace)\n return result\n\n class A(metaclass=OrderedClass):\n def one(self): pass\n def two(self): pass\n def three(self): pass\n def four(self): pass\n\n >>> A.members\n (\'__module__\', \'one\', \'two\', \'three\', \'four\')\n\nWhen the class definition for *A* gets executed, the process begins\nwith calling the metaclass\'s ``__prepare__()`` method which returns an\nempty ``collections.OrderedDict``. That mapping records the methods\nand attributes of *A* as they are defined within the body of the class\nstatement. Once those definitions are executed, the ordered dictionary\nis fully populated and the metaclass\'s ``__new__()`` method gets\ninvoked. That method builds the new type and it saves the ordered\ndictionary keys in an attribute called ``members``.\n\n\nCustomizing instance and subclass checks\n========================================\n\nThe following methods are used to override the default behavior of the\n``isinstance()`` and ``issubclass()`` built-in functions.\n\nIn particular, the metaclass ``abc.ABCMeta`` implements these methods\nin order to allow the addition of Abstract Base Classes (ABCs) as\n"virtual base classes" to any class or type (including built-in\ntypes), including other ABCs.\n\nclass.__instancecheck__(self, instance)\n\n Return true if *instance* should be considered a (direct or\n indirect) instance of *class*. If defined, called to implement\n ``isinstance(instance, class)``.\n\nclass.__subclasscheck__(self, subclass)\n\n Return true if *subclass* should be considered a (direct or\n indirect) subclass of *class*. If defined, called to implement\n ``issubclass(subclass, class)``.\n\nNote that these methods are looked up on the type (metaclass) of a\nclass. They cannot be defined as class methods in the actual class.\nThis is consistent with the lookup of special methods that are called\non instances, only in this case the instance is itself a class.\n\nSee also:\n\n **PEP 3119** - Introducing Abstract Base Classes\n Includes the specification for customizing ``isinstance()`` and\n ``issubclass()`` behavior through ``__instancecheck__()`` and\n ``__subclasscheck__()``, with motivation for this functionality\n in the context of adding Abstract Base Classes (see the ``abc``\n module) to the language.\n\n\nEmulating callable objects\n==========================\n\nobject.__call__(self[, args...])\n\n Called when the instance is "called" as a function; if this method\n is defined, ``x(arg1, arg2, ...)`` is a shorthand for\n ``x.__call__(arg1, arg2, ...)``.\n\n\nEmulating container types\n=========================\n\nThe following methods can be defined to implement container objects.\nContainers usually are sequences (such as lists or tuples) or mappings\n(like dictionaries), but can represent other containers as well. The\nfirst set of methods is used either to emulate a sequence or to\nemulate a mapping; the difference is that for a sequence, the\nallowable keys should be the integers *k* for which ``0 <= k < N``\nwhere *N* is the length of the sequence, or slice objects, which\ndefine a range of items. It is also recommended that mappings provide\nthe methods ``keys()``, ``values()``, ``items()``, ``get()``,\n``clear()``, ``setdefault()``, ``pop()``, ``popitem()``, ``copy()``,\nand ``update()`` behaving similar to those for Python\'s standard\ndictionary objects. The ``collections`` module provides a\n``MutableMapping`` abstract base class to help create those methods\nfrom a base set of ``__getitem__()``, ``__setitem__()``,\n``__delitem__()``, and ``keys()``. Mutable sequences should provide\nmethods ``append()``, ``count()``, ``index()``, ``extend()``,\n``insert()``, ``pop()``, ``remove()``, ``reverse()`` and ``sort()``,\nlike Python standard list objects. Finally, sequence types should\nimplement addition (meaning concatenation) and multiplication (meaning\nrepetition) by defining the methods ``__add__()``, ``__radd__()``,\n``__iadd__()``, ``__mul__()``, ``__rmul__()`` and ``__imul__()``\ndescribed below; they should not define other numerical operators. It\nis recommended that both mappings and sequences implement the\n``__contains__()`` method to allow efficient use of the ``in``\noperator; for mappings, ``in`` should search the mapping\'s keys; for\nsequences, it should search through the values. It is further\nrecommended that both mappings and sequences implement the\n``__iter__()`` method to allow efficient iteration through the\ncontainer; for mappings, ``__iter__()`` should be the same as\n``keys()``; for sequences, it should iterate through the values.\n\nobject.__len__(self)\n\n Called to implement the built-in function ``len()``. Should return\n the length of the object, an integer ``>=`` 0. Also, an object\n that doesn\'t define a ``__bool__()`` method and whose ``__len__()``\n method returns zero is considered to be false in a Boolean context.\n\nobject.__length_hint__(self)\n\n Called to implement ``operator.length_hint()``. Should return an\n estimated length for the object (which may be greater or less than\n the actual length). The length must be an integer ``>=`` 0. This\n method is purely an optimization and is never required for\n correctness.\n\n New in version 3.4.\n\nNote: Slicing is done exclusively with the following three methods. A\n call like\n\n a[1:2] = b\n\n is translated to\n\n a[slice(1, 2, None)] = b\n\n and so forth. Missing slice items are always filled in with\n ``None``.\n\nobject.__getitem__(self, key)\n\n Called to implement evaluation of ``self[key]``. For sequence\n types, the accepted keys should be integers and slice objects.\n Note that the special interpretation of negative indexes (if the\n class wishes to emulate a sequence type) is up to the\n ``__getitem__()`` method. If *key* is of an inappropriate type,\n ``TypeError`` may be raised; if of a value outside the set of\n indexes for the sequence (after any special interpretation of\n negative values), ``IndexError`` should be raised. For mapping\n types, if *key* is missing (not in the container), ``KeyError``\n should be raised.\n\n Note: ``for`` loops expect that an ``IndexError`` will be raised for\n illegal indexes to allow proper detection of the end of the\n sequence.\n\nobject.__setitem__(self, key, value)\n\n Called to implement assignment to ``self[key]``. Same note as for\n ``__getitem__()``. This should only be implemented for mappings if\n the objects support changes to the values for keys, or if new keys\n can be added, or for sequences if elements can be replaced. The\n same exceptions should be raised for improper *key* values as for\n the ``__getitem__()`` method.\n\nobject.__delitem__(self, key)\n\n Called to implement deletion of ``self[key]``. Same note as for\n ``__getitem__()``. This should only be implemented for mappings if\n the objects support removal of keys, or for sequences if elements\n can be removed from the sequence. The same exceptions should be\n raised for improper *key* values as for the ``__getitem__()``\n method.\n\nobject.__iter__(self)\n\n This method is called when an iterator is required for a container.\n This method should return a new iterator object that can iterate\n over all the objects in the container. For mappings, it should\n iterate over the keys of the container, and should also be made\n available as the method ``keys()``.\n\n Iterator objects also need to implement this method; they are\n required to return themselves. For more information on iterator\n objects, see *Iterator Types*.\n\nobject.__reversed__(self)\n\n Called (if present) by the ``reversed()`` built-in to implement\n reverse iteration. It should return a new iterator object that\n iterates over all the objects in the container in reverse order.\n\n If the ``__reversed__()`` method is not provided, the\n ``reversed()`` built-in will fall back to using the sequence\n protocol (``__len__()`` and ``__getitem__()``). Objects that\n support the sequence protocol should only provide\n ``__reversed__()`` if they can provide an implementation that is\n more efficient than the one provided by ``reversed()``.\n\nThe membership test operators (``in`` and ``not in``) are normally\nimplemented as an iteration through a sequence. However, container\nobjects can supply the following special method with a more efficient\nimplementation, which also does not require the object be a sequence.\n\nobject.__contains__(self, item)\n\n Called to implement membership test operators. Should return true\n if *item* is in *self*, false otherwise. For mapping objects, this\n should consider the keys of the mapping rather than the values or\n the key-item pairs.\n\n For objects that don\'t define ``__contains__()``, the membership\n test first tries iteration via ``__iter__()``, then the old\n sequence iteration protocol via ``__getitem__()``, see *this\n section in the language reference*.\n\n\nEmulating numeric types\n=======================\n\nThe following methods can be defined to emulate numeric objects.\nMethods corresponding to operations that are not supported by the\nparticular kind of number implemented (e.g., bitwise operations for\nnon-integral numbers) should be left undefined.\n\nobject.__add__(self, other)\nobject.__sub__(self, other)\nobject.__mul__(self, other)\nobject.__truediv__(self, other)\nobject.__floordiv__(self, other)\nobject.__mod__(self, other)\nobject.__divmod__(self, other)\nobject.__pow__(self, other[, modulo])\nobject.__lshift__(self, other)\nobject.__rshift__(self, other)\nobject.__and__(self, other)\nobject.__xor__(self, other)\nobject.__or__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations (``+``, ``-``, ``*``, ``/``, ``//``, ``%``,\n ``divmod()``, ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``,\n ``|``). For instance, to evaluate the expression ``x + y``, where\n *x* is an instance of a class that has an ``__add__()`` method,\n ``x.__add__(y)`` is called. The ``__divmod__()`` method should be\n the equivalent to using ``__floordiv__()`` and ``__mod__()``; it\n should not be related to ``__truediv__()``. Note that\n ``__pow__()`` should be defined to accept an optional third\n argument if the ternary version of the built-in ``pow()`` function\n is to be supported.\n\n If one of those methods does not support the operation with the\n supplied arguments, it should return ``NotImplemented``.\n\nobject.__radd__(self, other)\nobject.__rsub__(self, other)\nobject.__rmul__(self, other)\nobject.__rtruediv__(self, other)\nobject.__rfloordiv__(self, other)\nobject.__rmod__(self, other)\nobject.__rdivmod__(self, other)\nobject.__rpow__(self, other)\nobject.__rlshift__(self, other)\nobject.__rrshift__(self, other)\nobject.__rand__(self, other)\nobject.__rxor__(self, other)\nobject.__ror__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations (``+``, ``-``, ``*``, ``/``, ``//``, ``%``,\n ``divmod()``, ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``,\n ``|``) with reflected (swapped) operands. These functions are only\n called if the left operand does not support the corresponding\n operation and the operands are of different types. [2] For\n instance, to evaluate the expression ``x - y``, where *y* is an\n instance of a class that has an ``__rsub__()`` method,\n ``y.__rsub__(x)`` is called if ``x.__sub__(y)`` returns\n *NotImplemented*.\n\n Note that ternary ``pow()`` will not try calling ``__rpow__()``\n (the coercion rules would become too complicated).\n\n Note: If the right operand\'s type is a subclass of the left operand\'s\n type and that subclass provides the reflected method for the\n operation, this method will be called before the left operand\'s\n non-reflected method. This behavior allows subclasses to\n override their ancestors\' operations.\n\nobject.__iadd__(self, other)\nobject.__isub__(self, other)\nobject.__imul__(self, other)\nobject.__itruediv__(self, other)\nobject.__ifloordiv__(self, other)\nobject.__imod__(self, other)\nobject.__ipow__(self, other[, modulo])\nobject.__ilshift__(self, other)\nobject.__irshift__(self, other)\nobject.__iand__(self, other)\nobject.__ixor__(self, other)\nobject.__ior__(self, other)\n\n These methods are called to implement the augmented arithmetic\n assignments (``+=``, ``-=``, ``*=``, ``/=``, ``//=``, ``%=``,\n ``**=``, ``<<=``, ``>>=``, ``&=``, ``^=``, ``|=``). These methods\n should attempt to do the operation in-place (modifying *self*) and\n return the result (which could be, but does not have to be,\n *self*). If a specific method is not defined, the augmented\n assignment falls back to the normal methods. For instance, to\n execute the statement ``x += y``, where *x* is an instance of a\n class that has an ``__iadd__()`` method, ``x.__iadd__(y)`` is\n called. If *x* is an instance of a class that does not define a\n ``__iadd__()`` method, ``x.__add__(y)`` and ``y.__radd__(x)`` are\n considered, as with the evaluation of ``x + y``.\n\nobject.__neg__(self)\nobject.__pos__(self)\nobject.__abs__(self)\nobject.__invert__(self)\n\n Called to implement the unary arithmetic operations (``-``, ``+``,\n ``abs()`` and ``~``).\n\nobject.__complex__(self)\nobject.__int__(self)\nobject.__float__(self)\nobject.__round__(self[, n])\n\n Called to implement the built-in functions ``complex()``,\n ``int()``, ``float()`` and ``round()``. Should return a value of\n the appropriate type.\n\nobject.__index__(self)\n\n Called to implement ``operator.index()``. Also called whenever\n Python needs an integer object (such as in slicing, or in the\n built-in ``bin()``, ``hex()`` and ``oct()`` functions). Must return\n an integer.\n\n\nWith Statement Context Managers\n===============================\n\nA *context manager* is an object that defines the runtime context to\nbe established when executing a ``with`` statement. The context\nmanager handles the entry into, and the exit from, the desired runtime\ncontext for the execution of the block of code. Context managers are\nnormally invoked using the ``with`` statement (described in section\n*The with statement*), but can also be used by directly invoking their\nmethods.\n\nTypical uses of context managers include saving and restoring various\nkinds of global state, locking and unlocking resources, closing opened\nfiles, etc.\n\nFor more information on context managers, see *Context Manager Types*.\n\nobject.__enter__(self)\n\n Enter the runtime context related to this object. The ``with``\n statement will bind this method\'s return value to the target(s)\n specified in the ``as`` clause of the statement, if any.\n\nobject.__exit__(self, exc_type, exc_value, traceback)\n\n Exit the runtime context related to this object. The parameters\n describe the exception that caused the context to be exited. If the\n context was exited without an exception, all three arguments will\n be ``None``.\n\n If an exception is supplied, and the method wishes to suppress the\n exception (i.e., prevent it from being propagated), it should\n return a true value. Otherwise, the exception will be processed\n normally upon exit from this method.\n\n Note that ``__exit__()`` methods should not reraise the passed-in\n exception; this is the caller\'s responsibility.\n\nSee also:\n\n **PEP 0343** - The "with" statement\n The specification, background, and examples for the Python\n ``with`` statement.\n\n\nSpecial method lookup\n=====================\n\nFor custom classes, implicit invocations of special methods are only\nguaranteed to work correctly if defined on an object\'s type, not in\nthe object\'s instance dictionary. That behaviour is the reason why\nthe following code raises an exception:\n\n >>> class C:\n ... pass\n ...\n >>> c = C()\n >>> c.__len__ = lambda: 5\n >>> len(c)\n Traceback (most recent call last):\n File "<stdin>", line 1, in <module>\n TypeError: object of type \'C\' has no len()\n\nThe rationale behind this behaviour lies with a number of special\nmethods such as ``__hash__()`` and ``__repr__()`` that are implemented\nby all objects, including type objects. If the implicit lookup of\nthese methods used the conventional lookup process, they would fail\nwhen invoked on the type object itself:\n\n >>> 1 .__hash__() == hash(1)\n True\n >>> int.__hash__() == hash(int)\n Traceback (most recent call last):\n File "<stdin>", line 1, in <module>\n TypeError: descriptor \'__hash__\' of \'int\' object needs an argument\n\nIncorrectly attempting to invoke an unbound method of a class in this\nway is sometimes referred to as \'metaclass confusion\', and is avoided\nby bypassing the instance when looking up special methods:\n\n >>> type(1).__hash__(1) == hash(1)\n True\n >>> type(int).__hash__(int) == hash(int)\n True\n\nIn addition to bypassing any instance attributes in the interest of\ncorrectness, implicit special method lookup generally also bypasses\nthe ``__getattribute__()`` method even of the object\'s metaclass:\n\n >>> class Meta(type):\n ... def __getattribute__(*args):\n ... print("Metaclass getattribute invoked")\n ... return type.__getattribute__(*args)\n ...\n >>> class C(object, metaclass=Meta):\n ... def __len__(self):\n ... return 10\n ... def __getattribute__(*args):\n ... print("Class getattribute invoked")\n ... return object.__getattribute__(*args)\n ...\n >>> c = C()\n >>> c.__len__() # Explicit lookup via instance\n Class getattribute invoked\n 10\n >>> type(c).__len__(c) # Explicit lookup via type\n Metaclass getattribute invoked\n 10\n >>> len(c) # Implicit lookup\n 10\n\nBypassing the ``__getattribute__()`` machinery in this fashion\nprovides significant scope for speed optimisations within the\ninterpreter, at the cost of some flexibility in the handling of\nspecial methods (the special method *must* be set on the class object\nitself in order to be consistently invoked by the interpreter).\n\n-[ Footnotes ]-\n\n[1] It *is* possible in some cases to change an object\'s type, under\n certain controlled conditions. It generally isn\'t a good idea\n though, since it can lead to some very strange behaviour if it is\n handled incorrectly.\n\n[2] For operands of the same type, it is assumed that if the non-\n reflected method (such as ``__add__()``) fails the operation is\n not supported, which is why the reflected method is not called.\n', - 'string-methods': '\nString Methods\n**************\n\nStrings implement all of the *common* sequence operations, along with\nthe additional methods described below.\n\nStrings also support two styles of string formatting, one providing a\nlarge degree of flexibility and customization (see ``str.format()``,\n*Format String Syntax* and *String Formatting*) and the other based on\nC ``printf`` style formatting that handles a narrower range of types\nand is slightly harder to use correctly, but is often faster for the\ncases it can handle (*printf-style String Formatting*).\n\nThe *Text Processing Services* section of the standard library covers\na number of other modules that provide various text related utilities\n(including regular expression support in the ``re`` module).\n\nstr.capitalize()\n\n Return a copy of the string with its first character capitalized\n and the rest lowercased.\n\nstr.casefold()\n\n Return a casefolded copy of the string. Casefolded strings may be\n used for caseless matching.\n\n Casefolding is similar to lowercasing but more aggressive because\n it is intended to remove all case distinctions in a string. For\n example, the German lowercase letter ``\'\xc3\x9f\'`` is equivalent to\n ``"ss"``. Since it is already lowercase, ``lower()`` would do\n nothing to ``\'\xc3\x9f\'``; ``casefold()`` converts it to ``"ss"``.\n\n The casefolding algorithm is described in section 3.13 of the\n Unicode Standard.\n\n New in version 3.3.\n\nstr.center(width[, fillchar])\n\n Return centered in a string of length *width*. Padding is done\n using the specified *fillchar* (default is a space).\n\nstr.count(sub[, start[, end]])\n\n Return the number of non-overlapping occurrences of substring *sub*\n in the range [*start*, *end*]. Optional arguments *start* and\n *end* are interpreted as in slice notation.\n\nstr.encode(encoding="utf-8", errors="strict")\n\n Return an encoded version of the string as a bytes object. Default\n encoding is ``\'utf-8\'``. *errors* may be given to set a different\n error handling scheme. The default for *errors* is ``\'strict\'``,\n meaning that encoding errors raise a ``UnicodeError``. Other\n possible values are ``\'ignore\'``, ``\'replace\'``,\n ``\'xmlcharrefreplace\'``, ``\'backslashreplace\'`` and any other name\n registered via ``codecs.register_error()``, see section *Codec Base\n Classes*. For a list of possible encodings, see section *Standard\n Encodings*.\n\n Changed in version 3.1: Support for keyword arguments added.\n\nstr.endswith(suffix[, start[, end]])\n\n Return ``True`` if the string ends with the specified *suffix*,\n otherwise return ``False``. *suffix* can also be a tuple of\n suffixes to look for. With optional *start*, test beginning at\n that position. With optional *end*, stop comparing at that\n position.\n\nstr.expandtabs(tabsize=8)\n\n Return a copy of the string where all tab characters are replaced\n by one or more spaces, depending on the current column and the\n given tab size. Tab positions occur every *tabsize* characters\n (default is 8, giving tab positions at columns 0, 8, 16 and so on).\n To expand the string, the current column is set to zero and the\n string is examined character by character. If the character is a\n tab (``\\t``), one or more space characters are inserted in the\n result until the current column is equal to the next tab position.\n (The tab character itself is not copied.) If the character is a\n newline (``\\n``) or return (``\\r``), it is copied and the current\n column is reset to zero. Any other character is copied unchanged\n and the current column is incremented by one regardless of how the\n character is represented when printed.\n\n >>> \'01\\t012\\t0123\\t01234\'.expandtabs()\n \'01 012 0123 01234\'\n >>> \'01\\t012\\t0123\\t01234\'.expandtabs(4)\n \'01 012 0123 01234\'\n\nstr.find(sub[, start[, end]])\n\n Return the lowest index in the string where substring *sub* is\n found, such that *sub* is contained in the slice ``s[start:end]``.\n Optional arguments *start* and *end* are interpreted as in slice\n notation. Return ``-1`` if *sub* is not found.\n\n Note: The ``find()`` method should be used only if you need to know the\n position of *sub*. To check if *sub* is a substring or not, use\n the ``in`` operator:\n\n >>> \'Py\' in \'Python\'\n True\n\nstr.format(*args, **kwargs)\n\n Perform a string formatting operation. The string on which this\n method is called can contain literal text or replacement fields\n delimited by braces ``{}``. Each replacement field contains either\n the numeric index of a positional argument, or the name of a\n keyword argument. Returns a copy of the string where each\n replacement field is replaced with the string value of the\n corresponding argument.\n\n >>> "The sum of 1 + 2 is {0}".format(1+2)\n \'The sum of 1 + 2 is 3\'\n\n See *Format String Syntax* for a description of the various\n formatting options that can be specified in format strings.\n\nstr.format_map(mapping)\n\n Similar to ``str.format(**mapping)``, except that ``mapping`` is\n used directly and not copied to a ``dict`` . This is useful if for\n example ``mapping`` is a dict subclass:\n\n >>> class Default(dict):\n ... def __missing__(self, key):\n ... return key\n ...\n >>> \'{name} was born in {country}\'.format_map(Default(name=\'Guido\'))\n \'Guido was born in country\'\n\n New in version 3.2.\n\nstr.index(sub[, start[, end]])\n\n Like ``find()``, but raise ``ValueError`` when the substring is not\n found.\n\nstr.isalnum()\n\n Return true if all characters in the string are alphanumeric and\n there is at least one character, false otherwise. A character\n ``c`` is alphanumeric if one of the following returns ``True``:\n ``c.isalpha()``, ``c.isdecimal()``, ``c.isdigit()``, or\n ``c.isnumeric()``.\n\nstr.isalpha()\n\n Return true if all characters in the string are alphabetic and\n there is at least one character, false otherwise. Alphabetic\n characters are those characters defined in the Unicode character\n database as "Letter", i.e., those with general category property\n being one of "Lm", "Lt", "Lu", "Ll", or "Lo". Note that this is\n different from the "Alphabetic" property defined in the Unicode\n Standard.\n\nstr.isdecimal()\n\n Return true if all characters in the string are decimal characters\n and there is at least one character, false otherwise. Decimal\n characters are those from general category "Nd". This category\n includes digit characters, and all characters that can be used to\n form decimal-radix numbers, e.g. U+0660, ARABIC-INDIC DIGIT ZERO.\n\nstr.isdigit()\n\n Return true if all characters in the string are digits and there is\n at least one character, false otherwise. Digits include decimal\n characters and digits that need special handling, such as the\n compatibility superscript digits. Formally, a digit is a character\n that has the property value Numeric_Type=Digit or\n Numeric_Type=Decimal.\n\nstr.isidentifier()\n\n Return true if the string is a valid identifier according to the\n language definition, section *Identifiers and keywords*.\n\n Use ``keyword.iskeyword()`` to test for reserved identifiers such\n as ``def`` and ``class``.\n\nstr.islower()\n\n Return true if all cased characters [4] in the string are lowercase\n and there is at least one cased character, false otherwise.\n\nstr.isnumeric()\n\n Return true if all characters in the string are numeric characters,\n and there is at least one character, false otherwise. Numeric\n characters include digit characters, and all characters that have\n the Unicode numeric value property, e.g. U+2155, VULGAR FRACTION\n ONE FIFTH. Formally, numeric characters are those with the\n property value Numeric_Type=Digit, Numeric_Type=Decimal or\n Numeric_Type=Numeric.\n\nstr.isprintable()\n\n Return true if all characters in the string are printable or the\n string is empty, false otherwise. Nonprintable characters are\n those characters defined in the Unicode character database as\n "Other" or "Separator", excepting the ASCII space (0x20) which is\n considered printable. (Note that printable characters in this\n context are those which should not be escaped when ``repr()`` is\n invoked on a string. It has no bearing on the handling of strings\n written to ``sys.stdout`` or ``sys.stderr``.)\n\nstr.isspace()\n\n Return true if there are only whitespace characters in the string\n and there is at least one character, false otherwise. Whitespace\n characters are those characters defined in the Unicode character\n database as "Other" or "Separator" and those with bidirectional\n property being one of "WS", "B", or "S".\n\nstr.istitle()\n\n Return true if the string is a titlecased string and there is at\n least one character, for example uppercase characters may only\n follow uncased characters and lowercase characters only cased ones.\n Return false otherwise.\n\nstr.isupper()\n\n Return true if all cased characters [4] in the string are uppercase\n and there is at least one cased character, false otherwise.\n\nstr.join(iterable)\n\n Return a string which is the concatenation of the strings in the\n *iterable* *iterable*. A ``TypeError`` will be raised if there are\n any non-string values in *iterable*, including ``bytes`` objects.\n The separator between elements is the string providing this method.\n\nstr.ljust(width[, fillchar])\n\n Return the string left justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is a\n space). The original string is returned if *width* is less than or\n equal to ``len(s)``.\n\nstr.lower()\n\n Return a copy of the string with all the cased characters [4]\n converted to lowercase.\n\n The lowercasing algorithm used is described in section 3.13 of the\n Unicode Standard.\n\nstr.lstrip([chars])\n\n Return a copy of the string with leading characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or ``None``, the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a prefix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.lstrip()\n \'spacious \'\n >>> \'www.example.com\'.lstrip(\'cmowz.\')\n \'example.com\'\n\nstatic str.maketrans(x[, y[, z]])\n\n This static method returns a translation table usable for\n ``str.translate()``.\n\n If there is only one argument, it must be a dictionary mapping\n Unicode ordinals (integers) or characters (strings of length 1) to\n Unicode ordinals, strings (of arbitrary lengths) or None.\n Character keys will then be converted to ordinals.\n\n If there are two arguments, they must be strings of equal length,\n and in the resulting dictionary, each character in x will be mapped\n to the character at the same position in y. If there is a third\n argument, it must be a string, whose characters will be mapped to\n None in the result.\n\nstr.partition(sep)\n\n Split the string at the first occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing the string itself, followed by\n two empty strings.\n\nstr.replace(old, new[, count])\n\n Return a copy of the string with all occurrences of substring *old*\n replaced by *new*. If the optional argument *count* is given, only\n the first *count* occurrences are replaced.\n\nstr.rfind(sub[, start[, end]])\n\n Return the highest index in the string where substring *sub* is\n found, such that *sub* is contained within ``s[start:end]``.\n Optional arguments *start* and *end* are interpreted as in slice\n notation. Return ``-1`` on failure.\n\nstr.rindex(sub[, start[, end]])\n\n Like ``rfind()`` but raises ``ValueError`` when the substring *sub*\n is not found.\n\nstr.rjust(width[, fillchar])\n\n Return the string right justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is a\n space). The original string is returned if *width* is less than or\n equal to ``len(s)``.\n\nstr.rpartition(sep)\n\n Split the string at the last occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing two empty strings, followed by\n the string itself.\n\nstr.rsplit(sep=None, maxsplit=-1)\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit* splits\n are done, the *rightmost* ones. If *sep* is not specified or\n ``None``, any whitespace string is a separator. Except for\n splitting from the right, ``rsplit()`` behaves like ``split()``\n which is described in detail below.\n\nstr.rstrip([chars])\n\n Return a copy of the string with trailing characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or ``None``, the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a suffix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.rstrip()\n \' spacious\'\n >>> \'mississippi\'.rstrip(\'ipz\')\n \'mississ\'\n\nstr.split(sep=None, maxsplit=-1)\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit*\n splits are done (thus, the list will have at most ``maxsplit+1``\n elements). If *maxsplit* is not specified or ``-1``, then there is\n no limit on the number of splits (all possible splits are made).\n\n If *sep* is given, consecutive delimiters are not grouped together\n and are deemed to delimit empty strings (for example,\n ``\'1,,2\'.split(\',\')`` returns ``[\'1\', \'\', \'2\']``). The *sep*\n argument may consist of multiple characters (for example,\n ``\'1<>2<>3\'.split(\'<>\')`` returns ``[\'1\', \'2\', \'3\']``). Splitting\n an empty string with a specified separator returns ``[\'\']``.\n\n If *sep* is not specified or is ``None``, a different splitting\n algorithm is applied: runs of consecutive whitespace are regarded\n as a single separator, and the result will contain no empty strings\n at the start or end if the string has leading or trailing\n whitespace. Consequently, splitting an empty string or a string\n consisting of just whitespace with a ``None`` separator returns\n ``[]``.\n\n For example, ``\' 1 2 3 \'.split()`` returns ``[\'1\', \'2\', \'3\']``,\n and ``\' 1 2 3 \'.split(None, 1)`` returns ``[\'1\', \'2 3 \']``.\n\nstr.splitlines([keepends])\n\n Return a list of the lines in the string, breaking at line\n boundaries. This method uses the *universal newlines* approach to\n splitting lines. Line breaks are not included in the resulting list\n unless *keepends* is given and true.\n\n For example, ``\'ab c\\n\\nde fg\\rkl\\r\\n\'.splitlines()`` returns\n ``[\'ab c\', \'\', \'de fg\', \'kl\']``, while the same call with\n ``splitlines(True)`` returns ``[\'ab c\\n\', \'\\n\', \'de fg\\r\',\n \'kl\\r\\n\']``.\n\n Unlike ``split()`` when a delimiter string *sep* is given, this\n method returns an empty list for the empty string, and a terminal\n line break does not result in an extra line.\n\nstr.startswith(prefix[, start[, end]])\n\n Return ``True`` if string starts with the *prefix*, otherwise\n return ``False``. *prefix* can also be a tuple of prefixes to look\n for. With optional *start*, test string beginning at that\n position. With optional *end*, stop comparing string at that\n position.\n\nstr.strip([chars])\n\n Return a copy of the string with the leading and trailing\n characters removed. The *chars* argument is a string specifying the\n set of characters to be removed. If omitted or ``None``, the\n *chars* argument defaults to removing whitespace. The *chars*\n argument is not a prefix or suffix; rather, all combinations of its\n values are stripped:\n\n >>> \' spacious \'.strip()\n \'spacious\'\n >>> \'www.example.com\'.strip(\'cmowz.\')\n \'example\'\n\nstr.swapcase()\n\n Return a copy of the string with uppercase characters converted to\n lowercase and vice versa. Note that it is not necessarily true that\n ``s.swapcase().swapcase() == s``.\n\nstr.title()\n\n Return a titlecased version of the string where words start with an\n uppercase character and the remaining characters are lowercase.\n\n The algorithm uses a simple language-independent definition of a\n word as groups of consecutive letters. The definition works in\n many contexts but it means that apostrophes in contractions and\n possessives form word boundaries, which may not be the desired\n result:\n\n >>> "they\'re bill\'s friends from the UK".title()\n "They\'Re Bill\'S Friends From The Uk"\n\n A workaround for apostrophes can be constructed using regular\n expressions:\n\n >>> import re\n >>> def titlecase(s):\n ... return re.sub(r"[A-Za-z]+(\'[A-Za-z]+)?",\n ... lambda mo: mo.group(0)[0].upper() +\n ... mo.group(0)[1:].lower(),\n ... s)\n ...\n >>> titlecase("they\'re bill\'s friends.")\n "They\'re Bill\'s Friends."\n\nstr.translate(map)\n\n Return a copy of the *s* where all characters have been mapped\n through the *map* which must be a dictionary of Unicode ordinals\n (integers) to Unicode ordinals, strings or ``None``. Unmapped\n characters are left untouched. Characters mapped to ``None`` are\n deleted.\n\n You can use ``str.maketrans()`` to create a translation map from\n character-to-character mappings in different formats.\n\n Note: An even more flexible approach is to create a custom character\n mapping codec using the ``codecs`` module (see\n ``encodings.cp1251`` for an example).\n\nstr.upper()\n\n Return a copy of the string with all the cased characters [4]\n converted to uppercase. Note that ``str.upper().isupper()`` might\n be ``False`` if ``s`` contains uncased characters or if the Unicode\n category of the resulting character(s) is not "Lu" (Letter,\n uppercase), but e.g. "Lt" (Letter, titlecase).\n\n The uppercasing algorithm used is described in section 3.13 of the\n Unicode Standard.\n\nstr.zfill(width)\n\n Return the numeric string left filled with zeros in a string of\n length *width*. A sign prefix is handled correctly. The original\n string is returned if *width* is less than or equal to ``len(s)``.\n', - 'strings': '\nString and Bytes literals\n*************************\n\nString literals are described by the following lexical definitions:\n\n stringliteral ::= [stringprefix](shortstring | longstring)\n stringprefix ::= "r" | "u" | "R" | "U"\n shortstring ::= "\'" shortstringitem* "\'" | \'"\' shortstringitem* \'"\'\n longstring ::= "\'\'\'" longstringitem* "\'\'\'" | \'"""\' longstringitem* \'"""\'\n shortstringitem ::= shortstringchar | stringescapeseq\n longstringitem ::= longstringchar | stringescapeseq\n shortstringchar ::= <any source character except "\\" or newline or the quote>\n longstringchar ::= <any source character except "\\">\n stringescapeseq ::= "\\" <any source character>\n\n bytesliteral ::= bytesprefix(shortbytes | longbytes)\n bytesprefix ::= "b" | "B" | "br" | "Br" | "bR" | "BR" | "rb" | "rB" | "Rb" | "RB"\n shortbytes ::= "\'" shortbytesitem* "\'" | \'"\' shortbytesitem* \'"\'\n longbytes ::= "\'\'\'" longbytesitem* "\'\'\'" | \'"""\' longbytesitem* \'"""\'\n shortbytesitem ::= shortbyteschar | bytesescapeseq\n longbytesitem ::= longbyteschar | bytesescapeseq\n shortbyteschar ::= <any ASCII character except "\\" or newline or the quote>\n longbyteschar ::= <any ASCII character except "\\">\n bytesescapeseq ::= "\\" <any ASCII character>\n\nOne syntactic restriction not indicated by these productions is that\nwhitespace is not allowed between the ``stringprefix`` or\n``bytesprefix`` and the rest of the literal. The source character set\nis defined by the encoding declaration; it is UTF-8 if no encoding\ndeclaration is given in the source file; see section *Encoding\ndeclarations*.\n\nIn plain English: Both types of literals can be enclosed in matching\nsingle quotes (``\'``) or double quotes (``"``). They can also be\nenclosed in matching groups of three single or double quotes (these\nare generally referred to as *triple-quoted strings*). The backslash\n(``\\``) character is used to escape characters that otherwise have a\nspecial meaning, such as newline, backslash itself, or the quote\ncharacter.\n\nBytes literals are always prefixed with ``\'b\'`` or ``\'B\'``; they\nproduce an instance of the ``bytes`` type instead of the ``str`` type.\nThey may only contain ASCII characters; bytes with a numeric value of\n128 or greater must be expressed with escapes.\n\nAs of Python 3.3 it is possible again to prefix unicode strings with a\n``u`` prefix to simplify maintenance of dual 2.x and 3.x codebases.\n\nBoth string and bytes literals may optionally be prefixed with a\nletter ``\'r\'`` or ``\'R\'``; such strings are called *raw strings* and\ntreat backslashes as literal characters. As a result, in string\nliterals, ``\'\\U\'`` and ``\'\\u\'`` escapes in raw strings are not treated\nspecially. Given that Python 2.x\'s raw unicode literals behave\ndifferently than Python 3.x\'s the ``\'ur\'`` syntax is not supported.\n\n New in version 3.3: The ``\'rb\'`` prefix of raw bytes literals has\n been added as a synonym of ``\'br\'``.\n\n New in version 3.3: Support for the unicode legacy literal\n (``u\'value\'``) was reintroduced to simplify the maintenance of dual\n Python 2.x and 3.x codebases. See **PEP 414** for more information.\n\nIn triple-quoted strings, unescaped newlines and quotes are allowed\n(and are retained), except that three unescaped quotes in a row\nterminate the string. (A "quote" is the character used to open the\nstring, i.e. either ``\'`` or ``"``.)\n\nUnless an ``\'r\'`` or ``\'R\'`` prefix is present, escape sequences in\nstrings are interpreted according to rules similar to those used by\nStandard C. The recognized escape sequences are:\n\n+-------------------+-----------------------------------+---------+\n| Escape Sequence | Meaning | Notes |\n+===================+===================================+=========+\n| ``\\newline`` | Backslash and newline ignored | |\n+-------------------+-----------------------------------+---------+\n| ``\\\\`` | Backslash (``\\``) | |\n+-------------------+-----------------------------------+---------+\n| ``\\\'`` | Single quote (``\'``) | |\n+-------------------+-----------------------------------+---------+\n| ``\\"`` | Double quote (``"``) | |\n+-------------------+-----------------------------------+---------+\n| ``\\a`` | ASCII Bell (BEL) | |\n+-------------------+-----------------------------------+---------+\n| ``\\b`` | ASCII Backspace (BS) | |\n+-------------------+-----------------------------------+---------+\n| ``\\f`` | ASCII Formfeed (FF) | |\n+-------------------+-----------------------------------+---------+\n| ``\\n`` | ASCII Linefeed (LF) | |\n+-------------------+-----------------------------------+---------+\n| ``\\r`` | ASCII Carriage Return (CR) | |\n+-------------------+-----------------------------------+---------+\n| ``\\t`` | ASCII Horizontal Tab (TAB) | |\n+-------------------+-----------------------------------+---------+\n| ``\\v`` | ASCII Vertical Tab (VT) | |\n+-------------------+-----------------------------------+---------+\n| ``\\ooo`` | Character with octal value *ooo* | (1,3) |\n+-------------------+-----------------------------------+---------+\n| ``\\xhh`` | Character with hex value *hh* | (2,3) |\n+-------------------+-----------------------------------+---------+\n\nEscape sequences only recognized in string literals are:\n\n+-------------------+-----------------------------------+---------+\n| Escape Sequence | Meaning | Notes |\n+===================+===================================+=========+\n| ``\\N{name}`` | Character named *name* in the | (4) |\n| | Unicode database | |\n+-------------------+-----------------------------------+---------+\n| ``\\uxxxx`` | Character with 16-bit hex value | (5) |\n| | *xxxx* | |\n+-------------------+-----------------------------------+---------+\n| ``\\Uxxxxxxxx`` | Character with 32-bit hex value | (6) |\n| | *xxxxxxxx* | |\n+-------------------+-----------------------------------+---------+\n\nNotes:\n\n1. As in Standard C, up to three octal digits are accepted.\n\n2. Unlike in Standard C, exactly two hex digits are required.\n\n3. In a bytes literal, hexadecimal and octal escapes denote the byte\n with the given value. In a string literal, these escapes denote a\n Unicode character with the given value.\n\n4. Changed in version 3.3: Support for name aliases [1] has been\n added.\n\n5. Individual code units which form parts of a surrogate pair can be\n encoded using this escape sequence. Exactly four hex digits are\n required.\n\n6. Any Unicode character can be encoded this way. Exactly eight hex\n digits are required.\n\nUnlike Standard C, all unrecognized escape sequences are left in the\nstring unchanged, i.e., *the backslash is left in the string*. (This\nbehavior is useful when debugging: if an escape sequence is mistyped,\nthe resulting output is more easily recognized as broken.) It is also\nimportant to note that the escape sequences only recognized in string\nliterals fall into the category of unrecognized escapes for bytes\nliterals.\n\nEven in a raw string, string quotes can be escaped with a backslash,\nbut the backslash remains in the string; for example, ``r"\\""`` is a\nvalid string literal consisting of two characters: a backslash and a\ndouble quote; ``r"\\"`` is not a valid string literal (even a raw\nstring cannot end in an odd number of backslashes). Specifically, *a\nraw string cannot end in a single backslash* (since the backslash\nwould escape the following quote character). Note also that a single\nbackslash followed by a newline is interpreted as those two characters\nas part of the string, *not* as a line continuation.\n', - 'subscriptions': '\nSubscriptions\n*************\n\nA subscription selects an item of a sequence (string, tuple or list)\nor mapping (dictionary) object:\n\n subscription ::= primary "[" expression_list "]"\n\nThe primary must evaluate to an object that supports subscription,\ne.g. a list or dictionary. User-defined objects can support\nsubscription by defining a ``__getitem__()`` method.\n\nFor built-in objects, there are two types of objects that support\nsubscription:\n\nIf the primary is a mapping, the expression list must evaluate to an\nobject whose value is one of the keys of the mapping, and the\nsubscription selects the value in the mapping that corresponds to that\nkey. (The expression list is a tuple except if it has exactly one\nitem.)\n\nIf the primary is a sequence, the expression (list) must evaluate to\nan integer or a slice (as discussed in the following section).\n\nThe formal syntax makes no special provision for negative indices in\nsequences; however, built-in sequences all provide a ``__getitem__()``\nmethod that interprets negative indices by adding the length of the\nsequence to the index (so that ``x[-1]`` selects the last item of\n``x``). The resulting value must be a nonnegative integer less than\nthe number of items in the sequence, and the subscription selects the\nitem whose index is that value (counting from zero). Since the support\nfor negative indices and slicing occurs in the object\'s\n``__getitem__()`` method, subclasses overriding this method will need\nto explicitly add that support.\n\nA string\'s items are characters. A character is not a separate data\ntype but a string of exactly one character.\n', - 'truth': "\nTruth Value Testing\n*******************\n\nAny object can be tested for truth value, for use in an ``if`` or\n``while`` condition or as operand of the Boolean operations below. The\nfollowing values are considered false:\n\n* ``None``\n\n* ``False``\n\n* zero of any numeric type, for example, ``0``, ``0.0``, ``0j``.\n\n* any empty sequence, for example, ``''``, ``()``, ``[]``.\n\n* any empty mapping, for example, ``{}``.\n\n* instances of user-defined classes, if the class defines a\n ``__bool__()`` or ``__len__()`` method, when that method returns the\n integer zero or ``bool`` value ``False``. [1]\n\nAll other values are considered true --- so objects of many types are\nalways true.\n\nOperations and built-in functions that have a Boolean result always\nreturn ``0`` or ``False`` for false and ``1`` or ``True`` for true,\nunless otherwise stated. (Important exception: the Boolean operations\n``or`` and ``and`` always return one of their operands.)\n", - 'try': '\nThe ``try`` statement\n*********************\n\nThe ``try`` statement specifies exception handlers and/or cleanup code\nfor a group of statements:\n\n try_stmt ::= try1_stmt | try2_stmt\n try1_stmt ::= "try" ":" suite\n ("except" [expression ["as" target]] ":" suite)+\n ["else" ":" suite]\n ["finally" ":" suite]\n try2_stmt ::= "try" ":" suite\n "finally" ":" suite\n\nThe ``except`` clause(s) specify one or more exception handlers. When\nno exception occurs in the ``try`` clause, no exception handler is\nexecuted. When an exception occurs in the ``try`` suite, a search for\nan exception handler is started. This search inspects the except\nclauses in turn until one is found that matches the exception. An\nexpression-less except clause, if present, must be last; it matches\nany exception. For an except clause with an expression, that\nexpression is evaluated, and the clause matches the exception if the\nresulting object is "compatible" with the exception. An object is\ncompatible with an exception if it is the class or a base class of the\nexception object or a tuple containing an item compatible with the\nexception.\n\nIf no except clause matches the exception, the search for an exception\nhandler continues in the surrounding code and on the invocation stack.\n[1]\n\nIf the evaluation of an expression in the header of an except clause\nraises an exception, the original search for a handler is canceled and\na search starts for the new exception in the surrounding code and on\nthe call stack (it is treated as if the entire ``try`` statement\nraised the exception).\n\nWhen a matching except clause is found, the exception is assigned to\nthe target specified after the ``as`` keyword in that except clause,\nif present, and the except clause\'s suite is executed. All except\nclauses must have an executable block. When the end of this block is\nreached, execution continues normally after the entire try statement.\n(This means that if two nested handlers exist for the same exception,\nand the exception occurs in the try clause of the inner handler, the\nouter handler will not handle the exception.)\n\nWhen an exception has been assigned using ``as target``, it is cleared\nat the end of the except clause. This is as if\n\n except E as N:\n foo\n\nwas translated to\n\n except E as N:\n try:\n foo\n finally:\n del N\n\nThis means the exception must be assigned to a different name to be\nable to refer to it after the except clause. Exceptions are cleared\nbecause with the traceback attached to them, they form a reference\ncycle with the stack frame, keeping all locals in that frame alive\nuntil the next garbage collection occurs.\n\nBefore an except clause\'s suite is executed, details about the\nexception are stored in the ``sys`` module and can be access via\n``sys.exc_info()``. ``sys.exc_info()`` returns a 3-tuple consisting of\nthe exception class, the exception instance and a traceback object\n(see section *The standard type hierarchy*) identifying the point in\nthe program where the exception occurred. ``sys.exc_info()`` values\nare restored to their previous values (before the call) when returning\nfrom a function that handled an exception.\n\nThe optional ``else`` clause is executed if and when control flows off\nthe end of the ``try`` clause. [2] Exceptions in the ``else`` clause\nare not handled by the preceding ``except`` clauses.\n\nIf ``finally`` is present, it specifies a \'cleanup\' handler. The\n``try`` clause is executed, including any ``except`` and ``else``\nclauses. If an exception occurs in any of the clauses and is not\nhandled, the exception is temporarily saved. The ``finally`` clause is\nexecuted. If there is a saved exception it is re-raised at the end of\nthe ``finally`` clause. If the ``finally`` clause raises another\nexception, the saved exception is set as the context of the new\nexception. If the ``finally`` clause executes a ``return`` or\n``break`` statement, the saved exception is discarded:\n\n def f():\n try:\n 1/0\n finally:\n return 42\n\n >>> f()\n 42\n\nThe exception information is not available to the program during\nexecution of the ``finally`` clause.\n\nWhen a ``return``, ``break`` or ``continue`` statement is executed in\nthe ``try`` suite of a ``try``...``finally`` statement, the\n``finally`` clause is also executed \'on the way out.\' A ``continue``\nstatement is illegal in the ``finally`` clause. (The reason is a\nproblem with the current implementation --- this restriction may be\nlifted in the future).\n\nAdditional information on exceptions can be found in section\n*Exceptions*, and information on using the ``raise`` statement to\ngenerate exceptions may be found in section *The raise statement*.\n', - 'types': '\nThe standard type hierarchy\n***************************\n\nBelow is a list of the types that are built into Python. Extension\nmodules (written in C, Java, or other languages, depending on the\nimplementation) can define additional types. Future versions of\nPython may add types to the type hierarchy (e.g., rational numbers,\nefficiently stored arrays of integers, etc.), although such additions\nwill often be provided via the standard library instead.\n\nSome of the type descriptions below contain a paragraph listing\n\'special attributes.\' These are attributes that provide access to the\nimplementation and are not intended for general use. Their definition\nmay change in the future.\n\nNone\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name ``None``.\n It is used to signify the absence of a value in many situations,\n e.g., it is returned from functions that don\'t explicitly return\n anything. Its truth value is false.\n\nNotImplemented\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name\n ``NotImplemented``. Numeric methods and rich comparison methods may\n return this value if they do not implement the operation for the\n operands provided. (The interpreter will then try the reflected\n operation, or some other fallback, depending on the operator.) Its\n truth value is true.\n\nEllipsis\n This type has a single value. There is a single object with this\n value. This object is accessed through the literal ``...`` or the\n built-in name ``Ellipsis``. Its truth value is true.\n\n``numbers.Number``\n These are created by numeric literals and returned as results by\n arithmetic operators and arithmetic built-in functions. Numeric\n objects are immutable; once created their value never changes.\n Python numbers are of course strongly related to mathematical\n numbers, but subject to the limitations of numerical representation\n in computers.\n\n Python distinguishes between integers, floating point numbers, and\n complex numbers:\n\n ``numbers.Integral``\n These represent elements from the mathematical set of integers\n (positive and negative).\n\n There are two types of integers:\n\n Integers (``int``)\n\n These represent numbers in an unlimited range, subject to\n available (virtual) memory only. For the purpose of shift\n and mask operations, a binary representation is assumed, and\n negative numbers are represented in a variant of 2\'s\n complement which gives the illusion of an infinite string of\n sign bits extending to the left.\n\n Booleans (``bool``)\n These represent the truth values False and True. The two\n objects representing the values False and True are the only\n Boolean objects. The Boolean type is a subtype of the integer\n type, and Boolean values behave like the values 0 and 1,\n respectively, in almost all contexts, the exception being\n that when converted to a string, the strings ``"False"`` or\n ``"True"`` are returned, respectively.\n\n The rules for integer representation are intended to give the\n most meaningful interpretation of shift and mask operations\n involving negative integers.\n\n ``numbers.Real`` (``float``)\n These represent machine-level double precision floating point\n numbers. You are at the mercy of the underlying machine\n architecture (and C or Java implementation) for the accepted\n range and handling of overflow. Python does not support single-\n precision floating point numbers; the savings in processor and\n memory usage that are usually the reason for using these is\n dwarfed by the overhead of using objects in Python, so there is\n no reason to complicate the language with two kinds of floating\n point numbers.\n\n ``numbers.Complex`` (``complex``)\n These represent complex numbers as a pair of machine-level\n double precision floating point numbers. The same caveats apply\n as for floating point numbers. The real and imaginary parts of a\n complex number ``z`` can be retrieved through the read-only\n attributes ``z.real`` and ``z.imag``.\n\nSequences\n These represent finite ordered sets indexed by non-negative\n numbers. The built-in function ``len()`` returns the number of\n items of a sequence. When the length of a sequence is *n*, the\n index set contains the numbers 0, 1, ..., *n*-1. Item *i* of\n sequence *a* is selected by ``a[i]``.\n\n Sequences also support slicing: ``a[i:j]`` selects all items with\n index *k* such that *i* ``<=`` *k* ``<`` *j*. When used as an\n expression, a slice is a sequence of the same type. This implies\n that the index set is renumbered so that it starts at 0.\n\n Some sequences also support "extended slicing" with a third "step"\n parameter: ``a[i:j:k]`` selects all items of *a* with index *x*\n where ``x = i + n*k``, *n* ``>=`` ``0`` and *i* ``<=`` *x* ``<``\n *j*.\n\n Sequences are distinguished according to their mutability:\n\n Immutable sequences\n An object of an immutable sequence type cannot change once it is\n created. (If the object contains references to other objects,\n these other objects may be mutable and may be changed; however,\n the collection of objects directly referenced by an immutable\n object cannot change.)\n\n The following types are immutable sequences:\n\n Strings\n A string is a sequence of values that represent Unicode\n codepoints. All the codepoints in range ``U+0000 - U+10FFFF``\n can be represented in a string. Python doesn\'t have a\n ``chr`` type, and every character in the string is\n represented as a string object with length ``1``. The built-\n in function ``ord()`` converts a character to its codepoint\n (as an integer); ``chr()`` converts an integer in range ``0 -\n 10FFFF`` to the corresponding character. ``str.encode()`` can\n be used to convert a ``str`` to ``bytes`` using the given\n encoding, and ``bytes.decode()`` can be used to achieve the\n opposite.\n\n Tuples\n The items of a tuple are arbitrary Python objects. Tuples of\n two or more items are formed by comma-separated lists of\n expressions. A tuple of one item (a \'singleton\') can be\n formed by affixing a comma to an expression (an expression by\n itself does not create a tuple, since parentheses must be\n usable for grouping of expressions). An empty tuple can be\n formed by an empty pair of parentheses.\n\n Bytes\n A bytes object is an immutable array. The items are 8-bit\n bytes, represented by integers in the range 0 <= x < 256.\n Bytes literals (like ``b\'abc\'``) and the built-in function\n ``bytes()`` can be used to construct bytes objects. Also,\n bytes objects can be decoded to strings via the ``decode()``\n method.\n\n Mutable sequences\n Mutable sequences can be changed after they are created. The\n subscription and slicing notations can be used as the target of\n assignment and ``del`` (delete) statements.\n\n There are currently two intrinsic mutable sequence types:\n\n Lists\n The items of a list are arbitrary Python objects. Lists are\n formed by placing a comma-separated list of expressions in\n square brackets. (Note that there are no special cases needed\n to form lists of length 0 or 1.)\n\n Byte Arrays\n A bytearray object is a mutable array. They are created by\n the built-in ``bytearray()`` constructor. Aside from being\n mutable (and hence unhashable), byte arrays otherwise provide\n the same interface and functionality as immutable bytes\n objects.\n\n The extension module ``array`` provides an additional example of\n a mutable sequence type, as does the ``collections`` module.\n\nSet types\n These represent unordered, finite sets of unique, immutable\n objects. As such, they cannot be indexed by any subscript. However,\n they can be iterated over, and the built-in function ``len()``\n returns the number of items in a set. Common uses for sets are fast\n membership testing, removing duplicates from a sequence, and\n computing mathematical operations such as intersection, union,\n difference, and symmetric difference.\n\n For set elements, the same immutability rules apply as for\n dictionary keys. Note that numeric types obey the normal rules for\n numeric comparison: if two numbers compare equal (e.g., ``1`` and\n ``1.0``), only one of them can be contained in a set.\n\n There are currently two intrinsic set types:\n\n Sets\n These represent a mutable set. They are created by the built-in\n ``set()`` constructor and can be modified afterwards by several\n methods, such as ``add()``.\n\n Frozen sets\n These represent an immutable set. They are created by the\n built-in ``frozenset()`` constructor. As a frozenset is\n immutable and *hashable*, it can be used again as an element of\n another set, or as a dictionary key.\n\nMappings\n These represent finite sets of objects indexed by arbitrary index\n sets. The subscript notation ``a[k]`` selects the item indexed by\n ``k`` from the mapping ``a``; this can be used in expressions and\n as the target of assignments or ``del`` statements. The built-in\n function ``len()`` returns the number of items in a mapping.\n\n There is currently a single intrinsic mapping type:\n\n Dictionaries\n These represent finite sets of objects indexed by nearly\n arbitrary values. The only types of values not acceptable as\n keys are values containing lists or dictionaries or other\n mutable types that are compared by value rather than by object\n identity, the reason being that the efficient implementation of\n dictionaries requires a key\'s hash value to remain constant.\n Numeric types used for keys obey the normal rules for numeric\n comparison: if two numbers compare equal (e.g., ``1`` and\n ``1.0``) then they can be used interchangeably to index the same\n dictionary entry.\n\n Dictionaries are mutable; they can be created by the ``{...}``\n notation (see section *Dictionary displays*).\n\n The extension modules ``dbm.ndbm`` and ``dbm.gnu`` provide\n additional examples of mapping types, as does the\n ``collections`` module.\n\nCallable types\n These are the types to which the function call operation (see\n section *Calls*) can be applied:\n\n User-defined functions\n A user-defined function object is created by a function\n definition (see section *Function definitions*). It should be\n called with an argument list containing the same number of items\n as the function\'s formal parameter list.\n\n Special attributes:\n\n +---------------------------+---------------------------------+-------------+\n | Attribute | Meaning | |\n +===========================+=================================+=============+\n | ``__doc__`` | The function\'s documentation | Writable |\n | | string, or ``None`` if | |\n | | unavailable | |\n +---------------------------+---------------------------------+-------------+\n | ``__name__`` | The function\'s name | Writable |\n +---------------------------+---------------------------------+-------------+\n | ``__qualname__`` | The function\'s *qualified name* | Writable |\n | | New in version 3.3. | |\n +---------------------------+---------------------------------+-------------+\n | ``__module__`` | The name of the module the | Writable |\n | | function was defined in, or | |\n | | ``None`` if unavailable. | |\n +---------------------------+---------------------------------+-------------+\n | ``__defaults__`` | A tuple containing default | Writable |\n | | argument values for those | |\n | | arguments that have defaults, | |\n | | or ``None`` if no arguments | |\n | | have a default value | |\n +---------------------------+---------------------------------+-------------+\n | ``__code__`` | The code object representing | Writable |\n | | the compiled function body. | |\n +---------------------------+---------------------------------+-------------+\n | ``__globals__`` | A reference to the dictionary | Read-only |\n | | that holds the function\'s | |\n | | global variables --- the global | |\n | | namespace of the module in | |\n | | which the function was defined. | |\n +---------------------------+---------------------------------+-------------+\n | ``__dict__`` | The namespace supporting | Writable |\n | | arbitrary function attributes. | |\n +---------------------------+---------------------------------+-------------+\n | ``__closure__`` | ``None`` or a tuple of cells | Read-only |\n | | that contain bindings for the | |\n | | function\'s free variables. | |\n +---------------------------+---------------------------------+-------------+\n | ``__annotations__`` | A dict containing annotations | Writable |\n | | of parameters. The keys of the | |\n | | dict are the parameter names, | |\n | | or ``\'return\'`` for the return | |\n | | annotation, if provided. | |\n +---------------------------+---------------------------------+-------------+\n | ``__kwdefaults__`` | A dict containing defaults for | Writable |\n | | keyword-only parameters. | |\n +---------------------------+---------------------------------+-------------+\n\n Most of the attributes labelled "Writable" check the type of the\n assigned value.\n\n Function objects also support getting and setting arbitrary\n attributes, which can be used, for example, to attach metadata\n to functions. Regular attribute dot-notation is used to get and\n set such attributes. *Note that the current implementation only\n supports function attributes on user-defined functions. Function\n attributes on built-in functions may be supported in the\n future.*\n\n Additional information about a function\'s definition can be\n retrieved from its code object; see the description of internal\n types below.\n\n Instance methods\n An instance method object combines a class, a class instance and\n any callable object (normally a user-defined function).\n\n Special read-only attributes: ``__self__`` is the class instance\n object, ``__func__`` is the function object; ``__doc__`` is the\n method\'s documentation (same as ``__func__.__doc__``);\n ``__name__`` is the method name (same as ``__func__.__name__``);\n ``__module__`` is the name of the module the method was defined\n in, or ``None`` if unavailable.\n\n Methods also support accessing (but not setting) the arbitrary\n function attributes on the underlying function object.\n\n User-defined method objects may be created when getting an\n attribute of a class (perhaps via an instance of that class), if\n that attribute is a user-defined function object or a class\n method object.\n\n When an instance method object is created by retrieving a user-\n defined function object from a class via one of its instances,\n its ``__self__`` attribute is the instance, and the method\n object is said to be bound. The new method\'s ``__func__``\n attribute is the original function object.\n\n When a user-defined method object is created by retrieving\n another method object from a class or instance, the behaviour is\n the same as for a function object, except that the ``__func__``\n attribute of the new instance is not the original method object\n but its ``__func__`` attribute.\n\n When an instance method object is created by retrieving a class\n method object from a class or instance, its ``__self__``\n attribute is the class itself, and its ``__func__`` attribute is\n the function object underlying the class method.\n\n When an instance method object is called, the underlying\n function (``__func__``) is called, inserting the class instance\n (``__self__``) in front of the argument list. For instance,\n when ``C`` is a class which contains a definition for a function\n ``f()``, and ``x`` is an instance of ``C``, calling ``x.f(1)``\n is equivalent to calling ``C.f(x, 1)``.\n\n When an instance method object is derived from a class method\n object, the "class instance" stored in ``__self__`` will\n actually be the class itself, so that calling either ``x.f(1)``\n or ``C.f(1)`` is equivalent to calling ``f(C,1)`` where ``f`` is\n the underlying function.\n\n Note that the transformation from function object to instance\n method object happens each time the attribute is retrieved from\n the instance. In some cases, a fruitful optimization is to\n assign the attribute to a local variable and call that local\n variable. Also notice that this transformation only happens for\n user-defined functions; other callable objects (and all non-\n callable objects) are retrieved without transformation. It is\n also important to note that user-defined functions which are\n attributes of a class instance are not converted to bound\n methods; this *only* happens when the function is an attribute\n of the class.\n\n Generator functions\n A function or method which uses the ``yield`` statement (see\n section *The yield statement*) is called a *generator function*.\n Such a function, when called, always returns an iterator object\n which can be used to execute the body of the function: calling\n the iterator\'s ``iterator.__next__()`` method will cause the\n function to execute until it provides a value using the\n ``yield`` statement. When the function executes a ``return``\n statement or falls off the end, a ``StopIteration`` exception is\n raised and the iterator will have reached the end of the set of\n values to be returned.\n\n Built-in functions\n A built-in function object is a wrapper around a C function.\n Examples of built-in functions are ``len()`` and ``math.sin()``\n (``math`` is a standard built-in module). The number and type of\n the arguments are determined by the C function. Special read-\n only attributes: ``__doc__`` is the function\'s documentation\n string, or ``None`` if unavailable; ``__name__`` is the\n function\'s name; ``__self__`` is set to ``None`` (but see the\n next item); ``__module__`` is the name of the module the\n function was defined in or ``None`` if unavailable.\n\n Built-in methods\n This is really a different disguise of a built-in function, this\n time containing an object passed to the C function as an\n implicit extra argument. An example of a built-in method is\n ``alist.append()``, assuming *alist* is a list object. In this\n case, the special read-only attribute ``__self__`` is set to the\n object denoted by *alist*.\n\n Classes\n Classes are callable. These objects normally act as factories\n for new instances of themselves, but variations are possible for\n class types that override ``__new__()``. The arguments of the\n call are passed to ``__new__()`` and, in the typical case, to\n ``__init__()`` to initialize the new instance.\n\n Class Instances\n Instances of arbitrary classes can be made callable by defining\n a ``__call__()`` method in their class.\n\nModules\n Modules are a basic organizational unit of Python code, and are\n created by the *import system* as invoked either by the ``import``\n statement (see ``import``), or by calling functions such as\n ``importlib.import_module()`` and built-in ``__import__()``. A\n module object has a namespace implemented by a dictionary object\n (this is the dictionary referenced by the ``__globals__`` attribute\n of functions defined in the module). Attribute references are\n translated to lookups in this dictionary, e.g., ``m.x`` is\n equivalent to ``m.__dict__["x"]``. A module object does not contain\n the code object used to initialize the module (since it isn\'t\n needed once the initialization is done).\n\n Attribute assignment updates the module\'s namespace dictionary,\n e.g., ``m.x = 1`` is equivalent to ``m.__dict__["x"] = 1``.\n\n Special read-only attribute: ``__dict__`` is the module\'s namespace\n as a dictionary object.\n\n **CPython implementation detail:** Because of the way CPython\n clears module dictionaries, the module dictionary will be cleared\n when the module falls out of scope even if the dictionary still has\n live references. To avoid this, copy the dictionary or keep the\n module around while using its dictionary directly.\n\n Predefined (writable) attributes: ``__name__`` is the module\'s\n name; ``__doc__`` is the module\'s documentation string, or ``None``\n if unavailable; ``__file__`` is the pathname of the file from which\n the module was loaded, if it was loaded from a file. The\n ``__file__`` attribute may be missing for certain types of modules,\n such as C modules that are statically linked into the interpreter;\n for extension modules loaded dynamically from a shared library, it\n is the pathname of the shared library file.\n\nCustom classes\n Custom class types are typically created by class definitions (see\n section *Class definitions*). A class has a namespace implemented\n by a dictionary object. Class attribute references are translated\n to lookups in this dictionary, e.g., ``C.x`` is translated to\n ``C.__dict__["x"]`` (although there are a number of hooks which\n allow for other means of locating attributes). When the attribute\n name is not found there, the attribute search continues in the base\n classes. This search of the base classes uses the C3 method\n resolution order which behaves correctly even in the presence of\n \'diamond\' inheritance structures where there are multiple\n inheritance paths leading back to a common ancestor. Additional\n details on the C3 MRO used by Python can be found in the\n documentation accompanying the 2.3 release at\n http://www.python.org/download/releases/2.3/mro/.\n\n When a class attribute reference (for class ``C``, say) would yield\n a class method object, it is transformed into an instance method\n object whose ``__self__`` attributes is ``C``. When it would yield\n a static method object, it is transformed into the object wrapped\n by the static method object. See section *Implementing Descriptors*\n for another way in which attributes retrieved from a class may\n differ from those actually contained in its ``__dict__``.\n\n Class attribute assignments update the class\'s dictionary, never\n the dictionary of a base class.\n\n A class object can be called (see above) to yield a class instance\n (see below).\n\n Special attributes: ``__name__`` is the class name; ``__module__``\n is the module name in which the class was defined; ``__dict__`` is\n the dictionary containing the class\'s namespace; ``__bases__`` is a\n tuple (possibly empty or a singleton) containing the base classes,\n in the order of their occurrence in the base class list;\n ``__doc__`` is the class\'s documentation string, or None if\n undefined.\n\nClass instances\n A class instance is created by calling a class object (see above).\n A class instance has a namespace implemented as a dictionary which\n is the first place in which attribute references are searched.\n When an attribute is not found there, and the instance\'s class has\n an attribute by that name, the search continues with the class\n attributes. If a class attribute is found that is a user-defined\n function object, it is transformed into an instance method object\n whose ``__self__`` attribute is the instance. Static method and\n class method objects are also transformed; see above under\n "Classes". See section *Implementing Descriptors* for another way\n in which attributes of a class retrieved via its instances may\n differ from the objects actually stored in the class\'s\n ``__dict__``. If no class attribute is found, and the object\'s\n class has a ``__getattr__()`` method, that is called to satisfy the\n lookup.\n\n Attribute assignments and deletions update the instance\'s\n dictionary, never a class\'s dictionary. If the class has a\n ``__setattr__()`` or ``__delattr__()`` method, this is called\n instead of updating the instance dictionary directly.\n\n Class instances can pretend to be numbers, sequences, or mappings\n if they have methods with certain special names. See section\n *Special method names*.\n\n Special attributes: ``__dict__`` is the attribute dictionary;\n ``__class__`` is the instance\'s class.\n\nI/O objects (also known as file objects)\n A *file object* represents an open file. Various shortcuts are\n available to create file objects: the ``open()`` built-in function,\n and also ``os.popen()``, ``os.fdopen()``, and the ``makefile()``\n method of socket objects (and perhaps by other functions or methods\n provided by extension modules).\n\n The objects ``sys.stdin``, ``sys.stdout`` and ``sys.stderr`` are\n initialized to file objects corresponding to the interpreter\'s\n standard input, output and error streams; they are all open in text\n mode and therefore follow the interface defined by the\n ``io.TextIOBase`` abstract class.\n\nInternal types\n A few types used internally by the interpreter are exposed to the\n user. Their definitions may change with future versions of the\n interpreter, but they are mentioned here for completeness.\n\n Code objects\n Code objects represent *byte-compiled* executable Python code,\n or *bytecode*. The difference between a code object and a\n function object is that the function object contains an explicit\n reference to the function\'s globals (the module in which it was\n defined), while a code object contains no context; also the\n default argument values are stored in the function object, not\n in the code object (because they represent values calculated at\n run-time). Unlike function objects, code objects are immutable\n and contain no references (directly or indirectly) to mutable\n objects.\n\n Special read-only attributes: ``co_name`` gives the function\n name; ``co_argcount`` is the number of positional arguments\n (including arguments with default values); ``co_nlocals`` is the\n number of local variables used by the function (including\n arguments); ``co_varnames`` is a tuple containing the names of\n the local variables (starting with the argument names);\n ``co_cellvars`` is a tuple containing the names of local\n variables that are referenced by nested functions;\n ``co_freevars`` is a tuple containing the names of free\n variables; ``co_code`` is a string representing the sequence of\n bytecode instructions; ``co_consts`` is a tuple containing the\n literals used by the bytecode; ``co_names`` is a tuple\n containing the names used by the bytecode; ``co_filename`` is\n the filename from which the code was compiled;\n ``co_firstlineno`` is the first line number of the function;\n ``co_lnotab`` is a string encoding the mapping from bytecode\n offsets to line numbers (for details see the source code of the\n interpreter); ``co_stacksize`` is the required stack size\n (including local variables); ``co_flags`` is an integer encoding\n a number of flags for the interpreter.\n\n The following flag bits are defined for ``co_flags``: bit\n ``0x04`` is set if the function uses the ``*arguments`` syntax\n to accept an arbitrary number of positional arguments; bit\n ``0x08`` is set if the function uses the ``**keywords`` syntax\n to accept arbitrary keyword arguments; bit ``0x20`` is set if\n the function is a generator.\n\n Future feature declarations (``from __future__ import\n division``) also use bits in ``co_flags`` to indicate whether a\n code object was compiled with a particular feature enabled: bit\n ``0x2000`` is set if the function was compiled with future\n division enabled; bits ``0x10`` and ``0x1000`` were used in\n earlier versions of Python.\n\n Other bits in ``co_flags`` are reserved for internal use.\n\n If a code object represents a function, the first item in\n ``co_consts`` is the documentation string of the function, or\n ``None`` if undefined.\n\n Frame objects\n Frame objects represent execution frames. They may occur in\n traceback objects (see below).\n\n Special read-only attributes: ``f_back`` is to the previous\n stack frame (towards the caller), or ``None`` if this is the\n bottom stack frame; ``f_code`` is the code object being executed\n in this frame; ``f_locals`` is the dictionary used to look up\n local variables; ``f_globals`` is used for global variables;\n ``f_builtins`` is used for built-in (intrinsic) names;\n ``f_lasti`` gives the precise instruction (this is an index into\n the bytecode string of the code object).\n\n Special writable attributes: ``f_trace``, if not ``None``, is a\n function called at the start of each source code line (this is\n used by the debugger); ``f_lineno`` is the current line number\n of the frame --- writing to this from within a trace function\n jumps to the given line (only for the bottom-most frame). A\n debugger can implement a Jump command (aka Set Next Statement)\n by writing to f_lineno.\n\n Frame objects support one method:\n\n frame.clear()\n\n This method clears all references to local variables held by\n the frame. Also, if the frame belonged to a generator, the\n generator is finalized. This helps break reference cycles\n involving frame objects (for example when catching an\n exception and storing its traceback for later use).\n\n ``RuntimeError`` is raised if the frame is currently\n executing.\n\n New in version 3.4.\n\n Traceback objects\n Traceback objects represent a stack trace of an exception. A\n traceback object is created when an exception occurs. When the\n search for an exception handler unwinds the execution stack, at\n each unwound level a traceback object is inserted in front of\n the current traceback. When an exception handler is entered,\n the stack trace is made available to the program. (See section\n *The try statement*.) It is accessible as the third item of the\n tuple returned by ``sys.exc_info()``. When the program contains\n no suitable handler, the stack trace is written (nicely\n formatted) to the standard error stream; if the interpreter is\n interactive, it is also made available to the user as\n ``sys.last_traceback``.\n\n Special read-only attributes: ``tb_next`` is the next level in\n the stack trace (towards the frame where the exception\n occurred), or ``None`` if there is no next level; ``tb_frame``\n points to the execution frame of the current level;\n ``tb_lineno`` gives the line number where the exception\n occurred; ``tb_lasti`` indicates the precise instruction. The\n line number and last instruction in the traceback may differ\n from the line number of its frame object if the exception\n occurred in a ``try`` statement with no matching except clause\n or with a finally clause.\n\n Slice objects\n Slice objects are used to represent slices for ``__getitem__()``\n methods. They are also created by the built-in ``slice()``\n function.\n\n Special read-only attributes: ``start`` is the lower bound;\n ``stop`` is the upper bound; ``step`` is the step value; each is\n ``None`` if omitted. These attributes can have any type.\n\n Slice objects support one method:\n\n slice.indices(self, length)\n\n This method takes a single integer argument *length* and\n computes information about the slice that the slice object\n would describe if applied to a sequence of *length* items.\n It returns a tuple of three integers; respectively these are\n the *start* and *stop* indices and the *step* or stride\n length of the slice. Missing or out-of-bounds indices are\n handled in a manner consistent with regular slices.\n\n Static method objects\n Static method objects provide a way of defeating the\n transformation of function objects to method objects described\n above. A static method object is a wrapper around any other\n object, usually a user-defined method object. When a static\n method object is retrieved from a class or a class instance, the\n object actually returned is the wrapped object, which is not\n subject to any further transformation. Static method objects are\n not themselves callable, although the objects they wrap usually\n are. Static method objects are created by the built-in\n ``staticmethod()`` constructor.\n\n Class method objects\n A class method object, like a static method object, is a wrapper\n around another object that alters the way in which that object\n is retrieved from classes and class instances. The behaviour of\n class method objects upon such retrieval is described above,\n under "User-defined methods". Class method objects are created\n by the built-in ``classmethod()`` constructor.\n', - 'typesfunctions': '\nFunctions\n*********\n\nFunction objects are created by function definitions. The only\noperation on a function object is to call it: ``func(argument-list)``.\n\nThere are really two flavors of function objects: built-in functions\nand user-defined functions. Both support the same operation (to call\nthe function), but the implementation is different, hence the\ndifferent object types.\n\nSee *Function definitions* for more information.\n', - 'typesmapping': '\nMapping Types --- ``dict``\n**************************\n\nA *mapping* object maps *hashable* values to arbitrary objects.\nMappings are mutable objects. There is currently only one standard\nmapping type, the *dictionary*. (For other containers see the built-\nin ``list``, ``set``, and ``tuple`` classes, and the ``collections``\nmodule.)\n\nA dictionary\'s keys are *almost* arbitrary values. Values that are\nnot *hashable*, that is, values containing lists, dictionaries or\nother mutable types (that are compared by value rather than by object\nidentity) may not be used as keys. Numeric types used for keys obey\nthe normal rules for numeric comparison: if two numbers compare equal\n(such as ``1`` and ``1.0``) then they can be used interchangeably to\nindex the same dictionary entry. (Note however, that since computers\nstore floating-point numbers as approximations it is usually unwise to\nuse them as dictionary keys.)\n\nDictionaries can be created by placing a comma-separated list of\n``key: value`` pairs within braces, for example: ``{\'jack\': 4098,\n\'sjoerd\': 4127}`` or ``{4098: \'jack\', 4127: \'sjoerd\'}``, or by the\n``dict`` constructor.\n\nclass class dict(**kwarg)\nclass class dict(mapping, **kwarg)\nclass class dict(iterable, **kwarg)\n\n Return a new dictionary initialized from an optional positional\n argument and a possibly empty set of keyword arguments.\n\n If no positional argument is given, an empty dictionary is created.\n If a positional argument is given and it is a mapping object, a\n dictionary is created with the same key-value pairs as the mapping\n object. Otherwise, the positional argument must be an *iterator*\n object. Each item in the iterable must itself be an iterator with\n exactly two objects. The first object of each item becomes a key\n in the new dictionary, and the second object the corresponding\n value. If a key occurs more than once, the last value for that key\n becomes the corresponding value in the new dictionary.\n\n If keyword arguments are given, the keyword arguments and their\n values are added to the dictionary created from the positional\n argument. If a key being added is already present, the value from\n the keyword argument replaces the value from the positional\n argument.\n\n To illustrate, the following examples all return a dictionary equal\n to ``{"one": 1, "two": 2, "three": 3}``:\n\n >>> a = dict(one=1, two=2, three=3)\n >>> b = {\'one\': 1, \'two\': 2, \'three\': 3}\n >>> c = dict(zip([\'one\', \'two\', \'three\'], [1, 2, 3]))\n >>> d = dict([(\'two\', 2), (\'one\', 1), (\'three\', 3)])\n >>> e = dict({\'three\': 3, \'one\': 1, \'two\': 2})\n >>> a == b == c == d == e\n True\n\n Providing keyword arguments as in the first example only works for\n keys that are valid Python identifiers. Otherwise, any valid keys\n can be used.\n\n These are the operations that dictionaries support (and therefore,\n custom mapping types should support too):\n\n len(d)\n\n Return the number of items in the dictionary *d*.\n\n d[key]\n\n Return the item of *d* with key *key*. Raises a ``KeyError`` if\n *key* is not in the map.\n\n If a subclass of dict defines a method ``__missing__()``, if the\n key *key* is not present, the ``d[key]`` operation calls that\n method with the key *key* as argument. The ``d[key]`` operation\n then returns or raises whatever is returned or raised by the\n ``__missing__(key)`` call if the key is not present. No other\n operations or methods invoke ``__missing__()``. If\n ``__missing__()`` is not defined, ``KeyError`` is raised.\n ``__missing__()`` must be a method; it cannot be an instance\n variable:\n\n >>> class Counter(dict):\n ... def __missing__(self, key):\n ... return 0\n >>> c = Counter()\n >>> c[\'red\']\n 0\n >>> c[\'red\'] += 1\n >>> c[\'red\']\n 1\n\n See ``collections.Counter`` for a complete implementation\n including other methods helpful for accumulating and managing\n tallies.\n\n d[key] = value\n\n Set ``d[key]`` to *value*.\n\n del d[key]\n\n Remove ``d[key]`` from *d*. Raises a ``KeyError`` if *key* is\n not in the map.\n\n key in d\n\n Return ``True`` if *d* has a key *key*, else ``False``.\n\n key not in d\n\n Equivalent to ``not key in d``.\n\n iter(d)\n\n Return an iterator over the keys of the dictionary. This is a\n shortcut for ``iter(d.keys())``.\n\n clear()\n\n Remove all items from the dictionary.\n\n copy()\n\n Return a shallow copy of the dictionary.\n\n classmethod fromkeys(seq[, value])\n\n Create a new dictionary with keys from *seq* and values set to\n *value*.\n\n ``fromkeys()`` is a class method that returns a new dictionary.\n *value* defaults to ``None``.\n\n get(key[, default])\n\n Return the value for *key* if *key* is in the dictionary, else\n *default*. If *default* is not given, it defaults to ``None``,\n so that this method never raises a ``KeyError``.\n\n items()\n\n Return a new view of the dictionary\'s items (``(key, value)``\n pairs). See the *documentation of view objects*.\n\n keys()\n\n Return a new view of the dictionary\'s keys. See the\n *documentation of view objects*.\n\n pop(key[, default])\n\n If *key* is in the dictionary, remove it and return its value,\n else return *default*. If *default* is not given and *key* is\n not in the dictionary, a ``KeyError`` is raised.\n\n popitem()\n\n Remove and return an arbitrary ``(key, value)`` pair from the\n dictionary.\n\n ``popitem()`` is useful to destructively iterate over a\n dictionary, as often used in set algorithms. If the dictionary\n is empty, calling ``popitem()`` raises a ``KeyError``.\n\n setdefault(key[, default])\n\n If *key* is in the dictionary, return its value. If not, insert\n *key* with a value of *default* and return *default*. *default*\n defaults to ``None``.\n\n update([other])\n\n Update the dictionary with the key/value pairs from *other*,\n overwriting existing keys. Return ``None``.\n\n ``update()`` accepts either another dictionary object or an\n iterable of key/value pairs (as tuples or other iterables of\n length two). If keyword arguments are specified, the dictionary\n is then updated with those key/value pairs: ``d.update(red=1,\n blue=2)``.\n\n values()\n\n Return a new view of the dictionary\'s values. See the\n *documentation of view objects*.\n\nSee also:\n\n ``types.MappingProxyType`` can be used to create a read-only view\n of a ``dict``.\n\n\nDictionary view objects\n=======================\n\nThe objects returned by ``dict.keys()``, ``dict.values()`` and\n``dict.items()`` are *view objects*. They provide a dynamic view on\nthe dictionary\'s entries, which means that when the dictionary\nchanges, the view reflects these changes.\n\nDictionary views can be iterated over to yield their respective data,\nand support membership tests:\n\nlen(dictview)\n\n Return the number of entries in the dictionary.\n\niter(dictview)\n\n Return an iterator over the keys, values or items (represented as\n tuples of ``(key, value)``) in the dictionary.\n\n Keys and values are iterated over in an arbitrary order which is\n non-random, varies across Python implementations, and depends on\n the dictionary\'s history of insertions and deletions. If keys,\n values and items views are iterated over with no intervening\n modifications to the dictionary, the order of items will directly\n correspond. This allows the creation of ``(value, key)`` pairs\n using ``zip()``: ``pairs = zip(d.values(), d.keys())``. Another\n way to create the same list is ``pairs = [(v, k) for (k, v) in\n d.items()]``.\n\n Iterating views while adding or deleting entries in the dictionary\n may raise a ``RuntimeError`` or fail to iterate over all entries.\n\nx in dictview\n\n Return ``True`` if *x* is in the underlying dictionary\'s keys,\n values or items (in the latter case, *x* should be a ``(key,\n value)`` tuple).\n\nKeys views are set-like since their entries are unique and hashable.\nIf all values are hashable, so that ``(key, value)`` pairs are unique\nand hashable, then the items view is also set-like. (Values views are\nnot treated as set-like since the entries are generally not unique.)\nFor set-like views, all of the operations defined for the abstract\nbase class ``collections.abc.Set`` are available (for example, ``==``,\n``<``, or ``^``).\n\nAn example of dictionary view usage:\n\n >>> dishes = {\'eggs\': 2, \'sausage\': 1, \'bacon\': 1, \'spam\': 500}\n >>> keys = dishes.keys()\n >>> values = dishes.values()\n\n >>> # iteration\n >>> n = 0\n >>> for val in values:\n ... n += val\n >>> print(n)\n 504\n\n >>> # keys and values are iterated over in the same order\n >>> list(keys)\n [\'eggs\', \'bacon\', \'sausage\', \'spam\']\n >>> list(values)\n [2, 1, 1, 500]\n\n >>> # view objects are dynamic and reflect dict changes\n >>> del dishes[\'eggs\']\n >>> del dishes[\'sausage\']\n >>> list(keys)\n [\'spam\', \'bacon\']\n\n >>> # set operations\n >>> keys & {\'eggs\', \'bacon\', \'salad\'}\n {\'bacon\'}\n >>> keys ^ {\'sausage\', \'juice\'}\n {\'juice\', \'sausage\', \'bacon\', \'spam\'}\n', - 'typesmethods': '\nMethods\n*******\n\nMethods are functions that are called using the attribute notation.\nThere are two flavors: built-in methods (such as ``append()`` on\nlists) and class instance methods. Built-in methods are described\nwith the types that support them.\n\nIf you access a method (a function defined in a class namespace)\nthrough an instance, you get a special object: a *bound method* (also\ncalled *instance method*) object. When called, it will add the\n``self`` argument to the argument list. Bound methods have two\nspecial read-only attributes: ``m.__self__`` is the object on which\nthe method operates, and ``m.__func__`` is the function implementing\nthe method. Calling ``m(arg-1, arg-2, ..., arg-n)`` is completely\nequivalent to calling ``m.__func__(m.__self__, arg-1, arg-2, ...,\narg-n)``.\n\nLike function objects, bound method objects support getting arbitrary\nattributes. However, since method attributes are actually stored on\nthe underlying function object (``meth.__func__``), setting method\nattributes on bound methods is disallowed. Attempting to set an\nattribute on a method results in an ``AttributeError`` being raised.\nIn order to set a method attribute, you need to explicitly set it on\nthe underlying function object:\n\n >>> class C:\n ... def method(self):\n ... pass\n ...\n >>> c = C()\n >>> c.method.whoami = \'my name is method\' # can\'t set on the method\n Traceback (most recent call last):\n File "<stdin>", line 1, in <module>\n AttributeError: \'method\' object has no attribute \'whoami\'\n >>> c.method.__func__.whoami = \'my name is method\'\n >>> c.method.whoami\n \'my name is method\'\n\nSee *The standard type hierarchy* for more information.\n', - 'typesmodules': "\nModules\n*******\n\nThe only special operation on a module is attribute access:\n``m.name``, where *m* is a module and *name* accesses a name defined\nin *m*'s symbol table. Module attributes can be assigned to. (Note\nthat the ``import`` statement is not, strictly speaking, an operation\non a module object; ``import foo`` does not require a module object\nnamed *foo* to exist, rather it requires an (external) *definition*\nfor a module named *foo* somewhere.)\n\nA special attribute of every module is ``__dict__``. This is the\ndictionary containing the module's symbol table. Modifying this\ndictionary will actually change the module's symbol table, but direct\nassignment to the ``__dict__`` attribute is not possible (you can\nwrite ``m.__dict__['a'] = 1``, which defines ``m.a`` to be ``1``, but\nyou can't write ``m.__dict__ = {}``). Modifying ``__dict__`` directly\nis not recommended.\n\nModules built into the interpreter are written like this: ``<module\n'sys' (built-in)>``. If loaded from a file, they are written as\n``<module 'os' from '/usr/local/lib/pythonX.Y/os.pyc'>``.\n", - 'typesseq': '\nSequence Types --- ``list``, ``tuple``, ``range``\n*************************************************\n\nThere are three basic sequence types: lists, tuples, and range\nobjects. Additional sequence types tailored for processing of *binary\ndata* and *text strings* are described in dedicated sections.\n\n\nCommon Sequence Operations\n==========================\n\nThe operations in the following table are supported by most sequence\ntypes, both mutable and immutable. The ``collections.abc.Sequence``\nABC is provided to make it easier to correctly implement these\noperations on custom sequence types.\n\nThis table lists the sequence operations sorted in ascending priority\n(operations in the same box have the same priority). In the table,\n*s* and *t* are sequences of the same type, *n*, *i*, *j* and *k* are\nintegers and *x* is an arbitrary object that meets any type and value\nrestrictions imposed by *s*.\n\nThe ``in`` and ``not in`` operations have the same priorities as the\ncomparison operations. The ``+`` (concatenation) and ``*``\n(repetition) operations have the same priority as the corresponding\nnumeric operations.\n\n+----------------------------+----------------------------------+------------+\n| Operation | Result | Notes |\n+============================+==================================+============+\n| ``x in s`` | ``True`` if an item of *s* is | (1) |\n| | equal to *x*, else ``False`` | |\n+----------------------------+----------------------------------+------------+\n| ``x not in s`` | ``False`` if an item of *s* is | (1) |\n| | equal to *x*, else ``True`` | |\n+----------------------------+----------------------------------+------------+\n| ``s + t`` | the concatenation of *s* and *t* | (6)(7) |\n+----------------------------+----------------------------------+------------+\n| ``s * n`` or ``n * s`` | *n* shallow copies of *s* | (2)(7) |\n| | concatenated | |\n+----------------------------+----------------------------------+------------+\n| ``s[i]`` | *i*th item of *s*, origin 0 | (3) |\n+----------------------------+----------------------------------+------------+\n| ``s[i:j]`` | slice of *s* from *i* to *j* | (3)(4) |\n+----------------------------+----------------------------------+------------+\n| ``s[i:j:k]`` | slice of *s* from *i* to *j* | (3)(5) |\n| | with step *k* | |\n+----------------------------+----------------------------------+------------+\n| ``len(s)`` | length of *s* | |\n+----------------------------+----------------------------------+------------+\n| ``min(s)`` | smallest item of *s* | |\n+----------------------------+----------------------------------+------------+\n| ``max(s)`` | largest item of *s* | |\n+----------------------------+----------------------------------+------------+\n| ``s.index(x[, i[, j]])`` | index of the first occurrence of | (8) |\n| | *x* in *s* (at or after index | |\n| | *i* and before index *j*) | |\n+----------------------------+----------------------------------+------------+\n| ``s.count(x)`` | total number of occurrences of | |\n| | *x* in *s* | |\n+----------------------------+----------------------------------+------------+\n\nSequences of the same type also support comparisons. In particular,\ntuples and lists are compared lexicographically by comparing\ncorresponding elements. This means that to compare equal, every\nelement must compare equal and the two sequences must be of the same\ntype and have the same length. (For full details see *Comparisons* in\nthe language reference.)\n\nNotes:\n\n1. While the ``in`` and ``not in`` operations are used only for simple\n containment testing in the general case, some specialised sequences\n (such as ``str``, ``bytes`` and ``bytearray``) also use them for\n subsequence testing:\n\n >>> "gg" in "eggs"\n True\n\n2. Values of *n* less than ``0`` are treated as ``0`` (which yields an\n empty sequence of the same type as *s*). Note also that the copies\n are shallow; nested structures are not copied. This often haunts\n new Python programmers; consider:\n\n >>> lists = [[]] * 3\n >>> lists\n [[], [], []]\n >>> lists[0].append(3)\n >>> lists\n [[3], [3], [3]]\n\n What has happened is that ``[[]]`` is a one-element list containing\n an empty list, so all three elements of ``[[]] * 3`` are (pointers\n to) this single empty list. Modifying any of the elements of\n ``lists`` modifies this single list. You can create a list of\n different lists this way:\n\n >>> lists = [[] for i in range(3)]\n >>> lists[0].append(3)\n >>> lists[1].append(5)\n >>> lists[2].append(7)\n >>> lists\n [[3], [5], [7]]\n\n3. If *i* or *j* is negative, the index is relative to the end of the\n string: ``len(s) + i`` or ``len(s) + j`` is substituted. But note\n that ``-0`` is still ``0``.\n\n4. The slice of *s* from *i* to *j* is defined as the sequence of\n items with index *k* such that ``i <= k < j``. If *i* or *j* is\n greater than ``len(s)``, use ``len(s)``. If *i* is omitted or\n ``None``, use ``0``. If *j* is omitted or ``None``, use\n ``len(s)``. If *i* is greater than or equal to *j*, the slice is\n empty.\n\n5. The slice of *s* from *i* to *j* with step *k* is defined as the\n sequence of items with index ``x = i + n*k`` such that ``0 <= n <\n (j-i)/k``. In other words, the indices are ``i``, ``i+k``,\n ``i+2*k``, ``i+3*k`` and so on, stopping when *j* is reached (but\n never including *j*). If *i* or *j* is greater than ``len(s)``,\n use ``len(s)``. If *i* or *j* are omitted or ``None``, they become\n "end" values (which end depends on the sign of *k*). Note, *k*\n cannot be zero. If *k* is ``None``, it is treated like ``1``.\n\n6. Concatenating immutable sequences always results in a new object.\n This means that building up a sequence by repeated concatenation\n will have a quadratic runtime cost in the total sequence length.\n To get a linear runtime cost, you must switch to one of the\n alternatives below:\n\n * if concatenating ``str`` objects, you can build a list and use\n ``str.join()`` at the end or else write to a ``io.StringIO``\n instance and retrieve its value when complete\n\n * if concatenating ``bytes`` objects, you can similarly use\n ``bytes.join()`` or ``io.BytesIO``, or you can do in-place\n concatenation with a ``bytearray`` object. ``bytearray`` objects\n are mutable and have an efficient overallocation mechanism\n\n * if concatenating ``tuple`` objects, extend a ``list`` instead\n\n * for other types, investigate the relevant class documentation\n\n7. Some sequence types (such as ``range``) only support item sequences\n that follow specific patterns, and hence don\'t support sequence\n concatenation or repetition.\n\n8. ``index`` raises ``ValueError`` when *x* is not found in *s*. When\n supported, the additional arguments to the index method allow\n efficient searching of subsections of the sequence. Passing the\n extra arguments is roughly equivalent to using ``s[i:j].index(x)``,\n only without copying any data and with the returned index being\n relative to the start of the sequence rather than the start of the\n slice.\n\n\nImmutable Sequence Types\n========================\n\nThe only operation that immutable sequence types generally implement\nthat is not also implemented by mutable sequence types is support for\nthe ``hash()`` built-in.\n\nThis support allows immutable sequences, such as ``tuple`` instances,\nto be used as ``dict`` keys and stored in ``set`` and ``frozenset``\ninstances.\n\nAttempting to hash an immutable sequence that contains unhashable\nvalues will result in ``TypeError``.\n\n\nMutable Sequence Types\n======================\n\nThe operations in the following table are defined on mutable sequence\ntypes. The ``collections.abc.MutableSequence`` ABC is provided to make\nit easier to correctly implement these operations on custom sequence\ntypes.\n\nIn the table *s* is an instance of a mutable sequence type, *t* is any\niterable object and *x* is an arbitrary object that meets any type and\nvalue restrictions imposed by *s* (for example, ``bytearray`` only\naccepts integers that meet the value restriction ``0 <= x <= 255``).\n\n+--------------------------------+----------------------------------+-----------------------+\n| Operation | Result | Notes |\n+================================+==================================+=======================+\n| ``s[i] = x`` | item *i* of *s* is replaced by | |\n| | *x* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j] = t`` | slice of *s* from *i* to *j* is | |\n| | replaced by the contents of the | |\n| | iterable *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j]`` | same as ``s[i:j] = []`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j:k] = t`` | the elements of ``s[i:j:k]`` are | (1) |\n| | replaced by those of *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j:k]`` | removes the elements of | |\n| | ``s[i:j:k]`` from the list | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.append(x)`` | appends *x* to the end of the | |\n| | sequence (same as | |\n| | ``s[len(s):len(s)] = [x]``) | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.clear()`` | removes all items from ``s`` | (5) |\n| | (same as ``del s[:]``) | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.copy()`` | creates a shallow copy of ``s`` | (5) |\n| | (same as ``s[:]``) | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.extend(t)`` | extends *s* with the contents of | |\n| | *t* (same as ``s[len(s):len(s)] | |\n| | = t``) | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.insert(i, x)`` | inserts *x* into *s* at the | |\n| | index given by *i* (same as | |\n| | ``s[i:i] = [x]``) | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.pop([i])`` | retrieves the item at *i* and | (2) |\n| | also removes it from *s* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.remove(x)`` | remove the first item from *s* | (3) |\n| | where ``s[i] == x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.reverse()`` | reverses the items of *s* in | (4) |\n| | place | |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. The optional argument *i* defaults to ``-1``, so that by default\n the last item is removed and returned.\n\n3. ``remove`` raises ``ValueError`` when *x* is not found in *s*.\n\n4. The ``reverse()`` method modifies the sequence in place for economy\n of space when reversing a large sequence. To remind users that it\n operates by side effect, it does not return the reversed sequence.\n\n5. ``clear()`` and ``copy()`` are included for consistency with the\n interfaces of mutable containers that don\'t support slicing\n operations (such as ``dict`` and ``set``)\n\n New in version 3.3: ``clear()`` and ``copy()`` methods.\n\n\nLists\n=====\n\nLists are mutable sequences, typically used to store collections of\nhomogeneous items (where the precise degree of similarity will vary by\napplication).\n\nclass class list([iterable])\n\n Lists may be constructed in several ways:\n\n * Using a pair of square brackets to denote the empty list: ``[]``\n\n * Using square brackets, separating items with commas: ``[a]``,\n ``[a, b, c]``\n\n * Using a list comprehension: ``[x for x in iterable]``\n\n * Using the type constructor: ``list()`` or ``list(iterable)``\n\n The constructor builds a list whose items are the same and in the\n same order as *iterable*\'s items. *iterable* may be either a\n sequence, a container that supports iteration, or an iterator\n object. If *iterable* is already a list, a copy is made and\n returned, similar to ``iterable[:]``. For example, ``list(\'abc\')``\n returns ``[\'a\', \'b\', \'c\']`` and ``list( (1, 2, 3) )`` returns ``[1,\n 2, 3]``. If no argument is given, the constructor creates a new\n empty list, ``[]``.\n\n Many other operations also produce lists, including the\n ``sorted()`` built-in.\n\n Lists implement all of the *common* and *mutable* sequence\n operations. Lists also provide the following additional method:\n\n sort(*, key=None, reverse=None)\n\n This method sorts the list in place, using only ``<``\n comparisons between items. Exceptions are not suppressed - if\n any comparison operations fail, the entire sort operation will\n fail (and the list will likely be left in a partially modified\n state).\n\n ``sort()`` accepts two arguments that can only be passed by\n keyword (*keyword-only arguments*):\n\n *key* specifies a function of one argument that is used to\n extract a comparison key from each list element (for example,\n ``key=str.lower``). The key corresponding to each item in the\n list is calculated once and then used for the entire sorting\n process. The default value of ``None`` means that list items are\n sorted directly without calculating a separate key value.\n\n The ``functools.cmp_to_key()`` utility is available to convert a\n 2.x style *cmp* function to a *key* function.\n\n *reverse* is a boolean value. If set to ``True``, then the list\n elements are sorted as if each comparison were reversed.\n\n This method modifies the sequence in place for economy of space\n when sorting a large sequence. To remind users that it operates\n by side effect, it does not return the sorted sequence (use\n ``sorted()`` to explicitly request a new sorted list instance).\n\n The ``sort()`` method is guaranteed to be stable. A sort is\n stable if it guarantees not to change the relative order of\n elements that compare equal --- this is helpful for sorting in\n multiple passes (for example, sort by department, then by salary\n grade).\n\n **CPython implementation detail:** While a list is being sorted,\n the effect of attempting to mutate, or even inspect, the list is\n undefined. The C implementation of Python makes the list appear\n empty for the duration, and raises ``ValueError`` if it can\n detect that the list has been mutated during a sort.\n\n\nTuples\n======\n\nTuples are immutable sequences, typically used to store collections of\nheterogeneous data (such as the 2-tuples produced by the\n``enumerate()`` built-in). Tuples are also used for cases where an\nimmutable sequence of homogeneous data is needed (such as allowing\nstorage in a ``set`` or ``dict`` instance).\n\nclass class tuple([iterable])\n\n Tuples may be constructed in a number of ways:\n\n * Using a pair of parentheses to denote the empty tuple: ``()``\n\n * Using a trailing comma for a singleton tuple: ``a,`` or ``(a,)``\n\n * Separating items with commas: ``a, b, c`` or ``(a, b, c)``\n\n * Using the ``tuple()`` built-in: ``tuple()`` or\n ``tuple(iterable)``\n\n The constructor builds a tuple whose items are the same and in the\n same order as *iterable*\'s items. *iterable* may be either a\n sequence, a container that supports iteration, or an iterator\n object. If *iterable* is already a tuple, it is returned\n unchanged. For example, ``tuple(\'abc\')`` returns ``(\'a\', \'b\',\n \'c\')`` and ``tuple( [1, 2, 3] )`` returns ``(1, 2, 3)``. If no\n argument is given, the constructor creates a new empty tuple,\n ``()``.\n\n Note that it is actually the comma which makes a tuple, not the\n parentheses. The parentheses are optional, except in the empty\n tuple case, or when they are needed to avoid syntactic ambiguity.\n For example, ``f(a, b, c)`` is a function call with three\n arguments, while ``f((a, b, c))`` is a function call with a 3-tuple\n as the sole argument.\n\n Tuples implement all of the *common* sequence operations.\n\nFor heterogeneous collections of data where access by name is clearer\nthan access by index, ``collections.namedtuple()`` may be a more\nappropriate choice than a simple tuple object.\n\n\nRanges\n======\n\nThe ``range`` type represents an immutable sequence of numbers and is\ncommonly used for looping a specific number of times in ``for`` loops.\n\nclass class range(stop)\nclass class range(start, stop[, step])\n\n The arguments to the range constructor must be integers (either\n built-in ``int`` or any object that implements the ``__index__``\n special method). If the *step* argument is omitted, it defaults to\n ``1``. If the *start* argument is omitted, it defaults to ``0``. If\n *step* is zero, ``ValueError`` is raised.\n\n For a positive *step*, the contents of a range ``r`` are determined\n by the formula ``r[i] = start + step*i`` where ``i >= 0`` and\n ``r[i] < stop``.\n\n For a negative *step*, the contents of the range are still\n determined by the formula ``r[i] = start + step*i``, but the\n constraints are ``i >= 0`` and ``r[i] > stop``.\n\n A range object will be empty if ``r[0]`` does not meet the value\n constraint. Ranges do support negative indices, but these are\n interpreted as indexing from the end of the sequence determined by\n the positive indices.\n\n Ranges containing absolute values larger than ``sys.maxsize`` are\n permitted but some features (such as ``len()``) may raise\n ``OverflowError``.\n\n Range examples:\n\n >>> list(range(10))\n [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n >>> list(range(1, 11))\n [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n >>> list(range(0, 30, 5))\n [0, 5, 10, 15, 20, 25]\n >>> list(range(0, 10, 3))\n [0, 3, 6, 9]\n >>> list(range(0, -10, -1))\n [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]\n >>> list(range(0))\n []\n >>> list(range(1, 0))\n []\n\n Ranges implement all of the *common* sequence operations except\n concatenation and repetition (due to the fact that range objects\n can only represent sequences that follow a strict pattern and\n repetition and concatenation will usually violate that pattern).\n\nThe advantage of the ``range`` type over a regular ``list`` or\n``tuple`` is that a ``range`` object will always take the same (small)\namount of memory, no matter the size of the range it represents (as it\nonly stores the ``start``, ``stop`` and ``step`` values, calculating\nindividual items and subranges as needed).\n\nRange objects implement the ``collections.abc.Sequence`` ABC, and\nprovide features such as containment tests, element index lookup,\nslicing and support for negative indices (see *Sequence Types ---\nlist, tuple, range*):\n\n>>> r = range(0, 20, 2)\n>>> r\nrange(0, 20, 2)\n>>> 11 in r\nFalse\n>>> 10 in r\nTrue\n>>> r.index(10)\n5\n>>> r[5]\n10\n>>> r[:5]\nrange(0, 10, 2)\n>>> r[-1]\n18\n\nTesting range objects for equality with ``==`` and ``!=`` compares\nthem as sequences. That is, two range objects are considered equal if\nthey represent the same sequence of values. (Note that two range\nobjects that compare equal might have different ``start``, ``stop``\nand ``step`` attributes, for example ``range(0) == range(2, 1, 3)`` or\n``range(0, 3, 2) == range(0, 4, 2)``.)\n\nChanged in version 3.2: Implement the Sequence ABC. Support slicing\nand negative indices. Test ``int`` objects for membership in constant\ntime instead of iterating through all items.\n\nChanged in version 3.3: Define \'==\' and \'!=\' to compare range objects\nbased on the sequence of values they define (instead of comparing\nbased on object identity).\n\nNew in version 3.3: The ``start``, ``stop`` and ``step`` attributes.\n', - 'typesseq-mutable': "\nMutable Sequence Types\n**********************\n\nThe operations in the following table are defined on mutable sequence\ntypes. The ``collections.abc.MutableSequence`` ABC is provided to make\nit easier to correctly implement these operations on custom sequence\ntypes.\n\nIn the table *s* is an instance of a mutable sequence type, *t* is any\niterable object and *x* is an arbitrary object that meets any type and\nvalue restrictions imposed by *s* (for example, ``bytearray`` only\naccepts integers that meet the value restriction ``0 <= x <= 255``).\n\n+--------------------------------+----------------------------------+-----------------------+\n| Operation | Result | Notes |\n+================================+==================================+=======================+\n| ``s[i] = x`` | item *i* of *s* is replaced by | |\n| | *x* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j] = t`` | slice of *s* from *i* to *j* is | |\n| | replaced by the contents of the | |\n| | iterable *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j]`` | same as ``s[i:j] = []`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j:k] = t`` | the elements of ``s[i:j:k]`` are | (1) |\n| | replaced by those of *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j:k]`` | removes the elements of | |\n| | ``s[i:j:k]`` from the list | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.append(x)`` | appends *x* to the end of the | |\n| | sequence (same as | |\n| | ``s[len(s):len(s)] = [x]``) | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.clear()`` | removes all items from ``s`` | (5) |\n| | (same as ``del s[:]``) | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.copy()`` | creates a shallow copy of ``s`` | (5) |\n| | (same as ``s[:]``) | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.extend(t)`` | extends *s* with the contents of | |\n| | *t* (same as ``s[len(s):len(s)] | |\n| | = t``) | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.insert(i, x)`` | inserts *x* into *s* at the | |\n| | index given by *i* (same as | |\n| | ``s[i:i] = [x]``) | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.pop([i])`` | retrieves the item at *i* and | (2) |\n| | also removes it from *s* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.remove(x)`` | remove the first item from *s* | (3) |\n| | where ``s[i] == x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.reverse()`` | reverses the items of *s* in | (4) |\n| | place | |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. The optional argument *i* defaults to ``-1``, so that by default\n the last item is removed and returned.\n\n3. ``remove`` raises ``ValueError`` when *x* is not found in *s*.\n\n4. The ``reverse()`` method modifies the sequence in place for economy\n of space when reversing a large sequence. To remind users that it\n operates by side effect, it does not return the reversed sequence.\n\n5. ``clear()`` and ``copy()`` are included for consistency with the\n interfaces of mutable containers that don't support slicing\n operations (such as ``dict`` and ``set``)\n\n New in version 3.3: ``clear()`` and ``copy()`` methods.\n", - 'unary': '\nUnary arithmetic and bitwise operations\n***************************************\n\nAll unary arithmetic and bitwise operations have the same priority:\n\n u_expr ::= power | "-" u_expr | "+" u_expr | "~" u_expr\n\nThe unary ``-`` (minus) operator yields the negation of its numeric\nargument.\n\nThe unary ``+`` (plus) operator yields its numeric argument unchanged.\n\nThe unary ``~`` (invert) operator yields the bitwise inversion of its\ninteger argument. The bitwise inversion of ``x`` is defined as\n``-(x+1)``. It only applies to integral numbers.\n\nIn all three cases, if the argument does not have the proper type, a\n``TypeError`` exception is raised.\n', - 'while': '\nThe ``while`` statement\n***********************\n\nThe ``while`` statement is used for repeated execution as long as an\nexpression is true:\n\n while_stmt ::= "while" expression ":" suite\n ["else" ":" suite]\n\nThis repeatedly tests the expression and, if it is true, executes the\nfirst suite; if the expression is false (which may be the first time\nit is tested) the suite of the ``else`` clause, if present, is\nexecuted and the loop terminates.\n\nA ``break`` statement executed in the first suite terminates the loop\nwithout executing the ``else`` clause\'s suite. A ``continue``\nstatement executed in the first suite skips the rest of the suite and\ngoes back to testing the expression.\n', - 'with': '\nThe ``with`` statement\n**********************\n\nThe ``with`` statement is used to wrap the execution of a block with\nmethods defined by a context manager (see section *With Statement\nContext Managers*). This allows common\n``try``...``except``...``finally`` usage patterns to be encapsulated\nfor convenient reuse.\n\n with_stmt ::= "with" with_item ("," with_item)* ":" suite\n with_item ::= expression ["as" target]\n\nThe execution of the ``with`` statement with one "item" proceeds as\nfollows:\n\n1. The context expression (the expression given in the ``with_item``)\n is evaluated to obtain a context manager.\n\n2. The context manager\'s ``__exit__()`` is loaded for later use.\n\n3. The context manager\'s ``__enter__()`` method is invoked.\n\n4. If a target was included in the ``with`` statement, the return\n value from ``__enter__()`` is assigned to it.\n\n Note: The ``with`` statement guarantees that if the ``__enter__()``\n method returns without an error, then ``__exit__()`` will always\n be called. Thus, if an error occurs during the assignment to the\n target list, it will be treated the same as an error occurring\n within the suite would be. See step 6 below.\n\n5. The suite is executed.\n\n6. The context manager\'s ``__exit__()`` method is invoked. If an\n exception caused the suite to be exited, its type, value, and\n traceback are passed as arguments to ``__exit__()``. Otherwise,\n three ``None`` arguments are supplied.\n\n If the suite was exited due to an exception, and the return value\n from the ``__exit__()`` method was false, the exception is\n reraised. If the return value was true, the exception is\n suppressed, and execution continues with the statement following\n the ``with`` statement.\n\n If the suite was exited for any reason other than an exception, the\n return value from ``__exit__()`` is ignored, and execution proceeds\n at the normal location for the kind of exit that was taken.\n\nWith more than one item, the context managers are processed as if\nmultiple ``with`` statements were nested:\n\n with A() as a, B() as b:\n suite\n\nis equivalent to\n\n with A() as a:\n with B() as b:\n suite\n\nChanged in version 3.1: Support for multiple context expressions.\n\nSee also:\n\n **PEP 0343** - The "with" statement\n The specification, background, and examples for the Python\n ``with`` statement.\n', - 'yield': '\nThe ``yield`` statement\n***********************\n\n yield_stmt ::= yield_expression\n\nThe ``yield`` statement is only used when defining a generator\nfunction, and is only used in the body of the generator function.\nUsing a ``yield`` statement in a function definition is sufficient to\ncause that definition to create a generator function instead of a\nnormal function.\n\nWhen a generator function is called, it returns an iterator known as a\ngenerator iterator, or more commonly, a generator. The body of the\ngenerator function is executed by calling the ``next()`` function on\nthe generator repeatedly until it raises an exception.\n\nWhen a ``yield`` statement is executed, the state of the generator is\nfrozen and the value of ``expression_list`` is returned to\n``next()``\'s caller. By "frozen" we mean that all local state is\nretained, including the current bindings of local variables, the\ninstruction pointer, and the internal evaluation stack: enough\ninformation is saved so that the next time ``next()`` is invoked, the\nfunction can proceed exactly as if the ``yield`` statement were just\nanother external call.\n\nThe ``yield`` statement is allowed in the ``try`` clause of a ``try``\n... ``finally`` construct. If the generator is not resumed before it\nis finalized (by reaching a zero reference count or by being garbage\ncollected), the generator-iterator\'s ``close()`` method will be\ncalled, allowing any pending ``finally`` clauses to execute.\n\nWhen ``yield from <expr>`` is used, it treats the supplied expression\nas a subiterator, producing values from it until the underlying\niterator is exhausted.\n\n Changed in version 3.3: Added ``yield from <expr>`` to delegate\n control flow to a subiterator\n\nFor full details of ``yield`` semantics, refer to the *Yield\nexpressions* section.\n\nSee also:\n\n **PEP 0255** - Simple Generators\n The proposal for adding generators and the ``yield`` statement\n to Python.\n\n **PEP 0342** - Coroutines via Enhanced Generators\n The proposal to enhance the API and syntax of generators, making\n them usable as simple coroutines.\n\n **PEP 0380** - Syntax for Delegating to a Subgenerator\n The proposal to introduce the ``yield_from`` syntax, making\n delegation to sub-generators easy.\n'} +# Autogenerated by Sphinx on Sat Feb 7 15:53:56 2015 +topics = {'assert': u'\nThe "assert" statement\n**********************\n\nAssert statements are a convenient way to insert debugging assertions\ninto a program:\n\n assert_stmt ::= "assert" expression ["," expression]\n\nThe simple form, "assert expression", is equivalent to\n\n if __debug__:\n if not expression: raise AssertionError\n\nThe extended form, "assert expression1, expression2", is equivalent to\n\n if __debug__:\n if not expression1: raise AssertionError(expression2)\n\nThese equivalences assume that "__debug__" and "AssertionError" refer\nto the built-in variables with those names. In the current\nimplementation, the built-in variable "__debug__" is "True" under\nnormal circumstances, "False" when optimization is requested (command\nline option -O). The current code generator emits no code for an\nassert statement when optimization is requested at compile time. Note\nthat it is unnecessary to include the source code for the expression\nthat failed in the error message; it will be displayed as part of the\nstack trace.\n\nAssignments to "__debug__" are illegal. The value for the built-in\nvariable is determined when the interpreter starts.\n', + 'assignment': u'\nAssignment statements\n*********************\n\nAssignment statements are used to (re)bind names to values and to\nmodify attributes or items of mutable objects:\n\n assignment_stmt ::= (target_list "=")+ (expression_list | yield_expression)\n target_list ::= target ("," target)* [","]\n target ::= identifier\n | "(" target_list ")"\n | "[" target_list "]"\n | attributeref\n | subscription\n | slicing\n | "*" target\n\n(See section *Primaries* for the syntax definitions for\n*attributeref*, *subscription*, and *slicing*.)\n\nAn assignment statement evaluates the expression list (remember that\nthis can be a single expression or a comma-separated list, the latter\nyielding a tuple) and assigns the single resulting object to each of\nthe target lists, from left to right.\n\nAssignment is defined recursively depending on the form of the target\n(list). When a target is part of a mutable object (an attribute\nreference, subscription or slicing), the mutable object must\nultimately perform the assignment and decide about its validity, and\nmay raise an exception if the assignment is unacceptable. The rules\nobserved by various types and the exceptions raised are given with the\ndefinition of the object types (see section *The standard type\nhierarchy*).\n\nAssignment of an object to a target list, optionally enclosed in\nparentheses or square brackets, is recursively defined as follows.\n\n* If the target list is a single target: The object is assigned to\n that target.\n\n* If the target list is a comma-separated list of targets: The\n object must be an iterable with the same number of items as there\n are targets in the target list, and the items are assigned, from\n left to right, to the corresponding targets.\n\n * If the target list contains one target prefixed with an\n asterisk, called a "starred" target: The object must be a sequence\n with at least as many items as there are targets in the target\n list, minus one. The first items of the sequence are assigned,\n from left to right, to the targets before the starred target. The\n final items of the sequence are assigned to the targets after the\n starred target. A list of the remaining items in the sequence is\n then assigned to the starred target (the list can be empty).\n\n * Else: The object must be a sequence with the same number of\n items as there are targets in the target list, and the items are\n assigned, from left to right, to the corresponding targets.\n\nAssignment of an object to a single target is recursively defined as\nfollows.\n\n* If the target is an identifier (name):\n\n * If the name does not occur in a "global" or "nonlocal" statement\n in the current code block: the name is bound to the object in the\n current local namespace.\n\n * Otherwise: the name is bound to the object in the global\n namespace or the outer namespace determined by "nonlocal",\n respectively.\n\n The name is rebound if it was already bound. This may cause the\n reference count for the object previously bound to the name to reach\n zero, causing the object to be deallocated and its destructor (if it\n has one) to be called.\n\n* If the target is a target list enclosed in parentheses or in\n square brackets: The object must be an iterable with the same number\n of items as there are targets in the target list, and its items are\n assigned, from left to right, to the corresponding targets.\n\n* If the target is an attribute reference: The primary expression in\n the reference is evaluated. It should yield an object with\n assignable attributes; if this is not the case, "TypeError" is\n raised. That object is then asked to assign the assigned object to\n the given attribute; if it cannot perform the assignment, it raises\n an exception (usually but not necessarily "AttributeError").\n\n Note: If the object is a class instance and the attribute reference\n occurs on both sides of the assignment operator, the RHS expression,\n "a.x" can access either an instance attribute or (if no instance\n attribute exists) a class attribute. The LHS target "a.x" is always\n set as an instance attribute, creating it if necessary. Thus, the\n two occurrences of "a.x" do not necessarily refer to the same\n attribute: if the RHS expression refers to a class attribute, the\n LHS creates a new instance attribute as the target of the\n assignment:\n\n class Cls:\n x = 3 # class variable\n inst = Cls()\n inst.x = inst.x + 1 # writes inst.x as 4 leaving Cls.x as 3\n\n This description does not necessarily apply to descriptor\n attributes, such as properties created with "property()".\n\n* If the target is a subscription: The primary expression in the\n reference is evaluated. It should yield either a mutable sequence\n object (such as a list) or a mapping object (such as a dictionary).\n Next, the subscript expression is evaluated.\n\n If the primary is a mutable sequence object (such as a list), the\n subscript must yield an integer. If it is negative, the sequence\'s\n length is added to it. The resulting value must be a nonnegative\n integer less than the sequence\'s length, and the sequence is asked\n to assign the assigned object to its item with that index. If the\n index is out of range, "IndexError" is raised (assignment to a\n subscripted sequence cannot add new items to a list).\n\n If the primary is a mapping object (such as a dictionary), the\n subscript must have a type compatible with the mapping\'s key type,\n and the mapping is then asked to create a key/datum pair which maps\n the subscript to the assigned object. This can either replace an\n existing key/value pair with the same key value, or insert a new\n key/value pair (if no key with the same value existed).\n\n For user-defined objects, the "__setitem__()" method is called with\n appropriate arguments.\n\n* If the target is a slicing: The primary expression in the\n reference is evaluated. It should yield a mutable sequence object\n (such as a list). The assigned object should be a sequence object\n of the same type. Next, the lower and upper bound expressions are\n evaluated, insofar they are present; defaults are zero and the\n sequence\'s length. The bounds should evaluate to integers. If\n either bound is negative, the sequence\'s length is added to it. The\n resulting bounds are clipped to lie between zero and the sequence\'s\n length, inclusive. Finally, the sequence object is asked to replace\n the slice with the items of the assigned sequence. The length of\n the slice may be different from the length of the assigned sequence,\n thus changing the length of the target sequence, if the target\n sequence allows it.\n\n**CPython implementation detail:** In the current implementation, the\nsyntax for targets is taken to be the same as for expressions, and\ninvalid syntax is rejected during the code generation phase, causing\nless detailed error messages.\n\nAlthough the definition of assignment implies that overlaps between\nthe left-hand side and the right-hand side are \'simultanenous\' (for\nexample "a, b = b, a" swaps two variables), overlaps *within* the\ncollection of assigned-to variables occur left-to-right, sometimes\nresulting in confusion. For instance, the following program prints\n"[0, 2]":\n\n x = [0, 1]\n i = 0\n i, x[i] = 1, 2 # i is updated, then x[i] is updated\n print(x)\n\nSee also: **PEP 3132** - Extended Iterable Unpacking\n\n The specification for the "*target" feature.\n\n\nAugmented assignment statements\n===============================\n\nAugmented assignment is the combination, in a single statement, of a\nbinary operation and an assignment statement:\n\n augmented_assignment_stmt ::= augtarget augop (expression_list | yield_expression)\n augtarget ::= identifier | attributeref | subscription | slicing\n augop ::= "+=" | "-=" | "*=" | "@=" | "/=" | "//=" | "%=" | "**="\n | ">>=" | "<<=" | "&=" | "^=" | "|="\n\n(See section *Primaries* for the syntax definitions of the last three\nsymbols.)\n\nAn augmented assignment evaluates the target (which, unlike normal\nassignment statements, cannot be an unpacking) and the expression\nlist, performs the binary operation specific to the type of assignment\non the two operands, and assigns the result to the original target.\nThe target is only evaluated once.\n\nAn augmented assignment expression like "x += 1" can be rewritten as\n"x = x + 1" to achieve a similar, but not exactly equal effect. In the\naugmented version, "x" is only evaluated once. Also, when possible,\nthe actual operation is performed *in-place*, meaning that rather than\ncreating a new object and assigning that to the target, the old object\nis modified instead.\n\nUnlike normal assignments, augmented assignments evaluate the left-\nhand side *before* evaluating the right-hand side. For example, "a[i]\n+= f(x)" first looks-up "a[i]", then it evaluates "f(x)" and performs\nthe addition, and lastly, it writes the result back to "a[i]".\n\nWith the exception of assigning to tuples and multiple targets in a\nsingle statement, the assignment done by augmented assignment\nstatements is handled the same way as normal assignments. Similarly,\nwith the exception of the possible *in-place* behavior, the binary\noperation performed by augmented assignment is the same as the normal\nbinary operations.\n\nFor targets which are attribute references, the same *caveat about\nclass and instance attributes* applies as for regular assignments.\n', + 'atom-identifiers': u'\nIdentifiers (Names)\n*******************\n\nAn identifier occurring as an atom is a name. See section\n*Identifiers and keywords* for lexical definition and section *Naming\nand binding* for documentation of naming and binding.\n\nWhen the name is bound to an object, evaluation of the atom yields\nthat object. When a name is not bound, an attempt to evaluate it\nraises a "NameError" exception.\n\n**Private name mangling:** When an identifier that textually occurs in\na class definition begins with two or more underscore characters and\ndoes not end in two or more underscores, it is considered a *private\nname* of that class. Private names are transformed to a longer form\nbefore code is generated for them. The transformation inserts the\nclass name, with leading underscores removed and a single underscore\ninserted, in front of the name. For example, the identifier "__spam"\noccurring in a class named "Ham" will be transformed to "_Ham__spam".\nThis transformation is independent of the syntactical context in which\nthe identifier is used. If the transformed name is extremely long\n(longer than 255 characters), implementation defined truncation may\nhappen. If the class name consists only of underscores, no\ntransformation is done.\n', + 'atom-literals': u"\nLiterals\n********\n\nPython supports string and bytes literals and various numeric\nliterals:\n\n literal ::= stringliteral | bytesliteral\n | integer | floatnumber | imagnumber\n\nEvaluation of a literal yields an object of the given type (string,\nbytes, integer, floating point number, complex number) with the given\nvalue. The value may be approximated in the case of floating point\nand imaginary (complex) literals. See section *Literals* for details.\n\nAll literals correspond to immutable data types, and hence the\nobject's identity is less important than its value. Multiple\nevaluations of literals with the same value (either the same\noccurrence in the program text or a different occurrence) may obtain\nthe same object or a different object with the same value.\n", + 'attribute-access': u'\nCustomizing attribute access\n****************************\n\nThe following methods can be defined to customize the meaning of\nattribute access (use of, assignment to, or deletion of "x.name") for\nclass instances.\n\nobject.__getattr__(self, name)\n\n Called when an attribute lookup has not found the attribute in the\n usual places (i.e. it is not an instance attribute nor is it found\n in the class tree for "self"). "name" is the attribute name. This\n method should return the (computed) attribute value or raise an\n "AttributeError" exception.\n\n Note that if the attribute is found through the normal mechanism,\n "__getattr__()" is not called. (This is an intentional asymmetry\n between "__getattr__()" and "__setattr__()".) This is done both for\n efficiency reasons and because otherwise "__getattr__()" would have\n no way to access other attributes of the instance. Note that at\n least for instance variables, you can fake total control by not\n inserting any values in the instance attribute dictionary (but\n instead inserting them in another object). See the\n "__getattribute__()" method below for a way to actually get total\n control over attribute access.\n\nobject.__getattribute__(self, name)\n\n Called unconditionally to implement attribute accesses for\n instances of the class. If the class also defines "__getattr__()",\n the latter will not be called unless "__getattribute__()" either\n calls it explicitly or raises an "AttributeError". This method\n should return the (computed) attribute value or raise an\n "AttributeError" exception. In order to avoid infinite recursion in\n this method, its implementation should always call the base class\n method with the same name to access any attributes it needs, for\n example, "object.__getattribute__(self, name)".\n\n Note: This method may still be bypassed when looking up special\n methods as the result of implicit invocation via language syntax\n or built-in functions. See *Special method lookup*.\n\nobject.__setattr__(self, name, value)\n\n Called when an attribute assignment is attempted. This is called\n instead of the normal mechanism (i.e. store the value in the\n instance dictionary). *name* is the attribute name, *value* is the\n value to be assigned to it.\n\n If "__setattr__()" wants to assign to an instance attribute, it\n should call the base class method with the same name, for example,\n "object.__setattr__(self, name, value)".\n\nobject.__delattr__(self, name)\n\n Like "__setattr__()" but for attribute deletion instead of\n assignment. This should only be implemented if "del obj.name" is\n meaningful for the object.\n\nobject.__dir__(self)\n\n Called when "dir()" is called on the object. A sequence must be\n returned. "dir()" converts the returned sequence to a list and\n sorts it.\n\n\nImplementing Descriptors\n========================\n\nThe following methods only apply when an instance of the class\ncontaining the method (a so-called *descriptor* class) appears in an\n*owner* class (the descriptor must be in either the owner\'s class\ndictionary or in the class dictionary for one of its parents). In the\nexamples below, "the attribute" refers to the attribute whose name is\nthe key of the property in the owner class\' "__dict__".\n\nobject.__get__(self, instance, owner)\n\n Called to get the attribute of the owner class (class attribute\n access) or of an instance of that class (instance attribute\n access). *owner* is always the owner class, while *instance* is the\n instance that the attribute was accessed through, or "None" when\n the attribute is accessed through the *owner*. This method should\n return the (computed) attribute value or raise an "AttributeError"\n exception.\n\nobject.__set__(self, instance, value)\n\n Called to set the attribute on an instance *instance* of the owner\n class to a new value, *value*.\n\nobject.__delete__(self, instance)\n\n Called to delete the attribute on an instance *instance* of the\n owner class.\n\nThe attribute "__objclass__" is interpreted by the "inspect" module as\nspecifying the class where this object was defined (setting this\nappropriately can assist in runtime introspection of dynamic class\nattributes). For callables, it may indicate that an instance of the\ngiven type (or a subclass) is expected or required as the first\npositional argument (for example, CPython sets this attribute for\nunbound methods that are implemented in C).\n\n\nInvoking Descriptors\n====================\n\nIn general, a descriptor is an object attribute with "binding\nbehavior", one whose attribute access has been overridden by methods\nin the descriptor protocol: "__get__()", "__set__()", and\n"__delete__()". If any of those methods are defined for an object, it\nis said to be a descriptor.\n\nThe default behavior for attribute access is to get, set, or delete\nthe attribute from an object\'s dictionary. For instance, "a.x" has a\nlookup chain starting with "a.__dict__[\'x\']", then\n"type(a).__dict__[\'x\']", and continuing through the base classes of\n"type(a)" excluding metaclasses.\n\nHowever, if the looked-up value is an object defining one of the\ndescriptor methods, then Python may override the default behavior and\ninvoke the descriptor method instead. Where this occurs in the\nprecedence chain depends on which descriptor methods were defined and\nhow they were called.\n\nThe starting point for descriptor invocation is a binding, "a.x". How\nthe arguments are assembled depends on "a":\n\nDirect Call\n The simplest and least common call is when user code directly\n invokes a descriptor method: "x.__get__(a)".\n\nInstance Binding\n If binding to an object instance, "a.x" is transformed into the\n call: "type(a).__dict__[\'x\'].__get__(a, type(a))".\n\nClass Binding\n If binding to a class, "A.x" is transformed into the call:\n "A.__dict__[\'x\'].__get__(None, A)".\n\nSuper Binding\n If "a" is an instance of "super", then the binding "super(B,\n obj).m()" searches "obj.__class__.__mro__" for the base class "A"\n immediately preceding "B" and then invokes the descriptor with the\n call: "A.__dict__[\'m\'].__get__(obj, obj.__class__)".\n\nFor instance bindings, the precedence of descriptor invocation depends\non the which descriptor methods are defined. A descriptor can define\nany combination of "__get__()", "__set__()" and "__delete__()". If it\ndoes not define "__get__()", then accessing the attribute will return\nthe descriptor object itself unless there is a value in the object\'s\ninstance dictionary. If the descriptor defines "__set__()" and/or\n"__delete__()", it is a data descriptor; if it defines neither, it is\na non-data descriptor. Normally, data descriptors define both\n"__get__()" and "__set__()", while non-data descriptors have just the\n"__get__()" method. Data descriptors with "__set__()" and "__get__()"\ndefined always override a redefinition in an instance dictionary. In\ncontrast, non-data descriptors can be overridden by instances.\n\nPython methods (including "staticmethod()" and "classmethod()") are\nimplemented as non-data descriptors. Accordingly, instances can\nredefine and override methods. This allows individual instances to\nacquire behaviors that differ from other instances of the same class.\n\nThe "property()" function is implemented as a data descriptor.\nAccordingly, instances cannot override the behavior of a property.\n\n\n__slots__\n=========\n\nBy default, instances of classes have a dictionary for attribute\nstorage. This wastes space for objects having very few instance\nvariables. The space consumption can become acute when creating large\nnumbers of instances.\n\nThe default can be overridden by defining *__slots__* in a class\ndefinition. The *__slots__* declaration takes a sequence of instance\nvariables and reserves just enough space in each instance to hold a\nvalue for each variable. Space is saved because *__dict__* is not\ncreated for each instance.\n\nobject.__slots__\n\n This class variable can be assigned a string, iterable, or sequence\n of strings with variable names used by instances. *__slots__*\n reserves space for the declared variables and prevents the\n automatic creation of *__dict__* and *__weakref__* for each\n instance.\n\n\nNotes on using *__slots__*\n--------------------------\n\n* When inheriting from a class without *__slots__*, the *__dict__*\n attribute of that class will always be accessible, so a *__slots__*\n definition in the subclass is meaningless.\n\n* Without a *__dict__* variable, instances cannot be assigned new\n variables not listed in the *__slots__* definition. Attempts to\n assign to an unlisted variable name raises "AttributeError". If\n dynamic assignment of new variables is desired, then add\n "\'__dict__\'" to the sequence of strings in the *__slots__*\n declaration.\n\n* Without a *__weakref__* variable for each instance, classes\n defining *__slots__* do not support weak references to its\n instances. If weak reference support is needed, then add\n "\'__weakref__\'" to the sequence of strings in the *__slots__*\n declaration.\n\n* *__slots__* are implemented at the class level by creating\n descriptors (*Implementing Descriptors*) for each variable name. As\n a result, class attributes cannot be used to set default values for\n instance variables defined by *__slots__*; otherwise, the class\n attribute would overwrite the descriptor assignment.\n\n* The action of a *__slots__* declaration is limited to the class\n where it is defined. As a result, subclasses will have a *__dict__*\n unless they also define *__slots__* (which must only contain names\n of any *additional* slots).\n\n* If a class defines a slot also defined in a base class, the\n instance variable defined by the base class slot is inaccessible\n (except by retrieving its descriptor directly from the base class).\n This renders the meaning of the program undefined. In the future, a\n check may be added to prevent this.\n\n* Nonempty *__slots__* does not work for classes derived from\n "variable-length" built-in types such as "int", "bytes" and "tuple".\n\n* Any non-string iterable may be assigned to *__slots__*. Mappings\n may also be used; however, in the future, special meaning may be\n assigned to the values corresponding to each key.\n\n* *__class__* assignment works only if both classes have the same\n *__slots__*.\n', + 'attribute-references': u'\nAttribute references\n********************\n\nAn attribute reference is a primary followed by a period and a name:\n\n attributeref ::= primary "." identifier\n\nThe primary must evaluate to an object of a type that supports\nattribute references, which most objects do. This object is then\nasked to produce the attribute whose name is the identifier. This\nproduction can be customized by overriding the "__getattr__()" method.\nIf this attribute is not available, the exception "AttributeError" is\nraised. Otherwise, the type and value of the object produced is\ndetermined by the object. Multiple evaluations of the same attribute\nreference may yield different objects.\n', + 'augassign': u'\nAugmented assignment statements\n*******************************\n\nAugmented assignment is the combination, in a single statement, of a\nbinary operation and an assignment statement:\n\n augmented_assignment_stmt ::= augtarget augop (expression_list | yield_expression)\n augtarget ::= identifier | attributeref | subscription | slicing\n augop ::= "+=" | "-=" | "*=" | "@=" | "/=" | "//=" | "%=" | "**="\n | ">>=" | "<<=" | "&=" | "^=" | "|="\n\n(See section *Primaries* for the syntax definitions of the last three\nsymbols.)\n\nAn augmented assignment evaluates the target (which, unlike normal\nassignment statements, cannot be an unpacking) and the expression\nlist, performs the binary operation specific to the type of assignment\non the two operands, and assigns the result to the original target.\nThe target is only evaluated once.\n\nAn augmented assignment expression like "x += 1" can be rewritten as\n"x = x + 1" to achieve a similar, but not exactly equal effect. In the\naugmented version, "x" is only evaluated once. Also, when possible,\nthe actual operation is performed *in-place*, meaning that rather than\ncreating a new object and assigning that to the target, the old object\nis modified instead.\n\nUnlike normal assignments, augmented assignments evaluate the left-\nhand side *before* evaluating the right-hand side. For example, "a[i]\n+= f(x)" first looks-up "a[i]", then it evaluates "f(x)" and performs\nthe addition, and lastly, it writes the result back to "a[i]".\n\nWith the exception of assigning to tuples and multiple targets in a\nsingle statement, the assignment done by augmented assignment\nstatements is handled the same way as normal assignments. Similarly,\nwith the exception of the possible *in-place* behavior, the binary\noperation performed by augmented assignment is the same as the normal\nbinary operations.\n\nFor targets which are attribute references, the same *caveat about\nclass and instance attributes* applies as for regular assignments.\n', + 'binary': u'\nBinary arithmetic operations\n****************************\n\nThe binary arithmetic operations have the conventional priority\nlevels. Note that some of these operations also apply to certain non-\nnumeric types. Apart from the power operator, there are only two\nlevels, one for multiplicative operators and one for additive\noperators:\n\n m_expr ::= u_expr | m_expr "*" u_expr | m_expr "@" m_expr |\n m_expr "//" u_expr| m_expr "/" u_expr |\n m_expr "%" u_expr\n a_expr ::= m_expr | a_expr "+" m_expr | a_expr "-" m_expr\n\nThe "*" (multiplication) operator yields the product of its arguments.\nThe arguments must either both be numbers, or one argument must be an\ninteger and the other must be a sequence. In the former case, the\nnumbers are converted to a common type and then multiplied together.\nIn the latter case, sequence repetition is performed; a negative\nrepetition factor yields an empty sequence.\n\nThe "@" (at) operator is intended to be used for matrix\nmultiplication. No builtin Python types implement this operator.\n\nNew in version 3.5.\n\nThe "/" (division) and "//" (floor division) operators yield the\nquotient of their arguments. The numeric arguments are first\nconverted to a common type. Division of integers yields a float, while\nfloor division of integers results in an integer; the result is that\nof mathematical division with the \'floor\' function applied to the\nresult. Division by zero raises the "ZeroDivisionError" exception.\n\nThe "%" (modulo) operator yields the remainder from the division of\nthe first argument by the second. The numeric arguments are first\nconverted to a common type. A zero right argument raises the\n"ZeroDivisionError" exception. The arguments may be floating point\nnumbers, e.g., "3.14%0.7" equals "0.34" (since "3.14" equals "4*0.7 +\n0.34".) The modulo operator always yields a result with the same sign\nas its second operand (or zero); the absolute value of the result is\nstrictly smaller than the absolute value of the second operand [1].\n\nThe floor division and modulo operators are connected by the following\nidentity: "x == (x//y)*y + (x%y)". Floor division and modulo are also\nconnected with the built-in function "divmod()": "divmod(x, y) ==\n(x//y, x%y)". [2].\n\nIn addition to performing the modulo operation on numbers, the "%"\noperator is also overloaded by string objects to perform old-style\nstring formatting (also known as interpolation). The syntax for\nstring formatting is described in the Python Library Reference,\nsection *printf-style String Formatting*.\n\nThe floor division operator, the modulo operator, and the "divmod()"\nfunction are not defined for complex numbers. Instead, convert to a\nfloating point number using the "abs()" function if appropriate.\n\nThe "+" (addition) operator yields the sum of its arguments. The\narguments must either both be numbers or both be sequences of the same\ntype. In the former case, the numbers are converted to a common type\nand then added together. In the latter case, the sequences are\nconcatenated.\n\nThe "-" (subtraction) operator yields the difference of its arguments.\nThe numeric arguments are first converted to a common type.\n', + 'bitwise': u'\nBinary bitwise operations\n*************************\n\nEach of the three bitwise operations has a different priority level:\n\n and_expr ::= shift_expr | and_expr "&" shift_expr\n xor_expr ::= and_expr | xor_expr "^" and_expr\n or_expr ::= xor_expr | or_expr "|" xor_expr\n\nThe "&" operator yields the bitwise AND of its arguments, which must\nbe integers.\n\nThe "^" operator yields the bitwise XOR (exclusive OR) of its\narguments, which must be integers.\n\nThe "|" operator yields the bitwise (inclusive) OR of its arguments,\nwhich must be integers.\n', + 'bltin-code-objects': u'\nCode Objects\n************\n\nCode objects are used by the implementation to represent "pseudo-\ncompiled" executable Python code such as a function body. They differ\nfrom function objects because they don\'t contain a reference to their\nglobal execution environment. Code objects are returned by the built-\nin "compile()" function and can be extracted from function objects\nthrough their "__code__" attribute. See also the "code" module.\n\nA code object can be executed or evaluated by passing it (instead of a\nsource string) to the "exec()" or "eval()" built-in functions.\n\nSee *The standard type hierarchy* for more information.\n', + 'bltin-ellipsis-object': u'\nThe Ellipsis Object\n*******************\n\nThis object is commonly used by slicing (see *Slicings*). It supports\nno special operations. There is exactly one ellipsis object, named\n"Ellipsis" (a built-in name). "type(Ellipsis)()" produces the\n"Ellipsis" singleton.\n\nIt is written as "Ellipsis" or "...".\n', + 'bltin-null-object': u'\nThe Null Object\n***************\n\nThis object is returned by functions that don\'t explicitly return a\nvalue. It supports no special operations. There is exactly one null\nobject, named "None" (a built-in name). "type(None)()" produces the\nsame singleton.\n\nIt is written as "None".\n', + 'bltin-type-objects': u'\nType Objects\n************\n\nType objects represent the various object types. An object\'s type is\naccessed by the built-in function "type()". There are no special\noperations on types. The standard module "types" defines names for\nall standard built-in types.\n\nTypes are written like this: "<class \'int\'>".\n', + 'booleans': u'\nBoolean operations\n******************\n\n or_test ::= and_test | or_test "or" and_test\n and_test ::= not_test | and_test "and" not_test\n not_test ::= comparison | "not" not_test\n\nIn the context of Boolean operations, and also when expressions are\nused by control flow statements, the following values are interpreted\nas false: "False", "None", numeric zero of all types, and empty\nstrings and containers (including strings, tuples, lists,\ndictionaries, sets and frozensets). All other values are interpreted\nas true. User-defined objects can customize their truth value by\nproviding a "__bool__()" method.\n\nThe operator "not" yields "True" if its argument is false, "False"\notherwise.\n\nThe expression "x and y" first evaluates *x*; if *x* is false, its\nvalue is returned; otherwise, *y* is evaluated and the resulting value\nis returned.\n\nThe expression "x or y" first evaluates *x*; if *x* is true, its value\nis returned; otherwise, *y* is evaluated and the resulting value is\nreturned.\n\n(Note that neither "and" nor "or" restrict the value and type they\nreturn to "False" and "True", but rather return the last evaluated\nargument. This is sometimes useful, e.g., if "s" is a string that\nshould be replaced by a default value if it is empty, the expression\n"s or \'foo\'" yields the desired value. Because "not" has to create a\nnew value, it returns a boolean value regardless of the type of its\nargument (for example, "not \'foo\'" produces "False" rather than "\'\'".)\n', + 'break': u'\nThe "break" statement\n*********************\n\n break_stmt ::= "break"\n\n"break" may only occur syntactically nested in a "for" or "while"\nloop, but not nested in a function or class definition within that\nloop.\n\nIt terminates the nearest enclosing loop, skipping the optional "else"\nclause if the loop has one.\n\nIf a "for" loop is terminated by "break", the loop control target\nkeeps its current value.\n\nWhen "break" passes control out of a "try" statement with a "finally"\nclause, that "finally" clause is executed before really leaving the\nloop.\n', + 'callable-types': u'\nEmulating callable objects\n**************************\n\nobject.__call__(self[, args...])\n\n Called when the instance is "called" as a function; if this method\n is defined, "x(arg1, arg2, ...)" is a shorthand for\n "x.__call__(arg1, arg2, ...)".\n', + 'calls': u'\nCalls\n*****\n\nA call calls a callable object (e.g., a *function*) with a possibly\nempty series of *arguments*:\n\n call ::= primary "(" [argument_list [","] | comprehension] ")"\n argument_list ::= positional_arguments ["," keyword_arguments]\n ["," "*" expression] ["," keyword_arguments]\n ["," "**" expression]\n | keyword_arguments ["," "*" expression]\n ["," keyword_arguments] ["," "**" expression]\n | "*" expression ["," keyword_arguments] ["," "**" expression]\n | "**" expression\n positional_arguments ::= expression ("," expression)*\n keyword_arguments ::= keyword_item ("," keyword_item)*\n keyword_item ::= identifier "=" expression\n\nAn optional trailing comma may be present after the positional and\nkeyword arguments but does not affect the semantics.\n\nThe primary must evaluate to a callable object (user-defined\nfunctions, built-in functions, methods of built-in objects, class\nobjects, methods of class instances, and all objects having a\n"__call__()" method are callable). All argument expressions are\nevaluated before the call is attempted. Please refer to section\n*Function definitions* for the syntax of formal *parameter* lists.\n\nIf keyword arguments are present, they are first converted to\npositional arguments, as follows. First, a list of unfilled slots is\ncreated for the formal parameters. If there are N positional\narguments, they are placed in the first N slots. Next, for each\nkeyword argument, the identifier is used to determine the\ncorresponding slot (if the identifier is the same as the first formal\nparameter name, the first slot is used, and so on). If the slot is\nalready filled, a "TypeError" exception is raised. Otherwise, the\nvalue of the argument is placed in the slot, filling it (even if the\nexpression is "None", it fills the slot). When all arguments have\nbeen processed, the slots that are still unfilled are filled with the\ncorresponding default value from the function definition. (Default\nvalues are calculated, once, when the function is defined; thus, a\nmutable object such as a list or dictionary used as default value will\nbe shared by all calls that don\'t specify an argument value for the\ncorresponding slot; this should usually be avoided.) If there are any\nunfilled slots for which no default value is specified, a "TypeError"\nexception is raised. Otherwise, the list of filled slots is used as\nthe argument list for the call.\n\n**CPython implementation detail:** An implementation may provide\nbuilt-in functions whose positional parameters do not have names, even\nif they are \'named\' for the purpose of documentation, and which\ntherefore cannot be supplied by keyword. In CPython, this is the case\nfor functions implemented in C that use "PyArg_ParseTuple()" to parse\ntheir arguments.\n\nIf there are more positional arguments than there are formal parameter\nslots, a "TypeError" exception is raised, unless a formal parameter\nusing the syntax "*identifier" is present; in this case, that formal\nparameter receives a tuple containing the excess positional arguments\n(or an empty tuple if there were no excess positional arguments).\n\nIf any keyword argument does not correspond to a formal parameter\nname, a "TypeError" exception is raised, unless a formal parameter\nusing the syntax "**identifier" is present; in this case, that formal\nparameter receives a dictionary containing the excess keyword\narguments (using the keywords as keys and the argument values as\ncorresponding values), or a (new) empty dictionary if there were no\nexcess keyword arguments.\n\nIf the syntax "*expression" appears in the function call, "expression"\nmust evaluate to an iterable. Elements from this iterable are treated\nas if they were additional positional arguments; if there are\npositional arguments *x1*, ..., *xN*, and "expression" evaluates to a\nsequence *y1*, ..., *yM*, this is equivalent to a call with M+N\npositional arguments *x1*, ..., *xN*, *y1*, ..., *yM*.\n\nA consequence of this is that although the "*expression" syntax may\nappear *after* some keyword arguments, it is processed *before* the\nkeyword arguments (and the "**expression" argument, if any -- see\nbelow). So:\n\n >>> def f(a, b):\n ... print(a, b)\n ...\n >>> f(b=1, *(2,))\n 2 1\n >>> f(a=1, *(2,))\n Traceback (most recent call last):\n File "<stdin>", line 1, in ?\n TypeError: f() got multiple values for keyword argument \'a\'\n >>> f(1, *(2,))\n 1 2\n\nIt is unusual for both keyword arguments and the "*expression" syntax\nto be used in the same call, so in practice this confusion does not\narise.\n\nIf the syntax "**expression" appears in the function call,\n"expression" must evaluate to a mapping, the contents of which are\ntreated as additional keyword arguments. In the case of a keyword\nappearing in both "expression" and as an explicit keyword argument, a\n"TypeError" exception is raised.\n\nFormal parameters using the syntax "*identifier" or "**identifier"\ncannot be used as positional argument slots or as keyword argument\nnames.\n\nA call always returns some value, possibly "None", unless it raises an\nexception. How this value is computed depends on the type of the\ncallable object.\n\nIf it is---\n\na user-defined function:\n The code block for the function is executed, passing it the\n argument list. The first thing the code block will do is bind the\n formal parameters to the arguments; this is described in section\n *Function definitions*. When the code block executes a "return"\n statement, this specifies the return value of the function call.\n\na built-in function or method:\n The result is up to the interpreter; see *Built-in Functions* for\n the descriptions of built-in functions and methods.\n\na class object:\n A new instance of that class is returned.\n\na class instance method:\n The corresponding user-defined function is called, with an argument\n list that is one longer than the argument list of the call: the\n instance becomes the first argument.\n\na class instance:\n The class must define a "__call__()" method; the effect is then the\n same as if that method was called.\n', + 'class': u'\nClass definitions\n*****************\n\nA class definition defines a class object (see section *The standard\ntype hierarchy*):\n\n classdef ::= [decorators] "class" classname [inheritance] ":" suite\n inheritance ::= "(" [parameter_list] ")"\n classname ::= identifier\n\nA class definition is an executable statement. The inheritance list\nusually gives a list of base classes (see *Customizing class creation*\nfor more advanced uses), so each item in the list should evaluate to a\nclass object which allows subclassing. Classes without an inheritance\nlist inherit, by default, from the base class "object"; hence,\n\n class Foo:\n pass\n\nis equivalent to\n\n class Foo(object):\n pass\n\nThe class\'s suite is then executed in a new execution frame (see\n*Naming and binding*), using a newly created local namespace and the\noriginal global namespace. (Usually, the suite contains mostly\nfunction definitions.) When the class\'s suite finishes execution, its\nexecution frame is discarded but its local namespace is saved. [4] A\nclass object is then created using the inheritance list for the base\nclasses and the saved local namespace for the attribute dictionary.\nThe class name is bound to this class object in the original local\nnamespace.\n\nClass creation can be customized heavily using *metaclasses*.\n\nClasses can also be decorated: just like when decorating functions,\n\n @f1(arg)\n @f2\n class Foo: pass\n\nis equivalent to\n\n class Foo: pass\n Foo = f1(arg)(f2(Foo))\n\nThe evaluation rules for the decorator expressions are the same as for\nfunction decorators. The result must be a class object, which is then\nbound to the class name.\n\n**Programmer\'s note:** Variables defined in the class definition are\nclass attributes; they are shared by instances. Instance attributes\ncan be set in a method with "self.name = value". Both class and\ninstance attributes are accessible through the notation ""self.name"",\nand an instance attribute hides a class attribute with the same name\nwhen accessed in this way. Class attributes can be used as defaults\nfor instance attributes, but using mutable values there can lead to\nunexpected results. *Descriptors* can be used to create instance\nvariables with different implementation details.\n\nSee also: **PEP 3115** - Metaclasses in Python 3 **PEP 3129** -\n Class Decorators\n\n-[ Footnotes ]-\n\n[1] The exception is propagated to the invocation stack unless\n there is a "finally" clause which happens to raise another\n exception. That new exception causes the old one to be lost.\n\n[2] Currently, control "flows off the end" except in the case of\n an exception or the execution of a "return", "continue", or\n "break" statement.\n\n[3] A string literal appearing as the first statement in the\n function body is transformed into the function\'s "__doc__"\n attribute and therefore the function\'s *docstring*.\n\n[4] A string literal appearing as the first statement in the class\n body is transformed into the namespace\'s "__doc__" item and\n therefore the class\'s *docstring*.\n', + 'comparisons': u'\nComparisons\n***********\n\nUnlike C, all comparison operations in Python have the same priority,\nwhich is lower than that of any arithmetic, shifting or bitwise\noperation. Also unlike C, expressions like "a < b < c" have the\ninterpretation that is conventional in mathematics:\n\n comparison ::= or_expr ( comp_operator or_expr )*\n comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "!="\n | "is" ["not"] | ["not"] "in"\n\nComparisons yield boolean values: "True" or "False".\n\nComparisons can be chained arbitrarily, e.g., "x < y <= z" is\nequivalent to "x < y and y <= z", except that "y" is evaluated only\nonce (but in both cases "z" is not evaluated at all when "x < y" is\nfound to be false).\n\nFormally, if *a*, *b*, *c*, ..., *y*, *z* are expressions and *op1*,\n*op2*, ..., *opN* are comparison operators, then "a op1 b op2 c ... y\nopN z" is equivalent to "a op1 b and b op2 c and ... y opN z", except\nthat each expression is evaluated at most once.\n\nNote that "a op1 b op2 c" doesn\'t imply any kind of comparison between\n*a* and *c*, so that, e.g., "x < y > z" is perfectly legal (though\nperhaps not pretty).\n\nThe operators "<", ">", "==", ">=", "<=", and "!=" compare the values\nof two objects. The objects need not have the same type. If both are\nnumbers, they are converted to a common type. Otherwise, the "==" and\n"!=" operators *always* consider objects of different types to be\nunequal, while the "<", ">", ">=" and "<=" operators raise a\n"TypeError" when comparing objects of different types that do not\nimplement these operators for the given pair of types. You can\ncontrol comparison behavior of objects of non-built-in types by\ndefining rich comparison methods like "__gt__()", described in section\n*Basic customization*.\n\nComparison of objects of the same type depends on the type:\n\n* Numbers are compared arithmetically.\n\n* The values "float(\'NaN\')" and "Decimal(\'NaN\')" are special. The\n are identical to themselves, "x is x" but are not equal to\n themselves, "x != x". Additionally, comparing any value to a\n not-a-number value will return "False". For example, both "3 <\n float(\'NaN\')" and "float(\'NaN\') < 3" will return "False".\n\n* Bytes objects are compared lexicographically using the numeric\n values of their elements.\n\n* Strings are compared lexicographically using the numeric\n equivalents (the result of the built-in function "ord()") of their\n characters. [3] String and bytes object can\'t be compared!\n\n* Tuples and lists are compared lexicographically using comparison\n of corresponding elements. This means that to compare equal, each\n element must compare equal and the two sequences must be of the same\n type and have the same length.\n\n If not equal, the sequences are ordered the same as their first\n differing elements. For example, "[1,2,x] <= [1,2,y]" has the same\n value as "x <= y". If the corresponding element does not exist, the\n shorter sequence is ordered first (for example, "[1,2] < [1,2,3]").\n\n* Mappings (dictionaries) compare equal if and only if they have the\n same "(key, value)" pairs. Order comparisons "(\'<\', \'<=\', \'>=\',\n \'>\')" raise "TypeError".\n\n* Sets and frozensets define comparison operators to mean subset and\n superset tests. Those relations do not define total orderings (the\n two sets "{1,2}" and {2,3} are not equal, nor subsets of one\n another, nor supersets of one another). Accordingly, sets are not\n appropriate arguments for functions which depend on total ordering.\n For example, "min()", "max()", and "sorted()" produce undefined\n results given a list of sets as inputs.\n\n* Most other objects of built-in types compare unequal unless they\n are the same object; the choice whether one object is considered\n smaller or larger than another one is made arbitrarily but\n consistently within one execution of a program.\n\nComparison of objects of differing types depends on whether either of\nthe types provide explicit support for the comparison. Most numeric\ntypes can be compared with one another. When cross-type comparison is\nnot supported, the comparison method returns "NotImplemented".\n\nThe operators "in" and "not in" test for membership. "x in s"\nevaluates to true if *x* is a member of *s*, and false otherwise. "x\nnot in s" returns the negation of "x in s". All built-in sequences\nand set types support this as well as dictionary, for which "in" tests\nwhether the dictionary has a given key. For container types such as\nlist, tuple, set, frozenset, dict, or collections.deque, the\nexpression "x in y" is equivalent to "any(x is e or x == e for e in\ny)".\n\nFor the string and bytes types, "x in y" is true if and only if *x* is\na substring of *y*. An equivalent test is "y.find(x) != -1". Empty\nstrings are always considered to be a substring of any other string,\nso """ in "abc"" will return "True".\n\nFor user-defined classes which define the "__contains__()" method, "x\nin y" is true if and only if "y.__contains__(x)" is true.\n\nFor user-defined classes which do not define "__contains__()" but do\ndefine "__iter__()", "x in y" is true if some value "z" with "x == z"\nis produced while iterating over "y". If an exception is raised\nduring the iteration, it is as if "in" raised that exception.\n\nLastly, the old-style iteration protocol is tried: if a class defines\n"__getitem__()", "x in y" is true if and only if there is a non-\nnegative integer index *i* such that "x == y[i]", and all lower\ninteger indices do not raise "IndexError" exception. (If any other\nexception is raised, it is as if "in" raised that exception).\n\nThe operator "not in" is defined to have the inverse true value of\n"in".\n\nThe operators "is" and "is not" test for object identity: "x is y" is\ntrue if and only if *x* and *y* are the same object. "x is not y"\nyields the inverse truth value. [4]\n', + 'compound': u'\nCompound statements\n*******************\n\nCompound statements contain (groups of) other statements; they affect\nor control the execution of those other statements in some way. In\ngeneral, compound statements span multiple lines, although in simple\nincarnations a whole compound statement may be contained in one line.\n\nThe "if", "while" and "for" statements implement traditional control\nflow constructs. "try" specifies exception handlers and/or cleanup\ncode for a group of statements, while the "with" statement allows the\nexecution of initialization and finalization code around a block of\ncode. Function and class definitions are also syntactically compound\nstatements.\n\nA compound statement consists of one or more \'clauses.\' A clause\nconsists of a header and a \'suite.\' The clause headers of a\nparticular compound statement are all at the same indentation level.\nEach clause header begins with a uniquely identifying keyword and ends\nwith a colon. A suite is a group of statements controlled by a\nclause. A suite can be one or more semicolon-separated simple\nstatements on the same line as the header, following the header\'s\ncolon, or it can be one or more indented statements on subsequent\nlines. Only the latter form of a suite can contain nested compound\nstatements; the following is illegal, mostly because it wouldn\'t be\nclear to which "if" clause a following "else" clause would belong:\n\n if test1: if test2: print(x)\n\nAlso note that the semicolon binds tighter than the colon in this\ncontext, so that in the following example, either all or none of the\n"print()" calls are executed:\n\n if x < y < z: print(x); print(y); print(z)\n\nSummarizing:\n\n compound_stmt ::= if_stmt\n | while_stmt\n | for_stmt\n | try_stmt\n | with_stmt\n | funcdef\n | classdef\n suite ::= stmt_list NEWLINE | NEWLINE INDENT statement+ DEDENT\n statement ::= stmt_list NEWLINE | compound_stmt\n stmt_list ::= simple_stmt (";" simple_stmt)* [";"]\n\nNote that statements always end in a "NEWLINE" possibly followed by a\n"DEDENT". Also note that optional continuation clauses always begin\nwith a keyword that cannot start a statement, thus there are no\nambiguities (the \'dangling "else"\' problem is solved in Python by\nrequiring nested "if" statements to be indented).\n\nThe formatting of the grammar rules in the following sections places\neach clause on a separate line for clarity.\n\n\nThe "if" statement\n==================\n\nThe "if" statement is used for conditional execution:\n\n if_stmt ::= "if" expression ":" suite\n ( "elif" expression ":" suite )*\n ["else" ":" suite]\n\nIt selects exactly one of the suites by evaluating the expressions one\nby one until one is found to be true (see section *Boolean operations*\nfor the definition of true and false); then that suite is executed\n(and no other part of the "if" statement is executed or evaluated).\nIf all expressions are false, the suite of the "else" clause, if\npresent, is executed.\n\n\nThe "while" statement\n=====================\n\nThe "while" statement is used for repeated execution as long as an\nexpression is true:\n\n while_stmt ::= "while" expression ":" suite\n ["else" ":" suite]\n\nThis repeatedly tests the expression and, if it is true, executes the\nfirst suite; if the expression is false (which may be the first time\nit is tested) the suite of the "else" clause, if present, is executed\nand the loop terminates.\n\nA "break" statement executed in the first suite terminates the loop\nwithout executing the "else" clause\'s suite. A "continue" statement\nexecuted in the first suite skips the rest of the suite and goes back\nto testing the expression.\n\n\nThe "for" statement\n===================\n\nThe "for" statement is used to iterate over the elements of a sequence\n(such as a string, tuple or list) or other iterable object:\n\n for_stmt ::= "for" target_list "in" expression_list ":" suite\n ["else" ":" suite]\n\nThe expression list is evaluated once; it should yield an iterable\nobject. An iterator is created for the result of the\n"expression_list". The suite is then executed once for each item\nprovided by the iterator, in the order returned by the iterator. Each\nitem in turn is assigned to the target list using the standard rules\nfor assignments (see *Assignment statements*), and then the suite is\nexecuted. When the items are exhausted (which is immediately when the\nsequence is empty or an iterator raises a "StopIteration" exception),\nthe suite in the "else" clause, if present, is executed, and the loop\nterminates.\n\nA "break" statement executed in the first suite terminates the loop\nwithout executing the "else" clause\'s suite. A "continue" statement\nexecuted in the first suite skips the rest of the suite and continues\nwith the next item, or with the "else" clause if there is no next\nitem.\n\nThe for-loop makes assignments to the variables(s) in the target list.\nThis overwrites all previous assignments to those variables including\nthose made in the suite of the for-loop:\n\n for i in range(10):\n print(i)\n i = 5 # this will not affect the for-loop\n # because i will be overwritten with the next\n # index in the range\n\nNames in the target list are not deleted when the loop is finished,\nbut if the sequence is empty, they will not have been assigned to at\nall by the loop. Hint: the built-in function "range()" returns an\niterator of integers suitable to emulate the effect of Pascal\'s "for i\n:= a to b do"; e.g., "list(range(3))" returns the list "[0, 1, 2]".\n\nNote: There is a subtlety when the sequence is being modified by the\n loop (this can only occur for mutable sequences, i.e. lists). An\n internal counter is used to keep track of which item is used next,\n and this is incremented on each iteration. When this counter has\n reached the length of the sequence the loop terminates. This means\n that if the suite deletes the current (or a previous) item from the\n sequence, the next item will be skipped (since it gets the index of\n the current item which has already been treated). Likewise, if the\n suite inserts an item in the sequence before the current item, the\n current item will be treated again the next time through the loop.\n This can lead to nasty bugs that can be avoided by making a\n temporary copy using a slice of the whole sequence, e.g.,\n\n for x in a[:]:\n if x < 0: a.remove(x)\n\n\nThe "try" statement\n===================\n\nThe "try" statement specifies exception handlers and/or cleanup code\nfor a group of statements:\n\n try_stmt ::= try1_stmt | try2_stmt\n try1_stmt ::= "try" ":" suite\n ("except" [expression ["as" identifier]] ":" suite)+\n ["else" ":" suite]\n ["finally" ":" suite]\n try2_stmt ::= "try" ":" suite\n "finally" ":" suite\n\nThe "except" clause(s) specify one or more exception handlers. When no\nexception occurs in the "try" clause, no exception handler is\nexecuted. When an exception occurs in the "try" suite, a search for an\nexception handler is started. This search inspects the except clauses\nin turn until one is found that matches the exception. An expression-\nless except clause, if present, must be last; it matches any\nexception. For an except clause with an expression, that expression\nis evaluated, and the clause matches the exception if the resulting\nobject is "compatible" with the exception. An object is compatible\nwith an exception if it is the class or a base class of the exception\nobject or a tuple containing an item compatible with the exception.\n\nIf no except clause matches the exception, the search for an exception\nhandler continues in the surrounding code and on the invocation stack.\n[1]\n\nIf the evaluation of an expression in the header of an except clause\nraises an exception, the original search for a handler is canceled and\na search starts for the new exception in the surrounding code and on\nthe call stack (it is treated as if the entire "try" statement raised\nthe exception).\n\nWhen a matching except clause is found, the exception is assigned to\nthe target specified after the "as" keyword in that except clause, if\npresent, and the except clause\'s suite is executed. All except\nclauses must have an executable block. When the end of this block is\nreached, execution continues normally after the entire try statement.\n(This means that if two nested handlers exist for the same exception,\nand the exception occurs in the try clause of the inner handler, the\nouter handler will not handle the exception.)\n\nWhen an exception has been assigned using "as target", it is cleared\nat the end of the except clause. This is as if\n\n except E as N:\n foo\n\nwas translated to\n\n except E as N:\n try:\n foo\n finally:\n del N\n\nThis means the exception must be assigned to a different name to be\nable to refer to it after the except clause. Exceptions are cleared\nbecause with the traceback attached to them, they form a reference\ncycle with the stack frame, keeping all locals in that frame alive\nuntil the next garbage collection occurs.\n\nBefore an except clause\'s suite is executed, details about the\nexception are stored in the "sys" module and can be accessed via\n"sys.exc_info()". "sys.exc_info()" returns a 3-tuple consisting of the\nexception class, the exception instance and a traceback object (see\nsection *The standard type hierarchy*) identifying the point in the\nprogram where the exception occurred. "sys.exc_info()" values are\nrestored to their previous values (before the call) when returning\nfrom a function that handled an exception.\n\nThe optional "else" clause is executed if and when control flows off\nthe end of the "try" clause. [2] Exceptions in the "else" clause are\nnot handled by the preceding "except" clauses.\n\nIf "finally" is present, it specifies a \'cleanup\' handler. The "try"\nclause is executed, including any "except" and "else" clauses. If an\nexception occurs in any of the clauses and is not handled, the\nexception is temporarily saved. The "finally" clause is executed. If\nthere is a saved exception it is re-raised at the end of the "finally"\nclause. If the "finally" clause raises another exception, the saved\nexception is set as the context of the new exception. If the "finally"\nclause executes a "return" or "break" statement, the saved exception\nis discarded:\n\n >>> def f():\n ... try:\n ... 1/0\n ... finally:\n ... return 42\n ...\n >>> f()\n 42\n\nThe exception information is not available to the program during\nexecution of the "finally" clause.\n\nWhen a "return", "break" or "continue" statement is executed in the\n"try" suite of a "try"..."finally" statement, the "finally" clause is\nalso executed \'on the way out.\' A "continue" statement is illegal in\nthe "finally" clause. (The reason is a problem with the current\nimplementation --- this restriction may be lifted in the future).\n\nThe return value of a function is determined by the last "return"\nstatement executed. Since the "finally" clause always executes, a\n"return" statement executed in the "finally" clause will always be the\nlast one executed:\n\n >>> def foo():\n ... try:\n ... return \'try\'\n ... finally:\n ... return \'finally\'\n ...\n >>> foo()\n \'finally\'\n\nAdditional information on exceptions can be found in section\n*Exceptions*, and information on using the "raise" statement to\ngenerate exceptions may be found in section *The raise statement*.\n\n\nThe "with" statement\n====================\n\nThe "with" statement is used to wrap the execution of a block with\nmethods defined by a context manager (see section *With Statement\nContext Managers*). This allows common "try"..."except"..."finally"\nusage patterns to be encapsulated for convenient reuse.\n\n with_stmt ::= "with" with_item ("," with_item)* ":" suite\n with_item ::= expression ["as" target]\n\nThe execution of the "with" statement with one "item" proceeds as\nfollows:\n\n1. The context expression (the expression given in the "with_item")\n is evaluated to obtain a context manager.\n\n2. The context manager\'s "__exit__()" is loaded for later use.\n\n3. The context manager\'s "__enter__()" method is invoked.\n\n4. If a target was included in the "with" statement, the return\n value from "__enter__()" is assigned to it.\n\n Note: The "with" statement guarantees that if the "__enter__()"\n method returns without an error, then "__exit__()" will always be\n called. Thus, if an error occurs during the assignment to the\n target list, it will be treated the same as an error occurring\n within the suite would be. See step 6 below.\n\n5. The suite is executed.\n\n6. The context manager\'s "__exit__()" method is invoked. If an\n exception caused the suite to be exited, its type, value, and\n traceback are passed as arguments to "__exit__()". Otherwise, three\n "None" arguments are supplied.\n\n If the suite was exited due to an exception, and the return value\n from the "__exit__()" method was false, the exception is reraised.\n If the return value was true, the exception is suppressed, and\n execution continues with the statement following the "with"\n statement.\n\n If the suite was exited for any reason other than an exception, the\n return value from "__exit__()" is ignored, and execution proceeds\n at the normal location for the kind of exit that was taken.\n\nWith more than one item, the context managers are processed as if\nmultiple "with" statements were nested:\n\n with A() as a, B() as b:\n suite\n\nis equivalent to\n\n with A() as a:\n with B() as b:\n suite\n\nChanged in version 3.1: Support for multiple context expressions.\n\nSee also: **PEP 0343** - The "with" statement\n\n The specification, background, and examples for the Python "with"\n statement.\n\n\nFunction definitions\n====================\n\nA function definition defines a user-defined function object (see\nsection *The standard type hierarchy*):\n\n funcdef ::= [decorators] "def" funcname "(" [parameter_list] ")" ["->" expression] ":" suite\n decorators ::= decorator+\n decorator ::= "@" dotted_name ["(" [parameter_list [","]] ")"] NEWLINE\n dotted_name ::= identifier ("." identifier)*\n parameter_list ::= (defparameter ",")*\n | "*" [parameter] ("," defparameter)* ["," "**" parameter]\n | "**" parameter\n | defparameter [","] )\n parameter ::= identifier [":" expression]\n defparameter ::= parameter ["=" expression]\n funcname ::= identifier\n\nA function definition is an executable statement. Its execution binds\nthe function name in the current local namespace to a function object\n(a wrapper around the executable code for the function). This\nfunction object contains a reference to the current global namespace\nas the global namespace to be used when the function is called.\n\nThe function definition does not execute the function body; this gets\nexecuted only when the function is called. [3]\n\nA function definition may be wrapped by one or more *decorator*\nexpressions. Decorator expressions are evaluated when the function is\ndefined, in the scope that contains the function definition. The\nresult must be a callable, which is invoked with the function object\nas the only argument. The returned value is bound to the function name\ninstead of the function object. Multiple decorators are applied in\nnested fashion. For example, the following code\n\n @f1(arg)\n @f2\n def func(): pass\n\nis equivalent to\n\n def func(): pass\n func = f1(arg)(f2(func))\n\nWhen one or more *parameters* have the form *parameter* "="\n*expression*, the function is said to have "default parameter values."\nFor a parameter with a default value, the corresponding *argument* may\nbe omitted from a call, in which case the parameter\'s default value is\nsubstituted. If a parameter has a default value, all following\nparameters up until the ""*"" must also have a default value --- this\nis a syntactic restriction that is not expressed by the grammar.\n\n**Default parameter values are evaluated from left to right when the\nfunction definition is executed.** This means that the expression is\nevaluated once, when the function is defined, and that the same "pre-\ncomputed" value is used for each call. This is especially important\nto understand when a default parameter is a mutable object, such as a\nlist or a dictionary: if the function modifies the object (e.g. by\nappending an item to a list), the default value is in effect modified.\nThis is generally not what was intended. A way around this is to use\n"None" as the default, and explicitly test for it in the body of the\nfunction, e.g.:\n\n def whats_on_the_telly(penguin=None):\n if penguin is None:\n penguin = []\n penguin.append("property of the zoo")\n return penguin\n\nFunction call semantics are described in more detail in section\n*Calls*. A function call always assigns values to all parameters\nmentioned in the parameter list, either from position arguments, from\nkeyword arguments, or from default values. If the form\n""*identifier"" is present, it is initialized to a tuple receiving any\nexcess positional parameters, defaulting to the empty tuple. If the\nform ""**identifier"" is present, it is initialized to a new\ndictionary receiving any excess keyword arguments, defaulting to a new\nempty dictionary. Parameters after ""*"" or ""*identifier"" are\nkeyword-only parameters and may only be passed used keyword arguments.\n\nParameters may have annotations of the form "": expression"" following\nthe parameter name. Any parameter may have an annotation even those\nof the form "*identifier" or "**identifier". Functions may have\n"return" annotation of the form ""-> expression"" after the parameter\nlist. These annotations can be any valid Python expression and are\nevaluated when the function definition is executed. Annotations may\nbe evaluated in a different order than they appear in the source code.\nThe presence of annotations does not change the semantics of a\nfunction. The annotation values are available as values of a\ndictionary keyed by the parameters\' names in the "__annotations__"\nattribute of the function object.\n\nIt is also possible to create anonymous functions (functions not bound\nto a name), for immediate use in expressions. This uses lambda\nexpressions, described in section *Lambdas*. Note that the lambda\nexpression is merely a shorthand for a simplified function definition;\na function defined in a ""def"" statement can be passed around or\nassigned to another name just like a function defined by a lambda\nexpression. The ""def"" form is actually more powerful since it\nallows the execution of multiple statements and annotations.\n\n**Programmer\'s note:** Functions are first-class objects. A ""def""\nstatement executed inside a function definition defines a local\nfunction that can be returned or passed around. Free variables used\nin the nested function can access the local variables of the function\ncontaining the def. See section *Naming and binding* for details.\n\nSee also: **PEP 3107** - Function Annotations\n\n The original specification for function annotations.\n\n\nClass definitions\n=================\n\nA class definition defines a class object (see section *The standard\ntype hierarchy*):\n\n classdef ::= [decorators] "class" classname [inheritance] ":" suite\n inheritance ::= "(" [parameter_list] ")"\n classname ::= identifier\n\nA class definition is an executable statement. The inheritance list\nusually gives a list of base classes (see *Customizing class creation*\nfor more advanced uses), so each item in the list should evaluate to a\nclass object which allows subclassing. Classes without an inheritance\nlist inherit, by default, from the base class "object"; hence,\n\n class Foo:\n pass\n\nis equivalent to\n\n class Foo(object):\n pass\n\nThe class\'s suite is then executed in a new execution frame (see\n*Naming and binding*), using a newly created local namespace and the\noriginal global namespace. (Usually, the suite contains mostly\nfunction definitions.) When the class\'s suite finishes execution, its\nexecution frame is discarded but its local namespace is saved. [4] A\nclass object is then created using the inheritance list for the base\nclasses and the saved local namespace for the attribute dictionary.\nThe class name is bound to this class object in the original local\nnamespace.\n\nClass creation can be customized heavily using *metaclasses*.\n\nClasses can also be decorated: just like when decorating functions,\n\n @f1(arg)\n @f2\n class Foo: pass\n\nis equivalent to\n\n class Foo: pass\n Foo = f1(arg)(f2(Foo))\n\nThe evaluation rules for the decorator expressions are the same as for\nfunction decorators. The result must be a class object, which is then\nbound to the class name.\n\n**Programmer\'s note:** Variables defined in the class definition are\nclass attributes; they are shared by instances. Instance attributes\ncan be set in a method with "self.name = value". Both class and\ninstance attributes are accessible through the notation ""self.name"",\nand an instance attribute hides a class attribute with the same name\nwhen accessed in this way. Class attributes can be used as defaults\nfor instance attributes, but using mutable values there can lead to\nunexpected results. *Descriptors* can be used to create instance\nvariables with different implementation details.\n\nSee also: **PEP 3115** - Metaclasses in Python 3 **PEP 3129** -\n Class Decorators\n\n-[ Footnotes ]-\n\n[1] The exception is propagated to the invocation stack unless\n there is a "finally" clause which happens to raise another\n exception. That new exception causes the old one to be lost.\n\n[2] Currently, control "flows off the end" except in the case of\n an exception or the execution of a "return", "continue", or\n "break" statement.\n\n[3] A string literal appearing as the first statement in the\n function body is transformed into the function\'s "__doc__"\n attribute and therefore the function\'s *docstring*.\n\n[4] A string literal appearing as the first statement in the class\n body is transformed into the namespace\'s "__doc__" item and\n therefore the class\'s *docstring*.\n', + 'context-managers': u'\nWith Statement Context Managers\n*******************************\n\nA *context manager* is an object that defines the runtime context to\nbe established when executing a "with" statement. The context manager\nhandles the entry into, and the exit from, the desired runtime context\nfor the execution of the block of code. Context managers are normally\ninvoked using the "with" statement (described in section *The with\nstatement*), but can also be used by directly invoking their methods.\n\nTypical uses of context managers include saving and restoring various\nkinds of global state, locking and unlocking resources, closing opened\nfiles, etc.\n\nFor more information on context managers, see *Context Manager Types*.\n\nobject.__enter__(self)\n\n Enter the runtime context related to this object. The "with"\n statement will bind this method\'s return value to the target(s)\n specified in the "as" clause of the statement, if any.\n\nobject.__exit__(self, exc_type, exc_value, traceback)\n\n Exit the runtime context related to this object. The parameters\n describe the exception that caused the context to be exited. If the\n context was exited without an exception, all three arguments will\n be "None".\n\n If an exception is supplied, and the method wishes to suppress the\n exception (i.e., prevent it from being propagated), it should\n return a true value. Otherwise, the exception will be processed\n normally upon exit from this method.\n\n Note that "__exit__()" methods should not reraise the passed-in\n exception; this is the caller\'s responsibility.\n\nSee also: **PEP 0343** - The "with" statement\n\n The specification, background, and examples for the Python "with"\n statement.\n', + 'continue': u'\nThe "continue" statement\n************************\n\n continue_stmt ::= "continue"\n\n"continue" may only occur syntactically nested in a "for" or "while"\nloop, but not nested in a function or class definition or "finally"\nclause within that loop. It continues with the next cycle of the\nnearest enclosing loop.\n\nWhen "continue" passes control out of a "try" statement with a\n"finally" clause, that "finally" clause is executed before really\nstarting the next loop cycle.\n', + 'conversions': u'\nArithmetic conversions\n**********************\n\nWhen a description of an arithmetic operator below uses the phrase\n"the numeric arguments are converted to a common type," this means\nthat the operator implementation for built-in types works as follows:\n\n* If either argument is a complex number, the other is converted to\n complex;\n\n* otherwise, if either argument is a floating point number, the\n other is converted to floating point;\n\n* otherwise, both must be integers and no conversion is necessary.\n\nSome additional rules apply for certain operators (e.g., a string as a\nleft argument to the \'%\' operator). Extensions must define their own\nconversion behavior.\n', + 'customization': u'\nBasic customization\n*******************\n\nobject.__new__(cls[, ...])\n\n Called to create a new instance of class *cls*. "__new__()" is a\n static method (special-cased so you need not declare it as such)\n that takes the class of which an instance was requested as its\n first argument. The remaining arguments are those passed to the\n object constructor expression (the call to the class). The return\n value of "__new__()" should be the new object instance (usually an\n instance of *cls*).\n\n Typical implementations create a new instance of the class by\n invoking the superclass\'s "__new__()" method using\n "super(currentclass, cls).__new__(cls[, ...])" with appropriate\n arguments and then modifying the newly-created instance as\n necessary before returning it.\n\n If "__new__()" returns an instance of *cls*, then the new\n instance\'s "__init__()" method will be invoked like\n "__init__(self[, ...])", where *self* is the new instance and the\n remaining arguments are the same as were passed to "__new__()".\n\n If "__new__()" does not return an instance of *cls*, then the new\n instance\'s "__init__()" method will not be invoked.\n\n "__new__()" is intended mainly to allow subclasses of immutable\n types (like int, str, or tuple) to customize instance creation. It\n is also commonly overridden in custom metaclasses in order to\n customize class creation.\n\nobject.__init__(self[, ...])\n\n Called after the instance has been created (by "__new__()"), but\n before it is returned to the caller. The arguments are those\n passed to the class constructor expression. If a base class has an\n "__init__()" method, the derived class\'s "__init__()" method, if\n any, must explicitly call it to ensure proper initialization of the\n base class part of the instance; for example:\n "BaseClass.__init__(self, [args...])".\n\n Because "__new__()" and "__init__()" work together in constructing\n objects ("__new__()" to create it, and "__init__()" to customise\n it), no non-"None" value may be returned by "__init__()"; doing so\n will cause a "TypeError" to be raised at runtime.\n\nobject.__del__(self)\n\n Called when the instance is about to be destroyed. This is also\n called a destructor. If a base class has a "__del__()" method, the\n derived class\'s "__del__()" method, if any, must explicitly call it\n to ensure proper deletion of the base class part of the instance.\n Note that it is possible (though not recommended!) for the\n "__del__()" method to postpone destruction of the instance by\n creating a new reference to it. It may then be called at a later\n time when this new reference is deleted. It is not guaranteed that\n "__del__()" methods are called for objects that still exist when\n the interpreter exits.\n\n Note: "del x" doesn\'t directly call "x.__del__()" --- the former\n decrements the reference count for "x" by one, and the latter is\n only called when "x"\'s reference count reaches zero. Some common\n situations that may prevent the reference count of an object from\n going to zero include: circular references between objects (e.g.,\n a doubly-linked list or a tree data structure with parent and\n child pointers); a reference to the object on the stack frame of\n a function that caught an exception (the traceback stored in\n "sys.exc_info()[2]" keeps the stack frame alive); or a reference\n to the object on the stack frame that raised an unhandled\n exception in interactive mode (the traceback stored in\n "sys.last_traceback" keeps the stack frame alive). The first\n situation can only be remedied by explicitly breaking the cycles;\n the second can be resolved by freeing the reference to the\n traceback object when it is no longer useful, and the third can\n be resolved by storing "None" in "sys.last_traceback". Circular\n references which are garbage are detected and cleaned up when the\n cyclic garbage collector is enabled (it\'s on by default). Refer\n to the documentation for the "gc" module for more information\n about this topic.\n\n Warning: Due to the precarious circumstances under which\n "__del__()" methods are invoked, exceptions that occur during\n their execution are ignored, and a warning is printed to\n "sys.stderr" instead. Also, when "__del__()" is invoked in\n response to a module being deleted (e.g., when execution of the\n program is done), other globals referenced by the "__del__()"\n method may already have been deleted or in the process of being\n torn down (e.g. the import machinery shutting down). For this\n reason, "__del__()" methods should do the absolute minimum needed\n to maintain external invariants. Starting with version 1.5,\n Python guarantees that globals whose name begins with a single\n underscore are deleted from their module before other globals are\n deleted; if no other references to such globals exist, this may\n help in assuring that imported modules are still available at the\n time when the "__del__()" method is called.\n\nobject.__repr__(self)\n\n Called by the "repr()" built-in function to compute the "official"\n string representation of an object. If at all possible, this\n should look like a valid Python expression that could be used to\n recreate an object with the same value (given an appropriate\n environment). If this is not possible, a string of the form\n "<...some useful description...>" should be returned. The return\n value must be a string object. If a class defines "__repr__()" but\n not "__str__()", then "__repr__()" is also used when an "informal"\n string representation of instances of that class is required.\n\n This is typically used for debugging, so it is important that the\n representation is information-rich and unambiguous.\n\nobject.__str__(self)\n\n Called by "str(object)" and the built-in functions "format()" and\n "print()" to compute the "informal" or nicely printable string\n representation of an object. The return value must be a *string*\n object.\n\n This method differs from "object.__repr__()" in that there is no\n expectation that "__str__()" return a valid Python expression: a\n more convenient or concise representation can be used.\n\n The default implementation defined by the built-in type "object"\n calls "object.__repr__()".\n\nobject.__bytes__(self)\n\n Called by "bytes()" to compute a byte-string representation of an\n object. This should return a "bytes" object.\n\nobject.__format__(self, format_spec)\n\n Called by the "format()" built-in function (and by extension, the\n "str.format()" method of class "str") to produce a "formatted"\n string representation of an object. The "format_spec" argument is a\n string that contains a description of the formatting options\n desired. The interpretation of the "format_spec" argument is up to\n the type implementing "__format__()", however most classes will\n either delegate formatting to one of the built-in types, or use a\n similar formatting option syntax.\n\n See *Format Specification Mini-Language* for a description of the\n standard formatting syntax.\n\n The return value must be a string object.\n\n Changed in version 3.4: The __format__ method of "object" itself\n raises a "TypeError" if passed any non-empty string.\n\nobject.__lt__(self, other)\nobject.__le__(self, other)\nobject.__eq__(self, other)\nobject.__ne__(self, other)\nobject.__gt__(self, other)\nobject.__ge__(self, other)\n\n These are the so-called "rich comparison" methods. The\n correspondence between operator symbols and method names is as\n follows: "x<y" calls "x.__lt__(y)", "x<=y" calls "x.__le__(y)",\n "x==y" calls "x.__eq__(y)", "x!=y" calls "x.__ne__(y)", "x>y" calls\n "x.__gt__(y)", and "x>=y" calls "x.__ge__(y)".\n\n A rich comparison method may return the singleton "NotImplemented"\n if it does not implement the operation for a given pair of\n arguments. By convention, "False" and "True" are returned for a\n successful comparison. However, these methods can return any value,\n so if the comparison operator is used in a Boolean context (e.g.,\n in the condition of an "if" statement), Python will call "bool()"\n on the value to determine if the result is true or false.\n\n There are no implied relationships among the comparison operators.\n The truth of "x==y" does not imply that "x!=y" is false.\n Accordingly, when defining "__eq__()", one should also define\n "__ne__()" so that the operators will behave as expected. See the\n paragraph on "__hash__()" for some important notes on creating\n *hashable* objects which support custom comparison operations and\n are usable as dictionary keys.\n\n There are no swapped-argument versions of these methods (to be used\n when the left argument does not support the operation but the right\n argument does); rather, "__lt__()" and "__gt__()" are each other\'s\n reflection, "__le__()" and "__ge__()" are each other\'s reflection,\n and "__eq__()" and "__ne__()" are their own reflection.\n\n Arguments to rich comparison methods are never coerced.\n\n To automatically generate ordering operations from a single root\n operation, see "functools.total_ordering()".\n\nobject.__hash__(self)\n\n Called by built-in function "hash()" and for operations on members\n of hashed collections including "set", "frozenset", and "dict".\n "__hash__()" should return an integer. The only required property\n is that objects which compare equal have the same hash value; it is\n advised to somehow mix together (e.g. using exclusive or) the hash\n values for the components of the object that also play a part in\n comparison of objects.\n\n Note: "hash()" truncates the value returned from an object\'s\n custom "__hash__()" method to the size of a "Py_ssize_t". This\n is typically 8 bytes on 64-bit builds and 4 bytes on 32-bit\n builds. If an object\'s "__hash__()" must interoperate on builds\n of different bit sizes, be sure to check the width on all\n supported builds. An easy way to do this is with "python -c\n "import sys; print(sys.hash_info.width)""\n\n If a class does not define an "__eq__()" method it should not\n define a "__hash__()" operation either; if it defines "__eq__()"\n but not "__hash__()", its instances will not be usable as items in\n hashable collections. If a class defines mutable objects and\n implements an "__eq__()" method, it should not implement\n "__hash__()", since the implementation of hashable collections\n requires that a key\'s hash value is immutable (if the object\'s hash\n value changes, it will be in the wrong hash bucket).\n\n User-defined classes have "__eq__()" and "__hash__()" methods by\n default; with them, all objects compare unequal (except with\n themselves) and "x.__hash__()" returns an appropriate value such\n that "x == y" implies both that "x is y" and "hash(x) == hash(y)".\n\n A class that overrides "__eq__()" and does not define "__hash__()"\n will have its "__hash__()" implicitly set to "None". When the\n "__hash__()" method of a class is "None", instances of the class\n will raise an appropriate "TypeError" when a program attempts to\n retrieve their hash value, and will also be correctly identified as\n unhashable when checking "isinstance(obj, collections.Hashable").\n\n If a class that overrides "__eq__()" needs to retain the\n implementation of "__hash__()" from a parent class, the interpreter\n must be told this explicitly by setting "__hash__ =\n <ParentClass>.__hash__".\n\n If a class that does not override "__eq__()" wishes to suppress\n hash support, it should include "__hash__ = None" in the class\n definition. A class which defines its own "__hash__()" that\n explicitly raises a "TypeError" would be incorrectly identified as\n hashable by an "isinstance(obj, collections.Hashable)" call.\n\n Note: By default, the "__hash__()" values of str, bytes and\n datetime objects are "salted" with an unpredictable random value.\n Although they remain constant within an individual Python\n process, they are not predictable between repeated invocations of\n Python.This is intended to provide protection against a denial-\n of-service caused by carefully-chosen inputs that exploit the\n worst case performance of a dict insertion, O(n^2) complexity.\n See http://www.ocert.org/advisories/ocert-2011-003.html for\n details.Changing hash values affects the iteration order of\n dicts, sets and other mappings. Python has never made guarantees\n about this ordering (and it typically varies between 32-bit and\n 64-bit builds).See also "PYTHONHASHSEED".\n\n Changed in version 3.3: Hash randomization is enabled by default.\n\nobject.__bool__(self)\n\n Called to implement truth value testing and the built-in operation\n "bool()"; should return "False" or "True". When this method is not\n defined, "__len__()" is called, if it is defined, and the object is\n considered true if its result is nonzero. If a class defines\n neither "__len__()" nor "__bool__()", all its instances are\n considered true.\n', + 'debugger': u'\n"pdb" --- The Python Debugger\n*****************************\n\n**Source code:** Lib/pdb.py\n\n======================================================================\n\nThe module "pdb" defines an interactive source code debugger for\nPython programs. It supports setting (conditional) breakpoints and\nsingle stepping at the source line level, inspection of stack frames,\nsource code listing, and evaluation of arbitrary Python code in the\ncontext of any stack frame. It also supports post-mortem debugging\nand can be called under program control.\n\nThe debugger is extensible -- it is actually defined as the class\n"Pdb". This is currently undocumented but easily understood by reading\nthe source. The extension interface uses the modules "bdb" and "cmd".\n\nThe debugger\'s prompt is "(Pdb)". Typical usage to run a program under\ncontrol of the debugger is:\n\n >>> import pdb\n >>> import mymodule\n >>> pdb.run(\'mymodule.test()\')\n > <string>(0)?()\n (Pdb) continue\n > <string>(1)?()\n (Pdb) continue\n NameError: \'spam\'\n > <string>(1)?()\n (Pdb)\n\nChanged in version 3.3: Tab-completion via the "readline" module is\navailable for commands and command arguments, e.g. the current global\nand local names are offered as arguments of the "p" command.\n\n"pdb.py" can also be invoked as a script to debug other scripts. For\nexample:\n\n python3 -m pdb myscript.py\n\nWhen invoked as a script, pdb will automatically enter post-mortem\ndebugging if the program being debugged exits abnormally. After post-\nmortem debugging (or after normal exit of the program), pdb will\nrestart the program. Automatic restarting preserves pdb\'s state (such\nas breakpoints) and in most cases is more useful than quitting the\ndebugger upon program\'s exit.\n\nNew in version 3.2: "pdb.py" now accepts a "-c" option that executes\ncommands as if given in a ".pdbrc" file, see *Debugger Commands*.\n\nThe typical usage to break into the debugger from a running program is\nto insert\n\n import pdb; pdb.set_trace()\n\nat the location you want to break into the debugger. You can then\nstep through the code following this statement, and continue running\nwithout the debugger using the "continue" command.\n\nThe typical usage to inspect a crashed program is:\n\n >>> import pdb\n >>> import mymodule\n >>> mymodule.test()\n Traceback (most recent call last):\n File "<stdin>", line 1, in ?\n File "./mymodule.py", line 4, in test\n test2()\n File "./mymodule.py", line 3, in test2\n print(spam)\n NameError: spam\n >>> pdb.pm()\n > ./mymodule.py(3)test2()\n -> print(spam)\n (Pdb)\n\nThe module defines the following functions; each enters the debugger\nin a slightly different way:\n\npdb.run(statement, globals=None, locals=None)\n\n Execute the *statement* (given as a string or a code object) under\n debugger control. The debugger prompt appears before any code is\n executed; you can set breakpoints and type "continue", or you can\n step through the statement using "step" or "next" (all these\n commands are explained below). The optional *globals* and *locals*\n arguments specify the environment in which the code is executed; by\n default the dictionary of the module "__main__" is used. (See the\n explanation of the built-in "exec()" or "eval()" functions.)\n\npdb.runeval(expression, globals=None, locals=None)\n\n Evaluate the *expression* (given as a string or a code object)\n under debugger control. When "runeval()" returns, it returns the\n value of the expression. Otherwise this function is similar to\n "run()".\n\npdb.runcall(function, *args, **kwds)\n\n Call the *function* (a function or method object, not a string)\n with the given arguments. When "runcall()" returns, it returns\n whatever the function call returned. The debugger prompt appears\n as soon as the function is entered.\n\npdb.set_trace()\n\n Enter the debugger at the calling stack frame. This is useful to\n hard-code a breakpoint at a given point in a program, even if the\n code is not otherwise being debugged (e.g. when an assertion\n fails).\n\npdb.post_mortem(traceback=None)\n\n Enter post-mortem debugging of the given *traceback* object. If no\n *traceback* is given, it uses the one of the exception that is\n currently being handled (an exception must be being handled if the\n default is to be used).\n\npdb.pm()\n\n Enter post-mortem debugging of the traceback found in\n "sys.last_traceback".\n\nThe "run*" functions and "set_trace()" are aliases for instantiating\nthe "Pdb" class and calling the method of the same name. If you want\nto access further features, you have to do this yourself:\n\nclass class pdb.Pdb(completekey=\'tab\', stdin=None, stdout=None, skip=None, nosigint=False)\n\n "Pdb" is the debugger class.\n\n The *completekey*, *stdin* and *stdout* arguments are passed to the\n underlying "cmd.Cmd" class; see the description there.\n\n The *skip* argument, if given, must be an iterable of glob-style\n module name patterns. The debugger will not step into frames that\n originate in a module that matches one of these patterns. [1]\n\n By default, Pdb sets a handler for the SIGINT signal (which is sent\n when the user presses Ctrl-C on the console) when you give a\n "continue" command. This allows you to break into the debugger\n again by pressing Ctrl-C. If you want Pdb not to touch the SIGINT\n handler, set *nosigint* tot true.\n\n Example call to enable tracing with *skip*:\n\n import pdb; pdb.Pdb(skip=[\'django.*\']).set_trace()\n\n New in version 3.1: The *skip* argument.\n\n New in version 3.2: The *nosigint* argument. Previously, a SIGINT\n handler was never set by Pdb.\n\n run(statement, globals=None, locals=None)\n runeval(expression, globals=None, locals=None)\n runcall(function, *args, **kwds)\n set_trace()\n\n See the documentation for the functions explained above.\n\n\nDebugger Commands\n=================\n\nThe commands recognized by the debugger are listed below. Most\ncommands can be abbreviated to one or two letters as indicated; e.g.\n"h(elp)" means that either "h" or "help" can be used to enter the help\ncommand (but not "he" or "hel", nor "H" or "Help" or "HELP").\nArguments to commands must be separated by whitespace (spaces or\ntabs). Optional arguments are enclosed in square brackets ("[]") in\nthe command syntax; the square brackets must not be typed.\nAlternatives in the command syntax are separated by a vertical bar\n("|").\n\nEntering a blank line repeats the last command entered. Exception: if\nthe last command was a "list" command, the next 11 lines are listed.\n\nCommands that the debugger doesn\'t recognize are assumed to be Python\nstatements and are executed in the context of the program being\ndebugged. Python statements can also be prefixed with an exclamation\npoint ("!"). This is a powerful way to inspect the program being\ndebugged; it is even possible to change a variable or call a function.\nWhen an exception occurs in such a statement, the exception name is\nprinted but the debugger\'s state is not changed.\n\nThe debugger supports *aliases*. Aliases can have parameters which\nallows one a certain level of adaptability to the context under\nexamination.\n\nMultiple commands may be entered on a single line, separated by ";;".\n(A single ";" is not used as it is the separator for multiple commands\nin a line that is passed to the Python parser.) No intelligence is\napplied to separating the commands; the input is split at the first\n";;" pair, even if it is in the middle of a quoted string.\n\nIf a file ".pdbrc" exists in the user\'s home directory or in the\ncurrent directory, it is read in and executed as if it had been typed\nat the debugger prompt. This is particularly useful for aliases. If\nboth files exist, the one in the home directory is read first and\naliases defined there can be overridden by the local file.\n\nChanged in version 3.2: ".pdbrc" can now contain commands that\ncontinue debugging, such as "continue" or "next". Previously, these\ncommands had no effect.\n\nh(elp) [command]\n\n Without argument, print the list of available commands. With a\n *command* as argument, print help about that command. "help pdb"\n displays the full documentation (the docstring of the "pdb"\n module). Since the *command* argument must be an identifier, "help\n exec" must be entered to get help on the "!" command.\n\nw(here)\n\n Print a stack trace, with the most recent frame at the bottom. An\n arrow indicates the current frame, which determines the context of\n most commands.\n\nd(own) [count]\n\n Move the current frame *count* (default one) levels down in the\n stack trace (to a newer frame).\n\nu(p) [count]\n\n Move the current frame *count* (default one) levels up in the stack\n trace (to an older frame).\n\nb(reak) [([filename:]lineno | function) [, condition]]\n\n With a *lineno* argument, set a break there in the current file.\n With a *function* argument, set a break at the first executable\n statement within that function. The line number may be prefixed\n with a filename and a colon, to specify a breakpoint in another\n file (probably one that hasn\'t been loaded yet). The file is\n searched on "sys.path". Note that each breakpoint is assigned a\n number to which all the other breakpoint commands refer.\n\n If a second argument is present, it is an expression which must\n evaluate to true before the breakpoint is honored.\n\n Without argument, list all breaks, including for each breakpoint,\n the number of times that breakpoint has been hit, the current\n ignore count, and the associated condition if any.\n\ntbreak [([filename:]lineno | function) [, condition]]\n\n Temporary breakpoint, which is removed automatically when it is\n first hit. The arguments are the same as for "break".\n\ncl(ear) [filename:lineno | bpnumber [bpnumber ...]]\n\n With a *filename:lineno* argument, clear all the breakpoints at\n this line. With a space separated list of breakpoint numbers, clear\n those breakpoints. Without argument, clear all breaks (but first\n ask confirmation).\n\ndisable [bpnumber [bpnumber ...]]\n\n Disable the breakpoints given as a space separated list of\n breakpoint numbers. Disabling a breakpoint means it cannot cause\n the program to stop execution, but unlike clearing a breakpoint, it\n remains in the list of breakpoints and can be (re-)enabled.\n\nenable [bpnumber [bpnumber ...]]\n\n Enable the breakpoints specified.\n\nignore bpnumber [count]\n\n Set the ignore count for the given breakpoint number. If count is\n omitted, the ignore count is set to 0. A breakpoint becomes active\n when the ignore count is zero. When non-zero, the count is\n decremented each time the breakpoint is reached and the breakpoint\n is not disabled and any associated condition evaluates to true.\n\ncondition bpnumber [condition]\n\n Set a new *condition* for the breakpoint, an expression which must\n evaluate to true before the breakpoint is honored. If *condition*\n is absent, any existing condition is removed; i.e., the breakpoint\n is made unconditional.\n\ncommands [bpnumber]\n\n Specify a list of commands for breakpoint number *bpnumber*. The\n commands themselves appear on the following lines. Type a line\n containing just "end" to terminate the commands. An example:\n\n (Pdb) commands 1\n (com) p some_variable\n (com) end\n (Pdb)\n\n To remove all commands from a breakpoint, type commands and follow\n it immediately with "end"; that is, give no commands.\n\n With no *bpnumber* argument, commands refers to the last breakpoint\n set.\n\n You can use breakpoint commands to start your program up again.\n Simply use the continue command, or step, or any other command that\n resumes execution.\n\n Specifying any command resuming execution (currently continue,\n step, next, return, jump, quit and their abbreviations) terminates\n the command list (as if that command was immediately followed by\n end). This is because any time you resume execution (even with a\n simple next or step), you may encounter another breakpoint--which\n could have its own command list, leading to ambiguities about which\n list to execute.\n\n If you use the \'silent\' command in the command list, the usual\n message about stopping at a breakpoint is not printed. This may be\n desirable for breakpoints that are to print a specific message and\n then continue. If none of the other commands print anything, you\n see no sign that the breakpoint was reached.\n\ns(tep)\n\n Execute the current line, stop at the first possible occasion\n (either in a function that is called or on the next line in the\n current function).\n\nn(ext)\n\n Continue execution until the next line in the current function is\n reached or it returns. (The difference between "next" and "step"\n is that "step" stops inside a called function, while "next"\n executes called functions at (nearly) full speed, only stopping at\n the next line in the current function.)\n\nunt(il) [lineno]\n\n Without argument, continue execution until the line with a number\n greater than the current one is reached.\n\n With a line number, continue execution until a line with a number\n greater or equal to that is reached. In both cases, also stop when\n the current frame returns.\n\n Changed in version 3.2: Allow giving an explicit line number.\n\nr(eturn)\n\n Continue execution until the current function returns.\n\nc(ont(inue))\n\n Continue execution, only stop when a breakpoint is encountered.\n\nj(ump) lineno\n\n Set the next line that will be executed. Only available in the\n bottom-most frame. This lets you jump back and execute code again,\n or jump forward to skip code that you don\'t want to run.\n\n It should be noted that not all jumps are allowed -- for instance\n it is not possible to jump into the middle of a "for" loop or out\n of a "finally" clause.\n\nl(ist) [first[, last]]\n\n List source code for the current file. Without arguments, list 11\n lines around the current line or continue the previous listing.\n With "." as argument, list 11 lines around the current line. With\n one argument, list 11 lines around at that line. With two\n arguments, list the given range; if the second argument is less\n than the first, it is interpreted as a count.\n\n The current line in the current frame is indicated by "->". If an\n exception is being debugged, the line where the exception was\n originally raised or propagated is indicated by ">>", if it differs\n from the current line.\n\n New in version 3.2: The ">>" marker.\n\nll | longlist\n\n List all source code for the current function or frame.\n Interesting lines are marked as for "list".\n\n New in version 3.2.\n\na(rgs)\n\n Print the argument list of the current function.\n\np expression\n\n Evaluate the *expression* in the current context and print its\n value.\n\n Note: "print()" can also be used, but is not a debugger command\n --- this executes the Python "print()" function.\n\npp expression\n\n Like the "p" command, except the value of the expression is pretty-\n printed using the "pprint" module.\n\nwhatis expression\n\n Print the type of the *expression*.\n\nsource expression\n\n Try to get source code for the given object and display it.\n\n New in version 3.2.\n\ndisplay [expression]\n\n Display the value of the expression if it changed, each time\n execution stops in the current frame.\n\n Without expression, list all display expressions for the current\n frame.\n\n New in version 3.2.\n\nundisplay [expression]\n\n Do not display the expression any more in the current frame.\n Without expression, clear all display expressions for the current\n frame.\n\n New in version 3.2.\n\ninteract\n\n Start an interative interpreter (using the "code" module) whose\n global namespace contains all the (global and local) names found in\n the current scope.\n\n New in version 3.2.\n\nalias [name [command]]\n\n Create an alias called *name* that executes *command*. The command\n must *not* be enclosed in quotes. Replaceable parameters can be\n indicated by "%1", "%2", and so on, while "%*" is replaced by all\n the parameters. If no command is given, the current alias for\n *name* is shown. If no arguments are given, all aliases are listed.\n\n Aliases may be nested and can contain anything that can be legally\n typed at the pdb prompt. Note that internal pdb commands *can* be\n overridden by aliases. Such a command is then hidden until the\n alias is removed. Aliasing is recursively applied to the first\n word of the command line; all other words in the line are left\n alone.\n\n As an example, here are two useful aliases (especially when placed\n in the ".pdbrc" file):\n\n # Print instance variables (usage "pi classInst")\n alias pi for k in %1.__dict__.keys(): print("%1.",k,"=",%1.__dict__[k])\n # Print instance variables in self\n alias ps pi self\n\nunalias name\n\n Delete the specified alias.\n\n! statement\n\n Execute the (one-line) *statement* in the context of the current\n stack frame. The exclamation point can be omitted unless the first\n word of the statement resembles a debugger command. To set a\n global variable, you can prefix the assignment command with a\n "global" statement on the same line, e.g.:\n\n (Pdb) global list_options; list_options = [\'-l\']\n (Pdb)\n\nrun [args ...]\nrestart [args ...]\n\n Restart the debugged Python program. If an argument is supplied,\n it is split with "shlex" and the result is used as the new\n "sys.argv". History, breakpoints, actions and debugger options are\n preserved. "restart" is an alias for "run".\n\nq(uit)\n\n Quit from the debugger. The program being executed is aborted.\n\n-[ Footnotes ]-\n\n[1] Whether a frame is considered to originate in a certain module\n is determined by the "__name__" in the frame globals.\n', + 'del': u'\nThe "del" statement\n*******************\n\n del_stmt ::= "del" target_list\n\nDeletion is recursively defined very similar to the way assignment is\ndefined. Rather than spelling it out in full details, here are some\nhints.\n\nDeletion of a target list recursively deletes each target, from left\nto right.\n\nDeletion of a name removes the binding of that name from the local or\nglobal namespace, depending on whether the name occurs in a "global"\nstatement in the same code block. If the name is unbound, a\n"NameError" exception will be raised.\n\nDeletion of attribute references, subscriptions and slicings is passed\nto the primary object involved; deletion of a slicing is in general\nequivalent to assignment of an empty slice of the right type (but even\nthis is determined by the sliced object).\n\nChanged in version 3.2: Previously it was illegal to delete a name\nfrom the local namespace if it occurs as a free variable in a nested\nblock.\n', + 'dict': u'\nDictionary displays\n*******************\n\nA dictionary display is a possibly empty series of key/datum pairs\nenclosed in curly braces:\n\n dict_display ::= "{" [key_datum_list | dict_comprehension] "}"\n key_datum_list ::= key_datum ("," key_datum)* [","]\n key_datum ::= expression ":" expression\n dict_comprehension ::= expression ":" expression comp_for\n\nA dictionary display yields a new dictionary object.\n\nIf a comma-separated sequence of key/datum pairs is given, they are\nevaluated from left to right to define the entries of the dictionary:\neach key object is used as a key into the dictionary to store the\ncorresponding datum. This means that you can specify the same key\nmultiple times in the key/datum list, and the final dictionary\'s value\nfor that key will be the last one given.\n\nA dict comprehension, in contrast to list and set comprehensions,\nneeds two expressions separated with a colon followed by the usual\n"for" and "if" clauses. When the comprehension is run, the resulting\nkey and value elements are inserted in the new dictionary in the order\nthey are produced.\n\nRestrictions on the types of the key values are listed earlier in\nsection *The standard type hierarchy*. (To summarize, the key type\nshould be *hashable*, which excludes all mutable objects.) Clashes\nbetween duplicate keys are not detected; the last datum (textually\nrightmost in the display) stored for a given key value prevails.\n', + 'dynamic-features': u'\nInteraction with dynamic features\n*********************************\n\nThere are several cases where Python statements are illegal when used\nin conjunction with nested scopes that contain free variables.\n\nIf a variable is referenced in an enclosing scope, it is illegal to\ndelete the name. An error will be reported at compile time.\n\nIf the wild card form of import --- "import *" --- is used in a\nfunction and the function contains or is a nested block with free\nvariables, the compiler will raise a "SyntaxError".\n\nThe "eval()" and "exec()" functions do not have access to the full\nenvironment for resolving names. Names may be resolved in the local\nand global namespaces of the caller. Free variables are not resolved\nin the nearest enclosing namespace, but in the global namespace. [1]\nThe "exec()" and "eval()" functions have optional arguments to\noverride the global and local namespace. If only one namespace is\nspecified, it is used for both.\n', + 'else': u'\nThe "if" statement\n******************\n\nThe "if" statement is used for conditional execution:\n\n if_stmt ::= "if" expression ":" suite\n ( "elif" expression ":" suite )*\n ["else" ":" suite]\n\nIt selects exactly one of the suites by evaluating the expressions one\nby one until one is found to be true (see section *Boolean operations*\nfor the definition of true and false); then that suite is executed\n(and no other part of the "if" statement is executed or evaluated).\nIf all expressions are false, the suite of the "else" clause, if\npresent, is executed.\n', + 'exceptions': u'\nExceptions\n**********\n\nExceptions are a means of breaking out of the normal flow of control\nof a code block in order to handle errors or other exceptional\nconditions. An exception is *raised* at the point where the error is\ndetected; it may be *handled* by the surrounding code block or by any\ncode block that directly or indirectly invoked the code block where\nthe error occurred.\n\nThe Python interpreter raises an exception when it detects a run-time\nerror (such as division by zero). A Python program can also\nexplicitly raise an exception with the "raise" statement. Exception\nhandlers are specified with the "try" ... "except" statement. The\n"finally" clause of such a statement can be used to specify cleanup\ncode which does not handle the exception, but is executed whether an\nexception occurred or not in the preceding code.\n\nPython uses the "termination" model of error handling: an exception\nhandler can find out what happened and continue execution at an outer\nlevel, but it cannot repair the cause of the error and retry the\nfailing operation (except by re-entering the offending piece of code\nfrom the top).\n\nWhen an exception is not handled at all, the interpreter terminates\nexecution of the program, or returns to its interactive main loop. In\neither case, it prints a stack backtrace, except when the exception is\n"SystemExit".\n\nExceptions are identified by class instances. The "except" clause is\nselected depending on the class of the instance: it must reference the\nclass of the instance or a base class thereof. The instance can be\nreceived by the handler and can carry additional information about the\nexceptional condition.\n\nNote: Exception messages are not part of the Python API. Their\n contents may change from one version of Python to the next without\n warning and should not be relied on by code which will run under\n multiple versions of the interpreter.\n\nSee also the description of the "try" statement in section *The try\nstatement* and "raise" statement in section *The raise statement*.\n\n-[ Footnotes ]-\n\n[1] This limitation occurs because the code that is executed by\n these operations is not available at the time the module is\n compiled.\n', + 'execmodel': u'\nExecution model\n***************\n\n\nNaming and binding\n==================\n\n*Names* refer to objects. Names are introduced by name binding\noperations. Each occurrence of a name in the program text refers to\nthe *binding* of that name established in the innermost function block\ncontaining the use.\n\nA *block* is a piece of Python program text that is executed as a\nunit. The following are blocks: a module, a function body, and a class\ndefinition. Each command typed interactively is a block. A script\nfile (a file given as standard input to the interpreter or specified\nas a command line argument to the interpreter) is a code block. A\nscript command (a command specified on the interpreter command line\nwith the \'**-c**\' option) is a code block. The string argument passed\nto the built-in functions "eval()" and "exec()" is a code block.\n\nA code block is executed in an *execution frame*. A frame contains\nsome administrative information (used for debugging) and determines\nwhere and how execution continues after the code block\'s execution has\ncompleted.\n\nA *scope* defines the visibility of a name within a block. If a local\nvariable is defined in a block, its scope includes that block. If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name. The scope of names defined in a\nclass block is limited to the class block; it does not extend to the\ncode blocks of methods -- this includes comprehensions and generator\nexpressions since they are implemented using a function scope. This\nmeans that the following will fail:\n\n class A:\n a = 42\n b = list(a + i for i in range(10))\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope. The set of all such scopes visible to a code block\nis called the block\'s *environment*.\n\nIf a name is bound in a block, it is a local variable of that block,\nunless declared as "nonlocal". If a name is bound at the module\nlevel, it is a global variable. (The variables of the module code\nblock are local and global.) If a variable is used in a code block\nbut not defined there, it is a *free variable*.\n\nWhen a name is not found at all, a "NameError" exception is raised.\nIf the name refers to a local variable that has not been bound, an\n"UnboundLocalError" exception is raised. "UnboundLocalError" is a\nsubclass of "NameError".\n\nThe following constructs bind names: formal parameters to functions,\n"import" statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, "for" loop header, or after\n"as" in a "with" statement or "except" clause. The "import" statement\nof the form "from ... import *" binds all names defined in the\nimported module, except those beginning with an underscore. This form\nmay only be used at the module level.\n\nA target occurring in a "del" statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name).\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block. This can lead to errors when a name is used within a\nblock before it is bound. This rule is subtle. Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block. The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the "global" statement occurs within a block, all uses of the name\nspecified in the statement refer to the binding of that name in the\ntop-level namespace. Names are resolved in the top-level namespace by\nsearching the global namespace, i.e. the namespace of the module\ncontaining the code block, and the builtins namespace, the namespace\nof the module "builtins". The global namespace is searched first. If\nthe name is not found there, the builtins namespace is searched. The\n"global" statement must precede all uses of the name.\n\nThe builtins namespace associated with the execution of a code block\nis actually found by looking up the name "__builtins__" in its global\nnamespace; this should be a dictionary or a module (in the latter case\nthe module\'s dictionary is used). By default, when in the "__main__"\nmodule, "__builtins__" is the built-in module "builtins"; when in any\nother module, "__builtins__" is an alias for the dictionary of the\n"builtins" module itself. "__builtins__" can be set to a user-created\ndictionary to create a weak form of restricted execution.\n\n**CPython implementation detail:** Users should not touch\n"__builtins__"; it is strictly an implementation detail. Users\nwanting to override values in the builtins namespace should "import"\nthe "builtins" module and modify its attributes appropriately.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported. The main module for a script is always called\n"__main__".\n\nThe "global" statement has the same scope as a name binding operation\nin the same block. If the nearest enclosing scope for a free variable\ncontains a global statement, the free variable is treated as a global.\n\nA class definition is an executable statement that may use and define\nnames. These references follow the normal rules for name resolution.\nThe namespace of the class definition becomes the attribute dictionary\nof the class. Names defined at the class scope are not visible in\nmethods.\n\n\nInteraction with dynamic features\n---------------------------------\n\nThere are several cases where Python statements are illegal when used\nin conjunction with nested scopes that contain free variables.\n\nIf a variable is referenced in an enclosing scope, it is illegal to\ndelete the name. An error will be reported at compile time.\n\nIf the wild card form of import --- "import *" --- is used in a\nfunction and the function contains or is a nested block with free\nvariables, the compiler will raise a "SyntaxError".\n\nThe "eval()" and "exec()" functions do not have access to the full\nenvironment for resolving names. Names may be resolved in the local\nand global namespaces of the caller. Free variables are not resolved\nin the nearest enclosing namespace, but in the global namespace. [1]\nThe "exec()" and "eval()" functions have optional arguments to\noverride the global and local namespace. If only one namespace is\nspecified, it is used for both.\n\n\nExceptions\n==========\n\nExceptions are a means of breaking out of the normal flow of control\nof a code block in order to handle errors or other exceptional\nconditions. An exception is *raised* at the point where the error is\ndetected; it may be *handled* by the surrounding code block or by any\ncode block that directly or indirectly invoked the code block where\nthe error occurred.\n\nThe Python interpreter raises an exception when it detects a run-time\nerror (such as division by zero). A Python program can also\nexplicitly raise an exception with the "raise" statement. Exception\nhandlers are specified with the "try" ... "except" statement. The\n"finally" clause of such a statement can be used to specify cleanup\ncode which does not handle the exception, but is executed whether an\nexception occurred or not in the preceding code.\n\nPython uses the "termination" model of error handling: an exception\nhandler can find out what happened and continue execution at an outer\nlevel, but it cannot repair the cause of the error and retry the\nfailing operation (except by re-entering the offending piece of code\nfrom the top).\n\nWhen an exception is not handled at all, the interpreter terminates\nexecution of the program, or returns to its interactive main loop. In\neither case, it prints a stack backtrace, except when the exception is\n"SystemExit".\n\nExceptions are identified by class instances. The "except" clause is\nselected depending on the class of the instance: it must reference the\nclass of the instance or a base class thereof. The instance can be\nreceived by the handler and can carry additional information about the\nexceptional condition.\n\nNote: Exception messages are not part of the Python API. Their\n contents may change from one version of Python to the next without\n warning and should not be relied on by code which will run under\n multiple versions of the interpreter.\n\nSee also the description of the "try" statement in section *The try\nstatement* and "raise" statement in section *The raise statement*.\n\n-[ Footnotes ]-\n\n[1] This limitation occurs because the code that is executed by\n these operations is not available at the time the module is\n compiled.\n', + 'exprlists': u'\nExpression lists\n****************\n\n expression_list ::= expression ( "," expression )* [","]\n\nAn expression list containing at least one comma yields a tuple. The\nlength of the tuple is the number of expressions in the list. The\nexpressions are evaluated from left to right.\n\nThe trailing comma is required only to create a single tuple (a.k.a. a\n*singleton*); it is optional in all other cases. A single expression\nwithout a trailing comma doesn\'t create a tuple, but rather yields the\nvalue of that expression. (To create an empty tuple, use an empty pair\nof parentheses: "()".)\n', + 'floating': u'\nFloating point literals\n***********************\n\nFloating point literals are described by the following lexical\ndefinitions:\n\n floatnumber ::= pointfloat | exponentfloat\n pointfloat ::= [intpart] fraction | intpart "."\n exponentfloat ::= (intpart | pointfloat) exponent\n intpart ::= digit+\n fraction ::= "." digit+\n exponent ::= ("e" | "E") ["+" | "-"] digit+\n\nNote that the integer and exponent parts are always interpreted using\nradix 10. For example, "077e010" is legal, and denotes the same number\nas "77e10". The allowed range of floating point literals is\nimplementation-dependent. Some examples of floating point literals:\n\n 3.14 10. .001 1e100 3.14e-10 0e0\n\nNote that numeric literals do not include a sign; a phrase like "-1"\nis actually an expression composed of the unary operator "-" and the\nliteral "1".\n', + 'for': u'\nThe "for" statement\n*******************\n\nThe "for" statement is used to iterate over the elements of a sequence\n(such as a string, tuple or list) or other iterable object:\n\n for_stmt ::= "for" target_list "in" expression_list ":" suite\n ["else" ":" suite]\n\nThe expression list is evaluated once; it should yield an iterable\nobject. An iterator is created for the result of the\n"expression_list". The suite is then executed once for each item\nprovided by the iterator, in the order returned by the iterator. Each\nitem in turn is assigned to the target list using the standard rules\nfor assignments (see *Assignment statements*), and then the suite is\nexecuted. When the items are exhausted (which is immediately when the\nsequence is empty or an iterator raises a "StopIteration" exception),\nthe suite in the "else" clause, if present, is executed, and the loop\nterminates.\n\nA "break" statement executed in the first suite terminates the loop\nwithout executing the "else" clause\'s suite. A "continue" statement\nexecuted in the first suite skips the rest of the suite and continues\nwith the next item, or with the "else" clause if there is no next\nitem.\n\nThe for-loop makes assignments to the variables(s) in the target list.\nThis overwrites all previous assignments to those variables including\nthose made in the suite of the for-loop:\n\n for i in range(10):\n print(i)\n i = 5 # this will not affect the for-loop\n # because i will be overwritten with the next\n # index in the range\n\nNames in the target list are not deleted when the loop is finished,\nbut if the sequence is empty, they will not have been assigned to at\nall by the loop. Hint: the built-in function "range()" returns an\niterator of integers suitable to emulate the effect of Pascal\'s "for i\n:= a to b do"; e.g., "list(range(3))" returns the list "[0, 1, 2]".\n\nNote: There is a subtlety when the sequence is being modified by the\n loop (this can only occur for mutable sequences, i.e. lists). An\n internal counter is used to keep track of which item is used next,\n and this is incremented on each iteration. When this counter has\n reached the length of the sequence the loop terminates. This means\n that if the suite deletes the current (or a previous) item from the\n sequence, the next item will be skipped (since it gets the index of\n the current item which has already been treated). Likewise, if the\n suite inserts an item in the sequence before the current item, the\n current item will be treated again the next time through the loop.\n This can lead to nasty bugs that can be avoided by making a\n temporary copy using a slice of the whole sequence, e.g.,\n\n for x in a[:]:\n if x < 0: a.remove(x)\n', + 'formatstrings': u'\nFormat String Syntax\n********************\n\nThe "str.format()" method and the "Formatter" class share the same\nsyntax for format strings (although in the case of "Formatter",\nsubclasses can define their own format string syntax).\n\nFormat strings contain "replacement fields" surrounded by curly braces\n"{}". Anything that is not contained in braces is considered literal\ntext, which is copied unchanged to the output. If you need to include\na brace character in the literal text, it can be escaped by doubling:\n"{{" and "}}".\n\nThe grammar for a replacement field is as follows:\n\n replacement_field ::= "{" [field_name] ["!" conversion] [":" format_spec] "}"\n field_name ::= arg_name ("." attribute_name | "[" element_index "]")*\n arg_name ::= [identifier | integer]\n attribute_name ::= identifier\n element_index ::= integer | index_string\n index_string ::= <any source character except "]"> +\n conversion ::= "r" | "s" | "a"\n format_spec ::= <described in the next section>\n\nIn less formal terms, the replacement field can start with a\n*field_name* that specifies the object whose value is to be formatted\nand inserted into the output instead of the replacement field. The\n*field_name* is optionally followed by a *conversion* field, which is\npreceded by an exclamation point "\'!\'", and a *format_spec*, which is\npreceded by a colon "\':\'". These specify a non-default format for the\nreplacement value.\n\nSee also the *Format Specification Mini-Language* section.\n\nThe *field_name* itself begins with an *arg_name* that is either a\nnumber or a keyword. If it\'s a number, it refers to a positional\nargument, and if it\'s a keyword, it refers to a named keyword\nargument. If the numerical arg_names in a format string are 0, 1, 2,\n... in sequence, they can all be omitted (not just some) and the\nnumbers 0, 1, 2, ... will be automatically inserted in that order.\nBecause *arg_name* is not quote-delimited, it is not possible to\nspecify arbitrary dictionary keys (e.g., the strings "\'10\'" or\n"\':-]\'") within a format string. The *arg_name* can be followed by any\nnumber of index or attribute expressions. An expression of the form\n"\'.name\'" selects the named attribute using "getattr()", while an\nexpression of the form "\'[index]\'" does an index lookup using\n"__getitem__()".\n\nChanged in version 3.1: The positional argument specifiers can be\nomitted, so "\'{} {}\'" is equivalent to "\'{0} {1}\'".\n\nSome simple format string examples:\n\n "First, thou shalt count to {0}" # References first positional argument\n "Bring me a {}" # Implicitly references the first positional argument\n "From {} to {}" # Same as "From {0} to {1}"\n "My quest is {name}" # References keyword argument \'name\'\n "Weight in tons {0.weight}" # \'weight\' attribute of first positional arg\n "Units destroyed: {players[0]}" # First element of keyword argument \'players\'.\n\nThe *conversion* field causes a type coercion before formatting.\nNormally, the job of formatting a value is done by the "__format__()"\nmethod of the value itself. However, in some cases it is desirable to\nforce a type to be formatted as a string, overriding its own\ndefinition of formatting. By converting the value to a string before\ncalling "__format__()", the normal formatting logic is bypassed.\n\nThree conversion flags are currently supported: "\'!s\'" which calls\n"str()" on the value, "\'!r\'" which calls "repr()" and "\'!a\'" which\ncalls "ascii()".\n\nSome examples:\n\n "Harold\'s a clever {0!s}" # Calls str() on the argument first\n "Bring out the holy {name!r}" # Calls repr() on the argument first\n "More {!a}" # Calls ascii() on the argument first\n\nThe *format_spec* field contains a specification of how the value\nshould be presented, including such details as field width, alignment,\npadding, decimal precision and so on. Each value type can define its\nown "formatting mini-language" or interpretation of the *format_spec*.\n\nMost built-in types support a common formatting mini-language, which\nis described in the next section.\n\nA *format_spec* field can also include nested replacement fields\nwithin it. These nested replacement fields can contain only a field\nname; conversion flags and format specifications are not allowed. The\nreplacement fields within the format_spec are substituted before the\n*format_spec* string is interpreted. This allows the formatting of a\nvalue to be dynamically specified.\n\nSee the *Format examples* section for some examples.\n\n\nFormat Specification Mini-Language\n==================================\n\n"Format specifications" are used within replacement fields contained\nwithin a format string to define how individual values are presented\n(see *Format String Syntax*). They can also be passed directly to the\nbuilt-in "format()" function. Each formattable type may define how\nthe format specification is to be interpreted.\n\nMost built-in types implement the following options for format\nspecifications, although some of the formatting options are only\nsupported by the numeric types.\n\nA general convention is that an empty format string ("""") produces\nthe same result as if you had called "str()" on the value. A non-empty\nformat string typically modifies the result.\n\nThe general form of a *standard format specifier* is:\n\n format_spec ::= [[fill]align][sign][#][0][width][,][.precision][type]\n fill ::= <any character>\n align ::= "<" | ">" | "=" | "^"\n sign ::= "+" | "-" | " "\n width ::= integer\n precision ::= integer\n type ::= "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"\n\nIf a valid *align* value is specified, it can be preceded by a *fill*\ncharacter that can be any character and defaults to a space if\nomitted. Note that it is not possible to use "{" and "}" as *fill*\nchar while using the "str.format()" method; this limitation however\ndoesn\'t affect the "format()" function.\n\nThe meaning of the various alignment options is as follows:\n\n +-----------+------------------------------------------------------------+\n | Option | Meaning |\n +===========+============================================================+\n | "\'<\'" | Forces the field to be left-aligned within the available |\n | | space (this is the default for most objects). |\n +-----------+------------------------------------------------------------+\n | "\'>\'" | Forces the field to be right-aligned within the available |\n | | space (this is the default for numbers). |\n +-----------+------------------------------------------------------------+\n | "\'=\'" | Forces the padding to be placed after the sign (if any) |\n | | but before the digits. This is used for printing fields |\n | | in the form \'+000000120\'. This alignment option is only |\n | | valid for numeric types. |\n +-----------+------------------------------------------------------------+\n | "\'^\'" | Forces the field to be centered within the available |\n | | space. |\n +-----------+------------------------------------------------------------+\n\nNote that unless a minimum field width is defined, the field width\nwill always be the same size as the data to fill it, so that the\nalignment option has no meaning in this case.\n\nThe *sign* option is only valid for number types, and can be one of\nthe following:\n\n +-----------+------------------------------------------------------------+\n | Option | Meaning |\n +===========+============================================================+\n | "\'+\'" | indicates that a sign should be used for both positive as |\n | | well as negative numbers. |\n +-----------+------------------------------------------------------------+\n | "\'-\'" | indicates that a sign should be used only for negative |\n | | numbers (this is the default behavior). |\n +-----------+------------------------------------------------------------+\n | space | indicates that a leading space should be used on positive |\n | | numbers, and a minus sign on negative numbers. |\n +-----------+------------------------------------------------------------+\n\nThe "\'#\'" option causes the "alternate form" to be used for the\nconversion. The alternate form is defined differently for different\ntypes. This option is only valid for integer, float, complex and\nDecimal types. For integers, when binary, octal, or hexadecimal output\nis used, this option adds the prefix respective "\'0b\'", "\'0o\'", or\n"\'0x\'" to the output value. For floats, complex and Decimal the\nalternate form causes the result of the conversion to always contain a\ndecimal-point character, even if no digits follow it. Normally, a\ndecimal-point character appears in the result of these conversions\nonly if a digit follows it. In addition, for "\'g\'" and "\'G\'"\nconversions, trailing zeros are not removed from the result.\n\nThe "\',\'" option signals the use of a comma for a thousands separator.\nFor a locale aware separator, use the "\'n\'" integer presentation type\ninstead.\n\nChanged in version 3.1: Added the "\',\'" option (see also **PEP 378**).\n\n*width* is a decimal integer defining the minimum field width. If not\nspecified, then the field width will be determined by the content.\n\nPreceding the *width* field by a zero ("\'0\'") character enables sign-\naware zero-padding for numeric types. This is equivalent to a *fill*\ncharacter of "\'0\'" with an *alignment* type of "\'=\'".\n\nThe *precision* is a decimal number indicating how many digits should\nbe displayed after the decimal point for a floating point value\nformatted with "\'f\'" and "\'F\'", or before and after the decimal point\nfor a floating point value formatted with "\'g\'" or "\'G\'". For non-\nnumber types the field indicates the maximum field size - in other\nwords, how many characters will be used from the field content. The\n*precision* is not allowed for integer values.\n\nFinally, the *type* determines how the data should be presented.\n\nThe available string presentation types are:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | "\'s\'" | String format. This is the default type for strings and |\n | | may be omitted. |\n +-----------+------------------------------------------------------------+\n | None | The same as "\'s\'". |\n +-----------+------------------------------------------------------------+\n\nThe available integer presentation types are:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | "\'b\'" | Binary format. Outputs the number in base 2. |\n +-----------+------------------------------------------------------------+\n | "\'c\'" | Character. Converts the integer to the corresponding |\n | | unicode character before printing. |\n +-----------+------------------------------------------------------------+\n | "\'d\'" | Decimal Integer. Outputs the number in base 10. |\n +-----------+------------------------------------------------------------+\n | "\'o\'" | Octal format. Outputs the number in base 8. |\n +-----------+------------------------------------------------------------+\n | "\'x\'" | Hex format. Outputs the number in base 16, using lower- |\n | | case letters for the digits above 9. |\n +-----------+------------------------------------------------------------+\n | "\'X\'" | Hex format. Outputs the number in base 16, using upper- |\n | | case letters for the digits above 9. |\n +-----------+------------------------------------------------------------+\n | "\'n\'" | Number. This is the same as "\'d\'", except that it uses the |\n | | current locale setting to insert the appropriate number |\n | | separator characters. |\n +-----------+------------------------------------------------------------+\n | None | The same as "\'d\'". |\n +-----------+------------------------------------------------------------+\n\nIn addition to the above presentation types, integers can be formatted\nwith the floating point presentation types listed below (except "\'n\'"\nand None). When doing so, "float()" is used to convert the integer to\na floating point number before formatting.\n\nThe available presentation types for floating point and decimal values\nare:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | "\'e\'" | Exponent notation. Prints the number in scientific |\n | | notation using the letter \'e\' to indicate the exponent. |\n | | The default precision is "6". |\n +-----------+------------------------------------------------------------+\n | "\'E\'" | Exponent notation. Same as "\'e\'" except it uses an upper |\n | | case \'E\' as the separator character. |\n +-----------+------------------------------------------------------------+\n | "\'f\'" | Fixed point. Displays the number as a fixed-point number. |\n | | The default precision is "6". |\n +-----------+------------------------------------------------------------+\n | "\'F\'" | Fixed point. Same as "\'f\'", but converts "nan" to "NAN" |\n | | and "inf" to "INF". |\n +-----------+------------------------------------------------------------+\n | "\'g\'" | General format. For a given precision "p >= 1", this |\n | | rounds the number to "p" significant digits and then |\n | | formats the result in either fixed-point format or in |\n | | scientific notation, depending on its magnitude. The |\n | | precise rules are as follows: suppose that the result |\n | | formatted with presentation type "\'e\'" and precision "p-1" |\n | | would have exponent "exp". Then if "-4 <= exp < p", the |\n | | number is formatted with presentation type "\'f\'" and |\n | | precision "p-1-exp". Otherwise, the number is formatted |\n | | with presentation type "\'e\'" and precision "p-1". In both |\n | | cases insignificant trailing zeros are removed from the |\n | | significand, and the decimal point is also removed if |\n | | there are no remaining digits following it. Positive and |\n | | negative infinity, positive and negative zero, and nans, |\n | | are formatted as "inf", "-inf", "0", "-0" and "nan" |\n | | respectively, regardless of the precision. A precision of |\n | | "0" is treated as equivalent to a precision of "1". The |\n | | default precision is "6". |\n +-----------+------------------------------------------------------------+\n | "\'G\'" | General format. Same as "\'g\'" except switches to "\'E\'" if |\n | | the number gets too large. The representations of infinity |\n | | and NaN are uppercased, too. |\n +-----------+------------------------------------------------------------+\n | "\'n\'" | Number. This is the same as "\'g\'", except that it uses the |\n | | current locale setting to insert the appropriate number |\n | | separator characters. |\n +-----------+------------------------------------------------------------+\n | "\'%\'" | Percentage. Multiplies the number by 100 and displays in |\n | | fixed ("\'f\'") format, followed by a percent sign. |\n +-----------+------------------------------------------------------------+\n | None | Similar to "\'g\'", except that fixed-point notation, when |\n | | used, has at least one digit past the decimal point. The |\n | | default precision is as high as needed to represent the |\n | | particular value. The overall effect is to match the |\n | | output of "str()" as altered by the other format |\n | | modifiers. |\n +-----------+------------------------------------------------------------+\n\n\nFormat examples\n===============\n\nThis section contains examples of the new format syntax and comparison\nwith the old "%"-formatting.\n\nIn most of the cases the syntax is similar to the old "%"-formatting,\nwith the addition of the "{}" and with ":" used instead of "%". For\nexample, "\'%03.2f\'" can be translated to "\'{:03.2f}\'".\n\nThe new format syntax also supports new and different options, shown\nin the follow examples.\n\nAccessing arguments by position:\n\n >>> \'{0}, {1}, {2}\'.format(\'a\', \'b\', \'c\')\n \'a, b, c\'\n >>> \'{}, {}, {}\'.format(\'a\', \'b\', \'c\') # 3.1+ only\n \'a, b, c\'\n >>> \'{2}, {1}, {0}\'.format(\'a\', \'b\', \'c\')\n \'c, b, a\'\n >>> \'{2}, {1}, {0}\'.format(*\'abc\') # unpacking argument sequence\n \'c, b, a\'\n >>> \'{0}{1}{0}\'.format(\'abra\', \'cad\') # arguments\' indices can be repeated\n \'abracadabra\'\n\nAccessing arguments by name:\n\n >>> \'Coordinates: {latitude}, {longitude}\'.format(latitude=\'37.24N\', longitude=\'-115.81W\')\n \'Coordinates: 37.24N, -115.81W\'\n >>> coord = {\'latitude\': \'37.24N\', \'longitude\': \'-115.81W\'}\n >>> \'Coordinates: {latitude}, {longitude}\'.format(**coord)\n \'Coordinates: 37.24N, -115.81W\'\n\nAccessing arguments\' attributes:\n\n >>> c = 3-5j\n >>> (\'The complex number {0} is formed from the real part {0.real} \'\n ... \'and the imaginary part {0.imag}.\').format(c)\n \'The complex number (3-5j) is formed from the real part 3.0 and the imaginary part -5.0.\'\n >>> class Point:\n ... def __init__(self, x, y):\n ... self.x, self.y = x, y\n ... def __str__(self):\n ... return \'Point({self.x}, {self.y})\'.format(self=self)\n ...\n >>> str(Point(4, 2))\n \'Point(4, 2)\'\n\nAccessing arguments\' items:\n\n >>> coord = (3, 5)\n >>> \'X: {0[0]}; Y: {0[1]}\'.format(coord)\n \'X: 3; Y: 5\'\n\nReplacing "%s" and "%r":\n\n >>> "repr() shows quotes: {!r}; str() doesn\'t: {!s}".format(\'test1\', \'test2\')\n "repr() shows quotes: \'test1\'; str() doesn\'t: test2"\n\nAligning the text and specifying a width:\n\n >>> \'{:<30}\'.format(\'left aligned\')\n \'left aligned \'\n >>> \'{:>30}\'.format(\'right aligned\')\n \' right aligned\'\n >>> \'{:^30}\'.format(\'centered\')\n \' centered \'\n >>> \'{:*^30}\'.format(\'centered\') # use \'*\' as a fill char\n \'***********centered***********\'\n\nReplacing "%+f", "%-f", and "% f" and specifying a sign:\n\n >>> \'{:+f}; {:+f}\'.format(3.14, -3.14) # show it always\n \'+3.140000; -3.140000\'\n >>> \'{: f}; {: f}\'.format(3.14, -3.14) # show a space for positive numbers\n \' 3.140000; -3.140000\'\n >>> \'{:-f}; {:-f}\'.format(3.14, -3.14) # show only the minus -- same as \'{:f}; {:f}\'\n \'3.140000; -3.140000\'\n\nReplacing "%x" and "%o" and converting the value to different bases:\n\n >>> # format also supports binary numbers\n >>> "int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}".format(42)\n \'int: 42; hex: 2a; oct: 52; bin: 101010\'\n >>> # with 0x, 0o, or 0b as prefix:\n >>> "int: {0:d}; hex: {0:#x}; oct: {0:#o}; bin: {0:#b}".format(42)\n \'int: 42; hex: 0x2a; oct: 0o52; bin: 0b101010\'\n\nUsing the comma as a thousands separator:\n\n >>> \'{:,}\'.format(1234567890)\n \'1,234,567,890\'\n\nExpressing a percentage:\n\n >>> points = 19\n >>> total = 22\n >>> \'Correct answers: {:.2%}\'.format(points/total)\n \'Correct answers: 86.36%\'\n\nUsing type-specific formatting:\n\n >>> import datetime\n >>> d = datetime.datetime(2010, 7, 4, 12, 15, 58)\n >>> \'{:%Y-%m-%d %H:%M:%S}\'.format(d)\n \'2010-07-04 12:15:58\'\n\nNesting arguments and more complex examples:\n\n >>> for align, text in zip(\'<^>\', [\'left\', \'center\', \'right\']):\n ... \'{0:{fill}{align}16}\'.format(text, fill=align, align=align)\n ...\n \'left<<<<<<<<<<<<\'\n \'^^^^^center^^^^^\'\n \'>>>>>>>>>>>right\'\n >>>\n >>> octets = [192, 168, 0, 1]\n >>> \'{:02X}{:02X}{:02X}{:02X}\'.format(*octets)\n \'C0A80001\'\n >>> int(_, 16)\n 3232235521\n >>>\n >>> width = 5\n >>> for num in range(5,12): #doctest: +NORMALIZE_WHITESPACE\n ... for base in \'dXob\':\n ... print(\'{0:{width}{base}}\'.format(num, base=base, width=width), end=\' \')\n ... print()\n ...\n 5 5 5 101\n 6 6 6 110\n 7 7 7 111\n 8 8 10 1000\n 9 9 11 1001\n 10 A 12 1010\n 11 B 13 1011\n', + 'function': u'\nFunction definitions\n********************\n\nA function definition defines a user-defined function object (see\nsection *The standard type hierarchy*):\n\n funcdef ::= [decorators] "def" funcname "(" [parameter_list] ")" ["->" expression] ":" suite\n decorators ::= decorator+\n decorator ::= "@" dotted_name ["(" [parameter_list [","]] ")"] NEWLINE\n dotted_name ::= identifier ("." identifier)*\n parameter_list ::= (defparameter ",")*\n | "*" [parameter] ("," defparameter)* ["," "**" parameter]\n | "**" parameter\n | defparameter [","] )\n parameter ::= identifier [":" expression]\n defparameter ::= parameter ["=" expression]\n funcname ::= identifier\n\nA function definition is an executable statement. Its execution binds\nthe function name in the current local namespace to a function object\n(a wrapper around the executable code for the function). This\nfunction object contains a reference to the current global namespace\nas the global namespace to be used when the function is called.\n\nThe function definition does not execute the function body; this gets\nexecuted only when the function is called. [3]\n\nA function definition may be wrapped by one or more *decorator*\nexpressions. Decorator expressions are evaluated when the function is\ndefined, in the scope that contains the function definition. The\nresult must be a callable, which is invoked with the function object\nas the only argument. The returned value is bound to the function name\ninstead of the function object. Multiple decorators are applied in\nnested fashion. For example, the following code\n\n @f1(arg)\n @f2\n def func(): pass\n\nis equivalent to\n\n def func(): pass\n func = f1(arg)(f2(func))\n\nWhen one or more *parameters* have the form *parameter* "="\n*expression*, the function is said to have "default parameter values."\nFor a parameter with a default value, the corresponding *argument* may\nbe omitted from a call, in which case the parameter\'s default value is\nsubstituted. If a parameter has a default value, all following\nparameters up until the ""*"" must also have a default value --- this\nis a syntactic restriction that is not expressed by the grammar.\n\n**Default parameter values are evaluated from left to right when the\nfunction definition is executed.** This means that the expression is\nevaluated once, when the function is defined, and that the same "pre-\ncomputed" value is used for each call. This is especially important\nto understand when a default parameter is a mutable object, such as a\nlist or a dictionary: if the function modifies the object (e.g. by\nappending an item to a list), the default value is in effect modified.\nThis is generally not what was intended. A way around this is to use\n"None" as the default, and explicitly test for it in the body of the\nfunction, e.g.:\n\n def whats_on_the_telly(penguin=None):\n if penguin is None:\n penguin = []\n penguin.append("property of the zoo")\n return penguin\n\nFunction call semantics are described in more detail in section\n*Calls*. A function call always assigns values to all parameters\nmentioned in the parameter list, either from position arguments, from\nkeyword arguments, or from default values. If the form\n""*identifier"" is present, it is initialized to a tuple receiving any\nexcess positional parameters, defaulting to the empty tuple. If the\nform ""**identifier"" is present, it is initialized to a new\ndictionary receiving any excess keyword arguments, defaulting to a new\nempty dictionary. Parameters after ""*"" or ""*identifier"" are\nkeyword-only parameters and may only be passed used keyword arguments.\n\nParameters may have annotations of the form "": expression"" following\nthe parameter name. Any parameter may have an annotation even those\nof the form "*identifier" or "**identifier". Functions may have\n"return" annotation of the form ""-> expression"" after the parameter\nlist. These annotations can be any valid Python expression and are\nevaluated when the function definition is executed. Annotations may\nbe evaluated in a different order than they appear in the source code.\nThe presence of annotations does not change the semantics of a\nfunction. The annotation values are available as values of a\ndictionary keyed by the parameters\' names in the "__annotations__"\nattribute of the function object.\n\nIt is also possible to create anonymous functions (functions not bound\nto a name), for immediate use in expressions. This uses lambda\nexpressions, described in section *Lambdas*. Note that the lambda\nexpression is merely a shorthand for a simplified function definition;\na function defined in a ""def"" statement can be passed around or\nassigned to another name just like a function defined by a lambda\nexpression. The ""def"" form is actually more powerful since it\nallows the execution of multiple statements and annotations.\n\n**Programmer\'s note:** Functions are first-class objects. A ""def""\nstatement executed inside a function definition defines a local\nfunction that can be returned or passed around. Free variables used\nin the nested function can access the local variables of the function\ncontaining the def. See section *Naming and binding* for details.\n\nSee also: **PEP 3107** - Function Annotations\n\n The original specification for function annotations.\n', + 'global': u'\nThe "global" statement\n**********************\n\n global_stmt ::= "global" identifier ("," identifier)*\n\nThe "global" statement is a declaration which holds for the entire\ncurrent code block. It means that the listed identifiers are to be\ninterpreted as globals. It would be impossible to assign to a global\nvariable without "global", although free variables may refer to\nglobals without being declared global.\n\nNames listed in a "global" statement must not be used in the same code\nblock textually preceding that "global" statement.\n\nNames listed in a "global" statement must not be defined as formal\nparameters or in a "for" loop control target, "class" definition,\nfunction definition, or "import" statement.\n\n**CPython implementation detail:** The current implementation does not\nenforce the two restrictions, but programs should not abuse this\nfreedom, as future implementations may enforce them or silently change\nthe meaning of the program.\n\n**Programmer\'s note:** the "global" is a directive to the parser. It\napplies only to code parsed at the same time as the "global"\nstatement. In particular, a "global" statement contained in a string\nor code object supplied to the built-in "exec()" function does not\naffect the code block *containing* the function call, and code\ncontained in such a string is unaffected by "global" statements in the\ncode containing the function call. The same applies to the "eval()"\nand "compile()" functions.\n', + 'id-classes': u'\nReserved classes of identifiers\n*******************************\n\nCertain classes of identifiers (besides keywords) have special\nmeanings. These classes are identified by the patterns of leading and\ntrailing underscore characters:\n\n"_*"\n Not imported by "from module import *". The special identifier "_"\n is used in the interactive interpreter to store the result of the\n last evaluation; it is stored in the "builtins" module. When not\n in interactive mode, "_" has no special meaning and is not defined.\n See section *The import statement*.\n\n Note: The name "_" is often used in conjunction with\n internationalization; refer to the documentation for the\n "gettext" module for more information on this convention.\n\n"__*__"\n System-defined names. These names are defined by the interpreter\n and its implementation (including the standard library). Current\n system names are discussed in the *Special method names* section\n and elsewhere. More will likely be defined in future versions of\n Python. *Any* use of "__*__" names, in any context, that does not\n follow explicitly documented use, is subject to breakage without\n warning.\n\n"__*"\n Class-private names. Names in this category, when used within the\n context of a class definition, are re-written to use a mangled form\n to help avoid name clashes between "private" attributes of base and\n derived classes. See section *Identifiers (Names)*.\n', + 'identifiers': u'\nIdentifiers and keywords\n************************\n\nIdentifiers (also referred to as *names*) are described by the\nfollowing lexical definitions.\n\nThe syntax of identifiers in Python is based on the Unicode standard\nannex UAX-31, with elaboration and changes as defined below; see also\n**PEP 3131** for further details.\n\nWithin the ASCII range (U+0001..U+007F), the valid characters for\nidentifiers are the same as in Python 2.x: the uppercase and lowercase\nletters "A" through "Z", the underscore "_" and, except for the first\ncharacter, the digits "0" through "9".\n\nPython 3.0 introduces additional characters from outside the ASCII\nrange (see **PEP 3131**). For these characters, the classification\nuses the version of the Unicode Character Database as included in the\n"unicodedata" module.\n\nIdentifiers are unlimited in length. Case is significant.\n\n identifier ::= xid_start xid_continue*\n id_start ::= <all characters in general categories Lu, Ll, Lt, Lm, Lo, Nl, the underscore, and characters with the Other_ID_Start property>\n id_continue ::= <all characters in id_start, plus characters in the categories Mn, Mc, Nd, Pc and others with the Other_ID_Continue property>\n xid_start ::= <all characters in id_start whose NFKC normalization is in "id_start xid_continue*">\n xid_continue ::= <all characters in id_continue whose NFKC normalization is in "id_continue*">\n\nThe Unicode category codes mentioned above stand for:\n\n* *Lu* - uppercase letters\n\n* *Ll* - lowercase letters\n\n* *Lt* - titlecase letters\n\n* *Lm* - modifier letters\n\n* *Lo* - other letters\n\n* *Nl* - letter numbers\n\n* *Mn* - nonspacing marks\n\n* *Mc* - spacing combining marks\n\n* *Nd* - decimal numbers\n\n* *Pc* - connector punctuations\n\n* *Other_ID_Start* - explicit list of characters in PropList.txt to\n support backwards compatibility\n\n* *Other_ID_Continue* - likewise\n\nAll identifiers are converted into the normal form NFKC while parsing;\ncomparison of identifiers is based on NFKC.\n\nA non-normative HTML file listing all valid identifier characters for\nUnicode 4.1 can be found at http://www.dcl.hpi.uni-\npotsdam.de/home/loewis/table-3131.html.\n\n\nKeywords\n========\n\nThe following identifiers are used as reserved words, or *keywords* of\nthe language, and cannot be used as ordinary identifiers. They must\nbe spelled exactly as written here:\n\n False class finally is return\n None continue for lambda try\n True def from nonlocal while\n and del global not with\n as elif if or yield\n assert else import pass\n break except in raise\n\n\nReserved classes of identifiers\n===============================\n\nCertain classes of identifiers (besides keywords) have special\nmeanings. These classes are identified by the patterns of leading and\ntrailing underscore characters:\n\n"_*"\n Not imported by "from module import *". The special identifier "_"\n is used in the interactive interpreter to store the result of the\n last evaluation; it is stored in the "builtins" module. When not\n in interactive mode, "_" has no special meaning and is not defined.\n See section *The import statement*.\n\n Note: The name "_" is often used in conjunction with\n internationalization; refer to the documentation for the\n "gettext" module for more information on this convention.\n\n"__*__"\n System-defined names. These names are defined by the interpreter\n and its implementation (including the standard library). Current\n system names are discussed in the *Special method names* section\n and elsewhere. More will likely be defined in future versions of\n Python. *Any* use of "__*__" names, in any context, that does not\n follow explicitly documented use, is subject to breakage without\n warning.\n\n"__*"\n Class-private names. Names in this category, when used within the\n context of a class definition, are re-written to use a mangled form\n to help avoid name clashes between "private" attributes of base and\n derived classes. See section *Identifiers (Names)*.\n', + 'if': u'\nThe "if" statement\n******************\n\nThe "if" statement is used for conditional execution:\n\n if_stmt ::= "if" expression ":" suite\n ( "elif" expression ":" suite )*\n ["else" ":" suite]\n\nIt selects exactly one of the suites by evaluating the expressions one\nby one until one is found to be true (see section *Boolean operations*\nfor the definition of true and false); then that suite is executed\n(and no other part of the "if" statement is executed or evaluated).\nIf all expressions are false, the suite of the "else" clause, if\npresent, is executed.\n', + 'imaginary': u'\nImaginary literals\n******************\n\nImaginary literals are described by the following lexical definitions:\n\n imagnumber ::= (floatnumber | intpart) ("j" | "J")\n\nAn imaginary literal yields a complex number with a real part of 0.0.\nComplex numbers are represented as a pair of floating point numbers\nand have the same restrictions on their range. To create a complex\nnumber with a nonzero real part, add a floating point number to it,\ne.g., "(3+4j)". Some examples of imaginary literals:\n\n 3.14j 10.j 10j .001j 1e100j 3.14e-10j\n', + 'import': u'\nThe "import" statement\n**********************\n\n import_stmt ::= "import" module ["as" name] ( "," module ["as" name] )*\n | "from" relative_module "import" identifier ["as" name]\n ( "," identifier ["as" name] )*\n | "from" relative_module "import" "(" identifier ["as" name]\n ( "," identifier ["as" name] )* [","] ")"\n | "from" module "import" "*"\n module ::= (identifier ".")* identifier\n relative_module ::= "."* module | "."+\n name ::= identifier\n\nThe basic import statement (no "from" clause) is executed in two\nsteps:\n\n1. find a module, loading and initializing it if necessary\n\n2. define a name or names in the local namespace for the scope\n where the "import" statement occurs.\n\nWhen the statement contains multiple clauses (separated by commas) the\ntwo steps are carried out separately for each clause, just as though\nthe clauses had been separated out into individiual import statements.\n\nThe details of the first step, finding and loading modules are\ndescribed in greater detail in the section on the *import system*,\nwhich also describes the various types of packages and modules that\ncan be imported, as well as all the hooks that can be used to\ncustomize the import system. Note that failures in this step may\nindicate either that the module could not be located, *or* that an\nerror occurred while initializing the module, which includes execution\nof the module\'s code.\n\nIf the requested module is retrieved successfully, it will be made\navailable in the local namespace in one of three ways:\n\n* If the module name is followed by "as", then the name following\n "as" is bound directly to the imported module.\n\n* If no other name is specified, and the module being imported is a\n top level module, the module\'s name is bound in the local namespace\n as a reference to the imported module\n\n* If the module being imported is *not* a top level module, then the\n name of the top level package that contains the module is bound in\n the local namespace as a reference to the top level package. The\n imported module must be accessed using its full qualified name\n rather than directly\n\nThe "from" form uses a slightly more complex process:\n\n1. find the module specified in the "from" clause, loading and\n initializing it if necessary;\n\n2. for each of the identifiers specified in the "import" clauses:\n\n 1. check if the imported module has an attribute by that name\n\n 2. if not, attempt to import a submodule with that name and then\n check the imported module again for that attribute\n\n 3. if the attribute is not found, "ImportError" is raised.\n\n 4. otherwise, a reference to that value is stored in the local\n namespace, using the name in the "as" clause if it is present,\n otherwise using the attribute name\n\nExamples:\n\n import foo # foo imported and bound locally\n import foo.bar.baz # foo.bar.baz imported, foo bound locally\n import foo.bar.baz as fbb # foo.bar.baz imported and bound as fbb\n from foo.bar import baz # foo.bar.baz imported and bound as baz\n from foo import attr # foo imported and foo.attr bound as attr\n\nIf the list of identifiers is replaced by a star ("\'*\'"), all public\nnames defined in the module are bound in the local namespace for the\nscope where the "import" statement occurs.\n\nThe *public names* defined by a module are determined by checking the\nmodule\'s namespace for a variable named "__all__"; if defined, it must\nbe a sequence of strings which are names defined or imported by that\nmodule. The names given in "__all__" are all considered public and\nare required to exist. If "__all__" is not defined, the set of public\nnames includes all names found in the module\'s namespace which do not\nbegin with an underscore character ("\'_\'"). "__all__" should contain\nthe entire public API. It is intended to avoid accidentally exporting\nitems that are not part of the API (such as library modules which were\nimported and used within the module).\n\nThe wild card form of import --- "from module import *" --- is only\nallowed at the module level. Attempting to use it in class or\nfunction definitions will raise a "SyntaxError".\n\nWhen specifying what module to import you do not have to specify the\nabsolute name of the module. When a module or package is contained\nwithin another package it is possible to make a relative import within\nthe same top package without having to mention the package name. By\nusing leading dots in the specified module or package after "from" you\ncan specify how high to traverse up the current package hierarchy\nwithout specifying exact names. One leading dot means the current\npackage where the module making the import exists. Two dots means up\none package level. Three dots is up two levels, etc. So if you execute\n"from . import mod" from a module in the "pkg" package then you will\nend up importing "pkg.mod". If you execute "from ..subpkg2 import mod"\nfrom within "pkg.subpkg1" you will import "pkg.subpkg2.mod". The\nspecification for relative imports is contained within **PEP 328**.\n\n"importlib.import_module()" is provided to support applications that\ndetermine dynamically the modules to be loaded.\n\n\nFuture statements\n=================\n\nA *future statement* is a directive to the compiler that a particular\nmodule should be compiled using syntax or semantics that will be\navailable in a specified future release of Python where the feature\nbecomes standard.\n\nThe future statement is intended to ease migration to future versions\nof Python that introduce incompatible changes to the language. It\nallows use of the new features on a per-module basis before the\nrelease in which the feature becomes standard.\n\n future_statement ::= "from" "__future__" "import" feature ["as" name]\n ("," feature ["as" name])*\n | "from" "__future__" "import" "(" feature ["as" name]\n ("," feature ["as" name])* [","] ")"\n feature ::= identifier\n name ::= identifier\n\nA future statement must appear near the top of the module. The only\nlines that can appear before a future statement are:\n\n* the module docstring (if any),\n\n* comments,\n\n* blank lines, and\n\n* other future statements.\n\nThe features recognized by Python 3.0 are "absolute_import",\n"division", "generators", "unicode_literals", "print_function",\n"nested_scopes" and "with_statement". They are all redundant because\nthey are always enabled, and only kept for backwards compatibility.\n\nA future statement is recognized and treated specially at compile\ntime: Changes to the semantics of core constructs are often\nimplemented by generating different code. It may even be the case\nthat a new feature introduces new incompatible syntax (such as a new\nreserved word), in which case the compiler may need to parse the\nmodule differently. Such decisions cannot be pushed off until\nruntime.\n\nFor any given release, the compiler knows which feature names have\nbeen defined, and raises a compile-time error if a future statement\ncontains a feature not known to it.\n\nThe direct runtime semantics are the same as for any import statement:\nthere is a standard module "__future__", described later, and it will\nbe imported in the usual way at the time the future statement is\nexecuted.\n\nThe interesting runtime semantics depend on the specific feature\nenabled by the future statement.\n\nNote that there is nothing special about the statement:\n\n import __future__ [as name]\n\nThat is not a future statement; it\'s an ordinary import statement with\nno special semantics or syntax restrictions.\n\nCode compiled by calls to the built-in functions "exec()" and\n"compile()" that occur in a module "M" containing a future statement\nwill, by default, use the new syntax or semantics associated with the\nfuture statement. This can be controlled by optional arguments to\n"compile()" --- see the documentation of that function for details.\n\nA future statement typed at an interactive interpreter prompt will\ntake effect for the rest of the interpreter session. If an\ninterpreter is started with the *-i* option, is passed a script name\nto execute, and the script includes a future statement, it will be in\neffect in the interactive session started after the script is\nexecuted.\n\nSee also: **PEP 236** - Back to the __future__\n\n The original proposal for the __future__ mechanism.\n', + 'in': u'\nComparisons\n***********\n\nUnlike C, all comparison operations in Python have the same priority,\nwhich is lower than that of any arithmetic, shifting or bitwise\noperation. Also unlike C, expressions like "a < b < c" have the\ninterpretation that is conventional in mathematics:\n\n comparison ::= or_expr ( comp_operator or_expr )*\n comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "!="\n | "is" ["not"] | ["not"] "in"\n\nComparisons yield boolean values: "True" or "False".\n\nComparisons can be chained arbitrarily, e.g., "x < y <= z" is\nequivalent to "x < y and y <= z", except that "y" is evaluated only\nonce (but in both cases "z" is not evaluated at all when "x < y" is\nfound to be false).\n\nFormally, if *a*, *b*, *c*, ..., *y*, *z* are expressions and *op1*,\n*op2*, ..., *opN* are comparison operators, then "a op1 b op2 c ... y\nopN z" is equivalent to "a op1 b and b op2 c and ... y opN z", except\nthat each expression is evaluated at most once.\n\nNote that "a op1 b op2 c" doesn\'t imply any kind of comparison between\n*a* and *c*, so that, e.g., "x < y > z" is perfectly legal (though\nperhaps not pretty).\n\nThe operators "<", ">", "==", ">=", "<=", and "!=" compare the values\nof two objects. The objects need not have the same type. If both are\nnumbers, they are converted to a common type. Otherwise, the "==" and\n"!=" operators *always* consider objects of different types to be\nunequal, while the "<", ">", ">=" and "<=" operators raise a\n"TypeError" when comparing objects of different types that do not\nimplement these operators for the given pair of types. You can\ncontrol comparison behavior of objects of non-built-in types by\ndefining rich comparison methods like "__gt__()", described in section\n*Basic customization*.\n\nComparison of objects of the same type depends on the type:\n\n* Numbers are compared arithmetically.\n\n* The values "float(\'NaN\')" and "Decimal(\'NaN\')" are special. The\n are identical to themselves, "x is x" but are not equal to\n themselves, "x != x". Additionally, comparing any value to a\n not-a-number value will return "False". For example, both "3 <\n float(\'NaN\')" and "float(\'NaN\') < 3" will return "False".\n\n* Bytes objects are compared lexicographically using the numeric\n values of their elements.\n\n* Strings are compared lexicographically using the numeric\n equivalents (the result of the built-in function "ord()") of their\n characters. [3] String and bytes object can\'t be compared!\n\n* Tuples and lists are compared lexicographically using comparison\n of corresponding elements. This means that to compare equal, each\n element must compare equal and the two sequences must be of the same\n type and have the same length.\n\n If not equal, the sequences are ordered the same as their first\n differing elements. For example, "[1,2,x] <= [1,2,y]" has the same\n value as "x <= y". If the corresponding element does not exist, the\n shorter sequence is ordered first (for example, "[1,2] < [1,2,3]").\n\n* Mappings (dictionaries) compare equal if and only if they have the\n same "(key, value)" pairs. Order comparisons "(\'<\', \'<=\', \'>=\',\n \'>\')" raise "TypeError".\n\n* Sets and frozensets define comparison operators to mean subset and\n superset tests. Those relations do not define total orderings (the\n two sets "{1,2}" and {2,3} are not equal, nor subsets of one\n another, nor supersets of one another). Accordingly, sets are not\n appropriate arguments for functions which depend on total ordering.\n For example, "min()", "max()", and "sorted()" produce undefined\n results given a list of sets as inputs.\n\n* Most other objects of built-in types compare unequal unless they\n are the same object; the choice whether one object is considered\n smaller or larger than another one is made arbitrarily but\n consistently within one execution of a program.\n\nComparison of objects of differing types depends on whether either of\nthe types provide explicit support for the comparison. Most numeric\ntypes can be compared with one another. When cross-type comparison is\nnot supported, the comparison method returns "NotImplemented".\n\nThe operators "in" and "not in" test for membership. "x in s"\nevaluates to true if *x* is a member of *s*, and false otherwise. "x\nnot in s" returns the negation of "x in s". All built-in sequences\nand set types support this as well as dictionary, for which "in" tests\nwhether the dictionary has a given key. For container types such as\nlist, tuple, set, frozenset, dict, or collections.deque, the\nexpression "x in y" is equivalent to "any(x is e or x == e for e in\ny)".\n\nFor the string and bytes types, "x in y" is true if and only if *x* is\na substring of *y*. An equivalent test is "y.find(x) != -1". Empty\nstrings are always considered to be a substring of any other string,\nso """ in "abc"" will return "True".\n\nFor user-defined classes which define the "__contains__()" method, "x\nin y" is true if and only if "y.__contains__(x)" is true.\n\nFor user-defined classes which do not define "__contains__()" but do\ndefine "__iter__()", "x in y" is true if some value "z" with "x == z"\nis produced while iterating over "y". If an exception is raised\nduring the iteration, it is as if "in" raised that exception.\n\nLastly, the old-style iteration protocol is tried: if a class defines\n"__getitem__()", "x in y" is true if and only if there is a non-\nnegative integer index *i* such that "x == y[i]", and all lower\ninteger indices do not raise "IndexError" exception. (If any other\nexception is raised, it is as if "in" raised that exception).\n\nThe operator "not in" is defined to have the inverse true value of\n"in".\n\nThe operators "is" and "is not" test for object identity: "x is y" is\ntrue if and only if *x* and *y* are the same object. "x is not y"\nyields the inverse truth value. [4]\n', + 'integers': u'\nInteger literals\n****************\n\nInteger literals are described by the following lexical definitions:\n\n integer ::= decimalinteger | octinteger | hexinteger | bininteger\n decimalinteger ::= nonzerodigit digit* | "0"+\n nonzerodigit ::= "1"..."9"\n digit ::= "0"..."9"\n octinteger ::= "0" ("o" | "O") octdigit+\n hexinteger ::= "0" ("x" | "X") hexdigit+\n bininteger ::= "0" ("b" | "B") bindigit+\n octdigit ::= "0"..."7"\n hexdigit ::= digit | "a"..."f" | "A"..."F"\n bindigit ::= "0" | "1"\n\nThere is no limit for the length of integer literals apart from what\ncan be stored in available memory.\n\nNote that leading zeros in a non-zero decimal number are not allowed.\nThis is for disambiguation with C-style octal literals, which Python\nused before version 3.0.\n\nSome examples of integer literals:\n\n 7 2147483647 0o177 0b100110111\n 3 79228162514264337593543950336 0o377 0x100000000\n 79228162514264337593543950336 0xdeadbeef\n', + 'lambda': u'\nLambdas\n*******\n\n lambda_expr ::= "lambda" [parameter_list]: expression\n lambda_expr_nocond ::= "lambda" [parameter_list]: expression_nocond\n\nLambda expressions (sometimes called lambda forms) are used to create\nanonymous functions. The expression "lambda arguments: expression"\nyields a function object. The unnamed object behaves like a function\nobject defined with\n\n def <lambda>(arguments):\n return expression\n\nSee section *Function definitions* for the syntax of parameter lists.\nNote that functions created with lambda expressions cannot contain\nstatements or annotations.\n', + 'lists': u'\nList displays\n*************\n\nA list display is a possibly empty series of expressions enclosed in\nsquare brackets:\n\n list_display ::= "[" [expression_list | comprehension] "]"\n\nA list display yields a new list object, the contents being specified\nby either a list of expressions or a comprehension. When a comma-\nseparated list of expressions is supplied, its elements are evaluated\nfrom left to right and placed into the list object in that order.\nWhen a comprehension is supplied, the list is constructed from the\nelements resulting from the comprehension.\n', + 'naming': u'\nNaming and binding\n******************\n\n*Names* refer to objects. Names are introduced by name binding\noperations. Each occurrence of a name in the program text refers to\nthe *binding* of that name established in the innermost function block\ncontaining the use.\n\nA *block* is a piece of Python program text that is executed as a\nunit. The following are blocks: a module, a function body, and a class\ndefinition. Each command typed interactively is a block. A script\nfile (a file given as standard input to the interpreter or specified\nas a command line argument to the interpreter) is a code block. A\nscript command (a command specified on the interpreter command line\nwith the \'**-c**\' option) is a code block. The string argument passed\nto the built-in functions "eval()" and "exec()" is a code block.\n\nA code block is executed in an *execution frame*. A frame contains\nsome administrative information (used for debugging) and determines\nwhere and how execution continues after the code block\'s execution has\ncompleted.\n\nA *scope* defines the visibility of a name within a block. If a local\nvariable is defined in a block, its scope includes that block. If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name. The scope of names defined in a\nclass block is limited to the class block; it does not extend to the\ncode blocks of methods -- this includes comprehensions and generator\nexpressions since they are implemented using a function scope. This\nmeans that the following will fail:\n\n class A:\n a = 42\n b = list(a + i for i in range(10))\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope. The set of all such scopes visible to a code block\nis called the block\'s *environment*.\n\nIf a name is bound in a block, it is a local variable of that block,\nunless declared as "nonlocal". If a name is bound at the module\nlevel, it is a global variable. (The variables of the module code\nblock are local and global.) If a variable is used in a code block\nbut not defined there, it is a *free variable*.\n\nWhen a name is not found at all, a "NameError" exception is raised.\nIf the name refers to a local variable that has not been bound, an\n"UnboundLocalError" exception is raised. "UnboundLocalError" is a\nsubclass of "NameError".\n\nThe following constructs bind names: formal parameters to functions,\n"import" statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, "for" loop header, or after\n"as" in a "with" statement or "except" clause. The "import" statement\nof the form "from ... import *" binds all names defined in the\nimported module, except those beginning with an underscore. This form\nmay only be used at the module level.\n\nA target occurring in a "del" statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name).\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block. This can lead to errors when a name is used within a\nblock before it is bound. This rule is subtle. Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block. The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the "global" statement occurs within a block, all uses of the name\nspecified in the statement refer to the binding of that name in the\ntop-level namespace. Names are resolved in the top-level namespace by\nsearching the global namespace, i.e. the namespace of the module\ncontaining the code block, and the builtins namespace, the namespace\nof the module "builtins". The global namespace is searched first. If\nthe name is not found there, the builtins namespace is searched. The\n"global" statement must precede all uses of the name.\n\nThe builtins namespace associated with the execution of a code block\nis actually found by looking up the name "__builtins__" in its global\nnamespace; this should be a dictionary or a module (in the latter case\nthe module\'s dictionary is used). By default, when in the "__main__"\nmodule, "__builtins__" is the built-in module "builtins"; when in any\nother module, "__builtins__" is an alias for the dictionary of the\n"builtins" module itself. "__builtins__" can be set to a user-created\ndictionary to create a weak form of restricted execution.\n\n**CPython implementation detail:** Users should not touch\n"__builtins__"; it is strictly an implementation detail. Users\nwanting to override values in the builtins namespace should "import"\nthe "builtins" module and modify its attributes appropriately.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported. The main module for a script is always called\n"__main__".\n\nThe "global" statement has the same scope as a name binding operation\nin the same block. If the nearest enclosing scope for a free variable\ncontains a global statement, the free variable is treated as a global.\n\nA class definition is an executable statement that may use and define\nnames. These references follow the normal rules for name resolution.\nThe namespace of the class definition becomes the attribute dictionary\nof the class. Names defined at the class scope are not visible in\nmethods.\n\n\nInteraction with dynamic features\n=================================\n\nThere are several cases where Python statements are illegal when used\nin conjunction with nested scopes that contain free variables.\n\nIf a variable is referenced in an enclosing scope, it is illegal to\ndelete the name. An error will be reported at compile time.\n\nIf the wild card form of import --- "import *" --- is used in a\nfunction and the function contains or is a nested block with free\nvariables, the compiler will raise a "SyntaxError".\n\nThe "eval()" and "exec()" functions do not have access to the full\nenvironment for resolving names. Names may be resolved in the local\nand global namespaces of the caller. Free variables are not resolved\nin the nearest enclosing namespace, but in the global namespace. [1]\nThe "exec()" and "eval()" functions have optional arguments to\noverride the global and local namespace. If only one namespace is\nspecified, it is used for both.\n', + 'nonlocal': u'\nThe "nonlocal" statement\n************************\n\n nonlocal_stmt ::= "nonlocal" identifier ("," identifier)*\n\nThe "nonlocal" statement causes the listed identifiers to refer to\npreviously bound variables in the nearest enclosing scope excluding\nglobals. This is important because the default behavior for binding is\nto search the local namespace first. The statement allows\nencapsulated code to rebind variables outside of the local scope\nbesides the global (module) scope.\n\nNames listed in a "nonlocal" statement, unlike those listed in a\n"global" statement, must refer to pre-existing bindings in an\nenclosing scope (the scope in which a new binding should be created\ncannot be determined unambiguously).\n\nNames listed in a "nonlocal" statement must not collide with pre-\nexisting bindings in the local scope.\n\nSee also: **PEP 3104** - Access to Names in Outer Scopes\n\n The specification for the "nonlocal" statement.\n', + 'numbers': u'\nNumeric literals\n****************\n\nThere are three types of numeric literals: integers, floating point\nnumbers, and imaginary numbers. There are no complex literals\n(complex numbers can be formed by adding a real number and an\nimaginary number).\n\nNote that numeric literals do not include a sign; a phrase like "-1"\nis actually an expression composed of the unary operator \'"-"\' and the\nliteral "1".\n', + 'numeric-types': u'\nEmulating numeric types\n***********************\n\nThe following methods can be defined to emulate numeric objects.\nMethods corresponding to operations that are not supported by the\nparticular kind of number implemented (e.g., bitwise operations for\nnon-integral numbers) should be left undefined.\n\nobject.__add__(self, other)\nobject.__sub__(self, other)\nobject.__mul__(self, other)\nobject.__matmul__(self, other)\nobject.__truediv__(self, other)\nobject.__floordiv__(self, other)\nobject.__mod__(self, other)\nobject.__divmod__(self, other)\nobject.__pow__(self, other[, modulo])\nobject.__lshift__(self, other)\nobject.__rshift__(self, other)\nobject.__and__(self, other)\nobject.__xor__(self, other)\nobject.__or__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations ("+", "-", "*", "@", "/", "//", "%", "divmod()",\n "pow()", "**", "<<", ">>", "&", "^", "|"). For instance, to\n evaluate the expression "x + y", where *x* is an instance of a\n class that has an "__add__()" method, "x.__add__(y)" is called.\n The "__divmod__()" method should be the equivalent to using\n "__floordiv__()" and "__mod__()"; it should not be related to\n "__truediv__()". Note that "__pow__()" should be defined to accept\n an optional third argument if the ternary version of the built-in\n "pow()" function is to be supported.\n\n If one of those methods does not support the operation with the\n supplied arguments, it should return "NotImplemented".\n\nobject.__radd__(self, other)\nobject.__rsub__(self, other)\nobject.__rmul__(self, other)\nobject.__rmatmul__(self, other)\nobject.__rtruediv__(self, other)\nobject.__rfloordiv__(self, other)\nobject.__rmod__(self, other)\nobject.__rdivmod__(self, other)\nobject.__rpow__(self, other)\nobject.__rlshift__(self, other)\nobject.__rrshift__(self, other)\nobject.__rand__(self, other)\nobject.__rxor__(self, other)\nobject.__ror__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations ("+", "-", "*", "@", "/", "//", "%", "divmod()",\n "pow()", "**", "<<", ">>", "&", "^", "|") with reflected (swapped)\n operands. These functions are only called if the left operand does\n not support the corresponding operation and the operands are of\n different types. [2] For instance, to evaluate the expression "x -\n y", where *y* is an instance of a class that has an "__rsub__()"\n method, "y.__rsub__(x)" is called if "x.__sub__(y)" returns\n *NotImplemented*.\n\n Note that ternary "pow()" will not try calling "__rpow__()" (the\n coercion rules would become too complicated).\n\n Note: If the right operand\'s type is a subclass of the left\n operand\'s type and that subclass provides the reflected method\n for the operation, this method will be called before the left\n operand\'s non-reflected method. This behavior allows subclasses\n to override their ancestors\' operations.\n\nobject.__iadd__(self, other)\nobject.__isub__(self, other)\nobject.__imul__(self, other)\nobject.__imatmul__(self, other)\nobject.__itruediv__(self, other)\nobject.__ifloordiv__(self, other)\nobject.__imod__(self, other)\nobject.__ipow__(self, other[, modulo])\nobject.__ilshift__(self, other)\nobject.__irshift__(self, other)\nobject.__iand__(self, other)\nobject.__ixor__(self, other)\nobject.__ior__(self, other)\n\n These methods are called to implement the augmented arithmetic\n assignments ("+=", "-=", "*=", "@=", "/=", "//=", "%=", "**=",\n "<<=", ">>=", "&=", "^=", "|="). These methods should attempt to\n do the operation in-place (modifying *self*) and return the result\n (which could be, but does not have to be, *self*). If a specific\n method is not defined, the augmented assignment falls back to the\n normal methods. For instance, if *x* is an instance of a class\n with an "__iadd__()" method, "x += y" is equivalent to "x =\n x.__iadd__(y)" . Otherwise, "x.__add__(y)" and "y.__radd__(x)" are\n considered, as with the evaluation of "x + y". In certain\n situations, augmented assignment can result in unexpected errors\n (see *Why does a_tuple[i] += [\'item\'] raise an exception when the\n addition works?*), but this behavior is in fact part of the data\n model.\n\nobject.__neg__(self)\nobject.__pos__(self)\nobject.__abs__(self)\nobject.__invert__(self)\n\n Called to implement the unary arithmetic operations ("-", "+",\n "abs()" and "~").\n\nobject.__complex__(self)\nobject.__int__(self)\nobject.__float__(self)\nobject.__round__(self[, n])\n\n Called to implement the built-in functions "complex()", "int()",\n "float()" and "round()". Should return a value of the appropriate\n type.\n\nobject.__index__(self)\n\n Called to implement "operator.index()", and whenever Python needs\n to losslessly convert the numeric object to an integer object (such\n as in slicing, or in the built-in "bin()", "hex()" and "oct()"\n functions). Presence of this method indicates that the numeric\n object is an integer type. Must return an integer.\n\n Note: In order to have a coherent integer type class, when\n "__index__()" is defined "__int__()" should also be defined, and\n both should return the same value.\n', + 'objects': u'\nObjects, values and types\n*************************\n\n*Objects* are Python\'s abstraction for data. All data in a Python\nprogram is represented by objects or by relations between objects. (In\na sense, and in conformance to Von Neumann\'s model of a "stored\nprogram computer," code is also represented by objects.)\n\nEvery object has an identity, a type and a value. An object\'s\n*identity* never changes once it has been created; you may think of it\nas the object\'s address in memory. The \'"is"\' operator compares the\nidentity of two objects; the "id()" function returns an integer\nrepresenting its identity.\n\n**CPython implementation detail:** For CPython, "id(x)" is the memory\naddress where "x" is stored.\n\nAn object\'s type determines the operations that the object supports\n(e.g., "does it have a length?") and also defines the possible values\nfor objects of that type. The "type()" function returns an object\'s\ntype (which is an object itself). Like its identity, an object\'s\n*type* is also unchangeable. [1]\n\nThe *value* of some objects can change. Objects whose value can\nchange are said to be *mutable*; objects whose value is unchangeable\nonce they are created are called *immutable*. (The value of an\nimmutable container object that contains a reference to a mutable\nobject can change when the latter\'s value is changed; however the\ncontainer is still considered immutable, because the collection of\nobjects it contains cannot be changed. So, immutability is not\nstrictly the same as having an unchangeable value, it is more subtle.)\nAn object\'s mutability is determined by its type; for instance,\nnumbers, strings and tuples are immutable, while dictionaries and\nlists are mutable.\n\nObjects are never explicitly destroyed; however, when they become\nunreachable they may be garbage-collected. An implementation is\nallowed to postpone garbage collection or omit it altogether --- it is\na matter of implementation quality how garbage collection is\nimplemented, as long as no objects are collected that are still\nreachable.\n\n**CPython implementation detail:** CPython currently uses a reference-\ncounting scheme with (optional) delayed detection of cyclically linked\ngarbage, which collects most objects as soon as they become\nunreachable, but is not guaranteed to collect garbage containing\ncircular references. See the documentation of the "gc" module for\ninformation on controlling the collection of cyclic garbage. Other\nimplementations act differently and CPython may change. Do not depend\non immediate finalization of objects when they become unreachable (so\nyou should always close files explicitly).\n\nNote that the use of the implementation\'s tracing or debugging\nfacilities may keep objects alive that would normally be collectable.\nAlso note that catching an exception with a \'"try"..."except"\'\nstatement may keep objects alive.\n\nSome objects contain references to "external" resources such as open\nfiles or windows. It is understood that these resources are freed\nwhen the object is garbage-collected, but since garbage collection is\nnot guaranteed to happen, such objects also provide an explicit way to\nrelease the external resource, usually a "close()" method. Programs\nare strongly recommended to explicitly close such objects. The\n\'"try"..."finally"\' statement and the \'"with"\' statement provide\nconvenient ways to do this.\n\nSome objects contain references to other objects; these are called\n*containers*. Examples of containers are tuples, lists and\ndictionaries. The references are part of a container\'s value. In\nmost cases, when we talk about the value of a container, we imply the\nvalues, not the identities of the contained objects; however, when we\ntalk about the mutability of a container, only the identities of the\nimmediately contained objects are implied. So, if an immutable\ncontainer (like a tuple) contains a reference to a mutable object, its\nvalue changes if that mutable object is changed.\n\nTypes affect almost all aspects of object behavior. Even the\nimportance of object identity is affected in some sense: for immutable\ntypes, operations that compute new values may actually return a\nreference to any existing object with the same type and value, while\nfor mutable objects this is not allowed. E.g., after "a = 1; b = 1",\n"a" and "b" may or may not refer to the same object with the value\none, depending on the implementation, but after "c = []; d = []", "c"\nand "d" are guaranteed to refer to two different, unique, newly\ncreated empty lists. (Note that "c = d = []" assigns the same object\nto both "c" and "d".)\n', + 'operator-summary': u'\nOperator precedence\n*******************\n\nThe following table summarizes the operator precedence in Python, from\nlowest precedence (least binding) to highest precedence (most\nbinding). Operators in the same box have the same precedence. Unless\nthe syntax is explicitly given, operators are binary. Operators in\nthe same box group left to right (except for exponentiation, which\ngroups from right to left).\n\nNote that comparisons, membership tests, and identity tests, all have\nthe same precedence and have a left-to-right chaining feature as\ndescribed in the *Comparisons* section.\n\n+-------------------------------------------------+---------------------------------------+\n| Operator | Description |\n+=================================================+=======================================+\n| "lambda" | Lambda expression |\n+-------------------------------------------------+---------------------------------------+\n| "if" -- "else" | Conditional expression |\n+-------------------------------------------------+---------------------------------------+\n| "or" | Boolean OR |\n+-------------------------------------------------+---------------------------------------+\n| "and" | Boolean AND |\n+-------------------------------------------------+---------------------------------------+\n| "not" "x" | Boolean NOT |\n+-------------------------------------------------+---------------------------------------+\n| "in", "not in", "is", "is not", "<", "<=", ">", | Comparisons, including membership |\n| ">=", "!=", "==" | tests and identity tests |\n+-------------------------------------------------+---------------------------------------+\n| "|" | Bitwise OR |\n+-------------------------------------------------+---------------------------------------+\n| "^" | Bitwise XOR |\n+-------------------------------------------------+---------------------------------------+\n| "&" | Bitwise AND |\n+-------------------------------------------------+---------------------------------------+\n| "<<", ">>" | Shifts |\n+-------------------------------------------------+---------------------------------------+\n| "+", "-" | Addition and subtraction |\n+-------------------------------------------------+---------------------------------------+\n| "*", "@", "/", "//", "%" | Multiplication, matrix multiplication |\n| | division, remainder [5] |\n+-------------------------------------------------+---------------------------------------+\n| "+x", "-x", "~x" | Positive, negative, bitwise NOT |\n+-------------------------------------------------+---------------------------------------+\n| "**" | Exponentiation [6] |\n+-------------------------------------------------+---------------------------------------+\n| "x[index]", "x[index:index]", | Subscription, slicing, call, |\n| "x(arguments...)", "x.attribute" | attribute reference |\n+-------------------------------------------------+---------------------------------------+\n| "(expressions...)", "[expressions...]", "{key: | Binding or tuple display, list |\n| value...}", "{expressions...}" | display, dictionary display, set |\n| | display |\n+-------------------------------------------------+---------------------------------------+\n\n-[ Footnotes ]-\n\n[1] While "abs(x%y) < abs(y)" is true mathematically, for floats\n it may not be true numerically due to roundoff. For example, and\n assuming a platform on which a Python float is an IEEE 754 double-\n precision number, in order that "-1e-100 % 1e100" have the same\n sign as "1e100", the computed result is "-1e-100 + 1e100", which\n is numerically exactly equal to "1e100". The function\n "math.fmod()" returns a result whose sign matches the sign of the\n first argument instead, and so returns "-1e-100" in this case.\n Which approach is more appropriate depends on the application.\n\n[2] If x is very close to an exact integer multiple of y, it\'s\n possible for "x//y" to be one larger than "(x-x%y)//y" due to\n rounding. In such cases, Python returns the latter result, in\n order to preserve that "divmod(x,y)[0] * y + x % y" be very close\n to "x".\n\n[3] While comparisons between strings make sense at the byte\n level, they may be counter-intuitive to users. For example, the\n strings ""\\u00C7"" and ""\\u0327\\u0043"" compare differently, even\n though they both represent the same unicode character (LATIN\n CAPITAL LETTER C WITH CEDILLA). To compare strings in a human\n recognizable way, compare using "unicodedata.normalize()".\n\n[4] Due to automatic garbage-collection, free lists, and the\n dynamic nature of descriptors, you may notice seemingly unusual\n behaviour in certain uses of the "is" operator, like those\n involving comparisons between instance methods, or constants.\n Check their documentation for more info.\n\n[5] The "%" operator is also used for string formatting; the same\n precedence applies.\n\n[6] The power operator "**" binds less tightly than an arithmetic\n or bitwise unary operator on its right, that is, "2**-1" is "0.5".\n', + 'pass': u'\nThe "pass" statement\n********************\n\n pass_stmt ::= "pass"\n\n"pass" is a null operation --- when it is executed, nothing happens.\nIt is useful as a placeholder when a statement is required\nsyntactically, but no code needs to be executed, for example:\n\n def f(arg): pass # a function that does nothing (yet)\n\n class C: pass # a class with no methods (yet)\n', + 'power': u'\nThe power operator\n******************\n\nThe power operator binds more tightly than unary operators on its\nleft; it binds less tightly than unary operators on its right. The\nsyntax is:\n\n power ::= primary ["**" u_expr]\n\nThus, in an unparenthesized sequence of power and unary operators, the\noperators are evaluated from right to left (this does not constrain\nthe evaluation order for the operands): "-1**2" results in "-1".\n\nThe power operator has the same semantics as the built-in "pow()"\nfunction, when called with two arguments: it yields its left argument\nraised to the power of its right argument. The numeric arguments are\nfirst converted to a common type, and the result is of that type.\n\nFor int operands, the result has the same type as the operands unless\nthe second argument is negative; in that case, all arguments are\nconverted to float and a float result is delivered. For example,\n"10**2" returns "100", but "10**-2" returns "0.01".\n\nRaising "0.0" to a negative power results in a "ZeroDivisionError".\nRaising a negative number to a fractional power results in a "complex"\nnumber. (In earlier versions it raised a "ValueError".)\n', + 'raise': u'\nThe "raise" statement\n*********************\n\n raise_stmt ::= "raise" [expression ["from" expression]]\n\nIf no expressions are present, "raise" re-raises the last exception\nthat was active in the current scope. If no exception is active in\nthe current scope, a "RuntimeError" exception is raised indicating\nthat this is an error.\n\nOtherwise, "raise" evaluates the first expression as the exception\nobject. It must be either a subclass or an instance of\n"BaseException". If it is a class, the exception instance will be\nobtained when needed by instantiating the class with no arguments.\n\nThe *type* of the exception is the exception instance\'s class, the\n*value* is the instance itself.\n\nA traceback object is normally created automatically when an exception\nis raised and attached to it as the "__traceback__" attribute, which\nis writable. You can create an exception and set your own traceback in\none step using the "with_traceback()" exception method (which returns\nthe same exception instance, with its traceback set to its argument),\nlike so:\n\n raise Exception("foo occurred").with_traceback(tracebackobj)\n\nThe "from" clause is used for exception chaining: if given, the second\n*expression* must be another exception class or instance, which will\nthen be attached to the raised exception as the "__cause__" attribute\n(which is writable). If the raised exception is not handled, both\nexceptions will be printed:\n\n >>> try:\n ... print(1 / 0)\n ... except Exception as exc:\n ... raise RuntimeError("Something bad happened") from exc\n ...\n Traceback (most recent call last):\n File "<stdin>", line 2, in <module>\n ZeroDivisionError: int division or modulo by zero\n\n The above exception was the direct cause of the following exception:\n\n Traceback (most recent call last):\n File "<stdin>", line 4, in <module>\n RuntimeError: Something bad happened\n\nA similar mechanism works implicitly if an exception is raised inside\nan exception handler or a "finally" clause: the previous exception is\nthen attached as the new exception\'s "__context__" attribute:\n\n >>> try:\n ... print(1 / 0)\n ... except:\n ... raise RuntimeError("Something bad happened")\n ...\n Traceback (most recent call last):\n File "<stdin>", line 2, in <module>\n ZeroDivisionError: int division or modulo by zero\n\n During handling of the above exception, another exception occurred:\n\n Traceback (most recent call last):\n File "<stdin>", line 4, in <module>\n RuntimeError: Something bad happened\n\nAdditional information on exceptions can be found in section\n*Exceptions*, and information about handling exceptions is in section\n*The try statement*.\n', + 'return': u'\nThe "return" statement\n**********************\n\n return_stmt ::= "return" [expression_list]\n\n"return" may only occur syntactically nested in a function definition,\nnot within a nested class definition.\n\nIf an expression list is present, it is evaluated, else "None" is\nsubstituted.\n\n"return" leaves the current function call with the expression list (or\n"None") as return value.\n\nWhen "return" passes control out of a "try" statement with a "finally"\nclause, that "finally" clause is executed before really leaving the\nfunction.\n\nIn a generator function, the "return" statement indicates that the\ngenerator is done and will cause "StopIteration" to be raised. The\nreturned value (if any) is used as an argument to construct\n"StopIteration" and becomes the "StopIteration.value" attribute.\n', + 'sequence-types': u'\nEmulating container types\n*************************\n\nThe following methods can be defined to implement container objects.\nContainers usually are sequences (such as lists or tuples) or mappings\n(like dictionaries), but can represent other containers as well. The\nfirst set of methods is used either to emulate a sequence or to\nemulate a mapping; the difference is that for a sequence, the\nallowable keys should be the integers *k* for which "0 <= k < N" where\n*N* is the length of the sequence, or slice objects, which define a\nrange of items. It is also recommended that mappings provide the\nmethods "keys()", "values()", "items()", "get()", "clear()",\n"setdefault()", "pop()", "popitem()", "copy()", and "update()"\nbehaving similar to those for Python\'s standard dictionary objects.\nThe "collections" module provides a "MutableMapping" abstract base\nclass to help create those methods from a base set of "__getitem__()",\n"__setitem__()", "__delitem__()", and "keys()". Mutable sequences\nshould provide methods "append()", "count()", "index()", "extend()",\n"insert()", "pop()", "remove()", "reverse()" and "sort()", like Python\nstandard list objects. Finally, sequence types should implement\naddition (meaning concatenation) and multiplication (meaning\nrepetition) by defining the methods "__add__()", "__radd__()",\n"__iadd__()", "__mul__()", "__rmul__()" and "__imul__()" described\nbelow; they should not define other numerical operators. It is\nrecommended that both mappings and sequences implement the\n"__contains__()" method to allow efficient use of the "in" operator;\nfor mappings, "in" should search the mapping\'s keys; for sequences, it\nshould search through the values. It is further recommended that both\nmappings and sequences implement the "__iter__()" method to allow\nefficient iteration through the container; for mappings, "__iter__()"\nshould be the same as "keys()"; for sequences, it should iterate\nthrough the values.\n\nobject.__len__(self)\n\n Called to implement the built-in function "len()". Should return\n the length of the object, an integer ">=" 0. Also, an object that\n doesn\'t define a "__bool__()" method and whose "__len__()" method\n returns zero is considered to be false in a Boolean context.\n\nobject.__length_hint__(self)\n\n Called to implement "operator.length_hint()". Should return an\n estimated length for the object (which may be greater or less than\n the actual length). The length must be an integer ">=" 0. This\n method is purely an optimization and is never required for\n correctness.\n\n New in version 3.4.\n\nNote: Slicing is done exclusively with the following three methods.\n A call like\n\n a[1:2] = b\n\n is translated to\n\n a[slice(1, 2, None)] = b\n\n and so forth. Missing slice items are always filled in with "None".\n\nobject.__getitem__(self, key)\n\n Called to implement evaluation of "self[key]". For sequence types,\n the accepted keys should be integers and slice objects. Note that\n the special interpretation of negative indexes (if the class wishes\n to emulate a sequence type) is up to the "__getitem__()" method. If\n *key* is of an inappropriate type, "TypeError" may be raised; if of\n a value outside the set of indexes for the sequence (after any\n special interpretation of negative values), "IndexError" should be\n raised. For mapping types, if *key* is missing (not in the\n container), "KeyError" should be raised.\n\n Note: "for" loops expect that an "IndexError" will be raised for\n illegal indexes to allow proper detection of the end of the\n sequence.\n\nobject.__missing__(self, key)\n\n Called by "dict"."__getitem__()" to implement "self[key]" for dict\n subclasses when key is not in the dictionary.\n\nobject.__setitem__(self, key, value)\n\n Called to implement assignment to "self[key]". Same note as for\n "__getitem__()". This should only be implemented for mappings if\n the objects support changes to the values for keys, or if new keys\n can be added, or for sequences if elements can be replaced. The\n same exceptions should be raised for improper *key* values as for\n the "__getitem__()" method.\n\nobject.__delitem__(self, key)\n\n Called to implement deletion of "self[key]". Same note as for\n "__getitem__()". This should only be implemented for mappings if\n the objects support removal of keys, or for sequences if elements\n can be removed from the sequence. The same exceptions should be\n raised for improper *key* values as for the "__getitem__()" method.\n\nobject.__iter__(self)\n\n This method is called when an iterator is required for a container.\n This method should return a new iterator object that can iterate\n over all the objects in the container. For mappings, it should\n iterate over the keys of the container.\n\n Iterator objects also need to implement this method; they are\n required to return themselves. For more information on iterator\n objects, see *Iterator Types*.\n\nobject.__reversed__(self)\n\n Called (if present) by the "reversed()" built-in to implement\n reverse iteration. It should return a new iterator object that\n iterates over all the objects in the container in reverse order.\n\n If the "__reversed__()" method is not provided, the "reversed()"\n built-in will fall back to using the sequence protocol ("__len__()"\n and "__getitem__()"). Objects that support the sequence protocol\n should only provide "__reversed__()" if they can provide an\n implementation that is more efficient than the one provided by\n "reversed()".\n\nThe membership test operators ("in" and "not in") are normally\nimplemented as an iteration through a sequence. However, container\nobjects can supply the following special method with a more efficient\nimplementation, which also does not require the object be a sequence.\n\nobject.__contains__(self, item)\n\n Called to implement membership test operators. Should return true\n if *item* is in *self*, false otherwise. For mapping objects, this\n should consider the keys of the mapping rather than the values or\n the key-item pairs.\n\n For objects that don\'t define "__contains__()", the membership test\n first tries iteration via "__iter__()", then the old sequence\n iteration protocol via "__getitem__()", see *this section in the\n language reference*.\n', + 'shifting': u'\nShifting operations\n*******************\n\nThe shifting operations have lower priority than the arithmetic\noperations:\n\n shift_expr ::= a_expr | shift_expr ( "<<" | ">>" ) a_expr\n\nThese operators accept integers as arguments. They shift the first\nargument to the left or right by the number of bits given by the\nsecond argument.\n\nA right shift by *n* bits is defined as floor division by "pow(2,n)".\nA left shift by *n* bits is defined as multiplication with "pow(2,n)".\n\nNote: In the current implementation, the right-hand operand is\n required to be at most "sys.maxsize". If the right-hand operand is\n larger than "sys.maxsize" an "OverflowError" exception is raised.\n', + 'slicings': u'\nSlicings\n********\n\nA slicing selects a range of items in a sequence object (e.g., a\nstring, tuple or list). Slicings may be used as expressions or as\ntargets in assignment or "del" statements. The syntax for a slicing:\n\n slicing ::= primary "[" slice_list "]"\n slice_list ::= slice_item ("," slice_item)* [","]\n slice_item ::= expression | proper_slice\n proper_slice ::= [lower_bound] ":" [upper_bound] [ ":" [stride] ]\n lower_bound ::= expression\n upper_bound ::= expression\n stride ::= expression\n\nThere is ambiguity in the formal syntax here: anything that looks like\nan expression list also looks like a slice list, so any subscription\ncan be interpreted as a slicing. Rather than further complicating the\nsyntax, this is disambiguated by defining that in this case the\ninterpretation as a subscription takes priority over the\ninterpretation as a slicing (this is the case if the slice list\ncontains no proper slice).\n\nThe semantics for a slicing are as follows. The primary is indexed\n(using the same "__getitem__()" method as normal subscription) with a\nkey that is constructed from the slice list, as follows. If the slice\nlist contains at least one comma, the key is a tuple containing the\nconversion of the slice items; otherwise, the conversion of the lone\nslice item is the key. The conversion of a slice item that is an\nexpression is that expression. The conversion of a proper slice is a\nslice object (see section *The standard type hierarchy*) whose\n"start", "stop" and "step" attributes are the values of the\nexpressions given as lower bound, upper bound and stride,\nrespectively, substituting "None" for missing expressions.\n', + 'specialattrs': u'\nSpecial Attributes\n******************\n\nThe implementation adds a few special read-only attributes to several\nobject types, where they are relevant. Some of these are not reported\nby the "dir()" built-in function.\n\nobject.__dict__\n\n A dictionary or other mapping object used to store an object\'s\n (writable) attributes.\n\ninstance.__class__\n\n The class to which a class instance belongs.\n\nclass.__bases__\n\n The tuple of base classes of a class object.\n\nclass.__name__\n\n The name of the class or type.\n\nclass.__qualname__\n\n The *qualified name* of the class or type.\n\n New in version 3.3.\n\nclass.__mro__\n\n This attribute is a tuple of classes that are considered when\n looking for base classes during method resolution.\n\nclass.mro()\n\n This method can be overridden by a metaclass to customize the\n method resolution order for its instances. It is called at class\n instantiation, and its result is stored in "__mro__".\n\nclass.__subclasses__()\n\n Each class keeps a list of weak references to its immediate\n subclasses. This method returns a list of all those references\n still alive. Example:\n\n >>> int.__subclasses__()\n [<class \'bool\'>]\n\n-[ Footnotes ]-\n\n[1] Additional information on these special methods may be found\n in the Python Reference Manual (*Basic customization*).\n\n[2] As a consequence, the list "[1, 2]" is considered equal to\n "[1.0, 2.0]", and similarly for tuples.\n\n[3] They must have since the parser can\'t tell the type of the\n operands.\n\n[4] Cased characters are those with general category property\n being one of "Lu" (Letter, uppercase), "Ll" (Letter, lowercase),\n or "Lt" (Letter, titlecase).\n\n[5] To format only a tuple you should therefore provide a\n singleton tuple whose only element is the tuple to be formatted.\n', + 'specialnames': u'\nSpecial method names\n********************\n\nA class can implement certain operations that are invoked by special\nsyntax (such as arithmetic operations or subscripting and slicing) by\ndefining methods with special names. This is Python\'s approach to\n*operator overloading*, allowing classes to define their own behavior\nwith respect to language operators. For instance, if a class defines\na method named "__getitem__()", and "x" is an instance of this class,\nthen "x[i]" is roughly equivalent to "type(x).__getitem__(x, i)".\nExcept where mentioned, attempts to execute an operation raise an\nexception when no appropriate method is defined (typically\n"AttributeError" or "TypeError").\n\nWhen implementing a class that emulates any built-in type, it is\nimportant that the emulation only be implemented to the degree that it\nmakes sense for the object being modelled. For example, some\nsequences may work well with retrieval of individual elements, but\nextracting a slice may not make sense. (One example of this is the\n"NodeList" interface in the W3C\'s Document Object Model.)\n\n\nBasic customization\n===================\n\nobject.__new__(cls[, ...])\n\n Called to create a new instance of class *cls*. "__new__()" is a\n static method (special-cased so you need not declare it as such)\n that takes the class of which an instance was requested as its\n first argument. The remaining arguments are those passed to the\n object constructor expression (the call to the class). The return\n value of "__new__()" should be the new object instance (usually an\n instance of *cls*).\n\n Typical implementations create a new instance of the class by\n invoking the superclass\'s "__new__()" method using\n "super(currentclass, cls).__new__(cls[, ...])" with appropriate\n arguments and then modifying the newly-created instance as\n necessary before returning it.\n\n If "__new__()" returns an instance of *cls*, then the new\n instance\'s "__init__()" method will be invoked like\n "__init__(self[, ...])", where *self* is the new instance and the\n remaining arguments are the same as were passed to "__new__()".\n\n If "__new__()" does not return an instance of *cls*, then the new\n instance\'s "__init__()" method will not be invoked.\n\n "__new__()" is intended mainly to allow subclasses of immutable\n types (like int, str, or tuple) to customize instance creation. It\n is also commonly overridden in custom metaclasses in order to\n customize class creation.\n\nobject.__init__(self[, ...])\n\n Called after the instance has been created (by "__new__()"), but\n before it is returned to the caller. The arguments are those\n passed to the class constructor expression. If a base class has an\n "__init__()" method, the derived class\'s "__init__()" method, if\n any, must explicitly call it to ensure proper initialization of the\n base class part of the instance; for example:\n "BaseClass.__init__(self, [args...])".\n\n Because "__new__()" and "__init__()" work together in constructing\n objects ("__new__()" to create it, and "__init__()" to customise\n it), no non-"None" value may be returned by "__init__()"; doing so\n will cause a "TypeError" to be raised at runtime.\n\nobject.__del__(self)\n\n Called when the instance is about to be destroyed. This is also\n called a destructor. If a base class has a "__del__()" method, the\n derived class\'s "__del__()" method, if any, must explicitly call it\n to ensure proper deletion of the base class part of the instance.\n Note that it is possible (though not recommended!) for the\n "__del__()" method to postpone destruction of the instance by\n creating a new reference to it. It may then be called at a later\n time when this new reference is deleted. It is not guaranteed that\n "__del__()" methods are called for objects that still exist when\n the interpreter exits.\n\n Note: "del x" doesn\'t directly call "x.__del__()" --- the former\n decrements the reference count for "x" by one, and the latter is\n only called when "x"\'s reference count reaches zero. Some common\n situations that may prevent the reference count of an object from\n going to zero include: circular references between objects (e.g.,\n a doubly-linked list or a tree data structure with parent and\n child pointers); a reference to the object on the stack frame of\n a function that caught an exception (the traceback stored in\n "sys.exc_info()[2]" keeps the stack frame alive); or a reference\n to the object on the stack frame that raised an unhandled\n exception in interactive mode (the traceback stored in\n "sys.last_traceback" keeps the stack frame alive). The first\n situation can only be remedied by explicitly breaking the cycles;\n the second can be resolved by freeing the reference to the\n traceback object when it is no longer useful, and the third can\n be resolved by storing "None" in "sys.last_traceback". Circular\n references which are garbage are detected and cleaned up when the\n cyclic garbage collector is enabled (it\'s on by default). Refer\n to the documentation for the "gc" module for more information\n about this topic.\n\n Warning: Due to the precarious circumstances under which\n "__del__()" methods are invoked, exceptions that occur during\n their execution are ignored, and a warning is printed to\n "sys.stderr" instead. Also, when "__del__()" is invoked in\n response to a module being deleted (e.g., when execution of the\n program is done), other globals referenced by the "__del__()"\n method may already have been deleted or in the process of being\n torn down (e.g. the import machinery shutting down). For this\n reason, "__del__()" methods should do the absolute minimum needed\n to maintain external invariants. Starting with version 1.5,\n Python guarantees that globals whose name begins with a single\n underscore are deleted from their module before other globals are\n deleted; if no other references to such globals exist, this may\n help in assuring that imported modules are still available at the\n time when the "__del__()" method is called.\n\nobject.__repr__(self)\n\n Called by the "repr()" built-in function to compute the "official"\n string representation of an object. If at all possible, this\n should look like a valid Python expression that could be used to\n recreate an object with the same value (given an appropriate\n environment). If this is not possible, a string of the form\n "<...some useful description...>" should be returned. The return\n value must be a string object. If a class defines "__repr__()" but\n not "__str__()", then "__repr__()" is also used when an "informal"\n string representation of instances of that class is required.\n\n This is typically used for debugging, so it is important that the\n representation is information-rich and unambiguous.\n\nobject.__str__(self)\n\n Called by "str(object)" and the built-in functions "format()" and\n "print()" to compute the "informal" or nicely printable string\n representation of an object. The return value must be a *string*\n object.\n\n This method differs from "object.__repr__()" in that there is no\n expectation that "__str__()" return a valid Python expression: a\n more convenient or concise representation can be used.\n\n The default implementation defined by the built-in type "object"\n calls "object.__repr__()".\n\nobject.__bytes__(self)\n\n Called by "bytes()" to compute a byte-string representation of an\n object. This should return a "bytes" object.\n\nobject.__format__(self, format_spec)\n\n Called by the "format()" built-in function (and by extension, the\n "str.format()" method of class "str") to produce a "formatted"\n string representation of an object. The "format_spec" argument is a\n string that contains a description of the formatting options\n desired. The interpretation of the "format_spec" argument is up to\n the type implementing "__format__()", however most classes will\n either delegate formatting to one of the built-in types, or use a\n similar formatting option syntax.\n\n See *Format Specification Mini-Language* for a description of the\n standard formatting syntax.\n\n The return value must be a string object.\n\n Changed in version 3.4: The __format__ method of "object" itself\n raises a "TypeError" if passed any non-empty string.\n\nobject.__lt__(self, other)\nobject.__le__(self, other)\nobject.__eq__(self, other)\nobject.__ne__(self, other)\nobject.__gt__(self, other)\nobject.__ge__(self, other)\n\n These are the so-called "rich comparison" methods. The\n correspondence between operator symbols and method names is as\n follows: "x<y" calls "x.__lt__(y)", "x<=y" calls "x.__le__(y)",\n "x==y" calls "x.__eq__(y)", "x!=y" calls "x.__ne__(y)", "x>y" calls\n "x.__gt__(y)", and "x>=y" calls "x.__ge__(y)".\n\n A rich comparison method may return the singleton "NotImplemented"\n if it does not implement the operation for a given pair of\n arguments. By convention, "False" and "True" are returned for a\n successful comparison. However, these methods can return any value,\n so if the comparison operator is used in a Boolean context (e.g.,\n in the condition of an "if" statement), Python will call "bool()"\n on the value to determine if the result is true or false.\n\n There are no implied relationships among the comparison operators.\n The truth of "x==y" does not imply that "x!=y" is false.\n Accordingly, when defining "__eq__()", one should also define\n "__ne__()" so that the operators will behave as expected. See the\n paragraph on "__hash__()" for some important notes on creating\n *hashable* objects which support custom comparison operations and\n are usable as dictionary keys.\n\n There are no swapped-argument versions of these methods (to be used\n when the left argument does not support the operation but the right\n argument does); rather, "__lt__()" and "__gt__()" are each other\'s\n reflection, "__le__()" and "__ge__()" are each other\'s reflection,\n and "__eq__()" and "__ne__()" are their own reflection.\n\n Arguments to rich comparison methods are never coerced.\n\n To automatically generate ordering operations from a single root\n operation, see "functools.total_ordering()".\n\nobject.__hash__(self)\n\n Called by built-in function "hash()" and for operations on members\n of hashed collections including "set", "frozenset", and "dict".\n "__hash__()" should return an integer. The only required property\n is that objects which compare equal have the same hash value; it is\n advised to somehow mix together (e.g. using exclusive or) the hash\n values for the components of the object that also play a part in\n comparison of objects.\n\n Note: "hash()" truncates the value returned from an object\'s\n custom "__hash__()" method to the size of a "Py_ssize_t". This\n is typically 8 bytes on 64-bit builds and 4 bytes on 32-bit\n builds. If an object\'s "__hash__()" must interoperate on builds\n of different bit sizes, be sure to check the width on all\n supported builds. An easy way to do this is with "python -c\n "import sys; print(sys.hash_info.width)""\n\n If a class does not define an "__eq__()" method it should not\n define a "__hash__()" operation either; if it defines "__eq__()"\n but not "__hash__()", its instances will not be usable as items in\n hashable collections. If a class defines mutable objects and\n implements an "__eq__()" method, it should not implement\n "__hash__()", since the implementation of hashable collections\n requires that a key\'s hash value is immutable (if the object\'s hash\n value changes, it will be in the wrong hash bucket).\n\n User-defined classes have "__eq__()" and "__hash__()" methods by\n default; with them, all objects compare unequal (except with\n themselves) and "x.__hash__()" returns an appropriate value such\n that "x == y" implies both that "x is y" and "hash(x) == hash(y)".\n\n A class that overrides "__eq__()" and does not define "__hash__()"\n will have its "__hash__()" implicitly set to "None". When the\n "__hash__()" method of a class is "None", instances of the class\n will raise an appropriate "TypeError" when a program attempts to\n retrieve their hash value, and will also be correctly identified as\n unhashable when checking "isinstance(obj, collections.Hashable").\n\n If a class that overrides "__eq__()" needs to retain the\n implementation of "__hash__()" from a parent class, the interpreter\n must be told this explicitly by setting "__hash__ =\n <ParentClass>.__hash__".\n\n If a class that does not override "__eq__()" wishes to suppress\n hash support, it should include "__hash__ = None" in the class\n definition. A class which defines its own "__hash__()" that\n explicitly raises a "TypeError" would be incorrectly identified as\n hashable by an "isinstance(obj, collections.Hashable)" call.\n\n Note: By default, the "__hash__()" values of str, bytes and\n datetime objects are "salted" with an unpredictable random value.\n Although they remain constant within an individual Python\n process, they are not predictable between repeated invocations of\n Python.This is intended to provide protection against a denial-\n of-service caused by carefully-chosen inputs that exploit the\n worst case performance of a dict insertion, O(n^2) complexity.\n See http://www.ocert.org/advisories/ocert-2011-003.html for\n details.Changing hash values affects the iteration order of\n dicts, sets and other mappings. Python has never made guarantees\n about this ordering (and it typically varies between 32-bit and\n 64-bit builds).See also "PYTHONHASHSEED".\n\n Changed in version 3.3: Hash randomization is enabled by default.\n\nobject.__bool__(self)\n\n Called to implement truth value testing and the built-in operation\n "bool()"; should return "False" or "True". When this method is not\n defined, "__len__()" is called, if it is defined, and the object is\n considered true if its result is nonzero. If a class defines\n neither "__len__()" nor "__bool__()", all its instances are\n considered true.\n\n\nCustomizing attribute access\n============================\n\nThe following methods can be defined to customize the meaning of\nattribute access (use of, assignment to, or deletion of "x.name") for\nclass instances.\n\nobject.__getattr__(self, name)\n\n Called when an attribute lookup has not found the attribute in the\n usual places (i.e. it is not an instance attribute nor is it found\n in the class tree for "self"). "name" is the attribute name. This\n method should return the (computed) attribute value or raise an\n "AttributeError" exception.\n\n Note that if the attribute is found through the normal mechanism,\n "__getattr__()" is not called. (This is an intentional asymmetry\n between "__getattr__()" and "__setattr__()".) This is done both for\n efficiency reasons and because otherwise "__getattr__()" would have\n no way to access other attributes of the instance. Note that at\n least for instance variables, you can fake total control by not\n inserting any values in the instance attribute dictionary (but\n instead inserting them in another object). See the\n "__getattribute__()" method below for a way to actually get total\n control over attribute access.\n\nobject.__getattribute__(self, name)\n\n Called unconditionally to implement attribute accesses for\n instances of the class. If the class also defines "__getattr__()",\n the latter will not be called unless "__getattribute__()" either\n calls it explicitly or raises an "AttributeError". This method\n should return the (computed) attribute value or raise an\n "AttributeError" exception. In order to avoid infinite recursion in\n this method, its implementation should always call the base class\n method with the same name to access any attributes it needs, for\n example, "object.__getattribute__(self, name)".\n\n Note: This method may still be bypassed when looking up special\n methods as the result of implicit invocation via language syntax\n or built-in functions. See *Special method lookup*.\n\nobject.__setattr__(self, name, value)\n\n Called when an attribute assignment is attempted. This is called\n instead of the normal mechanism (i.e. store the value in the\n instance dictionary). *name* is the attribute name, *value* is the\n value to be assigned to it.\n\n If "__setattr__()" wants to assign to an instance attribute, it\n should call the base class method with the same name, for example,\n "object.__setattr__(self, name, value)".\n\nobject.__delattr__(self, name)\n\n Like "__setattr__()" but for attribute deletion instead of\n assignment. This should only be implemented if "del obj.name" is\n meaningful for the object.\n\nobject.__dir__(self)\n\n Called when "dir()" is called on the object. A sequence must be\n returned. "dir()" converts the returned sequence to a list and\n sorts it.\n\n\nImplementing Descriptors\n------------------------\n\nThe following methods only apply when an instance of the class\ncontaining the method (a so-called *descriptor* class) appears in an\n*owner* class (the descriptor must be in either the owner\'s class\ndictionary or in the class dictionary for one of its parents). In the\nexamples below, "the attribute" refers to the attribute whose name is\nthe key of the property in the owner class\' "__dict__".\n\nobject.__get__(self, instance, owner)\n\n Called to get the attribute of the owner class (class attribute\n access) or of an instance of that class (instance attribute\n access). *owner* is always the owner class, while *instance* is the\n instance that the attribute was accessed through, or "None" when\n the attribute is accessed through the *owner*. This method should\n return the (computed) attribute value or raise an "AttributeError"\n exception.\n\nobject.__set__(self, instance, value)\n\n Called to set the attribute on an instance *instance* of the owner\n class to a new value, *value*.\n\nobject.__delete__(self, instance)\n\n Called to delete the attribute on an instance *instance* of the\n owner class.\n\nThe attribute "__objclass__" is interpreted by the "inspect" module as\nspecifying the class where this object was defined (setting this\nappropriately can assist in runtime introspection of dynamic class\nattributes). For callables, it may indicate that an instance of the\ngiven type (or a subclass) is expected or required as the first\npositional argument (for example, CPython sets this attribute for\nunbound methods that are implemented in C).\n\n\nInvoking Descriptors\n--------------------\n\nIn general, a descriptor is an object attribute with "binding\nbehavior", one whose attribute access has been overridden by methods\nin the descriptor protocol: "__get__()", "__set__()", and\n"__delete__()". If any of those methods are defined for an object, it\nis said to be a descriptor.\n\nThe default behavior for attribute access is to get, set, or delete\nthe attribute from an object\'s dictionary. For instance, "a.x" has a\nlookup chain starting with "a.__dict__[\'x\']", then\n"type(a).__dict__[\'x\']", and continuing through the base classes of\n"type(a)" excluding metaclasses.\n\nHowever, if the looked-up value is an object defining one of the\ndescriptor methods, then Python may override the default behavior and\ninvoke the descriptor method instead. Where this occurs in the\nprecedence chain depends on which descriptor methods were defined and\nhow they were called.\n\nThe starting point for descriptor invocation is a binding, "a.x". How\nthe arguments are assembled depends on "a":\n\nDirect Call\n The simplest and least common call is when user code directly\n invokes a descriptor method: "x.__get__(a)".\n\nInstance Binding\n If binding to an object instance, "a.x" is transformed into the\n call: "type(a).__dict__[\'x\'].__get__(a, type(a))".\n\nClass Binding\n If binding to a class, "A.x" is transformed into the call:\n "A.__dict__[\'x\'].__get__(None, A)".\n\nSuper Binding\n If "a" is an instance of "super", then the binding "super(B,\n obj).m()" searches "obj.__class__.__mro__" for the base class "A"\n immediately preceding "B" and then invokes the descriptor with the\n call: "A.__dict__[\'m\'].__get__(obj, obj.__class__)".\n\nFor instance bindings, the precedence of descriptor invocation depends\non the which descriptor methods are defined. A descriptor can define\nany combination of "__get__()", "__set__()" and "__delete__()". If it\ndoes not define "__get__()", then accessing the attribute will return\nthe descriptor object itself unless there is a value in the object\'s\ninstance dictionary. If the descriptor defines "__set__()" and/or\n"__delete__()", it is a data descriptor; if it defines neither, it is\na non-data descriptor. Normally, data descriptors define both\n"__get__()" and "__set__()", while non-data descriptors have just the\n"__get__()" method. Data descriptors with "__set__()" and "__get__()"\ndefined always override a redefinition in an instance dictionary. In\ncontrast, non-data descriptors can be overridden by instances.\n\nPython methods (including "staticmethod()" and "classmethod()") are\nimplemented as non-data descriptors. Accordingly, instances can\nredefine and override methods. This allows individual instances to\nacquire behaviors that differ from other instances of the same class.\n\nThe "property()" function is implemented as a data descriptor.\nAccordingly, instances cannot override the behavior of a property.\n\n\n__slots__\n---------\n\nBy default, instances of classes have a dictionary for attribute\nstorage. This wastes space for objects having very few instance\nvariables. The space consumption can become acute when creating large\nnumbers of instances.\n\nThe default can be overridden by defining *__slots__* in a class\ndefinition. The *__slots__* declaration takes a sequence of instance\nvariables and reserves just enough space in each instance to hold a\nvalue for each variable. Space is saved because *__dict__* is not\ncreated for each instance.\n\nobject.__slots__\n\n This class variable can be assigned a string, iterable, or sequence\n of strings with variable names used by instances. *__slots__*\n reserves space for the declared variables and prevents the\n automatic creation of *__dict__* and *__weakref__* for each\n instance.\n\n\nNotes on using *__slots__*\n~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n* When inheriting from a class without *__slots__*, the *__dict__*\n attribute of that class will always be accessible, so a *__slots__*\n definition in the subclass is meaningless.\n\n* Without a *__dict__* variable, instances cannot be assigned new\n variables not listed in the *__slots__* definition. Attempts to\n assign to an unlisted variable name raises "AttributeError". If\n dynamic assignment of new variables is desired, then add\n "\'__dict__\'" to the sequence of strings in the *__slots__*\n declaration.\n\n* Without a *__weakref__* variable for each instance, classes\n defining *__slots__* do not support weak references to its\n instances. If weak reference support is needed, then add\n "\'__weakref__\'" to the sequence of strings in the *__slots__*\n declaration.\n\n* *__slots__* are implemented at the class level by creating\n descriptors (*Implementing Descriptors*) for each variable name. As\n a result, class attributes cannot be used to set default values for\n instance variables defined by *__slots__*; otherwise, the class\n attribute would overwrite the descriptor assignment.\n\n* The action of a *__slots__* declaration is limited to the class\n where it is defined. As a result, subclasses will have a *__dict__*\n unless they also define *__slots__* (which must only contain names\n of any *additional* slots).\n\n* If a class defines a slot also defined in a base class, the\n instance variable defined by the base class slot is inaccessible\n (except by retrieving its descriptor directly from the base class).\n This renders the meaning of the program undefined. In the future, a\n check may be added to prevent this.\n\n* Nonempty *__slots__* does not work for classes derived from\n "variable-length" built-in types such as "int", "bytes" and "tuple".\n\n* Any non-string iterable may be assigned to *__slots__*. Mappings\n may also be used; however, in the future, special meaning may be\n assigned to the values corresponding to each key.\n\n* *__class__* assignment works only if both classes have the same\n *__slots__*.\n\n\nCustomizing class creation\n==========================\n\nBy default, classes are constructed using "type()". The class body is\nexecuted in a new namespace and the class name is bound locally to the\nresult of "type(name, bases, namespace)".\n\nThe class creation process can be customised by passing the\n"metaclass" keyword argument in the class definition line, or by\ninheriting from an existing class that included such an argument. In\nthe following example, both "MyClass" and "MySubclass" are instances\nof "Meta":\n\n class Meta(type):\n pass\n\n class MyClass(metaclass=Meta):\n pass\n\n class MySubclass(MyClass):\n pass\n\nAny other keyword arguments that are specified in the class definition\nare passed through to all metaclass operations described below.\n\nWhen a class definition is executed, the following steps occur:\n\n* the appropriate metaclass is determined\n\n* the class namespace is prepared\n\n* the class body is executed\n\n* the class object is created\n\n\nDetermining the appropriate metaclass\n-------------------------------------\n\nThe appropriate metaclass for a class definition is determined as\nfollows:\n\n* if no bases and no explicit metaclass are given, then "type()" is\n used\n\n* if an explicit metaclass is given and it is *not* an instance of\n "type()", then it is used directly as the metaclass\n\n* if an instance of "type()" is given as the explicit metaclass, or\n bases are defined, then the most derived metaclass is used\n\nThe most derived metaclass is selected from the explicitly specified\nmetaclass (if any) and the metaclasses (i.e. "type(cls)") of all\nspecified base classes. The most derived metaclass is one which is a\nsubtype of *all* of these candidate metaclasses. If none of the\ncandidate metaclasses meets that criterion, then the class definition\nwill fail with "TypeError".\n\n\nPreparing the class namespace\n-----------------------------\n\nOnce the appropriate metaclass has been identified, then the class\nnamespace is prepared. If the metaclass has a "__prepare__" attribute,\nit is called as "namespace = metaclass.__prepare__(name, bases,\n**kwds)" (where the additional keyword arguments, if any, come from\nthe class definition).\n\nIf the metaclass has no "__prepare__" attribute, then the class\nnamespace is initialised as an empty "dict()" instance.\n\nSee also: **PEP 3115** - Metaclasses in Python 3000\n\n Introduced the "__prepare__" namespace hook\n\n\nExecuting the class body\n------------------------\n\nThe class body is executed (approximately) as "exec(body, globals(),\nnamespace)". The key difference from a normal call to "exec()" is that\nlexical scoping allows the class body (including any methods) to\nreference names from the current and outer scopes when the class\ndefinition occurs inside a function.\n\nHowever, even when the class definition occurs inside the function,\nmethods defined inside the class still cannot see names defined at the\nclass scope. Class variables must be accessed through the first\nparameter of instance or class methods, and cannot be accessed at all\nfrom static methods.\n\n\nCreating the class object\n-------------------------\n\nOnce the class namespace has been populated by executing the class\nbody, the class object is created by calling "metaclass(name, bases,\nnamespace, **kwds)" (the additional keywords passed here are the same\nas those passed to "__prepare__").\n\nThis class object is the one that will be referenced by the zero-\nargument form of "super()". "__class__" is an implicit closure\nreference created by the compiler if any methods in a class body refer\nto either "__class__" or "super". This allows the zero argument form\nof "super()" to correctly identify the class being defined based on\nlexical scoping, while the class or instance that was used to make the\ncurrent call is identified based on the first argument passed to the\nmethod.\n\nAfter the class object is created, it is passed to the class\ndecorators included in the class definition (if any) and the resulting\nobject is bound in the local namespace as the defined class.\n\nSee also: **PEP 3135** - New super\n\n Describes the implicit "__class__" closure reference\n\n\nMetaclass example\n-----------------\n\nThe potential uses for metaclasses are boundless. Some ideas that have\nbeen explored include logging, interface checking, automatic\ndelegation, automatic property creation, proxies, frameworks, and\nautomatic resource locking/synchronization.\n\nHere is an example of a metaclass that uses an\n"collections.OrderedDict" to remember the order that class variables\nare defined:\n\n class OrderedClass(type):\n\n @classmethod\n def __prepare__(metacls, name, bases, **kwds):\n return collections.OrderedDict()\n\n def __new__(cls, name, bases, namespace, **kwds):\n result = type.__new__(cls, name, bases, dict(namespace))\n result.members = tuple(namespace)\n return result\n\n class A(metaclass=OrderedClass):\n def one(self): pass\n def two(self): pass\n def three(self): pass\n def four(self): pass\n\n >>> A.members\n (\'__module__\', \'one\', \'two\', \'three\', \'four\')\n\nWhen the class definition for *A* gets executed, the process begins\nwith calling the metaclass\'s "__prepare__()" method which returns an\nempty "collections.OrderedDict". That mapping records the methods and\nattributes of *A* as they are defined within the body of the class\nstatement. Once those definitions are executed, the ordered dictionary\nis fully populated and the metaclass\'s "__new__()" method gets\ninvoked. That method builds the new type and it saves the ordered\ndictionary keys in an attribute called "members".\n\n\nCustomizing instance and subclass checks\n========================================\n\nThe following methods are used to override the default behavior of the\n"isinstance()" and "issubclass()" built-in functions.\n\nIn particular, the metaclass "abc.ABCMeta" implements these methods in\norder to allow the addition of Abstract Base Classes (ABCs) as\n"virtual base classes" to any class or type (including built-in\ntypes), including other ABCs.\n\nclass.__instancecheck__(self, instance)\n\n Return true if *instance* should be considered a (direct or\n indirect) instance of *class*. If defined, called to implement\n "isinstance(instance, class)".\n\nclass.__subclasscheck__(self, subclass)\n\n Return true if *subclass* should be considered a (direct or\n indirect) subclass of *class*. If defined, called to implement\n "issubclass(subclass, class)".\n\nNote that these methods are looked up on the type (metaclass) of a\nclass. They cannot be defined as class methods in the actual class.\nThis is consistent with the lookup of special methods that are called\non instances, only in this case the instance is itself a class.\n\nSee also: **PEP 3119** - Introducing Abstract Base Classes\n\n Includes the specification for customizing "isinstance()" and\n "issubclass()" behavior through "__instancecheck__()" and\n "__subclasscheck__()", with motivation for this functionality in\n the context of adding Abstract Base Classes (see the "abc"\n module) to the language.\n\n\nEmulating callable objects\n==========================\n\nobject.__call__(self[, args...])\n\n Called when the instance is "called" as a function; if this method\n is defined, "x(arg1, arg2, ...)" is a shorthand for\n "x.__call__(arg1, arg2, ...)".\n\n\nEmulating container types\n=========================\n\nThe following methods can be defined to implement container objects.\nContainers usually are sequences (such as lists or tuples) or mappings\n(like dictionaries), but can represent other containers as well. The\nfirst set of methods is used either to emulate a sequence or to\nemulate a mapping; the difference is that for a sequence, the\nallowable keys should be the integers *k* for which "0 <= k < N" where\n*N* is the length of the sequence, or slice objects, which define a\nrange of items. It is also recommended that mappings provide the\nmethods "keys()", "values()", "items()", "get()", "clear()",\n"setdefault()", "pop()", "popitem()", "copy()", and "update()"\nbehaving similar to those for Python\'s standard dictionary objects.\nThe "collections" module provides a "MutableMapping" abstract base\nclass to help create those methods from a base set of "__getitem__()",\n"__setitem__()", "__delitem__()", and "keys()". Mutable sequences\nshould provide methods "append()", "count()", "index()", "extend()",\n"insert()", "pop()", "remove()", "reverse()" and "sort()", like Python\nstandard list objects. Finally, sequence types should implement\naddition (meaning concatenation) and multiplication (meaning\nrepetition) by defining the methods "__add__()", "__radd__()",\n"__iadd__()", "__mul__()", "__rmul__()" and "__imul__()" described\nbelow; they should not define other numerical operators. It is\nrecommended that both mappings and sequences implement the\n"__contains__()" method to allow efficient use of the "in" operator;\nfor mappings, "in" should search the mapping\'s keys; for sequences, it\nshould search through the values. It is further recommended that both\nmappings and sequences implement the "__iter__()" method to allow\nefficient iteration through the container; for mappings, "__iter__()"\nshould be the same as "keys()"; for sequences, it should iterate\nthrough the values.\n\nobject.__len__(self)\n\n Called to implement the built-in function "len()". Should return\n the length of the object, an integer ">=" 0. Also, an object that\n doesn\'t define a "__bool__()" method and whose "__len__()" method\n returns zero is considered to be false in a Boolean context.\n\nobject.__length_hint__(self)\n\n Called to implement "operator.length_hint()". Should return an\n estimated length for the object (which may be greater or less than\n the actual length). The length must be an integer ">=" 0. This\n method is purely an optimization and is never required for\n correctness.\n\n New in version 3.4.\n\nNote: Slicing is done exclusively with the following three methods.\n A call like\n\n a[1:2] = b\n\n is translated to\n\n a[slice(1, 2, None)] = b\n\n and so forth. Missing slice items are always filled in with "None".\n\nobject.__getitem__(self, key)\n\n Called to implement evaluation of "self[key]". For sequence types,\n the accepted keys should be integers and slice objects. Note that\n the special interpretation of negative indexes (if the class wishes\n to emulate a sequence type) is up to the "__getitem__()" method. If\n *key* is of an inappropriate type, "TypeError" may be raised; if of\n a value outside the set of indexes for the sequence (after any\n special interpretation of negative values), "IndexError" should be\n raised. For mapping types, if *key* is missing (not in the\n container), "KeyError" should be raised.\n\n Note: "for" loops expect that an "IndexError" will be raised for\n illegal indexes to allow proper detection of the end of the\n sequence.\n\nobject.__missing__(self, key)\n\n Called by "dict"."__getitem__()" to implement "self[key]" for dict\n subclasses when key is not in the dictionary.\n\nobject.__setitem__(self, key, value)\n\n Called to implement assignment to "self[key]". Same note as for\n "__getitem__()". This should only be implemented for mappings if\n the objects support changes to the values for keys, or if new keys\n can be added, or for sequences if elements can be replaced. The\n same exceptions should be raised for improper *key* values as for\n the "__getitem__()" method.\n\nobject.__delitem__(self, key)\n\n Called to implement deletion of "self[key]". Same note as for\n "__getitem__()". This should only be implemented for mappings if\n the objects support removal of keys, or for sequences if elements\n can be removed from the sequence. The same exceptions should be\n raised for improper *key* values as for the "__getitem__()" method.\n\nobject.__iter__(self)\n\n This method is called when an iterator is required for a container.\n This method should return a new iterator object that can iterate\n over all the objects in the container. For mappings, it should\n iterate over the keys of the container.\n\n Iterator objects also need to implement this method; they are\n required to return themselves. For more information on iterator\n objects, see *Iterator Types*.\n\nobject.__reversed__(self)\n\n Called (if present) by the "reversed()" built-in to implement\n reverse iteration. It should return a new iterator object that\n iterates over all the objects in the container in reverse order.\n\n If the "__reversed__()" method is not provided, the "reversed()"\n built-in will fall back to using the sequence protocol ("__len__()"\n and "__getitem__()"). Objects that support the sequence protocol\n should only provide "__reversed__()" if they can provide an\n implementation that is more efficient than the one provided by\n "reversed()".\n\nThe membership test operators ("in" and "not in") are normally\nimplemented as an iteration through a sequence. However, container\nobjects can supply the following special method with a more efficient\nimplementation, which also does not require the object be a sequence.\n\nobject.__contains__(self, item)\n\n Called to implement membership test operators. Should return true\n if *item* is in *self*, false otherwise. For mapping objects, this\n should consider the keys of the mapping rather than the values or\n the key-item pairs.\n\n For objects that don\'t define "__contains__()", the membership test\n first tries iteration via "__iter__()", then the old sequence\n iteration protocol via "__getitem__()", see *this section in the\n language reference*.\n\n\nEmulating numeric types\n=======================\n\nThe following methods can be defined to emulate numeric objects.\nMethods corresponding to operations that are not supported by the\nparticular kind of number implemented (e.g., bitwise operations for\nnon-integral numbers) should be left undefined.\n\nobject.__add__(self, other)\nobject.__sub__(self, other)\nobject.__mul__(self, other)\nobject.__matmul__(self, other)\nobject.__truediv__(self, other)\nobject.__floordiv__(self, other)\nobject.__mod__(self, other)\nobject.__divmod__(self, other)\nobject.__pow__(self, other[, modulo])\nobject.__lshift__(self, other)\nobject.__rshift__(self, other)\nobject.__and__(self, other)\nobject.__xor__(self, other)\nobject.__or__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations ("+", "-", "*", "@", "/", "//", "%", "divmod()",\n "pow()", "**", "<<", ">>", "&", "^", "|"). For instance, to\n evaluate the expression "x + y", where *x* is an instance of a\n class that has an "__add__()" method, "x.__add__(y)" is called.\n The "__divmod__()" method should be the equivalent to using\n "__floordiv__()" and "__mod__()"; it should not be related to\n "__truediv__()". Note that "__pow__()" should be defined to accept\n an optional third argument if the ternary version of the built-in\n "pow()" function is to be supported.\n\n If one of those methods does not support the operation with the\n supplied arguments, it should return "NotImplemented".\n\nobject.__radd__(self, other)\nobject.__rsub__(self, other)\nobject.__rmul__(self, other)\nobject.__rmatmul__(self, other)\nobject.__rtruediv__(self, other)\nobject.__rfloordiv__(self, other)\nobject.__rmod__(self, other)\nobject.__rdivmod__(self, other)\nobject.__rpow__(self, other)\nobject.__rlshift__(self, other)\nobject.__rrshift__(self, other)\nobject.__rand__(self, other)\nobject.__rxor__(self, other)\nobject.__ror__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations ("+", "-", "*", "@", "/", "//", "%", "divmod()",\n "pow()", "**", "<<", ">>", "&", "^", "|") with reflected (swapped)\n operands. These functions are only called if the left operand does\n not support the corresponding operation and the operands are of\n different types. [2] For instance, to evaluate the expression "x -\n y", where *y* is an instance of a class that has an "__rsub__()"\n method, "y.__rsub__(x)" is called if "x.__sub__(y)" returns\n *NotImplemented*.\n\n Note that ternary "pow()" will not try calling "__rpow__()" (the\n coercion rules would become too complicated).\n\n Note: If the right operand\'s type is a subclass of the left\n operand\'s type and that subclass provides the reflected method\n for the operation, this method will be called before the left\n operand\'s non-reflected method. This behavior allows subclasses\n to override their ancestors\' operations.\n\nobject.__iadd__(self, other)\nobject.__isub__(self, other)\nobject.__imul__(self, other)\nobject.__imatmul__(self, other)\nobject.__itruediv__(self, other)\nobject.__ifloordiv__(self, other)\nobject.__imod__(self, other)\nobject.__ipow__(self, other[, modulo])\nobject.__ilshift__(self, other)\nobject.__irshift__(self, other)\nobject.__iand__(self, other)\nobject.__ixor__(self, other)\nobject.__ior__(self, other)\n\n These methods are called to implement the augmented arithmetic\n assignments ("+=", "-=", "*=", "@=", "/=", "//=", "%=", "**=",\n "<<=", ">>=", "&=", "^=", "|="). These methods should attempt to\n do the operation in-place (modifying *self*) and return the result\n (which could be, but does not have to be, *self*). If a specific\n method is not defined, the augmented assignment falls back to the\n normal methods. For instance, if *x* is an instance of a class\n with an "__iadd__()" method, "x += y" is equivalent to "x =\n x.__iadd__(y)" . Otherwise, "x.__add__(y)" and "y.__radd__(x)" are\n considered, as with the evaluation of "x + y". In certain\n situations, augmented assignment can result in unexpected errors\n (see *Why does a_tuple[i] += [\'item\'] raise an exception when the\n addition works?*), but this behavior is in fact part of the data\n model.\n\nobject.__neg__(self)\nobject.__pos__(self)\nobject.__abs__(self)\nobject.__invert__(self)\n\n Called to implement the unary arithmetic operations ("-", "+",\n "abs()" and "~").\n\nobject.__complex__(self)\nobject.__int__(self)\nobject.__float__(self)\nobject.__round__(self[, n])\n\n Called to implement the built-in functions "complex()", "int()",\n "float()" and "round()". Should return a value of the appropriate\n type.\n\nobject.__index__(self)\n\n Called to implement "operator.index()", and whenever Python needs\n to losslessly convert the numeric object to an integer object (such\n as in slicing, or in the built-in "bin()", "hex()" and "oct()"\n functions). Presence of this method indicates that the numeric\n object is an integer type. Must return an integer.\n\n Note: In order to have a coherent integer type class, when\n "__index__()" is defined "__int__()" should also be defined, and\n both should return the same value.\n\n\nWith Statement Context Managers\n===============================\n\nA *context manager* is an object that defines the runtime context to\nbe established when executing a "with" statement. The context manager\nhandles the entry into, and the exit from, the desired runtime context\nfor the execution of the block of code. Context managers are normally\ninvoked using the "with" statement (described in section *The with\nstatement*), but can also be used by directly invoking their methods.\n\nTypical uses of context managers include saving and restoring various\nkinds of global state, locking and unlocking resources, closing opened\nfiles, etc.\n\nFor more information on context managers, see *Context Manager Types*.\n\nobject.__enter__(self)\n\n Enter the runtime context related to this object. The "with"\n statement will bind this method\'s return value to the target(s)\n specified in the "as" clause of the statement, if any.\n\nobject.__exit__(self, exc_type, exc_value, traceback)\n\n Exit the runtime context related to this object. The parameters\n describe the exception that caused the context to be exited. If the\n context was exited without an exception, all three arguments will\n be "None".\n\n If an exception is supplied, and the method wishes to suppress the\n exception (i.e., prevent it from being propagated), it should\n return a true value. Otherwise, the exception will be processed\n normally upon exit from this method.\n\n Note that "__exit__()" methods should not reraise the passed-in\n exception; this is the caller\'s responsibility.\n\nSee also: **PEP 0343** - The "with" statement\n\n The specification, background, and examples for the Python "with"\n statement.\n\n\nSpecial method lookup\n=====================\n\nFor custom classes, implicit invocations of special methods are only\nguaranteed to work correctly if defined on an object\'s type, not in\nthe object\'s instance dictionary. That behaviour is the reason why\nthe following code raises an exception:\n\n >>> class C:\n ... pass\n ...\n >>> c = C()\n >>> c.__len__ = lambda: 5\n >>> len(c)\n Traceback (most recent call last):\n File "<stdin>", line 1, in <module>\n TypeError: object of type \'C\' has no len()\n\nThe rationale behind this behaviour lies with a number of special\nmethods such as "__hash__()" and "__repr__()" that are implemented by\nall objects, including type objects. If the implicit lookup of these\nmethods used the conventional lookup process, they would fail when\ninvoked on the type object itself:\n\n >>> 1 .__hash__() == hash(1)\n True\n >>> int.__hash__() == hash(int)\n Traceback (most recent call last):\n File "<stdin>", line 1, in <module>\n TypeError: descriptor \'__hash__\' of \'int\' object needs an argument\n\nIncorrectly attempting to invoke an unbound method of a class in this\nway is sometimes referred to as \'metaclass confusion\', and is avoided\nby bypassing the instance when looking up special methods:\n\n >>> type(1).__hash__(1) == hash(1)\n True\n >>> type(int).__hash__(int) == hash(int)\n True\n\nIn addition to bypassing any instance attributes in the interest of\ncorrectness, implicit special method lookup generally also bypasses\nthe "__getattribute__()" method even of the object\'s metaclass:\n\n >>> class Meta(type):\n ... def __getattribute__(*args):\n ... print("Metaclass getattribute invoked")\n ... return type.__getattribute__(*args)\n ...\n >>> class C(object, metaclass=Meta):\n ... def __len__(self):\n ... return 10\n ... def __getattribute__(*args):\n ... print("Class getattribute invoked")\n ... return object.__getattribute__(*args)\n ...\n >>> c = C()\n >>> c.__len__() # Explicit lookup via instance\n Class getattribute invoked\n 10\n >>> type(c).__len__(c) # Explicit lookup via type\n Metaclass getattribute invoked\n 10\n >>> len(c) # Implicit lookup\n 10\n\nBypassing the "__getattribute__()" machinery in this fashion provides\nsignificant scope for speed optimisations within the interpreter, at\nthe cost of some flexibility in the handling of special methods (the\nspecial method *must* be set on the class object itself in order to be\nconsistently invoked by the interpreter).\n\n-[ Footnotes ]-\n\n[1] It *is* possible in some cases to change an object\'s type,\n under certain controlled conditions. It generally isn\'t a good\n idea though, since it can lead to some very strange behaviour if\n it is handled incorrectly.\n\n[2] For operands of the same type, it is assumed that if the non-\n reflected method (such as "__add__()") fails the operation is not\n supported, which is why the reflected method is not called.\n', + 'string-methods': u'\nString Methods\n**************\n\nStrings implement all of the *common* sequence operations, along with\nthe additional methods described below.\n\nStrings also support two styles of string formatting, one providing a\nlarge degree of flexibility and customization (see "str.format()",\n*Format String Syntax* and *String Formatting*) and the other based on\nC "printf" style formatting that handles a narrower range of types and\nis slightly harder to use correctly, but is often faster for the cases\nit can handle (*printf-style String Formatting*).\n\nThe *Text Processing Services* section of the standard library covers\na number of other modules that provide various text related utilities\n(including regular expression support in the "re" module).\n\nstr.capitalize()\n\n Return a copy of the string with its first character capitalized\n and the rest lowercased.\n\nstr.casefold()\n\n Return a casefolded copy of the string. Casefolded strings may be\n used for caseless matching.\n\n Casefolding is similar to lowercasing but more aggressive because\n it is intended to remove all case distinctions in a string. For\n example, the German lowercase letter "\'\xdf\'" is equivalent to ""ss"".\n Since it is already lowercase, "lower()" would do nothing to "\'\xdf\'";\n "casefold()" converts it to ""ss"".\n\n The casefolding algorithm is described in section 3.13 of the\n Unicode Standard.\n\n New in version 3.3.\n\nstr.center(width[, fillchar])\n\n Return centered in a string of length *width*. Padding is done\n using the specified *fillchar* (default is an ASCII space). The\n original string is returned if *width* is less than or equal to\n "len(s)".\n\nstr.count(sub[, start[, end]])\n\n Return the number of non-overlapping occurrences of substring *sub*\n in the range [*start*, *end*]. Optional arguments *start* and\n *end* are interpreted as in slice notation.\n\nstr.encode(encoding="utf-8", errors="strict")\n\n Return an encoded version of the string as a bytes object. Default\n encoding is "\'utf-8\'". *errors* may be given to set a different\n error handling scheme. The default for *errors* is "\'strict\'",\n meaning that encoding errors raise a "UnicodeError". Other possible\n values are "\'ignore\'", "\'replace\'", "\'xmlcharrefreplace\'",\n "\'backslashreplace\'" and any other name registered via\n "codecs.register_error()", see section *Error Handlers*. For a list\n of possible encodings, see section *Standard Encodings*.\n\n Changed in version 3.1: Support for keyword arguments added.\n\nstr.endswith(suffix[, start[, end]])\n\n Return "True" if the string ends with the specified *suffix*,\n otherwise return "False". *suffix* can also be a tuple of suffixes\n to look for. With optional *start*, test beginning at that\n position. With optional *end*, stop comparing at that position.\n\nstr.expandtabs(tabsize=8)\n\n Return a copy of the string where all tab characters are replaced\n by one or more spaces, depending on the current column and the\n given tab size. Tab positions occur every *tabsize* characters\n (default is 8, giving tab positions at columns 0, 8, 16 and so on).\n To expand the string, the current column is set to zero and the\n string is examined character by character. If the character is a\n tab ("\\t"), one or more space characters are inserted in the result\n until the current column is equal to the next tab position. (The\n tab character itself is not copied.) If the character is a newline\n ("\\n") or return ("\\r"), it is copied and the current column is\n reset to zero. Any other character is copied unchanged and the\n current column is incremented by one regardless of how the\n character is represented when printed.\n\n >>> \'01\\t012\\t0123\\t01234\'.expandtabs()\n \'01 012 0123 01234\'\n >>> \'01\\t012\\t0123\\t01234\'.expandtabs(4)\n \'01 012 0123 01234\'\n\nstr.find(sub[, start[, end]])\n\n Return the lowest index in the string where substring *sub* is\n found, such that *sub* is contained in the slice "s[start:end]".\n Optional arguments *start* and *end* are interpreted as in slice\n notation. Return "-1" if *sub* is not found.\n\n Note: The "find()" method should be used only if you need to know\n the position of *sub*. To check if *sub* is a substring or not,\n use the "in" operator:\n\n >>> \'Py\' in \'Python\'\n True\n\nstr.format(*args, **kwargs)\n\n Perform a string formatting operation. The string on which this\n method is called can contain literal text or replacement fields\n delimited by braces "{}". Each replacement field contains either\n the numeric index of a positional argument, or the name of a\n keyword argument. Returns a copy of the string where each\n replacement field is replaced with the string value of the\n corresponding argument.\n\n >>> "The sum of 1 + 2 is {0}".format(1+2)\n \'The sum of 1 + 2 is 3\'\n\n See *Format String Syntax* for a description of the various\n formatting options that can be specified in format strings.\n\nstr.format_map(mapping)\n\n Similar to "str.format(**mapping)", except that "mapping" is used\n directly and not copied to a "dict". This is useful if for example\n "mapping" is a dict subclass:\n\n >>> class Default(dict):\n ... def __missing__(self, key):\n ... return key\n ...\n >>> \'{name} was born in {country}\'.format_map(Default(name=\'Guido\'))\n \'Guido was born in country\'\n\n New in version 3.2.\n\nstr.index(sub[, start[, end]])\n\n Like "find()", but raise "ValueError" when the substring is not\n found.\n\nstr.isalnum()\n\n Return true if all characters in the string are alphanumeric and\n there is at least one character, false otherwise. A character "c"\n is alphanumeric if one of the following returns "True":\n "c.isalpha()", "c.isdecimal()", "c.isdigit()", or "c.isnumeric()".\n\nstr.isalpha()\n\n Return true if all characters in the string are alphabetic and\n there is at least one character, false otherwise. Alphabetic\n characters are those characters defined in the Unicode character\n database as "Letter", i.e., those with general category property\n being one of "Lm", "Lt", "Lu", "Ll", or "Lo". Note that this is\n different from the "Alphabetic" property defined in the Unicode\n Standard.\n\nstr.isdecimal()\n\n Return true if all characters in the string are decimal characters\n and there is at least one character, false otherwise. Decimal\n characters are those from general category "Nd". This category\n includes digit characters, and all characters that can be used to\n form decimal-radix numbers, e.g. U+0660, ARABIC-INDIC DIGIT ZERO.\n\nstr.isdigit()\n\n Return true if all characters in the string are digits and there is\n at least one character, false otherwise. Digits include decimal\n characters and digits that need special handling, such as the\n compatibility superscript digits. Formally, a digit is a character\n that has the property value Numeric_Type=Digit or\n Numeric_Type=Decimal.\n\nstr.isidentifier()\n\n Return true if the string is a valid identifier according to the\n language definition, section *Identifiers and keywords*.\n\n Use "keyword.iskeyword()" to test for reserved identifiers such as\n "def" and "class".\n\nstr.islower()\n\n Return true if all cased characters [4] in the string are lowercase\n and there is at least one cased character, false otherwise.\n\nstr.isnumeric()\n\n Return true if all characters in the string are numeric characters,\n and there is at least one character, false otherwise. Numeric\n characters include digit characters, and all characters that have\n the Unicode numeric value property, e.g. U+2155, VULGAR FRACTION\n ONE FIFTH. Formally, numeric characters are those with the\n property value Numeric_Type=Digit, Numeric_Type=Decimal or\n Numeric_Type=Numeric.\n\nstr.isprintable()\n\n Return true if all characters in the string are printable or the\n string is empty, false otherwise. Nonprintable characters are\n those characters defined in the Unicode character database as\n "Other" or "Separator", excepting the ASCII space (0x20) which is\n considered printable. (Note that printable characters in this\n context are those which should not be escaped when "repr()" is\n invoked on a string. It has no bearing on the handling of strings\n written to "sys.stdout" or "sys.stderr".)\n\nstr.isspace()\n\n Return true if there are only whitespace characters in the string\n and there is at least one character, false otherwise. Whitespace\n characters are those characters defined in the Unicode character\n database as "Other" or "Separator" and those with bidirectional\n property being one of "WS", "B", or "S".\n\nstr.istitle()\n\n Return true if the string is a titlecased string and there is at\n least one character, for example uppercase characters may only\n follow uncased characters and lowercase characters only cased ones.\n Return false otherwise.\n\nstr.isupper()\n\n Return true if all cased characters [4] in the string are uppercase\n and there is at least one cased character, false otherwise.\n\nstr.join(iterable)\n\n Return a string which is the concatenation of the strings in the\n *iterable* *iterable*. A "TypeError" will be raised if there are\n any non-string values in *iterable*, including "bytes" objects.\n The separator between elements is the string providing this method.\n\nstr.ljust(width[, fillchar])\n\n Return the string left justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is an ASCII\n space). The original string is returned if *width* is less than or\n equal to "len(s)".\n\nstr.lower()\n\n Return a copy of the string with all the cased characters [4]\n converted to lowercase.\n\n The lowercasing algorithm used is described in section 3.13 of the\n Unicode Standard.\n\nstr.lstrip([chars])\n\n Return a copy of the string with leading characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or "None", the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a prefix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.lstrip()\n \'spacious \'\n >>> \'www.example.com\'.lstrip(\'cmowz.\')\n \'example.com\'\n\nstatic str.maketrans(x[, y[, z]])\n\n This static method returns a translation table usable for\n "str.translate()".\n\n If there is only one argument, it must be a dictionary mapping\n Unicode ordinals (integers) or characters (strings of length 1) to\n Unicode ordinals, strings (of arbitrary lengths) or None.\n Character keys will then be converted to ordinals.\n\n If there are two arguments, they must be strings of equal length,\n and in the resulting dictionary, each character in x will be mapped\n to the character at the same position in y. If there is a third\n argument, it must be a string, whose characters will be mapped to\n None in the result.\n\nstr.partition(sep)\n\n Split the string at the first occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing the string itself, followed by\n two empty strings.\n\nstr.replace(old, new[, count])\n\n Return a copy of the string with all occurrences of substring *old*\n replaced by *new*. If the optional argument *count* is given, only\n the first *count* occurrences are replaced.\n\nstr.rfind(sub[, start[, end]])\n\n Return the highest index in the string where substring *sub* is\n found, such that *sub* is contained within "s[start:end]".\n Optional arguments *start* and *end* are interpreted as in slice\n notation. Return "-1" on failure.\n\nstr.rindex(sub[, start[, end]])\n\n Like "rfind()" but raises "ValueError" when the substring *sub* is\n not found.\n\nstr.rjust(width[, fillchar])\n\n Return the string right justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is an ASCII\n space). The original string is returned if *width* is less than or\n equal to "len(s)".\n\nstr.rpartition(sep)\n\n Split the string at the last occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing two empty strings, followed by\n the string itself.\n\nstr.rsplit(sep=None, maxsplit=-1)\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit* splits\n are done, the *rightmost* ones. If *sep* is not specified or\n "None", any whitespace string is a separator. Except for splitting\n from the right, "rsplit()" behaves like "split()" which is\n described in detail below.\n\nstr.rstrip([chars])\n\n Return a copy of the string with trailing characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or "None", the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a suffix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.rstrip()\n \' spacious\'\n >>> \'mississippi\'.rstrip(\'ipz\')\n \'mississ\'\n\nstr.split(sep=None, maxsplit=-1)\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit*\n splits are done (thus, the list will have at most "maxsplit+1"\n elements). If *maxsplit* is not specified or "-1", then there is\n no limit on the number of splits (all possible splits are made).\n\n If *sep* is given, consecutive delimiters are not grouped together\n and are deemed to delimit empty strings (for example,\n "\'1,,2\'.split(\',\')" returns "[\'1\', \'\', \'2\']"). The *sep* argument\n may consist of multiple characters (for example,\n "\'1<>2<>3\'.split(\'<>\')" returns "[\'1\', \'2\', \'3\']"). Splitting an\n empty string with a specified separator returns "[\'\']".\n\n For example:\n\n >>> \'1,2,3\'.split(\',\')\n [\'1\', \'2\', \'3\']\n >>> \'1,2,3\'.split(\',\', maxsplit=1)\n [\'1\', \'2,3\']\n >>> \'1,2,,3,\'.split(\',\')\n [\'1\', \'2\', \'\', \'3\', \'\']\n\n If *sep* is not specified or is "None", a different splitting\n algorithm is applied: runs of consecutive whitespace are regarded\n as a single separator, and the result will contain no empty strings\n at the start or end if the string has leading or trailing\n whitespace. Consequently, splitting an empty string or a string\n consisting of just whitespace with a "None" separator returns "[]".\n\n For example:\n\n >>> \'1 2 3\'.split()\n [\'1\', \'2\', \'3\']\n >>> \'1 2 3\'.split(maxsplit=1)\n [\'1\', \'2 3\']\n >>> \' 1 2 3 \'.split()\n [\'1\', \'2\', \'3\']\n\nstr.splitlines([keepends])\n\n Return a list of the lines in the string, breaking at line\n boundaries. This method uses the *universal newlines* approach to\n splitting lines. Line breaks are not included in the resulting list\n unless *keepends* is given and true.\n\n For example:\n\n >>> \'ab c\\n\\nde fg\\rkl\\r\\n\'.splitlines()\n [\'ab c\', \'\', \'de fg\', \'kl\']\n >>> \'ab c\\n\\nde fg\\rkl\\r\\n\'.splitlines(keepends=True)\n [\'ab c\\n\', \'\\n\', \'de fg\\r\', \'kl\\r\\n\']\n\n Unlike "split()" when a delimiter string *sep* is given, this\n method returns an empty list for the empty string, and a terminal\n line break does not result in an extra line:\n\n >>> "".splitlines()\n []\n >>> "One line\\n".splitlines()\n [\'One line\']\n\n For comparison, "split(\'\\n\')" gives:\n\n >>> \'\'.split(\'\\n\')\n [\'\']\n >>> \'Two lines\\n\'.split(\'\\n\')\n [\'Two lines\', \'\']\n\nstr.startswith(prefix[, start[, end]])\n\n Return "True" if string starts with the *prefix*, otherwise return\n "False". *prefix* can also be a tuple of prefixes to look for.\n With optional *start*, test string beginning at that position.\n With optional *end*, stop comparing string at that position.\n\nstr.strip([chars])\n\n Return a copy of the string with the leading and trailing\n characters removed. The *chars* argument is a string specifying the\n set of characters to be removed. If omitted or "None", the *chars*\n argument defaults to removing whitespace. The *chars* argument is\n not a prefix or suffix; rather, all combinations of its values are\n stripped:\n\n >>> \' spacious \'.strip()\n \'spacious\'\n >>> \'www.example.com\'.strip(\'cmowz.\')\n \'example\'\n\nstr.swapcase()\n\n Return a copy of the string with uppercase characters converted to\n lowercase and vice versa. Note that it is not necessarily true that\n "s.swapcase().swapcase() == s".\n\nstr.title()\n\n Return a titlecased version of the string where words start with an\n uppercase character and the remaining characters are lowercase.\n\n For example:\n\n >>> \'Hello world\'.title()\n \'Hello World\'\n\n The algorithm uses a simple language-independent definition of a\n word as groups of consecutive letters. The definition works in\n many contexts but it means that apostrophes in contractions and\n possessives form word boundaries, which may not be the desired\n result:\n\n >>> "they\'re bill\'s friends from the UK".title()\n "They\'Re Bill\'S Friends From The Uk"\n\n A workaround for apostrophes can be constructed using regular\n expressions:\n\n >>> import re\n >>> def titlecase(s):\n ... return re.sub(r"[A-Za-z]+(\'[A-Za-z]+)?",\n ... lambda mo: mo.group(0)[0].upper() +\n ... mo.group(0)[1:].lower(),\n ... s)\n ...\n >>> titlecase("they\'re bill\'s friends.")\n "They\'re Bill\'s Friends."\n\nstr.translate(map)\n\n Return a copy of the *s* where all characters have been mapped\n through the *map* which must be a dictionary of Unicode ordinals\n (integers) to Unicode ordinals, strings or "None". Unmapped\n characters are left untouched. Characters mapped to "None" are\n deleted.\n\n You can use "str.maketrans()" to create a translation map from\n character-to-character mappings in different formats.\n\n Note: An even more flexible approach is to create a custom\n character mapping codec using the "codecs" module (see\n "encodings.cp1251" for an example).\n\nstr.upper()\n\n Return a copy of the string with all the cased characters [4]\n converted to uppercase. Note that "str.upper().isupper()" might be\n "False" if "s" contains uncased characters or if the Unicode\n category of the resulting character(s) is not "Lu" (Letter,\n uppercase), but e.g. "Lt" (Letter, titlecase).\n\n The uppercasing algorithm used is described in section 3.13 of the\n Unicode Standard.\n\nstr.zfill(width)\n\n Return a copy of the string left filled with ASCII "\'0\'" digits to\n make a string of length *width*. A leading sign prefix ("\'+\'"/"\'-\'"\n is handled by inserting the padding *after* the sign character\n rather than before. The original string is returned if *width* is\n less than or equal to "len(s)".\n\n For example:\n\n >>> "42".zfill(5)\n \'00042\'\n >>> "-42".zfill(5)\n \'-0042\'\n', + 'strings': u'\nString and Bytes literals\n*************************\n\nString literals are described by the following lexical definitions:\n\n stringliteral ::= [stringprefix](shortstring | longstring)\n stringprefix ::= "r" | "u" | "R" | "U"\n shortstring ::= "\'" shortstringitem* "\'" | \'"\' shortstringitem* \'"\'\n longstring ::= "\'\'\'" longstringitem* "\'\'\'" | \'"""\' longstringitem* \'"""\'\n shortstringitem ::= shortstringchar | stringescapeseq\n longstringitem ::= longstringchar | stringescapeseq\n shortstringchar ::= <any source character except "\\" or newline or the quote>\n longstringchar ::= <any source character except "\\">\n stringescapeseq ::= "\\" <any source character>\n\n bytesliteral ::= bytesprefix(shortbytes | longbytes)\n bytesprefix ::= "b" | "B" | "br" | "Br" | "bR" | "BR" | "rb" | "rB" | "Rb" | "RB"\n shortbytes ::= "\'" shortbytesitem* "\'" | \'"\' shortbytesitem* \'"\'\n longbytes ::= "\'\'\'" longbytesitem* "\'\'\'" | \'"""\' longbytesitem* \'"""\'\n shortbytesitem ::= shortbyteschar | bytesescapeseq\n longbytesitem ::= longbyteschar | bytesescapeseq\n shortbyteschar ::= <any ASCII character except "\\" or newline or the quote>\n longbyteschar ::= <any ASCII character except "\\">\n bytesescapeseq ::= "\\" <any ASCII character>\n\nOne syntactic restriction not indicated by these productions is that\nwhitespace is not allowed between the "stringprefix" or "bytesprefix"\nand the rest of the literal. The source character set is defined by\nthe encoding declaration; it is UTF-8 if no encoding declaration is\ngiven in the source file; see section *Encoding declarations*.\n\nIn plain English: Both types of literals can be enclosed in matching\nsingle quotes ("\'") or double quotes ("""). They can also be enclosed\nin matching groups of three single or double quotes (these are\ngenerally referred to as *triple-quoted strings*). The backslash\n("\\") character is used to escape characters that otherwise have a\nspecial meaning, such as newline, backslash itself, or the quote\ncharacter.\n\nBytes literals are always prefixed with "\'b\'" or "\'B\'"; they produce\nan instance of the "bytes" type instead of the "str" type. They may\nonly contain ASCII characters; bytes with a numeric value of 128 or\ngreater must be expressed with escapes.\n\nAs of Python 3.3 it is possible again to prefix string literals with a\n"u" prefix to simplify maintenance of dual 2.x and 3.x codebases.\n\nBoth string and bytes literals may optionally be prefixed with a\nletter "\'r\'" or "\'R\'"; such strings are called *raw strings* and treat\nbackslashes as literal characters. As a result, in string literals,\n"\'\\U\'" and "\'\\u\'" escapes in raw strings are not treated specially.\nGiven that Python 2.x\'s raw unicode literals behave differently than\nPython 3.x\'s the "\'ur\'" syntax is not supported.\n\nNew in version 3.3: The "\'rb\'" prefix of raw bytes literals has been\nadded as a synonym of "\'br\'".\n\nNew in version 3.3: Support for the unicode legacy literal\n("u\'value\'") was reintroduced to simplify the maintenance of dual\nPython 2.x and 3.x codebases. See **PEP 414** for more information.\n\nIn triple-quoted literals, unescaped newlines and quotes are allowed\n(and are retained), except that three unescaped quotes in a row\nterminate the literal. (A "quote" is the character used to open the\nliteral, i.e. either "\'" or """.)\n\nUnless an "\'r\'" or "\'R\'" prefix is present, escape sequences in string\nand bytes literals are interpreted according to rules similar to those\nused by Standard C. The recognized escape sequences are:\n\n+-------------------+-----------------------------------+---------+\n| Escape Sequence | Meaning | Notes |\n+===================+===================================+=========+\n| "\\newline" | Backslash and newline ignored | |\n+-------------------+-----------------------------------+---------+\n| "\\\\" | Backslash ("\\") | |\n+-------------------+-----------------------------------+---------+\n| "\\\'" | Single quote ("\'") | |\n+-------------------+-----------------------------------+---------+\n| "\\"" | Double quote (""") | |\n+-------------------+-----------------------------------+---------+\n| "\\a" | ASCII Bell (BEL) | |\n+-------------------+-----------------------------------+---------+\n| "\\b" | ASCII Backspace (BS) | |\n+-------------------+-----------------------------------+---------+\n| "\\f" | ASCII Formfeed (FF) | |\n+-------------------+-----------------------------------+---------+\n| "\\n" | ASCII Linefeed (LF) | |\n+-------------------+-----------------------------------+---------+\n| "\\r" | ASCII Carriage Return (CR) | |\n+-------------------+-----------------------------------+---------+\n| "\\t" | ASCII Horizontal Tab (TAB) | |\n+-------------------+-----------------------------------+---------+\n| "\\v" | ASCII Vertical Tab (VT) | |\n+-------------------+-----------------------------------+---------+\n| "\\ooo" | Character with octal value *ooo* | (1,3) |\n+-------------------+-----------------------------------+---------+\n| "\\xhh" | Character with hex value *hh* | (2,3) |\n+-------------------+-----------------------------------+---------+\n\nEscape sequences only recognized in string literals are:\n\n+-------------------+-----------------------------------+---------+\n| Escape Sequence | Meaning | Notes |\n+===================+===================================+=========+\n| "\\N{name}" | Character named *name* in the | (4) |\n| | Unicode database | |\n+-------------------+-----------------------------------+---------+\n| "\\uxxxx" | Character with 16-bit hex value | (5) |\n| | *xxxx* | |\n+-------------------+-----------------------------------+---------+\n| "\\Uxxxxxxxx" | Character with 32-bit hex value | (6) |\n| | *xxxxxxxx* | |\n+-------------------+-----------------------------------+---------+\n\nNotes:\n\n1. As in Standard C, up to three octal digits are accepted.\n\n2. Unlike in Standard C, exactly two hex digits are required.\n\n3. In a bytes literal, hexadecimal and octal escapes denote the\n byte with the given value. In a string literal, these escapes\n denote a Unicode character with the given value.\n\n4. Changed in version 3.3: Support for name aliases [1] has been\n added.\n\n5. Individual code units which form parts of a surrogate pair can\n be encoded using this escape sequence. Exactly four hex digits are\n required.\n\n6. Any Unicode character can be encoded this way. Exactly eight\n hex digits are required.\n\nUnlike Standard C, all unrecognized escape sequences are left in the\nstring unchanged, i.e., *the backslash is left in the result*. (This\nbehavior is useful when debugging: if an escape sequence is mistyped,\nthe resulting output is more easily recognized as broken.) It is also\nimportant to note that the escape sequences only recognized in string\nliterals fall into the category of unrecognized escapes for bytes\nliterals.\n\nEven in a raw literal, quotes can be escaped with a backslash, but the\nbackslash remains in the result; for example, "r"\\""" is a valid\nstring literal consisting of two characters: a backslash and a double\nquote; "r"\\"" is not a valid string literal (even a raw string cannot\nend in an odd number of backslashes). Specifically, *a raw literal\ncannot end in a single backslash* (since the backslash would escape\nthe following quote character). Note also that a single backslash\nfollowed by a newline is interpreted as those two characters as part\nof the literal, *not* as a line continuation.\n', + 'subscriptions': u'\nSubscriptions\n*************\n\nA subscription selects an item of a sequence (string, tuple or list)\nor mapping (dictionary) object:\n\n subscription ::= primary "[" expression_list "]"\n\nThe primary must evaluate to an object that supports subscription\n(lists or dictionaries for example). User-defined objects can support\nsubscription by defining a "__getitem__()" method.\n\nFor built-in objects, there are two types of objects that support\nsubscription:\n\nIf the primary is a mapping, the expression list must evaluate to an\nobject whose value is one of the keys of the mapping, and the\nsubscription selects the value in the mapping that corresponds to that\nkey. (The expression list is a tuple except if it has exactly one\nitem.)\n\nIf the primary is a sequence, the expression (list) must evaluate to\nan integer or a slice (as discussed in the following section).\n\nThe formal syntax makes no special provision for negative indices in\nsequences; however, built-in sequences all provide a "__getitem__()"\nmethod that interprets negative indices by adding the length of the\nsequence to the index (so that "x[-1]" selects the last item of "x").\nThe resulting value must be a nonnegative integer less than the number\nof items in the sequence, and the subscription selects the item whose\nindex is that value (counting from zero). Since the support for\nnegative indices and slicing occurs in the object\'s "__getitem__()"\nmethod, subclasses overriding this method will need to explicitly add\nthat support.\n\nA string\'s items are characters. A character is not a separate data\ntype but a string of exactly one character.\n', + 'truth': u'\nTruth Value Testing\n*******************\n\nAny object can be tested for truth value, for use in an "if" or\n"while" condition or as operand of the Boolean operations below. The\nfollowing values are considered false:\n\n* "None"\n\n* "False"\n\n* zero of any numeric type, for example, "0", "0.0", "0j".\n\n* any empty sequence, for example, "\'\'", "()", "[]".\n\n* any empty mapping, for example, "{}".\n\n* instances of user-defined classes, if the class defines a\n "__bool__()" or "__len__()" method, when that method returns the\n integer zero or "bool" value "False". [1]\n\nAll other values are considered true --- so objects of many types are\nalways true.\n\nOperations and built-in functions that have a Boolean result always\nreturn "0" or "False" for false and "1" or "True" for true, unless\notherwise stated. (Important exception: the Boolean operations "or"\nand "and" always return one of their operands.)\n', + 'try': u'\nThe "try" statement\n*******************\n\nThe "try" statement specifies exception handlers and/or cleanup code\nfor a group of statements:\n\n try_stmt ::= try1_stmt | try2_stmt\n try1_stmt ::= "try" ":" suite\n ("except" [expression ["as" identifier]] ":" suite)+\n ["else" ":" suite]\n ["finally" ":" suite]\n try2_stmt ::= "try" ":" suite\n "finally" ":" suite\n\nThe "except" clause(s) specify one or more exception handlers. When no\nexception occurs in the "try" clause, no exception handler is\nexecuted. When an exception occurs in the "try" suite, a search for an\nexception handler is started. This search inspects the except clauses\nin turn until one is found that matches the exception. An expression-\nless except clause, if present, must be last; it matches any\nexception. For an except clause with an expression, that expression\nis evaluated, and the clause matches the exception if the resulting\nobject is "compatible" with the exception. An object is compatible\nwith an exception if it is the class or a base class of the exception\nobject or a tuple containing an item compatible with the exception.\n\nIf no except clause matches the exception, the search for an exception\nhandler continues in the surrounding code and on the invocation stack.\n[1]\n\nIf the evaluation of an expression in the header of an except clause\nraises an exception, the original search for a handler is canceled and\na search starts for the new exception in the surrounding code and on\nthe call stack (it is treated as if the entire "try" statement raised\nthe exception).\n\nWhen a matching except clause is found, the exception is assigned to\nthe target specified after the "as" keyword in that except clause, if\npresent, and the except clause\'s suite is executed. All except\nclauses must have an executable block. When the end of this block is\nreached, execution continues normally after the entire try statement.\n(This means that if two nested handlers exist for the same exception,\nand the exception occurs in the try clause of the inner handler, the\nouter handler will not handle the exception.)\n\nWhen an exception has been assigned using "as target", it is cleared\nat the end of the except clause. This is as if\n\n except E as N:\n foo\n\nwas translated to\n\n except E as N:\n try:\n foo\n finally:\n del N\n\nThis means the exception must be assigned to a different name to be\nable to refer to it after the except clause. Exceptions are cleared\nbecause with the traceback attached to them, they form a reference\ncycle with the stack frame, keeping all locals in that frame alive\nuntil the next garbage collection occurs.\n\nBefore an except clause\'s suite is executed, details about the\nexception are stored in the "sys" module and can be accessed via\n"sys.exc_info()". "sys.exc_info()" returns a 3-tuple consisting of the\nexception class, the exception instance and a traceback object (see\nsection *The standard type hierarchy*) identifying the point in the\nprogram where the exception occurred. "sys.exc_info()" values are\nrestored to their previous values (before the call) when returning\nfrom a function that handled an exception.\n\nThe optional "else" clause is executed if and when control flows off\nthe end of the "try" clause. [2] Exceptions in the "else" clause are\nnot handled by the preceding "except" clauses.\n\nIf "finally" is present, it specifies a \'cleanup\' handler. The "try"\nclause is executed, including any "except" and "else" clauses. If an\nexception occurs in any of the clauses and is not handled, the\nexception is temporarily saved. The "finally" clause is executed. If\nthere is a saved exception it is re-raised at the end of the "finally"\nclause. If the "finally" clause raises another exception, the saved\nexception is set as the context of the new exception. If the "finally"\nclause executes a "return" or "break" statement, the saved exception\nis discarded:\n\n >>> def f():\n ... try:\n ... 1/0\n ... finally:\n ... return 42\n ...\n >>> f()\n 42\n\nThe exception information is not available to the program during\nexecution of the "finally" clause.\n\nWhen a "return", "break" or "continue" statement is executed in the\n"try" suite of a "try"..."finally" statement, the "finally" clause is\nalso executed \'on the way out.\' A "continue" statement is illegal in\nthe "finally" clause. (The reason is a problem with the current\nimplementation --- this restriction may be lifted in the future).\n\nThe return value of a function is determined by the last "return"\nstatement executed. Since the "finally" clause always executes, a\n"return" statement executed in the "finally" clause will always be the\nlast one executed:\n\n >>> def foo():\n ... try:\n ... return \'try\'\n ... finally:\n ... return \'finally\'\n ...\n >>> foo()\n \'finally\'\n\nAdditional information on exceptions can be found in section\n*Exceptions*, and information on using the "raise" statement to\ngenerate exceptions may be found in section *The raise statement*.\n', + 'types': u'\nThe standard type hierarchy\n***************************\n\nBelow is a list of the types that are built into Python. Extension\nmodules (written in C, Java, or other languages, depending on the\nimplementation) can define additional types. Future versions of\nPython may add types to the type hierarchy (e.g., rational numbers,\nefficiently stored arrays of integers, etc.), although such additions\nwill often be provided via the standard library instead.\n\nSome of the type descriptions below contain a paragraph listing\n\'special attributes.\' These are attributes that provide access to the\nimplementation and are not intended for general use. Their definition\nmay change in the future.\n\nNone\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name "None". It\n is used to signify the absence of a value in many situations, e.g.,\n it is returned from functions that don\'t explicitly return\n anything. Its truth value is false.\n\nNotImplemented\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name\n "NotImplemented". Numeric methods and rich comparison methods\n should return this value if they do not implement the operation for\n the operands provided. (The interpreter will then try the\n reflected operation, or some other fallback, depending on the\n operator.) Its truth value is true.\n\n See *Implementing the arithmetic operations* for more details.\n\nEllipsis\n This type has a single value. There is a single object with this\n value. This object is accessed through the literal "..." or the\n built-in name "Ellipsis". Its truth value is true.\n\n"numbers.Number"\n These are created by numeric literals and returned as results by\n arithmetic operators and arithmetic built-in functions. Numeric\n objects are immutable; once created their value never changes.\n Python numbers are of course strongly related to mathematical\n numbers, but subject to the limitations of numerical representation\n in computers.\n\n Python distinguishes between integers, floating point numbers, and\n complex numbers:\n\n "numbers.Integral"\n These represent elements from the mathematical set of integers\n (positive and negative).\n\n There are two types of integers:\n\n Integers ("int")\n\n These represent numbers in an unlimited range, subject to\n available (virtual) memory only. For the purpose of shift\n and mask operations, a binary representation is assumed, and\n negative numbers are represented in a variant of 2\'s\n complement which gives the illusion of an infinite string of\n sign bits extending to the left.\n\n Booleans ("bool")\n These represent the truth values False and True. The two\n objects representing the values "False" and "True" are the\n only Boolean objects. The Boolean type is a subtype of the\n integer type, and Boolean values behave like the values 0 and\n 1, respectively, in almost all contexts, the exception being\n that when converted to a string, the strings ""False"" or\n ""True"" are returned, respectively.\n\n The rules for integer representation are intended to give the\n most meaningful interpretation of shift and mask operations\n involving negative integers.\n\n "numbers.Real" ("float")\n These represent machine-level double precision floating point\n numbers. You are at the mercy of the underlying machine\n architecture (and C or Java implementation) for the accepted\n range and handling of overflow. Python does not support single-\n precision floating point numbers; the savings in processor and\n memory usage that are usually the reason for using these are\n dwarfed by the overhead of using objects in Python, so there is\n no reason to complicate the language with two kinds of floating\n point numbers.\n\n "numbers.Complex" ("complex")\n These represent complex numbers as a pair of machine-level\n double precision floating point numbers. The same caveats apply\n as for floating point numbers. The real and imaginary parts of a\n complex number "z" can be retrieved through the read-only\n attributes "z.real" and "z.imag".\n\nSequences\n These represent finite ordered sets indexed by non-negative\n numbers. The built-in function "len()" returns the number of items\n of a sequence. When the length of a sequence is *n*, the index set\n contains the numbers 0, 1, ..., *n*-1. Item *i* of sequence *a* is\n selected by "a[i]".\n\n Sequences also support slicing: "a[i:j]" selects all items with\n index *k* such that *i* "<=" *k* "<" *j*. When used as an\n expression, a slice is a sequence of the same type. This implies\n that the index set is renumbered so that it starts at 0.\n\n Some sequences also support "extended slicing" with a third "step"\n parameter: "a[i:j:k]" selects all items of *a* with index *x* where\n "x = i + n*k", *n* ">=" "0" and *i* "<=" *x* "<" *j*.\n\n Sequences are distinguished according to their mutability:\n\n Immutable sequences\n An object of an immutable sequence type cannot change once it is\n created. (If the object contains references to other objects,\n these other objects may be mutable and may be changed; however,\n the collection of objects directly referenced by an immutable\n object cannot change.)\n\n The following types are immutable sequences:\n\n Strings\n A string is a sequence of values that represent Unicode code\n points. All the code points in the range "U+0000 - U+10FFFF"\n can be represented in a string. Python doesn\'t have a "char"\n type; instead, every code point in the string is represented\n as a string object with length "1". The built-in function\n "ord()" converts a code point from its string form to an\n integer in the range "0 - 10FFFF"; "chr()" converts an\n integer in the range "0 - 10FFFF" to the corresponding length\n "1" string object. "str.encode()" can be used to convert a\n "str" to "bytes" using the given text encoding, and\n "bytes.decode()" can be used to achieve the opposite.\n\n Tuples\n The items of a tuple are arbitrary Python objects. Tuples of\n two or more items are formed by comma-separated lists of\n expressions. A tuple of one item (a \'singleton\') can be\n formed by affixing a comma to an expression (an expression by\n itself does not create a tuple, since parentheses must be\n usable for grouping of expressions). An empty tuple can be\n formed by an empty pair of parentheses.\n\n Bytes\n A bytes object is an immutable array. The items are 8-bit\n bytes, represented by integers in the range 0 <= x < 256.\n Bytes literals (like "b\'abc\'") and the built-in function\n "bytes()" can be used to construct bytes objects. Also,\n bytes objects can be decoded to strings via the "decode()"\n method.\n\n Mutable sequences\n Mutable sequences can be changed after they are created. The\n subscription and slicing notations can be used as the target of\n assignment and "del" (delete) statements.\n\n There are currently two intrinsic mutable sequence types:\n\n Lists\n The items of a list are arbitrary Python objects. Lists are\n formed by placing a comma-separated list of expressions in\n square brackets. (Note that there are no special cases needed\n to form lists of length 0 or 1.)\n\n Byte Arrays\n A bytearray object is a mutable array. They are created by\n the built-in "bytearray()" constructor. Aside from being\n mutable (and hence unhashable), byte arrays otherwise provide\n the same interface and functionality as immutable bytes\n objects.\n\n The extension module "array" provides an additional example of a\n mutable sequence type, as does the "collections" module.\n\nSet types\n These represent unordered, finite sets of unique, immutable\n objects. As such, they cannot be indexed by any subscript. However,\n they can be iterated over, and the built-in function "len()"\n returns the number of items in a set. Common uses for sets are fast\n membership testing, removing duplicates from a sequence, and\n computing mathematical operations such as intersection, union,\n difference, and symmetric difference.\n\n For set elements, the same immutability rules apply as for\n dictionary keys. Note that numeric types obey the normal rules for\n numeric comparison: if two numbers compare equal (e.g., "1" and\n "1.0"), only one of them can be contained in a set.\n\n There are currently two intrinsic set types:\n\n Sets\n These represent a mutable set. They are created by the built-in\n "set()" constructor and can be modified afterwards by several\n methods, such as "add()".\n\n Frozen sets\n These represent an immutable set. They are created by the\n built-in "frozenset()" constructor. As a frozenset is immutable\n and *hashable*, it can be used again as an element of another\n set, or as a dictionary key.\n\nMappings\n These represent finite sets of objects indexed by arbitrary index\n sets. The subscript notation "a[k]" selects the item indexed by "k"\n from the mapping "a"; this can be used in expressions and as the\n target of assignments or "del" statements. The built-in function\n "len()" returns the number of items in a mapping.\n\n There is currently a single intrinsic mapping type:\n\n Dictionaries\n These represent finite sets of objects indexed by nearly\n arbitrary values. The only types of values not acceptable as\n keys are values containing lists or dictionaries or other\n mutable types that are compared by value rather than by object\n identity, the reason being that the efficient implementation of\n dictionaries requires a key\'s hash value to remain constant.\n Numeric types used for keys obey the normal rules for numeric\n comparison: if two numbers compare equal (e.g., "1" and "1.0")\n then they can be used interchangeably to index the same\n dictionary entry.\n\n Dictionaries are mutable; they can be created by the "{...}"\n notation (see section *Dictionary displays*).\n\n The extension modules "dbm.ndbm" and "dbm.gnu" provide\n additional examples of mapping types, as does the "collections"\n module.\n\nCallable types\n These are the types to which the function call operation (see\n section *Calls*) can be applied:\n\n User-defined functions\n A user-defined function object is created by a function\n definition (see section *Function definitions*). It should be\n called with an argument list containing the same number of items\n as the function\'s formal parameter list.\n\n Special attributes:\n\n +---------------------------+---------------------------------+-------------+\n | Attribute | Meaning | |\n +===========================+=================================+=============+\n | "__doc__" | The function\'s documentation | Writable |\n | | string, or "None" if | |\n | | unavailable; not inherited by | |\n | | subclasses | |\n +---------------------------+---------------------------------+-------------+\n | "__name__" | The function\'s name | Writable |\n +---------------------------+---------------------------------+-------------+\n | "__qualname__" | The function\'s *qualified name* | Writable |\n | | New in version 3.3. | |\n +---------------------------+---------------------------------+-------------+\n | "__module__" | The name of the module the | Writable |\n | | function was defined in, or | |\n | | "None" if unavailable. | |\n +---------------------------+---------------------------------+-------------+\n | "__defaults__" | A tuple containing default | Writable |\n | | argument values for those | |\n | | arguments that have defaults, | |\n | | or "None" if no arguments have | |\n | | a default value | |\n +---------------------------+---------------------------------+-------------+\n | "__code__" | The code object representing | Writable |\n | | the compiled function body. | |\n +---------------------------+---------------------------------+-------------+\n | "__globals__" | A reference to the dictionary | Read-only |\n | | that holds the function\'s | |\n | | global variables --- the global | |\n | | namespace of the module in | |\n | | which the function was defined. | |\n +---------------------------+---------------------------------+-------------+\n | "__dict__" | The namespace supporting | Writable |\n | | arbitrary function attributes. | |\n +---------------------------+---------------------------------+-------------+\n | "__closure__" | "None" or a tuple of cells that | Read-only |\n | | contain bindings for the | |\n | | function\'s free variables. | |\n +---------------------------+---------------------------------+-------------+\n | "__annotations__" | A dict containing annotations | Writable |\n | | of parameters. The keys of the | |\n | | dict are the parameter names, | |\n | | and "\'return\'" for the return | |\n | | annotation, if provided. | |\n +---------------------------+---------------------------------+-------------+\n | "__kwdefaults__" | A dict containing defaults for | Writable |\n | | keyword-only parameters. | |\n +---------------------------+---------------------------------+-------------+\n\n Most of the attributes labelled "Writable" check the type of the\n assigned value.\n\n Function objects also support getting and setting arbitrary\n attributes, which can be used, for example, to attach metadata\n to functions. Regular attribute dot-notation is used to get and\n set such attributes. *Note that the current implementation only\n supports function attributes on user-defined functions. Function\n attributes on built-in functions may be supported in the\n future.*\n\n Additional information about a function\'s definition can be\n retrieved from its code object; see the description of internal\n types below.\n\n Instance methods\n An instance method object combines a class, a class instance and\n any callable object (normally a user-defined function).\n\n Special read-only attributes: "__self__" is the class instance\n object, "__func__" is the function object; "__doc__" is the\n method\'s documentation (same as "__func__.__doc__"); "__name__"\n is the method name (same as "__func__.__name__"); "__module__"\n is the name of the module the method was defined in, or "None"\n if unavailable.\n\n Methods also support accessing (but not setting) the arbitrary\n function attributes on the underlying function object.\n\n User-defined method objects may be created when getting an\n attribute of a class (perhaps via an instance of that class), if\n that attribute is a user-defined function object or a class\n method object.\n\n When an instance method object is created by retrieving a user-\n defined function object from a class via one of its instances,\n its "__self__" attribute is the instance, and the method object\n is said to be bound. The new method\'s "__func__" attribute is\n the original function object.\n\n When a user-defined method object is created by retrieving\n another method object from a class or instance, the behaviour is\n the same as for a function object, except that the "__func__"\n attribute of the new instance is not the original method object\n but its "__func__" attribute.\n\n When an instance method object is created by retrieving a class\n method object from a class or instance, its "__self__" attribute\n is the class itself, and its "__func__" attribute is the\n function object underlying the class method.\n\n When an instance method object is called, the underlying\n function ("__func__") is called, inserting the class instance\n ("__self__") in front of the argument list. For instance, when\n "C" is a class which contains a definition for a function "f()",\n and "x" is an instance of "C", calling "x.f(1)" is equivalent to\n calling "C.f(x, 1)".\n\n When an instance method object is derived from a class method\n object, the "class instance" stored in "__self__" will actually\n be the class itself, so that calling either "x.f(1)" or "C.f(1)"\n is equivalent to calling "f(C,1)" where "f" is the underlying\n function.\n\n Note that the transformation from function object to instance\n method object happens each time the attribute is retrieved from\n the instance. In some cases, a fruitful optimization is to\n assign the attribute to a local variable and call that local\n variable. Also notice that this transformation only happens for\n user-defined functions; other callable objects (and all non-\n callable objects) are retrieved without transformation. It is\n also important to note that user-defined functions which are\n attributes of a class instance are not converted to bound\n methods; this *only* happens when the function is an attribute\n of the class.\n\n Generator functions\n A function or method which uses the "yield" statement (see\n section *The yield statement*) is called a *generator function*.\n Such a function, when called, always returns an iterator object\n which can be used to execute the body of the function: calling\n the iterator\'s "iterator.__next__()" method will cause the\n function to execute until it provides a value using the "yield"\n statement. When the function executes a "return" statement or\n falls off the end, a "StopIteration" exception is raised and the\n iterator will have reached the end of the set of values to be\n returned.\n\n Built-in functions\n A built-in function object is a wrapper around a C function.\n Examples of built-in functions are "len()" and "math.sin()"\n ("math" is a standard built-in module). The number and type of\n the arguments are determined by the C function. Special read-\n only attributes: "__doc__" is the function\'s documentation\n string, or "None" if unavailable; "__name__" is the function\'s\n name; "__self__" is set to "None" (but see the next item);\n "__module__" is the name of the module the function was defined\n in or "None" if unavailable.\n\n Built-in methods\n This is really a different disguise of a built-in function, this\n time containing an object passed to the C function as an\n implicit extra argument. An example of a built-in method is\n "alist.append()", assuming *alist* is a list object. In this\n case, the special read-only attribute "__self__" is set to the\n object denoted by *alist*.\n\n Classes\n Classes are callable. These objects normally act as factories\n for new instances of themselves, but variations are possible for\n class types that override "__new__()". The arguments of the\n call are passed to "__new__()" and, in the typical case, to\n "__init__()" to initialize the new instance.\n\n Class Instances\n Instances of arbitrary classes can be made callable by defining\n a "__call__()" method in their class.\n\nModules\n Modules are a basic organizational unit of Python code, and are\n created by the *import system* as invoked either by the "import"\n statement (see "import"), or by calling functions such as\n "importlib.import_module()" and built-in "__import__()". A module\n object has a namespace implemented by a dictionary object (this is\n the dictionary referenced by the "__globals__" attribute of\n functions defined in the module). Attribute references are\n translated to lookups in this dictionary, e.g., "m.x" is equivalent\n to "m.__dict__["x"]". A module object does not contain the code\n object used to initialize the module (since it isn\'t needed once\n the initialization is done).\n\n Attribute assignment updates the module\'s namespace dictionary,\n e.g., "m.x = 1" is equivalent to "m.__dict__["x"] = 1".\n\n Special read-only attribute: "__dict__" is the module\'s namespace\n as a dictionary object.\n\n **CPython implementation detail:** Because of the way CPython\n clears module dictionaries, the module dictionary will be cleared\n when the module falls out of scope even if the dictionary still has\n live references. To avoid this, copy the dictionary or keep the\n module around while using its dictionary directly.\n\n Predefined (writable) attributes: "__name__" is the module\'s name;\n "__doc__" is the module\'s documentation string, or "None" if\n unavailable; "__file__" is the pathname of the file from which the\n module was loaded, if it was loaded from a file. The "__file__"\n attribute may be missing for certain types of modules, such as C\n modules that are statically linked into the interpreter; for\n extension modules loaded dynamically from a shared library, it is\n the pathname of the shared library file.\n\nCustom classes\n Custom class types are typically created by class definitions (see\n section *Class definitions*). A class has a namespace implemented\n by a dictionary object. Class attribute references are translated\n to lookups in this dictionary, e.g., "C.x" is translated to\n "C.__dict__["x"]" (although there are a number of hooks which allow\n for other means of locating attributes). When the attribute name is\n not found there, the attribute search continues in the base\n classes. This search of the base classes uses the C3 method\n resolution order which behaves correctly even in the presence of\n \'diamond\' inheritance structures where there are multiple\n inheritance paths leading back to a common ancestor. Additional\n details on the C3 MRO used by Python can be found in the\n documentation accompanying the 2.3 release at\n https://www.python.org/download/releases/2.3/mro/.\n\n When a class attribute reference (for class "C", say) would yield a\n class method object, it is transformed into an instance method\n object whose "__self__" attributes is "C". When it would yield a\n static method object, it is transformed into the object wrapped by\n the static method object. See section *Implementing Descriptors*\n for another way in which attributes retrieved from a class may\n differ from those actually contained in its "__dict__".\n\n Class attribute assignments update the class\'s dictionary, never\n the dictionary of a base class.\n\n A class object can be called (see above) to yield a class instance\n (see below).\n\n Special attributes: "__name__" is the class name; "__module__" is\n the module name in which the class was defined; "__dict__" is 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\nClass instances\n A class instance is created by calling a class object (see above).\n A class instance has a namespace implemented as a dictionary which\n is the first place in which attribute references are searched.\n When an attribute is not found there, and the instance\'s class has\n an attribute by that name, the search continues with the class\n attributes. If a class attribute is found that is a user-defined\n function object, it is transformed into an instance method object\n whose "__self__" attribute is the instance. Static method and\n class method objects are also transformed; see above under\n "Classes". See section *Implementing Descriptors* for another way\n in which attributes of a class retrieved via its instances may\n differ from the objects actually stored in the class\'s "__dict__".\n If no class attribute is found, and the object\'s class has a\n "__getattr__()" method, that is called to satisfy the lookup.\n\n Attribute assignments and deletions update the instance\'s\n dictionary, never a class\'s dictionary. If the class has a\n "__setattr__()" or "__delattr__()" method, this is called instead\n of updating the instance dictionary directly.\n\n Class instances can pretend to be numbers, sequences, or mappings\n if they have methods with certain special names. See section\n *Special method names*.\n\n Special attributes: "__dict__" is the attribute dictionary;\n "__class__" is the instance\'s class.\n\nI/O objects (also known as file objects)\n A *file object* represents an open file. Various shortcuts are\n available to create file objects: the "open()" built-in function,\n and also "os.popen()", "os.fdopen()", and the "makefile()" method\n of socket objects (and perhaps by other functions or methods\n provided by extension modules).\n\n The objects "sys.stdin", "sys.stdout" and "sys.stderr" are\n initialized to file objects corresponding to the interpreter\'s\n standard input, output and error streams; they are all open in text\n mode and therefore follow the interface defined by the\n "io.TextIOBase" abstract class.\n\nInternal types\n A few types used internally by the interpreter are exposed to the\n user. Their definitions may change with future versions of the\n interpreter, but they are mentioned here for completeness.\n\n Code objects\n Code objects represent *byte-compiled* executable Python code,\n or *bytecode*. The difference between a code object and a\n function object is that the function object contains an explicit\n reference to the function\'s globals (the module in which it was\n defined), while a code object contains no context; also the\n default argument values are stored in the function object, not\n in the code object (because they represent values calculated at\n run-time). Unlike function objects, code objects are immutable\n and contain no references (directly or indirectly) to mutable\n objects.\n\n Special read-only attributes: "co_name" gives the function name;\n "co_argcount" is the number of positional arguments (including\n arguments with default values); "co_nlocals" is the number of\n local variables used by the function (including arguments);\n "co_varnames" is a tuple containing the names of the local\n variables (starting with the argument names); "co_cellvars" is a\n tuple containing the names of local variables that are\n referenced by nested functions; "co_freevars" is a tuple\n containing the names of free variables; "co_code" is a string\n representing the sequence of bytecode instructions; "co_consts"\n is a tuple containing the literals used by the bytecode;\n "co_names" is a tuple containing the names used by the bytecode;\n "co_filename" is the filename from which the code was compiled;\n "co_firstlineno" is the first line number of the function;\n "co_lnotab" is a string encoding the mapping from bytecode\n offsets to line numbers (for details see the source code of the\n interpreter); "co_stacksize" is the required stack size\n (including local variables); "co_flags" is an integer encoding a\n number of flags for the interpreter.\n\n The following flag bits are defined for "co_flags": bit "0x04"\n is set if the function uses the "*arguments" syntax to accept an\n arbitrary number of positional arguments; bit "0x08" is set if\n the function uses the "**keywords" syntax to accept arbitrary\n keyword arguments; bit "0x20" is set if the function is a\n generator.\n\n Future feature declarations ("from __future__ import division")\n also use bits in "co_flags" to indicate whether a code object\n was compiled with a particular feature enabled: bit "0x2000" is\n set if the function was compiled with future division enabled;\n bits "0x10" and "0x1000" were used in earlier versions of\n Python.\n\n Other bits in "co_flags" are reserved for internal use.\n\n If a code object represents a function, the first item in\n "co_consts" is the documentation string of the function, or\n "None" if undefined.\n\n Frame objects\n Frame objects represent execution frames. They may occur in\n traceback objects (see below).\n\n Special read-only attributes: "f_back" is to the previous stack\n frame (towards the caller), or "None" if this is the bottom\n stack frame; "f_code" is the code object being executed in this\n frame; "f_locals" is the dictionary used to look up local\n variables; "f_globals" is used for global variables;\n "f_builtins" is used for built-in (intrinsic) names; "f_lasti"\n gives the precise instruction (this is an index into the\n bytecode string of the code object).\n\n Special writable attributes: "f_trace", if not "None", is a\n function called at the start of each source code line (this is\n used by the debugger); "f_lineno" is the current line number of\n the frame --- writing to this from within a trace function jumps\n to the given line (only for the bottom-most frame). A debugger\n can implement a Jump command (aka Set Next Statement) by writing\n to f_lineno.\n\n Frame objects support one method:\n\n frame.clear()\n\n This method clears all references to local variables held by\n the frame. Also, if the frame belonged to a generator, the\n generator is finalized. This helps break reference cycles\n involving frame objects (for example when catching an\n exception and storing its traceback for later use).\n\n "RuntimeError" is raised if the frame is currently executing.\n\n New in version 3.4.\n\n Traceback objects\n Traceback objects represent a stack trace of an exception. A\n traceback object is created when an exception occurs. When the\n search for an exception handler unwinds the execution stack, at\n each unwound level a traceback object is inserted in front of\n the current traceback. When an exception handler is entered,\n the stack trace is made available to the program. (See section\n *The try statement*.) It is accessible as the third item of the\n tuple returned by "sys.exc_info()". When the program contains no\n suitable handler, the stack trace is written (nicely formatted)\n to the standard error stream; if the interpreter is interactive,\n it is also made available to the user as "sys.last_traceback".\n\n Special read-only attributes: "tb_next" is the next level in the\n stack trace (towards the frame where the exception occurred), or\n "None" if there is no next level; "tb_frame" points to the\n execution frame of the current level; "tb_lineno" gives the line\n number where the exception occurred; "tb_lasti" indicates the\n precise instruction. The line number and last instruction in\n the traceback may differ from the line number of its frame\n object if the exception occurred in a "try" statement with no\n matching except clause or with a finally clause.\n\n Slice objects\n Slice objects are used to represent slices for "__getitem__()"\n methods. They are also created by the built-in "slice()"\n function.\n\n Special read-only attributes: "start" is the lower bound; "stop"\n is the upper bound; "step" is the step value; each is "None" if\n omitted. These attributes can have any type.\n\n Slice objects support one method:\n\n slice.indices(self, length)\n\n This method takes a single integer argument *length* and\n computes information about the slice that the slice object\n would describe if applied to a sequence of *length* items.\n It returns a tuple of three integers; respectively these are\n the *start* and *stop* indices and the *step* or stride\n length of the slice. Missing or out-of-bounds indices are\n handled in a manner consistent with regular slices.\n\n Static method objects\n Static method objects provide a way of defeating the\n transformation of function objects to method objects described\n above. A static method object is a wrapper around any other\n object, usually a user-defined method object. When a static\n method object is retrieved from a class or a class instance, the\n object actually returned is the wrapped object, which is not\n subject to any further transformation. Static method objects are\n not themselves callable, although the objects they wrap usually\n are. Static method objects are created by the built-in\n "staticmethod()" constructor.\n\n Class method objects\n A class method object, like a static method object, is a wrapper\n around another object that alters the way in which that object\n is retrieved from classes and class instances. The behaviour of\n class method objects upon such retrieval is described above,\n under "User-defined methods". Class method objects are created\n by the built-in "classmethod()" constructor.\n', + 'typesfunctions': u'\nFunctions\n*********\n\nFunction objects are created by function definitions. The only\noperation on a function object is to call it: "func(argument-list)".\n\nThere are really two flavors of function objects: built-in functions\nand user-defined functions. Both support the same operation (to call\nthe function), but the implementation is different, hence the\ndifferent object types.\n\nSee *Function definitions* for more information.\n', + 'typesmapping': u'\nMapping Types --- "dict"\n************************\n\nA *mapping* object maps *hashable* values to arbitrary objects.\nMappings are mutable objects. There is currently only one standard\nmapping type, the *dictionary*. (For other containers see the built-\nin "list", "set", and "tuple" classes, and the "collections" module.)\n\nA dictionary\'s keys are *almost* arbitrary values. Values that are\nnot *hashable*, that is, values containing lists, dictionaries or\nother mutable types (that are compared by value rather than by object\nidentity) may not be used as keys. Numeric types used for keys obey\nthe normal rules for numeric comparison: if two numbers compare equal\n(such as "1" and "1.0") then they can be used interchangeably to index\nthe same dictionary entry. (Note however, that since computers store\nfloating-point numbers as approximations it is usually unwise to use\nthem as dictionary keys.)\n\nDictionaries can be created by placing a comma-separated list of "key:\nvalue" pairs within braces, for example: "{\'jack\': 4098, \'sjoerd\':\n4127}" or "{4098: \'jack\', 4127: \'sjoerd\'}", or by the "dict"\nconstructor.\n\nclass class dict(**kwarg)\nclass class dict(mapping, **kwarg)\nclass class dict(iterable, **kwarg)\n\n Return a new dictionary initialized from an optional positional\n argument and a possibly empty set of keyword arguments.\n\n If no positional argument is given, an empty dictionary is created.\n If a positional argument is given and it is a mapping object, a\n dictionary is created with the same key-value pairs as the mapping\n object. Otherwise, the positional argument must be an *iterable*\n object. Each item in the iterable must itself be an iterable with\n exactly two objects. The first object of each item becomes a key\n in the new dictionary, and the second object the corresponding\n value. If a key occurs more than once, the last value for that key\n becomes the corresponding value in the new dictionary.\n\n If keyword arguments are given, the keyword arguments and their\n values are added to the dictionary created from the positional\n argument. If a key being added is already present, the value from\n the keyword argument replaces the value from the positional\n argument.\n\n To illustrate, the following examples all return a dictionary equal\n to "{"one": 1, "two": 2, "three": 3}":\n\n >>> a = dict(one=1, two=2, three=3)\n >>> b = {\'one\': 1, \'two\': 2, \'three\': 3}\n >>> c = dict(zip([\'one\', \'two\', \'three\'], [1, 2, 3]))\n >>> d = dict([(\'two\', 2), (\'one\', 1), (\'three\', 3)])\n >>> e = dict({\'three\': 3, \'one\': 1, \'two\': 2})\n >>> a == b == c == d == e\n True\n\n Providing keyword arguments as in the first example only works for\n keys that are valid Python identifiers. Otherwise, any valid keys\n can be used.\n\n These are the operations that dictionaries support (and therefore,\n custom mapping types should support too):\n\n len(d)\n\n Return the number of items in the dictionary *d*.\n\n d[key]\n\n Return the item of *d* with key *key*. Raises a "KeyError" if\n *key* is not in the map.\n\n If a subclass of dict defines a method "__missing__()" and *key*\n is not present, the "d[key]" operation calls that method with\n the key *key* as argument. The "d[key]" operation then returns\n or raises whatever is returned or raised by the\n "__missing__(key)" call. No other operations or methods invoke\n "__missing__()". If "__missing__()" is not defined, "KeyError"\n is raised. "__missing__()" must be a method; it cannot be an\n instance variable:\n\n >>> class Counter(dict):\n ... def __missing__(self, key):\n ... return 0\n >>> c = Counter()\n >>> c[\'red\']\n 0\n >>> c[\'red\'] += 1\n >>> c[\'red\']\n 1\n\n The example above shows part of the implementation of\n "collections.Counter". A different "__missing__" method is used\n by "collections.defaultdict".\n\n d[key] = value\n\n Set "d[key]" to *value*.\n\n del d[key]\n\n Remove "d[key]" from *d*. Raises a "KeyError" if *key* is not\n in the map.\n\n key in d\n\n Return "True" if *d* has a key *key*, else "False".\n\n key not in d\n\n Equivalent to "not key in d".\n\n iter(d)\n\n Return an iterator over the keys of the dictionary. This is a\n shortcut for "iter(d.keys())".\n\n clear()\n\n Remove all items from the dictionary.\n\n copy()\n\n Return a shallow copy of the dictionary.\n\n classmethod fromkeys(seq[, value])\n\n Create a new dictionary with keys from *seq* and values set to\n *value*.\n\n "fromkeys()" is a class method that returns a new dictionary.\n *value* defaults to "None".\n\n get(key[, default])\n\n Return the value for *key* if *key* is in the dictionary, else\n *default*. If *default* is not given, it defaults to "None", so\n that this method never raises a "KeyError".\n\n items()\n\n Return a new view of the dictionary\'s items ("(key, value)"\n pairs). See the *documentation of view objects*.\n\n keys()\n\n Return a new view of the dictionary\'s keys. See the\n *documentation of view objects*.\n\n pop(key[, default])\n\n If *key* is in the dictionary, remove it and return its value,\n else return *default*. If *default* is not given and *key* is\n not in the dictionary, a "KeyError" is raised.\n\n popitem()\n\n Remove and return an arbitrary "(key, value)" pair from the\n dictionary.\n\n "popitem()" is useful to destructively iterate over a\n dictionary, as often used in set algorithms. If the dictionary\n is empty, calling "popitem()" raises a "KeyError".\n\n setdefault(key[, default])\n\n If *key* is in the dictionary, return its value. If not, insert\n *key* with a value of *default* and return *default*. *default*\n defaults to "None".\n\n update([other])\n\n Update the dictionary with the key/value pairs from *other*,\n overwriting existing keys. Return "None".\n\n "update()" accepts either another dictionary object or an\n iterable of key/value pairs (as tuples or other iterables of\n length two). If keyword arguments are specified, the dictionary\n is then updated with those key/value pairs: "d.update(red=1,\n blue=2)".\n\n values()\n\n Return a new view of the dictionary\'s values. See the\n *documentation of view objects*.\n\nSee also: "types.MappingProxyType" can be used to create a read-only\n view of a "dict".\n\n\nDictionary view objects\n=======================\n\nThe objects returned by "dict.keys()", "dict.values()" and\n"dict.items()" are *view objects*. They provide a dynamic view on the\ndictionary\'s entries, which means that when the dictionary changes,\nthe view reflects these changes.\n\nDictionary views can be iterated over to yield their respective data,\nand support membership tests:\n\nlen(dictview)\n\n Return the number of entries in the dictionary.\n\niter(dictview)\n\n Return an iterator over the keys, values or items (represented as\n tuples of "(key, value)") in the dictionary.\n\n Keys and values are iterated over in an arbitrary order which is\n non-random, varies across Python implementations, and depends on\n the dictionary\'s history of insertions and deletions. If keys,\n values and items views are iterated over with no intervening\n modifications to the dictionary, the order of items will directly\n correspond. This allows the creation of "(value, key)" pairs using\n "zip()": "pairs = zip(d.values(), d.keys())". Another way to\n create the same list is "pairs = [(v, k) for (k, v) in d.items()]".\n\n Iterating views while adding or deleting entries in the dictionary\n may raise a "RuntimeError" or fail to iterate over all entries.\n\nx in dictview\n\n Return "True" if *x* is in the underlying dictionary\'s keys, values\n or items (in the latter case, *x* should be a "(key, value)"\n tuple).\n\nKeys views are set-like since their entries are unique and hashable.\nIf all values are hashable, so that "(key, value)" pairs are unique\nand hashable, then the items view is also set-like. (Values views are\nnot treated as set-like since the entries are generally not unique.)\nFor set-like views, all of the operations defined for the abstract\nbase class "collections.abc.Set" are available (for example, "==",\n"<", or "^").\n\nAn example of dictionary view usage:\n\n >>> dishes = {\'eggs\': 2, \'sausage\': 1, \'bacon\': 1, \'spam\': 500}\n >>> keys = dishes.keys()\n >>> values = dishes.values()\n\n >>> # iteration\n >>> n = 0\n >>> for val in values:\n ... n += val\n >>> print(n)\n 504\n\n >>> # keys and values are iterated over in the same order\n >>> list(keys)\n [\'eggs\', \'bacon\', \'sausage\', \'spam\']\n >>> list(values)\n [2, 1, 1, 500]\n\n >>> # view objects are dynamic and reflect dict changes\n >>> del dishes[\'eggs\']\n >>> del dishes[\'sausage\']\n >>> list(keys)\n [\'spam\', \'bacon\']\n\n >>> # set operations\n >>> keys & {\'eggs\', \'bacon\', \'salad\'}\n {\'bacon\'}\n >>> keys ^ {\'sausage\', \'juice\'}\n {\'juice\', \'sausage\', \'bacon\', \'spam\'}\n', + 'typesmethods': u'\nMethods\n*******\n\nMethods are functions that are called using the attribute notation.\nThere are two flavors: built-in methods (such as "append()" on lists)\nand class instance methods. Built-in methods are described with the\ntypes that support them.\n\nIf you access a method (a function defined in a class namespace)\nthrough an instance, you get a special object: a *bound method* (also\ncalled *instance method*) object. When called, it will add the "self"\nargument to the argument list. Bound methods have two special read-\nonly attributes: "m.__self__" is the object on which the method\noperates, and "m.__func__" is the function implementing the method.\nCalling "m(arg-1, arg-2, ..., arg-n)" is completely equivalent to\ncalling "m.__func__(m.__self__, arg-1, arg-2, ..., arg-n)".\n\nLike function objects, bound method objects support getting arbitrary\nattributes. However, since method attributes are actually stored on\nthe underlying function object ("meth.__func__"), setting method\nattributes on bound methods is disallowed. Attempting to set an\nattribute on a method results in an "AttributeError" being raised. In\norder to set a method attribute, you need to explicitly set it on the\nunderlying function object:\n\n >>> class C:\n ... def method(self):\n ... pass\n ...\n >>> c = C()\n >>> c.method.whoami = \'my name is method\' # can\'t set on the method\n Traceback (most recent call last):\n File "<stdin>", line 1, in <module>\n AttributeError: \'method\' object has no attribute \'whoami\'\n >>> c.method.__func__.whoami = \'my name is method\'\n >>> c.method.whoami\n \'my name is method\'\n\nSee *The standard type hierarchy* for more information.\n', + 'typesmodules': u'\nModules\n*******\n\nThe only special operation on a module is attribute access: "m.name",\nwhere *m* is a module and *name* accesses a name defined in *m*\'s\nsymbol table. Module attributes can be assigned to. (Note that the\n"import" statement is not, strictly speaking, an operation on a module\nobject; "import foo" does not require a module object named *foo* to\nexist, rather it requires an (external) *definition* for a module\nnamed *foo* somewhere.)\n\nA special attribute of every module is "__dict__". This is the\ndictionary containing the module\'s symbol table. Modifying this\ndictionary will actually change the module\'s symbol table, but direct\nassignment to the "__dict__" attribute is not possible (you can write\n"m.__dict__[\'a\'] = 1", which defines "m.a" to be "1", but you can\'t\nwrite "m.__dict__ = {}"). Modifying "__dict__" directly is not\nrecommended.\n\nModules built into the interpreter are written like this: "<module\n\'sys\' (built-in)>". If loaded from a file, they are written as\n"<module \'os\' from \'/usr/local/lib/pythonX.Y/os.pyc\'>".\n', + 'typesseq': u'\nSequence Types --- "list", "tuple", "range"\n*******************************************\n\nThere are three basic sequence types: lists, tuples, and range\nobjects. Additional sequence types tailored for processing of *binary\ndata* and *text strings* are described in dedicated sections.\n\n\nCommon Sequence Operations\n==========================\n\nThe operations in the following table are supported by most sequence\ntypes, both mutable and immutable. The "collections.abc.Sequence" ABC\nis provided to make it easier to correctly implement these operations\non custom sequence types.\n\nThis table lists the sequence operations sorted in ascending priority.\nIn the table, *s* and *t* are sequences of the same type, *n*, *i*,\n*j* and *k* are integers and *x* is an arbitrary object that meets any\ntype and value restrictions imposed by *s*.\n\nThe "in" and "not in" operations have the same priorities as the\ncomparison operations. The "+" (concatenation) and "*" (repetition)\noperations have the same priority as the corresponding numeric\noperations.\n\n+----------------------------+----------------------------------+------------+\n| Operation | Result | Notes |\n+============================+==================================+============+\n| "x in s" | "True" if an item of *s* is | (1) |\n| | equal to *x*, else "False" | |\n+----------------------------+----------------------------------+------------+\n| "x not in s" | "False" if an item of *s* is | (1) |\n| | equal to *x*, else "True" | |\n+----------------------------+----------------------------------+------------+\n| "s + t" | the concatenation of *s* and *t* | (6)(7) |\n+----------------------------+----------------------------------+------------+\n| "s * n" or "n * s" | *n* shallow copies of *s* | (2)(7) |\n| | concatenated | |\n+----------------------------+----------------------------------+------------+\n| "s[i]" | *i*th item of *s*, origin 0 | (3) |\n+----------------------------+----------------------------------+------------+\n| "s[i:j]" | slice of *s* from *i* to *j* | (3)(4) |\n+----------------------------+----------------------------------+------------+\n| "s[i:j:k]" | slice of *s* from *i* to *j* | (3)(5) |\n| | with step *k* | |\n+----------------------------+----------------------------------+------------+\n| "len(s)" | length of *s* | |\n+----------------------------+----------------------------------+------------+\n| "min(s)" | smallest item of *s* | |\n+----------------------------+----------------------------------+------------+\n| "max(s)" | largest item of *s* | |\n+----------------------------+----------------------------------+------------+\n| "s.index(x[, i[, j]])" | index of the first occurrence of | (8) |\n| | *x* in *s* (at or after index | |\n| | *i* and before index *j*) | |\n+----------------------------+----------------------------------+------------+\n| "s.count(x)" | total number of occurrences of | |\n| | *x* in *s* | |\n+----------------------------+----------------------------------+------------+\n\nSequences of the same type also support comparisons. In particular,\ntuples and lists are compared lexicographically by comparing\ncorresponding elements. This means that to compare equal, every\nelement must compare equal and the two sequences must be of the same\ntype and have the same length. (For full details see *Comparisons* in\nthe language reference.)\n\nNotes:\n\n1. While the "in" and "not in" operations are used only for simple\n containment testing in the general case, some specialised sequences\n (such as "str", "bytes" and "bytearray") also use them for\n subsequence testing:\n\n >>> "gg" in "eggs"\n True\n\n2. Values of *n* less than "0" are treated as "0" (which yields an\n empty sequence of the same type as *s*). Note also that the copies\n are shallow; nested structures are not copied. This often haunts\n new Python programmers; consider:\n\n >>> lists = [[]] * 3\n >>> lists\n [[], [], []]\n >>> lists[0].append(3)\n >>> lists\n [[3], [3], [3]]\n\n What has happened is that "[[]]" is a one-element list containing\n an empty list, so all three elements of "[[]] * 3" are (pointers\n to) this single empty list. Modifying any of the elements of\n "lists" modifies this single list. You can create a list of\n different lists this way:\n\n >>> lists = [[] for i in range(3)]\n >>> lists[0].append(3)\n >>> lists[1].append(5)\n >>> lists[2].append(7)\n >>> lists\n [[3], [5], [7]]\n\n3. If *i* or *j* is negative, the index is relative to the end of\n the string: "len(s) + i" or "len(s) + j" is substituted. But note\n that "-0" is still "0".\n\n4. The slice of *s* from *i* to *j* is defined as the sequence of\n items with index *k* such that "i <= k < j". If *i* or *j* is\n greater than "len(s)", use "len(s)". If *i* is omitted or "None",\n use "0". If *j* is omitted or "None", use "len(s)". If *i* is\n greater than or equal to *j*, the slice is empty.\n\n5. The slice of *s* from *i* to *j* with step *k* is defined as the\n sequence of items with index "x = i + n*k" such that "0 <= n <\n (j-i)/k". In other words, the indices are "i", "i+k", "i+2*k",\n "i+3*k" and so on, stopping when *j* is reached (but never\n including *j*). If *i* or *j* is greater than "len(s)", use\n "len(s)". If *i* or *j* are omitted or "None", they become "end"\n values (which end depends on the sign of *k*). Note, *k* cannot be\n zero. If *k* is "None", it is treated like "1".\n\n6. Concatenating immutable sequences always results in a new\n object. This means that building up a sequence by repeated\n concatenation will have a quadratic runtime cost in the total\n sequence length. To get a linear runtime cost, you must switch to\n one of the alternatives below:\n\n * if concatenating "str" objects, you can build a list and use\n "str.join()" at the end or else write to a "io.StringIO" instance\n and retrieve its value when complete\n\n * if concatenating "bytes" objects, you can similarly use\n "bytes.join()" or "io.BytesIO", or you can do in-place\n concatenation with a "bytearray" object. "bytearray" objects are\n mutable and have an efficient overallocation mechanism\n\n * if concatenating "tuple" objects, extend a "list" instead\n\n * for other types, investigate the relevant class documentation\n\n7. Some sequence types (such as "range") only support item\n sequences that follow specific patterns, and hence don\'t support\n sequence concatenation or repetition.\n\n8. "index" raises "ValueError" when *x* is not found in *s*. When\n supported, the additional arguments to the index method allow\n efficient searching of subsections of the sequence. Passing the\n extra arguments is roughly equivalent to using "s[i:j].index(x)",\n only without copying any data and with the returned index being\n relative to the start of the sequence rather than the start of the\n slice.\n\n\nImmutable Sequence Types\n========================\n\nThe only operation that immutable sequence types generally implement\nthat is not also implemented by mutable sequence types is support for\nthe "hash()" built-in.\n\nThis support allows immutable sequences, such as "tuple" instances, to\nbe used as "dict" keys and stored in "set" and "frozenset" instances.\n\nAttempting to hash an immutable sequence that contains unhashable\nvalues will result in "TypeError".\n\n\nMutable Sequence Types\n======================\n\nThe operations in the following table are defined on mutable sequence\ntypes. The "collections.abc.MutableSequence" ABC is provided to make\nit easier to correctly implement these operations on custom sequence\ntypes.\n\nIn the table *s* is an instance of a mutable sequence type, *t* is any\niterable object and *x* is an arbitrary object that meets any type and\nvalue restrictions imposed by *s* (for example, "bytearray" only\naccepts integers that meet the value restriction "0 <= x <= 255").\n\n+--------------------------------+----------------------------------+-----------------------+\n| Operation | Result | Notes |\n+================================+==================================+=======================+\n| "s[i] = x" | item *i* of *s* is replaced by | |\n| | *x* | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s[i:j] = t" | slice of *s* from *i* to *j* is | |\n| | replaced by the contents of the | |\n| | iterable *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| "del s[i:j]" | same as "s[i:j] = []" | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s[i:j:k] = t" | the elements of "s[i:j:k]" are | (1) |\n| | replaced by those of *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| "del s[i:j:k]" | removes the elements of | |\n| | "s[i:j:k]" from the list | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.append(x)" | appends *x* to the end of the | |\n| | sequence (same as | |\n| | "s[len(s):len(s)] = [x]") | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.clear()" | removes all items from "s" (same | (5) |\n| | as "del s[:]") | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.copy()" | creates a shallow copy of "s" | (5) |\n| | (same as "s[:]") | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.extend(t)" | extends *s* with the contents of | |\n| | *t* (same as "s[len(s):len(s)] = | |\n| | t") | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.insert(i, x)" | inserts *x* into *s* at the | |\n| | index given by *i* (same as | |\n| | "s[i:i] = [x]") | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.pop([i])" | retrieves the item at *i* and | (2) |\n| | also removes it from *s* | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.remove(x)" | remove the first item from *s* | (3) |\n| | where "s[i] == x" | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.reverse()" | reverses the items of *s* in | (4) |\n| | place | |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. The optional argument *i* defaults to "-1", so that by default\n the last item is removed and returned.\n\n3. "remove" raises "ValueError" when *x* is not found in *s*.\n\n4. The "reverse()" method modifies the sequence in place for\n economy of space when reversing a large sequence. To remind users\n that it operates by side effect, it does not return the reversed\n sequence.\n\n5. "clear()" and "copy()" are included for consistency with the\n interfaces of mutable containers that don\'t support slicing\n operations (such as "dict" and "set")\n\n New in version 3.3: "clear()" and "copy()" methods.\n\n\nLists\n=====\n\nLists are mutable sequences, typically used to store collections of\nhomogeneous items (where the precise degree of similarity will vary by\napplication).\n\nclass class list([iterable])\n\n Lists may be constructed in several ways:\n\n * Using a pair of square brackets to denote the empty list: "[]"\n\n * Using square brackets, separating items with commas: "[a]",\n "[a, b, c]"\n\n * Using a list comprehension: "[x for x in iterable]"\n\n * Using the type constructor: "list()" or "list(iterable)"\n\n The constructor builds a list whose items are the same and in the\n same order as *iterable*\'s items. *iterable* may be either a\n sequence, a container that supports iteration, or an iterator\n object. If *iterable* is already a list, a copy is made and\n returned, similar to "iterable[:]". For example, "list(\'abc\')"\n returns "[\'a\', \'b\', \'c\']" and "list( (1, 2, 3) )" returns "[1, 2,\n 3]". If no argument is given, the constructor creates a new empty\n list, "[]".\n\n Many other operations also produce lists, including the "sorted()"\n built-in.\n\n Lists implement all of the *common* and *mutable* sequence\n operations. Lists also provide the following additional method:\n\n sort(*, key=None, reverse=None)\n\n This method sorts the list in place, using only "<" comparisons\n between items. Exceptions are not suppressed - if any comparison\n operations fail, the entire sort operation will fail (and the\n list will likely be left in a partially modified state).\n\n "sort()" accepts two arguments that can only be passed by\n keyword (*keyword-only arguments*):\n\n *key* specifies a function of one argument that is used to\n extract a comparison key from each list element (for example,\n "key=str.lower"). The key corresponding to each item in the list\n is calculated once and then used for the entire sorting process.\n The default value of "None" means that list items are sorted\n directly without calculating a separate key value.\n\n The "functools.cmp_to_key()" utility is available to convert a\n 2.x style *cmp* function to a *key* function.\n\n *reverse* is a boolean value. If set to "True", then the list\n elements are sorted as if each comparison were reversed.\n\n This method modifies the sequence in place for economy of space\n when sorting a large sequence. To remind users that it operates\n by side effect, it does not return the sorted sequence (use\n "sorted()" to explicitly request a new sorted list instance).\n\n The "sort()" method is guaranteed to be stable. A sort is\n stable if it guarantees not to change the relative order of\n elements that compare equal --- this is helpful for sorting in\n multiple passes (for example, sort by department, then by salary\n grade).\n\n **CPython implementation detail:** While a list is being sorted,\n the effect of attempting to mutate, or even inspect, the list is\n undefined. The C implementation of Python makes the list appear\n empty for the duration, and raises "ValueError" if it can detect\n that the list has been mutated during a sort.\n\n\nTuples\n======\n\nTuples are immutable sequences, typically used to store collections of\nheterogeneous data (such as the 2-tuples produced by the "enumerate()"\nbuilt-in). Tuples are also used for cases where an immutable sequence\nof homogeneous data is needed (such as allowing storage in a "set" or\n"dict" instance).\n\nclass class tuple([iterable])\n\n Tuples may be constructed in a number of ways:\n\n * Using a pair of parentheses to denote the empty tuple: "()"\n\n * Using a trailing comma for a singleton tuple: "a," or "(a,)"\n\n * Separating items with commas: "a, b, c" or "(a, b, c)"\n\n * Using the "tuple()" built-in: "tuple()" or "tuple(iterable)"\n\n The constructor builds a tuple whose items are the same and in the\n same order as *iterable*\'s items. *iterable* may be either a\n sequence, a container that supports iteration, or an iterator\n object. If *iterable* is already a tuple, it is returned\n unchanged. For example, "tuple(\'abc\')" returns "(\'a\', \'b\', \'c\')"\n and "tuple( [1, 2, 3] )" returns "(1, 2, 3)". If no argument is\n given, the constructor creates a new empty tuple, "()".\n\n Note that it is actually the comma which makes a tuple, not the\n parentheses. The parentheses are optional, except in the empty\n tuple case, or when they are needed to avoid syntactic ambiguity.\n For example, "f(a, b, c)" is a function call with three arguments,\n while "f((a, b, c))" is a function call with a 3-tuple as the sole\n argument.\n\n Tuples implement all of the *common* sequence operations.\n\nFor heterogeneous collections of data where access by name is clearer\nthan access by index, "collections.namedtuple()" may be a more\nappropriate choice than a simple tuple object.\n\n\nRanges\n======\n\nThe "range" type represents an immutable sequence of numbers and is\ncommonly used for looping a specific number of times in "for" loops.\n\nclass class range(stop)\nclass class range(start, stop[, step])\n\n The arguments to the range constructor must be integers (either\n built-in "int" or any object that implements the "__index__"\n special method). If the *step* argument is omitted, it defaults to\n "1". If the *start* argument is omitted, it defaults to "0". If\n *step* is zero, "ValueError" is raised.\n\n For a positive *step*, the contents of a range "r" are determined\n by the formula "r[i] = start + step*i" where "i >= 0" and "r[i] <\n stop".\n\n For a negative *step*, the contents of the range are still\n determined by the formula "r[i] = start + step*i", but the\n constraints are "i >= 0" and "r[i] > stop".\n\n A range object will be empty if "r[0]" does not meet the value\n constraint. Ranges do support negative indices, but these are\n interpreted as indexing from the end of the sequence determined by\n the positive indices.\n\n Ranges containing absolute values larger than "sys.maxsize" are\n permitted but some features (such as "len()") may raise\n "OverflowError".\n\n Range examples:\n\n >>> list(range(10))\n [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n >>> list(range(1, 11))\n [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n >>> list(range(0, 30, 5))\n [0, 5, 10, 15, 20, 25]\n >>> list(range(0, 10, 3))\n [0, 3, 6, 9]\n >>> list(range(0, -10, -1))\n [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]\n >>> list(range(0))\n []\n >>> list(range(1, 0))\n []\n\n Ranges implement all of the *common* sequence operations except\n concatenation and repetition (due to the fact that range objects\n can only represent sequences that follow a strict pattern and\n repetition and concatenation will usually violate that pattern).\n\nThe advantage of the "range" type over a regular "list" or "tuple" is\nthat a "range" object will always take the same (small) amount of\nmemory, no matter the size of the range it represents (as it only\nstores the "start", "stop" and "step" values, calculating individual\nitems and subranges as needed).\n\nRange objects implement the "collections.abc.Sequence" ABC, and\nprovide features such as containment tests, element index lookup,\nslicing and support for negative indices (see *Sequence Types ---\nlist, tuple, range*):\n\n>>> r = range(0, 20, 2)\n>>> r\nrange(0, 20, 2)\n>>> 11 in r\nFalse\n>>> 10 in r\nTrue\n>>> r.index(10)\n5\n>>> r[5]\n10\n>>> r[:5]\nrange(0, 10, 2)\n>>> r[-1]\n18\n\nTesting range objects for equality with "==" and "!=" compares them as\nsequences. That is, two range objects are considered equal if they\nrepresent the same sequence of values. (Note that two range objects\nthat compare equal might have different "start", "stop" and "step"\nattributes, for example "range(0) == range(2, 1, 3)" or "range(0, 3,\n2) == range(0, 4, 2)".)\n\nChanged in version 3.2: Implement the Sequence ABC. Support slicing\nand negative indices. Test "int" objects for membership in constant\ntime instead of iterating through all items.\n\nChanged in version 3.3: Define \'==\' and \'!=\' to compare range objects\nbased on the sequence of values they define (instead of comparing\nbased on object identity).\n\nNew in version 3.3: The "start", "stop" and "step" attributes.\n', + 'typesseq-mutable': u'\nMutable Sequence Types\n**********************\n\nThe operations in the following table are defined on mutable sequence\ntypes. The "collections.abc.MutableSequence" ABC is provided to make\nit easier to correctly implement these operations on custom sequence\ntypes.\n\nIn the table *s* is an instance of a mutable sequence type, *t* is any\niterable object and *x* is an arbitrary object that meets any type and\nvalue restrictions imposed by *s* (for example, "bytearray" only\naccepts integers that meet the value restriction "0 <= x <= 255").\n\n+--------------------------------+----------------------------------+-----------------------+\n| Operation | Result | Notes |\n+================================+==================================+=======================+\n| "s[i] = x" | item *i* of *s* is replaced by | |\n| | *x* | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s[i:j] = t" | slice of *s* from *i* to *j* is | |\n| | replaced by the contents of the | |\n| | iterable *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| "del s[i:j]" | same as "s[i:j] = []" | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s[i:j:k] = t" | the elements of "s[i:j:k]" are | (1) |\n| | replaced by those of *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| "del s[i:j:k]" | removes the elements of | |\n| | "s[i:j:k]" from the list | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.append(x)" | appends *x* to the end of the | |\n| | sequence (same as | |\n| | "s[len(s):len(s)] = [x]") | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.clear()" | removes all items from "s" (same | (5) |\n| | as "del s[:]") | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.copy()" | creates a shallow copy of "s" | (5) |\n| | (same as "s[:]") | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.extend(t)" | extends *s* with the contents of | |\n| | *t* (same as "s[len(s):len(s)] = | |\n| | t") | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.insert(i, x)" | inserts *x* into *s* at the | |\n| | index given by *i* (same as | |\n| | "s[i:i] = [x]") | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.pop([i])" | retrieves the item at *i* and | (2) |\n| | also removes it from *s* | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.remove(x)" | remove the first item from *s* | (3) |\n| | where "s[i] == x" | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.reverse()" | reverses the items of *s* in | (4) |\n| | place | |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. The optional argument *i* defaults to "-1", so that by default\n the last item is removed and returned.\n\n3. "remove" raises "ValueError" when *x* is not found in *s*.\n\n4. The "reverse()" method modifies the sequence in place for\n economy of space when reversing a large sequence. To remind users\n that it operates by side effect, it does not return the reversed\n sequence.\n\n5. "clear()" and "copy()" are included for consistency with the\n interfaces of mutable containers that don\'t support slicing\n operations (such as "dict" and "set")\n\n New in version 3.3: "clear()" and "copy()" methods.\n', + 'unary': u'\nUnary arithmetic and bitwise operations\n***************************************\n\nAll unary arithmetic and bitwise operations have the same priority:\n\n u_expr ::= power | "-" u_expr | "+" u_expr | "~" u_expr\n\nThe unary "-" (minus) operator yields the negation of its numeric\nargument.\n\nThe unary "+" (plus) operator yields its numeric argument unchanged.\n\nThe unary "~" (invert) operator yields the bitwise inversion of its\ninteger argument. The bitwise inversion of "x" is defined as\n"-(x+1)". It only applies to integral numbers.\n\nIn all three cases, if the argument does not have the proper type, a\n"TypeError" exception is raised.\n', + 'while': u'\nThe "while" statement\n*********************\n\nThe "while" statement is used for repeated execution as long as an\nexpression is true:\n\n while_stmt ::= "while" expression ":" suite\n ["else" ":" suite]\n\nThis repeatedly tests the expression and, if it is true, executes the\nfirst suite; if the expression is false (which may be the first time\nit is tested) the suite of the "else" clause, if present, is executed\nand the loop terminates.\n\nA "break" statement executed in the first suite terminates the loop\nwithout executing the "else" clause\'s suite. A "continue" statement\nexecuted in the first suite skips the rest of the suite and goes back\nto testing the expression.\n', + 'with': u'\nThe "with" statement\n********************\n\nThe "with" statement is used to wrap the execution of a block with\nmethods defined by a context manager (see section *With Statement\nContext Managers*). This allows common "try"..."except"..."finally"\nusage patterns to be encapsulated for convenient reuse.\n\n with_stmt ::= "with" with_item ("," with_item)* ":" suite\n with_item ::= expression ["as" target]\n\nThe execution of the "with" statement with one "item" proceeds as\nfollows:\n\n1. The context expression (the expression given in the "with_item")\n is evaluated to obtain a context manager.\n\n2. The context manager\'s "__exit__()" is loaded for later use.\n\n3. The context manager\'s "__enter__()" method is invoked.\n\n4. If a target was included in the "with" statement, the return\n value from "__enter__()" is assigned to it.\n\n Note: The "with" statement guarantees that if the "__enter__()"\n method returns without an error, then "__exit__()" will always be\n called. Thus, if an error occurs during the assignment to the\n target list, it will be treated the same as an error occurring\n within the suite would be. See step 6 below.\n\n5. The suite is executed.\n\n6. The context manager\'s "__exit__()" method is invoked. If an\n exception caused the suite to be exited, its type, value, and\n traceback are passed as arguments to "__exit__()". Otherwise, three\n "None" arguments are supplied.\n\n If the suite was exited due to an exception, and the return value\n from the "__exit__()" method was false, the exception is reraised.\n If the return value was true, the exception is suppressed, and\n execution continues with the statement following the "with"\n statement.\n\n If the suite was exited for any reason other than an exception, the\n return value from "__exit__()" is ignored, and execution proceeds\n at the normal location for the kind of exit that was taken.\n\nWith more than one item, the context managers are processed as if\nmultiple "with" statements were nested:\n\n with A() as a, B() as b:\n suite\n\nis equivalent to\n\n with A() as a:\n with B() as b:\n suite\n\nChanged in version 3.1: Support for multiple context expressions.\n\nSee also: **PEP 0343** - The "with" statement\n\n The specification, background, and examples for the Python "with"\n statement.\n', + 'yield': u'\nThe "yield" statement\n*********************\n\n yield_stmt ::= yield_expression\n\nA "yield" statement is semantically equivalent to a *yield\nexpression*. The yield statement can be used to omit the parentheses\nthat would otherwise be required in the equivalent yield expression\nstatement. For example, the yield statements\n\n yield <expr>\n yield from <expr>\n\nare equivalent to the yield expression statements\n\n (yield <expr>)\n (yield from <expr>)\n\nYield expressions and statements are only used when defining a\n*generator* function, and are only used in the body of the generator\nfunction. Using yield in a function definition is sufficient to cause\nthat definition to create a generator function instead of a normal\nfunction.\n\nFor full details of "yield" semantics, refer to the *Yield\nexpressions* section.\n'} diff --git a/Lib/queue.py b/Lib/queue.py index 3cee36b8961e..572425e844c5 100644 --- a/Lib/queue.py +++ b/Lib/queue.py @@ -6,10 +6,7 @@ import dummy_threading as threading from collections import deque from heapq import heappush, heappop -try: - from time import monotonic as time -except ImportError: - from time import time +from time import monotonic as time __all__ = ['Empty', 'Full', 'Queue', 'PriorityQueue', 'LifoQueue'] diff --git a/Lib/quopri.py b/Lib/quopri.py index e5bd010d5ba8..46c2a4c7287c 100755 --- a/Lib/quopri.py +++ b/Lib/quopri.py @@ -44,13 +44,11 @@ def quote(c): def encode(input, output, quotetabs, header=False): """Read 'input', apply quoted-printable encoding, and write to 'output'. - 'input' and 'output' are files with readline() and write() methods. - The 'quotetabs' flag indicates whether embedded tabs and spaces should be - quoted. Note that line-ending tabs and spaces are always encoded, as per - RFC 1521. - The 'header' flag indicates whether we are encoding spaces as _ as per - RFC 1522. - """ + 'input' and 'output' are binary file objects. The 'quotetabs' flag + indicates whether embedded tabs and spaces should be quoted. Note that + line-ending tabs and spaces are always encoded, as per RFC 1521. + The 'header' flag indicates whether we are encoding spaces as _ as per RFC + 1522.""" if b2a_qp is not None: data = input.read() @@ -118,7 +116,7 @@ def encodestring(s, quotetabs=False, header=False): def decode(input, output, header=False): """Read 'input', apply quoted-printable decoding, and write to 'output'. - 'input' and 'output' are files with readline() and write() methods. + 'input' and 'output' are binary file objects. If 'header' is true, decode underscore as space (per RFC 1522).""" if a2b_qp is not None: diff --git a/Lib/random.py b/Lib/random.py index 808175ab4a10..1f5be45a4b6d 100644 --- a/Lib/random.py +++ b/Lib/random.py @@ -105,7 +105,9 @@ def seed(self, a=None, version=2): if a is None: try: - a = int.from_bytes(_urandom(32), 'big') + # Seed with enough bytes to span the 19937 bit + # state space for the Mersenne Twister + a = int.from_bytes(_urandom(2500), 'big') except NotImplementedError: import time a = int(time.time() * 256) # use fractional seconds @@ -353,7 +355,10 @@ def triangular(self, low=0.0, high=1.0, mode=None): """ u = self.random() - c = 0.5 if mode is None else (mode - low) / (high - low) + try: + c = 0.5 if mode is None else (mode - low) / (high - low) + except ZeroDivisionError: + return low if u > c: u = 1.0 - u c = 1.0 - c @@ -682,7 +687,7 @@ def _test_generator(n, func, args): print(round(t1-t0, 3), 'sec,', end=' ') avg = total/n stddev = _sqrt(sqsum/n - avg*avg) - print('avg %g, stddev %g, min %g, max %g' % \ + print('avg %g, stddev %g, min %g, max %g\n' % \ (avg, stddev, smallest, largest)) diff --git a/Lib/re.py b/Lib/re.py index 77f5e3fadbab..788fa6bd7897 100644 --- a/Lib/re.py +++ b/Lib/re.py @@ -122,12 +122,19 @@ import sys import sre_compile import sre_parse +try: + import _locale +except ImportError: + _locale = None # public symbols -__all__ = [ "match", "fullmatch", "search", "sub", "subn", "split", "findall", - "compile", "purge", "template", "escape", "A", "I", "L", "M", "S", "X", - "U", "ASCII", "IGNORECASE", "LOCALE", "MULTILINE", "DOTALL", "VERBOSE", - "UNICODE", "error" ] +__all__ = [ + "match", "fullmatch", "search", "sub", "subn", "split", + "findall", "finditer", "compile", "purge", "template", "escape", + "error", "A", "I", "L", "M", "S", "X", "U", + "ASCII", "IGNORECASE", "LOCALE", "MULTILINE", "DOTALL", "VERBOSE", + "UNICODE", +] __version__ = "2.2.1" @@ -205,14 +212,12 @@ def findall(pattern, string, flags=0): Empty matches are included in the result.""" return _compile(pattern, flags).findall(string) -if sys.hexversion >= 0x02020000: - __all__.append("finditer") - def finditer(pattern, string, flags=0): - """Return an iterator over all non-overlapping matches in the - string. For each match, the iterator returns a match object. +def finditer(pattern, string, flags=0): + """Return an iterator over all non-overlapping matches in the + string. For each match, the iterator returns a match object. - Empty matches are included in the result.""" - return _compile(pattern, flags).finditer(string) + Empty matches are included in the result.""" + return _compile(pattern, flags).finditer(string) def compile(pattern, flags=0): "Compile a regular expression pattern, returning a pattern object." @@ -273,7 +278,9 @@ def escape(pattern): def _compile(pattern, flags): # internal: compile pattern try: - return _cache[type(pattern), pattern, flags] + p, loc = _cache[type(pattern), pattern, flags] + if loc is None or loc == _locale.setlocale(_locale.LC_CTYPE): + return p except KeyError: pass if isinstance(pattern, _pattern_type): @@ -284,9 +291,16 @@ def _compile(pattern, flags): if not sre_compile.isstring(pattern): raise TypeError("first argument must be string or compiled pattern") p = sre_compile.compile(pattern, flags) - if len(_cache) >= _MAXCACHE: - _cache.clear() - _cache[type(pattern), pattern, flags] = p + if not (flags & DEBUG): + if len(_cache) >= _MAXCACHE: + _cache.clear() + if p.flags & LOCALE: + if not _locale: + return p + loc = _locale.setlocale(_locale.LC_CTYPE) + else: + loc = None + _cache[type(pattern), pattern, flags] = p, loc return p def _compile_repl(repl, pattern): @@ -337,10 +351,11 @@ def __init__(self, lexicon, flags=0): s = sre_parse.Pattern() s.flags = flags for phrase, action in lexicon: + gid = s.opengroup() p.append(sre_parse.SubPattern(s, [ - (SUBPATTERN, (len(p)+1, sre_parse.parse(phrase, flags))), + (SUBPATTERN, (gid, sre_parse.parse(phrase, flags))), ])) - s.groups = len(p)+1 + s.closegroup(gid, p[-1]) p = sre_parse.SubPattern(s, [(BRANCH, (None, p))]) self.scanner = sre_compile.compile(p) def scan(self, string): @@ -348,7 +363,7 @@ def scan(self, string): append = result.append match = self.scanner.scanner(string).match i = 0 - while 1: + while True: m = match() if not m: break diff --git a/Lib/reprlib.py b/Lib/reprlib.py index f8033604da28..ecbd2cc47228 100644 --- a/Lib/reprlib.py +++ b/Lib/reprlib.py @@ -83,16 +83,22 @@ def repr_list(self, x, level): return self._repr_iterable(x, level, '[', ']', self.maxlist) def repr_array(self, x, level): + if not x: + return "array('%s')" % x.typecode header = "array('%s', [" % x.typecode return self._repr_iterable(x, level, header, '])', self.maxarray) def repr_set(self, x, level): + if not x: + return 'set()' x = _possibly_sorted(x) - return self._repr_iterable(x, level, 'set([', '])', self.maxset) + return self._repr_iterable(x, level, '{', '}', self.maxset) def repr_frozenset(self, x, level): + if not x: + return 'frozenset()' x = _possibly_sorted(x) - return self._repr_iterable(x, level, 'frozenset([', '])', + return self._repr_iterable(x, level, 'frozenset({', '})', self.maxfrozenset) def repr_deque(self, x, level): @@ -136,7 +142,7 @@ def repr_instance(self, x, level): # Bugs in x.__repr__() can cause arbitrary # exceptions -- then make up something except Exception: - return '<%s instance at %x>' % (x.__class__.__name__, id(x)) + return '<%s instance at %#x>' % (x.__class__.__name__, id(x)) if len(s) > self.maxother: i = max(0, (self.maxother-3)//2) j = max(0, self.maxother-3-i) diff --git a/Lib/runpy.py b/Lib/runpy.py index 1e0a2be4f0c9..d9c643d6577c 100644 --- a/Lib/runpy.py +++ b/Lib/runpy.py @@ -10,11 +10,11 @@ # to implement PEP 338 (Executing Modules as Scripts) -import os import sys import importlib.machinery # importlib first so we can test #15386 via -m +import importlib.util import types -from pkgutil import read_code, get_loader, get_importer +from pkgutil import read_code, get_importer __all__ = [ "run_module", "run_path", @@ -58,51 +58,59 @@ def __exit__(self, *args): self.value = self._sentinel sys.argv[0] = self._saved_value +# TODO: Replace these helpers with importlib._bootstrap functions def _run_code(code, run_globals, init_globals=None, - mod_name=None, mod_fname=None, - mod_loader=None, pkg_name=None): + mod_name=None, mod_spec=None, + pkg_name=None, script_name=None): """Helper to run code in nominated namespace""" if init_globals is not None: run_globals.update(init_globals) + if mod_spec is None: + loader = None + fname = script_name + cached = None + else: + loader = mod_spec.loader + fname = mod_spec.origin + cached = mod_spec.cached + if pkg_name is None: + pkg_name = mod_spec.parent run_globals.update(__name__ = mod_name, - __file__ = mod_fname, - __cached__ = None, + __file__ = fname, + __cached__ = cached, __doc__ = None, - __loader__ = mod_loader, - __package__ = pkg_name) + __loader__ = loader, + __package__ = pkg_name, + __spec__ = mod_spec) exec(code, run_globals) return run_globals def _run_module_code(code, init_globals=None, - mod_name=None, mod_fname=None, - mod_loader=None, pkg_name=None): + mod_name=None, mod_spec=None, + pkg_name=None, script_name=None): """Helper to run code in new namespace with sys modified""" - with _TempModule(mod_name) as temp_module, _ModifiedArgv0(mod_fname): + fname = script_name if mod_spec is None else mod_spec.origin + with _TempModule(mod_name) as temp_module, _ModifiedArgv0(fname): mod_globals = temp_module.module.__dict__ _run_code(code, mod_globals, init_globals, - mod_name, mod_fname, mod_loader, pkg_name) + mod_name, mod_spec, pkg_name, script_name) # Copy the globals of the temporary module, as they # may be cleared when the temporary module goes away return mod_globals.copy() - -# This helper is needed due to a missing component in the PEP 302 -# loader protocol (specifically, "get_filename" is non-standard) -# Since we can't introduce new features in maintenance releases, -# support was added to zipimporter under the name '_get_filename' -def _get_filename(loader, mod_name): - for attr in ("get_filename", "_get_filename"): - meth = getattr(loader, attr, None) - if meth is not None: - return os.path.abspath(meth(mod_name)) - return None - # Helper to get the loader, code and filename for a module def _get_module_details(mod_name): - loader = get_loader(mod_name) - if loader is None: + try: + spec = importlib.util.find_spec(mod_name) + except (ImportError, AttributeError, TypeError, ValueError) as ex: + # This hack fixes an impedance mismatch between pkgutil and + # importlib, where the latter raises other errors for cases where + # pkgutil previously raised ImportError + msg = "Error while finding spec for {!r} ({}: {})" + raise ImportError(msg.format(mod_name, type(ex), ex)) from ex + if spec is None: raise ImportError("No module named %s" % mod_name) - if loader.is_package(mod_name): + if spec.submodule_search_locations is not None: if mod_name == "__main__" or mod_name.endswith(".__main__"): raise ImportError("Cannot use package as __main__ module") try: @@ -111,11 +119,14 @@ def _get_module_details(mod_name): except ImportError as e: raise ImportError(("%s; %r is a package and cannot " + "be directly executed") %(e, mod_name)) + loader = spec.loader + if loader is None: + raise ImportError("%r is a namespace package and cannot be executed" + % mod_name) code = loader.get_code(mod_name) if code is None: raise ImportError("No code object available for %s" % mod_name) - filename = _get_filename(loader, mod_name) - return mod_name, loader, code, filename + return mod_name, spec, code # XXX ncoghlan: Should this be documented and made public? # (Current thoughts: don't repeat the mistake that lead to its @@ -137,9 +148,9 @@ def _run_module_as_main(mod_name, alter_argv=True): """ try: if alter_argv or mod_name != "__main__": # i.e. -m switch - mod_name, loader, code, fname = _get_module_details(mod_name) + mod_name, mod_spec, code = _get_module_details(mod_name) else: # i.e. directory or zipfile execution - mod_name, loader, code, fname = _get_main_module_details() + mod_name, mod_spec, code = _get_main_module_details() except ImportError as exc: # Try to provide a good error message # for directories, zip files and the -m switch @@ -152,12 +163,11 @@ def _run_module_as_main(mod_name, alter_argv=True): info = "can't find '__main__' module in %r" % sys.argv[0] msg = "%s: %s" % (sys.executable, info) sys.exit(msg) - pkg_name = mod_name.rpartition('.')[0] main_globals = sys.modules["__main__"].__dict__ if alter_argv: - sys.argv[0] = fname + sys.argv[0] = mod_spec.origin return _run_code(code, main_globals, None, - "__main__", fname, loader, pkg_name) + "__main__", mod_spec) def run_module(mod_name, init_globals=None, run_name=None, alter_sys=False): @@ -165,17 +175,14 @@ def run_module(mod_name, init_globals=None, Returns the resulting top level namespace dictionary """ - mod_name, loader, code, fname = _get_module_details(mod_name) + mod_name, mod_spec, code = _get_module_details(mod_name) if run_name is None: run_name = mod_name - pkg_name = mod_name.rpartition('.')[0] if alter_sys: - return _run_module_code(code, init_globals, run_name, - fname, loader, pkg_name) + return _run_module_code(code, init_globals, run_name, mod_spec) else: # Leave the sys module alone - return _run_code(code, {}, init_globals, run_name, - fname, loader, pkg_name) + return _run_code(code, {}, init_globals, run_name, mod_spec) def _get_main_module_details(): # Helper that gives a nicer error message when attempting to @@ -204,10 +211,7 @@ def _get_code_from_file(run_name, fname): # That didn't work, so try it as normal source code with open(fname, "rb") as f: code = compile(f.read(), fname, 'exec') - loader = importlib.machinery.SourceFileLoader(run_name, fname) - else: - loader = importlib.machinery.SourcelessFileLoader(run_name, fname) - return code, loader + return code, fname def run_path(path_name, init_globals=None, run_name=None): """Execute code located at the specified filesystem location @@ -231,9 +235,9 @@ def run_path(path_name, init_globals=None, run_name=None): if isinstance(importer, type(None)) or is_NullImporter: # Not a valid sys.path entry, so run the code directly # execfile() doesn't help as we want to allow compiled files - code, mod_loader = _get_code_from_file(run_name, path_name) - return _run_module_code(code, init_globals, run_name, path_name, - mod_loader, pkg_name) + code, fname = _get_code_from_file(run_name, path_name) + return _run_module_code(code, init_globals, run_name, + pkg_name=pkg_name, script_name=fname) else: # Importer is defined for path, so add it to # the start of sys.path @@ -245,12 +249,12 @@ def run_path(path_name, init_globals=None, run_name=None): # have no choice and we have to remove it even while we read the # code. If we don't do this, a __loader__ attribute in the # existing __main__ module may prevent location of the new module. - mod_name, loader, code, fname = _get_main_module_details() + mod_name, mod_spec, code = _get_main_module_details() with _TempModule(run_name) as temp_module, \ _ModifiedArgv0(path_name): mod_globals = temp_module.module.__dict__ return _run_code(code, mod_globals, init_globals, - run_name, fname, loader, pkg_name).copy() + run_name, mod_spec, pkg_name).copy() finally: try: sys.path.remove(path_name) diff --git a/Lib/sched.py b/Lib/sched.py index 2e6b00a2a22e..b47648d973a9 100644 --- a/Lib/sched.py +++ b/Lib/sched.py @@ -35,16 +35,12 @@ import threading except ImportError: import dummy_threading as threading -try: - from time import monotonic as _time -except ImportError: - from time import time as _time +from time import monotonic as _time __all__ = ["scheduler"] class Event(namedtuple('Event', 'time, priority, action, argument, kwargs')): def __eq__(s, o): return (s.time, s.priority) == (o.time, o.priority) - def __ne__(s, o): return (s.time, s.priority) != (o.time, o.priority) def __lt__(s, o): return (s.time, s.priority) < (o.time, o.priority) def __le__(s, o): return (s.time, s.priority) <= (o.time, o.priority) def __gt__(s, o): return (s.time, s.priority) > (o.time, o.priority) diff --git a/Lib/selectors.py b/Lib/selectors.py index c533f13d6957..6d569c30adff 100644 --- a/Lib/selectors.py +++ b/Lib/selectors.py @@ -7,7 +7,7 @@ from abc import ABCMeta, abstractmethod from collections import namedtuple, Mapping -import functools +import math import select import sys @@ -25,6 +25,9 @@ def _fileobj_to_fd(fileobj): Returns: corresponding file descriptor + + Raises: + ValueError if the object is invalid """ if isinstance(fileobj, int): fd = fileobj @@ -55,7 +58,8 @@ def __len__(self): def __getitem__(self, fileobj): try: - return self._selector._fd_to_key[_fileobj_to_fd(fileobj)] + fd = self._selector._fileobj_lookup(fileobj) + return self._selector._fd_to_key[fd] except KeyError: raise KeyError("{!r} is not registered".format(fileobj)) from None @@ -75,7 +79,7 @@ class BaseSelector(metaclass=ABCMeta): A selector can use various implementations (select(), poll(), epoll()...) depending on the platform. The default `Selector` class uses the most - performant implementation on the current platform. + efficient implementation on the current platform. """ @abstractmethod @@ -89,6 +93,15 @@ def register(self, fileobj, events, data=None): Returns: SelectorKey instance + + Raises: + ValueError if events is invalid + KeyError if fileobj is already registered + OSError if fileobj is closed or otherwise is unacceptable to + the underlying system call (if a system call is made) + + Note: + OSError may or may not be raised """ raise NotImplementedError @@ -101,6 +114,13 @@ def unregister(self, fileobj): Returns: SelectorKey instance + + Raises: + KeyError if fileobj is not registered + + Note: + If fileobj is registered but has since been closed this does + *not* raise OSError (even if the wrapped syscall does) """ raise NotImplementedError @@ -114,6 +134,9 @@ def modify(self, fileobj, events, data=None): Returns: SelectorKey instance + + Raises: + Anything that unregister() or register() raises """ self.unregister(fileobj) return self.register(fileobj, events, data) @@ -151,6 +174,8 @@ def get_key(self, fileobj): SelectorKey for this file object """ mapping = self.get_map() + if mapping is None: + raise RuntimeError('Selector is closed') try: return mapping[fileobj] except KeyError: @@ -177,22 +202,41 @@ def __init__(self): # read-only mapping returned by get_map() self._map = _SelectorMapping(self) + def _fileobj_lookup(self, fileobj): + """Return a file descriptor from a file object. + + This wraps _fileobj_to_fd() to do an exhaustive search in case + the object is invalid but we still have it in our map. This + is used by unregister() so we can unregister an object that + was previously registered even if it is closed. It is also + used by _SelectorMapping. + """ + try: + return _fileobj_to_fd(fileobj) + except ValueError: + # Do an exhaustive search. + for key in self._fd_to_key.values(): + if key.fileobj is fileobj: + return key.fd + # Raise ValueError after all. + raise + def register(self, fileobj, events, data=None): if (not events) or (events & ~(EVENT_READ | EVENT_WRITE)): raise ValueError("Invalid events: {!r}".format(events)) - key = SelectorKey(fileobj, _fileobj_to_fd(fileobj), events, data) + key = SelectorKey(fileobj, self._fileobj_lookup(fileobj), events, data) if key.fd in self._fd_to_key: - raise KeyError("{!r} (FD {}) is already " - "registered".format(fileobj, key.fd)) + raise KeyError("{!r} (FD {}) is already registered" + .format(fileobj, key.fd)) self._fd_to_key[key.fd] = key return key def unregister(self, fileobj): try: - key = self._fd_to_key.pop(_fileobj_to_fd(fileobj)) + key = self._fd_to_key.pop(self._fileobj_lookup(fileobj)) except KeyError: raise KeyError("{!r} is not registered".format(fileobj)) from None return key @@ -200,7 +244,7 @@ def unregister(self, fileobj): def modify(self, fileobj, events, data=None): # TODO: Subclasses can probably optimize this even further. try: - key = self._fd_to_key[_fileobj_to_fd(fileobj)] + key = self._fd_to_key[self._fileobj_lookup(fileobj)] except KeyError: raise KeyError("{!r} is not registered".format(fileobj)) from None if events != key.events: @@ -214,6 +258,7 @@ def modify(self, fileobj, events, data=None): def close(self): self._fd_to_key.clear() + self._map = None def get_map(self): return self._map @@ -309,7 +354,14 @@ def unregister(self, fileobj): return key def select(self, timeout=None): - timeout = None if timeout is None else max(int(1000 * timeout), 0) + if timeout is None: + timeout = None + elif timeout <= 0: + timeout = 0 + else: + # poll() has a resolution of 1 millisecond, round away from + # zero to wait *at least* timeout seconds. + timeout = math.ceil(timeout * 1e3) ready = [] try: fd_event_list = self._poll.poll(timeout) @@ -352,12 +404,29 @@ def register(self, fileobj, events, data=None): def unregister(self, fileobj): key = super().unregister(fileobj) - self._epoll.unregister(key.fd) + try: + self._epoll.unregister(key.fd) + except OSError: + # This can happen if the FD was closed since it + # was registered. + pass return key def select(self, timeout=None): - timeout = -1 if timeout is None else max(timeout, 0) - max_ev = len(self._fd_to_key) + if timeout is None: + timeout = -1 + elif timeout <= 0: + timeout = 0 + else: + # epoll_wait() has a resolution of 1 millisecond, round away + # from zero to wait *at least* timeout seconds. + timeout = math.ceil(timeout * 1e3) * 1e-3 + + # epoll_wait() expects `maxevents` to be greater than zero; + # we want to make sure that `select()` can be called when no + # FD is registered. + max_ev = max(len(self._fd_to_key), 1) + ready = [] try: fd_event_list = self._epoll.poll(timeout, max_ev) @@ -380,6 +449,64 @@ def close(self): super().close() +if hasattr(select, 'devpoll'): + + class DevpollSelector(_BaseSelectorImpl): + """Solaris /dev/poll selector.""" + + def __init__(self): + super().__init__() + self._devpoll = select.devpoll() + + def fileno(self): + return self._devpoll.fileno() + + def register(self, fileobj, events, data=None): + key = super().register(fileobj, events, data) + poll_events = 0 + if events & EVENT_READ: + poll_events |= select.POLLIN + if events & EVENT_WRITE: + poll_events |= select.POLLOUT + self._devpoll.register(key.fd, poll_events) + return key + + def unregister(self, fileobj): + key = super().unregister(fileobj) + self._devpoll.unregister(key.fd) + return key + + def select(self, timeout=None): + if timeout is None: + timeout = None + elif timeout <= 0: + timeout = 0 + else: + # devpoll() has a resolution of 1 millisecond, round away from + # zero to wait *at least* timeout seconds. + timeout = math.ceil(timeout * 1e3) + ready = [] + try: + fd_event_list = self._devpoll.poll(timeout) + except InterruptedError: + return ready + for fd, event in fd_event_list: + events = 0 + if event & ~select.POLLIN: + events |= EVENT_WRITE + if event & ~select.POLLOUT: + events |= EVENT_READ + + key = self._key_from_fd(fd) + if key: + ready.append((key, events & key.events)) + return ready + + def close(self): + self._devpoll.close() + super().close() + + if hasattr(select, 'kqueue'): class KqueueSelector(_BaseSelectorImpl): @@ -409,11 +536,20 @@ def unregister(self, fileobj): if key.events & EVENT_READ: kev = select.kevent(key.fd, select.KQ_FILTER_READ, select.KQ_EV_DELETE) - self._kqueue.control([kev], 0, 0) + try: + self._kqueue.control([kev], 0, 0) + except OSError: + # This can happen if the FD was closed since it + # was registered. + pass if key.events & EVENT_WRITE: kev = select.kevent(key.fd, select.KQ_FILTER_WRITE, select.KQ_EV_DELETE) - self._kqueue.control([kev], 0, 0) + try: + self._kqueue.control([kev], 0, 0) + except OSError: + # See comment above. + pass return key def select(self, timeout=None): @@ -443,12 +579,15 @@ def close(self): super().close() -# Choose the best implementation: roughly, epoll|kqueue > poll > select. +# Choose the best implementation, roughly: +# epoll|kqueue|devpoll > poll > select. # select() also can't accept a FD > FD_SETSIZE (usually around 1024) if 'KqueueSelector' in globals(): DefaultSelector = KqueueSelector elif 'EpollSelector' in globals(): DefaultSelector = EpollSelector +elif 'DevpollSelector' in globals(): + DefaultSelector = DevpollSelector elif 'PollSelector' in globals(): DefaultSelector = PollSelector else: diff --git a/Lib/shlex.py b/Lib/shlex.py index 69f3b456af10..4672553f1cc7 100644 --- a/Lib/shlex.py +++ b/Lib/shlex.py @@ -290,15 +290,17 @@ def quote(s): return "'" + s.replace("'", "'\"'\"'") + "'" -if __name__ == '__main__': - if len(sys.argv) == 1: - lexer = shlex() - else: - file = sys.argv[1] - lexer = shlex(open(file), file) +def _print_tokens(lexer): while 1: tt = lexer.get_token() - if tt: - print("Token: " + repr(tt)) - else: + if not tt: break + print("Token: " + repr(tt)) + +if __name__ == '__main__': + if len(sys.argv) == 1: + _print_tokens(shlex()) + else: + fn = sys.argv[1] + with open(fn) as f: + _print_tokens(shlex(f, fn)) diff --git a/Lib/shutil.py b/Lib/shutil.py index 502bb6782c41..61dc8045a9fa 100644 --- a/Lib/shutil.py +++ b/Lib/shutil.py @@ -7,7 +7,6 @@ import os import sys import stat -from os.path import abspath import fnmatch import collections import errno @@ -20,6 +19,13 @@ except ImportError: _BZ2_SUPPORTED = False +try: + import lzma + del lzma + _LZMA_SUPPORTED = True +except ImportError: + _LZMA_SUPPORTED = False + try: from pwd import getpwnam except ImportError: @@ -36,7 +42,8 @@ "register_archive_format", "unregister_archive_format", "get_unpack_formats", "register_unpack_format", "unregister_unpack_format", "unpack_archive", - "ignore_patterns", "chown", "which"] + "ignore_patterns", "chown", "which", "get_terminal_size", + "SameFileError"] # disk_usage is added later, if available on the platform class Error(OSError): @@ -336,7 +343,7 @@ def copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, copystat(src, dst) except OSError as why: # Copying file access times may fail on Windows - if why.winerror is None: + if getattr(why, 'winerror', None) is None: errors.append((src, dst, str(why))) if errors: raise Error(errors) @@ -483,9 +490,10 @@ def onerror(*args): def _basename(path): # A basename() variant which first strips the trailing slash, if present. # Thus we always get the last component of the path, even for directories. - return os.path.basename(path.rstrip(os.path.sep)) + sep = os.path.sep + (os.path.altsep or '') + return os.path.basename(path.rstrip(sep)) -def move(src, dst): +def move(src, dst, copy_function=copy2): """Recursively move a file or directory to another location. This is similar to the Unix "mv" command. Return the file or directory's destination. @@ -502,6 +510,11 @@ def move(src, dst): recreated under the new name if os.rename() fails because of cross filesystem renames. + The optional `copy_function` argument is a callable that will be used + to copy the source or it will be delegated to `copytree`. + By default, copy2() is used, but any function that supports the same + signature (like copy()) can be used. + A lot more could be done here... A look at a mv.c shows a lot of the issues this implementation glosses over. @@ -526,17 +539,19 @@ def move(src, dst): os.unlink(src) elif os.path.isdir(src): if _destinsrc(src, dst): - raise Error("Cannot move a directory '%s' into itself '%s'." % (src, dst)) - copytree(src, real_dst, symlinks=True) + raise Error("Cannot move a directory '%s' into itself" + " '%s'." % (src, dst)) + copytree(src, real_dst, copy_function=copy_function, + symlinks=True) rmtree(src) else: - copy2(src, real_dst) + copy_function(src, real_dst) os.unlink(src) return real_dst def _destinsrc(src, dst): - src = abspath(src) - dst = abspath(dst) + src = os.path.abspath(src) + dst = os.path.abspath(dst) if not src.endswith(os.path.sep): src += os.path.sep if not dst.endswith(os.path.sep): @@ -572,14 +587,14 @@ def _make_tarball(base_name, base_dir, compress="gzip", verbose=0, dry_run=0, """Create a (possibly compressed) tar file from all the files under 'base_dir'. - 'compress' must be "gzip" (the default), "bzip2", or None. + 'compress' must be "gzip" (the default), "bzip2", "xz", or None. 'owner' and 'group' can be used to define an owner and a group for the archive that is being built. If not provided, the current owner and group will be used. The output tar file will be named 'base_name' + ".tar", possibly plus - the appropriate compression extension (".gz", or ".bz2"). + the appropriate compression extension (".gz", ".bz2", or ".xz"). Returns the output filename. """ @@ -590,6 +605,10 @@ def _make_tarball(base_name, base_dir, compress="gzip", verbose=0, dry_run=0, 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: raise ValueError("bad value for 'compress', or compression format not " @@ -598,7 +617,7 @@ def _make_tarball(base_name, base_dir, compress="gzip", verbose=0, dry_run=0, archive_name = base_name + '.tar' + compress_ext.get(compress, '') archive_dir = os.path.dirname(archive_name) - if not os.path.exists(archive_dir): + if archive_dir and not os.path.exists(archive_dir): if logger is not None: logger.info("creating %s", archive_dir) if not dry_run: @@ -629,23 +648,6 @@ def _set_uid_gid(tarinfo): return archive_name -def _call_external_zip(base_dir, zip_filename, verbose=False, dry_run=False): - # XXX see if we want to keep an external call here - if verbose: - zipoptions = "-r" - else: - zipoptions = "-rq" - from distutils.errors import DistutilsExecError - from distutils.spawn import spawn - try: - spawn(["zip", zipoptions, zip_filename, base_dir], dry_run=dry_run) - except DistutilsExecError: - # XXX really should distinguish between "couldn't find - # external 'zip' command" and "zip failed". - raise ExecError("unable to create zip file '%s': " - "could neither import the 'zipfile' module nor " - "find a standalone zip utility") % zip_filename - 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'. @@ -655,41 +657,31 @@ def _make_zipfile(base_name, base_dir, verbose=0, dry_run=0, logger=None): available, raises ExecError. Returns the name of the output zip file. """ + import zipfile + zip_filename = base_name + ".zip" archive_dir = os.path.dirname(base_name) - if not os.path.exists(archive_dir): + if archive_dir and not os.path.exists(archive_dir): if logger is not None: logger.info("creating %s", archive_dir) if not dry_run: os.makedirs(archive_dir) - # If zipfile module is not available, try spawning an external 'zip' - # command. - try: - import zipfile - except ImportError: - zipfile = None - - if zipfile is None: - _call_external_zip(base_dir, zip_filename, verbose, dry_run) - else: - if logger is not None: - logger.info("creating '%s' and adding '%s' to it", - zip_filename, base_dir) - - if not dry_run: - zip = zipfile.ZipFile(zip_filename, "w", - compression=zipfile.ZIP_DEFLATED) + if logger is not None: + logger.info("creating '%s' and adding '%s' to it", + zip_filename, base_dir) + if not dry_run: + with zipfile.ZipFile(zip_filename, "w", + compression=zipfile.ZIP_DEFLATED) as zf: for dirpath, dirnames, filenames in os.walk(base_dir): for name in filenames: path = os.path.normpath(os.path.join(dirpath, name)) if os.path.isfile(path): - zip.write(path, path) + zf.write(path, path) if logger is not None: logger.info("adding '%s'", path) - zip.close() return zip_filename @@ -703,6 +695,10 @@ def _make_zipfile(base_name, base_dir, verbose=0, dry_run=0, logger=None): _ARCHIVE_FORMATS['bztar'] = (_make_tarball, [('compress', 'bzip2')], "bzip2'ed tar-file") +if _LZMA_SUPPORTED: + _ARCHIVE_FORMATS['xztar'] = (_make_tarball, [('compress', 'xz')], + "xz'ed tar-file") + def get_archive_formats(): """Returns a list of supported formats for archiving and unarchiving. @@ -891,7 +887,7 @@ def _unpack_zipfile(filename, extract_dir): zip.close() def _unpack_tarfile(filename, extract_dir): - """Unpack tar/tar.gz/tar.bz2 `filename` to `extract_dir` + """Unpack tar/tar.gz/tar.bz2/tar.xz `filename` to `extract_dir` """ try: tarobj = tarfile.open(filename) @@ -910,9 +906,13 @@ def _unpack_tarfile(filename, extract_dir): } if _BZ2_SUPPORTED: - _UNPACK_FORMATS['bztar'] = (['.bz2'], _unpack_tarfile, [], + _UNPACK_FORMATS['bztar'] = (['.tar.bz2', '.tbz2'], _unpack_tarfile, [], "bzip2'ed tar-file") +if _LZMA_SUPPORTED: + _UNPACK_FORMATS['xztar'] = (['.tar.xz', '.txz'], _unpack_tarfile, [], + "xz'ed tar-file") + def _find_unpack_format(filename): for name, info in _UNPACK_FORMATS.items(): for extension in info[0]: diff --git a/Lib/signal.py b/Lib/signal.py new file mode 100644 index 000000000000..0db3df8bd618 --- /dev/null +++ b/Lib/signal.py @@ -0,0 +1,85 @@ +import _signal +from _signal import * +from functools import wraps as _wraps +from enum import IntEnum as _IntEnum + +_globals = globals() + +Signals = _IntEnum( + 'Signals', + {name: value for name, value in _globals.items() + if name.isupper() + and (name.startswith('SIG') and not name.startswith('SIG_')) + or name.startswith('CTRL_')}) + +class Handlers(_IntEnum): + SIG_DFL = _signal.SIG_DFL + SIG_IGN = _signal.SIG_IGN + +_globals.update(Signals.__members__) +_globals.update(Handlers.__members__) + +if 'pthread_sigmask' in _globals: + class Sigmasks(_IntEnum): + SIG_BLOCK = _signal.SIG_BLOCK + SIG_UNBLOCK = _signal.SIG_UNBLOCK + SIG_SETMASK = _signal.SIG_SETMASK + + _globals.update(Sigmasks.__members__) + + +def _int_to_enum(value, enum_klass): + """Convert a numeric value to an IntEnum member. + If it's not a known member, return the numeric value itself. + """ + try: + return enum_klass(value) + except ValueError: + return value + + +def _enum_to_int(value): + """Convert an IntEnum member to a numeric value. + If it's not a IntEnum member return the value itself. + """ + try: + return int(value) + except (ValueError, TypeError): + return value + + +@_wraps(_signal.signal) +def signal(signalnum, handler): + handler = _signal.signal(_enum_to_int(signalnum), _enum_to_int(handler)) + return _int_to_enum(handler, Handlers) + + +@_wraps(_signal.getsignal) +def getsignal(signalnum): + handler = _signal.getsignal(signalnum) + return _int_to_enum(handler, Handlers) + + +if 'pthread_sigmask' in _globals: + @_wraps(_signal.pthread_sigmask) + def pthread_sigmask(how, mask): + sigs_set = _signal.pthread_sigmask(how, mask) + return set(_int_to_enum(x, Signals) for x in sigs_set) + pthread_sigmask.__doc__ = _signal.pthread_sigmask.__doc__ + + +if 'sigpending' in _globals: + @_wraps(_signal.sigpending) + def sigpending(): + sigs = _signal.sigpending() + return set(_int_to_enum(x, Signals) for x in sigs) + + +if 'sigwait' in _globals: + @_wraps(_signal.sigwait) + def sigwait(sigset): + retsig = _signal.sigwait(sigset) + return _int_to_enum(retsig, Signals) + sigwait.__doc__ = _signal.sigwait + +del _globals, _wraps diff --git a/Lib/site.py b/Lib/site.py index b0d8268f8165..4959cfcf9c95 100644 --- a/Lib/site.py +++ b/Lib/site.py @@ -7,7 +7,7 @@ This will append site-specific paths to the module search path. On Unix (including Mac OSX), it starts with sys.prefix and sys.exec_prefix (if different) and appends -lib/python<version>/site-packages as well as lib/site-python. +lib/python<version>/site-packages. On other platforms (such as Windows), it tries each of the prefixes directly, as well as with lib/site-packages appended. The resulting directories, if they exist, are appended to sys.path, and @@ -15,7 +15,7 @@ If a file named "pyvenv.cfg" exists one directory above sys.executable, sys.prefix and sys.exec_prefix are set to that directory and -it is also checked for site-packages and site-python (sys.base_prefix and +it is also checked for site-packages (sys.base_prefix and sys.base_exec_prefix will always be the "real" prefixes of the Python installation). If "pyvenv.cfg" (a bootstrap configuration file) contains the key "include-system-site-packages" set to anything other than "false" @@ -285,8 +285,7 @@ def addusersitepackages(known_paths): return known_paths def getsitepackages(prefixes=None): - """Returns a list containing all global site-packages directories - (and possibly site-python). + """Returns a list containing all global site-packages directories. For each directory present in ``prefixes`` (or the global ``PREFIXES``), this function will find its `site-packages` subdirectory depending on the @@ -307,7 +306,6 @@ def getsitepackages(prefixes=None): sitepackages.append(os.path.join(prefix, "lib", "python" + sys.version[:3], "site-packages")) - sitepackages.append(os.path.join(prefix, "lib", "site-python")) else: sitepackages.append(prefix) sitepackages.append(os.path.join(prefix, "lib", "site-packages")) @@ -323,14 +321,9 @@ def getsitepackages(prefixes=None): return sitepackages def addsitepackages(known_paths, prefixes=None): - """Add site-packages (and possibly site-python) to sys.path""" + """Add site-packages to sys.path""" for sitedir in getsitepackages(prefixes): if os.path.isdir(sitedir): - if "site-python" in sitedir: - import warnings - warnings.warn('"site-python" directories will not be ' - 'supported in 3.5 anymore', - DeprecationWarning) addsitedir(sitedir, known_paths) return known_paths @@ -364,12 +357,17 @@ def setcopyright(): builtins.credits = _sitebuiltins._Printer("credits", """\ Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands for supporting Python development. See www.python.org for more information.""") - here = os.path.dirname(os.__file__) + files, dirs = [], [] + # Not all modules are required to have a __file__ attribute. See + # PEP 420 for more details. + if hasattr(os, '__file__'): + here = os.path.dirname(os.__file__) + files.extend(["LICENSE.txt", "LICENSE"]) + dirs.extend([os.path.join(here, os.pardir), here, os.curdir]) builtins.license = _sitebuiltins._Printer( "license", - "See http://www.python.org/download/releases/%.5s/license" % sys.version, - ["LICENSE.txt", "LICENSE"], - [os.path.join(here, os.pardir), here, os.curdir]) + "See https://www.python.org/psf/license/", + files, dirs) def sethelper(): @@ -409,7 +407,7 @@ def register_readline(): # want to ignore the exception. pass - if readline.get_history_item(1) is None: + if readline.get_current_history_length() == 0: # If no history was loaded, default to .python_history. # The guard is necessary to avoid doubling history size at # each interpreter exit when readline was already configured diff --git a/Lib/smtpd.py b/Lib/smtpd.py index 1fa157ade7cc..33653d4fbf4a 100755 --- a/Lib/smtpd.py +++ b/Lib/smtpd.py @@ -1,5 +1,5 @@ #! /usr/bin/env python3 -"""An RFC 5321 smtp proxy. +"""An RFC 5321 smtp proxy with optional RFC 1870 and RFC 6531 extensions. Usage: %(program)s [options] [localhost:localport [remotehost:remoteport]] @@ -25,6 +25,10 @@ Restrict the total size of the incoming message to "limit" number of bytes via the RFC 1870 SIZE extension. Defaults to 33554432 bytes. + --smtputf8 + -u + Enable the SMTPUTF8 extension and behave as an RFC 6531 smtp proxy. + --debug -d Turn on debugging prints. @@ -98,7 +102,6 @@ def flush(self): pass DEBUGSTREAM = Devnull() NEWLINE = '\n' -EMPTYSTRING = '' COMMASPACE = ', ' DATA_SIZE_DEFAULT = 33554432 @@ -116,26 +119,48 @@ class SMTPChannel(asynchat.async_chat): command_size_limit = 512 command_size_limits = collections.defaultdict(lambda x=command_size_limit: x) - command_size_limits.update({ - 'MAIL': command_size_limit + 26, - }) - max_command_size_limit = max(command_size_limits.values()) + + @property + def max_command_size_limit(self): + try: + return max(self.command_size_limits.values()) + except ValueError: + return self.command_size_limit def __init__(self, server, conn, addr, data_size_limit=DATA_SIZE_DEFAULT, - map=None): + map=None, enable_SMTPUTF8=False, decode_data=None): asynchat.async_chat.__init__(self, conn, map=map) self.smtp_server = server self.conn = conn self.addr = addr self.data_size_limit = data_size_limit - self.received_lines = [] - self.smtp_state = self.COMMAND + self.enable_SMTPUTF8 = enable_SMTPUTF8 + if enable_SMTPUTF8: + if decode_data: + ValueError("decode_data and enable_SMTPUTF8 cannot be set to" + " True at the same time") + decode_data = False + if decode_data is None: + warn("The decode_data default of True will change to False in 3.6;" + " specify an explicit value for this keyword", + DeprecationWarning, 2) + decode_data = True + self._decode_data = decode_data + if decode_data: + self._emptystring = '' + self._linesep = '\r\n' + self._dotsep = '.' + self._newline = NEWLINE + else: + self._emptystring = b'' + self._linesep = b'\r\n' + self._dotsep = b'.' + self._newline = b'\n' + self._set_rset_state() self.seen_greeting = '' - self.mailfrom = None - self.rcpttos = [] - self.received_data = '' + self.extended_smtp = False + self.command_size_limits.clear() self.fqdn = socket.getfqdn() - self.num_bytes = 0 try: self.peer = conn.getpeername() except OSError as err: @@ -147,8 +172,22 @@ def __init__(self, server, conn, addr, data_size_limit=DATA_SIZE_DEFAULT, return print('Peer:', repr(self.peer), file=DEBUGSTREAM) self.push('220 %s %s' % (self.fqdn, __version__)) + + def _set_post_data_state(self): + """Reset state variables to their post-DATA state.""" + self.smtp_state = self.COMMAND + self.mailfrom = None + self.rcpttos = [] + self.require_SMTPUTF8 = False + self.num_bytes = 0 self.set_terminator(b'\r\n') - self.extended_smtp = False + + def _set_rset_state(self): + """Reset all state variables except the greeting.""" + self._set_post_data_state() + self.received_data = '' + self.received_lines = [] + # properties for backwards-compatibility @property @@ -272,9 +311,10 @@ def __addr(self, value): "set 'addr' instead", DeprecationWarning, 2) self.addr = value - # Overrides base class for convenience + # Overrides base class for convenience. def push(self, msg): - asynchat.async_chat.push(self, bytes(msg + '\r\n', 'ascii')) + asynchat.async_chat.push(self, bytes( + msg + '\r\n', 'utf-8' if self.require_SMTPUTF8 else 'ascii')) # Implementation of base class abstract method def collect_incoming_data(self, data): @@ -287,11 +327,14 @@ def collect_incoming_data(self, data): return elif limit: self.num_bytes += len(data) - self.received_lines.append(str(data, "utf-8")) + if self._decode_data: + self.received_lines.append(str(data, 'utf-8')) + else: + self.received_lines.append(data) # Implementation of base class abstract method def found_terminator(self): - line = EMPTYSTRING.join(self.received_lines) + line = self._emptystring.join(self.received_lines) print('Data:', repr(line), file=DEBUGSTREAM) self.received_lines = [] if self.smtp_state == self.COMMAND: @@ -299,7 +342,8 @@ def found_terminator(self): if not line: self.push('500 Error: bad syntax') return - method = None + if not self._decode_data: + line = str(line, 'utf-8') i = line.find(' ') if i < 0: command = line.upper() @@ -330,21 +374,18 @@ def found_terminator(self): # Remove extraneous carriage returns and de-transparency according # to RFC 5321, Section 4.5.2. data = [] - for text in line.split('\r\n'): - if text and text[0] == '.': + for text in line.split(self._linesep): + if text and text[0] == self._dotsep: data.append(text[1:]) else: data.append(text) - self.received_data = NEWLINE.join(data) - status = self.smtp_server.process_message(self.peer, - self.mailfrom, - self.rcpttos, - self.received_data) - self.rcpttos = [] - self.mailfrom = None - self.smtp_state = self.COMMAND - self.num_bytes = 0 - self.set_terminator(b'\r\n') + self.received_data = self._newline.join(data) + args = (self.peer, self.mailfrom, self.rcpttos, self.received_data) + if self.require_SMTPUTF8: + status = self.smtp_server.process_smtputf8_message(*args) + else: + status = self.smtp_server.process_message(*args) + self._set_post_data_state() if not status: self.push('250 OK') else: @@ -355,26 +396,34 @@ def smtp_HELO(self, arg): if not arg: self.push('501 Syntax: HELO hostname') return + # See issue #21783 for a discussion of this behavior. if self.seen_greeting: self.push('503 Duplicate HELO/EHLO') - else: - self.seen_greeting = arg - self.extended_smtp = False - self.push('250 %s' % self.fqdn) + return + self._set_rset_state() + self.seen_greeting = arg + self.push('250 %s' % self.fqdn) def smtp_EHLO(self, arg): if not arg: self.push('501 Syntax: EHLO hostname') return + # See issue #21783 for a discussion of this behavior. if self.seen_greeting: self.push('503 Duplicate HELO/EHLO') - else: - self.seen_greeting = arg - self.extended_smtp = True - self.push('250-%s' % self.fqdn) - if self.data_size_limit: - self.push('250-SIZE %s' % self.data_size_limit) - self.push('250 HELP') + return + self._set_rset_state() + self.seen_greeting = arg + self.extended_smtp = True + self.push('250-%s' % self.fqdn) + if self.data_size_limit: + self.push('250-SIZE %s' % self.data_size_limit) + self.command_size_limits['MAIL'] += 26 + if self.enable_SMTPUTF8: + self.push('250-8BITMIME') + self.push('250-SMTPUTF8') + self.command_size_limits['MAIL'] += 10 + self.push('250 HELP') def smtp_NOOP(self, arg): if arg: @@ -407,8 +456,8 @@ def _getaddr(self, arg): def _getparams(self, params): # Return any parameters that appear to be syntactically valid according # to RFC 1869, ignore all others. (Postel rule: accept what we can.) - params = [param.split('=', 1) for param in params.split() - if '=' in param] + params = [param.split('=', 1) if '=' in param else (param, True) + for param in params.split()] return {k: v for k, v in params if k.isalnum()} def smtp_HELP(self, arg): @@ -486,6 +535,14 @@ def smtp_MAIL(self, arg): if params is None: self.push(syntaxerr) return + body = params.pop('BODY', '7BIT') + if self.enable_SMTPUTF8 and params.pop('SMTPUTF8', False): + if body != '8BITMIME': + self.push('501 Syntax: MAIL FROM: <address>' + ' [BODY=8BITMIME SMTPUTF8]') + return + else: + self.require_SMTPUTF8 = True size = params.pop('SIZE', None) if size: if not size.isdigit(): @@ -546,11 +603,7 @@ def smtp_RSET(self, arg): if arg: self.push('501 Syntax: RSET') return - # Resets the sender, recipients, and data, but not the greeting - self.mailfrom = None - self.rcpttos = [] - self.received_data = '' - self.smtp_state = self.COMMAND + self._set_rset_state() self.push('250 OK') def smtp_DATA(self, arg): @@ -577,13 +630,29 @@ class SMTPServer(asyncore.dispatcher): channel_class = SMTPChannel def __init__(self, localaddr, remoteaddr, - data_size_limit=DATA_SIZE_DEFAULT, map=None): + data_size_limit=DATA_SIZE_DEFAULT, map=None, + enable_SMTPUTF8=False, decode_data=None): self._localaddr = localaddr self._remoteaddr = remoteaddr self.data_size_limit = data_size_limit + self.enable_SMTPUTF8 = enable_SMTPUTF8 + if enable_SMTPUTF8: + if decode_data: + raise ValueError("The decode_data and enable_SMTPUTF8" + " parameters cannot be set to True at the" + " same time.") + decode_data = False + if decode_data is None: + warn("The decode_data default of True will change to False in 3.6;" + " specify an explicit value for this keyword", + DeprecationWarning, 2) + decode_data = True + self._decode_data = decode_data asyncore.dispatcher.__init__(self, map=map) try: - self.create_socket(socket.AF_INET, socket.SOCK_STREAM) + gai_results = socket.getaddrinfo(*localaddr, + type=socket.SOCK_STREAM) + self.create_socket(gai_results[0][0], gai_results[0][1]) # try to re-use a server port if possible self.set_reuse_addr() self.bind(localaddr) @@ -598,8 +667,13 @@ def __init__(self, localaddr, remoteaddr, def handle_accepted(self, conn, addr): print('Incoming connection from %s' % repr(addr), file=DEBUGSTREAM) - channel = self.channel_class(self, conn, addr, self.data_size_limit, - self._map) + channel = self.channel_class(self, + conn, + addr, + self.data_size_limit, + self._map, + self.enable_SMTPUTF8, + self._decode_data) # API for "doing something useful with the message" def process_message(self, peer, mailfrom, rcpttos, data): @@ -620,29 +694,63 @@ def process_message(self, peer, mailfrom, rcpttos, data): containing a `.' followed by other text has had the leading dot removed. - This function should return None, for a normal `250 Ok' response; - otherwise it returns the desired response string in RFC 821 format. + This function should return None for a normal `250 Ok' response; + otherwise, it should return the desired response string in RFC 821 + format. + + """ + raise NotImplementedError + + # API for processing messeges needing Unicode support (RFC 6531, RFC 6532). + def process_smtputf8_message(self, peer, mailfrom, rcpttos, data): + """Same as ``process_message`` but for messages for which the client + has sent the SMTPUTF8 parameter with the MAIL command (see the + enable_SMTPUTF8 parameter of the constructor). + + This function should return None for a normal `250 Ok' response; + otherwise, it should return the desired response string in RFC 6531 + format. """ raise NotImplementedError class DebuggingServer(SMTPServer): - # Do something with the gathered message - def process_message(self, peer, mailfrom, rcpttos, data): + + def _print_message_content(self, peer, data): inheaders = 1 - lines = data.split('\n') - print('---------- MESSAGE FOLLOWS ----------') + lines = data.splitlines() for line in lines: # headers first if inheaders and not line: - print('X-Peer:', peer[0]) + peerheader = 'X-Peer: ' + peer[0] + if not isinstance(data, str): + # decoded_data=false; make header match other binary output + peerheader = repr(peerheader.encode('utf-8')) + print(peerheader) inheaders = 0 + if not isinstance(data, str): + # Avoid spurious 'str on bytes instance' warning. + line = repr(line) print(line) + + def process_message(self, peer, mailfrom, rcpttos, data): + print('---------- MESSAGE FOLLOWS ----------') + self._print_message_content(peer, data) + print('------------ END MESSAGE ------------') + + def process_smtputf8_message(self, peer, mailfrom, rcpttos, data): + print('----- SMTPUTF8 MESSAGE FOLLOWS ------') + self._print_message_content(peer, data) print('------------ END MESSAGE ------------') class PureProxy(SMTPServer): + def __init__(self, *args, **kwargs): + if 'enable_SMTPUTF8' in kwargs and kwargs['enable_SMTPUTF8']: + raise ValueError("PureProxy does not support SMTPUTF8.") + super(PureProxy, self).__init__(*args, **kwargs) + def process_message(self, peer, mailfrom, rcpttos, data): lines = data.split('\n') # Look for the last header @@ -683,6 +791,11 @@ def _deliver(self, mailfrom, rcpttos, data): class MailmanProxy(PureProxy): + def __init__(self, *args, **kwargs): + if 'enable_SMTPUTF8' in kwargs and kwargs['enable_SMTPUTF8']: + raise ValueError("MailmanProxy does not support SMTPUTF8.") + super(PureProxy, self).__init__(*args, **kwargs) + def process_message(self, peer, mailfrom, rcpttos, data): from io import StringIO from Mailman import Utils @@ -761,17 +874,19 @@ def process_message(self, peer, mailfrom, rcpttos, data): class Options: - setuid = 1 + setuid = True classname = 'PureProxy' size_limit = None + enable_SMTPUTF8 = False def parseargs(): global DEBUGSTREAM try: opts, args = getopt.getopt( - sys.argv[1:], 'nVhc:s:d', - ['class=', 'nosetuid', 'version', 'help', 'size=', 'debug']) + sys.argv[1:], 'nVhc:s:du', + ['class=', 'nosetuid', 'version', 'help', 'size=', 'debug', + 'smtputf8']) except getopt.error as e: usage(1, e) @@ -783,11 +898,13 @@ def parseargs(): print(__version__) sys.exit(0) elif opt in ('-n', '--nosetuid'): - options.setuid = 0 + options.setuid = False elif opt in ('-c', '--class'): options.classname = arg elif opt in ('-d', '--debug'): DEBUGSTREAM = sys.stderr + elif opt in ('-u', '--smtputf8'): + options.enable_SMTPUTF8 = True elif opt in ('-s', '--size'): try: int_size = int(arg) @@ -842,7 +959,7 @@ def parseargs(): class_ = getattr(mod, classname) proxy = class_((options.localhost, options.localport), (options.remotehost, options.remoteport), - options.size_limit) + options.size_limit, enable_SMTPUTF8=options.enable_SMTPUTF8) if options.setuid: try: import pwd diff --git a/Lib/smtplib.py b/Lib/smtplib.py old mode 100644 new mode 100755 index 6fc65f6b6a3a..327a45473fa3 --- a/Lib/smtplib.py +++ b/Lib/smtplib.py @@ -62,6 +62,7 @@ SMTP_SSL_PORT = 465 CRLF = "\r\n" bCRLF = b"\r\n" +_MAXLINE = 8192 # more than 8 times larger than RFC 821, 4.5.3 OLDSTYLE_AUTH = re.compile(r"auth=(.*)", re.I) @@ -232,6 +233,7 @@ def __init__(self, host='', port=0, local_hostname=None, will be used. """ + self._host = host self.timeout = timeout self.esmtp_features = {} self.source_address = source_address @@ -364,7 +366,7 @@ def getreply(self): self.file = self.sock.makefile('rb') while 1: try: - line = self.file.readline() + line = self.file.readline(_MAXLINE + 1) except OSError as e: self.close() raise SMTPServerDisconnected("Connection unexpectedly closed: " @@ -374,6 +376,9 @@ def getreply(self): raise SMTPServerDisconnected("Connection unexpectedly closed") if self.debuglevel > 0: print('reply:', repr(line), file=stderr) + if len(line) > _MAXLINE: + self.close() + raise SMTPResponseException(500, "Line too long.") resp.append(line[4:].strip(b' \t\r\n')) code = line[:3] # Check that the error code is syntactically correct. @@ -474,6 +479,18 @@ def rset(self): """SMTP 'rset' command -- resets session.""" return self.docmd("rset") + def _rset(self): + """Internal 'rset' command which ignores any SMTPServerDisconnected error. + + Used internally in the library, since the server disconnected error + should appear to the application when the *next* command is issued, if + we are doing an internal "safety" reset. + """ + try: + self.rset() + except SMTPServerDisconnected: + pass + def noop(self): """SMTP 'noop' command -- doesn't do anything :>""" return self.docmd("noop") @@ -554,12 +571,60 @@ def ehlo_or_helo_if_needed(self): if not (200 <= code <= 299): raise SMTPHeloError(code, resp) + def auth(self, mechanism, authobject): + """Authentication command - requires response processing. + + 'mechanism' specifies which authentication mechanism is to + be used - the valid values are those listed in the 'auth' + element of 'esmtp_features'. + + 'authobject' must be a callable object taking a single argument: + + data = authobject(challenge) + + It will be called to process the server's challenge response; the + challenge argument it is passed will be a bytes. It should return + bytes data that will be base64 encoded and sent to the server. + """ + + mechanism = mechanism.upper() + (code, resp) = self.docmd("AUTH", mechanism) + # Server replies with 334 (challenge) or 535 (not supported) + if code == 334: + challenge = base64.decodebytes(resp) + response = encode_base64( + authobject(challenge).encode('ascii'), eol='') + (code, resp) = self.docmd(response) + if code in (235, 503): + return (code, resp) + raise SMTPAuthenticationError(code, resp) + + def auth_cram_md5(self, challenge): + """ Authobject to use with CRAM-MD5 authentication. Requires self.user + and self.password to be set.""" + return self.user + " " + hmac.HMAC( + self.password.encode('ascii'), challenge, 'md5').hexdigest() + + def auth_plain(self, challenge): + """ Authobject to use with PLAIN authentication. Requires self.user and + self.password to be set.""" + return "\0%s\0%s" % (self.user, self.password) + + def auth_login(self, challenge): + """ Authobject to use with LOGIN authentication. Requires self.user and + self.password to be set.""" + (code, resp) = self.docmd( + encode_base64(self.user.encode('ascii'), eol='')) + if code == 334: + return self.password + raise SMTPAuthenticationError(code, resp) + def login(self, user, password): """Log in on an SMTP server that requires authentication. The arguments are: - - user: The user name to authenticate with. - - password: The password for the authentication. + - user: The user name to authenticate with. + - password: The password for the authentication. If there has been no previous EHLO or HELO command this session, this method tries ESMTP EHLO first. @@ -576,63 +641,40 @@ def login(self, user, password): found. """ - def encode_cram_md5(challenge, user, password): - challenge = base64.decodebytes(challenge) - response = user + " " + hmac.HMAC(password.encode('ascii'), - challenge, 'md5').hexdigest() - return encode_base64(response.encode('ascii'), eol='') - - def encode_plain(user, password): - s = "\0%s\0%s" % (user, password) - return encode_base64(s.encode('ascii'), eol='') - - AUTH_PLAIN = "PLAIN" - AUTH_CRAM_MD5 = "CRAM-MD5" - AUTH_LOGIN = "LOGIN" - self.ehlo_or_helo_if_needed() - if not self.has_extn("auth"): raise SMTPException("SMTP AUTH extension not supported by server.") # Authentication methods the server claims to support advertised_authlist = self.esmtp_features["auth"].split() - # List of authentication methods we support: from preferred to - # less preferred methods. Except for the purpose of testing the weaker - # ones, we prefer stronger methods like CRAM-MD5: - preferred_auths = [AUTH_CRAM_MD5, AUTH_PLAIN, AUTH_LOGIN] + # Authentication methods we can handle in our preferred order: + preferred_auths = ['CRAM-MD5', 'PLAIN', 'LOGIN'] - # We try the authentication methods the server advertises, but only the - # ones *we* support. And in our preferred order. - authlist = [auth for auth in preferred_auths if auth in advertised_authlist] + # We try the supported authentications in our preferred order, if + # the server supports them. + authlist = [auth for auth in preferred_auths + if auth in advertised_authlist] if not authlist: raise SMTPException("No suitable authentication method found.") # Some servers advertise authentication methods they don't really # support, so if authentication fails, we continue until we've tried # all methods. + self.user, self.password = user, password for authmethod in authlist: - if authmethod == AUTH_CRAM_MD5: - (code, resp) = self.docmd("AUTH", AUTH_CRAM_MD5) - if code == 334: - (code, resp) = self.docmd(encode_cram_md5(resp, user, password)) - elif authmethod == AUTH_PLAIN: - (code, resp) = self.docmd("AUTH", - AUTH_PLAIN + " " + encode_plain(user, password)) - elif authmethod == AUTH_LOGIN: - (code, resp) = self.docmd("AUTH", - "%s %s" % (AUTH_LOGIN, encode_base64(user.encode('ascii'), eol=''))) - if code == 334: - (code, resp) = self.docmd(encode_base64(password.encode('ascii'), eol='')) - - # 235 == 'Authentication successful' - # 503 == 'Error: already authenticated' - if code in (235, 503): - return (code, resp) + method_name = 'auth_' + authmethod.lower().replace('-', '_') + try: + (code, resp) = self.auth(authmethod, getattr(self, method_name)) + # 235 == 'Authentication successful' + # 503 == 'Error: already authenticated' + if code in (235, 503): + return (code, resp) + except SMTPAuthenticationError as e: + last_exception = e - # We could not login sucessfully. Return result of last attempt. - raise SMTPAuthenticationError(code, resp) + # We could not login successfully. Return result of last attempt. + raise last_exception def starttls(self, keyfile=None, certfile=None, context=None): """Puts the connection to the SMTP server into TLS mode. @@ -667,7 +709,8 @@ def starttls(self, keyfile=None, certfile=None, context=None): if context is None: context = ssl._create_stdlib_context(certfile=certfile, keyfile=keyfile) - self.sock = context.wrap_socket(self.sock) + self.sock = context.wrap_socket(self.sock, + server_hostname=self._host) self.file = None # RFC 3207: # The client MUST discard any knowledge obtained from @@ -756,7 +799,7 @@ def sendmail(self, from_addr, to_addrs, msg, mail_options=[], if code == 421: self.close() else: - self.rset() + self._rset() raise SMTPSenderRefused(code, resp, from_addr) senderrs = {} if isinstance(to_addrs, str): @@ -770,14 +813,14 @@ def sendmail(self, from_addr, to_addrs, msg, mail_options=[], raise SMTPRecipientsRefused(senderrs) if len(senderrs) == len(to_addrs): # the server refused all our recipients - self.rset() + self._rset() raise SMTPRecipientsRefused(senderrs) (code, resp) = self.data(msg) if code != 250: if code == 421: self.close() else: - self.rset() + self._rset() raise SMTPDataError(code, resp) #if we got here then somebody got our mail return senderrs @@ -847,6 +890,10 @@ def close(self): def quit(self): """Terminate the SMTP session.""" res = self.docmd("quit") + # A new EHLO is required after reconnecting with connect() + self.ehlo_resp = self.helo_resp = None + self.esmtp_features = {} + self.does_esmtp = False self.close() return res @@ -892,7 +939,8 @@ def _get_socket(self, host, port, timeout): print('connect:', (host, port), file=stderr) new_socket = socket.create_connection((host, port), timeout, self.source_address) - new_socket = self.context.wrap_socket(new_socket) + new_socket = self.context.wrap_socket(new_socket, + server_hostname=self._host) return new_socket __all__.append("SMTP_SSL") diff --git a/Lib/sndhdr.py b/Lib/sndhdr.py index 240e5072f8fd..e5901ec58338 100644 --- a/Lib/sndhdr.py +++ b/Lib/sndhdr.py @@ -32,6 +32,11 @@ __all__ = ['what', 'whathdr'] +from collections import namedtuple + +SndHeaders = namedtuple('SndHeaders', + 'filetype framerate nchannels nframes sampwidth') + def what(filename): """Guess the type of a sound file.""" res = whathdr(filename) @@ -45,7 +50,7 @@ def whathdr(filename): for tf in tests: res = tf(h, f) if res: - return res + return SndHeaders(*res) return None diff --git a/Lib/socket.py b/Lib/socket.py index 6d67b3d2824b..9c39c69eaced 100644 --- a/Lib/socket.py +++ b/Lib/socket.py @@ -35,11 +35,13 @@ error -- exception raised for I/O errors has_ipv6 -- boolean value indicating if IPv6 is supported -Integer constants: +IntEnum constants: AF_INET, AF_UNIX -- socket domains (first argument to socket() call) SOCK_STREAM, SOCK_DGRAM, SOCK_RAW -- socket types (second argument) +Integer constants: + Many other constants may be defined; these may be used in calls to the setsockopt() and getsockopt() methods. """ @@ -47,7 +49,7 @@ import _socket from _socket import * -import os, sys, io +import os, sys, io, selectors from enum import IntEnum try: @@ -58,7 +60,8 @@ EAGAIN = getattr(errno, 'EAGAIN', 11) EWOULDBLOCK = getattr(errno, 'EWOULDBLOCK', 11) -__all__ = ["getfqdn", "create_connection"] +__all__ = ["fromfd", "getfqdn", "create_connection", + "AddressFamily", "SocketKind"] __all__.extend(os._get_exports_list(_socket)) # Set up the socket.AF_* socket.SOCK_* constants as members of IntEnums for @@ -71,10 +74,15 @@ if name.isupper() and name.startswith('AF_')}) globals().update(AddressFamily.__members__) -SocketType = IntEnum('SocketType', +SocketKind = IntEnum('SocketKind', {name: value for name, value in globals().items() if name.isupper() and name.startswith('SOCK_')}) -globals().update(SocketType.__members__) +globals().update(SocketKind.__members__) + + +_LOCALHOST = '127.0.0.1' +_LOCALHOST_V6 = '::1' + def _intenum_converter(value, enum_klass): """Convert a numeric family value to an IntEnum member. @@ -109,6 +117,9 @@ def _intenum_converter(value, enum_klass): __all__.append("errorTab") +class _GiveupOnSendfile(Exception): pass + + class socket(_socket.socket): """A subclass of _socket.socket adding the makefile() method.""" @@ -138,7 +149,7 @@ def __repr__(self): closed = getattr(self, '_closed', False) s = "<%s.%s%s fd=%i, family=%s, type=%s, proto=%i" \ % (self.__class__.__module__, - self.__class__.__name__, + self.__class__.__qualname__, " [closed]" if closed else "", self.fileno(), self.family, @@ -198,9 +209,8 @@ def makefile(self, mode="r", buffering=None, *, except the only mode characters supported are 'r', 'w' and 'b'. The semantics are similar too. (XXX refactor to share code?) """ - for c in mode: - if c not in {"r", "w", "b"}: - raise ValueError("invalid mode %r (only r, w, b allowed)") + if not set(mode) <= {"r", "w", "b"}: + raise ValueError("invalid mode %r (only r, w, b allowed)" % (mode,)) writing = "w" in mode reading = "r" in mode or not writing assert reading or writing @@ -233,6 +243,149 @@ def makefile(self, mode="r", buffering=None, *, text.mode = mode return text + if hasattr(os, 'sendfile'): + + def _sendfile_use_sendfile(self, file, offset=0, count=None): + self._check_sendfile_params(file, offset, count) + sockno = self.fileno() + try: + fileno = file.fileno() + except (AttributeError, io.UnsupportedOperation) as err: + raise _GiveupOnSendfile(err) # not a regular file + try: + fsize = os.fstat(fileno).st_size + except OSError: + raise _GiveupOnSendfile(err) # not a regular file + if not fsize: + return 0 # empty file + blocksize = fsize if not count else count + + timeout = self.gettimeout() + if timeout == 0: + raise ValueError("non-blocking sockets are not supported") + # poll/select have the advantage of not requiring any + # extra file descriptor, contrarily to epoll/kqueue + # (also, they require a single syscall). + if hasattr(selectors, 'PollSelector'): + selector = selectors.PollSelector() + else: + selector = selectors.SelectSelector() + selector.register(sockno, selectors.EVENT_WRITE) + + total_sent = 0 + # localize variable access to minimize overhead + selector_select = selector.select + os_sendfile = os.sendfile + try: + while True: + if timeout and not selector_select(timeout): + raise _socket.timeout('timed out') + if count: + blocksize = count - total_sent + if blocksize <= 0: + break + try: + sent = os_sendfile(sockno, fileno, offset, blocksize) + except BlockingIOError: + if not timeout: + # Block until the socket is ready to send some + # data; avoids hogging CPU resources. + selector_select() + continue + except OSError as err: + if total_sent == 0: + # We can get here for different reasons, the main + # one being 'file' is not a regular mmap(2)-like + # file, in which case we'll fall back on using + # plain send(). + raise _GiveupOnSendfile(err) + raise err from None + else: + if sent == 0: + break # EOF + offset += sent + total_sent += sent + return total_sent + finally: + if total_sent > 0 and hasattr(file, 'seek'): + file.seek(offset) + else: + def _sendfile_use_sendfile(self, file, offset=0, count=None): + raise _GiveupOnSendfile( + "os.sendfile() not available on this platform") + + def _sendfile_use_send(self, file, offset=0, count=None): + self._check_sendfile_params(file, offset, count) + if self.gettimeout() == 0: + raise ValueError("non-blocking sockets are not supported") + if offset: + file.seek(offset) + blocksize = min(count, 8192) if count else 8192 + total_sent = 0 + # localize variable access to minimize overhead + file_read = file.read + sock_send = self.send + try: + while True: + if count: + blocksize = min(count - total_sent, blocksize) + if blocksize <= 0: + break + data = memoryview(file_read(blocksize)) + if not data: + break # EOF + while True: + try: + sent = sock_send(data) + except BlockingIOError: + continue + else: + total_sent += sent + if sent < len(data): + data = data[sent:] + else: + break + return total_sent + finally: + if total_sent > 0 and hasattr(file, 'seek'): + file.seek(offset + total_sent) + + def _check_sendfile_params(self, file, offset, count): + if 'b' not in getattr(file, 'mode', 'b'): + raise ValueError("file should be opened in binary mode") + if not self.type & SOCK_STREAM: + raise ValueError("only SOCK_STREAM type sockets are supported") + if count is not None: + if not isinstance(count, int): + raise TypeError( + "count must be a positive integer (got {!r})".format(count)) + if count <= 0: + raise ValueError( + "count must be a positive integer (got {!r})".format(count)) + + def sendfile(self, file, offset=0, count=None): + """sendfile(file[, offset[, count]]) -> sent + + Send a file until EOF is reached by using high-performance + os.sendfile() and return the total number of bytes which + were sent. + *file* must be a regular file object opened in binary mode. + If os.sendfile() is not available (e.g. Windows) or file is + not a regular file socket.send() will be used instead. + *offset* tells from where to start reading the file. + If specified, *count* is the total number of bytes 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 file.tell() can be used to figure out the number of + bytes which were sent. + The socket must be of SOCK_STREAM type. + Non-blocking sockets are not supported. + """ + try: + return self._sendfile_use_sendfile(file, offset, count) + except _GiveupOnSendfile: + return self._sendfile_use_send(file, offset, count) + def _decref_socketios(self): if self._io_refs > 0: self._io_refs -= 1 @@ -269,7 +422,7 @@ def family(self): def type(self): """Read-only access to the socket type. """ - return _intenum_converter(super().type, SocketType) + return _intenum_converter(super().type, SocketKind) if os.name == 'nt': def get_inheritable(self): @@ -297,10 +450,11 @@ def fromfd(fd, family, type, proto=0): def fromshare(info): """ fromshare(info) -> socket object - Create a socket object from a the bytes object returned by + Create a socket object from the bytes object returned by socket.share(pid). """ return socket(0, 0, 0, info) + __all__.append("fromshare") if hasattr(_socket, "socketpair"): @@ -322,6 +476,52 @@ def socketpair(family=None, type=SOCK_STREAM, proto=0): b = socket(family, type, proto, b.detach()) return a, b +else: + + # Origin: https://gist.github.com/4325783, by Geert Jansen. Public domain. + def socketpair(family=AF_INET, type=SOCK_STREAM, proto=0): + if family == AF_INET: + host = _LOCALHOST + elif family == AF_INET6: + host = _LOCALHOST_V6 + else: + raise ValueError("Only AF_INET and AF_INET6 socket address families " + "are supported") + if type != SOCK_STREAM: + raise ValueError("Only SOCK_STREAM socket type is supported") + if proto != 0: + raise ValueError("Only protocol zero is supported") + + # We create a connected TCP socket. Note the trick with + # setblocking(False) that prevents us from having to create a thread. + lsock = socket(family, type, proto) + try: + lsock.bind((host, 0)) + lsock.listen() + # On IPv6, ignore flow_info and scope_id + addr, port = lsock.getsockname()[:2] + csock = socket(family, type, proto) + try: + csock.setblocking(False) + try: + csock.connect((addr, port)) + except (BlockingIOError, InterruptedError): + pass + csock.setblocking(True) + ssock, _ = lsock.accept() + except: + csock.close() + raise + finally: + lsock.close() + return (ssock, csock) + +socketpair.__doc__ = """socketpair([family[, type[, proto]]]) -> (socket object, socket object) +Create a pair of socket objects from the sockets returned by the platform +socketpair() function. +The arguments are the same as for socket() except the default family is AF_UNIX +if defined on the platform; otherwise, the default is AF_INET. +""" _blocking_errnos = { EAGAIN, EWOULDBLOCK } @@ -372,8 +572,6 @@ def readinto(self, b): except timeout: self._timeout_occurred = True raise - except InterruptedError: - continue except error as e: if e.args[0] in _blocking_errnos: return None @@ -530,6 +728,6 @@ def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): for res in _socket.getaddrinfo(host, port, family, type, proto, flags): af, socktype, proto, canonname, sa = res addrlist.append((_intenum_converter(af, AddressFamily), - _intenum_converter(socktype, SocketType), + _intenum_converter(socktype, SocketKind), proto, canonname, sa)) return addrlist diff --git a/Lib/socketserver.py b/Lib/socketserver.py index e9e4e4e4add0..0ce8e8106581 100644 --- a/Lib/socketserver.py +++ b/Lib/socketserver.py @@ -94,7 +94,7 @@ class will essentially render the service "deaf" while one request is Another approach to handling multiple simultaneous requests in an environment that supports neither threads nor fork (or where these are too expensive or inappropriate for the service) is to maintain an -explicit table of partially finished requests and to use select() to +explicit table of partially finished requests and to use a selector to decide which request to work on next (or whether to handle a new incoming request). This is particularly important for stream services where each client can potentially be connected for a long time (if @@ -104,7 +104,6 @@ class will essentially render the service "deaf" while one request is - Standard classes for Sun RPC (which uses either UDP or TCP) - Standard mix-in classes to implement various authentication and encryption schemes -- Standard framework for select-based multiplexing XXX Open problems: - What to do with out-of-band data? @@ -130,32 +129,31 @@ class will essentially render the service "deaf" while one request is import socket -import select -import sys +import selectors import os import errno try: import threading except ImportError: import dummy_threading as threading +from time import monotonic as time -__all__ = ["TCPServer","UDPServer","ForkingUDPServer","ForkingTCPServer", - "ThreadingUDPServer","ThreadingTCPServer","BaseRequestHandler", - "StreamRequestHandler","DatagramRequestHandler", - "ThreadingMixIn", "ForkingMixIn"] +__all__ = ["BaseServer", "TCPServer", "UDPServer", "ForkingUDPServer", + "ForkingTCPServer", "ThreadingUDPServer", "ThreadingTCPServer", + "BaseRequestHandler", "StreamRequestHandler", + "DatagramRequestHandler", "ThreadingMixIn", "ForkingMixIn"] if hasattr(socket, "AF_UNIX"): __all__.extend(["UnixStreamServer","UnixDatagramServer", "ThreadingUnixStreamServer", "ThreadingUnixDatagramServer"]) -def _eintr_retry(func, *args): - """restart a system call interrupted by EINTR""" - while True: - try: - return func(*args) - except OSError as e: - if e.errno != errno.EINTR: - raise +# poll/select have the advantage of not requiring any extra file descriptor, +# contrarily to epoll/kqueue (also, they require a single syscall). +if hasattr(selectors, 'PollSelector'): + _ServerSelector = selectors.PollSelector +else: + _ServerSelector = selectors.SelectSelector + class BaseServer: @@ -167,7 +165,7 @@ class BaseServer: - serve_forever(poll_interval=0.5) - shutdown() - handle_request() # if you do not use serve_forever() - - fileno() -> int # for select() + - fileno() -> int # for selector Methods that may be overridden: @@ -228,17 +226,19 @@ def serve_forever(self, poll_interval=0.5): """ self.__is_shut_down.clear() try: - while not self.__shutdown_request: - # XXX: Consider using another file descriptor or - # connecting to the socket to wake this up instead of - # polling. Polling reduces our responsiveness to a - # shutdown request and wastes cpu at all other times. - r, w, e = _eintr_retry(select.select, [self], [], [], - poll_interval) - if self in r: - self._handle_request_noblock() - - self.service_actions() + # XXX: Consider using another file descriptor or connecting to the + # socket to wake this up instead of polling. Polling reduces our + # responsiveness to a shutdown request and wastes cpu at all other + # times. + with _ServerSelector() as selector: + selector.register(self, selectors.EVENT_READ) + + while not self.__shutdown_request: + ready = selector.select(poll_interval) + if ready: + self._handle_request_noblock() + + self.service_actions() finally: self.__shutdown_request = False self.__is_shut_down.set() @@ -261,16 +261,16 @@ def service_actions(self): """ pass - # The distinction between handling, getting, processing and - # finishing a request is fairly arbitrary. Remember: + # The distinction between handling, getting, processing and finishing a + # request is fairly arbitrary. Remember: # - # - handle_request() is the top-level call. It calls - # select, get_request(), verify_request() and process_request() + # - handle_request() is the top-level call. It calls selector.select(), + # get_request(), verify_request() and process_request() # - get_request() is different for stream or datagram sockets - # - process_request() is the place that may fork a new process - # or create a new thread to finish the request - # - finish_request() instantiates the request handler class; - # this constructor will handle the request all by itself + # - process_request() is the place that may fork a new process or create a + # new thread to finish the request + # - finish_request() instantiates the request handler class; this + # constructor will handle the request all by itself def handle_request(self): """Handle one request, possibly blocking. @@ -284,18 +284,30 @@ def handle_request(self): timeout = self.timeout elif self.timeout is not None: timeout = min(timeout, self.timeout) - fd_sets = _eintr_retry(select.select, [self], [], [], timeout) - if not fd_sets[0]: - self.handle_timeout() - return - self._handle_request_noblock() + if timeout is not None: + deadline = time() + timeout + + # Wait until a request arrives or the timeout expires - the loop is + # necessary to accommodate early wakeups due to EINTR. + with _ServerSelector() as selector: + selector.register(self, selectors.EVENT_READ) + + while True: + ready = selector.select(timeout) + if ready: + return self._handle_request_noblock() + else: + if timeout is not None: + timeout = deadline - time() + if timeout < 0: + return self.handle_timeout() def _handle_request_noblock(self): """Handle one request, without blocking. - I assume that select.select has returned that the socket is - readable before this function was called, so there should be - no risk of blocking in get_request(). + I assume that selector.select() has returned that the socket is + readable before this function was called, so there should be no risk of + blocking in get_request(). """ try: request, client_address = self.get_request() @@ -378,7 +390,7 @@ class TCPServer(BaseServer): - serve_forever(poll_interval=0.5) - shutdown() - handle_request() # if you don't use serve_forever() - - fileno() -> int # for select() + - fileno() -> int # for selector Methods that may be overridden: @@ -427,8 +439,12 @@ def __init__(self, server_address, RequestHandlerClass, bind_and_activate=True): self.socket = socket.socket(self.address_family, self.socket_type) if bind_and_activate: - self.server_bind() - self.server_activate() + try: + self.server_bind() + self.server_activate() + except: + self.server_close() + raise def server_bind(self): """Called by constructor to bind the socket. @@ -460,7 +476,7 @@ def server_close(self): def fileno(self): """Return socket file number. - Interface required by select(). + Interface required by selector. """ return self.socket.fileno() @@ -524,35 +540,37 @@ class ForkingMixIn: def collect_children(self): """Internal routine to wait for children that have exited.""" - if self.active_children is None: return + if self.active_children is None: + return + + # If we're above the max number of children, wait and reap them until + # we go back below threshold. Note that we use waitpid(-1) below to be + # able to collect children in size(<defunct children>) syscalls instead + # of size(<children>): the downside is that this might reap children + # which we didn't spawn, which is why we only resort to this when we're + # above max_children. while len(self.active_children) >= self.max_children: - # XXX: This will wait for any child process, not just ones - # spawned by this library. This could confuse other - # libraries that expect to be able to wait for their own - # children. try: - pid, status = os.waitpid(0, 0) + pid, _ = os.waitpid(-1, 0) + self.active_children.discard(pid) + except ChildProcessError: + # we don't have any children, we're done + self.active_children.clear() except OSError: - pid = None - if pid not in self.active_children: continue - self.active_children.remove(pid) - - # XXX: This loop runs more system calls than it ought - # to. There should be a way to put the active_children into a - # process group and then use os.waitpid(-pgid) to wait for any - # of that set, but I couldn't find a way to allocate pgids - # that couldn't collide. - for child in self.active_children: + break + + # Now reap all defunct children. + for pid in self.active_children.copy(): try: - pid, status = os.waitpid(child, os.WNOHANG) + pid, _ = os.waitpid(pid, os.WNOHANG) + # if the child hasn't exited yet, pid will be 0 and ignored by + # discard() below + self.active_children.discard(pid) + except ChildProcessError: + # someone else reaped it + self.active_children.discard(pid) except OSError: - pid = None - if not pid: continue - try: - self.active_children.remove(pid) - except ValueError as e: - raise ValueError('%s. x=%d and list=%r' % (e.message, pid, - self.active_children)) + pass def handle_timeout(self): """Wait for zombies after self.timeout seconds of inactivity. @@ -574,8 +592,8 @@ def process_request(self, request, client_address): if pid: # Parent process if self.active_children is None: - self.active_children = [] - self.active_children.append(pid) + self.active_children = set() + self.active_children.add(pid) self.close_request(request) return else: diff --git a/Lib/sqlite3/dbapi2.py b/Lib/sqlite3/dbapi2.py index 9a0b76645e1e..991682ce9ef3 100644 --- a/Lib/sqlite3/dbapi2.py +++ b/Lib/sqlite3/dbapi2.py @@ -22,6 +22,7 @@ import datetime import time +import collections.abc from _sqlite3 import * @@ -50,6 +51,7 @@ def TimestampFromTicks(ticks): sqlite_version_info = tuple([int(x) for x in sqlite_version.split(".")]) Binary = memoryview +collections.abc.Sequence.register(Row) def register_adapters_and_converters(): def adapt_date(val): diff --git a/Lib/sqlite3/test/factory.py b/Lib/sqlite3/test/factory.py index 0314ebd4411a..98dcae5d6c4a 100644 --- a/Lib/sqlite3/test/factory.py +++ b/Lib/sqlite3/test/factory.py @@ -23,6 +23,7 @@ import unittest import sqlite3 as sqlite +from collections.abc import Sequence class MyConnection(sqlite.Connection): def __init__(self, *args, **kwargs): @@ -96,9 +97,19 @@ def CheckSqliteRowIndex(self): self.assertEqual(col1, 1, "by name: wrong result for column 'A'") self.assertEqual(col2, 2, "by name: wrong result for column 'B'") - col1, col2 = row[0], row[1] - self.assertEqual(col1, 1, "by index: wrong result for column 0") - self.assertEqual(col2, 2, "by index: wrong result for column 1") + self.assertEqual(row[0], 1, "by index: wrong result for column 0") + self.assertEqual(row[1], 2, "by index: wrong result for column 1") + self.assertEqual(row[-1], 2, "by index: wrong result for column -1") + self.assertEqual(row[-2], 1, "by index: wrong result for column -2") + + with self.assertRaises(IndexError): + row['c'] + with self.assertRaises(IndexError): + row[2] + with self.assertRaises(IndexError): + row[-3] + with self.assertRaises(IndexError): + row[2**1000] def CheckSqliteRowIter(self): """Checks if the row object is iterable""" @@ -112,6 +123,7 @@ def CheckSqliteRowAsTuple(self): self.con.row_factory = sqlite.Row row = self.con.execute("select 1 as a, 2 as b").fetchone() t = tuple(row) + self.assertEqual(t, (row['a'], row['b'])) def CheckSqliteRowAsDict(self): """Checks if the row object can be correctly converted to a dictionary""" @@ -141,6 +153,15 @@ def CheckSqliteRowHashCmp(self): self.assertNotEqual(row_1, row_3) self.assertNotEqual(hash(row_1), hash(row_3)) + def CheckSqliteRowAsSequence(self): + """ Checks if the row object can act like a sequence """ + self.con.row_factory = sqlite.Row + row = self.con.execute("select 1 as a, 2 as b").fetchone() + + as_tuple = tuple(row) + self.assertEqual(list(reversed(row)), list(reversed(as_tuple))) + self.assertIsInstance(row, Sequence) + def tearDown(self): self.con.close() diff --git a/Lib/sqlite3/test/hooks.py b/Lib/sqlite3/test/hooks.py index 60f760548213..ede0becad4eb 100644 --- a/Lib/sqlite3/test/hooks.py +++ b/Lib/sqlite3/test/hooks.py @@ -162,7 +162,7 @@ def progress(): create table bar (a, b) """) second_count = len(progress_calls) - self.assertGreater(first_count, second_count) + self.assertGreaterEqual(first_count, second_count) def CheckCancelOperation(self): """ diff --git a/Lib/sqlite3/test/regression.py b/Lib/sqlite3/test/regression.py index b927cb3ed185..eaaaa2c528eb 100644 --- a/Lib/sqlite3/test/regression.py +++ b/Lib/sqlite3/test/regression.py @@ -330,6 +330,21 @@ def CheckConvertTimestampMicrosecondPadding(self): datetime.datetime(2012, 4, 4, 15, 6, 0, 123456), ]) + def CheckInvalidIsolationLevelType(self): + # isolation level is a string, not an integer + self.assertRaises(TypeError, + sqlite.connect, ":memory:", isolation_level=123) + + + def CheckNullCharacter(self): + # Issue #21147 + con = sqlite.connect(":memory:") + self.assertRaises(ValueError, con, "\0select 1") + self.assertRaises(ValueError, con, "select 1\0") + cur = con.cursor() + self.assertRaises(ValueError, cur.execute, " \0select 2") + self.assertRaises(ValueError, cur.execute, "select 2\0") + def suite(): regression_suite = unittest.makeSuite(RegressionTests, "Check") diff --git a/Lib/sre_compile.py b/Lib/sre_compile.py index 3a5083fde872..30a5fae4851c 100644 --- a/Lib/sre_compile.py +++ b/Lib/sre_compile.py @@ -10,25 +10,56 @@ """Internal support module for sre""" -import _sre, sys +import _sre import sre_parse from sre_constants import * -from _sre import MAXREPEAT assert _sre.MAGIC == MAGIC, "SRE module mismatch" -if _sre.CODESIZE == 2: - MAXCODE = 65535 -else: - MAXCODE = 0xFFFFFFFF - -def _identityfunction(x): - return x - -_LITERAL_CODES = set([LITERAL, NOT_LITERAL]) -_REPEATING_CODES = set([REPEAT, MIN_REPEAT, MAX_REPEAT]) -_SUCCESS_CODES = set([SUCCESS, FAILURE]) -_ASSERT_CODES = set([ASSERT, ASSERT_NOT]) +_LITERAL_CODES = {LITERAL, NOT_LITERAL} +_REPEATING_CODES = {REPEAT, MIN_REPEAT, MAX_REPEAT} +_SUCCESS_CODES = {SUCCESS, FAILURE} +_ASSERT_CODES = {ASSERT, ASSERT_NOT} + +# Sets of lowercase characters which have the same uppercase. +_equivalences = ( + # LATIN SMALL LETTER I, LATIN SMALL LETTER DOTLESS I + (0x69, 0x131), # iı + # LATIN SMALL LETTER S, LATIN SMALL LETTER LONG S + (0x73, 0x17f), # sÅ¿ + # MICRO SIGN, GREEK SMALL LETTER MU + (0xb5, 0x3bc), # µμ + # COMBINING GREEK YPOGEGRAMMENI, GREEK SMALL LETTER IOTA, GREEK PROSGEGRAMMENI + (0x345, 0x3b9, 0x1fbe), # \u0345ιι + # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS, GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA + (0x390, 0x1fd3), # Îá¿“ + # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS, GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA + (0x3b0, 0x1fe3), # ΰΰ + # GREEK SMALL LETTER BETA, GREEK BETA SYMBOL + (0x3b2, 0x3d0), # Î²Ï + # GREEK SMALL LETTER EPSILON, GREEK LUNATE EPSILON SYMBOL + (0x3b5, 0x3f5), # εϵ + # GREEK SMALL LETTER THETA, GREEK THETA SYMBOL + (0x3b8, 0x3d1), # θϑ + # GREEK SMALL LETTER KAPPA, GREEK KAPPA SYMBOL + (0x3ba, 0x3f0), # κϰ + # GREEK SMALL LETTER PI, GREEK PI SYMBOL + (0x3c0, 0x3d6), # πϖ + # GREEK SMALL LETTER RHO, GREEK RHO SYMBOL + (0x3c1, 0x3f1), # Ïϱ + # GREEK SMALL LETTER FINAL SIGMA, GREEK SMALL LETTER SIGMA + (0x3c2, 0x3c3), # ςσ + # GREEK SMALL LETTER PHI, GREEK PHI SYMBOL + (0x3c6, 0x3d5), # φϕ + # LATIN SMALL LETTER S WITH DOT ABOVE, LATIN SMALL LETTER LONG S WITH DOT ABOVE + (0x1e61, 0x1e9b), # ṡẛ + # LATIN SMALL LIGATURE LONG S T, LATIN SMALL LIGATURE ST + (0xfb05, 0xfb06), # ſtst +) + +# Maps the lowercase code to lowercase codes which have the same uppercase. +_ignorecase_fixes = {i: tuple(j for j in t if i != j) + for t in _equivalences for i in t} def _compile(code, pattern, flags): # internal: compile a (sub)pattern @@ -38,68 +69,86 @@ def _compile(code, pattern, flags): REPEATING_CODES = _REPEATING_CODES SUCCESS_CODES = _SUCCESS_CODES ASSERT_CODES = _ASSERT_CODES + if (flags & SRE_FLAG_IGNORECASE and + not (flags & SRE_FLAG_LOCALE) and + flags & SRE_FLAG_UNICODE): + fixes = _ignorecase_fixes + else: + fixes = None for op, av in pattern: if op in LITERAL_CODES: if flags & SRE_FLAG_IGNORECASE: - emit(OPCODES[OP_IGNORE[op]]) - emit(_sre.getlower(av, flags)) + lo = _sre.getlower(av, flags) + if fixes and lo in fixes: + emit(IN_IGNORE) + skip = _len(code); emit(0) + if op is NOT_LITERAL: + emit(NEGATE) + for k in (lo,) + fixes[lo]: + emit(LITERAL) + emit(k) + emit(FAILURE) + code[skip] = _len(code) - skip + else: + emit(OP_IGNORE[op]) + emit(lo) else: - emit(OPCODES[op]) + emit(op) emit(av) elif op is IN: if flags & SRE_FLAG_IGNORECASE: - emit(OPCODES[OP_IGNORE[op]]) + emit(OP_IGNORE[op]) def fixup(literal, flags=flags): return _sre.getlower(literal, flags) else: - emit(OPCODES[op]) - fixup = _identityfunction + emit(op) + fixup = None skip = _len(code); emit(0) - _compile_charset(av, flags, code, fixup) + _compile_charset(av, flags, code, fixup, fixes) code[skip] = _len(code) - skip elif op is ANY: if flags & SRE_FLAG_DOTALL: - emit(OPCODES[ANY_ALL]) + emit(ANY_ALL) else: - emit(OPCODES[ANY]) + emit(ANY) elif op in REPEATING_CODES: if flags & SRE_FLAG_TEMPLATE: raise error("internal: unsupported template operator") elif _simple(av) and op is not REPEAT: if op is MAX_REPEAT: - emit(OPCODES[REPEAT_ONE]) + emit(REPEAT_ONE) else: - emit(OPCODES[MIN_REPEAT_ONE]) + emit(MIN_REPEAT_ONE) skip = _len(code); emit(0) emit(av[0]) emit(av[1]) _compile(code, av[2], flags) - emit(OPCODES[SUCCESS]) + emit(SUCCESS) code[skip] = _len(code) - skip else: - emit(OPCODES[REPEAT]) + emit(REPEAT) skip = _len(code); emit(0) emit(av[0]) emit(av[1]) _compile(code, av[2], flags) code[skip] = _len(code) - skip if op is MAX_REPEAT: - emit(OPCODES[MAX_UNTIL]) + emit(MAX_UNTIL) else: - emit(OPCODES[MIN_UNTIL]) + emit(MIN_UNTIL) elif op is SUBPATTERN: if av[0]: - emit(OPCODES[MARK]) + emit(MARK) emit((av[0]-1)*2) # _compile_info(code, av[1], flags) _compile(code, av[1], flags) if av[0]: - emit(OPCODES[MARK]) + emit(MARK) emit((av[0]-1)*2+1) elif op in SUCCESS_CODES: - emit(OPCODES[op]) + emit(op) elif op in ASSERT_CODES: - emit(OPCODES[op]) + emit(op) skip = _len(code); emit(0) if av[0] >= 0: emit(0) # look ahead @@ -109,57 +158,57 @@ def fixup(literal, flags=flags): raise error("look-behind requires fixed-width pattern") emit(lo) # look behind _compile(code, av[1], flags) - emit(OPCODES[SUCCESS]) + emit(SUCCESS) code[skip] = _len(code) - skip elif op is CALL: - emit(OPCODES[op]) + emit(op) skip = _len(code); emit(0) _compile(code, av, flags) - emit(OPCODES[SUCCESS]) + emit(SUCCESS) code[skip] = _len(code) - skip elif op is AT: - emit(OPCODES[op]) + emit(op) if flags & SRE_FLAG_MULTILINE: av = AT_MULTILINE.get(av, av) if flags & SRE_FLAG_LOCALE: av = AT_LOCALE.get(av, av) elif flags & SRE_FLAG_UNICODE: av = AT_UNICODE.get(av, av) - emit(ATCODES[av]) + emit(av) elif op is BRANCH: - emit(OPCODES[op]) + emit(op) tail = [] tailappend = tail.append for av in av[1]: skip = _len(code); emit(0) # _compile_info(code, av, flags) _compile(code, av, flags) - emit(OPCODES[JUMP]) + emit(JUMP) tailappend(_len(code)); emit(0) code[skip] = _len(code) - skip - emit(0) # end of branch + emit(FAILURE) # end of branch for tail in tail: code[tail] = _len(code) - tail elif op is CATEGORY: - emit(OPCODES[op]) + emit(op) if flags & SRE_FLAG_LOCALE: av = CH_LOCALE[av] elif flags & SRE_FLAG_UNICODE: av = CH_UNICODE[av] - emit(CHCODES[av]) + emit(av) elif op is GROUPREF: if flags & SRE_FLAG_IGNORECASE: - emit(OPCODES[OP_IGNORE[op]]) + emit(OP_IGNORE[op]) else: - emit(OPCODES[op]) + emit(op) emit(av-1) elif op is GROUPREF_EXISTS: - emit(OPCODES[op]) + emit(op) emit(av[0]-1) skipyes = _len(code); emit(0) _compile(code, av[1], flags) if av[2]: - emit(OPCODES[JUMP]) + emit(JUMP) skipno = _len(code); emit(0) code[skipyes] = _len(code) - skipyes + 1 _compile(code, av[2], flags) @@ -169,36 +218,34 @@ def fixup(literal, flags=flags): else: raise ValueError("unsupported operand type", op) -def _compile_charset(charset, flags, code, fixup=None): +def _compile_charset(charset, flags, code, fixup=None, fixes=None): # compile charset subprogram emit = code.append - if fixup is None: - fixup = _identityfunction - for op, av in _optimize_charset(charset, fixup): - emit(OPCODES[op]) + for op, av in _optimize_charset(charset, fixup, fixes): + emit(op) if op is NEGATE: pass elif op is LITERAL: - emit(fixup(av)) - elif op is RANGE: - emit(fixup(av[0])) - emit(fixup(av[1])) + emit(av) + elif op is RANGE or op is RANGE_IGNORE: + emit(av[0]) + emit(av[1]) elif op is CHARSET: code.extend(av) elif op is BIGCHARSET: code.extend(av) elif op is CATEGORY: if flags & SRE_FLAG_LOCALE: - emit(CHCODES[CH_LOCALE[av]]) + emit(CH_LOCALE[av]) elif flags & SRE_FLAG_UNICODE: - emit(CHCODES[CH_UNICODE[av]]) + emit(CH_UNICODE[av]) else: - emit(CHCODES[av]) + emit(av) else: raise error("internal: unsupported set operator") - emit(OPCODES[FAILURE]) + emit(FAILURE) -def _optimize_charset(charset, fixup): +def _optimize_charset(charset, fixup, fixes): # internal: optimize character set out = [] tail = [] @@ -207,10 +254,27 @@ def _optimize_charset(charset, fixup): while True: try: if op is LITERAL: - charmap[fixup(av)] = 1 + if fixup: + lo = fixup(av) + charmap[lo] = 1 + if fixes and lo in fixes: + for k in fixes[lo]: + charmap[k] = 1 + else: + charmap[av] = 1 elif op is RANGE: - for i in range(fixup(av[0]), fixup(av[1])+1): - charmap[i] = 1 + r = range(av[0], av[1]+1) + if fixup: + r = map(fixup, r) + if fixup and fixes: + for i in r: + charmap[i] = 1 + if i in fixes: + for k in fixes[i]: + charmap[k] = 1 + else: + for i in r: + charmap[i] = 1 elif op is NEGATE: out.append((op, av)) else: @@ -220,7 +284,12 @@ def _optimize_charset(charset, fixup): # character set contains non-UCS1 character codes charmap += b'\0' * 0xff00 continue - # character set contains non-BMP character codes + # Character set contains non-BMP character codes. + # There are only two ranges of cased non-BMP characters: + # 10400-1044F (Deseret) and 118A0-118DF (Warang Citi), + # and for both ranges RANGE_IGNORE works. + if fixup and op is RANGE: + op = RANGE_IGNORE tail.append((op, av)) break @@ -247,8 +316,10 @@ def _optimize_charset(charset, fixup): else: out.append((RANGE, (p, q - 1))) out += tail - if len(out) < len(charset): + # if the case was changed or new representation is more compact + if fixup or len(out) < len(charset): return out + # else original character set is good enough return charset # use bitmap @@ -298,6 +369,7 @@ def _optimize_charset(charset, fixup): return out _CODEBITS = _sre.CODESIZE * 8 +MAXCODE = (1 << _CODEBITS) - 1 _BITS_TRANS = b'0' + b'1' * 255 def _mk_bitmap(bits, _CODEBITS=_CODEBITS, _int=int): s = bits.translate(_BITS_TRANS)[::-1] @@ -306,8 +378,7 @@ def _mk_bitmap(bits, _CODEBITS=_CODEBITS, _int=int): def _bytes_to_codes(b): # Convert block indices to word array - import array - a = array.array('I', b) + a = memoryview(b).cast('I') assert a.itemsize == _sre.CODESIZE assert len(a) * a.itemsize == len(b) return a.tolist() @@ -343,8 +414,11 @@ def _compile_info(code, pattern, flags): # this contains min/max pattern width, and an optional literal # prefix or a character map lo, hi = pattern.getwidth() + if hi > MAXCODE: + hi = MAXCODE if lo == 0: - return # not worth it + code.extend([INFO, 4, 0, lo, hi]) + return # look for a literal prefix prefix = [] prefixappend = prefix.append @@ -402,21 +476,21 @@ def _compile_info(code, pattern, flags): elif op is IN: charset = av ## if prefix: -## print "*** PREFIX", prefix, prefix_skip +## print("*** PREFIX", prefix, prefix_skip) ## if charset: -## print "*** CHARSET", charset +## print("*** CHARSET", charset) # add an info block emit = code.append - emit(OPCODES[INFO]) + emit(INFO) skip = len(code); emit(0) # literal flag mask = 0 if prefix: mask = SRE_INFO_PREFIX if len(prefix) == prefix_skip == len(pattern.data): - mask = mask + SRE_INFO_LITERAL + mask = mask | SRE_INFO_LITERAL elif charset: - mask = mask + SRE_INFO_CHARSET + mask = mask | SRE_INFO_CHARSET emit(mask) # pattern length if lo < MAXCODE: @@ -424,10 +498,7 @@ def _compile_info(code, pattern, flags): else: emit(MAXCODE) prefix = prefix[:MAXCODE] - if hi < MAXCODE: - emit(hi) - else: - emit(0) + emit(min(hi, MAXCODE)) # add literal prefix if prefix: emit(len(prefix)) # length @@ -453,7 +524,7 @@ def _code(p, flags): # compile the pattern _compile(code, p.data, flags) - code.append(OPCODES[SUCCESS]) + code.append(SUCCESS) return code @@ -468,13 +539,7 @@ def compile(p, flags=0): code = _code(p, flags) - # print code - - # XXX: <fl> get rid of this limitation! - if p.pattern.groups > 100: - raise AssertionError( - "sorry, but this version only supports 100 named groups" - ) + # print(code) # map in either direction groupindex = p.pattern.groupdict diff --git a/Lib/sre_constants.py b/Lib/sre_constants.py index 23e3516006cd..8b6bbfaaf36d 100644 --- a/Lib/sre_constants.py +++ b/Lib/sre_constants.py @@ -13,153 +13,115 @@ # update when constants are added or removed -MAGIC = 20031017 +MAGIC = 20140917 -from _sre import MAXREPEAT +from _sre import MAXREPEAT, MAXGROUPS # SRE standard exception (access as sre.error) # should this really be here? class error(Exception): - pass + def __init__(self, msg, pattern=None, pos=None): + self.msg = msg + self.pattern = pattern + self.pos = pos + if pattern is not None and pos is not None: + msg = '%s at position %d' % (msg, pos) + if isinstance(pattern, str): + newline = '\n' + else: + newline = b'\n' + self.lineno = pattern.count(newline, 0, pos) + 1 + self.colno = pos - pattern.rfind(newline, 0, pos) + if newline in pattern: + msg = '%s (line %d, column %d)' % (msg, self.lineno, self.colno) + else: + self.lineno = self.colno = None + super().__init__(msg) + + +class _NamedIntConstant(int): + def __new__(cls, value, name): + self = super(_NamedIntConstant, cls).__new__(cls, value) + self.name = name + return self + + def __str__(self): + return self.name + + __repr__ = __str__ + +MAXREPEAT = _NamedIntConstant(MAXREPEAT, 'MAXREPEAT') + +def _makecodes(names): + names = names.strip().split() + items = [_NamedIntConstant(i, name) for i, name in enumerate(names)] + globals().update({item.name: item for item in items}) + return items # operators +# failure=0 success=1 (just because it looks better that way :-) +OPCODES = _makecodes(""" + FAILURE SUCCESS + + ANY ANY_ALL + ASSERT ASSERT_NOT + AT + BRANCH + CALL + CATEGORY + CHARSET BIGCHARSET + GROUPREF GROUPREF_EXISTS GROUPREF_IGNORE + IN IN_IGNORE + INFO + JUMP + LITERAL LITERAL_IGNORE + MARK + MAX_UNTIL + MIN_UNTIL + NOT_LITERAL NOT_LITERAL_IGNORE + NEGATE + RANGE + REPEAT + REPEAT_ONE + SUBPATTERN + MIN_REPEAT_ONE + RANGE_IGNORE -FAILURE = "failure" -SUCCESS = "success" - -ANY = "any" -ANY_ALL = "any_all" -ASSERT = "assert" -ASSERT_NOT = "assert_not" -AT = "at" -BIGCHARSET = "bigcharset" -BRANCH = "branch" -CALL = "call" -CATEGORY = "category" -CHARSET = "charset" -GROUPREF = "groupref" -GROUPREF_IGNORE = "groupref_ignore" -GROUPREF_EXISTS = "groupref_exists" -IN = "in" -IN_IGNORE = "in_ignore" -INFO = "info" -JUMP = "jump" -LITERAL = "literal" -LITERAL_IGNORE = "literal_ignore" -MARK = "mark" -MAX_REPEAT = "max_repeat" -MAX_UNTIL = "max_until" -MIN_REPEAT = "min_repeat" -MIN_UNTIL = "min_until" -NEGATE = "negate" -NOT_LITERAL = "not_literal" -NOT_LITERAL_IGNORE = "not_literal_ignore" -RANGE = "range" -REPEAT = "repeat" -REPEAT_ONE = "repeat_one" -SUBPATTERN = "subpattern" -MIN_REPEAT_ONE = "min_repeat_one" + MIN_REPEAT MAX_REPEAT +""") +del OPCODES[-2:] # remove MIN_REPEAT and MAX_REPEAT # positions -AT_BEGINNING = "at_beginning" -AT_BEGINNING_LINE = "at_beginning_line" -AT_BEGINNING_STRING = "at_beginning_string" -AT_BOUNDARY = "at_boundary" -AT_NON_BOUNDARY = "at_non_boundary" -AT_END = "at_end" -AT_END_LINE = "at_end_line" -AT_END_STRING = "at_end_string" -AT_LOC_BOUNDARY = "at_loc_boundary" -AT_LOC_NON_BOUNDARY = "at_loc_non_boundary" -AT_UNI_BOUNDARY = "at_uni_boundary" -AT_UNI_NON_BOUNDARY = "at_uni_non_boundary" +ATCODES = _makecodes(""" + AT_BEGINNING AT_BEGINNING_LINE AT_BEGINNING_STRING + AT_BOUNDARY AT_NON_BOUNDARY + AT_END AT_END_LINE AT_END_STRING + AT_LOC_BOUNDARY AT_LOC_NON_BOUNDARY + AT_UNI_BOUNDARY AT_UNI_NON_BOUNDARY +""") # categories -CATEGORY_DIGIT = "category_digit" -CATEGORY_NOT_DIGIT = "category_not_digit" -CATEGORY_SPACE = "category_space" -CATEGORY_NOT_SPACE = "category_not_space" -CATEGORY_WORD = "category_word" -CATEGORY_NOT_WORD = "category_not_word" -CATEGORY_LINEBREAK = "category_linebreak" -CATEGORY_NOT_LINEBREAK = "category_not_linebreak" -CATEGORY_LOC_WORD = "category_loc_word" -CATEGORY_LOC_NOT_WORD = "category_loc_not_word" -CATEGORY_UNI_DIGIT = "category_uni_digit" -CATEGORY_UNI_NOT_DIGIT = "category_uni_not_digit" -CATEGORY_UNI_SPACE = "category_uni_space" -CATEGORY_UNI_NOT_SPACE = "category_uni_not_space" -CATEGORY_UNI_WORD = "category_uni_word" -CATEGORY_UNI_NOT_WORD = "category_uni_not_word" -CATEGORY_UNI_LINEBREAK = "category_uni_linebreak" -CATEGORY_UNI_NOT_LINEBREAK = "category_uni_not_linebreak" - -OPCODES = [ - - # failure=0 success=1 (just because it looks better that way :-) - FAILURE, SUCCESS, - - ANY, ANY_ALL, - ASSERT, ASSERT_NOT, - AT, - BRANCH, - CALL, - CATEGORY, - CHARSET, BIGCHARSET, - GROUPREF, GROUPREF_EXISTS, GROUPREF_IGNORE, - IN, IN_IGNORE, - INFO, - JUMP, - LITERAL, LITERAL_IGNORE, - MARK, - MAX_UNTIL, - MIN_UNTIL, - NOT_LITERAL, NOT_LITERAL_IGNORE, - NEGATE, - RANGE, - REPEAT, - REPEAT_ONE, - SUBPATTERN, - MIN_REPEAT_ONE +CHCODES = _makecodes(""" + CATEGORY_DIGIT CATEGORY_NOT_DIGIT + CATEGORY_SPACE CATEGORY_NOT_SPACE + CATEGORY_WORD CATEGORY_NOT_WORD + CATEGORY_LINEBREAK CATEGORY_NOT_LINEBREAK + CATEGORY_LOC_WORD CATEGORY_LOC_NOT_WORD + CATEGORY_UNI_DIGIT CATEGORY_UNI_NOT_DIGIT + CATEGORY_UNI_SPACE CATEGORY_UNI_NOT_SPACE + CATEGORY_UNI_WORD CATEGORY_UNI_NOT_WORD + CATEGORY_UNI_LINEBREAK CATEGORY_UNI_NOT_LINEBREAK +""") -] - -ATCODES = [ - AT_BEGINNING, AT_BEGINNING_LINE, AT_BEGINNING_STRING, AT_BOUNDARY, - AT_NON_BOUNDARY, AT_END, AT_END_LINE, AT_END_STRING, - AT_LOC_BOUNDARY, AT_LOC_NON_BOUNDARY, AT_UNI_BOUNDARY, - AT_UNI_NON_BOUNDARY -] - -CHCODES = [ - CATEGORY_DIGIT, CATEGORY_NOT_DIGIT, CATEGORY_SPACE, - CATEGORY_NOT_SPACE, CATEGORY_WORD, CATEGORY_NOT_WORD, - CATEGORY_LINEBREAK, CATEGORY_NOT_LINEBREAK, CATEGORY_LOC_WORD, - CATEGORY_LOC_NOT_WORD, CATEGORY_UNI_DIGIT, CATEGORY_UNI_NOT_DIGIT, - CATEGORY_UNI_SPACE, CATEGORY_UNI_NOT_SPACE, CATEGORY_UNI_WORD, - CATEGORY_UNI_NOT_WORD, CATEGORY_UNI_LINEBREAK, - CATEGORY_UNI_NOT_LINEBREAK -] - -def makedict(list): - d = {} - i = 0 - for item in list: - d[item] = i - i = i + 1 - return d - -OPCODES = makedict(OPCODES) -ATCODES = makedict(ATCODES) -CHCODES = makedict(CHCODES) # replacement operations for "ignore case" mode OP_IGNORE = { GROUPREF: GROUPREF_IGNORE, IN: IN_IGNORE, LITERAL: LITERAL_IGNORE, - NOT_LITERAL: NOT_LITERAL_IGNORE + NOT_LITERAL: NOT_LITERAL_IGNORE, + RANGE: RANGE_IGNORE, } AT_MULTILINE = { @@ -217,9 +179,9 @@ def makedict(list): if __name__ == "__main__": def dump(f, d, prefix): - items = sorted(d.items(), key=lambda a: a[1]) - for k, v in items: - f.write("#define %s_%s %s\n" % (prefix, k.upper(), v)) + items = sorted(d) + for item in items: + f.write("#define %s_%s %d\n" % (prefix, item, item)) f = open("sre_constants.h", "w") f.write("""\ /* diff --git a/Lib/sre_parse.py b/Lib/sre_parse.py index 6583ef6c4a7d..98afd7cb4a68 100644 --- a/Lib/sre_parse.py +++ b/Lib/sre_parse.py @@ -12,20 +12,20 @@ # XXX: show string offset and offending character for all errors -import sys - from sre_constants import * -from _sre import MAXREPEAT SPECIAL_CHARS = ".\\[{()*+?^$|" REPEAT_CHARS = "*+?{" -DIGITS = set("0123456789") +DIGITS = frozenset("0123456789") + +OCTDIGITS = frozenset("01234567") +HEXDIGITS = frozenset("0123456789abcdefABCDEF") -OCTDIGITS = set("01234567") -HEXDIGITS = set("0123456789abcdefABCDEF") +WHITESPACE = frozenset(" \t\n\r\v\f") -WHITESPACE = set(" \t\n\r\v\f") +_REPEATCODES = frozenset({MIN_REPEAT, MAX_REPEAT}) +_UNITCODES = frozenset({ANY, RANGE, IN, LITERAL, NOT_LITERAL, CATEGORY}) ESCAPES = { r"\a": (LITERAL, ord("\a")), @@ -68,24 +68,36 @@ class Pattern: # master pattern object. keeps track of global attributes def __init__(self): self.flags = 0 - self.open = [] - self.groups = 1 self.groupdict = {} + self.subpatterns = [None] # group 0 + self.lookbehindgroups = None + @property + def groups(self): + return len(self.subpatterns) def opengroup(self, name=None): gid = self.groups - self.groups = gid + 1 + self.subpatterns.append(None) + if self.groups > MAXGROUPS: + raise error("groups number is too large") if name is not None: ogid = self.groupdict.get(name, None) if ogid is not None: - raise error("redefinition of group name %s as group %d; " - "was group %d" % (repr(name), gid, ogid)) + raise error("redefinition of group name %r as group %d; " + "was group %d" % (name, gid, ogid)) self.groupdict[name] = gid - self.open.append(gid) return gid - def closegroup(self, gid): - self.open.remove(gid) + def closegroup(self, gid, p): + self.subpatterns[gid] = p def checkgroup(self, gid): - return gid < self.groups and gid not in self.open + return gid < self.groups and self.subpatterns[gid] is not None + + def checklookbehindgroup(self, gid, source): + if self.lookbehindgroups is not None: + if not self.checkgroup(gid): + raise source.error('cannot refer to an open group') + if gid >= self.lookbehindgroups: + raise source.error('cannot refer to group defined in the same ' + 'lookbehind subpattern') class SubPattern: # a subpattern, in intermediate form @@ -96,33 +108,45 @@ def __init__(self, pattern, data=None): self.data = data self.width = None def dump(self, level=0): - nl = 1 + nl = True seqtypes = (tuple, list) for op, av in self.data: - print(level*" " + op, end=' '); nl = 0 - if op == "in": + print(level*" " + str(op), end='') + if op is IN: # member sublanguage - print(); nl = 1 + print() for op, a in av: - print((level+1)*" " + op, a) - elif op == "branch": - print(); nl = 1 - i = 0 - for a in av[1]: - if i > 0: - print(level*" " + "or") - a.dump(level+1); nl = 1 - i = i + 1 + print((level+1)*" " + str(op), a) + elif op is BRANCH: + print() + for i, a in enumerate(av[1]): + if i: + print(level*" " + "OR") + a.dump(level+1) + elif op is GROUPREF_EXISTS: + condgroup, item_yes, item_no = av + print('', condgroup) + item_yes.dump(level+1) + if item_no: + print(level*" " + "ELSE") + item_no.dump(level+1) elif isinstance(av, seqtypes): + nl = False for a in av: if isinstance(a, SubPattern): - if not nl: print() - a.dump(level+1); nl = 1 + if not nl: + print() + a.dump(level+1) + nl = True else: - print(a, end=' ') ; nl = 0 + if not nl: + print(' ', end='') + print(a, end='') + nl = False + if not nl: + print() else: - print(av, end=' ') ; nl = 0 - if not nl: print() + print('', av) def __repr__(self): return repr(self.data) def __len__(self): @@ -141,11 +165,9 @@ def append(self, code): self.data.append(code) def getwidth(self): # determine the width (min, max) for this subpattern - if self.width: + if self.width is not None: return self.width lo = hi = 0 - UNITCODES = (ANY, RANGE, IN, LITERAL, NOT_LITERAL, CATEGORY) - REPEATCODES = (MIN_REPEAT, MAX_REPEAT) for op, av in self.data: if op is BRANCH: i = MAXREPEAT - 1 @@ -164,14 +186,28 @@ def getwidth(self): i, j = av[1].getwidth() lo = lo + i hi = hi + j - elif op in REPEATCODES: + elif op in _REPEATCODES: i, j = av[2].getwidth() lo = lo + i * av[0] hi = hi + j * av[1] - elif op in UNITCODES: + elif op in _UNITCODES: lo = lo + 1 hi = hi + 1 - elif op == SUCCESS: + elif op is GROUPREF: + i, j = self.pattern.subpatterns[av].getwidth() + lo = lo + i + hi = hi + j + elif op is GROUPREF_EXISTS: + i, j = av[1].getwidth() + if av[2] is not None: + l, h = av[2].getwidth() + i = min(i, l) + j = max(j, h) + else: + i = 0 + lo = lo + i + hi = hi + j + elif op is SUCCESS: break self.width = min(lo, MAXREPEAT - 1), min(hi, MAXREPEAT) return self.width @@ -180,33 +216,33 @@ class Tokenizer: def __init__(self, string): self.istext = isinstance(string, str) self.string = string + if not self.istext: + string = str(string, 'latin1') + self.decoded_string = string self.index = 0 + self.next = None self.__next() def __next(self): - if self.index >= len(self.string): + index = self.index + try: + char = self.decoded_string[index] + except IndexError: self.next = None return - char = self.string[self.index:self.index+1] - # Special case for the str8, since indexing returns a integer - # XXX This is only needed for test_bug_926075 in test_re.py - if char and not self.istext: - char = chr(char[0]) if char == "\\": + index += 1 try: - c = self.string[self.index + 1] + char += self.decoded_string[index] except IndexError: - raise error("bogus escape (end of line)") - if not self.istext: - c = chr(c) - char = char + c - self.index = self.index + len(char) + raise error("bogus escape (end of line)", + self.string, len(self.string) - 1) from None + self.index = index + 1 self.next = char - def match(self, char, skip=1): + def match(self, char): if char == self.next: - if skip: - self.__next() - return 1 - return 0 + self.__next() + return True + return False def get(self): this = self.next self.__next() @@ -220,10 +256,25 @@ def getwhile(self, n, charset): result += c self.__next() return result + def getuntil(self, terminator): + result = '' + while True: + c = self.next + self.__next() + if c is None: + raise self.error("unterminated name") + if c == terminator: + break + result += c + return result def tell(self): - return self.index, self.next + return self.index - len(self.next or '') def seek(self, index): - self.index, self.next = index + self.index = index + self.__next() + + def error(self, msg, offset=0): + return error(msg, self.string, self.tell() - offset) # The following three functions are not used in this module anymore, but we keep # them here (with DeprecationWarnings) for backwards compatibility. @@ -258,7 +309,7 @@ def _class_escape(source, escape): if code: return code code = CATEGORIES.get(escape) - if code and code[0] == IN: + if code and code[0] is IN: return code try: c = escape[1:2] @@ -267,7 +318,7 @@ def _class_escape(source, escape): escape += source.getwhile(2, HEXDIGITS) if len(escape) != 4: raise ValueError - return LITERAL, int(escape[2:], 16) & 0xff + return LITERAL, int(escape[2:], 16) elif c == "u" and source.istext: # unicode escape (exactly four digits) escape += source.getwhile(4, HEXDIGITS) @@ -285,14 +336,18 @@ def _class_escape(source, escape): elif c in OCTDIGITS: # octal escape (up to three digits) escape += source.getwhile(2, OCTDIGITS) - return LITERAL, int(escape[1:], 8) & 0xff + c = int(escape[1:], 8) + if c > 0o377: + raise source.error('octal escape value %r outside of ' + 'range 0-0o377' % escape, len(escape)) + return LITERAL, c elif c in DIGITS: raise ValueError if len(escape) == 2: return LITERAL, ord(escape[1]) except ValueError: pass - raise error("bogus escape: %s" % repr(escape)) + raise source.error("bogus escape: %r" % escape, len(escape)) def _escape(source, escape, state): # handle escape code in expression @@ -309,7 +364,7 @@ def _escape(source, escape, state): escape += source.getwhile(2, HEXDIGITS) if len(escape) != 4: raise ValueError - return LITERAL, int(escape[2:], 16) & 0xff + return LITERAL, int(escape[2:], 16) elif c == "u" and source.istext: # unicode escape (exactly four digits) escape += source.getwhile(4, HEXDIGITS) @@ -327,45 +382,48 @@ def _escape(source, escape, state): elif c == "0": # octal escape escape += source.getwhile(2, OCTDIGITS) - return LITERAL, int(escape[1:], 8) & 0xff + return LITERAL, int(escape[1:], 8) elif c in DIGITS: # octal escape *or* decimal group reference (sigh) if source.next in DIGITS: - escape = escape + source.get() + escape += source.get() if (escape[1] in OCTDIGITS and escape[2] in OCTDIGITS and source.next in OCTDIGITS): # got three octal digits; this is an octal escape - escape = escape + source.get() - return LITERAL, int(escape[1:], 8) & 0xff + escape += source.get() + c = int(escape[1:], 8) + if c > 0o377: + raise source.error('octal escape value %r outside of ' + 'range 0-0o377' % escape, + len(escape)) + return LITERAL, c # not an octal escape, so this is a group reference group = int(escape[1:]) if group < state.groups: if not state.checkgroup(group): - raise error("cannot refer to open group") + raise source.error("cannot refer to open group", + len(escape)) + state.checklookbehindgroup(group, source) return GROUPREF, group raise ValueError if len(escape) == 2: return LITERAL, ord(escape[1]) except ValueError: pass - raise error("bogus escape: %s" % repr(escape)) + raise source.error("bogus escape: %r" % escape, len(escape)) -def _parse_sub(source, state, nested=1): +def _parse_sub(source, state, nested=True): # parse an alternation: a|b|c items = [] itemsappend = items.append sourcematch = source.match - while 1: + while True: itemsappend(_parse(source, state)) - if sourcematch("|"): - continue - if not nested: + if not sourcematch("|"): break - if not source.next or sourcematch(")", 0): - break - else: - raise error("pattern not properly closed") + if nested and source.next is not None and source.next != ")": + raise source.error("pattern not properly closed") if len(items) == 1: return items[0] @@ -374,7 +432,7 @@ def _parse_sub(source, state, nested=1): subpatternappend = subpattern.append # check if all items share a common prefix - while 1: + while True: prefix = None for item in items: if not item: @@ -394,16 +452,12 @@ def _parse_sub(source, state, nested=1): # check if the branch can be replaced by a character set for item in items: - if len(item) != 1 or item[0][0] != LITERAL: + if len(item) != 1 or item[0][0] is not LITERAL: break else: # we can store this as a character set instead of a # branch (the compiler may optimize this even more) - set = [] - setappend = set.append - for item in items: - setappend(item[0]) - subpatternappend((IN, set)) + subpatternappend((IN, [item[0] for item in items])) return subpattern subpattern.append((BRANCH, (None, items))) @@ -413,21 +467,16 @@ def _parse_sub_cond(source, state, condgroup): item_yes = _parse(source, state) if source.match("|"): item_no = _parse(source, state) - if source.match("|"): - raise error("conditional backref with more than two branches") + if source.next == "|": + raise source.error("conditional backref with more than two branches") else: item_no = None - if source.next and not source.match(")", 0): - raise error("pattern not properly closed") + if source.next is not None and source.next != ")": + raise source.error("pattern not properly closed") subpattern = SubPattern(state) subpattern.append((GROUPREF_EXISTS, (condgroup, item_yes, item_no))) return subpattern -_PATTERNENDERS = set("|)") -_ASSERTCHARS = set("=!<") -_LOOKBEHINDASSERTCHARS = set("=!") -_REPEATCODES = set([MIN_REPEAT, MAX_REPEAT]) - def _parse(source, state): # parse a simple pattern subpattern = SubPattern(state) @@ -437,32 +486,35 @@ def _parse(source, state): sourceget = source.get sourcematch = source.match _len = len - PATTERNENDERS = _PATTERNENDERS - ASSERTCHARS = _ASSERTCHARS - LOOKBEHINDASSERTCHARS = _LOOKBEHINDASSERTCHARS - REPEATCODES = _REPEATCODES + _ord = ord + verbose = state.flags & SRE_FLAG_VERBOSE - while 1: + while True: - if source.next in PATTERNENDERS: - break # end of subpattern - this = sourceget() + this = source.next if this is None: break # end of pattern + if this in "|)": + break # end of subpattern + sourceget() - if state.flags & SRE_FLAG_VERBOSE: + if verbose: # skip whitespace and comments if this in WHITESPACE: continue if this == "#": - while 1: + while True: this = sourceget() - if this in (None, "\n"): + if this is None or this == "\n": break continue - if this and this[0] not in SPECIAL_CHARS: - subpatternappend((LITERAL, ord(this))) + if this[0] == "\\": + code = _escape(source, this, state) + subpatternappend(code) + + elif this not in SPECIAL_CHARS: + subpatternappend((LITERAL, _ord(this))) elif this == "[": # character set @@ -474,39 +526,38 @@ def _parse(source, state): setappend((NEGATE, None)) # check remaining characters start = set[:] - while 1: + while True: this = sourceget() + if this is None: + raise source.error("unexpected end of regular expression") if this == "]" and set != start: break - elif this and this[0] == "\\": + elif this[0] == "\\": code1 = _class_escape(source, this) - elif this: - code1 = LITERAL, ord(this) else: - raise error("unexpected end of regular expression") + code1 = LITERAL, _ord(this) if sourcematch("-"): # potential range this = sourceget() + if this is None: + raise source.error("unexpected end of regular expression") if this == "]": if code1[0] is IN: code1 = code1[1][0] setappend(code1) - setappend((LITERAL, ord("-"))) + setappend((LITERAL, _ord("-"))) break - elif this: - if this[0] == "\\": - code2 = _class_escape(source, this) - else: - code2 = LITERAL, ord(this) - if code1[0] != LITERAL or code2[0] != LITERAL: - raise error("bad character range") - lo = code1[1] - hi = code2[1] - if hi < lo: - raise error("bad character range") - setappend((RANGE, (lo, hi))) + if this[0] == "\\": + code2 = _class_escape(source, this) else: - raise error("unexpected end of regular expression") + code2 = LITERAL, _ord(this) + if code1[0] != LITERAL or code2[0] != LITERAL: + raise source.error("bad character range", len(this)) + lo = code1[1] + hi = code2[1] + if hi < lo: + raise source.error("bad character range", len(this)) + setappend((RANGE, (lo, hi))) else: if code1[0] is IN: code1 = code1[1][0] @@ -521,8 +572,9 @@ def _parse(source, state): # XXX: <fl> should add charmap optimization here subpatternappend((IN, set)) - elif this and this[0] in REPEAT_CHARS: + elif this in REPEAT_CHARS: # repeat previous item + here = source.tell() if this == "?": min, max = 0, 1 elif this == "*": @@ -532,20 +584,19 @@ def _parse(source, state): min, max = 1, MAXREPEAT elif this == "{": if source.next == "}": - subpatternappend((LITERAL, ord(this))) + subpatternappend((LITERAL, _ord(this))) continue - here = source.tell() min, max = 0, MAXREPEAT lo = hi = "" while source.next in DIGITS: - lo = lo + source.get() + lo += sourceget() if sourcematch(","): while source.next in DIGITS: - hi = hi + sourceget() + hi += sourceget() else: hi = lo if not sourcematch("}"): - subpatternappend((LITERAL, ord(this))) + subpatternappend((LITERAL, _ord(this))) source.seek(here) continue if lo: @@ -557,18 +608,21 @@ def _parse(source, state): if max >= MAXREPEAT: raise OverflowError("the repetition number is too large") if max < min: - raise error("bad repeat interval") + raise source.error("bad repeat interval", + source.tell() - here) else: - raise error("not supported") + raise source.error("not supported", len(this)) # figure out which item to repeat if subpattern: item = subpattern[-1:] else: item = None - if not item or (_len(item) == 1 and item[0][0] == AT): - raise error("nothing to repeat") - if item[0][0] in REPEATCODES: - raise error("multiple repeat") + if not item or (_len(item) == 1 and item[0][0] is AT): + raise source.error("nothing to repeat", + source.tell() - here + len(this)) + if item[0][0] in _REPEATCODES: + raise source.error("multiple repeat", + source.tell() - here + len(this)) if sourcematch("?"): subpattern[-1] = (MIN_REPEAT, (min, max, item)) else: @@ -584,129 +638,137 @@ def _parse(source, state): if sourcematch("?"): group = 0 # options - if sourcematch("P"): + char = sourceget() + if char is None: + raise self.error("unexpected end of pattern") + if char == "P": # python extensions if sourcematch("<"): # named group: skip forward to end of name - name = "" - while 1: - char = sourceget() - if char is None: - raise error("unterminated name") - if char == ">": - break - name = name + char + name = source.getuntil(">") group = 1 if not name: - raise error("missing group name") + raise source.error("missing group name", 1) if not name.isidentifier(): - raise error("bad character in group name %r" % name) + raise source.error("bad character in group name " + "%r" % name, + len(name) + 1) elif sourcematch("="): # named backreference - name = "" - while 1: - char = sourceget() - if char is None: - raise error("unterminated name") - if char == ")": - break - name = name + char + name = source.getuntil(")") if not name: - raise error("missing group name") + raise source.error("missing group name", 1) if not name.isidentifier(): - raise error("bad character in backref group name " - "%r" % name) + raise source.error("bad character in backref " + "group name %r" % name, + len(name) + 1) gid = state.groupdict.get(name) if gid is None: - raise error("unknown group name") + msg = "unknown group name: {0!r}".format(name) + raise source.error(msg, len(name) + 1) + state.checklookbehindgroup(gid, source) subpatternappend((GROUPREF, gid)) continue else: char = sourceget() if char is None: - raise error("unexpected end of pattern") - raise error("unknown specifier: ?P%s" % char) - elif sourcematch(":"): + raise source.error("unexpected end of pattern") + raise source.error("unknown specifier: ?P%s" % char, + len(char)) + elif char == ":": # non-capturing group group = 2 - elif sourcematch("#"): + elif char == "#": # comment - while 1: - if source.next is None or source.next == ")": + while True: + if source.next is None: + raise source.error("unbalanced parenthesis") + if sourceget() == ")": break - sourceget() - if not sourcematch(")"): - raise error("unbalanced parenthesis") continue - elif source.next in ASSERTCHARS: + elif char in "=!<": # lookahead assertions - char = sourceget() dir = 1 if char == "<": - if source.next not in LOOKBEHINDASSERTCHARS: - raise error("syntax error") - dir = -1 # lookbehind char = sourceget() + if char is None or char not in "=!": + raise source.error("syntax error") + dir = -1 # lookbehind + lookbehindgroups = state.lookbehindgroups + if lookbehindgroups is None: + state.lookbehindgroups = state.groups p = _parse_sub(source, state) + if dir < 0: + if lookbehindgroups is None: + state.lookbehindgroups = None if not sourcematch(")"): - raise error("unbalanced parenthesis") + raise source.error("unbalanced parenthesis") if char == "=": subpatternappend((ASSERT, (dir, p))) else: subpatternappend((ASSERT_NOT, (dir, p))) continue - elif sourcematch("("): + elif char == "(": # conditional backreference group - condname = "" - while 1: - char = sourceget() - if char is None: - raise error("unterminated name") - if char == ")": - break - condname = condname + char + condname = source.getuntil(")") group = 2 if not condname: - raise error("missing group name") + raise source.error("missing group name", 1) if condname.isidentifier(): condgroup = state.groupdict.get(condname) if condgroup is None: - raise error("unknown group name") + msg = "unknown group name: {0!r}".format(condname) + raise source.error(msg, len(condname) + 1) else: try: condgroup = int(condname) + if condgroup < 0: + raise ValueError except ValueError: - raise error("bad character in group name") - else: + raise source.error("bad character in group name", + len(condname) + 1) + if not condgroup: + raise source.error("bad group number", + len(condname) + 1) + if condgroup >= MAXGROUPS: + raise source.error("the group number is too large", + len(condname) + 1) + state.checklookbehindgroup(condgroup, source) + elif char in FLAGS: # flags - if not source.next in FLAGS: - raise error("unexpected end of pattern") + state.flags |= FLAGS[char] while source.next in FLAGS: - state.flags = state.flags | FLAGS[sourceget()] + state.flags |= FLAGS[sourceget()] + verbose = state.flags & SRE_FLAG_VERBOSE + else: + raise source.error("unexpected end of pattern") if group: # parse group contents if group == 2: # anonymous group group = None else: - group = state.opengroup(name) + try: + group = state.opengroup(name) + except error as err: + raise source.error(err.msg, len(name) + 1) if condgroup: p = _parse_sub_cond(source, state, condgroup) else: p = _parse_sub(source, state) if not sourcematch(")"): - raise error("unbalanced parenthesis") + raise source.error("unbalanced parenthesis") if group is not None: - state.closegroup(group) + state.closegroup(group, p) subpatternappend((SUBPATTERN, (group, p))) else: - while 1: + while True: char = sourceget() if char is None: - raise error("unexpected end of pattern") + raise source.error("unexpected end of pattern") if char == ")": break - raise error("unknown extension") + raise source.error("unknown extension", len(char)) elif this == "^": subpatternappend((AT, AT_BEGINNING)) @@ -714,18 +776,19 @@ def _parse(source, state): elif this == "$": subpattern.append((AT, AT_END)) - elif this and this[0] == "\\": - code = _escape(source, this, state) - subpatternappend(code) - else: - raise error("parser error") + raise source.error("parser error", len(this)) return subpattern def fix_flags(src, flags): # Check and fix flags according to the type of pattern (str or bytes) if isinstance(src, str): + if flags & SRE_FLAG_LOCALE: + import warnings + warnings.warn("LOCALE flag with a str pattern is deprecated. " + "Will be an error in 3.6", + DeprecationWarning, stacklevel=6) if not flags & SRE_FLAG_ASCII: flags |= SRE_FLAG_UNICODE elif flags & SRE_FLAG_UNICODE: @@ -733,6 +796,11 @@ def fix_flags(src, flags): else: if flags & SRE_FLAG_UNICODE: raise ValueError("can't use UNICODE flag with a bytes pattern") + if flags & SRE_FLAG_LOCALE and flags & SRE_FLAG_ASCII: + import warnings + warnings.warn("ASCII and LOCALE flags are incompatible. " + "Will be an error in 3.6", + DeprecationWarning, stacklevel=6) return flags def parse(str, flags=0, pattern=None): @@ -748,11 +816,12 @@ def parse(str, flags=0, pattern=None): p = _parse_sub(source, pattern, 0) p.pattern.flags = fix_flags(str, p.pattern.flags) - tail = source.get() - if tail == ")": - raise error("unbalanced parenthesis") - elif tail: - raise error("bogus characters at end of regular expression") + if source.next is not None: + if source.next == ")": + raise source.error("unbalanced parenthesis") + else: + raise source.error("bogus characters at end of regular expression", + len(tail)) if flags & SRE_FLAG_DEBUG: p.dump() @@ -789,26 +858,25 @@ def addgroup(index): if c == "g": name = "" if s.match("<"): - while True: - char = sget() - if char is None: - raise error("unterminated group name") - if char == ">": - break - name += char + name = s.getuntil(">") if not name: - raise error("missing group name") + raise s.error("missing group name", 1) try: index = int(name) if index < 0: - raise error("negative group number") + raise s.error("negative group number", len(name) + 1) + if index >= MAXGROUPS: + raise s.error("the group number is too large", + len(name) + 1) except ValueError: if not name.isidentifier(): - raise error("bad character in group name") + raise s.error("bad character in group name", + len(name) + 1) try: index = pattern.groupindex[name] except KeyError: - raise IndexError("unknown group name") + msg = "unknown group name: {0!r}".format(name) + raise IndexError(msg) addgroup(index) elif c == "0": if s.next in OCTDIGITS: @@ -824,7 +892,11 @@ def addgroup(index): s.next in OCTDIGITS): this += sget() isoctal = True - lappend(chr(int(this[1:], 8) & 0xff)) + c = int(this[1:], 8) + if c > 0o377: + raise s.error('octal escape value %r outside of ' + 'range 0-0o377' % this, len(this)) + lappend(chr(c)) if not isoctal: addgroup(int(this[1:])) else: @@ -845,14 +917,12 @@ def addgroup(index): def expand_template(template, match): g = match.group - sep = match.string[:0] + empty = match.string[:0] groups, literals = template literals = literals[:] try: for index, group in groups: - literals[index] = s = g(group) - if s is None: - raise error("unmatched group") + literals[index] = g(group) or empty except IndexError: raise error("invalid group reference") - return sep.join(literals) + return empty.join(literals) diff --git a/Lib/ssl.py b/Lib/ssl.py index 4c155ea7d446..37a484a0c284 100644 --- a/Lib/ssl.py +++ b/Lib/ssl.py @@ -87,17 +87,18 @@ ALERT_DESCRIPTION_UNKNOWN_PSK_IDENTITY """ +import ipaddress import textwrap import re import sys import os from collections import namedtuple -from enum import Enum as _Enum +from enum import Enum as _Enum, IntEnum as _IntEnum import _ssl # if we can't import it, let the error propagate from _ssl import OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_INFO, OPENSSL_VERSION -from _ssl import _SSLContext +from _ssl import _SSLContext, MemoryBIO from _ssl import ( SSLError, SSLZeroReturnError, SSLWantReadError, SSLWantWriteError, SSLSyscallError, SSLEOFError, @@ -106,7 +107,12 @@ from _ssl import (VERIFY_DEFAULT, VERIFY_CRL_CHECK_LEAF, VERIFY_CRL_CHECK_CHAIN, VERIFY_X509_STRICT) from _ssl import txt2obj as _txt2obj, nid2obj as _nid2obj -from _ssl import RAND_status, RAND_egd, RAND_add, RAND_bytes, RAND_pseudo_bytes +from _ssl import RAND_status, RAND_add, RAND_bytes, RAND_pseudo_bytes +try: + from _ssl import RAND_egd +except ImportError: + # LibreSSL does not provide RAND_egd + pass def _import_symbols(prefix): for n in dir(_ssl): @@ -117,41 +123,28 @@ def _import_symbols(prefix): _import_symbols('ALERT_DESCRIPTION_') _import_symbols('SSL_ERROR_') -from _ssl import HAS_SNI, HAS_ECDH, HAS_NPN +from _ssl import HAS_SNI, HAS_ECDH, HAS_NPN, HAS_ALPN -from _ssl import PROTOCOL_SSLv3, PROTOCOL_SSLv23, PROTOCOL_TLSv1 from _ssl import _OPENSSL_API_VERSION +_SSLMethod = _IntEnum('_SSLMethod', + {name: value for name, value in vars(_ssl).items() + if name.startswith('PROTOCOL_')}) +globals().update(_SSLMethod.__members__) + +_PROTOCOL_NAMES = {value: name for name, value in _SSLMethod.__members__.items()} -_PROTOCOL_NAMES = { - PROTOCOL_TLSv1: "TLSv1", - PROTOCOL_SSLv23: "SSLv23", - PROTOCOL_SSLv3: "SSLv3", -} try: - from _ssl import PROTOCOL_SSLv2 _SSLv2_IF_EXISTS = PROTOCOL_SSLv2 -except ImportError: +except NameError: _SSLv2_IF_EXISTS = None -else: - _PROTOCOL_NAMES[PROTOCOL_SSLv2] = "SSLv2" - -try: - from _ssl import PROTOCOL_TLSv1_1, PROTOCOL_TLSv1_2 -except ImportError: - pass -else: - _PROTOCOL_NAMES[PROTOCOL_TLSv1_1] = "TLSv1.1" - _PROTOCOL_NAMES[PROTOCOL_TLSv1_2] = "TLSv1.2" if sys.platform == "win32": from _ssl import enum_certificates, enum_crls -from socket import getnameinfo as _getnameinfo -from socket import SHUT_RDWR as _SHUT_RDWR from socket import socket, AF_INET, SOCK_STREAM, create_connection +from socket import SOL_SOCKET, SO_TYPE import base64 # for DER-to-PEM translation -import traceback import errno @@ -164,14 +157,35 @@ def _import_symbols(prefix): # Disable weak or insecure ciphers by default # (OpenSSL's default setting is 'DEFAULT:!aNULL:!eNULL') -_DEFAULT_CIPHERS = 'DEFAULT:!aNULL:!eNULL:!LOW:!EXPORT:!SSLv2' - -# restricted and more secure ciphers -# HIGH: high encryption cipher suites with key length >= 128 bits (no MD5) -# !aNULL: only authenticated cipher suites (no anonymous DH) -# !RC4: no RC4 streaming cipher, RC4 is broken -# !DSS: RSA is preferred over DSA -_RESTRICTED_CIPHERS = 'HIGH:!aNULL:!RC4:!DSS' +# Enable a better set of ciphers by default +# This list has been explicitly chosen to: +# * Prefer cipher suites that offer perfect forward secrecy (DHE/ECDHE) +# * Prefer ECDHE over DHE for better performance +# * Prefer any AES-GCM over any AES-CBC for better performance and security +# * Then Use HIGH cipher suites as a fallback +# * Then Use 3DES as fallback which is secure but slow +# * Disable NULL authentication, NULL encryption, and MD5 MACs for security +# reasons +_DEFAULT_CIPHERS = ( + 'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+HIGH:' + 'DH+HIGH:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+HIGH:RSA+3DES:!aNULL:' + '!eNULL:!MD5' +) + +# Restricted and more secure ciphers for the server side +# This list has been explicitly chosen to: +# * Prefer cipher suites that offer perfect forward secrecy (DHE/ECDHE) +# * Prefer ECDHE over DHE for better performance +# * Prefer any AES-GCM over any AES-CBC for better performance and security +# * Then Use HIGH cipher suites as a fallback +# * Then Use 3DES as fallback which is secure but slow +# * Disable NULL authentication, NULL encryption, MD5 MACs, DSS, and RC4 for +# security reasons +_RESTRICTED_SERVER_CIPHERS = ( + 'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+HIGH:' + 'DH+HIGH:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+HIGH:RSA+3DES:!aNULL:' + '!eNULL:!MD5:!DSS:!RC4' +) class CertificateError(ValueError): @@ -192,7 +206,7 @@ def _dnsname_match(dn, hostname, max_wildcards=1): wildcards = leftmost.count('*') if wildcards > max_wildcards: # Issue #17980: avoid denials of service by refusing more - # than one wildcard per fragment. A survery of established + # than one wildcard per fragment. A survey of established # policy among SSL implementations showed it to be a # reasonable choice. raise CertificateError( @@ -227,6 +241,17 @@ def _dnsname_match(dn, hostname, max_wildcards=1): return pat.match(hostname) +def _ipaddress_match(ipname, host_ip): + """Exact matching of IP addresses. + + RFC 6125 explicitly doesn't define an algorithm for this + (section 1.7.2 - "Out of Scope"). + """ + # OpenSSL may add a trailing newline to a subjectAltName's IP address + ip = ipaddress.ip_address(ipname.rstrip()) + return ip == host_ip + + def match_hostname(cert, hostname): """Verify that *cert* (in decoded format as returned by SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125 @@ -239,11 +264,20 @@ def match_hostname(cert, hostname): raise ValueError("empty or no certificate, match_hostname needs a " "SSL socket or SSL context with either " "CERT_OPTIONAL or CERT_REQUIRED") + try: + host_ip = ipaddress.ip_address(hostname) + except ValueError: + # Not an IP address (common case) + host_ip = None dnsnames = [] san = cert.get('subjectAltName', ()) for key, value in san: if key == 'DNS': - if _dnsname_match(value, hostname): + if host_ip is None and _dnsname_match(value, hostname): + return + dnsnames.append(value) + elif key == 'IP Address': + if host_ip is not None and _ipaddress_match(value, host_ip): return dnsnames.append(value) if not dnsnames: @@ -342,6 +376,12 @@ def wrap_socket(self, sock, server_side=False, server_hostname=server_hostname, _context=self) + def wrap_bio(self, incoming, outgoing, server_side=False, + server_hostname=None): + sslobj = self._wrap_bio(incoming, outgoing, server_side=server_side, + server_hostname=server_hostname) + return SSLObject(sslobj) + def set_npn_protocols(self, npn_protocols): protos = bytearray() for protocol in npn_protocols: @@ -353,6 +393,17 @@ def set_npn_protocols(self, npn_protocols): self._set_npn_protocols(protos) + def set_alpn_protocols(self, alpn_protocols): + protos = bytearray() + for protocol in alpn_protocols: + b = bytes(protocol, 'ascii') + if len(b) == 0 or len(b) > 255: + raise SSLError('ALPN protocols must be 1 to 255 in length') + protos.append(len(b)) + protos.extend(b) + + self._set_alpn_protocols(protos) + def _load_windows_store_certs(self, storename, purpose): certs = bytearray() for cert, encoding, trust in enum_certificates(storename): @@ -369,8 +420,7 @@ def load_default_certs(self, purpose=Purpose.SERVER_AUTH): if sys.platform == "win32": for storename in self._windows_cert_stores: self._load_windows_store_certs(storename, purpose) - else: - self.set_default_verify_paths() + self.set_default_verify_paths() def create_default_context(purpose=Purpose.SERVER_AUTH, *, cafile=None, @@ -383,17 +433,35 @@ def create_default_context(purpose=Purpose.SERVER_AUTH, *, cafile=None, """ if not isinstance(purpose, _ASN1Object): raise TypeError(purpose) - context = SSLContext(PROTOCOL_TLSv1) + + context = SSLContext(PROTOCOL_SSLv23) + # SSLv2 considered harmful. context.options |= OP_NO_SSLv2 + + # SSLv3 has problematic security and is only required for really old + # clients such as IE6 on Windows XP + context.options |= OP_NO_SSLv3 + # disable compression to prevent CRIME attacks (OpenSSL 1.0+) context.options |= getattr(_ssl, "OP_NO_COMPRESSION", 0) - # disallow ciphers with known vulnerabilities - context.set_ciphers(_RESTRICTED_CIPHERS) - # verify certs and host name in client mode + if purpose == Purpose.SERVER_AUTH: + # verify certs and host name in client mode context.verify_mode = CERT_REQUIRED context.check_hostname = True + elif purpose == Purpose.CLIENT_AUTH: + # Prefer the server's ciphers by default so that we get stronger + # encryption + context.options |= getattr(_ssl, "OP_CIPHER_SERVER_PREFERENCE", 0) + + # Use single use keys in order to improve forward secrecy + context.options |= getattr(_ssl, "OP_SINGLE_DH_USE", 0) + context.options |= getattr(_ssl, "OP_SINGLE_ECDH_USE", 0) + + # disallow ciphers with known vulnerabilities + context.set_ciphers(_RESTRICTED_SERVER_CIPHERS) + if cafile or capath or cadata: context.load_verify_locations(cafile, capath, cadata) elif context.verify_mode != CERT_NONE: @@ -403,9 +471,8 @@ def create_default_context(purpose=Purpose.SERVER_AUTH, *, cafile=None, context.load_default_certs(purpose) return context - -def _create_stdlib_context(protocol=PROTOCOL_SSLv23, *, cert_reqs=None, - purpose=Purpose.SERVER_AUTH, +def _create_unverified_context(protocol=PROTOCOL_SSLv23, *, cert_reqs=None, + check_hostname=False, purpose=Purpose.SERVER_AUTH, certfile=None, keyfile=None, cafile=None, capath=None, cadata=None): """Create a SSLContext object for Python stdlib modules @@ -421,9 +488,13 @@ def _create_stdlib_context(protocol=PROTOCOL_SSLv23, *, cert_reqs=None, context = SSLContext(protocol) # SSLv2 considered harmful. context.options |= OP_NO_SSLv2 + # SSLv3 has problematic security and is only required for really old + # clients such as IE6 on Windows XP + context.options |= OP_NO_SSLv3 if cert_reqs is not None: context.verify_mode = cert_reqs + context.check_hostname = check_hostname if keyfile and not certfile: raise ValueError("certfile must be specified") @@ -441,6 +512,149 @@ def _create_stdlib_context(protocol=PROTOCOL_SSLv23, *, cert_reqs=None, return context +# Used by http.client if no context is explicitly passed. +_create_default_https_context = create_default_context + + +# Backwards compatibility alias, even though it's not a public name. +_create_stdlib_context = _create_unverified_context + + +class SSLObject: + """This class implements an interface on top of a low-level SSL object as + implemented by OpenSSL. This object captures the state of an SSL connection + but does not provide any network IO itself. IO needs to be performed + through separate "BIO" objects which are OpenSSL's IO abstraction layer. + + This class does not have a public constructor. Instances are returned by + ``SSLContext.wrap_bio``. This class is typically used by framework authors + that want to implement asynchronous IO for SSL through memory buffers. + + When compared to ``SSLSocket``, this object lacks the following features: + + * Any form of network IO incluging methods such as ``recv`` and ``send``. + * The ``do_handshake_on_connect`` and ``suppress_ragged_eofs`` machinery. + """ + + def __init__(self, sslobj, owner=None): + self._sslobj = sslobj + # Note: _sslobj takes a weak reference to owner + self._sslobj.owner = owner or self + + @property + def context(self): + """The SSLContext that is currently in use.""" + return self._sslobj.context + + @context.setter + def context(self, ctx): + self._sslobj.context = ctx + + @property + def server_side(self): + """Whether this is a server-side socket.""" + return self._sslobj.server_side + + @property + def server_hostname(self): + """The currently set server hostname (for SNI), or ``None`` if no + server hostame is set.""" + return self._sslobj.server_hostname + + def read(self, len=0, buffer=None): + """Read up to 'len' bytes from the SSL object and return them. + + If 'buffer' is provided, read into this buffer and return the number of + bytes read. + """ + if buffer is not None: + v = self._sslobj.read(len, buffer) + else: + v = self._sslobj.read(len or 1024) + return v + + def write(self, data): + """Write 'data' to the SSL object and return the number of bytes + written. + + The 'data' argument must support the buffer interface. + """ + return self._sslobj.write(data) + + def getpeercert(self, binary_form=False): + """Returns a formatted version of the data in the certificate provided + by the other end of the SSL channel. + + Return None if no certificate was provided, {} if a certificate was + provided, but not validated. + """ + return self._sslobj.peer_certificate(binary_form) + + def selected_npn_protocol(self): + """Return the currently selected NPN protocol as a string, or ``None`` + if a next protocol was not negotiated or if NPN is not supported by one + of the peers.""" + if _ssl.HAS_NPN: + return self._sslobj.selected_npn_protocol() + + def selected_alpn_protocol(self): + """Return the currently selected ALPN protocol as a string, or ``None`` + if a next protocol was not negotiated or if ALPN is not supported by one + of the peers.""" + if _ssl.HAS_ALPN: + return self._sslobj.selected_alpn_protocol() + + def cipher(self): + """Return the currently selected cipher as a 3-tuple ``(name, + ssl_version, secret_bits)``.""" + return self._sslobj.cipher() + + def shared_ciphers(self): + """Return a list of ciphers shared by the client during the handshake or + None if this is not a valid server connection. + """ + return self._sslobj.shared_ciphers() + + def compression(self): + """Return the current compression algorithm in use, or ``None`` if + compression was not negotiated or not supported by one of the peers.""" + return self._sslobj.compression() + + def pending(self): + """Return the number of bytes that can be read immediately.""" + return self._sslobj.pending() + + def do_handshake(self): + """Start the SSL/TLS handshake.""" + self._sslobj.do_handshake() + if self.context.check_hostname: + if not self.server_hostname: + raise ValueError("check_hostname needs server_hostname " + "argument") + match_hostname(self.getpeercert(), self.server_hostname) + + def unwrap(self): + """Start the SSL shutdown handshake.""" + return self._sslobj.shutdown() + + def get_channel_binding(self, cb_type="tls-unique"): + """Get channel binding data for current connection. Raise ValueError + if the requested `cb_type` is not supported. Return bytes of the data + or None if the data is not available (e.g. before the handshake).""" + if cb_type not in CHANNEL_BINDING_TYPES: + raise ValueError("Unsupported channel binding type") + if cb_type != "tls-unique": + raise NotImplementedError( + "{0} channel binding type not implemented" + .format(cb_type)) + return self._sslobj.tls_unique_cb() + + def version(self): + """Return a string identifying the protocol version used by the + current SSL channel. """ + return self._sslobj.version() + + class SSLSocket(socket): """This class implements a subtype of socket.socket that wraps the underlying OS socket in an SSL context when necessary, and @@ -481,16 +695,15 @@ def __init__(self, sock=None, keyfile=None, certfile=None, self.ssl_version = ssl_version self.ca_certs = ca_certs self.ciphers = ciphers + # Can't use sock.type as other flags (such as SOCK_NONBLOCK) get + # mixed in. + if sock.getsockopt(SOL_SOCKET, SO_TYPE) != SOCK_STREAM: + raise NotImplementedError("only stream sockets are supported") if server_side and server_hostname: raise ValueError("server_hostname can only be specified " "in client mode") if self._context.check_hostname and not server_hostname: - if HAS_SNI: - raise ValueError("check_hostname requires server_hostname") - else: - raise ValueError("check_hostname requires server_hostname, " - "but it's not supported by your OpenSSL " - "library") + raise ValueError("check_hostname requires server_hostname") self.server_side = server_side self.server_hostname = server_hostname self.do_handshake_on_connect = do_handshake_on_connect @@ -524,8 +737,9 @@ def __init__(self, sock=None, keyfile=None, certfile=None, if connected: # create the SSL object try: - self._sslobj = self._context._wrap_socket(self, server_side, - server_hostname) + sslobj = self._context._wrap_socket(self, server_side, + server_hostname) + self._sslobj = SSLObject(sslobj, owner=self) if do_handshake_on_connect: timeout = self.gettimeout() if timeout == 0.0: @@ -570,11 +784,7 @@ def read(self, len=0, buffer=None): if not self._sslobj: raise ValueError("Read on closed or unwrapped SSL socket.") try: - if buffer is not None: - v = self._sslobj.read(len, buffer) - else: - v = self._sslobj.read(len or 1024) - return v + return self._sslobj.read(len, buffer) except SSLError as x: if x.args[0] == SSL_ERROR_EOF and self.suppress_ragged_eofs: if buffer is not None: @@ -601,7 +811,7 @@ def getpeercert(self, binary_form=False): self._checkClosed() self._check_connected() - return self._sslobj.peer_certificate(binary_form) + return self._sslobj.getpeercert(binary_form) def selected_npn_protocol(self): self._checkClosed() @@ -610,6 +820,13 @@ def selected_npn_protocol(self): else: return self._sslobj.selected_npn_protocol() + def selected_alpn_protocol(self): + self._checkClosed() + if not self._sslobj or not _ssl.HAS_ALPN: + return None + else: + return self._sslobj.selected_alpn_protocol() + def cipher(self): self._checkClosed() if not self._sslobj: @@ -617,6 +834,12 @@ def cipher(self): else: return self._sslobj.cipher() + def shared_ciphers(self): + self._checkClosed() + if not self._sslobj: + return None + return self._sslobj.shared_ciphers() + def compression(self): self._checkClosed() if not self._sslobj: @@ -631,17 +854,7 @@ def send(self, data, flags=0): raise ValueError( "non-zero flags not allowed in calls to send() on %s" % self.__class__) - try: - v = self._sslobj.write(data) - except SSLError as x: - if x.args[0] == SSL_ERROR_WANT_READ: - return 0 - elif x.args[0] == SSL_ERROR_WANT_WRITE: - return 0 - else: - raise - else: - return v + return self._sslobj.write(data) else: return socket.send(self, data, flags) @@ -677,6 +890,16 @@ def sendall(self, data, flags=0): else: return socket.sendall(self, data, flags) + def sendfile(self, file, offset=0, count=None): + """Send a file, possibly by using os.sendfile() if this is a + clear-text socket. Return the total number of bytes sent. + """ + if self._sslobj is None: + # os.sendfile() works with plain sockets only + return super().sendfile(file, offset, count) + else: + return self._sendfile_use_send(file, offset, count) + def recv(self, buflen=1024, flags=0): self._checkClosed() if self._sslobj: @@ -741,7 +964,7 @@ def shutdown(self, how): def unwrap(self): if self._sslobj: - s = self._sslobj.shutdown() + s = self._sslobj.unwrap() self._sslobj = None return s else: @@ -762,17 +985,6 @@ def do_handshake(self, block=False): finally: self.settimeout(timeout) - if self.context.check_hostname: - try: - if not self.server_hostname: - raise ValueError("check_hostname needs server_hostname " - "argument") - match_hostname(self.getpeercert(), self.server_hostname) - except Exception: - self.shutdown(_SHUT_RDWR) - self.close() - raise - def _real_connect(self, addr, connect_ex): if self.server_side: raise ValueError("can't connect in server-side mode") @@ -780,7 +992,8 @@ def _real_connect(self, addr, connect_ex): # connected at the time of the call. We connect it, then wrap it. if self._connected: raise ValueError("attempt to connect already-connected SSLSocket!") - self._sslobj = self.context._wrap_socket(self, False, self.server_hostname) + sslobj = self.context._wrap_socket(self, False, self.server_hostname) + self._sslobj = SSLObject(sslobj, owner=self) try: if connect_ex: rc = socket.connect_ex(self, addr) @@ -823,15 +1036,18 @@ def get_channel_binding(self, cb_type="tls-unique"): if the requested `cb_type` is not supported. Return bytes of the data or None if the data is not available (e.g. before the handshake). """ - if cb_type not in CHANNEL_BINDING_TYPES: - raise ValueError("Unsupported channel binding type") - if cb_type != "tls-unique": - raise NotImplementedError( - "{0} channel binding type not implemented" - .format(cb_type)) if self._sslobj is None: return None - return self._sslobj.tls_unique_cb() + return self._sslobj.get_channel_binding(cb_type) + + def version(self): + """ + Return a string identifying the protocol version used by the + current SSL channel, or None if there is no established channel. + """ + if self._sslobj is None: + return None + return self._sslobj.version() def wrap_socket(sock, keyfile=None, certfile=None, @@ -851,12 +1067,34 @@ def wrap_socket(sock, keyfile=None, certfile=None, # some utility functions def cert_time_to_seconds(cert_time): - """Takes a date-time string in standard ASN1_print form - ("MON DAY 24HOUR:MINUTE:SEC YEAR TIMEZONE") and return - a Python time value in seconds past the epoch.""" + """Return the time in seconds since the Epoch, given the timestring + representing the "notBefore" or "notAfter" date from a certificate + in ``"%b %d %H:%M:%S %Y %Z"`` strptime format (C locale). + + "notBefore" or "notAfter" dates must use UTC (RFC 5280). - import time - return time.mktime(time.strptime(cert_time, "%b %d %H:%M:%S %Y GMT")) + Month is one of: Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec + UTC should be specified as GMT (see ASN1_TIME_print()) + """ + from time import strptime + from calendar import timegm + + months = ( + "Jan","Feb","Mar","Apr","May","Jun", + "Jul","Aug","Sep","Oct","Nov","Dec" + ) + time_format = ' %d %H:%M:%S %Y GMT' # NOTE: no month, fixed GMT + try: + month_number = months.index(cert_time[:3].title()) + 1 + except ValueError: + raise ValueError('time data %r does not match ' + 'format "%%b%s"' % (cert_time, time_format)) + else: + # found valid month + tt = strptime(cert_time[3:], time_format) + # return an integer, the previous mktime()-based implementation + # returned a float (fractional seconds are always zero here). + return timegm((tt[0], month_number) + tt[2:6]) PEM_HEADER = "-----BEGIN CERTIFICATE-----" PEM_FOOTER = "-----END CERTIFICATE-----" @@ -883,7 +1121,7 @@ def PEM_cert_to_DER_cert(pem_cert_string): d = pem_cert_string.strip()[len(PEM_HEADER):-len(PEM_FOOTER)] return base64.decodebytes(d.encode('ASCII', 'strict')) -def get_server_certificate(addr, ssl_version=PROTOCOL_SSLv3, ca_certs=None): +def get_server_certificate(addr, ssl_version=PROTOCOL_SSLv23, ca_certs=None): """Retrieve the certificate from the server at the specified address, and return it as a PEM-encoded string. If 'ca_certs' is specified, validate the server cert against it. diff --git a/Lib/stat.py b/Lib/stat.py index 3eecc3e0d348..46837c06dacf 100644 --- a/Lib/stat.py +++ b/Lib/stat.py @@ -148,6 +148,29 @@ def filemode(mode): perm.append("-") return "".join(perm) + +# Windows FILE_ATTRIBUTE constants for interpreting os.stat()'s +# "st_file_attributes" member + +FILE_ATTRIBUTE_ARCHIVE = 32 +FILE_ATTRIBUTE_COMPRESSED = 2048 +FILE_ATTRIBUTE_DEVICE = 64 +FILE_ATTRIBUTE_DIRECTORY = 16 +FILE_ATTRIBUTE_ENCRYPTED = 16384 +FILE_ATTRIBUTE_HIDDEN = 2 +FILE_ATTRIBUTE_INTEGRITY_STREAM = 32768 +FILE_ATTRIBUTE_NORMAL = 128 +FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 8192 +FILE_ATTRIBUTE_NO_SCRUB_DATA = 131072 +FILE_ATTRIBUTE_OFFLINE = 4096 +FILE_ATTRIBUTE_READONLY = 1 +FILE_ATTRIBUTE_REPARSE_POINT = 1024 +FILE_ATTRIBUTE_SPARSE_FILE = 512 +FILE_ATTRIBUTE_SYSTEM = 4 +FILE_ATTRIBUTE_TEMPORARY = 256 +FILE_ATTRIBUTE_VIRTUAL = 65536 + + # If available, use C implementation try: from _stat import * diff --git a/Lib/statistics.py b/Lib/statistics.py index a67a6d11cd6c..3972ed2e5f7e 100644 --- a/Lib/statistics.py +++ b/Lib/statistics.py @@ -144,19 +144,31 @@ def _sum(data, start=0): >>> _sum(data) Decimal('0.6963') + Mixed types are currently treated as an error, except that int is + allowed. """ + # We fail as soon as we reach a value that is not an int or the type of + # the first value which is not an int. E.g. _sum([int, int, float, int]) + # is okay, but sum([int, int, float, Fraction]) is not. + allowed_types = {int, type(start)} n, d = _exact_ratio(start) - T = type(start) partials = {d: n} # map {denominator: sum of numerators} # Micro-optimizations. - coerce_types = _coerce_types exact_ratio = _exact_ratio partials_get = partials.get - # Add numerators for each denominator, and track the "current" type. + # Add numerators for each denominator. for x in data: - T = _coerce_types(T, type(x)) + _check_type(type(x), allowed_types) n, d = exact_ratio(x) partials[d] = partials_get(d, 0) + n + # Find the expected result type. If allowed_types has only one item, it + # will be int; if it has two, use the one which isn't int. + assert len(allowed_types) in (1, 2) + if len(allowed_types) == 1: + assert allowed_types.pop() is int + T = int + else: + T = (allowed_types - {int}).pop() if None in partials: assert issubclass(T, (float, Decimal)) assert not math.isfinite(partials[None]) @@ -172,6 +184,15 @@ def _sum(data, start=0): return T(total) +def _check_type(T, allowed): + if T not in allowed: + if len(allowed) == 1: + allowed.add(T) + else: + types = ', '.join([t.__name__ for t in allowed] + [T.__name__]) + raise TypeError("unsupported mixed types: %s" % types) + + def _exact_ratio(x): """Convert Real number x exactly to (numerator, denominator) pair. @@ -222,55 +243,19 @@ def _decimal_to_ratio(d): num = 0 for digit in digits: num = num*10 + digit + if exp < 0: + den = 10**-exp + else: + num *= 10**exp + den = 1 if sign: num = -num - den = 10**-exp return (num, den) -def _coerce_types(T1, T2): - """Coerce types T1 and T2 to a common type. - - >>> _coerce_types(int, float) - <class 'float'> - - Coercion is performed according to this table, where "N/A" means - that a TypeError exception is raised. - - +----------+-----------+-----------+-----------+----------+ - | | int | Fraction | Decimal | float | - +----------+-----------+-----------+-----------+----------+ - | int | int | Fraction | Decimal | float | - | Fraction | Fraction | Fraction | N/A | float | - | Decimal | Decimal | N/A | Decimal | float | - | float | float | float | float | float | - +----------+-----------+-----------+-----------+----------+ - - Subclasses trump their parent class; two subclasses of the same - base class will be coerced to the second of the two. - - """ - # Get the common/fast cases out of the way first. - if T1 is T2: return T1 - if T1 is int: return T2 - if T2 is int: return T1 - # Subclasses trump their parent class. - if issubclass(T2, T1): return T2 - if issubclass(T1, T2): return T1 - # Floats trump everything else. - if issubclass(T2, float): return T2 - if issubclass(T1, float): return T1 - # Subclasses of the same base class give priority to the second. - if T1.__base__ is T2.__base__: return T2 - # Otherwise, just give up. - raise TypeError('cannot coerce types %r and %r' % (T1, T2)) - - def _counts(data): # Generate a table of sorted (value, frequency) pairs. - if data is None: - raise TypeError('None is not iterable') - table = collections.Counter(data).most_common() + table = collections.Counter(iter(data)).most_common() if not table: return table # Extract the values with the highest frequency. diff --git a/Lib/string.py b/Lib/string.py index b57c79b75e5b..72a09f72898d 100644 --- a/Lib/string.py +++ b/Lib/string.py @@ -169,7 +169,8 @@ def vformat(self, format_string, args, kwargs): self.check_unused_args(used_args, args, kwargs) return result - def _vformat(self, format_string, args, kwargs, used_args, recursion_depth): + def _vformat(self, format_string, args, kwargs, used_args, recursion_depth, + auto_arg_index=0): if recursion_depth < 0: raise ValueError('Max string recursion exceeded') result = [] @@ -185,6 +186,23 @@ def _vformat(self, format_string, args, kwargs, used_args, recursion_depth): # this is some markup, find the object and do # the formatting + # handle arg indexing when empty field_names are given. + if field_name == '': + if auto_arg_index is False: + raise ValueError('cannot switch from manual field ' + 'specification to automatic field ' + 'numbering') + field_name = str(auto_arg_index) + auto_arg_index += 1 + elif field_name.isdigit(): + if auto_arg_index: + raise ValueError('cannot switch from manual field ' + 'specification to automatic field ' + 'numbering') + # disable auto arg incrementing, if it gets + # used later on, then an exception will be raised + auto_arg_index = False + # given the field_name, find the object it references # and the argument it came from obj, arg_used = self.get_field(field_name, args, kwargs) @@ -195,7 +213,8 @@ def _vformat(self, format_string, args, kwargs, used_args, recursion_depth): # expand the format spec, if needed format_spec = self._vformat(format_spec, args, kwargs, - used_args, recursion_depth-1) + used_args, recursion_depth-1, + auto_arg_index=auto_arg_index) # format the object and append to the result result.append(self.format_field(obj, format_spec)) diff --git a/Lib/subprocess.py b/Lib/subprocess.py index 0942d94ef71f..25ffefff6c43 100644 --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -11,7 +11,7 @@ This module allows you to spawn processes, connect to their input/output/error pipes, and obtain their return codes. This module -intends to replace several other, older modules and functions, like: +intends to replace several older modules and functions: os.system os.spawn* @@ -104,17 +104,21 @@ class Popen(args, bufsize=-1, executable=None, If env is not None, it defines the environment variables for the new process. -If universal_newlines is false, the file objects stdin, stdout and stderr +If universal_newlines is False, the file objects stdin, stdout and stderr are opened as binary files, and no line ending conversion is done. -If universal_newlines is true, the file objects stdout and stderr are -opened as a text files, but lines may be terminated by any of '\n', +If universal_newlines is True, the file objects stdout and stderr are +opened as a text file, but lines may be terminated by any of '\n', the Unix end-of-line convention, '\r', the old Macintosh convention or '\r\n', the Windows convention. All of these external representations are seen as '\n' by the Python program. Also, the newlines attribute of the file objects stdout, stdin and stderr are not updated by the communicate() method. +In either case, the process being communicated with should start up +expecting to receive bytes on its standard input and decode them with +the same encoding they are sent in. + The startupinfo and creationflags, if given, will be passed to the underlying CreateProcess() function. They can specify things such as appearance of the main window and priority for the new process. @@ -184,6 +188,9 @@ class Popen(args, bufsize=-1, executable=None, pass a string to the subprocess's stdin. If you use this argument you may not also use the Popen constructor's "stdin" argument. + If universal_newlines is set to True, the "input" argument must + be a string rather than bytes, and the return value will be a string. + Exceptions ---------- Exceptions raised in the child process, before the new program has @@ -225,9 +232,13 @@ class Popen(args, bufsize=-1, executable=None, communicate(input=None) Interact with process: Send data to stdin. Read data from stdout and stderr, until end-of-file is reached. Wait for process to - terminate. The optional input argument should be a string to be + terminate. The optional input argument should be data to be sent to the child process, or None, if no data should be sent to - the child. + the child. If the Popen instance was constructed with universal_newlines + set to True, the input argument should be a string and will be encoded + using the preferred system encoding (see locale.getpreferredencoding); + if universal_newlines is False, the input argument should be a + byte string. communicate() returns a tuple (stdout, stderr). @@ -350,16 +361,11 @@ class Popen(args, bufsize=-1, executable=None, import io import os import time -import traceback -import gc import signal import builtins import warnings import errno -try: - from time import monotonic as _time -except ImportError: - from time import time as _time +from time import monotonic as _time # Exception classes used by this module. class SubprocessError(Exception): pass @@ -407,6 +413,10 @@ class STARTUPINFO: import _posixsubprocess import select import selectors + try: + import threading + except ImportError: + import dummy_threading as threading # When select or poll has indicated that the file is writable, # we can write up to _PIPE_BUF bytes without risk of blocking. @@ -451,15 +461,11 @@ def Detach(self): raise ValueError("already closed") def __repr__(self): - return "Handle(%d)" % int(self) + return "%s(%d)" % (self.__class__.__name__, int(self)) __del__ = Close __str__ = __repr__ -try: - MAXFD = os.sysconf("SC_OPEN_MAX") -except: - MAXFD = 256 # This lists holds Popen instances for which the underlying process had not # exited at the time its __del__ method got called: those processes are wait()ed @@ -483,14 +489,6 @@ def _cleanup(): DEVNULL = -3 -def _eintr_retry_call(func, *args): - while True: - try: - return func(*args) - except InterruptedError: - continue - - # XXX This function is only used by multiprocessing and the test suite, # but it's here so that it can be imported when Python is compiled without # threads. @@ -589,8 +587,8 @@ def check_output(*popenargs, timeout=None, **kwargs): ... input=b"when in the course of fooman events\n") b'when in the course of barman events\n' - If universal_newlines=True is passed, the return value will be a - string rather than bytes. + If universal_newlines=True is passed, the "input" argument must be a + string and the return value will be a string rather than bytes. """ if 'stdout' in kwargs: raise ValueError('stdout argument not allowed, it will be overridden.') @@ -738,6 +736,9 @@ def getoutput(cmd): class Popen(object): + + _child_created = False # Set here since __del__ checks it + def __init__(self, args, bufsize=-1, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=_PLATFORM_DEFAULT_CLOSE_FDS, @@ -747,8 +748,13 @@ def __init__(self, args, bufsize=-1, executable=None, pass_fds=()): """Create new Popen instance.""" _cleanup() + # Held while anything is calling waitpid before returncode has been + # updated to prevent clobbering returncode if wait() or poll() are + # called from multiple threads at once. After acquiring the lock, + # code must re-check self.returncode to see if another thread just + # finished a waitpid() call. + self._waitpid_lock = threading.Lock() - self._child_created = False self._input = None self._communication_started = False if bufsize is None: @@ -827,7 +833,8 @@ def __init__(self, args, bufsize=-1, executable=None, if p2cwrite != -1: self.stdin = io.open(p2cwrite, 'wb', bufsize) if universal_newlines: - self.stdin = io.TextIOWrapper(self.stdin, write_through=True) + self.stdin = io.TextIOWrapper(self.stdin, write_through=True, + line_buffering=(bufsize == 1)) if c2pread != -1: self.stdout = io.open(c2pread, 'rb', bufsize) if universal_newlines: @@ -890,11 +897,8 @@ def __exit__(self, type, value, traceback): # Wait for the process to terminate, to avoid zombies. self.wait() - def __del__(self, _maxsize=sys.maxsize, _active=_active): - # If __init__ hasn't had a chance to execute (e.g. if it - # was passed an undeclared keyword argument), we don't - # have a _child_created attribute at all. - if not getattr(self, '_child_created', False): + def __del__(self, _maxsize=sys.maxsize): + if not self._child_created: # We didn't get to successfully create a child process. return # In case the child hasn't been waited on, check if it's done. @@ -908,14 +912,35 @@ def _get_devnull(self): self._devnull = os.open(os.devnull, os.O_RDWR) return self._devnull + def _stdin_write(self, input): + if input: + try: + self.stdin.write(input) + except BrokenPipeError: + # communicate() must ignore broken pipe error + pass + except OSError as e: + if e.errno == errno.EINVAL and self.poll() is not None: + # Issue #19612: On Windows, stdin.write() fails with EINVAL + # if the process already exited before the write + pass + else: + raise + self.stdin.close() + def communicate(self, input=None, timeout=None): """Interact with process: Send data to stdin. Read data from stdout and stderr, until end-of-file is reached. Wait for - process to terminate. The optional input argument should be - bytes to be sent to the child process, or None, if no data - should be sent to the child. + process to terminate. - communicate() returns a tuple (stdout, stderr).""" + The optional "input" argument should be data to be sent to the + child process (if self.universal_newlines is True, this should + be a string; if it is False, "input" should be bytes), or + None, if no data should be sent to the child. + + communicate() returns a tuple (stdout, stderr). These will be + bytes or, if self.universal_newlines was True, a string. + """ if self._communication_started and input: raise ValueError("Cannot send input after starting communication") @@ -928,18 +953,12 @@ def communicate(self, input=None, timeout=None): stdout = None stderr = None if self.stdin: - if input: - try: - self.stdin.write(input) - except OSError as e: - if e.errno != errno.EPIPE and e.errno != errno.EINVAL: - raise - self.stdin.close() + self._stdin_write(input) elif self.stdout: - stdout = _eintr_retry_call(self.stdout.read) + stdout = self.stdout.read() self.stdout.close() elif self.stderr: - stderr = _eintr_retry_call(self.stderr.read) + stderr = self.stderr.read() self.stderr.close() self.wait() else: @@ -1183,13 +1202,7 @@ def _communicate(self, input, endtime, orig_timeout): self.stderr_thread.start() if self.stdin: - if input is not None: - try: - self.stdin.write(input) - except OSError as e: - if e.errno != errno.EPIPE: - raise - self.stdin.close() + self._stdin_write(input) # Wait for the reader threads, or time out. If we time out, the # threads remain reading and the fds left open in case the user @@ -1304,16 +1317,6 @@ def _get_handles(self, stdin, stdout, stderr): errread, errwrite) - def _close_fds(self, fds_to_keep): - start_fd = 3 - for fd in sorted(fds_to_keep): - if fd >= start_fd: - os.closerange(start_fd, fd) - start_fd = fd + 1 - if start_fd <= MAXFD: - os.closerange(start_fd, MAXFD) - - def _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, startupinfo, creationflags, shell, @@ -1399,7 +1402,7 @@ def _execute_child(self, args, executable, preexec_fn, close_fds, # exception (limited in size) errpipe_data = bytearray() while True: - part = _eintr_retry_call(os.read, errpipe_read, 50000) + part = os.read(errpipe_read, 50000) errpipe_data += part if not part or len(errpipe_data) > 50000: break @@ -1409,10 +1412,9 @@ def _execute_child(self, args, executable, preexec_fn, close_fds, if errpipe_data: try: - _eintr_retry_call(os.waitpid, self.pid, 0) - except OSError as e: - if e.errno != errno.ECHILD: - raise + os.waitpid(self.pid, 0) + except ChildProcessError: + pass try: exception_name, hex_errno, err_msg = ( errpipe_data.split(b':', 2)) @@ -1445,8 +1447,9 @@ def _execute_child(self, args, executable, preexec_fn, close_fds, def _handle_exitstatus(self, sts, _WIFSIGNALED=os.WIFSIGNALED, _WTERMSIG=os.WTERMSIG, _WIFEXITED=os.WIFEXITED, _WEXITSTATUS=os.WEXITSTATUS): + """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.""" + # refer to anything outside of its local scope. if _WIFSIGNALED(sts): self.returncode = -_WTERMSIG(sts) elif _WIFEXITED(sts): @@ -1466,7 +1469,13 @@ def _internal_poll(self, _deadstate=None, _waitpid=os.waitpid, """ if self.returncode is None: + if not self._waitpid_lock.acquire(False): + # Something else is busy calling waitpid. Don't allow two + # at once. We know nothing yet. + return None try: + if self.returncode is not None: + return self.returncode # Another thread waited. pid, sts = _waitpid(self.pid, _WNOHANG) if pid == self.pid: self._handle_exitstatus(sts) @@ -1480,15 +1489,16 @@ def _internal_poll(self, _deadstate=None, _waitpid=os.waitpid, # can't get the status. # http://bugs.python.org/issue15756 self.returncode = 0 + finally: + self._waitpid_lock.release() return self.returncode def _try_wait(self, wait_flags): + """All callers to this function MUST hold self._waitpid_lock.""" try: - (pid, sts) = _eintr_retry_call(os.waitpid, self.pid, wait_flags) - except OSError as e: - if e.errno != errno.ECHILD: - raise + (pid, sts) = os.waitpid(self.pid, wait_flags) + except ChildProcessError: # This happens if SIGCLD is set to be ignored or waiting # for child processes has otherwise been disabled for our # process. This child is dead, we can't get the status. @@ -1516,11 +1526,17 @@ def wait(self, timeout=None, endtime=None): # cribbed from Lib/threading.py in Thread.wait() at r71065. delay = 0.0005 # 500 us -> initial delay of 1 ms while True: - (pid, sts) = self._try_wait(os.WNOHANG) - assert pid == self.pid or pid == 0 - if pid == self.pid: - self._handle_exitstatus(sts) - break + if self._waitpid_lock.acquire(False): + try: + if self.returncode is not None: + break # Another thread waited. + (pid, sts) = self._try_wait(os.WNOHANG) + assert pid == self.pid or pid == 0 + if pid == self.pid: + self._handle_exitstatus(sts) + break + finally: + self._waitpid_lock.release() remaining = self._remaining_time(endtime) if remaining <= 0: raise TimeoutExpired(self.args, timeout) @@ -1528,11 +1544,15 @@ def wait(self, timeout=None, endtime=None): time.sleep(delay) else: while self.returncode is None: - (pid, sts) = self._try_wait(0) - # Check the pid and loop as waitpid has been known to return - # 0 even without WNOHANG in odd situations. issue14396. - if pid == self.pid: - self._handle_exitstatus(sts) + with self._waitpid_lock: + if self.returncode is not None: + break # Another thread waited. + (pid, sts) = self._try_wait(0) + # Check the pid and loop as waitpid has been known to + # return 0 even without WNOHANG in odd situations. + # http://bugs.python.org/issue14396. + if pid == self.pid: + self._handle_exitstatus(sts) return self.returncode @@ -1562,6 +1582,9 @@ def _communicate(self, input, endtime, orig_timeout): self._save_input(input) + if self._input: + input_view = memoryview(self._input) + with _PopenSelector() as selector: if self.stdin and input: selector.register(self.stdin, selectors.EVENT_WRITE) @@ -1583,22 +1606,19 @@ def _communicate(self, input, endtime, orig_timeout): for key, events in ready: if key.fileobj is self.stdin: - chunk = self._input[self._input_offset : - self._input_offset + _PIPE_BUF] + chunk = input_view[self._input_offset : + self._input_offset + _PIPE_BUF] try: self._input_offset += os.write(key.fd, chunk) - except OSError as e: - if e.errno == errno.EPIPE: - selector.unregister(key.fileobj) - key.fileobj.close() - else: - raise + except BrokenPipeError: + selector.unregister(key.fileobj) + key.fileobj.close() else: if self._input_offset >= len(self._input): selector.unregister(key.fileobj) key.fileobj.close() elif key.fileobj in (self.stdout, self.stderr): - data = os.read(key.fd, 4096) + data = os.read(key.fd, 32768) if not data: selector.unregister(key.fileobj) key.fileobj.close() diff --git a/Lib/sysconfig.py b/Lib/sysconfig.py index dbf77672054b..137932ef7846 100644 --- a/Lib/sysconfig.py +++ b/Lib/sysconfig.py @@ -57,7 +57,7 @@ 'purelib': '{userbase}/Python{py_version_nodot}/site-packages', 'platlib': '{userbase}/Python{py_version_nodot}/site-packages', 'include': '{userbase}/Python{py_version_nodot}/Include', - 'scripts': '{userbase}/Scripts', + 'scripts': '{userbase}/Python{py_version_nodot}/Scripts', 'data': '{userbase}', }, 'posix_user': { @@ -109,13 +109,8 @@ def _safe_realpath(path): # unable to retrieve the real program name _PROJECT_BASE = _safe_realpath(os.getcwd()) -if os.name == "nt" and "pcbuild" in _PROJECT_BASE[-8:].lower(): - _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir)) -# PC/VS7.1 -if os.name == "nt" and "\\pc\\v" in _PROJECT_BASE[-10:].lower(): - _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir, pardir)) -# PC/AMD64 -if os.name == "nt" and "\\pcbuild\\amd64" in _PROJECT_BASE[-14:].lower(): +if (os.name == 'nt' and + _PROJECT_BASE.lower().endswith(('\\pcbuild\\win32', '\\pcbuild\\amd64'))): _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir, pardir)) # set for cross builds @@ -129,11 +124,9 @@ def _is_python_source_dir(d): return False _sys_home = getattr(sys, '_home', None) -if _sys_home and os.name == 'nt' and \ - _sys_home.lower().endswith(('pcbuild', 'pcbuild\\amd64')): - _sys_home = os.path.dirname(_sys_home) - if _sys_home.endswith('pcbuild'): # must be amd64 - _sys_home = os.path.dirname(_sys_home) +if (_sys_home and os.name == 'nt' and + _sys_home.lower().endswith(('\\pcbuild\\win32', '\\pcbuild\\amd64'))): + _sys_home = os.path.dirname(os.path.dirname(_sys_home)) def is_python_build(check_home=False): if check_home and _sys_home: return _is_python_source_dir(_sys_home) diff --git a/Lib/tarfile.py b/Lib/tarfile.py old mode 100644 new mode 100755 index f4df6c7b0ac4..ea7a89a8d3c4 --- a/Lib/tarfile.py +++ b/Lib/tarfile.py @@ -65,8 +65,6 @@ # from tarfile import * __all__ = ["TarFile", "TarInfo", "is_tarfile", "TarError"] -from builtins import open as _open # Since 'open' is TarFile.open - #--------------------------------------------------------- # tar constants #--------------------------------------------------------- @@ -196,7 +194,7 @@ def itn(n, digits=8, format=DEFAULT_FORMAT): # A 0o200 byte indicates a positive number, a 0o377 byte a negative # number. if 0 <= n < 8 ** (digits - 1): - s = bytes("%0*o" % (digits - 1, n), "ascii") + NUL + s = bytes("%0*o" % (digits - 1, int(n)), "ascii") + NUL elif format == GNU_FORMAT and -256 ** (digits - 1) <= n < 256 ** (digits - 1): if n >= 0: s = bytearray([0o200]) @@ -257,6 +255,12 @@ def filemode(mode): DeprecationWarning, 2) return stat.filemode(mode) +def _safe_print(s): + encoding = getattr(sys.stdout, 'encoding', None) + if encoding is not None: + s = s.encode(encoding, 'backslashreplace').decode(encoding) + print(s, end=' ') + class TarError(Exception): """Base exception.""" @@ -1405,10 +1409,11 @@ def __init__(self, name=None, mode="r", fileobj=None, format=None, can be determined, `mode' is overridden by `fileobj's mode. `fileobj' is not closed, when TarFile is closed. """ - if len(mode) > 1 or mode not in "raw": - raise ValueError("mode must be 'r', 'a' or 'w'") + modes = {"r": "rb", "a": "r+b", "w": "wb", "x": "xb"} + if mode not in modes: + raise ValueError("mode must be 'r', 'a', 'w' or 'x'") self.mode = mode - self._mode = {"r": "rb", "a": "r+b", "w": "wb"}[mode] + self._mode = modes[mode] if not fileobj: if self.mode == "a" and not os.path.exists(name): @@ -1418,7 +1423,8 @@ def __init__(self, name=None, mode="r", fileobj=None, format=None, fileobj = bltn_open(name, self._mode) self._extfileobj = False else: - if name is None and hasattr(fileobj, "name"): + if (name is None and hasattr(fileobj, "name") and + isinstance(fileobj.name, (str, bytes))): name = fileobj.name if hasattr(fileobj, "mode"): self._mode = fileobj.mode @@ -1518,6 +1524,15 @@ def open(cls, name=None, mode="r", fileobj=None, bufsize=RECORDSIZE, **kwargs): 'w:bz2' open for writing with bzip2 compression 'w:xz' open for writing with lzma compression + 'x' or 'x:' create a tarfile exclusively without compression, raise + an exception if the file is already created + 'x:gz' create an gzip compressed tarfile, raise an exception + if the file is already created + 'x:bz2' create an bzip2 compressed tarfile, raise an exception + if the file is already created + 'x:xz' create an lzma compressed tarfile, raise an exception + if the file is already created + 'r|*' open a stream of tar blocks with transparent compression 'r|' open an uncompressed stream of tar blocks for reading 'r|gz' open a gzip compressed stream of tar blocks @@ -1564,7 +1579,7 @@ def open(cls, name=None, mode="r", fileobj=None, bufsize=RECORDSIZE, **kwargs): filemode = filemode or "r" comptype = comptype or "tar" - if filemode not in "rw": + if filemode not in ("r", "w"): raise ValueError("mode must be 'r' or 'w'") stream = _Stream(name, filemode, comptype, fileobj, bufsize) @@ -1576,7 +1591,7 @@ def open(cls, name=None, mode="r", fileobj=None, bufsize=RECORDSIZE, **kwargs): t._extfileobj = False return t - elif mode in "aw": + elif mode in ("a", "w", "x"): return cls.taropen(name, mode, fileobj, **kwargs) raise ValueError("undiscernible mode") @@ -1585,8 +1600,8 @@ def open(cls, name=None, mode="r", fileobj=None, bufsize=RECORDSIZE, **kwargs): def taropen(cls, name, mode="r", fileobj=None, **kwargs): """Open uncompressed tar archive name for reading or writing. """ - if len(mode) > 1 or mode not in "raw": - raise ValueError("mode must be 'r', 'a' or 'w'") + if mode not in ("r", "a", "w", "x"): + raise ValueError("mode must be 'r', 'a', 'w' or 'x'") return cls(name, mode, fileobj, **kwargs) @classmethod @@ -1594,8 +1609,8 @@ def gzopen(cls, name, mode="r", fileobj=None, compresslevel=9, **kwargs): """Open gzip compressed tar archive name for reading or writing. Appending is not allowed. """ - if len(mode) > 1 or mode not in "rw": - raise ValueError("mode must be 'r' or 'w'") + if mode not in ("r", "w", "x"): + raise ValueError("mode must be 'r', 'w' or 'x'") try: import gzip @@ -1603,21 +1618,24 @@ def gzopen(cls, name, mode="r", fileobj=None, compresslevel=9, **kwargs): except (ImportError, AttributeError): raise CompressionError("gzip module is not available") - extfileobj = fileobj is not None try: fileobj = gzip.GzipFile(name, mode + "b", compresslevel, fileobj) + except OSError: + if fileobj is not None and mode == 'r': + raise ReadError("not a gzip file") + raise + + try: t = cls.taropen(name, mode, fileobj, **kwargs) except OSError: - if not extfileobj and fileobj is not None: - fileobj.close() - if fileobj is None: - raise - raise ReadError("not a gzip file") + fileobj.close() + if mode == 'r': + raise ReadError("not a gzip file") + raise except: - if not extfileobj and fileobj is not None: - fileobj.close() + fileobj.close() raise - t._extfileobj = extfileobj + t._extfileobj = False return t @classmethod @@ -1625,8 +1643,8 @@ def bz2open(cls, name, mode="r", fileobj=None, compresslevel=9, **kwargs): """Open bzip2 compressed tar archive name for reading or writing. Appending is not allowed. """ - if len(mode) > 1 or mode not in "rw": - raise ValueError("mode must be 'r' or 'w'.") + if mode not in ("r", "w", "x"): + raise ValueError("mode must be 'r', 'w' or 'x'") try: import bz2 @@ -1640,7 +1658,12 @@ def bz2open(cls, name, mode="r", fileobj=None, compresslevel=9, **kwargs): t = cls.taropen(name, mode, fileobj, **kwargs) except (OSError, EOFError): fileobj.close() - raise ReadError("not a bzip2 file") + if mode == 'r': + raise ReadError("not a bzip2 file") + raise + except: + fileobj.close() + raise t._extfileobj = False return t @@ -1649,8 +1672,8 @@ def xzopen(cls, name, mode="r", fileobj=None, preset=None, **kwargs): """Open lzma compressed tar archive name for reading or writing. Appending is not allowed. """ - if mode not in ("r", "w"): - raise ValueError("mode must be 'r' or 'w'") + if mode not in ("r", "w", "x"): + raise ValueError("mode must be 'r', 'w' or 'x'") try: import lzma @@ -1663,7 +1686,12 @@ def xzopen(cls, name, mode="r", fileobj=None, preset=None, **kwargs): t = cls.taropen(name, mode, fileobj, **kwargs) except (lzma.LZMAError, EOFError): fileobj.close() - raise ReadError("not an lzma file") + if mode == 'r': + raise ReadError("not an lzma file") + raise + except: + fileobj.close() + raise t._extfileobj = False return t @@ -1732,7 +1760,7 @@ def gettarinfo(self, name=None, arcname=None, fileobj=None): addfile(). If given, `arcname' specifies an alternative name for the file in the archive. """ - self._check("aw") + self._check("awx") # When fileobj is given, replace name by # fileobj's real name. @@ -1823,33 +1851,36 @@ def gettarinfo(self, name=None, arcname=None, fileobj=None): tarinfo.devminor = os.minor(statres.st_rdev) return tarinfo - def list(self, verbose=True): + def list(self, verbose=True, *, members=None): """Print a table of contents to sys.stdout. If `verbose' is False, only the names of the members are printed. If it is True, an `ls -l'-like - output is produced. + output is produced. `members' is optional and must be a subset of the + list returned by getmembers(). """ self._check() - for tarinfo in self: + if members is None: + members = self + for tarinfo in members: if verbose: - print(stat.filemode(tarinfo.mode), end=' ') - print("%s/%s" % (tarinfo.uname or tarinfo.uid, - tarinfo.gname or tarinfo.gid), end=' ') + _safe_print(stat.filemode(tarinfo.mode)) + _safe_print("%s/%s" % (tarinfo.uname or tarinfo.uid, + tarinfo.gname or tarinfo.gid)) if tarinfo.ischr() or tarinfo.isblk(): - print("%10s" % ("%d,%d" \ - % (tarinfo.devmajor, tarinfo.devminor)), end=' ') + _safe_print("%10s" % + ("%d,%d" % (tarinfo.devmajor, tarinfo.devminor))) else: - print("%10d" % tarinfo.size, end=' ') - print("%d-%02d-%02d %02d:%02d:%02d" \ - % time.localtime(tarinfo.mtime)[:6], end=' ') + _safe_print("%10d" % tarinfo.size) + _safe_print("%d-%02d-%02d %02d:%02d:%02d" \ + % time.localtime(tarinfo.mtime)[:6]) - print(tarinfo.name + ("/" if tarinfo.isdir() else ""), end=' ') + _safe_print(tarinfo.name + ("/" if tarinfo.isdir() else "")) if verbose: if tarinfo.issym(): - print("->", tarinfo.linkname, end=' ') + _safe_print("-> " + tarinfo.linkname) if tarinfo.islnk(): - print("link to", tarinfo.linkname, end=' ') + _safe_print("link to " + tarinfo.linkname) print() def add(self, name, arcname=None, recursive=True, exclude=None, *, filter=None): @@ -1863,7 +1894,7 @@ def add(self, name, arcname=None, recursive=True, exclude=None, *, filter=None): TarInfo object, if it returns None the TarInfo object will be excluded from the archive. """ - self._check("aw") + self._check("awx") if arcname is None: arcname = name @@ -1920,7 +1951,7 @@ def addfile(self, tarinfo, fileobj=None): On Windows platforms, `fileobj' should always be opened with mode 'rb' to avoid irritation about the file size. """ - self._check("aw") + self._check("awx") tarinfo = copy.copy(tarinfo) @@ -2472,16 +2503,16 @@ def main(): _, ext = os.path.splitext(tar_name) compressions = { # gz - 'gz': 'gz', - 'tgz': 'gz', + '.gz': 'gz', + '.tgz': 'gz', # xz - 'xz': 'xz', - 'txz': 'xz', + '.xz': 'xz', + '.txz': 'xz', # bz2 - 'bz2': 'bz2', - 'tbz': 'bz2', - 'tbz2': 'bz2', - 'tb2': 'bz2', + '.bz2': 'bz2', + '.tbz': 'bz2', + '.tbz2': 'bz2', + '.tb2': 'bz2', } tar_mode = 'w:' + compressions[ext] if ext in compressions else 'w' tar_files = args.create diff --git a/Lib/telnetlib.py b/Lib/telnetlib.py index 0cacac85fa0e..eebb95290272 100644 --- a/Lib/telnetlib.py +++ b/Lib/telnetlib.py @@ -36,10 +36,7 @@ import sys import socket import selectors -try: - from time import monotonic as _time -except ImportError: - from time import time as _time +from time import monotonic as _time __all__ = ["Telnet"] diff --git a/Lib/tempfile.py b/Lib/tempfile.py index 5d3462102f19..0522c7978132 100644 --- a/Lib/tempfile.py +++ b/Lib/tempfile.py @@ -1,10 +1,10 @@ """Temporary files. This module provides generic, low- and high-level interfaces for -creating temporary files and directories. The interfaces listed -as "safe" just below can be used without fear of race conditions. -Those listed as "unsafe" cannot, and are provided for backward -compatibility only. +creating temporary files and directories. All of the interfaces +provided by this module can be used without fear of race conditions +except for 'mktemp'. 'mktemp' is subject to race conditions and +should not be used; it is provided for backward compatibility only. This module also provides some data items to the user: @@ -27,12 +27,14 @@ # Imports. +import functools as _functools import warnings as _warnings -import sys as _sys import io as _io import os as _os +import shutil as _shutil import errno as _errno from random import Random as _Random +import weakref as _weakref try: import _thread @@ -70,7 +72,7 @@ # file doesn't exist. def _stat(fn): fd = _os.open(fn, _os.O_RDONLY) - os.close(fd) + _os.close(fd) def _exists(fn): try: @@ -329,6 +331,47 @@ def mktemp(suffix="", prefix=template, dir=None): "No usable temporary filename found") +class _TemporaryFileCloser: + """A separate object allowing proper closing of a temporary file's + underlying file object, without adding a __del__ method to the + temporary file.""" + + file = None # Set here since __del__ checks it + close_called = False + + def __init__(self, file, name, delete=True): + self.file = file + self.name = name + self.delete = delete + + # NT provides delete-on-close as a primitive, so we don't need + # the wrapper to do anything special. We still use it so that + # file.name is useful (i.e. not "(fdopen)") with NamedTemporaryFile. + if _os.name != 'nt': + # Cache the unlinker so we don't get spurious errors at + # shutdown when the module-level "os" is None'd out. Note + # that this must be referenced as self.unlink, because the + # name TemporaryFileWrapper may also get None'd out before + # __del__ is called. + + def close(self, unlink=_os.unlink): + if not self.close_called and self.file is not None: + self.close_called = True + self.file.close() + if self.delete: + unlink(self.name) + + # Need to ensure the file is deleted on __del__ + def __del__(self): + self.close() + + else: + def close(self): + if not self.close_called: + self.close_called = True + self.file.close() + + class _TemporaryFileWrapper: """Temporary file wrapper @@ -340,8 +383,8 @@ class _TemporaryFileWrapper: def __init__(self, file, name, delete=True): self.file = file self.name = name - self.close_called = False self.delete = delete + self._closer = _TemporaryFileCloser(file, name, delete) def __getattr__(self, name): # Attribute lookups are delegated to the underlying file @@ -349,6 +392,15 @@ def __getattr__(self, name): # (i.e. methods are cached, closed and friends are not) file = self.__dict__['file'] a = getattr(file, name) + if hasattr(a, '__call__'): + func = a + @_functools.wraps(func) + def func_wrapper(*args, **kwargs): + return func(*args, **kwargs) + # Avoid closing the file as long as the wrapper is alive, + # see issue #18879. + func_wrapper._closer = self._closer + a = func_wrapper if not isinstance(a, int): setattr(self, name, a) return a @@ -359,41 +411,23 @@ def __enter__(self): self.file.__enter__() return self + # Need to trap __exit__ as well to ensure the file gets + # deleted when used in a with statement + def __exit__(self, exc, value, tb): + result = self.file.__exit__(exc, value, tb) + self.close() + return result + + def close(self): + """ + Close the temporary file, possibly deleting it. + """ + self._closer.close() + # iter() doesn't use __getattr__ to find the __iter__ method def __iter__(self): return iter(self.file) - # NT provides delete-on-close as a primitive, so we don't need - # the wrapper to do anything special. We still use it so that - # file.name is useful (i.e. not "(fdopen)") with NamedTemporaryFile. - if _os.name != 'nt': - # Cache the unlinker so we don't get spurious errors at - # shutdown when the module-level "os" is None'd out. Note - # that this must be referenced as self.unlink, because the - # name TemporaryFileWrapper may also get None'd out before - # __del__ is called. - unlink = _os.unlink - - def close(self): - if not self.close_called: - self.close_called = True - self.file.close() - if self.delete: - self.unlink(self.name) - - def __del__(self): - self.close() - - # Need to trap __exit__ as well to ensure the file gets - # deleted when used in a with statement - def __exit__(self, exc, value, tb): - result = self.file.__exit__(exc, value, tb) - self.close() - return result - else: - def __exit__(self, exc, value, tb): - self.file.__exit__(exc, value, tb) - def NamedTemporaryFile(mode='w+b', buffering=-1, encoding=None, newline=None, suffix="", prefix=template, @@ -424,10 +458,14 @@ def NamedTemporaryFile(mode='w+b', buffering=-1, encoding=None, flags |= _os.O_TEMPORARY (fd, name) = _mkstemp_inner(dir, prefix, suffix, flags) - file = _io.open(fd, mode, buffering=buffering, - newline=newline, encoding=encoding) + try: + file = _io.open(fd, mode, buffering=buffering, + newline=newline, encoding=encoding) - return _TemporaryFileWrapper(file, name, delete) + return _TemporaryFileWrapper(file, name, delete) + except Exception: + _os.close(fd) + raise if _os.name != 'posix' or _os.sys.platform == 'cygwin': # On non-POSIX and Cygwin systems, assume that we cannot unlink a file @@ -435,6 +473,11 @@ def NamedTemporaryFile(mode='w+b', buffering=-1, encoding=None, TemporaryFile = NamedTemporaryFile else: + # Is the O_TMPFILE flag available and does it work? + # The flag is set to False if os.open(dir, os.O_TMPFILE) raises an + # IsADirectoryError exception + _O_TMPFILE_WORKS = hasattr(_os, 'O_TMPFILE') + def TemporaryFile(mode='w+b', buffering=-1, encoding=None, newline=None, suffix="", prefix=template, dir=None): @@ -450,11 +493,32 @@ def TemporaryFile(mode='w+b', buffering=-1, encoding=None, Returns an object with a file-like interface. The file has no name, and will cease to exist when it is closed. """ + global _O_TMPFILE_WORKS if dir is None: dir = gettempdir() flags = _bin_openflags + if _O_TMPFILE_WORKS: + try: + flags2 = (flags | _os.O_TMPFILE) & ~_os.O_CREAT + fd = _os.open(dir, flags2, 0o600) + except IsADirectoryError: + # Linux kernel older than 3.11 ignores O_TMPFILE flag. + # Set flag to False to not try again. + _O_TMPFILE_WORKS = False + except OSError: + # The filesystem of the directory does not support O_TMPFILE. + # For example, OSError(95, 'Operation not supported'). + pass + else: + try: + return _io.open(fd, mode, buffering=buffering, + newline=newline, encoding=encoding) + except: + _os.close(fd) + raise + # Fallback to _mkstemp_inner(). (fd, name) = _mkstemp_inner(dir, prefix, suffix, flags) try: @@ -480,7 +544,7 @@ def __init__(self, max_size=0, mode='w+b', buffering=-1, else: # Setting newline="\n" avoids newline translation; # this is important because otherwise on Windows we'd - # hget double newline translation upon rollover(). + # get double newline translation upon rollover(). self._file = _io.StringIO(newline="\n") self._max_size = max_size self._rolled = False @@ -626,9 +690,16 @@ class TemporaryDirectory(object): """ def __init__(self, suffix="", prefix=template, dir=None): - self._closed = False - self.name = None # Handle mkdtemp raising an exception self.name = mkdtemp(suffix, prefix, dir) + self._finalizer = _weakref.finalize( + self, self._cleanup, self.name, + warn_message="Implicitly cleaning up {!r}".format(self)) + + @classmethod + def _cleanup(cls, name, warn_message): + _shutil.rmtree(name) + _warnings.warn(warn_message, ResourceWarning) + def __repr__(self): return "<{} {!r}>".format(self.__class__.__name__, self.name) @@ -636,60 +707,9 @@ def __repr__(self): def __enter__(self): return self.name - def cleanup(self, _warn=False): - if self.name and not self._closed: - try: - self._rmtree(self.name) - except (TypeError, AttributeError) as ex: - # Issue #10188: Emit a warning on stderr - # if the directory could not be cleaned - # up due to missing globals - if "None" not in str(ex): - raise - print("ERROR: {!r} while cleaning up {!r}".format(ex, self,), - file=_sys.stderr) - return - self._closed = True - if _warn: - self._warn("Implicitly cleaning up {!r}".format(self), - ResourceWarning) - def __exit__(self, exc, value, tb): self.cleanup() - def __del__(self): - # Issue a ResourceWarning if implicit cleanup needed - self.cleanup(_warn=True) - - # XXX (ncoghlan): The following code attempts to make - # this class tolerant of the module nulling out process - # that happens during CPython interpreter shutdown - # Alas, it doesn't actually manage it. See issue #10188 - _listdir = staticmethod(_os.listdir) - _path_join = staticmethod(_os.path.join) - _isdir = staticmethod(_os.path.isdir) - _islink = staticmethod(_os.path.islink) - _remove = staticmethod(_os.remove) - _rmdir = staticmethod(_os.rmdir) - _warn = _warnings.warn - - def _rmtree(self, path): - # Essentially a stripped down version of shutil.rmtree. We can't - # use globals because they may be None'ed out at shutdown. - for name in self._listdir(path): - fullname = self._path_join(path, name) - try: - isdir = self._isdir(fullname) and not self._islink(fullname) - except OSError: - isdir = False - if isdir: - self._rmtree(fullname) - else: - try: - self._remove(fullname) - except OSError: - pass - try: - self._rmdir(path) - except OSError: - pass + def cleanup(self): + if self._finalizer.detach(): + _shutil.rmtree(self.name) diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index bd26e3d3f2ca..d048f6feabc7 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - # # Unit tests for the multiprocessing package # @@ -198,7 +196,7 @@ class _TestProcess(BaseTestCase): def test_current(self): if self.TYPE == 'threads': - return + self.skipTest('test not appropriate for {}'.format(self.TYPE)) current = self.current_process() authkey = current.authkey @@ -212,7 +210,7 @@ def test_current(self): def test_daemon_argument(self): if self.TYPE == "threads": - return + self.skipTest('test not appropriate for {}'.format(self.TYPE)) # By default uses the current process's daemon flag. proc0 = self.Process(target=self._test) @@ -277,7 +275,7 @@ def _test_terminate(cls): def test_terminate(self): if self.TYPE == 'threads': - return + self.skipTest('test not appropriate for {}'.format(self.TYPE)) p = self.Process(target=self._test_terminate) p.daemon = True @@ -385,7 +383,7 @@ def _test_sentinel(cls, event): def test_sentinel(self): if self.TYPE == "threads": - return + self.skipTest('test not appropriate for {}'.format(self.TYPE)) event = self.Event() p = self.Process(target=self._test_sentinel, args=(event,)) with self.assertRaises(ValueError): @@ -441,7 +439,7 @@ def test_subclassing(self): def test_stderr_flush(self): # sys.stderr is flushed at process shutdown (issue #13812) if self.TYPE == "threads": - return + self.skipTest('test not appropriate for {}'.format(self.TYPE)) testfn = test.support.TESTFN self.addCleanup(test.support.unlink, testfn) @@ -469,7 +467,7 @@ def _test_sys_exit(cls, reason, testfn): def test_sys_exit(self): # See Issue 13854 if self.TYPE == 'threads': - return + self.skipTest('test not appropriate for {}'.format(self.TYPE)) testfn = test.support.TESTFN self.addCleanup(test.support.unlink, testfn) @@ -678,7 +676,7 @@ def test_qsize(self): try: self.assertEqual(q.qsize(), 0) except NotImplementedError: - return + self.skipTest('qsize method not implemented') q.put(1) self.assertEqual(q.qsize(), 1) q.put(5) @@ -697,9 +695,6 @@ def _test_task_done(cls, q): def test_task_done(self): queue = self.JoinableQueue() - if sys.version_info < (2, 5) and not hasattr(queue, 'task_done'): - self.skipTest("requires 'queue.task_done()' method") - workers = [self.Process(target=self._test_task_done, args=(queue,)) for i in range(4)] @@ -721,9 +716,11 @@ def test_task_done(self): def test_timeout(self): q = multiprocessing.Queue() start = time.time() - self.assertRaises(pyqueue.Empty, q.get, True, 0.2) + self.assertRaises(pyqueue.Empty, q.get, True, 0.200) delta = time.time() - start - self.assertGreaterEqual(delta, 0.18) + # Tolerate a delta of 30 ms because of the bad clock resolution on + # Windows (usually 15.6 ms) + self.assertGreaterEqual(delta, 0.170) # # @@ -786,7 +783,7 @@ def test_bounded_semaphore(self): def test_timeout(self): if self.TYPE != 'processes': - return + self.skipTest('test not appropriate for {}'.format(self.TYPE)) sem = self.Semaphore(0) acquire = TimingWrapper(sem.acquire) @@ -1406,7 +1403,7 @@ def _test_thousand_f(cls, barrier, passes, conn, lock): def test_thousand(self): if self.TYPE == 'manager': - return + self.skipTest('test not appropriate for {}'.format(self.TYPE)) passes = 1000 lock = self.Lock() conn, child_conn = self.Pipe(False) @@ -1701,7 +1698,7 @@ def test_map_async_callbacks(self): def test_map_unplicklable(self): # Issue #19425 -- failure to pickle should not cause a hang if self.TYPE == 'threads': - return + self.skipTest('test not appropriate for {}'.format(self.TYPE)) class A(object): def __reduce__(self): raise RuntimeError('cannot pickle') @@ -1815,6 +1812,17 @@ def test_traceback(self): self.assertIn('raise RuntimeError(123) # some comment', f1.getvalue()) + @classmethod + def _test_wrapped_exception(cls): + raise RuntimeError('foo') + + def test_wrapped_exception(self): + # Issue #20980: Should not wrap exception when using thread pool + with self.Pool(1) as p: + with self.assertRaises(RuntimeError): + p.apply(self._test_wrapped_exception) + + def raising(): raise KeyError("key") @@ -2012,6 +2020,12 @@ class QueueManager2(BaseManager): class _TestRemoteManager(BaseTestCase): ALLOWED_TYPES = ('manager',) + values = ['hello world', None, True, 2.25, + 'hall\xe5 v\xe4rlden', + '\u043f\u0440\u0438\u0432\u0456\u0442 \u0441\u0432\u0456\u0442', + b'hall\xe5 v\xe4rlden', + ] + result = values[:] @classmethod def _putter(cls, address, authkey): @@ -2020,7 +2034,8 @@ def _putter(cls, address, authkey): ) manager.connect() queue = manager.get_queue() - queue.put(('hello world', None, True, 2.25)) + # Note that xmlrpclib will deserialize object as a list not a tuple + queue.put(tuple(cls.values)) def test_remote(self): authkey = os.urandom(32) @@ -2040,8 +2055,7 @@ def test_remote(self): manager2.connect() queue = manager2.get_queue() - # Note that xmlrpclib will deserialize object as a list not a tuple - self.assertEqual(queue.get(), ['hello world', None, True, 2.25]) + self.assertEqual(queue.get(), self.result) # Because we are using xmlrpclib for serialization instead of # pickle this will cause a serialization error. @@ -2224,7 +2238,7 @@ def test_spawn_close(self): def test_sendbytes(self): if self.TYPE != 'processes': - return + self.skipTest('test not appropriate for {}'.format(self.TYPE)) msg = latin('abcdefghijklmnopqrstuvwxyz') a, b = self.Pipe() @@ -2537,7 +2551,7 @@ def _listener(cls, conn, families): l = socket.socket() l.bind((test.support.HOST, 0)) - l.listen(1) + l.listen() conn.send(l.getsockname()) new_conn, addr = l.accept() conn.send(new_conn) @@ -3184,7 +3198,7 @@ def test_wait_socket(self, slow=False): from multiprocessing.connection import wait l = socket.socket() l.bind((test.support.HOST, 0)) - l.listen(4) + l.listen() addr = l.getsockname() readers = [] procs = [] @@ -3397,12 +3411,12 @@ def test_noforkbomb(self): name = os.path.join(os.path.dirname(__file__), 'mp_fork_bomb.py') if sm != 'fork': rc, out, err = test.script_helper.assert_python_failure(name, sm) - self.assertEqual('', out.decode('ascii')) - self.assertIn('RuntimeError', err.decode('ascii')) + self.assertEqual(out, b'') + self.assertIn(b'RuntimeError', err) else: rc, out, err = test.script_helper.assert_python_ok(name, sm) - self.assertEqual('123', out.decode('ascii').rstrip()) - self.assertEqual('', err.decode('ascii')) + self.assertEqual(out.rstrip(), b'123') + self.assertEqual(err, b'') # # Issue #17555: ForkAwareThreadLock @@ -3656,7 +3670,7 @@ def test_semaphore_tracker(self): _multiprocessing.sem_unlink(name1) p.terminate() p.wait() - time.sleep(1.0) + time.sleep(2.0) with self.assertRaises(OSError) as ctx: _multiprocessing.sem_unlink(name2) # docs say it should be ENOENT, but OSX seems to give EINVAL diff --git a/Lib/test/audiotests.py b/Lib/test/audiotests.py index b7497ce5b06d..0ae22428512d 100644 --- a/Lib/test/audiotests.py +++ b/Lib/test/audiotests.py @@ -45,8 +45,9 @@ def check_params(self, f, nchannels, sampwidth, framerate, nframes, self.assertEqual(params.comptype, comptype) self.assertEqual(params.compname, compname) - dump = pickle.dumps(params) - self.assertEqual(pickle.loads(dump), params) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + dump = pickle.dumps(params, proto) + self.assertEqual(pickle.loads(dump), params) class AudioWriteTests(AudioTests): diff --git a/Lib/test/coding20731.py b/Lib/test/coding20731.py new file mode 100644 index 000000000000..b0e227ad110e --- /dev/null +++ b/Lib/test/coding20731.py @@ -0,0 +1,4 @@ +#coding:latin1 + + + diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py index b67d28c8b66d..7935cf23204d 100644 --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -3,8 +3,10 @@ See http://www.zope.org/Members/fdrake/DateTimeWiki/TestCases """ +import decimal import sys import pickle +import random import unittest from operator import lt, le, gt, ge, eq, ne, truediv, floordiv, mod @@ -49,6 +51,17 @@ def test_constants(self): self.assertEqual(datetime.MINYEAR, 1) self.assertEqual(datetime.MAXYEAR, 9999) + def test_name_cleanup(self): + if '_Fast' not in str(self): + return + datetime = datetime_module + names = set(name for name in dir(datetime) + if not name.startswith('__') and not name.endswith('__')) + allowed = set(['MAXYEAR', 'MINYEAR', 'date', 'datetime', + 'datetime_CAPI', 'time', 'timedelta', 'timezone', + 'tzinfo']) + self.assertEqual(names - allowed, set([])) + ############################################################################# # tzinfo tests @@ -76,8 +89,18 @@ class PicklableFixedOffset(FixedOffset): def __init__(self, offset=None, name=None, dstoffset=None): FixedOffset.__init__(self, offset, name, dstoffset) +class _TZInfo(tzinfo): + def utcoffset(self, datetime_module): + return random.random() + class TestTZInfo(unittest.TestCase): + def test_refcnt_crash_bug_22044(self): + tz1 = _TZInfo() + dt1 = datetime(2014, 7, 21, 11, 32, 3, 0, tz1) + with self.assertRaises(TypeError): + dt1.utcoffset() + def test_non_abstractness(self): # In order to allow subclasses to get pickled, the C implementation # wasn't able to get away with having __init__ raise @@ -605,8 +628,12 @@ def test_microsecond_rounding(self): # Single-field rounding. eq(td(milliseconds=0.4/1000), td(0)) # rounds to 0 eq(td(milliseconds=-0.4/1000), td(0)) # rounds to 0 + eq(td(milliseconds=0.5/1000), td(microseconds=0)) + eq(td(milliseconds=-0.5/1000), td(microseconds=0)) eq(td(milliseconds=0.6/1000), td(microseconds=1)) eq(td(milliseconds=-0.6/1000), td(microseconds=-1)) + eq(td(seconds=0.5/10**6), td(microseconds=0)) + eq(td(seconds=-0.5/10**6), td(microseconds=0)) # Rounding due to contributions from more than one field. us_per_hour = 3600e6 @@ -1120,11 +1147,13 @@ def test_strftime(self): #check that this standard extension works t.strftime("%f") - def test_format(self): dt = self.theclass(2007, 9, 10) self.assertEqual(dt.__format__(''), str(dt)) + with self.assertRaisesRegex(TypeError, '^must be str, not int$'): + dt.__format__(123) + # check that a derived class's __str__() gets called class A(self.theclass): def __str__(self): @@ -1276,8 +1305,6 @@ def __le__(self, other): return isinstance(other, LargerThanAnything) def __eq__(self, other): return isinstance(other, LargerThanAnything) - def __ne__(self, other): - return not isinstance(other, LargerThanAnything) def __gt__(self, other): return not isinstance(other, LargerThanAnything) def __ge__(self, other): @@ -1380,9 +1407,10 @@ def test_backdoor_resistance(self): for month_byte in b'9', b'\0', b'\r', b'\xff': self.assertRaises(TypeError, self.theclass, base[:2] + month_byte + base[3:]) - # Good bytes, but bad tzinfo: - self.assertRaises(TypeError, self.theclass, - bytes([1] * len(base)), 'EST') + if issubclass(self.theclass, datetime): + # Good bytes, but bad tzinfo: + with self.assertRaisesRegex(TypeError, '^bad tzinfo state arg$'): + self.theclass(bytes([1] * len(base)), 'EST') for ord_byte in range(1, 13): # This shouldn't blow up because of the month byte alone. If @@ -1458,6 +1486,9 @@ def test_format(self): dt = self.theclass(2007, 9, 10, 4, 5, 1, 123) self.assertEqual(dt.__format__(''), str(dt)) + with self.assertRaisesRegex(TypeError, '^must be str, not int$'): + dt.__format__(123) + # check that a derived class's __str__() gets called class A(self.theclass): def __str__(self): @@ -1671,11 +1702,12 @@ def test_pickling(self): def test_more_pickling(self): a = self.theclass(2003, 2, 7, 16, 48, 37, 444116) - s = pickle.dumps(a) - b = pickle.loads(s) - self.assertEqual(b.year, 2003) - self.assertEqual(b.month, 2) - self.assertEqual(b.day, 7) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + s = pickle.dumps(a, proto) + b = pickle.loads(s) + self.assertEqual(b.year, 2003) + self.assertEqual(b.month, 2) + self.assertEqual(b.day, 7) def test_pickling_subclass_datetime(self): args = 6, 7, 23, 20, 59, 1, 64**2 @@ -1778,6 +1810,7 @@ def test_timestamp_aware(self): tzinfo=timezone(timedelta(hours=-5), 'EST')) self.assertEqual(t.timestamp(), 18000 + 3600 + 2*60 + 3 + 4*1e-6) + def test_microsecond_rounding(self): for fts in [self.theclass.fromtimestamp, self.theclass.utcfromtimestamp]: @@ -1828,6 +1861,7 @@ def test_insane_utcfromtimestamp(self): for insane in -1e200, 1e200: self.assertRaises(OverflowError, self.theclass.utcfromtimestamp, insane) + @unittest.skipIf(sys.platform == "win32", "Windows doesn't accept negative timestamps") def test_negative_float_fromtimestamp(self): # The result is tz-dependent; at least test that this doesn't @@ -2029,6 +2063,7 @@ def newmeth(self, start): class TestSubclassDateTime(TestDateTime): theclass = SubclassDatetime # Override tests not designed for subclass + @unittest.skip('not appropriate for subclasses') def test_roundtrip(self): pass @@ -2206,6 +2241,9 @@ def test_format(self): t = self.theclass(1, 2, 3, 4) self.assertEqual(t.__format__(''), str(t)) + with self.assertRaisesRegex(TypeError, '^must be str, not int$'): + t.__format__(123) + # check that a derived class's __str__() gets called class A(self.theclass): def __str__(self): @@ -2269,13 +2307,14 @@ def test_pickling_subclass_time(self): self.assertEqual(orig, derived) def test_bool(self): + # time is always True. cls = self.theclass self.assertTrue(cls(1)) self.assertTrue(cls(0, 1)) self.assertTrue(cls(0, 0, 1)) self.assertTrue(cls(0, 0, 0, 1)) - self.assertFalse(cls(0)) - self.assertFalse(cls()) + self.assertTrue(cls(0)) + self.assertTrue(cls()) def test_replace(self): cls = self.theclass @@ -2334,6 +2373,9 @@ def test_backdoor_resistance(self): for hour_byte in ' ', '9', chr(24), '\xff': self.assertRaises(TypeError, self.theclass, hour_byte + base[1:]) + # Good bytes, but bad tzinfo: + with self.assertRaisesRegex(TypeError, '^bad tzinfo state arg$'): + self.theclass(bytes([1] * len(base)), 'EST') # A mixin for classes with a tzinfo= argument. Subclasses must define # theclass as a class atribute, and theclass(1, 1, 1, tzinfo=whatever) @@ -2593,7 +2635,7 @@ def tzname(self, dt): return self.tz self.assertRaises(TypeError, t.strftime, "%Z") # Issue #6697: - if '_Fast' in str(type(self)): + if '_Fast' in str(self): Badtzname.tz = '\ud800' self.assertRaises(ValueError, t.strftime, "%Z") @@ -2628,7 +2670,7 @@ def test_pickling(self): self.assertEqual(derived.tzname(), 'cookie') def test_more_bool(self): - # Test cases with non-None tzinfo. + # time is always True. cls = self.theclass t = cls(0, tzinfo=FixedOffset(-300, "")) @@ -2638,23 +2680,11 @@ def test_more_bool(self): self.assertTrue(t) t = cls(5, tzinfo=FixedOffset(300, "")) - self.assertFalse(t) + self.assertTrue(t) t = cls(23, 59, tzinfo=FixedOffset(23*60 + 59, "")) - self.assertFalse(t) - - # Mostly ensuring this doesn't overflow internally. - t = cls(0, tzinfo=FixedOffset(23*60 + 59, "")) self.assertTrue(t) - # But this should yield a value error -- the utcoffset is bogus. - t = cls(0, tzinfo=FixedOffset(24*60, "")) - self.assertRaises(ValueError, lambda: bool(t)) - - # Likewise. - t = cls(0, tzinfo=FixedOffset(-24*60, "")) - self.assertRaises(ValueError, lambda: bool(t)) - def test_replace(self): cls = self.theclass z100 = FixedOffset(100, "+100") @@ -3767,6 +3797,60 @@ def test_bug_1028306(self): self.assertEqual(as_datetime, datetime_sc) self.assertEqual(datetime_sc, as_datetime) + def test_extra_attributes(self): + for x in [date.today(), + time(), + datetime.utcnow(), + timedelta(), + tzinfo(), + timezone(timedelta())]: + with self.assertRaises(AttributeError): + x.abc = 1 + + def test_check_arg_types(self): + class Number: + def __init__(self, value): + self.value = value + def __int__(self): + return self.value + + for xx in [decimal.Decimal(10), + decimal.Decimal('10.9'), + Number(10)]: + self.assertEqual(datetime(10, 10, 10, 10, 10, 10, 10), + datetime(xx, xx, xx, xx, xx, xx, xx)) + + with self.assertRaisesRegex(TypeError, '^an integer is required ' + '\(got type str\)$'): + datetime(10, 10, '10') + + f10 = Number(10.9) + with self.assertRaisesRegex(TypeError, '^__int__ returned non-int ' + '\(type float\)$'): + datetime(10, 10, f10) + + class Float(float): + pass + s10 = Float(10.9) + with self.assertRaisesRegex(TypeError, '^integer argument expected, ' + 'got float$'): + datetime(10, 10, s10) + + with self.assertRaises(TypeError): + datetime(10., 10, 10) + with self.assertRaises(TypeError): + datetime(10, 10., 10) + with self.assertRaises(TypeError): + datetime(10, 10, 10.) + with self.assertRaises(TypeError): + datetime(10, 10, 10, 10.) + with self.assertRaises(TypeError): + datetime(10, 10, 10, 10, 10.) + with self.assertRaises(TypeError): + datetime(10, 10, 10, 10, 10, 10.) + with self.assertRaises(TypeError): + datetime(10, 10, 10, 10, 10, 10, 10.) + def test_main(): support.run_unittest(__name__) diff --git a/Lib/test/eintrdata/eintr_tester.py b/Lib/test/eintrdata/eintr_tester.py new file mode 100644 index 000000000000..40dca847d00f --- /dev/null +++ b/Lib/test/eintrdata/eintr_tester.py @@ -0,0 +1,260 @@ +""" +This test suite exercises some system calls subject to interruption with EINTR, +to check that it is actually handled transparently. +It is intended to be run by the main test suite within a child process, to +ensure there is no background thread running (so that signals are delivered to +the correct thread). +Signals are generated in-process using setitimer(ITIMER_REAL), which allows +sub-second periodicity (contrarily to signal()). +""" + +import io +import os +import signal +import socket +import time +import unittest + +from test import support + + +@unittest.skipUnless(hasattr(signal, "setitimer"), "requires setitimer()") +class EINTRBaseTest(unittest.TestCase): + """ Base class for EINTR tests. """ + + # delay for initial signal delivery + signal_delay = 0.1 + # signal delivery periodicity + signal_period = 0.1 + # default sleep time for tests - should obviously have: + # sleep_time > signal_period + sleep_time = 0.2 + + @classmethod + def setUpClass(cls): + cls.orig_handler = signal.signal(signal.SIGALRM, lambda *args: None) + signal.setitimer(signal.ITIMER_REAL, cls.signal_delay, + cls.signal_period) + + @classmethod + def tearDownClass(cls): + signal.setitimer(signal.ITIMER_REAL, 0, 0) + signal.signal(signal.SIGALRM, cls.orig_handler) + + @classmethod + def _sleep(cls): + # default sleep time + time.sleep(cls.sleep_time) + + +@unittest.skipUnless(hasattr(signal, "setitimer"), "requires setitimer()") +class OSEINTRTest(EINTRBaseTest): + """ EINTR tests for the os module. """ + + def _test_wait_multiple(self, wait_func): + num = 3 + for _ in range(num): + pid = os.fork() + if pid == 0: + self._sleep() + os._exit(0) + for _ in range(num): + wait_func() + + def test_wait(self): + self._test_wait_multiple(os.wait) + + @unittest.skipUnless(hasattr(os, 'wait3'), 'requires wait3()') + def test_wait3(self): + self._test_wait_multiple(lambda: os.wait3(0)) + + def _test_wait_single(self, wait_func): + pid = os.fork() + if pid == 0: + self._sleep() + os._exit(0) + else: + wait_func(pid) + + def test_waitpid(self): + self._test_wait_single(lambda pid: os.waitpid(pid, 0)) + + @unittest.skipUnless(hasattr(os, 'wait4'), 'requires wait4()') + def test_wait4(self): + self._test_wait_single(lambda pid: os.wait4(pid, 0)) + + def test_read(self): + rd, wr = os.pipe() + self.addCleanup(os.close, rd) + # wr closed explicitly by parent + + # the payload below are smaller than PIPE_BUF, hence the writes will be + # atomic + datas = [b"hello", b"world", b"spam"] + + pid = os.fork() + if pid == 0: + os.close(rd) + for data in datas: + # let the parent block on read() + self._sleep() + os.write(wr, data) + os._exit(0) + else: + self.addCleanup(os.waitpid, pid, 0) + os.close(wr) + for data in datas: + self.assertEqual(data, os.read(rd, len(data))) + + def test_write(self): + rd, wr = os.pipe() + self.addCleanup(os.close, wr) + # rd closed explicitly by parent + + # we must write enough data for the write() to block + data = b"xyz" * support.PIPE_MAX_SIZE + + pid = os.fork() + if pid == 0: + os.close(wr) + read_data = io.BytesIO() + # let the parent block on write() + self._sleep() + while len(read_data.getvalue()) < len(data): + chunk = os.read(rd, 2 * len(data)) + read_data.write(chunk) + self.assertEqual(read_data.getvalue(), data) + os._exit(0) + else: + os.close(rd) + written = 0 + while written < len(data): + written += os.write(wr, memoryview(data)[written:]) + self.assertEqual(0, os.waitpid(pid, 0)[1]) + + +@unittest.skipUnless(hasattr(signal, "setitimer"), "requires setitimer()") +class SocketEINTRTest(EINTRBaseTest): + """ EINTR tests for the socket module. """ + + @unittest.skipUnless(hasattr(socket, 'socketpair'), 'needs socketpair()') + def _test_recv(self, recv_func): + rd, wr = socket.socketpair() + self.addCleanup(rd.close) + # wr closed explicitly by parent + + # single-byte payload guard us against partial recv + datas = [b"x", b"y", b"z"] + + pid = os.fork() + if pid == 0: + rd.close() + for data in datas: + # let the parent block on recv() + self._sleep() + wr.sendall(data) + os._exit(0) + else: + self.addCleanup(os.waitpid, pid, 0) + wr.close() + for data in datas: + self.assertEqual(data, recv_func(rd, len(data))) + + def test_recv(self): + self._test_recv(socket.socket.recv) + + @unittest.skipUnless(hasattr(socket.socket, 'recvmsg'), 'needs recvmsg()') + def test_recvmsg(self): + self._test_recv(lambda sock, data: sock.recvmsg(data)[0]) + + def _test_send(self, send_func): + rd, wr = socket.socketpair() + self.addCleanup(wr.close) + # rd closed explicitly by parent + + # we must send enough data for the send() to block + data = b"xyz" * (support.SOCK_MAX_SIZE // 3) + + pid = os.fork() + if pid == 0: + wr.close() + # let the parent block on send() + self._sleep() + received_data = bytearray(len(data)) + n = 0 + while n < len(data): + n += rd.recv_into(memoryview(received_data)[n:]) + self.assertEqual(received_data, data) + os._exit(0) + else: + rd.close() + written = 0 + while written < len(data): + sent = send_func(wr, memoryview(data)[written:]) + # sendall() returns None + written += len(data) if sent is None else sent + self.assertEqual(0, os.waitpid(pid, 0)[1]) + + def test_send(self): + self._test_send(socket.socket.send) + + def test_sendall(self): + self._test_send(socket.socket.sendall) + + @unittest.skipUnless(hasattr(socket.socket, 'sendmsg'), 'needs sendmsg()') + def test_sendmsg(self): + self._test_send(lambda sock, data: sock.sendmsg([data])) + + def test_accept(self): + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.addCleanup(sock.close) + + sock.bind((support.HOST, 0)) + _, port = sock.getsockname() + sock.listen() + + pid = os.fork() + if pid == 0: + # let parent block on accept() + self._sleep() + with socket.create_connection((support.HOST, port)): + self._sleep() + os._exit(0) + else: + self.addCleanup(os.waitpid, pid, 0) + client_sock, _ = sock.accept() + client_sock.close() + + @unittest.skipUnless(hasattr(os, 'mkfifo'), 'needs mkfifo()') + def _test_open(self, do_open_close_reader, do_open_close_writer): + # Use a fifo: until the child opens it for reading, the parent will + # block when trying to open it for writing. + support.unlink(support.TESTFN) + os.mkfifo(support.TESTFN) + self.addCleanup(support.unlink, support.TESTFN) + + pid = os.fork() + if pid == 0: + # let the parent block + self._sleep() + do_open_close_reader(support.TESTFN) + os._exit(0) + else: + self.addCleanup(os.waitpid, pid, 0) + do_open_close_writer(support.TESTFN) + + def test_open(self): + self._test_open(lambda path: open(path, 'r').close(), + lambda path: open(path, 'w').close()) + + def test_os_open(self): + self._test_open(lambda path: os.close(os.open(path, os.O_RDONLY)), + lambda path: os.close(os.open(path, os.O_WRONLY))) + + +def test_main(): + support.run_unittest(OSEINTRTest, SocketEINTRTest) + + +if __name__ == "__main__": + test_main() diff --git a/Lib/test/fork_wait.py b/Lib/test/fork_wait.py index 19b54ec736b7..713039dd8268 100644 --- a/Lib/test/fork_wait.py +++ b/Lib/test/fork_wait.py @@ -48,7 +48,12 @@ def test_wait(self): for i in range(NUM_THREADS): _thread.start_new(self.f, (i,)) - time.sleep(LONGSLEEP) + # busy-loop to wait for threads + deadline = time.monotonic() + 10.0 + while len(self.alive) < NUM_THREADS: + time.sleep(0.1) + if deadline < time.monotonic(): + break a = sorted(self.alive.keys()) self.assertEqual(a, list(range(NUM_THREADS))) diff --git a/Lib/test/imghdrdata/python.bmp b/Lib/test/imghdrdata/python.bmp new file mode 100644 index 000000000000..675f95191a45 Binary files /dev/null and b/Lib/test/imghdrdata/python.bmp differ diff --git a/Lib/test/imghdrdata/python.exr b/Lib/test/imghdrdata/python.exr new file mode 100644 index 000000000000..773c81ee1fb8 Binary files /dev/null and b/Lib/test/imghdrdata/python.exr differ diff --git a/Lib/test/imghdrdata/python.gif b/Lib/test/imghdrdata/python.gif new file mode 100644 index 000000000000..96fd9fef76b1 Binary files /dev/null and b/Lib/test/imghdrdata/python.gif differ diff --git a/Lib/test/imghdrdata/python.jpg b/Lib/test/imghdrdata/python.jpg new file mode 100644 index 000000000000..21222c09f5a7 Binary files /dev/null and b/Lib/test/imghdrdata/python.jpg differ diff --git a/Lib/test/imghdrdata/python.pbm b/Lib/test/imghdrdata/python.pbm new file mode 100644 index 000000000000..1848ba7ff064 --- /dev/null +++ b/Lib/test/imghdrdata/python.pbm @@ -0,0 +1,3 @@ +P4 +16 16 +ûñ¿úßÕ­±[ñ¥a_ÁX°°ðððð?ÿÿ \ No newline at end of file diff --git a/Lib/test/imghdrdata/python.pgm b/Lib/test/imghdrdata/python.pgm new file mode 100644 index 000000000000..8349f2a53a9b Binary files /dev/null and b/Lib/test/imghdrdata/python.pgm differ diff --git a/Lib/test/imghdrdata/python.png b/Lib/test/imghdrdata/python.png new file mode 100644 index 000000000000..1a987f79fcd2 Binary files /dev/null and b/Lib/test/imghdrdata/python.png differ diff --git a/Lib/test/imghdrdata/python.ppm b/Lib/test/imghdrdata/python.ppm new file mode 100644 index 000000000000..7d9cdb321587 Binary files /dev/null and b/Lib/test/imghdrdata/python.ppm differ diff --git a/Lib/test/imghdrdata/python.ras b/Lib/test/imghdrdata/python.ras new file mode 100644 index 000000000000..130e96f817ed Binary files /dev/null and b/Lib/test/imghdrdata/python.ras differ diff --git a/Lib/test/imghdrdata/python.sgi b/Lib/test/imghdrdata/python.sgi new file mode 100644 index 000000000000..ffe9081c7a5b Binary files /dev/null and b/Lib/test/imghdrdata/python.sgi differ diff --git a/Lib/test/imghdrdata/python.tiff b/Lib/test/imghdrdata/python.tiff new file mode 100644 index 000000000000..39d0bfcec025 Binary files /dev/null and b/Lib/test/imghdrdata/python.tiff differ diff --git a/Lib/test/imghdrdata/python.webp b/Lib/test/imghdrdata/python.webp new file mode 100644 index 000000000000..e824ec7fb1c7 Binary files /dev/null and b/Lib/test/imghdrdata/python.webp differ diff --git a/Lib/test/imghdrdata/python.xbm b/Lib/test/imghdrdata/python.xbm new file mode 100644 index 000000000000..cfbee2e98062 --- /dev/null +++ b/Lib/test/imghdrdata/python.xbm @@ -0,0 +1,6 @@ +#define python_width 16 +#define python_height 16 +static char python_bits[] = { + 0xDF, 0xFE, 0x8F, 0xFD, 0x5F, 0xFB, 0xAB, 0xFE, 0xB5, 0x8D, 0xDA, 0x8F, + 0xA5, 0x86, 0xFA, 0x83, 0x1A, 0x80, 0x0D, 0x80, 0x0D, 0x80, 0x0F, 0xE0, + 0x0F, 0xF8, 0x0F, 0xF8, 0x0F, 0xFC, 0xFF, 0xFF, }; diff --git a/Lib/test/inspect_fodder2.py b/Lib/test/inspect_fodder2.py index bd7106fea86b..e452235cd8e5 100644 --- a/Lib/test/inspect_fodder2.py +++ b/Lib/test/inspect_fodder2.py @@ -109,3 +109,16 @@ def annotated(arg1: list): #line 109 def keyword_only_arg(*, arg): pass + +from functools import wraps + +def decorator(func): + @wraps(func) + def fake(): + return 42 + return fake + +#line 121 +@decorator +def real(): + return 20 diff --git a/Lib/test/list_tests.py b/Lib/test/list_tests.py index 42e118ba8f8f..906933796d23 100644 --- a/Lib/test/list_tests.py +++ b/Lib/test/list_tests.py @@ -30,6 +30,12 @@ def test_init(self): self.assertNotEqual(id(a), id(b)) self.assertEqual(a, b) + def test_getitem_error(self): + msg = "list indices must be integers or slices" + with self.assertRaisesRegex(TypeError, msg): + a = [] + a['a'] = "python" + def test_repr(self): l0 = [] l2 = [0, 1, 2] @@ -120,6 +126,10 @@ def test_setitem(self): a[-1] = 9 self.assertEqual(a, self.type2test([5,6,7,8,9])) + msg = "list indices must be integers or slices" + with self.assertRaisesRegex(TypeError, msg): + a['a'] = "python" + def test_delitem(self): a = self.type2test([0, 1]) del a[1] diff --git a/Lib/test/lock_tests.py b/Lib/test/lock_tests.py index 1cbcea234396..136f1c37c62b 100644 --- a/Lib/test/lock_tests.py +++ b/Lib/test/lock_tests.py @@ -82,7 +82,13 @@ def test_constructor(self): def test_repr(self): lock = self.locktype() - repr(lock) + self.assertRegex(repr(lock), "<unlocked .* object (.*)?at .*>") + del lock + + def test_locked_repr(self): + lock = self.locktype() + lock.acquire() + self.assertRegex(repr(lock), "<locked .* object (.*)?at .*>") del lock def test_acquire_destroy(self): diff --git a/Lib/test/make_ssl_certs.py b/Lib/test/make_ssl_certs.py index 4251d5524ffa..81d04f82dcfb 100644 --- a/Lib/test/make_ssl_certs.py +++ b/Lib/test/make_ssl_certs.py @@ -115,7 +115,7 @@ def make_ca(): with open(os.path.join('cadir','index.txt'),'a+') as f: pass # empty file with open(os.path.join('cadir','crl.txt'),'a+') as f: - r.write("00") + f.write("00") with open(os.path.join('cadir','index.txt.attr'),'w+') as f: f.write('unique_subject = no') diff --git a/Lib/test/mock_socket.py b/Lib/test/mock_socket.py index 8ef0ec8c8dae..b28c4732cc3c 100644 --- a/Lib/test/mock_socket.py +++ b/Lib/test/mock_socket.py @@ -21,8 +21,13 @@ class MockFile: """ def __init__(self, lines): self.lines = lines - def readline(self): - return self.lines.pop(0) + b'\r\n' + def readline(self, limit=-1): + result = self.lines.pop(0) + b'\r\n' + if limit >= 0: + # Re-insert the line, removing the \r\n we added. + self.lines.insert(0, result[limit:-2]) + result = result[:limit] + return result def close(self): pass @@ -30,8 +35,9 @@ def close(self): class MockSocket: """Mock socket object used by smtpd and smtplib tests. """ - def __init__(self): + def __init__(self, family=None): global _reply_data + self.family = family self.output = [] self.lines = [] if _reply_data: @@ -96,15 +102,14 @@ def send(self, data, flags=None): return len(data) def getpeername(self): - return 'peer' + return ('peer-address', 'peer-port') def close(self): pass def socket(family=None, type=None, proto=None): - return MockSocket() - + return MockSocket(family) def create_connection(address, timeout=socket_module._GLOBAL_DEFAULT_TIMEOUT, source_address=None): @@ -139,13 +144,16 @@ def gethostname(): def gethostbyname(name): return "" +def getaddrinfo(*args, **kw): + return socket_module.getaddrinfo(*args, **kw) gaierror = socket_module.gaierror error = socket_module.error # Constants -AF_INET = None -SOCK_STREAM = None +AF_INET = socket_module.AF_INET +AF_INET6 = socket_module.AF_INET6 +SOCK_STREAM = socket_module.SOCK_STREAM SOL_SOCKET = None SO_REUSEADDR = None diff --git a/Lib/test/multibytecodec_support.py b/Lib/test/multibytecodec_support.py index dcaae7b95c0d..bc1cfc8518d8 100644 --- a/Lib/test/multibytecodec_support.py +++ b/Lib/test/multibytecodec_support.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 # # multibytecodec_support.py # Common Unittest Routines for CJK codecs @@ -22,7 +21,7 @@ class TestBase: roundtriptest = 1 # set if roundtrip is possible with unicode has_iso10646 = 0 # set if this encoding contains whole iso10646 map xmlcharnametest = None # string to test xmlcharrefreplace - unmappedunicode = '\udeee' # a unicode codepoint that is not mapped. + unmappedunicode = '\udeee' # a unicode code point that is not mapped. def setUp(self): if self.codec is None: @@ -73,7 +72,7 @@ def test_errorhandle(self): def test_xmlcharrefreplace(self): if self.has_iso10646: - return + self.skipTest('encoding contains full ISO 10646 map') s = "\u0b13\u0b23\u0b60 nd eggs" self.assertEqual( @@ -83,7 +82,7 @@ def test_xmlcharrefreplace(self): def test_customreplace_encode(self): if self.has_iso10646: - return + self.skipTest('encoding contains full ISO 10646 map') from html.entities import codepoint2name @@ -278,8 +277,7 @@ class TestBase_Mapping(unittest.TestCase): supmaps = [] codectests = [] - def __init__(self, *args, **kw): - unittest.TestCase.__init__(self, *args, **kw) + def setUp(self): try: self.open_mapping_file().close() # test it to report the error early except (OSError, HTTPException): diff --git a/Lib/test/outstanding_bugs.py b/Lib/test/outstanding_bugs.py index 0849ee588582..7e527a670643 100644 --- a/Lib/test/outstanding_bugs.py +++ b/Lib/test/outstanding_bugs.py @@ -10,79 +10,9 @@ from test import support # -# One test case for outstanding bugs at the moment: +# No test cases for outstanding bugs at the moment. # -# test_io -import io -class TextIOWrapperTest(unittest.TestCase): - - def setUp(self): - self.testdata = b"AAA\r\nBBB\rCCC\r\nDDD\nEEE\r\n" - self.normalized = b"AAA\nBBB\nCCC\nDDD\nEEE\n".decode("ASCII") - - def tearDown(self): - support.unlink(support.TESTFN) - - - def test_issue1395_1(self): - txt = io.TextIOWrapper(io.BytesIO(self.testdata), encoding="ASCII") - - # read one char at a time - reads = "" - while True: - c = txt.read(1) - if not c: - break - reads += c - self.assertEqual(reads, self.normalized) - - def test_issue1395_2(self): - txt = io.TextIOWrapper(io.BytesIO(self.testdata), encoding="ASCII") - txt._CHUNK_SIZE = 4 - - reads = "" - while True: - c = txt.read(4) - if not c: - break - reads += c - self.assertEqual(reads, self.normalized) - - def test_issue1395_3(self): - txt = io.TextIOWrapper(io.BytesIO(self.testdata), encoding="ASCII") - txt._CHUNK_SIZE = 4 - - reads = txt.read(4) - reads += txt.read(4) - reads += txt.readline() - reads += txt.readline() - reads += txt.readline() - self.assertEqual(reads, self.normalized) - - def test_issue1395_4(self): - txt = io.TextIOWrapper(io.BytesIO(self.testdata), encoding="ASCII") - txt._CHUNK_SIZE = 4 - - reads = txt.read(4) - reads += txt.read() - self.assertEqual(reads, self.normalized) - - def test_issue1395_5(self): - txt = io.TextIOWrapper(io.BytesIO(self.testdata), encoding="ASCII") - txt._CHUNK_SIZE = 4 - - reads = txt.read(4) - pos = txt.tell() - txt.seek(0) - txt.seek(pos) - self.assertEqual(txt.read(4), "BBB\n") - - - -def test_main(): - support.run_unittest( - TextIOWrapperTest) if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py index 30b21bf62cb1..f8372e32e611 100644 --- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@ -3,6 +3,7 @@ import pickle import pickletools import random +import struct import sys import unittest import weakref @@ -20,8 +21,6 @@ # kind of outer loop. protocols = range(pickle.HIGHEST_PROTOCOL + 1) -ascii_char_size = 1 - # Return True if opcode code appears in the pickle, else False. def opcode_in_pickle(code, pickle): @@ -145,21 +144,22 @@ def create_dynamic_class(name, bases): # the object returned by create_data(). DATA0 = ( - b'(lp0\nL0L\naL1L\naF2.0\nac' - b'builtins\ncomplex\n' - b'p1\n(F3.0\nF0.0\ntp2\nRp' - b'3\naL1L\naL-1L\naL255L\naL-' - b'255L\naL-256L\naL65535L\na' - b'L-65535L\naL-65536L\naL2' - b'147483647L\naL-2147483' - b'647L\naL-2147483648L\na(' - b'Vabc\np4\ng4\nccopyreg' - b'\n_reconstructor\np5\n(' - b'c__main__\nC\np6\ncbu' - b'iltins\nobject\np7\nNt' - b'p8\nRp9\n(dp10\nVfoo\np1' - b'1\nL1L\nsVbar\np12\nL2L\nsb' - b'g9\ntp13\nag13\naL5L\na.' + b'(lp0\nL0L\naL1L\naF2.0\n' + b'ac__builtin__\ncomple' + b'x\np1\n(F3.0\nF0.0\ntp2\n' + b'Rp3\naL1L\naL-1L\naL255' + b'L\naL-255L\naL-256L\naL' + b'65535L\naL-65535L\naL-' + b'65536L\naL2147483647L' + b'\naL-2147483647L\naL-2' + b'147483648L\na(Vabc\np4' + b'\ng4\nccopy_reg\n_recon' + b'structor\np5\n(c__main' + b'__\nC\np6\nc__builtin__' + b'\nobject\np7\nNtp8\nRp9\n' + b'(dp10\nVfoo\np11\nL1L\ns' + b'Vbar\np12\nL2L\nsbg9\ntp' + b'13\nag13\naL5L\na.' ) # Disassembly of DATA0 @@ -173,88 +173,88 @@ def create_dynamic_class(name, bases): 14: a APPEND 15: F FLOAT 2.0 20: a APPEND - 21: c GLOBAL 'builtins complex' - 39: p PUT 1 - 42: ( MARK - 43: F FLOAT 3.0 - 48: F FLOAT 0.0 - 53: t TUPLE (MARK at 42) - 54: p PUT 2 - 57: R REDUCE - 58: p PUT 3 - 61: a APPEND - 62: L LONG 1 - 66: a APPEND - 67: L LONG -1 - 72: a APPEND - 73: L LONG 255 - 79: a APPEND - 80: L LONG -255 - 87: a APPEND - 88: L LONG -256 - 95: a APPEND - 96: L LONG 65535 - 104: a APPEND - 105: L LONG -65535 - 114: a APPEND - 115: L LONG -65536 - 124: a APPEND - 125: L LONG 2147483647 - 138: a APPEND - 139: L LONG -2147483647 - 153: a APPEND - 154: L LONG -2147483648 - 168: a APPEND - 169: ( MARK - 170: V UNICODE 'abc' - 175: p PUT 4 - 178: g GET 4 - 181: c GLOBAL 'copyreg _reconstructor' - 205: p PUT 5 - 208: ( MARK - 209: c GLOBAL '__main__ C' - 221: p PUT 6 - 224: c GLOBAL 'builtins object' - 241: p PUT 7 - 244: N NONE - 245: t TUPLE (MARK at 208) - 246: p PUT 8 - 249: R REDUCE - 250: p PUT 9 - 253: ( MARK - 254: d DICT (MARK at 253) - 255: p PUT 10 - 259: V UNICODE 'foo' - 264: p PUT 11 - 268: L LONG 1 - 272: s SETITEM - 273: V UNICODE 'bar' - 278: p PUT 12 - 282: L LONG 2 - 286: s SETITEM - 287: b BUILD - 288: g GET 9 - 291: t TUPLE (MARK at 169) - 292: p PUT 13 - 296: a APPEND - 297: g GET 13 - 301: a APPEND - 302: L LONG 5 - 306: a APPEND - 307: . STOP + 21: c GLOBAL '__builtin__ complex' + 42: p PUT 1 + 45: ( MARK + 46: F FLOAT 3.0 + 51: F FLOAT 0.0 + 56: t TUPLE (MARK at 45) + 57: p PUT 2 + 60: R REDUCE + 61: p PUT 3 + 64: a APPEND + 65: L LONG 1 + 69: a APPEND + 70: L LONG -1 + 75: a APPEND + 76: L LONG 255 + 82: a APPEND + 83: L LONG -255 + 90: a APPEND + 91: L LONG -256 + 98: a APPEND + 99: L LONG 65535 + 107: a APPEND + 108: L LONG -65535 + 117: a APPEND + 118: L LONG -65536 + 127: a APPEND + 128: L LONG 2147483647 + 141: a APPEND + 142: L LONG -2147483647 + 156: a APPEND + 157: L LONG -2147483648 + 171: a APPEND + 172: ( MARK + 173: V UNICODE 'abc' + 178: p PUT 4 + 181: g GET 4 + 184: c GLOBAL 'copy_reg _reconstructor' + 209: p PUT 5 + 212: ( MARK + 213: c GLOBAL '__main__ C' + 225: p PUT 6 + 228: c GLOBAL '__builtin__ object' + 248: p PUT 7 + 251: N NONE + 252: t TUPLE (MARK at 212) + 253: p PUT 8 + 256: R REDUCE + 257: p PUT 9 + 260: ( MARK + 261: d DICT (MARK at 260) + 262: p PUT 10 + 266: V UNICODE 'foo' + 271: p PUT 11 + 275: L LONG 1 + 279: s SETITEM + 280: V UNICODE 'bar' + 285: p PUT 12 + 289: L LONG 2 + 293: s SETITEM + 294: b BUILD + 295: g GET 9 + 298: t TUPLE (MARK at 172) + 299: p PUT 13 + 303: a APPEND + 304: g GET 13 + 308: a APPEND + 309: L LONG 5 + 313: a APPEND + 314: . STOP highest protocol among opcodes = 0 """ DATA1 = ( - b']q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c' - b'builtins\ncomplex\nq\x01' + b']q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c__' + b'builtin__\ncomplex\nq\x01' b'(G@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00t' b'q\x02Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xffJ' b'\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff' b'\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00ab' - b'cq\x04h\x04ccopyreg\n_reco' + b'cq\x04h\x04ccopy_reg\n_reco' b'nstructor\nq\x05(c__main' - b'__\nC\nq\x06cbuiltins\n' + b'__\nC\nq\x06c__builtin__\n' b'object\nq\x07Ntq\x08Rq\t}q\n(' b'X\x03\x00\x00\x00fooq\x0bK\x01X\x03\x00\x00\x00bar' b'q\x0cK\x02ubh\ttq\rh\rK\x05e.' @@ -268,66 +268,66 @@ def create_dynamic_class(name, bases): 4: K BININT1 0 6: K BININT1 1 8: G BINFLOAT 2.0 - 17: c GLOBAL 'builtins complex' - 35: q BINPUT 1 - 37: ( MARK - 38: G BINFLOAT 3.0 - 47: G BINFLOAT 0.0 - 56: t TUPLE (MARK at 37) - 57: q BINPUT 2 - 59: R REDUCE - 60: q BINPUT 3 - 62: K BININT1 1 - 64: J BININT -1 - 69: K BININT1 255 - 71: J BININT -255 - 76: J BININT -256 - 81: M BININT2 65535 - 84: J BININT -65535 - 89: J BININT -65536 - 94: J BININT 2147483647 - 99: J BININT -2147483647 - 104: J BININT -2147483648 - 109: ( MARK - 110: X BINUNICODE 'abc' - 118: q BINPUT 4 - 120: h BINGET 4 - 122: c GLOBAL 'copyreg _reconstructor' - 146: q BINPUT 5 - 148: ( MARK - 149: c GLOBAL '__main__ C' - 161: q BINPUT 6 - 163: c GLOBAL 'builtins object' - 180: q BINPUT 7 - 182: N NONE - 183: t TUPLE (MARK at 148) - 184: q BINPUT 8 - 186: R REDUCE - 187: q BINPUT 9 - 189: } EMPTY_DICT - 190: q BINPUT 10 - 192: ( MARK - 193: X BINUNICODE 'foo' - 201: q BINPUT 11 - 203: K BININT1 1 - 205: X BINUNICODE 'bar' - 213: q BINPUT 12 - 215: K BININT1 2 - 217: u SETITEMS (MARK at 192) - 218: b BUILD - 219: h BINGET 9 - 221: t TUPLE (MARK at 109) - 222: q BINPUT 13 - 224: h BINGET 13 - 226: K BININT1 5 - 228: e APPENDS (MARK at 3) - 229: . STOP + 17: c GLOBAL '__builtin__ complex' + 38: q BINPUT 1 + 40: ( MARK + 41: G BINFLOAT 3.0 + 50: G BINFLOAT 0.0 + 59: t TUPLE (MARK at 40) + 60: q BINPUT 2 + 62: R REDUCE + 63: q BINPUT 3 + 65: K BININT1 1 + 67: J BININT -1 + 72: K BININT1 255 + 74: J BININT -255 + 79: J BININT -256 + 84: M BININT2 65535 + 87: J BININT -65535 + 92: J BININT -65536 + 97: J BININT 2147483647 + 102: J BININT -2147483647 + 107: J BININT -2147483648 + 112: ( MARK + 113: X BINUNICODE 'abc' + 121: q BINPUT 4 + 123: h BINGET 4 + 125: c GLOBAL 'copy_reg _reconstructor' + 150: q BINPUT 5 + 152: ( MARK + 153: c GLOBAL '__main__ C' + 165: q BINPUT 6 + 167: c GLOBAL '__builtin__ object' + 187: q BINPUT 7 + 189: N NONE + 190: t TUPLE (MARK at 152) + 191: q BINPUT 8 + 193: R REDUCE + 194: q BINPUT 9 + 196: } EMPTY_DICT + 197: q BINPUT 10 + 199: ( MARK + 200: X BINUNICODE 'foo' + 208: q BINPUT 11 + 210: K BININT1 1 + 212: X BINUNICODE 'bar' + 220: q BINPUT 12 + 222: K BININT1 2 + 224: u SETITEMS (MARK at 199) + 225: b BUILD + 226: h BINGET 9 + 228: t TUPLE (MARK at 112) + 229: q BINPUT 13 + 231: h BINGET 13 + 233: K BININT1 5 + 235: e APPENDS (MARK at 3) + 236: . STOP highest protocol among opcodes = 1 """ DATA2 = ( b'\x80\x02]q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c' - b'builtins\ncomplex\n' + b'__builtin__\ncomplex\n' b'q\x01G@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00' b'\x86q\x02Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xff' b'J\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff' @@ -347,52 +347,52 @@ def create_dynamic_class(name, bases): 6: K BININT1 0 8: K BININT1 1 10: G BINFLOAT 2.0 - 19: c GLOBAL 'builtins complex' - 37: q BINPUT 1 - 39: G BINFLOAT 3.0 - 48: G BINFLOAT 0.0 - 57: \x86 TUPLE2 - 58: q BINPUT 2 - 60: R REDUCE - 61: q BINPUT 3 - 63: K BININT1 1 - 65: J BININT -1 - 70: K BININT1 255 - 72: J BININT -255 - 77: J BININT -256 - 82: M BININT2 65535 - 85: J BININT -65535 - 90: J BININT -65536 - 95: J BININT 2147483647 - 100: J BININT -2147483647 - 105: J BININT -2147483648 - 110: ( MARK - 111: X BINUNICODE 'abc' - 119: q BINPUT 4 - 121: h BINGET 4 - 123: c GLOBAL '__main__ C' - 135: q BINPUT 5 - 137: ) EMPTY_TUPLE - 138: \x81 NEWOBJ - 139: q BINPUT 6 - 141: } EMPTY_DICT - 142: q BINPUT 7 - 144: ( MARK - 145: X BINUNICODE 'foo' - 153: q BINPUT 8 - 155: K BININT1 1 - 157: X BINUNICODE 'bar' - 165: q BINPUT 9 - 167: K BININT1 2 - 169: u SETITEMS (MARK at 144) - 170: b BUILD - 171: h BINGET 6 - 173: t TUPLE (MARK at 110) - 174: q BINPUT 10 - 176: h BINGET 10 - 178: K BININT1 5 - 180: e APPENDS (MARK at 5) - 181: . STOP + 19: c GLOBAL '__builtin__ complex' + 40: q BINPUT 1 + 42: G BINFLOAT 3.0 + 51: G BINFLOAT 0.0 + 60: \x86 TUPLE2 + 61: q BINPUT 2 + 63: R REDUCE + 64: q BINPUT 3 + 66: K BININT1 1 + 68: J BININT -1 + 73: K BININT1 255 + 75: J BININT -255 + 80: J BININT -256 + 85: M BININT2 65535 + 88: J BININT -65535 + 93: J BININT -65536 + 98: J BININT 2147483647 + 103: J BININT -2147483647 + 108: J BININT -2147483648 + 113: ( MARK + 114: X BINUNICODE 'abc' + 122: q BINPUT 4 + 124: h BINGET 4 + 126: c GLOBAL '__main__ C' + 138: q BINPUT 5 + 140: ) EMPTY_TUPLE + 141: \x81 NEWOBJ + 142: q BINPUT 6 + 144: } EMPTY_DICT + 145: q BINPUT 7 + 147: ( MARK + 148: X BINUNICODE 'foo' + 156: q BINPUT 8 + 158: K BININT1 1 + 160: X BINUNICODE 'bar' + 168: q BINPUT 9 + 170: K BININT1 2 + 172: u SETITEMS (MARK at 147) + 173: b BUILD + 174: h BINGET 6 + 176: t TUPLE (MARK at 113) + 177: q BINPUT 10 + 179: h BINGET 10 + 181: K BININT1 5 + 183: e APPENDS (MARK at 5) + 184: . STOP highest protocol among opcodes = 2 """ @@ -571,14 +571,14 @@ def test_load_classic_instance(self): xname = X.__name__.encode('ascii') # Protocol 0 (text mode pickle): """ - 0: ( MARK - 1: i INST '__main__ X' (MARK at 0) - 15: p PUT 0 - 18: ( MARK - 19: d DICT (MARK at 18) - 20: p PUT 1 - 23: b BUILD - 24: . STOP + 0: ( MARK + 1: i INST '__main__ X' (MARK at 0) + 13: p PUT 0 + 16: ( MARK + 17: d DICT (MARK at 16) + 18: p PUT 1 + 21: b BUILD + 22: . STOP """ pickle0 = (b"(i__main__\n" b"X\n" @@ -588,15 +588,15 @@ def test_load_classic_instance(self): # Protocol 1 (binary mode pickle) """ - 0: ( MARK - 1: c GLOBAL '__main__ X' - 15: q BINPUT 0 - 17: o OBJ (MARK at 0) - 18: q BINPUT 1 - 20: } EMPTY_DICT - 21: q BINPUT 2 - 23: b BUILD - 24: . STOP + 0: ( MARK + 1: c GLOBAL '__main__ X' + 13: q BINPUT 0 + 15: o OBJ (MARK at 0) + 16: q BINPUT 1 + 18: } EMPTY_DICT + 19: q BINPUT 2 + 21: b BUILD + 22: . STOP """ pickle1 = (b'(c__main__\n' b'X\n' @@ -605,16 +605,16 @@ def test_load_classic_instance(self): # Protocol 2 (pickle2 = b'\x80\x02' + pickle1) """ - 0: \x80 PROTO 2 - 2: ( MARK - 3: c GLOBAL '__main__ X' - 17: q BINPUT 0 - 19: o OBJ (MARK at 2) - 20: q BINPUT 1 - 22: } EMPTY_DICT - 23: q BINPUT 2 - 25: b BUILD - 26: . STOP + 0: \x80 PROTO 2 + 2: ( MARK + 3: c GLOBAL '__main__ X' + 15: q BINPUT 0 + 17: o OBJ (MARK at 2) + 18: q BINPUT 1 + 20: } EMPTY_DICT + 21: q BINPUT 2 + 23: b BUILD + 24: . STOP """ pickle2 = (b'\x80\x02(c__main__\n' b'X\n' @@ -811,10 +811,18 @@ def test_float_format(self): self.assertEqual(self.dumps(1.2, 0)[0:3], b'F1.') def test_reduce(self): - pass + for proto in protocols: + inst = AAA() + dumped = self.dumps(inst, proto) + loaded = self.loads(dumped) + self.assertEqual(loaded, REDUCE_A) def test_getinitargs(self): - pass + for proto in protocols: + inst = initarg(1, 2) + dumped = self.dumps(inst, proto) + loaded = self.loads(dumped) + self.assert_is_copy(inst, loaded) def test_pop_empty_stack(self): # Test issue7455 @@ -1146,16 +1154,62 @@ def test_set_chunking(self): self.assertGreaterEqual(num_additems, 2) def test_simple_newobj(self): - x = object.__new__(SimpleNewObj) # avoid __init__ + x = SimpleNewObj.__new__(SimpleNewObj, 0xface) # avoid __init__ x.abc = 666 for proto in protocols: - s = self.dumps(x, proto) - self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s), - 2 <= proto < 4) - self.assertEqual(opcode_in_pickle(pickle.NEWOBJ_EX, s), - proto >= 4) - y = self.loads(s) # will raise TypeError if __init__ called - self.assert_is_copy(x, y) + with self.subTest(proto=proto): + s = self.dumps(x, proto) + if proto < 1: + self.assertIn(b'\nL64206', s) # LONG + else: + self.assertIn(b'M\xce\xfa', s) # BININT2 + self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s), + 2 <= proto) + self.assertFalse(opcode_in_pickle(pickle.NEWOBJ_EX, s)) + y = self.loads(s) # will raise TypeError if __init__ called + self.assert_is_copy(x, y) + + def test_complex_newobj(self): + x = ComplexNewObj.__new__(ComplexNewObj, 0xface) # avoid __init__ + x.abc = 666 + for proto in protocols: + with self.subTest(proto=proto): + s = self.dumps(x, proto) + if proto < 1: + self.assertIn(b'\nL64206', s) # LONG + elif proto < 2: + self.assertIn(b'M\xce\xfa', s) # BININT2 + elif proto < 4: + self.assertIn(b'X\x04\x00\x00\x00FACE', s) # BINUNICODE + else: + self.assertIn(b'\x8c\x04FACE', s) # SHORT_BINUNICODE + self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s), + 2 <= proto) + self.assertFalse(opcode_in_pickle(pickle.NEWOBJ_EX, s)) + y = self.loads(s) # will raise TypeError if __init__ called + self.assert_is_copy(x, y) + + def test_complex_newobj_ex(self): + x = ComplexNewObjEx.__new__(ComplexNewObjEx, 0xface) # avoid __init__ + x.abc = 666 + for proto in protocols: + with self.subTest(proto=proto): + if 2 <= proto < 4: + self.assertRaises(ValueError, self.dumps, x, proto) + continue + s = self.dumps(x, proto) + if proto < 1: + self.assertIn(b'\nL64206', s) # LONG + elif proto < 2: + self.assertIn(b'M\xce\xfa', s) # BININT2 + else: + assert proto >= 4 + self.assertIn(b'\x8c\x04FACE', s) # SHORT_BINUNICODE + self.assertFalse(opcode_in_pickle(pickle.NEWOBJ, s)) + self.assertEqual(opcode_in_pickle(pickle.NEWOBJ_EX, s), + 4 <= proto) + y = self.loads(s) # will raise TypeError if __init__ called + self.assert_is_copy(x, y) def test_newobj_list_slots(self): x = SlotList([1, 2, 3]) @@ -1277,7 +1331,7 @@ def test_unpickle_from_2x(self): loaded = self.loads(DATA5) self.assertEqual(type(loaded), SimpleCookie) self.assertEqual(list(loaded.keys()), ["key"]) - self.assertEqual(loaded["key"].value, "Set-Cookie: key=value") + self.assertEqual(loaded["key"].value, "value") for (exc, data) in DATA7.items(): loaded = self.loads(data) @@ -1304,6 +1358,35 @@ def test_pickle_to_2x(self): dumped = self.dumps(set([3]), 2) self.assertEqual(dumped, DATA6) + def test_load_python2_str_as_bytes(self): + # From Python 2: pickle.dumps('a\x00\xa0', protocol=0) + self.assertEqual(self.loads(b"S'a\\x00\\xa0'\n.", + encoding="bytes"), b'a\x00\xa0') + # From Python 2: pickle.dumps('a\x00\xa0', protocol=1) + self.assertEqual(self.loads(b'U\x03a\x00\xa0.', + encoding="bytes"), b'a\x00\xa0') + # From Python 2: pickle.dumps('a\x00\xa0', protocol=2) + self.assertEqual(self.loads(b'\x80\x02U\x03a\x00\xa0.', + encoding="bytes"), b'a\x00\xa0') + + def test_load_python2_unicode_as_str(self): + # From Python 2: pickle.dumps(u'Ï€', protocol=0) + self.assertEqual(self.loads(b'V\\u03c0\n.', + encoding='bytes'), 'Ï€') + # From Python 2: pickle.dumps(u'Ï€', protocol=1) + self.assertEqual(self.loads(b'X\x02\x00\x00\x00\xcf\x80.', + encoding="bytes"), 'Ï€') + # From Python 2: pickle.dumps(u'Ï€', protocol=2) + self.assertEqual(self.loads(b'\x80\x02X\x02\x00\x00\x00\xcf\x80.', + encoding="bytes"), 'Ï€') + + def test_load_long_python2_str_as_bytes(self): + # From Python 2: pickle.dumps('x' * 300, protocol=1) + self.assertEqual(self.loads(pickle.BINSTRING + + struct.pack("<I", 300) + + b'x' * 300 + pickle.STOP, + encoding='bytes'), b'x' * 300) + def test_large_pickles(self): # Test the correctness of internal buffering routines when handling # large data. @@ -1416,6 +1499,26 @@ def test_setitems_on_non_dicts(self): FRAME_SIZE_TARGET = 64 * 1024 + def check_frame_opcodes(self, pickled): + """ + Check the arguments of FRAME opcodes in a protocol 4+ pickle. + """ + frame_opcode_size = 9 + last_arg = last_pos = None + for op, arg, pos in pickletools.genops(pickled): + if op.name != 'FRAME': + continue + if last_pos is not None: + # The previous frame's size should be equal to the number + # of bytes up to the current frame. + frame_size = pos - last_pos - frame_opcode_size + self.assertEqual(frame_size, last_arg) + last_arg, last_pos = arg, pos + # The last frame's size should be equal to the number of bytes up + # to the pickle's end. + frame_size = len(pickled) - last_pos - frame_opcode_size + self.assertEqual(frame_size, last_arg) + def test_framing_many_objects(self): obj = list(range(10**5)) for proto in range(4, pickle.HIGHEST_PROTOCOL + 1): @@ -1429,6 +1532,7 @@ def test_framing_many_objects(self): self.FRAME_SIZE_TARGET / 2) self.assertLessEqual(bytes_per_frame, self.FRAME_SIZE_TARGET * 1) + self.check_frame_opcodes(pickled) def test_framing_large_objects(self): N = 1024 * 1024 @@ -1440,6 +1544,7 @@ def test_framing_large_objects(self): self.assertEqual(obj, unpickled) n_frames = count_opcode(pickle.FRAME, pickled) self.assertGreaterEqual(n_frames, len(obj)) + self.check_frame_opcodes(pickled) def test_optional_frames(self): if pickle.HIGHEST_PROTOCOL < 4: @@ -1480,6 +1585,14 @@ def remove_frames(pickled, keep_frame=None): count_opcode(pickle.FRAME, pickled)) self.assertEqual(obj, self.loads(some_frames_pickle)) + def test_frame_readline(self): + pickled = b'\x80\x04\x95\x05\x00\x00\x00\x00\x00\x00\x00I42\n.' + # 0: \x80 PROTO 4 + # 2: \x95 FRAME 5 + # 11: I INT 42 + # 15: . STOP + self.assertEqual(self.loads(pickled), 42) + def test_nested_names(self): global Nested class Nested: @@ -1543,7 +1656,6 @@ def pie(self): unpickled = self.loads(self.dumps(method, proto)) self.assertEqual(method(obj), unpickled(obj)) - def test_c_methods(self): global Subclass class Subclass(tuple): @@ -1579,19 +1691,40 @@ class Nested(str): unpickled = self.loads(self.dumps(method, proto)) self.assertEqual(method(*args), unpickled(*args)) + def test_local_lookup_error(self): + # Test that whichmodule() errors out cleanly when looking up + # an assumed globally-reachable object fails. + def f(): + pass + # Since the function is local, lookup will fail + for proto in range(0, pickle.HIGHEST_PROTOCOL + 1): + with self.assertRaises((AttributeError, pickle.PicklingError)): + pickletools.dis(self.dumps(f, proto)) + # Same without a __module__ attribute (exercises a different path + # in _pickle.c). + del f.__module__ + for proto in range(0, pickle.HIGHEST_PROTOCOL + 1): + with self.assertRaises((AttributeError, pickle.PicklingError)): + pickletools.dis(self.dumps(f, proto)) + # Yet a different path. + f.__name__ = f.__qualname__ + for proto in range(0, pickle.HIGHEST_PROTOCOL + 1): + with self.assertRaises((AttributeError, pickle.PicklingError)): + pickletools.dis(self.dumps(f, proto)) + class BigmemPickleTests(unittest.TestCase): # Binary protocols can serialize longs of up to 2GB-1 - @bigmemtest(size=_2G, memuse=1 + 1, dry_run=False) + @bigmemtest(size=_2G, memuse=3.6, dry_run=False) def test_huge_long_32b(self, size): data = 1 << (8 * size) try: for proto in protocols: + if proto < 2: + continue with self.subTest(proto=proto): - if proto < 2: - continue with self.assertRaises((ValueError, OverflowError)): self.dumps(data, protocol=proto) finally: @@ -1601,49 +1734,75 @@ def test_huge_long_32b(self, size): # (older protocols don't have a dedicated opcode for bytes and are # too inefficient) - @bigmemtest(size=_2G, memuse=1 + 1, dry_run=False) + @bigmemtest(size=_2G, memuse=2.5, dry_run=False) def test_huge_bytes_32b(self, size): data = b"abcd" * (size // 4) try: for proto in protocols: + if proto < 3: + continue with self.subTest(proto=proto): - if proto < 3: - continue try: pickled = self.dumps(data, protocol=proto) - self.assertTrue(b"abcd" in pickled[:19]) - self.assertTrue(b"abcd" in pickled[-18:]) + header = (pickle.BINBYTES + + struct.pack("<I", len(data))) + data_start = pickled.index(data) + self.assertEqual( + header, + pickled[data_start-len(header):data_start]) finally: pickled = None finally: data = None - @bigmemtest(size=_4G, memuse=1 + 1, dry_run=False) + @bigmemtest(size=_4G, memuse=2.5, dry_run=False) def test_huge_bytes_64b(self, size): - data = b"a" * size + data = b"acbd" * (size // 4) try: for proto in protocols: + if proto < 3: + continue with self.subTest(proto=proto): - if proto < 3: + if proto == 3: + # Protocol 3 does not support large bytes objects. + # Verify that we do not crash when processing one. + with self.assertRaises((ValueError, OverflowError)): + self.dumps(data, protocol=proto) continue - with self.assertRaises((ValueError, OverflowError)): - self.dumps(data, protocol=proto) + try: + pickled = self.dumps(data, protocol=proto) + header = (pickle.BINBYTES8 + + struct.pack("<Q", len(data))) + data_start = pickled.index(data) + self.assertEqual( + header, + pickled[data_start-len(header):data_start]) + finally: + pickled = None finally: data = None # All protocols use 1-byte per printable ASCII character; we add another # byte because the encoded form has to be copied into the internal buffer. - @bigmemtest(size=_2G, memuse=2 + ascii_char_size, dry_run=False) + @bigmemtest(size=_2G, memuse=8, dry_run=False) def test_huge_str_32b(self, size): data = "abcd" * (size // 4) try: for proto in protocols: + if proto == 0: + continue with self.subTest(proto=proto): try: pickled = self.dumps(data, protocol=proto) - self.assertTrue(b"abcd" in pickled[:19]) - self.assertTrue(b"abcd" in pickled[-18:]) + header = (pickle.BINUNICODE + + struct.pack("<I", len(data))) + data_start = pickled.index(b'abcd') + self.assertEqual( + header, + pickled[data_start-len(header):data_start]) + self.assertEqual((pickled.rindex(b"abcd") + len(b"abcd") - + pickled.index(b"abcd")), len(data)) finally: pickled = None finally: @@ -1653,24 +1812,30 @@ def test_huge_str_32b(self, size): # of utf-8 encoded unicode. BINUNICODE8 (protocol 4) supports these huge # unicode strings however. - @bigmemtest(size=_4G, memuse=2 + ascii_char_size, dry_run=False) + @bigmemtest(size=_4G, memuse=8, dry_run=False) def test_huge_str_64b(self, size): data = "abcd" * (size // 4) try: for proto in protocols: + if proto == 0: + continue with self.subTest(proto=proto): - if proto == 0: - continue if proto < 4: with self.assertRaises((ValueError, OverflowError)): self.dumps(data, protocol=proto) - else: - try: - pickled = self.dumps(data, protocol=proto) - self.assertTrue(b"abcd" in pickled[:19]) - self.assertTrue(b"abcd" in pickled[-18:]) - finally: - pickled = None + continue + try: + pickled = self.dumps(data, protocol=proto) + header = (pickle.BINUNICODE8 + + struct.pack("<Q", len(data))) + data_start = pickled.index(b'abcd') + self.assertEqual( + header, + pickled[data_start-len(header):data_start]) + self.assertEqual((pickled.rindex(b"abcd") + len(b"abcd") - + pickled.index(b"abcd")), len(data)) + finally: + pickled = None finally: data = None @@ -1781,12 +1946,20 @@ class MyFrozenSet(frozenset): class SlotList(MyList): __slots__ = ["foo"] -class SimpleNewObj(object): - def __init__(self, a, b, c): +class SimpleNewObj(int): + def __init__(self, *args, **kwargs): # raise an error, to make sure this isn't called raise TypeError("SimpleNewObj.__init__() didn't expect to get called") def __eq__(self, other): - return self.__dict__ == other.__dict__ + return int(self) == int(other) and self.__dict__ == other.__dict__ + +class ComplexNewObj(SimpleNewObj): + def __getnewargs__(self): + return ('%X' % self, 16) + +class ComplexNewObjEx(SimpleNewObj): + def __getnewargs_ex__(self): + return ('%X' % self,), {'base': 16} class BadGetattr: def __getattr__(self, key): diff --git a/Lib/test/pydoc_mod.py b/Lib/test/pydoc_mod.py index f86b5c621e34..cda1c9e23131 100644 --- a/Lib/test/pydoc_mod.py +++ b/Lib/test/pydoc_mod.py @@ -15,6 +15,16 @@ class B(object): NO_MEANING = "eggs" pass +class C(object): + def say_no(self): + return "no" + def get_answer(self): + """ Return say_no() """ + return self.say_no() + def is_it_true(self): + """ Return self.get_answer() """ + return self.get_answer() + def doc_func(): """ This function solves all of the world's problems: diff --git a/Lib/test/pystone.py b/Lib/test/pystone.py index d7f1ec9b6cc7..1f67e66e3f16 100755 --- a/Lib/test/pystone.py +++ b/Lib/test/pystone.py @@ -3,7 +3,7 @@ """ "PYSTONE" Benchmark Program -Version: Python/1.1 (corresponds to C/1.1 plus 2 Pystone fixes) +Version: Python/1.2 (corresponds to C/1.1 plus 3 Pystone fixes) Author: Reinhold P. Weicker, CACM Vol 27, No 10, 10/84 pg. 1013. @@ -30,13 +30,20 @@ percent faster than version 1.0, so benchmark figures of different versions can't be compared directly. + Version 1.2 changes the division to floor division. + + Under Python 3 version 1.1 would use the normal division + operator, resulting in some of the operations mistakenly + yielding floats. Version 1.2 instead uses floor division + making the benchmark a integer benchmark again. + """ LOOPS = 50000 -from time import clock +from time import time -__version__ = "1.1" +__version__ = "1.2" [Ident1, Ident2, Ident3, Ident4, Ident5] = range(1, 6) @@ -86,10 +93,10 @@ def Proc0(loops=LOOPS): global PtrGlb global PtrGlbNext - starttime = clock() + starttime = time() for i in range(loops): pass - nulltime = clock() - starttime + nulltime = time() - starttime PtrGlbNext = Record() PtrGlb = Record() @@ -101,7 +108,7 @@ def Proc0(loops=LOOPS): String1Loc = "DHRYSTONE PROGRAM, 1'ST STRING" Array2Glob[8][7] = 10 - starttime = clock() + starttime = time() for i in range(loops): Proc5() @@ -123,11 +130,11 @@ def Proc0(loops=LOOPS): EnumLoc = Proc6(Ident1) CharIndex = chr(ord(CharIndex)+1) IntLoc3 = IntLoc2 * IntLoc1 - IntLoc2 = IntLoc3 / IntLoc1 + IntLoc2 = IntLoc3 // IntLoc1 IntLoc2 = 7 * (IntLoc3 - IntLoc2) - IntLoc1 IntLoc1 = Proc2(IntLoc1) - benchtime = clock() - starttime - nulltime + benchtime = time() - starttime - nulltime if benchtime == 0.0: loopsPerBenchtime = 0.0 else: diff --git a/Lib/test/re_tests.py b/Lib/test/re_tests.py index 5d16e3d183c7..7f8075ec1485 100755 --- a/Lib/test/re_tests.py +++ b/Lib/test/re_tests.py @@ -86,7 +86,7 @@ (r'\a[\b]\f\n\r\t\v', '\a\b\f\n\r\t\v', SUCCEED, 'found', '\a\b\f\n\r\t\v'), (r'[\a][\b][\f][\n][\r][\t][\v]', '\a\b\f\n\r\t\v', SUCCEED, 'found', '\a\b\f\n\r\t\v'), # NOTE: not an error under PCRE/PRE: - # (r'\u', '', SYNTAX_ERROR), # A Perl escape + (r'\u', '', SYNTAX_ERROR), # A Perl escape (r'\c\e\g\h\i\j\k\m\o\p\q\y\z', 'ceghijkmopqyz', SUCCEED, 'found', 'ceghijkmopqyz'), (r'\xff', '\377', SUCCEED, 'found', chr(255)), # new \x semantics diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py index c1c831ff867c..ea1287ddde9b 100755 --- a/Lib/test/regrtest.py +++ b/Lib/test/regrtest.py @@ -1273,8 +1273,14 @@ def runtest_inner(test, verbose, quiet, # tests. If not, use normal unittest test loading. test_runner = getattr(the_module, "test_main", None) if test_runner is None: - tests = unittest.TestLoader().loadTestsFromModule(the_module) - test_runner = lambda: support.run_unittest(tests) + def test_runner(): + loader = unittest.TestLoader() + tests = loader.loadTestsFromModule(the_module) + for error in loader.errors: + print(error, file=sys.stderr) + if loader.errors: + raise Exception("errors while loading tests") + support.run_unittest(tests) test_runner() if huntrleaks: refleak = dash_R(the_module, test, test_runner, huntrleaks) diff --git a/Lib/test/script_helper.py b/Lib/test/script_helper.py index 4d5c1f120adf..5531a34b622a 100644 --- a/Lib/test/script_helper.py +++ b/Lib/test/script_helper.py @@ -15,18 +15,54 @@ from importlib.util import source_from_cache from test.support import make_legacy_pyc, strip_python_stderr, temp_dir + +# Cached result of the expensive test performed in the function below. +__cached_interp_requires_environment = None + +def interpreter_requires_environment(): + """ + Returns True if our sys.executable interpreter requires environment + variables in order to be able to run at all. + + This is designed to be used with @unittest.skipIf() to annotate tests + that need to use an assert_python*() function to launch an isolated + mode (-I) or no environment mode (-E) sub-interpreter process. + + A normal build & test does not run into this situation but it can happen + when trying to run the standard library test suite from an interpreter that + doesn't have an obvious home with Python's current home finding logic. + + Setting PYTHONHOME is one way to get most of the testsuite to run in that + situation. PYTHONPATH or PYTHONUSERSITE are other common envirnonment + variables that might impact whether or not the interpreter can start. + """ + global __cached_interp_requires_environment + if __cached_interp_requires_environment is None: + # Try running an interpreter with -E to see if it works or not. + try: + subprocess.check_call([sys.executable, '-E', + '-c', 'import sys; sys.exit(0)']) + except subprocess.CalledProcessError: + __cached_interp_requires_environment = True + else: + __cached_interp_requires_environment = False + + return __cached_interp_requires_environment + + # Executing the interpreter in a subprocess def _assert_python(expected_success, *args, **env_vars): + env_required = interpreter_requires_environment() if '__isolated' in env_vars: isolated = env_vars.pop('__isolated') else: - isolated = not env_vars + isolated = not env_vars and not env_required cmd_line = [sys.executable, '-X', 'faulthandler'] if isolated: # isolated mode: ignore Python environment variables, ignore user # site-packages, and don't add the current directory to sys.path cmd_line.append('-I') - elif not 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 @@ -51,8 +87,9 @@ def _assert_python(expected_success, *args, **env_vars): err = strip_python_stderr(err) if (rc and expected_success) or (not rc and not expected_success): raise AssertionError( - "Process return code is %d, " - "stderr follows:\n%s" % (rc, err.decode('ascii', 'ignore'))) + "Process return code is %d, command line was: %r, " + "stderr follows:\n%s" % (rc, cmd_line, + err.decode('ascii', 'ignore'))) return rc, out, err def assert_python_ok(*args, **env_vars): @@ -78,7 +115,7 @@ def assert_python_failure(*args, **env_vars): """ return _assert_python(False, *args, **env_vars) -def spawn_python(*args, **kw): +def spawn_python(*args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, **kw): """Run a Python subprocess with the given arguments. kw is extra keyword args to pass to subprocess.Popen. Returns a Popen @@ -86,8 +123,16 @@ def spawn_python(*args, **kw): """ cmd_line = [sys.executable, '-E'] cmd_line.extend(args) + # Under Fedora (?), GNU readline can output junk on stderr when initialized, + # depending on the TERM setting. Setting TERM=vt100 is supposed to disable + # that. References: + # - http://reinout.vanrees.org/weblog/2009/08/14/readline-invisible-character-hack.html + # - http://stackoverflow.com/questions/15760712/python-readline-module-prints-escape-character-during-import + # - http://lists.gnu.org/archive/html/bug-readline/2007-08/msg00004.html + env = kw.setdefault('env', dict(os.environ)) + env['TERM'] = 'vt100' return subprocess.Popen(cmd_line, stdin=subprocess.PIPE, - stdout=subprocess.PIPE, stderr=subprocess.STDOUT, + stdout=stdout, stderr=stderr, **kw) def kill_python(p): @@ -101,8 +146,10 @@ def kill_python(p): subprocess._cleanup() return data -def make_script(script_dir, script_basename, source): - script_filename = script_basename+os.extsep+'py' +def make_script(script_dir, script_basename, source, omit_suffix=False): + script_filename = script_basename + if not omit_suffix: + script_filename += os.extsep + 'py' script_name = os.path.join(script_dir, script_filename) # The script should be encoded to UTF-8, the default string encoding script_file = open(script_name, 'w', encoding='utf-8') @@ -145,8 +192,8 @@ def make_zip_pkg(zip_dir, zip_basename, pkg_name, script_basename, script_name = make_script(zip_dir, script_basename, source) unlink.append(script_name) if compiled: - init_name = py_compile(init_name, doraise=True) - script_name = py_compile(script_name, doraise=True) + init_name = py_compile.compile(init_name, doraise=True) + script_name = py_compile.compile(script_name, doraise=True) unlink.extend((init_name, script_name)) pkg_names = [os.sep.join([pkg_name]*i) for i in range(1, depth+1)] script_name_in_zip = os.path.join(pkg_names[-1], os.path.basename(script_name)) diff --git a/Lib/test/selfsigned_pythontestdotnet.pem b/Lib/test/selfsigned_pythontestdotnet.pem new file mode 100644 index 000000000000..9a80073a5ba0 --- /dev/null +++ b/Lib/test/selfsigned_pythontestdotnet.pem @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIIChzCCAfCgAwIBAgIJAKGU95wKR8pSMA0GCSqGSIb3DQEBBQUAMHAxCzAJBgNV +BAYTAlhZMRcwFQYDVQQHDA5DYXN0bGUgQW50aHJheDEjMCEGA1UECgwaUHl0aG9u +IFNvZnR3YXJlIEZvdW5kYXRpb24xIzAhBgNVBAMMGnNlbGYtc2lnbmVkLnB5dGhv +bnRlc3QubmV0MB4XDTE0MTEwMjE4MDkyOVoXDTI0MTAzMDE4MDkyOVowcDELMAkG +A1UEBhMCWFkxFzAVBgNVBAcMDkNhc3RsZSBBbnRocmF4MSMwIQYDVQQKDBpQeXRo +b24gU29mdHdhcmUgRm91bmRhdGlvbjEjMCEGA1UEAwwac2VsZi1zaWduZWQucHl0 +aG9udGVzdC5uZXQwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANDXQXW9tjyZ +Xt0Iv2tLL1+jinr4wGg36ioLDLFkMf+2Y1GL0v0BnKYG4N1OKlAU15LXGeGer8vm +Sv/yIvmdrELvhAbbo3w4a9TMYQA4XkIVLdvu3mvNOAet+8PMJxn26dbDhG809ALv +EHY57lQsBS3G59RZyBPVqAqmImWNJnVzAgMBAAGjKTAnMCUGA1UdEQQeMByCGnNl +bGYtc2lnbmVkLnB5dGhvbnRlc3QubmV0MA0GCSqGSIb3DQEBBQUAA4GBAIOXmdtM +eG9qzP9TiXW/Gc/zI4cBfdCpC+Y4gOfC9bQUC7hefix4iO3+iZjgy3X/FaRxUUoV +HKiXcXIaWqTSUWp45cSh0MbwZXudp6JIAptzdAhvvCrPKeC9i9GvxsPD4LtDAL97 +vSaxQBezA7hdxZd90/EeyMgVZgAnTCnvAWX9 +-----END CERTIFICATE----- diff --git a/Lib/test/seq_tests.py b/Lib/test/seq_tests.py index f185a8251c2f..9834af118a5c 100644 --- a/Lib/test/seq_tests.py +++ b/Lib/test/seq_tests.py @@ -392,6 +392,7 @@ def __eq__(self, other): def test_pickle(self): lst = self.type2test([4, 5, 6, 7]) - lst2 = pickle.loads(pickle.dumps(lst)) - self.assertEqual(lst2, lst) - self.assertNotEqual(id(lst2), id(lst)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + lst2 = pickle.loads(pickle.dumps(lst, proto)) + self.assertEqual(lst2, lst) + self.assertNotEqual(id(lst2), id(lst)) diff --git a/Lib/test/ssl_servers.py b/Lib/test/ssl_servers.py index 759b3f487e32..f9d30cf0bd73 100644 --- a/Lib/test/ssl_servers.py +++ b/Lib/test/ssl_servers.py @@ -150,7 +150,7 @@ def stop(self): def make_https_server(case, *, context=None, certfile=CERTFILE, host=HOST, handler_class=None): if context is None: - context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) + context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) # We assume the certfile contains both private key and certificate context.load_cert_chain(certfile) server = HTTPSServerThread(context, host, handler_class) @@ -182,6 +182,8 @@ def cleanup(): parser.add_argument('--curve-name', dest='curve_name', type=str, action='store', help='curve name for EC-based Diffie-Hellman') + parser.add_argument('--ciphers', dest='ciphers', type=str, + help='allowed cipher list') parser.add_argument('--dh', dest='dh_file', type=str, action='store', help='PEM file containing DH parameters') args = parser.parse_args() @@ -192,12 +194,14 @@ def cleanup(): else: handler_class = RootedHTTPRequestHandler handler_class.root = os.getcwd() - context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) + context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) context.load_cert_chain(CERTFILE) if args.curve_name: context.set_ecdh_curve(args.curve_name) if args.dh_file: context.load_dh_params(args.dh_file) + if args.ciphers: + context.set_ciphers(args.ciphers) server = HTTPSServer(("", args.port), handler_class, context) if args.verbose: diff --git a/Lib/test/ssltests.py b/Lib/test/ssltests.py new file mode 100644 index 000000000000..9b0ed22b9565 --- /dev/null +++ b/Lib/test/ssltests.py @@ -0,0 +1,22 @@ +# Convenience test module to run all of the SSL-related tests in the +# standard library. + +import sys +import subprocess + +TESTS = ['test_asyncio', 'test_ftplib', 'test_hashlib', 'test_httplib', + 'test_imaplib', 'test_nntplib', 'test_poplib', 'test_smtplib', + 'test_smtpnet', 'test_urllib2_localnet', 'test_venv'] + +def run_regrtests(*extra_args): + args = [sys.executable, "-m", "test"] + if not extra_args: + args.append("-unetwork") + else: + args.extend(extra_args) + args.extend(TESTS) + result = subprocess.call(args) + sys.exit(result) + +if __name__ == '__main__': + run_regrtests(*sys.argv[1:]) diff --git a/Lib/test/string_tests.py b/Lib/test/string_tests.py index 30784d4ec5b3..6e26474a3b3d 100644 --- a/Lib/test/string_tests.py +++ b/Lib/test/string_tests.py @@ -1,11 +1,10 @@ """ -Common tests shared by test_str, test_unicode, test_userstring and test_string. +Common tests shared by test_unicode, test_userstring and test_string. """ import unittest, string, sys, struct from test import support from collections import UserList -import _testcapi class Sequence: def __init__(self, seq='wxyz'): self.seq = seq @@ -80,11 +79,9 @@ class subtype(self.__class__.type2test): def checkraises(self, exc, obj, methodname, *args): obj = self.fixtype(obj) args = self.fixtype(args) - self.assertRaises( - exc, - getattr(obj, methodname), - *args - ) + with self.assertRaises(exc) as cm: + getattr(obj, methodname)(*args) + self.assertNotEqual(str(cm.exception), '') # call obj.method(*args) without any checks def checkcall(self, obj, methodname, *args): @@ -676,10 +673,10 @@ def test_replace(self): self.checkraises(TypeError, 'hello', 'replace', 42, 'h') self.checkraises(TypeError, 'hello', 'replace', 'h', 42) + @unittest.skipIf(sys.maxsize > (1 << 32) or struct.calcsize('P') != 4, + 'only applies to 32-bit platforms') def test_replace_overflow(self): # Check for overflow checking on 32 bit machines - if sys.maxsize != 2147483647 or struct.calcsize("P") > 4: - return A2_16 = "A" * (2**16) self.checkraises(OverflowError, A2_16, "replace", "", A2_16) self.checkraises(OverflowError, A2_16, "replace", "A", A2_16) @@ -1120,8 +1117,7 @@ def test_mul(self): def test_join(self): # join now works with any sequence type # moved here, because the argument order is - # different in string.join (see the test in - # test.test_string.StringTest.test_join) + # different in string.join self.checkequal('a b c d', ' ', 'join', ['a', 'b', 'c', 'd']) self.checkequal('abcd', '', 'join', ('a', 'b', 'c', 'd')) self.checkequal('bd', '', 'join', ('', 'b', '', 'd')) @@ -1141,6 +1137,7 @@ def test_join(self): self.checkequal('a b c', ' ', 'join', BadSeq2()) self.checkraises(TypeError, ' ', 'join') + self.checkraises(TypeError, ' ', 'join', None) self.checkraises(TypeError, ' ', 'join', 7) self.checkraises(TypeError, ' ', 'join', [1, 2, bytes()]) try: @@ -1198,19 +1195,27 @@ def test_formatting(self): # Outrageously large width or precision should raise ValueError. self.checkraises(ValueError, '%%%df' % (2**64), '__mod__', (3.2)) self.checkraises(ValueError, '%%.%df' % (2**64), '__mod__', (3.2)) + self.checkraises(OverflowError, '%*s', '__mod__', + (sys.maxsize + 1, '')) + self.checkraises(OverflowError, '%.*f', '__mod__', + (sys.maxsize + 1, 1. / 7)) + class X(object): pass + self.checkraises(TypeError, 'abc', '__mod__', X()) + + @support.cpython_only + def test_formatting_c_limits(self): + from _testcapi import PY_SSIZE_T_MAX, INT_MAX, UINT_MAX + SIZE_MAX = (1 << (PY_SSIZE_T_MAX.bit_length() + 1)) - 1 self.checkraises(OverflowError, '%*s', '__mod__', - (_testcapi.PY_SSIZE_T_MAX + 1, '')) + (PY_SSIZE_T_MAX + 1, '')) self.checkraises(OverflowError, '%.*f', '__mod__', - (_testcapi.INT_MAX + 1, 1. / 7)) + (INT_MAX + 1, 1. / 7)) # Issue 15989 self.checkraises(OverflowError, '%*s', '__mod__', - (1 << (_testcapi.PY_SSIZE_T_MAX.bit_length() + 1), '')) + (SIZE_MAX + 1, '')) self.checkraises(OverflowError, '%.*f', '__mod__', - (_testcapi.UINT_MAX + 1, 1. / 7)) - - class X(object): pass - self.checkraises(TypeError, 'abc', '__mod__', X()) + (UINT_MAX + 1, 1. / 7)) def test_floatformatting(self): # float formatting diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index a242a4727d13..205c47c0c1bb 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -3,29 +3,30 @@ if __name__ != 'test.support': raise ImportError('support must be imported from the test package') +import collections.abc import contextlib import errno +import fnmatch import functools import gc -import socket -import sys -import os -import platform -import shutil -import warnings -import unittest import importlib import importlib.util -import collections.abc +import logging.handlers +import os +import platform import re +import shutil +import socket +import stat +import struct import subprocess -import time +import sys import sysconfig -import fnmatch -import logging.handlers -import struct import tempfile -import _testcapi +import time +import unittest +import urllib.error +import warnings try: import _thread, threading @@ -85,7 +86,7 @@ "skip_unless_symlink", "requires_gzip", "requires_bz2", "requires_lzma", "bigmemtest", "bigaddrspacetest", "cpython_only", "get_attribute", "requires_IEEE_754", "skip_unless_xattr", "requires_zlib", - "anticipate_failure", + "anticipate_failure", "load_package_tests", # sys "is_jython", "check_impl_detail", # network @@ -188,6 +189,25 @@ def anticipate_failure(condition): return unittest.expectedFailure return lambda f: f +def load_package_tests(pkg_dir, loader, standard_tests, pattern): + """Generic load_tests implementation for simple test packages. + + Most packages can implement load_tests using this function as follows: + + def load_tests(*args): + return load_package_tests(os.path.dirname(__file__), *args) + """ + if pattern is None: + pattern = "test*" + top_dir = os.path.dirname( # Lib + os.path.dirname( # test + os.path.dirname(__file__))) # support + package_tests = loader.discover(start_dir=pkg_dir, + top_level_dir=top_dir, + pattern=pattern) + standard_tests.addTests(package_tests) + return standard_tests + def import_fresh_module(name, fresh=(), blocked=(), deprecated=False): """Import and return a module, deliberately bypassing sys.modules. @@ -317,7 +337,13 @@ def _rmtree(path): def _rmtree_inner(path): for name in os.listdir(path): fullname = os.path.join(path, name) - if os.path.isdir(fullname): + try: + mode = os.lstat(fullname).st_mode + except OSError as exc: + print("support.rmtree(): os.lstat(%r) failed with %s" % (fullname, exc), + file=sys.__stderr__) + mode = 0 + if stat.S_ISDIR(mode): _waitfor(_rmtree_inner, fullname, waitall=True) os.rmdir(fullname) else: @@ -379,12 +405,16 @@ def forget(modname): unlink(importlib.util.cache_from_source(source, debug_override=True)) unlink(importlib.util.cache_from_source(source, debug_override=False)) -# On some platforms, should not run gui test even if it is allowed -# in `use_resources'. -if sys.platform.startswith('win'): - import ctypes - import ctypes.wintypes - def _is_gui_available(): +# Check whether a gui is actually available +def _is_gui_available(): + if hasattr(_is_gui_available, 'result'): + return _is_gui_available.result + reason = None + if sys.platform.startswith('win'): + # if Python is running as a service (such as the buildbot service), + # gui interaction may be disallowed + import ctypes + import ctypes.wintypes UOI_FLAGS = 1 WSF_VISIBLE = 0x0001 class USEROBJECTFLAGS(ctypes.Structure): @@ -404,29 +434,63 @@ class USEROBJECTFLAGS(ctypes.Structure): ctypes.byref(needed)) if not res: raise ctypes.WinError() - return bool(uof.dwFlags & WSF_VISIBLE) -else: - def _is_gui_available(): - return True + if not bool(uof.dwFlags & WSF_VISIBLE): + reason = "gui not available (WSF_VISIBLE flag not set)" + elif sys.platform == 'darwin': + # The Aqua Tk implementations on OS X can abort the process if + # being called in an environment where a window server connection + # cannot be made, for instance when invoked by a buildbot or ssh + # process not running under the same user id as the current console + # user. To avoid that, raise an exception if the window manager + # connection is not available. + from ctypes import cdll, c_int, pointer, Structure + from ctypes.util import find_library + + app_services = cdll.LoadLibrary(find_library("ApplicationServices")) + + if app_services.CGMainDisplayID() == 0: + reason = "gui tests cannot run without OS X window manager" + else: + class ProcessSerialNumber(Structure): + _fields_ = [("highLongOfPSN", c_int), + ("lowLongOfPSN", c_int)] + psn = ProcessSerialNumber() + psn_p = pointer(psn) + if ( (app_services.GetCurrentProcess(psn_p) < 0) or + (app_services.SetFrontProcess(psn_p) < 0) ): + reason = "cannot run without OS X gui process" + + # check on every platform whether tkinter can actually do anything + if not reason: + try: + from tkinter import Tk + root = Tk() + root.update() + root.destroy() + except Exception as e: + err_string = str(e) + if len(err_string) > 50: + err_string = err_string[:50] + ' [...]' + reason = 'Tk unavailable due to {}: {}'.format(type(e).__name__, + err_string) + + _is_gui_available.reason = reason + _is_gui_available.result = not reason + + return _is_gui_available.result def is_resource_enabled(resource): - """Test whether a resource is enabled. Known resources are set by - regrtest.py.""" - return use_resources is not None and resource in use_resources + """Test whether a resource is enabled. -def requires(resource, msg=None): - """Raise ResourceDenied if the specified resource is not available. - - If the caller's module is __main__ then automatically return True. The - possibility of False being returned occurs when regrtest.py is - executing. + Known resources are set by regrtest.py. If not running under regrtest.py, + all resources are assumed enabled unless use_resources has been set. """ + return use_resources is None or resource in use_resources + +def requires(resource, msg=None): + """Raise ResourceDenied if the specified resource is not available.""" if resource == 'gui' and not _is_gui_available(): - raise unittest.SkipTest("Cannot use the 'gui' resource") - # see if the caller's module is __main__ - if so, treat as if - # the resource was set - if sys._getframe(1).f_globals.get("__name__") == "__main__": - return + raise ResourceDenied(_is_gui_available.reason) if not is_resource_enabled(resource): if msg is None: msg = "Use of the %r resource not enabled" % resource @@ -627,6 +691,18 @@ def _is_ipv6_enabled(): IPV6_ENABLED = _is_ipv6_enabled() +def system_must_validate_cert(f): + """Skip the test on TLS certificate validation failures.""" + @functools.wraps(f) + def dec(*args, **kwargs): + try: + f(*args, **kwargs) + except IOError as e: + if "CERTIFICATE_VERIFY_FAILED" in str(e): + raise unittest.SkipTest("system does not contain " + "necessary certificates") + raise + return dec # A constant likely larger than the underlying OS pipe buffer size, to # make writes blocking. @@ -964,8 +1040,14 @@ def check_valid_file(fn): # Verify the requirement before downloading the file requires('urlfetch') - print('\tfetching %s ...' % url, file=get_original_stdout()) - f = urllib.request.urlopen(url, timeout=15) + if verbose: + print('\tfetching %s ...' % url, file=get_original_stdout()) + opener = urllib.request.build_opener() + if gzip: + opener.addheaders.append(('Accept-Encoding', 'gzip')) + f = opener.open(url, timeout=15) + if gzip and f.headers.get('Content-Encoding') == 'gzip': + f = gzip.GzipFile(fileobj=f) try: with open(fn, "wb") as out: s = f.read() @@ -1243,6 +1325,8 @@ def filter_error(err): n = getattr(err, 'errno', None) if (isinstance(err, socket.timeout) or (isinstance(err, socket.gaierror) and n in gai_errnos) or + (isinstance(err, urllib.error.URLError) and + "ConnectionRefusedError" in err.reason) or n in captured_errnos): if not verbose: sys.stderr.write(denied.args[0] + "\n") @@ -1373,6 +1457,7 @@ def calcvobjsize(fmt): _TPFLAGS_HEAPTYPE = 1<<9 def check_sizeof(test, o, size): + import _testcapi result = sys.getsizeof(o) # add GC header size if ((type(o) == type) and (o.__flags__ & _TPFLAGS_HEAPTYPE) or\ @@ -1589,7 +1674,7 @@ def _id(obj): def requires_resource(resource): if resource == 'gui' and not _is_gui_available(): - return unittest.skip("resource 'gui' is not available") + return unittest.skip(_is_gui_available.reason) if is_resource_enabled(resource): return _id else: @@ -2172,4 +2257,5 @@ def run_in_subinterp(code): raise unittest.SkipTest("run_in_subinterp() cannot be used " "if tracemalloc module is tracing " "memory allocations") + import _testcapi return _testcapi.run_in_subinterp(code) diff --git a/Lib/test/test___all__.py b/Lib/test/test___all__.py index 8cc285f70a5c..e94d984f2b94 100644 --- a/Lib/test/test___all__.py +++ b/Lib/test/test___all__.py @@ -72,13 +72,14 @@ def test_all(self): # 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 - import locale except ImportError: pass - else: - locale.setlocale(locale.LC_CTYPE, 'C') + finally: + locale.setlocale(locale.LC_CTYPE, locale_tuple) ignored = [] failed_imports = [] diff --git a/Lib/test/test___future__.py b/Lib/test/test___future__.py index 9ae4ce40ad47..6f73c7fddfda 100644 --- a/Lib/test/test___future__.py +++ b/Lib/test/test___future__.py @@ -1,4 +1,3 @@ -#! /usr/bin/env python3 import unittest from test import support import __future__ diff --git a/Lib/test/test__locale.py b/Lib/test/test__locale.py index 4231f37bc963..8d1c8db2acc9 100644 --- a/Lib/test/test__locale.py +++ b/Lib/test/test__locale.py @@ -9,7 +9,6 @@ import sys import unittest from platform import uname -from test.support import run_unittest if uname().system == "Darwin": maj, min, mic = [int(part) for part in uname().release.split(".")] @@ -24,45 +23,52 @@ 'da_DK', 'nn_NO', 'cs_CZ', 'de_LU', 'es_BO', 'sq_AL', 'sk_SK', 'fr_CH', 'de_DE', 'sr_YU', 'br_FR', 'nl_BE', 'sv_FI', 'pl_PL', 'fr_CA', 'fo_FO', 'bs_BA', 'fr_LU', 'kl_GL', 'fa_IR', 'de_BE', 'sv_SE', 'it_CH', 'uk_UA', - 'eu_ES', 'vi_VN', 'af_ZA', 'nb_NO', 'en_DK', 'tg_TJ', 'en_US', + 'eu_ES', 'vi_VN', 'af_ZA', 'nb_NO', 'en_DK', 'tg_TJ', 'ps_AF', 'en_US', 'es_ES.ISO8859-1', 'fr_FR.ISO8859-15', 'ru_RU.KOI8-R', 'ko_KR.eucKR'] -# Issue #13441: Skip some locales (e.g. cs_CZ and hu_HU) on Solaris to -# workaround a mbstowcs() bug. For example, on Solaris, the hu_HU locale uses -# the locale encoding ISO-8859-2, the thousauds separator is b'\xA0' and it is -# decoded as U+30000020 (an invalid character) by mbstowcs(). -if sys.platform == 'sunos5': - old_locale = locale.setlocale(locale.LC_ALL) - try: - locales = [] - for loc in candidate_locales: - try: - locale.setlocale(locale.LC_ALL, loc) - except Error: - continue - encoding = locale.getpreferredencoding(False) - try: - localeconv() - except Exception as err: - print("WARNING: Skip locale %s (encoding %s): [%s] %s" - % (loc, encoding, type(err), err)) - else: - locales.append(loc) - candidate_locales = locales - finally: - locale.setlocale(locale.LC_ALL, old_locale) - -# Workaround for MSVC6(debug) crash bug -if "MSC v.1200" in sys.version: - def accept(loc): - a = loc.split(".") - return not(len(a) == 2 and len(a[-1]) >= 9) - candidate_locales = [loc for loc in candidate_locales if accept(loc)] +def setUpModule(): + global candidate_locales + # Issue #13441: Skip some locales (e.g. cs_CZ and hu_HU) on Solaris to + # workaround a mbstowcs() bug. For example, on Solaris, the hu_HU locale uses + # the locale encoding ISO-8859-2, the thousauds separator is b'\xA0' and it is + # decoded as U+30000020 (an invalid character) by mbstowcs(). + if sys.platform == 'sunos5': + old_locale = locale.setlocale(locale.LC_ALL) + try: + locales = [] + for loc in candidate_locales: + try: + locale.setlocale(locale.LC_ALL, loc) + except Error: + continue + encoding = locale.getpreferredencoding(False) + try: + localeconv() + except Exception as err: + print("WARNING: Skip locale %s (encoding %s): [%s] %s" + % (loc, encoding, type(err), err)) + else: + locales.append(loc) + candidate_locales = locales + finally: + locale.setlocale(locale.LC_ALL, old_locale) + + # Workaround for MSVC6(debug) crash bug + if "MSC v.1200" in sys.version: + def accept(loc): + a = loc.split(".") + return not(len(a) == 2 and len(a[-1]) >= 9) + candidate_locales = [loc for loc in candidate_locales if accept(loc)] # List known locale values to test against when available. # Dict formatted as ``<locale> : (<decimal_point>, <thousands_sep>)``. If a # value is not known, use '' . -known_numerics = {'fr_FR' : (',', ''), 'en_US':('.', ',')} +known_numerics = { + 'en_US': ('.', ','), + 'fr_FR' : (',', ' '), + 'de_DE' : (',', '.'), + 'ps_AF': ('\u066b', '\u066c'), +} class _LocaleTests(unittest.TestCase): @@ -91,10 +97,12 @@ def numeric_tester(self, calc_type, calc_value, data_type, used_locale): calc_value, known_value, calc_type, data_type, set_locale, used_locale)) + return True @unittest.skipUnless(nl_langinfo, "nl_langinfo is not available") def test_lc_numeric_nl_langinfo(self): # Test nl_langinfo against known values + tested = False for loc in candidate_locales: try: setlocale(LC_NUMERIC, loc) @@ -103,10 +111,14 @@ def test_lc_numeric_nl_langinfo(self): continue for li, lc in ((RADIXCHAR, "decimal_point"), (THOUSEP, "thousands_sep")): - self.numeric_tester('nl_langinfo', nl_langinfo(li), lc, loc) + if self.numeric_tester('nl_langinfo', nl_langinfo(li), lc, loc): + tested = True + if not tested: + self.skipTest('no suitable locales') def test_lc_numeric_localeconv(self): # Test localeconv against known values + tested = False for loc in candidate_locales: try: setlocale(LC_NUMERIC, loc) @@ -116,11 +128,15 @@ def test_lc_numeric_localeconv(self): formatting = localeconv() for lc in ("decimal_point", "thousands_sep"): - self.numeric_tester('localeconv', formatting[lc], lc, loc) + if self.numeric_tester('localeconv', formatting[lc], lc, loc): + tested = True + if not tested: + self.skipTest('no suitable locales') @unittest.skipUnless(nl_langinfo, "nl_langinfo is not available") def test_lc_numeric_basic(self): # Test nl_langinfo against localeconv + tested = False for loc in candidate_locales: try: setlocale(LC_NUMERIC, loc) @@ -140,10 +156,14 @@ def test_lc_numeric_basic(self): "(set to %s, using %s)" % ( nl_radixchar, li_radixchar, loc, set_locale)) + tested = True + if not tested: + self.skipTest('no suitable locales') def test_float_parsing(self): # Bug #1391872: Test whether float parsing is okay on European # locales. + tested = False for loc in candidate_locales: try: setlocale(LC_NUMERIC, loc) @@ -162,9 +182,10 @@ def test_float_parsing(self): if localeconv()['decimal_point'] != '.': self.assertRaises(ValueError, float, localeconv()['decimal_point'].join(['1', '23'])) + tested = True + if not tested: + self.skipTest('no suitable locales') -def test_main(): - run_unittest(_LocaleTests) if __name__ == '__main__': - test_main() + unittest.main() diff --git a/Lib/test/test__osx_support.py b/Lib/test/test__osx_support.py index fb159ecf4138..5dcadf7a409e 100644 --- a/Lib/test/test__osx_support.py +++ b/Lib/test/test__osx_support.py @@ -109,7 +109,9 @@ def test__save_modified_value_unchanged(self): def test__supports_universal_builds(self): import platform - self.assertEqual(platform.mac_ver()[0].split('.') >= ['10', '4'], + mac_ver_tuple = tuple(int(i) for i in + platform.mac_ver()[0].split('.')[0:2]) + self.assertEqual(mac_ver_tuple >= (10, 4), _osx_support._supports_universal_builds()) def test__find_appropriate_compiler(self): diff --git a/Lib/test/test_abstract_numbers.py b/Lib/test/test_abstract_numbers.py index 253e6f082c30..2e06f0d16fdd 100644 --- a/Lib/test/test_abstract_numbers.py +++ b/Lib/test/test_abstract_numbers.py @@ -4,7 +4,6 @@ import operator import unittest from numbers import Complex, Real, Rational, Integral -from test import support class TestNumbers(unittest.TestCase): def test_int(self): @@ -40,9 +39,6 @@ def test_complex(self): self.assertRaises(TypeError, float, c1) self.assertRaises(TypeError, int, c1) -def test_main(): - support.run_unittest(TestNumbers) - if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_aifc.py b/Lib/test/test_aifc.py index 041b23688c66..ab5143787b0d 100644 --- a/Lib/test/test_aifc.py +++ b/Lib/test/test_aifc.py @@ -14,9 +14,6 @@ class AifcTest(audiotests.AudioWriteTests, module = aifc close_fd = True test_unseekable_read = None - test_unseekable_write = None - test_unseekable_incompleted_write = None - test_unseekable_overflowed_write = None class AifcPCM8Test(AifcTest, unittest.TestCase): diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index c10c5909bf3e..d7f90cdaa988 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -20,15 +20,6 @@ class StdIOBuffer(StringIO): class TestCase(unittest.TestCase): - def assertEqual(self, obj1, obj2): - if obj1 != obj2: - print('') - print(repr(obj1)) - print(repr(obj2)) - print(obj1) - print(obj2) - super(TestCase, self).assertEqual(obj1, obj2) - def setUp(self): # The tests assume that line wrapping occurs at 80 columns, but this # behaviour can be overridden by setting the COLUMNS environment @@ -47,6 +38,9 @@ def setUp(self): def tearDown(self): os.chdir(self.old_dir) + for root, dirs, files in os.walk(self.temp_dir, topdown=False): + for name in files: + os.chmod(os.path.join(self.temp_dir, name), stat.S_IWRITE) shutil.rmtree(self.temp_dir, True) def create_readonly_file(self, filename): @@ -75,9 +69,6 @@ def __repr__(self): def __eq__(self, other): return vars(self) == vars(other) - def __ne__(self, other): - return not (self == other) - class ArgumentParserError(Exception): @@ -232,8 +223,8 @@ def test_failures(self, tester): parser = self._get_parser(tester) for args_str in tester.failures: args = args_str.split() - raises = tester.assertRaises - raises(ArgumentParserError, parser.parse_args, args) + with tester.assertRaises(ArgumentParserError, msg=args): + parser.parse_args(args) def test_successes(self, tester): parser = self._get_parser(tester) @@ -641,7 +632,7 @@ class TestOptionalsChoices(ParserTestCase): class TestOptionalsRequired(ParserTestCase): - """Tests the an optional action that is required""" + """Tests an optional action that is required""" argument_signatures = [ Sig('-x', type=int, required=True), @@ -762,6 +753,39 @@ class TestOptionalsActionCount(ParserTestCase): ] +class TestOptionalsAllowLongAbbreviation(ParserTestCase): + """Allow long options to be abbreviated unambiguously""" + + argument_signatures = [ + Sig('--foo'), + Sig('--foobaz'), + Sig('--fooble', action='store_true'), + ] + failures = ['--foob 5', '--foob'] + successes = [ + ('', NS(foo=None, foobaz=None, fooble=False)), + ('--foo 7', NS(foo='7', foobaz=None, fooble=False)), + ('--fooba a', NS(foo=None, foobaz='a', fooble=False)), + ('--foobl --foo g', NS(foo='g', foobaz=None, fooble=True)), + ] + + +class TestOptionalsDisallowLongAbbreviation(ParserTestCase): + """Do not allow abbreviations of long options at all""" + + parser_signature = Sig(allow_abbrev=False) + argument_signatures = [ + Sig('--foo'), + Sig('--foodle', action='store_true'), + Sig('--foonly'), + ] + failures = ['-foon 3', '--foon 3', '--food', '--food --foo 2'] + successes = [ + ('', NS(foo=None, foodle=False, foonly=None)), + ('--foo 3', NS(foo='3', foodle=False, foonly=None)), + ('--foonly 7 --foodle --foo 2', NS(foo='2', foodle=True, foonly='7')), + ] + # ================ # Positional tests # ================ @@ -1990,14 +2014,9 @@ def test_subparser_title_help(self): ''')) def _test_subparser_help(self, args_str, expected_help): - try: + with self.assertRaises(ArgumentParserError) as cm: self.parser.parse_args(args_str.split()) - except ArgumentParserError: - err = sys.exc_info()[1] - if err.stdout != expected_help: - print(repr(expected_help)) - print(repr(err.stdout)) - self.assertEqual(err.stdout, expected_help) + self.assertEqual(expected_help, cm.exception.stdout) def test_subparser1_help(self): self._test_subparser_help('5.0 1 -h', textwrap.dedent('''\ @@ -2792,6 +2811,13 @@ def test_set_defaults_parents(self): parser = ErrorRaisingArgumentParser(parents=[parent]) self.assertEqual(NS(x='foo'), parser.parse_args([])) + def test_set_defaults_on_parent_and_subparser(self): + parser = argparse.ArgumentParser() + xparser = parser.add_subparsers().add_parser('X') + parser.set_defaults(foo=1) + xparser.set_defaults(foo=2) + self.assertEqual(NS(foo=2), parser.parse_args(['X'])) + def test_set_defaults_same_as_add_argument(self): parser = ErrorRaisingArgumentParser() parser.set_defaults(w='W', x='X', y='Y', z='Z') @@ -2836,15 +2862,15 @@ class TestGetDefault(TestCase): def test_get_default(self): parser = ErrorRaisingArgumentParser() - self.assertEqual(None, parser.get_default("foo")) - self.assertEqual(None, parser.get_default("bar")) + self.assertIsNone(parser.get_default("foo")) + self.assertIsNone(parser.get_default("bar")) parser.add_argument("--foo") - self.assertEqual(None, parser.get_default("foo")) - self.assertEqual(None, parser.get_default("bar")) + self.assertIsNone(parser.get_default("foo")) + self.assertIsNone(parser.get_default("bar")) parser.add_argument("--bar", type=int, default=42) - self.assertEqual(None, parser.get_default("foo")) + self.assertIsNone(parser.get_default("foo")) self.assertEqual(42, parser.get_default("bar")) parser.set_defaults(foo="badger") @@ -2859,18 +2885,16 @@ class TestNamespaceContainsSimple(TestCase): def test_empty(self): ns = argparse.Namespace() - self.assertEqual('' in ns, False) - self.assertEqual('' not in ns, True) - self.assertEqual('x' in ns, False) + self.assertNotIn('', ns) + self.assertNotIn('x', ns) def test_non_empty(self): ns = argparse.Namespace(x=1, y=2) - self.assertEqual('x' in ns, True) - self.assertEqual('x' not in ns, False) - self.assertEqual('y' in ns, True) - self.assertEqual('' in ns, False) - self.assertEqual('xx' in ns, False) - self.assertEqual('z' in ns, False) + self.assertNotIn('', ns) + self.assertIn('x', ns) + self.assertIn('y', ns) + self.assertNotIn('xx', ns) + self.assertNotIn('z', ns) # ===================== # Help formatting tests @@ -2926,13 +2950,6 @@ def _get_parser(self, tester): def _test(self, tester, parser_text): expected_text = getattr(tester, self.func_suffix) expected_text = textwrap.dedent(expected_text) - if expected_text != parser_text: - print(repr(expected_text)) - print(repr(parser_text)) - for char1, char2 in zip(expected_text, parser_text): - if char1 != char2: - print('first diff: %r %r' % (char1, char2)) - break tester.assertEqual(expected_text, parser_text) def test_format(self, tester): @@ -3005,6 +3022,60 @@ class TestHelpBiggerOptionals(HelpTestCase): 0.1 ''' +class TestShortColumns(HelpTestCase): + '''Test extremely small number of columns. + + TestCase prevents "COLUMNS" from being too small in the tests themselves, + but we don't want any exceptions thrown in such case. Only ugly representation. + ''' + def setUp(self): + env = support.EnvironmentVarGuard() + env.set("COLUMNS", '15') + self.addCleanup(env.__exit__) + + parser_signature = TestHelpBiggerOptionals.parser_signature + argument_signatures = TestHelpBiggerOptionals.argument_signatures + argument_group_signatures = TestHelpBiggerOptionals.argument_group_signatures + usage = '''\ + usage: PROG + [-h] + [-v] + [-x] + [--y Y] + foo + bar + ''' + help = usage + '''\ + + DESCRIPTION + + positional arguments: + foo + FOO HELP + bar + BAR HELP + + optional arguments: + -h, --help + show this + help + message and + exit + -v, --version + show + program's + version + number and + exit + -x + X HELP + --y Y + Y HELP + + EPILOG + ''' + version = TestHelpBiggerOptionals.version + class TestHelpBiggerOptionalGroups(HelpTestCase): """Make sure that argument help aligns when options are longer""" @@ -4159,24 +4230,17 @@ def test_invalid_action(self): self.assertValueError('foo', action='baz') self.assertValueError('--foo', action=('store', 'append')) parser = argparse.ArgumentParser() - try: + with self.assertRaises(ValueError) as cm: parser.add_argument("--foo", action="store-true") - except ValueError: - e = sys.exc_info()[1] - expected = 'unknown action' - msg = 'expected %r, found %r' % (expected, e) - self.assertTrue(expected in str(e), msg) + self.assertIn('unknown action', str(cm.exception)) def test_multiple_dest(self): parser = argparse.ArgumentParser() parser.add_argument(dest='foo') - try: + with self.assertRaises(ValueError) as cm: parser.add_argument('bar', dest='baz') - except ValueError: - e = sys.exc_info()[1] - expected = 'dest supplied twice for positional argument' - msg = 'expected %r, found %r' % (expected, e) - self.assertTrue(expected in str(e), msg) + self.assertIn('dest supplied twice for positional argument', + str(cm.exception)) def test_no_argument_actions(self): for action in ['store_const', 'store_true', 'store_false', @@ -4333,18 +4397,10 @@ def test_resolve_error(self): class TestOptionalsHelpVersionActions(TestCase): """Test the help and version actions""" - def _get_error(self, func, *args, **kwargs): - try: - func(*args, **kwargs) - except ArgumentParserError: - return sys.exc_info()[1] - else: - self.assertRaises(ArgumentParserError, func, *args, **kwargs) - def assertPrintHelpExit(self, parser, args_str): - self.assertEqual( - parser.format_help(), - self._get_error(parser.parse_args, args_str.split()).stdout) + with self.assertRaises(ArgumentParserError) as cm: + parser.parse_args(args_str.split()) + self.assertEqual(parser.format_help(), cm.exception.stdout) def assertArgumentParserError(self, parser, *args): self.assertRaises(ArgumentParserError, parser.parse_args, args) @@ -4359,8 +4415,9 @@ def test_version(self): def test_version_format(self): parser = ErrorRaisingArgumentParser(prog='PPP') parser.add_argument('-v', '--version', action='version', version='%(prog)s 3.5') - msg = self._get_error(parser.parse_args, ['-v']).stdout - self.assertEqual('PPP 3.5\n', msg) + with self.assertRaises(ArgumentParserError) as cm: + parser.parse_args(['-v']) + self.assertEqual('PPP 3.5\n', cm.exception.stdout) def test_version_no_help(self): parser = ErrorRaisingArgumentParser(add_help=False) @@ -4372,8 +4429,9 @@ def test_version_no_help(self): def test_version_action(self): parser = ErrorRaisingArgumentParser(prog='XXX') parser.add_argument('-V', action='version', version='%(prog)s 3.7') - msg = self._get_error(parser.parse_args, ['-V']).stdout - self.assertEqual('XXX 3.7\n', msg) + with self.assertRaises(ArgumentParserError) as cm: + parser.parse_args(['-V']) + self.assertEqual('XXX 3.7\n', cm.exception.stdout) def test_no_help(self): parser = ErrorRaisingArgumentParser(add_help=False) @@ -4494,6 +4552,12 @@ def test_equality(self): self.assertTrue(ns2 != ns3) self.assertTrue(ns2 != ns4) + def test_equality_returns_notimplemeted(self): + # See issue 21481 + ns = argparse.Namespace(a=1, b=2) + self.assertIs(ns.__eq__(None), NotImplemented) + self.assertIs(ns.__ne__(None), NotImplemented) + # =================== # File encoding tests @@ -4537,14 +4601,10 @@ def spam(string): parser = ErrorRaisingArgumentParser(prog='PROG', add_help=False) parser.add_argument('x', type=spam) - try: + with self.assertRaises(ArgumentParserError) as cm: parser.parse_args(['XXX']) - except ArgumentParserError: - expected = 'usage: PROG x\nPROG: error: argument x: spam!\n' - msg = sys.exc_info()[1].stderr - self.assertEqual(expected, msg) - else: - self.fail() + self.assertEqual('usage: PROG x\nPROG: error: argument x: spam!\n', + cm.exception.stderr) # ========================= # MessageContentError tests diff --git a/Lib/test/test_array.py b/Lib/test/test_array.py old mode 100755 new mode 100644 index 409d586088ec..10d99462fd87 --- a/Lib/test/test_array.py +++ b/Lib/test/test_array.py @@ -1,4 +1,3 @@ -#! /usr/bin/env python3 """Test the arraymodule. Roger E. Masse """ @@ -286,17 +285,18 @@ def test_pickle_for_empty_array(self): def test_iterator_pickle(self): data = array.array(self.typecode, self.example) - orgit = iter(data) - d = pickle.dumps(orgit) - it = pickle.loads(d) - self.assertEqual(type(orgit), type(it)) - self.assertEqual(list(it), list(data)) - - if len(data): + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + orgit = iter(data) + d = pickle.dumps(orgit, proto) it = pickle.loads(d) - next(it) - d = pickle.dumps(it) - self.assertEqual(list(it), list(data)[1:]) + self.assertEqual(type(orgit), type(it)) + self.assertEqual(list(it), list(data)) + + if len(data): + it = pickle.loads(d) + next(it) + d = pickle.dumps(it, proto) + self.assertEqual(list(it), list(data)[1:]) def test_insert(self): a = array.array(self.typecode, self.example) @@ -394,7 +394,9 @@ def test_tofromlist(self): self.assertEqual(a, b) def test_tofromstring(self): - nb_warnings = 4 + # Warnings not raised when arguments are incorrect as Argument Clinic + # handles that before the warning can be raised. + nb_warnings = 2 with warnings.catch_warnings(record=True) as r: warnings.filterwarnings("always", message=r"(to|from)string\(\) is deprecated", @@ -946,7 +948,7 @@ def test_coveritertraverse(self): try: import gc except ImportError: - return + self.skipTest('gc module not available') a = array.array(self.typecode) l = [iter(a)] l.append(l) @@ -1039,6 +1041,11 @@ def test_initialize_with_unicode(self): a = array.array(self.typecode, "foo") a = array.array(self.typecode, array.array('u', 'foo')) + @support.cpython_only + def test_obsolete_write_lock(self): + from _testcapi import getbuffer_with_null_view + a = array.array('B', b"") + self.assertRaises(BufferError, getbuffer_with_null_view, a) class StringTest(BaseTest): diff --git a/Lib/test/test_asdl_parser.py b/Lib/test/test_asdl_parser.py new file mode 100644 index 000000000000..7a6426a4d35a --- /dev/null +++ b/Lib/test/test_asdl_parser.py @@ -0,0 +1,122 @@ +"""Tests for the asdl parser in Parser/asdl.py""" + +import importlib.machinery +import os +from os.path import dirname +import sys +import sysconfig +import unittest + + +# This test is only relevant for from-source builds of Python. +if not sysconfig.is_python_build(): + raise unittest.SkipTest('test irrelevant for an installed Python') + +src_base = dirname(dirname(dirname(__file__))) +parser_dir = os.path.join(src_base, 'Parser') + + +class TestAsdlParser(unittest.TestCase): + @classmethod + def setUpClass(cls): + # Loads the asdl module dynamically, since it's not in a real importable + # package. + # Parses Python.asdl into a ast.Module and run the check on it. + # There's no need to do this for each test method, hence setUpClass. + sys.path.insert(0, parser_dir) + loader = importlib.machinery.SourceFileLoader( + 'asdl', os.path.join(parser_dir, 'asdl.py')) + cls.asdl = loader.load_module() + cls.mod = cls.asdl.parse(os.path.join(parser_dir, 'Python.asdl')) + cls.assertTrue(cls.asdl.check(cls.mod), 'Module validation failed') + + @classmethod + def tearDownClass(cls): + del sys.path[0] + + def setUp(self): + # alias stuff from the class, for convenience + self.asdl = TestAsdlParser.asdl + self.mod = TestAsdlParser.mod + self.types = self.mod.types + + def test_module(self): + self.assertEqual(self.mod.name, 'Python') + self.assertIn('stmt', self.types) + self.assertIn('expr', self.types) + self.assertIn('mod', self.types) + + def test_definitions(self): + defs = self.mod.dfns + self.assertIsInstance(defs[0], self.asdl.Type) + self.assertIsInstance(defs[0].value, self.asdl.Sum) + + self.assertIsInstance(self.types['withitem'], self.asdl.Product) + self.assertIsInstance(self.types['alias'], self.asdl.Product) + + def test_product(self): + alias = self.types['alias'] + self.assertEqual( + str(alias), + 'Product([Field(identifier, name), Field(identifier, asname, opt=True)])') + + def test_attributes(self): + stmt = self.types['stmt'] + self.assertEqual(len(stmt.attributes), 2) + self.assertEqual(str(stmt.attributes[0]), 'Field(int, lineno)') + self.assertEqual(str(stmt.attributes[1]), 'Field(int, col_offset)') + + def test_constructor_fields(self): + ehandler = self.types['excepthandler'] + self.assertEqual(len(ehandler.types), 1) + self.assertEqual(len(ehandler.attributes), 2) + + cons = ehandler.types[0] + self.assertIsInstance(cons, self.asdl.Constructor) + self.assertEqual(len(cons.fields), 3) + + f0 = cons.fields[0] + self.assertEqual(f0.type, 'expr') + self.assertEqual(f0.name, 'type') + self.assertTrue(f0.opt) + + f1 = cons.fields[1] + self.assertEqual(f1.type, 'identifier') + self.assertEqual(f1.name, 'name') + self.assertTrue(f1.opt) + + f2 = cons.fields[2] + self.assertEqual(f2.type, 'stmt') + self.assertEqual(f2.name, 'body') + self.assertFalse(f2.opt) + self.assertTrue(f2.seq) + + def test_visitor(self): + class CustomVisitor(self.asdl.VisitorBase): + def __init__(self): + super().__init__() + self.names_with_seq = [] + + def visitModule(self, mod): + for dfn in mod.dfns: + self.visit(dfn) + + def visitType(self, type): + self.visit(type.value) + + def visitSum(self, sum): + for t in sum.types: + self.visit(t) + + def visitConstructor(self, cons): + for f in cons.fields: + if f.seq: + self.names_with_seq.append(cons.name) + + v = CustomVisitor() + v.visit(self.types['mod']) + self.assertEqual(v.names_with_seq, ['Module', 'Interactive', 'Suite']) + + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py index e69422a29273..a533f8693bc4 100644 --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -37,7 +37,7 @@ def to_tuple(t): # FunctionDef with kwargs "def f(**kwargs): pass", # FunctionDef with all kind of args - "def f(a, b=1, c=None, d=[], e={}, *args, **kwargs): pass", + "def f(a, b=1, c=None, d=[], e={}, *args, f=42, **kwargs): pass", # ClassDef "class C:pass", # ClassDef, new style class @@ -180,36 +180,20 @@ def to_tuple(t): class AST_Tests(unittest.TestCase): - def _assertTrueorder(self, ast_node, parent_pos, reverse_check = False): - def should_reverse_check(parent, child): - # In some situations, the children of nodes occur before - # their parents, for example in a.b.c, a occurs before b - # but a is a child of b. - if isinstance(parent, ast.Call): - if parent.func == child: - return True - if isinstance(parent, (ast.Attribute, ast.Subscript)): - return True - return False - + def _assertTrueorder(self, ast_node, parent_pos): if not isinstance(ast_node, ast.AST) or ast_node._fields is None: return if isinstance(ast_node, (ast.expr, ast.stmt, ast.excepthandler)): node_pos = (ast_node.lineno, ast_node.col_offset) - if reverse_check: - self.assertTrue(node_pos <= parent_pos) - else: - self.assertTrue(node_pos >= parent_pos) + self.assertTrue(node_pos >= parent_pos) parent_pos = (ast_node.lineno, ast_node.col_offset) for name in ast_node._fields: value = getattr(ast_node, name) if isinstance(value, list): for child in value: - self._assertTrueorder(child, parent_pos, - should_reverse_check(ast_node, child)) + self._assertTrueorder(child, parent_pos) elif value is not None: - self._assertTrueorder(value, parent_pos, - should_reverse_check(ast_node, value)) + self._assertTrueorder(value, parent_pos) def test_AST_objects(self): x = ast.AST() @@ -278,9 +262,8 @@ def test_field_attr_existence(self): def test_arguments(self): x = ast.arguments() - self.assertEqual(x._fields, ('args', 'vararg', - 'kwonlyargs', 'kw_defaults', - 'kwarg', 'defaults')) + self.assertEqual(x._fields, ('args', 'vararg', 'kwonlyargs', + 'kw_defaults', 'kwarg', 'defaults')) with self.assertRaises(AttributeError): x.vararg @@ -455,7 +438,7 @@ def test_dump(self): "lineno=1, col_offset=0), args=[Name(id='eggs', ctx=Load(), " "lineno=1, col_offset=5), Str(s='and cheese', lineno=1, " "col_offset=11)], keywords=[], starargs=None, kwargs=None, " - "lineno=1, col_offset=4), lineno=1, col_offset=0)])" + "lineno=1, col_offset=0), lineno=1, col_offset=0)])" ) def test_copy_location(self): @@ -476,7 +459,7 @@ def test_fix_missing_locations(self): "Module(body=[Expr(value=Call(func=Name(id='write', ctx=Load(), " "lineno=1, col_offset=0), args=[Str(s='spam', lineno=1, " "col_offset=6)], keywords=[], starargs=None, kwargs=None, " - "lineno=1, col_offset=5), lineno=1, col_offset=0), " + "lineno=1, col_offset=0), lineno=1, col_offset=0), " "Expr(value=Call(func=Name(id='spam', ctx=Load(), lineno=1, " "col_offset=0), args=[Str(s='eggs', lineno=1, col_offset=0)], " "keywords=[], starargs=None, kwargs=None, lineno=1, " @@ -973,7 +956,7 @@ def main(): ('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None)], None, [], [], None, [('Num', (1, 8), 0)]), [('Pass', (1, 12))], [], None)]), ('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], ('arg', (1, 7), 'args', None), [], [], None, []), [('Pass', (1, 14))], [], None)]), ('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], ('arg', (1, 8), 'kwargs', None), []), [('Pass', (1, 17))], [], None)]), -('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None), ('arg', (1, 9), 'b', None), ('arg', (1, 14), 'c', None), ('arg', (1, 22), 'd', None), ('arg', (1, 28), 'e', None)], ('arg', (1, 35), 'args', None), [], [], ('arg', (1, 43), 'kwargs', None), [('Num', (1, 11), 1), ('NameConstant', (1, 16), None), ('List', (1, 24), [], ('Load',)), ('Dict', (1, 30), [], [])]), [('Pass', (1, 52))], [], None)]), +('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None), ('arg', (1, 9), 'b', None), ('arg', (1, 14), 'c', None), ('arg', (1, 22), 'd', None), ('arg', (1, 28), 'e', None)], ('arg', (1, 35), 'args', None), [('arg', (1, 41), 'f', None)], [('Num', (1, 43), 42)], ('arg', (1, 49), 'kwargs', None), [('Num', (1, 11), 1), ('NameConstant', (1, 16), None), ('List', (1, 24), [], ('Load',)), ('Dict', (1, 30), [], [])]), [('Pass', (1, 58))], [], None)]), ('Module', [('ClassDef', (1, 0), 'C', [], [], None, None, [('Pass', (1, 8))], [])]), ('Module', [('ClassDef', (1, 0), 'C', [('Name', (1, 8), 'object', ('Load',))], [], None, None, [('Pass', (1, 17))], [])]), ('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], None, []), [('Return', (1, 8), ('Num', (1, 15), 1))], [], None)]), @@ -985,7 +968,7 @@ def main(): ('Module', [('If', (1, 0), ('Name', (1, 3), 'v', ('Load',)), [('Pass', (1, 5))], [])]), ('Module', [('With', (1, 0), [('withitem', ('Name', (1, 5), 'x', ('Load',)), ('Name', (1, 10), 'y', ('Store',)))], [('Pass', (1, 13))])]), ('Module', [('With', (1, 0), [('withitem', ('Name', (1, 5), 'x', ('Load',)), ('Name', (1, 10), 'y', ('Store',))), ('withitem', ('Name', (1, 13), 'z', ('Load',)), ('Name', (1, 18), 'q', ('Store',)))], [('Pass', (1, 21))])]), -('Module', [('Raise', (1, 0), ('Call', (1, 15), ('Name', (1, 6), 'Exception', ('Load',)), [('Str', (1, 16), 'string')], [], None, None), None)]), +('Module', [('Raise', (1, 0), ('Call', (1, 6), ('Name', (1, 6), 'Exception', ('Load',)), [('Str', (1, 16), 'string')], [], None, None), None)]), ('Module', [('Try', (1, 0), [('Pass', (2, 2))], [('ExceptHandler', (3, 0), ('Name', (3, 7), 'Exception', ('Load',)), None, [('Pass', (4, 2))])], [], [])]), ('Module', [('Try', (1, 0), [('Pass', (2, 2))], [], [], [('Pass', (4, 2))])]), ('Module', [('Assert', (1, 0), ('Name', (1, 7), 'v', ('Load',)), None)]), @@ -1022,17 +1005,17 @@ def main(): ('Expression', ('ListComp', (1, 1), ('Name', (1, 1), 'a', ('Load',)), [('comprehension', ('Name', (1, 7), 'b', ('Store',)), ('Name', (1, 12), 'c', ('Load',)), [('Name', (1, 17), 'd', ('Load',))])])), ('Expression', ('GeneratorExp', (1, 1), ('Name', (1, 1), 'a', ('Load',)), [('comprehension', ('Name', (1, 7), 'b', ('Store',)), ('Name', (1, 12), 'c', ('Load',)), [('Name', (1, 17), 'd', ('Load',))])])), ('Expression', ('Compare', (1, 0), ('Num', (1, 0), 1), [('Lt',), ('Lt',)], [('Num', (1, 4), 2), ('Num', (1, 8), 3)])), -('Expression', ('Call', (1, 1), ('Name', (1, 0), 'f', ('Load',)), [('Num', (1, 2), 1), ('Num', (1, 4), 2)], [('keyword', 'c', ('Num', (1, 8), 3))], ('Name', (1, 11), 'd', ('Load',)), ('Name', (1, 15), 'e', ('Load',)))), +('Expression', ('Call', (1, 0), ('Name', (1, 0), 'f', ('Load',)), [('Num', (1, 2), 1), ('Num', (1, 4), 2)], [('keyword', 'c', ('Num', (1, 8), 3))], ('Name', (1, 11), 'd', ('Load',)), ('Name', (1, 15), 'e', ('Load',)))), ('Expression', ('Num', (1, 0), 10)), ('Expression', ('Str', (1, 0), 'string')), -('Expression', ('Attribute', (1, 2), ('Name', (1, 0), 'a', ('Load',)), 'b', ('Load',))), -('Expression', ('Subscript', (1, 2), ('Name', (1, 0), 'a', ('Load',)), ('Slice', ('Name', (1, 2), 'b', ('Load',)), ('Name', (1, 4), 'c', ('Load',)), None), ('Load',))), +('Expression', ('Attribute', (1, 0), ('Name', (1, 0), 'a', ('Load',)), 'b', ('Load',))), +('Expression', ('Subscript', (1, 0), ('Name', (1, 0), 'a', ('Load',)), ('Slice', ('Name', (1, 2), 'b', ('Load',)), ('Name', (1, 4), 'c', ('Load',)), None), ('Load',))), ('Expression', ('Name', (1, 0), 'v', ('Load',))), ('Expression', ('List', (1, 0), [('Num', (1, 1), 1), ('Num', (1, 3), 2), ('Num', (1, 5), 3)], ('Load',))), ('Expression', ('List', (1, 0), [], ('Load',))), ('Expression', ('Tuple', (1, 0), [('Num', (1, 0), 1), ('Num', (1, 2), 2), ('Num', (1, 4), 3)], ('Load',))), ('Expression', ('Tuple', (1, 1), [('Num', (1, 1), 1), ('Num', (1, 3), 2), ('Num', (1, 5), 3)], ('Load',))), ('Expression', ('Tuple', (1, 0), [], ('Load',))), -('Expression', ('Call', (1, 7), ('Attribute', (1, 6), ('Attribute', (1, 4), ('Attribute', (1, 2), ('Name', (1, 0), 'a', ('Load',)), 'b', ('Load',)), 'c', ('Load',)), 'd', ('Load',)), [('Subscript', (1, 12), ('Attribute', (1, 10), ('Name', (1, 8), 'a', ('Load',)), 'b', ('Load',)), ('Slice', ('Num', (1, 12), 1), ('Num', (1, 14), 2), None), ('Load',))], [], None, None)), +('Expression', ('Call', (1, 0), ('Attribute', (1, 0), ('Attribute', (1, 0), ('Attribute', (1, 0), ('Name', (1, 0), 'a', ('Load',)), 'b', ('Load',)), 'c', ('Load',)), 'd', ('Load',)), [('Subscript', (1, 8), ('Attribute', (1, 8), ('Name', (1, 8), 'a', ('Load',)), 'b', ('Load',)), ('Slice', ('Num', (1, 12), 1), ('Num', (1, 14), 2), None), ('Load',))], [], None, None)), ] main() diff --git a/Lib/test/test_asynchat.py b/Lib/test/test_asynchat.py index f93a52d8c989..3a33fc8b2d78 100644 --- a/Lib/test/test_asynchat.py +++ b/Lib/test/test_asynchat.py @@ -5,9 +5,15 @@ # If this fails, the test will be skipped. thread = support.import_module('_thread') -import asyncore, asynchat, socket, time -import unittest +import asynchat +import asyncore +import errno +import socket import sys +import time +import unittest +import warnings +import unittest.mock try: import threading except ImportError: @@ -28,12 +34,12 @@ def __init__(self, event): self.event = event self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.port = support.bind_port(self.sock) - # This will be set if the client wants us to wait before echoing data - # back. + # This will be set if the client wants us to wait before echoing + # data back. self.start_resend_event = None def run(self): - self.sock.listen(1) + self.sock.listen() self.event.set() conn, client = self.sock.accept() self.buffer = b"" @@ -52,8 +58,8 @@ def run(self): # re-send entire set of collected data try: - # this may fail on some tests, such as test_close_when_done, since - # the client closes the channel when it's done sending + # this may fail on some tests, such as test_close_when_done, + # since the client closes the channel when it's done sending while self.buffer: n = conn.send(self.buffer[:self.chunk_size]) time.sleep(0.001) @@ -96,7 +102,7 @@ def start_echo_server(): s.start() event.wait() event.clear() - time.sleep(0.01) # Give server time to start accepting. + time.sleep(0.01) # Give server time to start accepting. return s, event @@ -104,10 +110,10 @@ def start_echo_server(): class TestAsynchat(unittest.TestCase): usepoll = False - def setUp (self): + def setUp(self): self._threads = support.threading_setup() - def tearDown (self): + def tearDown(self): support.threading_cleanup(*self._threads) def line_terminator_check(self, term, server_chunk): @@ -117,7 +123,7 @@ def line_terminator_check(self, term, server_chunk): s.start() event.wait() event.clear() - time.sleep(0.01) # Give server time to start accepting. + time.sleep(0.01) # Give server time to start accepting. c = echo_client(term, s.port) c.push(b"hello ") c.push(b"world" + term) @@ -136,17 +142,17 @@ def line_terminator_check(self, term, server_chunk): def test_line_terminator1(self): # test one-character terminator - for l in (1,2,3): + for l in (1, 2, 3): self.line_terminator_check(b'\n', l) def test_line_terminator2(self): # test two-character terminator - for l in (1,2,3): + for l in (1, 2, 3): self.line_terminator_check(b'\r\n', l) def test_line_terminator3(self): # test three-character terminator - for l in (1,2,3): + for l in (1, 2, 3): self.line_terminator_check(b'qqq', l) def numeric_terminator_check(self, termlen): @@ -249,18 +255,54 @@ def test_close_when_done(self): # (which could still result in the client not having received anything) self.assertGreater(len(s.buffer), 0) + def test_push(self): + # Issue #12523: push() should raise a TypeError if it doesn't get + # a bytes string + s, event = start_echo_server() + c = echo_client(b'\n', s.port) + data = b'bytes\n' + c.push(data) + c.push(bytearray(data)) + c.push(memoryview(data)) + self.assertRaises(TypeError, c.push, 10) + self.assertRaises(TypeError, c.push, 'unicode') + c.push(SERVER_QUIT) + asyncore.loop(use_poll=self.usepoll, count=300, timeout=.01) + s.join(timeout=TIMEOUT) + self.assertEqual(c.contents, [b'bytes', b'bytes', b'bytes']) + class TestAsynchat_WithPoll(TestAsynchat): usepoll = True + +class TestAsynchatMocked(unittest.TestCase): + def test_blockingioerror(self): + # Issue #16133: handle_read() must ignore BlockingIOError + sock = unittest.mock.Mock() + sock.recv.side_effect = BlockingIOError(errno.EAGAIN) + + dispatcher = asynchat.async_chat() + dispatcher.set_socket(sock) + self.addCleanup(dispatcher.del_channel) + + with unittest.mock.patch.object(dispatcher, 'handle_error') as error: + dispatcher.handle_read() + self.assertFalse(error.called) + + class TestHelperFunctions(unittest.TestCase): def test_find_prefix_at_end(self): self.assertEqual(asynchat.find_prefix_at_end("qwerty\r", "\r\n"), 1) self.assertEqual(asynchat.find_prefix_at_end("qwertydkjf", "\r\n"), 0) + class TestFifo(unittest.TestCase): def test_basic(self): - f = asynchat.fifo() + with self.assertWarns(DeprecationWarning) as cm: + f = asynchat.fifo() + self.assertEqual(str(cm.warning), + "fifo class will be removed in Python 3.6") f.push(7) f.push(b'a') self.assertEqual(len(f), 2) @@ -275,7 +317,10 @@ def test_basic(self): self.assertEqual(f.pop(), (0, None)) def test_given_list(self): - f = asynchat.fifo([b'x', 17, 3]) + with self.assertWarns(DeprecationWarning) as cm: + f = asynchat.fifo([b'x', 17, 3]) + self.assertEqual(str(cm.warning), + "fifo class will be removed in Python 3.6") self.assertEqual(len(f), 3) self.assertEqual(f.pop(), (1, b'x')) self.assertEqual(f.pop(), (1, 17)) @@ -283,5 +328,13 @@ def test_given_list(self): self.assertEqual(f.pop(), (0, None)) +class TestNotConnected(unittest.TestCase): + def test_disallow_negative_terminator(self): + # Issue #11259 + client = asynchat.async_chat() + self.assertRaises(ValueError, client.set_terminator, -1) + + + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_asyncio/__init__.py b/Lib/test/test_asyncio/__init__.py index 23ce5e805956..80a9eeaa8ead 100644 --- a/Lib/test/test_asyncio/__init__.py +++ b/Lib/test/test_asyncio/__init__.py @@ -1,31 +1,10 @@ import os -import sys -import unittest -from test.support import run_unittest, import_module +from test.support import load_package_tests, import_module # Skip tests if we don't have threading. import_module('threading') # Skip tests if we don't have concurrent.futures. import_module('concurrent.futures') - -def suite(): - tests_file = os.path.join(os.path.dirname(__file__), 'tests.txt') - with open(tests_file) as fp: - test_names = fp.read().splitlines() - tests = unittest.TestSuite() - loader = unittest.TestLoader() - for test_name in test_names: - mod_name = 'test.' + test_name - try: - __import__(mod_name) - except unittest.SkipTest: - pass - else: - mod = sys.modules[mod_name] - tests.addTests(loader.loadTestsFromModule(mod)) - return tests - - -def test_main(): - run_unittest(suite()) +def load_tests(*args): + return load_package_tests(os.path.dirname(__file__), *args) diff --git a/Lib/test/test_asyncio/__main__.py b/Lib/test/test_asyncio/__main__.py index b549492038fb..40a23a297ec2 100644 --- a/Lib/test/test_asyncio/__main__.py +++ b/Lib/test/test_asyncio/__main__.py @@ -1,5 +1,4 @@ -from . import test_main +from . import load_tests +import unittest - -if __name__ == '__main__': - test_main() +unittest.main() diff --git a/Lib/test/test_asyncio/keycert3.pem b/Lib/test/test_asyncio/keycert3.pem new file mode 100644 index 000000000000..5bfa62c4ca30 --- /dev/null +++ b/Lib/test/test_asyncio/keycert3.pem @@ -0,0 +1,73 @@ +-----BEGIN PRIVATE KEY----- +MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMLgD0kAKDb5cFyP +jbwNfR5CtewdXC+kMXAWD8DLxiTTvhMW7qVnlwOm36mZlszHKvsRf05lT4pegiFM +9z2j1OlaN+ci/X7NU22TNN6crYSiN77FjYJP464j876ndSxyD+rzys386T+1r1aZ +aggEdkj1TsSsv1zWIYKlPIjlvhuxAgMBAAECgYA0aH+T2Vf3WOPv8KdkcJg6gCRe +yJKXOWgWRcicx/CUzOEsTxmFIDPLxqAWA3k7v0B+3vjGw5Y9lycV/5XqXNoQI14j +y09iNsumds13u5AKkGdTJnZhQ7UKdoVHfuP44ZdOv/rJ5/VD6F4zWywpe90pcbK+ +AWDVtusgGQBSieEl1QJBAOyVrUG5l2yoUBtd2zr/kiGm/DYyXlIthQO/A3/LngDW +5/ydGxVsT7lAVOgCsoT+0L4efTh90PjzW8LPQrPBWVMCQQDS3h/FtYYd5lfz+FNL +9CEe1F1w9l8P749uNUD0g317zv1tatIqVCsQWHfVHNdVvfQ+vSFw38OORO00Xqs9 +1GJrAkBkoXXEkxCZoy4PteheO/8IWWLGGr6L7di6MzFl1lIqwT6D8L9oaV2vynFT +DnKop0pa09Unhjyw57KMNmSE2SUJAkEArloTEzpgRmCq4IK2/NpCeGdHS5uqRlbh +1VIa/xGps7EWQl5Mn8swQDel/YP3WGHTjfx7pgSegQfkyaRtGpZ9OQJAa9Vumj8m +JAAtI0Bnga8hgQx7BhTQY4CadDxyiRGOGYhwUzYVCqkb2sbVRH9HnwUaJT7cWBY3 +RnJdHOMXWem7/w== +-----END PRIVATE KEY----- +Certificate: + Data: + Version: 1 (0x0) + Serial Number: 12723342612721443281 (0xb09264b1f2da21d1) + Signature Algorithm: sha1WithRSAEncryption + Issuer: C=XY, O=Python Software Foundation CA, CN=our-ca-server + Validity + Not Before: Jan 4 19:47:07 2013 GMT + Not After : Nov 13 19:47:07 2022 GMT + Subject: C=XY, L=Castle Anthrax, O=Python Software Foundation, CN=localhost + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (1024 bit) + Modulus: + 00:c2:e0:0f:49:00:28:36:f9:70:5c:8f:8d:bc:0d: + 7d:1e:42:b5:ec:1d:5c:2f:a4:31:70:16:0f:c0:cb: + c6:24:d3:be:13:16:ee:a5:67:97:03:a6:df:a9:99: + 96:cc:c7:2a:fb:11:7f:4e:65:4f:8a:5e:82:21:4c: + f7:3d:a3:d4:e9:5a:37:e7:22:fd:7e:cd:53:6d:93: + 34:de:9c:ad:84:a2:37:be:c5:8d:82:4f:e3:ae:23: + f3:be:a7:75:2c:72:0f:ea:f3:ca:cd:fc:e9:3f:b5: + af:56:99:6a:08:04:76:48:f5:4e:c4:ac:bf:5c:d6: + 21:82:a5:3c:88:e5:be:1b:b1 + Exponent: 65537 (0x10001) + Signature Algorithm: sha1WithRSAEncryption + 2f:42:5f:a3:09:2c:fa:51:88:c7:37:7f:ea:0e:63:f0:a2:9a: + e5:5a:e2:c8:20:f0:3f:60:bc:c8:0f:b6:c6:76:ce:db:83:93: + f5:a3:33:67:01:8e:04:cd:00:9a:73:fd:f3:35:86:fa:d7:13: + e2:46:c6:9d:c0:29:53:d4:a9:90:b8:77:4b:e6:83:76:e4:92: + d6:9c:50:cf:43:d0:c6:01:77:61:9a:de:9b:70:f7:72:cd:59: + 00:31:69:d9:b4:ca:06:9c:6d:c3:c7:80:8c:68:e6:b5:a2:f8: + ef:1d:bb:16:9f:77:77:ef:87:62:22:9b:4d:69:a4:3a:1a:f1: + 21:5e:8c:32:ac:92:fd:15:6b:18:c2:7f:15:0d:98:30:ca:75: + 8f:1a:71:df:da:1d:b2:ef:9a:e8:2d:2e:02:fd:4a:3c:aa:96: + 0b:06:5d:35:b3:3d:24:87:4b:e0:b0:58:60:2f:45:ac:2e:48: + 8a:b0:99:10:65:27:ff:cc:b1:d8:fd:bd:26:6b:b9:0c:05:2a: + f4:45:63:35:51:07:ed:83:85:fe:6f:69:cb:bb:40:a8:ae:b6: + 3b:56:4a:2d:a4:ed:6d:11:2c:4d:ed:17:24:fd:47:bc:d3:41: + a2:d3:06:fe:0c:90:d8:d8:94:26:c4:ff:cc:a1:d8:42:77:eb: + fc:a9:94:71 +-----BEGIN CERTIFICATE----- +MIICpDCCAYwCCQCwkmSx8toh0TANBgkqhkiG9w0BAQUFADBNMQswCQYDVQQGEwJY +WTEmMCQGA1UECgwdUHl0aG9uIFNvZnR3YXJlIEZvdW5kYXRpb24gQ0ExFjAUBgNV +BAMMDW91ci1jYS1zZXJ2ZXIwHhcNMTMwMTA0MTk0NzA3WhcNMjIxMTEzMTk0NzA3 +WjBfMQswCQYDVQQGEwJYWTEXMBUGA1UEBxMOQ2FzdGxlIEFudGhyYXgxIzAhBgNV +BAoTGlB5dGhvbiBTb2Z0d2FyZSBGb3VuZGF0aW9uMRIwEAYDVQQDEwlsb2NhbGhv +c3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMLgD0kAKDb5cFyPjbwNfR5C +tewdXC+kMXAWD8DLxiTTvhMW7qVnlwOm36mZlszHKvsRf05lT4pegiFM9z2j1Ola +N+ci/X7NU22TNN6crYSiN77FjYJP464j876ndSxyD+rzys386T+1r1aZaggEdkj1 +TsSsv1zWIYKlPIjlvhuxAgMBAAEwDQYJKoZIhvcNAQEFBQADggEBAC9CX6MJLPpR +iMc3f+oOY/CimuVa4sgg8D9gvMgPtsZ2ztuDk/WjM2cBjgTNAJpz/fM1hvrXE+JG +xp3AKVPUqZC4d0vmg3bkktacUM9D0MYBd2Ga3ptw93LNWQAxadm0ygacbcPHgIxo +5rWi+O8duxafd3fvh2Iim01ppDoa8SFejDKskv0VaxjCfxUNmDDKdY8acd/aHbLv +mugtLgL9SjyqlgsGXTWzPSSHS+CwWGAvRawuSIqwmRBlJ//Msdj9vSZruQwFKvRF +YzVRB+2Dhf5vacu7QKiutjtWSi2k7W0RLE3tFyT9R7zTQaLTBv4MkNjYlCbE/8yh +2EJ36/yplHE= +-----END CERTIFICATE----- diff --git a/Lib/test/test_asyncio/pycacert.pem b/Lib/test/test_asyncio/pycacert.pem new file mode 100644 index 000000000000..09b1f3e08aee --- /dev/null +++ b/Lib/test/test_asyncio/pycacert.pem @@ -0,0 +1,78 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 12723342612721443280 (0xb09264b1f2da21d0) + Signature Algorithm: sha1WithRSAEncryption + Issuer: C=XY, O=Python Software Foundation CA, CN=our-ca-server + Validity + Not Before: Jan 4 19:47:07 2013 GMT + Not After : Jan 2 19:47:07 2023 GMT + Subject: C=XY, O=Python Software Foundation CA, CN=our-ca-server + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:e7:de:e9:e3:0c:9f:00:b6:a1:fd:2b:5b:96:d2: + 6f:cc:e0:be:86:b9:20:5e:ec:03:7a:55:ab:ea:a4: + e9:f9:49:85:d2:66:d5:ed:c7:7a:ea:56:8e:2d:8f: + e7:42:e2:62:28:a9:9f:d6:1b:8e:eb:b5:b4:9c:9f: + 14:ab:df:e6:94:8b:76:1d:3e:6d:24:61:ed:0c:bf: + 00:8a:61:0c:df:5c:c8:36:73:16:00:cd:47:ba:6d: + a4:a4:74:88:83:23:0a:19:fc:09:a7:3c:4a:4b:d3: + e7:1d:2d:e4:ea:4c:54:21:f3:26:db:89:37:18:d4: + 02:bb:40:32:5f:a4:ff:2d:1c:f7:d4:bb:ec:8e:cf: + 5c:82:ac:e6:7c:08:6c:48:85:61:07:7f:25:e0:5c: + e0:bc:34:5f:e0:b9:04:47:75:c8:47:0b:8d:bc:d6: + c8:68:5f:33:83:62:d2:20:44:35:b1:ad:81:1a:8a: + cd:bc:35:b0:5c:8b:47:d6:18:e9:9c:18:97:cc:01: + 3c:29:cc:e8:1e:e4:e4:c1:b8:de:e7:c2:11:18:87: + 5a:93:34:d8:a6:25:f7:14:71:eb:e4:21:a2:d2:0f: + 2e:2e:d4:62:00:35:d3:d6:ef:5c:60:4b:4c:a9:14: + e2:dd:15:58:46:37:33:26:b7:e7:2e:5d:ed:42:e4: + c5:4d + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Key Identifier: + BC:DD:62:D9:76:DA:1B:D2:54:6B:CF:E0:66:9B:1E:1E:7B:56:0C:0B + X509v3 Authority Key Identifier: + keyid:BC:DD:62:D9:76:DA:1B:D2:54:6B:CF:E0:66:9B:1E:1E:7B:56:0C:0B + + X509v3 Basic Constraints: + CA:TRUE + Signature Algorithm: sha1WithRSAEncryption + 7d:0a:f5:cb:8d:d3:5d:bd:99:8e:f8:2b:0f:ba:eb:c2:d9:a6: + 27:4f:2e:7b:2f:0e:64:d8:1c:35:50:4e:ee:fc:90:b9:8d:6d: + a8:c5:c6:06:b0:af:f3:2d:bf:3b:b8:42:07:dd:18:7d:6d:95: + 54:57:85:18:60:47:2f:eb:78:1b:f9:e8:17:fd:5a:0d:87:17: + 28:ac:4c:6a:e6:bc:29:f4:f4:55:70:29:42:de:85:ea:ab:6c: + 23:06:64:30:75:02:8e:53:bc:5e:01:33:37:cc:1e:cd:b8:a4: + fd:ca:e4:5f:65:3b:83:1c:86:f1:55:02:a0:3a:8f:db:91:b7: + 40:14:b4:e7:8d:d2:ee:73:ba:e3:e5:34:2d:bc:94:6f:4e:24: + 06:f7:5f:8b:0e:a7:8e:6b:de:5e:75:f4:32:9a:50:b1:44:33: + 9a:d0:05:e2:78:82:ff:db:da:8a:63:eb:a9:dd:d1:bf:a0:61: + ad:e3:9e:8a:24:5d:62:0e:e7:4c:91:7f:ef:df:34:36:3b:2f: + 5d:f5:84:b2:2f:c4:6d:93:96:1a:6f:30:28:f1:da:12:9a:64: + b4:40:33:1d:bd:de:2b:53:a8:ea:be:d6:bc:4e:96:f5:44:fb: + 32:18:ae:d5:1f:f6:69:af:b6:4e:7b:1d:58:ec:3b:a9:53:a3: + 5e:58:c8:9e +-----BEGIN CERTIFICATE----- +MIIDbTCCAlWgAwIBAgIJALCSZLHy2iHQMA0GCSqGSIb3DQEBBQUAME0xCzAJBgNV +BAYTAlhZMSYwJAYDVQQKDB1QeXRob24gU29mdHdhcmUgRm91bmRhdGlvbiBDQTEW +MBQGA1UEAwwNb3VyLWNhLXNlcnZlcjAeFw0xMzAxMDQxOTQ3MDdaFw0yMzAxMDIx +OTQ3MDdaME0xCzAJBgNVBAYTAlhZMSYwJAYDVQQKDB1QeXRob24gU29mdHdhcmUg +Rm91bmRhdGlvbiBDQTEWMBQGA1UEAwwNb3VyLWNhLXNlcnZlcjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAOfe6eMMnwC2of0rW5bSb8zgvoa5IF7sA3pV +q+qk6flJhdJm1e3HeupWji2P50LiYiipn9Ybjuu1tJyfFKvf5pSLdh0+bSRh7Qy/ +AIphDN9cyDZzFgDNR7ptpKR0iIMjChn8Cac8SkvT5x0t5OpMVCHzJtuJNxjUArtA +Ml+k/y0c99S77I7PXIKs5nwIbEiFYQd/JeBc4Lw0X+C5BEd1yEcLjbzWyGhfM4Ni +0iBENbGtgRqKzbw1sFyLR9YY6ZwYl8wBPCnM6B7k5MG43ufCERiHWpM02KYl9xRx +6+QhotIPLi7UYgA109bvXGBLTKkU4t0VWEY3Mya35y5d7ULkxU0CAwEAAaNQME4w +HQYDVR0OBBYEFLzdYtl22hvSVGvP4GabHh57VgwLMB8GA1UdIwQYMBaAFLzdYtl2 +2hvSVGvP4GabHh57VgwLMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEB +AH0K9cuN0129mY74Kw+668LZpidPLnsvDmTYHDVQTu78kLmNbajFxgawr/Mtvzu4 +QgfdGH1tlVRXhRhgRy/reBv56Bf9Wg2HFyisTGrmvCn09FVwKULeheqrbCMGZDB1 +Ao5TvF4BMzfMHs24pP3K5F9lO4MchvFVAqA6j9uRt0AUtOeN0u5zuuPlNC28lG9O +JAb3X4sOp45r3l519DKaULFEM5rQBeJ4gv/b2opj66nd0b+gYa3jnookXWIO50yR +f+/fNDY7L131hLIvxG2TlhpvMCjx2hKaZLRAMx293itTqOq+1rxOlvVE+zIYrtUf +9mmvtk57HVjsO6lTo15YyJ4= +-----END CERTIFICATE----- diff --git a/Lib/test/test_asyncio/sample.crt b/Lib/test/test_asyncio/sample.crt deleted file mode 100644 index 6a1e3f3c2e76..000000000000 --- a/Lib/test/test_asyncio/sample.crt +++ /dev/null @@ -1,14 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICMzCCAZwCCQDFl4ys0fU7iTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJV -UzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuLUZyYW5jaXNjbzEi -MCAGA1UECgwZUHl0aG9uIFNvZnR3YXJlIEZvbmRhdGlvbjAeFw0xMzAzMTgyMDA3 -MjhaFw0yMzAzMTYyMDA3MjhaMF4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp -Zm9ybmlhMRYwFAYDVQQHDA1TYW4tRnJhbmNpc2NvMSIwIAYDVQQKDBlQeXRob24g -U29mdHdhcmUgRm9uZGF0aW9uMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCn -t3s+J7L0xP/YdAQOacpPi9phlrzKZhcXL3XMu2LCUg2fNJpx/47Vc5TZSaO11uO7 -gdwVz3Z7Q2epAgwo59JLffLt5fia8+a/SlPweI/j4+wcIIIiqusnLfpqR8cIAavg -Z06cLYCDvb9wMlheIvSJY12skc1nnphWS2YJ0Xm6uQIDAQABMA0GCSqGSIb3DQEB -BQUAA4GBAE9PknG6pv72+5z/gsDGYy8sK5UNkbWSNr4i4e5lxVsF03+/M71H+3AB -MxVX4+A+Vlk2fmU+BrdHIIUE0r1dDcO3josQ9hc9OJpp5VLSQFP8VeuJCmzYPp9I -I8WbW93cnXnChTrYQVdgVoFdv7GE9YgU7NYkrGIM0nZl1/f/bHPB ------END CERTIFICATE----- diff --git a/Lib/test/test_asyncio/sample.key b/Lib/test/test_asyncio/sample.key deleted file mode 100644 index edfea8dcab3d..000000000000 --- a/Lib/test/test_asyncio/sample.key +++ /dev/null @@ -1,15 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIICXQIBAAKBgQCnt3s+J7L0xP/YdAQOacpPi9phlrzKZhcXL3XMu2LCUg2fNJpx -/47Vc5TZSaO11uO7gdwVz3Z7Q2epAgwo59JLffLt5fia8+a/SlPweI/j4+wcIIIi -qusnLfpqR8cIAavgZ06cLYCDvb9wMlheIvSJY12skc1nnphWS2YJ0Xm6uQIDAQAB -AoGABfm8k19Yue3W68BecKEGS0VBV57GRTPT+MiBGvVGNIQ15gk6w3sGfMZsdD1y -bsUkQgcDb2d/4i5poBTpl/+Cd41V+c20IC/sSl5X1IEreHMKSLhy/uyjyiyfXlP1 -iXhToFCgLWwENWc8LzfUV8vuAV5WG6oL9bnudWzZxeqx8V0CQQDR7xwVj6LN70Eb -DUhSKLkusmFw5Gk9NJ/7wZ4eHg4B8c9KNVvSlLCLhcsVTQXuqYeFpOqytI45SneP -lr0vrvsDAkEAzITYiXu6ox5huDCG7imX2W9CAYuX638urLxBqBXMS7GqBzojD6RL -21Q8oPwJWJquERa3HDScq1deiQbM9uKIkwJBAIa1PLslGN216Xv3UPHPScyKD/aF -ynXIv+OnANPoiyp6RH4ksQ/18zcEGiVH8EeNpvV9tlAHhb+DZibQHgNr74sCQQC0 -zhToplu/bVKSlUQUNO0rqrI9z30FErDewKeCw5KSsIRSU1E/uM3fHr9iyq4wiL6u -GNjUtKZ0y46lsT9uW6LFAkB5eqeEQnshAdr3X5GykWHJ8DDGBXPPn6Rce1NX4RSq -V9khG2z1bFyfo+hMqpYnF2k32hVq3E54RS8YYnwBsVof ------END RSA PRIVATE KEY----- diff --git a/Lib/test/test_asyncio/ssl_cert.pem b/Lib/test/test_asyncio/ssl_cert.pem new file mode 100644 index 000000000000..47a7d7e37e80 --- /dev/null +++ b/Lib/test/test_asyncio/ssl_cert.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICVDCCAb2gAwIBAgIJANfHOBkZr8JOMA0GCSqGSIb3DQEBBQUAMF8xCzAJBgNV +BAYTAlhZMRcwFQYDVQQHEw5DYXN0bGUgQW50aHJheDEjMCEGA1UEChMaUHl0aG9u +IFNvZnR3YXJlIEZvdW5kYXRpb24xEjAQBgNVBAMTCWxvY2FsaG9zdDAeFw0xMDEw +MDgyMzAxNTZaFw0yMDEwMDUyMzAxNTZaMF8xCzAJBgNVBAYTAlhZMRcwFQYDVQQH +Ew5DYXN0bGUgQW50aHJheDEjMCEGA1UEChMaUHl0aG9uIFNvZnR3YXJlIEZvdW5k +YXRpb24xEjAQBgNVBAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAw +gYkCgYEA21vT5isq7F68amYuuNpSFlKDPrMUCa4YWYqZRt2OZ+/3NKaZ2xAiSwr7 +6MrQF70t5nLbSPpqE5+5VrS58SY+g/sXLiFd6AplH1wJZwh78DofbFYXUggktFMt +pTyiX8jtP66bkcPkDADA089RI1TQR6Ca+n7HFa7c1fabVV6i3zkCAwEAAaMYMBYw +FAYDVR0RBA0wC4IJbG9jYWxob3N0MA0GCSqGSIb3DQEBBQUAA4GBAHPctQBEQ4wd +BJ6+JcpIraopLn8BGhbjNWj40mmRqWB/NAWF6M5ne7KpGAu7tLeG4hb1zLaldK8G +lxy2GPSRF6LFS48dpEj2HbMv2nvv6xxalDMJ9+DicWgAKTQ6bcX2j3GUkCR0g/T1 +CRlNBAAlvhKzO7Clpf9l0YKBEfraJByX +-----END CERTIFICATE----- diff --git a/Lib/test/test_asyncio/ssl_key.pem b/Lib/test/test_asyncio/ssl_key.pem new file mode 100644 index 000000000000..3fd3bbd54a34 --- /dev/null +++ b/Lib/test/test_asyncio/ssl_key.pem @@ -0,0 +1,16 @@ +-----BEGIN PRIVATE KEY----- +MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBANtb0+YrKuxevGpm +LrjaUhZSgz6zFAmuGFmKmUbdjmfv9zSmmdsQIksK++jK0Be9LeZy20j6ahOfuVa0 +ufEmPoP7Fy4hXegKZR9cCWcIe/A6H2xWF1IIJLRTLaU8ol/I7T+um5HD5AwAwNPP +USNU0Eegmvp+xxWu3NX2m1Veot85AgMBAAECgYA3ZdZ673X0oexFlq7AAmrutkHt +CL7LvwrpOiaBjhyTxTeSNWzvtQBkIU8DOI0bIazA4UreAFffwtvEuPmonDb3F+Iq +SMAu42XcGyVZEl+gHlTPU9XRX7nTOXVt+MlRRRxL6t9GkGfUAXI3XxJDXW3c0vBK +UL9xqD8cORXOfE06rQJBAP8mEX1ERkR64Ptsoe4281vjTlNfIbs7NMPkUnrn9N/Y +BLhjNIfQ3HFZG8BTMLfX7kCS9D593DW5tV4Z9BP/c6cCQQDcFzCcVArNh2JSywOQ +ZfTfRbJg/Z5Lt9Fkngv1meeGNPgIMLN8Sg679pAOOWmzdMO3V706rNPzSVMME7E5 +oPIfAkEA8pDddarP5tCvTTgUpmTFbakm0KoTZm2+FzHcnA4jRh+XNTjTOv98Y6Ik +eO5d1ZnKXseWvkZncQgxfdnMqqpj5wJAcNq/RVne1DbYlwWchT2Si65MYmmJ8t+F +0mcsULqjOnEMwf5e+ptq5LzwbyrHZYq5FNk7ocufPv/ZQrcSSC+cFwJBAKvOJByS +x56qyGeZLOQlWS2JS3KJo59XuLFGqcbgN9Om9xFa41Yb4N9NvplFivsvZdw3m1Q/ +SPIXQuT8RMPDVNQ= +-----END PRIVATE KEY----- diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py index 96f29750c721..9e7c50cc1713 100644 --- a/Lib/test/test_asyncio/test_base_events.py +++ b/Lib/test/test_asyncio/test_base_events.py @@ -2,30 +2,40 @@ import errno import logging +import math import socket +import sys +import threading import time import unittest -import unittest.mock -from test.support import find_unused_port, IPV6_ENABLED +from unittest import mock +import asyncio from asyncio import base_events from asyncio import constants -from asyncio import events -from asyncio import futures -from asyncio import protocols -from asyncio import tasks from asyncio import test_utils +try: + from test import support + from test.script_helper import assert_python_ok +except ImportError: + from asyncio import test_support as support + from asyncio.test_support import assert_python_ok -class BaseEventLoopTests(unittest.TestCase): +MOCK_ANY = mock.ANY +PY34 = sys.version_info >= (3, 4) + + +class BaseEventLoopTests(test_utils.TestCase): def setUp(self): self.loop = base_events.BaseEventLoop() - self.loop._selector = unittest.mock.Mock() - events.set_event_loop(None) + self.loop._selector = mock.Mock() + self.loop._selector.select.return_value = () + self.set_event_loop(self.loop) def test_not_implemented(self): - m = unittest.mock.Mock() + m = mock.Mock() self.assertRaises( NotImplementedError, self.loop._make_socket_transport, m, m) @@ -39,8 +49,6 @@ def test_not_implemented(self): NotImplementedError, self.loop._process_events, []) self.assertRaises( NotImplementedError, self.loop._write_to_self) - self.assertRaises( - NotImplementedError, self.loop._read_from_self) self.assertRaises( NotImplementedError, self.loop._make_read_pipe_transport, m, m) @@ -50,21 +58,29 @@ def test_not_implemented(self): gen = self.loop._make_subprocess_transport(m, m, m, m, m, m, m) self.assertRaises(NotImplementedError, next, iter(gen)) + def test_close(self): + self.assertFalse(self.loop.is_closed()) + self.loop.close() + self.assertTrue(self.loop.is_closed()) + + # it should be possible to call close() more than once + self.loop.close() + self.loop.close() + + # operation blocked when the loop is closed + f = asyncio.Future(loop=self.loop) + self.assertRaises(RuntimeError, self.loop.run_forever) + self.assertRaises(RuntimeError, self.loop.run_until_complete, f) + def test__add_callback_handle(self): - h = events.Handle(lambda: False, ()) + h = asyncio.Handle(lambda: False, (), self.loop) self.loop._add_callback(h) self.assertFalse(self.loop._scheduled) self.assertIn(h, self.loop._ready) - def test__add_callback_timer(self): - h = events.TimerHandle(time.monotonic()+10, lambda: False, ()) - - self.loop._add_callback(h) - self.assertIn(h, self.loop._scheduled) - def test__add_callback_cancelled_handle(self): - h = events.Handle(lambda: False, ()) + h = asyncio.Handle(lambda: False, (), self.loop) h.cancel() self.loop._add_callback(h) @@ -72,13 +88,13 @@ def test__add_callback_cancelled_handle(self): self.assertFalse(self.loop._ready) def test_set_default_executor(self): - executor = unittest.mock.Mock() + executor = mock.Mock() self.loop.set_default_executor(executor) self.assertIs(executor, self.loop._default_executor) def test_getnameinfo(self): - sockaddr = unittest.mock.Mock() - self.loop.run_in_executor = unittest.mock.Mock() + sockaddr = mock.Mock() + self.loop.run_in_executor = mock.Mock() self.loop.getnameinfo(sockaddr) self.assertEqual( (None, socket.getnameinfo, sockaddr, 0), @@ -90,7 +106,7 @@ def cb(): h = self.loop.call_soon(cb) self.assertEqual(h._callback, cb) - self.assertIsInstance(h, events.Handle) + self.assertIsInstance(h, asyncio.Handle) self.assertIn(h, self.loop._ready) def test_call_later(self): @@ -98,7 +114,7 @@ def cb(): pass h = self.loop.call_later(10.0, cb) - self.assertIsInstance(h, events.TimerHandle) + self.assertIsInstance(h, asyncio.TimerHandle) self.assertIn(h, self.loop._scheduled) self.assertNotIn(h, self.loop._ready) @@ -108,7 +124,7 @@ def test_call_later_negative_delays(self): def cb(arg): calls.append(arg) - self.loop._process_events = unittest.mock.Mock() + self.loop._process_events = mock.Mock() self.loop.call_later(-1, cb, 'a') self.loop.call_later(-2, cb, 'b') test_utils.run_briefly(self.loop) @@ -118,13 +134,86 @@ def test_time_and_call_at(self): def cb(): self.loop.stop() - self.loop._process_events = unittest.mock.Mock() - when = self.loop.time() + 0.1 + self.loop._process_events = mock.Mock() + delay = 0.1 + + when = self.loop.time() + delay self.loop.call_at(when, cb) t0 = self.loop.time() self.loop.run_forever() - t1 = self.loop.time() - self.assertTrue(0.09 <= t1-t0 <= 0.9, t1-t0) + dt = self.loop.time() - t0 + + # 50 ms: maximum granularity of the event loop + self.assertGreaterEqual(dt, delay - 0.050, dt) + # tolerate a difference of +800 ms because some Python buildbots + # are really slow + self.assertLessEqual(dt, 0.9, dt) + + def check_thread(self, loop, debug): + def cb(): + pass + + loop.set_debug(debug) + if debug: + msg = ("Non-thread-safe operation invoked on an event loop other " + "than the current one") + with self.assertRaisesRegex(RuntimeError, msg): + loop.call_soon(cb) + with self.assertRaisesRegex(RuntimeError, msg): + loop.call_later(60, cb) + with self.assertRaisesRegex(RuntimeError, msg): + loop.call_at(loop.time() + 60, cb) + else: + loop.call_soon(cb) + loop.call_later(60, cb) + loop.call_at(loop.time() + 60, cb) + + def test_check_thread(self): + def check_in_thread(loop, event, debug, create_loop, fut): + # wait until the event loop is running + event.wait() + + try: + if create_loop: + loop2 = base_events.BaseEventLoop() + try: + asyncio.set_event_loop(loop2) + self.check_thread(loop, debug) + finally: + asyncio.set_event_loop(None) + loop2.close() + else: + self.check_thread(loop, debug) + except Exception as exc: + loop.call_soon_threadsafe(fut.set_exception, exc) + else: + loop.call_soon_threadsafe(fut.set_result, None) + + def test_thread(loop, debug, create_loop=False): + event = threading.Event() + fut = asyncio.Future(loop=loop) + loop.call_soon(event.set) + args = (loop, event, debug, create_loop, fut) + thread = threading.Thread(target=check_in_thread, args=args) + thread.start() + loop.run_until_complete(fut) + thread.join() + + self.loop._process_events = mock.Mock() + self.loop._write_to_self = mock.Mock() + + # raise RuntimeError if the thread has no event loop + test_thread(self.loop, True) + + # check disabled if debug mode is disabled + test_thread(self.loop, False) + + # raise RuntimeError if the event loop of the thread is not the called + # event loop + test_thread(self.loop, True, create_loop=True) + + # check disabled if debug mode is disabled + test_thread(self.loop, False, create_loop=True) def test_run_once_in_executor_handle(self): def cb(): @@ -132,28 +221,28 @@ def cb(): self.assertRaises( AssertionError, self.loop.run_in_executor, - None, events.Handle(cb, ()), ('',)) + None, asyncio.Handle(cb, (), self.loop), ('',)) self.assertRaises( AssertionError, self.loop.run_in_executor, - None, events.TimerHandle(10, cb, ())) + None, asyncio.TimerHandle(10, cb, (), self.loop)) def test_run_once_in_executor_cancelled(self): def cb(): pass - h = events.Handle(cb, ()) + h = asyncio.Handle(cb, (), self.loop) h.cancel() f = self.loop.run_in_executor(None, h) - self.assertIsInstance(f, futures.Future) + self.assertIsInstance(f, asyncio.Future) self.assertTrue(f.done()) self.assertIsNone(f.result()) def test_run_once_in_executor_plain(self): def cb(): pass - h = events.Handle(cb, ()) - f = futures.Future(loop=self.loop) - executor = unittest.mock.Mock() + h = asyncio.Handle(cb, (), self.loop) + f = asyncio.Future(loop=self.loop) + executor = mock.Mock() executor.submit.return_value = f self.loop.set_default_executor(executor) @@ -161,7 +250,7 @@ def cb(): res = self.loop.run_in_executor(None, h) self.assertIs(f, res) - executor = unittest.mock.Mock() + executor = mock.Mock() executor.submit.return_value = f res = self.loop.run_in_executor(executor, h) self.assertIs(f, res) @@ -170,12 +259,14 @@ def cb(): f.cancel() # Don't complain about abandoned Future. def test__run_once(self): - h1 = events.TimerHandle(time.monotonic() + 5.0, lambda: True, ()) - h2 = events.TimerHandle(time.monotonic() + 10.0, lambda: True, ()) + h1 = asyncio.TimerHandle(time.monotonic() + 5.0, lambda: True, (), + self.loop) + h2 = asyncio.TimerHandle(time.monotonic() + 10.0, lambda: True, (), + self.loop) h1.cancel() - self.loop._process_events = unittest.mock.Mock() + self.loop._process_events = mock.Mock() self.loop._scheduled.append(h1) self.loop._scheduled.append(h2) self.loop._run_once() @@ -185,33 +276,36 @@ def test__run_once(self): self.assertEqual([h2], self.loop._scheduled) self.assertTrue(self.loop._process_events.called) - @unittest.mock.patch('asyncio.base_events.time') - @unittest.mock.patch('asyncio.base_events.logger') - def test__run_once_logging(self, m_logging, m_time): - # Log to INFO level if timeout > 1.0 sec. - idx = -1 - data = [10.0, 10.0, 12.0, 13.0] + def test_set_debug(self): + self.loop.set_debug(True) + self.assertTrue(self.loop.get_debug()) + self.loop.set_debug(False) + self.assertFalse(self.loop.get_debug()) - def monotonic(): - nonlocal data, idx - idx += 1 - return data[idx] + @mock.patch('asyncio.base_events.logger') + def test__run_once_logging(self, m_logger): + def slow_select(timeout): + # Sleep a bit longer than a second to avoid timer resolution + # issues. + time.sleep(1.1) + return [] - m_time.monotonic = monotonic - m_logging.INFO = logging.INFO - m_logging.DEBUG = logging.DEBUG + # logging needs debug flag + self.loop.set_debug(True) - self.loop._scheduled.append( - events.TimerHandle(11.0, lambda: True, ())) - self.loop._process_events = unittest.mock.Mock() + # Log to INFO level if timeout > 1.0 sec. + self.loop._selector.select = slow_select + self.loop._process_events = mock.Mock() self.loop._run_once() - self.assertEqual(logging.INFO, m_logging.log.call_args[0][0]) + self.assertEqual(logging.INFO, m_logger.log.call_args[0][0]) - idx = -1 - data = [10.0, 10.0, 10.3, 13.0] - self.loop._scheduled = [events.TimerHandle(11.0, lambda:True, ())] + def fast_select(timeout): + time.sleep(0.001) + return [] + + self.loop._selector.select = fast_select self.loop._run_once() - self.assertEqual(logging.DEBUG, m_logging.log.call_args[0][0]) + self.assertEqual(logging.DEBUG, m_logger.log.call_args[0][0]) def test__run_once_schedule_handle(self): handle = None @@ -222,28 +316,413 @@ def cb(loop): processed = True handle = loop.call_soon(lambda: True) - h = events.TimerHandle(time.monotonic() - 1, cb, (self.loop,)) + h = asyncio.TimerHandle(time.monotonic() - 1, cb, (self.loop,), + self.loop) - self.loop._process_events = unittest.mock.Mock() + self.loop._process_events = mock.Mock() self.loop._scheduled.append(h) self.loop._run_once() self.assertTrue(processed) self.assertEqual([handle], list(self.loop._ready)) + def test__run_once_cancelled_event_cleanup(self): + self.loop._process_events = mock.Mock() + + self.assertTrue( + 0 < base_events._MIN_CANCELLED_TIMER_HANDLES_FRACTION < 1.0) + + def cb(): + pass + + # Set up one "blocking" event that will not be cancelled to + # ensure later cancelled events do not make it to the head + # of the queue and get cleaned. + not_cancelled_count = 1 + self.loop.call_later(3000, cb) + + # Add less than threshold (base_events._MIN_SCHEDULED_TIMER_HANDLES) + # cancelled handles, ensure they aren't removed + + cancelled_count = 2 + for x in range(2): + h = self.loop.call_later(3600, cb) + h.cancel() + + # Add some cancelled events that will be at head and removed + cancelled_count += 2 + for x in range(2): + h = self.loop.call_later(100, cb) + h.cancel() + + # This test is invalid if _MIN_SCHEDULED_TIMER_HANDLES is too low + self.assertLessEqual(cancelled_count + not_cancelled_count, + base_events._MIN_SCHEDULED_TIMER_HANDLES) + + self.assertEqual(self.loop._timer_cancelled_count, cancelled_count) + + self.loop._run_once() + + cancelled_count -= 2 + + self.assertEqual(self.loop._timer_cancelled_count, cancelled_count) + + self.assertEqual(len(self.loop._scheduled), + cancelled_count + not_cancelled_count) + + # Need enough events to pass _MIN_CANCELLED_TIMER_HANDLES_FRACTION + # so that deletion of cancelled events will occur on next _run_once + add_cancel_count = int(math.ceil( + base_events._MIN_SCHEDULED_TIMER_HANDLES * + base_events._MIN_CANCELLED_TIMER_HANDLES_FRACTION)) + 1 + + add_not_cancel_count = max(base_events._MIN_SCHEDULED_TIMER_HANDLES - + add_cancel_count, 0) + + # Add some events that will not be cancelled + not_cancelled_count += add_not_cancel_count + for x in range(add_not_cancel_count): + self.loop.call_later(3600, cb) + + # Add enough cancelled events + cancelled_count += add_cancel_count + for x in range(add_cancel_count): + h = self.loop.call_later(3600, cb) + h.cancel() + + # Ensure all handles are still scheduled + self.assertEqual(len(self.loop._scheduled), + cancelled_count + not_cancelled_count) + + self.loop._run_once() + + # Ensure cancelled events were removed + self.assertEqual(len(self.loop._scheduled), not_cancelled_count) + + # Ensure only uncancelled events remain scheduled + self.assertTrue(all([not x._cancelled for x in self.loop._scheduled])) + def test_run_until_complete_type_error(self): - self.assertRaises( - TypeError, self.loop.run_until_complete, 'blah') + self.assertRaises(TypeError, + self.loop.run_until_complete, 'blah') + + def test_run_until_complete_loop(self): + task = asyncio.Future(loop=self.loop) + other_loop = self.new_test_loop() + self.addCleanup(other_loop.close) + self.assertRaises(ValueError, + other_loop.run_until_complete, task) + + def test_subprocess_exec_invalid_args(self): + args = [sys.executable, '-c', 'pass'] + + # missing program parameter (empty args) + self.assertRaises(TypeError, + self.loop.run_until_complete, self.loop.subprocess_exec, + asyncio.SubprocessProtocol) + + # expected multiple arguments, not a list + self.assertRaises(TypeError, + self.loop.run_until_complete, self.loop.subprocess_exec, + asyncio.SubprocessProtocol, args) + + # program arguments must be strings, not int + self.assertRaises(TypeError, + self.loop.run_until_complete, self.loop.subprocess_exec, + asyncio.SubprocessProtocol, sys.executable, 123) + + # universal_newlines, shell, bufsize must not be set + self.assertRaises(TypeError, + self.loop.run_until_complete, self.loop.subprocess_exec, + asyncio.SubprocessProtocol, *args, universal_newlines=True) + self.assertRaises(TypeError, + self.loop.run_until_complete, self.loop.subprocess_exec, + asyncio.SubprocessProtocol, *args, shell=True) + self.assertRaises(TypeError, + self.loop.run_until_complete, self.loop.subprocess_exec, + asyncio.SubprocessProtocol, *args, bufsize=4096) + + def test_subprocess_shell_invalid_args(self): + # expected a string, not an int or a list + self.assertRaises(TypeError, + self.loop.run_until_complete, self.loop.subprocess_shell, + asyncio.SubprocessProtocol, 123) + self.assertRaises(TypeError, + self.loop.run_until_complete, self.loop.subprocess_shell, + asyncio.SubprocessProtocol, [sys.executable, '-c', 'pass']) + + # universal_newlines, shell, bufsize must not be set + self.assertRaises(TypeError, + self.loop.run_until_complete, self.loop.subprocess_shell, + asyncio.SubprocessProtocol, 'exit 0', universal_newlines=True) + self.assertRaises(TypeError, + self.loop.run_until_complete, self.loop.subprocess_shell, + asyncio.SubprocessProtocol, 'exit 0', shell=True) + self.assertRaises(TypeError, + self.loop.run_until_complete, self.loop.subprocess_shell, + asyncio.SubprocessProtocol, 'exit 0', bufsize=4096) + + def test_default_exc_handler_callback(self): + self.loop._process_events = mock.Mock() + + def zero_error(fut): + fut.set_result(True) + 1/0 + + # Test call_soon (events.Handle) + with mock.patch('asyncio.base_events.logger') as log: + fut = asyncio.Future(loop=self.loop) + self.loop.call_soon(zero_error, fut) + fut.add_done_callback(lambda fut: self.loop.stop()) + self.loop.run_forever() + log.error.assert_called_with( + test_utils.MockPattern('Exception in callback.*zero'), + exc_info=(ZeroDivisionError, MOCK_ANY, MOCK_ANY)) + + # Test call_later (events.TimerHandle) + with mock.patch('asyncio.base_events.logger') as log: + fut = asyncio.Future(loop=self.loop) + self.loop.call_later(0.01, zero_error, fut) + fut.add_done_callback(lambda fut: self.loop.stop()) + self.loop.run_forever() + log.error.assert_called_with( + test_utils.MockPattern('Exception in callback.*zero'), + exc_info=(ZeroDivisionError, MOCK_ANY, MOCK_ANY)) + + def test_default_exc_handler_coro(self): + self.loop._process_events = mock.Mock() + + @asyncio.coroutine + def zero_error_coro(): + yield from asyncio.sleep(0.01, loop=self.loop) + 1/0 + + # Test Future.__del__ + with mock.patch('asyncio.base_events.logger') as log: + fut = asyncio.async(zero_error_coro(), loop=self.loop) + fut.add_done_callback(lambda *args: self.loop.stop()) + self.loop.run_forever() + fut = None # Trigger Future.__del__ or futures._TracebackLogger + if PY34: + # Future.__del__ in Python 3.4 logs error with + # an actual exception context + log.error.assert_called_with( + test_utils.MockPattern('.*exception was never retrieved'), + exc_info=(ZeroDivisionError, MOCK_ANY, MOCK_ANY)) + else: + # futures._TracebackLogger logs only textual traceback + log.error.assert_called_with( + test_utils.MockPattern( + '.*exception was never retrieved.*ZeroDiv'), + exc_info=False) + + def test_set_exc_handler_invalid(self): + with self.assertRaisesRegex(TypeError, 'A callable object or None'): + self.loop.set_exception_handler('spam') + + def test_set_exc_handler_custom(self): + def zero_error(): + 1/0 + + def run_loop(): + handle = self.loop.call_soon(zero_error) + self.loop._run_once() + return handle + + self.loop.set_debug(True) + self.loop._process_events = mock.Mock() + + mock_handler = mock.Mock() + self.loop.set_exception_handler(mock_handler) + handle = run_loop() + mock_handler.assert_called_with(self.loop, { + 'exception': MOCK_ANY, + 'message': test_utils.MockPattern( + 'Exception in callback.*zero_error'), + 'handle': handle, + 'source_traceback': handle._source_traceback, + }) + mock_handler.reset_mock() + + self.loop.set_exception_handler(None) + with mock.patch('asyncio.base_events.logger') as log: + run_loop() + log.error.assert_called_with( + test_utils.MockPattern( + 'Exception in callback.*zero'), + exc_info=(ZeroDivisionError, MOCK_ANY, MOCK_ANY)) + + assert not mock_handler.called + + def test_set_exc_handler_broken(self): + def run_loop(): + def zero_error(): + 1/0 + self.loop.call_soon(zero_error) + self.loop._run_once() + + def handler(loop, context): + raise AttributeError('spam') + + self.loop._process_events = mock.Mock() + + self.loop.set_exception_handler(handler) + + with mock.patch('asyncio.base_events.logger') as log: + run_loop() + log.error.assert_called_with( + test_utils.MockPattern( + 'Unhandled error in exception handler'), + exc_info=(AttributeError, MOCK_ANY, MOCK_ANY)) + + def test_default_exc_handler_broken(self): + _context = None + + class Loop(base_events.BaseEventLoop): + + _selector = mock.Mock() + _process_events = mock.Mock() + + def default_exception_handler(self, context): + nonlocal _context + _context = context + # Simulates custom buggy "default_exception_handler" + raise ValueError('spam') + + loop = Loop() + self.addCleanup(loop.close) + asyncio.set_event_loop(loop) + + def run_loop(): + def zero_error(): + 1/0 + loop.call_soon(zero_error) + loop._run_once() + + with mock.patch('asyncio.base_events.logger') as log: + run_loop() + log.error.assert_called_with( + 'Exception in default exception handler', + exc_info=True) + + def custom_handler(loop, context): + raise ValueError('ham') + + _context = None + loop.set_exception_handler(custom_handler) + with mock.patch('asyncio.base_events.logger') as log: + run_loop() + log.error.assert_called_with( + test_utils.MockPattern('Exception in default exception.*' + 'while handling.*in custom'), + exc_info=True) + + # Check that original context was passed to default + # exception handler. + self.assertIn('context', _context) + self.assertIs(type(_context['context']['exception']), + ZeroDivisionError) + + def test_env_var_debug(self): + code = '\n'.join(( + 'import asyncio', + 'loop = asyncio.get_event_loop()', + 'print(loop.get_debug())')) + + # Test with -E to not fail if the unit test was run with + # PYTHONASYNCIODEBUG set to a non-empty string + sts, stdout, stderr = assert_python_ok('-E', '-c', code) + self.assertEqual(stdout.rstrip(), b'False') + + sts, stdout, stderr = assert_python_ok('-c', code, + PYTHONASYNCIODEBUG='') + self.assertEqual(stdout.rstrip(), b'False') + + sts, stdout, stderr = assert_python_ok('-c', code, + PYTHONASYNCIODEBUG='1') + self.assertEqual(stdout.rstrip(), b'True') + + sts, stdout, stderr = assert_python_ok('-E', '-c', code, + PYTHONASYNCIODEBUG='1') + self.assertEqual(stdout.rstrip(), b'False') + + def test_create_task(self): + class MyTask(asyncio.Task): + pass + + @asyncio.coroutine + def test(): + pass + + class EventLoop(base_events.BaseEventLoop): + def create_task(self, coro): + return MyTask(coro, loop=loop) + + loop = EventLoop() + self.set_event_loop(loop) + + coro = test() + task = asyncio.async(coro, loop=loop) + self.assertIsInstance(task, MyTask) + + # make warnings quiet + task._log_destroy_pending = False + coro.close() + + def test_run_forever_keyboard_interrupt(self): + # Python issue #22601: ensure that the temporary task created by + # run_forever() consumes the KeyboardInterrupt and so don't log + # a warning + @asyncio.coroutine + def raise_keyboard_interrupt(): + raise KeyboardInterrupt + + self.loop._process_events = mock.Mock() + self.loop.call_exception_handler = mock.Mock() + + try: + self.loop.run_until_complete(raise_keyboard_interrupt()) + except KeyboardInterrupt: + pass + self.loop.close() + support.gc_collect() + + self.assertFalse(self.loop.call_exception_handler.called) + + def test_run_until_complete_baseexception(self): + # Python issue #22429: run_until_complete() must not schedule a pending + # call to stop() if the future raised a BaseException + @asyncio.coroutine + def raise_keyboard_interrupt(): + raise KeyboardInterrupt + + self.loop._process_events = mock.Mock() + + try: + self.loop.run_until_complete(raise_keyboard_interrupt()) + except KeyboardInterrupt: + pass + + def func(): + self.loop.stop() + func.called = True + func.called = False + try: + self.loop.call_soon(func) + self.loop.run_forever() + except KeyboardInterrupt: + pass + self.assertTrue(func.called) -class MyProto(protocols.Protocol): +class MyProto(asyncio.Protocol): done = None def __init__(self, create_future=False): self.state = 'INITIAL' self.nbytes = 0 if create_future: - self.done = futures.Future() + self.done = asyncio.Future() def connection_made(self, transport): self.transport = transport @@ -266,14 +745,14 @@ def connection_lost(self, exc): self.done.set_result(None) -class MyDatagramProto(protocols.DatagramProtocol): +class MyDatagramProto(asyncio.DatagramProtocol): done = None def __init__(self, create_future=False): self.state = 'INITIAL' self.nbytes = 0 if create_future: - self.done = futures.Future() + self.done = asyncio.Future() def connection_made(self, transport): self.transport = transport @@ -294,29 +773,26 @@ def connection_lost(self, exc): self.done.set_result(None) -class BaseEventLoopWithSelectorTests(unittest.TestCase): +class BaseEventLoopWithSelectorTests(test_utils.TestCase): def setUp(self): - self.loop = events.new_event_loop() - events.set_event_loop(None) + self.loop = asyncio.new_event_loop() + self.set_event_loop(self.loop) - def tearDown(self): - self.loop.close() - - @unittest.mock.patch('asyncio.base_events.socket') + @mock.patch('asyncio.base_events.socket') def test_create_connection_multiple_errors(self, m_socket): - class MyProto(protocols.Protocol): + class MyProto(asyncio.Protocol): pass - @tasks.coroutine + @asyncio.coroutine def getaddrinfo(*args, **kw): yield from [] return [(2, 1, 6, '', ('107.6.106.82', 80)), (2, 1, 6, '', ('107.6.106.82', 80))] def getaddrinfo_task(*args, **kwds): - return tasks.Task(getaddrinfo(*args, **kwds), loop=self.loop) + return asyncio.Task(getaddrinfo(*args, **kwds), loop=self.loop) idx = -1 errors = ['err1', 'err2'] @@ -336,6 +812,27 @@ def _socket(*args, **kw): self.assertEqual(str(cm.exception), 'Multiple exceptions: err1, err2') + @mock.patch('asyncio.base_events.socket') + def test_create_connection_timeout(self, m_socket): + # Ensure that the socket is closed on timeout + sock = mock.Mock() + m_socket.socket.return_value = sock + + def getaddrinfo(*args, **kw): + fut = asyncio.Future(loop=self.loop) + addr = (socket.AF_INET, socket.SOCK_STREAM, 0, '', + ('127.0.0.1', 80)) + fut.set_result([addr]) + return fut + self.loop.getaddrinfo = getaddrinfo + + with mock.patch.object(self.loop, 'sock_connect', + side_effect=asyncio.TimeoutError): + coro = self.loop.create_connection(MyProto, '127.0.0.1', 80) + with self.assertRaises(asyncio.TimeoutError): + self.loop.run_until_complete(coro) + self.assertTrue(sock.close.called) + def test_create_connection_host_port_sock(self): coro = self.loop.create_connection( MyProto, 'example.com', 80, sock=object()) @@ -346,12 +843,12 @@ def test_create_connection_no_host_port_sock(self): self.assertRaises(ValueError, self.loop.run_until_complete, coro) def test_create_connection_no_getaddrinfo(self): - @tasks.coroutine + @asyncio.coroutine def getaddrinfo(*args, **kw): yield from [] def getaddrinfo_task(*args, **kwds): - return tasks.Task(getaddrinfo(*args, **kwds), loop=self.loop) + return asyncio.Task(getaddrinfo(*args, **kwds), loop=self.loop) self.loop.getaddrinfo = getaddrinfo_task coro = self.loop.create_connection(MyProto, 'example.com', 80) @@ -359,16 +856,16 @@ def getaddrinfo_task(*args, **kwds): OSError, self.loop.run_until_complete, coro) def test_create_connection_connect_err(self): - @tasks.coroutine + @asyncio.coroutine def getaddrinfo(*args, **kw): yield from [] return [(2, 1, 6, '', ('107.6.106.82', 80))] def getaddrinfo_task(*args, **kwds): - return tasks.Task(getaddrinfo(*args, **kwds), loop=self.loop) + return asyncio.Task(getaddrinfo(*args, **kwds), loop=self.loop) self.loop.getaddrinfo = getaddrinfo_task - self.loop.sock_connect = unittest.mock.Mock() + self.loop.sock_connect = mock.Mock() self.loop.sock_connect.side_effect = OSError coro = self.loop.create_connection(MyProto, 'example.com', 80) @@ -376,16 +873,16 @@ def getaddrinfo_task(*args, **kwds): OSError, self.loop.run_until_complete, coro) def test_create_connection_multiple(self): - @tasks.coroutine + @asyncio.coroutine def getaddrinfo(*args, **kw): return [(2, 1, 6, '', ('0.0.0.1', 80)), (2, 1, 6, '', ('0.0.0.2', 80))] def getaddrinfo_task(*args, **kwds): - return tasks.Task(getaddrinfo(*args, **kwds), loop=self.loop) + return asyncio.Task(getaddrinfo(*args, **kwds), loop=self.loop) self.loop.getaddrinfo = getaddrinfo_task - self.loop.sock_connect = unittest.mock.Mock() + self.loop.sock_connect = mock.Mock() self.loop.sock_connect.side_effect = OSError coro = self.loop.create_connection( @@ -393,7 +890,7 @@ def getaddrinfo_task(*args, **kwds): with self.assertRaises(OSError): self.loop.run_until_complete(coro) - @unittest.mock.patch('asyncio.base_events.socket') + @mock.patch('asyncio.base_events.socket') def test_create_connection_multiple_errors_local_addr(self, m_socket): def bind(addr): @@ -404,16 +901,16 @@ def bind(addr): m_socket.socket.return_value.bind = bind - @tasks.coroutine + @asyncio.coroutine def getaddrinfo(*args, **kw): return [(2, 1, 6, '', ('0.0.0.1', 80)), (2, 1, 6, '', ('0.0.0.2', 80))] def getaddrinfo_task(*args, **kwds): - return tasks.Task(getaddrinfo(*args, **kwds), loop=self.loop) + return asyncio.Task(getaddrinfo(*args, **kwds), loop=self.loop) self.loop.getaddrinfo = getaddrinfo_task - self.loop.sock_connect = unittest.mock.Mock() + self.loop.sock_connect = mock.Mock() self.loop.sock_connect.side_effect = OSError('Err2') coro = self.loop.create_connection( @@ -426,7 +923,7 @@ def getaddrinfo_task(*args, **kwds): self.assertTrue(m_socket.socket.return_value.close.called) def test_create_connection_no_local_addr(self): - @tasks.coroutine + @asyncio.coroutine def getaddrinfo(host, *args, **kw): if host == 'example.com': return [(2, 1, 6, '', ('107.6.106.82', 80)), @@ -435,7 +932,7 @@ def getaddrinfo(host, *args, **kw): return [] def getaddrinfo_task(*args, **kwds): - return tasks.Task(getaddrinfo(*args, **kwds), loop=self.loop) + return asyncio.Task(getaddrinfo(*args, **kwds), loop=self.loop) self.loop.getaddrinfo = getaddrinfo_task coro = self.loop.create_connection( @@ -445,22 +942,25 @@ def getaddrinfo_task(*args, **kwds): OSError, self.loop.run_until_complete, coro) def test_create_connection_ssl_server_hostname_default(self): - self.loop.getaddrinfo = unittest.mock.Mock() + self.loop.getaddrinfo = mock.Mock() def mock_getaddrinfo(*args, **kwds): - f = futures.Future(loop=self.loop) + f = asyncio.Future(loop=self.loop) f.set_result([(socket.AF_INET, socket.SOCK_STREAM, socket.SOL_TCP, '', ('1.2.3.4', 80))]) return f self.loop.getaddrinfo.side_effect = mock_getaddrinfo - self.loop.sock_connect = unittest.mock.Mock() + self.loop.sock_connect = mock.Mock() self.loop.sock_connect.return_value = () - self.loop._make_ssl_transport = unittest.mock.Mock() + self.loop._make_ssl_transport = mock.Mock() class _SelectorTransportMock: _sock = None + def get_extra_info(self, key): + return mock.Mock() + def close(self): self._sock.close() @@ -472,7 +972,7 @@ def mock_make_ssl_transport(sock, protocol, sslcontext, waiter, return transport self.loop._make_ssl_transport.side_effect = mock_make_ssl_transport - ANY = unittest.mock.ANY + ANY = mock.ANY # First try the default server_hostname. self.loop._make_ssl_transport.reset_mock() coro = self.loop.create_connection(MyProto, 'python.org', 80, ssl=True) @@ -527,14 +1027,14 @@ def test_create_server_empty_host(self): # if host is empty string use None instead host = object() - @tasks.coroutine + @asyncio.coroutine def getaddrinfo(*args, **kw): nonlocal host host = args[0] yield from [] def getaddrinfo_task(*args, **kwds): - return tasks.Task(getaddrinfo(*args, **kwds), loop=self.loop) + return asyncio.Task(getaddrinfo(*args, **kwds), loop=self.loop) self.loop.getaddrinfo = getaddrinfo_task fut = self.loop.create_server(MyProto, '', 0) @@ -551,13 +1051,13 @@ def test_create_server_no_host_port_sock(self): self.assertRaises(ValueError, self.loop.run_until_complete, fut) def test_create_server_no_getaddrinfo(self): - getaddrinfo = self.loop.getaddrinfo = unittest.mock.Mock() + getaddrinfo = self.loop.getaddrinfo = mock.Mock() getaddrinfo.return_value = [] f = self.loop.create_server(MyProto, '0.0.0.0', 0) self.assertRaises(OSError, self.loop.run_until_complete, f) - @unittest.mock.patch('asyncio.base_events.socket') + @mock.patch('asyncio.base_events.socket') def test_create_server_cant_bind(self, m_socket): class Err(OSError): @@ -565,16 +1065,18 @@ class Err(OSError): m_socket.getaddrinfo.return_value = [ (2, 1, 6, '', ('127.0.0.1', 10100))] - m_sock = m_socket.socket.return_value = unittest.mock.Mock() + m_socket.getaddrinfo._is_coroutine = False + m_sock = m_socket.socket.return_value = mock.Mock() m_sock.bind.side_effect = Err fut = self.loop.create_server(MyProto, '0.0.0.0', 0) self.assertRaises(OSError, self.loop.run_until_complete, fut) self.assertTrue(m_sock.close.called) - @unittest.mock.patch('asyncio.base_events.socket') + @mock.patch('asyncio.base_events.socket') def test_create_datagram_endpoint_no_addrinfo(self, m_socket): m_socket.getaddrinfo.return_value = [] + m_socket.getaddrinfo._is_coroutine = False coro = self.loop.create_datagram_endpoint( MyDatagramProto, local_addr=('localhost', 0)) @@ -592,43 +1094,43 @@ def test_create_datagram_endpoint_addr_error(self): AssertionError, self.loop.run_until_complete, coro) def test_create_datagram_endpoint_connect_err(self): - self.loop.sock_connect = unittest.mock.Mock() + self.loop.sock_connect = mock.Mock() self.loop.sock_connect.side_effect = OSError coro = self.loop.create_datagram_endpoint( - protocols.DatagramProtocol, remote_addr=('127.0.0.1', 0)) + asyncio.DatagramProtocol, remote_addr=('127.0.0.1', 0)) self.assertRaises( OSError, self.loop.run_until_complete, coro) - @unittest.mock.patch('asyncio.base_events.socket') + @mock.patch('asyncio.base_events.socket') def test_create_datagram_endpoint_socket_err(self, m_socket): m_socket.getaddrinfo = socket.getaddrinfo m_socket.socket.side_effect = OSError coro = self.loop.create_datagram_endpoint( - protocols.DatagramProtocol, family=socket.AF_INET) + asyncio.DatagramProtocol, family=socket.AF_INET) self.assertRaises( OSError, self.loop.run_until_complete, coro) coro = self.loop.create_datagram_endpoint( - protocols.DatagramProtocol, local_addr=('127.0.0.1', 0)) + asyncio.DatagramProtocol, local_addr=('127.0.0.1', 0)) self.assertRaises( OSError, self.loop.run_until_complete, coro) - @unittest.skipUnless(IPV6_ENABLED, 'IPv6 not supported or enabled') + @unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 not supported or enabled') def test_create_datagram_endpoint_no_matching_family(self): coro = self.loop.create_datagram_endpoint( - protocols.DatagramProtocol, + asyncio.DatagramProtocol, remote_addr=('127.0.0.1', 0), local_addr=('::1', 0)) self.assertRaises( ValueError, self.loop.run_until_complete, coro) - @unittest.mock.patch('asyncio.base_events.socket') + @mock.patch('asyncio.base_events.socket') def test_create_datagram_endpoint_setblk_err(self, m_socket): m_socket.socket.return_value.setblocking.side_effect = OSError coro = self.loop.create_datagram_endpoint( - protocols.DatagramProtocol, family=socket.AF_INET) + asyncio.DatagramProtocol, family=socket.AF_INET) self.assertRaises( OSError, self.loop.run_until_complete, coro) self.assertTrue( @@ -636,17 +1138,17 @@ def test_create_datagram_endpoint_setblk_err(self, m_socket): def test_create_datagram_endpoint_noaddr_nofamily(self): coro = self.loop.create_datagram_endpoint( - protocols.DatagramProtocol) + asyncio.DatagramProtocol) self.assertRaises(ValueError, self.loop.run_until_complete, coro) - @unittest.mock.patch('asyncio.base_events.socket') + @mock.patch('asyncio.base_events.socket') def test_create_datagram_endpoint_cant_bind(self, m_socket): class Err(OSError): pass m_socket.AF_INET6 = socket.AF_INET6 m_socket.getaddrinfo = socket.getaddrinfo - m_sock = m_socket.socket.return_value = unittest.mock.Mock() + m_sock = m_socket.socket.return_value = mock.Mock() m_sock.bind.side_effect = Err fut = self.loop.create_datagram_endpoint( @@ -656,29 +1158,79 @@ class Err(OSError): self.assertTrue(m_sock.close.called) def test_accept_connection_retry(self): - sock = unittest.mock.Mock() + sock = mock.Mock() sock.accept.side_effect = BlockingIOError() self.loop._accept_connection(MyProto, sock) self.assertFalse(sock.close.called) - @unittest.mock.patch('asyncio.selector_events.logger') + @mock.patch('asyncio.base_events.logger') def test_accept_connection_exception(self, m_log): - sock = unittest.mock.Mock() + sock = mock.Mock() sock.fileno.return_value = 10 sock.accept.side_effect = OSError(errno.EMFILE, 'Too many open files') - self.loop.remove_reader = unittest.mock.Mock() - self.loop.call_later = unittest.mock.Mock() + self.loop.remove_reader = mock.Mock() + self.loop.call_later = mock.Mock() self.loop._accept_connection(MyProto, sock) - self.assertTrue(m_log.exception.called) + self.assertTrue(m_log.error.called) self.assertFalse(sock.close.called) self.loop.remove_reader.assert_called_with(10) self.loop.call_later.assert_called_with(constants.ACCEPT_RETRY_DELAY, # self.loop._start_serving - unittest.mock.ANY, + mock.ANY, MyProto, sock, None, None) + def test_call_coroutine(self): + @asyncio.coroutine + def simple_coroutine(): + pass + + coro_func = simple_coroutine + coro_obj = coro_func() + self.addCleanup(coro_obj.close) + for func in (coro_func, coro_obj): + with self.assertRaises(TypeError): + self.loop.call_soon(func) + with self.assertRaises(TypeError): + self.loop.call_soon_threadsafe(func) + with self.assertRaises(TypeError): + self.loop.call_later(60, func) + with self.assertRaises(TypeError): + self.loop.call_at(self.loop.time() + 60, func) + with self.assertRaises(TypeError): + self.loop.run_in_executor(None, func) + + @mock.patch('asyncio.base_events.logger') + def test_log_slow_callbacks(self, m_logger): + def stop_loop_cb(loop): + loop.stop() + + @asyncio.coroutine + def stop_loop_coro(loop): + yield from () + loop.stop() + + asyncio.set_event_loop(self.loop) + self.loop.set_debug(True) + self.loop.slow_callback_duration = 0.0 + + # slow callback + self.loop.call_soon(stop_loop_cb, self.loop) + self.loop.run_forever() + fmt, *args = m_logger.warning.call_args[0] + self.assertRegex(fmt % tuple(args), + "^Executing <Handle.*stop_loop_cb.*> " + "took .* seconds$") + + # slow task + asyncio.async(stop_loop_coro(self.loop), loop=self.loop) + self.loop.run_forever() + fmt, *args = m_logger.warning.call_args[0] + self.assertRegex(fmt % tuple(args), + "^Executing <Task.*stop_loop_coro.*> " + "took .* seconds$") + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_asyncio/test_events.py b/Lib/test/test_asyncio/test_events.py index 18411ecc246b..8fbba8fe0fc5 100644 --- a/Lib/test/test_asyncio/test_events.py +++ b/Lib/test/test_asyncio/test_events.py @@ -4,6 +4,8 @@ import gc import io import os +import platform +import re import signal import socket try: @@ -16,34 +18,65 @@ import time import errno import unittest -import unittest.mock -from test.support import find_unused_port, IPV6_ENABLED +from unittest import mock +import weakref -from asyncio import futures -from asyncio import events -from asyncio import transports -from asyncio import protocols +import asyncio +from asyncio import proactor_events from asyncio import selector_events -from asyncio import tasks +from asyncio import sslproto from asyncio import test_utils -from asyncio import locks +try: + from test import support +except ImportError: + from asyncio import test_support as support + + +def data_file(filename): + if hasattr(support, 'TEST_HOME_DIR'): + fullname = os.path.join(support.TEST_HOME_DIR, filename) + if os.path.isfile(fullname): + return fullname + fullname = os.path.join(os.path.dirname(__file__), filename) + if os.path.isfile(fullname): + return fullname + raise FileNotFoundError(filename) + + +def osx_tiger(): + """Return True if the platform is Mac OS 10.4 or older.""" + if sys.platform != 'darwin': + return False + version = platform.mac_ver()[0] + version = tuple(map(int, version.split('.'))) + return version < (10, 5) -class MyProto(protocols.Protocol): +ONLYCERT = data_file('ssl_cert.pem') +ONLYKEY = data_file('ssl_key.pem') +SIGNED_CERTFILE = data_file('keycert3.pem') +SIGNING_CA = data_file('pycacert.pem') + + +class MyBaseProto(asyncio.Protocol): + connected = None done = None def __init__(self, loop=None): + self.transport = None self.state = 'INITIAL' self.nbytes = 0 if loop is not None: - self.done = futures.Future(loop=loop) + self.connected = asyncio.Future(loop=loop) + self.done = asyncio.Future(loop=loop) def connection_made(self, transport): self.transport = transport assert self.state == 'INITIAL', self.state self.state = 'CONNECTED' - transport.write(b'GET / HTTP/1.0\r\nHost: example.com\r\n\r\n') + if self.connected: + self.connected.set_result(None) def data_received(self, data): assert self.state == 'CONNECTED', self.state @@ -60,14 +93,20 @@ def connection_lost(self, exc): self.done.set_result(None) -class MyDatagramProto(protocols.DatagramProtocol): +class MyProto(MyBaseProto): + def connection_made(self, transport): + super().connection_made(transport) + transport.write(b'GET / HTTP/1.0\r\nHost: example.com\r\n\r\n') + + +class MyDatagramProto(asyncio.DatagramProtocol): done = None def __init__(self, loop=None): self.state = 'INITIAL' self.nbytes = 0 if loop is not None: - self.done = futures.Future(loop=loop) + self.done = asyncio.Future(loop=loop) def connection_made(self, transport): self.transport = transport @@ -88,7 +127,7 @@ def connection_lost(self, exc): self.done.set_result(None) -class MyReadPipeProto(protocols.Protocol): +class MyReadPipeProto(asyncio.Protocol): done = None def __init__(self, loop=None): @@ -96,7 +135,7 @@ def __init__(self, loop=None): self.nbytes = 0 self.transport = None if loop is not None: - self.done = futures.Future(loop=loop) + self.done = asyncio.Future(loop=loop) def connection_made(self, transport): self.transport = transport @@ -112,20 +151,22 @@ def eof_received(self): self.state.append('EOF') def connection_lost(self, exc): + if 'EOF' not in self.state: + self.state.append('EOF') # It is okay if EOF is missed. assert self.state == ['INITIAL', 'CONNECTED', 'EOF'], self.state self.state.append('CLOSED') if self.done: self.done.set_result(None) -class MyWritePipeProto(protocols.BaseProtocol): +class MyWritePipeProto(asyncio.BaseProtocol): done = None def __init__(self, loop=None): self.state = 'INITIAL' self.transport = None if loop is not None: - self.done = futures.Future(loop=loop) + self.done = asyncio.Future(loop=loop) def connection_made(self, transport): self.transport = transport @@ -139,18 +180,18 @@ def connection_lost(self, exc): self.done.set_result(None) -class MySubprocessProtocol(protocols.SubprocessProtocol): +class MySubprocessProtocol(asyncio.SubprocessProtocol): def __init__(self, loop): self.state = 'INITIAL' self.transport = None - self.connected = futures.Future(loop=loop) - self.completed = futures.Future(loop=loop) - self.disconnects = {fd: futures.Future(loop=loop) for fd in range(3)} + self.connected = asyncio.Future(loop=loop) + self.completed = asyncio.Future(loop=loop) + self.disconnects = {fd: asyncio.Future(loop=loop) for fd in range(3)} self.data = {1: b'', 2: b''} self.returncode = None - self.got_data = {1: locks.Event(loop=loop), - 2: locks.Event(loop=loop)} + self.got_data = {1: asyncio.Event(loop=loop), + 2: asyncio.Event(loop=loop)} def connection_made(self, transport): self.transport = transport @@ -185,22 +226,23 @@ class EventLoopTestsMixin: def setUp(self): super().setUp() self.loop = self.create_event_loop() - events.set_event_loop(None) + self.set_event_loop(self.loop) def tearDown(self): # just in case if we have transport close callbacks - test_utils.run_briefly(self.loop) + if not self.loop.is_closed(): + test_utils.run_briefly(self.loop) self.loop.close() gc.collect() super().tearDown() def test_run_until_complete_nesting(self): - @tasks.coroutine + @asyncio.coroutine def coro1(): yield - @tasks.coroutine + @asyncio.coroutine def coro2(): self.assertTrue(self.loop.is_running()) self.loop.run_until_complete(coro1()) @@ -213,15 +255,15 @@ def coro2(): def test_run_until_complete(self): t0 = self.loop.time() - self.loop.run_until_complete(tasks.sleep(0.1, loop=self.loop)) + self.loop.run_until_complete(asyncio.sleep(0.1, loop=self.loop)) t1 = self.loop.time() self.assertTrue(0.08 <= t1-t0 <= 0.8, t1-t0) def test_run_until_complete_stopped(self): - @tasks.coroutine + @asyncio.coroutine def cb(): self.loop.stop() - yield from tasks.sleep(0.1, loop=self.loop) + yield from asyncio.sleep(0.1, loop=self.loop) task = cb() self.assertRaises(RuntimeError, self.loop.run_until_complete, task) @@ -297,7 +339,8 @@ def run(arg): def test_reader_callback(self): r, w = test_utils.socketpair() - bytes_read = [] + r.setblocking(False) + bytes_read = bytearray() def reader(): try: @@ -307,54 +350,84 @@ def reader(): # at least on Linux -- see man select. return if data: - bytes_read.append(data) + bytes_read.extend(data) else: self.assertTrue(self.loop.remove_reader(r.fileno())) r.close() self.loop.add_reader(r.fileno(), reader) self.loop.call_soon(w.send, b'abc') - test_utils.run_briefly(self.loop) + test_utils.run_until(self.loop, lambda: len(bytes_read) >= 3) self.loop.call_soon(w.send, b'def') - test_utils.run_briefly(self.loop) + test_utils.run_until(self.loop, lambda: len(bytes_read) >= 6) self.loop.call_soon(w.close) self.loop.call_soon(self.loop.stop) self.loop.run_forever() - self.assertEqual(b''.join(bytes_read), b'abcdef') + self.assertEqual(bytes_read, b'abcdef') def test_writer_callback(self): r, w = test_utils.socketpair() w.setblocking(False) - self.loop.add_writer(w.fileno(), w.send, b'x'*(256*1024)) - test_utils.run_briefly(self.loop) - def remove_writer(): - self.assertTrue(self.loop.remove_writer(w.fileno())) + def writer(data): + w.send(data) + self.loop.stop() - self.loop.call_soon(remove_writer) - self.loop.call_soon(self.loop.stop) + data = b'x' * 1024 + self.loop.add_writer(w.fileno(), writer, data) self.loop.run_forever() + + self.assertTrue(self.loop.remove_writer(w.fileno())) + self.assertFalse(self.loop.remove_writer(w.fileno())) + w.close() - data = r.recv(256*1024) + read = r.recv(len(data) * 2) r.close() - self.assertGreaterEqual(len(data), 200) + self.assertEqual(read, data) + + def _basetest_sock_client_ops(self, httpd, sock): + if not isinstance(self.loop, proactor_events.BaseProactorEventLoop): + # in debug mode, socket operations must fail + # if the socket is not in blocking mode + self.loop.set_debug(True) + sock.setblocking(True) + with self.assertRaises(ValueError): + self.loop.run_until_complete( + self.loop.sock_connect(sock, httpd.address)) + with self.assertRaises(ValueError): + self.loop.run_until_complete( + self.loop.sock_sendall(sock, b'GET / HTTP/1.0\r\n\r\n')) + with self.assertRaises(ValueError): + self.loop.run_until_complete( + self.loop.sock_recv(sock, 1024)) + with self.assertRaises(ValueError): + self.loop.run_until_complete( + self.loop.sock_accept(sock)) + + # test in non-blocking mode + sock.setblocking(False) + self.loop.run_until_complete( + self.loop.sock_connect(sock, httpd.address)) + self.loop.run_until_complete( + self.loop.sock_sendall(sock, b'GET / HTTP/1.0\r\n\r\n')) + data = self.loop.run_until_complete( + self.loop.sock_recv(sock, 1024)) + # consume data + self.loop.run_until_complete( + self.loop.sock_recv(sock, 1024)) + sock.close() + self.assertTrue(data.startswith(b'HTTP/1.0 200 OK')) def test_sock_client_ops(self): with test_utils.run_test_server() as httpd: sock = socket.socket() - sock.setblocking(False) - self.loop.run_until_complete( - self.loop.sock_connect(sock, httpd.address)) - self.loop.run_until_complete( - self.loop.sock_sendall(sock, b'GET / HTTP/1.0\r\n\r\n')) - data = self.loop.run_until_complete( - self.loop.sock_recv(sock, 1024)) - # consume data - self.loop.run_until_complete( - self.loop.sock_recv(sock, 1024)) - sock.close() + self._basetest_sock_client_ops(httpd, sock) - self.assertTrue(data.startswith(b'HTTP/1.0 200 OK')) + @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets') + def test_unix_sock_client_ops(self): + with test_utils.run_test_unix_server() as httpd: + sock = socket.socket(socket.AF_UNIX) + self._basetest_sock_client_ops(httpd, sock) def test_sock_client_fail(self): # Make sure that we will get an unused port @@ -423,10 +496,10 @@ def my_handler(): self.assertFalse(self.loop.remove_signal_handler(signal.SIGKILL)) # Now set a handler and handle it. self.loop.add_signal_handler(signal.SIGINT, my_handler) - test_utils.run_briefly(self.loop) + os.kill(os.getpid(), signal.SIGINT) - test_utils.run_briefly(self.loop) - self.assertEqual(caught, 1) + test_utils.run_until(self.loop, lambda: caught) + # Removing it should restore the default handler. self.assertTrue(self.loop.remove_signal_handler(signal.SIGINT)) self.assertEqual(signal.getsignal(signal.SIGINT), @@ -467,16 +540,33 @@ def my_handler(*args): self.loop.run_forever() self.assertEqual(caught, 1) + def _basetest_create_connection(self, connection_fut, check_sockname=True): + tr, pr = self.loop.run_until_complete(connection_fut) + self.assertIsInstance(tr, asyncio.Transport) + self.assertIsInstance(pr, asyncio.Protocol) + self.assertIs(pr.transport, tr) + if check_sockname: + self.assertIsNotNone(tr.get_extra_info('sockname')) + self.loop.run_until_complete(pr.done) + self.assertGreater(pr.nbytes, 0) + tr.close() + def test_create_connection(self): with test_utils.run_test_server() as httpd: - f = self.loop.create_connection( + conn_fut = self.loop.create_connection( lambda: MyProto(loop=self.loop), *httpd.address) - tr, pr = self.loop.run_until_complete(f) - self.assertIsInstance(tr, transports.Transport) - self.assertIsInstance(pr, protocols.Protocol) - self.loop.run_until_complete(pr.done) - self.assertGreater(pr.nbytes, 0) - tr.close() + self._basetest_create_connection(conn_fut) + + @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets') + def test_create_unix_connection(self): + # Issue #20682: On Mac OS X Tiger, getsockname() returns a + # zero-length address for UNIX socket. + check_sockname = not osx_tiger() + + with test_utils.run_test_unix_server() as httpd: + conn_fut = self.loop.create_unix_connection( + lambda: MyProto(loop=self.loop), httpd.address) + self._basetest_create_connection(conn_fut, check_sockname) def test_create_connection_sock(self): with test_utils.run_test_server() as httpd: @@ -500,30 +590,94 @@ def test_create_connection_sock(self): f = self.loop.create_connection( lambda: MyProto(loop=self.loop), sock=sock) tr, pr = self.loop.run_until_complete(f) - self.assertIsInstance(tr, transports.Transport) - self.assertIsInstance(pr, protocols.Protocol) + self.assertIsInstance(tr, asyncio.Transport) + self.assertIsInstance(pr, asyncio.Protocol) self.loop.run_until_complete(pr.done) self.assertGreater(pr.nbytes, 0) tr.close() + def _basetest_create_ssl_connection(self, connection_fut, + check_sockname=True): + tr, pr = self.loop.run_until_complete(connection_fut) + self.assertIsInstance(tr, asyncio.Transport) + self.assertIsInstance(pr, asyncio.Protocol) + self.assertTrue('ssl' in tr.__class__.__name__.lower()) + if check_sockname: + self.assertIsNotNone(tr.get_extra_info('sockname')) + self.loop.run_until_complete(pr.done) + self.assertGreater(pr.nbytes, 0) + tr.close() + + def _test_create_ssl_connection(self, httpd, create_connection, + check_sockname=True): + conn_fut = create_connection(ssl=test_utils.dummy_ssl_context()) + self._basetest_create_ssl_connection(conn_fut, check_sockname) + + # ssl.Purpose was introduced in Python 3.4 + if hasattr(ssl, 'Purpose'): + def _dummy_ssl_create_context(purpose=ssl.Purpose.SERVER_AUTH, *, + cafile=None, capath=None, + cadata=None): + """ + A ssl.create_default_context() replacement that doesn't enable + cert validation. + """ + self.assertEqual(purpose, ssl.Purpose.SERVER_AUTH) + return test_utils.dummy_ssl_context() + + # With ssl=True, ssl.create_default_context() should be called + with mock.patch('ssl.create_default_context', + side_effect=_dummy_ssl_create_context) as m: + conn_fut = create_connection(ssl=True) + self._basetest_create_ssl_connection(conn_fut, check_sockname) + self.assertEqual(m.call_count, 1) + + # With the real ssl.create_default_context(), certificate + # validation will fail + with self.assertRaises(ssl.SSLError) as cm: + conn_fut = create_connection(ssl=True) + # Ignore the "SSL handshake failed" log in debug mode + with test_utils.disable_logger(): + self._basetest_create_ssl_connection(conn_fut, check_sockname) + + self.assertEqual(cm.exception.reason, 'CERTIFICATE_VERIFY_FAILED') + @unittest.skipIf(ssl is None, 'No ssl module') def test_create_ssl_connection(self): with test_utils.run_test_server(use_ssl=True) as httpd: - f = self.loop.create_connection( - lambda: MyProto(loop=self.loop), *httpd.address, - ssl=test_utils.dummy_ssl_context()) - tr, pr = self.loop.run_until_complete(f) - self.assertIsInstance(tr, transports.Transport) - self.assertIsInstance(pr, protocols.Protocol) - self.assertTrue('ssl' in tr.__class__.__name__.lower()) - self.assertIsNotNone(tr.get_extra_info('sockname')) - self.loop.run_until_complete(pr.done) - self.assertGreater(pr.nbytes, 0) - tr.close() + create_connection = functools.partial( + self.loop.create_connection, + lambda: MyProto(loop=self.loop), + *httpd.address) + self._test_create_ssl_connection(httpd, create_connection) + + def test_legacy_create_ssl_connection(self): + with test_utils.force_legacy_ssl_support(): + self.test_create_ssl_connection() + + @unittest.skipIf(ssl is None, 'No ssl module') + @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets') + def test_create_ssl_unix_connection(self): + # Issue #20682: On Mac OS X Tiger, getsockname() returns a + # zero-length address for UNIX socket. + check_sockname = not osx_tiger() + + with test_utils.run_test_unix_server(use_ssl=True) as httpd: + create_connection = functools.partial( + self.loop.create_unix_connection, + lambda: MyProto(loop=self.loop), httpd.address, + server_hostname='127.0.0.1') + + self._test_create_ssl_connection(httpd, create_connection, + check_sockname) + + def test_legacy_create_ssl_unix_connection(self): + with test_utils.force_legacy_ssl_support(): + self.test_create_ssl_unix_connection() def test_create_connection_local_addr(self): with test_utils.run_test_server() as httpd: - port = find_unused_port() + port = support.find_unused_port() f = self.loop.create_connection( lambda: MyProto(loop=self.loop), *httpd.address, local_addr=(httpd.address[0], port)) @@ -543,14 +697,8 @@ def test_create_connection_local_addr_in_use(self): self.assertIn(str(httpd.address), cm.exception.strerror) def test_create_server(self): - proto = None - - def factory(): - nonlocal proto - proto = MyProto() - return proto - - f = self.loop.create_server(factory, '0.0.0.0', 0) + proto = MyProto(self.loop) + f = self.loop.create_server(lambda: proto, '0.0.0.0', 0) server = self.loop.run_until_complete(f) self.assertEqual(len(server.sockets), 1) sock = server.sockets[0] @@ -559,14 +707,11 @@ def factory(): client = socket.socket() client.connect(('127.0.0.1', port)) client.sendall(b'xxx') - test_utils.run_briefly(self.loop) - test_utils.run_until(self.loop, lambda: proto is not None, 10) - self.assertIsInstance(proto, MyProto) - self.assertEqual('INITIAL', proto.state) - test_utils.run_briefly(self.loop) + + self.loop.run_until_complete(proto.connected) self.assertEqual('CONNECTED', proto.state) - test_utils.run_until(self.loop, lambda: proto.nbytes > 0, - timeout=10) + + test_utils.run_until(self.loop, lambda: proto.nbytes > 0) self.assertEqual(3, proto.nbytes) # extra info is available @@ -576,7 +721,7 @@ def factory(): # close connection proto.transport.close() - test_utils.run_briefly(self.loop) # windows iocp + self.loop.run_until_complete(proto.done) self.assertEqual('CLOSED', proto.state) @@ -587,46 +732,90 @@ def factory(): # close server server.close() - @unittest.skipIf(ssl is None, 'No ssl module') - def test_create_server_ssl(self): - proto = None + def _make_unix_server(self, factory, **kwargs): + path = test_utils.gen_unix_socket_path() + self.addCleanup(lambda: os.path.exists(path) and os.unlink(path)) - class ClientMyProto(MyProto): - def connection_made(self, transport): - self.transport = transport - assert self.state == 'INITIAL', self.state - self.state = 'CONNECTED' + f = self.loop.create_unix_server(factory, path, **kwargs) + server = self.loop.run_until_complete(f) + + return server, path + + @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets') + def test_create_unix_server(self): + proto = MyProto(loop=self.loop) + server, path = self._make_unix_server(lambda: proto) + self.assertEqual(len(server.sockets), 1) + + client = socket.socket(socket.AF_UNIX) + client.connect(path) + client.sendall(b'xxx') - def factory(): - nonlocal proto - proto = MyProto(loop=self.loop) - return proto + self.loop.run_until_complete(proto.connected) + self.assertEqual('CONNECTED', proto.state) + test_utils.run_until(self.loop, lambda: proto.nbytes > 0) + self.assertEqual(3, proto.nbytes) + + # close connection + proto.transport.close() + self.loop.run_until_complete(proto.done) + + self.assertEqual('CLOSED', proto.state) - here = os.path.dirname(__file__) + # the client socket must be closed after to avoid ECONNRESET upon + # recv()/send() on the serving socket + client.close() + + # close server + server.close() + + @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets') + def test_create_unix_server_path_socket_error(self): + proto = MyProto(loop=self.loop) + sock = socket.socket() + with sock: + f = self.loop.create_unix_server(lambda: proto, '/test', sock=sock) + with self.assertRaisesRegex(ValueError, + 'path and sock can not be specified ' + 'at the same time'): + self.loop.run_until_complete(f) + + def _create_ssl_context(self, certfile, keyfile=None): sslcontext = ssl.SSLContext(ssl.PROTOCOL_SSLv23) - sslcontext.load_cert_chain( - certfile=os.path.join(here, 'sample.crt'), - keyfile=os.path.join(here, 'sample.key')) + sslcontext.options |= ssl.OP_NO_SSLv2 + sslcontext.load_cert_chain(certfile, keyfile) + return sslcontext - f = self.loop.create_server( - factory, '127.0.0.1', 0, ssl=sslcontext) + def _make_ssl_server(self, factory, certfile, keyfile=None): + sslcontext = self._create_ssl_context(certfile, keyfile) + f = self.loop.create_server(factory, '127.0.0.1', 0, ssl=sslcontext) server = self.loop.run_until_complete(f) + sock = server.sockets[0] host, port = sock.getsockname() self.assertEqual(host, '127.0.0.1') + return server, host, port + + def _make_ssl_unix_server(self, factory, certfile, keyfile=None): + sslcontext = self._create_ssl_context(certfile, keyfile) + return self._make_unix_server(factory, ssl=sslcontext) + + @unittest.skipIf(ssl is None, 'No ssl module') + def test_create_server_ssl(self): + proto = MyProto(loop=self.loop) + server, host, port = self._make_ssl_server( + lambda: proto, ONLYCERT, ONLYKEY) - f_c = self.loop.create_connection(ClientMyProto, host, port, + f_c = self.loop.create_connection(MyBaseProto, host, port, ssl=test_utils.dummy_ssl_context()) client, pr = self.loop.run_until_complete(f_c) client.write(b'xxx') - test_utils.run_briefly(self.loop) - self.assertIsInstance(proto, MyProto) - test_utils.run_briefly(self.loop) + self.loop.run_until_complete(proto.connected) self.assertEqual('CONNECTED', proto.state) - test_utils.run_until(self.loop, lambda: proto.nbytes > 0, - timeout=10) + + test_utils.run_until(self.loop, lambda: proto.nbytes > 0) self.assertEqual(3, proto.nbytes) # extra info is available @@ -646,8 +835,206 @@ def factory(): # stop serving server.close() + def test_legacy_create_server_ssl(self): + with test_utils.force_legacy_ssl_support(): + self.test_create_server_ssl() + + @unittest.skipIf(ssl is None, 'No ssl module') + @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets') + def test_create_unix_server_ssl(self): + proto = MyProto(loop=self.loop) + server, path = self._make_ssl_unix_server( + lambda: proto, ONLYCERT, ONLYKEY) + + f_c = self.loop.create_unix_connection( + MyBaseProto, path, ssl=test_utils.dummy_ssl_context(), + server_hostname='') + + client, pr = self.loop.run_until_complete(f_c) + + client.write(b'xxx') + self.loop.run_until_complete(proto.connected) + self.assertEqual('CONNECTED', proto.state) + test_utils.run_until(self.loop, lambda: proto.nbytes > 0) + self.assertEqual(3, proto.nbytes) + + # close connection + proto.transport.close() + self.loop.run_until_complete(proto.done) + self.assertEqual('CLOSED', proto.state) + + # the client socket must be closed after to avoid ECONNRESET upon + # recv()/send() on the serving socket + client.close() + + # stop serving + server.close() + + def test_legacy_create_unix_server_ssl(self): + with test_utils.force_legacy_ssl_support(): + self.test_create_unix_server_ssl() + + @unittest.skipIf(ssl is None, 'No ssl module') + def test_create_server_ssl_verify_failed(self): + proto = MyProto(loop=self.loop) + server, host, port = self._make_ssl_server( + lambda: proto, SIGNED_CERTFILE) + + sslcontext_client = ssl.SSLContext(ssl.PROTOCOL_SSLv23) + sslcontext_client.options |= ssl.OP_NO_SSLv2 + sslcontext_client.verify_mode = ssl.CERT_REQUIRED + if hasattr(sslcontext_client, 'check_hostname'): + sslcontext_client.check_hostname = True + + + # no CA loaded + f_c = self.loop.create_connection(MyProto, host, port, + ssl=sslcontext_client) + with mock.patch.object(self.loop, 'call_exception_handler'): + with test_utils.disable_logger(): + with self.assertRaisesRegex(ssl.SSLError, + 'certificate verify failed '): + self.loop.run_until_complete(f_c) + + # execute the loop to log the connection error + test_utils.run_briefly(self.loop) + + # close connection + self.assertIsNone(proto.transport) + server.close() + + def test_legacy_create_server_ssl_verify_failed(self): + with test_utils.force_legacy_ssl_support(): + self.test_create_server_ssl_verify_failed() + + @unittest.skipIf(ssl is None, 'No ssl module') + @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets') + def test_create_unix_server_ssl_verify_failed(self): + proto = MyProto(loop=self.loop) + server, path = self._make_ssl_unix_server( + lambda: proto, SIGNED_CERTFILE) + + sslcontext_client = ssl.SSLContext(ssl.PROTOCOL_SSLv23) + sslcontext_client.options |= ssl.OP_NO_SSLv2 + sslcontext_client.verify_mode = ssl.CERT_REQUIRED + if hasattr(sslcontext_client, 'check_hostname'): + sslcontext_client.check_hostname = True + + # no CA loaded + f_c = self.loop.create_unix_connection(MyProto, path, + ssl=sslcontext_client, + server_hostname='invalid') + with mock.patch.object(self.loop, 'call_exception_handler'): + with test_utils.disable_logger(): + with self.assertRaisesRegex(ssl.SSLError, + 'certificate verify failed '): + self.loop.run_until_complete(f_c) + + # execute the loop to log the connection error + test_utils.run_briefly(self.loop) + + # close connection + self.assertIsNone(proto.transport) + server.close() + + + def test_legacy_create_unix_server_ssl_verify_failed(self): + with test_utils.force_legacy_ssl_support(): + self.test_create_unix_server_ssl_verify_failed() + + @unittest.skipIf(ssl is None, 'No ssl module') + def test_create_server_ssl_match_failed(self): + proto = MyProto(loop=self.loop) + server, host, port = self._make_ssl_server( + lambda: proto, SIGNED_CERTFILE) + + sslcontext_client = ssl.SSLContext(ssl.PROTOCOL_SSLv23) + sslcontext_client.options |= ssl.OP_NO_SSLv2 + sslcontext_client.verify_mode = ssl.CERT_REQUIRED + sslcontext_client.load_verify_locations( + cafile=SIGNING_CA) + if hasattr(sslcontext_client, 'check_hostname'): + sslcontext_client.check_hostname = True + + # incorrect server_hostname + f_c = self.loop.create_connection(MyProto, host, port, + ssl=sslcontext_client) + with mock.patch.object(self.loop, 'call_exception_handler'): + with test_utils.disable_logger(): + with self.assertRaisesRegex( + ssl.CertificateError, + "hostname '127.0.0.1' doesn't match 'localhost'"): + self.loop.run_until_complete(f_c) + + # close connection + proto.transport.close() + server.close() + + def test_legacy_create_server_ssl_match_failed(self): + with test_utils.force_legacy_ssl_support(): + self.test_create_server_ssl_match_failed() + + @unittest.skipIf(ssl is None, 'No ssl module') + @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets') + def test_create_unix_server_ssl_verified(self): + proto = MyProto(loop=self.loop) + server, path = self._make_ssl_unix_server( + lambda: proto, SIGNED_CERTFILE) + + sslcontext_client = ssl.SSLContext(ssl.PROTOCOL_SSLv23) + sslcontext_client.options |= ssl.OP_NO_SSLv2 + sslcontext_client.verify_mode = ssl.CERT_REQUIRED + sslcontext_client.load_verify_locations(cafile=SIGNING_CA) + if hasattr(sslcontext_client, 'check_hostname'): + sslcontext_client.check_hostname = True + + # Connection succeeds with correct CA and server hostname. + f_c = self.loop.create_unix_connection(MyProto, path, + ssl=sslcontext_client, + server_hostname='localhost') + client, pr = self.loop.run_until_complete(f_c) + + # close connection + proto.transport.close() + client.close() + server.close() + self.loop.run_until_complete(proto.done) + + def test_legacy_create_unix_server_ssl_verified(self): + with test_utils.force_legacy_ssl_support(): + self.test_create_unix_server_ssl_verified() + + @unittest.skipIf(ssl is None, 'No ssl module') + def test_create_server_ssl_verified(self): + proto = MyProto(loop=self.loop) + server, host, port = self._make_ssl_server( + lambda: proto, SIGNED_CERTFILE) + + sslcontext_client = ssl.SSLContext(ssl.PROTOCOL_SSLv23) + sslcontext_client.options |= ssl.OP_NO_SSLv2 + sslcontext_client.verify_mode = ssl.CERT_REQUIRED + sslcontext_client.load_verify_locations(cafile=SIGNING_CA) + if hasattr(sslcontext_client, 'check_hostname'): + sslcontext_client.check_hostname = True + + # Connection succeeds with correct CA and server hostname. + f_c = self.loop.create_connection(MyProto, host, port, + ssl=sslcontext_client, + server_hostname='localhost') + client, pr = self.loop.run_until_complete(f_c) + + # close connection + proto.transport.close() + client.close() + server.close() + self.loop.run_until_complete(proto.done) + + def test_legacy_create_server_ssl_verified(self): + with test_utils.force_legacy_ssl_support(): + self.test_create_server_ssl_verified() + def test_create_server_sock(self): - proto = futures.Future(loop=self.loop) + proto = asyncio.Future(loop=self.loop) class TestMyProto(MyProto): def connection_made(self, transport): @@ -688,9 +1075,9 @@ def test_create_server_addr_in_use(self): server.close() - @unittest.skipUnless(IPV6_ENABLED, 'IPv6 not supported or enabled') + @unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 not supported or enabled') def test_create_server_dual_stack(self): - f_proto = futures.Future(loop=self.loop) + f_proto = asyncio.Future(loop=self.loop) class TestMyProto(MyProto): def connection_made(self, transport): @@ -700,7 +1087,7 @@ def connection_made(self, transport): try_count = 0 while True: try: - port = find_unused_port() + port = support.find_unused_port() f = self.loop.create_server(TestMyProto, host=None, port=port) server = self.loop.run_until_complete(f) except OSError as ex: @@ -719,7 +1106,7 @@ def connection_made(self, transport): proto.transport.close() client.close() - f_proto = futures.Future(loop=self.loop) + f_proto = asyncio.Future(loop=self.loop) client = socket.socket(socket.AF_INET6) client.connect(('::1', port)) client.send(b'xxx') @@ -761,22 +1148,25 @@ def datagram_received(self, data, addr): s_transport, server = self.loop.run_until_complete(coro) host, port = s_transport.get_extra_info('sockname') + self.assertIsInstance(s_transport, asyncio.Transport) + self.assertIsInstance(server, TestMyDatagramProto) + self.assertEqual('INITIALIZED', server.state) + self.assertIs(server.transport, s_transport) + coro = self.loop.create_datagram_endpoint( lambda: MyDatagramProto(loop=self.loop), remote_addr=(host, port)) transport, client = self.loop.run_until_complete(coro) + self.assertIsInstance(transport, asyncio.Transport) + self.assertIsInstance(client, MyDatagramProto) self.assertEqual('INITIALIZED', client.state) + self.assertIs(client.transport, transport) + transport.sendto(b'xxx') - for _ in range(1000): - if server.nbytes: - break - test_utils.run_briefly(self.loop) + test_utils.run_until(self.loop, lambda: server.nbytes) self.assertEqual(3, server.nbytes) - for _ in range(1000): - if client.nbytes: - break - test_utils.run_briefly(self.loop) + test_utils.run_until(self.loop, lambda: client.nbytes) # received self.assertEqual(8, client.nbytes) @@ -793,7 +1183,8 @@ def datagram_received(self, data, addr): def test_internal_fds(self): loop = self.create_event_loop() if not isinstance(loop, selector_events.BaseSelectorEventLoop): - return + loop.close() + self.skipTest('loop is not a BaseSelectorEventLoop') self.assertEqual(1, loop._internal_fds) loop.close() @@ -804,19 +1195,15 @@ def test_internal_fds(self): @unittest.skipUnless(sys.platform != 'win32', "Don't support pipes for Windows") def test_read_pipe(self): - proto = None - - def factory(): - nonlocal proto - proto = MyReadPipeProto(loop=self.loop) - return proto + proto = MyReadPipeProto(loop=self.loop) rpipe, wpipe = os.pipe() pipeobj = io.open(rpipe, 'rb', 1024) - @tasks.coroutine + @asyncio.coroutine def connect(): - t, p = yield from self.loop.connect_read_pipe(factory, pipeobj) + t, p = yield from self.loop.connect_read_pipe( + lambda: proto, pipeobj) self.assertIs(p, proto) self.assertIs(t, proto.transport) self.assertEqual(['INITIAL', 'CONNECTED'], proto.state) @@ -825,11 +1212,11 @@ def connect(): self.loop.run_until_complete(connect()) os.write(wpipe, b'1') - test_utils.run_briefly(self.loop) + test_utils.run_until(self.loop, lambda: proto.nbytes >= 1) self.assertEqual(1, proto.nbytes) os.write(wpipe, b'2345') - test_utils.run_briefly(self.loop) + test_utils.run_until(self.loop, lambda: proto.nbytes >= 5) self.assertEqual(['INITIAL', 'CONNECTED'], proto.state) self.assertEqual(5, proto.nbytes) @@ -842,38 +1229,71 @@ def connect(): @unittest.skipUnless(sys.platform != 'win32', "Don't support pipes for Windows") - def test_write_pipe(self): - proto = None - transport = None - - def factory(): - nonlocal proto - proto = MyWritePipeProto(loop=self.loop) - return proto - - rpipe, wpipe = os.pipe() - pipeobj = io.open(wpipe, 'wb', 1024) - - @tasks.coroutine + # select, poll and kqueue don't support character devices (PTY) on Mac OS X + # older than 10.6 (Snow Leopard) + @support.requires_mac_ver(10, 6) + # Issue #20495: The test hangs on FreeBSD 7.2 but pass on FreeBSD 9 + @support.requires_freebsd_version(8) + def test_read_pty_output(self): + proto = MyReadPipeProto(loop=self.loop) + + master, slave = os.openpty() + master_read_obj = io.open(master, 'rb', 0) + + @asyncio.coroutine def connect(): - nonlocal transport - t, p = yield from self.loop.connect_write_pipe(factory, pipeobj) + t, p = yield from self.loop.connect_read_pipe(lambda: proto, + master_read_obj) self.assertIs(p, proto) self.assertIs(t, proto.transport) - self.assertEqual('CONNECTED', proto.state) - transport = t + self.assertEqual(['INITIAL', 'CONNECTED'], proto.state) + self.assertEqual(0, proto.nbytes) self.loop.run_until_complete(connect()) + os.write(slave, b'1') + test_utils.run_until(self.loop, lambda: proto.nbytes) + self.assertEqual(1, proto.nbytes) + + os.write(slave, b'2345') + test_utils.run_until(self.loop, lambda: proto.nbytes >= 5) + self.assertEqual(['INITIAL', 'CONNECTED'], proto.state) + self.assertEqual(5, proto.nbytes) + + os.close(slave) + self.loop.run_until_complete(proto.done) + self.assertEqual( + ['INITIAL', 'CONNECTED', 'EOF', 'CLOSED'], proto.state) + # extra info is available + self.assertIsNotNone(proto.transport.get_extra_info('pipe')) + + @unittest.skipUnless(sys.platform != 'win32', + "Don't support pipes for Windows") + def test_write_pipe(self): + rpipe, wpipe = os.pipe() + pipeobj = io.open(wpipe, 'wb', 1024) + + proto = MyWritePipeProto(loop=self.loop) + connect = self.loop.connect_write_pipe(lambda: proto, pipeobj) + transport, p = self.loop.run_until_complete(connect) + self.assertIs(p, proto) + self.assertIs(transport, proto.transport) + self.assertEqual('CONNECTED', proto.state) + transport.write(b'1') - test_utils.run_briefly(self.loop) - data = os.read(rpipe, 1024) + + data = bytearray() + def reader(data): + chunk = os.read(rpipe, 1024) + data += chunk + return len(data) + + test_utils.run_until(self.loop, lambda: reader(data) >= 1) self.assertEqual(b'1', data) transport.write(b'2345') - test_utils.run_briefly(self.loop) - data = os.read(rpipe, 1024) - self.assertEqual(b'2345', data) + test_utils.run_until(self.loop, lambda: reader(data) >= 5) + self.assertEqual(b'12345', data) self.assertEqual('CONNECTED', proto.state) os.close(rpipe) @@ -889,28 +1309,15 @@ def connect(): @unittest.skipUnless(sys.platform != 'win32', "Don't support pipes for Windows") def test_write_pipe_disconnect_on_close(self): - proto = None - transport = None - - def factory(): - nonlocal proto - proto = MyWritePipeProto(loop=self.loop) - return proto - rsock, wsock = test_utils.socketpair() + rsock.setblocking(False) pipeobj = io.open(wsock.detach(), 'wb', 1024) - @tasks.coroutine - def connect(): - nonlocal transport - t, p = yield from self.loop.connect_write_pipe(factory, - pipeobj) - self.assertIs(p, proto) - self.assertIs(t, proto.transport) - self.assertEqual('CONNECTED', proto.state) - transport = t - - self.loop.run_until_complete(connect()) + proto = MyWritePipeProto(loop=self.loop) + connect = self.loop.connect_write_pipe(lambda: proto, pipeobj) + transport, p = self.loop.run_until_complete(connect) + self.assertIs(p, proto) + self.assertIs(transport, proto.transport) self.assertEqual('CONNECTED', proto.state) transport.write(b'1') @@ -922,6 +1329,50 @@ def connect(): self.loop.run_until_complete(proto.done) self.assertEqual('CLOSED', proto.state) + @unittest.skipUnless(sys.platform != 'win32', + "Don't support pipes for Windows") + # select, poll and kqueue don't support character devices (PTY) on Mac OS X + # older than 10.6 (Snow Leopard) + @support.requires_mac_ver(10, 6) + def test_write_pty(self): + master, slave = os.openpty() + slave_write_obj = io.open(slave, 'wb', 0) + + proto = MyWritePipeProto(loop=self.loop) + connect = self.loop.connect_write_pipe(lambda: proto, slave_write_obj) + transport, p = self.loop.run_until_complete(connect) + self.assertIs(p, proto) + self.assertIs(transport, proto.transport) + self.assertEqual('CONNECTED', proto.state) + + transport.write(b'1') + + data = bytearray() + def reader(data): + chunk = os.read(master, 1024) + data += chunk + return len(data) + + test_utils.run_until(self.loop, lambda: reader(data) >= 1, + timeout=10) + self.assertEqual(b'1', data) + + transport.write(b'2345') + test_utils.run_until(self.loop, lambda: reader(data) >= 5, + timeout=10) + self.assertEqual(b'12345', data) + self.assertEqual('CONNECTED', proto.state) + + os.close(master) + + # extra info is available + self.assertIsNotNone(proto.transport.get_extra_info('pipe')) + + # close connection + proto.transport.close() + self.loop.run_until_complete(proto.done) + self.assertEqual('CLOSED', proto.state) + def test_prompt_cancellation(self): r, w = test_utils.socketpair() r.setblocking(False) @@ -930,12 +1381,12 @@ def test_prompt_cancellation(self): if ov is not None: self.assertTrue(ov.pending) - @tasks.coroutine + @asyncio.coroutine def main(): try: self.loop.call_soon(f.cancel) yield from f - except futures.CancelledError: + except asyncio.CancelledError: res = 'cancelled' else: res = None @@ -944,13 +1395,13 @@ def main(): return res start = time.monotonic() - t = tasks.Task(main(), loop=self.loop) + t = asyncio.Task(main(), loop=self.loop) self.loop.run_forever() elapsed = time.monotonic() - start self.assertLess(elapsed, 0.1) self.assertEqual(t.result(), 'cancelled') - self.assertRaises(futures.CancelledError, f.result) + self.assertRaises(asyncio.CancelledError, f.result) if ov is not None: self.assertFalse(ov.pending) self.loop._stop_serving(r) @@ -958,6 +1409,121 @@ def main(): r.close() w.close() + def test_timeout_rounding(self): + def _run_once(): + self.loop._run_once_counter += 1 + orig_run_once() + + orig_run_once = self.loop._run_once + self.loop._run_once_counter = 0 + self.loop._run_once = _run_once + + @asyncio.coroutine + def wait(): + loop = self.loop + yield from asyncio.sleep(1e-2, loop=loop) + yield from asyncio.sleep(1e-4, loop=loop) + yield from asyncio.sleep(1e-6, loop=loop) + yield from asyncio.sleep(1e-8, loop=loop) + yield from asyncio.sleep(1e-10, loop=loop) + + self.loop.run_until_complete(wait()) + # The ideal number of call is 12, but on some platforms, the selector + # may sleep at little bit less than timeout depending on the resolution + # of the clock used by the kernel. Tolerate a few useless calls on + # these platforms. + self.assertLessEqual(self.loop._run_once_counter, 20, + {'clock_resolution': self.loop._clock_resolution, + 'selector': self.loop._selector.__class__.__name__}) + + def test_sock_connect_address(self): + # In debug mode, sock_connect() must ensure that the address is already + # resolved (call _check_resolved_address()) + self.loop.set_debug(True) + + addresses = [(socket.AF_INET, ('www.python.org', 80))] + if support.IPV6_ENABLED: + addresses.extend(( + (socket.AF_INET6, ('www.python.org', 80)), + (socket.AF_INET6, ('www.python.org', 80, 0, 0)), + )) + + for family, address in addresses: + for sock_type in (socket.SOCK_STREAM, socket.SOCK_DGRAM): + sock = socket.socket(family, sock_type) + with sock: + sock.setblocking(False) + connect = self.loop.sock_connect(sock, address) + with self.assertRaises(ValueError) as cm: + self.loop.run_until_complete(connect) + self.assertIn('address must be resolved', + str(cm.exception)) + + def test_remove_fds_after_closing(self): + loop = self.create_event_loop() + callback = lambda: None + r, w = test_utils.socketpair() + self.addCleanup(r.close) + self.addCleanup(w.close) + loop.add_reader(r, callback) + loop.add_writer(w, callback) + loop.close() + self.assertFalse(loop.remove_reader(r)) + self.assertFalse(loop.remove_writer(w)) + + def test_add_fds_after_closing(self): + loop = self.create_event_loop() + callback = lambda: None + r, w = test_utils.socketpair() + self.addCleanup(r.close) + self.addCleanup(w.close) + loop.close() + with self.assertRaises(RuntimeError): + loop.add_reader(r, callback) + with self.assertRaises(RuntimeError): + loop.add_writer(w, callback) + + def test_close_running_event_loop(self): + @asyncio.coroutine + def close_loop(loop): + self.loop.close() + + coro = close_loop(self.loop) + with self.assertRaises(RuntimeError): + self.loop.run_until_complete(coro) + + def test_close(self): + self.loop.close() + + @asyncio.coroutine + def test(): + pass + + func = lambda: False + coro = test() + self.addCleanup(coro.close) + + # operation blocked when the loop is closed + with self.assertRaises(RuntimeError): + self.loop.run_forever() + with self.assertRaises(RuntimeError): + fut = asyncio.Future(loop=self.loop) + self.loop.run_until_complete(fut) + with self.assertRaises(RuntimeError): + self.loop.call_soon(func) + with self.assertRaises(RuntimeError): + self.loop.call_soon_threadsafe(func) + with self.assertRaises(RuntimeError): + self.loop.call_later(1.0, func) + with self.assertRaises(RuntimeError): + self.loop.call_at(self.loop.time() + .0, func) + with self.assertRaises(RuntimeError): + self.loop.run_in_executor(None, func) + with self.assertRaises(RuntimeError): + self.loop.create_task(coro) + with self.assertRaises(RuntimeError): + self.loop.add_signal_handler(signal.SIGTERM, func) + class SubprocessTestsMixin: @@ -976,78 +1542,57 @@ def check_killed(self, returncode): self.assertEqual(-signal.SIGKILL, returncode) def test_subprocess_exec(self): - proto = None - transp = None - prog = os.path.join(os.path.dirname(__file__), 'echo.py') - @tasks.coroutine - def connect(): - nonlocal proto, transp - transp, proto = yield from self.loop.subprocess_exec( - functools.partial(MySubprocessProtocol, self.loop), - sys.executable, prog) - self.assertIsInstance(proto, MySubprocessProtocol) - - self.loop.run_until_complete(connect()) + connect = self.loop.subprocess_exec( + functools.partial(MySubprocessProtocol, self.loop), + sys.executable, prog) + transp, proto = self.loop.run_until_complete(connect) + self.assertIsInstance(proto, MySubprocessProtocol) self.loop.run_until_complete(proto.connected) self.assertEqual('CONNECTED', proto.state) stdin = transp.get_pipe_transport(0) stdin.write(b'Python The Winner') self.loop.run_until_complete(proto.got_data[1].wait()) - transp.close() + with test_utils.disable_logger(): + transp.close() self.loop.run_until_complete(proto.completed) - self.check_terminated(proto.returncode) + self.check_killed(proto.returncode) self.assertEqual(b'Python The Winner', proto.data[1]) def test_subprocess_interactive(self): - proto = None - transp = None - prog = os.path.join(os.path.dirname(__file__), 'echo.py') - @tasks.coroutine - def connect(): - nonlocal proto, transp - transp, proto = yield from self.loop.subprocess_exec( - functools.partial(MySubprocessProtocol, self.loop), - sys.executable, prog) - self.assertIsInstance(proto, MySubprocessProtocol) - - self.loop.run_until_complete(connect()) + connect = self.loop.subprocess_exec( + functools.partial(MySubprocessProtocol, self.loop), + sys.executable, prog) + transp, proto = self.loop.run_until_complete(connect) + self.assertIsInstance(proto, MySubprocessProtocol) self.loop.run_until_complete(proto.connected) self.assertEqual('CONNECTED', proto.state) - try: - stdin = transp.get_pipe_transport(0) - stdin.write(b'Python ') - self.loop.run_until_complete(proto.got_data[1].wait()) - proto.got_data[1].clear() - self.assertEqual(b'Python ', proto.data[1]) - - stdin.write(b'The Winner') - self.loop.run_until_complete(proto.got_data[1].wait()) - self.assertEqual(b'Python The Winner', proto.data[1]) - finally: - transp.close() + stdin = transp.get_pipe_transport(0) + stdin.write(b'Python ') + self.loop.run_until_complete(proto.got_data[1].wait()) + proto.got_data[1].clear() + self.assertEqual(b'Python ', proto.data[1]) + + stdin.write(b'The Winner') + self.loop.run_until_complete(proto.got_data[1].wait()) + self.assertEqual(b'Python The Winner', proto.data[1]) + with test_utils.disable_logger(): + transp.close() self.loop.run_until_complete(proto.completed) - self.check_terminated(proto.returncode) + self.check_killed(proto.returncode) def test_subprocess_shell(self): - proto = None - transp = None - - @tasks.coroutine - def connect(): - nonlocal proto, transp - transp, proto = yield from self.loop.subprocess_shell( - functools.partial(MySubprocessProtocol, self.loop), - 'echo Python') - self.assertIsInstance(proto, MySubprocessProtocol) - - self.loop.run_until_complete(connect()) + connect = self.loop.subprocess_shell( + functools.partial(MySubprocessProtocol, self.loop), + 'echo Python') + transp, proto = self.loop.run_until_complete(connect) + self.assertIsInstance(proto, MySubprocessProtocol) self.loop.run_until_complete(proto.connected) transp.get_pipe_transport(0).close() @@ -1056,35 +1601,24 @@ def connect(): self.assertTrue(all(f.done() for f in proto.disconnects.values())) self.assertEqual(proto.data[1].rstrip(b'\r\n'), b'Python') self.assertEqual(proto.data[2], b'') + transp.close() def test_subprocess_exitcode(self): - proto = None - - @tasks.coroutine - def connect(): - nonlocal proto - transp, proto = yield from self.loop.subprocess_shell( - functools.partial(MySubprocessProtocol, self.loop), - 'exit 7', stdin=None, stdout=None, stderr=None) - self.assertIsInstance(proto, MySubprocessProtocol) - - self.loop.run_until_complete(connect()) + connect = self.loop.subprocess_shell( + functools.partial(MySubprocessProtocol, self.loop), + 'exit 7', stdin=None, stdout=None, stderr=None) + transp, proto = self.loop.run_until_complete(connect) + self.assertIsInstance(proto, MySubprocessProtocol) self.loop.run_until_complete(proto.completed) self.assertEqual(7, proto.returncode) + transp.close() def test_subprocess_close_after_finish(self): - proto = None - transp = None - - @tasks.coroutine - def connect(): - nonlocal proto, transp - transp, proto = yield from self.loop.subprocess_shell( - functools.partial(MySubprocessProtocol, self.loop), - 'exit 7', stdin=None, stdout=None, stderr=None) - self.assertIsInstance(proto, MySubprocessProtocol) - - self.loop.run_until_complete(connect()) + connect = self.loop.subprocess_shell( + functools.partial(MySubprocessProtocol, self.loop), + 'exit 7', stdin=None, stdout=None, stderr=None) + transp, proto = self.loop.run_until_complete(connect) + self.assertIsInstance(proto, MySubprocessProtocol) self.assertIsNone(transp.get_pipe_transport(0)) self.assertIsNone(transp.get_pipe_transport(1)) self.assertIsNone(transp.get_pipe_transport(2)) @@ -1093,84 +1627,59 @@ def connect(): self.assertIsNone(transp.close()) def test_subprocess_kill(self): - proto = None - transp = None - prog = os.path.join(os.path.dirname(__file__), 'echo.py') - @tasks.coroutine - def connect(): - nonlocal proto, transp - transp, proto = yield from self.loop.subprocess_exec( - functools.partial(MySubprocessProtocol, self.loop), - sys.executable, prog) - self.assertIsInstance(proto, MySubprocessProtocol) - - self.loop.run_until_complete(connect()) + connect = self.loop.subprocess_exec( + functools.partial(MySubprocessProtocol, self.loop), + sys.executable, prog) + transp, proto = self.loop.run_until_complete(connect) + self.assertIsInstance(proto, MySubprocessProtocol) self.loop.run_until_complete(proto.connected) transp.kill() self.loop.run_until_complete(proto.completed) self.check_killed(proto.returncode) + transp.close() def test_subprocess_terminate(self): - proto = None - transp = None - prog = os.path.join(os.path.dirname(__file__), 'echo.py') - @tasks.coroutine - def connect(): - nonlocal proto, transp - transp, proto = yield from self.loop.subprocess_exec( - functools.partial(MySubprocessProtocol, self.loop), - sys.executable, prog) - self.assertIsInstance(proto, MySubprocessProtocol) - - self.loop.run_until_complete(connect()) + connect = self.loop.subprocess_exec( + functools.partial(MySubprocessProtocol, self.loop), + sys.executable, prog) + transp, proto = self.loop.run_until_complete(connect) + self.assertIsInstance(proto, MySubprocessProtocol) self.loop.run_until_complete(proto.connected) transp.terminate() self.loop.run_until_complete(proto.completed) self.check_terminated(proto.returncode) + transp.close() @unittest.skipIf(sys.platform == 'win32', "Don't have SIGHUP") def test_subprocess_send_signal(self): - proto = None - transp = None - prog = os.path.join(os.path.dirname(__file__), 'echo.py') - @tasks.coroutine - def connect(): - nonlocal proto, transp - transp, proto = yield from self.loop.subprocess_exec( - functools.partial(MySubprocessProtocol, self.loop), - sys.executable, prog) - self.assertIsInstance(proto, MySubprocessProtocol) - - self.loop.run_until_complete(connect()) + connect = self.loop.subprocess_exec( + functools.partial(MySubprocessProtocol, self.loop), + sys.executable, prog) + transp, proto = self.loop.run_until_complete(connect) + self.assertIsInstance(proto, MySubprocessProtocol) self.loop.run_until_complete(proto.connected) transp.send_signal(signal.SIGHUP) self.loop.run_until_complete(proto.completed) self.assertEqual(-signal.SIGHUP, proto.returncode) + transp.close() def test_subprocess_stderr(self): - proto = None - transp = None - prog = os.path.join(os.path.dirname(__file__), 'echo2.py') - @tasks.coroutine - def connect(): - nonlocal proto, transp - transp, proto = yield from self.loop.subprocess_exec( - functools.partial(MySubprocessProtocol, self.loop), - sys.executable, prog) - self.assertIsInstance(proto, MySubprocessProtocol) - - self.loop.run_until_complete(connect()) + connect = self.loop.subprocess_exec( + functools.partial(MySubprocessProtocol, self.loop), + sys.executable, prog) + transp, proto = self.loop.run_until_complete(connect) + self.assertIsInstance(proto, MySubprocessProtocol) self.loop.run_until_complete(proto.connected) stdin = transp.get_pipe_transport(0) @@ -1184,20 +1693,13 @@ def connect(): self.assertEqual(0, proto.returncode) def test_subprocess_stderr_redirect_to_stdout(self): - proto = None - transp = None - prog = os.path.join(os.path.dirname(__file__), 'echo2.py') - @tasks.coroutine - def connect(): - nonlocal proto, transp - transp, proto = yield from self.loop.subprocess_exec( - functools.partial(MySubprocessProtocol, self.loop), - sys.executable, prog, stderr=subprocess.STDOUT) - self.assertIsInstance(proto, MySubprocessProtocol) - - self.loop.run_until_complete(connect()) + connect = self.loop.subprocess_exec( + functools.partial(MySubprocessProtocol, self.loop), + sys.executable, prog, stderr=subprocess.STDOUT) + transp, proto = self.loop.run_until_complete(connect) + self.assertIsInstance(proto, MySubprocessProtocol) self.loop.run_until_complete(proto.connected) stdin = transp.get_pipe_transport(0) @@ -1214,20 +1716,13 @@ def connect(): self.assertEqual(0, proto.returncode) def test_subprocess_close_client_stream(self): - proto = None - transp = None - prog = os.path.join(os.path.dirname(__file__), 'echo3.py') - @tasks.coroutine - def connect(): - nonlocal proto, transp - transp, proto = yield from self.loop.subprocess_exec( - functools.partial(MySubprocessProtocol, self.loop), - sys.executable, prog) - self.assertIsInstance(proto, MySubprocessProtocol) - - self.loop.run_until_complete(connect()) + connect = self.loop.subprocess_exec( + functools.partial(MySubprocessProtocol, self.loop), + sys.executable, prog) + transp, proto = self.loop.run_until_complete(connect) + self.assertIsInstance(proto, MySubprocessProtocol) self.loop.run_until_complete(proto.connected) stdin = transp.get_pipe_transport(0) @@ -1248,49 +1743,99 @@ def connect(): # GetLastError()==ERROR_INVALID_NAME on Windows!?! (Using # WriteFile() we get ERROR_BROKEN_PIPE as expected.) self.assertEqual(b'ERR:OSError', proto.data[2]) - transp.close() + with test_utils.disable_logger(): + transp.close() self.loop.run_until_complete(proto.completed) - self.check_terminated(proto.returncode) + self.check_killed(proto.returncode) def test_subprocess_wait_no_same_group(self): - proto = None - transp = None - - @tasks.coroutine - def connect(): - nonlocal proto - # start the new process in a new session - transp, proto = yield from self.loop.subprocess_shell( - functools.partial(MySubprocessProtocol, self.loop), - 'exit 7', stdin=None, stdout=None, stderr=None, - start_new_session=True) - self.assertIsInstance(proto, MySubprocessProtocol) - - self.loop.run_until_complete(connect()) + # start the new process in a new session + connect = self.loop.subprocess_shell( + functools.partial(MySubprocessProtocol, self.loop), + 'exit 7', stdin=None, stdout=None, stderr=None, + start_new_session=True) + _, proto = yield self.loop.run_until_complete(connect) + self.assertIsInstance(proto, MySubprocessProtocol) self.loop.run_until_complete(proto.completed) self.assertEqual(7, proto.returncode) + def test_subprocess_exec_invalid_args(self): + @asyncio.coroutine + def connect(**kwds): + yield from self.loop.subprocess_exec( + asyncio.SubprocessProtocol, + 'pwd', **kwds) + + with self.assertRaises(ValueError): + self.loop.run_until_complete(connect(universal_newlines=True)) + with self.assertRaises(ValueError): + self.loop.run_until_complete(connect(bufsize=4096)) + with self.assertRaises(ValueError): + self.loop.run_until_complete(connect(shell=True)) + + def test_subprocess_shell_invalid_args(self): + @asyncio.coroutine + def connect(cmd=None, **kwds): + if not cmd: + cmd = 'pwd' + yield from self.loop.subprocess_shell( + asyncio.SubprocessProtocol, + cmd, **kwds) + + with self.assertRaises(ValueError): + self.loop.run_until_complete(connect(['ls', '-l'])) + with self.assertRaises(ValueError): + self.loop.run_until_complete(connect(universal_newlines=True)) + with self.assertRaises(ValueError): + self.loop.run_until_complete(connect(bufsize=4096)) + with self.assertRaises(ValueError): + self.loop.run_until_complete(connect(shell=False)) + if sys.platform == 'win32': - from asyncio import windows_events - class SelectEventLoopTests(EventLoopTestsMixin, unittest.TestCase): + class SelectEventLoopTests(EventLoopTestsMixin, test_utils.TestCase): def create_event_loop(self): - return windows_events.SelectorEventLoop() + return asyncio.SelectorEventLoop() class ProactorEventLoopTests(EventLoopTestsMixin, SubprocessTestsMixin, - unittest.TestCase): + test_utils.TestCase): def create_event_loop(self): - return windows_events.ProactorEventLoop() + return asyncio.ProactorEventLoop() + + if not sslproto._is_sslproto_available(): + def test_create_ssl_connection(self): + raise unittest.SkipTest("need python 3.5 (ssl.MemoryBIO)") + + def test_create_server_ssl(self): + raise unittest.SkipTest("need python 3.5 (ssl.MemoryBIO)") + + def test_create_server_ssl_verify_failed(self): + raise unittest.SkipTest("need python 3.5 (ssl.MemoryBIO)") + + def test_create_server_ssl_match_failed(self): + raise unittest.SkipTest("need python 3.5 (ssl.MemoryBIO)") + + def test_create_server_ssl_verified(self): + raise unittest.SkipTest("need python 3.5 (ssl.MemoryBIO)") - def test_create_ssl_connection(self): - raise unittest.SkipTest("IocpEventLoop imcompatible with SSL") + def test_legacy_create_ssl_connection(self): + raise unittest.SkipTest("IocpEventLoop incompatible with legacy SSL") - def test_create_server_ssl(self): - raise unittest.SkipTest("IocpEventLoop imcompatible with SSL") + def test_legacy_create_server_ssl(self): + raise unittest.SkipTest("IocpEventLoop incompatible with legacy SSL") + + def test_legacy_create_server_ssl_verify_failed(self): + raise unittest.SkipTest("IocpEventLoop incompatible with legacy SSL") + + def test_legacy_create_server_ssl_match_failed(self): + raise unittest.SkipTest("IocpEventLoop incompatible with legacy SSL") + + def test_legacy_create_server_ssl_verified(self): + raise unittest.SkipTest("IocpEventLoop incompatible with legacy SSL") def test_reader_callback(self): raise unittest.SkipTest("IocpEventLoop does not have add_reader()") @@ -1307,128 +1852,290 @@ def test_writer_callback_cancel(self): def test_create_datagram_endpoint(self): raise unittest.SkipTest( "IocpEventLoop does not have create_datagram_endpoint()") + + def test_remove_fds_after_closing(self): + raise unittest.SkipTest("IocpEventLoop does not have add_reader()") else: from asyncio import selectors - from asyncio import unix_events class UnixEventLoopTestsMixin(EventLoopTestsMixin): def setUp(self): super().setUp() - watcher = unix_events.SafeChildWatcher() + watcher = asyncio.SafeChildWatcher() watcher.attach_loop(self.loop) - events.set_child_watcher(watcher) + asyncio.set_child_watcher(watcher) def tearDown(self): - events.set_child_watcher(None) + asyncio.set_child_watcher(None) super().tearDown() if hasattr(selectors, 'KqueueSelector'): class KqueueEventLoopTests(UnixEventLoopTestsMixin, SubprocessTestsMixin, - unittest.TestCase): + test_utils.TestCase): def create_event_loop(self): - return unix_events.SelectorEventLoop( + return asyncio.SelectorEventLoop( selectors.KqueueSelector()) + # kqueue doesn't support character devices (PTY) on Mac OS X older + # than 10.9 (Maverick) + @support.requires_mac_ver(10, 9) + # Issue #20667: KqueueEventLoopTests.test_read_pty_output() + # hangs on OpenBSD 5.5 + @unittest.skipIf(sys.platform.startswith('openbsd'), + 'test hangs on OpenBSD') + def test_read_pty_output(self): + super().test_read_pty_output() + + # kqueue doesn't support character devices (PTY) on Mac OS X older + # than 10.9 (Maverick) + @support.requires_mac_ver(10, 9) + def test_write_pty(self): + super().test_write_pty() + if hasattr(selectors, 'EpollSelector'): class EPollEventLoopTests(UnixEventLoopTestsMixin, SubprocessTestsMixin, - unittest.TestCase): + test_utils.TestCase): def create_event_loop(self): - return unix_events.SelectorEventLoop(selectors.EpollSelector()) + return asyncio.SelectorEventLoop(selectors.EpollSelector()) if hasattr(selectors, 'PollSelector'): class PollEventLoopTests(UnixEventLoopTestsMixin, SubprocessTestsMixin, - unittest.TestCase): + test_utils.TestCase): def create_event_loop(self): - return unix_events.SelectorEventLoop(selectors.PollSelector()) + return asyncio.SelectorEventLoop(selectors.PollSelector()) # Should always exist. class SelectEventLoopTests(UnixEventLoopTestsMixin, SubprocessTestsMixin, - unittest.TestCase): + test_utils.TestCase): def create_event_loop(self): - return unix_events.SelectorEventLoop(selectors.SelectSelector()) + return asyncio.SelectorEventLoop(selectors.SelectSelector()) -class HandleTests(unittest.TestCase): +def noop(*args): + pass + + +class HandleTests(test_utils.TestCase): + + def setUp(self): + self.loop = mock.Mock() + self.loop.get_debug.return_value = True def test_handle(self): def callback(*args): return args args = () - h = events.Handle(callback, args) + h = asyncio.Handle(callback, args, self.loop) self.assertIs(h._callback, callback) self.assertIs(h._args, args) self.assertFalse(h._cancelled) - r = repr(h) - self.assertTrue(r.startswith( - 'Handle(' - '<function HandleTests.test_handle.<locals>.callback')) - self.assertTrue(r.endswith('())')) - h.cancel() self.assertTrue(h._cancelled) - r = repr(h) - self.assertTrue(r.startswith( - 'Handle(' - '<function HandleTests.test_handle.<locals>.callback')) - self.assertTrue(r.endswith('())<cancelled>'), r) - - def test_make_handle(self): + def test_handle_from_handle(self): def callback(*args): return args - h1 = events.Handle(callback, ()) + h1 = asyncio.Handle(callback, (), loop=self.loop) self.assertRaises( - AssertionError, events.make_handle, h1, ()) + AssertionError, asyncio.Handle, h1, (), self.loop) - @unittest.mock.patch('asyncio.events.logger') - def test_callback_with_exception(self, log): + def test_callback_with_exception(self): def callback(): raise ValueError() - h = events.Handle(callback, ()) + self.loop = mock.Mock() + self.loop.call_exception_handler = mock.Mock() + + h = asyncio.Handle(callback, (), self.loop) h._run() - self.assertTrue(log.exception.called) + + self.loop.call_exception_handler.assert_called_with({ + 'message': test_utils.MockPattern('Exception in callback.*'), + 'exception': mock.ANY, + 'handle': h, + 'source_traceback': h._source_traceback, + }) + + def test_handle_weakref(self): + wd = weakref.WeakValueDictionary() + h = asyncio.Handle(lambda: None, (), self.loop) + wd['h'] = h # Would fail without __weakref__ slot. + + def test_handle_repr(self): + self.loop.get_debug.return_value = False + + # simple function + h = asyncio.Handle(noop, (1, 2), self.loop) + filename, lineno = test_utils.get_function_source(noop) + self.assertEqual(repr(h), + '<Handle noop(1, 2) at %s:%s>' + % (filename, lineno)) + + # cancelled handle + h.cancel() + self.assertEqual(repr(h), + '<Handle cancelled>') + + # decorated function + cb = asyncio.coroutine(noop) + h = asyncio.Handle(cb, (), self.loop) + self.assertEqual(repr(h), + '<Handle noop() at %s:%s>' + % (filename, lineno)) + + # partial function + cb = functools.partial(noop, 1, 2) + h = asyncio.Handle(cb, (3,), self.loop) + regex = (r'^<Handle noop\(1, 2\)\(3\) at %s:%s>$' + % (re.escape(filename), lineno)) + self.assertRegex(repr(h), regex) + + # partial method + if sys.version_info >= (3, 4): + method = HandleTests.test_handle_repr + cb = functools.partialmethod(method) + filename, lineno = test_utils.get_function_source(method) + h = asyncio.Handle(cb, (), self.loop) + + cb_regex = r'<function HandleTests.test_handle_repr .*>' + cb_regex = (r'functools.partialmethod\(%s, , \)\(\)' % cb_regex) + regex = (r'^<Handle %s at %s:%s>$' + % (cb_regex, re.escape(filename), lineno)) + self.assertRegex(repr(h), regex) + + def test_handle_repr_debug(self): + self.loop.get_debug.return_value = True + + # simple function + create_filename = __file__ + create_lineno = sys._getframe().f_lineno + 1 + h = asyncio.Handle(noop, (1, 2), self.loop) + filename, lineno = test_utils.get_function_source(noop) + self.assertEqual(repr(h), + '<Handle noop(1, 2) at %s:%s created at %s:%s>' + % (filename, lineno, create_filename, create_lineno)) + + # cancelled handle + h.cancel() + self.assertEqual( + repr(h), + '<Handle cancelled noop(1, 2) at %s:%s created at %s:%s>' + % (filename, lineno, create_filename, create_lineno)) + + # double cancellation won't overwrite _repr + h.cancel() + self.assertEqual( + repr(h), + '<Handle cancelled noop(1, 2) at %s:%s created at %s:%s>' + % (filename, lineno, create_filename, create_lineno)) + + def test_handle_source_traceback(self): + loop = asyncio.get_event_loop_policy().new_event_loop() + loop.set_debug(True) + self.set_event_loop(loop) + + def check_source_traceback(h): + lineno = sys._getframe(1).f_lineno - 1 + self.assertIsInstance(h._source_traceback, list) + self.assertEqual(h._source_traceback[-1][:3], + (__file__, + lineno, + 'test_handle_source_traceback')) + + # call_soon + h = loop.call_soon(noop) + check_source_traceback(h) + + # call_soon_threadsafe + h = loop.call_soon_threadsafe(noop) + check_source_traceback(h) + + # call_later + h = loop.call_later(0, noop) + check_source_traceback(h) + + # call_at + h = loop.call_later(0, noop) + check_source_traceback(h) class TimerTests(unittest.TestCase): + def setUp(self): + self.loop = mock.Mock() + def test_hash(self): when = time.monotonic() - h = events.TimerHandle(when, lambda: False, ()) + h = asyncio.TimerHandle(when, lambda: False, (), + mock.Mock()) self.assertEqual(hash(h), hash(when)) def test_timer(self): def callback(*args): return args - args = () + args = (1, 2, 3) when = time.monotonic() - h = events.TimerHandle(when, callback, args) + h = asyncio.TimerHandle(when, callback, args, mock.Mock()) self.assertIs(h._callback, callback) self.assertIs(h._args, args) self.assertFalse(h._cancelled) - r = repr(h) - self.assertTrue(r.endswith('())')) - + # cancel h.cancel() self.assertTrue(h._cancelled) + self.assertIsNone(h._callback) + self.assertIsNone(h._args) - r = repr(h) - self.assertTrue(r.endswith('())<cancelled>'), r) - + # when cannot be None self.assertRaises(AssertionError, - events.TimerHandle, None, callback, args) + asyncio.TimerHandle, None, callback, args, + self.loop) + + def test_timer_repr(self): + self.loop.get_debug.return_value = False + + # simple function + h = asyncio.TimerHandle(123, noop, (), self.loop) + src = test_utils.get_function_source(noop) + self.assertEqual(repr(h), + '<TimerHandle when=123 noop() at %s:%s>' % src) + + # cancelled handle + h.cancel() + self.assertEqual(repr(h), + '<TimerHandle cancelled when=123>') + + def test_timer_repr_debug(self): + self.loop.get_debug.return_value = True + + # simple function + create_filename = __file__ + create_lineno = sys._getframe().f_lineno + 1 + h = asyncio.TimerHandle(123, noop, (), self.loop) + filename, lineno = test_utils.get_function_source(noop) + self.assertEqual(repr(h), + '<TimerHandle when=123 noop() ' + 'at %s:%s created at %s:%s>' + % (filename, lineno, create_filename, create_lineno)) + + # cancelled handle + h.cancel() + self.assertEqual(repr(h), + '<TimerHandle cancelled when=123 noop() ' + 'at %s:%s created at %s:%s>' + % (filename, lineno, create_filename, create_lineno)) + def test_timer_comparison(self): def callback(*args): @@ -1436,8 +2143,8 @@ def callback(*args): when = time.monotonic() - h1 = events.TimerHandle(when, callback, ()) - h2 = events.TimerHandle(when, callback, ()) + h1 = asyncio.TimerHandle(when, callback, (), self.loop) + h2 = asyncio.TimerHandle(when, callback, (), self.loop) # TODO: Use assertLess etc. self.assertFalse(h1 < h2) self.assertFalse(h2 < h1) @@ -1453,8 +2160,8 @@ def callback(*args): h2.cancel() self.assertFalse(h1 == h2) - h1 = events.TimerHandle(when, callback, ()) - h2 = events.TimerHandle(when + 10.0, callback, ()) + h1 = asyncio.TimerHandle(when, callback, (), self.loop) + h2 = asyncio.TimerHandle(when + 10.0, callback, (), self.loop) self.assertTrue(h1 < h2) self.assertFalse(h2 < h1) self.assertTrue(h1 <= h2) @@ -1466,7 +2173,7 @@ def callback(*args): self.assertFalse(h1 == h2) self.assertTrue(h1 != h2) - h3 = events.Handle(callback, ()) + h3 = asyncio.Handle(callback, (), self.loop) self.assertIs(NotImplemented, h1.__eq__(h3)) self.assertIs(NotImplemented, h1.__ne__(h3)) @@ -1474,8 +2181,8 @@ def callback(*args): class AbstractEventLoopTests(unittest.TestCase): def test_not_implemented(self): - f = unittest.mock.Mock() - loop = events.AbstractEventLoop() + f = mock.Mock() + loop = asyncio.AbstractEventLoop() self.assertRaises( NotImplementedError, loop.run_forever) self.assertRaises( @@ -1484,8 +2191,12 @@ def test_not_implemented(self): NotImplementedError, loop.stop) self.assertRaises( NotImplementedError, loop.is_running) + self.assertRaises( + NotImplementedError, loop.is_closed) self.assertRaises( NotImplementedError, loop.close) + self.assertRaises( + NotImplementedError, loop.create_task, None) self.assertRaises( NotImplementedError, loop.call_later, None, None) self.assertRaises( @@ -1534,34 +2245,44 @@ def test_not_implemented(self): NotImplementedError, loop.remove_signal_handler, 1) self.assertRaises( NotImplementedError, loop.connect_read_pipe, f, - unittest.mock.sentinel.pipe) + mock.sentinel.pipe) self.assertRaises( NotImplementedError, loop.connect_write_pipe, f, - unittest.mock.sentinel.pipe) + mock.sentinel.pipe) self.assertRaises( NotImplementedError, loop.subprocess_shell, f, - unittest.mock.sentinel) + mock.sentinel) self.assertRaises( NotImplementedError, loop.subprocess_exec, f) + self.assertRaises( + NotImplementedError, loop.set_exception_handler, f) + self.assertRaises( + NotImplementedError, loop.default_exception_handler, f) + self.assertRaises( + NotImplementedError, loop.call_exception_handler, f) + self.assertRaises( + NotImplementedError, loop.get_debug) + self.assertRaises( + NotImplementedError, loop.set_debug, f) class ProtocolsAbsTests(unittest.TestCase): def test_empty(self): - f = unittest.mock.Mock() - p = protocols.Protocol() + f = mock.Mock() + p = asyncio.Protocol() self.assertIsNone(p.connection_made(f)) self.assertIsNone(p.connection_lost(f)) self.assertIsNone(p.data_received(f)) self.assertIsNone(p.eof_received()) - dp = protocols.DatagramProtocol() + dp = asyncio.DatagramProtocol() self.assertIsNone(dp.connection_made(f)) self.assertIsNone(dp.connection_lost(f)) self.assertIsNone(dp.error_received(f)) self.assertIsNone(dp.datagram_received(f, f)) - sp = protocols.SubprocessProtocol() + sp = asyncio.SubprocessProtocol() self.assertIsNone(sp.connection_made(f)) self.assertIsNone(sp.connection_lost(f)) self.assertIsNone(sp.pipe_data_received(1, f)) @@ -1571,16 +2292,8 @@ def test_empty(self): class PolicyTests(unittest.TestCase): - def create_policy(self): - if sys.platform == "win32": - from asyncio import windows_events - return windows_events.DefaultEventLoopPolicy() - else: - from asyncio import unix_events - return unix_events.DefaultEventLoopPolicy() - def test_event_loop_policy(self): - policy = events.AbstractEventLoopPolicy() + policy = asyncio.AbstractEventLoopPolicy() self.assertRaises(NotImplementedError, policy.get_event_loop) self.assertRaises(NotImplementedError, policy.set_event_loop, object()) self.assertRaises(NotImplementedError, policy.new_event_loop) @@ -1589,20 +2302,20 @@ def test_event_loop_policy(self): object()) def test_get_event_loop(self): - policy = self.create_policy() + policy = asyncio.DefaultEventLoopPolicy() self.assertIsNone(policy._local._loop) loop = policy.get_event_loop() - self.assertIsInstance(loop, events.AbstractEventLoop) + self.assertIsInstance(loop, asyncio.AbstractEventLoop) self.assertIs(policy._local._loop, loop) self.assertIs(loop, policy.get_event_loop()) loop.close() def test_get_event_loop_calls_set_event_loop(self): - policy = self.create_policy() + policy = asyncio.DefaultEventLoopPolicy() - with unittest.mock.patch.object( + with mock.patch.object( policy, "set_event_loop", wraps=policy.set_event_loop) as m_set_event_loop: @@ -1616,30 +2329,30 @@ def test_get_event_loop_calls_set_event_loop(self): loop.close() def test_get_event_loop_after_set_none(self): - policy = self.create_policy() + policy = asyncio.DefaultEventLoopPolicy() policy.set_event_loop(None) - self.assertRaises(AssertionError, policy.get_event_loop) + self.assertRaises(RuntimeError, policy.get_event_loop) - @unittest.mock.patch('asyncio.events.threading.current_thread') + @mock.patch('asyncio.events.threading.current_thread') def test_get_event_loop_thread(self, m_current_thread): def f(): - policy = self.create_policy() - self.assertRaises(AssertionError, policy.get_event_loop) + policy = asyncio.DefaultEventLoopPolicy() + self.assertRaises(RuntimeError, policy.get_event_loop) th = threading.Thread(target=f) th.start() th.join() def test_new_event_loop(self): - policy = self.create_policy() + policy = asyncio.DefaultEventLoopPolicy() loop = policy.new_event_loop() - self.assertIsInstance(loop, events.AbstractEventLoop) + self.assertIsInstance(loop, asyncio.AbstractEventLoop) loop.close() def test_set_event_loop(self): - policy = self.create_policy() + policy = asyncio.DefaultEventLoopPolicy() old_loop = policy.get_event_loop() self.assertRaises(AssertionError, policy.set_event_loop, object()) @@ -1652,19 +2365,19 @@ def test_set_event_loop(self): old_loop.close() def test_get_event_loop_policy(self): - policy = events.get_event_loop_policy() - self.assertIsInstance(policy, events.AbstractEventLoopPolicy) - self.assertIs(policy, events.get_event_loop_policy()) + policy = asyncio.get_event_loop_policy() + self.assertIsInstance(policy, asyncio.AbstractEventLoopPolicy) + self.assertIs(policy, asyncio.get_event_loop_policy()) def test_set_event_loop_policy(self): self.assertRaises( - AssertionError, events.set_event_loop_policy, object()) + AssertionError, asyncio.set_event_loop_policy, object()) - old_policy = events.get_event_loop_policy() + old_policy = asyncio.get_event_loop_policy() - policy = self.create_policy() - events.set_event_loop_policy(policy) - self.assertIs(policy, events.get_event_loop_policy()) + policy = asyncio.DefaultEventLoopPolicy() + asyncio.set_event_loop_policy(policy) + self.assertIs(policy, asyncio.get_event_loop_policy()) self.assertIsNot(policy, old_policy) diff --git a/Lib/test/test_asyncio/test_futures.py b/Lib/test/test_asyncio/test_futures.py index e35fcf070855..c8b6829fb67c 100644 --- a/Lib/test/test_asyncio/test_futures.py +++ b/Lib/test/test_asyncio/test_futures.py @@ -1,87 +1,97 @@ """Tests for futures.py.""" import concurrent.futures +import re +import sys import threading import unittest -import unittest.mock +from unittest import mock -from asyncio import events -from asyncio import futures +import asyncio from asyncio import test_utils +try: + from test import support +except ImportError: + from asyncio import test_support as support def _fakefunc(f): return f +def first_cb(): + pass -class FutureTests(unittest.TestCase): +def last_cb(): + pass - def setUp(self): - self.loop = test_utils.TestLoop() - events.set_event_loop(None) - def tearDown(self): - self.loop.close() +class FutureTests(test_utils.TestCase): + + def setUp(self): + self.loop = self.new_test_loop() + self.addCleanup(self.loop.close) def test_initial_state(self): - f = futures.Future(loop=self.loop) + f = asyncio.Future(loop=self.loop) self.assertFalse(f.cancelled()) self.assertFalse(f.done()) f.cancel() self.assertTrue(f.cancelled()) def test_init_constructor_default_loop(self): - try: - events.set_event_loop(self.loop) - f = futures.Future() - self.assertIs(f._loop, self.loop) - finally: - events.set_event_loop(None) + asyncio.set_event_loop(self.loop) + f = asyncio.Future() + self.assertIs(f._loop, self.loop) def test_constructor_positional(self): - # Make sure Future does't accept a positional argument - self.assertRaises(TypeError, futures.Future, 42) + # Make sure Future doesn't accept a positional argument + self.assertRaises(TypeError, asyncio.Future, 42) def test_cancel(self): - f = futures.Future(loop=self.loop) + f = asyncio.Future(loop=self.loop) self.assertTrue(f.cancel()) self.assertTrue(f.cancelled()) self.assertTrue(f.done()) - self.assertRaises(futures.CancelledError, f.result) - self.assertRaises(futures.CancelledError, f.exception) - self.assertRaises(futures.InvalidStateError, f.set_result, None) - self.assertRaises(futures.InvalidStateError, f.set_exception, None) + self.assertRaises(asyncio.CancelledError, f.result) + self.assertRaises(asyncio.CancelledError, f.exception) + self.assertRaises(asyncio.InvalidStateError, f.set_result, None) + self.assertRaises(asyncio.InvalidStateError, f.set_exception, None) self.assertFalse(f.cancel()) def test_result(self): - f = futures.Future(loop=self.loop) - self.assertRaises(futures.InvalidStateError, f.result) + f = asyncio.Future(loop=self.loop) + self.assertRaises(asyncio.InvalidStateError, f.result) f.set_result(42) self.assertFalse(f.cancelled()) self.assertTrue(f.done()) self.assertEqual(f.result(), 42) self.assertEqual(f.exception(), None) - self.assertRaises(futures.InvalidStateError, f.set_result, None) - self.assertRaises(futures.InvalidStateError, f.set_exception, None) + self.assertRaises(asyncio.InvalidStateError, f.set_result, None) + self.assertRaises(asyncio.InvalidStateError, f.set_exception, None) self.assertFalse(f.cancel()) def test_exception(self): exc = RuntimeError() - f = futures.Future(loop=self.loop) - self.assertRaises(futures.InvalidStateError, f.exception) + f = asyncio.Future(loop=self.loop) + self.assertRaises(asyncio.InvalidStateError, f.exception) f.set_exception(exc) self.assertFalse(f.cancelled()) self.assertTrue(f.done()) self.assertRaises(RuntimeError, f.result) self.assertEqual(f.exception(), exc) - self.assertRaises(futures.InvalidStateError, f.set_result, None) - self.assertRaises(futures.InvalidStateError, f.set_exception, None) + self.assertRaises(asyncio.InvalidStateError, f.set_result, None) + self.assertRaises(asyncio.InvalidStateError, f.set_exception, None) self.assertFalse(f.cancel()) + def test_exception_class(self): + f = asyncio.Future(loop=self.loop) + f.set_exception(RuntimeError) + self.assertIsInstance(f.exception(), RuntimeError) + def test_yield_from_twice(self): - f = futures.Future(loop=self.loop) + f = asyncio.Future(loop=self.loop) def fixture(): yield 'A' @@ -98,68 +108,99 @@ def fixture(): # The second "yield from f" does not yield f. self.assertEqual(next(g), ('C', 42)) # yield 'C', y. - def test_repr(self): - f_pending = futures.Future(loop=self.loop) - self.assertEqual(repr(f_pending), 'Future<PENDING>') + def test_future_repr(self): + self.loop.set_debug(True) + f_pending_debug = asyncio.Future(loop=self.loop) + frame = f_pending_debug._source_traceback[-1] + self.assertEqual(repr(f_pending_debug), + '<Future pending created at %s:%s>' + % (frame[0], frame[1])) + f_pending_debug.cancel() + + self.loop.set_debug(False) + f_pending = asyncio.Future(loop=self.loop) + self.assertEqual(repr(f_pending), '<Future pending>') f_pending.cancel() - f_cancelled = futures.Future(loop=self.loop) + f_cancelled = asyncio.Future(loop=self.loop) f_cancelled.cancel() - self.assertEqual(repr(f_cancelled), 'Future<CANCELLED>') + self.assertEqual(repr(f_cancelled), '<Future cancelled>') - f_result = futures.Future(loop=self.loop) + f_result = asyncio.Future(loop=self.loop) f_result.set_result(4) - self.assertEqual(repr(f_result), 'Future<result=4>') + self.assertEqual(repr(f_result), '<Future finished result=4>') self.assertEqual(f_result.result(), 4) exc = RuntimeError() - f_exception = futures.Future(loop=self.loop) + f_exception = asyncio.Future(loop=self.loop) f_exception.set_exception(exc) - self.assertEqual(repr(f_exception), 'Future<exception=RuntimeError()>') + self.assertEqual(repr(f_exception), + '<Future finished exception=RuntimeError()>') self.assertIs(f_exception.exception(), exc) - f_few_callbacks = futures.Future(loop=self.loop) - f_few_callbacks.add_done_callback(_fakefunc) - self.assertIn('Future<PENDING, [<function _fakefunc', - repr(f_few_callbacks)) - f_few_callbacks.cancel() - - f_many_callbacks = futures.Future(loop=self.loop) - for i in range(20): + def func_repr(func): + filename, lineno = test_utils.get_function_source(func) + text = '%s() at %s:%s' % (func.__qualname__, filename, lineno) + return re.escape(text) + + f_one_callbacks = asyncio.Future(loop=self.loop) + f_one_callbacks.add_done_callback(_fakefunc) + fake_repr = func_repr(_fakefunc) + self.assertRegex(repr(f_one_callbacks), + r'<Future pending cb=\[%s\]>' % fake_repr) + f_one_callbacks.cancel() + self.assertEqual(repr(f_one_callbacks), + '<Future cancelled>') + + f_two_callbacks = asyncio.Future(loop=self.loop) + f_two_callbacks.add_done_callback(first_cb) + f_two_callbacks.add_done_callback(last_cb) + first_repr = func_repr(first_cb) + last_repr = func_repr(last_cb) + self.assertRegex(repr(f_two_callbacks), + r'<Future pending cb=\[%s, %s\]>' + % (first_repr, last_repr)) + + f_many_callbacks = asyncio.Future(loop=self.loop) + f_many_callbacks.add_done_callback(first_cb) + for i in range(8): f_many_callbacks.add_done_callback(_fakefunc) - r = repr(f_many_callbacks) - self.assertIn('Future<PENDING, [<function _fakefunc', r) - self.assertIn('<18 more>', r) + f_many_callbacks.add_done_callback(last_cb) + cb_regex = r'%s, <8 more>, %s' % (first_repr, last_repr) + self.assertRegex(repr(f_many_callbacks), + r'<Future pending cb=\[%s\]>' % cb_regex) f_many_callbacks.cancel() + self.assertEqual(repr(f_many_callbacks), + '<Future cancelled>') def test_copy_state(self): # Test the internal _copy_state method since it's being directly # invoked in other modules. - f = futures.Future(loop=self.loop) + f = asyncio.Future(loop=self.loop) f.set_result(10) - newf = futures.Future(loop=self.loop) + newf = asyncio.Future(loop=self.loop) newf._copy_state(f) self.assertTrue(newf.done()) self.assertEqual(newf.result(), 10) - f_exception = futures.Future(loop=self.loop) + f_exception = asyncio.Future(loop=self.loop) f_exception.set_exception(RuntimeError()) - newf_exception = futures.Future(loop=self.loop) + newf_exception = asyncio.Future(loop=self.loop) newf_exception._copy_state(f_exception) self.assertTrue(newf_exception.done()) self.assertRaises(RuntimeError, newf_exception.result) - f_cancelled = futures.Future(loop=self.loop) + f_cancelled = asyncio.Future(loop=self.loop) f_cancelled.cancel() - newf_cancelled = futures.Future(loop=self.loop) + newf_cancelled = asyncio.Future(loop=self.loop) newf_cancelled._copy_state(f_cancelled) self.assertTrue(newf_cancelled.cancelled()) def test_iter(self): - fut = futures.Future(loop=self.loop) + fut = asyncio.Future(loop=self.loop) def coro(): yield from fut @@ -170,46 +211,46 @@ def test(): self.assertRaises(AssertionError, test) fut.cancel() - @unittest.mock.patch('asyncio.futures.logger') + @mock.patch('asyncio.base_events.logger') def test_tb_logger_abandoned(self, m_log): - fut = futures.Future(loop=self.loop) + fut = asyncio.Future(loop=self.loop) del fut self.assertFalse(m_log.error.called) - @unittest.mock.patch('asyncio.futures.logger') + @mock.patch('asyncio.base_events.logger') def test_tb_logger_result_unretrieved(self, m_log): - fut = futures.Future(loop=self.loop) + fut = asyncio.Future(loop=self.loop) fut.set_result(42) del fut self.assertFalse(m_log.error.called) - @unittest.mock.patch('asyncio.futures.logger') + @mock.patch('asyncio.base_events.logger') def test_tb_logger_result_retrieved(self, m_log): - fut = futures.Future(loop=self.loop) + fut = asyncio.Future(loop=self.loop) fut.set_result(42) fut.result() del fut self.assertFalse(m_log.error.called) - @unittest.mock.patch('asyncio.futures.logger') + @mock.patch('asyncio.base_events.logger') def test_tb_logger_exception_unretrieved(self, m_log): - fut = futures.Future(loop=self.loop) + fut = asyncio.Future(loop=self.loop) fut.set_exception(RuntimeError('boom')) del fut test_utils.run_briefly(self.loop) self.assertTrue(m_log.error.called) - @unittest.mock.patch('asyncio.futures.logger') + @mock.patch('asyncio.base_events.logger') def test_tb_logger_exception_retrieved(self, m_log): - fut = futures.Future(loop=self.loop) + fut = asyncio.Future(loop=self.loop) fut.set_exception(RuntimeError('boom')) fut.exception() del fut self.assertFalse(m_log.error.called) - @unittest.mock.patch('asyncio.futures.logger') + @mock.patch('asyncio.base_events.logger') def test_tb_logger_exception_result_retrieved(self, m_log): - fut = futures.Future(loop=self.loop) + fut = asyncio.Future(loop=self.loop) fut.set_exception(RuntimeError('boom')) self.assertRaises(RuntimeError, fut.result) del fut @@ -221,29 +262,29 @@ def run(arg): return (arg, threading.get_ident()) ex = concurrent.futures.ThreadPoolExecutor(1) f1 = ex.submit(run, 'oi') - f2 = futures.wrap_future(f1, loop=self.loop) + f2 = asyncio.wrap_future(f1, loop=self.loop) res, ident = self.loop.run_until_complete(f2) - self.assertIsInstance(f2, futures.Future) + self.assertIsInstance(f2, asyncio.Future) self.assertEqual(res, 'oi') self.assertNotEqual(ident, threading.get_ident()) def test_wrap_future_future(self): - f1 = futures.Future(loop=self.loop) - f2 = futures.wrap_future(f1) + f1 = asyncio.Future(loop=self.loop) + f2 = asyncio.wrap_future(f1) self.assertIs(f1, f2) - @unittest.mock.patch('asyncio.futures.events') + @mock.patch('asyncio.futures.events') def test_wrap_future_use_global_loop(self, m_events): def run(arg): return (arg, threading.get_ident()) ex = concurrent.futures.ThreadPoolExecutor(1) f1 = ex.submit(run, 'oi') - f2 = futures.wrap_future(f1) + f2 = asyncio.wrap_future(f1) self.assertIs(m_events.get_event_loop.return_value, f2._loop) def test_wrap_future_cancel(self): f1 = concurrent.futures.Future() - f2 = futures.wrap_future(f1, loop=self.loop) + f2 = asyncio.wrap_future(f1, loop=self.loop) f2.cancel() test_utils.run_briefly(self.loop) self.assertTrue(f1.cancelled()) @@ -251,7 +292,7 @@ def test_wrap_future_cancel(self): def test_wrap_future_cancel2(self): f1 = concurrent.futures.Future() - f2 = futures.wrap_future(f1, loop=self.loop) + f2 = asyncio.wrap_future(f1, loop=self.loop) f1.set_result(42) f2.cancel() test_utils.run_briefly(self.loop) @@ -259,15 +300,100 @@ def test_wrap_future_cancel2(self): self.assertEqual(f1.result(), 42) self.assertTrue(f2.cancelled()) + def test_future_source_traceback(self): + self.loop.set_debug(True) + + future = asyncio.Future(loop=self.loop) + lineno = sys._getframe().f_lineno - 1 + self.assertIsInstance(future._source_traceback, list) + self.assertEqual(future._source_traceback[-1][:3], + (__file__, + lineno, + 'test_future_source_traceback')) + + @mock.patch('asyncio.base_events.logger') + def check_future_exception_never_retrieved(self, debug, m_log): + self.loop.set_debug(debug) + + def memory_error(): + try: + raise MemoryError() + except BaseException as exc: + return exc + exc = memory_error() + + future = asyncio.Future(loop=self.loop) + if debug: + source_traceback = future._source_traceback + future.set_exception(exc) + future = None + test_utils.run_briefly(self.loop) + support.gc_collect() + + if sys.version_info >= (3, 4): + if debug: + frame = source_traceback[-1] + regex = (r'^Future exception was never retrieved\n' + r'future: <Future finished exception=MemoryError\(\) ' + r'created at {filename}:{lineno}>\n' + r'source_traceback: Object ' + r'created at \(most recent call last\):\n' + r' File' + r'.*\n' + r' File "{filename}", line {lineno}, ' + r'in check_future_exception_never_retrieved\n' + r' future = asyncio\.Future\(loop=self\.loop\)$' + ).format(filename=re.escape(frame[0]), + lineno=frame[1]) + else: + regex = (r'^Future exception was never retrieved\n' + r'future: ' + r'<Future finished exception=MemoryError\(\)>$' + ) + exc_info = (type(exc), exc, exc.__traceback__) + m_log.error.assert_called_once_with(mock.ANY, exc_info=exc_info) + else: + if debug: + frame = source_traceback[-1] + regex = (r'^Future/Task exception was never retrieved\n' + r'Future/Task created at \(most recent call last\):\n' + r' File' + r'.*\n' + r' File "{filename}", line {lineno}, ' + r'in check_future_exception_never_retrieved\n' + r' future = asyncio\.Future\(loop=self\.loop\)\n' + r'Traceback \(most recent call last\):\n' + r'.*\n' + r'MemoryError$' + ).format(filename=re.escape(frame[0]), + lineno=frame[1]) + else: + regex = (r'^Future/Task exception was never retrieved\n' + r'Traceback \(most recent call last\):\n' + r'.*\n' + r'MemoryError$' + ) + m_log.error.assert_called_once_with(mock.ANY, exc_info=False) + message = m_log.error.call_args[0][0] + self.assertRegex(message, re.compile(regex, re.DOTALL)) + + def test_future_exception_never_retrieved(self): + self.check_future_exception_never_retrieved(False) + + def test_future_exception_never_retrieved_debug(self): + self.check_future_exception_never_retrieved(True) + + def test_set_result_unless_cancelled(self): + fut = asyncio.Future(loop=self.loop) + fut.cancel() + fut._set_result_unless_cancelled(2) + self.assertTrue(fut.cancelled()) -class FutureDoneCallbackTests(unittest.TestCase): - def setUp(self): - self.loop = test_utils.TestLoop() - events.set_event_loop(None) +class FutureDoneCallbackTests(test_utils.TestCase): - def tearDown(self): - self.loop.close() + def setUp(self): + self.loop = self.new_test_loop() def run_briefly(self): test_utils.run_briefly(self.loop) @@ -279,7 +405,7 @@ def bag_appender(future): return bag_appender def _new_future(self): - return futures.Future(loop=self.loop) + return asyncio.Future(loop=self.loop) def test_callbacks_invoked_on_set_result(self): bag = [] diff --git a/Lib/test/test_asyncio/test_locks.py b/Lib/test/test_asyncio/test_locks.py index df106e0d151d..dda4577aeddd 100644 --- a/Lib/test/test_asyncio/test_locks.py +++ b/Lib/test/test_asyncio/test_locks.py @@ -1,13 +1,10 @@ """Tests for lock.py""" import unittest -import unittest.mock +from unittest import mock import re -from asyncio import events -from asyncio import futures -from asyncio import locks -from asyncio import tasks +import asyncio from asyncio import test_utils @@ -20,37 +17,30 @@ RGX_REPR = re.compile(STR_RGX_REPR) -class LockTests(unittest.TestCase): +class LockTests(test_utils.TestCase): def setUp(self): - self.loop = test_utils.TestLoop() - events.set_event_loop(None) - - def tearDown(self): - self.loop.close() + self.loop = self.new_test_loop() def test_ctor_loop(self): - loop = unittest.mock.Mock() - lock = locks.Lock(loop=loop) + loop = mock.Mock() + lock = asyncio.Lock(loop=loop) self.assertIs(lock._loop, loop) - lock = locks.Lock(loop=self.loop) + lock = asyncio.Lock(loop=self.loop) self.assertIs(lock._loop, self.loop) def test_ctor_noloop(self): - try: - events.set_event_loop(self.loop) - lock = locks.Lock() - self.assertIs(lock._loop, self.loop) - finally: - events.set_event_loop(None) + asyncio.set_event_loop(self.loop) + lock = asyncio.Lock() + self.assertIs(lock._loop, self.loop) def test_repr(self): - lock = locks.Lock(loop=self.loop) + lock = asyncio.Lock(loop=self.loop) self.assertTrue(repr(lock).endswith('[unlocked]>')) self.assertTrue(RGX_REPR.match(repr(lock))) - @tasks.coroutine + @asyncio.coroutine def acquire_lock(): yield from lock @@ -59,9 +49,9 @@ def acquire_lock(): self.assertTrue(RGX_REPR.match(repr(lock))) def test_lock(self): - lock = locks.Lock(loop=self.loop) + lock = asyncio.Lock(loop=self.loop) - @tasks.coroutine + @asyncio.coroutine def acquire_lock(): return (yield from lock) @@ -74,31 +64,31 @@ def acquire_lock(): self.assertFalse(lock.locked()) def test_acquire(self): - lock = locks.Lock(loop=self.loop) + lock = asyncio.Lock(loop=self.loop) result = [] self.assertTrue(self.loop.run_until_complete(lock.acquire())) - @tasks.coroutine + @asyncio.coroutine def c1(result): if (yield from lock.acquire()): result.append(1) return True - @tasks.coroutine + @asyncio.coroutine def c2(result): if (yield from lock.acquire()): result.append(2) return True - @tasks.coroutine + @asyncio.coroutine def c3(result): if (yield from lock.acquire()): result.append(3) return True - t1 = tasks.Task(c1(result), loop=self.loop) - t2 = tasks.Task(c2(result), loop=self.loop) + t1 = asyncio.Task(c1(result), loop=self.loop) + t2 = asyncio.Task(c2(result), loop=self.loop) test_utils.run_briefly(self.loop) self.assertEqual([], result) @@ -110,7 +100,7 @@ def c3(result): test_utils.run_briefly(self.loop) self.assertEqual([1], result) - t3 = tasks.Task(c3(result), loop=self.loop) + t3 = asyncio.Task(c3(result), loop=self.loop) lock.release() test_utils.run_briefly(self.loop) @@ -128,13 +118,13 @@ def c3(result): self.assertTrue(t3.result()) def test_acquire_cancel(self): - lock = locks.Lock(loop=self.loop) + lock = asyncio.Lock(loop=self.loop) self.assertTrue(self.loop.run_until_complete(lock.acquire())) - task = tasks.Task(lock.acquire(), loop=self.loop) + task = asyncio.Task(lock.acquire(), loop=self.loop) self.loop.call_soon(task.cancel) self.assertRaises( - futures.CancelledError, + asyncio.CancelledError, self.loop.run_until_complete, task) self.assertFalse(lock._waiters) @@ -153,9 +143,9 @@ def test_cancel_race(self): # B's waiter; instead, it should move on to C's waiter. # Setup: A has the lock, b and c are waiting. - lock = locks.Lock(loop=self.loop) + lock = asyncio.Lock(loop=self.loop) - @tasks.coroutine + @asyncio.coroutine def lockit(name, blocker): yield from lock.acquire() try: @@ -164,14 +154,14 @@ def lockit(name, blocker): finally: lock.release() - fa = futures.Future(loop=self.loop) - ta = tasks.Task(lockit('A', fa), loop=self.loop) + fa = asyncio.Future(loop=self.loop) + ta = asyncio.Task(lockit('A', fa), loop=self.loop) test_utils.run_briefly(self.loop) self.assertTrue(lock.locked()) - tb = tasks.Task(lockit('B', None), loop=self.loop) + tb = asyncio.Task(lockit('B', None), loop=self.loop) test_utils.run_briefly(self.loop) self.assertEqual(len(lock._waiters), 1) - tc = tasks.Task(lockit('C', None), loop=self.loop) + tc = asyncio.Task(lockit('C', None), loop=self.loop) test_utils.run_briefly(self.loop) self.assertEqual(len(lock._waiters), 2) @@ -187,12 +177,12 @@ def lockit(name, blocker): self.assertTrue(tc.done()) def test_release_not_acquired(self): - lock = locks.Lock(loop=self.loop) + lock = asyncio.Lock(loop=self.loop) self.assertRaises(RuntimeError, lock.release) def test_release_no_waiters(self): - lock = locks.Lock(loop=self.loop) + lock = asyncio.Lock(loop=self.loop) self.loop.run_until_complete(lock.acquire()) self.assertTrue(lock.locked()) @@ -200,9 +190,9 @@ def test_release_no_waiters(self): self.assertFalse(lock.locked()) def test_context_manager(self): - lock = locks.Lock(loop=self.loop) + lock = asyncio.Lock(loop=self.loop) - @tasks.coroutine + @asyncio.coroutine def acquire_lock(): return (yield from lock) @@ -211,8 +201,26 @@ def acquire_lock(): self.assertFalse(lock.locked()) + def test_context_manager_cant_reuse(self): + lock = asyncio.Lock(loop=self.loop) + + @asyncio.coroutine + def acquire_lock(): + return (yield from lock) + + # This spells "yield from lock" outside a generator. + cm = self.loop.run_until_complete(acquire_lock()) + with cm: + self.assertTrue(lock.locked()) + + self.assertFalse(lock.locked()) + + with self.assertRaises(AttributeError): + with cm: + pass + def test_context_manager_no_yield(self): - lock = locks.Lock(loop=self.loop) + lock = asyncio.Lock(loop=self.loop) try: with lock: @@ -222,34 +230,29 @@ def test_context_manager_no_yield(self): str(err), '"yield from" should be used as context manager expression') + self.assertFalse(lock.locked()) -class EventTests(unittest.TestCase): - def setUp(self): - self.loop = test_utils.TestLoop() - events.set_event_loop(None) +class EventTests(test_utils.TestCase): - def tearDown(self): - self.loop.close() + def setUp(self): + self.loop = self.new_test_loop() def test_ctor_loop(self): - loop = unittest.mock.Mock() - ev = locks.Event(loop=loop) + loop = mock.Mock() + ev = asyncio.Event(loop=loop) self.assertIs(ev._loop, loop) - ev = locks.Event(loop=self.loop) + ev = asyncio.Event(loop=self.loop) self.assertIs(ev._loop, self.loop) def test_ctor_noloop(self): - try: - events.set_event_loop(self.loop) - ev = locks.Event() - self.assertIs(ev._loop, self.loop) - finally: - events.set_event_loop(None) + asyncio.set_event_loop(self.loop) + ev = asyncio.Event() + self.assertIs(ev._loop, self.loop) def test_repr(self): - ev = locks.Event(loop=self.loop) + ev = asyncio.Event(loop=self.loop) self.assertTrue(repr(ev).endswith('[unset]>')) match = RGX_REPR.match(repr(ev)) self.assertEqual(match.group('extras'), 'unset') @@ -258,38 +261,38 @@ def test_repr(self): self.assertTrue(repr(ev).endswith('[set]>')) self.assertTrue(RGX_REPR.match(repr(ev))) - ev._waiters.append(unittest.mock.Mock()) + ev._waiters.append(mock.Mock()) self.assertTrue('waiters:1' in repr(ev)) self.assertTrue(RGX_REPR.match(repr(ev))) def test_wait(self): - ev = locks.Event(loop=self.loop) + ev = asyncio.Event(loop=self.loop) self.assertFalse(ev.is_set()) result = [] - @tasks.coroutine + @asyncio.coroutine def c1(result): if (yield from ev.wait()): result.append(1) - @tasks.coroutine + @asyncio.coroutine def c2(result): if (yield from ev.wait()): result.append(2) - @tasks.coroutine + @asyncio.coroutine def c3(result): if (yield from ev.wait()): result.append(3) - t1 = tasks.Task(c1(result), loop=self.loop) - t2 = tasks.Task(c2(result), loop=self.loop) + t1 = asyncio.Task(c1(result), loop=self.loop) + t2 = asyncio.Task(c2(result), loop=self.loop) test_utils.run_briefly(self.loop) self.assertEqual([], result) - t3 = tasks.Task(c3(result), loop=self.loop) + t3 = asyncio.Task(c3(result), loop=self.loop) ev.set() test_utils.run_briefly(self.loop) @@ -303,24 +306,24 @@ def c3(result): self.assertIsNone(t3.result()) def test_wait_on_set(self): - ev = locks.Event(loop=self.loop) + ev = asyncio.Event(loop=self.loop) ev.set() res = self.loop.run_until_complete(ev.wait()) self.assertTrue(res) def test_wait_cancel(self): - ev = locks.Event(loop=self.loop) + ev = asyncio.Event(loop=self.loop) - wait = tasks.Task(ev.wait(), loop=self.loop) + wait = asyncio.Task(ev.wait(), loop=self.loop) self.loop.call_soon(wait.cancel) self.assertRaises( - futures.CancelledError, + asyncio.CancelledError, self.loop.run_until_complete, wait) self.assertFalse(ev._waiters) def test_clear(self): - ev = locks.Event(loop=self.loop) + ev = asyncio.Event(loop=self.loop) self.assertFalse(ev.is_set()) ev.set() @@ -330,16 +333,16 @@ def test_clear(self): self.assertFalse(ev.is_set()) def test_clear_with_waiters(self): - ev = locks.Event(loop=self.loop) + ev = asyncio.Event(loop=self.loop) result = [] - @tasks.coroutine + @asyncio.coroutine def c1(result): if (yield from ev.wait()): result.append(1) return True - t = tasks.Task(c1(result), loop=self.loop) + t = asyncio.Task(c1(result), loop=self.loop) test_utils.run_briefly(self.loop) self.assertEqual([], result) @@ -359,59 +362,52 @@ def c1(result): self.assertTrue(t.result()) -class ConditionTests(unittest.TestCase): +class ConditionTests(test_utils.TestCase): def setUp(self): - self.loop = test_utils.TestLoop() - events.set_event_loop(None) - - def tearDown(self): - self.loop.close() + self.loop = self.new_test_loop() def test_ctor_loop(self): - loop = unittest.mock.Mock() - cond = locks.Condition(loop=loop) + loop = mock.Mock() + cond = asyncio.Condition(loop=loop) self.assertIs(cond._loop, loop) - cond = locks.Condition(loop=self.loop) + cond = asyncio.Condition(loop=self.loop) self.assertIs(cond._loop, self.loop) def test_ctor_noloop(self): - try: - events.set_event_loop(self.loop) - cond = locks.Condition() - self.assertIs(cond._loop, self.loop) - finally: - events.set_event_loop(None) + asyncio.set_event_loop(self.loop) + cond = asyncio.Condition() + self.assertIs(cond._loop, self.loop) def test_wait(self): - cond = locks.Condition(loop=self.loop) + cond = asyncio.Condition(loop=self.loop) result = [] - @tasks.coroutine + @asyncio.coroutine def c1(result): yield from cond.acquire() if (yield from cond.wait()): result.append(1) return True - @tasks.coroutine + @asyncio.coroutine def c2(result): yield from cond.acquire() if (yield from cond.wait()): result.append(2) return True - @tasks.coroutine + @asyncio.coroutine def c3(result): yield from cond.acquire() if (yield from cond.wait()): result.append(3) return True - t1 = tasks.Task(c1(result), loop=self.loop) - t2 = tasks.Task(c2(result), loop=self.loop) - t3 = tasks.Task(c3(result), loop=self.loop) + t1 = asyncio.Task(c1(result), loop=self.loop) + t2 = asyncio.Task(c2(result), loop=self.loop) + t3 = asyncio.Task(c3(result), loop=self.loop) test_utils.run_briefly(self.loop) self.assertEqual([], result) @@ -451,25 +447,25 @@ def c3(result): self.assertTrue(t3.result()) def test_wait_cancel(self): - cond = locks.Condition(loop=self.loop) + cond = asyncio.Condition(loop=self.loop) self.loop.run_until_complete(cond.acquire()) - wait = tasks.Task(cond.wait(), loop=self.loop) + wait = asyncio.Task(cond.wait(), loop=self.loop) self.loop.call_soon(wait.cancel) self.assertRaises( - futures.CancelledError, + asyncio.CancelledError, self.loop.run_until_complete, wait) self.assertFalse(cond._waiters) self.assertTrue(cond.locked()) def test_wait_unacquired(self): - cond = locks.Condition(loop=self.loop) + cond = asyncio.Condition(loop=self.loop) self.assertRaises( RuntimeError, self.loop.run_until_complete, cond.wait()) def test_wait_for(self): - cond = locks.Condition(loop=self.loop) + cond = asyncio.Condition(loop=self.loop) presult = False def predicate(): @@ -477,7 +473,7 @@ def predicate(): result = [] - @tasks.coroutine + @asyncio.coroutine def c1(result): yield from cond.acquire() if (yield from cond.wait_for(predicate)): @@ -485,7 +481,7 @@ def c1(result): cond.release() return True - t = tasks.Task(c1(result), loop=self.loop) + t = asyncio.Task(c1(result), loop=self.loop) test_utils.run_briefly(self.loop) self.assertEqual([], result) @@ -507,7 +503,7 @@ def c1(result): self.assertTrue(t.result()) def test_wait_for_unacquired(self): - cond = locks.Condition(loop=self.loop) + cond = asyncio.Condition(loop=self.loop) # predicate can return true immediately res = self.loop.run_until_complete(cond.wait_for(lambda: [1, 2, 3])) @@ -519,10 +515,10 @@ def test_wait_for_unacquired(self): cond.wait_for(lambda: False)) def test_notify(self): - cond = locks.Condition(loop=self.loop) + cond = asyncio.Condition(loop=self.loop) result = [] - @tasks.coroutine + @asyncio.coroutine def c1(result): yield from cond.acquire() if (yield from cond.wait()): @@ -530,7 +526,7 @@ def c1(result): cond.release() return True - @tasks.coroutine + @asyncio.coroutine def c2(result): yield from cond.acquire() if (yield from cond.wait()): @@ -538,7 +534,7 @@ def c2(result): cond.release() return True - @tasks.coroutine + @asyncio.coroutine def c3(result): yield from cond.acquire() if (yield from cond.wait()): @@ -546,9 +542,9 @@ def c3(result): cond.release() return True - t1 = tasks.Task(c1(result), loop=self.loop) - t2 = tasks.Task(c2(result), loop=self.loop) - t3 = tasks.Task(c3(result), loop=self.loop) + t1 = asyncio.Task(c1(result), loop=self.loop) + t2 = asyncio.Task(c2(result), loop=self.loop) + t3 = asyncio.Task(c3(result), loop=self.loop) test_utils.run_briefly(self.loop) self.assertEqual([], result) @@ -574,11 +570,11 @@ def c3(result): self.assertTrue(t3.result()) def test_notify_all(self): - cond = locks.Condition(loop=self.loop) + cond = asyncio.Condition(loop=self.loop) result = [] - @tasks.coroutine + @asyncio.coroutine def c1(result): yield from cond.acquire() if (yield from cond.wait()): @@ -586,7 +582,7 @@ def c1(result): cond.release() return True - @tasks.coroutine + @asyncio.coroutine def c2(result): yield from cond.acquire() if (yield from cond.wait()): @@ -594,8 +590,8 @@ def c2(result): cond.release() return True - t1 = tasks.Task(c1(result), loop=self.loop) - t2 = tasks.Task(c2(result), loop=self.loop) + t1 = asyncio.Task(c1(result), loop=self.loop) + t2 = asyncio.Task(c2(result), loop=self.loop) test_utils.run_briefly(self.loop) self.assertEqual([], result) @@ -612,33 +608,33 @@ def c2(result): self.assertTrue(t2.result()) def test_notify_unacquired(self): - cond = locks.Condition(loop=self.loop) + cond = asyncio.Condition(loop=self.loop) self.assertRaises(RuntimeError, cond.notify) def test_notify_all_unacquired(self): - cond = locks.Condition(loop=self.loop) + cond = asyncio.Condition(loop=self.loop) self.assertRaises(RuntimeError, cond.notify_all) def test_repr(self): - cond = locks.Condition(loop=self.loop) + cond = asyncio.Condition(loop=self.loop) self.assertTrue('unlocked' in repr(cond)) self.assertTrue(RGX_REPR.match(repr(cond))) self.loop.run_until_complete(cond.acquire()) self.assertTrue('locked' in repr(cond)) - cond._waiters.append(unittest.mock.Mock()) + cond._waiters.append(mock.Mock()) self.assertTrue('waiters:1' in repr(cond)) self.assertTrue(RGX_REPR.match(repr(cond))) - cond._waiters.append(unittest.mock.Mock()) + cond._waiters.append(mock.Mock()) self.assertTrue('waiters:2' in repr(cond)) self.assertTrue(RGX_REPR.match(repr(cond))) def test_context_manager(self): - cond = locks.Condition(loop=self.loop) + cond = asyncio.Condition(loop=self.loop) - @tasks.coroutine + @asyncio.coroutine def acquire_cond(): return (yield from cond) @@ -648,7 +644,7 @@ def acquire_cond(): self.assertFalse(cond.locked()) def test_context_manager_no_yield(self): - cond = locks.Condition(loop=self.loop) + cond = asyncio.Condition(loop=self.loop) try: with cond: @@ -658,38 +654,48 @@ def test_context_manager_no_yield(self): str(err), '"yield from" should be used as context manager expression') + self.assertFalse(cond.locked()) -class SemaphoreTests(unittest.TestCase): + def test_explicit_lock(self): + lock = asyncio.Lock(loop=self.loop) + cond = asyncio.Condition(lock, loop=self.loop) + + self.assertIs(cond._lock, lock) + self.assertIs(cond._loop, lock._loop) + + def test_ambiguous_loops(self): + loop = self.new_test_loop() + self.addCleanup(loop.close) + + lock = asyncio.Lock(loop=self.loop) + with self.assertRaises(ValueError): + asyncio.Condition(lock, loop=loop) - def setUp(self): - self.loop = test_utils.TestLoop() - events.set_event_loop(None) - def tearDown(self): - self.loop.close() +class SemaphoreTests(test_utils.TestCase): + + def setUp(self): + self.loop = self.new_test_loop() def test_ctor_loop(self): - loop = unittest.mock.Mock() - sem = locks.Semaphore(loop=loop) + loop = mock.Mock() + sem = asyncio.Semaphore(loop=loop) self.assertIs(sem._loop, loop) - sem = locks.Semaphore(loop=self.loop) + sem = asyncio.Semaphore(loop=self.loop) self.assertIs(sem._loop, self.loop) def test_ctor_noloop(self): - try: - events.set_event_loop(self.loop) - sem = locks.Semaphore() - self.assertIs(sem._loop, self.loop) - finally: - events.set_event_loop(None) + asyncio.set_event_loop(self.loop) + sem = asyncio.Semaphore() + self.assertIs(sem._loop, self.loop) def test_initial_value_zero(self): - sem = locks.Semaphore(0, loop=self.loop) + sem = asyncio.Semaphore(0, loop=self.loop) self.assertTrue(sem.locked()) def test_repr(self): - sem = locks.Semaphore(loop=self.loop) + sem = asyncio.Semaphore(loop=self.loop) self.assertTrue(repr(sem).endswith('[unlocked,value:1]>')) self.assertTrue(RGX_REPR.match(repr(sem))) @@ -698,19 +704,19 @@ def test_repr(self): self.assertTrue('waiters' not in repr(sem)) self.assertTrue(RGX_REPR.match(repr(sem))) - sem._waiters.append(unittest.mock.Mock()) + sem._waiters.append(mock.Mock()) self.assertTrue('waiters:1' in repr(sem)) self.assertTrue(RGX_REPR.match(repr(sem))) - sem._waiters.append(unittest.mock.Mock()) + sem._waiters.append(mock.Mock()) self.assertTrue('waiters:2' in repr(sem)) self.assertTrue(RGX_REPR.match(repr(sem))) def test_semaphore(self): - sem = locks.Semaphore(loop=self.loop) + sem = asyncio.Semaphore(loop=self.loop) self.assertEqual(1, sem._value) - @tasks.coroutine + @asyncio.coroutine def acquire_lock(): return (yield from sem) @@ -725,43 +731,43 @@ def acquire_lock(): self.assertEqual(1, sem._value) def test_semaphore_value(self): - self.assertRaises(ValueError, locks.Semaphore, -1) + self.assertRaises(ValueError, asyncio.Semaphore, -1) def test_acquire(self): - sem = locks.Semaphore(3, loop=self.loop) + sem = asyncio.Semaphore(3, loop=self.loop) result = [] self.assertTrue(self.loop.run_until_complete(sem.acquire())) self.assertTrue(self.loop.run_until_complete(sem.acquire())) self.assertFalse(sem.locked()) - @tasks.coroutine + @asyncio.coroutine def c1(result): yield from sem.acquire() result.append(1) return True - @tasks.coroutine + @asyncio.coroutine def c2(result): yield from sem.acquire() result.append(2) return True - @tasks.coroutine + @asyncio.coroutine def c3(result): yield from sem.acquire() result.append(3) return True - @tasks.coroutine + @asyncio.coroutine def c4(result): yield from sem.acquire() result.append(4) return True - t1 = tasks.Task(c1(result), loop=self.loop) - t2 = tasks.Task(c2(result), loop=self.loop) - t3 = tasks.Task(c3(result), loop=self.loop) + t1 = asyncio.Task(c1(result), loop=self.loop) + t2 = asyncio.Task(c2(result), loop=self.loop) + t3 = asyncio.Task(c3(result), loop=self.loop) test_utils.run_briefly(self.loop) self.assertEqual([1], result) @@ -769,7 +775,7 @@ def c4(result): self.assertEqual(2, len(sem._waiters)) self.assertEqual(0, sem._value) - t4 = tasks.Task(c4(result), loop=self.loop) + t4 = asyncio.Task(c4(result), loop=self.loop) sem.release() sem.release() @@ -792,25 +798,26 @@ def c4(result): # cleanup locked semaphore sem.release() + self.loop.run_until_complete(t4) def test_acquire_cancel(self): - sem = locks.Semaphore(loop=self.loop) + sem = asyncio.Semaphore(loop=self.loop) self.loop.run_until_complete(sem.acquire()) - acquire = tasks.Task(sem.acquire(), loop=self.loop) + acquire = asyncio.Task(sem.acquire(), loop=self.loop) self.loop.call_soon(acquire.cancel) self.assertRaises( - futures.CancelledError, + asyncio.CancelledError, self.loop.run_until_complete, acquire) self.assertFalse(sem._waiters) def test_release_not_acquired(self): - sem = locks.BoundedSemaphore(loop=self.loop) + sem = asyncio.BoundedSemaphore(loop=self.loop) self.assertRaises(ValueError, sem.release) def test_release_no_waiters(self): - sem = locks.Semaphore(loop=self.loop) + sem = asyncio.Semaphore(loop=self.loop) self.loop.run_until_complete(sem.acquire()) self.assertTrue(sem.locked()) @@ -818,9 +825,9 @@ def test_release_no_waiters(self): self.assertFalse(sem.locked()) def test_context_manager(self): - sem = locks.Semaphore(2, loop=self.loop) + sem = asyncio.Semaphore(2, loop=self.loop) - @tasks.coroutine + @asyncio.coroutine def acquire_lock(): return (yield from sem) @@ -833,6 +840,19 @@ def acquire_lock(): self.assertEqual(2, sem._value) + def test_context_manager_no_yield(self): + sem = asyncio.Semaphore(2, loop=self.loop) + + try: + with sem: + self.fail('RuntimeError is not raised in with expression') + except RuntimeError as err: + self.assertEqual( + str(err), + '"yield from" should be used as context manager expression') + + self.assertEqual(2, sem._value) + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_asyncio/test_proactor_events.py b/Lib/test/test_asyncio/test_proactor_events.py index 5a2a51c42e6e..fcd9ab1e18f6 100644 --- a/Lib/test/test_asyncio/test_proactor_events.py +++ b/Lib/test/test_asyncio/test_proactor_events.py @@ -2,7 +2,7 @@ import socket import unittest -import unittest.mock +from unittest import mock import asyncio from asyncio.proactor_events import BaseProactorEventLoop @@ -12,26 +12,41 @@ from asyncio import test_utils -class ProactorSocketTransportTests(unittest.TestCase): +def close_transport(transport): + # Don't call transport.close() because the event loop and the IOCP proactor + # are mocked + if transport._sock is None: + return + transport._sock.close() + transport._sock = None + + +class ProactorSocketTransportTests(test_utils.TestCase): def setUp(self): - self.loop = test_utils.TestLoop() - self.proactor = unittest.mock.Mock() + self.loop = self.new_test_loop() + self.addCleanup(self.loop.close) + self.proactor = mock.Mock() self.loop._proactor = self.proactor self.protocol = test_utils.make_test_protocol(asyncio.Protocol) - self.sock = unittest.mock.Mock(socket.socket) + self.sock = mock.Mock(socket.socket) + + def socket_transport(self, waiter=None): + transport = _ProactorSocketTransport(self.loop, self.sock, + self.protocol, waiter=waiter) + self.addCleanup(close_transport, transport) + return transport def test_ctor(self): fut = asyncio.Future(loop=self.loop) - tr = _ProactorSocketTransport( - self.loop, self.sock, self.protocol, fut) + tr = self.socket_transport(waiter=fut) test_utils.run_briefly(self.loop) self.assertIsNone(fut.result()) self.protocol.connection_made(tr) self.proactor.recv.assert_called_with(self.sock, 4096) def test_loop_reading(self): - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) + tr = self.socket_transport() tr._loop_reading() self.loop._proactor.recv.assert_called_with(self.sock, 4096) self.assertFalse(self.protocol.data_received.called) @@ -41,8 +56,7 @@ def test_loop_reading_data(self): res = asyncio.Future(loop=self.loop) res.set_result(b'data') - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) - + tr = self.socket_transport() tr._read_fut = res tr._loop_reading(res) self.loop._proactor.recv.assert_called_with(self.sock, 4096) @@ -52,11 +66,10 @@ def test_loop_reading_no_data(self): res = asyncio.Future(loop=self.loop) res.set_result(b'') - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) - + tr = self.socket_transport() self.assertRaises(AssertionError, tr._loop_reading, res) - tr.close = unittest.mock.Mock() + tr.close = mock.Mock() tr._read_fut = res tr._loop_reading(res) self.assertFalse(self.loop._proactor.recv.called) @@ -66,35 +79,37 @@ def test_loop_reading_no_data(self): def test_loop_reading_aborted(self): err = self.loop._proactor.recv.side_effect = ConnectionAbortedError() - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) - tr._fatal_error = unittest.mock.Mock() + tr = self.socket_transport() + tr._fatal_error = mock.Mock() tr._loop_reading() - tr._fatal_error.assert_called_with(err) + tr._fatal_error.assert_called_with( + err, + 'Fatal read error on pipe transport') def test_loop_reading_aborted_closing(self): self.loop._proactor.recv.side_effect = ConnectionAbortedError() - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) + tr = self.socket_transport() tr._closing = True - tr._fatal_error = unittest.mock.Mock() + tr._fatal_error = mock.Mock() tr._loop_reading() self.assertFalse(tr._fatal_error.called) def test_loop_reading_aborted_is_fatal(self): self.loop._proactor.recv.side_effect = ConnectionAbortedError() - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) + tr = self.socket_transport() tr._closing = False - tr._fatal_error = unittest.mock.Mock() + tr._fatal_error = mock.Mock() tr._loop_reading() self.assertTrue(tr._fatal_error.called) def test_loop_reading_conn_reset_lost(self): err = self.loop._proactor.recv.side_effect = ConnectionResetError() - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) + tr = self.socket_transport() tr._closing = False - tr._fatal_error = unittest.mock.Mock() - tr._force_close = unittest.mock.Mock() + tr._fatal_error = mock.Mock() + tr._force_close = mock.Mock() tr._loop_reading() self.assertFalse(tr._fatal_error.called) tr._force_close.assert_called_with(err) @@ -102,47 +117,51 @@ def test_loop_reading_conn_reset_lost(self): def test_loop_reading_exception(self): err = self.loop._proactor.recv.side_effect = (OSError()) - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) - tr._fatal_error = unittest.mock.Mock() + tr = self.socket_transport() + tr._fatal_error = mock.Mock() tr._loop_reading() - tr._fatal_error.assert_called_with(err) + tr._fatal_error.assert_called_with( + err, + 'Fatal read error on pipe transport') def test_write(self): - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) - tr._loop_writing = unittest.mock.Mock() + tr = self.socket_transport() + tr._loop_writing = mock.Mock() tr.write(b'data') - self.assertEqual(tr._buffer, [b'data']) - self.assertTrue(tr._loop_writing.called) + self.assertEqual(tr._buffer, None) + tr._loop_writing.assert_called_with(data=b'data') def test_write_no_data(self): - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) + tr = self.socket_transport() tr.write(b'') self.assertFalse(tr._buffer) def test_write_more(self): - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) - tr._write_fut = unittest.mock.Mock() - tr._loop_writing = unittest.mock.Mock() + tr = self.socket_transport() + tr._write_fut = mock.Mock() + tr._loop_writing = mock.Mock() tr.write(b'data') - self.assertEqual(tr._buffer, [b'data']) + self.assertEqual(tr._buffer, b'data') self.assertFalse(tr._loop_writing.called) def test_loop_writing(self): - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) - tr._buffer = [b'da', b'ta'] + tr = self.socket_transport() + tr._buffer = bytearray(b'data') tr._loop_writing() self.loop._proactor.send.assert_called_with(self.sock, b'data') self.loop._proactor.send.return_value.add_done_callback.\ assert_called_with(tr._loop_writing) - @unittest.mock.patch('asyncio.proactor_events.logger') + @mock.patch('asyncio.proactor_events.logger') def test_loop_writing_err(self, m_log): err = self.loop._proactor.send.side_effect = OSError() - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) - tr._fatal_error = unittest.mock.Mock() + tr = self.socket_transport() + tr._fatal_error = mock.Mock() tr._buffer = [b'da', b'ta'] tr._loop_writing() - tr._fatal_error.assert_called_with(err) + tr._fatal_error.assert_called_with( + err, + 'Fatal write error on pipe transport') tr._conn_lost = 1 tr.write(b'data') @@ -150,14 +169,14 @@ def test_loop_writing_err(self, m_log): tr.write(b'data') tr.write(b'data') tr.write(b'data') - self.assertEqual(tr._buffer, []) + self.assertEqual(tr._buffer, None) m_log.warning.assert_called_with('socket.send() raised exception.') def test_loop_writing_stop(self): fut = asyncio.Future(loop=self.loop) fut.set_result(b'data') - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) + tr = self.socket_transport() tr._write_fut = fut tr._loop_writing(fut) self.assertIsNone(tr._write_fut) @@ -166,7 +185,7 @@ def test_loop_writing_closing(self): fut = asyncio.Future(loop=self.loop) fut.set_result(1) - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) + tr = self.socket_transport() tr._write_fut = fut tr.close() tr._loop_writing(fut) @@ -175,13 +194,13 @@ def test_loop_writing_closing(self): self.protocol.connection_lost.assert_called_with(None) def test_abort(self): - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) - tr._force_close = unittest.mock.Mock() + tr = self.socket_transport() + tr._force_close = mock.Mock() tr.abort() tr._force_close.assert_called_with(None) def test_close(self): - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) + tr = self.socket_transport() tr.close() test_utils.run_briefly(self.loop) self.protocol.connection_lost.assert_called_with(None) @@ -194,66 +213,65 @@ def test_close(self): self.assertFalse(self.protocol.connection_lost.called) def test_close_write_fut(self): - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) - tr._write_fut = unittest.mock.Mock() + tr = self.socket_transport() + tr._write_fut = mock.Mock() tr.close() test_utils.run_briefly(self.loop) self.assertFalse(self.protocol.connection_lost.called) def test_close_buffer(self): - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) + tr = self.socket_transport() tr._buffer = [b'data'] tr.close() test_utils.run_briefly(self.loop) self.assertFalse(self.protocol.connection_lost.called) - @unittest.mock.patch('asyncio.proactor_events.logger') + @mock.patch('asyncio.base_events.logger') def test_fatal_error(self, m_logging): - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) - tr._force_close = unittest.mock.Mock() + tr = self.socket_transport() + tr._force_close = mock.Mock() tr._fatal_error(None) self.assertTrue(tr._force_close.called) - self.assertTrue(m_logging.exception.called) + self.assertTrue(m_logging.error.called) def test_force_close(self): - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) + tr = self.socket_transport() tr._buffer = [b'data'] - read_fut = tr._read_fut = unittest.mock.Mock() - write_fut = tr._write_fut = unittest.mock.Mock() + read_fut = tr._read_fut = mock.Mock() + write_fut = tr._write_fut = mock.Mock() tr._force_close(None) read_fut.cancel.assert_called_with() write_fut.cancel.assert_called_with() test_utils.run_briefly(self.loop) self.protocol.connection_lost.assert_called_with(None) - self.assertEqual([], tr._buffer) + self.assertEqual(None, tr._buffer) self.assertEqual(tr._conn_lost, 1) def test_force_close_idempotent(self): - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) + tr = self.socket_transport() tr._closing = True tr._force_close(None) test_utils.run_briefly(self.loop) self.assertFalse(self.protocol.connection_lost.called) def test_fatal_error_2(self): - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) + tr = self.socket_transport() tr._buffer = [b'data'] tr._force_close(None) test_utils.run_briefly(self.loop) self.protocol.connection_lost.assert_called_with(None) - self.assertEqual([], tr._buffer) + self.assertEqual(None, tr._buffer) def test_call_connection_lost(self): - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) + tr = self.socket_transport() tr._call_connection_lost(None) self.assertTrue(self.protocol.connection_lost.called) self.assertTrue(self.sock.close.called) def test_write_eof(self): - tr = _ProactorSocketTransport( - self.loop, self.sock, self.protocol) + tr = self.socket_transport() self.assertTrue(tr.can_write_eof()) tr.write_eof() self.sock.shutdown.assert_called_with(socket.SHUT_WR) @@ -262,7 +280,7 @@ def test_write_eof(self): tr.close() def test_write_eof_buffer(self): - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) + tr = self.socket_transport() f = asyncio.Future(loop=self.loop) tr._loop._proactor.send.return_value = f tr.write(b'data') @@ -306,11 +324,10 @@ def test_write_eof_duplex_pipe(self): self.assertFalse(tr.can_write_eof()) with self.assertRaises(NotImplementedError): tr.write_eof() - tr.close() + close_transport(tr) def test_pause_resume_reading(self): - tr = _ProactorSocketTransport( - self.loop, self.sock, self.protocol) + tr = self.socket_transport() futures = [] for msg in [b'data1', b'data2', b'data3', b'data4', b'']: f = asyncio.Future(loop=self.loop) @@ -337,30 +354,111 @@ def test_pause_resume_reading(self): tr.close() -class BaseProactorEventLoopTests(unittest.TestCase): + def pause_writing_transport(self, high): + tr = self.socket_transport() + tr.set_write_buffer_limits(high=high) + + self.assertEqual(tr.get_write_buffer_size(), 0) + self.assertFalse(self.protocol.pause_writing.called) + self.assertFalse(self.protocol.resume_writing.called) + return tr + + def test_pause_resume_writing(self): + tr = self.pause_writing_transport(high=4) + + # write a large chunk, must pause writing + fut = asyncio.Future(loop=self.loop) + self.loop._proactor.send.return_value = fut + tr.write(b'large data') + self.loop._run_once() + self.assertTrue(self.protocol.pause_writing.called) + + # flush the buffer + fut.set_result(None) + self.loop._run_once() + self.assertEqual(tr.get_write_buffer_size(), 0) + self.assertTrue(self.protocol.resume_writing.called) + + def test_pause_writing_2write(self): + tr = self.pause_writing_transport(high=4) + + # first short write, the buffer is not full (3 <= 4) + fut1 = asyncio.Future(loop=self.loop) + self.loop._proactor.send.return_value = fut1 + tr.write(b'123') + self.loop._run_once() + self.assertEqual(tr.get_write_buffer_size(), 3) + self.assertFalse(self.protocol.pause_writing.called) + + # fill the buffer, must pause writing (6 > 4) + tr.write(b'abc') + self.loop._run_once() + self.assertEqual(tr.get_write_buffer_size(), 6) + self.assertTrue(self.protocol.pause_writing.called) + + def test_pause_writing_3write(self): + tr = self.pause_writing_transport(high=4) + + # first short write, the buffer is not full (1 <= 4) + fut = asyncio.Future(loop=self.loop) + self.loop._proactor.send.return_value = fut + tr.write(b'1') + self.loop._run_once() + self.assertEqual(tr.get_write_buffer_size(), 1) + self.assertFalse(self.protocol.pause_writing.called) + + # second short write, the buffer is not full (3 <= 4) + tr.write(b'23') + self.loop._run_once() + self.assertEqual(tr.get_write_buffer_size(), 3) + self.assertFalse(self.protocol.pause_writing.called) + + # fill the buffer, must pause writing (6 > 4) + tr.write(b'abc') + self.loop._run_once() + self.assertEqual(tr.get_write_buffer_size(), 6) + self.assertTrue(self.protocol.pause_writing.called) + + def test_dont_pause_writing(self): + tr = self.pause_writing_transport(high=4) + + # write a large chunk which completes immedialty, + # it should not pause writing + fut = asyncio.Future(loop=self.loop) + fut.set_result(None) + self.loop._proactor.send.return_value = fut + tr.write(b'very large data') + self.loop._run_once() + self.assertEqual(tr.get_write_buffer_size(), 0) + self.assertFalse(self.protocol.pause_writing.called) + + +class BaseProactorEventLoopTests(test_utils.TestCase): def setUp(self): - self.sock = unittest.mock.Mock(socket.socket) - self.proactor = unittest.mock.Mock() + self.sock = mock.Mock(socket.socket) + self.proactor = mock.Mock() - self.ssock, self.csock = unittest.mock.Mock(), unittest.mock.Mock() + self.ssock, self.csock = mock.Mock(), mock.Mock() class EventLoop(BaseProactorEventLoop): def _socketpair(s): return (self.ssock, self.csock) self.loop = EventLoop(self.proactor) + self.set_event_loop(self.loop) - @unittest.mock.patch.object(BaseProactorEventLoop, 'call_soon') - @unittest.mock.patch.object(BaseProactorEventLoop, '_socketpair') + @mock.patch.object(BaseProactorEventLoop, 'call_soon') + @mock.patch.object(BaseProactorEventLoop, '_socketpair') def test_ctor(self, socketpair, call_soon): ssock, csock = socketpair.return_value = ( - unittest.mock.Mock(), unittest.mock.Mock()) + mock.Mock(), mock.Mock()) loop = BaseProactorEventLoop(self.proactor) self.assertIs(loop._ssock, ssock) self.assertIs(loop._csock, csock) self.assertEqual(loop._internal_fds, 1) call_soon.assert_called_with(loop._loop_self_reading) + loop.close() def test_close_self_pipe(self): self.loop._close_self_pipe() @@ -370,8 +468,11 @@ def test_close_self_pipe(self): self.assertIsNone(self.loop._ssock) self.assertIsNone(self.loop._csock) + # Don't call close(): _close_self_pipe() cannot be called twice + self.loop._closed = True + def test_close(self): - self.loop._close_self_pipe = unittest.mock.Mock() + self.loop._close_self_pipe = mock.Mock() self.loop.close() self.assertTrue(self.loop._close_self_pipe.called) self.assertTrue(self.proactor.close.called) @@ -398,12 +499,17 @@ def test_sock_accept(self): self.proactor.accept.assert_called_with(self.sock) def test_socketpair(self): + class EventLoop(BaseProactorEventLoop): + # override the destructor to not log a ResourceWarning + def __del__(self): + pass self.assertRaises( - NotImplementedError, BaseProactorEventLoop, self.proactor) + NotImplementedError, EventLoop, self.proactor) def test_make_socket_transport(self): - tr = self.loop._make_socket_transport(self.sock, unittest.mock.Mock()) + tr = self.loop._make_socket_transport(self.sock, asyncio.Protocol()) self.assertIsInstance(tr, _ProactorSocketTransport) + close_transport(tr) def test_loop_self_reading(self): self.loop._loop_self_reading() @@ -412,7 +518,7 @@ def test_loop_self_reading(self): self.loop._loop_self_reading) def test_loop_self_reading_fut(self): - fut = unittest.mock.Mock() + fut = mock.Mock() self.loop._loop_self_reading(fut) self.assertTrue(fut.result.called) self.proactor.recv.assert_called_with(self.ssock, 4096) @@ -420,22 +526,23 @@ def test_loop_self_reading_fut(self): self.loop._loop_self_reading) def test_loop_self_reading_exception(self): - self.loop.close = unittest.mock.Mock() + self.loop.close = mock.Mock() + self.loop.call_exception_handler = mock.Mock() self.proactor.recv.side_effect = OSError() - self.assertRaises(OSError, self.loop._loop_self_reading) - self.assertTrue(self.loop.close.called) + self.loop._loop_self_reading() + self.assertTrue(self.loop.call_exception_handler.called) def test_write_to_self(self): self.loop._write_to_self() - self.csock.send.assert_called_with(b'x') + self.csock.send.assert_called_with(b'\0') def test_process_events(self): self.loop._process_events([]) - @unittest.mock.patch('asyncio.proactor_events.logger') + @mock.patch('asyncio.base_events.logger') def test_create_server(self, m_log): - pf = unittest.mock.Mock() - call_soon = self.loop.call_soon = unittest.mock.Mock() + pf = mock.Mock() + call_soon = self.loop.call_soon = mock.Mock() self.loop._start_serving(pf, self.sock) self.assertTrue(call_soon.called) @@ -446,10 +553,10 @@ def test_create_server(self, m_log): self.proactor.accept.assert_called_with(self.sock) # conn - fut = unittest.mock.Mock() - fut.result.return_value = (unittest.mock.Mock(), unittest.mock.Mock()) + fut = mock.Mock() + fut.result.return_value = (mock.Mock(), mock.Mock()) - make_tr = self.loop._make_socket_transport = unittest.mock.Mock() + make_tr = self.loop._make_socket_transport = mock.Mock() loop(fut) self.assertTrue(fut.result.called) self.assertTrue(make_tr.called) @@ -458,11 +565,11 @@ def test_create_server(self, m_log): fut.result.side_effect = OSError() loop(fut) self.assertTrue(self.sock.close.called) - self.assertTrue(m_log.exception.called) + self.assertTrue(m_log.error.called) def test_create_server_cancel(self): - pf = unittest.mock.Mock() - call_soon = self.loop.call_soon = unittest.mock.Mock() + pf = mock.Mock() + call_soon = self.loop.call_soon = mock.Mock() self.loop._start_serving(pf, self.sock) loop = call_soon.call_args[0][0] @@ -474,7 +581,7 @@ def test_create_server_cancel(self): self.assertTrue(self.sock.close.called) def test_stop_serving(self): - sock = unittest.mock.Mock() + sock = mock.Mock() self.loop._stop_serving(sock) self.assertTrue(sock.close.called) self.proactor._stop_serving.assert_called_with(sock) diff --git a/Lib/test/test_asyncio/test_queues.py b/Lib/test/test_asyncio/test_queues.py index 8af4ee7f9b03..a73539d1a6c7 100644 --- a/Lib/test/test_asyncio/test_queues.py +++ b/Lib/test/test_asyncio/test_queues.py @@ -1,24 +1,16 @@ """Tests for queues.py""" import unittest -import unittest.mock +from unittest import mock -from asyncio import events -from asyncio import futures -from asyncio import locks -from asyncio import queues -from asyncio import tasks +import asyncio from asyncio import test_utils -class _QueueTestBase(unittest.TestCase): +class _QueueTestBase(test_utils.TestCase): def setUp(self): - self.loop = test_utils.TestLoop() - events.set_event_loop(None) - - def tearDown(self): - self.loop.close() + self.loop = self.new_test_loop() class QueueBasicTests(_QueueTestBase): @@ -36,60 +28,56 @@ def gen(): self.assertAlmostEqual(0.2, when) yield 0.1 - loop = test_utils.TestLoop(gen) - self.addCleanup(loop.close) + loop = self.new_test_loop(gen) - q = queues.Queue(loop=loop) + q = asyncio.Queue(loop=loop) self.assertTrue(fn(q).startswith('<Queue'), fn(q)) id_is_present = hex(id(q)) in fn(q) self.assertEqual(expect_id, id_is_present) - @tasks.coroutine + @asyncio.coroutine def add_getter(): - q = queues.Queue(loop=loop) + q = asyncio.Queue(loop=loop) # Start a task that waits to get. - tasks.Task(q.get(), loop=loop) + asyncio.Task(q.get(), loop=loop) # Let it start waiting. - yield from tasks.sleep(0.1, loop=loop) + yield from asyncio.sleep(0.1, loop=loop) self.assertTrue('_getters[1]' in fn(q)) # resume q.get coroutine to finish generator q.put_nowait(0) loop.run_until_complete(add_getter()) - @tasks.coroutine + @asyncio.coroutine def add_putter(): - q = queues.Queue(maxsize=1, loop=loop) + q = asyncio.Queue(maxsize=1, loop=loop) q.put_nowait(1) # Start a task that waits to put. - tasks.Task(q.put(2), loop=loop) + asyncio.Task(q.put(2), loop=loop) # Let it start waiting. - yield from tasks.sleep(0.1, loop=loop) + yield from asyncio.sleep(0.1, loop=loop) self.assertTrue('_putters[1]' in fn(q)) # resume q.put coroutine to finish generator q.get_nowait() loop.run_until_complete(add_putter()) - q = queues.Queue(loop=loop) + q = asyncio.Queue(loop=loop) q.put_nowait(1) self.assertTrue('_queue=[1]' in fn(q)) def test_ctor_loop(self): - loop = unittest.mock.Mock() - q = queues.Queue(loop=loop) + loop = mock.Mock() + q = asyncio.Queue(loop=loop) self.assertIs(q._loop, loop) - q = queues.Queue(loop=self.loop) + q = asyncio.Queue(loop=self.loop) self.assertIs(q._loop, self.loop) def test_ctor_noloop(self): - try: - events.set_event_loop(self.loop) - q = queues.Queue() - self.assertIs(q._loop, self.loop) - finally: - events.set_event_loop(None) + asyncio.set_event_loop(self.loop) + q = asyncio.Queue() + self.assertIs(q._loop, self.loop) def test_repr(self): self._test_repr_or_str(repr, True) @@ -98,7 +86,7 @@ def test_str(self): self._test_repr_or_str(str, False) def test_empty(self): - q = queues.Queue(loop=self.loop) + q = asyncio.Queue(loop=self.loop) self.assertTrue(q.empty()) q.put_nowait(1) self.assertFalse(q.empty()) @@ -106,15 +94,15 @@ def test_empty(self): self.assertTrue(q.empty()) def test_full(self): - q = queues.Queue(loop=self.loop) + q = asyncio.Queue(loop=self.loop) self.assertFalse(q.full()) - q = queues.Queue(maxsize=1, loop=self.loop) + q = asyncio.Queue(maxsize=1, loop=self.loop) q.put_nowait(1) self.assertTrue(q.full()) def test_order(self): - q = queues.Queue(loop=self.loop) + q = asyncio.Queue(loop=self.loop) for i in [1, 3, 2]: q.put_nowait(i) @@ -130,31 +118,30 @@ def gen(): self.assertAlmostEqual(0.02, when) yield 0.01 - loop = test_utils.TestLoop(gen) - self.addCleanup(loop.close) + loop = self.new_test_loop(gen) - q = queues.Queue(maxsize=2, loop=loop) + q = asyncio.Queue(maxsize=2, loop=loop) self.assertEqual(2, q.maxsize) have_been_put = [] - @tasks.coroutine + @asyncio.coroutine def putter(): for i in range(3): yield from q.put(i) have_been_put.append(i) return True - @tasks.coroutine + @asyncio.coroutine def test(): - t = tasks.Task(putter(), loop=loop) - yield from tasks.sleep(0.01, loop=loop) + t = asyncio.Task(putter(), loop=loop) + yield from asyncio.sleep(0.01, loop=loop) # The putter is blocked after putting two items. self.assertEqual([0, 1], have_been_put) self.assertEqual(0, q.get_nowait()) # Let the putter resume and put last item. - yield from tasks.sleep(0.01, loop=loop) + yield from asyncio.sleep(0.01, loop=loop) self.assertEqual([0, 1, 2], have_been_put) self.assertEqual(1, q.get_nowait()) self.assertEqual(2, q.get_nowait()) @@ -169,10 +156,10 @@ def test(): class QueueGetTests(_QueueTestBase): def test_blocking_get(self): - q = queues.Queue(loop=self.loop) + q = asyncio.Queue(loop=self.loop) q.put_nowait(1) - @tasks.coroutine + @asyncio.coroutine def queue_get(): return (yield from q.get()) @@ -180,10 +167,10 @@ def queue_get(): self.assertEqual(1, res) def test_get_with_putters(self): - q = queues.Queue(1, loop=self.loop) + q = asyncio.Queue(1, loop=self.loop) q.put_nowait(1) - waiter = futures.Future(loop=self.loop) + waiter = asyncio.Future(loop=self.loop) q._putters.append((2, waiter)) res = self.loop.run_until_complete(q.get()) @@ -198,14 +185,13 @@ def gen(): self.assertAlmostEqual(0.01, when) yield 0.01 - loop = test_utils.TestLoop(gen) - self.addCleanup(loop.close) + loop = self.new_test_loop(gen) - q = queues.Queue(loop=loop) - started = locks.Event(loop=loop) + q = asyncio.Queue(loop=loop) + started = asyncio.Event(loop=loop) finished = False - @tasks.coroutine + @asyncio.coroutine def queue_get(): nonlocal finished started.set() @@ -213,10 +199,10 @@ def queue_get(): finished = True return res - @tasks.coroutine + @asyncio.coroutine def queue_put(): loop.call_later(0.01, q.put_nowait, 1) - queue_get_task = tasks.Task(queue_get(), loop=loop) + queue_get_task = asyncio.Task(queue_get(), loop=loop) yield from started.wait() self.assertFalse(finished) res = yield from queue_get_task @@ -228,13 +214,13 @@ def queue_put(): self.assertAlmostEqual(0.01, loop.time()) def test_nonblocking_get(self): - q = queues.Queue(loop=self.loop) + q = asyncio.Queue(loop=self.loop) q.put_nowait(1) self.assertEqual(1, q.get_nowait()) def test_nonblocking_get_exception(self): - q = queues.Queue(loop=self.loop) - self.assertRaises(queues.Empty, q.get_nowait) + q = asyncio.Queue(loop=self.loop) + self.assertRaises(asyncio.QueueEmpty, q.get_nowait) def test_get_cancelled(self): @@ -245,19 +231,18 @@ def gen(): self.assertAlmostEqual(0.061, when) yield 0.05 - loop = test_utils.TestLoop(gen) - self.addCleanup(loop.close) + loop = self.new_test_loop(gen) - q = queues.Queue(loop=loop) + q = asyncio.Queue(loop=loop) - @tasks.coroutine + @asyncio.coroutine def queue_get(): - return (yield from tasks.wait_for(q.get(), 0.051, loop=loop)) + return (yield from asyncio.wait_for(q.get(), 0.051, loop=loop)) - @tasks.coroutine + @asyncio.coroutine def test(): - get_task = tasks.Task(queue_get(), loop=loop) - yield from tasks.sleep(0.01, loop=loop) # let the task start + get_task = asyncio.Task(queue_get(), loop=loop) + yield from asyncio.sleep(0.01, loop=loop) # let the task start q.put_nowait(1) return (yield from get_task) @@ -265,10 +250,10 @@ def test(): self.assertAlmostEqual(0.06, loop.time()) def test_get_cancelled_race(self): - q = queues.Queue(loop=self.loop) + q = asyncio.Queue(loop=self.loop) - t1 = tasks.Task(q.get(), loop=self.loop) - t2 = tasks.Task(q.get(), loop=self.loop) + t1 = asyncio.Task(q.get(), loop=self.loop) + t2 = asyncio.Task(q.get(), loop=self.loop) test_utils.run_briefly(self.loop) t1.cancel() @@ -279,9 +264,9 @@ def test_get_cancelled_race(self): self.assertEqual(t2.result(), 'a') def test_get_with_waiting_putters(self): - q = queues.Queue(loop=self.loop, maxsize=1) - tasks.Task(q.put('a'), loop=self.loop) - tasks.Task(q.put('b'), loop=self.loop) + q = asyncio.Queue(loop=self.loop, maxsize=1) + asyncio.Task(q.put('a'), loop=self.loop) + asyncio.Task(q.put('b'), loop=self.loop) test_utils.run_briefly(self.loop) self.assertEqual(self.loop.run_until_complete(q.get()), 'a') self.assertEqual(self.loop.run_until_complete(q.get()), 'b') @@ -290,9 +275,9 @@ def test_get_with_waiting_putters(self): class QueuePutTests(_QueueTestBase): def test_blocking_put(self): - q = queues.Queue(loop=self.loop) + q = asyncio.Queue(loop=self.loop) - @tasks.coroutine + @asyncio.coroutine def queue_put(): # No maxsize, won't block. yield from q.put(1) @@ -306,14 +291,13 @@ def gen(): self.assertAlmostEqual(0.01, when) yield 0.01 - loop = test_utils.TestLoop(gen) - self.addCleanup(loop.close) + loop = self.new_test_loop(gen) - q = queues.Queue(maxsize=1, loop=loop) - started = locks.Event(loop=loop) + q = asyncio.Queue(maxsize=1, loop=loop) + started = asyncio.Event(loop=loop) finished = False - @tasks.coroutine + @asyncio.coroutine def queue_put(): nonlocal finished started.set() @@ -321,10 +305,10 @@ def queue_put(): yield from q.put(2) finished = True - @tasks.coroutine + @asyncio.coroutine def queue_get(): loop.call_later(0.01, q.get_nowait) - queue_put_task = tasks.Task(queue_put(), loop=loop) + queue_put_task = asyncio.Task(queue_put(), loop=loop) yield from started.wait() self.assertFalse(finished) yield from queue_put_task @@ -334,49 +318,69 @@ def queue_get(): self.assertAlmostEqual(0.01, loop.time()) def test_nonblocking_put(self): - q = queues.Queue(loop=self.loop) + q = asyncio.Queue(loop=self.loop) q.put_nowait(1) self.assertEqual(1, q.get_nowait()) def test_nonblocking_put_exception(self): - q = queues.Queue(maxsize=1, loop=self.loop) + q = asyncio.Queue(maxsize=1, loop=self.loop) q.put_nowait(1) - self.assertRaises(queues.Full, q.put_nowait, 2) + self.assertRaises(asyncio.QueueFull, q.put_nowait, 2) + + def test_float_maxsize(self): + q = asyncio.Queue(maxsize=1.3, loop=self.loop) + q.put_nowait(1) + q.put_nowait(2) + self.assertTrue(q.full()) + self.assertRaises(asyncio.QueueFull, q.put_nowait, 3) + + q = asyncio.Queue(maxsize=1.3, loop=self.loop) + @asyncio.coroutine + def queue_put(): + yield from q.put(1) + yield from q.put(2) + self.assertTrue(q.full()) + self.loop.run_until_complete(queue_put()) def test_put_cancelled(self): - q = queues.Queue(loop=self.loop) + q = asyncio.Queue(loop=self.loop) - @tasks.coroutine + @asyncio.coroutine def queue_put(): yield from q.put(1) return True - @tasks.coroutine + @asyncio.coroutine def test(): return (yield from q.get()) - t = tasks.Task(queue_put(), loop=self.loop) + t = asyncio.Task(queue_put(), loop=self.loop) self.assertEqual(1, self.loop.run_until_complete(test())) self.assertTrue(t.done()) self.assertTrue(t.result()) def test_put_cancelled_race(self): - q = queues.Queue(loop=self.loop, maxsize=1) + q = asyncio.Queue(loop=self.loop, maxsize=1) - tasks.Task(q.put('a'), loop=self.loop) - tasks.Task(q.put('c'), loop=self.loop) - t = tasks.Task(q.put('b'), loop=self.loop) + put_a = asyncio.Task(q.put('a'), loop=self.loop) + put_b = asyncio.Task(q.put('b'), loop=self.loop) + put_c = asyncio.Task(q.put('X'), loop=self.loop) test_utils.run_briefly(self.loop) - t.cancel() + self.assertTrue(put_a.done()) + self.assertFalse(put_b.done()) + + put_c.cancel() test_utils.run_briefly(self.loop) - self.assertTrue(t.done()) + self.assertTrue(put_c.done()) self.assertEqual(q.get_nowait(), 'a') - self.assertEqual(q.get_nowait(), 'c') + self.assertEqual(q.get_nowait(), 'b') + + self.loop.run_until_complete(put_b) def test_put_with_waiting_getters(self): - q = queues.Queue(loop=self.loop) - t = tasks.Task(q.get(), loop=self.loop) + q = asyncio.Queue(loop=self.loop) + t = asyncio.Task(q.get(), loop=self.loop) test_utils.run_briefly(self.loop) self.loop.run_until_complete(q.put('a')) self.assertEqual(self.loop.run_until_complete(t), 'a') @@ -385,7 +389,7 @@ def test_put_with_waiting_getters(self): class LifoQueueTests(_QueueTestBase): def test_order(self): - q = queues.LifoQueue(loop=self.loop) + q = asyncio.LifoQueue(loop=self.loop) for i in [1, 3, 2]: q.put_nowait(i) @@ -396,7 +400,7 @@ def test_order(self): class PriorityQueueTests(_QueueTestBase): def test_order(self): - q = queues.PriorityQueue(loop=self.loop) + q = asyncio.PriorityQueue(loop=self.loop) for i in [1, 3, 2]: q.put_nowait(i) @@ -404,14 +408,14 @@ def test_order(self): self.assertEqual([1, 2, 3], items) -class JoinableQueueTests(_QueueTestBase): +class QueueJoinTests(_QueueTestBase): def test_task_done_underflow(self): - q = queues.JoinableQueue(loop=self.loop) + q = asyncio.Queue(loop=self.loop) self.assertRaises(ValueError, q.task_done) def test_task_done(self): - q = queues.JoinableQueue(loop=self.loop) + q = asyncio.Queue(loop=self.loop) for i in range(100): q.put_nowait(i) @@ -421,7 +425,7 @@ def test_task_done(self): # Join the queue and assert all items have been processed. running = True - @tasks.coroutine + @asyncio.coroutine def worker(): nonlocal accumulator @@ -430,28 +434,30 @@ def worker(): accumulator += item q.task_done() - @tasks.coroutine + @asyncio.coroutine def test(): - for _ in range(2): - tasks.Task(worker(), loop=self.loop) + tasks = [asyncio.Task(worker(), loop=self.loop) + for index in range(2)] yield from q.join() + return tasks - self.loop.run_until_complete(test()) + tasks = self.loop.run_until_complete(test()) self.assertEqual(sum(range(100)), accumulator) # close running generators running = False - for i in range(2): + for i in range(len(tasks)): q.put_nowait(0) + self.loop.run_until_complete(asyncio.wait(tasks, loop=self.loop)) def test_join_empty_queue(self): - q = queues.JoinableQueue(loop=self.loop) + q = asyncio.Queue(loop=self.loop) # Test that a queue join()s successfully, and before anything else # (done twice for insurance). - @tasks.coroutine + @asyncio.coroutine def join(): yield from q.join() yield from q.join() @@ -459,7 +465,7 @@ def join(): self.loop.run_until_complete(join()) def test_format(self): - q = queues.JoinableQueue(loop=self.loop) + q = asyncio.Queue(loop=self.loop) self.assertEqual(q._format(), 'maxsize=0') q._unfinished_tasks = 2 diff --git a/Lib/test/test_asyncio/test_selector_events.py b/Lib/test/test_asyncio/test_selector_events.py index 38aa76699843..f64e40dafcd5 100644 --- a/Lib/test/test_asyncio/test_selector_events.py +++ b/Lib/test/test_asyncio/test_selector_events.py @@ -1,22 +1,17 @@ """Tests for selector_events.py""" -import collections import errno -import gc -import pprint import socket -import sys import unittest -import unittest.mock +from unittest import mock try: import ssl except ImportError: ssl = None -from asyncio import futures +import asyncio from asyncio import selectors from asyncio import test_utils -from asyncio.protocols import DatagramProtocol, Protocol from asyncio.selector_events import BaseSelectorEventLoop from asyncio.selector_events import _SelectorTransport from asyncio.selector_events import _SelectorSslTransport @@ -24,11 +19,19 @@ from asyncio.selector_events import _SelectorDatagramTransport +MOCK_ANY = mock.ANY + + class TestBaseSelectorEventLoop(BaseSelectorEventLoop): + def close(self): + # Don't call the close() method of the parent class, because the + # selector is mocked + self._closed = True + def _make_self_pipe(self): - self._ssock = unittest.mock.Mock() - self._csock = unittest.mock.Mock() + self._ssock = mock.Mock() + self._csock = mock.Mock() self._internal_fds += 1 @@ -36,47 +39,89 @@ def list_to_buffer(l=()): return bytearray().join(l) -class BaseSelectorEventLoopTests(unittest.TestCase): +def close_transport(transport): + # Don't call transport.close() because the event loop and the selector + # are mocked + if transport._sock is None: + return + transport._sock.close() + transport._sock = None + + +class BaseSelectorEventLoopTests(test_utils.TestCase): def setUp(self): - self.loop = TestBaseSelectorEventLoop(unittest.mock.Mock()) + self.selector = mock.Mock() + self.selector.select.return_value = [] + self.loop = TestBaseSelectorEventLoop(self.selector) + self.set_event_loop(self.loop) def test_make_socket_transport(self): - m = unittest.mock.Mock() - self.loop.add_reader = unittest.mock.Mock() - self.assertIsInstance( - self.loop._make_socket_transport(m, m), _SelectorSocketTransport) + m = mock.Mock() + self.loop.add_reader = mock.Mock() + self.loop.add_reader._is_coroutine = False + transport = self.loop._make_socket_transport(m, asyncio.Protocol()) + self.assertIsInstance(transport, _SelectorSocketTransport) + close_transport(transport) @unittest.skipIf(ssl is None, 'No ssl module') def test_make_ssl_transport(self): - m = unittest.mock.Mock() - self.loop.add_reader = unittest.mock.Mock() - self.loop.add_writer = unittest.mock.Mock() - self.loop.remove_reader = unittest.mock.Mock() - self.loop.remove_writer = unittest.mock.Mock() - self.assertIsInstance( - self.loop._make_ssl_transport(m, m, m, m), _SelectorSslTransport) - - @unittest.mock.patch('asyncio.selector_events.ssl', None) + m = mock.Mock() + self.loop.add_reader = mock.Mock() + self.loop.add_reader._is_coroutine = False + self.loop.add_writer = mock.Mock() + self.loop.remove_reader = mock.Mock() + self.loop.remove_writer = mock.Mock() + waiter = asyncio.Future(loop=self.loop) + with test_utils.disable_logger(): + transport = self.loop._make_ssl_transport( + m, asyncio.Protocol(), m, waiter) + # execute the handshake while the logger is disabled + # to ignore SSL handshake failure + test_utils.run_briefly(self.loop) + + # Sanity check + class_name = transport.__class__.__name__ + self.assertIn("ssl", class_name.lower()) + self.assertIn("transport", class_name.lower()) + + transport.close() + # execute pending callbacks to close the socket transport + test_utils.run_briefly(self.loop) + + @mock.patch('asyncio.selector_events.ssl', None) + @mock.patch('asyncio.sslproto.ssl', None) def test_make_ssl_transport_without_ssl_error(self): - m = unittest.mock.Mock() - self.loop.add_reader = unittest.mock.Mock() - self.loop.add_writer = unittest.mock.Mock() - self.loop.remove_reader = unittest.mock.Mock() - self.loop.remove_writer = unittest.mock.Mock() + m = mock.Mock() + self.loop.add_reader = mock.Mock() + self.loop.add_writer = mock.Mock() + self.loop.remove_reader = mock.Mock() + self.loop.remove_writer = mock.Mock() with self.assertRaises(RuntimeError): self.loop._make_ssl_transport(m, m, m, m) def test_close(self): + class EventLoop(BaseSelectorEventLoop): + def _make_self_pipe(self): + self._ssock = mock.Mock() + self._csock = mock.Mock() + self._internal_fds += 1 + + self.loop = EventLoop(self.selector) + self.set_event_loop(self.loop) + ssock = self.loop._ssock ssock.fileno.return_value = 7 csock = self.loop._csock csock.fileno.return_value = 1 - remove_reader = self.loop.remove_reader = unittest.mock.Mock() + remove_reader = self.loop.remove_reader = mock.Mock() self.loop._selector.close() - self.loop._selector = selector = unittest.mock.Mock() + self.loop._selector = selector = mock.Mock() + self.assertFalse(self.loop.is_closed()) + self.loop.close() + self.assertTrue(self.loop.is_closed()) self.assertIsNone(self.loop._selector) self.assertIsNone(self.loop._csock) self.assertIsNone(self.loop._ssock) @@ -85,21 +130,26 @@ def test_close(self): csock.close.assert_called_with() remove_reader.assert_called_with(7) + # it should be possible to call close() more than once self.loop.close() self.loop.close() - def test_close_no_selector(self): - ssock = self.loop._ssock - csock = self.loop._csock - remove_reader = self.loop.remove_reader = unittest.mock.Mock() + # operation blocked when the loop is closed + f = asyncio.Future(loop=self.loop) + self.assertRaises(RuntimeError, self.loop.run_forever) + self.assertRaises(RuntimeError, self.loop.run_until_complete, f) + fd = 0 + def callback(): + pass + self.assertRaises(RuntimeError, self.loop.add_reader, fd, callback) + self.assertRaises(RuntimeError, self.loop.add_writer, fd, callback) + def test_close_no_selector(self): + self.loop.remove_reader = mock.Mock() self.loop._selector.close() self.loop._selector = None self.loop.close() self.assertIsNone(self.loop._selector) - self.assertFalse(ssock.close.called) - self.assertFalse(csock.close.called) - self.assertFalse(remove_reader.called) def test_socketpair(self): self.assertRaises(NotImplementedError, self.loop._socketpair) @@ -114,54 +164,56 @@ def test_read_from_self_exception(self): def test_write_to_self_tryagain(self): self.loop._csock.send.side_effect = BlockingIOError - self.assertIsNone(self.loop._write_to_self()) + with test_utils.disable_logger(): + self.assertIsNone(self.loop._write_to_self()) def test_write_to_self_exception(self): - self.loop._csock.send.side_effect = OSError() - self.assertRaises(OSError, self.loop._write_to_self) + # _write_to_self() swallows OSError + self.loop._csock.send.side_effect = RuntimeError() + self.assertRaises(RuntimeError, self.loop._write_to_self) def test_sock_recv(self): - sock = unittest.mock.Mock() - self.loop._sock_recv = unittest.mock.Mock() + sock = test_utils.mock_nonblocking_socket() + self.loop._sock_recv = mock.Mock() f = self.loop.sock_recv(sock, 1024) - self.assertIsInstance(f, futures.Future) + self.assertIsInstance(f, asyncio.Future) self.loop._sock_recv.assert_called_with(f, False, sock, 1024) def test__sock_recv_canceled_fut(self): - sock = unittest.mock.Mock() + sock = mock.Mock() - f = futures.Future(loop=self.loop) + f = asyncio.Future(loop=self.loop) f.cancel() self.loop._sock_recv(f, False, sock, 1024) self.assertFalse(sock.recv.called) def test__sock_recv_unregister(self): - sock = unittest.mock.Mock() + sock = mock.Mock() sock.fileno.return_value = 10 - f = futures.Future(loop=self.loop) + f = asyncio.Future(loop=self.loop) f.cancel() - self.loop.remove_reader = unittest.mock.Mock() + self.loop.remove_reader = mock.Mock() self.loop._sock_recv(f, True, sock, 1024) self.assertEqual((10,), self.loop.remove_reader.call_args[0]) def test__sock_recv_tryagain(self): - f = futures.Future(loop=self.loop) - sock = unittest.mock.Mock() + f = asyncio.Future(loop=self.loop) + sock = mock.Mock() sock.fileno.return_value = 10 sock.recv.side_effect = BlockingIOError - self.loop.add_reader = unittest.mock.Mock() + self.loop.add_reader = mock.Mock() self.loop._sock_recv(f, False, sock, 1024) self.assertEqual((10, self.loop._sock_recv, f, True, sock, 1024), self.loop.add_reader.call_args[0]) def test__sock_recv_exception(self): - f = futures.Future(loop=self.loop) - sock = unittest.mock.Mock() + f = asyncio.Future(loop=self.loop) + sock = mock.Mock() sock.fileno.return_value = 10 err = sock.recv.side_effect = OSError() @@ -169,72 +221,72 @@ def test__sock_recv_exception(self): self.assertIs(err, f.exception()) def test_sock_sendall(self): - sock = unittest.mock.Mock() - self.loop._sock_sendall = unittest.mock.Mock() + sock = test_utils.mock_nonblocking_socket() + self.loop._sock_sendall = mock.Mock() f = self.loop.sock_sendall(sock, b'data') - self.assertIsInstance(f, futures.Future) + self.assertIsInstance(f, asyncio.Future) self.assertEqual( (f, False, sock, b'data'), self.loop._sock_sendall.call_args[0]) def test_sock_sendall_nodata(self): - sock = unittest.mock.Mock() - self.loop._sock_sendall = unittest.mock.Mock() + sock = test_utils.mock_nonblocking_socket() + self.loop._sock_sendall = mock.Mock() f = self.loop.sock_sendall(sock, b'') - self.assertIsInstance(f, futures.Future) + self.assertIsInstance(f, asyncio.Future) self.assertTrue(f.done()) self.assertIsNone(f.result()) self.assertFalse(self.loop._sock_sendall.called) def test__sock_sendall_canceled_fut(self): - sock = unittest.mock.Mock() + sock = mock.Mock() - f = futures.Future(loop=self.loop) + f = asyncio.Future(loop=self.loop) f.cancel() self.loop._sock_sendall(f, False, sock, b'data') self.assertFalse(sock.send.called) def test__sock_sendall_unregister(self): - sock = unittest.mock.Mock() + sock = mock.Mock() sock.fileno.return_value = 10 - f = futures.Future(loop=self.loop) + f = asyncio.Future(loop=self.loop) f.cancel() - self.loop.remove_writer = unittest.mock.Mock() + self.loop.remove_writer = mock.Mock() self.loop._sock_sendall(f, True, sock, b'data') self.assertEqual((10,), self.loop.remove_writer.call_args[0]) def test__sock_sendall_tryagain(self): - f = futures.Future(loop=self.loop) - sock = unittest.mock.Mock() + f = asyncio.Future(loop=self.loop) + sock = mock.Mock() sock.fileno.return_value = 10 sock.send.side_effect = BlockingIOError - self.loop.add_writer = unittest.mock.Mock() + self.loop.add_writer = mock.Mock() self.loop._sock_sendall(f, False, sock, b'data') self.assertEqual( (10, self.loop._sock_sendall, f, True, sock, b'data'), self.loop.add_writer.call_args[0]) def test__sock_sendall_interrupted(self): - f = futures.Future(loop=self.loop) - sock = unittest.mock.Mock() + f = asyncio.Future(loop=self.loop) + sock = mock.Mock() sock.fileno.return_value = 10 sock.send.side_effect = InterruptedError - self.loop.add_writer = unittest.mock.Mock() + self.loop.add_writer = mock.Mock() self.loop._sock_sendall(f, False, sock, b'data') self.assertEqual( (10, self.loop._sock_sendall, f, True, sock, b'data'), self.loop.add_writer.call_args[0]) def test__sock_sendall_exception(self): - f = futures.Future(loop=self.loop) - sock = unittest.mock.Mock() + f = asyncio.Future(loop=self.loop) + sock = mock.Mock() sock.fileno.return_value = 10 err = sock.send.side_effect = OSError() @@ -242,9 +294,9 @@ def test__sock_sendall_exception(self): self.assertIs(f.exception(), err) def test__sock_sendall(self): - sock = unittest.mock.Mock() + sock = mock.Mock() - f = futures.Future(loop=self.loop) + f = asyncio.Future(loop=self.loop) sock.fileno.return_value = 10 sock.send.return_value = 4 @@ -253,13 +305,13 @@ def test__sock_sendall(self): self.assertIsNone(f.result()) def test__sock_sendall_partial(self): - sock = unittest.mock.Mock() + sock = mock.Mock() - f = futures.Future(loop=self.loop) + f = asyncio.Future(loop=self.loop) sock.fileno.return_value = 10 sock.send.return_value = 2 - self.loop.add_writer = unittest.mock.Mock() + self.loop.add_writer = mock.Mock() self.loop._sock_sendall(f, False, sock, b'data') self.assertFalse(f.done()) self.assertEqual( @@ -267,13 +319,13 @@ def test__sock_sendall_partial(self): self.loop.add_writer.call_args[0]) def test__sock_sendall_none(self): - sock = unittest.mock.Mock() + sock = mock.Mock() - f = futures.Future(loop=self.loop) + f = asyncio.Future(loop=self.loop) sock.fileno.return_value = 10 sock.send.return_value = 0 - self.loop.add_writer = unittest.mock.Mock() + self.loop.add_writer = mock.Mock() self.loop._sock_sendall(f, False, sock, b'data') self.assertFalse(f.done()) self.assertEqual( @@ -281,86 +333,115 @@ def test__sock_sendall_none(self): self.loop.add_writer.call_args[0]) def test_sock_connect(self): - sock = unittest.mock.Mock() - self.loop._sock_connect = unittest.mock.Mock() + sock = test_utils.mock_nonblocking_socket() + self.loop._sock_connect = mock.Mock() f = self.loop.sock_connect(sock, ('127.0.0.1', 8080)) - self.assertIsInstance(f, futures.Future) + self.assertIsInstance(f, asyncio.Future) self.assertEqual( - (f, False, sock, ('127.0.0.1', 8080)), + (f, sock, ('127.0.0.1', 8080)), self.loop._sock_connect.call_args[0]) + def test_sock_connect_timeout(self): + # Tulip issue #205: sock_connect() must unregister the socket on + # timeout error + + # prepare mocks + self.loop.add_writer = mock.Mock() + self.loop.remove_writer = mock.Mock() + sock = test_utils.mock_nonblocking_socket() + sock.connect.side_effect = BlockingIOError + + # first call to sock_connect() registers the socket + fut = self.loop.sock_connect(sock, ('127.0.0.1', 80)) + self.assertTrue(sock.connect.called) + self.assertTrue(self.loop.add_writer.called) + self.assertEqual(len(fut._callbacks), 1) + + # on timeout, the socket must be unregistered + sock.connect.reset_mock() + fut.set_exception(asyncio.TimeoutError) + with self.assertRaises(asyncio.TimeoutError): + self.loop.run_until_complete(fut) + self.assertTrue(self.loop.remove_writer.called) + def test__sock_connect(self): - f = futures.Future(loop=self.loop) + f = asyncio.Future(loop=self.loop) - sock = unittest.mock.Mock() + sock = mock.Mock() sock.fileno.return_value = 10 - self.loop._sock_connect(f, False, sock, ('127.0.0.1', 8080)) + self.loop._sock_connect(f, sock, ('127.0.0.1', 8080)) self.assertTrue(f.done()) self.assertIsNone(f.result()) self.assertTrue(sock.connect.called) - def test__sock_connect_canceled_fut(self): - sock = unittest.mock.Mock() + def test__sock_connect_cb_cancelled_fut(self): + sock = mock.Mock() + self.loop.remove_writer = mock.Mock() - f = futures.Future(loop=self.loop) + f = asyncio.Future(loop=self.loop) f.cancel() - self.loop._sock_connect(f, False, sock, ('127.0.0.1', 8080)) - self.assertFalse(sock.connect.called) - - def test__sock_connect_unregister(self): - sock = unittest.mock.Mock() - sock.fileno.return_value = 10 + self.loop._sock_connect_cb(f, sock, ('127.0.0.1', 8080)) + self.assertFalse(sock.getsockopt.called) - f = futures.Future(loop=self.loop) - f.cancel() + def test__sock_connect_writer(self): + # check that the fd is registered and then unregistered + self.loop._process_events = mock.Mock() + self.loop.add_writer = mock.Mock() + self.loop.remove_writer = mock.Mock() - self.loop.remove_writer = unittest.mock.Mock() - self.loop._sock_connect(f, True, sock, ('127.0.0.1', 8080)) + sock = mock.Mock() + sock.fileno.return_value = 10 + sock.connect.side_effect = BlockingIOError + sock.getsockopt.return_value = 0 + address = ('127.0.0.1', 8080) + + f = asyncio.Future(loop=self.loop) + self.loop._sock_connect(f, sock, address) + self.assertTrue(self.loop.add_writer.called) + self.assertEqual(10, self.loop.add_writer.call_args[0][0]) + + self.loop._sock_connect_cb(f, sock, address) + # need to run the event loop to execute _sock_connect_done() callback + self.loop.run_until_complete(f) self.assertEqual((10,), self.loop.remove_writer.call_args[0]) - def test__sock_connect_tryagain(self): - f = futures.Future(loop=self.loop) - sock = unittest.mock.Mock() + def test__sock_connect_cb_tryagain(self): + f = asyncio.Future(loop=self.loop) + sock = mock.Mock() sock.fileno.return_value = 10 sock.getsockopt.return_value = errno.EAGAIN - self.loop.add_writer = unittest.mock.Mock() - self.loop.remove_writer = unittest.mock.Mock() + # check that the exception is handled + self.loop._sock_connect_cb(f, sock, ('127.0.0.1', 8080)) - self.loop._sock_connect(f, True, sock, ('127.0.0.1', 8080)) - self.assertEqual( - (10, self.loop._sock_connect, f, - True, sock, ('127.0.0.1', 8080)), - self.loop.add_writer.call_args[0]) - - def test__sock_connect_exception(self): - f = futures.Future(loop=self.loop) - sock = unittest.mock.Mock() + def test__sock_connect_cb_exception(self): + f = asyncio.Future(loop=self.loop) + sock = mock.Mock() sock.fileno.return_value = 10 sock.getsockopt.return_value = errno.ENOTCONN - self.loop.remove_writer = unittest.mock.Mock() - self.loop._sock_connect(f, True, sock, ('127.0.0.1', 8080)) + self.loop.remove_writer = mock.Mock() + self.loop._sock_connect_cb(f, sock, ('127.0.0.1', 8080)) self.assertIsInstance(f.exception(), OSError) def test_sock_accept(self): - sock = unittest.mock.Mock() - self.loop._sock_accept = unittest.mock.Mock() + sock = test_utils.mock_nonblocking_socket() + self.loop._sock_accept = mock.Mock() f = self.loop.sock_accept(sock) - self.assertIsInstance(f, futures.Future) + self.assertIsInstance(f, asyncio.Future) self.assertEqual( (f, False, sock), self.loop._sock_accept.call_args[0]) def test__sock_accept(self): - f = futures.Future(loop=self.loop) + f = asyncio.Future(loop=self.loop) - conn = unittest.mock.Mock() + conn = mock.Mock() - sock = unittest.mock.Mock() + sock = mock.Mock() sock.fileno.return_value = 10 sock.accept.return_value = conn, ('127.0.0.1', 1000) @@ -370,40 +451,40 @@ def test__sock_accept(self): self.assertEqual((False,), conn.setblocking.call_args[0]) def test__sock_accept_canceled_fut(self): - sock = unittest.mock.Mock() + sock = mock.Mock() - f = futures.Future(loop=self.loop) + f = asyncio.Future(loop=self.loop) f.cancel() self.loop._sock_accept(f, False, sock) self.assertFalse(sock.accept.called) def test__sock_accept_unregister(self): - sock = unittest.mock.Mock() + sock = mock.Mock() sock.fileno.return_value = 10 - f = futures.Future(loop=self.loop) + f = asyncio.Future(loop=self.loop) f.cancel() - self.loop.remove_reader = unittest.mock.Mock() + self.loop.remove_reader = mock.Mock() self.loop._sock_accept(f, True, sock) self.assertEqual((10,), self.loop.remove_reader.call_args[0]) def test__sock_accept_tryagain(self): - f = futures.Future(loop=self.loop) - sock = unittest.mock.Mock() + f = asyncio.Future(loop=self.loop) + sock = mock.Mock() sock.fileno.return_value = 10 sock.accept.side_effect = BlockingIOError - self.loop.add_reader = unittest.mock.Mock() + self.loop.add_reader = mock.Mock() self.loop._sock_accept(f, False, sock) self.assertEqual( (10, self.loop._sock_accept, f, True, sock), self.loop.add_reader.call_args[0]) def test__sock_accept_exception(self): - f = futures.Future(loop=self.loop) - sock = unittest.mock.Mock() + f = asyncio.Future(loop=self.loop) + sock = mock.Mock() sock.fileno.return_value = 10 err = sock.accept.side_effect = OSError() @@ -423,8 +504,8 @@ def test_add_reader(self): self.assertIsNone(w) def test_add_reader_existing(self): - reader = unittest.mock.Mock() - writer = unittest.mock.Mock() + reader = mock.Mock() + writer = mock.Mock() self.loop._selector.get_key.return_value = selectors.SelectorKey( 1, 1, selectors.EVENT_WRITE, (reader, writer)) cb = lambda: True @@ -440,7 +521,7 @@ def test_add_reader_existing(self): self.assertEqual(writer, w) def test_add_reader_existing_writer(self): - writer = unittest.mock.Mock() + writer = mock.Mock() self.loop._selector.get_key.return_value = selectors.SelectorKey( 1, 1, selectors.EVENT_WRITE, (None, writer)) cb = lambda: True @@ -462,8 +543,8 @@ def test_remove_reader(self): self.assertTrue(self.loop._selector.unregister.called) def test_remove_reader_read_write(self): - reader = unittest.mock.Mock() - writer = unittest.mock.Mock() + reader = mock.Mock() + writer = mock.Mock() self.loop._selector.get_key.return_value = selectors.SelectorKey( 1, 1, selectors.EVENT_READ | selectors.EVENT_WRITE, (reader, writer)) @@ -493,8 +574,8 @@ def test_add_writer(self): self.assertEqual(cb, w._callback) def test_add_writer_existing(self): - reader = unittest.mock.Mock() - writer = unittest.mock.Mock() + reader = mock.Mock() + writer = mock.Mock() self.loop._selector.get_key.return_value = selectors.SelectorKey( 1, 1, selectors.EVENT_READ, (reader, writer)) cb = lambda: True @@ -517,8 +598,8 @@ def test_remove_writer(self): self.assertTrue(self.loop._selector.unregister.called) def test_remove_writer_read_write(self): - reader = unittest.mock.Mock() - writer = unittest.mock.Mock() + reader = mock.Mock() + writer = mock.Mock() self.loop._selector.get_key.return_value = selectors.SelectorKey( 1, 1, selectors.EVENT_READ | selectors.EVENT_WRITE, (reader, writer)) @@ -536,10 +617,10 @@ def test_remove_writer_unknown(self): self.loop.remove_writer(1)) def test_process_events_read(self): - reader = unittest.mock.Mock() + reader = mock.Mock() reader._cancelled = False - self.loop._add_callback = unittest.mock.Mock() + self.loop._add_callback = mock.Mock() self.loop._process_events( [(selectors.SelectorKey( 1, 1, selectors.EVENT_READ, (reader, None)), @@ -548,10 +629,10 @@ def test_process_events_read(self): self.loop._add_callback.assert_called_with(reader) def test_process_events_read_cancelled(self): - reader = unittest.mock.Mock() + reader = mock.Mock() reader.cancelled = True - self.loop.remove_reader = unittest.mock.Mock() + self.loop.remove_reader = mock.Mock() self.loop._process_events( [(selectors.SelectorKey( 1, 1, selectors.EVENT_READ, (reader, None)), @@ -559,10 +640,10 @@ def test_process_events_read_cancelled(self): self.loop.remove_reader.assert_called_with(1) def test_process_events_write(self): - writer = unittest.mock.Mock() + writer = mock.Mock() writer._cancelled = False - self.loop._add_callback = unittest.mock.Mock() + self.loop._add_callback = mock.Mock() self.loop._process_events( [(selectors.SelectorKey(1, 1, selectors.EVENT_WRITE, (None, writer)), @@ -570,9 +651,9 @@ def test_process_events_write(self): self.loop._add_callback.assert_called_with(writer) def test_process_events_write_cancelled(self): - writer = unittest.mock.Mock() + writer = mock.Mock() writer.cancelled = True - self.loop.remove_writer = unittest.mock.Mock() + self.loop.remove_writer = mock.Mock() self.loop._process_events( [(selectors.SelectorKey(1, 1, selectors.EVENT_WRITE, @@ -581,29 +662,35 @@ def test_process_events_write_cancelled(self): self.loop.remove_writer.assert_called_with(1) -class SelectorTransportTests(unittest.TestCase): +class SelectorTransportTests(test_utils.TestCase): def setUp(self): - self.loop = test_utils.TestLoop() - self.protocol = test_utils.make_test_protocol(Protocol) - self.sock = unittest.mock.Mock(socket.socket) + self.loop = self.new_test_loop() + self.protocol = test_utils.make_test_protocol(asyncio.Protocol) + self.sock = mock.Mock(socket.socket) self.sock.fileno.return_value = 7 + def create_transport(self): + transport = _SelectorTransport(self.loop, self.sock, self.protocol, + None) + self.addCleanup(close_transport, transport) + return transport + def test_ctor(self): - tr = _SelectorTransport(self.loop, self.sock, self.protocol, None) + tr = self.create_transport() self.assertIs(tr._loop, self.loop) self.assertIs(tr._sock, self.sock) self.assertIs(tr._sock_fd, 7) def test_abort(self): - tr = _SelectorTransport(self.loop, self.sock, self.protocol, None) - tr._force_close = unittest.mock.Mock() + tr = self.create_transport() + tr._force_close = mock.Mock() tr.abort() tr._force_close.assert_called_with(None) def test_close(self): - tr = _SelectorTransport(self.loop, self.sock, self.protocol, None) + tr = self.create_transport() tr.close() self.assertTrue(tr._closing) @@ -616,7 +703,7 @@ def test_close(self): self.assertEqual(1, self.loop.remove_reader_count[7]) def test_close_write_buffer(self): - tr = _SelectorTransport(self.loop, self.sock, self.protocol, None) + tr = self.create_transport() tr._buffer.extend(b'data') tr.close() @@ -625,10 +712,10 @@ def test_close_write_buffer(self): self.assertFalse(self.protocol.connection_lost.called) def test_force_close(self): - tr = _SelectorTransport(self.loop, self.sock, self.protocol, None) + tr = self.create_transport() tr._buffer.extend(b'1') - self.loop.add_reader(7, unittest.mock.sentinel) - self.loop.add_writer(7, unittest.mock.sentinel) + self.loop.add_reader(7, mock.sentinel) + self.loop.add_writer(7, mock.sentinel) tr._force_close(None) self.assertTrue(tr._closing) @@ -641,19 +728,25 @@ def test_force_close(self): self.assertFalse(self.loop.readers) self.assertEqual(1, self.loop.remove_reader_count[7]) - @unittest.mock.patch('asyncio.log.logger.exception') + @mock.patch('asyncio.log.logger.error') def test_fatal_error(self, m_exc): exc = OSError() - tr = _SelectorTransport(self.loop, self.sock, self.protocol, None) - tr._force_close = unittest.mock.Mock() + tr = self.create_transport() + tr._force_close = mock.Mock() tr._fatal_error(exc) - m_exc.assert_called_with('Fatal error for %s', tr) + m_exc.assert_called_with( + test_utils.MockPattern( + 'Fatal error on transport\nprotocol:.*\ntransport:.*'), + exc_info=(OSError, MOCK_ANY, MOCK_ANY)) + tr._force_close.assert_called_with(exc) def test_connection_lost(self): exc = OSError() - tr = _SelectorTransport(self.loop, self.sock, self.protocol, None) + tr = self.create_transport() + self.assertIsNotNone(tr._protocol) + self.assertIsNotNone(tr._loop) tr._call_connection_lost(exc) self.protocol.connection_lost.assert_called_with(exc) @@ -661,39 +754,42 @@ def test_connection_lost(self): self.assertIsNone(tr._sock) self.assertIsNone(tr._protocol) - self.assertEqual(2, sys.getrefcount(self.protocol), - pprint.pformat(gc.get_referrers(self.protocol))) self.assertIsNone(tr._loop) - self.assertEqual(2, sys.getrefcount(self.loop), - pprint.pformat(gc.get_referrers(self.loop))) -class SelectorSocketTransportTests(unittest.TestCase): +class SelectorSocketTransportTests(test_utils.TestCase): def setUp(self): - self.loop = test_utils.TestLoop() - self.protocol = test_utils.make_test_protocol(Protocol) - self.sock = unittest.mock.Mock(socket.socket) + self.loop = self.new_test_loop() + self.protocol = test_utils.make_test_protocol(asyncio.Protocol) + self.sock = mock.Mock(socket.socket) self.sock_fd = self.sock.fileno.return_value = 7 + def socket_transport(self, waiter=None): + transport = _SelectorSocketTransport(self.loop, self.sock, + self.protocol, waiter=waiter) + self.addCleanup(close_transport, transport) + return transport + def test_ctor(self): - tr = _SelectorSocketTransport( - self.loop, self.sock, self.protocol) + waiter = asyncio.Future(loop=self.loop) + tr = self.socket_transport(waiter=waiter) + self.loop.run_until_complete(waiter) + self.loop.assert_reader(7, tr._read_ready) test_utils.run_briefly(self.loop) self.protocol.connection_made.assert_called_with(tr) def test_ctor_with_waiter(self): - fut = futures.Future(loop=self.loop) + waiter = asyncio.Future(loop=self.loop) + self.socket_transport(waiter=waiter) + self.loop.run_until_complete(waiter) - _SelectorSocketTransport( - self.loop, self.sock, self.protocol, fut) - test_utils.run_briefly(self.loop) - self.assertIsNone(fut.result()) + self.assertIsNone(waiter.result()) def test_pause_resume_reading(self): - tr = _SelectorSocketTransport( - self.loop, self.sock, self.protocol) + tr = self.socket_transport() + test_utils.run_briefly(self.loop) self.assertFalse(tr._paused) self.loop.assert_reader(7, tr._read_ready) tr.pause_reading() @@ -702,10 +798,11 @@ def test_pause_resume_reading(self): tr.resume_reading() self.assertFalse(tr._paused) self.loop.assert_reader(7, tr._read_ready) + with self.assertRaises(RuntimeError): + tr.resume_reading() def test_read_ready(self): - transport = _SelectorSocketTransport( - self.loop, self.sock, self.protocol) + transport = self.socket_transport() self.sock.recv.return_value = b'data' transport._read_ready() @@ -713,9 +810,8 @@ def test_read_ready(self): self.protocol.data_received.assert_called_with(b'data') def test_read_ready_eof(self): - transport = _SelectorSocketTransport( - self.loop, self.sock, self.protocol) - transport.close = unittest.mock.Mock() + transport = self.socket_transport() + transport.close = mock.Mock() self.sock.recv.return_value = b'' transport._read_ready() @@ -724,9 +820,8 @@ def test_read_ready_eof(self): transport.close.assert_called_with() def test_read_ready_eof_keep_open(self): - transport = _SelectorSocketTransport( - self.loop, self.sock, self.protocol) - transport.close = unittest.mock.Mock() + transport = self.socket_transport() + transport.close = mock.Mock() self.sock.recv.return_value = b'' self.protocol.eof_received.return_value = True @@ -735,55 +830,53 @@ def test_read_ready_eof_keep_open(self): self.protocol.eof_received.assert_called_with() self.assertFalse(transport.close.called) - @unittest.mock.patch('logging.exception') + @mock.patch('logging.exception') def test_read_ready_tryagain(self, m_exc): self.sock.recv.side_effect = BlockingIOError - transport = _SelectorSocketTransport( - self.loop, self.sock, self.protocol) - transport._fatal_error = unittest.mock.Mock() + transport = self.socket_transport() + transport._fatal_error = mock.Mock() transport._read_ready() self.assertFalse(transport._fatal_error.called) - @unittest.mock.patch('logging.exception') + @mock.patch('logging.exception') def test_read_ready_tryagain_interrupted(self, m_exc): self.sock.recv.side_effect = InterruptedError - transport = _SelectorSocketTransport( - self.loop, self.sock, self.protocol) - transport._fatal_error = unittest.mock.Mock() + transport = self.socket_transport() + transport._fatal_error = mock.Mock() transport._read_ready() self.assertFalse(transport._fatal_error.called) - @unittest.mock.patch('logging.exception') + @mock.patch('logging.exception') def test_read_ready_conn_reset(self, m_exc): err = self.sock.recv.side_effect = ConnectionResetError() - transport = _SelectorSocketTransport( - self.loop, self.sock, self.protocol) - transport._force_close = unittest.mock.Mock() - transport._read_ready() + transport = self.socket_transport() + transport._force_close = mock.Mock() + with test_utils.disable_logger(): + transport._read_ready() transport._force_close.assert_called_with(err) - @unittest.mock.patch('logging.exception') + @mock.patch('logging.exception') def test_read_ready_err(self, m_exc): err = self.sock.recv.side_effect = OSError() - transport = _SelectorSocketTransport( - self.loop, self.sock, self.protocol) - transport._fatal_error = unittest.mock.Mock() + transport = self.socket_transport() + transport._fatal_error = mock.Mock() transport._read_ready() - transport._fatal_error.assert_called_with(err) + transport._fatal_error.assert_called_with( + err, + 'Fatal read error on socket transport') def test_write(self): data = b'data' self.sock.send.return_value = len(data) - transport = _SelectorSocketTransport( - self.loop, self.sock, self.protocol) + transport = self.socket_transport() transport.write(data) self.sock.send.assert_called_with(data) @@ -791,8 +884,7 @@ def test_write_bytearray(self): data = bytearray(b'data') self.sock.send.return_value = len(data) - transport = _SelectorSocketTransport( - self.loop, self.sock, self.protocol) + transport = self.socket_transport() transport.write(data) self.sock.send.assert_called_with(data) self.assertEqual(data, bytearray(b'data')) # Hasn't been mutated. @@ -801,22 +893,19 @@ def test_write_memoryview(self): data = memoryview(b'data') self.sock.send.return_value = len(data) - transport = _SelectorSocketTransport( - self.loop, self.sock, self.protocol) + transport = self.socket_transport() transport.write(data) self.sock.send.assert_called_with(data) def test_write_no_data(self): - transport = _SelectorSocketTransport( - self.loop, self.sock, self.protocol) + transport = self.socket_transport() transport._buffer.extend(b'data') transport.write(b'') self.assertFalse(self.sock.send.called) self.assertEqual(list_to_buffer([b'data']), transport._buffer) def test_write_buffer(self): - transport = _SelectorSocketTransport( - self.loop, self.sock, self.protocol) + transport = self.socket_transport() transport._buffer.extend(b'data1') transport.write(b'data2') self.assertFalse(self.sock.send.called) @@ -827,8 +916,7 @@ def test_write_partial(self): data = b'data' self.sock.send.return_value = 2 - transport = _SelectorSocketTransport( - self.loop, self.sock, self.protocol) + transport = self.socket_transport() transport.write(data) self.loop.assert_writer(7, transport._write_ready) @@ -838,8 +926,7 @@ def test_write_partial_bytearray(self): data = bytearray(b'data') self.sock.send.return_value = 2 - transport = _SelectorSocketTransport( - self.loop, self.sock, self.protocol) + transport = self.socket_transport() transport.write(data) self.loop.assert_writer(7, transport._write_ready) @@ -850,8 +937,7 @@ def test_write_partial_memoryview(self): data = memoryview(b'data') self.sock.send.return_value = 2 - transport = _SelectorSocketTransport( - self.loop, self.sock, self.protocol) + transport = self.socket_transport() transport.write(data) self.loop.assert_writer(7, transport._write_ready) @@ -862,8 +948,7 @@ def test_write_partial_none(self): self.sock.send.return_value = 0 self.sock.fileno.return_value = 7 - transport = _SelectorSocketTransport( - self.loop, self.sock, self.protocol) + transport = self.socket_transport() transport.write(data) self.loop.assert_writer(7, transport._write_ready) @@ -873,23 +958,23 @@ def test_write_tryagain(self): self.sock.send.side_effect = BlockingIOError data = b'data' - transport = _SelectorSocketTransport( - self.loop, self.sock, self.protocol) + transport = self.socket_transport() transport.write(data) self.loop.assert_writer(7, transport._write_ready) self.assertEqual(list_to_buffer([b'data']), transport._buffer) - @unittest.mock.patch('asyncio.selector_events.logger') + @mock.patch('asyncio.selector_events.logger') def test_write_exception(self, m_log): err = self.sock.send.side_effect = OSError() data = b'data' - transport = _SelectorSocketTransport( - self.loop, self.sock, self.protocol) - transport._fatal_error = unittest.mock.Mock() + transport = self.socket_transport() + transport._fatal_error = mock.Mock() transport.write(data) - transport._fatal_error.assert_called_with(err) + transport._fatal_error.assert_called_with( + err, + 'Fatal write error on socket transport') transport._conn_lost = 1 self.sock.reset_mock() @@ -903,13 +988,11 @@ def test_write_exception(self, m_log): m_log.warning.assert_called_with('socket.send() raised exception.') def test_write_str(self): - transport = _SelectorSocketTransport( - self.loop, self.sock, self.protocol) + transport = self.socket_transport() self.assertRaises(TypeError, transport.write, 'str') def test_write_closing(self): - transport = _SelectorSocketTransport( - self.loop, self.sock, self.protocol) + transport = self.socket_transport() transport.close() self.assertEqual(transport._conn_lost, 1) transport.write(b'data') @@ -919,8 +1002,7 @@ def test_write_ready(self): data = b'data' self.sock.send.return_value = len(data) - transport = _SelectorSocketTransport( - self.loop, self.sock, self.protocol) + transport = self.socket_transport() transport._buffer.extend(data) self.loop.add_writer(7, transport._write_ready) transport._write_ready() @@ -931,8 +1013,7 @@ def test_write_ready_closing(self): data = b'data' self.sock.send.return_value = len(data) - transport = _SelectorSocketTransport( - self.loop, self.sock, self.protocol) + transport = self.socket_transport() transport._closing = True transport._buffer.extend(data) self.loop.add_writer(7, transport._write_ready) @@ -943,8 +1024,7 @@ def test_write_ready_closing(self): self.protocol.connection_lost.assert_called_with(None) def test_write_ready_no_data(self): - transport = _SelectorSocketTransport( - self.loop, self.sock, self.protocol) + transport = self.socket_transport() # This is an internal error. self.assertRaises(AssertionError, transport._write_ready) @@ -952,8 +1032,7 @@ def test_write_ready_partial(self): data = b'data' self.sock.send.return_value = 2 - transport = _SelectorSocketTransport( - self.loop, self.sock, self.protocol) + transport = self.socket_transport() transport._buffer.extend(data) self.loop.add_writer(7, transport._write_ready) transport._write_ready() @@ -964,8 +1043,7 @@ def test_write_ready_partial_none(self): data = b'data' self.sock.send.return_value = 0 - transport = _SelectorSocketTransport( - self.loop, self.sock, self.protocol) + transport = self.socket_transport() transport._buffer.extend(data) self.loop.add_writer(7, transport._write_ready) transport._write_ready() @@ -975,8 +1053,7 @@ def test_write_ready_partial_none(self): def test_write_ready_tryagain(self): self.sock.send.side_effect = BlockingIOError - transport = _SelectorSocketTransport( - self.loop, self.sock, self.protocol) + transport = self.socket_transport() transport._buffer = list_to_buffer([b'data1', b'data2']) self.loop.add_writer(7, transport._write_ready) transport._write_ready() @@ -987,28 +1064,27 @@ def test_write_ready_tryagain(self): def test_write_ready_exception(self): err = self.sock.send.side_effect = OSError() - transport = _SelectorSocketTransport( - self.loop, self.sock, self.protocol) - transport._fatal_error = unittest.mock.Mock() + transport = self.socket_transport() + transport._fatal_error = mock.Mock() transport._buffer.extend(b'data') transport._write_ready() - transport._fatal_error.assert_called_with(err) + transport._fatal_error.assert_called_with( + err, + 'Fatal write error on socket transport') - @unittest.mock.patch('asyncio.selector_events.logger') + @mock.patch('asyncio.base_events.logger') def test_write_ready_exception_and_close(self, m_log): self.sock.send.side_effect = OSError() - remove_writer = self.loop.remove_writer = unittest.mock.Mock() + remove_writer = self.loop.remove_writer = mock.Mock() - transport = _SelectorSocketTransport( - self.loop, self.sock, self.protocol) + transport = self.socket_transport() transport.close() transport._buffer.extend(b'data') transport._write_ready() remove_writer.assert_called_with(self.sock_fd) def test_write_eof(self): - tr = _SelectorSocketTransport( - self.loop, self.sock, self.protocol) + tr = self.socket_transport() self.assertTrue(tr.can_write_eof()) tr.write_eof() self.sock.shutdown.assert_called_with(socket.SHUT_WR) @@ -1017,8 +1093,7 @@ def test_write_eof(self): tr.close() def test_write_eof_buffer(self): - tr = _SelectorSocketTransport( - self.loop, self.sock, self.protocol) + tr = self.socket_transport() self.sock.send.side_effect = BlockingIOError tr.write(b'data') tr.write_eof() @@ -1033,21 +1108,27 @@ def test_write_eof_buffer(self): @unittest.skipIf(ssl is None, 'No ssl module') -class SelectorSslTransportTests(unittest.TestCase): +class SelectorSslTransportTests(test_utils.TestCase): def setUp(self): - self.loop = test_utils.TestLoop() - self.protocol = test_utils.make_test_protocol(Protocol) - self.sock = unittest.mock.Mock(socket.socket) + self.loop = self.new_test_loop() + self.protocol = test_utils.make_test_protocol(asyncio.Protocol) + self.sock = mock.Mock(socket.socket) self.sock.fileno.return_value = 7 - self.sslsock = unittest.mock.Mock() + self.sslsock = mock.Mock() self.sslsock.fileno.return_value = 1 - self.sslcontext = unittest.mock.Mock() + self.sslcontext = mock.Mock() self.sslcontext.wrap_socket.return_value = self.sslsock + def ssl_transport(self, waiter=None, server_hostname=None): + transport = _SelectorSslTransport(self.loop, self.sock, self.protocol, + self.sslcontext, waiter=waiter, + server_hostname=server_hostname) + self.addCleanup(close_transport, transport) + return transport + def _make_one(self, create_waiter=None): - transport = _SelectorSslTransport( - self.loop, self.sock, self.protocol, self.sslcontext) + transport = self.ssl_transport() self.sock.reset_mock() self.sslsock.reset_mock() self.sslcontext.reset_mock() @@ -1055,50 +1136,58 @@ def _make_one(self, create_waiter=None): return transport def test_on_handshake(self): - waiter = futures.Future(loop=self.loop) - tr = _SelectorSslTransport( - self.loop, self.sock, self.protocol, self.sslcontext, - waiter=waiter) + waiter = asyncio.Future(loop=self.loop) + tr = self.ssl_transport(waiter=waiter) self.assertTrue(self.sslsock.do_handshake.called) self.loop.assert_reader(1, tr._read_ready) test_utils.run_briefly(self.loop) self.assertIsNone(waiter.result()) def test_on_handshake_reader_retry(self): + self.loop.set_debug(False) self.sslsock.do_handshake.side_effect = ssl.SSLWantReadError - transport = _SelectorSslTransport( - self.loop, self.sock, self.protocol, self.sslcontext) - transport._on_handshake() - self.loop.assert_reader(1, transport._on_handshake) + transport = self.ssl_transport() + self.loop.assert_reader(1, transport._on_handshake, None) def test_on_handshake_writer_retry(self): + self.loop.set_debug(False) self.sslsock.do_handshake.side_effect = ssl.SSLWantWriteError - transport = _SelectorSslTransport( - self.loop, self.sock, self.protocol, self.sslcontext) - transport._on_handshake() - self.loop.assert_writer(1, transport._on_handshake) + transport = self.ssl_transport() + self.loop.assert_writer(1, transport._on_handshake, None) def test_on_handshake_exc(self): exc = ValueError() self.sslsock.do_handshake.side_effect = exc - transport = _SelectorSslTransport( - self.loop, self.sock, self.protocol, self.sslcontext) - transport._waiter = futures.Future(loop=self.loop) - transport._on_handshake() + with test_utils.disable_logger(): + waiter = asyncio.Future(loop=self.loop) + transport = self.ssl_transport(waiter=waiter) + self.assertTrue(waiter.done()) + self.assertIs(exc, waiter.exception()) self.assertTrue(self.sslsock.close.called) - self.assertTrue(transport._waiter.done()) - self.assertIs(exc, transport._waiter.exception()) def test_on_handshake_base_exc(self): - transport = _SelectorSslTransport( - self.loop, self.sock, self.protocol, self.sslcontext) - transport._waiter = futures.Future(loop=self.loop) + waiter = asyncio.Future(loop=self.loop) + transport = self.ssl_transport(waiter=waiter) exc = BaseException() self.sslsock.do_handshake.side_effect = exc - self.assertRaises(BaseException, transport._on_handshake) + with test_utils.disable_logger(): + self.assertRaises(BaseException, transport._on_handshake, 0) self.assertTrue(self.sslsock.close.called) - self.assertTrue(transport._waiter.done()) - self.assertIs(exc, transport._waiter.exception()) + self.assertTrue(waiter.done()) + self.assertIs(exc, waiter.exception()) + + def test_cancel_handshake(self): + # Python issue #23197: cancelling an handshake must not raise an + # exception or log an error, even if the handshake failed + waiter = asyncio.Future(loop=self.loop) + transport = self.ssl_transport(waiter=waiter) + waiter.cancel() + exc = ValueError() + self.sslsock.do_handshake.side_effect = exc + with test_utils.disable_logger(): + transport._on_handshake(0) + transport.close() + test_utils.run_briefly(self.loop) def test_pause_resume_reading(self): tr = self._make_one() @@ -1110,6 +1199,8 @@ def test_pause_resume_reading(self): tr.resume_reading() self.assertFalse(tr._paused) self.loop.assert_reader(1, tr._read_ready) + with self.assertRaises(RuntimeError): + tr.resume_reading() def test_write(self): transport = self._make_one() @@ -1147,7 +1238,7 @@ def test_write_closing(self): transport.write(b'data') self.assertEqual(transport._conn_lost, 2) - @unittest.mock.patch('asyncio.selector_events.logger') + @mock.patch('asyncio.selector_events.logger') def test_write_exception(self, m_log): transport = self._make_one() transport._conn_lost = 1 @@ -1167,11 +1258,11 @@ def test_read_ready_recv(self): self.assertEqual((b'data',), self.protocol.data_received.call_args[0]) def test_read_ready_write_wants_read(self): - self.loop.add_writer = unittest.mock.Mock() + self.loop.add_writer = mock.Mock() self.sslsock.recv.side_effect = BlockingIOError transport = self._make_one() transport._write_wants_read = True - transport._write_ready = unittest.mock.Mock() + transport._write_ready = mock.Mock() transport._buffer.extend(b'data') transport._read_ready() @@ -1183,7 +1274,7 @@ def test_read_ready_write_wants_read(self): def test_read_ready_recv_eof(self): self.sslsock.recv.return_value = b'' transport = self._make_one() - transport.close = unittest.mock.Mock() + transport.close = mock.Mock() transport._read_ready() transport.close.assert_called_with() self.protocol.eof_received.assert_called_with() @@ -1191,8 +1282,9 @@ def test_read_ready_recv_eof(self): def test_read_ready_recv_conn_reset(self): err = self.sslsock.recv.side_effect = ConnectionResetError() transport = self._make_one() - transport._force_close = unittest.mock.Mock() - transport._read_ready() + transport._force_close = mock.Mock() + with test_utils.disable_logger(): + transport._read_ready() transport._force_close.assert_called_with(err) def test_read_ready_recv_retry(self): @@ -1211,8 +1303,8 @@ def test_read_ready_recv_retry(self): self.assertFalse(self.protocol.data_received.called) def test_read_ready_recv_write(self): - self.loop.remove_reader = unittest.mock.Mock() - self.loop.add_writer = unittest.mock.Mock() + self.loop.remove_reader = mock.Mock() + self.loop.add_writer = mock.Mock() self.sslsock.recv.side_effect = ssl.SSLWantWriteError transport = self._make_one() transport._read_ready() @@ -1226,9 +1318,11 @@ def test_read_ready_recv_write(self): def test_read_ready_recv_exc(self): err = self.sslsock.recv.side_effect = OSError() transport = self._make_one() - transport._fatal_error = unittest.mock.Mock() + transport._fatal_error = mock.Mock() transport._read_ready() - transport._fatal_error.assert_called_with(err) + transport._fatal_error.assert_called_with( + err, + 'Fatal read error on SSL transport') def test_write_ready_send(self): self.sslsock.send.return_value = 4 @@ -1296,7 +1390,7 @@ def test_write_ready_send_read(self): transport = self._make_one() transport._buffer = list_to_buffer([b'data']) - self.loop.remove_writer = unittest.mock.Mock() + self.loop.remove_writer = mock.Mock() self.sslsock.send.side_effect = ssl.SSLWantReadError transport._write_ready() self.assertFalse(self.protocol.data_received.called) @@ -1308,17 +1402,19 @@ def test_write_ready_send_exc(self): transport = self._make_one() transport._buffer = list_to_buffer([b'data']) - transport._fatal_error = unittest.mock.Mock() + transport._fatal_error = mock.Mock() transport._write_ready() - transport._fatal_error.assert_called_with(err) + transport._fatal_error.assert_called_with( + err, + 'Fatal write error on SSL transport') self.assertEqual(list_to_buffer(), transport._buffer) def test_write_ready_read_wants_write(self): - self.loop.add_reader = unittest.mock.Mock() + self.loop.add_reader = mock.Mock() self.sslsock.send.side_effect = BlockingIOError transport = self._make_one() transport._read_wants_write = True - transport._read_ready = unittest.mock.Mock() + transport._read_ready = mock.Mock() transport._write_ready() self.assertFalse(transport._read_wants_write) @@ -1331,7 +1427,7 @@ def test_write_eof(self): self.assertFalse(tr.can_write_eof()) self.assertRaises(NotImplementedError, tr.write_eof) - def test_close(self): + def check_close(self): tr = self._make_one() tr.close() @@ -1343,11 +1439,22 @@ def test_close(self): self.assertEqual(tr._conn_lost, 1) self.assertEqual(1, self.loop.remove_reader_count[1]) - @unittest.skipIf(ssl is None or not ssl.HAS_SNI, 'No SNI support') + test_utils.run_briefly(self.loop) + + def test_close(self): + self.check_close() + self.assertTrue(self.protocol.connection_made.called) + self.assertTrue(self.protocol.connection_lost.called) + + def test_close_not_connected(self): + self.sslsock.do_handshake.side_effect = ssl.SSLWantReadError + self.check_close() + self.assertFalse(self.protocol.connection_made.called) + self.assertFalse(self.protocol.connection_lost.called) + + @unittest.skipIf(ssl is None, 'No SSL support') def test_server_hostname(self): - _SelectorSslTransport( - self.loop, self.sock, self.protocol, self.sslcontext, - server_hostname='localhost') + self.ssl_transport(server_hostname='localhost') self.sslcontext.wrap_socket.assert_called_with( self.sock, do_handshake_on_connect=False, server_side=False, server_hostname='localhost') @@ -1355,24 +1462,30 @@ def test_server_hostname(self): class SelectorSslWithoutSslTransportTests(unittest.TestCase): - @unittest.mock.patch('asyncio.selector_events.ssl', None) + @mock.patch('asyncio.selector_events.ssl', None) def test_ssl_transport_requires_ssl_module(self): - Mock = unittest.mock.Mock + Mock = mock.Mock with self.assertRaises(RuntimeError): - transport = _SelectorSslTransport(Mock(), Mock(), Mock(), Mock()) + _SelectorSslTransport(Mock(), Mock(), Mock(), Mock()) -class SelectorDatagramTransportTests(unittest.TestCase): +class SelectorDatagramTransportTests(test_utils.TestCase): def setUp(self): - self.loop = test_utils.TestLoop() - self.protocol = test_utils.make_test_protocol(DatagramProtocol) - self.sock = unittest.mock.Mock(spec_set=socket.socket) + self.loop = self.new_test_loop() + self.protocol = test_utils.make_test_protocol(asyncio.DatagramProtocol) + self.sock = mock.Mock(spec_set=socket.socket) self.sock.fileno.return_value = 7 + def datagram_transport(self, address=None): + transport = _SelectorDatagramTransport(self.loop, self.sock, + self.protocol, + address=address) + self.addCleanup(close_transport, transport) + return transport + def test_read_ready(self): - transport = _SelectorDatagramTransport( - self.loop, self.sock, self.protocol) + transport = self.datagram_transport() self.sock.recvfrom.return_value = (b'data', ('0.0.0.0', 1234)) transport._read_ready() @@ -1381,31 +1494,30 @@ def test_read_ready(self): b'data', ('0.0.0.0', 1234)) def test_read_ready_tryagain(self): - transport = _SelectorDatagramTransport( - self.loop, self.sock, self.protocol) + transport = self.datagram_transport() self.sock.recvfrom.side_effect = BlockingIOError - transport._fatal_error = unittest.mock.Mock() + transport._fatal_error = mock.Mock() transport._read_ready() self.assertFalse(transport._fatal_error.called) def test_read_ready_err(self): - transport = _SelectorDatagramTransport( - self.loop, self.sock, self.protocol) + transport = self.datagram_transport() err = self.sock.recvfrom.side_effect = RuntimeError() - transport._fatal_error = unittest.mock.Mock() + transport._fatal_error = mock.Mock() transport._read_ready() - transport._fatal_error.assert_called_with(err) + transport._fatal_error.assert_called_with( + err, + 'Fatal read error on datagram transport') def test_read_ready_oserr(self): - transport = _SelectorDatagramTransport( - self.loop, self.sock, self.protocol) + transport = self.datagram_transport() err = self.sock.recvfrom.side_effect = OSError() - transport._fatal_error = unittest.mock.Mock() + transport._fatal_error = mock.Mock() transport._read_ready() self.assertFalse(transport._fatal_error.called) @@ -1413,8 +1525,7 @@ def test_read_ready_oserr(self): def test_sendto(self): data = b'data' - transport = _SelectorDatagramTransport( - self.loop, self.sock, self.protocol) + transport = self.datagram_transport() transport.sendto(data, ('0.0.0.0', 1234)) self.assertTrue(self.sock.sendto.called) self.assertEqual( @@ -1422,8 +1533,7 @@ def test_sendto(self): def test_sendto_bytearray(self): data = bytearray(b'data') - transport = _SelectorDatagramTransport( - self.loop, self.sock, self.protocol) + transport = self.datagram_transport() transport.sendto(data, ('0.0.0.0', 1234)) self.assertTrue(self.sock.sendto.called) self.assertEqual( @@ -1431,16 +1541,14 @@ def test_sendto_bytearray(self): def test_sendto_memoryview(self): data = memoryview(b'data') - transport = _SelectorDatagramTransport( - self.loop, self.sock, self.protocol) + transport = self.datagram_transport() transport.sendto(data, ('0.0.0.0', 1234)) self.assertTrue(self.sock.sendto.called) self.assertEqual( self.sock.sendto.call_args[0], (data, ('0.0.0.0', 1234))) def test_sendto_no_data(self): - transport = _SelectorDatagramTransport( - self.loop, self.sock, self.protocol) + transport = self.datagram_transport() transport._buffer.append((b'data', ('0.0.0.0', 12345))) transport.sendto(b'', ()) self.assertFalse(self.sock.sendto.called) @@ -1448,8 +1556,7 @@ def test_sendto_no_data(self): [(b'data', ('0.0.0.0', 12345))], list(transport._buffer)) def test_sendto_buffer(self): - transport = _SelectorDatagramTransport( - self.loop, self.sock, self.protocol) + transport = self.datagram_transport() transport._buffer.append((b'data1', ('0.0.0.0', 12345))) transport.sendto(b'data2', ('0.0.0.0', 12345)) self.assertFalse(self.sock.sendto.called) @@ -1460,8 +1567,7 @@ def test_sendto_buffer(self): def test_sendto_buffer_bytearray(self): data2 = bytearray(b'data2') - transport = _SelectorDatagramTransport( - self.loop, self.sock, self.protocol) + transport = self.datagram_transport() transport._buffer.append((b'data1', ('0.0.0.0', 12345))) transport.sendto(data2, ('0.0.0.0', 12345)) self.assertFalse(self.sock.sendto.called) @@ -1473,8 +1579,7 @@ def test_sendto_buffer_bytearray(self): def test_sendto_buffer_memoryview(self): data2 = memoryview(b'data2') - transport = _SelectorDatagramTransport( - self.loop, self.sock, self.protocol) + transport = self.datagram_transport() transport._buffer.append((b'data1', ('0.0.0.0', 12345))) transport.sendto(data2, ('0.0.0.0', 12345)) self.assertFalse(self.sock.sendto.called) @@ -1489,26 +1594,26 @@ def test_sendto_tryagain(self): self.sock.sendto.side_effect = BlockingIOError - transport = _SelectorDatagramTransport( - self.loop, self.sock, self.protocol) + transport = self.datagram_transport() transport.sendto(data, ('0.0.0.0', 12345)) self.loop.assert_writer(7, transport._sendto_ready) self.assertEqual( [(b'data', ('0.0.0.0', 12345))], list(transport._buffer)) - @unittest.mock.patch('asyncio.selector_events.logger') + @mock.patch('asyncio.selector_events.logger') def test_sendto_exception(self, m_log): data = b'data' err = self.sock.sendto.side_effect = RuntimeError() - transport = _SelectorDatagramTransport( - self.loop, self.sock, self.protocol) - transport._fatal_error = unittest.mock.Mock() + transport = self.datagram_transport() + transport._fatal_error = mock.Mock() transport.sendto(data, ()) self.assertTrue(transport._fatal_error.called) - transport._fatal_error.assert_called_with(err) + transport._fatal_error.assert_called_with( + err, + 'Fatal write error on datagram transport') transport._conn_lost = 1 transport._address = ('123',) @@ -1524,9 +1629,8 @@ def test_sendto_error_received(self): self.sock.sendto.side_effect = ConnectionRefusedError - transport = _SelectorDatagramTransport( - self.loop, self.sock, self.protocol) - transport._fatal_error = unittest.mock.Mock() + transport = self.datagram_transport() + transport._fatal_error = mock.Mock() transport.sendto(data, ()) self.assertEqual(transport._conn_lost, 0) @@ -1537,28 +1641,24 @@ def test_sendto_error_received_connected(self): self.sock.send.side_effect = ConnectionRefusedError - transport = _SelectorDatagramTransport( - self.loop, self.sock, self.protocol, ('0.0.0.0', 1)) - transport._fatal_error = unittest.mock.Mock() + transport = self.datagram_transport(address=('0.0.0.0', 1)) + transport._fatal_error = mock.Mock() transport.sendto(data) self.assertFalse(transport._fatal_error.called) self.assertTrue(self.protocol.error_received.called) def test_sendto_str(self): - transport = _SelectorDatagramTransport( - self.loop, self.sock, self.protocol) + transport = self.datagram_transport() self.assertRaises(TypeError, transport.sendto, 'str', ()) def test_sendto_connected_addr(self): - transport = _SelectorDatagramTransport( - self.loop, self.sock, self.protocol, ('0.0.0.0', 1)) + transport = self.datagram_transport(address=('0.0.0.0', 1)) self.assertRaises( ValueError, transport.sendto, b'str', ('0.0.0.0', 2)) def test_sendto_closing(self): - transport = _SelectorDatagramTransport( - self.loop, self.sock, self.protocol, address=(1,)) + transport = self.datagram_transport(address=(1,)) transport.close() self.assertEqual(transport._conn_lost, 1) transport.sendto(b'data', (1,)) @@ -1568,8 +1668,7 @@ def test_sendto_ready(self): data = b'data' self.sock.sendto.return_value = len(data) - transport = _SelectorDatagramTransport( - self.loop, self.sock, self.protocol) + transport = self.datagram_transport() transport._buffer.append((data, ('0.0.0.0', 12345))) self.loop.add_writer(7, transport._sendto_ready) transport._sendto_ready() @@ -1582,8 +1681,7 @@ def test_sendto_ready_closing(self): data = b'data' self.sock.send.return_value = len(data) - transport = _SelectorDatagramTransport( - self.loop, self.sock, self.protocol) + transport = self.datagram_transport() transport._closing = True transport._buffer.append((data, ())) self.loop.add_writer(7, transport._sendto_ready) @@ -1594,8 +1692,7 @@ def test_sendto_ready_closing(self): self.protocol.connection_lost.assert_called_with(None) def test_sendto_ready_no_data(self): - transport = _SelectorDatagramTransport( - self.loop, self.sock, self.protocol) + transport = self.datagram_transport() self.loop.add_writer(7, transport._sendto_ready) transport._sendto_ready() self.assertFalse(self.sock.sendto.called) @@ -1604,8 +1701,7 @@ def test_sendto_ready_no_data(self): def test_sendto_ready_tryagain(self): self.sock.sendto.side_effect = BlockingIOError - transport = _SelectorDatagramTransport( - self.loop, self.sock, self.protocol) + transport = self.datagram_transport() transport._buffer.extend([(b'data1', ()), (b'data2', ())]) self.loop.add_writer(7, transport._sendto_ready) transport._sendto_ready() @@ -1618,20 +1714,20 @@ def test_sendto_ready_tryagain(self): def test_sendto_ready_exception(self): err = self.sock.sendto.side_effect = RuntimeError() - transport = _SelectorDatagramTransport( - self.loop, self.sock, self.protocol) - transport._fatal_error = unittest.mock.Mock() + transport = self.datagram_transport() + transport._fatal_error = mock.Mock() transport._buffer.append((b'data', ())) transport._sendto_ready() - transport._fatal_error.assert_called_with(err) + transport._fatal_error.assert_called_with( + err, + 'Fatal write error on datagram transport') def test_sendto_ready_error_received(self): self.sock.sendto.side_effect = ConnectionRefusedError - transport = _SelectorDatagramTransport( - self.loop, self.sock, self.protocol) - transport._fatal_error = unittest.mock.Mock() + transport = self.datagram_transport() + transport._fatal_error = mock.Mock() transport._buffer.append((b'data', ())) transport._sendto_ready() @@ -1640,23 +1736,24 @@ def test_sendto_ready_error_received(self): def test_sendto_ready_error_received_connection(self): self.sock.send.side_effect = ConnectionRefusedError - transport = _SelectorDatagramTransport( - self.loop, self.sock, self.protocol, ('0.0.0.0', 1)) - transport._fatal_error = unittest.mock.Mock() + transport = self.datagram_transport(address=('0.0.0.0', 1)) + transport._fatal_error = mock.Mock() transport._buffer.append((b'data', ())) transport._sendto_ready() self.assertFalse(transport._fatal_error.called) self.assertTrue(self.protocol.error_received.called) - @unittest.mock.patch('asyncio.log.logger.exception') + @mock.patch('asyncio.base_events.logger.error') def test_fatal_error_connected(self, m_exc): - transport = _SelectorDatagramTransport( - self.loop, self.sock, self.protocol, ('0.0.0.0', 1)) + transport = self.datagram_transport(address=('0.0.0.0', 1)) err = ConnectionRefusedError() transport._fatal_error(err) self.assertFalse(self.protocol.error_received.called) - m_exc.assert_called_with('Fatal error for %s', transport) + m_exc.assert_called_with( + test_utils.MockPattern( + 'Fatal error on transport\nprotocol:.*\ntransport:.*'), + exc_info=(ConnectionRefusedError, MOCK_ANY, MOCK_ANY)) if __name__ == '__main__': diff --git a/Lib/test/test_asyncio/test_sslproto.py b/Lib/test/test_asyncio/test_sslproto.py new file mode 100644 index 000000000000..a72967ea0714 --- /dev/null +++ b/Lib/test/test_asyncio/test_sslproto.py @@ -0,0 +1,71 @@ +"""Tests for asyncio/sslproto.py.""" + +import unittest +from unittest import mock +try: + import ssl +except ImportError: + ssl = None + +import asyncio +from asyncio import sslproto +from asyncio import test_utils + + +@unittest.skipIf(ssl is None, 'No ssl module') +class SslProtoHandshakeTests(test_utils.TestCase): + + def setUp(self): + self.loop = asyncio.new_event_loop() + self.set_event_loop(self.loop) + + def ssl_protocol(self, waiter=None): + sslcontext = test_utils.dummy_ssl_context() + app_proto = asyncio.Protocol() + proto = sslproto.SSLProtocol(self.loop, app_proto, sslcontext, waiter) + self.addCleanup(proto._app_transport.close) + return proto + + def connection_made(self, ssl_proto, do_handshake=None): + transport = mock.Mock() + sslpipe = mock.Mock() + sslpipe.shutdown.return_value = b'' + if do_handshake: + sslpipe.do_handshake.side_effect = do_handshake + else: + def mock_handshake(callback): + return [] + sslpipe.do_handshake.side_effect = mock_handshake + with mock.patch('asyncio.sslproto._SSLPipe', return_value=sslpipe): + ssl_proto.connection_made(transport) + + def test_cancel_handshake(self): + # Python issue #23197: cancelling an handshake must not raise an + # exception or log an error, even if the handshake failed + waiter = asyncio.Future(loop=self.loop) + ssl_proto = self.ssl_protocol(waiter) + handshake_fut = asyncio.Future(loop=self.loop) + + def do_handshake(callback): + exc = Exception() + callback(exc) + handshake_fut.set_result(None) + return [] + + waiter.cancel() + self.connection_made(ssl_proto, do_handshake) + + with test_utils.disable_logger(): + self.loop.run_until_complete(handshake_fut) + + def test_eof_received_waiter(self): + waiter = asyncio.Future(loop=self.loop) + ssl_proto = self.ssl_protocol(waiter) + self.connection_made(ssl_proto) + ssl_proto.eof_received() + test_utils.run_briefly(self.loop) + self.assertIsInstance(waiter.exception(), ConnectionResetError) + + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_asyncio/test_streams.py b/Lib/test/test_asyncio/test_streams.py index 5516c15873e6..2273049b8157 100644 --- a/Lib/test/test_asyncio/test_streams.py +++ b/Lib/test/test_asyncio/test_streams.py @@ -1,26 +1,27 @@ """Tests for streams.py.""" import gc +import os +import socket +import sys import unittest -import unittest.mock +from unittest import mock try: import ssl except ImportError: ssl = None -from asyncio import events -from asyncio import streams -from asyncio import tasks +import asyncio from asyncio import test_utils -class StreamReaderTests(unittest.TestCase): +class StreamReaderTests(test_utils.TestCase): DATA = b'line1\nline2\nline3\n' def setUp(self): - self.loop = events.new_event_loop() - events.set_event_loop(None) + self.loop = asyncio.new_event_loop() + self.set_event_loop(self.loop) def tearDown(self): # just in case if we have transport close callbacks @@ -28,80 +29,118 @@ def tearDown(self): self.loop.close() gc.collect() + super().tearDown() - @unittest.mock.patch('asyncio.streams.events') + @mock.patch('asyncio.streams.events') def test_ctor_global_loop(self, m_events): - stream = streams.StreamReader() + stream = asyncio.StreamReader() self.assertIs(stream._loop, m_events.get_event_loop.return_value) + def _basetest_open_connection(self, open_connection_fut): + reader, writer = self.loop.run_until_complete(open_connection_fut) + writer.write(b'GET / HTTP/1.0\r\n\r\n') + f = reader.readline() + data = self.loop.run_until_complete(f) + self.assertEqual(data, b'HTTP/1.0 200 OK\r\n') + f = reader.read() + data = self.loop.run_until_complete(f) + self.assertTrue(data.endswith(b'\r\n\r\nTest message')) + writer.close() + def test_open_connection(self): with test_utils.run_test_server() as httpd: - f = streams.open_connection(*httpd.address, loop=self.loop) - reader, writer = self.loop.run_until_complete(f) - writer.write(b'GET / HTTP/1.0\r\n\r\n') - f = reader.readline() - data = self.loop.run_until_complete(f) - self.assertEqual(data, b'HTTP/1.0 200 OK\r\n') - f = reader.read() - data = self.loop.run_until_complete(f) - self.assertTrue(data.endswith(b'\r\n\r\nTest message')) - - writer.close() + conn_fut = asyncio.open_connection(*httpd.address, + loop=self.loop) + self._basetest_open_connection(conn_fut) + + @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets') + def test_open_unix_connection(self): + with test_utils.run_test_unix_server() as httpd: + conn_fut = asyncio.open_unix_connection(httpd.address, + loop=self.loop) + self._basetest_open_connection(conn_fut) + + def _basetest_open_connection_no_loop_ssl(self, open_connection_fut): + try: + reader, writer = self.loop.run_until_complete(open_connection_fut) + finally: + asyncio.set_event_loop(None) + writer.write(b'GET / HTTP/1.0\r\n\r\n') + f = reader.read() + data = self.loop.run_until_complete(f) + self.assertTrue(data.endswith(b'\r\n\r\nTest message')) + + writer.close() @unittest.skipIf(ssl is None, 'No ssl module') def test_open_connection_no_loop_ssl(self): with test_utils.run_test_server(use_ssl=True) as httpd: - try: - events.set_event_loop(self.loop) - f = streams.open_connection(*httpd.address, - ssl=test_utils.dummy_ssl_context()) - reader, writer = self.loop.run_until_complete(f) - finally: - events.set_event_loop(None) - writer.write(b'GET / HTTP/1.0\r\n\r\n') - f = reader.read() - data = self.loop.run_until_complete(f) - self.assertTrue(data.endswith(b'\r\n\r\nTest message')) + conn_fut = asyncio.open_connection( + *httpd.address, + ssl=test_utils.dummy_ssl_context(), + loop=self.loop) - writer.close() + self._basetest_open_connection_no_loop_ssl(conn_fut) + + @unittest.skipIf(ssl is None, 'No ssl module') + @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets') + def test_open_unix_connection_no_loop_ssl(self): + with test_utils.run_test_unix_server(use_ssl=True) as httpd: + conn_fut = asyncio.open_unix_connection( + httpd.address, + ssl=test_utils.dummy_ssl_context(), + server_hostname='', + loop=self.loop) + + self._basetest_open_connection_no_loop_ssl(conn_fut) + + def _basetest_open_connection_error(self, open_connection_fut): + reader, writer = self.loop.run_until_complete(open_connection_fut) + writer._protocol.connection_lost(ZeroDivisionError()) + f = reader.read() + with self.assertRaises(ZeroDivisionError): + self.loop.run_until_complete(f) + writer.close() + test_utils.run_briefly(self.loop) def test_open_connection_error(self): with test_utils.run_test_server() as httpd: - f = streams.open_connection(*httpd.address, loop=self.loop) - reader, writer = self.loop.run_until_complete(f) - writer._protocol.connection_lost(ZeroDivisionError()) - f = reader.read() - with self.assertRaises(ZeroDivisionError): - self.loop.run_until_complete(f) + conn_fut = asyncio.open_connection(*httpd.address, + loop=self.loop) + self._basetest_open_connection_error(conn_fut) - writer.close() - test_utils.run_briefly(self.loop) + @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets') + def test_open_unix_connection_error(self): + with test_utils.run_test_unix_server() as httpd: + conn_fut = asyncio.open_unix_connection(httpd.address, + loop=self.loop) + self._basetest_open_connection_error(conn_fut) def test_feed_empty_data(self): - stream = streams.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop) stream.feed_data(b'') - self.assertEqual(0, stream._byte_count) + self.assertEqual(b'', stream._buffer) - def test_feed_data_byte_count(self): - stream = streams.StreamReader(loop=self.loop) + def test_feed_nonempty_data(self): + stream = asyncio.StreamReader(loop=self.loop) stream.feed_data(self.DATA) - self.assertEqual(len(self.DATA), stream._byte_count) + self.assertEqual(self.DATA, stream._buffer) def test_read_zero(self): # Read zero bytes. - stream = streams.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop) stream.feed_data(self.DATA) data = self.loop.run_until_complete(stream.read(0)) self.assertEqual(b'', data) - self.assertEqual(len(self.DATA), stream._byte_count) + self.assertEqual(self.DATA, stream._buffer) def test_read(self): # Read bytes. - stream = streams.StreamReader(loop=self.loop) - read_task = tasks.Task(stream.read(30), loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop) + read_task = asyncio.Task(stream.read(30), loop=self.loop) def cb(): stream.feed_data(self.DATA) @@ -109,23 +148,23 @@ def cb(): data = self.loop.run_until_complete(read_task) self.assertEqual(self.DATA, data) - self.assertFalse(stream._byte_count) + self.assertEqual(b'', stream._buffer) def test_read_line_breaks(self): # Read bytes without line breaks. - stream = streams.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop) stream.feed_data(b'line1') stream.feed_data(b'line2') data = self.loop.run_until_complete(stream.read(5)) self.assertEqual(b'line1', data) - self.assertEqual(5, stream._byte_count) + self.assertEqual(b'line2', stream._buffer) def test_read_eof(self): # Read bytes, stop at eof. - stream = streams.StreamReader(loop=self.loop) - read_task = tasks.Task(stream.read(1024), loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop) + read_task = asyncio.Task(stream.read(1024), loop=self.loop) def cb(): stream.feed_eof() @@ -133,12 +172,12 @@ def cb(): data = self.loop.run_until_complete(read_task) self.assertEqual(b'', data) - self.assertFalse(stream._byte_count) + self.assertEqual(b'', stream._buffer) def test_read_until_eof(self): # Read all bytes until eof. - stream = streams.StreamReader(loop=self.loop) - read_task = tasks.Task(stream.read(-1), loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop) + read_task = asyncio.Task(stream.read(-1), loop=self.loop) def cb(): stream.feed_data(b'chunk1\n') @@ -149,10 +188,10 @@ def cb(): data = self.loop.run_until_complete(read_task) self.assertEqual(b'chunk1\nchunk2', data) - self.assertFalse(stream._byte_count) + self.assertEqual(b'', stream._buffer) def test_read_exception(self): - stream = streams.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop) stream.feed_data(b'line\n') data = self.loop.run_until_complete(stream.read(2)) @@ -163,10 +202,11 @@ def test_read_exception(self): ValueError, self.loop.run_until_complete, stream.read(2)) def test_readline(self): - # Read one line. - stream = streams.StreamReader(loop=self.loop) + # Read one line. 'readline' will need to wait for the data + # to come from 'cb' + stream = asyncio.StreamReader(loop=self.loop) stream.feed_data(b'chunk1 ') - read_task = tasks.Task(stream.readline(), loop=self.loop) + read_task = asyncio.Task(stream.readline(), loop=self.loop) def cb(): stream.feed_data(b'chunk2 ') @@ -176,30 +216,55 @@ def cb(): line = self.loop.run_until_complete(read_task) self.assertEqual(b'chunk1 chunk2 chunk3 \n', line) - self.assertEqual(len(b'\n chunk4')-1, stream._byte_count) + self.assertEqual(b' chunk4', stream._buffer) def test_readline_limit_with_existing_data(self): - stream = streams.StreamReader(3, loop=self.loop) + # Read one line. The data is in StreamReader's buffer + # before the event loop is run. + + stream = asyncio.StreamReader(limit=3, loop=self.loop) stream.feed_data(b'li') stream.feed_data(b'ne1\nline2\n') self.assertRaises( ValueError, self.loop.run_until_complete, stream.readline()) - self.assertEqual([b'line2\n'], list(stream._buffer)) + # The buffer should contain the remaining data after exception + self.assertEqual(b'line2\n', stream._buffer) - stream = streams.StreamReader(3, loop=self.loop) + stream = asyncio.StreamReader(limit=3, loop=self.loop) stream.feed_data(b'li') stream.feed_data(b'ne1') stream.feed_data(b'li') self.assertRaises( ValueError, self.loop.run_until_complete, stream.readline()) - self.assertEqual([b'li'], list(stream._buffer)) - self.assertEqual(2, stream._byte_count) + # No b'\n' at the end. The 'limit' is set to 3. So before + # waiting for the new data in buffer, 'readline' will consume + # the entire buffer, and since the length of the consumed data + # is more than 3, it will raise a ValueError. The buffer is + # expected to be empty now. + self.assertEqual(b'', stream._buffer) + + def test_at_eof(self): + stream = asyncio.StreamReader(loop=self.loop) + self.assertFalse(stream.at_eof()) + + stream.feed_data(b'some data\n') + self.assertFalse(stream.at_eof()) + + self.loop.run_until_complete(stream.readline()) + self.assertFalse(stream.at_eof()) + + stream.feed_data(b'some data\n') + stream.feed_eof() + self.loop.run_until_complete(stream.readline()) + self.assertTrue(stream.at_eof()) def test_readline_limit(self): - stream = streams.StreamReader(7, loop=self.loop) + # Read one line. StreamReaders are fed with data after + # their 'readline' methods are called. + stream = asyncio.StreamReader(limit=7, loop=self.loop) def cb(): stream.feed_data(b'chunk1') stream.feed_data(b'chunk2') @@ -209,21 +274,36 @@ def cb(): self.assertRaises( ValueError, self.loop.run_until_complete, stream.readline()) - self.assertEqual([b'chunk3\n'], list(stream._buffer)) - self.assertEqual(7, stream._byte_count) + # The buffer had just one line of data, and after raising + # a ValueError it should be empty. + self.assertEqual(b'', stream._buffer) - def test_readline_line_byte_count(self): - stream = streams.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(limit=7, loop=self.loop) + def cb(): + stream.feed_data(b'chunk1') + stream.feed_data(b'chunk2\n') + stream.feed_data(b'chunk3\n') + stream.feed_eof() + self.loop.call_soon(cb) + + self.assertRaises( + ValueError, self.loop.run_until_complete, stream.readline()) + self.assertEqual(b'chunk3\n', stream._buffer) + + def test_readline_nolimit_nowait(self): + # All needed data for the first 'readline' call will be + # in the buffer. + stream = asyncio.StreamReader(loop=self.loop) stream.feed_data(self.DATA[:6]) stream.feed_data(self.DATA[6:]) line = self.loop.run_until_complete(stream.readline()) self.assertEqual(b'line1\n', line) - self.assertEqual(len(self.DATA) - len(b'line1\n'), stream._byte_count) + self.assertEqual(b'line2\nline3\n', stream._buffer) def test_readline_eof(self): - stream = streams.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop) stream.feed_data(b'some data') stream.feed_eof() @@ -231,14 +311,14 @@ def test_readline_eof(self): self.assertEqual(b'some data', line) def test_readline_empty_eof(self): - stream = streams.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop) stream.feed_eof() line = self.loop.run_until_complete(stream.readline()) self.assertEqual(b'', line) def test_readline_read_byte_count(self): - stream = streams.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop) stream.feed_data(self.DATA) self.loop.run_until_complete(stream.readline()) @@ -246,12 +326,10 @@ def test_readline_read_byte_count(self): data = self.loop.run_until_complete(stream.read(7)) self.assertEqual(b'line2\nl', data) - self.assertEqual( - len(self.DATA) - len(b'line1\n') - len(b'line2\nl'), - stream._byte_count) + self.assertEqual(b'ine3\n', stream._buffer) def test_readline_exception(self): - stream = streams.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop) stream.feed_data(b'line\n') data = self.loop.run_until_complete(stream.readline()) @@ -260,26 +338,27 @@ def test_readline_exception(self): stream.set_exception(ValueError()) self.assertRaises( ValueError, self.loop.run_until_complete, stream.readline()) + self.assertEqual(b'', stream._buffer) def test_readexactly_zero_or_less(self): # Read exact number of bytes (zero or less). - stream = streams.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop) stream.feed_data(self.DATA) data = self.loop.run_until_complete(stream.readexactly(0)) self.assertEqual(b'', data) - self.assertEqual(len(self.DATA), stream._byte_count) + self.assertEqual(self.DATA, stream._buffer) data = self.loop.run_until_complete(stream.readexactly(-1)) self.assertEqual(b'', data) - self.assertEqual(len(self.DATA), stream._byte_count) + self.assertEqual(self.DATA, stream._buffer) def test_readexactly(self): # Read exact number of bytes. - stream = streams.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop) n = 2 * len(self.DATA) - read_task = tasks.Task(stream.readexactly(n), loop=self.loop) + read_task = asyncio.Task(stream.readexactly(n), loop=self.loop) def cb(): stream.feed_data(self.DATA) @@ -289,25 +368,29 @@ def cb(): data = self.loop.run_until_complete(read_task) self.assertEqual(self.DATA + self.DATA, data) - self.assertEqual(len(self.DATA), stream._byte_count) + self.assertEqual(self.DATA, stream._buffer) def test_readexactly_eof(self): # Read exact number of bytes (eof). - stream = streams.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop) n = 2 * len(self.DATA) - read_task = tasks.Task(stream.readexactly(n), loop=self.loop) + read_task = asyncio.Task(stream.readexactly(n), loop=self.loop) def cb(): stream.feed_data(self.DATA) stream.feed_eof() self.loop.call_soon(cb) - data = self.loop.run_until_complete(read_task) - self.assertEqual(self.DATA, data) - self.assertFalse(stream._byte_count) + with self.assertRaises(asyncio.IncompleteReadError) as cm: + self.loop.run_until_complete(read_task) + self.assertEqual(cm.exception.partial, self.DATA) + self.assertEqual(cm.exception.expected, n) + self.assertEqual(str(cm.exception), + '18 bytes read on a total of 36 expected bytes') + self.assertEqual(b'', stream._buffer) def test_readexactly_exception(self): - stream = streams.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop) stream.feed_data(b'line\n') data = self.loop.run_until_complete(stream.readexactly(2)) @@ -318,7 +401,7 @@ def test_readexactly_exception(self): ValueError, self.loop.run_until_complete, stream.readexactly(2)) def test_exception(self): - stream = streams.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop) self.assertIsNone(stream.exception()) exc = ValueError() @@ -326,31 +409,23 @@ def test_exception(self): self.assertIs(stream.exception(), exc) def test_exception_waiter(self): - stream = streams.StreamReader(loop=self.loop) + stream = asyncio.StreamReader(loop=self.loop) - @tasks.coroutine + @asyncio.coroutine def set_err(): stream.set_exception(ValueError()) - @tasks.coroutine - def readline(): - yield from stream.readline() + t1 = asyncio.Task(stream.readline(), loop=self.loop) + t2 = asyncio.Task(set_err(), loop=self.loop) - t1 = tasks.Task(stream.readline(), loop=self.loop) - t2 = tasks.Task(set_err(), loop=self.loop) - - self.loop.run_until_complete(tasks.wait([t1, t2], loop=self.loop)) + self.loop.run_until_complete(asyncio.wait([t1, t2], loop=self.loop)) self.assertRaises(ValueError, t1.result) def test_exception_cancel(self): - stream = streams.StreamReader(loop=self.loop) - - @tasks.coroutine - def read_a_line(): - yield from stream.readline() + stream = asyncio.StreamReader(loop=self.loop) - t = tasks.Task(read_a_line(), loop=self.loop) + t = asyncio.Task(stream.readline(), loop=self.loop) test_utils.run_briefly(self.loop) t.cancel() test_utils.run_briefly(self.loop) @@ -367,19 +442,22 @@ def __init__(self, loop): self.server = None self.loop = loop - @tasks.coroutine + @asyncio.coroutine def handle_client(self, client_reader, client_writer): data = yield from client_reader.readline() client_writer.write(data) def start(self): + sock = socket.socket() + sock.bind(('127.0.0.1', 0)) self.server = self.loop.run_until_complete( - streams.start_server(self.handle_client, - '127.0.0.1', 12345, + asyncio.start_server(self.handle_client, + sock=sock, loop=self.loop)) + return sock.getsockname() def handle_client_callback(self, client_reader, client_writer): - task = tasks.Task(client_reader.readline(), loop=self.loop) + task = asyncio.Task(client_reader.readline(), loop=self.loop) def done(task): client_writer.write(task.result()) @@ -387,10 +465,15 @@ def done(task): task.add_done_callback(done) def start_callback(self): + sock = socket.socket() + sock.bind(('127.0.0.1', 0)) + addr = sock.getsockname() + sock.close() self.server = self.loop.run_until_complete( - streams.start_server(self.handle_client_callback, - '127.0.0.1', 12345, + asyncio.start_server(self.handle_client_callback, + host=addr[0], port=addr[1], loop=self.loop)) + return addr def stop(self): if self.server is not None: @@ -398,10 +481,10 @@ def stop(self): self.loop.run_until_complete(self.server.wait_closed()) self.server = None - @tasks.coroutine - def client(): - reader, writer = yield from streams.open_connection( - '127.0.0.1', 12345, loop=self.loop) + @asyncio.coroutine + def client(addr): + reader, writer = yield from asyncio.open_connection( + *addr, loop=self.loop) # send a line writer.write(b"hello world!\n") # read it back @@ -411,20 +494,148 @@ def client(): # test the server variant with a coroutine as client handler server = MyServer(self.loop) - server.start() - msg = self.loop.run_until_complete(tasks.Task(client(), - loop=self.loop)) + addr = server.start() + msg = self.loop.run_until_complete(asyncio.Task(client(addr), + loop=self.loop)) server.stop() self.assertEqual(msg, b"hello world!\n") # test the server variant with a callback as client handler server = MyServer(self.loop) - server.start_callback() - msg = self.loop.run_until_complete(tasks.Task(client(), - loop=self.loop)) + addr = server.start_callback() + msg = self.loop.run_until_complete(asyncio.Task(client(addr), + loop=self.loop)) server.stop() self.assertEqual(msg, b"hello world!\n") + @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets') + def test_start_unix_server(self): + + class MyServer: + + def __init__(self, loop, path): + self.server = None + self.loop = loop + self.path = path + + @asyncio.coroutine + def handle_client(self, client_reader, client_writer): + data = yield from client_reader.readline() + client_writer.write(data) + + def start(self): + self.server = self.loop.run_until_complete( + asyncio.start_unix_server(self.handle_client, + path=self.path, + loop=self.loop)) + + def handle_client_callback(self, client_reader, client_writer): + task = asyncio.Task(client_reader.readline(), loop=self.loop) + + def done(task): + client_writer.write(task.result()) + + task.add_done_callback(done) + + def start_callback(self): + self.server = self.loop.run_until_complete( + asyncio.start_unix_server(self.handle_client_callback, + path=self.path, + loop=self.loop)) + + def stop(self): + if self.server is not None: + self.server.close() + self.loop.run_until_complete(self.server.wait_closed()) + self.server = None + + @asyncio.coroutine + def client(path): + reader, writer = yield from asyncio.open_unix_connection( + path, loop=self.loop) + # send a line + writer.write(b"hello world!\n") + # read it back + msgback = yield from reader.readline() + writer.close() + return msgback + + # test the server variant with a coroutine as client handler + with test_utils.unix_socket_path() as path: + server = MyServer(self.loop, path) + server.start() + msg = self.loop.run_until_complete(asyncio.Task(client(path), + loop=self.loop)) + server.stop() + self.assertEqual(msg, b"hello world!\n") + + # test the server variant with a callback as client handler + with test_utils.unix_socket_path() as path: + server = MyServer(self.loop, path) + server.start_callback() + msg = self.loop.run_until_complete(asyncio.Task(client(path), + loop=self.loop)) + server.stop() + self.assertEqual(msg, b"hello world!\n") + + @unittest.skipIf(sys.platform == 'win32', "Don't have pipes") + def test_read_all_from_pipe_reader(self): + # See Tulip issue 168. This test is derived from the example + # subprocess_attach_read_pipe.py, but we configure the + # StreamReader's limit so that twice it is less than the size + # of the data writter. Also we must explicitly attach a child + # watcher to the event loop. + + code = """\ +import os, sys +fd = int(sys.argv[1]) +os.write(fd, b'data') +os.close(fd) +""" + rfd, wfd = os.pipe() + args = [sys.executable, '-c', code, str(wfd)] + + pipe = open(rfd, 'rb', 0) + reader = asyncio.StreamReader(loop=self.loop, limit=1) + protocol = asyncio.StreamReaderProtocol(reader, loop=self.loop) + transport, _ = self.loop.run_until_complete( + self.loop.connect_read_pipe(lambda: protocol, pipe)) + + watcher = asyncio.SafeChildWatcher() + watcher.attach_loop(self.loop) + try: + asyncio.set_child_watcher(watcher) + create = asyncio.create_subprocess_exec(*args, + pass_fds={wfd}, + loop=self.loop) + proc = self.loop.run_until_complete(create) + self.loop.run_until_complete(proc.wait()) + finally: + asyncio.set_child_watcher(None) + + os.close(wfd) + data = self.loop.run_until_complete(reader.read(-1)) + self.assertEqual(data, b'data') + + def test_streamreader_constructor(self): + self.addCleanup(asyncio.set_event_loop, None) + asyncio.set_event_loop(self.loop) + + # Tulip issue #184: Ensure that StreamReaderProtocol constructor + # retrieves the current loop if the loop parameter is not set + reader = asyncio.StreamReader() + self.assertIs(reader._loop, self.loop) + + def test_streamreaderprotocol_constructor(self): + self.addCleanup(asyncio.set_event_loop, None) + asyncio.set_event_loop(self.loop) + + # Tulip issue #184: Ensure that StreamReaderProtocol constructor + # retrieves the current loop if the loop parameter is not set + reader = mock.Mock() + protocol = asyncio.StreamReaderProtocol(reader) + self.assertIs(protocol._loop, self.loop) + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_asyncio/test_subprocess.py b/Lib/test/test_asyncio/test_subprocess.py new file mode 100644 index 000000000000..5ccdafb151f6 --- /dev/null +++ b/Lib/test/test_asyncio/test_subprocess.py @@ -0,0 +1,453 @@ +import signal +import sys +import unittest +from unittest import mock + +import asyncio +from asyncio import base_subprocess +from asyncio import subprocess +from asyncio import test_utils +try: + from test import support +except ImportError: + from asyncio import test_support as support +if sys.platform != 'win32': + from asyncio import unix_events + +# Program blocking +PROGRAM_BLOCKED = [sys.executable, '-c', 'import time; time.sleep(3600)'] + +# Program copying input to output +PROGRAM_CAT = [ + sys.executable, '-c', + ';'.join(('import sys', + 'data = sys.stdin.buffer.read()', + 'sys.stdout.buffer.write(data)'))] + +class TestSubprocessTransport(base_subprocess.BaseSubprocessTransport): + def _start(self, *args, **kwargs): + self._proc = mock.Mock() + self._proc.stdin = None + self._proc.stdout = None + self._proc.stderr = None + + +class SubprocessTransportTests(test_utils.TestCase): + def setUp(self): + self.loop = self.new_test_loop() + self.set_event_loop(self.loop) + + + def create_transport(self, waiter=None): + protocol = mock.Mock() + protocol.connection_made._is_coroutine = False + protocol.process_exited._is_coroutine = False + transport = TestSubprocessTransport( + self.loop, protocol, ['test'], False, + None, None, None, 0, waiter=waiter) + return (transport, protocol) + + def test_proc_exited(self): + waiter = asyncio.Future(loop=self.loop) + transport, protocol = self.create_transport(waiter) + transport._process_exited(6) + self.loop.run_until_complete(waiter) + + self.assertEqual(transport.get_returncode(), 6) + + self.assertTrue(protocol.connection_made.called) + self.assertTrue(protocol.process_exited.called) + self.assertTrue(protocol.connection_lost.called) + self.assertEqual(protocol.connection_lost.call_args[0], (None,)) + + self.assertFalse(transport._closed) + self.assertIsNone(transport._loop) + self.assertIsNone(transport._proc) + self.assertIsNone(transport._protocol) + + # methods must raise ProcessLookupError if the process exited + self.assertRaises(ProcessLookupError, + transport.send_signal, signal.SIGTERM) + self.assertRaises(ProcessLookupError, transport.terminate) + self.assertRaises(ProcessLookupError, transport.kill) + + transport.close() + + +class SubprocessMixin: + + def test_stdin_stdout(self): + args = PROGRAM_CAT + + @asyncio.coroutine + def run(data): + proc = yield from asyncio.create_subprocess_exec( + *args, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + loop=self.loop) + + # feed data + proc.stdin.write(data) + yield from proc.stdin.drain() + proc.stdin.close() + + # get output and exitcode + data = yield from proc.stdout.read() + exitcode = yield from proc.wait() + return (exitcode, data) + + task = run(b'some data') + task = asyncio.wait_for(task, 60.0, loop=self.loop) + exitcode, stdout = self.loop.run_until_complete(task) + self.assertEqual(exitcode, 0) + self.assertEqual(stdout, b'some data') + + def test_communicate(self): + args = PROGRAM_CAT + + @asyncio.coroutine + def run(data): + proc = yield from asyncio.create_subprocess_exec( + *args, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + loop=self.loop) + stdout, stderr = yield from proc.communicate(data) + return proc.returncode, stdout + + task = run(b'some data') + task = asyncio.wait_for(task, 60.0, loop=self.loop) + exitcode, stdout = self.loop.run_until_complete(task) + self.assertEqual(exitcode, 0) + self.assertEqual(stdout, b'some data') + + def test_shell(self): + create = asyncio.create_subprocess_shell('exit 7', + loop=self.loop) + proc = self.loop.run_until_complete(create) + exitcode = self.loop.run_until_complete(proc.wait()) + self.assertEqual(exitcode, 7) + + def test_start_new_session(self): + # start the new process in a new session + create = asyncio.create_subprocess_shell('exit 8', + start_new_session=True, + loop=self.loop) + proc = self.loop.run_until_complete(create) + exitcode = self.loop.run_until_complete(proc.wait()) + self.assertEqual(exitcode, 8) + + def test_kill(self): + args = PROGRAM_BLOCKED + create = asyncio.create_subprocess_exec(*args, loop=self.loop) + proc = self.loop.run_until_complete(create) + proc.kill() + returncode = self.loop.run_until_complete(proc.wait()) + if sys.platform == 'win32': + self.assertIsInstance(returncode, int) + # expect 1 but sometimes get 0 + else: + self.assertEqual(-signal.SIGKILL, returncode) + + def test_terminate(self): + args = PROGRAM_BLOCKED + create = asyncio.create_subprocess_exec(*args, loop=self.loop) + proc = self.loop.run_until_complete(create) + proc.terminate() + returncode = self.loop.run_until_complete(proc.wait()) + if sys.platform == 'win32': + self.assertIsInstance(returncode, int) + # expect 1 but sometimes get 0 + else: + self.assertEqual(-signal.SIGTERM, returncode) + + @unittest.skipIf(sys.platform == 'win32', "Don't have SIGHUP") + def test_send_signal(self): + code = 'import time; print("sleeping", flush=True); time.sleep(3600)' + args = [sys.executable, '-c', code] + create = asyncio.create_subprocess_exec(*args, + stdout=subprocess.PIPE, + loop=self.loop) + proc = self.loop.run_until_complete(create) + + @asyncio.coroutine + def send_signal(proc): + # basic synchronization to wait until the program is sleeping + line = yield from proc.stdout.readline() + self.assertEqual(line, b'sleeping\n') + + proc.send_signal(signal.SIGHUP) + returncode = (yield from proc.wait()) + return returncode + + returncode = self.loop.run_until_complete(send_signal(proc)) + self.assertEqual(-signal.SIGHUP, returncode) + + def prepare_broken_pipe_test(self): + # buffer large enough to feed the whole pipe buffer + large_data = b'x' * support.PIPE_MAX_SIZE + + # the program ends before the stdin can be feeded + create = asyncio.create_subprocess_exec( + sys.executable, '-c', 'pass', + stdin=subprocess.PIPE, + loop=self.loop) + proc = self.loop.run_until_complete(create) + return (proc, large_data) + + def test_stdin_broken_pipe(self): + proc, large_data = self.prepare_broken_pipe_test() + + @asyncio.coroutine + def write_stdin(proc, data): + proc.stdin.write(data) + yield from proc.stdin.drain() + + coro = write_stdin(proc, large_data) + # drain() must raise BrokenPipeError or ConnectionResetError + with test_utils.disable_logger(): + self.assertRaises((BrokenPipeError, ConnectionResetError), + self.loop.run_until_complete, coro) + self.loop.run_until_complete(proc.wait()) + + def test_communicate_ignore_broken_pipe(self): + proc, large_data = self.prepare_broken_pipe_test() + + # communicate() must ignore BrokenPipeError when feeding stdin + with test_utils.disable_logger(): + self.loop.run_until_complete(proc.communicate(large_data)) + self.loop.run_until_complete(proc.wait()) + + def test_pause_reading(self): + limit = 10 + size = (limit * 2 + 1) + + @asyncio.coroutine + def test_pause_reading(): + code = '\n'.join(( + 'import sys', + 'sys.stdout.write("x" * %s)' % size, + 'sys.stdout.flush()', + )) + + connect_read_pipe = self.loop.connect_read_pipe + + @asyncio.coroutine + def connect_read_pipe_mock(*args, **kw): + transport, protocol = yield from connect_read_pipe(*args, **kw) + transport.pause_reading = mock.Mock() + transport.resume_reading = mock.Mock() + return (transport, protocol) + + self.loop.connect_read_pipe = connect_read_pipe_mock + + proc = yield from asyncio.create_subprocess_exec( + sys.executable, '-c', code, + stdin=asyncio.subprocess.PIPE, + stdout=asyncio.subprocess.PIPE, + limit=limit, + loop=self.loop) + stdout_transport = proc._transport.get_pipe_transport(1) + + stdout, stderr = yield from proc.communicate() + + # The child process produced more than limit bytes of output, + # the stream reader transport should pause the protocol to not + # allocate too much memory. + return (stdout, stdout_transport) + + # Issue #22685: Ensure that the stream reader pauses the protocol + # when the child process produces too much data + stdout, transport = self.loop.run_until_complete(test_pause_reading()) + + self.assertEqual(stdout, b'x' * size) + self.assertTrue(transport.pause_reading.called) + self.assertTrue(transport.resume_reading.called) + + def test_stdin_not_inheritable(self): + # Tulip issue #209: stdin must not be inheritable, otherwise + # the Process.communicate() hangs + @asyncio.coroutine + def len_message(message): + code = 'import sys; data = sys.stdin.read(); print(len(data))' + proc = yield from asyncio.create_subprocess_exec( + sys.executable, '-c', code, + stdin=asyncio.subprocess.PIPE, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, + close_fds=False, + loop=self.loop) + stdout, stderr = yield from proc.communicate(message) + exitcode = yield from proc.wait() + return (stdout, exitcode) + + output, exitcode = self.loop.run_until_complete(len_message(b'abc')) + self.assertEqual(output.rstrip(), b'3') + self.assertEqual(exitcode, 0) + + def test_cancel_process_wait(self): + # Issue #23140: cancel Process.wait() + + @asyncio.coroutine + def cancel_wait(): + proc = yield from asyncio.create_subprocess_exec( + *PROGRAM_BLOCKED, + loop=self.loop) + + # Create an internal future waiting on the process exit + task = self.loop.create_task(proc.wait()) + self.loop.call_soon(task.cancel) + try: + yield from task + except asyncio.CancelledError: + pass + + # Cancel the future + task.cancel() + + # Kill the process and wait until it is done + proc.kill() + yield from proc.wait() + + self.loop.run_until_complete(cancel_wait()) + + def test_cancel_make_subprocess_transport_exec(self): + @asyncio.coroutine + def cancel_make_transport(): + coro = asyncio.create_subprocess_exec(*PROGRAM_BLOCKED, + loop=self.loop) + task = self.loop.create_task(coro) + + self.loop.call_soon(task.cancel) + try: + yield from task + except asyncio.CancelledError: + pass + + # ignore the log: + # "Exception during subprocess creation, kill the subprocess" + with test_utils.disable_logger(): + self.loop.run_until_complete(cancel_make_transport()) + + def test_cancel_post_init(self): + @asyncio.coroutine + def cancel_make_transport(): + coro = self.loop.subprocess_exec(asyncio.SubprocessProtocol, + *PROGRAM_BLOCKED) + task = self.loop.create_task(coro) + + self.loop.call_soon(task.cancel) + try: + yield from task + except asyncio.CancelledError: + pass + + # ignore the log: + # "Exception during subprocess creation, kill the subprocess" + with test_utils.disable_logger(): + self.loop.run_until_complete(cancel_make_transport()) + test_utils.run_briefly(self.loop) + + def test_close_kill_running(self): + @asyncio.coroutine + def kill_running(): + create = self.loop.subprocess_exec(asyncio.SubprocessProtocol, + *PROGRAM_BLOCKED) + transport, protocol = yield from create + + kill_called = False + def kill(): + nonlocal kill_called + kill_called = True + orig_kill() + + proc = transport.get_extra_info('subprocess') + orig_kill = proc.kill + proc.kill = kill + returncode = transport.get_returncode() + transport.close() + yield from transport._wait() + return (returncode, kill_called) + + # Ignore "Close running child process: kill ..." log + with test_utils.disable_logger(): + returncode, killed = self.loop.run_until_complete(kill_running()) + self.assertIsNone(returncode) + + # transport.close() must kill the process if it is still running + self.assertTrue(killed) + test_utils.run_briefly(self.loop) + + def test_close_dont_kill_finished(self): + @asyncio.coroutine + def kill_running(): + create = self.loop.subprocess_exec(asyncio.SubprocessProtocol, + *PROGRAM_BLOCKED) + transport, protocol = yield from create + proc = transport.get_extra_info('subprocess') + + # kill the process (but asyncio is not notified immediatly) + proc.kill() + proc.wait() + + proc.kill = mock.Mock() + proc_returncode = proc.poll() + transport_returncode = transport.get_returncode() + transport.close() + return (proc_returncode, transport_returncode, proc.kill.called) + + # Ignore "Unknown child process pid ..." log of SafeChildWatcher, + # emitted because the test already consumes the exit status: + # proc.wait() + with test_utils.disable_logger(): + result = self.loop.run_until_complete(kill_running()) + test_utils.run_briefly(self.loop) + + proc_returncode, transport_return_code, killed = result + + self.assertIsNotNone(proc_returncode) + self.assertIsNone(transport_return_code) + + # transport.close() must not kill the process if it finished, even if + # the transport was not notified yet + self.assertFalse(killed) + + +if sys.platform != 'win32': + # Unix + class SubprocessWatcherMixin(SubprocessMixin): + + Watcher = None + + def setUp(self): + policy = asyncio.get_event_loop_policy() + self.loop = policy.new_event_loop() + self.set_event_loop(self.loop) + + watcher = self.Watcher() + watcher.attach_loop(self.loop) + policy.set_child_watcher(watcher) + self.addCleanup(policy.set_child_watcher, None) + + class SubprocessSafeWatcherTests(SubprocessWatcherMixin, + test_utils.TestCase): + + Watcher = unix_events.SafeChildWatcher + + class SubprocessFastWatcherTests(SubprocessWatcherMixin, + test_utils.TestCase): + + Watcher = unix_events.FastChildWatcher + +else: + # Windows + class SubprocessProactorTests(SubprocessMixin, test_utils.TestCase): + + def setUp(self): + self.loop = asyncio.ProactorEventLoop() + self.set_event_loop(self.loop) + + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py index 8f0d081554bb..06447d778b58 100644 --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -1,158 +1,296 @@ """Tests for tasks.py.""" -import gc +import os +import re +import sys +import types import unittest -import unittest.mock -from unittest.mock import Mock +import weakref +from unittest import mock -from asyncio import events -from asyncio import futures -from asyncio import tasks +import asyncio +from asyncio import coroutines from asyncio import test_utils +try: + from test import support + from test.script_helper import assert_python_ok +except ImportError: + from asyncio import test_support as support + from asyncio.test_support import assert_python_ok + + +PY34 = (sys.version_info >= (3, 4)) +PY35 = (sys.version_info >= (3, 5)) + + +@asyncio.coroutine +def coroutine_function(): + pass + + +def format_coroutine(qualname, state, src, source_traceback, generator=False): + if generator: + state = '%s' % state + else: + state = '%s, defined' % state + if source_traceback is not None: + frame = source_traceback[-1] + return ('coro=<%s() %s at %s> created at %s:%s' + % (qualname, state, src, frame[0], frame[1])) + else: + return 'coro=<%s() %s at %s>' % (qualname, state, src) class Dummy: def __repr__(self): - return 'Dummy()' + return '<Dummy>' def __call__(self, *args): pass -class TaskTests(unittest.TestCase): +class TaskTests(test_utils.TestCase): def setUp(self): - self.loop = test_utils.TestLoop() - events.set_event_loop(None) - - def tearDown(self): - self.loop.close() - gc.collect() + self.loop = self.new_test_loop() def test_task_class(self): - @tasks.coroutine + @asyncio.coroutine def notmuch(): return 'ok' - t = tasks.Task(notmuch(), loop=self.loop) + t = asyncio.Task(notmuch(), loop=self.loop) self.loop.run_until_complete(t) self.assertTrue(t.done()) self.assertEqual(t.result(), 'ok') self.assertIs(t._loop, self.loop) - loop = events.new_event_loop() - t = tasks.Task(notmuch(), loop=loop) + loop = asyncio.new_event_loop() + self.set_event_loop(loop) + t = asyncio.Task(notmuch(), loop=loop) self.assertIs(t._loop, loop) + loop.run_until_complete(t) loop.close() def test_async_coroutine(self): - @tasks.coroutine + @asyncio.coroutine def notmuch(): return 'ok' - t = tasks.async(notmuch(), loop=self.loop) + t = asyncio.async(notmuch(), loop=self.loop) self.loop.run_until_complete(t) self.assertTrue(t.done()) self.assertEqual(t.result(), 'ok') self.assertIs(t._loop, self.loop) - loop = events.new_event_loop() - t = tasks.async(notmuch(), loop=loop) + loop = asyncio.new_event_loop() + self.set_event_loop(loop) + t = asyncio.async(notmuch(), loop=loop) self.assertIs(t._loop, loop) + loop.run_until_complete(t) loop.close() def test_async_future(self): - f_orig = futures.Future(loop=self.loop) + f_orig = asyncio.Future(loop=self.loop) f_orig.set_result('ko') - f = tasks.async(f_orig) + f = asyncio.async(f_orig) self.loop.run_until_complete(f) self.assertTrue(f.done()) self.assertEqual(f.result(), 'ko') self.assertIs(f, f_orig) - loop = events.new_event_loop() + loop = asyncio.new_event_loop() + self.set_event_loop(loop) with self.assertRaises(ValueError): - f = tasks.async(f_orig, loop=loop) + f = asyncio.async(f_orig, loop=loop) loop.close() - f = tasks.async(f_orig, loop=self.loop) + f = asyncio.async(f_orig, loop=self.loop) self.assertIs(f, f_orig) def test_async_task(self): - @tasks.coroutine + @asyncio.coroutine def notmuch(): return 'ok' - t_orig = tasks.Task(notmuch(), loop=self.loop) - t = tasks.async(t_orig) + t_orig = asyncio.Task(notmuch(), loop=self.loop) + t = asyncio.async(t_orig) self.loop.run_until_complete(t) self.assertTrue(t.done()) self.assertEqual(t.result(), 'ok') self.assertIs(t, t_orig) - loop = events.new_event_loop() + loop = asyncio.new_event_loop() + self.set_event_loop(loop) with self.assertRaises(ValueError): - t = tasks.async(t_orig, loop=loop) + t = asyncio.async(t_orig, loop=loop) loop.close() - t = tasks.async(t_orig, loop=self.loop) + t = asyncio.async(t_orig, loop=self.loop) self.assertIs(t, t_orig) def test_async_neither(self): with self.assertRaises(TypeError): - tasks.async('ok') + asyncio.async('ok') def test_task_repr(self): - @tasks.coroutine + self.loop.set_debug(False) + + @asyncio.coroutine def notmuch(): yield from [] return 'abc' - t = tasks.Task(notmuch(), loop=self.loop) + # test coroutine function + self.assertEqual(notmuch.__name__, 'notmuch') + if PY35: + self.assertEqual(notmuch.__qualname__, + 'TaskTests.test_task_repr.<locals>.notmuch') + self.assertEqual(notmuch.__module__, __name__) + + filename, lineno = test_utils.get_function_source(notmuch) + src = "%s:%s" % (filename, lineno) + + # test coroutine object + gen = notmuch() + if coroutines._DEBUG or PY35: + coro_qualname = 'TaskTests.test_task_repr.<locals>.notmuch' + else: + coro_qualname = 'notmuch' + self.assertEqual(gen.__name__, 'notmuch') + if PY35: + self.assertEqual(gen.__qualname__, + coro_qualname) + + # test pending Task + t = asyncio.Task(gen, loop=self.loop) t.add_done_callback(Dummy()) - self.assertEqual(repr(t), 'Task(<notmuch>)<PENDING, [Dummy()]>') + + coro = format_coroutine(coro_qualname, 'running', src, + t._source_traceback, generator=True) + self.assertEqual(repr(t), + '<Task pending %s cb=[<Dummy>()]>' % coro) + + # test cancelling Task t.cancel() # Does not take immediate effect! - self.assertEqual(repr(t), 'Task(<notmuch>)<CANCELLING, [Dummy()]>') - self.assertRaises(futures.CancelledError, + self.assertEqual(repr(t), + '<Task cancelling %s cb=[<Dummy>()]>' % coro) + + # test cancelled Task + self.assertRaises(asyncio.CancelledError, self.loop.run_until_complete, t) - self.assertEqual(repr(t), 'Task(<notmuch>)<CANCELLED>') - t = tasks.Task(notmuch(), loop=self.loop) + coro = format_coroutine(coro_qualname, 'done', src, + t._source_traceback) + self.assertEqual(repr(t), + '<Task cancelled %s>' % coro) + + # test finished Task + t = asyncio.Task(notmuch(), loop=self.loop) self.loop.run_until_complete(t) - self.assertEqual(repr(t), "Task(<notmuch>)<result='abc'>") + coro = format_coroutine(coro_qualname, 'done', src, + t._source_traceback) + self.assertEqual(repr(t), + "<Task finished %s result='abc'>" % coro) - def test_task_repr_custom(self): - @tasks.coroutine - def coro(): - pass + def test_task_repr_coro_decorator(self): + self.loop.set_debug(False) - class T(futures.Future): - def __repr__(self): - return 'T[]' + @asyncio.coroutine + def notmuch(): + # notmuch() function doesn't use yield from: it will be wrapped by + # @coroutine decorator + return 123 + + # test coroutine function + self.assertEqual(notmuch.__name__, 'notmuch') + if PY35: + self.assertEqual(notmuch.__qualname__, + 'TaskTests.test_task_repr_coro_decorator' + '.<locals>.notmuch') + self.assertEqual(notmuch.__module__, __name__) + + # test coroutine object + gen = notmuch() + if coroutines._DEBUG or PY35: + # On Python >= 3.5, generators now inherit the name of the + # function, as expected, and have a qualified name (__qualname__ + # attribute). + coro_name = 'notmuch' + coro_qualname = ('TaskTests.test_task_repr_coro_decorator' + '.<locals>.notmuch') + else: + # On Python < 3.5, generators inherit the name of the code, not of + # the function. See: http://bugs.python.org/issue21205 + coro_name = coro_qualname = 'coro' + self.assertEqual(gen.__name__, coro_name) + if PY35: + self.assertEqual(gen.__qualname__, coro_qualname) + + # test repr(CoroWrapper) + if coroutines._DEBUG: + # format the coroutine object + if coroutines._DEBUG: + filename, lineno = test_utils.get_function_source(notmuch) + frame = gen._source_traceback[-1] + coro = ('%s() running, defined at %s:%s, created at %s:%s' + % (coro_qualname, filename, lineno, + frame[0], frame[1])) + else: + code = gen.gi_code + coro = ('%s() running at %s:%s' + % (coro_qualname, code.co_filename, + code.co_firstlineno)) - class MyTask(tasks.Task, T): - def __repr__(self): - return super().__repr__() + self.assertEqual(repr(gen), '<CoroWrapper %s>' % coro) - gen = coro() - t = MyTask(gen, loop=self.loop) - self.assertEqual(repr(t), 'T[](<coro>)') - gen.close() + # test pending Task + t = asyncio.Task(gen, loop=self.loop) + t.add_done_callback(Dummy()) + + # format the coroutine object + if coroutines._DEBUG: + src = '%s:%s' % test_utils.get_function_source(notmuch) + else: + code = gen.gi_code + src = '%s:%s' % (code.co_filename, code.co_firstlineno) + coro = format_coroutine(coro_qualname, 'running', src, + t._source_traceback, + generator=not coroutines._DEBUG) + self.assertEqual(repr(t), + '<Task pending %s cb=[<Dummy>()]>' % coro) + self.loop.run_until_complete(t) + + def test_task_repr_wait_for(self): + self.loop.set_debug(False) + + @asyncio.coroutine + def wait_for(fut): + return (yield from fut) + + fut = asyncio.Future(loop=self.loop) + task = asyncio.Task(wait_for(fut), loop=self.loop) + test_utils.run_briefly(self.loop) + self.assertRegex(repr(task), + '<Task .* wait_for=%s>' % re.escape(repr(fut))) + + fut.set_result(None) + self.loop.run_until_complete(task) def test_task_basics(self): - @tasks.coroutine + @asyncio.coroutine def outer(): a = yield from inner1() b = yield from inner2() return a+b - @tasks.coroutine + @asyncio.coroutine def inner1(): return 42 - @tasks.coroutine + @asyncio.coroutine def inner2(): return 1000 @@ -166,69 +304,68 @@ def gen(): self.assertAlmostEqual(10.0, when) yield 0 - loop = test_utils.TestLoop(gen) - self.addCleanup(loop.close) + loop = self.new_test_loop(gen) - @tasks.coroutine + @asyncio.coroutine def task(): - yield from tasks.sleep(10.0, loop=loop) + yield from asyncio.sleep(10.0, loop=loop) return 12 - t = tasks.Task(task(), loop=loop) + t = asyncio.Task(task(), loop=loop) loop.call_soon(t.cancel) - with self.assertRaises(futures.CancelledError): + with self.assertRaises(asyncio.CancelledError): loop.run_until_complete(t) self.assertTrue(t.done()) self.assertTrue(t.cancelled()) self.assertFalse(t.cancel()) def test_cancel_yield(self): - @tasks.coroutine + @asyncio.coroutine def task(): yield yield return 12 - t = tasks.Task(task(), loop=self.loop) + t = asyncio.Task(task(), loop=self.loop) test_utils.run_briefly(self.loop) # start coro t.cancel() self.assertRaises( - futures.CancelledError, self.loop.run_until_complete, t) + asyncio.CancelledError, self.loop.run_until_complete, t) self.assertTrue(t.done()) self.assertTrue(t.cancelled()) self.assertFalse(t.cancel()) def test_cancel_inner_future(self): - f = futures.Future(loop=self.loop) + f = asyncio.Future(loop=self.loop) - @tasks.coroutine + @asyncio.coroutine def task(): yield from f return 12 - t = tasks.Task(task(), loop=self.loop) + t = asyncio.Task(task(), loop=self.loop) test_utils.run_briefly(self.loop) # start task f.cancel() - with self.assertRaises(futures.CancelledError): + with self.assertRaises(asyncio.CancelledError): self.loop.run_until_complete(t) self.assertTrue(f.cancelled()) self.assertTrue(t.cancelled()) def test_cancel_both_task_and_inner_future(self): - f = futures.Future(loop=self.loop) + f = asyncio.Future(loop=self.loop) - @tasks.coroutine + @asyncio.coroutine def task(): yield from f return 12 - t = tasks.Task(task(), loop=self.loop) + t = asyncio.Task(task(), loop=self.loop) test_utils.run_briefly(self.loop) f.cancel() t.cancel() - with self.assertRaises(futures.CancelledError): + with self.assertRaises(asyncio.CancelledError): self.loop.run_until_complete(t) self.assertTrue(t.done()) @@ -236,18 +373,18 @@ def task(): self.assertTrue(t.cancelled()) def test_cancel_task_catching(self): - fut1 = futures.Future(loop=self.loop) - fut2 = futures.Future(loop=self.loop) + fut1 = asyncio.Future(loop=self.loop) + fut2 = asyncio.Future(loop=self.loop) - @tasks.coroutine + @asyncio.coroutine def task(): yield from fut1 try: yield from fut2 - except futures.CancelledError: + except asyncio.CancelledError: return 42 - t = tasks.Task(task(), loop=self.loop) + t = asyncio.Task(task(), loop=self.loop) test_utils.run_briefly(self.loop) self.assertIs(t._fut_waiter, fut1) # White-box test. fut1.set_result(None) @@ -260,21 +397,21 @@ def task(): self.assertFalse(t.cancelled()) def test_cancel_task_ignoring(self): - fut1 = futures.Future(loop=self.loop) - fut2 = futures.Future(loop=self.loop) - fut3 = futures.Future(loop=self.loop) + fut1 = asyncio.Future(loop=self.loop) + fut2 = asyncio.Future(loop=self.loop) + fut3 = asyncio.Future(loop=self.loop) - @tasks.coroutine + @asyncio.coroutine def task(): yield from fut1 try: yield from fut2 - except futures.CancelledError: + except asyncio.CancelledError: pass res = yield from fut3 return res - t = tasks.Task(task(), loop=self.loop) + t = asyncio.Task(task(), loop=self.loop) test_utils.run_briefly(self.loop) self.assertIs(t._fut_waiter, fut1) # White-box test. fut1.set_result(None) @@ -291,20 +428,20 @@ def task(): self.assertFalse(t.cancelled()) def test_cancel_current_task(self): - loop = events.new_event_loop() - self.addCleanup(loop.close) + loop = asyncio.new_event_loop() + self.set_event_loop(loop) - @tasks.coroutine + @asyncio.coroutine def task(): t.cancel() self.assertTrue(t._must_cancel) # White-box test. # The sleep should be cancelled immediately. - yield from tasks.sleep(100, loop=loop) + yield from asyncio.sleep(100, loop=loop) return 12 - t = tasks.Task(task(), loop=loop) + t = asyncio.Task(task(), loop=loop) self.assertRaises( - futures.CancelledError, loop.run_until_complete, t) + asyncio.CancelledError, loop.run_until_complete, t) self.assertTrue(t.done()) self.assertFalse(t._must_cancel) # White-box test. self.assertFalse(t.cancel()) @@ -320,25 +457,26 @@ def gen(): self.assertAlmostEqual(0.3, when) yield 0.1 - loop = test_utils.TestLoop(gen) - self.addCleanup(loop.close) + loop = self.new_test_loop(gen) x = 0 waiters = [] - @tasks.coroutine + @asyncio.coroutine def task(): nonlocal x while x < 10: - waiters.append(tasks.sleep(0.1, loop=loop)) + waiters.append(asyncio.sleep(0.1, loop=loop)) yield from waiters[-1] x += 1 if x == 2: loop.stop() - t = tasks.Task(task(), loop=loop) - self.assertRaises( - RuntimeError, loop.run_until_complete, t) + t = asyncio.Task(task(), loop=loop) + with self.assertRaises(RuntimeError) as cm: + loop.run_until_complete(t) + self.assertEqual(str(cm.exception), + 'Event loop stopped before Future completed.') self.assertFalse(t.done()) self.assertEqual(x, 2) self.assertAlmostEqual(0.3, loop.time()) @@ -346,6 +484,8 @@ def task(): # close generators for w in waiters: w.close() + t.cancel() + self.assertRaises(asyncio.CancelledError, loop.run_until_complete, t) def test_wait_for(self): @@ -355,30 +495,42 @@ def gen(): when = yield 0 self.assertAlmostEqual(0.1, when) when = yield 0.1 - self.assertAlmostEqual(0.4, when) - yield 0.1 - loop = test_utils.TestLoop(gen) - self.addCleanup(loop.close) + loop = self.new_test_loop(gen) + + foo_running = None - @tasks.coroutine + @asyncio.coroutine def foo(): - yield from tasks.sleep(0.2, loop=loop) + nonlocal foo_running + foo_running = True + try: + yield from asyncio.sleep(0.2, loop=loop) + finally: + foo_running = False return 'done' - fut = tasks.Task(foo(), loop=loop) - - with self.assertRaises(futures.TimeoutError): - loop.run_until_complete(tasks.wait_for(fut, 0.1, loop=loop)) + fut = asyncio.Task(foo(), loop=loop) - self.assertFalse(fut.done()) + with self.assertRaises(asyncio.TimeoutError): + loop.run_until_complete(asyncio.wait_for(fut, 0.1, loop=loop)) + self.assertTrue(fut.done()) + # it should have been cancelled due to the timeout + self.assertTrue(fut.cancelled()) self.assertAlmostEqual(0.1, loop.time()) + self.assertEqual(foo_running, False) - # wait for result - res = loop.run_until_complete( - tasks.wait_for(fut, 0.3, loop=loop)) + def test_wait_for_blocking(self): + loop = self.new_test_loop() + + @asyncio.coroutine + def coro(): + return 'done' + + res = loop.run_until_complete(asyncio.wait_for(coro(), + timeout=None, + loop=loop)) self.assertEqual(res, 'done') - self.assertAlmostEqual(0.2, loop.time()) def test_wait_for_with_global_loop(self): @@ -389,28 +541,39 @@ def gen(): self.assertAlmostEqual(0.01, when) yield 0.01 - loop = test_utils.TestLoop(gen) - self.addCleanup(loop.close) + loop = self.new_test_loop(gen) - @tasks.coroutine + @asyncio.coroutine def foo(): - yield from tasks.sleep(0.2, loop=loop) + yield from asyncio.sleep(0.2, loop=loop) return 'done' - events.set_event_loop(loop) + asyncio.set_event_loop(loop) try: - fut = tasks.Task(foo(), loop=loop) - with self.assertRaises(futures.TimeoutError): - loop.run_until_complete(tasks.wait_for(fut, 0.01)) + fut = asyncio.Task(foo(), loop=loop) + with self.assertRaises(asyncio.TimeoutError): + loop.run_until_complete(asyncio.wait_for(fut, 0.01)) finally: - events.set_event_loop(None) + asyncio.set_event_loop(None) self.assertAlmostEqual(0.01, loop.time()) - self.assertFalse(fut.done()) + self.assertTrue(fut.done()) + self.assertTrue(fut.cancelled()) - # move forward to close generator - loop.advance_time(10) - loop.run_until_complete(fut) + def test_wait_for_race_condition(self): + + def gen(): + yield 0.1 + yield 0.1 + yield 0.1 + + loop = self.new_test_loop(gen) + + fut = asyncio.Future(loop=loop) + task = asyncio.wait_for(fut, timeout=0.2, loop=loop) + loop.call_later(0.1, fut.set_result, "ok") + res = loop.run_until_complete(task) + self.assertEqual(res, "ok") def test_wait(self): @@ -421,25 +584,24 @@ def gen(): self.assertAlmostEqual(0.15, when) yield 0.15 - loop = test_utils.TestLoop(gen) - self.addCleanup(loop.close) + loop = self.new_test_loop(gen) - a = tasks.Task(tasks.sleep(0.1, loop=loop), loop=loop) - b = tasks.Task(tasks.sleep(0.15, loop=loop), loop=loop) + a = asyncio.Task(asyncio.sleep(0.1, loop=loop), loop=loop) + b = asyncio.Task(asyncio.sleep(0.15, loop=loop), loop=loop) - @tasks.coroutine + @asyncio.coroutine def foo(): - done, pending = yield from tasks.wait([b, a], loop=loop) + done, pending = yield from asyncio.wait([b, a], loop=loop) self.assertEqual(done, set([a, b])) self.assertEqual(pending, set()) return 42 - res = loop.run_until_complete(tasks.Task(foo(), loop=loop)) + res = loop.run_until_complete(asyncio.Task(foo(), loop=loop)) self.assertEqual(res, 42) self.assertAlmostEqual(0.15, loop.time()) # Doing it again should take no time and exercise a different path. - res = loop.run_until_complete(tasks.Task(foo(), loop=loop)) + res = loop.run_until_complete(asyncio.Task(foo(), loop=loop)) self.assertAlmostEqual(0.15, loop.time()) self.assertEqual(res, 42) @@ -452,37 +614,51 @@ def gen(): self.assertAlmostEqual(0.015, when) yield 0.015 - loop = test_utils.TestLoop(gen) - self.addCleanup(loop.close) + loop = self.new_test_loop(gen) - a = tasks.Task(tasks.sleep(0.01, loop=loop), loop=loop) - b = tasks.Task(tasks.sleep(0.015, loop=loop), loop=loop) + a = asyncio.Task(asyncio.sleep(0.01, loop=loop), loop=loop) + b = asyncio.Task(asyncio.sleep(0.015, loop=loop), loop=loop) - @tasks.coroutine + @asyncio.coroutine def foo(): - done, pending = yield from tasks.wait([b, a]) + done, pending = yield from asyncio.wait([b, a]) self.assertEqual(done, set([a, b])) self.assertEqual(pending, set()) return 42 - events.set_event_loop(loop) - try: - res = loop.run_until_complete( - tasks.Task(foo(), loop=loop)) - finally: - events.set_event_loop(None) + asyncio.set_event_loop(loop) + res = loop.run_until_complete( + asyncio.Task(foo(), loop=loop)) self.assertEqual(res, 42) + def test_wait_duplicate_coroutines(self): + @asyncio.coroutine + def coro(s): + return s + c = coro('test') + + task = asyncio.Task( + asyncio.wait([c, c, coro('spam')], loop=self.loop), + loop=self.loop) + + done, pending = self.loop.run_until_complete(task) + + self.assertFalse(pending) + self.assertEqual(set(f.result() for f in done), {'test', 'spam'}) + def test_wait_errors(self): self.assertRaises( ValueError, self.loop.run_until_complete, - tasks.wait(set(), loop=self.loop)) + asyncio.wait(set(), loop=self.loop)) - self.assertRaises( - ValueError, self.loop.run_until_complete, - tasks.wait([tasks.sleep(10.0, loop=self.loop)], - return_when=-1, loop=self.loop)) + # -1 is an invalid return_when value + sleep_coro = asyncio.sleep(10.0, loop=self.loop) + wait_coro = asyncio.wait([sleep_coro], return_when=-1, loop=self.loop) + self.assertRaises(ValueError, + self.loop.run_until_complete, wait_coro) + + sleep_coro.close() def test_wait_first_completed(self): @@ -493,14 +669,13 @@ def gen(): self.assertAlmostEqual(0.1, when) yield 0.1 - loop = test_utils.TestLoop(gen) - self.addCleanup(loop.close) + loop = self.new_test_loop(gen) - a = tasks.Task(tasks.sleep(10.0, loop=loop), loop=loop) - b = tasks.Task(tasks.sleep(0.1, loop=loop), loop=loop) - task = tasks.Task( - tasks.wait([b, a], return_when=tasks.FIRST_COMPLETED, - loop=loop), + a = asyncio.Task(asyncio.sleep(10.0, loop=loop), loop=loop) + b = asyncio.Task(asyncio.sleep(0.1, loop=loop), loop=loop) + task = asyncio.Task( + asyncio.wait([b, a], return_when=asyncio.FIRST_COMPLETED, + loop=loop), loop=loop) done, pending = loop.run_until_complete(task) @@ -513,26 +688,26 @@ def gen(): # move forward to close generator loop.advance_time(10) - loop.run_until_complete(tasks.wait([a, b], loop=loop)) + loop.run_until_complete(asyncio.wait([a, b], loop=loop)) def test_wait_really_done(self): # there is possibility that some tasks in the pending list # became done but their callbacks haven't all been called yet - @tasks.coroutine + @asyncio.coroutine def coro1(): yield - @tasks.coroutine + @asyncio.coroutine def coro2(): yield yield - a = tasks.Task(coro1(), loop=self.loop) - b = tasks.Task(coro2(), loop=self.loop) - task = tasks.Task( - tasks.wait([b, a], return_when=tasks.FIRST_COMPLETED, - loop=self.loop), + a = asyncio.Task(coro1(), loop=self.loop) + b = asyncio.Task(coro2(), loop=self.loop) + task = asyncio.Task( + asyncio.wait([b, a], return_when=asyncio.FIRST_COMPLETED, + loop=self.loop), loop=self.loop) done, pending = self.loop.run_until_complete(task) @@ -549,20 +724,19 @@ def gen(): self.assertAlmostEqual(10.0, when) yield 0 - loop = test_utils.TestLoop(gen) - self.addCleanup(loop.close) + loop = self.new_test_loop(gen) # first_exception, task already has exception - a = tasks.Task(tasks.sleep(10.0, loop=loop), loop=loop) + a = asyncio.Task(asyncio.sleep(10.0, loop=loop), loop=loop) - @tasks.coroutine + @asyncio.coroutine def exc(): raise ZeroDivisionError('err') - b = tasks.Task(exc(), loop=loop) - task = tasks.Task( - tasks.wait([b, a], return_when=tasks.FIRST_EXCEPTION, - loop=loop), + b = asyncio.Task(exc(), loop=loop) + task = asyncio.Task( + asyncio.wait([b, a], return_when=asyncio.FIRST_EXCEPTION, + loop=loop), loop=loop) done, pending = loop.run_until_complete(task) @@ -572,7 +746,7 @@ def exc(): # move forward to close generator loop.advance_time(10) - loop.run_until_complete(tasks.wait([a, b], loop=loop)) + loop.run_until_complete(asyncio.wait([a, b], loop=loop)) def test_wait_first_exception_in_wait(self): @@ -583,20 +757,19 @@ def gen(): self.assertAlmostEqual(0.01, when) yield 0.01 - loop = test_utils.TestLoop(gen) - self.addCleanup(loop.close) + loop = self.new_test_loop(gen) # first_exception, exception during waiting - a = tasks.Task(tasks.sleep(10.0, loop=loop), loop=loop) + a = asyncio.Task(asyncio.sleep(10.0, loop=loop), loop=loop) - @tasks.coroutine + @asyncio.coroutine def exc(): - yield from tasks.sleep(0.01, loop=loop) + yield from asyncio.sleep(0.01, loop=loop) raise ZeroDivisionError('err') - b = tasks.Task(exc(), loop=loop) - task = tasks.wait([b, a], return_when=tasks.FIRST_EXCEPTION, - loop=loop) + b = asyncio.Task(exc(), loop=loop) + task = asyncio.wait([b, a], return_when=asyncio.FIRST_EXCEPTION, + loop=loop) done, pending = loop.run_until_complete(task) self.assertEqual({b}, done) @@ -605,7 +778,7 @@ def exc(): # move forward to close generator loop.advance_time(10) - loop.run_until_complete(tasks.wait([a, b], loop=loop)) + loop.run_until_complete(asyncio.wait([a, b], loop=loop)) def test_wait_with_exception(self): @@ -616,30 +789,29 @@ def gen(): self.assertAlmostEqual(0.15, when) yield 0.15 - loop = test_utils.TestLoop(gen) - self.addCleanup(loop.close) + loop = self.new_test_loop(gen) - a = tasks.Task(tasks.sleep(0.1, loop=loop), loop=loop) + a = asyncio.Task(asyncio.sleep(0.1, loop=loop), loop=loop) - @tasks.coroutine + @asyncio.coroutine def sleeper(): - yield from tasks.sleep(0.15, loop=loop) + yield from asyncio.sleep(0.15, loop=loop) raise ZeroDivisionError('really') - b = tasks.Task(sleeper(), loop=loop) + b = asyncio.Task(sleeper(), loop=loop) - @tasks.coroutine + @asyncio.coroutine def foo(): - done, pending = yield from tasks.wait([b, a], loop=loop) + done, pending = yield from asyncio.wait([b, a], loop=loop) self.assertEqual(len(done), 2) self.assertEqual(pending, set()) errors = set(f for f in done if f.exception() is not None) self.assertEqual(len(errors), 1) - loop.run_until_complete(tasks.Task(foo(), loop=loop)) + loop.run_until_complete(asyncio.Task(foo(), loop=loop)) self.assertAlmostEqual(0.15, loop.time()) - loop.run_until_complete(tasks.Task(foo(), loop=loop)) + loop.run_until_complete(asyncio.Task(foo(), loop=loop)) self.assertAlmostEqual(0.15, loop.time()) def test_wait_with_timeout(self): @@ -653,25 +825,24 @@ def gen(): self.assertAlmostEqual(0.11, when) yield 0.11 - loop = test_utils.TestLoop(gen) - self.addCleanup(loop.close) + loop = self.new_test_loop(gen) - a = tasks.Task(tasks.sleep(0.1, loop=loop), loop=loop) - b = tasks.Task(tasks.sleep(0.15, loop=loop), loop=loop) + a = asyncio.Task(asyncio.sleep(0.1, loop=loop), loop=loop) + b = asyncio.Task(asyncio.sleep(0.15, loop=loop), loop=loop) - @tasks.coroutine + @asyncio.coroutine def foo(): - done, pending = yield from tasks.wait([b, a], timeout=0.11, - loop=loop) + done, pending = yield from asyncio.wait([b, a], timeout=0.11, + loop=loop) self.assertEqual(done, set([a])) self.assertEqual(pending, set([b])) - loop.run_until_complete(tasks.Task(foo(), loop=loop)) + loop.run_until_complete(asyncio.Task(foo(), loop=loop)) self.assertAlmostEqual(0.11, loop.time()) # move forward to close generator loop.advance_time(10) - loop.run_until_complete(tasks.wait([a, b], loop=loop)) + loop.run_until_complete(asyncio.wait([a, b], loop=loop)) def test_wait_concurrent_complete(self): @@ -684,14 +855,13 @@ def gen(): self.assertAlmostEqual(0.1, when) yield 0.1 - loop = test_utils.TestLoop(gen) - self.addCleanup(loop.close) + loop = self.new_test_loop(gen) - a = tasks.Task(tasks.sleep(0.1, loop=loop), loop=loop) - b = tasks.Task(tasks.sleep(0.15, loop=loop), loop=loop) + a = asyncio.Task(asyncio.sleep(0.1, loop=loop), loop=loop) + b = asyncio.Task(asyncio.sleep(0.15, loop=loop), loop=loop) done, pending = loop.run_until_complete( - tasks.wait([b, a], timeout=0.1, loop=loop)) + asyncio.wait([b, a], timeout=0.1, loop=loop)) self.assertEqual(done, set([a])) self.assertEqual(pending, set([b])) @@ -699,7 +869,7 @@ def gen(): # move forward to close generator loop.advance_time(10) - loop.run_until_complete(tasks.wait([a, b], loop=loop)) + loop.run_until_complete(asyncio.wait([a, b], loop=loop)) def test_as_completed(self): @@ -709,15 +879,16 @@ def gen(): yield 0.01 yield 0 - loop = test_utils.TestLoop(gen) - self.addCleanup(loop.close) + loop = self.new_test_loop(gen) + # disable "slow callback" warning + loop.slow_callback_duration = 1.0 completed = set() time_shifted = False - @tasks.coroutine + @asyncio.coroutine def sleeper(dt, x): nonlocal time_shifted - yield from tasks.sleep(dt, loop=loop) + yield from asyncio.sleep(dt, loop=loop) completed.add(x) if not time_shifted and 'a' in completed and 'b' in completed: time_shifted = True @@ -728,63 +899,78 @@ def sleeper(dt, x): b = sleeper(0.01, 'b') c = sleeper(0.15, 'c') - @tasks.coroutine + @asyncio.coroutine def foo(): values = [] - for f in tasks.as_completed([b, c, a], loop=loop): + for f in asyncio.as_completed([b, c, a], loop=loop): values.append((yield from f)) return values - res = loop.run_until_complete(tasks.Task(foo(), loop=loop)) + res = loop.run_until_complete(asyncio.Task(foo(), loop=loop)) self.assertAlmostEqual(0.15, loop.time()) self.assertTrue('a' in res[:2]) self.assertTrue('b' in res[:2]) self.assertEqual(res[2], 'c') # Doing it again should take no time and exercise a different path. - res = loop.run_until_complete(tasks.Task(foo(), loop=loop)) + res = loop.run_until_complete(asyncio.Task(foo(), loop=loop)) self.assertAlmostEqual(0.15, loop.time()) def test_as_completed_with_timeout(self): def gen(): - when = yield - self.assertAlmostEqual(0.12, when) - when = yield 0 - self.assertAlmostEqual(0.1, when) - when = yield 0 - self.assertAlmostEqual(0.15, when) - when = yield 0.1 - self.assertAlmostEqual(0.12, when) - yield 0.02 + yield + yield 0 + yield 0 + yield 0.1 - loop = test_utils.TestLoop(gen) - self.addCleanup(loop.close) + loop = self.new_test_loop(gen) - a = tasks.sleep(0.1, 'a', loop=loop) - b = tasks.sleep(0.15, 'b', loop=loop) + a = asyncio.sleep(0.1, 'a', loop=loop) + b = asyncio.sleep(0.15, 'b', loop=loop) - @tasks.coroutine + @asyncio.coroutine def foo(): values = [] - for f in tasks.as_completed([a, b], timeout=0.12, loop=loop): + for f in asyncio.as_completed([a, b], timeout=0.12, loop=loop): + if values: + loop.advance_time(0.02) try: v = yield from f values.append((1, v)) - except futures.TimeoutError as exc: + except asyncio.TimeoutError as exc: values.append((2, exc)) return values - res = loop.run_until_complete(tasks.Task(foo(), loop=loop)) + res = loop.run_until_complete(asyncio.Task(foo(), loop=loop)) self.assertEqual(len(res), 2, res) self.assertEqual(res[0], (1, 'a')) self.assertEqual(res[1][0], 2) - self.assertIsInstance(res[1][1], futures.TimeoutError) + self.assertIsInstance(res[1][1], asyncio.TimeoutError) self.assertAlmostEqual(0.12, loop.time()) # move forward to close generator loop.advance_time(10) - loop.run_until_complete(tasks.wait([a, b], loop=loop)) + loop.run_until_complete(asyncio.wait([a, b], loop=loop)) + + def test_as_completed_with_unused_timeout(self): + + def gen(): + yield + yield 0 + yield 0.01 + + loop = self.new_test_loop(gen) + + a = asyncio.sleep(0.01, 'a', loop=loop) + + @asyncio.coroutine + def foo(): + for f in asyncio.as_completed([a], timeout=1, loop=loop): + v = yield from f + self.assertEqual(v, 'a') + + loop.run_until_complete(asyncio.Task(foo(), loop=loop)) def test_as_completed_reverse_wait(self): @@ -793,13 +979,12 @@ def gen(): yield 0.05 yield 0 - loop = test_utils.TestLoop(gen) - self.addCleanup(loop.close) + loop = self.new_test_loop(gen) - a = tasks.sleep(0.05, 'a', loop=loop) - b = tasks.sleep(0.10, 'b', loop=loop) + a = asyncio.sleep(0.05, 'a', loop=loop) + b = asyncio.sleep(0.10, 'b', loop=loop) fs = {a, b} - futs = list(tasks.as_completed(fs, loop=loop)) + futs = list(asyncio.as_completed(fs, loop=loop)) self.assertEqual(len(futs), 2) x = loop.run_until_complete(futs[1]) @@ -819,18 +1004,38 @@ def gen(): self.assertAlmostEqual(0.05, when) yield 0.05 - loop = test_utils.TestLoop(gen) - self.addCleanup(loop.close) + loop = self.new_test_loop(gen) - a = tasks.sleep(0.05, 'a', loop=loop) - b = tasks.sleep(0.05, 'b', loop=loop) + a = asyncio.sleep(0.05, 'a', loop=loop) + b = asyncio.sleep(0.05, 'b', loop=loop) fs = {a, b} - futs = list(tasks.as_completed(fs, loop=loop)) + futs = list(asyncio.as_completed(fs, loop=loop)) self.assertEqual(len(futs), 2) - waiter = tasks.wait(futs, loop=loop) + waiter = asyncio.wait(futs, loop=loop) done, pending = loop.run_until_complete(waiter) self.assertEqual(set(f.result() for f in done), {'a', 'b'}) + def test_as_completed_duplicate_coroutines(self): + + @asyncio.coroutine + def coro(s): + return s + + @asyncio.coroutine + def runner(): + result = [] + c = coro('ham') + for f in asyncio.as_completed([c, c, coro('spam')], + loop=self.loop): + result.append((yield from f)) + return result + + fut = asyncio.Task(runner(), loop=self.loop) + self.loop.run_until_complete(fut) + result = fut.result() + self.assertEqual(set(result), {'ham', 'spam'}) + self.assertEqual(len(result), 2) + def test_sleep(self): def gen(): @@ -840,16 +1045,15 @@ def gen(): self.assertAlmostEqual(0.1, when) yield 0.05 - loop = test_utils.TestLoop(gen) - self.addCleanup(loop.close) + loop = self.new_test_loop(gen) - @tasks.coroutine + @asyncio.coroutine def sleeper(dt, arg): - yield from tasks.sleep(dt/2, loop=loop) - res = yield from tasks.sleep(dt/2, arg, loop=loop) + yield from asyncio.sleep(dt/2, loop=loop) + res = yield from asyncio.sleep(dt/2, arg, loop=loop) return res - t = tasks.Task(sleeper(0.1, 'yeah'), loop=loop) + t = asyncio.Task(sleeper(0.1, 'yeah'), loop=loop) loop.run_until_complete(t) self.assertTrue(t.done()) self.assertEqual(t.result(), 'yeah') @@ -862,18 +1066,17 @@ def gen(): self.assertAlmostEqual(10.0, when) yield 0 - loop = test_utils.TestLoop(gen) - self.addCleanup(loop.close) + loop = self.new_test_loop(gen) - t = tasks.Task(tasks.sleep(10.0, 'yeah', loop=loop), - loop=loop) + t = asyncio.Task(asyncio.sleep(10.0, 'yeah', loop=loop), + loop=loop) handle = None orig_call_later = loop.call_later - def call_later(self, delay, callback, *args): + def call_later(delay, callback, *args): nonlocal handle - handle = orig_call_later(self, delay, callback, *args) + handle = orig_call_later(delay, callback, *args) return handle loop.call_later = call_later @@ -894,24 +1097,19 @@ def gen(): self.assertAlmostEqual(5000, when) yield 0.1 - loop = test_utils.TestLoop(gen) - self.addCleanup(loop.close) - - sleepfut = None + loop = self.new_test_loop(gen) - @tasks.coroutine + @asyncio.coroutine def sleep(dt): - nonlocal sleepfut - sleepfut = tasks.sleep(dt, loop=loop) - yield from sleepfut + yield from asyncio.sleep(dt, loop=loop) - @tasks.coroutine + @asyncio.coroutine def doit(): - sleeper = tasks.Task(sleep(5000), loop=loop) + sleeper = asyncio.Task(sleep(5000), loop=loop) loop.call_later(0.1, sleeper.cancel) try: yield from sleeper - except futures.CancelledError: + except asyncio.CancelledError: return 'cancelled' else: return 'slept in' @@ -921,37 +1119,37 @@ def doit(): self.assertAlmostEqual(0.1, loop.time()) def test_task_cancel_waiter_future(self): - fut = futures.Future(loop=self.loop) + fut = asyncio.Future(loop=self.loop) - @tasks.coroutine + @asyncio.coroutine def coro(): yield from fut - task = tasks.Task(coro(), loop=self.loop) + task = asyncio.Task(coro(), loop=self.loop) test_utils.run_briefly(self.loop) self.assertIs(task._fut_waiter, fut) task.cancel() test_utils.run_briefly(self.loop) self.assertRaises( - futures.CancelledError, self.loop.run_until_complete, task) + asyncio.CancelledError, self.loop.run_until_complete, task) self.assertIsNone(task._fut_waiter) self.assertTrue(fut.cancelled()) def test_step_in_completed_task(self): - @tasks.coroutine + @asyncio.coroutine def notmuch(): return 'ko' gen = notmuch() - task = tasks.Task(gen, loop=self.loop) + task = asyncio.Task(gen, loop=self.loop) task.set_result('ok') self.assertRaises(AssertionError, task._step) gen.close() def test_step_result(self): - @tasks.coroutine + @asyncio.coroutine def notmuch(): yield None yield 1 @@ -963,7 +1161,7 @@ def notmuch(): def test_step_result_future(self): # If coroutine returns future, task waits on this future. - class Fut(futures.Future): + class Fut(asyncio.Future): def __init__(self, *args, **kwds): self.cb_added = False super().__init__(*args, **kwds) @@ -975,12 +1173,12 @@ def add_done_callback(self, fn): fut = Fut(loop=self.loop) result = None - @tasks.coroutine + @asyncio.coroutine def wait_for_future(): nonlocal result result = yield from fut - t = tasks.Task(wait_for_future(), loop=self.loop) + t = asyncio.Task(wait_for_future(), loop=self.loop) test_utils.run_briefly(self.loop) self.assertTrue(fut.cb_added) @@ -992,11 +1190,11 @@ def wait_for_future(): self.assertIsNone(t.result()) def test_step_with_baseexception(self): - @tasks.coroutine + @asyncio.coroutine def notmutch(): raise BaseException() - task = tasks.Task(notmutch(), loop=self.loop) + task = asyncio.Task(notmutch(), loop=self.loop) self.assertRaises(BaseException, task._step) self.assertTrue(task.done()) @@ -1009,23 +1207,22 @@ def gen(): self.assertAlmostEqual(10.0, when) yield 0 - loop = test_utils.TestLoop(gen) - self.addCleanup(loop.close) + loop = self.new_test_loop(gen) - @tasks.coroutine + @asyncio.coroutine def sleeper(): - yield from tasks.sleep(10, loop=loop) + yield from asyncio.sleep(10, loop=loop) base_exc = BaseException() - @tasks.coroutine + @asyncio.coroutine def notmutch(): try: yield from sleeper() - except futures.CancelledError: + except asyncio.CancelledError: raise base_exc - task = tasks.Task(notmutch(), loop=loop) + task = asyncio.Task(notmutch(), loop=loop) test_utils.run_briefly(loop) task.cancel() @@ -1041,21 +1238,21 @@ def test_iscoroutinefunction(self): def fn(): pass - self.assertFalse(tasks.iscoroutinefunction(fn)) + self.assertFalse(asyncio.iscoroutinefunction(fn)) def fn1(): yield - self.assertFalse(tasks.iscoroutinefunction(fn1)) + self.assertFalse(asyncio.iscoroutinefunction(fn1)) - @tasks.coroutine + @asyncio.coroutine def fn2(): yield - self.assertTrue(tasks.iscoroutinefunction(fn2)) + self.assertTrue(asyncio.iscoroutinefunction(fn2)) def test_yield_vs_yield_from(self): - fut = futures.Future(loop=self.loop) + fut = asyncio.Future(loop=self.loop) - @tasks.coroutine + @asyncio.coroutine def wait_for_future(): yield fut @@ -1066,11 +1263,11 @@ def wait_for_future(): self.assertFalse(fut.done()) def test_yield_vs_yield_from_generator(self): - @tasks.coroutine + @asyncio.coroutine def coro(): yield - @tasks.coroutine + @asyncio.coroutine def wait_for_future(): gen = coro() try: @@ -1084,65 +1281,103 @@ def wait_for_future(): self.loop.run_until_complete, task) def test_coroutine_non_gen_function(self): - @tasks.coroutine + @asyncio.coroutine def func(): return 'test' - self.assertTrue(tasks.iscoroutinefunction(func)) + self.assertTrue(asyncio.iscoroutinefunction(func)) coro = func() - self.assertTrue(tasks.iscoroutine(coro)) + self.assertTrue(asyncio.iscoroutine(coro)) res = self.loop.run_until_complete(coro) self.assertEqual(res, 'test') def test_coroutine_non_gen_function_return_future(self): - fut = futures.Future(loop=self.loop) + fut = asyncio.Future(loop=self.loop) - @tasks.coroutine + @asyncio.coroutine def func(): return fut - @tasks.coroutine + @asyncio.coroutine def coro(): fut.set_result('test') - t1 = tasks.Task(func(), loop=self.loop) - t2 = tasks.Task(coro(), loop=self.loop) + t1 = asyncio.Task(func(), loop=self.loop) + t2 = asyncio.Task(coro(), loop=self.loop) res = self.loop.run_until_complete(t1) self.assertEqual(res, 'test') self.assertIsNone(t2.result()) + def test_current_task(self): + self.assertIsNone(asyncio.Task.current_task(loop=self.loop)) + + @asyncio.coroutine + def coro(loop): + self.assertTrue(asyncio.Task.current_task(loop=loop) is task) + + task = asyncio.Task(coro(self.loop), loop=self.loop) + self.loop.run_until_complete(task) + self.assertIsNone(asyncio.Task.current_task(loop=self.loop)) + + def test_current_task_with_interleaving_tasks(self): + self.assertIsNone(asyncio.Task.current_task(loop=self.loop)) + + fut1 = asyncio.Future(loop=self.loop) + fut2 = asyncio.Future(loop=self.loop) + + @asyncio.coroutine + def coro1(loop): + self.assertTrue(asyncio.Task.current_task(loop=loop) is task1) + yield from fut1 + self.assertTrue(asyncio.Task.current_task(loop=loop) is task1) + fut2.set_result(True) + + @asyncio.coroutine + def coro2(loop): + self.assertTrue(asyncio.Task.current_task(loop=loop) is task2) + fut1.set_result(True) + yield from fut2 + self.assertTrue(asyncio.Task.current_task(loop=loop) is task2) + + task1 = asyncio.Task(coro1(self.loop), loop=self.loop) + task2 = asyncio.Task(coro2(self.loop), loop=self.loop) + + self.loop.run_until_complete(asyncio.wait((task1, task2), + loop=self.loop)) + self.assertIsNone(asyncio.Task.current_task(loop=self.loop)) + # Some thorough tests for cancellation propagation through # coroutines, tasks and wait(). def test_yield_future_passes_cancel(self): # Cancelling outer() cancels inner() cancels waiter. proof = 0 - waiter = futures.Future(loop=self.loop) + waiter = asyncio.Future(loop=self.loop) - @tasks.coroutine + @asyncio.coroutine def inner(): nonlocal proof try: yield from waiter - except futures.CancelledError: + except asyncio.CancelledError: proof += 1 raise else: self.fail('got past sleep() in inner()') - @tasks.coroutine + @asyncio.coroutine def outer(): nonlocal proof try: yield from inner() - except futures.CancelledError: + except asyncio.CancelledError: proof += 100 # Expect this path. else: proof += 10 - f = tasks.async(outer(), loop=self.loop) + f = asyncio.async(outer(), loop=self.loop) test_utils.run_briefly(self.loop) f.cancel() self.loop.run_until_complete(f) @@ -1153,39 +1388,39 @@ def test_yield_wait_does_not_shield_cancel(self): # Cancelling outer() makes wait() return early, leaves inner() # running. proof = 0 - waiter = futures.Future(loop=self.loop) + waiter = asyncio.Future(loop=self.loop) - @tasks.coroutine + @asyncio.coroutine def inner(): nonlocal proof yield from waiter proof += 1 - @tasks.coroutine + @asyncio.coroutine def outer(): nonlocal proof - d, p = yield from tasks.wait([inner()], loop=self.loop) + d, p = yield from asyncio.wait([inner()], loop=self.loop) proof += 100 - f = tasks.async(outer(), loop=self.loop) + f = asyncio.async(outer(), loop=self.loop) test_utils.run_briefly(self.loop) f.cancel() self.assertRaises( - futures.CancelledError, self.loop.run_until_complete, f) + asyncio.CancelledError, self.loop.run_until_complete, f) waiter.set_result(None) test_utils.run_briefly(self.loop) self.assertEqual(proof, 1) def test_shield_result(self): - inner = futures.Future(loop=self.loop) - outer = tasks.shield(inner) + inner = asyncio.Future(loop=self.loop) + outer = asyncio.shield(inner) inner.set_result(42) res = self.loop.run_until_complete(outer) self.assertEqual(res, 42) def test_shield_exception(self): - inner = futures.Future(loop=self.loop) - outer = tasks.shield(inner) + inner = asyncio.Future(loop=self.loop) + outer = asyncio.shield(inner) test_utils.run_briefly(self.loop) exc = RuntimeError('expected') inner.set_exception(exc) @@ -1193,50 +1428,50 @@ def test_shield_exception(self): self.assertIs(outer.exception(), exc) def test_shield_cancel(self): - inner = futures.Future(loop=self.loop) - outer = tasks.shield(inner) + inner = asyncio.Future(loop=self.loop) + outer = asyncio.shield(inner) test_utils.run_briefly(self.loop) inner.cancel() test_utils.run_briefly(self.loop) self.assertTrue(outer.cancelled()) def test_shield_shortcut(self): - fut = futures.Future(loop=self.loop) + fut = asyncio.Future(loop=self.loop) fut.set_result(42) - res = self.loop.run_until_complete(tasks.shield(fut)) + res = self.loop.run_until_complete(asyncio.shield(fut)) self.assertEqual(res, 42) def test_shield_effect(self): # Cancelling outer() does not affect inner(). proof = 0 - waiter = futures.Future(loop=self.loop) + waiter = asyncio.Future(loop=self.loop) - @tasks.coroutine + @asyncio.coroutine def inner(): nonlocal proof yield from waiter proof += 1 - @tasks.coroutine + @asyncio.coroutine def outer(): nonlocal proof - yield from tasks.shield(inner(), loop=self.loop) + yield from asyncio.shield(inner(), loop=self.loop) proof += 100 - f = tasks.async(outer(), loop=self.loop) + f = asyncio.async(outer(), loop=self.loop) test_utils.run_briefly(self.loop) f.cancel() - with self.assertRaises(futures.CancelledError): + with self.assertRaises(asyncio.CancelledError): self.loop.run_until_complete(f) waiter.set_result(None) test_utils.run_briefly(self.loop) self.assertEqual(proof, 1) def test_shield_gather(self): - child1 = futures.Future(loop=self.loop) - child2 = futures.Future(loop=self.loop) - parent = tasks.gather(child1, child2, loop=self.loop) - outer = tasks.shield(parent, loop=self.loop) + child1 = asyncio.Future(loop=self.loop) + child2 = asyncio.Future(loop=self.loop) + parent = asyncio.gather(child1, child2, loop=self.loop) + outer = asyncio.shield(parent, loop=self.loop) test_utils.run_briefly(self.loop) outer.cancel() test_utils.run_briefly(self.loop) @@ -1247,41 +1482,272 @@ def test_shield_gather(self): self.assertEqual(parent.result(), [1, 2]) def test_gather_shield(self): - child1 = futures.Future(loop=self.loop) - child2 = futures.Future(loop=self.loop) - inner1 = tasks.shield(child1, loop=self.loop) - inner2 = tasks.shield(child2, loop=self.loop) - parent = tasks.gather(inner1, inner2, loop=self.loop) + child1 = asyncio.Future(loop=self.loop) + child2 = asyncio.Future(loop=self.loop) + inner1 = asyncio.shield(child1, loop=self.loop) + inner2 = asyncio.shield(child2, loop=self.loop) + parent = asyncio.gather(inner1, inner2, loop=self.loop) test_utils.run_briefly(self.loop) parent.cancel() # This should cancel inner1 and inner2 but bot child1 and child2. test_utils.run_briefly(self.loop) - self.assertIsInstance(parent.exception(), futures.CancelledError) + self.assertIsInstance(parent.exception(), asyncio.CancelledError) self.assertTrue(inner1.cancelled()) self.assertTrue(inner2.cancelled()) child1.set_result(1) child2.set_result(2) test_utils.run_briefly(self.loop) + def test_as_completed_invalid_args(self): + fut = asyncio.Future(loop=self.loop) + + # as_completed() expects a list of futures, not a future instance + self.assertRaises(TypeError, self.loop.run_until_complete, + asyncio.as_completed(fut, loop=self.loop)) + coro = coroutine_function() + self.assertRaises(TypeError, self.loop.run_until_complete, + asyncio.as_completed(coro, loop=self.loop)) + coro.close() + + def test_wait_invalid_args(self): + fut = asyncio.Future(loop=self.loop) + + # wait() expects a list of futures, not a future instance + self.assertRaises(TypeError, self.loop.run_until_complete, + asyncio.wait(fut, loop=self.loop)) + coro = coroutine_function() + self.assertRaises(TypeError, self.loop.run_until_complete, + asyncio.wait(coro, loop=self.loop)) + coro.close() + + # wait() expects at least a future + self.assertRaises(ValueError, self.loop.run_until_complete, + asyncio.wait([], loop=self.loop)) + + def test_corowrapper_mocks_generator(self): + + def check(): + # A function that asserts various things. + # Called twice, with different debug flag values. + + @asyncio.coroutine + def coro(): + # The actual coroutine. + self.assertTrue(gen.gi_running) + yield from fut + + # A completed Future used to run the coroutine. + fut = asyncio.Future(loop=self.loop) + fut.set_result(None) + + # Call the coroutine. + gen = coro() + + # Check some properties. + self.assertTrue(asyncio.iscoroutine(gen)) + self.assertIsInstance(gen.gi_frame, types.FrameType) + self.assertFalse(gen.gi_running) + self.assertIsInstance(gen.gi_code, types.CodeType) + + # Run it. + self.loop.run_until_complete(gen) + + # The frame should have changed. + self.assertIsNone(gen.gi_frame) + + # Save debug flag. + old_debug = asyncio.coroutines._DEBUG + try: + # Test with debug flag cleared. + asyncio.coroutines._DEBUG = False + check() + + # Test with debug flag set. + asyncio.coroutines._DEBUG = True + check() + + finally: + # Restore original debug flag. + asyncio.coroutines._DEBUG = old_debug + + def test_yield_from_corowrapper(self): + old_debug = asyncio.coroutines._DEBUG + asyncio.coroutines._DEBUG = True + try: + @asyncio.coroutine + def t1(): + return (yield from t2()) + + @asyncio.coroutine + def t2(): + f = asyncio.Future(loop=self.loop) + asyncio.Task(t3(f), loop=self.loop) + return (yield from f) + + @asyncio.coroutine + def t3(f): + f.set_result((1, 2, 3)) + + task = asyncio.Task(t1(), loop=self.loop) + val = self.loop.run_until_complete(task) + self.assertEqual(val, (1, 2, 3)) + finally: + asyncio.coroutines._DEBUG = old_debug + + def test_yield_from_corowrapper_send(self): + def foo(): + a = yield + return a + + def call(arg): + cw = asyncio.coroutines.CoroWrapper(foo(), foo) + cw.send(None) + try: + cw.send(arg) + except StopIteration as ex: + return ex.args[0] + else: + raise AssertionError('StopIteration was expected') + + self.assertEqual(call((1, 2)), (1, 2)) + self.assertEqual(call('spam'), 'spam') + + def test_corowrapper_weakref(self): + wd = weakref.WeakValueDictionary() + def foo(): yield from [] + cw = asyncio.coroutines.CoroWrapper(foo(), foo) + wd['cw'] = cw # Would fail without __weakref__ slot. + cw.gen = None # Suppress warning from __del__. + + @unittest.skipUnless(PY34, + 'need python 3.4 or later') + def test_log_destroyed_pending_task(self): + @asyncio.coroutine + def kill_me(loop): + future = asyncio.Future(loop=loop) + yield from future + # at this point, the only reference to kill_me() task is + # the Task._wakeup() method in future._callbacks + raise Exception("code never reached") + + mock_handler = mock.Mock() + self.loop.set_debug(True) + self.loop.set_exception_handler(mock_handler) + + # schedule the task + coro = kill_me(self.loop) + task = asyncio.async(coro, loop=self.loop) + self.assertEqual(asyncio.Task.all_tasks(loop=self.loop), {task}) + + # execute the task so it waits for future + self.loop._run_once() + self.assertEqual(len(self.loop._ready), 0) + + # remove the future used in kill_me(), and references to the task + del coro.gi_frame.f_locals['future'] + coro = None + source_traceback = task._source_traceback + task = None + + # no more reference to kill_me() task: the task is destroyed by the GC + support.gc_collect() + + self.assertEqual(asyncio.Task.all_tasks(loop=self.loop), set()) + + mock_handler.assert_called_with(self.loop, { + 'message': 'Task was destroyed but it is pending!', + 'task': mock.ANY, + 'source_traceback': source_traceback, + }) + mock_handler.reset_mock() + + @mock.patch('asyncio.coroutines.logger') + def test_coroutine_never_yielded(self, m_log): + debug = asyncio.coroutines._DEBUG + try: + asyncio.coroutines._DEBUG = True + @asyncio.coroutine + def coro_noop(): + pass + finally: + asyncio.coroutines._DEBUG = debug + + tb_filename = __file__ + tb_lineno = sys._getframe().f_lineno + 2 + # create a coroutine object but don't use it + coro_noop() + support.gc_collect() + + self.assertTrue(m_log.error.called) + message = m_log.error.call_args[0][0] + func_filename, func_lineno = test_utils.get_function_source(coro_noop) + regex = (r'^<CoroWrapper %s\(\) .* at %s:%s, .*> ' + r'was never yielded from\n' + r'Coroutine object created at \(most recent call last\):\n' + r'.*\n' + r' File "%s", line %s, in test_coroutine_never_yielded\n' + r' coro_noop\(\)$' + % (re.escape(coro_noop.__qualname__), + re.escape(func_filename), func_lineno, + re.escape(tb_filename), tb_lineno)) + + self.assertRegex(message, re.compile(regex, re.DOTALL)) + + def test_task_source_traceback(self): + self.loop.set_debug(True) + + task = asyncio.Task(coroutine_function(), loop=self.loop) + lineno = sys._getframe().f_lineno - 1 + self.assertIsInstance(task._source_traceback, list) + self.assertEqual(task._source_traceback[-1][:3], + (__file__, + lineno, + 'test_task_source_traceback')) + self.loop.run_until_complete(task) + + def _test_cancel_wait_for(self, timeout): + loop = asyncio.new_event_loop() + self.addCleanup(loop.close) + + @asyncio.coroutine + def blocking_coroutine(): + fut = asyncio.Future(loop=loop) + # Block: fut result is never set + yield from fut + + task = loop.create_task(blocking_coroutine()) + + wait = loop.create_task(asyncio.wait_for(task, timeout, loop=loop)) + loop.call_soon(wait.cancel) + + self.assertRaises(asyncio.CancelledError, + loop.run_until_complete, wait) + + # Python issue #23219: cancelling the wait must also cancel the task + self.assertTrue(task.cancelled()) + + def test_cancel_blocking_wait_for(self): + self._test_cancel_wait_for(None) + + def test_cancel_wait_for(self): + self._test_cancel_wait_for(60.0) + class GatherTestsBase: def setUp(self): - self.one_loop = test_utils.TestLoop() - self.other_loop = test_utils.TestLoop() - - def tearDown(self): - self.one_loop.close() - self.other_loop.close() + self.one_loop = self.new_test_loop() + self.other_loop = self.new_test_loop() + self.set_event_loop(self.one_loop, cleanup=False) def _run_loop(self, loop): while loop._ready: test_utils.run_briefly(loop) def _check_success(self, **kwargs): - a, b, c = [futures.Future(loop=self.one_loop) for i in range(3)] - fut = tasks.gather(*self.wrap_futures(a, b, c), **kwargs) - cb = Mock() + a, b, c = [asyncio.Future(loop=self.one_loop) for i in range(3)] + fut = asyncio.gather(*self.wrap_futures(a, b, c), **kwargs) + cb = test_utils.MockCallback() fut.add_done_callback(cb) b.set_result(1) a.set_result(2) @@ -1301,9 +1767,9 @@ def test_result_exception_success(self): self._check_success(return_exceptions=True) def test_one_exception(self): - a, b, c, d, e = [futures.Future(loop=self.one_loop) for i in range(5)] - fut = tasks.gather(*self.wrap_futures(a, b, c, d, e)) - cb = Mock() + a, b, c, d, e = [asyncio.Future(loop=self.one_loop) for i in range(5)] + fut = asyncio.gather(*self.wrap_futures(a, b, c, d, e)) + cb = test_utils.MockCallback() fut.add_done_callback(cb) exc = ZeroDivisionError() a.set_result(1) @@ -1316,12 +1782,13 @@ def test_one_exception(self): c.set_result(3) d.cancel() e.set_exception(RuntimeError()) + e.exception() def test_return_exceptions(self): - a, b, c, d = [futures.Future(loop=self.one_loop) for i in range(4)] - fut = tasks.gather(*self.wrap_futures(a, b, c, d), - return_exceptions=True) - cb = Mock() + a, b, c, d = [asyncio.Future(loop=self.one_loop) for i in range(4)] + fut = asyncio.gather(*self.wrap_futures(a, b, c, d), + return_exceptions=True) + cb = test_utils.MockCallback() fut.add_done_callback(cb) exc = ZeroDivisionError() exc2 = RuntimeError() @@ -1336,22 +1803,50 @@ def test_return_exceptions(self): cb.assert_called_once_with(fut) self.assertEqual(fut.result(), [3, 1, exc, exc2]) + def test_env_var_debug(self): + aio_path = os.path.dirname(os.path.dirname(asyncio.__file__)) -class FutureGatherTests(GatherTestsBase, unittest.TestCase): + code = '\n'.join(( + 'import asyncio.coroutines', + 'print(asyncio.coroutines._DEBUG)')) + + # Test with -E to not fail if the unit test was run with + # PYTHONASYNCIODEBUG set to a non-empty string + sts, stdout, stderr = assert_python_ok('-E', '-c', code, + PYTHONPATH=aio_path) + self.assertEqual(stdout.rstrip(), b'False') + + sts, stdout, stderr = assert_python_ok('-c', code, + PYTHONASYNCIODEBUG='', + PYTHONPATH=aio_path) + self.assertEqual(stdout.rstrip(), b'False') + + sts, stdout, stderr = assert_python_ok('-c', code, + PYTHONASYNCIODEBUG='1', + PYTHONPATH=aio_path) + self.assertEqual(stdout.rstrip(), b'True') + + sts, stdout, stderr = assert_python_ok('-E', '-c', code, + PYTHONASYNCIODEBUG='1', + PYTHONPATH=aio_path) + self.assertEqual(stdout.rstrip(), b'False') + + +class FutureGatherTests(GatherTestsBase, test_utils.TestCase): def wrap_futures(self, *futures): return futures def _check_empty_sequence(self, seq_or_iter): - events.set_event_loop(self.one_loop) - self.addCleanup(events.set_event_loop, None) - fut = tasks.gather(*seq_or_iter) - self.assertIsInstance(fut, futures.Future) + asyncio.set_event_loop(self.one_loop) + self.addCleanup(asyncio.set_event_loop, None) + fut = asyncio.gather(*seq_or_iter) + self.assertIsInstance(fut, asyncio.Future) self.assertIs(fut._loop, self.one_loop) self._run_loop(self.one_loop) self.assertTrue(fut.done()) self.assertEqual(fut.result(), []) - fut = tasks.gather(*seq_or_iter, loop=self.other_loop) + fut = asyncio.gather(*seq_or_iter, loop=self.other_loop) self.assertIs(fut._loop, self.other_loop) def test_constructor_empty_sequence(self): @@ -1361,28 +1856,28 @@ def test_constructor_empty_sequence(self): self._check_empty_sequence(iter("")) def test_constructor_heterogenous_futures(self): - fut1 = futures.Future(loop=self.one_loop) - fut2 = futures.Future(loop=self.other_loop) + fut1 = asyncio.Future(loop=self.one_loop) + fut2 = asyncio.Future(loop=self.other_loop) with self.assertRaises(ValueError): - tasks.gather(fut1, fut2) + asyncio.gather(fut1, fut2) with self.assertRaises(ValueError): - tasks.gather(fut1, loop=self.other_loop) + asyncio.gather(fut1, loop=self.other_loop) def test_constructor_homogenous_futures(self): - children = [futures.Future(loop=self.other_loop) for i in range(3)] - fut = tasks.gather(*children) + children = [asyncio.Future(loop=self.other_loop) for i in range(3)] + fut = asyncio.gather(*children) self.assertIs(fut._loop, self.other_loop) self._run_loop(self.other_loop) self.assertFalse(fut.done()) - fut = tasks.gather(*children, loop=self.other_loop) + fut = asyncio.gather(*children, loop=self.other_loop) self.assertIs(fut._loop, self.other_loop) self._run_loop(self.other_loop) self.assertFalse(fut.done()) def test_one_cancellation(self): - a, b, c, d, e = [futures.Future(loop=self.one_loop) for i in range(5)] - fut = tasks.gather(a, b, c, d, e) - cb = Mock() + a, b, c, d, e = [asyncio.Future(loop=self.one_loop) for i in range(5)] + fut = asyncio.gather(a, b, c, d, e) + cb = test_utils.MockCallback() fut.add_done_callback(cb) a.set_result(1) b.cancel() @@ -1390,17 +1885,18 @@ def test_one_cancellation(self): self.assertTrue(fut.done()) cb.assert_called_once_with(fut) self.assertFalse(fut.cancelled()) - self.assertIsInstance(fut.exception(), futures.CancelledError) + self.assertIsInstance(fut.exception(), asyncio.CancelledError) # Does nothing c.set_result(3) d.cancel() e.set_exception(RuntimeError()) + e.exception() def test_result_exception_one_cancellation(self): - a, b, c, d, e, f = [futures.Future(loop=self.one_loop) + a, b, c, d, e, f = [asyncio.Future(loop=self.one_loop) for i in range(6)] - fut = tasks.gather(a, b, c, d, e, f, return_exceptions=True) - cb = Mock() + fut = asyncio.gather(a, b, c, d, e, f, return_exceptions=True) + cb = test_utils.MockCallback() fut.add_done_callback(cb) a.set_result(1) zde = ZeroDivisionError() @@ -1413,75 +1909,80 @@ def test_result_exception_one_cancellation(self): rte = RuntimeError() f.set_exception(rte) res = self.one_loop.run_until_complete(fut) - self.assertIsInstance(res[2], futures.CancelledError) - self.assertIsInstance(res[4], futures.CancelledError) + self.assertIsInstance(res[2], asyncio.CancelledError) + self.assertIsInstance(res[4], asyncio.CancelledError) res[2] = res[4] = None self.assertEqual(res, [1, zde, None, 3, None, rte]) cb.assert_called_once_with(fut) -class CoroutineGatherTests(GatherTestsBase, unittest.TestCase): +class CoroutineGatherTests(GatherTestsBase, test_utils.TestCase): def setUp(self): super().setUp() - events.set_event_loop(self.one_loop) - - def tearDown(self): - events.set_event_loop(None) - super().tearDown() + asyncio.set_event_loop(self.one_loop) def wrap_futures(self, *futures): coros = [] for fut in futures: - @tasks.coroutine + @asyncio.coroutine def coro(fut=fut): return (yield from fut) coros.append(coro()) return coros def test_constructor_loop_selection(self): - @tasks.coroutine + @asyncio.coroutine def coro(): return 'abc' gen1 = coro() gen2 = coro() - fut = tasks.gather(gen1, gen2) + fut = asyncio.gather(gen1, gen2) self.assertIs(fut._loop, self.one_loop) - gen1.close() - gen2.close() + self.one_loop.run_until_complete(fut) + + self.set_event_loop(self.other_loop, cleanup=False) gen3 = coro() gen4 = coro() - fut = tasks.gather(gen3, gen4, loop=self.other_loop) - self.assertIs(fut._loop, self.other_loop) - gen3.close() - gen4.close() + fut2 = asyncio.gather(gen3, gen4, loop=self.other_loop) + self.assertIs(fut2._loop, self.other_loop) + self.other_loop.run_until_complete(fut2) + + def test_duplicate_coroutines(self): + @asyncio.coroutine + def coro(s): + return s + c = coro('abc') + fut = asyncio.gather(c, c, coro('def'), c, loop=self.one_loop) + self._run_loop(self.one_loop) + self.assertEqual(fut.result(), ['abc', 'abc', 'def', 'abc']) def test_cancellation_broadcast(self): # Cancelling outer() cancels all children. proof = 0 - waiter = futures.Future(loop=self.one_loop) + waiter = asyncio.Future(loop=self.one_loop) - @tasks.coroutine + @asyncio.coroutine def inner(): nonlocal proof yield from waiter proof += 1 - child1 = tasks.async(inner(), loop=self.one_loop) - child2 = tasks.async(inner(), loop=self.one_loop) + child1 = asyncio.async(inner(), loop=self.one_loop) + child2 = asyncio.async(inner(), loop=self.one_loop) gatherer = None - @tasks.coroutine + @asyncio.coroutine def outer(): nonlocal proof, gatherer - gatherer = tasks.gather(child1, child2, loop=self.one_loop) + gatherer = asyncio.gather(child1, child2, loop=self.one_loop) yield from gatherer proof += 100 - f = tasks.async(outer(), loop=self.one_loop) + f = asyncio.async(outer(), loop=self.one_loop) test_utils.run_briefly(self.one_loop) self.assertTrue(f.cancel()) - with self.assertRaises(futures.CancelledError): + with self.assertRaises(asyncio.CancelledError): self.one_loop.run_until_complete(f) self.assertFalse(gatherer.cancel()) self.assertTrue(waiter.cancelled()) @@ -1493,19 +1994,19 @@ def outer(): def test_exception_marking(self): # Test for the first line marked "Mark exception retrieved." - @tasks.coroutine + @asyncio.coroutine def inner(f): yield from f raise RuntimeError('should not be ignored') - a = futures.Future(loop=self.one_loop) - b = futures.Future(loop=self.one_loop) + a = asyncio.Future(loop=self.one_loop) + b = asyncio.Future(loop=self.one_loop) - @tasks.coroutine + @asyncio.coroutine def outer(): - yield from tasks.gather(inner(a), inner(b), loop=self.one_loop) + yield from asyncio.gather(inner(a), inner(b), loop=self.one_loop) - f = tasks.async(outer(), loop=self.one_loop) + f = asyncio.async(outer(), loop=self.one_loop) test_utils.run_briefly(self.one_loop) a.set_result(None) test_utils.run_briefly(self.one_loop) diff --git a/Lib/test/test_asyncio/test_transports.py b/Lib/test/test_asyncio/test_transports.py index f96445c19c85..3b6e3d67075b 100644 --- a/Lib/test/test_asyncio/test_transports.py +++ b/Lib/test/test_asyncio/test_transports.py @@ -1,19 +1,20 @@ """Tests for transports.py.""" import unittest -import unittest.mock +from unittest import mock +import asyncio from asyncio import transports class TransportTests(unittest.TestCase): def test_ctor_extra_is_none(self): - transport = transports.Transport() + transport = asyncio.Transport() self.assertEqual(transport._extra, {}) def test_get_extra_info(self): - transport = transports.Transport({'extra': 'info'}) + transport = asyncio.Transport({'extra': 'info'}) self.assertEqual('info', transport.get_extra_info('extra')) self.assertIsNone(transport.get_extra_info('unknown')) @@ -21,15 +22,21 @@ def test_get_extra_info(self): self.assertIs(default, transport.get_extra_info('unknown', default)) def test_writelines(self): - transport = transports.Transport() - transport.write = unittest.mock.Mock() + transport = asyncio.Transport() + transport.write = mock.Mock() - transport.writelines(['line1', 'line2', 'line3']) - self.assertEqual(3, transport.write.call_count) + transport.writelines([b'line1', + bytearray(b'line2'), + memoryview(b'line3')]) + self.assertEqual(1, transport.write.call_count) + transport.write.assert_called_with(b'line1line2line3') def test_not_implemented(self): - transport = transports.Transport() + transport = asyncio.Transport() + self.assertRaises(NotImplementedError, + transport.set_write_buffer_limits) + self.assertRaises(NotImplementedError, transport.get_write_buffer_size) self.assertRaises(NotImplementedError, transport.write, 'data') self.assertRaises(NotImplementedError, transport.write_eof) self.assertRaises(NotImplementedError, transport.can_write_eof) @@ -39,13 +46,13 @@ def test_not_implemented(self): self.assertRaises(NotImplementedError, transport.abort) def test_dgram_not_implemented(self): - transport = transports.DatagramTransport() + transport = asyncio.DatagramTransport() self.assertRaises(NotImplementedError, transport.sendto, 'data') self.assertRaises(NotImplementedError, transport.abort) def test_subprocess_transport_not_implemented(self): - transport = transports.SubprocessTransport() + transport = asyncio.SubprocessTransport() self.assertRaises(NotImplementedError, transport.get_pid) self.assertRaises(NotImplementedError, transport.get_returncode) @@ -54,6 +61,31 @@ def test_subprocess_transport_not_implemented(self): self.assertRaises(NotImplementedError, transport.terminate) self.assertRaises(NotImplementedError, transport.kill) + def test_flowcontrol_mixin_set_write_limits(self): + + class MyTransport(transports._FlowControlMixin, + transports.Transport): + + def get_write_buffer_size(self): + return 512 + + loop = mock.Mock() + transport = MyTransport(loop=loop) + transport._protocol = mock.Mock() + + self.assertFalse(transport._protocol_paused) + + with self.assertRaisesRegex(ValueError, 'high.*must be >= low'): + transport.set_write_buffer_limits(high=0, low=1) + + transport.set_write_buffer_limits(high=1024, low=128) + self.assertFalse(transport._protocol_paused) + self.assertEqual(transport.get_write_buffer_limits(), (128, 1024)) + + transport.set_write_buffer_limits(high=256, low=128) + self.assertTrue(transport._protocol_paused) + self.assertEqual(transport.get_write_buffer_limits(), (128, 256)) + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_asyncio/test_unix_events.py b/Lib/test/test_asyncio/test_unix_events.py index 98cf407959de..dc0835c527d1 100644 --- a/Lib/test/test_asyncio/test_unix_events.py +++ b/Lib/test/test_asyncio/test_unix_events.py @@ -1,38 +1,46 @@ """Tests for unix_events.py.""" import collections -import gc import errno import io import os -import pprint import signal +import socket import stat import sys +import tempfile import threading import unittest -import unittest.mock +from unittest import mock if sys.platform == 'win32': raise unittest.SkipTest('UNIX only') -from asyncio import events -from asyncio import futures -from asyncio import protocols +import asyncio +from asyncio import log from asyncio import test_utils from asyncio import unix_events +MOCK_ANY = mock.ANY + + +def close_pipe_transport(transport): + # Don't call transport.close() because the event loop and the selector + # are mocked + if transport._pipe is None: + return + transport._pipe.close() + transport._pipe = None + + @unittest.skipUnless(signal, 'Signals are not supported') -class SelectorEventLoopTests(unittest.TestCase): +class SelectorEventLoopSignalTests(test_utils.TestCase): def setUp(self): - self.loop = unix_events.SelectorEventLoop() - events.set_event_loop(None) - - def tearDown(self): - self.loop.close() + self.loop = asyncio.SelectorEventLoop() + self.set_event_loop(self.loop) def test_check_signal(self): self.assertRaises( @@ -41,17 +49,18 @@ def test_check_signal(self): ValueError, self.loop._check_signal, signal.NSIG + 1) def test_handle_signal_no_handler(self): - self.loop._handle_signal(signal.NSIG + 1, ()) + self.loop._handle_signal(signal.NSIG + 1) def test_handle_signal_cancelled_handler(self): - h = events.Handle(unittest.mock.Mock(), ()) + h = asyncio.Handle(mock.Mock(), (), + loop=mock.Mock()) h.cancel() self.loop._signal_handlers[signal.NSIG + 1] = h - self.loop.remove_signal_handler = unittest.mock.Mock() - self.loop._handle_signal(signal.NSIG + 1, ()) + self.loop.remove_signal_handler = mock.Mock() + self.loop._handle_signal(signal.NSIG + 1) self.loop.remove_signal_handler.assert_called_with(signal.NSIG + 1) - @unittest.mock.patch('asyncio.unix_events.signal') + @mock.patch('asyncio.unix_events.signal') def test_add_signal_handler_setup_error(self, m_signal): m_signal.NSIG = signal.NSIG m_signal.set_wakeup_fd.side_effect = ValueError @@ -61,17 +70,35 @@ def test_add_signal_handler_setup_error(self, m_signal): self.loop.add_signal_handler, signal.SIGINT, lambda: True) - @unittest.mock.patch('asyncio.unix_events.signal') + @mock.patch('asyncio.unix_events.signal') + def test_add_signal_handler_coroutine_error(self, m_signal): + m_signal.NSIG = signal.NSIG + + @asyncio.coroutine + def simple_coroutine(): + yield from [] + + # callback must not be a coroutine function + coro_func = simple_coroutine + coro_obj = coro_func() + self.addCleanup(coro_obj.close) + for func in (coro_func, coro_obj): + self.assertRaisesRegex( + TypeError, 'coroutines cannot be used with add_signal_handler', + self.loop.add_signal_handler, + signal.SIGINT, func) + + @mock.patch('asyncio.unix_events.signal') def test_add_signal_handler(self, m_signal): m_signal.NSIG = signal.NSIG cb = lambda: True self.loop.add_signal_handler(signal.SIGHUP, cb) h = self.loop._signal_handlers.get(signal.SIGHUP) - self.assertIsInstance(h, events.Handle) + self.assertIsInstance(h, asyncio.Handle) self.assertEqual(h._callback, cb) - @unittest.mock.patch('asyncio.unix_events.signal') + @mock.patch('asyncio.unix_events.signal') def test_add_signal_handler_install_error(self, m_signal): m_signal.NSIG = signal.NSIG @@ -89,8 +116,8 @@ class Err(OSError): self.loop.add_signal_handler, signal.SIGINT, lambda: True) - @unittest.mock.patch('asyncio.unix_events.signal') - @unittest.mock.patch('asyncio.unix_events.logger') + @mock.patch('asyncio.unix_events.signal') + @mock.patch('asyncio.base_events.logger') def test_add_signal_handler_install_error2(self, m_logging, m_signal): m_signal.NSIG = signal.NSIG @@ -106,8 +133,8 @@ class Err(OSError): self.assertFalse(m_logging.info.called) self.assertEqual(1, m_signal.set_wakeup_fd.call_count) - @unittest.mock.patch('asyncio.unix_events.signal') - @unittest.mock.patch('asyncio.unix_events.logger') + @mock.patch('asyncio.unix_events.signal') + @mock.patch('asyncio.base_events.logger') def test_add_signal_handler_install_error3(self, m_logging, m_signal): class Err(OSError): errno = errno.EINVAL @@ -121,7 +148,7 @@ class Err(OSError): self.assertFalse(m_logging.info.called) self.assertEqual(2, m_signal.set_wakeup_fd.call_count) - @unittest.mock.patch('asyncio.unix_events.signal') + @mock.patch('asyncio.unix_events.signal') def test_remove_signal_handler(self, m_signal): m_signal.NSIG = signal.NSIG @@ -134,7 +161,7 @@ def test_remove_signal_handler(self, m_signal): self.assertEqual( (signal.SIGHUP, m_signal.SIG_DFL), m_signal.signal.call_args[0]) - @unittest.mock.patch('asyncio.unix_events.signal') + @mock.patch('asyncio.unix_events.signal') def test_remove_signal_handler_2(self, m_signal): m_signal.NSIG = signal.NSIG m_signal.SIGINT = signal.SIGINT @@ -151,8 +178,8 @@ def test_remove_signal_handler_2(self, m_signal): (signal.SIGINT, m_signal.default_int_handler), m_signal.signal.call_args[0]) - @unittest.mock.patch('asyncio.unix_events.signal') - @unittest.mock.patch('asyncio.unix_events.logger') + @mock.patch('asyncio.unix_events.signal') + @mock.patch('asyncio.base_events.logger') def test_remove_signal_handler_cleanup_error(self, m_logging, m_signal): m_signal.NSIG = signal.NSIG self.loop.add_signal_handler(signal.SIGHUP, lambda: True) @@ -162,7 +189,7 @@ def test_remove_signal_handler_cleanup_error(self, m_logging, m_signal): self.loop.remove_signal_handler(signal.SIGHUP) self.assertTrue(m_logging.info) - @unittest.mock.patch('asyncio.unix_events.signal') + @mock.patch('asyncio.unix_events.signal') def test_remove_signal_handler_error(self, m_signal): m_signal.NSIG = signal.NSIG self.loop.add_signal_handler(signal.SIGHUP, lambda: True) @@ -172,7 +199,7 @@ def test_remove_signal_handler_error(self, m_signal): self.assertRaises( OSError, self.loop.remove_signal_handler, signal.SIGHUP) - @unittest.mock.patch('asyncio.unix_events.signal') + @mock.patch('asyncio.unix_events.signal') def test_remove_signal_handler_error2(self, m_signal): m_signal.NSIG = signal.NSIG self.loop.add_signal_handler(signal.SIGHUP, lambda: True) @@ -184,7 +211,7 @@ class Err(OSError): self.assertRaises( RuntimeError, self.loop.remove_signal_handler, signal.SIGHUP) - @unittest.mock.patch('asyncio.unix_events.signal') + @mock.patch('asyncio.unix_events.signal') def test_close(self, m_signal): m_signal.NSIG = signal.NSIG @@ -201,53 +228,148 @@ def test_close(self, m_signal): m_signal.set_wakeup_fd.assert_called_once_with(-1) -class UnixReadPipeTransportTests(unittest.TestCase): +@unittest.skipUnless(hasattr(socket, 'AF_UNIX'), + 'UNIX Sockets are not supported') +class SelectorEventLoopUnixSocketTests(test_utils.TestCase): + + def setUp(self): + self.loop = asyncio.SelectorEventLoop() + self.set_event_loop(self.loop) + + def test_create_unix_server_existing_path_sock(self): + with test_utils.unix_socket_path() as path: + sock = socket.socket(socket.AF_UNIX) + sock.bind(path) + with sock: + coro = self.loop.create_unix_server(lambda: None, path) + with self.assertRaisesRegex(OSError, + 'Address.*is already in use'): + self.loop.run_until_complete(coro) + + def test_create_unix_server_existing_path_nonsock(self): + with tempfile.NamedTemporaryFile() as file: + coro = self.loop.create_unix_server(lambda: None, file.name) + with self.assertRaisesRegex(OSError, + 'Address.*is already in use'): + self.loop.run_until_complete(coro) + + def test_create_unix_server_ssl_bool(self): + coro = self.loop.create_unix_server(lambda: None, path='spam', + ssl=True) + with self.assertRaisesRegex(TypeError, + 'ssl argument must be an SSLContext'): + self.loop.run_until_complete(coro) + + def test_create_unix_server_nopath_nosock(self): + coro = self.loop.create_unix_server(lambda: None, path=None) + with self.assertRaisesRegex(ValueError, + 'path was not specified, and no sock'): + self.loop.run_until_complete(coro) + + def test_create_unix_server_path_inetsock(self): + sock = socket.socket() + with sock: + coro = self.loop.create_unix_server(lambda: None, path=None, + sock=sock) + with self.assertRaisesRegex(ValueError, + 'A UNIX Domain Socket was expected'): + self.loop.run_until_complete(coro) + + @mock.patch('asyncio.unix_events.socket') + def test_create_unix_server_bind_error(self, m_socket): + # Ensure that the socket is closed on any bind error + sock = mock.Mock() + m_socket.socket.return_value = sock + + sock.bind.side_effect = OSError + coro = self.loop.create_unix_server(lambda: None, path="/test") + with self.assertRaises(OSError): + self.loop.run_until_complete(coro) + self.assertTrue(sock.close.called) + + sock.bind.side_effect = MemoryError + coro = self.loop.create_unix_server(lambda: None, path="/test") + with self.assertRaises(MemoryError): + self.loop.run_until_complete(coro) + self.assertTrue(sock.close.called) + + def test_create_unix_connection_path_sock(self): + coro = self.loop.create_unix_connection( + lambda: None, os.devnull, sock=object()) + with self.assertRaisesRegex(ValueError, 'path and sock can not be'): + self.loop.run_until_complete(coro) + + def test_create_unix_connection_nopath_nosock(self): + coro = self.loop.create_unix_connection( + lambda: None, None) + with self.assertRaisesRegex(ValueError, + 'no path and sock were specified'): + self.loop.run_until_complete(coro) + + def test_create_unix_connection_nossl_serverhost(self): + coro = self.loop.create_unix_connection( + lambda: None, os.devnull, server_hostname='spam') + with self.assertRaisesRegex(ValueError, + 'server_hostname is only meaningful'): + self.loop.run_until_complete(coro) + + def test_create_unix_connection_ssl_noserverhost(self): + coro = self.loop.create_unix_connection( + lambda: None, os.devnull, ssl=True) + + with self.assertRaisesRegex( + ValueError, 'you have to pass server_hostname when using ssl'): + + self.loop.run_until_complete(coro) + + +class UnixReadPipeTransportTests(test_utils.TestCase): def setUp(self): - self.loop = test_utils.TestLoop() - self.protocol = test_utils.make_test_protocol(protocols.Protocol) - self.pipe = unittest.mock.Mock(spec_set=io.RawIOBase) + self.loop = self.new_test_loop() + self.protocol = test_utils.make_test_protocol(asyncio.Protocol) + self.pipe = mock.Mock(spec_set=io.RawIOBase) self.pipe.fileno.return_value = 5 - fcntl_patcher = unittest.mock.patch('fcntl.fcntl') - fcntl_patcher.start() - self.addCleanup(fcntl_patcher.stop) + blocking_patcher = mock.patch('asyncio.unix_events._set_nonblocking') + blocking_patcher.start() + self.addCleanup(blocking_patcher.stop) - fstat_patcher = unittest.mock.patch('os.fstat') + fstat_patcher = mock.patch('os.fstat') m_fstat = fstat_patcher.start() - st = unittest.mock.Mock() + st = mock.Mock() st.st_mode = stat.S_IFIFO m_fstat.return_value = st self.addCleanup(fstat_patcher.stop) + def read_pipe_transport(self, waiter=None): + transport = unix_events._UnixReadPipeTransport(self.loop, self.pipe, + self.protocol, + waiter=waiter) + self.addCleanup(close_pipe_transport, transport) + return transport + def test_ctor(self): - tr = unix_events._UnixReadPipeTransport( - self.loop, self.pipe, self.protocol) - self.loop.assert_reader(5, tr._read_ready) - test_utils.run_briefly(self.loop) - self.protocol.connection_made.assert_called_with(tr) + waiter = asyncio.Future(loop=self.loop) + tr = self.read_pipe_transport(waiter=waiter) + self.loop.run_until_complete(waiter) - def test_ctor_with_waiter(self): - fut = futures.Future(loop=self.loop) - unix_events._UnixReadPipeTransport( - self.loop, self.pipe, self.protocol, fut) - test_utils.run_briefly(self.loop) - self.assertIsNone(fut.result()) + self.protocol.connection_made.assert_called_with(tr) + self.loop.assert_reader(5, tr._read_ready) + self.assertIsNone(waiter.result()) - @unittest.mock.patch('os.read') + @mock.patch('os.read') def test__read_ready(self, m_read): - tr = unix_events._UnixReadPipeTransport( - self.loop, self.pipe, self.protocol) + tr = self.read_pipe_transport() m_read.return_value = b'data' tr._read_ready() m_read.assert_called_with(5, tr.max_size) self.protocol.data_received.assert_called_with(b'data') - @unittest.mock.patch('os.read') + @mock.patch('os.read') def test__read_ready_eof(self, m_read): - tr = unix_events._UnixReadPipeTransport( - self.loop, self.pipe, self.protocol) + tr = self.read_pipe_transport() m_read.return_value = b'' tr._read_ready() @@ -257,10 +379,9 @@ def test__read_ready_eof(self, m_read): self.protocol.eof_received.assert_called_with() self.protocol.connection_lost.assert_called_with(None) - @unittest.mock.patch('os.read') + @mock.patch('os.read') def test__read_ready_blocked(self, m_read): - tr = unix_events._UnixReadPipeTransport( - self.loop, self.pipe, self.protocol) + tr = self.read_pipe_transport() m_read.side_effect = BlockingIOError tr._read_ready() @@ -268,62 +389,55 @@ def test__read_ready_blocked(self, m_read): test_utils.run_briefly(self.loop) self.assertFalse(self.protocol.data_received.called) - @unittest.mock.patch('asyncio.log.logger.exception') - @unittest.mock.patch('os.read') + @mock.patch('asyncio.log.logger.error') + @mock.patch('os.read') def test__read_ready_error(self, m_read, m_logexc): - tr = unix_events._UnixReadPipeTransport( - self.loop, self.pipe, self.protocol) + tr = self.read_pipe_transport() err = OSError() m_read.side_effect = err - tr._close = unittest.mock.Mock() + tr._close = mock.Mock() tr._read_ready() m_read.assert_called_with(5, tr.max_size) tr._close.assert_called_with(err) - m_logexc.assert_called_with('Fatal error for %s', tr) + m_logexc.assert_called_with( + test_utils.MockPattern( + 'Fatal read error on pipe transport' + '\nprotocol:.*\ntransport:.*'), + exc_info=(OSError, MOCK_ANY, MOCK_ANY)) - @unittest.mock.patch('os.read') + @mock.patch('os.read') def test_pause_reading(self, m_read): - tr = unix_events._UnixReadPipeTransport( - self.loop, self.pipe, self.protocol) - - m = unittest.mock.Mock() + tr = self.read_pipe_transport() + m = mock.Mock() self.loop.add_reader(5, m) tr.pause_reading() self.assertFalse(self.loop.readers) - @unittest.mock.patch('os.read') + @mock.patch('os.read') def test_resume_reading(self, m_read): - tr = unix_events._UnixReadPipeTransport( - self.loop, self.pipe, self.protocol) - + tr = self.read_pipe_transport() tr.resume_reading() self.loop.assert_reader(5, tr._read_ready) - @unittest.mock.patch('os.read') + @mock.patch('os.read') def test_close(self, m_read): - tr = unix_events._UnixReadPipeTransport( - self.loop, self.pipe, self.protocol) - - tr._close = unittest.mock.Mock() + tr = self.read_pipe_transport() + tr._close = mock.Mock() tr.close() tr._close.assert_called_with(None) - @unittest.mock.patch('os.read') + @mock.patch('os.read') def test_close_already_closing(self, m_read): - tr = unix_events._UnixReadPipeTransport( - self.loop, self.pipe, self.protocol) - + tr = self.read_pipe_transport() tr._closing = True - tr._close = unittest.mock.Mock() + tr._close = mock.Mock() tr.close() self.assertFalse(tr._close.called) - @unittest.mock.patch('os.read') + @mock.patch('os.read') def test__close(self, m_read): - tr = unix_events._UnixReadPipeTransport( - self.loop, self.pipe, self.protocol) - + tr = self.read_pipe_transport() err = object() tr._close(err) self.assertTrue(tr._closing) @@ -332,8 +446,9 @@ def test__close(self, m_read): self.protocol.connection_lost.assert_called_with(err) def test__call_connection_lost(self): - tr = unix_events._UnixReadPipeTransport( - self.loop, self.pipe, self.protocol) + tr = self.read_pipe_transport() + self.assertIsNotNone(tr._protocol) + self.assertIsNotNone(tr._loop) err = None tr._call_connection_lost(err) @@ -341,15 +456,12 @@ def test__call_connection_lost(self): self.pipe.close.assert_called_with() self.assertIsNone(tr._protocol) - self.assertEqual(2, sys.getrefcount(self.protocol), - pprint.pformat(gc.get_referrers(self.protocol))) self.assertIsNone(tr._loop) - self.assertEqual(2, sys.getrefcount(self.loop), - pprint.pformat(gc.get_referrers(self.loop))) def test__call_connection_lost_with_err(self): - tr = unix_events._UnixReadPipeTransport( - self.loop, self.pipe, self.protocol) + tr = self.read_pipe_transport() + self.assertIsNotNone(tr._protocol) + self.assertIsNotNone(tr._loop) err = OSError() tr._call_connection_lost(err) @@ -357,89 +469,77 @@ def test__call_connection_lost_with_err(self): self.pipe.close.assert_called_with() self.assertIsNone(tr._protocol) - self.assertEqual(2, sys.getrefcount(self.protocol), - pprint.pformat(gc.get_referrers(self.protocol))) self.assertIsNone(tr._loop) - self.assertEqual(2, sys.getrefcount(self.loop), - pprint.pformat(gc.get_referrers(self.loop))) -class UnixWritePipeTransportTests(unittest.TestCase): +class UnixWritePipeTransportTests(test_utils.TestCase): def setUp(self): - self.loop = test_utils.TestLoop() - self.protocol = test_utils.make_test_protocol(protocols.BaseProtocol) - self.pipe = unittest.mock.Mock(spec_set=io.RawIOBase) + self.loop = self.new_test_loop() + self.protocol = test_utils.make_test_protocol(asyncio.BaseProtocol) + self.pipe = mock.Mock(spec_set=io.RawIOBase) self.pipe.fileno.return_value = 5 - fcntl_patcher = unittest.mock.patch('fcntl.fcntl') - fcntl_patcher.start() - self.addCleanup(fcntl_patcher.stop) + blocking_patcher = mock.patch('asyncio.unix_events._set_nonblocking') + blocking_patcher.start() + self.addCleanup(blocking_patcher.stop) - fstat_patcher = unittest.mock.patch('os.fstat') + fstat_patcher = mock.patch('os.fstat') m_fstat = fstat_patcher.start() - st = unittest.mock.Mock() + st = mock.Mock() st.st_mode = stat.S_IFSOCK m_fstat.return_value = st self.addCleanup(fstat_patcher.stop) + def write_pipe_transport(self, waiter=None): + transport = unix_events._UnixWritePipeTransport(self.loop, self.pipe, + self.protocol, + waiter=waiter) + self.addCleanup(close_pipe_transport, transport) + return transport + def test_ctor(self): - tr = unix_events._UnixWritePipeTransport( - self.loop, self.pipe, self.protocol) - self.loop.assert_reader(5, tr._read_ready) - test_utils.run_briefly(self.loop) - self.protocol.connection_made.assert_called_with(tr) + waiter = asyncio.Future(loop=self.loop) + tr = self.write_pipe_transport(waiter=waiter) + self.loop.run_until_complete(waiter) - def test_ctor_with_waiter(self): - fut = futures.Future(loop=self.loop) - tr = unix_events._UnixWritePipeTransport( - self.loop, self.pipe, self.protocol, fut) + self.protocol.connection_made.assert_called_with(tr) self.loop.assert_reader(5, tr._read_ready) - test_utils.run_briefly(self.loop) - self.assertEqual(None, fut.result()) + self.assertEqual(None, waiter.result()) def test_can_write_eof(self): - tr = unix_events._UnixWritePipeTransport( - self.loop, self.pipe, self.protocol) + tr = self.write_pipe_transport() self.assertTrue(tr.can_write_eof()) - @unittest.mock.patch('os.write') + @mock.patch('os.write') def test_write(self, m_write): - tr = unix_events._UnixWritePipeTransport( - self.loop, self.pipe, self.protocol) - + tr = self.write_pipe_transport() m_write.return_value = 4 tr.write(b'data') m_write.assert_called_with(5, b'data') self.assertFalse(self.loop.writers) self.assertEqual([], tr._buffer) - @unittest.mock.patch('os.write') + @mock.patch('os.write') def test_write_no_data(self, m_write): - tr = unix_events._UnixWritePipeTransport( - self.loop, self.pipe, self.protocol) - + tr = self.write_pipe_transport() tr.write(b'') self.assertFalse(m_write.called) self.assertFalse(self.loop.writers) self.assertEqual([], tr._buffer) - @unittest.mock.patch('os.write') + @mock.patch('os.write') def test_write_partial(self, m_write): - tr = unix_events._UnixWritePipeTransport( - self.loop, self.pipe, self.protocol) - + tr = self.write_pipe_transport() m_write.return_value = 2 tr.write(b'data') m_write.assert_called_with(5, b'data') self.loop.assert_writer(5, tr._write_ready) self.assertEqual([b'ta'], tr._buffer) - @unittest.mock.patch('os.write') + @mock.patch('os.write') def test_write_buffer(self, m_write): - tr = unix_events._UnixWritePipeTransport( - self.loop, self.pipe, self.protocol) - + tr = self.write_pipe_transport() self.loop.add_writer(5, tr._write_ready) tr._buffer = [b'previous'] tr.write(b'data') @@ -447,31 +547,29 @@ def test_write_buffer(self, m_write): self.loop.assert_writer(5, tr._write_ready) self.assertEqual([b'previous', b'data'], tr._buffer) - @unittest.mock.patch('os.write') + @mock.patch('os.write') def test_write_again(self, m_write): - tr = unix_events._UnixWritePipeTransport( - self.loop, self.pipe, self.protocol) - + tr = self.write_pipe_transport() m_write.side_effect = BlockingIOError() tr.write(b'data') m_write.assert_called_with(5, b'data') self.loop.assert_writer(5, tr._write_ready) self.assertEqual([b'data'], tr._buffer) - @unittest.mock.patch('asyncio.unix_events.logger') - @unittest.mock.patch('os.write') + @mock.patch('asyncio.unix_events.logger') + @mock.patch('os.write') def test_write_err(self, m_write, m_log): - tr = unix_events._UnixWritePipeTransport( - self.loop, self.pipe, self.protocol) - + tr = self.write_pipe_transport() err = OSError() m_write.side_effect = err - tr._fatal_error = unittest.mock.Mock() + tr._fatal_error = mock.Mock() tr.write(b'data') m_write.assert_called_with(5, b'data') self.assertFalse(self.loop.writers) self.assertEqual([], tr._buffer) - tr._fatal_error.assert_called_with(err) + tr._fatal_error.assert_called_with( + err, + 'Fatal write error on pipe transport') self.assertEqual(1, tr._conn_lost) tr.write(b'data') @@ -483,11 +581,11 @@ def test_write_err(self, m_write, m_log): # This is a bit overspecified. :-( m_log.warning.assert_called_with( 'pipe closed by peer or os.write(pipe, data) raised exception.') + tr.close() - @unittest.mock.patch('os.write') + @mock.patch('os.write') def test_write_close(self, m_write): - tr = unix_events._UnixWritePipeTransport( - self.loop, self.pipe, self.protocol) + tr = self.write_pipe_transport() tr._read_ready() # pipe was closed by peer tr.write(b'data') @@ -496,8 +594,7 @@ def test_write_close(self, m_write): self.assertEqual(tr._conn_lost, 2) def test__read_ready(self): - tr = unix_events._UnixWritePipeTransport(self.loop, self.pipe, - self.protocol) + tr = self.write_pipe_transport() tr._read_ready() self.assertFalse(self.loop.readers) self.assertFalse(self.loop.writers) @@ -505,10 +602,9 @@ def test__read_ready(self): test_utils.run_briefly(self.loop) self.protocol.connection_lost.assert_called_with(None) - @unittest.mock.patch('os.write') + @mock.patch('os.write') def test__write_ready(self, m_write): - tr = unix_events._UnixWritePipeTransport( - self.loop, self.pipe, self.protocol) + tr = self.write_pipe_transport() self.loop.add_writer(5, tr._write_ready) tr._buffer = [b'da', b'ta'] m_write.return_value = 4 @@ -517,11 +613,9 @@ def test__write_ready(self, m_write): self.assertFalse(self.loop.writers) self.assertEqual([], tr._buffer) - @unittest.mock.patch('os.write') + @mock.patch('os.write') def test__write_ready_partial(self, m_write): - tr = unix_events._UnixWritePipeTransport( - self.loop, self.pipe, self.protocol) - + tr = self.write_pipe_transport() self.loop.add_writer(5, tr._write_ready) tr._buffer = [b'da', b'ta'] m_write.return_value = 3 @@ -530,11 +624,9 @@ def test__write_ready_partial(self, m_write): self.loop.assert_writer(5, tr._write_ready) self.assertEqual([b'a'], tr._buffer) - @unittest.mock.patch('os.write') + @mock.patch('os.write') def test__write_ready_again(self, m_write): - tr = unix_events._UnixWritePipeTransport( - self.loop, self.pipe, self.protocol) - + tr = self.write_pipe_transport() self.loop.add_writer(5, tr._write_ready) tr._buffer = [b'da', b'ta'] m_write.side_effect = BlockingIOError() @@ -543,11 +635,9 @@ def test__write_ready_again(self, m_write): self.loop.assert_writer(5, tr._write_ready) self.assertEqual([b'data'], tr._buffer) - @unittest.mock.patch('os.write') + @mock.patch('os.write') def test__write_ready_empty(self, m_write): - tr = unix_events._UnixWritePipeTransport( - self.loop, self.pipe, self.protocol) - + tr = self.write_pipe_transport() self.loop.add_writer(5, tr._write_ready) tr._buffer = [b'da', b'ta'] m_write.return_value = 0 @@ -556,12 +646,10 @@ def test__write_ready_empty(self, m_write): self.loop.assert_writer(5, tr._write_ready) self.assertEqual([b'data'], tr._buffer) - @unittest.mock.patch('asyncio.log.logger.exception') - @unittest.mock.patch('os.write') + @mock.patch('asyncio.log.logger.error') + @mock.patch('os.write') def test__write_ready_err(self, m_write, m_logexc): - tr = unix_events._UnixWritePipeTransport( - self.loop, self.pipe, self.protocol) - + tr = self.write_pipe_transport() self.loop.add_writer(5, tr._write_ready) tr._buffer = [b'da', b'ta'] m_write.side_effect = err = OSError() @@ -571,16 +659,18 @@ def test__write_ready_err(self, m_write, m_logexc): self.assertFalse(self.loop.readers) self.assertEqual([], tr._buffer) self.assertTrue(tr._closing) - m_logexc.assert_called_with('Fatal error for %s', tr) + m_logexc.assert_called_with( + test_utils.MockPattern( + 'Fatal write error on pipe transport' + '\nprotocol:.*\ntransport:.*'), + exc_info=(OSError, MOCK_ANY, MOCK_ANY)) self.assertEqual(1, tr._conn_lost) test_utils.run_briefly(self.loop) self.protocol.connection_lost.assert_called_with(err) - @unittest.mock.patch('os.write') + @mock.patch('os.write') def test__write_ready_closing(self, m_write): - tr = unix_events._UnixWritePipeTransport( - self.loop, self.pipe, self.protocol) - + tr = self.write_pipe_transport() self.loop.add_writer(5, tr._write_ready) tr._closing = True tr._buffer = [b'da', b'ta'] @@ -593,11 +683,9 @@ def test__write_ready_closing(self, m_write): self.protocol.connection_lost.assert_called_with(None) self.pipe.close.assert_called_with() - @unittest.mock.patch('os.write') + @mock.patch('os.write') def test_abort(self, m_write): - tr = unix_events._UnixWritePipeTransport( - self.loop, self.pipe, self.protocol) - + tr = self.write_pipe_transport() self.loop.add_writer(5, tr._write_ready) self.loop.add_reader(5, tr._read_ready) tr._buffer = [b'da', b'ta'] @@ -611,8 +699,9 @@ def test_abort(self, m_write): self.protocol.connection_lost.assert_called_with(None) def test__call_connection_lost(self): - tr = unix_events._UnixWritePipeTransport( - self.loop, self.pipe, self.protocol) + tr = self.write_pipe_transport() + self.assertIsNotNone(tr._protocol) + self.assertIsNotNone(tr._loop) err = None tr._call_connection_lost(err) @@ -620,15 +709,12 @@ def test__call_connection_lost(self): self.pipe.close.assert_called_with() self.assertIsNone(tr._protocol) - self.assertEqual(2, sys.getrefcount(self.protocol), - pprint.pformat(gc.get_referrers(self.protocol))) self.assertIsNone(tr._loop) - self.assertEqual(2, sys.getrefcount(self.loop), - pprint.pformat(gc.get_referrers(self.loop))) def test__call_connection_lost_with_err(self): - tr = unix_events._UnixWritePipeTransport( - self.loop, self.pipe, self.protocol) + tr = self.write_pipe_transport() + self.assertIsNotNone(tr._protocol) + self.assertIsNotNone(tr._loop) err = OSError() tr._call_connection_lost(err) @@ -636,33 +722,26 @@ def test__call_connection_lost_with_err(self): self.pipe.close.assert_called_with() self.assertIsNone(tr._protocol) - self.assertEqual(2, sys.getrefcount(self.protocol), - pprint.pformat(gc.get_referrers(self.protocol))) self.assertIsNone(tr._loop) - self.assertEqual(2, sys.getrefcount(self.loop), - pprint.pformat(gc.get_referrers(self.loop))) def test_close(self): - tr = unix_events._UnixWritePipeTransport( - self.loop, self.pipe, self.protocol) - - tr.write_eof = unittest.mock.Mock() + tr = self.write_pipe_transport() + tr.write_eof = mock.Mock() tr.close() tr.write_eof.assert_called_with() - def test_close_closing(self): - tr = unix_events._UnixWritePipeTransport( - self.loop, self.pipe, self.protocol) + # closing the transport twice must not fail + tr.close() - tr.write_eof = unittest.mock.Mock() + def test_close_closing(self): + tr = self.write_pipe_transport() + tr.write_eof = mock.Mock() tr._closing = True tr.close() self.assertFalse(tr.write_eof.called) def test_write_eof(self): - tr = unix_events._UnixWritePipeTransport( - self.loop, self.pipe, self.protocol) - + tr = self.write_pipe_transport() tr.write_eof() self.assertTrue(tr._closing) self.assertFalse(self.loop.readers) @@ -670,8 +749,7 @@ def test_write_eof(self): self.protocol.connection_lost.assert_called_with(None) def test_write_eof_pending(self): - tr = unix_events._UnixWritePipeTransport( - self.loop, self.pipe, self.protocol) + tr = self.write_pipe_transport() tr._buffer = [b'data'] tr.write_eof() self.assertTrue(tr._closing) @@ -681,8 +759,8 @@ def test_write_eof_pending(self): class AbstractChildWatcherTests(unittest.TestCase): def test_not_implemented(self): - f = unittest.mock.Mock() - watcher = unix_events.AbstractChildWatcher() + f = mock.Mock() + watcher = asyncio.AbstractChildWatcher() self.assertRaises( NotImplementedError, watcher.add_child_handler, f, f) self.assertRaises( @@ -700,7 +778,7 @@ def test_not_implemented(self): class BaseChildWatcherTests(unittest.TestCase): def test_not_implemented(self): - f = unittest.mock.Mock() + f = mock.Mock() watcher = unix_events.BaseChildWatcher() self.assertRaises( NotImplementedError, watcher._do_waitpid, f) @@ -717,20 +795,20 @@ def test_not_implemented(self): class ChildWatcherTestsMixin: - ignore_warnings = unittest.mock.patch.object(unix_events.logger, "warning") + ignore_warnings = mock.patch.object(log.logger, "warning") def setUp(self): - self.loop = test_utils.TestLoop() + self.loop = self.new_test_loop() self.running = False self.zombies = {} - with unittest.mock.patch.object( + with mock.patch.object( self.loop, "add_signal_handler") as self.m_add_signal_handler: self.watcher = self.create_watcher() self.watcher.attach_loop(self.loop) def waitpid(self, pid, flags): - if isinstance(self.watcher, unix_events.SafeChildWatcher) or pid != -1: + if isinstance(self.watcher, asyncio.SafeChildWatcher) or pid != -1: self.assertGreater(pid, 0) try: if pid < 0: @@ -768,8 +846,8 @@ def test_create_watcher(self): def waitpid_mocks(func): def wrapped_func(self): def patch(target, wrapper): - return unittest.mock.patch(target, wraps=wrapper, - new_callable=unittest.mock.Mock) + return mock.patch(target, wraps=wrapper, + new_callable=mock.Mock) with patch('os.WTERMSIG', self.WTERMSIG) as m_WTERMSIG, \ patch('os.WEXITSTATUS', self.WEXITSTATUS) as m_WEXITSTATUS, \ @@ -785,7 +863,7 @@ def patch(target, wrapper): @waitpid_mocks def test_sigchld(self, m): # register a child - callback = unittest.mock.Mock() + callback = mock.Mock() with self.watcher: self.running = True @@ -845,8 +923,8 @@ def test_sigchld(self, m): @waitpid_mocks def test_sigchld_two_children(self, m): - callback1 = unittest.mock.Mock() - callback2 = unittest.mock.Mock() + callback1 = mock.Mock() + callback2 = mock.Mock() # register child 1 with self.watcher: @@ -871,7 +949,7 @@ def test_sigchld_two_children(self, m): self.assertFalse(m.WEXITSTATUS.called) self.assertFalse(m.WTERMSIG.called) - # childen are running + # children are running self.watcher._sig_chld() self.assertFalse(callback1.called) @@ -949,8 +1027,8 @@ def test_sigchld_two_children(self, m): @waitpid_mocks def test_sigchld_two_children_terminating_together(self, m): - callback1 = unittest.mock.Mock() - callback2 = unittest.mock.Mock() + callback1 = mock.Mock() + callback2 = mock.Mock() # register child 1 with self.watcher: @@ -975,7 +1053,7 @@ def test_sigchld_two_children_terminating_together(self, m): self.assertFalse(m.WEXITSTATUS.called) self.assertFalse(m.WTERMSIG.called) - # childen are running + # children are running self.watcher._sig_chld() self.assertFalse(callback1.called) @@ -1019,7 +1097,7 @@ def test_sigchld_two_children_terminating_together(self, m): @waitpid_mocks def test_sigchld_race_condition(self, m): # register a child - callback = unittest.mock.Mock() + callback = mock.Mock() with self.watcher: # child terminates before being registered @@ -1040,8 +1118,8 @@ def test_sigchld_race_condition(self, m): @waitpid_mocks def test_sigchld_replace_handler(self, m): - callback1 = unittest.mock.Mock() - callback2 = unittest.mock.Mock() + callback1 = mock.Mock() + callback2 = mock.Mock() # register a child with self.watcher: @@ -1093,7 +1171,7 @@ def test_sigchld_replace_handler(self, m): @waitpid_mocks def test_sigchld_remove_handler(self, m): - callback = unittest.mock.Mock() + callback = mock.Mock() # register a child with self.watcher: @@ -1125,7 +1203,7 @@ def test_sigchld_remove_handler(self, m): @waitpid_mocks def test_sigchld_unknown_status(self, m): - callback = unittest.mock.Mock() + callback = mock.Mock() # register a child with self.watcher: @@ -1162,9 +1240,9 @@ def test_sigchld_unknown_status(self, m): @waitpid_mocks def test_remove_child_handler(self, m): - callback1 = unittest.mock.Mock() - callback2 = unittest.mock.Mock() - callback3 = unittest.mock.Mock() + callback1 = mock.Mock() + callback2 = mock.Mock() + callback3 = mock.Mock() # register children with self.watcher: @@ -1195,7 +1273,7 @@ def test_remove_child_handler(self, m): @waitpid_mocks def test_sigchld_unhandled_exception(self, m): - callback = unittest.mock.Mock() + callback = mock.Mock() # register a child with self.watcher: @@ -1205,16 +1283,16 @@ def test_sigchld_unhandled_exception(self, m): # raise an exception m.waitpid.side_effect = ValueError - with unittest.mock.patch.object(unix_events.logger, - "exception") as m_exception: + with mock.patch.object(log.logger, + 'error') as m_error: self.assertEqual(self.watcher._sig_chld(), None) - self.assertTrue(m_exception.called) + self.assertTrue(m_error.called) @waitpid_mocks def test_sigchld_child_reaped_elsewhere(self, m): # register a child - callback = unittest.mock.Mock() + callback = mock.Mock() with self.watcher: self.running = True @@ -1239,8 +1317,7 @@ def test_sigchld_child_reaped_elsewhere(self, m): with self.ignore_warnings: self.watcher._sig_chld() - callback.assert_called(m.waitpid) - if isinstance(self.watcher, unix_events.FastChildWatcher): + if isinstance(self.watcher, asyncio.FastChildWatcher): # here the FastChildWatche enters a deadlock # (there is no way to prevent it) self.assertFalse(callback.called) @@ -1250,8 +1327,8 @@ def test_sigchld_child_reaped_elsewhere(self, m): @waitpid_mocks def test_sigchld_unknown_pid_during_registration(self, m): # register two children - callback1 = unittest.mock.Mock() - callback2 = unittest.mock.Mock() + callback1 = mock.Mock() + callback2 = mock.Mock() with self.ignore_warnings, self.watcher: self.running = True @@ -1271,7 +1348,7 @@ def test_sigchld_unknown_pid_during_registration(self, m): @waitpid_mocks def test_set_loop(self, m): # register a child - callback = unittest.mock.Mock() + callback = mock.Mock() with self.watcher: self.running = True @@ -1279,20 +1356,17 @@ def test_set_loop(self, m): # attach a new loop old_loop = self.loop - self.loop = test_utils.TestLoop() + self.loop = self.new_test_loop() + patch = mock.patch.object - with unittest.mock.patch.object( - old_loop, - "remove_signal_handler") as m_old_remove_signal_handler, \ - unittest.mock.patch.object( - self.loop, - "add_signal_handler") as m_new_add_signal_handler: + with patch(old_loop, "remove_signal_handler") as m_old_remove, \ + patch(self.loop, "add_signal_handler") as m_new_add: self.watcher.attach_loop(self.loop) - m_old_remove_signal_handler.assert_called_once_with( + m_old_remove.assert_called_once_with( signal.SIGCHLD) - m_new_add_signal_handler.assert_called_once_with( + m_new_add.assert_called_once_with( signal.SIGCHLD, self.watcher._sig_chld) # child terminates @@ -1305,9 +1379,9 @@ def test_set_loop(self, m): @waitpid_mocks def test_set_loop_race_condition(self, m): # register 3 children - callback1 = unittest.mock.Mock() - callback2 = unittest.mock.Mock() - callback3 = unittest.mock.Mock() + callback1 = mock.Mock() + callback2 = mock.Mock() + callback3 = mock.Mock() with self.watcher: self.running = True @@ -1319,7 +1393,7 @@ def test_set_loop_race_condition(self, m): old_loop = self.loop self.loop = None - with unittest.mock.patch.object( + with mock.patch.object( old_loop, "remove_signal_handler") as m_remove_signal_handler: self.watcher.attach_loop(None) @@ -1331,15 +1405,15 @@ def test_set_loop_race_condition(self, m): self.add_zombie(61, 11) self.add_zombie(62, -5) - # SIGCHLD was not catched + # SIGCHLD was not caught self.assertFalse(callback1.called) self.assertFalse(callback2.called) self.assertFalse(callback3.called) # attach a new loop - self.loop = test_utils.TestLoop() + self.loop = self.new_test_loop() - with unittest.mock.patch.object( + with mock.patch.object( self.loop, "add_signal_handler") as m_add_signal_handler: self.watcher.attach_loop(self.loop) @@ -1365,8 +1439,7 @@ def test_set_loop_race_condition(self, m): @waitpid_mocks def test_close(self, m): # register two children - callback1 = unittest.mock.Mock() - callback2 = unittest.mock.Mock() + callback1 = mock.Mock() with self.watcher: self.running = True @@ -1380,10 +1453,10 @@ def test_close(self, m): self.watcher.add_child_handler(64, callback1) self.assertEqual(len(self.watcher._callbacks), 1) - if isinstance(self.watcher, unix_events.FastChildWatcher): + if isinstance(self.watcher, asyncio.FastChildWatcher): self.assertEqual(len(self.watcher._zombies), 1) - with unittest.mock.patch.object( + with mock.patch.object( self.loop, "remove_signal_handler") as m_remove_signal_handler: @@ -1392,31 +1465,31 @@ def test_close(self, m): m_remove_signal_handler.assert_called_once_with( signal.SIGCHLD) self.assertFalse(self.watcher._callbacks) - if isinstance(self.watcher, unix_events.FastChildWatcher): + if isinstance(self.watcher, asyncio.FastChildWatcher): self.assertFalse(self.watcher._zombies) -class SafeChildWatcherTests (ChildWatcherTestsMixin, unittest.TestCase): +class SafeChildWatcherTests (ChildWatcherTestsMixin, test_utils.TestCase): def create_watcher(self): - return unix_events.SafeChildWatcher() + return asyncio.SafeChildWatcher() -class FastChildWatcherTests (ChildWatcherTestsMixin, unittest.TestCase): +class FastChildWatcherTests (ChildWatcherTestsMixin, test_utils.TestCase): def create_watcher(self): - return unix_events.FastChildWatcher() + return asyncio.FastChildWatcher() class PolicyTests(unittest.TestCase): def create_policy(self): - return unix_events.DefaultEventLoopPolicy() + return asyncio.DefaultEventLoopPolicy() def test_get_child_watcher(self): policy = self.create_policy() self.assertIsNone(policy._watcher) watcher = policy.get_child_watcher() - self.assertIsInstance(watcher, unix_events.SafeChildWatcher) + self.assertIsInstance(watcher, asyncio.SafeChildWatcher) self.assertIs(policy._watcher, watcher) @@ -1425,7 +1498,7 @@ def test_get_child_watcher(self): def test_get_child_watcher_after_set(self): policy = self.create_policy() - watcher = unix_events.FastChildWatcher() + watcher = asyncio.FastChildWatcher() policy.set_child_watcher(watcher) self.assertIs(policy._watcher, watcher) @@ -1438,7 +1511,7 @@ def test_get_child_watcher_with_mainloop_existing(self): self.assertIsNone(policy._watcher) watcher = policy.get_child_watcher() - self.assertIsInstance(watcher, unix_events.SafeChildWatcher) + self.assertIsInstance(watcher, asyncio.SafeChildWatcher) self.assertIs(watcher._loop, loop) loop.close() @@ -1449,10 +1522,10 @@ def f(): policy.set_event_loop(policy.new_event_loop()) self.assertIsInstance(policy.get_event_loop(), - events.AbstractEventLoop) + asyncio.AbstractEventLoop) watcher = policy.get_child_watcher() - self.assertIsInstance(watcher, unix_events.SafeChildWatcher) + self.assertIsInstance(watcher, asyncio.SafeChildWatcher) self.assertIsNone(watcher._loop) policy.get_event_loop().close() diff --git a/Lib/test/test_asyncio/test_windows_events.py b/Lib/test/test_asyncio/test_windows_events.py index 7ba33dacc41d..73d8fcdb1854 100644 --- a/Lib/test/test_asyncio/test_windows_events.py +++ b/Lib/test/test_asyncio/test_windows_events.py @@ -1,6 +1,7 @@ import os import sys import unittest +from unittest import mock if sys.platform != 'win32': raise unittest.SkipTest('Windows only') @@ -8,17 +9,12 @@ import _winapi import asyncio - -from asyncio import windows_events -from asyncio import futures -from asyncio import protocols -from asyncio import streams -from asyncio import transports -from asyncio import test_utils from asyncio import _overlapped +from asyncio import test_utils +from asyncio import windows_events -class UpperProto(protocols.Protocol): +class UpperProto(asyncio.Protocol): def __init__(self): self.buf = [] @@ -32,29 +28,26 @@ def data_received(self, data): self.trans.close() -class ProactorTests(unittest.TestCase): +class ProactorTests(test_utils.TestCase): def setUp(self): - self.loop = windows_events.ProactorEventLoop() - asyncio.set_event_loop(None) - - def tearDown(self): - self.loop.close() - self.loop = None + self.loop = asyncio.ProactorEventLoop() + self.set_event_loop(self.loop) def test_close(self): a, b = self.loop._socketpair() - trans = self.loop._make_socket_transport(a, protocols.Protocol()) + trans = self.loop._make_socket_transport(a, asyncio.Protocol()) f = asyncio.async(self.loop.sock_recv(b, 100)) trans.close() self.loop.run_until_complete(f) self.assertEqual(f.result(), b'') + b.close() def test_double_bind(self): ADDRESS = r'\\.\pipe\test_double_bind-%s' % os.getpid() server1 = windows_events.PipeServer(ADDRESS) with self.assertRaises(PermissionError): - server2 = windows_events.PipeServer(ADDRESS) + windows_events.PipeServer(ADDRESS) server1.close() def test_pipe(self): @@ -66,7 +59,7 @@ def _test_pipe(self): with self.assertRaises(FileNotFoundError): yield from self.loop.create_pipe_connection( - protocols.Protocol, ADDRESS) + asyncio.Protocol, ADDRESS) [server] = yield from self.loop.start_serving_pipe( UpperProto, ADDRESS) @@ -74,11 +67,12 @@ def _test_pipe(self): clients = [] for i in range(5): - stream_reader = streams.StreamReader(loop=self.loop) - protocol = streams.StreamReaderProtocol(stream_reader) + stream_reader = asyncio.StreamReader(loop=self.loop) + protocol = asyncio.StreamReaderProtocol(stream_reader, + loop=self.loop) trans, proto = yield from self.loop.create_pipe_connection( lambda: protocol, ADDRESS) - self.assertIsInstance(trans, transports.Transport) + self.assertIsInstance(trans, asyncio.Transport) self.assertEqual(protocol, proto) clients.append((stream_reader, trans)) @@ -94,45 +88,71 @@ def _test_pipe(self): with self.assertRaises(FileNotFoundError): yield from self.loop.create_pipe_connection( - protocols.Protocol, ADDRESS) + asyncio.Protocol, ADDRESS) return 'done' + def test_connect_pipe_cancel(self): + exc = OSError() + exc.winerror = _overlapped.ERROR_PIPE_BUSY + with mock.patch.object(_overlapped, 'ConnectPipe', side_effect=exc) as connect: + coro = self.loop._proactor.connect_pipe('pipe_address') + task = self.loop.create_task(coro) + + # check that it's possible to cancel connect_pipe() + task.cancel() + with self.assertRaises(asyncio.CancelledError): + self.loop.run_until_complete(task) + def test_wait_for_handle(self): event = _overlapped.CreateEvent(None, True, False, None) self.addCleanup(_winapi.CloseHandle, event) - # Wait for unset event with 0.2s timeout; + # Wait for unset event with 0.5s timeout; # result should be False at timeout - f = self.loop._proactor.wait_for_handle(event, 0.2) + fut = self.loop._proactor.wait_for_handle(event, 0.5) start = self.loop.time() - self.loop.run_until_complete(f) + done = self.loop.run_until_complete(fut) elapsed = self.loop.time() - start - self.assertFalse(f.result()) - self.assertTrue(0.18 < elapsed < 0.5, elapsed) + + self.assertEqual(done, False) + self.assertFalse(fut.result()) + self.assertTrue(0.48 < elapsed < 0.9, elapsed) _overlapped.SetEvent(event) - # Wait for for set event; + # Wait for set event; # result should be True immediately - f = self.loop._proactor.wait_for_handle(event, 10) + fut = self.loop._proactor.wait_for_handle(event, 10) start = self.loop.time() - self.loop.run_until_complete(f) + done = self.loop.run_until_complete(fut) elapsed = self.loop.time() - start - self.assertTrue(f.result()) - self.assertTrue(0 <= elapsed < 0.02, elapsed) - _overlapped.ResetEvent(event) + self.assertEqual(done, True) + self.assertTrue(fut.result()) + self.assertTrue(0 <= elapsed < 0.3, elapsed) + + # Tulip issue #195: cancelling a done _WaitHandleFuture must not crash + fut.cancel() + + def test_wait_for_handle_cancel(self): + event = _overlapped.CreateEvent(None, True, False, None) + self.addCleanup(_winapi.CloseHandle, event) # Wait for unset event with a cancelled future; # CancelledError should be raised immediately - f = self.loop._proactor.wait_for_handle(event, 10) - f.cancel() + fut = self.loop._proactor.wait_for_handle(event, 10) + fut.cancel() start = self.loop.time() - with self.assertRaises(futures.CancelledError): - self.loop.run_until_complete(f) + with self.assertRaises(asyncio.CancelledError): + self.loop.run_until_complete(fut) elapsed = self.loop.time() - start - self.assertTrue(0 <= elapsed < 0.02, elapsed) + self.assertTrue(0 <= elapsed < 0.1, elapsed) + + # Tulip issue #195: cancelling a _WaitHandleFuture twice must not crash + fut = self.loop._proactor.wait_for_handle(event) + fut.cancel() + fut.cancel() if __name__ == '__main__': diff --git a/Lib/test/test_asyncio/test_windows_utils.py b/Lib/test/test_asyncio/test_windows_utils.py index fa9d66c0217d..d48b8bcbb087 100644 --- a/Lib/test/test_asyncio/test_windows_utils.py +++ b/Lib/test/test_asyncio/test_windows_utils.py @@ -1,38 +1,73 @@ """Tests for window_utils""" +import socket import sys -import test.support import unittest -import unittest.mock +import warnings +from unittest import mock if sys.platform != 'win32': raise unittest.SkipTest('Windows only') import _winapi -from asyncio import windows_utils from asyncio import _overlapped +from asyncio import windows_utils +try: + from test import support +except ImportError: + from asyncio import test_support as support class WinsocketpairTests(unittest.TestCase): - def test_winsocketpair(self): - ssock, csock = windows_utils.socketpair() - + def check_winsocketpair(self, ssock, csock): csock.send(b'xxx') self.assertEqual(b'xxx', ssock.recv(1024)) - csock.close() ssock.close() - @unittest.mock.patch('asyncio.windows_utils.socket') + def test_winsocketpair(self): + ssock, csock = windows_utils.socketpair() + self.check_winsocketpair(ssock, csock) + + @unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 not supported or enabled') + def test_winsocketpair_ipv6(self): + ssock, csock = windows_utils.socketpair(family=socket.AF_INET6) + self.check_winsocketpair(ssock, csock) + + @unittest.skipIf(hasattr(socket, 'socketpair'), + 'socket.socketpair is available') + @mock.patch('asyncio.windows_utils.socket') def test_winsocketpair_exc(self, m_socket): + m_socket.AF_INET = socket.AF_INET + m_socket.SOCK_STREAM = socket.SOCK_STREAM m_socket.socket.return_value.getsockname.return_value = ('', 12345) m_socket.socket.return_value.accept.return_value = object(), object() m_socket.socket.return_value.connect.side_effect = OSError() self.assertRaises(OSError, windows_utils.socketpair) + def test_winsocketpair_invalid_args(self): + self.assertRaises(ValueError, + windows_utils.socketpair, family=socket.AF_UNSPEC) + self.assertRaises(ValueError, + windows_utils.socketpair, type=socket.SOCK_DGRAM) + self.assertRaises(ValueError, + windows_utils.socketpair, proto=1) + + @unittest.skipIf(hasattr(socket, 'socketpair'), + 'socket.socketpair is available') + @mock.patch('asyncio.windows_utils.socket') + def test_winsocketpair_close(self, m_socket): + m_socket.AF_INET = socket.AF_INET + m_socket.SOCK_STREAM = socket.SOCK_STREAM + sock = mock.Mock() + m_socket.socket.return_value = sock + sock.bind.side_effect = OSError + self.assertRaises(OSError, windows_utils.socketpair) + self.assertTrue(sock.close.called) + class PipeTests(unittest.TestCase): @@ -81,8 +116,10 @@ def test_pipe_handle(self): self.assertEqual(p.handle, h) # check garbage collection of p closes handle - del p - test.support.gc_collect() + with warnings.catch_warnings(): + warnings.filterwarnings("ignore", "", ResourceWarning) + del p + support.gc_collect() try: _winapi.CloseHandle(h) except OSError as e: @@ -136,6 +173,10 @@ def test_popen(self): self.assertTrue(msg.upper().rstrip().startswith(out)) self.assertTrue(b"stderr".startswith(err)) + # The context manager calls wait() and closes resources + with p: + pass + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_asyncio/tests.txt b/Lib/test/test_asyncio/tests.txt deleted file mode 100644 index 30609cd5fe24..000000000000 --- a/Lib/test/test_asyncio/tests.txt +++ /dev/null @@ -1,13 +0,0 @@ -test_asyncio.test_base_events -test_asyncio.test_events -test_asyncio.test_futures -test_asyncio.test_locks -test_asyncio.test_proactor_events -test_asyncio.test_queues -test_asyncio.test_selector_events -test_asyncio.test_streams -test_asyncio.test_tasks -test_asyncio.test_transports -test_asyncio.test_unix_events -test_asyncio.test_windows_events -test_asyncio.test_windows_utils diff --git a/Lib/test/test_asyncore.py b/Lib/test/test_asyncore.py index 084d2472952c..38579168cfd4 100644 --- a/Lib/test/test_asyncore.py +++ b/Lib/test/test_asyncore.py @@ -5,14 +5,11 @@ import socket import sys import time -import warnings import errno import struct from test import support -from test.support import TESTFN, run_unittest, unlink, HOST, HOSTv6 from io import BytesIO -from io import StringIO try: import threading @@ -67,7 +64,7 @@ def handle_error(self): # used when testing senders; just collects what it gets until newline is sent def capture_server(evt, buf, serv): try: - serv.listen(5) + serv.listen() conn, addr = serv.accept() except socket.timeout: pass @@ -94,7 +91,7 @@ def bind_af_aware(sock, addr): """Helper function to bind a socket according to its family.""" if HAS_UNIX_SOCKETS and sock.family == socket.AF_UNIX: # Make sure the path doesn't exist. - unlink(addr) + support.unlink(addr) sock.bind(addr) @@ -257,40 +254,29 @@ def test_log(self): d = asyncore.dispatcher() # capture output of dispatcher.log() (to stderr) - fp = StringIO() - stderr = sys.stderr l1 = "Lovely spam! Wonderful spam!" l2 = "I don't like spam!" - try: - sys.stderr = fp + with support.captured_stderr() as stderr: d.log(l1) d.log(l2) - finally: - sys.stderr = stderr - lines = fp.getvalue().splitlines() + lines = stderr.getvalue().splitlines() self.assertEqual(lines, ['log: %s' % l1, 'log: %s' % l2]) def test_log_info(self): d = asyncore.dispatcher() # capture output of dispatcher.log_info() (to stdout via print) - fp = StringIO() - stdout = sys.stdout l1 = "Have you got anything without spam?" l2 = "Why can't she have egg bacon spam and sausage?" l3 = "THAT'S got spam in it!" - try: - sys.stdout = fp + with support.captured_stdout() as stdout: d.log_info(l1, 'EGGS') d.log_info(l2) d.log_info(l3, 'SPAM') - finally: - sys.stdout = stdout - lines = fp.getvalue().splitlines() + lines = stdout.getvalue().splitlines() expected = ['EGGS: %s' % l1, 'info: %s' % l2, 'SPAM: %s' % l3] - self.assertEqual(lines, expected) def test_unhandled(self): @@ -298,41 +284,19 @@ def test_unhandled(self): d.ignore_log_types = () # capture output of dispatcher.log_info() (to stdout via print) - fp = StringIO() - stdout = sys.stdout - try: - sys.stdout = fp + with support.captured_stdout() as stdout: d.handle_expt() d.handle_read() d.handle_write() d.handle_connect() - finally: - sys.stdout = stdout - lines = fp.getvalue().splitlines() + lines = stdout.getvalue().splitlines() expected = ['warning: unhandled incoming priority event', 'warning: unhandled read event', 'warning: unhandled write event', 'warning: unhandled connect event'] self.assertEqual(lines, expected) - def test_issue_8594(self): - # XXX - this test is supposed to be removed in next major Python - # version - d = asyncore.dispatcher(socket.socket()) - # make sure the error message no longer refers to the socket - # object but the dispatcher instance instead - self.assertRaisesRegex(AttributeError, 'dispatcher instance', - getattr, d, 'foo') - # cheap inheritance with the underlying socket is supposed - # to still work but a DeprecationWarning is expected - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter("always") - family = d.family - self.assertEqual(family, socket.AF_INET) - self.assertEqual(len(w), 1) - self.assertTrue(issubclass(w[0].category, DeprecationWarning)) - def test_strerror(self): # refers to bug #8573 err = asyncore._strerror(errno.EPERM) @@ -349,9 +313,8 @@ def readable(self): def handle_connect(self): pass -class DispatcherWithSendTests(unittest.TestCase): - usepoll = False +class DispatcherWithSendTests(unittest.TestCase): def setUp(self): pass @@ -378,7 +341,7 @@ def test_send(self): data = b"Suppose there isn't a 16-ton weight?" d = dispatcherwithsend_noread() d.create_socket() - d.connect((HOST, port)) + d.connect((support.HOST, port)) # give time for socket to connect time.sleep(0.1) @@ -401,23 +364,19 @@ def test_send(self): self.fail("join() timed out") - -class DispatcherWithSendTests_UsePoll(DispatcherWithSendTests): - usepoll = True - @unittest.skipUnless(hasattr(asyncore, 'file_wrapper'), 'asyncore.file_wrapper required') class FileWrapperTest(unittest.TestCase): def setUp(self): self.d = b"It's not dead, it's sleeping!" - with open(TESTFN, 'wb') as file: + with open(support.TESTFN, 'wb') as file: file.write(self.d) def tearDown(self): - unlink(TESTFN) + support.unlink(support.TESTFN) def test_recv(self): - fd = os.open(TESTFN, os.O_RDONLY) + fd = os.open(support.TESTFN, os.O_RDONLY) w = asyncore.file_wrapper(fd) os.close(fd) @@ -431,20 +390,20 @@ def test_recv(self): def test_send(self): d1 = b"Come again?" d2 = b"I want to buy some cheese." - fd = os.open(TESTFN, os.O_WRONLY | os.O_APPEND) + fd = os.open(support.TESTFN, os.O_WRONLY | os.O_APPEND) w = asyncore.file_wrapper(fd) os.close(fd) w.write(d1) w.send(d2) w.close() - with open(TESTFN, 'rb') as file: + with open(support.TESTFN, 'rb') as file: self.assertEqual(file.read(), self.d + d1 + d2) @unittest.skipUnless(hasattr(asyncore, 'file_dispatcher'), 'asyncore.file_dispatcher required') def test_dispatcher(self): - fd = os.open(TESTFN, os.O_RDONLY) + fd = os.open(support.TESTFN, os.O_RDONLY) data = [] class FileDispatcher(asyncore.file_dispatcher): def handle_read(self): @@ -454,6 +413,26 @@ def handle_read(self): asyncore.loop(timeout=0.01, use_poll=True, count=2) self.assertEqual(b"".join(data), self.d) + def test_resource_warning(self): + # Issue #11453 + fd = os.open(support.TESTFN, os.O_RDONLY) + f = asyncore.file_wrapper(fd) + + os.close(fd) + with support.check_warnings(('', ResourceWarning)): + f = None + support.gc_collect() + + def test_close_twice(self): + fd = os.open(support.TESTFN, os.O_RDONLY) + f = asyncore.file_wrapper(fd) + os.close(fd) + + f.close() + self.assertEqual(f.fd, -1) + # calling close twice should not fail + f.close() + class BaseTestHandler(asyncore.dispatcher): @@ -815,12 +794,12 @@ def cleanup(): class TestAPI_UseIPv4Sockets(BaseTestAPI): family = socket.AF_INET - addr = (HOST, 0) + addr = (support.HOST, 0) @unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 support required') class TestAPI_UseIPv6Sockets(BaseTestAPI): family = socket.AF_INET6 - addr = (HOSTv6, 0) + addr = (support.HOSTv6, 0) @unittest.skipUnless(HAS_UNIX_SOCKETS, 'Unix sockets required') class TestAPI_UseUnixSockets(BaseTestAPI): @@ -829,7 +808,7 @@ class TestAPI_UseUnixSockets(BaseTestAPI): addr = support.TESTFN def tearDown(self): - unlink(self.addr) + support.unlink(self.addr) BaseTestAPI.tearDown(self) class TestAPI_UseIPv4Select(TestAPI_UseIPv4Sockets, unittest.TestCase): diff --git a/Lib/test/test_atexit.py b/Lib/test/test_atexit.py index 84644f17a887..70d2f1cf54b7 100644 --- a/Lib/test/test_atexit.py +++ b/Lib/test/test_atexit.py @@ -2,7 +2,6 @@ import unittest import io import atexit -import _testcapi from test import support ### helpers diff --git a/Lib/test/test_audioop.py b/Lib/test/test_audioop.py index d5075450e637..879adea2b8eb 100644 --- a/Lib/test/test_audioop.py +++ b/Lib/test/test_audioop.py @@ -269,6 +269,11 @@ def test_lin2adpcm(self): self.assertEqual(audioop.lin2adpcm(b'\0' * w * 10, w, None), (b'\0' * 5, (0, 0))) + def test_invalid_adpcm_state(self): + # state must be a tuple or None, not an integer + self.assertRaises(TypeError, audioop.adpcm2lin, b'\0', 1, 555) + self.assertRaises(TypeError, audioop.lin2adpcm, b'\0', 1, 555) + def test_lin2alaw(self): self.assertEqual(audioop.lin2alaw(datas[1], 1), b'\xd5\x87\xa4\x24\xaa\x2a\x5a') diff --git a/Lib/test/test_augassign.py b/Lib/test/test_augassign.py index 9a59c58ec066..19b76874bead 100644 --- a/Lib/test/test_augassign.py +++ b/Lib/test/test_augassign.py @@ -136,6 +136,14 @@ def __imul__(self, val): output.append("__imul__ called") return self + def __matmul__(self, val): + output.append("__matmul__ called") + def __rmatmul__(self, val): + output.append("__rmatmul__ called") + def __imatmul__(self, val): + output.append("__imatmul__ called") + return self + def __div__(self, val): output.append("__div__ called") def __rdiv__(self, val): @@ -233,6 +241,10 @@ def __ilshift__(self, val): 1 * x x *= 1 + x @ 1 + 1 @ x + x @= 1 + x / 1 1 / x x /= 1 @@ -279,6 +291,9 @@ def __ilshift__(self, val): __mul__ called __rmul__ called __imul__ called +__matmul__ called +__rmatmul__ called +__imatmul__ called __truediv__ called __rtruediv__ called __itruediv__ called diff --git a/Lib/test/test_binascii.py b/Lib/test/test_binascii.py index 04d8f9d68048..22d53af1905a 100644 --- a/Lib/test/test_binascii.py +++ b/Lib/test/test_binascii.py @@ -162,7 +162,9 @@ def test_hex(self): self.assertRaises(binascii.Error, binascii.a2b_hex, t[:-1]) self.assertRaises(binascii.Error, binascii.a2b_hex, t[:-1] + b'q') - self.assertEqual(binascii.hexlify(b'a'), b'61') + # Confirm that b2a_hex == hexlify and a2b_hex == unhexlify + self.assertEqual(binascii.hexlify(self.type2test(s)), t) + self.assertEqual(binascii.unhexlify(self.type2test(t)), u) def test_qp(self): # A test for SF bug 534347 (segfaults without the proper fix) diff --git a/Lib/test/test_binhex.py b/Lib/test/test_binhex.py old mode 100755 new mode 100644 index a807bca6393d..9d4c85afaa6d --- a/Lib/test/test_binhex.py +++ b/Lib/test/test_binhex.py @@ -1,4 +1,3 @@ -#! /usr/bin/env python3 """Test script for the binhex C module Uses the mechanism of the python binhex module diff --git a/Lib/test/test_binop.py b/Lib/test/test_binop.py index 84179167e218..9c4c18e63614 100644 --- a/Lib/test/test_binop.py +++ b/Lib/test/test_binop.py @@ -194,10 +194,6 @@ def __eq__(self, other): return float(self) == other return NotImplemented - def __ne__(self, other): - """Compare two Rats for inequality.""" - return not self == other - class RatTestCase(unittest.TestCase): """Unit tests for Rat class and its support utilities.""" diff --git a/Lib/test/test_bool.py b/Lib/test/test_bool.py index 4bab28be7750..250743949bf5 100644 --- a/Lib/test/test_bool.py +++ b/Lib/test/test_bool.py @@ -269,10 +269,9 @@ def test_marshal(self): def test_pickle(self): import pickle - self.assertIs(pickle.loads(pickle.dumps(True)), True) - self.assertIs(pickle.loads(pickle.dumps(False)), False) - self.assertIs(pickle.loads(pickle.dumps(True, True)), True) - self.assertIs(pickle.loads(pickle.dumps(False, True)), False) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.assertIs(pickle.loads(pickle.dumps(True, proto)), True) + self.assertIs(pickle.loads(pickle.dumps(False, proto)), False) def test_picklevalues(self): # Test for specific backwards-compatible pickle values diff --git a/Lib/test/test_buffer.py b/Lib/test/test_buffer.py index 1667847a9df1..0976fa9e34d8 100644 --- a/Lib/test/test_buffer.py +++ b/Lib/test/test_buffer.py @@ -216,7 +216,7 @@ def iter_format(nitems, testobj='ndarray'): for t in iter_mode(nitems, testobj): yield t if testobj != 'ndarray': - raise StopIteration + return yield struct_items(nitems, testobj) @@ -1007,6 +1007,7 @@ def test_ndarray_getbuf(self): # shape, strides, offset structure = ( ([], [], 0), + ([1,3,1], [], 0), ([12], [], 0), ([12], [-1], 11), ([6], [2], 0), @@ -1078,6 +1079,18 @@ def test_ndarray_getbuf(self): self.assertRaises(BufferError, ndarray, ex, getbuf=PyBUF_ANY_CONTIGUOUS) nd = ndarray(ex, getbuf=PyBUF_SIMPLE) + # Issue #22445: New precise contiguity definition. + for shape in [1,12,1], [7,0,7]: + for order in 0, ND_FORTRAN: + ex = ndarray(items, shape=shape, flags=order|ND_WRITABLE) + self.assertTrue(is_contiguous(ex, 'F')) + self.assertTrue(is_contiguous(ex, 'C')) + + for flags in requests: + nd = ndarray(ex, getbuf=flags) + self.assertTrue(is_contiguous(nd, 'F')) + self.assertTrue(is_contiguous(nd, 'C')) + def test_ndarray_exceptions(self): nd = ndarray([9], [1]) ndm = ndarray([9], [1], flags=ND_VAREXPORT) diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py index 68430660f016..6166da563e68 100644 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -16,6 +16,7 @@ import warnings from operator import neg from test.support import TESTFN, unlink, run_unittest, check_warnings +from test.script_helper import assert_python_ok try: import pty, signal except ImportError: @@ -120,9 +121,9 @@ def map_char(arg): class BuiltinTest(unittest.TestCase): # Helper to check picklability - def check_iter_pickle(self, it, seq): + def check_iter_pickle(self, it, seq, proto): itorg = it - d = pickle.dumps(it) + d = pickle.dumps(it, proto) it = pickle.loads(d) self.assertEqual(type(itorg), type(it)) self.assertEqual(list(it), seq) @@ -133,7 +134,7 @@ def check_iter_pickle(self, it, seq): next(it) except StopIteration: return - d = pickle.dumps(it) + d = pickle.dumps(it, proto) it = pickle.loads(d) self.assertEqual(list(it), seq[1:]) @@ -311,11 +312,11 @@ def test_compile(self): self.assertRaises(TypeError, compile) self.assertRaises(ValueError, compile, 'print(42)\n', '<string>', 'badmode') self.assertRaises(ValueError, compile, 'print(42)\n', '<string>', 'single', 0xff) - self.assertRaises(TypeError, compile, chr(0), 'f', 'exec') + self.assertRaises(ValueError, compile, chr(0), 'f', 'exec') self.assertRaises(TypeError, compile, 'pass', '?', 'exec', mode='eval', source='0', filename='tmp') compile('print("\xe5")\n', '', 'exec') - self.assertRaises(TypeError, compile, chr(0), 'f', 'exec') + self.assertRaises(ValueError, compile, chr(0), 'f', 'exec') self.assertRaises(ValueError, compile, str('a = 1'), 'f', 'bad') # test the optimize argument @@ -635,9 +636,10 @@ def badfunc(): self.assertRaises(TypeError, list, filter(42, (1, 2))) def test_filter_pickle(self): - f1 = filter(filter_char, "abcdeabcde") - f2 = filter(filter_char, "abcdeabcde") - self.check_iter_pickle(f1, list(f2)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + f1 = filter(filter_char, "abcdeabcde") + f2 = filter(filter_char, "abcdeabcde") + self.check_iter_pickle(f1, list(f2), proto) def test_getattr(self): self.assertTrue(getattr(sys, 'stdout') is sys.stdout) @@ -833,9 +835,10 @@ def badfunc(x): self.assertRaises(RuntimeError, list, map(badfunc, range(5))) def test_map_pickle(self): - m1 = map(map_char, "Is this the real life?") - m2 = map(map_char, "Is this the real life?") - self.check_iter_pickle(m1, list(m2)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + m1 = map(map_char, "Is this the real life?") + m2 = map(map_char, "Is this the real life?") + self.check_iter_pickle(m1, list(m2), proto) def test_max(self): self.assertEqual(max('123123'), '3') @@ -1091,7 +1094,7 @@ def test_pow(self): self.assertAlmostEqual(pow(-1, 0.5), 1j) self.assertAlmostEqual(pow(-1, 1/3), 0.5 + 0.8660254037844386j) - self.assertRaises(TypeError, pow, -1, -2, 3) + self.assertRaises(ValueError, pow, -1, -2, 3) self.assertRaises(ValueError, pow, 1, 2, 0) self.assertRaises(TypeError, pow) @@ -1432,8 +1435,9 @@ def test_zip_pickle(self): a = (1, 2, 3) b = (4, 5, 6) t = [(1, 4), (2, 5), (3, 6)] - z1 = zip(a, b) - self.check_iter_pickle(z1, t) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + z1 = zip(a, b) + self.check_iter_pickle(z1, t, proto) def test_format(self): # Test the basic machinery of the format() builtin. Don't test @@ -1592,6 +1596,41 @@ def test_baddecorator(self): data = 'The quick Brown fox Jumped over The lazy Dog'.split() self.assertRaises(TypeError, sorted, data, None, lambda x,y: 0) + +class ShutdownTest(unittest.TestCase): + + def test_cleanup(self): + # Issue #19255: builtins are still available at shutdown + code = """if 1: + import builtins + import sys + + class C: + def __del__(self): + print("before") + # Check that builtins still exist + len(()) + print("after") + + c = C() + # Make this module survive until builtins and sys are cleaned + builtins.here = sys.modules[__name__] + sys.here = sys.modules[__name__] + # Create a reference loop so that this module needs to go + # through a GC phase. + here = sys.modules[__name__] + """ + # Issue #20599: Force ASCII encoding to get a codec implemented in C, + # otherwise the codec may be unloaded before C.__del__() is called, and + # so print("before") fails because the codec cannot be used to encode + # "before" to sys.stdout.encoding. For example, on Windows, + # sys.stdout.encoding is the OEM code page and these code pages are + # implemented in Python + rc, out, err = assert_python_ok("-c", code, + PYTHONIOENCODING="ascii") + self.assertEqual(["before", "after"], out.decode().splitlines()) + + def load_tests(loader, tests, pattern): from doctest import DocTestSuite tests.addTest(DocTestSuite(builtins)) diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py index 847c7a613fe7..a9f64a0dccbc 100644 --- a/Lib/test/test_bytes.py +++ b/Lib/test/test_bytes.py @@ -13,9 +13,11 @@ import pickle import tempfile import unittest + import test.support import test.string_tests import test.buffer_tests +from test.support import bigaddrspacetest, MAX_Py_ssize_t if sys.flags.bytes_warning: @@ -98,6 +100,14 @@ class C: self.assertRaises(TypeError, self.type2test, [0.0]) self.assertRaises(TypeError, self.type2test, [None]) self.assertRaises(TypeError, self.type2test, [C()]) + self.assertRaises(TypeError, self.type2test, 0, 'ascii') + self.assertRaises(TypeError, self.type2test, b'', 'ascii') + self.assertRaises(TypeError, self.type2test, 0, errors='ignore') + self.assertRaises(TypeError, self.type2test, b'', errors='ignore') + self.assertRaises(TypeError, self.type2test, '') + self.assertRaises(TypeError, self.type2test, '', errors='ignore') + self.assertRaises(TypeError, self.type2test, '', b'ascii') + self.assertRaises(TypeError, self.type2test, '', 'ascii', b'ignore') def test_constructor_value_errors(self): self.assertRaises(ValueError, self.type2test, [-1]) @@ -111,6 +121,17 @@ def test_constructor_value_errors(self): self.assertRaises(ValueError, self.type2test, [sys.maxsize+1]) self.assertRaises(ValueError, self.type2test, [10**100]) + @bigaddrspacetest + def test_constructor_overflow(self): + size = MAX_Py_ssize_t + self.assertRaises((OverflowError, MemoryError), self.type2test, size) + try: + # Should either pass or raise an error (e.g. on debug builds with + # additional malloc() overhead), but shouldn't crash. + bytearray(size - 4) + except (OverflowError, MemoryError): + pass + def test_compare(self): b1 = self.type2test([1, 2, 3]) b2 = self.type2test([1, 2, 3]) @@ -298,6 +319,7 @@ def test_join(self): seq = [b"abc"] * 1000 expected = b"abc" + b".:abc" * 999 self.assertEqual(dot_join(seq), expected) + self.assertRaises(TypeError, self.type2test(b" ").join, None) # Error handling and cleanup when some item in the middle of the # sequence has the wrong type. with self.assertRaises(TypeError): @@ -439,6 +461,28 @@ def test_rindex(self): self.assertEqual(b.rindex(i, 3, 9), 7) self.assertRaises(ValueError, b.rindex, w, 1, 3) + def test_mod(self): + b = b'hello, %b!' + orig = b + b = b % b'world' + self.assertEqual(b, b'hello, world!') + self.assertEqual(orig, b'hello, %b!') + self.assertFalse(b is orig) + b = b'%s / 100 = %d%%' + a = b % (b'seventy-nine', 79) + self.assertEqual(a, b'seventy-nine / 100 = 79%') + + def test_imod(self): + b = b'hello, %b!' + orig = b + b %= b'world' + self.assertEqual(b, b'hello, world!') + self.assertEqual(orig, b'hello, %b!') + self.assertFalse(b is orig) + b = b'%s / 100 = %d%%' + b %= (b'seventy-nine', 79) + self.assertEqual(b, b'seventy-nine / 100 = 79%') + def test_replace(self): b = self.type2test(b'mississippi') self.assertEqual(b.replace(b'i', b'a'), b'massassappa') @@ -533,22 +577,23 @@ def test_pickling(self): self.assertEqual(b, q) def test_iterator_pickling(self): - for b in b"", b"a", b"abc", b"\xffab\x80", b"\0\0\377\0\0": - it = itorg = iter(self.type2test(b)) - data = list(self.type2test(b)) - d = pickle.dumps(it) - it = pickle.loads(d) - self.assertEqual(type(itorg), type(it)) - self.assertEqual(list(it), data) - - it = pickle.loads(d) - try: - next(it) - except StopIteration: - continue - d = pickle.dumps(it) - it = pickle.loads(d) - self.assertEqual(list(it), data[1:]) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + for b in b"", b"a", b"abc", b"\xffab\x80", b"\0\0\377\0\0": + it = itorg = iter(self.type2test(b)) + data = list(self.type2test(b)) + d = pickle.dumps(it, proto) + it = pickle.loads(d) + self.assertEqual(type(itorg), type(it)) + self.assertEqual(list(it), data) + + it = pickle.loads(d) + try: + next(it) + except StopIteration: + continue + d = pickle.dumps(it, proto) + it = pickle.loads(d) + self.assertEqual(list(it), data[1:]) def test_strip(self): b = self.type2test(b'mississippi') @@ -699,8 +744,13 @@ def test_find_etc_raise_correct_error_messages(self): class BytesTest(BaseBytesTest, unittest.TestCase): type2test = bytes + def test_getitem_error(self): + msg = "byte indices must be integers or slices" + with self.assertRaisesRegex(TypeError, msg): + b'python'['a'] + def test_buffer_is_readonly(self): - fd = os.dup(sys.stdin.fileno()) + fd = os.open(__file__, os.O_RDONLY) with open(fd, "rb", buffering=0) as f: self.assertRaises(TypeError, f.readinto, b"") @@ -743,10 +793,27 @@ def test_from_format(self): self.assertEqual(PyBytes_FromFormat(b's:%s', c_char_p(b'cstr')), b's:cstr') + # Issue #19969 + self.assertRaises(OverflowError, + PyBytes_FromFormat, b'%c', c_int(-1)) + self.assertRaises(OverflowError, + PyBytes_FromFormat, b'%c', c_int(256)) + class ByteArrayTest(BaseBytesTest, unittest.TestCase): type2test = bytearray + def test_getitem_error(self): + msg = "bytearray indices must be integers or slices" + with self.assertRaisesRegex(TypeError, msg): + bytearray(b'python')['a'] + + def test_setitem_error(self): + msg = "bytearray indices must be integers or slices" + with self.assertRaisesRegex(TypeError, msg): + b = bytearray(b'python') + b['a'] = "python" + def test_nohash(self): self.assertRaises(TypeError, hash, bytearray()) @@ -945,6 +1012,28 @@ def test_setslice_trap(self): b[8:] = b self.assertEqual(b, bytearray(list(range(8)) + list(range(256)))) + def test_mod(self): + b = bytearray(b'hello, %b!') + orig = b + b = b % b'world' + self.assertEqual(b, b'hello, world!') + self.assertEqual(orig, bytearray(b'hello, %b!')) + self.assertFalse(b is orig) + b = bytearray(b'%s / 100 = %d%%') + a = b % (b'seventy-nine', 79) + self.assertEqual(a, bytearray(b'seventy-nine / 100 = 79%')) + + def test_imod(self): + b = bytearray(b'hello, %b!') + orig = b + b %= b'world' + self.assertEqual(b, b'hello, world!') + self.assertEqual(orig, bytearray(b'hello, %b!')) + self.assertFalse(b is orig) + b = bytearray(b'%s / 100 = %d%%') + b %= (b'seventy-nine', 79) + self.assertEqual(b, bytearray(b'seventy-nine / 100 = 79%')) + def test_iconcat(self): b = bytearray(b"abc") b1 = b @@ -1135,6 +1224,10 @@ def delslice(): self.assertRaises(BufferError, delslice) self.assertEqual(b, orig) + @test.support.cpython_only + def test_obsolete_write_lock(self): + from _testcapi import getbuffer_with_null_view + self.assertRaises(BufferError, getbuffer_with_null_view, bytearray()) class AssortedBytesTest(unittest.TestCase): # diff --git a/Lib/test/test_bz2.py b/Lib/test/test_bz2.py index 8d93e2d88fe1..1535e8e6695b 100644 --- a/Lib/test/test_bz2.py +++ b/Lib/test/test_bz2.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 from test import support from test.support import bigmemtest, _4G @@ -50,6 +49,7 @@ class BaseTest(unittest.TestCase): TEXT = b''.join(TEXT_LINES) DATA = b'BZh91AY&SY.\xc8N\x18\x00\x01>_\x80\x00\x10@\x02\xff\xf0\x01\x07n\x00?\xe7\xff\xe00\x01\x99\xaa\x00\xc0\x03F\x86\x8c#&\x83F\x9a\x03\x06\xa6\xd0\xa6\x93M\x0fQ\xa7\xa8\x06\x804hh\x12$\x11\xa4i4\xf14S\xd2<Q\xb5\x0fH\xd3\xd4\xdd\xd5\x87\xbb\xf8\x94\r\x8f\xafI\x12\xe1\xc9\xf8/E\x00pu\x89\x12]\xc9\xbbDL\nQ\x0e\t1\x12\xdf\xa0\xc0\x97\xac2O9\x89\x13\x94\x0e\x1c7\x0ed\x95I\x0c\xaaJ\xa4\x18L\x10\x05#\x9c\xaf\xba\xbc/\x97\x8a#C\xc8\xe1\x8cW\xf9\xe2\xd0\xd6M\xa7\x8bXa<e\x84t\xcbL\xb3\xa7\xd9\xcd\xd1\xcb\x84.\xaf\xb3\xab\xab\xad`n}\xa0lh\tE,\x8eZ\x15\x17VH>\x88\xe5\xcd9gd6\x0b\n\xe9\x9b\xd5\x8a\x99\xf7\x08.K\x8ev\xfb\xf7xw\xbb\xdf\xa1\x92\xf1\xdd|/";\xa2\xba\x9f\xd5\xb1#A\xb6\xf6\xb3o\xc9\xc5y\\\xebO\xe7\x85\x9a\xbc\xb6f8\x952\xd5\xd7"%\x89>V,\xf7\xa6z\xe2\x9f\xa3\xdf\x11\x11"\xd6E)I\xa9\x13^\xca\xf3r\xd0\x03U\x922\xf26\xec\xb6\xed\x8b\xc3U\x13\x9d\xc5\x170\xa4\xfa^\x92\xacDF\x8a\x97\xd6\x19\xfe\xdd\xb8\xbd\x1a\x9a\x19\xa3\x80ankR\x8b\xe5\xd83]\xa9\xc6\x08\x82f\xf6\xb9"6l$\xb8j@\xc0\x8a\xb0l1..\xbak\x83ls\x15\xbc\xf4\xc1\x13\xbe\xf8E\xb8\x9d\r\xa8\x9dk\x84\xd3n\xfa\xacQ\x07\xb1%y\xaav\xb4\x08\xe0z\x1b\x16\xf5\x04\xe9\xcc\xb9\x08z\x1en7.G\xfc]\xc9\x14\xe1B@\xbb!8`' EMPTY_DATA = b'BZh9\x17rE8P\x90\x00\x00\x00\x00' + BAD_DATA = b'this is not a valid bzip2 file' def setUp(self): self.filename = support.TESTFN @@ -80,17 +80,18 @@ def decompress(self, data): class BZ2FileTest(BaseTest): "Test the BZ2File class." - def createTempFile(self, streams=1): + def createTempFile(self, streams=1, suffix=b""): with open(self.filename, "wb") as f: f.write(self.DATA * streams) + f.write(suffix) def testBadArgs(self): self.assertRaises(TypeError, BZ2File, 123.456) - self.assertRaises(ValueError, BZ2File, "/dev/null", "z") - self.assertRaises(ValueError, BZ2File, "/dev/null", "rx") - self.assertRaises(ValueError, BZ2File, "/dev/null", "rbt") - self.assertRaises(ValueError, BZ2File, "/dev/null", compresslevel=0) - self.assertRaises(ValueError, BZ2File, "/dev/null", compresslevel=10) + self.assertRaises(ValueError, BZ2File, os.devnull, "z") + self.assertRaises(ValueError, BZ2File, os.devnull, "rx") + self.assertRaises(ValueError, BZ2File, os.devnull, "rbt") + self.assertRaises(ValueError, BZ2File, os.devnull, compresslevel=0) + self.assertRaises(ValueError, BZ2File, os.devnull, compresslevel=10) def testRead(self): self.createTempFile() @@ -98,6 +99,11 @@ def testRead(self): self.assertRaises(TypeError, bz2f.read, None) self.assertEqual(bz2f.read(), self.TEXT) + def testReadBadFile(self): + self.createTempFile(streams=0, suffix=self.BAD_DATA) + with BZ2File(self.filename) as bz2f: + self.assertRaises(OSError, bz2f.read) + def testReadMultiStream(self): self.createTempFile(streams=5) with BZ2File(self.filename) as bz2f: @@ -117,6 +123,16 @@ def testReadMonkeyMultiStream(self): finally: bz2._BUFFER_SIZE = buffer_size + def testReadTrailingJunk(self): + self.createTempFile(suffix=self.BAD_DATA) + with BZ2File(self.filename) as bz2f: + self.assertEqual(bz2f.read(), self.TEXT) + + def testReadMultiStreamTrailingJunk(self): + self.createTempFile(streams=5, suffix=self.BAD_DATA) + with BZ2File(self.filename) as bz2f: + self.assertEqual(bz2f.read(), self.TEXT * 5) + def testRead0(self): self.createTempFile() with BZ2File(self.filename) as bz2f: @@ -630,8 +646,9 @@ def testCompress4G(self, size): data = None def testPickle(self): - with self.assertRaises(TypeError): - pickle.dumps(BZ2Compressor()) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.assertRaises(TypeError): + pickle.dumps(BZ2Compressor(), proto) class BZ2DecompressorTest(BaseTest): @@ -669,7 +686,7 @@ def testEOFError(self): self.assertRaises(EOFError, bz2d.decompress, b"anything") self.assertRaises(EOFError, bz2d.decompress, b"") - @bigmemtest(size=_4G + 100, memuse=3) + @bigmemtest(size=_4G + 100, memuse=3.3) def testDecompress4G(self, size): # "Test BZ2Decompressor.decompress() with >4GiB input" blocksize = 10 * 1024 * 1024 @@ -686,8 +703,9 @@ def testDecompress4G(self, size): decompressed = None def testPickle(self): - with self.assertRaises(TypeError): - pickle.dumps(BZ2Decompressor()) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.assertRaises(TypeError): + pickle.dumps(BZ2Decompressor(), proto) class CompressDecompressTest(BaseTest): @@ -714,10 +732,21 @@ def testDecompressToEmptyString(self): def testDecompressIncomplete(self): self.assertRaises(ValueError, bz2.decompress, self.DATA[:-10]) + def testDecompressBadData(self): + self.assertRaises(OSError, bz2.decompress, self.BAD_DATA) + def testDecompressMultiStream(self): text = bz2.decompress(self.DATA * 5) self.assertEqual(text, self.TEXT * 5) + def testDecompressTrailingJunk(self): + text = bz2.decompress(self.DATA + self.BAD_DATA) + self.assertEqual(text, self.TEXT) + + def testDecompressMultiStreamTrailingJunk(self): + text = bz2.decompress(self.DATA * 5 + self.BAD_DATA) + self.assertEqual(text, self.TEXT * 5) + class OpenTest(BaseTest): "Test the open function." diff --git a/Lib/test/test_calendar.py b/Lib/test/test_calendar.py index f680b52f0974..9193857197b4 100644 --- a/Lib/test/test_calendar.py +++ b/Lib/test/test_calendar.py @@ -2,13 +2,14 @@ import unittest from test import support -from test.script_helper import assert_python_ok +from test.script_helper import assert_python_ok, assert_python_failure import time import locale import sys import datetime +import os -result_2004_01_text = """ +result_2004_01_text = """\ January 2004 Mo Tu We Th Fr Sa Su 1 2 3 4 @@ -18,7 +19,7 @@ 26 27 28 29 30 31 """ -result_2004_text = """ +result_2004_text = """\ 2004 January February March @@ -56,7 +57,7 @@ 25 26 27 28 29 30 31 29 30 27 28 29 30 31 """ -result_2004_html = """ +result_2004_html = """\ <?xml version="1.0" encoding="%(e)s"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html> @@ -327,8 +328,8 @@ def neitherspacenordigit(c): def check_htmlcalendar_encoding(self, req, res): cal = calendar.HTMLCalendar() self.assertEqual( - cal.formatyearpage(2004, encoding=req).strip(b' \t\n'), - (result_2004_html % {'e': res}).strip(' \t\n').encode(res) + cal.formatyearpage(2004, encoding=req), + (result_2004_html % {'e': res}).encode(res) ) def test_output(self): @@ -339,8 +340,8 @@ def test_output(self): def test_output_textcalendar(self): self.assertEqual( - calendar.TextCalendar().formatyear(2004).strip(), - result_2004_text.strip() + calendar.TextCalendar().formatyear(2004), + result_2004_text ) def test_output_htmlcalendar_encoding_ascii(self): @@ -383,8 +384,8 @@ def test_formatweekheader_long(self): def test_formatmonth(self): self.assertEqual( - calendar.TextCalendar().formatmonth(2004, 1).strip(), - result_2004_01_text.strip() + calendar.TextCalendar().formatmonth(2004, 1), + result_2004_01_text ) def test_formatmonthname_with_year(self): @@ -692,23 +693,127 @@ def test_several_leapyears_in_range(self): self.assertEqual(calendar.leapdays(1997,2020), 5) -class ConsoleOutputTestCase(unittest.TestCase): - def test_outputs_bytes(self): - (return_code, stdout, stderr) = assert_python_ok('-m', 'calendar', '--type=html', '2010') +def conv(s): + return s.replace('\n', os.linesep).encode() + +class CommandLineTestCase(unittest.TestCase): + def run_ok(self, *args): + return assert_python_ok('-m', 'calendar', *args)[1] + + def assertFailure(self, *args): + rc, stdout, stderr = assert_python_failure('-m', 'calendar', *args) + self.assertIn(b'Usage:', stderr) + self.assertEqual(rc, 2) + + def test_help(self): + stdout = self.run_ok('-h') + self.assertIn(b'Usage:', stdout) + self.assertIn(b'calendar.py', stdout) + self.assertIn(b'--help', stdout) + + def test_illegal_arguments(self): + self.assertFailure('-z') + #self.assertFailure('spam') + #self.assertFailure('2004', 'spam') + self.assertFailure('-t', 'html', '2004', '1') + + def test_output_current_year(self): + stdout = self.run_ok() + year = datetime.datetime.now().year + self.assertIn((' %s' % year).encode(), stdout) + self.assertIn(b'January', stdout) + self.assertIn(b'Mo Tu We Th Fr Sa Su', stdout) + + def test_output_year(self): + stdout = self.run_ok('2004') + self.assertEqual(stdout, conv(result_2004_text)) + + def test_output_month(self): + stdout = self.run_ok('2004', '1') + self.assertEqual(stdout, conv(result_2004_01_text)) + + def test_option_encoding(self): + self.assertFailure('-e') + self.assertFailure('--encoding') + stdout = self.run_ok('--encoding', 'utf-16-le', '2004') + self.assertEqual(stdout, result_2004_text.encode('utf-16-le')) + + def test_option_locale(self): + self.assertFailure('-L') + self.assertFailure('--locale') + self.assertFailure('-L', 'en') + lang, enc = locale.getdefaultlocale() + lang = lang or 'C' + enc = enc or 'UTF-8' + try: + oldlocale = locale.getlocale(locale.LC_TIME) + try: + locale.setlocale(locale.LC_TIME, (lang, enc)) + finally: + locale.setlocale(locale.LC_TIME, oldlocale) + except (locale.Error, ValueError): + self.skipTest('cannot set the system default locale') + stdout = self.run_ok('--locale', lang, '--encoding', enc, '2004') + self.assertIn('2004'.encode(enc), stdout) + + def test_option_width(self): + self.assertFailure('-w') + self.assertFailure('--width') + self.assertFailure('-w', 'spam') + stdout = self.run_ok('--width', '3', '2004') + self.assertIn(b'Mon Tue Wed Thu Fri Sat Sun', stdout) + + def test_option_lines(self): + self.assertFailure('-l') + self.assertFailure('--lines') + self.assertFailure('-l', 'spam') + stdout = self.run_ok('--lines', '2', '2004') + self.assertIn(conv('December\n\nMo Tu We'), stdout) + + def test_option_spacing(self): + self.assertFailure('-s') + self.assertFailure('--spacing') + self.assertFailure('-s', 'spam') + stdout = self.run_ok('--spacing', '8', '2004') + self.assertIn(b'Su Mo', stdout) + + def test_option_months(self): + self.assertFailure('-m') + self.assertFailure('--month') + self.assertFailure('-m', 'spam') + stdout = self.run_ok('--months', '1', '2004') + self.assertIn(conv('\nMo Tu We Th Fr Sa Su\n'), stdout) + + def test_option_type(self): + self.assertFailure('-t') + self.assertFailure('--type') + self.assertFailure('-t', 'spam') + stdout = self.run_ok('--type', 'text', '2004') + self.assertEqual(stdout, conv(result_2004_text)) + stdout = self.run_ok('--type', 'html', '2004') self.assertEqual(stdout[:6], b'<?xml ') + self.assertIn(b'<title>Calendar for 2004', stdout) + + def test_html_output_current_year(self): + stdout = self.run_ok('--type', 'html') + year = datetime.datetime.now().year + self.assertIn(('Calendar for %s' % year).encode(), + stdout) + self.assertIn(b'January', + stdout) + + def test_html_output_year_encoding(self): + stdout = self.run_ok('-t', 'html', '--encoding', 'ascii', '2004') + self.assertEqual(stdout, + (result_2004_html % {'e': 'ascii'}).encode('ascii')) -def test_main(): - support.run_unittest( - OutputTestCase, - CalendarTestCase, - MondayTestCase, - SundayTestCase, - TimegmTestCase, - MonthRangeTestCase, - LeapdaysTestCase, - ConsoleOutputTestCase - ) + def test_html_output_year_css(self): + self.assertFailure('-t', 'html', '-c') + self.assertFailure('-t', 'html', '--css') + stdout = self.run_ok('-t', 'html', '--css', 'custom.css', '2004') + self.assertIn(b'', stdout) if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py index 22c8eb0709ce..de8d65a963ce 100644 --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -18,7 +18,8 @@ import threading except ImportError: threading = None -import _testcapi +# Skip this test if the _testcapi module isn't available. +_testcapi = support.import_module('_testcapi') def testfunction(self): @@ -125,20 +126,46 @@ def test_docstring_signature_parsing(self): self.assertEqual(_testcapi.docstring_no_signature.__text_signature__, None) self.assertEqual(_testcapi.docstring_with_invalid_signature.__doc__, - "docstring_with_invalid_signature (boo)\n" + "docstring_with_invalid_signature($module, /, boo)\n" "\n" "This docstring has an invalid signature." ) self.assertEqual(_testcapi.docstring_with_invalid_signature.__text_signature__, None) + self.assertEqual(_testcapi.docstring_with_invalid_signature2.__doc__, + "docstring_with_invalid_signature2($module, /, boo)\n" + "\n" + "--\n" + "\n" + "This docstring also has an invalid signature." + ) + self.assertEqual(_testcapi.docstring_with_invalid_signature2.__text_signature__, None) + self.assertEqual(_testcapi.docstring_with_signature.__doc__, "This docstring has a valid signature.") - self.assertEqual(_testcapi.docstring_with_signature.__text_signature__, "(sig)") + self.assertEqual(_testcapi.docstring_with_signature.__text_signature__, "($module, /, sig)") self.assertEqual(_testcapi.docstring_with_signature_and_extra_newlines.__doc__, - "This docstring has a valid signature and some extra newlines.") + "\nThis docstring has a valid signature and some extra newlines.") self.assertEqual(_testcapi.docstring_with_signature_and_extra_newlines.__text_signature__, - "(parameter)") + "($module, /, parameter)") + + def test_c_type_with_matrix_multiplication(self): + M = _testcapi.matmulType + m1 = M() + m2 = M() + self.assertEqual(m1 @ m2, ("matmul", m1, m2)) + self.assertEqual(m1 @ 42, ("matmul", m1, 42)) + self.assertEqual(42 @ m1, ("matmul", 42, m1)) + o = m1 + o @= m2 + self.assertEqual(o, ("imatmul", m1, m2)) + o = m1 + o @= 42 + self.assertEqual(o, ("imatmul", m1, 42)) + o = 42 + o @= m1 + self.assertEqual(o, ("matmul", 42, m1)) @unittest.skipUnless(threading, 'Threading required for this test.') @@ -258,7 +285,7 @@ def setUp(self): exename += ext exepath = os.path.dirname(sys.executable) else: - exepath = os.path.join(basepath, "Modules") + exepath = os.path.join(basepath, "Programs") self.test_exe = exe = os.path.join(exepath, exename) if not os.path.exists(exe): self.skipTest("%r doesn't exist" % exe) @@ -277,12 +304,13 @@ def run_embedded_interpreter(self, *args): cmd.extend(args) p = subprocess.Popen(cmd, stdout=subprocess.PIPE, - stderr=subprocess.PIPE) + stderr=subprocess.PIPE, + universal_newlines=True) (out, err) = p.communicate() self.assertEqual(p.returncode, 0, "bad returncode %d, stderr is %r" % (p.returncode, err)) - return out.decode("latin1"), err.decode("latin1") + return out, err def test_subinterps(self): # This is just a "don't crash" test @@ -309,34 +337,38 @@ def test_forced_io_encoding(self): print() print(out) print(err) + expected_errors = sys.__stdout__.errors expected_stdin_encoding = sys.__stdin__.encoding expected_pipe_encoding = self._get_default_pipe_encoding() - expected_output = os.linesep.join([ + expected_output = '\n'.join([ "--- Use defaults ---", "Expected encoding: default", "Expected errors: default", - "stdin: {0}:strict", - "stdout: {1}:strict", - "stderr: {1}:backslashreplace", + "stdin: {in_encoding}:{errors}", + "stdout: {out_encoding}:{errors}", + "stderr: {out_encoding}:backslashreplace", "--- Set errors only ---", "Expected encoding: default", - "Expected errors: surrogateescape", - "stdin: {0}:surrogateescape", - "stdout: {1}:surrogateescape", - "stderr: {1}:backslashreplace", + "Expected errors: ignore", + "stdin: {in_encoding}:ignore", + "stdout: {out_encoding}:ignore", + "stderr: {out_encoding}:backslashreplace", "--- Set encoding only ---", "Expected encoding: latin-1", "Expected errors: default", - "stdin: latin-1:strict", - "stdout: latin-1:strict", + "stdin: latin-1:{errors}", + "stdout: latin-1:{errors}", "stderr: latin-1:backslashreplace", "--- Set encoding and errors ---", "Expected encoding: latin-1", - "Expected errors: surrogateescape", - "stdin: latin-1:surrogateescape", - "stdout: latin-1:surrogateescape", - "stderr: latin-1:backslashreplace"]).format(expected_stdin_encoding, - expected_pipe_encoding) + "Expected errors: replace", + "stdin: latin-1:replace", + "stdout: latin-1:replace", + "stderr: latin-1:backslashreplace"]) + expected_output = expected_output.format( + in_encoding=expected_stdin_encoding, + out_encoding=expected_pipe_encoding, + errors=expected_errors) # This is useful if we ever trip over odd platform behaviour self.maxDiff = None self.assertEqual(out.strip(), expected_output) diff --git a/Lib/test/test_cgi.py b/Lib/test/test_cgi.py index d80ec0776787..715bd73279d5 100644 --- a/Lib/test/test_cgi.py +++ b/Lib/test/test_cgi.py @@ -1,4 +1,4 @@ -from test.support import run_unittest, check_warnings +from test.support import check_warnings import cgi import os import sys @@ -137,6 +137,13 @@ def test_fieldstorage_properties(self): fs.list.append(namedtuple('MockFieldStorage', 'name')('fieldvalue')) self.assertTrue(fs) + def test_fieldstorage_invalid(self): + self.assertRaises(TypeError, cgi.FieldStorage, "not-a-file-obj", + environ={"REQUEST_METHOD":"PUT"}) + self.assertRaises(TypeError, cgi.FieldStorage, "foo", "bar") + fs = cgi.FieldStorage(headers={'content-type':'text/plain'}) + self.assertRaises(TypeError, bool, fs) + def test_escape(self): # cgi.escape() is deprecated. with warnings.catch_warnings(): @@ -179,9 +186,9 @@ def test_log(self): cgi.initlog("%s", "Testing initlog 1") cgi.log("%s", "Testing log 2") self.assertEqual(cgi.logfp.getvalue(), "Testing initlog 1\nTesting log 2\n") - if os.path.exists("/dev/null"): + if os.path.exists(os.devnull): cgi.logfp = None - cgi.logfile = "/dev/null" + cgi.logfile = os.devnull cgi.initlog("%s", "Testing log 3") self.addCleanup(cgi.closelog) cgi.log("Testing log 4") @@ -220,7 +227,7 @@ def __getattr__(self, name): # if we're not chunking properly, readline is only called twice # (by read_binary); if we are chunking properly, it will be called 5 times # as long as the chunksize is 1 << 16. - self.assertTrue(f.numcalls > 2) + self.assertGreater(f.numcalls, 2) f.close() def test_fieldstorage_multipart(self): @@ -300,6 +307,17 @@ def test_fieldstorage_multipart_w3c(self): got = getattr(files[x], k) self.assertEqual(got, exp) + def test_fieldstorage_as_context_manager(self): + fp = BytesIO(b'x' * 10) + env = {'REQUEST_METHOD': 'PUT'} + with cgi.FieldStorage(fp=fp, environ=env) as fs: + content = fs.file.read() + self.assertFalse(fs.file.closed) + self.assertTrue(fs.file.closed) + self.assertEqual(content, 'x' * 10) + with self.assertRaisesRegex(ValueError, 'I/O operation on closed file'): + fs.file.read() + _qs_result = { 'key1': 'value1', 'key2': ['value2x', 'value2y'], @@ -474,9 +492,5 @@ def test_parse_header(self): --AaB03x-- """ - -def test_main(): - run_unittest(CgiTests) - if __name__ == '__main__': - test_main() + unittest.main() diff --git a/Lib/test/test_cmd.py b/Lib/test/test_cmd.py index 661853582372..0c31454456d0 100644 --- a/Lib/test/test_cmd.py +++ b/Lib/test/test_cmd.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 """ Test script for the 'cmd' module Original by Michael Schneider @@ -230,7 +229,7 @@ def test_coverage(coverdir): trace = support.import_module('trace') tracer=trace.Trace(ignoredirs=[sys.base_prefix, sys.base_exec_prefix,], trace=0, count=1) - tracer.run('reload(cmd);test_main()') + tracer.run('import importlib; importlib.reload(cmd); test_main()') r=tracer.results() print("Writing coverage results...") r.write_results(show_missing=True, summary=True, coverdir=coverdir) diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py index 327c1455fcf7..ebe557e73cd0 100644 --- a/Lib/test/test_cmd_line.py +++ b/Lib/test/test_cmd_line.py @@ -8,6 +8,7 @@ import sys import subprocess import tempfile +from test import script_helper from test.script_helper import (spawn_python, kill_python, assert_python_ok, assert_python_failure) @@ -439,7 +440,8 @@ def test_unknown_options(self): self.assertEqual(err.splitlines().count(b'Unknown option: -a'), 1) self.assertEqual(b'', out) - + @unittest.skipIf(script_helper.interpreter_requires_environment(), + 'Cannot run -I tests when PYTHON env vars are required.') def test_isolatedmode(self): self.verify_valid_flag('-I') self.verify_valid_flag('-IEs') diff --git a/Lib/test/test_cmd_line_script.py b/Lib/test/test_cmd_line_script.py index f804d8645f68..88a9e2bbb523 100644 --- a/Lib/test/test_cmd_line_script.py +++ b/Lib/test/test_cmd_line_script.py @@ -1,5 +1,6 @@ # tests command line execution of scripts +import contextlib import importlib import importlib.machinery import zipimport @@ -8,6 +9,7 @@ import os import os.path import py_compile +import subprocess import textwrap from test import support @@ -41,11 +43,28 @@ def f(): _loader = __loader__ if __loader__ is BuiltinImporter else type(__loader__) print('__loader__==%a' % _loader) print('__file__==%a' % __file__) -assertEqual(__cached__, None) +print('__cached__==%a' % __cached__) print('__package__==%r' % __package__) +# Check PEP 451 details +import os.path +if __package__ is not None: + print('__main__ was located through the import system') + assertIdentical(__spec__.loader, __loader__) + expected_spec_name = os.path.splitext(os.path.basename(__file__))[0] + if __package__: + expected_spec_name = __package__ + "." + expected_spec_name + assertEqual(__spec__.name, expected_spec_name) + assertEqual(__spec__.parent, __package__) + assertIdentical(__spec__.submodule_search_locations, None) + assertEqual(__spec__.origin, __file__) + if __spec__.cached is not None: + assertEqual(__spec__.cached, __cached__) # Check the sys module import sys assertIdentical(globals(), sys.modules[__name__].__dict__) +if __spec__ is not None: + # XXX: We're not currently making __main__ available under its real name + pass # assertIdentical(globals(), sys.modules[__spec__.name].__dict__) from test import test_cmd_line_script example_args_list = test_cmd_line_script.example_args assertEqual(sys.argv[1:], example_args_list) @@ -156,6 +175,53 @@ def test_stdin_loader(self): expected = repr(importlib.machinery.BuiltinImporter).encode("utf-8") self.assertIn(expected, out) + @contextlib.contextmanager + def interactive_python(self, separate_stderr=False): + if separate_stderr: + p = spawn_python('-i', bufsize=1, stderr=subprocess.PIPE) + stderr = p.stderr + else: + p = spawn_python('-i', bufsize=1, stderr=subprocess.STDOUT) + stderr = p.stdout + try: + # Drain stderr until prompt + while True: + data = stderr.read(4) + if data == b">>> ": + break + stderr.readline() + yield p + finally: + kill_python(p) + stderr.close() + + def check_repl_stdout_flush(self, separate_stderr=False): + with self.interactive_python(separate_stderr) as p: + p.stdin.write(b"print('foo')\n") + p.stdin.flush() + self.assertEqual(b'foo', p.stdout.readline().strip()) + + def check_repl_stderr_flush(self, separate_stderr=False): + with self.interactive_python(separate_stderr) as p: + p.stdin.write(b"1/0\n") + p.stdin.flush() + stderr = p.stderr if separate_stderr else p.stdout + self.assertIn(b'Traceback ', stderr.readline()) + self.assertIn(b'File ""', stderr.readline()) + self.assertIn(b'ZeroDivisionError', stderr.readline()) + + def test_repl_stdout_flush(self): + self.check_repl_stdout_flush() + + def test_repl_stdout_flush_separate_stderr(self): + self.check_repl_stdout_flush(True) + + def test_repl_stderr_flush(self): + self.check_repl_stderr_flush() + + def test_repl_stderr_flush_separate_stderr(self): + self.check_repl_stderr_flush(True) + def test_basic_script(self): with temp_dir() as script_dir: script_name = _make_test_script(script_dir, 'script') @@ -388,6 +454,24 @@ def test_non_ascii(self): 'stdout=%r stderr=%r' % (stdout, stderr)) self.assertEqual(0, rc) + def test_issue20500_exit_with_exception_value(self): + script = textwrap.dedent("""\ + import sys + error = None + try: + raise ValueError('some text') + except ValueError as err: + error = err + + if error: + sys.exit(error) + """) + with temp_dir() as script_dir: + script_name = _make_test_script(script_dir, 'script', script) + exitcode, stdout, stderr = assert_python_failure(script_name) + text = stderr.decode('ascii') + self.assertEqual(text, "some text") + def test_main(): support.run_unittest(CmdLineTest) diff --git a/Lib/test/test_code.py b/Lib/test/test_code.py index 3377a7b07a8c..21b12a56e4a8 100644 --- a/Lib/test/test_code.py +++ b/Lib/test/test_code.py @@ -104,7 +104,7 @@ import unittest import weakref -import _testcapi +from test.support import run_doctest, run_unittest, cpython_only def consts(t): @@ -126,7 +126,9 @@ def dump(co): class CodeTest(unittest.TestCase): + @cpython_only def test_newempty(self): + import _testcapi co = _testcapi.code_newempty("filename", "funcname", 15) self.assertEqual(co.co_filename, "filename") self.assertEqual(co.co_name, "funcname") @@ -159,7 +161,6 @@ def callback(code): def test_main(verbose=None): - from test.support import run_doctest, run_unittest from test import test_code run_doctest(test_code, verbose) run_unittest(CodeTest, CodeWeakRefTest) diff --git a/Lib/test/test_code_module.py b/Lib/test/test_code_module.py index 5fd21dc32c61..9b177672b432 100644 --- a/Lib/test/test_code_module.py +++ b/Lib/test/test_code_module.py @@ -1,6 +1,7 @@ "Test InteractiveConsole and InteractiveInterpreter from code module" import sys import unittest +from textwrap import dedent from contextlib import ExitStack from unittest import mock from test import support @@ -51,7 +52,7 @@ def test_syntax_error(self): self.infunc.side_effect = ["undefined", EOFError('Finished')] self.console.interact() for call in self.stderr.method_calls: - if 'NameError:' in ''.join(call[1]): + if 'NameError' in ''.join(call[1]): break else: raise AssertionError("No syntax error from console") @@ -78,6 +79,40 @@ def test_banner(self): self.console.interact(banner='') self.assertEqual(len(self.stderr.method_calls), 1) + def test_cause_tb(self): + self.infunc.side_effect = ["raise ValueError('') from AttributeError", + EOFError('Finished')] + self.console.interact() + output = ''.join(''.join(call[1]) for call in self.stderr.method_calls) + expected = dedent(""" + AttributeError + + The above exception was the direct cause of the following exception: + + Traceback (most recent call last): + File "", line 1, in + ValueError + """) + self.assertIn(expected, output) + + def test_context_tb(self): + self.infunc.side_effect = ["try: ham\nexcept: eggs\n", + EOFError('Finished')] + self.console.interact() + output = ''.join(''.join(call[1]) for call in self.stderr.method_calls) + expected = dedent(""" + Traceback (most recent call last): + File "", line 1, in + NameError: name 'ham' is not defined + + During handling of the above exception, another exception occurred: + + Traceback (most recent call last): + File "", line 2, in + NameError: name 'eggs' is not defined + """) + self.assertIn(expected, output) + def test_main(): support.run_unittest(TestInteractiveConsole) diff --git a/Lib/test/test_codeccallbacks.py b/Lib/test/test_codeccallbacks.py index 84804bb0dafa..e29ac53039eb 100644 --- a/Lib/test/test_codeccallbacks.py +++ b/Lib/test/test_codeccallbacks.py @@ -158,6 +158,22 @@ def test_backslashescape(self): sout = b"a\xac\\u1234\xa4\\u8000\\U0010ffff" self.assertEqual(sin.encode("iso-8859-15", "backslashreplace"), sout) + def test_nameescape(self): + # Does the same as backslashescape, but prefers ``\N{...}`` escape + # sequences. + sin = "a\xac\u1234\u20ac\u8000\U0010ffff" + sout = (b'a\\N{NOT SIGN}\\N{ETHIOPIC SYLLABLE SEE}\\N{EURO SIGN}' + b'\\N{CJK UNIFIED IDEOGRAPH-8000}\\U0010ffff') + self.assertEqual(sin.encode("ascii", "namereplace"), sout) + + sout = (b'a\xac\\N{ETHIOPIC SYLLABLE SEE}\\N{EURO SIGN}' + b'\\N{CJK UNIFIED IDEOGRAPH-8000}\\U0010ffff') + self.assertEqual(sin.encode("latin-1", "namereplace"), sout) + + sout = (b'a\xac\\N{ETHIOPIC SYLLABLE SEE}\xa4' + b'\\N{CJK UNIFIED IDEOGRAPH-8000}\\U0010ffff') + self.assertEqual(sin.encode("iso-8859-15", "namereplace"), sout) + def test_decoding_callbacks(self): # This is a test for a decoding callback handler # that allows the decoding of the invalid sequence @@ -230,6 +246,11 @@ def handler_unicodeinternal(exc): "\u0000\ufffd" ) + self.assertEqual( + b"\x00\x00\x00\x00\x00".decode("unicode-internal", "backslashreplace"), + "\u0000\\x00" + ) + codecs.register_error("test.hui", handler_unicodeinternal) self.assertEqual( @@ -297,7 +318,7 @@ def handler2(exc): def test_longstrings(self): # test long strings to check for memory overflow problems errors = [ "strict", "ignore", "replace", "xmlcharrefreplace", - "backslashreplace"] + "backslashreplace", "namereplace"] # register the handlers under different names, # to prevent the codec from recognizing the name for err in errors: @@ -549,17 +570,6 @@ def test_badandgoodbackslashreplaceexceptions(self): codecs.backslashreplace_errors, UnicodeError("ouch") ) - # "backslashreplace" can only be used for encoding - self.assertRaises( - TypeError, - codecs.backslashreplace_errors, - UnicodeDecodeError("ascii", bytearray(b"\xff"), 0, 1, "ouch") - ) - self.assertRaises( - TypeError, - codecs.backslashreplace_errors, - UnicodeTranslateError("\u3042", 0, 1, "ouch") - ) # Use the correct exception self.assertEqual( codecs.backslashreplace_errors( @@ -611,6 +621,91 @@ def test_badandgoodbackslashreplaceexceptions(self): ("\\udfff", 1) ) + def test_badandgoodnamereplaceexceptions(self): + # "namereplace" complains about a non-exception passed in + self.assertRaises( + TypeError, + codecs.namereplace_errors, + 42 + ) + # "namereplace" complains about the wrong exception types + self.assertRaises( + TypeError, + codecs.namereplace_errors, + UnicodeError("ouch") + ) + # "namereplace" can only be used for encoding + self.assertRaises( + TypeError, + codecs.namereplace_errors, + UnicodeDecodeError("ascii", bytearray(b"\xff"), 0, 1, "ouch") + ) + self.assertRaises( + TypeError, + codecs.namereplace_errors, + UnicodeTranslateError("\u3042", 0, 1, "ouch") + ) + # Use the correct exception + self.assertEqual( + codecs.namereplace_errors( + UnicodeEncodeError("ascii", "\u3042", 0, 1, "ouch")), + ("\\N{HIRAGANA LETTER A}", 1) + ) + self.assertEqual( + codecs.namereplace_errors( + UnicodeEncodeError("ascii", "\x00", 0, 1, "ouch")), + ("\\x00", 1) + ) + self.assertEqual( + codecs.namereplace_errors( + UnicodeEncodeError("ascii", "\xff", 0, 1, "ouch")), + ("\\N{LATIN SMALL LETTER Y WITH DIAERESIS}", 1) + ) + self.assertEqual( + codecs.namereplace_errors( + UnicodeEncodeError("ascii", "\u0100", 0, 1, "ouch")), + ("\\N{LATIN CAPITAL LETTER A WITH MACRON}", 1) + ) + self.assertEqual( + codecs.namereplace_errors( + UnicodeEncodeError("ascii", "\uffff", 0, 1, "ouch")), + ("\\uffff", 1) + ) + if SIZEOF_WCHAR_T > 0: + self.assertEqual( + codecs.namereplace_errors( + UnicodeEncodeError("ascii", "\U00010000", + 0, 1, "ouch")), + ("\\N{LINEAR B SYLLABLE B008 A}", 1) + ) + self.assertEqual( + codecs.namereplace_errors( + UnicodeEncodeError("ascii", "\U0010ffff", + 0, 1, "ouch")), + ("\\U0010ffff", 1) + ) + # Lone surrogates (regardless of unicode width) + self.assertEqual( + codecs.namereplace_errors( + UnicodeEncodeError("ascii", "\ud800", 0, 1, "ouch")), + ("\\ud800", 1) + ) + self.assertEqual( + codecs.namereplace_errors( + UnicodeEncodeError("ascii", "\udfff", 0, 1, "ouch")), + ("\\udfff", 1) + ) + self.assertEqual( + codecs.backslashreplace_errors( + UnicodeDecodeError("ascii", bytearray(b"\xff"), 0, 1, "ouch")), + ("\\xff", 1) + ) + self.assertEqual( + codecs.backslashreplace_errors( + UnicodeTranslateError("\u3042", 0, 1, "ouch")), + ("\\u3042", 1) + ) + def test_badhandlerresults(self): results = ( 42, "foo", (1,2,3), ("foo", 1, 3), ("foo", None), ("foo",), ("foo", 1, 3), ("foo", None), ("foo",) ) encs = ("ascii", "latin-1", "iso-8859-1", "iso-8859-15") @@ -651,6 +746,10 @@ def test_lookup(self): codecs.backslashreplace_errors, codecs.lookup_error("backslashreplace") ) + self.assertEqual( + codecs.namereplace_errors, + codecs.lookup_error("namereplace") + ) def test_unencodablereplacement(self): def unencrepl(exc): @@ -804,7 +903,8 @@ def badencodereturn2(exc): class D(dict): def __getitem__(self, key): raise ValueError - for err in ("strict", "replace", "xmlcharrefreplace", "backslashreplace", "test.posreturn"): + for err in ("strict", "replace", "xmlcharrefreplace", + "backslashreplace", "namereplace", "test.posreturn"): self.assertRaises(UnicodeError, codecs.charmap_encode, "\xff", err, {0xff: None}) self.assertRaises(ValueError, codecs.charmap_encode, "\xff", err, D()) self.assertRaises(TypeError, codecs.charmap_encode, "\xff", err, {0xff: 300}) @@ -819,7 +919,7 @@ class D(dict): def __getitem__(self, key): raise ValueError #self.assertRaises(ValueError, "\xff".translate, D()) - self.assertRaises(TypeError, "\xff".translate, {0xff: sys.maxunicode+1}) + self.assertRaises(ValueError, "\xff".translate, {0xff: sys.maxunicode+1}) self.assertRaises(TypeError, "\xff".translate, {0xff: ()}) def test_bug828737(self): diff --git a/Lib/test/test_codecencodings_cn.py b/Lib/test/test_codecencodings_cn.py index b08c5fcb1a7f..60e69eb76267 100644 --- a/Lib/test/test_codecencodings_cn.py +++ b/Lib/test/test_codecencodings_cn.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 # # test_codecencodings_cn.py # Codec encoding tests for PRC encodings. diff --git a/Lib/test/test_codecencodings_hk.py b/Lib/test/test_codecencodings_hk.py index 31363f4bea87..25c05b6048f7 100644 --- a/Lib/test/test_codecencodings_hk.py +++ b/Lib/test/test_codecencodings_hk.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 # # test_codecencodings_hk.py # Codec encoding tests for HongKong encodings. diff --git a/Lib/test/test_codecencodings_iso2022.py b/Lib/test/test_codecencodings_iso2022.py index e4c1839b4267..87768646fe46 100644 --- a/Lib/test/test_codecencodings_iso2022.py +++ b/Lib/test/test_codecencodings_iso2022.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python -# # Codec encoding tests for ISO 2022 encodings. from test import support @@ -36,6 +34,7 @@ class Test_ISO2022_KR(multibytecodec_support.TestBase, unittest.TestCase): # iso2022_kr.txt cannot be used to test "chunk coding": the escape # sequence is only written on the first line + @unittest.skip('iso2022_kr.txt cannot be used to test "chunk coding"') def test_chunkcoding(self): pass diff --git a/Lib/test/test_codecencodings_jp.py b/Lib/test/test_codecencodings_jp.py index 30c9e195f317..4091948b9b80 100644 --- a/Lib/test/test_codecencodings_jp.py +++ b/Lib/test/test_codecencodings_jp.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 # # test_codecencodings_jp.py # Codec encoding tests for Japanese encodings. diff --git a/Lib/test/test_codecencodings_kr.py b/Lib/test/test_codecencodings_kr.py index 4dd60499c87f..cd7696acaa34 100644 --- a/Lib/test/test_codecencodings_kr.py +++ b/Lib/test/test_codecencodings_kr.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 # # test_codecencodings_kr.py # Codec encoding tests for ROK encodings. diff --git a/Lib/test/test_codecencodings_tw.py b/Lib/test/test_codecencodings_tw.py index 96245b74ed34..ea6e1c162398 100644 --- a/Lib/test/test_codecencodings_tw.py +++ b/Lib/test/test_codecencodings_tw.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 # # test_codecencodings_tw.py # Codec encoding tests for ROC encodings. diff --git a/Lib/test/test_codecmaps_cn.py b/Lib/test/test_codecmaps_cn.py index 1a761cffc763..f1bd3840c9ab 100644 --- a/Lib/test/test_codecmaps_cn.py +++ b/Lib/test/test_codecmaps_cn.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 # # test_codecmaps_cn.py # Codec mapping tests for PRC encodings @@ -11,23 +10,18 @@ class TestGB2312Map(multibytecodec_support.TestBase_Mapping, unittest.TestCase): encoding = 'gb2312' - mapfileurl = 'http://people.freebsd.org/~perky/i18n/EUC-CN.TXT' + mapfileurl = 'http://www.pythontest.net/unicode/EUC-CN.TXT' class TestGBKMap(multibytecodec_support.TestBase_Mapping, unittest.TestCase): encoding = 'gbk' - mapfileurl = 'http://www.unicode.org/Public/MAPPINGS/VENDORS/' \ - 'MICSFT/WINDOWS/CP936.TXT' + mapfileurl = 'http://www.pythontest.net/unicode/CP936.TXT' class TestGB18030Map(multibytecodec_support.TestBase_Mapping, unittest.TestCase): encoding = 'gb18030' - mapfileurl = 'http://source.icu-project.org/repos/icu/data/' \ - 'trunk/charset/data/xml/gb-18030-2000.xml' + mapfileurl = 'http://www.pythontest.net/unicode/gb-18030-2000.xml' -def test_main(): - support.run_unittest(__name__) - if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_codecmaps_hk.py b/Lib/test/test_codecmaps_hk.py index 5f4e7c7e0201..4c0c4156da9d 100644 --- a/Lib/test/test_codecmaps_hk.py +++ b/Lib/test/test_codecmaps_hk.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 # # test_codecmaps_hk.py # Codec mapping tests for HongKong encodings @@ -11,11 +10,7 @@ class TestBig5HKSCSMap(multibytecodec_support.TestBase_Mapping, unittest.TestCase): encoding = 'big5hkscs' - mapfileurl = 'http://people.freebsd.org/~perky/i18n/BIG5HKSCS-2004.TXT' - -def test_main(): - support.run_unittest(__name__) + mapfileurl = 'http://www.pythontest.net/unicode/BIG5HKSCS-2004.TXT' if __name__ == "__main__": - support.use_resources = ['urlfetch'] - test_main() + unittest.main() diff --git a/Lib/test/test_codecmaps_jp.py b/Lib/test/test_codecmaps_jp.py index 1fdbf634e3ac..577382329a90 100644 --- a/Lib/test/test_codecmaps_jp.py +++ b/Lib/test/test_codecmaps_jp.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 # # test_codecmaps_jp.py # Codec mapping tests for Japanese encodings @@ -11,8 +10,7 @@ class TestCP932Map(multibytecodec_support.TestBase_Mapping, unittest.TestCase): encoding = 'cp932' - mapfileurl = 'http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/' \ - 'WINDOWS/CP932.TXT' + mapfileurl = 'http://www.pythontest.net/unicode/CP932.TXT' supmaps = [ (b'\x80', '\u0080'), (b'\xa0', '\uf8f0'), @@ -28,15 +26,14 @@ class TestEUCJPCOMPATMap(multibytecodec_support.TestBase_Mapping, unittest.TestCase): encoding = 'euc_jp' mapfilename = 'EUC-JP.TXT' - mapfileurl = 'http://people.freebsd.org/~perky/i18n/EUC-JP.TXT' + mapfileurl = 'http://www.pythontest.net/unicode/EUC-JP.TXT' class TestSJISCOMPATMap(multibytecodec_support.TestBase_Mapping, unittest.TestCase): encoding = 'shift_jis' mapfilename = 'SHIFTJIS.TXT' - mapfileurl = 'http://www.unicode.org/Public/MAPPINGS/OBSOLETE' \ - '/EASTASIA/JIS/SHIFTJIS.TXT' + mapfileurl = 'http://www.pythontest.net/unicode/SHIFTJIS.TXT' pass_enctest = [ (b'\x81_', '\\'), ] @@ -50,18 +47,15 @@ class TestEUCJISX0213Map(multibytecodec_support.TestBase_Mapping, unittest.TestCase): encoding = 'euc_jisx0213' mapfilename = 'EUC-JISX0213.TXT' - mapfileurl = 'http://people.freebsd.org/~perky/i18n/EUC-JISX0213.TXT' + mapfileurl = 'http://www.pythontest.net/unicode/EUC-JISX0213.TXT' class TestSJISX0213Map(multibytecodec_support.TestBase_Mapping, unittest.TestCase): encoding = 'shift_jisx0213' mapfilename = 'SHIFT_JISX0213.TXT' - mapfileurl = 'http://people.freebsd.org/~perky/i18n/SHIFT_JISX0213.TXT' + mapfileurl = 'http://www.pythontest.net/unicode/SHIFT_JISX0213.TXT' -def test_main(): - support.run_unittest(__name__) - if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_codecmaps_kr.py b/Lib/test/test_codecmaps_kr.py index 03564025ed25..6cb41c8b290d 100644 --- a/Lib/test/test_codecmaps_kr.py +++ b/Lib/test/test_codecmaps_kr.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 # # test_codecmaps_kr.py # Codec mapping tests for ROK encodings @@ -11,14 +10,13 @@ class TestCP949Map(multibytecodec_support.TestBase_Mapping, unittest.TestCase): encoding = 'cp949' - mapfileurl = 'http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT' \ - '/WINDOWS/CP949.TXT' + mapfileurl = 'http://www.pythontest.net/unicode/CP949.TXT' class TestEUCKRMap(multibytecodec_support.TestBase_Mapping, unittest.TestCase): encoding = 'euc_kr' - mapfileurl = 'http://people.freebsd.org/~perky/i18n/EUC-KR.TXT' + mapfileurl = 'http://www.pythontest.net/unicode/EUC-KR.TXT' # A4D4 HANGUL FILLER indicates the begin of 8-bytes make-up sequence. pass_enctest = [(b'\xa4\xd4', '\u3164')] @@ -28,8 +26,7 @@ class TestEUCKRMap(multibytecodec_support.TestBase_Mapping, class TestJOHABMap(multibytecodec_support.TestBase_Mapping, unittest.TestCase): encoding = 'johab' - mapfileurl = 'http://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/' \ - 'KSC/JOHAB.TXT' + mapfileurl = 'http://www.pythontest.net/unicode/JOHAB.TXT' # KS X 1001 standard assigned 0x5c as WON SIGN. # but, in early 90s that is the only era used johab widely, # the most softwares implements it as REVERSE SOLIDUS. @@ -37,8 +34,5 @@ class TestJOHABMap(multibytecodec_support.TestBase_Mapping, pass_enctest = [(b'\\', '\u20a9')] pass_dectest = [(b'\\', '\u20a9')] -def test_main(): - support.run_unittest(__name__) - if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_codecmaps_tw.py b/Lib/test/test_codecmaps_tw.py index 44467e378a72..2ea44b56f1f6 100644 --- a/Lib/test/test_codecmaps_tw.py +++ b/Lib/test/test_codecmaps_tw.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 # # test_codecmaps_tw.py # Codec mapping tests for ROC encodings @@ -11,14 +10,12 @@ class TestBIG5Map(multibytecodec_support.TestBase_Mapping, unittest.TestCase): encoding = 'big5' - mapfileurl = 'http://www.unicode.org/Public/MAPPINGS/OBSOLETE/' \ - 'EASTASIA/OTHER/BIG5.TXT' + mapfileurl = 'http://www.pythontest.net/unicode/BIG5.TXT' class TestCP950Map(multibytecodec_support.TestBase_Mapping, unittest.TestCase): encoding = 'cp950' - mapfileurl = 'http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/' \ - 'WINDOWS/CP950.TXT' + mapfileurl = 'http://www.pythontest.net/unicode/CP950.TXT' pass_enctest = [ (b'\xa2\xcc', '\u5341'), (b'\xa2\xce', '\u5345'), @@ -27,8 +24,5 @@ class TestCP950Map(multibytecodec_support.TestBase_Mapping, (b"\xFFxy", "replace", "\ufffdxy"), ) -def test_main(): - support.run_unittest(__name__) - if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py index f6823805feec..4d5d7bbba831 100644 --- a/Lib/test/test_codecs.py +++ b/Lib/test/test_codecs.py @@ -1,4 +1,3 @@ -import _testcapi import codecs import contextlib import io @@ -148,19 +147,20 @@ def readalllines(input, keepends=True, size=None): self.assertEqual(readalllines(s, True, 10), sexpected) self.assertEqual(readalllines(s, False, 10), sexpectednoends) + lineends = ("\n", "\r\n", "\r", "\u2028") # Test long lines (multiple calls to read() in readline()) vw = [] vwo = [] - for (i, lineend) in enumerate("\n \r\n \r \u2028".split()): - vw.append((i*200)*"\3042" + lineend) - vwo.append((i*200)*"\3042") - self.assertEqual(readalllines("".join(vw), True), "".join(vw)) - self.assertEqual(readalllines("".join(vw), False),"".join(vwo)) + for (i, lineend) in enumerate(lineends): + vw.append((i*200+200)*"\u3042" + lineend) + vwo.append((i*200+200)*"\u3042") + self.assertEqual(readalllines("".join(vw), True), "|".join(vw)) + self.assertEqual(readalllines("".join(vw), False), "|".join(vwo)) # Test lines where the first read might end with \r, so the # reader has to look ahead whether this is a lone \r or a \r\n for size in range(80): - for lineend in "\n \r\n \r \u2028".split(): + for lineend in lineends: s = 10*(size*"a" + lineend + "xxx\n") reader = getreader(s) for i in range(10): @@ -168,12 +168,54 @@ def readalllines(input, keepends=True, size=None): reader.readline(keepends=True), size*"a" + lineend, ) + self.assertEqual( + reader.readline(keepends=True), + "xxx\n", + ) reader = getreader(s) for i in range(10): self.assertEqual( reader.readline(keepends=False), size*"a", ) + self.assertEqual( + reader.readline(keepends=False), + "xxx", + ) + + def test_mixed_readline_and_read(self): + lines = ["Humpty Dumpty sat on a wall,\n", + "Humpty Dumpty had a great fall.\r\n", + "All the king's horses and all the king's men\r", + "Couldn't put Humpty together again."] + data = ''.join(lines) + def getreader(): + stream = io.BytesIO(data.encode(self.encoding)) + return codecs.getreader(self.encoding)(stream) + + # Issue #8260: Test readline() followed by read() + f = getreader() + self.assertEqual(f.readline(), lines[0]) + self.assertEqual(f.read(), ''.join(lines[1:])) + self.assertEqual(f.read(), '') + + # Issue #16636: Test readline() followed by readlines() + f = getreader() + self.assertEqual(f.readline(), lines[0]) + self.assertEqual(f.readlines(), lines[1:]) + self.assertEqual(f.read(), '') + + # Test read() followed by read() + f = getreader() + self.assertEqual(f.read(size=40, chars=5), data[:5]) + self.assertEqual(f.read(), data[5:]) + self.assertEqual(f.read(), '') + + # Issue #12446: Test read() followed by readlines() + f = getreader() + self.assertEqual(f.read(size=40, chars=5), data[:5]) + self.assertEqual(f.readlines(), [lines[0][5:]] + lines[1:]) + self.assertEqual(f.read(), '') def test_bug1175396(self): s = [ @@ -307,6 +349,8 @@ def test_lone_surrogates(self): self.assertRaises(UnicodeEncodeError, "\ud800".encode, self.encoding) self.assertEqual("[\uDC80]".encode(self.encoding, "backslashreplace"), "[\\udc80]".encode(self.encoding)) + self.assertEqual("[\uDC80]".encode(self.encoding, "namereplace"), + "[\\udc80]".encode(self.encoding)) self.assertEqual("[\uDC80]".encode(self.encoding, "xmlcharrefreplace"), "[�]".encode(self.encoding)) self.assertEqual("[\uDC80]".encode(self.encoding, "ignore"), @@ -334,6 +378,10 @@ def test_lone_surrogates(self): before + after) self.assertEqual(test_sequence.decode(self.encoding, "replace"), before + self.ill_formed_sequence_replace + after) + backslashreplace = ''.join('\\x%02x' % b + for b in self.ill_formed_sequence) + self.assertEqual(test_sequence.decode(self.encoding, "backslashreplace"), + before + backslashreplace + after) class UTF32Test(ReadTest, unittest.TestCase): encoding = "utf-32" @@ -766,6 +814,7 @@ def test_encode(self): ('\udc80', 'ignore', b''), ('\udc80', 'replace', b'?'), ('\udc80', 'backslashreplace', b'\\udc80'), + ('\udc80', 'namereplace', b'\\udc80'), ('\udc80', 'surrogatepass', b'\xed\xb2\x80'), )) else: @@ -827,6 +876,8 @@ def test_lone_surrogates(self): self.assertRaises(UnicodeDecodeError, b"\xed\xa0\x80".decode, "cp65001") self.assertEqual("[\uDC80]".encode("cp65001", "backslashreplace"), b'[\\udc80]') + self.assertEqual("[\uDC80]".encode("cp65001", "namereplace"), + b'[\\udc80]') self.assertEqual("[\uDC80]".encode("cp65001", "xmlcharrefreplace"), b'[�]') self.assertEqual("[\uDC80]".encode("cp65001", "surrogateescape"), @@ -849,19 +900,45 @@ def test_surrogatepass_handler(self): self.assertTrue(codecs.lookup_error("surrogatepass")) - class UTF7Test(ReadTest, unittest.TestCase): encoding = "utf-7" def test_partial(self): self.check_partial( - "a+-b", + 'a+-b\x00c\x80d\u0100e\U00010000f', [ - "a", - "a", - "a+", - "a+-", - "a+-b", + 'a', + 'a', + 'a+', + 'a+-', + 'a+-b', + 'a+-b', + 'a+-b', + 'a+-b', + 'a+-b', + 'a+-b\x00', + 'a+-b\x00c', + 'a+-b\x00c', + 'a+-b\x00c', + 'a+-b\x00c', + 'a+-b\x00c', + 'a+-b\x00c\x80', + 'a+-b\x00c\x80d', + 'a+-b\x00c\x80d', + 'a+-b\x00c\x80d', + 'a+-b\x00c\x80d', + 'a+-b\x00c\x80d', + 'a+-b\x00c\x80d\u0100', + 'a+-b\x00c\x80d\u0100e', + 'a+-b\x00c\x80d\u0100e', + 'a+-b\x00c\x80d\u0100e', + 'a+-b\x00c\x80d\u0100e', + 'a+-b\x00c\x80d\u0100e', + 'a+-b\x00c\x80d\u0100e', + 'a+-b\x00c\x80d\u0100e', + 'a+-b\x00c\x80d\u0100e', + 'a+-b\x00c\x80d\u0100e\U00010000', + 'a+-b\x00c\x80d\u0100e\U00010000f', ] ) @@ -1067,6 +1144,8 @@ def test_recoding(self): # Python used to crash on this at exit because of a refcount # bug in _codecsmodule.c + self.assertTrue(f.closed) + # From RFC 3492 punycode_testcases = [ # A Arabic (Egyptian): @@ -1225,14 +1304,19 @@ def test_bug1251300(self): "unicode_internal") if sys.byteorder == "little": invalid = b"\x00\x00\x11\x00" + invalid_backslashreplace = r"\x00\x00\x11\x00" else: invalid = b"\x00\x11\x00\x00" + invalid_backslashreplace = r"\x00\x11\x00\x00" with support.check_warnings(): self.assertRaises(UnicodeDecodeError, invalid.decode, "unicode_internal") with support.check_warnings(): self.assertEqual(invalid.decode("unicode_internal", "replace"), '\ufffd') + with support.check_warnings(): + self.assertEqual(invalid.decode("unicode_internal", "backslashreplace"), + invalid_backslashreplace) @unittest.skipUnless(SIZEOF_WCHAR_T == 4, 'specific to 32-bit wchar_t') def test_decode_error_attributes(self): @@ -1519,6 +1603,16 @@ def test_incremental_encode(self): self.assertEqual(encoder.encode("ample.org."), b"xn--xample-9ta.org.") self.assertEqual(encoder.encode("", True), b"") + def test_errors(self): + """Only supports "strict" error handler""" + "python.org".encode("idna", "strict") + b"python.org".decode("idna", "strict") + for errors in ("ignore", "replace", "backslashreplace", + "surrogateescape"): + self.assertRaises(Exception, "python.org".encode, "idna", errors) + self.assertRaises(Exception, + b"python.org".decode, "idna", errors) + class CodecsModuleTest(unittest.TestCase): def test_decode(self): @@ -1528,6 +1622,12 @@ def test_decode(self): self.assertEqual(codecs.decode(b'abc'), 'abc') self.assertRaises(UnicodeDecodeError, codecs.decode, b'\xff', 'ascii') + # test keywords + self.assertEqual(codecs.decode(obj=b'\xe4\xf6\xfc', encoding='latin-1'), + '\xe4\xf6\xfc') + self.assertEqual(codecs.decode(b'[\xff]', 'ascii', errors='ignore'), + '[]') + def test_encode(self): self.assertEqual(codecs.encode('\xe4\xf6\xfc', 'latin-1'), b'\xe4\xf6\xfc') @@ -1536,6 +1636,12 @@ def test_encode(self): self.assertEqual(codecs.encode('abc'), b'abc') self.assertRaises(UnicodeEncodeError, codecs.encode, '\xffff', 'ascii') + # test keywords + self.assertEqual(codecs.encode(obj='\xe4\xf6\xfc', encoding='latin-1'), + b'\xe4\xf6\xfc') + self.assertEqual(codecs.encode('[\xff]', 'ascii', errors='ignore'), + b'[]') + def test_register(self): self.assertRaises(TypeError, codecs.register) self.assertRaises(TypeError, codecs.register, 42) @@ -1574,6 +1680,47 @@ def test_lookup_issue1813(self): c = codecs.lookup('ASCII') self.assertEqual(c.name, 'ascii') + def test_all(self): + api = ( + "encode", "decode", + "register", "CodecInfo", "Codec", "IncrementalEncoder", + "IncrementalDecoder", "StreamReader", "StreamWriter", "lookup", + "getencoder", "getdecoder", "getincrementalencoder", + "getincrementaldecoder", "getreader", "getwriter", + "register_error", "lookup_error", + "strict_errors", "replace_errors", "ignore_errors", + "xmlcharrefreplace_errors", "backslashreplace_errors", + "namereplace_errors", + "open", "EncodedFile", + "iterencode", "iterdecode", + "BOM", "BOM_BE", "BOM_LE", + "BOM_UTF8", "BOM_UTF16", "BOM_UTF16_BE", "BOM_UTF16_LE", + "BOM_UTF32", "BOM_UTF32_BE", "BOM_UTF32_LE", + "BOM32_BE", "BOM32_LE", "BOM64_BE", "BOM64_LE", # Undocumented + "StreamReaderWriter", "StreamRecoder", + ) + self.assertCountEqual(api, codecs.__all__) + for api in codecs.__all__: + getattr(codecs, api) + + def test_open(self): + self.addCleanup(support.unlink, support.TESTFN) + for mode in ('w', 'r', 'r+', 'w+', 'a', 'a+'): + with self.subTest(mode), \ + codecs.open(support.TESTFN, mode, 'ascii') as file: + self.assertIsInstance(file, codecs.StreamReaderWriter) + + def test_undefined(self): + self.assertRaises(UnicodeError, codecs.encode, 'abc', 'undefined') + self.assertRaises(UnicodeError, codecs.decode, b'abc', 'undefined') + self.assertRaises(UnicodeError, codecs.encode, '', 'undefined') + self.assertRaises(UnicodeError, codecs.decode, b'', 'undefined') + for errors in ('strict', 'ignore', 'replace', 'backslashreplace'): + self.assertRaises(UnicodeError, + codecs.encode, 'abc', 'undefined', errors) + self.assertRaises(UnicodeError, + codecs.decode, b'abc', 'undefined', errors) + class StreamReaderTest(unittest.TestCase): def setUp(self): @@ -1707,17 +1854,14 @@ def test_basic(self): # "undefined" # The following encodings don't work in stateful mode -broken_unicode_with_streams = [ +broken_unicode_with_stateful = [ "punycode", "unicode_internal" ] -broken_incremental_coders = broken_unicode_with_streams + [ - "idna", -] class BasicUnicodeTest(unittest.TestCase, MixInCheckStateHandling): def test_basics(self): - s = "abc123" # all codecs should be able to encode these + s = "abc123" # all codecs should be able to encode these for encoding in all_unicode_encodings: name = codecs.lookup(encoding).name if encoding.endswith("_codec"): @@ -1729,11 +1873,11 @@ def test_basics(self): with support.check_warnings(): # unicode-internal has been deprecated (b, size) = codecs.getencoder(encoding)(s) - self.assertEqual(size, len(s), "%r != %r (encoding=%r)" % (size, len(s), encoding)) + self.assertEqual(size, len(s), "encoding=%r" % encoding) (chars, size) = codecs.getdecoder(encoding)(b) - self.assertEqual(chars, s, "%r != %r (encoding=%r)" % (chars, s, encoding)) + self.assertEqual(chars, s, "encoding=%r" % encoding) - if encoding not in broken_unicode_with_streams: + if encoding not in broken_unicode_with_stateful: # check stream reader/writer q = Queue(b"") writer = codecs.getwriter(encoding)(q) @@ -1749,15 +1893,13 @@ def test_basics(self): for c in encodedresult: q.write(bytes([c])) decodedresult += reader.read() - self.assertEqual(decodedresult, s, "%r != %r (encoding=%r)" % (decodedresult, s, encoding)) + self.assertEqual(decodedresult, s, "encoding=%r" % encoding) - if encoding not in broken_incremental_coders: - # check incremental decoder/encoder (fetched via the Python - # and C API) and iterencode()/iterdecode() + if encoding not in broken_unicode_with_stateful: + # check incremental decoder/encoder and iterencode()/iterdecode() try: encoder = codecs.getincrementalencoder(encoding)() - cencoder = _testcapi.codec_incrementalencoder(encoding) - except LookupError: # no IncrementalEncoder + except LookupError: # no IncrementalEncoder pass else: # check incremental decoder/encoder @@ -1770,45 +1912,71 @@ def test_basics(self): for c in encodedresult: decodedresult += decoder.decode(bytes([c])) decodedresult += decoder.decode(b"", True) - self.assertEqual(decodedresult, s, "%r != %r (encoding=%r)" % (decodedresult, s, encoding)) + self.assertEqual(decodedresult, s, + "encoding=%r" % encoding) + + # check iterencode()/iterdecode() + result = "".join(codecs.iterdecode( + codecs.iterencode(s, encoding), encoding)) + self.assertEqual(result, s, "encoding=%r" % encoding) + # check iterencode()/iterdecode() with empty string + result = "".join(codecs.iterdecode( + codecs.iterencode("", encoding), encoding)) + self.assertEqual(result, "") + + if encoding not in ("idna", "mbcs"): + # check incremental decoder/encoder with errors argument + try: + encoder = codecs.getincrementalencoder(encoding)("ignore") + except LookupError: # no IncrementalEncoder + pass + else: + encodedresult = b"".join(encoder.encode(c) for c in s) + decoder = codecs.getincrementaldecoder(encoding)("ignore") + decodedresult = "".join(decoder.decode(bytes([c])) + for c in encodedresult) + self.assertEqual(decodedresult, s, + "encoding=%r" % encoding) + + @support.cpython_only + def test_basics_capi(self): + from _testcapi import codec_incrementalencoder, codec_incrementaldecoder + s = "abc123" # all codecs should be able to encode these + for encoding in all_unicode_encodings: + if encoding not in broken_unicode_with_stateful: + # check incremental decoder/encoder (fetched via the C API) + try: + cencoder = codec_incrementalencoder(encoding) + except LookupError: # no IncrementalEncoder + pass + else: # check C API encodedresult = b"" for c in s: encodedresult += cencoder.encode(c) encodedresult += cencoder.encode("", True) - cdecoder = _testcapi.codec_incrementaldecoder(encoding) + cdecoder = codec_incrementaldecoder(encoding) decodedresult = "" for c in encodedresult: decodedresult += cdecoder.decode(bytes([c])) decodedresult += cdecoder.decode(b"", True) - self.assertEqual(decodedresult, s, "%r != %r (encoding=%r)" % (decodedresult, s, encoding)) - - # check iterencode()/iterdecode() - result = "".join(codecs.iterdecode(codecs.iterencode(s, encoding), encoding)) - self.assertEqual(result, s, "%r != %r (encoding=%r)" % (result, s, encoding)) - - # check iterencode()/iterdecode() with empty string - result = "".join(codecs.iterdecode(codecs.iterencode("", encoding), encoding)) - self.assertEqual(result, "") + self.assertEqual(decodedresult, s, + "encoding=%r" % encoding) if encoding not in ("idna", "mbcs"): # check incremental decoder/encoder with errors argument try: - encoder = codecs.getincrementalencoder(encoding)("ignore") - cencoder = _testcapi.codec_incrementalencoder(encoding, "ignore") - except LookupError: # no IncrementalEncoder + cencoder = codec_incrementalencoder(encoding, "ignore") + except LookupError: # no IncrementalEncoder pass else: - encodedresult = b"".join(encoder.encode(c) for c in s) - decoder = codecs.getincrementaldecoder(encoding)("ignore") - decodedresult = "".join(decoder.decode(bytes([c])) for c in encodedresult) - self.assertEqual(decodedresult, s, "%r != %r (encoding=%r)" % (decodedresult, s, encoding)) - encodedresult = b"".join(cencoder.encode(c) for c in s) - cdecoder = _testcapi.codec_incrementaldecoder(encoding, "ignore") - decodedresult = "".join(cdecoder.decode(bytes([c])) for c in encodedresult) - self.assertEqual(decodedresult, s, "%r != %r (encoding=%r)" % (decodedresult, s, encoding)) + cdecoder = codec_incrementaldecoder(encoding, "ignore") + decodedresult = "".join(cdecoder.decode(bytes([c])) + for c in encodedresult) + self.assertEqual(decodedresult, s, + "encoding=%r" % encoding) def test_seek(self): # all codecs should be able to encode these @@ -1816,7 +1984,7 @@ def test_seek(self): for encoding in all_unicode_encodings: if encoding == "idna": # FIXME: See SF bug #1163178 continue - if encoding in broken_unicode_with_streams: + if encoding in broken_unicode_with_stateful: continue reader = codecs.getreader(encoding)(io.BytesIO(s.encode(encoding))) for t in range(5): @@ -1849,7 +2017,7 @@ def test_decoder_state(self): # Check that getstate() and setstate() handle the state properly u = "abc123" for encoding in all_unicode_encodings: - if encoding not in broken_incremental_coders: + if encoding not in broken_unicode_with_stateful: self.check_state_handling_decode(encoding, u, u.encode(encoding)) self.check_state_handling_encode(encoding, u, u.encode(encoding)) @@ -1883,6 +2051,16 @@ def test_decode_with_string_map(self): ("ab\ufffd", 3) ) + self.assertEqual( + codecs.charmap_decode(b"\x00\x01\x02", "backslashreplace", "ab"), + ("ab\\x02", 3) + ) + + self.assertEqual( + codecs.charmap_decode(b"\x00\x01\x02", "backslashreplace", "ab\ufffe"), + ("ab\\x02", 3) + ) + self.assertEqual( codecs.charmap_decode(b"\x00\x01\x02", "ignore", "ab"), ("ab", 3) @@ -1959,6 +2137,25 @@ def test_decode_with_int2str_map(self): ("ab\ufffd", 3) ) + self.assertEqual( + codecs.charmap_decode(b"\x00\x01\x02", "backslashreplace", + {0: 'a', 1: 'b'}), + ("ab\\x02", 3) + ) + + self.assertEqual( + codecs.charmap_decode(b"\x00\x01\x02", "backslashreplace", + {0: 'a', 1: 'b', 2: None}), + ("ab\\x02", 3) + ) + + # Issue #14850 + self.assertEqual( + codecs.charmap_decode(b"\x00\x01\x02", "backslashreplace", + {0: 'a', 1: 'b', 2: '\ufffe'}), + ("ab\\x02", 3) + ) + self.assertEqual( codecs.charmap_decode(b"\x00\x01\x02", "ignore", {0: 'a', 1: 'b'}), @@ -2035,6 +2232,18 @@ def test_decode_with_int2int_map(self): ("ab\ufffd", 3) ) + self.assertEqual( + codecs.charmap_decode(b"\x00\x01\x02", "backslashreplace", + {0: a, 1: b}), + ("ab\\x02", 3) + ) + + self.assertEqual( + codecs.charmap_decode(b"\x00\x01\x02", "backslashreplace", + {0: a, 1: b, 2: 0xFFFE}), + ("ab\\x02", 3) + ) + self.assertEqual( codecs.charmap_decode(b"\x00\x01\x02", "ignore", {0: a, 1: b}), @@ -2053,6 +2262,7 @@ def test_encodedfile(self): f = io.BytesIO(b"\xc3\xbc") with codecs.EncodedFile(f, "latin-1", "utf-8") as ef: self.assertEqual(ef.read(), b"\xfc") + self.assertTrue(f.closed) def test_streamreaderwriter(self): f = io.BytesIO(b"\xc3\xbc") @@ -2093,9 +2303,13 @@ def test_unicode_escape(self): self.assertRaises(UnicodeDecodeError, codecs.unicode_escape_decode, br"\U00110000") self.assertEqual(codecs.unicode_escape_decode(r"\U00110000", "replace"), ("\ufffd", 10)) + self.assertEqual(codecs.unicode_escape_decode(r"\U00110000", "backslashreplace"), + (r"\x5c\x55\x30\x30\x31\x31\x30\x30\x30\x30", 10)) self.assertRaises(UnicodeDecodeError, codecs.raw_unicode_escape_decode, br"\U00110000") self.assertEqual(codecs.raw_unicode_escape_decode(r"\U00110000", "replace"), ("\ufffd", 10)) + self.assertEqual(codecs.raw_unicode_escape_decode(r"\U00110000", "backslashreplace"), + (r"\x5c\x55\x30\x30\x31\x31\x30\x30\x30\x30", 10)) class UnicodeEscapeTest(unittest.TestCase): @@ -2335,7 +2549,7 @@ def test_seek0(self): try: import zlib except ImportError: - pass + zlib = None else: bytes_transform_encodings.append("zlib_codec") transform_aliases["zlib_codec"] = ["zip", "zlib"] @@ -2370,8 +2584,6 @@ def test_read(self): def test_readline(self): for encoding in bytes_transform_encodings: - if encoding in ['uu_codec', 'zlib_codec']: - continue with self.subTest(encoding=encoding): sin = codecs.encode(b"\x80", encoding) reader = codecs.getreader(encoding)(io.BytesIO(sin)) @@ -2440,6 +2652,7 @@ def test_binary_to_text_blacklists_text_transforms(self): bad_input.decode("rot_13") self.assertIsNone(failure.exception.__cause__) + @unittest.skipUnless(zlib, "Requires zlib support") def test_custom_zlib_error_is_wrapped(self): # Check zlib codec gives a good error for malformed input msg = "^decoding with 'zlib_codec' codec failed" @@ -2468,6 +2681,10 @@ def test_aliases(self): info = codecs.lookup(alias) self.assertEqual(info.name, expected_name) + def test_uu_invalid(self): + # Missing "begin" line + self.assertRaises(ValueError, codecs.decode, b"", "uu-codec") + # The codec system tries to wrap exceptions in order to ensure the error # mentions the operation being performed and the codec involved. We @@ -2483,6 +2700,14 @@ def _get_test_codec(codec_name): return _TEST_CODECS.get(codec_name) codecs.register(_get_test_codec) # Returns None, not usable as a decorator +try: + # Issue #22166: Also need to clear the internal cache in CPython + from _codecs import _forget_codec +except ImportError: + def _forget_codec(codec_name): + pass + + class ExceptionChainingTest(unittest.TestCase): def setUp(self): @@ -2508,6 +2733,12 @@ def setUp(self): def tearDown(self): _TEST_CODECS.pop(self.codec_name, None) + # Issue #22166: Also pop from caches to avoid appearance of ref leaks + encodings._cache.pop(self.codec_name, None) + try: + _forget_codec(self.codec_name) + except KeyError: + pass def set_codec(self, encode, decode): codec_info = codecs.CodecInfo(encode, decode, @@ -2521,6 +2752,7 @@ def assertWrapped(self, operation, exc_type, msg): with self.assertRaisesRegex(exc_type, full_msg) as caught: yield caught self.assertIsInstance(caught.exception.__cause__, exc_type) + self.assertIsNotNone(caught.exception.__cause__.__traceback__) def raise_obj(self, *args, **kwds): # Helper to dynamically change the object raised by a test codec @@ -2654,15 +2886,15 @@ def test_code_page_name(self): self.assertRaisesRegex(UnicodeEncodeError, 'cp932', codecs.code_page_encode, 932, '\xff') self.assertRaisesRegex(UnicodeDecodeError, 'cp932', - codecs.code_page_decode, 932, b'\x81\x00') + codecs.code_page_decode, 932, b'\x81\x00', 'strict', True) self.assertRaisesRegex(UnicodeDecodeError, 'CP_UTF8', - codecs.code_page_decode, self.CP_UTF8, b'\xff') + codecs.code_page_decode, self.CP_UTF8, b'\xff', 'strict', True) def check_decode(self, cp, tests): for raw, errors, expected in tests: if expected is not None: try: - decoded = codecs.code_page_decode(cp, raw, errors) + decoded = codecs.code_page_decode(cp, raw, errors, True) except UnicodeDecodeError as err: self.fail('Unable to decode %a from "cp%s" with ' 'errors=%r: %s' % (raw, cp, errors, err)) @@ -2674,7 +2906,7 @@ def check_decode(self, cp, tests): self.assertLessEqual(decoded[1], len(raw)) else: self.assertRaises(UnicodeDecodeError, - codecs.code_page_decode, cp, raw, errors) + codecs.code_page_decode, cp, raw, errors, True) def check_encode(self, cp, tests): for text, errors, expected in tests: @@ -2702,7 +2934,12 @@ def test_cp932(self): ('[\xff]', 'replace', b'[y]'), ('[\u20ac]', 'replace', b'[?]'), ('[\xff]', 'backslashreplace', b'[\\xff]'), + ('[\xff]', 'namereplace', + b'[\\N{LATIN SMALL LETTER Y WITH DIAERESIS}]'), ('[\xff]', 'xmlcharrefreplace', b'[ÿ]'), + ('\udcff', 'strict', None), + ('[\udcff]', 'surrogateescape', b'[\xff]'), + ('[\udcff]', 'surrogatepass', None), )) self.check_decode(932, ( (b'abc', 'strict', 'abc'), @@ -2711,10 +2948,13 @@ def test_cp932(self): (b'[\xff]', 'strict', None), (b'[\xff]', 'ignore', '[]'), (b'[\xff]', 'replace', '[\ufffd]'), + (b'[\xff]', 'backslashreplace', '[\\xff]'), (b'[\xff]', 'surrogateescape', '[\udcff]'), + (b'[\xff]', 'surrogatepass', None), (b'\x81\x00abc', 'strict', None), (b'\x81\x00abc', 'ignore', '\x00abc'), (b'\x81\x00abc', 'replace', '\ufffd\x00abc'), + (b'\x81\x00abc', 'backslashreplace', '\\x81\x00abc'), )) def test_cp1252(self): @@ -2722,9 +2962,12 @@ def test_cp1252(self): ('abc', 'strict', b'abc'), ('\xe9\u20ac', 'strict', b'\xe9\x80'), ('\xff', 'strict', b'\xff'), + # test error handlers ('\u0141', 'strict', None), ('\u0141', 'ignore', b''), ('\u0141', 'replace', b'L'), + ('\udc98', 'surrogateescape', b'\x98'), + ('\udc98', 'surrogatepass', None), )) self.check_decode(1252, ( (b'abc', 'strict', 'abc'), diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py index 56e812070582..a94b5da860f7 100644 --- a/Lib/test/test_collections.py +++ b/Lib/test/test_collections.py @@ -63,10 +63,17 @@ def test_basics(self): for m1, m2 in zip(d.maps[1:], e.maps[1:]): self.assertIs(m1, m2) - for e in [pickle.loads(pickle.dumps(d)), - copy.deepcopy(d), + # check deep copies + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + e = pickle.loads(pickle.dumps(d, proto)) + self.assertEqual(d, e) + self.assertEqual(d.maps, e.maps) + self.assertIsNot(d, e) + for m1, m2 in zip(d.maps, e.maps): + self.assertIsNot(m1, m2, e) + for e in [copy.deepcopy(d), eval(repr(d)) - ]: # check deep copies + ]: self.assertEqual(d, e) self.assertEqual(d.maps, e.maps) self.assertIsNot(d, e) @@ -301,7 +308,7 @@ def test_pickle(self): for module in (pickle,): loads = getattr(module, 'loads') dumps = getattr(module, 'dumps') - for protocol in -1, 0, 1, 2: + for protocol in range(-1, module.HIGHEST_PROTOCOL + 1): q = loads(dumps(p, protocol)) self.assertEqual(p, q) self.assertEqual(p._fields, q._fields) @@ -511,7 +518,7 @@ def test_Iterator(self): class NextOnly: def __next__(self): yield 1 - raise StopIteration + return self.assertNotIsInstance(NextOnly(), Iterator) def test_Sized(self): @@ -640,6 +647,59 @@ def __hash__(self): a, b = OneTwoThreeSet(), OneTwoThreeSet() self.assertTrue(hash(a) == hash(b)) + def test_isdisjoint_Set(self): + class MySet(Set): + def __init__(self, itr): + self.contents = itr + def __contains__(self, x): + return x in self.contents + def __iter__(self): + return iter(self.contents) + def __len__(self): + return len([x for x in self.contents]) + s1 = MySet((1, 2, 3)) + s2 = MySet((4, 5, 6)) + s3 = MySet((1, 5, 6)) + self.assertTrue(s1.isdisjoint(s2)) + self.assertFalse(s1.isdisjoint(s3)) + + def test_equality_Set(self): + class MySet(Set): + def __init__(self, itr): + self.contents = itr + def __contains__(self, x): + return x in self.contents + def __iter__(self): + return iter(self.contents) + def __len__(self): + return len([x for x in self.contents]) + s1 = MySet((1,)) + s2 = MySet((1, 2)) + s3 = MySet((3, 4)) + s4 = MySet((3, 4)) + self.assertTrue(s2 > s1) + self.assertTrue(s1 < s2) + self.assertFalse(s2 <= s1) + self.assertFalse(s2 <= s3) + self.assertFalse(s1 >= s2) + self.assertEqual(s3, s4) + self.assertNotEqual(s2, s3) + + def test_arithmetic_Set(self): + class MySet(Set): + def __init__(self, itr): + self.contents = itr + def __contains__(self, x): + return x in self.contents + def __iter__(self): + return iter(self.contents) + def __len__(self): + return len([x for x in self.contents]) + s1 = MySet((1, 2, 3)) + s2 = MySet((3, 4, 5)) + s3 = s1 & s2 + self.assertEqual(s3, MySet((3,))) + def test_MutableSet(self): self.assertIsInstance(set(), MutableSet) self.assertTrue(issubclass(set, MutableSet)) @@ -720,14 +780,166 @@ def __lt__(self, x): cs = MyComparableSet() ncs = MyNonComparableSet() + self.assertFalse(ncs < cs) + self.assertTrue(ncs <= cs) + self.assertFalse(ncs > cs) + self.assertTrue(ncs >= cs) + + def assertSameSet(self, s1, s2): + # coerce both to a real set then check equality + self.assertSetEqual(set(s1), set(s2)) + + def test_Set_interoperability_with_real_sets(self): + # Issue: 8743 + class ListSet(Set): + def __init__(self, elements=()): + self.data = [] + for elem in elements: + if elem not in self.data: + self.data.append(elem) + def __contains__(self, elem): + return elem in self.data + def __iter__(self): + return iter(self.data) + def __len__(self): + return len(self.data) + def __repr__(self): + return 'Set({!r})'.format(self.data) + + r1 = set('abc') + r2 = set('bcd') + r3 = set('abcde') + f1 = ListSet('abc') + f2 = ListSet('bcd') + f3 = ListSet('abcde') + l1 = list('abccba') + l2 = list('bcddcb') + l3 = list('abcdeedcba') + + target = r1 & r2 + self.assertSameSet(f1 & f2, target) + self.assertSameSet(f1 & r2, target) + self.assertSameSet(r2 & f1, target) + self.assertSameSet(f1 & l2, target) + + target = r1 | r2 + self.assertSameSet(f1 | f2, target) + self.assertSameSet(f1 | r2, target) + self.assertSameSet(r2 | f1, target) + self.assertSameSet(f1 | l2, target) + + fwd_target = r1 - r2 + rev_target = r2 - r1 + self.assertSameSet(f1 - f2, fwd_target) + self.assertSameSet(f2 - f1, rev_target) + self.assertSameSet(f1 - r2, fwd_target) + self.assertSameSet(f2 - r1, rev_target) + self.assertSameSet(r1 - f2, fwd_target) + self.assertSameSet(r2 - f1, rev_target) + self.assertSameSet(f1 - l2, fwd_target) + self.assertSameSet(f2 - l1, rev_target) + + target = r1 ^ r2 + self.assertSameSet(f1 ^ f2, target) + self.assertSameSet(f1 ^ r2, target) + self.assertSameSet(r2 ^ f1, target) + self.assertSameSet(f1 ^ l2, target) + + # Don't change the following to use assertLess or other + # "more specific" unittest assertions. The current + # assertTrue/assertFalse style makes the pattern of test + # case combinations clear and allows us to know for sure + # the exact operator being invoked. + + # proper subset + self.assertTrue(f1 < f3) + self.assertFalse(f1 < f1) + self.assertFalse(f1 < f2) + self.assertTrue(r1 < f3) + self.assertFalse(r1 < f1) + self.assertFalse(r1 < f2) + self.assertTrue(r1 < r3) + self.assertFalse(r1 < r1) + self.assertFalse(r1 < r2) + with self.assertRaises(TypeError): + f1 < l3 + with self.assertRaises(TypeError): + f1 < l1 + with self.assertRaises(TypeError): + f1 < l2 + + # any subset + self.assertTrue(f1 <= f3) + self.assertTrue(f1 <= f1) + self.assertFalse(f1 <= f2) + self.assertTrue(r1 <= f3) + self.assertTrue(r1 <= f1) + self.assertFalse(r1 <= f2) + self.assertTrue(r1 <= r3) + self.assertTrue(r1 <= r1) + self.assertFalse(r1 <= r2) + with self.assertRaises(TypeError): + f1 <= l3 + with self.assertRaises(TypeError): + f1 <= l1 + with self.assertRaises(TypeError): + f1 <= l2 + + # proper superset + self.assertTrue(f3 > f1) + self.assertFalse(f1 > f1) + self.assertFalse(f2 > f1) + self.assertTrue(r3 > r1) + self.assertFalse(f1 > r1) + self.assertFalse(f2 > r1) + self.assertTrue(r3 > r1) + self.assertFalse(r1 > r1) + self.assertFalse(r2 > r1) with self.assertRaises(TypeError): - ncs < cs + f1 > l3 with self.assertRaises(TypeError): - ncs <= cs + f1 > l1 with self.assertRaises(TypeError): - cs > ncs + f1 > l2 + + # any superset + self.assertTrue(f3 >= f1) + self.assertTrue(f1 >= f1) + self.assertFalse(f2 >= f1) + self.assertTrue(r3 >= r1) + self.assertTrue(f1 >= r1) + self.assertFalse(f2 >= r1) + self.assertTrue(r3 >= r1) + self.assertTrue(r1 >= r1) + self.assertFalse(r2 >= r1) with self.assertRaises(TypeError): - cs >= ncs + f1 >= l3 + with self.assertRaises(TypeError): + f1 >=l1 + with self.assertRaises(TypeError): + f1 >= l2 + + # equality + self.assertTrue(f1 == f1) + self.assertTrue(r1 == f1) + self.assertTrue(f1 == r1) + self.assertFalse(f1 == f3) + self.assertFalse(r1 == f3) + self.assertFalse(f1 == r3) + self.assertFalse(f1 == l3) + self.assertFalse(f1 == l1) + self.assertFalse(f1 == l2) + + # inequality + self.assertFalse(f1 != f1) + self.assertFalse(r1 != f1) + self.assertFalse(f1 != r1) + self.assertTrue(f1 != f3) + self.assertTrue(r1 != f3) + self.assertTrue(f1 != r3) + self.assertTrue(f1 != l3) + self.assertTrue(f1 != l1) + self.assertTrue(f1 != l2) def test_Mapping(self): for sample in [dict]: @@ -932,32 +1144,47 @@ def test_basics(self): self.assertEqual(c.setdefault('e', 5), 5) self.assertEqual(c['e'], 5) + def test_init(self): + self.assertEqual(list(Counter(self=42).items()), [('self', 42)]) + self.assertEqual(list(Counter(iterable=42).items()), [('iterable', 42)]) + self.assertEqual(list(Counter(iterable=None).items()), [('iterable', None)]) + self.assertRaises(TypeError, Counter, 42) + self.assertRaises(TypeError, Counter, (), ()) + self.assertRaises(TypeError, Counter.__init__) + + def test_update(self): + c = Counter() + c.update(self=42) + self.assertEqual(list(c.items()), [('self', 42)]) + c = Counter() + c.update(iterable=42) + self.assertEqual(list(c.items()), [('iterable', 42)]) + c = Counter() + c.update(iterable=None) + self.assertEqual(list(c.items()), [('iterable', None)]) + self.assertRaises(TypeError, Counter().update, 42) + self.assertRaises(TypeError, Counter().update, {}, {}) + self.assertRaises(TypeError, Counter.update) + def test_copying(self): # Check that counters are copyable, deepcopyable, picklable, and #have a repr/eval round-trip words = Counter('which witch had which witches wrist watch'.split()) + def check(dup): + msg = "\ncopy: %s\nwords: %s" % (dup, words) + self.assertIsNot(dup, words, msg) + self.assertEqual(dup, words) + check(words.copy()) + check(copy.copy(words)) + check(copy.deepcopy(words)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(proto=proto): + check(pickle.loads(pickle.dumps(words, proto))) + check(eval(repr(words))) update_test = Counter() update_test.update(words) - for label, dup in [ - ('words.copy()', words.copy()), - ('copy.copy(words)', copy.copy(words)), - ('copy.deepcopy(words)', copy.deepcopy(words)), - ('pickle.loads(pickle.dumps(words, 0))', - pickle.loads(pickle.dumps(words, 0))), - ('pickle.loads(pickle.dumps(words, 1))', - pickle.loads(pickle.dumps(words, 1))), - ('pickle.loads(pickle.dumps(words, 2))', - pickle.loads(pickle.dumps(words, 2))), - ('pickle.loads(pickle.dumps(words, -1))', - pickle.loads(pickle.dumps(words, -1))), - ('eval(repr(words))', eval(repr(words))), - ('update_test', update_test), - ('Counter(words)', Counter(words)), - ]: - with self.subTest(label=label): - msg = "\ncopy: %s\nwords: %s" % (dup, words) - self.assertIsNot(dup, words, msg) - self.assertEqual(dup, words) + check(update_test) + check(Counter(words)) def test_copy_subclass(self): class MyCounter(Counter): @@ -1053,6 +1280,16 @@ def test_subtract(self): c.subtract('aaaabbcce') self.assertEqual(c, Counter(a=-1, b=0, c=-1, d=1, e=-1)) + c = Counter() + c.subtract(self=42) + self.assertEqual(list(c.items()), [('self', -42)]) + c = Counter() + c.subtract(iterable=42) + self.assertEqual(list(c.items()), [('iterable', -42)]) + self.assertRaises(TypeError, Counter().subtract, 42) + self.assertRaises(TypeError, Counter().subtract, {}, {}) + self.assertRaises(TypeError, Counter.subtract) + def test_unary(self): c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40) self.assertEqual(dict(+c), dict(c=5, d=10, e=15, g=40)) @@ -1103,8 +1340,11 @@ def test_init(self): c=3, e=5).items()), pairs) # mixed input # make sure no positional args conflict with possible kwdargs - self.assertEqual(inspect.getargspec(OrderedDict.__dict__['__init__']).args, - ['self']) + self.assertEqual(list(OrderedDict(self=42).items()), [('self', 42)]) + self.assertEqual(list(OrderedDict(other=42).items()), [('other', 42)]) + self.assertRaises(TypeError, OrderedDict, 42) + self.assertRaises(TypeError, OrderedDict, (), ()) + self.assertRaises(TypeError, OrderedDict.__init__) # Make sure that direct calls to __init__ do not clear previous contents d = OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 44), ('e', 55)]) @@ -1149,6 +1389,10 @@ def test_update(self): self.assertEqual(list(d.items()), [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7)]) + self.assertRaises(TypeError, OrderedDict().update, 42) + self.assertRaises(TypeError, OrderedDict().update, (), ()) + self.assertRaises(TypeError, OrderedDict.update) + def test_abc(self): self.assertIsInstance(OrderedDict(), MutableMapping) self.assertTrue(issubclass(OrderedDict, MutableMapping)) @@ -1187,6 +1431,21 @@ def test_iterators(self): self.assertEqual(list(od.items()), pairs) self.assertEqual(list(reversed(od)), [t[0] for t in reversed(pairs)]) + self.assertEqual(list(reversed(od.keys())), + [t[0] for t in reversed(pairs)]) + self.assertEqual(list(reversed(od.values())), + [t[1] for t in reversed(pairs)]) + self.assertEqual(list(reversed(od.items())), list(reversed(pairs))) + + def test_detect_deletion_during_iteration(self): + od = OrderedDict.fromkeys('abc') + it = iter(od) + key = next(it) + del od[key] + with self.assertRaises(Exception): + # Note, the exact exception raised is not guaranteed + # The only guarantee that the next() will not succeed + next(it) def test_popitem(self): pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] @@ -1242,30 +1501,21 @@ def test_copying(self): # and have a repr/eval round-trip pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] od = OrderedDict(pairs) + def check(dup): + msg = "\ncopy: %s\nod: %s" % (dup, od) + self.assertIsNot(dup, od, msg) + self.assertEqual(dup, od) + check(od.copy()) + check(copy.copy(od)) + check(copy.deepcopy(od)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(proto=proto): + check(pickle.loads(pickle.dumps(od, proto))) + check(eval(repr(od))) update_test = OrderedDict() update_test.update(od) - for label, dup in [ - ('od.copy()', od.copy()), - ('copy.copy(od)', copy.copy(od)), - ('copy.deepcopy(od)', copy.deepcopy(od)), - ('pickle.loads(pickle.dumps(od, 0))', - pickle.loads(pickle.dumps(od, 0))), - ('pickle.loads(pickle.dumps(od, 1))', - pickle.loads(pickle.dumps(od, 1))), - ('pickle.loads(pickle.dumps(od, 2))', - pickle.loads(pickle.dumps(od, 2))), - ('pickle.loads(pickle.dumps(od, 3))', - pickle.loads(pickle.dumps(od, 3))), - ('pickle.loads(pickle.dumps(od, -1))', - pickle.loads(pickle.dumps(od, -1))), - ('eval(repr(od))', eval(repr(od))), - ('update_test', update_test), - ('OrderedDict(od)', OrderedDict(od)), - ]: - with self.subTest(label=label): - msg = "\ncopy: %s\nod: %s" % (dup, od) - self.assertIsNot(dup, od, msg) - self.assertEqual(dup, od) + check(update_test) + check(OrderedDict(od)) def test_yaml_linkage(self): # Verify that __reduce__ is setup in a way that supports PyYAML's dump() feature. diff --git a/Lib/test/test_compare.py b/Lib/test/test_compare.py index ee3794ae9a3d..a663832b3da7 100644 --- a/Lib/test/test_compare.py +++ b/Lib/test/test_compare.py @@ -48,8 +48,69 @@ def test_id_comparisons(self): def test_ne_defaults_to_not_eq(self): a = Cmp(1) b = Cmp(1) - self.assertTrue(a == b) - self.assertFalse(a != b) + c = Cmp(2) + self.assertIs(a == b, True) + self.assertIs(a != b, False) + self.assertIs(a != c, True) + + def test_ne_high_priority(self): + """object.__ne__() should allow reflected __ne__() to be tried""" + calls = [] + class Left: + # Inherits object.__ne__() + def __eq__(*args): + calls.append('Left.__eq__') + return NotImplemented + class Right: + def __eq__(*args): + calls.append('Right.__eq__') + return NotImplemented + def __ne__(*args): + calls.append('Right.__ne__') + return NotImplemented + Left() != Right() + self.assertSequenceEqual(calls, ['Left.__eq__', 'Right.__ne__']) + + def test_ne_low_priority(self): + """object.__ne__() should not invoke reflected __eq__()""" + calls = [] + class Base: + # Inherits object.__ne__() + def __eq__(*args): + calls.append('Base.__eq__') + return NotImplemented + class Derived(Base): # Subclassing forces higher priority + def __eq__(*args): + calls.append('Derived.__eq__') + return NotImplemented + def __ne__(*args): + calls.append('Derived.__ne__') + return NotImplemented + Base() != Derived() + self.assertSequenceEqual(calls, ['Derived.__ne__', 'Base.__eq__']) + + def test_other_delegation(self): + """No default delegation between operations except __ne__()""" + ops = ( + ('__eq__', lambda a, b: a == b), + ('__lt__', lambda a, b: a < b), + ('__le__', lambda a, b: a <= b), + ('__gt__', lambda a, b: a > b), + ('__ge__', lambda a, b: a >= b), + ) + for name, func in ops: + with self.subTest(name): + def unexpected(*args): + self.fail('Unexpected operator method called') + class C: + __ne__ = unexpected + for other, _ in ops: + if other != name: + setattr(C, other, unexpected) + if name == '__eq__': + self.assertIs(func(C(), object()), False) + else: + self.assertRaises(TypeError, func, C(), object()) def test_issue_1393(self): x = lambda: None diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index ccd08db66703..611667690fe3 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -1,3 +1,4 @@ +import math import unittest import sys import _ast @@ -303,9 +304,26 @@ def test_lambda_doc(self): l = lambda: "foo" self.assertIsNone(l.__doc__) -## def test_unicode_encoding(self): -## code = "# -*- coding: utf-8 -*-\npass\n" -## self.assertRaises(SyntaxError, compile, code, "tmp", "exec") + def test_encoding(self): + code = b'# -*- coding: badencoding -*-\npass\n' + self.assertRaises(SyntaxError, compile, code, 'tmp', 'exec') + code = '# -*- coding: badencoding -*-\n"\xc2\xa4"\n' + compile(code, 'tmp', 'exec') + self.assertEqual(eval(code), '\xc2\xa4') + code = '"\xc2\xa4"\n' + self.assertEqual(eval(code), '\xc2\xa4') + code = b'"\xc2\xa4"\n' + self.assertEqual(eval(code), '\xa4') + code = b'# -*- coding: latin1 -*-\n"\xc2\xa4"\n' + self.assertEqual(eval(code), '\xc2\xa4') + code = b'# -*- coding: utf-8 -*-\n"\xc2\xa4"\n' + self.assertEqual(eval(code), '\xa4') + code = b'# -*- coding: iso8859-15 -*-\n"\xc2\xa4"\n' + self.assertEqual(eval(code), '\xc2\u20ac') + code = '"""\\\n# -*- coding: iso8859-15 -*-\n\xc2\xa4"""\n' + self.assertEqual(eval(code), '# -*- coding: iso8859-15 -*-\n\xc2\xa4') + code = b'"""\\\n# -*- coding: iso8859-15 -*-\n\xc2\xa4"""\n' + self.assertEqual(eval(code), '# -*- coding: iso8859-15 -*-\n\xa4') def test_subscripts(self): # SF bug 1448804 @@ -501,8 +519,43 @@ def check_limit(prefix, repeated): check_limit("a", "*a") -def test_main(): - support.run_unittest(TestSpecifics) +class TestStackSize(unittest.TestCase): + # These tests check that the computed stack size for a code object + # stays within reasonable bounds (see issue #21523 for an example + # dysfunction). + N = 100 + + def check_stack_size(self, code): + # To assert that the alleged stack size is not O(N), we + # check that it is smaller than log(N). + if isinstance(code, str): + code = compile(code, "", "single") + max_size = math.ceil(math.log(len(code.co_code))) + self.assertLessEqual(code.co_stacksize, max_size) + + def test_and(self): + self.check_stack_size("x and " * self.N + "x") + + def test_or(self): + self.check_stack_size("x or " * self.N + "x") + + def test_and_or(self): + self.check_stack_size("x and x or " * self.N + "x") + + def test_chained_comparison(self): + self.check_stack_size("x < " * self.N + "x") + + def test_if_else(self): + self.check_stack_size("x if x else " * self.N + "x") + + def test_binop(self): + self.check_stack_size("x + " * self.N + "x") + + def test_func_and(self): + code = "def f(x):\n" + code += " x and x\n" * self.N + self.check_stack_size(code) + if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_compileall.py b/Lib/test/test_compileall.py index ff2515df4cf1..7506c7018bfc 100644 --- a/Lib/test/test_compileall.py +++ b/Lib/test/test_compileall.py @@ -5,13 +5,18 @@ import py_compile import shutil import struct -import subprocess -import sys import tempfile import time import unittest import io +from unittest import mock, skipUnless +try: + from concurrent.futures import ProcessPoolExecutor + _have_multiprocessing = True +except ImportError: + _have_multiprocessing = False + from test import support, script_helper class CompileallTests(unittest.TestCase): @@ -108,6 +113,33 @@ def test_optimize(self): debug_override=not optimize) self.assertTrue(os.path.isfile(cached3)) + @mock.patch('compileall.ProcessPoolExecutor') + def test_compile_pool_called(self, pool_mock): + compileall.compile_dir(self.directory, quiet=True, workers=5) + self.assertTrue(pool_mock.called) + + def test_compile_workers_non_positive(self): + with self.assertRaisesRegex(ValueError, + "workers must be greater or equal to 0"): + compileall.compile_dir(self.directory, workers=-1) + + @mock.patch('compileall.ProcessPoolExecutor') + def test_compile_workers_cpu_count(self, pool_mock): + compileall.compile_dir(self.directory, quiet=True, workers=0) + self.assertEqual(pool_mock.call_args[1]['max_workers'], None) + + @mock.patch('compileall.ProcessPoolExecutor') + @mock.patch('compileall.compile_file') + def test_compile_one_worker(self, compile_file_mock, pool_mock): + compileall.compile_dir(self.directory, quiet=True) + self.assertFalse(pool_mock.called) + self.assertTrue(compile_file_mock.called) + + @mock.patch('compileall.ProcessPoolExecutor', new=None) + def test_compile_missing_multiprocessing(self): + with self.assertRaisesRegex(NotImplementedError, + "multiprocessing support not available"): + compileall.compile_dir(self.directory, quiet=True, workers=5) class EncodingTest(unittest.TestCase): """Issue 6716: compileall should escape source code when printing errors @@ -181,6 +213,29 @@ def test_no_args_compiles_path(self): self.assertNotCompiled(self.initfn) self.assertNotCompiled(self.barfn) + def test_no_args_respects_force_flag(self): + bazfn = script_helper.make_script(self.directory, 'baz', '') + self.assertRunOK(PYTHONPATH=self.directory) + pycpath = importlib.util.cache_from_source(bazfn) + # Set atime/mtime backward to avoid file timestamp resolution issues + os.utime(pycpath, (time.time()-60,)*2) + mtime = os.stat(pycpath).st_mtime + # Without force, no recompilation + self.assertRunOK(PYTHONPATH=self.directory) + mtime2 = os.stat(pycpath).st_mtime + self.assertEqual(mtime, mtime2) + # Now force it. + self.assertRunOK('-f', PYTHONPATH=self.directory) + mtime2 = os.stat(pycpath).st_mtime + self.assertNotEqual(mtime, mtime2) + + def test_no_args_respects_quiet_flag(self): + script_helper.make_script(self.directory, 'baz', '') + noisy = self.assertRunOK(PYTHONPATH=self.directory) + self.assertIn(b'Listing ', noisy) + quiet = self.assertRunOK('-q', PYTHONPATH=self.directory) + self.assertNotIn(b'Listing ', quiet) + # Ensure that the default behavior of compileall's CLI is to create # PEP 3147 pyc/pyo files. for name, ext, switch in [ @@ -252,12 +307,53 @@ def test_recursion_control(self): self.assertCompiled(subinitfn) self.assertCompiled(hamfn) + def test_recursion_limit(self): + subpackage = os.path.join(self.pkgdir, 'spam') + subpackage2 = os.path.join(subpackage, 'ham') + subpackage3 = os.path.join(subpackage2, 'eggs') + for pkg in (subpackage, subpackage2, subpackage3): + script_helper.make_pkg(pkg) + + subinitfn = os.path.join(subpackage, '__init__.py') + hamfn = script_helper.make_script(subpackage, 'ham', '') + spamfn = script_helper.make_script(subpackage2, 'spam', '') + eggfn = script_helper.make_script(subpackage3, 'egg', '') + + self.assertRunOK('-q', '-r 0', self.pkgdir) + self.assertNotCompiled(subinitfn) + self.assertFalse( + os.path.exists(os.path.join(subpackage, '__pycache__'))) + + self.assertRunOK('-q', '-r 1', self.pkgdir) + self.assertCompiled(subinitfn) + self.assertCompiled(hamfn) + self.assertNotCompiled(spamfn) + + self.assertRunOK('-q', '-r 2', self.pkgdir) + self.assertCompiled(subinitfn) + self.assertCompiled(hamfn) + self.assertCompiled(spamfn) + self.assertNotCompiled(eggfn) + + self.assertRunOK('-q', '-r 5', self.pkgdir) + self.assertCompiled(subinitfn) + self.assertCompiled(hamfn) + self.assertCompiled(spamfn) + self.assertCompiled(eggfn) + def test_quiet(self): noisy = self.assertRunOK(self.pkgdir) quiet = self.assertRunOK('-q', self.pkgdir) self.assertNotEqual(b'', noisy) self.assertEqual(b'', quiet) + def test_silent(self): + script_helper.make_script(self.pkgdir, 'crunchyfrog', 'bad(syntax') + _, quiet, _ = self.assertRunNotOK('-q', self.pkgdir) + _, silent, _ = self.assertRunNotOK('-qq', self.pkgdir) + self.assertNotEqual(b'', quiet) + self.assertEqual(b'', silent) + def test_regexp(self): self.assertRunOK('-q', '-x', r'ba[^\\/]*$', self.pkgdir) self.assertNotCompiled(self.barfn) @@ -358,6 +454,29 @@ def test_invalid_arg_produces_message(self): out = self.assertRunOK('badfilename') self.assertRegex(out, b"Can't list 'badfilename'") + @skipUnless(_have_multiprocessing, "requires multiprocessing") + def test_workers(self): + bar2fn = script_helper.make_script(self.directory, 'bar2', '') + files = [] + for suffix in range(5): + pkgdir = os.path.join(self.directory, 'foo{}'.format(suffix)) + os.mkdir(pkgdir) + fn = script_helper.make_script(pkgdir, '__init__', '') + files.append(script_helper.make_script(pkgdir, 'bar2', '')) + + self.assertRunOK(self.directory, '-j', '0') + self.assertCompiled(bar2fn) + for file in files: + self.assertCompiled(file) + + @mock.patch('compileall.compile_dir') + def test_workers_available_cores(self, compile_dir): + with mock.patch("sys.argv", + new=[sys.executable, self.directory, "-j0"]): + compileall.main() + self.assertTrue(compile_dir.called) + self.assertEqual(compile_dir.call_args[-1]['workers'], None) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_complex.py b/Lib/test/test_complex.py index cd55375bdb98..0ef9a7a1098e 100644 --- a/Lib/test/test_complex.py +++ b/Lib/test/test_complex.py @@ -27,7 +27,7 @@ def assertAlmostEqual(self, a, b): unittest.TestCase.assertAlmostEqual(self, a, b) def assertCloseAbs(self, x, y, eps=1e-9): - """Return true iff floats x and y "are close\"""" + """Return true iff floats x and y "are close".""" # put the one with larger magnitude second if abs(x) > abs(y): x, y = y, x @@ -62,7 +62,7 @@ def assertFloatsAreIdentical(self, x, y): self.fail(msg.format(x, y)) def assertClose(self, x, y, eps=1e-9): - """Return true iff complexes x and y "are close\"""" + """Return true iff complexes x and y "are close".""" self.assertCloseAbs(x.real, y.real, eps) self.assertCloseAbs(x.imag, y.imag, eps) @@ -104,6 +104,11 @@ def test_truediv(self): self.assertAlmostEqual(complex.__truediv__(2+0j, 1+1j), 1-1j) self.assertRaises(ZeroDivisionError, complex.__truediv__, 1+1j, 0+0j) + for denom_real, denom_imag in [(0, NAN), (NAN, 0), (NAN, NAN)]: + z = complex(0, 0) / complex(denom_real, denom_imag) + self.assertTrue(isnan(z.real)) + self.assertTrue(isnan(z.imag)) + def test_floordiv(self): self.assertRaises(TypeError, complex.__floordiv__, 3+0j, 1.5+0j) self.assertRaises(TypeError, complex.__floordiv__, 3+0j, 0+0j) diff --git a/Lib/test/test_concurrent_futures.py b/Lib/test/test_concurrent_futures.py index a7e945cb5e9d..86802c2d56d9 100644 --- a/Lib/test/test_concurrent_futures.py +++ b/Lib/test/test_concurrent_futures.py @@ -11,6 +11,7 @@ from test.script_helper import assert_python_ok +import os import sys import threading import time @@ -350,6 +351,13 @@ def test_zero_timeout(self): SUCCESSFUL_FUTURE]), completed_futures) + def test_duplicate_futures(self): + # Issue 20367. Duplicate futures should not raise exceptions or give + # duplicate responses. + future1 = self.executor.submit(time.sleep, 2) + completed = [f for f in futures.as_completed([future1,future1])] + self.assertEqual(len(completed), 1) + class ThreadPoolAsCompletedTests(ThreadPoolMixin, AsCompletedTests, unittest.TestCase): pass @@ -418,6 +426,13 @@ def test_no_stale_references(self): self.assertTrue(collected, "Stale reference not collected within timeout.") + def test_max_workers_negative(self): + for number in (0, -1): + with self.assertRaisesRegex(ValueError, + "max_workers must be greater " + "than 0"): + self.executor_type(max_workers=number) + class ThreadPoolExecutorTest(ThreadPoolMixin, ExecutorTest, unittest.TestCase): def test_map_submits_without_iteration(self): @@ -430,6 +445,11 @@ def record_finished(n): self.executor.shutdown(wait=True) self.assertCountEqual(finished, range(10)) + def test_default_workers(self): + executor = self.executor_type() + self.assertEqual(executor._max_workers, + (os.cpu_count() or 1) * 5) + class ProcessPoolExecutorTest(ProcessPoolMixin, ExecutorTest, unittest.TestCase): def test_killed_child(self): @@ -444,6 +464,48 @@ def test_killed_child(self): # Submitting other jobs fails as well. self.assertRaises(BrokenProcessPool, self.executor.submit, pow, 2, 8) + def test_map_chunksize(self): + def bad_map(): + list(self.executor.map(pow, range(40), range(40), chunksize=-1)) + + ref = list(map(pow, range(40), range(40))) + self.assertEqual( + list(self.executor.map(pow, range(40), range(40), chunksize=6)), + ref) + self.assertEqual( + list(self.executor.map(pow, range(40), range(40), chunksize=50)), + ref) + self.assertEqual( + list(self.executor.map(pow, range(40), range(40), chunksize=40)), + ref) + self.assertRaises(ValueError, bad_map) + + @classmethod + def _test_traceback(cls): + raise RuntimeError(123) # some comment + + def test_traceback(self): + # We want ensure that the traceback from the child process is + # contained in the traceback raised in the main process. + future = self.executor.submit(self._test_traceback) + with self.assertRaises(Exception) as cm: + future.result() + + exc = cm.exception + self.assertIs(type(exc), RuntimeError) + self.assertEqual(exc.args, (123,)) + cause = exc.__cause__ + self.assertIs(type(cause), futures.process._RemoteTraceback) + self.assertIn('raise RuntimeError(123) # some comment', cause.tb) + + with test.support.captured_stderr() as f1: + try: + raise exc + except RuntimeError: + sys.excepthook(*sys.exc_info()) + self.assertIn('raise RuntimeError(123) # some comment', + f1.getvalue()) + class FutureTests(unittest.TestCase): def test_done_callback_with_result(self): diff --git a/Lib/test/test_configparser.py b/Lib/test/test_configparser.py index 29e7ed99ae92..470d2cd1f32e 100644 --- a/Lib/test/test_configparser.py +++ b/Lib/test/test_configparser.py @@ -579,7 +579,7 @@ def get_error(self, cf, exc, section, option): return e else: self.fail("expected exception type %s.%s" - % (exc.__module__, exc.__name__)) + % (exc.__module__, exc.__qualname__)) def test_boolean(self): cf = self.fromstring( @@ -707,8 +707,7 @@ class mystr(str): def test_read_returns_file_list(self): if self.delimiters[0] != '=': - # skip reading the file if we're using an incompatible format - return + self.skipTest('incompatible format') file1 = support.findfile("cfgparser.1") # check when we pass a mix of readable and non-readable files: cf = self.newconfig() @@ -1585,6 +1584,34 @@ def test_sectionproxy_repr(self): """) self.assertEqual(repr(parser['section']), '') + def test_inconsistent_converters_state(self): + parser = configparser.ConfigParser() + import decimal + parser.converters['decimal'] = decimal.Decimal + parser.read_string(""" + [s1] + one = 1 + [s2] + two = 2 + """) + self.assertIn('decimal', parser.converters) + self.assertEqual(parser.getdecimal('s1', 'one'), 1) + self.assertEqual(parser.getdecimal('s2', 'two'), 2) + self.assertEqual(parser['s1'].getdecimal('one'), 1) + self.assertEqual(parser['s2'].getdecimal('two'), 2) + del parser.getdecimal + with self.assertRaises(AttributeError): + parser.getdecimal('s1', 'one') + self.assertIn('decimal', parser.converters) + del parser.converters['decimal'] + self.assertNotIn('decimal', parser.converters) + with self.assertRaises(AttributeError): + parser.getdecimal('s1', 'one') + with self.assertRaises(AttributeError): + parser['s1'].getdecimal('one') + with self.assertRaises(AttributeError): + parser['s2'].getdecimal('two') + class ExceptionPicklingTestCase(unittest.TestCase): """Tests for issue #13760: ConfigParser exceptions are not picklable.""" @@ -1592,104 +1619,113 @@ class ExceptionPicklingTestCase(unittest.TestCase): def test_error(self): import pickle e1 = configparser.Error('value') - pickled = pickle.dumps(e1) - e2 = pickle.loads(pickled) - self.assertEqual(e1.message, e2.message) - self.assertEqual(repr(e1), repr(e2)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + pickled = pickle.dumps(e1, proto) + e2 = pickle.loads(pickled) + self.assertEqual(e1.message, e2.message) + self.assertEqual(repr(e1), repr(e2)) def test_nosectionerror(self): import pickle e1 = configparser.NoSectionError('section') - pickled = pickle.dumps(e1) - e2 = pickle.loads(pickled) - self.assertEqual(e1.message, e2.message) - self.assertEqual(e1.args, e2.args) - self.assertEqual(e1.section, e2.section) - self.assertEqual(repr(e1), repr(e2)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + pickled = pickle.dumps(e1, proto) + e2 = pickle.loads(pickled) + self.assertEqual(e1.message, e2.message) + self.assertEqual(e1.args, e2.args) + self.assertEqual(e1.section, e2.section) + self.assertEqual(repr(e1), repr(e2)) def test_nooptionerror(self): import pickle e1 = configparser.NoOptionError('option', 'section') - pickled = pickle.dumps(e1) - e2 = pickle.loads(pickled) - self.assertEqual(e1.message, e2.message) - self.assertEqual(e1.args, e2.args) - self.assertEqual(e1.section, e2.section) - self.assertEqual(e1.option, e2.option) - self.assertEqual(repr(e1), repr(e2)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + pickled = pickle.dumps(e1, proto) + e2 = pickle.loads(pickled) + self.assertEqual(e1.message, e2.message) + self.assertEqual(e1.args, e2.args) + self.assertEqual(e1.section, e2.section) + self.assertEqual(e1.option, e2.option) + self.assertEqual(repr(e1), repr(e2)) def test_duplicatesectionerror(self): import pickle e1 = configparser.DuplicateSectionError('section', 'source', 123) - pickled = pickle.dumps(e1) - e2 = pickle.loads(pickled) - self.assertEqual(e1.message, e2.message) - self.assertEqual(e1.args, e2.args) - self.assertEqual(e1.section, e2.section) - self.assertEqual(e1.source, e2.source) - self.assertEqual(e1.lineno, e2.lineno) - self.assertEqual(repr(e1), repr(e2)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + pickled = pickle.dumps(e1, proto) + e2 = pickle.loads(pickled) + self.assertEqual(e1.message, e2.message) + self.assertEqual(e1.args, e2.args) + self.assertEqual(e1.section, e2.section) + self.assertEqual(e1.source, e2.source) + self.assertEqual(e1.lineno, e2.lineno) + self.assertEqual(repr(e1), repr(e2)) def test_duplicateoptionerror(self): import pickle e1 = configparser.DuplicateOptionError('section', 'option', 'source', 123) - pickled = pickle.dumps(e1) - e2 = pickle.loads(pickled) - self.assertEqual(e1.message, e2.message) - self.assertEqual(e1.args, e2.args) - self.assertEqual(e1.section, e2.section) - self.assertEqual(e1.option, e2.option) - self.assertEqual(e1.source, e2.source) - self.assertEqual(e1.lineno, e2.lineno) - self.assertEqual(repr(e1), repr(e2)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + pickled = pickle.dumps(e1, proto) + e2 = pickle.loads(pickled) + self.assertEqual(e1.message, e2.message) + self.assertEqual(e1.args, e2.args) + self.assertEqual(e1.section, e2.section) + self.assertEqual(e1.option, e2.option) + self.assertEqual(e1.source, e2.source) + self.assertEqual(e1.lineno, e2.lineno) + self.assertEqual(repr(e1), repr(e2)) def test_interpolationerror(self): import pickle e1 = configparser.InterpolationError('option', 'section', 'msg') - pickled = pickle.dumps(e1) - e2 = pickle.loads(pickled) - self.assertEqual(e1.message, e2.message) - self.assertEqual(e1.args, e2.args) - self.assertEqual(e1.section, e2.section) - self.assertEqual(e1.option, e2.option) - self.assertEqual(repr(e1), repr(e2)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + pickled = pickle.dumps(e1, proto) + e2 = pickle.loads(pickled) + self.assertEqual(e1.message, e2.message) + self.assertEqual(e1.args, e2.args) + self.assertEqual(e1.section, e2.section) + self.assertEqual(e1.option, e2.option) + self.assertEqual(repr(e1), repr(e2)) def test_interpolationmissingoptionerror(self): import pickle e1 = configparser.InterpolationMissingOptionError('option', 'section', 'rawval', 'reference') - pickled = pickle.dumps(e1) - e2 = pickle.loads(pickled) - self.assertEqual(e1.message, e2.message) - self.assertEqual(e1.args, e2.args) - self.assertEqual(e1.section, e2.section) - self.assertEqual(e1.option, e2.option) - self.assertEqual(e1.reference, e2.reference) - self.assertEqual(repr(e1), repr(e2)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + pickled = pickle.dumps(e1, proto) + e2 = pickle.loads(pickled) + self.assertEqual(e1.message, e2.message) + self.assertEqual(e1.args, e2.args) + self.assertEqual(e1.section, e2.section) + self.assertEqual(e1.option, e2.option) + self.assertEqual(e1.reference, e2.reference) + self.assertEqual(repr(e1), repr(e2)) def test_interpolationsyntaxerror(self): import pickle e1 = configparser.InterpolationSyntaxError('option', 'section', 'msg') - pickled = pickle.dumps(e1) - e2 = pickle.loads(pickled) - self.assertEqual(e1.message, e2.message) - self.assertEqual(e1.args, e2.args) - self.assertEqual(e1.section, e2.section) - self.assertEqual(e1.option, e2.option) - self.assertEqual(repr(e1), repr(e2)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + pickled = pickle.dumps(e1, proto) + e2 = pickle.loads(pickled) + self.assertEqual(e1.message, e2.message) + self.assertEqual(e1.args, e2.args) + self.assertEqual(e1.section, e2.section) + self.assertEqual(e1.option, e2.option) + self.assertEqual(repr(e1), repr(e2)) def test_interpolationdeptherror(self): import pickle e1 = configparser.InterpolationDepthError('option', 'section', 'rawval') - pickled = pickle.dumps(e1) - e2 = pickle.loads(pickled) - self.assertEqual(e1.message, e2.message) - self.assertEqual(e1.args, e2.args) - self.assertEqual(e1.section, e2.section) - self.assertEqual(e1.option, e2.option) - self.assertEqual(repr(e1), repr(e2)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + pickled = pickle.dumps(e1, proto) + e2 = pickle.loads(pickled) + self.assertEqual(e1.message, e2.message) + self.assertEqual(e1.args, e2.args) + self.assertEqual(e1.section, e2.section) + self.assertEqual(e1.option, e2.option) + self.assertEqual(repr(e1), repr(e2)) def test_parsingerror(self): import pickle @@ -1697,36 +1733,39 @@ def test_parsingerror(self): e1.append(1, 'line1') e1.append(2, 'line2') e1.append(3, 'line3') - pickled = pickle.dumps(e1) - e2 = pickle.loads(pickled) - self.assertEqual(e1.message, e2.message) - self.assertEqual(e1.args, e2.args) - self.assertEqual(e1.source, e2.source) - self.assertEqual(e1.errors, e2.errors) - self.assertEqual(repr(e1), repr(e2)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + pickled = pickle.dumps(e1, proto) + e2 = pickle.loads(pickled) + self.assertEqual(e1.message, e2.message) + self.assertEqual(e1.args, e2.args) + self.assertEqual(e1.source, e2.source) + self.assertEqual(e1.errors, e2.errors) + self.assertEqual(repr(e1), repr(e2)) e1 = configparser.ParsingError(filename='filename') e1.append(1, 'line1') e1.append(2, 'line2') e1.append(3, 'line3') - pickled = pickle.dumps(e1) - e2 = pickle.loads(pickled) - self.assertEqual(e1.message, e2.message) - self.assertEqual(e1.args, e2.args) - self.assertEqual(e1.source, e2.source) - self.assertEqual(e1.errors, e2.errors) - self.assertEqual(repr(e1), repr(e2)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + pickled = pickle.dumps(e1, proto) + e2 = pickle.loads(pickled) + self.assertEqual(e1.message, e2.message) + self.assertEqual(e1.args, e2.args) + self.assertEqual(e1.source, e2.source) + self.assertEqual(e1.errors, e2.errors) + self.assertEqual(repr(e1), repr(e2)) def test_missingsectionheadererror(self): import pickle e1 = configparser.MissingSectionHeaderError('filename', 123, 'line') - pickled = pickle.dumps(e1) - e2 = pickle.loads(pickled) - self.assertEqual(e1.message, e2.message) - self.assertEqual(e1.args, e2.args) - self.assertEqual(e1.line, e2.line) - self.assertEqual(e1.source, e2.source) - self.assertEqual(e1.lineno, e2.lineno) - self.assertEqual(repr(e1), repr(e2)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + pickled = pickle.dumps(e1, proto) + e2 = pickle.loads(pickled) + self.assertEqual(e1.message, e2.message) + self.assertEqual(e1.args, e2.args) + self.assertEqual(e1.line, e2.line) + self.assertEqual(e1.source, e2.source) + self.assertEqual(e1.lineno, e2.lineno) + self.assertEqual(repr(e1), repr(e2)) class InlineCommentStrippingTestCase(unittest.TestCase): @@ -1765,5 +1804,252 @@ def test_stripping(self): self.assertEqual(s['k3'], 'v3;#//still v3# and still v3') +class ExceptionContextTestCase(unittest.TestCase): + """ Test that implementation details doesn't leak + through raising exceptions. """ + + def test_get_basic_interpolation(self): + parser = configparser.ConfigParser() + parser.read_string(""" + [Paths] + home_dir: /Users + my_dir: %(home_dir1)s/lumberjack + my_pictures: %(my_dir)s/Pictures + """) + cm = self.assertRaises(configparser.InterpolationMissingOptionError) + with cm: + parser.get('Paths', 'my_dir') + self.assertIs(cm.exception.__suppress_context__, True) + + def test_get_extended_interpolation(self): + parser = configparser.ConfigParser( + interpolation=configparser.ExtendedInterpolation()) + parser.read_string(""" + [Paths] + home_dir: /Users + my_dir: ${home_dir1}/lumberjack + my_pictures: ${my_dir}/Pictures + """) + cm = self.assertRaises(configparser.InterpolationMissingOptionError) + with cm: + parser.get('Paths', 'my_dir') + self.assertIs(cm.exception.__suppress_context__, True) + + def test_missing_options(self): + parser = configparser.ConfigParser() + parser.read_string(""" + [Paths] + home_dir: /Users + """) + with self.assertRaises(configparser.NoSectionError) as cm: + parser.options('test') + self.assertIs(cm.exception.__suppress_context__, True) + + def test_missing_section(self): + config = configparser.ConfigParser() + with self.assertRaises(configparser.NoSectionError) as cm: + config.set('Section1', 'an_int', '15') + self.assertIs(cm.exception.__suppress_context__, True) + + def test_remove_option(self): + config = configparser.ConfigParser() + with self.assertRaises(configparser.NoSectionError) as cm: + config.remove_option('Section1', 'an_int') + self.assertIs(cm.exception.__suppress_context__, True) + + +class ConvertersTestCase(BasicTestCase, unittest.TestCase): + """Introduced in 3.5, issue #18159.""" + + config_class = configparser.ConfigParser + + def newconfig(self, defaults=None): + instance = super().newconfig(defaults=defaults) + instance.converters['list'] = lambda v: [e.strip() for e in v.split() + if e.strip()] + return instance + + def test_converters(self): + cfg = self.newconfig() + self.assertIn('boolean', cfg.converters) + self.assertIn('list', cfg.converters) + self.assertIsNone(cfg.converters['int']) + self.assertIsNone(cfg.converters['float']) + self.assertIsNone(cfg.converters['boolean']) + self.assertIsNotNone(cfg.converters['list']) + self.assertEqual(len(cfg.converters), 4) + with self.assertRaises(ValueError): + cfg.converters[''] = lambda v: v + with self.assertRaises(ValueError): + cfg.converters[None] = lambda v: v + cfg.read_string(""" + [s] + str = string + int = 1 + float = 0.5 + list = a b c d e f g + bool = yes + """) + s = cfg['s'] + self.assertEqual(s['str'], 'string') + self.assertEqual(s['int'], '1') + self.assertEqual(s['float'], '0.5') + self.assertEqual(s['list'], 'a b c d e f g') + self.assertEqual(s['bool'], 'yes') + self.assertEqual(cfg.get('s', 'str'), 'string') + self.assertEqual(cfg.get('s', 'int'), '1') + self.assertEqual(cfg.get('s', 'float'), '0.5') + self.assertEqual(cfg.get('s', 'list'), 'a b c d e f g') + self.assertEqual(cfg.get('s', 'bool'), 'yes') + self.assertEqual(cfg.get('s', 'str'), 'string') + self.assertEqual(cfg.getint('s', 'int'), 1) + self.assertEqual(cfg.getfloat('s', 'float'), 0.5) + self.assertEqual(cfg.getlist('s', 'list'), ['a', 'b', 'c', 'd', + 'e', 'f', 'g']) + self.assertEqual(cfg.getboolean('s', 'bool'), True) + self.assertEqual(s.get('str'), 'string') + self.assertEqual(s.getint('int'), 1) + self.assertEqual(s.getfloat('float'), 0.5) + self.assertEqual(s.getlist('list'), ['a', 'b', 'c', 'd', + 'e', 'f', 'g']) + self.assertEqual(s.getboolean('bool'), True) + with self.assertRaises(AttributeError): + cfg.getdecimal('s', 'float') + with self.assertRaises(AttributeError): + s.getdecimal('float') + import decimal + cfg.converters['decimal'] = decimal.Decimal + self.assertIn('decimal', cfg.converters) + self.assertIsNotNone(cfg.converters['decimal']) + self.assertEqual(len(cfg.converters), 5) + dec0_5 = decimal.Decimal('0.5') + self.assertEqual(cfg.getdecimal('s', 'float'), dec0_5) + self.assertEqual(s.getdecimal('float'), dec0_5) + del cfg.converters['decimal'] + self.assertNotIn('decimal', cfg.converters) + self.assertEqual(len(cfg.converters), 4) + with self.assertRaises(AttributeError): + cfg.getdecimal('s', 'float') + with self.assertRaises(AttributeError): + s.getdecimal('float') + with self.assertRaises(KeyError): + del cfg.converters['decimal'] + with self.assertRaises(KeyError): + del cfg.converters[''] + with self.assertRaises(KeyError): + del cfg.converters[None] + + +class BlatantOverrideConvertersTestCase(unittest.TestCase): + """What if somebody overrode a getboolean()? We want to make sure that in + this case the automatic converters do not kick in.""" + + config = """ + [one] + one = false + two = false + three = long story short + + [two] + one = false + two = false + three = four + """ + + def test_converters_at_init(self): + cfg = configparser.ConfigParser(converters={'len': len}) + cfg.read_string(self.config) + self._test_len(cfg) + self.assertIsNotNone(cfg.converters['len']) + + def test_inheritance(self): + class StrangeConfigParser(configparser.ConfigParser): + gettysburg = 'a historic borough in south central Pennsylvania' + + def getboolean(self, section, option, *, raw=False, vars=None, + fallback=configparser._UNSET): + if section == option: + return True + return super().getboolean(section, option, raw=raw, vars=vars, + fallback=fallback) + def getlen(self, section, option, *, raw=False, vars=None, + fallback=configparser._UNSET): + return self._get_conv(section, option, len, raw=raw, vars=vars, + fallback=fallback) + + cfg = StrangeConfigParser() + cfg.read_string(self.config) + self._test_len(cfg) + self.assertIsNone(cfg.converters['len']) + self.assertTrue(cfg.getboolean('one', 'one')) + self.assertTrue(cfg.getboolean('two', 'two')) + self.assertFalse(cfg.getboolean('one', 'two')) + self.assertFalse(cfg.getboolean('two', 'one')) + cfg.converters['boolean'] = cfg._convert_to_boolean + self.assertFalse(cfg.getboolean('one', 'one')) + self.assertFalse(cfg.getboolean('two', 'two')) + self.assertFalse(cfg.getboolean('one', 'two')) + self.assertFalse(cfg.getboolean('two', 'one')) + + def _test_len(self, cfg): + self.assertEqual(len(cfg.converters), 4) + self.assertIn('boolean', cfg.converters) + self.assertIn('len', cfg.converters) + self.assertNotIn('tysburg', cfg.converters) + self.assertIsNone(cfg.converters['int']) + self.assertIsNone(cfg.converters['float']) + self.assertIsNone(cfg.converters['boolean']) + self.assertEqual(cfg.getlen('one', 'one'), 5) + self.assertEqual(cfg.getlen('one', 'two'), 5) + self.assertEqual(cfg.getlen('one', 'three'), 16) + self.assertEqual(cfg.getlen('two', 'one'), 5) + self.assertEqual(cfg.getlen('two', 'two'), 5) + self.assertEqual(cfg.getlen('two', 'three'), 4) + self.assertEqual(cfg.getlen('two', 'four', fallback=0), 0) + with self.assertRaises(configparser.NoOptionError): + cfg.getlen('two', 'four') + self.assertEqual(cfg['one'].getlen('one'), 5) + self.assertEqual(cfg['one'].getlen('two'), 5) + self.assertEqual(cfg['one'].getlen('three'), 16) + self.assertEqual(cfg['two'].getlen('one'), 5) + self.assertEqual(cfg['two'].getlen('two'), 5) + self.assertEqual(cfg['two'].getlen('three'), 4) + self.assertEqual(cfg['two'].getlen('four', 0), 0) + self.assertEqual(cfg['two'].getlen('four'), None) + + def test_instance_assignment(self): + cfg = configparser.ConfigParser() + cfg.getboolean = lambda section, option: True + cfg.getlen = lambda section, option: len(cfg[section][option]) + cfg.read_string(self.config) + self.assertEqual(len(cfg.converters), 3) + self.assertIn('boolean', cfg.converters) + self.assertNotIn('len', cfg.converters) + self.assertIsNone(cfg.converters['int']) + self.assertIsNone(cfg.converters['float']) + self.assertIsNone(cfg.converters['boolean']) + self.assertTrue(cfg.getboolean('one', 'one')) + self.assertTrue(cfg.getboolean('two', 'two')) + self.assertTrue(cfg.getboolean('one', 'two')) + self.assertTrue(cfg.getboolean('two', 'one')) + cfg.converters['boolean'] = cfg._convert_to_boolean + self.assertFalse(cfg.getboolean('one', 'one')) + self.assertFalse(cfg.getboolean('two', 'two')) + self.assertFalse(cfg.getboolean('one', 'two')) + self.assertFalse(cfg.getboolean('two', 'one')) + self.assertEqual(cfg.getlen('one', 'one'), 5) + self.assertEqual(cfg.getlen('one', 'two'), 5) + self.assertEqual(cfg.getlen('one', 'three'), 16) + self.assertEqual(cfg.getlen('two', 'one'), 5) + self.assertEqual(cfg.getlen('two', 'two'), 5) + self.assertEqual(cfg.getlen('two', 'three'), 4) + # If a getter impl is assigned straight to the instance, it won't + # be available on the section proxies. + with self.assertRaises(AttributeError): + self.assertEqual(cfg['one'].getlen('one'), 5) + with self.assertRaises(AttributeError): + self.assertEqual(cfg['two'].getlen('one'), 5) + + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_contextlib.py b/Lib/test/test_contextlib.py index b8770c828f56..c52066be3cc8 100644 --- a/Lib/test/test_contextlib.py +++ b/Lib/test/test_contextlib.py @@ -626,6 +626,67 @@ def suppress_exc(*exc_details): else: self.fail("Expected KeyError, but no exception was raised") + def test_exit_exception_with_correct_context(self): + # http://bugs.python.org/issue20317 + @contextmanager + def gets_the_context_right(exc): + try: + yield + finally: + raise exc + + exc1 = Exception(1) + exc2 = Exception(2) + exc3 = Exception(3) + exc4 = Exception(4) + + # The contextmanager already fixes the context, so prior to the + # fix, ExitStack would try to fix it *again* and get into an + # infinite self-referential loop + try: + with ExitStack() as stack: + stack.enter_context(gets_the_context_right(exc4)) + stack.enter_context(gets_the_context_right(exc3)) + stack.enter_context(gets_the_context_right(exc2)) + raise exc1 + except Exception as exc: + self.assertIs(exc, exc4) + self.assertIs(exc.__context__, exc3) + self.assertIs(exc.__context__.__context__, exc2) + self.assertIs(exc.__context__.__context__.__context__, exc1) + self.assertIsNone( + exc.__context__.__context__.__context__.__context__) + + def test_exit_exception_with_existing_context(self): + # Addresses a lack of test coverage discovered after checking in a + # fix for issue 20317 that still contained debugging code. + def raise_nested(inner_exc, outer_exc): + try: + raise inner_exc + finally: + raise outer_exc + exc1 = Exception(1) + exc2 = Exception(2) + exc3 = Exception(3) + exc4 = Exception(4) + exc5 = Exception(5) + try: + with ExitStack() as stack: + stack.callback(raise_nested, exc4, exc5) + stack.callback(raise_nested, exc2, exc3) + raise exc1 + except Exception as exc: + self.assertIs(exc, exc5) + self.assertIs(exc.__context__, exc4) + self.assertIs(exc.__context__.__context__, exc3) + self.assertIs(exc.__context__.__context__.__context__, exc2) + self.assertIs( + exc.__context__.__context__.__context__.__context__, exc1) + self.assertIsNone( + exc.__context__.__context__.__context__.__context__.__context__) + + + def test_body_exception_suppress(self): def suppress_exc(*exc_details): return True @@ -657,60 +718,76 @@ class Example(object): pass stack.push(cm) self.assertIs(stack._exit_callbacks[-1], cm) -class TestRedirectStdout(unittest.TestCase): + +class TestRedirectStream: + + redirect_stream = None + orig_stream = None @support.requires_docstrings def test_instance_docs(self): # Issue 19330: ensure context manager instances have good docstrings - cm_docstring = redirect_stdout.__doc__ - obj = redirect_stdout(None) + cm_docstring = self.redirect_stream.__doc__ + obj = self.redirect_stream(None) self.assertEqual(obj.__doc__, cm_docstring) def test_no_redirect_in_init(self): - orig_stdout = sys.stdout - redirect_stdout(None) - self.assertIs(sys.stdout, orig_stdout) + orig_stdout = getattr(sys, self.orig_stream) + self.redirect_stream(None) + self.assertIs(getattr(sys, self.orig_stream), orig_stdout) def test_redirect_to_string_io(self): f = io.StringIO() msg = "Consider an API like help(), which prints directly to stdout" - orig_stdout = sys.stdout - with redirect_stdout(f): - print(msg) - self.assertIs(sys.stdout, orig_stdout) + orig_stdout = getattr(sys, self.orig_stream) + with self.redirect_stream(f): + print(msg, file=getattr(sys, self.orig_stream)) + self.assertIs(getattr(sys, self.orig_stream), orig_stdout) s = f.getvalue().strip() self.assertEqual(s, msg) def test_enter_result_is_target(self): f = io.StringIO() - with redirect_stdout(f) as enter_result: + with self.redirect_stream(f) as enter_result: self.assertIs(enter_result, f) def test_cm_is_reusable(self): f = io.StringIO() - write_to_f = redirect_stdout(f) - orig_stdout = sys.stdout + write_to_f = self.redirect_stream(f) + orig_stdout = getattr(sys, self.orig_stream) with write_to_f: - print("Hello", end=" ") + print("Hello", end=" ", file=getattr(sys, self.orig_stream)) with write_to_f: - print("World!") - self.assertIs(sys.stdout, orig_stdout) + print("World!", file=getattr(sys, self.orig_stream)) + self.assertIs(getattr(sys, self.orig_stream), orig_stdout) s = f.getvalue() self.assertEqual(s, "Hello World!\n") def test_cm_is_reentrant(self): f = io.StringIO() - write_to_f = redirect_stdout(f) - orig_stdout = sys.stdout + write_to_f = self.redirect_stream(f) + orig_stdout = getattr(sys, self.orig_stream) with write_to_f: - print("Hello", end=" ") + print("Hello", end=" ", file=getattr(sys, self.orig_stream)) with write_to_f: - print("World!") - self.assertIs(sys.stdout, orig_stdout) + print("World!", file=getattr(sys, self.orig_stream)) + self.assertIs(getattr(sys, self.orig_stream), orig_stdout) s = f.getvalue() self.assertEqual(s, "Hello World!\n") +class TestRedirectStdout(TestRedirectStream, unittest.TestCase): + + redirect_stream = redirect_stdout + orig_stream = "stdout" + + +class TestRedirectStderr(TestRedirectStream, unittest.TestCase): + + redirect_stream = redirect_stderr + orig_stream = "stderr" + + class TestSuppress(unittest.TestCase): @support.requires_docstrings diff --git a/Lib/test/test_copy.py b/Lib/test/test_copy.py index cde0baecad62..eb8d18cf0b12 100644 --- a/Lib/test/test_copy.py +++ b/Lib/test/test_copy.py @@ -98,6 +98,7 @@ class WithMetaclass(metaclass=abc.ABCMeta): pass tests = [None, 42, 2**100, 3.14, True, False, 1j, "hello", "hello\u1234", f.__code__, + b"world", bytes(range(256)), NewStyle, range(10), Classic, max, WithMetaclass] for x in tests: self.assertIs(copy.copy(x), x) diff --git a/Lib/test/test_cprofile.py b/Lib/test/test_cprofile.py index c3eb7faf8f6a..f18983fbb279 100644 --- a/Lib/test/test_cprofile.py +++ b/Lib/test/test_cprofile.py @@ -11,7 +11,7 @@ class CProfileTest(ProfileTest): profilerclass = cProfile.Profile profilermodule = cProfile - expected_max_output = "{built-in method max}" + expected_max_output = "{built-in method builtins.max}" def get_expected_output(self): return _ProfileOutput @@ -29,6 +29,7 @@ def test_bad_counter_during_dealloc(self): obj.enable() obj = _lsprof.Profiler(1) obj.disable() + obj.clear() finally: sys.stderr = orig_stderr finally: @@ -71,9 +72,9 @@ def main(): profilee.py:88(helper2) <- 6 0.234 0.300 profilee.py:55(helper) 2 0.078 0.100 profilee.py:84(helper2_indirect) profilee.py:98(subhelper) <- 8 0.064 0.080 profilee.py:88(helper2) -{built-in method exc_info} <- 4 0.000 0.000 profilee.py:73(helper1) -{built-in method hasattr} <- 4 0.000 0.004 profilee.py:73(helper1) +{built-in method builtins.hasattr} <- 4 0.000 0.004 profilee.py:73(helper1) 8 0.000 0.008 profilee.py:88(helper2) +{built-in method sys.exc_info} <- 4 0.000 0.000 profilee.py:73(helper1) {method 'append' of 'list' objects} <- 4 0.000 0.000 profilee.py:73(helper1)""" _ProfileOutput['print_callees'] = """\ :1() -> 1 0.270 1.000 profilee.py:25(testfunc) @@ -86,12 +87,12 @@ def main(): profilee.py:55(helper) -> 4 0.116 0.120 profilee.py:73(helper1) 2 0.000 0.140 profilee.py:84(helper2_indirect) 6 0.234 0.300 profilee.py:88(helper2) -profilee.py:73(helper1) -> 4 0.000 0.000 {built-in method exc_info} +profilee.py:73(helper1) -> 4 0.000 0.004 {built-in method builtins.hasattr} profilee.py:84(helper2_indirect) -> 2 0.006 0.040 profilee.py:35(factorial) 2 0.078 0.100 profilee.py:88(helper2) profilee.py:88(helper2) -> 8 0.064 0.080 profilee.py:98(subhelper) profilee.py:98(subhelper) -> 16 0.016 0.016 profilee.py:110(__getattr__) -{built-in method hasattr} -> 12 0.012 0.012 profilee.py:110(__getattr__)""" +{built-in method builtins.hasattr} -> 12 0.012 0.012 profilee.py:110(__getattr__)""" if __name__ == "__main__": main() diff --git a/Lib/test/test_csv.py b/Lib/test/test_csv.py index 01fba21f0e3c..3f3f3288499d 100644 --- a/Lib/test/test_csv.py +++ b/Lib/test/test_csv.py @@ -575,6 +575,16 @@ def test_write_simple_dict(self): fileobj.readline() # header self.assertEqual(fileobj.read(), "10,,abc\r\n") + def test_write_multiple_dict_rows(self): + fileobj = StringIO() + writer = csv.DictWriter(fileobj, fieldnames=["f1", "f2", "f3"]) + writer.writeheader() + self.assertEqual(fileobj.getvalue(), "f1,f2,f3\r\n") + writer.writerows([{"f1": 1, "f2": "abc", "f3": "f"}, + {"f1": 2, "f2": 5, "f3": "xyz"}]) + self.assertEqual(fileobj.getvalue(), + "f1,f2,f3\r\n1,abc,f\r\n2,5,xyz\r\n") + def test_write_no_fields(self): fileobj = StringIO() self.assertRaises(TypeError, csv.DictWriter, fileobj) @@ -756,6 +766,7 @@ class mydialect(csv.Dialect): lineterminator = '\r\n' quoting = csv.QUOTE_NONE d = mydialect() + self.assertEqual(d.quoting, csv.QUOTE_NONE) mydialect.quoting = None self.assertRaises(csv.Error, mydialect) @@ -764,12 +775,21 @@ class mydialect(csv.Dialect): mydialect.quoting = csv.QUOTE_ALL mydialect.quotechar = '"' d = mydialect() + self.assertEqual(d.quoting, csv.QUOTE_ALL) + self.assertEqual(d.quotechar, '"') + self.assertTrue(d.doublequote) mydialect.quotechar = "''" - self.assertRaises(csv.Error, mydialect) + with self.assertRaises(csv.Error) as cm: + mydialect() + self.assertEqual(str(cm.exception), + '"quotechar" must be a 1-character string') mydialect.quotechar = 4 - self.assertRaises(csv.Error, mydialect) + with self.assertRaises(csv.Error) as cm: + mydialect() + self.assertEqual(str(cm.exception), + '"quotechar" must be string, not int') def test_delimiter(self): class mydialect(csv.Dialect): @@ -780,12 +800,31 @@ class mydialect(csv.Dialect): lineterminator = '\r\n' quoting = csv.QUOTE_NONE d = mydialect() + self.assertEqual(d.delimiter, ";") mydialect.delimiter = ":::" - self.assertRaises(csv.Error, mydialect) + with self.assertRaises(csv.Error) as cm: + mydialect() + self.assertEqual(str(cm.exception), + '"delimiter" must be a 1-character string') + + mydialect.delimiter = "" + with self.assertRaises(csv.Error) as cm: + mydialect() + self.assertEqual(str(cm.exception), + '"delimiter" must be a 1-character string') + + mydialect.delimiter = b"," + with self.assertRaises(csv.Error) as cm: + mydialect() + self.assertEqual(str(cm.exception), + '"delimiter" must be string, not bytes') mydialect.delimiter = 4 - self.assertRaises(csv.Error, mydialect) + with self.assertRaises(csv.Error) as cm: + mydialect() + self.assertEqual(str(cm.exception), + '"delimiter" must be string, not int') def test_lineterminator(self): class mydialect(csv.Dialect): @@ -796,12 +835,31 @@ class mydialect(csv.Dialect): lineterminator = '\r\n' quoting = csv.QUOTE_NONE d = mydialect() + self.assertEqual(d.lineterminator, '\r\n') mydialect.lineterminator = ":::" d = mydialect() + self.assertEqual(d.lineterminator, ":::") mydialect.lineterminator = 4 - self.assertRaises(csv.Error, mydialect) + with self.assertRaises(csv.Error) as cm: + mydialect() + self.assertEqual(str(cm.exception), + '"lineterminator" must be a string') + + def test_invalid_chars(self): + def create_invalid(field_name, value): + class mydialect(csv.Dialect): + pass + setattr(mydialect, field_name, value) + d = mydialect() + + for field_name in ("delimiter", "escapechar", "quotechar"): + with self.subTest(field_name=field_name): + self.assertRaises(csv.Error, create_invalid, field_name, "") + self.assertRaises(csv.Error, create_invalid, field_name, "abc") + self.assertRaises(csv.Error, create_invalid, field_name, b'x') + self.assertRaises(csv.Error, create_invalid, field_name, 5) class TestSniffer(unittest.TestCase): diff --git a/Lib/test/test_ctypes.py b/Lib/test/test_ctypes.py index 496355e61d34..68268992e9f9 100644 --- a/Lib/test/test_ctypes.py +++ b/Lib/test/test_ctypes.py @@ -1,16 +1,9 @@ import unittest - from test.support import import_module -# Skip tests if _ctypes module was not built. -import_module('_ctypes') - -import ctypes.test +ctypes_test = import_module('ctypes.test') -def load_tests(*args): - skipped, testcases = ctypes.test.get_tests(ctypes.test, "test_*.py", verbosity=0) - suites = [unittest.makeSuite(t) for t in testcases] - return unittest.TestSuite(suites) +load_tests = ctypes_test.load_tests if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_curses.py b/Lib/test/test_curses.py index 7310afc9958f..bd7d4fca8bee 100644 --- a/Lib/test/test_curses.py +++ b/Lib/test/test_curses.py @@ -2,364 +2,374 @@ # Test script for the curses module # # This script doesn't actually display anything very coherent. but it -# does call every method and function. +# does call (nearly) every method and function. # # Functions not tested: {def,reset}_{shell,prog}_mode, getch(), getstr(), # init_color() # Only called, not tested: getmouse(), ungetmouse() # -import sys, tempfile, os +import os +import sys +import tempfile +import unittest + +from test.support import requires, import_module, verbose # Optionally test curses module. This currently requires that the # 'curses' resource be given on the regrtest command line using the -u # option. If not available, nothing after this line will be executed. - -import unittest -from test.support import requires, import_module +import inspect requires('curses') # If either of these don't exist, skip the tests. curses = import_module('curses') curses.panel = import_module('curses.panel') +term = os.environ.get('TERM', 'unknown') + +@unittest.skipUnless(sys.__stdout__.isatty(), 'sys.__stdout__ is not a tty') +@unittest.skipIf(term == 'unknown', + "$TERM=%r, calling initscr() may cause exit" % term) +@unittest.skipIf(sys.platform == "cygwin", + "cygwin's curses mostly just hangs") +class TestCurses(unittest.TestCase): + @classmethod + def setUpClass(cls): + curses.setupterm(fd=sys.__stdout__.fileno()) + + def setUp(self): + if verbose: + # just to make the test output a little more readable + print() + self.stdscr = curses.initscr() + curses.savetty() + + def tearDown(self): + curses.resetty() + curses.endwin() + + def test_window_funcs(self): + "Test the methods of windows" + stdscr = self.stdscr + win = curses.newwin(10,10) + win = curses.newwin(5,5, 5,5) + win2 = curses.newwin(15,15, 5,5) + + for meth in [stdscr.addch, stdscr.addstr]: + for args in [('a'), ('a', curses.A_BOLD), + (4,4, 'a'), (5,5, 'a', curses.A_BOLD)]: + meth(*args) + + for meth in [stdscr.box, stdscr.clear, stdscr.clrtobot, + stdscr.clrtoeol, stdscr.cursyncup, stdscr.delch, + stdscr.deleteln, stdscr.erase, stdscr.getbegyx, + stdscr.getbkgd, stdscr.getkey, stdscr.getmaxyx, + stdscr.getparyx, stdscr.getyx, stdscr.inch, + stdscr.insertln, stdscr.instr, stdscr.is_wintouched, + win.noutrefresh, stdscr.redrawwin, stdscr.refresh, + stdscr.standout, stdscr.standend, stdscr.syncdown, + stdscr.syncup, stdscr.touchwin, stdscr.untouchwin]: + meth() + + stdscr.addnstr('1234', 3) + stdscr.addnstr('1234', 3, curses.A_BOLD) + stdscr.addnstr(4,4, '1234', 3) + stdscr.addnstr(5,5, '1234', 3, curses.A_BOLD) + + stdscr.attron(curses.A_BOLD) + stdscr.attroff(curses.A_BOLD) + stdscr.attrset(curses.A_BOLD) + stdscr.bkgd(' ') + stdscr.bkgd(' ', curses.A_REVERSE) + stdscr.bkgdset(' ') + stdscr.bkgdset(' ', curses.A_REVERSE) -# XXX: if newterm was supported we could use it instead of initscr and not exit -term = os.environ.get('TERM') -if not term or term == 'unknown': - raise unittest.SkipTest("$TERM=%r, calling initscr() may cause exit" % term) - -if sys.platform == "cygwin": - raise unittest.SkipTest("cygwin's curses mostly just hangs") - -def window_funcs(stdscr): - "Test the methods of windows" - win = curses.newwin(10,10) - win = curses.newwin(5,5, 5,5) - win2 = curses.newwin(15,15, 5,5) - - for meth in [stdscr.addch, stdscr.addstr]: - for args in [('a'), ('a', curses.A_BOLD), - (4,4, 'a'), (5,5, 'a', curses.A_BOLD)]: - meth(*args) - - for meth in [stdscr.box, stdscr.clear, stdscr.clrtobot, - stdscr.clrtoeol, stdscr.cursyncup, stdscr.delch, - stdscr.deleteln, stdscr.erase, stdscr.getbegyx, - stdscr.getbkgd, stdscr.getkey, stdscr.getmaxyx, - stdscr.getparyx, stdscr.getyx, stdscr.inch, - stdscr.insertln, stdscr.instr, stdscr.is_wintouched, - win.noutrefresh, stdscr.redrawwin, stdscr.refresh, - stdscr.standout, stdscr.standend, stdscr.syncdown, - stdscr.syncup, stdscr.touchwin, stdscr.untouchwin]: - meth() - - stdscr.addnstr('1234', 3) - stdscr.addnstr('1234', 3, curses.A_BOLD) - stdscr.addnstr(4,4, '1234', 3) - stdscr.addnstr(5,5, '1234', 3, curses.A_BOLD) - - stdscr.attron(curses.A_BOLD) - stdscr.attroff(curses.A_BOLD) - stdscr.attrset(curses.A_BOLD) - stdscr.bkgd(' ') - stdscr.bkgd(' ', curses.A_REVERSE) - stdscr.bkgdset(' ') - stdscr.bkgdset(' ', curses.A_REVERSE) - - win.border(65, 66, 67, 68, - 69, 70, 71, 72) - win.border('|', '!', '-', '_', - '+', '\\', '#', '/') - try: win.border(65, 66, 67, 68, - 69, [], 71, 72) - except TypeError: - pass - else: - raise RuntimeError("Expected win.border() to raise TypeError") - - stdscr.clearok(1) - - win4 = stdscr.derwin(2,2) - win4 = stdscr.derwin(1,1, 5,5) - win4.mvderwin(9,9) - - stdscr.echochar('a') - stdscr.echochar('a', curses.A_BOLD) - stdscr.hline('-', 5) - stdscr.hline('-', 5, curses.A_BOLD) - stdscr.hline(1,1,'-', 5) - stdscr.hline(1,1,'-', 5, curses.A_BOLD) - - stdscr.idcok(1) - stdscr.idlok(1) - stdscr.immedok(1) - stdscr.insch('c') - stdscr.insdelln(1) - stdscr.insnstr('abc', 3) - stdscr.insnstr('abc', 3, curses.A_BOLD) - stdscr.insnstr(5, 5, 'abc', 3) - stdscr.insnstr(5, 5, 'abc', 3, curses.A_BOLD) - - stdscr.insstr('def') - stdscr.insstr('def', curses.A_BOLD) - stdscr.insstr(5, 5, 'def') - stdscr.insstr(5, 5, 'def', curses.A_BOLD) - stdscr.is_linetouched(0) - stdscr.keypad(1) - stdscr.leaveok(1) - stdscr.move(3,3) - win.mvwin(2,2) - stdscr.nodelay(1) - stdscr.notimeout(1) - win2.overlay(win) - win2.overwrite(win) - win2.overlay(win, 1, 2, 3, 3, 2, 1) - win2.overwrite(win, 1, 2, 3, 3, 2, 1) - stdscr.redrawln(1,2) - - stdscr.scrollok(1) - stdscr.scroll() - stdscr.scroll(2) - stdscr.scroll(-3) - - stdscr.move(12, 2) - stdscr.setscrreg(10,15) - win3 = stdscr.subwin(10,10) - win3 = stdscr.subwin(10,10, 5,5) - stdscr.syncok(1) - stdscr.timeout(5) - stdscr.touchline(5,5) - stdscr.touchline(5,5,0) - stdscr.vline('a', 3) - stdscr.vline('a', 3, curses.A_STANDOUT) - stdscr.chgat(5, 2, 3, curses.A_BLINK) - stdscr.chgat(3, curses.A_BOLD) - stdscr.chgat(5, 8, curses.A_UNDERLINE) - stdscr.chgat(curses.A_BLINK) - stdscr.refresh() - - stdscr.vline(1,1, 'a', 3) - stdscr.vline(1,1, 'a', 3, curses.A_STANDOUT) - - if hasattr(curses, 'resize'): - stdscr.resize() - if hasattr(curses, 'enclose'): - stdscr.enclose() - - -def module_funcs(stdscr): - "Test module-level functions" - - for func in [curses.baudrate, curses.beep, curses.can_change_color, - curses.cbreak, curses.def_prog_mode, curses.doupdate, - curses.filter, curses.flash, curses.flushinp, - curses.has_colors, curses.has_ic, curses.has_il, - curses.isendwin, curses.killchar, curses.longname, - curses.nocbreak, curses.noecho, curses.nonl, - curses.noqiflush, curses.noraw, - curses.reset_prog_mode, curses.termattrs, - curses.termname, curses.erasechar, curses.getsyx]: - func() - - # Functions that actually need arguments - if curses.tigetstr("cnorm"): - curses.curs_set(1) - curses.delay_output(1) - curses.echo() ; curses.echo(1) - - f = tempfile.TemporaryFile() - stdscr.putwin(f) - f.seek(0) - curses.getwin(f) - f.close() - - curses.halfdelay(1) - curses.intrflush(1) - curses.meta(1) - curses.napms(100) - curses.newpad(50,50) - win = curses.newwin(5,5) - win = curses.newwin(5,5, 1,1) - curses.nl() ; curses.nl(1) - curses.putp(b'abc') - curses.qiflush() - curses.raw() ; curses.raw(1) - curses.setsyx(5,5) - curses.tigetflag('hc') - curses.tigetnum('co') - curses.tigetstr('cr') - curses.tparm(b'cr') - curses.typeahead(sys.__stdin__.fileno()) - curses.unctrl('a') - curses.ungetch('a') - curses.use_env(1) - - # Functions only available on a few platforms - if curses.has_colors(): - curses.start_color() - curses.init_pair(2, 1,1) - curses.color_content(1) - curses.color_pair(2) - curses.pair_content(curses.COLOR_PAIRS - 1) - curses.pair_number(0) - - if hasattr(curses, 'use_default_colors'): - curses.use_default_colors() - - if hasattr(curses, 'keyname'): - curses.keyname(13) - - if hasattr(curses, 'has_key'): - curses.has_key(13) - - if hasattr(curses, 'getmouse'): - (availmask, oldmask) = curses.mousemask(curses.BUTTON1_PRESSED) - # availmask indicates that mouse stuff not available. - if availmask != 0: - curses.mouseinterval(10) - # just verify these don't cause errors - curses.ungetmouse(0, 0, 0, 0, curses.BUTTON1_PRESSED) - m = curses.getmouse() - - if hasattr(curses, 'is_term_resized'): - curses.is_term_resized(*stdscr.getmaxyx()) - if hasattr(curses, 'resizeterm'): - curses.resizeterm(*stdscr.getmaxyx()) - if hasattr(curses, 'resize_term'): - curses.resize_term(*stdscr.getmaxyx()) - -def unit_tests(): - from curses import ascii - for ch, expected in [('a', 'a'), ('A', 'A'), - (';', ';'), (' ', ' '), - ('\x7f', '^?'), ('\n', '^J'), ('\0', '^@'), - # Meta-bit characters - ('\x8a', '!^J'), ('\xc1', '!A'), - ]: - if ascii.unctrl(ch) != expected: - print('curses.unctrl fails on character', repr(ch)) - - -def test_userptr_without_set(stdscr): - w = curses.newwin(10, 10) - p = curses.panel.new_panel(w) - # try to access userptr() before calling set_userptr() -- segfaults - try: - p.userptr() - raise RuntimeError('userptr should fail since not set') - except curses.panel.error: - pass - -def test_userptr_memory_leak(stdscr): - w = curses.newwin(10, 10) - p = curses.panel.new_panel(w) - obj = object() - nrefs = sys.getrefcount(obj) - for i in range(100): - p.set_userptr(obj) - - p.set_userptr(None) - if sys.getrefcount(obj) != nrefs: - raise RuntimeError("set_userptr leaked references") - -def test_userptr_segfault(stdscr): - panel = curses.panel.new_panel(stdscr) - class A: - def __del__(self): - panel.set_userptr(None) - panel.set_userptr(A()) - panel.set_userptr(None) - -def test_resize_term(stdscr): - if hasattr(curses, 'resizeterm'): + 69, 70, 71, 72) + win.border('|', '!', '-', '_', + '+', '\\', '#', '/') + with self.assertRaises(TypeError, + msg="Expected win.border() to raise TypeError"): + win.border(65, 66, 67, 68, + 69, [], 71, 72) + + stdscr.clearok(1) + + win4 = stdscr.derwin(2,2) + win4 = stdscr.derwin(1,1, 5,5) + win4.mvderwin(9,9) + + stdscr.echochar('a') + stdscr.echochar('a', curses.A_BOLD) + stdscr.hline('-', 5) + stdscr.hline('-', 5, curses.A_BOLD) + stdscr.hline(1,1,'-', 5) + stdscr.hline(1,1,'-', 5, curses.A_BOLD) + + stdscr.idcok(1) + stdscr.idlok(1) + stdscr.immedok(1) + stdscr.insch('c') + stdscr.insdelln(1) + stdscr.insnstr('abc', 3) + stdscr.insnstr('abc', 3, curses.A_BOLD) + stdscr.insnstr(5, 5, 'abc', 3) + stdscr.insnstr(5, 5, 'abc', 3, curses.A_BOLD) + + stdscr.insstr('def') + stdscr.insstr('def', curses.A_BOLD) + stdscr.insstr(5, 5, 'def') + stdscr.insstr(5, 5, 'def', curses.A_BOLD) + stdscr.is_linetouched(0) + stdscr.keypad(1) + stdscr.leaveok(1) + stdscr.move(3,3) + win.mvwin(2,2) + stdscr.nodelay(1) + stdscr.notimeout(1) + win2.overlay(win) + win2.overwrite(win) + win2.overlay(win, 1, 2, 2, 1, 3, 3) + win2.overwrite(win, 1, 2, 2, 1, 3, 3) + stdscr.redrawln(1,2) + + stdscr.scrollok(1) + stdscr.scroll() + stdscr.scroll(2) + stdscr.scroll(-3) + + stdscr.move(12, 2) + stdscr.setscrreg(10,15) + win3 = stdscr.subwin(10,10) + win3 = stdscr.subwin(10,10, 5,5) + stdscr.syncok(1) + stdscr.timeout(5) + stdscr.touchline(5,5) + stdscr.touchline(5,5,0) + stdscr.vline('a', 3) + stdscr.vline('a', 3, curses.A_STANDOUT) + stdscr.chgat(5, 2, 3, curses.A_BLINK) + stdscr.chgat(3, curses.A_BOLD) + stdscr.chgat(5, 8, curses.A_UNDERLINE) + stdscr.chgat(curses.A_BLINK) + stdscr.refresh() + + stdscr.vline(1,1, 'a', 3) + stdscr.vline(1,1, 'a', 3, curses.A_STANDOUT) + + if hasattr(curses, 'resize'): + stdscr.resize() + if hasattr(curses, 'enclose'): + stdscr.enclose() + + + def test_module_funcs(self): + "Test module-level functions" + stdscr = self.stdscr + for func in [curses.baudrate, curses.beep, curses.can_change_color, + curses.cbreak, curses.def_prog_mode, curses.doupdate, + curses.filter, curses.flash, curses.flushinp, + curses.has_colors, curses.has_ic, curses.has_il, + curses.isendwin, curses.killchar, curses.longname, + curses.nocbreak, curses.noecho, curses.nonl, + curses.noqiflush, curses.noraw, + curses.reset_prog_mode, curses.termattrs, + curses.termname, curses.erasechar, curses.getsyx]: + func() + + # Functions that actually need arguments + if curses.tigetstr("cnorm"): + curses.curs_set(1) + curses.delay_output(1) + curses.echo() ; curses.echo(1) + + f = tempfile.TemporaryFile() + stdscr.putwin(f) + f.seek(0) + curses.getwin(f) + f.close() + + curses.halfdelay(1) + curses.intrflush(1) + curses.meta(1) + curses.napms(100) + curses.newpad(50,50) + win = curses.newwin(5,5) + win = curses.newwin(5,5, 1,1) + curses.nl() ; curses.nl(1) + curses.putp(b'abc') + curses.qiflush() + curses.raw() ; curses.raw(1) + curses.setsyx(5,5) + curses.tigetflag('hc') + curses.tigetnum('co') + curses.tigetstr('cr') + curses.tparm(b'cr') + curses.typeahead(sys.__stdin__.fileno()) + curses.unctrl('a') + curses.ungetch('a') + curses.use_env(1) + + # Functions only available on a few platforms + if curses.has_colors(): + curses.start_color() + curses.init_pair(2, 1,1) + curses.color_content(1) + curses.color_pair(2) + curses.pair_content(curses.COLOR_PAIRS - 1) + curses.pair_number(0) + + if hasattr(curses, 'use_default_colors'): + curses.use_default_colors() + + if hasattr(curses, 'keyname'): + curses.keyname(13) + + if hasattr(curses, 'has_key'): + curses.has_key(13) + + if hasattr(curses, 'getmouse'): + (availmask, oldmask) = curses.mousemask(curses.BUTTON1_PRESSED) + # availmask indicates that mouse stuff not available. + if availmask != 0: + curses.mouseinterval(10) + # just verify these don't cause errors + curses.ungetmouse(0, 0, 0, 0, curses.BUTTON1_PRESSED) + m = curses.getmouse() + + if hasattr(curses, 'is_term_resized'): + curses.is_term_resized(*stdscr.getmaxyx()) + if hasattr(curses, 'resizeterm'): + curses.resizeterm(*stdscr.getmaxyx()) + if hasattr(curses, 'resize_term'): + curses.resize_term(*stdscr.getmaxyx()) + + def test_unctrl(self): + from curses import ascii + for ch, expected in [('a', 'a'), ('A', 'A'), + (';', ';'), (' ', ' '), + ('\x7f', '^?'), ('\n', '^J'), ('\0', '^@'), + # Meta-bit characters + ('\x8a', '!^J'), ('\xc1', '!A'), + ]: + self.assertEqual(ascii.unctrl(ch), expected, + 'curses.unctrl fails on character %r' % ch) + + + def test_userptr_without_set(self): + w = curses.newwin(10, 10) + p = curses.panel.new_panel(w) + # try to access userptr() before calling set_userptr() -- segfaults + with self.assertRaises(curses.panel.error, + msg='userptr should fail since not set'): + p.userptr() + + def test_userptr_memory_leak(self): + w = curses.newwin(10, 10) + p = curses.panel.new_panel(w) + obj = object() + nrefs = sys.getrefcount(obj) + for i in range(100): + p.set_userptr(obj) + + p.set_userptr(None) + self.assertEqual(sys.getrefcount(obj), nrefs, + "set_userptr leaked references") + + def test_userptr_segfault(self): + panel = curses.panel.new_panel(self.stdscr) + class A: + def __del__(self): + panel.set_userptr(None) + panel.set_userptr(A()) + panel.set_userptr(None) + + @unittest.skipUnless(hasattr(curses, 'resizeterm'), + 'resizeterm not available') + def test_resize_term(self): lines, cols = curses.LINES, curses.COLS - curses.resizeterm(lines - 1, cols + 1) - - if curses.LINES != lines - 1 or curses.COLS != cols + 1: - raise RuntimeError("Expected resizeterm to update LINES and COLS") - -def test_issue6243(stdscr): - curses.ungetch(1025) - stdscr.getkey() - -def test_unget_wch(stdscr): - if not hasattr(curses, 'unget_wch'): - return - encoding = stdscr.encoding - for ch in ('a', '\xe9', '\u20ac', '\U0010FFFF'): + new_lines = lines - 1 + new_cols = cols + 1 + curses.resizeterm(new_lines, new_cols) + + self.assertEqual(curses.LINES, new_lines) + self.assertEqual(curses.COLS, new_cols) + + def test_issue6243(self): + curses.ungetch(1025) + self.stdscr.getkey() + + @unittest.skipUnless(hasattr(curses, 'unget_wch'), + 'unget_wch not available') + def test_unget_wch(self): + stdscr = self.stdscr + encoding = stdscr.encoding + for ch in ('a', '\xe9', '\u20ac', '\U0010FFFF'): + try: + ch.encode(encoding) + except UnicodeEncodeError: + continue + try: + curses.unget_wch(ch) + except Exception as err: + self.fail("unget_wch(%a) failed with encoding %s: %s" + % (ch, stdscr.encoding, err)) + read = stdscr.get_wch() + self.assertEqual(read, ch) + + code = ord(ch) + curses.unget_wch(code) + read = stdscr.get_wch() + self.assertEqual(read, ch) + + def test_issue10570(self): + b = curses.tparm(curses.tigetstr("cup"), 5, 3) + self.assertIs(type(b), bytes) + curses.putp(b) + + def test_encoding(self): + stdscr = self.stdscr + import codecs + encoding = stdscr.encoding + codecs.lookup(encoding) + + with self.assertRaises(TypeError): + stdscr.encoding = 10 + + stdscr.encoding = encoding + with self.assertRaises(TypeError): + del stdscr.encoding + + def test_issue21088(self): + stdscr = self.stdscr + # + # http://bugs.python.org/issue21088 + # + # the bug: + # when converting curses.window.addch to Argument Clinic + # the first two parameters were switched. + + # if someday we can represent the signature of addch + # we will need to rewrite this test. try: - ch.encode(encoding) - except UnicodeEncodeError: - continue - try: - curses.unget_wch(ch) - except Exception as err: - raise Exception("unget_wch(%a) failed with encoding %s: %s" - % (ch, stdscr.encoding, err)) - read = stdscr.get_wch() - if read != ch: - raise AssertionError("%r != %r" % (read, ch)) - - code = ord(ch) - curses.unget_wch(code) - read = stdscr.get_wch() - if read != ch: - raise AssertionError("%r != %r" % (read, ch)) - -def test_issue10570(): - b = curses.tparm(curses.tigetstr("cup"), 5, 3) - assert type(b) is bytes - curses.putp(b) - -def test_encoding(stdscr): - import codecs - encoding = stdscr.encoding - codecs.lookup(encoding) - try: - stdscr.encoding = 10 - except TypeError: - pass - else: - raise AssertionError("TypeError not raised") - stdscr.encoding = encoding - try: - del stdscr.encoding - except TypeError: - pass - else: - raise AssertionError("TypeError not raised") - -def main(stdscr): - curses.savetty() - try: - module_funcs(stdscr) - window_funcs(stdscr) - test_userptr_without_set(stdscr) - test_userptr_memory_leak(stdscr) - test_userptr_segfault(stdscr) - test_resize_term(stdscr) - test_issue6243(stdscr) - test_unget_wch(stdscr) - test_issue10570() - test_encoding(stdscr) - finally: - curses.resetty() + signature = inspect.signature(stdscr.addch) + self.assertFalse(signature) + except ValueError: + # not generating a signature is fine. + pass + + # So. No signature for addch. + # But Argument Clinic gave us a human-readable equivalent + # as the first line of the docstring. So we parse that, + # and ensure that the parameters appear in the correct order. + # Since this is parsing output from Argument Clinic, we can + # be reasonably certain the generated parsing code will be + # correct too. + human_readable_signature = stdscr.addch.__doc__.split("\n")[0] + offset = human_readable_signature.find("[y, x,]") + assert offset >= 0, "" -def test_main(): - if not sys.__stdout__.isatty(): - raise unittest.SkipTest("sys.__stdout__ is not a tty") - # testing setupterm() inside initscr/endwin - # causes terminal breakage - curses.setupterm(fd=sys.__stdout__.fileno()) - try: - stdscr = curses.initscr() - main(stdscr) - finally: - curses.endwin() - unit_tests() if __name__ == '__main__': - curses.wrapper(main) - unit_tests() + unittest.main() diff --git a/Lib/test/test_datetime.py b/Lib/test/test_datetime.py index d9ddb32363a0..2d4eb52c62c0 100644 --- a/Lib/test/test_datetime.py +++ b/Lib/test/test_datetime.py @@ -1,20 +1,20 @@ import unittest import sys + from test.support import import_fresh_module, run_unittest TESTS = 'test.datetimetester' -# XXX: import_fresh_module() is supposed to leave sys.module cache untouched, -# XXX: but it does not, so we have to save and restore it ourselves. -save_sys_modules = sys.modules.copy() try: pure_tests = import_fresh_module(TESTS, fresh=['datetime', '_strptime'], blocked=['_datetime']) fast_tests = import_fresh_module(TESTS, fresh=['datetime', '_datetime', '_strptime']) finally: - sys.modules.clear() - sys.modules.update(save_sys_modules) + # XXX: import_fresh_module() is supposed to leave sys.module cache untouched, + # XXX: but it does not, so we have to cleanup ourselves. + for modname in ['datetime', '_datetime', '_strptime']: + sys.modules.pop(modname, None) test_modules = [pure_tests, fast_tests] test_suffixes = ["_Pure", "_Fast"] # XXX(gb) First run all the _Pure tests, then all the _Fast tests. You might diff --git a/Lib/test/test_dbm.py b/Lib/test/test_dbm.py index 1c5777024234..623d9929d58f 100644 --- a/Lib/test/test_dbm.py +++ b/Lib/test/test_dbm.py @@ -1,4 +1,3 @@ -#! /usr/bin/env python3 """Test script for the dbm.open function based on testdumbdbm.py""" import os diff --git a/Lib/test/test_dbm_dumb.py b/Lib/test/test_dbm_dumb.py index 9fd8cde59a84..ff63c88c0bc5 100644 --- a/Lib/test/test_dbm_dumb.py +++ b/Lib/test/test_dbm_dumb.py @@ -1,13 +1,14 @@ -#! /usr/bin/env python3 """Test script for the dumbdbm module Original by Roger E. Masse """ import io +import operator import os import unittest import dbm.dumb as dumbdbm from test import support +from functools import partial _fname = support.TESTFN @@ -191,12 +192,48 @@ def test_context_manager(self): with dumbdbm.open(_fname, 'r') as db: self.assertEqual(list(db.keys()), [b"dumbdbm context manager"]) - # This currently just raises AttributeError rather than a specific - # exception like the GNU or NDBM based implementations. See - # http://bugs.python.org/issue19385 for details. - with self.assertRaises(Exception): + with self.assertRaises(dumbdbm.error): db.keys() + def test_check_closed(self): + f = dumbdbm.open(_fname, 'c') + f.close() + + for meth in (partial(operator.delitem, f), + partial(operator.setitem, f, 'b'), + partial(operator.getitem, f), + partial(operator.contains, f)): + with self.assertRaises(dumbdbm.error) as cm: + meth('test') + self.assertEqual(str(cm.exception), + "DBM object has already been closed") + + for meth in (operator.methodcaller('keys'), + operator.methodcaller('iterkeys'), + operator.methodcaller('items'), + len): + with self.assertRaises(dumbdbm.error) as cm: + meth(f) + self.assertEqual(str(cm.exception), + "DBM object has already been closed") + + def test_create_new(self): + with dumbdbm.open(_fname, 'n') as f: + for k in self._dict: + f[k] = self._dict[k] + + with dumbdbm.open(_fname, 'n') as f: + self.assertEqual(f.keys(), []) + + def test_eval(self): + with open(_fname + '.dir', 'w') as stream: + stream.write("str(print('Hacked!')), 0\n") + with support.captured_stdout() as stdout: + with self.assertRaises(ValueError): + with dumbdbm.open(_fname) as f: + pass + self.assertEqual(stdout.getvalue(), '') + def tearDown(self): _delete_files() diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py index 6378ef300e21..137aaa537e2d 100644 --- a/Lib/test/test_decimal.py +++ b/Lib/test/test_decimal.py @@ -33,12 +33,13 @@ import numbers import locale from test.support import (run_unittest, run_doctest, is_resource_enabled, - requires_IEEE_754) + requires_IEEE_754, requires_docstrings) from test.support import (check_warnings, import_fresh_module, TestFailed, run_with_locale, cpython_only) import random import time import warnings +import inspect try: import threading except ImportError: @@ -300,7 +301,6 @@ def eval_file(self, file): #Exception raised where there shouldn't have been one. self.fail('Exception "'+exception.__class__.__name__ + '" raised on line '+line) - return def eval_line(self, s): if s.find(' -> ') >= 0 and s[:2] != '--' and not s.startswith(' --'): @@ -460,7 +460,6 @@ def FixQuotes(val): self.assertEqual(myexceptions, theirexceptions, 'Incorrect flags set in ' + s + ' -- got ' + str(myexceptions)) - return def getexceptions(self): return [e for e in Signals[self.decimal] if self.context.flags[e]] @@ -1059,6 +1058,11 @@ def test_formatting(self): # issue 6850 ('a=-7.0', '0.12345', 'aaaa0.1'), + + # issue 22090 + ('<^+15.20%', 'inf', '<<+Infinity%<<<'), + ('\x07>,%', 'sNaN1234567', 'sNaN1234567%'), + ('=10.10%', 'NaN123', ' NaN123%'), ] for fmt, d, result in test_values: self.assertEqual(format(Decimal(d), fmt), result) @@ -1072,7 +1076,7 @@ def test_n_format(self): try: from locale import CHAR_MAX except ImportError: - return + self.skipTest('locale.CHAR_MAX not available') def make_grouping(lst): return ''.join([chr(x) for x in lst]) if self.decimal == C else lst @@ -1163,8 +1167,12 @@ def test_wide_char_separator_decimal_point(self): decimal_point = locale.localeconv()['decimal_point'] thousands_sep = locale.localeconv()['thousands_sep'] - if decimal_point != '\u066b' or thousands_sep != '\u066c': - return + if decimal_point != '\u066b': + self.skipTest('inappropriate decimal point separator' + '({!a} not {!a})'.format(decimal_point, '\u066b')) + if thousands_sep != '\u066c': + self.skipTest('inappropriate thousands separator' + '({!a} not {!a})'.format(thousands_sep, '\u066c')) self.assertEqual(format(Decimal('100000000.123'), 'n'), '100\u066c000\u066c000\u066b123') @@ -1514,7 +1522,6 @@ def thfunc1(cls): cls.assertTrue(c1.flags[Inexact]) for sig in Overflow, Underflow, DivisionByZero, InvalidOperation: cls.assertFalse(c1.flags[sig]) - return def thfunc2(cls): Decimal = cls.decimal.Decimal @@ -1559,7 +1566,6 @@ def thfunc2(cls): cls.assertTrue(thiscontext.flags[Inexact]) for sig in Overflow, Underflow, DivisionByZero, InvalidOperation: cls.assertFalse(thiscontext.flags[sig]) - return class ThreadingTest(unittest.TestCase): '''Unit tests for thread local contexts in Decimal.''' @@ -1601,7 +1607,6 @@ def test_threading(self): DefaultContext.prec = save_prec DefaultContext.Emax = save_emax DefaultContext.Emin = save_emin - return @unittest.skipUnless(threading, 'threading required') class CThreadingTest(ThreadingTest): @@ -2402,37 +2407,55 @@ def test_abc(self): self.assertNotIsInstance(Decimal(0), numbers.Real) def test_pickle(self): - Decimal = self.decimal.Decimal + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + Decimal = self.decimal.Decimal - savedecimal = sys.modules['decimal'] + savedecimal = sys.modules['decimal'] - # Round trip - sys.modules['decimal'] = self.decimal - d = Decimal('-3.141590000') - p = pickle.dumps(d) - e = pickle.loads(p) - self.assertEqual(d, e) + # Round trip + sys.modules['decimal'] = self.decimal + d = Decimal('-3.141590000') + p = pickle.dumps(d, proto) + e = pickle.loads(p) + self.assertEqual(d, e) - if C: - # Test interchangeability - x = C.Decimal('-3.123e81723') - y = P.Decimal('-3.123e81723') + if C: + # Test interchangeability + x = C.Decimal('-3.123e81723') + y = P.Decimal('-3.123e81723') - sys.modules['decimal'] = C - sx = pickle.dumps(x) - sys.modules['decimal'] = P - r = pickle.loads(sx) - self.assertIsInstance(r, P.Decimal) - self.assertEqual(r, y) + sys.modules['decimal'] = C + sx = pickle.dumps(x, proto) + sys.modules['decimal'] = P + r = pickle.loads(sx) + self.assertIsInstance(r, P.Decimal) + self.assertEqual(r, y) + + sys.modules['decimal'] = P + sy = pickle.dumps(y, proto) + sys.modules['decimal'] = C + r = pickle.loads(sy) + self.assertIsInstance(r, C.Decimal) + self.assertEqual(r, x) - sys.modules['decimal'] = P - sy = pickle.dumps(y) - sys.modules['decimal'] = C - r = pickle.loads(sy) - self.assertIsInstance(r, C.Decimal) - self.assertEqual(r, x) + x = C.Decimal('-3.123e81723').as_tuple() + y = P.Decimal('-3.123e81723').as_tuple() - sys.modules['decimal'] = savedecimal + sys.modules['decimal'] = C + sx = pickle.dumps(x, proto) + sys.modules['decimal'] = P + r = pickle.loads(sx) + self.assertIsInstance(r, P.DecimalTuple) + self.assertEqual(r, y) + + sys.modules['decimal'] = P + sy = pickle.dumps(y, proto) + sys.modules['decimal'] = C + r = pickle.loads(sy) + self.assertIsInstance(r, C.DecimalTuple) + self.assertEqual(r, x) + + sys.modules['decimal'] = savedecimal def test_int(self): Decimal = self.decimal.Decimal @@ -2756,63 +2779,64 @@ def test_from_legacy_strings(self): def test_pickle(self): - Context = self.decimal.Context + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + Context = self.decimal.Context - savedecimal = sys.modules['decimal'] + savedecimal = sys.modules['decimal'] - # Round trip - sys.modules['decimal'] = self.decimal - c = Context() - e = pickle.loads(pickle.dumps(c)) - - self.assertEqual(c.prec, e.prec) - self.assertEqual(c.Emin, e.Emin) - self.assertEqual(c.Emax, e.Emax) - self.assertEqual(c.rounding, e.rounding) - self.assertEqual(c.capitals, e.capitals) - self.assertEqual(c.clamp, e.clamp) - self.assertEqual(c.flags, e.flags) - self.assertEqual(c.traps, e.traps) - - # Test interchangeability - combinations = [(C, P), (P, C)] if C else [(P, P)] - for dumper, loader in combinations: - for ri, _ in enumerate(RoundingModes): - for fi, _ in enumerate(OrderedSignals[dumper]): - for ti, _ in enumerate(OrderedSignals[dumper]): - - prec = random.randrange(1, 100) - emin = random.randrange(-100, 0) - emax = random.randrange(1, 100) - caps = random.randrange(2) - clamp = random.randrange(2) - - # One module dumps - sys.modules['decimal'] = dumper - c = dumper.Context( - prec=prec, Emin=emin, Emax=emax, - rounding=RoundingModes[ri], - capitals=caps, clamp=clamp, - flags=OrderedSignals[dumper][:fi], - traps=OrderedSignals[dumper][:ti] - ) - s = pickle.dumps(c) - - # The other module loads - sys.modules['decimal'] = loader - d = pickle.loads(s) - self.assertIsInstance(d, loader.Context) - - self.assertEqual(d.prec, prec) - self.assertEqual(d.Emin, emin) - self.assertEqual(d.Emax, emax) - self.assertEqual(d.rounding, RoundingModes[ri]) - self.assertEqual(d.capitals, caps) - self.assertEqual(d.clamp, clamp) - assert_signals(self, d, 'flags', OrderedSignals[loader][:fi]) - assert_signals(self, d, 'traps', OrderedSignals[loader][:ti]) - - sys.modules['decimal'] = savedecimal + # Round trip + sys.modules['decimal'] = self.decimal + c = Context() + e = pickle.loads(pickle.dumps(c, proto)) + + self.assertEqual(c.prec, e.prec) + self.assertEqual(c.Emin, e.Emin) + self.assertEqual(c.Emax, e.Emax) + self.assertEqual(c.rounding, e.rounding) + self.assertEqual(c.capitals, e.capitals) + self.assertEqual(c.clamp, e.clamp) + self.assertEqual(c.flags, e.flags) + self.assertEqual(c.traps, e.traps) + + # Test interchangeability + combinations = [(C, P), (P, C)] if C else [(P, P)] + for dumper, loader in combinations: + for ri, _ in enumerate(RoundingModes): + for fi, _ in enumerate(OrderedSignals[dumper]): + for ti, _ in enumerate(OrderedSignals[dumper]): + + prec = random.randrange(1, 100) + emin = random.randrange(-100, 0) + emax = random.randrange(1, 100) + caps = random.randrange(2) + clamp = random.randrange(2) + + # One module dumps + sys.modules['decimal'] = dumper + c = dumper.Context( + prec=prec, Emin=emin, Emax=emax, + rounding=RoundingModes[ri], + capitals=caps, clamp=clamp, + flags=OrderedSignals[dumper][:fi], + traps=OrderedSignals[dumper][:ti] + ) + s = pickle.dumps(c, proto) + + # The other module loads + sys.modules['decimal'] = loader + d = pickle.loads(s) + self.assertIsInstance(d, loader.Context) + + self.assertEqual(d.prec, prec) + self.assertEqual(d.Emin, emin) + self.assertEqual(d.Emax, emax) + self.assertEqual(d.rounding, RoundingModes[ri]) + self.assertEqual(d.capitals, caps) + self.assertEqual(d.clamp, clamp) + assert_signals(self, d, 'flags', OrderedSignals[loader][:fi]) + assert_signals(self, d, 'traps', OrderedSignals[loader][:ti]) + + sys.modules['decimal'] = savedecimal def test_equality_with_other_types(self): Decimal = self.decimal.Decimal @@ -4151,9 +4175,7 @@ def test_module_attributes(self): self.assertEqual(C.__version__, P.__version__) self.assertEqual(C.__libmpdec_version__, P.__libmpdec_version__) - x = dir(C) - y = [s for s in dir(P) if '__' in s or not s.startswith('_')] - self.assertEqual(set(x) - set(y), set()) + self.assertEqual(dir(C), dir(P)) def test_context_attributes(self): @@ -4432,18 +4454,6 @@ class PyCoverage(Coverage): class PyFunctionality(unittest.TestCase): """Extra functionality in decimal.py""" - def test_py_quantize_watchexp(self): - # watchexp functionality - Decimal = P.Decimal - localcontext = P.localcontext - - with localcontext() as c: - c.prec = 1 - c.Emax = 1 - c.Emin = -1 - x = Decimal(99999).quantize(Decimal("1e3"), watchexp=False) - self.assertEqual(x, Decimal('1.00E+5')) - def test_py_alternate_formatting(self): # triples giving a format, a Decimal, and the expected result Decimal = P.Decimal @@ -4524,7 +4534,6 @@ def checkSameDec(operation, useOther=False): self.assertEqual(d1._sign, b1._sign) self.assertEqual(d1._int, b1._int) self.assertEqual(d1._exp, b1._exp) - return Decimal(d1) self.assertEqual(d1._sign, b1._sign) @@ -5270,7 +5279,7 @@ def test_invalid_override(self): try: from locale import CHAR_MAX except ImportError: - return + self.skipTest('locale.CHAR_MAX not available') def make_grouping(lst): return ''.join([chr(x) for x in lst]) @@ -5387,6 +5396,143 @@ def test_sizeof(self): y = Decimal(10**(9*25)).__sizeof__() self.assertEqual(y, x+4) +@requires_docstrings +@unittest.skipUnless(C, "test requires C version") +class SignatureTest(unittest.TestCase): + """Function signatures""" + + def test_inspect_module(self): + for attr in dir(P): + if attr.startswith('_'): + continue + p_func = getattr(P, attr) + c_func = getattr(C, attr) + if (attr == 'Decimal' or attr == 'Context' or + inspect.isfunction(p_func)): + p_sig = inspect.signature(p_func) + c_sig = inspect.signature(c_func) + + # parameter names: + c_names = list(c_sig.parameters.keys()) + p_names = [x for x in p_sig.parameters.keys() if not + x.startswith('_')] + + self.assertEqual(c_names, p_names, + msg="parameter name mismatch in %s" % p_func) + + c_kind = [x.kind for x in c_sig.parameters.values()] + p_kind = [x[1].kind for x in p_sig.parameters.items() if not + x[0].startswith('_')] + + # parameters: + if attr != 'setcontext': + self.assertEqual(c_kind, p_kind, + msg="parameter kind mismatch in %s" % p_func) + + def test_inspect_types(self): + + POS = inspect._ParameterKind.POSITIONAL_ONLY + POS_KWD = inspect._ParameterKind.POSITIONAL_OR_KEYWORD + + # Type heuristic (type annotations would help!): + pdict = {C: {'other': C.Decimal(1), + 'third': C.Decimal(1), + 'x': C.Decimal(1), + 'y': C.Decimal(1), + 'z': C.Decimal(1), + 'a': C.Decimal(1), + 'b': C.Decimal(1), + 'c': C.Decimal(1), + 'exp': C.Decimal(1), + 'modulo': C.Decimal(1), + 'num': "1", + 'f': 1.0, + 'rounding': C.ROUND_HALF_UP, + 'context': C.getcontext()}, + P: {'other': P.Decimal(1), + 'third': P.Decimal(1), + 'a': P.Decimal(1), + 'b': P.Decimal(1), + 'c': P.Decimal(1), + 'exp': P.Decimal(1), + 'modulo': P.Decimal(1), + 'num': "1", + 'f': 1.0, + 'rounding': P.ROUND_HALF_UP, + 'context': P.getcontext()}} + + def mkargs(module, sig): + args = [] + kwargs = {} + for name, param in sig.parameters.items(): + if name == 'self': continue + if param.kind == POS: + args.append(pdict[module][name]) + elif param.kind == POS_KWD: + kwargs[name] = pdict[module][name] + else: + raise TestFailed("unexpected parameter kind") + return args, kwargs + + def tr(s): + """The C Context docstrings use 'x' in order to prevent confusion + with the article 'a' in the descriptions.""" + if s == 'x': return 'a' + if s == 'y': return 'b' + if s == 'z': return 'c' + return s + + def doit(ty): + p_type = getattr(P, ty) + c_type = getattr(C, ty) + for attr in dir(p_type): + if attr.startswith('_'): + continue + p_func = getattr(p_type, attr) + c_func = getattr(c_type, attr) + if inspect.isfunction(p_func): + p_sig = inspect.signature(p_func) + c_sig = inspect.signature(c_func) + + # parameter names: + p_names = list(p_sig.parameters.keys()) + c_names = [tr(x) for x in c_sig.parameters.keys()] + + self.assertEqual(c_names, p_names, + msg="parameter name mismatch in %s" % p_func) + + p_kind = [x.kind for x in p_sig.parameters.values()] + c_kind = [x.kind for x in c_sig.parameters.values()] + + # 'self' parameter: + self.assertIs(p_kind[0], POS_KWD) + self.assertIs(c_kind[0], POS) + + # remaining parameters: + if ty == 'Decimal': + self.assertEqual(c_kind[1:], p_kind[1:], + msg="parameter kind mismatch in %s" % p_func) + else: # Context methods are positional only in the C version. + self.assertEqual(len(c_kind), len(p_kind), + msg="parameter kind mismatch in %s" % p_func) + + # Run the function: + args, kwds = mkargs(C, c_sig) + try: + getattr(c_type(9), attr)(*args, **kwds) + except Exception as err: + raise TestFailed("invalid signature for %s: %s %s" % (c_func, args, kwds)) + + args, kwds = mkargs(P, p_sig) + try: + getattr(p_type(9), attr)(*args, **kwds) + except Exception as err: + raise TestFailed("invalid signature for %s: %s %s" % (p_func, args, kwds)) + + doit('Decimal') + doit('Context') + + all_tests = [ CExplicitConstructionTest, PyExplicitConstructionTest, CImplicitConstructionTest, PyImplicitConstructionTest, @@ -5412,9 +5558,10 @@ def test_sizeof(self): all_tests = all_tests[1::2] else: all_tests.insert(0, CheckAttributes) + all_tests.insert(1, SignatureTest) -def test_main(arith=False, verbose=None, todo_tests=None, debug=None): +def test_main(arith=None, verbose=None, todo_tests=None, debug=None): """ Execute the tests. Runs all arithmetic tests if arith is True or if the "decimal" resource @@ -5424,7 +5571,7 @@ def test_main(arith=False, verbose=None, todo_tests=None, debug=None): init(C) init(P) global TEST_ALL, DEBUG - TEST_ALL = arith or is_resource_enabled('decimal') + TEST_ALL = arith if arith is not None else is_resource_enabled('decimal') DEBUG = debug if todo_tests is None: diff --git a/Lib/test/test_defaultdict.py b/Lib/test/test_defaultdict.py index 532d535981b3..48d1cb537bc1 100644 --- a/Lib/test/test_defaultdict.py +++ b/Lib/test/test_defaultdict.py @@ -157,8 +157,9 @@ def __init__(self): def _factory(self): return [] d = sub() - self.assertTrue(repr(d).startswith( - "defaultdict(, \{\}\)") # NOTE: printing a subclass of a builtin type does not call its # tp_print slot. So this part is essentially the same test as above. diff --git a/Lib/test/test_deque.py b/Lib/test/test_deque.py index 7bff1d2798b4..e336e5a38489 100644 --- a/Lib/test/test_deque.py +++ b/Lib/test/test_deque.py @@ -474,16 +474,17 @@ def test_pickle(self): def test_iterator_pickle(self): data = deque(range(200)) - it = itorg = iter(data) - d = pickle.dumps(it) - it = pickle.loads(d) - self.assertEqual(type(itorg), type(it)) - self.assertEqual(list(it), list(data)) - - it = pickle.loads(d) - next(it) - d = pickle.dumps(it) - self.assertEqual(list(it), list(data)[1:]) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + it = itorg = iter(data) + d = pickle.dumps(it, proto) + it = pickle.loads(d) + self.assertEqual(type(itorg), type(it)) + self.assertEqual(list(it), list(data)) + + it = pickle.loads(d) + next(it) + d = pickle.dumps(it, proto) + self.assertEqual(list(it), list(data)[1:]) def test_deepcopy(self): mut = [10] @@ -507,6 +508,11 @@ def test_reversed(self): for s in ('abcd', range(2000)): self.assertEqual(list(reversed(deque(s))), list(reversed(s))) + def test_reversed_new(self): + klass = type(reversed(deque())) + for s in ('abcd', range(2000)): + self.assertEqual(list(klass(deque(s))), list(reversed(s))) + def test_gc_doesnt_blowup(self): import gc # This used to assert-fail in deque_traverse() under a debug @@ -614,11 +620,12 @@ def test_copy_pickle(self): self.assertEqual(type(d), type(e)) self.assertEqual(list(d), list(e)) - s = pickle.dumps(d) - e = pickle.loads(s) - self.assertNotEqual(id(d), id(e)) - self.assertEqual(type(d), type(e)) - self.assertEqual(list(d), list(e)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + s = pickle.dumps(d, proto) + e = pickle.loads(s) + self.assertNotEqual(id(d), id(e)) + self.assertEqual(type(d), type(e)) + self.assertEqual(list(d), list(e)) d = Deque('abcde', maxlen=4) @@ -630,11 +637,12 @@ def test_copy_pickle(self): self.assertEqual(type(d), type(e)) self.assertEqual(list(d), list(e)) - s = pickle.dumps(d) - e = pickle.loads(s) - self.assertNotEqual(id(d), id(e)) - self.assertEqual(type(d), type(e)) - self.assertEqual(list(d), list(e)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + s = pickle.dumps(d, proto) + e = pickle.loads(s) + self.assertNotEqual(id(d), id(e)) + self.assertEqual(type(d), type(e)) + self.assertEqual(list(d), list(e)) ## def test_pickle(self): ## d = Deque('abc') diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index f08a3d2bf613..8d6205afbfce 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -1026,6 +1026,22 @@ class Cdict(object): self.assertEqual(x.foo, 1) self.assertEqual(x.__dict__, {'foo': 1}) + def test_object_class_assignment_between_heaptypes_and_nonheaptypes(self): + class SubType(types.ModuleType): + a = 1 + + m = types.ModuleType("m") + self.assertTrue(m.__class__ is types.ModuleType) + self.assertFalse(hasattr(m, "a")) + + m.__class__ = SubType + self.assertTrue(m.__class__ is SubType) + self.assertTrue(hasattr(m, "a")) + + m.__class__ = types.ModuleType + self.assertTrue(m.__class__ is types.ModuleType) + self.assertFalse(hasattr(m, "a")) + def test_slots(self): # Testing __slots__... class C0(object): @@ -1149,7 +1165,7 @@ class C(object): except (TypeError, UnicodeEncodeError): pass else: - raise TestFailed("[chr(128)] slots not caught") + self.fail("[chr(128)] slots not caught") # Test leaks class Counted(object): @@ -2050,6 +2066,7 @@ def setter(self_, value): prop2 = property(fset=setter) self.assertEqual(prop2.__doc__, None) + @support.cpython_only def test_testcapi_no_segfault(self): # this segfaulted in 2.5b2 try: @@ -4159,6 +4176,7 @@ def check(expr, x, y): ('__add__', 'x + y', 'x += y'), ('__sub__', 'x - y', 'x -= y'), ('__mul__', 'x * y', 'x *= y'), + ('__matmul__', 'x @ y', 'x @= y'), ('__truediv__', 'operator.truediv(x, y)', None), ('__floordiv__', 'operator.floordiv(x, y)', None), ('__div__', 'x / y', 'x /= y'), @@ -4413,6 +4431,69 @@ class OverrideBoth(OverrideNew, OverrideInit): self.assertRaises(TypeError, case, 1, 2, 3) self.assertRaises(TypeError, case, 1, 2, foo=3) + def test_subclassing_does_not_duplicate_dict_descriptors(self): + class Base: + pass + class Sub(Base): + pass + self.assertIn("__dict__", Base.__dict__) + self.assertNotIn("__dict__", Sub.__dict__) + + def test_bound_method_repr(self): + class Foo: + def method(self): + pass + self.assertRegex(repr(Foo().method), + r">") + + + class Base: + def method(self): + pass + class Derived1(Base): + pass + class Derived2(Base): + def method(self): + pass + base = Base() + derived1 = Derived1() + derived2 = Derived2() + super_d2 = super(Derived2, derived2) + self.assertRegex(repr(base.method), + r">") + self.assertRegex(repr(derived1.method), + r">") + self.assertRegex(repr(derived2.method), + r">") + self.assertRegex(repr(super_d2.method), + r">") + + class Foo: + @classmethod + def method(cls): + pass + foo = Foo() + self.assertRegex(repr(foo.method), # access via instance + r">") + self.assertRegex(repr(Foo.method), # access via the class + r">") + + + class MyCallable: + def __call__(self, arg): + pass + func = MyCallable() # func has no __name__ or __qualname__ attributes + instance = object() + method = types.MethodType(func, instance) + self.assertRegex(repr(method), + r">") + func.__name__ = "name" + self.assertRegex(repr(method), + r">") + func.__qualname__ = "qualname" + self.assertRegex(repr(method), + r">") + class DictProxyTests(unittest.TestCase): def setUp(self): @@ -4527,26 +4608,15 @@ class PicklingTests(unittest.TestCase): def _check_reduce(self, proto, obj, args=(), kwargs={}, state=None, listitems=None, dictitems=None): - if proto >= 4: + if proto >= 2: reduce_value = obj.__reduce_ex__(proto) - self.assertEqual(reduce_value[:3], - (copyreg.__newobj_ex__, - (type(obj), args, kwargs), - state)) - if listitems is not None: - self.assertListEqual(list(reduce_value[3]), listitems) - else: - self.assertIsNone(reduce_value[3]) - if dictitems is not None: - self.assertDictEqual(dict(reduce_value[4]), dictitems) + if kwargs: + self.assertEqual(reduce_value[0], copyreg.__newobj_ex__) + self.assertEqual(reduce_value[1], (type(obj), args, kwargs)) else: - self.assertIsNone(reduce_value[4]) - elif proto >= 2: - reduce_value = obj.__reduce_ex__(proto) - self.assertEqual(reduce_value[:3], - (copyreg.__newobj__, - (type(obj),) + args, - state)) + self.assertEqual(reduce_value[0], copyreg.__newobj__) + self.assertEqual(reduce_value[1], (type(obj),) + args) + self.assertEqual(reduce_value[2], state) if listitems is not None: self.assertListEqual(list(reduce_value[3]), listitems) else: @@ -4700,6 +4770,20 @@ class C16(list): for proto in protocols: self._check_reduce(proto, obj, listitems=list(obj)) + def test_special_method_lookup(self): + protocols = range(pickle.HIGHEST_PROTOCOL + 1) + class Picky: + def __getstate__(self): + return {} + + def __getattr__(self, attr): + if attr in ("__getnewargs__", "__getnewargs_ex__"): + raise AssertionError(attr) + return None + for protocol in protocols: + state = {} if protocol >= 2 else None + self._check_reduce(protocol, Picky(), state=state) + def _assert_is_copy(self, obj, objcopy, msg=None): """Utility method to verify if two objects are copies of each others. """ @@ -4951,11 +5035,258 @@ def __repr__(self): self._assert_is_copy(obj, objcopy2) +class SharedKeyTests(unittest.TestCase): + + @support.cpython_only + def test_subclasses(self): + # Verify that subclasses can share keys (per PEP 412) + class A: + pass + class B(A): + pass + + a, b = A(), B() + self.assertEqual(sys.getsizeof(vars(a)), sys.getsizeof(vars(b))) + self.assertLess(sys.getsizeof(vars(a)), sys.getsizeof({})) + a.x, a.y, a.z, a.w = range(4) + self.assertNotEqual(sys.getsizeof(vars(a)), sys.getsizeof(vars(b))) + a2 = A() + self.assertEqual(sys.getsizeof(vars(a)), sys.getsizeof(vars(a2))) + self.assertLess(sys.getsizeof(vars(a)), sys.getsizeof({})) + b.u, b.v, b.w, b.t = range(4) + self.assertLess(sys.getsizeof(vars(b)), sys.getsizeof({})) + + +class DebugHelperMeta(type): + """ + Sets default __doc__ and simplifies repr() output. + """ + def __new__(mcls, name, bases, attrs): + if attrs.get('__doc__') is None: + attrs['__doc__'] = name # helps when debugging with gdb + return type.__new__(mcls, name, bases, attrs) + def __repr__(cls): + return repr(cls.__name__) + + +class MroTest(unittest.TestCase): + """ + Regressions for some bugs revealed through + mcsl.mro() customization (typeobject.c: mro_internal()) and + cls.__bases__ assignment (typeobject.c: type_set_bases()). + """ + + def setUp(self): + self.step = 0 + self.ready = False + + def step_until(self, limit): + ret = (self.step < limit) + if ret: + self.step += 1 + return ret + + def test_incomplete_set_bases_on_self(self): + """ + type_set_bases must be aware that type->tp_mro can be NULL. + """ + class M(DebugHelperMeta): + def mro(cls): + if self.step_until(1): + assert cls.__mro__ is None + cls.__bases__ += () + + return type.mro(cls) + + class A(metaclass=M): + pass + + def test_reent_set_bases_on_base(self): + """ + Deep reentrancy must not over-decref old_mro. + """ + class M(DebugHelperMeta): + def mro(cls): + if cls.__mro__ is not None and cls.__name__ == 'B': + # 4-5 steps are usually enough to make it crash somewhere + if self.step_until(10): + A.__bases__ += () + + return type.mro(cls) + + class A(metaclass=M): + pass + class B(A): + pass + B.__bases__ += () + + def test_reent_set_bases_on_direct_base(self): + """ + Similar to test_reent_set_bases_on_base, but may crash differently. + """ + class M(DebugHelperMeta): + def mro(cls): + base = cls.__bases__[0] + if base is not object: + if self.step_until(5): + base.__bases__ += () + + return type.mro(cls) + + class A(metaclass=M): + pass + class B(A): + pass + class C(B): + pass + + def test_reent_set_bases_tp_base_cycle(self): + """ + type_set_bases must check for an inheritance cycle not only through + MRO of the type, which may be not yet updated in case of reentrance, + but also through tp_base chain, which is assigned before diving into + inner calls to mro(). + + Otherwise, the following snippet can loop forever: + do { + // ... + type = type->tp_base; + } while (type != NULL); + + Functions that rely on tp_base (like solid_base and PyType_IsSubtype) + would not be happy in that case, causing a stack overflow. + """ + class M(DebugHelperMeta): + def mro(cls): + if self.ready: + if cls.__name__ == 'B1': + B2.__bases__ = (B1,) + if cls.__name__ == 'B2': + B1.__bases__ = (B2,) + return type.mro(cls) + + class A(metaclass=M): + pass + class B1(A): + pass + class B2(A): + pass + + self.ready = True + with self.assertRaises(TypeError): + B1.__bases__ += () + + def test_tp_subclasses_cycle_in_update_slots(self): + """ + type_set_bases must check for reentrancy upon finishing its job + by updating tp_subclasses of old/new bases of the type. + Otherwise, an implicit inheritance cycle through tp_subclasses + can break functions that recurse on elements of that field + (like recurse_down_subclasses and mro_hierarchy) eventually + leading to a stack overflow. + """ + class M(DebugHelperMeta): + def mro(cls): + if self.ready and cls.__name__ == 'C': + self.ready = False + C.__bases__ = (B2,) + return type.mro(cls) + + class A(metaclass=M): + pass + class B1(A): + pass + class B2(A): + pass + class C(A): + pass + + self.ready = True + C.__bases__ = (B1,) + B1.__bases__ = (C,) + + self.assertEqual(C.__bases__, (B2,)) + self.assertEqual(B2.__subclasses__(), [C]) + self.assertEqual(B1.__subclasses__(), []) + + self.assertEqual(B1.__bases__, (C,)) + self.assertEqual(C.__subclasses__(), [B1]) + + def test_tp_subclasses_cycle_error_return_path(self): + """ + The same as test_tp_subclasses_cycle_in_update_slots, but tests + a code path executed on error (goto bail). + """ + class E(Exception): + pass + class M(DebugHelperMeta): + def mro(cls): + if self.ready and cls.__name__ == 'C': + if C.__bases__ == (B2,): + self.ready = False + else: + C.__bases__ = (B2,) + raise E + return type.mro(cls) + + class A(metaclass=M): + pass + class B1(A): + pass + class B2(A): + pass + class C(A): + pass + + self.ready = True + with self.assertRaises(E): + C.__bases__ = (B1,) + B1.__bases__ = (C,) + + self.assertEqual(C.__bases__, (B2,)) + self.assertEqual(C.__mro__, tuple(type.mro(C))) + + def test_incomplete_extend(self): + """ + Extending an unitialized type with type->tp_mro == NULL must + throw a reasonable TypeError exception, instead of failing + with PyErr_BadInternalCall. + """ + class M(DebugHelperMeta): + def mro(cls): + if cls.__mro__ is None and cls.__name__ != 'X': + with self.assertRaises(TypeError): + class X(cls): + pass + + return type.mro(cls) + + class A(metaclass=M): + pass + + def test_incomplete_super(self): + """ + Attrubute lookup on a super object must be aware that + its target type can be uninitialized (type->tp_mro == NULL). + """ + class M(DebugHelperMeta): + def mro(cls): + if cls.__mro__ is None: + with self.assertRaises(AttributeError): + super(cls, cls).xxx + + return type.mro(cls) + + class A(metaclass=M): + pass + + def test_main(): # Run all local test cases, with PTypesLongInitTest first. support.run_unittest(PTypesLongInitTest, OperatorsTest, ClassPropertiesAndMethods, DictProxyTests, - MiscTests, PicklingTests) + MiscTests, PicklingTests, SharedKeyTests, + MroTest) if __name__ == "__main__": test_main() diff --git a/Lib/test/test_devpoll.py b/Lib/test/test_devpoll.py index 40ebeee5975b..955618ae1557 100644 --- a/Lib/test/test_devpoll.py +++ b/Lib/test/test_devpoll.py @@ -7,12 +7,10 @@ import select import sys import unittest -from test.support import TESTFN, run_unittest +from test.support import TESTFN, run_unittest, cpython_only -try: - select.devpoll -except AttributeError: - raise unittest.SkipTest("select.devpoll not defined") +if not hasattr(select, 'devpoll') : + raise unittest.SkipTest('test works only on Solaris OS family') def find_ready_matching(ready, flag): @@ -120,6 +118,26 @@ def test_fd_non_inheritable(self): self.addCleanup(devpoll.close) self.assertEqual(os.get_inheritable(devpoll.fileno()), False) + def test_events_mask_overflow(self): + pollster = select.devpoll() + w, r = os.pipe() + pollster.register(w) + # Issue #17919 + self.assertRaises(OverflowError, pollster.register, 0, -1) + self.assertRaises(OverflowError, pollster.register, 0, 1 << 64) + self.assertRaises(OverflowError, pollster.modify, 1, -1) + self.assertRaises(OverflowError, pollster.modify, 1, 1 << 64) + + @cpython_only + def test_events_mask_overflow_c_limits(self): + from _testcapi import USHRT_MAX + pollster = select.devpoll() + w, r = os.pipe() + pollster.register(w) + # Issue #17919 + self.assertRaises(OverflowError, pollster.register, 0, USHRT_MAX + 1) + self.assertRaises(OverflowError, pollster.modify, 1, USHRT_MAX + 1) + def test_main(): run_unittest(DevPollTests) diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py index a38895945ed5..c96d0006edd4 100644 --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -837,57 +837,60 @@ class MyDict(dict): self._tracked(MyDict()) def test_iterator_pickling(self): - data = {1:"a", 2:"b", 3:"c"} - it = iter(data) - d = pickle.dumps(it) - it = pickle.loads(d) - self.assertEqual(sorted(it), sorted(data)) - - it = pickle.loads(d) - try: - drop = next(it) - except StopIteration: - return - d = pickle.dumps(it) - it = pickle.loads(d) - del data[drop] - self.assertEqual(sorted(it), sorted(data)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + data = {1:"a", 2:"b", 3:"c"} + it = iter(data) + d = pickle.dumps(it, proto) + it = pickle.loads(d) + self.assertEqual(sorted(it), sorted(data)) + + it = pickle.loads(d) + try: + drop = next(it) + except StopIteration: + continue + d = pickle.dumps(it, proto) + it = pickle.loads(d) + del data[drop] + self.assertEqual(sorted(it), sorted(data)) def test_itemiterator_pickling(self): - data = {1:"a", 2:"b", 3:"c"} - # dictviews aren't picklable, only their iterators - itorg = iter(data.items()) - d = pickle.dumps(itorg) - it = pickle.loads(d) - # note that the type of type of the unpickled iterator - # is not necessarily the same as the original. It is - # merely an object supporting the iterator protocol, yielding - # the same objects as the original one. - # self.assertEqual(type(itorg), type(it)) - self.assertTrue(isinstance(it, collections.abc.Iterator)) - self.assertEqual(dict(it), data) - - it = pickle.loads(d) - drop = next(it) - d = pickle.dumps(it) - it = pickle.loads(d) - del data[drop[0]] - self.assertEqual(dict(it), data) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + data = {1:"a", 2:"b", 3:"c"} + # dictviews aren't picklable, only their iterators + itorg = iter(data.items()) + d = pickle.dumps(itorg, proto) + it = pickle.loads(d) + # note that the type of type of the unpickled iterator + # is not necessarily the same as the original. It is + # merely an object supporting the iterator protocol, yielding + # the same objects as the original one. + # self.assertEqual(type(itorg), type(it)) + self.assertIsInstance(it, collections.abc.Iterator) + self.assertEqual(dict(it), data) + + it = pickle.loads(d) + drop = next(it) + d = pickle.dumps(it, proto) + it = pickle.loads(d) + del data[drop[0]] + self.assertEqual(dict(it), data) def test_valuesiterator_pickling(self): - data = {1:"a", 2:"b", 3:"c"} - # data.values() isn't picklable, only its iterator - it = iter(data.values()) - d = pickle.dumps(it) - it = pickle.loads(d) - self.assertEqual(sorted(list(it)), sorted(list(data.values()))) - - it = pickle.loads(d) - drop = next(it) - d = pickle.dumps(it) - it = pickle.loads(d) - values = list(it) + [drop] - self.assertEqual(sorted(values), sorted(list(data.values()))) + for proto in range(pickle.HIGHEST_PROTOCOL): + data = {1:"a", 2:"b", 3:"c"} + # data.values() isn't picklable, only its iterator + it = iter(data.values()) + d = pickle.dumps(it, proto) + it = pickle.loads(d) + self.assertEqual(sorted(list(it)), sorted(list(data.values()))) + + it = pickle.loads(d) + drop = next(it) + d = pickle.dumps(it, proto) + it = pickle.loads(d) + values = list(it) + [drop] + self.assertEqual(sorted(values), sorted(list(data.values()))) def test_instance_dict_getattr_str_subclass(self): class Foo: @@ -906,6 +909,35 @@ class Foo: pass f.a = 'a' self.assertEqual(f.__dict__, {1:1, 'a':'a'}) + def check_reentrant_insertion(self, mutate): + # This object will trigger mutation of the dict when replaced + # by another value. Note this relies on refcounting: the test + # won't achieve its purpose on fully-GCed Python implementations. + class Mutating: + def __del__(self): + mutate(d) + + d = {k: Mutating() for k in 'abcdefghijklmnopqr'} + for k in list(d): + d[k] = k + + def test_reentrant_insertion(self): + # Reentrant insertion shouldn't crash (see issue #22653) + def mutate(d): + d['b'] = 5 + self.check_reentrant_insertion(mutate) + + def mutate(d): + d.update(self.__dict__) + d.clear() + self.check_reentrant_insertion(mutate) + + def mutate(d): + while d: + d.popitem() + self.check_reentrant_insertion(mutate) + + from test import mapping_tests class GeneralMappingTests(mapping_tests.BasicTestMappingProtocol): diff --git a/Lib/test/test_difflib.py b/Lib/test/test_difflib.py index 325449aa557c..0ba8f0e05bcf 100644 --- a/Lib/test/test_difflib.py +++ b/Lib/test/test_difflib.py @@ -76,6 +76,15 @@ def test_comparing_empty_lists(self): diff_gen = difflib.unified_diff([], []) self.assertRaises(StopIteration, next, diff_gen) + def test_matching_blocks_cache(self): + # Issue #21635 + s = difflib.SequenceMatcher(None, "abxcd", "abcd") + first = s.get_matching_blocks() + second = s.get_matching_blocks() + self.assertEqual(second[0].size, 2) + self.assertEqual(second[1].size, 2) + self.assertEqual(second[2].size, 0) + def test_added_tab_hint(self): # Check fix for bug #1488943 diff = list(difflib.Differ().compare(["\tI am a buggy"],["\t\tI am a bug"])) diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index 94d6be735c4e..4f30183ac067 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -7,6 +7,7 @@ import sys import dis import io +import re import types import contextlib @@ -106,27 +107,26 @@ def bug1333982(x=[]): pass dis_bug1333982 = """\ - %-4d 0 LOAD_CONST 1 (0) - 3 JUMP_IF_TRUE 33 (to 39) - 6 POP_TOP - 7 LOAD_GLOBAL 0 (AssertionError) - 10 BUILD_LIST 0 - 13 LOAD_FAST 0 (x) - 16 GET_ITER - >> 17 FOR_ITER 12 (to 32) - 20 STORE_FAST 1 (s) - 23 LOAD_FAST 1 (s) - 26 LIST_APPEND 2 - 29 JUMP_ABSOLUTE 17 - - %-4d >> 32 LOAD_CONST 2 (1) - 35 BINARY_ADD - 36 RAISE_VARARGS 2 - >> 39 POP_TOP - - %-4d 40 LOAD_CONST 0 (None) - 43 RETURN_VALUE +%3d 0 LOAD_CONST 1 (0) + 3 POP_JUMP_IF_TRUE 35 + 6 LOAD_GLOBAL 0 (AssertionError) + 9 LOAD_CONST 2 ( at 0x..., file "%s", line %d>) + 12 LOAD_CONST 3 ('bug1333982..') + 15 MAKE_FUNCTION 0 + 18 LOAD_FAST 0 (x) + 21 GET_ITER + 22 CALL_FUNCTION 1 (1 positional, 0 keyword pair) + +%3d 25 LOAD_CONST 4 (1) + 28 BINARY_ADD + 29 CALL_FUNCTION 1 (1 positional, 0 keyword pair) + 32 RAISE_VARARGS 1 + +%3d >> 35 LOAD_CONST 0 (None) + 38 RETURN_VALUE """ % (bug1333982.__code__.co_firstlineno + 1, + __file__, + bug1333982.__code__.co_firstlineno + 1, bug1333982.__code__.co_firstlineno + 2, bug1333982.__code__.co_firstlineno + 3) @@ -178,15 +178,16 @@ def bug1333982(x=[]): 1 0 LOAD_CONST 0 (0) 3 STORE_NAME 0 (x) - 2 6 SETUP_LOOP 13 (to 22) + 2 6 SETUP_LOOP 14 (to 23) 3 >> 9 LOAD_NAME 0 (x) 12 LOAD_CONST 1 (1) 15 INPLACE_ADD 16 STORE_NAME 0 (x) 19 JUMP_ABSOLUTE 9 - >> 22 LOAD_CONST 2 (None) - 25 RETURN_VALUE + 22 POP_BLOCK + >> 23 LOAD_CONST 2 (None) + 26 RETURN_VALUE """ dis_traceback = """\ @@ -229,6 +230,9 @@ def bug1333982(x=[]): TRACEBACK_CODE.co_firstlineno + 4, TRACEBACK_CODE.co_firstlineno + 5) +def _g(x): + yield x + class DisTests(unittest.TestCase): def get_disassembly(self, func, lasti=-1, wrapper=True): @@ -244,8 +248,14 @@ def get_disassembly(self, func, lasti=-1, wrapper=True): def get_disassemble_as_string(self, func, lasti=-1): return self.get_disassembly(func, lasti, False) + def strip_addresses(self, text): + return re.sub(r'\b0x[0-9A-Fa-f]+\b', '0x...', text) + def do_disassembly_test(self, func, expected): - self.assertEqual(self.get_disassembly(func), expected) + got = self.get_disassembly(func) + if got != expected: + got = self.strip_addresses(got) + self.assertEqual(got, expected) def test_opmap(self): self.assertEqual(dis.opmap["NOP"], 9) @@ -266,15 +276,12 @@ def test_bug_708901(self): self.do_disassembly_test(bug708901, dis_bug708901) def test_bug_1333982(self): - # XXX: re-enable this test! # This one is checking bytecodes generated for an `assert` statement, # so fails if the tests are run with -O. Skip this test then. - pass # Test has been disabled due to change in the way - # list comps are handled. The byte code now includes - # a memory address and a file location, so they change from - # run to run. - # if __debug__: - # self.do_disassembly_test(bug1333982, dis_bug1333982) + if not __debug__: + self.skipTest('need asserts, run without -O') + + self.do_disassembly_test(bug1333982, dis_bug1333982) def test_big_linenos(self): def func(count): @@ -311,6 +318,11 @@ def test_disassemble_method_bytes(self): method_bytecode = _C(1).__init__.__code__.co_code self.do_disassembly_test(method_bytecode, dis_c_instance_method_bytes) + def test_disassemble_generator(self): + gen_func_disas = self.get_disassembly(_g) # Disassemble generator function + gen_disas = self.get_disassembly(_g(1)) # Disassemble generator itself + self.assertEqual(gen_disas, gen_func_disas) + def test_dis_none(self): try: del sys.last_traceback @@ -557,10 +569,10 @@ def jumpy(): #_instructions = dis.get_instructions(outer, first_line=expected_outer_line) #print('expected_opinfo_outer = [\n ', #',\n '.join(map(str, _instructions)), ',\n]', sep='') -#_instructions = dis.get_instructions(outer(), first_line=expected_outer_line) +#_instructions = dis.get_instructions(outer(), first_line=expected_f_line) #print('expected_opinfo_f = [\n ', #',\n '.join(map(str, _instructions)), ',\n]', sep='') -#_instructions = dis.get_instructions(outer()(), first_line=expected_outer_line) +#_instructions = dis.get_instructions(outer()(), first_line=expected_inner_line) #print('expected_opinfo_inner = [\n ', #',\n '.join(map(str, _instructions)), ',\n]', sep='') #_instructions = dis.get_instructions(jumpy, first_line=expected_jumpy_line) @@ -631,12 +643,12 @@ def jumpy(): ] expected_opinfo_jumpy = [ - Instruction(opname='SETUP_LOOP', opcode=120, arg=74, argval=77, argrepr='to 77', offset=0, starts_line=3, is_jump_target=False), + Instruction(opname='SETUP_LOOP', opcode=120, arg=68, argval=71, argrepr='to 71', offset=0, starts_line=3, is_jump_target=False), Instruction(opname='LOAD_GLOBAL', opcode=116, arg=0, argval='range', argrepr='range', offset=3, starts_line=None, is_jump_target=False), Instruction(opname='LOAD_CONST', opcode=100, arg=1, argval=10, argrepr='10', offset=6, starts_line=None, is_jump_target=False), Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='1 positional, 0 keyword pair', offset=9, starts_line=None, is_jump_target=False), Instruction(opname='GET_ITER', opcode=68, arg=None, argval=None, argrepr='', offset=12, starts_line=None, is_jump_target=False), - Instruction(opname='FOR_ITER', opcode=93, arg=50, argval=66, argrepr='to 66', offset=13, starts_line=None, is_jump_target=True), + Instruction(opname='FOR_ITER', opcode=93, arg=44, argval=60, argrepr='to 60', offset=13, starts_line=None, is_jump_target=True), Instruction(opname='STORE_FAST', opcode=125, arg=0, argval='i', argrepr='i', offset=16, starts_line=None, is_jump_target=False), Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=19, starts_line=4, is_jump_target=False), Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=22, starts_line=None, is_jump_target=False), @@ -645,92 +657,88 @@ def jumpy(): Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=29, starts_line=5, is_jump_target=False), Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=32, starts_line=None, is_jump_target=False), Instruction(opname='COMPARE_OP', opcode=107, arg=0, argval='<', argrepr='<', offset=35, starts_line=None, is_jump_target=False), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=47, argval=47, argrepr='', offset=38, starts_line=None, is_jump_target=False), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=44, argval=44, argrepr='', offset=38, starts_line=None, is_jump_target=False), Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=13, argval=13, argrepr='', offset=41, starts_line=6, is_jump_target=False), - Instruction(opname='JUMP_FORWARD', opcode=110, arg=0, argval=47, argrepr='to 47', offset=44, starts_line=None, is_jump_target=False), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=47, starts_line=7, is_jump_target=True), - Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=50, starts_line=None, is_jump_target=False), - Instruction(opname='COMPARE_OP', opcode=107, arg=4, argval='>', argrepr='>', offset=53, starts_line=None, is_jump_target=False), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=13, argval=13, argrepr='', offset=56, starts_line=None, is_jump_target=False), - Instruction(opname='BREAK_LOOP', opcode=80, arg=None, argval=None, argrepr='', offset=59, starts_line=8, is_jump_target=False), - Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=13, argval=13, argrepr='', offset=60, starts_line=None, is_jump_target=False), - Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=13, argval=13, argrepr='', offset=63, starts_line=None, is_jump_target=False), - Instruction(opname='POP_BLOCK', opcode=87, arg=None, argval=None, argrepr='', offset=66, starts_line=None, is_jump_target=True), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=67, starts_line=10, is_jump_target=False), - Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=70, starts_line=None, is_jump_target=False), - Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='1 positional, 0 keyword pair', offset=73, starts_line=None, is_jump_target=False), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=76, starts_line=None, is_jump_target=False), - Instruction(opname='SETUP_LOOP', opcode=120, arg=74, argval=154, argrepr='to 154', offset=77, starts_line=11, is_jump_target=True), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=80, starts_line=None, is_jump_target=True), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=143, argval=143, argrepr='', offset=83, starts_line=None, is_jump_target=False), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=86, starts_line=12, is_jump_target=False), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=89, starts_line=None, is_jump_target=False), - Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='1 positional, 0 keyword pair', offset=92, starts_line=None, is_jump_target=False), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=95, starts_line=None, is_jump_target=False), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=96, starts_line=13, is_jump_target=False), - Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=99, starts_line=None, is_jump_target=False), - Instruction(opname='INPLACE_SUBTRACT', opcode=56, arg=None, argval=None, argrepr='', offset=102, starts_line=None, is_jump_target=False), - Instruction(opname='STORE_FAST', opcode=125, arg=0, argval='i', argrepr='i', offset=103, starts_line=None, is_jump_target=False), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=106, starts_line=14, is_jump_target=False), - Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=109, starts_line=None, is_jump_target=False), - Instruction(opname='COMPARE_OP', opcode=107, arg=4, argval='>', argrepr='>', offset=112, starts_line=None, is_jump_target=False), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=124, argval=124, argrepr='', offset=115, starts_line=None, is_jump_target=False), - Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=80, argval=80, argrepr='', offset=118, starts_line=15, is_jump_target=False), - Instruction(opname='JUMP_FORWARD', opcode=110, arg=0, argval=124, argrepr='to 124', offset=121, starts_line=None, is_jump_target=False), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=124, starts_line=16, is_jump_target=True), - Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=127, starts_line=None, is_jump_target=False), - Instruction(opname='COMPARE_OP', opcode=107, arg=0, argval='<', argrepr='<', offset=130, starts_line=None, is_jump_target=False), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=80, argval=80, argrepr='', offset=133, starts_line=None, is_jump_target=False), - Instruction(opname='BREAK_LOOP', opcode=80, arg=None, argval=None, argrepr='', offset=136, starts_line=17, is_jump_target=False), - Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=80, argval=80, argrepr='', offset=137, starts_line=None, is_jump_target=False), - Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=80, argval=80, argrepr='', offset=140, starts_line=None, is_jump_target=False), - Instruction(opname='POP_BLOCK', opcode=87, arg=None, argval=None, argrepr='', offset=143, starts_line=None, is_jump_target=True), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=144, starts_line=19, is_jump_target=False), - Instruction(opname='LOAD_CONST', opcode=100, arg=6, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=147, starts_line=None, is_jump_target=False), - Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='1 positional, 0 keyword pair', offset=150, starts_line=None, is_jump_target=False), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=153, starts_line=None, is_jump_target=False), - Instruction(opname='SETUP_FINALLY', opcode=122, arg=72, argval=229, argrepr='to 229', offset=154, starts_line=20, is_jump_target=True), - Instruction(opname='SETUP_EXCEPT', opcode=121, arg=12, argval=172, argrepr='to 172', offset=157, starts_line=None, is_jump_target=False), - Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=160, starts_line=21, is_jump_target=False), - Instruction(opname='LOAD_CONST', opcode=100, arg=7, argval=0, argrepr='0', offset=163, starts_line=None, is_jump_target=False), - Instruction(opname='BINARY_TRUE_DIVIDE', opcode=27, arg=None, argval=None, argrepr='', offset=166, starts_line=None, is_jump_target=False), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=167, starts_line=None, is_jump_target=False), - Instruction(opname='POP_BLOCK', opcode=87, arg=None, argval=None, argrepr='', offset=168, starts_line=None, is_jump_target=False), - Instruction(opname='JUMP_FORWARD', opcode=110, arg=28, argval=200, argrepr='to 200', offset=169, starts_line=None, is_jump_target=False), - Instruction(opname='DUP_TOP', opcode=4, arg=None, argval=None, argrepr='', offset=172, starts_line=22, is_jump_target=True), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=2, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=173, starts_line=None, is_jump_target=False), - Instruction(opname='COMPARE_OP', opcode=107, arg=10, argval='exception match', argrepr='exception match', offset=176, starts_line=None, is_jump_target=False), - Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=199, argval=199, argrepr='', offset=179, starts_line=None, is_jump_target=False), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=44, starts_line=7, is_jump_target=True), + Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=47, starts_line=None, is_jump_target=False), + Instruction(opname='COMPARE_OP', opcode=107, arg=4, argval='>', argrepr='>', offset=50, starts_line=None, is_jump_target=False), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=13, argval=13, argrepr='', offset=53, starts_line=None, is_jump_target=False), + Instruction(opname='BREAK_LOOP', opcode=80, arg=None, argval=None, argrepr='', offset=56, starts_line=8, is_jump_target=False), + Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=13, argval=13, argrepr='', offset=57, starts_line=None, is_jump_target=False), + Instruction(opname='POP_BLOCK', opcode=87, arg=None, argval=None, argrepr='', offset=60, starts_line=None, is_jump_target=True), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=61, starts_line=10, is_jump_target=False), + Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=64, starts_line=None, is_jump_target=False), + Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='1 positional, 0 keyword pair', offset=67, starts_line=None, is_jump_target=False), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=70, starts_line=None, is_jump_target=False), + Instruction(opname='SETUP_LOOP', opcode=120, arg=68, argval=142, argrepr='to 142', offset=71, starts_line=11, is_jump_target=True), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=74, starts_line=None, is_jump_target=True), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=131, argval=131, argrepr='', offset=77, starts_line=None, is_jump_target=False), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=80, starts_line=12, is_jump_target=False), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=83, starts_line=None, is_jump_target=False), + Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='1 positional, 0 keyword pair', offset=86, starts_line=None, is_jump_target=False), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=89, starts_line=None, is_jump_target=False), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=90, starts_line=13, is_jump_target=False), + Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=93, starts_line=None, is_jump_target=False), + Instruction(opname='INPLACE_SUBTRACT', opcode=56, arg=None, argval=None, argrepr='', offset=96, starts_line=None, is_jump_target=False), + Instruction(opname='STORE_FAST', opcode=125, arg=0, argval='i', argrepr='i', offset=97, starts_line=None, is_jump_target=False), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=100, starts_line=14, is_jump_target=False), + Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=103, starts_line=None, is_jump_target=False), + Instruction(opname='COMPARE_OP', opcode=107, arg=4, argval='>', argrepr='>', offset=106, starts_line=None, is_jump_target=False), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=115, argval=115, argrepr='', offset=109, starts_line=None, is_jump_target=False), + Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=74, argval=74, argrepr='', offset=112, starts_line=15, is_jump_target=False), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=115, starts_line=16, is_jump_target=True), + Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=118, starts_line=None, is_jump_target=False), + Instruction(opname='COMPARE_OP', opcode=107, arg=0, argval='<', argrepr='<', offset=121, starts_line=None, is_jump_target=False), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=74, argval=74, argrepr='', offset=124, starts_line=None, is_jump_target=False), + Instruction(opname='BREAK_LOOP', opcode=80, arg=None, argval=None, argrepr='', offset=127, starts_line=17, is_jump_target=False), + Instruction(opname='JUMP_ABSOLUTE', opcode=113, arg=74, argval=74, argrepr='', offset=128, starts_line=None, is_jump_target=False), + Instruction(opname='POP_BLOCK', opcode=87, arg=None, argval=None, argrepr='', offset=131, starts_line=None, is_jump_target=True), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=132, starts_line=19, is_jump_target=False), + Instruction(opname='LOAD_CONST', opcode=100, arg=6, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=135, starts_line=None, is_jump_target=False), + Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='1 positional, 0 keyword pair', offset=138, starts_line=None, is_jump_target=False), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=141, starts_line=None, is_jump_target=False), + Instruction(opname='SETUP_FINALLY', opcode=122, arg=72, argval=217, argrepr='to 217', offset=142, starts_line=20, is_jump_target=True), + Instruction(opname='SETUP_EXCEPT', opcode=121, arg=12, argval=160, argrepr='to 160', offset=145, starts_line=None, is_jump_target=False), + Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=148, starts_line=21, is_jump_target=False), + Instruction(opname='LOAD_CONST', opcode=100, arg=7, argval=0, argrepr='0', offset=151, starts_line=None, is_jump_target=False), + Instruction(opname='BINARY_TRUE_DIVIDE', opcode=27, arg=None, argval=None, argrepr='', offset=154, starts_line=None, is_jump_target=False), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=155, starts_line=None, is_jump_target=False), + Instruction(opname='POP_BLOCK', opcode=87, arg=None, argval=None, argrepr='', offset=156, starts_line=None, is_jump_target=False), + Instruction(opname='JUMP_FORWARD', opcode=110, arg=28, argval=188, argrepr='to 188', offset=157, starts_line=None, is_jump_target=False), + Instruction(opname='DUP_TOP', opcode=4, arg=None, argval=None, argrepr='', offset=160, starts_line=22, is_jump_target=True), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=2, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=161, starts_line=None, is_jump_target=False), + Instruction(opname='COMPARE_OP', opcode=107, arg=10, argval='exception match', argrepr='exception match', offset=164, starts_line=None, is_jump_target=False), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=187, argval=187, argrepr='', offset=167, starts_line=None, is_jump_target=False), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=170, starts_line=None, is_jump_target=False), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=171, starts_line=None, is_jump_target=False), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=172, starts_line=None, is_jump_target=False), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=173, starts_line=23, is_jump_target=False), + Instruction(opname='LOAD_CONST', opcode=100, arg=8, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=176, starts_line=None, is_jump_target=False), + Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='1 positional, 0 keyword pair', offset=179, starts_line=None, is_jump_target=False), Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=182, starts_line=None, is_jump_target=False), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=183, starts_line=None, is_jump_target=False), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=184, starts_line=None, is_jump_target=False), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=185, starts_line=23, is_jump_target=False), - Instruction(opname='LOAD_CONST', opcode=100, arg=8, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=188, starts_line=None, is_jump_target=False), - Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='1 positional, 0 keyword pair', offset=191, starts_line=None, is_jump_target=False), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=194, starts_line=None, is_jump_target=False), - Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=195, starts_line=None, is_jump_target=False), - Instruction(opname='JUMP_FORWARD', opcode=110, arg=26, argval=225, argrepr='to 225', offset=196, starts_line=None, is_jump_target=False), - Instruction(opname='END_FINALLY', opcode=88, arg=None, argval=None, argrepr='', offset=199, starts_line=None, is_jump_target=True), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=200, starts_line=25, is_jump_target=True), - Instruction(opname='SETUP_WITH', opcode=143, arg=17, argval=223, argrepr='to 223', offset=203, starts_line=None, is_jump_target=False), - Instruction(opname='STORE_FAST', opcode=125, arg=1, argval='dodgy', argrepr='dodgy', offset=206, starts_line=None, is_jump_target=False), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=209, starts_line=26, is_jump_target=False), - Instruction(opname='LOAD_CONST', opcode=100, arg=9, argval='Never reach this', argrepr="'Never reach this'", offset=212, starts_line=None, is_jump_target=False), - Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='1 positional, 0 keyword pair', offset=215, starts_line=None, is_jump_target=False), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=218, starts_line=None, is_jump_target=False), - Instruction(opname='POP_BLOCK', opcode=87, arg=None, argval=None, argrepr='', offset=219, starts_line=None, is_jump_target=False), - Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=220, starts_line=None, is_jump_target=False), - Instruction(opname='WITH_CLEANUP', opcode=81, arg=None, argval=None, argrepr='', offset=223, starts_line=None, is_jump_target=True), - Instruction(opname='END_FINALLY', opcode=88, arg=None, argval=None, argrepr='', offset=224, starts_line=None, is_jump_target=False), - Instruction(opname='POP_BLOCK', opcode=87, arg=None, argval=None, argrepr='', offset=225, starts_line=None, is_jump_target=True), - Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=226, starts_line=None, is_jump_target=False), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=229, starts_line=28, is_jump_target=True), - Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=232, starts_line=None, is_jump_target=False), - Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='1 positional, 0 keyword pair', offset=235, starts_line=None, is_jump_target=False), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=238, starts_line=None, is_jump_target=False), - Instruction(opname='END_FINALLY', opcode=88, arg=None, argval=None, argrepr='', offset=239, starts_line=None, is_jump_target=False), - Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=240, starts_line=None, is_jump_target=False), - Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=243, starts_line=None, is_jump_target=False), + Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=183, starts_line=None, is_jump_target=False), + Instruction(opname='JUMP_FORWARD', opcode=110, arg=26, argval=213, argrepr='to 213', offset=184, starts_line=None, is_jump_target=False), + Instruction(opname='END_FINALLY', opcode=88, arg=None, argval=None, argrepr='', offset=187, starts_line=None, is_jump_target=True), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=188, starts_line=25, is_jump_target=True), + Instruction(opname='SETUP_WITH', opcode=143, arg=17, argval=211, argrepr='to 211', offset=191, starts_line=None, is_jump_target=False), + Instruction(opname='STORE_FAST', opcode=125, arg=1, argval='dodgy', argrepr='dodgy', offset=194, starts_line=None, is_jump_target=False), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=197, starts_line=26, is_jump_target=False), + Instruction(opname='LOAD_CONST', opcode=100, arg=9, argval='Never reach this', argrepr="'Never reach this'", offset=200, starts_line=None, is_jump_target=False), + Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='1 positional, 0 keyword pair', offset=203, starts_line=None, is_jump_target=False), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=206, starts_line=None, is_jump_target=False), + Instruction(opname='POP_BLOCK', opcode=87, arg=None, argval=None, argrepr='', offset=207, starts_line=None, is_jump_target=False), + Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=208, starts_line=None, is_jump_target=False), + Instruction(opname='WITH_CLEANUP', opcode=81, arg=None, argval=None, argrepr='', offset=211, starts_line=None, is_jump_target=True), + Instruction(opname='END_FINALLY', opcode=88, arg=None, argval=None, argrepr='', offset=212, starts_line=None, is_jump_target=False), + Instruction(opname='POP_BLOCK', opcode=87, arg=None, argval=None, argrepr='', offset=213, starts_line=None, is_jump_target=True), + Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=214, starts_line=None, is_jump_target=False), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=217, starts_line=28, is_jump_target=True), + Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=220, starts_line=None, is_jump_target=False), + Instruction(opname='CALL_FUNCTION', opcode=131, arg=1, argval=1, argrepr='1 positional, 0 keyword pair', offset=223, starts_line=None, is_jump_target=False), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=226, starts_line=None, is_jump_target=False), + Instruction(opname='END_FINALLY', opcode=88, arg=None, argval=None, argrepr='', offset=227, starts_line=None, is_jump_target=False), + Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=228, starts_line=None, is_jump_target=False), + Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=231, starts_line=None, is_jump_target=False), ] # One last piece of inspect fodder to check the default line number handling @@ -825,9 +833,5 @@ def test_from_traceback_dis(self): b = dis.Bytecode.from_traceback(tb) self.assertEqual(b.dis(), dis_traceback) -def test_main(): - run_unittest(DisTests, DisWithFileTests, CodeInfoTests, - InstructionTests, BytecodeTests) - if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_doctest.py b/Lib/test/test_doctest.py index 5b53ca8e02fd..95700a3d3f1a 100644 --- a/Lib/test/test_doctest.py +++ b/Lib/test/test_doctest.py @@ -4,6 +4,7 @@ from test import support import doctest +import functools import os import sys @@ -434,7 +435,7 @@ def basics(): r""" >>> tests = finder.find(sample_func) >>> print(tests) # doctest: +ELLIPSIS - [] + [] The exact name depends on how test_doctest was invoked, so allow for leading path components. @@ -1054,6 +1055,33 @@ def exceptions(): r""" ValueError: message TestResults(failed=1, attempted=1) +If the exception does not have a message, you can still use +IGNORE_EXCEPTION_DETAIL to normalize the modules between Python 2 and 3: + + >>> def f(x): + ... r''' + ... >>> from http.client import HTTPException + ... >>> raise HTTPException() #doctest: +IGNORE_EXCEPTION_DETAIL + ... Traceback (most recent call last): + ... foo.bar.HTTPException + ... ''' + >>> test = doctest.DocTestFinder().find(f)[0] + >>> doctest.DocTestRunner(verbose=False).run(test) + TestResults(failed=0, attempted=2) + +Note that a trailing colon doesn't matter either: + + >>> def f(x): + ... r''' + ... >>> from http.client import HTTPException + ... >>> raise HTTPException() #doctest: +IGNORE_EXCEPTION_DETAIL + ... Traceback (most recent call last): + ... foo.bar.HTTPException: + ... ''' + >>> test = doctest.DocTestFinder().find(f)[0] + >>> doctest.DocTestRunner(verbose=False).run(test) + TestResults(failed=0, attempted=2) + If an exception is raised but not expected, then it is reported as an unexpected exception: @@ -2069,22 +2097,9 @@ def test_DocTestSuite(): >>> suite.run(unittest.TestResult()) - However, if DocTestSuite finds no docstrings, it raises an error: - - >>> try: - ... doctest.DocTestSuite('test.sample_doctest_no_docstrings') - ... except ValueError as e: - ... error = e - - >>> print(error.args[1]) - has no docstrings - - You can prevent this error by passing a DocTestFinder instance with - the `exclude_empty` keyword argument set to False: + The module need not contain any docstrings either: - >>> finder = doctest.DocTestFinder(exclude_empty=False) - >>> suite = doctest.DocTestSuite('test.sample_doctest_no_docstrings', - ... test_finder=finder) + >>> suite = doctest.DocTestSuite('test.sample_doctest_no_docstrings') >>> suite.run(unittest.TestResult()) @@ -2094,6 +2109,22 @@ def test_DocTestSuite(): >>> suite.run(unittest.TestResult()) + We can also provide a DocTestFinder: + + >>> finder = doctest.DocTestFinder() + >>> suite = doctest.DocTestSuite('test.sample_doctest', + ... test_finder=finder) + >>> suite.run(unittest.TestResult()) + + + The DocTestFinder need not return any tests: + + >>> finder = doctest.DocTestFinder() + >>> suite = doctest.DocTestSuite('test.sample_doctest_no_docstrings', + ... test_finder=finder) + >>> suite.run(unittest.TestResult()) + + We can supply global variables. If we pass globs, they will be used instead of the module globals. Here we'll pass an empty globals, triggering an extra error: @@ -2141,7 +2172,7 @@ def test_DocTestSuite(): >>> test.test_doctest.sillySetup Traceback (most recent call last): ... - AttributeError: 'module' object has no attribute 'sillySetup' + AttributeError: module 'test.test_doctest' has no attribute 'sillySetup' The setUp and tearDown funtions are passed test objects. Here we'll use the setUp function to supply the missing variable y: @@ -2287,7 +2318,7 @@ def test_DocFileSuite(): >>> test.test_doctest.sillySetup Traceback (most recent call last): ... - AttributeError: 'module' object has no attribute 'sillySetup' + AttributeError: module 'test.test_doctest' has no attribute 'sillySetup' The setUp and tearDown funtions are passed test objects. Here, we'll use a setUp function to set the favorite color in @@ -2334,6 +2365,22 @@ def test_trailing_space_in_test(): foo \n """ +class Wrapper: + def __init__(self, func): + self.func = func + functools.update_wrapper(self, func) + + def __call__(self, *args, **kwargs): + self.func(*args, **kwargs) + +@Wrapper +def test_look_in_unwrapped(): + """ + Docstrings in wrapped functions must be detected as well. + + >>> 'one other test' + 'one other test' + """ def test_unittest_reportflags(): """Default unittest reporting flags can be set to control reporting @@ -2586,6 +2633,36 @@ def test_testfile(): r""" >>> sys.argv = save_argv """ +def test_lineendings(): r""" +*nix systems use \n line endings, while Windows systems use \r\n. Python +handles this using universal newline mode for reading files. Let's make +sure doctest does so (issue 8473) by creating temporary test files using each +of the two line disciplines. One of the two will be the "wrong" one for the +platform the test is run on. + +Windows line endings first: + + >>> import tempfile, os + >>> fn = tempfile.mktemp() + >>> with open(fn, 'w') as f: + ... f.write('Test:\r\n\r\n >>> x = 1 + 1\r\n\r\nDone.\r\n') + 35 + >>> doctest.testfile(fn, False) + TestResults(failed=0, attempted=1) + >>> os.remove(fn) + +And now *nix line endings: + + >>> fn = tempfile.mktemp() + >>> with open(fn, 'w') as f: + ... f.write('Test:\n\n >>> x = 1 + 1\n\nDone.\n') + 30 + >>> doctest.testfile(fn, False) + TestResults(failed=0, attempted=1) + >>> os.remove(fn) + +""" + def test_testmod(): r""" Tests for the testmod function. More might be useful, but for now we're just testing the case raised by Issue 6195, where trying to doctest a C module would @@ -2870,7 +2947,7 @@ def test_CLI(): r""" def test_main(): # Check the doctest cases in doctest itself: - support.run_doctest(doctest, verbosity=True) + ret = support.run_doctest(doctest, verbosity=True) # Check the doctest cases defined here: from test import test_doctest support.run_doctest(test_doctest, verbosity=True) diff --git a/Lib/test/test_docxmlrpc.py b/Lib/test/test_docxmlrpc.py index 7086d9a6a122..d9fd9170bbab 100644 --- a/Lib/test/test_docxmlrpc.py +++ b/Lib/test/test_docxmlrpc.py @@ -10,7 +10,7 @@ PORT = None def make_request_and_skipIf(condition, reason): - # If we skip the test, we have to make a request because the + # If we skip the test, we have to make a request because # the server created in setUp blocks expecting one to come in. if not condition: return lambda func: func @@ -87,10 +87,11 @@ def setUp(self): threading.Thread(target=server, args=(self.evt, 1)).start() # wait for port to be assigned - n = 1000 - while n > 0 and PORT is None: - time.sleep(0.001) - n -= 1 + deadline = time.monotonic() + 10.0 + while PORT is None: + time.sleep(0.010) + if time.monotonic() > deadline: + break self.client = http.client.HTTPConnection("localhost:%d" % PORT) @@ -202,10 +203,12 @@ def test_annotations(self): """ Test that annotations works as expected """ self.client.request("GET", "/") response = self.client.getresponse() + docstring = (b'' if sys.flags.optimize >= 2 else + b'
Use function annotations.
') self.assertIn( (b'
annotation' - b'(x: int)
Use function annotations.' - b'
\n
' + b'(x: int)
' + docstring + b'
\n' + b'
' b'method_annotation(x: bytes)
'), response.read()) diff --git a/Lib/test/test_eintr.py b/Lib/test/test_eintr.py new file mode 100644 index 000000000000..8b5f5070e66d --- /dev/null +++ b/Lib/test/test_eintr.py @@ -0,0 +1,20 @@ +import os +import signal +import unittest + +from test import script_helper, support + + +@unittest.skipUnless(os.name == "posix", "only supported on Unix") +class EINTRTests(unittest.TestCase): + + @unittest.skipUnless(hasattr(signal, "setitimer"), "requires setitimer()") + def test_all(self): + # Run the tester in a sub-process, to make sure there is only one + # thread (for reliable signal delivery). + tester = support.findfile("eintr_tester.py", subdir="eintrdata") + script_helper.assert_python_ok(tester) + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_email/__init__.py b/Lib/test/test_email/__init__.py index d8896eed46f5..a59775c4ff59 100644 --- a/Lib/test/test_email/__init__.py +++ b/Lib/test/test_email/__init__.py @@ -1,31 +1,16 @@ import os import sys import unittest -import test.support import collections import email from email.message import Message from email._policybase import compat32 +from test.support import load_package_tests from test.test_email import __file__ as landmark -# Run all tests in package for '-m unittest test.test_email' -def load_tests(loader, standard_tests, pattern): - this_dir = os.path.dirname(__file__) - if pattern is None: - pattern = "test*" - package_tests = loader.discover(start_dir=this_dir, pattern=pattern) - standard_tests.addTests(package_tests) - return standard_tests - - -# used by regrtest and __main__. -def test_main(): - here = os.path.dirname(__file__) - # Unittest mucks with the path, so we have to save and restore - # it to keep regrtest happy. - savepath = sys.path[:] - test.support._run_suite(unittest.defaultTestLoader.discover(here)) - sys.path[:] = savepath +# Load all tests in package +def load_tests(*args): + return load_package_tests(os.path.dirname(__file__), *args) # helper code used by a number of test modules. diff --git a/Lib/test/test_email/__main__.py b/Lib/test/test_email/__main__.py index 98af9ecbad3f..4b14f773db42 100644 --- a/Lib/test/test_email/__main__.py +++ b/Lib/test/test_email/__main__.py @@ -1,3 +1,4 @@ -from test.test_email import test_main +from test.test_email import load_tests +import unittest -test_main() +unittest.main() diff --git a/Lib/test/test_email/data/msg_02.txt b/Lib/test/test_email/data/msg_02.txt index 43f248038a8e..5d0a7e16c825 100644 --- a/Lib/test/test_email/data/msg_02.txt +++ b/Lib/test/test_email/data/msg_02.txt @@ -119,6 +119,7 @@ hello --__--__---- + --192.168.1.2.889.32614.987812255.500.21814 Content-type: text/plain; charset=us-ascii Content-description: Digest Footer diff --git a/Lib/test/test_email/data/msg_06.txt b/Lib/test/test_email/data/msg_06.txt index 69f3a47ff429..f51ac96114bd 100644 --- a/Lib/test/test_email/data/msg_06.txt +++ b/Lib/test/test_email/data/msg_06.txt @@ -5,7 +5,7 @@ Content-Type: message/rfc822 Content-Description: forwarded message Content-Transfer-Encoding: 7bit Message-ID: <15265.9482.641338.555352@python.org> -From: barry@zope.com (Barry A. Warsaw) +From: barry@python.org (Barry A. Warsaw) Sender: barry@python.org To: barry@python.org Subject: forwarded message from Barry A. Warsaw @@ -20,7 +20,7 @@ Content-Type: text/plain; charset=us-ascii Return-Path: Delivered-To: barry@python.org Message-ID: <15265.9468.713530.98441@python.org> -From: barry@zope.com (Barry A. Warsaw) +From: barry@python.org (Barry A. Warsaw) Sender: barry@python.org To: barry@python.org Subject: testing diff --git a/Lib/test/test_email/data/msg_08.txt b/Lib/test/test_email/data/msg_08.txt index b5630836c54a..132ce7ada9bf 100644 --- a/Lib/test/test_email/data/msg_08.txt +++ b/Lib/test/test_email/data/msg_08.txt @@ -1,5 +1,5 @@ MIME-Version: 1.0 -From: Barry Warsaw +From: Barry Warsaw To: Dingus Lovers Subject: Lyrics Date: Fri, 20 Apr 2001 19:35:02 -0400 diff --git a/Lib/test/test_email/data/msg_09.txt b/Lib/test/test_email/data/msg_09.txt index 575c4c205a16..0cfa6bab2baf 100644 --- a/Lib/test/test_email/data/msg_09.txt +++ b/Lib/test/test_email/data/msg_09.txt @@ -1,5 +1,5 @@ MIME-Version: 1.0 -From: Barry Warsaw +From: Barry Warsaw To: Dingus Lovers Subject: Lyrics Date: Fri, 20 Apr 2001 19:35:02 -0400 diff --git a/Lib/test/test_email/data/msg_10.txt b/Lib/test/test_email/data/msg_10.txt index 07903960f9fe..d49e477a818d 100644 --- a/Lib/test/test_email/data/msg_10.txt +++ b/Lib/test/test_email/data/msg_10.txt @@ -1,5 +1,5 @@ MIME-Version: 1.0 -From: Barry Warsaw +From: Barry Warsaw To: Dingus Lovers Subject: Lyrics Date: Fri, 20 Apr 2001 19:35:02 -0400 diff --git a/Lib/test/test_email/data/msg_12.txt b/Lib/test/test_email/data/msg_12.txt index 4bec8d944498..b109b985c8b7 100644 --- a/Lib/test/test_email/data/msg_12.txt +++ b/Lib/test/test_email/data/msg_12.txt @@ -1,5 +1,5 @@ MIME-Version: 1.0 -From: Barry Warsaw +From: Barry Warsaw To: Dingus Lovers Subject: Lyrics Date: Fri, 20 Apr 2001 19:35:02 -0400 diff --git a/Lib/test/test_email/data/msg_12a.txt b/Lib/test/test_email/data/msg_12a.txt index e94224ecfe5e..2092aa0c351b 100644 --- a/Lib/test/test_email/data/msg_12a.txt +++ b/Lib/test/test_email/data/msg_12a.txt @@ -1,5 +1,5 @@ MIME-Version: 1.0 -From: Barry Warsaw +From: Barry Warsaw To: Dingus Lovers Subject: Lyrics Date: Fri, 20 Apr 2001 19:35:02 -0400 diff --git a/Lib/test/test_email/test__header_value_parser.py b/Lib/test/test_email/test__header_value_parser.py index 646082b4a40a..5404d1913f88 100644 --- a/Lib/test/test_email/test__header_value_parser.py +++ b/Lib/test/test_email/test__header_value_parser.py @@ -540,6 +540,15 @@ def test_get_bare_quoted_string_empty_quotes(self): self._test_get_x(parser.get_bare_quoted_string, '""', '""', '', [], '') + # Issue 16983: apply postel's law to some bad encoding. + def test_encoded_word_inside_quotes(self): + self._test_get_x(parser.get_bare_quoted_string, + '"=?utf-8?Q?not_really_valid?="', + '"not really valid"', + 'not really valid', + [errors.InvalidHeaderDefect], + '') + # get_comment def test_get_comment_only(self): @@ -2434,6 +2443,18 @@ def test_get_address_list_group_and_mailboxes(self): self.assertEqual(str(address_list.addresses[1]), str(address_list.mailboxes[2])) + def test_invalid_content_disposition(self): + content_disp = self._test_parse_x( + parser.parse_content_disposition_header, + ";attachment", "; attachment", ";attachment", + [errors.InvalidHeaderDefect]*2 + ) + + def test_invalid_content_transfer_encoding(self): + cte = self._test_parse_x( + parser.parse_content_transfer_encoding_header, + ";foo", ";foo", ";foo", [errors.InvalidHeaderDefect]*3 + ) @parameterize class Test_parse_mime_version(TestParserMixin, TestEmailBase): diff --git a/Lib/test/test_email/test_contentmanager.py b/Lib/test/test_email/test_contentmanager.py index 1629e2d8fd56..cdb04e45ed2d 100644 --- a/Lib/test/test_email/test_contentmanager.py +++ b/Lib/test/test_email/test_contentmanager.py @@ -536,8 +536,8 @@ def test_set_message_with_non_ascii_and_coercion_to_7bit(self): From: victim@monty.org Subject: Help Content-Type: text/plain; charset="utf-8" - MIME-Version: 1.0 Content-Transfer-Encoding: base64 + MIME-Version: 1.0 aidhaSB1biBwcm9ibMOobWUgZGUgcHl0aG9uLiBpbCBlc3Qgc29ydGkgZGUgc29uIHZpdmFyaXVt Lgo= diff --git a/Lib/test/test_email/test_email.py b/Lib/test/test_email/test_email.py index 57f12ae466f6..218ce0ce8134 100644 --- a/Lib/test/test_email/test_email.py +++ b/Lib/test/test_email/test_email.py @@ -10,6 +10,7 @@ from io import StringIO, BytesIO from itertools import chain +from random import choice import email import email.policy @@ -92,6 +93,46 @@ def test_set_payload_with_charset(self): msg.set_payload('This is a string payload', charset) self.assertEqual(msg.get_charset().input_charset, 'iso-8859-1') + def test_set_payload_with_8bit_data_and_charset(self): + data = b'\xd0\x90\xd0\x91\xd0\x92' + charset = Charset('utf-8') + msg = Message() + msg.set_payload(data, charset) + self.assertEqual(msg['content-transfer-encoding'], 'base64') + self.assertEqual(msg.get_payload(decode=True), data) + self.assertEqual(msg.get_payload(), '0JDQkdCS\n') + + def test_set_payload_with_non_ascii_and_charset_body_encoding_none(self): + data = b'\xd0\x90\xd0\x91\xd0\x92' + charset = Charset('utf-8') + charset.body_encoding = None # Disable base64 encoding + msg = Message() + msg.set_payload(data.decode('utf-8'), charset) + self.assertEqual(msg['content-transfer-encoding'], '8bit') + self.assertEqual(msg.get_payload(decode=True), data) + + def test_set_payload_with_8bit_data_and_charset_body_encoding_none(self): + data = b'\xd0\x90\xd0\x91\xd0\x92' + charset = Charset('utf-8') + charset.body_encoding = None # Disable base64 encoding + msg = Message() + msg.set_payload(data, charset) + self.assertEqual(msg['content-transfer-encoding'], '8bit') + self.assertEqual(msg.get_payload(decode=True), data) + + def test_set_payload_to_list(self): + msg = Message() + msg.set_payload([]) + self.assertEqual(msg.get_payload(), []) + + def test_attach_when_payload_is_string(self): + msg = Message() + msg['Content-Type'] = 'multipart/mixed' + msg.set_payload('string payload') + sub_msg = MIMEMessage(Message()) + self.assertRaisesRegex(TypeError, "[Aa]ttach.*non-multipart", + msg.attach, sub_msg) + def test_get_charsets(self): eq = self.assertEqual @@ -737,8 +778,15 @@ def test_encode7or8bit(self): # whose output character set is 7bit gets a transfer-encoding # of 7bit. eq = self.assertEqual - msg = MIMEText('文', _charset='euc-jp') + msg = MIMEText('文\n', _charset='euc-jp') eq(msg['content-transfer-encoding'], '7bit') + eq(msg.as_string(), textwrap.dedent("""\ + MIME-Version: 1.0 + Content-Type: text/plain; charset="iso-2022-jp" + Content-Transfer-Encoding: 7bit + + \x1b$BJ8\x1b(B + """)) def test_qp_encode_latin1(self): msg = MIMEText('\xe1\xf6\n', 'text', 'ISO-8859-1') @@ -1588,6 +1636,10 @@ def test_charset(self): msg = MIMEText('hello there', _charset='us-ascii') eq(msg.get_charset().input_charset, 'us-ascii') eq(msg['content-type'], 'text/plain; charset="us-ascii"') + # Also accept a Charset instance + msg = MIMEText('hello there', _charset=Charset('utf-8')) + eq(msg.get_charset().input_charset, 'utf-8') + eq(msg['content-type'], 'text/plain; charset="utf-8"') def test_7bit_input(self): eq = self.assertEqual @@ -1706,7 +1758,8 @@ def test_no_parts_in_a_multipart_with_none_epilogue(self): --BOUNDARY ---BOUNDARY--''') +--BOUNDARY-- +''') def test_no_parts_in_a_multipart_with_empty_epilogue(self): outer = MIMEBase('multipart', 'mixed') @@ -1751,7 +1804,8 @@ def test_one_part_in_a_multipart(self): Content-Transfer-Encoding: 7bit hello world ---BOUNDARY--''') +--BOUNDARY-- +''') def test_seq_parts_in_a_multipart_with_empty_preamble(self): eq = self.ndiffAssertEqual @@ -1777,7 +1831,8 @@ def test_seq_parts_in_a_multipart_with_empty_preamble(self): Content-Transfer-Encoding: 7bit hello world ---BOUNDARY--''') +--BOUNDARY-- +''') def test_seq_parts_in_a_multipart_with_none_preamble(self): @@ -1803,7 +1858,8 @@ def test_seq_parts_in_a_multipart_with_none_preamble(self): Content-Transfer-Encoding: 7bit hello world ---BOUNDARY--''') +--BOUNDARY-- +''') def test_seq_parts_in_a_multipart_with_none_epilogue(self): @@ -1829,7 +1885,8 @@ def test_seq_parts_in_a_multipart_with_none_epilogue(self): Content-Transfer-Encoding: 7bit hello world ---BOUNDARY--''') +--BOUNDARY-- +''') def test_seq_parts_in_a_multipart_with_empty_epilogue(self): @@ -3301,16 +3358,77 @@ def test_pushCR_LF(self): bsf.push(il) nt += n n1 = 0 - while True: - ol = bsf.readline() - if ol == NeedMoreData: - break + for ol in iter(bsf.readline, NeedMoreData): om.append(ol) n1 += 1 self.assertEqual(n, n1) self.assertEqual(len(om), nt) self.assertEqual(''.join([il for il, n in imt]), ''.join(om)) + def test_push_random(self): + from email.feedparser import BufferedSubFile, NeedMoreData + + n = 10000 + chunksize = 5 + chars = 'abcd \t\r\n' + + s = ''.join(choice(chars) for i in range(n)) + '\n' + target = s.splitlines(True) + + bsf = BufferedSubFile() + lines = [] + for i in range(0, len(s), chunksize): + chunk = s[i:i+chunksize] + bsf.push(chunk) + lines.extend(iter(bsf.readline, NeedMoreData)) + self.assertEqual(lines, target) + + +class TestFeedParsers(TestEmailBase): + + def parse(self, chunks): + from email.feedparser import FeedParser + feedparser = FeedParser() + for chunk in chunks: + feedparser.feed(chunk) + return feedparser.close() + + def test_empty_header_name_handled(self): + # Issue 19996 + msg = self.parse("First: val\n: bad\nSecond: val") + self.assertEqual(msg['First'], 'val') + self.assertEqual(msg['Second'], 'val') + + def test_newlines(self): + m = self.parse(['a:\nb:\rc:\r\nd:\n']) + self.assertEqual(m.keys(), ['a', 'b', 'c', 'd']) + m = self.parse(['a:\nb:\rc:\r\nd:']) + self.assertEqual(m.keys(), ['a', 'b', 'c', 'd']) + m = self.parse(['a:\rb', 'c:\n']) + self.assertEqual(m.keys(), ['a', 'bc']) + m = self.parse(['a:\r', 'b:\n']) + self.assertEqual(m.keys(), ['a', 'b']) + m = self.parse(['a:\r', '\nb:\n']) + self.assertEqual(m.keys(), ['a', 'b']) + m = self.parse(['a:\x85b:\u2028c:\n']) + self.assertEqual(m.items(), [('a', '\x85'), ('b', '\u2028'), ('c', '')]) + m = self.parse(['a:\r', 'b:\x85', 'c:\n']) + self.assertEqual(m.items(), [('a', ''), ('b', '\x85'), ('c', '')]) + + def test_long_lines(self): + # Expected peak memory use on 32-bit platform: 6*N*M bytes. + M, N = 1000, 20000 + m = self.parse(['a:b\n\n'] + ['x'*M] * N) + self.assertEqual(m.items(), [('a', 'b')]) + self.assertEqual(m.get_payload(), 'x'*M*N) + m = self.parse(['a:b\r\r'] + ['x'*M] * N) + self.assertEqual(m.items(), [('a', 'b')]) + self.assertEqual(m.get_payload(), 'x'*M*N) + m = self.parse(['a:b\r\r'] + ['x'*M+'\x85'] * N) + self.assertEqual(m.items(), [('a', 'b')]) + self.assertEqual(m.get_payload(), ('x'*M+'\x85')*N) + m = self.parse(['a:\r', 'b: '] + ['x'*M] * N) + self.assertEqual(m.items(), [('a', ''), ('b', 'x'*M*N)]) class TestParsers(TestEmailBase): @@ -3338,6 +3456,31 @@ def test_bytes_header_parser(self): self.assertIsInstance(msg.get_payload(), str) self.assertIsInstance(msg.get_payload(decode=True), bytes) + def test_bytes_parser_does_not_close_file(self): + with openfile('msg_02.txt', 'rb') as fp: + email.parser.BytesParser().parse(fp) + self.assertFalse(fp.closed) + + def test_bytes_parser_on_exception_does_not_close_file(self): + with openfile('msg_15.txt', 'rb') as fp: + bytesParser = email.parser.BytesParser + self.assertRaises(email.errors.StartBoundaryNotFoundDefect, + bytesParser(policy=email.policy.strict).parse, + fp) + self.assertFalse(fp.closed) + + def test_parser_does_not_close_file(self): + with openfile('msg_02.txt', 'r') as fp: + email.parser.Parser().parse(fp) + self.assertFalse(fp.closed) + + def test_parser_on_exception_does_not_close_file(self): + with openfile('msg_15.txt', 'r') as fp: + parser = email.parser.Parser + self.assertRaises(email.errors.StartBoundaryNotFoundDefect, + parser(policy=email.policy.strict).parse, fp) + self.assertFalse(fp.closed) + def test_whitespace_continuation(self): eq = self.assertEqual # This message contains a line after the Subject: header that has only @@ -3490,7 +3633,7 @@ def test_CRLFLF_at_end_of_part(self): self.assertTrue(msg.get_payload(0).get_payload().endswith('\r\n')) -class Test8BitBytesHandling(unittest.TestCase): +class Test8BitBytesHandling(TestEmailBase): # In Python3 all input is string, but that doesn't work if the actual input # uses an 8bit transfer encoding. To hack around that, in email 5.1 we # decode byte streams using the surrogateescape error handler, and @@ -3743,6 +3886,16 @@ def test_generator_handles_8bit(self): email.generator.Generator(out).flatten(msg) self.assertEqual(out.getvalue(), self.non_latin_bin_msg_as7bit_wrapped) + def test_str_generator_should_not_mutate_msg_when_handling_8bit(self): + msg = email.message_from_bytes(self.non_latin_bin_msg) + out = BytesIO() + BytesGenerator(out).flatten(msg) + orig_value = out.getvalue() + Generator(StringIO()).flatten(msg) # Should not mutate msg! + out = BytesIO() + BytesGenerator(out).flatten(msg) + self.assertEqual(out.getvalue(), orig_value) + def test_bytes_generator_with_unix_from(self): # The unixfrom contains a current date, so we can't check it # literally. Just make sure the first word is 'From' and the @@ -4211,6 +4364,11 @@ def test_encode_one_line_crlf(self): def test_encode_one_line_eol(self): self._test_encode('hello\n', 'hello\r\n', eol='\r\n') + def test_encode_one_line_eol_after_non_ascii(self): + # issue 20206; see changeset 0cf700464177 for why the encode/decode. + self._test_encode('hello\u03c5\n'.encode('utf-8').decode('latin1'), + 'hello=CF=85\r\n', eol='\r\n') + def test_encode_one_space(self): self._test_encode(' ', '=20') @@ -5008,6 +5166,26 @@ def test_rfc2231_single_tick_in_filename(self): self.assertNotIsInstance(param, tuple) self.assertEqual(param, "Frank's Document") + def test_rfc2231_missing_tick(self): + m = '''\ +Content-Disposition: inline; +\tfilename*0*="'This%20is%20broken"; +''' + msg = email.message_from_string(m) + self.assertEqual( + msg.get_filename(), + "'This is broken") + + def test_rfc2231_missing_tick_with_encoded_non_ascii(self): + m = '''\ +Content-Disposition: inline; +\tfilename*0*="'This%20is%E2broken"; +''' + msg = email.message_from_string(m) + self.assertEqual( + msg.get_filename(), + "'This is\ufffdbroken") + # test_headerregistry.TestContentTypeHeader.rfc2231_single_quote_in_value_with_charset_and_lang def test_rfc2231_tick_attack_extended(self): eq = self.assertEqual diff --git a/Lib/test/test_email/test_headerregistry.py b/Lib/test/test_email/test_headerregistry.py index f2df3720eb9f..55ecdea9aacb 100644 --- a/Lib/test/test_email/test_headerregistry.py +++ b/Lib/test/test_email/test_headerregistry.py @@ -1,6 +1,7 @@ import datetime import textwrap import unittest +import types from email import errors from email import policy from email.message import Message @@ -235,6 +236,8 @@ def content_type_as_value(self, self.assertEqual(h.maintype, maintype) self.assertEqual(h.subtype, subtype) self.assertEqual(h.params, parmdict) + with self.assertRaises(TypeError): + h.params['abc'] = 'xyz' # params is read-only. self.assertDefectsEqual(h.defects, defects) self.assertEqual(h, decoded) self.assertEqual(h.fold(policy=policy.default), folded) @@ -1155,6 +1158,16 @@ class TestAddressHeader(TestHeaderBase): 'example.com', None), + 'rfc2047_atom_in_quoted_string_is_decoded': + ('"=?utf-8?q?=C3=89ric?=" ', + [errors.InvalidHeaderDefect], + 'Éric ', + 'Éric', + 'foo@example.com', + 'foo', + 'example.com', + None), + } # XXX: Need many more examples, and in particular some with names in diff --git a/Lib/test/test_email/test_message.py b/Lib/test/test_email/test_message.py index e0ebb8ad6c52..d78049e315d0 100644 --- a/Lib/test/test_email/test_message.py +++ b/Lib/test/test_email/test_message.py @@ -1,6 +1,6 @@ import unittest import textwrap -from email import policy +from email import policy, message_from_string from email.message import EmailMessage, MIMEPart from test.test_email import TestEmailBase, parameterize @@ -20,6 +20,20 @@ def test_error_on_setitem_if_max_count_exceeded(self): with self.assertRaises(ValueError): m['To'] = 'xyz@abc' + def test_rfc2043_auto_decoded_and_emailmessage_used(self): + m = message_from_string(textwrap.dedent("""\ + Subject: Ayons asperges pour le =?utf-8?q?d=C3=A9jeuner?= + From: =?utf-8?q?Pep=C3=A9?= Le Pew + To: "Penelope Pussycat" <"penelope@example.com"> + MIME-Version: 1.0 + Content-Type: text/plain; charset="utf-8" + + sample text + """), policy=policy.default) + self.assertEqual(m['subject'], "Ayons asperges pour le déjeuner") + self.assertEqual(m['from'], "Pepé Le Pew ") + self.assertIsInstance(m, EmailMessage) + @parameterize class TestEmailMessageBase: @@ -708,14 +722,15 @@ def message_as_clear_content(self, body_parts, attachments, parts, msg): def test_is_attachment(self): m = self._make_message() - self.assertFalse(m.is_attachment) + self.assertFalse(m.is_attachment()) m['Content-Disposition'] = 'inline' - self.assertFalse(m.is_attachment) + self.assertFalse(m.is_attachment()) m.replace_header('Content-Disposition', 'attachment') - self.assertTrue(m.is_attachment) + self.assertTrue(m.is_attachment()) m.replace_header('Content-Disposition', 'AtTachMent') - self.assertTrue(m.is_attachment) - + self.assertTrue(m.is_attachment()) + m.set_param('filename', 'abc.png', 'Content-Disposition') + self.assertTrue(m.is_attachment()) class TestEmailMessage(TestEmailMessageBase, TestEmailBase): diff --git a/Lib/test/test_email/test_pickleable.py b/Lib/test/test_email/test_pickleable.py index daa8d25053dc..16b446711463 100644 --- a/Lib/test/test_email/test_pickleable.py +++ b/Lib/test/test_email/test_pickleable.py @@ -30,9 +30,10 @@ def header_as_deepcopy(self, name, value): def header_as_pickle(self, name, value): header = self.header_factory(name, value) - p = pickle.dumps(header) - h = pickle.loads(p) - self.assertEqual(str(h), str(header)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + p = pickle.dumps(header, proto) + h = pickle.loads(p) + self.assertEqual(str(h), str(header)) @parameterize @@ -65,9 +66,10 @@ def msg_as_deepcopy(self, msg): self.assertEqual(msg2.as_string(), msg.as_string()) def msg_as_pickle(self, msg): - p = pickle.dumps(msg) - msg2 = pickle.loads(p) - self.assertEqual(msg2.as_string(), msg.as_string()) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + p = pickle.dumps(msg, proto) + msg2 = pickle.loads(p) + self.assertEqual(msg2.as_string(), msg.as_string()) if __name__ == '__main__': diff --git a/Lib/test/test_email/test_policy.py b/Lib/test/test_email/test_policy.py index 06ad5f24b80d..e797f36b72ed 100644 --- a/Lib/test/test_email/test_policy.py +++ b/Lib/test/test_email/test_policy.py @@ -319,5 +319,14 @@ def test_message_policy_used_by_as_string(self): self.assertEqual(msg.as_string(), "Subject: testXTo: fooXX") +class TestConcretePolicies(unittest.TestCase): + + def test_header_store_parse_rejects_newlines(self): + instance = email.policy.EmailPolicy() + self.assertRaises(ValueError, + instance.header_store_parse, + 'From', 'spam\negg@foo.py') + + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_ensurepip.py b/Lib/test/test_ensurepip.py index c119327d4250..759168ec97e1 100644 --- a/Lib/test/test_ensurepip.py +++ b/Lib/test/test_ensurepip.py @@ -1,20 +1,34 @@ import unittest import unittest.mock -import ensurepip import test.support import os import os.path import contextlib import sys +import ensurepip +import ensurepip._uninstall + +# pip currently requires ssl support, so we ensure we handle +# it being missing (http://bugs.python.org/issue19744) +ensurepip_no_ssl = test.support.import_fresh_module("ensurepip", + blocked=["ssl"]) +try: + import ssl +except ImportError: + def requires_usable_pip(f): + deco = unittest.skip(ensurepip._MISSING_SSL_MESSAGE) + return deco(f) +else: + def requires_usable_pip(f): + return f class TestEnsurePipVersion(unittest.TestCase): def test_returns_version(self): self.assertEqual(ensurepip._PIP_VERSION, ensurepip.version()) - -class TestBootstrap(unittest.TestCase): +class EnsurepipMixin: def setUp(self): run_pip_patch = unittest.mock.patch("ensurepip._run_pip") @@ -22,19 +36,25 @@ def setUp(self): self.addCleanup(run_pip_patch.stop) # Avoid side effects on the actual os module + real_devnull = os.devnull os_patch = unittest.mock.patch("ensurepip.os") patched_os = os_patch.start() self.addCleanup(os_patch.stop) + patched_os.devnull = real_devnull patched_os.path = os.path self.os_environ = patched_os.environ = os.environ.copy() + +class TestBootstrap(EnsurepipMixin, unittest.TestCase): + + @requires_usable_pip def test_basic_bootstrapping(self): ensurepip.bootstrap() self.run_pip.assert_called_once_with( [ "install", "--no-index", "--find-links", - unittest.mock.ANY, "--pre", "setuptools", "pip", + unittest.mock.ANY, "setuptools", "pip", ], unittest.mock.ANY, ) @@ -42,81 +62,90 @@ def test_basic_bootstrapping(self): additional_paths = self.run_pip.call_args[0][1] self.assertEqual(len(additional_paths), 2) + @requires_usable_pip def test_bootstrapping_with_root(self): ensurepip.bootstrap(root="/foo/bar/") self.run_pip.assert_called_once_with( [ "install", "--no-index", "--find-links", - unittest.mock.ANY, "--pre", "--root", "/foo/bar/", + unittest.mock.ANY, "--root", "/foo/bar/", "setuptools", "pip", ], unittest.mock.ANY, ) + @requires_usable_pip def test_bootstrapping_with_user(self): ensurepip.bootstrap(user=True) self.run_pip.assert_called_once_with( [ "install", "--no-index", "--find-links", - unittest.mock.ANY, "--pre", "--user", "setuptools", "pip", + unittest.mock.ANY, "--user", "setuptools", "pip", ], unittest.mock.ANY, ) + @requires_usable_pip def test_bootstrapping_with_upgrade(self): ensurepip.bootstrap(upgrade=True) self.run_pip.assert_called_once_with( [ "install", "--no-index", "--find-links", - unittest.mock.ANY, "--pre", "--upgrade", "setuptools", "pip", + unittest.mock.ANY, "--upgrade", "setuptools", "pip", ], unittest.mock.ANY, ) + @requires_usable_pip def test_bootstrapping_with_verbosity_1(self): ensurepip.bootstrap(verbosity=1) self.run_pip.assert_called_once_with( [ "install", "--no-index", "--find-links", - unittest.mock.ANY, "--pre", "-v", "setuptools", "pip", + unittest.mock.ANY, "-v", "setuptools", "pip", ], unittest.mock.ANY, ) + @requires_usable_pip def test_bootstrapping_with_verbosity_2(self): ensurepip.bootstrap(verbosity=2) self.run_pip.assert_called_once_with( [ "install", "--no-index", "--find-links", - unittest.mock.ANY, "--pre", "-vv", "setuptools", "pip", + unittest.mock.ANY, "-vv", "setuptools", "pip", ], unittest.mock.ANY, ) + @requires_usable_pip def test_bootstrapping_with_verbosity_3(self): ensurepip.bootstrap(verbosity=3) self.run_pip.assert_called_once_with( [ "install", "--no-index", "--find-links", - unittest.mock.ANY, "--pre", "-vvv", "setuptools", "pip", + unittest.mock.ANY, "-vvv", "setuptools", "pip", ], unittest.mock.ANY, ) + @requires_usable_pip def test_bootstrapping_with_regular_install(self): ensurepip.bootstrap() self.assertEqual(self.os_environ["ENSUREPIP_OPTIONS"], "install") + @requires_usable_pip def test_bootstrapping_with_alt_install(self): ensurepip.bootstrap(altinstall=True) self.assertEqual(self.os_environ["ENSUREPIP_OPTIONS"], "altinstall") + @requires_usable_pip def test_bootstrapping_with_default_pip(self): ensurepip.bootstrap(default_pip=True) self.assertNotIn("ENSUREPIP_OPTIONS", self.os_environ) @@ -124,7 +153,22 @@ def test_bootstrapping_with_default_pip(self): def test_altinstall_default_pip_conflict(self): with self.assertRaises(ValueError): ensurepip.bootstrap(altinstall=True, default_pip=True) - self.run_pip.assert_not_called() + self.assertFalse(self.run_pip.called) + + @requires_usable_pip + def test_pip_environment_variables_removed(self): + # ensurepip deliberately ignores all pip environment variables + # See http://bugs.python.org/issue19734 for details + self.os_environ["PIP_THIS_SHOULD_GO_AWAY"] = "test fodder" + ensurepip.bootstrap() + self.assertNotIn("PIP_THIS_SHOULD_GO_AWAY", self.os_environ) + + @requires_usable_pip + def test_pip_config_file_disabled(self): + # ensurepip deliberately ignores the pip config file + # See http://bugs.python.org/issue20053 for details + ensurepip.bootstrap() + self.assertEqual(self.os_environ["PIP_CONFIG_FILE"], os.devnull) @contextlib.contextmanager def fake_pip(version=ensurepip._PIP_VERSION): @@ -145,57 +189,155 @@ class FakePip(): else: sys.modules["pip"] = orig_pip -class TestUninstall(unittest.TestCase): - - def setUp(self): - run_pip_patch = unittest.mock.patch("ensurepip._run_pip") - self.run_pip = run_pip_patch.start() - self.addCleanup(run_pip_patch.stop) +class TestUninstall(EnsurepipMixin, unittest.TestCase): def test_uninstall_skipped_when_not_installed(self): with fake_pip(None): - ensurepip._uninstall() - self.run_pip.assert_not_called() + ensurepip._uninstall_helper() + self.assertFalse(self.run_pip.called) - def test_uninstall_fails_with_wrong_version(self): + def test_uninstall_skipped_with_warning_for_wrong_version(self): with fake_pip("not a valid version"): - with self.assertRaises(RuntimeError): - ensurepip._uninstall() - self.run_pip.assert_not_called() + with test.support.captured_stderr() as stderr: + ensurepip._uninstall_helper() + warning = stderr.getvalue().strip() + self.assertIn("only uninstall a matching version", warning) + self.assertFalse(self.run_pip.called) + @requires_usable_pip def test_uninstall(self): with fake_pip(): - ensurepip._uninstall() + ensurepip._uninstall_helper() self.run_pip.assert_called_once_with( ["uninstall", "-y", "pip", "setuptools"] ) + @requires_usable_pip def test_uninstall_with_verbosity_1(self): with fake_pip(): - ensurepip._uninstall(verbosity=1) + ensurepip._uninstall_helper(verbosity=1) self.run_pip.assert_called_once_with( ["uninstall", "-y", "-v", "pip", "setuptools"] ) + @requires_usable_pip def test_uninstall_with_verbosity_2(self): with fake_pip(): - ensurepip._uninstall(verbosity=2) + ensurepip._uninstall_helper(verbosity=2) self.run_pip.assert_called_once_with( ["uninstall", "-y", "-vv", "pip", "setuptools"] ) + @requires_usable_pip def test_uninstall_with_verbosity_3(self): with fake_pip(): - ensurepip._uninstall(verbosity=3) + ensurepip._uninstall_helper(verbosity=3) self.run_pip.assert_called_once_with( ["uninstall", "-y", "-vvv", "pip", "setuptools"] ) + @requires_usable_pip + def test_pip_environment_variables_removed(self): + # ensurepip deliberately ignores all pip environment variables + # See http://bugs.python.org/issue19734 for details + self.os_environ["PIP_THIS_SHOULD_GO_AWAY"] = "test fodder" + with fake_pip(): + ensurepip._uninstall_helper() + self.assertNotIn("PIP_THIS_SHOULD_GO_AWAY", self.os_environ) + + @requires_usable_pip + def test_pip_config_file_disabled(self): + # ensurepip deliberately ignores the pip config file + # See http://bugs.python.org/issue20053 for details + with fake_pip(): + ensurepip._uninstall_helper() + self.assertEqual(self.os_environ["PIP_CONFIG_FILE"], os.devnull) + + +class TestMissingSSL(EnsurepipMixin, unittest.TestCase): + + def setUp(self): + sys.modules["ensurepip"] = ensurepip_no_ssl + @self.addCleanup + def restore_module(): + sys.modules["ensurepip"] = ensurepip + super().setUp() + + def test_bootstrap_requires_ssl(self): + self.os_environ["PIP_THIS_SHOULD_STAY"] = "test fodder" + with self.assertRaisesRegex(RuntimeError, "requires SSL/TLS"): + ensurepip_no_ssl.bootstrap() + self.assertFalse(self.run_pip.called) + self.assertIn("PIP_THIS_SHOULD_STAY", self.os_environ) + + def test_uninstall_requires_ssl(self): + self.os_environ["PIP_THIS_SHOULD_STAY"] = "test fodder" + with self.assertRaisesRegex(RuntimeError, "requires SSL/TLS"): + with fake_pip(): + ensurepip_no_ssl._uninstall_helper() + self.assertFalse(self.run_pip.called) + self.assertIn("PIP_THIS_SHOULD_STAY", self.os_environ) + + def test_main_exits_early_with_warning(self): + with test.support.captured_stderr() as stderr: + ensurepip_no_ssl._main(["--version"]) + warning = stderr.getvalue().strip() + self.assertTrue(warning.endswith("requires SSL/TLS"), warning) + self.assertFalse(self.run_pip.called) + +# Basic testing of the main functions and their argument parsing + +EXPECTED_VERSION_OUTPUT = "pip " + ensurepip._PIP_VERSION + +class TestBootstrappingMainFunction(EnsurepipMixin, unittest.TestCase): + + @requires_usable_pip + def test_bootstrap_version(self): + with test.support.captured_stdout() as stdout: + with self.assertRaises(SystemExit): + ensurepip._main(["--version"]) + result = stdout.getvalue().strip() + self.assertEqual(result, EXPECTED_VERSION_OUTPUT) + self.assertFalse(self.run_pip.called) + + @requires_usable_pip + def test_basic_bootstrapping(self): + ensurepip._main([]) + + self.run_pip.assert_called_once_with( + [ + "install", "--no-index", "--find-links", + unittest.mock.ANY, "setuptools", "pip", + ], + unittest.mock.ANY, + ) + + additional_paths = self.run_pip.call_args[0][1] + self.assertEqual(len(additional_paths), 2) + +class TestUninstallationMainFunction(EnsurepipMixin, unittest.TestCase): + + def test_uninstall_version(self): + with test.support.captured_stdout() as stdout: + with self.assertRaises(SystemExit): + ensurepip._uninstall._main(["--version"]) + result = stdout.getvalue().strip() + self.assertEqual(result, EXPECTED_VERSION_OUTPUT) + self.assertFalse(self.run_pip.called) + + @requires_usable_pip + def test_basic_uninstall(self): + with fake_pip(): + ensurepip._uninstall._main([]) + + self.run_pip.assert_called_once_with( + ["uninstall", "-y", "pip", "setuptools"] + ) diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py index 03f0e5d5cda5..7d172c86e4f5 100644 --- a/Lib/test/test_enum.py +++ b/Lib/test/test_enum.py @@ -5,7 +5,7 @@ from collections import OrderedDict from enum import Enum, IntEnum, EnumMeta, unique from io import StringIO -from pickle import dumps, loads, PicklingError +from pickle import dumps, loads, PicklingError, HIGHEST_PROTOCOL # for pickle tests try: @@ -52,6 +52,11 @@ class Name(StrEnum): except Exception as exc: Answer = exc +try: + Theory = Enum('Theory', 'rule law supposition', qualname='spanish_inquisition') +except Exception as exc: + Theory = exc + # for doctests try: class Fruit(Enum): @@ -61,6 +66,20 @@ class Fruit(Enum): except Exception: pass +def test_pickle_dump_load(assertion, source, target=None, + *, protocol=(0, HIGHEST_PROTOCOL)): + start, stop = protocol + if target is None: + target = source + for protocol in range(start, stop+1): + assertion(loads(dumps(source, protocol=protocol)), target) + +def test_pickle_exception(assertion, exception, obj, + *, protocol=(0, HIGHEST_PROTOCOL)): + start, stop = protocol + for protocol in range(start, stop+1): + with assertion(exception): + dumps(obj, protocol=protocol) class TestHelpers(unittest.TestCase): # _is_descriptor, _is_sunder, _is_dunder @@ -91,6 +110,7 @@ def test_is_dunder(self): class TestEnum(unittest.TestCase): + def setUp(self): class Season(Enum): SPRING = 1 @@ -156,6 +176,18 @@ def wowser(self): set(['__class__', '__doc__', '__module__', 'name', 'value', 'wowser']), ) + def test_dir_on_sub_with_behavior_on_super(self): + # see issue22506 + class SuperEnum(Enum): + def invisible(self): + return "did you see me?" + class SubEnum(SuperEnum): + sample = 5 + self.assertEqual( + set(dir(SubEnum.sample)), + set(['__class__', '__doc__', '__module__', 'name', 'value', 'invisible']), + ) + def test_enum_in_enum_out(self): Season = self.Season self.assertIs(Season(Season.WINTER), Season.WINTER) @@ -503,41 +535,60 @@ class WeekDay(IntEnum): def test_pickle_enum(self): if isinstance(Stooges, Exception): raise Stooges - self.assertIs(Stooges.CURLY, loads(dumps(Stooges.CURLY))) - self.assertIs(Stooges, loads(dumps(Stooges))) + test_pickle_dump_load(self.assertIs, Stooges.CURLY) + test_pickle_dump_load(self.assertIs, Stooges) def test_pickle_int(self): if isinstance(IntStooges, Exception): raise IntStooges - self.assertIs(IntStooges.CURLY, loads(dumps(IntStooges.CURLY))) - self.assertIs(IntStooges, loads(dumps(IntStooges))) + test_pickle_dump_load(self.assertIs, IntStooges.CURLY) + test_pickle_dump_load(self.assertIs, IntStooges) def test_pickle_float(self): if isinstance(FloatStooges, Exception): raise FloatStooges - self.assertIs(FloatStooges.CURLY, loads(dumps(FloatStooges.CURLY))) - self.assertIs(FloatStooges, loads(dumps(FloatStooges))) + test_pickle_dump_load(self.assertIs, FloatStooges.CURLY) + test_pickle_dump_load(self.assertIs, FloatStooges) def test_pickle_enum_function(self): if isinstance(Answer, Exception): raise Answer - self.assertIs(Answer.him, loads(dumps(Answer.him))) - self.assertIs(Answer, loads(dumps(Answer))) + test_pickle_dump_load(self.assertIs, Answer.him) + test_pickle_dump_load(self.assertIs, Answer) def test_pickle_enum_function_with_module(self): if isinstance(Question, Exception): raise Question - self.assertIs(Question.who, loads(dumps(Question.who))) - self.assertIs(Question, loads(dumps(Question))) + test_pickle_dump_load(self.assertIs, Question.who) + test_pickle_dump_load(self.assertIs, Question) + + def test_enum_function_with_qualname(self): + if isinstance(Theory, Exception): + raise Theory + self.assertEqual(Theory.__qualname__, 'spanish_inquisition') + + def test_class_nested_enum_and_pickle_protocol_four(self): + # would normally just have this directly in the class namespace + class NestedEnum(Enum): + twigs = 'common' + shiny = 'rare' + + self.__class__.NestedEnum = NestedEnum + self.NestedEnum.__qualname__ = '%s.NestedEnum' % self.__class__.__name__ + test_pickle_exception( + self.assertRaises, PicklingError, self.NestedEnum.twigs, + protocol=(0, 3)) + test_pickle_dump_load(self.assertIs, self.NestedEnum.twigs, + protocol=(4, HIGHEST_PROTOCOL)) def test_exploding_pickle(self): - BadPickle = Enum('BadPickle', 'dill sweet bread-n-butter') - enum._make_class_unpicklable(BadPickle) + BadPickle = Enum( + 'BadPickle', 'dill sweet bread-n-butter', module=__name__) globals()['BadPickle'] = BadPickle - with self.assertRaises(TypeError): - dumps(BadPickle.dill) - with self.assertRaises(PicklingError): - dumps(BadPickle) + # now break BadPickle to test exception raising + enum._make_class_unpicklable(BadPickle) + test_pickle_exception(self.assertRaises, TypeError, BadPickle.dill) + test_pickle_exception(self.assertRaises, PicklingError, BadPickle) def test_string_enum(self): class SkillLevel(str, Enum): @@ -595,6 +646,23 @@ def test_programatic_function_string(self): self.assertIn(e, SummerMonth) self.assertIs(type(e), SummerMonth) + def test_programatic_function_string_with_start(self): + SummerMonth = Enum('SummerMonth', 'june july august', start=10) + lst = list(SummerMonth) + self.assertEqual(len(lst), len(SummerMonth)) + self.assertEqual(len(SummerMonth), 3, SummerMonth) + self.assertEqual( + [SummerMonth.june, SummerMonth.july, SummerMonth.august], + lst, + ) + for i, month in enumerate('june july august'.split(), 10): + e = SummerMonth(i) + self.assertEqual(int(e.value), i) + self.assertNotEqual(e, i) + self.assertEqual(e.name, month) + self.assertIn(e, SummerMonth) + self.assertIs(type(e), SummerMonth) + def test_programatic_function_string_list(self): SummerMonth = Enum('SummerMonth', ['june', 'july', 'august']) lst = list(SummerMonth) @@ -612,6 +680,23 @@ def test_programatic_function_string_list(self): self.assertIn(e, SummerMonth) self.assertIs(type(e), SummerMonth) + def test_programatic_function_string_list_with_start(self): + SummerMonth = Enum('SummerMonth', ['june', 'july', 'august'], start=20) + lst = list(SummerMonth) + self.assertEqual(len(lst), len(SummerMonth)) + self.assertEqual(len(SummerMonth), 3, SummerMonth) + self.assertEqual( + [SummerMonth.june, SummerMonth.july, SummerMonth.august], + lst, + ) + for i, month in enumerate('june july august'.split(), 20): + e = SummerMonth(i) + self.assertEqual(int(e.value), i) + self.assertNotEqual(e, i) + self.assertEqual(e.name, month) + self.assertIn(e, SummerMonth) + self.assertIs(type(e), SummerMonth) + def test_programatic_function_iterable(self): SummerMonth = Enum( 'SummerMonth', @@ -668,6 +753,22 @@ def test_programatic_function_type(self): self.assertIn(e, SummerMonth) self.assertIs(type(e), SummerMonth) + def test_programatic_function_type_with_start(self): + SummerMonth = Enum('SummerMonth', 'june july august', type=int, start=30) + lst = list(SummerMonth) + self.assertEqual(len(lst), len(SummerMonth)) + self.assertEqual(len(SummerMonth), 3, SummerMonth) + self.assertEqual( + [SummerMonth.june, SummerMonth.july, SummerMonth.august], + lst, + ) + for i, month in enumerate('june july august'.split(), 30): + e = SummerMonth(i) + self.assertEqual(e, i) + self.assertEqual(e.name, month) + self.assertIn(e, SummerMonth) + self.assertIs(type(e), SummerMonth) + def test_programatic_function_type_from_subclass(self): SummerMonth = IntEnum('SummerMonth', 'june july august') lst = list(SummerMonth) @@ -684,13 +785,29 @@ def test_programatic_function_type_from_subclass(self): self.assertIn(e, SummerMonth) self.assertIs(type(e), SummerMonth) + def test_programatic_function_type_from_subclass_with_start(self): + SummerMonth = IntEnum('SummerMonth', 'june july august', start=40) + lst = list(SummerMonth) + self.assertEqual(len(lst), len(SummerMonth)) + self.assertEqual(len(SummerMonth), 3, SummerMonth) + self.assertEqual( + [SummerMonth.june, SummerMonth.july, SummerMonth.august], + lst, + ) + for i, month in enumerate('june july august'.split(), 40): + e = SummerMonth(i) + self.assertEqual(e, i) + self.assertEqual(e.name, month) + self.assertIn(e, SummerMonth) + self.assertIs(type(e), SummerMonth) + def test_subclassing(self): if isinstance(Name, Exception): raise Name self.assertEqual(Name.BDFL, 'Guido van Rossum') self.assertTrue(Name.BDFL, Name('Guido van Rossum')) self.assertIs(Name.BDFL, getattr(Name, 'BDFL')) - self.assertIs(Name.BDFL, loads(dumps(Name.BDFL))) + test_pickle_dump_load(self.assertIs, Name.BDFL) def test_extending(self): class Color(Enum): @@ -864,6 +981,7 @@ class TestAutoInt(AutoIntEnum): def test_subclasses_with_getnewargs(self): class NamedInt(int): + __qualname__ = 'NamedInt' # needed for pickle protocol 4 def __new__(cls, *args): _args = args name, *args = args @@ -902,6 +1020,64 @@ def __add__(self, other): return temp class NEI(NamedInt, Enum): + __qualname__ = 'NEI' # needed for pickle protocol 4 + x = ('the-x', 1) + y = ('the-y', 2) + + + self.assertIs(NEI.__new__, Enum.__new__) + self.assertEqual(repr(NEI.x + NEI.y), "NamedInt('(the-x + the-y)', 3)") + globals()['NamedInt'] = NamedInt + globals()['NEI'] = NEI + NI5 = NamedInt('test', 5) + self.assertEqual(NI5, 5) + test_pickle_dump_load(self.assertEqual, NI5, 5) + self.assertEqual(NEI.y.value, 2) + test_pickle_dump_load(self.assertIs, NEI.y) + test_pickle_dump_load(self.assertIs, NEI) + + def test_subclasses_with_getnewargs_ex(self): + class NamedInt(int): + __qualname__ = 'NamedInt' # needed for pickle protocol 4 + def __new__(cls, *args): + _args = args + name, *args = args + if len(args) == 0: + raise TypeError("name and value must be specified") + self = int.__new__(cls, *args) + self._intname = name + self._args = _args + return self + def __getnewargs_ex__(self): + return self._args, {} + @property + def __name__(self): + return self._intname + def __repr__(self): + # repr() is updated to include the name and type info + return "{}({!r}, {})".format(type(self).__name__, + self.__name__, + int.__repr__(self)) + def __str__(self): + # str() is unchanged, even if it relies on the repr() fallback + base = int + base_str = base.__str__ + if base_str.__objclass__ is object: + return base.__repr__(self) + return base_str(self) + # for simplicity, we only define one operator that + # propagates expressions + def __add__(self, other): + temp = int(self) + int( other) + if isinstance(self, NamedInt) and isinstance(other, NamedInt): + return NamedInt( + '({0} + {1})'.format(self.__name__, other.__name__), + temp ) + else: + return temp + + class NEI(NamedInt, Enum): + __qualname__ = 'NEI' # needed for pickle protocol 4 x = ('the-x', 1) y = ('the-y', 2) @@ -912,12 +1088,14 @@ class NEI(NamedInt, Enum): globals()['NEI'] = NEI NI5 = NamedInt('test', 5) self.assertEqual(NI5, 5) - self.assertEqual(loads(dumps(NI5)), 5) + test_pickle_dump_load(self.assertEqual, NI5, 5, protocol=(4, 4)) self.assertEqual(NEI.y.value, 2) - self.assertIs(loads(dumps(NEI.y)), NEI.y) + test_pickle_dump_load(self.assertIs, NEI.y, protocol=(4, 4)) + test_pickle_dump_load(self.assertIs, NEI) - def test_subclasses_without_getnewargs(self): + def test_subclasses_with_reduce(self): class NamedInt(int): + __qualname__ = 'NamedInt' # needed for pickle protocol 4 def __new__(cls, *args): _args = args name, *args = args @@ -927,6 +1105,8 @@ def __new__(cls, *args): self._intname = name self._args = _args return self + def __reduce__(self): + return self.__class__, self._args @property def __name__(self): return self._intname @@ -954,23 +1134,190 @@ def __add__(self, other): return temp class NEI(NamedInt, Enum): + __qualname__ = 'NEI' # needed for pickle protocol 4 x = ('the-x', 1) y = ('the-y', 2) + self.assertIs(NEI.__new__, Enum.__new__) self.assertEqual(repr(NEI.x + NEI.y), "NamedInt('(the-x + the-y)', 3)") globals()['NamedInt'] = NamedInt globals()['NEI'] = NEI NI5 = NamedInt('test', 5) self.assertEqual(NI5, 5) + test_pickle_dump_load(self.assertEqual, NI5, 5) self.assertEqual(NEI.y.value, 2) - with self.assertRaises(TypeError): - dumps(NEI.x) - with self.assertRaises(PicklingError): - dumps(NEI) + test_pickle_dump_load(self.assertIs, NEI.y) + test_pickle_dump_load(self.assertIs, NEI) + + def test_subclasses_with_reduce_ex(self): + class NamedInt(int): + __qualname__ = 'NamedInt' # needed for pickle protocol 4 + def __new__(cls, *args): + _args = args + name, *args = args + if len(args) == 0: + raise TypeError("name and value must be specified") + self = int.__new__(cls, *args) + self._intname = name + self._args = _args + return self + def __reduce_ex__(self, proto): + return self.__class__, self._args + @property + def __name__(self): + return self._intname + def __repr__(self): + # repr() is updated to include the name and type info + return "{}({!r}, {})".format(type(self).__name__, + self.__name__, + int.__repr__(self)) + def __str__(self): + # str() is unchanged, even if it relies on the repr() fallback + base = int + base_str = base.__str__ + if base_str.__objclass__ is object: + return base.__repr__(self) + return base_str(self) + # for simplicity, we only define one operator that + # propagates expressions + def __add__(self, other): + temp = int(self) + int( other) + if isinstance(self, NamedInt) and isinstance(other, NamedInt): + return NamedInt( + '({0} + {1})'.format(self.__name__, other.__name__), + temp ) + else: + return temp + + class NEI(NamedInt, Enum): + __qualname__ = 'NEI' # needed for pickle protocol 4 + x = ('the-x', 1) + y = ('the-y', 2) + + + self.assertIs(NEI.__new__, Enum.__new__) + self.assertEqual(repr(NEI.x + NEI.y), "NamedInt('(the-x + the-y)', 3)") + globals()['NamedInt'] = NamedInt + globals()['NEI'] = NEI + NI5 = NamedInt('test', 5) + self.assertEqual(NI5, 5) + test_pickle_dump_load(self.assertEqual, NI5, 5) + self.assertEqual(NEI.y.value, 2) + test_pickle_dump_load(self.assertIs, NEI.y) + test_pickle_dump_load(self.assertIs, NEI) + + def test_subclasses_without_direct_pickle_support(self): + class NamedInt(int): + __qualname__ = 'NamedInt' + def __new__(cls, *args): + _args = args + name, *args = args + if len(args) == 0: + raise TypeError("name and value must be specified") + self = int.__new__(cls, *args) + self._intname = name + self._args = _args + return self + @property + def __name__(self): + return self._intname + def __repr__(self): + # repr() is updated to include the name and type info + return "{}({!r}, {})".format(type(self).__name__, + self.__name__, + int.__repr__(self)) + def __str__(self): + # str() is unchanged, even if it relies on the repr() fallback + base = int + base_str = base.__str__ + if base_str.__objclass__ is object: + return base.__repr__(self) + return base_str(self) + # for simplicity, we only define one operator that + # propagates expressions + def __add__(self, other): + temp = int(self) + int( other) + if isinstance(self, NamedInt) and isinstance(other, NamedInt): + return NamedInt( + '({0} + {1})'.format(self.__name__, other.__name__), + temp ) + else: + return temp + + class NEI(NamedInt, Enum): + __qualname__ = 'NEI' + x = ('the-x', 1) + y = ('the-y', 2) + + self.assertIs(NEI.__new__, Enum.__new__) + self.assertEqual(repr(NEI.x + NEI.y), "NamedInt('(the-x + the-y)', 3)") + globals()['NamedInt'] = NamedInt + globals()['NEI'] = NEI + NI5 = NamedInt('test', 5) + self.assertEqual(NI5, 5) + self.assertEqual(NEI.y.value, 2) + test_pickle_exception(self.assertRaises, TypeError, NEI.x) + test_pickle_exception(self.assertRaises, PicklingError, NEI) + + def test_subclasses_without_direct_pickle_support_using_name(self): + class NamedInt(int): + __qualname__ = 'NamedInt' + def __new__(cls, *args): + _args = args + name, *args = args + if len(args) == 0: + raise TypeError("name and value must be specified") + self = int.__new__(cls, *args) + self._intname = name + self._args = _args + return self + @property + def __name__(self): + return self._intname + def __repr__(self): + # repr() is updated to include the name and type info + return "{}({!r}, {})".format(type(self).__name__, + self.__name__, + int.__repr__(self)) + def __str__(self): + # str() is unchanged, even if it relies on the repr() fallback + base = int + base_str = base.__str__ + if base_str.__objclass__ is object: + return base.__repr__(self) + return base_str(self) + # for simplicity, we only define one operator that + # propagates expressions + def __add__(self, other): + temp = int(self) + int( other) + if isinstance(self, NamedInt) and isinstance(other, NamedInt): + return NamedInt( + '({0} + {1})'.format(self.__name__, other.__name__), + temp ) + else: + return temp + + class NEI(NamedInt, Enum): + __qualname__ = 'NEI' + x = ('the-x', 1) + y = ('the-y', 2) + def __reduce_ex__(self, proto): + return getattr, (self.__class__, self._name_) + + self.assertIs(NEI.__new__, Enum.__new__) + self.assertEqual(repr(NEI.x + NEI.y), "NamedInt('(the-x + the-y)', 3)") + globals()['NamedInt'] = NamedInt + globals()['NEI'] = NEI + NI5 = NamedInt('test', 5) + self.assertEqual(NI5, 5) + self.assertEqual(NEI.y.value, 2) + test_pickle_dump_load(self.assertIs, NEI.y) + test_pickle_dump_load(self.assertIs, NEI) def test_tuple_subclass(self): class SomeTuple(tuple, Enum): + __qualname__ = 'SomeTuple' # needed for pickle protocol 4 first = (1, 'for the money') second = (2, 'for the show') third = (3, 'for the music') @@ -978,7 +1325,7 @@ class SomeTuple(tuple, Enum): self.assertIsInstance(SomeTuple.second, tuple) self.assertEqual(SomeTuple.third, (3, 'for the music')) globals()['SomeTuple'] = SomeTuple - self.assertIs(loads(dumps(SomeTuple.first)), SomeTuple.first) + test_pickle_dump_load(self.assertIs, SomeTuple.first) def test_duplicate_values_give_unique_enum_items(self): class AutoNumber(Enum): @@ -1259,9 +1606,7 @@ def test_pydoc(self): helper = pydoc.Helper(output=output) helper(self.Color) result = output.getvalue().strip() - if result != expected_text: - print_diffs(expected_text, result) - self.fail("outputs are not equal, see diff above") + self.assertEqual(result, expected_text) def test_inspect_getmembers(self): values = dict(( diff --git a/Lib/test/test_enumerate.py b/Lib/test/test_enumerate.py index 8742afcea8c6..e85254c1de52 100644 --- a/Lib/test/test_enumerate.py +++ b/Lib/test/test_enumerate.py @@ -66,20 +66,21 @@ def __iter__(self): class PickleTest: # Helper to check picklability def check_pickle(self, itorg, seq): - d = pickle.dumps(itorg) - it = pickle.loads(d) - self.assertEqual(type(itorg), type(it)) - self.assertEqual(list(it), seq) - - it = pickle.loads(d) - try: - next(it) - except StopIteration: - self.assertFalse(seq[1:]) - return - d = pickle.dumps(it) - it = pickle.loads(d) - self.assertEqual(list(it), seq[1:]) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + d = pickle.dumps(itorg, proto) + it = pickle.loads(d) + self.assertEqual(type(itorg), type(it)) + self.assertEqual(list(it), seq) + + it = pickle.loads(d) + try: + next(it) + except StopIteration: + self.assertFalse(seq[1:]) + continue + d = pickle.dumps(it, proto) + it = pickle.loads(d) + self.assertEqual(list(it), seq[1:]) class EnumerateTestCase(unittest.TestCase, PickleTest): diff --git a/Lib/test/test_eof.py b/Lib/test/test_eof.py index fb4ac9a639fb..52e7932c1ab0 100644 --- a/Lib/test/test_eof.py +++ b/Lib/test/test_eof.py @@ -1,4 +1,3 @@ -#! /usr/bin/env python3 """test script for a few new invalid token catches""" import unittest diff --git a/Lib/test/test_epoll.py b/Lib/test/test_epoll.py index 6459fbafc8c1..d72740376fde 100644 --- a/Lib/test/test_epoll.py +++ b/Lib/test/test_epoll.py @@ -44,10 +44,9 @@ class TestEPoll(unittest.TestCase): def setUp(self): self.serverSocket = socket.socket() self.serverSocket.bind(('127.0.0.1', 0)) - self.serverSocket.listen(1) + self.serverSocket.listen() self.connections = [self.serverSocket] - def tearDown(self): for skt in self.connections: skt.close() @@ -164,9 +163,9 @@ def test_control_and_wait(self): ep.register(client.fileno(), select.EPOLLIN | select.EPOLLOUT | select.EPOLLET) - now = time.time() + now = time.monotonic() events = ep.poll(1, 4) - then = time.time() + then = time.monotonic() self.assertFalse(then - now > 0.1, then - now) events.sort() @@ -175,19 +174,16 @@ def test_control_and_wait(self): expected.sort() self.assertEqual(events, expected) - self.assertFalse(then - now > 0.01, then - now) - now = time.time() events = ep.poll(timeout=2.1, maxevents=4) - then = time.time() self.assertFalse(events) client.send(b"Hello!") server.send(b"world!!!") - now = time.time() + now = time.monotonic() events = ep.poll(1, 4) - then = time.time() + then = time.monotonic() self.assertFalse(then - now > 0.01) events.sort() @@ -199,9 +195,9 @@ def test_control_and_wait(self): ep.unregister(client.fileno()) ep.modify(server.fileno(), select.EPOLLOUT) - now = time.time() + now = time.monotonic() events = ep.poll(1, 4) - then = time.time() + then = time.monotonic() self.assertFalse(then - now > 0.01) expected = [(server.fileno(), select.EPOLLOUT)] @@ -218,9 +214,9 @@ def test_unregister_closed(self): ep = select.epoll(16) ep.register(server) - now = time.time() + now = time.monotonic() events = ep.poll(1, 4) - then = time.time() + then = time.monotonic() self.assertFalse(then - now > 0.01) server.close() diff --git a/Lib/test/test_errno.py b/Lib/test/test_errno.py old mode 100755 new mode 100644 index f414a87796fc..058dcb9a2355 --- a/Lib/test/test_errno.py +++ b/Lib/test/test_errno.py @@ -1,4 +1,3 @@ -#! /usr/bin/env python3 """Test the errno module Roger E. Masse """ diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index f0851bdbe2e7..28801bd859b9 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -148,6 +148,19 @@ def ckmsg(src, msg): ckmsg(s, "'continue' not properly in loop") ckmsg("continue\n", "'continue' not properly in loop") + def testSyntaxErrorOffset(self): + def check(src, lineno, offset): + with self.assertRaises(SyntaxError) as cm: + compile(src, '', 'exec') + self.assertEqual(cm.exception.lineno, lineno) + self.assertEqual(cm.exception.offset, offset) + + check('def fact(x):\n\treturn x!\n', 2, 10) + check('1 +\n', 1, 4) + check('def spam():\n print(1)\n print(2)', 3, 10) + check('Python = "Python" +', 1, 20) + check('Python = "\u1e54\xfd\u0163\u0125\xf2\xf1" +', 1, 20) + @cpython_only def testSettingException(self): # test that setting an exception at the C level works even if the @@ -253,8 +266,8 @@ def testAttributes(self): (OSError, ('foo', 'bar', 'baz'), {'args' : ('foo', 'bar'), 'filename' : 'baz', 'errno' : 'foo', 'strerror' : 'bar'}), - (OSError, ('foo', 'bar', 'baz', 'quux'), - {'args' : ('foo', 'bar', 'baz', 'quux')}), + (OSError, ('foo', 'bar', 'baz', None, 'quux'), + {'args' : ('foo', 'bar'), 'filename' : 'baz', 'filename2': 'quux'}), (OSError, ('errnoStr', 'strErrorStr', 'filenameStr'), {'args' : ('errnoStr', 'strErrorStr'), 'strerror' : 'strErrorStr', 'errno' : 'errnoStr', @@ -750,7 +763,7 @@ def __del__(self): pass self.assertEqual(e, (None, None, None)) - def testUnicodeChangeAttributes(self): + def test_unicode_change_attributes(self): # See issue 7309. This was a crasher. u = UnicodeEncodeError('baz', 'xxxxx', 1, 5, 'foo') @@ -787,6 +800,12 @@ def testUnicodeChangeAttributes(self): u.start = 1000 self.assertEqual(str(u), "can't translate characters in position 1000-4: 965230951443685724997") + def test_unicode_errors_no_object(self): + # See issue #21134. + klasses = UnicodeEncodeError, UnicodeDecodeError, UnicodeTranslateError + for klass in klasses: + self.assertEqual(str(klass.__new__(klass)), "") + @no_tracing def test_badisinstance(self): # Bug #2542: if issubclass(e, MyException) raises an exception, @@ -819,6 +838,7 @@ def g(): self.assertIn("maximum recursion depth exceeded", str(v)) + @cpython_only def test_MemoryError(self): # PyErr_NoMemory always raises the same exception instance. # Check that the traceback is not doubled. @@ -877,6 +897,7 @@ class C(object): self.assertEqual(error5.a, 1) self.assertEqual(error5.__doc__, "") + @cpython_only def test_memory_error_cleanup(self): # Issue #5437: preallocated MemoryError instances should not keep # traceback objects alive. diff --git a/Lib/test/test_faulthandler.py b/Lib/test/test_faulthandler.py index ebd99edc8fc4..35129b6a7125 100644 --- a/Lib/test/test_faulthandler.py +++ b/Lib/test/test_faulthandler.py @@ -10,12 +10,17 @@ from test.script_helper import assert_python_ok import tempfile import unittest +from textwrap import dedent try: import threading HAVE_THREADS = True except ImportError: HAVE_THREADS = False +try: + import _testcapi +except ImportError: + _testcapi = None TIMEOUT = 0.5 @@ -47,6 +52,7 @@ def get_output(self, code, filename=None): build, and replace "Current thread 0x00007f8d8fbd9700" by "Current thread XXX". """ + code = dedent(code).strip() with support.SuppressCrashReport(): process = script_helper.spawn_python('-c', code) stdout, stderr = process.communicate() @@ -76,15 +82,15 @@ def check_fatal_error(self, code, line_number, name_regex, else: header = 'Stack (most recent call first)' regex = """ -^Fatal Python error: {name} + ^Fatal Python error: {name} -{header}: - File "", line {lineno} in -""".strip() - regex = regex.format( + {header}: + File "", line {lineno} in + """ + regex = dedent(regex.format( lineno=line_number, name=name_regex, - header=re.escape(header)) + header=re.escape(header))).strip() if other_regex: regex += '|' + other_regex output, exitcode = self.get_output(code, filename) @@ -96,29 +102,29 @@ def check_fatal_error(self, code, line_number, name_regex, "the first page of memory is a mapped read-only on AIX") def test_read_null(self): self.check_fatal_error(""" -import faulthandler -faulthandler.enable() -faulthandler._read_null() -""".strip(), + import faulthandler + faulthandler.enable() + faulthandler._read_null() + """, 3, # Issue #12700: Read NULL raises SIGILL on Mac OS X Lion '(?:Segmentation fault|Bus error|Illegal instruction)') def test_sigsegv(self): self.check_fatal_error(""" -import faulthandler -faulthandler.enable() -faulthandler._sigsegv() -""".strip(), + import faulthandler + faulthandler.enable() + faulthandler._sigsegv() + """, 3, 'Segmentation fault') def test_sigabrt(self): self.check_fatal_error(""" -import faulthandler -faulthandler.enable() -faulthandler._sigabrt() -""".strip(), + import faulthandler + faulthandler.enable() + faulthandler._sigabrt() + """, 3, 'Aborted') @@ -126,40 +132,46 @@ def test_sigabrt(self): "SIGFPE cannot be caught on Windows") def test_sigfpe(self): self.check_fatal_error(""" -import faulthandler -faulthandler.enable() -faulthandler._sigfpe() -""".strip(), + import faulthandler + faulthandler.enable() + faulthandler._sigfpe() + """, 3, 'Floating point exception') - @unittest.skipIf(not hasattr(faulthandler, '_sigbus'), - "need faulthandler._sigbus()") + @unittest.skipIf(_testcapi is None, 'need _testcapi') + @unittest.skipUnless(hasattr(signal, 'SIGBUS'), 'need signal.SIGBUS') def test_sigbus(self): self.check_fatal_error(""" -import faulthandler -faulthandler.enable() -faulthandler._sigbus() -""".strip(), - 3, + import _testcapi + import faulthandler + import signal + + faulthandler.enable() + _testcapi.raise_signal(signal.SIGBUS) + """, + 6, 'Bus error') - @unittest.skipIf(not hasattr(faulthandler, '_sigill'), - "need faulthandler._sigill()") + @unittest.skipIf(_testcapi is None, 'need _testcapi') + @unittest.skipUnless(hasattr(signal, 'SIGILL'), 'need signal.SIGILL') def test_sigill(self): self.check_fatal_error(""" -import faulthandler -faulthandler.enable() -faulthandler._sigill() -""".strip(), - 3, + import _testcapi + import faulthandler + import signal + + faulthandler.enable() + _testcapi.raise_signal(signal.SIGILL) + """, + 6, 'Illegal instruction') def test_fatal_error(self): self.check_fatal_error(""" -import faulthandler -faulthandler._fatal_error(b'xyz') -""".strip(), + import faulthandler + faulthandler._fatal_error(b'xyz') + """, 2, 'xyz') @@ -170,55 +182,55 @@ def test_fatal_error(self): 'need faulthandler._stack_overflow()') def test_stack_overflow(self): self.check_fatal_error(""" -import faulthandler -faulthandler.enable() -faulthandler._stack_overflow() -""".strip(), + import faulthandler + faulthandler.enable() + faulthandler._stack_overflow() + """, 3, '(?:Segmentation fault|Bus error)', other_regex='unable to raise a stack overflow') def test_gil_released(self): self.check_fatal_error(""" -import faulthandler -faulthandler.enable() -faulthandler._read_null(True) -""".strip(), + import faulthandler + faulthandler.enable() + faulthandler._sigsegv(True) + """, 3, - '(?:Segmentation fault|Bus error|Illegal instruction)') + 'Segmentation fault') def test_enable_file(self): with temporary_filename() as filename: self.check_fatal_error(""" -import faulthandler -output = open({filename}, 'wb') -faulthandler.enable(output) -faulthandler._sigsegv() -""".strip().format(filename=repr(filename)), + import faulthandler + output = open({filename}, 'wb') + faulthandler.enable(output) + faulthandler._sigsegv() + """.format(filename=repr(filename)), 4, 'Segmentation fault', filename=filename) def test_enable_single_thread(self): self.check_fatal_error(""" -import faulthandler -faulthandler.enable(all_threads=False) -faulthandler._sigsegv() -""".strip(), + import faulthandler + faulthandler.enable(all_threads=False) + faulthandler._sigsegv() + """, 3, 'Segmentation fault', all_threads=False) def test_disable(self): code = """ -import faulthandler -faulthandler.enable() -faulthandler.disable() -faulthandler._sigsegv() -""".strip() + import faulthandler + faulthandler.enable() + faulthandler.disable() + faulthandler._sigsegv() + """ not_expected = 'Fatal Python error' stderr, exitcode = self.get_output(code) - stder = '\n'.join(stderr) + stderr = '\n'.join(stderr) self.assertTrue(not_expected not in stderr, "%r is present in %r" % (not_expected, stderr)) self.assertNotEqual(exitcode, 0) @@ -248,17 +260,25 @@ def test_is_enabled(self): def test_disabled_by_default(self): # By default, the module should be disabled code = "import faulthandler; print(faulthandler.is_enabled())" - args = (sys.executable, '-E', '-c', code) - # don't use assert_python_ok() because it always enable faulthandler - output = subprocess.check_output(args) + args = filter(None, (sys.executable, + "-E" if sys.flags.ignore_environment else "", + "-c", code)) + env = os.environ.copy() + env.pop("PYTHONFAULTHANDLER", None) + # don't use assert_python_ok() because it always enables faulthandler + output = subprocess.check_output(args, env=env) self.assertEqual(output.rstrip(), b"False") def test_sys_xoptions(self): # Test python -X faulthandler code = "import faulthandler; print(faulthandler.is_enabled())" - args = (sys.executable, "-E", "-X", "faulthandler", "-c", code) - # don't use assert_python_ok() because it always enable faulthandler - output = subprocess.check_output(args) + args = filter(None, (sys.executable, + "-E" if sys.flags.ignore_environment else "", + "-X", "faulthandler", "-c", code)) + env = os.environ.copy() + env.pop("PYTHONFAULTHANDLER", None) + # don't use assert_python_ok() because it always enables faulthandler + output = subprocess.check_output(args, env=env) self.assertEqual(output.rstrip(), b"True") def test_env_var(self): @@ -267,7 +287,7 @@ def test_env_var(self): args = (sys.executable, "-c", code) env = os.environ.copy() env['PYTHONFAULTHANDLER'] = '' - # don't use assert_python_ok() because it always enable faulthandler + # don't use assert_python_ok() because it always enables faulthandler output = subprocess.check_output(args, env=env) self.assertEqual(output.rstrip(), b"False") @@ -283,20 +303,20 @@ def check_dump_traceback(self, filename): Raise an error if the output doesn't match the expected format. """ code = """ -import faulthandler + import faulthandler -def funcB(): - if {has_filename}: - with open({filename}, "wb") as fp: - faulthandler.dump_traceback(fp, all_threads=False) - else: - faulthandler.dump_traceback(all_threads=False) + def funcB(): + if {has_filename}: + with open({filename}, "wb") as fp: + faulthandler.dump_traceback(fp, all_threads=False) + else: + faulthandler.dump_traceback(all_threads=False) -def funcA(): - funcB() + def funcA(): + funcB() -funcA() -""".strip() + funcA() + """ code = code.format( filename=repr(filename), has_filename=bool(filename), @@ -327,13 +347,13 @@ def test_truncate(self): func_name = 'x' * (maxlen + 50) truncated = 'x' * maxlen + '...' code = """ -import faulthandler + import faulthandler -def {func_name}(): - faulthandler.dump_traceback(all_threads=False) + def {func_name}(): + faulthandler.dump_traceback(all_threads=False) -{func_name}() -""".strip() + {func_name}() + """ code = code.format( func_name=func_name, ) @@ -353,37 +373,37 @@ def check_dump_traceback_threads(self, filename): Raise an error if the output doesn't match the expected format. """ code = """ -import faulthandler -from threading import Thread, Event -import time - -def dump(): - if {filename}: - with open({filename}, "wb") as fp: - faulthandler.dump_traceback(fp, all_threads=True) - else: - faulthandler.dump_traceback(all_threads=True) - -class Waiter(Thread): - # avoid blocking if the main thread raises an exception. - daemon = True - - def __init__(self): - Thread.__init__(self) - self.running = Event() - self.stop = Event() - - def run(self): - self.running.set() - self.stop.wait() - -waiter = Waiter() -waiter.start() -waiter.running.wait() -dump() -waiter.stop.set() -waiter.join() -""".strip() + import faulthandler + from threading import Thread, Event + import time + + def dump(): + if {filename}: + with open({filename}, "wb") as fp: + faulthandler.dump_traceback(fp, all_threads=True) + else: + faulthandler.dump_traceback(all_threads=True) + + class Waiter(Thread): + # avoid blocking if the main thread raises an exception. + daemon = True + + def __init__(self): + Thread.__init__(self) + self.running = Event() + self.stop = Event() + + def run(self): + self.running.set() + self.stop.wait() + + waiter = Waiter() + waiter.start() + waiter.running.wait() + dump() + waiter.stop.set() + waiter.join() + """ code = code.format(filename=repr(filename)) output, exitcode = self.get_output(code, filename) output = '\n'.join(output) @@ -392,17 +412,17 @@ def run(self): else: lineno = 10 regex = """ -^Thread 0x[0-9a-f]+ \(most recent call first\): -(?: File ".*threading.py", line [0-9]+ in [_a-z]+ -){{1,3}} File "", line 23 in run - File ".*threading.py", line [0-9]+ in _bootstrap_inner - File ".*threading.py", line [0-9]+ in _bootstrap - -Current thread XXX \(most recent call first\): - File "", line {lineno} in dump - File "", line 28 in $ -""".strip() - regex = regex.format(lineno=lineno) + ^Thread 0x[0-9a-f]+ \(most recent call first\): + (?: File ".*threading.py", line [0-9]+ in [_a-z]+ + ){{1,3}} File "", line 23 in run + File ".*threading.py", line [0-9]+ in _bootstrap_inner + File ".*threading.py", line [0-9]+ in _bootstrap + + Current thread XXX \(most recent call first\): + File "", line {lineno} in dump + File "", line 28 in $ + """ + regex = dedent(regex.format(lineno=lineno)).strip() self.assertRegex(output, regex) self.assertEqual(exitcode, 0) @@ -423,29 +443,29 @@ def _check_dump_traceback_later(self, repeat, cancel, filename, loops): """ timeout_str = str(datetime.timedelta(seconds=TIMEOUT)) code = """ -import faulthandler -import time - -def func(timeout, repeat, cancel, file, loops): - for loop in range(loops): - faulthandler.dump_traceback_later(timeout, repeat=repeat, file=file) - if cancel: - faulthandler.cancel_dump_traceback_later() - time.sleep(timeout * 5) - faulthandler.cancel_dump_traceback_later() - -timeout = {timeout} -repeat = {repeat} -cancel = {cancel} -loops = {loops} -if {has_filename}: - file = open({filename}, "wb") -else: - file = None -func(timeout, repeat, cancel, file, loops) -if file is not None: - file.close() -""".strip() + import faulthandler + import time + + def func(timeout, repeat, cancel, file, loops): + for loop in range(loops): + faulthandler.dump_traceback_later(timeout, repeat=repeat, file=file) + if cancel: + faulthandler.cancel_dump_traceback_later() + time.sleep(timeout * 5) + faulthandler.cancel_dump_traceback_later() + + timeout = {timeout} + repeat = {repeat} + cancel = {cancel} + loops = {loops} + if {has_filename}: + file = open({filename}, "wb") + else: + file = None + func(timeout, repeat, cancel, file, loops) + if file is not None: + file.close() + """ code = code.format( timeout=TIMEOUT, repeat=repeat, @@ -512,45 +532,45 @@ def check_register(self, filename=False, all_threads=False, """ signum = signal.SIGUSR1 code = """ -import faulthandler -import os -import signal -import sys + import faulthandler + import os + import signal + import sys -def func(signum): - os.kill(os.getpid(), signum) - -def handler(signum, frame): - handler.called = True -handler.called = False - -exitcode = 0 -signum = {signum} -unregister = {unregister} -chain = {chain} - -if {has_filename}: - file = open({filename}, "wb") -else: - file = None -if chain: - signal.signal(signum, handler) -faulthandler.register(signum, file=file, - all_threads={all_threads}, chain={chain}) -if unregister: - faulthandler.unregister(signum) -func(signum) -if chain and not handler.called: - if file is not None: - output = file - else: - output = sys.stderr - print("Error: signal handler not called!", file=output) - exitcode = 1 -if file is not None: - file.close() -sys.exit(exitcode) -""".strip() + def func(signum): + os.kill(os.getpid(), signum) + + def handler(signum, frame): + handler.called = True + handler.called = False + + exitcode = 0 + signum = {signum} + unregister = {unregister} + chain = {chain} + + if {has_filename}: + file = open({filename}, "wb") + else: + file = None + if chain: + signal.signal(signum, handler) + faulthandler.register(signum, file=file, + all_threads={all_threads}, chain={chain}) + if unregister: + faulthandler.unregister(signum) + func(signum) + if chain and not handler.called: + if file is not None: + output = file + else: + output = sys.stderr + print("Error: signal handler not called!", file=output) + exitcode = 1 + if file is not None: + file.close() + sys.exit(exitcode) + """ code = code.format( filename=repr(filename), has_filename=bool(filename), @@ -591,6 +611,31 @@ def test_register_threads(self): def test_register_chain(self): self.check_register(chain=True) + @contextmanager + def check_stderr_none(self): + stderr = sys.stderr + try: + sys.stderr = None + with self.assertRaises(RuntimeError) as cm: + yield + self.assertEqual(str(cm.exception), "sys.stderr is None") + finally: + sys.stderr = stderr + + def test_stderr_None(self): + # Issue #21497: provide an helpful error if sys.stderr is None, + # instead of just an attribute error: "None has no attribute fileno". + with self.check_stderr_none(): + faulthandler.enable() + with self.check_stderr_none(): + faulthandler.dump_traceback() + if hasattr(faulthandler, 'dump_traceback_later'): + with self.check_stderr_none(): + faulthandler.dump_traceback_later(1e-3) + if hasattr(faulthandler, "register"): + with self.check_stderr_none(): + faulthandler.register(signal.SIGUSR1) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_fcntl.py b/Lib/test/test_fcntl.py index c816d970d750..e3b7ed20a08d 100644 --- a/Lib/test/test_fcntl.py +++ b/Lib/test/test_fcntl.py @@ -4,9 +4,9 @@ import os import struct import sys -import _testcapi import unittest -from test.support import verbose, TESTFN, unlink, run_unittest, import_module +from test.support import (verbose, TESTFN, unlink, run_unittest, import_module, + cpython_only) # Skip test if no fcntl module. fcntl = import_module('fcntl') @@ -45,6 +45,12 @@ def get_lockdata(): lockdata = get_lockdata() +class BadFile: + def __init__(self, fn): + self.fn = fn + def fileno(self): + return self.fn + class TestFcntl(unittest.TestCase): def setUp(self): @@ -78,24 +84,27 @@ def test_fcntl_file_descriptor(self): self.f.close() def test_fcntl_bad_file(self): - class F: - def __init__(self, fn): - self.fn = fn - def fileno(self): - return self.fn - self.assertRaises(ValueError, fcntl.fcntl, -1, fcntl.F_SETFL, os.O_NONBLOCK) - self.assertRaises(ValueError, fcntl.fcntl, F(-1), fcntl.F_SETFL, os.O_NONBLOCK) - self.assertRaises(TypeError, fcntl.fcntl, 'spam', fcntl.F_SETFL, os.O_NONBLOCK) - self.assertRaises(TypeError, fcntl.fcntl, F('spam'), fcntl.F_SETFL, os.O_NONBLOCK) + with self.assertRaises(ValueError): + fcntl.fcntl(-1, fcntl.F_SETFL, os.O_NONBLOCK) + with self.assertRaises(ValueError): + fcntl.fcntl(BadFile(-1), fcntl.F_SETFL, os.O_NONBLOCK) + with self.assertRaises(TypeError): + fcntl.fcntl('spam', fcntl.F_SETFL, os.O_NONBLOCK) + with self.assertRaises(TypeError): + fcntl.fcntl(BadFile('spam'), fcntl.F_SETFL, os.O_NONBLOCK) + + @cpython_only + def test_fcntl_bad_file_overflow(self): + from _testcapi import INT_MAX, INT_MIN # Issue 15989 - self.assertRaises(OverflowError, fcntl.fcntl, _testcapi.INT_MAX + 1, - fcntl.F_SETFL, os.O_NONBLOCK) - self.assertRaises(OverflowError, fcntl.fcntl, F(_testcapi.INT_MAX + 1), - fcntl.F_SETFL, os.O_NONBLOCK) - self.assertRaises(OverflowError, fcntl.fcntl, _testcapi.INT_MIN - 1, - fcntl.F_SETFL, os.O_NONBLOCK) - self.assertRaises(OverflowError, fcntl.fcntl, F(_testcapi.INT_MIN - 1), - fcntl.F_SETFL, os.O_NONBLOCK) + with self.assertRaises(OverflowError): + fcntl.fcntl(INT_MAX + 1, fcntl.F_SETFL, os.O_NONBLOCK) + with self.assertRaises(OverflowError): + fcntl.fcntl(BadFile(INT_MAX + 1), fcntl.F_SETFL, os.O_NONBLOCK) + with self.assertRaises(OverflowError): + fcntl.fcntl(INT_MIN - 1, fcntl.F_SETFL, os.O_NONBLOCK) + with self.assertRaises(OverflowError): + fcntl.fcntl(BadFile(INT_MIN - 1), fcntl.F_SETFL, os.O_NONBLOCK) @unittest.skipIf( platform.machine().startswith('arm') and platform.system() == 'Linux', @@ -115,6 +124,26 @@ def test_fcntl_64_bit(self): finally: os.close(fd) + def test_flock(self): + # Solaris needs readable file for shared lock + self.f = open(TESTFN, 'wb+') + fileno = self.f.fileno() + fcntl.flock(fileno, fcntl.LOCK_SH) + fcntl.flock(fileno, fcntl.LOCK_UN) + fcntl.flock(self.f, fcntl.LOCK_SH | fcntl.LOCK_NB) + fcntl.flock(self.f, fcntl.LOCK_UN) + fcntl.flock(fileno, fcntl.LOCK_EX) + fcntl.flock(fileno, fcntl.LOCK_UN) + + self.assertRaises(ValueError, fcntl.flock, -1, fcntl.LOCK_SH) + self.assertRaises(TypeError, fcntl.flock, 'spam', fcntl.LOCK_SH) + + @cpython_only + def test_flock_overflow(self): + import _testcapi + self.assertRaises(OverflowError, fcntl.flock, _testcapi.INT_MAX+1, + fcntl.LOCK_SH) + def test_main(): run_unittest(TestFcntl) diff --git a/Lib/test/test_filecmp.py b/Lib/test/test_filecmp.py index c7cb3fcf3677..b5b24a24c8dd 100644 --- a/Lib/test/test_filecmp.py +++ b/Lib/test/test_filecmp.py @@ -1,7 +1,12 @@ -import os, filecmp, shutil, tempfile +import filecmp +import os +import shutil +import tempfile import unittest + from test import support + class FileCompareTestCase(unittest.TestCase): def setUp(self): self.name = support.TESTFN @@ -9,13 +14,11 @@ def setUp(self): self.name_diff = support.TESTFN + '-diff' data = 'Contents of file go here.\n' for name in [self.name, self.name_same, self.name_diff]: - output = open(name, 'w') - output.write(data) - output.close() + with open(name, 'w') as output: + output.write(data) - output = open(self.name_diff, 'a+') - output.write('An extra line.\n') - output.close() + with open(self.name_diff, 'a+') as output: + output.write('An extra line.\n') self.dir = tempfile.gettempdir() def tearDown(self): @@ -24,13 +27,13 @@ def tearDown(self): os.unlink(self.name_diff) def test_matching(self): - self.assertTrue(filecmp.cmp(self.name, self.name_same), - "Comparing file to itself fails") - self.assertTrue(filecmp.cmp(self.name, self.name_same, shallow=False), + self.assertTrue(filecmp.cmp(self.name, self.name), "Comparing file to itself fails") self.assertTrue(filecmp.cmp(self.name, self.name, shallow=False), + "Comparing file to itself fails") + self.assertTrue(filecmp.cmp(self.name, self.name_same), "Comparing file to identical file fails") - self.assertTrue(filecmp.cmp(self.name, self.name), + self.assertTrue(filecmp.cmp(self.name, self.name_same, shallow=False), "Comparing file to identical file fails") def test_different(self): @@ -66,13 +69,11 @@ def setUp(self): fn = 'FiLe' # Verify case-insensitive comparison else: fn = 'file' - output = open(os.path.join(dir, fn), 'w') - output.write(data) - output.close() + with open(os.path.join(dir, fn), 'w') as output: + output.write(data) - output = open(os.path.join(self.dir_diff, 'file2'), 'w') - output.write('An extra file.\n') - output.close() + with open(os.path.join(self.dir_diff, 'file2'), 'w') as output: + output.write('An extra file.\n') def tearDown(self): for dir in (self.dir, self.dir_same, self.dir_diff): @@ -99,9 +100,8 @@ def test_cmpfiles(self): "Comparing directory to same fails") # Add different file2 - output = open(os.path.join(self.dir, 'file2'), 'w') - output.write('Different contents.\n') - output.close() + with open(os.path.join(self.dir, 'file2'), 'w') as output: + output.write('Different contents.\n') self.assertFalse(filecmp.cmpfiles(self.dir, self.dir_same, ['file', 'file2']) == @@ -120,30 +120,94 @@ def test_dircmp(self): else: self.assertEqual([d.left_list, d.right_list],[['file'], ['file']]) self.assertEqual(d.common, ['file']) - self.assertTrue(d.left_only == d.right_only == []) + self.assertEqual(d.left_only, []) + self.assertEqual(d.right_only, []) self.assertEqual(d.same_files, ['file']) self.assertEqual(d.diff_files, []) + expected_report = [ + "diff {} {}".format(self.dir, self.dir_same), + "Identical files : ['file']", + ] + self._assert_report(d.report, expected_report) - # Check attributes for comparison of two different directories + # Check attributes for comparison of two different directories (right) left_dir, right_dir = self.dir, self.dir_diff d = filecmp.dircmp(left_dir, right_dir) self.assertEqual(d.left, left_dir) self.assertEqual(d.right, right_dir) self.assertEqual(d.left_list, ['file']) - self.assertTrue(d.right_list == ['file', 'file2']) + self.assertEqual(d.right_list, ['file', 'file2']) self.assertEqual(d.common, ['file']) self.assertEqual(d.left_only, []) self.assertEqual(d.right_only, ['file2']) self.assertEqual(d.same_files, ['file']) self.assertEqual(d.diff_files, []) + expected_report = [ + "diff {} {}".format(self.dir, self.dir_diff), + "Only in {} : ['file2']".format(self.dir_diff), + "Identical files : ['file']", + ] + self._assert_report(d.report, expected_report) + + # Check attributes for comparison of two different directories (left) + left_dir, right_dir = self.dir, self.dir_diff + shutil.move( + os.path.join(self.dir_diff, 'file2'), + os.path.join(self.dir, 'file2') + ) + d = filecmp.dircmp(left_dir, right_dir) + self.assertEqual(d.left, left_dir) + self.assertEqual(d.right, right_dir) + self.assertEqual(d.left_list, ['file', 'file2']) + self.assertEqual(d.right_list, ['file']) + self.assertEqual(d.common, ['file']) + self.assertEqual(d.left_only, ['file2']) + self.assertEqual(d.right_only, []) + self.assertEqual(d.same_files, ['file']) + self.assertEqual(d.diff_files, []) + expected_report = [ + "diff {} {}".format(self.dir, self.dir_diff), + "Only in {} : ['file2']".format(self.dir), + "Identical files : ['file']", + ] + self._assert_report(d.report, expected_report) # Add different file2 - output = open(os.path.join(self.dir, 'file2'), 'w') - output.write('Different contents.\n') - output.close() + with open(os.path.join(self.dir_diff, 'file2'), 'w') as output: + output.write('Different contents.\n') d = filecmp.dircmp(self.dir, self.dir_diff) self.assertEqual(d.same_files, ['file']) self.assertEqual(d.diff_files, ['file2']) + expected_report = [ + "diff {} {}".format(self.dir, self.dir_diff), + "Identical files : ['file']", + "Differing files : ['file2']", + ] + self._assert_report(d.report, expected_report) + + def test_report_partial_closure(self): + left_dir, right_dir = self.dir, self.dir_same + d = filecmp.dircmp(left_dir, right_dir) + expected_report = [ + "diff {} {}".format(self.dir, self.dir_same), + "Identical files : ['file']", + ] + self._assert_report(d.report_partial_closure, expected_report) + + def test_report_full_closure(self): + left_dir, right_dir = self.dir, self.dir_same + d = filecmp.dircmp(left_dir, right_dir) + expected_report = [ + "diff {} {}".format(self.dir, self.dir_same), + "Identical files : ['file']", + ] + self._assert_report(d.report_full_closure, expected_report) + + def _assert_report(self, dircmp_report, expected_report_lines): + with support.captured_stdout() as stdout: + dircmp_report() + report_lines = stdout.getvalue().strip().split('\n') + self.assertEqual(report_lines, expected_report_lines) def test_main(): diff --git a/Lib/test/test_fileinput.py b/Lib/test/test_fileinput.py index db6082cb12e6..1d089f52b8a7 100644 --- a/Lib/test/test_fileinput.py +++ b/Lib/test/test_fileinput.py @@ -19,11 +19,12 @@ except ImportError: gzip = None -from io import StringIO +from io import BytesIO, StringIO from fileinput import FileInput, hook_encoded from test.support import verbose, TESTFN, run_unittest, check_warnings from test.support import unlink as safe_unlink +from unittest import mock # The fileinput module has 2 interfaces: the FileInput class which does @@ -232,6 +233,13 @@ def test_opening_mode(self): finally: remove_tempfiles(t1) + def test_stdin_binary_mode(self): + with mock.patch('sys.stdin') as m_stdin: + m_stdin.buffer = BytesIO(b'spam, bacon, sausage, and spam') + fi = FileInput(files=['-'], mode='rb') + lines = list(fi) + self.assertEqual(lines, [b'spam, bacon, sausage, and spam']) + def test_file_opening_hook(self): try: # cannot use openhook and inplace mode @@ -260,6 +268,27 @@ def __call__(self, *args): fi.readline() self.assertTrue(custom_open_hook.invoked, "openhook not invoked") + def test_readline(self): + with open(TESTFN, 'wb') as f: + f.write(b'A\nB\r\nC\r') + # Fill TextIOWrapper buffer. + f.write(b'123456789\n' * 1000) + # Issue #20501: readline() shouldn't read whole file. + f.write(b'\x80') + self.addCleanup(safe_unlink, TESTFN) + + with FileInput(files=TESTFN, + openhook=hook_encoded('ascii'), bufsize=8) as fi: + try: + self.assertEqual(fi.readline(), 'A\n') + self.assertEqual(fi.readline(), 'B\n') + self.assertEqual(fi.readline(), 'C\n') + except UnicodeDecodeError: + self.fail('Read to end of file') + with self.assertRaises(UnicodeDecodeError): + # Read to the end of file. + list(fi) + def test_context_manager(self): try: t1 = writeTmp(1, ["A\nB\nC"]) @@ -837,6 +866,26 @@ def test(self): self.assertIs(kwargs.pop('encoding'), encoding) self.assertFalse(kwargs) + def test_modes(self): + with open(TESTFN, 'wb') as f: + # UTF-7 is a convenient, seldom used encoding + f.write(b'A\nB\r\nC\rD+IKw-') + self.addCleanup(safe_unlink, TESTFN) + + def check(mode, expected_lines): + with FileInput(files=TESTFN, mode=mode, + openhook=hook_encoded('utf-7')) as fi: + lines = list(fi) + self.assertEqual(lines, expected_lines) + + check('r', ['A\n', 'B\n', 'C\n', 'D\u20ac']) + with self.assertWarns(DeprecationWarning): + check('rU', ['A\n', 'B\n', 'C\n', 'D\u20ac']) + with self.assertWarns(DeprecationWarning): + check('U', ['A\n', 'B\n', 'C\n', 'D\u20ac']) + with self.assertRaises(ValueError): + check('rb', ['A\n', 'B\r\n', 'C\r', 'D\u20ac']) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_fileio.py b/Lib/test/test_fileio.py index e67876985e9b..743ca5c73ce1 100644 --- a/Lib/test/test_fileio.py +++ b/Lib/test/test_fileio.py @@ -8,9 +8,8 @@ from array import array from weakref import proxy from functools import wraps -import _testcapi -from test.support import TESTFN, check_warnings, run_unittest, make_bad_fd +from test.support import TESTFN, check_warnings, run_unittest, make_bad_fd, cpython_only from collections import UserList from _io import FileIO as _FileIO @@ -61,6 +60,15 @@ def testAttributes(self): self.assertRaises((AttributeError, TypeError), setattr, f, attr, 'oops') + def testBlksize(self): + # test private _blksize attribute + blksize = io.DEFAULT_BUFFER_SIZE + # try to get preferred blksize from stat.st_blksize, if available + if hasattr(os, 'fstat'): + fst = os.fstat(self.f.fileno()) + blksize = getattr(fst, 'st_blksize', blksize) + self.assertEqual(self.f._blksize, blksize) + def testReadinto(self): # verify readinto self.f.write(bytes([1, 2])) @@ -104,14 +112,26 @@ def test_reject(self): self.assertRaises(TypeError, self.f.write, "Hello!") def testRepr(self): - self.assertEqual(repr(self.f), "<_io.FileIO name=%r mode=%r>" - % (self.f.name, self.f.mode)) + self.assertEqual( + repr(self.f), "<_io.FileIO name=%r mode=%r closefd=True>" + % (self.f.name, self.f.mode)) del self.f.name - self.assertEqual(repr(self.f), "<_io.FileIO fd=%r mode=%r>" - % (self.f.fileno(), self.f.mode)) + self.assertEqual( + repr(self.f), "<_io.FileIO fd=%r mode=%r closefd=True>" + % (self.f.fileno(), self.f.mode)) self.f.close() self.assertEqual(repr(self.f), "<_io.FileIO [closed]>") + def testReprNoCloseFD(self): + fd = os.open(TESTFN, os.O_RDONLY) + try: + with _FileIO(fd, 'r', closefd=False) as f: + self.assertEqual(repr(f), + "<_io.FileIO name=%r mode=%r closefd=False>" + % (f.name, f.mode)) + finally: + os.close(fd) + def testErrors(self): f = self.f self.assertTrue(not f.isatty()) @@ -142,7 +162,7 @@ def testMethods(self): def testOpendir(self): # Issue 3703: opening a directory should fill the errno # Windows always returns "[Errno 13]: Permission denied - # Unix calls dircheck() and returns "[Errno 21]: Is a directory" + # Unix uses fstat and returns "[Errno 21]: Is a directory" try: _FileIO('.', 'r') except OSError as e: @@ -341,8 +361,7 @@ def testBytesOpen(self): try: fn = TESTFN.encode("ascii") except UnicodeEncodeError: - # Skip test - return + self.skipTest('could not encode %r to ascii' % TESTFN) f = _FileIO(fn, "w") try: f.write(b"abc") @@ -354,8 +373,8 @@ def testBytesOpen(self): def testConstructorHandlesNULChars(self): fn_with_NUL = 'foo\0bar' - self.assertRaises(TypeError, _FileIO, fn_with_NUL, 'w') - self.assertRaises(TypeError, _FileIO, bytes(fn_with_NUL, 'ascii'), 'w') + self.assertRaises(ValueError, _FileIO, fn_with_NUL, 'w') + self.assertRaises(ValueError, _FileIO, bytes(fn_with_NUL, 'ascii'), 'w') def testInvalidFd(self): self.assertRaises(ValueError, _FileIO, -10) @@ -363,7 +382,11 @@ def testInvalidFd(self): if sys.platform == 'win32': import msvcrt self.assertRaises(OSError, msvcrt.get_osfhandle, make_bad_fd()) + + @cpython_only + def testInvalidFd_overflow(self): # Issue 15989 + import _testcapi self.assertRaises(TypeError, _FileIO, _testcapi.INT_MAX + 1) self.assertRaises(TypeError, _FileIO, _testcapi.INT_MIN - 1) diff --git a/Lib/test/test_finalization.py b/Lib/test/test_finalization.py index 80c9b8798878..03ac1aa274da 100644 --- a/Lib/test/test_finalization.py +++ b/Lib/test/test_finalization.py @@ -7,7 +7,15 @@ import unittest import weakref -import _testcapi +try: + from _testcapi import with_tp_del +except ImportError: + def with_tp_del(cls): + class C(object): + def __new__(cls, *args, **kwargs): + raise TypeError('requires _testcapi.with_tp_del') + return C + from test import support @@ -423,11 +431,11 @@ def __tp_del__(self): except Exception as e: self.errors.append(e) -@_testcapi.with_tp_del +@with_tp_del class Legacy(LegacyBase): pass -@_testcapi.with_tp_del +@with_tp_del class LegacyResurrector(LegacyBase): def side_effect(self): @@ -436,11 +444,12 @@ def side_effect(self): """ self.survivors.append(self) -@_testcapi.with_tp_del +@with_tp_del class LegacySelfCycle(SelfCycleBase, LegacyBase): pass +@support.cpython_only class LegacyFinalizationTest(TestBase, unittest.TestCase): """ Test finalization of objects with a tp_del. diff --git a/Lib/test/test_float.py b/Lib/test/test_float.py index 5c2dc3ff3bcd..e1e1f0423ea2 100644 --- a/Lib/test/test_float.py +++ b/Lib/test/test_float.py @@ -71,7 +71,7 @@ def test_float_with_comma(self): # it still has to accept the normal python syntax import locale if not locale.localeconv()['decimal_point'] == ',': - return + self.skipTest('decimal_point is not ","') self.assertEqual(float(" 3.14 "), 3.14) self.assertEqual(float("+3.14 "), 3.14) diff --git a/Lib/test/test_fork1.py b/Lib/test/test_fork1.py index e0626dffdcb9..8bcbd465cc32 100644 --- a/Lib/test/test_fork1.py +++ b/Lib/test/test_fork1.py @@ -18,13 +18,14 @@ class ForkTest(ForkWait): def wait_impl(self, cpid): - for i in range(10): + deadline = time.monotonic() + 10.0 + while time.monotonic() <= deadline: # waitpid() shouldn't hang, but some of the buildbots seem to hang # in the forking tests. This is an attempt to fix the problem. spid, status = os.waitpid(cpid, os.WNOHANG) if spid == cpid: break - time.sleep(1.0) + time.sleep(0.1) self.assertEqual(spid, cpid) self.assertEqual(status, 0, "cause = %d, exit = %d" % (status&0xff, status>>8)) diff --git a/Lib/test/test_format.py b/Lib/test/test_format.py index 29330f917132..9d1f5d33029c 100644 --- a/Lib/test/test_format.py +++ b/Lib/test/test_format.py @@ -9,7 +9,7 @@ # test string formatting operator (I am not sure if this is being tested # elsewhere but, surely, some of the given cases are *not* tested because # they crash python) -# test on unicode strings as well +# test on bytes object as well def testformat(formatstr, args, output=None, limit=None, overflowok=False): if verbose: @@ -46,186 +46,209 @@ def testformat(formatstr, args, output=None, limit=None, overflowok=False): if verbose: print('yes') +def testcommon(formatstr, args, output=None, limit=None, overflowok=False): + # if formatstr is a str, test str, bytes, and bytearray; + # otherwise, test bytes and bytearry + if isinstance(formatstr, str): + testformat(formatstr, args, output, limit, overflowok) + b_format = formatstr.encode('ascii') + else: + b_format = formatstr + ba_format = bytearray(b_format) + b_args = [] + if not isinstance(args, tuple): + args = (args, ) + b_args = tuple(args) + if output is None: + b_output = ba_output = None + else: + if isinstance(output, str): + b_output = output.encode('ascii') + else: + b_output = output + ba_output = bytearray(b_output) + testformat(b_format, b_args, b_output, limit, overflowok) + testformat(ba_format, b_args, ba_output, limit, overflowok) + class FormatTest(unittest.TestCase): - def test_format(self): - testformat("%.1d", (1,), "1") - testformat("%.*d", (sys.maxsize,1), overflowok=True) # expect overflow - testformat("%.100d", (1,), '00000000000000000000000000000000000000' + + def test_common_format(self): + # test the format identifiers that work the same across + # str, bytes, and bytearrays (integer, float, oct, hex) + testcommon("%.1d", (1,), "1") + testcommon("%.*d", (sys.maxsize,1), overflowok=True) # expect overflow + testcommon("%.100d", (1,), '00000000000000000000000000000000000000' '000000000000000000000000000000000000000000000000000000' '00000001', overflowok=True) - testformat("%#.117x", (1,), '0x00000000000000000000000000000000000' + testcommon("%#.117x", (1,), '0x00000000000000000000000000000000000' '000000000000000000000000000000000000000000000000000000' '0000000000000000000000000001', overflowok=True) - testformat("%#.118x", (1,), '0x00000000000000000000000000000000000' + testcommon("%#.118x", (1,), '0x00000000000000000000000000000000000' '000000000000000000000000000000000000000000000000000000' '00000000000000000000000000001', overflowok=True) - testformat("%f", (1.0,), "1.000000") + testcommon("%f", (1.0,), "1.000000") # these are trying to test the limits of the internal magic-number-length # formatting buffer, if that number changes then these tests are less # effective - testformat("%#.*g", (109, -1.e+49/3.)) - testformat("%#.*g", (110, -1.e+49/3.)) - testformat("%#.*g", (110, -1.e+100/3.)) + testcommon("%#.*g", (109, -1.e+49/3.)) + testcommon("%#.*g", (110, -1.e+49/3.)) + testcommon("%#.*g", (110, -1.e+100/3.)) # test some ridiculously large precision, expect overflow - testformat('%12.*f', (123456, 1.0)) + testcommon('%12.*f', (123456, 1.0)) # check for internal overflow validation on length of precision # these tests should no longer cause overflow in Python # 2.7/3.1 and later. - testformat("%#.*g", (110, -1.e+100/3.)) - testformat("%#.*G", (110, -1.e+100/3.)) - testformat("%#.*f", (110, -1.e+100/3.)) - testformat("%#.*F", (110, -1.e+100/3.)) + testcommon("%#.*g", (110, -1.e+100/3.)) + testcommon("%#.*G", (110, -1.e+100/3.)) + testcommon("%#.*f", (110, -1.e+100/3.)) + testcommon("%#.*F", (110, -1.e+100/3.)) # Formatting of integers. Overflow is not ok - testformat("%x", 10, "a") - testformat("%x", 100000000000, "174876e800") - testformat("%o", 10, "12") - testformat("%o", 100000000000, "1351035564000") - testformat("%d", 10, "10") - testformat("%d", 100000000000, "100000000000") + testcommon("%x", 10, "a") + testcommon("%x", 100000000000, "174876e800") + testcommon("%o", 10, "12") + testcommon("%o", 100000000000, "1351035564000") + testcommon("%d", 10, "10") + testcommon("%d", 100000000000, "100000000000") big = 123456789012345678901234567890 - testformat("%d", big, "123456789012345678901234567890") - testformat("%d", -big, "-123456789012345678901234567890") - testformat("%5d", -big, "-123456789012345678901234567890") - testformat("%31d", -big, "-123456789012345678901234567890") - testformat("%32d", -big, " -123456789012345678901234567890") - testformat("%-32d", -big, "-123456789012345678901234567890 ") - testformat("%032d", -big, "-0123456789012345678901234567890") - testformat("%-032d", -big, "-123456789012345678901234567890 ") - testformat("%034d", -big, "-000123456789012345678901234567890") - testformat("%034d", big, "0000123456789012345678901234567890") - testformat("%0+34d", big, "+000123456789012345678901234567890") - testformat("%+34d", big, " +123456789012345678901234567890") - testformat("%34d", big, " 123456789012345678901234567890") - testformat("%.2d", big, "123456789012345678901234567890") - testformat("%.30d", big, "123456789012345678901234567890") - testformat("%.31d", big, "0123456789012345678901234567890") - testformat("%32.31d", big, " 0123456789012345678901234567890") - testformat("%d", float(big), "123456________________________", 6) + testcommon("%d", big, "123456789012345678901234567890") + testcommon("%d", -big, "-123456789012345678901234567890") + testcommon("%5d", -big, "-123456789012345678901234567890") + testcommon("%31d", -big, "-123456789012345678901234567890") + testcommon("%32d", -big, " -123456789012345678901234567890") + testcommon("%-32d", -big, "-123456789012345678901234567890 ") + testcommon("%032d", -big, "-0123456789012345678901234567890") + testcommon("%-032d", -big, "-123456789012345678901234567890 ") + testcommon("%034d", -big, "-000123456789012345678901234567890") + testcommon("%034d", big, "0000123456789012345678901234567890") + testcommon("%0+34d", big, "+000123456789012345678901234567890") + testcommon("%+34d", big, " +123456789012345678901234567890") + testcommon("%34d", big, " 123456789012345678901234567890") + testcommon("%.2d", big, "123456789012345678901234567890") + testcommon("%.30d", big, "123456789012345678901234567890") + testcommon("%.31d", big, "0123456789012345678901234567890") + testcommon("%32.31d", big, " 0123456789012345678901234567890") + testcommon("%d", float(big), "123456________________________", 6) big = 0x1234567890abcdef12345 # 21 hex digits - testformat("%x", big, "1234567890abcdef12345") - testformat("%x", -big, "-1234567890abcdef12345") - testformat("%5x", -big, "-1234567890abcdef12345") - testformat("%22x", -big, "-1234567890abcdef12345") - testformat("%23x", -big, " -1234567890abcdef12345") - testformat("%-23x", -big, "-1234567890abcdef12345 ") - testformat("%023x", -big, "-01234567890abcdef12345") - testformat("%-023x", -big, "-1234567890abcdef12345 ") - testformat("%025x", -big, "-0001234567890abcdef12345") - testformat("%025x", big, "00001234567890abcdef12345") - testformat("%0+25x", big, "+0001234567890abcdef12345") - testformat("%+25x", big, " +1234567890abcdef12345") - testformat("%25x", big, " 1234567890abcdef12345") - testformat("%.2x", big, "1234567890abcdef12345") - testformat("%.21x", big, "1234567890abcdef12345") - testformat("%.22x", big, "01234567890abcdef12345") - testformat("%23.22x", big, " 01234567890abcdef12345") - testformat("%-23.22x", big, "01234567890abcdef12345 ") - testformat("%X", big, "1234567890ABCDEF12345") - testformat("%#X", big, "0X1234567890ABCDEF12345") - testformat("%#x", big, "0x1234567890abcdef12345") - testformat("%#x", -big, "-0x1234567890abcdef12345") - testformat("%#.23x", -big, "-0x001234567890abcdef12345") - testformat("%#+.23x", big, "+0x001234567890abcdef12345") - testformat("%# .23x", big, " 0x001234567890abcdef12345") - testformat("%#+.23X", big, "+0X001234567890ABCDEF12345") - testformat("%#-+.23X", big, "+0X001234567890ABCDEF12345") - testformat("%#-+26.23X", big, "+0X001234567890ABCDEF12345") - testformat("%#-+27.23X", big, "+0X001234567890ABCDEF12345 ") - testformat("%#+27.23X", big, " +0X001234567890ABCDEF12345") + testcommon("%x", big, "1234567890abcdef12345") + testcommon("%x", -big, "-1234567890abcdef12345") + testcommon("%5x", -big, "-1234567890abcdef12345") + testcommon("%22x", -big, "-1234567890abcdef12345") + testcommon("%23x", -big, " -1234567890abcdef12345") + testcommon("%-23x", -big, "-1234567890abcdef12345 ") + testcommon("%023x", -big, "-01234567890abcdef12345") + testcommon("%-023x", -big, "-1234567890abcdef12345 ") + testcommon("%025x", -big, "-0001234567890abcdef12345") + testcommon("%025x", big, "00001234567890abcdef12345") + testcommon("%0+25x", big, "+0001234567890abcdef12345") + testcommon("%+25x", big, " +1234567890abcdef12345") + testcommon("%25x", big, " 1234567890abcdef12345") + testcommon("%.2x", big, "1234567890abcdef12345") + testcommon("%.21x", big, "1234567890abcdef12345") + testcommon("%.22x", big, "01234567890abcdef12345") + testcommon("%23.22x", big, " 01234567890abcdef12345") + testcommon("%-23.22x", big, "01234567890abcdef12345 ") + testcommon("%X", big, "1234567890ABCDEF12345") + testcommon("%#X", big, "0X1234567890ABCDEF12345") + testcommon("%#x", big, "0x1234567890abcdef12345") + testcommon("%#x", -big, "-0x1234567890abcdef12345") + testcommon("%#.23x", -big, "-0x001234567890abcdef12345") + 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 - testformat("%#+027.23X", big, "+0X0001234567890ABCDEF12345") + testcommon("%#+027.23X", big, "+0X0001234567890ABCDEF12345") # same, except no 0 flag - testformat("%#+27.23X", big, " +0X001234567890ABCDEF12345") - testformat("%x", float(big), "123456_______________", 6) + testcommon("%#+27.23X", big, " +0X001234567890ABCDEF12345") big = 0o12345670123456701234567012345670 # 32 octal digits - testformat("%o", big, "12345670123456701234567012345670") - testformat("%o", -big, "-12345670123456701234567012345670") - testformat("%5o", -big, "-12345670123456701234567012345670") - testformat("%33o", -big, "-12345670123456701234567012345670") - testformat("%34o", -big, " -12345670123456701234567012345670") - testformat("%-34o", -big, "-12345670123456701234567012345670 ") - testformat("%034o", -big, "-012345670123456701234567012345670") - testformat("%-034o", -big, "-12345670123456701234567012345670 ") - testformat("%036o", -big, "-00012345670123456701234567012345670") - testformat("%036o", big, "000012345670123456701234567012345670") - testformat("%0+36o", big, "+00012345670123456701234567012345670") - testformat("%+36o", big, " +12345670123456701234567012345670") - testformat("%36o", big, " 12345670123456701234567012345670") - testformat("%.2o", big, "12345670123456701234567012345670") - testformat("%.32o", big, "12345670123456701234567012345670") - testformat("%.33o", big, "012345670123456701234567012345670") - testformat("%34.33o", big, " 012345670123456701234567012345670") - testformat("%-34.33o", big, "012345670123456701234567012345670 ") - testformat("%o", big, "12345670123456701234567012345670") - testformat("%#o", big, "0o12345670123456701234567012345670") - testformat("%#o", -big, "-0o12345670123456701234567012345670") - testformat("%#.34o", -big, "-0o0012345670123456701234567012345670") - testformat("%#+.34o", big, "+0o0012345670123456701234567012345670") - testformat("%# .34o", big, " 0o0012345670123456701234567012345670") - testformat("%#+.34o", big, "+0o0012345670123456701234567012345670") - testformat("%#-+.34o", big, "+0o0012345670123456701234567012345670") - testformat("%#-+37.34o", big, "+0o0012345670123456701234567012345670") - testformat("%#+37.34o", big, "+0o0012345670123456701234567012345670") + testcommon("%o", big, "12345670123456701234567012345670") + testcommon("%o", -big, "-12345670123456701234567012345670") + testcommon("%5o", -big, "-12345670123456701234567012345670") + testcommon("%33o", -big, "-12345670123456701234567012345670") + testcommon("%34o", -big, " -12345670123456701234567012345670") + testcommon("%-34o", -big, "-12345670123456701234567012345670 ") + testcommon("%034o", -big, "-012345670123456701234567012345670") + testcommon("%-034o", -big, "-12345670123456701234567012345670 ") + testcommon("%036o", -big, "-00012345670123456701234567012345670") + testcommon("%036o", big, "000012345670123456701234567012345670") + testcommon("%0+36o", big, "+00012345670123456701234567012345670") + testcommon("%+36o", big, " +12345670123456701234567012345670") + testcommon("%36o", big, " 12345670123456701234567012345670") + testcommon("%.2o", big, "12345670123456701234567012345670") + testcommon("%.32o", big, "12345670123456701234567012345670") + testcommon("%.33o", big, "012345670123456701234567012345670") + testcommon("%34.33o", big, " 012345670123456701234567012345670") + testcommon("%-34.33o", big, "012345670123456701234567012345670 ") + testcommon("%o", big, "12345670123456701234567012345670") + testcommon("%#o", big, "0o12345670123456701234567012345670") + testcommon("%#o", -big, "-0o12345670123456701234567012345670") + testcommon("%#.34o", -big, "-0o0012345670123456701234567012345670") + 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") # next one gets one leading zero from precision - testformat("%.33o", big, "012345670123456701234567012345670") + testcommon("%.33o", big, "012345670123456701234567012345670") # base marker shouldn't change that, since "0" is redundant - testformat("%#.33o", big, "0o012345670123456701234567012345670") + testcommon("%#.33o", big, "0o012345670123456701234567012345670") # but reduce precision, and base marker should add a zero - testformat("%#.32o", big, "0o12345670123456701234567012345670") + testcommon("%#.32o", big, "0o12345670123456701234567012345670") # one leading zero from precision, and another from "0" flag & width - testformat("%034.33o", big, "0012345670123456701234567012345670") + testcommon("%034.33o", big, "0012345670123456701234567012345670") # base marker shouldn't change that - testformat("%0#34.33o", big, "0o012345670123456701234567012345670") - testformat("%o", float(big), "123456__________________________", 6) + testcommon("%0#34.33o", big, "0o012345670123456701234567012345670") # Some small ints, in both Python int and flavors). - testformat("%d", 42, "42") - testformat("%d", -42, "-42") - testformat("%d", 42, "42") - testformat("%d", -42, "-42") - testformat("%d", 42.0, "42") - testformat("%#x", 1, "0x1") - testformat("%#x", 1, "0x1") - testformat("%#X", 1, "0X1") - testformat("%#X", 1, "0X1") - testformat("%#x", 1.0, "0x1") - testformat("%#o", 1, "0o1") - testformat("%#o", 1, "0o1") - testformat("%#o", 0, "0o0") - testformat("%#o", 0, "0o0") - testformat("%o", 0, "0") - testformat("%o", 0, "0") - testformat("%d", 0, "0") - testformat("%d", 0, "0") - testformat("%#x", 0, "0x0") - testformat("%#x", 0, "0x0") - testformat("%#X", 0, "0X0") - testformat("%#X", 0, "0X0") - testformat("%x", 0x42, "42") - testformat("%x", -0x42, "-42") - testformat("%x", 0x42, "42") - testformat("%x", -0x42, "-42") - testformat("%x", float(0x42), "42") - testformat("%o", 0o42, "42") - testformat("%o", -0o42, "-42") - testformat("%o", 0o42, "42") - testformat("%o", -0o42, "-42") - testformat("%o", float(0o42), "42") + 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 + testcommon('%g', 1.1, '1.1') + testcommon('%#g', 1.1, '1.10000') + + def test_str_format(self): testformat("%r", "\u0378", "'\\u0378'") # non printable testformat("%a", "\u0378", "'\\u0378'") # non printable testformat("%r", "\u0374", "'\u0374'") # printable testformat("%a", "\u0374", "'\\u0374'") # printable - # alternate float formatting - testformat('%g', 1.1, '1.1') - testformat('%#g', 1.1, '1.10000') - - # Test exception for unknown format characters + # Test exception for unknown format characters, etc. if verbose: print('Testing exceptions') def test_exc(formatstr, args, exception, excmsg): @@ -252,8 +275,83 @@ def test_exc(formatstr, args, exception, excmsg): test_exc('%g', '1', TypeError, "a float is required") test_exc('no format', '1', TypeError, "not all arguments converted during string formatting") - test_exc('no format', '1', TypeError, - "not all arguments converted during string formatting") + + if maxsize == 2**31-1: + # crashes 2.2.1 and earlier: + try: + "%*d"%(maxsize, -127) + except MemoryError: + pass + else: + raise TestFailed('"%*d"%(maxsize, -127) should fail') + + def test_bytes_and_bytearray_format(self): + # %c will insert a single byte, either from an int in range(256), or + # from a bytes argument of length 1, not from a str. + testcommon(b"%c", 7, b"\x07") + testcommon(b"%c", b"Z", b"Z") + testcommon(b"%c", bytearray(b"Z"), b"Z") + # %b will insert a series of bytes, either from a type that supports + # the Py_buffer protocol, or something that has a __bytes__ method + class FakeBytes(object): + def __bytes__(self): + return b'123' + fb = FakeBytes() + testcommon(b"%b", b"abc", b"abc") + testcommon(b"%b", bytearray(b"def"), b"def") + testcommon(b"%b", fb, b"123") + # # %s is an alias for %b -- should only be used for Py2/3 code + testcommon(b"%s", b"abc", b"abc") + testcommon(b"%s", bytearray(b"def"), b"def") + testcommon(b"%s", fb, b"123") + # %a will give the equivalent of + # repr(some_obj).encode('ascii', 'backslashreplace') + testcommon(b"%a", 3.14, b"3.14") + testcommon(b"%a", b"ghi", b"b'ghi'") + testcommon(b"%a", "jkl", b"'jkl'") + testcommon(b"%a", "\u0544", b"'\\u0544'") + + # Test exception for unknown format characters, etc. + if verbose: + print('Testing exceptions') + def test_exc(formatstr, args, exception, excmsg): + try: + testformat(formatstr, args) + except exception as exc: + if str(exc) == excmsg: + if verbose: + print("yes") + else: + if verbose: print('no') + print('Unexpected ', exception, ':', repr(str(exc))) + except: + if verbose: print('no') + print('Unexpected exception') + raise + else: + raise TestFailed('did not get expected exception: %s' % excmsg) + test_exc(b'%d', '1', TypeError, + "%d format: a number is required, not str") + test_exc(b'%d', b'1', TypeError, + "%d format: a number is required, not bytes") + test_exc(b'%g', '1', TypeError, "float argument required, not str") + test_exc(b'%g', b'1', TypeError, "float argument required, not bytes") + test_exc(b'no format', 7, TypeError, + "not all arguments converted during bytes formatting") + test_exc(b'no format', b'1', TypeError, + "not all arguments converted during bytes formatting") + test_exc(b'no format', bytearray(b'1'), TypeError, + "not all arguments converted during bytes formatting") + test_exc(b"%c", 256, TypeError, + "%c requires an integer in range(256) or a single byte") + test_exc(b"%c", b"Za", TypeError, + "%c requires an integer in range(256) or a single byte") + test_exc(b"%c", "Yb", TypeError, + "%c requires an integer in range(256) or a single byte") + test_exc(b"%b", "Xc", TypeError, + "%b requires bytes, or an object that implements __bytes__, not 'str'") + test_exc(b"%s", "Wd", TypeError, + "%b requires bytes, or an object that implements __bytes__, not 'str'") if maxsize == 2**31-1: # crashes 2.2.1 and earlier: @@ -327,19 +425,28 @@ def test_optimisations(self): self.assertIs(text % (), text) self.assertIs(text.format(), text) - @support.cpython_only def test_precision(self): - from _testcapi import INT_MAX - f = 1.2 self.assertEqual(format(f, ".0f"), "1") self.assertEqual(format(f, ".3f"), "1.200") with self.assertRaises(ValueError) as cm: - format(f, ".%sf" % (INT_MAX + 1)) + format(f, ".%sf" % (sys.maxsize + 1)) c = complex(f) self.assertEqual(format(c, ".0f"), "1+0j") self.assertEqual(format(c, ".3f"), "1.200+0.000j") + with self.assertRaises(ValueError) as cm: + format(c, ".%sf" % (sys.maxsize + 1)) + + @support.cpython_only + def test_precision_c_limits(self): + from _testcapi import INT_MAX + + f = 1.2 + with self.assertRaises(ValueError) as cm: + format(f, ".%sf" % (INT_MAX + 1)) + + c = complex(f) with self.assertRaises(ValueError) as cm: format(c, ".%sf" % (INT_MAX + 1)) diff --git a/Lib/test/test_fractions.py b/Lib/test/test_fractions.py index 33365322b948..e86d5cee6e79 100644 --- a/Lib/test/test_fractions.py +++ b/Lib/test/test_fractions.py @@ -330,7 +330,6 @@ def testRound(self): self.assertTypedEquals(F(-2, 10), round(F(-15, 100), 1)) self.assertTypedEquals(F(-2, 10), round(F(-25, 100), 1)) - def testArithmetic(self): self.assertEqual(F(1, 2), F(1, 10) + F(2, 5)) self.assertEqual(F(-3, 10), F(1, 10) - F(2, 5)) @@ -402,6 +401,8 @@ def testMixedArithmetic(self): self.assertTypedEquals(2.0 , 4 ** F(1, 2)) self.assertTypedEquals(0.25, 2.0 ** F(-2, 1)) self.assertTypedEquals(1.0 + 0j, (1.0 + 0j) ** F(1, 10)) + self.assertRaises(ZeroDivisionError, operator.pow, + F(0, 1), -2) def testMixingWithDecimal(self): # Decimal refuses mixed arithmetic (but not mixed comparisons) diff --git a/Lib/test/test_frame.py b/Lib/test/test_frame.py index 2dd5780c8890..c402ec394e1d 100644 --- a/Lib/test/test_frame.py +++ b/Lib/test/test_frame.py @@ -1,5 +1,6 @@ import gc import sys +import types import unittest import weakref @@ -109,6 +110,57 @@ class C: self.assertIs(None, wr()) +class FrameLocalsTest(unittest.TestCase): + """ + Tests for the .f_locals attribute. + """ + + def make_frames(self): + def outer(): + x = 5 + y = 6 + def inner(): + z = x + 2 + 1/0 + t = 9 + return inner() + try: + outer() + except ZeroDivisionError as e: + tb = e.__traceback__ + frames = [] + while tb: + frames.append(tb.tb_frame) + tb = tb.tb_next + return frames + + def test_locals(self): + f, outer, inner = self.make_frames() + outer_locals = outer.f_locals + self.assertIsInstance(outer_locals.pop('inner'), types.FunctionType) + self.assertEqual(outer_locals, {'x': 5, 'y': 6}) + inner_locals = inner.f_locals + self.assertEqual(inner_locals, {'x': 5, 'z': 7}) + + def test_clear_locals(self): + # Test f_locals after clear() (issue #21897) + f, outer, inner = self.make_frames() + outer.clear() + inner.clear() + self.assertEqual(outer.f_locals, {}) + self.assertEqual(inner.f_locals, {}) + + def test_locals_clear_locals(self): + # Test f_locals before and after clear() (to exercise caching) + f, outer, inner = self.make_frames() + outer.f_locals + inner.f_locals + outer.clear() + inner.clear() + self.assertEqual(outer.f_locals, {}) + self.assertEqual(inner.f_locals, {}) + + def test_main(): support.run_unittest(__name__) diff --git a/Lib/test/test_ftplib.py b/Lib/test/test_ftplib.py index 15458a8ebfed..aef66da98af2 100644 --- a/Lib/test/test_ftplib.py +++ b/Lib/test/test_ftplib.py @@ -73,7 +73,7 @@ def push(self, what): super(DummyDTPHandler, self).push(what.encode('ascii')) def handle_error(self): - raise + raise Exception class DummyFTPHandler(asynchat.async_chat): @@ -118,7 +118,7 @@ def found_terminator(self): self.push('550 command "%s" not understood.' %cmd) def handle_error(self): - raise + raise Exception def push(self, data): asynchat.async_chat.push(self, data.encode('ascii') + b'\r\n') @@ -134,7 +134,7 @@ def cmd_port(self, arg): def cmd_pasv(self, arg): with socket.socket() as sock: sock.bind((self.socket.getsockname()[0], 0)) - sock.listen(5) + sock.listen() sock.settimeout(TIMEOUT) ip, port = sock.getsockname()[:2] ip = ip.replace('.', ','); p1 = port / 256; p2 = port % 256 @@ -152,7 +152,7 @@ def cmd_eprt(self, arg): def cmd_epsv(self, arg): with socket.socket(socket.AF_INET6) as sock: sock.bind((self.socket.getsockname()[0], 0)) - sock.listen(5) + sock.listen() sock.settimeout(TIMEOUT) port = sock.getsockname()[1] self.push('229 entering extended passive mode (|||%d|)' %port) @@ -296,7 +296,7 @@ def writable(self): return 0 def handle_error(self): - raise + raise Exception if ssl is not None: @@ -394,7 +394,7 @@ def recv(self, buffer_size): raise def handle_error(self): - raise + raise Exception def close(self): if (isinstance(self.socket, ssl.SSLSocket) and @@ -670,7 +670,7 @@ def test_entry(line, type=None, perm=None, unique=None, name=None): self.assertRaises(StopIteration, next, self.client.mlsd()) set_data('') for x in self.client.mlsd(): - self.fail("unexpected data %s" % data) + self.fail("unexpected data %s" % x) def test_makeport(self): with self.client.makeport(): @@ -889,7 +889,7 @@ def test_auth_issued_twice(self): def test_auth_ssl(self): try: - self.client.ssl_version = ssl.PROTOCOL_SSLv3 + self.client.ssl_version = ssl.PROTOCOL_SSLv23 self.client.auth() self.assertRaises(ValueError, self.client.auth) finally: @@ -979,7 +979,7 @@ def server(self): # 1) when the connection is ready to be accepted. # 2) when it is safe for the caller to close the connection # 3) when we have closed the socket - self.sock.listen(5) + self.sock.listen() # (1) Signal the caller that we are ready to accept the connection. self.evt.set() try: @@ -997,7 +997,7 @@ def server(self): def testTimeoutDefault(self): # default -- use global socket timeout - self.assertTrue(socket.getdefaulttimeout() is None) + self.assertIsNone(socket.getdefaulttimeout()) socket.setdefaulttimeout(30) try: ftp = ftplib.FTP(HOST) @@ -1009,13 +1009,13 @@ def testTimeoutDefault(self): def testTimeoutNone(self): # no timeout -- do not use global socket timeout - self.assertTrue(socket.getdefaulttimeout() is None) + self.assertIsNone(socket.getdefaulttimeout()) socket.setdefaulttimeout(30) try: ftp = ftplib.FTP(HOST, timeout=None) finally: socket.setdefaulttimeout(None) - self.assertTrue(ftp.sock.gettimeout() is None) + self.assertIsNone(ftp.sock.gettimeout()) self.evt.wait() ftp.close() @@ -1049,19 +1049,8 @@ def testTimeoutDirectAccess(self): ftp.close() -class TestNetrcDeprecation(TestCase): - - def test_deprecation(self): - with support.temp_cwd(), support.EnvironmentVarGuard() as env: - env['HOME'] = os.getcwd() - open('.netrc', 'w').close() - with self.assertWarns(DeprecationWarning): - ftplib.Netrc() - - - def test_main(): - tests = [TestFTPClass, TestTimeouts, TestNetrcDeprecation, + tests = [TestFTPClass, TestTimeouts, TestIPv6Environment, TestTLS_FTPClassMixin, TestTLS_FTPClass] diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py index 38c9713bf37a..55b96b4b8f4d 100644 --- a/Lib/test/test_functools.py +++ b/Lib/test/test_functools.py @@ -42,20 +42,6 @@ def test_attributes(self): self.assertEqual(p.func, capture) self.assertEqual(p.args, (1, 2)) self.assertEqual(p.keywords, dict(a=10, b=20)) - # attributes should not be writable - if not isinstance(self.partial, type): - return - self.assertRaises(AttributeError, setattr, p, 'func', map) - self.assertRaises(AttributeError, setattr, p, 'args', (1, 2)) - self.assertRaises(AttributeError, setattr, p, 'keywords', dict(a=1, b=2)) - - p = self.partial(hex) - try: - del p.__dict__ - except TypeError: - pass - else: - self.fail('partial object allowed __dict__ to be deleted') def test_argument_checking(self): self.assertRaises(TypeError, self.partial) # need at least a func arg @@ -151,12 +137,27 @@ class TestPartialC(TestPartial, unittest.TestCase): if c_functools: partial = c_functools.partial + def test_attributes_unwritable(self): + # attributes should not be writable + p = self.partial(capture, 1, 2, a=10, b=20) + self.assertRaises(AttributeError, setattr, p, 'func', map) + self.assertRaises(AttributeError, setattr, p, 'args', (1, 2)) + self.assertRaises(AttributeError, setattr, p, 'keywords', dict(a=1, b=2)) + + p = self.partial(hex) + try: + del p.__dict__ + except TypeError: + pass + else: + self.fail('partial object allowed __dict__ to be deleted') + def test_repr(self): args = (object(), object()) args_repr = ', '.join(repr(a) for a in args) - #kwargs = {'a': object(), 'b': object()} - kwargs = {'a': object()} - kwargs_repr = ', '.join("%s=%r" % (k, v) for k, v in kwargs.items()) + kwargs = {'a': object(), 'b': object()} + kwargs_reprs = ['a={a!r}, b={b!r}'.format_map(kwargs), + 'b={b!r}, a={a!r}'.format_map(kwargs)] if self.partial is c_functools.partial: name = 'functools.partial' else: @@ -171,18 +172,21 @@ def test_repr(self): repr(f)) f = self.partial(capture, **kwargs) - self.assertEqual('{}({!r}, {})'.format(name, capture, kwargs_repr), - repr(f)) + self.assertIn(repr(f), + ['{}({!r}, {})'.format(name, capture, kwargs_repr) + for kwargs_repr in kwargs_reprs]) f = self.partial(capture, *args, **kwargs) - self.assertEqual('{}({!r}, {}, {})'.format(name, capture, args_repr, kwargs_repr), - repr(f)) + self.assertIn(repr(f), + ['{}({!r}, {}, {})'.format(name, capture, args_repr, kwargs_repr) + for kwargs_repr in kwargs_reprs]) def test_pickle(self): f = self.partial(signature, 'asdf', bar=True) f.add_something_to__dict__ = True - f_copy = pickle.loads(pickle.dumps(f)) - self.assertEqual(signature(f), signature(f_copy)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + f_copy = pickle.loads(pickle.dumps(f, proto)) + self.assertEqual(signature(f), signature(f_copy)) # Issue 6083: Reference counting bug def test_setstate_refcount(self): @@ -878,6 +882,24 @@ def __lt__(self, other): with self.assertRaises(TypeError): a <= b + def test_pickle(self): + for proto in range(4, pickle.HIGHEST_PROTOCOL + 1): + for name in '__lt__', '__gt__', '__le__', '__ge__': + with self.subTest(method=name, proto=proto): + method = getattr(Orderable_LT, name) + method_copy = pickle.loads(pickle.dumps(method, proto)) + self.assertIs(method_copy, method) + +@functools.total_ordering +class Orderable_LT: + def __init__(self, value): + self.value = value + def __lt__(self, other): + return self.value < other.value + def __eq__(self, other): + return self.value == other.value + + class TestLRU(unittest.TestCase): def test_lru(self): @@ -1069,6 +1091,13 @@ def __eq__(self, other): self.assertEqual(test_func(DoubleEq(2)), # Trigger a re-entrant __eq__ call DoubleEq(2)) # Verify the correct return value + def test_early_detection_of_bad_call(self): + # Issue #22184 + with self.assertRaises(TypeError): + @functools.lru_cache + def f(): + pass + class TestSingleDispatch(unittest.TestCase): def test_simple_overloads(self): @@ -1125,7 +1154,8 @@ def g(obj): "Simple test" return "Test" self.assertEqual(g.__name__, "g") - self.assertEqual(g.__doc__, "Simple test") + if sys.flags.optimize < 2: + self.assertEqual(g.__doc__, "Simple test") @unittest.skipUnless(decimal, 'requires _decimal') @support.cpython_only diff --git a/Lib/test/test_gc.py b/Lib/test/test_gc.py index e8f52a508f85..c0be53795f0f 100644 --- a/Lib/test/test_gc.py +++ b/Lib/test/test_gc.py @@ -1,7 +1,6 @@ -import _testcapi import unittest from test.support import (verbose, refcount_test, run_unittest, - strip_python_stderr) + strip_python_stderr, cpython_only) from test.script_helper import assert_python_ok, make_script, temp_dir import sys @@ -14,6 +13,15 @@ except ImportError: threading = None +try: + from _testcapi import with_tp_del +except ImportError: + def with_tp_del(cls): + class C(object): + def __new__(cls, *args, **kwargs): + raise TypeError('requires _testcapi.with_tp_del') + return C + ### Support code ############################################################################### @@ -41,7 +49,7 @@ def it_happened(ignored): # gc collects it. self.wr = weakref.ref(C1055820(666), it_happened) -@_testcapi.with_tp_del +@with_tp_del class Uncollectable(object): """Create a reference cycle with multiple __del__ methods. @@ -143,10 +151,11 @@ def __init__(self): del a self.assertNotEqual(gc.collect(), 0) + @cpython_only def test_legacy_finalizer(self): # A() is uncollectable if it is part of a cycle, make sure it shows up # in gc.garbage. - @_testcapi.with_tp_del + @with_tp_del class A: def __tp_del__(self): pass class B: @@ -168,10 +177,11 @@ class B: self.fail("didn't find obj in garbage (finalizer)") gc.garbage.remove(obj) + @cpython_only def test_legacy_finalizer_newclass(self): # A() is uncollectable if it is part of a cycle, make sure it shows up # in gc.garbage. - @_testcapi.with_tp_del + @with_tp_del class A(object): def __tp_del__(self): pass class B(object): @@ -570,6 +580,39 @@ def callback(ignored): # would be damaged, with an empty __dict__. self.assertEqual(x, None) + def test_bug21435(self): + # This is a poor test - its only virtue is that it happened to + # segfault on Tim's Windows box before the patch for 21435 was + # applied. That's a nasty bug relying on specific pieces of cyclic + # trash appearing in exactly the right order in finalize_garbage()'s + # input list. + # But there's no reliable way to force that order from Python code, + # so over time chances are good this test won't really be testing much + # of anything anymore. Still, if it blows up, there's _some_ + # problem ;-) + gc.collect() + + class A: + pass + + class B: + def __init__(self, x): + self.x = x + + def __del__(self): + self.attr = None + + def do_work(): + a = A() + b = B(A()) + + a.attr = b + b.attr = a + + do_work() + gc.collect() # this blows up (bad C pointer) when it fails + + @cpython_only def test_garbage_at_shutdown(self): import subprocess code = """if 1: @@ -764,6 +807,7 @@ def test_collect_generation(self): info = v[2] self.assertEqual(info["generation"], 2) + @cpython_only def test_collect_garbage(self): self.preclean() # Each of these cause four objects to be garbage: Two diff --git a/Lib/test/test_gdb.py b/Lib/test/test_gdb.py index 0e254a248748..c57875c3dd56 100644 --- a/Lib/test/test_gdb.py +++ b/Lib/test/test_gdb.py @@ -22,7 +22,7 @@ from test.support import run_unittest, findfile, python_is_optimized try: - gdb_version, _ = subprocess.Popen(["gdb", "--version"], + gdb_version, _ = subprocess.Popen(["gdb", "-nx", "--version"], stdout=subprocess.PIPE).communicate() except OSError: # This is what "no gdb" looks like. There may, however, be other @@ -54,7 +54,9 @@ def run_gdb(*args, **env_vars): env.update(env_vars) else: env = None - base_cmd = ('gdb', '--batch') + # -nx: Do not execute commands from any .gdbinit initialization files + # (issue #22188) + base_cmd = ('gdb', '--batch', '-nx') if (gdb_major_version, gdb_minor_version) >= (7, 4): base_cmd += ('-iex', 'add-auto-load-safe-path ' + checkout_hook_path) out, err = subprocess.Popen(base_cmd + args, @@ -121,7 +123,28 @@ def get_stack_trace(self, source=None, script=None, # Generate a list of commands in gdb's language: commands = ['set breakpoint pending yes', 'break %s' % breakpoint, + + # The tests assume that the first frame of printed + # backtrace will not contain program counter, + # that is however not guaranteed by gdb + # therefore we need to use 'set print address off' to + # make sure the counter is not there. For example: + # #0 in PyObject_Print ... + # is assumed, but sometimes this can be e.g. + # #0 0x00003fffb7dd1798 in PyObject_Print ... + 'set print address off', + 'run'] + + # GDB as of 7.4 onwards can distinguish between the + # value of a variable at entry vs current value: + # http://sourceware.org/gdb/onlinedocs/gdb/Variables.html + # which leads to the selftests failing with errors like this: + # AssertionError: 'v@entry=()' != '()' + # Disable this: + if (gdb_major_version, gdb_minor_version) >= (7, 4): + commands += ['set print entry-values no'] + if cmds_after_breakpoint: commands += cmds_after_breakpoint else: @@ -130,7 +153,7 @@ def get_stack_trace(self, source=None, script=None, # print commands # Use "commands" to generate the arguments with which to invoke "gdb": - args = ["gdb", "--batch"] + args = ["gdb", "--batch", "-nx"] args += ['--eval-command=%s' % cmd for cmd in commands] args += ["--args", sys.executable] @@ -167,6 +190,8 @@ def get_stack_trace(self, source=None, script=None, 'linux-vdso.so', 'warning: Could not load shared library symbols for ' 'linux-gate.so', + 'warning: Could not load shared library symbols for ' + 'linux-vdso64.so', 'Do you need "set solib-search-path" or ' '"set sysroot"?', 'warning: Source file is more recent than executable.', diff --git a/Lib/test/test_generators.py b/Lib/test/test_generators.py index 4e921177a59b..9e610132cd7c 100644 --- a/Lib/test/test_generators.py +++ b/Lib/test/test_generators.py @@ -50,6 +50,154 @@ def gen(): self.assertEqual(gc.garbage, old_garbage) +class GeneratorTest(unittest.TestCase): + + def test_name(self): + def func(): + yield 1 + + # check generator names + gen = func() + self.assertEqual(gen.__name__, "func") + self.assertEqual(gen.__qualname__, + "GeneratorTest.test_name..func") + + # modify generator names + gen.__name__ = "name" + gen.__qualname__ = "qualname" + self.assertEqual(gen.__name__, "name") + self.assertEqual(gen.__qualname__, "qualname") + + # generator names must be a string and cannot be deleted + self.assertRaises(TypeError, setattr, gen, '__name__', 123) + self.assertRaises(TypeError, setattr, gen, '__qualname__', 123) + self.assertRaises(TypeError, delattr, gen, '__name__') + self.assertRaises(TypeError, delattr, gen, '__qualname__') + + # modify names of the function creating the generator + func.__qualname__ = "func_qualname" + func.__name__ = "func_name" + gen = func() + self.assertEqual(gen.__name__, "func_name") + self.assertEqual(gen.__qualname__, "func_qualname") + + # unnamed generator + gen = (x for x in range(10)) + self.assertEqual(gen.__name__, + "") + self.assertEqual(gen.__qualname__, + "GeneratorTest.test_name..") + + +class ExceptionTest(unittest.TestCase): + # Tests for the issue #23353: check that the currently handled exception + # is correctly saved/restored in PyEval_EvalFrameEx(). + + def test_except_throw(self): + def store_raise_exc_generator(): + try: + self.assertEqual(sys.exc_info()[0], None) + yield + except Exception as exc: + # exception raised by gen.throw(exc) + self.assertEqual(sys.exc_info()[0], ValueError) + self.assertIsNone(exc.__context__) + yield + + # ensure that the exception is not lost + self.assertEqual(sys.exc_info()[0], ValueError) + yield + + # we should be able to raise back the ValueError + raise + + make = store_raise_exc_generator() + next(make) + + try: + raise ValueError() + except Exception as exc: + try: + make.throw(exc) + except Exception: + pass + + next(make) + with self.assertRaises(ValueError) as cm: + next(make) + self.assertIsNone(cm.exception.__context__) + + self.assertEqual(sys.exc_info(), (None, None, None)) + + def test_except_next(self): + def gen(): + self.assertEqual(sys.exc_info()[0], ValueError) + yield "done" + + g = gen() + try: + raise ValueError + except Exception: + self.assertEqual(next(g), "done") + self.assertEqual(sys.exc_info(), (None, None, None)) + + def test_except_gen_except(self): + def gen(): + try: + self.assertEqual(sys.exc_info()[0], None) + yield + # we are called from "except ValueError:", TypeError must + # inherit ValueError in its context + raise TypeError() + except TypeError as exc: + self.assertEqual(sys.exc_info()[0], TypeError) + self.assertEqual(type(exc.__context__), ValueError) + # here we are still called from the "except ValueError:" + self.assertEqual(sys.exc_info()[0], ValueError) + yield + self.assertIsNone(sys.exc_info()[0]) + yield "done" + + g = gen() + next(g) + try: + raise ValueError + except Exception: + next(g) + + self.assertEqual(next(g), "done") + self.assertEqual(sys.exc_info(), (None, None, None)) + + def test_except_throw_exception_context(self): + def gen(): + try: + try: + self.assertEqual(sys.exc_info()[0], None) + yield + except ValueError: + # we are called from "except ValueError:" + self.assertEqual(sys.exc_info()[0], ValueError) + raise TypeError() + except Exception as exc: + self.assertEqual(sys.exc_info()[0], TypeError) + self.assertEqual(type(exc.__context__), ValueError) + # we are still called from "except ValueError:" + self.assertEqual(sys.exc_info()[0], ValueError) + yield + self.assertIsNone(sys.exc_info()[0]) + yield "done" + + g = gen() + next(g) + try: + raise ValueError + except Exception as exc: + g.throw(exc) + + self.assertEqual(next(g), "done") + self.assertEqual(sys.exc_info(), (None, None, None)) + + tutorial_tests = """ Let's try a simple generator: @@ -436,8 +584,8 @@ def gen(): >>> [s for s in dir(i) if not s.startswith('_')] ['close', 'gi_code', 'gi_frame', 'gi_running', 'send', 'throw'] >>> from test.support import HAVE_DOCSTRINGS ->>> print(i.__next__.__doc__ if HAVE_DOCSTRINGS else 'x.__next__() <==> next(x)') -x.__next__() <==> next(x) +>>> print(i.__next__.__doc__ if HAVE_DOCSTRINGS else 'Implement next(self).') +Implement next(self). >>> iter(i) is i True >>> import types diff --git a/Lib/test/test_genericpath.py b/Lib/test/test_genericpath.py index e967897d7577..f2722bcc8a51 100644 --- a/Lib/test/test_genericpath.py +++ b/Lib/test/test_genericpath.py @@ -329,7 +329,6 @@ def test_expandvars(self): self.assertEqual(expandvars("$[foo]bar"), "$[foo]bar") self.assertEqual(expandvars("$bar bar"), "$bar bar") self.assertEqual(expandvars("$?bar"), "$?bar") - self.assertEqual(expandvars("${foo}bar"), "barbar") self.assertEqual(expandvars("$foo}bar"), "bar}bar") self.assertEqual(expandvars("${foo"), "${foo") self.assertEqual(expandvars("${{foo}}"), "baz1}") @@ -342,13 +341,40 @@ def test_expandvars(self): self.assertEqual(expandvars(b"$[foo]bar"), b"$[foo]bar") self.assertEqual(expandvars(b"$bar bar"), b"$bar bar") self.assertEqual(expandvars(b"$?bar"), b"$?bar") - self.assertEqual(expandvars(b"${foo}bar"), b"barbar") self.assertEqual(expandvars(b"$foo}bar"), b"bar}bar") self.assertEqual(expandvars(b"${foo"), b"${foo") self.assertEqual(expandvars(b"${{foo}}"), b"baz1}") self.assertEqual(expandvars(b"$foo$foo"), b"barbar") self.assertEqual(expandvars(b"$bar$bar"), b"$bar$bar") + @unittest.skipUnless(support.FS_NONASCII, 'need support.FS_NONASCII') + def test_expandvars_nonascii(self): + if self.pathmodule.__name__ == 'macpath': + self.skipTest('macpath.expandvars is a stub') + expandvars = self.pathmodule.expandvars + def check(value, expected): + self.assertEqual(expandvars(value), expected) + with support.EnvironmentVarGuard() as env: + env.clear() + nonascii = support.FS_NONASCII + env['spam'] = nonascii + env[nonascii] = 'ham' + nonascii + check(nonascii, nonascii) + check('$spam bar', '%s bar' % nonascii) + check('${spam}bar', '%sbar' % nonascii) + check('${%s}bar' % nonascii, 'ham%sbar' % nonascii) + check('$bar%s bar' % nonascii, '$bar%s bar' % nonascii) + check('$spam}bar', '%s}bar' % nonascii) + + check(os.fsencode(nonascii), os.fsencode(nonascii)) + check(b'$spam bar', os.fsencode('%s bar' % nonascii)) + check(b'${spam}bar', os.fsencode('%sbar' % nonascii)) + check(os.fsencode('${%s}bar' % nonascii), + os.fsencode('ham%sbar' % nonascii)) + check(os.fsencode('$bar%s bar' % nonascii), + os.fsencode('$bar%s bar' % nonascii)) + check(b'$spam}bar', os.fsencode('%s}bar' % nonascii)) + def test_abspath(self): self.assertIn("foo", self.pathmodule.abspath("foo")) with warnings.catch_warnings(): @@ -408,6 +434,40 @@ def test_nonascii_abspath(self): with support.temp_cwd(name): self.test_abspath() + def test_join_errors(self): + # Check join() raises friendly TypeErrors. + with support.check_warnings(('', BytesWarning), quiet=True): + errmsg = "Can't mix strings and bytes in path components" + with self.assertRaisesRegex(TypeError, errmsg): + self.pathmodule.join(b'bytes', 'str') + with self.assertRaisesRegex(TypeError, errmsg): + self.pathmodule.join('str', b'bytes') + # regression, see #15377 + errmsg = r'join\(\) argument must be str or bytes, not %r' + with self.assertRaisesRegex(TypeError, errmsg % 'int'): + self.pathmodule.join(42, 'str') + with self.assertRaisesRegex(TypeError, errmsg % 'int'): + self.pathmodule.join('str', 42) + with self.assertRaisesRegex(TypeError, errmsg % 'bytearray'): + self.pathmodule.join(bytearray(b'foo'), bytearray(b'bar')) + + def test_relpath_errors(self): + # Check relpath() raises friendly TypeErrors. + with support.check_warnings(('', (BytesWarning, DeprecationWarning)), + quiet=True): + errmsg = "Can't mix strings and bytes in path components" + with self.assertRaisesRegex(TypeError, errmsg): + self.pathmodule.relpath(b'bytes', 'str') + with self.assertRaisesRegex(TypeError, errmsg): + self.pathmodule.relpath('str', b'bytes') + errmsg = r'relpath\(\) argument must be str or bytes, not %r' + with self.assertRaisesRegex(TypeError, errmsg % 'int'): + self.pathmodule.relpath(42, 'str') + with self.assertRaisesRegex(TypeError, errmsg % 'int'): + self.pathmodule.relpath('str', 42) + with self.assertRaisesRegex(TypeError, errmsg % 'bytearray'): + self.pathmodule.relpath(bytearray(b'foo'), bytearray(b'bar')) + if __name__=="__main__": unittest.main() diff --git a/Lib/test/test_genexps.py b/Lib/test/test_genexps.py index 203b336fde0c..fb531d6d472b 100644 --- a/Lib/test/test_genexps.py +++ b/Lib/test/test_genexps.py @@ -222,8 +222,8 @@ True >>> from test.support import HAVE_DOCSTRINGS - >>> print(g.__next__.__doc__ if HAVE_DOCSTRINGS else 'x.__next__() <==> next(x)') - x.__next__() <==> next(x) + >>> print(g.__next__.__doc__ if HAVE_DOCSTRINGS else 'Implement next(self).') + Implement next(self). >>> import types >>> isinstance(g, types.GeneratorType) True diff --git a/Lib/test/test_getargs2.py b/Lib/test/test_getargs2.py index beea76a9209a..71472cd163cb 100644 --- a/Lib/test/test_getargs2.py +++ b/Lib/test/test_getargs2.py @@ -1,5 +1,7 @@ import unittest from test import support +# Skip this test if the _testcapi module isn't available. +support.import_module('_testcapi') from _testcapi import getargs_keywords, getargs_keyword_only try: from _testcapi import getargs_L, getargs_K @@ -32,8 +34,8 @@ # > ** Changed from previous "range-and-a-half" to "none"; the # > range-and-a-half checking wasn't particularly useful. # -# Plus a C API or two, e.g. PyInt_AsLongMask() -> -# unsigned long and PyInt_AsLongLongMask() -> unsigned +# Plus a C API or two, e.g. PyLong_AsUnsignedLongMask() -> +# unsigned long and PyLong_AsUnsignedLongLongMask() -> unsigned # long long (if that exists). LARGE = 0x7FFFFFFF @@ -52,12 +54,34 @@ class Int: def __int__(self): return 99 +class IntSubclass(int): + def __int__(self): + return 99 + +class BadInt: + def __int__(self): + return 1.0 + +class BadInt2: + def __int__(self): + return True + +class BadInt3(int): + def __int__(self): + return True + + class Unsigned_TestCase(unittest.TestCase): def test_b(self): from _testcapi import getargs_b # b returns 'unsigned char', and does range checking (0 ... UCHAR_MAX) self.assertRaises(TypeError, getargs_b, 3.14) self.assertEqual(99, getargs_b(Int())) + self.assertEqual(0, getargs_b(IntSubclass())) + self.assertRaises(TypeError, getargs_b, BadInt()) + with self.assertWarns(DeprecationWarning): + self.assertEqual(1, getargs_b(BadInt2())) + self.assertEqual(0, getargs_b(BadInt3())) self.assertRaises(OverflowError, getargs_b, -1) self.assertEqual(0, getargs_b(0)) @@ -72,6 +96,11 @@ def test_B(self): # B returns 'unsigned char', no range checking self.assertRaises(TypeError, getargs_B, 3.14) self.assertEqual(99, getargs_B(Int())) + self.assertEqual(0, getargs_B(IntSubclass())) + self.assertRaises(TypeError, getargs_B, BadInt()) + with self.assertWarns(DeprecationWarning): + self.assertEqual(1, getargs_B(BadInt2())) + self.assertEqual(0, getargs_B(BadInt3())) self.assertEqual(UCHAR_MAX, getargs_B(-1)) self.assertEqual(0, getargs_B(0)) @@ -86,6 +115,11 @@ def test_H(self): # H returns 'unsigned short', no range checking self.assertRaises(TypeError, getargs_H, 3.14) self.assertEqual(99, getargs_H(Int())) + self.assertEqual(0, getargs_H(IntSubclass())) + self.assertRaises(TypeError, getargs_H, BadInt()) + with self.assertWarns(DeprecationWarning): + self.assertEqual(1, getargs_H(BadInt2())) + self.assertEqual(0, getargs_H(BadInt3())) self.assertEqual(USHRT_MAX, getargs_H(-1)) self.assertEqual(0, getargs_H(0)) @@ -101,6 +135,11 @@ def test_I(self): # I returns 'unsigned int', no range checking self.assertRaises(TypeError, getargs_I, 3.14) self.assertEqual(99, getargs_I(Int())) + self.assertEqual(0, getargs_I(IntSubclass())) + self.assertRaises(TypeError, getargs_I, BadInt()) + with self.assertWarns(DeprecationWarning): + self.assertEqual(1, getargs_I(BadInt2())) + self.assertEqual(0, getargs_I(BadInt3())) self.assertEqual(UINT_MAX, getargs_I(-1)) self.assertEqual(0, getargs_I(0)) @@ -117,6 +156,10 @@ def test_k(self): # it does not accept float, or instances with __int__ self.assertRaises(TypeError, getargs_k, 3.14) self.assertRaises(TypeError, getargs_k, Int()) + self.assertEqual(0, getargs_k(IntSubclass())) + self.assertRaises(TypeError, getargs_k, BadInt()) + self.assertRaises(TypeError, getargs_k, BadInt2()) + self.assertEqual(0, getargs_k(BadInt3())) self.assertEqual(ULONG_MAX, getargs_k(-1)) self.assertEqual(0, getargs_k(0)) @@ -133,6 +176,11 @@ def test_h(self): # h returns 'short', and does range checking (SHRT_MIN ... SHRT_MAX) self.assertRaises(TypeError, getargs_h, 3.14) self.assertEqual(99, getargs_h(Int())) + self.assertEqual(0, getargs_h(IntSubclass())) + self.assertRaises(TypeError, getargs_h, BadInt()) + with self.assertWarns(DeprecationWarning): + self.assertEqual(1, getargs_h(BadInt2())) + self.assertEqual(0, getargs_h(BadInt3())) self.assertRaises(OverflowError, getargs_h, SHRT_MIN-1) self.assertEqual(SHRT_MIN, getargs_h(SHRT_MIN)) @@ -147,6 +195,11 @@ def test_i(self): # i returns 'int', and does range checking (INT_MIN ... INT_MAX) self.assertRaises(TypeError, getargs_i, 3.14) self.assertEqual(99, getargs_i(Int())) + self.assertEqual(0, getargs_i(IntSubclass())) + self.assertRaises(TypeError, getargs_i, BadInt()) + with self.assertWarns(DeprecationWarning): + self.assertEqual(1, getargs_i(BadInt2())) + self.assertEqual(0, getargs_i(BadInt3())) self.assertRaises(OverflowError, getargs_i, INT_MIN-1) self.assertEqual(INT_MIN, getargs_i(INT_MIN)) @@ -161,6 +214,11 @@ def test_l(self): # l returns 'long', and does range checking (LONG_MIN ... LONG_MAX) self.assertRaises(TypeError, getargs_l, 3.14) self.assertEqual(99, getargs_l(Int())) + self.assertEqual(0, getargs_l(IntSubclass())) + self.assertRaises(TypeError, getargs_l, BadInt()) + with self.assertWarns(DeprecationWarning): + self.assertEqual(1, getargs_l(BadInt2())) + self.assertEqual(0, getargs_l(BadInt3())) self.assertRaises(OverflowError, getargs_l, LONG_MIN-1) self.assertEqual(LONG_MIN, getargs_l(LONG_MIN)) @@ -176,6 +234,10 @@ def test_n(self): # (PY_SSIZE_T_MIN ... PY_SSIZE_T_MAX) self.assertRaises(TypeError, getargs_n, 3.14) self.assertRaises(TypeError, getargs_n, Int()) + self.assertEqual(0, getargs_n(IntSubclass())) + self.assertRaises(TypeError, getargs_n, BadInt()) + self.assertRaises(TypeError, getargs_n, BadInt2()) + self.assertEqual(0, getargs_n(BadInt3())) self.assertRaises(OverflowError, getargs_n, PY_SSIZE_T_MIN-1) self.assertEqual(PY_SSIZE_T_MIN, getargs_n(PY_SSIZE_T_MIN)) @@ -195,6 +257,11 @@ def test_L(self): self.assertRaises(TypeError, getargs_L, 3.14) self.assertRaises(TypeError, getargs_L, "Hello") self.assertEqual(99, getargs_L(Int())) + self.assertEqual(0, getargs_L(IntSubclass())) + self.assertRaises(TypeError, getargs_L, BadInt()) + with self.assertWarns(DeprecationWarning): + self.assertEqual(1, getargs_L(BadInt2())) + self.assertEqual(0, getargs_L(BadInt3())) self.assertRaises(OverflowError, getargs_L, LLONG_MIN-1) self.assertEqual(LLONG_MIN, getargs_L(LLONG_MIN)) @@ -209,6 +276,11 @@ def test_K(self): # K return 'unsigned long long', no range checking self.assertRaises(TypeError, getargs_K, 3.14) self.assertRaises(TypeError, getargs_K, Int()) + self.assertEqual(0, getargs_K(IntSubclass())) + self.assertRaises(TypeError, getargs_K, BadInt()) + self.assertRaises(TypeError, getargs_K, BadInt2()) + self.assertEqual(0, getargs_K(BadInt3())) + self.assertEqual(ULLONG_MAX, getargs_K(ULLONG_MAX)) self.assertEqual(0, getargs_K(0)) self.assertEqual(0, getargs_K(ULLONG_MAX+1)) @@ -410,7 +482,7 @@ def test_c(self): def test_s(self): from _testcapi import getargs_s self.assertEqual(getargs_s('abc\xe9'), b'abc\xc3\xa9') - self.assertRaises(TypeError, getargs_s, 'nul:\0') + self.assertRaises(ValueError, getargs_s, 'nul:\0') self.assertRaises(TypeError, getargs_s, b'bytes') self.assertRaises(TypeError, getargs_s, bytearray(b'bytearray')) self.assertRaises(TypeError, getargs_s, memoryview(b'memoryview')) @@ -437,7 +509,7 @@ def test_s_hash(self): def test_z(self): from _testcapi import getargs_z self.assertEqual(getargs_z('abc\xe9'), b'abc\xc3\xa9') - self.assertRaises(TypeError, getargs_z, 'nul:\0') + self.assertRaises(ValueError, getargs_z, 'nul:\0') self.assertRaises(TypeError, getargs_z, b'bytes') self.assertRaises(TypeError, getargs_z, bytearray(b'bytearray')) self.assertRaises(TypeError, getargs_z, memoryview(b'memoryview')) @@ -465,7 +537,7 @@ def test_y(self): from _testcapi import getargs_y self.assertRaises(TypeError, getargs_y, 'abc\xe9') self.assertEqual(getargs_y(b'bytes'), b'bytes') - self.assertRaises(TypeError, getargs_y, b'nul:\0') + self.assertRaises(ValueError, getargs_y, b'nul:\0') self.assertRaises(TypeError, getargs_y, bytearray(b'bytearray')) self.assertRaises(TypeError, getargs_y, memoryview(b'memoryview')) self.assertRaises(TypeError, getargs_y, None) @@ -505,7 +577,7 @@ class Unicode_TestCase(unittest.TestCase): def test_u(self): from _testcapi import getargs_u self.assertEqual(getargs_u('abc\xe9'), 'abc\xe9') - self.assertRaises(TypeError, getargs_u, 'nul:\0') + self.assertRaises(ValueError, getargs_u, 'nul:\0') self.assertRaises(TypeError, getargs_u, b'bytes') self.assertRaises(TypeError, getargs_u, bytearray(b'bytearray')) self.assertRaises(TypeError, getargs_u, memoryview(b'memoryview')) @@ -523,7 +595,7 @@ def test_u_hash(self): def test_Z(self): from _testcapi import getargs_Z self.assertEqual(getargs_Z('abc\xe9'), 'abc\xe9') - self.assertRaises(TypeError, getargs_Z, 'nul:\0') + self.assertRaises(ValueError, getargs_Z, 'nul:\0') self.assertRaises(TypeError, getargs_Z, b'bytes') self.assertRaises(TypeError, getargs_Z, bytearray(b'bytearray')) self.assertRaises(TypeError, getargs_Z, memoryview(b'memoryview')) diff --git a/Lib/test/test_getpass.py b/Lib/test/test_getpass.py index 1731bd44a650..3452e46213a7 100644 --- a/Lib/test/test_getpass.py +++ b/Lib/test/test_getpass.py @@ -1,7 +1,7 @@ import getpass import os import unittest -from io import BytesIO, StringIO +from io import BytesIO, StringIO, TextIOWrapper from unittest import mock from test import support @@ -69,6 +69,14 @@ def test_uses_stdin_as_default_input(self, mock_input): getpass._raw_input(stream=StringIO()) mock_input.readline.assert_called_once_with() + @mock.patch('sys.stdin') + def test_uses_stdin_as_different_locale(self, mock_input): + stream = TextIOWrapper(BytesIO(), encoding="ascii") + mock_input.readline.return_value = "HasÅ‚o: " + getpass._raw_input(prompt="HasÅ‚o: ",stream=stream) + mock_input.readline.assert_called_once_with() + + def test_raises_on_empty_input(self): input = StringIO('') self.assertRaises(EOFError, getpass._raw_input, input=input) diff --git a/Lib/test/test_gettext.py b/Lib/test/test_gettext.py index 5456948ca4b0..c7ceb3ffe7df 100644 --- a/Lib/test/test_gettext.py +++ b/Lib/test/test_gettext.py @@ -33,6 +33,55 @@ ciBUQUgKdHJnZ3JrZyB6cmZmbnRyIHBuZ255YnQgeXZvZW5lbC4AYmFjb24Ad2luayB3aW5rAA== ''' +# This data contains an invalid major version number (5) +# An unexpected major version number should be treated as an error when +# parsing a .mo file + +GNU_MO_DATA_BAD_MAJOR_VERSION = b'''\ +3hIElQAABQAGAAAAHAAAAEwAAAALAAAAfAAAAAAAAACoAAAAFQAAAKkAAAAjAAAAvwAAAKEAAADj +AAAABwAAAIUBAAALAAAAjQEAAEUBAACZAQAAFgAAAN8CAAAeAAAA9gIAAKEAAAAVAwAABQAAALcD +AAAJAAAAvQMAAAEAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABQAAAAYAAAACAAAAAFJh +eW1vbmQgTHV4dXJ5IFlhY2gtdABUaGVyZSBpcyAlcyBmaWxlAFRoZXJlIGFyZSAlcyBmaWxlcwBU +aGlzIG1vZHVsZSBwcm92aWRlcyBpbnRlcm5hdGlvbmFsaXphdGlvbiBhbmQgbG9jYWxpemF0aW9u +CnN1cHBvcnQgZm9yIHlvdXIgUHl0aG9uIHByb2dyYW1zIGJ5IHByb3ZpZGluZyBhbiBpbnRlcmZh +Y2UgdG8gdGhlIEdOVQpnZXR0ZXh0IG1lc3NhZ2UgY2F0YWxvZyBsaWJyYXJ5LgBtdWxsdXNrAG51 +ZGdlIG51ZGdlAFByb2plY3QtSWQtVmVyc2lvbjogMi4wClBPLVJldmlzaW9uLURhdGU6IDIwMDAt +MDgtMjkgMTI6MTktMDQ6MDAKTGFzdC1UcmFuc2xhdG9yOiBKLiBEYXZpZCBJYsOhw7FleiA8ai1k +YXZpZEBub29zLmZyPgpMYW5ndWFnZS1UZWFtOiBYWCA8cHl0aG9uLWRldkBweXRob24ub3JnPgpN +SU1FLVZlcnNpb246IDEuMApDb250ZW50LVR5cGU6IHRleHQvcGxhaW47IGNoYXJzZXQ9aXNvLTg4 +NTktMQpDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBub25lCkdlbmVyYXRlZC1CeTogcHlnZXR0 +ZXh0LnB5IDEuMQpQbHVyYWwtRm9ybXM6IG5wbHVyYWxzPTI7IHBsdXJhbD1uIT0xOwoAVGhyb2F0 +d29iYmxlciBNYW5ncm92ZQBIYXkgJXMgZmljaGVybwBIYXkgJXMgZmljaGVyb3MAR3V2ZiB6YnFo +eXIgY2ViaXZxcmYgdmFncmVhbmd2YmFueXZtbmd2YmEgbmFxIHlicG55dm1uZ3ZiYQpmaGNjYmVn +IHNiZSBsYmhlIENsZ3ViYSBjZWJ0ZW56ZiBvbCBjZWJpdnF2YXQgbmEgdmFncmVzbnByIGdiIGd1 +ciBUQUgKdHJnZ3JrZyB6cmZmbnRyIHBuZ255YnQgeXZvZW5lbC4AYmFjb24Ad2luayB3aW5rAA== +''' + +# This data contains an invalid minor version number (7) +# An unexpected minor version number only indicates that some of the file's +# contents may not be able to be read. It does not indicate an error. + +GNU_MO_DATA_BAD_MINOR_VERSION = b'''\ +3hIElQcAAAAGAAAAHAAAAEwAAAALAAAAfAAAAAAAAACoAAAAFQAAAKkAAAAjAAAAvwAAAKEAAADj +AAAABwAAAIUBAAALAAAAjQEAAEUBAACZAQAAFgAAAN8CAAAeAAAA9gIAAKEAAAAVAwAABQAAALcD +AAAJAAAAvQMAAAEAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABQAAAAYAAAACAAAAAFJh +eW1vbmQgTHV4dXJ5IFlhY2gtdABUaGVyZSBpcyAlcyBmaWxlAFRoZXJlIGFyZSAlcyBmaWxlcwBU +aGlzIG1vZHVsZSBwcm92aWRlcyBpbnRlcm5hdGlvbmFsaXphdGlvbiBhbmQgbG9jYWxpemF0aW9u +CnN1cHBvcnQgZm9yIHlvdXIgUHl0aG9uIHByb2dyYW1zIGJ5IHByb3ZpZGluZyBhbiBpbnRlcmZh +Y2UgdG8gdGhlIEdOVQpnZXR0ZXh0IG1lc3NhZ2UgY2F0YWxvZyBsaWJyYXJ5LgBtdWxsdXNrAG51 +ZGdlIG51ZGdlAFByb2plY3QtSWQtVmVyc2lvbjogMi4wClBPLVJldmlzaW9uLURhdGU6IDIwMDAt +MDgtMjkgMTI6MTktMDQ6MDAKTGFzdC1UcmFuc2xhdG9yOiBKLiBEYXZpZCBJYsOhw7FleiA8ai1k +YXZpZEBub29zLmZyPgpMYW5ndWFnZS1UZWFtOiBYWCA8cHl0aG9uLWRldkBweXRob24ub3JnPgpN +SU1FLVZlcnNpb246IDEuMApDb250ZW50LVR5cGU6IHRleHQvcGxhaW47IGNoYXJzZXQ9aXNvLTg4 +NTktMQpDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBub25lCkdlbmVyYXRlZC1CeTogcHlnZXR0 +ZXh0LnB5IDEuMQpQbHVyYWwtRm9ybXM6IG5wbHVyYWxzPTI7IHBsdXJhbD1uIT0xOwoAVGhyb2F0 +d29iYmxlciBNYW5ncm92ZQBIYXkgJXMgZmljaGVybwBIYXkgJXMgZmljaGVyb3MAR3V2ZiB6YnFo +eXIgY2ViaXZxcmYgdmFncmVhbmd2YmFueXZtbmd2YmEgbmFxIHlicG55dm1uZ3ZiYQpmaGNjYmVn +IHNiZSBsYmhlIENsZ3ViYSBjZWJ0ZW56ZiBvbCBjZWJpdnF2YXQgbmEgdmFncmVzbnByIGdiIGd1 +ciBUQUgKdHJnZ3JrZyB6cmZmbnRyIHBuZ255YnQgeXZvZW5lbC4AYmFjb24Ad2luayB3aW5rAA== +''' + + UMO_DATA = b'''\ 3hIElQAAAAACAAAAHAAAACwAAAAFAAAAPAAAAAAAAABQAAAABAAAAFEAAAAPAQAAVgAAAAQAAABm AQAAAQAAAAIAAAAAAAAAAAAAAAAAAAAAYWLDngBQcm9qZWN0LUlkLVZlcnNpb246IDIuMApQTy1S @@ -56,6 +105,8 @@ LOCALEDIR = os.path.join('xx', 'LC_MESSAGES') MOFILE = os.path.join(LOCALEDIR, 'gettext.mo') +MOFILE_BAD_MAJOR_VERSION = os.path.join(LOCALEDIR, 'gettext_bad_major_version.mo') +MOFILE_BAD_MINOR_VERSION = os.path.join(LOCALEDIR, 'gettext_bad_minor_version.mo') UMOFILE = os.path.join(LOCALEDIR, 'ugettext.mo') MMOFILE = os.path.join(LOCALEDIR, 'metadata.mo') @@ -66,6 +117,10 @@ def setUp(self): os.makedirs(LOCALEDIR) with open(MOFILE, 'wb') as fp: fp.write(base64.decodebytes(GNU_MO_DATA)) + with open(MOFILE_BAD_MAJOR_VERSION, 'wb') as fp: + fp.write(base64.decodebytes(GNU_MO_DATA_BAD_MAJOR_VERSION)) + with open(MOFILE_BAD_MINOR_VERSION, 'wb') as fp: + fp.write(base64.decodebytes(GNU_MO_DATA_BAD_MINOR_VERSION)) with open(UMOFILE, 'wb') as fp: fp.write(base64.decodebytes(UMO_DATA)) with open(MMOFILE, 'wb') as fp: @@ -77,7 +132,7 @@ def setUp(self): def tearDown(self): self.env.__exit__() del self.env - shutil.rmtree(os.path.split(LOCALEDIR)[0]) + support.rmtree(os.path.split(LOCALEDIR)[0]) class GettextTestCase1(GettextBaseTest): @@ -166,6 +221,21 @@ def test_bindtextdomain(self): def test_textdomain(self): self.assertEqual(gettext.textdomain(), 'gettext') + def test_bad_major_version(self): + with open(MOFILE_BAD_MAJOR_VERSION, 'rb') as fp: + with self.assertRaises(OSError) as cm: + gettext.GNUTranslations(fp) + + exception = cm.exception + self.assertEqual(exception.errno, 0) + self.assertEqual(exception.strerror, "Bad version number 5") + self.assertEqual(exception.filename, MOFILE_BAD_MAJOR_VERSION) + + def test_bad_minor_version(self): + with open(MOFILE_BAD_MINOR_VERSION, 'rb') as fp: + # Check that no error is thrown with a bad minor version number + gettext.GNUTranslations(fp) + def test_some_translations(self): eq = self.assertEqual # test some translations diff --git a/Lib/test/test_glob.py b/Lib/test/test_glob.py index a5ab8d6c3e94..21b015330646 100644 --- a/Lib/test/test_glob.py +++ b/Lib/test/test_glob.py @@ -4,8 +4,8 @@ import sys import unittest -from test.support import (run_unittest, TESTFN, skip_unless_symlink, - can_symlink, create_empty_file) +from test.support import (TESTFN, skip_unless_symlink, + can_symlink, create_empty_file, change_cwd) class GlobTests(unittest.TestCase): @@ -13,6 +13,9 @@ class GlobTests(unittest.TestCase): def norm(self, *parts): return os.path.normpath(os.path.join(self.tempdir, *parts)) + def joins(self, *tuples): + return [os.path.join(self.tempdir, *parts) for parts in tuples] + def mktemp(self, *parts): filename = self.norm(*parts) base, file = os.path.split(filename) @@ -38,17 +41,17 @@ def setUp(self): def tearDown(self): shutil.rmtree(self.tempdir) - def glob(self, *parts): + def glob(self, *parts, **kwargs): if len(parts) == 1: pattern = parts[0] else: pattern = os.path.join(*parts) p = os.path.join(self.tempdir, pattern) - res = glob.glob(p) - self.assertEqual(list(glob.iglob(p)), res) + res = glob.glob(p, **kwargs) + self.assertEqual(list(glob.iglob(p, **kwargs)), res) bres = [os.fsencode(x) for x in res] - self.assertEqual(glob.glob(os.fsencode(p)), bres) - self.assertEqual(list(glob.iglob(os.fsencode(p))), bres) + self.assertEqual(glob.glob(os.fsencode(p), **kwargs), bres) + self.assertEqual(list(glob.iglob(os.fsencode(p), **kwargs)), bres) return res def assertSequencesEqual_noorder(self, l1, l2): @@ -192,9 +195,118 @@ def test_escape_windows(self): check('//?/c:/?', '//?/c:/[?]') check('//*/*/*', '//*/*/[*]') -def test_main(): - run_unittest(GlobTests) + def rglob(self, *parts, **kwargs): + return self.glob(*parts, recursive=True, **kwargs) + + def test_recursive_glob(self): + eq = self.assertSequencesEqual_noorder + full = [('ZZZ',), + ('a',), ('a', 'D'), + ('a', 'bcd'), + ('a', 'bcd', 'EF'), + ('a', 'bcd', 'efg'), + ('a', 'bcd', 'efg', 'ha'), + ('aaa',), ('aaa', 'zzzF'), + ('aab',), ('aab', 'F'), + ] + if can_symlink(): + full += [('sym1',), ('sym2',), + ('sym3',), + ('sym3', 'EF'), + ('sym3', 'efg'), + ('sym3', 'efg', 'ha'), + ] + eq(self.rglob('**'), self.joins(('',), *full)) + eq(self.rglob('.', '**'), self.joins(('.',''), + *(('.',) + i for i in full))) + dirs = [('a', ''), ('a', 'bcd', ''), ('a', 'bcd', 'efg', ''), + ('aaa', ''), ('aab', '')] + if can_symlink(): + dirs += [('sym3', ''), ('sym3', 'efg', '')] + eq(self.rglob('**', ''), self.joins(('',), *dirs)) + + eq(self.rglob('a', '**'), self.joins( + ('a', ''), ('a', 'D'), ('a', 'bcd'), ('a', 'bcd', 'EF'), + ('a', 'bcd', 'efg'), ('a', 'bcd', 'efg', 'ha'))) + eq(self.rglob('a**'), self.joins(('a',), ('aaa',), ('aab',))) + expect = [('a', 'bcd', 'EF')] + if can_symlink(): + expect += [('sym3', 'EF')] + eq(self.rglob('**', 'EF'), self.joins(*expect)) + expect = [('a', 'bcd', 'EF'), ('aaa', 'zzzF'), ('aab', 'F')] + if can_symlink(): + expect += [('sym3', 'EF')] + eq(self.rglob('**', '*F'), self.joins(*expect)) + eq(self.rglob('**', '*F', ''), []) + eq(self.rglob('**', 'bcd', '*'), self.joins( + ('a', 'bcd', 'EF'), ('a', 'bcd', 'efg'))) + eq(self.rglob('a', '**', 'bcd'), self.joins(('a', 'bcd'))) + + predir = os.path.abspath(os.curdir) + try: + os.chdir(self.tempdir) + join = os.path.join + eq(glob.glob('**', recursive=True), [join(*i) for i in full]) + eq(glob.glob(join('**', ''), recursive=True), + [join(*i) for i in dirs]) + eq(glob.glob(join('**','zz*F'), recursive=True), + [join('aaa', 'zzzF')]) + eq(glob.glob('**zz*F', recursive=True), []) + expect = [join('a', 'bcd', 'EF')] + if can_symlink(): + expect += [join('sym3', 'EF')] + eq(glob.glob(join('**', 'EF'), recursive=True), expect) + finally: + os.chdir(predir) + + +@skip_unless_symlink +class SymlinkLoopGlobTests(unittest.TestCase): + + def test_selflink(self): + tempdir = TESTFN + "_dir" + os.makedirs(tempdir) + self.addCleanup(shutil.rmtree, tempdir) + with change_cwd(tempdir): + os.makedirs('dir') + create_empty_file(os.path.join('dir', 'file')) + os.symlink(os.curdir, os.path.join('dir', 'link')) + + results = glob.glob('**', recursive=True) + self.assertEqual(len(results), len(set(results))) + results = set(results) + depth = 0 + while results: + path = os.path.join(*(['dir'] + ['link'] * depth)) + self.assertIn(path, results) + results.remove(path) + if not results: + break + path = os.path.join(path, 'file') + self.assertIn(path, results) + results.remove(path) + depth += 1 + + results = glob.glob(os.path.join('**', 'file'), recursive=True) + self.assertEqual(len(results), len(set(results))) + results = set(results) + depth = 0 + while results: + path = os.path.join(*(['dir'] + ['link'] * depth + ['file'])) + self.assertIn(path, results) + results.remove(path) + depth += 1 + + results = glob.glob(os.path.join('**', ''), recursive=True) + self.assertEqual(len(results), len(set(results))) + results = set(results) + depth = 0 + while results: + path = os.path.join(*(['dir'] + ['link'] * depth + [''])) + self.assertIn(path, results) + results.remove(path) + depth += 1 if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py index 6b326bdaa112..7069fb94ea84 100644 --- a/Lib/test/test_grammar.py +++ b/Lib/test/test_grammar.py @@ -80,6 +80,12 @@ def test_floats(self): x = .3e14 x = 3.1e4 + def test_float_exponent_tokenization(self): + # See issue 21642. + self.assertEqual(1 if 1else 0, 1) + self.assertEqual(1 if 0else 0, 0) + self.assertRaises(SyntaxError, eval, "0 if 1Else 0") + def test_string_literals(self): x = ''; y = ""; self.assertTrue(len(x) == 0 and x == y) x = '\''; y = "'"; self.assertTrue(len(x) == 1 and x == y and ord(x) == 39) @@ -314,6 +320,13 @@ def f(a, b:1, c:2, d, e:3=4, f=5, *g:6, h:7, i=8, j:9=10, self.assertEqual(f.__annotations__, {'b': 1, 'c': 2, 'e': 3, 'g': 6, 'h': 7, 'j': 9, 'k': 11, 'return': 12}) + # Check for issue #20625 -- annotations mangling + class Spam: + def f(self, *, __kw:1): + pass + class Ham(Spam): pass + self.assertEqual(Spam.f.__annotations__, {'_Spam__kw': 1}) + self.assertEqual(Ham.f.__annotations__, {'_Spam__kw': 1}) # Check for SF Bug #1697248 - mixing decorators and a return annotation def null(x): return x @null @@ -377,6 +390,31 @@ def test_expr_stmt(self): check_syntax_error(self, "x + 1 = 1") check_syntax_error(self, "a + 1 = b + 2") + # Check the heuristic for print & exec covers significant cases + # As well as placing some limits on false positives + def test_former_statements_refer_to_builtins(self): + keywords = "print", "exec" + # Cases where we want the custom error + cases = [ + "{} foo", + "{} {{1:foo}}", + "if 1: {} foo", + "if 1: {} {{1:foo}}", + "if 1:\n {} foo", + "if 1:\n {} {{1:foo}}", + ] + for keyword in keywords: + custom_msg = "call to '{}'".format(keyword) + for case in cases: + source = case.format(keyword) + with self.subTest(source=source): + with self.assertRaisesRegex(SyntaxError, custom_msg): + exec(source) + source = source.replace("foo", "(foo.)") + with self.subTest(source=source): + with self.assertRaisesRegex(SyntaxError, "invalid syntax"): + exec(source) + def test_del_stmt(self): # 'del' exprlist abc = [1,2,3] @@ -978,6 +1016,20 @@ def test_paren_evaluation(self): self.assertFalse((False is 2) is 3) self.assertFalse(False is 2 is 3) + def test_matrix_mul(self): + # This is not intended to be a comprehensive test, rather just to be few + # samples of the @ operator in test_grammar.py. + class M: + def __matmul__(self, o): + return 4 + def __imatmul__(self, o): + self.other = o + return self + m = M() + self.assertEqual(m @ m, 4) + m @= 42 + self.assertEqual(m.other, 42) + def test_main(): run_unittest(TokenTests, GrammarTests) diff --git a/Lib/test/test_grp.py b/Lib/test/test_grp.py index 04a8af6ac9b7..749041c2810c 100644 --- a/Lib/test/test_grp.py +++ b/Lib/test/test_grp.py @@ -26,8 +26,10 @@ def test_values(self): for e in entries: self.check_value(e) + def test_values_extended(self): + entries = grp.getgrall() if len(entries) > 1000: # Huge group file (NIS?) -- skip the rest - return + self.skipTest('huge group file, extended test skipped') for e in entries: e2 = grp.getgrgid(e.gr_gid) diff --git a/Lib/test/test_gzip.py b/Lib/test/test_gzip.py index aeafc6536d7a..b7a7e03c96ac 100644 --- a/Lib/test/test_gzip.py +++ b/Lib/test/test_gzip.py @@ -1,4 +1,3 @@ -#! /usr/bin/env python3 """Test script for the gzip module. """ @@ -422,6 +421,13 @@ def test_read_with_extra(self): with gzip.GzipFile(fileobj=io.BytesIO(gzdata)) as f: self.assertEqual(f.read(), b'Test') + def test_prepend_error(self): + # See issue #20875 + with gzip.open(self.filename, "wb") as f: + f.write(data1) + with gzip.open(self.filename, "rb") as f: + f.fileobj.prepend() + class TestOpen(BaseTest): def test_binary_modes(self): uncompressed = data1 * 50 diff --git a/Lib/test/test_hash.py b/Lib/test/test_hash.py index f6657bd3cb70..f647c6f7d2bc 100644 --- a/Lib/test/test_hash.py +++ b/Lib/test/test_hash.py @@ -172,7 +172,7 @@ class HashRandomizationTests: # an object to be tested def get_hash_command(self, repr_): - return 'print(hash(eval(%s.decode("utf-8"))))' % repr_.encode("utf-8") + return 'print(hash(eval(%a)))' % repr_ def get_hash(self, repr_, seed=None): env = os.environ.copy() @@ -233,7 +233,8 @@ class StringlikeHashRandomizationTests(HashRandomizationTests): [44402817, 8998297579845987431, -1956240331, -782697888614047887], # seed 42, 'äú∑ℇ' - [-283066365, -4576729883824601543, -271871407, None], + [-283066365, -4576729883824601543, -271871407, + -3927695501187247084], ] } @@ -330,15 +331,16 @@ def test_hash_distribution(self): base = "abcdefghabcdefg" for i in range(1, len(base)): prefix = base[:i] - s15 = set() - s255 = set() - for c in range(256): - h = hash(prefix + chr(c)) - s15.add(h & 0xf) - s255.add(h & 0xff) - # SipHash24 distribution depends on key, usually > 60% - self.assertGreater(len(s15), 8, prefix) - self.assertGreater(len(s255), 128, prefix) + with self.subTest(prefix=prefix): + s15 = set() + s255 = set() + for c in range(256): + h = hash(prefix + chr(c)) + s15.add(h & 0xf) + s255.add(h & 0xff) + # SipHash24 distribution depends on key, usually > 60% + self.assertGreater(len(s15), 8, prefix) + self.assertGreater(len(s255), 128, prefix) if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_hashlib.py b/Lib/test/test_hashlib.py index 4a5ea7f1a948..85ec2f96dbac 100644 --- a/Lib/test/test_hashlib.py +++ b/Lib/test/test_hashlib.py @@ -38,10 +38,7 @@ def hexstr(s): class HashLibTestCase(unittest.TestCase): supported_hash_names = ( 'md5', 'MD5', 'sha1', 'SHA1', 'sha224', 'SHA224', 'sha256', 'SHA256', - 'sha384', 'SHA384', 'sha512', 'SHA512', - 'sha3_224', 'sha3_256', 'sha3_384', - 'sha3_512', 'SHA3_224', 'SHA3_256', - 'SHA3_384', 'SHA3_512' ) + 'sha384', 'SHA384', 'sha512', 'SHA512') # Issue #14693: fallback modules are always compiled under POSIX _warn_on_extension_import = os.name == 'posix' or COMPILED_WITH_PYDEBUG @@ -102,12 +99,6 @@ def add_builtin_constructor(name): if _sha512: add_builtin_constructor('sha384') add_builtin_constructor('sha512') - _sha3 = self._conditional_import_module('_sha3') - if _sha3: - add_builtin_constructor('sha3_224') - add_builtin_constructor('sha3_256') - add_builtin_constructor('sha3_384') - add_builtin_constructor('sha3_512') super(HashLibTestCase, self).__init__(*args, **kwargs) @@ -234,10 +225,6 @@ def test_no_unicode(self): self.check_no_unicode('sha256') self.check_no_unicode('sha384') self.check_no_unicode('sha512') - self.check_no_unicode('sha3_224') - self.check_no_unicode('sha3_256') - self.check_no_unicode('sha3_384') - self.check_no_unicode('sha3_512') def check_blocksize_name(self, name, block_size=0, digest_size=0): constructors = self.constructors_to_test[name] @@ -257,10 +244,6 @@ def test_blocksize_name(self): self.check_blocksize_name('sha256', 64, 32) self.check_blocksize_name('sha384', 128, 48) self.check_blocksize_name('sha512', 128, 64) - self.check_blocksize_name('sha3_224', NotImplemented, 28) - self.check_blocksize_name('sha3_256', NotImplemented, 32) - self.check_blocksize_name('sha3_384', NotImplemented, 48) - self.check_blocksize_name('sha3_512', NotImplemented, 64) def test_case_md5_0(self): self.check('md5', b'', 'd41d8cd98f00b204e9800998ecf8427e') @@ -273,21 +256,15 @@ def test_case_md5_2(self): b'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789', 'd174ab98d277d9f5a5611c2c9f419d9f') - @bigmemtest(size=_4G + 5, memuse=1) + @unittest.skipIf(sys.maxsize < _4G + 5, 'test cannot run on 32-bit systems') + @bigmemtest(size=_4G + 5, memuse=1, dry_run=False) def test_case_md5_huge(self, size): - if size == _4G + 5: - try: - self.check('md5', b'A'*size, 'c9af2dff37468ce5dfee8f2cfc0a9c6d') - except OverflowError: - pass # 32-bit arch + self.check('md5', b'A'*size, 'c9af2dff37468ce5dfee8f2cfc0a9c6d') - @bigmemtest(size=_4G - 1, memuse=1) + @unittest.skipIf(sys.maxsize < _4G - 1, 'test cannot run on 32-bit systems') + @bigmemtest(size=_4G - 1, memuse=1, dry_run=False) def test_case_md5_uintmax(self, size): - if size == _4G - 1: - try: - self.check('md5', b'A'*size, '28138d306ff1b8281f1a9067e1a1a2b3') - except OverflowError: - pass # 32-bit arch + self.check('md5', b'A'*size, '28138d306ff1b8281f1a9067e1a1a2b3') # use the three examples from Federal Information Processing Standards # Publication 180-1, Secure Hash Standard, 1995 April 17 @@ -396,108 +373,6 @@ def test_case_sha512_3(self): "e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973eb"+ "de0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b") - # SHA-3 family - def test_case_sha3_224_0(self): - self.check('sha3_224', b"", - "F71837502BA8E10837BDD8D365ADB85591895602FC552B48B7390ABD") - - def test_case_sha3_224_1(self): - self.check('sha3_224', bytes.fromhex("CC"), - "A9CAB59EB40A10B246290F2D6086E32E3689FAF1D26B470C899F2802") - - def test_case_sha3_224_2(self): - self.check('sha3_224', bytes.fromhex("41FB"), - "615BA367AFDC35AAC397BC7EB5D58D106A734B24986D5D978FEFD62C") - - def test_case_sha3_224_3(self): - self.check('sha3_224', bytes.fromhex( - "433C5303131624C0021D868A30825475E8D0BD3052A022180398F4CA4423B9"+ - "8214B6BEAAC21C8807A2C33F8C93BD42B092CC1B06CEDF3224D5ED1EC29784"+ - "444F22E08A55AA58542B524B02CD3D5D5F6907AFE71C5D7462224A3F9D9E53"+ - "E7E0846DCBB4CE"), - "62B10F1B6236EBC2DA72957742A8D4E48E213B5F8934604BFD4D2C3A") - - @bigmemtest(size=_4G + 5, memuse=1) - def test_case_sha3_224_huge(self, size): - if size == _4G + 5: - try: - self.check('sha3_224', b'A'*size, - '58ef60057c9dddb6a87477e9ace5a26f0d9db01881cf9b10a9f8c224') - except OverflowError: - pass # 32-bit arch - - - def test_case_sha3_256_0(self): - self.check('sha3_256', b"", - "C5D2460186F7233C927E7DB2DCC703C0E500B653CA82273B7BFAD8045D85A470") - - def test_case_sha3_256_1(self): - self.check('sha3_256', bytes.fromhex("CC"), - "EEAD6DBFC7340A56CAEDC044696A168870549A6A7F6F56961E84A54BD9970B8A") - - def test_case_sha3_256_2(self): - self.check('sha3_256', bytes.fromhex("41FB"), - "A8EACEDA4D47B3281A795AD9E1EA2122B407BAF9AABCB9E18B5717B7873537D2") - - def test_case_sha3_256_3(self): - self.check('sha3_256', bytes.fromhex( - "433C5303131624C0021D868A30825475E8D0BD3052A022180398F4CA4423B9"+ - "8214B6BEAAC21C8807A2C33F8C93BD42B092CC1B06CEDF3224D5ED1EC29784"+ - "444F22E08A55AA58542B524B02CD3D5D5F6907AFE71C5D7462224A3F9D9E53"+ - "E7E0846DCBB4CE"), - "CE87A5173BFFD92399221658F801D45C294D9006EE9F3F9D419C8D427748DC41") - - - def test_case_sha3_384_0(self): - self.check('sha3_384', b"", - "2C23146A63A29ACF99E73B88F8C24EAA7DC60AA771780CCC006AFBFA8FE2479B"+ - "2DD2B21362337441AC12B515911957FF") - - def test_case_sha3_384_1(self): - self.check('sha3_384', bytes.fromhex("CC"), - "1B84E62A46E5A201861754AF5DC95C4A1A69CAF4A796AE405680161E29572641"+ - "F5FA1E8641D7958336EE7B11C58F73E9") - - def test_case_sha3_384_2(self): - self.check('sha3_384', bytes.fromhex("41FB"), - "495CCE2714CD72C8C53C3363D22C58B55960FE26BE0BF3BBC7A3316DD563AD1D"+ - "B8410E75EEFEA655E39D4670EC0B1792") - - def test_case_sha3_384_3(self): - self.check('sha3_384', bytes.fromhex( - "433C5303131624C0021D868A30825475E8D0BD3052A022180398F4CA4423B9"+ - "8214B6BEAAC21C8807A2C33F8C93BD42B092CC1B06CEDF3224D5ED1EC29784"+ - "444F22E08A55AA58542B524B02CD3D5D5F6907AFE71C5D7462224A3F9D9E53"+ - "E7E0846DCBB4CE"), - "135114508DD63E279E709C26F7817C0482766CDE49132E3EDF2EEDD8996F4E35"+ - "96D184100B384868249F1D8B8FDAA2C9") - - - def test_case_sha3_512_0(self): - self.check('sha3_512', b"", - "0EAB42DE4C3CEB9235FC91ACFFE746B29C29A8C366B7C60E4E67C466F36A4304"+ - "C00FA9CAF9D87976BA469BCBE06713B435F091EF2769FB160CDAB33D3670680E") - - def test_case_sha3_512_1(self): - self.check('sha3_512', bytes.fromhex("CC"), - "8630C13CBD066EA74BBE7FE468FEC1DEE10EDC1254FB4C1B7C5FD69B646E4416"+ - "0B8CE01D05A0908CA790DFB080F4B513BC3B6225ECE7A810371441A5AC666EB9") - - def test_case_sha3_512_2(self): - self.check('sha3_512', bytes.fromhex("41FB"), - "551DA6236F8B96FCE9F97F1190E901324F0B45E06DBBB5CDB8355D6ED1DC34B3"+ - "F0EAE7DCB68622FF232FA3CECE0D4616CDEB3931F93803662A28DF1CD535B731") - - def test_case_sha3_512_3(self): - self.check('sha3_512', bytes.fromhex( - "433C5303131624C0021D868A30825475E8D0BD3052A022180398F4CA4423B9"+ - "8214B6BEAAC21C8807A2C33F8C93BD42B092CC1B06CEDF3224D5ED1EC29784"+ - "444F22E08A55AA58542B524B02CD3D5D5F6907AFE71C5D7462224A3F9D9E53"+ - "E7E0846DCBB4CE"), - "527D28E341E6B14F4684ADB4B824C496C6482E51149565D3D17226828884306B"+ - "51D6148A72622C2B75F5D3510B799D8BDC03EAEDE453676A6EC8FE03A1AD0EAB") - - def test_gil(self): # Check things work fine with an input larger than the size required # for multithreaded operation (which is hardwired to 2048). diff --git a/Lib/test/test_heapq.py b/Lib/test/test_heapq.py index b5a2fd803a80..0dcd8c5161ad 100644 --- a/Lib/test/test_heapq.py +++ b/Lib/test/test_heapq.py @@ -6,14 +6,15 @@ from test import support from unittest import TestCase, skipUnless +from operator import itemgetter py_heapq = support.import_fresh_module('heapq', blocked=['_heapq']) c_heapq = support.import_fresh_module('heapq', fresh=['_heapq']) # _heapq.nlargest/nsmallest are saved in heapq._nlargest/_smallest when # _heapq is imported, so check them there -func_names = ['heapify', 'heappop', 'heappush', 'heappushpop', - 'heapreplace', '_nlargest', '_nsmallest'] +func_names = ['heapify', 'heappop', 'heappush', 'heappushpop', 'heapreplace', + '_heappop_max', '_heapreplace_max', '_heapify_max'] class TestModules(TestCase): def test_py_functions(self): @@ -152,11 +153,21 @@ def test_heapsort(self): def test_merge(self): inputs = [] - for i in range(random.randrange(5)): - row = sorted(random.randrange(1000) for j in range(random.randrange(10))) + for i in range(random.randrange(25)): + row = [] + for j in range(random.randrange(100)): + tup = random.choice('ABC'), random.randrange(-500, 500) + row.append(tup) inputs.append(row) - self.assertEqual(sorted(chain(*inputs)), list(self.module.merge(*inputs))) - self.assertEqual(list(self.module.merge()), []) + + for key in [None, itemgetter(0), itemgetter(1), itemgetter(1, 0)]: + for reverse in [False, True]: + seqs = [] + for seq in inputs: + seqs.append(sorted(seq, key=key, reverse=reverse)) + self.assertEqual(sorted(chain(*inputs), key=key, reverse=reverse), + list(self.module.merge(*seqs, key=key, reverse=reverse))) + self.assertEqual(list(self.module.merge()), []) def test_merge_does_not_suppress_index_error(self): # Issue 19018: Heapq.merge suppresses IndexError from user generator diff --git a/Lib/test/test_html.py b/Lib/test/test_html.py index 5e9f382a2d13..d6f0ae857d2e 100644 --- a/Lib/test/test_html.py +++ b/Lib/test/test_html.py @@ -48,10 +48,10 @@ def check_num(num, expected): check(s % num, char) for end in [' ', 'X']: check((s+end) % num, char+end) - # check invalid codepoints + # check invalid code points for cp in [0xD800, 0xDB00, 0xDC00, 0xDFFF, 0x110000]: check_num(cp, '\uFFFD') - # check more invalid codepoints + # check more invalid code points for cp in [0x1, 0xb, 0xe, 0x7f, 0xfffe, 0xffff, 0x10fffe, 0x10ffff]: check_num(cp, '') # check invalid numbers diff --git a/Lib/test/test_htmlparser.py b/Lib/test/test_htmlparser.py index 1a480c818721..de8f3e80d4b7 100644 --- a/Lib/test/test_htmlparser.py +++ b/Lib/test/test_htmlparser.py @@ -85,7 +85,7 @@ def handle_entityref(self, data): class TestCaseBase(unittest.TestCase): def get_collector(self): - raise NotImplementedError + return EventCollector(convert_charrefs=False) def _run_check(self, source, expected_events, collector=None): if collector is None: @@ -105,21 +105,8 @@ def _run_check_extra(self, source, events): self._run_check(source, events, EventCollectorExtra(convert_charrefs=False)) - def _parse_error(self, source): - def parse(source=source): - parser = self.get_collector() - parser.feed(source) - parser.close() - with self.assertRaises(html.parser.HTMLParseError): - with self.assertWarns(DeprecationWarning): - parse() - -class HTMLParserStrictTestCase(TestCaseBase): - - def get_collector(self): - with support.check_warnings(("", DeprecationWarning), quite=False): - return EventCollector(strict=True, convert_charrefs=False) +class HTMLParserTestCase(TestCaseBase): def test_processing_instruction_only(self): self._run_check("", [ @@ -167,6 +154,12 @@ def test_malformatted_charref(self): ("data", "&#bad;"), ("endtag", "p"), ]) + # add the [] as a workaround to avoid buffering (see #20288) + self._run_check(["
&#bad;
"], [ + ("starttag", "div", []), + ("data", "&#bad;"), + ("endtag", "div"), + ]) def test_unclosed_entityref(self): self._run_check("&entityref foo", [ @@ -195,9 +188,6 @@ def test_bare_pointy_brackets(self): ("data", "this < text > contains < bare>pointy< brackets"), ]) - def test_illegal_declarations(self): - self._parse_error('') - def test_starttag_end_boundary(self): self._run_check("""""", [("starttag", "a", [("b", "<")])]) self._run_check("""""", [("starttag", "a", [("b", ">")])]) @@ -232,25 +222,6 @@ def test_buffer_artefacts(self): self._run_check(["", ""], output) - def test_starttag_junk_chars(self): - self._parse_error("") - self._parse_error("") - self._parse_error("") - self._parse_error("") - self._parse_error("'") - self._parse_error("" % dtd, [('decl', 'DOCTYPE ' + dtd)]) - def test_declaration_junk_chars(self): - self._parse_error("") - def test_startendtag(self): self._run_check("

", [ ("startendtag", "p", []), @@ -378,7 +346,8 @@ def test_condcoms(self): self._run_check(html, expected) def test_convert_charrefs(self): - collector = lambda: EventCollectorCharrefs(convert_charrefs=True) + # default value for convert_charrefs is now True + collector = lambda: EventCollectorCharrefs() self.assertTrue(collector().convert_charrefs) charrefs = ['"', '"', '"', '"', '"', '"'] # check charrefs in the middle of the text/attributes @@ -415,23 +384,8 @@ def test_convert_charrefs(self): self._run_check('no charrefs here', [('data', 'no charrefs here')], collector=collector()) - -class HTMLParserTolerantTestCase(HTMLParserStrictTestCase): - - def get_collector(self): - return EventCollector(convert_charrefs=False) - - def test_deprecation_warnings(self): - with self.assertWarns(DeprecationWarning): - EventCollector() # convert_charrefs not passed explicitly - with self.assertWarns(DeprecationWarning): - EventCollector(strict=True) - with self.assertWarns(DeprecationWarning): - EventCollector(strict=False) - with self.assertRaises(html.parser.HTMLParseError): - with self.assertWarns(DeprecationWarning): - EventCollector().error('test') - + # the remaining tests were for the "tolerant" parser (which is now + # the default), and check various kind of broken markup def test_tolerant_parsing(self): self._run_check('te>>xt&a<\n' '", diff --git a/Lib/test/test_http_cookies.py b/Lib/test/test_http_cookies.py index 1cfbe742e465..ee30f174808f 100644 --- a/Lib/test/test_http_cookies.py +++ b/Lib/test/test_http_cookies.py @@ -3,7 +3,7 @@ from test.support import run_unittest, run_doctest, check_warnings import unittest from http import cookies - +import pickle import warnings class CookieTests(unittest.TestCase): @@ -114,7 +114,7 @@ def test_set_secure_httponly_attrs(self): C['Customer']['secure'] = True C['Customer']['httponly'] = True self.assertEqual(C.output(), - 'Set-Cookie: Customer="WILE_E_COYOTE"; httponly; secure') + 'Set-Cookie: Customer="WILE_E_COYOTE"; HttpOnly; Secure') def test_secure_httponly_false_if_not_present(self): C = cookies.SimpleCookie() @@ -141,18 +141,11 @@ def test_secure_httponly_true_if_have_value(self): self.assertEqual(C['eggs']['httponly'], 'foo') self.assertEqual(C['eggs']['secure'], 'bar') - def test_bad_attrs(self): - # issue 16611: make sure we don't break backward compatibility. - C = cookies.SimpleCookie() - C.load('cookie=with; invalid; version; second=cookie;') - self.assertEqual(C.output(), - 'Set-Cookie: cookie=with\r\nSet-Cookie: second=cookie') - def test_extra_spaces(self): C = cookies.SimpleCookie() C.load('eggs = scrambled ; secure ; path = bar ; foo=foo ') self.assertEqual(C.output(), - 'Set-Cookie: eggs=scrambled; Path=bar; secure\r\nSet-Cookie: foo=foo') + 'Set-Cookie: eggs=scrambled; Path=bar; Secure\r\nSet-Cookie: foo=foo') def test_quoted_meta(self): # Try cookie with quoted meta-data @@ -179,6 +172,31 @@ def test_quoted_meta(self): """) + def test_invalid_cookies(self): + # Accepting these could be a security issue + C = cookies.SimpleCookie() + for s in (']foo=x', '[foo=x', 'blah]foo=x', 'blah[foo=x', + 'Set-Cookie: foo=bar', 'Set-Cookie: foo', + 'foo=bar; baz', 'baz; foo=bar', + 'secure;foo=bar', 'Version=1;foo=bar'): + C.load(s) + self.assertEqual(dict(C), {}) + self.assertEqual(C.output(), '') + + def test_pickle(self): + rawdata = 'Customer="WILE_E_COYOTE"; Path=/acme; Version=1' + expected_output = 'Set-Cookie: %s' % rawdata + + C = cookies.SimpleCookie() + C.load(rawdata) + self.assertEqual(C.output(), expected_output) + + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(proto=proto): + C1 = pickle.loads(pickle.dumps(C, protocol=proto)) + self.assertEqual(C1.output(), expected_output) + + class MorselTests(unittest.TestCase): """Tests for the Morsel object.""" diff --git a/Lib/test/test_httplib.py b/Lib/test/test_httplib.py index 31c0b6a6cae5..50ddf185176a 100644 --- a/Lib/test/test_httplib.py +++ b/Lib/test/test_httplib.py @@ -15,19 +15,42 @@ CERT_localhost = os.path.join(here, 'keycert.pem') # Self-signed cert file for 'fakehostname' CERT_fakehostname = os.path.join(here, 'keycert2.pem') -# Root cert file (CA) for svn.python.org's cert -CACERT_svn_python_org = os.path.join(here, 'https_svn_python_org_root.pem') +# Self-signed cert file for self-signed.pythontest.net +CERT_selfsigned_pythontestdotnet = os.path.join(here, 'selfsigned_pythontestdotnet.pem') + +# constants for testing chunked encoding +chunked_start = ( + 'HTTP/1.1 200 OK\r\n' + 'Transfer-Encoding: chunked\r\n\r\n' + 'a\r\n' + 'hello worl\r\n' + '3\r\n' + 'd! \r\n' + '8\r\n' + 'and now \r\n' + '22\r\n' + 'for something completely different\r\n' +) +chunked_expected = b'hello world! and now for something completely different' +chunk_extension = ";foo=bar" +last_chunk = "0\r\n" +last_chunk_extended = "0" + chunk_extension + "\r\n" +trailers = "X-Dummy: foo\r\nX-Dumm2: bar\r\n" +chunked_end = "\r\n" HOST = support.HOST class FakeSocket: - def __init__(self, text, fileclass=io.BytesIO): + def __init__(self, text, fileclass=io.BytesIO, host=None, port=None): if isinstance(text, str): text = text.encode("ascii") self.text = text self.fileclass = fileclass self.data = b'' self.sendall_calls = 0 + self.file_closed = False + self.host = host + self.port = port def sendall(self, data): self.sendall_calls += 1 @@ -36,7 +59,19 @@ def sendall(self, data): def makefile(self, mode, bufsize=None): if mode != 'r' and mode != 'rb': raise client.UnimplementedFileMode() - return self.fileclass(self.text) + # keep the file around so we can check how much was read from it + self.file = self.fileclass(self.text) + self.file.close = self.file_close #nerf close () + return self.file + + def file_close(self): + self.file_closed = True + + def close(self): + pass + + def setsockopt(self, level, optname, value): + pass class EPipeSocket(FakeSocket): @@ -134,7 +169,7 @@ def test_putheader(self): conn.sock = FakeSocket(None) conn.putrequest('GET','/') conn.putheader('Content-length', 42) - self.assertTrue(b'Content-length: 42' in conn._buffer) + self.assertIn(b'Content-length: 42', conn._buffer) def test_ipv6host_header(self): # Default host header on IPv6 transaction should wrapped by [] if @@ -155,6 +190,16 @@ def test_ipv6host_header(self): conn.request('GET', '/foo') self.assertTrue(sock.data.startswith(expected)) + def test_malformed_headers_coped_with(self): + # Issue 19996 + body = "HTTP/1.1 200 OK\r\nFirst: val\r\n: nval\r\nSecond: val\r\n\r\n" + sock = FakeSocket(body) + resp = client.HTTPResponse(sock) + resp.begin() + + self.assertEqual(resp.getheader('First'), 'val') + self.assertEqual(resp.getheader('Second'), 'val') + class BasicTest(TestCase): def test_status_lines(self): @@ -164,6 +209,9 @@ def test_status_lines(self): sock = FakeSocket(body) resp = client.HTTPResponse(sock) resp.begin() + self.assertEqual(resp.read(0), b'') # Issue #20007 + self.assertFalse(resp.isclosed()) + self.assertFalse(resp.closed) self.assertEqual(resp.read(), b"Text") self.assertTrue(resp.isclosed()) self.assertFalse(resp.closed) @@ -427,20 +475,8 @@ def test_send_type_error(self): conn.request('POST', 'test', conn) def test_chunked(self): - chunked_start = ( - 'HTTP/1.1 200 OK\r\n' - 'Transfer-Encoding: chunked\r\n\r\n' - 'a\r\n' - 'hello worl\r\n' - '3\r\n' - 'd! \r\n' - '8\r\n' - 'and now \r\n' - '22\r\n' - 'for something completely different\r\n' - ) - expected = b'hello world! and now for something completely different' - sock = FakeSocket(chunked_start + '0\r\n') + expected = chunked_expected + sock = FakeSocket(chunked_start + last_chunk + chunked_end) resp = client.HTTPResponse(sock, method="GET") resp.begin() self.assertEqual(resp.read(), expected) @@ -448,7 +484,7 @@ def test_chunked(self): # Various read sizes for n in range(1, 12): - sock = FakeSocket(chunked_start + '0\r\n') + sock = FakeSocket(chunked_start + last_chunk + chunked_end) resp = client.HTTPResponse(sock, method="GET") resp.begin() self.assertEqual(resp.read(n) + resp.read(n) + resp.read(), expected) @@ -471,23 +507,12 @@ def test_chunked(self): resp.close() def test_readinto_chunked(self): - chunked_start = ( - 'HTTP/1.1 200 OK\r\n' - 'Transfer-Encoding: chunked\r\n\r\n' - 'a\r\n' - 'hello worl\r\n' - '3\r\n' - 'd! \r\n' - '8\r\n' - 'and now \r\n' - '22\r\n' - 'for something completely different\r\n' - ) - expected = b'hello world! and now for something completely different' + + expected = chunked_expected nexpected = len(expected) b = bytearray(128) - sock = FakeSocket(chunked_start + '0\r\n') + sock = FakeSocket(chunked_start + last_chunk + chunked_end) resp = client.HTTPResponse(sock, method="GET") resp.begin() n = resp.readinto(b) @@ -497,7 +522,7 @@ def test_readinto_chunked(self): # Various read sizes for n in range(1, 12): - sock = FakeSocket(chunked_start + '0\r\n') + sock = FakeSocket(chunked_start + last_chunk + chunked_end) resp = client.HTTPResponse(sock, method="GET") resp.begin() m = memoryview(b) @@ -533,7 +558,7 @@ def test_chunked_head(self): '1\r\n' 'd\r\n' ) - sock = FakeSocket(chunked_start + '0\r\n') + sock = FakeSocket(chunked_start + last_chunk + chunked_end) resp = client.HTTPResponse(sock, method="HEAD") resp.begin() self.assertEqual(resp.read(), b'') @@ -553,7 +578,7 @@ def test_readinto_chunked_head(self): '1\r\n' 'd\r\n' ) - sock = FakeSocket(chunked_start + '0\r\n') + sock = FakeSocket(chunked_start + last_chunk + chunked_end) resp = client.HTTPResponse(sock, method="HEAD") resp.begin() b = bytearray(5) @@ -628,6 +653,7 @@ def test_overflowing_chunked_line(self): + '0' * 65536 + 'a\r\n' 'hello world\r\n' '0\r\n' + '\r\n' ) resp = client.HTTPResponse(FakeSocket(body)) resp.begin() @@ -645,39 +671,342 @@ def test_early_eof(self): resp.close() self.assertTrue(resp.closed) - def test_delayed_ack_opt(self): - # Test that Nagle/delayed_ack optimistaion works correctly. - - # For small payloads, it should coalesce the body with - # headers, resulting in a single sendall() call + def test_error_leak(self): + # Test that the socket is not leaked if getresponse() fails conn = client.HTTPConnection('example.com') - sock = FakeSocket(None) - conn.sock = sock - body = b'x' * (conn.mss - 1) - conn.request('POST', '/', body) - self.assertEqual(sock.sendall_calls, 1) + response = None + class Response(client.HTTPResponse): + def __init__(self, *pos, **kw): + nonlocal response + response = self # Avoid garbage collector closing the socket + client.HTTPResponse.__init__(self, *pos, **kw) + conn.response_class = Response + conn.sock = FakeSocket('') # Emulate server dropping connection + conn.request('GET', '/') + self.assertRaises(client.BadStatusLine, conn.getresponse) + self.assertTrue(response.closed) + self.assertTrue(conn.sock.file_closed) + + def test_chunked_extension(self): + extra = '3;foo=bar\r\n' + 'abc\r\n' + expected = chunked_expected + b'abc' + + sock = FakeSocket(chunked_start + extra + last_chunk_extended + chunked_end) + resp = client.HTTPResponse(sock, method="GET") + resp.begin() + self.assertEqual(resp.read(), expected) + resp.close() + + def test_chunked_missing_end(self): + """some servers may serve up a short chunked encoding stream""" + expected = chunked_expected + sock = FakeSocket(chunked_start + last_chunk) #no terminating crlf + resp = client.HTTPResponse(sock, method="GET") + resp.begin() + self.assertEqual(resp.read(), expected) + resp.close() + + def test_chunked_trailers(self): + """See that trailers are read and ignored""" + expected = chunked_expected + sock = FakeSocket(chunked_start + last_chunk + trailers + chunked_end) + resp = client.HTTPResponse(sock, method="GET") + resp.begin() + self.assertEqual(resp.read(), expected) + # we should have reached the end of the file + self.assertEqual(sock.file.read(100), b"") #we read to the end + resp.close() + + def test_chunked_sync(self): + """Check that we don't read past the end of the chunked-encoding stream""" + expected = chunked_expected + extradata = "extradata" + sock = FakeSocket(chunked_start + last_chunk + trailers + chunked_end + extradata) + resp = client.HTTPResponse(sock, method="GET") + resp.begin() + self.assertEqual(resp.read(), expected) + # the file should now have our extradata ready to be read + self.assertEqual(sock.file.read(100), extradata.encode("ascii")) #we read to the end + resp.close() + + def test_content_length_sync(self): + """Check that we don't read past the end of the Content-Length stream""" + extradata = "extradata" + expected = b"Hello123\r\n" + sock = FakeSocket('HTTP/1.1 200 OK\r\nContent-Length: 10\r\n\r\nHello123\r\n' + extradata) + resp = client.HTTPResponse(sock, method="GET") + resp.begin() + self.assertEqual(resp.read(), expected) + # the file should now have our extradata ready to be read + self.assertEqual(sock.file.read(100), extradata.encode("ascii")) #we read to the end + resp.close() + +class ExtendedReadTest(TestCase): + """ + Test peek(), read1(), readline() + """ + lines = ( + 'HTTP/1.1 200 OK\r\n' + '\r\n' + 'hello world!\n' + 'and now \n' + 'for something completely different\n' + 'foo' + ) + lines_expected = lines[lines.find('hello'):].encode("ascii") + lines_chunked = ( + 'HTTP/1.1 200 OK\r\n' + 'Transfer-Encoding: chunked\r\n\r\n' + 'a\r\n' + 'hello worl\r\n' + '3\r\n' + 'd!\n\r\n' + '9\r\n' + 'and now \n\r\n' + '23\r\n' + 'for something completely different\n\r\n' + '3\r\n' + 'foo\r\n' + '0\r\n' # terminating chunk + '\r\n' # end of trailers + ) + + def setUp(self): + sock = FakeSocket(self.lines) + resp = client.HTTPResponse(sock, method="GET") + resp.begin() + resp.fp = io.BufferedReader(resp.fp) + self.resp = resp + + + + def test_peek(self): + resp = self.resp + # patch up the buffered peek so that it returns not too much stuff + oldpeek = resp.fp.peek + def mypeek(n=-1): + p = oldpeek(n) + if n >= 0: + return p[:n] + return p[:10] + resp.fp.peek = mypeek + + all = [] + while True: + # try a short peek + p = resp.peek(3) + if p: + self.assertGreater(len(p), 0) + # then unbounded peek + p2 = resp.peek() + self.assertGreaterEqual(len(p2), len(p)) + self.assertTrue(p2.startswith(p)) + next = resp.read(len(p2)) + self.assertEqual(next, p2) + else: + next = resp.read() + self.assertFalse(next) + all.append(next) + if not next: + break + self.assertEqual(b"".join(all), self.lines_expected) + + def test_readline(self): + resp = self.resp + self._verify_readline(self.resp.readline, self.lines_expected) + + def _verify_readline(self, readline, expected): + all = [] + while True: + # short readlines + line = readline(5) + if line and line != b"foo": + if len(line) < 5: + self.assertTrue(line.endswith(b"\n")) + all.append(line) + if not line: + break + self.assertEqual(b"".join(all), expected) + + def test_read1(self): + resp = self.resp + def r(): + res = resp.read1(4) + self.assertLessEqual(len(res), 4) + return res + readliner = Readliner(r) + self._verify_readline(readliner.readline, self.lines_expected) + + def test_read1_unbounded(self): + resp = self.resp + all = [] + while True: + data = resp.read1() + if not data: + break + all.append(data) + self.assertEqual(b"".join(all), self.lines_expected) + + def test_read1_bounded(self): + resp = self.resp + all = [] + while True: + data = resp.read1(10) + if not data: + break + self.assertLessEqual(len(data), 10) + all.append(data) + self.assertEqual(b"".join(all), self.lines_expected) + + def test_read1_0(self): + self.assertEqual(self.resp.read1(0), b"") + + def test_peek_0(self): + p = self.resp.peek(0) + self.assertLessEqual(0, len(p)) + +class ExtendedReadTestChunked(ExtendedReadTest): + """ + Test peek(), read1(), readline() in chunked mode + """ + lines = ( + 'HTTP/1.1 200 OK\r\n' + 'Transfer-Encoding: chunked\r\n\r\n' + 'a\r\n' + 'hello worl\r\n' + '3\r\n' + 'd!\n\r\n' + '9\r\n' + 'and now \n\r\n' + '23\r\n' + 'for something completely different\n\r\n' + '3\r\n' + 'foo\r\n' + '0\r\n' # terminating chunk + '\r\n' # end of trailers + ) + + +class Readliner: + """ + a simple readline class that uses an arbitrary read function and buffering + """ + def __init__(self, readfunc): + self.readfunc = readfunc + self.remainder = b"" + + def readline(self, limit): + data = [] + datalen = 0 + read = self.remainder + try: + while True: + idx = read.find(b'\n') + if idx != -1: + break + if datalen + len(read) >= limit: + idx = limit - datalen - 1 + # read more data + data.append(read) + read = self.readfunc() + if not read: + idx = 0 #eof condition + break + idx += 1 + data.append(read[:idx]) + self.remainder = read[idx:] + return b"".join(data) + except: + self.remainder = b"".join(data) + raise - # For large payloads, it should send the headers and - # then the body, resulting in more than one sendall() - # call - conn = client.HTTPConnection('example.com') - sock = FakeSocket(None) - conn.sock = sock - body = b'x' * conn.mss - conn.request('POST', '/', body) - self.assertGreater(sock.sendall_calls, 1) class OfflineTest(TestCase): + def test_all(self): + # Documented objects defined in the module should be in __all__ + expected = {"responses"} # White-list documented dict() object + # HTTPMessage, parse_headers(), and the HTTP status code constants are + # intentionally omitted for simplicity + blacklist = {"HTTPMessage", "parse_headers"} + for name in dir(client): + if name in blacklist: + continue + module_object = getattr(client, name) + if getattr(module_object, "__module__", None) == "http.client": + expected.add(name) + self.assertCountEqual(client.__all__, expected) + def test_responses(self): self.assertEqual(client.responses[client.NOT_FOUND], "Not Found") + def test_client_constants(self): + # Make sure we don't break backward compatibility with 3.4 + expected = [ + 'CONTINUE', + 'SWITCHING_PROTOCOLS', + 'PROCESSING', + 'OK', + 'CREATED', + 'ACCEPTED', + 'NON_AUTHORITATIVE_INFORMATION', + 'NO_CONTENT', + 'RESET_CONTENT', + 'PARTIAL_CONTENT', + 'MULTI_STATUS', + 'IM_USED', + 'MULTIPLE_CHOICES', + 'MOVED_PERMANENTLY', + 'FOUND', + 'SEE_OTHER', + 'NOT_MODIFIED', + 'USE_PROXY', + 'TEMPORARY_REDIRECT', + 'BAD_REQUEST', + 'UNAUTHORIZED', + 'PAYMENT_REQUIRED', + 'FORBIDDEN', + 'NOT_FOUND', + 'METHOD_NOT_ALLOWED', + 'NOT_ACCEPTABLE', + 'PROXY_AUTHENTICATION_REQUIRED', + 'REQUEST_TIMEOUT', + 'CONFLICT', + 'GONE', + 'LENGTH_REQUIRED', + 'PRECONDITION_FAILED', + 'REQUEST_ENTITY_TOO_LARGE', + 'REQUEST_URI_TOO_LONG', + 'UNSUPPORTED_MEDIA_TYPE', + 'REQUESTED_RANGE_NOT_SATISFIABLE', + 'EXPECTATION_FAILED', + 'UNPROCESSABLE_ENTITY', + 'LOCKED', + 'FAILED_DEPENDENCY', + 'UPGRADE_REQUIRED', + 'PRECONDITION_REQUIRED', + 'TOO_MANY_REQUESTS', + 'REQUEST_HEADER_FIELDS_TOO_LARGE', + 'INTERNAL_SERVER_ERROR', + 'NOT_IMPLEMENTED', + 'BAD_GATEWAY', + 'SERVICE_UNAVAILABLE', + 'GATEWAY_TIMEOUT', + 'HTTP_VERSION_NOT_SUPPORTED', + 'INSUFFICIENT_STORAGE', + 'NOT_EXTENDED', + 'NETWORK_AUTHENTICATION_REQUIRED', + ] + for const in expected: + with self.subTest(constant=const): + self.assertTrue(hasattr(client, const)) + class SourceAddressTest(TestCase): def setUp(self): self.serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.port = support.bind_port(self.serv) self.source_port = support.find_unused_port() - self.serv.listen(5) + self.serv.listen() self.conn = None def tearDown(self): @@ -709,7 +1038,7 @@ class TimeoutTest(TestCase): def setUp(self): self.serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM) TimeoutTest.PORT = support.bind_port(self.serv) - self.serv.listen(5) + self.serv.listen() def tearDown(self): self.serv.close() @@ -720,7 +1049,7 @@ def testTimeoutAttribute(self): # and into the socket. # default -- use global socket timeout - self.assertTrue(socket.getdefaulttimeout() is None) + self.assertIsNone(socket.getdefaulttimeout()) socket.setdefaulttimeout(30) try: httpConn = client.HTTPConnection(HOST, TimeoutTest.PORT) @@ -731,7 +1060,7 @@ def testTimeoutAttribute(self): httpConn.close() # no timeout -- do not use global socket default - self.assertTrue(socket.getdefaulttimeout() is None) + self.assertIsNone(socket.getdefaulttimeout()) socket.setdefaulttimeout(30) try: httpConn = client.HTTPConnection(HOST, TimeoutTest.PORT, @@ -764,44 +1093,74 @@ def test_attributes(self): h = client.HTTPSConnection(HOST, TimeoutTest.PORT, timeout=30) self.assertEqual(h.timeout, 30) - def _check_svn_python_org(self, resp): - # Just a simple check that everything went fine - server_string = resp.getheader('server') - self.assertIn('Apache', server_string) - def test_networked(self): - # Default settings: no cert verification is done + # Default settings: requires a valid cert from a trusted CA + import ssl support.requires('network') - with support.transient_internet('svn.python.org'): - h = client.HTTPSConnection('svn.python.org', 443) + with support.transient_internet('self-signed.pythontest.net'): + h = client.HTTPSConnection('self-signed.pythontest.net', 443) + with self.assertRaises(ssl.SSLError) as exc_info: + h.request('GET', '/') + self.assertEqual(exc_info.exception.reason, 'CERTIFICATE_VERIFY_FAILED') + + def test_networked_noverification(self): + # Switch off cert verification + import ssl + support.requires('network') + with support.transient_internet('self-signed.pythontest.net'): + context = ssl._create_unverified_context() + h = client.HTTPSConnection('self-signed.pythontest.net', 443, + context=context) + h.request('GET', '/') + resp = h.getresponse() + self.assertIn('nginx', resp.getheader('server')) + + @support.system_must_validate_cert + def test_networked_trusted_by_default_cert(self): + # Default settings: requires a valid cert from a trusted CA + support.requires('network') + with support.transient_internet('www.python.org'): + h = client.HTTPSConnection('www.python.org', 443) h.request('GET', '/') resp = h.getresponse() - self._check_svn_python_org(resp) + content_type = resp.getheader('content-type') + self.assertIn('text/html', content_type) def test_networked_good_cert(self): - # We feed a CA cert that validates the server's cert + # We feed the server's cert as a validating cert import ssl support.requires('network') - with support.transient_internet('svn.python.org'): + with support.transient_internet('self-signed.pythontest.net'): context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) context.verify_mode = ssl.CERT_REQUIRED - context.load_verify_locations(CACERT_svn_python_org) - h = client.HTTPSConnection('svn.python.org', 443, context=context) + context.load_verify_locations(CERT_selfsigned_pythontestdotnet) + h = client.HTTPSConnection('self-signed.pythontest.net', 443, context=context) h.request('GET', '/') resp = h.getresponse() - self._check_svn_python_org(resp) + server_string = resp.getheader('server') + self.assertIn('nginx', server_string) def test_networked_bad_cert(self): # We feed a "CA" cert that is unrelated to the server's cert import ssl support.requires('network') - with support.transient_internet('svn.python.org'): + with support.transient_internet('self-signed.pythontest.net'): context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) context.verify_mode = ssl.CERT_REQUIRED context.load_verify_locations(CERT_localhost) - h = client.HTTPSConnection('svn.python.org', 443, context=context) - with self.assertRaises(ssl.SSLError): + h = client.HTTPSConnection('self-signed.pythontest.net', 443, context=context) + with self.assertRaises(ssl.SSLError) as exc_info: h.request('GET', '/') + self.assertEqual(exc_info.exception.reason, 'CERTIFICATE_VERIFY_FAILED') + + def test_local_unknown_cert(self): + # The custom cert isn't known to the default trust bundle + import ssl + server = self.make_server(CERT_localhost) + h = client.HTTPSConnection('localhost', server.port) + with self.assertRaises(ssl.SSLError) as exc_info: + h.request('GET', '/') + self.assertEqual(exc_info.exception.reason, 'CERTIFICATE_VERIFY_FAILED') def test_local_good_hostname(self): # The (valid) cert validates the HTTP hostname @@ -814,7 +1173,6 @@ def test_local_good_hostname(self): h.request('GET', '/nonexistent') resp = h.getresponse() self.assertEqual(resp.status, 404) - del server def test_local_bad_hostname(self): # The (valid) cert doesn't validate the HTTP hostname @@ -822,6 +1180,7 @@ def test_local_bad_hostname(self): server = self.make_server(CERT_fakehostname) context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) context.verify_mode = ssl.CERT_REQUIRED + context.check_hostname = True context.load_verify_locations(CERT_fakehostname) h = client.HTTPSConnection('localhost', server.port, context=context) with self.assertRaises(ssl.CertificateError): @@ -832,12 +1191,24 @@ def test_local_bad_hostname(self): with self.assertRaises(ssl.CertificateError): h.request('GET', '/') # With check_hostname=False, the mismatching is ignored + context.check_hostname = False h = client.HTTPSConnection('localhost', server.port, context=context, check_hostname=False) h.request('GET', '/nonexistent') resp = h.getresponse() self.assertEqual(resp.status, 404) - del server + # The context's check_hostname setting is used if one isn't passed to + # HTTPSConnection. + context.check_hostname = False + h = client.HTTPSConnection('localhost', server.port, context=context) + h.request('GET', '/nonexistent') + self.assertEqual(h.getresponse().status, 404) + # Passing check_hostname to HTTPSConnection should override the + # context's setting. + h = client.HTTPSConnection('localhost', server.port, context=context, + check_hostname=True) + with self.assertRaises(ssl.CertificateError): + h.request('GET', '/') @unittest.skipIf(not hasattr(client, 'HTTPSConnection'), 'http.client.HTTPSConnection not available') @@ -967,10 +1338,85 @@ def test_getting_header_defaultint(self): header = self.resp.getheader('No-Such-Header',default=42) self.assertEqual(header, 42) +class TunnelTests(TestCase): + def setUp(self): + response_text = ( + 'HTTP/1.0 200 OK\r\n\r\n' # Reply to CONNECT + 'HTTP/1.1 200 OK\r\n' # Reply to HEAD + 'Content-Length: 42\r\n\r\n' + ) + self.host = 'proxy.com' + self.conn = client.HTTPConnection(self.host) + self.conn._create_connection = self._create_connection(response_text) + + def tearDown(self): + self.conn.close() + + def _create_connection(self, response_text): + def create_connection(address, timeout=None, source_address=None): + return FakeSocket(response_text, host=address[0], port=address[1]) + return create_connection + + def test_set_tunnel_host_port_headers(self): + tunnel_host = 'destination.com' + tunnel_port = 8888 + tunnel_headers = {'User-Agent': 'Mozilla/5.0 (compatible, MSIE 11)'} + self.conn.set_tunnel(tunnel_host, port=tunnel_port, + headers=tunnel_headers) + self.conn.request('HEAD', '/', '') + self.assertEqual(self.conn.sock.host, self.host) + self.assertEqual(self.conn.sock.port, client.HTTP_PORT) + self.assertEqual(self.conn._tunnel_host, tunnel_host) + self.assertEqual(self.conn._tunnel_port, tunnel_port) + self.assertEqual(self.conn._tunnel_headers, tunnel_headers) + + def test_disallow_set_tunnel_after_connect(self): + # Once connected, we shouldn't be able to tunnel anymore + self.conn.connect() + self.assertRaises(RuntimeError, self.conn.set_tunnel, + 'destination.com') + + def test_connect_with_tunnel(self): + self.conn.set_tunnel('destination.com') + self.conn.request('HEAD', '/', '') + self.assertEqual(self.conn.sock.host, self.host) + self.assertEqual(self.conn.sock.port, client.HTTP_PORT) + self.assertIn(b'CONNECT destination.com', self.conn.sock.data) + # issue22095 + self.assertNotIn(b'Host: destination.com:None', self.conn.sock.data) + self.assertIn(b'Host: destination.com', self.conn.sock.data) + + # This test should be removed when CONNECT gets the HTTP/1.1 blessing + self.assertNotIn(b'Host: proxy.com', self.conn.sock.data) + + def test_connect_put_request(self): + self.conn.set_tunnel('destination.com') + self.conn.request('PUT', '/', '') + self.assertEqual(self.conn.sock.host, self.host) + self.assertEqual(self.conn.sock.port, client.HTTP_PORT) + self.assertIn(b'CONNECT destination.com', self.conn.sock.data) + self.assertIn(b'Host: destination.com', self.conn.sock.data) + + def test_tunnel_debuglog(self): + expected_header = 'X-Dummy: 1' + response_text = 'HTTP/1.0 200 OK\r\n{}\r\n\r\n'.format(expected_header) + + self.conn.set_debuglevel(1) + self.conn._create_connection = self._create_connection(response_text) + self.conn.set_tunnel('destination.com') + + with support.captured_stdout() as output: + self.conn.request('PUT', '/', '') + lines = output.getvalue().splitlines() + self.assertIn('header: {}'.format(expected_header), lines) + + +@support.reap_threads def test_main(verbose=None): support.run_unittest(HeaderTests, OfflineTest, BasicTest, TimeoutTest, HTTPSTest, RequestBodyTest, SourceAddressTest, - HTTPResponseTest) + HTTPResponseTest, ExtendedReadTest, + ExtendedReadTestChunked, TunnelTests) if __name__ == '__main__': test_main() diff --git a/Lib/test/test_httpservers.py b/Lib/test/test_httpservers.py index b2bce1c27ab5..74e07143eb45 100644 --- a/Lib/test/test_httpservers.py +++ b/Lib/test/test_httpservers.py @@ -14,6 +14,7 @@ import base64 import shutil import urllib.parse +import html import http.client import tempfile from io import BytesIO @@ -125,7 +126,7 @@ def test_command(self): def test_request_line_trimming(self): self.con._http_vsn_str = 'HTTP/1.1\n' - self.con.putrequest('GET', '/') + self.con.putrequest('XYZBOGUS', '/') self.con.endheaders() res = self.con.getresponse() self.assertEqual(res.status, 501) @@ -152,8 +153,9 @@ def test_version_none_get(self): self.assertEqual(res.status, 501) def test_version_none(self): + # Test that a valid method is rejected when not HTTP/1.x self.con._http_vsn_str = '' - self.con.putrequest('PUT', '/') + self.con.putrequest('CUSTOM', '/') self.con.endheaders() res = self.con.getresponse() self.assertEqual(res.status, 400) @@ -265,6 +267,33 @@ def check_status_and_reason(self, response, status, data=None): self.assertIsNotNone(response.reason) if data: self.assertEqual(data, body) + return body + + @support.requires_mac_ver(10, 5) + @unittest.skipUnless(support.TESTFN_UNDECODABLE, + 'need support.TESTFN_UNDECODABLE') + def test_undecodable_filename(self): + enc = sys.getfilesystemencoding() + filename = os.fsdecode(support.TESTFN_UNDECODABLE) + '.txt' + with open(os.path.join(self.tempdir, filename), 'wb') as f: + f.write(support.TESTFN_UNDECODABLE) + response = self.request(self.tempdir_name + '/') + if sys.platform == 'darwin': + # On Mac OS the HFS+ filesystem replaces bytes that aren't valid + # UTF-8 into a percent-encoded value. + for name in os.listdir(self.tempdir): + if name != 'test': # Ignore a filename created in setUp(). + filename = name + break + body = self.check_status_and_reason(response, 200) + quotedname = urllib.parse.quote(filename, errors='surrogatepass') + self.assertIn(('href="%s"' % quotedname) + .encode(enc, 'surrogateescape'), body) + self.assertIn(('>%s<' % html.escape(filename)) + .encode(enc, 'surrogateescape'), body) + response = self.request(self.tempdir_name + '/' + quotedname) + self.check_status_and_reason(response, 200, + data=support.TESTFN_UNDECODABLE) def test_get(self): #constructs the path relative to the root directory of the HTTPServer @@ -277,6 +306,12 @@ def test_get(self): self.check_status_and_reason(response, 200) response = self.request(self.tempdir_name) self.check_status_and_reason(response, 301) + response = self.request(self.tempdir_name + '/?hi=2') + self.check_status_and_reason(response, 200) + response = self.request(self.tempdir_name + '?hi=1') + self.check_status_and_reason(response, 301) + self.assertEqual(response.getheader("Location"), + self.tempdir_name + "/?hi=1") response = self.request('/ThisDoesNotExist') self.check_status_and_reason(response, 404) response = self.request('/' + 'ThisDoesNotExist' + '/') @@ -305,7 +340,7 @@ def test_invalid_requests(self): response = self.request('/', method='FOO') self.check_status_and_reason(response, 501) # requests must be case sensitive,so this should fail too - response = self.request('/', method='get') + response = self.request('/', method='custom') self.check_status_and_reason(response, 501) response = self.request('/', method='GETs') self.check_status_and_reason(response, 501) @@ -345,10 +380,13 @@ def setUp(self): self.cwd = os.getcwd() self.parent_dir = tempfile.mkdtemp() self.cgi_dir = os.path.join(self.parent_dir, 'cgi-bin') + self.cgi_child_dir = os.path.join(self.cgi_dir, 'child-dir') os.mkdir(self.cgi_dir) + os.mkdir(self.cgi_child_dir) self.nocgi_path = None self.file1_path = None self.file2_path = None + self.file3_path = None # The shebang line should be pure ASCII: use symlink if possible. # See issue #7668. @@ -382,6 +420,11 @@ def setUp(self): file2.write(cgi_file2 % self.pythonexe) os.chmod(self.file2_path, 0o777) + self.file3_path = os.path.join(self.cgi_child_dir, 'file3.py') + with open(self.file3_path, 'w', encoding='utf-8') as file3: + file3.write(cgi_file1 % self.pythonexe) + os.chmod(self.file3_path, 0o777) + os.chdir(self.parent_dir) def tearDown(self): @@ -395,6 +438,9 @@ def tearDown(self): os.remove(self.file1_path) if self.file2_path: os.remove(self.file2_path) + if self.file3_path: + os.remove(self.file3_path) + os.rmdir(self.cgi_child_dir) os.rmdir(self.cgi_dir) os.rmdir(self.parent_dir) finally: @@ -485,6 +531,16 @@ def test_os_environ_is_not_altered(self): (res.read(), res.getheader('Content-type'), res.status)) self.assertEqual(os.environ['SERVER_SOFTWARE'], signature) + def test_urlquote_decoding_in_cgi_check(self): + res = self.request('/cgi-bin%2ffile1.py') + self.assertEqual((b'Hello World' + self.linesep, 'text/html', 200), + (res.read(), res.getheader('Content-type'), res.status)) + + def test_nested_cgi_path_issue21323(self): + res = self.request('/cgi-bin/child-dir/file3.py') + self.assertEqual((b'Hello World' + self.linesep, 'text/html', 200), + (res.read(), res.getheader('Content-type'), res.status)) + class SocketlessRequestHandler(SimpleHTTPRequestHandler): def __init__(self): @@ -552,7 +608,7 @@ def verify_expected_headers(self, headers): def verify_http_server_response(self, response): match = self.HTTPResponseMatch.search(response) - self.assertTrue(match is not None) + self.assertIsNotNone(match) def test_http_1_1(self): result = self.send_typical_request(b'GET / HTTP/1.1\r\n\r\n') @@ -560,6 +616,11 @@ def test_http_1_1(self): self.verify_expected_headers(result[1:-1]) self.verify_get_called() self.assertEqual(result[-1], b'Data\r\n') + self.assertEqual(self.handler.requestline, 'GET / HTTP/1.1') + self.assertEqual(self.handler.command, 'GET') + self.assertEqual(self.handler.path, '/') + self.assertEqual(self.handler.request_version, 'HTTP/1.1') + self.assertSequenceEqual(self.handler.headers.items(), ()) def test_http_1_0(self): result = self.send_typical_request(b'GET / HTTP/1.0\r\n\r\n') @@ -567,6 +628,11 @@ def test_http_1_0(self): self.verify_expected_headers(result[1:-1]) self.verify_get_called() self.assertEqual(result[-1], b'Data\r\n') + self.assertEqual(self.handler.requestline, 'GET / HTTP/1.0') + self.assertEqual(self.handler.command, 'GET') + self.assertEqual(self.handler.path, '/') + self.assertEqual(self.handler.request_version, 'HTTP/1.0') + self.assertSequenceEqual(self.handler.headers.items(), ()) def test_http_0_9(self): result = self.send_typical_request(b'GET / HTTP/0.9\r\n\r\n') @@ -580,14 +646,27 @@ def test_with_continue_1_0(self): self.verify_expected_headers(result[1:-1]) self.verify_get_called() self.assertEqual(result[-1], b'Data\r\n') + self.assertEqual(self.handler.requestline, 'GET / HTTP/1.0') + self.assertEqual(self.handler.command, 'GET') + self.assertEqual(self.handler.path, '/') + self.assertEqual(self.handler.request_version, 'HTTP/1.0') + headers = (("Expect", "100-continue"),) + self.assertSequenceEqual(self.handler.headers.items(), headers) def test_with_continue_1_1(self): result = self.send_typical_request(b'GET / HTTP/1.1\r\nExpect: 100-continue\r\n\r\n') self.assertEqual(result[0], b'HTTP/1.1 100 Continue\r\n') - self.assertEqual(result[1], b'HTTP/1.1 200 OK\r\n') + self.assertEqual(result[1], b'\r\n') + self.assertEqual(result[2], b'HTTP/1.1 200 OK\r\n') self.verify_expected_headers(result[2:-1]) self.verify_get_called() self.assertEqual(result[-1], b'Data\r\n') + self.assertEqual(self.handler.requestline, 'GET / HTTP/1.1') + self.assertEqual(self.handler.command, 'GET') + self.assertEqual(self.handler.path, '/') + self.assertEqual(self.handler.request_version, 'HTTP/1.1') + headers = (("Expect", "100-continue"),) + self.assertSequenceEqual(self.handler.headers.items(), headers) def test_header_buffering_of_send_error(self): @@ -652,7 +731,8 @@ def _readAndReseek(f): self.assertNotEqual(_readAndReseek(output), b'') result = _readAndReseek(output).split(b'\r\n') self.assertEqual(result[0], b'HTTP/1.1 100 Continue') - self.assertEqual(result[1], b'HTTP/1.1 200 OK') + self.assertEqual(result[1], b'') + self.assertEqual(result[2], b'HTTP/1.1 200 OK') def test_with_continue_rejected(self): usual_handler = self.handler # Save to avoid breaking any subsequent tests. @@ -672,6 +752,7 @@ def test_request_length(self): result = self.send_typical_request(b'GET ' + b'x' * 65537) self.assertEqual(result[0], b'HTTP/1.1 414 Request-URI Too Long\r\n') self.assertFalse(self.handler.get_called) + self.assertIsInstance(self.handler.requestline, str) def test_header_length(self): # Issue #6791: same for headers @@ -679,6 +760,22 @@ def test_header_length(self): b'GET / HTTP/1.1\r\nX-Foo: bar' + b'r' * 65537 + b'\r\n\r\n') self.assertEqual(result[0], b'HTTP/1.1 400 Line too long\r\n') self.assertFalse(self.handler.get_called) + self.assertEqual(self.handler.requestline, 'GET / HTTP/1.1') + + def test_close_connection(self): + # handle_one_request() should be repeatedly called until + # it sets close_connection + def handle_one_request(): + self.handler.close_connection = next(close_values) + self.handler.handle_one_request = handle_one_request + + close_values = iter((True,)) + self.handler.handle() + self.assertRaises(StopIteration, next, close_values) + + close_values = iter((False, False, True)) + self.handler.handle() + self.assertRaises(StopIteration, next, close_values) class SimpleHTTPRequestHandlerTestCase(unittest.TestCase): """ Test url parsing """ @@ -702,6 +799,19 @@ def test_start_with_double_slash(self): self.assertEqual(path, self.translated) +class MiscTestCase(unittest.TestCase): + def test_all(self): + expected = [] + blacklist = {'executable', 'nobody_uid', 'test'} + for name in dir(server): + if name.startswith('_') or name in blacklist: + continue + module_object = getattr(server, name) + if getattr(module_object, '__module__', None) == 'http.server': + expected.append(name) + self.assertCountEqual(server.__all__, expected) + + def test_main(verbose=None): cwd = os.getcwd() try: @@ -711,6 +821,7 @@ def test_main(verbose=None): SimpleHTTPServerTestCase, CGIHTTPServerTestCase, SimpleHTTPRequestHandlerTestCase, + MiscTestCase, ) finally: os.chdir(cwd) diff --git a/Lib/test/test_idle.py b/Lib/test/test_idle.py index 819151eda4af..141e89e49318 100644 --- a/Lib/test/test_idle.py +++ b/Lib/test/test_idle.py @@ -1,31 +1,16 @@ import unittest from test import support -from test.support import import_module, use_resources +from test.support import import_module # Skip test if _thread or _tkinter wasn't built or idlelib was deleted. import_module('threading') # imported by PyShell, imports _thread tk = import_module('tkinter') # imports _tkinter idletest = import_module('idlelib.idle_test') -# If buildbot improperly sets gui resource (#18365, #18441), remove it -# so requires('gui') tests are skipped while non-gui tests still run. -# If there is a problem with Macs, see #18441, msg 193805 -if use_resources and 'gui' in use_resources: - try: - root = tk.Tk() - root.destroy() - except tk.TclError: - while 'gui' in use_resources: - use_resources.remove('gui') - # Without test_main present, regrtest.runtest_inner (line1219) calls # unittest.TestLoader().loadTestsFromModule(this_module) which calls # load_tests() if it finds it. (Unittest.main does the same.) load_tests = idletest.load_tests if __name__ == '__main__': - # Until unittest supports resources, we emulate regrtest's -ugui - # so loaded tests run the same as if textually present here. - # If any Idle test ever needs another resource, add it to the list. - support.use_resources = ['gui'] # use_resources is initially None unittest.main(verbosity=2, exit=False) diff --git a/Lib/test/test_imaplib.py b/Lib/test/test_imaplib.py index 81bfd1fbc2d7..5485a2a7b79f 100644 --- a/Lib/test/test_imaplib.py +++ b/Lib/test/test_imaplib.py @@ -11,7 +11,8 @@ import time import calendar -from test.support import reap_threads, verbose, transient_internet, run_with_tz, run_with_locale +from test.support import (reap_threads, verbose, transient_internet, + run_with_tz, run_with_locale) import unittest from datetime import datetime, timezone, timedelta try: @@ -19,7 +20,8 @@ except ImportError: ssl = None -CERTFILE = None +CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir, "keycert3.pem") +CAFILE = os.path.join(os.path.dirname(__file__) or os.curdir, "pycacert.pem") class TestImaplib(unittest.TestCase): @@ -40,17 +42,15 @@ def test_Internaldate2tuple(self): def test_Internaldate2tuple_issue10941(self): self.assertNotEqual(imaplib.Internaldate2tuple( b'25 (INTERNALDATE "02-Apr-2000 02:30:00 +0000")'), - imaplib.Internaldate2tuple( - b'25 (INTERNALDATE "02-Apr-2000 03:30:00 +0000")')) - - + imaplib.Internaldate2tuple( + b'25 (INTERNALDATE "02-Apr-2000 03:30:00 +0000")')) def timevalues(self): return [2000000000, 2000000000.0, time.localtime(2000000000), (2033, 5, 18, 5, 33, 20, -1, -1, -1), (2033, 5, 18, 5, 33, 20, -1, -1, 1), datetime.fromtimestamp(2000000000, - timezone(timedelta(0, 2*60*60))), + timezone(timedelta(0, 2 * 60 * 60))), '"18-May-2033 05:33:20 +0200"'] @run_with_locale('LC_ALL', 'de_DE', 'fr_FR') @@ -71,7 +71,6 @@ def test_that_Time2Internaldate_returns_a_result(self): if ssl: - class SecureTCPServer(socketserver.TCPServer): def get_request(self): @@ -92,13 +91,17 @@ class SecureTCPServer: class SimpleIMAPHandler(socketserver.StreamRequestHandler): - timeout = 1 continuation = None capabilities = '' + def setup(self): + super().setup() + self.server.logged = None + def _send(self, message): - if verbose: print("SENT: %r" % message.strip()) + if verbose: + print("SENT: %r" % message.strip()) self.wfile.write(message) def _send_line(self, message): @@ -131,7 +134,8 @@ def handle(self): if line.endswith(b'\r\n'): break - if verbose: print('GOT: %r' % line.strip()) + if verbose: + print('GOT: %r' % line.strip()) if self.continuation: try: self.continuation.send(line) @@ -143,8 +147,8 @@ def handle(self): cmd = splitline[1] args = splitline[2:] - if hasattr(self, 'cmd_'+cmd): - continuation = getattr(self, 'cmd_'+cmd)(tag, args) + if hasattr(self, 'cmd_' + cmd): + continuation = getattr(self, 'cmd_' + cmd)(tag, args) if continuation: self.continuation = continuation next(continuation) @@ -152,16 +156,25 @@ def handle(self): self._send_tagged(tag, 'BAD', cmd + ' unknown') def cmd_CAPABILITY(self, tag, args): - caps = 'IMAP4rev1 ' + self.capabilities if self.capabilities else 'IMAP4rev1' + caps = ('IMAP4rev1 ' + self.capabilities + if self.capabilities + else 'IMAP4rev1') self._send_textline('* CAPABILITY ' + caps) self._send_tagged(tag, 'OK', 'CAPABILITY completed') def cmd_LOGOUT(self, tag, args): + self.server.logged = None self._send_textline('* BYE IMAP4ref1 Server logging out') self._send_tagged(tag, 'OK', 'LOGOUT completed') + def cmd_LOGIN(self, tag, args): + self.server.logged = args[0] + self._send_tagged(tag, 'OK', 'LOGIN completed') -class BaseThreadedNetworkedTests(unittest.TestCase): + +class ThreadedNetworkedTests(unittest.TestCase): + server_class = socketserver.TCPServer + imap_class = imaplib.IMAP4 def make_server(self, addr, hdlr): @@ -171,7 +184,8 @@ def handle_error(self, request, client_address): self.server_close() raise - if verbose: print("creating server") + if verbose: + print("creating server") server = MyServer(addr, hdlr) self.assertEqual(server.server_address, server.socket.getsockname()) @@ -187,18 +201,21 @@ def handle_error(self, request, client_address): # 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}) + kwargs={'poll_interval': 0.01}) t.daemon = True # In case this function raises. t.start() - if verbose: print("server running") + if verbose: + print("server running") return server, t def reap_server(self, server, thread): - if verbose: print("waiting for server") + if verbose: + print("waiting for server") server.shutdown() server.server_close() thread.join() - if verbose: print("done") + if verbose: + print("done") @contextmanager def reaped_server(self, hdlr): @@ -210,13 +227,12 @@ def reaped_server(self, hdlr): @contextmanager def reaped_pair(self, hdlr): - server, thread = self.make_server((support.HOST, 0), hdlr) - client = self.imap_class(*server.server_address) - try: - yield server, client - finally: - client.logout() - self.reap_server(server, thread) + with self.reaped_server(hdlr) as server: + client = self.imap_class(*server.server_address) + try: + yield server, client + finally: + client.logout() @reap_threads def test_connect(self): @@ -256,7 +272,7 @@ class MyServer(SimpleIMAPHandler): def cmd_AUTHENTICATE(self, tag, args): self._send_tagged(tag, 'NO', 'unrecognized authentication ' - 'type {}'.format(args[0])) + 'type {}'.format(args[0])) with self.reaped_pair(MyServer) as (server, client): with self.assertRaises(imaplib.IMAP4.error): @@ -290,13 +306,13 @@ def cmd_AUTHENTICATE(self, tag, args): code, data = client.authenticate('MYAUTH', lambda x: b'fake') self.assertEqual(code, 'OK') self.assertEqual(server.response, - b'ZmFrZQ==\r\n') #b64 encoded 'fake' + b'ZmFrZQ==\r\n') # b64 encoded 'fake' with self.reaped_pair(MyServer) as (server, client): code, data = client.authenticate('MYAUTH', lambda x: 'fake') self.assertEqual(code, 'OK') self.assertEqual(server.response, - b'ZmFrZQ==\r\n') #b64 encoded 'fake' + b'ZmFrZQ==\r\n') # b64 encoded 'fake' @reap_threads def test_login_cram_md5(self): @@ -307,9 +323,10 @@ class AuthHandler(SimpleIMAPHandler): def cmd_AUTHENTICATE(self, tag, args): self._send_textline('+ PDE4OTYuNjk3MTcwOTUyQHBvc3RvZmZpY2Uucm' - 'VzdG9uLm1jaS5uZXQ=') + 'VzdG9uLm1jaS5uZXQ=') r = yield - if r == b'dGltIGYxY2E2YmU0NjRiOWVmYTFjY2E2ZmZkNmNmMmQ5ZjMy\r\n': + if (r == b'dGltIGYxY2E2YmU0NjRiOWVmYT' + b'FjY2E2ZmZkNmNmMmQ5ZjMy\r\n'): self._send_tagged(tag, 'OK', 'CRAM-MD5 successful') else: self._send_tagged(tag, 'NO', 'No access') @@ -324,31 +341,71 @@ def cmd_AUTHENTICATE(self, tag, args): ret, data = client.login_cram_md5("tim", b"tanstaaftanstaaf") self.assertEqual(ret, "OK") - def test_linetoolong(self): class TooLongHandler(SimpleIMAPHandler): def handle(self): # Send a very long response line - self.wfile.write(b'* OK ' + imaplib._MAXLINE*b'x' + b'\r\n') + self.wfile.write(b'* OK ' + imaplib._MAXLINE * b'x' + b'\r\n') with self.reaped_server(TooLongHandler) as server: self.assertRaises(imaplib.IMAP4.error, self.imap_class, *server.server_address) + @reap_threads + def test_simple_with_statement(self): + # simplest call + with self.reaped_server(SimpleIMAPHandler) as server: + with self.imap_class(*server.server_address): + pass -class ThreadedNetworkedTests(BaseThreadedNetworkedTests): + @reap_threads + def test_with_statement(self): + with self.reaped_server(SimpleIMAPHandler) as server: + with self.imap_class(*server.server_address) as imap: + imap.login('user', 'pass') + self.assertEqual(server.logged, 'user') + self.assertIsNone(server.logged) - server_class = socketserver.TCPServer - imap_class = imaplib.IMAP4 + @reap_threads + def test_with_statement_logout(self): + # what happens if already logout in the block? + with self.reaped_server(SimpleIMAPHandler) as server: + 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) @unittest.skipUnless(ssl, "SSL not available") -class ThreadedNetworkedTestsSSL(BaseThreadedNetworkedTests): - +class ThreadedNetworkedTestsSSL(ThreadedNetworkedTests): server_class = SecureTCPServer imap_class = IMAP4_SSL + @reap_threads + 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) + + with self.assertRaisesRegex( + ssl.CertificateError, + "hostname '127.0.0.1' doesn't match 'localhost'"): + with self.reaped_server(SimpleIMAPHandler) as server: + client = self.imap_class(*server.server_address, + ssl_context=ssl_context) + client.shutdown() + + with self.reaped_server(SimpleIMAPHandler) as server: + client = self.imap_class("localhost", server.server_address[1], + ssl_context=ssl_context) + client.shutdown() + +@unittest.skipUnless( + support.is_resource_enabled('network'), 'network resource disabled') class RemoteIMAPTest(unittest.TestCase): host = 'cyrus.andrew.cmu.edu' port = 143 @@ -382,6 +439,8 @@ def test_logout(self): @unittest.skipUnless(ssl, "SSL not available") +@unittest.skipUnless( + support.is_resource_enabled('network'), 'network resource disabled') class RemoteIMAP_STARTTLSTest(RemoteIMAPTest): def setUp(self): @@ -435,7 +494,8 @@ def test_logincapa_with_client_certfile(self): def test_logincapa_with_client_ssl_context(self): with transient_internet(self.host): - _server = self.imap_class(self.host, self.port, ssl_context=self.create_ssl_context()) + _server = self.imap_class( + self.host, self.port, ssl_context=self.create_ssl_context()) self.check_logincapa(_server) def test_logout(self): @@ -446,33 +506,16 @@ def test_logout(self): def test_ssl_context_certfile_exclusive(self): with transient_internet(self.host): - self.assertRaises(ValueError, self.imap_class, self.host, self.port, - certfile=CERTFILE, ssl_context=self.create_ssl_context()) + self.assertRaises( + ValueError, self.imap_class, self.host, self.port, + certfile=CERTFILE, ssl_context=self.create_ssl_context()) def test_ssl_context_keyfile_exclusive(self): with transient_internet(self.host): - self.assertRaises(ValueError, self.imap_class, self.host, self.port, - keyfile=CERTFILE, ssl_context=self.create_ssl_context()) - - -def load_tests(*args): - tests = [TestImaplib] - - if support.is_resource_enabled('network'): - if ssl: - global CERTFILE - CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir, - "keycert.pem") - if not os.path.exists(CERTFILE): - raise support.TestFailed("Can't read certificate files!") - tests.extend([ - ThreadedNetworkedTests, ThreadedNetworkedTestsSSL, - RemoteIMAPTest, RemoteIMAP_SSLTest, RemoteIMAP_STARTTLSTest, - ]) - - return unittest.TestSuite([unittest.makeSuite(test) for test in tests]) + self.assertRaises( + ValueError, self.imap_class, self.host, self.port, + keyfile=CERTFILE, ssl_context=self.create_ssl_context()) if __name__ == "__main__": - support.use_resources = ['network'] unittest.main() diff --git a/Lib/test/test_imghdr.py b/Lib/test/test_imghdr.py new file mode 100644 index 000000000000..b54daf8e2ca1 --- /dev/null +++ b/Lib/test/test_imghdr.py @@ -0,0 +1,133 @@ +import imghdr +import io +import os +import unittest +import warnings +from test.support import findfile, TESTFN, unlink + +TEST_FILES = ( + ('python.png', 'png'), + ('python.gif', 'gif'), + ('python.bmp', 'bmp'), + ('python.ppm', 'ppm'), + ('python.pgm', 'pgm'), + ('python.pbm', 'pbm'), + ('python.jpg', 'jpeg'), + ('python.ras', 'rast'), + ('python.sgi', 'rgb'), + ('python.tiff', 'tiff'), + ('python.xbm', 'xbm'), + ('python.webp', 'webp'), + ('python.exr', 'exr'), +) + +class UnseekableIO(io.FileIO): + def tell(self): + raise io.UnsupportedOperation + + def seek(self, *args, **kwargs): + raise io.UnsupportedOperation + +class TestImghdr(unittest.TestCase): + @classmethod + def setUpClass(cls): + cls.testfile = findfile('python.png', subdir='imghdrdata') + with open(cls.testfile, 'rb') as stream: + cls.testdata = stream.read() + + def tearDown(self): + unlink(TESTFN) + + def test_data(self): + for filename, expected in TEST_FILES: + filename = findfile(filename, subdir='imghdrdata') + self.assertEqual(imghdr.what(filename), expected) + with open(filename, 'rb') as stream: + self.assertEqual(imghdr.what(stream), expected) + with open(filename, 'rb') as stream: + data = stream.read() + self.assertEqual(imghdr.what(None, data), expected) + self.assertEqual(imghdr.what(None, bytearray(data)), expected) + + def test_register_test(self): + def test_jumbo(h, file): + if h.startswith(b'eggs'): + return 'ham' + imghdr.tests.append(test_jumbo) + self.addCleanup(imghdr.tests.pop) + self.assertEqual(imghdr.what(None, b'eggs'), 'ham') + + def test_file_pos(self): + with open(TESTFN, 'wb') as stream: + stream.write(b'ababagalamaga') + pos = stream.tell() + stream.write(self.testdata) + with open(TESTFN, 'rb') as stream: + stream.seek(pos) + self.assertEqual(imghdr.what(stream), 'png') + self.assertEqual(stream.tell(), pos) + + def test_bad_args(self): + with self.assertRaises(TypeError): + imghdr.what() + with self.assertRaises(AttributeError): + imghdr.what(None) + with self.assertRaises(TypeError): + imghdr.what(self.testfile, 1) + with self.assertRaises(AttributeError): + imghdr.what(os.fsencode(self.testfile)) + with open(self.testfile, 'rb') as f: + with self.assertRaises(AttributeError): + imghdr.what(f.fileno()) + + def test_invalid_headers(self): + for header in (b'\211PN\r\n', + b'\001\331', + b'\x59\xA6', + b'cutecat', + b'000000JFI', + b'GIF80'): + self.assertIsNone(imghdr.what(None, header)) + + def test_string_data(self): + with warnings.catch_warnings(): + warnings.simplefilter("ignore", BytesWarning) + for filename, _ in TEST_FILES: + filename = findfile(filename, subdir='imghdrdata') + with open(filename, 'rb') as stream: + data = stream.read().decode('latin1') + with self.assertRaises(TypeError): + imghdr.what(io.StringIO(data)) + with self.assertRaises(TypeError): + imghdr.what(None, data) + + def test_missing_file(self): + with self.assertRaises(FileNotFoundError): + imghdr.what('missing') + + def test_closed_file(self): + stream = open(self.testfile, 'rb') + stream.close() + with self.assertRaises(ValueError) as cm: + imghdr.what(stream) + stream = io.BytesIO(self.testdata) + stream.close() + with self.assertRaises(ValueError) as cm: + imghdr.what(stream) + + def test_unseekable(self): + with open(TESTFN, 'wb') as stream: + stream.write(self.testdata) + with UnseekableIO(TESTFN, 'rb') as stream: + with self.assertRaises(io.UnsupportedOperation): + imghdr.what(stream) + + def test_output_stream(self): + with open(TESTFN, 'wb') as stream: + stream.write(self.testdata) + stream.seek(0) + with self.assertRaises(OSError) as cm: + imghdr.what(stream) + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_imp.py b/Lib/test/test_imp.py index 78f573407c75..80b9ec38c5d0 100644 --- a/Lib/test/test_imp.py +++ b/Lib/test/test_imp.py @@ -198,6 +198,7 @@ def test_issue5604(self): support.unlink(temp_mod_name + ext) support.unlink(init_file_name + ext) support.rmtree(test_package_name) + support.rmtree('__pycache__') def test_issue9319(self): path = os.path.dirname(__file__) @@ -272,7 +273,7 @@ def test_load_module_extension_file_is_None(self): if found[0] is not None: found[0].close() if found[2][2] != imp.C_EXTENSION: - return + self.skipTest("found module doesn't appear to be a C extension") imp.load_module(name, None, *found[1:]) @unittest.skipIf(sys.dont_write_bytecode, diff --git a/Lib/test/test_import.py b/Lib/test/test_import/__init__.py similarity index 95% rename from Lib/test/test_import.py rename to Lib/test/test_import/__init__.py index bda1541fdb1a..fd21fa29e7cc 100644 --- a/Lib/test/test_import.py +++ b/Lib/test/test_import/__init__.py @@ -190,12 +190,12 @@ def test_import_name_binding(self): # import x.y.z binds x in the current namespace import test as x import test.support - self.assertTrue(x is test, x.__name__) + self.assertIs(x, test, x.__name__) self.assertTrue(hasattr(test.support, "__file__")) # import x.y.z as w binds z as w import test.support as y - self.assertTrue(y is test.support, y.__name__) + self.assertIs(y, test.support, y.__name__) def test_failing_reload(self): # A failing reload should leave the module object in sys.modules. @@ -223,7 +223,7 @@ def test_failing_reload(self): self.assertRaises(ZeroDivisionError, importlib.reload, mod) # But we still expect the module to be in sys.modules. mod = sys.modules.get(TESTFN) - self.assertIsNot(mod, None, "expected module to be in sys.modules") + self.assertIsNotNone(mod, "expected module to be in sys.modules") # We should have replaced a w/ 10, but the old b value should # stick. @@ -568,7 +568,7 @@ def tearDown(self): def test_relimport_star(self): # This will import * from .test_import. - from . import relimport + from .. import relimport self.assertTrue(hasattr(relimport, "RelativeImportTests")) def test_issue3221(self): @@ -1062,11 +1062,52 @@ def test_unencodable_filename(self): # Issue #11619: The Python parser and the import machinery must not # encode filenames, especially on Windows pyname = script_helper.make_script('', TESTFN_UNENCODABLE, 'pass') + self.addCleanup(unlink, pyname) name = pyname[:-3] script_helper.assert_python_ok("-c", "mod = __import__(%a)" % name, __isolated=False) +class CircularImportTests(unittest.TestCase): + + """See the docstrings of the modules being imported for the purpose of the + test.""" + + def tearDown(self): + """Make sure no modules pre-exist in sys.modules which are being used to + test.""" + for key in list(sys.modules.keys()): + if key.startswith('test.test_import.data.circular_imports'): + del sys.modules[key] + + def test_direct(self): + try: + import test.test_import.data.circular_imports.basic + except ImportError: + self.fail('circular import through relative imports failed') + + def test_indirect(self): + try: + import test.test_import.data.circular_imports.indirect + except ImportError: + self.fail('relative import in module contributing to circular ' + 'import failed') + + def test_subpackage(self): + try: + import test.test_import.data.circular_imports.subpackage + except ImportError: + self.fail('circular import involving a subpackage failed') + + def test_rebinding(self): + try: + import test.test_import.data.circular_imports.rebinding as rebinding + except ImportError: + self.fail('circular import with rebinding of module attribute failed') + from test.test_import.data.circular_imports.subpkg import util + self.assertIs(util.util, rebinding.util) + + if __name__ == '__main__': # Test needs to be a package, so we can do relative imports. unittest.main() diff --git a/Lib/test/test_import/__main__.py b/Lib/test/test_import/__main__.py new file mode 100644 index 000000000000..24f02a171ad8 --- /dev/null +++ b/Lib/test/test_import/__main__.py @@ -0,0 +1,3 @@ +import unittest + +unittest.main('test.test_import') diff --git a/Lib/test/test_import/data/circular_imports/basic.py b/Lib/test/test_import/data/circular_imports/basic.py new file mode 100644 index 000000000000..3e41e395dbbf --- /dev/null +++ b/Lib/test/test_import/data/circular_imports/basic.py @@ -0,0 +1,2 @@ +"""Circular imports through direct, relative imports.""" +from . import basic2 diff --git a/Lib/test/test_import/data/circular_imports/basic2.py b/Lib/test/test_import/data/circular_imports/basic2.py new file mode 100644 index 000000000000..00bd2f29f3ba --- /dev/null +++ b/Lib/test/test_import/data/circular_imports/basic2.py @@ -0,0 +1 @@ +from . import basic diff --git a/Lib/test/test_import/data/circular_imports/indirect.py b/Lib/test/test_import/data/circular_imports/indirect.py new file mode 100644 index 000000000000..6925788d6035 --- /dev/null +++ b/Lib/test/test_import/data/circular_imports/indirect.py @@ -0,0 +1 @@ +from . import basic, basic2 diff --git a/Lib/test/test_import/data/circular_imports/rebinding.py b/Lib/test/test_import/data/circular_imports/rebinding.py new file mode 100644 index 000000000000..2b773755591a --- /dev/null +++ b/Lib/test/test_import/data/circular_imports/rebinding.py @@ -0,0 +1,3 @@ +"""Test the binding of names when a circular import shares the same name as an +attribute.""" +from .rebinding2 import util diff --git a/Lib/test/test_import/data/circular_imports/rebinding2.py b/Lib/test/test_import/data/circular_imports/rebinding2.py new file mode 100644 index 000000000000..57a9e6945d61 --- /dev/null +++ b/Lib/test/test_import/data/circular_imports/rebinding2.py @@ -0,0 +1,3 @@ +from .subpkg import util +from . import rebinding +util = util.util diff --git a/Lib/test/test_import/data/circular_imports/subpackage.py b/Lib/test/test_import/data/circular_imports/subpackage.py new file mode 100644 index 000000000000..7b412f76fc75 --- /dev/null +++ b/Lib/test/test_import/data/circular_imports/subpackage.py @@ -0,0 +1,2 @@ +"""Circular import involving a sub-package.""" +from .subpkg import subpackage2 diff --git a/Lib/test/test_import/data/circular_imports/subpkg/subpackage2.py b/Lib/test/test_import/data/circular_imports/subpkg/subpackage2.py new file mode 100644 index 000000000000..17b893a1a2fe --- /dev/null +++ b/Lib/test/test_import/data/circular_imports/subpkg/subpackage2.py @@ -0,0 +1,2 @@ +#from .util import util +from .. import subpackage diff --git a/Lib/test/test_import/data/circular_imports/subpkg/util.py b/Lib/test/test_import/data/circular_imports/subpkg/util.py new file mode 100644 index 000000000000..343bd843b2ed --- /dev/null +++ b/Lib/test/test_import/data/circular_imports/subpkg/util.py @@ -0,0 +1,2 @@ +def util(): + pass diff --git a/Lib/test/test_import/data/circular_imports/util.py b/Lib/test/test_import/data/circular_imports/util.py new file mode 100644 index 000000000000..343bd843b2ed --- /dev/null +++ b/Lib/test/test_import/data/circular_imports/util.py @@ -0,0 +1,2 @@ +def util(): + pass diff --git a/Lib/test/test_importlib/__init__.py b/Lib/test/test_importlib/__init__.py index 0e345cdc2d40..4b16ecc31156 100644 --- a/Lib/test/test_importlib/__init__.py +++ b/Lib/test/test_importlib/__init__.py @@ -1,33 +1,5 @@ import os -import sys -from test import support -import unittest +from test.support import load_package_tests -def test_suite(package=__package__, directory=os.path.dirname(__file__)): - suite = unittest.TestSuite() - for name in os.listdir(directory): - if name.startswith(('.', '__')): - continue - path = os.path.join(directory, name) - if (os.path.isfile(path) and name.startswith('test_') and - name.endswith('.py')): - submodule_name = os.path.splitext(name)[0] - module_name = "{0}.{1}".format(package, submodule_name) - __import__(module_name, level=0) - module_tests = unittest.findTestCases(sys.modules[module_name]) - suite.addTest(module_tests) - elif os.path.isdir(path): - package_name = "{0}.{1}".format(package, name) - __import__(package_name, level=0) - package_tests = getattr(sys.modules[package_name], 'test_suite')() - suite.addTest(package_tests) - else: - continue - return suite - - -def test_main(): - start_dir = os.path.dirname(__file__) - top_dir = os.path.dirname(os.path.dirname(start_dir)) - test_loader = unittest.TestLoader() - support.run_unittest(test_loader.discover(start_dir, top_level_dir=top_dir)) +def load_tests(*args): + return load_package_tests(os.path.dirname(__file__), *args) diff --git a/Lib/test/test_importlib/__main__.py b/Lib/test/test_importlib/__main__.py index 14bd5bc01722..40a23a297ec2 100644 --- a/Lib/test/test_importlib/__main__.py +++ b/Lib/test/test_importlib/__main__.py @@ -1,9 +1,4 @@ -"""Run importlib's test suite. +from . import load_tests +import unittest -Specifying the ``--builtin`` flag will run tests, where applicable, with -builtins.__import__ instead of importlib.__import__. - -""" -if __name__ == '__main__': - from . import test_main - test_main() +unittest.main() diff --git a/Lib/test/test_importlib/builtin/__init__.py b/Lib/test/test_importlib/builtin/__init__.py index 15c0ade207e1..4b16ecc31156 100644 --- a/Lib/test/test_importlib/builtin/__init__.py +++ b/Lib/test/test_importlib/builtin/__init__.py @@ -1,12 +1,5 @@ -from .. import test_suite import os +from test.support import load_package_tests - -def test_suite(): - directory = os.path.dirname(__file__) - return test_suite('importlib.test.builtin', directory) - - -if __name__ == '__main__': - from test.support import run_unittest - run_unittest(test_suite()) +def load_tests(*args): + return load_package_tests(os.path.dirname(__file__), *args) diff --git a/Lib/test/test_importlib/builtin/__main__.py b/Lib/test/test_importlib/builtin/__main__.py new file mode 100644 index 000000000000..40a23a297ec2 --- /dev/null +++ b/Lib/test/test_importlib/builtin/__main__.py @@ -0,0 +1,4 @@ +from . import load_tests +import unittest + +unittest.main() diff --git a/Lib/test/test_importlib/builtin/test_finder.py b/Lib/test/test_importlib/builtin/test_finder.py index 934562feb6e3..a2e6e1edc36c 100644 --- a/Lib/test/test_importlib/builtin/test_finder.py +++ b/Lib/test/test_importlib/builtin/test_finder.py @@ -1,21 +1,21 @@ from .. import abc from .. import util -from . import util as builtin_util -frozen_machinery, source_machinery = util.import_importlib('importlib.machinery') +machinery = util.import_importlib('importlib.machinery') import sys import unittest +@unittest.skipIf(util.BUILTINS.good_name is None, 'no reasonable builtin module') class FindSpecTests(abc.FinderTests): """Test find_spec() for built-in modules.""" def test_module(self): # Common case. - with util.uncache(builtin_util.NAME): - found = self.machinery.BuiltinImporter.find_spec(builtin_util.NAME) + with util.uncache(util.BUILTINS.good_name): + found = self.machinery.BuiltinImporter.find_spec(util.BUILTINS.good_name) self.assertTrue(found) self.assertEqual(found.origin, 'built-in') @@ -39,23 +39,26 @@ def test_failure(self): def test_ignore_path(self): # The value for 'path' should always trigger a failed import. - with util.uncache(builtin_util.NAME): - spec = self.machinery.BuiltinImporter.find_spec(builtin_util.NAME, + with util.uncache(util.BUILTINS.good_name): + spec = self.machinery.BuiltinImporter.find_spec(util.BUILTINS.good_name, ['pkg']) self.assertIsNone(spec) -Frozen_FindSpecTests, Source_FindSpecTests = util.test_both(FindSpecTests, - machinery=[frozen_machinery, source_machinery]) +(Frozen_FindSpecTests, + Source_FindSpecTests + ) = util.test_both(FindSpecTests, machinery=machinery) + +@unittest.skipIf(util.BUILTINS.good_name is None, 'no reasonable builtin module') class FinderTests(abc.FinderTests): """Test find_module() for built-in modules.""" def test_module(self): # Common case. - with util.uncache(builtin_util.NAME): - found = self.machinery.BuiltinImporter.find_module(builtin_util.NAME) + with util.uncache(util.BUILTINS.good_name): + found = self.machinery.BuiltinImporter.find_module(util.BUILTINS.good_name) self.assertTrue(found) self.assertTrue(hasattr(found, 'load_module')) @@ -72,13 +75,15 @@ def test_failure(self): def test_ignore_path(self): # The value for 'path' should always trigger a failed import. - with util.uncache(builtin_util.NAME): - loader = self.machinery.BuiltinImporter.find_module(builtin_util.NAME, + with util.uncache(util.BUILTINS.good_name): + loader = self.machinery.BuiltinImporter.find_module(util.BUILTINS.good_name, ['pkg']) self.assertIsNone(loader) -Frozen_FinderTests, Source_FinderTests = util.test_both(FinderTests, - machinery=[frozen_machinery, source_machinery]) + +(Frozen_FinderTests, + Source_FinderTests + ) = util.test_both(FinderTests, machinery=machinery) if __name__ == '__main__': diff --git a/Lib/test/test_importlib/builtin/test_loader.py b/Lib/test/test_importlib/builtin/test_loader.py index a636f778fa51..1684ab6eb411 100644 --- a/Lib/test/test_importlib/builtin/test_loader.py +++ b/Lib/test/test_importlib/builtin/test_loader.py @@ -1,14 +1,13 @@ from .. import abc from .. import util -from . import util as builtin_util -frozen_machinery, source_machinery = util.import_importlib('importlib.machinery') +machinery = util.import_importlib('importlib.machinery') import sys import types import unittest - +@unittest.skipIf(util.BUILTINS.good_name is None, 'no reasonable builtin module') class LoaderTests(abc.LoaderTests): """Test load_module() for built-in modules.""" @@ -29,8 +28,8 @@ def load_module(self, name): def test_module(self): # Common case. - with util.uncache(builtin_util.NAME): - module = self.load_module(builtin_util.NAME) + with util.uncache(util.BUILTINS.good_name): + module = self.load_module(util.BUILTINS.good_name) self.verify(module) # Built-in modules cannot be a package. @@ -41,9 +40,9 @@ def test_module(self): def test_module_reuse(self): # Test that the same module is used in a reload. - with util.uncache(builtin_util.NAME): - module1 = self.load_module(builtin_util.NAME) - module2 = self.load_module(builtin_util.NAME) + with util.uncache(util.BUILTINS.good_name): + module1 = self.load_module(util.BUILTINS.good_name) + module2 = self.load_module(util.BUILTINS.good_name) self.assertIs(module1, module2) def test_unloadable(self): @@ -66,40 +65,44 @@ def test_already_imported(self): self.assertEqual(cm.exception.name, module_name) -Frozen_LoaderTests, Source_LoaderTests = util.test_both(LoaderTests, - machinery=[frozen_machinery, source_machinery]) +(Frozen_LoaderTests, + Source_LoaderTests + ) = util.test_both(LoaderTests, machinery=machinery) +@unittest.skipIf(util.BUILTINS.good_name is None, 'no reasonable builtin module') class InspectLoaderTests: """Tests for InspectLoader methods for BuiltinImporter.""" def test_get_code(self): # There is no code object. - result = self.machinery.BuiltinImporter.get_code(builtin_util.NAME) + result = self.machinery.BuiltinImporter.get_code(util.BUILTINS.good_name) self.assertIsNone(result) def test_get_source(self): # There is no source. - result = self.machinery.BuiltinImporter.get_source(builtin_util.NAME) + result = self.machinery.BuiltinImporter.get_source(util.BUILTINS.good_name) self.assertIsNone(result) def test_is_package(self): # Cannot be a package. - result = self.machinery.BuiltinImporter.is_package(builtin_util.NAME) - self.assertTrue(not result) + result = self.machinery.BuiltinImporter.is_package(util.BUILTINS.good_name) + self.assertFalse(result) + @unittest.skipIf(util.BUILTINS.bad_name is None, 'all modules are built in') def test_not_builtin(self): # Modules not built-in should raise ImportError. for meth_name in ('get_code', 'get_source', 'is_package'): method = getattr(self.machinery.BuiltinImporter, meth_name) with self.assertRaises(ImportError) as cm: - method(builtin_util.BAD_NAME) - self.assertRaises(builtin_util.BAD_NAME) + method(util.BUILTINS.bad_name) + self.assertRaises(util.BUILTINS.bad_name) + -Frozen_InspectLoaderTests, Source_InspectLoaderTests = util.test_both( - InspectLoaderTests, - machinery=[frozen_machinery, source_machinery]) +(Frozen_InspectLoaderTests, + Source_InspectLoaderTests + ) = util.test_both(InspectLoaderTests, machinery=machinery) if __name__ == '__main__': diff --git a/Lib/test/test_importlib/builtin/util.py b/Lib/test/test_importlib/builtin/util.py deleted file mode 100644 index 5704699ee239..000000000000 --- a/Lib/test/test_importlib/builtin/util.py +++ /dev/null @@ -1,7 +0,0 @@ -import sys - -assert 'errno' in sys.builtin_module_names -NAME = 'errno' - -assert 'importlib' not in sys.builtin_module_names -BAD_NAME = 'importlib' diff --git a/Lib/test/test_importlib/extension/__init__.py b/Lib/test/test_importlib/extension/__init__.py index c0339236fa61..4b16ecc31156 100644 --- a/Lib/test/test_importlib/extension/__init__.py +++ b/Lib/test/test_importlib/extension/__init__.py @@ -1,13 +1,5 @@ -from .. import test_suite -import os.path -import unittest +import os +from test.support import load_package_tests - -def test_suite(): - directory = os.path.dirname(__file__) - return test_suite('importlib.test.extension', directory) - - -if __name__ == '__main__': - from test.support import run_unittest - run_unittest(test_suite()) +def load_tests(*args): + return load_package_tests(os.path.dirname(__file__), *args) diff --git a/Lib/test/test_importlib/extension/__main__.py b/Lib/test/test_importlib/extension/__main__.py new file mode 100644 index 000000000000..40a23a297ec2 --- /dev/null +++ b/Lib/test/test_importlib/extension/__main__.py @@ -0,0 +1,4 @@ +from . import load_tests +import unittest + +unittest.main() diff --git a/Lib/test/test_importlib/extension/test_case_sensitivity.py b/Lib/test/test_importlib/extension/test_case_sensitivity.py index bb2528e6267c..c7d6ca61f8e3 100644 --- a/Lib/test/test_importlib/extension/test_case_sensitivity.py +++ b/Lib/test/test_importlib/extension/test_case_sensitivity.py @@ -4,22 +4,21 @@ import unittest from .. import util -from . import util as ext_util -frozen_machinery, source_machinery = util.import_importlib('importlib.machinery') +machinery = util.import_importlib('importlib.machinery') # XXX find_spec tests -@unittest.skipIf(ext_util.FILENAME is None, '_testcapi not available') +@unittest.skipIf(util.EXTENSIONS.filename is None, '_testcapi not available') @util.case_insensitive_tests class ExtensionModuleCaseSensitivityTest: def find_module(self): - good_name = ext_util.NAME + good_name = util.EXTENSIONS.name bad_name = good_name.upper() assert good_name != bad_name - finder = self.machinery.FileFinder(ext_util.PATH, + finder = self.machinery.FileFinder(util.EXTENSIONS.path, (self.machinery.ExtensionFileLoader, self.machinery.EXTENSION_SUFFIXES)) return finder.find_module(bad_name) @@ -42,9 +41,10 @@ def test_case_insensitivity(self): loader = self.find_module() self.assertTrue(hasattr(loader, 'load_module')) -Frozen_ExtensionCaseSensitivity, Source_ExtensionCaseSensitivity = util.test_both( - ExtensionModuleCaseSensitivityTest, - machinery=[frozen_machinery, source_machinery]) + +(Frozen_ExtensionCaseSensitivity, + Source_ExtensionCaseSensitivity + ) = util.test_both(ExtensionModuleCaseSensitivityTest, machinery=machinery) if __name__ == '__main__': diff --git a/Lib/test/test_importlib/extension/test_finder.py b/Lib/test/test_importlib/extension/test_finder.py index d0c8bb099437..71bf67febdfa 100644 --- a/Lib/test/test_importlib/extension/test_finder.py +++ b/Lib/test/test_importlib/extension/test_finder.py @@ -1,10 +1,10 @@ from .. import abc -from .. import util as test_util -from . import util +from .. import util -machinery = test_util.import_importlib('importlib.machinery') +machinery = util.import_importlib('importlib.machinery') import unittest +import warnings # XXX find_spec tests @@ -13,13 +13,15 @@ class FinderTests(abc.FinderTests): """Test the finder for extension modules.""" def find_module(self, fullname): - importer = self.machinery.FileFinder(util.PATH, + importer = self.machinery.FileFinder(util.EXTENSIONS.path, (self.machinery.ExtensionFileLoader, self.machinery.EXTENSION_SUFFIXES)) - return importer.find_module(fullname) + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + return importer.find_module(fullname) def test_module(self): - self.assertTrue(self.find_module(util.NAME)) + self.assertTrue(self.find_module(util.EXTENSIONS.name)) # No extension module as an __init__ available for testing. test_package = test_package_in_package = None @@ -33,8 +35,10 @@ def test_module(self): def test_failure(self): self.assertIsNone(self.find_module('asdfjkl;')) -Frozen_FinderTests, Source_FinderTests = test_util.test_both( - FinderTests, machinery=machinery) + +(Frozen_FinderTests, + Source_FinderTests + ) = util.test_both(FinderTests, machinery=machinery) if __name__ == '__main__': diff --git a/Lib/test/test_importlib/extension/test_loader.py b/Lib/test/test_importlib/extension/test_loader.py index d04dff5959c9..aefd050ff0c7 100644 --- a/Lib/test/test_importlib/extension/test_loader.py +++ b/Lib/test/test_importlib/extension/test_loader.py @@ -1,4 +1,3 @@ -from . import util as ext_util from .. import abc from .. import util @@ -15,8 +14,8 @@ class LoaderTests(abc.LoaderTests): """Test load_module() for extension modules.""" def setUp(self): - self.loader = self.machinery.ExtensionFileLoader(ext_util.NAME, - ext_util.FILEPATH) + self.loader = self.machinery.ExtensionFileLoader(util.EXTENSIONS.name, + util.EXTENSIONS.file_path) def load_module(self, fullname): return self.loader.load_module(fullname) @@ -28,15 +27,24 @@ def test_load_module_API(self): with self.assertRaises(ImportError): self.load_module('XXX') + def test_equality(self): + other = self.machinery.ExtensionFileLoader(util.EXTENSIONS.name, + util.EXTENSIONS.file_path) + self.assertEqual(self.loader, other) + + def test_inequality(self): + other = self.machinery.ExtensionFileLoader('_' + util.EXTENSIONS.name, + util.EXTENSIONS.file_path) + self.assertNotEqual(self.loader, other) def test_module(self): - with util.uncache(ext_util.NAME): - module = self.load_module(ext_util.NAME) - for attr, value in [('__name__', ext_util.NAME), - ('__file__', ext_util.FILEPATH), + with util.uncache(util.EXTENSIONS.name): + module = self.load_module(util.EXTENSIONS.name) + for attr, value in [('__name__', util.EXTENSIONS.name), + ('__file__', util.EXTENSIONS.file_path), ('__package__', '')]: self.assertEqual(getattr(module, attr), value) - self.assertIn(ext_util.NAME, sys.modules) + self.assertIn(util.EXTENSIONS.name, sys.modules) self.assertIsInstance(module.__loader__, self.machinery.ExtensionFileLoader) @@ -47,9 +55,9 @@ def test_module(self): test_lacking_parent = None def test_module_reuse(self): - with util.uncache(ext_util.NAME): - module1 = self.load_module(ext_util.NAME) - module2 = self.load_module(ext_util.NAME) + with util.uncache(util.EXTENSIONS.name): + module1 = self.load_module(util.EXTENSIONS.name) + module2 = self.load_module(util.EXTENSIONS.name) self.assertIs(module1, module2) # No easy way to trigger a failure after a successful import. @@ -62,14 +70,15 @@ def test_unloadable(self): self.assertEqual(cm.exception.name, name) def test_is_package(self): - self.assertFalse(self.loader.is_package(ext_util.NAME)) + self.assertFalse(self.loader.is_package(util.EXTENSIONS.name)) for suffix in self.machinery.EXTENSION_SUFFIXES: path = os.path.join('some', 'path', 'pkg', '__init__' + suffix) loader = self.machinery.ExtensionFileLoader('pkg', path) self.assertTrue(loader.is_package('pkg')) -Frozen_LoaderTests, Source_LoaderTests = util.test_both( - LoaderTests, machinery=machinery) +(Frozen_LoaderTests, + Source_LoaderTests + ) = util.test_both(LoaderTests, machinery=machinery) diff --git a/Lib/test/test_importlib/extension/test_path_hook.py b/Lib/test/test_importlib/extension/test_path_hook.py index 49d6734711b6..8f4b8bb16126 100644 --- a/Lib/test/test_importlib/extension/test_path_hook.py +++ b/Lib/test/test_importlib/extension/test_path_hook.py @@ -1,7 +1,6 @@ -from .. import util as test_util -from . import util +from .. import util -machinery = test_util.import_importlib('importlib.machinery') +machinery = util.import_importlib('importlib.machinery') import collections import sys @@ -22,10 +21,12 @@ def hook(self, entry): def test_success(self): # Path hook should handle a directory where a known extension module # exists. - self.assertTrue(hasattr(self.hook(util.PATH), 'find_module')) + self.assertTrue(hasattr(self.hook(util.EXTENSIONS.path), 'find_module')) -Frozen_PathHooksTests, Source_PathHooksTests = test_util.test_both( - PathHookTests, machinery=machinery) + +(Frozen_PathHooksTests, + Source_PathHooksTests + ) = util.test_both(PathHookTests, machinery=machinery) if __name__ == '__main__': diff --git a/Lib/test/test_importlib/extension/util.py b/Lib/test/test_importlib/extension/util.py deleted file mode 100644 index 8d089f0d7c3f..000000000000 --- a/Lib/test/test_importlib/extension/util.py +++ /dev/null @@ -1,19 +0,0 @@ -from importlib import machinery -import os -import sys - -PATH = None -EXT = None -FILENAME = None -NAME = '_testcapi' -try: - for PATH in sys.path: - for EXT in machinery.EXTENSION_SUFFIXES: - FILENAME = NAME + EXT - FILEPATH = os.path.join(PATH, FILENAME) - if os.path.exists(os.path.join(PATH, FILENAME)): - raise StopIteration - else: - PATH = EXT = FILENAME = FILEPATH = None -except StopIteration: - pass diff --git a/Lib/test/test_importlib/frozen/__init__.py b/Lib/test/test_importlib/frozen/__init__.py index 9ef103bce708..4b16ecc31156 100644 --- a/Lib/test/test_importlib/frozen/__init__.py +++ b/Lib/test/test_importlib/frozen/__init__.py @@ -1,13 +1,5 @@ -from .. import test_suite -import os.path -import unittest +import os +from test.support import load_package_tests - -def test_suite(): - directory = os.path.dirname(__file__) - return test_suite('importlib.test.frozen', directory) - - -if __name__ == '__main__': - from test.support import run_unittest - run_unittest(test_suite()) +def load_tests(*args): + return load_package_tests(os.path.dirname(__file__), *args) diff --git a/Lib/test/test_importlib/frozen/__main__.py b/Lib/test/test_importlib/frozen/__main__.py new file mode 100644 index 000000000000..40a23a297ec2 --- /dev/null +++ b/Lib/test/test_importlib/frozen/__main__.py @@ -0,0 +1,4 @@ +from . import load_tests +import unittest + +unittest.main() diff --git a/Lib/test/test_importlib/frozen/test_finder.py b/Lib/test/test_importlib/frozen/test_finder.py index f9f97f385108..519aa027d610 100644 --- a/Lib/test/test_importlib/frozen/test_finder.py +++ b/Lib/test/test_importlib/frozen/test_finder.py @@ -37,8 +37,10 @@ def test_failure(self): spec = self.find('') self.assertIsNone(spec) -Frozen_FindSpecTests, Source_FindSpecTests = util.test_both(FindSpecTests, - machinery=machinery) + +(Frozen_FindSpecTests, + Source_FindSpecTests + ) = util.test_both(FindSpecTests, machinery=machinery) class FinderTests(abc.FinderTests): @@ -72,8 +74,10 @@ def test_failure(self): loader = self.find('') self.assertIsNone(loader) -Frozen_FinderTests, Source_FinderTests = util.test_both(FinderTests, - machinery=machinery) + +(Frozen_FinderTests, + Source_FinderTests + ) = util.test_both(FinderTests, machinery=machinery) if __name__ == '__main__': diff --git a/Lib/test/test_importlib/frozen/test_loader.py b/Lib/test/test_importlib/frozen/test_loader.py index 2abbe929bc71..603c7d7b1929 100644 --- a/Lib/test/test_importlib/frozen/test_loader.py +++ b/Lib/test/test_importlib/frozen/test_loader.py @@ -8,6 +8,7 @@ from test.support import captured_stdout import types import unittest +import warnings class ExecModuleTests(abc.LoaderTests): @@ -60,8 +61,16 @@ def test_lacking_parent(self): expected=value)) self.assertEqual(output, 'Hello world!\n') - def test_module_repr(self): + name = '__hello__' + module, output = self.exec_module(name) + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + repr_str = self.machinery.FrozenImporter.module_repr(module) + self.assertEqual(repr_str, + "") + + def test_module_repr_indirect(self): name = '__hello__' module, output = self.exec_module(name) self.assertEqual(repr(module), @@ -76,15 +85,19 @@ def test_unloadable(self): self.exec_module('_not_real') self.assertEqual(cm.exception.name, '_not_real') -Frozen_ExecModuleTests, Source_ExecModuleTests = util.test_both(ExecModuleTests, - machinery=machinery) + +(Frozen_ExecModuleTests, + Source_ExecModuleTests + ) = util.test_both(ExecModuleTests, machinery=machinery) class LoaderTests(abc.LoaderTests): def test_module(self): with util.uncache('__hello__'), captured_stdout() as stdout: - module = self.machinery.FrozenImporter.load_module('__hello__') + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + module = self.machinery.FrozenImporter.load_module('__hello__') check = {'__name__': '__hello__', '__package__': '', '__loader__': self.machinery.FrozenImporter, @@ -96,7 +109,9 @@ def test_module(self): def test_package(self): with util.uncache('__phello__'), captured_stdout() as stdout: - module = self.machinery.FrozenImporter.load_module('__phello__') + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + module = self.machinery.FrozenImporter.load_module('__phello__') check = {'__name__': '__phello__', '__package__': '__phello__', '__path__': [], @@ -113,7 +128,9 @@ def test_package(self): def test_lacking_parent(self): with util.uncache('__phello__', '__phello__.spam'), \ captured_stdout() as stdout: - module = self.machinery.FrozenImporter.load_module('__phello__.spam') + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + module = self.machinery.FrozenImporter.load_module('__phello__.spam') check = {'__name__': '__phello__.spam', '__package__': '__phello__', '__loader__': self.machinery.FrozenImporter, @@ -128,18 +145,29 @@ def test_lacking_parent(self): def test_module_reuse(self): with util.uncache('__hello__'), captured_stdout() as stdout: - module1 = self.machinery.FrozenImporter.load_module('__hello__') - module2 = self.machinery.FrozenImporter.load_module('__hello__') + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + module1 = self.machinery.FrozenImporter.load_module('__hello__') + module2 = self.machinery.FrozenImporter.load_module('__hello__') self.assertIs(module1, module2) self.assertEqual(stdout.getvalue(), 'Hello world!\nHello world!\n') def test_module_repr(self): with util.uncache('__hello__'), captured_stdout(): - module = self.machinery.FrozenImporter.load_module('__hello__') - self.assertEqual(repr(module), + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + module = self.machinery.FrozenImporter.load_module('__hello__') + repr_str = self.machinery.FrozenImporter.module_repr(module) + self.assertEqual(repr_str, "") + def test_module_repr_indirect(self): + with util.uncache('__hello__'), captured_stdout(): + module = self.machinery.FrozenImporter.load_module('__hello__') + self.assertEqual(repr(module), + "") + # No way to trigger an error in a frozen module. test_state_after_failure = None @@ -149,8 +177,10 @@ def test_unloadable(self): self.machinery.FrozenImporter.load_module('_not_real') self.assertEqual(cm.exception.name, '_not_real') -Frozen_LoaderTests, Source_LoaderTests = util.test_both(LoaderTests, - machinery=machinery) + +(Frozen_LoaderTests, + Source_LoaderTests + ) = util.test_both(LoaderTests, machinery=machinery) class InspectLoaderTests: @@ -188,8 +218,9 @@ def test_failure(self): method('importlib') self.assertEqual(cm.exception.name, 'importlib') -Frozen_ILTests, Source_ILTests = util.test_both(InspectLoaderTests, - machinery=machinery) +(Frozen_ILTests, + Source_ILTests + ) = util.test_both(InspectLoaderTests, machinery=machinery) if __name__ == '__main__': diff --git a/Lib/test/test_importlib/import_/__init__.py b/Lib/test/test_importlib/import_/__init__.py index 366e53133379..4b16ecc31156 100644 --- a/Lib/test/test_importlib/import_/__init__.py +++ b/Lib/test/test_importlib/import_/__init__.py @@ -1,13 +1,5 @@ -from .. import test_suite -import os.path -import unittest +import os +from test.support import load_package_tests - -def test_suite(): - directory = os.path.dirname(__file__) - return test_suite('importlib.test.import_', directory) - - -if __name__ == '__main__': - from test.support import run_unittest - run_unittest(test_suite()) +def load_tests(*args): + return load_package_tests(os.path.dirname(__file__), *args) diff --git a/Lib/test/test_importlib/import_/__main__.py b/Lib/test/test_importlib/import_/__main__.py new file mode 100644 index 000000000000..40a23a297ec2 --- /dev/null +++ b/Lib/test/test_importlib/import_/__main__.py @@ -0,0 +1,4 @@ +from . import load_tests +import unittest + +unittest.main() diff --git a/Lib/test/test_importlib/import_/test___loader__.py b/Lib/test/test_importlib/import_/test___loader__.py index 6df80101fa50..4b18093cf903 100644 --- a/Lib/test/test_importlib/import_/test___loader__.py +++ b/Lib/test/test_importlib/import_/test___loader__.py @@ -4,7 +4,6 @@ import unittest from .. import util -from . import util as import_util class SpecLoaderMock: @@ -12,6 +11,9 @@ class SpecLoaderMock: def find_spec(self, fullname, path=None, target=None): return machinery.ModuleSpec(fullname, self) + def create_module(self, spec): + return None + def exec_module(self, module): pass @@ -24,8 +26,10 @@ def test___loader__(self): module = self.__import__('blah') self.assertEqual(loader, module.__loader__) -Frozen_SpecTests, Source_SpecTests = util.test_both( - SpecLoaderAttributeTests, __import__=import_util.__import__) + +(Frozen_SpecTests, + Source_SpecTests + ) = util.test_both(SpecLoaderAttributeTests, __import__=util.__import__) class LoaderMock: @@ -62,8 +66,9 @@ def test___loader___is_None(self): self.assertEqual(loader, module.__loader__) -Frozen_Tests, Source_Tests = util.test_both(LoaderAttributeTests, - __import__=import_util.__import__) +(Frozen_Tests, + Source_Tests + ) = util.test_both(LoaderAttributeTests, __import__=util.__import__) if __name__ == '__main__': diff --git a/Lib/test/test_importlib/import_/test___package__.py b/Lib/test/test_importlib/import_/test___package__.py index 5fa432f2e3cf..c7d3a2a20487 100644 --- a/Lib/test/test_importlib/import_/test___package__.py +++ b/Lib/test/test_importlib/import_/test___package__.py @@ -6,7 +6,6 @@ """ import unittest from .. import util -from . import util as import_util class Using__package__: @@ -36,7 +35,7 @@ def calc_package(caller_name, has___path__): def test_using___package__(self): # [__package__] - with util.mock_modules('pkg.__init__', 'pkg.fake') as importer: + with self.mock_modules('pkg.__init__', 'pkg.fake') as importer: with util.import_state(meta_path=[importer]): self.__import__('pkg.fake') module = self.__import__('', @@ -49,7 +48,7 @@ def test_using___name__(self, package_as_None=False): globals_ = {'__name__': 'pkg.fake', '__path__': []} if package_as_None: globals_['__package__'] = None - with util.mock_modules('pkg.__init__', 'pkg.fake') as importer: + with self.mock_modules('pkg.__init__', 'pkg.fake') as importer: with util.import_state(meta_path=[importer]): self.__import__('pkg.fake') module = self.__import__('', globals= globals_, @@ -70,11 +69,26 @@ def test_bunk__package__(self): with self.assertRaises(TypeError): self.__import__('', globals, {}, ['relimport'], 1) -Frozen_UsingPackage, Source_UsingPackage = util.test_both( - Using__package__, __import__=import_util.__import__) +class Using__package__PEP302(Using__package__): + mock_modules = util.mock_modules -class Setting__package__(unittest.TestCase): + +(Frozen_UsingPackagePEP302, + Source_UsingPackagePEP302 + ) = util.test_both(Using__package__PEP302, __import__=util.__import__) + + +class Using__package__PEP451(Using__package__): + mock_modules = util.mock_spec + + +(Frozen_UsingPackagePEP451, + Source_UsingPackagePEP451 + ) = util.test_both(Using__package__PEP451, __import__=util.__import__) + + +class Setting__package__: """Because __package__ is a new feature, it is not always set by a loader. Import will set it as needed to help with the transition to relying on @@ -86,11 +100,11 @@ class Setting__package__(unittest.TestCase): """ - __import__ = import_util.__import__[1] + __import__ = util.__import__['Source'] # [top-level] def test_top_level(self): - with util.mock_modules('top_level') as mock: + with self.mock_modules('top_level') as mock: with util.import_state(meta_path=[mock]): del mock['top_level'].__package__ module = self.__import__('top_level') @@ -98,7 +112,7 @@ def test_top_level(self): # [package] def test_package(self): - with util.mock_modules('pkg.__init__') as mock: + with self.mock_modules('pkg.__init__') as mock: with util.import_state(meta_path=[mock]): del mock['pkg'].__package__ module = self.__import__('pkg') @@ -106,13 +120,19 @@ def test_package(self): # [submodule] def test_submodule(self): - with util.mock_modules('pkg.__init__', 'pkg.mod') as mock: + with self.mock_modules('pkg.__init__', 'pkg.mod') as mock: with util.import_state(meta_path=[mock]): del mock['pkg.mod'].__package__ pkg = self.__import__('pkg.mod') module = getattr(pkg, 'mod') self.assertEqual(module.__package__, 'pkg') +class Setting__package__PEP302(Setting__package__, unittest.TestCase): + mock_modules = util.mock_modules + +class Setting__package__PEP451(Setting__package__, unittest.TestCase): + mock_modules = util.mock_spec + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_importlib/import_/test_api.py b/Lib/test/test_importlib/import_/test_api.py index 439c105e9b49..7069d9e58dca 100644 --- a/Lib/test/test_importlib/import_/test_api.py +++ b/Lib/test/test_importlib/import_/test_api.py @@ -1,5 +1,4 @@ from .. import util -from . import util as import_util from importlib import machinery import sys @@ -17,6 +16,10 @@ def find_spec(cls, fullname, path=None, target=None): spec = machinery.ModuleSpec(fullname, cls) return spec + @staticmethod + def create_module(spec): + return None + @staticmethod def exec_module(module): if module.__name__ == SUBMOD_NAME: @@ -79,15 +82,19 @@ def test_fromlist_load_error_propagates(self): class OldAPITests(APITest): bad_finder_loader = BadLoaderFinder -Frozen_OldAPITests, Source_OldAPITests = util.test_both( - OldAPITests, __import__=import_util.__import__) + +(Frozen_OldAPITests, + Source_OldAPITests + ) = util.test_both(OldAPITests, __import__=util.__import__) class SpecAPITests(APITest): bad_finder_loader = BadSpecFinderLoader -Frozen_SpecAPITests, Source_SpecAPITests = util.test_both( - SpecAPITests, __import__=import_util.__import__) + +(Frozen_SpecAPITests, + Source_SpecAPITests + ) = util.test_both(SpecAPITests, __import__=util.__import__) if __name__ == '__main__': diff --git a/Lib/test/test_importlib/import_/test_caching.py b/Lib/test/test_importlib/import_/test_caching.py index 4d082b8eeb2a..8079add5b214 100644 --- a/Lib/test/test_importlib/import_/test_caching.py +++ b/Lib/test/test_importlib/import_/test_caching.py @@ -1,6 +1,5 @@ """Test that sys.modules is used properly by import.""" from .. import util -from . import util as import_util import sys from types import MethodType import unittest @@ -39,6 +38,18 @@ def test_None_in_cache(self): self.__import__(name) self.assertEqual(cm.exception.name, name) + +(Frozen_UseCache, + Source_UseCache + ) = util.test_both(UseCache, __import__=util.__import__) + + +class ImportlibUseCache(UseCache, unittest.TestCase): + + # Pertinent only to PEP 302; exec_module() doesn't return a module. + + __import__ = util.__import__['Source'] + def create_mock(self, *names, return_=None): mock = util.mock_modules(*names) original_load = mock.load_module @@ -48,14 +59,6 @@ def load_module(self, fullname): mock.load_module = MethodType(load_module, mock) return mock -Frozen_UseCache, Source_UseCache = util.test_both( - UseCache, __import__=import_util.__import__) - - -class ImportlibUseCache(UseCache, unittest.TestCase): - - __import__ = import_util.__import__[1] - # __import__ inconsistent between loaders and built-in import when it comes # to when to use the module in sys.modules and when not to. def test_using_cache_after_loader(self): diff --git a/Lib/test/test_importlib/import_/test_fromlist.py b/Lib/test/test_importlib/import_/test_fromlist.py index fc29ce667dca..80454655adad 100644 --- a/Lib/test/test_importlib/import_/test_fromlist.py +++ b/Lib/test/test_importlib/import_/test_fromlist.py @@ -1,6 +1,5 @@ """Test that the semantics relating to the 'fromlist' argument are correct.""" from .. import util -from . import util as import_util import unittest @@ -17,7 +16,7 @@ class ReturnValue: def test_return_from_import(self): # [import return] - with util.mock_modules('pkg.__init__', 'pkg.module') as importer: + with util.mock_spec('pkg.__init__', 'pkg.module') as importer: with util.import_state(meta_path=[importer]): module = self.__import__('pkg.module') self.assertEqual(module.__name__, 'pkg') @@ -29,8 +28,10 @@ def test_return_from_from_import(self): module = self.__import__('pkg.module', fromlist=['attr']) self.assertEqual(module.__name__, 'pkg.module') -Frozen_ReturnValue, Source_ReturnValue = util.test_both( - ReturnValue, __import__=import_util.__import__) + +(Frozen_ReturnValue, + Source_ReturnValue + ) = util.test_both(ReturnValue, __import__=util.__import__) class HandlingFromlist: @@ -61,7 +62,7 @@ def test_nonexistent_object(self): with util.import_state(meta_path=[importer]): module = self.__import__('module', fromlist=['non_existent']) self.assertEqual(module.__name__, 'module') - self.assertTrue(not hasattr(module, 'non_existent')) + self.assertFalse(hasattr(module, 'non_existent')) def test_module_from_package(self): # [module] @@ -121,8 +122,10 @@ def test_star_with_others(self): self.assertEqual(module.module1.__name__, 'pkg.module1') self.assertEqual(module.module2.__name__, 'pkg.module2') -Frozen_FromList, Source_FromList = util.test_both( - HandlingFromlist, __import__=import_util.__import__) + +(Frozen_FromList, + Source_FromList + ) = util.test_both(HandlingFromlist, __import__=util.__import__) if __name__ == '__main__': diff --git a/Lib/test/test_importlib/import_/test_meta_path.py b/Lib/test/test_importlib/import_/test_meta_path.py index a56253ddde09..c452cdd063c4 100644 --- a/Lib/test/test_importlib/import_/test_meta_path.py +++ b/Lib/test/test_importlib/import_/test_meta_path.py @@ -1,5 +1,4 @@ from .. import util -from . import util as import_util import importlib._bootstrap import sys from types import MethodType @@ -18,23 +17,18 @@ class CallingOrder: def test_first_called(self): # [first called] mod = 'top_level' - first = util.mock_modules(mod) - second = util.mock_modules(mod) - with util.mock_modules(mod) as first, util.mock_modules(mod) as second: - first.modules[mod] = 42 - second.modules[mod] = -13 + with util.mock_spec(mod) as first, util.mock_spec(mod) as second: with util.import_state(meta_path=[first, second]): - self.assertEqual(self.__import__(mod), 42) + self.assertIs(self.__import__(mod), first.modules[mod]) def test_continuing(self): # [continuing] mod_name = 'for_real' - with util.mock_modules('nonexistent') as first, \ - util.mock_modules(mod_name) as second: - first.find_module = lambda self, fullname, path=None: None - second.modules[mod_name] = 42 + with util.mock_spec('nonexistent') as first, \ + util.mock_spec(mod_name) as second: + first.find_spec = lambda self, fullname, path=None, parent=None: None with util.import_state(meta_path=[first, second]): - self.assertEqual(self.__import__(mod_name), 42) + self.assertIs(self.__import__(mod_name), second.modules[mod_name]) def test_empty(self): # Raise an ImportWarning if sys.meta_path is empty. @@ -51,8 +45,10 @@ def test_empty(self): self.assertEqual(len(w), 1) self.assertTrue(issubclass(w[-1].category, ImportWarning)) -Frozen_CallingOrder, Source_CallingOrder = util.test_both( - CallingOrder, __import__=import_util.__import__) + +(Frozen_CallingOrder, + Source_CallingOrder + ) = util.test_both(CallingOrder, __import__=util.__import__) class CallSignature: @@ -61,29 +57,27 @@ class CallSignature: [no path]. Otherwise, the value for __path__ is passed in for the 'path' argument [path set].""" - def log(self, fxn): + def log_finder(self, importer): + fxn = getattr(importer, self.finder_name) log = [] def wrapper(self, *args, **kwargs): log.append([args, kwargs]) return fxn(*args, **kwargs) return log, wrapper - def test_no_path(self): # [no path] mod_name = 'top_level' assert '.' not in mod_name - with util.mock_modules(mod_name) as importer: - log, wrapped_call = self.log(importer.find_module) - importer.find_module = MethodType(wrapped_call, importer) + with self.mock_modules(mod_name) as importer: + log, wrapped_call = self.log_finder(importer) + setattr(importer, self.finder_name, MethodType(wrapped_call, importer)) with util.import_state(meta_path=[importer]): self.__import__(mod_name) assert len(log) == 1 args = log[0][0] kwargs = log[0][1] # Assuming all arguments are positional. - self.assertEqual(len(args), 2) - self.assertEqual(len(kwargs), 0) self.assertEqual(args[0], mod_name) self.assertIsNone(args[1]) @@ -93,22 +87,39 @@ def test_with_path(self): mod_name = pkg_name + '.module' path = [42] assert '.' in mod_name - with util.mock_modules(pkg_name+'.__init__', mod_name) as importer: + with self.mock_modules(pkg_name+'.__init__', mod_name) as importer: importer.modules[pkg_name].__path__ = path - log, wrapped_call = self.log(importer.find_module) - importer.find_module = MethodType(wrapped_call, importer) + log, wrapped_call = self.log_finder(importer) + setattr(importer, self.finder_name, MethodType(wrapped_call, importer)) with util.import_state(meta_path=[importer]): self.__import__(mod_name) assert len(log) == 2 args = log[1][0] kwargs = log[1][1] # Assuming all arguments are positional. - self.assertTrue(not kwargs) + self.assertFalse(kwargs) self.assertEqual(args[0], mod_name) self.assertIs(args[1], path) -Frozen_CallSignature, Source_CallSignature = util.test_both( - CallSignature, __import__=import_util.__import__) + +class CallSignaturePEP302(CallSignature): + mock_modules = util.mock_modules + finder_name = 'find_module' + + +(Frozen_CallSignaturePEP302, + Source_CallSignaturePEP302 + ) = util.test_both(CallSignaturePEP302, __import__=util.__import__) + + +class CallSignaturePEP451(CallSignature): + mock_modules = util.mock_spec + finder_name = 'find_spec' + + +(Frozen_CallSignaturePEP451, + Source_CallSignaturePEP451 + ) = util.test_both(CallSignaturePEP451, __import__=util.__import__) if __name__ == '__main__': diff --git a/Lib/test/test_importlib/import_/test_packages.py b/Lib/test/test_importlib/import_/test_packages.py index 2df421d78eae..3755b84a1a0f 100644 --- a/Lib/test/test_importlib/import_/test_packages.py +++ b/Lib/test/test_importlib/import_/test_packages.py @@ -1,5 +1,4 @@ from .. import util -from . import util as import_util import sys import unittest import importlib @@ -11,13 +10,13 @@ class ParentModuleTests: """Importing a submodule should import the parent modules.""" def test_import_parent(self): - with util.mock_modules('pkg.__init__', 'pkg.module') as mock: + with util.mock_spec('pkg.__init__', 'pkg.module') as mock: with util.import_state(meta_path=[mock]): module = self.__import__('pkg.module') self.assertIn('pkg', sys.modules) def test_bad_parent(self): - with util.mock_modules('pkg.module') as mock: + with util.mock_spec('pkg.module') as mock: with util.import_state(meta_path=[mock]): with self.assertRaises(ImportError) as cm: self.__import__('pkg.module') @@ -27,7 +26,7 @@ def test_raising_parent_after_importing_child(self): def __init__(): import pkg.module 1/0 - mock = util.mock_modules('pkg.__init__', 'pkg.module', + mock = util.mock_spec('pkg.__init__', 'pkg.module', module_code={'pkg': __init__}) with mock: with util.import_state(meta_path=[mock]): @@ -44,7 +43,7 @@ def test_raising_parent_after_relative_importing_child(self): def __init__(): from . import module 1/0 - mock = util.mock_modules('pkg.__init__', 'pkg.module', + mock = util.mock_spec('pkg.__init__', 'pkg.module', module_code={'pkg': __init__}) with mock: with util.import_state(meta_path=[mock]): @@ -63,7 +62,7 @@ def test_raising_parent_after_double_relative_importing_child(self): def __init__(): from ..subpkg import module 1/0 - mock = util.mock_modules('pkg.__init__', 'pkg.subpkg.__init__', + mock = util.mock_spec('pkg.__init__', 'pkg.subpkg.__init__', 'pkg.subpkg.module', module_code={'pkg.subpkg': __init__}) with mock: @@ -93,17 +92,19 @@ def test_module_not_package_but_side_effects(self): subname = name + '.b' def module_injection(): sys.modules[subname] = 'total bunk' - mock_modules = util.mock_modules('mod', + mock_spec = util.mock_spec('mod', module_code={'mod': module_injection}) - with mock_modules as mock: + with mock_spec as mock: with util.import_state(meta_path=[mock]): try: submodule = self.__import__(subname) finally: support.unload(subname) -Frozen_ParentTests, Source_ParentTests = util.test_both( - ParentModuleTests, __import__=import_util.__import__) + +(Frozen_ParentTests, + Source_ParentTests + ) = util.test_both(ParentModuleTests, __import__=util.__import__) if __name__ == '__main__': diff --git a/Lib/test/test_importlib/import_/test_path.py b/Lib/test/test_importlib/import_/test_path.py index 2e5033eb9ef2..f257f117b479 100644 --- a/Lib/test/test_importlib/import_/test_path.py +++ b/Lib/test/test_importlib/import_/test_path.py @@ -1,11 +1,11 @@ from .. import util -from . import util as import_util importlib = util.import_importlib('importlib') machinery = util.import_importlib('importlib.machinery') import os import sys +import tempfile from types import ModuleType import unittest import warnings @@ -27,7 +27,7 @@ def test_sys_path(self): # Implicitly tests that sys.path_importer_cache is used. module = '' path = '' - importer = util.mock_modules(module) + importer = util.mock_spec(module) with util.import_state(path_importer_cache={path: importer}, path=[path]): loader = self.machinery.PathFinder.find_module(module) @@ -38,7 +38,7 @@ def test_path(self): # Implicitly tests that sys.path_importer_cache is used. module = '' path = '' - importer = util.mock_modules(module) + importer = util.mock_spec(module) with util.import_state(path_importer_cache={path: importer}): loader = self.machinery.PathFinder.find_module(module, [path]) self.assertIs(loader, importer) @@ -47,7 +47,7 @@ def test_empty_list(self): # An empty list should not count as asking for sys.path. module = 'module' path = '' - importer = util.mock_modules(module) + importer = util.mock_spec(module) with util.import_state(path_importer_cache={path: importer}, path=[path]): self.assertIsNone(self.machinery.PathFinder.find_module('module', [])) @@ -57,8 +57,8 @@ def test_path_hooks(self): # Test that sys.path_importer_cache is set. module = '' path = '' - importer = util.mock_modules(module) - hook = import_util.mock_path_hook(path, importer=importer) + importer = util.mock_spec(module) + hook = util.mock_path_hook(path, importer=importer) with util.import_state(path_hooks=[hook]): loader = self.machinery.PathFinder.find_module(module, [path]) self.assertIs(loader, importer) @@ -82,8 +82,8 @@ def test_path_importer_cache_empty_string(self): # The empty string should create a finder using the cwd. path = '' module = '' - importer = util.mock_modules(module) - hook = import_util.mock_path_hook(os.getcwd(), importer=importer) + importer = util.mock_spec(module) + hook = util.mock_path_hook(os.getcwd(), importer=importer) with util.import_state(path=[path], path_hooks=[hook]): loader = self.machinery.PathFinder.find_module(module) self.assertIs(loader, importer) @@ -112,8 +112,101 @@ def test_None_on_sys_path(self): if email is not missing: sys.modules['email'] = email -Frozen_FinderTests, Source_FinderTests = util.test_both( - FinderTests, importlib=importlib, machinery=machinery) + def test_finder_with_find_module(self): + class TestFinder: + def find_module(self, fullname): + return self.to_return + failing_finder = TestFinder() + failing_finder.to_return = None + path = 'testing path' + with util.import_state(path_importer_cache={path: failing_finder}): + self.assertIsNone( + self.machinery.PathFinder.find_spec('whatever', [path])) + success_finder = TestFinder() + success_finder.to_return = __loader__ + with util.import_state(path_importer_cache={path: success_finder}): + spec = self.machinery.PathFinder.find_spec('whatever', [path]) + self.assertEqual(spec.loader, __loader__) + + def test_finder_with_find_loader(self): + class TestFinder: + loader = None + portions = [] + def find_loader(self, fullname): + return self.loader, self.portions + path = 'testing path' + with util.import_state(path_importer_cache={path: TestFinder()}): + self.assertIsNone( + self.machinery.PathFinder.find_spec('whatever', [path])) + success_finder = TestFinder() + success_finder.loader = __loader__ + with util.import_state(path_importer_cache={path: success_finder}): + spec = self.machinery.PathFinder.find_spec('whatever', [path]) + self.assertEqual(spec.loader, __loader__) + + def test_finder_with_find_spec(self): + class TestFinder: + spec = None + def find_spec(self, fullname, target=None): + return self.spec + path = 'testing path' + with util.import_state(path_importer_cache={path: TestFinder()}): + self.assertIsNone( + self.machinery.PathFinder.find_spec('whatever', [path])) + success_finder = TestFinder() + success_finder.spec = self.machinery.ModuleSpec('whatever', __loader__) + with util.import_state(path_importer_cache={path: success_finder}): + got = self.machinery.PathFinder.find_spec('whatever', [path]) + self.assertEqual(got, success_finder.spec) + + @unittest.skipIf(sys.platform == 'win32', "cwd can't not exist on Windows") + def test_deleted_cwd(self): + # Issue #22834 + self.addCleanup(os.chdir, os.getcwd()) + try: + with tempfile.TemporaryDirectory() as path: + os.chdir(path) + except OSError as exc: + if exc.errno == 22: + # issue #22834 + self.skipTest("platform does not allow the deletion of the cwd") + raise + with util.import_state(path=['']): + # Do not want FileNotFoundError raised. + self.assertIsNone(self.machinery.PathFinder.find_spec('whatever')) + + + + +(Frozen_FinderTests, + Source_FinderTests + ) = util.test_both(FinderTests, importlib=importlib, machinery=machinery) + + +class PathEntryFinderTests: + + def test_finder_with_failing_find_module(self): + # PathEntryFinder with find_module() defined should work. + # Issue #20763. + class Finder: + path_location = 'test_finder_with_find_module' + def __init__(self, path): + if path != self.path_location: + raise ImportError + + @staticmethod + def find_module(fullname): + return None + + + with util.import_state(path=[Finder.path_location]+sys.path[:], + path_hooks=[Finder]): + self.machinery.PathFinder.find_spec('importlib') + + +(Frozen_PEFTests, + Source_PEFTests + ) = util.test_both(PathEntryFinderTests, machinery=machinery) if __name__ == '__main__': diff --git a/Lib/test/test_importlib/import_/test_relative_imports.py b/Lib/test/test_importlib/import_/test_relative_imports.py index fc6d25a5e52e..28bb6f7c0c91 100644 --- a/Lib/test/test_importlib/import_/test_relative_imports.py +++ b/Lib/test/test_importlib/import_/test_relative_imports.py @@ -1,6 +1,5 @@ """Test relative imports (PEP 328).""" from .. import util -from . import util as import_util import sys import unittest @@ -64,7 +63,7 @@ def relative_import_test(self, create, globals_, callback): uncache_names.append(name) else: uncache_names.append(name[:-len('.__init__')]) - with util.mock_modules(*create) as importer: + with util.mock_spec(*create) as importer: with util.import_state(meta_path=[importer]): for global_ in globals_: with util.uncache(*uncache_names): @@ -208,8 +207,10 @@ def test_relative_import_no_globals(self): with self.assertRaises(KeyError): self.__import__('sys', level=1) -Frozen_RelativeImports, Source_RelativeImports = util.test_both( - RelativeImports, __import__=import_util.__import__) + +(Frozen_RelativeImports, + Source_RelativeImports + ) = util.test_both(RelativeImports, __import__=util.__import__) if __name__ == '__main__': diff --git a/Lib/test/test_importlib/import_/util.py b/Lib/test/test_importlib/import_/util.py deleted file mode 100644 index dcb490f96754..000000000000 --- a/Lib/test/test_importlib/import_/util.py +++ /dev/null @@ -1,20 +0,0 @@ -from .. import util - -frozen_importlib, source_importlib = util.import_importlib('importlib') - -import builtins -import functools -import importlib -import unittest - - -__import__ = staticmethod(builtins.__import__), staticmethod(source_importlib.__import__) - - -def mock_path_hook(*entries, importer): - """A mock sys.path_hooks entry.""" - def hook(entry): - if entry not in entries: - raise ImportError - return importer - return hook diff --git a/Lib/test/namespace_pkgs/both_portions/foo/one.py b/Lib/test/test_importlib/namespace_pkgs/both_portions/foo/one.py similarity index 100% rename from Lib/test/namespace_pkgs/both_portions/foo/one.py rename to Lib/test/test_importlib/namespace_pkgs/both_portions/foo/one.py diff --git a/Lib/test/namespace_pkgs/both_portions/foo/two.py b/Lib/test/test_importlib/namespace_pkgs/both_portions/foo/two.py similarity index 100% rename from Lib/test/namespace_pkgs/both_portions/foo/two.py rename to Lib/test/test_importlib/namespace_pkgs/both_portions/foo/two.py diff --git a/Lib/test/namespace_pkgs/missing_directory.zip b/Lib/test/test_importlib/namespace_pkgs/missing_directory.zip similarity index 100% rename from Lib/test/namespace_pkgs/missing_directory.zip rename to Lib/test/test_importlib/namespace_pkgs/missing_directory.zip diff --git a/Lib/test/namespace_pkgs/module_and_namespace_package/a_test.py b/Lib/test/test_importlib/namespace_pkgs/module_and_namespace_package/a_test.py similarity index 100% rename from Lib/test/namespace_pkgs/module_and_namespace_package/a_test.py rename to Lib/test/test_importlib/namespace_pkgs/module_and_namespace_package/a_test.py diff --git a/Lib/test/namespace_pkgs/module_and_namespace_package/a_test/empty b/Lib/test/test_importlib/namespace_pkgs/module_and_namespace_package/a_test/empty similarity index 100% rename from Lib/test/namespace_pkgs/module_and_namespace_package/a_test/empty rename to Lib/test/test_importlib/namespace_pkgs/module_and_namespace_package/a_test/empty diff --git a/Lib/test/namespace_pkgs/nested_portion1.zip b/Lib/test/test_importlib/namespace_pkgs/nested_portion1.zip similarity index 100% rename from Lib/test/namespace_pkgs/nested_portion1.zip rename to Lib/test/test_importlib/namespace_pkgs/nested_portion1.zip diff --git a/Lib/test/namespace_pkgs/not_a_namespace_pkg/foo/__init__.py b/Lib/test/test_importlib/namespace_pkgs/not_a_namespace_pkg/foo/__init__.py similarity index 100% rename from Lib/test/namespace_pkgs/not_a_namespace_pkg/foo/__init__.py rename to Lib/test/test_importlib/namespace_pkgs/not_a_namespace_pkg/foo/__init__.py diff --git a/Lib/test/namespace_pkgs/not_a_namespace_pkg/foo/one.py b/Lib/test/test_importlib/namespace_pkgs/not_a_namespace_pkg/foo/one.py similarity index 100% rename from Lib/test/namespace_pkgs/not_a_namespace_pkg/foo/one.py rename to Lib/test/test_importlib/namespace_pkgs/not_a_namespace_pkg/foo/one.py diff --git a/Lib/test/namespace_pkgs/portion1/foo/one.py b/Lib/test/test_importlib/namespace_pkgs/portion1/foo/one.py similarity index 100% rename from Lib/test/namespace_pkgs/portion1/foo/one.py rename to Lib/test/test_importlib/namespace_pkgs/portion1/foo/one.py diff --git a/Lib/test/namespace_pkgs/portion2/foo/two.py b/Lib/test/test_importlib/namespace_pkgs/portion2/foo/two.py similarity index 100% rename from Lib/test/namespace_pkgs/portion2/foo/two.py rename to Lib/test/test_importlib/namespace_pkgs/portion2/foo/two.py diff --git a/Lib/test/namespace_pkgs/project1/parent/child/one.py b/Lib/test/test_importlib/namespace_pkgs/project1/parent/child/one.py similarity index 100% rename from Lib/test/namespace_pkgs/project1/parent/child/one.py rename to Lib/test/test_importlib/namespace_pkgs/project1/parent/child/one.py diff --git a/Lib/test/namespace_pkgs/project2/parent/child/two.py b/Lib/test/test_importlib/namespace_pkgs/project2/parent/child/two.py similarity index 100% rename from Lib/test/namespace_pkgs/project2/parent/child/two.py rename to Lib/test/test_importlib/namespace_pkgs/project2/parent/child/two.py diff --git a/Lib/test/namespace_pkgs/project3/parent/child/three.py b/Lib/test/test_importlib/namespace_pkgs/project3/parent/child/three.py similarity index 100% rename from Lib/test/namespace_pkgs/project3/parent/child/three.py rename to Lib/test/test_importlib/namespace_pkgs/project3/parent/child/three.py diff --git a/Lib/test/namespace_pkgs/top_level_portion1.zip b/Lib/test/test_importlib/namespace_pkgs/top_level_portion1.zip similarity index 100% rename from Lib/test/namespace_pkgs/top_level_portion1.zip rename to Lib/test/test_importlib/namespace_pkgs/top_level_portion1.zip diff --git a/Lib/test/test_importlib/source/__init__.py b/Lib/test/test_importlib/source/__init__.py index 3ef97f3aa039..4b16ecc31156 100644 --- a/Lib/test/test_importlib/source/__init__.py +++ b/Lib/test/test_importlib/source/__init__.py @@ -1,13 +1,5 @@ -from .. import test_suite -import os.path -import unittest +import os +from test.support import load_package_tests - -def test_suite(): - directory = os.path.dirname(__file__) - return test.test_suite('importlib.test.source', directory) - - -if __name__ == '__main__': - from test.support import run_unittest - run_unittest(test_suite()) +def load_tests(*args): + return load_package_tests(os.path.dirname(__file__), *args) diff --git a/Lib/test/test_importlib/source/__main__.py b/Lib/test/test_importlib/source/__main__.py new file mode 100644 index 000000000000..40a23a297ec2 --- /dev/null +++ b/Lib/test/test_importlib/source/__main__.py @@ -0,0 +1,4 @@ +from . import load_tests +import unittest + +unittest.main() diff --git a/Lib/test/test_importlib/source/test_case_sensitivity.py b/Lib/test/test_importlib/source/test_case_sensitivity.py index b3e9d25bb264..29e95b2bbc7b 100644 --- a/Lib/test/test_importlib/source/test_case_sensitivity.py +++ b/Lib/test/test_importlib/source/test_case_sensitivity.py @@ -1,6 +1,5 @@ """Test case-sensitivity (PEP 235).""" from .. import util -from . import util as source_util importlib = util.import_importlib('importlib') machinery = util.import_importlib('importlib.machinery') @@ -21,23 +20,24 @@ class CaseSensitivityTest: name = 'MoDuLe' assert name != name.lower() - def find(self, path): - finder = self.machinery.FileFinder(path, + def finder(self, path): + return self.machinery.FileFinder(path, (self.machinery.SourceFileLoader, self.machinery.SOURCE_SUFFIXES), (self.machinery.SourcelessFileLoader, self.machinery.BYTECODE_SUFFIXES)) - return finder.find_module(self.name) def sensitivity_test(self): """Look for a module with matching and non-matching sensitivity.""" sensitive_pkg = 'sensitive.{0}'.format(self.name) insensitive_pkg = 'insensitive.{0}'.format(self.name.lower()) - context = source_util.create_modules(insensitive_pkg, sensitive_pkg) + context = util.create_modules(insensitive_pkg, sensitive_pkg) with context as mapping: sensitive_path = os.path.join(mapping['.root'], 'sensitive') insensitive_path = os.path.join(mapping['.root'], 'insensitive') - return self.find(sensitive_path), self.find(insensitive_path) + sensitive_finder = self.finder(sensitive_path) + insensitive_finder = self.finder(insensitive_path) + return self.find(sensitive_finder), self.find(insensitive_finder) def test_sensitive(self): with test_support.EnvironmentVarGuard() as env: @@ -46,7 +46,7 @@ def test_sensitive(self): self.skipTest('os.environ changes not reflected in ' '_os.environ') sensitive, insensitive = self.sensitivity_test() - self.assertTrue(hasattr(sensitive, 'load_module')) + self.assertIsNotNone(sensitive) self.assertIn(self.name, sensitive.get_filename(self.name)) self.assertIsNone(insensitive) @@ -57,13 +57,33 @@ def test_insensitive(self): self.skipTest('os.environ changes not reflected in ' '_os.environ') sensitive, insensitive = self.sensitivity_test() - self.assertTrue(hasattr(sensitive, 'load_module')) + self.assertIsNotNone(sensitive) self.assertIn(self.name, sensitive.get_filename(self.name)) - self.assertTrue(hasattr(insensitive, 'load_module')) + self.assertIsNotNone(insensitive) self.assertIn(self.name, insensitive.get_filename(self.name)) -Frozen_CaseSensitivityTest, Source_CaseSensitivityTest = util.test_both( - CaseSensitivityTest, importlib=importlib, machinery=machinery) + +class CaseSensitivityTestPEP302(CaseSensitivityTest): + def find(self, finder): + return finder.find_module(self.name) + + +(Frozen_CaseSensitivityTestPEP302, + Source_CaseSensitivityTestPEP302 + ) = util.test_both(CaseSensitivityTestPEP302, importlib=importlib, + machinery=machinery) + + +class CaseSensitivityTestPEP451(CaseSensitivityTest): + def find(self, finder): + found = finder.find_spec(self.name) + return found.loader if found is not None else found + + +(Frozen_CaseSensitivityTestPEP451, + Source_CaseSensitivityTestPEP451 + ) = util.test_both(CaseSensitivityTestPEP451, importlib=importlib, + machinery=machinery) if __name__ == '__main__': diff --git a/Lib/test/test_importlib/source/test_file_loader.py b/Lib/test/test_importlib/source/test_file_loader.py index f1e2713a971a..73f4c620706b 100644 --- a/Lib/test/test_importlib/source/test_file_loader.py +++ b/Lib/test/test_importlib/source/test_file_loader.py @@ -1,6 +1,5 @@ from .. import abc from .. import util -from . import util as source_util importlib = util.import_importlib('importlib') importlib_abc = util.import_importlib('importlib.abc') @@ -16,6 +15,7 @@ import sys import types import unittest +import warnings from test.support import make_legacy_pyc, unload @@ -27,6 +27,11 @@ class SimpleTest(abc.LoaderTests): """ + def setUp(self): + self.name = 'spam' + self.filepath = os.path.join('ham', self.name + '.py') + self.loader = self.machinery.SourceFileLoader(self.name, self.filepath) + def test_load_module_API(self): class Tester(self.abc.FileLoader): def get_source(self, _): return 'attr = 42' @@ -34,7 +39,9 @@ def is_package(self, _): return False loader = Tester('blah', 'blah.py') self.addCleanup(unload, 'blah') - module = loader.load_module() # Should not raise an exception. + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + module = loader.load_module() # Should not raise an exception. def test_get_filename_API(self): # If fullname is not set then assume self.path is desired. @@ -53,11 +60,21 @@ def module_repr(self, _): pass with self.assertRaises(ImportError): loader.get_filename(name + 'XXX') + def test_equality(self): + other = self.machinery.SourceFileLoader(self.name, self.filepath) + self.assertEqual(self.loader, other) + + def test_inequality(self): + other = self.machinery.SourceFileLoader('_' + self.name, self.filepath) + self.assertNotEqual(self.loader, other) + # [basic] def test_module(self): - with source_util.create_modules('_temp') as mapping: + with util.create_modules('_temp') as mapping: loader = self.machinery.SourceFileLoader('_temp', mapping['_temp']) - module = loader.load_module('_temp') + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + module = loader.load_module('_temp') self.assertIn('_temp', sys.modules) check = {'__name__': '_temp', '__file__': mapping['_temp'], '__package__': ''} @@ -65,10 +82,12 @@ def test_module(self): self.assertEqual(getattr(module, attr), value) def test_package(self): - with source_util.create_modules('_pkg.__init__') as mapping: + with util.create_modules('_pkg.__init__') as mapping: loader = self.machinery.SourceFileLoader('_pkg', mapping['_pkg.__init__']) - module = loader.load_module('_pkg') + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + module = loader.load_module('_pkg') self.assertIn('_pkg', sys.modules) check = {'__name__': '_pkg', '__file__': mapping['_pkg.__init__'], '__path__': [os.path.dirname(mapping['_pkg.__init__'])], @@ -78,10 +97,12 @@ def test_package(self): def test_lacking_parent(self): - with source_util.create_modules('_pkg.__init__', '_pkg.mod')as mapping: + with util.create_modules('_pkg.__init__', '_pkg.mod')as mapping: loader = self.machinery.SourceFileLoader('_pkg.mod', mapping['_pkg.mod']) - module = loader.load_module('_pkg.mod') + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + module = loader.load_module('_pkg.mod') self.assertIn('_pkg.mod', sys.modules) check = {'__name__': '_pkg.mod', '__file__': mapping['_pkg.mod'], '__package__': '_pkg'} @@ -93,14 +114,18 @@ def fake_mtime(self, fxn): return lambda name: fxn(name) + 1 def test_module_reuse(self): - with source_util.create_modules('_temp') as mapping: + with util.create_modules('_temp') as mapping: loader = self.machinery.SourceFileLoader('_temp', mapping['_temp']) - module = loader.load_module('_temp') + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + module = loader.load_module('_temp') module_id = id(module) module_dict_id = id(module.__dict__) with open(mapping['_temp'], 'w') as file: file.write("testing_var = 42\n") - module = loader.load_module('_temp') + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + module = loader.load_module('_temp') self.assertIn('testing_var', module.__dict__, "'testing_var' not in " "{0}".format(list(module.__dict__.keys()))) @@ -113,7 +138,7 @@ def test_state_after_failure(self): attributes = ('__file__', '__path__', '__package__') value = '' name = '_temp' - with source_util.create_modules(name) as mapping: + with util.create_modules(name) as mapping: orig_module = types.ModuleType(name) for attr in attributes: setattr(orig_module, attr, value) @@ -121,18 +146,26 @@ def test_state_after_failure(self): file.write('+++ bad syntax +++') loader = self.machinery.SourceFileLoader('_temp', mapping['_temp']) with self.assertRaises(SyntaxError): - loader.load_module(name) + loader.exec_module(orig_module) + for attr in attributes: + self.assertEqual(getattr(orig_module, attr), value) + with self.assertRaises(SyntaxError): + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + loader.load_module(name) for attr in attributes: self.assertEqual(getattr(orig_module, attr), value) # [syntax error] def test_bad_syntax(self): - with source_util.create_modules('_temp') as mapping: + with util.create_modules('_temp') as mapping: with open(mapping['_temp'], 'w') as file: file.write('=') loader = self.machinery.SourceFileLoader('_temp', mapping['_temp']) with self.assertRaises(SyntaxError): - loader.load_module('_temp') + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + loader.load_module('_temp') self.assertNotIn('_temp', sys.modules) def test_file_from_empty_string_dir(self): @@ -144,7 +177,9 @@ def test_file_from_empty_string_dir(self): try: with util.uncache('_temp'): loader = self.machinery.SourceFileLoader('_temp', file_path) - mod = loader.load_module('_temp') + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + mod = loader.load_module('_temp') self.assertEqual(file_path, mod.__file__) self.assertEqual(self.util.cache_from_source(file_path), mod.__cached__) @@ -154,10 +189,11 @@ def test_file_from_empty_string_dir(self): if os.path.exists(pycache): shutil.rmtree(pycache) + @util.writes_bytecode_files def test_timestamp_overflow(self): # When a modification timestamp is larger than 2**32, it should be # truncated rather than raise an OverflowError. - with source_util.create_modules('_temp') as mapping: + with util.create_modules('_temp') as mapping: source = mapping['_temp'] compiled = self.util.cache_from_source(source) with open(source, 'w') as f: @@ -171,28 +207,49 @@ def test_timestamp_overflow(self): raise self.skipTest("cannot set modification time to large integer ({})".format(e)) loader = self.machinery.SourceFileLoader('_temp', mapping['_temp']) - mod = loader.load_module('_temp') + # PEP 451 + module = types.ModuleType('_temp') + module.__spec__ = self.util.spec_from_loader('_temp', loader) + loader.exec_module(module) + self.assertEqual(module.x, 5) + self.assertTrue(os.path.exists(compiled)) + os.unlink(compiled) + # PEP 302 + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + mod = loader.load_module('_temp') # XXX # Sanity checks. self.assertEqual(mod.__cached__, compiled) self.assertEqual(mod.x, 5) # The pyc file was created. - os.stat(compiled) + self.assertTrue(os.path.exists(compiled)) def test_unloadable(self): loader = self.machinery.SourceFileLoader('good name', {}) + module = types.ModuleType('bad name') + module.__spec__ = self.machinery.ModuleSpec('bad name', loader) + with self.assertRaises(ImportError): + loader.exec_module(module) with self.assertRaises(ImportError): - loader.load_module('bad name') + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + loader.load_module('bad name') -Frozen_SimpleTest, Source_SimpleTest = util.test_both( - SimpleTest, importlib=importlib, machinery=machinery, abc=importlib_abc, - util=importlib_util) + +(Frozen_SimpleTest, + Source_SimpleTest + ) = util.test_both(SimpleTest, importlib=importlib, machinery=machinery, + abc=importlib_abc, util=importlib_util) class BadBytecodeTest: def import_(self, file, module_name): loader = self.loader(module_name, file) - module = loader.load_module(module_name) + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + # XXX Change to use exec_module(). + module = loader.load_module(module_name) self.assertIn(module_name, sys.modules) def manipulate_bytecode(self, name, mapping, manipulator, *, @@ -219,45 +276,45 @@ def manipulate_bytecode(self, name, mapping, manipulator, *, return bytecode_path def _test_empty_file(self, test, *, del_source=False): - with source_util.create_modules('_temp') as mapping: + with util.create_modules('_temp') as mapping: bc_path = self.manipulate_bytecode('_temp', mapping, lambda bc: b'', del_source=del_source) test('_temp', mapping, bc_path) - @source_util.writes_bytecode_files + @util.writes_bytecode_files def _test_partial_magic(self, test, *, del_source=False): # When their are less than 4 bytes to a .pyc, regenerate it if # possible, else raise ImportError. - with source_util.create_modules('_temp') as mapping: + with util.create_modules('_temp') as mapping: bc_path = self.manipulate_bytecode('_temp', mapping, lambda bc: bc[:3], del_source=del_source) test('_temp', mapping, bc_path) def _test_magic_only(self, test, *, del_source=False): - with source_util.create_modules('_temp') as mapping: + with util.create_modules('_temp') as mapping: bc_path = self.manipulate_bytecode('_temp', mapping, lambda bc: bc[:4], del_source=del_source) test('_temp', mapping, bc_path) def _test_partial_timestamp(self, test, *, del_source=False): - with source_util.create_modules('_temp') as mapping: + with util.create_modules('_temp') as mapping: bc_path = self.manipulate_bytecode('_temp', mapping, lambda bc: bc[:7], del_source=del_source) test('_temp', mapping, bc_path) def _test_partial_size(self, test, *, del_source=False): - with source_util.create_modules('_temp') as mapping: + with util.create_modules('_temp') as mapping: bc_path = self.manipulate_bytecode('_temp', mapping, lambda bc: bc[:11], del_source=del_source) test('_temp', mapping, bc_path) def _test_no_marshal(self, *, del_source=False): - with source_util.create_modules('_temp') as mapping: + with util.create_modules('_temp') as mapping: bc_path = self.manipulate_bytecode('_temp', mapping, lambda bc: bc[:12], del_source=del_source) @@ -266,7 +323,7 @@ def _test_no_marshal(self, *, del_source=False): self.import_(file_path, '_temp') def _test_non_code_marshal(self, *, del_source=False): - with source_util.create_modules('_temp') as mapping: + with util.create_modules('_temp') as mapping: bytecode_path = self.manipulate_bytecode('_temp', mapping, lambda bc: bc[:12] + marshal.dumps(b'abcd'), del_source=del_source) @@ -277,7 +334,7 @@ def _test_non_code_marshal(self, *, del_source=False): self.assertEqual(cm.exception.path, bytecode_path) def _test_bad_marshal(self, *, del_source=False): - with source_util.create_modules('_temp') as mapping: + with util.create_modules('_temp') as mapping: bytecode_path = self.manipulate_bytecode('_temp', mapping, lambda bc: bc[:12] + b'', del_source=del_source) @@ -286,19 +343,38 @@ def _test_bad_marshal(self, *, del_source=False): self.import_(file_path, '_temp') def _test_bad_magic(self, test, *, del_source=False): - with source_util.create_modules('_temp') as mapping: + with util.create_modules('_temp') as mapping: bc_path = self.manipulate_bytecode('_temp', mapping, lambda bc: b'\x00\x00\x00\x00' + bc[4:]) test('_temp', mapping, bc_path) -class SourceLoaderBadBytecodeTest(BadBytecodeTest): +class BadBytecodeTestPEP451(BadBytecodeTest): + + def import_(self, file, module_name): + loader = self.loader(module_name, file) + module = types.ModuleType(module_name) + module.__spec__ = self.util.spec_from_loader(module_name, loader) + loader.exec_module(module) + + +class BadBytecodeTestPEP302(BadBytecodeTest): + + def import_(self, file, module_name): + loader = self.loader(module_name, file) + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + module = loader.load_module(module_name) + self.assertIn(module_name, sys.modules) + + +class SourceLoaderBadBytecodeTest: @classmethod def setUpClass(cls): cls.loader = cls.machinery.SourceFileLoader - @source_util.writes_bytecode_files + @util.writes_bytecode_files def test_empty_file(self): # When a .pyc is empty, regenerate it if possible, else raise # ImportError. @@ -317,7 +393,7 @@ def test(name, mapping, bytecode_path): self._test_partial_magic(test) - @source_util.writes_bytecode_files + @util.writes_bytecode_files def test_magic_only(self): # When there is only the magic number, regenerate the .pyc if possible, # else raise EOFError. @@ -328,7 +404,7 @@ def test(name, mapping, bytecode_path): self._test_magic_only(test) - @source_util.writes_bytecode_files + @util.writes_bytecode_files def test_bad_magic(self): # When the magic number is different, the bytecode should be # regenerated. @@ -340,7 +416,7 @@ def test(name, mapping, bytecode_path): self._test_bad_magic(test) - @source_util.writes_bytecode_files + @util.writes_bytecode_files def test_partial_timestamp(self): # When the timestamp is partial, regenerate the .pyc, else # raise EOFError. @@ -351,7 +427,7 @@ def test(name, mapping, bc_path): self._test_partial_timestamp(test) - @source_util.writes_bytecode_files + @util.writes_bytecode_files def test_partial_size(self): # When the size is partial, regenerate the .pyc, else # raise EOFError. @@ -362,29 +438,29 @@ def test(name, mapping, bc_path): self._test_partial_size(test) - @source_util.writes_bytecode_files + @util.writes_bytecode_files def test_no_marshal(self): # When there is only the magic number and timestamp, raise EOFError. self._test_no_marshal() - @source_util.writes_bytecode_files + @util.writes_bytecode_files def test_non_code_marshal(self): self._test_non_code_marshal() # XXX ImportError when sourceless # [bad marshal] - @source_util.writes_bytecode_files + @util.writes_bytecode_files def test_bad_marshal(self): # Bad marshal data should raise a ValueError. self._test_bad_marshal() # [bad timestamp] - @source_util.writes_bytecode_files + @util.writes_bytecode_files def test_old_timestamp(self): # When the timestamp is older than the source, bytecode should be # regenerated. zeros = b'\x00\x00\x00\x00' - with source_util.create_modules('_temp') as mapping: + with util.create_modules('_temp') as mapping: py_compile.compile(mapping['_temp']) bytecode_path = self.util.cache_from_source(mapping['_temp']) with open(bytecode_path, 'r+b') as bytecode_file: @@ -398,10 +474,10 @@ def test_old_timestamp(self): self.assertEqual(bytecode_file.read(4), source_timestamp) # [bytecode read-only] - @source_util.writes_bytecode_files + @util.writes_bytecode_files def test_read_only_bytecode(self): # When bytecode is read-only but should be rewritten, fail silently. - with source_util.create_modules('_temp') as mapping: + with util.create_modules('_temp') as mapping: # Create bytecode that will need to be re-created. py_compile.compile(mapping['_temp']) bytecode_path = self.util.cache_from_source(mapping['_temp']) @@ -418,12 +494,32 @@ def test_read_only_bytecode(self): # Make writable for eventual clean-up. os.chmod(bytecode_path, stat.S_IWUSR) -Frozen_SourceBadBytecode, Source_SourceBadBytecode = util.test_both( - SourceLoaderBadBytecodeTest, importlib=importlib, machinery=machinery, - abc=importlib_abc, util=importlib_util) +class SourceLoaderBadBytecodeTestPEP451( + SourceLoaderBadBytecodeTest, BadBytecodeTestPEP451): + pass + + +(Frozen_SourceBadBytecodePEP451, + Source_SourceBadBytecodePEP451 + ) = util.test_both(SourceLoaderBadBytecodeTestPEP451, importlib=importlib, + machinery=machinery, abc=importlib_abc, + util=importlib_util) + + +class SourceLoaderBadBytecodeTestPEP302( + SourceLoaderBadBytecodeTest, BadBytecodeTestPEP302): + pass + + +(Frozen_SourceBadBytecodePEP302, + Source_SourceBadBytecodePEP302 + ) = util.test_both(SourceLoaderBadBytecodeTestPEP302, importlib=importlib, + machinery=machinery, abc=importlib_abc, + util=importlib_util) -class SourcelessLoaderBadBytecodeTest(BadBytecodeTest): + +class SourcelessLoaderBadBytecodeTest: @classmethod def setUpClass(cls): @@ -482,9 +578,29 @@ def test_no_marshal(self): def test_non_code_marshal(self): self._test_non_code_marshal(del_source=True) -Frozen_SourcelessBadBytecode, Source_SourcelessBadBytecode = util.test_both( - SourcelessLoaderBadBytecodeTest, importlib=importlib, - machinery=machinery, abc=importlib_abc, util=importlib_util) + +class SourcelessLoaderBadBytecodeTestPEP451(SourcelessLoaderBadBytecodeTest, + BadBytecodeTestPEP451): + pass + + +(Frozen_SourcelessBadBytecodePEP451, + Source_SourcelessBadBytecodePEP451 + ) = util.test_both(SourcelessLoaderBadBytecodeTestPEP451, importlib=importlib, + machinery=machinery, abc=importlib_abc, + util=importlib_util) + + +class SourcelessLoaderBadBytecodeTestPEP302(SourcelessLoaderBadBytecodeTest, + BadBytecodeTestPEP302): + pass + + +(Frozen_SourcelessBadBytecodePEP302, + Source_SourcelessBadBytecodePEP302 + ) = util.test_both(SourcelessLoaderBadBytecodeTestPEP302, importlib=importlib, + machinery=machinery, abc=importlib_abc, + util=importlib_util) if __name__ == '__main__': diff --git a/Lib/test/test_importlib/source/test_finder.py b/Lib/test/test_importlib/source/test_finder.py index 8bf8cb788084..f372b850dc7c 100644 --- a/Lib/test/test_importlib/source/test_finder.py +++ b/Lib/test/test_importlib/source/test_finder.py @@ -1,6 +1,5 @@ from .. import abc from .. import util -from . import util as source_util machinery = util.import_importlib('importlib.machinery') @@ -47,7 +46,8 @@ def get_finder(self, root): return self.machinery.FileFinder(root, *loader_details) def import_(self, root, module): - return self.get_finder(root).find_module(module) + finder = self.get_finder(root) + return self._find(finder, module, loader_only=True) def run_test(self, test, create=None, *, compile_=None, unlink=None): """Test the finding of 'test' with the creation of modules listed in @@ -59,7 +59,7 @@ def run_test(self, test, create=None, *, compile_=None, unlink=None): """ if create is None: create = {test} - with source_util.create_modules(*create) as mapping: + with util.create_modules(*create) as mapping: if compile_: for name in compile_: py_compile.compile(mapping[name]) @@ -99,14 +99,14 @@ def test_package(self): # [sub module] def test_module_in_package(self): - with source_util.create_modules('pkg.__init__', 'pkg.sub') as mapping: + with util.create_modules('pkg.__init__', 'pkg.sub') as mapping: pkg_dir = os.path.dirname(mapping['pkg.__init__']) loader = self.import_(pkg_dir, 'pkg.sub') self.assertTrue(hasattr(loader, 'load_module')) # [sub package] def test_package_in_package(self): - context = source_util.create_modules('pkg.__init__', 'pkg.sub.__init__') + context = util.create_modules('pkg.__init__', 'pkg.sub.__init__') with context as mapping: pkg_dir = os.path.dirname(mapping['pkg.__init__']) loader = self.import_(pkg_dir, 'pkg.sub') @@ -119,7 +119,7 @@ def test_package_over_module(self): self.assertIn('__init__', loader.get_filename(name)) def test_failure(self): - with source_util.create_modules('blah') as mapping: + with util.create_modules('blah') as mapping: nothing = self.import_(mapping['.root'], 'sdfsadsadf') self.assertIsNone(nothing) @@ -130,7 +130,7 @@ def test_empty_string_for_dir(self): with open('mod.py', 'w') as file: file.write("# test file for importlib") try: - loader = finder.find_module('mod') + loader = self._find(finder, 'mod', loader_only=True) self.assertTrue(hasattr(loader, 'load_module')) finally: os.unlink('mod.py') @@ -146,10 +146,12 @@ def test_invalidate_caches(self): # Regression test for http://bugs.python.org/issue14846 def test_dir_removal_handling(self): mod = 'mod' - with source_util.create_modules(mod) as mapping: + with util.create_modules(mod) as mapping: finder = self.get_finder(mapping['.root']) - self.assertIsNotNone(finder.find_module(mod)) - self.assertIsNone(finder.find_module(mod)) + found = self._find(finder, 'mod', loader_only=True) + self.assertIsNotNone(found) + found = self._find(finder, 'mod', loader_only=True) + self.assertIsNone(found) @unittest.skipUnless(sys.platform != 'win32', 'os.chmod() does not support the needed arguments under Windows') @@ -173,17 +175,61 @@ def cleanup(tempdir): self.addCleanup(cleanup, tempdir) os.chmod(tempdir.name, stat.S_IWUSR | stat.S_IXUSR) finder = self.get_finder(tempdir.name) - self.assertEqual((None, []), finder.find_loader('doesnotexist')) + found = self._find(finder, 'doesnotexist') + self.assertEqual(found, self.NOT_FOUND) def test_ignore_file(self): # If a directory got changed to a file from underneath us, then don't # worry about looking for submodules. with tempfile.NamedTemporaryFile() as file_obj: finder = self.get_finder(file_obj.name) - self.assertEqual((None, []), finder.find_loader('doesnotexist')) + found = self._find(finder, 'doesnotexist') + self.assertEqual(found, self.NOT_FOUND) -Frozen_FinderTests, Source_FinderTests = util.test_both(FinderTests, machinery=machinery) +class FinderTestsPEP451(FinderTests): + + NOT_FOUND = None + + def _find(self, finder, name, loader_only=False): + spec = finder.find_spec(name) + return spec.loader if spec is not None else spec + + +(Frozen_FinderTestsPEP451, + Source_FinderTestsPEP451 + ) = util.test_both(FinderTestsPEP451, machinery=machinery) + + +class FinderTestsPEP420(FinderTests): + + NOT_FOUND = (None, []) + + def _find(self, finder, name, loader_only=False): + with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + loader_portions = finder.find_loader(name) + return loader_portions[0] if loader_only else loader_portions + + +(Frozen_FinderTestsPEP420, + Source_FinderTestsPEP420 + ) = util.test_both(FinderTestsPEP420, machinery=machinery) + + +class FinderTestsPEP302(FinderTests): + + NOT_FOUND = None + + def _find(self, finder, name, loader_only=False): + with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + return finder.find_module(name) + + +(Frozen_FinderTestsPEP302, + Source_FinderTestsPEP302 + ) = util.test_both(FinderTestsPEP302, machinery=machinery) if __name__ == '__main__': diff --git a/Lib/test/test_importlib/source/test_path_hook.py b/Lib/test/test_importlib/source/test_path_hook.py index 92da77265b5d..e6a2415bda4e 100644 --- a/Lib/test/test_importlib/source/test_path_hook.py +++ b/Lib/test/test_importlib/source/test_path_hook.py @@ -1,5 +1,4 @@ from .. import util -from . import util as source_util machinery = util.import_importlib('importlib.machinery') @@ -15,7 +14,7 @@ def path_hook(self): self.machinery.SOURCE_SUFFIXES)) def test_success(self): - with source_util.create_modules('dummy') as mapping: + with util.create_modules('dummy') as mapping: self.assertTrue(hasattr(self.path_hook()(mapping['.root']), 'find_module')) @@ -23,7 +22,10 @@ def test_empty_string(self): # The empty string represents the cwd. self.assertTrue(hasattr(self.path_hook()(''), 'find_module')) -Frozen_PathHookTest, Source_PathHooktest = util.test_both(PathHookTest, machinery=machinery) + +(Frozen_PathHookTest, + Source_PathHooktest + ) = util.test_both(PathHookTest, machinery=machinery) if __name__ == '__main__': diff --git a/Lib/test/test_importlib/source/test_source_encoding.py b/Lib/test/test_importlib/source/test_source_encoding.py index 654f4c2b2f6b..b604afb5ec88 100644 --- a/Lib/test/test_importlib/source/test_source_encoding.py +++ b/Lib/test/test_importlib/source/test_source_encoding.py @@ -1,15 +1,17 @@ from .. import util -from . import util as source_util machinery = util.import_importlib('importlib.machinery') import codecs +import importlib.util import re import sys +import types # Because sys.path gets essentially blanked, need to have unicodedata already # imported for the parser to use. import unicodedata import unittest +import warnings CODING_RE = re.compile(r'^[ \t\f]*#.*coding[:=][ \t]*([-\w.]+)', re.ASCII) @@ -34,12 +36,12 @@ class EncodingTest: module_name = '_temp' def run_test(self, source): - with source_util.create_modules(self.module_name) as mapping: + with util.create_modules(self.module_name) as mapping: with open(mapping[self.module_name], 'wb') as file: file.write(source) loader = self.machinery.SourceFileLoader(self.module_name, mapping[self.module_name]) - return loader.load_module(self.module_name) + return self.load(loader) def create_source(self, encoding): encoding_line = "# coding={0}".format(encoding) @@ -86,7 +88,32 @@ def test_bom_conflict(self): with self.assertRaises(SyntaxError): self.run_test(source) -Frozen_EncodingTest, Source_EncodingTest = util.test_both(EncodingTest, machinery=machinery) + +class EncodingTestPEP451(EncodingTest): + + def load(self, loader): + module = types.ModuleType(self.module_name) + module.__spec__ = importlib.util.spec_from_loader(self.module_name, loader) + loader.exec_module(module) + return module + + +(Frozen_EncodingTestPEP451, + Source_EncodingTestPEP451 + ) = util.test_both(EncodingTestPEP451, machinery=machinery) + + +class EncodingTestPEP302(EncodingTest): + + def load(self, loader): + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + return loader.load_module(self.module_name) + + +(Frozen_EncodingTestPEP302, + Source_EncodingTestPEP302 + ) = util.test_both(EncodingTestPEP302, machinery=machinery) class LineEndingTest: @@ -98,12 +125,12 @@ def run_test(self, line_ending): module_name = '_temp' source_lines = [b"a = 42", b"b = -13", b''] source = line_ending.join(source_lines) - with source_util.create_modules(module_name) as mapping: + with util.create_modules(module_name) as mapping: with open(mapping[module_name], 'wb') as file: file.write(source) loader = self.machinery.SourceFileLoader(module_name, - mapping[module_name]) - return loader.load_module(module_name) + mapping[module_name]) + return self.load(loader, module_name) # [cr] def test_cr(self): @@ -117,8 +144,32 @@ def test_crlf(self): def test_lf(self): self.run_test(b'\n') -Frozen_LineEndings, Source_LineEndings = util.test_both(LineEndingTest, machinery=machinery) +class LineEndingTestPEP451(LineEndingTest): + + def load(self, loader, module_name): + module = types.ModuleType(module_name) + module.__spec__ = importlib.util.spec_from_loader(module_name, loader) + loader.exec_module(module) + return module + + +(Frozen_LineEndingTestPEP451, + Source_LineEndingTestPEP451 + ) = util.test_both(LineEndingTestPEP451, machinery=machinery) + + +class LineEndingTestPEP302(LineEndingTest): + + def load(self, loader, module_name): + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + return loader.load_module(module_name) + + +(Frozen_LineEndingTestPEP302, + Source_LineEndingTestPEP302 + ) = util.test_both(LineEndingTestPEP302, machinery=machinery) if __name__ == '__main__': diff --git a/Lib/test/test_importlib/source/util.py b/Lib/test/test_importlib/source/util.py deleted file mode 100644 index 63cd25adc4c7..000000000000 --- a/Lib/test/test_importlib/source/util.py +++ /dev/null @@ -1,96 +0,0 @@ -from .. import util -import contextlib -import errno -import functools -import os -import os.path -import sys -import tempfile -from test import support - - -def writes_bytecode_files(fxn): - """Decorator to protect sys.dont_write_bytecode from mutation and to skip - tests that require it to be set to False.""" - if sys.dont_write_bytecode: - return lambda *args, **kwargs: None - @functools.wraps(fxn) - def wrapper(*args, **kwargs): - original = sys.dont_write_bytecode - sys.dont_write_bytecode = False - try: - to_return = fxn(*args, **kwargs) - finally: - sys.dont_write_bytecode = original - return to_return - return wrapper - - -def ensure_bytecode_path(bytecode_path): - """Ensure that the __pycache__ directory for PEP 3147 pyc file exists. - - :param bytecode_path: File system path to PEP 3147 pyc file. - """ - try: - os.mkdir(os.path.dirname(bytecode_path)) - except OSError as error: - if error.errno != errno.EEXIST: - raise - - -@contextlib.contextmanager -def create_modules(*names): - """Temporarily create each named module with an attribute (named 'attr') - that contains the name passed into the context manager that caused the - creation of the module. - - All files are created in a temporary directory returned by - tempfile.mkdtemp(). This directory is inserted at the beginning of - sys.path. When the context manager exits all created files (source and - bytecode) are explicitly deleted. - - No magic is performed when creating packages! This means that if you create - a module within a package you must also create the package's __init__ as - well. - - """ - source = 'attr = {0!r}' - created_paths = [] - mapping = {} - state_manager = None - uncache_manager = None - try: - temp_dir = tempfile.mkdtemp() - mapping['.root'] = temp_dir - import_names = set() - for name in names: - if not name.endswith('__init__'): - import_name = name - else: - import_name = name[:-len('.__init__')] - import_names.add(import_name) - if import_name in sys.modules: - del sys.modules[import_name] - name_parts = name.split('.') - file_path = temp_dir - for directory in name_parts[:-1]: - file_path = os.path.join(file_path, directory) - if not os.path.exists(file_path): - os.mkdir(file_path) - created_paths.append(file_path) - file_path = os.path.join(file_path, name_parts[-1] + '.py') - with open(file_path, 'w') as file: - file.write(source.format(name)) - created_paths.append(file_path) - mapping[name] = file_path - uncache_manager = util.uncache(*import_names) - uncache_manager.__enter__() - state_manager = util.import_state(path=[temp_dir]) - state_manager.__enter__() - yield mapping - finally: - if state_manager is not None: - state_manager.__exit__(None, None, None) - if uncache_manager is not None: - uncache_manager.__exit__(None, None, None) - support.rmtree(temp_dir) diff --git a/Lib/test/test_importlib/test_abc.py b/Lib/test/test_importlib/test_abc.py index ba8d60542beb..d4bf9153e93f 100644 --- a/Lib/test/test_importlib/test_abc.py +++ b/Lib/test/test_importlib/test_abc.py @@ -8,12 +8,15 @@ import types import unittest from unittest import mock +import warnings -from . import util +from . import util as test_util + +init = test_util.import_importlib('importlib') +abc = test_util.import_importlib('importlib.abc') +machinery = test_util.import_importlib('importlib.machinery') +util = test_util.import_importlib('importlib.util') -frozen_init, source_init = util.import_importlib('importlib') -frozen_abc, source_abc = util.import_importlib('importlib.abc') -frozen_util, source_util = util.import_importlib('importlib.util') ##### Inheritance ############################################################## class InheritanceTests: @@ -24,8 +27,7 @@ class InheritanceTests: subclasses = [] superclasses = [] - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) + def setUp(self): self.superclasses = [getattr(self.abc, class_name) for class_name in self.superclass_names] if hasattr(self, 'subclass_names'): @@ -34,11 +36,11 @@ def __init__(self, *args, **kwargs): # checking across module boundaries (i.e. the _bootstrap in abc is # not the same as the one in machinery). That means stealing one of # the modules from the other to make sure the same instance is used. - self.subclasses = [getattr(self.abc.machinery, class_name) - for class_name in self.subclass_names] + machinery = self.abc.machinery + self.subclasses = [getattr(machinery, class_name) + for class_name in self.subclass_names] assert self.subclasses or self.superclasses, self.__class__ - testing = self.__class__.__name__.partition('_')[2] - self.__test = getattr(self.abc, testing) + self.__test = getattr(self.abc, self._NAME) def test_subclasses(self): # Test that the expected subclasses inherit. @@ -52,94 +54,97 @@ def test_superclasses(self): self.assertTrue(issubclass(self.__test, superclass), "{0} is not a superclass of {1}".format(superclass, self.__test)) -def create_inheritance_tests(base_class): - def set_frozen(ns): - ns['abc'] = frozen_abc - def set_source(ns): - ns['abc'] = source_abc - - classes = [] - for prefix, ns_set in [('Frozen', set_frozen), ('Source', set_source)]: - classes.append(types.new_class('_'.join([prefix, base_class.__name__]), - (base_class, unittest.TestCase), - exec_body=ns_set)) - return classes - class MetaPathFinder(InheritanceTests): superclass_names = ['Finder'] subclass_names = ['BuiltinImporter', 'FrozenImporter', 'PathFinder', 'WindowsRegistryFinder'] -tests = create_inheritance_tests(MetaPathFinder) -Frozen_MetaPathFinderInheritanceTests, Source_MetaPathFinderInheritanceTests = tests + +(Frozen_MetaPathFinderInheritanceTests, + Source_MetaPathFinderInheritanceTests + ) = test_util.test_both(MetaPathFinder, abc=abc) class PathEntryFinder(InheritanceTests): superclass_names = ['Finder'] subclass_names = ['FileFinder'] -tests = create_inheritance_tests(PathEntryFinder) -Frozen_PathEntryFinderInheritanceTests, Source_PathEntryFinderInheritanceTests = tests + +(Frozen_PathEntryFinderInheritanceTests, + Source_PathEntryFinderInheritanceTests + ) = test_util.test_both(PathEntryFinder, abc=abc) class ResourceLoader(InheritanceTests): superclass_names = ['Loader'] -tests = create_inheritance_tests(ResourceLoader) -Frozen_ResourceLoaderInheritanceTests, Source_ResourceLoaderInheritanceTests = tests + +(Frozen_ResourceLoaderInheritanceTests, + Source_ResourceLoaderInheritanceTests + ) = test_util.test_both(ResourceLoader, abc=abc) class InspectLoader(InheritanceTests): superclass_names = ['Loader'] subclass_names = ['BuiltinImporter', 'FrozenImporter', 'ExtensionFileLoader'] -tests = create_inheritance_tests(InspectLoader) -Frozen_InspectLoaderInheritanceTests, Source_InspectLoaderInheritanceTests = tests + +(Frozen_InspectLoaderInheritanceTests, + Source_InspectLoaderInheritanceTests + ) = test_util.test_both(InspectLoader, abc=abc) class ExecutionLoader(InheritanceTests): superclass_names = ['InspectLoader'] subclass_names = ['ExtensionFileLoader'] -tests = create_inheritance_tests(ExecutionLoader) -Frozen_ExecutionLoaderInheritanceTests, Source_ExecutionLoaderInheritanceTests = tests + +(Frozen_ExecutionLoaderInheritanceTests, + Source_ExecutionLoaderInheritanceTests + ) = test_util.test_both(ExecutionLoader, abc=abc) class FileLoader(InheritanceTests): superclass_names = ['ResourceLoader', 'ExecutionLoader'] subclass_names = ['SourceFileLoader', 'SourcelessFileLoader'] -tests = create_inheritance_tests(FileLoader) -Frozen_FileLoaderInheritanceTests, Source_FileLoaderInheritanceTests = tests + +(Frozen_FileLoaderInheritanceTests, + Source_FileLoaderInheritanceTests + ) = test_util.test_both(FileLoader, abc=abc) class SourceLoader(InheritanceTests): superclass_names = ['ResourceLoader', 'ExecutionLoader'] subclass_names = ['SourceFileLoader'] -tests = create_inheritance_tests(SourceLoader) -Frozen_SourceLoaderInheritanceTests, Source_SourceLoaderInheritanceTests = tests + +(Frozen_SourceLoaderInheritanceTests, + Source_SourceLoaderInheritanceTests + ) = test_util.test_both(SourceLoader, abc=abc) + ##### Default return values #################################################### -def make_abc_subclasses(base_class): - classes = [] - for kind, abc in [('Frozen', frozen_abc), ('Source', source_abc)]: - name = '_'.join([kind, base_class.__name__]) - base_classes = base_class, getattr(abc, base_class.__name__) - classes.append(types.new_class(name, base_classes)) - return classes - -def make_return_value_tests(base_class, test_class): - frozen_class, source_class = make_abc_subclasses(base_class) - tests = [] - for prefix, class_in_test in [('Frozen', frozen_class), ('Source', source_class)]: - def set_ns(ns): - ns['ins'] = class_in_test() - tests.append(types.new_class('_'.join([prefix, test_class.__name__]), - (test_class, unittest.TestCase), - exec_body=set_ns)) - return tests + +def make_abc_subclasses(base_class, name=None, inst=False, **kwargs): + if name is None: + name = base_class.__name__ + base = {kind: getattr(splitabc, name) + for kind, splitabc in abc.items()} + return {cls._KIND: cls() if inst else cls + for cls in test_util.split_frozen(base_class, base, **kwargs)} + + +class ABCTestHarness: + + @property + def ins(self): + # Lazily set ins on the class. + cls = self.SPLIT[self._KIND] + ins = cls() + self.__class__.ins = ins + return ins class MetaPathFinder: @@ -147,10 +152,10 @@ class MetaPathFinder: def find_module(self, fullname, path): return super().find_module(fullname, path) -Frozen_MPF, Source_MPF = make_abc_subclasses(MetaPathFinder) +class MetaPathFinderDefaultsTests(ABCTestHarness): -class MetaPathFinderDefaultsTests: + SPLIT = make_abc_subclasses(MetaPathFinder) def test_find_module(self): # Default should return None. @@ -161,8 +166,9 @@ def test_invalidate_caches(self): self.ins.invalidate_caches() -tests = make_return_value_tests(MetaPathFinder, MetaPathFinderDefaultsTests) -Frozen_MPFDefaultTests, Source_MPFDefaultTests = tests +(Frozen_MPFDefaultTests, + Source_MPFDefaultTests + ) = test_util.test_both(MetaPathFinderDefaultsTests) class PathEntryFinder: @@ -170,10 +176,10 @@ class PathEntryFinder: def find_loader(self, fullname): return super().find_loader(fullname) -Frozen_PEF, Source_PEF = make_abc_subclasses(PathEntryFinder) +class PathEntryFinderDefaultsTests(ABCTestHarness): -class PathEntryFinderDefaultsTests: + SPLIT = make_abc_subclasses(PathEntryFinder) def test_find_loader(self): self.assertEqual((None, []), self.ins.find_loader('something')) @@ -186,8 +192,9 @@ def test_invalidate_caches(self): self.ins.invalidate_caches() -tests = make_return_value_tests(PathEntryFinder, PathEntryFinderDefaultsTests) -Frozen_PEFDefaultTests, Source_PEFDefaultTests = tests +(Frozen_PEFDefaultTests, + Source_PEFDefaultTests + ) = test_util.test_both(PathEntryFinderDefaultsTests) class Loader: @@ -196,10 +203,9 @@ def load_module(self, fullname): return super().load_module(fullname) -Frozen_L, Source_L = make_abc_subclasses(Loader) +class LoaderDefaultsTests(ABCTestHarness): - -class LoaderDefaultsTests: + SPLIT = make_abc_subclasses(Loader) def test_load_module(self): with self.assertRaises(ImportError): @@ -215,8 +221,9 @@ def test_module_repr(self): self.assertTrue(repr(mod)) -tests = make_return_value_tests(Loader, LoaderDefaultsTests) -Frozen_LDefaultTests, SourceLDefaultTests = tests +(Frozen_LDefaultTests, + SourceLDefaultTests + ) = test_util.test_both(LoaderDefaultsTests) class ResourceLoader(Loader): @@ -225,18 +232,18 @@ def get_data(self, path): return super().get_data(path) -Frozen_RL, Source_RL = make_abc_subclasses(ResourceLoader) - +class ResourceLoaderDefaultsTests(ABCTestHarness): -class ResourceLoaderDefaultsTests: + SPLIT = make_abc_subclasses(ResourceLoader) def test_get_data(self): with self.assertRaises(IOError): self.ins.get_data('/some/path') -tests = make_return_value_tests(ResourceLoader, ResourceLoaderDefaultsTests) -Frozen_RLDefaultTests, Source_RLDefaultTests = tests +(Frozen_RLDefaultTests, + Source_RLDefaultTests + ) = test_util.test_both(ResourceLoaderDefaultsTests) class InspectLoader(Loader): @@ -248,10 +255,12 @@ def get_source(self, fullname): return super().get_source(fullname) -Frozen_IL, Source_IL = make_abc_subclasses(InspectLoader) +SPLIT_IL = make_abc_subclasses(InspectLoader) -class InspectLoaderDefaultsTests: +class InspectLoaderDefaultsTests(ABCTestHarness): + + SPLIT = SPLIT_IL def test_is_package(self): with self.assertRaises(ImportError): @@ -262,8 +271,9 @@ def test_get_source(self): self.ins.get_source('blah') -tests = make_return_value_tests(InspectLoader, InspectLoaderDefaultsTests) -Frozen_ILDefaultTests, Source_ILDefaultTests = tests +(Frozen_ILDefaultTests, + Source_ILDefaultTests + ) = test_util.test_both(InspectLoaderDefaultsTests) class ExecutionLoader(InspectLoader): @@ -271,18 +281,150 @@ class ExecutionLoader(InspectLoader): def get_filename(self, fullname): return super().get_filename(fullname) -Frozen_EL, Source_EL = make_abc_subclasses(ExecutionLoader) + +SPLIT_EL = make_abc_subclasses(ExecutionLoader) -class ExecutionLoaderDefaultsTests: +class ExecutionLoaderDefaultsTests(ABCTestHarness): + + SPLIT = SPLIT_EL def test_get_filename(self): with self.assertRaises(ImportError): self.ins.get_filename('blah') -tests = make_return_value_tests(ExecutionLoader, InspectLoaderDefaultsTests) -Frozen_ELDefaultTests, Source_ELDefaultsTests = tests +(Frozen_ELDefaultTests, + Source_ELDefaultsTests + ) = test_util.test_both(InspectLoaderDefaultsTests) + + +##### MetaPathFinder concrete methods ########################################## +class MetaPathFinderFindModuleTests: + + @classmethod + def finder(cls, spec): + class MetaPathSpecFinder(cls.abc.MetaPathFinder): + + def find_spec(self, fullname, path, target=None): + self.called_for = fullname, path + return spec + + return MetaPathSpecFinder() + + def test_no_spec(self): + finder = self.finder(None) + path = ['a', 'b', 'c'] + name = 'blah' + found = finder.find_module(name, path) + self.assertIsNone(found) + self.assertEqual(name, finder.called_for[0]) + self.assertEqual(path, finder.called_for[1]) + + def test_spec(self): + loader = object() + spec = self.util.spec_from_loader('blah', loader) + finder = self.finder(spec) + found = finder.find_module('blah', None) + self.assertIs(found, spec.loader) + + +(Frozen_MPFFindModuleTests, + Source_MPFFindModuleTests + ) = test_util.test_both(MetaPathFinderFindModuleTests, abc=abc, util=util) + + +##### PathEntryFinder concrete methods ######################################### +class PathEntryFinderFindLoaderTests: + + @classmethod + def finder(cls, spec): + class PathEntrySpecFinder(cls.abc.PathEntryFinder): + + def find_spec(self, fullname, target=None): + self.called_for = fullname + return spec + + return PathEntrySpecFinder() + + def test_no_spec(self): + finder = self.finder(None) + name = 'blah' + found = finder.find_loader(name) + self.assertIsNone(found[0]) + self.assertEqual([], found[1]) + self.assertEqual(name, finder.called_for) + + def test_spec_with_loader(self): + loader = object() + spec = self.util.spec_from_loader('blah', loader) + finder = self.finder(spec) + found = finder.find_loader('blah') + self.assertIs(found[0], spec.loader) + + def test_spec_with_portions(self): + spec = self.machinery.ModuleSpec('blah', None) + paths = ['a', 'b', 'c'] + spec.submodule_search_locations = paths + finder = self.finder(spec) + found = finder.find_loader('blah') + self.assertIsNone(found[0]) + self.assertEqual(paths, found[1]) + + +(Frozen_PEFFindLoaderTests, + Source_PEFFindLoaderTests + ) = test_util.test_both(PathEntryFinderFindLoaderTests, abc=abc, util=util, + machinery=machinery) + + +##### Loader concrete methods ################################################## +class LoaderLoadModuleTests: + + def loader(self): + class SpecLoader(self.abc.Loader): + found = None + def exec_module(self, module): + self.found = module + + def is_package(self, fullname): + """Force some non-default module state to be set.""" + return True + + return SpecLoader() + + def test_fresh(self): + loader = self.loader() + name = 'blah' + with test_util.uncache(name): + loader.load_module(name) + module = loader.found + self.assertIs(sys.modules[name], module) + self.assertEqual(loader, module.__loader__) + self.assertEqual(loader, module.__spec__.loader) + self.assertEqual(name, module.__name__) + self.assertEqual(name, module.__spec__.name) + self.assertIsNotNone(module.__path__) + self.assertIsNotNone(module.__path__, + module.__spec__.submodule_search_locations) + + def test_reload(self): + name = 'blah' + loader = self.loader() + module = types.ModuleType(name) + module.__spec__ = self.util.spec_from_loader(name, loader) + module.__loader__ = loader + with test_util.uncache(name): + sys.modules[name] = module + loader.load_module(name) + found = loader.found + self.assertIs(found, sys.modules[name]) + self.assertIs(module, sys.modules[name]) + + +(Frozen_LoaderLoadModuleTests, + Source_LoaderLoadModuleTests + ) = test_util.test_both(LoaderLoadModuleTests, abc=abc, util=util) ##### InspectLoader concrete methods ########################################### @@ -328,11 +470,10 @@ def test_source_to_code_no_path(self): self.assertEqual(code.co_filename, '') -class Frozen_ILSourceToCodeTests(InspectLoaderSourceToCodeTests, unittest.TestCase): - InspectLoaderSubclass = Frozen_IL - -class Source_ILSourceToCodeTests(InspectLoaderSourceToCodeTests, unittest.TestCase): - InspectLoaderSubclass = Source_IL +(Frozen_ILSourceToCodeTests, + Source_ILSourceToCodeTests + ) = test_util.test_both(InspectLoaderSourceToCodeTests, + InspectLoaderSubclass=SPLIT_IL) class InspectLoaderGetCodeTests: @@ -362,11 +503,10 @@ def test_get_code_source_not_found(self): loader.get_code('blah') -class Frozen_ILGetCodeTests(InspectLoaderGetCodeTests, unittest.TestCase): - InspectLoaderSubclass = Frozen_IL - -class Source_ILGetCodeTests(InspectLoaderGetCodeTests, unittest.TestCase): - InspectLoaderSubclass = Source_IL +(Frozen_ILGetCodeTests, + Source_ILGetCodeTests + ) = test_util.test_both(InspectLoaderGetCodeTests, + InspectLoaderSubclass=SPLIT_IL) class InspectLoaderLoadModuleTests: @@ -388,7 +528,9 @@ def test_get_code_ImportError(self): mocked_get_code.side_effect = ImportError with self.assertRaises(ImportError): loader = self.InspectLoaderSubclass() - loader.load_module(self.module_name) + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + loader.load_module(self.module_name) def test_get_code_None(self): # If get_code() returns None, raise ImportError. @@ -408,11 +550,10 @@ def test_module_returned(self): self.assertEqual(module, sys.modules[self.module_name]) -class Frozen_ILLoadModuleTests(InspectLoaderLoadModuleTests, unittest.TestCase): - InspectLoaderSubclass = Frozen_IL - -class Source_ILLoadModuleTests(InspectLoaderLoadModuleTests, unittest.TestCase): - InspectLoaderSubclass = Source_IL +(Frozen_ILLoadModuleTests, + Source_ILLoadModuleTests + ) = test_util.test_both(InspectLoaderLoadModuleTests, + InspectLoaderSubclass=SPLIT_IL) ##### ExecutionLoader concrete methods ######################################### @@ -473,15 +614,14 @@ def test_get_code_no_path(self): self.assertEqual(module.attr, 42) -class Frozen_ELGetCodeTests(ExecutionLoaderGetCodeTests, unittest.TestCase): - ExecutionLoaderSubclass = Frozen_EL - -class Source_ELGetCodeTests(ExecutionLoaderGetCodeTests, unittest.TestCase): - ExecutionLoaderSubclass = Source_EL +(Frozen_ELGetCodeTests, + Source_ELGetCodeTests + ) = test_util.test_both(ExecutionLoaderGetCodeTests, + ExecutionLoaderSubclass=SPLIT_EL) ##### SourceLoader concrete methods ############################################ -class SourceLoader: +class SourceOnlyLoader: # Globals that should be defined for all modules. source = (b"_ = '::'.join([__name__, __file__, __cached__, __package__, " @@ -502,10 +642,10 @@ def module_repr(self, module): return '' -Frozen_SourceOnlyL, Source_SourceOnlyL = make_abc_subclasses(SourceLoader) +SPLIT_SOL = make_abc_subclasses(SourceOnlyLoader, 'SourceLoader') -class SourceLoader(SourceLoader): +class SourceLoader(SourceOnlyLoader): source_mtime = 1 @@ -542,11 +682,7 @@ def set_data(self, path, data): return path == self.bytecode_path -Frozen_SL, Source_SL = make_abc_subclasses(SourceLoader) -Frozen_SL.util = frozen_util -Source_SL.util = source_util -Frozen_SL.init = frozen_init -Source_SL.init = source_init +SPLIT_SL = make_abc_subclasses(SourceLoader, util=util, init=init) class SourceLoaderTestHarness: @@ -630,8 +766,10 @@ def test_load_module(self): # Loading a module should set __name__, __loader__, __package__, # __path__ (for packages), __file__, and __cached__. # The module should also be put into sys.modules. - with util.uncache(self.name): - module = self.loader.load_module(self.name) + with test_util.uncache(self.name): + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + module = self.loader.load_module(self.name) self.verify_module(module) self.assertEqual(module.__path__, [os.path.dirname(self.path)]) self.assertIn(self.name, sys.modules) @@ -641,10 +779,12 @@ def test_package_settings(self): # is a package. # Testing the values for a package are covered by test_load_module. self.setUp(is_package=False) - with util.uncache(self.name): - module = self.loader.load_module(self.name) + with test_util.uncache(self.name): + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + module = self.loader.load_module(self.name) self.verify_module(module) - self.assertTrue(not hasattr(module, '__path__')) + self.assertFalse(hasattr(module, '__path__')) def test_get_source_encoding(self): # Source is considered encoded in UTF-8 by default unless otherwise @@ -659,13 +799,10 @@ def test_get_source_encoding(self): self.assertEqual(returned_source, source) -class Frozen_SourceOnlyLTests(SourceOnlyLoaderTests, unittest.TestCase): - loader_mock = Frozen_SourceOnlyL - util = frozen_util - -class Source_SourceOnlyLTests(SourceOnlyLoaderTests, unittest.TestCase): - loader_mock = Source_SourceOnlyL - util = source_util +(Frozen_SourceOnlyLoaderTests, + Source_SourceOnlyLoaderTests + ) = test_util.test_both(SourceOnlyLoaderTests, util=util, + loader_mock=SPLIT_SOL) @unittest.skipIf(sys.dont_write_bytecode, "sys.dont_write_bytecode is true") @@ -757,15 +894,10 @@ def closure(*args, **kwargs): self.verify_code(code_object) -class Frozen_SLBytecodeTests(SourceLoaderBytecodeTests, unittest.TestCase): - loader_mock = Frozen_SL - init = frozen_init - util = frozen_util - -class SourceSLBytecodeTests(SourceLoaderBytecodeTests, unittest.TestCase): - loader_mock = Source_SL - init = source_init - util = source_util +(Frozen_SLBytecodeTests, + SourceSLBytecodeTests + ) = test_util.test_both(SourceLoaderBytecodeTests, init=init, util=util, + loader_mock=SPLIT_SL) class SourceLoaderGetSourceTests: @@ -801,11 +933,10 @@ def test_universal_newlines(self): self.assertEqual(mock.get_source(name), expect) -class Frozen_SourceOnlyLGetSourceTests(SourceLoaderGetSourceTests, unittest.TestCase): - SourceOnlyLoaderMock = Frozen_SourceOnlyL - -class Source_SourceOnlyLGetSourceTests(SourceLoaderGetSourceTests, unittest.TestCase): - SourceOnlyLoaderMock = Source_SourceOnlyL +(Frozen_SourceOnlyLoaderGetSourceTests, + Source_SourceOnlyLoaderGetSourceTests + ) = test_util.test_both(SourceLoaderGetSourceTests, + SourceOnlyLoaderMock=SPLIT_SOL) if __name__ == '__main__': diff --git a/Lib/test/test_importlib/test_api.py b/Lib/test/test_importlib/test_api.py index c6c2d47051a3..6bc3c564a58b 100644 --- a/Lib/test/test_importlib/test_api.py +++ b/Lib/test/test_importlib/test_api.py @@ -1,14 +1,15 @@ -from . import util +from . import util as test_util -frozen_init, source_init = util.import_importlib('importlib') -frozen_util, source_util = util.import_importlib('importlib.util') -frozen_machinery, source_machinery = util.import_importlib('importlib.machinery') +init = test_util.import_importlib('importlib') +util = test_util.import_importlib('importlib.util') +machinery = test_util.import_importlib('importlib.machinery') import os.path import sys from test import support import types import unittest +import warnings class ImportModuleTests: @@ -17,8 +18,8 @@ class ImportModuleTests: def test_module_import(self): # Test importing a top-level module. - with util.mock_modules('top_level') as mock: - with util.import_state(meta_path=[mock]): + with test_util.mock_modules('top_level') as mock: + with test_util.import_state(meta_path=[mock]): module = self.init.import_module('top_level') self.assertEqual(module.__name__, 'top_level') @@ -27,8 +28,8 @@ def test_absolute_package_import(self): pkg_name = 'pkg' pkg_long_name = '{0}.__init__'.format(pkg_name) name = '{0}.mod'.format(pkg_name) - with util.mock_modules(pkg_long_name, name) as mock: - with util.import_state(meta_path=[mock]): + with test_util.mock_modules(pkg_long_name, name) as mock: + with test_util.import_state(meta_path=[mock]): module = self.init.import_module(name) self.assertEqual(module.__name__, name) @@ -39,16 +40,16 @@ def test_shallow_relative_package_import(self): module_name = 'mod' absolute_name = '{0}.{1}'.format(pkg_name, module_name) relative_name = '.{0}'.format(module_name) - with util.mock_modules(pkg_long_name, absolute_name) as mock: - with util.import_state(meta_path=[mock]): + with test_util.mock_modules(pkg_long_name, absolute_name) as mock: + with test_util.import_state(meta_path=[mock]): self.init.import_module(pkg_name) module = self.init.import_module(relative_name, pkg_name) self.assertEqual(module.__name__, absolute_name) def test_deep_relative_package_import(self): modules = ['a.__init__', 'a.b.__init__', 'a.c'] - with util.mock_modules(*modules) as mock: - with util.import_state(meta_path=[mock]): + with test_util.mock_modules(*modules) as mock: + with test_util.import_state(meta_path=[mock]): self.init.import_module('a') self.init.import_module('a.b') module = self.init.import_module('..c', 'a.b') @@ -60,8 +61,8 @@ def test_absolute_import_with_package(self): pkg_name = 'pkg' pkg_long_name = '{0}.__init__'.format(pkg_name) name = '{0}.mod'.format(pkg_name) - with util.mock_modules(pkg_long_name, name) as mock: - with util.import_state(meta_path=[mock]): + with test_util.mock_modules(pkg_long_name, name) as mock: + with test_util.import_state(meta_path=[mock]): self.init.import_module(pkg_name) module = self.init.import_module(name, pkg_name) self.assertEqual(module.__name__, name) @@ -85,16 +86,15 @@ def load_b(): b_load_count += 1 code = {'a': load_a, 'a.b': load_b} modules = ['a.__init__', 'a.b'] - with util.mock_modules(*modules, module_code=code) as mock: - with util.import_state(meta_path=[mock]): + with test_util.mock_modules(*modules, module_code=code) as mock: + with test_util.import_state(meta_path=[mock]): self.init.import_module('a.b') self.assertEqual(b_load_count, 1) -class Frozen_ImportModuleTests(ImportModuleTests, unittest.TestCase): - init = frozen_init -class Source_ImportModuleTests(ImportModuleTests, unittest.TestCase): - init = source_init +(Frozen_ImportModuleTests, + Source_ImportModuleTests + ) = test_util.test_both(ImportModuleTests, init=init) class FindLoaderTests: @@ -106,29 +106,33 @@ def find_module(name, path=None): return name, path def test_sys_modules(self): # If a module with __loader__ is in sys.modules, then return it. name = 'some_mod' - with util.uncache(name): + with test_util.uncache(name): module = types.ModuleType(name) loader = 'a loader!' module.__loader__ = loader sys.modules[name] = module - found = self.init.find_loader(name) + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + found = self.init.find_loader(name) self.assertEqual(loader, found) def test_sys_modules_loader_is_None(self): # If sys.modules[name].__loader__ is None, raise ValueError. name = 'some_mod' - with util.uncache(name): + with test_util.uncache(name): module = types.ModuleType(name) module.__loader__ = None sys.modules[name] = module with self.assertRaises(ValueError): - self.init.find_loader(name) + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + self.init.find_loader(name) def test_sys_modules_loader_is_not_set(self): # Should raise ValueError # Issue #17099 name = 'some_mod' - with util.uncache(name): + with test_util.uncache(name): module = types.ModuleType(name) try: del module.__loader__ @@ -136,123 +140,40 @@ def test_sys_modules_loader_is_not_set(self): pass sys.modules[name] = module with self.assertRaises(ValueError): - self.init.find_loader(name) + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + self.init.find_loader(name) def test_success(self): # Return the loader found on sys.meta_path. name = 'some_mod' - with util.uncache(name): - with util.import_state(meta_path=[self.FakeMetaFinder]): - self.assertEqual((name, None), self.init.find_loader(name)) + with test_util.uncache(name): + with test_util.import_state(meta_path=[self.FakeMetaFinder]): + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + self.assertEqual((name, None), self.init.find_loader(name)) def test_success_path(self): # Searching on a path should work. name = 'some_mod' path = 'path to some place' - with util.uncache(name): - with util.import_state(meta_path=[self.FakeMetaFinder]): - self.assertEqual((name, path), - self.init.find_loader(name, path)) + with test_util.uncache(name): + with test_util.import_state(meta_path=[self.FakeMetaFinder]): + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + self.assertEqual((name, path), + self.init.find_loader(name, path)) def test_nothing(self): # None is returned upon failure to find a loader. - self.assertIsNone(self.init.find_loader('nevergoingtofindthismodule')) + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + self.assertIsNone(self.init.find_loader('nevergoingtofindthismodule')) -class Frozen_FindLoaderTests(FindLoaderTests, unittest.TestCase): - init = frozen_init -class Source_FindLoaderTests(FindLoaderTests, unittest.TestCase): - init = source_init - - -class FindSpecTests: - - class FakeMetaFinder: - @staticmethod - def find_spec(name, path=None, target=None): return name, path, target - - def test_sys_modules(self): - name = 'some_mod' - with util.uncache(name): - module = types.ModuleType(name) - loader = 'a loader!' - spec = self.machinery.ModuleSpec(name, loader) - module.__loader__ = loader - module.__spec__ = spec - sys.modules[name] = module - found = self.init.find_spec(name) - self.assertEqual(found, spec) - - def test_sys_modules_without___loader__(self): - name = 'some_mod' - with util.uncache(name): - module = types.ModuleType(name) - del module.__loader__ - loader = 'a loader!' - spec = self.machinery.ModuleSpec(name, loader) - module.__spec__ = spec - sys.modules[name] = module - found = self.init.find_spec(name) - self.assertEqual(found, spec) - - def test_sys_modules_spec_is_None(self): - name = 'some_mod' - with util.uncache(name): - module = types.ModuleType(name) - module.__spec__ = None - sys.modules[name] = module - with self.assertRaises(ValueError): - self.init.find_spec(name) - - def test_sys_modules_loader_is_None(self): - name = 'some_mod' - with util.uncache(name): - module = types.ModuleType(name) - spec = self.machinery.ModuleSpec(name, None) - module.__spec__ = spec - sys.modules[name] = module - found = self.init.find_spec(name) - self.assertEqual(found, spec) - - def test_sys_modules_spec_is_not_set(self): - name = 'some_mod' - with util.uncache(name): - module = types.ModuleType(name) - try: - del module.__spec__ - except AttributeError: - pass - sys.modules[name] = module - with self.assertRaises(ValueError): - self.init.find_spec(name) - - def test_success(self): - name = 'some_mod' - with util.uncache(name): - with util.import_state(meta_path=[self.FakeMetaFinder]): - self.assertEqual((name, None, None), - self.init.find_spec(name)) - - def test_success_path(self): - # Searching on a path should work. - name = 'some_mod' - path = 'path to some place' - with util.uncache(name): - with util.import_state(meta_path=[self.FakeMetaFinder]): - self.assertEqual((name, path, None), - self.init.find_spec(name, path)) - - def test_nothing(self): - # None is returned upon failure to find a loader. - self.assertIsNone(self.init.find_spec('nevergoingtofindthismodule')) - -class Frozen_FindSpecTests(FindSpecTests, unittest.TestCase): - init = frozen_init - machinery = frozen_machinery - -class Source_FindSpecTests(FindSpecTests, unittest.TestCase): - init = source_init - machinery = source_machinery +(Frozen_FindLoaderTests, + Source_FindLoaderTests + ) = test_util.test_both(FindLoaderTests, init=init) class ReloadTests: @@ -272,10 +193,10 @@ def code(): module = type(sys)('top_level') module.spam = 3 sys.modules['top_level'] = module - mock = util.mock_modules('top_level', - module_code={'top_level': code}) + mock = test_util.mock_modules('top_level', + module_code={'top_level': code}) with mock: - with util.import_state(meta_path=[mock]): + with test_util.import_state(meta_path=[mock]): module = self.init.import_module('top_level') reloaded = self.init.reload(module) actual = sys.modules['top_level'] @@ -307,7 +228,7 @@ def test_reload_loader_replaced(self): def test_reload_location_changed(self): name = 'spam' with support.temp_cwd(None) as cwd: - with util.uncache('spam'): + with test_util.uncache('spam'): with support.DirsOnSysPath(cwd): # Start as a plain module. self.init.invalidate_caches() @@ -318,13 +239,13 @@ def test_reload_location_changed(self): '__file__': path, '__cached__': cached, '__doc__': None, - '__builtins__': __builtins__, } support.create_empty_file(path) module = self.init.import_module(name) - ns = vars(module) + ns = vars(module).copy() loader = ns.pop('__loader__') spec = ns.pop('__spec__') + ns.pop('__builtins__', None) # An implementation detail. self.assertEqual(spec.name, name) self.assertEqual(spec.loader, loader) self.assertEqual(loader.path, path) @@ -340,14 +261,14 @@ def test_reload_location_changed(self): '__cached__': cached, '__path__': [os.path.dirname(init_path)], '__doc__': None, - '__builtins__': __builtins__, } os.mkdir(name) os.rename(path, init_path) reloaded = self.init.reload(module) - ns = vars(reloaded) + ns = vars(reloaded).copy() loader = ns.pop('__loader__') spec = ns.pop('__spec__') + ns.pop('__builtins__', None) # An implementation detail. self.assertEqual(spec.name, name) self.assertEqual(spec.loader, loader) self.assertIs(reloaded, module) @@ -358,7 +279,7 @@ def test_reload_location_changed(self): def test_reload_namespace_changed(self): name = 'spam' with support.temp_cwd(None) as cwd: - with util.uncache('spam'): + with test_util.uncache('spam'): with support.DirsOnSysPath(cwd): # Start as a namespace package. self.init.invalidate_caches() @@ -372,10 +293,11 @@ def test_reload_namespace_changed(self): with open(bad_path, 'w') as init_file: init_file.write('eggs = None') module = self.init.import_module(name) - ns = vars(module) + ns = vars(module).copy() loader = ns.pop('__loader__') path = ns.pop('__path__') spec = ns.pop('__spec__') + ns.pop('__builtins__', None) # An implementation detail. self.assertEqual(spec.name, name) self.assertIs(spec.loader, None) self.assertIsNot(loader, None) @@ -396,28 +318,34 @@ def test_reload_namespace_changed(self): '__cached__': cached, '__path__': [os.path.dirname(init_path)], '__doc__': None, - '__builtins__': __builtins__, 'eggs': None, } os.rename(bad_path, init_path) reloaded = self.init.reload(module) - ns = vars(reloaded) + ns = vars(reloaded).copy() loader = ns.pop('__loader__') spec = ns.pop('__spec__') + ns.pop('__builtins__', None) # An implementation detail. self.assertEqual(spec.name, name) self.assertEqual(spec.loader, loader) self.assertIs(reloaded, module) self.assertEqual(loader.path, init_path) self.assertEqual(ns, expected) + def test_reload_submodule(self): + # See #19851. + name = 'spam' + subname = 'ham' + with test_util.temp_module(name, pkg=True) as pkg_dir: + fullname, _ = test_util.submodule(name, subname, pkg_dir) + ham = self.init.import_module(fullname) + reloaded = self.init.reload(ham) + self.assertIs(reloaded, ham) -class Frozen_ReloadTests(ReloadTests, unittest.TestCase): - init = frozen_init - util = frozen_util -class Source_ReloadTests(ReloadTests, unittest.TestCase): - init = source_init - util = source_util +(Frozen_ReloadTests, + Source_ReloadTests + ) = test_util.test_both(ReloadTests, init=init, util=util) class InvalidateCacheTests: @@ -450,11 +378,10 @@ def test_method_lacking(self): self.addCleanup(lambda: sys.path_importer_cache.__delitem__(key)) self.init.invalidate_caches() # Shouldn't trigger an exception. -class Frozen_InvalidateCacheTests(InvalidateCacheTests, unittest.TestCase): - init = frozen_init -class Source_InvalidateCacheTests(InvalidateCacheTests, unittest.TestCase): - init = source_init +(Frozen_InvalidateCacheTests, + Source_InvalidateCacheTests + ) = test_util.test_both(InvalidateCacheTests, init=init) class FrozenImportlibTests(unittest.TestCase): @@ -464,6 +391,7 @@ def test_no_frozen_importlib(self): # Can't do an isinstance() check since separate copies of importlib # may have been used for import, so just check the name is not for the # frozen loader. + source_init = init['Source'] self.assertNotEqual(source_init.__loader__.__class__.__name__, 'FrozenImporter') @@ -492,11 +420,10 @@ def test_everyone_has___spec__(self): elif self.machinery.FrozenImporter.find_module(name): self.assertIsNot(module.__spec__, None) -class Frozen_StartupTests(StartupTests, unittest.TestCase): - machinery = frozen_machinery -class Source_StartupTests(StartupTests, unittest.TestCase): - machinery = source_machinery +(Frozen_StartupTests, + Source_StartupTests + ) = test_util.test_both(StartupTests, machinery=machinery) if __name__ == '__main__': diff --git a/Lib/test/test_importlib/test_lazy.py b/Lib/test/test_importlib/test_lazy.py new file mode 100644 index 000000000000..2e191bbf5cab --- /dev/null +++ b/Lib/test/test_importlib/test_lazy.py @@ -0,0 +1,132 @@ +import importlib +from importlib import abc +from importlib import util +import unittest + +from . import util as test_util + + +class CollectInit: + + def __init__(self, *args, **kwargs): + self.args = args + self.kwargs = kwargs + + def exec_module(self, module): + return self + + +class LazyLoaderFactoryTests(unittest.TestCase): + + def test_init(self): + factory = util.LazyLoader.factory(CollectInit) + # E.g. what importlib.machinery.FileFinder instantiates loaders with + # plus keyword arguments. + lazy_loader = factory('module name', 'module path', kw='kw') + loader = lazy_loader.loader + self.assertEqual(('module name', 'module path'), loader.args) + self.assertEqual({'kw': 'kw'}, loader.kwargs) + + def test_validation(self): + # No exec_module(), no lazy loading. + with self.assertRaises(TypeError): + util.LazyLoader.factory(object) + + +class TestingImporter(abc.MetaPathFinder, abc.Loader): + + module_name = 'lazy_loader_test' + mutated_name = 'changed' + loaded = None + source_code = 'attr = 42; __name__ = {!r}'.format(mutated_name) + + def find_spec(self, name, path, target=None): + if name != self.module_name: + return None + return util.spec_from_loader(name, util.LazyLoader(self)) + + def exec_module(self, module): + exec(self.source_code, module.__dict__) + self.loaded = module + + +class LazyLoaderTests(unittest.TestCase): + + def test_init(self): + with self.assertRaises(TypeError): + util.LazyLoader(object) + + def new_module(self, source_code=None): + loader = TestingImporter() + if source_code is not None: + loader.source_code = source_code + spec = util.spec_from_loader(TestingImporter.module_name, + util.LazyLoader(loader)) + module = spec.loader.create_module(spec) + module.__spec__ = spec + module.__loader__ = spec.loader + spec.loader.exec_module(module) + # Module is now lazy. + self.assertIsNone(loader.loaded) + return module + + def test_e2e(self): + # End-to-end test to verify the load is in fact lazy. + importer = TestingImporter() + assert importer.loaded is None + with test_util.uncache(importer.module_name): + with test_util.import_state(meta_path=[importer]): + module = importlib.import_module(importer.module_name) + self.assertIsNone(importer.loaded) + # Trigger load. + self.assertEqual(module.__loader__, importer) + self.assertIsNotNone(importer.loaded) + self.assertEqual(module, importer.loaded) + + def test_attr_unchanged(self): + # An attribute only mutated as a side-effect of import should not be + # changed needlessly. + module = self.new_module() + self.assertEqual(TestingImporter.mutated_name, module.__name__) + + def test_new_attr(self): + # A new attribute should persist. + module = self.new_module() + module.new_attr = 42 + self.assertEqual(42, module.new_attr) + + def test_mutated_preexisting_attr(self): + # Changing an attribute that already existed on the module -- + # e.g. __name__ -- should persist. + module = self.new_module() + module.__name__ = 'bogus' + self.assertEqual('bogus', module.__name__) + + def test_mutated_attr(self): + # Changing an attribute that comes into existence after an import + # should persist. + module = self.new_module() + module.attr = 6 + self.assertEqual(6, module.attr) + + def test_delete_eventual_attr(self): + # Deleting an attribute should stay deleted. + module = self.new_module() + del module.attr + self.assertFalse(hasattr(module, 'attr')) + + def test_delete_preexisting_attr(self): + module = self.new_module() + del module.__name__ + self.assertFalse(hasattr(module, '__name__')) + + def test_module_substitution_error(self): + source_code = 'import sys; sys.modules[__name__] = 42' + module = self.new_module(source_code) + with test_util.uncache(TestingImporter.module_name): + with self.assertRaises(ValueError): + module.__name__ + + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_importlib/test_locks.py b/Lib/test/test_importlib/test_locks.py index dc97ba15671a..df0af12d3886 100644 --- a/Lib/test/test_importlib/test_locks.py +++ b/Lib/test/test_importlib/test_locks.py @@ -1,7 +1,6 @@ -from . import util -frozen_init, source_init = util.import_importlib('importlib') -frozen_bootstrap = frozen_init._bootstrap -source_bootstrap = source_init._bootstrap +from . import util as test_util + +init = test_util.import_importlib('importlib') import sys import time @@ -32,14 +31,20 @@ class ModuleLockAsRLockTests: test_timeout = None # _release_save() unsupported test_release_save_unacquired = None + # lock status in repr unsupported + test_repr = None + test_locked_repr = None - class Frozen_ModuleLockAsRLockTests(ModuleLockAsRLockTests, lock_tests.RLockTests): - LockType = frozen_bootstrap._ModuleLock - - class Source_ModuleLockAsRLockTests(ModuleLockAsRLockTests, lock_tests.RLockTests): - LockType = source_bootstrap._ModuleLock + LOCK_TYPES = {kind: splitinit._bootstrap._ModuleLock + for kind, splitinit in init.items()} + (Frozen_ModuleLockAsRLockTests, + Source_ModuleLockAsRLockTests + ) = test_util.test_both(ModuleLockAsRLockTests, lock_tests.RLockTests, + LockType=LOCK_TYPES) else: + LOCK_TYPES = {} + class Frozen_ModuleLockAsRLockTests(unittest.TestCase): pass @@ -47,78 +52,94 @@ class Source_ModuleLockAsRLockTests(unittest.TestCase): pass -class DeadlockAvoidanceTests: - - def setUp(self): - try: - self.old_switchinterval = sys.getswitchinterval() - sys.setswitchinterval(0.000001) - except AttributeError: - self.old_switchinterval = None - - def tearDown(self): - if self.old_switchinterval is not None: - sys.setswitchinterval(self.old_switchinterval) - - def run_deadlock_avoidance_test(self, create_deadlock): - NLOCKS = 10 - locks = [self.LockType(str(i)) for i in range(NLOCKS)] - pairs = [(locks[i], locks[(i+1)%NLOCKS]) for i in range(NLOCKS)] - if create_deadlock: - NTHREADS = NLOCKS - else: - NTHREADS = NLOCKS - 1 - barrier = threading.Barrier(NTHREADS) - results = [] - def _acquire(lock): - """Try to acquire the lock. Return True on success, False on deadlock.""" +if threading is not None: + class DeadlockAvoidanceTests: + + def setUp(self): try: - lock.acquire() - except self.DeadlockError: - return False + self.old_switchinterval = sys.getswitchinterval() + sys.setswitchinterval(0.000001) + except AttributeError: + self.old_switchinterval = None + + def tearDown(self): + if self.old_switchinterval is not None: + sys.setswitchinterval(self.old_switchinterval) + + def run_deadlock_avoidance_test(self, create_deadlock): + NLOCKS = 10 + locks = [self.LockType(str(i)) for i in range(NLOCKS)] + pairs = [(locks[i], locks[(i+1)%NLOCKS]) for i in range(NLOCKS)] + if create_deadlock: + NTHREADS = NLOCKS else: - return True - def f(): - a, b = pairs.pop() - ra = _acquire(a) - barrier.wait() - rb = _acquire(b) - results.append((ra, rb)) - if rb: - b.release() - if ra: - a.release() - lock_tests.Bunch(f, NTHREADS).wait_for_finished() - self.assertEqual(len(results), NTHREADS) - return results - - def test_deadlock(self): - results = self.run_deadlock_avoidance_test(True) - # At least one of the threads detected a potential deadlock on its - # second acquire() call. It may be several of them, because the - # deadlock avoidance mechanism is conservative. - nb_deadlocks = results.count((True, False)) - self.assertGreaterEqual(nb_deadlocks, 1) - self.assertEqual(results.count((True, True)), len(results) - nb_deadlocks) - - def test_no_deadlock(self): - results = self.run_deadlock_avoidance_test(False) - self.assertEqual(results.count((True, False)), 0) - self.assertEqual(results.count((True, True)), len(results)) - -@unittest.skipUnless(threading, "threads needed for this test") -class Frozen_DeadlockAvoidanceTests(DeadlockAvoidanceTests, unittest.TestCase): - LockType = frozen_bootstrap._ModuleLock - DeadlockError = frozen_bootstrap._DeadlockError - -@unittest.skipUnless(threading, "threads needed for this test") -class Source_DeadlockAvoidanceTests(DeadlockAvoidanceTests, unittest.TestCase): - LockType = source_bootstrap._ModuleLock - DeadlockError = source_bootstrap._DeadlockError + NTHREADS = NLOCKS - 1 + barrier = threading.Barrier(NTHREADS) + results = [] + + def _acquire(lock): + """Try to acquire the lock. Return True on success, + False on deadlock.""" + try: + lock.acquire() + except self.DeadlockError: + return False + else: + return True + + def f(): + a, b = pairs.pop() + ra = _acquire(a) + barrier.wait() + rb = _acquire(b) + results.append((ra, rb)) + if rb: + b.release() + if ra: + a.release() + lock_tests.Bunch(f, NTHREADS).wait_for_finished() + self.assertEqual(len(results), NTHREADS) + return results + + def test_deadlock(self): + results = self.run_deadlock_avoidance_test(True) + # At least one of the threads detected a potential deadlock on its + # second acquire() call. It may be several of them, because the + # deadlock avoidance mechanism is conservative. + nb_deadlocks = results.count((True, False)) + self.assertGreaterEqual(nb_deadlocks, 1) + self.assertEqual(results.count((True, True)), len(results) - nb_deadlocks) + + def test_no_deadlock(self): + results = self.run_deadlock_avoidance_test(False) + self.assertEqual(results.count((True, False)), 0) + self.assertEqual(results.count((True, True)), len(results)) + + + DEADLOCK_ERRORS = {kind: splitinit._bootstrap._DeadlockError + for kind, splitinit in init.items()} + + (Frozen_DeadlockAvoidanceTests, + Source_DeadlockAvoidanceTests + ) = test_util.test_both(DeadlockAvoidanceTests, + LockType=LOCK_TYPES, + DeadlockError=DEADLOCK_ERRORS) +else: + DEADLOCK_ERRORS = {} + + class Frozen_DeadlockAvoidanceTests(unittest.TestCase): + pass + + class Source_DeadlockAvoidanceTests(unittest.TestCase): + pass class LifetimeTests: + @property + def bootstrap(self): + return self.init._bootstrap + def test_lock_lifetime(self): name = "xyzzy" self.assertNotIn(name, self.bootstrap._module_locks) @@ -135,11 +156,10 @@ def test_all_locks(self): self.assertEqual(0, len(self.bootstrap._module_locks), self.bootstrap._module_locks) -class Frozen_LifetimeTests(LifetimeTests, unittest.TestCase): - bootstrap = frozen_bootstrap -class Source_LifetimeTests(LifetimeTests, unittest.TestCase): - bootstrap = source_bootstrap +(Frozen_LifetimeTests, + Source_LifetimeTests + ) = test_util.test_both(LifetimeTests, init=init) @support.reap_threads diff --git a/Lib/test/test_namespace_pkgs.py b/Lib/test/test_importlib/test_namespace_pkgs.py similarity index 100% rename from Lib/test/test_namespace_pkgs.py rename to Lib/test/test_importlib/test_namespace_pkgs.py diff --git a/Lib/test/test_importlib/test_spec.py b/Lib/test/test_importlib/test_spec.py index e4ef39fd295d..8b333e8c2fa8 100644 --- a/Lib/test/test_importlib/test_spec.py +++ b/Lib/test/test_importlib/test_spec.py @@ -1,28 +1,20 @@ -from . import util +from . import util as test_util -frozen_init, source_init = util.import_importlib('importlib') -frozen_bootstrap = frozen_init._bootstrap -source_bootstrap = source_init._bootstrap -frozen_machinery, source_machinery = util.import_importlib('importlib.machinery') -frozen_util, source_util = util.import_importlib('importlib.util') +init = test_util.import_importlib('importlib') +machinery = test_util.import_importlib('importlib.machinery') +util = test_util.import_importlib('importlib.util') import os.path from test.support import CleanImport import unittest import sys +import warnings class TestLoader: def __init__(self, path=None, is_package=None): -# if path: -# if is_package: -# if not path.endswith('.py'): -# path = os.path.join(path, '__init__.py') -# elif is_package is None: -# is_package = path.endswith('__init__.py') - self.path = path self.package = is_package @@ -42,6 +34,9 @@ def _get_filename(self, name): def _is_package(self, name): return self.package + def create_module(self, spec): + return None + class NewLoader(TestLoader): @@ -55,10 +50,15 @@ class LegacyLoader(TestLoader): HAM = -1 - @frozen_util.module_for_loader - def load_module(self, module): - module.ham = self.HAM - return module + with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + + frozen_util = util['Frozen'] + + @frozen_util.module_for_loader + def load_module(self, module): + module.ham = self.HAM + return module class ModuleSpecTests: @@ -119,6 +119,13 @@ def test_default_is_package_true(self): self.assertIs(spec.cached, None) self.assertFalse(spec.has_location) + def test_has_location_setter(self): + spec = self.machinery.ModuleSpec(self.name, self.loader, + origin='somewhere') + self.assertFalse(spec.has_location) + spec.has_location = True + self.assertTrue(spec.has_location) + def test_equality(self): other = type(sys.implementation)(name=self.name, loader=self.loader, @@ -217,18 +224,17 @@ def test_cached_sourceless(self): self.assertEqual(self.loc_spec.cached, 'spam.pyc') -class Frozen_ModuleSpecTests(ModuleSpecTests, unittest.TestCase): - util = frozen_util - machinery = frozen_machinery - - -class Source_ModuleSpecTests(ModuleSpecTests, unittest.TestCase): - util = source_util - machinery = source_machinery +(Frozen_ModuleSpecTests, + Source_ModuleSpecTests + ) = test_util.test_both(ModuleSpecTests, util=util, machinery=machinery) class ModuleSpecMethodsTests: + @property + def bootstrap(self): + return self.init._bootstrap + def setUp(self): self.name = 'spam' self.path = 'spam.py' @@ -239,152 +245,14 @@ def setUp(self): origin=self.path) self.loc_spec._set_fileattr = True - # init_module_attrs - - def test_init_module_attrs(self): - module = type(sys)(self.name) - spec = self.machinery.ModuleSpec(self.name, self.loader) - self.bootstrap._SpecMethods(spec).init_module_attrs(module) - - self.assertEqual(module.__name__, spec.name) - self.assertIs(module.__loader__, spec.loader) - self.assertEqual(module.__package__, spec.parent) - self.assertIs(module.__spec__, spec) - self.assertFalse(hasattr(module, '__path__')) - self.assertFalse(hasattr(module, '__file__')) - self.assertFalse(hasattr(module, '__cached__')) - - def test_init_module_attrs_package(self): - module = type(sys)(self.name) - spec = self.machinery.ModuleSpec(self.name, self.loader) - spec.submodule_search_locations = ['spam', 'ham'] - self.bootstrap._SpecMethods(spec).init_module_attrs(module) - - self.assertEqual(module.__name__, spec.name) - self.assertIs(module.__loader__, spec.loader) - self.assertEqual(module.__package__, spec.parent) - self.assertIs(module.__spec__, spec) - self.assertIs(module.__path__, spec.submodule_search_locations) - self.assertFalse(hasattr(module, '__file__')) - self.assertFalse(hasattr(module, '__cached__')) - - def test_init_module_attrs_location(self): - module = type(sys)(self.name) - spec = self.loc_spec - self.bootstrap._SpecMethods(spec).init_module_attrs(module) - - self.assertEqual(module.__name__, spec.name) - self.assertIs(module.__loader__, spec.loader) - self.assertEqual(module.__package__, spec.parent) - self.assertIs(module.__spec__, spec) - self.assertFalse(hasattr(module, '__path__')) - self.assertEqual(module.__file__, spec.origin) - self.assertEqual(module.__cached__, - self.util.cache_from_source(spec.origin)) - - def test_init_module_attrs_different_name(self): - module = type(sys)('eggs') - spec = self.machinery.ModuleSpec(self.name, self.loader) - self.bootstrap._SpecMethods(spec).init_module_attrs(module) - - self.assertEqual(module.__name__, spec.name) - - def test_init_module_attrs_different_spec(self): - module = type(sys)(self.name) - module.__spec__ = self.machinery.ModuleSpec('eggs', object()) - spec = self.machinery.ModuleSpec(self.name, self.loader) - self.bootstrap._SpecMethods(spec).init_module_attrs(module) - - self.assertEqual(module.__name__, spec.name) - self.assertIs(module.__loader__, spec.loader) - self.assertEqual(module.__package__, spec.parent) - self.assertIs(module.__spec__, spec) - - def test_init_module_attrs_already_set(self): - module = type(sys)('ham.eggs') - module.__loader__ = object() - module.__package__ = 'ham' - module.__path__ = ['eggs'] - module.__file__ = 'ham/eggs/__init__.py' - module.__cached__ = self.util.cache_from_source(module.__file__) - original = vars(module).copy() - spec = self.loc_spec - spec.submodule_search_locations = [''] - self.bootstrap._SpecMethods(spec).init_module_attrs(module) - - self.assertIs(module.__loader__, original['__loader__']) - self.assertEqual(module.__package__, original['__package__']) - self.assertIs(module.__path__, original['__path__']) - self.assertEqual(module.__file__, original['__file__']) - self.assertEqual(module.__cached__, original['__cached__']) - - def test_init_module_attrs_immutable(self): - module = object() - spec = self.loc_spec - spec.submodule_search_locations = [''] - self.bootstrap._SpecMethods(spec).init_module_attrs(module) - - self.assertFalse(hasattr(module, '__name__')) - self.assertFalse(hasattr(module, '__loader__')) - self.assertFalse(hasattr(module, '__package__')) - self.assertFalse(hasattr(module, '__spec__')) - self.assertFalse(hasattr(module, '__path__')) - self.assertFalse(hasattr(module, '__file__')) - self.assertFalse(hasattr(module, '__cached__')) - - # create() - - def test_create(self): - created = self.bootstrap._SpecMethods(self.spec).create() - - self.assertEqual(created.__name__, self.spec.name) - self.assertIs(created.__loader__, self.spec.loader) - self.assertEqual(created.__package__, self.spec.parent) - self.assertIs(created.__spec__, self.spec) - self.assertFalse(hasattr(created, '__path__')) - self.assertFalse(hasattr(created, '__file__')) - self.assertFalse(hasattr(created, '__cached__')) - - def test_create_from_loader(self): - module = type(sys.implementation)() - class CreatingLoader(TestLoader): - def create_module(self, spec): - return module - self.spec.loader = CreatingLoader() - created = self.bootstrap._SpecMethods(self.spec).create() - - self.assertIs(created, module) - self.assertEqual(created.__name__, self.spec.name) - self.assertIs(created.__loader__, self.spec.loader) - self.assertEqual(created.__package__, self.spec.parent) - self.assertIs(created.__spec__, self.spec) - self.assertFalse(hasattr(created, '__path__')) - self.assertFalse(hasattr(created, '__file__')) - self.assertFalse(hasattr(created, '__cached__')) - - def test_create_from_loader_not_handled(self): - class CreatingLoader(TestLoader): - def create_module(self, spec): - return None - self.spec.loader = CreatingLoader() - created = self.bootstrap._SpecMethods(self.spec).create() - - self.assertEqual(created.__name__, self.spec.name) - self.assertIs(created.__loader__, self.spec.loader) - self.assertEqual(created.__package__, self.spec.parent) - self.assertIs(created.__spec__, self.spec) - self.assertFalse(hasattr(created, '__path__')) - self.assertFalse(hasattr(created, '__file__')) - self.assertFalse(hasattr(created, '__cached__')) - # exec() def test_exec(self): self.spec.loader = NewLoader() - module = self.bootstrap._SpecMethods(self.spec).create() + module = self.util.module_from_spec(self.spec) sys.modules[self.name] = module self.assertFalse(hasattr(module, 'eggs')) - self.bootstrap._SpecMethods(self.spec).exec(module) + self.bootstrap._exec(self.spec, module) self.assertEqual(module.eggs, 1) @@ -393,7 +261,7 @@ def test_exec(self): def test_load(self): self.spec.loader = NewLoader() with CleanImport(self.spec.name): - loaded = self.bootstrap._SpecMethods(self.spec).load() + loaded = self.bootstrap._load(self.spec) installed = sys.modules[self.spec.name] self.assertEqual(loaded.eggs, 1) @@ -406,7 +274,7 @@ def exec_module(self, module): sys.modules[module.__name__] = replacement self.spec.loader = ReplacingLoader() with CleanImport(self.spec.name): - loaded = self.bootstrap._SpecMethods(self.spec).load() + loaded = self.bootstrap._load(self.spec) installed = sys.modules[self.spec.name] self.assertIs(loaded, replacement) @@ -419,7 +287,7 @@ def exec_module(self, module): self.spec.loader = FailedLoader() with CleanImport(self.spec.name): with self.assertRaises(RuntimeError): - loaded = self.bootstrap._SpecMethods(self.spec).load() + loaded = self.bootstrap._load(self.spec) self.assertNotIn(self.spec.name, sys.modules) def test_load_failed_removed(self): @@ -430,32 +298,20 @@ def exec_module(self, module): self.spec.loader = FailedLoader() with CleanImport(self.spec.name): with self.assertRaises(RuntimeError): - loaded = self.bootstrap._SpecMethods(self.spec).load() + loaded = self.bootstrap._load(self.spec) self.assertNotIn(self.spec.name, sys.modules) - def test_load_existing(self): - existing = type(sys)('ham') - existing.count = 5 - self.spec.loader = NewLoader() - with CleanImport(self.name): - sys.modules[self.name] = existing - assert self.spec.name == self.name - loaded = self.bootstrap._SpecMethods(self.spec).load() - - self.assertEqual(loaded.eggs, 1) - self.assertFalse(hasattr(loaded, 'ham')) - def test_load_legacy(self): self.spec.loader = LegacyLoader() with CleanImport(self.spec.name): - loaded = self.bootstrap._SpecMethods(self.spec).load() + loaded = self.bootstrap._load(self.spec) self.assertEqual(loaded.ham, -1) def test_load_legacy_attributes(self): self.spec.loader = LegacyLoader() with CleanImport(self.spec.name): - loaded = self.bootstrap._SpecMethods(self.spec).load() + loaded = self.bootstrap._load(self.spec) self.assertIs(loaded.__loader__, self.spec.loader) self.assertEqual(loaded.__package__, self.spec.parent) @@ -469,7 +325,7 @@ def load_module(self, name): return module self.spec.loader = ImmutableLoader() with CleanImport(self.spec.name): - loaded = self.bootstrap._SpecMethods(self.spec).load() + loaded = self.bootstrap._load(self.spec) self.assertIs(sys.modules[self.spec.name], module) @@ -478,8 +334,8 @@ def load_module(self, name): def test_reload(self): self.spec.loader = NewLoader() with CleanImport(self.spec.name): - loaded = self.bootstrap._SpecMethods(self.spec).load() - reloaded = self.bootstrap._SpecMethods(self.spec).exec(loaded) + loaded = self.bootstrap._load(self.spec) + reloaded = self.bootstrap._exec(self.spec, loaded) installed = sys.modules[self.spec.name] self.assertEqual(loaded.eggs, 1) @@ -489,9 +345,9 @@ def test_reload(self): def test_reload_modified(self): self.spec.loader = NewLoader() with CleanImport(self.spec.name): - loaded = self.bootstrap._SpecMethods(self.spec).load() + loaded = self.bootstrap._load(self.spec) loaded.eggs = 2 - reloaded = self.bootstrap._SpecMethods(self.spec).exec(loaded) + reloaded = self.bootstrap._exec(self.spec, loaded) self.assertEqual(loaded.eggs, 1) self.assertIs(reloaded, loaded) @@ -499,9 +355,9 @@ def test_reload_modified(self): def test_reload_extra_attributes(self): self.spec.loader = NewLoader() with CleanImport(self.spec.name): - loaded = self.bootstrap._SpecMethods(self.spec).load() + loaded = self.bootstrap._load(self.spec) loaded.available = False - reloaded = self.bootstrap._SpecMethods(self.spec).exec(loaded) + reloaded = self.bootstrap._exec(self.spec, loaded) self.assertFalse(loaded.available) self.assertIs(reloaded, loaded) @@ -509,12 +365,12 @@ def test_reload_extra_attributes(self): def test_reload_init_module_attrs(self): self.spec.loader = NewLoader() with CleanImport(self.spec.name): - loaded = self.bootstrap._SpecMethods(self.spec).load() + loaded = self.bootstrap._load(self.spec) loaded.__name__ = 'ham' del loaded.__loader__ del loaded.__package__ del loaded.__spec__ - self.bootstrap._SpecMethods(self.spec).exec(loaded) + self.bootstrap._exec(self.spec, loaded) self.assertEqual(loaded.__name__, self.spec.name) self.assertIs(loaded.__loader__, self.spec.loader) @@ -527,8 +383,8 @@ def test_reload_init_module_attrs(self): def test_reload_legacy(self): self.spec.loader = LegacyLoader() with CleanImport(self.spec.name): - loaded = self.bootstrap._SpecMethods(self.spec).load() - reloaded = self.bootstrap._SpecMethods(self.spec).exec(loaded) + loaded = self.bootstrap._load(self.spec) + reloaded = self.bootstrap._exec(self.spec, loaded) installed = sys.modules[self.spec.name] self.assertEqual(loaded.ham, -1) @@ -536,22 +392,17 @@ def test_reload_legacy(self): self.assertIs(installed, loaded) -class Frozen_ModuleSpecMethodsTests(ModuleSpecMethodsTests, unittest.TestCase): - bootstrap = frozen_bootstrap - machinery = frozen_machinery - util = frozen_util - - -class Source_ModuleSpecMethodsTests(ModuleSpecMethodsTests, unittest.TestCase): - bootstrap = source_bootstrap - machinery = source_machinery - util = source_util +(Frozen_ModuleSpecMethodsTests, + Source_ModuleSpecMethodsTests + ) = test_util.test_both(ModuleSpecMethodsTests, init=init, util=util, + machinery=machinery) class ModuleReprTests: - # XXX Add more tests for repr(module) once ModuleSpec._module_repr() - # is in place? + @property + def bootstrap(self): + return self.init._bootstrap def setUp(self): self.module = type(os)('spam') @@ -636,16 +487,10 @@ def test_module_no_file_no_loader(self): self.assertEqual(modrepr, ''.format('spam')) -class Frozen_ModuleReprTests(ModuleReprTests, unittest.TestCase): - bootstrap = frozen_bootstrap - machinery = frozen_machinery - util = frozen_util - - -class Source_ModuleReprTests(ModuleReprTests, unittest.TestCase): - bootstrap = source_bootstrap - machinery = source_machinery - util = source_util +(Frozen_ModuleReprTests, + Source_ModuleReprTests + ) = test_util.test_both(ModuleReprTests, init=init, util=util, + machinery=machinery) class FactoryTests: @@ -798,13 +643,14 @@ def test_spec_from_loader_is_package_true_with_fileloader(self): # spec_from_file_location() def test_spec_from_file_location_default(self): - if self.machinery is source_machinery: - raise unittest.SkipTest('not sure why this is breaking...') spec = self.util.spec_from_file_location(self.name, self.path) self.assertEqual(spec.name, self.name) + # Need to use a circuitous route to get at importlib.machinery to make + # sure the same class object is used in the isinstance() check as + # would have been used to create the loader. self.assertIsInstance(spec.loader, - self.machinery.SourceFileLoader) + self.util.abc.machinery.SourceFileLoader) self.assertEqual(spec.loader.name, self.name) self.assertEqual(spec.loader.path, self.path) self.assertEqual(spec.origin, self.path) @@ -958,11 +804,10 @@ def is_package(self, name): self.assertTrue(spec.has_location) -class Frozen_FactoryTests(FactoryTests, unittest.TestCase): - util = frozen_util - machinery = frozen_machinery +(Frozen_FactoryTests, + Source_FactoryTests + ) = test_util.test_both(FactoryTests, util=util, machinery=machinery) -class Source_FactoryTests(FactoryTests, unittest.TestCase): - util = source_util - machinery = source_machinery +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_importlib/test_util.py b/Lib/test/test_importlib/test_util.py index 604e44d1b350..2493af7dea3f 100644 --- a/Lib/test/test_importlib/test_util.py +++ b/Lib/test/test_importlib/test_util.py @@ -1,6 +1,8 @@ -from importlib import util -from . import util as test_util -frozen_util, source_util = test_util.import_importlib('importlib.util') +from . import util +abc = util.import_importlib('importlib.abc') +init = util.import_importlib('importlib') +machinery = util.import_importlib('importlib.machinery') +importlib_util = util.import_importlib('importlib.util') import os import sys @@ -30,8 +32,94 @@ def test_universal_newlines(self): self.assertEqual(self.util.decode_source(source_bytes), '\n'.join([self.source, self.source])) -Frozen_DecodeSourceBytesTests, Source_DecodeSourceBytesTests = test_util.test_both( - DecodeSourceBytesTests, util=[frozen_util, source_util]) + +(Frozen_DecodeSourceBytesTests, + Source_DecodeSourceBytesTests + ) = util.test_both(DecodeSourceBytesTests, util=importlib_util) + + +class ModuleFromSpecTests: + + def test_no_create_module(self): + class Loader: + def exec_module(self, module): + pass + spec = self.machinery.ModuleSpec('test', Loader()) + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always') + module = self.util.module_from_spec(spec) + self.assertEqual(1, len(w)) + self.assertTrue(issubclass(w[0].category, DeprecationWarning)) + self.assertIn('create_module', str(w[0].message)) + self.assertIsInstance(module, types.ModuleType) + self.assertEqual(module.__name__, spec.name) + + def test_create_module_returns_None(self): + class Loader(self.abc.Loader): + def create_module(self, spec): + return None + spec = self.machinery.ModuleSpec('test', Loader()) + module = self.util.module_from_spec(spec) + self.assertIsInstance(module, types.ModuleType) + self.assertEqual(module.__name__, spec.name) + + def test_create_module(self): + name = 'already set' + class CustomModule(types.ModuleType): + pass + class Loader(self.abc.Loader): + def create_module(self, spec): + module = CustomModule(spec.name) + module.__name__ = name + return module + spec = self.machinery.ModuleSpec('test', Loader()) + module = self.util.module_from_spec(spec) + self.assertIsInstance(module, CustomModule) + self.assertEqual(module.__name__, name) + + def test___name__(self): + spec = self.machinery.ModuleSpec('test', object()) + module = self.util.module_from_spec(spec) + self.assertEqual(module.__name__, spec.name) + + def test___spec__(self): + spec = self.machinery.ModuleSpec('test', object()) + module = self.util.module_from_spec(spec) + self.assertEqual(module.__spec__, spec) + + def test___loader__(self): + loader = object() + spec = self.machinery.ModuleSpec('test', loader) + module = self.util.module_from_spec(spec) + self.assertIs(module.__loader__, loader) + + def test___package__(self): + spec = self.machinery.ModuleSpec('test.pkg', object()) + module = self.util.module_from_spec(spec) + self.assertEqual(module.__package__, spec.parent) + + def test___path__(self): + spec = self.machinery.ModuleSpec('test', object(), is_package=True) + module = self.util.module_from_spec(spec) + self.assertEqual(module.__path__, spec.submodule_search_locations) + + def test___file__(self): + spec = self.machinery.ModuleSpec('test', object(), origin='some/path') + spec.has_location = True + module = self.util.module_from_spec(spec) + self.assertEqual(module.__file__, spec.origin) + + def test___cached__(self): + spec = self.machinery.ModuleSpec('test', object()) + spec.cached = 'some/path' + spec.has_location = True + module = self.util.module_from_spec(spec) + self.assertEqual(module.__cached__, spec.cached) + +(Frozen_ModuleFromSpecTests, + Source_ModuleFromSpecTests +) = util.test_both(ModuleFromSpecTests, abc=abc, machinery=machinery, + util=importlib_util) class ModuleForLoaderTests: @@ -41,14 +129,14 @@ class ModuleForLoaderTests: @classmethod def module_for_loader(cls, func): with warnings.catch_warnings(): - warnings.simplefilter('ignore', PendingDeprecationWarning) + warnings.simplefilter('ignore', DeprecationWarning) return cls.util.module_for_loader(func) def test_warning(self): # Should raise a PendingDeprecationWarning when used. with warnings.catch_warnings(): - warnings.simplefilter('error', PendingDeprecationWarning) - with self.assertRaises(PendingDeprecationWarning): + warnings.simplefilter('error', DeprecationWarning) + with self.assertRaises(DeprecationWarning): func = self.util.module_for_loader(lambda x: x) def return_module(self, name): @@ -68,7 +156,7 @@ def test_new_module(self): # Test that when no module exists in sys.modules a new module is # created. module_name = 'a.b.c' - with test_util.uncache(module_name): + with util.uncache(module_name): module = self.return_module(module_name) self.assertIn(module_name, sys.modules) self.assertIsInstance(module, types.ModuleType) @@ -86,7 +174,7 @@ def load_module(self, module): module = types.ModuleType('a.b.c') module.__loader__ = 42 module.__package__ = 42 - with test_util.uncache(name): + with util.uncache(name): sys.modules[name] = module loader = FakeLoader() returned_module = loader.load_module(name) @@ -98,7 +186,7 @@ def test_new_module_failure(self): # Test that a module is removed from sys.modules if added but an # exception is raised. name = 'a.b.c' - with test_util.uncache(name): + with util.uncache(name): self.raise_exception(name) self.assertNotIn(name, sys.modules) @@ -106,7 +194,7 @@ def test_reload_failure(self): # Test that a failure on reload leaves the module in-place. name = 'a.b.c' module = types.ModuleType(name) - with test_util.uncache(name): + with util.uncache(name): sys.modules[name] = module self.raise_exception(name) self.assertIs(module, sys.modules[name]) @@ -125,7 +213,7 @@ def __bool__(self): return False name = 'mod' module = FalseModule(name) - with test_util.uncache(name): + with util.uncache(name): self.assertFalse(module) sys.modules[name] = module given = self.return_module(name) @@ -144,7 +232,7 @@ def load_module(self, module): return module name = 'pkg.mod' - with test_util.uncache(name): + with util.uncache(name): loader = FakeLoader(False) module = loader.load_module(name) self.assertEqual(module.__name__, name) @@ -152,15 +240,17 @@ def load_module(self, module): self.assertEqual(module.__package__, 'pkg') name = 'pkg.sub' - with test_util.uncache(name): + with util.uncache(name): loader = FakeLoader(True) module = loader.load_module(name) self.assertEqual(module.__name__, name) self.assertIs(module.__loader__, loader) self.assertEqual(module.__package__, name) -Frozen_ModuleForLoaderTests, Source_ModuleForLoaderTests = test_util.test_both( - ModuleForLoaderTests, util=[frozen_util, source_util]) + +(Frozen_ModuleForLoaderTests, + Source_ModuleForLoaderTests + ) = util.test_both(ModuleForLoaderTests, util=importlib_util) class SetPackageTests: @@ -172,7 +262,9 @@ def verify(self, module, expect): passing through set_package.""" fxn = lambda: module wrapped = self.util.set_package(fxn) - wrapped() + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + wrapped() self.assertTrue(hasattr(module, '__package__')) self.assertEqual(expect, module.__package__) @@ -212,22 +304,31 @@ def test_leaving_alone(self): def test_decorator_attrs(self): def fxn(module): pass - wrapped = self.util.set_package(fxn) + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + wrapped = self.util.set_package(fxn) self.assertEqual(wrapped.__name__, fxn.__name__) self.assertEqual(wrapped.__qualname__, fxn.__qualname__) -Frozen_SetPackageTests, Source_SetPackageTests = test_util.test_both( - SetPackageTests, util=[frozen_util, source_util]) + +(Frozen_SetPackageTests, + Source_SetPackageTests + ) = util.test_both(SetPackageTests, util=importlib_util) class SetLoaderTests: """Tests importlib.util.set_loader().""" - class DummyLoader: - @util.set_loader - def load_module(self, module): - return self.module + @property + def DummyLoader(self): + # Set DummyLoader on the class lazily. + class DummyLoader: + @self.util.set_loader + def load_module(self, module): + return self.module + self.__class__.DummyLoader = DummyLoader + return DummyLoader def test_no_attribute(self): loader = self.DummyLoader() @@ -236,31 +337,30 @@ def test_no_attribute(self): del loader.module.__loader__ except AttributeError: pass - self.assertEqual(loader, loader.load_module('blah').__loader__) + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + self.assertEqual(loader, loader.load_module('blah').__loader__) def test_attribute_is_None(self): loader = self.DummyLoader() loader.module = types.ModuleType('blah') loader.module.__loader__ = None - self.assertEqual(loader, loader.load_module('blah').__loader__) + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + self.assertEqual(loader, loader.load_module('blah').__loader__) def test_not_reset(self): loader = self.DummyLoader() loader.module = types.ModuleType('blah') loader.module.__loader__ = 42 - self.assertEqual(42, loader.load_module('blah').__loader__) + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + self.assertEqual(42, loader.load_module('blah').__loader__) -class Frozen_SetLoaderTests(SetLoaderTests, unittest.TestCase): - class DummyLoader: - @frozen_util.set_loader - def load_module(self, module): - return self.module -class Source_SetLoaderTests(SetLoaderTests, unittest.TestCase): - class DummyLoader: - @source_util.set_loader - def load_module(self, module): - return self.module +(Frozen_SetLoaderTests, + Source_SetLoaderTests + ) = util.test_both(SetLoaderTests, util=importlib_util) class ResolveNameTests: @@ -295,9 +395,150 @@ def test_escape(self): with self.assertRaises(ValueError): self.util.resolve_name('..bacon', 'spam') -Frozen_ResolveNameTests, Source_ResolveNameTests = test_util.test_both( - ResolveNameTests, - util=[frozen_util, source_util]) + +(Frozen_ResolveNameTests, + Source_ResolveNameTests + ) = util.test_both(ResolveNameTests, util=importlib_util) + + +class FindSpecTests: + + class FakeMetaFinder: + @staticmethod + def find_spec(name, path=None, target=None): return name, path, target + + def test_sys_modules(self): + name = 'some_mod' + with util.uncache(name): + module = types.ModuleType(name) + loader = 'a loader!' + spec = self.machinery.ModuleSpec(name, loader) + module.__loader__ = loader + module.__spec__ = spec + sys.modules[name] = module + found = self.util.find_spec(name) + self.assertEqual(found, spec) + + def test_sys_modules_without___loader__(self): + name = 'some_mod' + with util.uncache(name): + module = types.ModuleType(name) + del module.__loader__ + loader = 'a loader!' + spec = self.machinery.ModuleSpec(name, loader) + module.__spec__ = spec + sys.modules[name] = module + found = self.util.find_spec(name) + self.assertEqual(found, spec) + + def test_sys_modules_spec_is_None(self): + name = 'some_mod' + with util.uncache(name): + module = types.ModuleType(name) + module.__spec__ = None + sys.modules[name] = module + with self.assertRaises(ValueError): + self.util.find_spec(name) + + def test_sys_modules_loader_is_None(self): + name = 'some_mod' + with util.uncache(name): + module = types.ModuleType(name) + spec = self.machinery.ModuleSpec(name, None) + module.__spec__ = spec + sys.modules[name] = module + found = self.util.find_spec(name) + self.assertEqual(found, spec) + + def test_sys_modules_spec_is_not_set(self): + name = 'some_mod' + with util.uncache(name): + module = types.ModuleType(name) + try: + del module.__spec__ + except AttributeError: + pass + sys.modules[name] = module + with self.assertRaises(ValueError): + self.util.find_spec(name) + + def test_success(self): + name = 'some_mod' + with util.uncache(name): + with util.import_state(meta_path=[self.FakeMetaFinder]): + self.assertEqual((name, None, None), + self.util.find_spec(name)) + +# def test_success_path(self): +# # Searching on a path should work. +# name = 'some_mod' +# path = 'path to some place' +# with util.uncache(name): +# with util.import_state(meta_path=[self.FakeMetaFinder]): +# self.assertEqual((name, path, None), +# self.util.find_spec(name, path)) + + def test_nothing(self): + # None is returned upon failure to find a loader. + self.assertIsNone(self.util.find_spec('nevergoingtofindthismodule')) + + def test_find_submodule(self): + name = 'spam' + subname = 'ham' + with util.temp_module(name, pkg=True) as pkg_dir: + fullname, _ = util.submodule(name, subname, pkg_dir) + spec = self.util.find_spec(fullname) + self.assertIsNot(spec, None) + self.assertIn(name, sorted(sys.modules)) + self.assertNotIn(fullname, sorted(sys.modules)) + # Ensure successive calls behave the same. + spec_again = self.util.find_spec(fullname) + self.assertEqual(spec_again, spec) + + def test_find_submodule_parent_already_imported(self): + name = 'spam' + subname = 'ham' + with util.temp_module(name, pkg=True) as pkg_dir: + self.init.import_module(name) + fullname, _ = util.submodule(name, subname, pkg_dir) + spec = self.util.find_spec(fullname) + self.assertIsNot(spec, None) + self.assertIn(name, sorted(sys.modules)) + self.assertNotIn(fullname, sorted(sys.modules)) + # Ensure successive calls behave the same. + spec_again = self.util.find_spec(fullname) + self.assertEqual(spec_again, spec) + + def test_find_relative_module(self): + name = 'spam' + subname = 'ham' + with util.temp_module(name, pkg=True) as pkg_dir: + fullname, _ = util.submodule(name, subname, pkg_dir) + relname = '.' + subname + spec = self.util.find_spec(relname, name) + self.assertIsNot(spec, None) + self.assertIn(name, sorted(sys.modules)) + self.assertNotIn(fullname, sorted(sys.modules)) + # Ensure successive calls behave the same. + spec_again = self.util.find_spec(fullname) + self.assertEqual(spec_again, spec) + + def test_find_relative_module_missing_package(self): + name = 'spam' + subname = 'ham' + with util.temp_module(name, pkg=True) as pkg_dir: + fullname, _ = util.submodule(name, subname, pkg_dir) + relname = '.' + subname + with self.assertRaises(ValueError): + self.util.find_spec(relname) + self.assertNotIn(name, sorted(sys.modules)) + self.assertNotIn(fullname, sorted(sys.modules)) + + +(Frozen_FindSpecTests, + Source_FindSpecTests + ) = util.test_both(FindSpecTests, init=init, util=importlib_util, + machinery=machinery) class MagicNumberTests: @@ -310,8 +551,10 @@ def test_incorporates_rn(self): # The magic number uses \r\n to come out wrong when splitting on lines. self.assertTrue(self.util.MAGIC_NUMBER.endswith(b'\r\n')) -Frozen_MagicNumberTests, Source_MagicNumberTests = test_util.test_both( - MagicNumberTests, util=[frozen_util, source_util]) + +(Frozen_MagicNumberTests, + Source_MagicNumberTests + ) = util.test_both(MagicNumberTests, util=importlib_util) class PEP3147Tests: @@ -426,9 +669,10 @@ def test_source_from_cache_no__pycache__(self): ValueError, self.util.source_from_cache, '/foo/bar/foo.cpython-32.foo.pyc') -Frozen_PEP3147Tests, Source_PEP3147Tests = test_util.test_both( - PEP3147Tests, - util=[frozen_util, source_util]) + +(Frozen_PEP3147Tests, + Source_PEP3147Tests + ) = util.test_both(PEP3147Tests, util=importlib_util) if __name__ == '__main__': diff --git a/Lib/test/test_importlib/test_windows.py b/Lib/test/test_importlib/test_windows.py new file mode 100644 index 000000000000..c893bcf565eb --- /dev/null +++ b/Lib/test/test_importlib/test_windows.py @@ -0,0 +1,109 @@ +from . import util as test_util +machinery = test_util.import_importlib('importlib.machinery') + +import os +import re +import sys +import unittest +from test import support +from distutils.util import get_platform +from contextlib import contextmanager +from .util import temp_module + +support.import_module('winreg', required_on=['win']) +from winreg import ( + CreateKey, HKEY_CURRENT_USER, + SetValue, REG_SZ, KEY_ALL_ACCESS, + EnumKey, CloseKey, DeleteKey, OpenKey +) + +def delete_registry_tree(root, subkey): + try: + hkey = OpenKey(root, subkey, access=KEY_ALL_ACCESS) + except OSError: + # subkey does not exist + return + while True: + try: + subsubkey = EnumKey(hkey, 0) + except OSError: + # no more subkeys + break + delete_registry_tree(hkey, subsubkey) + CloseKey(hkey) + DeleteKey(root, subkey) + +@contextmanager +def setup_module(machinery, name, path=None): + if machinery.WindowsRegistryFinder.DEBUG_BUILD: + root = machinery.WindowsRegistryFinder.REGISTRY_KEY_DEBUG + else: + root = machinery.WindowsRegistryFinder.REGISTRY_KEY + key = root.format(fullname=name, + sys_version=sys.version[:3]) + try: + with temp_module(name, "a = 1") as location: + subkey = CreateKey(HKEY_CURRENT_USER, key) + if path is None: + path = location + ".py" + SetValue(subkey, "", REG_SZ, path) + yield + finally: + if machinery.WindowsRegistryFinder.DEBUG_BUILD: + key = os.path.dirname(key) + delete_registry_tree(HKEY_CURRENT_USER, key) + + +@unittest.skipUnless(sys.platform.startswith('win'), 'requires Windows') +class WindowsRegistryFinderTests: + # The module name is process-specific, allowing for + # simultaneous runs of the same test on a single machine. + test_module = "spamham{}".format(os.getpid()) + + def test_find_spec_missing(self): + spec = self.machinery.WindowsRegistryFinder.find_spec('spam') + self.assertIs(spec, None) + + def test_find_module_missing(self): + loader = self.machinery.WindowsRegistryFinder.find_module('spam') + self.assertIs(loader, None) + + def test_module_found(self): + with setup_module(self.machinery, self.test_module): + loader = self.machinery.WindowsRegistryFinder.find_module(self.test_module) + spec = self.machinery.WindowsRegistryFinder.find_spec(self.test_module) + self.assertIsNot(loader, None) + self.assertIsNot(spec, None) + + def test_module_not_found(self): + with setup_module(self.machinery, self.test_module, path="."): + loader = self.machinery.WindowsRegistryFinder.find_module(self.test_module) + spec = self.machinery.WindowsRegistryFinder.find_spec(self.test_module) + self.assertIsNone(loader) + self.assertIsNone(spec) + +(Frozen_WindowsRegistryFinderTests, + Source_WindowsRegistryFinderTests + ) = test_util.test_both(WindowsRegistryFinderTests, machinery=machinery) + +@unittest.skipUnless(sys.platform.startswith('win'), 'requires Windows') +class WindowsExtensionSuffixTests: + def test_tagged_suffix(self): + suffixes = self.machinery.EXTENSION_SUFFIXES + expected_tag = ".cp{0.major}{0.minor}-{1}.pyd".format(sys.version_info, + re.sub('[^a-zA-Z0-9]', '_', get_platform())) + try: + untagged_i = suffixes.index(".pyd") + except ValueError: + untagged_i = suffixes.index("_d.pyd") + expected_tag = "_d" + expected_tag + + self.assertIn(expected_tag, suffixes) + + # Ensure the tags are in the correct order + tagged_i = suffixes.index(expected_tag) + self.assertLess(tagged_i, untagged_i) + +(Frozen_WindowsExtensionSuffixTests, + Source_WindowsExtensionSuffixTests + ) = test_util.test_both(WindowsExtensionSuffixTests, machinery=machinery) diff --git a/Lib/test/test_importlib/util.py b/Lib/test/test_importlib/util.py index 80d43b5baaaf..aa4cd7e86124 100644 --- a/Lib/test/test_importlib/util.py +++ b/Lib/test/test_importlib/util.py @@ -1,30 +1,85 @@ -from contextlib import contextmanager +import builtins +import contextlib +import errno +import functools +import importlib +from importlib import machinery, util, invalidate_caches +import os import os.path from test import support import unittest import sys +import tempfile import types +BUILTINS = types.SimpleNamespace() +BUILTINS.good_name = None +BUILTINS.bad_name = None +if 'errno' in sys.builtin_module_names: + BUILTINS.good_name = 'errno' +if 'importlib' not in sys.builtin_module_names: + BUILTINS.bad_name = 'importlib' + +EXTENSIONS = types.SimpleNamespace() +EXTENSIONS.path = None +EXTENSIONS.ext = None +EXTENSIONS.filename = None +EXTENSIONS.file_path = None +EXTENSIONS.name = '_testcapi' + +def _extension_details(): + global EXTENSIONS + for path in sys.path: + for ext in machinery.EXTENSION_SUFFIXES: + filename = EXTENSIONS.name + ext + file_path = os.path.join(path, filename) + if os.path.exists(file_path): + EXTENSIONS.path = path + EXTENSIONS.ext = ext + EXTENSIONS.filename = filename + EXTENSIONS.file_path = file_path + return + +_extension_details() + + def import_importlib(module_name): """Import a module from importlib both w/ and w/o _frozen_importlib.""" fresh = ('importlib',) if '.' in module_name else () frozen = support.import_fresh_module(module_name) source = support.import_fresh_module(module_name, fresh=fresh, blocked=('_frozen_importlib',)) + return {'Frozen': frozen, 'Source': source} + + +def specialize_class(cls, kind, base=None, **kwargs): + # XXX Support passing in submodule names--load (and cache) them? + # That would clean up the test modules a bit more. + if base is None: + base = unittest.TestCase + elif not isinstance(base, type): + base = base[kind] + name = '{}_{}'.format(kind, cls.__name__) + bases = (cls, base) + specialized = types.new_class(name, bases) + specialized.__module__ = cls.__module__ + specialized._NAME = cls.__name__ + specialized._KIND = kind + for attr, values in kwargs.items(): + value = values[kind] + setattr(specialized, attr, value) + return specialized + + +def split_frozen(cls, base=None, **kwargs): + frozen = specialize_class(cls, 'Frozen', base, **kwargs) + source = specialize_class(cls, 'Source', base, **kwargs) return frozen, source -def test_both(test_class, **kwargs): - frozen_tests = types.new_class('Frozen_'+test_class.__name__, - (test_class, unittest.TestCase)) - source_tests = types.new_class('Source_'+test_class.__name__, - (test_class, unittest.TestCase)) - frozen_tests.__module__ = source_tests.__module__ = test_class.__module__ - for attr, (frozen_value, source_value) in kwargs.items(): - setattr(frozen_tests, attr, frozen_value) - setattr(source_tests, attr, source_value) - return frozen_tests, source_tests +def test_both(test_class, base=None, **kwargs): + return split_frozen(test_class, base, **kwargs) CASE_INSENSITIVE_FS = True @@ -37,6 +92,10 @@ def test_both(test_class, **kwargs): if not os.path.exists(changed_name): CASE_INSENSITIVE_FS = False +source_importlib = import_importlib('importlib')['Source'] +__import__ = {'Frozen': staticmethod(builtins.__import__), + 'Source': staticmethod(source_importlib.__import__)} + def case_insensitive_tests(test): """Class decorator that nullifies tests requiring a case-insensitive @@ -45,7 +104,14 @@ def case_insensitive_tests(test): "requires a case-insensitive filesystem")(test) -@contextmanager +def submodule(parent, name, pkg_dir, content=''): + path = os.path.join(pkg_dir, name + '.py') + with open(path, 'w') as subfile: + subfile.write(content) + return '{}.{}'.format(parent, name), path + + +@contextlib.contextmanager def uncache(*names): """Uncache a module from sys.modules. @@ -70,7 +136,32 @@ def uncache(*names): except KeyError: pass -@contextmanager + +@contextlib.contextmanager +def temp_module(name, content='', *, pkg=False): + conflicts = [n for n in sys.modules if n.partition('.')[0] == name] + with support.temp_cwd(None) as cwd: + with uncache(name, *conflicts): + with support.DirsOnSysPath(cwd): + invalidate_caches() + + location = os.path.join(cwd, name) + if pkg: + modpath = os.path.join(location, '__init__.py') + os.mkdir(name) + else: + modpath = location + '.py' + if content is None: + # Make sure the module file gets created. + content = '' + if content is not None: + # not a namespace package + with open(modpath, 'w') as modfile: + modfile.write(content) + yield location + + +@contextlib.contextmanager def import_state(**kwargs): """Context manager to manage the various importers and stored state in the sys module. @@ -101,9 +192,9 @@ def import_state(**kwargs): setattr(sys, attr, value) -class mock_modules: +class _ImporterMock: - """A mock importer/loader.""" + """Base class to help with creating importer mocks.""" def __init__(self, *names, module_code={}): self.modules = {} @@ -133,6 +224,19 @@ def __init__(self, *names, module_code={}): def __getitem__(self, name): return self.modules[name] + def __enter__(self): + self._uncache = uncache(*self.modules.keys()) + self._uncache.__enter__() + return self + + def __exit__(self, *exc_info): + self._uncache.__exit__(None, None, None) + + +class mock_modules(_ImporterMock): + + """Importer mock using PEP 302 APIs.""" + def find_module(self, fullname, path=None): if fullname not in self.modules: return None @@ -152,10 +256,125 @@ def load_module(self, fullname): raise return self.modules[fullname] - def __enter__(self): - self._uncache = uncache(*self.modules.keys()) - self._uncache.__enter__() - return self - def __exit__(self, *exc_info): - self._uncache.__exit__(None, None, None) +class mock_spec(_ImporterMock): + + """Importer mock using PEP 451 APIs.""" + + def find_spec(self, fullname, path=None, parent=None): + try: + module = self.modules[fullname] + except KeyError: + return None + is_package = hasattr(module, '__path__') + spec = util.spec_from_file_location( + fullname, module.__file__, loader=self, + submodule_search_locations=getattr(module, '__path__', None)) + return spec + + def create_module(self, spec): + if spec.name not in self.modules: + raise ImportError + return self.modules[spec.name] + + def exec_module(self, module): + try: + self.module_code[module.__spec__.name]() + except KeyError: + pass + + +def writes_bytecode_files(fxn): + """Decorator to protect sys.dont_write_bytecode from mutation and to skip + tests that require it to be set to False.""" + if sys.dont_write_bytecode: + return lambda *args, **kwargs: None + @functools.wraps(fxn) + def wrapper(*args, **kwargs): + original = sys.dont_write_bytecode + sys.dont_write_bytecode = False + try: + to_return = fxn(*args, **kwargs) + finally: + sys.dont_write_bytecode = original + return to_return + return wrapper + + +def ensure_bytecode_path(bytecode_path): + """Ensure that the __pycache__ directory for PEP 3147 pyc file exists. + + :param bytecode_path: File system path to PEP 3147 pyc file. + """ + try: + os.mkdir(os.path.dirname(bytecode_path)) + except OSError as error: + if error.errno != errno.EEXIST: + raise + + +@contextlib.contextmanager +def create_modules(*names): + """Temporarily create each named module with an attribute (named 'attr') + that contains the name passed into the context manager that caused the + creation of the module. + + All files are created in a temporary directory returned by + tempfile.mkdtemp(). This directory is inserted at the beginning of + sys.path. When the context manager exits all created files (source and + bytecode) are explicitly deleted. + + No magic is performed when creating packages! This means that if you create + a module within a package you must also create the package's __init__ as + well. + + """ + source = 'attr = {0!r}' + created_paths = [] + mapping = {} + state_manager = None + uncache_manager = None + try: + temp_dir = tempfile.mkdtemp() + mapping['.root'] = temp_dir + import_names = set() + for name in names: + if not name.endswith('__init__'): + import_name = name + else: + import_name = name[:-len('.__init__')] + import_names.add(import_name) + if import_name in sys.modules: + del sys.modules[import_name] + name_parts = name.split('.') + file_path = temp_dir + for directory in name_parts[:-1]: + file_path = os.path.join(file_path, directory) + if not os.path.exists(file_path): + os.mkdir(file_path) + created_paths.append(file_path) + file_path = os.path.join(file_path, name_parts[-1] + '.py') + with open(file_path, 'w') as file: + file.write(source.format(name)) + created_paths.append(file_path) + mapping[name] = file_path + uncache_manager = uncache(*import_names) + uncache_manager.__enter__() + state_manager = import_state(path=[temp_dir]) + state_manager.__enter__() + yield mapping + finally: + if state_manager is not None: + state_manager.__exit__(None, None, None) + if uncache_manager is not None: + uncache_manager.__exit__(None, None, None) + support.rmtree(temp_dir) + + +def mock_path_hook(*entries, importer): + """A mock sys.path_hooks entry.""" + def hook(entry): + if entry not in entries: + raise ImportError + return importer + return hook diff --git a/Lib/test/test_index.py b/Lib/test/test_index.py index 66eedaaed72a..a2ac32132e23 100644 --- a/Lib/test/test_index.py +++ b/Lib/test/test_index.py @@ -9,7 +9,7 @@ def __index__(self): class TrapInt(int): def __index__(self): - return self + return int(self) class BaseTestCase(unittest.TestCase): def setUp(self): @@ -55,6 +55,40 @@ def test_error(self): self.assertRaises(TypeError, slice(self.o).indices, 0) self.assertRaises(TypeError, slice(self.n).indices, 0) + def test_int_subclass_with_index(self): + # __index__ should be used when computing indices, even for int + # subclasses. See issue #17576. + class MyInt(int): + def __index__(self): + return int(self) + 1 + + my_int = MyInt(7) + direct_index = my_int.__index__() + operator_index = operator.index(my_int) + self.assertEqual(direct_index, 8) + self.assertEqual(operator_index, 7) + # Both results should be of exact type int. + self.assertIs(type(direct_index), int) + #self.assertIs(type(operator_index), int) + + def test_index_returns_int_subclass(self): + class BadInt: + def __index__(self): + return True + + class BadInt2(int): + def __index__(self): + return True + + bad_int = BadInt() + with self.assertWarns(DeprecationWarning): + n = operator.index(bad_int) + self.assertEqual(n, 1) + + bad_int = BadInt2() + n = operator.index(bad_int) + self.assertEqual(n, 0) + class SeqTestCase: # This test case isn't run directly. It just defines common tests diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py index 365f59230a48..bbc53856f1c1 100644 --- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect.py @@ -1,29 +1,37 @@ -import re -import sys -import types -import unittest -import inspect -import linecache -import datetime +import builtins import collections -import os -import shutil +import datetime import functools import importlib +import inspect +import io +import linecache +import os from os.path import normcase +import _pickle +import pickle +import re +import shutil +import sys +import types +import textwrap +import unicodedata +import unittest +import unittest.mock + try: from concurrent.futures import ThreadPoolExecutor except ImportError: ThreadPoolExecutor = None -from test.support import run_unittest, TESTFN, DirsOnSysPath -from test.support import MISSING_C_DOCSTRINGS +from test.support import run_unittest, TESTFN, DirsOnSysPath, cpython_only +from test.support import MISSING_C_DOCSTRINGS, cpython_only from test.script_helper import assert_python_ok, assert_python_failure from test import inspect_fodder as mod from test import inspect_fodder2 as mod2 -# C module for test_findsource_binary -import unicodedata +from test.test_import import _ready_to_import + # Functions tested in this suite: # ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode, @@ -70,6 +78,7 @@ def generator_function_example(self): for i in range(2): yield i + class TestPredicates(IsTestBase): def test_sixteen(self): count = len([x for x in dir(inspect) if x.startswith('is')]) @@ -176,6 +185,14 @@ def test_stack(self): (modfile, 43, 'argue', [' spam(a, b, c)\n'], 0)) self.assertEqual(revise(*mod.st[3][1:]), (modfile, 39, 'abuse', [' self.argue(a, b, c)\n'], 0)) + # Test named tuple fields + record = mod.st[0] + self.assertIs(record.frame, mod.fr) + self.assertEqual(record.lineno, 16) + self.assertEqual(record.filename, mod.__file__) + self.assertEqual(record.function, 'eggs') + self.assertIn('inspect.stack()', record.code_context[0]) + self.assertEqual(record.index, 0) def test_trace(self): self.assertEqual(len(git.tr), 3) @@ -316,6 +333,16 @@ def test_getsourcefile(self): def test_getfile(self): self.assertEqual(inspect.getfile(mod.StupidGit), mod.__file__) + def test_getfile_class_without_module(self): + class CM(type): + @property + def __module__(cls): + raise AttributeError + class C(metaclass=CM): + pass + with self.assertRaises(TypeError): + inspect.getfile(C) + def test_getmodule_recursion(self): from types import ModuleType name = '__inspect_dummy' @@ -353,6 +380,9 @@ def test_wrapped_decorator(self): def test_replacing_decorator(self): self.assertSourceEqual(mod2.gone, 9, 10) + def test_getsource_unwrap(self): + self.assertSourceEqual(mod2.real, 122, 124) + class TestOneliners(GetSourceBase): fodderModule = mod2 def test_oneline_lambda(self): @@ -419,10 +449,11 @@ def test_with_comment_instead_of_docstring(self): def test_method_in_dynamic_class(self): self.assertSourceEqual(mod2.method_in_dynamic_class, 95, 97) - @unittest.skipIf( - not hasattr(unicodedata, '__file__') or - unicodedata.__file__[-4:] in (".pyc", ".pyo"), - "unicodedata is not an external binary module") + # This should not skip for CPython, but might on a repackaged python where + # unicodedata is not an external module, or on pypy. + @unittest.skipIf(not hasattr(unicodedata, '__file__') or + unicodedata.__file__.endswith('.py'), + "unicodedata is not an external binary module") def test_findsource_binary(self): self.assertRaises(OSError, inspect.getsource, unicodedata) self.assertRaises(OSError, inspect.findsource, unicodedata) @@ -565,6 +596,96 @@ def test_getfullargspec(self): kwonlyargs_e=['arg'], formatted='(*, arg)') + def test_argspec_api_ignores_wrapped(self): + # Issue 20684: low level introspection API must ignore __wrapped__ + @functools.wraps(mod.spam) + def ham(x, y): + pass + # Basic check + self.assertArgSpecEquals(ham, ['x', 'y'], formatted='(x, y)') + self.assertFullArgSpecEquals(ham, ['x', 'y'], formatted='(x, y)') + self.assertFullArgSpecEquals(functools.partial(ham), + ['x', 'y'], formatted='(x, y)') + # Other variants + def check_method(f): + self.assertArgSpecEquals(f, ['self', 'x', 'y'], + formatted='(self, x, y)') + class C: + @functools.wraps(mod.spam) + def ham(self, x, y): + pass + pham = functools.partialmethod(ham) + @functools.wraps(mod.spam) + def __call__(self, x, y): + pass + check_method(C()) + check_method(C.ham) + check_method(C().ham) + check_method(C.pham) + check_method(C().pham) + + class C_new: + @functools.wraps(mod.spam) + def __new__(self, x, y): + pass + check_method(C_new) + + class C_init: + @functools.wraps(mod.spam) + def __init__(self, x, y): + pass + check_method(C_init) + + def test_getfullargspec_signature_attr(self): + def test(): + pass + spam_param = inspect.Parameter('spam', inspect.Parameter.POSITIONAL_ONLY) + test.__signature__ = inspect.Signature(parameters=(spam_param,)) + + self.assertFullArgSpecEquals(test, args_e=['spam'], formatted='(spam)') + + def test_getfullargspec_signature_annos(self): + def test(a:'spam') -> 'ham': pass + spec = inspect.getfullargspec(test) + self.assertEqual(test.__annotations__, spec.annotations) + + def test(): pass + spec = inspect.getfullargspec(test) + self.assertEqual(test.__annotations__, spec.annotations) + + @unittest.skipIf(MISSING_C_DOCSTRINGS, + "Signature information for builtins requires docstrings") + def test_getfullargspec_builtin_methods(self): + self.assertFullArgSpecEquals(_pickle.Pickler.dump, + args_e=['self', 'obj'], formatted='(self, obj)') + + self.assertFullArgSpecEquals(_pickle.Pickler(io.BytesIO()).dump, + args_e=['self', 'obj'], formatted='(self, obj)') + + self.assertFullArgSpecEquals( + os.stat, + args_e=['path'], + kwonlyargs_e=['dir_fd', 'follow_symlinks'], + kwonlydefaults_e={'dir_fd': None, 'follow_symlinks': True}, + formatted='(path, *, dir_fd=None, follow_symlinks=True)') + + @cpython_only + @unittest.skipIf(MISSING_C_DOCSTRINGS, + "Signature information for builtins requires docstrings") + def test_getfullagrspec_builtin_func(self): + import _testcapi + builtin = _testcapi.docstring_with_signature_with_defaults + spec = inspect.getfullargspec(builtin) + self.assertEqual(spec.defaults[0], 'avocado') + + @cpython_only + @unittest.skipIf(MISSING_C_DOCSTRINGS, + "Signature information for builtins requires docstrings") + def test_getfullagrspec_builtin_func_no_signature(self): + import _testcapi + builtin = _testcapi.docstring_no_signature + with self.assertRaises(TypeError): + inspect.getfullargspec(builtin) def test_getargspec_method(self): class A(object): @@ -594,6 +715,10 @@ def m1(self): pass md = _BrokenMethodDescriptor() attrs = attrs_wo_objs(A) + + self.assertIn(('__new__', 'method', object), attrs, 'missing __new__') + self.assertIn(('__init__', 'method', object), attrs, 'missing __init__') + self.assertIn(('s', 'static method', A), attrs, 'missing static method') self.assertIn(('c', 'class method', A), attrs, 'missing class method') self.assertIn(('p', 'property', A), attrs, 'missing property') @@ -1099,6 +1224,20 @@ def test_errors(self): self.assertEqualException(f3, '1, 2') self.assertEqualException(f3, '1, 2, a=1, b=2') + # issue #20816: getcallargs() fails to iterate over non-existent + # kwonlydefaults and raises a wrong TypeError + def f5(*, a): pass + with self.assertRaisesRegex(TypeError, + 'missing 1 required keyword-only'): + inspect.getcallargs(f5) + + + # issue20817: + def f6(a, b, c): + pass + with self.assertRaisesRegex(TypeError, "'a', 'b' and 'c'"): + inspect.getcallargs(f6) + class TestGetcallargsMethods(TestGetcallargsFunctions): def setUp(self): @@ -1490,6 +1629,68 @@ def test_getgeneratorlocals_error(self): self.assertRaises(TypeError, inspect.getgeneratorlocals, (2,3)) +class MySignature(inspect.Signature): + # Top-level to make it picklable; + # used in test_signature_object_pickle + pass + +class MyParameter(inspect.Parameter): + # Top-level to make it picklable; + # used in test_signature_object_pickle + pass + + @cpython_only + @unittest.skipIf(MISSING_C_DOCSTRINGS, + "Signature information for builtins requires docstrings") + def test_builtins_have_signatures(self): + # This checks all builtin callables in CPython have signatures + # A few have signatures Signature can't yet handle, so we skip those + # since they will have to wait until PEP 457 adds the required + # introspection support to the inspect module + # Some others also haven't been converted yet for various other + # reasons, so we also skip those for the time being, but design + # the test to fail in order to indicate when it needs to be + # updated. + no_signature = set() + # These need PEP 457 groups + needs_groups = ["range", "slice", "dir", "getattr", + "next", "iter", "vars"] + no_signature |= needs_groups + # These need PEP 457 groups or a signature change to accept None + needs_semantic_update = ["round"] + no_signature |= needs_semantic_update + # These need *args support in Argument Clinic + needs_varargs = ["min", "max", "print", "__build_class__"] + no_signature |= needs_varargs + # These simply weren't covered in the initial AC conversion + # for builtin callables + not_converted_yet = ["open", "__import__"] + no_signature |= not_converted_yet + # These builtin types are expected to provide introspection info + types_with_signatures = set() + # Check the signatures we expect to be there + ns = vars(builtins) + for name, obj in sorted(ns.items()): + if not callable(obj): + continue + # The builtin types haven't been converted to AC yet + if isinstance(obj, type) and (name not in types_with_signatures): + # Note that this also skips all the exception types + no_signature.append(name) + if (name in no_signature): + # Not yet converted + continue + with self.subTest(builtin=name): + self.assertIsNotNone(inspect.signature(obj)) + # Check callables that haven't been converted don't claim a signature + # This ensures this test will start failing as more signatures are + # added, so the affected items can be moved into the scope of the + # regression test above + for name in no_signature: + with self.subTest(builtin=name): + self.assertIsNone(ns[name].__text_signature__) + + class TestSignatureObject(unittest.TestCase): @staticmethod def signature(func): @@ -1509,11 +1710,13 @@ def test_signature_object(self): self.assertEqual(str(S()), '()') - def test(po, pk, *args, ko, **kwargs): + def test(po, pk, pod=42, pkd=100, *args, ko, **kwargs): pass sig = inspect.signature(test) po = sig.parameters['po'].replace(kind=P.POSITIONAL_ONLY) + pod = sig.parameters['pod'].replace(kind=P.POSITIONAL_ONLY) pk = sig.parameters['pk'] + pkd = sig.parameters['pkd'] args = sig.parameters['args'] ko = sig.parameters['ko'] kwargs = sig.parameters['kwargs'] @@ -1536,6 +1739,46 @@ def test(po, pk, *args, ko, **kwargs): with self.assertRaisesRegex(ValueError, 'duplicate parameter name'): S((po, pk, args, kwargs2, ko)) + with self.assertRaisesRegex(ValueError, 'follows default argument'): + S((pod, po)) + + with self.assertRaisesRegex(ValueError, 'follows default argument'): + S((po, pkd, pk)) + + with self.assertRaisesRegex(ValueError, 'follows default argument'): + S((pkd, pk)) + + self.assertTrue(repr(sig).startswith(' {42:'ham'}: pass + foo_partial = functools.partial(foo, a=1) + + sig = inspect.signature(foo_partial) + + for ver in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(pickle_ver=ver, subclass=False): + sig_pickled = pickle.loads(pickle.dumps(sig, ver)) + self.assertEqual(sig, sig_pickled) + + # Test that basic sub-classing works + sig = inspect.signature(foo) + myparam = MyParameter(name='z', kind=inspect.Parameter.POSITIONAL_ONLY) + myparams = collections.OrderedDict(sig.parameters, a=myparam) + mysig = MySignature().replace(parameters=myparams.values(), + return_annotation=sig.return_annotation) + self.assertTrue(isinstance(mysig, MySignature)) + self.assertTrue(isinstance(mysig.parameters['z'], MyParameter)) + + for ver in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(pickle_ver=ver, subclass=True): + sig_pickled = pickle.loads(pickle.dumps(mysig, ver)) + self.assertEqual(mysig, sig_pickled) + self.assertTrue(isinstance(sig_pickled, MySignature)) + self.assertTrue(isinstance(sig_pickled.parameters['z'], + MyParameter)) + def test_signature_immutability(self): def test(a): pass @@ -1580,22 +1823,100 @@ def test(a, b:'foo'=10, *args:'bar', spam:'baz', ham=123, **kwargs:int): ('kwargs', ..., int, "var_keyword")), ...)) - def test_signature_on_unsupported_builtins(self): - with self.assertRaisesRegex(ValueError, 'not supported by signature'): - inspect.signature(type) - with self.assertRaisesRegex(ValueError, 'not supported by signature'): - # support for 'wrapper_descriptor' - inspect.signature(type.__call__) - with self.assertRaisesRegex(ValueError, 'not supported by signature'): - # support for 'method-wrapper' - inspect.signature(min.__call__) - + @cpython_only @unittest.skipIf(MISSING_C_DOCSTRINGS, "Signature information for builtins requires docstrings") def test_signature_on_builtins(self): - self.assertEqual(inspect.signature(min), None) - signature = inspect.signature(os.stat) - self.assertTrue(isinstance(signature, inspect.Signature)) + import _testcapi + + def test_unbound_method(o): + """Use this to test unbound methods (things that should have a self)""" + signature = inspect.signature(o) + self.assertTrue(isinstance(signature, inspect.Signature)) + self.assertEqual(list(signature.parameters.values())[0].name, 'self') + return signature + + def test_callable(o): + """Use this to test bound methods or normal callables (things that don't expect self)""" + signature = inspect.signature(o) + self.assertTrue(isinstance(signature, inspect.Signature)) + if signature.parameters: + self.assertNotEqual(list(signature.parameters.values())[0].name, 'self') + return signature + + signature = test_callable(_testcapi.docstring_with_signature_with_defaults) + def p(name): return signature.parameters[name].default + self.assertEqual(p('s'), 'avocado') + self.assertEqual(p('b'), b'bytes') + self.assertEqual(p('d'), 3.14) + self.assertEqual(p('i'), 35) + self.assertEqual(p('n'), None) + self.assertEqual(p('t'), True) + self.assertEqual(p('f'), False) + self.assertEqual(p('local'), 3) + self.assertEqual(p('sys'), sys.maxsize) + self.assertEqual(p('exp'), sys.maxsize - 1) + + test_callable(object) + + # normal method + # (PyMethodDescr_Type, "method_descriptor") + test_unbound_method(_pickle.Pickler.dump) + d = _pickle.Pickler(io.StringIO()) + test_callable(d.dump) + + # static method + test_callable(str.maketrans) + test_callable('abc'.maketrans) + + # class method + test_callable(dict.fromkeys) + test_callable({}.fromkeys) + + # wrapper around slot (PyWrapperDescr_Type, "wrapper_descriptor") + test_unbound_method(type.__call__) + test_unbound_method(int.__add__) + test_callable((3).__add__) + + # _PyMethodWrapper_Type + # support for 'method-wrapper' + test_callable(min.__call__) + + # This doesn't work now. + # (We don't have a valid signature for "type" in 3.4) + with self.assertRaisesRegex(ValueError, "no signature found"): + class ThisWorksNow: + __call__ = type + test_callable(ThisWorksNow()) + + # Regression test for issue #20786 + test_unbound_method(dict.__delitem__) + test_unbound_method(property.__delete__) + + + @cpython_only + @unittest.skipIf(MISSING_C_DOCSTRINGS, + "Signature information for builtins requires docstrings") + def test_signature_on_decorated_builtins(self): + import _testcapi + func = _testcapi.docstring_with_signature_with_defaults + + def decorator(func): + @functools.wraps(func) + def wrapper(*args, **kwargs) -> int: + return func(*args, **kwargs) + return wrapper + + decorated_func = decorator(func) + + self.assertEqual(inspect.signature(func), + inspect.signature(decorated_func)) + + @cpython_only + def test_signature_on_builtins_no_signature(self): + import _testcapi + with self.assertRaisesRegex(ValueError, 'no signature found for builtin'): + inspect.signature(_testcapi.docstring_no_signature) def test_signature_on_non_function(self): with self.assertRaisesRegex(TypeError, 'is not a callable object'): @@ -1604,18 +1925,112 @@ def test_signature_on_non_function(self): with self.assertRaisesRegex(TypeError, 'is not a Python function'): inspect.Signature.from_function(42) + def test_signature_from_builtin_errors(self): + with self.assertRaisesRegex(TypeError, 'is not a Python builtin'): + inspect.Signature.from_builtin(42) + + def test_signature_from_functionlike_object(self): + def func(a,b, *args, kwonly=True, kwonlyreq, **kwargs): + pass + + class funclike: + # Has to be callable, and have correct + # __code__, __annotations__, __defaults__, __name__, + # and __kwdefaults__ attributes + + def __init__(self, func): + self.__name__ = func.__name__ + self.__code__ = func.__code__ + self.__annotations__ = func.__annotations__ + self.__defaults__ = func.__defaults__ + self.__kwdefaults__ = func.__kwdefaults__ + self.func = func + + def __call__(self, *args, **kwargs): + return self.func(*args, **kwargs) + + sig_func = inspect.Signature.from_function(func) + + sig_funclike = inspect.Signature.from_function(funclike(func)) + self.assertEqual(sig_funclike, sig_func) + + sig_funclike = inspect.signature(funclike(func)) + self.assertEqual(sig_funclike, sig_func) + + # If object is not a duck type of function, then + # signature will try to get a signature for its '__call__' + # method + fl = funclike(func) + del fl.__defaults__ + self.assertEqual(self.signature(fl), + ((('args', ..., ..., "var_positional"), + ('kwargs', ..., ..., "var_keyword")), + ...)) + + # Test with cython-like builtins: + _orig_isdesc = inspect.ismethoddescriptor + def _isdesc(obj): + if hasattr(obj, '_builtinmock'): + return True + return _orig_isdesc(obj) + + with unittest.mock.patch('inspect.ismethoddescriptor', _isdesc): + builtin_func = funclike(func) + # Make sure that our mock setup is working + self.assertFalse(inspect.ismethoddescriptor(builtin_func)) + builtin_func._builtinmock = True + self.assertTrue(inspect.ismethoddescriptor(builtin_func)) + self.assertEqual(inspect.signature(builtin_func), sig_func) + + def test_signature_functionlike_class(self): + # We only want to duck type function-like objects, + # not classes. + + def func(a,b, *args, kwonly=True, kwonlyreq, **kwargs): + pass + + class funclike: + def __init__(self, marker): + pass + + __name__ = func.__name__ + __code__ = func.__code__ + __annotations__ = func.__annotations__ + __defaults__ = func.__defaults__ + __kwdefaults__ = func.__kwdefaults__ + + with self.assertRaisesRegex(TypeError, 'is not a Python function'): + inspect.Signature.from_function(funclike) + + self.assertEqual(str(inspect.signature(funclike)), '(marker)') + def test_signature_on_method(self): class Test: - def foo(self, arg1, arg2=1) -> int: + def __init__(*args): + pass + def m1(self, arg1, arg2=1) -> int: + pass + def m2(*args): + pass + def __call__(*, a): pass - meth = Test().foo - - self.assertEqual(self.signature(meth), + self.assertEqual(self.signature(Test().m1), ((('arg1', ..., ..., "positional_or_keyword"), ('arg2', 1, ..., "positional_or_keyword")), int)) + self.assertEqual(self.signature(Test().m2), + ((('args', ..., ..., "var_positional"),), + ...)) + + self.assertEqual(self.signature(Test), + ((('args', ..., ..., "var_positional"),), + ...)) + + with self.assertRaisesRegex(ValueError, 'invalid method signature'): + self.signature(Test()) + def test_signature_on_classmethod(self): class Test: @classmethod @@ -1655,6 +2070,8 @@ def foo(cls, *, arg): def test_signature_on_partial(self): from functools import partial + Parameter = inspect.Parameter + def test(): pass @@ -1690,15 +2107,22 @@ def test(a, b, *, c, d): self.assertEqual(self.signature(partial(test, b=1, c=2)), ((('a', ..., ..., "positional_or_keyword"), - ('b', 1, ..., "positional_or_keyword"), + ('b', 1, ..., "keyword_only"), ('c', 2, ..., "keyword_only"), ('d', ..., ..., "keyword_only")), ...)) self.assertEqual(self.signature(partial(test, 0, b=1, c=2)), - ((('b', 1, ..., "positional_or_keyword"), + ((('b', 1, ..., "keyword_only"), ('c', 2, ..., "keyword_only"), - ('d', ..., ..., "keyword_only"),), + ('d', ..., ..., "keyword_only")), + ...)) + + self.assertEqual(self.signature(partial(test, a=1)), + ((('a', 1, ..., "keyword_only"), + ('b', ..., ..., "keyword_only"), + ('c', ..., ..., "keyword_only"), + ('d', ..., ..., "keyword_only")), ...)) def test(a, *args, b, **kwargs): @@ -1710,13 +2134,18 @@ def test(a, *args, b, **kwargs): ('kwargs', ..., ..., "var_keyword")), ...)) + self.assertEqual(self.signature(partial(test, a=1)), + ((('a', 1, ..., "keyword_only"), + ('b', ..., ..., "keyword_only"), + ('kwargs', ..., ..., "var_keyword")), + ...)) + self.assertEqual(self.signature(partial(test, 1, 2, 3)), ((('args', ..., ..., "var_positional"), ('b', ..., ..., "keyword_only"), ('kwargs', ..., ..., "var_keyword")), ...)) - self.assertEqual(self.signature(partial(test, 1, 2, 3, test=True)), ((('args', ..., ..., "var_positional"), ('b', ..., ..., "keyword_only"), @@ -1763,7 +2192,7 @@ def foo(a): return a _foo = partial(partial(foo, a=10), a=20) self.assertEqual(self.signature(_foo), - ((('a', 20, ..., "positional_or_keyword"),), + ((('a', 20, ..., "keyword_only"),), ...)) # check that we don't have any side-effects in signature(), # and the partial object is still functioning @@ -1772,42 +2201,119 @@ def foo(a): def foo(a, b, c): return a, b, c _foo = partial(partial(foo, 1, b=20), b=30) + self.assertEqual(self.signature(_foo), - ((('b', 30, ..., "positional_or_keyword"), - ('c', ..., ..., "positional_or_keyword")), + ((('b', 30, ..., "keyword_only"), + ('c', ..., ..., "keyword_only")), ...)) self.assertEqual(_foo(c=10), (1, 30, 10)) - _foo = partial(_foo, 2) # now 'b' has two values - - # positional and keyword - with self.assertRaisesRegex(ValueError, "has incorrect arguments"): - inspect.signature(_foo) def foo(a, b, c, *, d): return a, b, c, d _foo = partial(partial(foo, d=20, c=20), b=10, d=30) self.assertEqual(self.signature(_foo), ((('a', ..., ..., "positional_or_keyword"), - ('b', 10, ..., "positional_or_keyword"), - ('c', 20, ..., "positional_or_keyword"), - ('d', 30, ..., "keyword_only")), + ('b', 10, ..., "keyword_only"), + ('c', 20, ..., "keyword_only"), + ('d', 30, ..., "keyword_only"), + ), ...)) ba = inspect.signature(_foo).bind(a=200, b=11) self.assertEqual(_foo(*ba.args, **ba.kwargs), (200, 11, 20, 30)) def foo(a=1, b=2, c=3): return a, b, c - _foo = partial(foo, a=10, c=13) - ba = inspect.signature(_foo).bind(11) + _foo = partial(foo, c=13) # (a=1, b=2, *, c=13) + + ba = inspect.signature(_foo).bind(a=11) self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 2, 13)) + ba = inspect.signature(_foo).bind(11, 12) self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13)) + ba = inspect.signature(_foo).bind(11, b=12) self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13)) + ba = inspect.signature(_foo).bind(b=12) - self.assertEqual(_foo(*ba.args, **ba.kwargs), (10, 12, 13)) - _foo = partial(_foo, b=10) - ba = inspect.signature(_foo).bind(12, 14) - self.assertEqual(_foo(*ba.args, **ba.kwargs), (12, 14, 13)) + self.assertEqual(_foo(*ba.args, **ba.kwargs), (1, 12, 13)) + + _foo = partial(_foo, b=10, c=20) + ba = inspect.signature(_foo).bind(12) + self.assertEqual(_foo(*ba.args, **ba.kwargs), (12, 10, 20)) + + + def foo(a, b, c, d, **kwargs): + pass + sig = inspect.signature(foo) + params = sig.parameters.copy() + params['a'] = params['a'].replace(kind=Parameter.POSITIONAL_ONLY) + params['b'] = params['b'].replace(kind=Parameter.POSITIONAL_ONLY) + foo.__signature__ = inspect.Signature(params.values()) + sig = inspect.signature(foo) + self.assertEqual(str(sig), '(a, b, /, c, d, **kwargs)') + + self.assertEqual(self.signature(partial(foo, 1)), + ((('b', ..., ..., 'positional_only'), + ('c', ..., ..., 'positional_or_keyword'), + ('d', ..., ..., 'positional_or_keyword'), + ('kwargs', ..., ..., 'var_keyword')), + ...)) + + self.assertEqual(self.signature(partial(foo, 1, 2)), + ((('c', ..., ..., 'positional_or_keyword'), + ('d', ..., ..., 'positional_or_keyword'), + ('kwargs', ..., ..., 'var_keyword')), + ...)) + + self.assertEqual(self.signature(partial(foo, 1, 2, 3)), + ((('d', ..., ..., 'positional_or_keyword'), + ('kwargs', ..., ..., 'var_keyword')), + ...)) + + self.assertEqual(self.signature(partial(foo, 1, 2, c=3)), + ((('c', 3, ..., 'keyword_only'), + ('d', ..., ..., 'keyword_only'), + ('kwargs', ..., ..., 'var_keyword')), + ...)) + + self.assertEqual(self.signature(partial(foo, 1, c=3)), + ((('b', ..., ..., 'positional_only'), + ('c', 3, ..., 'keyword_only'), + ('d', ..., ..., 'keyword_only'), + ('kwargs', ..., ..., 'var_keyword')), + ...)) + + def test_signature_on_partialmethod(self): + from functools import partialmethod + + class Spam: + def test(): + pass + ham = partialmethod(test) + + with self.assertRaisesRegex(ValueError, "has incorrect arguments"): + inspect.signature(Spam.ham) + + class Spam: + def test(it, a, *, c) -> 'spam': + pass + ham = partialmethod(test, c=1) + + self.assertEqual(self.signature(Spam.ham), + ((('it', ..., ..., 'positional_or_keyword'), + ('a', ..., ..., 'positional_or_keyword'), + ('c', 1, ..., 'keyword_only')), + 'spam')) + + self.assertEqual(self.signature(Spam().ham), + ((('a', ..., ..., 'positional_or_keyword'), + ('c', 1, ..., 'keyword_only')), + 'spam')) + + def test_signature_on_fake_partialmethod(self): + def foo(a): pass + foo._partialmethod = 'spam' + self.assertEqual(str(inspect.signature(foo)), '(a)') def test_signature_on_decorated(self): import functools @@ -1950,6 +2456,49 @@ def __init__(self, b): ('bar', 2, ..., "keyword_only")), ...)) + @unittest.skipIf(MISSING_C_DOCSTRINGS, + "Signature information for builtins requires docstrings") + def test_signature_on_class_without_init(self): + # Test classes without user-defined __init__ or __new__ + class C: pass + self.assertEqual(str(inspect.signature(C)), '()') + class D(C): pass + self.assertEqual(str(inspect.signature(D)), '()') + + # Test meta-classes without user-defined __init__ or __new__ + class C(type): pass + class D(C): pass + with self.assertRaisesRegex(ValueError, "callable.*is not supported"): + self.assertEqual(inspect.signature(C), None) + with self.assertRaisesRegex(ValueError, "callable.*is not supported"): + self.assertEqual(inspect.signature(D), None) + + @unittest.skipIf(MISSING_C_DOCSTRINGS, + "Signature information for builtins requires docstrings") + def test_signature_on_builtin_class(self): + self.assertEqual(str(inspect.signature(_pickle.Pickler)), + '(file, protocol=None, fix_imports=True)') + + class P(_pickle.Pickler): pass + class EmptyTrait: pass + class P2(EmptyTrait, P): pass + self.assertEqual(str(inspect.signature(P)), + '(file, protocol=None, fix_imports=True)') + self.assertEqual(str(inspect.signature(P2)), + '(file, protocol=None, fix_imports=True)') + + class P3(P2): + def __init__(self, spam): + pass + self.assertEqual(str(inspect.signature(P3)), '(spam)') + + class MetaP(type): + def __call__(cls, foo, bar): + pass + class P4(P2, metaclass=MetaP): + pass + self.assertEqual(str(inspect.signature(P4)), '(foo, bar)') + def test_signature_on_callable_objects(self): class Foo: def __call__(self, a): @@ -1971,12 +2520,6 @@ class Bar(Spam, Foo): ((('a', ..., ..., "positional_or_keyword"),), ...)) - class ToFail: - __call__ = type - with self.assertRaisesRegex(ValueError, "not supported by signature"): - inspect.signature(ToFail()) - - class Wrapped: pass Wrapped.__wrapped__ = lambda a: None @@ -1999,49 +2542,91 @@ def foo(a, *, b:int) -> float: pass def bar(a, *, b:int) -> float: pass self.assertEqual(inspect.signature(foo), inspect.signature(bar)) + self.assertEqual( + hash(inspect.signature(foo)), hash(inspect.signature(bar))) def bar(a, *, b:int) -> int: pass self.assertNotEqual(inspect.signature(foo), inspect.signature(bar)) + self.assertNotEqual( + hash(inspect.signature(foo)), hash(inspect.signature(bar))) def bar(a, *, b:int): pass self.assertNotEqual(inspect.signature(foo), inspect.signature(bar)) + self.assertNotEqual( + hash(inspect.signature(foo)), hash(inspect.signature(bar))) def bar(a, *, b:int=42) -> float: pass self.assertNotEqual(inspect.signature(foo), inspect.signature(bar)) + self.assertNotEqual( + hash(inspect.signature(foo)), hash(inspect.signature(bar))) def bar(a, *, c) -> float: pass self.assertNotEqual(inspect.signature(foo), inspect.signature(bar)) + self.assertNotEqual( + hash(inspect.signature(foo)), hash(inspect.signature(bar))) def bar(a, b:int) -> float: pass self.assertNotEqual(inspect.signature(foo), inspect.signature(bar)) + self.assertNotEqual( + hash(inspect.signature(foo)), hash(inspect.signature(bar))) def spam(b:int, a) -> float: pass self.assertNotEqual(inspect.signature(spam), inspect.signature(bar)) + self.assertNotEqual( + hash(inspect.signature(spam)), hash(inspect.signature(bar))) def foo(*, a, b, c): pass def bar(*, c, b, a): pass self.assertEqual(inspect.signature(foo), inspect.signature(bar)) + self.assertEqual( + hash(inspect.signature(foo)), hash(inspect.signature(bar))) def foo(*, a=1, b, c): pass def bar(*, c, b, a=1): pass self.assertEqual(inspect.signature(foo), inspect.signature(bar)) + self.assertEqual( + hash(inspect.signature(foo)), hash(inspect.signature(bar))) def foo(pos, *, a=1, b, c): pass def bar(pos, *, c, b, a=1): pass self.assertEqual(inspect.signature(foo), inspect.signature(bar)) + self.assertEqual( + hash(inspect.signature(foo)), hash(inspect.signature(bar))) def foo(pos, *, a, b, c): pass def bar(pos, *, c, b, a=1): pass self.assertNotEqual(inspect.signature(foo), inspect.signature(bar)) + self.assertNotEqual( + hash(inspect.signature(foo)), hash(inspect.signature(bar))) def foo(pos, *args, a=42, b, c, **kwargs:int): pass def bar(pos, *args, c, b, a=42, **kwargs:int): pass self.assertEqual(inspect.signature(foo), inspect.signature(bar)) + self.assertEqual( + hash(inspect.signature(foo)), hash(inspect.signature(bar))) + + def test_signature_hashable(self): + S = inspect.Signature + P = inspect.Parameter - def test_signature_unhashable(self): def foo(a): pass - sig = inspect.signature(foo) + foo_sig = inspect.signature(foo) + + manual_sig = S(parameters=[P('a', P.POSITIONAL_OR_KEYWORD)]) + + self.assertEqual(hash(foo_sig), hash(manual_sig)) + self.assertNotEqual(hash(foo_sig), + hash(manual_sig.replace(return_annotation='spam'))) + + def bar(a) -> 1: pass + self.assertNotEqual(hash(foo_sig), hash(inspect.signature(bar))) + + def foo(a={}): pass + with self.assertRaisesRegex(TypeError, 'unhashable type'): + hash(inspect.signature(foo)) + + def foo(a) -> {}: pass with self.assertRaisesRegex(TypeError, 'unhashable type'): - hash(sig) + hash(inspect.signature(foo)) def test_signature_str(self): def foo(a:int=1, *, b, c=None, **kwargs) -> 42: @@ -2060,6 +2645,7 @@ def foo(): def test_signature_str_positional_only(self): P = inspect.Parameter + S = inspect.Signature def test(a_po, *, b, **kwargs): return a_po, kwargs @@ -2070,14 +2656,20 @@ def test(a_po, *, b, **kwargs): test.__signature__ = sig.replace(parameters=new_params) self.assertEqual(str(inspect.signature(test)), - '(, *, b, **kwargs)') + '(a_po, /, *, b, **kwargs)') - sig = inspect.signature(test) - new_params = list(sig.parameters.values()) - new_params[0] = new_params[0].replace(name=None) - test.__signature__ = sig.replace(parameters=new_params) - self.assertEqual(str(inspect.signature(test)), - '(<0>, *, b, **kwargs)') + self.assertEqual(str(S(parameters=[P('foo', P.POSITIONAL_ONLY)])), + '(foo, /)') + + self.assertEqual(str(S(parameters=[ + P('foo', P.POSITIONAL_ONLY), + P('bar', P.VAR_KEYWORD)])), + '(foo, /, **bar)') + + self.assertEqual(str(S(parameters=[ + P('foo', P.POSITIONAL_ONLY), + P('bar', P.VAR_POSITIONAL)])), + '(foo, /, *bar)') def test_signature_replace_anno(self): def test() -> 42: @@ -2092,6 +2684,35 @@ def test() -> 42: self.assertEqual(sig.return_annotation, 42) self.assertEqual(sig, inspect.signature(test)) + def test_signature_on_mangled_parameters(self): + class Spam: + def foo(self, __p1:1=2, *, __p2:2=3): + pass + class Ham(Spam): + pass + + self.assertEqual(self.signature(Spam.foo), + ((('self', ..., ..., "positional_or_keyword"), + ('_Spam__p1', 2, 1, "positional_or_keyword"), + ('_Spam__p2', 3, 2, "keyword_only")), + ...)) + + self.assertEqual(self.signature(Spam.foo), + self.signature(Ham.foo)) + + def test_signature_from_callable_python_obj(self): + class MySignature(inspect.Signature): pass + def foo(a, *, b:1): pass + foo_sig = MySignature.from_callable(foo) + self.assertTrue(isinstance(foo_sig, MySignature)) + + @unittest.skipIf(MISSING_C_DOCSTRINGS, + "Signature information for builtins requires docstrings") + def test_signature_from_callable_builtin_obj(self): + class MySignature(inspect.Signature): pass + sig = MySignature.from_callable(_pickle.Pickler) + self.assertTrue(isinstance(sig, MySignature)) + class TestParameterObject(unittest.TestCase): def test_signature_parameter_kinds(self): @@ -2116,10 +2737,13 @@ def test_signature_parameter_object(self): with self.assertRaisesRegex(ValueError, 'not a valid parameter name'): inspect.Parameter('1', kind=inspect.Parameter.VAR_KEYWORD) - with self.assertRaisesRegex(ValueError, - 'non-positional-only parameter'): + with self.assertRaisesRegex(TypeError, 'name must be a str'): inspect.Parameter(None, kind=inspect.Parameter.VAR_KEYWORD) + with self.assertRaisesRegex(ValueError, + 'is not a valid parameter name'): + inspect.Parameter('$', kind=inspect.Parameter.VAR_KEYWORD) + with self.assertRaisesRegex(ValueError, 'cannot have default values'): inspect.Parameter('a', default=42, kind=inspect.Parameter.VAR_KEYWORD) @@ -2134,6 +2758,16 @@ def test_signature_parameter_object(self): p.replace(kind=inspect.Parameter.VAR_POSITIONAL) self.assertTrue(repr(p).startswith('') - - p = p.replace(name='1') - self.assertEqual(str(p), '<1>') + with self.assertRaisesRegex(TypeError, 'name must be a str'): + inspect.Parameter(None, kind=inspect.Parameter.POSITIONAL_ONLY) def test_signature_parameter_immutability(self): - p = inspect.Parameter(None, kind=inspect.Parameter.POSITIONAL_ONLY) + p = inspect.Parameter('spam', kind=inspect.Parameter.KEYWORD_ONLY) with self.assertRaises(AttributeError): p.foo = 'bar' @@ -2395,6 +3020,15 @@ def test(a_po, b_po, c_po=3, foo=42, *, bar=50, **kwargs): self.assertEqual(self.call(test, 1, 2, 4, 5, bar=6), (1, 2, 4, 5, 6, {})) + self.assertEqual(self.call(test, 1, 2), + (1, 2, 3, 42, 50, {})) + + self.assertEqual(self.call(test, 1, 2, foo=4, bar=5), + (1, 2, 3, 4, 5, {})) + + with self.assertRaisesRegex(TypeError, "but was passed as a keyword"): + self.call(test, 1, 2, foo=4, bar=5, c_po=10) + with self.assertRaisesRegex(TypeError, "parameter is positional only"): self.call(test, 1, 2, c_po=4) @@ -2411,6 +3045,22 @@ def test(a, self, b): ba = sig.bind(1, self=2, b=3) self.assertEqual(ba.args, (1, 2, 3)) + def test_signature_bind_vararg_name(self): + def test(a, *args): + return a, args + sig = inspect.signature(test) + + with self.assertRaisesRegex(TypeError, "too many keyword arguments"): + sig.bind(a=0, args=1) + + def test(*args, **kwargs): + return args, kwargs + self.assertEqual(self.call(test, args=1), ((), {'args': 1})) + + sig = inspect.signature(test) + ba = sig.bind(args=1) + self.assertEqual(ba.arguments, {'kwargs': {'args': 1}}) + class TestBoundArguments(unittest.TestCase): def test_signature_bound_arguments_unhashable(self): @@ -2437,6 +3087,80 @@ def bar(b): pass ba4 = inspect.signature(bar).bind(1) self.assertNotEqual(ba, ba4) + def test_signature_bound_arguments_pickle(self): + def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass + sig = inspect.signature(foo) + ba = sig.bind(20, 30, z={}) + + for ver in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(pickle_ver=ver): + ba_pickled = pickle.loads(pickle.dumps(ba, ver)) + self.assertEqual(ba, ba_pickled) + + +class TestSignaturePrivateHelpers(unittest.TestCase): + def test_signature_get_bound_param(self): + getter = inspect._signature_get_bound_param + + self.assertEqual(getter('($self)'), 'self') + self.assertEqual(getter('($self, obj)'), 'self') + self.assertEqual(getter('($cls, /, obj)'), 'cls') + + def _strip_non_python_syntax(self, input, + clean_signature, self_parameter, last_positional_only): + computed_clean_signature, \ + computed_self_parameter, \ + computed_last_positional_only = \ + inspect._signature_strip_non_python_syntax(input) + self.assertEqual(computed_clean_signature, clean_signature) + self.assertEqual(computed_self_parameter, self_parameter) + self.assertEqual(computed_last_positional_only, last_positional_only) + + def test_signature_strip_non_python_syntax(self): + self._strip_non_python_syntax( + "($module, /, path, mode, *, dir_fd=None, " + + "effective_ids=False,\n follow_symlinks=True)", + "(module, path, mode, *, dir_fd=None, " + + "effective_ids=False, follow_symlinks=True)", + 0, + 0) + + self._strip_non_python_syntax( + "($module, word, salt, /)", + "(module, word, salt)", + 0, + 2) + + self._strip_non_python_syntax( + "(x, y=None, z=None, /)", + "(x, y=None, z=None)", + None, + 2) + + self._strip_non_python_syntax( + "(x, y=None, z=None)", + "(x, y=None, z=None)", + None, + None) + + self._strip_non_python_syntax( + "(x,\n y=None,\n z = None )", + "(x, y=None, z=None)", + None, + None) + + self._strip_non_python_syntax( + "", + "", + None, + None) + + self._strip_non_python_syntax( + None, + None, + None, + None) + class TestUnwrap(unittest.TestCase): @@ -2503,6 +3227,13 @@ def test_only_source(self): self.assertEqual(lines[:-1], inspect.getsource(module).splitlines()) self.assertEqual(err, b'') + def test_custom_getattr(self): + def foo(): + pass + foo.__signature__ = 42 + with self.assertRaises(TypeError): + inspect.signature(foo) + @unittest.skipIf(ThreadPoolExecutor is None, 'threads required to test __qualname__ for source files') def test_qualname_source(self): @@ -2529,10 +3260,39 @@ def test_details(self): # Just a quick sanity check on the output self.assertIn(module.__name__, output) self.assertIn(module.__file__, output) - self.assertIn(module.__cached__, output) + if not sys.flags.optimize: + self.assertIn(module.__cached__, output) self.assertEqual(err, b'') +class TestReload(unittest.TestCase): + + src_before = textwrap.dedent("""\ +def foo(): + print("Bla") + """) + + src_after = textwrap.dedent("""\ +def foo(): + print("Oh no!") + """) + + def assertInspectEqual(self, path, source): + inspected_src = inspect.getsource(source) + with open(path) as src: + self.assertEqual( + src.read().splitlines(True), + inspected_src.splitlines(True) + ) + + def test_getsource_reload(self): + # see issue 1218234 + with _ready_to_import('reload_bug', self.src_before) as (name, path): + module = importlib.import_module(name) + self.assertInspectEqual(path, module) + with open(path, 'w') as src: + src.write(self.src_after) + self.assertInspectEqual(path, module) def test_main(): @@ -2542,7 +3302,8 @@ def test_main(): TestGetcallargsFunctions, TestGetcallargsMethods, TestGetcallargsUnboundMethods, TestGetattrStatic, TestGetGeneratorState, TestNoEOL, TestSignatureObject, TestSignatureBind, TestParameterObject, - TestBoundArguments, TestGetClosureVars, TestUnwrap, TestMain + TestBoundArguments, TestSignaturePrivateHelpers, TestGetClosureVars, + TestUnwrap, TestMain, TestReload ) if __name__ == "__main__": diff --git a/Lib/test/test_int.py b/Lib/test/test_int.py index 4e00622325a0..e94602e88dd0 100644 --- a/Lib/test/test_int.py +++ b/Lib/test/test_int.py @@ -304,32 +304,7 @@ class Foo0: def __int__(self): return 42 - class Foo1(object): - def __int__(self): - return 42 - - class Foo2(int): - def __int__(self): - return 42 - - class Foo3(int): - def __int__(self): - return self - - class Foo4(int): - def __int__(self): - return 42 - - class Foo5(int): - def __int__(self): - return 42. - self.assertEqual(int(Foo0()), 42) - self.assertEqual(int(Foo1()), 42) - self.assertEqual(int(Foo2()), 42) - self.assertEqual(int(Foo3()), 0) - self.assertEqual(int(Foo4()), 42) - self.assertRaises(TypeError, int, Foo5()) class Classic: pass @@ -392,6 +367,57 @@ def __trunc__(self): with self.assertRaises(TypeError): int(TruncReturnsBadInt()) + def test_int_subclass_with_int(self): + class MyInt(int): + def __int__(self): + return 42 + + class BadInt(int): + def __int__(self): + return 42.0 + + my_int = MyInt(7) + self.assertEqual(my_int, 7) + self.assertEqual(int(my_int), 42) + + self.assertRaises(TypeError, int, BadInt()) + + def test_int_returns_int_subclass(self): + class BadInt: + def __int__(self): + return True + + class BadInt2(int): + def __int__(self): + return True + + class TruncReturnsBadInt: + def __trunc__(self): + return BadInt() + + class TruncReturnsIntSubclass: + def __trunc__(self): + return True + + bad_int = BadInt() + with self.assertWarns(DeprecationWarning): + n = int(bad_int) + self.assertEqual(n, 1) + + bad_int = BadInt2() + with self.assertWarns(DeprecationWarning): + n = int(bad_int) + self.assertEqual(n, 1) + + bad_int = TruncReturnsBadInt() + with self.assertWarns(DeprecationWarning): + n = int(bad_int) + self.assertEqual(n, 1) + + good_int = TruncReturnsIntSubclass() + n = int(good_int) + self.assertEqual(n, 1) + def test_error_message(self): def check(s, base=None): with self.assertRaises(ValueError, diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index 57f3659667ab..198cc5d32d56 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -32,10 +32,10 @@ import unittest import warnings import weakref -import _testcapi from collections import deque, UserList from itertools import cycle, count from test import support +from test.script_helper import assert_python_ok import codecs import io # C implementation of io @@ -44,10 +44,6 @@ import threading except ImportError: threading = None -try: - import fcntl -except ImportError: - fcntl = None def _default_chunk_size(): """Get the default TextIOWrapper chunk size""" @@ -367,8 +363,8 @@ def test_invalid_operations(self): def test_open_handles_NUL_chars(self): fn_with_NUL = 'foo\0bar' - self.assertRaises(TypeError, self.open, fn_with_NUL, 'w') - self.assertRaises(TypeError, self.open, bytes(fn_with_NUL, 'ascii'), 'w') + self.assertRaises(ValueError, self.open, fn_with_NUL, 'w') + self.assertRaises(ValueError, self.open, bytes(fn_with_NUL, 'ascii'), 'w') def test_raw_file_io(self): with self.open(support.TESTFN, "wb", buffering=0) as f: @@ -421,14 +417,9 @@ def test_large_file_ops(self): # a long time to build the >2GB file and takes >2GB of disk space # therefore the resource must be enabled to run this test. if sys.platform[:3] == 'win' or sys.platform == 'darwin': - if not support.is_resource_enabled("largefile"): - print("\nTesting large file ops skipped on %s." % sys.platform, - file=sys.stderr) - print("It requires %d bytes and a long time." % self.LARGE, - file=sys.stderr) - print("Use 'regrtest.py -u largefile test_io' to run it.", - file=sys.stderr) - return + support.requires( + 'largefile', + 'test requires %s bytes and a long time to run' % self.LARGE) with self.open(support.TESTFN, "w+b", 0) as f: self.large_file_ops(f) with self.open(support.TESTFN, "w+b") as f: @@ -598,13 +589,43 @@ def test_unbounded_file(self): with self.open(zero, "r") as f: self.assertRaises(OverflowError, f.read) - def test_flush_error_on_close(self): - f = self.open(support.TESTFN, "wb", buffering=0) + def check_flush_error_on_close(self, *args, **kwargs): + # Test that the file is closed despite failed flush + # and that flush() is called before file closed. + f = self.open(*args, **kwargs) + closed = [] def bad_flush(): + closed[:] = [f.closed] raise OSError() f.flush = bad_flush self.assertRaises(OSError, f.close) # exception not swallowed self.assertTrue(f.closed) + self.assertTrue(closed) # flush() called + self.assertFalse(closed[0]) # flush() called before file closed + + def test_flush_error_on_close(self): + # raw file + # Issue #5700: io.FileIO calls flush() after file closed + self.check_flush_error_on_close(support.TESTFN, 'wb', buffering=0) + fd = os.open(support.TESTFN, os.O_WRONLY|os.O_CREAT) + self.check_flush_error_on_close(fd, 'wb', buffering=0) + fd = os.open(support.TESTFN, os.O_WRONLY|os.O_CREAT) + self.check_flush_error_on_close(fd, 'wb', buffering=0, closefd=False) + os.close(fd) + # buffered io + self.check_flush_error_on_close(support.TESTFN, 'wb') + fd = os.open(support.TESTFN, os.O_WRONLY|os.O_CREAT) + self.check_flush_error_on_close(fd, 'wb') + fd = os.open(support.TESTFN, os.O_WRONLY|os.O_CREAT) + self.check_flush_error_on_close(fd, 'wb', closefd=False) + os.close(fd) + # text io + self.check_flush_error_on_close(support.TESTFN, 'w') + fd = os.open(support.TESTFN, os.O_WRONLY|os.O_CREAT) + self.check_flush_error_on_close(fd, 'w') + fd = os.open(support.TESTFN, os.O_WRONLY|os.O_CREAT) + self.check_flush_error_on_close(fd, 'w', closefd=False) + os.close(fd) def test_multi_close(self): f = self.open(support.TESTFN, "wb", buffering=0) @@ -658,6 +679,20 @@ def test_fileio_closefd(self): fileio.close() f2.readline() + def test_nonbuffered_textio(self): + with warnings.catch_warnings(record=True) as recorded: + with self.assertRaises(ValueError): + self.open(support.TESTFN, 'w', buffering=0) + support.gc_collect() + self.assertEqual(recorded, []) + + def test_invalid_newline(self): + with warnings.catch_warnings(record=True) as recorded: + with self.assertRaises(ValueError): + self.open(support.TESTFN, 'w', newline='invalid') + support.gc_collect() + self.assertEqual(recorded, []) + class CIOTest(IOTest): @@ -692,12 +727,15 @@ def test_detach(self): self.assertIs(buf.detach(), raw) self.assertRaises(ValueError, buf.detach) + repr(buf) # Should still work + def test_fileno(self): rawio = self.MockRawIO() bufio = self.tp(rawio) self.assertEqual(42, bufio.fileno()) + @unittest.skip('test having existential crisis') def test_no_fileno(self): # XXX will we always have fileno() function? If so, kill # this test. Else, write it. @@ -768,7 +806,7 @@ def f(): def test_repr(self): raw = self.MockRawIO() b = self.tp(raw) - clsname = "%s.%s" % (self.tp.__module__, self.tp.__name__) + clsname = "%s.%s" % (self.tp.__module__, self.tp.__qualname__) self.assertEqual(repr(b), "<%s>" % clsname) raw.name = "dummy" self.assertEqual(repr(b), "<%s name='dummy'>" % clsname) @@ -776,13 +814,21 @@ def test_repr(self): self.assertEqual(repr(b), "<%s name=b'dummy'>" % clsname) def test_flush_error_on_close(self): + # Test that buffered file is closed despite failed flush + # and that flush() is called before file closed. raw = self.MockRawIO() + closed = [] def bad_flush(): + closed[:] = [b.closed, raw.closed] raise OSError() raw.flush = bad_flush b = self.tp(raw) self.assertRaises(OSError, b.close) # exception not swallowed self.assertTrue(b.closed) + self.assertTrue(raw.closed) + self.assertTrue(closed) # flush() called + self.assertFalse(closed[0]) # flush() called before file closed + self.assertFalse(closed[1]) def test_close_error_on_close(self): raw = self.MockRawIO() @@ -796,9 +842,27 @@ def bad_close(): with self.assertRaises(OSError) as err: # exception not swallowed b.close() self.assertEqual(err.exception.args, ('close',)) + self.assertIsInstance(err.exception.__context__, OSError) self.assertEqual(err.exception.__context__.args, ('flush',)) self.assertFalse(b.closed) + def test_nonnormalized_close_error_on_close(self): + # Issue #21677 + raw = self.MockRawIO() + def bad_flush(): + raise non_existing_flush + def bad_close(): + raise non_existing_close + raw.close = bad_close + b = self.tp(raw) + b.flush = bad_flush + with self.assertRaises(NameError) as err: # exception not swallowed + b.close() + self.assertIn('non_existing_close', str(err.exception)) + self.assertIsInstance(err.exception.__context__, NameError) + self.assertIn('non_existing_flush', str(err.exception.__context__)) + self.assertFalse(b.closed) + def test_multi_close(self): raw = self.MockRawIO() b = self.tp(raw) @@ -859,6 +923,16 @@ def test_constructor(self): bufio.__init__(rawio) self.assertEqual(b"abc", bufio.read()) + def test_uninitialized(self): + bufio = self.tp.__new__(self.tp) + del bufio + bufio = self.tp.__new__(self.tp) + self.assertRaisesRegex((ValueError, AttributeError), + 'uninitialized|has no attribute', + bufio.read, 0) + bufio.__init__(self.MockRawIO()) + self.assertEqual(bufio.read(0), b'') + def test_read(self): for arg in (None, 7): rawio = self.MockRawIO((b"abc", b"d", b"efg")) @@ -905,6 +979,71 @@ def test_readinto(self): self.assertEqual(bufio.readinto(b), 1) self.assertEqual(b, b"cb") + def test_readinto1(self): + buffer_size = 10 + rawio = self.MockRawIO((b"abc", b"de", b"fgh", b"jkl")) + bufio = self.tp(rawio, buffer_size=buffer_size) + b = bytearray(2) + self.assertEqual(bufio.peek(3), b'abc') + self.assertEqual(rawio._reads, 1) + self.assertEqual(bufio.readinto1(b), 2) + self.assertEqual(b, b"ab") + self.assertEqual(rawio._reads, 1) + self.assertEqual(bufio.readinto1(b), 1) + self.assertEqual(b[:1], b"c") + self.assertEqual(rawio._reads, 1) + self.assertEqual(bufio.readinto1(b), 2) + self.assertEqual(b, b"de") + self.assertEqual(rawio._reads, 2) + b = bytearray(2*buffer_size) + self.assertEqual(bufio.peek(3), b'fgh') + self.assertEqual(rawio._reads, 3) + self.assertEqual(bufio.readinto1(b), 6) + self.assertEqual(b[:6], b"fghjkl") + self.assertEqual(rawio._reads, 4) + + def test_readinto_array(self): + buffer_size = 60 + data = b"a" * 26 + rawio = self.MockRawIO((data,)) + bufio = self.tp(rawio, buffer_size=buffer_size) + + # Create an array with element size > 1 byte + b = array.array('i', b'x' * 32) + assert len(b) != 16 + + # Read into it. We should get as many *bytes* as we can fit into b + # (which is more than the number of elements) + n = bufio.readinto(b) + self.assertGreater(n, len(b)) + + # Check that old contents of b are preserved + bm = memoryview(b).cast('B') + self.assertLess(n, len(bm)) + self.assertEqual(bm[:n], data[:n]) + self.assertEqual(bm[n:], b'x' * (len(bm[n:]))) + + def test_readinto1_array(self): + buffer_size = 60 + data = b"a" * 26 + rawio = self.MockRawIO((data,)) + bufio = self.tp(rawio, buffer_size=buffer_size) + + # Create an array with element size > 1 byte + b = array.array('i', b'x' * 32) + assert len(b) != 16 + + # Read into it. We should get as many *bytes* as we can fit into b + # (which is more than the number of elements) + n = bufio.readinto1(b) + self.assertGreater(n, len(b)) + + # Check that old contents of b are preserved + bm = memoryview(b).cast('B') + self.assertLess(n, len(bm)) + self.assertEqual(bm[:n], data[:n]) + self.assertEqual(bm[n:], b'x' * (len(bm[n:]))) + def test_readlines(self): def bufio(): rawio = self.MockRawIO((b"abc\n", b"d\n", b"ef")) @@ -1110,6 +1249,16 @@ def test_constructor(self): bufio.flush() self.assertEqual(b"".join(rawio._write_stack), b"abcghi") + def test_uninitialized(self): + bufio = self.tp.__new__(self.tp) + del bufio + bufio = self.tp.__new__(self.tp) + self.assertRaisesRegex((ValueError, AttributeError), + 'uninitialized|has no attribute', + bufio.write, b'') + bufio.__init__(self.MockRawIO()) + self.assertEqual(bufio.write(b''), 0) + def test_detach_flush(self): raw = self.MockRawIO() buf = self.tp(raw) @@ -1394,6 +1543,20 @@ def test_constructor(self): pair = self.tp(self.MockRawIO(), self.MockRawIO()) self.assertFalse(pair.closed) + def test_uninitialized(self): + pair = self.tp.__new__(self.tp) + del pair + pair = self.tp.__new__(self.tp) + self.assertRaisesRegex((ValueError, AttributeError), + 'uninitialized|has no attribute', + pair.read, 0) + self.assertRaisesRegex((ValueError, AttributeError), + 'uninitialized|has no attribute', + pair.write, b'') + pair.__init__(self.MockRawIO(), self.MockRawIO()) + self.assertEqual(pair.read(0), b'') + self.assertEqual(pair.write(b''), 0) + def test_detach(self): pair = self.tp(self.MockRawIO(), self.MockRawIO()) self.assertRaises(self.UnsupportedOperation, pair.detach) @@ -1505,6 +1668,12 @@ def isatty(self): pair = self.tp(SelectableIsAtty(True), SelectableIsAtty(True)) self.assertTrue(pair.isatty()) + def test_weakref_clearing(self): + brw = self.tp(self.MockRawIO(), self.MockRawIO()) + ref = weakref.ref(brw) + brw = None + ref = None # Shouldn't segfault. + class CBufferedRWPairTest(BufferedRWPairTest): tp = io.BufferedRWPair @@ -1520,6 +1689,10 @@ def test_constructor(self): BufferedReaderTest.test_constructor(self) BufferedWriterTest.test_constructor(self) + def test_uninitialized(self): + BufferedReaderTest.test_uninitialized(self) + BufferedWriterTest.test_uninitialized(self) + def test_read_and_write(self): raw = self.MockRawIO((b"asdf", b"ghjk")) rw = self.tp(raw, 8) @@ -1932,6 +2105,15 @@ def test_constructor(self): self.assertRaises(TypeError, t.__init__, b, newline=42) self.assertRaises(ValueError, t.__init__, b, newline='xyzzy') + def test_non_text_encoding_codecs_are_rejected(self): + # Ensure the constructor complains if passed a codec that isn't + # marked as a text encoding + # http://bugs.python.org/issue20404 + r = self.BytesIO() + b = self.BufferedWriter(r) + with self.assertRaisesRegex(LookupError, "is not a text encoding"): + self.TextIOWrapper(b, encoding="hex") + def test_detach(self): r = self.BytesIO() b = self.BufferedWriter(r) @@ -1945,6 +2127,12 @@ def test_detach(self): self.assertEqual(r.getvalue(), b"howdy") self.assertRaises(ValueError, t.detach) + # Operations independent of the detached stream should still work + repr(t) + self.assertEqual(t.encoding, "ascii") + self.assertEqual(t.errors, "strict") + self.assertFalse(t.line_buffering) + def test_repr(self): raw = self.BytesIO("hello".encode("utf-8")) b = self.BufferedReader(raw) @@ -1962,6 +2150,9 @@ def test_repr(self): self.assertEqual(repr(t), "<%s.TextIOWrapper name=b'dummy' mode='r' encoding='utf-8'>" % modname) + t.buffer.detach() + repr(t) # Should not raise an exception + def test_line_buffering(self): r = self.BytesIO() b = self.BufferedWriter(r, 1000) @@ -1991,8 +2182,10 @@ def test_default_encoding(self): os.environ.clear() os.environ.update(old_environ) - # Issue 15989 + @support.cpython_only def test_device_encoding(self): + # Issue 15989 + import _testcapi b = self.BytesIO() b.fileno = lambda: _testcapi.INT_MAX + 1 self.assertRaises(OverflowError, self.TextIOWrapper, b) @@ -2524,12 +2717,53 @@ def run(n): self.assertEqual(content.count("Thread%03d\n" % n), 1) def test_flush_error_on_close(self): + # Test that text file is closed despite failed flush + # and that flush() is called before file closed. txt = self.TextIOWrapper(self.BytesIO(self.testdata), encoding="ascii") + closed = [] def bad_flush(): + closed[:] = [txt.closed, txt.buffer.closed] raise OSError() txt.flush = bad_flush self.assertRaises(OSError, txt.close) # exception not swallowed self.assertTrue(txt.closed) + self.assertTrue(txt.buffer.closed) + self.assertTrue(closed) # flush() called + self.assertFalse(closed[0]) # flush() called before file closed + self.assertFalse(closed[1]) + + def test_close_error_on_close(self): + buffer = self.BytesIO(self.testdata) + def bad_flush(): + raise OSError('flush') + def bad_close(): + raise OSError('close') + buffer.close = bad_close + txt = self.TextIOWrapper(buffer, encoding="ascii") + txt.flush = bad_flush + with self.assertRaises(OSError) as err: # exception not swallowed + txt.close() + self.assertEqual(err.exception.args, ('close',)) + self.assertIsInstance(err.exception.__context__, OSError) + self.assertEqual(err.exception.__context__.args, ('flush',)) + self.assertFalse(txt.closed) + + def test_nonnormalized_close_error_on_close(self): + # Issue #21677 + buffer = self.BytesIO(self.testdata) + def bad_flush(): + raise non_existing_flush + def bad_close(): + raise non_existing_close + buffer.close = bad_close + txt = self.TextIOWrapper(buffer, encoding="ascii") + txt.flush = bad_flush + with self.assertRaises(NameError) as err: # exception not swallowed + txt.close() + self.assertIn('non_existing_close', str(err.exception)) + self.assertIsInstance(err.exception.__context__, NameError) + self.assertIn('non_existing_flush', str(err.exception.__context__)) + self.assertFalse(txt.closed) def test_multi_close(self): txt = self.TextIOWrapper(self.BytesIO(self.testdata), encoding="ascii") @@ -2570,6 +2804,38 @@ def test_rawio_write_through(self): txt.write('5') self.assertEqual(b''.join(raw._write_stack), b'123\n45') + def test_bufio_write_through(self): + # Issue #21396: write_through=True doesn't force a flush() + # on the underlying binary buffered object. + flush_called, write_called = [], [] + class BufferedWriter(self.BufferedWriter): + def flush(self, *args, **kwargs): + flush_called.append(True) + return super().flush(*args, **kwargs) + def write(self, *args, **kwargs): + write_called.append(True) + return super().write(*args, **kwargs) + + rawio = self.BytesIO() + data = b"a" + bufio = BufferedWriter(rawio, len(data)*2) + textio = self.TextIOWrapper(bufio, encoding='ascii', + write_through=True) + # write to the buffered io but don't overflow the buffer + text = data.decode('ascii') + textio.write(text) + + # buffer.flush is not called with write_through=True + self.assertFalse(flush_called) + # buffer.write *is* called with write_through=True + self.assertTrue(write_called) + self.assertEqual(rawio.getvalue(), b"") # no flush + + write_called = [] # reset + textio.write(text * 10) # total content is larger than bufio buffer + self.assertTrue(write_called) + self.assertEqual(rawio.getvalue(), data * 11) # all flushed + def test_read_nonbytes(self): # Issue #17106 # Crash when underlying read() returns non-bytes @@ -2582,19 +2848,109 @@ def test_read_nonbytes(self): def test_illegal_decoder(self): # Issue #17106 + # Bypass the early encoding check added in issue 20404 + def _make_illegal_wrapper(): + quopri = codecs.lookup("quopri") + quopri._is_text_encoding = True + try: + t = self.TextIOWrapper(self.BytesIO(b'aaaaaa'), + newline='\n', encoding="quopri") + finally: + quopri._is_text_encoding = False + return t # Crash when decoder returns non-string - t = self.TextIOWrapper(self.BytesIO(b'aaaaaa'), newline='\n', - encoding='quopri_codec') + t = _make_illegal_wrapper() self.assertRaises(TypeError, t.read, 1) - t = self.TextIOWrapper(self.BytesIO(b'aaaaaa'), newline='\n', - encoding='quopri_codec') + t = _make_illegal_wrapper() self.assertRaises(TypeError, t.readline) - t = self.TextIOWrapper(self.BytesIO(b'aaaaaa'), newline='\n', - encoding='quopri_codec') + t = _make_illegal_wrapper() self.assertRaises(TypeError, t.read) + def _check_create_at_shutdown(self, **kwargs): + # Issue #20037: creating a TextIOWrapper at shutdown + # shouldn't crash the interpreter. + iomod = self.io.__name__ + code = """if 1: + import codecs + import {iomod} as io + + # Avoid looking up codecs at shutdown + codecs.lookup('utf-8') + + class C: + def __init__(self): + self.buf = io.BytesIO() + def __del__(self): + io.TextIOWrapper(self.buf, **{kwargs}) + print("ok") + c = C() + """.format(iomod=iomod, kwargs=kwargs) + return assert_python_ok("-c", code) + + def test_create_at_shutdown_without_encoding(self): + rc, out, err = self._check_create_at_shutdown() + if err: + # Can error out with a RuntimeError if the module state + # isn't found. + self.assertIn(self.shutdown_error, err.decode()) + else: + self.assertEqual("ok", out.decode().strip()) + + def test_create_at_shutdown_with_encoding(self): + rc, out, err = self._check_create_at_shutdown(encoding='utf-8', + errors='strict') + self.assertFalse(err) + self.assertEqual("ok", out.decode().strip()) + + def test_read_byteslike(self): + r = MemviewBytesIO(b'Just some random string\n') + t = self.TextIOWrapper(r, 'utf-8') + + # TextIOwrapper will not read the full string, because + # we truncate it to a multiple of the native int size + # so that we can construct a more complex memoryview. + bytes_val = _to_memoryview(r.getvalue()).tobytes() + + self.assertEqual(t.read(200), bytes_val.decode('utf-8')) + + def test_issue22849(self): + class F(object): + def readable(self): return True + def writable(self): return True + def seekable(self): return True + + for i in range(10): + try: + self.TextIOWrapper(F(), encoding='utf-8') + except Exception: + pass + + F.tell = lambda x: 0 + t = self.TextIOWrapper(F(), encoding='utf-8') + + +class MemviewBytesIO(io.BytesIO): + '''A BytesIO object whose read method returns memoryviews + rather than bytes''' + + def read1(self, len_): + return _to_memoryview(super().read1(len_)) + + def read(self, len_): + return _to_memoryview(super().read(len_)) + +def _to_memoryview(buf): + '''Convert bytes-object *buf* to a non-trivial memoryview''' + + arr = array.array('i') + idx = len(buf) - len(buf) % arr.itemsize + arr.frombytes(buf[:idx]) + return memoryview(arr) + class CTextIOWrapperTest(TextIOWrapperTest): + io = io + shutdown_error = "RuntimeError: could not find io module state" def test_initialization(self): r = self.BytesIO(b"\xc3\xa9\n\n") @@ -2605,6 +2961,9 @@ def test_initialization(self): self.assertRaises(ValueError, t.__init__, b, newline='xyzzy') self.assertRaises(ValueError, t.read) + t = self.TextIOWrapper.__new__(self.TextIOWrapper) + self.assertRaises(Exception, repr, t) + def test_garbage_collection(self): # C TextIOWrapper objects are collected, and collecting them flushes # all data to disk. @@ -2638,7 +2997,9 @@ def test_rwpair_cleared_before_textio(self): class PyTextIOWrapperTest(TextIOWrapperTest): - pass + io = pyio + #shutdown_error = "LookupError: unknown encoding: ascii" + shutdown_error = "TypeError: 'NoneType' object is not iterable" class IncrementalNewlineDecoderTest(unittest.TestCase): @@ -2833,6 +3194,8 @@ def test_io_after_close(self): self.assertRaises(ValueError, f.readall) if hasattr(f, "readinto"): self.assertRaises(ValueError, f.readinto, bytearray(1024)) + if hasattr(f, "readinto1"): + self.assertRaises(ValueError, f.readinto1, bytearray(1024)) self.assertRaises(ValueError, f.readline) self.assertRaises(ValueError, f.readlines) self.assertRaises(ValueError, f.seek, 0) @@ -2946,26 +3309,20 @@ def test_pickling(self): with self.open(support.TESTFN, **kwargs) as f: self.assertRaises(TypeError, pickle.dumps, f, protocol) - @unittest.skipUnless(fcntl, 'fcntl required for this test') def test_nonblock_pipe_write_bigbuf(self): self._test_nonblock_pipe_write(16*1024) - @unittest.skipUnless(fcntl, 'fcntl required for this test') def test_nonblock_pipe_write_smallbuf(self): self._test_nonblock_pipe_write(1024) - def _set_non_blocking(self, fd): - flags = fcntl.fcntl(fd, fcntl.F_GETFL) - self.assertNotEqual(flags, -1) - res = fcntl.fcntl(fd, fcntl.F_SETFL, flags | os.O_NONBLOCK) - self.assertEqual(res, 0) - + @unittest.skipUnless(hasattr(os, 'set_blocking'), + 'os.set_blocking() required for this test') def _test_nonblock_pipe_write(self, bufsize): sent = [] received = [] r, w = os.pipe() - self._set_non_blocking(r) - self._set_non_blocking(w) + os.set_blocking(r, False) + os.set_blocking(w, False) # To exercise all code paths in the C implementation we need # to play with buffer sizes. For instance, if we choose a @@ -3109,6 +3466,8 @@ def test_interrupted_write_unbuffered(self): def test_interrupted_write_buffered(self): self.check_interrupted_write(b"xy", b"xy", mode="wb") + # Issue #22331: The test hangs on FreeBSD 7.2 + @support.requires_freebsd_version(8) def test_interrupted_write_text(self): self.check_interrupted_write("xy", b"xy", mode="w", encoding="ascii") diff --git a/Lib/test/test_ipaddress.py b/Lib/test/test_ipaddress.py index f3b1565744e0..e985329117f7 100644 --- a/Lib/test/test_ipaddress.py +++ b/Lib/test/test_ipaddress.py @@ -7,9 +7,12 @@ import unittest import re import contextlib +import functools import operator +import pickle import ipaddress + class BaseTestCase(unittest.TestCase): # One big change in ipaddress over the original ipaddr module is # error reporting that tries to assume users *don't know the rules* @@ -52,17 +55,18 @@ def assertCleanError(self, exc_type, details, *args): def assertAddressError(self, details, *args): """Ensure a clean AddressValueError""" return self.assertCleanError(ipaddress.AddressValueError, - details, *args) + details, *args) def assertNetmaskError(self, details, *args): """Ensure a clean NetmaskValueError""" return self.assertCleanError(ipaddress.NetmaskValueError, - details, *args) + details, *args) def assertInstancesEqual(self, lhs, rhs): """Check constructor arguments produce equivalent instances""" self.assertEqual(self.factory(lhs), self.factory(rhs)) + class CommonTestMixin: def test_empty_address(self): @@ -80,6 +84,13 @@ def test_not_an_index_issue15559(self): self.assertRaises(TypeError, hex, self.factory(1)) self.assertRaises(TypeError, bytes, self.factory(1)) + def pickle_test(self, addr): + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(proto=proto): + x = self.factory(addr) + y = pickle.loads(pickle.dumps(x, proto)) + self.assertEqual(y, x) + class CommonTestMixin_v4(CommonTestMixin): @@ -115,6 +126,7 @@ def assertBadLength(length): assertBadLength(3) assertBadLength(5) + class CommonTestMixin_v6(CommonTestMixin): def test_leading_zeros(self): @@ -195,7 +207,7 @@ def assertBadSplit(addr): def test_empty_octet(self): def assertBadOctet(addr): with self.assertAddressError("Empty octet not permitted in %r", - addr): + addr): ipaddress.IPv4Address(addr) assertBadOctet("42..42.42") @@ -244,6 +256,9 @@ def assertBadOctet(addr, octet): assertBadOctet("257.0.0.0", 257) assertBadOctet("192.168.0.999", 999) + def test_pickle(self): + self.pickle_test('192.0.2.1') + class AddressTestCase_v6(BaseTestCase, CommonTestMixin_v6): factory = ipaddress.IPv6Address @@ -376,6 +391,9 @@ def assertBadPart(addr, part): assertBadPart("02001:db8::", "02001") assertBadPart('2001:888888::1', "888888") + def test_pickle(self): + self.pickle_test('2001:db8::') + class NetmaskTestMixin_v4(CommonTestMixin_v4): """Input validation on interfaces and networks is very similar""" @@ -398,22 +416,57 @@ def assertBadAddress(addr, details): assertBadAddress("::1.2.3.4", "Only decimal digits") assertBadAddress("1.2.3.256", re.escape("256 (> 255)")) + def test_valid_netmask(self): + self.assertEqual(str(self.factory('192.0.2.0/255.255.255.0')), + '192.0.2.0/24') + for i in range(0, 33): + # Generate and re-parse the CIDR format (trivial). + net_str = '0.0.0.0/%d' % i + net = self.factory(net_str) + self.assertEqual(str(net), net_str) + # Generate and re-parse the expanded netmask. + self.assertEqual( + str(self.factory('0.0.0.0/%s' % net.netmask)), net_str) + # Zero prefix is treated as decimal. + self.assertEqual(str(self.factory('0.0.0.0/0%d' % i)), net_str) + # Generate and re-parse the expanded hostmask. The ambiguous + # cases (/0 and /32) are treated as netmasks. + if i in (32, 0): + net_str = '0.0.0.0/%d' % (32 - i) + self.assertEqual( + str(self.factory('0.0.0.0/%s' % net.hostmask)), net_str) + def test_netmask_errors(self): def assertBadNetmask(addr, netmask): - msg = "%r is not a valid netmask" - with self.assertNetmaskError(msg % netmask): + msg = "%r is not a valid netmask" % netmask + with self.assertNetmaskError(re.escape(msg)): self.factory("%s/%s" % (addr, netmask)) assertBadNetmask("1.2.3.4", "") + assertBadNetmask("1.2.3.4", "-1") + assertBadNetmask("1.2.3.4", "+1") + assertBadNetmask("1.2.3.4", " 1 ") + assertBadNetmask("1.2.3.4", "0x1") assertBadNetmask("1.2.3.4", "33") assertBadNetmask("1.2.3.4", "254.254.255.256") + assertBadNetmask("1.2.3.4", "1.a.2.3") assertBadNetmask("1.1.1.1", "254.xyz.2.3") assertBadNetmask("1.1.1.1", "240.255.0.0") + assertBadNetmask("1.1.1.1", "255.254.128.0") + assertBadNetmask("1.1.1.1", "0.1.127.255") assertBadNetmask("1.1.1.1", "pudding") + assertBadNetmask("1.1.1.1", "::") + + def test_pickle(self): + self.pickle_test('192.0.2.0/27') + self.pickle_test('192.0.2.0/31') # IPV4LENGTH - 1 + self.pickle_test('192.0.2.0') # IPV4LENGTH + class InterfaceTestCase_v4(BaseTestCase, NetmaskTestMixin_v4): factory = ipaddress.IPv4Interface + class NetworkTestCase_v4(BaseTestCase, NetmaskTestMixin_v4): factory = ipaddress.IPv4Network @@ -438,21 +491,45 @@ def assertBadAddress(addr, details): assertBadAddress("10/8", "At least 3 parts") assertBadAddress("1234:axy::b", "Only hex digits") + def test_valid_netmask(self): + # We only support CIDR for IPv6, because expanded netmasks are not + # standard notation. + self.assertEqual(str(self.factory('2001:db8::/32')), '2001:db8::/32') + for i in range(0, 129): + # Generate and re-parse the CIDR format (trivial). + net_str = '::/%d' % i + self.assertEqual(str(self.factory(net_str)), net_str) + # Zero prefix is treated as decimal. + self.assertEqual(str(self.factory('::/0%d' % i)), net_str) + def test_netmask_errors(self): def assertBadNetmask(addr, netmask): - msg = "%r is not a valid netmask" - with self.assertNetmaskError(msg % netmask): + msg = "%r is not a valid netmask" % netmask + with self.assertNetmaskError(re.escape(msg)): self.factory("%s/%s" % (addr, netmask)) assertBadNetmask("::1", "") assertBadNetmask("::1", "::1") assertBadNetmask("::1", "1::") + assertBadNetmask("::1", "-1") + assertBadNetmask("::1", "+1") + assertBadNetmask("::1", " 1 ") + assertBadNetmask("::1", "0x1") assertBadNetmask("::1", "129") + assertBadNetmask("::1", "1.2.3.4") assertBadNetmask("::1", "pudding") + assertBadNetmask("::", "::") + + def test_pickle(self): + self.pickle_test('2001:db8::1000/124') + self.pickle_test('2001:db8::1000/127') # IPV6LENGTH - 1 + self.pickle_test('2001:db8::1000') # IPV6LENGTH + class InterfaceTestCase_v6(BaseTestCase, NetmaskTestMixin_v6): factory = ipaddress.IPv6Interface + class NetworkTestCase_v6(BaseTestCase, NetmaskTestMixin_v6): factory = ipaddress.IPv6Network @@ -476,6 +553,20 @@ def test_ip_network(self): self.assertFactoryError(ipaddress.ip_network, "network") +@functools.total_ordering +class LargestObject: + def __eq__(self, other): + return isinstance(other, LargestObject) + def __lt__(self, other): + return False + +@functools.total_ordering +class SmallestObject: + def __eq__(self, other): + return isinstance(other, SmallestObject) + def __gt__(self, other): + return False + class ComparisonTests(unittest.TestCase): v4addr = ipaddress.IPv4Address(1) @@ -529,6 +620,28 @@ def test_mixed_type_ordering(self): self.assertRaises(TypeError, lambda: lhs <= rhs) self.assertRaises(TypeError, lambda: lhs >= rhs) + def test_foreign_type_ordering(self): + other = object() + smallest = SmallestObject() + largest = LargestObject() + for obj in self.objects: + with self.assertRaises(TypeError): + obj < other + with self.assertRaises(TypeError): + obj > other + with self.assertRaises(TypeError): + obj <= other + with self.assertRaises(TypeError): + obj >= other + self.assertTrue(obj < largest) + self.assertFalse(obj > largest) + self.assertTrue(obj <= largest) + self.assertFalse(obj >= largest) + self.assertFalse(obj < smallest) + self.assertTrue(obj > smallest) + self.assertFalse(obj <= smallest) + self.assertTrue(obj >= smallest) + def test_mixed_type_key(self): # with get_mixed_type_key, you can sort addresses and network. v4_ordered = [self.v4addr, self.v4net, self.v4intf] @@ -549,7 +662,7 @@ def test_incompatible_versions(self): v4addr = ipaddress.ip_address('1.1.1.1') v4net = ipaddress.ip_network('1.1.1.1') v6addr = ipaddress.ip_address('::1') - v6net = ipaddress.ip_address('::1') + v6net = ipaddress.ip_network('::1') self.assertRaises(TypeError, v4addr.__lt__, v6addr) self.assertRaises(TypeError, v4addr.__gt__, v6addr) @@ -562,7 +675,6 @@ def test_incompatible_versions(self): self.assertRaises(TypeError, v6net.__gt__, v4net) - class IpaddrUnitTest(unittest.TestCase): def setUp(self): @@ -582,6 +694,119 @@ def testRepr(self): self.assertEqual("IPv6Interface('::1/128')", repr(ipaddress.IPv6Interface('::1'))) + # issue #16531: constructing IPv4Network from a (address, mask) tuple + def testIPv4Tuple(self): + # /32 + ip = ipaddress.IPv4Address('192.0.2.1') + net = ipaddress.IPv4Network('192.0.2.1/32') + self.assertEqual(ipaddress.IPv4Network(('192.0.2.1', 32)), net) + self.assertEqual(ipaddress.IPv4Network((ip, 32)), net) + self.assertEqual(ipaddress.IPv4Network((3221225985, 32)), net) + self.assertEqual(ipaddress.IPv4Network(('192.0.2.1', + '255.255.255.255')), net) + self.assertEqual(ipaddress.IPv4Network((ip, + '255.255.255.255')), net) + self.assertEqual(ipaddress.IPv4Network((3221225985, + '255.255.255.255')), net) + # strict=True and host bits set + with self.assertRaises(ValueError): + ipaddress.IPv4Network(('192.0.2.1', 24)) + with self.assertRaises(ValueError): + ipaddress.IPv4Network((ip, 24)) + with self.assertRaises(ValueError): + ipaddress.IPv4Network((3221225985, 24)) + with self.assertRaises(ValueError): + ipaddress.IPv4Network(('192.0.2.1', '255.255.255.0')) + with self.assertRaises(ValueError): + ipaddress.IPv4Network((ip, '255.255.255.0')) + with self.assertRaises(ValueError): + ipaddress.IPv4Network((3221225985, '255.255.255.0')) + # strict=False and host bits set + net = ipaddress.IPv4Network('192.0.2.0/24') + self.assertEqual(ipaddress.IPv4Network(('192.0.2.1', 24), + strict=False), net) + self.assertEqual(ipaddress.IPv4Network((ip, 24), + strict=False), net) + self.assertEqual(ipaddress.IPv4Network((3221225985, 24), + strict=False), net) + self.assertEqual(ipaddress.IPv4Network(('192.0.2.1', + '255.255.255.0'), + strict=False), net) + self.assertEqual(ipaddress.IPv4Network((ip, + '255.255.255.0'), + strict=False), net) + self.assertEqual(ipaddress.IPv4Network((3221225985, + '255.255.255.0'), + strict=False), net) + + # /24 + ip = ipaddress.IPv4Address('192.0.2.0') + net = ipaddress.IPv4Network('192.0.2.0/24') + self.assertEqual(ipaddress.IPv4Network(('192.0.2.0', + '255.255.255.0')), net) + self.assertEqual(ipaddress.IPv4Network((ip, + '255.255.255.0')), net) + self.assertEqual(ipaddress.IPv4Network((3221225984, + '255.255.255.0')), net) + self.assertEqual(ipaddress.IPv4Network(('192.0.2.0', 24)), net) + self.assertEqual(ipaddress.IPv4Network((ip, 24)), net) + self.assertEqual(ipaddress.IPv4Network((3221225984, 24)), net) + + self.assertEqual(ipaddress.IPv4Interface(('192.0.2.1', 24)), + ipaddress.IPv4Interface('192.0.2.1/24')) + self.assertEqual(ipaddress.IPv4Interface((3221225985, 24)), + ipaddress.IPv4Interface('192.0.2.1/24')) + + # issue #16531: constructing IPv6Network from a (address, mask) tuple + def testIPv6Tuple(self): + # /128 + ip = ipaddress.IPv6Address('2001:db8::') + net = ipaddress.IPv6Network('2001:db8::/128') + self.assertEqual(ipaddress.IPv6Network(('2001:db8::', '128')), + net) + self.assertEqual(ipaddress.IPv6Network( + (42540766411282592856903984951653826560, 128)), + net) + self.assertEqual(ipaddress.IPv6Network((ip, '128')), + net) + ip = ipaddress.IPv6Address('2001:db8::') + net = ipaddress.IPv6Network('2001:db8::/96') + self.assertEqual(ipaddress.IPv6Network(('2001:db8::', '96')), + net) + self.assertEqual(ipaddress.IPv6Network( + (42540766411282592856903984951653826560, 96)), + net) + self.assertEqual(ipaddress.IPv6Network((ip, '96')), + net) + + # strict=True and host bits set + ip = ipaddress.IPv6Address('2001:db8::1') + with self.assertRaises(ValueError): + ipaddress.IPv6Network(('2001:db8::1', 96)) + with self.assertRaises(ValueError): + ipaddress.IPv6Network(( + 42540766411282592856903984951653826561, 96)) + with self.assertRaises(ValueError): + ipaddress.IPv6Network((ip, 96)) + # strict=False and host bits set + net = ipaddress.IPv6Network('2001:db8::/96') + self.assertEqual(ipaddress.IPv6Network(('2001:db8::1', 96), + strict=False), + net) + self.assertEqual(ipaddress.IPv6Network( + (42540766411282592856903984951653826561, 96), + strict=False), + net) + self.assertEqual(ipaddress.IPv6Network((ip, 96), strict=False), + net) + + # /96 + self.assertEqual(ipaddress.IPv6Interface(('2001:db8::1', '96')), + ipaddress.IPv6Interface('2001:db8::1/96')) + self.assertEqual(ipaddress.IPv6Interface( + (42540766411282592856903984951653826561, '96')), + ipaddress.IPv6Interface('2001:db8::1/96')) + # issue57 def testAddressIntMath(self): self.assertEqual(ipaddress.IPv4Address('1.1.1.1') + 255, @@ -602,20 +827,18 @@ def testInvalidIntToBytes(self): 2 ** ipaddress.IPV6LENGTH) def testInternals(self): - first, last = ipaddress._find_address_range([ - ipaddress.IPv4Address('10.10.10.10'), - ipaddress.IPv4Address('10.10.10.12')]) - self.assertEqual(first, last) + ip1 = ipaddress.IPv4Address('10.10.10.10') + ip2 = ipaddress.IPv4Address('10.10.10.11') + ip3 = ipaddress.IPv4Address('10.10.10.12') + self.assertEqual(list(ipaddress._find_address_range([ip1])), + [(ip1, ip1)]) + self.assertEqual(list(ipaddress._find_address_range([ip1, ip3])), + [(ip1, ip1), (ip3, ip3)]) + self.assertEqual(list(ipaddress._find_address_range([ip1, ip2, ip3])), + [(ip1, ip3)]) self.assertEqual(128, ipaddress._count_righthand_zero_bits(0, 128)) self.assertEqual("IPv4Network('1.2.3.0/24')", repr(self.ipv4_network)) - def testMissingAddressVersion(self): - class Broken(ipaddress._BaseAddress): - pass - broken = Broken('127.0.0.1') - with self.assertRaisesRegex(NotImplementedError, "Broken.*version"): - broken.version - def testMissingNetworkVersion(self): class Broken(ipaddress._BaseNetwork): pass @@ -694,16 +917,14 @@ def testGetNetmask(self): def testZeroNetmask(self): ipv4_zero_netmask = ipaddress.IPv4Interface('1.2.3.4/0') self.assertEqual(int(ipv4_zero_netmask.network.netmask), 0) - self.assertTrue(ipv4_zero_netmask.network._is_valid_netmask( - str(0))) + self.assertEqual(ipv4_zero_netmask._prefix_from_prefix_string('0'), 0) self.assertTrue(ipv4_zero_netmask._is_valid_netmask('0')) self.assertTrue(ipv4_zero_netmask._is_valid_netmask('0.0.0.0')) self.assertFalse(ipv4_zero_netmask._is_valid_netmask('invalid')) ipv6_zero_netmask = ipaddress.IPv6Interface('::1/0') self.assertEqual(int(ipv6_zero_netmask.network.netmask), 0) - self.assertTrue(ipv6_zero_netmask.network._is_valid_netmask( - str(0))) + self.assertEqual(ipv6_zero_netmask._prefix_from_prefix_string('0'), 0) def testIPv4NetAndHostmasks(self): net = self.ipv4_network @@ -719,7 +940,7 @@ def testIPv4NetAndHostmasks(self): self.assertFalse(net._is_hostmask('1.2.3.4')) net = ipaddress.IPv4Network('127.0.0.0/0.0.0.255') - self.assertEqual(24, net.prefixlen) + self.assertEqual(net.prefixlen, 24) def testGetBroadcast(self): self.assertEqual(int(self.ipv4_network.broadcast_address), 16909311) @@ -877,13 +1098,13 @@ def testGetNum_Addresses(self): 36893488147419103232) def testContains(self): - self.assertTrue(ipaddress.IPv4Interface('1.2.3.128/25') in - self.ipv4_network) - self.assertFalse(ipaddress.IPv4Interface('1.2.4.1/24') in + self.assertIn(ipaddress.IPv4Interface('1.2.3.128/25'), + self.ipv4_network) + self.assertNotIn(ipaddress.IPv4Interface('1.2.4.1/24'), self.ipv4_network) # We can test addresses and string as well. addr1 = ipaddress.IPv4Address('1.2.3.37') - self.assertTrue(addr1 in self.ipv4_network) + self.assertIn(addr1, self.ipv4_network) # issue 61, bad network comparison on like-ip'd network objects # with identical broadcast addresses. self.assertFalse(ipaddress.IPv4Network('1.1.0.0/16').__contains__( @@ -1199,10 +1420,10 @@ def testNetworkComparison(self): unsorted = [ip4, ip1, ip3, ip2] unsorted.sort() self.assertEqual(sorted, unsorted) - self.assertRaises(TypeError, ip1.__lt__, - ipaddress.ip_address('10.10.10.0')) - self.assertRaises(TypeError, ip2.__lt__, - ipaddress.ip_address('10.10.10.0')) + self.assertIs(ip1.__lt__(ipaddress.ip_address('10.10.10.0')), + NotImplemented) + self.assertIs(ip2.__lt__(ipaddress.ip_address('10.10.10.0')), + NotImplemented) # <=, >= self.assertTrue(ipaddress.ip_network('1.1.1.1') <= @@ -1271,11 +1492,6 @@ def testPacked(self): self.assertEqual(ipaddress.IPv6Interface('::1:0:0:0:0').packed, b'\x00' * 6 + b'\x00\x01' + b'\x00' * 8) - def testIpStrFromPrefixlen(self): - ipv4 = ipaddress.IPv4Interface('1.2.3.4/24') - self.assertEqual(ipv4._ip_string_from_prefix(), '255.255.255.0') - self.assertEqual(ipv4._ip_string_from_prefix(28), '255.255.255.240') - def testIpType(self): ipv4net = ipaddress.ip_network('1.2.3.4') ipv4addr = ipaddress.ip_address('1.2.3.4') @@ -1473,20 +1689,14 @@ def testHash(self): dummy[self.ipv6_address] = None dummy[ip1] = None dummy[ip2] = None - self.assertTrue(self.ipv4_address in dummy) - self.assertTrue(ip2 in dummy) + self.assertIn(self.ipv4_address, dummy) + self.assertIn(ip2, dummy) def testIPBases(self): net = self.ipv4_network self.assertEqual('1.2.3.0/24', net.compressed) - self.assertEqual( - net._ip_int_from_prefix(24), - net._ip_int_from_prefix(None)) net = self.ipv6_network self.assertRaises(ValueError, net._string_from_ip_int, 2**128 + 1) - self.assertEqual( - self.ipv6_address._string_from_ip_int(self.ipv6_address._ip), - self.ipv6_address._string_from_ip_int(None)) def testIPv6NetworkHelpers(self): net = self.ipv6_network @@ -1560,6 +1770,14 @@ def testExplodeShortHandIpStr(self): addr3.exploded) self.assertEqual('192.168.178.1', addr4.exploded) + def testReversePointer(self): + addr1 = ipaddress.IPv4Address('127.0.0.1') + addr2 = ipaddress.IPv6Address('2001:db8::1') + self.assertEqual('1.0.0.127.in-addr.arpa', addr1.reverse_pointer) + self.assertEqual('1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.' + + 'b.d.0.1.0.0.2.ip6.arpa', + addr2.reverse_pointer) + def testIntRepresentation(self): self.assertEqual(16909060, int(self.ipv4_address)) self.assertEqual(42540616829182469433547762482097946625, @@ -1587,9 +1805,9 @@ def testWithStar(self): def testNetworkElementCaching(self): # V4 - make sure we're empty - self.assertFalse('network_address' in self.ipv4_network._cache) - self.assertFalse('broadcast_address' in self.ipv4_network._cache) - self.assertFalse('hostmask' in self.ipv4_network._cache) + self.assertNotIn('network_address', self.ipv4_network._cache) + self.assertNotIn('broadcast_address', self.ipv4_network._cache) + self.assertNotIn('hostmask', self.ipv4_network._cache) # V4 - populate and test self.assertEqual(self.ipv4_network.network_address, @@ -1600,12 +1818,12 @@ def testNetworkElementCaching(self): ipaddress.IPv4Address('0.0.0.255')) # V4 - check we're cached - self.assertTrue('broadcast_address' in self.ipv4_network._cache) - self.assertTrue('hostmask' in self.ipv4_network._cache) + self.assertIn('broadcast_address', self.ipv4_network._cache) + self.assertIn('hostmask', self.ipv4_network._cache) # V6 - make sure we're empty - self.assertFalse('broadcast_address' in self.ipv6_network._cache) - self.assertFalse('hostmask' in self.ipv6_network._cache) + self.assertNotIn('broadcast_address', self.ipv6_network._cache) + self.assertNotIn('hostmask', self.ipv6_network._cache) # V6 - populate and test self.assertEqual(self.ipv6_network.network_address, @@ -1625,11 +1843,10 @@ def testNetworkElementCaching(self): ipaddress.IPv6Address('::ffff:ffff:ffff:ffff')) # V6 - check we're cached - self.assertTrue('broadcast_address' in self.ipv6_network._cache) - self.assertTrue('hostmask' in self.ipv6_network._cache) - self.assertTrue( - 'broadcast_address' in self.ipv6_interface.network._cache) - self.assertTrue('hostmask' in self.ipv6_interface.network._cache) + self.assertIn('broadcast_address', self.ipv6_network._cache) + self.assertIn('hostmask', self.ipv6_network._cache) + self.assertIn('broadcast_address', self.ipv6_interface.network._cache) + self.assertIn('hostmask', self.ipv6_interface.network._cache) def testTeredo(self): # stolen from wikipedia diff --git a/Lib/test/test_iter.py b/Lib/test/test_iter.py index 43f8e1588bd4..e06f239ddab4 100644 --- a/Lib/test/test_iter.py +++ b/Lib/test/test_iter.py @@ -76,22 +76,23 @@ def check_for_loop(self, expr, seq, pickle=True): # Helper to check picklability def check_pickle(self, itorg, seq): - d = pickle.dumps(itorg) - it = pickle.loads(d) - # Cannot assert type equality because dict iterators unpickle as list - # iterators. - # self.assertEqual(type(itorg), type(it)) - self.assertTrue(isinstance(it, collections.abc.Iterator)) - self.assertEqual(list(it), seq) - - it = pickle.loads(d) - try: - next(it) - except StopIteration: - return - d = pickle.dumps(it) - it = pickle.loads(d) - self.assertEqual(list(it), seq[1:]) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + d = pickle.dumps(itorg, proto) + it = pickle.loads(d) + # Cannot assert type equality because dict iterators unpickle as list + # iterators. + # self.assertEqual(type(itorg), type(it)) + self.assertTrue(isinstance(it, collections.abc.Iterator)) + self.assertEqual(list(it), seq) + + it = pickle.loads(d) + try: + next(it) + except StopIteration: + continue + d = pickle.dumps(it, proto) + it = pickle.loads(d) + self.assertEqual(list(it), seq[1:]) # Test basic use of iter() function def test_iter_basic(self): diff --git a/Lib/test/test_itertools.py b/Lib/test/test_itertools.py index 2672b00c56f4..6a0130e6e0c3 100644 --- a/Lib/test/test_itertools.py +++ b/Lib/test/test_itertools.py @@ -1,7 +1,7 @@ import unittest from test import support from itertools import * -from weakref import proxy +import weakref from decimal import Decimal from fractions import Fraction import sys @@ -10,6 +10,8 @@ import copy import pickle from functools import reduce +import sys +import struct maxsize = support.MAX_Py_ssize_t minsize = -maxsize-1 @@ -72,9 +74,12 @@ def testR2(r): def underten(x): return x<10 +picklecopiers = [lambda s, proto=proto: pickle.loads(pickle.dumps(s, proto)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1)] + class TestBasicOps(unittest.TestCase): - def pickletest(self, it, stop=4, take=1, compare=None): + def pickletest(self, protocol, it, stop=4, take=1, compare=None): """Test that an iterator is the same after pickling, also when part-consumed""" def expand(it, i=0): # Recursively expand iterables, within sensible bounds @@ -89,7 +94,7 @@ def expand(it, i=0): return [expand(e, i+1) for e in l] # Test the initial copy against the original - dump = pickle.dumps(it) + dump = pickle.dumps(it, protocol) i2 = pickle.loads(dump) self.assertEqual(type(it), type(i2)) a, b = expand(it), expand(i2) @@ -107,7 +112,7 @@ def expand(it, i=0): took += 1 except StopIteration: pass #in case there is less data than 'take' - dump = pickle.dumps(i3) + dump = pickle.dumps(i3, protocol) i4 = pickle.loads(dump) a, b = expand(i3), expand(i4) self.assertEqual(a, b) @@ -141,7 +146,8 @@ def test_accumulate(self): [2, 16, 144, 720, 5040, 0, 0, 0, 0, 0]) with self.assertRaises(TypeError): list(accumulate(s, chr)) # unary-operation - self.pickletest(accumulate(range(10))) # test pickling + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.pickletest(proto, accumulate(range(10))) # test pickling def test_chain(self): @@ -166,9 +172,7 @@ def test_chain_from_iterable(self): self.assertRaises(TypeError, list, chain.from_iterable([2, 3])) def test_chain_reducible(self): - operators = [copy.deepcopy, - lambda s: pickle.loads(pickle.dumps(s))] - for oper in operators: + for oper in [copy.deepcopy] + picklecopiers: it = chain('abc', 'def') self.assertEqual(list(oper(it)), list('abcdef')) self.assertEqual(next(it), 'a') @@ -177,7 +181,8 @@ def test_chain_reducible(self): self.assertEqual(list(oper(chain(''))), []) self.assertEqual(take(4, oper(chain('abc', 'def'))), list('abcd')) self.assertRaises(TypeError, list, oper(chain(2, 3))) - self.pickletest(chain('abc', 'def'), compare=list('abcdef')) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.pickletest(proto, chain('abc', 'def'), compare=list('abcdef')) def test_combinations(self): self.assertRaises(TypeError, combinations, 'abc') # missing r argument @@ -185,7 +190,7 @@ def test_combinations(self): self.assertRaises(TypeError, combinations, None) # pool is not iterable self.assertRaises(ValueError, combinations, 'abc', -2) # r is negative - for op in (lambda a:a, lambda a:pickle.loads(pickle.dumps(a))): + for op in [lambda a:a] + picklecopiers: self.assertEqual(list(op(combinations('abc', 32))), []) # r > n self.assertEqual(list(op(combinations('ABCD', 2))), @@ -256,7 +261,13 @@ def combinations3(iterable, r): self.assertEqual(result, list(combinations2(values, r))) # matches second pure python version self.assertEqual(result, list(combinations3(values, r))) # matches second pure python version - self.pickletest(combinations(values, r)) # test pickling + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.pickletest(proto, combinations(values, r)) # test pickling + + @support.bigaddrspacetest + def test_combinations_overflow(self): + with self.assertRaises((OverflowError, MemoryError)): + combinations("AA", 2**29) # Test implementation detail: tuple re-use @support.impl_detail("tuple reuse is specific to CPython") @@ -271,7 +282,7 @@ def test_combinations_with_replacement(self): self.assertRaises(TypeError, cwr, None) # pool is not iterable self.assertRaises(ValueError, cwr, 'abc', -2) # r is negative - for op in (lambda a:a, lambda a:pickle.loads(pickle.dumps(a))): + for op in [lambda a:a] + picklecopiers: self.assertEqual(list(op(cwr('ABC', 2))), [('A','A'), ('A','B'), ('A','C'), ('B','B'), ('B','C'), ('C','C')]) testIntermediate = cwr('ABC', 2) @@ -337,10 +348,15 @@ def numcombs(n, r): self.assertEqual(result, list(cwr1(values, r))) # matches first pure python version self.assertEqual(result, list(cwr2(values, r))) # matches second pure python version - self.pickletest(cwr(values,r)) # test pickling + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.pickletest(proto, cwr(values,r)) # test pickling - # Test implementation detail: tuple re-use + @support.bigaddrspacetest + def test_combinations_with_replacement_overflow(self): + with self.assertRaises((OverflowError, MemoryError)): + combinations_with_replacement("AA", 2**30) + # Test implementation detail: tuple re-use @support.impl_detail("tuple reuse is specific to CPython") def test_combinations_with_replacement_tuple_reuse(self): cwr = combinations_with_replacement @@ -407,9 +423,15 @@ def permutations2(iterable, r=None): self.assertEqual(result, list(permutations(values, None))) # test r as None self.assertEqual(result, list(permutations(values))) # test default r - self.pickletest(permutations(values, r)) # test pickling + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.pickletest(proto, permutations(values, r)) # test pickling + + @support.bigaddrspacetest + def test_permutations_overflow(self): + with self.assertRaises((OverflowError, MemoryError)): + permutations("A", 2**30) - @support.impl_detail("tuple resuse is CPython specific") + @support.impl_detail("tuple reuse is specific to CPython") def test_permutations_tuple_reuse(self): self.assertEqual(len(set(map(id, permutations('abcde', 3)))), 1) self.assertNotEqual(len(set(map(id, list(permutations('abcde', 3))))), 1) @@ -464,7 +486,7 @@ def test_compress(self): self.assertRaises(TypeError, compress, range(6), None) # too many args # check copy, deepcopy, pickle - for op in (lambda a:copy.copy(a), lambda a:copy.deepcopy(a), lambda a:pickle.loads(pickle.dumps(a))): + for op in [lambda a:copy.copy(a), lambda a:copy.deepcopy(a)] + picklecopiers: for data, selectors, result1, result2 in [ ('ABCDEF', [1,0,1,0,1,1], 'ACEF', 'CEF'), ('ABCDEF', [0,0,0,0,0,0], '', ''), @@ -515,7 +537,8 @@ def test_count(self): c = count(value) self.assertEqual(next(copy.copy(c)), value) self.assertEqual(next(copy.deepcopy(c)), value) - self.pickletest(count(value)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.pickletest(proto, count(value)) #check proper internal error handling for large "step' sizes count(1, maxsize+5); sys.exc_info() @@ -562,7 +585,8 @@ def test_count_with_stride(self): else: r2 = ('count(%r, %r)' % (i, j)) self.assertEqual(r1, r2) - self.pickletest(count(i, j)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.pickletest(proto, count(i, j)) def test_cycle(self): self.assertEqual(take(10, cycle('abc')), list('abcabcabca')) @@ -578,10 +602,16 @@ def test_cycle(self): #an internal iterator #self.assertEqual(take(10, copy.copy(c)), list('bcabcabcab')) self.assertEqual(take(10, copy.deepcopy(c)), list('bcabcabcab')) - self.assertEqual(take(10, pickle.loads(pickle.dumps(c))), list('bcabcabcab')) - next(c) - self.assertEqual(take(10, pickle.loads(pickle.dumps(c))), list('cabcabcabc')) - self.pickletest(cycle('abc')) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.assertEqual(take(10, pickle.loads(pickle.dumps(c, proto))), + list('bcabcabcab')) + next(c) + self.assertEqual(take(10, pickle.loads(pickle.dumps(c, proto))), + list('cabcabcabc')) + next(c) + next(c) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.pickletest(proto, cycle('abc')) def test_groupby(self): # Check whether it accepts arguments correctly @@ -602,12 +632,13 @@ def test_groupby(self): self.assertEqual(s, dup) # Check normal pickled - dup = [] - for k, g in pickle.loads(pickle.dumps(groupby(s, testR))): - for elem in g: - self.assertEqual(k, elem[0]) - dup.append(elem) - self.assertEqual(s, dup) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + dup = [] + for k, g in pickle.loads(pickle.dumps(groupby(s, testR), proto)): + for elem in g: + self.assertEqual(k, elem[0]) + dup.append(elem) + self.assertEqual(s, dup) # Check nested case dup = [] @@ -620,14 +651,15 @@ def test_groupby(self): self.assertEqual(s, dup) # Check nested and pickled - dup = [] - for k, g in pickle.loads(pickle.dumps(groupby(s, testR))): - for ik, ig in pickle.loads(pickle.dumps(groupby(g, testR2))): - for elem in ig: - self.assertEqual(k, elem[0]) - self.assertEqual(ik, elem[2]) - dup.append(elem) - self.assertEqual(s, dup) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + dup = [] + for k, g in pickle.loads(pickle.dumps(groupby(s, testR), proto)): + for ik, ig in pickle.loads(pickle.dumps(groupby(g, testR2), proto)): + for elem in ig: + self.assertEqual(k, elem[0]) + self.assertEqual(ik, elem[2]) + dup.append(elem) + self.assertEqual(s, dup) # Check case where inner iterator is not used @@ -709,12 +741,14 @@ def test_filter(self): self.assertEqual(list(copy.copy(c)), ans) c = filter(isEven, range(6)) self.assertEqual(list(copy.deepcopy(c)), ans) - c = filter(isEven, range(6)) - self.assertEqual(list(pickle.loads(pickle.dumps(c))), ans) - next(c) - self.assertEqual(list(pickle.loads(pickle.dumps(c))), ans[1:]) - c = filter(isEven, range(6)) - self.pickletest(c) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + c = filter(isEven, range(6)) + self.assertEqual(list(pickle.loads(pickle.dumps(c, proto))), ans) + next(c) + self.assertEqual(list(pickle.loads(pickle.dumps(c, proto))), ans[1:]) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + c = filter(isEven, range(6)) + self.pickletest(proto, c) def test_filterfalse(self): self.assertEqual(list(filterfalse(isEven, range(6))), [1,3,5]) @@ -726,7 +760,8 @@ def test_filterfalse(self): self.assertRaises(TypeError, filterfalse, lambda x:x, range(6), 7) self.assertRaises(TypeError, filterfalse, isEven, 3) self.assertRaises(TypeError, next, filterfalse(range(6), range(6))) - self.pickletest(filterfalse(isEven, range(6))) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.pickletest(proto, filterfalse(isEven, range(6))) def test_zip(self): # XXX This is rather silly now that builtin zip() calls zip()... @@ -758,15 +793,18 @@ def test_zip_tuple_reuse(self): ans = [(x,y) for x, y in copy.deepcopy(zip('abc',count()))] self.assertEqual(ans, [('a', 0), ('b', 1), ('c', 2)]) - ans = [(x,y) for x, y in pickle.loads(pickle.dumps(zip('abc',count())))] - self.assertEqual(ans, [('a', 0), ('b', 1), ('c', 2)]) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + ans = [(x,y) for x, y in pickle.loads(pickle.dumps(zip('abc',count()), proto))] + self.assertEqual(ans, [('a', 0), ('b', 1), ('c', 2)]) - testIntermediate = zip('abc',count()) - next(testIntermediate) - ans = [(x,y) for x, y in pickle.loads(pickle.dumps(testIntermediate))] - self.assertEqual(ans, [('b', 1), ('c', 2)]) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + testIntermediate = zip('abc',count()) + next(testIntermediate) + ans = [(x,y) for x, y in pickle.loads(pickle.dumps(testIntermediate, proto))] + self.assertEqual(ans, [('b', 1), ('c', 2)]) - self.pickletest(zip('abc', count())) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.pickletest(proto, zip('abc', count())) def test_ziplongest(self): for args in [ @@ -818,10 +856,11 @@ def test_zip_longest_tuple_reuse(self): self.assertEqual(len(dict.fromkeys(ids)), len(ids)) def test_zip_longest_pickling(self): - self.pickletest(zip_longest("abc", "def")) - self.pickletest(zip_longest("abc", "defgh")) - self.pickletest(zip_longest("abc", "defgh", fillvalue=1)) - self.pickletest(zip_longest("", "defgh")) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.pickletest(proto, zip_longest("abc", "def")) + self.pickletest(proto, zip_longest("abc", "defgh")) + self.pickletest(proto, zip_longest("abc", "defgh", fillvalue=1)) + self.pickletest(proto, zip_longest("", "defgh")) def test_bug_7244(self): @@ -921,6 +960,11 @@ def product2(*args, **kwds): args = map(iter, args) self.assertEqual(len(list(product(*args))), expected_len) + @support.bigaddrspacetest + def test_product_overflow(self): + with self.assertRaises((OverflowError, MemoryError)): + product(*(['ab']*2**5), repeat=2**25) + @support.impl_detail("tuple reuse is specific to CPython") def test_product_tuple_reuse(self): self.assertEqual(len(set(map(id, product('abc', 'def')))), 1) @@ -938,7 +982,8 @@ def test_product_pickling(self): ]: self.assertEqual(list(copy.copy(product(*args))), result) self.assertEqual(list(copy.deepcopy(product(*args))), result) - self.pickletest(product(*args)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.pickletest(proto, product(*args)) def test_repeat(self): self.assertEqual(list(repeat(object='a', times=3)), ['a', 'a', 'a']) @@ -963,7 +1008,14 @@ def test_repeat(self): self.assertEqual(next(c), 'a') self.assertEqual(take(2, copy.copy(c)), list('a' * 2)) self.assertEqual(take(2, copy.deepcopy(c)), list('a' * 2)) - self.pickletest(repeat(object='a', times=10)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.pickletest(proto, repeat(object='a', times=10)) + + def test_repeat_with_negative_times(self): + self.assertEqual(repr(repeat('a', -1)), "repeat('a', 0)") + self.assertEqual(repr(repeat('a', -2)), "repeat('a', 0)") + self.assertEqual(repr(repeat('a', times=-1)), "repeat('a', 0)") + self.assertEqual(repr(repeat('a', times=-2)), "repeat('a', 0)") def test_map(self): self.assertEqual(list(map(operator.pow, range(3), range(1,7))), @@ -991,8 +1043,9 @@ def test_map(self): c = map(tupleize, 'abc', count()) self.assertEqual(list(copy.deepcopy(c)), ans) - c = map(tupleize, 'abc', count()) - self.pickletest(c) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + c = map(tupleize, 'abc', count()) + self.pickletest(proto, c) def test_starmap(self): self.assertEqual(list(starmap(operator.pow, zip(range(3), range(1,7)))), @@ -1017,8 +1070,9 @@ def test_starmap(self): c = starmap(operator.pow, zip(range(3), range(1,7))) self.assertEqual(list(copy.deepcopy(c)), ans) - c = starmap(operator.pow, zip(range(3), range(1,7))) - self.pickletest(c) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + c = starmap(operator.pow, zip(range(3), range(1,7))) + self.pickletest(proto, c) def test_islice(self): for args in [ # islice(args) should agree with range(args) @@ -1083,7 +1137,18 @@ def test_islice(self): list(range(*args))) self.assertEqual(list(copy.deepcopy(islice(range(100), *args))), list(range(*args))) - self.pickletest(islice(range(100), *args)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.pickletest(proto, islice(range(100), *args)) + + # Issue #21321: check source iterator is not referenced + # from islice() after the latter has been exhausted + it = (x for x in (1, 2)) + wr = weakref.ref(it) + it = islice(it, 1) + self.assertIsNotNone(wr()) + list(it) # exhaust the iterator + support.gc_collect() + self.assertIsNone(wr()) def test_takewhile(self): data = [1, 3, 5, 20, 2, 4, 6, 8] @@ -1102,7 +1167,8 @@ def test_takewhile(self): self.assertEqual(list(copy.copy(takewhile(underten, data))), [1, 3, 5]) self.assertEqual(list(copy.deepcopy(takewhile(underten, data))), [1, 3, 5]) - self.pickletest(takewhile(underten, data)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.pickletest(proto, takewhile(underten, data)) def test_dropwhile(self): data = [1, 3, 5, 20, 2, 4, 6, 8] @@ -1118,7 +1184,8 @@ def test_dropwhile(self): self.assertEqual(list(copy.copy(dropwhile(underten, data))), [20, 2, 4, 6, 8]) self.assertEqual(list(copy.deepcopy(dropwhile(underten, data))), [20, 2, 4, 6, 8]) - self.pickletest(dropwhile(underten, data)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.pickletest(proto, dropwhile(underten, data)) def test_tee(self): n = 200 @@ -1201,7 +1268,7 @@ def test_tee(self): # test that tee objects are weak referencable a, b = tee(range(10)) - p = proxy(a) + p = weakref.proxy(a) self.assertEqual(getattr(p, '__class__'), type(b)) del a self.assertRaises(ReferenceError, getattr, p, '__class__') @@ -1262,10 +1329,11 @@ def test_tee(self): self.assertEqual(list(b), long_ans[60:]) # check pickle - self.pickletest(iter(tee('abc'))) - a, b = tee('abc') - self.pickletest(a, compare=ans) - self.pickletest(b, compare=ans) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.pickletest(proto, iter(tee('abc'))) + a, b = tee('abc') + self.pickletest(proto, a, compare=ans) + self.pickletest(proto, b, compare=ans) # Issue 13454: Crash when deleting backward iterator from tee() def test_tee_del_backward(self): @@ -1305,11 +1373,14 @@ def test_accumulate_reducible(self): # check copy, deepcopy, pickle data = [1, 2, 3, 4, 5] accumulated = [1, 3, 6, 10, 15] - it = accumulate(data) - self.assertEqual(list(pickle.loads(pickle.dumps(it))), accumulated[:]) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + it = accumulate(data) + self.assertEqual(list(pickle.loads(pickle.dumps(it, proto))), accumulated[:]) + self.assertEqual(next(it), 1) + self.assertEqual(list(pickle.loads(pickle.dumps(it, proto))), accumulated[1:]) + it = accumulate(data) self.assertEqual(next(it), 1) - self.assertEqual(list(pickle.loads(pickle.dumps(it))), accumulated[1:]) self.assertEqual(list(copy.deepcopy(it)), accumulated[1:]) self.assertEqual(list(copy.copy(it)), accumulated[1:]) @@ -1730,8 +1801,15 @@ class LengthTransparency(unittest.TestCase): def test_repeat(self): self.assertEqual(operator.length_hint(repeat(None, 50)), 50) + self.assertEqual(operator.length_hint(repeat(None, 0)), 0) self.assertEqual(operator.length_hint(repeat(None), 12), 12) + def test_repeat_with_negative_times(self): + self.assertEqual(operator.length_hint(repeat(None, -1)), 0) + self.assertEqual(operator.length_hint(repeat(None, -2)), 0) + self.assertEqual(operator.length_hint(repeat(None, times=-1)), 0) + self.assertEqual(operator.length_hint(repeat(None, times=-2)), 0) + class RegressionTests(unittest.TestCase): def test_sf_793826(self): @@ -1778,8 +1856,6 @@ def gen2(x): hist.append(3) yield 2 hist.append(4) - if x: - raise StopIteration hist = [] self.assertRaises(AssertionError, list, chain(gen1(), gen2(False))) @@ -1807,6 +1883,44 @@ def __init__(self, newarg=None, *args): # we expect type errors because of wrong argument count self.assertNotIn("does not take keyword arguments", err.args[0]) +@support.cpython_only +class SizeofTest(unittest.TestCase): + def setUp(self): + self.ssize_t = struct.calcsize('n') + + check_sizeof = support.check_sizeof + + def test_product_sizeof(self): + basesize = support.calcobjsize('3Pi') + check = self.check_sizeof + check(product('ab', '12'), basesize + 2 * self.ssize_t) + check(product(*(('abc',) * 10)), basesize + 10 * self.ssize_t) + + def test_combinations_sizeof(self): + basesize = support.calcobjsize('3Pni') + check = self.check_sizeof + check(combinations('abcd', 3), basesize + 3 * self.ssize_t) + check(combinations(range(10), 4), basesize + 4 * self.ssize_t) + + def test_combinations_with_replacement_sizeof(self): + cwr = combinations_with_replacement + basesize = support.calcobjsize('3Pni') + check = self.check_sizeof + check(cwr('abcd', 3), basesize + 3 * self.ssize_t) + check(cwr(range(10), 4), basesize + 4 * self.ssize_t) + + def test_permutations_sizeof(self): + basesize = support.calcobjsize('4Pni') + check = self.check_sizeof + check(permutations('abcd'), + basesize + 4 * self.ssize_t + 4 * self.ssize_t) + check(permutations('abcd', 3), + basesize + 4 * self.ssize_t + 3 * self.ssize_t) + check(permutations('abcde', 3), + basesize + 5 * self.ssize_t + 3 * self.ssize_t) + check(permutations(range(10), 4), + basesize + 10 * self.ssize_t + 4 * self.ssize_t) + libreftest = """ Doctest for examples in the library reference: libitertools.tex @@ -1958,6 +2072,19 @@ def __init__(self, newarg=None, *args): ... # unique_justseen('ABBCcAD', str.lower) --> A B C A D ... return map(next, map(itemgetter(1), groupby(iterable, key))) +>>> def first_true(iterable, default=False, pred=None): +... '''Returns the first true value in the iterable. +... +... If no true value is found, returns *default* +... +... If *pred* is not None, returns the first item +... for which pred(item) is true. +... +... ''' +... # first_true([a,b,c], x) --> a or b or c or x +... # first_true([a,b], x, f) --> a if f(a) else b if f(b) else x +... return next(filter(pred, iterable), default) + This is not part of the examples but it tests to make sure the definitions perform as purported. @@ -2035,6 +2162,9 @@ def __init__(self, newarg=None, *args): >>> list(unique_justseen('ABBCcAD', str.lower)) ['A', 'B', 'C', 'A', 'D'] +>>> first_true('ABC0DEF1', '9', str.isdigit) +'0' + """ __test__ = {'libreftest' : libreftest} @@ -2042,7 +2172,8 @@ def __init__(self, newarg=None, *args): def test_main(verbose=None): test_classes = (TestBasicOps, TestVariousIteratorArgs, TestGC, RegressionTests, LengthTransparency, - SubclassWithKwargsTest, TestExamples) + SubclassWithKwargsTest, TestExamples, + SizeofTest) support.run_unittest(*test_classes) # verify reference counting diff --git a/Lib/test/test_json/__init__.py b/Lib/test/test_json/__init__.py index f994f9b5896b..0807e6fb4f06 100644 --- a/Lib/test/test_json/__init__.py +++ b/Lib/test/test_json/__init__.py @@ -9,12 +9,15 @@ # import json with and without accelerations cjson = support.import_fresh_module('json', fresh=['_json']) pyjson = support.import_fresh_module('json', blocked=['_json']) +# JSONDecodeError is cached inside the _json module +cjson.JSONDecodeError = cjson.decoder.JSONDecodeError = json.JSONDecodeError # create two base classes that will be used by the other tests class PyTest(unittest.TestCase): json = pyjson loads = staticmethod(pyjson.loads) dumps = staticmethod(pyjson.dumps) + JSONDecodeError = staticmethod(pyjson.JSONDecodeError) @unittest.skipUnless(cjson, 'requires _json') class CTest(unittest.TestCase): @@ -22,6 +25,7 @@ class CTest(unittest.TestCase): json = cjson loads = staticmethod(cjson.loads) dumps = staticmethod(cjson.dumps) + JSONDecodeError = staticmethod(cjson.JSONDecodeError) # test PyTest and CTest checking if the functions come from the right module class TestPyTest(PyTest): @@ -42,23 +46,12 @@ def test_cjson(self): '_json') -here = os.path.dirname(__file__) - -def load_tests(*args): - suite = additional_tests() - loader = unittest.TestLoader() - for fn in os.listdir(here): - if fn.startswith("test") and fn.endswith(".py"): - modname = "test.test_json." + fn[:-3] - __import__(modname) - module = sys.modules[modname] - suite.addTests(loader.loadTestsFromModule(module)) - return suite - -def additional_tests(): +def load_tests(loader, _, pattern): suite = unittest.TestSuite() for mod in (json, json.encoder, json.decoder): suite.addTest(doctest.DocTestSuite(mod)) suite.addTest(TestPyTest('test_pyjson')) suite.addTest(TestCTest('test_cjson')) - return suite + + pkg_dir = os.path.dirname(__file__) + return support.load_package_tests(pkg_dir, loader, suite, pattern) diff --git a/Lib/test/test_json/test_decode.py b/Lib/test/test_json/test_decode.py index 35c02de88cc6..cc83b45e8b85 100644 --- a/Lib/test/test_json/test_decode.py +++ b/Lib/test/test_json/test_decode.py @@ -63,12 +63,12 @@ def test_keys_reuse(self): def test_extra_data(self): s = '[1, 2, 3]5' msg = 'Extra data' - self.assertRaisesRegex(ValueError, msg, self.loads, s) + self.assertRaisesRegex(self.JSONDecodeError, msg, self.loads, s) def test_invalid_escape(self): s = '["abc\\y"]' msg = 'escape' - self.assertRaisesRegex(ValueError, msg, self.loads, s) + self.assertRaisesRegex(self.JSONDecodeError, msg, self.loads, s) def test_invalid_input_type(self): msg = 'the JSON object must be str' @@ -80,10 +80,10 @@ def test_invalid_input_type(self): def test_string_with_utf8_bom(self): # see #18958 bom_json = "[1,2,3]".encode('utf-8-sig').decode('utf-8') - with self.assertRaises(ValueError) as cm: + with self.assertRaises(self.JSONDecodeError) as cm: self.loads(bom_json) self.assertIn('BOM', str(cm.exception)) - with self.assertRaises(ValueError) as cm: + with self.assertRaises(self.JSONDecodeError) as cm: self.json.load(StringIO(bom_json)) self.assertIn('BOM', str(cm.exception)) # make sure that the BOM is not detected in the middle of a string @@ -91,5 +91,9 @@ def test_string_with_utf8_bom(self): self.assertEqual(self.loads(bom_in_str), '\ufeff') self.assertEqual(self.json.load(StringIO(bom_in_str)), '\ufeff') + def test_negative_index(self): + d = self.json.JSONDecoder() + self.assertRaises(ValueError, d.raw_decode, 'a'*42, -50000) + class TestPyDecode(TestDecode, PyTest): pass class TestCDecode(TestDecode, CTest): pass diff --git a/Lib/test/test_json/test_encode_basestring_ascii.py b/Lib/test/test_json/test_encode_basestring_ascii.py index 480afd686e45..4bbc6c71489a 100644 --- a/Lib/test/test_json/test_encode_basestring_ascii.py +++ b/Lib/test/test_json/test_encode_basestring_ascii.py @@ -1,5 +1,6 @@ from collections import OrderedDict from test.test_json import PyTest, CTest +from test.support import bigaddrspacetest CASES = [ @@ -11,9 +12,6 @@ (' s p a c e d ', '" s p a c e d "'), ('\U0001d120', '"\\ud834\\udd20"'), ('\u03b1\u03a9', '"\\u03b1\\u03a9"'), - ('\u03b1\u03a9', '"\\u03b1\\u03a9"'), - ('\u03b1\u03a9', '"\\u03b1\\u03a9"'), - ('\u03b1\u03a9', '"\\u03b1\\u03a9"'), ("`1~!@#$%^&*()_+-={':[,]}|;.?", '"`1~!@#$%^&*()_+-={\':[,]}|;.?"'), ('\x08\x0c\n\r\t', '"\\b\\f\\n\\r\\t"'), ('\u0123\u4567\u89ab\ucdef\uabcd\uef4a', '"\\u0123\\u4567\\u89ab\\ucdef\\uabcd\\uef4a"'), @@ -41,4 +39,10 @@ def test_sorted_dict(self): class TestPyEncodeBasestringAscii(TestEncodeBasestringAscii, PyTest): pass -class TestCEncodeBasestringAscii(TestEncodeBasestringAscii, CTest): pass +class TestCEncodeBasestringAscii(TestEncodeBasestringAscii, CTest): + @bigaddrspacetest + def test_overflow(self): + size = (2**32)//6 + 1 + s = "\x00"*size + with self.assertRaises(OverflowError): + self.json.encoder.encode_basestring_ascii(s) diff --git a/Lib/test/test_json/test_fail.py b/Lib/test/test_json/test_fail.py index 7caafdbdddc7..95ff5b8d1ee8 100644 --- a/Lib/test/test_json/test_fail.py +++ b/Lib/test/test_json/test_fail.py @@ -87,7 +87,7 @@ def test_failures(self): continue try: self.loads(doc) - except ValueError: + except self.JSONDecodeError: pass else: self.fail("Expected failure for fail{0}.json: {1!r}".format(idx, doc)) @@ -124,10 +124,16 @@ def test_truncated_input(self): ('"spam', 'Unterminated string starting at', 0), ] for data, msg, idx in test_cases: - self.assertRaisesRegex(ValueError, - r'^{0}: line 1 column {1} \(char {2}\)'.format( - re.escape(msg), idx + 1, idx), - self.loads, data) + with self.assertRaises(self.JSONDecodeError) as cm: + self.loads(data) + err = cm.exception + self.assertEqual(err.msg, msg) + self.assertEqual(err.pos, idx) + self.assertEqual(err.lineno, 1) + self.assertEqual(err.colno, idx + 1) + self.assertEqual(str(err), + '%s: line 1 column %d (char %d)' % + (msg, idx + 1, idx)) def test_unexpected_data(self): test_cases = [ @@ -154,10 +160,16 @@ def test_unexpected_data(self): ('{"spam":42,}', 'Expecting property name enclosed in double quotes', 11), ] for data, msg, idx in test_cases: - self.assertRaisesRegex(ValueError, - r'^{0}: line 1 column {1} \(char {2}\)'.format( - re.escape(msg), idx + 1, idx), - self.loads, data) + with self.assertRaises(self.JSONDecodeError) as cm: + self.loads(data) + err = cm.exception + self.assertEqual(err.msg, msg) + self.assertEqual(err.pos, idx) + self.assertEqual(err.lineno, 1) + self.assertEqual(err.colno, idx + 1) + self.assertEqual(str(err), + '%s: line 1 column %d (char %d)' % + (msg, idx + 1, idx)) def test_extra_data(self): test_cases = [ @@ -171,11 +183,16 @@ def test_extra_data(self): ('"spam",42', 'Extra data', 6), ] for data, msg, idx in test_cases: - self.assertRaisesRegex(ValueError, - r'^{0}: line 1 column {1} - line 1 column {2}' - r' \(char {3} - {4}\)'.format( - re.escape(msg), idx + 1, len(data) + 1, idx, len(data)), - self.loads, data) + with self.assertRaises(self.JSONDecodeError) as cm: + self.loads(data) + err = cm.exception + self.assertEqual(err.msg, msg) + self.assertEqual(err.pos, idx) + self.assertEqual(err.lineno, 1) + self.assertEqual(err.colno, idx + 1) + self.assertEqual(str(err), + '%s: line 1 column %d (char %d)' % + (msg, idx + 1, idx)) def test_linecol(self): test_cases = [ @@ -185,10 +202,16 @@ def test_linecol(self): ('\n \n\n !', 4, 6, 10), ] for data, line, col, idx in test_cases: - self.assertRaisesRegex(ValueError, - r'^Expecting value: line {0} column {1}' - r' \(char {2}\)$'.format(line, col, idx), - self.loads, data) + with self.assertRaises(self.JSONDecodeError) as cm: + self.loads(data) + err = cm.exception + self.assertEqual(err.msg, 'Expecting value') + self.assertEqual(err.pos, idx) + self.assertEqual(err.lineno, line) + self.assertEqual(err.colno, col) + self.assertEqual(str(err), + 'Expecting value: line %s column %d (char %d)' % + (line, col, idx)) class TestPyFail(TestFail, PyTest): pass class TestCFail(TestFail, CTest): pass diff --git a/Lib/test/test_json/test_scanstring.py b/Lib/test/test_json/test_scanstring.py index 07f4358100da..2d3ee8a8bf0f 100644 --- a/Lib/test/test_json/test_scanstring.py +++ b/Lib/test/test_json/test_scanstring.py @@ -129,7 +129,7 @@ def test_bad_escapes(self): '"\\ud834\\u0X20"', ] for s in bad_escapes: - with self.assertRaises(ValueError, msg=s): + with self.assertRaises(self.JSONDecodeError, msg=s): scanstring(s, 1, True) def test_overflow(self): diff --git a/Lib/test/test_json/test_tool.py b/Lib/test/test_json/test_tool.py index 0c39e56837ba..bd63e2b31119 100644 --- a/Lib/test/test_json/test_tool.py +++ b/Lib/test/test_json/test_tool.py @@ -6,6 +6,7 @@ from test import support from test.script_helper import assert_python_ok + class TestTool(unittest.TestCase): data = """ @@ -15,7 +16,7 @@ class TestTool(unittest.TestCase): :"yes"} ] """ - expect = textwrap.dedent("""\ + expect_without_sort_keys = textwrap.dedent("""\ [ [ "blorpie" @@ -37,6 +38,28 @@ class TestTool(unittest.TestCase): ] """) + expect = textwrap.dedent("""\ + [ + [ + "blorpie" + ], + [ + "whoops" + ], + [], + "d-shtaeou", + "d-nthiouh", + "i-vhbjkhnth", + { + "nifty": 87 + }, + { + "morefield": false, + "field": "yes" + } + ] + """) + def test_stdin_stdout(self): with subprocess.Popen( (sys.executable, '-m', 'json.tool'), @@ -55,6 +78,7 @@ def _create_infile(self): def test_infile_stdout(self): infile = self._create_infile() rc, out, err = assert_python_ok('-m', 'json.tool', infile) + self.assertEqual(rc, 0) self.assertEqual(out.splitlines(), self.expect.encode().splitlines()) self.assertEqual(err, b'') @@ -65,5 +89,20 @@ def test_infile_outfile(self): self.addCleanup(os.remove, outfile) with open(outfile, "r") as fp: self.assertEqual(fp.read(), self.expect) + self.assertEqual(rc, 0) self.assertEqual(out, b'') self.assertEqual(err, b'') + + def test_help_flag(self): + rc, out, err = assert_python_ok('-m', 'json.tool', '-h') + self.assertEqual(rc, 0) + self.assertTrue(out.startswith(b'usage: ')) + self.assertEqual(err, b'') + + def test_sort_keys_flag(self): + infile = self._create_infile() + rc, out, err = assert_python_ok('-m', 'json.tool', '--sort-keys', infile) + self.assertEqual(rc, 0) + self.assertEqual(out.splitlines(), + self.expect_without_sort_keys.encode().splitlines()) + self.assertEqual(err, b'') diff --git a/Lib/test/test_keywordonlyarg.py b/Lib/test/test_keywordonlyarg.py index e4a44c1d8fdb..7f315d4cb41e 100644 --- a/Lib/test/test_keywordonlyarg.py +++ b/Lib/test/test_keywordonlyarg.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - """Unit tests for the keyword only argument specified in PEP 3102.""" __author__ = "Jiwon Seo" diff --git a/Lib/test/test_kqueue.py b/Lib/test/test_kqueue.py index bafdeba6ff13..2585ca6810b7 100644 --- a/Lib/test/test_kqueue.py +++ b/Lib/test/test_kqueue.py @@ -86,10 +86,35 @@ def test_create_event(self): self.assertEqual(ev, ev) self.assertNotEqual(ev, other) + # Issue 11973 + bignum = 0xffff + ev = select.kevent(0, 1, bignum) + self.assertEqual(ev.ident, 0) + self.assertEqual(ev.filter, 1) + self.assertEqual(ev.flags, bignum) + self.assertEqual(ev.fflags, 0) + self.assertEqual(ev.data, 0) + self.assertEqual(ev.udata, 0) + self.assertEqual(ev, ev) + self.assertNotEqual(ev, other) + + # Issue 11973 + bignum = 0xffffffff + ev = select.kevent(0, 1, 2, bignum) + self.assertEqual(ev.ident, 0) + self.assertEqual(ev.filter, 1) + self.assertEqual(ev.flags, 2) + self.assertEqual(ev.fflags, bignum) + self.assertEqual(ev.data, 0) + self.assertEqual(ev.udata, 0) + self.assertEqual(ev, ev) + self.assertNotEqual(ev, other) + + def test_queue_event(self): serverSocket = socket.socket() serverSocket.bind(('127.0.0.1', 0)) - serverSocket.listen(1) + serverSocket.listen() client = socket.socket() client.setblocking(False) try: diff --git a/Lib/test/test_lib2to3.py b/Lib/test/test_lib2to3.py index df4c37b2418d..5eaa5164d490 100644 --- a/Lib/test/test_lib2to3.py +++ b/Lib/test/test_lib2to3.py @@ -1,22 +1,5 @@ -# Skipping test_parser and test_all_fixers -# because of running -from lib2to3.tests import (test_fixers, test_pytree, test_util, test_refactor, - test_parser, - test_main as test_main_) +from lib2to3.tests import load_tests import unittest -from test.support import run_unittest - -def suite(): - tests = unittest.TestSuite() - loader = unittest.TestLoader() - for m in (test_fixers, test_pytree, test_util, test_refactor, test_parser, - test_main_): - tests.addTests(loader.loadTestsFromModule(m)) - return tests - -def test_main(): - run_unittest(suite()) - if __name__ == '__main__': - test_main() + unittest.main() diff --git a/Lib/test/test_list.py b/Lib/test/test_list.py index 5df27d30add4..3b94700bb9e3 100644 --- a/Lib/test/test_list.py +++ b/Lib/test/test_list.py @@ -74,29 +74,31 @@ def test_iterator_pickle(self): # Userlist iterators don't support pickling yet since # they are based on generators. data = self.type2test([4, 5, 6, 7]) - it = itorg = iter(data) - d = pickle.dumps(it) - it = pickle.loads(d) - self.assertEqual(type(itorg), type(it)) - self.assertEqual(self.type2test(it), self.type2test(data)) - - it = pickle.loads(d) - next(it) - d = pickle.dumps(it) - self.assertEqual(self.type2test(it), self.type2test(data)[1:]) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + it = itorg = iter(data) + d = pickle.dumps(it, proto) + it = pickle.loads(d) + self.assertEqual(type(itorg), type(it)) + self.assertEqual(self.type2test(it), self.type2test(data)) + + it = pickle.loads(d) + next(it) + d = pickle.dumps(it, proto) + self.assertEqual(self.type2test(it), self.type2test(data)[1:]) def test_reversed_pickle(self): data = self.type2test([4, 5, 6, 7]) - it = itorg = reversed(data) - d = pickle.dumps(it) - it = pickle.loads(d) - self.assertEqual(type(itorg), type(it)) - self.assertEqual(self.type2test(it), self.type2test(reversed(data))) - - it = pickle.loads(d) - next(it) - d = pickle.dumps(it) - self.assertEqual(self.type2test(it), self.type2test(reversed(data))[1:]) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + it = itorg = reversed(data) + d = pickle.dumps(it, proto) + it = pickle.loads(d) + self.assertEqual(type(itorg), type(it)) + self.assertEqual(self.type2test(it), self.type2test(reversed(data))) + + it = pickle.loads(d) + next(it) + d = pickle.dumps(it, proto) + self.assertEqual(self.type2test(it), self.type2test(reversed(data))[1:]) def test_no_comdat_folding(self): # Issue 8847: In the PGO build, the MSVC linker's COMDAT folding diff --git a/Lib/test/test_locale.py b/Lib/test/test_locale.py index 48bf36deecff..fae2c3dabb37 100644 --- a/Lib/test/test_locale.py +++ b/Lib/test/test_locale.py @@ -365,6 +365,117 @@ def test_strxfrm_with_diacritic(self): self.assertLess(locale.strxfrm('à'), locale.strxfrm('b')) +class NormalizeTest(unittest.TestCase): + def check(self, localename, expected): + self.assertEqual(locale.normalize(localename), expected, msg=localename) + + def test_locale_alias(self): + for localename, alias in locale.locale_alias.items(): + with self.subTest(locale=(localename, alias)): + self.check(localename, alias) + + def test_empty(self): + self.check('', '') + + def test_c(self): + self.check('c', 'C') + self.check('posix', 'C') + + def test_english(self): + self.check('en', 'en_US.ISO8859-1') + self.check('EN', 'en_US.ISO8859-1') + self.check('en.iso88591', 'en_US.ISO8859-1') + self.check('en_US', 'en_US.ISO8859-1') + self.check('en_us', 'en_US.ISO8859-1') + self.check('en_GB', 'en_GB.ISO8859-1') + self.check('en_US.UTF-8', 'en_US.UTF-8') + self.check('en_US.utf8', 'en_US.UTF-8') + self.check('en_US:UTF-8', 'en_US.UTF-8') + self.check('en_US.ISO8859-1', 'en_US.ISO8859-1') + self.check('en_US.US-ASCII', 'en_US.ISO8859-1') + self.check('en_US.88591', 'en_US.ISO8859-1') + self.check('en_US.885915', 'en_US.ISO8859-15') + self.check('english', 'en_EN.ISO8859-1') + self.check('english_uk.ascii', 'en_GB.ISO8859-1') + + def test_hyphenated_encoding(self): + self.check('az_AZ.iso88599e', 'az_AZ.ISO8859-9E') + self.check('az_AZ.ISO8859-9E', 'az_AZ.ISO8859-9E') + self.check('tt_RU.koi8c', 'tt_RU.KOI8-C') + self.check('tt_RU.KOI8-C', 'tt_RU.KOI8-C') + self.check('lo_LA.cp1133', 'lo_LA.IBM-CP1133') + self.check('lo_LA.ibmcp1133', 'lo_LA.IBM-CP1133') + self.check('lo_LA.IBM-CP1133', 'lo_LA.IBM-CP1133') + self.check('uk_ua.microsoftcp1251', 'uk_UA.CP1251') + self.check('uk_ua.microsoft-cp1251', 'uk_UA.CP1251') + self.check('ka_ge.georgianacademy', 'ka_GE.GEORGIAN-ACADEMY') + self.check('ka_GE.GEORGIAN-ACADEMY', 'ka_GE.GEORGIAN-ACADEMY') + self.check('cs_CZ.iso88592', 'cs_CZ.ISO8859-2') + self.check('cs_CZ.ISO8859-2', 'cs_CZ.ISO8859-2') + + def test_euro_modifier(self): + self.check('de_DE@euro', 'de_DE.ISO8859-15') + self.check('en_US.ISO8859-15@euro', 'en_US.ISO8859-15') + self.check('de_DE.utf8@euro', 'de_DE.UTF-8') + + def test_latin_modifier(self): + self.check('be_BY.UTF-8@latin', 'be_BY.UTF-8@latin') + self.check('sr_RS.UTF-8@latin', 'sr_RS.UTF-8@latin') + self.check('sr_RS.UTF-8@latn', 'sr_RS.UTF-8@latin') + + def test_valencia_modifier(self): + self.check('ca_ES.UTF-8@valencia', 'ca_ES.UTF-8@valencia') + self.check('ca_ES@valencia', 'ca_ES.ISO8859-15@valencia') + self.check('ca@valencia', 'ca_ES.ISO8859-1@valencia') + + def test_devanagari_modifier(self): + self.check('ks_IN.UTF-8@devanagari', 'ks_IN.UTF-8@devanagari') + self.check('ks_IN@devanagari', 'ks_IN.UTF-8@devanagari') + self.check('ks@devanagari', 'ks_IN.UTF-8@devanagari') + self.check('ks_IN.UTF-8', 'ks_IN.UTF-8') + self.check('ks_IN', 'ks_IN.UTF-8') + self.check('ks', 'ks_IN.UTF-8') + self.check('sd_IN.UTF-8@devanagari', 'sd_IN.UTF-8@devanagari') + self.check('sd_IN@devanagari', 'sd_IN.UTF-8@devanagari') + self.check('sd@devanagari', 'sd_IN.UTF-8@devanagari') + self.check('sd_IN.UTF-8', 'sd_IN.UTF-8') + self.check('sd_IN', 'sd_IN.UTF-8') + self.check('sd', 'sd_IN.UTF-8') + + def test_euc_encoding(self): + self.check('ja_jp.euc', 'ja_JP.eucJP') + self.check('ja_jp.eucjp', 'ja_JP.eucJP') + self.check('ko_kr.euc', 'ko_KR.eucKR') + self.check('ko_kr.euckr', 'ko_KR.eucKR') + self.check('zh_cn.euc', 'zh_CN.eucCN') + self.check('zh_tw.euc', 'zh_TW.eucTW') + self.check('zh_tw.euctw', 'zh_TW.eucTW') + + def test_japanese(self): + self.check('ja', 'ja_JP.eucJP') + self.check('ja.jis', 'ja_JP.JIS7') + self.check('ja.sjis', 'ja_JP.SJIS') + self.check('ja_jp', 'ja_JP.eucJP') + self.check('ja_jp.ajec', 'ja_JP.eucJP') + self.check('ja_jp.euc', 'ja_JP.eucJP') + self.check('ja_jp.eucjp', 'ja_JP.eucJP') + self.check('ja_jp.iso-2022-jp', 'ja_JP.JIS7') + self.check('ja_jp.iso2022jp', 'ja_JP.JIS7') + self.check('ja_jp.jis', 'ja_JP.JIS7') + self.check('ja_jp.jis7', 'ja_JP.JIS7') + self.check('ja_jp.mscode', 'ja_JP.SJIS') + self.check('ja_jp.pck', 'ja_JP.SJIS') + self.check('ja_jp.sjis', 'ja_JP.SJIS') + self.check('ja_jp.ujis', 'ja_JP.eucJP') + self.check('ja_jp.utf8', 'ja_JP.UTF-8') + self.check('japan', 'ja_JP.eucJP') + self.check('japanese', 'ja_JP.eucJP') + self.check('japanese-euc', 'ja_JP.eucJP') + self.check('japanese.euc', 'ja_JP.eucJP') + self.check('japanese.sjis', 'ja_JP.SJIS') + self.check('jp_jp', 'ja_JP.eucJP') + + class TestMiscellaneous(unittest.TestCase): def test_getpreferredencoding(self): # Invoke getpreferredencoding to make sure it does not cause exceptions. @@ -400,7 +511,7 @@ def test_getsetlocale_issue1813(self): self.skipTest('test needs Turkish locale') loc = locale.getlocale(locale.LC_CTYPE) if verbose: - print('got locale %a' % (loc,)) + print('testing with %a' % (loc,), end=' ', flush=True) locale.setlocale(locale.LC_CTYPE, loc) self.assertEqual(loc, locale.getlocale(locale.LC_CTYPE)) @@ -413,5 +524,59 @@ def test_invalid_iterable_in_localetuple(self): locale.setlocale(locale.LC_ALL, (b'not', b'valid')) +class BaseDelocalizeTest(BaseLocalizedTest): + + def _test_delocalize(self, value, out): + self.assertEqual(locale.delocalize(value), out) + + def _test_atof(self, value, out): + self.assertEqual(locale.atof(value), out) + + def _test_atoi(self, value, out): + self.assertEqual(locale.atoi(value), out) + + +class TestEnUSDelocalize(EnUSCookedTest, BaseDelocalizeTest): + + def test_delocalize(self): + self._test_delocalize('50000.00', '50000.00') + self._test_delocalize('50,000.00', '50000.00') + + def test_atof(self): + self._test_atof('50000.00', 50000.) + self._test_atof('50,000.00', 50000.) + + def test_atoi(self): + self._test_atoi('50000', 50000) + self._test_atoi('50,000', 50000) + + +class TestCDelocalizeTest(CCookedTest, BaseDelocalizeTest): + + def test_delocalize(self): + self._test_delocalize('50000.00', '50000.00') + + def test_atof(self): + self._test_atof('50000.00', 50000.) + + def test_atoi(self): + self._test_atoi('50000', 50000) + + +class TestfrFRDelocalizeTest(FrFRCookedTest, BaseDelocalizeTest): + + def test_delocalize(self): + self._test_delocalize('50000,00', '50000.00') + self._test_delocalize('50 000,00', '50000.00') + + def test_atof(self): + self._test_atof('50000,00', 50000.) + self._test_atof('50 000,00', 50000.) + + def test_atoi(self): + self._test_atoi('50000', 50000) + self._test_atoi('50 000', 50000) + + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index ffd0c8bf2b54..c8b6a9803272 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -1,6 +1,4 @@ -#!/usr/bin/env python -# -# Copyright 2001-2013 by Vinay Sajip. All Rights Reserved. +# Copyright 2001-2014 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, @@ -18,7 +16,7 @@ """Test harness for the logging module. Run all tests. -Copyright (C) 2001-2013 Vinay Sajip. All Rights Reserved. +Copyright (C) 2001-2014 Vinay Sajip. All Rights Reserved. """ import logging @@ -36,13 +34,12 @@ import queue import random import re -import select import socket import struct import sys import tempfile -from test.support import (captured_stdout, run_with_locale, run_unittest, - patch, requires_zlib, TestHandler, Matcher) +from test.script_helper import assert_python_ok +from test import support import textwrap import time import unittest @@ -52,16 +49,12 @@ import threading # The following imports are needed only for tests which # require threading - import asynchat import asyncore - import errno from http.server import HTTPServer, BaseHTTPRequestHandler import smtpd from urllib.parse import urlparse, parse_qs from socketserver import (ThreadingUDPServer, DatagramRequestHandler, - ThreadingTCPServer, StreamRequestHandler, - ThreadingUnixStreamServer, - ThreadingUnixDatagramServer) + ThreadingTCPServer, StreamRequestHandler) except ImportError: threading = None try: @@ -314,6 +307,10 @@ def test_nested_with_virtual_parent(self): ('INF.BADPARENT', 'INFO', '4'), ]) + def test_regression_22386(self): + """See issue #22386 for more information.""" + self.assertEqual(logging.getLevelName('INFO'), logging.INFO) + self.assertEqual(logging.getLevelName(logging.INFO), 'INFO') class BasicFilterTest(BaseTest): @@ -590,6 +587,7 @@ def remove_loop(fname, tries): for _ in range(tries): try: os.unlink(fname) + self.deletion_time = time.time() except OSError: pass time.sleep(0.004 * random.randint(0, 4)) @@ -597,6 +595,9 @@ def remove_loop(fname, tries): del_count = 500 log_count = 500 + self.handle_time = None + self.deletion_time = None + for delay in (False, True): fd, fn = tempfile.mkstemp('.log', 'test_logging-3-') os.close(fd) @@ -610,7 +611,14 @@ def remove_loop(fname, tries): for _ in range(log_count): time.sleep(0.005) r = logging.makeLogRecord({'msg': 'testing' }) - h.handle(r) + try: + self.handle_time = time.time() + h.handle(r) + except Exception: + print('Deleted at %s, ' + 'opened at %s' % (self.deletion_time, + self.handle_time)) + raise finally: remover.join() h.close() @@ -631,22 +639,23 @@ def test_error_handling(self): h = TestStreamHandler(BadStream()) r = logging.makeLogRecord({}) old_raise = logging.raiseExceptions - old_stderr = sys.stderr + try: h.handle(r) self.assertIs(h.error_record, r) + h = logging.StreamHandler(BadStream()) - sys.stderr = sio = io.StringIO() - h.handle(r) - self.assertIn('\nRuntimeError: deliberate mistake\n', - sio.getvalue()) + with support.captured_stderr() as stderr: + h.handle(r) + msg = '\nRuntimeError: deliberate mistake\n' + self.assertIn(msg, stderr.getvalue()) + logging.raiseExceptions = False - sys.stderr = sio = io.StringIO() - h.handle(r) - self.assertEqual('', sio.getvalue()) + with support.captured_stderr() as stderr: + h.handle(r) + self.assertEqual('', stderr.getvalue()) finally: logging.raiseExceptions = old_raise - sys.stderr = old_stderr # -- The following section could be moved into a server_helper.py module # -- if it proves to be of wider utility than just test_logging @@ -674,7 +683,8 @@ class TestSMTPServer(smtpd.SMTPServer): """ def __init__(self, addr, handler, poll_interval, sockmap): - smtpd.SMTPServer.__init__(self, addr, None, map=sockmap) + smtpd.SMTPServer.__init__(self, addr, None, map=sockmap, + decode_data=True) self.port = self.socket.getsockname()[1] self._handler = handler self._thread = None @@ -855,9 +865,6 @@ def server_bind(self): super(TestTCPServer, self).server_bind() self.port = self.socket.getsockname()[1] - class TestUnixStreamServer(TestTCPServer): - address_family = socket.AF_UNIX - class TestUDPServer(ControlMixin, ThreadingUDPServer): """ A UDP server which is controllable using :class:`ControlMixin`. @@ -905,26 +912,32 @@ def server_close(self): super(TestUDPServer, self).server_close() self._closed = True - class TestUnixDatagramServer(TestUDPServer): - address_family = socket.AF_UNIX + if hasattr(socket, "AF_UNIX"): + class TestUnixStreamServer(TestTCPServer): + address_family = socket.AF_UNIX + + class TestUnixDatagramServer(TestUDPServer): + address_family = socket.AF_UNIX # - end of server_helper section @unittest.skipUnless(threading, 'Threading required for this test.') class SMTPHandlerTest(BaseTest): + TIMEOUT = 8.0 def test_basic(self): sockmap = {} - server = TestSMTPServer(('localhost', 0), self.process_message, 0.001, + server = TestSMTPServer((support.HOST, 0), self.process_message, 0.001, sockmap) server.start() - addr = ('localhost', server.port) - h = logging.handlers.SMTPHandler(addr, 'me', 'you', 'Log', timeout=5.0) + addr = (support.HOST, server.port) + h = logging.handlers.SMTPHandler(addr, 'me', 'you', 'Log', + timeout=self.TIMEOUT) self.assertEqual(h.toaddrs, ['you']) self.messages = [] r = logging.makeLogRecord({'msg': 'Hello'}) self.handled = threading.Event() h.handle(r) - self.handled.wait(5.0) # 14314: don't wait forever + self.handled.wait(self.TIMEOUT) # 14314: don't wait forever server.stop() self.assertTrue(self.handled.is_set()) self.assertEqual(len(self.messages), 1) @@ -1232,7 +1245,7 @@ def apply_config(self, conf, **kwargs): def test_config0_ok(self): # A simple config file which overrides the default settings. - with captured_stdout() as output: + with support.captured_stdout() as output: self.apply_config(self.config0) logger = logging.getLogger() # Won't output anything @@ -1247,7 +1260,7 @@ def test_config0_ok(self): def test_config0_using_cp_ok(self): # A simple config file which overrides the default settings. - with captured_stdout() as output: + with support.captured_stdout() as output: file = io.StringIO(textwrap.dedent(self.config0)) cp = configparser.ConfigParser() cp.read_file(file) @@ -1265,7 +1278,7 @@ def test_config0_using_cp_ok(self): def test_config1_ok(self, config=config1): # A config file defining a sub-parser as well. - with captured_stdout() as output: + with support.captured_stdout() as output: self.apply_config(config) logger = logging.getLogger("compiler.parser") # Both will output a message @@ -1288,7 +1301,7 @@ def test_config3_failure(self): def test_config4_ok(self): # A config file specifying a custom formatter class. - with captured_stdout() as output: + with support.captured_stdout() as output: self.apply_config(self.config4) logger = logging.getLogger() try: @@ -1308,7 +1321,7 @@ def test_config6_ok(self): self.test_config1_ok(config=self.config6) def test_config7_ok(self): - with captured_stdout() as output: + with support.captured_stdout() as output: self.apply_config(self.config1a) logger = logging.getLogger("compiler.parser") # See issue #11424. compiler-hyphenated sorts @@ -1328,7 +1341,7 @@ def test_config7_ok(self): ], stream=output) # Original logger output is empty. self.assert_log_lines([]) - with captured_stdout() as output: + with support.captured_stdout() as output: self.apply_config(self.config7) logger = logging.getLogger("compiler.parser") self.assertFalse(logger.disabled) @@ -1445,12 +1458,13 @@ def _get_temp_domain_socket(): os.remove(fn) return fn +@unittest.skipUnless(hasattr(socket, "AF_UNIX"), "Unix sockets required") @unittest.skipUnless(threading, 'Threading required for this test.') class UnixSocketHandlerTest(SocketHandlerTest): """Test for SocketHandler with unix sockets.""" - if threading: + if threading and hasattr(socket, "AF_UNIX"): server_class = TestUnixStreamServer def setUp(self): @@ -1516,13 +1530,13 @@ def test_output(self): self.handled.wait() self.assertEqual(self.log_output, "spam\neggs\n") - +@unittest.skipUnless(hasattr(socket, "AF_UNIX"), "Unix sockets required") @unittest.skipUnless(threading, 'Threading required for this test.') class UnixDatagramHandlerTest(DatagramHandlerTest): """Test for DatagramHandler using Unix sockets.""" - if threading: + if threading and hasattr(socket, "AF_UNIX"): server_class = TestUnixDatagramServer def setUp(self): @@ -1591,13 +1605,13 @@ def test_output(self): self.handled.wait() self.assertEqual(self.log_output, b'<11>h\xc3\xa4m-sp\xc3\xa4m') - +@unittest.skipUnless(hasattr(socket, "AF_UNIX"), "Unix sockets required") @unittest.skipUnless(threading, 'Threading required for this test.') class UnixSysLogHandlerTest(SysLogHandlerTest): """Test for SysLogHandler with Unix sockets.""" - if threading: + if threading and hasattr(socket, "AF_UNIX"): server_class = TestUnixDatagramServer def setUp(self): @@ -1613,36 +1627,6 @@ def tearDown(self): class HTTPHandlerTest(BaseTest): """Test for HTTPHandler.""" - PEMFILE = """-----BEGIN RSA PRIVATE KEY----- -MIICXQIBAAKBgQDGT4xS5r91rbLJQK2nUDenBhBG6qFk+bVOjuAGC/LSHlAoBnvG -zQG3agOG+e7c5z2XT8m2ktORLqG3E4mYmbxgyhDrzP6ei2Anc+pszmnxPoK3Puh5 -aXV+XKt0bU0C1m2+ACmGGJ0t3P408art82nOxBw8ZHgIg9Dtp6xIUCyOqwIDAQAB -AoGBAJFTnFboaKh5eUrIzjmNrKsG44jEyy+vWvHN/FgSC4l103HxhmWiuL5Lv3f7 -0tMp1tX7D6xvHwIG9VWvyKb/Cq9rJsDibmDVIOslnOWeQhG+XwJyitR0pq/KlJIB -5LjORcBw795oKWOAi6RcOb1ON59tysEFYhAGQO9k6VL621gRAkEA/Gb+YXULLpbs -piXN3q4zcHzeaVANo69tUZ6TjaQqMeTxE4tOYM0G0ZoSeHEdaP59AOZGKXXNGSQy -2z/MddcYGQJBAMkjLSYIpOLJY11ja8OwwswFG2hEzHe0cS9bzo++R/jc1bHA5R0Y -i6vA5iPi+wopPFvpytdBol7UuEBe5xZrxWMCQQCWxELRHiP2yWpEeLJ3gGDzoXMN -PydWjhRju7Bx3AzkTtf+D6lawz1+eGTuEss5i0JKBkMEwvwnN2s1ce+EuF4JAkBb -E96h1lAzkVW5OAfYOPY8RCPA90ZO/hoyg7PpSxR0ECuDrgERR8gXIeYUYfejBkEa -rab4CfRoVJKKM28Yq/xZAkBvuq670JRCwOgfUTdww7WpdOQBYPkzQccsKNCslQW8 -/DyW6y06oQusSENUvynT6dr3LJxt/NgZPhZX2+k1eYDV ------END RSA PRIVATE KEY----- ------BEGIN CERTIFICATE----- -MIICGzCCAYSgAwIBAgIJAIq84a2Q/OvlMA0GCSqGSIb3DQEBBQUAMBQxEjAQBgNV -BAMTCWxvY2FsaG9zdDAeFw0xMTA1MjExMDIzMzNaFw03NTAzMjEwMzU1MTdaMBQx -EjAQBgNVBAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA -xk+MUua/da2yyUCtp1A3pwYQRuqhZPm1To7gBgvy0h5QKAZ7xs0Bt2oDhvnu3Oc9 -l0/JtpLTkS6htxOJmJm8YMoQ68z+notgJ3PqbM5p8T6Ctz7oeWl1flyrdG1NAtZt -vgAphhidLdz+NPGq7fNpzsQcPGR4CIPQ7aesSFAsjqsCAwEAAaN1MHMwHQYDVR0O -BBYEFLWaUPO6N7efGiuoS9i3DVYcUwn0MEQGA1UdIwQ9MDuAFLWaUPO6N7efGiuo -S9i3DVYcUwn0oRikFjAUMRIwEAYDVQQDEwlsb2NhbGhvc3SCCQCKvOGtkPzr5TAM -BgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAMK5whPjLNQK1Ivvk88oqJqq -4f889OwikGP0eUhOBhbFlsZs+jq5YZC2UzHz+evzKBlgAP1u4lP/cB85CnjvWqM+ -1c/lywFHQ6HOdDeQ1L72tSYMrNOG4XNmLn0h7rx6GoTU7dcFRfseahBCq8mv0IDt -IRbTpvlHWPjsSvHz0ZOH ------END CERTIFICATE-----""" - def setUp(self): """Set up an HTTP server to receive log messages, and a HTTPHandler pointing to that server's address and port.""" @@ -1672,17 +1656,18 @@ def test_output(self): if secure: try: import ssl - fd, fn = tempfile.mkstemp() - os.close(fd) - with open(fn, 'w') as f: - f.write(self.PEMFILE) - sslctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23) - sslctx.load_cert_chain(fn) - os.unlink(fn) except ImportError: sslctx = None + else: + here = os.path.dirname(__file__) + localhost_cert = os.path.join(here, "keycert.pem") + sslctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23) + sslctx.load_cert_chain(localhost_cert) + + context = ssl.create_default_context(cafile=localhost_cert) else: sslctx = None + context = None self.server = server = TestHTTPServer(addr, self.handle_request, 0.01, sslctx=sslctx) server.start() @@ -1690,7 +1675,8 @@ def test_output(self): host = 'localhost:%d' % server.server_port secure_client = secure and sslctx self.h_hdlr = logging.handlers.HTTPHandler(host, '/frob', - secure=secure_client) + secure=secure_client, + context=context) self.log_data = None root_logger.addHandler(self.h_hdlr) @@ -2502,7 +2488,7 @@ def apply_config(self, conf): def test_config0_ok(self): # A simple config which overrides the default settings. - with captured_stdout() as output: + with support.captured_stdout() as output: self.apply_config(self.config0) logger = logging.getLogger() # Won't output anything @@ -2517,7 +2503,7 @@ def test_config0_ok(self): def test_config1_ok(self, config=config1): # A config defining a sub-parser as well. - with captured_stdout() as output: + with support.captured_stdout() as output: self.apply_config(config) logger = logging.getLogger("compiler.parser") # Both will output a message @@ -2548,7 +2534,7 @@ def test_config3_failure(self): def test_config4_ok(self): # A config specifying a custom formatter class. - with captured_stdout() as output: + with support.captured_stdout() as output: self.apply_config(self.config4) #logger = logging.getLogger() try: @@ -2563,7 +2549,7 @@ def test_config4_ok(self): def test_config4a_ok(self): # A config specifying a custom formatter class. - with captured_stdout() as output: + with support.captured_stdout() as output: self.apply_config(self.config4a) #logger = logging.getLogger() try: @@ -2583,7 +2569,7 @@ def test_config6_failure(self): self.assertRaises(Exception, self.apply_config, self.config6) def test_config7_ok(self): - with captured_stdout() as output: + with support.captured_stdout() as output: self.apply_config(self.config1) logger = logging.getLogger("compiler.parser") # Both will output a message @@ -2595,7 +2581,7 @@ def test_config7_ok(self): ], stream=output) # Original logger output is empty. self.assert_log_lines([]) - with captured_stdout() as output: + with support.captured_stdout() as output: self.apply_config(self.config7) logger = logging.getLogger("compiler.parser") self.assertTrue(logger.disabled) @@ -2612,7 +2598,7 @@ def test_config7_ok(self): #Same as test_config_7_ok but don't disable old loggers. def test_config_8_ok(self): - with captured_stdout() as output: + with support.captured_stdout() as output: self.apply_config(self.config1) logger = logging.getLogger("compiler.parser") # All will output a message @@ -2624,7 +2610,7 @@ def test_config_8_ok(self): ], stream=output) # Original logger output is empty. self.assert_log_lines([]) - with captured_stdout() as output: + with support.captured_stdout() as output: self.apply_config(self.config8) logger = logging.getLogger("compiler.parser") self.assertFalse(logger.disabled) @@ -2645,7 +2631,7 @@ def test_config_8_ok(self): self.assert_log_lines([]) def test_config_8a_ok(self): - with captured_stdout() as output: + with support.captured_stdout() as output: self.apply_config(self.config1a) logger = logging.getLogger("compiler.parser") # See issue #11424. compiler-hyphenated sorts @@ -2665,7 +2651,7 @@ def test_config_8a_ok(self): ], stream=output) # Original logger output is empty. self.assert_log_lines([]) - with captured_stdout() as output: + with support.captured_stdout() as output: self.apply_config(self.config8a) logger = logging.getLogger("compiler.parser") self.assertFalse(logger.disabled) @@ -2688,7 +2674,7 @@ def test_config_8a_ok(self): self.assert_log_lines([]) def test_config_9_ok(self): - with captured_stdout() as output: + with support.captured_stdout() as output: self.apply_config(self.config9) logger = logging.getLogger("compiler.parser") #Nothing will be output since both handler and logger are set to WARNING @@ -2706,7 +2692,7 @@ def test_config_9_ok(self): ], stream=output) def test_config_10_ok(self): - with captured_stdout() as output: + with support.captured_stdout() as output: self.apply_config(self.config10) logger = logging.getLogger("compiler.parser") logger.warning(self.next_message()) @@ -2734,7 +2720,7 @@ def test_config13_failure(self): self.assertRaises(Exception, self.apply_config, self.config13) def test_config14_ok(self): - with captured_stdout() as output: + with support.captured_stdout() as output: self.apply_config(self.config14) h = logging._handlers['hand1'] self.assertEqual(h.foo, 'bar') @@ -2773,7 +2759,7 @@ def setup_via_listener(self, text, verify=None): @unittest.skipUnless(threading, 'Threading required for this test.') def test_listen_config_10_ok(self): - with captured_stdout() as output: + with support.captured_stdout() as output: self.setup_via_listener(json.dumps(self.config10)) logger = logging.getLogger("compiler.parser") logger.warning(self.next_message()) @@ -2793,7 +2779,7 @@ def test_listen_config_10_ok(self): @unittest.skipUnless(threading, 'Threading required for this test.') def test_listen_config_1_ok(self): - with captured_stdout() as output: + with support.captured_stdout() as output: self.setup_via_listener(textwrap.dedent(ConfigFileTest.config1)) logger = logging.getLogger("compiler.parser") # Both will output a message @@ -2820,7 +2806,7 @@ def verify_reverse(stuff): # First, specify a verification function that will fail. # We expect to see no output, since our configuration # never took effect. - with captured_stdout() as output: + with support.captured_stdout() as output: self.setup_via_listener(to_send, verify_fail) # Both will output a message logger.info(self.next_message()) @@ -2835,7 +2821,7 @@ def verify_reverse(stuff): # Now, perform no verification. Our configuration # should take effect. - with captured_stdout() as output: + with support.captured_stdout() as output: self.setup_via_listener(to_send) # no verify callable specified logger = logging.getLogger("compiler.parser") # Both will output a message @@ -2853,7 +2839,7 @@ def verify_reverse(stuff): # Now, perform verification which transforms the bytes. - with captured_stdout() as output: + with support.captured_stdout() as output: self.setup_via_listener(to_send[::-1], verify_reverse) logger = logging.getLogger("compiler.parser") # Both will output a message @@ -3008,7 +2994,7 @@ def test_queue_handler(self): @unittest.skipUnless(hasattr(logging.handlers, 'QueueListener'), 'logging.handlers.QueueListener required for this test') def test_queue_listener(self): - handler = TestHandler(Matcher()) + handler = support.TestHandler(support.Matcher()) listener = logging.handlers.QueueListener(self.queue, handler) listener.start() try: @@ -3020,6 +3006,25 @@ def test_queue_listener(self): self.assertTrue(handler.matches(levelno=logging.WARNING, message='1')) self.assertTrue(handler.matches(levelno=logging.ERROR, message='2')) self.assertTrue(handler.matches(levelno=logging.CRITICAL, message='3')) + handler.close() + + # Now test with respect_handler_level set + + handler = support.TestHandler(support.Matcher()) + handler.setLevel(logging.CRITICAL) + listener = logging.handlers.QueueListener(self.queue, handler, + respect_handler_level=True) + listener.start() + try: + self.que_logger.warning(self.next_message()) + self.que_logger.error(self.next_message()) + self.que_logger.critical(self.next_message()) + finally: + listener.stop() + self.assertFalse(handler.matches(levelno=logging.WARNING, message='4')) + self.assertFalse(handler.matches(levelno=logging.ERROR, message='5')) + self.assertTrue(handler.matches(levelno=logging.CRITICAL, message='6')) + ZERO = datetime.timedelta(0) @@ -3176,32 +3181,35 @@ def test_last_resort(self): # Test the last resort handler root = self.root_logger root.removeHandler(self.root_hdlr) - old_stderr = sys.stderr old_lastresort = logging.lastResort old_raise_exceptions = logging.raiseExceptions + try: - sys.stderr = sio = io.StringIO() - root.debug('This should not appear') - self.assertEqual(sio.getvalue(), '') - root.warning('This is your final chance!') - self.assertEqual(sio.getvalue(), 'This is your final chance!\n') - #No handlers and no last resort, so 'No handlers' message + with support.captured_stderr() as stderr: + root.debug('This should not appear') + self.assertEqual(stderr.getvalue(), '') + root.warning('Final chance!') + self.assertEqual(stderr.getvalue(), 'Final chance!\n') + + # No handlers and no last resort, so 'No handlers' message logging.lastResort = None - sys.stderr = sio = io.StringIO() - root.warning('This is your final chance!') - self.assertEqual(sio.getvalue(), 'No handlers could be found for logger "root"\n') + with support.captured_stderr() as stderr: + root.warning('Final chance!') + msg = 'No handlers could be found for logger "root"\n' + self.assertEqual(stderr.getvalue(), msg) + # 'No handlers' message only printed once - sys.stderr = sio = io.StringIO() - root.warning('This is your final chance!') - self.assertEqual(sio.getvalue(), '') + with support.captured_stderr() as stderr: + root.warning('Final chance!') + self.assertEqual(stderr.getvalue(), '') + + # If raiseExceptions is False, no message is printed root.manager.emittedNoHandlerWarning = False - #If raiseExceptions is False, no message is printed logging.raiseExceptions = False - sys.stderr = sio = io.StringIO() - root.warning('This is your final chance!') - self.assertEqual(sio.getvalue(), '') + with support.captured_stderr() as stderr: + root.warning('Final chance!') + self.assertEqual(stderr.getvalue(), '') finally: - sys.stderr = old_stderr root.addHandler(self.root_hdlr) logging.lastResort = old_lastresort logging.raiseExceptions = old_raise_exceptions @@ -3332,8 +3340,8 @@ def test_disable(self): def _test_log(self, method, level=None): called = [] - patch(self, logging, 'basicConfig', - lambda *a, **kw: called.append((a, kw))) + support.patch(self, logging, 'basicConfig', + lambda *a, **kw: called.append((a, kw))) recording = RecordingHandler() logging.root.addHandler(recording) @@ -3384,6 +3392,25 @@ class MyLogger(logging.Logger): logging.setLoggerClass(logging.Logger) self.assertEqual(logging.getLoggerClass(), logging.Logger) + def test_logging_at_shutdown(self): + # Issue #20037 + code = """if 1: + import logging + + class A: + def __del__(self): + try: + raise ValueError("some error") + except Exception: + logging.exception("exception in __del__") + + a = A()""" + rc, out, err = assert_python_ok("-c", code) + err = err.decode() + self.assertIn("exception in __del__", err) + self.assertIn("ValueError: some error", err) + + class LogRecordTest(BaseTest): def test_str_rep(self): r = logging.makeLogRecord({}) @@ -3484,6 +3511,22 @@ def test_no_kwargs(self): # level is not explicitly set self.assertEqual(logging.root.level, self.original_logging_level) + def test_strformatstyle(self): + with support.captured_stdout() as output: + logging.basicConfig(stream=sys.stdout, style="{") + logging.error("Log an error") + sys.stdout.seek(0) + self.assertEqual(output.getvalue().strip(), + "ERROR:root:Log an error") + + def test_stringtemplatestyle(self): + with support.captured_stdout() as output: + logging.basicConfig(stream=sys.stdout, style="$") + logging.error("Log an error") + sys.stdout.seek(0) + self.assertEqual(output.getvalue().strip(), + "ERROR:root:Log an error") + def test_filename(self): def cleanup(h1, h2, fn): @@ -3594,7 +3637,7 @@ def my_basic_config(*a, **kw): self.addCleanup(logging.root.setLevel, old_level) called.append((a, kw)) - patch(self, logging, 'basicConfig', my_basic_config) + support.patch(self, logging, 'basicConfig', my_basic_config) log_method = getattr(logging, method) if level is not None: @@ -3660,6 +3703,19 @@ def test_exception(self): self.assertEqual(record.exc_info, (exc.__class__, exc, exc.__traceback__)) + def test_exception_excinfo(self): + try: + 1 / 0 + except ZeroDivisionError as e: + exc = e + + self.adapter.exception('exc_info test', exc_info=exc) + + self.assertEqual(len(self.recording.records), 1) + record = self.recording.records[0] + self.assertEqual(record.exc_info, + (exc.__class__, exc, exc.__traceback__)) + def test_critical(self): msg = 'critical test! %r' self.adapter.critical(msg, self.recording) @@ -3734,8 +3790,8 @@ def test_log_invalid_level_no_raise(self): def test_find_caller_with_stack_info(self): called = [] - patch(self, logging.traceback, 'print_stack', - lambda f, file: called.append(file.getvalue())) + support.patch(self, logging.traceback, 'print_stack', + lambda f, file: called.append(file.getvalue())) self.logger.findCaller(stack_info=True) @@ -3872,7 +3928,7 @@ def namer(name): self.assertFalse(os.path.exists(namer(self.fn + ".3"))) rh.close() - @requires_zlib + @support.requires_zlib def test_rotator(self): def namer(name): return name + ".gz" @@ -4105,22 +4161,20 @@ def test_basic(self): # Set the locale to the platform-dependent default. I have no idea # why the test does this, but in any case we save the current locale # first and restore it at the end. -@run_with_locale('LC_ALL', '') +@support.run_with_locale('LC_ALL', '') def test_main(): - run_unittest(BuiltinLevelsTest, BasicFilterTest, - CustomLevelsAndFiltersTest, HandlerTest, MemoryHandlerTest, - ConfigFileTest, SocketHandlerTest, DatagramHandlerTest, - MemoryTest, EncodingTest, WarningsTest, ConfigDictTest, - ManagerTest, FormatterTest, BufferingFormatterTest, - StreamHandlerTest, LogRecordFactoryTest, ChildLoggerTest, - QueueHandlerTest, ShutdownTest, ModuleLevelMiscTest, - BasicConfigTest, LoggerAdapterTest, LoggerTest, - SMTPHandlerTest, FileHandlerTest, RotatingFileHandlerTest, - LastResortTest, LogRecordTest, ExceptionTest, - SysLogHandlerTest, HTTPHandlerTest, NTEventLogHandlerTest, - TimedRotatingFileHandlerTest, UnixSocketHandlerTest, - UnixDatagramHandlerTest, UnixSysLogHandlerTest - ) + support.run_unittest( + BuiltinLevelsTest, BasicFilterTest, CustomLevelsAndFiltersTest, + HandlerTest, MemoryHandlerTest, ConfigFileTest, SocketHandlerTest, + DatagramHandlerTest, MemoryTest, EncodingTest, WarningsTest, + ConfigDictTest, ManagerTest, FormatterTest, BufferingFormatterTest, + StreamHandlerTest, LogRecordFactoryTest, ChildLoggerTest, + QueueHandlerTest, ShutdownTest, ModuleLevelMiscTest, BasicConfigTest, + LoggerAdapterTest, LoggerTest, SMTPHandlerTest, FileHandlerTest, + RotatingFileHandlerTest, LastResortTest, LogRecordTest, + ExceptionTest, SysLogHandlerTest, HTTPHandlerTest, + NTEventLogHandlerTest, TimedRotatingFileHandlerTest, + UnixSocketHandlerTest, UnixDatagramHandlerTest, UnixSysLogHandlerTest) if __name__ == "__main__": test_main() diff --git a/Lib/test/test_long.py b/Lib/test/test_long.py index 6c30fed7c942..57847d88f748 100644 --- a/Lib/test/test_long.py +++ b/Lib/test/test_long.py @@ -130,7 +130,7 @@ class LongTest(unittest.TestCase): # The sign of the number is also random. def getran(self, ndigits): - self.assertTrue(ndigits > 0) + self.assertGreater(ndigits, 0) nbits_hi = ndigits * SHIFT nbits_lo = nbits_hi - SHIFT + 1 answer = 0 @@ -599,8 +599,6 @@ def _cmp__(self, other): return (x > y) - (x < y) def __eq__(self, other): return self._cmp__(other) == 0 - def __ne__(self, other): - return self._cmp__(other) != 0 def __ge__(self, other): return self._cmp__(other) >= 0 def __gt__(self, other): @@ -865,21 +863,21 @@ def test_correctly_rounded_true_division(self): def test_small_ints(self): for i in range(-5, 257): - self.assertTrue(i is i + 0) - self.assertTrue(i is i * 1) - self.assertTrue(i is i - 0) - self.assertTrue(i is i // 1) - self.assertTrue(i is i & -1) - self.assertTrue(i is i | 0) - self.assertTrue(i is i ^ 0) - self.assertTrue(i is ~~i) - self.assertTrue(i is i**1) - self.assertTrue(i is int(str(i))) - self.assertTrue(i is i<<2>>2, str(i)) + self.assertIs(i, i + 0) + self.assertIs(i, i * 1) + self.assertIs(i, i - 0) + self.assertIs(i, i // 1) + self.assertIs(i, i & -1) + self.assertIs(i, i | 0) + self.assertIs(i, i ^ 0) + self.assertIs(i, ~~i) + self.assertIs(i, i**1) + self.assertIs(i, int(str(i))) + self.assertIs(i, i<<2>>2, str(i)) # corner cases i = 1 << 70 - self.assertTrue(i - i is 0) - self.assertTrue(0 * i is 0) + self.assertIs(i - i, 0) + self.assertIs(0 * i, 0) def test_bit_length(self): tiny = 1e-10 @@ -926,7 +924,7 @@ def test_round(self): got = round(k+offset, -1) expected = v+offset self.assertEqual(got, expected) - self.assertTrue(type(got) is int) + self.assertIs(type(got), int) # larger second argument self.assertEqual(round(-150, -2), -200) @@ -965,7 +963,7 @@ def test_round(self): got = round(10**k + 324678, -3) expect = 10**k + 325000 self.assertEqual(got, expect) - self.assertTrue(type(got) is int) + self.assertIs(type(got), int) # nonnegative second argument: round(x, n) should just return x for n in range(5): @@ -973,7 +971,7 @@ def test_round(self): x = random.randrange(-10000, 10000) got = round(x, n) self.assertEqual(got, x) - self.assertTrue(type(got) is int) + self.assertIs(type(got), int) for huge_n in 2**31-1, 2**31, 2**63-1, 2**63, 2**100, 10**100: self.assertEqual(round(8979323, huge_n), 8979323) @@ -982,7 +980,7 @@ def test_round(self): x = random.randrange(-10000, 10000) got = round(x) self.assertEqual(got, x) - self.assertTrue(type(got) is int) + self.assertIs(type(got), int) # bad second argument bad_exponents = ('brian', 2.0, 0j, None) @@ -1187,15 +1185,15 @@ def check(tests, byteorder, signed=False): class myint(int): pass - self.assertTrue(type(myint.from_bytes(b'\x00', 'big')) is myint) + self.assertIs(type(myint.from_bytes(b'\x00', 'big')), myint) self.assertEqual(myint.from_bytes(b'\x01', 'big'), 1) - self.assertTrue( - type(myint.from_bytes(b'\x00', 'big', signed=False)) is myint) + self.assertIs( + type(myint.from_bytes(b'\x00', 'big', signed=False)), myint) self.assertEqual(myint.from_bytes(b'\x01', 'big', signed=False), 1) - self.assertTrue(type(myint.from_bytes(b'\x00', 'little')) is myint) + self.assertIs(type(myint.from_bytes(b'\x00', 'little')), myint) self.assertEqual(myint.from_bytes(b'\x01', 'little'), 1) - self.assertTrue(type(myint.from_bytes( - b'\x00', 'little', signed=False)) is myint) + self.assertIs(type(myint.from_bytes( + b'\x00', 'little', signed=False)), myint) self.assertEqual(myint.from_bytes(b'\x01', 'little', signed=False), 1) self.assertEqual( int.from_bytes([255, 0, 0], 'big', signed=True), -65536) @@ -1235,6 +1233,13 @@ def __new__(cls, value=0): for n in map(int, integers): self.assertEqual(n, 0) + def test_shift_bool(self): + # Issue #21422: ensure that bool << int and bool >> int return int + for value in (True, False): + for shift in (0, 2): + self.assertEqual(type(value << shift), int) + self.assertEqual(type(value >> shift), int) + def test_main(): support.run_unittest(LongTest) diff --git a/Lib/test/test_lzma.py b/Lib/test/test_lzma.py index 26d19da5e95e..cded28c9b299 100644 --- a/Lib/test/test_lzma.py +++ b/Lib/test/test_lzma.py @@ -135,6 +135,97 @@ def test_decompressor_chunks(self): self.assertTrue(lzd.eof) self.assertEqual(lzd.unused_data, b"") + def test_decompressor_chunks_maxsize(self): + lzd = LZMADecompressor() + max_length = 100 + out = [] + + # Feed first half the input + len_ = len(COMPRESSED_XZ) // 2 + out.append(lzd.decompress(COMPRESSED_XZ[:len_], + max_length=max_length)) + self.assertFalse(lzd.needs_input) + self.assertEqual(len(out[-1]), max_length) + + # Retrieve more data without providing more input + out.append(lzd.decompress(b'', max_length=max_length)) + self.assertFalse(lzd.needs_input) + self.assertEqual(len(out[-1]), max_length) + + # Retrieve more data while providing more input + out.append(lzd.decompress(COMPRESSED_XZ[len_:], + max_length=max_length)) + self.assertLessEqual(len(out[-1]), max_length) + + # Retrieve remaining uncompressed data + while not lzd.eof: + out.append(lzd.decompress(b'', max_length=max_length)) + self.assertLessEqual(len(out[-1]), max_length) + + out = b"".join(out) + self.assertEqual(out, INPUT) + self.assertEqual(lzd.check, lzma.CHECK_CRC64) + self.assertEqual(lzd.unused_data, b"") + + def test_decompressor_inputbuf_1(self): + # Test reusing input buffer after moving existing + # contents to beginning + lzd = LZMADecompressor() + out = [] + + # Create input buffer and fill it + self.assertEqual(lzd.decompress(COMPRESSED_XZ[:100], + max_length=0), b'') + + # Retrieve some results, freeing capacity at beginning + # of input buffer + out.append(lzd.decompress(b'', 2)) + + # Add more data that fits into input buffer after + # moving existing data to beginning + out.append(lzd.decompress(COMPRESSED_XZ[100:105], 15)) + + # Decompress rest of data + out.append(lzd.decompress(COMPRESSED_XZ[105:])) + self.assertEqual(b''.join(out), INPUT) + + def test_decompressor_inputbuf_2(self): + # Test reusing input buffer by appending data at the + # end right away + lzd = LZMADecompressor() + out = [] + + # Create input buffer and empty it + self.assertEqual(lzd.decompress(COMPRESSED_XZ[:200], + max_length=0), b'') + out.append(lzd.decompress(b'')) + + # Fill buffer with new data + out.append(lzd.decompress(COMPRESSED_XZ[200:280], 2)) + + # Append some more data, not enough to require resize + out.append(lzd.decompress(COMPRESSED_XZ[280:300], 2)) + + # Decompress rest of data + out.append(lzd.decompress(COMPRESSED_XZ[300:])) + self.assertEqual(b''.join(out), INPUT) + + def test_decompressor_inputbuf_3(self): + # Test reusing input buffer after extending it + + lzd = LZMADecompressor() + out = [] + + # Create almost full input buffer + out.append(lzd.decompress(COMPRESSED_XZ[:200], 5)) + + # Add even more data to it, requiring resize + out.append(lzd.decompress(COMPRESSED_XZ[200:300], 5)) + + # Decompress rest of data + out.append(lzd.decompress(COMPRESSED_XZ[300:])) + self.assertEqual(b''.join(out), INPUT) + def test_decompressor_unused_data(self): lzd = LZMADecompressor() extra = b"fooblibar" @@ -220,10 +311,11 @@ def test_decompressor_bigmem(self, size): # Pickling raises an exception; there's no way to serialize an lzma_stream. def test_pickle(self): - with self.assertRaises(TypeError): - pickle.dumps(LZMACompressor()) - with self.assertRaises(TypeError): - pickle.dumps(LZMADecompressor()) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.assertRaises(TypeError): + pickle.dumps(LZMACompressor(), proto) + with self.assertRaises(TypeError): + pickle.dumps(LZMADecompressor(), proto) class CompressDecompressFunctionTestCase(unittest.TestCase): @@ -313,6 +405,8 @@ def test_decompress_incomplete_input(self): format=lzma.FORMAT_RAW, filters=FILTERS_RAW_4) def test_decompress_bad_input(self): + with self.assertRaises(LZMAError): + lzma.decompress(COMPRESSED_BOGUS) with self.assertRaises(LZMAError): lzma.decompress(COMPRESSED_RAW_1) with self.assertRaises(LZMAError): @@ -348,6 +442,16 @@ def test_decompress_multistream(self): ddata = lzma.decompress(COMPRESSED_XZ + COMPRESSED_ALONE) self.assertEqual(ddata, INPUT * 2) + # Test robust handling of non-LZMA data following the compressed stream(s). + + def test_decompress_trailing_junk(self): + ddata = lzma.decompress(COMPRESSED_XZ + COMPRESSED_BOGUS) + self.assertEqual(ddata, INPUT) + + def test_decompress_multistream_trailing_junk(self): + ddata = lzma.decompress(COMPRESSED_XZ * 3 + COMPRESSED_BOGUS) + self.assertEqual(ddata, INPUT * 3) + class TempFile: """Context manager - creates a file, and deletes it on __exit__.""" @@ -676,6 +780,14 @@ def test_read_multistream_buffer_size_aligned(self): finally: lzma._BUFFER_SIZE = saved_buffer_size + def test_read_trailing_junk(self): + with LZMAFile(BytesIO(COMPRESSED_XZ + COMPRESSED_BOGUS)) as f: + self.assertEqual(f.read(), INPUT) + + def test_read_multistream_trailing_junk(self): + with LZMAFile(BytesIO(COMPRESSED_XZ * 5 + COMPRESSED_BOGUS)) as f: + self.assertEqual(f.read(), INPUT * 5) + def test_read_from_file(self): with TempFile(TESTFN, COMPRESSED_XZ): with LZMAFile(TESTFN) as f: @@ -719,6 +831,10 @@ def test_read_bad_args(self): with LZMAFile(BytesIO(COMPRESSED_XZ)) as f: self.assertRaises(TypeError, f.read, None) + def test_read_bad_data(self): + with LZMAFile(BytesIO(COMPRESSED_BOGUS)) as f: + self.assertRaises(LZMAError, f.read) + def test_read1(self): with LZMAFile(BytesIO(COMPRESSED_XZ)) as f: blocks = [] @@ -1232,6 +1348,8 @@ def test_filter_properties_roundtrip(self): Farewell. """ +COMPRESSED_BOGUS = b"this is not a valid lzma stream" + COMPRESSED_XZ = ( b"\xfd7zXZ\x00\x00\x04\xe6\xd6\xb4F\x02\x00!\x01\x16\x00\x00\x00t/\xe5\xa3" b"\xe0\x07\x80\x03\xdf]\x00\x05\x14\x07bX\x19\xcd\xddn\x98\x15\xe4\xb4\x9d" diff --git a/Lib/test/test_macpath.py b/Lib/test/test_macpath.py index ae4e5640fa92..80bec7a799a0 100644 --- a/Lib/test/test_macpath.py +++ b/Lib/test/test_macpath.py @@ -49,16 +49,40 @@ def test_split(self): def test_join(self): join = macpath.join self.assertEqual(join('a', 'b'), ':a:b') + self.assertEqual(join(':a', 'b'), ':a:b') + self.assertEqual(join(':a:', 'b'), ':a:b') + self.assertEqual(join(':a::', 'b'), ':a::b') + self.assertEqual(join(':a', '::b'), ':a::b') + self.assertEqual(join('a', ':'), ':a:') + self.assertEqual(join('a:', ':'), 'a:') + self.assertEqual(join('a', ''), ':a:') + self.assertEqual(join('a:', ''), 'a:') + self.assertEqual(join('', ''), '') self.assertEqual(join('', 'a:b'), 'a:b') + self.assertEqual(join('', 'a', 'b'), ':a:b') self.assertEqual(join('a:b', 'c'), 'a:b:c') self.assertEqual(join('a:b', ':c'), 'a:b:c') self.assertEqual(join('a', ':b', ':c'), ':a:b:c') + self.assertEqual(join('a', 'b:'), 'b:') + self.assertEqual(join('a:', 'b:'), 'b:') self.assertEqual(join(b'a', b'b'), b':a:b') + self.assertEqual(join(b':a', b'b'), b':a:b') + self.assertEqual(join(b':a:', b'b'), b':a:b') + self.assertEqual(join(b':a::', b'b'), b':a::b') + self.assertEqual(join(b':a', b'::b'), b':a::b') + self.assertEqual(join(b'a', b':'), b':a:') + self.assertEqual(join(b'a:', b':'), b'a:') + self.assertEqual(join(b'a', b''), b':a:') + self.assertEqual(join(b'a:', b''), b'a:') + self.assertEqual(join(b'', b''), b'') self.assertEqual(join(b'', b'a:b'), b'a:b') + self.assertEqual(join(b'', b'a', b'b'), b':a:b') self.assertEqual(join(b'a:b', b'c'), b'a:b:c') self.assertEqual(join(b'a:b', b':c'), b'a:b:c') self.assertEqual(join(b'a', b':b', b':c'), b':a:b:c') + self.assertEqual(join(b'a', b'b:'), b'b:') + self.assertEqual(join(b'a:', b'b:'), b'b:') def test_splitext(self): splitext = macpath.splitext @@ -118,6 +142,8 @@ def test_normpath(self): class MacCommonTest(test_genericpath.CommonTest, unittest.TestCase): pathmodule = macpath + test_relpath_errors = None + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_mailbox.py b/Lib/test/test_mailbox.py index 78e2a30dbccb..0991f74f8406 100644 --- a/Lib/test/test_mailbox.py +++ b/Lib/test/test_mailbox.py @@ -233,7 +233,7 @@ def test_get(self): msg = self._box.get(key0) self.assertEqual(msg['from'], 'foo') self.assertEqual(msg.get_payload(), '0\n') - self.assertIs(self._box.get('foo'), None) + self.assertIsNone(self._box.get('foo')) self.assertIs(self._box.get('foo', False), False) self._box.close() self._box = self._factory(self._path) @@ -300,7 +300,7 @@ def test_get_file_can_be_closed_twice(self): def test_iterkeys(self): # Get keys using iterkeys() - self._check_iteration(self._box.keys, do_keys=True, do_values=False) + self._check_iteration(self._box.iterkeys, do_keys=True, do_values=False) def test_keys(self): # Get keys using keys() @@ -308,7 +308,7 @@ def test_keys(self): def test_itervalues(self): # Get values using itervalues() - self._check_iteration(self._box.values, do_keys=False, + self._check_iteration(self._box.itervalues, do_keys=False, do_values=True) def test_iter(self): @@ -322,7 +322,7 @@ def test_values(self): def test_iteritems(self): # Get keys and values using iteritems() - self._check_iteration(self._box.items, do_keys=True, + self._check_iteration(self._box.iteritems, do_keys=True, do_values=True) def test_items(self): @@ -564,12 +564,12 @@ def test_notimplemented(self): self.assertRaises(NotImplementedError, lambda: box.__delitem__('')) self.assertRaises(NotImplementedError, lambda: box.discard('')) self.assertRaises(NotImplementedError, lambda: box.__setitem__('', '')) + self.assertRaises(NotImplementedError, lambda: box.iterkeys()) self.assertRaises(NotImplementedError, lambda: box.keys()) - self.assertRaises(NotImplementedError, lambda: box.keys()) - self.assertRaises(NotImplementedError, lambda: box.values().__next__()) + self.assertRaises(NotImplementedError, lambda: box.itervalues().__next__()) self.assertRaises(NotImplementedError, lambda: box.__iter__().__next__()) self.assertRaises(NotImplementedError, lambda: box.values()) - self.assertRaises(NotImplementedError, lambda: box.items().next()) + self.assertRaises(NotImplementedError, lambda: box.iteritems().__next__()) self.assertRaises(NotImplementedError, lambda: box.items()) self.assertRaises(NotImplementedError, lambda: box.get('')) self.assertRaises(NotImplementedError, lambda: box.__getitem__('')) @@ -760,7 +760,7 @@ def test_create_tmp(self, repetitions=10): "tmp")), "File in wrong location: '%s'" % head) match = pattern.match(tail) - self.assertIsNot(match, None, "Invalid file name: '%s'" % tail) + self.assertIsNotNone(match, "Invalid file name: '%s'" % tail) groups = match.groups() if previous_groups is not None: self.assertGreaterEqual(int(groups[0]), int(previous_groups[0]), @@ -1020,7 +1020,7 @@ def test_open_close_open(self): mtime = os.path.getmtime(self._path) self._box = self._factory(self._path) self.assertEqual(len(self._box), 3) - for key in self._box.keys(): + for key in self._box.iterkeys(): self.assertIn(self._box.get_string(key), values) self._box.close() self.assertEqual(mtime, os.path.getmtime(self._path)) @@ -1394,7 +1394,7 @@ def test_initialize_with_nothing(self): self.assertIsInstance(msg, self._factory) self.assertEqual(msg.keys(), []) self.assertFalse(msg.is_multipart()) - self.assertEqual(msg.get_payload(), None) + self.assertIsNone(msg.get_payload()) def test_initialize_incorrectly(self): # Initialize with invalid argument @@ -1405,7 +1405,7 @@ def test_all_eMM_attribues_exist(self): eMM = email.message_from_string(_sample_message) msg = self._factory(_sample_message) for attr in eMM.__dict__: - self.assertTrue(attr in msg.__dict__, + self.assertIn(attr, msg.__dict__, '{} attribute does not exist'.format(attr)) def test_become_message(self): @@ -1547,8 +1547,9 @@ def _check_from(self, msg, sender=None): # Check contents of "From " line if sender is None: sender = "MAILER-DAEMON" - self.assertTrue(re.match(sender + r" \w{3} \w{3} [\d ]\d [\d ]\d:\d{2}:" - r"\d{2} \d{4}", msg.get_from()) is not None) + self.assertIsNotNone(re.match( + sender + r" \w{3} \w{3} [\d ]\d [\d ]\d:\d{2}:\d{2} \d{4}", + msg.get_from())) class TestMboxMessage(_TestMboxMMDFMessage, TestMessage): @@ -1622,19 +1623,19 @@ def test_visible(self): msg = mailbox.BabylMessage(_sample_message) visible = msg.get_visible() self.assertEqual(visible.keys(), []) - self.assertIs(visible.get_payload(), None) + self.assertIsNone(visible.get_payload()) visible['User-Agent'] = 'FooBar 1.0' visible['X-Whatever'] = 'Blah' self.assertEqual(msg.get_visible().keys(), []) msg.set_visible(visible) visible = msg.get_visible() - self.assertTrue(visible.keys() == ['User-Agent', 'X-Whatever']) - self.assertTrue(visible['User-Agent'] == 'FooBar 1.0') + self.assertEqual(visible.keys(), ['User-Agent', 'X-Whatever']) + self.assertEqual(visible['User-Agent'], 'FooBar 1.0') self.assertEqual(visible['X-Whatever'], 'Blah') - self.assertIs(visible.get_payload(), None) + self.assertIsNone(visible.get_payload()) msg.update_visible() self.assertEqual(visible.keys(), ['User-Agent', 'X-Whatever']) - self.assertIs(visible.get_payload(), None) + self.assertIsNone(visible.get_payload()) visible = msg.get_visible() self.assertEqual(visible.keys(), ['User-Agent', 'Date', 'From', 'To', 'Subject']) @@ -2156,34 +2157,34 @@ def test_empty_maildir(self): self.mbox = mailbox.Maildir(support.TESTFN) #self.assertTrue(hasattr(self.mbox, "boxes")) #self.assertEqual(len(self.mbox.boxes), 0) - self.assertIs(self.mbox.next(), None) - self.assertIs(self.mbox.next(), None) + self.assertIsNone(self.mbox.next()) + self.assertIsNone(self.mbox.next()) def test_nonempty_maildir_cur(self): self.createMessage("cur") self.mbox = mailbox.Maildir(support.TESTFN) #self.assertEqual(len(self.mbox.boxes), 1) - self.assertIsNot(self.mbox.next(), None) - self.assertIs(self.mbox.next(), None) - self.assertIs(self.mbox.next(), None) + self.assertIsNotNone(self.mbox.next()) + self.assertIsNone(self.mbox.next()) + self.assertIsNone(self.mbox.next()) def test_nonempty_maildir_new(self): self.createMessage("new") self.mbox = mailbox.Maildir(support.TESTFN) #self.assertEqual(len(self.mbox.boxes), 1) - self.assertIsNot(self.mbox.next(), None) - self.assertIs(self.mbox.next(), None) - self.assertIs(self.mbox.next(), None) + self.assertIsNotNone(self.mbox.next()) + self.assertIsNone(self.mbox.next()) + self.assertIsNone(self.mbox.next()) def test_nonempty_maildir_both(self): self.createMessage("cur") self.createMessage("new") self.mbox = mailbox.Maildir(support.TESTFN) #self.assertEqual(len(self.mbox.boxes), 2) - self.assertIsNot(self.mbox.next(), None) - self.assertIsNot(self.mbox.next(), None) - self.assertIs(self.mbox.next(), None) - self.assertIs(self.mbox.next(), None) + self.assertIsNotNone(self.mbox.next()) + self.assertIsNotNone(self.mbox.next()) + self.assertIsNone(self.mbox.next()) + self.assertIsNone(self.mbox.next()) ## End: tests from the original module (for backward compatibility). diff --git a/Lib/test/test_marshal.py b/Lib/test/test_marshal.py index 255eb87bb31d..c7def9a5995b 100644 --- a/Lib/test/test_marshal.py +++ b/Lib/test/test_marshal.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - from test import support import array import io @@ -9,6 +7,11 @@ import os import types +try: + import _testcapi +except ImportError: + _testcapi = None + class HelperMixin: def helper(self, sample, *extra): new = marshal.loads(marshal.dumps(sample, *extra)) @@ -190,7 +193,7 @@ def test_recursion_limit(self): head = last = [] # The max stack depth should match the value in Python/marshal.c. if os.name == 'nt' and hasattr(sys, 'gettotalrefcount'): - MAX_MARSHAL_STACK_DEPTH = 1500 + MAX_MARSHAL_STACK_DEPTH = 1000 else: MAX_MARSHAL_STACK_DEPTH = 2000 for i in range(MAX_MARSHAL_STACK_DEPTH - 2): @@ -288,19 +291,19 @@ class LargeValuesTestCase(unittest.TestCase): def check_unmarshallable(self, data): self.assertRaises(ValueError, marshal.dump, data, NullWriter()) - @support.bigmemtest(size=LARGE_SIZE, memuse=1, dry_run=False) + @support.bigmemtest(size=LARGE_SIZE, memuse=2, dry_run=False) def test_bytes(self, size): self.check_unmarshallable(b'x' * size) - @support.bigmemtest(size=LARGE_SIZE, memuse=1, dry_run=False) + @support.bigmemtest(size=LARGE_SIZE, memuse=2, dry_run=False) def test_str(self, size): self.check_unmarshallable('x' * size) - @support.bigmemtest(size=LARGE_SIZE, memuse=pointer_size, dry_run=False) + @support.bigmemtest(size=LARGE_SIZE, memuse=pointer_size + 1, dry_run=False) def test_tuple(self, size): self.check_unmarshallable((None,) * size) - @support.bigmemtest(size=LARGE_SIZE, memuse=pointer_size, dry_run=False) + @support.bigmemtest(size=LARGE_SIZE, memuse=pointer_size + 1, dry_run=False) def test_list(self, size): self.check_unmarshallable([None] * size) @@ -316,7 +319,7 @@ def test_set(self, size): def test_frozenset(self, size): self.check_unmarshallable(frozenset(range(size))) - @support.bigmemtest(size=LARGE_SIZE, memuse=1, dry_run=False) + @support.bigmemtest(size=LARGE_SIZE, memuse=2, dry_run=False) def test_bytearray(self, size): self.check_unmarshallable(bytearray(size)) @@ -436,18 +439,88 @@ def testNoIntern(self): s2 = sys.intern(s) self.assertNotEqual(id(s2), id(s)) +@support.cpython_only +@unittest.skipUnless(_testcapi, 'requires _testcapi') +class CAPI_TestCase(unittest.TestCase, HelperMixin): + + def test_write_long_to_file(self): + for v in range(marshal.version + 1): + _testcapi.pymarshal_write_long_to_file(0x12345678, support.TESTFN, v) + with open(support.TESTFN, 'rb') as f: + data = f.read() + support.unlink(support.TESTFN) + self.assertEqual(data, b'\x78\x56\x34\x12') + + def test_write_object_to_file(self): + obj = ('\u20ac', b'abc', 123, 45.6, 7+8j, 'long line '*1000) + for v in range(marshal.version + 1): + _testcapi.pymarshal_write_object_to_file(obj, support.TESTFN, v) + with open(support.TESTFN, 'rb') as f: + data = f.read() + support.unlink(support.TESTFN) + self.assertEqual(marshal.loads(data), obj) + + def test_read_short_from_file(self): + with open(support.TESTFN, 'wb') as f: + f.write(b'\x34\x12xxxx') + r, p = _testcapi.pymarshal_read_short_from_file(support.TESTFN) + support.unlink(support.TESTFN) + self.assertEqual(r, 0x1234) + self.assertEqual(p, 2) + + with open(support.TESTFN, 'wb') as f: + f.write(b'\x12') + with self.assertRaises(EOFError): + _testcapi.pymarshal_read_short_from_file(support.TESTFN) + support.unlink(support.TESTFN) + + def test_read_long_from_file(self): + with open(support.TESTFN, 'wb') as f: + f.write(b'\x78\x56\x34\x12xxxx') + r, p = _testcapi.pymarshal_read_long_from_file(support.TESTFN) + support.unlink(support.TESTFN) + self.assertEqual(r, 0x12345678) + self.assertEqual(p, 4) + + with open(support.TESTFN, 'wb') as f: + f.write(b'\x56\x34\x12') + with self.assertRaises(EOFError): + _testcapi.pymarshal_read_long_from_file(support.TESTFN) + support.unlink(support.TESTFN) + + def test_read_last_object_from_file(self): + obj = ('\u20ac', b'abc', 123, 45.6, 7+8j) + for v in range(marshal.version + 1): + data = marshal.dumps(obj, v) + with open(support.TESTFN, 'wb') as f: + f.write(data + b'xxxx') + r, p = _testcapi.pymarshal_read_last_object_from_file(support.TESTFN) + support.unlink(support.TESTFN) + self.assertEqual(r, obj) + + with open(support.TESTFN, 'wb') as f: + f.write(data[:1]) + with self.assertRaises(EOFError): + _testcapi.pymarshal_read_last_object_from_file(support.TESTFN) + support.unlink(support.TESTFN) + + def test_read_object_from_file(self): + obj = ('\u20ac', b'abc', 123, 45.6, 7+8j) + for v in range(marshal.version + 1): + data = marshal.dumps(obj, v) + with open(support.TESTFN, 'wb') as f: + f.write(data + b'xxxx') + r, p = _testcapi.pymarshal_read_object_from_file(support.TESTFN) + support.unlink(support.TESTFN) + self.assertEqual(r, obj) + self.assertEqual(p, len(data)) + + with open(support.TESTFN, 'wb') as f: + f.write(data[:1]) + with self.assertRaises(EOFError): + _testcapi.pymarshal_read_object_from_file(support.TESTFN) + support.unlink(support.TESTFN) -def test_main(): - support.run_unittest(IntTestCase, - FloatTestCase, - StringTestCase, - CodeTestCase, - ContainerTestCase, - ExceptionTestCase, - BufferTestCase, - BugsTestCase, - LargeValuesTestCase, - ) if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index 48f84ba73241..023dea94654a 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -422,9 +422,17 @@ def testFactorial(self): self.assertEqual(math.factorial(i), py_factorial(i)) self.assertRaises(ValueError, math.factorial, -1) self.assertRaises(ValueError, math.factorial, -1.0) + self.assertRaises(ValueError, math.factorial, -10**100) + self.assertRaises(ValueError, math.factorial, -1e100) self.assertRaises(ValueError, math.factorial, math.pi) - self.assertRaises(OverflowError, math.factorial, sys.maxsize+1) - self.assertRaises(OverflowError, math.factorial, 10e100) + + # Other implementations may place different upper bounds. + @support.cpython_only + def testFactorialHugeInputs(self): + # Currently raises ValueError for inputs that are too large + # to fit into a C long. + self.assertRaises(OverflowError, math.factorial, 10**100) + self.assertRaises(OverflowError, math.factorial, 1e100) def testFloor(self): self.assertRaises(TypeError, math.floor) @@ -975,6 +983,17 @@ def testIsinf(self): self.assertFalse(math.isinf(0.)) self.assertFalse(math.isinf(1.)) + @requires_IEEE_754 + def test_nan_constant(self): + self.assertTrue(math.isnan(math.nan)) + + @requires_IEEE_754 + def test_inf_constant(self): + self.assertTrue(math.isinf(math.inf)) + self.assertGreater(math.inf, 0.0) + self.assertEqual(math.inf, float("inf")) + self.assertEqual(-math.inf, float("-inf")) + # RED_FLAG 16-Oct-2000 Tim # While 2.0 is more consistent about exceptions than previous releases, it # still fails this part of the test on some platforms. For now, we only diff --git a/Lib/test/test_memoryio.py b/Lib/test/test_memoryio.py index 4de4f653297d..77749e78e8e3 100644 --- a/Lib/test/test_memoryio.py +++ b/Lib/test/test_memoryio.py @@ -9,6 +9,7 @@ import io import _pyio as pyio import pickle +import sys class MemorySeekTestMixin: @@ -366,13 +367,14 @@ def __init__(me, initvalue, foo): # the module-level. import __main__ PickleTestMemIO.__module__ = '__main__' + PickleTestMemIO.__qualname__ = PickleTestMemIO.__name__ __main__.PickleTestMemIO = PickleTestMemIO submemio = PickleTestMemIO(buf, 80) submemio.seek(2) # We only support pickle protocol 2 and onward since we use extended # __reduce__ API of PEP 307 to provide pickling support. - for proto in range(2, pickle.HIGHEST_PROTOCOL): + for proto in range(2, pickle.HIGHEST_PROTOCOL + 1): for obj in (memio, submemio): obj2 = pickle.loads(pickle.dumps(obj, protocol=proto)) self.assertEqual(obj.getvalue(), obj2.getvalue()) @@ -397,14 +399,19 @@ def test_getbuffer(self): # raises a BufferError. self.assertRaises(BufferError, memio.write, b'x' * 100) self.assertRaises(BufferError, memio.truncate) + self.assertRaises(BufferError, memio.close) + self.assertFalse(memio.closed) # Mutating the buffer updates the BytesIO buf[3:6] = b"abc" self.assertEqual(bytes(buf), b"123abc7890") self.assertEqual(memio.getvalue(), b"123abc7890") - # After the buffer gets released, we can resize the BytesIO again + # After the buffer gets released, we can resize and close the BytesIO + # again del buf support.gc_collect() memio.truncate() + memio.close() + self.assertRaises(ValueError, memio.getbuffer) class PyBytesIOTest(MemoryTestMixin, MemorySeekTestMixin, @@ -536,6 +543,17 @@ def test_textio_properties(self): self.assertIsNone(memio.errors) self.assertFalse(memio.line_buffering) + def test_newline_default(self): + memio = self.ioclass("a\nb\r\nc\rd") + self.assertEqual(list(memio), ["a\n", "b\r\n", "c\rd"]) + self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd") + + memio = self.ioclass() + self.assertEqual(memio.write("a\nb\r\nc\rd"), 8) + memio.seek(0) + self.assertEqual(list(memio), ["a\n", "b\r\n", "c\rd"]) + self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd") + def test_newline_none(self): # newline=None memio = self.ioclass("a\nb\r\nc\rd", newline=None) @@ -545,12 +563,16 @@ def test_newline_none(self): self.assertEqual(memio.read(2), "\nb") self.assertEqual(memio.read(2), "\nc") self.assertEqual(memio.read(1), "\n") + self.assertEqual(memio.getvalue(), "a\nb\nc\nd") + memio = self.ioclass(newline=None) self.assertEqual(2, memio.write("a\n")) self.assertEqual(3, memio.write("b\r\n")) self.assertEqual(3, memio.write("c\rd")) memio.seek(0) self.assertEqual(memio.read(), "a\nb\nc\nd") + self.assertEqual(memio.getvalue(), "a\nb\nc\nd") + memio = self.ioclass("a\r\nb", newline=None) self.assertEqual(memio.read(3), "a\nb") @@ -562,6 +584,8 @@ def test_newline_empty(self): self.assertEqual(memio.read(4), "a\nb\r") self.assertEqual(memio.read(2), "\nc") self.assertEqual(memio.read(1), "\r") + self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd") + memio = self.ioclass(newline="") self.assertEqual(2, memio.write("a\n")) self.assertEqual(2, memio.write("b\r")) @@ -569,11 +593,19 @@ def test_newline_empty(self): self.assertEqual(2, memio.write("\rd")) memio.seek(0) self.assertEqual(list(memio), ["a\n", "b\r\n", "c\r", "d"]) + self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd") def test_newline_lf(self): # newline="\n" - memio = self.ioclass("a\nb\r\nc\rd") + memio = self.ioclass("a\nb\r\nc\rd", newline="\n") + self.assertEqual(list(memio), ["a\n", "b\r\n", "c\rd"]) + self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd") + + memio = self.ioclass(newline="\n") + self.assertEqual(memio.write("a\nb\r\nc\rd"), 8) + memio.seek(0) self.assertEqual(list(memio), ["a\n", "b\r\n", "c\rd"]) + self.assertEqual(memio.getvalue(), "a\nb\r\nc\rd") def test_newline_cr(self): # newline="\r" @@ -581,6 +613,15 @@ def test_newline_cr(self): self.assertEqual(memio.read(), "a\rb\r\rc\rd") memio.seek(0) self.assertEqual(list(memio), ["a\r", "b\r", "\r", "c\r", "d"]) + self.assertEqual(memio.getvalue(), "a\rb\r\rc\rd") + + memio = self.ioclass(newline="\r") + self.assertEqual(memio.write("a\nb\r\nc\rd"), 8) + memio.seek(0) + self.assertEqual(list(memio), ["a\r", "b\r", "\r", "c\r", "d"]) + memio.seek(0) + self.assertEqual(memio.readlines(), ["a\r", "b\r", "\r", "c\r", "d"]) + self.assertEqual(memio.getvalue(), "a\rb\r\rc\rd") def test_newline_crlf(self): # newline="\r\n" @@ -588,11 +629,21 @@ def test_newline_crlf(self): self.assertEqual(memio.read(), "a\r\nb\r\r\nc\rd") memio.seek(0) self.assertEqual(list(memio), ["a\r\n", "b\r\r\n", "c\rd"]) + memio.seek(0) + self.assertEqual(memio.readlines(), ["a\r\n", "b\r\r\n", "c\rd"]) + self.assertEqual(memio.getvalue(), "a\r\nb\r\r\nc\rd") + + memio = self.ioclass(newline="\r\n") + self.assertEqual(memio.write("a\nb\r\nc\rd"), 8) + memio.seek(0) + self.assertEqual(list(memio), ["a\r\n", "b\r\r\n", "c\rd"]) + self.assertEqual(memio.getvalue(), "a\r\nb\r\r\nc\rd") def test_issue5265(self): # StringIO can duplicate newlines in universal newlines mode memio = self.ioclass("a\r\nb\r\n", newline=None) self.assertEqual(memio.read(5), "a\nb\n") + self.assertEqual(memio.getvalue(), "a\nb\n") def test_newline_argument(self): self.assertRaises(TypeError, self.ioclass, newline=b"\n") @@ -609,6 +660,15 @@ class PyStringIOTest(MemoryTestMixin, MemorySeekTestMixin, UnsupportedOperation = pyio.UnsupportedOperation EOF = "" + def test_lone_surrogates(self): + # Issue #20424 + memio = self.ioclass('\ud800') + self.assertEqual(memio.read(), '\ud800') + + memio = self.ioclass() + memio.write('\ud800') + self.assertEqual(memio.getvalue(), '\ud800') + class PyStringIOPickleTest(TextIOTestMixin, unittest.TestCase): """Test if pickle restores properly the internal state of StringIO. @@ -658,12 +718,56 @@ def test_setstate(self): @support.cpython_only def test_sizeof(self): - basesize = support.calcobjsize('P2nN2Pn') + basesize = support.calcobjsize('P2n2Pn') check = self.check_sizeof self.assertEqual(object.__sizeof__(io.BytesIO()), basesize) check(io.BytesIO(), basesize ) - check(io.BytesIO(b'a'), basesize + 1 + 1 ) - check(io.BytesIO(b'a' * 1000), basesize + 1000 + 1 ) + check(io.BytesIO(b'a' * 1000), basesize + sys.getsizeof(b'a' * 1000)) + + # Various tests of copy-on-write behaviour for BytesIO. + + def _test_cow_mutation(self, mutation): + # Common code for all BytesIO copy-on-write mutation tests. + imm = b' ' * 1024 + old_rc = sys.getrefcount(imm) + memio = self.ioclass(imm) + self.assertEqual(sys.getrefcount(imm), old_rc + 1) + mutation(memio) + self.assertEqual(sys.getrefcount(imm), old_rc) + + @support.cpython_only + def test_cow_truncate(self): + # Ensure truncate causes a copy. + def mutation(memio): + memio.truncate(1) + self._test_cow_mutation(mutation) + + @support.cpython_only + def test_cow_write(self): + # Ensure write that would not cause a resize still results in a copy. + def mutation(memio): + memio.seek(0) + memio.write(b'foo') + self._test_cow_mutation(mutation) + + @support.cpython_only + def test_cow_setstate(self): + # __setstate__ should cause buffer to be released. + memio = self.ioclass(b'foooooo') + state = memio.__getstate__() + def mutation(memio): + memio.__setstate__(state) + self._test_cow_mutation(mutation) + + @support.cpython_only + def test_cow_mutable(self): + # BytesIO should accept only Bytes for copy-on-write sharing, since + # arbitrary buffer-exporting objects like bytearray() aren't guaranteed + # to be immutable. + ba = bytearray(1024) + old_rc = sys.getrefcount(ba) + memio = self.ioclass(ba) + self.assertEqual(sys.getrefcount(ba), old_rc) class CStringIOTest(PyStringIOTest): ioclass = io.StringIO diff --git a/Lib/test/test_memoryview.py b/Lib/test/test_memoryview.py index ffd4f5851a20..e9bd9fdf82c3 100644 --- a/Lib/test/test_memoryview.py +++ b/Lib/test/test_memoryview.py @@ -57,7 +57,7 @@ def test_iter(self): def test_setitem_readonly(self): if not self.ro_type: - return + self.skipTest("no read-only type to test") b = self.ro_type(self._source) oldrefcount = sys.getrefcount(b) m = self._view(b) @@ -71,7 +71,7 @@ def setitem(value): def test_setitem_writable(self): if not self.rw_type: - return + self.skipTest("no writable type to test") tp = self.rw_type b = self.rw_type(self._source) oldrefcount = sys.getrefcount(b) @@ -189,13 +189,13 @@ def check_attributes_with_type(self, tp): def test_attributes_readonly(self): if not self.ro_type: - return + self.skipTest("no read-only type to test") m = self.check_attributes_with_type(self.ro_type) self.assertEqual(m.readonly, True) def test_attributes_writable(self): if not self.rw_type: - return + self.skipTest("no writable type to test") m = self.check_attributes_with_type(self.rw_type) self.assertEqual(m.readonly, False) @@ -301,7 +301,7 @@ def test_writable_readonly(self): # buffer as writable causing a segfault if using mmap tp = self.ro_type if tp is None: - return + self.skipTest("no read-only type to test") b = tp(self._source) m = self._view(b) i = io.BytesIO(b'ZZZZ') @@ -360,6 +360,27 @@ def test_reversed(self): self.assertEqual(list(reversed(m)), aslist) self.assertEqual(list(reversed(m)), list(m[::-1])) + def test_issue22668(self): + a = array.array('H', [256, 256, 256, 256]) + x = memoryview(a) + m = x.cast('B') + b = m.cast('H') + c = b[0:2] + d = memoryview(b) + + del b + + self.assertEqual(c[0], 256) + self.assertEqual(d[0], 256) + self.assertEqual(c.format, "H") + self.assertEqual(d.format, "H") + + _ = m.cast('I') + self.assertEqual(c[0], 256) + self.assertEqual(d[0], 256) + self.assertEqual(c.format, "H") + self.assertEqual(d.format, "H") + # Variations on source objects for the buffer: bytes-like objects, then arrays # with itemsize > 1. @@ -379,12 +400,12 @@ class BaseArrayMemoryTests(AbstractMemoryTests): itemsize = array.array('i').itemsize format = 'i' + @unittest.skip('XXX test should be adapted for non-byte buffers') def test_getbuffer(self): - # XXX Test should be adapted for non-byte buffers pass + @unittest.skip('XXX NotImplementedError: tolist() only supports byte views') def test_tolist(self): - # XXX NotImplementedError: tolist() only supports byte views pass diff --git a/Lib/test/test_minidom.py b/Lib/test/test_minidom.py index a1516c242da5..d06a83d61121 100644 --- a/Lib/test/test_minidom.py +++ b/Lib/test/test_minidom.py @@ -1468,43 +1468,44 @@ def testPickledDocument(self): " \n" "]> text\n" " ") - s = pickle.dumps(doc) - doc2 = pickle.loads(s) - stack = [(doc, doc2)] - while stack: - n1, n2 = stack.pop() - self.confirm(n1.nodeType == n2.nodeType - and len(n1.childNodes) == len(n2.childNodes) - and n1.nodeName == n2.nodeName - and not n1.isSameNode(n2) - and not n2.isSameNode(n1)) - if n1.nodeType == Node.DOCUMENT_TYPE_NODE: - len(n1.entities) - len(n2.entities) - len(n1.notations) - len(n2.notations) - self.confirm(len(n1.entities) == len(n2.entities) - and len(n1.notations) == len(n2.notations)) - for i in range(len(n1.notations)): - # XXX this loop body doesn't seem to be executed? - no1 = n1.notations.item(i) - no2 = n1.notations.item(i) - self.confirm(no1.name == no2.name - and no1.publicId == no2.publicId - and no1.systemId == no2.systemId) - stack.append((no1, no2)) - for i in range(len(n1.entities)): - e1 = n1.entities.item(i) - e2 = n2.entities.item(i) - self.confirm(e1.notationName == e2.notationName - and e1.publicId == e2.publicId - and e1.systemId == e2.systemId) - stack.append((e1, e2)) - if n1.nodeType != Node.DOCUMENT_NODE: - self.confirm(n1.ownerDocument.isSameNode(doc) - and n2.ownerDocument.isSameNode(doc2)) - for i in range(len(n1.childNodes)): - stack.append((n1.childNodes[i], n2.childNodes[i])) + for proto in range(2, pickle.HIGHEST_PROTOCOL + 1): + s = pickle.dumps(doc, proto) + doc2 = pickle.loads(s) + stack = [(doc, doc2)] + while stack: + n1, n2 = stack.pop() + self.confirm(n1.nodeType == n2.nodeType + and len(n1.childNodes) == len(n2.childNodes) + and n1.nodeName == n2.nodeName + and not n1.isSameNode(n2) + and not n2.isSameNode(n1)) + if n1.nodeType == Node.DOCUMENT_TYPE_NODE: + len(n1.entities) + len(n2.entities) + len(n1.notations) + len(n2.notations) + self.confirm(len(n1.entities) == len(n2.entities) + and len(n1.notations) == len(n2.notations)) + for i in range(len(n1.notations)): + # XXX this loop body doesn't seem to be executed? + no1 = n1.notations.item(i) + no2 = n1.notations.item(i) + self.confirm(no1.name == no2.name + and no1.publicId == no2.publicId + and no1.systemId == no2.systemId) + stack.append((no1, no2)) + for i in range(len(n1.entities)): + e1 = n1.entities.item(i) + e2 = n2.entities.item(i) + self.confirm(e1.notationName == e2.notationName + and e1.publicId == e2.publicId + and e1.systemId == e2.systemId) + stack.append((e1, e2)) + if n1.nodeType != Node.DOCUMENT_NODE: + self.confirm(n1.ownerDocument.isSameNode(doc) + and n2.ownerDocument.isSameNode(doc2)) + for i in range(len(n1.childNodes)): + stack.append((n1.childNodes[i], n2.childNodes[i])) def testSerializeCommentNodeWithDoubleHyphen(self): doc = create_doc_without_doctype() @@ -1518,6 +1519,10 @@ def testEmptyXMLNSValue(self): doc2 = parseString(doc.toxml()) self.confirm(doc2.namespaceURI == xml.dom.EMPTY_NAMESPACE) + def testExceptionOnSpacesInXMLNSValue(self): + with self.assertRaisesRegex(ValueError, 'Unsupported syntax'): + parseString('') + def testDocRemoveChild(self): doc = parse(tstfile) title_tag = doc.documentElement.getElementsByTagName("TITLE")[0] @@ -1527,6 +1532,13 @@ def testDocRemoveChild(self): num_children_after = len(doc.childNodes) self.assertTrue(num_children_after == num_children_before - 1) + def testProcessingInstructionNameError(self): + # wrong variable in .nodeValue property will + # lead to "NameError: name 'data' is not defined" + doc = parse(tstfile) + pi = doc.createProcessingInstruction("y", "z") + pi.nodeValue = "crash" + def test_main(): run_unittest(MinidomTest) diff --git a/Lib/test/test_mmap.py b/Lib/test/test_mmap.py index 6ca5e1b73096..4d23f1689079 100644 --- a/Lib/test/test_mmap.py +++ b/Lib/test/test_mmap.py @@ -1,5 +1,5 @@ from test.support import (TESTFN, run_unittest, import_module, unlink, - requires, _2G, _4G, gc_collect) + requires, _2G, _4G, gc_collect, cpython_only) import unittest import os import re @@ -639,6 +639,15 @@ def test_tagname(self): m2.close() m1.close() + @cpython_only + @unittest.skipUnless(os.name == 'nt', 'requires Windows') + def test_sizeof(self): + m1 = mmap.mmap(-1, 100) + tagname = "foo" + m2 = mmap.mmap(-1, 100, tagname=tagname) + self.assertEqual(sys.getsizeof(m2), + sys.getsizeof(m1) + len(tagname) + 1) + @unittest.skipUnless(os.name == 'nt', 'requires Windows') def test_crasher_on_windows(self): # Should not crash (Issue 1733986) diff --git a/Lib/test/test_module.py b/Lib/test/test_module.py index 123029367008..9da353633385 100644 --- a/Lib/test/test_module.py +++ b/Lib/test/test_module.py @@ -30,6 +30,22 @@ def test_uninitialized(self): pass self.assertEqual(foo.__doc__, ModuleType.__doc__) + def test_unintialized_missing_getattr(self): + # Issue 8297 + # test the text in the AttributeError of an uninitialized module + foo = ModuleType.__new__(ModuleType) + self.assertRaisesRegex( + AttributeError, "module has no attribute 'not_here'", + getattr, foo, "not_here") + + def test_missing_getattr(self): + # Issue 8297 + # test the text in the AttributeError + foo = ModuleType("foo") + self.assertRaisesRegex( + AttributeError, "module 'foo' has no attribute 'not_here'", + getattr, foo, "not_here") + def test_no_docstring(self): # Regularly initialized module, no docstring foo = ModuleType("foo") @@ -211,6 +227,14 @@ def test_module_finalization_at_shutdown(self): b"len = len", b"shutil.rmtree = rmtree"}) + def test_descriptor_errors_propogate(self): + class Descr: + def __get__(self, o, t): + raise RuntimeError + class M(ModuleType): + melon = Descr() + self.assertRaises(RuntimeError, getattr, M("mymod"), "melon") + # frozen and namespace module reprs are tested in importlib. diff --git a/Lib/test/test_modulefinder.py b/Lib/test/test_modulefinder.py index 53ea23217491..4c49e9aeafcd 100644 --- a/Lib/test/test_modulefinder.py +++ b/Lib/test/test_modulefinder.py @@ -1,5 +1,7 @@ import os import errno +import importlib.machinery +import py_compile import shutil import unittest import tempfile @@ -208,6 +210,14 @@ def foo(): pass from . import * """] +bytecode_test = [ + "a", + ["a"], + [], + [], + "" +] + def open_file(path): dirname = os.path.dirname(path) @@ -235,11 +245,12 @@ def create_package(source): class ModuleFinderTest(unittest.TestCase): - def _do_test(self, info, report=False): + def _do_test(self, info, report=False, debug=0, replace_paths=[]): import_this, modules, missing, maybe_missing, source = info create_package(source) try: - mf = modulefinder.ModuleFinder(path=TEST_PATH) + mf = modulefinder.ModuleFinder(path=TEST_PATH, debug=debug, + replace_paths=replace_paths) mf.import_hook(import_this) if report: mf.report() @@ -288,9 +299,26 @@ def test_relative_imports_3(self): def test_relative_imports_4(self): self._do_test(relative_import_test_4) + def test_bytecode(self): + base_path = os.path.join(TEST_DIR, 'a') + source_path = base_path + importlib.machinery.SOURCE_SUFFIXES[0] + bytecode_path = base_path + importlib.machinery.BYTECODE_SUFFIXES[0] + with open_file(source_path) as file: + file.write('testing_modulefinder = True\n') + py_compile.compile(source_path, cfile=bytecode_path) + os.remove(source_path) + self._do_test(bytecode_test) + + def test_replace_paths(self): + old_path = os.path.join(TEST_DIR, 'a', 'module.py') + new_path = os.path.join(TEST_DIR, 'a', 'spam.py') + with support.captured_stdout() as output: + self._do_test(maybe_test, debug=2, + replace_paths=[(old_path, new_path)]) + output = output.getvalue() + expected = "co_filename %r changed to %r" % (old_path, new_path) + self.assertIn(expected, output) -def test_main(): - support.run_unittest(ModuleFinderTest) if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_multibytecodec.py b/Lib/test/test_multibytecodec.py index 91148a6fc52d..2929f988a8e5 100644 --- a/Lib/test/test_multibytecodec.py +++ b/Lib/test/test_multibytecodec.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 # # test_multibytecodec.py # Unit test for multibytecodec itself @@ -45,6 +44,13 @@ def test_errorcallback_longindex(self): self.assertRaises(IndexError, dec, b'apple\x92ham\x93spam', 'test.cjktest') + def test_errorcallback_custom_ignore(self): + # Issue #23215: MemoryError with custom error handlers and multibyte codecs + data = 100 * "\udc00" + codecs.register_error("test.ignore", codecs.ignore_errors) + for enc in ALL_CJKENCODINGS: + self.assertEqual(data.encode(enc, "test.ignore"), b'') + def test_codingspec(self): try: for enc in ALL_CJKENCODINGS: @@ -81,7 +87,7 @@ def test_stateless(self): self.assertEqual(encoder.reset(), None) def test_stateful(self): - # jisx0213 encoder is stateful for a few codepoints. eg) + # jisx0213 encoder is stateful for a few code points. eg) # U+00E6 => A9DC # U+00E6 U+0300 => ABC4 # U+0300 => ABDC diff --git a/Lib/test/test_multiprocessing_main_handling.py b/Lib/test/test_multiprocessing_main_handling.py new file mode 100644 index 000000000000..97539e061eae --- /dev/null +++ b/Lib/test/test_multiprocessing_main_handling.py @@ -0,0 +1,289 @@ +# tests __main__ module handling in multiprocessing +from test import support +# Skip tests if _thread or _multiprocessing wasn't built. +support.import_module('_thread') +support.import_module('_multiprocessing') + +import importlib +import importlib.machinery +import zipimport +import unittest +import sys +import os +import os.path +import py_compile + +from test.script_helper import ( + make_pkg, make_script, make_zip_pkg, make_zip_script, + assert_python_ok, assert_python_failure, temp_dir, + spawn_python, kill_python) + +# Look up which start methods are available to test +import multiprocessing +AVAILABLE_START_METHODS = set(multiprocessing.get_all_start_methods()) + +# Issue #22332: Skip tests if sem_open implementation is broken. +support.import_module('multiprocessing.synchronize') + +verbose = support.verbose + +test_source = """\ +# multiprocessing includes all sorts of shenanigans to make __main__ +# attributes accessible in the subprocess in a pickle compatible way. + +# We run the "doesn't work in the interactive interpreter" example from +# the docs to make sure it *does* work from an executed __main__, +# regardless of the invocation mechanism + +import sys +import time +from multiprocessing import Pool, set_start_method + +# We use this __main__ defined function in the map call below in order to +# check that multiprocessing in correctly running the unguarded +# code in child processes and then making it available as __main__ +def f(x): + return x*x + +# Check explicit relative imports +if "check_sibling" in __file__: + # We're inside a package and not in a __main__.py file + # so make sure explicit relative imports work correctly + from . import sibling + +if __name__ == '__main__': + start_method = sys.argv[1] + set_start_method(start_method) + p = Pool(5) + results = [] + p.map_async(f, [1, 2, 3], callback=results.extend) + deadline = time.time() + 10 # up to 10 s to report the results + while not results: + time.sleep(0.05) + if time.time() > deadline: + raise RuntimeError("Timed out waiting for results") + results.sort() + print(start_method, "->", results) +""" + +test_source_main_skipped_in_children = """\ +# __main__.py files have an implied "if __name__ == '__main__'" so +# multiprocessing should always skip running them in child processes + +# This means we can't use __main__ defined functions in child processes, +# so we just use "int" as a passthrough operation below + +if __name__ != "__main__": + raise RuntimeError("Should only be called as __main__!") + +import sys +import time +from multiprocessing import Pool, set_start_method + +start_method = sys.argv[1] +set_start_method(start_method) +p = Pool(5) +results = [] +p.map_async(int, [1, 4, 9], callback=results.extend) +deadline = time.time() + 10 # up to 10 s to report the results +while not results: + time.sleep(0.05) + if time.time() > deadline: + raise RuntimeError("Timed out waiting for results") +results.sort() +print(start_method, "->", results) +""" + +# These helpers were copied from test_cmd_line_script & tweaked a bit... + +def _make_test_script(script_dir, script_basename, + source=test_source, omit_suffix=False): + to_return = make_script(script_dir, script_basename, + source, omit_suffix) + # Hack to check explicit relative imports + if script_basename == "check_sibling": + make_script(script_dir, "sibling", "") + importlib.invalidate_caches() + return to_return + +def _make_test_zip_pkg(zip_dir, zip_basename, pkg_name, script_basename, + source=test_source, depth=1): + to_return = make_zip_pkg(zip_dir, zip_basename, pkg_name, script_basename, + source, depth) + importlib.invalidate_caches() + return to_return + +# There's no easy way to pass the script directory in to get +# -m to work (avoiding that is the whole point of making +# directories and zipfiles executable!) +# So we fake it for testing purposes with a custom launch script +launch_source = """\ +import sys, os.path, runpy +sys.path.insert(0, %s) +runpy._run_module_as_main(%r) +""" + +def _make_launch_script(script_dir, script_basename, module_name, path=None): + if path is None: + path = "os.path.dirname(__file__)" + else: + path = repr(path) + source = launch_source % (path, module_name) + to_return = make_script(script_dir, script_basename, source) + importlib.invalidate_caches() + return to_return + +class MultiProcessingCmdLineMixin(): + maxDiff = None # Show full tracebacks on subprocess failure + + def setUp(self): + if self.start_method not in AVAILABLE_START_METHODS: + self.skipTest("%r start method not available" % self.start_method) + + def _check_output(self, script_name, exit_code, out, err): + if verbose > 1: + print("Output from test script %r:" % script_name) + print(out) + self.assertEqual(exit_code, 0) + self.assertEqual(err.decode('utf-8'), '') + expected_results = "%s -> [1, 4, 9]" % self.start_method + self.assertEqual(out.decode('utf-8').strip(), expected_results) + + def _check_script(self, script_name, *cmd_line_switches): + if not __debug__: + cmd_line_switches += ('-' + 'O' * sys.flags.optimize,) + run_args = cmd_line_switches + (script_name, self.start_method) + rc, out, err = assert_python_ok(*run_args, __isolated=False) + self._check_output(script_name, rc, out, err) + + def test_basic_script(self): + with temp_dir() as script_dir: + script_name = _make_test_script(script_dir, 'script') + self._check_script(script_name) + + def test_basic_script_no_suffix(self): + with temp_dir() as script_dir: + script_name = _make_test_script(script_dir, 'script', + omit_suffix=True) + self._check_script(script_name) + + def test_ipython_workaround(self): + # Some versions of the IPython launch script are missing the + # __name__ = "__main__" guard, and multiprocessing has long had + # a workaround for that case + # See https://github.com/ipython/ipython/issues/4698 + source = test_source_main_skipped_in_children + with temp_dir() as script_dir: + script_name = _make_test_script(script_dir, 'ipython', + source=source) + self._check_script(script_name) + script_no_suffix = _make_test_script(script_dir, 'ipython', + source=source, + omit_suffix=True) + self._check_script(script_no_suffix) + + def test_script_compiled(self): + with temp_dir() as script_dir: + script_name = _make_test_script(script_dir, 'script') + py_compile.compile(script_name, doraise=True) + os.remove(script_name) + pyc_file = support.make_legacy_pyc(script_name) + self._check_script(pyc_file) + + def test_directory(self): + source = self.main_in_children_source + with temp_dir() as script_dir: + script_name = _make_test_script(script_dir, '__main__', + source=source) + self._check_script(script_dir) + + def test_directory_compiled(self): + source = self.main_in_children_source + with temp_dir() as script_dir: + script_name = _make_test_script(script_dir, '__main__', + source=source) + py_compile.compile(script_name, doraise=True) + os.remove(script_name) + pyc_file = support.make_legacy_pyc(script_name) + self._check_script(script_dir) + + def test_zipfile(self): + source = self.main_in_children_source + with temp_dir() as script_dir: + script_name = _make_test_script(script_dir, '__main__', + source=source) + zip_name, run_name = make_zip_script(script_dir, 'test_zip', script_name) + self._check_script(zip_name) + + def test_zipfile_compiled(self): + source = self.main_in_children_source + with temp_dir() as script_dir: + script_name = _make_test_script(script_dir, '__main__', + source=source) + compiled_name = py_compile.compile(script_name, doraise=True) + zip_name, run_name = make_zip_script(script_dir, 'test_zip', compiled_name) + self._check_script(zip_name) + + def test_module_in_package(self): + with temp_dir() as script_dir: + pkg_dir = os.path.join(script_dir, 'test_pkg') + make_pkg(pkg_dir) + script_name = _make_test_script(pkg_dir, 'check_sibling') + launch_name = _make_launch_script(script_dir, 'launch', + 'test_pkg.check_sibling') + self._check_script(launch_name) + + def test_module_in_package_in_zipfile(self): + with temp_dir() as script_dir: + zip_name, run_name = _make_test_zip_pkg(script_dir, 'test_zip', 'test_pkg', 'script') + launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg.script', zip_name) + self._check_script(launch_name) + + def test_module_in_subpackage_in_zipfile(self): + with temp_dir() as script_dir: + zip_name, run_name = _make_test_zip_pkg(script_dir, 'test_zip', 'test_pkg', 'script', depth=2) + launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg.test_pkg.script', zip_name) + self._check_script(launch_name) + + def test_package(self): + source = self.main_in_children_source + with temp_dir() as script_dir: + pkg_dir = os.path.join(script_dir, 'test_pkg') + make_pkg(pkg_dir) + script_name = _make_test_script(pkg_dir, '__main__', + source=source) + launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg') + self._check_script(launch_name) + + def test_package_compiled(self): + source = self.main_in_children_source + with temp_dir() as script_dir: + pkg_dir = os.path.join(script_dir, 'test_pkg') + make_pkg(pkg_dir) + script_name = _make_test_script(pkg_dir, '__main__', + source=source) + compiled_name = py_compile.compile(script_name, doraise=True) + os.remove(script_name) + pyc_file = support.make_legacy_pyc(script_name) + launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg') + self._check_script(launch_name) + +# Test all supported start methods (setupClass skips as appropriate) + +class SpawnCmdLineTest(MultiProcessingCmdLineMixin, unittest.TestCase): + start_method = 'spawn' + main_in_children_source = test_source_main_skipped_in_children + +class ForkCmdLineTest(MultiProcessingCmdLineMixin, unittest.TestCase): + start_method = 'fork' + main_in_children_source = test_source + +class ForkServerCmdLineTest(MultiProcessingCmdLineMixin, unittest.TestCase): + start_method = 'forkserver' + main_in_children_source = test_source_main_skipped_in_children + +def tearDownModule(): + support.reap_children() + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_nis.py b/Lib/test/test_nis.py index 830c24d78130..a3a3c260e379 100644 --- a/Lib/test/test_nis.py +++ b/Lib/test/test_nis.py @@ -12,11 +12,7 @@ def test_maps(self): maps = nis.maps() except nis.error as msg: # NIS is probably not active, so this test isn't useful - if support.verbose: - print("Test Skipped:", msg) - # Can't raise SkipTest as regrtest only recognizes the exception - # import time. - return + self.skipTest(str(msg)) try: # On some systems, this map is only accessible to the # super user diff --git a/Lib/test/test_nntplib.py b/Lib/test/test_nntplib.py index 71a4ec022b14..fb216c1f52c4 100644 --- a/Lib/test/test_nntplib.py +++ b/Lib/test/test_nntplib.py @@ -1412,11 +1412,18 @@ def gives(y, M, d, date_str, time_str): def test_ssl_support(self): self.assertTrue(hasattr(nntplib, 'NNTP_SSL')) -def test_main(): - tests = [MiscTests, NNTPv1Tests, NNTPv2Tests, CapsAfterLoginNNTPv2Tests, - SendReaderNNTPv2Tests, NetworkedNNTPTests, NetworkedNNTP_SSLTests] - support.run_unittest(*tests) +class PublicAPITests(unittest.TestCase): + """Ensures that the correct values are exposed in the public API.""" + + def test_module_all_attribute(self): + self.assertTrue(hasattr(nntplib, '__all__')) + target_api = ['NNTP', 'NNTPError', 'NNTPReplyError', + 'NNTPTemporaryError', 'NNTPPermanentError', + 'NNTPProtocolError', 'NNTPDataError', 'decode_header'] + if ssl is not None: + target_api.append('NNTP_SSL') + self.assertEqual(set(nntplib.__all__), set(target_api)) if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_normalization.py b/Lib/test/test_normalization.py index ab2eeb77da00..5dac5db37ec1 100644 --- a/Lib/test/test_normalization.py +++ b/Lib/test/test_normalization.py @@ -7,7 +7,7 @@ from unicodedata import normalize, unidata_version TESTDATAFILE = "NormalizationTest.txt" -TESTDATAURL = "http://www.unicode.org/Public/" + unidata_version + "/ucd/" + TESTDATAFILE +TESTDATAURL = "http://www.pythontest.net/unicode/" + unidata_version + "/" + TESTDATAFILE def check_version(testfile): hdr = testfile.readline() diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py index 285ef62a46ad..c8d84a7467c9 100644 --- a/Lib/test/test_ntpath.py +++ b/Lib/test/test_ntpath.py @@ -22,13 +22,15 @@ def tester(fn, wantResult): fn = fn.replace('["', '[b"') fn = fn.replace(", '", ", b'") fn = fn.replace(', "', ', b"') + fn = os.fsencode(fn).decode('latin1') + fn = fn.encode('ascii', 'backslashreplace').decode('ascii') with warnings.catch_warnings(): warnings.simplefilter("ignore", DeprecationWarning) gotResult = eval(fn) if isinstance(wantResult, str): - wantResult = wantResult.encode('ascii') + wantResult = os.fsencode(wantResult) elif isinstance(wantResult, tuple): - wantResult = tuple(r.encode('ascii') for r in wantResult) + wantResult = tuple(os.fsencode(r) for r in wantResult) gotResult = eval(fn) if wantResult != gotResult: @@ -66,6 +68,32 @@ def test_splitdrive(self): ('', '\\\\conky\\\\mountpoint\\foo\\bar')) tester('ntpath.splitdrive("//conky//mountpoint/foo/bar")', ('', '//conky//mountpoint/foo/bar')) + # Issue #19911: UNC part containing U+0130 + self.assertEqual(ntpath.splitdrive('//conky/MOUNTPOİNT/foo/bar'), + ('//conky/MOUNTPOİNT', '/foo/bar')) + + def test_splitunc(self): + with self.assertWarns(DeprecationWarning): + ntpath.splitunc('') + with support.check_warnings(('', DeprecationWarning)): + tester('ntpath.splitunc("c:\\foo\\bar")', + ('', 'c:\\foo\\bar')) + tester('ntpath.splitunc("c:/foo/bar")', + ('', 'c:/foo/bar')) + tester('ntpath.splitunc("\\\\conky\\mountpoint\\foo\\bar")', + ('\\\\conky\\mountpoint', '\\foo\\bar')) + tester('ntpath.splitunc("//conky/mountpoint/foo/bar")', + ('//conky/mountpoint', '/foo/bar')) + tester('ntpath.splitunc("\\\\\\conky\\mountpoint\\foo\\bar")', + ('', '\\\\\\conky\\mountpoint\\foo\\bar')) + tester('ntpath.splitunc("///conky/mountpoint/foo/bar")', + ('', '///conky/mountpoint/foo/bar')) + tester('ntpath.splitunc("\\\\conky\\\\mountpoint\\foo\\bar")', + ('', '\\\\conky\\\\mountpoint\\foo\\bar')) + tester('ntpath.splitunc("//conky//mountpoint/foo/bar")', + ('', '//conky//mountpoint/foo/bar')) + self.assertEqual(ntpath.splitunc('//conky/MOUNTPOİNT/foo/bar'), + ('//conky/MOUNTPOİNT', '/foo/bar')) def test_split(self): tester('ntpath.split("c:\\foo\\bar")', ('c:\\foo', 'bar')) @@ -100,10 +128,7 @@ def test_join(self): tester('ntpath.join("/a")', '/a') tester('ntpath.join("\\a")', '\\a') tester('ntpath.join("a:")', 'a:') - tester('ntpath.join("a:", "b")', 'a:b') - tester('ntpath.join("a:", "/b")', 'a:/b') tester('ntpath.join("a:", "\\b")', 'a:\\b') - tester('ntpath.join("a", "/b")', '/b') tester('ntpath.join("a", "\\b")', '\\b') tester('ntpath.join("a", "b", "c")', 'a\\b\\c') tester('ntpath.join("a\\", "b", "c")', 'a\\b\\c') @@ -111,42 +136,48 @@ def test_join(self): tester('ntpath.join("a", "b", "\\c")', '\\c') tester('ntpath.join("d:\\", "\\pleep")', 'd:\\pleep') tester('ntpath.join("d:\\", "a", "b")', 'd:\\a\\b') - tester("ntpath.join('c:', '/a')", 'c:/a') - tester("ntpath.join('c:/', '/a')", 'c:/a') - tester("ntpath.join('c:/a', '/b')", '/b') - tester("ntpath.join('c:', 'd:/')", 'd:/') - tester("ntpath.join('c:/', 'd:/')", 'd:/') - tester("ntpath.join('c:/', 'd:/a/b')", 'd:/a/b') - - tester("ntpath.join('')", '') - tester("ntpath.join('', '', '', '', '')", '') - tester("ntpath.join('a')", 'a') + tester("ntpath.join('', 'a')", 'a') tester("ntpath.join('', '', '', '', 'a')", 'a') tester("ntpath.join('a', '')", 'a\\') tester("ntpath.join('a', '', '', '', '')", 'a\\') tester("ntpath.join('a\\', '')", 'a\\') tester("ntpath.join('a\\', '', '', '', '')", 'a\\') - - # from comment in ntpath.join - tester("ntpath.join('c:', '/a')", 'c:/a') - tester("ntpath.join('//computer/share', '/a')", '//computer/share/a') - tester("ntpath.join('c:/', '/a')", 'c:/a') - tester("ntpath.join('//computer/share/', '/a')", '//computer/share/a') - tester("ntpath.join('c:/a', '/b')", '/b') - tester("ntpath.join('//computer/share/a', '/b')", '/b') - tester("ntpath.join('c:', 'd:/')", 'd:/') - tester("ntpath.join('c:', '//computer/share/')", '//computer/share/') - tester("ntpath.join('//computer/share', 'd:/')", 'd:/') - tester("ntpath.join('//computer/share', '//computer/share/')", '//computer/share/') - tester("ntpath.join('c:/', 'd:/')", 'd:/') - tester("ntpath.join('c:/', '//computer/share/')", '//computer/share/') - tester("ntpath.join('//computer/share/', 'd:/')", 'd:/') - tester("ntpath.join('//computer/share/', '//computer/share/')", '//computer/share/') - - tester("ntpath.join('c:', '//computer/share/')", '//computer/share/') - tester("ntpath.join('c:/', '//computer/share/')", '//computer/share/') - tester("ntpath.join('c:/', '//computer/share/a/b')", '//computer/share/a/b') + tester("ntpath.join('a/', '')", 'a/') + + tester("ntpath.join('a/b', 'x/y')", 'a/b\\x/y') + tester("ntpath.join('/a/b', 'x/y')", '/a/b\\x/y') + tester("ntpath.join('/a/b/', 'x/y')", '/a/b/x/y') + tester("ntpath.join('c:', 'x/y')", 'c:x/y') + tester("ntpath.join('c:a/b', 'x/y')", 'c:a/b\\x/y') + tester("ntpath.join('c:a/b/', 'x/y')", 'c:a/b/x/y') + tester("ntpath.join('c:/', 'x/y')", 'c:/x/y') + tester("ntpath.join('c:/a/b', 'x/y')", 'c:/a/b\\x/y') + tester("ntpath.join('c:/a/b/', 'x/y')", 'c:/a/b/x/y') + tester("ntpath.join('//computer/share', 'x/y')", '//computer/share\\x/y') + tester("ntpath.join('//computer/share/', 'x/y')", '//computer/share/x/y') + tester("ntpath.join('//computer/share/a/b', 'x/y')", '//computer/share/a/b\\x/y') + + tester("ntpath.join('a/b', '/x/y')", '/x/y') + tester("ntpath.join('/a/b', '/x/y')", '/x/y') + tester("ntpath.join('c:', '/x/y')", 'c:/x/y') + tester("ntpath.join('c:a/b', '/x/y')", 'c:/x/y') + tester("ntpath.join('c:/', '/x/y')", 'c:/x/y') + tester("ntpath.join('c:/a/b', '/x/y')", 'c:/x/y') + tester("ntpath.join('//computer/share', '/x/y')", '//computer/share/x/y') + tester("ntpath.join('//computer/share/', '/x/y')", '//computer/share/x/y') + tester("ntpath.join('//computer/share/a', '/x/y')", '//computer/share/x/y') + + tester("ntpath.join('c:', 'C:x/y')", 'C:x/y') + tester("ntpath.join('c:a/b', 'C:x/y')", 'C:a/b\\x/y') + tester("ntpath.join('c:/', 'C:x/y')", 'C:/x/y') + tester("ntpath.join('c:/a/b', 'C:x/y')", 'C:/a/b\\x/y') + + for x in ('', 'a/b', '/a/b', 'c:', 'c:a/b', 'c:/', 'c:/a/b', + '//computer/share', '//computer/share/', '//computer/share/a/b'): + for y in ('d:', 'd:x/y', 'd:/', 'd:/x/y', + '//machine/common', '//machine/common/', '//machine/common/x/y'): + tester("ntpath.join(%r, %r)" % (x, y), y) tester("ntpath.join('\\\\computer\\share\\', 'a', 'b')", '\\\\computer\\share\\a\\b') tester("ntpath.join('\\\\computer\\share', 'a', 'b')", '\\\\computer\\share\\a\\b') @@ -194,7 +225,6 @@ def test_expandvars(self): tester('ntpath.expandvars("$[foo]bar")', "$[foo]bar") tester('ntpath.expandvars("$bar bar")', "$bar bar") tester('ntpath.expandvars("$?bar")', "$?bar") - tester('ntpath.expandvars("${foo}bar")', "barbar") tester('ntpath.expandvars("$foo}bar")', "bar}bar") tester('ntpath.expandvars("${foo")', "${foo") tester('ntpath.expandvars("${{foo}}")', "baz1}") @@ -208,6 +238,61 @@ def test_expandvars(self): tester('ntpath.expandvars("%foo%%bar")', "bar%bar") tester('ntpath.expandvars("\'%foo%\'%bar")', "\'%foo%\'%bar") + @unittest.skipUnless(support.FS_NONASCII, 'need support.FS_NONASCII') + def test_expandvars_nonascii(self): + def check(value, expected): + tester('ntpath.expandvars(%r)' % value, expected) + with support.EnvironmentVarGuard() as env: + env.clear() + nonascii = support.FS_NONASCII + env['spam'] = nonascii + env[nonascii] = 'ham' + nonascii + check('$spam bar', '%s bar' % nonascii) + check('$%s bar' % nonascii, '$%s bar' % nonascii) + check('${spam}bar', '%sbar' % nonascii) + check('${%s}bar' % nonascii, 'ham%sbar' % nonascii) + check('$spam}bar', '%s}bar' % nonascii) + check('$%s}bar' % nonascii, '$%s}bar' % nonascii) + check('%spam% bar', '%s bar' % nonascii) + check('%{}% bar'.format(nonascii), 'ham%s bar' % nonascii) + check('%spam%bar', '%sbar' % nonascii) + check('%{}%bar'.format(nonascii), 'ham%sbar' % nonascii) + + def test_expanduser(self): + tester('ntpath.expanduser("test")', 'test') + + with support.EnvironmentVarGuard() as env: + env.clear() + tester('ntpath.expanduser("~test")', '~test') + + env['HOMEPATH'] = 'eric\\idle' + env['HOMEDRIVE'] = 'C:\\' + tester('ntpath.expanduser("~test")', 'C:\\eric\\test') + tester('ntpath.expanduser("~")', 'C:\\eric\\idle') + + del env['HOMEDRIVE'] + tester('ntpath.expanduser("~test")', 'eric\\test') + tester('ntpath.expanduser("~")', 'eric\\idle') + + env.clear() + env['USERPROFILE'] = 'C:\\eric\\idle' + tester('ntpath.expanduser("~test")', 'C:\\eric\\test') + tester('ntpath.expanduser("~")', 'C:\\eric\\idle') + + env.clear() + env['HOME'] = 'C:\\idle\\eric' + tester('ntpath.expanduser("~test")', 'C:\\idle\\test') + tester('ntpath.expanduser("~")', 'C:\\idle\\eric') + + tester('ntpath.expanduser("~test\\foo\\bar")', + 'C:\\idle\\test\\foo\\bar') + tester('ntpath.expanduser("~test/foo/bar")', + 'C:\\idle\\test/foo/bar') + tester('ntpath.expanduser("~\\foo\\bar")', + 'C:\\idle\\eric\\foo\\bar') + tester('ntpath.expanduser("~/foo/bar")', + 'C:\\idle\\eric/foo/bar') + def test_abspath(self): # ntpath.abspath() can only be used on a system with the "nt" module # (reasonably), so we protect this test with "import nt". This allows @@ -218,16 +303,17 @@ def test_abspath(self): import nt tester('ntpath.abspath("C:\\")', "C:\\") except ImportError: - pass + self.skipTest('nt module not available') def test_relpath(self): - currentdir = os.path.split(os.getcwd())[-1] tester('ntpath.relpath("a")', 'a') tester('ntpath.relpath(os.path.abspath("a"))', 'a') tester('ntpath.relpath("a/b")', 'a\\b') tester('ntpath.relpath("../a/b")', '..\\a\\b') - tester('ntpath.relpath("a", "../b")', '..\\'+currentdir+'\\a') - tester('ntpath.relpath("a/b", "../c")', '..\\'+currentdir+'\\a\\b') + with support.temp_cwd(support.TESTFN) as cwd_dir: + currentdir = os.path.basename(cwd_dir) + tester('ntpath.relpath("a", "../b")', '..\\'+currentdir+'\\a') + tester('ntpath.relpath("a/b", "../c")', '..\\'+currentdir+'\\a\\b') tester('ntpath.relpath("a", "b/c")', '..\\..\\a') tester('ntpath.relpath("c:/foo/bar/bat", "c:/x/y")', '..\\..\\foo\\bar\\bat') tester('ntpath.relpath("//conky/mountpoint/a", "//conky/mountpoint/b/c")', '..\\..\\a') diff --git a/Lib/test/test_operator.py b/Lib/test/test_operator.py index ab58a98365ce..1bd0391ee297 100644 --- a/Lib/test/test_operator.py +++ b/Lib/test/test_operator.py @@ -203,6 +203,15 @@ def test_mul(self): self.assertRaises(TypeError, operator.mul, None, None) self.assertTrue(operator.mul(5, 2) == 10) + def test_matmul(self): + operator = self.module + self.assertRaises(TypeError, operator.matmul) + self.assertRaises(TypeError, operator.matmul, 42, 42) + class M: + def __matmul__(self, other): + return other - 1 + self.assertEqual(M() @ 42, 41) + def test_neg(self): operator = self.module self.assertRaises(TypeError, operator.neg) @@ -416,6 +425,7 @@ def __ifloordiv__(self, other): return "ifloordiv" def __ilshift__ (self, other): return "ilshift" def __imod__ (self, other): return "imod" def __imul__ (self, other): return "imul" + def __imatmul__ (self, other): return "imatmul" def __ior__ (self, other): return "ior" def __ipow__ (self, other): return "ipow" def __irshift__ (self, other): return "irshift" @@ -430,6 +440,7 @@ def __getitem__(self, other): return 5 # so that C is a sequence self.assertEqual(operator.ilshift (c, 5), "ilshift") self.assertEqual(operator.imod (c, 5), "imod") self.assertEqual(operator.imul (c, 5), "imul") + self.assertEqual(operator.imatmul (c, 5), "imatmul") self.assertEqual(operator.ior (c, 5), "ior") self.assertEqual(operator.ipow (c, 5), "ipow") self.assertEqual(operator.irshift (c, 5), "irshift") diff --git a/Lib/test/test_optparse.py b/Lib/test/test_optparse.py index 94730119e907..7621c2430554 100644 --- a/Lib/test/test_optparse.py +++ b/Lib/test/test_optparse.py @@ -395,6 +395,7 @@ def test_remove_nonexistent(self): self.assertRaises(self.parser.remove_option, ('foo',), None, ValueError, "no such option 'foo'") + @support.impl_detail('Relies on sys.getrefcount', cpython=True) def test_refleak(self): # If an OptionParser is carrying around a reference to a large # object, various cycles can prevent it from being GC'd in @@ -1443,6 +1444,39 @@ def test_conflict_override_args(self): -h, --help show this help message and exit """ +_expected_very_help_short_lines = """\ +Usage: bar.py [options] + +Options: + -a APPLE + throw + APPLEs at + basket + -b NUM, --boo=NUM + shout + "boo!" NUM + times (in + order to + frighten + away all + the evil + spirits + that cause + trouble and + mayhem) + --foo=FOO + store FOO + in the foo + list for + later + fooing + -h, --help + show this + help + message and + exit +""" + class TestHelp(BaseTest): def setUp(self): self.parser = self.make_parser(80) @@ -1500,6 +1534,8 @@ def test_wrap_columns(self): # we look at $COLUMNS. self.parser = self.make_parser(60) self.assertHelpEquals(_expected_help_short_lines) + self.parser = self.make_parser(0) + self.assertHelpEquals(_expected_very_help_short_lines) def test_help_unicode(self): self.parser = InterceptingOptionParser(usage=SUPPRESS_USAGE) diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 1ffa7dafeb65..afa7a4a1d1c0 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -4,6 +4,7 @@ import os import errno +import getpass import unittest import warnings import sys @@ -27,6 +28,7 @@ import decimal import fractions import pickle +import sysconfig try: import threading except ImportError: @@ -39,9 +41,35 @@ import fcntl except ImportError: fcntl = None +try: + import _winapi +except ImportError: + _winapi = None +try: + import grp + groups = [g.gr_gid for g in grp.getgrall() if getpass.getuser() in g.gr_mem] + if hasattr(os, 'getgid'): + process_gid = os.getgid() + if process_gid not in groups: + groups.append(process_gid) +except ImportError: + groups = [] +try: + import pwd + all_users = [u.pw_uid for u in pwd.getpwall()] +except ImportError: + all_users = [] +try: + from _testcapi import INT_MAX, PY_SSIZE_T_MAX +except ImportError: + INT_MAX = PY_SSIZE_T_MAX = sys.maxsize from test.script_helper import assert_python_ok +root_in_posix = False +if hasattr(os, 'geteuid'): + root_in_posix = (os.geteuid() == 0) + with warnings.catch_warnings(): warnings.simplefilter("ignore", DeprecationWarning) os.stat_float_times(True) @@ -115,6 +143,26 @@ def test_read(self): self.assertEqual(type(s), bytes) self.assertEqual(s, b"spam") + @support.cpython_only + # Skip the test on 32-bit platforms: the number of bytes must fit in a + # Py_ssize_t type + @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, + "needs INT_MAX < PY_SSIZE_T_MAX") + @support.bigmemtest(size=INT_MAX + 10, memuse=1, dry_run=False) + def test_large_read(self, size): + with open(support.TESTFN, "wb") as fp: + fp.write(b'test') + self.addCleanup(support.unlink, support.TESTFN) + + # Issue #21932: Make sure that os.read() does not raise an + # OverflowError for size larger than INT_MAX + with open(support.TESTFN, "rb") as fp: + data = os.read(fp.fileno(), size) + + # The test does not try to read more than 2 GB at once because the + # operating system is free to return less bytes than requested. + self.assertEqual(data, b'test') + def test_write(self): # os.write() accepts bytes- and buffer-like objects but not strings fd = os.open(support.TESTFN, os.O_CREAT | os.O_WRONLY) @@ -265,10 +313,13 @@ def test_stat_attributes_bytes(self): def test_stat_result_pickle(self): result = os.stat(self.fname) - p = pickle.dumps(result) - self.assertIn(b'\x03cos\nstat_result\n', p) - unpickled = pickle.loads(p) - self.assertEqual(result, unpickled) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + p = pickle.dumps(result, proto) + self.assertIn(b'stat_result', p) + if proto < 4: + self.assertIn(b'cos\nstat_result\n', p) + unpickled = pickle.loads(p) + self.assertEqual(result, unpickled) @unittest.skipUnless(hasattr(os, 'statvfs'), 'test needs os.statvfs()') def test_statvfs_attributes(self): @@ -324,10 +375,13 @@ def test_statvfs_result_pickle(self): if e.errno == errno.ENOSYS: self.skipTest('os.statvfs() failed with ENOSYS') - p = pickle.dumps(result) - self.assertIn(b'\x03cos\nstatvfs_result\n', p) - unpickled = pickle.loads(p) - self.assertEqual(result, unpickled) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + p = pickle.dumps(result, proto) + self.assertIn(b'statvfs_result', p) + if proto < 4: + self.assertIn(b'cos\nstatvfs_result\n', p) + unpickled = pickle.loads(p) + self.assertEqual(result, unpickled) def test_utime_dir(self): delta = 1000000 @@ -508,7 +562,7 @@ def test_1686475(self): try: os.stat(r"c:\pagefile.sys") except FileNotFoundError: - pass # file does not exist; cannot run test + self.skipTest(r'c:\pagefile.sys does not exist') except OSError as e: self.fail("Could not stat pagefile.sys") @@ -526,6 +580,28 @@ def test_15261(self): os.stat(r) self.assertEqual(ctx.exception.errno, errno.EBADF) + def check_file_attributes(self, result): + self.assertTrue(hasattr(result, 'st_file_attributes')) + self.assertTrue(isinstance(result.st_file_attributes, int)) + self.assertTrue(0 <= result.st_file_attributes <= 0xFFFFFFFF) + + @unittest.skipUnless(sys.platform == "win32", + "st_file_attributes is Win32 specific") + def test_file_attributes(self): + # test file st_file_attributes (FILE_ATTRIBUTE_DIRECTORY not set) + result = os.stat(self.fname) + self.check_file_attributes(result) + self.assertEqual( + result.st_file_attributes & stat.FILE_ATTRIBUTE_DIRECTORY, + 0) + + # test directory st_file_attributes (FILE_ATTRIBUTE_DIRECTORY set) + result = os.stat(support.TESTFN) + self.check_file_attributes(result) + self.assertEqual( + result.st_file_attributes & stat.FILE_ATTRIBUTE_DIRECTORY, + stat.FILE_ATTRIBUTE_DIRECTORY) + from test import mapping_tests class EnvironTests(mapping_tests.BasicTestMappingProtocol): @@ -901,21 +977,10 @@ def test_exist_ok_existing_directory(self): os.makedirs(path, mode) self.assertRaises(OSError, os.makedirs, path, mode) self.assertRaises(OSError, os.makedirs, path, mode, exist_ok=False) - self.assertRaises(OSError, os.makedirs, path, 0o776, exist_ok=True) + os.makedirs(path, 0o776, exist_ok=True) os.makedirs(path, mode=mode, exist_ok=True) os.umask(old_mask) - @unittest.skipUnless(hasattr(os, 'chown'), 'test needs os.chown') - def test_chown_uid_gid_arguments_must_be_index(self): - stat = os.stat(support.TESTFN) - uid = stat.st_uid - gid = stat.st_gid - for value in (-1.0, -1j, decimal.Decimal(-1), fractions.Fraction(-2, 2)): - self.assertRaises(TypeError, os.chown, support.TESTFN, value, gid) - self.assertRaises(TypeError, os.chown, support.TESTFN, uid, value) - self.assertIsNone(os.chown(support.TESTFN, uid, gid)) - self.assertIsNone(os.chown(support.TESTFN, -1, -1)) - def test_exist_ok_s_isgid_directory(self): path = os.path.join(support.TESTFN, 'dir1') S_ISGID = stat.S_ISGID @@ -938,9 +1003,8 @@ def test_exist_ok_s_isgid_directory(self): os.makedirs(path, mode, exist_ok=True) # remove the bit. os.chmod(path, stat.S_IMODE(os.lstat(path).st_mode) & ~S_ISGID) - with self.assertRaises(OSError): - # Should fail when the bit is not already set when demanded. - os.makedirs(path, mode | S_ISGID, exist_ok=True) + # May work even when the bit is not already set when demanded. + os.makedirs(path, mode | S_ISGID, exist_ok=True) finally: os.umask(old_mask) @@ -967,6 +1031,58 @@ def tearDown(self): os.removedirs(path) +@unittest.skipUnless(hasattr(os, 'chown'), "Test needs chown") +class ChownFileTests(unittest.TestCase): + + def setUpClass(): + os.mkdir(support.TESTFN) + + def test_chown_uid_gid_arguments_must_be_index(self): + stat = os.stat(support.TESTFN) + uid = stat.st_uid + gid = stat.st_gid + for value in (-1.0, -1j, decimal.Decimal(-1), fractions.Fraction(-2, 2)): + self.assertRaises(TypeError, os.chown, support.TESTFN, value, gid) + self.assertRaises(TypeError, os.chown, support.TESTFN, uid, value) + self.assertIsNone(os.chown(support.TESTFN, uid, gid)) + self.assertIsNone(os.chown(support.TESTFN, -1, -1)) + + @unittest.skipUnless(len(groups) > 1, "test needs more than one group") + def test_chown(self): + gid_1, gid_2 = groups[:2] + uid = os.stat(support.TESTFN).st_uid + os.chown(support.TESTFN, uid, gid_1) + gid = os.stat(support.TESTFN).st_gid + self.assertEqual(gid, gid_1) + os.chown(support.TESTFN, uid, gid_2) + gid = os.stat(support.TESTFN).st_gid + self.assertEqual(gid, gid_2) + + @unittest.skipUnless(root_in_posix and len(all_users) > 1, + "test needs root privilege and more than one user") + def test_chown_with_root(self): + uid_1, uid_2 = all_users[:2] + gid = os.stat(support.TESTFN).st_gid + os.chown(support.TESTFN, uid_1, gid) + uid = os.stat(support.TESTFN).st_uid + self.assertEqual(uid, uid_1) + os.chown(support.TESTFN, uid_2, gid) + uid = os.stat(support.TESTFN).st_uid + self.assertEqual(uid, uid_2) + + @unittest.skipUnless(not root_in_posix and len(all_users) > 1, + "test needs non-root account and more than one user") + def test_chown_without_permission(self): + uid_1, uid_2 = all_users[:2] + gid = os.stat(support.TESTFN).st_gid + with self.assertRaises(PermissionError): + os.chown(support.TESTFN, uid_1, gid) + os.chown(support.TESTFN, uid_2, gid) + + def tearDownClass(): + os.rmdir(support.TESTFN) + + class RemoveDirsTests(unittest.TestCase): def setUp(self): os.makedirs(support.TESTFN) @@ -1048,6 +1164,12 @@ def test_urandom_subprocess(self): data2 = self.get_urandom_subprocess(16) self.assertNotEqual(data1, data2) + +HAVE_GETENTROPY = (sysconfig.get_config_var('HAVE_GETENTROPY') == 1) + +@unittest.skipIf(HAVE_GETENTROPY, + "getentropy() does not use a file descriptor") +class URandomFDTests(unittest.TestCase): @unittest.skipUnless(resource, "test requires the resource module") def test_urandom_failure(self): # Check urandom() failing when it is not able to open /dev/random. @@ -1071,6 +1193,49 @@ def test_urandom_failure(self): """ assert_python_ok('-c', code) + def test_urandom_fd_closed(self): + # Issue #21207: urandom() should reopen its fd to /dev/urandom if + # closed. + code = """if 1: + import os + import sys + os.urandom(4) + os.closerange(3, 256) + sys.stdout.buffer.write(os.urandom(4)) + """ + rc, out, err = assert_python_ok('-Sc', code) + + def test_urandom_fd_reopened(self): + # Issue #21207: urandom() should detect its fd to /dev/urandom + # changed to something else, and reopen it. + with open(support.TESTFN, 'wb') as f: + f.write(b"x" * 256) + self.addCleanup(os.unlink, support.TESTFN) + code = """if 1: + import os + import sys + os.urandom(4) + for fd in range(3, 256): + try: + os.close(fd) + except OSError: + pass + else: + # Found the urandom fd (XXX hopefully) + break + os.closerange(3, 256) + with open({TESTFN!r}, 'rb') as f: + os.dup2(f.fileno(), fd) + sys.stdout.buffer.write(os.urandom(4)) + sys.stdout.buffer.write(os.urandom(4)) + """.format(TESTFN=support.TESTFN) + rc, out, err = assert_python_ok('-Sc', code) + self.assertEqual(len(out), 8) + self.assertNotEqual(out[0:4], out[4:8]) + rc, out2, err2 = assert_python_ok('-Sc', code) + self.assertEqual(len(out2), 8) + self.assertNotEqual(out2, out) + @contextlib.contextmanager def _execvpe_mockup(defpath=None): @@ -1267,6 +1432,11 @@ def test_lseek(self): def test_read(self): self.check(os.read, 1) + @unittest.skipUnless(hasattr(os, 'readv'), 'test needs os.readv()') + def test_readv(self): + buf = bytearray(10) + self.check(os.readv, [buf]) + @unittest.skipUnless(hasattr(os, 'tcsetpgrp'), 'test needs os.tcsetpgrp()') def test_tcsetpgrpt(self): self.check(os.tcsetpgrp, 0) @@ -1275,6 +1445,20 @@ def test_tcsetpgrpt(self): def test_write(self): self.check(os.write, b" ") + @unittest.skipUnless(hasattr(os, 'writev'), 'test needs os.writev()') + def test_writev(self): + self.check(os.writev, [b'abc']) + + def test_inheritable(self): + self.check(os.get_inheritable) + self.check(os.set_inheritable, True) + + @unittest.skipUnless(hasattr(os, 'get_blocking'), + 'needs os.get_blocking() and os.set_blocking()') + def test_blocking(self): + self.check(os.get_blocking) + self.check(os.set_blocking, True) + class LinkTests(unittest.TestCase): def setUp(self): @@ -1722,6 +1906,37 @@ def test_12084(self): shutil.rmtree(level1) +@unittest.skipUnless(sys.platform == "win32", "Win32 specific tests") +class Win32JunctionTests(unittest.TestCase): + junction = 'junctiontest' + junction_target = os.path.dirname(os.path.abspath(__file__)) + + def setUp(self): + assert os.path.exists(self.junction_target) + assert not os.path.exists(self.junction) + + def tearDown(self): + if os.path.exists(self.junction): + # os.rmdir delegates to Windows' RemoveDirectoryW, + # which removes junction points safely. + os.rmdir(self.junction) + + def test_create_junction(self): + _winapi.CreateJunction(self.junction_target, self.junction) + self.assertTrue(os.path.exists(self.junction)) + self.assertTrue(os.path.isdir(self.junction)) + + # Junctions are not recognized as links. + self.assertFalse(os.path.islink(self.junction)) + + def test_unlink_removes_junction(self): + _winapi.CreateJunction(self.junction_target, self.junction) + self.assertTrue(os.path.exists(self.junction)) + + os.unlink(self.junction) + self.assertFalse(os.path.exists(self.junction)) + + @support.skip_unless_symlink class NonLocalSymlinkTests(unittest.TestCase): @@ -1928,11 +2143,13 @@ class TestSendfile(unittest.TestCase): @classmethod def setUpClass(cls): + cls.key = support.threading_setup() with open(support.TESTFN, "wb") as f: f.write(cls.DATA) @classmethod def tearDownClass(cls): + support.threading_cleanup(*cls.key) support.unlink(support.TESTFN) def setUp(self): @@ -2459,41 +2676,27 @@ def test_openpty(self): self.assertEqual(os.get_inheritable(slave_fd), False) -@support.reap_threads -def test_main(): - support.run_unittest( - FileTests, - StatAttributeTests, - EnvironTests, - WalkTests, - FwalkTests, - MakedirTests, - DevNullTests, - URandomTests, - ExecTests, - Win32ErrorTests, - TestInvalidFD, - PosixUidGidTests, - Pep383Tests, - Win32KillTests, - Win32ListdirTests, - Win32SymlinkTests, - NonLocalSymlinkTests, - FSEncodingTests, - DeviceEncodingTests, - PidTests, - LoginTests, - LinkTests, - TestSendfile, - ProgramPriorityTests, - ExtendedAttributeTests, - Win32DeprecatedBytesAPI, - TermsizeTests, - OSErrorTests, - RemoveDirsTests, - CPUCountTests, - FDInheritanceTests, - ) +@unittest.skipUnless(hasattr(os, 'get_blocking'), + 'needs os.get_blocking() and os.set_blocking()') +class BlockingTests(unittest.TestCase): + def test_blocking(self): + fd = os.open(__file__, os.O_RDONLY) + self.addCleanup(os.close, fd) + self.assertEqual(os.get_blocking(fd), True) + + os.set_blocking(fd, False) + self.assertEqual(os.get_blocking(fd), False) + + os.set_blocking(fd, True) + self.assertEqual(os.get_blocking(fd), True) + + + +class ExportsTests(unittest.TestCase): + def test_os_all(self): + self.assertIn('open', os.__all__) + self.assertIn('walk', os.__all__) + if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py old mode 100755 new mode 100644 index 8f0855e61873..1c53ab78ea4e --- a/Lib/test/test_pathlib.py +++ b/Lib/test/test_pathlib.py @@ -4,13 +4,10 @@ import errno import pathlib import pickle -import shutil import socket import stat -import sys import tempfile import unittest -from contextlib import contextmanager from test import support TESTFN = support.TESTFN @@ -105,31 +102,35 @@ def test_parse_parts(self): check = self._check_parse_parts # First part is anchored check(['c:'], ('c:', '', ['c:'])) - check(['c:\\'], ('c:', '\\', ['c:\\'])) - check(['\\'], ('', '\\', ['\\'])) + check(['c:/'], ('c:', '\\', ['c:\\'])) + check(['/'], ('', '\\', ['\\'])) check(['c:a'], ('c:', '', ['c:', 'a'])) - check(['c:\\a'], ('c:', '\\', ['c:\\', 'a'])) - check(['\\a'], ('', '\\', ['\\', 'a'])) + check(['c:/a'], ('c:', '\\', ['c:\\', 'a'])) + check(['/a'], ('', '\\', ['\\', 'a'])) # UNC paths - check(['\\\\a\\b'], ('\\\\a\\b', '\\', ['\\\\a\\b\\'])) - check(['\\\\a\\b\\'], ('\\\\a\\b', '\\', ['\\\\a\\b\\'])) - check(['\\\\a\\b\\c'], ('\\\\a\\b', '\\', ['\\\\a\\b\\', 'c'])) + check(['//a/b'], ('\\\\a\\b', '\\', ['\\\\a\\b\\'])) + check(['//a/b/'], ('\\\\a\\b', '\\', ['\\\\a\\b\\'])) + check(['//a/b/c'], ('\\\\a\\b', '\\', ['\\\\a\\b\\', 'c'])) # Second part is anchored, so that the first part is ignored check(['a', 'Z:b', 'c'], ('Z:', '', ['Z:', 'b', 'c'])) - check(['a', 'Z:\\b', 'c'], ('Z:', '\\', ['Z:\\', 'b', 'c'])) - check(['a', '\\b', 'c'], ('', '\\', ['\\', 'b', 'c'])) + check(['a', 'Z:/b', 'c'], ('Z:', '\\', ['Z:\\', 'b', 'c'])) # UNC paths - check(['a', '\\\\b\\c', 'd'], ('\\\\b\\c', '\\', ['\\\\b\\c\\', 'd'])) + check(['a', '//b/c', 'd'], ('\\\\b\\c', '\\', ['\\\\b\\c\\', 'd'])) # Collapsing and stripping excess slashes - check(['a', 'Z:\\\\b\\\\c\\', 'd\\'], ('Z:', '\\', ['Z:\\', 'b', 'c', 'd'])) + check(['a', 'Z://b//c/', 'd/'], ('Z:', '\\', ['Z:\\', 'b', 'c', 'd'])) # UNC paths - check(['a', '\\\\b\\c\\\\', 'd'], ('\\\\b\\c', '\\', ['\\\\b\\c\\', 'd'])) + check(['a', '//b/c//', 'd'], ('\\\\b\\c', '\\', ['\\\\b\\c\\', 'd'])) # Extended paths - check(['\\\\?\\c:\\'], ('\\\\?\\c:', '\\', ['\\\\?\\c:\\'])) - check(['\\\\?\\c:\\a'], ('\\\\?\\c:', '\\', ['\\\\?\\c:\\', 'a'])) + check(['//?/c:/'], ('\\\\?\\c:', '\\', ['\\\\?\\c:\\'])) + check(['//?/c:/a'], ('\\\\?\\c:', '\\', ['\\\\?\\c:\\', 'a'])) + check(['//?/c:/a', '/b'], ('\\\\?\\c:', '\\', ['\\\\?\\c:\\', 'b'])) # Extended UNC paths (format is "\\?\UNC\server\share") - check(['\\\\?\\UNC\\b\\c'], ('\\\\?\\UNC\\b\\c', '\\', ['\\\\?\\UNC\\b\\c\\'])) - check(['\\\\?\\UNC\\b\\c\\d'], ('\\\\?\\UNC\\b\\c', '\\', ['\\\\?\\UNC\\b\\c\\', 'd'])) + check(['//?/UNC/b/c'], ('\\\\?\\UNC\\b\\c', '\\', ['\\\\?\\UNC\\b\\c\\'])) + check(['//?/UNC/b/c/d'], ('\\\\?\\UNC\\b\\c', '\\', ['\\\\?\\UNC\\b\\c\\', 'd'])) + # Second part has a root but not drive + check(['a', '/b', 'c'], ('', '\\', ['\\', 'b', 'c'])) + check(['Z:/a', '/b', 'c'], ('Z:', '\\', ['Z:\\', 'b', 'c'])) + check(['//?/Z:/a', '/b', 'c'], ('\\\\?\\Z:', '\\', ['\\\\?\\Z:\\', 'b', 'c'])) def test_splitroot(self): f = self.flavour.splitroot @@ -197,6 +198,25 @@ def test_constructor_common(self): self.assertEqual(P(P('a'), 'b'), P('a/b')) self.assertEqual(P(P('a'), P('b')), P('a/b')) + def _check_str_subclass(self, *args): + # Issue #21127: it should be possible to construct a PurePath object + # from an str subclass instance, and it then gets converted to + # a pure str object. + class StrSubclass(str): + pass + P = self.cls + p = P(*(StrSubclass(x) for x in args)) + self.assertEqual(p, P(*args)) + for part in p.parts: + self.assertIs(type(part), str) + + def test_str_subclass_common(self): + self._check_str_subclass('') + self._check_str_subclass('.') + self._check_str_subclass('a') + self._check_str_subclass('a/b.txt') + self._check_str_subclass('/a/b.txt') + def test_join_common(self): P = self.cls p = P('a/b') @@ -521,6 +541,10 @@ def test_with_name_common(self): self.assertRaises(ValueError, P('').with_name, 'd.xml') self.assertRaises(ValueError, P('.').with_name, 'd.xml') self.assertRaises(ValueError, P('/').with_name, 'd.xml') + self.assertRaises(ValueError, P('a/b').with_name, '') + self.assertRaises(ValueError, P('a/b').with_name, '/c') + self.assertRaises(ValueError, P('a/b').with_name, 'c/') + self.assertRaises(ValueError, P('a/b').with_name, 'c/d') def test_with_suffix_common(self): P = self.cls @@ -528,17 +552,35 @@ def test_with_suffix_common(self): self.assertEqual(P('/a/b').with_suffix('.gz'), P('/a/b.gz')) self.assertEqual(P('a/b.py').with_suffix('.gz'), P('a/b.gz')) self.assertEqual(P('/a/b.py').with_suffix('.gz'), P('/a/b.gz')) + # Stripping suffix + self.assertEqual(P('a/b.py').with_suffix(''), P('a/b')) + self.assertEqual(P('/a/b').with_suffix(''), P('/a/b')) + # Path doesn't have a "filename" component self.assertRaises(ValueError, P('').with_suffix, '.gz') self.assertRaises(ValueError, P('.').with_suffix, '.gz') self.assertRaises(ValueError, P('/').with_suffix, '.gz') + # Invalid suffix + self.assertRaises(ValueError, P('a/b').with_suffix, 'gz') + self.assertRaises(ValueError, P('a/b').with_suffix, '/') + self.assertRaises(ValueError, P('a/b').with_suffix, '.') + self.assertRaises(ValueError, P('a/b').with_suffix, '/.gz') + self.assertRaises(ValueError, P('a/b').with_suffix, 'c/d') + self.assertRaises(ValueError, P('a/b').with_suffix, '.c/.d') + self.assertRaises(ValueError, P('a/b').with_suffix, './.d') + self.assertRaises(ValueError, P('a/b').with_suffix, '.d/.') def test_relative_to_common(self): P = self.cls p = P('a/b') self.assertRaises(TypeError, p.relative_to) + self.assertRaises(TypeError, p.relative_to, b'a') self.assertEqual(p.relative_to(P()), P('a/b')) + self.assertEqual(p.relative_to(''), P('a/b')) self.assertEqual(p.relative_to(P('a')), P('b')) + self.assertEqual(p.relative_to('a'), P('b')) + self.assertEqual(p.relative_to('a/'), P('b')) self.assertEqual(p.relative_to(P('a/b')), P()) + self.assertEqual(p.relative_to('a/b'), P()) # With several args self.assertEqual(p.relative_to('a', 'b'), P()) # Unrelated paths @@ -548,13 +590,18 @@ def test_relative_to_common(self): self.assertRaises(ValueError, p.relative_to, P('/a')) p = P('/a/b') self.assertEqual(p.relative_to(P('/')), P('a/b')) + self.assertEqual(p.relative_to('/'), P('a/b')) self.assertEqual(p.relative_to(P('/a')), P('b')) + self.assertEqual(p.relative_to('/a'), P('b')) + self.assertEqual(p.relative_to('/a/'), P('b')) self.assertEqual(p.relative_to(P('/a/b')), P()) + self.assertEqual(p.relative_to('/a/b'), P()) # Unrelated paths self.assertRaises(ValueError, p.relative_to, P('/c')) self.assertRaises(ValueError, p.relative_to, P('/a/b/c')) self.assertRaises(ValueError, p.relative_to, P('/a/c')) self.assertRaises(ValueError, p.relative_to, P()) + self.assertRaises(ValueError, p.relative_to, '') self.assertRaises(ValueError, p.relative_to, P('a')) def test_pickling_common(self): @@ -673,6 +720,17 @@ def test_str(self): p = self.cls('//a/b/c/d') self.assertEqual(str(p), '\\\\a\\b\\c\\d') + def test_str_subclass(self): + self._check_str_subclass('c:') + self._check_str_subclass('c:a') + self._check_str_subclass('c:a\\b.txt') + self._check_str_subclass('c:\\') + self._check_str_subclass('c:\\a') + self._check_str_subclass('c:\\a\\b.txt') + self._check_str_subclass('\\\\some\\share') + self._check_str_subclass('\\\\some\\share\\a') + self._check_str_subclass('\\\\some\\share\\a\\b.txt') + def test_eq(self): P = self.cls self.assertEqual(P('c:a/b'), P('c:a/b')) @@ -686,7 +744,6 @@ def test_eq(self): self.assertEqual(P('//Some/SHARE/a/B'), P('//somE/share/A/b')) def test_as_uri(self): - from urllib.parse import quote_from_bytes P = self.cls with self.assertRaises(ValueError): P('/a/b').as_uri() @@ -903,6 +960,10 @@ def test_with_name(self): self.assertRaises(ValueError, P('c:').with_name, 'd.xml') self.assertRaises(ValueError, P('c:/').with_name, 'd.xml') self.assertRaises(ValueError, P('//My/Share').with_name, 'd.xml') + self.assertRaises(ValueError, P('c:a/b').with_name, 'd:') + self.assertRaises(ValueError, P('c:a/b').with_name, 'd:e') + self.assertRaises(ValueError, P('c:a/b').with_name, 'd:/e') + self.assertRaises(ValueError, P('c:a/b').with_name, '//My/Share') def test_with_suffix(self): P = self.cls @@ -910,49 +971,81 @@ def test_with_suffix(self): self.assertEqual(P('c:/a/b').with_suffix('.gz'), P('c:/a/b.gz')) self.assertEqual(P('c:a/b.py').with_suffix('.gz'), P('c:a/b.gz')) self.assertEqual(P('c:/a/b.py').with_suffix('.gz'), P('c:/a/b.gz')) + # Path doesn't have a "filename" component self.assertRaises(ValueError, P('').with_suffix, '.gz') self.assertRaises(ValueError, P('.').with_suffix, '.gz') self.assertRaises(ValueError, P('/').with_suffix, '.gz') self.assertRaises(ValueError, P('//My/Share').with_suffix, '.gz') + # Invalid suffix + self.assertRaises(ValueError, P('c:a/b').with_suffix, 'gz') + self.assertRaises(ValueError, P('c:a/b').with_suffix, '/') + self.assertRaises(ValueError, P('c:a/b').with_suffix, '\\') + self.assertRaises(ValueError, P('c:a/b').with_suffix, 'c:') + self.assertRaises(ValueError, P('c:a/b').with_suffix, '/.gz') + self.assertRaises(ValueError, P('c:a/b').with_suffix, '\\.gz') + self.assertRaises(ValueError, P('c:a/b').with_suffix, 'c:.gz') + self.assertRaises(ValueError, P('c:a/b').with_suffix, 'c/d') + self.assertRaises(ValueError, P('c:a/b').with_suffix, 'c\\d') + self.assertRaises(ValueError, P('c:a/b').with_suffix, '.c/d') + self.assertRaises(ValueError, P('c:a/b').with_suffix, '.c\\d') def test_relative_to(self): P = self.cls - p = P('c:a/b') - self.assertEqual(p.relative_to(P('c:')), P('a/b')) - self.assertEqual(p.relative_to(P('c:a')), P('b')) - self.assertEqual(p.relative_to(P('c:a/b')), P()) + p = P('C:Foo/Bar') + self.assertEqual(p.relative_to(P('c:')), P('Foo/Bar')) + self.assertEqual(p.relative_to('c:'), P('Foo/Bar')) + self.assertEqual(p.relative_to(P('c:foO')), P('Bar')) + self.assertEqual(p.relative_to('c:foO'), P('Bar')) + self.assertEqual(p.relative_to('c:foO/'), P('Bar')) + self.assertEqual(p.relative_to(P('c:foO/baR')), P()) + self.assertEqual(p.relative_to('c:foO/baR'), P()) # Unrelated paths self.assertRaises(ValueError, p.relative_to, P()) + self.assertRaises(ValueError, p.relative_to, '') self.assertRaises(ValueError, p.relative_to, P('d:')) - self.assertRaises(ValueError, p.relative_to, P('a')) - self.assertRaises(ValueError, p.relative_to, P('/a')) - self.assertRaises(ValueError, p.relative_to, P('c:a/b/c')) - self.assertRaises(ValueError, p.relative_to, P('c:a/c')) - self.assertRaises(ValueError, p.relative_to, P('c:/a')) - p = P('c:/a/b') - self.assertEqual(p.relative_to(P('c:')), P('/a/b')) - self.assertEqual(p.relative_to(P('c:/')), P('a/b')) - self.assertEqual(p.relative_to(P('c:/a')), P('b')) - self.assertEqual(p.relative_to(P('c:/a/b')), P()) + self.assertRaises(ValueError, p.relative_to, P('/')) + self.assertRaises(ValueError, p.relative_to, P('Foo')) + self.assertRaises(ValueError, p.relative_to, P('/Foo')) + self.assertRaises(ValueError, p.relative_to, P('C:/Foo')) + self.assertRaises(ValueError, p.relative_to, P('C:Foo/Bar/Baz')) + self.assertRaises(ValueError, p.relative_to, P('C:Foo/Baz')) + p = P('C:/Foo/Bar') + self.assertEqual(p.relative_to(P('c:')), P('/Foo/Bar')) + self.assertEqual(p.relative_to('c:'), P('/Foo/Bar')) + self.assertEqual(str(p.relative_to(P('c:'))), '\\Foo\\Bar') + self.assertEqual(str(p.relative_to('c:')), '\\Foo\\Bar') + self.assertEqual(p.relative_to(P('c:/')), P('Foo/Bar')) + self.assertEqual(p.relative_to('c:/'), P('Foo/Bar')) + self.assertEqual(p.relative_to(P('c:/foO')), P('Bar')) + self.assertEqual(p.relative_to('c:/foO'), P('Bar')) + self.assertEqual(p.relative_to('c:/foO/'), P('Bar')) + self.assertEqual(p.relative_to(P('c:/foO/baR')), P()) + self.assertEqual(p.relative_to('c:/foO/baR'), P()) # Unrelated paths - self.assertRaises(ValueError, p.relative_to, P('c:/c')) - self.assertRaises(ValueError, p.relative_to, P('c:/a/b/c')) - self.assertRaises(ValueError, p.relative_to, P('c:/a/c')) - self.assertRaises(ValueError, p.relative_to, P('c:a')) + self.assertRaises(ValueError, p.relative_to, P('C:/Baz')) + self.assertRaises(ValueError, p.relative_to, P('C:/Foo/Bar/Baz')) + self.assertRaises(ValueError, p.relative_to, P('C:/Foo/Baz')) + self.assertRaises(ValueError, p.relative_to, P('C:Foo')) self.assertRaises(ValueError, p.relative_to, P('d:')) self.assertRaises(ValueError, p.relative_to, P('d:/')) - self.assertRaises(ValueError, p.relative_to, P('/a')) - self.assertRaises(ValueError, p.relative_to, P('//c/a')) + self.assertRaises(ValueError, p.relative_to, P('/')) + self.assertRaises(ValueError, p.relative_to, P('/Foo')) + self.assertRaises(ValueError, p.relative_to, P('//C/Foo')) # UNC paths - p = P('//a/b/c/d') - self.assertEqual(p.relative_to(P('//a/b')), P('c/d')) - self.assertEqual(p.relative_to(P('//a/b/c')), P('d')) - self.assertEqual(p.relative_to(P('//a/b/c/d')), P()) + p = P('//Server/Share/Foo/Bar') + self.assertEqual(p.relative_to(P('//sErver/sHare')), P('Foo/Bar')) + self.assertEqual(p.relative_to('//sErver/sHare'), P('Foo/Bar')) + self.assertEqual(p.relative_to('//sErver/sHare/'), P('Foo/Bar')) + self.assertEqual(p.relative_to(P('//sErver/sHare/Foo')), P('Bar')) + self.assertEqual(p.relative_to('//sErver/sHare/Foo'), P('Bar')) + self.assertEqual(p.relative_to('//sErver/sHare/Foo/'), P('Bar')) + self.assertEqual(p.relative_to(P('//sErver/sHare/Foo/Bar')), P()) + self.assertEqual(p.relative_to('//sErver/sHare/Foo/Bar'), P()) # Unrelated paths - self.assertRaises(ValueError, p.relative_to, P('/a/b/c')) - self.assertRaises(ValueError, p.relative_to, P('c:/a/b/c')) - self.assertRaises(ValueError, p.relative_to, P('//z/b/c')) - self.assertRaises(ValueError, p.relative_to, P('//a/z/c')) + self.assertRaises(ValueError, p.relative_to, P('/Server/Share/Foo')) + self.assertRaises(ValueError, p.relative_to, P('c:/Server/Share/Foo')) + self.assertRaises(ValueError, p.relative_to, P('//z/Share/Foo')) + self.assertRaises(ValueError, p.relative_to, P('//Server/z/Foo')) def test_is_absolute(self): P = self.cls @@ -975,6 +1068,48 @@ def test_is_absolute(self): self.assertTrue(P('//a/b/c').is_absolute()) self.assertTrue(P('//a/b/c/d').is_absolute()) + def test_join(self): + P = self.cls + p = P('C:/a/b') + pp = p.joinpath('x/y') + self.assertEqual(pp, P('C:/a/b/x/y')) + pp = p.joinpath('/x/y') + self.assertEqual(pp, P('C:/x/y')) + # Joining with a different drive => the first path is ignored, even + # if the second path is relative. + pp = p.joinpath('D:x/y') + self.assertEqual(pp, P('D:x/y')) + pp = p.joinpath('D:/x/y') + self.assertEqual(pp, P('D:/x/y')) + pp = p.joinpath('//host/share/x/y') + self.assertEqual(pp, P('//host/share/x/y')) + # Joining with the same drive => the first path is appended to if + # the second path is relative. + pp = p.joinpath('c:x/y') + self.assertEqual(pp, P('C:/a/b/x/y')) + pp = p.joinpath('c:/x/y') + self.assertEqual(pp, P('C:/x/y')) + + def test_div(self): + # Basically the same as joinpath() + P = self.cls + p = P('C:/a/b') + self.assertEqual(p / 'x/y', P('C:/a/b/x/y')) + self.assertEqual(p / 'x' / 'y', P('C:/a/b/x/y')) + self.assertEqual(p / '/x/y', P('C:/x/y')) + self.assertEqual(p / '/x' / 'y', P('C:/x/y')) + # Joining with a different drive => the first path is ignored, even + # if the second path is relative. + self.assertEqual(p / 'D:x/y', P('D:x/y')) + self.assertEqual(p / 'D:' / 'x/y', P('D:x/y')) + self.assertEqual(p / 'D:/x/y', P('D:/x/y')) + self.assertEqual(p / 'D:' / '/x/y', P('D:/x/y')) + self.assertEqual(p / '//host/share/x/y', P('//host/share/x/y')) + # Joining with the same drive => the first path is appended to if + # the second path is relative. + self.assertEqual(p / 'c:x/y', P('C:/a/b/x/y')) + self.assertEqual(p / 'c:/x/y', P('C:/x/y')) + def test_is_reserved(self): P = self.cls self.assertIs(False, P('').is_reserved()) @@ -1079,7 +1214,7 @@ class _BasePathTest(object): def setUp(self): os.mkdir(BASE) - self.addCleanup(shutil.rmtree, BASE) + self.addCleanup(support.rmtree, BASE) os.mkdir(join('dirA')) os.mkdir(join('dirB')) os.mkdir(join('dirC')) @@ -1093,20 +1228,21 @@ def setUp(self): with open(join('dirC', 'dirD', 'fileD'), 'wb') as f: f.write(b"this is file D\n") if not symlink_skip_reason: - if os.name == 'nt': - # Workaround for http://bugs.python.org/issue13772 - def dirlink(src, dest): - os.symlink(src, dest, target_is_directory=True) - else: - def dirlink(src, dest): - os.symlink(src, dest) # Relative symlinks os.symlink('fileA', join('linkA')) os.symlink('non-existing', join('brokenLink')) - dirlink('dirB', join('linkB')) - dirlink(os.path.join('..', 'dirB'), join('dirA', 'linkC')) + self.dirlink('dirB', join('linkB')) + self.dirlink(os.path.join('..', 'dirB'), join('dirA', 'linkC')) # This one goes upwards but doesn't create a loop - dirlink(os.path.join('..', 'dirB'), join('dirB', 'linkD')) + self.dirlink(os.path.join('..', 'dirB'), join('dirB', 'linkD')) + + if os.name == 'nt': + # Workaround for http://bugs.python.org/issue13772 + def dirlink(self, src, dest): + os.symlink(src, dest, target_is_directory=True) + else: + def dirlink(self, src, dest): + os.symlink(src, dest) def assertSame(self, path_a, path_b): self.assertTrue(os.path.samefile(str(path_a), str(path_b)), @@ -1129,20 +1265,67 @@ def test_cwd(self): p = self.cls.cwd() self._test_cwd(p) + def _test_home(self, p): + q = self.cls(os.path.expanduser('~')) + self.assertEqual(p, q) + self.assertEqual(str(p), str(q)) + self.assertIs(type(p), type(q)) + self.assertTrue(p.is_absolute()) + + def test_home(self): + p = self.cls.home() + self._test_home(p) + + def test_samefile(self): + fileA_path = os.path.join(BASE, 'fileA') + fileB_path = os.path.join(BASE, 'dirB', 'fileB') + p = self.cls(fileA_path) + pp = self.cls(fileA_path) + q = self.cls(fileB_path) + self.assertTrue(p.samefile(fileA_path)) + self.assertTrue(p.samefile(pp)) + self.assertFalse(p.samefile(fileB_path)) + self.assertFalse(p.samefile(q)) + # Test the non-existent file case + non_existent = os.path.join(BASE, 'foo') + r = self.cls(non_existent) + self.assertRaises(FileNotFoundError, p.samefile, r) + self.assertRaises(FileNotFoundError, p.samefile, non_existent) + self.assertRaises(FileNotFoundError, r.samefile, p) + self.assertRaises(FileNotFoundError, r.samefile, non_existent) + self.assertRaises(FileNotFoundError, r.samefile, r) + self.assertRaises(FileNotFoundError, r.samefile, non_existent) + def test_empty_path(self): # The empty path points to '.' p = self.cls('') self.assertEqual(p.stat(), os.stat('.')) + def test_expanduser_common(self): + P = self.cls + p = P('~') + self.assertEqual(p.expanduser(), P(os.path.expanduser('~'))) + p = P('foo') + self.assertEqual(p.expanduser(), p) + p = P('/~') + self.assertEqual(p.expanduser(), p) + p = P('../~') + self.assertEqual(p.expanduser(), p) + p = P(P('').absolute().anchor) / '~' + self.assertEqual(p.expanduser(), p) + def test_exists(self): P = self.cls p = P(BASE) self.assertIs(True, p.exists()) self.assertIs(True, (p / 'dirA').exists()) self.assertIs(True, (p / 'fileA').exists()) + self.assertIs(False, (p / 'fileA' / 'bah').exists()) if not symlink_skip_reason: self.assertIs(True, (p / 'linkA').exists()) self.assertIs(True, (p / 'linkB').exists()) + self.assertIs(True, (p / 'linkB' / 'fileB').exists()) + self.assertIs(False, (p / 'linkA' / 'bah').exists()) self.assertIs(False, (p / 'foo').exists()) self.assertIs(False, P('/xyzzy').exists()) @@ -1158,6 +1341,23 @@ def test_open_common(self): self.assertIsInstance(f, io.RawIOBase) self.assertEqual(f.read().strip(), b"this is file A") + def test_read_write_bytes(self): + p = self.cls(BASE) + (p / 'fileA').write_bytes(b'abcdefg') + self.assertEqual((p / 'fileA').read_bytes(), b'abcdefg') + # check that trying to write str does not truncate the file + self.assertRaises(TypeError, (p / 'fileA').write_bytes, 'somestr') + self.assertEqual((p / 'fileA').read_bytes(), b'abcdefg') + + def test_read_write_text(self): + p = self.cls(BASE) + (p / 'fileA').write_text('äbcdefg', encoding='latin-1') + self.assertEqual((p / 'fileA').read_text( + encoding='utf-8', errors='ignore'), 'bcdefg') + # check that trying to write bytes does not truncate the file + self.assertRaises(TypeError, (p / 'fileA').write_text, b'somebytes') + self.assertEqual((p / 'fileA').read_text(encoding='latin-1'), 'äbcdefg') + def test_iterdir(self): P = self.cls p = P(BASE) @@ -1263,12 +1463,22 @@ def test_resolve_common(self): self._check_resolve_relative(p, P(BASE, 'dirB', 'fileB')) # Now create absolute symlinks d = tempfile.mkdtemp(suffix='-dirD') - self.addCleanup(shutil.rmtree, d) + self.addCleanup(support.rmtree, d) os.symlink(os.path.join(d), join('dirA', 'linkX')) os.symlink(join('dirB'), os.path.join(d, 'linkY')) p = P(BASE, 'dirA', 'linkX', 'linkY', 'fileB') self._check_resolve_absolute(p, P(BASE, 'dirB', 'fileB')) + @with_symlinks + def test_resolve_dot(self): + # See https://bitbucket.org/pitrou/pathlib/issue/9/pathresolve-fails-on-complex-symlinks + p = self.cls(BASE) + self.dirlink('.', join('0')) + self.dirlink(os.path.join('0', '0'), join('1')) + self.dirlink(os.path.join('1', '1'), join('2')) + q = p / '2' + self.assertEqual(q.resolve(), p) + def test_with(self): p = self.cls(BASE) it = p.iterdir() @@ -1425,7 +1635,6 @@ def test_mkdir(self): with self.assertRaises(OSError) as cm: p.mkdir() self.assertEqual(cm.exception.errno, errno.EEXIST) - # XXX test `mode` arg def test_mkdir_parents(self): # Creating a chain of directories @@ -1440,7 +1649,70 @@ def test_mkdir_parents(self): with self.assertRaises(OSError) as cm: p.mkdir(parents=True) self.assertEqual(cm.exception.errno, errno.EEXIST) - # XXX test `mode` arg + # test `mode` arg + mode = stat.S_IMODE(p.stat().st_mode) # default mode + p = self.cls(BASE, 'newdirD', 'newdirE') + p.mkdir(0o555, parents=True) + self.assertTrue(p.exists()) + self.assertTrue(p.is_dir()) + if os.name != 'nt': + # the directory's permissions follow the mode argument + self.assertEqual(stat.S_IMODE(p.stat().st_mode), 0o7555 & mode) + # the parent's permissions follow the default process settings + self.assertEqual(stat.S_IMODE(p.parent.stat().st_mode), mode) + + def test_mkdir_exist_ok(self): + p = self.cls(BASE, 'dirB') + st_ctime_first = p.stat().st_ctime + self.assertTrue(p.exists()) + self.assertTrue(p.is_dir()) + with self.assertRaises(FileExistsError) as cm: + p.mkdir() + self.assertEqual(cm.exception.errno, errno.EEXIST) + p.mkdir(exist_ok=True) + self.assertTrue(p.exists()) + self.assertEqual(p.stat().st_ctime, st_ctime_first) + + def test_mkdir_exist_ok_with_parent(self): + p = self.cls(BASE, 'dirC') + self.assertTrue(p.exists()) + with self.assertRaises(FileExistsError) as cm: + p.mkdir() + self.assertEqual(cm.exception.errno, errno.EEXIST) + p = p / 'newdirC' + p.mkdir(parents=True) + st_ctime_first = p.stat().st_ctime + self.assertTrue(p.exists()) + with self.assertRaises(FileExistsError) as cm: + p.mkdir(parents=True) + self.assertEqual(cm.exception.errno, errno.EEXIST) + p.mkdir(parents=True, exist_ok=True) + self.assertTrue(p.exists()) + self.assertEqual(p.stat().st_ctime, st_ctime_first) + + def test_mkdir_with_child_file(self): + p = self.cls(BASE, 'dirB', 'fileB') + self.assertTrue(p.exists()) + # An exception is raised when the last path component is an existing + # regular file, regardless of whether exist_ok is true or not. + with self.assertRaises(FileExistsError) as cm: + p.mkdir(parents=True) + self.assertEqual(cm.exception.errno, errno.EEXIST) + with self.assertRaises(FileExistsError) as cm: + p.mkdir(parents=True, exist_ok=True) + self.assertEqual(cm.exception.errno, errno.EEXIST) + + def test_mkdir_no_parents_file(self): + p = self.cls(BASE, 'fileA') + self.assertTrue(p.exists()) + # An exception is raised when the last path component is an existing + # regular file, regardless of whether exist_ok is true or not. + with self.assertRaises(FileExistsError) as cm: + p.mkdir() + self.assertEqual(cm.exception.errno, errno.EEXIST) + with self.assertRaises(FileExistsError) as cm: + p.mkdir(exist_ok=True) + self.assertEqual(cm.exception.errno, errno.EEXIST) @with_symlinks def test_symlink_to(self): @@ -1471,6 +1743,7 @@ def test_is_dir(self): self.assertTrue((P / 'dirA').is_dir()) self.assertFalse((P / 'fileA').is_dir()) self.assertFalse((P / 'non-existing').is_dir()) + self.assertFalse((P / 'fileA' / 'bah').is_dir()) if not symlink_skip_reason: self.assertFalse((P / 'linkA').is_dir()) self.assertTrue((P / 'linkB').is_dir()) @@ -1481,6 +1754,7 @@ def test_is_file(self): self.assertTrue((P / 'fileA').is_file()) self.assertFalse((P / 'dirA').is_file()) self.assertFalse((P / 'non-existing').is_file()) + self.assertFalse((P / 'fileA' / 'bah').is_file()) if not symlink_skip_reason: self.assertTrue((P / 'linkA').is_file()) self.assertFalse((P / 'linkB').is_file()) @@ -1491,6 +1765,7 @@ def test_is_symlink(self): self.assertFalse((P / 'fileA').is_symlink()) self.assertFalse((P / 'dirA').is_symlink()) self.assertFalse((P / 'non-existing').is_symlink()) + self.assertFalse((P / 'fileA' / 'bah').is_symlink()) if not symlink_skip_reason: self.assertTrue((P / 'linkA').is_symlink()) self.assertTrue((P / 'linkB').is_symlink()) @@ -1501,6 +1776,7 @@ def test_is_fifo_false(self): self.assertFalse((P / 'fileA').is_fifo()) self.assertFalse((P / 'dirA').is_fifo()) self.assertFalse((P / 'non-existing').is_fifo()) + self.assertFalse((P / 'fileA' / 'bah').is_fifo()) @unittest.skipUnless(hasattr(os, "mkfifo"), "os.mkfifo() required") def test_is_fifo_true(self): @@ -1515,6 +1791,7 @@ def test_is_socket_false(self): self.assertFalse((P / 'fileA').is_socket()) self.assertFalse((P / 'dirA').is_socket()) self.assertFalse((P / 'non-existing').is_socket()) + self.assertFalse((P / 'fileA' / 'bah').is_socket()) @unittest.skipUnless(hasattr(socket, "AF_UNIX"), "Unix sockets required") def test_is_socket_true(self): @@ -1535,12 +1812,14 @@ def test_is_block_device_false(self): self.assertFalse((P / 'fileA').is_block_device()) self.assertFalse((P / 'dirA').is_block_device()) self.assertFalse((P / 'non-existing').is_block_device()) + self.assertFalse((P / 'fileA' / 'bah').is_block_device()) def test_is_char_device_false(self): P = self.cls(BASE) self.assertFalse((P / 'fileA').is_char_device()) self.assertFalse((P / 'dirA').is_char_device()) self.assertFalse((P / 'non-existing').is_char_device()) + self.assertFalse((P / 'fileA' / 'bah').is_char_device()) def test_is_char_device_true(self): # Under Unix, /dev/null should generally be a char device @@ -1567,6 +1846,59 @@ def test_parts_interning(self): # 'bin' self.assertIs(p.parts[2], q.parts[3]) + def _check_complex_symlinks(self, link0_target): + # Test solving a non-looping chain of symlinks (issue #19887) + P = self.cls(BASE) + self.dirlink(os.path.join('link0', 'link0'), join('link1')) + self.dirlink(os.path.join('link1', 'link1'), join('link2')) + self.dirlink(os.path.join('link2', 'link2'), join('link3')) + self.dirlink(link0_target, join('link0')) + + # Resolve absolute paths + p = (P / 'link0').resolve() + self.assertEqual(p, P) + self.assertEqual(str(p), BASE) + p = (P / 'link1').resolve() + self.assertEqual(p, P) + self.assertEqual(str(p), BASE) + p = (P / 'link2').resolve() + self.assertEqual(p, P) + self.assertEqual(str(p), BASE) + p = (P / 'link3').resolve() + self.assertEqual(p, P) + self.assertEqual(str(p), BASE) + + # Resolve relative paths + old_path = os.getcwd() + os.chdir(BASE) + try: + p = self.cls('link0').resolve() + self.assertEqual(p, P) + self.assertEqual(str(p), BASE) + p = self.cls('link1').resolve() + self.assertEqual(p, P) + self.assertEqual(str(p), BASE) + p = self.cls('link2').resolve() + self.assertEqual(p, P) + self.assertEqual(str(p), BASE) + p = self.cls('link3').resolve() + self.assertEqual(p, P) + self.assertEqual(str(p), BASE) + finally: + os.chdir(old_path) + + @with_symlinks + def test_complex_symlinks_absolute(self): + self._check_complex_symlinks(BASE) + + @with_symlinks + def test_complex_symlinks_relative(self): + self._check_complex_symlinks('.') + + @with_symlinks + def test_complex_symlinks_relative_dot_dot(self): + self._check_complex_symlinks(os.path.join('dirA', '..')) + class PathTest(_BasePathTest, unittest.TestCase): cls = pathlib.Path @@ -1624,7 +1956,6 @@ def test_touch_mode(self): @with_symlinks def test_resolve_loop(self): # Loop detection for broken symlinks under POSIX - P = self.cls # Loops with relative symlinks os.symlink('linkX/inside', join('linkX')) self._check_symlink_loop(BASE, 'linkX') @@ -1656,6 +1987,48 @@ def test_rglob(self): self.assertEqual(given, expect) self.assertEqual(set(p.rglob("FILEd*")), set()) + def test_expanduser(self): + P = self.cls + support.import_module('pwd') + import pwd + pwdent = pwd.getpwuid(os.getuid()) + username = pwdent.pw_name + userhome = pwdent.pw_dir.rstrip('/') + # find arbitrary different user (if exists) + for pwdent in pwd.getpwall(): + othername = pwdent.pw_name + otherhome = pwdent.pw_dir.rstrip('/') + if othername != username and otherhome: + break + + p1 = P('~/Documents') + p2 = P('~' + username + '/Documents') + p3 = P('~' + othername + '/Documents') + p4 = P('../~' + username + '/Documents') + p5 = P('/~' + username + '/Documents') + p6 = P('') + p7 = P('~fakeuser/Documents') + + with support.EnvironmentVarGuard() as env: + env.pop('HOME', None) + + self.assertEqual(p1.expanduser(), P(userhome) / 'Documents') + self.assertEqual(p2.expanduser(), P(userhome) / 'Documents') + self.assertEqual(p3.expanduser(), P(otherhome) / 'Documents') + self.assertEqual(p4.expanduser(), p4) + self.assertEqual(p5.expanduser(), p5) + self.assertEqual(p6.expanduser(), p6) + self.assertRaises(RuntimeError, p7.expanduser) + + env['HOME'] = '/tmp' + self.assertEqual(p1.expanduser(), P('/tmp/Documents')) + self.assertEqual(p2.expanduser(), P(userhome) / 'Documents') + self.assertEqual(p3.expanduser(), P(otherhome) / 'Documents') + self.assertEqual(p4.expanduser(), p4) + self.assertEqual(p5.expanduser(), p5) + self.assertEqual(p6.expanduser(), p6) + self.assertRaises(RuntimeError, p7.expanduser) + @only_nt class WindowsPathTest(_BasePathTest, unittest.TestCase): @@ -1671,6 +2044,61 @@ def test_rglob(self): p = P(BASE, "dirC") self.assertEqual(set(p.rglob("FILEd")), { P(BASE, "dirC/dirD/fileD") }) + def test_expanduser(self): + P = self.cls + with support.EnvironmentVarGuard() as env: + env.pop('HOME', None) + env.pop('USERPROFILE', None) + env.pop('HOMEPATH', None) + env.pop('HOMEDRIVE', None) + env['USERNAME'] = 'alice' + + # test that the path returns unchanged + p1 = P('~/My Documents') + p2 = P('~alice/My Documents') + p3 = P('~bob/My Documents') + p4 = P('/~/My Documents') + p5 = P('d:~/My Documents') + p6 = P('') + self.assertRaises(RuntimeError, p1.expanduser) + self.assertRaises(RuntimeError, p2.expanduser) + self.assertRaises(RuntimeError, p3.expanduser) + self.assertEqual(p4.expanduser(), p4) + self.assertEqual(p5.expanduser(), p5) + self.assertEqual(p6.expanduser(), p6) + + def check(): + env.pop('USERNAME', None) + self.assertEqual(p1.expanduser(), + P('C:/Users/alice/My Documents')) + self.assertRaises(KeyError, p2.expanduser) + env['USERNAME'] = 'alice' + self.assertEqual(p2.expanduser(), + P('C:/Users/alice/My Documents')) + self.assertEqual(p3.expanduser(), + P('C:/Users/bob/My Documents')) + self.assertEqual(p4.expanduser(), p4) + self.assertEqual(p5.expanduser(), p5) + self.assertEqual(p6.expanduser(), p6) + + # test the first lookup key in the env vars + env['HOME'] = 'C:\\Users\\alice' + check() + + # test that HOMEPATH is available instead + env.pop('HOME', None) + env['HOMEPATH'] = 'C:\\Users\\alice' + check() + + env['HOMEDRIVE'] = 'C:\\' + env['HOMEPATH'] = 'Users\\alice' + check() + + env.pop('HOMEDRIVE', None) + env.pop('HOMEPATH', None) + env['USERPROFILE'] = 'C:\\Users\\alice' + check() + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 74253b338f66..edc9e75438c7 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -614,6 +614,8 @@ def test_next_until_return_at_return_event(): ... test_function_2() ... end = 1 + >>> from bdb import Breakpoint + >>> Breakpoint.next = 1 >>> with PdbTestInput(['break test_function_2', ... 'continue', ... 'return', @@ -914,6 +916,7 @@ def run_pdb(self, script, commands): with open(filename, 'w') as f: f.write(textwrap.dedent(script)) self.addCleanup(support.unlink, filename) + self.addCleanup(support.rmtree, '__pycache__') cmd = [sys.executable, '-m', 'pdb', filename] stdout = stderr = None with subprocess.Popen(cmd, stdout=subprocess.PIPE, diff --git a/Lib/test/test_pep277.py b/Lib/test/test_pep277.py index 9bae6dcad7a3..6c833a8b2f2e 100644 --- a/Lib/test/test_pep277.py +++ b/Lib/test/test_pep277.py @@ -56,17 +56,6 @@ "Unicode-friendly filesystem encoding") -# Destroy directory dirname and all files under it, to one level. -def deltree(dirname): - # Don't hide legitimate errors: if one of these suckers exists, it's - # an error if we can't remove it. - if os.path.exists(dirname): - # must pass unicode to os.listdir() so we get back unicode results. - for fname in os.listdir(str(dirname)): - os.unlink(os.path.join(dirname, fname)) - os.rmdir(dirname) - - class UnicodeFileTests(unittest.TestCase): files = set(filenames) normal_form = None @@ -76,6 +65,8 @@ def setUp(self): os.mkdir(support.TESTFN) except FileExistsError: pass + self.addCleanup(support.rmtree, support.TESTFN) + files = set() for name in self.files: name = os.path.join(support.TESTFN, self.norm(name)) @@ -85,9 +76,6 @@ def setUp(self): files.add(name) self.files = files - def tearDown(self): - deltree(support.TESTFN) - def norm(self, s): if self.normal_form: return normalize(self.normal_form, s) @@ -200,16 +188,13 @@ class UnicodeNFKDFileTests(UnicodeFileTests): def test_main(): - try: - support.run_unittest( - UnicodeFileTests, - UnicodeNFCFileTests, - UnicodeNFDFileTests, - UnicodeNFKCFileTests, - UnicodeNFKDFileTests, - ) - finally: - deltree(support.TESTFN) + support.run_unittest( + UnicodeFileTests, + UnicodeNFCFileTests, + UnicodeNFDFileTests, + UnicodeNFKCFileTests, + UnicodeNFKDFileTests, + ) if __name__ == "__main__": diff --git a/Lib/test/test_pep3151.py b/Lib/test/test_pep3151.py index 2792c10f9892..7d4a5d844634 100644 --- a/Lib/test/test_pep3151.py +++ b/Lib/test/test_pep3151.py @@ -157,8 +157,6 @@ def test_blockingioerror(self): e.characters_written = 5 self.assertEqual(e.characters_written, 5) - # XXX VMSError not tested - class ExplicitSubclassingTest(unittest.TestCase): diff --git a/Lib/test/test_pep380.py b/Lib/test/test_pep380.py index 4a43b7d62b5d..69194df9e750 100644 --- a/Lib/test/test_pep380.py +++ b/Lib/test/test_pep380.py @@ -993,6 +993,25 @@ def outer(): del inner_gen gc_collect() + def test_send_tuple_with_custom_generator(self): + # See issue #21209. + class MyGen: + def __iter__(self): + return self + def __next__(self): + return 42 + def send(self, what): + nonlocal v + v = what + return None + def outer(): + v = yield from MyGen() + g = outer() + next(g) + v = None + g.send((1, 2, 3, 4)) + self.assertEqual(v, (1, 2, 3, 4)) + def test_main(): from test import support diff --git a/Lib/test/test_pickle.py b/Lib/test/test_pickle.py index fbe96ac2a818..e1a88b6b5861 100644 --- a/Lib/test/test_pickle.py +++ b/Lib/test/test_pickle.py @@ -1,7 +1,10 @@ import pickle import io import collections +import struct +import sys +import unittest from test import support from test.pickletester import AbstractPickleTests @@ -83,13 +86,17 @@ class PyPicklerUnpicklerObjectTests(AbstractPicklerUnpicklerObjectTests): class PyDispatchTableTests(AbstractDispatchTableTests): + pickler_class = pickle._Pickler + def get_dispatch_table(self): return pickle.dispatch_table.copy() class PyChainDispatchTableTests(AbstractDispatchTableTests): + pickler_class = pickle._Pickler + def get_dispatch_table(self): return collections.ChainMap({}, pickle.dispatch_table) @@ -134,6 +141,71 @@ class CChainDispatchTableTests(AbstractDispatchTableTests): def get_dispatch_table(self): return collections.ChainMap({}, pickle.dispatch_table) + @support.cpython_only + class SizeofTests(unittest.TestCase): + check_sizeof = support.check_sizeof + + def test_pickler(self): + basesize = support.calcobjsize('5P2n3i2n3iP') + p = _pickle.Pickler(io.BytesIO()) + self.assertEqual(object.__sizeof__(p), basesize) + MT_size = struct.calcsize('3nP0n') + ME_size = struct.calcsize('Pn0P') + check = self.check_sizeof + check(p, basesize + + MT_size + 8 * ME_size + # Minimal memo table size. + sys.getsizeof(b'x'*4096)) # Minimal write buffer size. + for i in range(6): + p.dump(chr(i)) + check(p, basesize + + MT_size + 32 * ME_size + # Size of memo table required to + # save references to 6 objects. + 0) # Write buffer is cleared after every dump(). + + def test_unpickler(self): + basesize = support.calcobjsize('2Pn2P 2P2n2i5P 2P3n6P2n2i') + unpickler = _pickle.Unpickler + P = struct.calcsize('P') # Size of memo table entry. + n = struct.calcsize('n') # Size of mark table entry. + check = self.check_sizeof + for encoding in 'ASCII', 'UTF-16', 'latin-1': + for errors in 'strict', 'replace': + u = unpickler(io.BytesIO(), + encoding=encoding, errors=errors) + self.assertEqual(object.__sizeof__(u), basesize) + check(u, basesize + + 32 * P + # Minimal memo table size. + len(encoding) + 1 + len(errors) + 1) + + stdsize = basesize + len('ASCII') + 1 + len('strict') + 1 + def check_unpickler(data, memo_size, marks_size): + dump = pickle.dumps(data) + u = unpickler(io.BytesIO(dump), + encoding='ASCII', errors='strict') + u.load() + check(u, stdsize + memo_size * P + marks_size * n) + + check_unpickler(0, 32, 0) + # 20 is minimal non-empty mark stack size. + check_unpickler([0] * 100, 32, 20) + # 128 is memo table size required to save references to 100 objects. + check_unpickler([chr(i) for i in range(100)], 128, 20) + def recurse(deep): + data = 0 + for i in range(deep): + data = [data, data] + return data + check_unpickler(recurse(0), 32, 0) + check_unpickler(recurse(1), 32, 20) + check_unpickler(recurse(20), 32, 58) + check_unpickler(recurse(50), 64, 58) + check_unpickler(recurse(100), 128, 134) + + u = unpickler(io.BytesIO(pickle.dumps('a', 0)), + encoding='ASCII', errors='strict') + u.load() + check(u, stdsize + 32 * P + 2 + 1) + def test_main(): tests = [PickleTests, PyPicklerTests, PyPersPicklerTests, @@ -144,7 +216,7 @@ def test_main(): PyPicklerUnpicklerObjectTests, CPicklerUnpicklerObjectTests, CDispatchTableTests, CChainDispatchTableTests, - InMemoryPickleTests]) + InMemoryPickleTests, SizeofTests]) support.run_unittest(*tests) support.run_doctest(pickle) diff --git a/Lib/test/test_pickletools.py b/Lib/test/test_pickletools.py index d37ac263c4c1..bbe6875545a7 100644 --- a/Lib/test/test_pickletools.py +++ b/Lib/test/test_pickletools.py @@ -1,3 +1,4 @@ +import struct import pickle import pickletools from test import support @@ -15,6 +16,48 @@ def loads(self, buf, **kwds): # Test relies on precise output of dumps() test_pickle_to_2x = None + def test_optimize_long_binget(self): + data = [str(i) for i in range(257)] + data.append(data[-1]) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + pickled = pickle.dumps(data, proto) + unpickled = pickle.loads(pickled) + self.assertEqual(unpickled, data) + self.assertIs(unpickled[-1], unpickled[-2]) + + pickled2 = pickletools.optimize(pickled) + unpickled2 = pickle.loads(pickled2) + self.assertEqual(unpickled2, data) + self.assertIs(unpickled2[-1], unpickled2[-2]) + self.assertNotIn(pickle.LONG_BINGET, pickled2) + self.assertNotIn(pickle.LONG_BINPUT, pickled2) + + def test_optimize_binput_and_memoize(self): + pickled = (b'\x80\x04\x95\x15\x00\x00\x00\x00\x00\x00\x00' + b']\x94(\x8c\x04spamq\x01\x8c\x03ham\x94h\x02e.') + # 0: \x80 PROTO 4 + # 2: \x95 FRAME 21 + # 11: ] EMPTY_LIST + # 12: \x94 MEMOIZE + # 13: ( MARK + # 14: \x8c SHORT_BINUNICODE 'spam' + # 20: q BINPUT 1 + # 22: \x8c SHORT_BINUNICODE 'ham' + # 27: \x94 MEMOIZE + # 28: h BINGET 2 + # 30: e APPENDS (MARK at 13) + # 31: . STOP + self.assertIn(pickle.BINPUT, pickled) + unpickled = pickle.loads(pickled) + self.assertEqual(unpickled, ['spam', 'ham', 'ham']) + self.assertIs(unpickled[1], unpickled[2]) + + pickled2 = pickletools.optimize(pickled) + unpickled2 = pickle.loads(pickled2) + self.assertEqual(unpickled2, ['spam', 'ham', 'ham']) + self.assertIs(unpickled2[1], unpickled2[2]) + self.assertNotIn(pickle.BINPUT, pickled2) + def test_main(): support.run_unittest(OptimizedPickleTests) diff --git a/Lib/test/test_pkgutil.py b/Lib/test/test_pkgutil.py index d73b2117d3cc..57ebf1fd7fa6 100644 --- a/Lib/test/test_pkgutil.py +++ b/Lib/test/test_pkgutil.py @@ -1,7 +1,8 @@ -from test.support import run_unittest, unload, check_warnings +from test.support import run_unittest, unload, check_warnings, CleanImport import unittest import sys import importlib +from importlib.util import spec_from_file_location import pkgutil import os import os.path @@ -103,23 +104,23 @@ def test_unreadable_dir_on_syspath(self): class PkgutilPEP302Tests(unittest.TestCase): class MyTestLoader(object): - def load_module(self, fullname): - # Create an empty module - mod = sys.modules.setdefault(fullname, types.ModuleType(fullname)) - mod.__file__ = "<%s>" % self.__class__.__name__ - mod.__loader__ = self - # Make it a package - mod.__path__ = [] + def create_module(self, spec): + return None + + def exec_module(self, mod): # Count how many times the module is reloaded - mod.__dict__['loads'] = mod.__dict__.get('loads',0) + 1 - return mod + mod.__dict__['loads'] = mod.__dict__.get('loads', 0) + 1 def get_data(self, path): return "Hello, world!" class MyTestImporter(object): - def find_module(self, fullname, path=None): - return PkgutilPEP302Tests.MyTestLoader() + def find_spec(self, fullname, path=None, target=None): + loader = PkgutilPEP302Tests.MyTestLoader() + return spec_from_file_location(fullname, + '<%s>' % loader.__class__.__name__, + loader=loader, + submodule_search_locations=[]) def setUp(self): sys.meta_path.insert(0, self.MyTestImporter()) @@ -210,7 +211,8 @@ def test_iter_importers(self): importers = list(iter_importers(fullname)) expected_importer = get_importer(pathitem) for finder in importers: - loader = finder.find_module(fullname) + spec = pkgutil._get_spec(finder, fullname) + loader = spec.loader try: loader = loader.loader except AttributeError: @@ -221,7 +223,7 @@ def test_iter_importers(self): self.assertEqual(finder, expected_importer) self.assertIsInstance(loader, importlib.machinery.SourceFileLoader) - self.assertIsNone(finder.find_module(pkgname)) + self.assertIsNone(pkgutil._get_spec(finder, pkgname)) with self.assertRaises(ImportError): list(iter_importers('invalid.module')) @@ -335,6 +337,56 @@ def test_get_loader_avoids_emulation(self): self.assertIsNotNone(pkgutil.get_loader("test.support")) self.assertEqual(len(w.warnings), 0) + def test_get_loader_handles_missing_loader_attribute(self): + global __loader__ + this_loader = __loader__ + del __loader__ + try: + with check_warnings() as w: + self.assertIsNotNone(pkgutil.get_loader(__name__)) + self.assertEqual(len(w.warnings), 0) + finally: + __loader__ = this_loader + + def test_get_loader_handles_missing_spec_attribute(self): + name = 'spam' + mod = type(sys)(name) + del mod.__spec__ + with CleanImport(name): + sys.modules[name] = mod + loader = pkgutil.get_loader(name) + self.assertIsNone(loader) + + def test_get_loader_handles_spec_attribute_none(self): + name = 'spam' + mod = type(sys)(name) + mod.__spec__ = None + with CleanImport(name): + sys.modules[name] = mod + loader = pkgutil.get_loader(name) + self.assertIsNone(loader) + + def test_get_loader_None_in_sys_modules(self): + name = 'totally bogus' + sys.modules[name] = None + try: + loader = pkgutil.get_loader(name) + finally: + del sys.modules[name] + self.assertIsNone(loader) + + def test_find_loader_missing_module(self): + name = 'totally bogus' + loader = pkgutil.find_loader(name) + self.assertIsNone(loader) + + def test_find_loader_avoids_emulation(self): + with check_warnings() as w: + self.assertIsNotNone(pkgutil.find_loader("sys")) + self.assertIsNotNone(pkgutil.find_loader("os")) + self.assertIsNotNone(pkgutil.find_loader("test.support")) + self.assertEqual(len(w.warnings), 0) + def test_get_importer_avoids_emulation(self): # We use an illegal path so *none* of the path hooks should fire with check_warnings() as w: diff --git a/Lib/test/test_platform.py b/Lib/test/test_platform.py index 0dcfe0504a5e..ededbdba4219 100644 --- a/Lib/test/test_platform.py +++ b/Lib/test/test_platform.py @@ -1,7 +1,9 @@ +from unittest import mock import os import platform import subprocess import sys +import tempfile import unittest import warnings @@ -295,6 +297,19 @@ def test_popen(self): returncode = ret >> 8 self.assertEqual(returncode, len(data)) + def test_linux_distribution_encoding(self): + # Issue #17429 + with tempfile.TemporaryDirectory() as tempdir: + filename = os.path.join(tempdir, 'fedora-release') + with open(filename, 'w', encoding='utf-8') as f: + f.write('Fedora release 19 (Schr\xf6dinger\u2019s Cat)\n') + + with mock.patch('platform._UNIXCONFDIR', tempdir): + distname, version, distid = platform.linux_distribution() + + self.assertEqual(distname, 'Fedora') + self.assertEqual(version, '19') + self.assertEqual(distid, 'Schr\xf6dinger\u2019s Cat') def test_main(): support.run_unittest( diff --git a/Lib/test/test_plistlib.py b/Lib/test/test_plistlib.py index abb1d19e63aa..fef9f3997237 100644 --- a/Lib/test/test_plistlib.py +++ b/Lib/test/test_plistlib.py @@ -7,6 +7,7 @@ import codecs import binascii import collections +import struct from test import support from io import BytesIO @@ -19,68 +20,75 @@ PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPCFET0NU WVBFIHBsaXN0IFBVQkxJQyAiLS8vQXBwbGUvL0RURCBQTElTVCAxLjAvL0VO IiAiaHR0cDovL3d3dy5hcHBsZS5jb20vRFREcy9Qcm9wZXJ0eUxpc3QtMS4w - LmR0ZCI+CjxwbGlzdCB2ZXJzaW9uPSIxLjAiPgo8ZGljdD4KCTxrZXk+YURh - dGU8L2tleT4KCTxkYXRlPjIwMDQtMTAtMjZUMTA6MzM6MzNaPC9kYXRlPgoJ - PGtleT5hRGljdDwva2V5PgoJPGRpY3Q+CgkJPGtleT5hRmFsc2VWYWx1ZTwv - a2V5PgoJCTxmYWxzZS8+CgkJPGtleT5hVHJ1ZVZhbHVlPC9rZXk+CgkJPHRy - dWUvPgoJCTxrZXk+YVVuaWNvZGVWYWx1ZTwva2V5PgoJCTxzdHJpbmc+TcOk - c3NpZywgTWHDnzwvc3RyaW5nPgoJCTxrZXk+YW5vdGhlclN0cmluZzwva2V5 - PgoJCTxzdHJpbmc+Jmx0O2hlbGxvICZhbXA7ICdoaScgdGhlcmUhJmd0Ozwv - c3RyaW5nPgoJCTxrZXk+ZGVlcGVyRGljdDwva2V5PgoJCTxkaWN0PgoJCQk8 - a2V5PmE8L2tleT4KCQkJPGludGVnZXI+MTc8L2ludGVnZXI+CgkJCTxrZXk+ - Yjwva2V5PgoJCQk8cmVhbD4zMi41PC9yZWFsPgoJCQk8a2V5PmM8L2tleT4K - CQkJPGFycmF5PgoJCQkJPGludGVnZXI+MTwvaW50ZWdlcj4KCQkJCTxpbnRl - Z2VyPjI8L2ludGVnZXI+CgkJCQk8c3RyaW5nPnRleHQ8L3N0cmluZz4KCQkJ - PC9hcnJheT4KCQk8L2RpY3Q+Cgk8L2RpY3Q+Cgk8a2V5PmFGbG9hdDwva2V5 - PgoJPHJlYWw+MC41PC9yZWFsPgoJPGtleT5hTGlzdDwva2V5PgoJPGFycmF5 - PgoJCTxzdHJpbmc+QTwvc3RyaW5nPgoJCTxzdHJpbmc+Qjwvc3RyaW5nPgoJ - CTxpbnRlZ2VyPjEyPC9pbnRlZ2VyPgoJCTxyZWFsPjMyLjU8L3JlYWw+CgkJ - PGFycmF5PgoJCQk8aW50ZWdlcj4xPC9pbnRlZ2VyPgoJCQk8aW50ZWdlcj4y - PC9pbnRlZ2VyPgoJCQk8aW50ZWdlcj4zPC9pbnRlZ2VyPgoJCTwvYXJyYXk+ - Cgk8L2FycmF5PgoJPGtleT5hU3RyaW5nPC9rZXk+Cgk8c3RyaW5nPkRvb2Rh - aDwvc3RyaW5nPgoJPGtleT5hbkVtcHR5RGljdDwva2V5PgoJPGRpY3QvPgoJ - PGtleT5hbkVtcHR5TGlzdDwva2V5PgoJPGFycmF5Lz4KCTxrZXk+YW5JbnQ8 - L2tleT4KCTxpbnRlZ2VyPjcyODwvaW50ZWdlcj4KCTxrZXk+bmVzdGVkRGF0 - YTwva2V5PgoJPGFycmF5PgoJCTxkYXRhPgoJCVBHeHZkSE1nYjJZZ1ltbHVZ - WEo1SUdkMWJtcytBQUVDQXp4c2IzUnpJRzltSUdKcGJtRnllU0JuZFc1cgoJ - CVBnQUJBZ004Ykc5MGN5QnZaaUJpYVc1aGNua2daM1Z1YXo0QUFRSURQR3h2 - ZEhNZ2IyWWdZbWx1WVhKNQoJCUlHZDFibXMrQUFFQ0F6eHNiM1J6SUc5bUlH - SnBibUZ5ZVNCbmRXNXJQZ0FCQWdNOGJHOTBjeUJ2WmlCaQoJCWFXNWhjbmtn - WjNWdWF6NEFBUUlEUEd4dmRITWdiMllnWW1sdVlYSjVJR2QxYm1zK0FBRUNB - enhzYjNSegoJCUlHOW1JR0pwYm1GeWVTQm5kVzVyUGdBQkFnTThiRzkwY3lC - dlppQmlhVzVoY25rZ1ozVnVhejRBQVFJRAoJCVBHeHZkSE1nYjJZZ1ltbHVZ - WEo1SUdkMWJtcytBQUVDQXc9PQoJCTwvZGF0YT4KCTwvYXJyYXk+Cgk8a2V5 - PnNvbWVEYXRhPC9rZXk+Cgk8ZGF0YT4KCVBHSnBibUZ5ZVNCbmRXNXJQZz09 - Cgk8L2RhdGE+Cgk8a2V5PnNvbWVNb3JlRGF0YTwva2V5PgoJPGRhdGE+CglQ - R3h2ZEhNZ2IyWWdZbWx1WVhKNUlHZDFibXMrQUFFQ0F6eHNiM1J6SUc5bUlH - SnBibUZ5ZVNCbmRXNXJQZ0FCQWdNOAoJYkc5MGN5QnZaaUJpYVc1aGNua2da - M1Z1YXo0QUFRSURQR3h2ZEhNZ2IyWWdZbWx1WVhKNUlHZDFibXMrQUFFQ0F6 - eHMKCWIzUnpJRzltSUdKcGJtRnllU0JuZFc1clBnQUJBZ004Ykc5MGN5QnZa - aUJpYVc1aGNua2daM1Z1YXo0QUFRSURQR3h2CglkSE1nYjJZZ1ltbHVZWEo1 - SUdkMWJtcytBQUVDQXp4c2IzUnpJRzltSUdKcGJtRnllU0JuZFc1clBnQUJB - Z004Ykc5MAoJY3lCdlppQmlhVzVoY25rZ1ozVnVhejRBQVFJRFBHeHZkSE1n - YjJZZ1ltbHVZWEo1SUdkMWJtcytBQUVDQXc9PQoJPC9kYXRhPgoJPGtleT7D - hWJlbnJhYTwva2V5PgoJPHN0cmluZz5UaGF0IHdhcyBhIHVuaWNvZGUga2V5 - Ljwvc3RyaW5nPgo8L2RpY3Q+CjwvcGxpc3Q+Cg=='''), + LmR0ZCI+CjxwbGlzdCB2ZXJzaW9uPSIxLjAiPgo8ZGljdD4KCTxrZXk+YUJp + Z0ludDwva2V5PgoJPGludGVnZXI+OTIyMzM3MjAzNjg1NDc3NTc2NDwvaW50 + ZWdlcj4KCTxrZXk+YUJpZ0ludDI8L2tleT4KCTxpbnRlZ2VyPjkyMjMzNzIw + MzY4NTQ3NzU4NTI8L2ludGVnZXI+Cgk8a2V5PmFEYXRlPC9rZXk+Cgk8ZGF0 + ZT4yMDA0LTEwLTI2VDEwOjMzOjMzWjwvZGF0ZT4KCTxrZXk+YURpY3Q8L2tl + eT4KCTxkaWN0PgoJCTxrZXk+YUZhbHNlVmFsdWU8L2tleT4KCQk8ZmFsc2Uv + PgoJCTxrZXk+YVRydWVWYWx1ZTwva2V5PgoJCTx0cnVlLz4KCQk8a2V5PmFV + bmljb2RlVmFsdWU8L2tleT4KCQk8c3RyaW5nPk3DpHNzaWcsIE1hw588L3N0 + cmluZz4KCQk8a2V5PmFub3RoZXJTdHJpbmc8L2tleT4KCQk8c3RyaW5nPiZs + dDtoZWxsbyAmYW1wOyAnaGknIHRoZXJlISZndDs8L3N0cmluZz4KCQk8a2V5 + PmRlZXBlckRpY3Q8L2tleT4KCQk8ZGljdD4KCQkJPGtleT5hPC9rZXk+CgkJ + CTxpbnRlZ2VyPjE3PC9pbnRlZ2VyPgoJCQk8a2V5PmI8L2tleT4KCQkJPHJl + YWw+MzIuNTwvcmVhbD4KCQkJPGtleT5jPC9rZXk+CgkJCTxhcnJheT4KCQkJ + CTxpbnRlZ2VyPjE8L2ludGVnZXI+CgkJCQk8aW50ZWdlcj4yPC9pbnRlZ2Vy + PgoJCQkJPHN0cmluZz50ZXh0PC9zdHJpbmc+CgkJCTwvYXJyYXk+CgkJPC9k + aWN0PgoJPC9kaWN0PgoJPGtleT5hRmxvYXQ8L2tleT4KCTxyZWFsPjAuNTwv + cmVhbD4KCTxrZXk+YUxpc3Q8L2tleT4KCTxhcnJheT4KCQk8c3RyaW5nPkE8 + L3N0cmluZz4KCQk8c3RyaW5nPkI8L3N0cmluZz4KCQk8aW50ZWdlcj4xMjwv + aW50ZWdlcj4KCQk8cmVhbD4zMi41PC9yZWFsPgoJCTxhcnJheT4KCQkJPGlu + dGVnZXI+MTwvaW50ZWdlcj4KCQkJPGludGVnZXI+MjwvaW50ZWdlcj4KCQkJ + PGludGVnZXI+MzwvaW50ZWdlcj4KCQk8L2FycmF5PgoJPC9hcnJheT4KCTxr + ZXk+YU5lZ2F0aXZlQmlnSW50PC9rZXk+Cgk8aW50ZWdlcj4tODAwMDAwMDAw + MDA8L2ludGVnZXI+Cgk8a2V5PmFOZWdhdGl2ZUludDwva2V5PgoJPGludGVn + ZXI+LTU8L2ludGVnZXI+Cgk8a2V5PmFTdHJpbmc8L2tleT4KCTxzdHJpbmc+ + RG9vZGFoPC9zdHJpbmc+Cgk8a2V5PmFuRW1wdHlEaWN0PC9rZXk+Cgk8ZGlj + dC8+Cgk8a2V5PmFuRW1wdHlMaXN0PC9rZXk+Cgk8YXJyYXkvPgoJPGtleT5h + bkludDwva2V5PgoJPGludGVnZXI+NzI4PC9pbnRlZ2VyPgoJPGtleT5uZXN0 + ZWREYXRhPC9rZXk+Cgk8YXJyYXk+CgkJPGRhdGE+CgkJUEd4dmRITWdiMlln + WW1sdVlYSjVJR2QxYm1zK0FBRUNBenhzYjNSeklHOW1JR0pwYm1GeWVTQm5k + VzVyCgkJUGdBQkFnTThiRzkwY3lCdlppQmlhVzVoY25rZ1ozVnVhejRBQVFJ + RFBHeHZkSE1nYjJZZ1ltbHVZWEo1CgkJSUdkMWJtcytBQUVDQXp4c2IzUnpJ + RzltSUdKcGJtRnllU0JuZFc1clBnQUJBZ004Ykc5MGN5QnZaaUJpCgkJYVc1 + aGNua2daM1Z1YXo0QUFRSURQR3h2ZEhNZ2IyWWdZbWx1WVhKNUlHZDFibXMr + QUFFQ0F6eHNiM1J6CgkJSUc5bUlHSnBibUZ5ZVNCbmRXNXJQZ0FCQWdNOGJH + OTBjeUJ2WmlCaWFXNWhjbmtnWjNWdWF6NEFBUUlECgkJUEd4dmRITWdiMlln + WW1sdVlYSjVJR2QxYm1zK0FBRUNBdz09CgkJPC9kYXRhPgoJPC9hcnJheT4K + CTxrZXk+c29tZURhdGE8L2tleT4KCTxkYXRhPgoJUEdKcGJtRnllU0JuZFc1 + clBnPT0KCTwvZGF0YT4KCTxrZXk+c29tZU1vcmVEYXRhPC9rZXk+Cgk8ZGF0 + YT4KCVBHeHZkSE1nYjJZZ1ltbHVZWEo1SUdkMWJtcytBQUVDQXp4c2IzUnpJ + RzltSUdKcGJtRnllU0JuZFc1clBnQUJBZ004CgliRzkwY3lCdlppQmlhVzVo + Y25rZ1ozVnVhejRBQVFJRFBHeHZkSE1nYjJZZ1ltbHVZWEo1SUdkMWJtcytB + QUVDQXp4cwoJYjNSeklHOW1JR0pwYm1GeWVTQm5kVzVyUGdBQkFnTThiRzkw + Y3lCdlppQmlhVzVoY25rZ1ozVnVhejRBQVFJRFBHeHYKCWRITWdiMllnWW1s + dVlYSjVJR2QxYm1zK0FBRUNBenhzYjNSeklHOW1JR0pwYm1GeWVTQm5kVzVy + UGdBQkFnTThiRzkwCgljeUJ2WmlCaWFXNWhjbmtnWjNWdWF6NEFBUUlEUEd4 + dmRITWdiMllnWW1sdVlYSjVJR2QxYm1zK0FBRUNBdz09Cgk8L2RhdGE+Cgk8 + a2V5PsOFYmVucmFhPC9rZXk+Cgk8c3RyaW5nPlRoYXQgd2FzIGEgdW5pY29k + ZSBrZXkuPC9zdHJpbmc+CjwvZGljdD4KPC9wbGlzdD4K'''), plistlib.FMT_BINARY: binascii.a2b_base64(b''' - YnBsaXN0MDDcAQIDBAUGBwgJCgsMDQ4iIykqKywtLy4wVWFEYXRlVWFEaWN0 - VmFGbG9hdFVhTGlzdFdhU3RyaW5nW2FuRW1wdHlEaWN0W2FuRW1wdHlMaXN0 - VWFuSW50Wm5lc3RlZERhdGFYc29tZURhdGFcc29tZU1vcmVEYXRhZwDFAGIA - ZQBuAHIAYQBhM0GcuX30AAAA1Q8QERITFBUWFxhbYUZhbHNlVmFsdWVaYVRy - dWVWYWx1ZV1hVW5pY29kZVZhbHVlXWFub3RoZXJTdHJpbmdaZGVlcGVyRGlj - dAgJawBNAOQAcwBzAGkAZwAsACAATQBhAN9fEBU8aGVsbG8gJiAnaGknIHRo - ZXJlIT7TGRobHB0eUWFRYlFjEBEjQEBAAAAAAACjHyAhEAEQAlR0ZXh0Iz/g - AAAAAAAApSQlJh0nUUFRQhAMox8gKBADVkRvb2RhaNCgEQLYoS5PEPo8bG90 - cyBvZiBiaW5hcnkgZ3Vuaz4AAQIDPGxvdHMgb2YgYmluYXJ5IGd1bms+AAEC - Azxsb3RzIG9mIGJpbmFyeSBndW5rPgABAgM8bG90cyBvZiBiaW5hcnkgZ3Vu - az4AAQIDPGxvdHMgb2YgYmluYXJ5IGd1bms+AAECAzxsb3RzIG9mIGJpbmFy - eSBndW5rPgABAgM8bG90cyBvZiBiaW5hcnkgZ3Vuaz4AAQIDPGxvdHMgb2Yg - YmluYXJ5IGd1bms+AAECAzxsb3RzIG9mIGJpbmFyeSBndW5rPgABAgM8bG90 - cyBvZiBiaW5hcnkgZ3Vuaz4AAQIDTTxiaW5hcnkgZ3Vuaz5fEBdUaGF0IHdh - cyBhIHVuaWNvZGUga2V5LgAIACEAJwAtADQAOgBCAE4AWgBgAGsAdACBAJAA - mQCkALAAuwDJANcA4gDjAOQA+wETARoBHAEeASABIgErAS8BMQEzATgBQQFH - AUkBSwFNAVEBUwFaAVsBXAFfAWECXgJsAAAAAAAAAgEAAAAAAAAAMQAAAAAA - AAAAAAAAAAAAAoY='''), + YnBsaXN0MDDfEBABAgMEBQYHCAkKCwwNDg8QERITFCgpLzAxMjM0NTc2OFdh + QmlnSW50WGFCaWdJbnQyVWFEYXRlVWFEaWN0VmFGbG9hdFVhTGlzdF8QD2FO + ZWdhdGl2ZUJpZ0ludFxhTmVnYXRpdmVJbnRXYVN0cmluZ1thbkVtcHR5RGlj + dFthbkVtcHR5TGlzdFVhbkludFpuZXN0ZWREYXRhWHNvbWVEYXRhXHNvbWVN + b3JlRGF0YWcAxQBiAGUAbgByAGEAYRN/////////1BQAAAAAAAAAAIAAAAAA + AAAsM0GcuX30AAAA1RUWFxgZGhscHR5bYUZhbHNlVmFsdWVaYVRydWVWYWx1 + ZV1hVW5pY29kZVZhbHVlXWFub3RoZXJTdHJpbmdaZGVlcGVyRGljdAgJawBN + AOQAcwBzAGkAZwAsACAATQBhAN9fEBU8aGVsbG8gJiAnaGknIHRoZXJlIT7T + HyAhIiMkUWFRYlFjEBEjQEBAAAAAAACjJSYnEAEQAlR0ZXh0Iz/gAAAAAAAA + pSorLCMtUUFRQhAMoyUmLhADE////+1foOAAE//////////7VkRvb2RhaNCg + EQLYoTZPEPo8bG90cyBvZiBiaW5hcnkgZ3Vuaz4AAQIDPGxvdHMgb2YgYmlu + YXJ5IGd1bms+AAECAzxsb3RzIG9mIGJpbmFyeSBndW5rPgABAgM8bG90cyBv + ZiBiaW5hcnkgZ3Vuaz4AAQIDPGxvdHMgb2YgYmluYXJ5IGd1bms+AAECAzxs + b3RzIG9mIGJpbmFyeSBndW5rPgABAgM8bG90cyBvZiBiaW5hcnkgZ3Vuaz4A + AQIDPGxvdHMgb2YgYmluYXJ5IGd1bms+AAECAzxsb3RzIG9mIGJpbmFyeSBn + dW5rPgABAgM8bG90cyBvZiBiaW5hcnkgZ3Vuaz4AAQIDTTxiaW5hcnkgZ3Vu + az5fEBdUaGF0IHdhcyBhIHVuaWNvZGUga2V5LgAIACsAMwA8AEIASABPAFUA + ZwB0AHwAiACUAJoApQCuALsAygDTAOQA7QD4AQQBDwEdASsBNgE3ATgBTwFn + AW4BcAFyAXQBdgF/AYMBhQGHAYwBlQGbAZ0BnwGhAaUBpwGwAbkBwAHBAcIB + xQHHAsQC0gAAAAAAAAIBAAAAAAAAADkAAAAAAAAAAAAAAAAAAALs'''), } @@ -98,6 +106,10 @@ def _create(self, fmt=None): aList=["A", "B", 12, 32.5, [1, 2, 3]], aFloat = 0.5, anInt = 728, + aBigInt = 2 ** 63 - 44, + aBigInt2 = 2 ** 63 + 44, + aNegativeInt = -5, + aNegativeBigInt = -80000000000, aDict=dict( anotherString="", aUnicodeValue='M\xe4ssig, Ma\xdf', @@ -133,6 +145,30 @@ def test_io(self): self.assertRaises(AttributeError, plistlib.dump, pl, 'filename') self.assertRaises(AttributeError, plistlib.load, 'filename') + def test_invalid_type(self): + pl = [ object() ] + + for fmt in ALL_FORMATS: + with self.subTest(fmt=fmt): + self.assertRaises(TypeError, plistlib.dumps, pl, fmt=fmt) + + def test_int(self): + for pl in [0, 2**8-1, 2**8, 2**16-1, 2**16, 2**32-1, 2**32, + 2**63-1, 2**64-1, 1, -2**63]: + for fmt in ALL_FORMATS: + with self.subTest(pl=pl, fmt=fmt): + data = plistlib.dumps(pl, fmt=fmt) + pl2 = plistlib.loads(data) + self.assertIsInstance(pl2, int) + self.assertEqual(pl, pl2) + data2 = plistlib.dumps(pl2, fmt=fmt) + self.assertEqual(data, data2) + + for fmt in ALL_FORMATS: + for pl in (2 ** 64 + 1, 2 ** 127-1, -2**64, -2 ** 127): + with self.subTest(pl=pl, fmt=fmt): + self.assertRaises(OverflowError, plistlib.dumps, + pl, fmt=fmt) def test_bytes(self): pl = self._create() @@ -171,6 +207,9 @@ def test_appleformattingfromliteral(self): for fmt in ALL_FORMATS: with self.subTest(fmt=fmt): pl = self._create(fmt=fmt) + pl2 = plistlib.loads(TESTDATA[fmt], fmt=fmt) + self.assertEqual(dict(pl), dict(pl2), + "generated data was not identical to Apple's output") pl2 = plistlib.loads(TESTDATA[fmt]) self.assertEqual(dict(pl), dict(pl2), "generated data was not identical to Apple's output") @@ -181,6 +220,8 @@ def test_bytesio(self): b = BytesIO() pl = self._create(fmt=fmt) plistlib.dump(pl, b, fmt=fmt) + pl2 = plistlib.load(BytesIO(b.getvalue()), fmt=fmt) + self.assertEqual(dict(pl), dict(pl2)) pl2 = plistlib.load(BytesIO(b.getvalue())) self.assertEqual(dict(pl), dict(pl2)) @@ -375,6 +416,18 @@ def test_xml_encodings(self): pl2 = plistlib.loads(data) self.assertEqual(dict(pl), dict(pl2)) + def test_nonstandard_refs_size(self): + # Issue #21538: Refs and offsets are 24-bit integers + data = (b'bplist00' + b'\xd1\x00\x00\x01\x00\x00\x02QaQb' + b'\x00\x00\x08\x00\x00\x0f\x00\x00\x11' + b'\x00\x00\x00\x00\x00\x00' + b'\x03\x03' + b'\x00\x00\x00\x00\x00\x00\x00\x03' + b'\x00\x00\x00\x00\x00\x00\x00\x00' + b'\x00\x00\x00\x00\x00\x00\x00\x13') + self.assertEqual(plistlib.loads(data), {'a': 'b'}) + class TestPlistlibDeprecated(unittest.TestCase): def test_io_deprecated(self): diff --git a/Lib/test/test_poll.py b/Lib/test/test_poll.py index a1e5c3dbf875..a0a332bdbcb7 100644 --- a/Lib/test/test_poll.py +++ b/Lib/test/test_poll.py @@ -4,14 +4,13 @@ import subprocess import random import select -import _testcapi try: import threading except ImportError: threading = None import time import unittest -from test.support import TESTFN, run_unittest, reap_threads +from test.support import TESTFN, run_unittest, reap_threads, cpython_only try: select.poll @@ -161,14 +160,23 @@ def test_poll3(self): if x != 5: self.fail('Overflow must have occurred') + # Issues #15989, #17919 + self.assertRaises(OverflowError, pollster.register, 0, -1) + self.assertRaises(OverflowError, pollster.register, 0, 1 << 64) + self.assertRaises(OverflowError, pollster.modify, 1, -1) + self.assertRaises(OverflowError, pollster.modify, 1, 1 << 64) + + @cpython_only + def test_poll_c_limits(self): + from _testcapi import USHRT_MAX, INT_MAX, UINT_MAX pollster = select.poll() - # Issue 15989 - self.assertRaises(OverflowError, pollster.register, 0, - _testcapi.SHRT_MAX + 1) - self.assertRaises(OverflowError, pollster.register, 0, - _testcapi.USHRT_MAX + 1) - self.assertRaises(OverflowError, pollster.poll, _testcapi.INT_MAX + 1) - self.assertRaises(OverflowError, pollster.poll, _testcapi.UINT_MAX + 1) + pollster.register(1) + + # Issues #15989, #17919 + self.assertRaises(OverflowError, pollster.register, 0, USHRT_MAX + 1) + self.assertRaises(OverflowError, pollster.modify, 1, USHRT_MAX + 1) + self.assertRaises(OverflowError, pollster.poll, INT_MAX + 1) + self.assertRaises(OverflowError, pollster.poll, UINT_MAX + 1) @unittest.skipUnless(threading, 'Threading required for this test.') @reap_threads diff --git a/Lib/test/test_popen.py b/Lib/test/test_popen.py index accf187b54d7..225e41f86b48 100644 --- a/Lib/test/test_popen.py +++ b/Lib/test/test_popen.py @@ -1,4 +1,3 @@ -#! /usr/bin/env python3 """Basic tests for os.popen() Particularly useful for platforms that fake popen. diff --git a/Lib/test/test_poplib.py b/Lib/test/test_poplib.py index 70fe4265c5b4..14a519d8ecc2 100644 --- a/Lib/test/test_poplib.py +++ b/Lib/test/test_poplib.py @@ -23,7 +23,9 @@ import ssl SUPPORTS_SSL = True - CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir, "keycert.pem") + CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir, "keycert3.pem") + CAFILE = os.path.join(os.path.dirname(__file__) or os.curdir, "pycacert.pem") + requires_ssl = skipUnless(SUPPORTS_SSL, 'SSL not supported') # the dummy data returned by server when LIST and RETR commands are issued @@ -332,28 +334,29 @@ def test_stls(self): def test_stls_context(self): expected = b'+OK Begin TLS negotiation' ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) + ctx.load_verify_locations(CAFILE) + ctx.verify_mode = ssl.CERT_REQUIRED + ctx.check_hostname = True + with self.assertRaises(ssl.CertificateError): + resp = self.client.stls(context=ctx) + self.client = poplib.POP3("localhost", self.server.port, timeout=3) resp = self.client.stls(context=ctx) self.assertEqual(resp, expected) if SUPPORTS_SSL: + from test.test_ftplib import SSLConnection - class DummyPOP3_SSLHandler(DummyPOP3Handler): + class DummyPOP3_SSLHandler(SSLConnection, DummyPOP3Handler): def __init__(self, conn): asynchat.async_chat.__init__(self, conn) - ssl_socket = ssl.wrap_socket(self.socket, certfile=CERTFILE, - server_side=True, - do_handshake_on_connect=False) - self.del_channel() - self.set_socket(ssl_socket) - # Must try handshake before calling push() - self.tls_active = True - self.tls_starting = True - self._do_tls_handshake() + self.secure_connection() self.set_terminator(b"\r\n") self.in_buffer = [] self.push('+OK dummy pop3 server ready. ') + self.tls_active = True + self.tls_starting = False @requires_ssl @@ -414,7 +417,7 @@ def tearDown(self): # happens in the test_too_long_lines case; the overlong # response will be treated as response to QUIT and raise # this exception - pass + self.client.close() self.server.stop() def test_stls(self): @@ -444,7 +447,7 @@ def tearDown(self): del self.thread # Clear out any dangling Thread objects. def server(self, evt, serv): - serv.listen(5) + serv.listen() evt.set() try: conn, addr = serv.accept() @@ -456,7 +459,7 @@ def server(self, evt, serv): serv.close() def testTimeoutDefault(self): - self.assertTrue(socket.getdefaulttimeout() is None) + self.assertIsNone(socket.getdefaulttimeout()) socket.setdefaulttimeout(30) try: pop = poplib.POP3(HOST, self.port) @@ -466,13 +469,13 @@ def testTimeoutDefault(self): pop.sock.close() def testTimeoutNone(self): - self.assertTrue(socket.getdefaulttimeout() is None) + self.assertIsNone(socket.getdefaulttimeout()) socket.setdefaulttimeout(30) try: pop = poplib.POP3(HOST, self.port, timeout=None) finally: socket.setdefaulttimeout(None) - self.assertTrue(pop.sock.gettimeout() is None) + self.assertIsNone(pop.sock.gettimeout()) pop.sock.close() def testTimeoutValue(self): diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py index 1eceebe7ac95..f37f2de11c10 100644 --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -9,7 +9,6 @@ import sys import time import os -import fcntl import platform import pwd import shutil @@ -17,7 +16,6 @@ import tempfile import unittest import warnings -import _testcapi _DUMMY_SYMLINK = os.path.join(tempfile.gettempdir(), support.TESTFN + '-dummy-symlink') @@ -283,9 +281,21 @@ def test_utime_nofollow_symlinks(self): def test_writev(self): fd = os.open(support.TESTFN, os.O_RDWR | os.O_CREAT) try: - os.writev(fd, (b'test1', b'tt2', b't3')) + n = os.writev(fd, (b'test1', b'tt2', b't3')) + self.assertEqual(n, 10) + os.lseek(fd, 0, os.SEEK_SET) self.assertEqual(b'test1tt2t3', posix.read(fd, 10)) + + # Issue #20113: empty list of buffers should not crash + try: + size = posix.writev(fd, []) + except OSError: + # writev(fd, []) raises OSError(22, "Invalid argument") + # on OpenIndiana + pass + else: + self.assertEqual(size, 0) finally: os.close(fd) @@ -298,6 +308,16 @@ def test_readv(self): buf = [bytearray(i) for i in [5, 3, 2]] self.assertEqual(posix.readv(fd, buf), 10) self.assertEqual([b'test1', b'tt2', b't3'], [bytes(i) for i in buf]) + + # Issue #20113: empty list of buffers should not crash + try: + size = posix.readv(fd, []) + except OSError: + # readv(fd, []) raises OSError(22, "Invalid argument") + # on OpenIndiana + pass + else: + self.assertEqual(size, 0) finally: os.close(fd) @@ -334,7 +354,7 @@ def test_dup2(self): def test_oscloexec(self): fd = os.open(support.TESTFN, os.O_RDONLY|os.O_CLOEXEC) self.addCleanup(os.close, fd) - self.assertTrue(fcntl.fcntl(fd, fcntl.F_GETFD) & fcntl.FD_CLOEXEC) + self.assertFalse(os.get_inheritable(fd)) @unittest.skipUnless(hasattr(posix, 'O_EXLOCK'), 'test needs posix.O_EXLOCK') @@ -584,8 +604,8 @@ def test_pipe2(self): self.addCleanup(os.close, w) self.assertFalse(os.get_inheritable(r)) self.assertFalse(os.get_inheritable(w)) - self.assertTrue(fcntl.fcntl(r, fcntl.F_GETFL) & os.O_NONBLOCK) - self.assertTrue(fcntl.fcntl(w, fcntl.F_GETFL) & os.O_NONBLOCK) + self.assertFalse(os.get_blocking(r)) + self.assertFalse(os.get_blocking(w)) # try reading from an empty pipe: this should fail, not block self.assertRaises(OSError, os.read, r, 1) # try a write big enough to fill-up the pipe: this should either @@ -595,7 +615,12 @@ def test_pipe2(self): except OSError: pass + @support.cpython_only + @unittest.skipUnless(hasattr(os, 'pipe2'), "test needs os.pipe2()") + @support.requires_linux_version(2, 6, 27) + def test_pipe2_c_limits(self): # Issue 15989 + import _testcapi self.assertRaises(OverflowError, os.pipe2, _testcapi.INT_MAX + 1) self.assertRaises(OverflowError, os.pipe2, _testcapi.UINT_MAX + 1) @@ -731,7 +756,7 @@ def test_getgrouplist(self): @unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()") def test_getgroups(self): - with os.popen('id -G') as idg: + with os.popen('id -G 2>/dev/null') as idg: groups = idg.read().strip() ret = idg.close() @@ -742,7 +767,7 @@ def test_getgroups(self): if sys.platform == 'darwin': import sysconfig dt = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') or '10.0' - if float(dt) < 10.6: + if tuple(int(n) for n in dt.split('.')[0:2]) < (10, 6): raise unittest.SkipTest("getgroups(2) is broken prior to 10.6") # 'id -G' and 'os.getgroups()' should return the same @@ -1095,6 +1120,24 @@ def test_fs_holes(self): # http://lists.freebsd.org/pipermail/freebsd-amd64/2012-January/014332.html raise unittest.SkipTest("OSError raised!") + def test_path_error2(self): + """ + Test functions that call path_error2(), providing two filenames in their exceptions. + """ + for name in ("rename", "replace", "link"): + function = getattr(os, name, None) + if function is None: + continue + + for dst in ("noodly2", support.TESTFN): + try: + function('doesnotexistfilename', dst) + except OSError as e: + self.assertIn("'doesnotexistfilename' -> '{}'".format(dst), str(e)) + break + else: + self.fail("No valid path_error2() test for os." + name) + class PosixGroupsTester(unittest.TestCase): def setUp(self): @@ -1118,7 +1161,7 @@ def tearDown(self): def test_initgroups(self): # find missing group - g = max(self.saved_groups) + 1 + g = max(self.saved_groups or [0]) + 1 name = pwd.getpwuid(posix.getuid()).pw_name posix.initgroups(name, g) self.assertIn(g, posix.getgroups()) diff --git a/Lib/test/test_posixpath.py b/Lib/test/test_posixpath.py index 412849cff3a3..b2454794e5bd 100644 --- a/Lib/test/test_posixpath.py +++ b/Lib/test/test_posixpath.py @@ -57,22 +57,6 @@ def test_join(self): self.assertEqual(posixpath.join(b"/foo/", b"bar/", b"baz/"), b"/foo/bar/baz/") - def check_error_msg(list_of_args, msg): - """Check posixpath.join raises friendly TypeErrors.""" - for args in (item for perm in list_of_args - for item in itertools.permutations(perm)): - with self.assertRaises(TypeError) as cm: - posixpath.join(*args) - self.assertEqual(msg, cm.exception.args[0]) - - check_error_msg([[b'bytes', 'str'], [bytearray(b'bytes'), 'str']], - "Can't mix strings and bytes in path components.") - # regression, see #15377 - with self.assertRaises(TypeError) as cm: - posixpath.join(None, 'str') - self.assertNotEqual("Can't mix strings and bytes in path components.", - cm.exception.args[0]) - def test_split(self): self.assertEqual(posixpath.split("/foo/bar"), ("/foo", "bar")) self.assertEqual(posixpath.split("/"), ("/", "")) diff --git a/Lib/test/test_pprint.py b/Lib/test/test_pprint.py index 3d364c459574..c0568808a075 100644 --- a/Lib/test/test_pprint.py +++ b/Lib/test/test_pprint.py @@ -191,11 +191,53 @@ def test_nested_indentations(self): o2 = dict(first=1, second=2, third=3) o = [o1, o2] expected = """\ +[ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], + {'first': 1, 'second': 2, 'third': 3}]""" + self.assertEqual(pprint.pformat(o, indent=4, width=42), expected) + expected = """\ [ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], { 'first': 1, 'second': 2, 'third': 3}]""" - self.assertEqual(pprint.pformat(o, indent=4, width=42), expected) + self.assertEqual(pprint.pformat(o, indent=4, width=41), expected) + + def test_width(self): + expected = """\ +[[[[[[1, 2, 3], + '1 2']]]], + {1: [1, 2, 3], + 2: [12, 34]}, + 'abc def ghi', + ('ab cd ef',), + set2({1, 23}), + [[[[[1, 2, 3], + '1 2']]]]]""" + o = eval(expected) + self.assertEqual(pprint.pformat(o, width=15), expected) + self.assertEqual(pprint.pformat(o, width=16), expected) + self.assertEqual(pprint.pformat(o, width=25), expected) + self.assertEqual(pprint.pformat(o, width=14), """\ +[[[[[[1, + 2, + 3], + '1 ' + '2']]]], + {1: [1, + 2, + 3], + 2: [12, + 34]}, + 'abc def ' + 'ghi', + ('ab cd ' + 'ef',), + set2({1, + 23}), + [[[[[1, + 2, + 3], + '1 ' + '2']]]]]""") def test_sorted_dict(self): # Starting in Python 2.5, pprint sorts dict displays by key regardless @@ -535,12 +577,12 @@ def test_sort_unorderable_values(self): def test_str_wrap(self): # pprint tries to wrap strings intelligently fox = 'the quick brown fox jumped over a lazy dog' - self.assertEqual(pprint.pformat(fox, width=20), """\ -'the quick brown ' -'fox jumped over ' -'a lazy dog'""") + self.assertEqual(pprint.pformat(fox, width=19), """\ +('the quick brown ' + 'fox jumped over ' + 'a lazy dog')""") self.assertEqual(pprint.pformat({'a': 1, 'b': fox, 'c': 2}, - width=26), """\ + width=25), """\ {'a': 1, 'b': 'the quick brown ' 'fox jumped over ' @@ -552,12 +594,34 @@ def test_str_wrap(self): # - non-ASCII is allowed # - an apostrophe doesn't disrupt the pprint special = "Portons dix bons \"whiskys\"\nà l'avocat goujat\t qui fumait au zoo" + self.assertEqual(pprint.pformat(special, width=68), repr(special)) + self.assertEqual(pprint.pformat(special, width=31), """\ +('Portons dix bons "whiskys"\\n' + "à l'avocat goujat\\t qui " + 'fumait au zoo')""") self.assertEqual(pprint.pformat(special, width=20), """\ -'Portons dix bons ' -'"whiskys"\\n' -"à l'avocat " -'goujat\\t qui ' -'fumait au zoo'""") +('Portons dix bons ' + '"whiskys"\\n' + "à l'avocat " + 'goujat\\t qui ' + 'fumait au zoo')""") + self.assertEqual(pprint.pformat([[[[[special]]]]], width=35), """\ +[[[[['Portons dix bons "whiskys"\\n' + "à l'avocat goujat\\t qui " + 'fumait au zoo']]]]]""") + self.assertEqual(pprint.pformat([[[[[special]]]]], width=25), """\ +[[[[['Portons dix bons ' + '"whiskys"\\n' + "à l'avocat " + 'goujat\\t qui ' + 'fumait au zoo']]]]]""") + self.assertEqual(pprint.pformat([[[[[special]]]]], width=23), """\ +[[[[['Portons dix ' + 'bons "whiskys"\\n' + "à l'avocat " + 'goujat\\t qui ' + 'fumait au ' + 'zoo']]]]]""") # An unwrappable string is formatted as its repr unwrappable = "x" * 100 self.assertEqual(pprint.pformat(unwrappable, width=80), repr(unwrappable)) @@ -566,7 +630,9 @@ def test_str_wrap(self): special *= 10 for width in range(3, 40): formatted = pprint.pformat(special, width=width) - self.assertEqual(eval("(" + formatted + ")"), special) + self.assertEqual(eval(formatted), special) + formatted = pprint.pformat([special] * 2, width=width) + self.assertEqual(eval(formatted), [special] * 2) def test_compact(self): o = ([list(range(i * i)) for i in range(5)] + @@ -578,7 +644,19 @@ def test_compact(self): 14, 15], [], [0], [0, 1], [0, 1, 2], [0, 1, 2, 3], [0, 1, 2, 3, 4]]""" - self.assertEqual(pprint.pformat(o, width=48, compact=True), expected) + self.assertEqual(pprint.pformat(o, width=47, compact=True), expected) + + def test_compact_width(self): + levels = 20 + number = 10 + o = [0] * number + for i in range(levels - 1): + o = [o] + for w in range(levels * 2 + 1, levels + 3 * number - 1): + lines = pprint.pformat(o, width=w, compact=True).splitlines() + maxwidth = max(map(len, lines)) + self.assertLessEqual(maxwidth, w) + self.assertGreater(maxwidth, w - 3) class DottedPrettyPrinter(pprint.PrettyPrinter): diff --git a/Lib/test/test_pty.py b/Lib/test/test_pty.py index 8916861f5bb4..9b783c376832 100644 --- a/Lib/test/test_pty.py +++ b/Lib/test/test_pty.py @@ -1,7 +1,6 @@ from test.support import verbose, run_unittest, import_module, reap_children -#Skip these tests if either fcntl or termios is not available -fcntl = import_module('fcntl') +# Skip these tests if termios is not available import_module('termios') import errno @@ -84,16 +83,18 @@ def test_basic(self): # in master_open(), we need to read the EOF. # Ensure the fd is non-blocking in case there's nothing to read. - orig_flags = fcntl.fcntl(master_fd, fcntl.F_GETFL) - fcntl.fcntl(master_fd, fcntl.F_SETFL, orig_flags | os.O_NONBLOCK) + blocking = os.get_blocking(master_fd) try: - s1 = os.read(master_fd, 1024) - self.assertEqual(b'', s1) - except OSError as e: - if e.errno != errno.EAGAIN: - raise - # Restore the original flags. - fcntl.fcntl(master_fd, fcntl.F_SETFL, orig_flags) + os.set_blocking(master_fd, False) + try: + s1 = os.read(master_fd, 1024) + self.assertEqual(b'', s1) + except OSError as e: + if e.errno != errno.EAGAIN: + raise + finally: + # Restore the original flags. + os.set_blocking(master_fd, blocking) debug("Writing to slave_fd") os.write(slave_fd, TEST_STRING_1) diff --git a/Lib/test/test_pwd.py b/Lib/test/test_pwd.py index aa8f69f69bfd..37a1bcb28b83 100644 --- a/Lib/test/test_pwd.py +++ b/Lib/test/test_pwd.py @@ -8,8 +8,6 @@ class PwdTest(unittest.TestCase): def test_values(self): entries = pwd.getpwall() - entriesbyname = {} - entriesbyuid = {} for e in entries: self.assertEqual(len(e), 7) @@ -32,13 +30,20 @@ def test_values(self): # for one uid # self.assertEqual(pwd.getpwuid(e.pw_uid), e) # instead of this collect all entries for one uid - # and check afterwards + # and check afterwards (done in test_values_extended) + + def test_values_extended(self): + entries = pwd.getpwall() + entriesbyname = {} + entriesbyuid = {} + + if len(entries) > 1000: # Huge passwd file (NIS?) -- skip this test + self.skipTest('passwd file is huge; extended test skipped') + + for e in entries: entriesbyname.setdefault(e.pw_name, []).append(e) entriesbyuid.setdefault(e.pw_uid, []).append(e) - if len(entries) > 1000: # Huge passwd file (NIS?) -- skip the rest - return - # check whether the entry returned by getpwuid() # for each uid is among those from getpwall() for this uid for e in entries: diff --git a/Lib/test/test_py_compile.py b/Lib/test/test_py_compile.py index 154c08a6a2e4..1abea278a2b0 100644 --- a/Lib/test/test_py_compile.py +++ b/Lib/test/test_py_compile.py @@ -7,7 +7,8 @@ import tempfile import unittest -from test import support, script_helper +from test import support + class PyCompileTests(unittest.TestCase): @@ -92,6 +93,32 @@ def test_exceptions_propagate(self): finally: os.chmod(self.directory, mode.st_mode) + def test_bad_coding(self): + bad_coding = os.path.join(os.path.dirname(__file__), 'bad_coding2.py') + with support.captured_stderr(): + self.assertIsNone(py_compile.compile(bad_coding, doraise=False)) + self.assertFalse(os.path.exists( + importlib.util.cache_from_source(bad_coding))) + + def test_double_dot_no_clobber(self): + # http://bugs.python.org/issue22966 + # py_compile foo.bar.py -> __pycache__/foo.cpython-34.pyc + weird_path = os.path.join(self.directory, 'foo.bar.py') + cache_path = importlib.util.cache_from_source(weird_path) + pyc_path = weird_path + 'c' + head, tail = os.path.split(cache_path) + penultimate_tail = os.path.basename(head) + self.assertEqual( + os.path.join(penultimate_tail, tail), + os.path.join( + '__pycache__', + 'foo.bar.{}.pyc'.format(sys.implementation.cache_tag))) + with open(weird_path, 'w') as file: + file.write('x = 123\n') + py_compile.compile(weird_path) + self.assertTrue(os.path.exists(cache_path)) + self.assertFalse(os.path.exists(pyc_path)) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_pyclbr.py b/Lib/test/test_pyclbr.py index 88aff898d400..39eb65f10d5f 100644 --- a/Lib/test/test_pyclbr.py +++ b/Lib/test/test_pyclbr.py @@ -159,7 +159,7 @@ def test_others(self): cm('cgi', ignore=('log',)) # set with = in module cm('pickle') cm('aifc', ignore=('openfp', '_aifc_params')) # set with = in module - cm('sre_parse', ignore=('dump',)) # from sre_constants import * + cm('sre_parse', ignore=('dump', 'groups')) # from sre_constants import *; property cm('pdb') cm('pydoc') diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py index cdf28a4d3d0a..e9fed0ad1681 100644 --- a/Lib/test/test_pydoc.py +++ b/Lib/test/test_pydoc.py @@ -2,17 +2,21 @@ import sys import builtins import contextlib -import difflib +import importlib.util import inspect import pydoc +import py_compile import keyword +import _pickle import pkgutil import re +import stat import string import test.support import time import types import unittest +import urllib.parse import xml.etree import textwrap from io import StringIO @@ -21,7 +25,7 @@ from test.support import ( TESTFN, rmtree, reap_children, reap_threads, captured_output, captured_stdout, - captured_stderr, unlink + captured_stderr, unlink, requires_docstrings ) from test import pydoc_mod @@ -30,6 +34,10 @@ except ImportError: threading = None +class nonascii: + 'Це не латиницÑ' + pass + if test.support.HAVE_DOCSTRINGS: expected_data_docstrings = ( 'dictionary for instance variables (if defined)', @@ -46,6 +54,7 @@ builtins.object A B + C \x20\x20\x20\x20 class A(builtins.object) | Hello and goodbye @@ -73,6 +82,26 @@ class B(builtins.object) | Data and other attributes defined here: |\x20\x20 | NO_MEANING = 'eggs' +\x20\x20\x20\x20 + class C(builtins.object) + | Methods defined here: + |\x20\x20 + | get_answer(self) + | Return say_no() + |\x20\x20 + | is_it_true(self) + | Return self.get_answer() + |\x20\x20 + | say_no(self) + |\x20\x20 + | ---------------------------------------------------------------------- + | Data descriptors defined here: + |\x20\x20 + | __dict__ + | dictionary for instance variables (if defined) + |\x20\x20 + | __weakref__ + | list of weak references to the object (if defined) FUNCTIONS doc_func() @@ -123,6 +152,7 @@ class B(builtins.object)

A
B +
C
@@ -164,6 +194,28 @@ class B(builtins.object) Data and other attributes defined here:
NO_MEANING = 'eggs'
+

+ + + +\x20\x20\x20\x20 + +
 
+class C(builtins.object)
    Methods defined here:
+
get_answer(self)
Return say_no()
+ +
is_it_true(self)
Return self.get_answer()
+ +
say_no(self)
+ +
+Data descriptors defined here:
+
__dict__
+
dictionary for instance variables (if defined)
+
+
__weakref__
+
list of weak references to the object (if defined)
+

@@ -311,15 +363,6 @@ def get_pydoc_text(module): output = patt.sub('', output) return output.strip(), loc -def print_diffs(text1, text2): - "Prints unified diffs for two texts" - # XXX now obsolete, use unittest built-in support - lines1 = text1.splitlines(keepends=True) - lines2 = text2.splitlines(keepends=True) - diffs = difflib.unified_diff(lines1, lines2, n=0, fromfile='expected', - tofile='got') - print('\n' + ''.join(diffs)) - def get_html_title(text): # Bit of hack, but good enough for test purposes header, _, _ = text.partition("") @@ -357,40 +400,52 @@ class PydocDocTest(unittest.TestCase): "Docstrings are omitted with -O2 and above") @unittest.skipIf(hasattr(sys, 'gettrace') and sys.gettrace(), 'trace function introduces __locals__ unexpectedly') + @requires_docstrings def test_html_doc(self): result, doc_loc = get_pydoc_html(pydoc_mod) mod_file = inspect.getabsfile(pydoc_mod) - if sys.platform == 'win32': - import nturl2path - mod_url = nturl2path.pathname2url(mod_file) - else: - mod_url = mod_file + mod_url = urllib.parse.quote(mod_file) expected_html = expected_html_pattern % ( (mod_url, mod_file, doc_loc) + expected_html_data_docstrings) - if result != expected_html: - print_diffs(expected_html, result) - self.fail("outputs are not equal, see diff above") + self.assertEqual(result, expected_html) @unittest.skipIf(sys.flags.optimize >= 2, "Docstrings are omitted with -O2 and above") @unittest.skipIf(hasattr(sys, 'gettrace') and sys.gettrace(), 'trace function introduces __locals__ unexpectedly') + @requires_docstrings def test_text_doc(self): result, doc_loc = get_pydoc_text(pydoc_mod) expected_text = expected_text_pattern % ( (doc_loc,) + expected_text_data_docstrings + (inspect.getabsfile(pydoc_mod),)) - if result != expected_text: - print_diffs(expected_text, result) - self.fail("outputs are not equal, see diff above") + self.assertEqual(expected_text, result) + + def test_text_enum_member_with_value_zero(self): + # Test issue #20654 to ensure enum member with value 0 can be + # displayed. It used to throw KeyError: 'zero'. + import enum + class BinaryInteger(enum.IntEnum): + zero = 0 + one = 1 + doc = pydoc.render_doc(BinaryInteger) + self.assertIn('', doc) def test_issue8225(self): # Test issue8225 to ensure no doc link appears for xml.etree result, doc_loc = get_pydoc_text(xml.etree) self.assertEqual(doc_loc, "", "MODULE DOCS incorrectly includes a link") + def test_getpager_with_stdin_none(self): + previous_stdin = sys.stdin + try: + sys.stdin = None + pydoc.getpager() # Shouldn't fail. + finally: + sys.stdin = previous_stdin + def test_non_str_name(self): # issue14638 # Treat illegal (non-str) name like no name @@ -409,6 +464,11 @@ def test_not_here(self): self.assertEqual(expected, result, "documentation for missing module found") + def test_not_ascii(self): + result = run_pydoc('test.test_pydoc.nonascii', PYTHONIOENCODING='ascii') + encoded = nonascii.__doc__.encode('ascii', 'backslashreplace') + self.assertIn(encoded, result) + def test_input_strip(self): missing_module = " test.i_am_not_here " result = str(run_pydoc(missing_module), 'ascii') @@ -432,6 +492,7 @@ def test_stripid(self): 'Docstrings are omitted with -O2 and above') @unittest.skipIf(hasattr(sys, 'gettrace') and sys.gettrace(), 'trace function introduces __locals__ unexpectedly') + @requires_docstrings def test_help_output_redirect(self): # issue 940286, if output is set in Helper, then all output from # Helper.help should be redirected @@ -487,6 +548,25 @@ def test_synopsis(self): synopsis = pydoc.synopsis(TESTFN, {}) self.assertEqual(synopsis, 'line 1: h\xe9') + def test_synopsis_sourceless(self): + expected = os.__doc__.splitlines()[0] + filename = os.__cached__ + synopsis = pydoc.synopsis(filename) + + self.assertEqual(synopsis, expected) + + def test_synopsis_sourceless_empty_doc(self): + with test.support.temp_cwd() as test_dir: + init_path = os.path.join(test_dir, 'foomod42.py') + cached_path = importlib.util.cache_from_source(init_path) + with open(init_path, 'w') as fobj: + fobj.write("foo = 1") + py_compile.compile(init_path) + synopsis = pydoc.synopsis(init_path, {}) + self.assertIsNone(synopsis) + synopsis_cached = pydoc.synopsis(cached_path, {}) + self.assertIsNone(synopsis_cached) + def test_splitdoc_with_description(self): example_string = "I Am A Doc\n\n\nHere is my description" self.assertEqual(pydoc.splitdoc(example_string), @@ -542,6 +622,7 @@ class PydocImportTest(PydocBaseTest): def setUp(self): self.test_dir = os.mkdir(TESTFN) self.addCleanup(rmtree, TESTFN) + importlib.invalidate_caches() def test_badimport(self): # This tests the fix for issue 5230, where if pydoc found the module @@ -600,6 +681,71 @@ def test_apropos_with_unreadable_dir(self): self.assertEqual(out.getvalue(), '') self.assertEqual(err.getvalue(), '') + def test_apropos_empty_doc(self): + pkgdir = os.path.join(TESTFN, 'walkpkg') + os.mkdir(pkgdir) + self.addCleanup(rmtree, pkgdir) + init_path = os.path.join(pkgdir, '__init__.py') + with open(init_path, 'w') as fobj: + fobj.write("foo = 1") + current_mode = stat.S_IMODE(os.stat(pkgdir).st_mode) + try: + os.chmod(pkgdir, current_mode & ~stat.S_IEXEC) + with self.restrict_walk_packages(path=[TESTFN]), captured_stdout() as stdout: + pydoc.apropos('') + self.assertIn('walkpkg', stdout.getvalue()) + finally: + os.chmod(pkgdir, current_mode) + + @unittest.skip('causes undesireable side-effects (#20128)') + def test_modules(self): + # See Helper.listmodules(). + num_header_lines = 2 + num_module_lines_min = 5 # Playing it safe. + num_footer_lines = 3 + expected = num_header_lines + num_module_lines_min + num_footer_lines + + output = StringIO() + helper = pydoc.Helper(output=output) + helper('modules') + result = output.getvalue().strip() + num_lines = len(result.splitlines()) + + self.assertGreaterEqual(num_lines, expected) + + @unittest.skip('causes undesireable side-effects (#20128)') + def test_modules_search(self): + # See Helper.listmodules(). + expected = 'pydoc - ' + + output = StringIO() + helper = pydoc.Helper(output=output) + with captured_stdout() as help_io: + helper('modules pydoc') + result = help_io.getvalue() + + self.assertIn(expected, result) + + @unittest.skip('some buildbots are not cooperating (#20128)') + def test_modules_search_builtin(self): + expected = 'gc - ' + + output = StringIO() + helper = pydoc.Helper(output=output) + with captured_stdout() as help_io: + helper('modules garbage') + result = help_io.getvalue() + + self.assertTrue(result.startswith(expected)) + + def test_importfile(self): + loaded_pydoc = pydoc.importfile(pydoc.__file__) + + self.assertIsNot(loaded_pydoc, pydoc) + self.assertEqual(loaded_pydoc.__name__, 'pydoc') + self.assertEqual(loaded_pydoc.__file__, pydoc.__file__) + self.assertEqual(loaded_pydoc.__spec__, pydoc.__spec__) + class TestDescriptions(unittest.TestCase): @@ -627,7 +773,7 @@ def test_builtin(self): try: pydoc.render_doc(name) except ImportError: - self.fail('finding the doc of {!r} failed'.format(o)) + self.fail('finding the doc of {!r} failed'.format(name)) for name in ('notbuiltins', 'strrr', 'strr.translate', 'str.trrrranslate', 'builtins.strrr', @@ -635,6 +781,42 @@ def test_builtin(self): self.assertIsNone(pydoc.locate(name)) self.assertRaises(ImportError, pydoc.render_doc, name) + @staticmethod + def _get_summary_line(o): + text = pydoc.plain(pydoc.render_doc(o)) + lines = text.split('\n') + assert len(lines) >= 2 + return lines[2] + + # these should include "self" + def test_unbound_python_method(self): + self.assertEqual(self._get_summary_line(textwrap.TextWrapper.wrap), + "wrap(self, text)") + + @requires_docstrings + def test_unbound_builtin_method(self): + self.assertEqual(self._get_summary_line(_pickle.Pickler.dump), + "dump(self, obj, /)") + + # these no longer include "self" + def test_bound_python_method(self): + t = textwrap.TextWrapper() + self.assertEqual(self._get_summary_line(t.wrap), + "wrap(text) method of textwrap.TextWrapper instance") + + @requires_docstrings + def test_bound_builtin_method(self): + s = StringIO() + p = _pickle.Pickler(s) + self.assertEqual(self._get_summary_line(p.dump), + "dump(obj, /) method of _pickle.Pickler instance") + + # this should *never* include self! + @requires_docstrings + def test_module_level_callable(self): + self.assertEqual(self._get_summary_line(os.stat), + "stat(path, *, dir_fd=None, follow_symlinks=True)") + @unittest.skipUnless(threading, 'Threading required for this test.') class PydocServerTest(unittest.TestCase): @@ -648,6 +830,8 @@ def my_url_handler(url, content_type): return text serverthread = pydoc._start_server(my_url_handler, port=0) + self.assertIn('localhost', serverthread.docserver.address) + starttime = time.time() timeout = 1 #seconds @@ -729,9 +913,7 @@ def ham(self): expected_text = expected_dynamicattribute_pattern % ( (__name__,) + expected_text_data_docstrings[:2]) result = output.getvalue().strip() - if result != expected_text: - print_diffs(expected_text, result) - self.fail("outputs are not equal, see diff above") + self.assertEqual(expected_text, result) @unittest.skipIf(sys.flags.optimize >= 2, "Docstrings are omitted with -O2 and above") @@ -752,9 +934,7 @@ class Class(metaclass=Meta): helper(Class) expected_text = expected_virtualattribute_pattern1 % __name__ result = output.getvalue().strip() - if result != expected_text: - print_diffs(expected_text, result) - self.fail("outputs are not equal, see diff above") + self.assertEqual(expected_text, result) @unittest.skipIf(sys.flags.optimize >= 2, "Docstrings are omitted with -O2 and above") @@ -794,19 +974,13 @@ class Class2(Class1, metaclass=Meta3): helper(Class1) expected_text1 = expected_virtualattribute_pattern2 % __name__ result1 = output.getvalue().strip() - if result1 != expected_text1: - print_diffs(expected_text1, result1) - fail1 = True + self.assertEqual(expected_text1, result1) output = StringIO() helper = pydoc.Helper(output=output) helper(Class2) expected_text2 = expected_virtualattribute_pattern3 % __name__ result2 = output.getvalue().strip() - if result2 != expected_text2: - print_diffs(expected_text2, result2) - fail2 = True - if fail1 or fail2: - self.fail("outputs are not equal, see diff above") + self.assertEqual(expected_text2, result2) @unittest.skipIf(sys.flags.optimize >= 2, "Docstrings are omitted with -O2 and above") @@ -823,9 +997,8 @@ class C(metaclass=M): helper(C) expected_text = expected_missingattribute_pattern % __name__ result = output.getvalue().strip() - if result != expected_text: - print_diffs(expected_text, result) - self.fail("outputs are not equal, see diff above") + self.assertEqual(expected_text, result) + @reap_threads def test_main(): diff --git a/Lib/test/test_pyexpat.py b/Lib/test/test_pyexpat.py index 8ef391791f71..c233bc11e315 100644 --- a/Lib/test/test_pyexpat.py +++ b/Lib/test/test_pyexpat.py @@ -2,7 +2,10 @@ # handler, are obscure and unhelpful. from io import BytesIO +import os +import sysconfig import unittest +import traceback from xml.parsers import expat from xml.parsers.expat import errors @@ -236,6 +239,18 @@ def test_parse_file(self): operations = out.out self._verify_parse_output(operations) + def test_parse_again(self): + parser = expat.ParserCreate() + file = BytesIO(data) + parser.ParseFile(file) + # Issue 6676: ensure a meaningful exception is raised when attempting + # to parse more than one XML document per xmlparser instance, + # a limitation of the Expat library. + with self.assertRaises(expat.error) as cm: + parser.ParseFile(file) + self.assertEqual(expat.ErrorString(cm.exception.code), + expat.errors.XML_ERROR_FINISHED) + class NamespaceSeparatorTest(unittest.TestCase): def test_legal(self): # Tests that make sure we get errors when the namespace_separator value @@ -407,7 +422,11 @@ class HandlerExceptionTest(unittest.TestCase): def StartElementHandler(self, name, attrs): raise RuntimeError(name) - def test(self): + def check_traceback_entry(self, entry, filename, funcname): + self.assertEqual(os.path.basename(entry[0]), filename) + self.assertEqual(entry[2], funcname) + + def test_exception(self): parser = expat.ParserCreate() parser.StartElementHandler = self.StartElementHandler try: @@ -417,6 +436,17 @@ def test(self): self.assertEqual(e.args[0], 'a', "Expected RuntimeError for element 'a', but" + \ " found %r" % e.args[0]) + # Check that the traceback contains the relevant line in pyexpat.c + entries = traceback.extract_tb(e.__traceback__) + self.assertEqual(len(entries), 3) + self.check_traceback_entry(entries[0], + "test_pyexpat.py", "test_exception") + self.check_traceback_entry(entries[1], + "pyexpat.c", "StartElement") + self.check_traceback_entry(entries[2], + "test_pyexpat.py", "StartElementHandler") + if sysconfig.is_python_build(): + self.assertIn('call_with_frame("StartElement"', entries[1][3]) # Test Current* members: diff --git a/Lib/test/test_random.py b/Lib/test/test_random.py index 7d1a53a55073..e64804556db8 100644 --- a/Lib/test/test_random.py +++ b/Lib/test/test_random.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - import unittest import unittest.mock import random @@ -161,11 +159,12 @@ def test_gauss(self): self.assertEqual(y1, y2) def test_pickling(self): - state = pickle.dumps(self.gen) - origseq = [self.gen.random() for i in range(10)] - newgen = pickle.loads(state) - restoredseq = [newgen.random() for i in range(10)] - self.assertEqual(origseq, restoredseq) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + state = pickle.dumps(self.gen, proto) + origseq = [self.gen.random() for i in range(10)] + newgen = pickle.loads(state) + restoredseq = [newgen.random() for i in range(10)] + self.assertEqual(origseq, restoredseq) def test_bug_1727780(self): # verify that version-2-pickles can be loaded @@ -217,7 +216,8 @@ def test_gauss(self): self.assertEqual(self.gen.gauss_next, None) def test_pickling(self): - self.assertRaises(NotImplementedError, pickle.dumps, self.gen) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.assertRaises(NotImplementedError, pickle.dumps, self.gen, proto) def test_53_bits_per_float(self): # This should pass whenever a C double has 53 bit precision. @@ -604,7 +604,7 @@ def test_constant(self): for variate, args, expected in [ (g.uniform, (10.0, 10.0), 10.0), (g.triangular, (10.0, 10.0), 10.0), - #(g.triangular, (10.0, 10.0, 10.0), 10.0), + (g.triangular, (10.0, 10.0, 10.0), 10.0), (g.expovariate, (float('inf'),), 0.0), (g.vonmisesvariate, (3.0, float('inf')), 3.0), (g.gauss, (10.0, 0.0), 10.0), diff --git a/Lib/test/test_range.py b/Lib/test/test_range.py index d9d4cf88a201..2dbcebcc049d 100644 --- a/Lib/test/test_range.py +++ b/Lib/test/test_range.py @@ -366,7 +366,7 @@ def test_iterator_pickling(self): it = itorg = iter(range(*t)) data = list(range(*t)) - d = pickle.dumps(it) + d = pickle.dumps(it, proto) it = pickle.loads(d) self.assertEqual(type(itorg), type(it)) self.assertEqual(list(it), data) @@ -376,10 +376,36 @@ def test_iterator_pickling(self): next(it) except StopIteration: continue - d = pickle.dumps(it) + d = pickle.dumps(it, proto) it = pickle.loads(d) self.assertEqual(list(it), data[1:]) + def test_exhausted_iterator_pickling(self): + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + r = range(2**65, 2**65+2) + i = iter(r) + while True: + r = next(i) + if r == 2**65+1: + break + d = pickle.dumps(i, proto) + i2 = pickle.loads(d) + self.assertEqual(list(i), []) + self.assertEqual(list(i2), []) + + def test_large_exhausted_iterator_pickling(self): + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + r = range(20) + i = iter(r) + while True: + r = next(i) + if r == 19: + break + d = pickle.dumps(i, proto) + i2 = pickle.loads(d) + self.assertEqual(list(i), []) + self.assertEqual(list(i2), []) + def test_odd_bug(self): # This used to raise a "SystemError: NULL result without error" # because the range validation step was eating the exception diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index a4e11c6746cc..0fbf8c5a2379 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -1,6 +1,7 @@ from test.support import verbose, run_unittest, gc_collect, bigmemtest, _2G, \ - cpython_only + cpython_only, captured_stdout import io +import locale import re from re import Scanner import sre_compile @@ -59,12 +60,12 @@ def test_search_star_plus(self): self.assertEqual(re.search('x*', 'axx').span(), (0, 0)) self.assertEqual(re.search('x+', 'axx').span(0), (1, 3)) self.assertEqual(re.search('x+', 'axx').span(), (1, 3)) - self.assertEqual(re.search('x', 'aaa'), None) + self.assertIsNone(re.search('x', 'aaa')) self.assertEqual(re.match('a*', 'xxx').span(0), (0, 0)) self.assertEqual(re.match('a*', 'xxx').span(), (0, 0)) self.assertEqual(re.match('x*', 'xxxa').span(0), (0, 3)) self.assertEqual(re.match('x*', 'xxxa').span(), (0, 3)) - self.assertEqual(re.match('a+', 'xxx'), None) + self.assertIsNone(re.match('a+', 'xxx')) def bump_num(self, matchobj): int_value = int(matchobj.group(0)) @@ -83,7 +84,7 @@ def test_basic_re_sub(self): self.assertEqual(re.sub("(?i)b+", "x", "bbbb BBBB"), 'x x') self.assertEqual(re.sub(r'\d+', self.bump_num, '08.2 -2 23x99y'), '9.3 -3 24x100y') - self.assertEqual(re.sub(r'\d+', self.bump_num, '08.2 -2 23x99y', 3), + self.assertEqual(re.sub(r'\d+', self.bump_num, '08.2 -2 23x99y', count=3), '9.3 -3 23x99y') self.assertEqual(re.sub('.', lambda m: r"\n", 'x'), '\\n') @@ -154,8 +155,8 @@ def test_sub_template_numeric_escape(self): self.assertEqual(re.sub('x', r'\09', 'x'), '\0' + '9') self.assertEqual(re.sub('x', r'\0a', 'x'), '\0' + 'a') - self.assertEqual(re.sub('x', r'\400', 'x'), '\0') - self.assertEqual(re.sub('x', r'\777', 'x'), '\377') + self.assertRaises(re.error, re.sub, 'x', r'\400', 'x') + self.assertRaises(re.error, re.sub, 'x', r'\777', 'x') self.assertRaises(re.error, re.sub, 'x', r'\1', 'x') self.assertRaises(re.error, re.sub, 'x', r'\8', 'x') @@ -179,7 +180,7 @@ def test_sub_template_numeric_escape(self): def test_qualified_re_sub(self): self.assertEqual(re.sub('a', 'b', 'aaaaa'), 'bbbbb') - self.assertEqual(re.sub('a', 'b', 'aaaaa', 1), 'baaaa') + self.assertEqual(re.sub('a', 'b', 'aaaaa', count=1), 'baaaa') def test_bug_114660(self): self.assertEqual(re.sub(r'(\S)\s+(\S)', r'\1 \2', 'hello there'), @@ -193,6 +194,7 @@ def test_bug_462270(self): def test_symbolic_groups(self): re.compile('(?Px)(?P=a)(?(a)y)') re.compile('(?Px)(?P=a1)(?(a1)y)') + re.compile('(?Px)\1(?(1)y)') self.assertRaises(re.error, re.compile, '(?P)(?P)') self.assertRaises(re.error, re.compile, '(?Px)') self.assertRaises(re.error, re.compile, '(?P=)') @@ -212,6 +214,10 @@ def test_symbolic_groups(self): re.compile('(?P<µ>x)(?P=µ)(?(µ)y)') re.compile('(?P<ð”˜ð”«ð”¦ð” ð”¬ð”¡ð”¢>x)(?P=ð”˜ð”«ð”¦ð” ð”¬ð”¡ð”¢)(?(ð”˜ð”«ð”¦ð” ð”¬ð”¡ð”¢)y)') self.assertRaises(re.error, re.compile, '(?P<©>x)') + # Support > 100 groups. + pat = '|'.join('x(?P%x)y' % (i, i) for i in range(1, 200 + 1)) + pat = '(?:%s)(?(200)z|t)' % pat + self.assertEqual(re.match(pat, 'xc8yz').span(), (0, 5)) def test_symbolic_refs(self): self.assertRaises(re.error, re.sub, '(?Px)', '\gx)', '\g', 'xx') self.assertRaises(re.error, re.sub, '(?Px)', '\g<>', 'xx') self.assertRaises(re.error, re.sub, '(?Px)', '\g<1a1>', 'xx') + self.assertRaises(re.error, re.sub, '(?Px)', r'\g<2>', 'xx') + self.assertRaises(re.error, re.sub, '(?Px)', r'\2', 'xx') self.assertRaises(IndexError, re.sub, '(?Px)', '\g', 'xx') - self.assertRaises(re.error, re.sub, '(?Px)|(?Py)', '\g', 'xx') - self.assertRaises(re.error, re.sub, '(?Px)|(?Py)', '\\2', 'xx') + self.assertEqual(re.sub('(?Px)|(?Py)', r'\g', 'xx'), '') + self.assertEqual(re.sub('(?Px)|(?Py)', r'\2', 'xx'), '') self.assertRaises(re.error, re.sub, '(?Px)', '\g<-1>', 'xx') # New valid/invalid identifiers in Python 3 self.assertEqual(re.sub('(?P<µ>x)', r'\g<µ>', 'xx'), 'xx') self.assertEqual(re.sub('(?P<ð”˜ð”«ð”¦ð” ð”¬ð”¡ð”¢>x)', r'\g<ð”˜ð”«ð”¦ð” ð”¬ð”¡ð”¢>', 'xx'), 'xx') self.assertRaises(re.error, re.sub, '(?Px)', r'\g<©>', 'xx') + # Support > 100 groups. + pat = '|'.join('x(?P%x)y' % (i, i) for i in range(1, 200 + 1)) + self.assertEqual(re.sub(pat, '\g<200>', 'xc8yzxc8y'), 'c8zc8') def test_re_subn(self): self.assertEqual(re.subn("(?i)b+", "x", "bbbb BBBB"), ('x x', 2)) self.assertEqual(re.subn("b+", "x", "bbbb BBBB"), ('x BBBB', 1)) self.assertEqual(re.subn("b+", "x", "xyz"), ('xyz', 0)) self.assertEqual(re.subn("b*", "x", "xyz"), ('xxxyxzx', 4)) - self.assertEqual(re.subn("b*", "x", "xyz", 2), ('xxxyz', 2)) + self.assertEqual(re.subn("b*", "x", "xyz", count=2), ('xxxyz', 2)) def test_re_split(self): for string in ":a:b::c", S(":a:b::c"): self.assertTypedEqual(re.split(":", string), ['', 'a', 'b', '', 'c']) - self.assertTypedEqual(re.split(":*", string), + self.assertTypedEqual(re.split(":+", string), ['', 'a', 'b', 'c']) - self.assertTypedEqual(re.split("(:*)", string), + self.assertTypedEqual(re.split("(:+)", string), ['', ':', 'a', ':', 'b', '::', 'c']) for string in (b":a:b::c", B(b":a:b::c"), bytearray(b":a:b::c"), memoryview(b":a:b::c")): self.assertTypedEqual(re.split(b":", string), [b'', b'a', b'b', b'', b'c']) - self.assertTypedEqual(re.split(b":*", string), + self.assertTypedEqual(re.split(b":+", string), [b'', b'a', b'b', b'c']) - self.assertTypedEqual(re.split(b"(:*)", string), + self.assertTypedEqual(re.split(b"(:+)", string), [b'', b':', b'a', b':', b'b', b'::', b'c']) for a, b, c in ("\xe0\xdf\xe7", "\u0430\u0431\u0432", "\U0001d49c\U0001d49e\U0001d4b5"): string = ":%s:%s::%s" % (a, b, c) self.assertEqual(re.split(":", string), ['', a, b, '', c]) - self.assertEqual(re.split(":*", string), ['', a, b, c]) - self.assertEqual(re.split("(:*)", string), + self.assertEqual(re.split(":+", string), ['', a, b, c]) + self.assertEqual(re.split("(:+)", string), ['', ':', a, ':', b, '::', c]) - self.assertEqual(re.split("(?::*)", ":a:b::c"), ['', 'a', 'b', 'c']) - self.assertEqual(re.split("(:)*", ":a:b::c"), + self.assertEqual(re.split("(?::+)", ":a:b::c"), ['', 'a', 'b', 'c']) + self.assertEqual(re.split("(:)+", ":a:b::c"), ['', ':', 'a', ':', 'b', ':', 'c']) self.assertEqual(re.split("([b:]+)", ":a:b::c"), ['', ':', 'a', ':b::', 'c']) @@ -271,13 +282,34 @@ def test_re_split(self): self.assertEqual(re.split("(?:b)|(?::+)", ":a:b::c"), ['', 'a', '', '', 'c']) + for sep, expected in [ + (':*', ['', 'a', 'b', 'c']), + ('(?::*)', ['', 'a', 'b', 'c']), + ('(:*)', ['', ':', 'a', ':', 'b', '::', 'c']), + ('(:)*', ['', ':', 'a', ':', 'b', ':', 'c']), + ]: + with self.subTest(sep=sep), self.assertWarns(FutureWarning): + self.assertTypedEqual(re.split(sep, ':a:b::c'), expected) + + for sep, expected in [ + ('', [':a:b::c']), + (r'\b', [':a:b::c']), + (r'(?=:)', [':a:b::c']), + (r'(?<=:)', [':a:b::c']), + ]: + with self.subTest(sep=sep), self.assertRaises(ValueError): + self.assertTypedEqual(re.split(sep, ':a:b::c'), expected) + def test_qualified_re_split(self): - self.assertEqual(re.split(":", ":a:b::c", 2), ['', 'a', 'b::c']) - self.assertEqual(re.split(':', 'a:b:c:d', 2), ['a', 'b', 'c:d']) - self.assertEqual(re.split("(:)", ":a:b::c", 2), + self.assertEqual(re.split(":", ":a:b::c", maxsplit=2), ['', 'a', 'b::c']) + self.assertEqual(re.split(':', 'a:b:c:d', maxsplit=2), ['a', 'b', 'c:d']) + self.assertEqual(re.split("(:)", ":a:b::c", maxsplit=2), ['', ':', 'a', ':', 'b::c']) - self.assertEqual(re.split("(:*)", ":a:b::c", 2), + self.assertEqual(re.split("(:+)", ":a:b::c", maxsplit=2), ['', ':', 'a', ':', 'b::c']) + with self.assertWarns(FutureWarning): + self.assertEqual(re.split("(:*)", ":a:b::c", maxsplit=2), + ['', ':', 'a', ':', 'b::c']) def test_re_findall(self): self.assertEqual(re.findall(":+", "abc"), []) @@ -384,8 +416,8 @@ def test_re_groupref_exists(self): ('(', 'a')) self.assertEqual(re.match('^(\()?([^()]+)(?(1)\))$', 'a').groups(), (None, 'a')) - self.assertEqual(re.match('^(\()?([^()]+)(?(1)\))$', 'a)'), None) - self.assertEqual(re.match('^(\()?([^()]+)(?(1)\))$', '(a'), None) + self.assertIsNone(re.match('^(\()?([^()]+)(?(1)\))$', 'a)')) + self.assertIsNone(re.match('^(\()?([^()]+)(?(1)\))$', '(a')) self.assertEqual(re.match('^(?:(a)|c)((?(1)b|d))$', 'ab').groups(), ('a', 'b')) self.assertEqual(re.match('^(?:(a)|c)((?(1)b|d))$', 'cd').groups(), @@ -401,17 +433,21 @@ def test_re_groupref_exists(self): ('a', 'b', 'c')) self.assertEqual(p.match('ad').groups(), ('a', None, 'd')) - self.assertEqual(p.match('abd'), None) - self.assertEqual(p.match('ac'), None) + self.assertIsNone(p.match('abd')) + self.assertIsNone(p.match('ac')) + # Support > 100 groups. + pat = '|'.join('x(?P%x)y' % (i, i) for i in range(1, 200 + 1)) + pat = '(?:%s)(?(200)z)' % pat + self.assertEqual(re.match(pat, 'xc8yz').span(), (0, 5)) def test_re_groupref(self): self.assertEqual(re.match(r'^(\|)?([^()]+)\1$', '|a|').groups(), ('|', 'a')) self.assertEqual(re.match(r'^(\|)?([^()]+)\1?$', 'a').groups(), (None, 'a')) - self.assertEqual(re.match(r'^(\|)?([^()]+)\1$', 'a|'), None) - self.assertEqual(re.match(r'^(\|)?([^()]+)\1$', '|a'), None) + self.assertIsNone(re.match(r'^(\|)?([^()]+)\1$', 'a|')) + self.assertIsNone(re.match(r'^(\|)?([^()]+)\1$', '|a')) self.assertEqual(re.match(r'^(?:(a)|c)(\1)$', 'aa').groups(), ('a', 'a')) self.assertEqual(re.match(r'^(?:(a)|c)(\1)?$', 'c').groups(), @@ -427,12 +463,16 @@ def test_expand(self): "first second") .expand(r"\2 \1 \g \g"), "second first second first") + self.assertEqual(re.match("(?Pfirst)|(?Psecond)", + "first") + .expand(r"\2 \g"), + " ") def test_repeat_minmax(self): - self.assertEqual(re.match("^(\w){1}$", "abc"), None) - self.assertEqual(re.match("^(\w){1}?$", "abc"), None) - self.assertEqual(re.match("^(\w){1,2}$", "abc"), None) - self.assertEqual(re.match("^(\w){1,2}?$", "abc"), None) + self.assertIsNone(re.match("^(\w){1}$", "abc")) + self.assertIsNone(re.match("^(\w){1}?$", "abc")) + self.assertIsNone(re.match("^(\w){1,2}$", "abc")) + self.assertIsNone(re.match("^(\w){1,2}?$", "abc")) self.assertEqual(re.match("^(\w){3}$", "abc").group(1), "c") self.assertEqual(re.match("^(\w){1,3}$", "abc").group(1), "c") @@ -443,22 +483,22 @@ def test_repeat_minmax(self): self.assertEqual(re.match("^(\w){1,4}?$", "abc").group(1), "c") self.assertEqual(re.match("^(\w){3,4}?$", "abc").group(1), "c") - self.assertEqual(re.match("^x{1}$", "xxx"), None) - self.assertEqual(re.match("^x{1}?$", "xxx"), None) - self.assertEqual(re.match("^x{1,2}$", "xxx"), None) - self.assertEqual(re.match("^x{1,2}?$", "xxx"), None) + self.assertIsNone(re.match("^x{1}$", "xxx")) + self.assertIsNone(re.match("^x{1}?$", "xxx")) + self.assertIsNone(re.match("^x{1,2}$", "xxx")) + self.assertIsNone(re.match("^x{1,2}?$", "xxx")) - self.assertNotEqual(re.match("^x{3}$", "xxx"), None) - self.assertNotEqual(re.match("^x{1,3}$", "xxx"), None) - self.assertNotEqual(re.match("^x{1,4}$", "xxx"), None) - self.assertNotEqual(re.match("^x{3,4}?$", "xxx"), None) - self.assertNotEqual(re.match("^x{3}?$", "xxx"), None) - self.assertNotEqual(re.match("^x{1,3}?$", "xxx"), None) - self.assertNotEqual(re.match("^x{1,4}?$", "xxx"), None) - self.assertNotEqual(re.match("^x{3,4}?$", "xxx"), None) + self.assertTrue(re.match("^x{3}$", "xxx")) + self.assertTrue(re.match("^x{1,3}$", "xxx")) + self.assertTrue(re.match("^x{1,4}$", "xxx")) + self.assertTrue(re.match("^x{3,4}?$", "xxx")) + self.assertTrue(re.match("^x{3}?$", "xxx")) + self.assertTrue(re.match("^x{1,3}?$", "xxx")) + self.assertTrue(re.match("^x{1,4}?$", "xxx")) + self.assertTrue(re.match("^x{3,4}?$", "xxx")) - self.assertEqual(re.match("^x{}$", "xxx"), None) - self.assertNotEqual(re.match("^x{}$", "x{}"), None) + self.assertIsNone(re.match("^x{}$", "xxx")) + self.assertTrue(re.match("^x{}$", "x{}")) def test_getattr(self): self.assertEqual(re.compile("(?i)(a)(b)").pattern, "(?i)(a)(b)") @@ -472,7 +512,7 @@ def test_getattr(self): self.assertEqual(re.match("(a)", "a").endpos, 1) self.assertEqual(re.match("(a)", "a").string, "a") self.assertEqual(re.match("(a)", "a").regs, ((0, 1), (0, 1))) - self.assertNotEqual(re.match("(a)", "a").re, None) + self.assertTrue(re.match("(a)", "a").re) def test_special_escapes(self): self.assertEqual(re.search(r"\b(b.)\b", @@ -480,29 +520,45 @@ def test_special_escapes(self): self.assertEqual(re.search(r"\B(b.)\B", "abc bcd bc abxd").group(1), "bx") self.assertEqual(re.search(r"\b(b.)\b", - "abcd abc bcd bx", re.LOCALE).group(1), "bx") - self.assertEqual(re.search(r"\B(b.)\B", - "abc bcd bc abxd", re.LOCALE).group(1), "bx") - self.assertEqual(re.search(r"\b(b.)\b", - "abcd abc bcd bx", re.UNICODE).group(1), "bx") - self.assertEqual(re.search(r"\B(b.)\B", - "abc bcd bc abxd", re.UNICODE).group(1), "bx") - self.assertEqual(re.search(r"^abc$", "\nabc\n", re.M).group(0), "abc") - self.assertEqual(re.search(r"^\Aabc\Z$", "abc", re.M).group(0), "abc") - self.assertEqual(re.search(r"^\Aabc\Z$", "\nabc\n", re.M), None) - self.assertEqual(re.search(r"\b(b.)\b", - "abcd abc bcd bx").group(1), "bx") + "abcd abc bcd bx", re.ASCII).group(1), "bx") self.assertEqual(re.search(r"\B(b.)\B", - "abc bcd bc abxd").group(1), "bx") + "abc bcd bc abxd", re.ASCII).group(1), "bx") self.assertEqual(re.search(r"^abc$", "\nabc\n", re.M).group(0), "abc") self.assertEqual(re.search(r"^\Aabc\Z$", "abc", re.M).group(0), "abc") - self.assertEqual(re.search(r"^\Aabc\Z$", "\nabc\n", re.M), None) + self.assertIsNone(re.search(r"^\Aabc\Z$", "\nabc\n", re.M)) + self.assertEqual(re.search(br"\b(b.)\b", + b"abcd abc bcd bx").group(1), b"bx") + self.assertEqual(re.search(br"\B(b.)\B", + b"abc bcd bc abxd").group(1), b"bx") + self.assertEqual(re.search(br"\b(b.)\b", + b"abcd abc bcd bx", re.LOCALE).group(1), b"bx") + self.assertEqual(re.search(br"\B(b.)\B", + b"abc bcd bc abxd", re.LOCALE).group(1), b"bx") + self.assertEqual(re.search(br"^abc$", b"\nabc\n", re.M).group(0), b"abc") + self.assertEqual(re.search(br"^\Aabc\Z$", b"abc", re.M).group(0), b"abc") + self.assertIsNone(re.search(br"^\Aabc\Z$", b"\nabc\n", re.M)) self.assertEqual(re.search(r"\d\D\w\W\s\S", "1aa! a").group(0), "1aa! a") + self.assertEqual(re.search(br"\d\D\w\W\s\S", + b"1aa! a").group(0), b"1aa! a") self.assertEqual(re.search(r"\d\D\w\W\s\S", - "1aa! a", re.LOCALE).group(0), "1aa! a") - self.assertEqual(re.search(r"\d\D\w\W\s\S", - "1aa! a", re.UNICODE).group(0), "1aa! a") + "1aa! a", re.ASCII).group(0), "1aa! a") + self.assertEqual(re.search(br"\d\D\w\W\s\S", + b"1aa! a", re.LOCALE).group(0), b"1aa! a") + + def test_other_escapes(self): + self.assertRaises(re.error, re.compile, "\\") + self.assertEqual(re.match(r"\(", '(').group(), '(') + self.assertIsNone(re.match(r"\(", ')')) + self.assertEqual(re.match(r"\\", '\\').group(), '\\') + self.assertEqual(re.match(r"\y", 'y').group(), 'y') + self.assertIsNone(re.match(r"\y", 'z')) + self.assertEqual(re.match(r"[\]]", ']').group(), ']') + self.assertIsNone(re.match(r"[\]]", '[')) + self.assertEqual(re.match(r"[a\-c]", '-').group(), '-') + self.assertIsNone(re.match(r"[a\-c]", 'b')) + self.assertEqual(re.match(r"[\^a]+", 'a^').group(), 'a^') + self.assertIsNone(re.match(r"[\^a]+", 'b')) def test_string_boundaries(self): # See http://bugs.python.org/issue10713 @@ -516,10 +572,10 @@ def test_string_boundaries(self): self.assertFalse(re.match(r"\B", "abc")) # However, an empty string contains no word boundaries, and also no # non-boundaries. - self.assertEqual(re.search(r"\B", ""), None) + self.assertIsNone(re.search(r"\B", "")) # This one is questionable and different from the perlre behaviour, # but describes current behavior. - self.assertEqual(re.search(r"\b", ""), None) + self.assertIsNone(re.search(r"\b", "")) # A single word-character string has two boundaries, but no # non-boundary gaps. self.assertEqual(len(re.findall(r"\b", "a")), 2) @@ -533,17 +589,14 @@ def test_string_boundaries(self): def test_bigcharset(self): self.assertEqual(re.match("([\u2222\u2223])", "\u2222").group(1), "\u2222") - self.assertEqual(re.match("([\u2222\u2223])", - "\u2222", re.UNICODE).group(1), "\u2222") r = '[%s]' % ''.join(map(chr, range(256, 2**16, 255))) - self.assertEqual(re.match(r, - "\uff01", re.UNICODE).group(), "\uff01") + self.assertEqual(re.match(r, "\uff01").group(), "\uff01") def test_big_codesize(self): # Issue #1160 r = re.compile('|'.join(('%d'%x for x in range(10000)))) - self.assertIsNotNone(r.match('1000')) - self.assertIsNotNone(r.match('9999')) + self.assertTrue(r.match('1000')) + self.assertTrue(r.match('9999')) def test_anyall(self): self.assertEqual(re.match("a.b", "a\nb", re.DOTALL).group(0), @@ -551,7 +604,7 @@ def test_anyall(self): self.assertEqual(re.match("a.*b", "a\n\nb", re.DOTALL).group(0), "a\n\nb") - def test_non_consuming(self): + def test_lookahead(self): self.assertEqual(re.match("(a(?=\s[^a]))", "a b").group(1), "a") self.assertEqual(re.match("(a(?=\s[^a]*))", "a b").group(1), "a") self.assertEqual(re.match("(a(?=\s[abc]))", "a b").group(1), "a") @@ -565,9 +618,49 @@ def test_non_consuming(self): self.assertEqual(re.match(r"(a)(?!\s\1)", "a b").group(1), "a") self.assertEqual(re.match(r"(a)(?!\s(abc|a))", "a b").group(1), "a") + # Group reference. + self.assertTrue(re.match(r'(a)b(?=\1)a', 'aba')) + self.assertIsNone(re.match(r'(a)b(?=\1)c', 'abac')) + # Conditional group reference. + self.assertTrue(re.match(r'(?:(a)|(x))b(?=(?(2)x|c))c', 'abc')) + self.assertIsNone(re.match(r'(?:(a)|(x))b(?=(?(2)c|x))c', 'abc')) + self.assertTrue(re.match(r'(?:(a)|(x))b(?=(?(2)x|c))c', 'abc')) + self.assertIsNone(re.match(r'(?:(a)|(x))b(?=(?(1)b|x))c', 'abc')) + self.assertTrue(re.match(r'(?:(a)|(x))b(?=(?(1)c|x))c', 'abc')) + # Group used before defined. + self.assertTrue(re.match(r'(a)b(?=(?(2)x|c))(c)', 'abc')) + self.assertIsNone(re.match(r'(a)b(?=(?(2)b|x))(c)', 'abc')) + self.assertTrue(re.match(r'(a)b(?=(?(1)c|x))(c)', 'abc')) + + def test_lookbehind(self): + self.assertTrue(re.match(r'ab(?<=b)c', 'abc')) + self.assertIsNone(re.match(r'ab(?<=c)c', 'abc')) + self.assertIsNone(re.match(r'ab(?.)(?P=a))(c)') + self.assertRaises(re.error, re.compile, r'(a)b(?<=(a)(?(2)b|x))(c)') + self.assertRaises(re.error, re.compile, r'(a)b(?<=(.)(?<=\2))(c)') + def test_ignore_case(self): self.assertEqual(re.match("abc", "ABC", re.I).group(0), "ABC") - self.assertEqual(re.match("abc", "ABC", re.I).group(0), "ABC") + self.assertEqual(re.match(b"abc", b"ABC", re.I).group(0), b"ABC") self.assertEqual(re.match(r"(a\s[^a])", "a b", re.I).group(1), "a b") self.assertEqual(re.match(r"(a\s[^a]*)", "a bb", re.I).group(1), "a bb") self.assertEqual(re.match(r"(a\s[abc])", "a b", re.I).group(1), "a b") @@ -577,6 +670,76 @@ def test_ignore_case(self): self.assertEqual(re.match(r"((a)\s(abc|a))", "a a", re.I).group(1), "a a") self.assertEqual(re.match(r"((a)\s(abc|a)*)", "a aa", re.I).group(1), "a aa") + assert '\u212a'.lower() == 'k' # 'K' + self.assertTrue(re.match(r'K', '\u212a', re.I)) + self.assertTrue(re.match(r'k', '\u212a', re.I)) + self.assertTrue(re.match(r'\u212a', 'K', re.I)) + self.assertTrue(re.match(r'\u212a', 'k', re.I)) + assert '\u017f'.upper() == 'S' # 'Å¿' + self.assertTrue(re.match(r'S', '\u017f', re.I)) + self.assertTrue(re.match(r's', '\u017f', re.I)) + self.assertTrue(re.match(r'\u017f', 'S', re.I)) + self.assertTrue(re.match(r'\u017f', 's', re.I)) + assert '\ufb05'.upper() == '\ufb06'.upper() == 'ST' # 'ſt', 'st' + self.assertTrue(re.match(r'\ufb05', '\ufb06', re.I)) + self.assertTrue(re.match(r'\ufb06', '\ufb05', re.I)) + + def test_ignore_case_set(self): + self.assertTrue(re.match(r'[19A]', 'A', re.I)) + self.assertTrue(re.match(r'[19a]', 'a', re.I)) + self.assertTrue(re.match(r'[19a]', 'A', re.I)) + self.assertTrue(re.match(r'[19A]', 'a', re.I)) + self.assertTrue(re.match(br'[19A]', b'A', re.I)) + self.assertTrue(re.match(br'[19a]', b'a', re.I)) + self.assertTrue(re.match(br'[19a]', b'A', re.I)) + self.assertTrue(re.match(br'[19A]', b'a', re.I)) + assert '\u212a'.lower() == 'k' # 'K' + self.assertTrue(re.match(r'[19K]', '\u212a', re.I)) + self.assertTrue(re.match(r'[19k]', '\u212a', re.I)) + self.assertTrue(re.match(r'[19\u212a]', 'K', re.I)) + self.assertTrue(re.match(r'[19\u212a]', 'k', re.I)) + assert '\u017f'.upper() == 'S' # 'Å¿' + self.assertTrue(re.match(r'[19S]', '\u017f', re.I)) + self.assertTrue(re.match(r'[19s]', '\u017f', re.I)) + self.assertTrue(re.match(r'[19\u017f]', 'S', re.I)) + self.assertTrue(re.match(r'[19\u017f]', 's', re.I)) + assert '\ufb05'.upper() == '\ufb06'.upper() == 'ST' # 'ſt', 'st' + self.assertTrue(re.match(r'[19\ufb05]', '\ufb06', re.I)) + self.assertTrue(re.match(r'[19\ufb06]', '\ufb05', re.I)) + + def test_ignore_case_range(self): + # Issues #3511, #17381. + self.assertTrue(re.match(r'[9-a]', '_', re.I)) + self.assertIsNone(re.match(r'[9-A]', '_', re.I)) + self.assertTrue(re.match(br'[9-a]', b'_', re.I)) + self.assertIsNone(re.match(br'[9-A]', b'_', re.I)) + self.assertTrue(re.match(r'[\xc0-\xde]', '\xd7', re.I)) + self.assertIsNone(re.match(r'[\xc0-\xde]', '\xf7', re.I)) + self.assertTrue(re.match(r'[\xe0-\xfe]', '\xf7', re.I)) + self.assertIsNone(re.match(r'[\xe0-\xfe]', '\xd7', re.I)) + self.assertTrue(re.match(r'[\u0430-\u045f]', '\u0450', re.I)) + self.assertTrue(re.match(r'[\u0430-\u045f]', '\u0400', re.I)) + self.assertTrue(re.match(r'[\u0400-\u042f]', '\u0450', re.I)) + self.assertTrue(re.match(r'[\u0400-\u042f]', '\u0400', re.I)) + self.assertTrue(re.match(r'[\U00010428-\U0001044f]', '\U00010428', re.I)) + self.assertTrue(re.match(r'[\U00010428-\U0001044f]', '\U00010400', re.I)) + self.assertTrue(re.match(r'[\U00010400-\U00010427]', '\U00010428', re.I)) + self.assertTrue(re.match(r'[\U00010400-\U00010427]', '\U00010400', re.I)) + + assert '\u212a'.lower() == 'k' # 'K' + self.assertTrue(re.match(r'[J-M]', '\u212a', re.I)) + self.assertTrue(re.match(r'[j-m]', '\u212a', re.I)) + self.assertTrue(re.match(r'[\u2129-\u212b]', 'K', re.I)) + self.assertTrue(re.match(r'[\u2129-\u212b]', 'k', re.I)) + assert '\u017f'.upper() == 'S' # 'Å¿' + self.assertTrue(re.match(r'[R-T]', '\u017f', re.I)) + self.assertTrue(re.match(r'[r-t]', '\u017f', re.I)) + self.assertTrue(re.match(r'[\u017e-\u0180]', 'S', re.I)) + self.assertTrue(re.match(r'[\u017e-\u0180]', 's', re.I)) + assert '\ufb05'.upper() == '\ufb06'.upper() == 'ST' # 'ſt', 'st' + self.assertTrue(re.match(r'[\ufb04-\ufb05]', '\ufb06', re.I)) + self.assertTrue(re.match(r'[\ufb06-\ufb07]', '\ufb05', re.I)) + def test_category(self): self.assertEqual(re.match(r"(\s)", " ").group(1), " ") @@ -585,9 +748,12 @@ def test_getlower(self): self.assertEqual(_sre.getlower(ord('A'), 0), ord('a')) self.assertEqual(_sre.getlower(ord('A'), re.LOCALE), ord('a')) self.assertEqual(_sre.getlower(ord('A'), re.UNICODE), ord('a')) + self.assertEqual(_sre.getlower(ord('A'), re.ASCII), ord('a')) self.assertEqual(re.match("abc", "ABC", re.I).group(0), "ABC") - self.assertEqual(re.match("abc", "ABC", re.I).group(0), "ABC") + self.assertEqual(re.match(b"abc", b"ABC", re.I).group(0), b"ABC") + self.assertEqual(re.match("abc", "ABC", re.I|re.A).group(0), "ABC") + self.assertEqual(re.match(b"abc", b"ABC", re.I|re.L).group(0), b"ABC") def test_not_literal(self): self.assertEqual(re.search("\s([^a])", " b").group(1), "b") @@ -654,11 +820,15 @@ def test_re_escape_non_ascii_bytes(self): res = re.findall(re.escape('\u2620'.encode('utf-8')), b) self.assertEqual(len(res), 2) - def pickle_test(self, pickle): - oldpat = re.compile('a(?:b|(c|e){1,2}?|d)+?(.)') - s = pickle.dumps(oldpat) - newpat = pickle.loads(s) - self.assertEqual(oldpat, newpat) + def test_pickling(self): + import pickle + oldpat = re.compile('a(?:b|(c|e){1,2}?|d)+?(.)', re.UNICODE) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + pickled = pickle.dumps(oldpat, proto) + newpat = pickle.loads(pickled) + self.assertEqual(newpat, oldpat) + # current pickle expects the _compile() reconstructor in re module + from re import _compile def test_constants(self): self.assertEqual(re.I, re.IGNORECASE) @@ -668,30 +838,32 @@ def test_constants(self): self.assertEqual(re.X, re.VERBOSE) def test_flags(self): - for flag in [re.I, re.M, re.X, re.S, re.L]: - self.assertNotEqual(re.compile('^pattern$', flag), None) + for flag in [re.I, re.M, re.X, re.S, re.A, re.U]: + self.assertTrue(re.compile('^pattern$', flag)) + for flag in [re.I, re.M, re.X, re.S, re.A, re.L]: + self.assertTrue(re.compile(b'^pattern$', flag)) def test_sre_character_literals(self): for i in [0, 8, 16, 32, 64, 127, 128, 255, 256, 0xFFFF, 0x10000, 0x10FFFF]: if i < 256: - self.assertIsNotNone(re.match(r"\%03o" % i, chr(i))) - self.assertIsNotNone(re.match(r"\%03o0" % i, chr(i)+"0")) - self.assertIsNotNone(re.match(r"\%03o8" % i, chr(i)+"8")) - self.assertIsNotNone(re.match(r"\x%02x" % i, chr(i))) - self.assertIsNotNone(re.match(r"\x%02x0" % i, chr(i)+"0")) - self.assertIsNotNone(re.match(r"\x%02xz" % i, chr(i)+"z")) + self.assertTrue(re.match(r"\%03o" % i, chr(i))) + self.assertTrue(re.match(r"\%03o0" % i, chr(i)+"0")) + self.assertTrue(re.match(r"\%03o8" % i, chr(i)+"8")) + self.assertTrue(re.match(r"\x%02x" % i, chr(i))) + self.assertTrue(re.match(r"\x%02x0" % i, chr(i)+"0")) + self.assertTrue(re.match(r"\x%02xz" % i, chr(i)+"z")) if i < 0x10000: - self.assertIsNotNone(re.match(r"\u%04x" % i, chr(i))) - self.assertIsNotNone(re.match(r"\u%04x0" % i, chr(i)+"0")) - self.assertIsNotNone(re.match(r"\u%04xz" % i, chr(i)+"z")) - self.assertIsNotNone(re.match(r"\U%08x" % i, chr(i))) - self.assertIsNotNone(re.match(r"\U%08x0" % i, chr(i)+"0")) - self.assertIsNotNone(re.match(r"\U%08xz" % i, chr(i)+"z")) - self.assertIsNotNone(re.match(r"\0", "\000")) - self.assertIsNotNone(re.match(r"\08", "\0008")) - self.assertIsNotNone(re.match(r"\01", "\001")) - self.assertIsNotNone(re.match(r"\018", "\0018")) - self.assertIsNotNone(re.match(r"\567", chr(0o167))) + self.assertTrue(re.match(r"\u%04x" % i, chr(i))) + self.assertTrue(re.match(r"\u%04x0" % i, chr(i)+"0")) + self.assertTrue(re.match(r"\u%04xz" % i, chr(i)+"z")) + self.assertTrue(re.match(r"\U%08x" % i, chr(i))) + self.assertTrue(re.match(r"\U%08x0" % i, chr(i)+"0")) + self.assertTrue(re.match(r"\U%08xz" % i, chr(i)+"z")) + self.assertTrue(re.match(r"\0", "\000")) + self.assertTrue(re.match(r"\08", "\0008")) + self.assertTrue(re.match(r"\01", "\001")) + self.assertTrue(re.match(r"\018", "\0018")) + self.assertRaises(re.error, re.match, r"\567", "") self.assertRaises(re.error, re.match, r"\911", "") self.assertRaises(re.error, re.match, r"\x1", "") self.assertRaises(re.error, re.match, r"\x1z", "") @@ -704,61 +876,63 @@ def test_sre_character_literals(self): def test_sre_character_class_literals(self): for i in [0, 8, 16, 32, 64, 127, 128, 255, 256, 0xFFFF, 0x10000, 0x10FFFF]: if i < 256: - self.assertIsNotNone(re.match(r"[\%o]" % i, chr(i))) - self.assertIsNotNone(re.match(r"[\%o8]" % i, chr(i))) - self.assertIsNotNone(re.match(r"[\%03o]" % i, chr(i))) - self.assertIsNotNone(re.match(r"[\%03o0]" % i, chr(i))) - self.assertIsNotNone(re.match(r"[\%03o8]" % i, chr(i))) - self.assertIsNotNone(re.match(r"[\x%02x]" % i, chr(i))) - self.assertIsNotNone(re.match(r"[\x%02x0]" % i, chr(i))) - self.assertIsNotNone(re.match(r"[\x%02xz]" % i, chr(i))) + self.assertTrue(re.match(r"[\%o]" % i, chr(i))) + self.assertTrue(re.match(r"[\%o8]" % i, chr(i))) + self.assertTrue(re.match(r"[\%03o]" % i, chr(i))) + self.assertTrue(re.match(r"[\%03o0]" % i, chr(i))) + self.assertTrue(re.match(r"[\%03o8]" % i, chr(i))) + self.assertTrue(re.match(r"[\x%02x]" % i, chr(i))) + self.assertTrue(re.match(r"[\x%02x0]" % i, chr(i))) + self.assertTrue(re.match(r"[\x%02xz]" % i, chr(i))) if i < 0x10000: - self.assertIsNotNone(re.match(r"[\u%04x]" % i, chr(i))) - self.assertIsNotNone(re.match(r"[\u%04x0]" % i, chr(i))) - self.assertIsNotNone(re.match(r"[\u%04xz]" % i, chr(i))) - self.assertIsNotNone(re.match(r"[\U%08x]" % i, chr(i))) - self.assertIsNotNone(re.match(r"[\U%08x0]" % i, chr(i)+"0")) - self.assertIsNotNone(re.match(r"[\U%08xz]" % i, chr(i)+"z")) - self.assertIsNotNone(re.match(r"[\U0001d49c-\U0001d4b5]", "\U0001d49e")) + self.assertTrue(re.match(r"[\u%04x]" % i, chr(i))) + self.assertTrue(re.match(r"[\u%04x0]" % i, chr(i))) + self.assertTrue(re.match(r"[\u%04xz]" % i, chr(i))) + self.assertTrue(re.match(r"[\U%08x]" % i, chr(i))) + self.assertTrue(re.match(r"[\U%08x0]" % i, chr(i)+"0")) + self.assertTrue(re.match(r"[\U%08xz]" % i, chr(i)+"z")) + self.assertRaises(re.error, re.match, r"[\567]", "") self.assertRaises(re.error, re.match, r"[\911]", "") self.assertRaises(re.error, re.match, r"[\x1z]", "") self.assertRaises(re.error, re.match, r"[\u123z]", "") self.assertRaises(re.error, re.match, r"[\U0001234z]", "") self.assertRaises(re.error, re.match, r"[\U00110000]", "") + self.assertTrue(re.match(r"[\U0001d49c-\U0001d4b5]", "\U0001d49e")) def test_sre_byte_literals(self): for i in [0, 8, 16, 32, 64, 127, 128, 255]: - self.assertIsNotNone(re.match((r"\%03o" % i).encode(), bytes([i]))) - self.assertIsNotNone(re.match((r"\%03o0" % i).encode(), bytes([i])+b"0")) - self.assertIsNotNone(re.match((r"\%03o8" % i).encode(), bytes([i])+b"8")) - self.assertIsNotNone(re.match((r"\x%02x" % i).encode(), bytes([i]))) - self.assertIsNotNone(re.match((r"\x%02x0" % i).encode(), bytes([i])+b"0")) - self.assertIsNotNone(re.match((r"\x%02xz" % i).encode(), bytes([i])+b"z")) - self.assertIsNotNone(re.match(br"\u", b'u')) - self.assertIsNotNone(re.match(br"\U", b'U')) - self.assertIsNotNone(re.match(br"\0", b"\000")) - self.assertIsNotNone(re.match(br"\08", b"\0008")) - self.assertIsNotNone(re.match(br"\01", b"\001")) - self.assertIsNotNone(re.match(br"\018", b"\0018")) - self.assertIsNotNone(re.match(br"\567", bytes([0o167]))) + self.assertTrue(re.match((r"\%03o" % i).encode(), bytes([i]))) + self.assertTrue(re.match((r"\%03o0" % i).encode(), bytes([i])+b"0")) + self.assertTrue(re.match((r"\%03o8" % i).encode(), bytes([i])+b"8")) + self.assertTrue(re.match((r"\x%02x" % i).encode(), bytes([i]))) + self.assertTrue(re.match((r"\x%02x0" % i).encode(), bytes([i])+b"0")) + self.assertTrue(re.match((r"\x%02xz" % i).encode(), bytes([i])+b"z")) + self.assertTrue(re.match(br"\u", b'u')) + self.assertTrue(re.match(br"\U", b'U')) + self.assertTrue(re.match(br"\0", b"\000")) + self.assertTrue(re.match(br"\08", b"\0008")) + self.assertTrue(re.match(br"\01", b"\001")) + self.assertTrue(re.match(br"\018", b"\0018")) + self.assertRaises(re.error, re.match, br"\567", b"") self.assertRaises(re.error, re.match, br"\911", b"") self.assertRaises(re.error, re.match, br"\x1", b"") self.assertRaises(re.error, re.match, br"\x1z", b"") def test_sre_byte_class_literals(self): for i in [0, 8, 16, 32, 64, 127, 128, 255]: - self.assertIsNotNone(re.match((r"[\%o]" % i).encode(), bytes([i]))) - self.assertIsNotNone(re.match((r"[\%o8]" % i).encode(), bytes([i]))) - self.assertIsNotNone(re.match((r"[\%03o]" % i).encode(), bytes([i]))) - self.assertIsNotNone(re.match((r"[\%03o0]" % i).encode(), bytes([i]))) - self.assertIsNotNone(re.match((r"[\%03o8]" % i).encode(), bytes([i]))) - self.assertIsNotNone(re.match((r"[\x%02x]" % i).encode(), bytes([i]))) - self.assertIsNotNone(re.match((r"[\x%02x0]" % i).encode(), bytes([i]))) - self.assertIsNotNone(re.match((r"[\x%02xz]" % i).encode(), bytes([i]))) - self.assertIsNotNone(re.match(br"[\u]", b'u')) - self.assertIsNotNone(re.match(br"[\U]", b'U')) - self.assertRaises(re.error, re.match, br"[\911]", "") - self.assertRaises(re.error, re.match, br"[\x1z]", "") + self.assertTrue(re.match((r"[\%o]" % i).encode(), bytes([i]))) + self.assertTrue(re.match((r"[\%o8]" % i).encode(), bytes([i]))) + self.assertTrue(re.match((r"[\%03o]" % i).encode(), bytes([i]))) + self.assertTrue(re.match((r"[\%03o0]" % i).encode(), bytes([i]))) + self.assertTrue(re.match((r"[\%03o8]" % i).encode(), bytes([i]))) + self.assertTrue(re.match((r"[\x%02x]" % i).encode(), bytes([i]))) + self.assertTrue(re.match((r"[\x%02x0]" % i).encode(), bytes([i]))) + self.assertTrue(re.match((r"[\x%02xz]" % i).encode(), bytes([i]))) + self.assertTrue(re.match(br"[\u]", b'u')) + self.assertTrue(re.match(br"[\U]", b'U')) + self.assertRaises(re.error, re.match, br"[\567]", b"") + self.assertRaises(re.error, re.match, br"[\911]", b"") + self.assertRaises(re.error, re.match, br"[\x1z]", b"") def test_bug_113254(self): self.assertEqual(re.match(r'(a)|(b)', 'b').start(1), -1) @@ -767,7 +941,7 @@ def test_bug_113254(self): def test_bug_527371(self): # bug described in patches 527371/672491 - self.assertEqual(re.match(r'(a)?a','a').lastindex, None) + self.assertIsNone(re.match(r'(a)?a','a').lastindex) self.assertEqual(re.match(r'(a)(b)?b','ab').lastindex, 1) self.assertEqual(re.match(r'(?Pa)(?Pb)?b','ab').lastgroup, 'a') self.assertEqual(re.match("(?Pa(b))", "ab").lastgroup, 'a') @@ -824,7 +998,7 @@ def s_int(scanner, token): return int(token) (r"\s+", None), ]) - self.assertNotEqual(scanner.scanner.scanner("").pattern, None) + self.assertTrue(scanner.scanner.scanner("").pattern) self.assertEqual(scanner.scan("sum = 3*foo + 312.50 + bar"), (['sum', 'op=', 3, 'op*', 'foo', 'op+', 312.5, @@ -869,7 +1043,7 @@ def test_bug_764548(self): # bug 764548, re.compile() barfs on str/unicode subclasses class my_unicode(str): pass pat = re.compile(my_unicode("abc")) - self.assertEqual(pat.match("xyz"), None) + self.assertIsNone(pat.match("xyz")) def test_finditer(self): iter = re.finditer(r":+", "a:b::c:::d") @@ -897,11 +1071,11 @@ def test_finditer(self): ["::", "::"]) def test_bug_926075(self): - self.assertTrue(re.compile('bug_926075') is not - re.compile(b'bug_926075')) + self.assertIsNot(re.compile('bug_926075'), + re.compile(b'bug_926075')) def test_bug_931848(self): - pattern = eval('"[\u002E\u3002\uFF0E\uFF61]"') + pattern = "[\u002E\u3002\uFF0E\uFF61]" self.assertEqual(re.compile(pattern).split("a.b.c"), ['a','b','c']) @@ -912,7 +1086,7 @@ def test_bug_581080(self): scanner = re.compile(r"\s").scanner("a b") self.assertEqual(scanner.search().span(), (1, 2)) - self.assertEqual(scanner.search(), None) + self.assertIsNone(scanner.search()) def test_bug_817234(self): iter = re.finditer(r".*", "asdf") @@ -946,37 +1120,37 @@ def test_empty_array(self): import array for typecode in 'bBuhHiIlLfd': a = array.array(typecode) - self.assertEqual(re.compile(b"bla").match(a), None) + self.assertIsNone(re.compile(b"bla").match(a)) self.assertEqual(re.compile(b"").match(a).groups(), ()) def test_inline_flags(self): # Bug #1700 - upper_char = chr(0x1ea0) # Latin Capital Letter A with Dot Bellow - lower_char = chr(0x1ea1) # Latin Small Letter A with Dot Bellow + upper_char = '\u1ea0' # Latin Capital Letter A with Dot Below + lower_char = '\u1ea1' # Latin Small Letter A with Dot Below p = re.compile(upper_char, re.I | re.U) q = p.match(lower_char) - self.assertNotEqual(q, None) + self.assertTrue(q) p = re.compile(lower_char, re.I | re.U) q = p.match(upper_char) - self.assertNotEqual(q, None) + self.assertTrue(q) p = re.compile('(?i)' + upper_char, re.U) q = p.match(lower_char) - self.assertNotEqual(q, None) + self.assertTrue(q) p = re.compile('(?i)' + lower_char, re.U) q = p.match(upper_char) - self.assertNotEqual(q, None) + self.assertTrue(q) p = re.compile('(?iu)' + upper_char) q = p.match(lower_char) - self.assertNotEqual(q, None) + self.assertTrue(q) p = re.compile('(?iu)' + lower_char) q = p.match(upper_char) - self.assertNotEqual(q, None) + self.assertTrue(q) def test_dollar_matches_twice(self): "$ matches the end of string, and just before the terminating \n" @@ -1007,23 +1181,23 @@ def test_ascii_and_unicode_flag(self): # String patterns for flags in (0, re.UNICODE): pat = re.compile('\xc0', flags | re.IGNORECASE) - self.assertNotEqual(pat.match('\xe0'), None) + self.assertTrue(pat.match('\xe0')) pat = re.compile('\w', flags) - self.assertNotEqual(pat.match('\xe0'), None) + self.assertTrue(pat.match('\xe0')) pat = re.compile('\xc0', re.ASCII | re.IGNORECASE) - self.assertEqual(pat.match('\xe0'), None) + self.assertIsNone(pat.match('\xe0')) pat = re.compile('(?a)\xc0', re.IGNORECASE) - self.assertEqual(pat.match('\xe0'), None) + self.assertIsNone(pat.match('\xe0')) pat = re.compile('\w', re.ASCII) - self.assertEqual(pat.match('\xe0'), None) + self.assertIsNone(pat.match('\xe0')) pat = re.compile('(?a)\w') - self.assertEqual(pat.match('\xe0'), None) + self.assertIsNone(pat.match('\xe0')) # Bytes patterns for flags in (0, re.ASCII): - pat = re.compile(b'\xc0', re.IGNORECASE) - self.assertEqual(pat.match(b'\xe0'), None) - pat = re.compile(b'\w') - self.assertEqual(pat.match(b'\xe0'), None) + pat = re.compile(b'\xc0', flags | re.IGNORECASE) + self.assertIsNone(pat.match(b'\xe0')) + pat = re.compile(b'\w', flags) + self.assertIsNone(pat.match(b'\xe0')) # Incompatibilities self.assertRaises(ValueError, re.compile, b'\w', re.UNICODE) self.assertRaises(ValueError, re.compile, b'(?u)\w') @@ -1032,6 +1206,52 @@ def test_ascii_and_unicode_flag(self): self.assertRaises(ValueError, re.compile, '(?a)\w', re.UNICODE) self.assertRaises(ValueError, re.compile, '(?au)\w') + def test_locale_flag(self): + import locale + _, enc = locale.getlocale(locale.LC_CTYPE) + # Search non-ASCII letter + for i in range(128, 256): + try: + c = bytes([i]).decode(enc) + sletter = c.lower() + if sletter == c: continue + bletter = sletter.encode(enc) + if len(bletter) != 1: continue + if bletter.decode(enc) != sletter: continue + bpat = re.escape(bytes([i])) + break + except (UnicodeError, TypeError): + pass + else: + bletter = None + bpat = b'A' + # Bytes patterns + pat = re.compile(bpat, re.LOCALE | re.IGNORECASE) + if bletter: + self.assertTrue(pat.match(bletter)) + pat = re.compile(b'(?L)' + bpat, re.IGNORECASE) + if bletter: + self.assertTrue(pat.match(bletter)) + pat = re.compile(bpat, re.IGNORECASE) + if bletter: + self.assertIsNone(pat.match(bletter)) + pat = re.compile(b'\w', re.LOCALE) + if bletter: + self.assertTrue(pat.match(bletter)) + pat = re.compile(b'(?L)\w') + if bletter: + self.assertTrue(pat.match(bletter)) + pat = re.compile(b'\w') + if bletter: + self.assertIsNone(pat.match(bletter)) + # Incompatibilities + self.assertWarns(DeprecationWarning, re.compile, '', re.LOCALE) + self.assertWarns(DeprecationWarning, re.compile, '(?L)') + self.assertWarns(DeprecationWarning, re.compile, b'', re.LOCALE | re.ASCII) + self.assertWarns(DeprecationWarning, re.compile, b'(?L)', re.ASCII) + self.assertWarns(DeprecationWarning, re.compile, b'(?a)', re.LOCALE) + self.assertWarns(DeprecationWarning, re.compile, b'(?aL)') + def test_bug_6509(self): # Replacement strings of both types must parse properly. # all strings @@ -1059,15 +1279,17 @@ def test_dealloc(self): # a RuntimeError is raised instead of OverflowError. long_overflow = 2**128 self.assertRaises(TypeError, re.finditer, "a", {}) - self.assertRaises(OverflowError, _sre.compile, "abc", 0, [long_overflow]) - self.assertRaises(TypeError, _sre.compile, {}, 0, []) + with self.assertRaises(OverflowError): + _sre.compile("abc", 0, [long_overflow], 0, [], []) + with self.assertRaises(TypeError): + _sre.compile({}, 0, [], 0, [], []) def test_search_dot_unicode(self): - self.assertIsNotNone(re.search("123.*-", '123abc-')) - self.assertIsNotNone(re.search("123.*-", '123\xe9-')) - self.assertIsNotNone(re.search("123.*-", '123\u20ac-')) - self.assertIsNotNone(re.search("123.*-", '123\U0010ffff-')) - self.assertIsNotNone(re.search("123.*-", '123\xe9\u20ac\U0010ffff-')) + self.assertTrue(re.search("123.*-", '123abc-')) + self.assertTrue(re.search("123.*-", '123\xe9-')) + self.assertTrue(re.search("123.*-", '123\u20ac-')) + self.assertTrue(re.search("123.*-", '123\U0010ffff-')) + self.assertTrue(re.search("123.*-", '123\xe9\u20ac\U0010ffff-')) def test_compile(self): # Test return value when given string and pattern as parameter @@ -1193,6 +1415,130 @@ def test_bug_2537(self): self.assertEqual(m.group(1), "") self.assertEqual(m.group(2), "y") + def test_debug_flag(self): + pat = r'(\.)(?:[ch]|py)(?(1)$|: )' + with captured_stdout() as out: + re.compile(pat, re.DEBUG) + dump = '''\ +SUBPATTERN 1 + LITERAL 46 +SUBPATTERN None + BRANCH + IN + LITERAL 99 + LITERAL 104 + OR + LITERAL 112 + LITERAL 121 +SUBPATTERN None + GROUPREF_EXISTS 1 + AT AT_END + ELSE + LITERAL 58 + LITERAL 32 +''' + self.assertEqual(out.getvalue(), dump) + # Debug output is output again even a second time (bypassing + # the cache -- issue #20426). + with captured_stdout() as out: + re.compile(pat, re.DEBUG) + self.assertEqual(out.getvalue(), dump) + + def test_keyword_parameters(self): + # Issue #20283: Accepting the string keyword parameter. + pat = re.compile(r'(ab)') + self.assertEqual( + pat.match(string='abracadabra', pos=7, endpos=10).span(), (7, 9)) + self.assertEqual( + pat.fullmatch(string='abracadabra', pos=7, endpos=9).span(), (7, 9)) + self.assertEqual( + pat.search(string='abracadabra', pos=3, endpos=10).span(), (7, 9)) + self.assertEqual( + pat.findall(string='abracadabra', pos=3, endpos=10), ['ab']) + self.assertEqual( + pat.split(string='abracadabra', maxsplit=1), + ['', 'ab', 'racadabra']) + self.assertEqual( + pat.scanner(string='abracadabra', pos=3, endpos=10).search().span(), + (7, 9)) + + def test_bug_20998(self): + # Issue #20998: Fullmatch of repeated single character pattern + # with ignore case. + self.assertEqual(re.fullmatch('[a-c]+', 'ABC', re.I).span(), (0, 3)) + + def test_locale_caching(self): + # Issue #22410 + oldlocale = locale.setlocale(locale.LC_CTYPE) + self.addCleanup(locale.setlocale, locale.LC_CTYPE, oldlocale) + for loc in 'en_US.iso88591', 'en_US.utf8': + try: + locale.setlocale(locale.LC_CTYPE, loc) + except locale.Error: + # Unsupported locale on this system + self.skipTest('test needs %s locale' % loc) + + re.purge() + self.check_en_US_iso88591() + self.check_en_US_utf8() + re.purge() + self.check_en_US_utf8() + self.check_en_US_iso88591() + + def check_en_US_iso88591(self): + locale.setlocale(locale.LC_CTYPE, 'en_US.iso88591') + self.assertTrue(re.match(b'\xc5\xe5', b'\xc5\xe5', re.L|re.I)) + self.assertTrue(re.match(b'\xc5', b'\xe5', re.L|re.I)) + self.assertTrue(re.match(b'\xe5', b'\xc5', re.L|re.I)) + self.assertTrue(re.match(b'(?Li)\xc5\xe5', b'\xc5\xe5')) + self.assertTrue(re.match(b'(?Li)\xc5', b'\xe5')) + self.assertTrue(re.match(b'(?Li)\xe5', b'\xc5')) + + def check_en_US_utf8(self): + locale.setlocale(locale.LC_CTYPE, 'en_US.utf8') + self.assertTrue(re.match(b'\xc5\xe5', b'\xc5\xe5', re.L|re.I)) + self.assertIsNone(re.match(b'\xc5', b'\xe5', re.L|re.I)) + self.assertIsNone(re.match(b'\xe5', b'\xc5', re.L|re.I)) + self.assertTrue(re.match(b'(?Li)\xc5\xe5', b'\xc5\xe5')) + self.assertIsNone(re.match(b'(?Li)\xc5', b'\xe5')) + self.assertIsNone(re.match(b'(?Li)\xe5', b'\xc5')) + + def test_error(self): + with self.assertRaises(re.error) as cm: + re.compile('(\u20ac))') + err = cm.exception + self.assertIsInstance(err.pattern, str) + self.assertEqual(err.pattern, '(\u20ac))') + self.assertEqual(err.pos, 3) + self.assertEqual(err.lineno, 1) + self.assertEqual(err.colno, 4) + self.assertIn(err.msg, str(err)) + self.assertIn(' at position 3', str(err)) + self.assertNotIn(' at position 3', err.msg) + # Bytes pattern + with self.assertRaises(re.error) as cm: + re.compile(b'(\xa4))') + err = cm.exception + self.assertIsInstance(err.pattern, bytes) + self.assertEqual(err.pattern, b'(\xa4))') + self.assertEqual(err.pos, 3) + # Multiline pattern + with self.assertRaises(re.error) as cm: + re.compile(""" + ( + abc + ) + ) + ( + """, re.VERBOSE) + err = cm.exception + self.assertEqual(err.pos, 77) + self.assertEqual(err.lineno, 5) + self.assertEqual(err.colno, 17) + self.assertIn(err.msg, str(err)) + self.assertIn(' at position 77', str(err)) + self.assertIn('(line 5, column 17)', str(err)) + class PatternReprTests(unittest.TestCase): def check(self, pattern, expected): @@ -1237,6 +1583,10 @@ def test_bytes(self): self.check_flags(b'bytes pattern', re.A, "re.compile(b'bytes pattern', re.ASCII)") + def test_locale(self): + self.check_flags(b'bytes pattern', re.L, + "re.compile(b'bytes pattern', re.LOCALE)") + def test_quotes(self): self.check('random "double quoted" pattern', '''re.compile('random "double quoted" pattern')''') @@ -1271,55 +1621,55 @@ def test_overlap_table(self): self.assertEqual(f("abcabdac"), [0, 0, 0, 1, 2, 0, 1, 0]) -def run_re_tests(): - from test.re_tests import tests, SUCCEED, FAIL, SYNTAX_ERROR - if verbose: - print('Running re_tests test suite') - else: - # To save time, only run the first and last 10 tests - #tests = tests[:10] + tests[-10:] - pass - - for t in tests: - sys.stdout.flush() - pattern = s = outcome = repl = expected = None - if len(t) == 5: - pattern, s, outcome, repl, expected = t - elif len(t) == 3: - pattern, s, outcome = t - else: - raise ValueError('Test tuples should have 3 or 5 fields', t) - - try: - obj = re.compile(pattern) - except re.error: - if outcome == SYNTAX_ERROR: pass # Expected a syntax error +class ExternalTests(unittest.TestCase): + + def test_re_benchmarks(self): + 're_tests benchmarks' + from test.re_tests import benchmarks + for pattern, s in benchmarks: + with self.subTest(pattern=pattern, string=s): + p = re.compile(pattern) + self.assertTrue(p.search(s)) + self.assertTrue(p.match(s)) + self.assertTrue(p.fullmatch(s)) + s2 = ' '*10000 + s + ' '*10000 + self.assertTrue(p.search(s2)) + self.assertTrue(p.match(s2, 10000)) + self.assertTrue(p.match(s2, 10000, 10000 + len(s))) + self.assertTrue(p.fullmatch(s2, 10000, 10000 + len(s))) + + def test_re_tests(self): + 're_tests test suite' + from test.re_tests import tests, SUCCEED, FAIL, SYNTAX_ERROR + for t in tests: + pattern = s = outcome = repl = expected = None + if len(t) == 5: + pattern, s, outcome, repl, expected = t + elif len(t) == 3: + pattern, s, outcome = t else: - print('=== Syntax error:', t) - except KeyboardInterrupt: raise KeyboardInterrupt - except: - print('*** Unexpected error ***', t) - if verbose: - traceback.print_exc(file=sys.stdout) - else: - try: + raise ValueError('Test tuples should have 3 or 5 fields', t) + + with self.subTest(pattern=pattern, string=s): + if outcome == SYNTAX_ERROR: # Expected a syntax error + with self.assertRaises(re.error): + re.compile(pattern) + continue + + obj = re.compile(pattern) result = obj.search(s) - except re.error as msg: - print('=== Unexpected exception', t, repr(msg)) - if outcome == SYNTAX_ERROR: - # This should have been a syntax error; forget it. - pass - elif outcome == FAIL: - if result is None: pass # No match, as expected - else: print('=== Succeeded incorrectly', t) - elif outcome == SUCCEED: - if result is not None: + if outcome == FAIL: + self.assertIsNone(result, 'Succeeded incorrectly') + continue + + with self.subTest(): + self.assertTrue(result, 'Failed incorrectly') # Matched, as expected, so now we compute the # result string and compare it to our expected result. start, end = result.span(0) - vardict={'found': result.group(0), - 'groups': result.group(), - 'flags': result.re.flags} + vardict = {'found': result.group(0), + 'groups': result.group(), + 'flags': result.re.flags} for i in range(1, 100): try: gi = result.group(i) @@ -1337,12 +1687,8 @@ def run_re_tests(): except IndexError: gi = "Error" vardict[i] = gi - repl = eval(repl, vardict) - if repl != expected: - print('=== grouping error', t, end=' ') - print(repr(repl) + ' should be ' + repr(expected)) - else: - print('=== Failed incorrectly', t) + self.assertEqual(eval(repl, vardict), expected, + 'grouping error') # Try the match with both pattern and string converted to # bytes, and check that it still succeeds. @@ -1353,55 +1699,40 @@ def run_re_tests(): # skip non-ascii tests pass else: - try: - bpat = re.compile(bpat) - except Exception: - print('=== Fails on bytes pattern compile', t) - if verbose: - traceback.print_exc(file=sys.stdout) - else: - bytes_result = bpat.search(bs) - if bytes_result is None: - print('=== Fails on bytes pattern match', t) + with self.subTest('bytes pattern match'): + obj = re.compile(bpat) + self.assertTrue(obj.search(bs)) + + # Try the match with LOCALE enabled, and check that it + # still succeeds. + with self.subTest('locale-sensitive match'): + obj = re.compile(bpat, re.LOCALE) + result = obj.search(bs) + if result is None: + print('=== Fails on locale-sensitive match', t) # Try the match with the search area limited to the extent # of the match and see if it still succeeds. \B will # break (because it won't match at the end or start of a # string), so we'll ignore patterns that feature it. - - if pattern[:2] != '\\B' and pattern[-2:] != '\\B' \ - and result is not None: - obj = re.compile(pattern) - result = obj.search(s, result.start(0), result.end(0) + 1) - if result is None: - print('=== Failed on range-limited match', t) + if (pattern[:2] != r'\B' and pattern[-2:] != r'\B' + and result is not None): + with self.subTest('range-limited match'): + obj = re.compile(pattern) + self.assertTrue(obj.search(s, start, end + 1)) # Try the match with IGNORECASE enabled, and check that it # still succeeds. - obj = re.compile(pattern, re.IGNORECASE) - result = obj.search(s) - if result is None: - print('=== Fails on case-insensitive match', t) - - # Try the match with LOCALE enabled, and check that it - # still succeeds. - if '(?u)' not in pattern: - obj = re.compile(pattern, re.LOCALE) - result = obj.search(s) - if result is None: - print('=== Fails on locale-sensitive match', t) + with self.subTest('case-insensitive match'): + obj = re.compile(pattern, re.IGNORECASE) + self.assertTrue(obj.search(s)) # Try the match with UNICODE locale enabled, and check # that it still succeeds. - obj = re.compile(pattern, re.UNICODE) - result = obj.search(s) - if result is None: - print('=== Fails on unicode-sensitive match', t) - + with self.subTest('unicode-sensitive match'): + obj = re.compile(pattern, re.UNICODE) + self.assertTrue(obj.search(s)) -def test_main(): - run_unittest(__name__) - run_re_tests() if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_readline.py b/Lib/test/test_readline.py index 5483dd31b805..23d6194e8ece 100644 --- a/Lib/test/test_readline.py +++ b/Lib/test/test_readline.py @@ -1,21 +1,25 @@ """ Very minimal unittests for parts of the readline module. - -These tests were added to check that the libedit emulation on OSX and -the "real" readline have the same interface for history manipulation. That's -why the tests cover only a small subset of the interface. """ +import os +import tempfile import unittest -from test.support import run_unittest, import_module +from test.support import run_unittest, import_module, unlink +from test.script_helper import assert_python_ok # Skip tests if there is no readline module readline = import_module('readline') class TestHistoryManipulation (unittest.TestCase): + """ + These tests were added to check that the libedit emulation on OSX and the + "real" readline have the same interface for history manipulation. That's + why the tests cover only a small subset of the interface. + """ - @unittest.skipIf(not hasattr(readline, 'clear_history'), - "The history update test cannot be run because the " - "clear_history method is not available.") + @unittest.skipUnless(hasattr(readline, "clear_history"), + "The history update test cannot be run because the " + "clear_history method is not available.") def testHistoryUpdates(self): readline.clear_history() @@ -39,9 +43,62 @@ def testHistoryUpdates(self): self.assertEqual(readline.get_current_history_length(), 1) + @unittest.skipUnless(hasattr(readline, "append_history_file"), + "append_history not available") + def test_write_read_append(self): + hfile = tempfile.NamedTemporaryFile(delete=False) + hfile.close() + hfilename = hfile.name + self.addCleanup(unlink, hfilename) + + # test write-clear-read == nop + readline.clear_history() + readline.add_history("first line") + readline.add_history("second line") + readline.write_history_file(hfilename) + + readline.clear_history() + self.assertEqual(readline.get_current_history_length(), 0) + + readline.read_history_file(hfilename) + self.assertEqual(readline.get_current_history_length(), 2) + self.assertEqual(readline.get_history_item(1), "first line") + self.assertEqual(readline.get_history_item(2), "second line") + + # test append + readline.append_history_file(1, hfilename) + readline.clear_history() + readline.read_history_file(hfilename) + self.assertEqual(readline.get_current_history_length(), 3) + self.assertEqual(readline.get_history_item(1), "first line") + self.assertEqual(readline.get_history_item(2), "second line") + self.assertEqual(readline.get_history_item(3), "second line") + + # test 'no such file' behaviour + os.unlink(hfilename) + with self.assertRaises(FileNotFoundError): + readline.append_history_file(1, hfilename) + + # write_history_file can create the target + readline.write_history_file(hfilename) + + +class TestReadline(unittest.TestCase): + + @unittest.skipIf(readline._READLINE_VERSION < 0x0600 + and "libedit" not in readline.__doc__, + "not supported in this library version") + def test_init(self): + # Issue #19884: Ensure that the ANSI sequence "\033[1034h" is not + # written into stdout when the readline module is imported and stdout + # is redirected to a pipe. + rc, stdout, stderr = assert_python_ok('-c', 'import readline', + TERM='xterm-256color') + self.assertEqual(stdout, b'') + def test_main(): - run_unittest(TestHistoryManipulation) + run_unittest(TestHistoryManipulation, TestReadline) if __name__ == "__main__": test_main() diff --git a/Lib/test/test_reprlib.py b/Lib/test/test_reprlib.py index a504bde4e404..a51c4d7523f6 100644 --- a/Lib/test/test_reprlib.py +++ b/Lib/test/test_reprlib.py @@ -10,7 +10,7 @@ import importlib.util import unittest -from test.support import run_unittest, create_empty_file, verbose +from test.support import create_empty_file, verbose from reprlib import repr as r # Don't shadow builtin repr from reprlib import Repr from reprlib import recursive_repr @@ -70,18 +70,18 @@ def test_container(self): eq(r([1, 2, 3, 4, 5, 6, 7]), "[1, 2, 3, 4, 5, 6, ...]") # Sets give up after 6 as well - eq(r(set([])), "set([])") - eq(r(set([1])), "set([1])") - eq(r(set([1, 2, 3])), "set([1, 2, 3])") - eq(r(set([1, 2, 3, 4, 5, 6])), "set([1, 2, 3, 4, 5, 6])") - eq(r(set([1, 2, 3, 4, 5, 6, 7])), "set([1, 2, 3, 4, 5, 6, ...])") + eq(r(set([])), "set()") + eq(r(set([1])), "{1}") + eq(r(set([1, 2, 3])), "{1, 2, 3}") + eq(r(set([1, 2, 3, 4, 5, 6])), "{1, 2, 3, 4, 5, 6}") + eq(r(set([1, 2, 3, 4, 5, 6, 7])), "{1, 2, 3, 4, 5, 6, ...}") # Frozensets give up after 6 as well - eq(r(frozenset([])), "frozenset([])") - eq(r(frozenset([1])), "frozenset([1])") - eq(r(frozenset([1, 2, 3])), "frozenset([1, 2, 3])") - eq(r(frozenset([1, 2, 3, 4, 5, 6])), "frozenset([1, 2, 3, 4, 5, 6])") - eq(r(frozenset([1, 2, 3, 4, 5, 6, 7])), "frozenset([1, 2, 3, 4, 5, 6, ...])") + eq(r(frozenset([])), "frozenset()") + eq(r(frozenset([1])), "frozenset({1})") + eq(r(frozenset([1, 2, 3])), "frozenset({1, 2, 3})") + eq(r(frozenset([1, 2, 3, 4, 5, 6])), "frozenset({1, 2, 3, 4, 5, 6})") + eq(r(frozenset([1, 2, 3, 4, 5, 6, 7])), "frozenset({1, 2, 3, 4, 5, 6, ...})") # collections.deque after 6 eq(r(deque([1, 2, 3, 4, 5, 6, 7])), "deque([1, 2, 3, 4, 5, 6, ...])") @@ -94,7 +94,7 @@ def test_container(self): eq(r(d), "{'alice': 1, 'arthur': 1, 'bob': 2, 'charles': 3, ...}") # array.array after 5. - eq(r(array('i')), "array('i', [])") + eq(r(array('i')), "array('i')") eq(r(array('i', [1])), "array('i', [1])") eq(r(array('i', [1, 2])), "array('i', [1, 2])") eq(r(array('i', [1, 2, 3])), "array('i', [1, 2, 3])") @@ -103,6 +103,20 @@ def test_container(self): eq(r(array('i', [1, 2, 3, 4, 5, 6])), "array('i', [1, 2, 3, 4, 5, ...])") + def test_set_literal(self): + eq = self.assertEqual + eq(r({1}), "{1}") + eq(r({1, 2, 3}), "{1, 2, 3}") + eq(r({1, 2, 3, 4, 5, 6}), "{1, 2, 3, 4, 5, 6}") + eq(r({1, 2, 3, 4, 5, 6, 7}), "{1, 2, 3, 4, 5, 6, ...}") + + def test_frozenset(self): + eq = self.assertEqual + eq(r(frozenset({1})), "frozenset({1})") + eq(r(frozenset({1, 2, 3})), "frozenset({1, 2, 3})") + eq(r(frozenset({1, 2, 3, 4, 5, 6})), "frozenset({1, 2, 3, 4, 5, 6})") + eq(r(frozenset({1, 2, 3, 4, 5, 6, 7})), "frozenset({1, 2, 3, 4, 5, 6, ...})") + def test_numbers(self): eq = self.assertEqual eq(r(123), repr(123)) @@ -123,7 +137,7 @@ def test_instance(self): eq(r(i2), expected) i3 = ClassWithFailingRepr() - eq(r(i3), (""%id(i3))) + eq(r(i3), (""%id(i3))) s = r(ClassWithFailingRepr) self.assertTrue(s.startswith("') + self.assertRegex(r(x), r'') def test_descriptors(self): eq = self.assertEqual @@ -274,6 +295,7 @@ class foo(object): eq(repr(foo.foo), "" % foo.__name__) + @unittest.skip('need a suitable object') def test_object(self): # XXX Test the repr of a type with a really long tp_name but with no # tp_repr. WIBNI we had ::Inline? :) @@ -321,6 +343,7 @@ def amethod(self): pass '') -def test_main(): - run_unittest(ReprTests) - run_unittest(LongReprTest) - run_unittest(TestRecursiveRepr) - - if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_resource.py b/Lib/test/test_resource.py index 006198fc410b..2ecae0fc450a 100644 --- a/Lib/test/test_resource.py +++ b/Lib/test/test_resource.py @@ -138,6 +138,12 @@ def test_linux_constants(self): with contextlib.suppress(AttributeError): self.assertIsInstance(getattr(resource, 'RLIMIT_' + attr), int) + @support.requires_freebsd_version(9) + def test_freebsd_contants(self): + for attr in ['SWAP', 'SBSIZE', 'NPTS']: + with contextlib.suppress(AttributeError): + self.assertIsInstance(getattr(resource, 'RLIMIT_' + attr), int) + @unittest.skipUnless(hasattr(resource, 'prlimit'), 'no prlimit') @support.requires_linux_version(2, 6, 36) def test_prlimit(self): diff --git a/Lib/test/test_robotparser.py b/Lib/test/test_robotparser.py index d1dfd9eeec02..d01266f330eb 100644 --- a/Lib/test/test_robotparser.py +++ b/Lib/test/test_robotparser.py @@ -4,6 +4,12 @@ from urllib.error import URLError, HTTPError from urllib.request import urlopen from test import support +from http.server import BaseHTTPRequestHandler, HTTPServer +try: + import threading +except ImportError: + threading = None + class RobotTestCase(unittest.TestCase): def __init__(self, index=None, parser=None, url=None, good=None, agent=None): @@ -247,34 +253,54 @@ def RobotTest(index, robots_txt, good_urls, bad_urls, RobotTest(16, doc, good, bad) -class NetworkTestCase(unittest.TestCase): +class RobotHandler(BaseHTTPRequestHandler): + + def do_GET(self): + self.send_error(403, "Forbidden access") + + def log_message(self, format, *args): + pass + + +@unittest.skipUnless(threading, 'threading required for this test') +class PasswordProtectedSiteTestCase(unittest.TestCase): + + def setUp(self): + self.server = HTTPServer((support.HOST, 0), RobotHandler) + + self.t = threading.Thread( + name='HTTPServer serving', + 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.t.daemon = True # In case this function raises. + self.t.start() + + def tearDown(self): + self.server.shutdown() + self.t.join() + self.server.server_close() + + def runTest(self): + self.testPasswordProtectedSite() def testPasswordProtectedSite(self): - support.requires('network') - with support.transient_internet('mueblesmoraleda.com'): - url = 'http://mueblesmoraleda.com' - robots_url = url + "/robots.txt" - # First check the URL is usable for our purposes, since the - # test site is a bit flaky. - try: - urlopen(robots_url) - except HTTPError as e: - if e.code not in {401, 403}: - self.skipTest( - "%r should return a 401 or 403 HTTP error, not %r" - % (robots_url, e.code)) - else: - self.skipTest( - "%r should return a 401 or 403 HTTP error, not succeed" - % (robots_url)) - parser = urllib.robotparser.RobotFileParser() - parser.set_url(url) - try: - parser.read() - except URLError: - self.skipTest('%s is unavailable' % url) - self.assertEqual(parser.can_fetch("*", robots_url), False) + addr = self.server.server_address + url = 'http://' + support.HOST + ':' + str(addr[1]) + robots_url = url + "/robots.txt" + parser = urllib.robotparser.RobotFileParser() + parser.set_url(url) + parser.read() + self.assertFalse(parser.can_fetch("*", robots_url)) + + def __str__(self): + return '%s' % self.__class__.__name__ + +class NetworkTestCase(unittest.TestCase): + @unittest.skip('does not handle the gzip encoding delivered by pydotorg') def testPythonOrg(self): support.requires('network') with support.transient_internet('www.python.org'): @@ -287,8 +313,8 @@ def testPythonOrg(self): def load_tests(loader, suite, pattern): suite = unittest.makeSuite(NetworkTestCase) suite.addTest(tests) + suite.addTest(PasswordProtectedSiteTestCase()) return suite if __name__=='__main__': - support.use_resources = ['network'] unittest.main() diff --git a/Lib/test/test_runpy.py b/Lib/test/test_runpy.py index f19c4ab7ebe9..786b813b32e7 100644 --- a/Lib/test/test_runpy.py +++ b/Lib/test/test_runpy.py @@ -5,7 +5,7 @@ import sys import re import tempfile -import importlib +import importlib, importlib.machinery, importlib.util import py_compile from test.support import ( forget, make_legacy_pyc, run_unittest, unload, verbose, no_tracing, @@ -47,7 +47,7 @@ def f(): "__cached__": None, "__package__": None, "__doc__": None, -# "__spec__": None, # XXX Uncomment. + "__spec__": None } example_namespace = { "sys": sys, @@ -57,7 +57,7 @@ def f(): "run_name_in_sys_modules": False, "module_in_sys_modules": False, "nested": dict(implicit_namespace, - x=1, __name__="", __loader__=None, __spec__=None), + x=1, __name__="", __loader__=None), } example_namespace.update(implicit_namespace) @@ -68,11 +68,19 @@ class CodeExecutionMixin: # testing occurs at those upper layers as well, not just at the utility # layer + # Figuring out the loader details in advance is hard to do, so we skip + # checking the full details of loader and loader_state + CHECKED_SPEC_ATTRIBUTES = ["name", "parent", "origin", "cached", + "has_location", "submodule_search_locations"] + def assertNamespaceMatches(self, result_ns, expected_ns): """Check two namespaces match. Ignores any unspecified interpreter created names """ + # Avoid side effects + result_ns = result_ns.copy() + expected_ns = expected_ns.copy() # Impls are permitted to add extra names, so filter them out for k in list(result_ns): if k.startswith("__") and k.endswith("__"): @@ -80,7 +88,25 @@ def assertNamespaceMatches(self, result_ns, expected_ns): result_ns.pop(k) if k not in expected_ns["nested"]: result_ns["nested"].pop(k) - # Don't use direct dict comparison - the diffs are too hard to debug + # Spec equality includes the loader, so we take the spec out of the + # result namespace and check that separately + result_spec = result_ns.pop("__spec__") + expected_spec = expected_ns.pop("__spec__") + if expected_spec is None: + self.assertIsNone(result_spec) + else: + # If an expected loader is set, we just check we got the right + # type, rather than checking for full equality + if expected_spec.loader is not None: + self.assertEqual(type(result_spec.loader), + type(expected_spec.loader)) + for attr in self.CHECKED_SPEC_ATTRIBUTES: + k = "__spec__." + attr + actual = (k, getattr(result_spec, attr)) + expected = (k, getattr(expected_spec, attr)) + self.assertEqual(actual, expected) + # For the rest, we still don't use direct dict comparison on the + # namespace, as the diffs are too hard to debug if anything breaks self.assertEqual(set(result_ns), set(expected_ns)) for k in result_ns: actual = (k, result_ns[k]) @@ -131,12 +157,16 @@ def test_run_module_code(self): mod_fname = "Some other nonsense" mod_loader = "Now you're just being silly" mod_package = '' # Treat as a top level module + mod_spec = importlib.machinery.ModuleSpec(mod_name, + origin=mod_fname, + loader=mod_loader) expected_ns = example_namespace.copy() expected_ns.update({ "__name__": mod_name, "__file__": mod_fname, "__loader__": mod_loader, "__package__": mod_package, + "__spec__": mod_spec, "run_argv0": mod_fname, "run_name_in_sys_modules": True, "module_in_sys_modules": True, @@ -145,9 +175,7 @@ def create_ns(init_globals): return _run_module_code(example_source, init_globals, mod_name, - mod_fname, - mod_loader, - mod_package) + mod_spec) self.check_code_execution(create_ns, expected_ns) # TODO: Use self.addCleanup to get rid of a lot of try-finally blocks @@ -177,31 +205,43 @@ def test_invalid_names(self): def test_library_module(self): self.assertEqual(run_module("runpy")["__name__"], "runpy") - def _add_pkg_dir(self, pkg_dir): + def _add_pkg_dir(self, pkg_dir, namespace=False): os.mkdir(pkg_dir) + if namespace: + return None pkg_fname = os.path.join(pkg_dir, "__init__.py") create_empty_file(pkg_fname) return pkg_fname - def _make_pkg(self, source, depth, mod_base="runpy_test"): + def _make_pkg(self, source, depth, mod_base="runpy_test", + *, namespace=False, parent_namespaces=False): + # Enforce a couple of internal sanity checks on test cases + if (namespace or parent_namespaces) and not depth: + raise RuntimeError("Can't mark top level module as a " + "namespace package") pkg_name = "__runpy_pkg__" test_fname = mod_base+os.extsep+"py" pkg_dir = sub_dir = os.path.realpath(tempfile.mkdtemp()) if verbose > 1: print(" Package tree in:", sub_dir) sys.path.insert(0, pkg_dir) if verbose > 1: print(" Updated sys.path:", sys.path[0]) - for i in range(depth): - sub_dir = os.path.join(sub_dir, pkg_name) - pkg_fname = self._add_pkg_dir(sub_dir) - if verbose > 1: print(" Next level in:", sub_dir) - if verbose > 1: print(" Created:", pkg_fname) + if depth: + namespace_flags = [parent_namespaces] * depth + namespace_flags[-1] = namespace + for namespace_flag in namespace_flags: + sub_dir = os.path.join(sub_dir, pkg_name) + pkg_fname = self._add_pkg_dir(sub_dir, namespace_flag) + if verbose > 1: print(" Next level in:", sub_dir) + if verbose > 1: print(" Created:", pkg_fname) mod_fname = os.path.join(sub_dir, test_fname) mod_file = open(mod_fname, "w") mod_file.write(source) mod_file.close() if verbose > 1: print(" Created:", mod_fname) mod_name = (pkg_name+".")*depth + mod_base - return pkg_dir, mod_fname, mod_name + mod_spec = importlib.util.spec_from_file_location(mod_name, + mod_fname) + return pkg_dir, mod_fname, mod_name, mod_spec def _del_pkg(self, top, depth, mod_name): for entry in list(sys.modules): @@ -231,20 +271,29 @@ def _del_pkg(self, top, depth, mod_name): def _fix_ns_for_legacy_pyc(self, ns, alter_sys): char_to_add = "c" if __debug__ else "o" ns["__file__"] += char_to_add + ns["__cached__"] = ns["__file__"] + spec = ns["__spec__"] + new_spec = importlib.util.spec_from_file_location(spec.name, + ns["__file__"]) + ns["__spec__"] = new_spec if alter_sys: ns["run_argv0"] += char_to_add - def _check_module(self, depth, alter_sys=False): - pkg_dir, mod_fname, mod_name = ( - self._make_pkg(example_source, depth)) + def _check_module(self, depth, alter_sys=False, + *, namespace=False, parent_namespaces=False): + pkg_dir, mod_fname, mod_name, mod_spec = ( + self._make_pkg(example_source, depth, + namespace=namespace, + parent_namespaces=parent_namespaces)) forget(mod_name) expected_ns = example_namespace.copy() expected_ns.update({ "__name__": mod_name, "__file__": mod_fname, + "__cached__": mod_spec.cached, "__package__": mod_name.rpartition(".")[0], -# "__spec__": None, # XXX Needs to be set. + "__spec__": mod_spec, }) if alter_sys: expected_ns.update({ @@ -271,17 +320,21 @@ def create_ns(init_globals): self._del_pkg(pkg_dir, depth, mod_name) if verbose > 1: print("Module executed successfully") - def _check_package(self, depth, alter_sys=False): - pkg_dir, mod_fname, mod_name = ( - self._make_pkg(example_source, depth, "__main__")) + def _check_package(self, depth, alter_sys=False, + *, namespace=False, parent_namespaces=False): + pkg_dir, mod_fname, mod_name, mod_spec = ( + self._make_pkg(example_source, depth, "__main__", + namespace=namespace, + parent_namespaces=parent_namespaces)) pkg_name = mod_name.rpartition(".")[0] forget(mod_name) expected_ns = example_namespace.copy() expected_ns.update({ "__name__": mod_name, "__file__": mod_fname, + "__cached__": importlib.util.cache_from_source(mod_fname), "__package__": pkg_name, -# "__spec__": None, # XXX Needs to be set. + "__spec__": mod_spec, }) if alter_sys: expected_ns.update({ @@ -337,7 +390,7 @@ def _check_relative_imports(self, depth, run_name=None): from . import sibling from ..uncle.cousin import nephew """ - pkg_dir, mod_fname, mod_name = ( + pkg_dir, mod_fname, mod_name, mod_spec = ( self._make_pkg(contents, depth)) if run_name is None: expected_name = mod_name @@ -376,11 +429,31 @@ def test_run_module(self): if verbose > 1: print("Testing package depth:", depth) self._check_module(depth) + def test_run_module_in_namespace_package(self): + for depth in range(1, 4): + if verbose > 1: print("Testing package depth:", depth) + self._check_module(depth, namespace=True, parent_namespaces=True) + def test_run_package(self): for depth in range(1, 4): if verbose > 1: print("Testing package depth:", depth) self._check_package(depth) + def test_run_package_in_namespace_package(self): + for depth in range(1, 4): + if verbose > 1: print("Testing package depth:", depth) + self._check_package(depth, parent_namespaces=True) + + def test_run_namespace_package(self): + for depth in range(1, 4): + if verbose > 1: print("Testing package depth:", depth) + self._check_package(depth, namespace=True) + + def test_run_namespace_package_in_namespace_package(self): + for depth in range(1, 4): + if verbose > 1: print("Testing package depth:", depth) + self._check_package(depth, namespace=True, parent_namespaces=True) + def test_run_module_alter_sys(self): for depth in range(4): if verbose > 1: print("Testing package depth:", depth) @@ -404,14 +477,16 @@ def test_main_relative_import(self): def test_run_name(self): depth = 1 run_name = "And now for something completely different" - pkg_dir, mod_fname, mod_name = ( + pkg_dir, mod_fname, mod_name, mod_spec = ( self._make_pkg(example_source, depth)) forget(mod_name) expected_ns = example_namespace.copy() expected_ns.update({ "__name__": run_name, "__file__": mod_fname, + "__cached__": importlib.util.cache_from_source(mod_fname), "__package__": mod_name.rpartition(".")[0], + "__spec__": mod_spec, }) def create_ns(init_globals): return run_module(mod_name, init_globals, run_name) @@ -440,7 +515,7 @@ def test_pkgutil_walk_packages(self): pkg_name = ".".join([base_name] * max_depth) expected_packages.add(pkg_name) expected_modules.add(pkg_name + ".runpy_test") - pkg_dir, mod_fname, mod_name = ( + pkg_dir, mod_fname, mod_name, mod_spec = ( self._make_pkg("", max_depth)) self.addCleanup(self._del_pkg, pkg_dir, max_depth, mod_name) for depth in range(2, max_depth+1): @@ -458,21 +533,39 @@ def test_pkgutil_walk_packages(self): class RunPathTestCase(unittest.TestCase, CodeExecutionMixin): """Unit tests for runpy.run_path""" - def _make_test_script(self, script_dir, script_basename, source=None): + def _make_test_script(self, script_dir, script_basename, + source=None, omit_suffix=False): if source is None: source = example_source - return make_script(script_dir, script_basename, source) + return make_script(script_dir, script_basename, + source, omit_suffix) def _check_script(self, script_name, expected_name, expected_file, - expected_argv0): + expected_argv0, mod_name=None, + expect_spec=True, check_loader=True): # First check is without run_name def create_ns(init_globals): return run_path(script_name, init_globals) expected_ns = example_namespace.copy() + if mod_name is None: + spec_name = expected_name + else: + spec_name = mod_name + if expect_spec: + mod_spec = importlib.util.spec_from_file_location(spec_name, + expected_file) + mod_cached = mod_spec.cached + if not check_loader: + mod_spec.loader = None + else: + mod_spec = mod_cached = None + expected_ns.update({ "__name__": expected_name, "__file__": expected_file, + "__cached__": mod_cached, "__package__": "", + "__spec__": mod_spec, "run_argv0": expected_argv0, "run_name_in_sys_modules": True, "module_in_sys_modules": True, @@ -482,6 +575,12 @@ def create_ns(init_globals): run_name = "prove.issue15230.is.fixed" def create_ns(init_globals): return run_path(script_name, init_globals, run_name) + if expect_spec and mod_name is None: + mod_spec = importlib.util.spec_from_file_location(run_name, + expected_file) + if not check_loader: + mod_spec.loader = None + expected_ns["__spec__"] = mod_spec expected_ns["__name__"] = run_name expected_ns["__package__"] = run_name.rpartition(".")[0] self.check_code_execution(create_ns, expected_ns) @@ -495,7 +594,15 @@ def test_basic_script(self): mod_name = 'script' script_name = self._make_test_script(script_dir, mod_name) self._check_script(script_name, "", script_name, - script_name) + script_name, expect_spec=False) + + def test_basic_script_no_suffix(self): + with temp_dir() as script_dir: + mod_name = 'script' + script_name = self._make_test_script(script_dir, mod_name, + omit_suffix=True) + self._check_script(script_name, "", script_name, + script_name, expect_spec=False) def test_script_compiled(self): with temp_dir() as script_dir: @@ -504,14 +611,14 @@ def test_script_compiled(self): compiled_name = py_compile.compile(script_name, doraise=True) os.remove(script_name) self._check_script(compiled_name, "", compiled_name, - compiled_name) + compiled_name, expect_spec=False) def test_directory(self): with temp_dir() as script_dir: mod_name = '__main__' script_name = self._make_test_script(script_dir, mod_name) self._check_script(script_dir, "", script_name, - script_dir) + script_dir, mod_name=mod_name) def test_directory_compiled(self): with temp_dir() as script_dir: @@ -522,7 +629,7 @@ def test_directory_compiled(self): if not sys.dont_write_bytecode: legacy_pyc = make_legacy_pyc(script_name) self._check_script(script_dir, "", legacy_pyc, - script_dir) + script_dir, mod_name=mod_name) def test_directory_error(self): with temp_dir() as script_dir: @@ -536,7 +643,8 @@ def test_zipfile(self): mod_name = '__main__' script_name = self._make_test_script(script_dir, mod_name) zip_name, fname = make_zip_script(script_dir, 'test_zip', script_name) - self._check_script(zip_name, "", fname, zip_name) + self._check_script(zip_name, "", fname, zip_name, + mod_name=mod_name, check_loader=False) def test_zipfile_compiled(self): with temp_dir() as script_dir: @@ -545,7 +653,8 @@ def test_zipfile_compiled(self): compiled_name = py_compile.compile(script_name, doraise=True) zip_name, fname = make_zip_script(script_dir, 'test_zip', compiled_name) - self._check_script(zip_name, "", fname, zip_name) + self._check_script(zip_name, "", fname, zip_name, + mod_name=mod_name, check_loader=False) def test_zipfile_error(self): with temp_dir() as script_dir: diff --git a/Lib/test/test_sax.py b/Lib/test/test_sax.py index cfa18f7da5e0..a6238b278617 100644 --- a/Lib/test/test_sax.py +++ b/Lib/test/test_sax.py @@ -648,6 +648,30 @@ def test_expat_file_nonascii(self): self.assertEqual(result.getvalue(), xml_test_out) + def test_expat_binary_file_bytes_name(self): + fname = os.fsencode(TEST_XMLFILE) + parser = create_parser() + result = BytesIO() + xmlgen = XMLGenerator(result) + + parser.setContentHandler(xmlgen) + with open(fname, 'rb') as f: + parser.parse(f) + + self.assertEqual(result.getvalue(), xml_test_out) + + def test_expat_binary_file_int_name(self): + parser = create_parser() + result = BytesIO() + xmlgen = XMLGenerator(result) + + parser.setContentHandler(xmlgen) + with open(TEST_XMLFILE, 'rb') as f: + with open(f.fileno(), 'rb', closefd=False) as f2: + parser.parse(f2) + + self.assertEqual(result.getvalue(), xml_test_out) + # ===== DTDHandler support class TestDTDHandler: diff --git a/Lib/test/test_sched.py b/Lib/test/test_sched.py index c6abf3d89a29..fe8e7850920d 100644 --- a/Lib/test/test_sched.py +++ b/Lib/test/test_sched.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - import queue import sched import time diff --git a/Lib/test/test_script_helper.py b/Lib/test/test_script_helper.py new file mode 100755 index 000000000000..74333c9db8fc --- /dev/null +++ b/Lib/test/test_script_helper.py @@ -0,0 +1,109 @@ +"""Unittests for test.script_helper. Who tests the test helper?""" + +import subprocess +import sys +from test import script_helper +import unittest +from unittest import mock + + +class TestScriptHelper(unittest.TestCase): + def test_assert_python_expect_success(self): + t = script_helper._assert_python(True, '-c', 'import sys; sys.exit(0)') + self.assertEqual(0, t[0], 'return code was not 0') + + def test_assert_python_expect_failure(self): + # I didn't import the sys module so this child will fail. + rc, out, err = script_helper._assert_python(False, '-c', 'sys.exit(0)') + self.assertNotEqual(0, rc, 'return code should not be 0') + + def test_assert_python_raises_expect_success(self): + # I didn't import the sys module so this child will fail. + with self.assertRaises(AssertionError) as error_context: + script_helper._assert_python(True, '-c', 'sys.exit(0)') + error_msg = str(error_context.exception) + self.assertIn('command line was:', error_msg) + self.assertIn('sys.exit(0)', error_msg, msg='unexpected command line') + + def test_assert_python_raises_expect_failure(self): + with self.assertRaises(AssertionError) as error_context: + script_helper._assert_python(False, '-c', 'import sys; sys.exit(0)') + error_msg = str(error_context.exception) + self.assertIn('Process return code is 0,', error_msg) + self.assertIn('import sys; sys.exit(0)', error_msg, + msg='unexpected command line.') + + @mock.patch('subprocess.Popen') + def test_assert_python_isolated_when_env_not_required(self, mock_popen): + with mock.patch.object(script_helper, + 'interpreter_requires_environment', + return_value=False) as mock_ire_func: + mock_popen.side_effect = RuntimeError('bail out of unittest') + try: + script_helper._assert_python(True, '-c', 'None') + except RuntimeError as err: + self.assertEqual('bail out of unittest', err.args[0]) + self.assertEqual(1, mock_popen.call_count) + self.assertEqual(1, mock_ire_func.call_count) + popen_command = mock_popen.call_args[0][0] + self.assertEqual(sys.executable, popen_command[0]) + self.assertIn('None', popen_command) + self.assertIn('-I', popen_command) + self.assertNotIn('-E', popen_command) # -I overrides this + + @mock.patch('subprocess.Popen') + def test_assert_python_not_isolated_when_env_is_required(self, mock_popen): + """Ensure that -I is not passed when the environment is required.""" + with mock.patch.object(script_helper, + 'interpreter_requires_environment', + return_value=True) as mock_ire_func: + mock_popen.side_effect = RuntimeError('bail out of unittest') + try: + script_helper._assert_python(True, '-c', 'None') + except RuntimeError as err: + self.assertEqual('bail out of unittest', err.args[0]) + popen_command = mock_popen.call_args[0][0] + self.assertNotIn('-I', popen_command) + self.assertNotIn('-E', popen_command) + + +class TestScriptHelperEnvironment(unittest.TestCase): + """Code coverage for interpreter_requires_environment().""" + + def setUp(self): + self.assertTrue( + hasattr(script_helper, '__cached_interp_requires_environment')) + # Reset the private cached state. + script_helper.__dict__['__cached_interp_requires_environment'] = None + + def tearDown(self): + # Reset the private cached state. + script_helper.__dict__['__cached_interp_requires_environment'] = None + + @mock.patch('subprocess.check_call') + def test_interpreter_requires_environment_true(self, mock_check_call): + mock_check_call.side_effect = subprocess.CalledProcessError('', '') + self.assertTrue(script_helper.interpreter_requires_environment()) + self.assertTrue(script_helper.interpreter_requires_environment()) + self.assertEqual(1, mock_check_call.call_count) + + @mock.patch('subprocess.check_call') + def test_interpreter_requires_environment_false(self, mock_check_call): + # The mocked subprocess.check_call fakes a no-error process. + script_helper.interpreter_requires_environment() + self.assertFalse(script_helper.interpreter_requires_environment()) + self.assertEqual(1, mock_check_call.call_count) + + @mock.patch('subprocess.check_call') + def test_interpreter_requires_environment_details(self, mock_check_call): + script_helper.interpreter_requires_environment() + self.assertFalse(script_helper.interpreter_requires_environment()) + self.assertFalse(script_helper.interpreter_requires_environment()) + self.assertEqual(1, mock_check_call.call_count) + check_call_command = mock_check_call.call_args[0][0] + self.assertEqual(sys.executable, check_call_command[0]) + self.assertIn('-E', check_call_command) + + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_selectors.py b/Lib/test/test_selectors.py index f5e67b100598..9521481901ba 100644 --- a/Lib/test/test_selectors.py +++ b/Lib/test/test_selectors.py @@ -1,16 +1,15 @@ import errno +import os import random import selectors import signal import socket +import sys from test import support from time import sleep import unittest import unittest.mock -try: - from time import monotonic as time -except ImportError: - from time import time as time +from time import monotonic as time try: import resource except ImportError: @@ -23,7 +22,7 @@ def socketpair(family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0): with socket.socket(family, type, proto) as l: l.bind((support.HOST, 0)) - l.listen(3) + l.listen() c = socket.socket(family, type, proto) try: c.connect(l.getsockname()) @@ -49,13 +48,17 @@ def find_ready_matching(ready, flag): class BaseSelectorTestCase(unittest.TestCase): + def make_socketpair(self): + rd, wr = socketpair() + self.addCleanup(rd.close) + self.addCleanup(wr.close) + return rd, wr + def test_register(self): s = self.SELECTOR() self.addCleanup(s.close) - rd, wr = socketpair() - self.addCleanup(rd.close) - self.addCleanup(wr.close) + rd, wr = self.make_socketpair() key = s.register(rd, selectors.EVENT_READ, "data") self.assertIsInstance(key, selectors.SelectorKey) @@ -81,9 +84,7 @@ def test_unregister(self): s = self.SELECTOR() self.addCleanup(s.close) - rd, wr = socketpair() - self.addCleanup(rd.close) - self.addCleanup(wr.close) + rd, wr = self.make_socketpair() s.register(rd, selectors.EVENT_READ) s.unregister(rd) @@ -94,13 +95,52 @@ def test_unregister(self): # unregister twice self.assertRaises(KeyError, s.unregister, rd) + def test_unregister_after_fd_close(self): + s = self.SELECTOR() + self.addCleanup(s.close) + rd, wr = self.make_socketpair() + r, w = rd.fileno(), wr.fileno() + s.register(r, selectors.EVENT_READ) + s.register(w, selectors.EVENT_WRITE) + rd.close() + wr.close() + s.unregister(r) + s.unregister(w) + + @unittest.skipUnless(os.name == 'posix', "requires posix") + def test_unregister_after_fd_close_and_reuse(self): + s = self.SELECTOR() + self.addCleanup(s.close) + rd, wr = self.make_socketpair() + r, w = rd.fileno(), wr.fileno() + s.register(r, selectors.EVENT_READ) + s.register(w, selectors.EVENT_WRITE) + rd2, wr2 = self.make_socketpair() + rd.close() + wr.close() + os.dup2(rd2.fileno(), r) + os.dup2(wr2.fileno(), w) + self.addCleanup(os.close, r) + self.addCleanup(os.close, w) + s.unregister(r) + s.unregister(w) + + def test_unregister_after_socket_close(self): + s = self.SELECTOR() + self.addCleanup(s.close) + rd, wr = self.make_socketpair() + s.register(rd, selectors.EVENT_READ) + s.register(wr, selectors.EVENT_WRITE) + rd.close() + wr.close() + s.unregister(rd) + s.unregister(wr) + def test_modify(self): s = self.SELECTOR() self.addCleanup(s.close) - rd, wr = socketpair() - self.addCleanup(rd.close) - self.addCleanup(wr.close) + rd, wr = self.make_socketpair() key = s.register(rd, selectors.EVENT_READ) @@ -138,24 +178,23 @@ def test_close(self): s = self.SELECTOR() self.addCleanup(s.close) - rd, wr = socketpair() - self.addCleanup(rd.close) - self.addCleanup(wr.close) + mapping = s.get_map() + rd, wr = self.make_socketpair() s.register(rd, selectors.EVENT_READ) s.register(wr, selectors.EVENT_WRITE) s.close() - self.assertRaises(KeyError, s.get_key, rd) - self.assertRaises(KeyError, s.get_key, wr) + self.assertRaises(RuntimeError, s.get_key, rd) + self.assertRaises(RuntimeError, s.get_key, wr) + self.assertRaises(KeyError, mapping.__getitem__, rd) + self.assertRaises(KeyError, mapping.__getitem__, wr) def test_get_key(self): s = self.SELECTOR() self.addCleanup(s.close) - rd, wr = socketpair() - self.addCleanup(rd.close) - self.addCleanup(wr.close) + rd, wr = self.make_socketpair() key = s.register(rd, selectors.EVENT_READ, "data") self.assertEqual(key, s.get_key(rd)) @@ -167,9 +206,7 @@ def test_get_map(self): s = self.SELECTOR() self.addCleanup(s.close) - rd, wr = socketpair() - self.addCleanup(rd.close) - self.addCleanup(wr.close) + rd, wr = self.make_socketpair() keys = s.get_map() self.assertFalse(keys) @@ -194,9 +231,7 @@ def test_select(self): s = self.SELECTOR() self.addCleanup(s.close) - rd, wr = socketpair() - self.addCleanup(rd.close) - self.addCleanup(wr.close) + rd, wr = self.make_socketpair() s.register(rd, selectors.EVENT_READ) wr_key = s.register(wr, selectors.EVENT_WRITE) @@ -214,16 +249,14 @@ def test_context_manager(self): s = self.SELECTOR() self.addCleanup(s.close) - rd, wr = socketpair() - self.addCleanup(rd.close) - self.addCleanup(wr.close) + rd, wr = self.make_socketpair() with s as sel: sel.register(rd, selectors.EVENT_READ) sel.register(wr, selectors.EVENT_WRITE) - self.assertRaises(KeyError, s.get_key, rd) - self.assertRaises(KeyError, s.get_key, wr) + self.assertRaises(RuntimeError, s.get_key, rd) + self.assertRaises(RuntimeError, s.get_key, wr) def test_fileno(self): s = self.SELECTOR() @@ -247,9 +280,7 @@ def test_selector(self): w2r = {} for i in range(NUM_SOCKETS): - rd, wr = socketpair() - self.addCleanup(rd.close) - self.addCleanup(wr.close) + rd, wr = self.make_socketpair() s.register(rd, selectors.EVENT_READ) s.register(wr, selectors.EVENT_WRITE) readers.append(rd) @@ -289,13 +320,20 @@ def test_selector(self): self.assertEqual(bufs, [MSG] * NUM_SOCKETS) + @unittest.skipIf(sys.platform == 'win32', + 'select.select() cannot be used with empty fd sets') + def test_empty_select(self): + # Issue #23009: Make sure EpollSelector.select() works when no FD is + # registered. + s = self.SELECTOR() + self.addCleanup(s.close) + self.assertEqual(s.select(timeout=0), []) + def test_timeout(self): s = self.SELECTOR() self.addCleanup(s.close) - rd, wr = socketpair() - self.addCleanup(rd.close) - self.addCleanup(wr.close) + rd, wr = self.make_socketpair() s.register(wr, selectors.EVENT_WRITE) t = time() @@ -314,7 +352,8 @@ def test_timeout(self): self.assertFalse(s.select(1)) t1 = time() dt = t1 - t0 - self.assertTrue(0.8 <= dt <= 1.6, dt) + # Tolerate 2.0 seconds for very slow buildbots + self.assertTrue(0.8 <= dt <= 2.0, dt) @unittest.skipUnless(hasattr(signal, "alarm"), "signal.alarm() required for this test") @@ -322,9 +361,7 @@ def test_select_interrupt(self): s = self.SELECTOR() self.addCleanup(s.close) - rd, wr = socketpair() - self.addCleanup(rd.close) - self.addCleanup(wr.close) + rd, wr = self.make_socketpair() orig_alrm_handler = signal.signal(signal.SIGALRM, lambda *args: None) self.addCleanup(signal.signal, signal.SIGALRM, orig_alrm_handler) @@ -352,7 +389,7 @@ def test_above_fd_setsize(self): resource.setrlimit(resource.RLIMIT_NOFILE, (hard, hard)) self.addCleanup(resource.setrlimit, resource.RLIMIT_NOFILE, (soft, hard)) - NUM_FDS = hard + NUM_FDS = min(hard, 2**16) except (OSError, ValueError): NUM_FDS = soft @@ -364,16 +401,13 @@ def test_above_fd_setsize(self): for i in range(NUM_FDS // 2): try: - rd, wr = socketpair() + rd, wr = self.make_socketpair() except OSError: # too many FDs, skip - note that we should only catch EMFILE # here, but apparently *BSD and Solaris can fail upon connect() # or bind() with EADDRNOTAVAIL, so let's be safe self.skipTest("FD limit reached") - self.addCleanup(rd.close) - self.addCleanup(wr.close) - try: s.register(rd, selectors.EVENT_READ) s.register(wr, selectors.EVENT_WRITE) @@ -418,10 +452,18 @@ class KqueueSelectorTestCase(BaseSelectorTestCase, ScalableSelectorMixIn): SELECTOR = getattr(selectors, 'KqueueSelector', None) +@unittest.skipUnless(hasattr(selectors, 'DevpollSelector'), + "Test needs selectors.DevpollSelector") +class DevpollSelectorTestCase(BaseSelectorTestCase, ScalableSelectorMixIn): + + SELECTOR = getattr(selectors, 'DevpollSelector', None) + + + def test_main(): tests = [DefaultSelectorTestCase, SelectSelectorTestCase, PollSelectorTestCase, EpollSelectorTestCase, - KqueueSelectorTestCase] + KqueueSelectorTestCase, DevpollSelectorTestCase] support.run_unittest(*tests) support.reap_children() diff --git a/Lib/test/test_set.py b/Lib/test/test_set.py index bfef6210939d..c25386fad6d5 100644 --- a/Lib/test/test_set.py +++ b/Lib/test/test_set.py @@ -231,29 +231,30 @@ def test_pickling(self): self.assertEqual(self.s, dup, "%s != %s" % (self.s, dup)) if type(self.s) not in (set, frozenset): self.s.x = 10 - p = pickle.dumps(self.s) + p = pickle.dumps(self.s, i) dup = pickle.loads(p) self.assertEqual(self.s.x, dup.x) def test_iterator_pickling(self): - itorg = iter(self.s) - data = self.thetype(self.s) - d = pickle.dumps(itorg) - it = pickle.loads(d) - # Set iterators unpickle as list iterators due to the - # undefined order of set items. - # self.assertEqual(type(itorg), type(it)) - self.assertTrue(isinstance(it, collections.abc.Iterator)) - self.assertEqual(self.thetype(it), data) - - it = pickle.loads(d) - try: - drop = next(it) - except StopIteration: - return - d = pickle.dumps(it) - it = pickle.loads(d) - self.assertEqual(self.thetype(it), data - self.thetype((drop,))) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + itorg = iter(self.s) + data = self.thetype(self.s) + d = pickle.dumps(itorg, proto) + it = pickle.loads(d) + # Set iterators unpickle as list iterators due to the + # undefined order of set items. + # self.assertEqual(type(itorg), type(it)) + self.assertIsInstance(it, collections.abc.Iterator) + self.assertEqual(self.thetype(it), data) + + it = pickle.loads(d) + try: + drop = next(it) + except StopIteration: + continue + d = pickle.dumps(it, proto) + it = pickle.loads(d) + self.assertEqual(self.thetype(it), data - self.thetype((drop,))) def test_deepcopy(self): class Tracer: @@ -851,10 +852,11 @@ def test_iteration(self): self.assertEqual(setiter.__length_hint__(), len(self.set)) def test_pickling(self): - p = pickle.dumps(self.set) - copy = pickle.loads(p) - self.assertEqual(self.set, copy, - "%s != %s" % (self.set, copy)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + p = pickle.dumps(self.set, proto) + copy = pickle.loads(p) + self.assertEqual(self.set, copy, + "%s != %s" % (self.set, copy)) #------------------------------------------------------------------------------ @@ -929,7 +931,7 @@ def test_repr(self): class TestBasicOpsBytes(TestBasicOps, unittest.TestCase): def setUp(self): - self.case = "string set" + self.case = "bytes set" self.values = [b"a", b"b", b"c"] self.set = set(self.values) self.dup = set(self.values) diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py index deb157761134..c5545ba3b32f 100644 --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -1,6 +1,7 @@ # Copyright (C) 2003 Python Software Foundation import unittest +import unittest.mock import shutil import tempfile import sys @@ -10,6 +11,7 @@ import errno import functools import subprocess +from contextlib import ExitStack from test import support from test.support import TESTFN from os.path import splitdrive @@ -32,6 +34,12 @@ except ImportError: BZ2_SUPPORTED = False +try: + import lzma + LZMA_SUPPORTED = True +except ImportError: + LZMA_SUPPORTED = False + TESTFN2 = TESTFN + "2" try: @@ -116,7 +124,9 @@ def test_rmtree_works_on_bytes(self): write_file(os.path.join(victim, 'somefile'), 'foo') victim = os.fsencode(victim) self.assertIsInstance(victim, bytes) - shutil.rmtree(victim) + win = (os.name == 'nt') + with self.assertWarns(DeprecationWarning) if win else ExitStack(): + shutil.rmtree(victim) @support.skip_unless_symlink def test_rmtree_fails_on_symlink(self): @@ -288,18 +298,20 @@ def test_copymode_follow_symlinks(self): self.assertNotEqual(os.stat(src).st_mode, os.stat(dst).st_mode) shutil.copymode(src, dst) self.assertEqual(os.stat(src).st_mode, os.stat(dst).st_mode) - # follow src link - os.chmod(dst, stat.S_IRWXO) - shutil.copymode(src_link, dst) - self.assertEqual(os.stat(src).st_mode, os.stat(dst).st_mode) - # follow dst link - os.chmod(dst, stat.S_IRWXO) - shutil.copymode(src, dst_link) - self.assertEqual(os.stat(src).st_mode, os.stat(dst).st_mode) - # follow both links - os.chmod(dst, stat.S_IRWXO) - shutil.copymode(src_link, dst) - self.assertEqual(os.stat(src).st_mode, os.stat(dst).st_mode) + # On Windows, os.chmod does not follow symlinks (issue #15411) + if os.name != 'nt': + # follow src link + os.chmod(dst, stat.S_IRWXO) + shutil.copymode(src_link, dst) + self.assertEqual(os.stat(src).st_mode, os.stat(dst).st_mode) + # follow dst link + os.chmod(dst, stat.S_IRWXO) + shutil.copymode(src, dst_link) + self.assertEqual(os.stat(src).st_mode, os.stat(dst).st_mode) + # follow both links + os.chmod(dst, stat.S_IRWXO) + shutil.copymode(src_link, dst_link) + self.assertEqual(os.stat(src).st_mode, os.stat(dst).st_mode) @unittest.skipUnless(hasattr(os, 'lchmod'), 'requires os.lchmod') @support.skip_unless_symlink @@ -429,7 +441,7 @@ def test_copyxattr(self): os.setxattr(src, 'user.foo', b'42') os.setxattr(src, 'user.bar', b'43') shutil._copyxattr(src, dst) - self.assertEqual(os.listxattr(src), os.listxattr(dst)) + self.assertEqual(sorted(os.listxattr(src)), sorted(os.listxattr(dst))) self.assertEqual( os.getxattr(src, 'user.foo'), os.getxattr(dst, 'user.foo')) @@ -753,11 +765,23 @@ def test_copytree_retains_permissions(self): self.assertEqual(os.stat(restrictive_subdir).st_mode, os.stat(restrictive_subdir_dst).st_mode) + @unittest.mock.patch('os.chmod') + def test_copytree_winerror(self, mock_patch): + # When copying to VFAT, copystat() raises OSError. On Windows, the + # exception object has a meaningful 'winerror' attribute, but not + # on other operating systems. Do not assume 'winerror' is set. + src_dir = tempfile.mkdtemp() + dst_dir = os.path.join(tempfile.mkdtemp(), 'destination') + self.addCleanup(shutil.rmtree, src_dir) + self.addCleanup(shutil.rmtree, os.path.dirname(dst_dir)) + + mock_patch.side_effect = PermissionError('ka-boom') + with self.assertRaises(shutil.Error): + shutil.copytree(src_dir, dst_dir) + + @unittest.skipIf(os.name == 'nt', 'temporarily disabled on Windows') @unittest.skipUnless(hasattr(os, 'link'), 'requires os.link') def test_dont_copy_file_onto_link_to_itself(self): - # Temporarily disable test on Windows. - if os.name == 'nt': - return # bug 851123. os.mkdir(TESTFN) src = os.path.join(TESTFN, 'cheese') @@ -1123,6 +1147,21 @@ def _breaks(*args, **kw): finally: unregister_archive_format('xxx') + def test_make_tarfile_in_curdir(self): + # Issue #21280 + root_dir = self.mkdtemp() + with support.change_cwd(root_dir): + self.assertEqual(make_archive('test', 'tar'), 'test.tar') + self.assertTrue(os.path.isfile('test.tar')) + + @requires_zlib + def test_make_zipfile_in_curdir(self): + # Issue #21280 + root_dir = self.mkdtemp() + with support.change_cwd(root_dir): + self.assertEqual(make_archive('test', 'zip'), 'test.zip') + self.assertTrue(os.path.isfile('test.zip')) + def test_register_archive_format(self): self.assertRaises(TypeError, register_archive_format, 'xxx', 1) @@ -1156,6 +1195,8 @@ def test_unpack_archive(self): formats = ['tar', 'gztar', 'zip'] if BZ2_SUPPORTED: formats.append('bztar') + if LZMA_SUPPORTED: + formats.append('xztar') for format in formats: tmpdir = self.mkdtemp() @@ -1492,6 +1533,15 @@ def test_move_dir_to_dir_other_fs(self): # Move a dir inside an existing dir on another filesystem. self.test_move_dir_to_dir() + def test_move_dir_sep_to_dir(self): + self._check_move_dir(self.src_dir + os.path.sep, self.dst_dir, + os.path.join(self.dst_dir, os.path.basename(self.src_dir))) + + @unittest.skipUnless(os.path.altsep, 'requires os.path.altsep') + def test_move_dir_altsep_to_dir(self): + self._check_move_dir(self.src_dir + os.path.altsep, self.dst_dir, + os.path.join(self.dst_dir, os.path.basename(self.src_dir))) + def test_existing_file_inside_dest_dir(self): # A file with the same name inside the destination dir already exists. with open(self.dst_file, "wb"): @@ -1556,7 +1606,11 @@ def test_move_dangling_symlink(self): dst_link = os.path.join(self.dst_dir, 'quux') shutil.move(dst, dst_link) self.assertTrue(os.path.islink(dst_link)) - self.assertEqual(os.path.realpath(src), os.path.realpath(dst_link)) + # On Windows, os.path.realpath does not follow symlinks (issue #9949) + if os.name == 'nt': + self.assertEqual(os.path.realpath(src), os.readlink(dst_link)) + else: + self.assertEqual(os.path.realpath(src), os.path.realpath(dst_link)) @support.skip_unless_symlink @mock_rename @@ -1579,6 +1633,24 @@ def test_move_as_rename_return_value(self): rv = shutil.move(self.src_file, os.path.join(self.dst_dir, 'bar')) self.assertEqual(rv, os.path.join(self.dst_dir, 'bar')) + @mock_rename + def test_move_file_special_function(self): + moved = [] + def _copy(src, dst): + moved.append((src, dst)) + shutil.move(self.src_file, self.dst_dir, copy_function=_copy) + self.assertEqual(len(moved), 1) + + @mock_rename + def test_move_dir_special_function(self): + moved = [] + def _copy(src, dst): + moved.append((src, dst)) + support.create_empty_file(os.path.join(self.src_dir, 'child')) + support.create_empty_file(os.path.join(self.src_dir, 'child1')) + shutil.move(self.src_dir, self.dst_dir, copy_function=_copy) + self.assertEqual(len(moved), 3) + class TestCopyFile(unittest.TestCase): @@ -1746,5 +1818,23 @@ def test_stty_match(self): self.assertEqual(expected, actual) +class PublicAPITests(unittest.TestCase): + """Ensures that the correct values are exposed in the public API.""" + + def test_module_all_attribute(self): + self.assertTrue(hasattr(shutil, '__all__')) + target_api = ['copyfileobj', 'copyfile', 'copymode', 'copystat', + 'copy', 'copy2', 'copytree', 'move', 'rmtree', 'Error', + 'SpecialFileError', 'ExecError', 'make_archive', + 'get_archive_formats', 'register_archive_format', + 'unregister_archive_format', 'get_unpack_formats', + 'register_unpack_format', 'unregister_unpack_format', + 'unpack_archive', 'ignore_patterns', 'chown', 'which', + 'get_terminal_size', 'SameFileError'] + if hasattr(os, 'statvfs') or os.name == 'nt': + target_api.append('disk_usage') + self.assertEqual(set(shutil.__all__), set(target_api)) + + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py index 3530d8a14ed5..774fc809a152 100644 --- a/Lib/test/test_signal.py +++ b/Lib/test/test_signal.py @@ -1,10 +1,12 @@ import unittest from test import support from contextlib import closing +import enum import gc import pickle import select import signal +import socket import struct import subprocess import traceback @@ -14,6 +16,10 @@ import threading except ImportError: threading = None +try: + import _testcapi +except ImportError: + _testcapi = None class HandlerBCalled(Exception): @@ -39,6 +45,23 @@ def ignoring_eintr(__func, *args, **kwargs): return None +class GenericTests(unittest.TestCase): + + @unittest.skipIf(threading is None, "test needs threading module") + def test_enums(self): + for name in dir(signal): + sig = getattr(signal, name) + if name in {'SIG_DFL', 'SIG_IGN'}: + self.assertIsInstance(sig, signal.Handlers) + elif name in {'SIG_BLOCK', 'SIG_UNBLOCK', 'SIG_SETMASK'}: + self.assertIsInstance(sig, signal.Sigmasks) + elif name.startswith('SIG') and not name.startswith('SIG_'): + self.assertIsInstance(sig, signal.Signals) + elif name.startswith('CTRL_'): + self.assertIsInstance(sig, signal.Signals) + self.assertEqual(sys.platform, "win32") + + @unittest.skipIf(sys.platform == "win32", "Not valid on Windows") class InterProcessSignalTests(unittest.TestCase): MAX_DURATION = 20 # Entire test should last at most 20 sec. @@ -195,6 +218,7 @@ def test_setting_signal_handler_to_none_raises_error(self): def test_getsignal(self): hup = signal.signal(signal.SIGHUP, self.trivial_signal_handler) + self.assertIsInstance(hup, signal.Handlers) self.assertEqual(signal.getsignal(signal.SIGHUP), self.trivial_signal_handler) signal.signal(signal.SIGHUP, hup) @@ -229,15 +253,77 @@ class WakeupFDTests(unittest.TestCase): def test_invalid_fd(self): fd = support.make_bad_fd() - self.assertRaises(ValueError, signal.set_wakeup_fd, fd) + self.assertRaises((ValueError, OSError), + signal.set_wakeup_fd, fd) + + def test_invalid_socket(self): + sock = socket.socket() + fd = sock.fileno() + sock.close() + self.assertRaises((ValueError, OSError), + signal.set_wakeup_fd, fd) + + def test_set_wakeup_fd_result(self): + r1, w1 = os.pipe() + self.addCleanup(os.close, r1) + self.addCleanup(os.close, w1) + r2, w2 = os.pipe() + self.addCleanup(os.close, r2) + self.addCleanup(os.close, w2) + + if hasattr(os, 'set_blocking'): + os.set_blocking(w1, False) + os.set_blocking(w2, False) + + signal.set_wakeup_fd(w1) + self.assertEqual(signal.set_wakeup_fd(w2), w1) + self.assertEqual(signal.set_wakeup_fd(-1), w2) + self.assertEqual(signal.set_wakeup_fd(-1), -1) + + def test_set_wakeup_fd_socket_result(self): + sock1 = socket.socket() + self.addCleanup(sock1.close) + sock1.setblocking(False) + fd1 = sock1.fileno() + + sock2 = socket.socket() + self.addCleanup(sock2.close) + sock2.setblocking(False) + fd2 = sock2.fileno() + + signal.set_wakeup_fd(fd1) + self.assertEqual(signal.set_wakeup_fd(fd2), fd1) + self.assertEqual(signal.set_wakeup_fd(-1), fd2) + self.assertEqual(signal.set_wakeup_fd(-1), -1) + + # On Windows, files are always blocking and Windows does not provide a + # function to test if a socket is in non-blocking mode. + @unittest.skipIf(sys.platform == "win32", "tests specific to POSIX") + def test_set_wakeup_fd_blocking(self): + rfd, wfd = os.pipe() + self.addCleanup(os.close, rfd) + self.addCleanup(os.close, wfd) + + # fd must be non-blocking + os.set_blocking(wfd, True) + with self.assertRaises(ValueError) as cm: + signal.set_wakeup_fd(wfd) + self.assertEqual(str(cm.exception), + "the fd %s must be in non-blocking mode" % wfd) + + # non-blocking is ok + os.set_blocking(wfd, False) + signal.set_wakeup_fd(wfd) + signal.set_wakeup_fd(-1) @unittest.skipIf(sys.platform == "win32", "Not valid on Windows") class WakeupSignalTests(unittest.TestCase): + @unittest.skipIf(_testcapi is None, 'need _testcapi') def check_wakeup(self, test_body, *signals, ordered=True): # use a subprocess to have only one thread code = """if 1: - import fcntl + import _testcapi import os import signal import struct @@ -260,10 +346,7 @@ def check_signum(signals): signal.signal(signal.SIGALRM, handler) read, write = os.pipe() - for fd in (read, write): - flags = fcntl.fcntl(fd, fcntl.F_GETFL, 0) - flags = flags | os.O_NONBLOCK - fcntl.fcntl(fd, fcntl.F_SETFL, flags) + os.set_blocking(write, False) signal.set_wakeup_fd(write) test() @@ -271,21 +354,21 @@ def check_signum(signals): os.close(read) os.close(write) - """.format(signals, ordered, test_body) + """.format(tuple(map(int, signals)), ordered, test_body) assert_python_ok('-c', code) + @unittest.skipIf(_testcapi is None, 'need _testcapi') def test_wakeup_write_error(self): # Issue #16105: write() errors in the C signal handler should not # pass silently. # Use a subprocess to have only one thread. code = """if 1: + import _testcapi import errno - import fcntl import os import signal import sys - import time from test.support import captured_stderr def handler(signum, frame): @@ -293,15 +376,13 @@ def handler(signum, frame): signal.signal(signal.SIGALRM, handler) r, w = os.pipe() - flags = fcntl.fcntl(r, fcntl.F_GETFL, 0) - fcntl.fcntl(r, fcntl.F_SETFL, flags | os.O_NONBLOCK) + os.set_blocking(r, False) # Set wakeup_fd a read-only file descriptor to trigger the error signal.set_wakeup_fd(r) try: with captured_stderr() as err: - signal.alarm(1) - time.sleep(5.0) + _testcapi.raise_signal(signal.SIGALRM) except ZeroDivisionError: # An ignored exception should have been printed out on stderr err = err.getvalue() @@ -312,6 +393,9 @@ def handler(signum, frame): raise AssertionError(err) else: raise AssertionError("ZeroDivisionError not raised") + + os.close(r) + os.close(w) """ r, w = os.pipe() try: @@ -375,9 +459,10 @@ def test_wakeup_fd_during(self): def test_signum(self): self.check_wakeup("""def test(): + import _testcapi signal.signal(signal.SIGUSR1, handler) - os.kill(os.getpid(), signal.SIGUSR1) - os.kill(os.getpid(), signal.SIGALRM) + _testcapi.raise_signal(signal.SIGUSR1) + _testcapi.raise_signal(signal.SIGALRM) """, signal.SIGUSR1, signal.SIGALRM) @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'), @@ -391,13 +476,97 @@ def test_pending(self): signal.signal(signum2, handler) signal.pthread_sigmask(signal.SIG_BLOCK, (signum1, signum2)) - os.kill(os.getpid(), signum1) - os.kill(os.getpid(), signum2) + _testcapi.raise_signal(signum1) + _testcapi.raise_signal(signum2) # Unblocking the 2 signals calls the C signal handler twice signal.pthread_sigmask(signal.SIG_UNBLOCK, (signum1, signum2)) """, signal.SIGUSR1, signal.SIGUSR2, ordered=False) +@unittest.skipUnless(hasattr(socket, 'socketpair'), 'need socket.socketpair') +class WakeupSocketSignalTests(unittest.TestCase): + + @unittest.skipIf(_testcapi is None, 'need _testcapi') + def test_socket(self): + # use a subprocess to have only one thread + code = """if 1: + import signal + import socket + import struct + import _testcapi + + signum = signal.SIGINT + signals = (signum,) + + def handler(signum, frame): + pass + + signal.signal(signum, handler) + + read, write = socket.socketpair() + read.setblocking(False) + write.setblocking(False) + signal.set_wakeup_fd(write.fileno()) + + _testcapi.raise_signal(signum) + + data = read.recv(1) + if not data: + raise Exception("no signum written") + raised = struct.unpack('B', data) + if raised != signals: + raise Exception("%r != %r" % (raised, signals)) + + read.close() + write.close() + """ + + assert_python_ok('-c', code) + + @unittest.skipIf(_testcapi is None, 'need _testcapi') + def test_send_error(self): + # Use a subprocess to have only one thread. + if os.name == 'nt': + action = 'send' + else: + action = 'write' + code = """if 1: + import errno + import signal + import socket + import sys + import time + import _testcapi + from test.support import captured_stderr + + signum = signal.SIGINT + + def handler(signum, frame): + pass + + signal.signal(signum, handler) + + read, write = socket.socketpair() + read.setblocking(False) + write.setblocking(False) + + signal.set_wakeup_fd(write.fileno()) + + # Close sockets: send() will fail + read.close() + write.close() + + with captured_stderr() as err: + _testcapi.raise_signal(signum) + + err = err.getvalue() + if ('Exception ignored when trying to {action} to the signal wakeup fd' + not in err): + raise AssertionError(err) + """.format(action=action) + assert_python_ok('-c', code) + + @unittest.skipIf(sys.platform == "win32", "Not valid on Windows") class SiginterruptTest(unittest.TestCase): @@ -418,7 +587,7 @@ def readpipe_interrupted(self, interrupt): r, w = os.pipe() def handler(signum, frame): - pass + 1 / 0 signal.signal(signal.SIGALRM, handler) if interrupt is not None: @@ -428,18 +597,21 @@ def handler(signum, frame): sys.stdout.flush() # run the test twice - for loop in range(2): - # send a SIGALRM in a second (during the read) - signal.alarm(1) - try: - # blocking call: read from a pipe without data - os.read(r, 1) - except OSError as err: - if err.errno != errno.EINTR: - raise - else: - sys.exit(2) - sys.exit(3) + try: + for loop in range(2): + # send a SIGALRM in a second (during the read) + signal.alarm(1) + try: + # blocking call: read from a pipe without data + os.read(r, 1) + except ZeroDivisionError: + pass + else: + sys.exit(2) + sys.exit(3) + finally: + os.close(r) + os.close(w) """ % (interrupt,) with spawn_python('-c', code) as process: try: @@ -454,7 +626,7 @@ def handler(signum, frame): stdout = first_line + stdout exitcode = process.wait() if exitcode not in (2, 3): - raise Exception("Child error (exit code %s): %s" + raise Exception("Child error (exit code %s): %r" % (exitcode, stdout)) return (exitcode == 3) @@ -604,6 +776,8 @@ def handler(signum, frame): signal.pthread_sigmask(signal.SIG_BLOCK, [signum]) os.kill(os.getpid(), signum) pending = signal.sigpending() + for sig in pending: + assert isinstance(sig, signal.Signals), repr(pending) if pending != {signum}: raise Exception('%s != {%s}' % (pending, signum)) try: @@ -660,6 +834,7 @@ def wait_helper(self, blocked, test): code = '''if 1: import signal import sys + from signal import Signals def handler(signum, frame): 1/0 @@ -702,6 +877,7 @@ def test_sigwait(self): def test(signum): signal.alarm(1) received = signal.sigwait([signum]) + assert isinstance(received, signal.Signals), received if received != signum: raise Exception('received %s, not %s' % (received, signum)) ''') @@ -842,8 +1018,14 @@ def handler(signum, frame): def kill(signum): os.kill(os.getpid(), signum) + def check_mask(mask): + for sig in mask: + assert isinstance(sig, signal.Signals), repr(sig) + def read_sigmask(): - return signal.pthread_sigmask(signal.SIG_BLOCK, []) + sigmask = signal.pthread_sigmask(signal.SIG_BLOCK, []) + check_mask(sigmask) + return sigmask signum = signal.SIGUSR1 @@ -852,6 +1034,7 @@ def read_sigmask(): # Unblock SIGUSR1 (and copy the old mask) to test our signal handler old_mask = signal.pthread_sigmask(signal.SIG_UNBLOCK, [signum]) + check_mask(old_mask) try: kill(signum) except ZeroDivisionError: @@ -861,11 +1044,13 @@ def read_sigmask(): # Block and then raise SIGUSR1. The signal is blocked: the signal # handler is not called, and the signal is now pending - signal.pthread_sigmask(signal.SIG_BLOCK, [signum]) + mask = signal.pthread_sigmask(signal.SIG_BLOCK, [signum]) + check_mask(mask) kill(signum) # Check the new mask blocked = read_sigmask() + check_mask(blocked) if signum not in blocked: raise Exception("%s not in %s" % (signum, blocked)) if old_mask ^ blocked != {signum}: @@ -873,7 +1058,7 @@ def read_sigmask(): # Unblock SIGUSR1 try: - # unblock the pending signal calls immediatly the signal handler + # unblock the pending signal calls immediately the signal handler signal.pthread_sigmask(signal.SIG_UNBLOCK, [signum]) except ZeroDivisionError: pass @@ -928,8 +1113,9 @@ def handler(signum, frame): def test_main(): try: - support.run_unittest(PosixTests, InterProcessSignalTests, + support.run_unittest(GenericTests, PosixTests, InterProcessSignalTests, WakeupFDTests, WakeupSignalTests, + WakeupSocketSignalTests, SiginterruptTest, ItimerTest, WindowsSignalTests, PendingSignalsTests) finally: diff --git a/Lib/test/test_site.py b/Lib/test/test_site.py index cb7c393074d3..e234164b3758 100644 --- a/Lib/test/test_site.py +++ b/Lib/test/test_site.py @@ -6,8 +6,7 @@ """ import unittest import test.support -from test.support import run_unittest, TESTFN, EnvironmentVarGuard -from test.support import captured_stderr +from test.support import captured_stderr, TESTFN, EnvironmentVarGuard import builtins import os import sys @@ -19,13 +18,13 @@ import sysconfig from copy import copy -# Need to make sure to not import 'site' if someone specified ``-S`` at the -# command-line. Detect this by just making sure 'site' has not been imported -# already. -if "site" in sys.modules: - import site -else: - raise unittest.SkipTest("importation of site.py suppressed") +# These tests are not particularly useful if Python was invoked with -S. +# If you add tests that are useful under -S, this skip should be moved +# to the class level. +if sys.flags.no_site: + raise unittest.SkipTest("Python was invoked with -S") + +import site if site.ENABLE_USER_SITE and not os.path.isdir(site.USER_SITE): # need to add user site directory for tests @@ -148,7 +147,7 @@ def test_addpackage_import_bad_pth_file(self): re.escape(os.path.join(pth_dir, pth_fn))) # XXX: ditto previous XXX comment. self.assertRegex(err_out.getvalue(), 'Traceback') - self.assertRegex(err_out.getvalue(), 'TypeError') + self.assertRegex(err_out.getvalue(), 'ValueError') def test_addsitedir(self): # Same tests for test_addpackage since addsitedir() essentially just @@ -236,20 +235,18 @@ def test_getsitepackages(self): # OS X framework builds site.PREFIXES = ['Python.framework'] dirs = site.getsitepackages() - self.assertEqual(len(dirs), 3) + self.assertEqual(len(dirs), 2) wanted = os.path.join('/Library', sysconfig.get_config_var("PYTHONFRAMEWORK"), sys.version[:3], 'site-packages') - self.assertEqual(dirs[2], wanted) + self.assertEqual(dirs[1], wanted) elif os.sep == '/': # OS X non-framwework builds, Linux, FreeBSD, etc - self.assertEqual(len(dirs), 2) + self.assertEqual(len(dirs), 1) wanted = os.path.join('xoxo', 'lib', 'python' + sys.version[:3], 'site-packages') self.assertEqual(dirs[0], wanted) - wanted = os.path.join('xoxo', 'lib', 'site-python') - self.assertEqual(dirs[1], wanted) else: # other platforms self.assertEqual(len(dirs), 2) @@ -370,6 +367,7 @@ def test_no_duplicate_paths(self): self.assertNotIn(path, seen_paths) seen_paths.add(path) + @unittest.skip('test not implemented') def test_add_build_dir(self): # Test that the build directory's Modules directory is used when it # should be. @@ -412,8 +410,11 @@ def test_sitecustomize_executed(self): self.fail("sitecustomize not imported automatically") @test.support.requires_resource('network') + @test.support.system_must_validate_cert @unittest.skipUnless(sys.version_info[3] == 'final', 'only for released versions') + @unittest.skipUnless(hasattr(urllib.request, "HTTPSHandler"), + 'need SSL support to download license') def test_license_exists_at_url(self): # This test is a bit fragile since it depends on the format of the # string displayed by license in the absence of a LICENSE file. @@ -457,7 +458,8 @@ def test_startup_imports(self): # http://bugs.python.org/issue19218> collection_mods = {'_collections', 'collections', 'functools', 'heapq', 'itertools', 'keyword', 'operator', - 'reprlib', 'types', 'weakref'} + 'reprlib', 'types', 'weakref' + }.difference(sys.builtin_module_names) self.assertFalse(modules.intersection(collection_mods), stderr) diff --git a/Lib/test/test_smtpd.py b/Lib/test/test_smtpd.py index 93f14c4562bc..6eb47f1deec7 100644 --- a/Lib/test/test_smtpd.py +++ b/Lib/test/test_smtpd.py @@ -1,4 +1,5 @@ import unittest +import textwrap from test import support, mock_socket import socket import io @@ -7,15 +8,22 @@ class DummyServer(smtpd.SMTPServer): - def __init__(self, localaddr, remoteaddr): - smtpd.SMTPServer.__init__(self, localaddr, remoteaddr) + def __init__(self, *args, **kwargs): + smtpd.SMTPServer.__init__(self, *args, **kwargs) self.messages = [] + if self._decode_data: + self.return_status = 'return status' + else: + self.return_status = b'return status' def process_message(self, peer, mailfrom, rcpttos, data): self.messages.append((peer, mailfrom, rcpttos, data)) - if data == 'return status': + if data == self.return_status: return '250 Okish' + def process_smtputf8_message(self, *args, **kwargs): + return '250 SMTPUTF8 message okish' + class DummyDispatcherBroken(Exception): pass @@ -31,9 +39,10 @@ def setUp(self): smtpd.socket = asyncore.socket = mock_socket def test_process_message_unimplemented(self): - server = smtpd.SMTPServer('a', 'b') + server = smtpd.SMTPServer((support.HOST, 0), ('b', 0), + decode_data=True) conn, addr = server.accept() - channel = smtpd.SMTPChannel(server, conn, addr) + channel = smtpd.SMTPChannel(server, conn, addr, decode_data=True) def write_line(line): channel.socket.queue_recv(line) @@ -45,19 +54,163 @@ def write_line(line): write_line(b'DATA') self.assertRaises(NotImplementedError, write_line, b'spam\r\n.\r\n') + def test_process_smtputf8_message_unimplemented(self): + server = smtpd.SMTPServer((support.HOST, 0), ('b', 0), + enable_SMTPUTF8=True) + conn, addr = server.accept() + channel = smtpd.SMTPChannel(server, conn, addr, enable_SMTPUTF8=True) + + def write_line(line): + channel.socket.queue_recv(line) + channel.handle_read() + + write_line(b'EHLO example') + write_line(b'MAIL From: BODY=8BITMIME SMTPUTF8') + write_line(b'RCPT To: ') + write_line(b'DATA') + self.assertRaises(NotImplementedError, write_line, b'spam\r\n.\r\n') + + def test_decode_data_default_warns(self): + with self.assertWarns(DeprecationWarning): + smtpd.SMTPServer((support.HOST, 0), ('b', 0)) + + def test_decode_data_and_enable_SMTPUTF8_raises(self): + self.assertRaises( + ValueError, + smtpd.SMTPServer, + (support.HOST, 0), + ('b', 0), + enable_SMTPUTF8=True, + decode_data=True) + + def tearDown(self): + asyncore.close_all() + asyncore.socket = smtpd.socket = socket + + +class DebuggingServerTest(unittest.TestCase): + + def setUp(self): + smtpd.socket = asyncore.socket = mock_socket + + def send_data(self, channel, data, enable_SMTPUTF8=False): + def write_line(line): + channel.socket.queue_recv(line) + channel.handle_read() + write_line(b'EHLO example') + if enable_SMTPUTF8: + write_line(b'MAIL From:eggs@example BODY=8BITMIME SMTPUTF8') + else: + write_line(b'MAIL From:eggs@example') + write_line(b'RCPT To:spam@example') + write_line(b'DATA') + write_line(data) + write_line(b'.') + + def test_process_message_with_decode_data_true(self): + server = smtpd.DebuggingServer((support.HOST, 0), ('b', 0), + decode_data=True) + conn, addr = server.accept() + channel = smtpd.SMTPChannel(server, conn, addr, decode_data=True) + with support.captured_stdout() as s: + self.send_data(channel, b'From: test\n\nhello\n') + stdout = s.getvalue() + self.assertEqual(stdout, textwrap.dedent("""\ + ---------- MESSAGE FOLLOWS ---------- + From: test + X-Peer: peer-address + + hello + ------------ END MESSAGE ------------ + """)) + + def test_process_message_with_decode_data_false(self): + server = smtpd.DebuggingServer((support.HOST, 0), ('b', 0), + decode_data=False) + conn, addr = server.accept() + channel = smtpd.SMTPChannel(server, conn, addr, decode_data=False) + with support.captured_stdout() as s: + self.send_data(channel, b'From: test\n\nh\xc3\xa9llo\xff\n') + stdout = s.getvalue() + self.assertEqual(stdout, textwrap.dedent("""\ + ---------- MESSAGE FOLLOWS ---------- + b'From: test' + b'X-Peer: peer-address' + b'' + b'h\\xc3\\xa9llo\\xff' + ------------ END MESSAGE ------------ + """)) + + def test_process_message_with_enable_SMTPUTF8_true(self): + server = smtpd.DebuggingServer((support.HOST, 0), ('b', 0), + enable_SMTPUTF8=True) + conn, addr = server.accept() + channel = smtpd.SMTPChannel(server, conn, addr, enable_SMTPUTF8=True) + with support.captured_stdout() as s: + self.send_data(channel, b'From: test\n\nh\xc3\xa9llo\xff\n') + stdout = s.getvalue() + self.assertEqual(stdout, textwrap.dedent("""\ + ---------- MESSAGE FOLLOWS ---------- + b'From: test' + b'X-Peer: peer-address' + b'' + b'h\\xc3\\xa9llo\\xff' + ------------ END MESSAGE ------------ + """)) + + def test_process_SMTPUTF8_message_with_enable_SMTPUTF8_true(self): + server = smtpd.DebuggingServer((support.HOST, 0), ('b', 0), + enable_SMTPUTF8=True) + conn, addr = server.accept() + channel = smtpd.SMTPChannel(server, conn, addr, enable_SMTPUTF8=True) + with support.captured_stdout() as s: + self.send_data(channel, b'From: test\n\nh\xc3\xa9llo\xff\n', + enable_SMTPUTF8=True) + stdout = s.getvalue() + self.assertEqual(stdout, textwrap.dedent("""\ + ----- SMTPUTF8 MESSAGE FOLLOWS ------ + b'From: test' + b'X-Peer: peer-address' + b'' + b'h\\xc3\\xa9llo\\xff' + ------------ END MESSAGE ------------ + """)) + def tearDown(self): asyncore.close_all() asyncore.socket = smtpd.socket = socket +class TestFamilyDetection(unittest.TestCase): + def setUp(self): + smtpd.socket = asyncore.socket = mock_socket + + def tearDown(self): + asyncore.close_all() + asyncore.socket = smtpd.socket = socket + + @unittest.skipUnless(support.IPV6_ENABLED, "IPv6 not enabled") + def test_socket_uses_IPv6(self): + server = smtpd.SMTPServer((support.HOSTv6, 0), (support.HOST, 0), + decode_data=False) + self.assertEqual(server.socket.family, socket.AF_INET6) + + def test_socket_uses_IPv4(self): + server = smtpd.SMTPServer((support.HOST, 0), (support.HOSTv6, 0), + decode_data=False) + self.assertEqual(server.socket.family, socket.AF_INET) + + class SMTPDChannelTest(unittest.TestCase): def setUp(self): smtpd.socket = asyncore.socket = mock_socket self.old_debugstream = smtpd.DEBUGSTREAM self.debug = smtpd.DEBUGSTREAM = io.StringIO() - self.server = DummyServer('a', 'b') + self.server = DummyServer((support.HOST, 0), ('b', 0), + decode_data=True) conn, addr = self.server.accept() - self.channel = smtpd.SMTPChannel(self.server, conn, addr) + self.channel = smtpd.SMTPChannel(self.server, conn, addr, + decode_data=True) def tearDown(self): asyncore.close_all() @@ -69,7 +222,9 @@ def write_line(self, line): self.channel.handle_read() def test_broken_connect(self): - self.assertRaises(DummyDispatcherBroken, BrokenDummyServer, 'a', 'b') + self.assertRaises( + DummyDispatcherBroken, BrokenDummyServer, + (support.HOST, 0), ('b', 0), decode_data=True) def test_server_accept(self): self.server.handle_accept() @@ -214,6 +369,12 @@ def test_MAIL_command_limit_extended_with_SIZE(self): self.assertEqual(self.channel.socket.last, b'500 Error: line too long\r\n') + def test_MAIL_command_rejects_SMTPUTF8_by_default(self): + self.write_line(b'EHLO example') + self.write_line( + b'MAIL from: BODY=8BITMIME SMTPUTF8') + self.assertEqual(self.channel.socket.last[0:1], b'5') + def test_data_longer_than_default_data_size_limit(self): # Hack the default so we don't have to generate so much data. self.channel.data_size_limit = 1048 @@ -387,7 +548,10 @@ def test_data_dialog(self): self.write_line(b'data\r\nmore\r\n.') self.assertEqual(self.channel.socket.last, b'250 OK\r\n') self.assertEqual(self.server.messages, - [('peer', 'eggs@example', ['spam@example'], 'data\nmore')]) + [(('peer-address', 'peer-port'), + 'eggs@example', + ['spam@example'], + 'data\nmore')]) def test_DATA_syntax(self): self.write_line(b'HELO example') @@ -417,7 +581,10 @@ def test_multiple_RCPT(self): self.write_line(b'DATA') self.write_line(b'data\r\n.') self.assertEqual(self.server.messages, - [('peer', 'eggs@example', ['spam@example','ham@example'], 'data')]) + [(('peer-address', 'peer-port'), + 'eggs@example', + ['spam@example','ham@example'], + 'data')]) def test_manual_status(self): # checks that the Channel is able to return a custom status message @@ -439,7 +606,10 @@ def test_RSET(self): self.write_line(b'DATA') self.write_line(b'data\r\n.') self.assertEqual(self.server.messages, - [('peer', 'foo@example', ['eggs@example'], 'data')]) + [(('peer-address', 'peer-port'), + 'foo@example', + ['eggs@example'], + 'data')]) def test_HELO_RSET(self): self.write_line(b'HELO example') @@ -502,6 +672,24 @@ def test_attribute_deprecations(self): with support.check_warnings(('', DeprecationWarning)): self.channel._SMTPChannel__addr = 'spam' + def test_decode_data_default_warning(self): + with self.assertWarns(DeprecationWarning): + server = DummyServer((support.HOST, 0), ('b', 0)) + conn, addr = self.server.accept() + with self.assertWarns(DeprecationWarning): + smtpd.SMTPChannel(server, conn, addr) + +@unittest.skipUnless(support.IPV6_ENABLED, "IPv6 not enabled") +class SMTPDChannelIPv6Test(SMTPDChannelTest): + def setUp(self): + smtpd.socket = asyncore.socket = mock_socket + self.old_debugstream = smtpd.DEBUGSTREAM + self.debug = smtpd.DEBUGSTREAM = io.StringIO() + self.server = DummyServer((support.HOSTv6, 0), ('b', 0), + decode_data=True) + conn, addr = self.server.accept() + self.channel = smtpd.SMTPChannel(self.server, conn, addr, + decode_data=True) class SMTPDChannelWithDataSizeLimitTest(unittest.TestCase): @@ -509,10 +697,12 @@ def setUp(self): smtpd.socket = asyncore.socket = mock_socket self.old_debugstream = smtpd.DEBUGSTREAM self.debug = smtpd.DEBUGSTREAM = io.StringIO() - self.server = DummyServer('a', 'b') + self.server = DummyServer((support.HOST, 0), ('b', 0), + decode_data=True) conn, addr = self.server.accept() # Set DATA size limit to 32 bytes for easy testing - self.channel = smtpd.SMTPChannel(self.server, conn, addr, 32) + self.channel = smtpd.SMTPChannel(self.server, conn, addr, 32, + decode_data=True) def tearDown(self): asyncore.close_all() @@ -536,7 +726,10 @@ def test_data_limit_dialog(self): self.write_line(b'data\r\nmore\r\n.') self.assertEqual(self.channel.socket.last, b'250 OK\r\n') self.assertEqual(self.server.messages, - [('peer', 'eggs@example', ['spam@example'], 'data\nmore')]) + [(('peer-address', 'peer-port'), + 'eggs@example', + ['spam@example'], + 'data\nmore')]) def test_data_limit_dialog_too_much_data(self): self.write_line(b'HELO example') @@ -553,5 +746,181 @@ def test_data_limit_dialog_too_much_data(self): b'552 Error: Too much mail data\r\n') +class SMTPDChannelWithDecodeDataFalse(unittest.TestCase): + + def setUp(self): + smtpd.socket = asyncore.socket = mock_socket + self.old_debugstream = smtpd.DEBUGSTREAM + self.debug = smtpd.DEBUGSTREAM = io.StringIO() + self.server = DummyServer((support.HOST, 0), ('b', 0), + decode_data=False) + conn, addr = self.server.accept() + # Set decode_data to False + self.channel = smtpd.SMTPChannel(self.server, conn, addr, + decode_data=False) + + def tearDown(self): + asyncore.close_all() + asyncore.socket = smtpd.socket = socket + smtpd.DEBUGSTREAM = self.old_debugstream + + def write_line(self, line): + self.channel.socket.queue_recv(line) + self.channel.handle_read() + + def test_ascii_data(self): + self.write_line(b'HELO example') + self.write_line(b'MAIL From:eggs@example') + self.write_line(b'RCPT To:spam@example') + self.write_line(b'DATA') + self.write_line(b'plain ascii text') + self.write_line(b'.') + self.assertEqual(self.channel.received_data, b'plain ascii text') + + def test_utf8_data(self): + self.write_line(b'HELO example') + self.write_line(b'MAIL From:eggs@example') + self.write_line(b'RCPT To:spam@example') + self.write_line(b'DATA') + self.write_line(b'utf8 enriched text: \xc5\xbc\xc5\xba\xc4\x87') + self.write_line(b'and some plain ascii') + self.write_line(b'.') + self.assertEqual( + self.channel.received_data, + b'utf8 enriched text: \xc5\xbc\xc5\xba\xc4\x87\n' + b'and some plain ascii') + + +class SMTPDChannelWithDecodeDataTrue(unittest.TestCase): + + def setUp(self): + smtpd.socket = asyncore.socket = mock_socket + self.old_debugstream = smtpd.DEBUGSTREAM + self.debug = smtpd.DEBUGSTREAM = io.StringIO() + self.server = DummyServer((support.HOST, 0), ('b', 0), + decode_data=True) + conn, addr = self.server.accept() + # Set decode_data to True + self.channel = smtpd.SMTPChannel(self.server, conn, addr, + decode_data=True) + + def tearDown(self): + asyncore.close_all() + asyncore.socket = smtpd.socket = socket + smtpd.DEBUGSTREAM = self.old_debugstream + + def write_line(self, line): + self.channel.socket.queue_recv(line) + self.channel.handle_read() + + def test_ascii_data(self): + self.write_line(b'HELO example') + self.write_line(b'MAIL From:eggs@example') + self.write_line(b'RCPT To:spam@example') + self.write_line(b'DATA') + self.write_line(b'plain ascii text') + self.write_line(b'.') + self.assertEqual(self.channel.received_data, 'plain ascii text') + + def test_utf8_data(self): + self.write_line(b'HELO example') + self.write_line(b'MAIL From:eggs@example') + self.write_line(b'RCPT To:spam@example') + self.write_line(b'DATA') + self.write_line(b'utf8 enriched text: \xc5\xbc\xc5\xba\xc4\x87') + self.write_line(b'and some plain ascii') + self.write_line(b'.') + self.assertEqual( + self.channel.received_data, + 'utf8 enriched text: żźć\nand some plain ascii') + + +class SMTPDChannelTestWithEnableSMTPUTF8True(unittest.TestCase): + def setUp(self): + smtpd.socket = asyncore.socket = mock_socket + self.old_debugstream = smtpd.DEBUGSTREAM + self.debug = smtpd.DEBUGSTREAM = io.StringIO() + self.server = DummyServer((support.HOST, 0), ('b', 0), + enable_SMTPUTF8=True) + conn, addr = self.server.accept() + self.channel = smtpd.SMTPChannel(self.server, conn, addr, + enable_SMTPUTF8=True) + + def tearDown(self): + asyncore.close_all() + asyncore.socket = smtpd.socket = socket + smtpd.DEBUGSTREAM = self.old_debugstream + + def write_line(self, line): + self.channel.socket.queue_recv(line) + self.channel.handle_read() + + def test_MAIL_command_accepts_SMTPUTF8_when_announced(self): + self.write_line(b'EHLO example') + self.write_line( + 'MAIL from: BODY=8BITMIME SMTPUTF8'.encode( + 'utf-8') + ) + self.assertEqual(self.channel.socket.last, b'250 OK\r\n') + + def test_process_smtputf8_message(self): + self.write_line(b'EHLO example') + for mail_parameters in [b'', b'BODY=8BITMIME SMTPUTF8']: + self.write_line(b'MAIL from: ' + mail_parameters) + self.assertEqual(self.channel.socket.last[0:3], b'250') + self.write_line(b'rcpt to:') + self.assertEqual(self.channel.socket.last[0:3], b'250') + self.write_line(b'data') + self.assertEqual(self.channel.socket.last[0:3], b'354') + self.write_line(b'c\r\n.') + if mail_parameters == b'': + self.assertEqual(self.channel.socket.last, b'250 OK\r\n') + else: + self.assertEqual(self.channel.socket.last, + b'250 SMTPUTF8 message okish\r\n') + + def test_utf8_data(self): + self.write_line(b'EHLO example') + self.write_line( + 'MAIL From: naïve@examplé BODY=8BITMIME SMTPUTF8'.encode('utf-8')) + self.assertEqual(self.channel.socket.last[0:3], b'250') + self.write_line('RCPT To:späm@examplé'.encode('utf-8')) + self.assertEqual(self.channel.socket.last[0:3], b'250') + self.write_line(b'DATA') + self.assertEqual(self.channel.socket.last[0:3], b'354') + self.write_line(b'utf8 enriched text: \xc5\xbc\xc5\xba\xc4\x87') + self.write_line(b'.') + self.assertEqual( + self.channel.received_data, + b'utf8 enriched text: \xc5\xbc\xc5\xba\xc4\x87') + + def test_MAIL_command_limit_extended_with_SIZE_and_SMTPUTF8(self): + self.write_line(b'ehlo example') + fill_len = (512 + 26 + 10) - len('mail from:<@example>') + self.write_line(b'MAIL from:<' + + b'a' * (fill_len + 1) + + b'@example>') + self.assertEqual(self.channel.socket.last, + b'500 Error: line too long\r\n') + self.write_line(b'MAIL from:<' + + b'a' * fill_len + + b'@example>') + self.assertEqual(self.channel.socket.last, b'250 OK\r\n') + + def test_multiple_emails_with_extended_command_length(self): + self.write_line(b'ehlo example') + fill_len = (512 + 26 + 10) - len('mail from:<@example>') + for char in [b'a', b'b', b'c']: + self.write_line(b'MAIL from:<' + char * fill_len + b'a@example>') + self.assertEqual(self.channel.socket.last[0:3], b'500') + self.write_line(b'MAIL from:<' + char * fill_len + b'@example>') + self.assertEqual(self.channel.socket.last[0:3], b'250') + self.write_line(b'rcpt to:') + self.assertEqual(self.channel.socket.last[0:3], b'250') + self.write_line(b'data') + self.assertEqual(self.channel.socket.last[0:3], b'354') + self.write_line(b'test\r\n.') + self.assertEqual(self.channel.socket.last[0:3], b'250') + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_smtplib.py b/Lib/test/test_smtplib.py index e6f39dec7739..5f12d28eeafe 100644 --- a/Lib/test/test_smtplib.py +++ b/Lib/test/test_smtplib.py @@ -10,6 +10,7 @@ import time import select import errno +import base64 import unittest from test import support, mock_socket @@ -30,7 +31,7 @@ def handle_expt(self): def server(evt, buf, serv): - serv.listen(5) + serv.listen() evt.set() try: conn, addr = serv.accept() @@ -96,7 +97,7 @@ def testLocalHostName(self): def testTimeoutDefault(self): mock_socket.reply_with(b"220 Hola mundo") - self.assertTrue(mock_socket.getdefaulttimeout() is None) + self.assertIsNone(mock_socket.getdefaulttimeout()) mock_socket.setdefaulttimeout(30) self.assertEqual(mock_socket.getdefaulttimeout(), 30) try: @@ -108,13 +109,13 @@ def testTimeoutDefault(self): def testTimeoutNone(self): mock_socket.reply_with(b"220 Hola mundo") - self.assertTrue(socket.getdefaulttimeout() is None) + self.assertIsNone(socket.getdefaulttimeout()) socket.setdefaulttimeout(30) try: smtp = smtplib.SMTP(HOST, self.port, timeout=None) finally: socket.setdefaulttimeout(None) - self.assertTrue(smtp.sock.gettimeout() is None) + self.assertIsNone(smtp.sock.gettimeout()) smtp.close() def testTimeoutValue(self): @@ -184,7 +185,8 @@ def setUp(self): self.old_DEBUGSTREAM = smtpd.DEBUGSTREAM smtpd.DEBUGSTREAM = io.StringIO() # Pick a random unused port by passing 0 for the port number - self.serv = smtpd.DebuggingServer((HOST, 0), ('nowhere', -1)) + self.serv = smtpd.DebuggingServer((HOST, 0), ('nowhere', -1), + decode_data=True) # Keep a note of what port was assigned self.port = self.serv.socket.getsockname()[1] serv_args = (self.serv, self.serv_evt, self.client_evt) @@ -563,6 +565,33 @@ def testFailingHELO(self): HOST, self.port, 'localhost', 3) +@unittest.skipUnless(threading, 'Threading required for this test.') +class TooLongLineTests(unittest.TestCase): + respdata = b'250 OK' + (b'.' * smtplib._MAXLINE * 2) + b'\n' + + def setUp(self): + self.old_stdout = sys.stdout + self.output = io.StringIO() + sys.stdout = self.output + + self.evt = threading.Event() + self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.sock.settimeout(15) + self.port = support.bind_port(self.sock) + servargs = (self.evt, self.respdata, self.sock) + threading.Thread(target=server, args=servargs).start() + self.evt.wait() + self.evt.clear() + + def tearDown(self): + self.evt.wait() + sys.stdout = self.old_stdout + + def testLineTooLong(self): + self.assertRaises(smtplib.SMTPResponseException, smtplib.SMTP, + HOST, self.port, 'localhost', 3) + + sim_users = {'Mr.A@somewhere.com':'John A', 'Ms.B@xn--fo-fka.com':'Sally B', 'Mrs.C@somewhereesle.com':'Ruth C', @@ -577,7 +606,8 @@ def testFailingHELO(self): 'cram-md5': ('TXIUQUBZB21LD2HLCMUUY29TIDG4OWQ0MJ' 'KWZGQ4ODNMNDA4NTGXMDRLZWMYZJDMODG1'), } -sim_auth_login_password = 'C29TZXBHC3N3B3JK' +sim_auth_login_user = 'TXIUQUBZB21LD2HLCMUUY29T' +sim_auth_plain = 'AE1YLKFAC29TZXDOZXJLLMNVBQBZB21LCGFZC3DVCMQ=' sim_lists = {'list-1':['Mr.A@somewhere.com','Mrs.C@somewhereesle.com'], 'list-2':['Ms.B@xn--fo-fka.com',], @@ -592,6 +622,7 @@ class SimSMTPChannel(smtpd.SMTPChannel): data_response = None rcpt_count = 0 rset_count = 0 + disconnect = 0 def __init__(self, extra_features, *args, **kw): self._extrafeatures = ''.join( @@ -630,18 +661,16 @@ def smtp_EXPN(self, arg): self.push('550 No access for you!') def smtp_AUTH(self, arg): - if arg.strip().lower()=='cram-md5': + mech = arg.strip().lower() + if mech=='cram-md5': self.push('334 {}'.format(sim_cram_md5_challenge)) - return - mech, auth = arg.split() - mech = mech.lower() - if mech not in sim_auth_credentials: + elif mech not in sim_auth_credentials: self.push('504 auth type unimplemented') return - if mech == 'plain' and auth==sim_auth_credentials['plain']: - self.push('235 plain auth ok') - elif mech=='login' and auth==sim_auth_credentials['login']: - self.push('334 Password:') + elif mech=='plain': + self.push('334 ') + elif mech=='login': + self.push('334 ') else: self.push('550 No access for you!') @@ -657,6 +686,8 @@ def smtp_MAIL(self, arg): super().smtp_MAIL(arg) else: self.push(self.mail_response) + if self.disconnect: + self.close_when_done() def smtp_RCPT(self, arg): if self.rcpt_response is None: @@ -689,7 +720,8 @@ def __init__(self, *args, **kw): def handle_accepted(self, conn, addr): self._SMTPchannel = self.channel_class( - self._extra_features, self, conn, addr) + self._extra_features, self, conn, addr, + decode_data=self._decode_data) def process_message(self, peer, mailfrom, rcpttos, data): pass @@ -712,7 +744,7 @@ def setUp(self): self.serv_evt = threading.Event() self.client_evt = threading.Event() # Pick a random unused port by passing 0 for the port number - self.serv = SimSMTPServer((HOST, 0), ('nowhere', -1)) + self.serv = SimSMTPServer((HOST, 0), ('nowhere', -1), decode_data=True) # Keep a note of what port was assigned self.port = self.serv.socket.getsockname()[1] serv_args = (self.serv, self.serv_evt, self.client_evt) @@ -786,28 +818,28 @@ def testEXPN(self): self.assertEqual(smtp.expn(u), expected_unknown) smtp.quit() - def testAUTH_PLAIN(self): - self.serv.add_feature("AUTH PLAIN") - smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=15) - - expected_auth_ok = (235, b'plain auth ok') - self.assertEqual(smtp.login(sim_auth[0], sim_auth[1]), expected_auth_ok) - smtp.close() - - # SimSMTPChannel doesn't fully support LOGIN or CRAM-MD5 auth because they - # require a synchronous read to obtain the credentials...so instead smtpd + # SimSMTPChannel doesn't fully support AUTH because it requires a + # synchronous read to obtain the credentials...so instead smtpd # sees the credential sent by smtplib's login method as an unknown command, # which results in smtplib raising an auth error. Fortunately the error # message contains the encoded credential, so we can partially check that it # was generated correctly (partially, because the 'word' is uppercased in # the error message). + def testAUTH_PLAIN(self): + self.serv.add_feature("AUTH PLAIN") + smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=15) + try: smtp.login(sim_auth[0], sim_auth[1]) + except smtplib.SMTPAuthenticationError as err: + self.assertIn(sim_auth_plain, str(err)) + smtp.close() + def testAUTH_LOGIN(self): self.serv.add_feature("AUTH LOGIN") smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=15) try: smtp.login(sim_auth[0], sim_auth[1]) except smtplib.SMTPAuthenticationError as err: - self.assertIn(sim_auth_login_password, str(err)) + self.assertIn(sim_auth_login_user, str(err)) smtp.close() def testAUTH_CRAM_MD5(self): @@ -825,9 +857,40 @@ def testAUTH_multiple(self): smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=15) try: smtp.login(sim_auth[0], sim_auth[1]) except smtplib.SMTPAuthenticationError as err: - self.assertIn(sim_auth_login_password, str(err)) + self.assertIn(sim_auth_login_user, str(err)) + smtp.close() + + def test_auth_function(self): + smtp = smtplib.SMTP(HOST, self.port, + local_hostname='localhost', timeout=15) + self.serv.add_feature("AUTH CRAM-MD5") + smtp.user, smtp.password = sim_auth[0], sim_auth[1] + supported = {'CRAM-MD5': smtp.auth_cram_md5, + 'PLAIN': smtp.auth_plain, + 'LOGIN': smtp.auth_login, + } + for mechanism, method in supported.items(): + try: smtp.auth(mechanism, method) + except smtplib.SMTPAuthenticationError as err: + self.assertIn(sim_auth_credentials[mechanism.lower()].upper(), + str(err)) smtp.close() + def test_quit_resets_greeting(self): + smtp = smtplib.SMTP(HOST, self.port, + local_hostname='localhost', + timeout=15) + code, message = smtp.ehlo() + self.assertEqual(code, 250) + self.assertIn('size', smtp.esmtp_features) + smtp.quit() + self.assertNotIn('size', smtp.esmtp_features) + smtp.connect(HOST, self.port) + self.assertNotIn('size', smtp.esmtp_features) + smtp.ehlo_or_helo_if_needed() + self.assertIn('size', smtp.esmtp_features) + smtp.quit() + def test_with_statement(self): with smtplib.SMTP(HOST, self.port) as smtp: code, message = smtp.noop() @@ -848,6 +911,16 @@ def test_with_statement_QUIT_failure(self): #TODO: add tests for correct AUTH method fallback now that the #test infrastructure can support it. + # Issue 17498: make sure _rset does not raise SMTPServerDisconnected exception + def test__rest_from_mail_cmd(self): + smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=15) + smtp.noop() + self.serv._SMTPchannel.mail_response = '451 Requested action aborted' + self.serv._SMTPchannel.disconnect = True + with self.assertRaises(smtplib.SMTPSenderRefused): + smtp.sendmail('John', 'Sally', 'test message') + self.assertIsNone(smtp.sock) + # Issue 5713: make sure close, not rset, is called if we get a 421 error def test_421_from_mail_cmd(self): smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=15) @@ -888,7 +961,8 @@ def found_terminator(self): def test_main(verbose=None): support.run_unittest(GeneralTests, DebuggingServerTests, NonConnectingTests, - BadHELOServerTests, SMTPSimTests) + BadHELOServerTests, SMTPSimTests, + TooLongLineTests) if __name__ == '__main__': test_main() diff --git a/Lib/test/test_smtpnet.py b/Lib/test/test_smtpnet.py index 86224ef2e45b..03bf93b8e7ca 100644 --- a/Lib/test/test_smtpnet.py +++ b/Lib/test/test_smtpnet.py @@ -1,25 +1,35 @@ -#!/usr/bin/env python3 - import unittest from test import support import smtplib +import socket ssl = support.import_module("ssl") support.requires("network") +def check_ssl_verifiy(host, port): + context = ssl.create_default_context() + with socket.create_connection((host, port)) as sock: + try: + sock = context.wrap_socket(sock, server_hostname=host) + except Exception: + return False + else: + sock.close() + return True + class SmtpTest(unittest.TestCase): testServer = 'smtp.gmail.com' remotePort = 25 - context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) def test_connect_starttls(self): support.get_attribute(smtplib, 'SMTP_SSL') + context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) with support.transient_internet(self.testServer): server = smtplib.SMTP(self.testServer, self.remotePort) try: - server.starttls(context=self.context) + server.starttls(context=context) except smtplib.SMTPException as e: if e.args[0] == 'STARTTLS extension not supported by server.': unittest.skip(e.args[0]) @@ -32,7 +42,6 @@ def test_connect_starttls(self): class SmtpSSLTest(unittest.TestCase): testServer = 'smtp.gmail.com' remotePort = 465 - context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) def test_connect(self): support.get_attribute(smtplib, 'SMTP_SSL') @@ -49,9 +58,23 @@ def test_connect_default_port(self): server.quit() def test_connect_using_sslcontext(self): + context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) + support.get_attribute(smtplib, 'SMTP_SSL') + with support.transient_internet(self.testServer): + server = smtplib.SMTP_SSL(self.testServer, self.remotePort, context=context) + server.ehlo() + server.quit() + + def test_connect_using_sslcontext_verified(self): + with support.transient_internet(self.testServer): + can_verify = check_ssl_verifiy(self.testServer, self.remotePort) + if not can_verify: + self.skipTest("SSL certificate can't be verified") + support.get_attribute(smtplib, 'SMTP_SSL') + context = ssl.create_default_context() with support.transient_internet(self.testServer): - server = smtplib.SMTP_SSL(self.testServer, self.remotePort, context=self.context) + server = smtplib.SMTP_SSL(self.testServer, self.remotePort, context=context) server.ehlo() server.quit() diff --git a/Lib/test/test_sndhdr.py b/Lib/test/test_sndhdr.py index 5e0abe0b363d..426417c03820 100644 --- a/Lib/test/test_sndhdr.py +++ b/Lib/test/test_sndhdr.py @@ -1,4 +1,5 @@ import sndhdr +import pickle import unittest from test.support import findfile @@ -18,6 +19,19 @@ def test_data(self): what = sndhdr.what(filename) self.assertNotEqual(what, None, filename) self.assertSequenceEqual(what, expected) + self.assertEqual(what.filetype, expected[0]) + self.assertEqual(what.framerate, expected[1]) + self.assertEqual(what.nchannels, expected[2]) + self.assertEqual(what.nframes, expected[3]) + self.assertEqual(what.sampwidth, expected[4]) + + def test_pickleable(self): + filename = findfile('sndhdr.aifc', subdir="sndhdrdata") + what = sndhdr.what(filename) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + dump = pickle.dumps(what, proto) + self.assertEqual(pickle.loads(dump), what) + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 3c9fbf060313..cf45b7346ca1 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -1,14 +1,12 @@ -#!/usr/bin/env python3 - import unittest from test import support import errno import io +import itertools import socket import select import tempfile -import _testcapi import time import traceback import queue @@ -22,6 +20,8 @@ import math import pickle import struct +import random +import string try: import multiprocessing except ImportError: @@ -40,6 +40,11 @@ except ImportError: thread = None threading = None +try: + import _socket +except ImportError: + _socket = None + def _have_socket_can(): """Check whether CAN sockets are supported on this host.""" @@ -73,7 +78,7 @@ class SocketTCPTest(unittest.TestCase): def setUp(self): self.serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.port = support.bind_port(self.serv) - self.serv.listen(1) + self.serv.listen() def tearDown(self): self.serv.close() @@ -442,7 +447,7 @@ class SocketListeningTestMixin(SocketTestBase): def setUp(self): super().setUp() - self.serv.listen(1) + self.serv.listen() class ThreadedSocketTestMixin(ThreadSafeCleanupTestCase, SocketTestBase, @@ -646,6 +651,13 @@ def requireSocket(*args): class GeneralModuleTests(unittest.TestCase): + def test_SocketType_is_socketobject(self): + import _socket + self.assertTrue(socket.SocketType is _socket.socket) + s = socket.socket() + self.assertIsInstance(s, socket.SocketType) + s.close() + def test_repr(self): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) with s: @@ -660,6 +672,19 @@ def test_repr(self): self.assertIn('[closed]', repr(s)) self.assertNotIn('laddr', repr(s)) + @unittest.skipUnless(_socket is not None, 'need _socket module') + def test_csocket_repr(self): + s = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM) + try: + expected = ('' + % (s.fileno(), s.family, s.type, s.proto)) + self.assertEqual(repr(s), expected) + finally: + s.close() + expected = ('' + % (s.family, s.type, s.proto)) + self.assertEqual(repr(s), expected) + def test_weakref(self): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) p = proxy(s) @@ -693,11 +718,11 @@ def testSendtoErrors(self): with self.assertRaises(TypeError) as cm: s.sendto('\u2620', sockname) self.assertEqual(str(cm.exception), - "'str' does not support the buffer interface") + "a bytes-like object is required, not 'str'") with self.assertRaises(TypeError) as cm: s.sendto(5j, sockname) self.assertEqual(str(cm.exception), - "'complex' does not support the buffer interface") + "a bytes-like object is required, not 'complex'") with self.assertRaises(TypeError) as cm: s.sendto(b'foo', None) self.assertIn('not NoneType',str(cm.exception)) @@ -705,11 +730,11 @@ def testSendtoErrors(self): with self.assertRaises(TypeError) as cm: s.sendto('\u2620', 0, sockname) self.assertEqual(str(cm.exception), - "'str' does not support the buffer interface") + "a bytes-like object is required, not 'str'") with self.assertRaises(TypeError) as cm: s.sendto(5j, 0, sockname) self.assertEqual(str(cm.exception), - "'complex' does not support the buffer interface") + "a bytes-like object is required, not 'complex'") with self.assertRaises(TypeError) as cm: s.sendto(b'foo', 0, None) self.assertIn('not NoneType', str(cm.exception)) @@ -745,13 +770,13 @@ def testHostnameRes(self): ip = socket.gethostbyname(hostname) except OSError: # Probably name lookup wasn't set up right; skip this test - return + self.skipTest('name lookup failure') self.assertTrue(ip.find('.') >= 0, "Error resolving host to ip.") try: hname, aliases, ipaddrs = socket.gethostbyaddr(ip) except OSError: # Probably a similar problem as above; skip this test - return + self.skipTest('name lookup failure') all_host_names = [hostname, hname] + aliases fqhn = socket.getfqdn(ip) if not fqhn in all_host_names: @@ -870,7 +895,7 @@ def testGetServBy(self): # Find one service that exists, then check all the related interfaces. # I've ordered this by protocols that have both a tcp and udp # protocol, at least for modern Linuxes. - if (sys.platform.startswith(('freebsd', 'netbsd')) + if (sys.platform.startswith(('freebsd', 'netbsd', 'gnukfreebsd')) or sys.platform in ('linux', 'darwin')): # avoid the 'echo' service on this platform, as there is an # assumption breaking non-standard port/protocol entry @@ -977,16 +1002,16 @@ def testIPv6toString(self): try: from socket import inet_pton, AF_INET6, has_ipv6 if not has_ipv6: - return + self.skipTest('IPv6 not available') except ImportError: - return + self.skipTest('could not import needed symbols from socket') if sys.platform == "win32": try: inet_pton(AF_INET6, '::') except OSError as e: if e.winerror == 10022: - return # IPv6 might not be installed on this PC + self.skipTest('IPv6 might not be supported') f = lambda a: inet_pton(AF_INET6, a) assertInvalid = lambda a: self.assertRaises( @@ -1063,16 +1088,16 @@ def testStringToIPv6(self): try: from socket import inet_ntop, AF_INET6, has_ipv6 if not has_ipv6: - return + self.skipTest('IPv6 not available') except ImportError: - return + self.skipTest('could not import needed symbols from socket') if sys.platform == "win32": try: inet_ntop(AF_INET6, b'\x00' * 16) except OSError as e: if e.winerror == 10022: - return # IPv6 might not be installed on this PC + self.skipTest('IPv6 might not be supported') f = lambda a: inet_ntop(AF_INET6, a) assertInvalid = lambda a: self.assertRaises( @@ -1106,7 +1131,7 @@ def testSockName(self): my_ip_addr = socket.gethostbyname(socket.gethostname()) except OSError: # Probably name lookup wasn't set up right; skip this test - return + self.skipTest('name lookup failure') self.assertIn(name[0], ("0.0.0.0", my_ip_addr), '%s invalid' % name[0]) self.assertEqual(name[1], port) @@ -1148,17 +1173,24 @@ def testNewAttributes(self): sock.close() def test_getsockaddrarg(self): - host = '0.0.0.0' + sock = socket.socket() + self.addCleanup(sock.close) port = support.find_unused_port() big_port = port + 65536 neg_port = port - 65536 - sock = socket.socket() - try: - self.assertRaises(OverflowError, sock.bind, (host, big_port)) - self.assertRaises(OverflowError, sock.bind, (host, neg_port)) - sock.bind((host, port)) - finally: - sock.close() + self.assertRaises(OverflowError, sock.bind, (HOST, big_port)) + self.assertRaises(OverflowError, sock.bind, (HOST, neg_port)) + # Since find_unused_port() is inherently subject to race conditions, we + # call it a couple times if necessary. + for i in itertools.count(): + port = support.find_unused_port() + try: + sock.bind((HOST, port)) + except OSError as e: + if e.errno != errno.EADDRINUSE or i == 5: + raise + else: + break @unittest.skipUnless(os.name == "nt", "Windows specific") def test_sock_ioctl(self): @@ -1201,7 +1233,7 @@ def testGetaddrinfo(self): self.assertEqual(family, socket.AF_INET) self.assertEqual(str(family), 'AddressFamily.AF_INET') self.assertEqual(type, socket.SOCK_STREAM) - self.assertEqual(str(type), 'SocketType.SOCK_STREAM') + self.assertEqual(str(type), 'SocketKind.SOCK_STREAM') infos = socket.getaddrinfo(HOST, None, 0, socket.SOCK_STREAM) for _, socktype, _, _, _ in infos: self.assertEqual(socktype, socket.SOCK_STREAM) @@ -1237,9 +1269,15 @@ def testGetaddrinfo(self): # Issue #6697. self.assertRaises(UnicodeEncodeError, socket.getaddrinfo, 'localhost', '\uD800') - # Issue 17269 + # Issue 17269: test workaround for OS X platform bug segfault if hasattr(socket, 'AI_NUMERICSERV'): - socket.getaddrinfo("localhost", None, 0, 0, 0, socket.AI_NUMERICSERV) + try: + # The arguments here are undefined and the call may succeed + # or fail. All we care here is that it doesn't segfault. + socket.getaddrinfo("localhost", None, 0, 0, 0, + socket.AI_NUMERICSERV) + except socket.gaierror: + pass def test_getnameinfo(self): # only IP addresses are allowed @@ -1255,9 +1293,10 @@ def test_idna(self): if e.errno == socket.EAI_NODATA: self.skipTest('internet access required for this test') # these should all be successful - socket.gethostbyname('иÑпытание.python.org') - socket.gethostbyname_ex('иÑпытание.python.org') - socket.getaddrinfo('иÑпытание.python.org',0,socket.AF_UNSPEC,socket.SOCK_STREAM) + domain = 'иÑпытание.pythontest.net' + socket.gethostbyname(domain) + socket.gethostbyname_ex(domain) + socket.getaddrinfo(domain,0,socket.AF_UNSPEC,socket.SOCK_STREAM) # this may not work if the forward lookup choses the IPv6 address, as that doesn't # have a reverse entry yet # socket.gethostbyaddr('иÑпытание.python.org') @@ -1341,12 +1380,18 @@ def test_pickle(self): def test_listen_backlog(self): for backlog in 0, -1: - srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as srv: + srv.bind((HOST, 0)) + srv.listen(backlog) + + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as srv: srv.bind((HOST, 0)) - srv.listen(backlog) - srv.close() + srv.listen() + @support.cpython_only + def test_listen_backlog_overflow(self): # Issue 15989 + import _testcapi srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM) srv.bind((HOST, 0)) self.assertRaises(OverflowError, srv.listen, _testcapi.INT_MAX + 1) @@ -1364,7 +1409,7 @@ def test_str_for_enums(self): # reprs. with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: self.assertEqual(str(s.family), 'AddressFamily.AF_INET') - self.assertEqual(str(s.type), 'SocketType.SOCK_STREAM') + self.assertEqual(str(s.type), 'SocketKind.SOCK_STREAM') @unittest.skipIf(os.name == 'nt', 'Will not work on Windows') def test_uknown_socket_family_repr(self): @@ -1450,6 +1495,7 @@ def testFilter(self): @unittest.skipUnless(HAVE_SOCKET_CAN, 'SocketCan required for this test.') +@unittest.skipUnless(thread, 'Threading required for this test.') class CANTest(ThreadedCANSocketTest): def __init__(self, methodName='runTest'): @@ -1739,6 +1785,14 @@ def testShutdown(self): self.done.wait() def _testShutdown(self): + self.serv_conn.send(MSG) + self.serv_conn.shutdown(2) + + testShutdown_overflow = support.cpython_only(testShutdown) + + @support.cpython_only + def _testShutdown_overflow(self): + import _testcapi self.serv_conn.send(MSG) # Issue 15989 self.assertRaises(OverflowError, self.serv_conn.shutdown, @@ -2167,7 +2221,7 @@ def _testSendmsgTimeout(self): # Linux supports MSG_DONTWAIT when sending, but in general, it # only works when receiving. Could add other platforms if they # support it too. - @skipWithClientIf(sys.platform not in {"linux2"}, + @skipWithClientIf(sys.platform not in {"linux"}, "MSG_DONTWAIT not known to work on this platform when " "sending") def testSendmsgDontWait(self): @@ -2508,7 +2562,12 @@ class CmsgMacroTests(unittest.TestCase): # code with these functions. # Match the definition in socketmodule.c - socklen_t_limit = min(0x7fffffff, _testcapi.INT_MAX) + try: + import _testcapi + except ImportError: + socklen_t_limit = 0x7fffffff + else: + socklen_t_limit = min(0x7fffffff, _testcapi.INT_MAX) @requireAttrs(socket, "CMSG_LEN") def testCMSG_LEN(self): @@ -3531,7 +3590,7 @@ class InterruptedTimeoutBase(unittest.TestCase): def setUp(self): super().setUp() orig_alrm_handler = signal.signal(signal.SIGALRM, - lambda signum, frame: None) + lambda signum, frame: 1 / 0) self.addCleanup(signal.signal, signal.SIGALRM, orig_alrm_handler) self.addCleanup(self.setAlarm, 0) @@ -3568,13 +3627,11 @@ def setUp(self): self.serv.settimeout(self.timeout) def checkInterruptedRecv(self, func, *args, **kwargs): - # Check that func(*args, **kwargs) raises OSError with an + # Check that func(*args, **kwargs) raises # errno of EINTR when interrupted by a signal. self.setAlarm(self.alarm_time) - with self.assertRaises(OSError) as cm: + with self.assertRaises(ZeroDivisionError) as cm: func(*args, **kwargs) - self.assertNotIsInstance(cm.exception, socket.timeout) - self.assertEqual(cm.exception.errno, errno.EINTR) def testInterruptedRecvTimeout(self): self.checkInterruptedRecv(self.serv.recv, 1024) @@ -3630,19 +3687,17 @@ def checkInterruptedSend(self, func, *args, **kwargs): # Check that func(*args, **kwargs), run in a loop, raises # OSError with an errno of EINTR when interrupted by a # signal. - with self.assertRaises(OSError) as cm: + with self.assertRaises(ZeroDivisionError) as cm: while True: self.setAlarm(self.alarm_time) func(*args, **kwargs) - self.assertNotIsInstance(cm.exception, socket.timeout) - self.assertEqual(cm.exception.errno, errno.EINTR) - # Issue #12958: The following tests have problems on Mac OS X - @support.anticipate_failure(sys.platform == "darwin") + # Issue #12958: The following tests have problems on OS X prior to 10.7 + @support.requires_mac_ver(10, 7) def testInterruptedSendTimeout(self): self.checkInterruptedSend(self.serv_conn.send, b"a"*512) - @support.anticipate_failure(sys.platform == "darwin") + @support.requires_mac_ver(10, 7) def testInterruptedSendtoTimeout(self): # Passing an actual address here as Python's wrapper for # sendto() doesn't allow passing a zero-length one; POSIX @@ -3651,7 +3706,7 @@ def testInterruptedSendtoTimeout(self): self.checkInterruptedSend(self.serv_conn.sendto, b"a"*512, self.serv_addr) - @support.anticipate_failure(sys.platform == "darwin") + @support.requires_mac_ver(10, 7) @requireAttrs(socket.socket, "sendmsg") def testInterruptedSendmsgTimeout(self): self.checkInterruptedSend(self.serv_conn.sendmsg, [b"a"*512]) @@ -3677,8 +3732,6 @@ def _testClose(self): self.cli.connect((HOST, self.port)) time.sleep(1.0) -@unittest.skipUnless(hasattr(socket, 'socketpair'), - 'test needs socket.socketpair()') @unittest.skipUnless(thread, 'Threading required for this test.') class BasicSocketPairTest(SocketPairTest): @@ -3733,14 +3786,23 @@ def testSetBlocking(self): pass end = time.time() self.assertTrue((end - start) < 1.0, "Error setting non-blocking mode.") - # Issue 15989 - if _testcapi.UINT_MAX < _testcapi.ULONG_MAX: - self.serv.setblocking(_testcapi.UINT_MAX + 1) - self.assertIsNone(self.serv.gettimeout()) def _testSetBlocking(self): pass + @support.cpython_only + def testSetBlocking_overflow(self): + # Issue 15989 + import _testcapi + if _testcapi.UINT_MAX >= _testcapi.ULONG_MAX: + self.skipTest('needs UINT_MAX < ULONG_MAX') + self.serv.setblocking(False) + self.assertEqual(self.serv.gettimeout(), 0.0) + self.serv.setblocking(_testcapi.UINT_MAX + 1) + self.assertIsNone(self.serv.gettimeout()) + + _testSetBlocking_overflow = support.cpython_only(_testSetBlocking) + @unittest.skipUnless(hasattr(socket, 'SOCK_NONBLOCK'), 'test needs socket.SOCK_NONBLOCK') @support.requires_linux_version(2, 6, 28) @@ -3750,7 +3812,7 @@ def testInitNonBlocking(self): self.serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM | socket.SOCK_NONBLOCK) self.port = support.bind_port(self.serv) - self.serv.listen(1) + self.serv.listen() # actual testing start = time.time() try: @@ -3996,117 +4058,6 @@ def _testRealClose(self): pass -class FileObjectInterruptedTestCase(unittest.TestCase): - """Test that the file object correctly handles EINTR internally.""" - - class MockSocket(object): - def __init__(self, recv_funcs=()): - # A generator that returns callables that we'll call for each - # call to recv(). - self._recv_step = iter(recv_funcs) - - def recv_into(self, buffer): - data = next(self._recv_step)() - assert len(buffer) >= len(data) - buffer[:len(data)] = data - return len(data) - - def _decref_socketios(self): - pass - - def _textiowrap_for_test(self, buffering=-1): - raw = socket.SocketIO(self, "r") - if buffering < 0: - buffering = io.DEFAULT_BUFFER_SIZE - if buffering == 0: - return raw - buffer = io.BufferedReader(raw, buffering) - text = io.TextIOWrapper(buffer, None, None) - text.mode = "rb" - return text - - @staticmethod - def _raise_eintr(): - raise OSError(errno.EINTR, "interrupted") - - def _textiowrap_mock_socket(self, mock, buffering=-1): - raw = socket.SocketIO(mock, "r") - if buffering < 0: - buffering = io.DEFAULT_BUFFER_SIZE - if buffering == 0: - return raw - buffer = io.BufferedReader(raw, buffering) - text = io.TextIOWrapper(buffer, None, None) - text.mode = "rb" - return text - - def _test_readline(self, size=-1, buffering=-1): - mock_sock = self.MockSocket(recv_funcs=[ - lambda : b"This is the first line\nAnd the sec", - self._raise_eintr, - lambda : b"ond line is here\n", - lambda : b"", - lambda : b"", # XXX(gps): io library does an extra EOF read - ]) - fo = mock_sock._textiowrap_for_test(buffering=buffering) - self.assertEqual(fo.readline(size), "This is the first line\n") - self.assertEqual(fo.readline(size), "And the second line is here\n") - - def _test_read(self, size=-1, buffering=-1): - mock_sock = self.MockSocket(recv_funcs=[ - lambda : b"This is the first line\nAnd the sec", - self._raise_eintr, - lambda : b"ond line is here\n", - lambda : b"", - lambda : b"", # XXX(gps): io library does an extra EOF read - ]) - expecting = (b"This is the first line\n" - b"And the second line is here\n") - fo = mock_sock._textiowrap_for_test(buffering=buffering) - if buffering == 0: - data = b'' - else: - data = '' - expecting = expecting.decode('utf-8') - while len(data) != len(expecting): - part = fo.read(size) - if not part: - break - data += part - self.assertEqual(data, expecting) - - def test_default(self): - self._test_readline() - self._test_readline(size=100) - self._test_read() - self._test_read(size=100) - - def test_with_1k_buffer(self): - self._test_readline(buffering=1024) - self._test_readline(size=100, buffering=1024) - self._test_read(buffering=1024) - self._test_read(size=100, buffering=1024) - - def _test_readline_no_buffer(self, size=-1): - mock_sock = self.MockSocket(recv_funcs=[ - lambda : b"a", - lambda : b"\n", - lambda : b"B", - self._raise_eintr, - lambda : b"b", - lambda : b"", - ]) - fo = mock_sock._textiowrap_for_test(buffering=0) - self.assertEqual(fo.readline(size), b"a\n") - self.assertEqual(fo.readline(size), b"Bb") - - def test_no_buffer(self): - self._test_readline_no_buffer() - self._test_readline_no_buffer(size=4) - self._test_read(buffering=0) - self._test_read(size=100, buffering=0) - - class UnbufferedFileObjectClassTestCase(FileObjectClassTestCase): """Repeat the tests from FileObjectClassTestCase with bufsize==0. @@ -4525,7 +4476,7 @@ def testLinuxAbstractNamespace(self): address = b"\x00python-test-hello\x00\xff" with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s1: s1.bind(address) - s1.listen(1) + s1.listen() with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s2: s2.connect(s1.getsockname()) with s1.accept()[0] as s3: @@ -4683,6 +4634,21 @@ def testRecvFromIntoMemoryview(self): _testRecvFromIntoMemoryview = _testRecvFromIntoArray + def testRecvFromIntoSmallBuffer(self): + # See issue #20246. + buf = bytearray(8) + self.assertRaises(ValueError, self.cli_conn.recvfrom_into, buf, 1024) + + def _testRecvFromIntoSmallBuffer(self): + self.serv_conn.send(MSG) + + def testRecvFromIntoEmptyBuffer(self): + buf = bytearray() + self.cli_conn.recvfrom_into(buf) + self.cli_conn.recvfrom_into(buf, 0) + + _testRecvFromIntoEmptyBuffer = _testRecvFromIntoArray + TIPC_STYPE = 2000 TIPC_LOWER = 200 @@ -4742,7 +4708,7 @@ def setUp(self): srvaddr = (socket.TIPC_ADDR_NAMESEQ, TIPC_STYPE, TIPC_LOWER, TIPC_UPPER) self.srv.bind(srvaddr) - self.srv.listen(5) + self.srv.listen() self.serverExplicitReady() self.conn, self.connaddr = self.srv.accept() self.addCleanup(self.conn.close) @@ -5031,6 +4997,275 @@ def testTypes(self): source.close() +@unittest.skipUnless(thread, 'Threading required for this test.') +class SendfileUsingSendTest(ThreadedTCPSocketTest): + """ + Test the send() implementation of socket.sendfile(). + """ + + FILESIZE = (10 * 1024 * 1024) # 10MB + BUFSIZE = 8192 + FILEDATA = b"" + TIMEOUT = 2 + + @classmethod + def setUpClass(cls): + def chunks(total, step): + assert total >= step + while total > step: + yield step + total -= step + if total: + yield total + + chunk = b"".join([random.choice(string.ascii_letters).encode() + for i in range(cls.BUFSIZE)]) + with open(support.TESTFN, 'wb') as f: + for csize in chunks(cls.FILESIZE, cls.BUFSIZE): + f.write(chunk) + with open(support.TESTFN, 'rb') as f: + cls.FILEDATA = f.read() + assert len(cls.FILEDATA) == cls.FILESIZE + + @classmethod + def tearDownClass(cls): + support.unlink(support.TESTFN) + + def accept_conn(self): + self.serv.settimeout(self.TIMEOUT) + conn, addr = self.serv.accept() + conn.settimeout(self.TIMEOUT) + self.addCleanup(conn.close) + return conn + + def recv_data(self, conn): + received = [] + while True: + chunk = conn.recv(self.BUFSIZE) + if not chunk: + break + received.append(chunk) + return b''.join(received) + + def meth_from_sock(self, sock): + # Depending on the mixin class being run return either send() + # or sendfile() method implementation. + return getattr(sock, "_sendfile_use_send") + + # regular file + + def _testRegularFile(self): + address = self.serv.getsockname() + file = open(support.TESTFN, 'rb') + with socket.create_connection(address) as sock, file as file: + meth = self.meth_from_sock(sock) + sent = meth(file) + self.assertEqual(sent, self.FILESIZE) + self.assertEqual(file.tell(), self.FILESIZE) + + def testRegularFile(self): + conn = self.accept_conn() + data = self.recv_data(conn) + self.assertEqual(len(data), self.FILESIZE) + self.assertEqual(data, self.FILEDATA) + + # non regular file + + def _testNonRegularFile(self): + address = self.serv.getsockname() + file = io.BytesIO(self.FILEDATA) + with socket.create_connection(address) as sock, file as file: + sent = sock.sendfile(file) + self.assertEqual(sent, self.FILESIZE) + self.assertEqual(file.tell(), self.FILESIZE) + self.assertRaises(socket._GiveupOnSendfile, + sock._sendfile_use_sendfile, file) + + def testNonRegularFile(self): + conn = self.accept_conn() + data = self.recv_data(conn) + self.assertEqual(len(data), self.FILESIZE) + self.assertEqual(data, self.FILEDATA) + + # empty file + + def _testEmptyFileSend(self): + address = self.serv.getsockname() + filename = support.TESTFN + "2" + with open(filename, 'wb'): + self.addCleanup(support.unlink, filename) + file = open(filename, 'rb') + with socket.create_connection(address) as sock, file as file: + meth = self.meth_from_sock(sock) + sent = meth(file) + self.assertEqual(sent, 0) + self.assertEqual(file.tell(), 0) + + def testEmptyFileSend(self): + conn = self.accept_conn() + data = self.recv_data(conn) + self.assertEqual(data, b"") + + # offset + + def _testOffset(self): + address = self.serv.getsockname() + file = open(support.TESTFN, 'rb') + with socket.create_connection(address) as sock, file as file: + meth = self.meth_from_sock(sock) + sent = meth(file, offset=5000) + self.assertEqual(sent, self.FILESIZE - 5000) + self.assertEqual(file.tell(), self.FILESIZE) + + def testOffset(self): + conn = self.accept_conn() + data = self.recv_data(conn) + self.assertEqual(len(data), self.FILESIZE - 5000) + self.assertEqual(data, self.FILEDATA[5000:]) + + # count + + def _testCount(self): + address = self.serv.getsockname() + file = open(support.TESTFN, 'rb') + with socket.create_connection(address, timeout=2) as sock, file as file: + count = 5000007 + meth = self.meth_from_sock(sock) + sent = meth(file, count=count) + self.assertEqual(sent, count) + self.assertEqual(file.tell(), count) + + def testCount(self): + count = 5000007 + conn = self.accept_conn() + data = self.recv_data(conn) + self.assertEqual(len(data), count) + self.assertEqual(data, self.FILEDATA[:count]) + + # count small + + def _testCountSmall(self): + address = self.serv.getsockname() + file = open(support.TESTFN, 'rb') + with socket.create_connection(address, timeout=2) as sock, file as file: + count = 1 + meth = self.meth_from_sock(sock) + sent = meth(file, count=count) + self.assertEqual(sent, count) + self.assertEqual(file.tell(), count) + + def testCountSmall(self): + count = 1 + conn = self.accept_conn() + data = self.recv_data(conn) + self.assertEqual(len(data), count) + self.assertEqual(data, self.FILEDATA[:count]) + + # count + offset + + def _testCountWithOffset(self): + address = self.serv.getsockname() + file = open(support.TESTFN, 'rb') + with socket.create_connection(address, timeout=2) as sock, file as file: + count = 100007 + meth = self.meth_from_sock(sock) + sent = meth(file, offset=2007, count=count) + self.assertEqual(sent, count) + self.assertEqual(file.tell(), count + 2007) + + def testCountWithOffset(self): + count = 100007 + conn = self.accept_conn() + data = self.recv_data(conn) + self.assertEqual(len(data), count) + self.assertEqual(data, self.FILEDATA[2007:count+2007]) + + # non blocking sockets are not supposed to work + + def _testNonBlocking(self): + address = self.serv.getsockname() + file = open(support.TESTFN, 'rb') + with socket.create_connection(address) as sock, file as file: + sock.setblocking(False) + meth = self.meth_from_sock(sock) + self.assertRaises(ValueError, meth, file) + self.assertRaises(ValueError, sock.sendfile, file) + + def testNonBlocking(self): + conn = self.accept_conn() + if conn.recv(8192): + self.fail('was not supposed to receive any data') + + # timeout (non-triggered) + + def _testWithTimeout(self): + address = self.serv.getsockname() + file = open(support.TESTFN, 'rb') + with socket.create_connection(address, timeout=2) as sock, file as file: + meth = self.meth_from_sock(sock) + sent = meth(file) + self.assertEqual(sent, self.FILESIZE) + + def testWithTimeout(self): + conn = self.accept_conn() + data = self.recv_data(conn) + self.assertEqual(len(data), self.FILESIZE) + self.assertEqual(data, self.FILEDATA) + + # timeout (triggered) + + def _testWithTimeoutTriggeredSend(self): + address = self.serv.getsockname() + file = open(support.TESTFN, 'rb') + with socket.create_connection(address, timeout=0.01) as sock, \ + file as file: + meth = self.meth_from_sock(sock) + self.assertRaises(socket.timeout, meth, file) + + def testWithTimeoutTriggeredSend(self): + conn = self.accept_conn() + conn.recv(88192) + + # errors + + def _test_errors(self): + pass + + def test_errors(self): + with open(support.TESTFN, 'rb') as file: + with socket.socket(type=socket.SOCK_DGRAM) as s: + meth = self.meth_from_sock(s) + self.assertRaisesRegex( + ValueError, "SOCK_STREAM", meth, file) + with open(support.TESTFN, 'rt') as file: + with socket.socket() as s: + meth = self.meth_from_sock(s) + self.assertRaisesRegex( + ValueError, "binary mode", meth, file) + with open(support.TESTFN, 'rb') as file: + with socket.socket() as s: + meth = self.meth_from_sock(s) + self.assertRaisesRegex(TypeError, "positive integer", + meth, file, count='2') + self.assertRaisesRegex(TypeError, "positive integer", + meth, file, count=0.1) + self.assertRaisesRegex(ValueError, "positive integer", + meth, file, count=0) + self.assertRaisesRegex(ValueError, "positive integer", + meth, file, count=-1) + + +@unittest.skipUnless(thread, 'Threading required for this test.') +@unittest.skipUnless(hasattr(os, "sendfile"), + 'os.sendfile() required for this test.') +class SendfileUsingSendfileTest(SendfileUsingSendTest): + """ + Test the sendfile() implementation of socket.sendfile(). + """ + def meth_from_sock(self, sock): + return getattr(sock, "_sendfile_use_sendfile") + + def test_main(): tests = [GeneralModuleTests, BasicTCPTest, TCPCloserTest, TCPTimeoutTest, TestExceptions, BufferIOTest, BasicTCPTest2, BasicUDPTest, UDPTimeoutTest ] @@ -5038,7 +5273,6 @@ def test_main(): tests.extend([ NonBlockingTCPTests, FileObjectClassTestCase, - FileObjectInterruptedTestCase, UnbufferedFileObjectClassTestCase, LineBufferedFileObjectClassTestCase, SmallBufferedFileObjectClassTestCase, @@ -5083,6 +5317,8 @@ def test_main(): InterruptedRecvTimeoutTest, InterruptedSendTimeoutTest, TestSocketSharing, + SendfileUsingSendTest, + SendfileUsingSendfileTest, ]) thread_info = support.threading_setup() diff --git a/Lib/test/test_socketserver.py b/Lib/test/test_socketserver.py index 0617b30a69e7..31ab3b64f569 100644 --- a/Lib/test/test_socketserver.py +++ b/Lib/test/test_socketserver.py @@ -2,7 +2,6 @@ Test suite for socketserver. """ -import _imp as imp import contextlib import os import select @@ -222,38 +221,6 @@ def test_ForkingUDPServer(self): socketserver.DatagramRequestHandler, self.dgram_examine) - @contextlib.contextmanager - def mocked_select_module(self): - """Mocks the select.select() call to raise EINTR for first call""" - old_select = select.select - - class MockSelect: - def __init__(self): - self.called = 0 - - def __call__(self, *args): - self.called += 1 - if self.called == 1: - # raise the exception on first call - raise OSError(errno.EINTR, os.strerror(errno.EINTR)) - else: - # Return real select value for consecutive calls - return old_select(*args) - - select.select = MockSelect() - try: - yield select.select - finally: - select.select = old_select - - def test_InterruptServerSelectCall(self): - with self.mocked_select_module() as mock_select: - pid = self.run_server(socketserver.TCPServer, - socketserver.StreamRequestHandler, - self.stream_examine) - # Make sure select was called again: - self.assertGreater(mock_select.called, 1) - # Alas, on Linux (at least) recvfrom() doesn't return a meaningful # client address so this cannot work: @@ -302,13 +269,29 @@ class MyHandler(socketserver.StreamRequestHandler): t.join() s.server_close() + def test_tcpserver_bind_leak(self): + # Issue #22435: the server socket wouldn't be closed if bind()/listen() + # failed. + # Create many servers for which bind() will fail, to see if this result + # in FD exhaustion. + for i in range(1024): + with self.assertRaises(OverflowError): + socketserver.TCPServer((HOST, -1), + socketserver.StreamRequestHandler) + + +class MiscTestCase(unittest.TestCase): -def test_main(): - if imp.lock_held(): - # If the import lock is held, the threads will hang - raise unittest.SkipTest("can't run when import lock is held") + def test_all(self): + # objects defined in the module should be in __all__ + expected = [] + for name in dir(socketserver): + if not name.startswith('_'): + mod_object = getattr(socketserver, name) + if getattr(mod_object, '__module__', None) == 'socketserver': + expected.append(name) + self.assertCountEqual(socketserver.__all__, expected) - test.support.run_unittest(SocketServerTest) if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_source_encoding.py b/Lib/test/test_source_encoding.py index cd9d2b374c73..39a7c56019ba 100644 --- a/Lib/test/test_source_encoding.py +++ b/Lib/test/test_source_encoding.py @@ -1,10 +1,11 @@ # -*- coding: koi8-r -*- import unittest -from test.support import TESTFN, unlink, unload +from test.support import TESTFN, unlink, unload, rmtree import importlib import os import sys +import subprocess class SourceEncodingTest(unittest.TestCase): @@ -58,6 +59,15 @@ def test_issue7820(self): # two bytes in common with the UTF-8 BOM self.assertRaises(SyntaxError, eval, b'\xef\xbb\x20') + def test_20731(self): + sub = subprocess.Popen([sys.executable, + os.path.join(os.path.dirname(__file__), + 'coding20731.py')], + stderr=subprocess.PIPE) + err = sub.communicate()[1] + self.assertEqual(sub.returncode, 0) + self.assertNotIn(b'SyntaxError', err) + def test_error_message(self): compile(b'# -*- coding: iso-8859-15 -*-\n', 'dummy', 'exec') compile(b'\xef\xbb\xbf\n', 'dummy', 'exec') @@ -119,6 +129,7 @@ def test_file_parse(self): unlink(filename + "c") unlink(filename + "o") unload(TESTFN) + rmtree('__pycache__') def test_error_from_string(self): # See http://bugs.python.org/issue6289 diff --git a/Lib/test/test_spwd.py b/Lib/test/test_spwd.py new file mode 100644 index 000000000000..bea7ab1ba5d2 --- /dev/null +++ b/Lib/test/test_spwd.py @@ -0,0 +1,60 @@ +import os +import unittest +from test import support + +spwd = support.import_module('spwd') + + +@unittest.skipUnless(hasattr(os, 'geteuid') and os.geteuid() == 0, + 'root privileges required') +class TestSpwdRoot(unittest.TestCase): + + def test_getspall(self): + entries = spwd.getspall() + self.assertIsInstance(entries, list) + for entry in entries: + self.assertIsInstance(entry, spwd.struct_spwd) + + def test_getspnam(self): + entries = spwd.getspall() + if not entries: + self.skipTest('empty shadow password database') + random_name = entries[0].sp_namp + entry = spwd.getspnam(random_name) + self.assertIsInstance(entry, spwd.struct_spwd) + self.assertEqual(entry.sp_namp, random_name) + self.assertEqual(entry.sp_namp, entry[0]) + self.assertEqual(entry.sp_namp, entry.sp_nam) + self.assertIsInstance(entry.sp_pwdp, str) + self.assertEqual(entry.sp_pwdp, entry[1]) + self.assertEqual(entry.sp_pwdp, entry.sp_pwd) + self.assertIsInstance(entry.sp_lstchg, int) + self.assertEqual(entry.sp_lstchg, entry[2]) + self.assertIsInstance(entry.sp_min, int) + self.assertEqual(entry.sp_min, entry[3]) + self.assertIsInstance(entry.sp_max, int) + self.assertEqual(entry.sp_max, entry[4]) + self.assertIsInstance(entry.sp_warn, int) + self.assertEqual(entry.sp_warn, entry[5]) + self.assertIsInstance(entry.sp_inact, int) + self.assertEqual(entry.sp_inact, entry[6]) + self.assertIsInstance(entry.sp_expire, int) + self.assertEqual(entry.sp_expire, entry[7]) + self.assertIsInstance(entry.sp_flag, int) + self.assertEqual(entry.sp_flag, entry[8]) + with self.assertRaises(KeyError) as cx: + spwd.getspnam('invalid user name') + self.assertEqual(str(cx.exception), "'getspnam(): name not found'") + self.assertRaises(TypeError, spwd.getspnam) + self.assertRaises(TypeError, spwd.getspnam, 0) + self.assertRaises(TypeError, spwd.getspnam, random_name, 0) + try: + bytes_name = os.fsencode(random_name) + except UnicodeEncodeError: + pass + else: + self.assertRaises(TypeError, spwd.getspnam, bytes_name) + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index ed263c397412..ce427b4db2c7 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -86,6 +86,12 @@ def have_verify_flags(): # 0.9.8 or higher return ssl.OPENSSL_VERSION_INFO >= (0, 9, 8, 0, 15) +def utc_offset(): #NOTE: ignore issues like #1647654 + # local time = utc time + utc offset + if time.daylight and time.localtime().tm_isdst > 0: + return -time.altzone # seconds + return -time.timezone + def asn1time(cert_time): # Some versions of OpenSSL ignore seconds, see #18207 # 0.9.8.i @@ -134,6 +140,14 @@ def test_constants(self): self.assertIn(ssl.HAS_SNI, {True, False}) self.assertIn(ssl.HAS_ECDH, {True, False}) + def test_str_for_enums(self): + # Make sure that the PROTOCOL_* constants have enum-like string + # reprs. + proto = ssl.PROTOCOL_SSLv23 + self.assertEqual(str(proto), '_SSLMethod.PROTOCOL_SSLv23') + ctx = ssl.SSLContext(proto) + self.assertIs(ctx.protocol, proto) + def test_random(self): v = ssl.RAND_status() if support.verbose: @@ -150,8 +164,13 @@ def test_random(self): else: self.assertRaises(ssl.SSLError, ssl.RAND_bytes, 16) - self.assertRaises(TypeError, ssl.RAND_egd, 1) - self.assertRaises(TypeError, ssl.RAND_egd, 'foo', 1) + # negative num is invalid + self.assertRaises(ValueError, ssl.RAND_bytes, -5) + self.assertRaises(ValueError, ssl.RAND_pseudo_bytes, -5) + + if hasattr(ssl, 'RAND_egd'): + self.assertRaises(TypeError, ssl.RAND_egd, 1) + self.assertRaises(TypeError, ssl.RAND_egd, 'foo', 1) ssl.RAND_add("this is a random string", 75.0) @unittest.skipUnless(os.name == 'posix', 'requires posix') @@ -277,22 +296,26 @@ def test_openssl_version(self): # Some sanity checks follow # >= 0.9 self.assertGreaterEqual(n, 0x900000) - # < 2.0 - self.assertLess(n, 0x20000000) + # < 3.0 + self.assertLess(n, 0x30000000) major, minor, fix, patch, status = t self.assertGreaterEqual(major, 0) - self.assertLess(major, 2) + self.assertLess(major, 3) self.assertGreaterEqual(minor, 0) self.assertLess(minor, 256) self.assertGreaterEqual(fix, 0) self.assertLess(fix, 256) self.assertGreaterEqual(patch, 0) - self.assertLessEqual(patch, 26) + self.assertLessEqual(patch, 63) self.assertGreaterEqual(status, 0) self.assertLessEqual(status, 15) - # Version string as returned by OpenSSL, the format might change - self.assertTrue(s.startswith("OpenSSL {:d}.{:d}.{:d}".format(major, minor, fix)), - (s, t)) + # Version string as returned by {Open,Libre}SSL, the format might change + if "LibreSSL" in s: + self.assertTrue(s.startswith("LibreSSL {:d}.{:d}".format(major, minor)), + (s, t, hex(n))) + else: + self.assertTrue(s.startswith("OpenSSL {:d}.{:d}.{:d}".format(major, minor, fix)), + (s, t, hex(n))) @support.cpython_only def test_refcycle(self): @@ -360,6 +383,8 @@ def fail(cert, hostname): self.assertRaises(ssl.CertificateError, ssl.match_hostname, cert, hostname) + # -- Hostname matching -- + cert = {'subject': ((('commonName', 'example.com'),),)} ok(cert, 'example.com') ok(cert, 'ExAmple.cOm') @@ -445,6 +470,28 @@ def fail(cert, hostname): # Only commonName is considered fail(cert, 'California') + # -- IPv4 matching -- + cert = {'subject': ((('commonName', 'example.com'),),), + 'subjectAltName': (('DNS', 'example.com'), + ('IP Address', '10.11.12.13'), + ('IP Address', '14.15.16.17'))} + ok(cert, '10.11.12.13') + ok(cert, '14.15.16.17') + fail(cert, '14.15.16.18') + fail(cert, 'example.net') + + # -- IPv6 matching -- + cert = {'subject': ((('commonName', 'example.com'),),), + 'subjectAltName': (('DNS', 'example.com'), + ('IP Address', '2001:0:0:0:0:0:0:CAFE\n'), + ('IP Address', '2003:0:0:0:0:0:0:BABA\n'))} + ok(cert, '2001::cafe') + ok(cert, '2003::baba') + fail(cert, '2003::bebe') + fail(cert, 'example.net') + + # -- Miscellaneous -- + # Neither commonName nor subjectAltName cert = {'notAfter': 'Dec 18 23:59:59 2011 GMT', 'subject': ((('countryName', 'US'),), @@ -496,9 +543,14 @@ def test_server_side(self): def test_unknown_channel_binding(self): # should raise ValueError for unknown type s = socket.socket(socket.AF_INET) - with ssl.wrap_socket(s) as ss: + s.bind(('127.0.0.1', 0)) + s.listen() + c = socket.socket(socket.AF_INET) + c.connect(s.getsockname()) + with ssl.wrap_socket(c, do_handshake_on_connect=False) as ss: with self.assertRaises(ValueError): ss.get_channel_binding("unknown-type") + s.close() @unittest.skipUnless("tls-unique" in ssl.CHANNEL_BINDING_TYPES, "'tls-unique' channel binding not available") @@ -628,6 +680,82 @@ def test_purpose_enum(self): self.assertEqual(ssl.Purpose.CLIENT_AUTH.oid, '1.3.6.1.5.5.7.3.2') + def test_unsupported_dtls(self): + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + self.addCleanup(s.close) + with self.assertRaises(NotImplementedError) as cx: + ssl.wrap_socket(s, cert_reqs=ssl.CERT_NONE) + self.assertEqual(str(cx.exception), "only stream sockets are supported") + ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23) + with self.assertRaises(NotImplementedError) as cx: + ctx.wrap_socket(s) + self.assertEqual(str(cx.exception), "only stream sockets are supported") + + def cert_time_ok(self, timestring, timestamp): + self.assertEqual(ssl.cert_time_to_seconds(timestring), timestamp) + + def cert_time_fail(self, timestring): + with self.assertRaises(ValueError): + ssl.cert_time_to_seconds(timestring) + + @unittest.skipUnless(utc_offset(), + 'local time needs to be different from UTC') + def test_cert_time_to_seconds_timezone(self): + # Issue #19940: ssl.cert_time_to_seconds() returns wrong + # results if local timezone is not UTC + self.cert_time_ok("May 9 00:00:00 2007 GMT", 1178668800.0) + self.cert_time_ok("Jan 5 09:34:43 2018 GMT", 1515144883.0) + + def test_cert_time_to_seconds(self): + timestring = "Jan 5 09:34:43 2018 GMT" + ts = 1515144883.0 + self.cert_time_ok(timestring, ts) + # accept keyword parameter, assert its name + self.assertEqual(ssl.cert_time_to_seconds(cert_time=timestring), ts) + # accept both %e and %d (space or zero generated by strftime) + self.cert_time_ok("Jan 05 09:34:43 2018 GMT", ts) + # case-insensitive + self.cert_time_ok("JaN 5 09:34:43 2018 GmT", ts) + self.cert_time_fail("Jan 5 09:34 2018 GMT") # no seconds + self.cert_time_fail("Jan 5 09:34:43 2018") # no GMT + self.cert_time_fail("Jan 5 09:34:43 2018 UTC") # not GMT timezone + self.cert_time_fail("Jan 35 09:34:43 2018 GMT") # invalid day + self.cert_time_fail("Jon 5 09:34:43 2018 GMT") # invalid month + self.cert_time_fail("Jan 5 24:00:00 2018 GMT") # invalid hour + self.cert_time_fail("Jan 5 09:60:43 2018 GMT") # invalid minute + + newyear_ts = 1230768000.0 + # leap seconds + self.cert_time_ok("Dec 31 23:59:60 2008 GMT", newyear_ts) + # same timestamp + self.cert_time_ok("Jan 1 00:00:00 2009 GMT", newyear_ts) + + self.cert_time_ok("Jan 5 09:34:59 2018 GMT", 1515144899) + # allow 60th second (even if it is not a leap second) + self.cert_time_ok("Jan 5 09:34:60 2018 GMT", 1515144900) + # allow 2nd leap second for compatibility with time.strptime() + self.cert_time_ok("Jan 5 09:34:61 2018 GMT", 1515144901) + self.cert_time_fail("Jan 5 09:34:62 2018 GMT") # invalid seconds + + # no special treatement for the special value: + # 99991231235959Z (rfc 5280) + self.cert_time_ok("Dec 31 23:59:59 9999 GMT", 253402300799.0) + + @support.run_with_locale('LC_ALL', '') + def test_cert_time_to_seconds_locale(self): + # `cert_time_to_seconds()` should be locale independent + + def local_february_name(): + return time.strftime('%b', (1, 2, 3, 4, 5, 6, 0, 0, 0)) + + if local_february_name().lower() == 'feb': + self.skipTest("locale-specific month name needs to be " + "different from C locale") + + # locale-independent + self.cert_time_ok("Feb 9 00:00:00 2007 GMT", 1170979200.0) + self.cert_time_fail(local_february_name() + " 9 00:00:00 2007 GMT") + class ContextTests(unittest.TestCase): @@ -655,9 +783,7 @@ def test_ciphers(self): @skip_if_broken_ubuntu_ssl def test_options(self): ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) - # OP_ALL is the default value - self.assertEqual(ssl.OP_ALL, ctx.options) - ctx.options |= ssl.OP_NO_SSLv2 + # OP_ALL | OP_NO_SSLv2 is the default value self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2, ctx.options) ctx.options |= ssl.OP_NO_SSLv3 @@ -710,7 +836,7 @@ def test_verify_flags(self): def test_load_cert_chain(self): ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) # Combined key and cert in a single file - ctx.load_cert_chain(CERTFILE) + ctx.load_cert_chain(CERTFILE, keyfile=None) ctx.load_cert_chain(CERTFILE, keyfile=CERTFILE) self.assertRaises(TypeError, ctx.load_cert_chain, keyfile=CERTFILE) with self.assertRaises(OSError) as cm: @@ -999,25 +1125,68 @@ def test_load_default_certs(self): self.assertRaises(TypeError, ctx.load_default_certs, None) self.assertRaises(TypeError, ctx.load_default_certs, 'SERVER_AUTH') + @unittest.skipIf(sys.platform == "win32", "not-Windows specific") + def test_load_default_certs_env(self): + ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) + with support.EnvironmentVarGuard() as env: + env["SSL_CERT_DIR"] = CAPATH + env["SSL_CERT_FILE"] = CERTFILE + ctx.load_default_certs() + self.assertEqual(ctx.cert_store_stats(), {"crl": 0, "x509": 1, "x509_ca": 0}) + + @unittest.skipUnless(sys.platform == "win32", "Windows specific") + def test_load_default_certs_env_windows(self): + ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) + ctx.load_default_certs() + stats = ctx.cert_store_stats() + + ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) + with support.EnvironmentVarGuard() as env: + env["SSL_CERT_DIR"] = CAPATH + env["SSL_CERT_FILE"] = CERTFILE + ctx.load_default_certs() + stats["x509"] += 1 + self.assertEqual(ctx.cert_store_stats(), stats) + def test_create_default_context(self): ctx = ssl.create_default_context() - self.assertEqual(ctx.protocol, ssl.PROTOCOL_TLSv1) + self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23) self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED) self.assertTrue(ctx.check_hostname) self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2) + self.assertEqual( + ctx.options & getattr(ssl, "OP_NO_COMPRESSION", 0), + getattr(ssl, "OP_NO_COMPRESSION", 0), + ) with open(SIGNING_CA) as f: cadata = f.read() ctx = ssl.create_default_context(cafile=SIGNING_CA, capath=CAPATH, cadata=cadata) - self.assertEqual(ctx.protocol, ssl.PROTOCOL_TLSv1) + self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23) self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED) self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2) + self.assertEqual( + ctx.options & getattr(ssl, "OP_NO_COMPRESSION", 0), + getattr(ssl, "OP_NO_COMPRESSION", 0), + ) ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) - self.assertEqual(ctx.protocol, ssl.PROTOCOL_TLSv1) + self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23) self.assertEqual(ctx.verify_mode, ssl.CERT_NONE) self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2) + self.assertEqual( + ctx.options & getattr(ssl, "OP_NO_COMPRESSION", 0), + getattr(ssl, "OP_NO_COMPRESSION", 0), + ) + self.assertEqual( + ctx.options & getattr(ssl, "OP_SINGLE_DH_USE", 0), + getattr(ssl, "OP_SINGLE_DH_USE", 0), + ) + self.assertEqual( + ctx.options & getattr(ssl, "OP_SINGLE_ECDH_USE", 0), + getattr(ssl, "OP_SINGLE_ECDH_USE", 0), + ) def test__create_stdlib_context(self): ctx = ssl._create_stdlib_context() @@ -1032,9 +1201,11 @@ def test__create_stdlib_context(self): self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2) ctx = ssl._create_stdlib_context(ssl.PROTOCOL_TLSv1, - cert_reqs=ssl.CERT_REQUIRED) + cert_reqs=ssl.CERT_REQUIRED, + check_hostname=True) self.assertEqual(ctx.protocol, ssl.PROTOCOL_TLSv1) self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED) + self.assertTrue(ctx.check_hostname) self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2) ctx = ssl._create_stdlib_context(purpose=ssl.Purpose.CLIENT_AUTH) @@ -1093,7 +1264,7 @@ def test_subclass(self): ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) with socket.socket() as s: s.bind(("127.0.0.1", 0)) - s.listen(5) + s.listen() c = socket.socket() c.connect(s.getsockname()) c.setblocking(False) @@ -1106,6 +1277,69 @@ def test_subclass(self): self.assertEqual(cm.exception.errno, ssl.SSL_ERROR_WANT_READ) +class MemoryBIOTests(unittest.TestCase): + + def test_read_write(self): + bio = ssl.MemoryBIO() + bio.write(b'foo') + self.assertEqual(bio.read(), b'foo') + self.assertEqual(bio.read(), b'') + bio.write(b'foo') + bio.write(b'bar') + self.assertEqual(bio.read(), b'foobar') + self.assertEqual(bio.read(), b'') + bio.write(b'baz') + self.assertEqual(bio.read(2), b'ba') + self.assertEqual(bio.read(1), b'z') + self.assertEqual(bio.read(1), b'') + + def test_eof(self): + bio = ssl.MemoryBIO() + self.assertFalse(bio.eof) + self.assertEqual(bio.read(), b'') + self.assertFalse(bio.eof) + bio.write(b'foo') + self.assertFalse(bio.eof) + bio.write_eof() + self.assertFalse(bio.eof) + self.assertEqual(bio.read(2), b'fo') + self.assertFalse(bio.eof) + self.assertEqual(bio.read(1), b'o') + self.assertTrue(bio.eof) + self.assertEqual(bio.read(), b'') + self.assertTrue(bio.eof) + + def test_pending(self): + bio = ssl.MemoryBIO() + self.assertEqual(bio.pending, 0) + bio.write(b'foo') + self.assertEqual(bio.pending, 3) + for i in range(3): + bio.read(1) + self.assertEqual(bio.pending, 3-i-1) + for i in range(3): + bio.write(b'x') + self.assertEqual(bio.pending, i+1) + bio.read() + self.assertEqual(bio.pending, 0) + + def test_buffer_types(self): + bio = ssl.MemoryBIO() + bio.write(b'foo') + self.assertEqual(bio.read(), b'foo') + bio.write(bytearray(b'bar')) + self.assertEqual(bio.read(), b'bar') + bio.write(memoryview(b'baz')) + self.assertEqual(bio.read(), b'baz') + + def test_error_types(self): + bio = ssl.MemoryBIO() + self.assertRaises(TypeError, bio.write, 'foo') + self.assertRaises(TypeError, bio.write, None) + self.assertRaises(TypeError, bio.write, True) + self.assertRaises(TypeError, bio.write, 1) + + class NetworkedTests(unittest.TestCase): def test_connect(self): @@ -1199,8 +1433,10 @@ def test_connect_ex_error(self): cert_reqs=ssl.CERT_REQUIRED, ca_certs=SVN_PYTHON_ORG_ROOT_CERT) try: - self.assertEqual(errno.ECONNREFUSED, - s.connect_ex(("svn.python.org", 444))) + rc = s.connect_ex(("svn.python.org", 444)) + # Issue #19919: Windows machines or VMs hosted on Windows + # machines sometimes return EWOULDBLOCK. + self.assertIn(rc, (errno.ECONNREFUSED, errno.EWOULDBLOCK)) finally: s.close() @@ -1217,11 +1453,8 @@ def test_connect_with_context(self): # Same with a server hostname s = ctx.wrap_socket(socket.socket(socket.AF_INET), server_hostname="svn.python.org") - if ssl.HAS_SNI: - s.connect(("svn.python.org", 443)) - s.close() - else: - self.assertRaises(ValueError, s.connect, ("svn.python.org", 443)) + s.connect(("svn.python.org", 443)) + s.close() # This should fail because we have no verification certs ctx.verify_mode = ssl.CERT_REQUIRED s = ctx.wrap_socket(socket.socket(socket.AF_INET)) @@ -1339,7 +1572,8 @@ def _test_get_server_certificate(host, port, cert=None): self.fail("No server certificate on %s:%s!" % (host, port)) try: - pem = ssl.get_server_certificate((host, port), ca_certs=CERTFILE) + pem = ssl.get_server_certificate((host, port), + ca_certs=CERTFILE) except ssl.SSLError as x: #should fail if support.verbose: @@ -1347,7 +1581,8 @@ def _test_get_server_certificate(host, port, cert=None): else: self.fail("Got server certificate %s for %s:%s!" % (pem, host, port)) - pem = ssl.get_server_certificate((host, port), ca_certs=cert) + pem = ssl.get_server_certificate((host, port), + ca_certs=cert) if not pem: self.fail("No server certificate on %s:%s!" % (host, port)) if support.verbose: @@ -1417,6 +1652,108 @@ def test_get_ca_certs_capath(self): s.close() self.assertEqual(len(ctx.get_ca_certs()), 1) + @needs_sni + def test_context_setget(self): + # Check that the context of a connected socket can be replaced. + with support.transient_internet("svn.python.org"): + ctx1 = ssl.SSLContext(ssl.PROTOCOL_TLSv1) + ctx2 = ssl.SSLContext(ssl.PROTOCOL_SSLv23) + s = socket.socket(socket.AF_INET) + with ctx1.wrap_socket(s) as ss: + ss.connect(("svn.python.org", 443)) + self.assertIs(ss.context, ctx1) + self.assertIs(ss._sslobj.context, ctx1) + ss.context = ctx2 + self.assertIs(ss.context, ctx2) + self.assertIs(ss._sslobj.context, ctx2) + + +class NetworkedBIOTests(unittest.TestCase): + + def ssl_io_loop(self, sock, incoming, outgoing, func, *args, **kwargs): + # A simple IO loop. Call func(*args) depending on the error we get + # (WANT_READ or WANT_WRITE) move data between the socket and the BIOs. + timeout = kwargs.get('timeout', 10) + count = 0 + while True: + errno = None + count += 1 + try: + ret = func(*args) + except ssl.SSLError as e: + # Note that we get a spurious -1/SSL_ERROR_SYSCALL for + # non-blocking IO. The SSL_shutdown manpage hints at this. + # It *should* be safe to just ignore SYS_ERROR_SYSCALL because + # with a Memory BIO there's no syscalls (for IO at least). + if e.errno not in (ssl.SSL_ERROR_WANT_READ, + ssl.SSL_ERROR_WANT_WRITE, + ssl.SSL_ERROR_SYSCALL): + raise + errno = e.errno + # Get any data from the outgoing BIO irrespective of any error, and + # send it to the socket. + buf = outgoing.read() + sock.sendall(buf) + # If there's no error, we're done. For WANT_READ, we need to get + # data from the socket and put it in the incoming BIO. + if errno is None: + break + elif errno == ssl.SSL_ERROR_WANT_READ: + buf = sock.recv(32768) + if buf: + incoming.write(buf) + else: + incoming.write_eof() + if support.verbose: + sys.stdout.write("Needed %d calls to complete %s().\n" + % (count, func.__name__)) + return ret + + def test_handshake(self): + with support.transient_internet("svn.python.org"): + sock = socket.socket(socket.AF_INET) + sock.connect(("svn.python.org", 443)) + incoming = ssl.MemoryBIO() + outgoing = ssl.MemoryBIO() + ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23) + ctx.verify_mode = ssl.CERT_REQUIRED + ctx.load_verify_locations(SVN_PYTHON_ORG_ROOT_CERT) + ctx.check_hostname = True + sslobj = ctx.wrap_bio(incoming, outgoing, False, 'svn.python.org') + self.assertIs(sslobj._sslobj.owner, sslobj) + self.assertIsNone(sslobj.cipher()) + self.assertIsNone(sslobj.shared_ciphers()) + self.assertRaises(ValueError, sslobj.getpeercert) + if 'tls-unique' in ssl.CHANNEL_BINDING_TYPES: + self.assertIsNone(sslobj.get_channel_binding('tls-unique')) + self.ssl_io_loop(sock, incoming, outgoing, sslobj.do_handshake) + self.assertTrue(sslobj.cipher()) + self.assertIsNone(sslobj.shared_ciphers()) + self.assertTrue(sslobj.getpeercert()) + if 'tls-unique' in ssl.CHANNEL_BINDING_TYPES: + self.assertTrue(sslobj.get_channel_binding('tls-unique')) + self.ssl_io_loop(sock, incoming, outgoing, sslobj.unwrap) + self.assertRaises(ssl.SSLError, sslobj.write, b'foo') + sock.close() + + def test_read_write_data(self): + with support.transient_internet("svn.python.org"): + sock = socket.socket(socket.AF_INET) + sock.connect(("svn.python.org", 443)) + incoming = ssl.MemoryBIO() + outgoing = ssl.MemoryBIO() + ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23) + ctx.verify_mode = ssl.CERT_NONE + sslobj = ctx.wrap_bio(incoming, outgoing, False) + self.ssl_io_loop(sock, incoming, outgoing, sslobj.do_handshake) + req = b'GET / HTTP/1.0\r\n\r\n' + self.ssl_io_loop(sock, incoming, outgoing, sslobj.write, req) + buf = self.ssl_io_loop(sock, incoming, outgoing, sslobj.read, 1024) + self.assertEqual(buf[:5], b'HTTP/') + self.ssl_io_loop(sock, incoming, outgoing, sslobj.unwrap) + sock.close() + + try: import threading except ImportError: @@ -1448,7 +1785,8 @@ def wrap_conn(self): try: self.sslconn = self.server.context.wrap_socket( self.sock, server_side=True) - self.server.selected_protocols.append(self.sslconn.selected_npn_protocol()) + self.server.selected_npn_protocols.append(self.sslconn.selected_npn_protocol()) + self.server.selected_alpn_protocols.append(self.sslconn.selected_alpn_protocol()) except (ssl.SSLError, ConnectionResetError) as e: # We treat ConnectionResetError as though it were an # SSLError - OpenSSL on Ubuntu abruptly closes the @@ -1465,6 +1803,7 @@ def wrap_conn(self): self.close() return False else: + self.server.shared_ciphers.append(self.sslconn.shared_ciphers()) if self.server.context.verify_mode == ssl.CERT_REQUIRED: cert = self.sslconn.getpeercert() if support.verbose and self.server.chatty: @@ -1555,7 +1894,8 @@ def run(self): def __init__(self, certificate=None, ssl_version=None, certreqs=None, cacerts=None, chatty=True, connectionchatty=False, starttls_server=False, - npn_protocols=None, ciphers=None, context=None): + npn_protocols=None, alpn_protocols=None, + ciphers=None, context=None): if context: self.context = context else: @@ -1570,6 +1910,8 @@ def __init__(self, certificate=None, ssl_version=None, self.context.load_cert_chain(certificate) if npn_protocols: self.context.set_npn_protocols(npn_protocols) + if alpn_protocols: + self.context.set_alpn_protocols(alpn_protocols) if ciphers: self.context.set_ciphers(ciphers) self.chatty = chatty @@ -1579,7 +1921,9 @@ def __init__(self, certificate=None, ssl_version=None, self.port = support.bind_port(self.sock) self.flag = None self.active = False - self.selected_protocols = [] + self.selected_npn_protocols = [] + self.selected_alpn_protocols = [] + self.shared_ciphers = [] self.conn_errors = [] threading.Thread.__init__(self) self.daemon = True @@ -1599,7 +1943,7 @@ def start(self, flag=None): def run(self): self.sock.settimeout(0.05) - self.sock.listen(5) + self.sock.listen() self.active = True if self.flag: # signal an event @@ -1805,14 +2149,25 @@ def server_params_test(client_context, server_context, indata=b"FOO\n", 'compression': s.compression(), 'cipher': s.cipher(), 'peercert': s.getpeercert(), - 'client_npn_protocol': s.selected_npn_protocol() + 'client_alpn_protocol': s.selected_alpn_protocol(), + 'client_npn_protocol': s.selected_npn_protocol(), + 'version': s.version(), }) s.close() - stats['server_npn_protocols'] = server.selected_protocols + stats['server_alpn_protocols'] = server.selected_alpn_protocols + stats['server_npn_protocols'] = server.selected_npn_protocols + stats['server_shared_ciphers'] = server.shared_ciphers return stats def try_protocol_combo(server_protocol, client_protocol, expect_success, certsreqs=None, server_options=0, client_options=0): + """ + Try to SSL-connect using *client_protocol* to *server_protocol*. + If *expect_success* is true, assert that the connection succeeds, + if it's false, assert that the connection fails. + Also, if *expect_success* is a string, assert that it is the protocol + version actually used by the connection. + """ if certsreqs is None: certsreqs = ssl.CERT_NONE certtype = { @@ -1827,9 +2182,9 @@ def try_protocol_combo(server_protocol, client_protocol, expect_success, ssl.get_protocol_name(server_protocol), certtype)) client_context = ssl.SSLContext(client_protocol) - client_context.options = ssl.OP_ALL | client_options + client_context.options |= client_options server_context = ssl.SSLContext(server_protocol) - server_context.options = ssl.OP_ALL | server_options + server_context.options |= server_options # NOTE: we must enable "ALL" ciphers on the client, otherwise an # SSLv23 client will send an SSLv3 hello (rather than SSLv2) @@ -1842,8 +2197,8 @@ def try_protocol_combo(server_protocol, client_protocol, expect_success, ctx.load_cert_chain(CERTFILE) ctx.load_verify_locations(CERTFILE) try: - server_params_test(client_context, server_context, - chatty=False, connectionchatty=False) + stats = server_params_test(client_context, server_context, + chatty=False, connectionchatty=False) # Protocol mismatch can result in either an SSLError, or a # "Connection reset by peer" error. except ssl.SSLError: @@ -1858,6 +2213,10 @@ def try_protocol_combo(server_protocol, client_protocol, expect_success, "Client protocol %s succeeded with server protocol %s!" % (ssl.get_protocol_name(client_protocol), ssl.get_protocol_name(server_protocol))) + elif (expect_success is not True + and expect_success != stats['version']): + raise AssertionError("version mismatch: expected %r, got %r" + % (expect_success, stats['version'])) class ThreadedTests(unittest.TestCase): @@ -2024,7 +2383,7 @@ def test_rude_shutdown(self): # and sets Event `listener_gone` to let the main thread know # the socket is gone. def listener(): - s.listen(5) + s.listen() listener_ready.set() newsock, addr = s.accept() newsock.close() @@ -2060,17 +2419,18 @@ def test_protocol_sslv2(self): try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True) try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL) try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED) - try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True) - try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False) + try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False) + if hasattr(ssl, 'PROTOCOL_SSLv3'): + try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False) try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False) # SSLv23 client with specific SSL options if no_sslv2_implies_sslv3_hello(): # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False, client_options=ssl.OP_NO_SSLv2) - try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True, + try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False, client_options=ssl.OP_NO_SSLv3) - try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True, + try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False, client_options=ssl.OP_NO_TLSv1) @skip_if_broken_ubuntu_ssl @@ -2087,20 +2447,24 @@ def test_protocol_sslv23(self): sys.stdout.write( " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n" % str(x)) - try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True) + if hasattr(ssl, 'PROTOCOL_SSLv3'): + try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, 'SSLv3') try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True) - try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True) + try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, 'TLSv1') - try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL) + if hasattr(ssl, 'PROTOCOL_SSLv3'): + try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, 'SSLv3', ssl.CERT_OPTIONAL) try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL) - try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL) + try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_OPTIONAL) - try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED) + if hasattr(ssl, 'PROTOCOL_SSLv3'): + try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, 'SSLv3', ssl.CERT_REQUIRED) try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED) - try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED) + try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_REQUIRED) # Server with specific SSL options - try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False, + if hasattr(ssl, 'PROTOCOL_SSLv3'): + try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False, server_options=ssl.OP_NO_SSLv3) # Will choose TLSv1 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, @@ -2110,13 +2474,15 @@ def test_protocol_sslv23(self): @skip_if_broken_ubuntu_ssl + @unittest.skipUnless(hasattr(ssl, 'PROTOCOL_SSLv3'), + "OpenSSL is compiled without SSLv3 support") def test_protocol_sslv3(self): """Connecting to an SSLv3 server with various client options""" if support.verbose: sys.stdout.write("\n") - try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True) - try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL) - try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED) + try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, 'SSLv3') + try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, 'SSLv3', ssl.CERT_OPTIONAL) + try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, 'SSLv3', ssl.CERT_REQUIRED) if hasattr(ssl, 'PROTOCOL_SSLv2'): try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False) try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False, @@ -2124,7 +2490,7 @@ def test_protocol_sslv3(self): try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False) if no_sslv2_implies_sslv3_hello(): # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs - try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, True, + try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, 'SSLv3', client_options=ssl.OP_NO_SSLv2) @skip_if_broken_ubuntu_ssl @@ -2132,12 +2498,13 @@ def test_protocol_tlsv1(self): """Connecting to a TLSv1 server with various client options""" if support.verbose: sys.stdout.write("\n") - try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True) - try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL) - try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED) + try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, 'TLSv1') + try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_OPTIONAL) + try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_REQUIRED) if hasattr(ssl, 'PROTOCOL_SSLv2'): try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False) - try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False) + if hasattr(ssl, 'PROTOCOL_SSLv3'): + try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False) try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False, client_options=ssl.OP_NO_TLSv1) @@ -2149,14 +2516,15 @@ def test_protocol_tlsv1_1(self): Testing against older TLS versions.""" if support.verbose: sys.stdout.write("\n") - try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1_1, True) + try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1_1, 'TLSv1.1') if hasattr(ssl, 'PROTOCOL_SSLv2'): try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv2, False) - try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv3, False) + if hasattr(ssl, 'PROTOCOL_SSLv3'): + try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv3, False) try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv23, False, client_options=ssl.OP_NO_TLSv1_1) - try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1_1, True) + try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1_1, 'TLSv1.1') try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1, False) try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1_1, False) @@ -2169,16 +2537,17 @@ def test_protocol_tlsv1_2(self): Testing against older TLS versions.""" if support.verbose: sys.stdout.write("\n") - try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1_2, True, + try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1_2, 'TLSv1.2', server_options=ssl.OP_NO_SSLv3|ssl.OP_NO_SSLv2, client_options=ssl.OP_NO_SSLv3|ssl.OP_NO_SSLv2,) if hasattr(ssl, 'PROTOCOL_SSLv2'): try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv2, False) - try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv3, False) + if hasattr(ssl, 'PROTOCOL_SSLv3'): + try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv3, False) try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv23, False, client_options=ssl.OP_NO_TLSv1_2) - try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1_2, True) + try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1_2, 'TLSv1.2') try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1, False) try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1_2, False) try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1_1, False) @@ -2252,9 +2621,10 @@ def test_socketserver(self): d1 = f.read() d2 = '' # now fetch the same data from the HTTPS server - url = 'https://%s:%d/%s' % ( - HOST, server.port, os.path.split(CERTFILE)[1]) - f = urllib.request.urlopen(url) + url = 'https://localhost:%d/%s' % ( + server.port, os.path.split(CERTFILE)[1]) + context = ssl.create_default_context(cafile=CERTFILE) + f = urllib.request.urlopen(url, context=context) try: dlen = f.info().get("content-length") if dlen and (int(dlen) > 0): @@ -2413,6 +2783,36 @@ def _recvfrom_into(): s.write(b"over\n") s.close() + def test_nonblocking_send(self): + server = ThreadedEchoServer(CERTFILE, + certreqs=ssl.CERT_NONE, + ssl_version=ssl.PROTOCOL_TLSv1, + cacerts=CERTFILE, + chatty=True, + connectionchatty=False) + with server: + s = ssl.wrap_socket(socket.socket(), + server_side=False, + certfile=CERTFILE, + ca_certs=CERTFILE, + cert_reqs=ssl.CERT_NONE, + ssl_version=ssl.PROTOCOL_TLSv1) + s.connect((HOST, server.port)) + s.setblocking(False) + + # If we keep sending data, at some point the buffers + # will be full and the call will block + buf = bytearray(8192) + def fill_buffer(): + while True: + s.send(buf) + self.assertRaises((ssl.SSLWantWriteError, + ssl.SSLWantReadError), fill_buffer) + + # Now read all the output and discard it + s.setblocking(True) + s.close() + def test_handshake_timeout(self): # Issue #5103: SSL handshake must respect the socket timeout server = socket.socket(socket.AF_INET) @@ -2422,7 +2822,7 @@ def test_handshake_timeout(self): finish = False def serve(): - server.listen(5) + server.listen() started.set() conns = [] while not finish: @@ -2479,7 +2879,7 @@ def test_server_accept(self): peer = None def serve(): nonlocal remote, peer - server.listen(5) + server.listen() # Block on the accept and wait on the connection to close. evt.set() remote, peer = server.accept() @@ -2529,6 +2929,38 @@ def test_default_ciphers(self): s.connect((HOST, server.port)) self.assertIn("no shared cipher", str(server.conn_errors[0])) + def test_version_basic(self): + """ + Basic tests for SSLSocket.version(). + More tests are done in the test_protocol_*() methods. + """ + context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) + with ThreadedEchoServer(CERTFILE, + ssl_version=ssl.PROTOCOL_TLSv1, + chatty=False) as server: + with context.wrap_socket(socket.socket()) as s: + self.assertIs(s.version(), None) + s.connect((HOST, server.port)) + self.assertEqual(s.version(), "TLSv1") + self.assertIs(s.version(), None) + + @unittest.skipUnless(ssl.HAS_ECDH, "test requires ECDH-enabled OpenSSL") + def test_default_ecdh_curve(self): + # Issue #21015: elliptic curve-based Diffie Hellman key exchange + # should be enabled by default on SSL contexts. + context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) + context.load_cert_chain(CERTFILE) + # Prior to OpenSSL 1.0.0, ECDH ciphers have to be enabled + # explicitly using the 'ECCdraft' cipher alias. Otherwise, + # our default cipher list should prefer ECDH-based ciphers + # automatically. + if ssl.OPENSSL_VERSION_INFO < (1, 0, 0): + context.set_ciphers("ECCdraft:ECDH") + with ThreadedEchoServer(context=context) as server: + with context.wrap_socket(socket.socket()) as s: + s.connect((HOST, server.port)) + self.assertIn("ECDH", s.cipher()[0]) + @unittest.skipUnless("tls-unique" in ssl.CHANNEL_BINDING_TYPES, "'tls-unique' channel binding not available") def test_tls_unique_channel_binding(self): @@ -2621,6 +3053,55 @@ def test_dh_params(self): if "ADH" not in parts and "EDH" not in parts and "DHE" not in parts: self.fail("Non-DH cipher: " + cipher[0]) + def test_selected_alpn_protocol(self): + # selected_alpn_protocol() is None unless ALPN is used. + context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) + context.load_cert_chain(CERTFILE) + stats = server_params_test(context, context, + chatty=True, connectionchatty=True) + self.assertIs(stats['client_alpn_protocol'], None) + + @unittest.skipUnless(ssl.HAS_ALPN, "ALPN support required") + def test_selected_alpn_protocol_if_server_uses_alpn(self): + # selected_alpn_protocol() is None unless ALPN is used by the client. + client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) + client_context.load_verify_locations(CERTFILE) + server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) + server_context.load_cert_chain(CERTFILE) + server_context.set_alpn_protocols(['foo', 'bar']) + stats = server_params_test(client_context, server_context, + chatty=True, connectionchatty=True) + self.assertIs(stats['client_alpn_protocol'], None) + + @unittest.skipUnless(ssl.HAS_ALPN, "ALPN support needed for this test") + def test_alpn_protocols(self): + server_protocols = ['foo', 'bar', 'milkshake'] + protocol_tests = [ + (['foo', 'bar'], 'foo'), + (['bar', 'foo'], 'foo'), + (['milkshake'], 'milkshake'), + (['http/3.0', 'http/4.0'], None) + ] + for client_protocols, expected in protocol_tests: + server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) + server_context.load_cert_chain(CERTFILE) + server_context.set_alpn_protocols(server_protocols) + client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) + client_context.load_cert_chain(CERTFILE) + client_context.set_alpn_protocols(client_protocols) + stats = server_params_test(client_context, server_context, + chatty=True, connectionchatty=True) + + msg = "failed trying %s (s) and %s (c).\n" \ + "was expecting %s, but got %%s from the %%s" \ + % (str(server_protocols), str(client_protocols), + str(expected)) + client_result = stats['client_alpn_protocol'] + self.assertEqual(client_result, expected, msg % (client_result, "client")) + server_result = stats['server_alpn_protocols'][-1] \ + if len(stats['server_alpn_protocols']) else 'nothing' + self.assertEqual(server_result, expected, msg % (server_result, "server")) + def test_selected_npn_protocol(self): # selected_npn_protocol() is None unless NPN is used context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) @@ -2761,6 +3242,20 @@ def cb_wrong_return_type(ssl_sock, server_name, initial_context): self.assertEqual(cm.exception.reason, 'TLSV1_ALERT_INTERNAL_ERROR') self.assertIn("TypeError", stderr.getvalue()) + def test_shared_ciphers(self): + server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) + server_context.load_cert_chain(SIGNED_CERTFILE) + client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) + client_context.verify_mode = ssl.CERT_REQUIRED + client_context.load_verify_locations(SIGNING_CA) + client_context.set_ciphers("RC4") + server_context.set_ciphers("AES:RC4") + stats = server_params_test(client_context, server_context) + ciphers = stats['server_shared_ciphers'][0] + self.assertGreater(len(ciphers), 0) + for name, tls_version, bits in ciphers: + self.assertIn("RC4", name.split("-")) + def test_read_write_after_close_raises_valuerror(self): context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) context.verify_mode = ssl.CERT_REQUIRED @@ -2776,6 +3271,23 @@ def test_read_write_after_close_raises_valuerror(self): self.assertRaises(ValueError, s.read, 1024) self.assertRaises(ValueError, s.write, b'hello') + def test_sendfile(self): + TEST_DATA = b"x" * 512 + with open(support.TESTFN, 'wb') as f: + f.write(TEST_DATA) + self.addCleanup(support.unlink, support.TESTFN) + context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) + context.verify_mode = ssl.CERT_REQUIRED + context.load_verify_locations(CERTFILE) + context.load_cert_chain(CERTFILE) + server = ThreadedEchoServer(context=context, chatty=False) + with server: + with context.wrap_socket(socket.socket()) as s: + s.connect((HOST, server.port)) + with open(support.TESTFN, 'rb') as file: + s.sendfile(file) + self.assertEqual(s.recv(1024), TEST_DATA) + def test_main(verbose=False): if support.verbose: @@ -2809,10 +3321,11 @@ def test_main(verbose=False): if not os.path.exists(filename): raise support.TestFailed("Can't read certificate file %r" % filename) - tests = [ContextTests, BasicSocketTests, SSLErrorTests] + tests = [ContextTests, BasicSocketTests, SSLErrorTests, MemoryBIOTests] if support.is_resource_enabled('network'): tests.append(NetworkedTests) + tests.append(NetworkedBIOTests) if _have_threads: thread_info = support.threading_setup() diff --git a/Lib/test/test_stat.py b/Lib/test/test_stat.py index af6ced420404..f1a5938a39fe 100644 --- a/Lib/test/test_stat.py +++ b/Lib/test/test_stat.py @@ -1,5 +1,6 @@ import unittest import os +import sys from test.support import TESTFN, import_fresh_module c_stat = import_fresh_module('stat', fresh=['_stat']) @@ -52,6 +53,26 @@ class TestFilemode: 'S_IWOTH': 0o002, 'S_IXOTH': 0o001} + # defined by the Windows API documentation + file_attributes = { + 'FILE_ATTRIBUTE_ARCHIVE': 32, + 'FILE_ATTRIBUTE_COMPRESSED': 2048, + 'FILE_ATTRIBUTE_DEVICE': 64, + 'FILE_ATTRIBUTE_DIRECTORY': 16, + 'FILE_ATTRIBUTE_ENCRYPTED': 16384, + 'FILE_ATTRIBUTE_HIDDEN': 2, + 'FILE_ATTRIBUTE_INTEGRITY_STREAM': 32768, + 'FILE_ATTRIBUTE_NORMAL': 128, + 'FILE_ATTRIBUTE_NOT_CONTENT_INDEXED': 8192, + 'FILE_ATTRIBUTE_NO_SCRUB_DATA': 131072, + 'FILE_ATTRIBUTE_OFFLINE': 4096, + 'FILE_ATTRIBUTE_READONLY': 1, + 'FILE_ATTRIBUTE_REPARSE_POINT': 1024, + 'FILE_ATTRIBUTE_SPARSE_FILE': 512, + 'FILE_ATTRIBUTE_SYSTEM': 4, + 'FILE_ATTRIBUTE_TEMPORARY': 256, + 'FILE_ATTRIBUTE_VIRTUAL': 65536} + def setUp(self): try: os.remove(TESTFN) @@ -185,6 +206,14 @@ def test_module_attributes(self): self.assertTrue(callable(func)) self.assertEqual(func(0), 0) + @unittest.skipUnless(sys.platform == "win32", + "FILE_ATTRIBUTE_* constants are Win32 specific") + def test_file_attribute_constants(self): + for key, value in sorted(self.file_attributes.items()): + self.assertTrue(hasattr(self.statmod, key), key) + modvalue = getattr(self.statmod, key) + self.assertEqual(value, modvalue, key) + class TestFilemodeCStat(TestFilemode, unittest.TestCase): statmod = c_stat diff --git a/Lib/test/test_statistics.py b/Lib/test/test_statistics.py index ee585e2c1c1c..f1da21ed2ba2 100644 --- a/Lib/test/test_statistics.py +++ b/Lib/test/test_statistics.py @@ -8,6 +8,7 @@ import doctest import math import random +import sys import types import unittest @@ -625,6 +626,8 @@ def test_check_all(self): class DocTests(unittest.TestCase): + @unittest.skipIf(sys.flags.optimize >= 2, + "Docstrings are omitted with -OO and above") def test_doc_tests(self): failed, tried = doctest.testmod(statistics) self.assertGreater(tried, 0) @@ -683,6 +686,58 @@ def testSpecialsRaise(self): for d in (Decimal('NAN'), Decimal('sNAN'), Decimal('INF')): self.assertRaises(ValueError, statistics._decimal_to_ratio, d) + def test_sign(self): + # Test sign is calculated correctly. + numbers = [Decimal("9.8765e12"), Decimal("9.8765e-12")] + for d in numbers: + # First test positive decimals. + assert d > 0 + num, den = statistics._decimal_to_ratio(d) + self.assertGreaterEqual(num, 0) + self.assertGreater(den, 0) + # Then test negative decimals. + num, den = statistics._decimal_to_ratio(-d) + self.assertLessEqual(num, 0) + self.assertGreater(den, 0) + + def test_negative_exponent(self): + # Test result when the exponent is negative. + t = statistics._decimal_to_ratio(Decimal("0.1234")) + self.assertEqual(t, (1234, 10000)) + + def test_positive_exponent(self): + # Test results when the exponent is positive. + t = statistics._decimal_to_ratio(Decimal("1.234e7")) + self.assertEqual(t, (12340000, 1)) + + def test_regression_20536(self): + # Regression test for issue 20536. + # See http://bugs.python.org/issue20536 + t = statistics._decimal_to_ratio(Decimal("1e2")) + self.assertEqual(t, (100, 1)) + t = statistics._decimal_to_ratio(Decimal("1.47e5")) + self.assertEqual(t, (147000, 1)) + + +class CheckTypeTest(unittest.TestCase): + # Test _check_type private function. + + def test_allowed(self): + # Test that a type which should be allowed is allowed. + allowed = set([int, float]) + statistics._check_type(int, allowed) + statistics._check_type(float, allowed) + + def test_not_allowed(self): + # Test that a type which should not be allowed raises. + allowed = set([int, float]) + self.assertRaises(TypeError, statistics._check_type, Decimal, allowed) + + def test_add_to_allowed(self): + # Test that a second type will be added to the allowed set. + allowed = set([int]) + statistics._check_type(float, allowed) + self.assertEqual(allowed, set([int, float])) # === Tests for public functions === @@ -878,40 +933,11 @@ def test_bytes_fail(self): self.assertRaises(TypeError, self.func, [1, 2, 3, b'999']) def test_mixed_sum(self): - # Mixed sums are allowed. - - # Careful here: order matters. Can't mix Fraction and Decimal directly, - # only after they're converted to float. - data = [1, 2, Fraction(1, 2), 3.0, Decimal("0.25")] - self.assertEqual(self.func(data), 6.75) - - -class SumInternalsTest(NumericTestCase): - # Test internals of the sum function. - - def test_ignore_instance_float_method(self): - # Test that __float__ methods on data instances are ignored. - - # Python typically calls __dunder__ methods on the class, not the - # instance. The ``sum`` implementation calls __float__ directly. To - # better match the behaviour of Python, we call it only on the class, - # not the instance. This test will fail if somebody "fixes" that code. - - # Create a fake __float__ method. - def __float__(self): - raise AssertionError('test fails') - - # Inject it into an instance. - class MyNumber(Fraction): - pass - x = MyNumber(3) - x.__float__ = types.MethodType(__float__, x) - - # Check it works as expected. - self.assertRaises(AssertionError, x.__float__) - self.assertEqual(float(x), 3.0) - # And now test the function. - self.assertEqual(statistics._sum([1.0, 2.0, x, 4.0]), 10.0) + # Mixed input types are not (currently) allowed. + # Check that mixed data types fail. + self.assertRaises(TypeError, self.func, [1, 2.0, Fraction(1, 2)]) + # And so does mixed start argument. + self.assertRaises(TypeError, self.func, [1, 2.0], Decimal(1)) class SumTortureTest(NumericTestCase): @@ -965,14 +991,14 @@ def test_float_mismatched_infs(self): result = statistics._sum([1, 2, inf, 3, -inf, 4]) self.assertTrue(math.isnan(result)) - def test_decimal_mismatched_infs_to_nan(self): + def test_decimal_extendedcontext_mismatched_infs_to_nan(self): # Test adding Decimal INFs with opposite sign returns NAN. inf = Decimal('inf') data = [1, 2, inf, 3, -inf, 4] with decimal.localcontext(decimal.ExtendedContext): self.assertTrue(math.isnan(statistics._sum(data))) - def test_decimal_mismatched_infs_to_nan(self): + def test_decimal_basiccontext_mismatched_infs_to_nan(self): # Test adding Decimal INFs with opposite sign raises InvalidOperation. inf = Decimal('inf') data = [1, 2, inf, 3, -inf, 4] @@ -1080,6 +1106,12 @@ def test_doubled_data(self): actual = self.func(data*2) self.assertApproxEqual(actual, expected) + def test_regression_20561(self): + # Regression test for issue 20561. + # See http://bugs.python.org/issue20561 + d = Decimal('1e4') + self.assertEqual(statistics.mean([d]), d) + class TestMedian(NumericTestCase, AverageMixin): # Common tests for median and all median.* functions. @@ -1352,6 +1384,14 @@ def test_none_data(self): # collections.Counter, which accepts None and returns an empty dict. self.assertRaises(TypeError, self.func, None) + def test_counter_data(self): + # Test that a Counter is treated like any other iterable. + data = collections.Counter([1, 1, 1, 2]) + # Since the keys of the counter are treated as data points, not the + # counts, this should raise. + self.assertRaises(statistics.StatisticsError, self.func, data) + + # === Tests for variances and standard deviations === diff --git a/Lib/test/test_string.py b/Lib/test/test_string.py index c2bdfdb0b01d..3e6507151e57 100644 --- a/Lib/test/test_string.py +++ b/Lib/test/test_string.py @@ -32,6 +32,23 @@ def test_basic_formatter(self): self.assertEqual(fmt.format("foo{0}", "bar"), "foobar") self.assertEqual(fmt.format("foo{1}{0}-{1}", "bar", 6), "foo6bar-6") + def test_auto_numbering(self): + fmt = string.Formatter() + self.assertEqual(fmt.format('foo{}{}', 'bar', 6), + 'foo{}{}'.format('bar', 6)) + self.assertEqual(fmt.format('foo{1}{num}{1}', None, 'bar', num=6), + 'foo{1}{num}{1}'.format(None, 'bar', num=6)) + self.assertEqual(fmt.format('{:^{}}', 'bar', 6), + '{:^{}}'.format('bar', 6)) + self.assertEqual(fmt.format('{:^{pad}}{}', 'foo', 'bar', pad=6), + '{:^{pad}}{}'.format('foo', 'bar', pad=6)) + + with self.assertRaises(ValueError): + fmt.format('foo{1}{}', 'bar', 6) + + with self.assertRaises(ValueError): + fmt.format('foo{}{1}', 'bar', 6) + def test_conversion_specifiers(self): fmt = string.Formatter() self.assertEqual(fmt.format("-{arg!r}-", arg='test'), "-'test'-") diff --git a/Lib/test/test_stringprep.py b/Lib/test/test_stringprep.py index aa7122172f3a..e763635efe27 100644 --- a/Lib/test/test_stringprep.py +++ b/Lib/test/test_stringprep.py @@ -1,5 +1,5 @@ # To fully test this module, we would need a copy of the stringprep tables. -# Since we don't have them, this test checks only a few codepoints. +# Since we don't have them, this test checks only a few code points. import unittest from test import support diff --git a/Lib/test/test_strptime.py b/Lib/test/test_strptime.py index d5bc39d0dd38..13a72d450d8c 100644 --- a/Lib/test/test_strptime.py +++ b/Lib/test/test_strptime.py @@ -323,7 +323,7 @@ def test_bad_timezone(self): # when time.tzname[0] == time.tzname[1] and time.daylight tz_name = time.tzname[0] if tz_name.upper() in ("UTC", "GMT"): - return + self.skipTest('need non-UTC/GMT timezone') try: original_tzname = time.tzname original_daylight = time.daylight @@ -536,7 +536,7 @@ def test_TimeRE_recreation(self): try: locale.setlocale(locale.LC_TIME, ('en_US', 'UTF8')) except locale.Error: - return + self.skipTest('test needs en_US.UTF8 locale') try: _strptime._strptime_time('10', '%d') # Get id of current cache object. @@ -553,7 +553,7 @@ def test_TimeRE_recreation(self): # If this is the case just suppress the exception and fall-through # to the resetting to the original locale. except locale.Error: - pass + self.skipTest('test needs de_DE.UTF8 locale') # Make sure we don't trample on the locale setting once we leave the # test. finally: diff --git a/Lib/test/test_structmembers.py b/Lib/test/test_structmembers.py index 18fecc382901..1c931ae77815 100644 --- a/Lib/test/test_structmembers.py +++ b/Lib/test/test_structmembers.py @@ -1,3 +1,8 @@ +import unittest +from test import support + +# Skip this test if the _testcapi module isn't available. +support.import_module('_testcapi') from _testcapi import _test_structmembersType, \ CHAR_MAX, CHAR_MIN, UCHAR_MAX, \ SHRT_MAX, SHRT_MIN, USHRT_MAX, \ @@ -6,9 +11,6 @@ LLONG_MAX, LLONG_MIN, ULLONG_MAX, \ PY_SSIZE_T_MAX, PY_SSIZE_T_MIN -import unittest -from test import support - ts=_test_structmembersType(False, # T_BOOL 1, # T_BYTE 2, # T_UBYTE diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py index 46e012d142ce..460876f41056 100644 --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -786,6 +786,7 @@ def test_universal_newlines(self): stdout=subprocess.PIPE, universal_newlines=1) p.stdin.write("line1\n") + p.stdin.flush() self.assertEqual(p.stdout.readline(), "line1\n") p.stdin.write("line3\n") p.stdin.close() @@ -1007,6 +1008,39 @@ def test_bufsize_is_none(self): p = subprocess.Popen([sys.executable, "-c", "pass"], bufsize=None) self.assertEqual(p.wait(), 0) + def _test_bufsize_equal_one(self, line, expected, universal_newlines): + # subprocess may deadlock with bufsize=1, see issue #21332 + with subprocess.Popen([sys.executable, "-c", "import sys;" + "sys.stdout.write(sys.stdin.readline());" + "sys.stdout.flush()"], + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.DEVNULL, + bufsize=1, + universal_newlines=universal_newlines) as p: + p.stdin.write(line) # expect that it flushes the line in text mode + os.close(p.stdin.fileno()) # close it without flushing the buffer + read_line = p.stdout.readline() + try: + p.stdin.close() + except OSError: + pass + p.stdin = None + self.assertEqual(p.returncode, 0) + self.assertEqual(read_line, expected) + + def test_bufsize_equal_one_text_mode(self): + # line is flushed in text mode with bufsize=1. + # we should get the full line in return + line = "line\n" + self._test_bufsize_equal_one(line, line, universal_newlines=True) + + def test_bufsize_equal_one_binary_mode(self): + # line is not flushed in binary mode with bufsize=1. + # we should get empty response + line = b'line' + os.linesep.encode() # assume ascii-based locale + self._test_bufsize_equal_one(line, b'', universal_newlines=False) + def test_leaking_fds_on_error(self): # see bug #5179: Popen leaks file descriptors to PIPEs if # the child fails to execute; this will eventually exhaust @@ -1052,6 +1086,59 @@ def open_fds(): if exc is not None: raise exc + @unittest.skipIf(threading is None, "threading required") + def test_threadsafe_wait(self): + """Issue21291: Popen.wait() needs to be threadsafe for returncode.""" + proc = subprocess.Popen([sys.executable, '-c', + 'import time; time.sleep(12)']) + self.assertEqual(proc.returncode, None) + results = [] + + def kill_proc_timer_thread(): + results.append(('thread-start-poll-result', proc.poll())) + # terminate it from the thread and wait for the result. + proc.kill() + proc.wait() + results.append(('thread-after-kill-and-wait', proc.returncode)) + # this wait should be a no-op given the above. + proc.wait() + results.append(('thread-after-second-wait', proc.returncode)) + + # This is a timing sensitive test, the failure mode is + # triggered when both the main thread and this thread are in + # the wait() call at once. The delay here is to allow the + # main thread to most likely be blocked in its wait() call. + t = threading.Timer(0.2, kill_proc_timer_thread) + t.start() + + if mswindows: + expected_errorcode = 1 + else: + # Should be -9 because of the proc.kill() from the thread. + expected_errorcode = -9 + + # Wait for the process to finish; the thread should kill it + # long before it finishes on its own. Supplying a timeout + # triggers a different code path for better coverage. + proc.wait(timeout=20) + self.assertEqual(proc.returncode, expected_errorcode, + msg="unexpected result in wait from main thread") + + # This should be a no-op with no change in returncode. + proc.wait() + self.assertEqual(proc.returncode, expected_errorcode, + msg="unexpected result in second main wait.") + + t.join() + # Ensure that all of the thread results are as expected. + # When a race condition occurs in wait(), the returncode could + # be set by the wrong thread that doesn't actually have it + # leading to an incorrect value. + self.assertEqual([('thread-start-poll-result', None), + ('thread-after-kill-and-wait', expected_errorcode), + ('thread-after-second-wait', expected_errorcode)], + results) + def test_issue8780(self): # Ensure that stdout is inherited from the parent # if stdout=PIPE is not used @@ -1835,7 +1922,7 @@ def test_close_fds(self): open_fds = set(fds) # add a bunch more fds for _ in range(9): - fd = os.open("/dev/null", os.O_RDONLY) + fd = os.open(os.devnull, os.O_RDONLY) self.addCleanup(os.close, fd) open_fds.add(fd) @@ -1872,6 +1959,86 @@ def test_close_fds(self): "Some fds not in pass_fds were left open") self.assertIn(1, remaining_fds, "Subprocess failed") + + @unittest.skipIf(sys.platform.startswith("freebsd") and + os.stat("/dev").st_dev == os.stat("/dev/fd").st_dev, + "Requires fdescfs mounted on /dev/fd on FreeBSD.") + def test_close_fds_when_max_fd_is_lowered(self): + """Confirm that issue21618 is fixed (may fail under valgrind).""" + fd_status = support.findfile("fd_status.py", subdir="subprocessdata") + + # This launches the meat of the test in a child process to + # avoid messing with the larger unittest processes maximum + # number of file descriptors. + # This process launches: + # +--> Process that lowers its RLIMIT_NOFILE aftr setting up + # a bunch of high open fds above the new lower rlimit. + # Those are reported via stdout before launching a new + # process with close_fds=False to run the actual test: + # +--> The TEST: This one launches a fd_status.py + # subprocess with close_fds=True so we can find out if + # any of the fds above the lowered rlimit are still open. + p = subprocess.Popen([sys.executable, '-c', textwrap.dedent( + ''' + import os, resource, subprocess, sys, textwrap + open_fds = set() + # Add a bunch more fds to pass down. + for _ in range(40): + fd = os.open(os.devnull, os.O_RDONLY) + open_fds.add(fd) + + # Leave a two pairs of low ones available for use by the + # internal child error pipe and the stdout pipe. + # We also leave 10 more open as some Python buildbots run into + # "too many open files" errors during the test if we do not. + for fd in sorted(open_fds)[:14]: + os.close(fd) + open_fds.remove(fd) + + for fd in open_fds: + #self.addCleanup(os.close, fd) + os.set_inheritable(fd, True) + + max_fd_open = max(open_fds) + + # Communicate the open_fds to the parent unittest.TestCase process. + print(','.join(map(str, sorted(open_fds)))) + sys.stdout.flush() + + rlim_cur, rlim_max = resource.getrlimit(resource.RLIMIT_NOFILE) + try: + # 29 is lower than the highest fds we are leaving open. + resource.setrlimit(resource.RLIMIT_NOFILE, (29, rlim_max)) + # Launch a new Python interpreter with our low fd rlim_cur that + # inherits open fds above that limit. It then uses subprocess + # with close_fds=True to get a report of open fds in the child. + # An explicit list of fds to check is passed to fd_status.py as + # letting fd_status rely on its default logic would miss the + # fds above rlim_cur as it normally only checks up to that limit. + subprocess.Popen( + [sys.executable, '-c', + textwrap.dedent(""" + import subprocess, sys + subprocess.Popen([sys.executable, %r] + + [str(x) for x in range({max_fd})], + close_fds=True).wait() + """.format(max_fd=max_fd_open+1))], + close_fds=False).wait() + finally: + resource.setrlimit(resource.RLIMIT_NOFILE, (rlim_cur, rlim_max)) + ''' % fd_status)], stdout=subprocess.PIPE) + + output, unused_stderr = p.communicate() + output_lines = output.splitlines() + self.assertEqual(len(output_lines), 2, + msg="expected exactly two lines of output:\n%r" % output) + opened_fds = set(map(int, output_lines[0].strip().split(b','))) + remaining_fds = set(map(int, output_lines[1].strip().split(b','))) + + self.assertFalse(remaining_fds & opened_fds, + msg="Some fds were left open.") + + # Mac OS X Tiger (10.4) has a kernel bug: sometimes, the file # descriptor of a pipe closed in the parent process is valid in the # child process according to fstat(), but the mode of the file @@ -2049,6 +2216,39 @@ def test_close_fds_after_preexec(self): self.assertNotIn(fd, remaining_fds) + @support.cpython_only + def test_fork_exec(self): + # Issue #22290: fork_exec() must not crash on memory allocation failure + # or other errors + import _posixsubprocess + gc_enabled = gc.isenabled() + try: + # Use a preexec function and enable the garbage collector + # to force fork_exec() to re-enable the garbage collector + # on error. + func = lambda: None + gc.enable() + + executable_list = "exec" # error: must be a sequence + + for args, exe_list, cwd, env_list in ( + (123, [b"exe"], None, [b"env"]), + ([b"arg"], 123, None, [b"env"]), + ([b"arg"], [b"exe"], 123, [b"env"]), + ([b"arg"], [b"exe"], None, 123), + ): + with self.assertRaises(TypeError): + _posixsubprocess.fork_exec( + args, exe_list, + True, [], cwd, env_list, + -1, -1, -1, -1, + 1, 2, 3, 4, + True, True, func) + finally: + if not gc_enabled: + gc.disable() + + @unittest.skipUnless(mswindows, "Windows specific tests") class Win32ProcessTestCase(BaseTestCase): @@ -2221,25 +2421,6 @@ def tearDown(self): ProcessTestCase.tearDown(self) -class HelperFunctionTests(unittest.TestCase): - @unittest.skipIf(mswindows, "errno and EINTR make no sense on windows") - def test_eintr_retry_call(self): - record_calls = [] - def fake_os_func(*args): - record_calls.append(args) - if len(record_calls) == 2: - raise OSError(errno.EINTR, "fake interrupted system call") - return tuple(reversed(args)) - - self.assertEqual((999, 256), - subprocess._eintr_retry_call(fake_os_func, 256, 999)) - self.assertEqual([(256, 999)], record_calls) - # This time there will be an EINTR so it will loop once. - self.assertEqual((666,), - subprocess._eintr_retry_call(fake_os_func, 666)) - self.assertEqual([(256, 999), (666,), (666,)], record_calls) - - @unittest.skipUnless(mswindows, "Windows-specific tests") class CommandsWithSpaces (BaseTestCase): @@ -2328,7 +2509,6 @@ def test_main(): Win32ProcessTestCase, CommandTests, ProcessTestCaseNoPoll, - HelperFunctionTests, CommandsWithSpaces, ContextManagerTests, ) diff --git a/Lib/test/test_sunau.py b/Lib/test/test_sunau.py index af9ffec622de..0f4134e9822e 100644 --- a/Lib/test/test_sunau.py +++ b/Lib/test/test_sunau.py @@ -6,10 +6,12 @@ import sunau -class SunauPCM8Test(audiotests.AudioWriteTests, - audiotests.AudioTestsWithSourceFile, - unittest.TestCase): +class SunauTest(audiotests.AudioWriteTests, + audiotests.AudioTestsWithSourceFile): module = sunau + + +class SunauPCM8Test(SunauTest, unittest.TestCase): sndfilename = 'pluck-pcm8.au' sndfilenframes = 3307 nchannels = 2 @@ -26,10 +28,7 @@ class SunauPCM8Test(audiotests.AudioWriteTests, """) -class SunauPCM16Test(audiotests.AudioWriteTests, - audiotests.AudioTestsWithSourceFile, - unittest.TestCase): - module = sunau +class SunauPCM16Test(SunauTest, unittest.TestCase): sndfilename = 'pluck-pcm16.au' sndfilenframes = 3307 nchannels = 2 @@ -48,10 +47,7 @@ class SunauPCM16Test(audiotests.AudioWriteTests, """) -class SunauPCM24Test(audiotests.AudioWriteTests, - audiotests.AudioTestsWithSourceFile, - unittest.TestCase): - module = sunau +class SunauPCM24Test(SunauTest, unittest.TestCase): sndfilename = 'pluck-pcm24.au' sndfilenframes = 3307 nchannels = 2 @@ -76,10 +72,7 @@ class SunauPCM24Test(audiotests.AudioWriteTests, """) -class SunauPCM32Test(audiotests.AudioWriteTests, - audiotests.AudioTestsWithSourceFile, - unittest.TestCase): - module = sunau +class SunauPCM32Test(SunauTest, unittest.TestCase): sndfilename = 'pluck-pcm32.au' sndfilenframes = 3307 nchannels = 2 @@ -104,10 +97,7 @@ class SunauPCM32Test(audiotests.AudioWriteTests, """) -class SunauULAWTest(audiotests.AudioWriteTests, - audiotests.AudioTestsWithSourceFile, - unittest.TestCase): - module = sunau +class SunauULAWTest(SunauTest, unittest.TestCase): sndfilename = 'pluck-ulaw.au' sndfilenframes = 3307 nchannels = 2 diff --git a/Lib/test/test_sundry.py b/Lib/test/test_sundry.py index 2da3ac05dc75..e99ca9ed37f8 100644 --- a/Lib/test/test_sundry.py +++ b/Lib/test/test_sundry.py @@ -6,7 +6,7 @@ class TestUntestedModules(unittest.TestCase): def test_untested_modules_can_be_imported(self): - untested = ('bdb', 'encodings', 'formatter', 'imghdr', + untested = ('bdb', 'encodings', 'formatter', 'nturl2path', 'tabnanny') with support.check_warnings(quiet=True): for name in untested: diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py index 16b660bce1d2..a02d2f4f6ffc 100644 --- a/Lib/test/test_support.py +++ b/Lib/test/test_support.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - import importlib import shutil import sys @@ -71,6 +69,7 @@ def test_forget(self): finally: del sys.path[0] support.unlink(mod_filename) + support.rmtree('__pycache__') def test_HOST(self): s = socket.socket() @@ -86,7 +85,7 @@ def test_find_unused_port(self): def test_bind_port(self): s = socket.socket() support.bind_port(s) - s.listen(1) + s.listen() s.close() # Tests for temp_dir() @@ -104,7 +103,7 @@ def test_temp_dir(self): self.assertTrue(os.path.isdir(path)) self.assertFalse(os.path.isdir(path)) finally: - shutil.rmtree(parent_dir) + support.rmtree(parent_dir) def test_temp_dir__path_none(self): """Test passing no path.""" diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index f0c71483ed7a..ed6b47d2e4ff 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -1,4 +1,5 @@ import unittest, test.support +from test.script_helper import assert_python_ok, assert_python_failure import sys, io, os import struct import subprocess @@ -89,74 +90,54 @@ def test_excepthook(self): # Python/pythonrun.c::PyErr_PrintEx() is tricky. def test_exit(self): - + # call with two arguments self.assertRaises(TypeError, sys.exit, 42, 42) # call without argument - try: - sys.exit(0) - except SystemExit as exc: - self.assertEqual(exc.code, 0) - except: - self.fail("wrong exception") - else: - self.fail("no exception") + with self.assertRaises(SystemExit) as cm: + sys.exit() + self.assertIsNone(cm.exception.code) - # call with tuple argument with one entry - # entry will be unpacked - try: - sys.exit(42) - except SystemExit as exc: - self.assertEqual(exc.code, 42) - except: - self.fail("wrong exception") - else: - self.fail("no exception") + rc, out, err = assert_python_ok('-c', 'import sys; sys.exit()') + self.assertEqual(rc, 0) + self.assertEqual(out, b'') + self.assertEqual(err, b'') # call with integer argument - try: + with self.assertRaises(SystemExit) as cm: + sys.exit(42) + self.assertEqual(cm.exception.code, 42) + + # call with tuple argument with one entry + # entry will be unpacked + with self.assertRaises(SystemExit) as cm: sys.exit((42,)) - except SystemExit as exc: - self.assertEqual(exc.code, 42) - except: - self.fail("wrong exception") - else: - self.fail("no exception") + self.assertEqual(cm.exception.code, 42) # call with string argument - try: + with self.assertRaises(SystemExit) as cm: sys.exit("exit") - except SystemExit as exc: - self.assertEqual(exc.code, "exit") - except: - self.fail("wrong exception") - else: - self.fail("no exception") + self.assertEqual(cm.exception.code, "exit") # call with tuple argument with two entries - try: + with self.assertRaises(SystemExit) as cm: sys.exit((17, 23)) - except SystemExit as exc: - self.assertEqual(exc.code, (17, 23)) - except: - self.fail("wrong exception") - else: - self.fail("no exception") + self.assertEqual(cm.exception.code, (17, 23)) # test that the exit machinery handles SystemExits properly - rc = subprocess.call([sys.executable, "-c", - "raise SystemExit(47)"]) + rc, out, err = assert_python_failure('-c', 'raise SystemExit(47)') self.assertEqual(rc, 47) + self.assertEqual(out, b'') + self.assertEqual(err, b'') - def check_exit_message(code, expected, env=None): - process = subprocess.Popen([sys.executable, "-c", code], - stderr=subprocess.PIPE, env=env) - stdout, stderr = process.communicate() - self.assertEqual(process.returncode, 1) - self.assertTrue(stderr.startswith(expected), - "%s doesn't start with %s" % (ascii(stderr), ascii(expected))) + def check_exit_message(code, expected, **env_vars): + rc, out, err = assert_python_failure('-c', code, **env_vars) + self.assertEqual(rc, 1) + self.assertEqual(out, b'') + self.assertTrue(err.startswith(expected), + "%s doesn't start with %s" % (ascii(err), ascii(expected))) - # test that stderr buffer if flushed before the exit message is written + # test that stderr buffer is flushed before the exit message is written # into stderr check_exit_message( r'import sys; sys.stderr.write("unflushed,"); sys.exit("message")', @@ -170,11 +151,9 @@ def check_exit_message(code, expected, env=None): # test that the unicode message is encoded to the stderr encoding # instead of the default encoding (utf8) - env = os.environ.copy() - env['PYTHONIOENCODING'] = 'latin-1' check_exit_message( r'import sys; sys.exit("h\xe9")', - b"h\xe9", env=env) + b"h\xe9", PYTHONIOENCODING='latin-1') def test_getdefaultencoding(self): self.assertRaises(TypeError, sys.getdefaultencoding, 42) @@ -447,7 +426,7 @@ def test_attributes(self): self.assertIsInstance(sys.hash_info.inf, int) self.assertIsInstance(sys.hash_info.nan, int) self.assertIsInstance(sys.hash_info.imag, int) - algo = sysconfig.get_config_var("PY_HASH_ALGORITHM") + algo = sysconfig.get_config_var("Py_HASH_ALGORITHM") if sys.hash_info.algorithm in {"fnv", "siphash24"}: self.assertIn(sys.hash_info.hash_bits, {32, 64}) self.assertIn(sys.hash_info.seed_bits, {32, 64, 128}) @@ -457,11 +436,7 @@ def test_attributes(self): elif algo == 2: self.assertEqual(sys.hash_info.algorithm, "fnv") else: - processor = platform.processor().lower() - if processor in {"sparc", "mips"}: - self.assertEqual(sys.hash_info.algorithm, "fnv") - else: - self.assertEqual(sys.hash_info.algorithm, "siphash24") + self.assertIn(sys.hash_info.algorithm, {"fnv", "siphash24"}) else: # PY_HASH_EXTERNAL self.assertEqual(algo, 0) @@ -544,6 +519,27 @@ def test_sys_flags(self): self.assertTrue(repr(sys.flags)) self.assertEqual(len(sys.flags), len(attrs)) + def assert_raise_on_new_sys_type(self, sys_attr): + # Users are intentionally prevented from creating new instances of + # sys.flags, sys.version_info, and sys.getwindowsversion. + attr_type = type(sys_attr) + with self.assertRaises(TypeError): + attr_type() + with self.assertRaises(TypeError): + attr_type.__new__(attr_type) + + def test_sys_flags_no_instantiation(self): + self.assert_raise_on_new_sys_type(sys.flags) + + def test_sys_version_info_no_instantiation(self): + self.assert_raise_on_new_sys_type(sys.version_info) + + def test_sys_getwindowsversion_no_instantiation(self): + # Skip if not being run on Windows. + test.support.get_attribute(sys, "getwindowsversion") + self.assert_raise_on_new_sys_type(sys.getwindowsversion()) + + @test.support.cpython_only def test_clear_type_cache(self): sys._clear_type_cache() @@ -640,6 +636,53 @@ def test_getfilesystemencoding(self): expected = None self.check_fsencoding(fs_encoding, expected) + def c_locale_get_error_handler(self, isolated=False, encoding=None): + # Force the POSIX locale + env = os.environ.copy() + env["LC_ALL"] = "C" + code = '\n'.join(( + 'import sys', + 'def dump(name):', + ' std = getattr(sys, name)', + ' print("%s: %s" % (name, std.errors))', + 'dump("stdin")', + 'dump("stdout")', + 'dump("stderr")', + )) + args = [sys.executable, "-c", code] + if isolated: + args.append("-I") + elif encoding: + env['PYTHONIOENCODING'] = encoding + p = subprocess.Popen(args, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + env=env, + universal_newlines=True) + stdout, stderr = p.communicate() + return stdout + + def test_c_locale_surrogateescape(self): + out = self.c_locale_get_error_handler(isolated=True) + self.assertEqual(out, + 'stdin: surrogateescape\n' + 'stdout: surrogateescape\n' + 'stderr: backslashreplace\n') + + # replace the default error handler + out = self.c_locale_get_error_handler(encoding=':strict') + self.assertEqual(out, + 'stdin: strict\n' + 'stdout: strict\n' + 'stderr: backslashreplace\n') + + # force the encoding + out = self.c_locale_get_error_handler(encoding='iso8859-1') + self.assertEqual(out, + 'stdin: surrogateescape\n' + 'stdout: surrogateescape\n' + 'stderr: backslashreplace\n') + def test_implementation(self): # This test applies to all implementations equally. @@ -662,6 +705,7 @@ def test_implementation(self): self.assertEqual(sys.implementation.name, sys.implementation.name.lower()) + @test.support.cpython_only def test_debugmallocstats(self): # Test sys._debugmallocstats() from test.script_helper import assert_python_ok @@ -669,6 +713,9 @@ def test_debugmallocstats(self): ret, out, err = assert_python_ok(*args) self.assertIn(b"free PyDictObjects", err) + # The function has no parameter + self.assertRaises(TypeError, sys._debugmallocstats, True) + @unittest.skipUnless(hasattr(sys, "getallocatedblocks"), "sys.getallocatedblocks unavailable on this build") def test_getallocatedblocks(self): @@ -698,7 +745,29 @@ def test_getallocatedblocks(self): c = sys.getallocatedblocks() self.assertIn(c, range(b - 50, b + 50)) + def test_is_finalizing(self): + self.assertIs(sys.is_finalizing(), False) + # Don't use the atexit module because _Py_Finalizing is only set + # after calling atexit callbacks + code = """if 1: + import sys + + class AtExit: + is_finalizing = sys.is_finalizing + print = print + def __del__(self): + self.print(self.is_finalizing(), flush=True) + + # Keep a reference in the __main__ module namespace, so the + # AtExit destructor will be called at Python exit + ref = AtExit() + """ + rc, stdout, stderr = assert_python_ok('-c', code) + self.assertEqual(stdout.rstrip(), b'True') + + +@test.support.cpython_only class SizeofTest(unittest.TestCase): def setUp(self): @@ -723,6 +792,37 @@ def test_gc_head_size(self): # but lists are self.assertEqual(sys.getsizeof([]), vsize('Pn') + gc_header_size) + def test_errors(self): + class BadSizeof: + def __sizeof__(self): + raise ValueError + self.assertRaises(ValueError, sys.getsizeof, BadSizeof()) + + class InvalidSizeof: + def __sizeof__(self): + return None + self.assertRaises(TypeError, sys.getsizeof, InvalidSizeof()) + sentinel = ["sentinel"] + self.assertIs(sys.getsizeof(InvalidSizeof(), sentinel), sentinel) + + class FloatSizeof: + def __sizeof__(self): + return 4.5 + self.assertRaises(TypeError, sys.getsizeof, FloatSizeof()) + self.assertIs(sys.getsizeof(FloatSizeof(), sentinel), sentinel) + + class OverflowSizeof(int): + def __sizeof__(self): + return int(self) + self.assertEqual(sys.getsizeof(OverflowSizeof(sys.maxsize)), + sys.maxsize + self.gc_headsize) + with self.assertRaises(OverflowError): + sys.getsizeof(OverflowSizeof(sys.maxsize + 1)) + with self.assertRaises(ValueError): + sys.getsizeof(OverflowSizeof(-1)) + with self.assertRaises((ValueError, OverflowError)): + sys.getsizeof(OverflowSizeof(-sys.maxsize - 1)) + def test_default(self): size = test.support.calcvobjsize self.assertEqual(sys.getsizeof(True), size('') + self.longdigit) @@ -738,7 +838,7 @@ def test_objecttypes(self): # buffer # XXX # builtin_function_or_method - check(len, size('3P')) # XXX check layout + check(len, size('4P')) # XXX check layout # bytearray samples = [b'', b'u'*100000] for sample in samples: @@ -822,7 +922,7 @@ class C(object): pass nfrees = len(x.f_code.co_freevars) extras = x.f_code.co_stacksize + x.f_code.co_nlocals +\ ncells + nfrees - 1 - check(x, vsize('13P3ic' + CO_MAXBLOCKS*'3i' + 'P' + extras*'P')) + check(x, vsize('12P3ic' + CO_MAXBLOCKS*'3i' + 'P' + extras*'P')) # function def func(): pass check(func, size('12P')) @@ -839,7 +939,7 @@ def bar(cls): check(bar, size('PP')) # generator def get_gen(): yield 1 - check(get_gen(), size('Pb2P')) + check(get_gen(), size('Pb2PPP')) # iterator check(iter('abc'), size('lP')) # callable-iterator @@ -866,7 +966,7 @@ def get_gen(): yield 1 check(int(PyLong_BASE**2-1), vsize('') + 2*self.longdigit) check(int(PyLong_BASE**2), vsize('') + 3*self.longdigit) # memoryview - check(memoryview(b''), size('Pnin 2P2n2i5P 3cPn')) + check(memoryview(b''), size('Pnin 2P2n2i5P Pn')) # module check(unittest, size('PnPPP')) # None @@ -895,7 +995,7 @@ def delx(self): del self.__x # frozenset PySet_MINSIZE = 8 samples = [[], range(10), range(50)] - s = size('3n2P' + PySet_MINSIZE*'nP' + 'nP') + s = size('3nP' + PySet_MINSIZE*'nP' + '2nP') for sample in samples: minused = len(sample) if minused == 0: tmp = 1 @@ -926,7 +1026,7 @@ def delx(self): del self.__x check(int, s) # (PyTypeObject + PyNumberMethods + PyMappingMethods + # PySequenceMethods + PyBufferProcs + 4P) - s = vsize('P2n15Pl4Pn9Pn11PIP') + struct.calcsize('34P 3P 10P 2P 4P') + s = vsize('P2n17Pl4Pn9Pn11PIP') + struct.calcsize('34P 3P 10P 2P 4P') # Separate block for PyDictKeysObject with 4 entries s += struct.calcsize("2nPn") + 4*struct.calcsize("n2P") # class diff --git a/Lib/test/test_sys_setprofile.py b/Lib/test/test_sys_setprofile.py index 9816e3ed6466..e59320b1588a 100644 --- a/Lib/test/test_sys_setprofile.py +++ b/Lib/test/test_sys_setprofile.py @@ -260,7 +260,6 @@ def test_stop_iteration(self): def f(): for i in range(2): yield i - raise StopIteration def g(p): for i in f(): pass diff --git a/Lib/test/test_sys_settrace.py b/Lib/test/test_sys_settrace.py index f0b0b8290af7..ae8f845ee1bd 100644 --- a/Lib/test/test_sys_settrace.py +++ b/Lib/test/test_sys_settrace.py @@ -579,6 +579,15 @@ def jump_in_nested_finally(output): jump_in_nested_finally.jump = (4, 9) jump_in_nested_finally.output = [2, 9] +def jump_infinite_while_loop(output): + output.append(1) + while 1: + output.append(2) + output.append(3) + +jump_infinite_while_loop.jump = (3, 4) +jump_infinite_while_loop.output = [1, 3] + # The second set of 'jump' tests are for things that are not allowed: def no_jump_too_far_forwards(output): @@ -755,6 +764,8 @@ def test_06_jump_to_same_line(self): self.run_test(jump_to_same_line) def test_07_jump_in_nested_finally(self): self.run_test(jump_in_nested_finally) + def test_jump_infinite_while_loop(self): + self.run_test(jump_infinite_while_loop) def test_08_no_jump_too_far_forwards(self): self.run_test(no_jump_too_far_forwards) def test_09_no_jump_too_far_backwards(self): diff --git a/Lib/test/test_syslog.py b/Lib/test/test_syslog.py index 4e7621e5ec2f..b7fd2bdabb5e 100644 --- a/Lib/test/test_syslog.py +++ b/Lib/test/test_syslog.py @@ -32,6 +32,10 @@ def test_log_mask(self): def test_log_upto(self): syslog.LOG_UPTO(syslog.LOG_INFO) + def test_openlog_noargs(self): + syslog.openlog() + syslog.syslog('test message from python test_syslog') + def test_main(): support.run_unittest(__name__) diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py index 9d318100fa87..01d1a922ee69 100644 --- a/Lib/test/test_tarfile.py +++ b/Lib/test/test_tarfile.py @@ -1,7 +1,6 @@ import sys import os import io -import shutil from hashlib import md5 import unittest @@ -43,6 +42,7 @@ class TarTest: tarname = tarname suffix = '' open = io.FileIO + taropen = tarfile.TarFile.taropen @property def mode(self): @@ -53,18 +53,21 @@ class GzipTest: tarname = gzipname suffix = 'gz' open = gzip.GzipFile if gzip else None + taropen = tarfile.TarFile.gzopen @support.requires_bz2 class Bz2Test: tarname = bz2name suffix = 'bz2' open = bz2.BZ2File if bz2 else None + taropen = tarfile.TarFile.bz2open @support.requires_lzma class LzmaTest: tarname = xzname suffix = 'xz' open = lzma.LZMAFile if lzma else None + taropen = tarfile.TarFile.xzopen class ReadTest(TarTest): @@ -215,6 +218,98 @@ class LzmaUstarReadTest(LzmaTest, UstarReadTest): pass +class ListTest(ReadTest, unittest.TestCase): + + # Override setUp to use default encoding (UTF-8) + def setUp(self): + self.tar = tarfile.open(self.tarname, mode=self.mode) + + def test_list(self): + tio = io.TextIOWrapper(io.BytesIO(), 'ascii', newline='\n') + with support.swap_attr(sys, 'stdout', tio): + self.tar.list(verbose=False) + out = tio.detach().getvalue() + self.assertIn(b'ustar/conttype', out) + self.assertIn(b'ustar/regtype', out) + self.assertIn(b'ustar/lnktype', out) + self.assertIn(b'ustar' + (b'/12345' * 40) + b'67/longname', out) + self.assertIn(b'./ustar/linktest2/symtype', out) + self.assertIn(b'./ustar/linktest2/lnktype', out) + # Make sure it puts trailing slash for directory + self.assertIn(b'ustar/dirtype/', out) + self.assertIn(b'ustar/dirtype-with-size/', out) + # Make sure it is able to print unencodable characters + def conv(b): + s = b.decode(self.tar.encoding, 'surrogateescape') + return s.encode('ascii', 'backslashreplace') + self.assertIn(conv(b'ustar/umlauts-\xc4\xd6\xdc\xe4\xf6\xfc\xdf'), out) + self.assertIn(conv(b'misc/regtype-hpux-signed-chksum-' + b'\xc4\xd6\xdc\xe4\xf6\xfc\xdf'), out) + self.assertIn(conv(b'misc/regtype-old-v7-signed-chksum-' + b'\xc4\xd6\xdc\xe4\xf6\xfc\xdf'), out) + self.assertIn(conv(b'pax/bad-pax-\xe4\xf6\xfc'), out) + self.assertIn(conv(b'pax/hdrcharset-\xe4\xf6\xfc'), out) + # Make sure it prints files separated by one newline without any + # 'ls -l'-like accessories if verbose flag is not being used + # ... + # ustar/conttype + # ustar/regtype + # ... + self.assertRegex(out, br'ustar/conttype ?\r?\n' + br'ustar/regtype ?\r?\n') + # Make sure it does not print the source of link without verbose flag + self.assertNotIn(b'link to', out) + self.assertNotIn(b'->', out) + + def test_list_verbose(self): + tio = io.TextIOWrapper(io.BytesIO(), 'ascii', newline='\n') + with support.swap_attr(sys, 'stdout', tio): + self.tar.list(verbose=True) + out = tio.detach().getvalue() + # Make sure it prints files separated by one newline with 'ls -l'-like + # accessories if verbose flag is being used + # ... + # ?rw-r--r-- tarfile/tarfile 7011 2003-01-06 07:19:43 ustar/conttype + # ?rw-r--r-- tarfile/tarfile 7011 2003-01-06 07:19:43 ustar/regtype + # ... + self.assertRegex(out, (br'\?rw-r--r-- tarfile/tarfile\s+7011 ' + br'\d{4}-\d\d-\d\d\s+\d\d:\d\d:\d\d ' + br'ustar/\w+type ?\r?\n') * 2) + # Make sure it prints the source of link with verbose flag + self.assertIn(b'ustar/symtype -> regtype', out) + self.assertIn(b'./ustar/linktest2/symtype -> ../linktest1/regtype', out) + self.assertIn(b'./ustar/linktest2/lnktype link to ' + b'./ustar/linktest1/regtype', out) + self.assertIn(b'gnu' + (b'/123' * 125) + b'/longlink link to gnu' + + (b'/123' * 125) + b'/longname', out) + self.assertIn(b'pax' + (b'/123' * 125) + b'/longlink link to pax' + + (b'/123' * 125) + b'/longname', out) + + def test_list_members(self): + tio = io.TextIOWrapper(io.BytesIO(), 'ascii', newline='\n') + def members(tar): + for tarinfo in tar.getmembers(): + if 'reg' in tarinfo.name: + yield tarinfo + with support.swap_attr(sys, 'stdout', tio): + self.tar.list(verbose=False, members=members(self.tar)) + out = tio.detach().getvalue() + self.assertIn(b'ustar/regtype', out) + self.assertNotIn(b'ustar/conttype', out) + + +class GzipListTest(GzipTest, ListTest): + pass + + +class Bz2ListTest(Bz2Test, ListTest): + pass + + +class LzmaListTest(LzmaTest, ListTest): + pass + + class CommonReadTest(ReadTest): def test_empty_tarfile(self): @@ -234,6 +329,12 @@ def test_empty_tarfile(self): finally: tar.close() + def test_non_existent_tarfile(self): + # Test for issue11513: prevent non-existent gzipped tarfiles raising + # multiple exceptions. + with self.assertRaisesRegex(FileNotFoundError, "xxx"): + tarfile.open("xxx", self.mode) + def test_null_tarfile(self): # Test for issue6123: Allow opening empty archives. # This test guarantees that tarfile.open() does not treat an empty @@ -262,10 +363,16 @@ def test_ignore_zeros(self): class MiscReadTestBase(CommonReadTest): + def requires_name_attribute(self): + pass + def test_no_name_argument(self): + self.requires_name_attribute() with open(self.tarname, "rb") as fobj: - tar = tarfile.open(fileobj=fobj, mode=self.mode) - self.assertEqual(tar.name, os.path.abspath(fobj.name)) + self.assertIsInstance(fobj.name, str) + with tarfile.open(fileobj=fobj, mode=self.mode) as tar: + self.assertIsInstance(tar.name, str) + self.assertEqual(tar.name, os.path.abspath(fobj.name)) def test_no_name_attribute(self): with open(self.tarname, "rb") as fobj: @@ -273,7 +380,7 @@ def test_no_name_attribute(self): fobj = io.BytesIO(data) self.assertRaises(AttributeError, getattr, fobj, "name") tar = tarfile.open(fileobj=fobj, mode=self.mode) - self.assertEqual(tar.name, None) + self.assertIsNone(tar.name) def test_empty_name_attribute(self): with open(self.tarname, "rb") as fobj: @@ -281,7 +388,35 @@ def test_empty_name_attribute(self): fobj = io.BytesIO(data) fobj.name = "" with tarfile.open(fileobj=fobj, mode=self.mode) as tar: - self.assertEqual(tar.name, None) + self.assertIsNone(tar.name) + + def test_int_name_attribute(self): + # Issue 21044: tarfile.open() should handle fileobj with an integer + # 'name' attribute. + fd = os.open(self.tarname, os.O_RDONLY) + with open(fd, 'rb') as fobj: + self.assertIsInstance(fobj.name, int) + with tarfile.open(fileobj=fobj, mode=self.mode) as tar: + self.assertIsNone(tar.name) + + def test_bytes_name_attribute(self): + self.requires_name_attribute() + tarname = os.fsencode(self.tarname) + with open(tarname, 'rb') as fobj: + self.assertIsInstance(fobj.name, bytes) + with tarfile.open(fileobj=fobj, mode=self.mode) as tar: + self.assertIsInstance(tar.name, bytes) + self.assertEqual(tar.name, os.path.abspath(fobj.name)) + + def test_illegal_mode_arg(self): + with open(tmpname, 'wb'): + pass + with self.assertRaisesRegex(ValueError, 'mode must be '): + tar = self.taropen(tmpname, 'q') + with self.assertRaisesRegex(ValueError, 'mode must be '): + tar = self.taropen(tmpname, 'rw') + with self.assertRaisesRegex(ValueError, 'mode must be '): + tar = self.taropen(tmpname, '') def test_fileobj_with_offset(self): # Skip the first member and store values from the second member @@ -356,16 +491,16 @@ def test_extract_hardlink(self): # Test hardlink extraction (e.g. bug #857297). with tarfile.open(tarname, errorlevel=1, encoding="iso8859-1") as tar: tar.extract("ustar/regtype", TEMPDIR) - self.addCleanup(os.remove, os.path.join(TEMPDIR, "ustar/regtype")) + self.addCleanup(support.unlink, os.path.join(TEMPDIR, "ustar/regtype")) tar.extract("ustar/lnktype", TEMPDIR) - self.addCleanup(os.remove, os.path.join(TEMPDIR, "ustar/lnktype")) + self.addCleanup(support.unlink, os.path.join(TEMPDIR, "ustar/lnktype")) with open(os.path.join(TEMPDIR, "ustar/lnktype"), "rb") as f: data = f.read() self.assertEqual(md5sum(data), md5_regtype) tar.extract("ustar/symtype", TEMPDIR) - self.addCleanup(os.remove, os.path.join(TEMPDIR, "ustar/symtype")) + self.addCleanup(support.unlink, os.path.join(TEMPDIR, "ustar/symtype")) with open(os.path.join(TEMPDIR, "ustar/symtype"), "rb") as f: data = f.read() self.assertEqual(md5sum(data), md5_regtype) @@ -398,7 +533,7 @@ def format_mtime(mtime): self.assertEqual(tarinfo.mtime, file_mtime, errmsg) finally: tar.close() - shutil.rmtree(DIR) + support.rmtree(DIR) def test_extract_directory(self): dirtype = "ustar/dirtype" @@ -413,7 +548,7 @@ def test_extract_directory(self): if sys.platform != "win32": self.assertEqual(os.stat(extracted).st_mode & 0o777, 0o755) finally: - shutil.rmtree(DIR) + support.rmtree(DIR) def test_init_close_fobj(self): # Issue #7341: Close the internal file object in the TarFile @@ -446,18 +581,14 @@ class MiscReadTest(MiscReadTestBase, unittest.TestCase): test_fail_comp = None class GzipMiscReadTest(GzipTest, MiscReadTestBase, unittest.TestCase): - def test_non_existent_targz_file(self): - # Test for issue11513: prevent non-existent gzipped tarfiles raising - # multiple exceptions. - with self.assertRaisesRegex(FileNotFoundError, "xxx"): - tarfile.open("xxx", self.mode) + pass class Bz2MiscReadTest(Bz2Test, MiscReadTestBase, unittest.TestCase): - def test_no_name_argument(self): + def requires_name_attribute(self): self.skipTest("BZ2File have no name attribute") class LzmaMiscReadTest(LzmaTest, MiscReadTestBase, unittest.TestCase): - def test_no_name_argument(self): + def requires_name_attribute(self): self.skipTest("LZMAFile have no name attribute") @@ -781,7 +912,7 @@ def _fs_supports_holes(): fobj.seek(4096) fobj.truncate() s = os.stat(name) - os.remove(name) + support.unlink(name) return s.st_blocks == 0 else: return False @@ -841,6 +972,12 @@ def test_fileobj_no_close(self): tar.addfile(tarfile.TarInfo("foo")) tar.close() self.assertFalse(fobj.closed, "external fileobjs must never closed") + # Issue #20238: Incomplete gzip output with mode="w:gz" + data = fobj.getvalue() + del tar + support.gc_collect() + self.assertFalse(fobj.closed) + self.assertEqual(data, fobj.getvalue()) class WriteTest(WriteTestBase, unittest.TestCase): @@ -908,7 +1045,7 @@ def test_directory_size(self): finally: tar.close() finally: - os.rmdir(path) + support.rmdir(path) @unittest.skipUnless(hasattr(os, "link"), "Missing hardlink implementation") @@ -928,8 +1065,8 @@ def test_link_size(self): finally: tar.close() finally: - os.remove(target) - os.remove(link) + support.unlink(target) + support.unlink(link) @support.skip_unless_symlink def test_symlink_size(self): @@ -943,7 +1080,7 @@ def test_symlink_size(self): finally: tar.close() finally: - os.remove(path) + support.unlink(path) def test_add_self(self): # Test for #1257255. @@ -990,7 +1127,7 @@ def test_exclude(self): finally: tar.close() finally: - shutil.rmtree(tempdir) + support.rmtree(tempdir) def test_filter(self): tempdir = os.path.join(TEMPDIR, "filter") @@ -1026,7 +1163,7 @@ def filter(tarinfo): finally: tar.close() finally: - shutil.rmtree(tempdir) + support.rmtree(tempdir) # Guarantee that stored pathnames are not modified. Don't # remove ./ or ../ or double slashes. Still make absolute @@ -1054,9 +1191,9 @@ def _test_pathname(self, path, cmp_path=None, dir=False): tar.close() if not dir: - os.remove(foo) + support.unlink(foo) else: - os.rmdir(foo) + support.rmdir(foo) self.assertEqual(t.name, cmp_path or path.replace(os.sep, "/")) @@ -1087,8 +1224,8 @@ def test_extractall_symlinks(self): finally: tar.close() finally: - os.unlink(temparchive) - shutil.rmtree(tempdir) + support.unlink(temparchive) + support.rmtree(tempdir) def test_pathnames(self): self._test_pathname("foo") @@ -1135,6 +1272,22 @@ def test_cwd(self): finally: os.chdir(cwd) + def test_open_nonwritable_fileobj(self): + for exctype in OSError, EOFError, RuntimeError: + class BadFile(io.BytesIO): + first = True + def write(self, data): + if self.first: + self.first = False + raise exctype + + f = BadFile() + with self.assertRaises(exctype): + tar = tarfile.open(tmpname, self.mode, fileobj=f, + format=tarfile.PAX_FORMAT, + pax_headers={'non': 'empty'}) + self.assertFalse(f.closed) + class GzipWriteTest(GzipTest, WriteTest): pass @@ -1172,7 +1325,7 @@ def test_file_mode(self): # Test for issue #8464: Create files with correct # permissions. if os.path.exists(tmpname): - os.remove(tmpname) + support.unlink(tmpname) original_umask = os.umask(0o022) try: @@ -1275,6 +1428,88 @@ def test_longnamelink_1025(self): ("longlnk/" * 127) + "longlink_") +class CreateTest(TarTest, unittest.TestCase): + + prefix = "x:" + + file_path = os.path.join(TEMPDIR, "spameggs42") + + def setUp(self): + support.unlink(tmpname) + + @classmethod + def setUpClass(cls): + with open(cls.file_path, "wb") as fobj: + fobj.write(b"aaa") + + @classmethod + def tearDownClass(cls): + support.unlink(cls.file_path) + + def test_create(self): + with tarfile.open(tmpname, self.mode) as tobj: + tobj.add(self.file_path) + + with self.taropen(tmpname) as tobj: + names = tobj.getnames() + self.assertEqual(len(names), 1) + self.assertIn('spameggs42', names[0]) + + def test_create_existing(self): + with tarfile.open(tmpname, self.mode) as tobj: + tobj.add(self.file_path) + + with self.assertRaises(FileExistsError): + tobj = tarfile.open(tmpname, self.mode) + + with self.taropen(tmpname) as tobj: + names = tobj.getnames() + self.assertEqual(len(names), 1) + self.assertIn('spameggs42', names[0]) + + def test_create_taropen(self): + with self.taropen(tmpname, "x") as tobj: + tobj.add(self.file_path) + + with self.taropen(tmpname) as tobj: + names = tobj.getnames() + self.assertEqual(len(names), 1) + self.assertIn('spameggs42', names[0]) + + def test_create_existing_taropen(self): + with self.taropen(tmpname, "x") as tobj: + tobj.add(self.file_path) + + with self.assertRaises(FileExistsError): + with self.taropen(tmpname, "x"): + pass + + with self.taropen(tmpname) as tobj: + names = tobj.getnames() + self.assertEqual(len(names), 1) + self.assertIn("spameggs42", names[0]) + + +class GzipCreateTest(GzipTest, CreateTest): + pass + + +class Bz2CreateTest(Bz2Test, CreateTest): + pass + + +class LzmaCreateTest(LzmaTest, CreateTest): + pass + + +class CreateWithXModeTest(CreateTest): + + prefix = "x" + + test_create_taropen = None + test_create_existing_taropen = None + + @unittest.skipUnless(hasattr(os, "link"), "Missing hardlink implementation") class HardlinkTest(unittest.TestCase): # Test the creation of LNKTYPE (hardlink) members in an archive. @@ -1526,7 +1761,7 @@ class AppendTestBase: def setUp(self): self.tarname = tmpname if os.path.exists(self.tarname): - os.remove(self.tarname) + support.unlink(self.tarname) def _create_testtar(self, mode="w:"): with tarfile.open(tarname, encoding="iso8859-1") as src: @@ -1728,8 +1963,9 @@ def test_number_field_limits(self): class CommandLineTest(unittest.TestCase): - def tarfilecmd(self, *args): - rc, out, err = script_helper.assert_python_ok('-m', 'tarfile', *args) + def tarfilecmd(self, *args, **kwargs): + rc, out, err = script_helper.assert_python_ok('-m', 'tarfile', *args, + **kwargs) return out.replace(os.linesep.encode(), b'\n') def tarfilecmd_failure(self, *args): @@ -1777,24 +2013,26 @@ def test_test_command_invalid_file(self): support.unlink(tmpname) def test_list_command(self): - self.make_simple_tarfile(tmpname) - with support.captured_stdout() as t: - with tarfile.open(tmpname, 'r') as tf: - tf.list(verbose=False) - expected = t.getvalue().encode(sys.getfilesystemencoding()) - for opt in '-l', '--list': - out = self.tarfilecmd(opt, tmpname) - self.assertEqual(out, expected) + for tar_name in testtarnames: + with support.captured_stdout() as t: + with tarfile.open(tar_name, 'r') as tf: + tf.list(verbose=False) + expected = t.getvalue().encode('ascii', 'backslashreplace') + for opt in '-l', '--list': + out = self.tarfilecmd(opt, tar_name, + PYTHONIOENCODING='ascii') + self.assertEqual(out, expected) def test_list_command_verbose(self): - self.make_simple_tarfile(tmpname) - with support.captured_stdout() as t: - with tarfile.open(tmpname, 'r') as tf: - tf.list(verbose=True) - expected = t.getvalue().encode(sys.getfilesystemencoding()) - for opt in '-v', '--verbose': - out = self.tarfilecmd(opt, '-l', tmpname) - self.assertEqual(out, expected) + for tar_name in testtarnames: + with support.captured_stdout() as t: + with tarfile.open(tar_name, 'r') as tf: + tf.list(verbose=True) + expected = t.getvalue().encode('ascii', 'backslashreplace') + for opt in '-v', '--verbose': + out = self.tarfilecmd(opt, '-l', tar_name, + PYTHONIOENCODING='ascii') + self.assertEqual(out, expected) def test_list_command_invalid_file(self): zipname = support.findfile('zipdir.zip') @@ -1850,6 +2088,21 @@ def test_create_command_dot_started_filename(self): finally: support.unlink(tar_name) + def test_create_command_compressed(self): + files = [support.findfile('tokenize_tests.txt'), + support.findfile('tokenize_tests-no-coding-cookie-' + 'and-utf8-bom-sig-only.txt')] + for filetype in (GzipTest, Bz2Test, LzmaTest): + if not filetype.open: + continue + try: + tar_name = tmpname + '.' + filetype.suffix + out = self.tarfilecmd('-c', tar_name, *files) + with filetype.taropen(tar_name) as tar: + tar.getmembers() + finally: + support.unlink(tar_name) + def test_extract_command(self): self.make_simple_tarfile(tmpname) for opt in '-e', '--extract': @@ -2030,7 +2283,7 @@ def setUpModule(): def tearDownModule(): if os.path.exists(TEMPDIR): - shutil.rmtree(TEMPDIR) + support.rmtree(TEMPDIR) if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_tcl.py b/Lib/test/test_tcl.py index 66c49ffedcb5..d0251aa339c5 100644 --- a/Lib/test/test_tcl.py +++ b/Lib/test/test_tcl.py @@ -1,20 +1,22 @@ -#!/usr/bin/env python3 - import unittest import sys import os -import _testcapi from test import support # Skip this test if the _tkinter module wasn't built. _tkinter = support.import_module('_tkinter') # Make sure tkinter._fix runs to set up the environment -support.import_fresh_module('tkinter') +tkinter = support.import_fresh_module('tkinter') from tkinter import Tcl from _tkinter import TclError +try: + from _testcapi import INT_MAX, PY_SSIZE_T_MAX +except ImportError: + INT_MAX = PY_SSIZE_T_MAX = sys.maxsize + tcl_version = _tkinter.TCL_VERSION.split('.') try: for i in range(len(tcl_version)): @@ -23,6 +25,21 @@ pass tcl_version = tuple(tcl_version) +_tk_patchlevel = None +def get_tk_patchlevel(): + global _tk_patchlevel + if _tk_patchlevel is None: + tcl = Tcl() + patchlevel = [] + for x in tcl.call('info', 'patchlevel').split('.'): + try: + x = int(x, 10) + except ValueError: + x = -1 + patchlevel.append(x) + _tk_patchlevel = tuple(patchlevel) + return _tk_patchlevel + class TkinterTest(unittest.TestCase): @@ -35,12 +52,17 @@ class TclTest(unittest.TestCase): def setUp(self): self.interp = Tcl() + self.wantobjects = self.interp.tk.wantobjects() def testEval(self): tcl = self.interp tcl.eval('set a 1') self.assertEqual(tcl.eval('set a'),'1') + def test_eval_null_in_result(self): + tcl = self.interp + self.assertEqual(tcl.eval('set a "a\\0b"'), 'a\x00b') + def testEvalException(self): tcl = self.interp self.assertRaises(TclError,tcl.eval,'set a') @@ -111,22 +133,75 @@ def testUnsetVarException(self): tcl = self.interp self.assertRaises(TclError,tcl.unsetvar,'a') + def test_getint(self): + tcl = self.interp.tk + self.assertEqual(tcl.getint(' 42 '), 42) + self.assertEqual(tcl.getint(42), 42) + self.assertRaises(TypeError, tcl.getint) + self.assertRaises(TypeError, tcl.getint, '42', '10') + self.assertRaises(TypeError, tcl.getint, b'42') + self.assertRaises(TypeError, tcl.getint, 42.0) + self.assertRaises(TclError, tcl.getint, 'a') + self.assertRaises((TypeError, ValueError, TclError), + tcl.getint, '42\0') + self.assertRaises((UnicodeEncodeError, ValueError, TclError), + tcl.getint, '42\ud800') + + def test_getdouble(self): + tcl = self.interp.tk + self.assertEqual(tcl.getdouble(' 42 '), 42.0) + self.assertEqual(tcl.getdouble(' 42.5 '), 42.5) + self.assertEqual(tcl.getdouble(42.5), 42.5) + self.assertRaises(TypeError, tcl.getdouble) + self.assertRaises(TypeError, tcl.getdouble, '42.5', '10') + self.assertRaises(TypeError, tcl.getdouble, b'42.5') + self.assertRaises(TypeError, tcl.getdouble, 42) + self.assertRaises(TclError, tcl.getdouble, 'a') + self.assertRaises((TypeError, ValueError, TclError), + tcl.getdouble, '42.5\0') + self.assertRaises((UnicodeEncodeError, ValueError, TclError), + tcl.getdouble, '42.5\ud800') + + def test_getboolean(self): + tcl = self.interp.tk + self.assertIs(tcl.getboolean('on'), True) + self.assertIs(tcl.getboolean('1'), True) + self.assertEqual(tcl.getboolean(42), 42) + self.assertRaises(TypeError, tcl.getboolean) + self.assertRaises(TypeError, tcl.getboolean, 'on', '1') + self.assertRaises(TypeError, tcl.getboolean, b'on') + self.assertRaises(TypeError, tcl.getboolean, 1.0) + self.assertRaises(TclError, tcl.getboolean, 'a') + self.assertRaises((TypeError, ValueError, TclError), + tcl.getboolean, 'on\0') + self.assertRaises((UnicodeEncodeError, ValueError, TclError), + tcl.getboolean, 'on\ud800') + def testEvalFile(self): tcl = self.interp - filename = "testEvalFile.tcl" - fd = open(filename,'w') - script = """set a 1 - set b 2 - set c [ expr $a + $b ] - """ - fd.write(script) - fd.close() - tcl.evalfile(filename) - os.remove(filename) + with open(support.TESTFN, 'w') as f: + self.addCleanup(support.unlink, support.TESTFN) + f.write("""set a 1 + set b 2 + set c [ expr $a + $b ] + """) + tcl.evalfile(support.TESTFN) self.assertEqual(tcl.eval('set a'),'1') self.assertEqual(tcl.eval('set b'),'2') self.assertEqual(tcl.eval('set c'),'3') + def test_evalfile_null_in_result(self): + tcl = self.interp + with open(support.TESTFN, 'w') as f: + self.addCleanup(support.unlink, support.TESTFN) + f.write(""" + set a "a\0b" + set b "a\\0b" + """) + tcl.evalfile(support.TESTFN) + self.assertEqual(tcl.eval('set a'), 'a\x00b') + self.assertEqual(tcl.eval('set b'), 'a\x00b') + def testEvalFileException(self): tcl = self.interp filename = "doesnotexists" @@ -163,26 +238,237 @@ def testLoadWithUNC(self): # exit code must be zero self.assertEqual(f.close(), None) + def test_exprstring(self): + tcl = self.interp + tcl.call('set', 'a', 3) + tcl.call('set', 'b', 6) + def check(expr, expected): + result = tcl.exprstring(expr) + self.assertEqual(result, expected) + self.assertIsInstance(result, str) + + self.assertRaises(TypeError, tcl.exprstring) + self.assertRaises(TypeError, tcl.exprstring, '8.2', '+6') + self.assertRaises(TypeError, tcl.exprstring, b'8.2 + 6') + self.assertRaises(TclError, tcl.exprstring, 'spam') + check('', '0') + check('8.2 + 6', '14.2') + check('3.1 + $a', '6.1') + check('2 + "$a.$b"', '5.6') + check('4*[llength "6 2"]', '8') + check('{word one} < "word $a"', '0') + check('4*2 < 7', '0') + check('hypot($a, 4)', '5.0') + check('5 / 4', '1') + check('5 / 4.0', '1.25') + check('5 / ( [string length "abcd"] + 0.0 )', '1.25') + check('20.0/5.0', '4.0') + check('"0x03" > "2"', '1') + check('[string length "a\xbd\u20ac"]', '3') + check(r'[string length "a\xbd\u20ac"]', '3') + check('"abc"', 'abc') + check('"a\xbd\u20ac"', 'a\xbd\u20ac') + check(r'"a\xbd\u20ac"', 'a\xbd\u20ac') + check(r'"a\0b"', 'a\x00b') + if tcl_version >= (8, 5): + check('2**64', str(2**64)) + + def test_exprdouble(self): + tcl = self.interp + tcl.call('set', 'a', 3) + tcl.call('set', 'b', 6) + def check(expr, expected): + result = tcl.exprdouble(expr) + self.assertEqual(result, expected) + self.assertIsInstance(result, float) + + self.assertRaises(TypeError, tcl.exprdouble) + self.assertRaises(TypeError, tcl.exprdouble, '8.2', '+6') + self.assertRaises(TypeError, tcl.exprdouble, b'8.2 + 6') + self.assertRaises(TclError, tcl.exprdouble, 'spam') + check('', 0.0) + check('8.2 + 6', 14.2) + check('3.1 + $a', 6.1) + check('2 + "$a.$b"', 5.6) + check('4*[llength "6 2"]', 8.0) + check('{word one} < "word $a"', 0.0) + check('4*2 < 7', 0.0) + check('hypot($a, 4)', 5.0) + check('5 / 4', 1.0) + check('5 / 4.0', 1.25) + check('5 / ( [string length "abcd"] + 0.0 )', 1.25) + check('20.0/5.0', 4.0) + check('"0x03" > "2"', 1.0) + check('[string length "a\xbd\u20ac"]', 3.0) + check(r'[string length "a\xbd\u20ac"]', 3.0) + self.assertRaises(TclError, tcl.exprdouble, '"abc"') + if tcl_version >= (8, 5): + check('2**64', float(2**64)) + + def test_exprlong(self): + tcl = self.interp + tcl.call('set', 'a', 3) + tcl.call('set', 'b', 6) + def check(expr, expected): + result = tcl.exprlong(expr) + self.assertEqual(result, expected) + self.assertIsInstance(result, int) + + self.assertRaises(TypeError, tcl.exprlong) + self.assertRaises(TypeError, tcl.exprlong, '8.2', '+6') + self.assertRaises(TypeError, tcl.exprlong, b'8.2 + 6') + self.assertRaises(TclError, tcl.exprlong, 'spam') + check('', 0) + check('8.2 + 6', 14) + check('3.1 + $a', 6) + check('2 + "$a.$b"', 5) + check('4*[llength "6 2"]', 8) + check('{word one} < "word $a"', 0) + check('4*2 < 7', 0) + check('hypot($a, 4)', 5) + check('5 / 4', 1) + check('5 / 4.0', 1) + check('5 / ( [string length "abcd"] + 0.0 )', 1) + check('20.0/5.0', 4) + check('"0x03" > "2"', 1) + check('[string length "a\xbd\u20ac"]', 3) + check(r'[string length "a\xbd\u20ac"]', 3) + self.assertRaises(TclError, tcl.exprlong, '"abc"') + if tcl_version >= (8, 5): + self.assertRaises(TclError, tcl.exprlong, '2**64') + + def test_exprboolean(self): + tcl = self.interp + tcl.call('set', 'a', 3) + tcl.call('set', 'b', 6) + def check(expr, expected): + result = tcl.exprboolean(expr) + self.assertEqual(result, expected) + self.assertIsInstance(result, int) + self.assertNotIsInstance(result, bool) + + self.assertRaises(TypeError, tcl.exprboolean) + self.assertRaises(TypeError, tcl.exprboolean, '8.2', '+6') + self.assertRaises(TypeError, tcl.exprboolean, b'8.2 + 6') + self.assertRaises(TclError, tcl.exprboolean, 'spam') + check('', False) + for value in ('0', 'false', 'no', 'off'): + check(value, False) + check('"%s"' % value, False) + check('{%s}' % value, False) + for value in ('1', 'true', 'yes', 'on'): + check(value, True) + check('"%s"' % value, True) + check('{%s}' % value, True) + check('8.2 + 6', True) + check('3.1 + $a', True) + check('2 + "$a.$b"', True) + check('4*[llength "6 2"]', True) + check('{word one} < "word $a"', False) + check('4*2 < 7', False) + check('hypot($a, 4)', True) + check('5 / 4', True) + check('5 / 4.0', True) + check('5 / ( [string length "abcd"] + 0.0 )', True) + check('20.0/5.0', True) + check('"0x03" > "2"', True) + check('[string length "a\xbd\u20ac"]', True) + check(r'[string length "a\xbd\u20ac"]', True) + self.assertRaises(TclError, tcl.exprboolean, '"abc"') + if tcl_version >= (8, 5): + check('2**64', True) + def test_passing_values(self): def passValue(value): return self.interp.call('set', '_', value) - self.assertEqual(passValue(True), True) - self.assertEqual(passValue(False), False) + self.assertEqual(passValue(True), True if self.wantobjects else '1') + self.assertEqual(passValue(False), False if self.wantobjects else '0') self.assertEqual(passValue('string'), 'string') self.assertEqual(passValue('string\u20ac'), 'string\u20ac') + self.assertEqual(passValue('str\x00ing'), 'str\x00ing') + self.assertEqual(passValue('str\x00ing\xbd'), 'str\x00ing\xbd') + self.assertEqual(passValue('str\x00ing\u20ac'), 'str\x00ing\u20ac') + self.assertEqual(passValue(b'str\x00ing'), + b'str\x00ing' if self.wantobjects else 'str\x00ing') + self.assertEqual(passValue(b'str\xc0\x80ing'), + b'str\xc0\x80ing' if self.wantobjects else 'str\xc0\x80ing') + self.assertEqual(passValue(b'str\xbding'), + b'str\xbding' if self.wantobjects else 'str\xbding') for i in (0, 1, -1, 2**31-1, -2**31): - self.assertEqual(passValue(i), i) + self.assertEqual(passValue(i), i if self.wantobjects else str(i)) for f in (0.0, 1.0, -1.0, 1/3, sys.float_info.min, sys.float_info.max, -sys.float_info.min, -sys.float_info.max): - self.assertEqual(passValue(f), f) - for f in float('nan'), float('inf'), -float('inf'): - if f != f: # NaN - self.assertNotEqual(passValue(f), f) - else: + if self.wantobjects: self.assertEqual(passValue(f), f) - self.assertEqual(passValue((1, '2', (3.4,))), (1, '2', (3.4,))) + else: + self.assertEqual(float(passValue(f)), f) + if self.wantobjects: + f = passValue(float('nan')) + self.assertNotEqual(f, f) + self.assertEqual(passValue(float('inf')), float('inf')) + self.assertEqual(passValue(-float('inf')), -float('inf')) + else: + self.assertEqual(float(passValue(float('inf'))), float('inf')) + self.assertEqual(float(passValue(-float('inf'))), -float('inf')) + # XXX NaN representation can be not parsable by float() + self.assertEqual(passValue((1, '2', (3.4,))), + (1, '2', (3.4,)) if self.wantobjects else '1 2 3.4') + self.assertEqual(passValue(['a', ['b', 'c']]), + ('a', ('b', 'c')) if self.wantobjects else 'a {b c}') + + def test_user_command(self): + result = None + def testfunc(arg): + nonlocal result + result = arg + return arg + self.interp.createcommand('testfunc', testfunc) + self.addCleanup(self.interp.tk.deletecommand, 'testfunc') + def check(value, expected=None, *, eq=self.assertEqual): + if expected is None: + expected = value + nonlocal result + result = None + r = self.interp.call('testfunc', value) + self.assertIsInstance(result, str) + eq(result, expected) + self.assertIsInstance(r, str) + eq(r, expected) + def float_eq(actual, expected): + self.assertAlmostEqual(float(actual), expected, + delta=abs(expected) * 1e-10) + + check(True, '1') + check(False, '0') + check('string') + check('string\xbd') + check('string\u20ac') + check('') + check(b'string', 'string') + check(b'string\xe2\x82\xac', 'string\xe2\x82\xac') + check(b'string\xbd', 'string\xbd') + check(b'', '') + check('str\x00ing') + check('str\x00ing\xbd') + check('str\x00ing\u20ac') + check(b'str\x00ing', 'str\x00ing') + check(b'str\xc0\x80ing', 'str\xc0\x80ing') + check(b'str\xc0\x80ing\xe2\x82\xac', 'str\xc0\x80ing\xe2\x82\xac') + for i in (0, 1, -1, 2**31-1, -2**31): + check(i, str(i)) + for f in (0.0, 1.0, -1.0): + check(f, repr(f)) + for f in (1/3.0, sys.float_info.min, sys.float_info.max, + -sys.float_info.min, -sys.float_info.max): + check(f, eq=float_eq) + check(float('inf'), eq=float_eq) + check(-float('inf'), eq=float_eq) + # XXX NaN representation can be not parsable by float() + check((), '') + check((1, (2,), (3, 4), '5 6', ()), '1 2 {3 4} {5 6} {}') + check([1, [2,], [3, 4], '5 6', []], '1 2 {3 4} {5 6} {}') def test_splitlist(self): splitlist = self.interp.tk.splitlist @@ -199,6 +485,7 @@ def test_splitlist(self): (b'a\n b\t\r c\n ', ('a', 'b', 'c')), ('a \u20ac', ('a', '\u20ac')), (b'a \xe2\x82\xac', ('a', '\u20ac')), + (b'a\xc0\x80b c\xc0\x80d', ('a\x00b', 'c\x00d')), ('a {b c}', ('a', 'b c')), (r'a b\ c', ('a', 'b c')), (('a', 'b c'), ('a', 'b c')), @@ -207,15 +494,28 @@ def test_splitlist(self): ('a 3.4', ('a', '3.4')), (('a', 3.4), ('a', 3.4)), ((), ()), - (call('list', 1, '2', (3.4,)), (1, '2', (3.4,))), + ([], ()), + (['a', ['b', 'c']], ('a', ['b', 'c'])), + (call('list', 1, '2', (3.4,)), + (1, '2', (3.4,)) if self.wantobjects else + ('1', '2', '3.4')), ] + tk_patchlevel = get_tk_patchlevel() if tcl_version >= (8, 5): + if not self.wantobjects or tk_patchlevel < (8, 5, 5): + # Before 8.5.5 dicts were converted to lists through string + expected = ('12', '\u20ac', '\xe2\x82\xac', '3.4') + else: + expected = (12, '\u20ac', b'\xe2\x82\xac', (3.4,)) testcases += [ - (call('dict', 'create', 1, '\u20ac', b'\xe2\x82\xac', (3.4,)), - (1, '\u20ac', '\u20ac', (3.4,))), + (call('dict', 'create', 12, '\u20ac', b'\xe2\x82\xac', (3.4,)), + expected), ] + dbg_info = ('want objects? %s, Tcl version: %s, Tk patchlevel: %s' + % (self.wantobjects, tcl_version, tk_patchlevel)) for arg, res in testcases: - self.assertEqual(splitlist(arg), res, msg=arg) + self.assertEqual(splitlist(arg), res, + 'arg=%a, %s' % (arg, dbg_info)) self.assertRaises(TclError, splitlist, '{') def test_split(self): @@ -234,6 +534,9 @@ def test_split(self): (b'a\n b\t\r c\n ', ('a', 'b', 'c')), ('a \u20ac', ('a', '\u20ac')), (b'a \xe2\x82\xac', ('a', '\u20ac')), + (b'a\xc0\x80b', 'a\x00b'), + (b'a\xc0\x80b c\xc0\x80d', ('a\x00b', 'c\x00d')), + (b'{a\xc0\x80b c\xc0\x80d', '{a\x00b c\x00d'), ('a {b c}', ('a', ('b', 'c'))), (r'a b\ c', ('a', ('b', 'c'))), (('a', b'b c'), ('a', ('b', 'c'))), @@ -244,29 +547,99 @@ def test_split(self): (('a', 3.4), ('a', 3.4)), (('a', (2, 3.4)), ('a', (2, 3.4))), ((), ()), - (call('list', 1, '2', (3.4,)), (1, '2', (3.4,))), + ([], ()), + (['a', 'b c'], ('a', ('b', 'c'))), + (['a', ['b', 'c']], ('a', ('b', 'c'))), + (call('list', 1, '2', (3.4,)), + (1, '2', (3.4,)) if self.wantobjects else + ('1', '2', '3.4')), ] if tcl_version >= (8, 5): + if not self.wantobjects or get_tk_patchlevel() < (8, 5, 5): + # Before 8.5.5 dicts were converted to lists through string + expected = ('12', '\u20ac', '\xe2\x82\xac', '3.4') + else: + expected = (12, '\u20ac', b'\xe2\x82\xac', (3.4,)) testcases += [ (call('dict', 'create', 12, '\u20ac', b'\xe2\x82\xac', (3.4,)), - (12, '\u20ac', '\u20ac', (3.4,))), + expected), ] for arg, res in testcases: self.assertEqual(split(arg), res, msg=arg) + def test_splitdict(self): + splitdict = tkinter._splitdict + tcl = self.interp.tk + + arg = '-a {1 2 3} -something foo status {}' + self.assertEqual(splitdict(tcl, arg, False), + {'-a': '1 2 3', '-something': 'foo', 'status': ''}) + self.assertEqual(splitdict(tcl, arg), + {'a': '1 2 3', 'something': 'foo', 'status': ''}) + + arg = ('-a', (1, 2, 3), '-something', 'foo', 'status', '{}') + self.assertEqual(splitdict(tcl, arg, False), + {'-a': (1, 2, 3), '-something': 'foo', 'status': '{}'}) + self.assertEqual(splitdict(tcl, arg), + {'a': (1, 2, 3), 'something': 'foo', 'status': '{}'}) + + self.assertRaises(RuntimeError, splitdict, tcl, '-a b -c ') + self.assertRaises(RuntimeError, splitdict, tcl, ('-a', 'b', '-c')) + + arg = tcl.call('list', + '-a', (1, 2, 3), '-something', 'foo', 'status', ()) + self.assertEqual(splitdict(tcl, arg), + {'a': (1, 2, 3) if self.wantobjects else '1 2 3', + 'something': 'foo', 'status': ''}) + + if tcl_version >= (8, 5): + arg = tcl.call('dict', 'create', + '-a', (1, 2, 3), '-something', 'foo', 'status', ()) + if not self.wantobjects or get_tk_patchlevel() < (8, 5, 5): + # Before 8.5.5 dicts were converted to lists through string + expected = {'a': '1 2 3', 'something': 'foo', 'status': ''} + else: + expected = {'a': (1, 2, 3), 'something': 'foo', 'status': ''} + self.assertEqual(splitdict(tcl, arg), expected) + class BigmemTclTest(unittest.TestCase): def setUp(self): self.interp = Tcl() - @unittest.skipUnless(_testcapi.INT_MAX < _testcapi.PY_SSIZE_T_MAX, - "needs UINT_MAX < SIZE_MAX") - @support.bigmemtest(size=_testcapi.INT_MAX + 1, memuse=5, dry_run=False) - def test_huge_string(self, size): + @support.cpython_only + @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX") + @support.bigmemtest(size=INT_MAX + 1, memuse=5, dry_run=False) + def test_huge_string_call(self, size): value = ' ' * size self.assertRaises(OverflowError, self.interp.call, 'set', '_', value) + @support.cpython_only + @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX") + @support.bigmemtest(size=INT_MAX + 1, memuse=9, dry_run=False) + def test_huge_string_builtins(self, size): + value = '1' + ' ' * size + self.assertRaises(OverflowError, self.interp.tk.getint, value) + self.assertRaises(OverflowError, self.interp.tk.getdouble, value) + self.assertRaises(OverflowError, self.interp.tk.getboolean, value) + self.assertRaises(OverflowError, self.interp.eval, value) + self.assertRaises(OverflowError, self.interp.evalfile, value) + self.assertRaises(OverflowError, self.interp.record, value) + self.assertRaises(OverflowError, self.interp.adderrorinfo, value) + self.assertRaises(OverflowError, self.interp.setvar, value, 'x', 'a') + self.assertRaises(OverflowError, self.interp.setvar, 'x', value, 'a') + self.assertRaises(OverflowError, self.interp.unsetvar, value) + self.assertRaises(OverflowError, self.interp.unsetvar, 'x', value) + self.assertRaises(OverflowError, self.interp.adderrorinfo, value) + self.assertRaises(OverflowError, self.interp.exprstring, value) + self.assertRaises(OverflowError, self.interp.exprlong, value) + self.assertRaises(OverflowError, self.interp.exprboolean, value) + self.assertRaises(OverflowError, self.interp.splitlist, value) + self.assertRaises(OverflowError, self.interp.split, value) + self.assertRaises(OverflowError, self.interp.createcommand, value, max) + self.assertRaises(OverflowError, self.interp.deletecommand, value) + def setUpModule(): if support.verbose: diff --git a/Lib/test/test_telnetlib.py b/Lib/test/test_telnetlib.py index 4f61e44d2c69..e1ef99af3a2a 100644 --- a/Lib/test/test_telnetlib.py +++ b/Lib/test/test_telnetlib.py @@ -11,7 +11,7 @@ HOST = support.HOST def server(evt, serv): - serv.listen(5) + serv.listen() evt.set() try: conn, addr = serv.accept() @@ -116,6 +116,10 @@ class MockSelector(selectors.BaseSelector): def __init__(self): self.keys = {} + @property + def resolution(self): + return 1e-3 + def register(self, fileobj, events, data=None): key = selectors.SelectorKey(fileobj, 0, events, data) self.keys[fileobj] = key diff --git a/Lib/test/test_tempfile.py b/Lib/test/test_tempfile.py index ac4d8609dfe2..2e10fddae0f4 100644 --- a/Lib/test/test_tempfile.py +++ b/Lib/test/test_tempfile.py @@ -8,9 +8,11 @@ import re import warnings import contextlib +import weakref +from unittest import mock import unittest -from test import support +from test import support, script_helper if hasattr(os, 'stat'): @@ -324,10 +326,9 @@ def test_choose_directory(self): finally: os.rmdir(dir) + @unittest.skipUnless(has_stat, 'os.stat not available') def test_file_mode(self): # _mkstemp_inner creates files with the proper mode - if not has_stat: - return # ugh, can't use SkipTest. file = self.do_create() mode = stat.S_IMODE(os.stat(file.name).st_mode) @@ -339,10 +340,9 @@ def test_file_mode(self): expected = user * (1 + 8 + 64) self.assertEqual(mode, expected) + @unittest.skipUnless(has_spawnl, 'os.spawnl not available') def test_noinherit(self): # _mkstemp_inner file handles are not inherited by child processes - if not has_spawnl: - return # ugh, can't use SkipTest. if support.verbose: v="v" @@ -378,10 +378,9 @@ def test_noinherit(self): "child process caught fatal signal %d" % -retval) self.assertFalse(retval > 0, "child process reports failure %d"%retval) + @unittest.skipUnless(has_textmode, "text mode not available") def test_textmode(self): # _mkstemp_inner can create files in text mode - if not has_textmode: - return # ugh, can't use SkipTest. # A text file is truncated at the first Ctrl+Z byte f = self.do_create(bin=0) @@ -571,10 +570,9 @@ def test_choose_directory(self): finally: os.rmdir(dir) + @unittest.skipUnless(has_stat, 'os.stat not available') def test_mode(self): # mkdtemp creates directories with the proper mode - if not has_stat: - return # ugh, can't use SkipTest. dir = self.do_create() try: @@ -693,6 +691,22 @@ def test_basic(self): self.do_create(pre="a", suf="b") self.do_create(pre="aa", suf=".txt") + def test_method_lookup(self): + # Issue #18879: Looking up a temporary file method should keep it + # alive long enough. + f = self.do_create() + wr = weakref.ref(f) + write = f.write + write2 = f.write + del f + write(b'foo') + del write + write2(b'bar') + del write2 + if support.check_impl_detail(cpython=True): + # No reference cycle was created. + self.assertIsNone(wr()) + def test_creates_named(self): # NamedTemporaryFile creates files with names f = tempfile.NamedTemporaryFile() @@ -745,6 +759,19 @@ def use_closed(): pass self.assertRaises(ValueError, use_closed) + def test_no_leak_fd(self): + # Issue #21058: don't leak file descriptor when io.open() fails + closed = [] + os_close = os.close + def close(fd): + closed.append(fd) + os_close(fd) + + with mock.patch('os.close', side_effect=close): + with mock.patch('io.open', side_effect=ValueError): + self.assertRaises(ValueError, tempfile.NamedTemporaryFile) + self.assertEqual(len(closed), 1) + # How to test the mode and bufsize parameters? @@ -1048,6 +1075,20 @@ def roundtrip(input, *args, **kwargs): roundtrip("\u039B", "w+", encoding="utf-16") roundtrip("foo\r\n", "w+", newline="") + def test_no_leak_fd(self): + # Issue #21058: don't leak file descriptor when io.open() fails + closed = [] + os_close = os.close + def close(fd): + closed.append(fd) + os_close(fd) + + with mock.patch('os.close', side_effect=close): + with mock.patch('io.open', side_effect=ValueError): + self.assertRaises(ValueError, tempfile.TemporaryFile) + self.assertEqual(len(closed), 1) + + # Helper for test_del_on_shutdown class NulledModules: @@ -1075,7 +1116,8 @@ def do_create(self, dir=None, pre="", suf="", recurse=1): self.nameCheck(tmp.name, dir, pre, suf) # Create a subdirectory and some files if recurse: - self.do_create(tmp.name, pre, suf, recurse-1) + d1 = self.do_create(tmp.name, pre, suf, recurse-1) + d1.name = None with open(os.path.join(tmp.name, "test.txt"), "wb") as f: f.write(b"Hello world!") return tmp @@ -1107,7 +1149,7 @@ def test_explicit_cleanup(self): def test_cleanup_with_symlink_to_a_directory(self): # cleanup() should not follow symlinks to directories (issue #12464) d1 = self.do_create() - d2 = self.do_create() + d2 = self.do_create(recurse=0) # Symlink d1/foo -> d2 os.symlink(d2.name, os.path.join(d1.name, "foo")) @@ -1137,60 +1179,75 @@ def test_del_on_collection(self): finally: os.rmdir(dir) - @unittest.expectedFailure # See issue #10188 def test_del_on_shutdown(self): # A TemporaryDirectory may be cleaned up during shutdown - # Make sure it works with the relevant modules nulled out with self.do_create() as dir: - d = self.do_create(dir=dir) - # Mimic the nulling out of modules that - # occurs during system shutdown - modules = [os, os.path] - if has_stat: - modules.append(stat) - # Currently broken, so suppress the warning - # that is otherwise emitted on stdout - with support.captured_stderr() as err: - with NulledModules(*modules): - d.cleanup() - # Currently broken, so stop spurious exception by - # indicating the object has already been closed - d._closed = True - # And this assert will fail, as expected by the - # unittest decorator... - self.assertFalse(os.path.exists(d.name), - "TemporaryDirectory %s exists after cleanup" % d.name) + for mod in ('builtins', 'os', 'shutil', 'sys', 'tempfile', 'warnings'): + code = """if True: + import builtins + import os + import shutil + import sys + import tempfile + import warnings + + tmp = tempfile.TemporaryDirectory(dir={dir!r}) + sys.stdout.buffer.write(tmp.name.encode()) + + tmp2 = os.path.join(tmp.name, 'test_dir') + os.mkdir(tmp2) + with open(os.path.join(tmp2, "test.txt"), "w") as f: + f.write("Hello world!") + + {mod}.tmp = tmp + + warnings.filterwarnings("always", category=ResourceWarning) + """.format(dir=dir, mod=mod) + rc, out, err = script_helper.assert_python_ok("-c", code) + tmp_name = out.decode().strip() + self.assertFalse(os.path.exists(tmp_name), + "TemporaryDirectory %s exists after cleanup" % tmp_name) + err = err.decode('utf-8', 'backslashreplace') + self.assertNotIn("Exception ", err) + self.assertIn("ResourceWarning: Implicitly cleaning up", err) + + def test_exit_on_shutdown(self): + # Issue #22427 + with self.do_create() as dir: + code = """if True: + import sys + import tempfile + import warnings + + def generator(): + with tempfile.TemporaryDirectory(dir={dir!r}) as tmp: + yield tmp + g = generator() + sys.stdout.buffer.write(next(g).encode()) + + warnings.filterwarnings("always", category=ResourceWarning) + """.format(dir=dir) + rc, out, err = script_helper.assert_python_ok("-c", code) + tmp_name = out.decode().strip() + self.assertFalse(os.path.exists(tmp_name), + "TemporaryDirectory %s exists after cleanup" % tmp_name) + err = err.decode('utf-8', 'backslashreplace') + self.assertNotIn("Exception ", err) + self.assertIn("ResourceWarning: Implicitly cleaning up", err) def test_warnings_on_cleanup(self): - # Two kinds of warning on shutdown - # Issue 10888: may write to stderr if modules are nulled out - # ResourceWarning will be triggered by __del__ + # ResourceWarning will be triggered by __del__ with self.do_create() as dir: - if os.sep != '\\': - # Embed a backslash in order to make sure string escaping - # in the displayed error message is dealt with correctly - suffix = '\\check_backslash_handling' - else: - suffix = '' - d = self.do_create(dir=dir, suf=suffix) - - #Check for the Issue 10888 message - modules = [os, os.path] - if has_stat: - modules.append(stat) - with support.captured_stderr() as err: - with NulledModules(*modules): - d.cleanup() - message = err.getvalue().replace('\\\\', '\\') - self.assertIn("while cleaning up", message) - self.assertIn(d.name, message) + d = self.do_create(dir=dir, recurse=3) + name = d.name # Check for the resource warning with support.check_warnings(('Implicitly', ResourceWarning), quiet=False): warnings.filterwarnings("always", category=ResourceWarning) - d.__del__() - self.assertFalse(os.path.exists(d.name), - "TemporaryDirectory %s exists after __del__" % d.name) + del d + support.gc_collect() + self.assertFalse(os.path.exists(name), + "TemporaryDirectory %s exists after __del__" % name) def test_multiple_close(self): # Can be cleaned-up many times without error diff --git a/Lib/test/test_thread.py b/Lib/test/test_thread.py index f9a721b03bc1..614490199aea 100644 --- a/Lib/test/test_thread.py +++ b/Lib/test/test_thread.py @@ -68,39 +68,35 @@ def test_stack_size(self): thread.stack_size(0) self.assertEqual(thread.stack_size(), 0, "stack_size not reset to default") - if os.name not in ("nt", "posix"): - return - - tss_supported = True + @unittest.skipIf(os.name not in ("nt", "posix"), 'test meant for nt and posix') + def test_nt_and_posix_stack_size(self): try: thread.stack_size(4096) except ValueError: verbose_print("caught expected ValueError setting " "stack_size(4096)") except thread.error: - tss_supported = False - verbose_print("platform does not support changing thread stack " - "size") - - if tss_supported: - fail_msg = "stack_size(%d) failed - should succeed" - for tss in (262144, 0x100000, 0): - thread.stack_size(tss) - self.assertEqual(thread.stack_size(), tss, fail_msg % tss) - verbose_print("successfully set stack_size(%d)" % tss) - - for tss in (262144, 0x100000): - verbose_print("trying stack_size = (%d)" % tss) - self.next_ident = 0 - self.created = 0 - for i in range(NUMTASKS): - self.newtask() - - verbose_print("waiting for all tasks to complete") - self.done_mutex.acquire() - verbose_print("all tasks done") - - thread.stack_size(0) + self.skipTest("platform does not support changing thread stack " + "size") + + fail_msg = "stack_size(%d) failed - should succeed" + for tss in (262144, 0x100000, 0): + thread.stack_size(tss) + self.assertEqual(thread.stack_size(), tss, fail_msg % tss) + verbose_print("successfully set stack_size(%d)" % tss) + + for tss in (262144, 0x100000): + verbose_print("trying stack_size = (%d)" % tss) + self.next_ident = 0 + self.created = 0 + for i in range(NUMTASKS): + self.newtask() + + verbose_print("waiting for all tasks to complete") + self.done_mutex.acquire() + verbose_print("all tasks done") + + thread.stack_size(0) def test__count(self): # Test the _count() function. diff --git a/Lib/test/test_threaded_import.py b/Lib/test/test_threaded_import.py index 3d961b5ee28e..5bf670c81575 100644 --- a/Lib/test/test_threaded_import.py +++ b/Lib/test/test_threaded_import.py @@ -13,7 +13,8 @@ import shutil import unittest from test.support import ( - verbose, import_module, run_unittest, TESTFN, reap_threads, forget, unlink) + verbose, import_module, run_unittest, TESTFN, reap_threads, + forget, unlink, rmtree) threading = import_module('threading') def task(N, done, done_tasks, errors): @@ -57,7 +58,7 @@ def task(N, done, done_tasks, errors): } class Finder: - """A dummy finder to detect concurrent access to its find_module() + """A dummy finder to detect concurrent access to its find_spec() method.""" def __init__(self): @@ -65,8 +66,8 @@ def __init__(self): self.x = 0 self.lock = threading.Lock() - def find_module(self, name, path=None): - # Simulate some thread-unsafe behaviour. If calls to find_module() + def find_spec(self, name, path=None, target=None): + # Simulate some thread-unsafe behaviour. If calls to find_spec() # are properly serialized, `x` will end up the same as `numcalls`. # Otherwise not. assert imp.lock_held() @@ -80,7 +81,7 @@ class FlushingFinder: """A dummy finder which flushes sys.path_importer_cache when it gets called.""" - def find_module(self, name, path=None): + def find_spec(self, name, path=None, target=None): sys.path_importer_cache.clear() @@ -114,12 +115,18 @@ def check_parallel_module_init(self): errors = [] done_tasks = [] done.clear() + t0 = time.monotonic() for i in range(N): t = threading.Thread(target=task, args=(N, done, done_tasks, errors,)) t.start() - self.assertTrue(done.wait(60)) - self.assertFalse(errors) + completed = done.wait(10 * 60) + dt = time.monotonic() - t0 + if verbose: + print("%.1f ms" % (dt*1e3), flush=True, end=" ") + dbg_info = 'done: %s/%s' % (len(done_tasks), N) + self.assertFalse(errors, dbg_info) + self.assertTrue(completed, dbg_info) if verbose: print("OK.") @@ -145,13 +152,13 @@ def test_parallel_path_hooks(self): # dedicated meta_path entry. flushing_finder = FlushingFinder() def path_hook(path): - finder.find_module('') + finder.find_spec('') raise ImportError sys.path_hooks.insert(0, path_hook) sys.meta_path.append(flushing_finder) try: # Flush the cache a first time - flushing_finder.find_module('') + flushing_finder.find_spec('') numtests = self.check_parallel_module_init() self.assertGreater(finder.numcalls, 0) self.assertEqual(finder.x, finder.numcalls) @@ -222,6 +229,7 @@ def target(): f.write(code.encode('utf-8')) self.addCleanup(unlink, filename) self.addCleanup(forget, TESTFN) + self.addCleanup(rmtree, '__pycache__') importlib.invalidate_caches() __import__(TESTFN) diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py index a84577cc0f09..98f01ee42acf 100644 --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -3,20 +3,18 @@ """ import test.support -from test.support import verbose, strip_python_stderr, import_module -from test.script_helper import assert_python_ok +from test.support import verbose, strip_python_stderr, import_module, cpython_only +from test.script_helper import assert_python_ok, assert_python_failure import random import re import sys _thread = import_module('_thread') threading = import_module('threading') -import _testcapi import time import unittest import weakref import os -from test.script_helper import assert_python_ok, assert_python_failure import subprocess from test import lock_tests @@ -617,50 +615,45 @@ def test_BoundedSemaphore_limit(self): t.join() self.assertRaises(ValueError, bs.release) - def test_locals_at_exit(self): - # Issue #19466: thread locals must not be deleted before destructors - # are called - rc, out, err = assert_python_ok("-c", """if 1: - import threading - - class Atexit: - def __del__(self): - print("thread_dict.atexit = %r" % thread_dict.atexit) - - thread_dict = threading.local() - thread_dict.atexit = "atexit" - - atexit = Atexit() - """) - self.assertEqual(out.rstrip(), b"thread_dict.atexit = 'atexit'") - - def test_warnings_at_exit(self): - # Issue #19466: try to call most destructors at Python shutdown before - # destroying Python thread states - filename = __file__ - rc, out, err = assert_python_ok("-Wd", "-c", """if 1: - import time - import threading - - def open_sleep(): - # a warning will be emitted when the open file will be - # destroyed (without being explicitly closed) while the daemon - # thread is destroyed - fileobj = open(%a, 'rb') - start_event.set() - time.sleep(60.0) - - start_event = threading.Event() + @cpython_only + def test_frame_tstate_tracing(self): + # Issue #14432: Crash when a generator is created in a C thread that is + # destroyed while the generator is still used. The issue was that a + # generator contains a frame, and the frame kept a reference to the + # Python state of the destroyed C thread. The crash occurs when a trace + # function is setup. + + def noop_trace(frame, event, arg): + # no operation + return noop_trace + + def generator(): + while 1: + yield "genereator" + + def callback(): + if callback.gen is None: + callback.gen = generator() + return next(callback.gen) + callback.gen = None + + old_trace = sys.gettrace() + sys.settrace(noop_trace) + try: + # Install a trace function + threading.settrace(noop_trace) - thread = threading.Thread(target=open_sleep) - thread.daemon = True - thread.start() + # Create a generator in a C thread which exits after the call + import _testcapi + _testcapi.call_in_temporary_c_thread(callback) - # wait until the thread started - start_event.wait() - """ % filename) - self.assertRegex(err.rstrip(), - b"^sys:1: ResourceWarning: unclosed file ") + # Call the generator in a different Python thread, check that the + # generator didn't keep a reference to the destroyed thread state + for test in range(3): + # The trace function is still called here + callback() + finally: + sys.settrace(old_trace) class ThreadJoinOnShutdown(BaseTestCase): @@ -747,10 +740,6 @@ def test_4_daemon_threads(self): import sys import time import threading - import warnings - - # ignore "unclosed file ..." warnings - warnings.filterwarnings('ignore', '', ResourceWarning) thread_has_run = set() @@ -890,6 +879,7 @@ def f(): # The thread was joined properly. self.assertEqual(os.read(r, 1), b"x") + @cpython_only def test_daemon_threads_fatal_error(self): subinterp_code = r"""if 1: import os @@ -971,6 +961,88 @@ def outer(): self.assertEqual(p.returncode, 0, "Unexpected error: " + stderr.decode()) self.assertEqual(data, expected_output) + def test_print_exception(self): + script = r"""if True: + import threading + import time + + running = False + def run(): + global running + running = True + while running: + time.sleep(0.01) + 1/0 + t = threading.Thread(target=run) + t.start() + while not running: + time.sleep(0.01) + running = False + t.join() + """ + rc, out, err = assert_python_ok("-c", script) + self.assertEqual(out, b'') + err = err.decode() + self.assertIn("Exception in thread", err) + self.assertIn("Traceback (most recent call last):", err) + self.assertIn("ZeroDivisionError", err) + self.assertNotIn("Unhandled exception", err) + + def test_print_exception_stderr_is_none_1(self): + script = r"""if True: + import sys + import threading + import time + + running = False + def run(): + global running + running = True + while running: + time.sleep(0.01) + 1/0 + t = threading.Thread(target=run) + t.start() + while not running: + time.sleep(0.01) + sys.stderr = None + running = False + t.join() + """ + rc, out, err = assert_python_ok("-c", script) + self.assertEqual(out, b'') + err = err.decode() + self.assertIn("Exception in thread", err) + self.assertIn("Traceback (most recent call last):", err) + self.assertIn("ZeroDivisionError", err) + self.assertNotIn("Unhandled exception", err) + + def test_print_exception_stderr_is_none_2(self): + script = r"""if True: + import sys + import threading + import time + + running = False + def run(): + global running + running = True + while running: + time.sleep(0.01) + 1/0 + sys.stderr = None + t = threading.Thread(target=run) + t.start() + while not running: + time.sleep(0.01) + running = False + t.join() + """ + rc, out, err = assert_python_ok("-c", script) + self.assertEqual(out, b'') + self.assertNotIn("Unhandled exception", err.decode()) + + class TimerTests(BaseTestCase): def setUp(self): diff --git a/Lib/test/test_threadsignals.py b/Lib/test/test_threadsignals.py index b1004e668903..9d927423756e 100644 --- a/Lib/test/test_threadsignals.py +++ b/Lib/test/test_threadsignals.py @@ -74,6 +74,9 @@ def alarm_interrupt(self, sig, frame): @unittest.skipIf(USING_PTHREAD_COND, 'POSIX condition variables cannot be interrupted') + # Issue #20564: sem_timedwait() cannot be interrupted on OpenBSD + @unittest.skipIf(sys.platform.startswith('openbsd'), + 'lock cannot be interrupted on OpenBSD') def test_lock_acquire_interruption(self): # Mimic receiving a SIGINT (KeyboardInterrupt) with SIGALRM while stuck # in a deadlock. @@ -97,6 +100,9 @@ def test_lock_acquire_interruption(self): @unittest.skipIf(USING_PTHREAD_COND, 'POSIX condition variables cannot be interrupted') + # Issue #20564: sem_timedwait() cannot be interrupted on OpenBSD + @unittest.skipIf(sys.platform.startswith('openbsd'), + 'lock cannot be interrupted on OpenBSD') def test_rlock_acquire_interruption(self): # Mimic receiving a SIGINT (KeyboardInterrupt) with SIGALRM while stuck # in a deadlock. diff --git a/Lib/test/test_time.py b/Lib/test/test_time.py index 44bcb943cba9..be7ddcc34d6e 100644 --- a/Lib/test/test_time.py +++ b/Lib/test/test_time.py @@ -14,6 +14,8 @@ SIZEOF_INT = sysconfig.get_config_var('SIZEOF_INT') or 4 TIME_MAXYEAR = (1 << 8 * SIZEOF_INT - 1) - 1 TIME_MINYEAR = -TIME_MAXYEAR - 1 +_PyTime_ROUND_DOWN = 0 +_PyTime_ROUND_UP = 1 class TimeTestCase(unittest.TestCase): @@ -226,7 +228,7 @@ def test_ctime(self): self.assertEqual(time.ctime(t), 'Sun Sep 16 01:03:52 1973') t = time.mktime((2000, 1, 1, 0, 0, 0, 0, 0, -1)) self.assertEqual(time.ctime(t), 'Sat Jan 1 00:00:00 2000') - for year in [-100, 100, 1000, 2000, 10000]: + for year in [-100, 100, 1000, 2000, 2050, 10000]: try: testval = time.mktime((year, 1, 10) + (0,)*6) except (ValueError, OverflowError): @@ -344,6 +346,13 @@ def test_localtime_without_arg(self): def test_mktime(self): # Issue #1726687 for t in (-2, -1, 0, 1): + if sys.platform.startswith('aix') and t == -1: + # Issue #11188, #19748: mktime() returns -1 on error. On Linux, + # the tm_wday field is used as a sentinel () to detect if -1 is + # really an error or a valid timestamp. On AIX, tm_wday is + # unchanged even on success and so cannot be used as a + # sentinel. + continue try: tt = time.localtime(t) except (OverflowError, OSError): @@ -384,7 +393,8 @@ def test_monotonic(self): t2 = time.monotonic() dt = t2 - t1 self.assertGreater(t2, t1) - self.assertAlmostEqual(dt, 0.5, delta=0.2) + # Issue #20101: On some Windows machines, dt may be slightly low + self.assertTrue(0.45 <= dt <= 1.0, dt) # monotonic() is a monotonic but non adjustable clock info = time.get_clock_info('monotonic') @@ -472,8 +482,7 @@ def test_bug_3061(self): try: tmp = locale.setlocale(locale.LC_ALL, "fr_FR") except locale.Error: - # skip this test - return + self.skipTest('could not set locale.LC_ALL to fr_FR') # This should not cause an exception time.strftime("%B", (2009,2,1,0,0,0,0,0,0)) @@ -582,58 +591,119 @@ def setUp(self): -(2.0 ** 100.0), 2.0 ** 100.0, ) + @support.cpython_only def test_time_t(self): from _testcapi import pytime_object_to_time_t - for obj, time_t in ( - (0, 0), - (-1, -1), - (-1.0, -1), - (-1.9, -1), - (1.0, 1), - (1.9, 1), + for obj, time_t, rnd in ( + # Round towards zero + (0, 0, _PyTime_ROUND_DOWN), + (-1, -1, _PyTime_ROUND_DOWN), + (-1.0, -1, _PyTime_ROUND_DOWN), + (-1.9, -1, _PyTime_ROUND_DOWN), + (1.0, 1, _PyTime_ROUND_DOWN), + (1.9, 1, _PyTime_ROUND_DOWN), + # Round away from zero + (0, 0, _PyTime_ROUND_UP), + (-1, -1, _PyTime_ROUND_UP), + (-1.0, -1, _PyTime_ROUND_UP), + (-1.9, -2, _PyTime_ROUND_UP), + (1.0, 1, _PyTime_ROUND_UP), + (1.9, 2, _PyTime_ROUND_UP), ): - self.assertEqual(pytime_object_to_time_t(obj), time_t) + self.assertEqual(pytime_object_to_time_t(obj, rnd), time_t) + rnd = _PyTime_ROUND_DOWN for invalid in self.invalid_values: - self.assertRaises(OverflowError, pytime_object_to_time_t, invalid) + self.assertRaises(OverflowError, + pytime_object_to_time_t, invalid, rnd) + @support.cpython_only def test_timeval(self): from _testcapi import pytime_object_to_timeval - for obj, timeval in ( - (0, (0, 0)), - (-1, (-1, 0)), - (-1.0, (-1, 0)), - (1e-6, (0, 1)), - (-1e-6, (-1, 999999)), - (-1.2, (-2, 800000)), - (1.1234560, (1, 123456)), - (1.1234569, (1, 123456)), - (-1.1234560, (-2, 876544)), - (-1.1234561, (-2, 876543)), + for obj, timeval, rnd in ( + # Round towards zero + (0, (0, 0), _PyTime_ROUND_DOWN), + (-1, (-1, 0), _PyTime_ROUND_DOWN), + (-1.0, (-1, 0), _PyTime_ROUND_DOWN), + (1e-6, (0, 1), _PyTime_ROUND_DOWN), + (1e-7, (0, 0), _PyTime_ROUND_DOWN), + (-1e-6, (-1, 999999), _PyTime_ROUND_DOWN), + (-1e-7, (-1, 999999), _PyTime_ROUND_DOWN), + (-1.2, (-2, 800000), _PyTime_ROUND_DOWN), + (0.9999999, (0, 999999), _PyTime_ROUND_DOWN), + (0.0000041, (0, 4), _PyTime_ROUND_DOWN), + (1.1234560, (1, 123456), _PyTime_ROUND_DOWN), + (1.1234569, (1, 123456), _PyTime_ROUND_DOWN), + (-0.0000040, (-1, 999996), _PyTime_ROUND_DOWN), + (-0.0000041, (-1, 999995), _PyTime_ROUND_DOWN), + (-1.1234560, (-2, 876544), _PyTime_ROUND_DOWN), + (-1.1234561, (-2, 876543), _PyTime_ROUND_DOWN), + # Round away from zero + (0, (0, 0), _PyTime_ROUND_UP), + (-1, (-1, 0), _PyTime_ROUND_UP), + (-1.0, (-1, 0), _PyTime_ROUND_UP), + (1e-6, (0, 1), _PyTime_ROUND_UP), + (1e-7, (0, 1), _PyTime_ROUND_UP), + (-1e-6, (-1, 999999), _PyTime_ROUND_UP), + (-1e-7, (-1, 999999), _PyTime_ROUND_UP), + (-1.2, (-2, 800000), _PyTime_ROUND_UP), + (0.9999999, (1, 0), _PyTime_ROUND_UP), + (0.0000041, (0, 5), _PyTime_ROUND_UP), + (1.1234560, (1, 123457), _PyTime_ROUND_UP), + (1.1234569, (1, 123457), _PyTime_ROUND_UP), + (-0.0000040, (-1, 999996), _PyTime_ROUND_UP), + (-0.0000041, (-1, 999995), _PyTime_ROUND_UP), + (-1.1234560, (-2, 876544), _PyTime_ROUND_UP), + (-1.1234561, (-2, 876543), _PyTime_ROUND_UP), ): - self.assertEqual(pytime_object_to_timeval(obj), timeval) + with self.subTest(obj=obj, round=rnd, timeval=timeval): + self.assertEqual(pytime_object_to_timeval(obj, rnd), timeval) + rnd = _PyTime_ROUND_DOWN for invalid in self.invalid_values: - self.assertRaises(OverflowError, pytime_object_to_timeval, invalid) + self.assertRaises(OverflowError, + pytime_object_to_timeval, invalid, rnd) + @support.cpython_only def test_timespec(self): from _testcapi import pytime_object_to_timespec - for obj, timespec in ( - (0, (0, 0)), - (-1, (-1, 0)), - (-1.0, (-1, 0)), - (1e-9, (0, 1)), - (-1e-9, (-1, 999999999)), - (-1.2, (-2, 800000000)), - (1.1234567890, (1, 123456789)), - (1.1234567899, (1, 123456789)), - (-1.1234567890, (-2, 876543211)), - (-1.1234567891, (-2, 876543210)), + for obj, timespec, rnd in ( + # Round towards zero + (0, (0, 0), _PyTime_ROUND_DOWN), + (-1, (-1, 0), _PyTime_ROUND_DOWN), + (-1.0, (-1, 0), _PyTime_ROUND_DOWN), + (1e-9, (0, 1), _PyTime_ROUND_DOWN), + (1e-10, (0, 0), _PyTime_ROUND_DOWN), + (-1e-9, (-1, 999999999), _PyTime_ROUND_DOWN), + (-1e-10, (-1, 999999999), _PyTime_ROUND_DOWN), + (-1.2, (-2, 800000000), _PyTime_ROUND_DOWN), + (0.9999999999, (0, 999999999), _PyTime_ROUND_DOWN), + (1.1234567890, (1, 123456789), _PyTime_ROUND_DOWN), + (1.1234567899, (1, 123456789), _PyTime_ROUND_DOWN), + (-1.1234567890, (-2, 876543211), _PyTime_ROUND_DOWN), + (-1.1234567891, (-2, 876543210), _PyTime_ROUND_DOWN), + # Round away from zero + (0, (0, 0), _PyTime_ROUND_UP), + (-1, (-1, 0), _PyTime_ROUND_UP), + (-1.0, (-1, 0), _PyTime_ROUND_UP), + (1e-9, (0, 1), _PyTime_ROUND_UP), + (1e-10, (0, 1), _PyTime_ROUND_UP), + (-1e-9, (-1, 999999999), _PyTime_ROUND_UP), + (-1e-10, (-1, 999999999), _PyTime_ROUND_UP), + (-1.2, (-2, 800000000), _PyTime_ROUND_UP), + (0.9999999999, (1, 0), _PyTime_ROUND_UP), + (1.1234567890, (1, 123456790), _PyTime_ROUND_UP), + (1.1234567899, (1, 123456790), _PyTime_ROUND_UP), + (-1.1234567890, (-2, 876543211), _PyTime_ROUND_UP), + (-1.1234567891, (-2, 876543210), _PyTime_ROUND_UP), ): - self.assertEqual(pytime_object_to_timespec(obj), timespec) + with self.subTest(obj=obj, round=rnd, timespec=timespec): + self.assertEqual(pytime_object_to_timespec(obj, rnd), timespec) + rnd = _PyTime_ROUND_DOWN for invalid in self.invalid_values: - self.assertRaises(OverflowError, pytime_object_to_timespec, invalid) + self.assertRaises(OverflowError, + pytime_object_to_timespec, invalid, rnd) @unittest.skipUnless(time._STRUCT_TM_ITEMS == 11, "needs tm_zone support") def test_localtime_timezone(self): diff --git a/Lib/test/test_timeit.py b/Lib/test/test_timeit.py index 625fb8da90b5..267d2c80c90a 100644 --- a/Lib/test/test_timeit.py +++ b/Lib/test/test_timeit.py @@ -73,9 +73,21 @@ def test_reindent_multi(self): def test_timer_invalid_stmt(self): self.assertRaises(ValueError, timeit.Timer, stmt=None) + self.assertRaises(SyntaxError, timeit.Timer, stmt='return') + self.assertRaises(SyntaxError, timeit.Timer, stmt='yield') + self.assertRaises(SyntaxError, timeit.Timer, stmt='yield from ()') + self.assertRaises(SyntaxError, timeit.Timer, stmt='break') + self.assertRaises(SyntaxError, timeit.Timer, stmt='continue') + self.assertRaises(SyntaxError, timeit.Timer, stmt='from timeit import *') def test_timer_invalid_setup(self): self.assertRaises(ValueError, timeit.Timer, setup=None) + self.assertRaises(SyntaxError, timeit.Timer, setup='return') + self.assertRaises(SyntaxError, timeit.Timer, setup='yield') + self.assertRaises(SyntaxError, timeit.Timer, setup='yield from ()') + self.assertRaises(SyntaxError, timeit.Timer, setup='break') + self.assertRaises(SyntaxError, timeit.Timer, setup='continue') + self.assertRaises(SyntaxError, timeit.Timer, setup='from timeit import *') fake_setup = "import timeit; timeit._fake_timer.setup()" fake_stmt = "import timeit; timeit._fake_timer.inc()" @@ -86,9 +98,10 @@ def fake_callable_setup(self): def fake_callable_stmt(self): self.fake_timer.inc() - def timeit(self, stmt, setup, number=None): + def timeit(self, stmt, setup, number=None, globals=None): self.fake_timer = FakeTimer() - t = timeit.Timer(stmt=stmt, setup=setup, timer=self.fake_timer) + t = timeit.Timer(stmt=stmt, setup=setup, timer=self.fake_timer, + globals=globals) kwargs = {} if number is None: number = DEFAULT_NUMBER @@ -127,6 +140,17 @@ def test_timeit_function_zero_iters(self): timer=FakeTimer()) self.assertEqual(delta_time, 0) + def test_timeit_globals_args(self): + global _global_timer + _global_timer = FakeTimer() + t = timeit.Timer(stmt='_global_timer.inc()', timer=_global_timer) + self.assertRaises(NameError, t.timeit, number=3) + timeit.timeit(stmt='_global_timer.inc()', timer=_global_timer, + globals=globals(), number=3) + local_timer = FakeTimer() + timeit.timeit(stmt='local_timer.inc()', timer=local_timer, + globals=locals(), number=3) + def repeat(self, stmt, setup, repeat=None, number=None): self.fake_timer = FakeTimer() t = timeit.Timer(stmt=stmt, setup=setup, timer=self.fake_timer) diff --git a/Lib/test/test_timeout.py b/Lib/test/test_timeout.py index 703c43ab2bc7..3c75dcc6f922 100644 --- a/Lib/test/test_timeout.py +++ b/Lib/test/test_timeout.py @@ -243,14 +243,14 @@ def testRecvTimeout(self): def testAcceptTimeout(self): # Test accept() timeout support.bind_port(self.sock, self.localhost) - self.sock.listen(5) + self.sock.listen() self._sock_operation(1, 1.5, 'accept') def testSend(self): # Test send() timeout with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as serv: support.bind_port(serv, self.localhost) - serv.listen(5) + serv.listen() self.sock.connect(serv.getsockname()) # Send a lot of data in order to bypass buffering in the TCP stack. self._sock_operation(100, 1.5, 'send', b"X" * 200000) @@ -259,7 +259,7 @@ def testSendto(self): # Test sendto() timeout with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as serv: support.bind_port(serv, self.localhost) - serv.listen(5) + serv.listen() self.sock.connect(serv.getsockname()) # The address argument is ignored since we already connected. self._sock_operation(100, 1.5, 'sendto', b"X" * 200000, @@ -269,7 +269,7 @@ def testSendall(self): # Test sendall() timeout with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as serv: support.bind_port(serv, self.localhost) - serv.listen(5) + serv.listen() self.sock.connect(serv.getsockname()) # Send a lot of data in order to bypass buffering in the TCP stack. self._sock_operation(100, 1.5, 'sendall', b"X" * 200000) diff --git a/Lib/test/test_tk.py b/Lib/test/test_tk.py index 7551a7f4709c..62729f0f3249 100644 --- a/Lib/test/test_tk.py +++ b/Lib/test/test_tk.py @@ -6,20 +6,13 @@ support.import_fresh_module('tkinter') # Skip test if tk cannot be initialized. -from tkinter.test.support import check_tk_availability -check_tk_availability() +support.requires('gui') from tkinter.test import runtktests -def test_main(enable_gui=False): - if enable_gui: - if support.use_resources is None: - support.use_resources = ['gui'] - elif 'gui' not in support.use_resources: - support.use_resources.append('gui') - +def test_main(): support.run_unittest( *runtktests.get_tests(text=False, packages=['test_tkinter'])) if __name__ == '__main__': - test_main(enable_gui=True) + test_main() diff --git a/Lib/test/test_tokenize.py b/Lib/test/test_tokenize.py index 17650855eb33..8f74a06df586 100644 --- a/Lib/test/test_tokenize.py +++ b/Lib/test/test_tokenize.py @@ -2,7 +2,7 @@ Tests for the tokenize module. The tests can be really simple. Given a small fragment of source -code, print out a table with tokens. The ENDMARK is omitted for +code, print out a table with tokens. The ENDMARKER is omitted for brevity. >>> dump_tokens("1 + 1") @@ -464,7 +464,7 @@ Multiplicative - >>> dump_tokens("x = 1//1*1/5*12%0x12") + >>> dump_tokens("x = 1//1*1/5*12%0x12@42") ENCODING 'utf-8' (0, 0) (0, 0) NAME 'x' (1, 0) (1, 1) OP '=' (1, 2) (1, 3) @@ -479,6 +479,8 @@ NUMBER '12' (1, 13) (1, 15) OP '%' (1, 15) (1, 16) NUMBER '0x12' (1, 16) (1, 20) + OP '@' (1, 20) (1, 21) + NUMBER '42' (1, 21) (1, 23) Unary @@ -578,9 +580,15 @@ >>> tempdir = os.path.dirname(f) or os.curdir >>> testfiles = glob.glob(os.path.join(tempdir, "test*.py")) -tokenize is broken on test_pep3131.py because regular expressions are broken on -the obscure unicode identifiers in it. *sigh* +Tokenize is broken on test_pep3131.py because regular expressions are +broken on the obscure unicode identifiers in it. *sigh* +With roundtrip extended to test the 5-tuple mode of untokenize, +7 more testfiles fail. Remove them also until the failure is diagnosed. + >>> testfiles.remove(os.path.join(tempdir, "test_pep3131.py")) + >>> for f in ('buffer', 'builtin', 'fileio', 'inspect', 'os', 'platform', 'sys'): + ... testfiles.remove(os.path.join(tempdir, "test_%s.py") % f) + ... >>> if not support.is_resource_enabled("cpu"): ... testfiles = random.sample(testfiles, 10) ... @@ -638,7 +646,7 @@ from test import support from tokenize import (tokenize, _tokenize, untokenize, NUMBER, NAME, OP, STRING, ENDMARKER, ENCODING, tok_name, detect_encoding, - open as tokenize_open) + open as tokenize_open, Untokenizer) from io import BytesIO from unittest import TestCase import os, sys, glob @@ -659,21 +667,39 @@ def dump_tokens(s): def roundtrip(f): """ Test roundtrip for `untokenize`. `f` is an open file or a string. - The source code in f is tokenized, converted back to source code via - tokenize.untokenize(), and tokenized again from the latter. The test - fails if the second tokenization doesn't match the first. + The source code in f is tokenized to both 5- and 2-tuples. + Both sequences are converted back to source code via + tokenize.untokenize(), and the latter tokenized again to 2-tuples. + The test fails if the 3 pair tokenizations do not match. + + When untokenize bugs are fixed, untokenize with 5-tuples should + reproduce code that does not contain a backslash continuation + following spaces. A proper test should test this. + + This function would be more useful for correcting bugs if it reported + the first point of failure, like assertEqual, rather than just + returning False -- or if it were only used in unittests and not + doctest and actually used assertEqual. """ + # Get source code and original tokenizations if isinstance(f, str): - f = BytesIO(f.encode('utf-8')) - try: - token_list = list(tokenize(f.readline)) - finally: + code = f.encode('utf-8') + else: + code = f.read() f.close() - tokens1 = [tok[:2] for tok in token_list] - new_bytes = untokenize(tokens1) - readline = (line for line in new_bytes.splitlines(keepends=True)).__next__ - tokens2 = [tok[:2] for tok in tokenize(readline)] - return tokens1 == tokens2 + readline = iter(code.splitlines(keepends=True)).__next__ + tokens5 = list(tokenize(readline)) + tokens2 = [tok[:2] for tok in tokens5] + # Reproduce tokens2 from pairs + bytes_from2 = untokenize(tokens2) + readline2 = iter(bytes_from2.splitlines(keepends=True)).__next__ + tokens2_from2 = [tok[:2] for tok in tokenize(readline2)] + # Reproduce tokens2 from 5-tuples + bytes_from5 = untokenize(tokens5) + readline5 = iter(bytes_from5.splitlines(keepends=True)).__next__ + tokens2_from5 = [tok[:2] for tok in tokenize(readline5)] + # Compare 3 versions + return tokens2 == tokens2_from2 == tokens2_from5 # This is an example from the docs, set up as a doctest. def decistmt(s): @@ -885,6 +911,39 @@ def test_mismatched_bom_and_cookie_second_line_raises_syntaxerror(self): readline = self.get_readline(lines) self.assertRaises(SyntaxError, detect_encoding, readline) + def test_cookie_second_line_noncommented_first_line(self): + lines = ( + b"print('\xc2\xa3')\n", + b'# vim: set fileencoding=iso8859-15 :\n', + b"print('\xe2\x82\xac')\n" + ) + encoding, consumed_lines = detect_encoding(self.get_readline(lines)) + self.assertEqual(encoding, 'utf-8') + expected = [b"print('\xc2\xa3')\n"] + self.assertEqual(consumed_lines, expected) + + def test_cookie_second_line_commented_first_line(self): + lines = ( + b"#print('\xc2\xa3')\n", + b'# vim: set fileencoding=iso8859-15 :\n', + b"print('\xe2\x82\xac')\n" + ) + encoding, consumed_lines = detect_encoding(self.get_readline(lines)) + self.assertEqual(encoding, 'iso8859-15') + expected = [b"#print('\xc2\xa3')\n", b'# vim: set fileencoding=iso8859-15 :\n'] + self.assertEqual(consumed_lines, expected) + + def test_cookie_second_line_empty_first_line(self): + lines = ( + b'\n', + b'# vim: set fileencoding=iso8859-15 :\n', + b"print('\xe2\x82\xac')\n" + ) + encoding, consumed_lines = detect_encoding(self.get_readline(lines)) + self.assertEqual(encoding, 'iso8859-15') + expected = [b'\n', b'# vim: set fileencoding=iso8859-15 :\n'] + self.assertEqual(consumed_lines, expected) + def test_latin1_normalization(self): # See get_normal_name() in tokenizer.c. encodings = ("latin-1", "iso-8859-1", "iso-latin-1", "latin-1-unix", @@ -1097,6 +1156,7 @@ def test_exact_type(self): self.assertExactTypeEqual('//', token.DOUBLESLASH) self.assertExactTypeEqual('//=', token.DOUBLESLASHEQUAL) self.assertExactTypeEqual('@', token.AT) + self.assertExactTypeEqual('@=', token.ATEQUAL) self.assertExactTypeEqual('a**2+b**2==c**2', NAME, token.DOUBLESTAR, NUMBER, @@ -1120,6 +1180,47 @@ def test_pathological_trailing_whitespace(self): # See http://bugs.python.org/issue16152 self.assertExactTypeEqual('@ ', token.AT) +class UntokenizeTest(TestCase): + + def test_bad_input_order(self): + # raise if previous row + u = Untokenizer() + u.prev_row = 2 + u.prev_col = 2 + with self.assertRaises(ValueError) as cm: + u.add_whitespace((1,3)) + self.assertEqual(cm.exception.args[0], + 'start (1,3) precedes previous end (2,2)') + # raise if previous column in row + self.assertRaises(ValueError, u.add_whitespace, (2,1)) + + def test_backslash_continuation(self): + # The problem is that \ leaves no token + u = Untokenizer() + u.prev_row = 1 + u.prev_col = 1 + u.tokens = [] + u.add_whitespace((2, 0)) + self.assertEqual(u.tokens, ['\\\n']) + u.prev_row = 2 + u.add_whitespace((4, 4)) + self.assertEqual(u.tokens, ['\\\n', '\\\n\\\n', ' ']) + self.assertTrue(roundtrip('a\n b\n c\n \\\n c\n')) + + def test_iter_compat(self): + u = Untokenizer() + token = (NAME, 'Hello') + tokens = [(ENCODING, 'utf-8'), token] + u.compat(token, iter([])) + self.assertEqual(u.tokens, ["Hello "]) + u = Untokenizer() + self.assertEqual(u.untokenize(iter([token])), 'Hello ') + u = Untokenizer() + self.assertEqual(u.untokenize(iter(tokens)), 'Hello ') + self.assertEqual(u.encoding, 'utf-8') + self.assertEqual(untokenize(iter(tokens)), b'Hello ') + + __test__ = {"doctests" : doctests, 'decistmt': decistmt} def test_main(): @@ -1129,6 +1230,7 @@ def test_main(): support.run_unittest(Test_Tokenize) support.run_unittest(TestDetectEncoding) support.run_unittest(TestTokenize) + support.run_unittest(UntokenizeTest) if __name__ == "__main__": test_main() diff --git a/Lib/test/test_tools/__init__.py b/Lib/test/test_tools/__init__.py new file mode 100644 index 000000000000..04c8726e1117 --- /dev/null +++ b/Lib/test/test_tools/__init__.py @@ -0,0 +1,25 @@ +"""Support functions for testing scripts in the Tools directory.""" +import os +import unittest +import importlib +from test import support +from fnmatch import fnmatch + +basepath = os.path.dirname( # + os.path.dirname( # Lib + os.path.dirname( # test + os.path.dirname(__file__)))) # test_tools + +toolsdir = os.path.join(basepath, 'Tools') +scriptsdir = os.path.join(toolsdir, 'scripts') + +def skip_if_missing(): + if not os.path.isdir(scriptsdir): + raise unittest.SkipTest('scripts directory could not be found') + +def import_tool(toolname): + with support.DirsOnSysPath(scriptsdir): + return importlib.import_module(toolname) + +def load_tests(*args): + return support.load_package_tests(os.path.dirname(__file__), *args) diff --git a/Lib/test/test_tools/__main__.py b/Lib/test/test_tools/__main__.py new file mode 100644 index 000000000000..b6f13e534edb --- /dev/null +++ b/Lib/test/test_tools/__main__.py @@ -0,0 +1,4 @@ +from test.test_tools import load_tests +import unittest + +unittest.main() diff --git a/Lib/test/test_tools/test_gprof2html.py b/Lib/test/test_tools/test_gprof2html.py new file mode 100644 index 000000000000..845a2a8cfa90 --- /dev/null +++ b/Lib/test/test_tools/test_gprof2html.py @@ -0,0 +1,36 @@ +"""Tests for the gprof2html script in the Tools directory.""" + +import os +import sys +import importlib +import unittest +from unittest import mock +import tempfile + +from test.test_tools import scriptsdir, skip_if_missing, import_tool + +skip_if_missing() + +class Gprof2htmlTests(unittest.TestCase): + + def setUp(self): + self.gprof = import_tool('gprof2html') + oldargv = sys.argv + def fixup(): + sys.argv = oldargv + self.addCleanup(fixup) + sys.argv = [] + + def test_gprof(self): + # Issue #14508: this used to fail with an NameError. + with mock.patch.object(self.gprof, 'webbrowser') as wmock, \ + tempfile.TemporaryDirectory() as tmpdir: + fn = os.path.join(tmpdir, 'abc') + open(fn, 'w').close() + sys.argv = ['gprof2html', fn] + self.gprof.main() + self.assertTrue(wmock.open.called) + + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_tools/test_md5sum.py b/Lib/test/test_tools/test_md5sum.py new file mode 100644 index 000000000000..59ea149238e4 --- /dev/null +++ b/Lib/test/test_tools/test_md5sum.py @@ -0,0 +1,77 @@ +"""Tests for the md5sum script in the Tools directory.""" + +import os +import sys +import unittest +from test import support +from test.script_helper import assert_python_ok, assert_python_failure + +from test.test_tools import scriptsdir, import_tool, skip_if_missing + +skip_if_missing() + +class MD5SumTests(unittest.TestCase): + @classmethod + def setUpClass(cls): + cls.script = os.path.join(scriptsdir, 'md5sum.py') + os.mkdir(support.TESTFN) + cls.fodder = os.path.join(support.TESTFN, 'md5sum.fodder') + with open(cls.fodder, 'wb') as f: + f.write(b'md5sum\r\ntest file\r\n') + cls.fodder_md5 = b'd38dae2eb1ab346a292ef6850f9e1a0d' + cls.fodder_textmode_md5 = b'a8b07894e2ca3f2a4c3094065fa6e0a5' + + @classmethod + def tearDownClass(cls): + support.rmtree(support.TESTFN) + + def test_noargs(self): + rc, out, err = assert_python_ok(self.script) + self.assertEqual(rc, 0) + self.assertTrue( + out.startswith(b'd41d8cd98f00b204e9800998ecf8427e ')) + self.assertFalse(err) + + def test_checksum_fodder(self): + rc, out, err = assert_python_ok(self.script, self.fodder) + self.assertEqual(rc, 0) + self.assertTrue(out.startswith(self.fodder_md5)) + for part in self.fodder.split(os.path.sep): + self.assertIn(part.encode(), out) + self.assertFalse(err) + + def test_dash_l(self): + rc, out, err = assert_python_ok(self.script, '-l', self.fodder) + self.assertEqual(rc, 0) + self.assertIn(self.fodder_md5, out) + parts = self.fodder.split(os.path.sep) + self.assertIn(parts[-1].encode(), out) + self.assertNotIn(parts[-2].encode(), out) + + def test_dash_t(self): + rc, out, err = assert_python_ok(self.script, '-t', self.fodder) + self.assertEqual(rc, 0) + self.assertTrue(out.startswith(self.fodder_textmode_md5)) + self.assertNotIn(self.fodder_md5, out) + + def test_dash_s(self): + rc, out, err = assert_python_ok(self.script, '-s', '512', self.fodder) + self.assertEqual(rc, 0) + self.assertIn(self.fodder_md5, out) + + def test_multiple_files(self): + rc, out, err = assert_python_ok(self.script, self.fodder, self.fodder) + self.assertEqual(rc, 0) + lines = out.splitlines() + self.assertEqual(len(lines), 2) + self.assertEqual(*lines) + + def test_usage(self): + rc, out, err = assert_python_failure(self.script, '-h') + self.assertEqual(rc, 2) + self.assertEqual(out, b'') + self.assertGreater(err, b'') + + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_tools/test_pdeps.py b/Lib/test/test_tools/test_pdeps.py new file mode 100644 index 000000000000..091fa6a06dff --- /dev/null +++ b/Lib/test/test_tools/test_pdeps.py @@ -0,0 +1,34 @@ +"""Tests for the pdeps script in the Tools directory.""" + +import os +import sys +import unittest +import tempfile +from test import support + +from test.test_tools import scriptsdir, skip_if_missing, import_tool + +skip_if_missing() + + +class PdepsTests(unittest.TestCase): + + @classmethod + def setUpClass(self): + self.pdeps = import_tool('pdeps') + + def test_process_errors(self): + # Issue #14492: m_import.match(line) can be None. + with tempfile.TemporaryDirectory() as tmpdir: + fn = os.path.join(tmpdir, 'foo') + with open(fn, 'w') as stream: + stream.write("#!/this/will/fail") + self.pdeps.process(fn, {}) + + def test_inverse_attribute_error(self): + # Issue #14492: this used to fail with an AttributeError. + self.pdeps.inverse({'a': []}) + + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_tools.py b/Lib/test/test_tools/test_pindent.py similarity index 65% rename from Lib/test/test_tools.py rename to Lib/test/test_tools/test_pindent.py index f97151589936..14a0aa270f11 100644 --- a/Lib/test/test_tools.py +++ b/Lib/test/test_tools/test_pindent.py @@ -1,42 +1,16 @@ -"""Tests for scripts in the Tools directory. - -This file contains regression tests for some of the scripts found in the -Tools directory of a Python checkout or tarball, such as reindent.py. -""" +"""Tests for the pindent script in the Tools directory.""" import os import sys -import importlib.machinery import unittest -from unittest import mock -import shutil import subprocess -import sysconfig -import tempfile import textwrap from test import support -from test.script_helper import assert_python_ok, temp_dir - -if not sysconfig.is_python_build(): - # XXX some installers do contain the tools, should we detect that - # and run the tests in that case too? - raise unittest.SkipTest('test irrelevant for an installed Python') - -basepath = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), - 'Tools') -scriptsdir = os.path.join(basepath, 'scripts') - +from test.script_helper import assert_python_ok -class ReindentTests(unittest.TestCase): - script = os.path.join(scriptsdir, 'reindent.py') +from test.test_tools import scriptsdir, skip_if_missing - def test_noargs(self): - assert_python_ok(self.script) - - def test_help(self): - rc, out, err = assert_python_ok(self.script, '-h') - self.assertEqual(out, b'') - self.assertGreater(err, b'') +skip_if_missing() class PindentTests(unittest.TestCase): @@ -60,7 +34,7 @@ def lstriplines(self, data): def test_selftest(self): self.maxDiff = None - with temp_dir() as directory: + with support.temp_dir() as directory: data_path = os.path.join(directory, '_test.py') with open(self.script) as f: closed = f.read() @@ -361,104 +335,5 @@ def test_oneline(self): self.pindent_test(clean, closed) -class TestSundryScripts(unittest.TestCase): - # At least make sure the rest don't have syntax errors. When tests are - # added for a script it should be added to the whitelist below. - - # scripts that have independent tests. - whitelist = ['reindent.py', 'pdeps.py', 'gprof2html'] - # scripts that can't be imported without running - blacklist = ['make_ctype.py'] - # scripts that use windows-only modules - windows_only = ['win_add2path.py'] - # blacklisted for other reasons - other = ['analyze_dxp.py'] - - skiplist = blacklist + whitelist + windows_only + other - - def setUp(self): - cm = support.DirsOnSysPath(scriptsdir) - cm.__enter__() - self.addCleanup(cm.__exit__) - - def test_sundry(self): - for fn in os.listdir(scriptsdir): - if fn.endswith('.py') and fn not in self.skiplist: - __import__(fn[:-3]) - - @unittest.skipIf(sys.platform != "win32", "Windows-only test") - def test_sundry_windows(self): - for fn in self.windows_only: - __import__(fn[:-3]) - - @unittest.skipIf(not support.threading, "test requires _thread module") - def test_analyze_dxp_import(self): - if hasattr(sys, 'getdxp'): - import analyze_dxp - else: - with self.assertRaises(RuntimeError): - import analyze_dxp - - -class PdepsTests(unittest.TestCase): - - @classmethod - def setUpClass(self): - path = os.path.join(scriptsdir, 'pdeps.py') - loader = importlib.machinery.SourceFileLoader('pdeps', path) - self.pdeps = loader.load_module() - - @classmethod - def tearDownClass(self): - if 'pdeps' in sys.modules: - del sys.modules['pdeps'] - - def test_process_errors(self): - # Issue #14492: m_import.match(line) can be None. - with tempfile.TemporaryDirectory() as tmpdir: - fn = os.path.join(tmpdir, 'foo') - with open(fn, 'w') as stream: - stream.write("#!/this/will/fail") - self.pdeps.process(fn, {}) - - def test_inverse_attribute_error(self): - # Issue #14492: this used to fail with an AttributeError. - self.pdeps.inverse({'a': []}) - - -class Gprof2htmlTests(unittest.TestCase): - - def setUp(self): - path = os.path.join(scriptsdir, 'gprof2html.py') - loader = importlib.machinery.SourceFileLoader('gprof2html', path) - self.gprof = loader.load_module() - oldargv = sys.argv - def fixup(): - sys.argv = oldargv - self.addCleanup(fixup) - sys.argv = [] - - def test_gprof(self): - # Issue #14508: this used to fail with an NameError. - with mock.patch.object(self.gprof, 'webbrowser') as wmock, \ - tempfile.TemporaryDirectory() as tmpdir: - fn = os.path.join(tmpdir, 'abc') - open(fn, 'w').close() - sys.argv = ['gprof2html', fn] - self.gprof.main() - self.assertTrue(wmock.open.called) - - -# Run the tests in Tools/parser/test_unparse.py -with support.DirsOnSysPath(os.path.join(basepath, 'parser')): - from test_unparse import UnparseTestCase - from test_unparse import DirectoryTestCase - - -def test_main(): - support.run_unittest(*[obj for obj in globals().values() - if isinstance(obj, type)]) - - if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_tools/test_reindent.py b/Lib/test/test_tools/test_reindent.py new file mode 100644 index 000000000000..45cebf728869 --- /dev/null +++ b/Lib/test/test_tools/test_reindent.py @@ -0,0 +1,28 @@ +"""Tests for scripts in the Tools directory. + +This file contains regression tests for some of the scripts found in the +Tools directory of a Python checkout or tarball, such as reindent.py. +""" + +import os +import unittest +from test.script_helper import assert_python_ok + +from test.test_tools import scriptsdir, skip_if_missing + +skip_if_missing() + +class ReindentTests(unittest.TestCase): + script = os.path.join(scriptsdir, 'reindent.py') + + def test_noargs(self): + assert_python_ok(self.script) + + def test_help(self): + rc, out, err = assert_python_ok(self.script, '-h') + self.assertEqual(out, b'') + self.assertGreater(err, b'') + + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_tools/test_sundry.py b/Lib/test/test_tools/test_sundry.py new file mode 100644 index 000000000000..39e541b45bd2 --- /dev/null +++ b/Lib/test/test_tools/test_sundry.py @@ -0,0 +1,53 @@ +"""Tests for scripts in the Tools directory. + +This file contains extremely basic regression tests for the scripts found in +the Tools directory of a Python checkout or tarball which don't have separate +tests of their own, such as h2py.py. +""" + +import os +import sys +import unittest +from test import support + +from test.test_tools import scriptsdir, import_tool, skip_if_missing + +skip_if_missing() + +class TestSundryScripts(unittest.TestCase): + # At least make sure the rest don't have syntax errors. When tests are + # added for a script it should be added to the whitelist below. + + # scripts that have independent tests. + whitelist = ['reindent', 'pdeps', 'gprof2html', 'md5sum'] + # scripts that can't be imported without running + blacklist = ['make_ctype'] + # scripts that use windows-only modules + windows_only = ['win_add2path'] + # blacklisted for other reasons + other = ['analyze_dxp'] + + skiplist = blacklist + whitelist + windows_only + other + + def test_sundry(self): + for fn in os.listdir(scriptsdir): + name = fn[:-3] + if fn.endswith('.py') and name not in self.skiplist: + import_tool(name) + + @unittest.skipIf(sys.platform != "win32", "Windows-only test") + def test_sundry_windows(self): + for name in self.windows_only: + import_tool(name) + + @unittest.skipIf(not support.threading, "test requires _thread module") + def test_analyze_dxp_import(self): + if hasattr(sys, 'getdxp'): + import_tool('analyze_dxp') + else: + with self.assertRaises(RuntimeError): + import_tool('analyze_dxp') + + +if __name__ == '__main__': + unittest.main() diff --git a/Tools/parser/test_unparse.py b/Lib/test/test_tools/test_unparse.py similarity index 95% rename from Tools/parser/test_unparse.py rename to Lib/test/test_tools/test_unparse.py index be84400c38ff..976a6c59ae10 100644 --- a/Tools/parser/test_unparse.py +++ b/Lib/test/test_tools/test_unparse.py @@ -1,12 +1,22 @@ +"""Tests for the unparse.py script in the Tools/parser directory.""" + import unittest import test.support import io import os import random import tokenize -import unparse import ast +from test.test_tools import basepath, toolsdir, skip_if_missing + +skip_if_missing() + +parser_path = os.path.join(toolsdir, "parser") + +with test.support.DirsOnSysPath(parser_path): + import unparse + def read_pyfile(filename): """Read and return the contents of a Python source file (as a string), taking into account the file encoding.""" @@ -249,11 +259,10 @@ class DirectoryTestCase(ASTTestCase): def test_files(self): # get names of files to test - dist_dir = os.path.join(os.path.dirname(__file__), os.pardir, os.pardir) names = [] for d in self.test_directories: - test_dir = os.path.join(dist_dir, d) + test_dir = os.path.join(basepath, d) for n in os.listdir(test_dir): if n.endswith('.py') and not n.startswith('bad'): names.append(os.path.join(test_dir, n)) @@ -269,8 +278,5 @@ def test_files(self): self.check_roundtrip(source) -def test_main(): - test.support.run_unittest(UnparseTestCase, DirectoryTestCase) - if __name__ == '__main__': - test_main() + unittest.main() diff --git a/Lib/test/test_trace.py b/Lib/test/test_trace.py index 1cec710ee580..05bf274ca8ac 100644 --- a/Lib/test/test_trace.py +++ b/Lib/test/test_trace.py @@ -10,7 +10,6 @@ from test.tracedmodules import testmod - #------------------------------- Utilities -----------------------------------# def fix_ext_py(filename): @@ -224,6 +223,11 @@ def setUp(self): self.addCleanup(sys.settrace, sys.gettrace()) self.tracer = Trace(count=0, trace=0, countfuncs=1) self.filemod = my_file_and_modname() + self._saved_tracefunc = sys.gettrace() + + def tearDown(self): + if self._saved_tracefunc is not None: + sys.settrace(self._saved_tracefunc) def test_simple_caller(self): self.tracer.runfunc(traced_func_simple_caller, 1) diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py index 96ef951139eb..6bd6fa630330 100644 --- a/Lib/test/test_traceback.py +++ b/Lib/test/test_traceback.py @@ -1,12 +1,13 @@ """Test cases for traceback module""" -from _testcapi import traceback_print, exception_print from io import StringIO import sys import unittest import re from test.support import run_unittest, Error, captured_output -from test.support import TESTFN, unlink +from test.support import TESTFN, unlink, cpython_only +from test.script_helper import assert_python_ok +import textwrap import traceback @@ -32,6 +33,12 @@ def syntax_error_with_caret_2(self): def syntax_error_bad_indentation(self): compile("def spam():\n print(1)\n print(2)", "?", "exec") + def syntax_error_with_caret_non_ascii(self): + compile('Python = "\u1e54\xfd\u0163\u0125\xf2\xf1" +', "?", "exec") + + def syntax_error_bad_indentation2(self): + compile(" print(2)", "?", "exec") + def test_caret(self): err = self.get_exception_format(self.syntax_error_with_caret, SyntaxError) @@ -43,8 +50,14 @@ def test_caret(self): err = self.get_exception_format(self.syntax_error_with_caret_2, SyntaxError) self.assertIn("^", err[2]) # third line has caret - self.assertTrue(err[2].count('\n') == 1) # and no additional newline - self.assertTrue(err[1].find("+") == err[2].find("^")) # in the right place + self.assertEqual(err[2].count('\n'), 1) # and no additional newline + self.assertEqual(err[1].find("+"), err[2].find("^")) # in the right place + + err = self.get_exception_format(self.syntax_error_with_caret_non_ascii, + SyntaxError) + self.assertIn("^", err[2]) # third line has caret + self.assertEqual(err[2].count('\n'), 1) # and no additional newline + self.assertEqual(err[1].find("+"), err[2].find("^")) # in the right place def test_nocaret(self): exc = SyntaxError("error", ("x.py", 23, None, "bad syntax")) @@ -60,6 +73,13 @@ def test_bad_indentation(self): self.assertIn("^", err[2]) self.assertEqual(err[1].find(")"), err[2].find("^")) + err = self.get_exception_format(self.syntax_error_bad_indentation2, + IndentationError) + self.assertEqual(len(err), 4) + self.assertEqual(err[1].strip(), "print(2)") + self.assertIn("^", err[2]) + self.assertEqual(err[1].find("p"), err[2].find("^")) + def test_base_exception(self): # Test that exceptions derived from BaseException are formatted right e = KeyboardInterrupt() @@ -74,9 +94,9 @@ def __str__(self): self.assertEqual(len(err), 1) str_value = '' % X.__name__ if X.__module__ in ('__main__', 'builtins'): - str_name = X.__name__ + str_name = X.__qualname__ else: - str_name = '.'.join([X.__module__, X.__name__]) + str_name = '.'.join([X.__module__, X.__qualname__]) self.assertEqual(err[0], "%s: %s\n" % (str_name, str_value)) def test_without_exception(self): @@ -146,6 +166,41 @@ def do_test(firstlines, message, charset, lineno): text, charset, 4) do_test("#!shebang\n# coding: {0}\n".format(charset), text, charset, 5) + do_test(" \t\f\n# coding: {0}\n".format(charset), + text, charset, 5) + # Issue #18960: coding spec should has no effect + do_test("0\n# coding: GBK\n", "h\xe9 ho", 'utf-8', 5) + + def test_print_traceback_at_exit(self): + # Issue #22599: Ensure that it is possible to use the traceback module + # to display an exception at Python exit + code = textwrap.dedent(""" + import sys + import traceback + + class PrintExceptionAtExit(object): + def __init__(self): + try: + x = 1 / 0 + except Exception: + self.exc_info = sys.exc_info() + # self.exc_info[1] (traceback) contains frames: + # explicitly clear the reference to self in the current + # frame to break a reference cycle + self = None + + def __del__(self): + traceback.print_exception(*self.exc_info) + + # Keep a reference in the module namespace to call the destructor + # when the module is unloaded + obj = PrintExceptionAtExit() + """) + rc, stdout, stderr = assert_python_ok('-c', code) + expected = [b'Traceback (most recent call last):', + b' File "", line 8, in __init__', + b'ZeroDivisionError: division by zero'] + self.assertEqual(stderr.splitlines(), expected) class TracebackFormatTests(unittest.TestCase): @@ -153,7 +208,9 @@ class TracebackFormatTests(unittest.TestCase): def some_exception(self): raise KeyError('blah') + @cpython_only def check_traceback_format(self, cleanup_func=None): + from _testcapi import traceback_print try: self.some_exception() except KeyError: @@ -381,7 +438,9 @@ class CExcReportingTests(BaseExceptionReportingTests, unittest.TestCase): # This checks built-in reporting by the interpreter. # + @cpython_only def get_report(self, e): + from _testcapi import exception_print e = self.get_exception(e) with captured_output("stderr") as s: exception_print(e) diff --git a/Lib/test/test_tracemalloc.py b/Lib/test/test_tracemalloc.py index 484e313a1a97..19d3fd8dda88 100644 --- a/Lib/test/test_tracemalloc.py +++ b/Lib/test/test_tracemalloc.py @@ -5,7 +5,7 @@ import unittest from unittest.mock import patch from test.script_helper import assert_python_ok, assert_python_failure -from test import support +from test import script_helper, support try: import threading except ImportError: @@ -123,7 +123,6 @@ def test_set_traceback_limit(self): self.assertEqual(len(traceback), 1) self.assertEqual(traceback, obj_traceback) - def find_trace(self, traces, traceback): for trace in traces: if trace[1] == traceback._frames: @@ -147,7 +146,6 @@ def test_get_traces(self): tracemalloc.stop() self.assertEqual(tracemalloc._get_traces(), []) - def test_get_traces_intern_traceback(self): # dummy wrappers to get more useful and identical frames in the traceback def allocate_bytes2(size): @@ -348,6 +346,8 @@ def test_filter_traces(self): self.assertIsNot(snapshot5.traces, snapshot.traces) self.assertEqual(snapshot5.traces, snapshot.traces) + self.assertRaises(TypeError, snapshot.filter_traces, filter1) + def test_snapshot_group_by_line(self): snapshot, snapshot2 = create_snapshots() tb_0 = traceback_lineno('', 0) @@ -503,6 +503,34 @@ def test_statistic_diff_format(self): self.assertEqual(str(stat), 'a.py:5: size=5002 B (+5000 B), count=2 (+1), average=2501 B') + def test_slices(self): + snapshot, snapshot2 = create_snapshots() + self.assertEqual(snapshot.traces[:2], + (snapshot.traces[0], snapshot.traces[1])) + + traceback = snapshot.traces[0].traceback + self.assertEqual(traceback[:2], + (traceback[0], traceback[1])) + + def test_format_traceback(self): + snapshot, snapshot2 = create_snapshots() + def getline(filename, lineno): + return ' <%s, %s>' % (filename, lineno) + with unittest.mock.patch('tracemalloc.linecache.getline', + side_effect=getline): + tb = snapshot.traces[0].traceback + self.assertEqual(tb.format(), + [' File "a.py", line 2', + ' ', + ' File "b.py", line 4', + ' ']) + + self.assertEqual(tb.format(limit=1), + [' File "a.py", line 2', + ' ']) + + self.assertEqual(tb.format(limit=-1), + []) class TestFilters(unittest.TestCase): @@ -720,26 +748,30 @@ def test_filter_match_trace(self): class TestCommandLine(unittest.TestCase): - def test_env_var(self): + def test_env_var_disabled_by_default(self): # not tracing by default code = 'import tracemalloc; print(tracemalloc.is_tracing())' ok, stdout, stderr = assert_python_ok('-c', code) stdout = stdout.rstrip() self.assertEqual(stdout, b'False') - # PYTHON* environment variables must be ignored when -E option is - # present + @unittest.skipIf(script_helper.interpreter_requires_environment(), + 'Cannot run -E tests when PYTHON env vars are required.') + def test_env_var_ignored_with_E(self): + """PYTHON* environment variables must be ignored when -E is present.""" code = 'import tracemalloc; print(tracemalloc.is_tracing())' ok, stdout, stderr = assert_python_ok('-E', '-c', code, PYTHONTRACEMALLOC='1') stdout = stdout.rstrip() self.assertEqual(stdout, b'False') + def test_env_var_enabled_at_startup(self): # tracing at startup code = 'import tracemalloc; print(tracemalloc.is_tracing())' ok, stdout, stderr = assert_python_ok('-c', code, PYTHONTRACEMALLOC='1') stdout = stdout.rstrip() self.assertEqual(stdout, b'True') + def test_env_limit(self): # start and set the number of frames code = 'import tracemalloc; print(tracemalloc.get_traceback_limit())' ok, stdout, stderr = assert_python_ok('-c', code, PYTHONTRACEMALLOC='10') @@ -779,6 +811,12 @@ def test_sys_xoptions_invalid(self): b'number of frames', stderr) + def test_pymem_alloc0(self): + # Issue #21639: Check that PyMem_Malloc(0) with tracemalloc enabled + # does not crash. + code = 'import _testcapi; _testcapi.test_pymem_alloc0(); 1' + assert_python_ok('-X', 'tracemalloc', '-c', code) + def test_main(): support.run_unittest( diff --git a/Lib/test/test_ttk_guionly.py b/Lib/test/test_ttk_guionly.py index 3a3459bdd2e1..fcdedac34dc6 100644 --- a/Lib/test/test_ttk_guionly.py +++ b/Lib/test/test_ttk_guionly.py @@ -6,35 +6,32 @@ support.import_module('_tkinter') # Make sure tkinter._fix runs to set up the environment -support.import_fresh_module('tkinter') +tkinter = support.import_fresh_module('tkinter') # Skip test if tk cannot be initialized. -from tkinter.test.support import check_tk_availability -check_tk_availability() +support.requires('gui') from _tkinter import TclError from tkinter import ttk from tkinter.test import runtktests -from tkinter.test.support import get_tk_root +root = None try: - ttk.Button() + root = tkinter.Tk() + button = ttk.Button(root) + button.destroy() + del button except TclError as msg: # assuming ttk is not available raise unittest.SkipTest("ttk not available: %s" % msg) +finally: + if root is not None: + root.destroy() + del root -def test_main(enable_gui=False): - if enable_gui: - if support.use_resources is None: - support.use_resources = ['gui'] - elif 'gui' not in support.use_resources: - support.use_resources.append('gui') - - try: - support.run_unittest( - *runtktests.get_tests(text=False, packages=['test_ttk'])) - finally: - get_tk_root().destroy() +def test_main(): + support.run_unittest( + *runtktests.get_tests(text=False, packages=['test_ttk'])) if __name__ == '__main__': - test_main(enable_gui=True) + test_main() diff --git a/Lib/test/test_tuple.py b/Lib/test/test_tuple.py index e41711c8e69e..d711116e37f6 100644 --- a/Lib/test/test_tuple.py +++ b/Lib/test/test_tuple.py @@ -6,6 +6,11 @@ class TupleTest(seq_tests.CommonTest): type2test = tuple + def test_getitem_error(self): + msg = "tuple indices must be integers or slices" + with self.assertRaisesRegex(TypeError, msg): + ()['a'] + def test_constructors(self): super().test_constructors() # calling built-in types without argument must return empty @@ -169,29 +174,31 @@ def test_iterator_pickle(self): # Userlist iterators don't support pickling yet since # they are based on generators. data = self.type2test([4, 5, 6, 7]) - itorg = iter(data) - d = pickle.dumps(itorg) - it = pickle.loads(d) - self.assertEqual(type(itorg), type(it)) - self.assertEqual(self.type2test(it), self.type2test(data)) - - it = pickle.loads(d) - next(it) - d = pickle.dumps(it) - self.assertEqual(self.type2test(it), self.type2test(data)[1:]) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + itorg = iter(data) + d = pickle.dumps(itorg, proto) + it = pickle.loads(d) + self.assertEqual(type(itorg), type(it)) + self.assertEqual(self.type2test(it), self.type2test(data)) + + it = pickle.loads(d) + next(it) + d = pickle.dumps(it, proto) + self.assertEqual(self.type2test(it), self.type2test(data)[1:]) def test_reversed_pickle(self): data = self.type2test([4, 5, 6, 7]) - itorg = reversed(data) - d = pickle.dumps(itorg) - it = pickle.loads(d) - self.assertEqual(type(itorg), type(it)) - self.assertEqual(self.type2test(it), self.type2test(reversed(data))) - - it = pickle.loads(d) - next(it) - d = pickle.dumps(it) - self.assertEqual(self.type2test(it), self.type2test(reversed(data))[1:]) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + itorg = reversed(data) + d = pickle.dumps(itorg, proto) + it = pickle.loads(d) + self.assertEqual(type(itorg), type(it)) + self.assertEqual(self.type2test(it), self.type2test(reversed(data))) + + it = pickle.loads(d) + next(it) + d = pickle.dumps(it, proto) + self.assertEqual(self.type2test(it), self.type2test(reversed(data))[1:]) def test_no_comdat_folding(self): # Issue 8847: In the PGO build, the MSVC linker's COMDAT folding @@ -201,6 +208,14 @@ class T(tuple): pass with self.assertRaises(TypeError): [3,] + T((1,2)) + def test_lexicographic_ordering(self): + # Issue 21100 + a = self.type2test([1, 2]) + b = self.type2test([1, 2, 0]) + c = self.type2test([1, 3]) + self.assertLess(a, b) + self.assertLess(b, c) + def test_main(): support.run_unittest(TupleTest) diff --git a/Lib/test/test_types.py b/Lib/test/test_types.py index ec10752e6a2a..11d95465a813 100644 --- a/Lib/test/test_types.py +++ b/Lib/test/test_types.py @@ -343,6 +343,8 @@ def test(i, format_spec, result): self.assertRaises(ValueError, 3 .__format__, ",n") # can't have ',' with 'c' self.assertRaises(ValueError, 3 .__format__, ",c") + # can't have '#' with 'c' + self.assertRaises(ValueError, 3 .__format__, "#c") # ensure that only int and float type specifiers work for format_spec in ([chr(x) for x in range(ord('a'), ord('z')+1)] + diff --git a/Lib/test/test_ucn.py b/Lib/test/test_ucn.py index 59bde7475aea..1e07f6629f88 100644 --- a/Lib/test/test_ucn.py +++ b/Lib/test/test_ucn.py @@ -9,12 +9,16 @@ import unittest import unicodedata -import _testcapi from test import support from http.client import HTTPException from test.test_normalization import check_version +try: + from _testcapi import INT_MAX, PY_SSIZE_T_MAX, UINT_MAX +except ImportError: + INT_MAX = PY_SSIZE_T_MAX = UINT_MAX = 2**64 - 1 + class UnicodeNamesTest(unittest.TestCase): def checkletter(self, name, code): @@ -168,7 +172,7 @@ def test_named_sequences_sample(self): def test_named_sequences_full(self): # Check all the named sequences - url = ("http://www.unicode.org/Public/%s/ucd/NamedSequences.txt" % + url = ("http://www.pythontest.net/unicode/%s/NamedSequences.txt" % unicodedata.unidata_version) try: testdata = support.open_urlresource(url, encoding="utf-8", @@ -216,15 +220,13 @@ def test_strict_error_handling(self): str, b"\\NSPACE", 'unicode-escape', 'strict' ) - @unittest.skipUnless(_testcapi.INT_MAX < _testcapi.PY_SSIZE_T_MAX, - "needs UINT_MAX < SIZE_MAX") - @support.bigmemtest(size=_testcapi.UINT_MAX + 1, - memuse=2 + 1, dry_run=False) + @support.cpython_only + @unittest.skipUnless(INT_MAX < PY_SSIZE_T_MAX, "needs UINT_MAX < SIZE_MAX") + @support.bigmemtest(size=UINT_MAX + 1, memuse=2 + 1, dry_run=False) def test_issue16335(self, size): # very very long bogus character name - x = b'\\N{SPACE' + b'x' * (_testcapi.UINT_MAX + 1) + b'}' - self.assertEqual(len(x), len(b'\\N{SPACE}') + - (_testcapi.UINT_MAX + 1)) + x = b'\\N{SPACE' + b'x' * (UINT_MAX + 1) + b'}' + self.assertEqual(len(x), len(b'\\N{SPACE}') + (UINT_MAX + 1)) self.assertRaisesRegex(UnicodeError, 'unknown Unicode character name', x.decode, 'unicode-escape' diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py index 575c4a58507b..e4cd99b06f65 100644 --- a/Lib/test/test_unicode.py +++ b/Lib/test/test_unicode.py @@ -8,6 +8,7 @@ import _string import codecs import itertools +import operator import struct import sys import unittest @@ -250,6 +251,7 @@ def test_maketrans_translate(self): {ord('a'): None, ord('b'): ''}) self.checkequalnofix('xyyx', 'xzx', 'translate', {ord('z'): 'yy'}) + # this needs maketrans() self.checkequalnofix('abababc', 'abababc', 'translate', {'b': ''}) @@ -259,6 +261,33 @@ def test_maketrans_translate(self): tbl = self.type2test.maketrans('abc', 'xyz', 'd') self.checkequalnofix('xyzzy', 'abdcdcbdddd', 'translate', tbl) + # various tests switching from ASCII to latin1 or the opposite; + # same length, remove a letter, or replace with a longer string. + self.assertEqual("[a]".translate(str.maketrans('a', 'X')), + "[X]") + self.assertEqual("[a]".translate(str.maketrans({'a': 'X'})), + "[X]") + self.assertEqual("[a]".translate(str.maketrans({'a': None})), + "[]") + self.assertEqual("[a]".translate(str.maketrans({'a': 'XXX'})), + "[XXX]") + self.assertEqual("[a]".translate(str.maketrans({'a': '\xe9'})), + "[\xe9]") + self.assertEqual("[a]".translate(str.maketrans({'a': '<\xe9>'})), + "[<\xe9>]") + self.assertEqual("[\xe9]".translate(str.maketrans({'\xe9': 'a'})), + "[a]") + self.assertEqual("[\xe9]".translate(str.maketrans({'\xe9': None})), + "[]") + + # invalid Unicode characters + invalid_char = 0x10ffff+1 + for before in "a\xe9\u20ac\U0010ffff": + mapping = str.maketrans({before: invalid_char}) + text = "[%s]" % before + self.assertRaises(ValueError, text.translate, mapping) + + # errors self.assertRaises(TypeError, self.type2test.maketrans) self.assertRaises(ValueError, self.type2test.maketrans, 'abc', 'defg') self.assertRaises(TypeError, self.type2test.maketrans, 2, 'def') @@ -672,6 +701,12 @@ def test_center(self): self.assertEqual('x'.center(4, '\U0010FFFF'), '\U0010FFFFx\U0010FFFF\U0010FFFF') + @unittest.skipUnless(sys.maxsize == 2**31 - 1, "requires 32-bit system") + @support.cpython_only + def test_case_operation_overflow(self): + # Issue #22643 + self.assertRaises(OverflowError, ("ü"*(2**32//12 + 1)).upper) + def test_contains(self): # Testing Unicode contains method self.assertIn('a', 'abdb') @@ -845,6 +880,27 @@ def __format__(self, format_spec): self.assertEqual('{0:10000}'.format(''), ' ' * 10000) self.assertEqual('{0:10000000}'.format(''), ' ' * 10000000) + # issue 12546: use \x00 as a fill character + self.assertEqual('{0:\x00<6s}'.format('foo'), 'foo\x00\x00\x00') + self.assertEqual('{0:\x01<6s}'.format('foo'), 'foo\x01\x01\x01') + self.assertEqual('{0:\x00^6s}'.format('foo'), '\x00foo\x00\x00') + self.assertEqual('{0:^6s}'.format('foo'), ' foo ') + + self.assertEqual('{0:\x00<6}'.format(3), '3\x00\x00\x00\x00\x00') + self.assertEqual('{0:\x01<6}'.format(3), '3\x01\x01\x01\x01\x01') + self.assertEqual('{0:\x00^6}'.format(3), '\x00\x003\x00\x00\x00') + self.assertEqual('{0:<6}'.format(3), '3 ') + + self.assertEqual('{0:\x00<6}'.format(3.14), '3.14\x00\x00') + self.assertEqual('{0:\x01<6}'.format(3.14), '3.14\x01\x01') + self.assertEqual('{0:\x00^6}'.format(3.14), '\x003.14\x00') + self.assertEqual('{0:^6}'.format(3.14), ' 3.14 ') + + self.assertEqual('{0:\x00<12}'.format(3+2.0j), '(3+2j)\x00\x00\x00\x00\x00\x00') + self.assertEqual('{0:\x01<12}'.format(3+2.0j), '(3+2j)\x01\x01\x01\x01\x01\x01') + self.assertEqual('{0:\x00^12}'.format(3+2.0j), '\x00\x00\x00(3+2j)\x00\x00\x00') + self.assertEqual('{0:^12}'.format(3+2.0j), ' (3+2j) ') + # format specifiers for user defined type self.assertEqual('{0:abc}'.format(C()), 'abc') @@ -1126,6 +1182,35 @@ def __str__(self): self.assertEqual('%.1s' % "a\xe9\u20ac", 'a') self.assertEqual('%.2s' % "a\xe9\u20ac", 'a\xe9') + #issue 19995 + class PseudoInt: + def __init__(self, value): + self.value = int(value) + def __int__(self): + return self.value + def __index__(self): + return self.value + class PseudoFloat: + def __init__(self, value): + self.value = float(value) + def __int__(self): + return int(self.value) + pi = PseudoFloat(3.1415) + letter_m = PseudoInt(109) + self.assertEqual('%x' % 42, '2a') + self.assertEqual('%X' % 15, 'F') + self.assertEqual('%o' % 9, '11') + self.assertEqual('%c' % 109, 'm') + self.assertEqual('%x' % letter_m, '6d') + self.assertEqual('%X' % letter_m, '6D') + self.assertEqual('%o' % letter_m, '155') + self.assertEqual('%c' % letter_m, 'm') + self.assertRaisesRegex(TypeError, '%x format: an integer is required, not float', operator.mod, '%x', 3.14), + self.assertRaisesRegex(TypeError, '%X format: an integer is required, not float', operator.mod, '%X', 2.11), + self.assertRaisesRegex(TypeError, '%o format: an integer is required, not float', operator.mod, '%o', 1.79), + self.assertRaisesRegex(TypeError, '%x format: an integer is required, not PseudoFloat', operator.mod, '%x', pi), + self.assertRaises(TypeError, operator.mod, '%c', pi), + def test_formatting_with_enum(self): # issue18780 import enum @@ -1158,8 +1243,13 @@ class Str(str, enum.Enum): self.assertEqual('...%(foo)f...' % {'foo':Float.PI,'def':123}, '...3.141593...') - @support.cpython_only def test_formatting_huge_precision(self): + format_string = "%.{}f".format(sys.maxsize + 1) + with self.assertRaises(ValueError): + result = format_string % 2.34 + + @support.cpython_only + def test_formatting_huge_precision_c_limits(self): from _testcapi import INT_MAX format_string = "%.{}f".format(INT_MAX + 1) with self.assertRaises(ValueError): @@ -1380,9 +1470,9 @@ def test_utf8_decode_valid_sequences(self): def test_utf8_decode_invalid_sequences(self): # continuation bytes in a sequence of 2, 3, or 4 bytes continuation_bytes = [bytes([x]) for x in range(0x80, 0xC0)] - # start bytes of a 2-byte sequence equivalent to codepoints < 0x7F + # start bytes of a 2-byte sequence equivalent to code points < 0x7F invalid_2B_seq_start_bytes = [bytes([x]) for x in range(0xC0, 0xC2)] - # start bytes of a 4-byte sequence equivalent to codepoints > 0x10FFFF + # start bytes of a 4-byte sequence equivalent to code points > 0x10FFFF invalid_4B_seq_start_bytes = [bytes([x]) for x in range(0xF5, 0xF8)] invalid_start_bytes = ( continuation_bytes + invalid_2B_seq_start_bytes + @@ -2002,12 +2092,12 @@ def test_printable_repr(self): self.assertEqual(repr('\U00010000'), "'%c'" % (0x10000,)) # printable self.assertEqual(repr('\U00014000'), "'\\U00014000'") # nonprintable + # This test only affects 32-bit platforms because expandtabs can only take + # an int as the max value, not a 64-bit C long. If expandtabs is changed + # to take a 64-bit long, this test should apply to all platforms. + @unittest.skipIf(sys.maxsize > (1 << 32) or struct.calcsize('P') != 4, + 'only applies to 32-bit platforms') def test_expandtabs_overflows_gracefully(self): - # This test only affects 32-bit platforms because expandtabs can only take - # an int as the max value, not a 64-bit C long. If expandtabs is changed - # to take a 64-bit long, this test should apply to all platforms. - if sys.maxsize > (1 << 32) or struct.calcsize('P') != 4: - return self.assertRaises(OverflowError, 't\tt\t'.expandtabs, sys.maxsize) @support.cpython_only @@ -2286,6 +2376,7 @@ def check_format(expected, format, *args): b'%.%s', b'abc') # Test PyUnicode_AsWideChar() + @support.cpython_only def test_aswidechar(self): from _testcapi import unicode_aswidechar support.import_module('ctypes') @@ -2323,6 +2414,7 @@ def test_aswidechar(self): self.assertEqual(wchar, nonbmp + '\0') # Test PyUnicode_AsWideCharString() + @support.cpython_only def test_aswidecharstring(self): from _testcapi import unicode_aswidecharstring support.import_module('ctypes') @@ -2357,6 +2449,7 @@ def __iadd__(self, o): s += "4" self.assertEqual(s, "3") + @support.cpython_only def test_encode_decimal(self): from _testcapi import unicode_encodedecimal self.assertEqual(unicode_encodedecimal('123'), @@ -2372,6 +2465,7 @@ def test_encode_decimal(self): "^'decimal' codec can't encode character", unicode_encodedecimal, "123\u20ac", "replace") + @support.cpython_only def test_transform_decimal(self): from _testcapi import unicode_transformdecimaltoascii as transform_decimal self.assertEqual(transform_decimal('123'), diff --git a/Lib/test/test_unicodedata.py b/Lib/test/test_unicodedata.py index 707b30e50c0d..f8788a058876 100644 --- a/Lib/test/test_unicodedata.py +++ b/Lib/test/test_unicodedata.py @@ -21,7 +21,7 @@ class UnicodeMethodsTest(unittest.TestCase): # update this, if the database changes - expectedchecksum = 'e74e878de71b6e780ffac271785c3cb58f6251f3' + expectedchecksum = '618e2c1a22ee79d2235319709f16c50f987ee21f' def test_method_checksum(self): h = hashlib.sha1() @@ -79,8 +79,9 @@ def tearDown(self): class UnicodeFunctionsTest(UnicodeDatabaseTest): - # update this, if the database changes - expectedchecksum = 'f0b74d26776331cc7bdc3a4698f037d73f2cee2b' + # Update this if the database changes. Make sure to do a full rebuild + # (e.g. 'make distclean && make') to get the correct checksum. + expectedchecksum = '585302895deead0c1c8478c51da9241d4efedca9' def test_function_checksum(self): data = [] h = hashlib.sha1() diff --git a/Lib/test/test_urllib.py b/Lib/test/test_urllib.py index 94f640b923c9..fcd20738f8a3 100644 --- a/Lib/test/test_urllib.py +++ b/Lib/test/test_urllib.py @@ -7,8 +7,13 @@ import email.message import io import unittest +from unittest.mock import patch from test import support import os +try: + import ssl +except ImportError: + ssl = None import sys import tempfile from nturl2path import url2pathname, pathname2url @@ -47,48 +52,73 @@ def urlopen(url, data=None, proxies=None): return opener.open(url, data) -class FakeHTTPMixin(object): - def fakehttp(self, fakedata): - class FakeSocket(io.BytesIO): - io_refs = 1 +def fakehttp(fakedata): + class FakeSocket(io.BytesIO): + io_refs = 1 - def sendall(self, data): - FakeHTTPConnection.buf = data + def sendall(self, data): + FakeHTTPConnection.buf = data - def makefile(self, *args, **kwds): - self.io_refs += 1 - return self + def makefile(self, *args, **kwds): + self.io_refs += 1 + return self - def read(self, amt=None): - if self.closed: - return b"" - return io.BytesIO.read(self, amt) + def read(self, amt=None): + if self.closed: + return b"" + return io.BytesIO.read(self, amt) - def readline(self, length=None): - if self.closed: - return b"" - return io.BytesIO.readline(self, length) + def readline(self, length=None): + if self.closed: + return b"" + return io.BytesIO.readline(self, length) - def close(self): - self.io_refs -= 1 - if self.io_refs == 0: - io.BytesIO.close(self) + def close(self): + self.io_refs -= 1 + if self.io_refs == 0: + io.BytesIO.close(self) + + class FakeHTTPConnection(http.client.HTTPConnection): + + # buffer to store data for verification in urlopen tests. + buf = None + fakesock = FakeSocket(fakedata) - class FakeHTTPConnection(http.client.HTTPConnection): + def connect(self): + self.sock = self.fakesock - # buffer to store data for verification in urlopen tests. - buf = None + return FakeHTTPConnection - def connect(self): - self.sock = FakeSocket(fakedata) +class FakeHTTPMixin(object): + def fakehttp(self, fakedata): self._connection_class = http.client.HTTPConnection - http.client.HTTPConnection = FakeHTTPConnection + http.client.HTTPConnection = fakehttp(fakedata) def unfakehttp(self): http.client.HTTPConnection = self._connection_class +class FakeFTPMixin(object): + def fakeftp(self): + class FakeFtpWrapper(object): + def __init__(self, user, passwd, host, port, dirs, timeout=None, + persistent=True): + pass + + def retrfile(self, file, type): + return io.BytesIO(), 0 + + def close(self): + pass + + self._ftpwrapper_class = urllib.request.ftpwrapper + urllib.request.ftpwrapper = FakeFtpWrapper + + def unfakeftp(self): + urllib.request.ftpwrapper = self._ftpwrapper_class + + class urlopen_FileTests(unittest.TestCase): """Test urlopen() opening a temporary file. @@ -195,7 +225,7 @@ def test_getproxies_environment_keep_no_proxies(self): self.env.set('NO_PROXY', 'localhost, anotherdomain.com, newdomain.com') self.assertTrue(urllib.request.proxy_bypass_environment('anotherdomain.com')) -class urlopen_HttpTests(unittest.TestCase, FakeHTTPMixin): +class urlopen_HttpTests(unittest.TestCase, FakeHTTPMixin, FakeFTPMixin): """Test urlopen() opening a fake http connection.""" def check_read(self, ver): @@ -309,6 +339,15 @@ def test_ftp_nonexisting(self): self.assertFalse(e.exception.filename) self.assertTrue(e.exception.reason) + @patch.object(urllib.request, 'MAXFTPCACHE', 0) + def test_ftp_cache_pruning(self): + self.fakeftp() + try: + urllib.request.ftpcache['test'] = urllib.request.ftpwrapper('user', 'pass', 'localhost', 21, []) + urlopen('ftp://localhost') + finally: + self.unfakeftp() + def test_userpass_inurl(self): self.fakehttp(b"HTTP/1.0 200 OK\r\n\r\nHello!") @@ -344,6 +383,14 @@ def test_URLopener_deprecation(self): with support.check_warnings(('',DeprecationWarning)): urllib.request.URLopener() + @unittest.skipUnless(ssl, "ssl module required") + def test_cafile_and_context(self): + context = ssl.create_default_context() + with self.assertRaises(ValueError): + urllib.request.urlopen( + "https://localhost", cafile="/nonexistent/path", context=context + ) + class urlopen_DataTests(unittest.TestCase): """Test urlopen() opening a data URL.""" @@ -1303,7 +1350,7 @@ def open_spam(self, url): # serv.settimeout(3) # serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # serv.bind(("", 9093)) -# serv.listen(5) +# serv.listen() # try: # conn, addr = serv.accept() # conn.send("1 Hola mundo\n") @@ -1340,7 +1387,7 @@ def open_spam(self, url): # def testTimeoutNone(self): # # global default timeout is ignored # import socket -# self.assertTrue(socket.getdefaulttimeout() is None) +# self.assertIsNone(socket.getdefaulttimeout()) # socket.setdefaulttimeout(30) # try: # ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, []) @@ -1352,7 +1399,7 @@ def open_spam(self, url): # def testTimeoutDefault(self): # # global default timeout is used # import socket -# self.assertTrue(socket.getdefaulttimeout() is None) +# self.assertIsNone(socket.getdefaulttimeout()) # socket.setdefaulttimeout(30) # try: # ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, []) diff --git a/Lib/test/test_urllib2.py b/Lib/test/test_urllib2.py index dbd1c60ec24b..3182390c4274 100644 --- a/Lib/test/test_urllib2.py +++ b/Lib/test/test_urllib2.py @@ -1,5 +1,6 @@ import unittest from test import support +from test import test_urllib import os import io @@ -10,9 +11,10 @@ import urllib.request # The proxy bypass method imported below has logic specific to the OSX # proxy config data structure but is testable on all platforms. -from urllib.request import Request, OpenerDirector, _proxy_bypass_macosx_sysconf +from urllib.request import Request, OpenerDirector, _parse_proxy, _proxy_bypass_macosx_sysconf from urllib.parse import urlparse import urllib.error +import http.client # XXX # Request @@ -42,7 +44,7 @@ def test_trivial(self): self.assertRaises(ValueError, urllib.request.urlopen, 'bogus url') # XXX Name hacking to get this to work on Windows. - fname = os.path.abspath(urllib.request.__file__).replace('\\', '/') + fname = os.path.abspath(urllib.request.__file__).replace(os.sep, '/') if os.name == 'nt': file_url = "file:///%s" % fname @@ -603,8 +605,8 @@ def test_processors(self): self.assertIsInstance(args[0], Request) # response from opener.open is None, because there's no # handler that defines http_open to handle it - self.assertTrue(args[1] is None or - isinstance(args[1], MockResponse)) + if args[1] is not None: + self.assertIsInstance(args[1], MockResponse) def sanepathname2url(path): try: @@ -678,7 +680,7 @@ def connect_ftp(self, user, passwd, host, port, dirs, self.assertEqual(int(headers["Content-length"]), len(data)) def test_file(self): - import email.utils, socket + import email.utils h = urllib.request.FileHandler() o = h.parent = MockOpener() @@ -725,6 +727,7 @@ def test_file(self): for url in [ "file://localhost:80%s" % urlpath, "file:///file_does_not_exist.txt", + "file://not-a-local-host.com//dir/file.txt", "file://%s:80%s/%s" % (socket.gethostbyname('localhost'), os.getcwd(), TESTFN), "file://somerandomhost.ontheinternet.com%s/%s" % @@ -1018,7 +1021,8 @@ def test_redirect(self): MockHeaders({"location": to_url})) except urllib.error.HTTPError: # 307 in response to POST requires user OK - self.assertTrue(code == 307 and data is not None) + self.assertEqual(code, 307) + self.assertIsNotNone(data) self.assertEqual(o.req.get_full_url(), to_url) try: self.assertEqual(o.req.get_method(), "GET") @@ -1226,7 +1230,8 @@ def test_osx_proxy_bypass(self): self.assertTrue(_proxy_bypass_macosx_sysconf(host, bypass), 'expected bypass of %s to be True' % host) # Check hosts that should not trigger the proxy bypass - for host in ('abc.foo.bar', 'bar.com', '127.0.0.2', '10.11.0.1', 'test'): + for host in ('abc.foo.bar', 'bar.com', '127.0.0.2', '10.11.0.1', + 'notinbypass'): self.assertFalse(_proxy_bypass_macosx_sysconf(host, bypass), 'expected bypass of %s to be False' % host) @@ -1390,6 +1395,48 @@ def _test_basic_auth(self, opener, auth_handler, auth_header, self.assertEqual(len(http_handler.requests), 1) self.assertFalse(http_handler.requests[0].has_header(auth_header)) + def test_http_closed(self): + """Test the connection is cleaned up when the response is closed""" + for (transfer, data) in ( + ("Connection: close", b"data"), + ("Transfer-Encoding: chunked", b"4\r\ndata\r\n0\r\n\r\n"), + ("Content-Length: 4", b"data"), + ): + header = "HTTP/1.1 200 OK\r\n{}\r\n\r\n".format(transfer) + conn = test_urllib.fakehttp(header.encode() + data) + handler = urllib.request.AbstractHTTPHandler() + req = Request("http://dummy/") + req.timeout = None + with handler.do_open(conn, req) as resp: + resp.read() + self.assertTrue(conn.fakesock.closed, + "Connection not closed with {!r}".format(transfer)) + + def test_invalid_closed(self): + """Test the connection is cleaned up after an invalid response""" + conn = test_urllib.fakehttp(b"") + handler = urllib.request.AbstractHTTPHandler() + req = Request("http://dummy/") + req.timeout = None + with self.assertRaises(http.client.BadStatusLine): + handler.do_open(conn, req) + self.assertTrue(conn.fakesock.closed, "Connection not closed") + + def test_auth_prior_handler(self): + pwd_manager = MockPasswordManager() + pwd_manager.add_password(None, 'https://example.com', + 'somebody', 'verysecret') + auth_prior_handler = urllib.request.HTTPBasicPriorAuthHandler( + pwd_manager) + http_hand = MockHTTPSHandler() + + opener = OpenerDirector() + opener.add_handler(http_hand) + opener.add_handler(auth_prior_handler) + + req = Request("https://example.com") + opener.open(req) + self.assertNotIn('Authorization', http_hand.httpconn.req_headers) class MiscTests(unittest.TestCase): @@ -1438,7 +1485,7 @@ class MyOtherHTTPHandler(urllib.request.HTTPHandler): pass 'test requires network access') def test_issue16464(self): opener = urllib.request.build_opener() - request = urllib.request.Request("http://www.python.org/~jeremy/") + request = urllib.request.Request("http://www.example.com/") self.assertEqual(None, request.data) opener.open(request, "1".encode("us-ascii")) @@ -1465,6 +1512,43 @@ def test_HTTPError_interface(self): expected_errmsg = 'HTTP Error %s: %s' % (err.code, err.msg) self.assertEqual(str(err), expected_errmsg) + def test_parse_proxy(self): + parse_proxy_test_cases = [ + ('proxy.example.com', + (None, None, None, 'proxy.example.com')), + ('proxy.example.com:3128', + (None, None, None, 'proxy.example.com:3128')), + ('proxy.example.com', (None, None, None, 'proxy.example.com')), + ('proxy.example.com:3128', + (None, None, None, 'proxy.example.com:3128')), + # The authority component may optionally include userinfo + # (assumed to be # username:password): + ('joe:password@proxy.example.com', + (None, 'joe', 'password', 'proxy.example.com')), + ('joe:password@proxy.example.com:3128', + (None, 'joe', 'password', 'proxy.example.com:3128')), + #Examples with URLS + ('http://proxy.example.com/', + ('http', None, None, 'proxy.example.com')), + ('http://proxy.example.com:3128/', + ('http', None, None, 'proxy.example.com:3128')), + ('http://joe:password@proxy.example.com/', + ('http', 'joe', 'password', 'proxy.example.com')), + ('http://joe:password@proxy.example.com:3128', + ('http', 'joe', 'password', 'proxy.example.com:3128')), + # Everything after the authority is ignored + ('ftp://joe:password@proxy.example.com/rubbish:3128', + ('ftp', 'joe', 'password', 'proxy.example.com')), + # Test for no trailing '/' case + ('http://joe:password@proxy.example.com', + ('http', 'joe', 'password', 'proxy.example.com')) + ] + + for tc, expected in parse_proxy_test_cases: + self.assertEqual(_parse_proxy(tc), expected) + + self.assertRaises(ValueError, _parse_proxy, 'file:/ftp.example.com'), + class RequestTests(unittest.TestCase): class PutRequest(Request): method='PUT' diff --git a/Lib/test/test_urllib2_localnet.py b/Lib/test/test_urllib2_localnet.py index 08250c36e5d6..0650aa274431 100644 --- a/Lib/test/test_urllib2_localnet.py +++ b/Lib/test/test_urllib2_localnet.py @@ -1,5 +1,4 @@ -#!/usr/bin/env python3 - +import base64 import os import email import urllib.parse @@ -7,8 +6,11 @@ import http.server import unittest import hashlib + from test import support + threading = support.import_module('threading') + try: import ssl except ImportError: @@ -59,14 +61,11 @@ def __init__(self, request_handler): request_handler.protocol_version = "HTTP/1.0" self.httpd = LoopbackHttpServer(("127.0.0.1", 0), request_handler) - #print "Serving HTTP on %s port %s" % (self.httpd.server_name, - # self.httpd.server_port) self.port = self.httpd.server_port def stop(self): """Stops the webserver if it's currently running.""" - # Set the stop flag. self._stop_server = True self.join() @@ -199,6 +198,49 @@ def handle_request(self, request_handler): return self._return_auth_challenge(request_handler) return True + +class BasicAuthHandler(http.server.BaseHTTPRequestHandler): + """Handler for performing basic authentication.""" + # Server side values + USER = 'testUser' + PASSWD = 'testPass' + REALM = 'Test' + USER_PASSWD = "%s:%s" % (USER, PASSWD) + ENCODED_AUTH = base64.b64encode(USER_PASSWD.encode('ascii')).decode('ascii') + + def __init__(self, *args, **kwargs): + http.server.BaseHTTPRequestHandler.__init__(self, *args, **kwargs) + + def log_message(self, format, *args): + # Suppress console log message + pass + + def do_HEAD(self): + self.send_response(200) + self.send_header("Content-type", "text/html") + self.end_headers() + + def do_AUTHHEAD(self): + self.send_response(401) + self.send_header("WWW-Authenticate", "Basic realm=\"%s\"" % self.REALM) + self.send_header("Content-type", "text/html") + self.end_headers() + + def do_GET(self): + if not self.headers.get("Authorization", ""): + self.do_AUTHHEAD() + self.wfile.write(b"No Auth header received") + elif self.headers.get( + "Authorization", "") == "Basic " + self.ENCODED_AUTH: + self.send_response(200) + self.end_headers() + self.wfile.write(b"It works") + else: + # Request Unauthorized + self.do_AUTHHEAD() + + + # Proxy test infrastructure class FakeProxyHandler(http.server.BaseHTTPRequestHandler): @@ -234,6 +276,44 @@ def do_GET(self): # Test cases +@unittest.skipUnless(threading, "Threading required for this test.") +class BasicAuthTests(unittest.TestCase): + USER = "testUser" + PASSWD = "testPass" + INCORRECT_PASSWD = "Incorrect" + REALM = "Test" + + def setUp(self): + super(BasicAuthTests, self).setUp() + # With Basic Authentication + def http_server_with_basic_auth_handler(*args, **kwargs): + return BasicAuthHandler(*args, **kwargs) + self.server = LoopbackHttpServerThread(http_server_with_basic_auth_handler) + self.server_url = 'http://127.0.0.1:%s' % self.server.port + self.server.start() + self.server.ready.wait() + + def tearDown(self): + self.server.stop() + super(BasicAuthTests, self).tearDown() + + def test_basic_auth_success(self): + ah = urllib.request.HTTPBasicAuthHandler() + ah.add_password(self.REALM, self.server_url, self.USER, self.PASSWD) + urllib.request.install_opener(urllib.request.build_opener(ah)) + try: + self.assertTrue(urllib.request.urlopen(self.server_url)) + except urllib.error.HTTPError: + self.fail("Basic auth failed for the url: %s", self.server_url) + + def test_basic_auth_httperror(self): + ah = urllib.request.HTTPBasicAuthHandler() + ah.add_password(self.REALM, self.server_url, self.USER, self.INCORRECT_PASSWD) + urllib.request.install_opener(urllib.request.build_opener(ah)) + self.assertRaises(urllib.error.HTTPError, urllib.request.urlopen, self.server_url) + + +@unittest.skipUnless(threading, "Threading required for this test.") class ProxyAuthTests(unittest.TestCase): URL = "http://localhost" @@ -246,6 +326,7 @@ def setUp(self): self.digest_auth_handler = DigestAuthHandler() self.digest_auth_handler.set_users({self.USER: self.PASSWD}) self.digest_auth_handler.set_realm(self.REALM) + # With Digest Authentication. def create_fake_proxy_handler(*args, **kwargs): return FakeProxyHandler(self.digest_auth_handler, *args, **kwargs) @@ -345,6 +426,7 @@ def log_message(self, *args): return FakeHTTPRequestHandler +@unittest.skipUnless(threading, "Threading required for this test.") class TestUrlopen(unittest.TestCase): """Tests urllib.request.urlopen using the network. @@ -463,12 +545,12 @@ def test_200_with_parameters(self): def test_https(self): handler = self.start_https_server() - data = self.urlopen("https://localhost:%s/bizarre" % handler.port) + context = ssl.create_default_context(cafile=CERT_localhost) + data = self.urlopen("https://localhost:%s/bizarre" % handler.port, context=context) self.assertEqual(data, b"we care a bit") def test_https_with_cafile(self): handler = self.start_https_server(certfile=CERT_localhost) - import ssl # Good cert data = self.urlopen("https://localhost:%s/bizarre" % handler.port, cafile=CERT_localhost) @@ -502,7 +584,8 @@ def cb_sni(ssl_sock, server_name, initial_context): context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) context.set_servername_callback(cb_sni) handler = self.start_https_server(context=context, certfile=CERT_localhost) - self.urlopen("https://localhost:%s" % handler.port) + context = ssl.create_default_context(cafile=CERT_localhost) + self.urlopen("https://localhost:%s" % handler.port, context=context) self.assertEqual(sni_name, "localhost") def test_sending_headers(self): @@ -592,9 +675,17 @@ def test_line_iteration(self): self.assertEqual(index + 1, len(lines)) -@support.reap_threads -def test_main(): - support.run_unittest(ProxyAuthTests, TestUrlopen) +threads_key = None + +def setUpModule(): + # Store the threading_setup in a key and ensure that it is cleaned up + # in the tearDown + global threads_key + threads_key = support.threading_setup() + +def tearDownModule(): + if threads_key: + support.threading_cleanup(threads_key) if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_urllib2net.py b/Lib/test/test_urllib2net.py index fba3ceac83f1..fc2140809ed5 100644 --- a/Lib/test/test_urllib2net.py +++ b/Lib/test/test_urllib2net.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - import unittest from test import support from test.test_urllib2 import sanepathname2url @@ -9,10 +7,8 @@ import urllib.error import urllib.request import sys -try: - import ssl -except ImportError: - ssl = None + +support.requires("network") TIMEOUT = 60 # seconds @@ -83,11 +79,11 @@ class CloseSocketTest(unittest.TestCase): def test_close(self): # calling .close() on urllib2's response objects should close the # underlying socket - url = "http://www.python.org/" + url = "http://www.example.com/" with support.transient_internet(url): response = _urlopen_with_retry(url) sock = response.fp - self.assertTrue(not sock.closed) + self.assertFalse(sock.closed) response.close() self.assertTrue(sock.closed) @@ -103,9 +99,9 @@ def setUp(self): def test_ftp(self): urls = [ - 'ftp://ftp.kernel.org/pub/linux/kernel/README', - 'ftp://ftp.kernel.org/pub/linux/kernel/non-existent-file', - #'ftp://ftp.kernel.org/pub/leenox/kernel/test', + 'ftp://ftp.debian.org/debian/README', + ('ftp://ftp.debian.org/debian/non-existent-file', + None, urllib.error.URLError), 'ftp://gatekeeper.research.compaq.com/pub/DEC/SRC' '/research-reports/00README-Legal-Rules-Regs', ] @@ -157,20 +153,20 @@ def test_file(self): ## self._test_urls(urls, self._extra_handlers()+[bauth, dauth]) def test_urlwithfrag(self): - urlwith_frag = "http://docs.python.org/2/glossary.html#glossary" + urlwith_frag = "http://www.pythontest.net/index.html#frag" with support.transient_internet(urlwith_frag): req = urllib.request.Request(urlwith_frag) res = urllib.request.urlopen(req) self.assertEqual(res.geturl(), - "http://docs.python.org/2/glossary.html#glossary") + "http://www.pythontest.net/index.html#frag") def test_redirect_url_withfrag(self): - redirect_url_with_frag = "http://bitly.com/urllibredirecttest" + redirect_url_with_frag = "http://www.pythontest.net/redir/with_frag/" with support.transient_internet(redirect_url_with_frag): req = urllib.request.Request(redirect_url_with_frag) res = urllib.request.urlopen(req) self.assertEqual(res.geturl(), - "http://docs.python.org/3.4/glossary.html#term-global-interpreter-lock") + "http://www.pythontest.net/elsewhere/#frag") def test_custom_headers(self): url = "http://www.example.com" @@ -215,39 +211,34 @@ def _test_urls(self, urls, handlers, retry=True): urlopen = _wrap_with_retry_thrice(urlopen, urllib.error.URLError) for url in urls: - if isinstance(url, tuple): - url, req, expected_err = url - else: - req = expected_err = None - - with support.transient_internet(url): - debug(url) - try: - f = urlopen(url, req, TIMEOUT) - except OSError as err: - debug(err) - if expected_err: - msg = ("Didn't get expected error(s) %s for %s %s, got %s: %s" % - (expected_err, url, req, type(err), err)) - self.assertIsInstance(err, expected_err, msg) - except urllib.error.URLError as err: - if isinstance(err[0], socket.timeout): - print("" % url, file=sys.stderr) - continue - else: - raise + with self.subTest(url=url): + if isinstance(url, tuple): + url, req, expected_err = url else: + req = expected_err = None + + with support.transient_internet(url): try: - with support.time_out, \ - support.socket_peer_reset, \ - support.ioerror_peer_reset: - buf = f.read() - debug("read %d bytes" % len(buf)) - except socket.timeout: - print("" % url, file=sys.stderr) - f.close() - debug("******** next url coming up...") - time.sleep(0.1) + f = urlopen(url, req, TIMEOUT) + # urllib.error.URLError is a subclass of OSError + except OSError as err: + if expected_err: + msg = ("Didn't get expected error(s) %s for %s %s, got %s: %s" % + (expected_err, url, req, type(err), err)) + self.assertIsInstance(err, expected_err, msg) + else: + raise + else: + try: + with support.time_out, \ + support.socket_peer_reset, \ + support.ioerror_peer_reset: + buf = f.read() + debug("read %d bytes" % len(buf)) + except socket.timeout: + print("" % url, file=sys.stderr) + f.close() + time.sleep(0.1) def _extra_handlers(self): handlers = [] @@ -262,16 +253,16 @@ def _extra_handlers(self): class TimeoutTest(unittest.TestCase): def test_http_basic(self): - self.assertTrue(socket.getdefaulttimeout() is None) - url = "http://www.python.org" + self.assertIsNone(socket.getdefaulttimeout()) + url = "http://www.example.com" with support.transient_internet(url, timeout=None): u = _urlopen_with_retry(url) self.addCleanup(u.close) - self.assertTrue(u.fp.raw._sock.gettimeout() is None) + self.assertIsNone(u.fp.raw._sock.gettimeout()) def test_http_default_timeout(self): - self.assertTrue(socket.getdefaulttimeout() is None) - url = "http://www.python.org" + self.assertIsNone(socket.getdefaulttimeout()) + url = "http://www.example.com" with support.transient_internet(url): socket.setdefaulttimeout(60) try: @@ -282,8 +273,8 @@ def test_http_default_timeout(self): self.assertEqual(u.fp.raw._sock.gettimeout(), 60) def test_http_no_timeout(self): - self.assertTrue(socket.getdefaulttimeout() is None) - url = "http://www.python.org" + self.assertIsNone(socket.getdefaulttimeout()) + url = "http://www.example.com" with support.transient_internet(url): socket.setdefaulttimeout(60) try: @@ -291,10 +282,10 @@ def test_http_no_timeout(self): self.addCleanup(u.close) finally: socket.setdefaulttimeout(None) - self.assertTrue(u.fp.raw._sock.gettimeout() is None) + self.assertIsNone(u.fp.raw._sock.gettimeout()) def test_http_timeout(self): - url = "http://www.python.org" + url = "http://www.example.com" with support.transient_internet(url): u = _urlopen_with_retry(url, timeout=120) self.addCleanup(u.close) @@ -303,14 +294,14 @@ def test_http_timeout(self): FTP_HOST = "ftp://ftp.mirror.nl/pub/gnu/" def test_ftp_basic(self): - self.assertTrue(socket.getdefaulttimeout() is None) + self.assertIsNone(socket.getdefaulttimeout()) with support.transient_internet(self.FTP_HOST, timeout=None): u = _urlopen_with_retry(self.FTP_HOST) self.addCleanup(u.close) - self.assertTrue(u.fp.fp.raw._sock.gettimeout() is None) + self.assertIsNone(u.fp.fp.raw._sock.gettimeout()) def test_ftp_default_timeout(self): - self.assertTrue(socket.getdefaulttimeout() is None) + self.assertIsNone(socket.getdefaulttimeout()) with support.transient_internet(self.FTP_HOST): socket.setdefaulttimeout(60) try: @@ -321,7 +312,7 @@ def test_ftp_default_timeout(self): self.assertEqual(u.fp.fp.raw._sock.gettimeout(), 60) def test_ftp_no_timeout(self): - self.assertTrue(socket.getdefaulttimeout() is None) + self.assertIsNone(socket.getdefaulttimeout()) with support.transient_internet(self.FTP_HOST): socket.setdefaulttimeout(60) try: @@ -329,7 +320,7 @@ def test_ftp_no_timeout(self): self.addCleanup(u.close) finally: socket.setdefaulttimeout(None) - self.assertTrue(u.fp.fp.raw._sock.gettimeout() is None) + self.assertIsNone(u.fp.fp.raw._sock.gettimeout()) def test_ftp_timeout(self): with support.transient_internet(self.FTP_HOST): @@ -339,5 +330,4 @@ def test_ftp_timeout(self): if __name__ == "__main__": - support.requires("network") unittest.main() diff --git a/Lib/test/test_urllib_response.py b/Lib/test/test_urllib_response.py index fdd33259dd38..0eb59426ccb6 100644 --- a/Lib/test/test_urllib_response.py +++ b/Lib/test/test_urllib_response.py @@ -1,42 +1,59 @@ """Unit tests for code in urllib.response.""" -import test.support +import socket +import tempfile import urllib.response import unittest -class TestFile(object): - - def __init__(self): - self.closed = False - - def read(self, bytes): - pass - - def readline(self): - pass - - def close(self): - self.closed = True - -class Testaddbase(unittest.TestCase): - - # TODO(jhylton): Write tests for other functionality of addbase() +class TestResponse(unittest.TestCase): def setUp(self): - self.fp = TestFile() - self.addbase = urllib.response.addbase(self.fp) + self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.fp = self.sock.makefile('rb') + self.test_headers = {"Host": "www.python.org", + "Connection": "close"} def test_with(self): + addbase = urllib.response.addbase(self.fp) + + self.assertIsInstance(addbase, tempfile._TemporaryFileWrapper) + def f(): - with self.addbase as spam: + with addbase as spam: pass self.assertFalse(self.fp.closed) f() self.assertTrue(self.fp.closed) self.assertRaises(ValueError, f) -def test_main(): - test.support.run_unittest(Testaddbase) + def test_addclosehook(self): + closehook_called = False + + def closehook(): + nonlocal closehook_called + closehook_called = True + + closehook = urllib.response.addclosehook(self.fp, closehook) + closehook.close() + + self.assertTrue(self.fp.closed) + self.assertTrue(closehook_called) + + def test_addinfo(self): + info = urllib.response.addinfo(self.fp, self.test_headers) + self.assertEqual(info.info(), self.test_headers) + + def test_addinfourl(self): + url = "http://www.python.org" + code = 200 + infourl = urllib.response.addinfourl(self.fp, self.test_headers, + url, code) + self.assertEqual(infourl.info(), self.test_headers) + self.assertEqual(infourl.geturl(), url) + self.assertEqual(infourl.getcode(), code) + + def tearDown(self): + self.sock.close() if __name__ == '__main__': - test_main() + unittest.main() diff --git a/Lib/test/test_urllibnet.py b/Lib/test/test_urllibnet.py index b6888f3d7be7..42ebb6e60b5e 100644 --- a/Lib/test/test_urllibnet.py +++ b/Lib/test/test_urllibnet.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - import unittest from test import support @@ -12,6 +10,8 @@ import time +support.requires('network') + class URLTimeoutTest(unittest.TestCase): # XXX this test doesn't seem to test anything useful. @@ -24,8 +24,8 @@ def tearDown(self): socket.setdefaulttimeout(None) def testURLread(self): - with support.transient_internet("www.python.org"): - f = urllib.request.urlopen("http://www.python.org/") + with support.transient_internet("www.example.com"): + f = urllib.request.urlopen("http://www.example.com/") x = f.read() @@ -38,7 +38,7 @@ class urlopenNetworkTests(unittest.TestCase): for transparent redirection have been written. setUp is not used for always constructing a connection to - http://www.python.org/ since there a few tests that don't use that address + http://www.example.com/ since there a few tests that don't use that address and making a connection is expensive enough to warrant minimizing unneeded connections. @@ -56,7 +56,7 @@ def urlopen(self, *args, **kwargs): def test_basic(self): # Simple test expected to pass. - with self.urlopen("http://www.python.org/") as open_url: + with self.urlopen("http://www.example.com/") as open_url: for attr in ("read", "readline", "readlines", "fileno", "close", "info", "geturl"): self.assertTrue(hasattr(open_url, attr), "object returned from " @@ -65,7 +65,7 @@ def test_basic(self): def test_readlines(self): # Test both readline and readlines. - with self.urlopen("http://www.python.org/") as open_url: + with self.urlopen("http://www.example.com/") as open_url: self.assertIsInstance(open_url.readline(), bytes, "readline did not return a string") self.assertIsInstance(open_url.readlines(), list, @@ -73,7 +73,7 @@ def test_readlines(self): def test_info(self): # Test 'info'. - with self.urlopen("http://www.python.org/") as open_url: + with self.urlopen("http://www.example.com/") as open_url: info_obj = open_url.info() self.assertIsInstance(info_obj, email.message.Message, "object returned by 'info' is not an " @@ -82,31 +82,31 @@ def test_info(self): def test_geturl(self): # Make sure same URL as opened is returned by geturl. - URL = "http://www.python.org/" + URL = "http://www.example.com/" with self.urlopen(URL) as open_url: gotten_url = open_url.geturl() self.assertEqual(gotten_url, URL) def test_getcode(self): # test getcode() with the fancy opener to get 404 error codes - URL = "http://www.python.org/XXXinvalidXXX" + URL = "http://www.example.com/XXXinvalidXXX" with support.transient_internet(URL): - open_url = urllib.request.FancyURLopener().open(URL) + with self.assertWarns(DeprecationWarning): + open_url = urllib.request.FancyURLopener().open(URL) try: code = open_url.getcode() finally: open_url.close() self.assertEqual(code, 404) + # On Windows, socket handles are not file descriptors; this + # test can't pass on Windows. + @unittest.skipIf(sys.platform in ('win32',), 'not appropriate for Windows') def test_fileno(self): - if sys.platform in ('win32',): - # On Windows, socket handles are not file descriptors; this - # test can't pass on Windows. - return # Make sure fd returned by fileno is valid. - with self.urlopen("http://www.python.org/", timeout=None) as open_url: + with self.urlopen("http://www.google.com/", timeout=None) as open_url: fd = open_url.fileno() - with os.fdopen(fd, encoding='utf-8') as f: + with os.fdopen(fd, 'rb') as f: self.assertTrue(f.read(), "reading from file created using fd " "returned by fileno failed") @@ -150,29 +150,29 @@ def urlretrieve(self, *args, **kwargs): def test_basic(self): # Test basic functionality. - with self.urlretrieve("http://www.python.org/") as (file_location, info): + with self.urlretrieve("http://www.example.com/") as (file_location, info): self.assertTrue(os.path.exists(file_location), "file location returned by" " urlretrieve is not a valid path") - with open(file_location, encoding='utf-8') as f: + with open(file_location, 'rb') as f: self.assertTrue(f.read(), "reading from the file location returned" " by urlretrieve failed") def test_specified_path(self): # Make sure that specifying the location of the file to write to works. - with self.urlretrieve("http://www.python.org/", + with self.urlretrieve("http://www.example.com/", support.TESTFN) as (file_location, info): self.assertEqual(file_location, support.TESTFN) self.assertTrue(os.path.exists(file_location)) - with open(file_location, encoding='utf-8') as f: + with open(file_location, 'rb') as f: self.assertTrue(f.read(), "reading from temporary file failed") def test_header(self): # Make sure header returned as 2nd value from urlretrieve is good. - with self.urlretrieve("http://www.python.org/") as (file_location, info): + with self.urlretrieve("http://www.example.com/") as (file_location, info): self.assertIsInstance(info, email.message.Message, "info is not an instance of email.message.Message") - logo = "http://www.python.org/community/logos/python-logo-master-v3-TM.png" + logo = "http://www.example.com/" def test_data_header(self): with self.urlretrieve(self.logo) as (file_location, fileheaders): @@ -209,11 +209,5 @@ def recording_reporthook(blocks, block_size, total_size): " >= total size in %s" % records_repr) -def test_main(): - support.requires('network') - support.run_unittest(URLTimeoutTest, - urlopenNetworkTests, - urlretrieveNetworkTests) - if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_urlparse.py b/Lib/test/test_urlparse.py old mode 100755 new mode 100644 index c938f09951af..cb323d3423be --- a/Lib/test/test_urlparse.py +++ b/Lib/test/test_urlparse.py @@ -1,5 +1,3 @@ -#! /usr/bin/env python3 - from test import support import unittest import urllib.parse @@ -213,10 +211,6 @@ def test_RFC1808(self): # "abnormal" cases from RFC 1808: self.checkJoin(RFC1808_BASE, '', 'http://a/b/c/d;p?q#f') - self.checkJoin(RFC1808_BASE, '../../../g', 'http://a/../g') - self.checkJoin(RFC1808_BASE, '../../../../g', 'http://a/../../g') - self.checkJoin(RFC1808_BASE, '/./g', 'http://a/./g') - self.checkJoin(RFC1808_BASE, '/../g', 'http://a/../g') self.checkJoin(RFC1808_BASE, 'g.', 'http://a/b/c/g.') self.checkJoin(RFC1808_BASE, '.g', 'http://a/b/c/.g') self.checkJoin(RFC1808_BASE, 'g..', 'http://a/b/c/g..') @@ -231,6 +225,13 @@ def test_RFC1808(self): #self.checkJoin(RFC1808_BASE, 'http:g', 'http:g') #self.checkJoin(RFC1808_BASE, 'http:', 'http:') + # XXX: The following tests are no longer compatible with RFC3986 + # self.checkJoin(RFC1808_BASE, '../../../g', 'http://a/../g') + # self.checkJoin(RFC1808_BASE, '../../../../g', 'http://a/../../g') + # self.checkJoin(RFC1808_BASE, '/./g', 'http://a/./g') + # self.checkJoin(RFC1808_BASE, '/../g', 'http://a/../g') + + def test_RFC2368(self): # Issue 11467: path that starts with a number is not parsed correctly self.assertEqual(urllib.parse.urlparse('mailto:1337@example.org'), @@ -261,10 +262,6 @@ def test_RFC2396(self): self.checkJoin(RFC2396_BASE, '../../', 'http://a/') self.checkJoin(RFC2396_BASE, '../../g', 'http://a/g') self.checkJoin(RFC2396_BASE, '', RFC2396_BASE) - self.checkJoin(RFC2396_BASE, '../../../g', 'http://a/../g') - self.checkJoin(RFC2396_BASE, '../../../../g', 'http://a/../../g') - self.checkJoin(RFC2396_BASE, '/./g', 'http://a/./g') - self.checkJoin(RFC2396_BASE, '/../g', 'http://a/../g') self.checkJoin(RFC2396_BASE, 'g.', 'http://a/b/c/g.') self.checkJoin(RFC2396_BASE, '.g', 'http://a/b/c/.g') self.checkJoin(RFC2396_BASE, 'g..', 'http://a/b/c/g..') @@ -280,10 +277,17 @@ def test_RFC2396(self): self.checkJoin(RFC2396_BASE, 'g#s/./x', 'http://a/b/c/g#s/./x') self.checkJoin(RFC2396_BASE, 'g#s/../x', 'http://a/b/c/g#s/../x') + # XXX: The following tests are no longer compatible with RFC3986 + # self.checkJoin(RFC2396_BASE, '../../../g', 'http://a/../g') + # self.checkJoin(RFC2396_BASE, '../../../../g', 'http://a/../../g') + # self.checkJoin(RFC2396_BASE, '/./g', 'http://a/./g') + # self.checkJoin(RFC2396_BASE, '/../g', 'http://a/../g') + + def test_RFC3986(self): # Test cases from RFC3986 self.checkJoin(RFC3986_BASE, '?y','http://a/b/c/d;p?y') - self.checkJoin(RFC2396_BASE, ';x', 'http://a/b/c/;x') + self.checkJoin(RFC3986_BASE, ';x', 'http://a/b/c/;x') self.checkJoin(RFC3986_BASE, 'g:h','g:h') self.checkJoin(RFC3986_BASE, 'g','http://a/b/c/g') self.checkJoin(RFC3986_BASE, './g','http://a/b/c/g') @@ -307,17 +311,17 @@ def test_RFC3986(self): self.checkJoin(RFC3986_BASE, '../..','http://a/') self.checkJoin(RFC3986_BASE, '../../','http://a/') self.checkJoin(RFC3986_BASE, '../../g','http://a/g') + self.checkJoin(RFC3986_BASE, '../../../g', 'http://a/g') #Abnormal Examples # The 'abnormal scenarios' are incompatible with RFC2986 parsing # Tests are here for reference. - #self.checkJoin(RFC3986_BASE, '../../../g','http://a/g') - #self.checkJoin(RFC3986_BASE, '../../../../g','http://a/g') - #self.checkJoin(RFC3986_BASE, '/./g','http://a/g') - #self.checkJoin(RFC3986_BASE, '/../g','http://a/g') - + self.checkJoin(RFC3986_BASE, '../../../g','http://a/g') + self.checkJoin(RFC3986_BASE, '../../../../g','http://a/g') + self.checkJoin(RFC3986_BASE, '/./g','http://a/g') + self.checkJoin(RFC3986_BASE, '/../g','http://a/g') self.checkJoin(RFC3986_BASE, 'g.','http://a/b/c/g.') self.checkJoin(RFC3986_BASE, '.g','http://a/b/c/.g') self.checkJoin(RFC3986_BASE, 'g..','http://a/b/c/g..') @@ -357,10 +361,8 @@ def test_urljoins(self): self.checkJoin(SIMPLE_BASE, '../g','http://a/b/g') self.checkJoin(SIMPLE_BASE, '../..','http://a/') self.checkJoin(SIMPLE_BASE, '../../g','http://a/g') - self.checkJoin(SIMPLE_BASE, '../../../g','http://a/../g') self.checkJoin(SIMPLE_BASE, './../g','http://a/b/g') self.checkJoin(SIMPLE_BASE, './g/.','http://a/b/c/g/') - self.checkJoin(SIMPLE_BASE, '/./g','http://a/./g') self.checkJoin(SIMPLE_BASE, 'g/./h','http://a/b/c/g/h') self.checkJoin(SIMPLE_BASE, 'g/../h','http://a/b/c/h') self.checkJoin(SIMPLE_BASE, 'http:g','http://a/b/c/g') @@ -374,6 +376,22 @@ def test_urljoins(self): self.checkJoin('svn://pathtorepo/dir1', 'dir2', 'svn://pathtorepo/dir2') self.checkJoin('svn+ssh://pathtorepo/dir1', 'dir2', 'svn+ssh://pathtorepo/dir2') + # XXX: The following tests are no longer compatible with RFC3986 + # self.checkJoin(SIMPLE_BASE, '../../../g','http://a/../g') + # self.checkJoin(SIMPLE_BASE, '/./g','http://a/./g') + + # test for issue22118 duplicate slashes + self.checkJoin(SIMPLE_BASE + '/', 'foo', SIMPLE_BASE + '/foo') + + # Non-RFC-defined tests, covering variations of base and trailing + # slashes + self.checkJoin('http://a/b/c/d/e/', '../../f/g/', 'http://a/b/c/f/g/') + self.checkJoin('http://a/b/c/d/e', '../../f/g/', 'http://a/b/f/g/') + self.checkJoin('http://a/b/c/d/e/', '/../../f/g/', 'http://a/f/g/') + self.checkJoin('http://a/b/c/d/e', '/../../f/g/', 'http://a/f/g/') + self.checkJoin('http://a/b/c/d/e/', '../../f/g', 'http://a/b/c/f/g') + self.checkJoin('http://a/b/', '../../f/g/', 'http://a/f/g/') + def test_RFC2732(self): str_cases = [ ('http://Test.python.org:5432/foo/', 'test.python.org', 5432), @@ -396,6 +414,16 @@ def test_RFC2732(self): ('http://[::12.34.56.78]/foo/', '::12.34.56.78', None), ('http://[::ffff:12.34.56.78]/foo/', '::ffff:12.34.56.78', None), + ('http://Test.python.org:/foo/', 'test.python.org', None), + ('http://12.34.56.78:/foo/', '12.34.56.78', None), + ('http://[::1]:/foo/', '::1', None), + ('http://[dead:beef::1]:/foo/', 'dead:beef::1', None), + ('http://[dead:beef::]:/foo/', 'dead:beef::', None), + ('http://[dead:beef:cafe:5417:affe:8FA3:deaf:feed]:/foo/', + 'dead:beef:cafe:5417:affe:8fa3:deaf:feed', None), + ('http://[::12.34.56.78]:/foo/', '::12.34.56.78', None), + ('http://[::ffff:12.34.56.78]:/foo/', + '::ffff:12.34.56.78', None), ] def _encode(t): return t[0].encode('ascii'), t[1].encode('ascii'), t[2] @@ -741,17 +769,25 @@ def test_parse_qsl_encoding(self): errors="ignore") self.assertEqual(result, [('key', '\u0141-')]) + def test_splitport(self): + splitport = urllib.parse.splitport + self.assertEqual(splitport('parrot:88'), ('parrot', '88')) + self.assertEqual(splitport('parrot'), ('parrot', None)) + self.assertEqual(splitport('parrot:'), ('parrot', None)) + self.assertEqual(splitport('127.0.0.1'), ('127.0.0.1', None)) + self.assertEqual(splitport('parrot:cheese'), ('parrot:cheese', None)) + def test_splitnport(self): - # Normal cases are exercised by other tests; ensure that we also - # catch cases with no port specified. (testcase ensuring coverage) - result = urllib.parse.splitnport('parrot:88') - self.assertEqual(result, ('parrot', 88)) - result = urllib.parse.splitnport('parrot') - self.assertEqual(result, ('parrot', -1)) - result = urllib.parse.splitnport('parrot', 55) - self.assertEqual(result, ('parrot', 55)) - result = urllib.parse.splitnport('parrot:') - self.assertEqual(result, ('parrot', None)) + splitnport = urllib.parse.splitnport + self.assertEqual(splitnport('parrot:88'), ('parrot', 88)) + self.assertEqual(splitnport('parrot'), ('parrot', -1)) + self.assertEqual(splitnport('parrot', 55), ('parrot', 55)) + self.assertEqual(splitnport('parrot:'), ('parrot', -1)) + self.assertEqual(splitnport('parrot:', 55), ('parrot', 55)) + self.assertEqual(splitnport('127.0.0.1'), ('127.0.0.1', -1)) + self.assertEqual(splitnport('127.0.0.1', 55), ('127.0.0.1', 55)) + self.assertEqual(splitnport('parrot:cheese'), ('parrot', None)) + self.assertEqual(splitnport('parrot:cheese', 55), ('parrot', None)) def test_splitquery(self): # Normal cases are exercised by other tests; ensure that we also diff --git a/Lib/test/test_userstring.py b/Lib/test/test_userstring.py old mode 100755 new mode 100644 index 71fcac25e13f..9bc8edd99d2e --- a/Lib/test/test_userstring.py +++ b/Lib/test/test_userstring.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 # UserString is a wrapper around the native builtin string type. # UserString instances should behave similar to builtin string objects. @@ -29,14 +28,12 @@ def checkequal(self, result, object, methodname, *args, **kwargs): realresult ) - def checkraises(self, exc, object, methodname, *args): - object = self.fixtype(object) + def checkraises(self, exc, obj, methodname, *args): + obj = self.fixtype(obj) # we don't fix the arguments, because UserString can't cope with it - self.assertRaises( - exc, - getattr(object, methodname), - *args - ) + with self.assertRaises(exc) as cm: + getattr(obj, methodname)(*args) + self.assertNotEqual(str(cm.exception), '') def checkcall(self, object, methodname, *args): object = self.fixtype(object) diff --git a/Lib/test/test_uu.py b/Lib/test/test_uu.py index cbf6724fd2d3..25fffbf9936a 100644 --- a/Lib/test/test_uu.py +++ b/Lib/test/test_uu.py @@ -93,6 +93,28 @@ def test_missingbegin(self): except uu.Error as e: self.assertEqual(str(e), "No valid begin line found in input file") + def test_garbage_padding(self): + # Issue #22406 + encodedtext = ( + b"begin 644 file\n" + # length 1; bits 001100 111111 111111 111111 + b"\x21\x2C\x5F\x5F\x5F\n" + b"\x20\n" + b"end\n" + ) + plaintext = b"\x33" # 00110011 + + with self.subTest("uu.decode()"): + inp = io.BytesIO(encodedtext) + out = io.BytesIO() + uu.decode(inp, out, quiet=True) + self.assertEqual(out.getvalue(), plaintext) + + with self.subTest("uu_codec"): + import codecs + decoded = codecs.decode(encodedtext, "uu_codec") + self.assertEqual(decoded, plaintext) + class UUStdIOTest(unittest.TestCase): def setUp(self): diff --git a/Lib/test/test_uuid.py b/Lib/test/test_uuid.py index 072734e7286f..fcb84540c12a 100644 --- a/Lib/test/test_uuid.py +++ b/Lib/test/test_uuid.py @@ -1,8 +1,10 @@ -import unittest +import unittest.mock from test import support import builtins import io import os +import shutil +import subprocess import uuid def importable(name): @@ -13,9 +15,6 @@ def importable(name): return False class TestUUID(unittest.TestCase): - last_node = None - source2node = {} - def test_UUID(self): equal = self.assertEqual ascending = [] @@ -293,90 +292,13 @@ def test_exceptions(self): badtype(lambda: setattr(u, 'clock_seq_low', 0)) badtype(lambda: setattr(u, 'node', 0)) - def check_node(self, node, source): - message = "%012x is not an RFC 4122 node ID" % node - self.assertTrue(0 < node, message) - self.assertTrue(node < (1 << 48), message) - - TestUUID.source2node[source] = node - if TestUUID.last_node: - if TestUUID.last_node != node: - msg = "different sources disagree on node:\n" - for s, n in TestUUID.source2node.items(): - msg += " from source %r, node was %012x\n" % (s, n) - # There's actually no reason to expect the MAC addresses - # to agree across various methods -- e.g., a box may have - # multiple network interfaces, and different ways of getting - # a MAC address may favor different HW. - ##self.fail(msg) - else: - TestUUID.last_node = node - - @unittest.skipUnless(os.name == 'posix', 'requires Posix') - def test_ifconfig_getnode(self): - node = uuid._ifconfig_getnode() - if node is not None: - self.check_node(node, 'ifconfig') - - @unittest.skipUnless(os.name == 'nt', 'requires Windows') - def test_ipconfig_getnode(self): - node = uuid._ipconfig_getnode() - if node is not None: - self.check_node(node, 'ipconfig') - - @unittest.skipUnless(importable('win32wnet'), 'requires win32wnet') - @unittest.skipUnless(importable('netbios'), 'requires netbios') - def test_netbios_getnode(self): - self.check_node(uuid._netbios_getnode(), 'netbios') - - def test_random_getnode(self): - node = uuid._random_getnode() - # Least significant bit of first octet must be set. - self.assertTrue(node & 0x010000000000) - self.assertTrue(node < (1 << 48)) - - @unittest.skipUnless(os.name == 'posix', 'requires Posix') - @unittest.skipUnless(importable('ctypes'), 'requires ctypes') - def test_unixdll_getnode(self): - try: # Issues 1481, 3581: _uuid_generate_time() might be None. - self.check_node(uuid._unixdll_getnode(), 'unixdll') - except TypeError: - pass - - @unittest.skipUnless(os.name == 'nt', 'requires Windows') - @unittest.skipUnless(importable('ctypes'), 'requires ctypes') - def test_windll_getnode(self): - self.check_node(uuid._windll_getnode(), 'windll') - def test_getnode(self): node1 = uuid.getnode() - self.check_node(node1, "getnode1") + self.assertTrue(0 < node1 < (1 << 48), '%012x' % node1) # Test it again to ensure consistency. node2 = uuid.getnode() - self.check_node(node2, "getnode2") - - self.assertEqual(node1, node2) - - @unittest.skipUnless(os.name == 'posix', 'requires Posix') - def test_find_mac(self): - data = '''\ - -fake hwaddr -cscotun0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 -eth0 Link encap:Ethernet HWaddr 12:34:56:78:90:ab -''' - def mock_popen(cmd): - return io.StringIO(data) - - with support.swap_attr(os, 'popen', mock_popen): - mac = uuid._find_mac( - command='ifconfig', - args='', - hw_identifiers=['hwaddr'], - get_index=lambda x: x + 1, - ) - self.assertEqual(mac, 0x1234567890ab) + self.assertEqual(node1, node2, '%012x != %012x' % (node1, node2)) @unittest.skipUnless(importable('ctypes'), 'requires ctypes') def test_uuid1(self): @@ -488,5 +410,101 @@ def testIssue8621(self): self.assertNotEqual(parent_value, child_value) +class TestInternals(unittest.TestCase): + @unittest.skipUnless(os.name == 'posix', 'requires Posix') + def test_find_mac(self): + data = ''' +fake hwaddr +cscotun0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 +eth0 Link encap:Ethernet HWaddr 12:34:56:78:90:ab +''' + + popen = unittest.mock.MagicMock() + popen.stdout = io.BytesIO(data.encode()) + + with unittest.mock.patch.object(shutil, 'which', + return_value='/sbin/ifconfig'): + with unittest.mock.patch.object(subprocess, 'Popen', + return_value=popen): + mac = uuid._find_mac( + command='ifconfig', + args='', + hw_identifiers=[b'hwaddr'], + get_index=lambda x: x + 1, + ) + + self.assertEqual(mac, 0x1234567890ab) + + def check_node(self, node, requires=None, network=False): + if requires and node is None: + self.skipTest('requires ' + requires) + hex = '%012x' % node + if support.verbose >= 2: + print(hex, end=' ') + if network: + # 47 bit will never be set in IEEE 802 addresses obtained + # from network cards. + self.assertFalse(node & 0x010000000000, hex) + self.assertTrue(0 < node < (1 << 48), + "%s is not an RFC 4122 node ID" % hex) + + @unittest.skipUnless(os.name == 'posix', 'requires Posix') + def test_ifconfig_getnode(self): + node = uuid._ifconfig_getnode() + self.check_node(node, 'ifconfig', True) + + @unittest.skipUnless(os.name == 'posix', 'requires Posix') + def test_ip_getnode(self): + node = uuid._ip_getnode() + self.check_node(node, 'ip', True) + + @unittest.skipUnless(os.name == 'posix', 'requires Posix') + def test_arp_getnode(self): + node = uuid._arp_getnode() + self.check_node(node, 'arp', True) + + @unittest.skipUnless(os.name == 'posix', 'requires Posix') + def test_lanscan_getnode(self): + node = uuid._lanscan_getnode() + self.check_node(node, 'lanscan', True) + + @unittest.skipUnless(os.name == 'posix', 'requires Posix') + def test_netstat_getnode(self): + node = uuid._netstat_getnode() + self.check_node(node, 'netstat', True) + + @unittest.skipUnless(os.name == 'nt', 'requires Windows') + def test_ipconfig_getnode(self): + node = uuid._ipconfig_getnode() + self.check_node(node, 'ipconfig', True) + + @unittest.skipUnless(importable('win32wnet'), 'requires win32wnet') + @unittest.skipUnless(importable('netbios'), 'requires netbios') + def test_netbios_getnode(self): + node = uuid._netbios_getnode() + self.check_node(node, network=True) + + def test_random_getnode(self): + node = uuid._random_getnode() + # Least significant bit of first octet must be set. + self.assertTrue(node & 0x010000000000, '%012x' % node) + self.check_node(node) + + @unittest.skipUnless(os.name == 'posix', 'requires Posix') + @unittest.skipUnless(importable('ctypes'), 'requires ctypes') + def test_unixdll_getnode(self): + try: # Issues 1481, 3581: _uuid_generate_time() might be None. + node = uuid._unixdll_getnode() + except TypeError: + self.skipTest('requires uuid_generate_time') + self.check_node(node) + + @unittest.skipUnless(os.name == 'nt', 'requires Windows') + @unittest.skipUnless(importable('ctypes'), 'requires ctypes') + def test_windll_getnode(self): + node = uuid._windll_getnode() + self.check_node(node) + + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_venv.py b/Lib/test/test_venv.py index eb225fa4aec9..b462588e34b2 100644 --- a/Lib/test/test_venv.py +++ b/Lib/test/test_venv.py @@ -8,15 +8,18 @@ import ensurepip import os import os.path -import shutil +import struct import subprocess import sys import tempfile from test.support import (captured_stdout, captured_stderr, run_unittest, - can_symlink, EnvironmentVarGuard) + can_symlink, EnvironmentVarGuard, rmtree) import textwrap import unittest import venv + +# pip currently requires ssl support, so we ensure we handle +# it being missing (http://bugs.python.org/issue19744) try: import ssl except ImportError: @@ -25,6 +28,12 @@ skipInVenv = unittest.skipIf(sys.prefix != sys.base_prefix, 'Test not appropriate in a venv') +# os.path.exists('nul') is False: http://bugs.python.org/issue20541 +if os.devnull.lower() == 'nul': + failsOnWindows = unittest.expectedFailure +else: + def failsOnWindows(f): + return f class BaseTest(unittest.TestCase): """Base class for venv tests.""" @@ -46,7 +55,7 @@ def setUp(self): self.exe = os.path.split(executable)[-1] def tearDown(self): - shutil.rmtree(self.env_dir) + rmtree(self.env_dir) def run_with_capture(self, func, *args, **kwargs): with captured_stdout() as output: @@ -73,11 +82,19 @@ def test_defaults(self): """ Test the create function with default arguments. """ - shutil.rmtree(self.env_dir) + rmtree(self.env_dir) self.run_with_capture(venv.create, self.env_dir) self.isdir(self.bindir) self.isdir(self.include) self.isdir(*self.lib) + # Issue 21197 + p = self.get_env_file('lib64') + conditions = ((struct.calcsize('P') == 8) and (os.name == 'posix') and + (sys.platform != 'darwin')) + if conditions: + self.assertTrue(os.path.islink(p)) + else: + self.assertFalse(os.path.exists(p)) data = self.get_text_file_contents('pyvenv.cfg') if sys.platform == 'darwin' and ('__PYVENV_LAUNCHER__' in os.environ): @@ -103,7 +120,7 @@ def test_prefixes(self): self.assertEqual(sys.base_exec_prefix, sys.exec_prefix) # check a venv's prefixes - shutil.rmtree(self.env_dir) + rmtree(self.env_dir) self.run_with_capture(venv.create, self.env_dir) envpy = os.path.join(self.env_dir, self.bindir, self.exe) cmd = [envpy, '-c', None] @@ -170,7 +187,7 @@ def clear_directory(self, path): if os.path.islink(fn) or os.path.isfile(fn): os.remove(fn) elif os.path.isdir(fn): - shutil.rmtree(fn) + rmtree(fn) def test_unoverwritable_fails(self): #create a file clashing with directories in the env dir @@ -185,17 +202,22 @@ def test_upgrade(self): """ Test upgrading an existing environment directory. """ - builder = venv.EnvBuilder(upgrade=True) - self.run_with_capture(builder.create, self.env_dir) - self.isdir(self.bindir) - self.isdir(self.include) - self.isdir(*self.lib) - fn = self.get_env_file(self.bindir, self.exe) - if not os.path.exists(fn): # diagnostics for Windows buildbot failures - bd = self.get_env_file(self.bindir) - print('Contents of %r:' % bd) - print(' %r' % os.listdir(bd)) - self.assertTrue(os.path.exists(fn), 'File %r should exist.' % fn) + # See Issue #21643: the loop needs to run twice to ensure + # that everything works on the upgrade (the first run just creates + # the venv). + for upgrade in (False, True): + builder = venv.EnvBuilder(upgrade=upgrade) + self.run_with_capture(builder.create, self.env_dir) + self.isdir(self.bindir) + self.isdir(self.include) + self.isdir(*self.lib) + fn = self.get_env_file(self.bindir, self.exe) + if not os.path.exists(fn): + # diagnostics for Windows buildbot failures + bd = self.get_env_file(self.bindir) + print('Contents of %r:' % bd) + print(' %r' % os.listdir(bd)) + self.assertTrue(os.path.exists(fn), 'File %r should exist.' % fn) def test_isolation(self): """ @@ -231,7 +253,7 @@ def test_executable(self): """ Test that the sys.executable value is as expected. """ - shutil.rmtree(self.env_dir) + rmtree(self.env_dir) self.run_with_capture(venv.create, self.env_dir) envpy = os.path.join(os.path.realpath(self.env_dir), self.bindir, self.exe) cmd = [envpy, '-c', 'import sys; print(sys.executable)'] @@ -245,7 +267,7 @@ def test_executable_symlinks(self): """ Test that the sys.executable value is as expected. """ - shutil.rmtree(self.env_dir) + rmtree(self.env_dir) builder = venv.EnvBuilder(clear=True, symlinks=True) builder.create(self.env_dir) envpy = os.path.join(os.path.realpath(self.env_dir), self.bindir, self.exe) @@ -276,37 +298,68 @@ def assert_pip_not_installed(self): def test_no_pip_by_default(self): - shutil.rmtree(self.env_dir) + rmtree(self.env_dir) self.run_with_capture(venv.create, self.env_dir) self.assert_pip_not_installed() def test_explicit_no_pip(self): - shutil.rmtree(self.env_dir) + rmtree(self.env_dir) self.run_with_capture(venv.create, self.env_dir, with_pip=False) self.assert_pip_not_installed() - # Temporary skip for http://bugs.python.org/issue19744 - @unittest.skipIf(ssl is None, 'pip needs SSL support') + @failsOnWindows + def test_devnull_exists_and_is_empty(self): + # Fix for issue #20053 uses os.devnull to force a config file to + # appear empty. However http://bugs.python.org/issue20541 means + # that doesn't currently work properly on Windows. Once that is + # fixed, the "win_location" part of test_with_pip should be restored + self.assertTrue(os.path.exists(os.devnull)) + with open(os.devnull, "rb") as f: + self.assertEqual(f.read(), b"") + + # Requesting pip fails without SSL (http://bugs.python.org/issue19744) + @unittest.skipIf(ssl is None, ensurepip._MISSING_SSL_MESSAGE) def test_with_pip(self): - shutil.rmtree(self.env_dir) + rmtree(self.env_dir) with EnvironmentVarGuard() as envvars: # pip's cross-version compatibility may trigger deprecation # warnings in current versions of Python. Ensure related # environment settings don't cause venv to fail. envvars["PYTHONWARNINGS"] = "e" - # pip doesn't ignore environment variables when running in - # isolated mode, and we don't have an active virtualenv here, - # we're relying on the native venv support in 3.3+ - # See http://bugs.python.org/issue19734 for details - del envvars["PIP_REQUIRE_VIRTUALENV"] - try: - self.run_with_capture(venv.create, self.env_dir, with_pip=True) - except subprocess.CalledProcessError as exc: - # The output this produces can be a little hard to read, but - # least it has all the details - details = exc.output.decode(errors="replace") - msg = "{}\n\n**Subprocess Output**\n{}".format(exc, details) - self.fail(msg) + # ensurepip is different enough from a normal pip invocation + # that we want to ensure it ignores the normal pip environment + # variable settings. We set PIP_NO_INSTALL here specifically + # to check that ensurepip (and hence venv) ignores it. + # See http://bugs.python.org/issue19734 + envvars["PIP_NO_INSTALL"] = "1" + # Also check that we ignore the pip configuration file + # See http://bugs.python.org/issue20053 + with tempfile.TemporaryDirectory() as home_dir: + envvars["HOME"] = home_dir + bad_config = "[global]\nno-install=1" + # Write to both config file names on all platforms to reduce + # cross-platform variation in test code behaviour + win_location = ("pip", "pip.ini") + posix_location = (".pip", "pip.conf") + # Skips win_location due to http://bugs.python.org/issue20541 + for dirname, fname in (posix_location,): + dirpath = os.path.join(home_dir, dirname) + os.mkdir(dirpath) + fpath = os.path.join(dirpath, fname) + with open(fpath, 'w') as f: + f.write(bad_config) + + # Actually run the create command with all that unhelpful + # config in place to ensure we ignore it + try: + self.run_with_capture(venv.create, self.env_dir, + with_pip=True) + except subprocess.CalledProcessError as exc: + # The output this produces can be a little hard to read, + # but at least it has all the details + details = exc.output.decode(errors="replace") + msg = "{}\n\n**Subprocess Output**\n{}" + self.fail(msg.format(exc, details)) # Ensure pip is available in the virtual environment envpy = os.path.join(os.path.realpath(self.env_dir), self.bindir, self.exe) cmd = [envpy, '-Im', 'pip', '--version'] @@ -328,11 +381,6 @@ def test_with_pip(self): # installers works (at least in a virtual environment) cmd = [envpy, '-Im', 'ensurepip._uninstall'] with EnvironmentVarGuard() as envvars: - # pip doesn't ignore environment variables when running in - # isolated mode, and we don't have an active virtualenv here, - # we're relying on the native venv support in 3.3+ - # See http://bugs.python.org/issue19734 for details - del envvars["PIP_REQUIRE_VIRTUALENV"] p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = p.communicate() diff --git a/Lib/test/test_wait3.py b/Lib/test/test_wait3.py index f6a065d850d9..bb71481adc3f 100644 --- a/Lib/test/test_wait3.py +++ b/Lib/test/test_wait3.py @@ -18,7 +18,8 @@ def wait_impl(self, cpid): # This many iterations can be required, since some previously run # tests (e.g. test_ctypes) could have spawned a lot of children # very quickly. - for i in range(30): + deadline = time.monotonic() + 10.0 + while time.monotonic() <= deadline: # wait3() shouldn't hang, but some of the buildbots seem to hang # in the forking tests. This is an attempt to fix the problem. spid, status, rusage = os.wait3(os.WNOHANG) diff --git a/Lib/test/test_wait4.py b/Lib/test/test_wait4.py index 352c11aadec3..b427a9b1a4cb 100644 --- a/Lib/test/test_wait4.py +++ b/Lib/test/test_wait4.py @@ -19,13 +19,14 @@ def wait_impl(self, cpid): # Issue #11185: wait4 is broken on AIX and will always return 0 # with WNOHANG. option = 0 - for i in range(10): + deadline = time.monotonic() + 10.0 + while time.monotonic() <= deadline: # wait4() shouldn't hang, but some of the buildbots seem to hang # in the forking tests. This is an attempt to fix the problem. spid, status, rusage = os.wait4(cpid, option) if spid == cpid: break - time.sleep(1.0) + time.sleep(0.1) self.assertEqual(spid, cpid) self.assertEqual(status, 0, "cause = %d, exit = %d" % (status&0xff, status>>8)) self.assertTrue(rusage) diff --git a/Lib/test/test_warnings.py b/Lib/test/test_warnings.py index 87463ac1a31c..9ac2139e3307 100644 --- a/Lib/test/test_warnings.py +++ b/Lib/test/test_warnings.py @@ -4,9 +4,8 @@ from io import StringIO import sys import unittest -import subprocess from test import support -from test.script_helper import assert_python_ok +from test.script_helper import assert_python_ok, assert_python_failure from test import warning_tests @@ -62,6 +61,25 @@ def tearDown(self): sys.modules['warnings'] = original_warnings super(BaseTest, self).tearDown() +class PublicAPITests(BaseTest): + + """Ensures that the correct values are exposed in the + public API. + """ + + def test_module_all_attribute(self): + self.assertTrue(hasattr(self.module, '__all__')) + target_api = ["warn", "warn_explicit", "showwarning", + "formatwarning", "filterwarnings", "simplefilter", + "resetwarnings", "catch_warnings"] + self.assertSetEqual(set(self.module.__all__), + set(target_api)) + +class CPublicAPITests(PublicAPITests, unittest.TestCase): + module = c_warnings + +class PyPublicAPITests(PublicAPITests, unittest.TestCase): + module = py_warnings class FilterTests(BaseTest): @@ -74,6 +92,16 @@ def test_error(self): self.assertRaises(UserWarning, self.module.warn, "FilterTests.test_error") + def test_error_after_default(self): + with original_warnings.catch_warnings(module=self.module) as w: + self.module.resetwarnings() + message = "FilterTests.test_ignore_after_default" + def f(): + self.module.warn(message, UserWarning) + f() + self.module.filterwarnings("error", category=UserWarning) + self.assertRaises(UserWarning, f) + def test_ignore(self): with original_warnings.catch_warnings(record=True, module=self.module) as w: @@ -82,6 +110,19 @@ def test_ignore(self): self.module.warn("FilterTests.test_ignore", UserWarning) self.assertEqual(len(w), 0) + def test_ignore_after_default(self): + with original_warnings.catch_warnings(record=True, + module=self.module) as w: + self.module.resetwarnings() + message = "FilterTests.test_ignore_after_default" + def f(): + self.module.warn(message, UserWarning) + f() + self.module.filterwarnings("ignore", category=UserWarning) + f() + f() + self.assertEqual(len(w), 1) + def test_always(self): with original_warnings.catch_warnings(record=True, module=self.module) as w: @@ -93,6 +134,26 @@ def test_always(self): self.module.warn(message, UserWarning) self.assertTrue(w[-1].message, message) + def test_always_after_default(self): + with original_warnings.catch_warnings(record=True, + module=self.module) as w: + self.module.resetwarnings() + message = "FilterTests.test_always_after_ignore" + def f(): + self.module.warn(message, UserWarning) + f() + self.assertEqual(len(w), 1) + self.assertEqual(w[-1].message.args[0], message) + f() + self.assertEqual(len(w), 1) + self.module.filterwarnings("always", category=UserWarning) + f() + self.assertEqual(len(w), 2) + self.assertEqual(w[-1].message.args[0], message) + f() + self.assertEqual(len(w), 3) + self.assertEqual(w[-1].message.args[0], message) + def test_default(self): with original_warnings.catch_warnings(record=True, module=self.module) as w: @@ -371,6 +432,41 @@ def __str__(self): with self.assertRaises(ValueError): self.module.warn(BadStrWarning()) + def test_warning_classes(self): + class MyWarningClass(Warning): + pass + + class NonWarningSubclass: + pass + + # passing a non-subclass of Warning should raise a TypeError + with self.assertRaises(TypeError) as cm: + self.module.warn('bad warning category', '') + self.assertIn('category must be a Warning subclass, not ', + str(cm.exception)) + + with self.assertRaises(TypeError) as cm: + self.module.warn('bad warning category', NonWarningSubclass) + self.assertIn('category must be a Warning subclass, not ', + str(cm.exception)) + + # check that warning instances also raise a TypeError + with self.assertRaises(TypeError) as cm: + self.module.warn('bad warning category', MyWarningClass()) + self.assertIn('category must be a Warning subclass, not ', + str(cm.exception)) + + with self.assertWarns(MyWarningClass) as cm: + self.module.warn('good warning category', MyWarningClass) + self.assertEqual('good warning category', str(cm.warning)) + + with self.assertWarns(UserWarning) as cm: + self.module.warn('good warning category', None) + self.assertEqual('good warning category', str(cm.warning)) + + with self.assertWarns(MyWarningClass) as cm: + self.module.warn('good warning category', MyWarningClass) + self.assertIsInstance(cm.warning, Warning) class CWarnTests(WarnTests, unittest.TestCase): module = c_warnings @@ -488,7 +584,9 @@ def test_default_action(self): registry=registry) self.assertEqual(w[-1].message, message) self.assertEqual(len(w), 1) - self.assertEqual(len(registry), 1) + # One actual registry key plus the "version" key + self.assertEqual(len(registry), 2) + self.assertIn("version", registry) del w[:] # Test removal. del self.module.defaultaction @@ -498,7 +596,7 @@ def test_default_action(self): registry=registry) self.assertEqual(w[-1].message, message) self.assertEqual(len(w), 1) - self.assertEqual(len(registry), 1) + self.assertEqual(len(registry), 2) del w[:] # Test setting. self.module.defaultaction = "ignore" @@ -568,6 +666,15 @@ def test_filename_none(self): finally: globals_dict['__file__'] = oldfile + def test_stderr_none(self): + rc, stdout, stderr = assert_python_ok("-c", + "import sys; sys.stderr = None; " + "import warnings; warnings.simplefilter('always'); " + "warnings.warn('Warning!')") + self.assertEqual(stdout, b'') + self.assertNotIn(b'Warning!', stderr) + self.assertNotIn(b'Error', stderr) + class WarningsDisplayTests(BaseTest): @@ -695,7 +802,7 @@ def test_check_warnings(self): # Explicit tests for the test.support convenience wrapper wmod = self.module if wmod is not sys.modules['warnings']: - return + self.skipTest('module to test is not loaded warnings module') with support.check_warnings(quiet=False) as w: self.assertEqual(w.warnings, []) wmod.simplefilter("always") @@ -732,47 +839,46 @@ class PyCatchWarningTests(CatchWarningTests, unittest.TestCase): class EnvironmentVariableTests(BaseTest): def test_single_warning(self): - newenv = os.environ.copy() - newenv["PYTHONWARNINGS"] = "ignore::DeprecationWarning" - p = subprocess.Popen([sys.executable, - "-c", "import sys; sys.stdout.write(str(sys.warnoptions))"], - stdout=subprocess.PIPE, env=newenv) - self.assertEqual(p.communicate()[0], b"['ignore::DeprecationWarning']") - self.assertEqual(p.wait(), 0) + rc, stdout, stderr = assert_python_ok("-c", + "import sys; sys.stdout.write(str(sys.warnoptions))", + PYTHONWARNINGS="ignore::DeprecationWarning") + self.assertEqual(stdout, b"['ignore::DeprecationWarning']") def test_comma_separated_warnings(self): - newenv = os.environ.copy() - newenv["PYTHONWARNINGS"] = ("ignore::DeprecationWarning," - "ignore::UnicodeWarning") - p = subprocess.Popen([sys.executable, - "-c", "import sys; sys.stdout.write(str(sys.warnoptions))"], - stdout=subprocess.PIPE, env=newenv) - self.assertEqual(p.communicate()[0], - b"['ignore::DeprecationWarning', 'ignore::UnicodeWarning']") - self.assertEqual(p.wait(), 0) + rc, stdout, stderr = assert_python_ok("-c", + "import sys; sys.stdout.write(str(sys.warnoptions))", + PYTHONWARNINGS="ignore::DeprecationWarning,ignore::UnicodeWarning") + self.assertEqual(stdout, + b"['ignore::DeprecationWarning', 'ignore::UnicodeWarning']") def test_envvar_and_command_line(self): - newenv = os.environ.copy() - newenv["PYTHONWARNINGS"] = "ignore::DeprecationWarning" - p = subprocess.Popen([sys.executable, "-W" "ignore::UnicodeWarning", - "-c", "import sys; sys.stdout.write(str(sys.warnoptions))"], - stdout=subprocess.PIPE, env=newenv) - self.assertEqual(p.communicate()[0], - b"['ignore::UnicodeWarning', 'ignore::DeprecationWarning']") - self.assertEqual(p.wait(), 0) + rc, stdout, stderr = assert_python_ok("-Wignore::UnicodeWarning", "-c", + "import sys; sys.stdout.write(str(sys.warnoptions))", + PYTHONWARNINGS="ignore::DeprecationWarning") + self.assertEqual(stdout, + b"['ignore::DeprecationWarning', 'ignore::UnicodeWarning']") + + def test_conflicting_envvar_and_command_line(self): + rc, stdout, stderr = assert_python_failure("-Werror::DeprecationWarning", "-c", + "import sys, warnings; sys.stdout.write(str(sys.warnoptions)); " + "warnings.warn('Message', DeprecationWarning)", + PYTHONWARNINGS="default::DeprecationWarning") + self.assertEqual(stdout, + b"['default::DeprecationWarning', 'error::DeprecationWarning']") + self.assertEqual(stderr.splitlines(), + [b"Traceback (most recent call last):", + b" File \"\", line 1, in ", + b"DeprecationWarning: Message"]) @unittest.skipUnless(sys.getfilesystemencoding() != 'ascii', 'requires non-ascii filesystemencoding') def test_nonascii(self): - newenv = os.environ.copy() - newenv["PYTHONWARNINGS"] = "ignore:DeprecaciónWarning" - newenv["PYTHONIOENCODING"] = "utf-8" - p = subprocess.Popen([sys.executable, - "-c", "import sys; sys.stdout.write(str(sys.warnoptions))"], - stdout=subprocess.PIPE, env=newenv) - self.assertEqual(p.communicate()[0], - "['ignore:DeprecaciónWarning']".encode('utf-8')) - self.assertEqual(p.wait(), 0) + rc, stdout, stderr = assert_python_ok("-c", + "import sys; sys.stdout.write(str(sys.warnoptions))", + PYTHONIOENCODING="utf-8", + PYTHONWARNINGS="ignore:DeprecaciónWarning") + self.assertEqual(stdout, + "['ignore:DeprecaciónWarning']".encode('utf-8')) class CEnvironmentVariableTests(EnvironmentVariableTests, unittest.TestCase): module = c_warnings @@ -787,18 +893,11 @@ def test_issue_8766(self): # or not completely loaded (warnings imports indirectly encodings by # importing linecache) yet with support.temp_cwd() as cwd, support.temp_cwd('encodings'): - env = os.environ.copy() - env['PYTHONPATH'] = cwd - # encodings loaded by initfsencoding() - retcode = subprocess.call([sys.executable, '-c', 'pass'], env=env) - self.assertEqual(retcode, 0) + assert_python_ok('-c', 'pass', PYTHONPATH=cwd) # Use -W to load warnings module at startup - retcode = subprocess.call( - [sys.executable, '-c', 'pass', '-W', 'always'], - env=env) - self.assertEqual(retcode, 0) + assert_python_ok('-c', 'pass', '-W', 'always', PYTHONPATH=cwd) class FinalizationTest(unittest.TestCase): def test_finalization(self): diff --git a/Lib/test/test_wave.py b/Lib/test/test_wave.py index 549ca8961516..3eff773bca37 100644 --- a/Lib/test/test_wave.py +++ b/Lib/test/test_wave.py @@ -6,10 +6,12 @@ import wave -class WavePCM8Test(audiotests.AudioWriteTests, - audiotests.AudioTestsWithSourceFile, - unittest.TestCase): +class WaveTest(audiotests.AudioWriteTests, + audiotests.AudioTestsWithSourceFile): module = wave + + +class WavePCM8Test(WaveTest, unittest.TestCase): sndfilename = 'pluck-pcm8.wav' sndfilenframes = 3307 nchannels = 2 @@ -26,10 +28,7 @@ class WavePCM8Test(audiotests.AudioWriteTests, """) -class WavePCM16Test(audiotests.AudioWriteTests, - audiotests.AudioTestsWithSourceFile, - unittest.TestCase): - module = wave +class WavePCM16Test(WaveTest, unittest.TestCase): sndfilename = 'pluck-pcm16.wav' sndfilenframes = 3307 nchannels = 2 @@ -50,10 +49,7 @@ class WavePCM16Test(audiotests.AudioWriteTests, frames = byteswap(frames, 2) -class WavePCM24Test(audiotests.AudioWriteTests, - audiotests.AudioTestsWithSourceFile, - unittest.TestCase): - module = wave +class WavePCM24Test(WaveTest, unittest.TestCase): sndfilename = 'pluck-pcm24.wav' sndfilenframes = 3307 nchannels = 2 @@ -80,10 +76,7 @@ class WavePCM24Test(audiotests.AudioWriteTests, frames = byteswap(frames, 3) -class WavePCM32Test(audiotests.AudioWriteTests, - audiotests.AudioTestsWithSourceFile, - unittest.TestCase): - module = wave +class WavePCM32Test(WaveTest, unittest.TestCase): sndfilename = 'pluck-pcm32.wav' sndfilenframes = 3307 nchannels = 2 diff --git a/Lib/test/test_weakref.py b/Lib/test/test_weakref.py index cccb51525273..e735376a67fc 100644 --- a/Lib/test/test_weakref.py +++ b/Lib/test/test_weakref.py @@ -92,6 +92,18 @@ def test_basic_callback(self): self.check_basic_callback(create_function) self.check_basic_callback(create_bound_method) + @support.cpython_only + def test_cfunction(self): + import _testcapi + create_cfunction = _testcapi.create_cfunction + f = create_cfunction() + wr = weakref.ref(f) + self.assertIs(wr(), f) + del f + self.assertIsNone(wr()) + self.check_basic_ref(create_cfunction) + self.check_basic_callback(create_cfunction) + def test_multiple_callbacks(self): o = C() ref1 = weakref.ref(o, self.callback) @@ -1298,6 +1310,36 @@ def check_weak_destroy_and_mutate_while_iterating(self, dict, testcontext): dict.clear() self.assertEqual(len(dict), 0) + def check_weak_del_and_len_while_iterating(self, dict, testcontext): + # Check that len() works when both iterating and removing keys + # explicitly through various means (.pop(), .clear()...), while + # implicit mutation is deferred because an iterator is alive. + # (each call to testcontext() should schedule one item for removal + # for this test to work properly) + o = Object(123456) + with testcontext(): + n = len(dict) + dict.popitem() + self.assertEqual(len(dict), n - 1) + dict[o] = o + self.assertEqual(len(dict), n) + with testcontext(): + self.assertEqual(len(dict), n - 1) + dict.pop(next(dict.keys())) + self.assertEqual(len(dict), n - 2) + with testcontext(): + self.assertEqual(len(dict), n - 3) + del dict[next(dict.keys())] + self.assertEqual(len(dict), n - 4) + with testcontext(): + self.assertEqual(len(dict), n - 5) + dict.popitem() + self.assertEqual(len(dict), n - 6) + with testcontext(): + dict.clear() + self.assertEqual(len(dict), 0) + self.assertEqual(len(dict), 0) + def test_weak_keys_destroy_while_iterating(self): # Issue #7105: iterators shouldn't crash when a key is implicitly removed dict, objects = self.make_weak_keyed_dict() @@ -1317,7 +1359,12 @@ def testcontext(): yield Object(v), v finally: it = None # should commit all removals + gc.collect() self.check_weak_destroy_and_mutate_while_iterating(dict, testcontext) + # Issue #21173: len() fragile when keys are both implicitly and + # explicitly removed. + dict, objects = self.make_weak_keyed_dict() + self.check_weak_del_and_len_while_iterating(dict, testcontext) def test_weak_values_destroy_while_iterating(self): # Issue #7105: iterators shouldn't crash when a key is implicitly removed @@ -1339,7 +1386,10 @@ def testcontext(): yield k, Object(k) finally: it = None # should commit all removals + gc.collect() self.check_weak_destroy_and_mutate_while_iterating(dict, testcontext) + dict, objects = self.make_weak_valued_dict() + self.check_weak_del_and_len_while_iterating(dict, testcontext) def test_make_weak_keyed_dict_from_dict(self): o = Object(3) @@ -1536,6 +1586,14 @@ def __eq__(self, other): self.assertEqual(len(d), 0) self.assertEqual(count, 2) + def test_make_weak_valued_dict_repr(self): + dict = weakref.WeakValueDictionary() + self.assertRegex(repr(dict), '') + + def test_make_weak_keyed_dict_repr(self): + dict = weakref.WeakKeyDictionary() + self.assertRegex(repr(dict), '') + from test import mapping_tests class WeakValueDictionaryTestCase(mapping_tests.BasicTestMappingProtocol): diff --git a/Lib/test/test_weakset.py b/Lib/test/test_weakset.py index 5b782dae9145..fb22879dfab9 100644 --- a/Lib/test/test_weakset.py +++ b/Lib/test/test_weakset.py @@ -370,10 +370,14 @@ def test_weak_destroy_and_mutate_while_iterating(self): def testcontext(): try: it = iter(s) - next(it) - del it + # Start iterator + yielded = ustr(str(next(it))) # Schedule an item for removal and recreate it u = ustr(str(items.pop())) + if yielded == u: + # The iterator still has a reference to the removed item, + # advance it (issue #20006). + next(it) gc.collect() # just in case yield u finally: diff --git a/Lib/test/test_winreg.py b/Lib/test/test_winreg.py index ef4ce552f1af..2c4ac08f390e 100644 --- a/Lib/test/test_winreg.py +++ b/Lib/test/test_winreg.py @@ -341,7 +341,7 @@ def test_setvalueex_value_range(self): def test_queryvalueex_return_value(self): # Test for Issue #16759, return unsigned int from QueryValueEx. # Reg2Py, which gets called by QueryValueEx, was returning a value - # generated by PyLong_FromLong. The implmentation now uses + # generated by PyLong_FromLong. The implementation now uses # PyLong_FromUnsignedLong to match DWORD's size. try: with CreateKey(HKEY_CURRENT_USER, test_key_name) as ck: @@ -354,6 +354,19 @@ def test_queryvalueex_return_value(self): finally: DeleteKey(HKEY_CURRENT_USER, test_key_name) + def test_setvalueex_crash_with_none_arg(self): + # Test for Issue #21151, segfault when None is passed to SetValueEx + try: + with CreateKey(HKEY_CURRENT_USER, test_key_name) as ck: + self.assertNotEqual(ck.handle, 0) + test_val = None + SetValueEx(ck, "test_name", 0, REG_BINARY, test_val) + ret_val, ret_type = QueryValueEx(ck, "test_name") + self.assertEqual(ret_type, REG_BINARY) + self.assertEqual(ret_val, test_val) + finally: + DeleteKey(HKEY_CURRENT_USER, test_key_name) + @unittest.skipUnless(REMOTE_NAME, "Skipping remote registry tests") diff --git a/Lib/test/test_winsound.py b/Lib/test/test_winsound.py index d8a617e64fbd..83618b6a4440 100644 --- a/Lib/test/test_winsound.py +++ b/Lib/test/test_winsound.py @@ -158,14 +158,15 @@ def test_alias_question(self): ) def test_alias_fallback(self): - if _have_soundcard(): + # In the absense of the ability to tell if a sound was actually + # played, this test has two acceptable outcomes: success (no error, + # sound was theoretically played; although as issue #19987 shows + # a box without a soundcard can "succeed") or RuntimeError. Any + # other error is a failure. + try: winsound.PlaySound('!"$%&/(#+*', winsound.SND_ALIAS) - else: - self.assertRaises( - RuntimeError, - winsound.PlaySound, - '!"$%&/(#+*', winsound.SND_ALIAS - ) + except RuntimeError: + pass def test_alias_nofallback(self): if _have_soundcard(): diff --git a/Lib/test/test_with.py b/Lib/test/test_with.py index e8cc8c056ec6..7068a809702d 100644 --- a/Lib/test/test_with.py +++ b/Lib/test/test_with.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - """Unit tests for the with statement specified in PEP 343.""" diff --git a/Lib/test/test_wsgiref.py b/Lib/test/test_wsgiref.py index 05c1f4fc2386..479fcbc5383c 100644 --- a/Lib/test/test_wsgiref.py +++ b/Lib/test/test_wsgiref.py @@ -118,6 +118,11 @@ def test_plain_hello(self): out, err = run_amock() self.check_hello(out) + def test_request_length(self): + out, err = run_amock(data=b"GET " + (b"x" * 65537) + b" HTTP/1.0\n\n") + self.assertEqual(out.splitlines()[0], + b"HTTP/1.0 414 Request-URI Too Long") + def test_validated_hello(self): out, err = run_amock(validator(hello_app)) # the middleware doesn't support len(), so content-length isn't there @@ -196,7 +201,7 @@ def checkDefault(self, key, value, alt=None): # Check existing value env = {key:alt} util.setup_testing_defaults(env) - self.assertTrue(env[key] is alt) + self.assertIs(env[key], alt) def checkCrossDefault(self,key,value,**kw): util.setup_testing_defaults(kw) @@ -286,7 +291,7 @@ def testGuessScheme(self): def testAppURIs(self): self.checkAppURI("http://127.0.0.1/") self.checkAppURI("http://127.0.0.1/spam", SCRIPT_NAME="/spam") - self.checkAppURI("http://127.0.0.1/sp%C3%A4m", SCRIPT_NAME="/späm") + self.checkAppURI("http://127.0.0.1/sp%E4m", SCRIPT_NAME="/sp\xe4m") self.checkAppURI("http://spam.example.com:2071/", HTTP_HOST="spam.example.com:2071", SERVER_PORT="2071") self.checkAppURI("http://spam.example.com/", @@ -300,15 +305,19 @@ def testAppURIs(self): def testReqURIs(self): self.checkReqURI("http://127.0.0.1/") self.checkReqURI("http://127.0.0.1/spam", SCRIPT_NAME="/spam") - self.checkReqURI("http://127.0.0.1/sp%C3%A4m", SCRIPT_NAME="/späm") + self.checkReqURI("http://127.0.0.1/sp%E4m", SCRIPT_NAME="/sp\xe4m") self.checkReqURI("http://127.0.0.1/spammity/spam", SCRIPT_NAME="/spammity", PATH_INFO="/spam") + self.checkReqURI("http://127.0.0.1/spammity/sp%E4m", + SCRIPT_NAME="/spammity", PATH_INFO="/sp\xe4m") self.checkReqURI("http://127.0.0.1/spammity/spam;ham", SCRIPT_NAME="/spammity", PATH_INFO="/spam;ham") self.checkReqURI("http://127.0.0.1/spammity/spam;cookie=1234,5678", SCRIPT_NAME="/spammity", PATH_INFO="/spam;cookie=1234,5678") self.checkReqURI("http://127.0.0.1/spammity/spam?say=ni", SCRIPT_NAME="/spammity", PATH_INFO="/spam",QUERY_STRING="say=ni") + self.checkReqURI("http://127.0.0.1/spammity/spam?s%E4y=ni", + SCRIPT_NAME="/spammity", PATH_INFO="/spam",QUERY_STRING="s%E4y=ni") self.checkReqURI("http://127.0.0.1/spammity/spam", 0, SCRIPT_NAME="/spammity", PATH_INFO="/spam",QUERY_STRING="say=ni") @@ -334,14 +343,15 @@ class HeaderTests(TestCase): def testMappingInterface(self): test = [('x','y')] + self.assertEqual(len(Headers()), 0) self.assertEqual(len(Headers([])),0) self.assertEqual(len(Headers(test[:])),1) self.assertEqual(Headers(test[:]).keys(), ['x']) self.assertEqual(Headers(test[:]).values(), ['y']) self.assertEqual(Headers(test[:]).items(), test) - self.assertFalse(Headers(test).items() is test) # must be copy! + self.assertIsNot(Headers(test).items(), test) # must be copy! - h=Headers([]) + h = Headers() del h['foo'] # should not raise an error h['Foo'] = 'bar' @@ -366,9 +376,8 @@ def testMappingInterface(self): def testRequireList(self): self.assertRaises(TypeError, Headers, "foo") - def testExtras(self): - h = Headers([]) + h = Headers() self.assertEqual(str(h),'\r\n') h.add_header('foo','bar',baz="spam") diff --git a/Lib/test/test_xdrlib.py b/Lib/test/test_xdrlib.py index 6004c9f1c67c..70496d63b43f 100644 --- a/Lib/test/test_xdrlib.py +++ b/Lib/test/test_xdrlib.py @@ -51,8 +51,32 @@ def test_xdr(self): up.done() self.assertRaises(EOFError, up.unpack_uint) +class ConversionErrorTest(unittest.TestCase): + + def setUp(self): + self.packer = xdrlib.Packer() + + def assertRaisesConversion(self, *args): + self.assertRaises(xdrlib.ConversionError, *args) + + def test_pack_int(self): + self.assertRaisesConversion(self.packer.pack_int, 'string') + + def test_pack_uint(self): + self.assertRaisesConversion(self.packer.pack_uint, 'string') + + def test_float(self): + self.assertRaisesConversion(self.packer.pack_float, 'string') + + def test_double(self): + self.assertRaisesConversion(self.packer.pack_double, 'string') + + def test_uhyper(self): + self.assertRaisesConversion(self.packer.pack_uhyper, 'string') + def test_main(): support.run_unittest(XDRTest) + support.run_unittest(ConversionErrorTest) if __name__ == "__main__": test_main() diff --git a/Lib/test/test_xml_dom_minicompat.py b/Lib/test/test_xml_dom_minicompat.py index 085e52aea396..47c4de62e056 100644 --- a/Lib/test/test_xml_dom_minicompat.py +++ b/Lib/test/test_xml_dom_minicompat.py @@ -84,18 +84,19 @@ def test_nodelist___radd__(self): def test_nodelist_pickle_roundtrip(self): # Test pickling and unpickling of a NodeList. - # Empty NodeList. - node_list = NodeList() - pickled = pickle.dumps(node_list) - unpickled = pickle.loads(pickled) - self.assertEqual(unpickled, node_list) - - # Non-empty NodeList. - node_list.append(1) - node_list.append(2) - pickled = pickle.dumps(node_list) - unpickled = pickle.loads(pickled) - self.assertEqual(unpickled, node_list) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + # Empty NodeList. + node_list = NodeList() + pickled = pickle.dumps(node_list, proto) + unpickled = pickle.loads(pickled) + self.assertEqual(unpickled, node_list) + + # Non-empty NodeList. + node_list.append(1) + node_list.append(2) + pickled = pickle.dumps(node_list, proto) + unpickled = pickle.loads(pickled) + self.assertEqual(unpickled, node_list) if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py index 89971f16ca53..d3c0da081d1f 100644 --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -121,11 +121,11 @@ class ElementTestCase: def setUpClass(cls): cls.modules = {pyET, ET} - def pickleRoundTrip(self, obj, name, dumper, loader): + def pickleRoundTrip(self, obj, name, dumper, loader, proto): save_m = sys.modules[name] try: sys.modules[name] = dumper - temp = pickle.dumps(obj) + temp = pickle.dumps(obj, proto) sys.modules[name] = loader result = pickle.loads(temp) except pickle.PicklingError as pe: @@ -1677,33 +1677,36 @@ def test_get_keyword_args(self): def test_pickle(self): # issue #16076: the C implementation wasn't pickleable. - for dumper, loader in product(self.modules, repeat=2): - e = dumper.Element('foo', bar=42) - e.text = "text goes here" - e.tail = "opposite of head" - dumper.SubElement(e, 'child').append(dumper.Element('grandchild')) - e.append(dumper.Element('child')) - e.findall('.//grandchild')[0].set('attr', 'other value') - - e2 = self.pickleRoundTrip(e, 'xml.etree.ElementTree', - dumper, loader) - - self.assertEqual(e2.tag, 'foo') - self.assertEqual(e2.attrib['bar'], 42) - self.assertEqual(len(e2), 2) - self.assertEqualElements(e, e2) + for proto in range(2, pickle.HIGHEST_PROTOCOL + 1): + for dumper, loader in product(self.modules, repeat=2): + e = dumper.Element('foo', bar=42) + e.text = "text goes here" + e.tail = "opposite of head" + dumper.SubElement(e, 'child').append(dumper.Element('grandchild')) + e.append(dumper.Element('child')) + e.findall('.//grandchild')[0].set('attr', 'other value') + + e2 = self.pickleRoundTrip(e, 'xml.etree.ElementTree', + dumper, loader, proto) + + self.assertEqual(e2.tag, 'foo') + self.assertEqual(e2.attrib['bar'], 42) + self.assertEqual(len(e2), 2) + self.assertEqualElements(e, e2) def test_pickle_issue18997(self): - for dumper, loader in product(self.modules, repeat=2): - XMLTEXT = """ - 4 - """ - e1 = dumper.fromstring(XMLTEXT) - if hasattr(e1, '__getstate__'): - self.assertEqual(e1.__getstate__()['tag'], 'group') - e2 = self.pickleRoundTrip(e1, 'xml.etree.ElementTree', dumper, loader) - self.assertEqual(e2.tag, 'group') - self.assertEqual(e2[0].tag, 'dogs') + for proto in range(2, pickle.HIGHEST_PROTOCOL + 1): + for dumper, loader in product(self.modules, repeat=2): + XMLTEXT = """ + 4 + """ + e1 = dumper.fromstring(XMLTEXT) + if hasattr(e1, '__getstate__'): + self.assertEqual(e1.__getstate__()['tag'], 'group') + e2 = self.pickleRoundTrip(e1, 'xml.etree.ElementTree', + dumper, loader, proto) + self.assertEqual(e2.tag, 'group') + self.assertEqual(e2[0].tag, 'dogs') class ElementTreeTypeTest(unittest.TestCase): diff --git a/Lib/test/test_xml_etree_c.py b/Lib/test/test_xml_etree_c.py index b3ff7ae37d9f..d0df38d3e68c 100644 --- a/Lib/test/test_xml_etree_c.py +++ b/Lib/test/test_xml_etree_c.py @@ -13,10 +13,8 @@ class MiscTests(unittest.TestCase): # Issue #8651. - @support.bigmemtest(size=support._2G + 100, memuse=1) + @support.bigmemtest(size=support._2G + 100, memuse=1, dry_run=False) def test_length_overflow(self, size): - if size < support._2G + 100: - self.skipTest("not enough free memory, need at least 2 GB") data = b'x' * size parser = cET.XMLParser() try: @@ -57,7 +55,7 @@ class SizeofTest(unittest.TestCase): def setUp(self): self.elementsize = support.calcobjsize('5P') # extra - self.extra = struct.calcsize('PiiP4P') + self.extra = struct.calcsize('PnnP4P') check_sizeof = support.check_sizeof diff --git a/Lib/test/test_xmlrpc.py b/Lib/test/test_xmlrpc.py index 99b3eda13ee4..dc37be2bf1a6 100644 --- a/Lib/test/test_xmlrpc.py +++ b/Lib/test/test_xmlrpc.py @@ -287,7 +287,7 @@ def test_datetime_datetime(self): def test_repr(self): d = datetime.datetime(2007,1,2,3,4,5) t = xmlrpclib.DateTime(d) - val ="" % id(t) + val ="" % id(t) self.assertEqual(repr(t), val) def test_decode(self): @@ -517,7 +517,7 @@ def is_unavailable_exception(e): return True def make_request_and_skipIf(condition, reason): - # If we skip the test, we have to make a request because the + # If we skip the test, we have to make a request because # the server created in setUp blocks expecting one to come in. if not condition: return lambda func: func @@ -713,6 +713,23 @@ def test_partial_post(self): conn.request('POST', '/RPC2 HTTP/1.0\r\nContent-Length: 100\r\n\r\nbye') conn.close() + def test_context_manager(self): + with xmlrpclib.ServerProxy(URL) as server: + server.add(2, 3) + self.assertNotEqual(server('transport')._connection, + (None, None)) + self.assertEqual(server('transport')._connection, + (None, None)) + + def test_context_manager_method_error(self): + try: + with xmlrpclib.ServerProxy(URL) as server: + server.add(2, "a") + except xmlrpclib.Fault: + pass + self.assertEqual(server('transport')._connection, + (None, None)) + class MultiPathServerTestCase(BaseServerTestCase): threadFunc = staticmethod(http_multi_server) @@ -863,7 +880,7 @@ def test_bad_gzip_request(self): p.pow(6, 8) p("close")() - def test_gsip_response(self): + def test_gzip_response(self): t = self.Transport() p = xmlrpclib.ServerProxy(URL, transport=t) old = self.requestHandler.encode_threshold @@ -877,6 +894,27 @@ def test_gsip_response(self): self.requestHandler.encode_threshold = old self.assertTrue(a>b) + +@unittest.skipIf(gzip is None, 'requires gzip') +class GzipUtilTestCase(unittest.TestCase): + + def test_gzip_decode_limit(self): + max_gzip_decode = 20 * 1024 * 1024 + data = b'\0' * max_gzip_decode + encoded = xmlrpclib.gzip_encode(data) + decoded = xmlrpclib.gzip_decode(encoded) + self.assertEqual(len(decoded), max_gzip_decode) + + data = b'\0' * (max_gzip_decode + 1) + encoded = xmlrpclib.gzip_encode(data) + + with self.assertRaisesRegex(ValueError, + "max gzipped payload length exceeded"): + xmlrpclib.gzip_decode(encoded) + + xmlrpclib.gzip_decode(encoded, max_decode=-1) + + #Test special attributes of the ServerProxy object class ServerProxyTestCase(unittest.TestCase): def setUp(self): @@ -898,6 +936,7 @@ def test_transport(self): p = xmlrpclib.ServerProxy(self.url, transport=t) self.assertEqual(p('transport'), t) + # This is a contrived way to make a failure occur on the server side # in order to test the _send_traceback_header flag on the server class FailingMessageClass(http.client.HTTPMessage): @@ -1105,7 +1144,7 @@ def test_main(): support.run_unittest(XMLRPCTestCase, HelperTestCase, DateTimeTestCase, BinaryTestCase, FaultTestCase, UseBuiltinTypesTestCase, SimpleServerTestCase, KeepaliveServerTestCase1, - KeepaliveServerTestCase2, GzipServerTestCase, + KeepaliveServerTestCase2, GzipServerTestCase, GzipUtilTestCase, MultiPathServerTestCase, ServerProxyTestCase, FailingServerTestCase, CGIHandlerTestCase) diff --git a/Lib/test/test_xmlrpc_net.py b/Lib/test/test_xmlrpc_net.py index 00aca199dfc7..b60b82f3e232 100644 --- a/Lib/test/test_xmlrpc_net.py +++ b/Lib/test/test_xmlrpc_net.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - import collections.abc import errno import socket @@ -19,7 +17,6 @@ def test_python_builders(self): builders = server.getAllBuilders() except OSError as e: self.skipTest("network error: %s" % e) - return self.addCleanup(lambda: server('close')()) # Perform a minimal sanity check on the result, just to be sure diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py index 49eccbb1d7da..f458f303ddab 100644 --- a/Lib/test/test_zipfile.py +++ b/Lib/test/test_zipfile.py @@ -1,9 +1,9 @@ +import contextlib import io import os import sys import importlib.util import time -import shutil import struct import zipfile import unittest @@ -12,7 +12,7 @@ from tempfile import TemporaryFile from random import randint, random, getrandbits -from test.support import (TESTFN, findfile, unlink, +from test.support import (TESTFN, findfile, unlink, rmtree, requires_zlib, requires_bz2, requires_lzma, captured_stdout, check_warnings) @@ -26,6 +26,9 @@ ('ziptest2dir/ziptest3dir/_ziptest3', 'azsxdcfvgb'), ('ziptest2dir/ziptest3dir/ziptest4dir/_ziptest3', '6y7u8i9o0p')] +def getrandbytes(size): + return getrandbits(8 * size).to_bytes(size, 'little') + def get_files(test): yield TESTFN2 with TemporaryFile() as f: @@ -290,13 +293,74 @@ def test_read_return_size(self): # than requested. for test_size in (1, 4095, 4096, 4097, 16384): file_size = test_size + 1 - junk = getrandbits(8 * file_size).to_bytes(file_size, 'little') + junk = getrandbytes(file_size) with zipfile.ZipFile(io.BytesIO(), "w", self.compression) as zipf: zipf.writestr('foo', junk) with zipf.open('foo', 'r') as fp: buf = fp.read(test_size) self.assertEqual(len(buf), test_size) + def test_truncated_zipfile(self): + fp = io.BytesIO() + with zipfile.ZipFile(fp, mode='w') as zipf: + zipf.writestr('strfile', self.data, compress_type=self.compression) + end_offset = fp.tell() + zipfiledata = fp.getvalue() + + fp = io.BytesIO(zipfiledata) + with zipfile.ZipFile(fp) as zipf: + with zipf.open('strfile') as zipopen: + fp.truncate(end_offset - 20) + with self.assertRaises(EOFError): + zipopen.read() + + fp = io.BytesIO(zipfiledata) + with zipfile.ZipFile(fp) as zipf: + with zipf.open('strfile') as zipopen: + fp.truncate(end_offset - 20) + with self.assertRaises(EOFError): + while zipopen.read(100): + pass + + fp = io.BytesIO(zipfiledata) + with zipfile.ZipFile(fp) as zipf: + with zipf.open('strfile') as zipopen: + fp.truncate(end_offset - 20) + with self.assertRaises(EOFError): + while zipopen.read1(100): + pass + + def test_repr(self): + fname = 'file.name' + for f in get_files(self): + with zipfile.ZipFile(f, 'w', self.compression) as zipfp: + zipfp.write(TESTFN, fname) + r = repr(zipfp) + self.assertIn("mode='w'", r) + + with zipfile.ZipFile(f, 'r') as zipfp: + r = repr(zipfp) + if isinstance(f, str): + self.assertIn('filename=%r' % f, r) + else: + self.assertIn('file=%r' % f, r) + self.assertIn("mode='r'", r) + r = repr(zipfp.getinfo(fname)) + self.assertIn('filename=%r' % fname, r) + self.assertIn('filemode=', r) + self.assertIn('file_size=', r) + if self.compression != zipfile.ZIP_STORED: + self.assertIn('compress_type=', r) + self.assertIn('compress_size=', r) + with zipfp.open(fname) as zipopen: + r = repr(zipopen) + self.assertIn('name=%r' % fname, r) + self.assertIn("mode='r'", r) + if self.compression != zipfile.ZIP_STORED: + self.assertIn('compress_type=', r) + self.assertIn('[closed]', repr(zipopen)) + self.assertIn('[closed]', repr(zipfp)) + def tearDown(self): unlink(TESTFN) unlink(TESTFN2) @@ -393,6 +457,7 @@ def test_add_file_before_1980(self): with zipfile.ZipFile(TESTFN2, "w") as zipfp: self.assertRaises(ValueError, zipfp.write, TESTFN) + @requires_zlib class DeflateTestsWithSourceFile(AbstractTestsWithSourceFile, unittest.TestCase): @@ -432,7 +497,9 @@ def setUpClass(cls): def setUp(self): self._limit = zipfile.ZIP64_LIMIT - zipfile.ZIP64_LIMIT = 5 + self._filecount_limit = zipfile.ZIP_FILECOUNT_LIMIT + zipfile.ZIP64_LIMIT = 1000 + zipfile.ZIP_FILECOUNT_LIMIT = 9 # Make a source file with some lines with open(TESTFN, "wb") as fp: @@ -499,8 +566,67 @@ def test_basic(self): for f in get_files(self): self.zip_test(f, self.compression) + def test_too_many_files(self): + # This test checks that more than 64k files can be added to an archive, + # and that the resulting archive can be read properly by ZipFile + zipf = zipfile.ZipFile(TESTFN, "w", self.compression, + allowZip64=True) + zipf.debug = 100 + numfiles = 15 + for i in range(numfiles): + zipf.writestr("foo%08d" % i, "%d" % (i**3 % 57)) + self.assertEqual(len(zipf.namelist()), numfiles) + zipf.close() + + zipf2 = zipfile.ZipFile(TESTFN, "r", self.compression) + self.assertEqual(len(zipf2.namelist()), numfiles) + for i in range(numfiles): + content = zipf2.read("foo%08d" % i).decode('ascii') + self.assertEqual(content, "%d" % (i**3 % 57)) + zipf2.close() + + def test_too_many_files_append(self): + zipf = zipfile.ZipFile(TESTFN, "w", self.compression, + allowZip64=False) + zipf.debug = 100 + numfiles = 9 + for i in range(numfiles): + zipf.writestr("foo%08d" % i, "%d" % (i**3 % 57)) + self.assertEqual(len(zipf.namelist()), numfiles) + with self.assertRaises(zipfile.LargeZipFile): + zipf.writestr("foo%08d" % numfiles, b'') + self.assertEqual(len(zipf.namelist()), numfiles) + zipf.close() + + zipf = zipfile.ZipFile(TESTFN, "a", self.compression, + allowZip64=False) + zipf.debug = 100 + self.assertEqual(len(zipf.namelist()), numfiles) + with self.assertRaises(zipfile.LargeZipFile): + zipf.writestr("foo%08d" % numfiles, b'') + self.assertEqual(len(zipf.namelist()), numfiles) + zipf.close() + + zipf = zipfile.ZipFile(TESTFN, "a", self.compression, + allowZip64=True) + zipf.debug = 100 + self.assertEqual(len(zipf.namelist()), numfiles) + numfiles2 = 15 + for i in range(numfiles, numfiles2): + zipf.writestr("foo%08d" % i, "%d" % (i**3 % 57)) + self.assertEqual(len(zipf.namelist()), numfiles2) + zipf.close() + + zipf2 = zipfile.ZipFile(TESTFN, "r", self.compression) + self.assertEqual(len(zipf2.namelist()), numfiles2) + for i in range(numfiles2): + content = zipf2.read("foo%08d" % i).decode('ascii') + self.assertEqual(content, "%d" % (i**3 % 57)) + zipf2.close() + def tearDown(self): zipfile.ZIP64_LIMIT = self._limit + zipfile.ZIP_FILECOUNT_LIMIT = self._filecount_limit unlink(TESTFN) unlink(TESTFN2) @@ -553,7 +679,14 @@ def assertCompiledIn(self, name, namelist): if name + 'o' not in namelist: self.assertIn(name + 'c', namelist) + def requiresWriteAccess(self, path): + # effective_ids unavailable on windows + if not os.access(path, os.W_OK, + effective_ids=os.access in os.supports_effective_ids): + self.skipTest('requires write access to the installed location') + def test_write_pyfile(self): + self.requiresWriteAccess(os.path.dirname(__file__)) with TemporaryFile() as t, zipfile.PyZipFile(t, "w") as zipfp: fn = __file__ if fn.endswith('.pyc') or fn.endswith('.pyo'): @@ -585,6 +718,7 @@ def test_write_pyfile(self): def test_write_python_package(self): import email packagedir = os.path.dirname(email.__file__) + self.requiresWriteAccess(packagedir) with TemporaryFile() as t, zipfile.PyZipFile(t, "w") as zipfp: zipfp.writepy(packagedir) @@ -598,6 +732,7 @@ def test_write_python_package(self): def test_write_filtered_python_package(self): import test packagedir = os.path.dirname(test.__file__) + self.requiresWriteAccess(packagedir) with TemporaryFile() as t, zipfile.PyZipFile(t, "w") as zipfp: @@ -615,7 +750,7 @@ def test_write_filtered_python_package(self): self.assertTrue('SyntaxError' not in reportStr) # then check that the filter works on individual files - with captured_stdout() as reportSIO: + with captured_stdout() as reportSIO, self.assertWarns(UserWarning): zipfp.writepy(packagedir, filterfunc=lambda fn: 'bad' not in fn) reportStr = reportSIO.getvalue() @@ -626,6 +761,7 @@ def test_write_filtered_python_package(self): def test_write_with_optimization(self): import email packagedir = os.path.dirname(email.__file__) + self.requiresWriteAccess(packagedir) # use .pyc if running test in optimization mode, # use .pyo if running test in debug mode optlevel = 1 if __debug__ else 0 @@ -660,7 +796,7 @@ def test_write_python_directory(self): self.assertNotIn('mod2.txt', names) finally: - shutil.rmtree(TESTFN2) + rmtree(TESTFN2) def test_write_python_directory_filtered(self): os.mkdir(TESTFN2) @@ -680,14 +816,14 @@ def test_write_python_directory_filtered(self): self.assertNotIn('mod2.py', names) finally: - shutil.rmtree(TESTFN2) + rmtree(TESTFN2) def test_write_non_pyfile(self): with TemporaryFile() as t, zipfile.PyZipFile(t, "w") as zipfp: with open(TESTFN, 'w') as f: f.write('most definitely not a python file') self.assertRaises(RuntimeError, zipfp.writepy, TESTFN) - os.remove(TESTFN) + unlink(TESTFN) def test_write_pyfile_bad_syntax(self): os.mkdir(TESTFN2) @@ -710,7 +846,7 @@ def test_write_pyfile_bad_syntax(self): self.assertNotIn('mod1.pyo', names) finally: - shutil.rmtree(TESTFN2) + rmtree(TESTFN2) class ExtractTests(unittest.TestCase): @@ -733,10 +869,10 @@ def test_extract(self): with open(writtenfile, "rb") as f: self.assertEqual(fdata.encode(), f.read()) - os.remove(writtenfile) + unlink(writtenfile) # remove the test file subdirectories - shutil.rmtree(os.path.join(os.getcwd(), 'ziptest2dir')) + rmtree(os.path.join(os.getcwd(), 'ziptest2dir')) def test_extract_all(self): with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp: @@ -751,10 +887,10 @@ def test_extract_all(self): with open(outfile, "rb") as f: self.assertEqual(fdata.encode(), f.read()) - os.remove(outfile) + unlink(outfile) # remove the test file subdirectories - shutil.rmtree(os.path.join(os.getcwd(), 'ziptest2dir')) + rmtree(os.path.join(os.getcwd(), 'ziptest2dir')) def check_file(self, filename, content): self.assertTrue(os.path.isfile(filename)) @@ -836,12 +972,12 @@ def _test_extract_hackers_arcnames(self, hacknames): msg='extract %r: %r != %r' % (arcname, writtenfile, correctfile)) self.check_file(correctfile, content) - shutil.rmtree('target') + rmtree('target') with zipfile.ZipFile(TESTFN2, 'r') as zipfp: zipfp.extractall(targetpath) self.check_file(correctfile, content) - shutil.rmtree('target') + rmtree('target') correctfile = os.path.join(os.getcwd(), *fixedname.split('/')) @@ -850,14 +986,14 @@ def _test_extract_hackers_arcnames(self, hacknames): self.assertEqual(writtenfile, correctfile, msg="extract %r" % arcname) self.check_file(correctfile, content) - shutil.rmtree(fixedname.split('/')[0]) + rmtree(fixedname.split('/')[0]) with zipfile.ZipFile(TESTFN2, 'r') as zipfp: zipfp.extractall() self.check_file(correctfile, content) - shutil.rmtree(fixedname.split('/')[0]) + rmtree(fixedname.split('/')[0]) - os.remove(TESTFN2) + unlink(TESTFN2) class OtherTests(unittest.TestCase): @@ -865,7 +1001,9 @@ def test_open_via_zip_info(self): # Create the ZIP archive with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp: zipfp.writestr("name", "foo") - zipfp.writestr("name", "bar") + with self.assertWarns(UserWarning): + zipfp.writestr("name", "bar") + self.assertEqual(zipfp.namelist(), ["name"] * 2) with zipfile.ZipFile(TESTFN2, "r") as zipfp: infos = zipfp.infolist() @@ -1182,7 +1320,8 @@ def test_comments(self): # check a comment that is too long is truncated with zipfile.ZipFile(TESTFN, mode="w") as zipf: - zipf.comment = comment2 + b'oops' + with self.assertWarns(UserWarning): + zipf.comment = comment2 + b'oops' zipf.writestr("foo.txt", "O, for a Muse of Fire!") with zipfile.ZipFile(TESTFN, mode="r") as zipfr: self.assertEqual(zipfr.comment, comment2) @@ -1256,6 +1395,21 @@ def test_create_zipinfo_before_1980(self): self.assertRaises(ValueError, zipfile.ZipInfo, 'seventies', (1979, 1, 1, 0, 0, 0)) + def test_zipfile_with_short_extra_field(self): + """If an extra field in the header is less than 4 bytes, skip it.""" + zipdata = ( + b'PK\x03\x04\x14\x00\x00\x00\x00\x00\x93\x9b\xad@\x8b\x9e' + b'\xd9\xd3\x01\x00\x00\x00\x01\x00\x00\x00\x03\x00\x03\x00ab' + b'c\x00\x00\x00APK\x01\x02\x14\x03\x14\x00\x00\x00\x00' + b'\x00\x93\x9b\xad@\x8b\x9e\xd9\xd3\x01\x00\x00\x00\x01\x00\x00' + b'\x00\x03\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x00' + b'\x00\x00\x00abc\x00\x00PK\x05\x06\x00\x00\x00\x00' + b'\x01\x00\x01\x003\x00\x00\x00%\x00\x00\x00\x00\x00' + ) + with zipfile.ZipFile(io.BytesIO(zipdata), 'r') as zipf: + # testzip returns the name of the first corrupt file, or None + self.assertIsNone(zipf.testzip()) + def tearDown(self): unlink(TESTFN) unlink(TESTFN2) @@ -1524,48 +1678,141 @@ class LzmaTestsWithRandomBinaryFiles(AbstractTestsWithRandomBinaryFiles, compression = zipfile.ZIP_LZMA +# Privide the tell() method but not seek() +class Tellable: + def __init__(self, fp): + self.fp = fp + self.offset = 0 + + def write(self, data): + self.offset += self.fp.write(data) + + def tell(self): + return self.offset + + def flush(self): + pass + +class UnseekableTests(unittest.TestCase): + def test_writestr_tellable(self): + f = io.BytesIO() + with zipfile.ZipFile(Tellable(f), 'w', zipfile.ZIP_STORED) as zipfp: + zipfp.writestr('ones', b'111') + zipfp.writestr('twos', b'222') + with zipfile.ZipFile(f, mode='r') as zipf: + with zipf.open('ones') as zopen: + self.assertEqual(zopen.read(), b'111') + with zipf.open('twos') as zopen: + self.assertEqual(zopen.read(), b'222') + + @requires_zlib class TestsWithMultipleOpens(unittest.TestCase): - def setUp(self): + @classmethod + def setUpClass(cls): + cls.data1 = b'111' + getrandbytes(10000) + cls.data2 = b'222' + getrandbytes(10000) + + def make_test_archive(self, f): # Create the ZIP archive - with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_DEFLATED) as zipfp: - zipfp.writestr('ones', '1'*FIXEDTEST_SIZE) - zipfp.writestr('twos', '2'*FIXEDTEST_SIZE) + with zipfile.ZipFile(f, "w", zipfile.ZIP_DEFLATED) as zipfp: + zipfp.writestr('ones', self.data1) + zipfp.writestr('twos', self.data2) def test_same_file(self): # Verify that (when the ZipFile is in control of creating file objects) # multiple open() calls can be made without interfering with each other. - with zipfile.ZipFile(TESTFN2, mode="r") as zipf: - with zipf.open('ones') as zopen1, zipf.open('ones') as zopen2: - data1 = zopen1.read(500) - data2 = zopen2.read(500) - data1 += zopen1.read(500) - data2 += zopen2.read(500) - self.assertEqual(data1, data2) + for f in get_files(self): + self.make_test_archive(f) + with zipfile.ZipFile(f, mode="r") as zipf: + with zipf.open('ones') as zopen1, zipf.open('ones') as zopen2: + data1 = zopen1.read(500) + data2 = zopen2.read(500) + data1 += zopen1.read() + data2 += zopen2.read() + self.assertEqual(data1, data2) + self.assertEqual(data1, self.data1) def test_different_file(self): # Verify that (when the ZipFile is in control of creating file objects) # multiple open() calls can be made without interfering with each other. - with zipfile.ZipFile(TESTFN2, mode="r") as zipf: - with zipf.open('ones') as zopen1, zipf.open('twos') as zopen2: - data1 = zopen1.read(500) - data2 = zopen2.read(500) - data1 += zopen1.read(500) - data2 += zopen2.read(500) - self.assertEqual(data1, b'1'*FIXEDTEST_SIZE) - self.assertEqual(data2, b'2'*FIXEDTEST_SIZE) + for f in get_files(self): + self.make_test_archive(f) + with zipfile.ZipFile(f, mode="r") as zipf: + with zipf.open('ones') as zopen1, zipf.open('twos') as zopen2: + data1 = zopen1.read(500) + data2 = zopen2.read(500) + data1 += zopen1.read() + data2 += zopen2.read() + self.assertEqual(data1, self.data1) + self.assertEqual(data2, self.data2) def test_interleaved(self): # Verify that (when the ZipFile is in control of creating file objects) # multiple open() calls can be made without interfering with each other. - with zipfile.ZipFile(TESTFN2, mode="r") as zipf: - with zipf.open('ones') as zopen1, zipf.open('twos') as zopen2: + for f in get_files(self): + self.make_test_archive(f) + with zipfile.ZipFile(f, mode="r") as zipf: + with zipf.open('ones') as zopen1, zipf.open('twos') as zopen2: + data1 = zopen1.read(500) + data2 = zopen2.read(500) + data1 += zopen1.read() + data2 += zopen2.read() + self.assertEqual(data1, self.data1) + self.assertEqual(data2, self.data2) + + def test_read_after_close(self): + for f in get_files(self): + self.make_test_archive(f) + with contextlib.ExitStack() as stack: + with zipfile.ZipFile(f, 'r') as zipf: + zopen1 = stack.enter_context(zipf.open('ones')) + zopen2 = stack.enter_context(zipf.open('twos')) data1 = zopen1.read(500) data2 = zopen2.read(500) - data1 += zopen1.read(500) - data2 += zopen2.read(500) - self.assertEqual(data1, b'1'*FIXEDTEST_SIZE) - self.assertEqual(data2, b'2'*FIXEDTEST_SIZE) + data1 += zopen1.read() + data2 += zopen2.read() + self.assertEqual(data1, self.data1) + self.assertEqual(data2, self.data2) + + def test_read_after_write(self): + for f in get_files(self): + with zipfile.ZipFile(f, 'w', zipfile.ZIP_DEFLATED) as zipf: + zipf.writestr('ones', self.data1) + zipf.writestr('twos', self.data2) + with zipf.open('ones') as zopen1: + data1 = zopen1.read(500) + self.assertEqual(data1, self.data1[:500]) + with zipfile.ZipFile(f, 'r') as zipf: + data1 = zipf.read('ones') + data2 = zipf.read('twos') + self.assertEqual(data1, self.data1) + self.assertEqual(data2, self.data2) + + def test_write_after_read(self): + for f in get_files(self): + with zipfile.ZipFile(f, "w", zipfile.ZIP_DEFLATED) as zipf: + zipf.writestr('ones', self.data1) + with zipf.open('ones') as zopen1: + zopen1.read(500) + zipf.writestr('twos', self.data2) + with zipfile.ZipFile(f, 'r') as zipf: + data1 = zipf.read('ones') + data2 = zipf.read('twos') + self.assertEqual(data1, self.data1) + self.assertEqual(data2, self.data2) + + def test_many_opens(self): + # Verify that read() and open() promptly close the file descriptor, + # and don't rely on the garbage collector to free resources. + self.make_test_archive(TESTFN2) + with zipfile.ZipFile(TESTFN2, mode="r") as zipf: + for x in range(100): + zipf.read('ones') + with zipf.open('ones') as zopen1: + pass + with open(os.devnull) as f: + self.assertLess(f.fileno(), 100) def tearDown(self): unlink(TESTFN2) @@ -1587,14 +1834,51 @@ def test_bug_6050(self): os.mkdir(os.path.join(TESTFN2, "a")) self.test_extract_dir() - def test_store_dir(self): + def test_write_dir(self): + dirpath = os.path.join(TESTFN2, "x") + os.mkdir(dirpath) + mode = os.stat(dirpath).st_mode & 0xFFFF + with zipfile.ZipFile(TESTFN, "w") as zipf: + zipf.write(dirpath) + zinfo = zipf.filelist[0] + self.assertTrue(zinfo.filename.endswith("/x/")) + self.assertEqual(zinfo.external_attr, (mode << 16) | 0x10) + zipf.write(dirpath, "y") + zinfo = zipf.filelist[1] + self.assertTrue(zinfo.filename, "y/") + self.assertEqual(zinfo.external_attr, (mode << 16) | 0x10) + with zipfile.ZipFile(TESTFN, "r") as zipf: + zinfo = zipf.filelist[0] + self.assertTrue(zinfo.filename.endswith("/x/")) + self.assertEqual(zinfo.external_attr, (mode << 16) | 0x10) + zinfo = zipf.filelist[1] + self.assertTrue(zinfo.filename, "y/") + self.assertEqual(zinfo.external_attr, (mode << 16) | 0x10) + target = os.path.join(TESTFN2, "target") + os.mkdir(target) + zipf.extractall(target) + self.assertTrue(os.path.isdir(os.path.join(target, "y"))) + self.assertEqual(len(os.listdir(target)), 2) + + def test_writestr_dir(self): os.mkdir(os.path.join(TESTFN2, "x")) - zipf = zipfile.ZipFile(TESTFN, "w") - zipf.write(os.path.join(TESTFN2, "x"), "x") - self.assertTrue(zipf.filelist[0].filename.endswith("x/")) + with zipfile.ZipFile(TESTFN, "w") as zipf: + zipf.writestr("x/", b'') + zinfo = zipf.filelist[0] + self.assertEqual(zinfo.filename, "x/") + self.assertEqual(zinfo.external_attr, (0o40775 << 16) | 0x10) + with zipfile.ZipFile(TESTFN, "r") as zipf: + zinfo = zipf.filelist[0] + self.assertTrue(zinfo.filename.endswith("x/")) + self.assertEqual(zinfo.external_attr, (0o40775 << 16) | 0x10) + target = os.path.join(TESTFN2, "target") + os.mkdir(target) + zipf.extractall(target) + self.assertTrue(os.path.isdir(os.path.join(target, "x"))) + self.assertEqual(os.listdir(target), ["x"]) def tearDown(self): - shutil.rmtree(TESTFN2) + rmtree(TESTFN2) if os.path.exists(TESTFN): unlink(TESTFN) @@ -1707,7 +1991,7 @@ def test_iterlines(self): def tearDown(self): for sep, fn in self.arcfiles.items(): - os.remove(fn) + unlink(fn) unlink(TESTFN) unlink(TESTFN2) diff --git a/Lib/test/test_zipfile64.py b/Lib/test/test_zipfile64.py index 498d464db3e2..7dea8a32120a 100644 --- a/Lib/test/test_zipfile64.py +++ b/Lib/test/test_zipfile64.py @@ -18,7 +18,7 @@ from io import StringIO from tempfile import TemporaryFile -from test.support import TESTFN, run_unittest, requires_zlib +from test.support import TESTFN, requires_zlib TESTFN2 = TESTFN + "2" @@ -92,7 +92,7 @@ class OtherTests(unittest.TestCase): def testMoreThan64kFiles(self): # This test checks that more than 64k files can be added to an archive, # and that the resulting archive can be read properly by ZipFile - zipf = zipfile.ZipFile(TESTFN, mode="w", allowZip64=False) + zipf = zipfile.ZipFile(TESTFN, mode="w", allowZip64=True) zipf.debug = 100 numfiles = (1 << 16) * 3//2 for i in range(numfiles): @@ -105,14 +105,47 @@ def testMoreThan64kFiles(self): for i in range(numfiles): content = zipf2.read("foo%08d" % i).decode('ascii') self.assertEqual(content, "%d" % (i**3 % 57)) + zipf2.close() + + def testMoreThan64kFilesAppend(self): + zipf = zipfile.ZipFile(TESTFN, mode="w", allowZip64=False) + zipf.debug = 100 + numfiles = (1 << 16) - 1 + for i in range(numfiles): + zipf.writestr("foo%08d" % i, "%d" % (i**3 % 57)) + self.assertEqual(len(zipf.namelist()), numfiles) + with self.assertRaises(zipfile.LargeZipFile): + zipf.writestr("foo%08d" % numfiles, b'') + self.assertEqual(len(zipf.namelist()), numfiles) zipf.close() + zipf = zipfile.ZipFile(TESTFN, mode="a", allowZip64=False) + zipf.debug = 100 + self.assertEqual(len(zipf.namelist()), numfiles) + with self.assertRaises(zipfile.LargeZipFile): + zipf.writestr("foo%08d" % numfiles, b'') + self.assertEqual(len(zipf.namelist()), numfiles) + zipf.close() + + zipf = zipfile.ZipFile(TESTFN, mode="a", allowZip64=True) + zipf.debug = 100 + self.assertEqual(len(zipf.namelist()), numfiles) + numfiles2 = (1 << 16) * 3//2 + for i in range(numfiles, numfiles2): + zipf.writestr("foo%08d" % i, "%d" % (i**3 % 57)) + self.assertEqual(len(zipf.namelist()), numfiles2) + zipf.close() + + zipf2 = zipfile.ZipFile(TESTFN, mode="r") + self.assertEqual(len(zipf2.namelist()), numfiles2) + for i in range(numfiles2): + content = zipf2.read("foo%08d" % i).decode('ascii') + self.assertEqual(content, "%d" % (i**3 % 57)) + zipf2.close() + def tearDown(self): support.unlink(TESTFN) support.unlink(TESTFN2) -def test_main(): - run_unittest(TestsWithSourceFile, OtherTests) - if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_zipimport.py b/Lib/test/test_zipimport.py index 3f16041f511f..1e351c8c8a16 100644 --- a/Lib/test/test_zipimport.py +++ b/Lib/test/test_zipimport.py @@ -136,7 +136,7 @@ def testAFakeZlib(self): # so we'll simply skip it then. Bug #765456. # if "zlib" in sys.builtin_module_names: - return + self.skipTest('zlib is a builtin module') if "zlib" in sys.modules: del sys.modules["zlib"] files = {"zlib.py": (NOW, test_src)} diff --git a/Lib/test/test_zipimport_support.py b/Lib/test/test_zipimport_support.py index 84ba5e047a36..2e801a8119ee 100644 --- a/Lib/test/test_zipimport_support.py +++ b/Lib/test/test_zipimport_support.py @@ -39,7 +39,7 @@ def _run_object_doctest(obj, module): # Use the object's fully qualified name if it has one # Otherwise, use the module's name try: - name = "%s.%s" % (obj.__module__, obj.__name__) + name = "%s.%s" % (obj.__module__, obj.__qualname__) except AttributeError: name = module.__name__ for example in finder.find(obj, name, module): @@ -57,7 +57,7 @@ class ZipSupportTests(unittest.TestCase): # This used to use the ImportHooksBaseTestCase to restore # the state of the import related information # in the sys module after each test. However, that restores - # *too much* information and breaks for the invocation of + # *too much* information and breaks for the invocation # of test_doctest. So we do our own thing and leave # sys.modules alone. # We also clear the linecache and zipimport cache diff --git a/Lib/test/time_hashlib.py b/Lib/test/time_hashlib.py index d9394630638d..2585ecb78207 100644 --- a/Lib/test/time_hashlib.py +++ b/Lib/test/time_hashlib.py @@ -1,7 +1,8 @@ # It's intended that this script be run by hand. It runs speed tests on # hashlib functions; it does not test for correctness. -import sys, time +import sys +import time import hashlib @@ -9,8 +10,8 @@ def creatorFunc(): raise RuntimeError("eek, creatorFunc not overridden") def test_scaled_msg(scale, name): - iterations = 106201/scale * 20 - longStr = 'Z'*scale + iterations = 106201//scale * 20 + longStr = b'Z'*scale localCF = creatorFunc start = time.time() diff --git a/Lib/threading.py b/Lib/threading.py index d907c89f3fce..24cc911c203c 100644 --- a/Lib/threading.py +++ b/Lib/threading.py @@ -3,14 +3,10 @@ import sys as _sys import _thread -from time import sleep as _sleep -try: - from time import monotonic as _time -except ImportError: - from time import time as _time +from time import monotonic as _time from traceback import format_exc as _format_exc from _weakrefset import WeakSet -from itertools import islice as _islice +from itertools import islice as _islice, count as _count try: from _collections import deque as _deque except ImportError: @@ -107,8 +103,14 @@ def __repr__(self): owner = _active[owner].name except KeyError: pass - return "<%s owner=%r count=%d>" % ( - self.__class__.__name__, owner, self._count) + return "<%s %s.%s object owner=%r count=%d at %s>" % ( + "locked" if self._block.locked() else "unlocked", + self.__class__.__module__, + self.__class__.__qualname__, + owner, + self._count, + hex(id(self)) + ) def acquire(self, blocking=True, timeout=-1): """Acquire a lock, blocking or non-blocking. @@ -249,7 +251,7 @@ def _acquire_restore(self, x): def _is_owned(self): # Return True if lock is owned by current_thread. - # This method is called only if __lock doesn't have _is_owned(). + # This method is called only if _lock doesn't have _is_owned(). if self._lock.acquire(0): self._lock.release() return False @@ -285,6 +287,7 @@ def wait(self, timeout=None): waiter.acquire() self._waiters.append(waiter) saved_state = self._release_save() + gotit = False try: # restore state no matter what (e.g., KeyboardInterrupt) if timeout is None: waiter.acquire() @@ -294,14 +297,14 @@ def wait(self, timeout=None): gotit = waiter.acquire(True, timeout) else: gotit = waiter.acquire(False) - if not gotit: - try: - self._waiters.remove(waiter) - except ValueError: - pass return gotit finally: self._acquire_restore(saved_state) + if not gotit: + try: + self._waiters.remove(waiter) + except ValueError: + pass def wait_for(self, predicate, timeout=None): """Wait until a condition evaluates to True. @@ -726,11 +729,10 @@ class BrokenBarrierError(RuntimeError): # Helper to generate new thread names -_counter = 0 +_counter = _count().__next__ +_counter() # Consume 0 so first non-main thread has id 1. def _newname(template="Thread-%d"): - global _counter - _counter += 1 - return template % _counter + return template % _counter() # Active thread administration _active_limbo_lock = _allocate_lock() @@ -749,12 +751,12 @@ class Thread: """ - __initialized = False + _initialized = False # Need to store a reference to sys.exc_info for printing # out exceptions when a thread tries to use a global var. during interp. # shutdown and thus raises an exception about trying to perform some # operation on/with a NoneType - __exc_info = _sys.exc_info + _exc_info = _sys.exc_info # Keep sys.exc_clear too to clear the exception just before # allowing .join() to return. #XXX __exc_clear = _sys.exc_clear @@ -926,10 +928,10 @@ def _bootstrap_inner(self): # shutdown) use self._stderr. Otherwise still use sys (as in # _sys) in case sys.stderr was redefined since the creation of # self. - if _sys: - _sys.stderr.write("Exception in thread %s:\n%s\n" % - (self.name, _format_exc())) - else: + if _sys and _sys.stderr is not None: + print("Exception in thread %s:\n%s" % + (self.name, _format_exc()), file=self._stderr) + elif self._stderr is not None: # Do the best job possible w/o a huge amt. of code to # approximate a traceback (code ideas from # Lib/traceback.py) @@ -957,7 +959,7 @@ def _bootstrap_inner(self): # test_threading.test_no_refcycle_through_target when # the exception keeps the target alive past when we # assert that it's dead. - #XXX self.__exc_clear() + #XXX self._exc_clear() pass finally: with _active_limbo_lock: @@ -1143,7 +1145,7 @@ def daemon(self, daemonic): if not self._initialized: raise RuntimeError("Thread.__init__() not called") if self._started.is_set(): - raise RuntimeError("cannot set daemon status of active thread"); + raise RuntimeError("cannot set daemon status of active thread") self._daemonic = daemonic def isDaemon(self): diff --git a/Lib/timeit.py b/Lib/timeit.py old mode 100644 new mode 100755 index ead203051524..38077941fe89 --- a/Lib/timeit.py +++ b/Lib/timeit.py @@ -60,6 +60,8 @@ default_repeat = 3 default_timer = time.perf_counter +_globals = globals + # Don't change the indentation of the template; the reindent() calls # in Timer.__init__() depend on setup being indented 4 spaces and stmt # being indented 8 spaces. @@ -94,7 +96,9 @@ class Timer: The constructor takes a statement to be timed, an additional statement used for setup, and a timer function. Both statements default to 'pass'; the timer function is platform-dependent (see - module doc string). + module doc string). If 'globals' is specified, the code will be + executed within that namespace (as opposed to inside timeit's + namespace). To measure the execution time of the first statement, use the timeit() method. The repeat() method is a convenience to call @@ -104,30 +108,38 @@ class Timer: multi-line string literals. """ - def __init__(self, stmt="pass", setup="pass", timer=default_timer): + def __init__(self, stmt="pass", setup="pass", timer=default_timer, + globals=None): """Constructor. See class doc string.""" self.timer = timer - ns = {} + local_ns = {} + global_ns = _globals() if globals is None else globals if isinstance(stmt, str): + # Check that the code can be compiled outside a function + if isinstance(setup, str): + compile(setup, dummy_src_name, "exec") + compile(setup + '\n' + stmt, dummy_src_name, "exec") + else: + compile(stmt, dummy_src_name, "exec") stmt = reindent(stmt, 8) if isinstance(setup, str): setup = reindent(setup, 4) src = template.format(stmt=stmt, setup=setup) elif callable(setup): src = template.format(stmt=stmt, setup='_setup()') - ns['_setup'] = setup + local_ns['_setup'] = setup else: raise ValueError("setup is neither a string nor callable") - self.src = src # Save for traceback display + self.src = src # Save for traceback display code = compile(src, dummy_src_name, "exec") - exec(code, globals(), ns) - self.inner = ns["inner"] + exec(code, global_ns, local_ns) + self.inner = local_ns["inner"] elif callable(stmt): self.src = None if isinstance(setup, str): _setup = setup def setup(): - exec(_setup, globals(), ns) + exec(_setup, global_ns, local_ns) elif not callable(setup): raise ValueError("setup is neither a string nor callable") self.inner = _template_func(setup, stmt) @@ -208,14 +220,14 @@ def repeat(self, repeat=default_repeat, number=default_number): return r def timeit(stmt="pass", setup="pass", timer=default_timer, - number=default_number): + number=default_number, globals=None): """Convenience function to create Timer object and call timeit method.""" - return Timer(stmt, setup, timer).timeit(number) + return Timer(stmt, setup, timer, globals).timeit(number) def repeat(stmt="pass", setup="pass", timer=default_timer, - repeat=default_repeat, number=default_number): + repeat=default_repeat, number=default_number, globals=None): """Convenience function to create Timer object and call repeat method.""" - return Timer(stmt, setup, timer).repeat(repeat, number) + return Timer(stmt, setup, timer, globals).repeat(repeat, number) def main(args=None, *, _wrap_timer=None): """Main program, used when run as a script. diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py index 22a41acc0da3..beb0a73d00de 100644 --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -35,8 +35,6 @@ # Attempt to configure Tcl/Tk without requiring PATH from tkinter import _fix -import warnings - import _tkinter # If this fails your Python may not be configured for Tk TclError = _tkinter.TclError from tkinter.constants import * @@ -114,6 +112,29 @@ def _cnfmerge(cnfs): try: _cnfmerge = _tkinter._cnfmerge except AttributeError: pass +def _splitdict(tk, v, cut_minus=True, conv=None): + """Return a properly formatted dict built from Tcl list pairs. + + If cut_minus is True, the supposed '-' prefix will be removed from + keys. If conv is specified, it is used to convert values. + + Tcl list is expected to contain an even number of elements. + """ + t = tk.splitlist(v) + if len(t) % 2: + raise RuntimeError('Tcl list representing a dict is expected ' + 'to contain an even number of elements') + it = iter(t) + dict = {} + for key, value in zip(it, it): + key = str(key) + if cut_minus and key[0] == '-': + key = key[1:] + if conv: + value = conv(value) + dict[key] = value + return dict + class Event: """Container for the properties of an event. @@ -193,6 +214,7 @@ class Variable: that constrain the type of the value returned from get().""" _default = "" _tk = None + _tclCommands = None def __init__(self, master=None, value=None, name=None): """Construct a variable @@ -211,7 +233,7 @@ def __init__(self, master=None, value=None, name=None): global _varnum if not master: master = _default_root - self._master = master + self._root = master._root() self._tk = master.tk if name: self._name = name @@ -220,13 +242,19 @@ def __init__(self, master=None, value=None, name=None): _varnum += 1 if value is not None: self.initialize(value) - elif not self._tk.call("info", "exists", self._name): + elif not self._tk.getboolean(self._tk.call("info", "exists", self._name)): self.initialize(self._default) def __del__(self): """Unset the variable in Tcl.""" - if (self._tk is not None and self._tk.call("info", "exists", - self._name)): + if self._tk is None: + return + if self._tk.getboolean(self._tk.call("info", "exists", self._name)): self._tk.globalunsetvar(self._name) + if self._tclCommands is not None: + for name in self._tclCommands: + #print '- Tkinter: deleted command', name + self._tk.deletecommand(name) + self._tclCommands = None def __str__(self): """Return the name of the variable in Tcl.""" return self._name @@ -246,7 +274,20 @@ def trace_variable(self, mode, callback): Return the name of the callback. """ - cbname = self._master._register(callback) + f = CallWrapper(callback, None, self).__call__ + cbname = repr(id(f)) + try: + callback = callback.__func__ + except AttributeError: + pass + try: + cbname = cbname + callback.__name__ + except AttributeError: + pass + self._tk.createcommand(cbname, f) + if self._tclCommands is None: + self._tclCommands = [] + self._tclCommands.append(cbname) self._tk.call("trace", "variable", self._name, mode, cbname) return cbname trace = trace_variable @@ -257,7 +298,11 @@ def trace_vdelete(self, mode, cbname): CBNAME is the name of the callback returned from trace_variable or trace. """ self._tk.call("trace", "vdelete", self._name, mode, cbname) - self._master.deletecommand(cbname) + self._tk.deletecommand(cbname) + try: + self._tclCommands.remove(cbname) + except ValueError: + pass def trace_vinfo(self): """Return all trace callback information.""" return [self._tk.split(x) for x in self._tk.splitlist( @@ -423,7 +468,10 @@ def tk_setPalette(self, *args, **kw): + _flatten(args) + _flatten(list(kw.items()))) def tk_menuBar(self, *args): """Do not use. Needed in Tk 3.6 and earlier.""" - pass # obsolete since Tk 4.0 + # obsolete since Tk 4.0 + import warnings + warnings.warn('tk_menuBar() does nothing and will be removed in 3.6', + DeprecationWarning, stacklevel=2) def wait_variable(self, name='PY_VAR'): """Wait until the variable is modified. @@ -537,6 +585,7 @@ def callit(): self.deletecommand(name) except TclError: pass + callit.__name__ = func.__name__ name = self._register(callit) return self.tk.call('after', ms, name) def after_idle(self, func, *args): @@ -721,9 +770,6 @@ def tkraise(self, aboveThis=None): """Raise this widget in the stacking order.""" self.tk.call('raise', self._w, aboveThis) lift = tkraise - def colormodel(self, value=None): - """Useless. Not implemented in Tk.""" - return self.tk.call('tk', 'colormodel', self._w, value) def winfo_atom(self, name, displayof=0): """Return integer which represents atom NAME.""" args = ('winfo', 'atom') + self._displayof(displayof) + (name,) @@ -1235,6 +1281,19 @@ def _report_exception(self): exc, val, tb = sys.exc_info() root = self._root() root.report_callback_exception(exc, val, tb) + + def _getconfigure(self, *args): + """Call Tcl configure command and return the result as a dict.""" + cnf = {} + for x in self.tk.splitlist(self.tk.call(*args)): + x = self.tk.splitlist(x) + cnf[x[0][1:]] = (x[0][1:],) + x[1:] + return cnf + + def _getconfigure1(self, *args): + x = self.tk.splitlist(self.tk.call(*args)) + return (x[0][1:],) + x[1:] + def _configure(self, cmd, cnf, kw): """Internal function.""" if kw: @@ -1242,15 +1301,9 @@ def _configure(self, cmd, cnf, kw): elif cnf: cnf = _cnfmerge(cnf) if cnf is None: - cnf = {} - for x in self.tk.split( - self.tk.call(_flatten((self._w, cmd)))): - cnf[x[0][1:]] = (x[0][1:],) + x[1:] - return cnf + return self._getconfigure(_flatten((self._w, cmd))) if isinstance(cnf, str): - x = self.tk.split( - self.tk.call(_flatten((self._w, cmd, '-'+cnf)))) - return (x[0][1:],) + x[1:] + return self._getconfigure1(_flatten((self._w, cmd, '-'+cnf))) self.tk.call(_flatten((self._w, cmd)) + self._options(cnf)) # These used to be defined in Widget: def configure(self, cnf=None, **kw): @@ -1271,10 +1324,15 @@ def __setitem__(self, key, value): def keys(self): """Return a list of all resource names of this widget.""" return [x[0][1:] for x in - self.tk.split(self.tk.call(self._w, 'configure'))] + self.tk.splitlist(self.tk.call(self._w, 'configure'))] def __str__(self): """Return the window path name of this widget.""" return self._w + + def __repr__(self): + return '<%s.%s object %s>' % ( + self.__class__.__module__, self.__class__.__qualname__, self._w) + # Pack methods that apply to the master _noarg_ = ['_noarg_'] def pack_propagate(self, flag=_noarg_): @@ -1332,6 +1390,21 @@ def grid_bbox(self, column=None, row=None, col2=None, row2=None): args = args + (col2, row2) return self._getints(self.tk.call(*args)) or None bbox = grid_bbox + + def _gridconvvalue(self, value): + if isinstance(value, (str, _tkinter.Tcl_Obj)): + try: + svalue = str(value) + if not svalue: + return None + elif '.' in svalue: + return getdouble(svalue) + else: + return getint(svalue) + except ValueError: + pass + return value + def _grid_configure(self, command, index, cnf, kw): """Internal function.""" if isinstance(cnf, str) and not kw: @@ -1343,29 +1416,16 @@ def _grid_configure(self, command, index, cnf, kw): else: options = self._options(cnf, kw) if not options: - res = self.tk.call('grid', - command, self._w, index) - words = self.tk.splitlist(res) - dict = {} - for i in range(0, len(words), 2): - key = words[i][1:] - value = words[i+1] - if not value: - value = None - elif '.' in str(value): - value = getdouble(value) - else: - value = getint(value) - dict[key] = value - return dict + return _splitdict( + self.tk, + self.tk.call('grid', command, self._w, index), + conv=self._gridconvvalue) res = self.tk.call( ('grid', command, self._w, index) + options) if len(options) == 1: - if not res: return None - # In Tk 7.5, -width can be a float - if '.' in res: return getdouble(res) - return getint(res) + return self._gridconvvalue(res) + def grid_columnconfigure(self, index, cnf={}, **kw): """Configure column INDEX of a grid. @@ -1452,11 +1512,11 @@ def event_info(self, virtual=None): def image_names(self): """Return a list of all existing image names.""" - return self.tk.call('image', 'names') + return self.tk.splitlist(self.tk.call('image', 'names')) def image_types(self): """Return a list of all available image types (e.g. phote bitmap).""" - return self.tk.call('image', 'types') + return self.tk.splitlist(self.tk.call('image', 'types')) class CallWrapper: @@ -1570,7 +1630,11 @@ def wm_colormapwindows(self, *wlist): if len(wlist) > 1: wlist = (wlist,) # Tk needs a list of windows here args = ('wm', 'colormapwindows', self._w) + wlist - return [self._nametowidget(x) for x in self.tk.call(args)] + if wlist: + self.tk.call(args) + else: + return [self._nametowidget(x) + for x in self.tk.splitlist(self.tk.call(args))] colormapwindows = wm_colormapwindows def wm_command(self, value=None): """Store VALUE in WM_COMMAND property. It is the command @@ -1855,9 +1919,12 @@ def readprofile(self, baseName, className): if os.path.isfile(base_py): exec(open(base_py).read(), dir) def report_callback_exception(self, exc, val, tb): - """Internal function. It reports exception on sys.stderr.""" + """Report callback exception on sys.stderr. + + Applications may want to override this internal function, and + should when sys.stderr is None.""" import traceback - sys.stderr.write("Exception in Tkinter callback\n") + print("Exception in Tkinter callback", file=sys.stderr) sys.last_type = exc sys.last_value = val sys.last_traceback = tb @@ -1915,16 +1982,10 @@ def pack_forget(self): def pack_info(self): """Return information about the packing options for this widget.""" - words = self.tk.splitlist( - self.tk.call('pack', 'info', self._w)) - dict = {} - for i in range(0, len(words), 2): - key = words[i][1:] - value = words[i+1] - if str(value)[:1] == '.': - value = self._nametowidget(value) - dict[key] = value - return dict + d = _splitdict(self.tk, self.tk.call('pack', 'info', self._w)) + if 'in' in d: + d['in'] = self.nametowidget(d['in']) + return d info = pack_info propagate = pack_propagate = Misc.pack_propagate slaves = pack_slaves = Misc.pack_slaves @@ -1966,16 +2027,10 @@ def place_forget(self): def place_info(self): """Return information about the placing options for this widget.""" - words = self.tk.splitlist( - self.tk.call('place', 'info', self._w)) - dict = {} - for i in range(0, len(words), 2): - key = words[i][1:] - value = words[i+1] - if str(value)[:1] == '.': - value = self._nametowidget(value) - dict[key] = value - return dict + d = _splitdict(self.tk, self.tk.call('place', 'info', self._w)) + if 'in' in d: + d['in'] = self.nametowidget(d['in']) + return d info = place_info slaves = place_slaves = Misc.place_slaves @@ -2015,16 +2070,10 @@ def grid_remove(self): def grid_info(self): """Return information about the options for positioning this widget in a grid.""" - words = self.tk.splitlist( - self.tk.call('grid', 'info', self._w)) - dict = {} - for i in range(0, len(words), 2): - key = words[i][1:] - value = words[i+1] - if str(value)[:1] == '.': - value = self._nametowidget(value) - dict[key] = value - return dict + d = _splitdict(self.tk, self.tk.call('grid', 'info', self._w)) + if 'in' in d: + d['in'] = self.nametowidget(d['in']) + return d info = grid_info location = grid_location = Misc.grid_location propagate = grid_propagate = Misc.grid_propagate @@ -2144,21 +2193,6 @@ def __init__(self, master=None, cnf={}, **kw): """ Widget.__init__(self, master, 'button', cnf, kw) - def tkButtonEnter(self, *dummy): - self.tk.call('tkButtonEnter', self._w) - - def tkButtonLeave(self, *dummy): - self.tk.call('tkButtonLeave', self._w) - - def tkButtonDown(self, *dummy): - self.tk.call('tkButtonDown', self._w) - - def tkButtonUp(self, *dummy): - self.tk.call('tkButtonUp', self._w) - - def tkButtonInvoke(self, *dummy): - self.tk.call('tkButtonInvoke', self._w) - def flash(self): """Flash the button. @@ -2570,22 +2604,19 @@ def __init__(self, master=None, cnf={}, **kw): def activate(self, index): """Activate item identified by INDEX.""" self.tk.call(self._w, 'activate', index) - def bbox(self, *args): + def bbox(self, index): """Return a tuple of X1,Y1,X2,Y2 coordinates for a rectangle - which encloses the item identified by index in ARGS.""" - return self._getints( - self.tk.call((self._w, 'bbox') + args)) or None + which encloses the item identified by the given index.""" + return self._getints(self.tk.call(self._w, 'bbox', index)) or None def curselection(self): - """Return list of indices of currently selected item.""" - # XXX Ought to apply self._getints()... - return self.tk.splitlist(self.tk.call( - self._w, 'curselection')) + """Return the indices of currently selected item.""" + return self._getints(self.tk.call(self._w, 'curselection')) or () def delete(self, first, last=None): - """Delete items from FIRST to LAST (not included).""" + """Delete items from FIRST to LAST (included).""" self.tk.call(self._w, 'delete', first, last) def get(self, first, last=None): - """Get list of items from FIRST to LAST (not included).""" - if last: + """Get list of items from FIRST to LAST (included).""" + if last is not None: return self.tk.splitlist(self.tk.call( self._w, 'get', first, last)) else: @@ -2618,7 +2649,7 @@ def selection_anchor(self, index): self.tk.call(self._w, 'selection', 'anchor', index) select_anchor = selection_anchor def selection_clear(self, first, last=None): - """Clear the selection from FIRST to LAST (not included).""" + """Clear the selection from FIRST to LAST (included).""" self.tk.call(self._w, 'selection', 'clear', first, last) select_clear = selection_clear @@ -2628,7 +2659,7 @@ def selection_includes(self, index): self._w, 'selection', 'includes', index)) select_includes = selection_includes def selection_set(self, first, last=None): - """Set the selection from FIRST to LAST (not included) without + """Set the selection from FIRST to LAST (included) without changing the currently selected elements.""" self.tk.call(self._w, 'selection', 'set', first, last) select_set = selection_set @@ -2660,31 +2691,15 @@ def __init__(self, master=None, cnf={}, **kw): disabledforeground, fg, font, foreground, postcommand, relief, selectcolor, takefocus, tearoff, tearoffcommand, title, type.""" Widget.__init__(self, master, 'menu', cnf, kw) - def tk_bindForTraversal(self): - pass # obsolete since Tk 4.0 - def tk_mbPost(self): - self.tk.call('tk_mbPost', self._w) - def tk_mbUnpost(self): - self.tk.call('tk_mbUnpost') - def tk_traverseToMenu(self, char): - self.tk.call('tk_traverseToMenu', self._w, char) - def tk_traverseWithinMenu(self, char): - self.tk.call('tk_traverseWithinMenu', self._w, char) - def tk_getMenuButtons(self): - return self.tk.call('tk_getMenuButtons', self._w) - def tk_nextMenu(self, count): - self.tk.call('tk_nextMenu', count) - def tk_nextMenuEntry(self, count): - self.tk.call('tk_nextMenuEntry', count) - def tk_invokeMenu(self): - self.tk.call('tk_invokeMenu', self._w) - def tk_firstMenu(self): - self.tk.call('tk_firstMenu', self._w) - def tk_mbButtonDown(self): - self.tk.call('tk_mbButtonDown', self._w) def tk_popup(self, x, y, entry=""): """Post the menu at position X,Y with entry ENTRY.""" self.tk.call('tk_popup', self._w, x, y, entry) + def tk_bindForTraversal(self): + # obsolete since Tk 4.0 + import warnings + warnings.warn('tk_bindForTraversal() does nothing and ' + 'will be removed in 3.6', + DeprecationWarning, stacklevel=2) def activate(self, index): """Activate entry at INDEX.""" self.tk.call(self._w, 'activate', index) @@ -2857,10 +2872,14 @@ def __init__(self, master=None, cnf={}, **kw): relief, repeatdelay, repeatinterval, takefocus, troughcolor, width.""" Widget.__init__(self, master, 'scrollbar', cnf, kw) - def activate(self, index): - """Display the element at INDEX with activebackground and activerelief. - INDEX can be "arrow1","slider" or "arrow2".""" - self.tk.call(self._w, 'activate', index) + def activate(self, index=None): + """Marks the element indicated by index as active. + The only index values understood by this method are "arrow1", + "slider", or "arrow2". If any other value is specified then no + element of the scrollbar will be active. If index is not specified, + the method returns the name of the element that is currently active, + or None if no element is active.""" + return self.tk.call(self._w, 'activate', index) or None def delta(self, deltax, deltay): """Return the fractional change of the scrollbar setting if it would be moved by DELTAX or DELTAY pixels.""" @@ -2878,10 +2897,10 @@ def get(self): """Return the current fractional values (upper and lower end) of the slider position.""" return self._getdoubles(self.tk.call(self._w, 'get')) - def set(self, *args): + def set(self, first, last): """Set the fractional values of the slider position (upper and lower ends as value between 0 and 1).""" - self.tk.call((self._w, 'set') + args) + self.tk.call(self._w, 'set', first, last) @@ -2916,14 +2935,6 @@ def bbox(self, index): box of the visible part of the character at the given index.""" return self._getints( self.tk.call(self._w, 'bbox', index)) or None - def tk_textSelectTo(self, index): - self.tk.call('tk_textSelectTo', self._w, index) - def tk_textBackspace(self): - self.tk.call('tk_textBackspace', self._w) - def tk_textIndexCloser(self, a, b, c): - self.tk.call('tk_textIndexCloser', self._w, a, b, c) - def tk_textResetAnchor(self, index): - self.tk.call('tk_textResetAnchor', self._w, index) def compare(self, index1, op, index2): """Return whether between index INDEX1 and index INDEX2 the relation OP is satisfied. OP is one of <, <=, ==, >=, >, or !=.""" @@ -2952,7 +2963,7 @@ def debug(self, boolean=None): """Turn on the internal consistency checks of the B-Tree inside the text widget according to BOOLEAN.""" if boolean is None: - return self.tk.call(self._w, 'debug') + return self.tk.getboolean(self.tk.call(self._w, 'debug')) self.tk.call(self._w, 'debug', boolean) def delete(self, index1, index2=None): """Delete the characters between INDEX1 and INDEX2 (not included).""" @@ -3307,7 +3318,7 @@ def __init__(self, imgtype, name=None, cnf={}, master=None, **kw): master = _default_root if not master: raise RuntimeError('Too early to create image') - self.tk = master.tk + self.tk = getattr(master, 'tk', master) if not name: Image._last_id += 1 name = "pyimage%r" % (Image._last_id,) # tk itself would use image @@ -3378,20 +3389,20 @@ def __getitem__(self, key): # XXX copy -from, -to, ...? def copy(self): """Return a new PhotoImage with the same image as this widget.""" - destImage = PhotoImage() + destImage = PhotoImage(master=self.tk) self.tk.call(destImage, 'copy', self.name) return destImage def zoom(self,x,y=''): """Return a new PhotoImage with the same image as this widget but zoom it with X and Y.""" - destImage = PhotoImage() + destImage = PhotoImage(master=self.tk) if y=='': y=x self.tk.call(destImage, 'copy', self.name, '-zoom',x,y) return destImage def subsample(self,x,y=''): """Return a new PhotoImage based on the same image as this widget but use only every Xth or Yth pixel.""" - destImage = PhotoImage() + destImage = PhotoImage(master=self.tk) if y=='': y=x self.tk.call(destImage, 'copy', self.name, '-subsample',x,y) return destImage @@ -3426,8 +3437,11 @@ def __init__(self, name=None, cnf={}, master=None, **kw): Valid resource names: background, data, file, foreground, maskdata, maskfile.""" Image.__init__(self, 'bitmap', name, cnf, master, **kw) -def image_names(): return _default_root.tk.call('image', 'names') -def image_types(): return _default_root.tk.call('image', 'types') +def image_names(): + return _default_root.tk.splitlist(_default_root.tk.call('image', 'names')) + +def image_types(): + return _default_root.tk.splitlist(_default_root.tk.call('image', 'types')) class Spinbox(Widget, XView): @@ -3786,53 +3800,24 @@ def paneconfigure(self, tagOrId, cnf=None, **kw): """ if cnf is None and not kw: - cnf = {} - for x in self.tk.split( - self.tk.call(self._w, - 'paneconfigure', tagOrId)): - cnf[x[0][1:]] = (x[0][1:],) + x[1:] - return cnf + return self._getconfigure(self._w, 'paneconfigure', tagOrId) if isinstance(cnf, str) and not kw: - x = self.tk.split(self.tk.call( - self._w, 'paneconfigure', tagOrId, '-'+cnf)) - return (x[0][1:],) + x[1:] + return self._getconfigure1( + self._w, 'paneconfigure', tagOrId, '-'+cnf) self.tk.call((self._w, 'paneconfigure', tagOrId) + self._options(cnf, kw)) paneconfig = paneconfigure def panes(self): """Returns an ordered list of the child panes.""" - return self.tk.call(self._w, 'panes') - -###################################################################### -# Extensions: + return self.tk.splitlist(self.tk.call(self._w, 'panes')) -class Studbutton(Button): - def __init__(self, master=None, cnf={}, **kw): - Widget.__init__(self, master, 'studbutton', cnf, kw) - self.bind('', self.tkButtonEnter) - self.bind('', self.tkButtonLeave) - self.bind('<1>', self.tkButtonDown) - self.bind('', self.tkButtonUp) - -class Tributton(Button): - def __init__(self, master=None, cnf={}, **kw): - Widget.__init__(self, master, 'tributton', cnf, kw) - self.bind('', self.tkButtonEnter) - self.bind('', self.tkButtonLeave) - self.bind('<1>', self.tkButtonDown) - self.bind('', self.tkButtonUp) - self['fg'] = self['bg'] - self['activebackground'] = self['bg'] - -###################################################################### # Test: def _test(): root = Tk() text = "This is Tcl/Tk version %s" % TclVersion - if TclVersion >= 8.1: - text += "\nThis should be a cedilla: \xe7" + text += "\nThis should be a cedilla: \xe7" label = Label(root, text=text) label.pack() test = Button(root, text="Click me!", diff --git a/Lib/tkinter/_fix.py b/Lib/tkinter/_fix.py index 5f32d25abc8b..fa88734c0527 100644 --- a/Lib/tkinter/_fix.py +++ b/Lib/tkinter/_fix.py @@ -48,8 +48,8 @@ def convert_path(s): prefix = os.path.join(sys.base_prefix,"tcl") if not os.path.exists(prefix): - # devdir/../tcltk/lib - prefix = os.path.join(sys.base_prefix, os.path.pardir, "tcltk", "lib") + # devdir/externals/tcltk/lib + prefix = os.path.join(sys.base_prefix, "externals", "tcltk", "lib") prefix = os.path.abspath(prefix) # if this does not exist, no further search is needed if os.path.exists(prefix): diff --git a/Lib/tkinter/colorchooser.py b/Lib/tkinter/colorchooser.py index 6027067208cf..9dc967133640 100644 --- a/Lib/tkinter/colorchooser.py +++ b/Lib/tkinter/colorchooser.py @@ -1,4 +1,4 @@ -# tk common colour chooser dialogue +# tk common color chooser dialogue # # this module provides an interface to the native color dialogue # available in Tk 4.2 and newer. @@ -11,7 +11,7 @@ # # options (all have default values): # -# - initialcolor: colour to mark as selected when dialog is displayed +# - initialcolor: color to mark as selected when dialog is displayed # (given as an RGB triplet or a Tk color string) # # - parent: which window to place the dialog on top of diff --git a/Lib/tkinter/font.py b/Lib/tkinter/font.py index 49292412f0da..b96673208bee 100644 --- a/Lib/tkinter/font.py +++ b/Lib/tkinter/font.py @@ -69,9 +69,10 @@ def __init__(self, root=None, font=None, name=None, exists=False, **options): if not root: root = tkinter._default_root + tk = getattr(root, 'tk', root) if font: # get actual settings corresponding to the given font - font = root.tk.splitlist(root.tk.call("font", "actual", font)) + font = tk.splitlist(tk.call("font", "actual", font)) else: font = self._set(options) if not name: @@ -81,20 +82,19 @@ def __init__(self, root=None, font=None, name=None, exists=False, if exists: self.delete_font = False # confirm font exists - if self.name not in root.tk.call("font", "names"): + if self.name not in tk.splitlist(tk.call("font", "names")): raise tkinter._tkinter.TclError( "named font %s does not already exist" % (self.name,)) # if font config info supplied, apply it if font: - root.tk.call("font", "configure", self.name, *font) + tk.call("font", "configure", self.name, *font) else: # create new font (raises TclError if the font exists) - root.tk.call("font", "create", self.name, *font) + tk.call("font", "create", self.name, *font) self.delete_font = True - # backlinks! - self._root = root - self._split = root.tk.splitlist - self._call = root.tk.call + self._tk = tk + self._split = tk.splitlist + self._call = tk.call def __str__(self): return self.name @@ -119,7 +119,7 @@ def __del__(self): def copy(self): "Return a distinct copy of the current font" - return Font(self._root, **self.actual()) + return Font(self._tk, **self.actual()) def actual(self, option=None, displayof=None): "Return actual font attributes" diff --git a/Lib/tkinter/test/runtktests.py b/Lib/tkinter/test/runtktests.py index e21eca4c45e0..ccb375556fab 100644 --- a/Lib/tkinter/test/runtktests.py +++ b/Lib/tkinter/test/runtktests.py @@ -68,5 +68,4 @@ def get_tests(text=True, gui=True, packages=None): yield test if __name__ == "__main__": - test.support.use_resources = ['gui'] test.support.run_unittest(*get_tests()) diff --git a/Lib/tkinter/test/support.py b/Lib/tkinter/test/support.py index fcd9ffc1ca46..067fc71c8fb7 100644 --- a/Lib/tkinter/test/support.py +++ b/Lib/tkinter/test/support.py @@ -1,74 +1,46 @@ import sys import tkinter import unittest - -_tk_unavailable = None - -def check_tk_availability(): - """Check that Tk is installed and available.""" - global _tk_unavailable - - if _tk_unavailable is None: - _tk_unavailable = False - if sys.platform == 'darwin': - # The Aqua Tk implementations on OS X can abort the process if - # being called in an environment where a window server connection - # cannot be made, for instance when invoked by a buildbot or ssh - # process not running under the same user id as the current console - # user. To avoid that, raise an exception if the window manager - # connection is not available. - from ctypes import cdll, c_int, pointer, Structure - from ctypes.util import find_library - - app_services = cdll.LoadLibrary(find_library("ApplicationServices")) - - if app_services.CGMainDisplayID() == 0: - _tk_unavailable = "cannot run without OS X window manager" - else: - class ProcessSerialNumber(Structure): - _fields_ = [("highLongOfPSN", c_int), - ("lowLongOfPSN", c_int)] - psn = ProcessSerialNumber() - psn_p = pointer(psn) - if ( (app_services.GetCurrentProcess(psn_p) < 0) or - (app_services.SetFrontProcess(psn_p) < 0) ): - _tk_unavailable = "cannot run without OS X gui process" - else: # not OS X - import tkinter - try: - tkinter.Button() - except tkinter.TclError as msg: - # assuming tk is not available - _tk_unavailable = "tk not available: %s" % msg - - if _tk_unavailable: - raise unittest.SkipTest(_tk_unavailable) - return - -def get_tk_root(): - check_tk_availability() # raise exception if tk unavailable - try: - root = tkinter._default_root - except AttributeError: - # it is possible to disable default root in Tkinter, although - # I haven't seen people doing it (but apparently someone did it - # here). - root = None - - if root is None: - # create a new master only if there isn't one already - root = tkinter.Tk() - - return root - -def root_deiconify(): - root = get_tk_root() - root.deiconify() - -def root_withdraw(): - root = get_tk_root() - root.withdraw() - +from test.support import requires + +class AbstractTkTest: + + @classmethod + def setUpClass(cls): + cls._old_support_default_root = tkinter._support_default_root + destroy_default_root() + tkinter.NoDefaultRoot() + cls.root = tkinter.Tk() + cls.wantobjects = cls.root.wantobjects() + # De-maximize main window. + # Some window managers can maximize new windows. + cls.root.wm_state('normal') + try: + cls.root.wm_attributes('-zoomed', False) + except tkinter.TclError: + pass + + @classmethod + def tearDownClass(cls): + cls.root.update_idletasks() + cls.root.destroy() + cls.root = None + tkinter._default_root = None + tkinter._support_default_root = cls._old_support_default_root + + def setUp(self): + self.root.deiconify() + + def tearDown(self): + for w in self.root.winfo_children(): + w.destroy() + self.root.withdraw() + +def destroy_default_root(): + if getattr(tkinter, '_default_root', None): + tkinter._default_root.update_idletasks() + tkinter._default_root.destroy() + tkinter._default_root = None def simulate_mouse_click(widget, x, y): """Generate proper events to click at the x, y position (tries to act diff --git a/Lib/tkinter/test/test_tkinter/test_font.py b/Lib/tkinter/test/test_tkinter/test_font.py index dfd630b4de4f..09c963ee38ec 100644 --- a/Lib/tkinter/test/test_tkinter/test_font.py +++ b/Lib/tkinter/test/test_tkinter/test_font.py @@ -2,26 +2,20 @@ import tkinter from tkinter import font from test.support import requires, run_unittest -import tkinter.test.support as support +from tkinter.test.support import AbstractTkTest requires('gui') -class FontTest(unittest.TestCase): - - def setUp(self): - support.root_deiconify() - - def tearDown(self): - support.root_withdraw() +class FontTest(AbstractTkTest, unittest.TestCase): def test_font_eq(self): fontname = "TkDefaultFont" try: - f = font.Font(name=fontname, exists=True) + f = font.Font(root=self.root, name=fontname, exists=True) except tkinter._tkinter.TclError: - f = font.Font(name=fontname, exists=False) - font1 = font.nametofont(fontname) - font2 = font.nametofont(fontname) + f = font.Font(root=self.root, name=fontname, exists=False) + font1 = font.Font(root=self.root, name=fontname, exists=True) + font2 = font.Font(root=self.root, name=fontname, exists=True) self.assertIsNot(font1, font2) self.assertEqual(font1, font2) self.assertNotEqual(font1, font1.copy()) diff --git a/Lib/tkinter/test/test_tkinter/test_geometry_managers.py b/Lib/tkinter/test/test_tkinter/test_geometry_managers.py new file mode 100644 index 000000000000..e42b1be56a8f --- /dev/null +++ b/Lib/tkinter/test/test_tkinter/test_geometry_managers.py @@ -0,0 +1,900 @@ +import unittest +import re +import tkinter +from tkinter import TclError +from test.support import requires + +from tkinter.test.support import pixels_conv, tcl_version, requires_tcl +from tkinter.test.widget_tests import AbstractWidgetTest + +requires('gui') + + +class PackTest(AbstractWidgetTest, unittest.TestCase): + + def create2(self): + pack = tkinter.Toplevel(self.root, name='pack') + pack.wm_geometry('300x200+0+0') + pack.wm_minsize(1, 1) + a = tkinter.Frame(pack, name='a', width=20, height=40, bg='red') + b = tkinter.Frame(pack, name='b', width=50, height=30, bg='blue') + c = tkinter.Frame(pack, name='c', width=80, height=80, bg='green') + d = tkinter.Frame(pack, name='d', width=40, height=30, bg='yellow') + return pack, a, b, c, d + + def test_pack_configure_after(self): + pack, a, b, c, d = self.create2() + with self.assertRaisesRegex(TclError, 'window "%s" isn\'t packed' % b): + a.pack_configure(after=b) + with self.assertRaisesRegex(TclError, 'bad window path name ".foo"'): + a.pack_configure(after='.foo') + a.pack_configure(side='top') + b.pack_configure(side='top') + c.pack_configure(side='top') + d.pack_configure(side='top') + self.assertEqual(pack.pack_slaves(), [a, b, c, d]) + a.pack_configure(after=b) + self.assertEqual(pack.pack_slaves(), [b, a, c, d]) + a.pack_configure(after=a) + self.assertEqual(pack.pack_slaves(), [b, a, c, d]) + + def test_pack_configure_anchor(self): + pack, a, b, c, d = self.create2() + def check(anchor, geom): + a.pack_configure(side='top', ipadx=5, padx=10, ipady=15, pady=20, + expand=True, anchor=anchor) + self.root.update() + self.assertEqual(a.winfo_geometry(), geom) + check('n', '30x70+135+20') + check('ne', '30x70+260+20') + check('e', '30x70+260+65') + check('se', '30x70+260+110') + check('s', '30x70+135+110') + check('sw', '30x70+10+110') + check('w', '30x70+10+65') + check('nw', '30x70+10+20') + check('center', '30x70+135+65') + + def test_pack_configure_before(self): + pack, a, b, c, d = self.create2() + with self.assertRaisesRegex(TclError, 'window "%s" isn\'t packed' % b): + a.pack_configure(before=b) + with self.assertRaisesRegex(TclError, 'bad window path name ".foo"'): + a.pack_configure(before='.foo') + a.pack_configure(side='top') + b.pack_configure(side='top') + c.pack_configure(side='top') + d.pack_configure(side='top') + self.assertEqual(pack.pack_slaves(), [a, b, c, d]) + a.pack_configure(before=d) + self.assertEqual(pack.pack_slaves(), [b, c, a, d]) + a.pack_configure(before=a) + self.assertEqual(pack.pack_slaves(), [b, c, a, d]) + + def test_pack_configure_expand(self): + pack, a, b, c, d = self.create2() + def check(*geoms): + self.root.update() + self.assertEqual(a.winfo_geometry(), geoms[0]) + self.assertEqual(b.winfo_geometry(), geoms[1]) + self.assertEqual(c.winfo_geometry(), geoms[2]) + self.assertEqual(d.winfo_geometry(), geoms[3]) + a.pack_configure(side='left') + b.pack_configure(side='top') + c.pack_configure(side='right') + d.pack_configure(side='bottom') + check('20x40+0+80', '50x30+135+0', '80x80+220+75', '40x30+100+170') + a.pack_configure(side='left', expand='yes') + b.pack_configure(side='top', expand='on') + c.pack_configure(side='right', expand=True) + d.pack_configure(side='bottom', expand=1) + check('20x40+40+80', '50x30+175+35', '80x80+180+110', '40x30+100+135') + a.pack_configure(side='left', expand='yes', fill='both') + b.pack_configure(side='top', expand='on', fill='both') + c.pack_configure(side='right', expand=True, fill='both') + d.pack_configure(side='bottom', expand=1, fill='both') + check('100x200+0+0', '200x100+100+0', '160x100+140+100', '40x100+100+100') + + def test_pack_configure_in(self): + pack, a, b, c, d = self.create2() + a.pack_configure(side='top') + b.pack_configure(side='top') + c.pack_configure(side='top') + d.pack_configure(side='top') + a.pack_configure(in_=pack) + self.assertEqual(pack.pack_slaves(), [b, c, d, a]) + a.pack_configure(in_=c) + self.assertEqual(pack.pack_slaves(), [b, c, d]) + self.assertEqual(c.pack_slaves(), [a]) + with self.assertRaisesRegex(TclError, + 'can\'t pack %s inside itself' % (a,)): + a.pack_configure(in_=a) + with self.assertRaisesRegex(TclError, 'bad window path name ".foo"'): + a.pack_configure(in_='.foo') + + def test_pack_configure_padx_ipadx_fill(self): + pack, a, b, c, d = self.create2() + def check(geom1, geom2, **kwargs): + a.pack_forget() + b.pack_forget() + a.pack_configure(**kwargs) + b.pack_configure(expand=True, fill='both') + self.root.update() + self.assertEqual(a.winfo_geometry(), geom1) + self.assertEqual(b.winfo_geometry(), geom2) + check('20x40+260+80', '240x200+0+0', side='right', padx=20) + check('20x40+250+80', '240x200+0+0', side='right', padx=(10, 30)) + check('60x40+240+80', '240x200+0+0', side='right', ipadx=20) + check('30x40+260+80', '250x200+0+0', side='right', ipadx=5, padx=10) + check('20x40+260+80', '240x200+0+0', side='right', padx=20, fill='x') + check('20x40+249+80', '240x200+0+0', + side='right', padx=(9, 31), fill='x') + check('60x40+240+80', '240x200+0+0', side='right', ipadx=20, fill='x') + check('30x40+260+80', '250x200+0+0', + side='right', ipadx=5, padx=10, fill='x') + check('30x40+255+80', '250x200+0+0', + side='right', ipadx=5, padx=(5, 15), fill='x') + check('20x40+140+0', '300x160+0+40', side='top', padx=20) + check('20x40+120+0', '300x160+0+40', side='top', padx=(0, 40)) + check('60x40+120+0', '300x160+0+40', side='top', ipadx=20) + check('30x40+135+0', '300x160+0+40', side='top', ipadx=5, padx=10) + check('30x40+130+0', '300x160+0+40', side='top', ipadx=5, padx=(5, 15)) + check('260x40+20+0', '300x160+0+40', side='top', padx=20, fill='x') + check('260x40+25+0', '300x160+0+40', + side='top', padx=(25, 15), fill='x') + check('300x40+0+0', '300x160+0+40', side='top', ipadx=20, fill='x') + check('280x40+10+0', '300x160+0+40', + side='top', ipadx=5, padx=10, fill='x') + check('280x40+5+0', '300x160+0+40', + side='top', ipadx=5, padx=(5, 15), fill='x') + a.pack_configure(padx='1c') + self.assertEqual(a.pack_info()['padx'], + self._str(pack.winfo_pixels('1c'))) + a.pack_configure(ipadx='1c') + self.assertEqual(a.pack_info()['ipadx'], + self._str(pack.winfo_pixels('1c'))) + + def test_pack_configure_pady_ipady_fill(self): + pack, a, b, c, d = self.create2() + def check(geom1, geom2, **kwargs): + a.pack_forget() + b.pack_forget() + a.pack_configure(**kwargs) + b.pack_configure(expand=True, fill='both') + self.root.update() + self.assertEqual(a.winfo_geometry(), geom1) + self.assertEqual(b.winfo_geometry(), geom2) + check('20x40+280+80', '280x200+0+0', side='right', pady=20) + check('20x40+280+70', '280x200+0+0', side='right', pady=(10, 30)) + check('20x80+280+60', '280x200+0+0', side='right', ipady=20) + check('20x50+280+75', '280x200+0+0', side='right', ipady=5, pady=10) + check('20x40+280+80', '280x200+0+0', side='right', pady=20, fill='x') + check('20x40+280+69', '280x200+0+0', + side='right', pady=(9, 31), fill='x') + check('20x80+280+60', '280x200+0+0', side='right', ipady=20, fill='x') + check('20x50+280+75', '280x200+0+0', + side='right', ipady=5, pady=10, fill='x') + check('20x50+280+70', '280x200+0+0', + side='right', ipady=5, pady=(5, 15), fill='x') + check('20x40+140+20', '300x120+0+80', side='top', pady=20) + check('20x40+140+0', '300x120+0+80', side='top', pady=(0, 40)) + check('20x80+140+0', '300x120+0+80', side='top', ipady=20) + check('20x50+140+10', '300x130+0+70', side='top', ipady=5, pady=10) + check('20x50+140+5', '300x130+0+70', side='top', ipady=5, pady=(5, 15)) + check('300x40+0+20', '300x120+0+80', side='top', pady=20, fill='x') + check('300x40+0+25', '300x120+0+80', + side='top', pady=(25, 15), fill='x') + check('300x80+0+0', '300x120+0+80', side='top', ipady=20, fill='x') + check('300x50+0+10', '300x130+0+70', + side='top', ipady=5, pady=10, fill='x') + check('300x50+0+5', '300x130+0+70', + side='top', ipady=5, pady=(5, 15), fill='x') + a.pack_configure(pady='1c') + self.assertEqual(a.pack_info()['pady'], + self._str(pack.winfo_pixels('1c'))) + a.pack_configure(ipady='1c') + self.assertEqual(a.pack_info()['ipady'], + self._str(pack.winfo_pixels('1c'))) + + def test_pack_configure_side(self): + pack, a, b, c, d = self.create2() + def check(side, geom1, geom2): + a.pack_configure(side=side) + self.assertEqual(a.pack_info()['side'], side) + b.pack_configure(expand=True, fill='both') + self.root.update() + self.assertEqual(a.winfo_geometry(), geom1) + self.assertEqual(b.winfo_geometry(), geom2) + check('top', '20x40+140+0', '300x160+0+40') + check('bottom', '20x40+140+160', '300x160+0+0') + check('left', '20x40+0+80', '280x200+20+0') + check('right', '20x40+280+80', '280x200+0+0') + + def test_pack_forget(self): + pack, a, b, c, d = self.create2() + a.pack_configure() + b.pack_configure() + c.pack_configure() + self.assertEqual(pack.pack_slaves(), [a, b, c]) + b.pack_forget() + self.assertEqual(pack.pack_slaves(), [a, c]) + b.pack_forget() + self.assertEqual(pack.pack_slaves(), [a, c]) + d.pack_forget() + + def test_pack_info(self): + pack, a, b, c, d = self.create2() + with self.assertRaisesRegex(TclError, 'window "%s" isn\'t packed' % a): + a.pack_info() + a.pack_configure() + b.pack_configure(side='right', in_=a, anchor='s', expand=True, fill='x', + ipadx=5, padx=10, ipady=2, pady=(5, 15)) + info = a.pack_info() + self.assertIsInstance(info, dict) + self.assertEqual(info['anchor'], 'center') + self.assertEqual(info['expand'], self._str(0)) + self.assertEqual(info['fill'], 'none') + self.assertEqual(info['in'], pack) + self.assertEqual(info['ipadx'], self._str(0)) + self.assertEqual(info['ipady'], self._str(0)) + self.assertEqual(info['padx'], self._str(0)) + self.assertEqual(info['pady'], self._str(0)) + self.assertEqual(info['side'], 'top') + info = b.pack_info() + self.assertIsInstance(info, dict) + self.assertEqual(info['anchor'], 's') + self.assertEqual(info['expand'], self._str(1)) + self.assertEqual(info['fill'], 'x') + self.assertEqual(info['in'], a) + self.assertEqual(info['ipadx'], self._str(5)) + self.assertEqual(info['ipady'], self._str(2)) + self.assertEqual(info['padx'], self._str(10)) + self.assertEqual(info['pady'], self._str((5, 15))) + self.assertEqual(info['side'], 'right') + + def test_pack_propagate(self): + pack, a, b, c, d = self.create2() + pack.configure(width=300, height=200) + a.pack_configure() + pack.pack_propagate(False) + self.root.update() + self.assertEqual(pack.winfo_reqwidth(), 300) + self.assertEqual(pack.winfo_reqheight(), 200) + pack.pack_propagate(True) + self.root.update() + self.assertEqual(pack.winfo_reqwidth(), 20) + self.assertEqual(pack.winfo_reqheight(), 40) + + def test_pack_slaves(self): + pack, a, b, c, d = self.create2() + self.assertEqual(pack.pack_slaves(), []) + a.pack_configure() + self.assertEqual(pack.pack_slaves(), [a]) + b.pack_configure() + self.assertEqual(pack.pack_slaves(), [a, b]) + + +class PlaceTest(AbstractWidgetTest, unittest.TestCase): + + def create2(self): + t = tkinter.Toplevel(self.root, width=300, height=200, bd=0) + t.wm_geometry('300x200+0+0') + f = tkinter.Frame(t, width=154, height=84, bd=2, relief='raised') + f.place_configure(x=48, y=38) + f2 = tkinter.Frame(t, width=30, height=60, bd=2, relief='raised') + self.root.update() + return t, f, f2 + + def test_place_configure_in(self): + t, f, f2 = self.create2() + self.assertEqual(f2.winfo_manager(), '') + with self.assertRaisesRegex(TclError, "can't place %s relative to " + "itself" % re.escape(str(f2))): + f2.place_configure(in_=f2) + if tcl_version >= (8, 5): + self.assertEqual(f2.winfo_manager(), '') + with self.assertRaisesRegex(TclError, 'bad window path name'): + f2.place_configure(in_='spam') + f2.place_configure(in_=f) + self.assertEqual(f2.winfo_manager(), 'place') + + def test_place_configure_x(self): + t, f, f2 = self.create2() + f2.place_configure(in_=f) + self.assertEqual(f2.place_info()['x'], '0') + self.root.update() + self.assertEqual(f2.winfo_x(), 50) + f2.place_configure(x=100) + self.assertEqual(f2.place_info()['x'], '100') + self.root.update() + self.assertEqual(f2.winfo_x(), 150) + f2.place_configure(x=-10, relx=1) + self.assertEqual(f2.place_info()['x'], '-10') + self.root.update() + self.assertEqual(f2.winfo_x(), 190) + with self.assertRaisesRegex(TclError, 'bad screen distance "spam"'): + f2.place_configure(in_=f, x='spam') + + def test_place_configure_y(self): + t, f, f2 = self.create2() + f2.place_configure(in_=f) + self.assertEqual(f2.place_info()['y'], '0') + self.root.update() + self.assertEqual(f2.winfo_y(), 40) + f2.place_configure(y=50) + self.assertEqual(f2.place_info()['y'], '50') + self.root.update() + self.assertEqual(f2.winfo_y(), 90) + f2.place_configure(y=-10, rely=1) + self.assertEqual(f2.place_info()['y'], '-10') + self.root.update() + self.assertEqual(f2.winfo_y(), 110) + with self.assertRaisesRegex(TclError, 'bad screen distance "spam"'): + f2.place_configure(in_=f, y='spam') + + def test_place_configure_relx(self): + t, f, f2 = self.create2() + f2.place_configure(in_=f) + self.assertEqual(f2.place_info()['relx'], '0') + self.root.update() + self.assertEqual(f2.winfo_x(), 50) + f2.place_configure(relx=0.5) + self.assertEqual(f2.place_info()['relx'], '0.5') + self.root.update() + self.assertEqual(f2.winfo_x(), 125) + f2.place_configure(relx=1) + self.assertEqual(f2.place_info()['relx'], '1') + self.root.update() + self.assertEqual(f2.winfo_x(), 200) + with self.assertRaisesRegex(TclError, 'expected floating-point number ' + 'but got "spam"'): + f2.place_configure(in_=f, relx='spam') + + def test_place_configure_rely(self): + t, f, f2 = self.create2() + f2.place_configure(in_=f) + self.assertEqual(f2.place_info()['rely'], '0') + self.root.update() + self.assertEqual(f2.winfo_y(), 40) + f2.place_configure(rely=0.5) + self.assertEqual(f2.place_info()['rely'], '0.5') + self.root.update() + self.assertEqual(f2.winfo_y(), 80) + f2.place_configure(rely=1) + self.assertEqual(f2.place_info()['rely'], '1') + self.root.update() + self.assertEqual(f2.winfo_y(), 120) + with self.assertRaisesRegex(TclError, 'expected floating-point number ' + 'but got "spam"'): + f2.place_configure(in_=f, rely='spam') + + def test_place_configure_anchor(self): + f = tkinter.Frame(self.root) + with self.assertRaisesRegex(TclError, 'bad anchor "j"'): + f.place_configure(anchor='j') + with self.assertRaisesRegex(TclError, 'ambiguous anchor ""'): + f.place_configure(anchor='') + for value in 'n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw', 'center': + f.place_configure(anchor=value) + self.assertEqual(f.place_info()['anchor'], value) + + def test_place_configure_width(self): + t, f, f2 = self.create2() + f2.place_configure(in_=f, width=120) + self.root.update() + self.assertEqual(f2.winfo_width(), 120) + f2.place_configure(width='') + self.root.update() + self.assertEqual(f2.winfo_width(), 30) + with self.assertRaisesRegex(TclError, 'bad screen distance "abcd"'): + f2.place_configure(width='abcd') + + def test_place_configure_height(self): + t, f, f2 = self.create2() + f2.place_configure(in_=f, height=120) + self.root.update() + self.assertEqual(f2.winfo_height(), 120) + f2.place_configure(height='') + self.root.update() + self.assertEqual(f2.winfo_height(), 60) + with self.assertRaisesRegex(TclError, 'bad screen distance "abcd"'): + f2.place_configure(height='abcd') + + def test_place_configure_relwidth(self): + t, f, f2 = self.create2() + f2.place_configure(in_=f, relwidth=0.5) + self.root.update() + self.assertEqual(f2.winfo_width(), 75) + f2.place_configure(relwidth='') + self.root.update() + self.assertEqual(f2.winfo_width(), 30) + with self.assertRaisesRegex(TclError, 'expected floating-point number ' + 'but got "abcd"'): + f2.place_configure(relwidth='abcd') + + def test_place_configure_relheight(self): + t, f, f2 = self.create2() + f2.place_configure(in_=f, relheight=0.5) + self.root.update() + self.assertEqual(f2.winfo_height(), 40) + f2.place_configure(relheight='') + self.root.update() + self.assertEqual(f2.winfo_height(), 60) + with self.assertRaisesRegex(TclError, 'expected floating-point number ' + 'but got "abcd"'): + f2.place_configure(relheight='abcd') + + def test_place_configure_bordermode(self): + f = tkinter.Frame(self.root) + with self.assertRaisesRegex(TclError, 'bad bordermode "j"'): + f.place_configure(bordermode='j') + with self.assertRaisesRegex(TclError, 'ambiguous bordermode ""'): + f.place_configure(bordermode='') + for value in 'inside', 'outside', 'ignore': + f.place_configure(bordermode=value) + self.assertEqual(f.place_info()['bordermode'], value) + + def test_place_forget(self): + foo = tkinter.Frame(self.root) + foo.place_configure(width=50, height=50) + self.root.update() + foo.place_forget() + self.root.update() + self.assertFalse(foo.winfo_ismapped()) + with self.assertRaises(TypeError): + foo.place_forget(0) + + def test_place_info(self): + t, f, f2 = self.create2() + f2.place_configure(in_=f, x=1, y=2, width=3, height=4, + relx=0.1, rely=0.2, relwidth=0.3, relheight=0.4, + anchor='se', bordermode='outside') + info = f2.place_info() + self.assertIsInstance(info, dict) + self.assertEqual(info['x'], '1') + self.assertEqual(info['y'], '2') + self.assertEqual(info['width'], '3') + self.assertEqual(info['height'], '4') + self.assertEqual(info['relx'], '0.1') + self.assertEqual(info['rely'], '0.2') + self.assertEqual(info['relwidth'], '0.3') + self.assertEqual(info['relheight'], '0.4') + self.assertEqual(info['anchor'], 'se') + self.assertEqual(info['bordermode'], 'outside') + self.assertEqual(info['x'], '1') + self.assertEqual(info['x'], '1') + with self.assertRaises(TypeError): + f2.place_info(0) + + def test_place_slaves(self): + foo = tkinter.Frame(self.root) + bar = tkinter.Frame(self.root) + self.assertEqual(foo.place_slaves(), []) + bar.place_configure(in_=foo) + self.assertEqual(foo.place_slaves(), [bar]) + with self.assertRaises(TypeError): + foo.place_slaves(0) + + +class GridTest(AbstractWidgetTest, unittest.TestCase): + + def tearDown(self): + cols, rows = self.root.grid_size() + for i in range(cols + 1): + self.root.grid_columnconfigure(i, weight=0, minsize=0, pad=0, uniform='') + for i in range(rows + 1): + self.root.grid_rowconfigure(i, weight=0, minsize=0, pad=0, uniform='') + self.root.grid_propagate(1) + if tcl_version >= (8, 5): + self.root.grid_anchor('nw') + super().tearDown() + + def test_grid_configure(self): + b = tkinter.Button(self.root) + self.assertEqual(b.grid_info(), {}) + b.grid_configure() + self.assertEqual(b.grid_info()['in'], self.root) + self.assertEqual(b.grid_info()['column'], self._str(0)) + self.assertEqual(b.grid_info()['row'], self._str(0)) + b.grid_configure({'column': 1}, row=2) + self.assertEqual(b.grid_info()['column'], self._str(1)) + self.assertEqual(b.grid_info()['row'], self._str(2)) + + def test_grid_configure_column(self): + b = tkinter.Button(self.root) + with self.assertRaisesRegex(TclError, 'bad column value "-1": ' + 'must be a non-negative integer'): + b.grid_configure(column=-1) + b.grid_configure(column=2) + self.assertEqual(b.grid_info()['column'], self._str(2)) + + def test_grid_configure_columnspan(self): + b = tkinter.Button(self.root) + with self.assertRaisesRegex(TclError, 'bad columnspan value "0": ' + 'must be a positive integer'): + b.grid_configure(columnspan=0) + b.grid_configure(columnspan=2) + self.assertEqual(b.grid_info()['columnspan'], self._str(2)) + + def test_grid_configure_in(self): + f = tkinter.Frame(self.root) + b = tkinter.Button(self.root) + self.assertEqual(b.grid_info(), {}) + b.grid_configure() + self.assertEqual(b.grid_info()['in'], self.root) + b.grid_configure(in_=f) + self.assertEqual(b.grid_info()['in'], f) + b.grid_configure({'in': self.root}) + self.assertEqual(b.grid_info()['in'], self.root) + + def test_grid_configure_ipadx(self): + b = tkinter.Button(self.root) + with self.assertRaisesRegex(TclError, 'bad ipadx value "-1": ' + 'must be positive screen distance'): + b.grid_configure(ipadx=-1) + b.grid_configure(ipadx=1) + self.assertEqual(b.grid_info()['ipadx'], self._str(1)) + b.grid_configure(ipadx='.5c') + self.assertEqual(b.grid_info()['ipadx'], + self._str(round(pixels_conv('.5c') * self.scaling))) + + def test_grid_configure_ipady(self): + b = tkinter.Button(self.root) + with self.assertRaisesRegex(TclError, 'bad ipady value "-1": ' + 'must be positive screen distance'): + b.grid_configure(ipady=-1) + b.grid_configure(ipady=1) + self.assertEqual(b.grid_info()['ipady'], self._str(1)) + b.grid_configure(ipady='.5c') + self.assertEqual(b.grid_info()['ipady'], + self._str(round(pixels_conv('.5c') * self.scaling))) + + def test_grid_configure_padx(self): + b = tkinter.Button(self.root) + with self.assertRaisesRegex(TclError, 'bad pad value "-1": ' + 'must be positive screen distance'): + b.grid_configure(padx=-1) + b.grid_configure(padx=1) + self.assertEqual(b.grid_info()['padx'], self._str(1)) + b.grid_configure(padx=(10, 5)) + self.assertEqual(b.grid_info()['padx'], self._str((10, 5))) + b.grid_configure(padx='.5c') + self.assertEqual(b.grid_info()['padx'], + self._str(round(pixels_conv('.5c') * self.scaling))) + + def test_grid_configure_pady(self): + b = tkinter.Button(self.root) + with self.assertRaisesRegex(TclError, 'bad pad value "-1": ' + 'must be positive screen distance'): + b.grid_configure(pady=-1) + b.grid_configure(pady=1) + self.assertEqual(b.grid_info()['pady'], self._str(1)) + b.grid_configure(pady=(10, 5)) + self.assertEqual(b.grid_info()['pady'], self._str((10, 5))) + b.grid_configure(pady='.5c') + self.assertEqual(b.grid_info()['pady'], + self._str(round(pixels_conv('.5c') * self.scaling))) + + def test_grid_configure_row(self): + b = tkinter.Button(self.root) + with self.assertRaisesRegex(TclError, 'bad (row|grid) value "-1": ' + 'must be a non-negative integer'): + b.grid_configure(row=-1) + b.grid_configure(row=2) + self.assertEqual(b.grid_info()['row'], self._str(2)) + + def test_grid_configure_rownspan(self): + b = tkinter.Button(self.root) + with self.assertRaisesRegex(TclError, 'bad rowspan value "0": ' + 'must be a positive integer'): + b.grid_configure(rowspan=0) + b.grid_configure(rowspan=2) + self.assertEqual(b.grid_info()['rowspan'], self._str(2)) + + def test_grid_configure_sticky(self): + f = tkinter.Frame(self.root, bg='red') + with self.assertRaisesRegex(TclError, 'bad stickyness value "glue"'): + f.grid_configure(sticky='glue') + f.grid_configure(sticky='ne') + self.assertEqual(f.grid_info()['sticky'], 'ne') + f.grid_configure(sticky='n,s,e,w') + self.assertEqual(f.grid_info()['sticky'], 'nesw') + + def test_grid_columnconfigure(self): + with self.assertRaises(TypeError): + self.root.grid_columnconfigure() + self.assertEqual(self.root.grid_columnconfigure(0), + {'minsize': 0, 'pad': 0, 'uniform': None, 'weight': 0}) + with self.assertRaisesRegex(TclError, 'bad option "-foo"'): + self.root.grid_columnconfigure(0, 'foo') + self.root.grid_columnconfigure((0, 3), weight=2) + with self.assertRaisesRegex(TclError, + 'must specify a single element on retrieval'): + self.root.grid_columnconfigure((0, 3)) + b = tkinter.Button(self.root) + b.grid_configure(column=0, row=0) + if tcl_version >= (8, 5): + self.root.grid_columnconfigure('all', weight=3) + with self.assertRaisesRegex(TclError, 'expected integer but got "all"'): + self.root.grid_columnconfigure('all') + self.assertEqual(self.root.grid_columnconfigure(0, 'weight'), 3) + self.assertEqual(self.root.grid_columnconfigure(3, 'weight'), 2) + self.assertEqual(self.root.grid_columnconfigure(265, 'weight'), 0) + if tcl_version >= (8, 5): + self.root.grid_columnconfigure(b, weight=4) + self.assertEqual(self.root.grid_columnconfigure(0, 'weight'), 4) + + def test_grid_columnconfigure_minsize(self): + with self.assertRaisesRegex(TclError, 'bad screen distance "foo"'): + self.root.grid_columnconfigure(0, minsize='foo') + self.root.grid_columnconfigure(0, minsize=10) + self.assertEqual(self.root.grid_columnconfigure(0, 'minsize'), 10) + self.assertEqual(self.root.grid_columnconfigure(0)['minsize'], 10) + + def test_grid_columnconfigure_weight(self): + with self.assertRaisesRegex(TclError, 'expected integer but got "bad"'): + self.root.grid_columnconfigure(0, weight='bad') + with self.assertRaisesRegex(TclError, 'invalid arg "-weight": ' + 'should be non-negative'): + self.root.grid_columnconfigure(0, weight=-3) + self.root.grid_columnconfigure(0, weight=3) + self.assertEqual(self.root.grid_columnconfigure(0, 'weight'), 3) + self.assertEqual(self.root.grid_columnconfigure(0)['weight'], 3) + + def test_grid_columnconfigure_pad(self): + with self.assertRaisesRegex(TclError, 'bad screen distance "foo"'): + self.root.grid_columnconfigure(0, pad='foo') + with self.assertRaisesRegex(TclError, 'invalid arg "-pad": ' + 'should be non-negative'): + self.root.grid_columnconfigure(0, pad=-3) + self.root.grid_columnconfigure(0, pad=3) + self.assertEqual(self.root.grid_columnconfigure(0, 'pad'), 3) + self.assertEqual(self.root.grid_columnconfigure(0)['pad'], 3) + + def test_grid_columnconfigure_uniform(self): + self.root.grid_columnconfigure(0, uniform='foo') + self.assertEqual(self.root.grid_columnconfigure(0, 'uniform'), 'foo') + self.assertEqual(self.root.grid_columnconfigure(0)['uniform'], 'foo') + + def test_grid_rowconfigure(self): + with self.assertRaises(TypeError): + self.root.grid_rowconfigure() + self.assertEqual(self.root.grid_rowconfigure(0), + {'minsize': 0, 'pad': 0, 'uniform': None, 'weight': 0}) + with self.assertRaisesRegex(TclError, 'bad option "-foo"'): + self.root.grid_rowconfigure(0, 'foo') + self.root.grid_rowconfigure((0, 3), weight=2) + with self.assertRaisesRegex(TclError, + 'must specify a single element on retrieval'): + self.root.grid_rowconfigure((0, 3)) + b = tkinter.Button(self.root) + b.grid_configure(column=0, row=0) + if tcl_version >= (8, 5): + self.root.grid_rowconfigure('all', weight=3) + with self.assertRaisesRegex(TclError, 'expected integer but got "all"'): + self.root.grid_rowconfigure('all') + self.assertEqual(self.root.grid_rowconfigure(0, 'weight'), 3) + self.assertEqual(self.root.grid_rowconfigure(3, 'weight'), 2) + self.assertEqual(self.root.grid_rowconfigure(265, 'weight'), 0) + if tcl_version >= (8, 5): + self.root.grid_rowconfigure(b, weight=4) + self.assertEqual(self.root.grid_rowconfigure(0, 'weight'), 4) + + def test_grid_rowconfigure_minsize(self): + with self.assertRaisesRegex(TclError, 'bad screen distance "foo"'): + self.root.grid_rowconfigure(0, minsize='foo') + self.root.grid_rowconfigure(0, minsize=10) + self.assertEqual(self.root.grid_rowconfigure(0, 'minsize'), 10) + self.assertEqual(self.root.grid_rowconfigure(0)['minsize'], 10) + + def test_grid_rowconfigure_weight(self): + with self.assertRaisesRegex(TclError, 'expected integer but got "bad"'): + self.root.grid_rowconfigure(0, weight='bad') + with self.assertRaisesRegex(TclError, 'invalid arg "-weight": ' + 'should be non-negative'): + self.root.grid_rowconfigure(0, weight=-3) + self.root.grid_rowconfigure(0, weight=3) + self.assertEqual(self.root.grid_rowconfigure(0, 'weight'), 3) + self.assertEqual(self.root.grid_rowconfigure(0)['weight'], 3) + + def test_grid_rowconfigure_pad(self): + with self.assertRaisesRegex(TclError, 'bad screen distance "foo"'): + self.root.grid_rowconfigure(0, pad='foo') + with self.assertRaisesRegex(TclError, 'invalid arg "-pad": ' + 'should be non-negative'): + self.root.grid_rowconfigure(0, pad=-3) + self.root.grid_rowconfigure(0, pad=3) + self.assertEqual(self.root.grid_rowconfigure(0, 'pad'), 3) + self.assertEqual(self.root.grid_rowconfigure(0)['pad'], 3) + + def test_grid_rowconfigure_uniform(self): + self.root.grid_rowconfigure(0, uniform='foo') + self.assertEqual(self.root.grid_rowconfigure(0, 'uniform'), 'foo') + self.assertEqual(self.root.grid_rowconfigure(0)['uniform'], 'foo') + + def test_grid_forget(self): + b = tkinter.Button(self.root) + c = tkinter.Button(self.root) + b.grid_configure(row=2, column=2, rowspan=2, columnspan=2, + padx=3, pady=4, sticky='ns') + self.assertEqual(self.root.grid_slaves(), [b]) + b.grid_forget() + c.grid_forget() + self.assertEqual(self.root.grid_slaves(), []) + self.assertEqual(b.grid_info(), {}) + b.grid_configure(row=0, column=0) + info = b.grid_info() + self.assertEqual(info['row'], self._str(0)) + self.assertEqual(info['column'], self._str(0)) + self.assertEqual(info['rowspan'], self._str(1)) + self.assertEqual(info['columnspan'], self._str(1)) + self.assertEqual(info['padx'], self._str(0)) + self.assertEqual(info['pady'], self._str(0)) + self.assertEqual(info['sticky'], '') + + def test_grid_remove(self): + b = tkinter.Button(self.root) + c = tkinter.Button(self.root) + b.grid_configure(row=2, column=2, rowspan=2, columnspan=2, + padx=3, pady=4, sticky='ns') + self.assertEqual(self.root.grid_slaves(), [b]) + b.grid_remove() + c.grid_remove() + self.assertEqual(self.root.grid_slaves(), []) + self.assertEqual(b.grid_info(), {}) + b.grid_configure(row=0, column=0) + info = b.grid_info() + self.assertEqual(info['row'], self._str(0)) + self.assertEqual(info['column'], self._str(0)) + self.assertEqual(info['rowspan'], self._str(2)) + self.assertEqual(info['columnspan'], self._str(2)) + self.assertEqual(info['padx'], self._str(3)) + self.assertEqual(info['pady'], self._str(4)) + self.assertEqual(info['sticky'], 'ns') + + def test_grid_info(self): + b = tkinter.Button(self.root) + self.assertEqual(b.grid_info(), {}) + b.grid_configure(row=2, column=2, rowspan=2, columnspan=2, + padx=3, pady=4, sticky='ns') + info = b.grid_info() + self.assertIsInstance(info, dict) + self.assertEqual(info['in'], self.root) + self.assertEqual(info['row'], self._str(2)) + self.assertEqual(info['column'], self._str(2)) + self.assertEqual(info['rowspan'], self._str(2)) + self.assertEqual(info['columnspan'], self._str(2)) + self.assertEqual(info['padx'], self._str(3)) + self.assertEqual(info['pady'], self._str(4)) + self.assertEqual(info['sticky'], 'ns') + + @requires_tcl(8, 5) + def test_grid_anchor(self): + with self.assertRaisesRegex(TclError, 'bad anchor "x"'): + self.root.grid_anchor('x') + with self.assertRaisesRegex(TclError, 'ambiguous anchor ""'): + self.root.grid_anchor('') + with self.assertRaises(TypeError): + self.root.grid_anchor('se', 'nw') + self.root.grid_anchor('se') + self.assertEqual(self.root.tk.call('grid', 'anchor', self.root), 'se') + + def test_grid_bbox(self): + self.assertEqual(self.root.grid_bbox(), (0, 0, 0, 0)) + self.assertEqual(self.root.grid_bbox(0, 0), (0, 0, 0, 0)) + self.assertEqual(self.root.grid_bbox(0, 0, 1, 1), (0, 0, 0, 0)) + with self.assertRaisesRegex(TclError, 'expected integer but got "x"'): + self.root.grid_bbox('x', 0) + with self.assertRaisesRegex(TclError, 'expected integer but got "x"'): + self.root.grid_bbox(0, 'x') + with self.assertRaisesRegex(TclError, 'expected integer but got "x"'): + self.root.grid_bbox(0, 0, 'x', 0) + with self.assertRaisesRegex(TclError, 'expected integer but got "x"'): + self.root.grid_bbox(0, 0, 0, 'x') + with self.assertRaises(TypeError): + self.root.grid_bbox(0, 0, 0, 0, 0) + t = self.root + # de-maximize + t.wm_geometry('1x1+0+0') + t.wm_geometry('') + f1 = tkinter.Frame(t, width=75, height=75, bg='red') + f2 = tkinter.Frame(t, width=90, height=90, bg='blue') + f1.grid_configure(row=0, column=0) + f2.grid_configure(row=1, column=1) + self.root.update() + self.assertEqual(t.grid_bbox(), (0, 0, 165, 165)) + self.assertEqual(t.grid_bbox(0, 0), (0, 0, 75, 75)) + self.assertEqual(t.grid_bbox(0, 0, 1, 1), (0, 0, 165, 165)) + self.assertEqual(t.grid_bbox(1, 1), (75, 75, 90, 90)) + self.assertEqual(t.grid_bbox(10, 10, 0, 0), (0, 0, 165, 165)) + self.assertEqual(t.grid_bbox(-2, -2, -1, -1), (0, 0, 0, 0)) + self.assertEqual(t.grid_bbox(10, 10, 12, 12), (165, 165, 0, 0)) + + def test_grid_location(self): + with self.assertRaises(TypeError): + self.root.grid_location() + with self.assertRaises(TypeError): + self.root.grid_location(0) + with self.assertRaises(TypeError): + self.root.grid_location(0, 0, 0) + with self.assertRaisesRegex(TclError, 'bad screen distance "x"'): + self.root.grid_location('x', 'y') + with self.assertRaisesRegex(TclError, 'bad screen distance "y"'): + self.root.grid_location('1c', 'y') + t = self.root + # de-maximize + t.wm_geometry('1x1+0+0') + t.wm_geometry('') + f = tkinter.Frame(t, width=200, height=100, + highlightthickness=0, bg='red') + self.assertEqual(f.grid_location(10, 10), (-1, -1)) + f.grid_configure() + self.root.update() + self.assertEqual(t.grid_location(-10, -10), (-1, -1)) + self.assertEqual(t.grid_location(-10, 0), (-1, 0)) + self.assertEqual(t.grid_location(-1, 0), (-1, 0)) + self.assertEqual(t.grid_location(0, -10), (0, -1)) + self.assertEqual(t.grid_location(0, -1), (0, -1)) + self.assertEqual(t.grid_location(0, 0), (0, 0)) + self.assertEqual(t.grid_location(200, 0), (0, 0)) + self.assertEqual(t.grid_location(201, 0), (1, 0)) + self.assertEqual(t.grid_location(0, 100), (0, 0)) + self.assertEqual(t.grid_location(0, 101), (0, 1)) + self.assertEqual(t.grid_location(201, 101), (1, 1)) + + def test_grid_propagate(self): + self.assertEqual(self.root.grid_propagate(), True) + with self.assertRaises(TypeError): + self.root.grid_propagate(False, False) + self.root.grid_propagate(False) + self.assertFalse(self.root.grid_propagate()) + f = tkinter.Frame(self.root, width=100, height=100, bg='red') + f.grid_configure(row=0, column=0) + self.root.update() + self.assertEqual(f.winfo_width(), 100) + self.assertEqual(f.winfo_height(), 100) + f.grid_propagate(False) + g = tkinter.Frame(self.root, width=75, height=85, bg='green') + g.grid_configure(in_=f, row=0, column=0) + self.root.update() + self.assertEqual(f.winfo_width(), 100) + self.assertEqual(f.winfo_height(), 100) + f.grid_propagate(True) + self.root.update() + self.assertEqual(f.winfo_width(), 75) + self.assertEqual(f.winfo_height(), 85) + + def test_grid_size(self): + with self.assertRaises(TypeError): + self.root.grid_size(0) + self.assertEqual(self.root.grid_size(), (0, 0)) + f = tkinter.Scale(self.root) + f.grid_configure(row=0, column=0) + self.assertEqual(self.root.grid_size(), (1, 1)) + f.grid_configure(row=4, column=5) + self.assertEqual(self.root.grid_size(), (6, 5)) + + def test_grid_slaves(self): + self.assertEqual(self.root.grid_slaves(), []) + a = tkinter.Label(self.root) + a.grid_configure(row=0, column=1) + b = tkinter.Label(self.root) + b.grid_configure(row=1, column=0) + c = tkinter.Label(self.root) + c.grid_configure(row=1, column=1) + d = tkinter.Label(self.root) + d.grid_configure(row=1, column=1) + self.assertEqual(self.root.grid_slaves(), [d, c, b, a]) + self.assertEqual(self.root.grid_slaves(row=0), [a]) + self.assertEqual(self.root.grid_slaves(row=1), [d, c, b]) + self.assertEqual(self.root.grid_slaves(column=0), [b]) + self.assertEqual(self.root.grid_slaves(column=1), [d, c, a]) + self.assertEqual(self.root.grid_slaves(row=1, column=1), [d, c]) + + +tests_gui = ( + PackTest, PlaceTest, GridTest, +) + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/tkinter/test/test_tkinter/test_images.py b/Lib/tkinter/test/test_tkinter/test_images.py new file mode 100644 index 000000000000..85a8cd0495ba --- /dev/null +++ b/Lib/tkinter/test/test_tkinter/test_images.py @@ -0,0 +1,327 @@ +import unittest +import tkinter +from test import support +from tkinter.test.support import AbstractTkTest, requires_tcl + +support.requires('gui') + + +class MiscTest(AbstractTkTest, unittest.TestCase): + + def test_image_types(self): + image_types = self.root.image_types() + self.assertIsInstance(image_types, tuple) + self.assertIn('photo', image_types) + self.assertIn('bitmap', image_types) + + def test_image_names(self): + image_names = self.root.image_names() + self.assertIsInstance(image_names, tuple) + + +class BitmapImageTest(AbstractTkTest, unittest.TestCase): + + @classmethod + def setUpClass(cls): + AbstractTkTest.setUpClass.__func__(cls) + cls.testfile = support.findfile('python.xbm', subdir='imghdrdata') + + def test_create_from_file(self): + image = tkinter.BitmapImage('::img::test', master=self.root, + foreground='yellow', background='blue', + file=self.testfile) + self.assertEqual(str(image), '::img::test') + self.assertEqual(image.type(), 'bitmap') + self.assertEqual(image.width(), 16) + self.assertEqual(image.height(), 16) + self.assertIn('::img::test', self.root.image_names()) + del image + self.assertNotIn('::img::test', self.root.image_names()) + + def test_create_from_data(self): + with open(self.testfile, 'rb') as f: + data = f.read() + image = tkinter.BitmapImage('::img::test', master=self.root, + foreground='yellow', background='blue', + data=data) + self.assertEqual(str(image), '::img::test') + self.assertEqual(image.type(), 'bitmap') + self.assertEqual(image.width(), 16) + self.assertEqual(image.height(), 16) + self.assertIn('::img::test', self.root.image_names()) + del image + self.assertNotIn('::img::test', self.root.image_names()) + + def assertEqualStrList(self, actual, expected): + self.assertIsInstance(actual, str) + self.assertEqual(self.root.splitlist(actual), expected) + + def test_configure_data(self): + image = tkinter.BitmapImage('::img::test', master=self.root) + self.assertEqual(image['data'], '-data {} {} {} {}') + with open(self.testfile, 'rb') as f: + data = f.read() + image.configure(data=data) + self.assertEqualStrList(image['data'], + ('-data', '', '', '', data.decode('ascii'))) + self.assertEqual(image.width(), 16) + self.assertEqual(image.height(), 16) + + self.assertEqual(image['maskdata'], '-maskdata {} {} {} {}') + image.configure(maskdata=data) + self.assertEqualStrList(image['maskdata'], + ('-maskdata', '', '', '', data.decode('ascii'))) + + def test_configure_file(self): + image = tkinter.BitmapImage('::img::test', master=self.root) + self.assertEqual(image['file'], '-file {} {} {} {}') + image.configure(file=self.testfile) + self.assertEqualStrList(image['file'], + ('-file', '', '', '',self.testfile)) + self.assertEqual(image.width(), 16) + self.assertEqual(image.height(), 16) + + self.assertEqual(image['maskfile'], '-maskfile {} {} {} {}') + image.configure(maskfile=self.testfile) + self.assertEqualStrList(image['maskfile'], + ('-maskfile', '', '', '', self.testfile)) + + def test_configure_background(self): + image = tkinter.BitmapImage('::img::test', master=self.root) + self.assertEqual(image['background'], '-background {} {} {} {}') + image.configure(background='blue') + self.assertEqual(image['background'], '-background {} {} {} blue') + + def test_configure_foreground(self): + image = tkinter.BitmapImage('::img::test', master=self.root) + self.assertEqual(image['foreground'], + '-foreground {} {} #000000 #000000') + image.configure(foreground='yellow') + self.assertEqual(image['foreground'], + '-foreground {} {} #000000 yellow') + + +class PhotoImageTest(AbstractTkTest, unittest.TestCase): + + @classmethod + def setUpClass(cls): + AbstractTkTest.setUpClass.__func__(cls) + cls.testfile = support.findfile('python.gif', subdir='imghdrdata') + + def create(self): + return tkinter.PhotoImage('::img::test', master=self.root, + file=self.testfile) + + def colorlist(self, *args): + if tkinter.TkVersion >= 8.6 and self.wantobjects: + return args + else: + return tkinter._join(args) + + def check_create_from_file(self, ext): + testfile = support.findfile('python.' + ext, subdir='imghdrdata') + image = tkinter.PhotoImage('::img::test', master=self.root, + file=testfile) + self.assertEqual(str(image), '::img::test') + self.assertEqual(image.type(), 'photo') + self.assertEqual(image.width(), 16) + self.assertEqual(image.height(), 16) + self.assertEqual(image['data'], '') + self.assertEqual(image['file'], testfile) + self.assertIn('::img::test', self.root.image_names()) + del image + self.assertNotIn('::img::test', self.root.image_names()) + + def check_create_from_data(self, ext): + testfile = support.findfile('python.' + ext, subdir='imghdrdata') + with open(testfile, 'rb') as f: + data = f.read() + image = tkinter.PhotoImage('::img::test', master=self.root, + data=data) + self.assertEqual(str(image), '::img::test') + self.assertEqual(image.type(), 'photo') + self.assertEqual(image.width(), 16) + self.assertEqual(image.height(), 16) + self.assertEqual(image['data'], data if self.wantobjects + else data.decode('latin1')) + self.assertEqual(image['file'], '') + self.assertIn('::img::test', self.root.image_names()) + del image + self.assertNotIn('::img::test', self.root.image_names()) + + def test_create_from_ppm_file(self): + self.check_create_from_file('ppm') + + def test_create_from_ppm_data(self): + self.check_create_from_data('ppm') + + def test_create_from_pgm_file(self): + self.check_create_from_file('pgm') + + def test_create_from_pgm_data(self): + self.check_create_from_data('pgm') + + def test_create_from_gif_file(self): + self.check_create_from_file('gif') + + def test_create_from_gif_data(self): + self.check_create_from_data('gif') + + @requires_tcl(8, 6) + def test_create_from_png_file(self): + self.check_create_from_file('png') + + @requires_tcl(8, 6) + def test_create_from_png_data(self): + self.check_create_from_data('png') + + def test_configure_data(self): + image = tkinter.PhotoImage('::img::test', master=self.root) + self.assertEqual(image['data'], '') + with open(self.testfile, 'rb') as f: + data = f.read() + image.configure(data=data) + self.assertEqual(image['data'], data if self.wantobjects + else data.decode('latin1')) + self.assertEqual(image.width(), 16) + self.assertEqual(image.height(), 16) + + def test_configure_format(self): + image = tkinter.PhotoImage('::img::test', master=self.root) + self.assertEqual(image['format'], '') + image.configure(file=self.testfile, format='gif') + self.assertEqual(image['format'], ('gif',) if self.wantobjects + else 'gif') + self.assertEqual(image.width(), 16) + self.assertEqual(image.height(), 16) + + def test_configure_file(self): + image = tkinter.PhotoImage('::img::test', master=self.root) + self.assertEqual(image['file'], '') + image.configure(file=self.testfile) + self.assertEqual(image['file'], self.testfile) + self.assertEqual(image.width(), 16) + self.assertEqual(image.height(), 16) + + def test_configure_gamma(self): + image = tkinter.PhotoImage('::img::test', master=self.root) + self.assertEqual(image['gamma'], '1.0') + image.configure(gamma=2.0) + self.assertEqual(image['gamma'], '2.0') + + def test_configure_width_height(self): + image = tkinter.PhotoImage('::img::test', master=self.root) + self.assertEqual(image['width'], '0') + self.assertEqual(image['height'], '0') + image.configure(width=20) + image.configure(height=10) + self.assertEqual(image['width'], '20') + self.assertEqual(image['height'], '10') + self.assertEqual(image.width(), 20) + self.assertEqual(image.height(), 10) + + def test_configure_palette(self): + image = tkinter.PhotoImage('::img::test', master=self.root) + self.assertEqual(image['palette'], '') + image.configure(palette=256) + self.assertEqual(image['palette'], '256') + image.configure(palette='3/4/2') + self.assertEqual(image['palette'], '3/4/2') + + def test_blank(self): + image = self.create() + image.blank() + self.assertEqual(image.width(), 16) + self.assertEqual(image.height(), 16) + self.assertEqual(image.get(4, 6), self.colorlist(0, 0, 0)) + + def test_copy(self): + image = self.create() + image2 = image.copy() + self.assertEqual(image2.width(), 16) + self.assertEqual(image2.height(), 16) + self.assertEqual(image.get(4, 6), image.get(4, 6)) + + def test_subsample(self): + image = self.create() + image2 = image.subsample(2, 3) + self.assertEqual(image2.width(), 8) + self.assertEqual(image2.height(), 6) + self.assertEqual(image2.get(2, 2), image.get(4, 6)) + + image2 = image.subsample(2) + self.assertEqual(image2.width(), 8) + self.assertEqual(image2.height(), 8) + self.assertEqual(image2.get(2, 3), image.get(4, 6)) + + def test_zoom(self): + image = self.create() + image2 = image.zoom(2, 3) + self.assertEqual(image2.width(), 32) + self.assertEqual(image2.height(), 48) + self.assertEqual(image2.get(8, 18), image.get(4, 6)) + self.assertEqual(image2.get(9, 20), image.get(4, 6)) + + image2 = image.zoom(2) + self.assertEqual(image2.width(), 32) + self.assertEqual(image2.height(), 32) + self.assertEqual(image2.get(8, 12), image.get(4, 6)) + self.assertEqual(image2.get(9, 13), image.get(4, 6)) + + def test_put(self): + image = self.create() + image.put('{red green} {blue yellow}', to=(4, 6)) + self.assertEqual(image.get(4, 6), self.colorlist(255, 0, 0)) + self.assertEqual(image.get(5, 6), + self.colorlist(0, 128 if tkinter.TkVersion >= 8.6 + else 255, 0)) + self.assertEqual(image.get(4, 7), self.colorlist(0, 0, 255)) + self.assertEqual(image.get(5, 7), self.colorlist(255, 255, 0)) + + image.put((('#f00', '#00ff00'), ('#000000fff', '#ffffffff0000'))) + self.assertEqual(image.get(0, 0), self.colorlist(255, 0, 0)) + self.assertEqual(image.get(1, 0), self.colorlist(0, 255, 0)) + self.assertEqual(image.get(0, 1), self.colorlist(0, 0, 255)) + self.assertEqual(image.get(1, 1), self.colorlist(255, 255, 0)) + + def test_get(self): + image = self.create() + self.assertEqual(image.get(4, 6), self.colorlist(62, 116, 162)) + self.assertEqual(image.get(0, 0), self.colorlist(0, 0, 0)) + self.assertEqual(image.get(15, 15), self.colorlist(0, 0, 0)) + self.assertRaises(tkinter.TclError, image.get, -1, 0) + self.assertRaises(tkinter.TclError, image.get, 0, -1) + self.assertRaises(tkinter.TclError, image.get, 16, 15) + self.assertRaises(tkinter.TclError, image.get, 15, 16) + + def test_write(self): + image = self.create() + self.addCleanup(support.unlink, support.TESTFN) + + image.write(support.TESTFN) + image2 = tkinter.PhotoImage('::img::test2', master=self.root, + format='ppm', + file=support.TESTFN) + self.assertEqual(str(image2), '::img::test2') + self.assertEqual(image2.type(), 'photo') + self.assertEqual(image2.width(), 16) + self.assertEqual(image2.height(), 16) + self.assertEqual(image2.get(0, 0), image.get(0, 0)) + self.assertEqual(image2.get(15, 8), image.get(15, 8)) + + image.write(support.TESTFN, format='gif', from_coords=(4, 6, 6, 9)) + image3 = tkinter.PhotoImage('::img::test3', master=self.root, + format='gif', + file=support.TESTFN) + self.assertEqual(str(image3), '::img::test3') + self.assertEqual(image3.type(), 'photo') + self.assertEqual(image3.width(), 2) + self.assertEqual(image3.height(), 3) + self.assertEqual(image3.get(0, 0), image.get(4, 6)) + self.assertEqual(image3.get(1, 2), image.get(5, 8)) + + +tests_gui = (MiscTest, BitmapImageTest, PhotoImageTest,) + +if __name__ == "__main__": + support.run_unittest(*tests_gui) diff --git a/Lib/tkinter/test/test_tkinter/test_misc.py b/Lib/tkinter/test/test_tkinter/test_misc.py index d325b3132a7e..85ee2c70b1bf 100644 --- a/Lib/tkinter/test/test_tkinter/test_misc.py +++ b/Lib/tkinter/test/test_tkinter/test_misc.py @@ -1,14 +1,16 @@ import unittest import tkinter -from tkinter import ttk from test import support +from tkinter.test.support import AbstractTkTest support.requires('gui') -class MiscTest(unittest.TestCase): +class MiscTest(AbstractTkTest, unittest.TestCase): - def setUp(self): - self.root = ttk.setup_master() + def test_repr(self): + t = tkinter.Toplevel(self.root, name='top') + f = tkinter.Frame(t, name='child') + self.assertEqual(repr(f), '') def test_tk_setPalette(self): root = self.root diff --git a/Lib/tkinter/test/test_tkinter/test_text.py b/Lib/tkinter/test/test_tkinter/test_text.py index 4c3fa04188e0..13b7c56a3978 100644 --- a/Lib/tkinter/test/test_tkinter/test_text.py +++ b/Lib/tkinter/test/test_tkinter/test_text.py @@ -1,19 +1,16 @@ import unittest import tkinter from test.support import requires, run_unittest -from tkinter.ttk import setup_master +from tkinter.test.support import AbstractTkTest requires('gui') -class TextTest(unittest.TestCase): +class TextTest(AbstractTkTest, unittest.TestCase): def setUp(self): - self.root = setup_master() + super().setUp() self.text = tkinter.Text(self.root) - def tearDown(self): - self.text.destroy() - def test_debug(self): text = self.text olddebug = text.debug() diff --git a/Lib/tkinter/test/test_tkinter/test_variables.py b/Lib/tkinter/test/test_tkinter/test_variables.py index 378cc92ebf0f..7b7e2999baa7 100644 --- a/Lib/tkinter/test/test_tkinter/test_variables.py +++ b/Lib/tkinter/test/test_tkinter/test_variables.py @@ -1,6 +1,6 @@ import unittest -from tkinter import Variable, StringVar, IntVar, DoubleVar, BooleanVar, Tk +from tkinter import Variable, StringVar, IntVar, DoubleVar, BooleanVar, Tcl class Var(Variable): @@ -16,14 +16,17 @@ def set(self, value): class TestBase(unittest.TestCase): def setUp(self): - self.root = Tk() + self.root = Tcl() def tearDown(self): - self.root.destroy() + del self.root class TestVariable(TestBase): + def info_exists(self, *args): + return self.root.getboolean(self.root.call("info", "exists", *args)) + def test_default(self): v = Variable(self.root) self.assertEqual("", v.get()) @@ -35,21 +38,21 @@ def test_name_and_value(self): self.assertEqual("varname", str(v)) def test___del__(self): - self.assertFalse(self.root.call("info", "exists", "varname")) + self.assertFalse(self.info_exists("varname")) v = Variable(self.root, "sample string", "varname") - self.assertTrue(self.root.call("info", "exists", "varname")) + self.assertTrue(self.info_exists("varname")) del v - self.assertFalse(self.root.call("info", "exists", "varname")) + self.assertFalse(self.info_exists("varname")) def test_dont_unset_not_existing(self): - self.assertFalse(self.root.call("info", "exists", "varname")) + self.assertFalse(self.info_exists("varname")) v1 = Variable(self.root, name="name") v2 = Variable(self.root, name="name") del v1 - self.assertFalse(self.root.call("info", "exists", "name")) + self.assertFalse(self.info_exists("name")) # shouldn't raise exception del v2 - self.assertFalse(self.root.call("info", "exists", "name")) + self.assertFalse(self.info_exists("name")) def test___eq__(self): # values doesn't matter, only class and name are checked @@ -65,8 +68,20 @@ def test_invalid_name(self): with self.assertRaises(TypeError): Variable(self.root, name=123) + def test_null_in_name(self): + with self.assertRaises(ValueError): + Variable(self.root, name='var\x00name') + with self.assertRaises(ValueError): + self.root.globalsetvar('var\x00name', "value") + with self.assertRaises(ValueError): + self.root.globalsetvar(b'var\x00name', "value") + with self.assertRaises(ValueError): + self.root.setvar('var\x00name', "value") + with self.assertRaises(ValueError): + self.root.setvar(b'var\x00name', "value") + def test_initialize(self): - v = Var() + v = Var(self.root) self.assertFalse(v.side_effect) v.set("value") self.assertTrue(v.side_effect) @@ -84,6 +99,12 @@ def test_get(self): self.root.globalsetvar("name", "value") self.assertEqual("value", v.get()) + def test_get_null(self): + v = StringVar(self.root, "abc\x00def", "name") + self.assertEqual("abc\x00def", v.get()) + self.root.globalsetvar("name", "val\x00ue") + self.assertEqual("val\x00ue", v.get()) + class TestIntVar(TestBase): diff --git a/Lib/tkinter/test/test_tkinter/test_widgets.py b/Lib/tkinter/test/test_tkinter/test_widgets.py index 4de65313bb5d..25b1a0226be8 100644 --- a/Lib/tkinter/test/test_tkinter/test_widgets.py +++ b/Lib/tkinter/test/test_tkinter/test_widgets.py @@ -1,5 +1,6 @@ import unittest import tkinter +from tkinter import TclError import os import sys from test.support import requires @@ -65,7 +66,7 @@ class ToplevelTest(AbstractToplevelTest, unittest.TestCase): 'takefocus', 'use', 'visual', 'width', ) - def _create(self, **kwargs): + def create(self, **kwargs): return tkinter.Toplevel(self.root, **kwargs) def test_menu(self): @@ -104,7 +105,7 @@ class FrameTest(AbstractToplevelTest, unittest.TestCase): 'relief', 'takefocus', 'visual', 'width', ) - def _create(self, **kwargs): + def create(self, **kwargs): return tkinter.Frame(self.root, **kwargs) @@ -119,7 +120,7 @@ class LabelFrameTest(AbstractToplevelTest, unittest.TestCase): 'takefocus', 'text', 'visual', 'width', ) - def _create(self, **kwargs): + def create(self, **kwargs): return tkinter.LabelFrame(self.root, **kwargs) def test_labelanchor(self): @@ -157,7 +158,7 @@ class LabelTest(AbstractLabelTest, unittest.TestCase): 'underline', 'width', 'wraplength', ) - def _create(self, **kwargs): + def create(self, **kwargs): return tkinter.Label(self.root, **kwargs) @@ -174,7 +175,7 @@ class ButtonTest(AbstractLabelTest, unittest.TestCase): 'state', 'takefocus', 'text', 'textvariable', 'underline', 'width', 'wraplength') - def _create(self, **kwargs): + def create(self, **kwargs): return tkinter.Button(self.root, **kwargs) def test_default(self): @@ -198,7 +199,7 @@ class CheckbuttonTest(AbstractLabelTest, unittest.TestCase): 'underline', 'variable', 'width', 'wraplength', ) - def _create(self, **kwargs): + def create(self, **kwargs): return tkinter.Checkbutton(self.root, **kwargs) @@ -226,7 +227,7 @@ class RadiobuttonTest(AbstractLabelTest, unittest.TestCase): 'underline', 'value', 'variable', 'width', 'wraplength', ) - def _create(self, **kwargs): + def create(self, **kwargs): return tkinter.Radiobutton(self.root, **kwargs) def test_value(self): @@ -249,7 +250,7 @@ class MenubuttonTest(AbstractLabelTest, unittest.TestCase): ) _conv_pixels = staticmethod(pixels_round) - def _create(self, **kwargs): + def create(self, **kwargs): return tkinter.Menubutton(self.root, **kwargs) def test_direction(self): @@ -267,7 +268,7 @@ def test_height(self): 'crashes with Cocoa Tk (issue19733)') def test_image(self): widget = self.create() - image = tkinter.PhotoImage('image1') + image = tkinter.PhotoImage(master=self.root, name='image1') self.checkParam(widget, 'image', image, conv=str) errmsg = 'image "spam" doesn\'t exist' with self.assertRaises(tkinter.TclError) as cm: @@ -302,7 +303,7 @@ def test_width(self): class OptionMenuTest(MenubuttonTest, unittest.TestCase): - def _create(self, default='b', values=('a', 'b', 'c'), **kwargs): + def create(self, default='b', values=('a', 'b', 'c'), **kwargs): return tkinter.OptionMenu(self.root, None, default, *values, **kwargs) @@ -321,7 +322,7 @@ class EntryTest(AbstractWidgetTest, unittest.TestCase): 'validate', 'validatecommand', 'width', 'xscrollcommand', ) - def _create(self, **kwargs): + def create(self, **kwargs): return tkinter.Entry(self.root, **kwargs) def test_disabledbackground(self): @@ -329,10 +330,11 @@ def test_disabledbackground(self): self.checkColorParam(widget, 'disabledbackground') def test_insertborderwidth(self): - widget = self.create() - self.checkPixelsParam(widget, 'insertborderwidth', 0, 1.3, -2) - self.checkParam(widget, 'insertborderwidth', 2, expected=1) - self.checkParam(widget, 'insertborderwidth', '10p', expected=1) + widget = self.create(insertwidth=100) + self.checkPixelsParam(widget, 'insertborderwidth', + 0, 1.3, 2.6, 6, -2, '10p') + # insertborderwidth is bounded above by a half of insertwidth. + self.checkParam(widget, 'insertborderwidth', 60, expected=100//2) def test_insertwidth(self): widget = self.create() @@ -394,7 +396,7 @@ class SpinboxTest(EntryTest, unittest.TestCase): 'width', 'wrap', 'xscrollcommand', ) - def _create(self, **kwargs): + def create(self, **kwargs): return tkinter.Spinbox(self.root, **kwargs) test_show = None @@ -465,11 +467,7 @@ def test_wrap(self): def test_bbox(self): widget = self.create() - bbox = widget.bbox(0) - self.assertEqual(len(bbox), 4) - for item in bbox: - self.assertIsInstance(item, int) - + self.assertIsBoundingBox(widget.bbox(0)) self.assertRaises(tkinter.TclError, widget.bbox, 'noindex') self.assertRaises(tkinter.TclError, widget.bbox, None) self.assertRaises(TypeError, widget.bbox) @@ -492,9 +490,9 @@ class TextTest(AbstractWidgetTest, unittest.TestCase): 'xscrollcommand', 'yscrollcommand', ) if tcl_version < (8, 5): - wantobjects = False + _stringify = True - def _create(self, **kwargs): + def create(self, **kwargs): return tkinter.Text(self.root, **kwargs) def test_autoseparators(self): @@ -622,11 +620,7 @@ def test_wrap(self): def test_bbox(self): widget = self.create() - bbox = widget.bbox('1.1') - self.assertEqual(len(bbox), 4) - for item in bbox: - self.assertIsInstance(item, int) - + self.assertIsBoundingBox(widget.bbox('1.1')) self.assertIsNone(widget.bbox('end')) self.assertRaises(tkinter.TclError, widget.bbox, 'noindex') self.assertRaises(tkinter.TclError, widget.bbox, None) @@ -650,9 +644,9 @@ class CanvasTest(AbstractWidgetTest, unittest.TestCase): ) _conv_pixels = round - wantobjects = False + _stringify = True - def _create(self, **kwargs): + def create(self, **kwargs): return tkinter.Canvas(self.root, **kwargs) def test_closeenough(self): @@ -705,7 +699,7 @@ class ListboxTest(AbstractWidgetTest, unittest.TestCase): 'takefocus', 'width', 'xscrollcommand', 'yscrollcommand', ) - def _create(self, **kwargs): + def create(self, **kwargs): return tkinter.Listbox(self.root, **kwargs) def test_activestyle(self): @@ -715,7 +709,7 @@ def test_activestyle(self): def test_listvariable(self): widget = self.create() - var = tkinter.DoubleVar() + var = tkinter.DoubleVar(self.root) self.checkVariableParam(widget, 'listvariable', var) def test_selectmode(self): @@ -729,6 +723,101 @@ def test_state(self): widget = self.create() self.checkEnumParam(widget, 'state', 'disabled', 'normal') + def test_itemconfigure(self): + widget = self.create() + with self.assertRaisesRegex(TclError, 'item number "0" out of range'): + widget.itemconfigure(0) + colors = 'red orange yellow green blue white violet'.split() + widget.insert('end', *colors) + for i, color in enumerate(colors): + widget.itemconfigure(i, background=color) + with self.assertRaises(TypeError): + widget.itemconfigure() + with self.assertRaisesRegex(TclError, 'bad listbox index "red"'): + widget.itemconfigure('red') + self.assertEqual(widget.itemconfigure(0, 'background'), + ('background', 'background', 'Background', '', 'red')) + self.assertEqual(widget.itemconfigure('end', 'background'), + ('background', 'background', 'Background', '', 'violet')) + self.assertEqual(widget.itemconfigure('@0,0', 'background'), + ('background', 'background', 'Background', '', 'red')) + + d = widget.itemconfigure(0) + self.assertIsInstance(d, dict) + for k, v in d.items(): + self.assertIn(len(v), (2, 5)) + if len(v) == 5: + self.assertEqual(v, widget.itemconfigure(0, k)) + self.assertEqual(v[4], widget.itemcget(0, k)) + + def check_itemconfigure(self, name, value): + widget = self.create() + widget.insert('end', 'a', 'b', 'c', 'd') + widget.itemconfigure(0, **{name: value}) + self.assertEqual(widget.itemconfigure(0, name)[4], value) + self.assertEqual(widget.itemcget(0, name), value) + with self.assertRaisesRegex(TclError, 'unknown color name "spam"'): + widget.itemconfigure(0, **{name: 'spam'}) + + def test_itemconfigure_background(self): + self.check_itemconfigure('background', '#ff0000') + + def test_itemconfigure_bg(self): + self.check_itemconfigure('bg', '#ff0000') + + def test_itemconfigure_fg(self): + self.check_itemconfigure('fg', '#110022') + + def test_itemconfigure_foreground(self): + self.check_itemconfigure('foreground', '#110022') + + def test_itemconfigure_selectbackground(self): + self.check_itemconfigure('selectbackground', '#110022') + + def test_itemconfigure_selectforeground(self): + self.check_itemconfigure('selectforeground', '#654321') + + def test_box(self): + lb = self.create() + lb.insert(0, *('el%d' % i for i in range(8))) + lb.pack() + self.assertIsBoundingBox(lb.bbox(0)) + self.assertIsNone(lb.bbox(-1)) + self.assertIsNone(lb.bbox(10)) + self.assertRaises(TclError, lb.bbox, 'noindex') + self.assertRaises(TclError, lb.bbox, None) + self.assertRaises(TypeError, lb.bbox) + self.assertRaises(TypeError, lb.bbox, 0, 1) + + def test_curselection(self): + lb = self.create() + lb.insert(0, *('el%d' % i for i in range(8))) + lb.selection_clear(0, tkinter.END) + lb.selection_set(2, 4) + lb.selection_set(6) + self.assertEqual(lb.curselection(), (2, 3, 4, 6)) + self.assertRaises(TypeError, lb.curselection, 0) + + def test_get(self): + lb = self.create() + lb.insert(0, *('el%d' % i for i in range(8))) + self.assertEqual(lb.get(0), 'el0') + self.assertEqual(lb.get(3), 'el3') + self.assertEqual(lb.get('end'), 'el7') + self.assertEqual(lb.get(8), '') + self.assertEqual(lb.get(-1), '') + self.assertEqual(lb.get(3, 5), ('el3', 'el4', 'el5')) + self.assertEqual(lb.get(5, 'end'), ('el5', 'el6', 'el7')) + self.assertEqual(lb.get(5, 0), ()) + self.assertEqual(lb.get(0, 0), ('el0',)) + self.assertRaises(TclError, lb.get, 'noindex') + self.assertRaises(TclError, lb.get, None) + self.assertRaises(TypeError, lb.get) + self.assertRaises(TclError, lb.get, 'end', 'noindex') + self.assertRaises(TypeError, lb.get, 1, 2, 3) + self.assertRaises(TclError, lb.get, 2.4) + + @add_standard_options(PixelSizeTests, StandardOptionsTests) class ScaleTest(AbstractWidgetTest, unittest.TestCase): OPTIONS = ( @@ -742,7 +831,7 @@ class ScaleTest(AbstractWidgetTest, unittest.TestCase): ) default_orient = 'vertical' - def _create(self, **kwargs): + def create(self, **kwargs): return tkinter.Scale(self.root, **kwargs) def test_bigincrement(self): @@ -808,10 +897,10 @@ class ScrollbarTest(AbstractWidgetTest, unittest.TestCase): 'takefocus', 'troughcolor', 'width', ) _conv_pixels = round - wantobjects = False + _stringify = True default_orient = 'vertical' - def _create(self, **kwargs): + def create(self, **kwargs): return tkinter.Scrollbar(self.root, **kwargs) def test_activerelief(self): @@ -827,6 +916,25 @@ def test_orient(self): self.checkEnumParam(widget, 'orient', 'vertical', 'horizontal', errmsg='bad orientation "{}": must be vertical or horizontal') + def test_activate(self): + sb = self.create() + for e in ('arrow1', 'slider', 'arrow2'): + sb.activate(e) + self.assertEqual(sb.activate(), e) + sb.activate('') + self.assertIsNone(sb.activate()) + self.assertRaises(TypeError, sb.activate, 'arrow1', 'arrow2') + + def test_set(self): + sb = self.create() + sb.set(0.2, 0.4) + self.assertEqual(sb.get(), (0.2, 0.4)) + self.assertRaises(TclError, sb.set, 'abc', 'def') + self.assertRaises(TclError, sb.set, 0.6, 'def') + self.assertRaises(TclError, sb.set, 0.6, None) + self.assertRaises(TypeError, sb.set, 0.6) + self.assertRaises(TypeError, sb.set, 0.6, 0.7, 0.8) + @add_standard_options(StandardOptionsTests) class PanedWindowTest(AbstractWidgetTest, unittest.TestCase): @@ -839,7 +947,7 @@ class PanedWindowTest(AbstractWidgetTest, unittest.TestCase): ) default_orient = 'horizontal' - def _create(self, **kwargs): + def create(self, **kwargs): return tkinter.PanedWindow(self.root, **kwargs) def test_handlepad(self): @@ -886,6 +994,105 @@ def test_width(self): self.checkPixelsParam(widget, 'width', 402, 403.4, 404.6, -402, 0, '5i', conv=noconv) + def create2(self): + p = self.create() + b = tkinter.Button(p) + c = tkinter.Button(p) + p.add(b) + p.add(c) + return p, b, c + + def test_paneconfigure(self): + p, b, c = self.create2() + self.assertRaises(TypeError, p.paneconfigure) + d = p.paneconfigure(b) + self.assertIsInstance(d, dict) + for k, v in d.items(): + self.assertEqual(len(v), 5) + self.assertEqual(v, p.paneconfigure(b, k)) + self.assertEqual(v[4], p.panecget(b, k)) + + def check_paneconfigure(self, p, b, name, value, expected, stringify=False): + conv = lambda x: x + if not self.wantobjects or stringify: + expected = str(expected) + if self.wantobjects and stringify: + conv = str + p.paneconfigure(b, **{name: value}) + self.assertEqual(conv(p.paneconfigure(b, name)[4]), expected) + self.assertEqual(conv(p.panecget(b, name)), expected) + + def check_paneconfigure_bad(self, p, b, name, msg): + with self.assertRaisesRegex(TclError, msg): + p.paneconfigure(b, **{name: 'badValue'}) + + def test_paneconfigure_after(self): + p, b, c = self.create2() + self.check_paneconfigure(p, b, 'after', c, str(c)) + self.check_paneconfigure_bad(p, b, 'after', + 'bad window path name "badValue"') + + def test_paneconfigure_before(self): + p, b, c = self.create2() + self.check_paneconfigure(p, b, 'before', c, str(c)) + self.check_paneconfigure_bad(p, b, 'before', + 'bad window path name "badValue"') + + def test_paneconfigure_height(self): + p, b, c = self.create2() + self.check_paneconfigure(p, b, 'height', 10, 10, + stringify=tcl_version < (8, 5)) + self.check_paneconfigure_bad(p, b, 'height', + 'bad screen distance "badValue"') + + @requires_tcl(8, 5) + def test_paneconfigure_hide(self): + p, b, c = self.create2() + self.check_paneconfigure(p, b, 'hide', False, 0) + self.check_paneconfigure_bad(p, b, 'hide', + 'expected boolean value but got "badValue"') + + def test_paneconfigure_minsize(self): + p, b, c = self.create2() + self.check_paneconfigure(p, b, 'minsize', 10, 10) + self.check_paneconfigure_bad(p, b, 'minsize', + 'bad screen distance "badValue"') + + def test_paneconfigure_padx(self): + p, b, c = self.create2() + self.check_paneconfigure(p, b, 'padx', 1.3, 1) + self.check_paneconfigure_bad(p, b, 'padx', + 'bad screen distance "badValue"') + + def test_paneconfigure_pady(self): + p, b, c = self.create2() + self.check_paneconfigure(p, b, 'pady', 1.3, 1) + self.check_paneconfigure_bad(p, b, 'pady', + 'bad screen distance "badValue"') + + def test_paneconfigure_sticky(self): + p, b, c = self.create2() + self.check_paneconfigure(p, b, 'sticky', 'nsew', 'nesw') + self.check_paneconfigure_bad(p, b, 'sticky', + 'bad stickyness value "badValue": must ' + 'be a string containing zero or more of ' + 'n, e, s, and w') + + @requires_tcl(8, 5) + def test_paneconfigure_stretch(self): + p, b, c = self.create2() + self.check_paneconfigure(p, b, 'stretch', 'alw', 'always') + self.check_paneconfigure_bad(p, b, 'stretch', + 'bad stretch "badValue": must be ' + 'always, first, last, middle, or never') + + def test_paneconfigure_width(self): + p, b, c = self.create2() + self.check_paneconfigure(p, b, 'width', 10, 10, + stringify=tcl_version < (8, 5)) + self.check_paneconfigure_bad(p, b, 'width', + 'bad screen distance "badValue"') + @add_standard_options(StandardOptionsTests) class MenuTest(AbstractWidgetTest, unittest.TestCase): @@ -898,7 +1105,7 @@ class MenuTest(AbstractWidgetTest, unittest.TestCase): ) _conv_pixels = noconv - def _create(self, **kwargs): + def create(self, **kwargs): return tkinter.Menu(self.root, **kwargs) def test_postcommand(self): @@ -922,6 +1129,39 @@ def test_type(self): self.checkEnumParam(widget, 'type', 'normal', 'tearoff', 'menubar') + def test_entryconfigure(self): + m1 = self.create() + m1.add_command(label='test') + self.assertRaises(TypeError, m1.entryconfigure) + with self.assertRaisesRegex(TclError, 'bad menu entry index "foo"'): + m1.entryconfigure('foo') + d = m1.entryconfigure(1) + self.assertIsInstance(d, dict) + for k, v in d.items(): + self.assertIsInstance(k, str) + self.assertIsInstance(v, tuple) + self.assertEqual(len(v), 5) + self.assertEqual(v[0], k) + self.assertEqual(m1.entrycget(1, k), v[4]) + m1.destroy() + + def test_entryconfigure_label(self): + m1 = self.create() + m1.add_command(label='test') + self.assertEqual(m1.entrycget(1, 'label'), 'test') + m1.entryconfigure(1, label='changed') + self.assertEqual(m1.entrycget(1, 'label'), 'changed') + + def test_entryconfigure_variable(self): + m1 = self.create() + v1 = tkinter.BooleanVar(self.root) + v2 = tkinter.BooleanVar(self.root) + m1.add_checkbutton(variable=v1, onvalue=True, offvalue=False, + label='Nonsense') + self.assertEqual(str(m1.entrycget(1, 'variable')), str(v1)) + m1.entryconfigure(1, variable=v2) + self.assertEqual(str(m1.entrycget(1, 'variable')), str(v2)) + @add_standard_options(PixelSizeTests, StandardOptionsTests) class MessageTest(AbstractWidgetTest, unittest.TestCase): @@ -934,7 +1174,7 @@ class MessageTest(AbstractWidgetTest, unittest.TestCase): ) _conv_pad_pixels = noconv - def _create(self, **kwargs): + def create(self, **kwargs): return tkinter.Message(self.root, **kwargs) def test_aspect(self): diff --git a/Lib/tkinter/test/test_ttk/test_extensions.py b/Lib/tkinter/test/test_ttk/test_extensions.py index 0bd8c92763a6..c3af06cddd0c 100644 --- a/Lib/tkinter/test/test_ttk/test_extensions.py +++ b/Lib/tkinter/test/test_ttk/test_extensions.py @@ -2,82 +2,93 @@ import unittest import tkinter from tkinter import ttk -from test.support import requires, run_unittest - -import tkinter.test.support as support +from test.support import requires, run_unittest, swap_attr +from tkinter.test.support import AbstractTkTest, destroy_default_root requires('gui') -class LabeledScaleTest(unittest.TestCase): - - def setUp(self): - support.root_deiconify() +class LabeledScaleTest(AbstractTkTest, unittest.TestCase): def tearDown(self): - support.root_withdraw() - + self.root.update_idletasks() + super().tearDown() def test_widget_destroy(self): # automatically created variable - x = ttk.LabeledScale() + x = ttk.LabeledScale(self.root) var = x._variable._name x.destroy() self.assertRaises(tkinter.TclError, x.tk.globalgetvar, var) # manually created variable - myvar = tkinter.DoubleVar() + myvar = tkinter.DoubleVar(self.root) name = myvar._name - x = ttk.LabeledScale(variable=myvar) + x = ttk.LabeledScale(self.root, variable=myvar) x.destroy() - self.assertEqual(x.tk.globalgetvar(name), myvar.get()) + if self.wantobjects: + self.assertEqual(x.tk.globalgetvar(name), myvar.get()) + else: + self.assertEqual(float(x.tk.globalgetvar(name)), myvar.get()) del myvar self.assertRaises(tkinter.TclError, x.tk.globalgetvar, name) # checking that the tracing callback is properly removed - myvar = tkinter.IntVar() + myvar = tkinter.IntVar(self.root) # LabeledScale will start tracing myvar - x = ttk.LabeledScale(variable=myvar) + x = ttk.LabeledScale(self.root, variable=myvar) x.destroy() # Unless the tracing callback was removed, creating a new # LabeledScale with the same var will cause an error now. This # happens because the variable will be set to (possibly) a new # value which causes the tracing callback to be called and then # it tries calling instance attributes not yet defined. - ttk.LabeledScale(variable=myvar) + ttk.LabeledScale(self.root, variable=myvar) if hasattr(sys, 'last_type'): self.assertNotEqual(sys.last_type, tkinter.TclError) + def test_initialization_no_master(self): + # no master passing + with swap_attr(tkinter, '_default_root', None), \ + swap_attr(tkinter, '_support_default_root', True): + try: + x = ttk.LabeledScale() + self.assertIsNotNone(tkinter._default_root) + self.assertEqual(x.master, tkinter._default_root) + self.assertEqual(x.tk, tkinter._default_root.tk) + x.destroy() + finally: + destroy_default_root() + def test_initialization(self): # master passing - x = ttk.LabeledScale() - self.assertEqual(x.master, tkinter._default_root) - x.destroy() - master = tkinter.Frame() + master = tkinter.Frame(self.root) x = ttk.LabeledScale(master) self.assertEqual(x.master, master) x.destroy() # variable initialization/passing - passed_expected = ((2.5, 2), ('0', 0), (0, 0), (10, 10), + passed_expected = (('0', 0), (0, 0), (10, 10), (-1, -1), (sys.maxsize + 1, sys.maxsize + 1)) + if self.wantobjects: + passed_expected += ((2.5, 2),) for pair in passed_expected: - x = ttk.LabeledScale(from_=pair[0]) + x = ttk.LabeledScale(self.root, from_=pair[0]) self.assertEqual(x.value, pair[1]) x.destroy() - x = ttk.LabeledScale(from_='2.5') + x = ttk.LabeledScale(self.root, from_='2.5') self.assertRaises(ValueError, x._variable.get) x.destroy() - x = ttk.LabeledScale(from_=None) + x = ttk.LabeledScale(self.root, from_=None) self.assertRaises(ValueError, x._variable.get) x.destroy() # variable should have its default value set to the from_ value - myvar = tkinter.DoubleVar(value=20) - x = ttk.LabeledScale(variable=myvar) + myvar = tkinter.DoubleVar(self.root, value=20) + x = ttk.LabeledScale(self.root, variable=myvar) self.assertEqual(x.value, 0) x.destroy() # check that it is really using a DoubleVar - x = ttk.LabeledScale(variable=myvar, from_=0.5) + x = ttk.LabeledScale(self.root, variable=myvar, from_=0.5) self.assertEqual(x.value, 0.5) self.assertEqual(x._variable._name, myvar._name) x.destroy() @@ -86,25 +97,26 @@ def test_initialization(self): def check_positions(scale, scale_pos, label, label_pos): self.assertEqual(scale.pack_info()['side'], scale_pos) self.assertEqual(label.place_info()['anchor'], label_pos) - x = ttk.LabeledScale(compound='top') + x = ttk.LabeledScale(self.root, compound='top') check_positions(x.scale, 'bottom', x.label, 'n') x.destroy() - x = ttk.LabeledScale(compound='bottom') + x = ttk.LabeledScale(self.root, compound='bottom') check_positions(x.scale, 'top', x.label, 's') x.destroy() - x = ttk.LabeledScale(compound='unknown') # invert default positions + # invert default positions + x = ttk.LabeledScale(self.root, compound='unknown') check_positions(x.scale, 'top', x.label, 's') x.destroy() - x = ttk.LabeledScale() # take default positions + x = ttk.LabeledScale(self.root) # take default positions check_positions(x.scale, 'bottom', x.label, 'n') x.destroy() # extra, and invalid, kwargs - self.assertRaises(tkinter.TclError, ttk.LabeledScale, a='b') + self.assertRaises(tkinter.TclError, ttk.LabeledScale, master, a='b') def test_horizontal_range(self): - lscale = ttk.LabeledScale(from_=0, to=10) + lscale = ttk.LabeledScale(self.root, from_=0, to=10) lscale.pack() lscale.wait_visibility() lscale.update() @@ -123,7 +135,7 @@ def test_horizontal_range(self): self.assertNotEqual(prev_xcoord, curr_xcoord) # the label widget should have been repositioned too linfo_2 = lscale.label.place_info() - self.assertEqual(lscale.label['text'], 0) + self.assertEqual(lscale.label['text'], 0 if self.wantobjects else '0') self.assertEqual(curr_xcoord, int(linfo_2['x'])) # change the range back lscale.scale.configure(from_=0, to=10) @@ -134,7 +146,7 @@ def test_horizontal_range(self): def test_variable_change(self): - x = ttk.LabeledScale() + x = ttk.LabeledScale(self.root) x.pack() x.wait_visibility() x.update() @@ -145,15 +157,20 @@ def test_variable_change(self): # The following update is needed since the test doesn't use mainloop, # at the same time this shouldn't affect test outcome x.update() - self.assertEqual(x.label['text'], newval) + self.assertEqual(x.label['text'], + newval if self.wantobjects else str(newval)) self.assertGreater(x.scale.coords()[0], curr_xcoord) self.assertEqual(x.scale.coords()[0], int(x.label.place_info()['x'])) # value outside range - x.value = x.scale['to'] + 1 # no changes shouldn't happen + if self.wantobjects: + conv = lambda x: x + else: + conv = int + x.value = conv(x.scale['to']) + 1 # no changes shouldn't happen x.update() - self.assertEqual(x.label['text'], newval) + self.assertEqual(conv(x.label['text']), newval) self.assertEqual(x.scale.coords()[0], int(x.label.place_info()['x'])) @@ -161,7 +178,7 @@ def test_variable_change(self): def test_resize(self): - x = ttk.LabeledScale() + x = ttk.LabeledScale(self.root) x.pack(expand=True, fill='both') x.wait_visibility() x.update() @@ -180,20 +197,20 @@ def test_resize(self): x.destroy() -class OptionMenuTest(unittest.TestCase): +class OptionMenuTest(AbstractTkTest, unittest.TestCase): def setUp(self): - support.root_deiconify() - self.textvar = tkinter.StringVar() + super().setUp() + self.textvar = tkinter.StringVar(self.root) def tearDown(self): del self.textvar - support.root_withdraw() + super().tearDown() def test_widget_destroy(self): - var = tkinter.StringVar() - optmenu = ttk.OptionMenu(None, var) + var = tkinter.StringVar(self.root) + optmenu = ttk.OptionMenu(self.root, var) name = var._name optmenu.update_idletasks() optmenu.destroy() @@ -204,9 +221,9 @@ def test_widget_destroy(self): def test_initialization(self): self.assertRaises(tkinter.TclError, - ttk.OptionMenu, None, self.textvar, invalid='thing') + ttk.OptionMenu, self.root, self.textvar, invalid='thing') - optmenu = ttk.OptionMenu(None, self.textvar, 'b', 'a', 'b') + optmenu = ttk.OptionMenu(self.root, self.textvar, 'b', 'a', 'b') self.assertEqual(optmenu._variable.get(), 'b') self.assertTrue(optmenu['menu']) @@ -218,7 +235,7 @@ def test_initialization(self): def test_menu(self): items = ('a', 'b', 'c') default = 'a' - optmenu = ttk.OptionMenu(None, self.textvar, default, *items) + optmenu = ttk.OptionMenu(self.root, self.textvar, default, *items) found_default = False for i in range(len(items)): value = optmenu['menu'].entrycget(i, 'value') @@ -230,7 +247,7 @@ def test_menu(self): # default shouldn't be in menu if it is not part of values default = 'd' - optmenu = ttk.OptionMenu(None, self.textvar, default, *items) + optmenu = ttk.OptionMenu(self.root, self.textvar, default, *items) curr = None i = 0 while True: @@ -259,7 +276,7 @@ def test_menu(self): def cb_test(item): self.assertEqual(item, items[1]) success.append(True) - optmenu = ttk.OptionMenu(None, self.textvar, 'a', command=cb_test, + optmenu = ttk.OptionMenu(self.root, self.textvar, 'a', command=cb_test, *items) optmenu['menu'].invoke(1) if not success: diff --git a/Lib/tkinter/test/test_ttk/test_functions.py b/Lib/tkinter/test/test_ttk/test_functions.py index 0d8df1630cb8..c9dcf975f820 100644 --- a/Lib/tkinter/test/test_ttk/test_functions.py +++ b/Lib/tkinter/test/test_ttk/test_functions.py @@ -1,7 +1,19 @@ # -*- encoding: utf-8 -*- import unittest +import tkinter from tkinter import ttk +class MockTkApp: + + def splitlist(self, arg): + if isinstance(arg, tuple): + return arg + return arg.split(':') + + def wantobjects(self): + return True + + class MockTclObj(object): typename = 'test' @@ -312,26 +324,13 @@ def test_script_from_settings(self): "-opt {3 2m}") - def test_dict_from_tcltuple(self): - fakettuple = ('-a', '{1 2 3}', '-something', 'foo') - - self.assertEqual(ttk._dict_from_tcltuple(fakettuple, False), - {'-a': '{1 2 3}', '-something': 'foo'}) - - self.assertEqual(ttk._dict_from_tcltuple(fakettuple), - {'a': '{1 2 3}', 'something': 'foo'}) - - # passing a tuple with a single item should return an empty dict, - # since it tries to break the tuple by pairs. - self.assertFalse(ttk._dict_from_tcltuple(('single', ))) - - sspec = MockStateSpec('a', 'b') - self.assertEqual(ttk._dict_from_tcltuple(('-a', (sspec, 'val'))), - {'a': [('a', 'b', 'val')]}) - - self.assertEqual(ttk._dict_from_tcltuple((MockTclObj('-padding'), - [MockTclObj('1'), 2, MockTclObj('3m')])), - {'padding': [1, 2, '3m']}) + def test_tclobj_to_py(self): + self.assertEqual( + ttk._tclobj_to_py((MockStateSpec('a', 'b'), 'val')), + [('a', 'b', 'val')]) + self.assertEqual( + ttk._tclobj_to_py([MockTclObj('1'), 2, MockTclObj('3m')]), + [1, 2, '3m']) def test_list_from_statespec(self): @@ -352,20 +351,22 @@ def test_it(sspec, value, res_value, states): def test_list_from_layouttuple(self): + tk = MockTkApp() + # empty layout tuple - self.assertFalse(ttk._list_from_layouttuple(())) + self.assertFalse(ttk._list_from_layouttuple(tk, ())) # shortest layout tuple - self.assertEqual(ttk._list_from_layouttuple(('name', )), + self.assertEqual(ttk._list_from_layouttuple(tk, ('name', )), [('name', {})]) # not so interesting ltuple sample_ltuple = ('name', '-option', 'value') - self.assertEqual(ttk._list_from_layouttuple(sample_ltuple), + self.assertEqual(ttk._list_from_layouttuple(tk, sample_ltuple), [('name', {'option': 'value'})]) # empty children - self.assertEqual(ttk._list_from_layouttuple( + self.assertEqual(ttk._list_from_layouttuple(tk, ('something', '-children', ())), [('something', {'children': []})] ) @@ -378,7 +379,7 @@ def test_list_from_layouttuple(self): ) ) ) - self.assertEqual(ttk._list_from_layouttuple(ltuple), + self.assertEqual(ttk._list_from_layouttuple(tk, ltuple), [('name', {'option': 'niceone', 'children': [('otherone', {'otheropt': 'othervalue', 'children': [('child', {})] @@ -387,27 +388,35 @@ def test_list_from_layouttuple(self): ) # bad tuples - self.assertRaises(ValueError, ttk._list_from_layouttuple, + self.assertRaises(ValueError, ttk._list_from_layouttuple, tk, ('name', 'no_minus')) - self.assertRaises(ValueError, ttk._list_from_layouttuple, + self.assertRaises(ValueError, ttk._list_from_layouttuple, tk, ('name', 'no_minus', 'value')) - self.assertRaises(ValueError, ttk._list_from_layouttuple, + self.assertRaises(ValueError, ttk._list_from_layouttuple, tk, ('something', '-children')) # no children - self.assertRaises(ValueError, ttk._list_from_layouttuple, - ('something', '-children', 'value')) # invalid children def test_val_or_dict(self): - def func(opt, val=None): + def func(res, opt=None, val=None): + if opt is None: + return res if val is None: return "test val" return (opt, val) - options = {'test': None} - self.assertEqual(ttk._val_or_dict(options, func), "test val") + tk = MockTkApp() + tk.call = func + + self.assertEqual(ttk._val_or_dict(tk, {}, '-test:3'), + {'test': '3'}) + self.assertEqual(ttk._val_or_dict(tk, {}, ('-test', 3)), + {'test': 3}) + + self.assertEqual(ttk._val_or_dict(tk, {'test': None}, 'x:y'), + 'test val') - options = {'test': 3} - self.assertEqual(ttk._val_or_dict(options, func), options) + self.assertEqual(ttk._val_or_dict(tk, {'test': 3}, 'x:y'), + {'test': 3}) def test_convert_stringval(self): diff --git a/Lib/tkinter/test/test_ttk/test_style.py b/Lib/tkinter/test/test_ttk/test_style.py index 2466c73994f7..3537536d81bc 100644 --- a/Lib/tkinter/test/test_ttk/test_style.py +++ b/Lib/tkinter/test/test_ttk/test_style.py @@ -2,15 +2,15 @@ import tkinter from tkinter import ttk from test.support import requires, run_unittest - -import tkinter.test.support as support +from tkinter.test.support import AbstractTkTest requires('gui') -class StyleTest(unittest.TestCase): +class StyleTest(AbstractTkTest, unittest.TestCase): def setUp(self): - self.style = ttk.Style() + super().setUp() + self.style = ttk.Style(self.root) def test_configure(self): @@ -25,7 +25,8 @@ def test_map(self): style = self.style style.map('TButton', background=[('active', 'background', 'blue')]) self.assertEqual(style.map('TButton', 'background'), - [('active', 'background', 'blue')]) + [('active', 'background', 'blue')] if self.wantobjects else + [('active background', 'blue')]) self.assertIsInstance(style.map('TButton'), dict) diff --git a/Lib/tkinter/test/test_ttk/test_widgets.py b/Lib/tkinter/test/test_ttk/test_widgets.py index 0035214b8017..8a27324d5237 100644 --- a/Lib/tkinter/test/test_ttk/test_widgets.py +++ b/Lib/tkinter/test/test_ttk/test_widgets.py @@ -1,12 +1,12 @@ import unittest import tkinter -from tkinter import ttk +from tkinter import ttk, TclError from test.support import requires import sys -import tkinter.test.support as support from tkinter.test.test_ttk.test_functions import MockTclObj -from tkinter.test.support import tcl_version +from tkinter.test.support import (AbstractTkTest, tcl_version, get_tk_patchlevel, + simulate_mouse_click) from tkinter.test.widget_tests import (add_standard_options, noconv, AbstractWidgetTest, StandardOptionsTests, IntegerSizeTests, PixelSizeTests, setUpModule) @@ -20,7 +20,7 @@ def test_class(self): widget = self.create() self.assertEqual(widget['class'], '') errmsg='attempt to change read-only option' - if tcl_version < (8, 6): + if get_tk_patchlevel() < (8, 6, 0): # actually this was changed in 8.6b3 errmsg='Attempt to change read-only option' self.checkInvalidParam(widget, 'class', 'Foo', errmsg=errmsg) widget2 = self.create(class_='Foo') @@ -53,19 +53,15 @@ def test_style(self): pass -class WidgetTest(unittest.TestCase): +class WidgetTest(AbstractTkTest, unittest.TestCase): """Tests methods available in every ttk widget.""" def setUp(self): - support.root_deiconify() - self.widget = ttk.Button(width=0, text="Text") + super().setUp() + self.widget = ttk.Button(self.root, width=0, text="Text") self.widget.pack() self.widget.wait_visibility() - def tearDown(self): - self.widget.destroy() - support.root_withdraw() - def test_identify(self): self.widget.update_idletasks() @@ -128,7 +124,7 @@ class FrameTest(AbstractToplevelTest, unittest.TestCase): 'width', ) - def _create(self, **kwargs): + def create(self, **kwargs): return ttk.Frame(self.root, **kwargs) @@ -141,7 +137,7 @@ class LabelFrameTest(AbstractToplevelTest, unittest.TestCase): 'text', 'underline', 'width', ) - def _create(self, **kwargs): + def create(self, **kwargs): return ttk.LabelFrame(self.root, **kwargs) def test_labelanchor(self): @@ -161,8 +157,8 @@ def test_labelwidget(self): class AbstractLabelTest(AbstractWidgetTest): def checkImageParam(self, widget, name): - image = tkinter.PhotoImage('image1') - image2 = tkinter.PhotoImage('image2') + image = tkinter.PhotoImage(master=self.root, name='image1') + image2 = tkinter.PhotoImage(master=self.root, name='image2') self.checkParam(widget, name, image, expected=('image1',)) self.checkParam(widget, name, 'image1', expected=('image1',)) self.checkParam(widget, name, (image,), expected=('image1',)) @@ -199,7 +195,7 @@ class LabelTest(AbstractLabelTest, unittest.TestCase): ) _conv_pixels = noconv - def _create(self, **kwargs): + def create(self, **kwargs): return ttk.Label(self.root, **kwargs) def test_font(self): @@ -216,7 +212,7 @@ class ButtonTest(AbstractLabelTest, unittest.TestCase): 'underline', 'width', ) - def _create(self, **kwargs): + def create(self, **kwargs): return ttk.Button(self.root, **kwargs) def test_default(self): @@ -225,7 +221,7 @@ def test_default(self): def test_invoke(self): success = [] - btn = ttk.Button(command=lambda: success.append(1)) + btn = ttk.Button(self.root, command=lambda: success.append(1)) btn.invoke() self.assertTrue(success) @@ -241,7 +237,7 @@ class CheckbuttonTest(AbstractLabelTest, unittest.TestCase): 'underline', 'variable', 'width', ) - def _create(self, **kwargs): + def create(self, **kwargs): return ttk.Checkbutton(self.root, **kwargs) def test_offvalue(self): @@ -258,7 +254,7 @@ def cb_test(): success.append(1) return "cb test called" - cbtn = ttk.Checkbutton(command=cb_test) + cbtn = ttk.Checkbutton(self.root, command=cb_test) # the variable automatically created by ttk.Checkbutton is actually # undefined till we invoke the Checkbutton self.assertEqual(cbtn.state(), ('alternate', )) @@ -289,15 +285,9 @@ class ComboboxTest(AbstractWidgetTest, unittest.TestCase): def setUp(self): super().setUp() - support.root_deiconify() self.combo = self.create() - def tearDown(self): - self.combo.destroy() - support.root_withdraw() - super().tearDown() - - def _create(self, **kwargs): + def create(self, **kwargs): return ttk.Combobox(self.root, **kwargs) def test_height(self): @@ -382,15 +372,21 @@ def check_get_current(getval, currval): # testing values with empty string set through configure self.combo.configure(values=[1, '', 2]) - self.assertEqual(self.combo['values'], ('1', '', '2')) + self.assertEqual(self.combo['values'], + ('1', '', '2') if self.wantobjects else + '1 {} 2') # testing values with spaces self.combo['values'] = ['a b', 'a\tb', 'a\nb'] - self.assertEqual(self.combo['values'], ('a b', 'a\tb', 'a\nb')) + self.assertEqual(self.combo['values'], + ('a b', 'a\tb', 'a\nb') if self.wantobjects else + '{a b} {a\tb} {a\nb}') # testing values with special characters self.combo['values'] = [r'a\tb', '"a"', '} {'] - self.assertEqual(self.combo['values'], (r'a\tb', '"a"', '} {')) + self.assertEqual(self.combo['values'], + (r'a\tb', '"a"', '} {') if self.wantobjects else + r'a\\tb {"a"} \}\ \{') # out of range self.assertRaises(tkinter.TclError, self.combo.current, @@ -399,8 +395,9 @@ def check_get_current(getval, currval): self.assertRaises(tkinter.TclError, self.combo.current, '') # testing creating combobox with empty string in values - combo2 = ttk.Combobox(values=[1, 2, '']) - self.assertEqual(combo2['values'], ('1', '2', '')) + combo2 = ttk.Combobox(self.root, values=[1, 2, '']) + self.assertEqual(combo2['values'], + ('1', '2', '') if self.wantobjects else '1 2 {}') combo2.destroy() @@ -416,15 +413,9 @@ class EntryTest(AbstractWidgetTest, unittest.TestCase): def setUp(self): super().setUp() - support.root_deiconify() self.entry = self.create() - def tearDown(self): - self.entry.destroy() - support.root_withdraw() - super().tearDown() - - def _create(self, **kwargs): + def create(self, **kwargs): return ttk.Entry(self.root, **kwargs) def test_invalidcommand(self): @@ -453,10 +444,7 @@ def test_validatecommand(self): def test_bbox(self): - self.assertEqual(len(self.entry.bbox(0)), 4) - for item in self.entry.bbox(0): - self.assertIsInstance(item, int) - + self.assertIsBoundingBox(self.entry.bbox(0)) self.assertRaises(tkinter.TclError, self.entry.bbox, 'noindex') self.assertRaises(tkinter.TclError, self.entry.bbox, None) @@ -554,22 +542,16 @@ class PanedWindowTest(AbstractWidgetTest, unittest.TestCase): def setUp(self): super().setUp() - support.root_deiconify() self.paned = self.create() - def tearDown(self): - self.paned.destroy() - support.root_withdraw() - super().tearDown() - - def _create(self, **kwargs): + def create(self, **kwargs): return ttk.PanedWindow(self.root, **kwargs) def test_orient(self): widget = self.create() self.assertEqual(str(widget['orient']), 'vertical') errmsg='attempt to change read-only option' - if tcl_version < (8, 6): + if get_tk_patchlevel() < (8, 6, 0): # actually this was changed in 8.6b3 errmsg='Attempt to change read-only option' self.checkInvalidParam(widget, 'orient', 'horizontal', errmsg=errmsg) @@ -584,13 +566,13 @@ def test_add(self): label.destroy() child.destroy() # another attempt - label = ttk.Label() + label = ttk.Label(self.root) child = ttk.Label(label) self.assertRaises(tkinter.TclError, self.paned.add, child) child.destroy() label.destroy() - good_child = ttk.Label() + good_child = ttk.Label(self.root) self.paned.add(good_child) # re-adding a child is not accepted self.assertRaises(tkinter.TclError, self.paned.add, good_child) @@ -608,7 +590,7 @@ def test_forget(self): self.assertRaises(tkinter.TclError, self.paned.forget, None) self.assertRaises(tkinter.TclError, self.paned.forget, 0) - self.paned.add(ttk.Label()) + self.paned.add(ttk.Label(self.root)) self.paned.forget(0) self.assertRaises(tkinter.TclError, self.paned.forget, 0) @@ -618,9 +600,9 @@ def test_insert(self): self.assertRaises(tkinter.TclError, self.paned.insert, 0, None) self.assertRaises(tkinter.TclError, self.paned.insert, 0, 0) - child = ttk.Label() - child2 = ttk.Label() - child3 = ttk.Label() + child = ttk.Label(self.root) + child2 = ttk.Label(self.root) + child3 = ttk.Label(self.root) self.assertRaises(tkinter.TclError, self.paned.insert, 0, child) @@ -651,12 +633,14 @@ def test_insert(self): def test_pane(self): self.assertRaises(tkinter.TclError, self.paned.pane, 0) - child = ttk.Label() + child = ttk.Label(self.root) self.paned.add(child) self.assertIsInstance(self.paned.pane(0), dict) - self.assertEqual(self.paned.pane(0, weight=None), 0) + self.assertEqual(self.paned.pane(0, weight=None), + 0 if self.wantobjects else '0') # newer form for querying a single option - self.assertEqual(self.paned.pane(0, 'weight'), 0) + self.assertEqual(self.paned.pane(0, 'weight'), + 0 if self.wantobjects else '0') self.assertEqual(self.paned.pane(0), self.paned.pane(str(child))) self.assertRaises(tkinter.TclError, self.paned.pane, 0, @@ -694,7 +678,7 @@ class RadiobuttonTest(AbstractLabelTest, unittest.TestCase): 'underline', 'value', 'variable', 'width', ) - def _create(self, **kwargs): + def create(self, **kwargs): return ttk.Radiobutton(self.root, **kwargs) def test_value(self): @@ -707,24 +691,31 @@ def cb_test(): success.append(1) return "cb test called" - myvar = tkinter.IntVar() - cbtn = ttk.Radiobutton(command=cb_test, variable=myvar, value=0) - cbtn2 = ttk.Radiobutton(command=cb_test, variable=myvar, value=1) + myvar = tkinter.IntVar(self.root) + cbtn = ttk.Radiobutton(self.root, command=cb_test, + variable=myvar, value=0) + cbtn2 = ttk.Radiobutton(self.root, command=cb_test, + variable=myvar, value=1) + + if self.wantobjects: + conv = lambda x: x + else: + conv = int res = cbtn.invoke() self.assertEqual(res, "cb test called") - self.assertEqual(cbtn['value'], myvar.get()) + self.assertEqual(conv(cbtn['value']), myvar.get()) self.assertEqual(myvar.get(), - cbtn.tk.globalgetvar(cbtn['variable'])) + conv(cbtn.tk.globalgetvar(cbtn['variable']))) self.assertTrue(success) cbtn2['command'] = '' res = cbtn2.invoke() self.assertEqual(str(res), '') self.assertLessEqual(len(success), 1) - self.assertEqual(cbtn2['value'], myvar.get()) + self.assertEqual(conv(cbtn2['value']), myvar.get()) self.assertEqual(myvar.get(), - cbtn.tk.globalgetvar(cbtn['variable'])) + conv(cbtn.tk.globalgetvar(cbtn['variable']))) self.assertEqual(str(cbtn['variable']), str(cbtn2['variable'])) @@ -737,7 +728,7 @@ class MenubuttonTest(AbstractLabelTest, unittest.TestCase): 'underline', 'width', ) - def _create(self, **kwargs): + def create(self, **kwargs): return ttk.Menubutton(self.root, **kwargs) def test_direction(self): @@ -763,17 +754,11 @@ class ScaleTest(AbstractWidgetTest, unittest.TestCase): def setUp(self): super().setUp() - support.root_deiconify() self.scale = self.create() self.scale.pack() self.scale.update() - def tearDown(self): - self.scale.destroy() - support.root_withdraw() - super().tearDown() - - def _create(self, **kwargs): + def create(self, **kwargs): return ttk.Scale(self.root, **kwargs) def test_from(self): @@ -812,10 +797,15 @@ def test_custom_event(self): def test_get(self): + if self.wantobjects: + conv = lambda x: x + else: + conv = float + scale_width = self.scale.winfo_width() self.assertEqual(self.scale.get(scale_width, 0), self.scale['to']) - self.assertEqual(self.scale.get(0, 0), self.scale['from']) + self.assertEqual(conv(self.scale.get(0, 0)), conv(self.scale['from'])) self.assertEqual(self.scale.get(), self.scale['value']) self.scale['value'] = 30 self.assertEqual(self.scale.get(), self.scale['value']) @@ -825,32 +815,37 @@ def test_get(self): def test_set(self): + if self.wantobjects: + conv = lambda x: x + else: + conv = float + # set restricts the max/min values according to the current range - max = self.scale['to'] + max = conv(self.scale['to']) new_max = max + 10 self.scale.set(new_max) - self.assertEqual(self.scale.get(), max) - min = self.scale['from'] + self.assertEqual(conv(self.scale.get()), max) + min = conv(self.scale['from']) self.scale.set(min - 1) - self.assertEqual(self.scale.get(), min) + self.assertEqual(conv(self.scale.get()), min) # changing directly the variable doesn't impose this limitation tho - var = tkinter.DoubleVar() + var = tkinter.DoubleVar(self.root) self.scale['variable'] = var var.set(max + 5) - self.assertEqual(self.scale.get(), var.get()) - self.assertEqual(self.scale.get(), max + 5) + self.assertEqual(conv(self.scale.get()), var.get()) + self.assertEqual(conv(self.scale.get()), max + 5) del var # the same happens with the value option self.scale['value'] = max + 10 - self.assertEqual(self.scale.get(), max + 10) - self.assertEqual(self.scale.get(), self.scale['value']) + self.assertEqual(conv(self.scale.get()), max + 10) + self.assertEqual(conv(self.scale.get()), conv(self.scale['value'])) # nevertheless, note that the max/min values we can get specifying # x, y coords are the ones according to the current range - self.assertEqual(self.scale.get(0, 0), min) - self.assertEqual(self.scale.get(self.scale.winfo_width(), 0), max) + self.assertEqual(conv(self.scale.get(0, 0)), min) + self.assertEqual(conv(self.scale.get(self.scale.winfo_width(), 0)), max) self.assertRaises(tkinter.TclError, self.scale.set, None) @@ -865,7 +860,7 @@ class ProgressbarTest(AbstractWidgetTest, unittest.TestCase): _conv_pixels = noconv default_orient = 'horizontal' - def _create(self, **kwargs): + def create(self, **kwargs): return ttk.Progressbar(self.root, **kwargs) def test_length(self): @@ -899,7 +894,7 @@ class ScrollbarTest(AbstractWidgetTest, unittest.TestCase): ) default_orient = 'vertical' - def _create(self, **kwargs): + def create(self, **kwargs): return ttk.Scrollbar(self.root, **kwargs) @@ -911,21 +906,13 @@ class NotebookTest(AbstractWidgetTest, unittest.TestCase): def setUp(self): super().setUp() - support.root_deiconify() self.nb = self.create(padding=0) - self.child1 = ttk.Label() - self.child2 = ttk.Label() + self.child1 = ttk.Label(self.root) + self.child2 = ttk.Label(self.root) self.nb.add(self.child1, text='a') self.nb.add(self.child2, text='b') - def tearDown(self): - self.child1.destroy() - self.child2.destroy() - self.nb.destroy() - support.root_withdraw() - super().tearDown() - - def _create(self, **kwargs): + def create(self, **kwargs): return ttk.Notebook(self.root, **kwargs) def test_tab_identifiers(self): @@ -964,7 +951,7 @@ def test_add_and_hidden(self): self.assertRaises(tkinter.TclError, self.nb.hide, 'hi') self.assertRaises(tkinter.TclError, self.nb.hide, None) self.assertRaises(tkinter.TclError, self.nb.add, None) - self.assertRaises(tkinter.TclError, self.nb.add, ttk.Label(), + self.assertRaises(tkinter.TclError, self.nb.add, ttk.Label(self.root), unknown='option') tabs = self.nb.tabs() @@ -972,7 +959,7 @@ def test_add_and_hidden(self): self.nb.add(self.child1) self.assertEqual(self.nb.tabs(), tabs) - child = ttk.Label() + child = ttk.Label(self.root) self.nb.add(child, text='c') tabs = self.nb.tabs() @@ -1030,7 +1017,7 @@ def test_insert(self): self.assertRaises(tkinter.TclError, self.nb.insert, -1, tabs[0]) # new tab - child3 = ttk.Label() + child3 = ttk.Label(self.root) self.nb.insert(1, child3) self.assertEqual(self.nb.tabs(), (tabs[0], str(child3), tabs[1])) self.nb.forget(child3) @@ -1096,7 +1083,7 @@ def test_traversal(self): self.nb.select(0) - support.simulate_mouse_click(self.nb, 5, 5) + simulate_mouse_click(self.nb, 5, 5) self.nb.focus_force() self.nb.event_generate('') self.assertEqual(self.nb.select(), str(self.child2)) @@ -1110,7 +1097,7 @@ def test_traversal(self): self.nb.tab(self.child1, text='a', underline=0) self.nb.enable_traversal() self.nb.focus_force() - support.simulate_mouse_click(self.nb, 5, 5) + simulate_mouse_click(self.nb, 5, 5) if sys.platform == 'darwin': self.nb.event_generate('') else: @@ -1128,15 +1115,9 @@ class TreeviewTest(AbstractWidgetTest, unittest.TestCase): def setUp(self): super().setUp() - support.root_deiconify() self.tv = self.create(padding=0) - def tearDown(self): - self.tv.destroy() - support.root_withdraw() - super().tearDown() - - def _create(self, **kwargs): + def create(self, **kwargs): return ttk.Treeview(self.root, **kwargs) def test_columns(self): @@ -1192,18 +1173,15 @@ def test_bbox(self): self.assertTrue(children) bbox = self.tv.bbox(children[0]) - self.assertEqual(len(bbox), 4) - self.assertIsInstance(bbox, tuple) - for item in bbox: - if not isinstance(item, int): - self.fail("Invalid bounding box: %s" % bbox) - break + self.assertIsBoundingBox(bbox) # compare width in bboxes self.tv['columns'] = ['test'] self.tv.column('test', width=50) bbox_column0 = self.tv.bbox(children[0], 0) root_width = self.tv.column('#0', width=None) + if not self.wantobjects: + root_width = int(root_width) self.assertEqual(bbox_column0[0], bbox[0] + root_width) # verify that bbox of a closed item is the empty string @@ -1243,12 +1221,15 @@ def test_column(self): # return a dict with all options/values self.assertIsInstance(self.tv.column('#0'), dict) # return a single value of the given option - self.assertIsInstance(self.tv.column('#0', width=None), int) + if self.wantobjects: + self.assertIsInstance(self.tv.column('#0', width=None), int) # set a new value for an option self.tv.column('#0', width=10) # testing new way to get option value - self.assertEqual(self.tv.column('#0', 'width'), 10) - self.assertEqual(self.tv.column('#0', width=None), 10) + self.assertEqual(self.tv.column('#0', 'width'), + 10 if self.wantobjects else '10') + self.assertEqual(self.tv.column('#0', width=None), + 10 if self.wantobjects else '10') # check read-only option self.assertRaises(tkinter.TclError, self.tv.column, '#0', id='X') @@ -1372,7 +1353,7 @@ def test_heading(self): def test_heading_callback(self): def simulate_heading_click(x, y): - support.simulate_mouse_click(self.tv, x, y) + simulate_mouse_click(self.tv, x, y) self.tv.update() success = [] # no success for now @@ -1461,11 +1442,14 @@ def test_insert_item(self): # unicode values value = '\xe1ba' item = self.tv.insert('', 'end', values=(value, )) - self.assertEqual(self.tv.item(item, 'values'), (value, )) - self.assertEqual(self.tv.item(item, values=None), (value, )) + self.assertEqual(self.tv.item(item, 'values'), + (value,) if self.wantobjects else value) + self.assertEqual(self.tv.item(item, values=None), + (value,) if self.wantobjects else value) - self.tv.item(item, values=list(self.tv.item(item, values=None))) - self.assertEqual(self.tv.item(item, values=None), (value, )) + self.tv.item(item, values=self.root.splitlist(self.tv.item(item, values=None))) + self.assertEqual(self.tv.item(item, values=None), + (value,) if self.wantobjects else value) self.assertIsInstance(self.tv.item(item), dict) @@ -1475,17 +1459,21 @@ def test_insert_item(self): # item tags item = self.tv.insert('', 'end', tags=[1, 2, value]) - self.assertEqual(self.tv.item(item, tags=None), ('1', '2', value)) + self.assertEqual(self.tv.item(item, tags=None), + ('1', '2', value) if self.wantobjects else + '1 2 %s' % value) self.tv.item(item, tags=[]) self.assertFalse(self.tv.item(item, tags=None)) self.tv.item(item, tags=(1, 2)) - self.assertEqual(self.tv.item(item, tags=None), ('1', '2')) + self.assertEqual(self.tv.item(item, tags=None), + ('1', '2') if self.wantobjects else '1 2') # values with spaces item = self.tv.insert('', 'end', values=('a b c', '%s %s' % (value, value))) self.assertEqual(self.tv.item(item, values=None), - ('a b c', '%s %s' % (value, value))) + ('a b c', '%s %s' % (value, value)) if self.wantobjects else + '{a b c} {%s %s}' % (value, value)) # text self.assertEqual(self.tv.item( @@ -1502,19 +1490,24 @@ def test_set(self): self.assertEqual(self.tv.set(item), {'A': 'a', 'B': 'b'}) self.tv.set(item, 'B', 'a') - self.assertEqual(self.tv.item(item, values=None), ('a', 'a')) + self.assertEqual(self.tv.item(item, values=None), + ('a', 'a') if self.wantobjects else 'a a') self.tv['columns'] = ['B'] self.assertEqual(self.tv.set(item), {'B': 'a'}) self.tv.set(item, 'B', 'b') self.assertEqual(self.tv.set(item, column='B'), 'b') - self.assertEqual(self.tv.item(item, values=None), ('b', 'a')) + self.assertEqual(self.tv.item(item, values=None), + ('b', 'a') if self.wantobjects else 'b a') self.tv.set(item, 'B', 123) - self.assertEqual(self.tv.set(item, 'B'), 123) - self.assertEqual(self.tv.item(item, values=None), (123, 'a')) - self.assertEqual(self.tv.set(item), {'B': 123}) + self.assertEqual(self.tv.set(item, 'B'), + 123 if self.wantobjects else '123') + self.assertEqual(self.tv.item(item, values=None), + (123, 'a') if self.wantobjects else '123 a') + self.assertEqual(self.tv.set(item), + {'B': 123} if self.wantobjects else {'B': '123'}) # inexistent column self.assertRaises(tkinter.TclError, self.tv.set, item, 'A') @@ -1549,7 +1542,7 @@ def test_tag_bind(self): self.assertEqual(len(pos_y), 2) # item1 and item2 y pos for y in pos_y: - support.simulate_mouse_click(self.tv, 0, y) + simulate_mouse_click(self.tv, 0, y) # by now there should be 4 things in the events list, since each # item had a bind for two events that were simulated above @@ -1570,6 +1563,21 @@ def test_tag_configure(self): 'blue') self.assertIsInstance(self.tv.tag_configure('test'), dict) + def test_tag_has(self): + item1 = self.tv.insert('', 'end', text='Item 1', tags=['tag1']) + item2 = self.tv.insert('', 'end', text='Item 2', tags=['tag2']) + self.assertRaises(TypeError, self.tv.tag_has) + self.assertRaises(TclError, self.tv.tag_has, 'tag1', 'non-existing') + self.assertTrue(self.tv.tag_has('tag1', item1)) + self.assertFalse(self.tv.tag_has('tag1', item2)) + self.assertFalse(self.tv.tag_has('tag2', item1)) + self.assertTrue(self.tv.tag_has('tag2', item2)) + self.assertFalse(self.tv.tag_has('tag3', item1)) + self.assertFalse(self.tv.tag_has('tag3', item2)) + self.assertEqual(self.tv.tag_has('tag1'), (item1,)) + self.assertEqual(self.tv.tag_has('tag2'), (item2,)) + self.assertEqual(self.tv.tag_has('tag3'), ()) + @add_standard_options(StandardTtkOptionsTests) class SeparatorTest(AbstractWidgetTest, unittest.TestCase): @@ -1579,7 +1587,7 @@ class SeparatorTest(AbstractWidgetTest, unittest.TestCase): ) default_orient = 'horizontal' - def _create(self, **kwargs): + def create(self, **kwargs): return ttk.Separator(self.root, **kwargs) @@ -1590,7 +1598,7 @@ class SizegripTest(AbstractWidgetTest, unittest.TestCase): # 'state'? ) - def _create(self, **kwargs): + def create(self, **kwargs): return ttk.Sizegrip(self.root, **kwargs) tests_gui = ( diff --git a/Lib/tkinter/test/widget_tests.py b/Lib/tkinter/test/widget_tests.py index bd274e60d315..779538d2e0c3 100644 --- a/Lib/tkinter/test/widget_tests.py +++ b/Lib/tkinter/test/widget_tests.py @@ -3,9 +3,10 @@ import unittest import sys import tkinter -from tkinter.ttk import setup_master, Scale -from tkinter.test.support import (tcl_version, requires_tcl, get_tk_patchlevel, - pixels_conv, tcl_obj_eq) +from tkinter.ttk import Scale +from tkinter.test.support import (AbstractTkTest, tcl_version, requires_tcl, + get_tk_patchlevel, pixels_conv, tcl_obj_eq) +import test.support noconv = False @@ -21,21 +22,25 @@ _sentinel = object() -class AbstractWidgetTest: +class AbstractWidgetTest(AbstractTkTest): _conv_pixels = staticmethod(pixels_round) _conv_pad_pixels = None - wantobjects = True - - def setUp(self): - self.root = setup_master() - self.scaling = float(self.root.call('tk', 'scaling')) - if not self.root.wantobjects(): - self.wantobjects = False - - def create(self, **kwargs): - widget = self._create(**kwargs) - self.addCleanup(widget.destroy) - return widget + _stringify = False + + @property + def scaling(self): + try: + return self._scaling + except AttributeError: + self._scaling = float(self.root.call('tk', 'scaling')) + return self._scaling + + def _str(self, value): + if not self._stringify and self.wantobjects and tcl_version >= (8, 6): + return value + if isinstance(value, tuple): + return ' '.join(map(self._str, value)) + return str(value) def assertEqual2(self, actual, expected, msg=None, eq=object.__eq__): if eq(actual, expected): @@ -49,7 +54,7 @@ def checkParam(self, widget, name, value, *, expected=_sentinel, expected = value if conv: expected = conv(expected) - if not self.wantobjects: + if self._stringify or not self.wantobjects: if isinstance(expected, tuple): expected = tkinter._join(expected) else: @@ -62,9 +67,7 @@ def checkParam(self, widget, name, value, *, expected=_sentinel, if not isinstance(widget, Scale): t = widget.configure(name) self.assertEqual(len(t), 5) - ## XXX - if not isinstance(t[4], tuple): - self.assertEqual2(t[4], expected, eq=eq) + self.assertEqual2(t[4], expected, eq=eq) def checkInvalidParam(self, widget, name, value, errmsg=None, *, keep_orig=True): @@ -183,7 +186,7 @@ def checkReliefParam(self, widget, name): errmsg=errmsg) def checkImageParam(self, widget, name): - image = tkinter.PhotoImage('image1') + image = tkinter.PhotoImage(master=self.root, name='image1') self.checkParam(widget, name, image, conv=str) self.checkInvalidParam(widget, name, 'spam', errmsg='image "spam" doesn\'t exist') @@ -192,6 +195,16 @@ def checkImageParam(self, widget, name): def checkVariableParam(self, widget, name, var): self.checkParam(widget, name, var, conv=str) + def assertIsBoundingBox(self, bbox): + self.assertIsNotNone(bbox) + self.assertIsInstance(bbox, tuple) + if len(bbox) != 4: + self.fail('Invalid bounding box: %r' % (bbox,)) + for item in bbox: + if not isinstance(item, int): + self.fail('Invalid bounding box: %r' % (bbox,)) + break + class StandardOptionsTests: STANDARD_OPTIONS = ( @@ -236,8 +249,14 @@ def test_bitmap(self): widget = self.create() self.checkParam(widget, 'bitmap', 'questhead') self.checkParam(widget, 'bitmap', 'gray50') - self.checkInvalidParam(widget, 'bitmap', 'spam', - errmsg='bitmap "spam" not defined') + filename = test.support.findfile('python.xbm', subdir='imghdrdata') + self.checkParam(widget, 'bitmap', '@' + filename) + # Cocoa Tk widgets don't detect invalid -bitmap values + # See https://core.tcl.tk/tk/info/31cd33dbf0 + if not ('aqua' in self.root.tk.call('tk', 'windowingsystem') and + 'AppKit' in self.root.winfo_server()): + self.checkInvalidParam(widget, 'bitmap', 'spam', + errmsg='bitmap "spam" not defined') def test_borderwidth(self): widget = self.create() @@ -388,7 +407,7 @@ def test_text(self): def test_textvariable(self): widget = self.create() - var = tkinter.StringVar() + var = tkinter.StringVar(self.root) self.checkVariableParam(widget, 'textvariable', var) def test_troughcolor(self): @@ -449,7 +468,7 @@ def test_tristatevalue(self): def test_variable(self): widget = self.create() - var = tkinter.DoubleVar() + var = tkinter.DoubleVar(self.root) self.checkVariableParam(widget, 'variable', var) @@ -497,7 +516,6 @@ def test(self, option=option): return decorator def setUpModule(): - import test.support if test.support.verbose: tcl = tkinter.Tcl() print('patchlevel =', tcl.call('info', 'patchlevel')) diff --git a/Lib/tkinter/tix.py b/Lib/tkinter/tix.py index 5eecd04132ca..c1cdfa7c0337 100644 --- a/Lib/tkinter/tix.py +++ b/Lib/tkinter/tix.py @@ -27,7 +27,7 @@ # from tkinter import * -from tkinter import _flatten, _cnfmerge, _default_root +from tkinter import _cnfmerge, _default_root # WARNING - TkVersion is a limited precision floating point number if TkVersion < 3.999: @@ -122,13 +122,9 @@ def tix_configure(self, cnf=None, **kw): elif cnf: cnf = _cnfmerge(cnf) if cnf is None: - cnf = {} - for x in self.tk.split(self.tk.call('tix', 'configure')): - cnf[x[0][1:]] = (x[0][1:],) + x[1:] - return cnf + return self._getconfigure('tix', 'configure') if isinstance(cnf, str): - x = self.tk.split(self.tk.call('tix', 'configure', '-'+cnf)) - return (x[0][1:],) + x[1:] + return self._getconfigure1('tix', 'configure', '-'+cnf) return self.tk.call(('tix', 'configure') + self._options(cnf)) def tix_filedialog(self, dlgclass=None): @@ -380,7 +376,7 @@ def _subwidget_names(self): """Return the name of all subwidgets.""" try: x = self.tk.call(self._w, 'subwidgets', '-all') - return self.tk.split(x) + return self.tk.splitlist(x) except TclError: return None @@ -473,13 +469,6 @@ def destroy(self): self.tk.call('destroy', self._w) -# Useful func. to split Tcl lists and return as a dict. From Tkinter.py -def _lst2dict(lst): - dict = {} - for x in lst: - dict[x[0][1:]] = (x[0][1:],) + x[1:] - return dict - # Useful class to create a display style - later shared by many items. # Contributed by Steffen Kremser class DisplayStyle: @@ -515,10 +504,8 @@ def __setitem__(self,key,value): self.tk.call(self.stylename, 'configure', '-%s'%key, value) def config(self, cnf={}, **kw): - return _lst2dict( - self.tk.split( - self.tk.call( - self.stylename, 'configure', *self._options(cnf,kw)))) + return self._getconfigure( + self.stylename, 'configure', *self._options(cnf,kw)) def __getitem__(self,key): return self.tk.call(self.stylename, 'cget', '-%s'%key) @@ -928,9 +915,7 @@ def header_create(self, col, cnf={}, **kw): def header_configure(self, col, cnf={}, **kw): if cnf is None: - return _lst2dict( - self.tk.split( - self.tk.call(self._w, 'header', 'configure', col))) + return self._getconfigure(self._w, 'header', 'configure', col) self.tk.call(self._w, 'header', 'configure', col, *self._options(cnf, kw)) @@ -955,9 +940,8 @@ def indicator_create(self, entry, cnf={}, **kw): def indicator_configure(self, entry, cnf={}, **kw): if cnf is None: - return _lst2dict( - self.tk.split( - self.tk.call(self._w, 'indicator', 'configure', entry))) + return self._getconfigure( + self._w, 'indicator', 'configure', entry) self.tk.call( self._w, 'indicator', 'configure', entry, *self._options(cnf, kw)) @@ -1017,9 +1001,7 @@ def item_cget(self, entry, col, opt): def item_configure(self, entry, col, cnf={}, **kw): if cnf is None: - return _lst2dict( - self.tk.split( - self.tk.call(self._w, 'item', 'configure', entry, col))) + return self._getconfigure(self._w, 'item', 'configure', entry, col) self.tk.call(self._w, 'item', 'configure', entry, col, *self._options(cnf, kw)) @@ -1038,9 +1020,7 @@ def entrycget(self, entry, opt): def entryconfigure(self, entry, cnf={}, **kw): if cnf is None: - return _lst2dict( - self.tk.split( - self.tk.call(self._w, 'entryconfigure', entry))) + return self._getconfigure(self._w, 'entryconfigure', entry) self.tk.call(self._w, 'entryconfigure', entry, *self._options(cnf, kw)) @@ -1254,9 +1234,7 @@ def panecget(self, entry, opt): def paneconfigure(self, entry, cnf={}, **kw): if cnf is None: - return _lst2dict( - self.tk.split( - self.tk.call(self._w, 'paneconfigure', entry))) + return self._getconfigure(self._w, 'paneconfigure', entry) self.tk.call(self._w, 'paneconfigure', entry, *self._options(cnf, kw)) def panes(self): diff --git a/Lib/tkinter/ttk.py b/Lib/tkinter/ttk.py index 6cd4ea69072e..4327dbb05d74 100644 --- a/Lib/tkinter/ttk.py +++ b/Lib/tkinter/ttk.py @@ -26,7 +26,7 @@ "tclobjs_to_py", "setup_master"] import tkinter -from tkinter import _flatten, _join, _stringify +from tkinter import _flatten, _join, _stringify, _splitdict # Verify if Tk is new enough to not need the Tile package _REQUIRE_TILE = True if tkinter.TkVersion < 8.5 else False @@ -240,21 +240,6 @@ def _script_from_settings(settings): return '\n'.join(script) -def _dict_from_tcltuple(ttuple, cut_minus=True): - """Break tuple in pairs, format it properly, then build the return - dict. If cut_minus is True, the supposed '-' prefixing options will - be removed. - - ttuple is expected to contain an even number of elements.""" - opt_start = 1 if cut_minus else 0 - - retdict = {} - it = iter(ttuple) - for opt, val in zip(it, it): - retdict[str(opt)[opt_start:]] = val - - return tclobjs_to_py(retdict) - def _list_from_statespec(stuple): """Construct a list from the given statespec tuple according to the accepted statespec accepted by _format_mapdict.""" @@ -272,9 +257,10 @@ def _list_from_statespec(stuple): it = iter(nval) return [_flatten(spec) for spec in zip(it, it)] -def _list_from_layouttuple(ltuple): +def _list_from_layouttuple(tk, ltuple): """Construct a list from the tuple returned by ttk::layout, this is somewhat the reverse of _format_layoutlist.""" + ltuple = tk.splitlist(ltuple) res = [] indx = 0 @@ -293,14 +279,14 @@ def _list_from_layouttuple(ltuple): indx += 2 if opt == 'children': - val = _list_from_layouttuple(val) + val = _list_from_layouttuple(tk, val) opts[opt] = val return res -def _val_or_dict(options, func, *args): - """Format options then call func with args and options and return +def _val_or_dict(tk, options, *args): + """Format options then call Tk command with args and options and return the appropriate result. If no option is specified, a dict is returned. If a option is @@ -308,12 +294,12 @@ def _val_or_dict(options, func, *args): Otherwise, the function just sets the passed options and the caller shouldn't be expecting a return value anyway.""" options = _format_optdict(options) - res = func(*(args + options)) + res = tk.call(*(args + options)) if len(options) % 2: # option specified without a value, return its value return res - return _dict_from_tcltuple(res) + return _splitdict(tk, res, conv=_tclobj_to_py) def _convert_stringval(value): """Converts a value to, hopefully, a more appropriate Python object.""" @@ -325,20 +311,32 @@ def _convert_stringval(value): return value +def _to_number(x): + if isinstance(x, str): + if '.' in x: + x = float(x) + else: + x = int(x) + return x + +def _tclobj_to_py(val): + """Return value converted from Tcl object to Python object.""" + if val and hasattr(val, '__len__') and not isinstance(val, str): + if getattr(val[0], 'typename', None) == 'StateSpec': + val = _list_from_statespec(val) + else: + val = list(map(_convert_stringval, val)) + + elif hasattr(val, 'typename'): # some other (single) Tcl object + val = _convert_stringval(val) + + return val + def tclobjs_to_py(adict): """Returns adict with its values converted from Tcl objects to Python objects.""" for opt, val in adict.items(): - if val and hasattr(val, '__len__') and not isinstance(val, str): - if getattr(val[0], 'typename', None) == 'StateSpec': - val = _list_from_statespec(val) - else: - val = list(map(_convert_stringval, val)) - - elif hasattr(val, 'typename'): # some other (single) Tcl object - val = _convert_stringval(val) - - adict[opt] = val + adict[opt] = _tclobj_to_py(val) return adict @@ -383,7 +381,7 @@ def configure(self, style, query_opt=None, **kw): a sequence identifying the value for that option.""" if query_opt is not None: kw[query_opt] = None - return _val_or_dict(kw, self.tk.call, self._name, "configure", style) + return _val_or_dict(self.tk, kw, self._name, "configure", style) def map(self, style, query_opt=None, **kw): @@ -395,11 +393,13 @@ def map(self, style, query_opt=None, **kw): or something else of your preference. A statespec is compound of one or more states and then a value.""" if query_opt is not None: - return _list_from_statespec( - self.tk.call(self._name, "map", style, '-%s' % query_opt)) + return _list_from_statespec(self.tk.splitlist( + self.tk.call(self._name, "map", style, '-%s' % query_opt))) - return _dict_from_tcltuple( - self.tk.call(self._name, "map", style, *(_format_mapdict(kw)))) + return _splitdict( + self.tk, + self.tk.call(self._name, "map", style, *_format_mapdict(kw)), + conv=_tclobj_to_py) def lookup(self, style, option, state=None, default=None): @@ -453,7 +453,7 @@ def layout(self, style, layoutspec=None): lspec = "null" # could be any other word, but this may make sense # when calling layout(style) later - return _list_from_layouttuple( + return _list_from_layouttuple(self.tk, self.tk.call(self._name, "layout", style, lspec)) @@ -466,12 +466,12 @@ def element_create(self, elementname, etype, *args, **kw): def element_names(self): """Returns the list of elements defined in the current theme.""" - return self.tk.call(self._name, "element", "names") + return self.tk.splitlist(self.tk.call(self._name, "element", "names")) def element_options(self, elementname): """Return the list of elementname's options.""" - return self.tk.call(self._name, "element", "options", elementname) + return self.tk.splitlist(self.tk.call(self._name, "element", "options", elementname)) def theme_create(self, themename, parent=None, settings=None): @@ -505,7 +505,7 @@ def theme_settings(self, themename, settings): def theme_names(self): """Returns a list of all known themes.""" - return self.tk.call(self._name, "theme", "names") + return self.tk.splitlist(self.tk.call(self._name, "theme", "names")) def theme_use(self, themename=None): @@ -568,7 +568,8 @@ def instate(self, statespec, callback=None, *args, **kw): matches statespec and False otherwise. If callback is specified, then it will be invoked with *args, **kw if the widget state matches statespec. statespec is expected to be a sequence.""" - ret = self.tk.call(self._w, "instate", ' '.join(statespec)) + ret = self.tk.getboolean( + self.tk.call(self._w, "instate", ' '.join(statespec))) if ret and callback: return callback(*args, **kw) @@ -667,7 +668,7 @@ def __init__(self, master=None, widget=None, **kw): def bbox(self, index): """Return a tuple of (x, y, width, height) which describes the bounding box of the character given by index.""" - return self.tk.call(self._w, "bbox", index) + return self._getints(self.tk.call(self._w, "bbox", index)) def identify(self, x, y): @@ -680,7 +681,7 @@ def validate(self): """Force revalidation, independent of the conditions specified by the validate option. Returns False if validation fails, True if it succeeds. Sets or clears the invalid state accordingly.""" - return bool(self.tk.call(self._w, "validate")) + return bool(self.tk.getboolean(self.tk.call(self._w, "validate"))) class Combobox(Entry): @@ -707,6 +708,8 @@ def current(self, newindex=None): element at position newindex in the list of values. Otherwise, returns the index of the current value in the list of values or -1 if the current value does not appear in the list.""" + if newindex is None: + return self.tk.getint(self.tk.call(self._w, "current")) return self.tk.call(self._w, "current", newindex) @@ -861,7 +864,7 @@ def identify(self, x, y): def index(self, tab_id): """Returns the numeric index of the tab specified by tab_id, or the total number of tabs if tab_id is the string "end".""" - return self.tk.call(self._w, "index", tab_id) + return self.tk.getint(self.tk.call(self._w, "index", tab_id)) def insert(self, pos, child, **kw): @@ -891,12 +894,12 @@ def tab(self, tab_id, option=None, **kw): options to the corresponding values.""" if option is not None: kw[option] = None - return _val_or_dict(kw, self.tk.call, self._w, "tab", tab_id) + return _val_or_dict(self.tk, kw, self._w, "tab", tab_id) def tabs(self): """Returns a list of windows managed by the notebook.""" - return self.tk.call(self._w, "tabs") or () + return self.tk.splitlist(self.tk.call(self._w, "tabs") or ()) def enable_traversal(self): @@ -968,7 +971,7 @@ def pane(self, pane, option=None, **kw): Otherwise, sets the options to the corresponding values.""" if option is not None: kw[option] = None - return _val_or_dict(kw, self.tk.call, self._w, "pane", pane) + return _val_or_dict(self.tk, kw, self._w, "pane", pane) def sashpos(self, index, newpos=None): @@ -979,7 +982,7 @@ def sashpos(self, index, newpos=None): constrained to be between 0 and the total size of the widget. Returns the new position of sash number index.""" - return self.tk.call(self._w, "sashpos", index, newpos) + return self.tk.getint(self.tk.call(self._w, "sashpos", index, newpos)) PanedWindow = Panedwindow # tkinter name compatibility @@ -1179,14 +1182,15 @@ def bbox(self, item, column=None): If column is specified, returns the bounding box of that cell. If the item is not visible (i.e., if it is a descendant of a closed item or is scrolled offscreen), returns an empty string.""" - return self.tk.call(self._w, "bbox", item, column) + return self._getints(self.tk.call(self._w, "bbox", item, column)) or '' def get_children(self, item=None): """Returns a tuple of children belonging to item. If item is not specified, returns root children.""" - return self.tk.call(self._w, "children", item or '') or () + return self.tk.splitlist( + self.tk.call(self._w, "children", item or '') or ()) def set_children(self, item, *newchildren): @@ -1206,7 +1210,7 @@ def column(self, column, option=None, **kw): Otherwise, sets the options to the corresponding values.""" if option is not None: kw[option] = None - return _val_or_dict(kw, self.tk.call, self._w, "column", column) + return _val_or_dict(self.tk, kw, self._w, "column", column) def delete(self, *items): @@ -1227,7 +1231,7 @@ def detach(self, *items): def exists(self, item): """Returns True if the specified item is present in the tree, False otherwise.""" - return bool(self.tk.call(self._w, "exists", item)) + return bool(self.tk.getboolean(self.tk.call(self._w, "exists", item))) def focus(self, item=None): @@ -1265,7 +1269,7 @@ def heading(self, column, option=None, **kw): if option is not None: kw[option] = None - return _val_or_dict(kw, self.tk.call, self._w, 'heading', column) + return _val_or_dict(self.tk, kw, self._w, 'heading', column) def identify(self, component, x, y): @@ -1309,7 +1313,7 @@ def identify_element(self, x, y): def index(self, item): """Returns the integer index of item within its parent's list of children.""" - return self.tk.call(self._w, "index", item) + return self.tk.getint(self.tk.call(self._w, "index", item)) def insert(self, parent, index, iid=None, **kw): @@ -1344,7 +1348,7 @@ def item(self, item, option=None, **kw): values as given by kw.""" if option is not None: kw[option] = None - return _val_or_dict(kw, self.tk.call, self._w, "item", item) + return _val_or_dict(self.tk, kw, self._w, "item", item) def move(self, item, parent, index): @@ -1412,13 +1416,16 @@ def selection_toggle(self, items): def set(self, item, column=None, value=None): - """With one argument, returns a dictionary of column/value pairs - for the specified item. With two arguments, returns the current - value of the specified column. With three arguments, sets the + """Query or set the value of given item. + + With one argument, return a dictionary of column/value pairs + for the specified item. With two arguments, return the current + value of the specified column. With three arguments, set the value of given column in given item to the specified value.""" res = self.tk.call(self._w, "set", item, column, value) if column is None and value is None: - return _dict_from_tcltuple(res, False) + return _splitdict(self.tk, res, + cut_minus=False, conv=_tclobj_to_py) else: return res @@ -1439,7 +1446,7 @@ def tag_configure(self, tagname, option=None, **kw): values for the given tagname.""" if option is not None: kw[option] = None - return _val_or_dict(kw, self.tk.call, self._w, "tag", "configure", + return _val_or_dict(self.tk, kw, self._w, "tag", "configure", tagname) @@ -1449,7 +1456,12 @@ def tag_has(self, tagname, item=None): all items which have the specified tag. * Availability: Tk 8.6""" - return self.tk.call(self._w, "tag", "has", tagname, item) + if item is None: + return self.tk.splitlist( + self.tk.call(self._w, "tag", "has", tagname)) + else: + return self.tk.getboolean( + self.tk.call(self._w, "tag", "has", tagname, item)) # Extensions @@ -1521,7 +1533,8 @@ def adjust_label(): self.label.place_configure(x=x, y=y) - from_, to = self.scale['from'], self.scale['to'] + from_ = _to_number(self.scale['from']) + to = _to_number(self.scale['to']) if to < from_: from_, to = to, from_ newval = self._variable.get() diff --git a/Lib/token.py b/Lib/token.py old mode 100755 new mode 100644 index 7470c8c3763f..bdfcec8ea4b1 --- a/Lib/token.py +++ b/Lib/token.py @@ -60,11 +60,12 @@ DOUBLESLASH = 47 DOUBLESLASHEQUAL = 48 AT = 49 -RARROW = 50 -ELLIPSIS = 51 -OP = 52 -ERRORTOKEN = 53 -N_TOKENS = 54 +ATEQUAL = 50 +RARROW = 51 +ELLIPSIS = 52 +OP = 53 +ERRORTOKEN = 54 +N_TOKENS = 55 NT_OFFSET = 256 #--end constants-- diff --git a/Lib/tokenize.py b/Lib/tokenize.py index f614aeb164f3..0659c55a0682 100644 --- a/Lib/tokenize.py +++ b/Lib/tokenize.py @@ -24,14 +24,16 @@ __credits__ = ('GvR, ESR, Tim Peters, Thomas Wouters, Fred Drake, ' 'Skip Montanaro, Raymond Hettinger, Trent Nelson, ' 'Michael Foord') -import builtins -import re -import sys -from token import * from codecs import lookup, BOM_UTF8 import collections from io import TextIOWrapper +from itertools import chain +import re +import sys +from token import * + cookie_re = re.compile(r'^[ \t\f]*#.*coding[:=][ \t]*([-\w.]+)', re.ASCII) +blank_re = re.compile(br'^[ \t\f]*(?:[#\r\n]|$)', re.ASCII) import token __all__ = token.__all__ + ["COMMENT", "tokenize", "detect_encoding", @@ -88,7 +90,8 @@ '**=': DOUBLESTAREQUAL, '//': DOUBLESLASH, '//=': DOUBLESLASHEQUAL, - '@': AT + '@': AT, + '@=': ATEQUAL, } class TokenInfo(collections.namedtuple('TokenInfo', 'type string start end line')): @@ -147,7 +150,7 @@ def maybe(*choices): return group(*choices) + '?' # recognized as two instances of =). Operator = group(r"\*\*=?", r">>=?", r"<<=?", r"!=", r"//=?", r"->", - r"[+\-*/%&|^=<>]=?", + r"[+\-*/%&@|^=<>]=?", r"~") Bracket = '[][(){}]' @@ -183,7 +186,6 @@ def _compile(expr): "rB'''": Single3, 'rB"""': Double3, "RB'''": Single3, 'RB"""': Double3, "u'''": Single3, 'u"""': Double3, - "R'''": Single3, 'R"""': Double3, "U'''": Single3, 'U"""': Double3, 'r': None, 'R': None, 'b': None, 'B': None, 'u': None, 'U': None} @@ -228,20 +230,29 @@ def __init__(self): def add_whitespace(self, start): row, col = start - assert row <= self.prev_row + if row < self.prev_row or row == self.prev_row and col < self.prev_col: + raise ValueError("start ({},{}) precedes previous end ({},{})" + .format(row, col, self.prev_row, self.prev_col)) + row_offset = row - self.prev_row + if row_offset: + self.tokens.append("\\\n" * row_offset) + self.prev_col = 0 col_offset = col - self.prev_col if col_offset: self.tokens.append(" " * col_offset) def untokenize(self, iterable): - for t in iterable: + it = iter(iterable) + for t in it: if len(t) == 2: - self.compat(t, iterable) + self.compat(t, it) break tok_type, token, start, end, line = t if tok_type == ENCODING: self.encoding = token continue + if tok_type == ENDMARKER: + break self.add_whitespace(start) self.tokens.append(token) self.prev_row, self.prev_col = end @@ -251,17 +262,12 @@ def untokenize(self, iterable): return "".join(self.tokens) def compat(self, token, iterable): - startline = False indents = [] toks_append = self.tokens.append - toknum, tokval = token - - if toknum in (NAME, NUMBER): - tokval += ' ' - if toknum in (NEWLINE, NL): - startline = True + startline = token[0] in (NEWLINE, NL) prevstring = False - for tok in iterable: + + for tok in chain([token], iterable): toknum, tokval = tok[:2] if toknum == ENCODING: self.encoding = tokval @@ -409,6 +415,8 @@ def find_cookie(line): encoding = find_cookie(first) if encoding: return encoding, [first] + if not blank_re.match(first): + return default, [first] second = read_or_stop() if not second: @@ -421,11 +429,13 @@ def find_cookie(line): return default, [first, second] +_builtin_open = open + def open(filename): """Open a file in read only mode using the encoding detected by detect_encoding(). """ - buffer = builtins.open(filename, 'rb') + buffer = _builtin_open(filename, 'rb') encoding, lines = detect_encoding(buffer.readline) buffer.seek(0) text = TextIOWrapper(buffer, encoding, line_buffering=True) @@ -648,7 +658,7 @@ def error(message, filename=None, location=None): # Tokenize the input if args.filename: filename = args.filename - with builtins.open(filename, 'rb') as f: + with _builtin_open(filename, 'rb') as f: tokens = list(tokenize(f.readline)) else: filename = "" diff --git a/Lib/trace.py b/Lib/trace.py old mode 100644 new mode 100755 index 09fe9ee0e48f..fe849734be45 --- a/Lib/trace.py +++ b/Lib/trace.py @@ -59,10 +59,7 @@ import dis import pickle from warnings import warn as _warn -try: - from time import monotonic as _time -except ImportError: - from time import time as _time +from time import monotonic as _time try: import threading @@ -326,16 +323,17 @@ def write_results(self, show_missing=True, summary=False, coverdir=None): lnotab = _find_executable_linenos(filename) else: lnotab = {} + if lnotab: + source = linecache.getlines(filename) + coverpath = os.path.join(dir, modulename + ".cover") + with open(filename, 'rb') as fp: + encoding, _ = tokenize.detect_encoding(fp.readline) + n_hits, n_lines = self.write_results_file(coverpath, source, + lnotab, count, encoding) + if summary and n_lines: + percent = int(100 * n_hits / n_lines) + sums[modulename] = n_lines, percent, modulename, filename - source = linecache.getlines(filename) - coverpath = os.path.join(dir, modulename + ".cover") - with open(filename, 'rb') as fp: - encoding, _ = tokenize.detect_encoding(fp.readline) - n_hits, n_lines = self.write_results_file(coverpath, source, - lnotab, count, encoding) - if summary and n_lines: - percent = int(100 * n_hits / n_lines) - sums[modulename] = n_lines, percent, modulename, filename if summary and sums: print("lines cov% module (path)") diff --git a/Lib/traceback.py b/Lib/traceback.py index 3b2cae748e97..c1ab36ec4451 100644 --- a/Lib/traceback.py +++ b/Lib/traceback.py @@ -205,7 +205,7 @@ def _format_exception_only_iter(etype, value): yield _format_final_exc_line(etype, value) return - stype = etype.__name__ + stype = etype.__qualname__ smod = etype.__module__ if smod not in ("__main__", "builtins"): stype = smod + '.' + stype @@ -224,11 +224,12 @@ def _format_exception_only_iter(etype, value): if badline is not None: yield ' {}\n'.format(badline.strip()) if offset is not None: - caretspace = badline.rstrip('\n')[:offset].lstrip() + caretspace = badline.rstrip('\n') + offset = min(len(caretspace), offset) - 1 + caretspace = caretspace[:offset].lstrip() # non-space whitespace (likes tabs) must be kept for alignment caretspace = ((c.isspace() and c or ' ') for c in caretspace) - # only three spaces to account for offset1 == pos 0 - yield ' {}^\n'.format(''.join(caretspace)) + yield ' {}^\n'.format(''.join(caretspace)) msg = value.msg or "" yield "{}: {}\n".format(stype, msg) diff --git a/Lib/tracemalloc.py b/Lib/tracemalloc.py index 816f7346d64b..adedfc5fb44b 100644 --- a/Lib/tracemalloc.py +++ b/Lib/tracemalloc.py @@ -1,6 +1,7 @@ -from collections import Sequence +from collections import Sequence, Iterable from functools import total_ordering import fnmatch +import linecache import os.path import pickle @@ -118,12 +119,12 @@ def _compare_grouped_stats(old_group, new_group): previous = old_group.pop(traceback, None) if previous is not None: stat = StatisticDiff(traceback, - stat.size, stat.size - previous.size, - stat.count, stat.count - previous.count) + stat.size, stat.size - previous.size, + stat.count, stat.count - previous.count) else: stat = StatisticDiff(traceback, - stat.size, stat.size, - stat.count, stat.count) + stat.size, stat.size, + stat.count, stat.count) statistics.append(stat) for traceback, stat in old_group.items(): @@ -140,6 +141,7 @@ class Frame: __slots__ = ("_frame",) def __init__(self, frame): + # frame is a tuple: (filename: str, lineno: int) self._frame = frame @property @@ -176,14 +178,18 @@ class Traceback(Sequence): def __init__(self, frames): Sequence.__init__(self) + # frames is a tuple of frame tuples: see Frame constructor for the + # format of a frame tuple self._frames = frames def __len__(self): return len(self._frames) def __getitem__(self, index): - trace = self._frames[index] - return Frame(trace) + if isinstance(index, slice): + return tuple(Frame(trace) for trace in self._frames[index]) + else: + return Frame(self._frames[index]) def __contains__(self, frame): return frame._frame in self._frames @@ -203,6 +209,18 @@ def __str__(self): def __repr__(self): return "" % (tuple(self),) + def format(self, limit=None): + lines = [] + if limit is not None and limit < 0: + return lines + for frame in self[:limit]: + lines.append(' File "%s", line %s' + % (frame.filename, frame.lineno)) + line = linecache.getline(frame.filename, frame.lineno).strip() + if line: + lines.append(' %s' % line) + return lines + def get_object_traceback(obj): """ @@ -226,6 +244,8 @@ class Trace: __slots__ = ("_trace",) def __init__(self, trace): + # trace is a tuple: (size, traceback), see Traceback constructor + # for the format of the traceback tuple self._trace = trace @property @@ -253,14 +273,17 @@ def __repr__(self): class _Traces(Sequence): def __init__(self, traces): Sequence.__init__(self) + # traces is a tuple of trace tuples: see Trace constructor self._traces = traces def __len__(self): return len(self._traces) def __getitem__(self, index): - trace = self._traces[index] - return Trace(trace) + if isinstance(index, slice): + return tuple(Trace(trace) for trace in self._traces[index]) + else: + return Trace(self._traces[index]) def __contains__(self, trace): return trace._trace in self._traces @@ -321,6 +344,8 @@ class Snapshot: """ def __init__(self, traces, traceback_limit): + # traces is a tuple of trace tuples: see _Traces constructor for + # the exact format self.traces = _Traces(traces) self.traceback_limit = traceback_limit @@ -357,6 +382,9 @@ def filter_traces(self, filters): is a list of Filter instances. If filters is an empty list, return a new Snapshot instance with a copy of the traces. """ + if not isinstance(filters, Iterable): + raise TypeError("filters must be a list of filters, not %s" + % type(filters).__name__) if filters: include_filters = [] exclude_filters = [] diff --git a/Lib/turtle.py b/Lib/turtle.py index ab7b6ba42a6c..f4400c90fd73 100644 --- a/Lib/turtle.py +++ b/Lib/turtle.py @@ -109,6 +109,7 @@ import math import time import inspect +import sys from os.path import isfile, split, join from copy import deepcopy @@ -139,7 +140,7 @@ _tg_utilities = ['write_docstringdict', 'done'] __all__ = (_tg_classes + _tg_screen_functions + _tg_turtle_functions + - _tg_utilities) # + _math_functions) + _tg_utilities + ['Terminator']) # + _math_functions) _alias_list = ['addshape', 'backward', 'bk', 'fd', 'ht', 'lt', 'pd', 'pos', 'pu', 'rt', 'seth', 'setpos', 'setposition', 'st', @@ -992,6 +993,13 @@ def __init__(self, cv, mode=_CFG["mode"], self._colormode = _CFG["colormode"] self._keys = [] self.clear() + if sys.platform == 'darwin': + # Force Turtle window to the front on OS X. This is needed because + # the Turtle window will show behind the Terminal window when you + # start the demo from the command line. + rootwindow = cv.winfo_toplevel() + rootwindow.call('wm', 'attributes', '.', '-topmost', '1') + rootwindow.call('wm', 'attributes', '.', '-topmost', '0') def clear(self): """Delete all drawings and all turtles from the TurtleScreen. @@ -2587,7 +2595,7 @@ def setundobuffer(self, size): Example (for a Turtle instance named turtle): >>> turtle.setundobuffer(42) """ - if size is None: + if size is None or size <= 0: self.undobuffer = None else: self.undobuffer = Tbuffer(size) @@ -2938,7 +2946,7 @@ def shapetransform(self, t11=None, t12=None, t21=None, t22=None): self._stretchfactor = a11, a22 self._shearfactor = a12/a22 self._tilt = alfa - self._update() + self.pen(resizemode="user") def _polytrafo(self, poly): diff --git a/Lib/turtledemo/__init__.py b/Lib/turtledemo/__init__.py index e69de29bb2d1..77150e25331c 100644 --- a/Lib/turtledemo/__init__.py +++ b/Lib/turtledemo/__init__.py @@ -0,0 +1,14 @@ +""" + -------------------------------------- + About this viewer + -------------------------------------- + + Tiny demo viewer to view turtle graphics example scripts. + + Quickly and dirtyly assembled by Gregor Lingl. + June, 2006 + + For more information see: turtledemo - Help + + Have fun! +""" diff --git a/Lib/turtledemo/__main__.py b/Lib/turtledemo/__main__.py index a14684c35681..6280c8497b61 100755 --- a/Lib/turtledemo/__main__.py +++ b/Lib/turtledemo/__main__.py @@ -1,17 +1,104 @@ #!/usr/bin/env python3 + +""" + ---------------------------------------------- + turtleDemo - Help + ---------------------------------------------- + + This document has two sections: + + (1) How to use the demo viewer + (2) How to add your own demos to the demo repository + + + (1) How to use the demo viewer. + + Select a demoscript from the example menu. + The (syntax colored) source code appears in the left + source code window. IT CANNOT BE EDITED, but ONLY VIEWED! + + The demo viewer windows can be resized. The divider between text + and canvas can be moved by grabbing it with the mouse. The text font + size can be changed from the menu and with Control/Command '-'/'+'. + It can also be changed on most systems with Control-mousewheel + when the mouse is over the text. + + Press START button to start the demo. + Stop execution by pressing the STOP button. + Clear screen by pressing the CLEAR button. + Restart by pressing the START button again. + + SPECIAL demos, such as clock.py are those which run EVENTDRIVEN. + + Press START button to start the demo. + + - Until the EVENTLOOP is entered everything works + as in an ordinary demo script. + + - When the EVENTLOOP is entered, you control the + application by using the mouse and/or keys (or it's + controlled by some timer events) + To stop it you can and must press the STOP button. + + While the EVENTLOOP is running, the examples menu is disabled. + + - Only after having pressed the STOP button, you may + restart it or choose another example script. + + * * * * * * * * + In some rare situations there may occur interferences/conflicts + between events concerning the demo script and those concerning the + demo-viewer. (They run in the same process.) Strange behaviour may be + the consequence and in the worst case you must close and restart the + viewer. + * * * * * * * * + + + (2) How to add your own demos to the demo repository + + - Place the file in the same directory as turtledemo/__main__.py + IMPORTANT! When imported, the demo should not modify the system + by calling functions in other modules, such as sys, tkinter, or + turtle. Global variables should be initialized in main(). + + - The code must contain a main() function which will + be executed by the viewer (see provided example scripts). + It may return a string which will be displayed in the Label below + the source code window (when execution has finished.) + + - In order to run mydemo.py by itself, such as during development, + add the following at the end of the file: + + if __name__ == '__main__': + main() + mainloop() # keep window open + + python -m turtledemo.mydemo # will then run it + + - If the demo is EVENT DRIVEN, main must return the string + "EVENTLOOP". This informs the demo viewer that the script is + still running and must be stopped by the user! + + If an "EVENTLOOP" demo runs by itself, as with clock, which uses + ontimer, or minimal_hanoi, which loops by recursion, then the + code should catch the turtle.Terminator exception that will be + raised when the user presses the STOP button. (Paint is not such + a demo; it only acts in response to mouse clicks and movements.) +""" import sys import os from tkinter import * from idlelib.Percolator import Percolator from idlelib.ColorDelegator import ColorDelegator -from idlelib.textView import view_file # TextViewer -from importlib import reload +from idlelib.textView import view_text +from turtledemo import __doc__ as about_turtledemo import turtle import time demo_dir = os.path.dirname(os.path.abspath(__file__)) +darwin = sys.platform == 'darwin' STARTUP = 1 READY = 2 @@ -21,170 +108,213 @@ menufont = ("Arial", 12, NORMAL) btnfont = ("Arial", 12, 'bold') -txtfont = ('Lucida Console', 8, 'normal') +txtfont = ['Lucida Console', 10, 'normal'] + +MINIMUM_FONT_SIZE = 6 +MAXIMUM_FONT_SIZE = 100 +font_sizes = [8, 9, 10, 11, 12, 14, 18, 20, 22, 24, 30] def getExampleEntries(): return [entry[:-3] for entry in os.listdir(demo_dir) if entry.endswith(".py") and entry[0] != '_'] -def showDemoHelp(): - view_file(demo.root, "Help on turtleDemo", - os.path.join(demo_dir, "demohelp.txt")) - -def showAboutDemo(): - view_file(demo.root, "About turtleDemo", - os.path.join(demo_dir, "about_turtledemo.txt")) - -def showAboutTurtle(): - view_file(demo.root, "About the new turtle module.", - os.path.join(demo_dir, "about_turtle.txt")) +help_entries = ( # (help_label, help_doc) + ('Turtledemo help', __doc__), + ('About turtledemo', about_turtledemo), + ('About turtle module', turtle.__doc__), + ) class DemoWindow(object): - def __init__(self, filename=None): #, root=None): + def __init__(self, filename=None): self.root = root = turtle._root = Tk() - root.wm_protocol("WM_DELETE_WINDOW", self._destroy) - - ################# - self.mBar = Frame(root, relief=RAISED, borderwidth=2) - self.mBar.pack(fill=X) - - self.ExamplesBtn = self.makeLoadDemoMenu() - self.OptionsBtn = self.makeHelpMenu() - self.mBar.tk_menuBar(self.ExamplesBtn, self.OptionsBtn) #, QuitBtn) - root.title('Python turtle-graphics examples') - ################# - self.left_frame = left_frame = Frame(root) - self.text_frame = text_frame = Frame(left_frame) - self.vbar = vbar =Scrollbar(text_frame, name='vbar') - self.text = text = Text(text_frame, - name='text', padx=5, wrap='none', - width=45) - vbar['command'] = text.yview - vbar.pack(side=LEFT, fill=Y) - ##################### - self.hbar = hbar =Scrollbar(text_frame, name='hbar', orient=HORIZONTAL) - hbar['command'] = text.xview - hbar.pack(side=BOTTOM, fill=X) - ##################### - text['yscrollcommand'] = vbar.set - text.config(font=txtfont) - text.config(xscrollcommand=hbar.set) - text.pack(side=LEFT, fill=Y, expand=1) - ##################### - self.output_lbl = Label(left_frame, height= 1,text=" --- ", bg = "#ddf", - font = ("Arial", 16, 'normal')) - self.output_lbl.pack(side=BOTTOM, expand=0, fill=X) - ##################### - text_frame.pack(side=LEFT, fill=BOTH, expand=0) - left_frame.pack(side=LEFT, fill=BOTH, expand=0) - self.graph_frame = g_frame = Frame(root) - - turtle._Screen._root = g_frame - turtle._Screen._canvas = turtle.ScrolledCanvas(g_frame, 800, 600, 1000, 800) - #xturtle.Screen._canvas.pack(expand=1, fill="both") - self.screen = _s_ = turtle.Screen() -##### - turtle.TurtleScreen.__init__(_s_, _s_._canvas) -##### - self.scanvas = _s_._canvas - #xturtle.RawTurtle.canvases = [self.scanvas] - turtle.RawTurtle.screens = [_s_] - - self.scanvas.pack(side=TOP, fill=BOTH, expand=1) - - self.btn_frame = btn_frame = Frame(g_frame, height=100) - self.start_btn = Button(btn_frame, text=" START ", font=btnfont, fg = "white", - disabledforeground = "#fed", command=self.startDemo) - self.start_btn.pack(side=LEFT, fill=X, expand=1) - self.stop_btn = Button(btn_frame, text=" STOP ", font=btnfont, fg = "white", - disabledforeground = "#fed", command = self.stopIt) - self.stop_btn.pack(side=LEFT, fill=X, expand=1) - self.clear_btn = Button(btn_frame, text=" CLEAR ", font=btnfont, fg = "white", - disabledforeground = "#fed", command = self.clearCanvas) - self.clear_btn.pack(side=LEFT, fill=X, expand=1) - - self.btn_frame.pack(side=TOP, fill=BOTH, expand=0) - self.graph_frame.pack(side=TOP, fill=BOTH, expand=1) + root.wm_protocol("WM_DELETE_WINDOW", self._destroy) - Percolator(text).insertfilter(ColorDelegator()) + if darwin: + import subprocess + # Make sure we are the currently activated OS X application + # so that our menu bar appears. + p = subprocess.Popen( + [ + 'osascript', + '-e', 'tell application "System Events"', + '-e', 'set frontmost of the first process whose ' + 'unix id is {} to true'.format(os.getpid()), + '-e', 'end tell', + ], + stderr=subprocess.DEVNULL, + stdout=subprocess.DEVNULL,) + + root.grid_rowconfigure(0, weight=1) + root.grid_columnconfigure(0, weight=1) + root.grid_columnconfigure(1, minsize=90, weight=1) + root.grid_columnconfigure(2, minsize=90, weight=1) + root.grid_columnconfigure(3, minsize=90, weight=1) + + self.mBar = Menu(root, relief=RAISED, borderwidth=2) + self.mBar.add_cascade(menu=self.makeLoadDemoMenu(self.mBar), + label='Examples', underline=0) + self.mBar.add_cascade(menu=self.makeFontMenu(self.mBar), + label='Fontsize', underline=0) + self.mBar.add_cascade(menu=self.makeHelpMenu(self.mBar), + label='Help', underline=0) + root['menu'] = self.mBar + + pane = PanedWindow(orient=HORIZONTAL, sashwidth=5, + sashrelief=SOLID, bg='#ddd') + pane.add(self.makeTextFrame(pane)) + pane.add(self.makeGraphFrame(pane)) + pane.grid(row=0, columnspan=4, sticky='news') + + self.output_lbl = Label(root, height= 1, text=" --- ", bg="#ddf", + font=("Arial", 16, 'normal'), borderwidth=2, + relief=RIDGE) + self.start_btn = Button(root, text=" START ", font=btnfont, + fg="white", disabledforeground = "#fed", + command=self.startDemo) + self.stop_btn = Button(root, text=" STOP ", font=btnfont, + fg="white", disabledforeground = "#fed", + command=self.stopIt) + self.clear_btn = Button(root, text=" CLEAR ", font=btnfont, + fg="white", disabledforeground="#fed", + command = self.clearCanvas) + self.output_lbl.grid(row=1, column=0, sticky='news', padx=(0,5)) + self.start_btn.grid(row=1, column=1, sticky='ew') + self.stop_btn.grid(row=1, column=2, sticky='ew') + self.clear_btn.grid(row=1, column=3, sticky='ew') + + Percolator(self.text).insertfilter(ColorDelegator()) self.dirty = False self.exitflag = False if filename: self.loadfile(filename) - self.configGUI(NORMAL, DISABLED, DISABLED, DISABLED, + self.configGUI(DISABLED, DISABLED, DISABLED, "Choose example from menu", "black") self.state = STARTUP - def _destroy(self): - self.root.destroy() - sys.exit() - def configGUI(self, menu, start, stop, clear, txt="", color="blue"): - self.ExamplesBtn.config(state=menu) + def onResize(self, event): + cwidth = self._canvas.winfo_width() + cheight = self._canvas.winfo_height() + self._canvas.xview_moveto(0.5*(self.canvwidth-cwidth)/self.canvwidth) + self._canvas.yview_moveto(0.5*(self.canvheight-cheight)/self.canvheight) - self.start_btn.config(state=start) - if start == NORMAL: - self.start_btn.config(bg="#d00") - else: - self.start_btn.config(bg="#fca") + def makeTextFrame(self, root): + self.text_frame = text_frame = Frame(root) + self.text = text = Text(text_frame, name='text', padx=5, + wrap='none', width=45) - self.stop_btn.config(state=stop) - if stop == NORMAL: - self.stop_btn.config(bg="#d00") - else: - self.stop_btn.config(bg="#fca") - self.clear_btn.config(state=clear) + self.vbar = vbar = Scrollbar(text_frame, name='vbar') + vbar['command'] = text.yview + vbar.pack(side=LEFT, fill=Y) + self.hbar = hbar = Scrollbar(text_frame, name='hbar', orient=HORIZONTAL) + hbar['command'] = text.xview + hbar.pack(side=BOTTOM, fill=X) + text['yscrollcommand'] = vbar.set + text['xscrollcommand'] = hbar.set + + text['font'] = tuple(txtfont) + shortcut = 'Command' if darwin else 'Control' + text.bind_all('<%s-minus>' % shortcut, self.decrease_size) + text.bind_all('<%s-underscore>' % shortcut, self.decrease_size) + text.bind_all('<%s-equal>' % shortcut, self.increase_size) + text.bind_all('<%s-plus>' % shortcut, self.increase_size) + text.bind('', self.update_mousewheel) + text.bind('', self.increase_size) + text.bind('', self.decrease_size) + + text.pack(side=LEFT, fill=BOTH, expand=1) + return text_frame + + def makeGraphFrame(self, root): + turtle._Screen._root = root + self.canvwidth = 1000 + self.canvheight = 800 + turtle._Screen._canvas = self._canvas = canvas = turtle.ScrolledCanvas( + root, 800, 600, self.canvwidth, self.canvheight) + canvas.adjustScrolls() + canvas._rootwindow.bind('', self.onResize) + canvas._canvas['borderwidth'] = 0 - self.clear_btn.config(state=clear) - if clear == NORMAL: - self.clear_btn.config(bg="#d00") + self.screen = _s_ = turtle.Screen() + turtle.TurtleScreen.__init__(_s_, _s_._canvas) + self.scanvas = _s_._canvas + turtle.RawTurtle.screens = [_s_] + return canvas + + def set_txtsize(self, size): + txtfont[1] = size + self.text['font'] = tuple(txtfont) + self.output_lbl['text'] = 'Font size %d' % size + + def decrease_size(self, dummy=None): + self.set_txtsize(max(txtfont[1] - 1, MINIMUM_FONT_SIZE)) + return 'break' + + def increase_size(self, dummy=None): + self.set_txtsize(min(txtfont[1] + 1, MAXIMUM_FONT_SIZE)) + return 'break' + + def update_mousewheel(self, event): + # For wheel up, event.delte = 120 on Windows, -1 on darwin. + # X-11 sends Control-Button-4 event instead. + if (event.delta < 0) == (not darwin): + return self.decrease_size() else: - self.clear_btn.config(bg="#fca") - + return self.increase_size() + + def configGUI(self, start, stop, clear, txt="", color="blue"): + self.start_btn.config(state=start, + bg="#d00" if start == NORMAL else "#fca") + self.stop_btn.config(state=stop, + bg="#d00" if stop == NORMAL else "#fca") + self.clear_btn.config(state=clear, + bg="#d00" if clear == NORMAL else"#fca") self.output_lbl.config(text=txt, fg=color) - - def makeLoadDemoMenu(self): - CmdBtn = Menubutton(self.mBar, text='Examples', underline=0, font=menufont) - CmdBtn.pack(side=LEFT, padx="2m") - CmdBtn.menu = Menu(CmdBtn) + def makeLoadDemoMenu(self, master): + menu = Menu(master) for entry in getExampleEntries(): - def loadexample(x): - def emit(): - self.loadfile(x) - return emit - CmdBtn.menu.add_command(label=entry, underline=0, - font=menufont, command=loadexample(entry)) - - CmdBtn['menu'] = CmdBtn.menu - return CmdBtn - - def makeHelpMenu(self): - CmdBtn = Menubutton(self.mBar, text='Help', underline=0, font=menufont) - CmdBtn.pack(side=LEFT, padx='2m') - CmdBtn.menu = Menu(CmdBtn) - - CmdBtn.menu.add_command(label='About turtle.py', font=menufont, - command=showAboutTurtle) - CmdBtn.menu.add_command(label='turtleDemo - Help', font=menufont, - command=showDemoHelp) - CmdBtn.menu.add_command(label='About turtleDemo', font=menufont, - command=showAboutDemo) - - CmdBtn['menu'] = CmdBtn.menu - return CmdBtn + def load(entry=entry): + self.loadfile(entry) + menu.add_command(label=entry, underline=0, + font=menufont, command=load) + return menu + + def makeFontMenu(self, master): + menu = Menu(master) + menu.add_command(label="Decrease (C-'-')", command=self.decrease_size, + font=menufont) + menu.add_command(label="Increase (C-'+')", command=self.increase_size, + font=menufont) + menu.add_separator() + + for size in font_sizes: + def resize(size=size): + self.set_txtsize(size) + menu.add_command(label=str(size), underline=0, + font=menufont, command=resize) + return menu + + def makeHelpMenu(self, master): + menu = Menu(master) + + for help_label, help_file in help_entries: + def show(help_label=help_label, help_file=help_file): + view_text(self.root, help_label, help_file) + menu.add_command(label=help_label, font=menufont, command=show) + return menu def refreshCanvas(self): - if not self.dirty: return - self.screen.clear() - #self.screen.mode("standard") - self.dirty=False + if self.dirty: + self.screen.clear() + self.dirty=False def loadfile(self, filename): - self.refreshCanvas() + self.clearCanvas() + turtle.TurtleScreen._RUNNING = False modname = 'turtledemo.' + filename __import__(modname) self.module = sys.modules[modname] @@ -193,8 +323,7 @@ def loadfile(self, filename): self.text.delete("1.0", "end") self.text.insert("1.0", chars) self.root.title(filename + " - a Python turtle graphics example") - reload(self.module) - self.configGUI(NORMAL, NORMAL, DISABLED, DISABLED, + self.configGUI(NORMAL, DISABLED, DISABLED, "Press start button", "red") self.state = READY @@ -202,7 +331,7 @@ def startDemo(self): self.refreshCanvas() self.dirty = True turtle.TurtleScreen._RUNNING = True - self.configGUI(DISABLED, DISABLED, NORMAL, DISABLED, + self.configGUI(DISABLED, NORMAL, DISABLED, "demo running...", "black") self.screen.clear() self.screen.mode("standard") @@ -218,49 +347,34 @@ def startDemo(self): self.state = DONE result = "stopped!" if self.state == DONE: - self.configGUI(NORMAL, NORMAL, DISABLED, NORMAL, + self.configGUI(NORMAL, DISABLED, NORMAL, result) elif self.state == EVENTDRIVEN: self.exitflag = True - self.configGUI(DISABLED, DISABLED, NORMAL, DISABLED, + self.configGUI(DISABLED, NORMAL, DISABLED, "use mouse/keys or STOP", "red") def clearCanvas(self): self.refreshCanvas() self.screen._delete("all") self.scanvas.config(cursor="") - self.configGUI(NORMAL, NORMAL, DISABLED, DISABLED) + self.configGUI(NORMAL, DISABLED, DISABLED) def stopIt(self): if self.exitflag: self.clearCanvas() self.exitflag = False - self.configGUI(NORMAL, NORMAL, DISABLED, DISABLED, + self.configGUI(NORMAL, DISABLED, DISABLED, "STOPPED!", "red") - turtle.TurtleScreen._RUNNING = False - #print "stopIT: exitflag = True" - else: - turtle.TurtleScreen._RUNNING = False - #print "stopIt: exitflag = False" + turtle.TurtleScreen._RUNNING = False -if __name__ == '__main__': + def _destroy(self): + self.root.destroy() + + +def main(): demo = DemoWindow() - RUN = True - while RUN: - try: - #print("ENTERING mainloop") - demo.root.mainloop() - except AttributeError: - #print("AttributeError!- WAIT A MOMENT!") - time.sleep(0.3) - print("GOING ON ..") - demo.ckearCanvas() - except TypeError: - demo.screen._delete("all") - #print("CRASH!!!- WAIT A MOMENT!") - time.sleep(0.3) - #print("GOING ON ..") - demo.clearCanvas() - except: - print("BYE!") - RUN = False + demo.root.mainloop() + +if __name__ == '__main__': + main() diff --git a/Lib/turtledemo/about_turtle.txt b/Lib/turtledemo/about_turtle.txt deleted file mode 100644 index d02c7b32600b..000000000000 --- a/Lib/turtledemo/about_turtle.txt +++ /dev/null @@ -1,76 +0,0 @@ - -======================================================== - A new turtle module for Python -======================================================== - -Turtle graphics is a popular way for introducing programming to -kids. It was part of the original Logo programming language developed -by Wally Feurzig and Seymour Papert in 1966. - -Imagine a robotic turtle starting at (0, 0) in the x-y plane. After an ``import turtle``, give it -the command turtle.forward(15), and it moves (on-screen!) 15 pixels in -the direction it is facing, drawing a line as it moves. Give it the -command turtle.right(25), and it rotates in-place 25 degrees clockwise. - -By combining together these and similar commands, intricate shapes and -pictures can easily be drawn. - ------ turtle.py - -This module is an extended reimplementation of turtle.py from the -Python standard distribution up to Python 2.5. (See: http:\\www.python.org) - -It tries to keep the merits of turtle.py and to be (nearly) 100% -compatible with it. This means in the first place to enable the -learning programmer to use all the commands, classes and methods -interactively when using the module from within IDLE run with -the -n switch. - -Roughly it has the following features added: - -- Better animation of the turtle movements, especially of turning the - turtle. So the turtles can more easily be used as a visual feedback - instrument by the (beginning) programmer. - -- Different turtle shapes, gif-images as turtle shapes, user defined - and user controllable turtle shapes, among them compound - (multicolored) shapes. Turtle shapes can be stgretched and tilted, which - makes turtles zu very versatile geometrical objects. - -- Fine control over turtle movement and screen updates via delay(), - and enhanced tracer() and speed() methods. - -- Aliases for the most commonly used commands, like fd for forward etc., - following the early Logo traditions. This reduces the boring work of - typing long sequences of commands, which often occur in a natural way - when kids try to program fancy pictures on their first encounter with - turtle graphcis. - -- Turtles now have an undo()-method with configurable undo-buffer. - -- Some simple commands/methods for creating event driven programs - (mouse-, key-, timer-events). Especially useful for programming games. - -- A scrollable Canvas class. The default scrollable Canvas can be - extended interactively as needed while playing around with the turtle(s). - -- A TurtleScreen class with methods controlling background color or - background image, window and canvas size and other properties of the - TurtleScreen. - -- There is a method, setworldcoordinates(), to install a user defined - coordinate-system for the TurtleScreen. - -- The implementation uses a 2-vector class named Vec2D, derived from tuple. - This class is public, so it can be imported by the application programmer, - which makes certain types of computations very natural and compact. - -- Appearance of the TurtleScreen and the Turtles at startup/import can be - configured by means of a turtle.cfg configuration file. - The default configuration mimics the appearance of the old turtle module. - -- If configured appropriately the module reads in docstrings from a docstring - dictionary in some different language, supplied separately and replaces - the english ones by those read in. There is a utility function - write_docstringdict() to write a dictionary with the original (english) - docstrings to disc, so it can serve as a template for translations. diff --git a/Lib/turtledemo/about_turtledemo.txt b/Lib/turtledemo/about_turtledemo.txt deleted file mode 100644 index a9009bd5fbfe..000000000000 --- a/Lib/turtledemo/about_turtledemo.txt +++ /dev/null @@ -1,13 +0,0 @@ - - -------------------------------------- - About this viewer - -------------------------------------- - - Tiny demo viewer to view turtle graphics example scripts. - - Quickly and dirtyly assembled by Gregor Lingl. - June, 2006 - - For more information see: turtleDemo - Help - - Have fun! diff --git a/Lib/turtledemo/chaos.py b/Lib/turtledemo/chaos.py index d4656f891485..6a45d0d807ef 100644 --- a/Lib/turtledemo/chaos.py +++ b/Lib/turtledemo/chaos.py @@ -29,8 +29,8 @@ def coosys(): line(-1, 0, N+1, 0) line(0, -0.1, 0, 1.1) -def plot(fun, start, colour): - pencolor(colour) +def plot(fun, start, color): + pencolor(color) x = start jumpto(0, x) pendown() diff --git a/Lib/turtledemo/clock.py b/Lib/turtledemo/clock.py old mode 100644 new mode 100755 index a0d157ba49d2..62c8851606b3 --- a/Lib/turtledemo/clock.py +++ b/Lib/turtledemo/clock.py @@ -13,8 +13,6 @@ from turtle import * from datetime import datetime -mode("logo") - def jump(distanz, winkel=0): penup() right(winkel) @@ -42,7 +40,6 @@ def make_hand_shape(name, laenge, spitze): hand_form = get_poly() register_shape(name, hand_form) - def clockface(radius): reset() pensize(7) @@ -83,7 +80,6 @@ def setup(): writer.pu() writer.bk(85) - def wochentag(t): wochentag = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"] @@ -102,22 +98,25 @@ def tick(): sekunde = t.second + t.microsecond*0.000001 minute = t.minute + sekunde/60.0 stunde = t.hour + minute/60.0 - tracer(False) - writer.clear() - writer.home() - writer.forward(65) - writer.write(wochentag(t), - align="center", font=("Courier", 14, "bold")) - writer.back(150) - writer.write(datum(t), - align="center", font=("Courier", 14, "bold")) - writer.forward(85) - tracer(True) - second_hand.setheading(6*sekunde) - minute_hand.setheading(6*minute) - hour_hand.setheading(30*stunde) - tracer(True) - ontimer(tick, 100) + try: + tracer(False) # Terminator can occur here + writer.clear() + writer.home() + writer.forward(65) + writer.write(wochentag(t), + align="center", font=("Courier", 14, "bold")) + writer.back(150) + writer.write(datum(t), + align="center", font=("Courier", 14, "bold")) + writer.forward(85) + tracer(True) + second_hand.setheading(6*sekunde) # or here + minute_hand.setheading(6*minute) + hour_hand.setheading(30*stunde) + tracer(True) + ontimer(tick, 100) + except Terminator: + pass # turtledemo user pressed STOP def main(): tracer(False) @@ -127,6 +126,7 @@ def main(): return "EVENTLOOP" if __name__ == "__main__": + mode("logo") msg = main() print(msg) mainloop() diff --git a/Lib/turtledemo/colormixer.py b/Lib/turtledemo/colormixer.py index f5d308d44305..448db83361a6 100644 --- a/Lib/turtledemo/colormixer.py +++ b/Lib/turtledemo/colormixer.py @@ -1,8 +1,6 @@ # colormixer from turtle import Screen, Turtle, mainloop -import sys -sys.setrecursionlimit(20000) # overcomes, for now, an instability of Python 3.0 class ColorTurtle(Turtle): diff --git a/Lib/turtledemo/demohelp.txt b/Lib/turtledemo/demohelp.txt deleted file mode 100644 index fe83bc760196..000000000000 --- a/Lib/turtledemo/demohelp.txt +++ /dev/null @@ -1,70 +0,0 @@ - - - ---------------------------------------------- - - turtleDemo - Help - - ---------------------------------------------- - - This document has two sections: - - (1) How to use the demo viewer - (2) How to add your own demos to the demo repository - - - (1) How to use the demo viewer. - - Select a demoscript from the example menu. - The (syntax coloured) source code appears in the left - source code window. IT CANNOT BE EDITED, but ONLY VIEWED! - - - Press START button to start the demo. - - Stop execution by pressing the STOP button. - - Clear screen by pressing the CLEAR button. - - Restart by pressing the START button again. - - SPECIAL demos are those which run EVENTDRIVEN. - (For example clock.py - or oldTurtleDemo.py which - in the end expects a mouse click.): - - Press START button to start the demo. - - - Until the EVENTLOOP is entered everything works - as in an ordinary demo script. - - - When the EVENTLOOP is entered, you control the - application by using the mouse and/or keys (or it's - controlled by some timer events) - To stop it you can and must press the STOP button. - - While the EVENTLOOP is running, the examples menu is disabled. - - - Only after having pressed the STOP button, you may - restart it or choose another example script. - - * * * * * * * * - In some rare situations there may occur interferences/conflicts - between events concerning the demo script and those concerning the - demo-viewer. (They run in the same process.) Strange behaviour may be - the consequence and in the worst case you must close and restart the - viewer. - * * * * * * * * - - - (2) How to add your own demos to the demo repository - - - place: same directory as turtledemo/__main__.py - - - requirements on source code: - code must contain a main() function which will - be executed by the viewer (see provided example scripts) - main() may return a string which will be displayed - in the Label below the source code window (when execution - has finished.) - - !! For programs, which are EVENT DRIVEN, main must return - !! the string "EVENTLOOP". This informs the viewer, that the - !! script is still running and must be stopped by the user! - - - diff --git a/Lib/turtledemo/forest.py b/Lib/turtledemo/forest.py old mode 100644 new mode 100755 index a837d844c917..7fe080e6333a --- a/Lib/turtledemo/forest.py +++ b/Lib/turtledemo/forest.py @@ -3,12 +3,12 @@ tdemo_forest.py -Displays a 'forest' of 3 'breadth-first-trees' -similar to the one from example tree. -For further remarks see xtx_tree.py +Displays a 'forest' of 3 breadth-first-trees +similar to the one in tree. +For further remarks see tree.py This example is a 'breadth-first'-rewrite of -a Logo program written by Erich Neuwirth. See: +a Logo program written by Erich Neuwirth. See http://homepage.univie.ac.at/erich.neuwirth/ """ from turtle import Turtle, colormode, tracer, mainloop @@ -104,6 +104,5 @@ def main(): return "runtime: %.2f sec." % (b-a) if __name__ == '__main__': - msg = main() - print(msg) + main() mainloop() diff --git a/Lib/turtledemo/minimal_hanoi.py b/Lib/turtledemo/minimal_hanoi.py old mode 100644 new mode 100755 index cfb78dcac141..4a432f2b2908 --- a/Lib/turtledemo/minimal_hanoi.py +++ b/Lib/turtledemo/minimal_hanoi.py @@ -50,9 +50,12 @@ def hanoi(n, from_, with_, to_): def play(): onkey(None,"space") clear() - hanoi(6, t1, t2, t3) - write("press STOP button to exit", - align="center", font=("Courier", 16, "bold")) + try: + hanoi(6, t1, t2, t3) + write("press STOP button to exit", + align="center", font=("Courier", 16, "bold")) + except Terminator: + pass # turtledemo user pressed STOP def main(): global t1, t2, t3 diff --git a/Lib/turtledemo/nim.py b/Lib/turtledemo/nim.py index 792ba5153482..9ae6cc5c01b9 100644 --- a/Lib/turtledemo/nim.py +++ b/Lib/turtledemo/nim.py @@ -143,7 +143,6 @@ def display(self, msg1, msg2=None): self.writer.write(msg1, align="center", font=("Courier",14,"bold")) self.screen.tracer(True) - def setup(self): self.screen.tracer(False) for row in range(3): @@ -181,6 +180,7 @@ def clear(self): if self.game.state == Nim.OVER: self.screen.clear() + class NimController(object): def __init__(self, game): @@ -201,6 +201,7 @@ def notify_move(self, row, col): self.game.model.notify_move(row, col) self.BUSY = False + class Nim(object): CREATED = 0 RUNNING = 1 @@ -213,13 +214,12 @@ def __init__(self, screen): self.controller = NimController(self) -mainscreen = turtle.Screen() -mainscreen.mode("standard") -mainscreen.setup(SCREENWIDTH, SCREENHEIGHT) - def main(): + mainscreen = turtle.Screen() + mainscreen.mode("standard") + mainscreen.setup(SCREENWIDTH, SCREENHEIGHT) nim = Nim(mainscreen) - return "EVENTLOOP!" + return "EVENTLOOP" if __name__ == "__main__": main() diff --git a/Lib/turtledemo/paint.py b/Lib/turtledemo/paint.py old mode 100644 new mode 100755 index 68058ab6ac8a..dde16912dfed --- a/Lib/turtledemo/paint.py +++ b/Lib/turtledemo/paint.py @@ -3,11 +3,15 @@ tdemo_paint.py -A simple eventdriven paint program +A simple event-driven paint program -- use left mouse button to move turtle -- middle mouse button to change color -- right mouse button do turn filling on/off +- left mouse button moves turtle +- middle mouse button changes color +- right mouse button toogles betweem pen up +(no line drawn when the turtle moves) and +pen down (line is drawn). If pen up follows +at least two pen-down moves, the polygon that +includes the starting point is filled. ------------------------------------------- Play around by clicking into the canvas using all three mouse buttons. diff --git a/Lib/turtledemo/peace.py b/Lib/turtledemo/peace.py old mode 100644 new mode 100755 index 63cf7cc2e1b0..e2ba9288d9e4 --- a/Lib/turtledemo/peace.py +++ b/Lib/turtledemo/peace.py @@ -3,14 +3,10 @@ tdemo_peace.py -A very simple drawing suitable as a beginner's -programming example. - -Uses only commands, which are also available in -old turtle.py. - -Intentionally no variables are used except for the -colorloop: +A simple drawing suitable as a beginner's +programming example. Aside from the +peacecolors assignment and the for loop, +it only uses turtle commands. """ from turtle import * @@ -21,7 +17,7 @@ def main(): "royalblue1", "dodgerblue4") reset() - s = Screen() + Screen() up() goto(-320,-195) width(70) @@ -58,7 +54,7 @@ def main(): up() goto(0,300) # vanish if hideturtle() is not available ;-) - return "Done!!" + return "Done!" if __name__ == "__main__": main() diff --git a/Lib/turtledemo/planet_and_moon.py b/Lib/turtledemo/planet_and_moon.py old mode 100644 new mode 100755 index 14c4bbccc411..26abfdb0690a --- a/Lib/turtledemo/planet_and_moon.py +++ b/Lib/turtledemo/planet_and_moon.py @@ -12,9 +12,9 @@ Planet has a circular orbit, moon a stable orbit around the planet. -You can hold the movement temporarily by pressing -the left mouse button with mouse over the -scrollbar of the canvas. +You can hold the movement temporarily by +pressing the left mouse button with the +mouse over the scrollbar of the canvas. """ from turtle import Shape, Turtle, mainloop, Vec2D as Vec @@ -108,6 +108,5 @@ def main(): return "Done!" if __name__ == '__main__': - msg = main() - print(msg) - #mainloop() + main() + mainloop() diff --git a/Lib/turtledemo/tree.py b/Lib/turtledemo/tree.py old mode 100644 new mode 100755 index 9c0b1f7bb43a..71fff355c7cf --- a/Lib/turtledemo/tree.py +++ b/Lib/turtledemo/tree.py @@ -11,9 +11,9 @@ (1) a tree-generator, where the drawing is quasi the side-effect, whereas the generator always yields None. -(2) Turtle-cloning: At each branching point the -current pen is cloned. So in the end there -are 1024 turtles. +(2) Turtle-cloning: At each branching point +the current pen is cloned. So in the end +there are 1024 turtles. """ from turtle import Turtle, mainloop from time import clock diff --git a/Lib/turtledemo/two_canvases.py b/Lib/turtledemo/two_canvases.py old mode 100644 new mode 100755 index 02d89db57e71..d579876616ff --- a/Lib/turtledemo/two_canvases.py +++ b/Lib/turtledemo/two_canvases.py @@ -1,52 +1,54 @@ -#!/usr/bin/env python3 -## DEMONSTRATES USE OF 2 CANVASES, SO CANNOT BE RUN IN DEMOVIEWER! -"""turtle example: Using TurtleScreen and RawTurtle -for drawing on two distinct canvases. +"""turtledemo.two_canvases + +Use TurtleScreen and RawTurtle to draw on two +distinct canvases in a separate windows. The +new window must be separately closed in +addition to pressing the STOP button. """ + from turtle import TurtleScreen, RawTurtle, TK -root = TK.Tk() -cv1 = TK.Canvas(root, width=300, height=200, bg="#ddffff") -cv2 = TK.Canvas(root, width=300, height=200, bg="#ffeeee") -cv1.pack() -cv2.pack() +def main(): + root = TK.Tk() + cv1 = TK.Canvas(root, width=300, height=200, bg="#ddffff") + cv2 = TK.Canvas(root, width=300, height=200, bg="#ffeeee") + cv1.pack() + cv2.pack() -s1 = TurtleScreen(cv1) -s1.bgcolor(0.85, 0.85, 1) -s2 = TurtleScreen(cv2) -s2.bgcolor(1, 0.85, 0.85) + s1 = TurtleScreen(cv1) + s1.bgcolor(0.85, 0.85, 1) + s2 = TurtleScreen(cv2) + s2.bgcolor(1, 0.85, 0.85) -p = RawTurtle(s1) -q = RawTurtle(s2) + p = RawTurtle(s1) + q = RawTurtle(s2) -p.color("red", (1, 0.85, 0.85)) -p.width(3) -q.color("blue", (0.85, 0.85, 1)) -q.width(3) + p.color("red", (1, 0.85, 0.85)) + p.width(3) + q.color("blue", (0.85, 0.85, 1)) + q.width(3) -for t in p,q: - t.shape("turtle") - t.lt(36) + for t in p,q: + t.shape("turtle") + t.lt(36) -q.lt(180) + q.lt(180) -for t in p, q: - t.begin_fill() -for i in range(5): for t in p, q: - t.fd(50) - t.lt(72) -for t in p,q: - t.end_fill() - t.lt(54) - t.pu() - t.bk(50) - -## Want to get some info? - -#print(s1, s2) -#print(p, q) -#print(s1.turtles()) -#print(s2.turtles()) - -TK.mainloop() + t.begin_fill() + for i in range(5): + for t in p, q: + t.fd(50) + t.lt(72) + for t in p,q: + t.end_fill() + t.lt(54) + t.pu() + t.bk(50) + + return "EVENTLOOP" + + +if __name__ == '__main__': + main() + TK.mainloop() # keep window open until user closes it diff --git a/Lib/unittest/__init__.py b/Lib/unittest/__init__.py index a5d50af78f28..f6d7ae278ba1 100644 --- a/Lib/unittest/__init__.py +++ b/Lib/unittest/__init__.py @@ -67,3 +67,12 @@ def testMultiply(self): # deprecated _TextTestResult = TextTestResult + +# There are no tests here, so don't try to run anything discovered from +# introspecting the symbols (e.g. FunctionTestCase). Instead, all our +# tests come from within unittest.test. +def load_tests(loader, tests, pattern): + import os.path + # top level directory cached on loader instance + this_dir = os.path.dirname(__file__) + return loader.discover(start_dir=this_dir, pattern=pattern) diff --git a/Lib/unittest/case.py b/Lib/unittest/case.py index 7ed932fafd13..69888a5a688c 100644 --- a/Lib/unittest/case.py +++ b/Lib/unittest/case.py @@ -9,6 +9,7 @@ import warnings import collections import contextlib +import traceback from . import result from .util import (strclass, safe_repr, _count_diff_all_purpose, @@ -69,6 +70,9 @@ def testPartExecutor(self, test_case, isTest=False): else: self.success = False self.errors.append((test_case, exc_info)) + # explicitly break a reference cycle: + # exc_info -> frame -> exc_info + exc_info = None else: if self.result_supports_subtests and self.success: self.errors.append((test_case, None)) @@ -140,7 +144,7 @@ def __init__(self, expected, test_case, callable_obj=None, self.obj_name = str(callable_obj) else: self.obj_name = None - if isinstance(expected_regex, (bytes, str)): + if expected_regex is not None: expected_regex = re.compile(expected_regex) self.expected_regex = expected_regex self.msg = None @@ -175,6 +179,8 @@ def __exit__(self, exc_type, exc_value, tb): self.obj_name)) else: self._raiseFailure("{} not raised".format(exc_name)) + else: + traceback.clear_frames(tb) if not issubclass(exc_type, self.expected): # let unexpected exceptions pass through return False @@ -559,8 +565,8 @@ def run(self, result=None): return expecting_failure = getattr(testMethod, "__unittest_expecting_failure__", False) + outcome = _Outcome(result) try: - outcome = _Outcome(result) self._outcome = outcome with outcome.testPartExecutor(self): @@ -593,6 +599,15 @@ def run(self, result=None): if stopTestRun is not None: stopTestRun() + # explicitly break reference cycles: + # outcome.errors -> frame -> outcome -> outcome.errors + # outcome.expectedFailure -> frame -> outcome -> outcome.expectedFailure + outcome.errors.clear() + outcome.expectedFailure = None + + # clear the outcome, no more needed + self._outcome = None + def doCleanups(self): """Execute all cleanup functions. Normally called for you after tearDown.""" @@ -1327,9 +1342,6 @@ def __eq__(self, other): self._testFunc == other._testFunc and \ self._description == other._description - def __ne__(self, other): - return not self == other - def __hash__(self): return hash((type(self), self._setUpFunc, self._tearDownFunc, self._testFunc, self._description)) diff --git a/Lib/unittest/loader.py b/Lib/unittest/loader.py index 808c50eb6681..8ee6c5615312 100644 --- a/Lib/unittest/loader.py +++ b/Lib/unittest/loader.py @@ -6,6 +6,7 @@ import traceback import types import functools +import warnings from fnmatch import fnmatch @@ -20,19 +21,22 @@ def _make_failed_import_test(name, suiteClass): - message = 'Failed to import test module: %s\n%s' % (name, traceback.format_exc()) + message = 'Failed to import test module: %s\n%s' % ( + name, traceback.format_exc()) return _make_failed_test('ModuleImportFailure', name, ImportError(message), - suiteClass) + suiteClass, message) def _make_failed_load_tests(name, exception, suiteClass): - return _make_failed_test('LoadTestsFailure', name, exception, suiteClass) + message = 'Failed to call load_tests:\n%s' % (traceback.format_exc(),) + return _make_failed_test( + 'LoadTestsFailure', name, exception, suiteClass, message) -def _make_failed_test(classname, methodname, exception, suiteClass): +def _make_failed_test(classname, methodname, exception, suiteClass, message): def testFailure(self): raise exception attrs = {methodname: testFailure} TestClass = type(classname, (case.TestCase,), attrs) - return suiteClass((TestClass(methodname),)) + return suiteClass((TestClass(methodname),)), message def _make_skipped_test(methodname, exception, suiteClass): @case.skip(str(exception)) @@ -58,6 +62,13 @@ class TestLoader(object): suiteClass = suite.TestSuite _top_level_dir = None + def __init__(self): + super(TestLoader, self).__init__() + self.errors = [] + # Tracks packages which we have called into via load_tests, to + # avoid infinite re-entrancy. + self._loading_packages = set() + def loadTestsFromTestCase(self, testCaseClass): """Return a suite of all tests cases contained in testCaseClass""" if issubclass(testCaseClass, suite.TestSuite): @@ -70,8 +81,30 @@ def loadTestsFromTestCase(self, testCaseClass): loaded_suite = self.suiteClass(map(testCaseClass, testCaseNames)) return loaded_suite - def loadTestsFromModule(self, module, use_load_tests=True): + # 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""" + # 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 + # ignore it and issue a deprecation warning if it's present. + if len(args) > 0 or 'use_load_tests' in kws: + warnings.warn('use_load_tests is deprecated and ignored', + DeprecationWarning) + kws.pop('use_load_tests', None) + if len(args) > 1: + # Complain about the number of arguments, but don't forget the + # required `module` argument. + complaint = len(args) + 1 + raise TypeError('loadTestsFromModule() takes 1 positional argument but {} were given'.format(complaint)) + if len(kws) != 0: + # Since the keyword arguments are unsorted (see PEP 468), just + # pick the alphabetically sorted first argument to complain about, + # if multiple were given. At least the error message will be + # predictable. + complaint = sorted(kws)[0] + raise TypeError("loadTestsFromModule() got an unexpected keyword argument '{}'".format(complaint)) tests = [] for name in dir(module): obj = getattr(module, name) @@ -80,12 +113,14 @@ def loadTestsFromModule(self, module, use_load_tests=True): load_tests = getattr(module, 'load_tests', None) tests = self.suiteClass(tests) - if use_load_tests and load_tests is not None: + if load_tests is not None: try: - return load_tests(self, tests, None) + return load_tests(self, tests, pattern) except Exception as e: - return _make_failed_load_tests(module.__name__, e, - self.suiteClass) + error_case, error_message = _make_failed_load_tests( + module.__name__, e, self.suiteClass) + self.errors.append(error_message) + return error_case return tests def loadTestsFromName(self, name, module=None): @@ -98,20 +133,47 @@ def loadTestsFromName(self, name, module=None): The method optionally resolves the names relative to a given module. """ parts = name.split('.') + error_case, error_message = None, None if module is None: parts_copy = parts[:] while parts_copy: try: - module = __import__('.'.join(parts_copy)) + module_name = '.'.join(parts_copy) + module = __import__(module_name) break except ImportError: - del parts_copy[-1] + next_attribute = parts_copy.pop() + # Last error so we can give it to the user if needed. + error_case, error_message = _make_failed_import_test( + next_attribute, self.suiteClass) if not parts_copy: - raise + # Even the top level import failed: report that error. + self.errors.append(error_message) + return error_case parts = parts[1:] obj = module for part in parts: - parent, obj = obj, getattr(obj, part) + try: + parent, obj = obj, getattr(obj, part) + except AttributeError as e: + # We can't traverse some part of the name. + if (getattr(obj, '__path__', None) is not None + and error_case is not None): + # This is a package (no __path__ per importlib docs), and we + # encountered an error importing something. We cannot tell + # the difference between package.WrongNameTestClass and + # package.wrong_module_name so we just report the + # ImportError - it is more informative. + self.errors.append(error_message) + return error_case + else: + # Otherwise, we signal that an AttributeError has occurred. + error_case, error_message = _make_failed_test( + 'AttributeError', part, e, self.suiteClass, + 'Failed to access attribute:\n%s' % ( + traceback.format_exc(),)) + self.errors.append(error_message) + return error_case if isinstance(obj, types.ModuleType): return self.loadTestsFromModule(obj) @@ -170,9 +232,13 @@ def discover(self, start_dir, pattern='test*.py', top_level_dir=None): If a test package name (directory with '__init__.py') matches the pattern then the package will be checked for a 'load_tests' function. If - this exists then it will be called with loader, tests, pattern. + this exists then it will be called with (loader, tests, pattern) unless + the package has already had load_tests called from the same discovery + invocation, in which case the package module object is not scanned for + tests - this ensures that when a package uses discover to further + discover child tests that infinite recursion does not happen. - If load_tests exists then discovery does *not* recurse into the package, + If load_tests exists then discovery does *not* recurse into the package, load_tests is responsible for loading all tests in the package. The pattern is deliberately not stored as a loader attribute so that @@ -277,6 +343,8 @@ def _get_directory_containing_module(self, module_name): return os.path.dirname(full_path) def _get_name_from_path(self, path): + if path == self._top_level_dir: + return '.' path = _jython_aware_splitext(os.path.normpath(path)) _relpath = os.path.relpath(path, self._top_level_dir) @@ -296,63 +364,111 @@ def _match_path(self, path, full_path, pattern): def _find_tests(self, start_dir, pattern, namespace=False): """Used by discovery. Yields test suites it loads.""" + # Handle the __init__ in this package + name = self._get_name_from_path(start_dir) + # name is '.' when start_dir == top_level_dir (and top_level_dir is by + # definition not a package). + if name != '.' and name not in self._loading_packages: + # name is in self._loading_packages while we have called into + # loadTestsFromModule with name. + tests, should_recurse = self._find_test_path( + start_dir, pattern, namespace) + if tests is not None: + yield tests + if not should_recurse: + # Either an error occured, or load_tests was used by the + # package. + return + # Handle the contents. paths = sorted(os.listdir(start_dir)) - for path in paths: full_path = os.path.join(start_dir, path) - if os.path.isfile(full_path): - if not VALID_MODULE_NAME.match(path): - # valid Python identifiers only - continue - if not self._match_path(path, full_path, pattern): - continue - # if the test file matches, load it + tests, should_recurse = self._find_test_path( + full_path, pattern, namespace) + if tests is not None: + yield tests + if should_recurse: + # we found a package that didn't use load_tests. name = self._get_name_from_path(full_path) + self._loading_packages.add(name) try: - module = self._get_module_from_name(name) - except case.SkipTest as e: - yield _make_skipped_test(name, e, self.suiteClass) - except: - yield _make_failed_import_test(name, self.suiteClass) - else: - mod_file = os.path.abspath(getattr(module, '__file__', full_path)) - realpath = _jython_aware_splitext(os.path.realpath(mod_file)) - fullpath_noext = _jython_aware_splitext(os.path.realpath(full_path)) - if realpath.lower() != fullpath_noext.lower(): - module_dir = os.path.dirname(realpath) - mod_name = _jython_aware_splitext(os.path.basename(full_path)) - expected_dir = os.path.dirname(full_path) - msg = ("%r module incorrectly imported from %r. Expected %r. " - "Is this module globally installed?") - raise ImportError(msg % (mod_name, module_dir, expected_dir)) - yield self.loadTestsFromModule(module) - elif os.path.isdir(full_path): - if (not namespace and - not os.path.isfile(os.path.join(full_path, '__init__.py'))): - continue - - load_tests = None - tests = None - if fnmatch(path, pattern): - # only check load_tests if the package directory itself matches the filter - name = self._get_name_from_path(full_path) - package = self._get_module_from_name(name) - load_tests = getattr(package, 'load_tests', None) - tests = self.loadTestsFromModule(package, use_load_tests=False) - - if load_tests is None: - if tests is not None: - # tests loaded from package file - yield tests - # recurse into the package - yield from self._find_tests(full_path, pattern, - namespace=namespace) - else: - try: - yield load_tests(self, tests, pattern) - except Exception as e: - yield _make_failed_load_tests(package.__name__, e, - self.suiteClass) + yield from self._find_tests(full_path, pattern, namespace) + finally: + self._loading_packages.discard(name) + + def _find_test_path(self, full_path, pattern, namespace=False): + """Used by discovery. + + Loads tests from a single file, or a directories' __init__.py when + passed the directory. + + Returns a tuple (None_or_tests_from_file, should_recurse). + """ + basename = os.path.basename(full_path) + if os.path.isfile(full_path): + if not VALID_MODULE_NAME.match(basename): + # valid Python identifiers only + return None, False + if not self._match_path(basename, full_path, pattern): + return None, False + # if the test file matches, load it + name = self._get_name_from_path(full_path) + try: + module = self._get_module_from_name(name) + except case.SkipTest as e: + return _make_skipped_test(name, e, self.suiteClass), False + except: + error_case, error_message = \ + _make_failed_import_test(name, self.suiteClass) + self.errors.append(error_message) + return error_case, False + else: + mod_file = os.path.abspath( + getattr(module, '__file__', full_path)) + realpath = _jython_aware_splitext( + os.path.realpath(mod_file)) + fullpath_noext = _jython_aware_splitext( + os.path.realpath(full_path)) + if realpath.lower() != fullpath_noext.lower(): + module_dir = os.path.dirname(realpath) + mod_name = _jython_aware_splitext( + os.path.basename(full_path)) + expected_dir = os.path.dirname(full_path) + msg = ("%r module incorrectly imported from %r. Expected " + "%r. Is this module globally installed?") + raise ImportError( + msg % (mod_name, module_dir, expected_dir)) + return self.loadTestsFromModule(module, pattern=pattern), False + elif os.path.isdir(full_path): + if (not namespace and + not os.path.isfile(os.path.join(full_path, '__init__.py'))): + return None, False + + load_tests = None + tests = None + name = self._get_name_from_path(full_path) + try: + package = self._get_module_from_name(name) + except case.SkipTest as e: + return _make_skipped_test(name, e, self.suiteClass), False + except: + error_case, error_message = \ + _make_failed_import_test(name, self.suiteClass) + self.errors.append(error_message) + return error_case, False + else: + load_tests = getattr(package, 'load_tests', None) + # Mark this package as being in load_tests (possibly ;)) + self._loading_packages.add(name) + try: + tests = self.loadTestsFromModule(package, pattern=pattern) + if load_tests is not None: + # loadTestsFromModule(package) has loaded tests for us. + return tests, False + return tests, True + finally: + self._loading_packages.discard(name) + defaultTestLoader = TestLoader() diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py index dc5c0337399a..3b7c157c7d47 100644 --- a/Lib/unittest/mock.py +++ b/Lib/unittest/mock.py @@ -27,9 +27,13 @@ import inspect import pprint import sys +import builtins +from types import ModuleType from functools import wraps, partial +_builtins = {name for name in dir(builtins) if not name.startswith('_')} + BaseExceptions = (BaseException,) if 'java' in sys.platform: # jython @@ -112,11 +116,24 @@ def checksig(_mock_self, *args, **kwargs): def _copy_func_details(func, funcopy): funcopy.__name__ = func.__name__ funcopy.__doc__ = func.__doc__ + try: + funcopy.__text_signature__ = func.__text_signature__ + except AttributeError: + pass # we explicitly don't copy func.__dict__ into this copy as it would # expose original attributes that should be mocked - funcopy.__module__ = func.__module__ - funcopy.__defaults__ = func.__defaults__ - funcopy.__kwdefaults__ = func.__kwdefaults__ + try: + funcopy.__module__ = func.__module__ + except AttributeError: + pass + try: + funcopy.__defaults__ = func.__defaults__ + except AttributeError: + pass + try: + funcopy.__kwdefaults__ = func.__kwdefaults__ + except AttributeError: + pass def _callable(obj): @@ -258,13 +275,11 @@ def _copy(value): return value -_allowed_names = set( - [ - 'return_value', '_mock_return_value', 'side_effect', - '_mock_side_effect', '_mock_parent', '_mock_new_parent', - '_mock_name', '_mock_new_name' - ] -) +_allowed_names = { + 'return_value', '_mock_return_value', 'side_effect', + '_mock_side_effect', '_mock_parent', '_mock_new_parent', + '_mock_name', '_mock_new_name' +} def _delegating_property(name): @@ -330,7 +345,14 @@ def _check_and_set_parent(parent, value, name, new_name): value._mock_name = name return True - +# Internal class to identify if we wrapped an iterator object or not. +class _MockIter(object): + def __init__(self, obj): + self.obj = iter(obj) + def __iter__(self): + return self + def __next__(self): + return next(self.obj) class Base(object): _mock_return_value = DEFAULT @@ -355,7 +377,7 @@ def __new__(cls, *args, **kw): def __init__( self, spec=None, wraps=None, name=None, spec_set=None, parent=None, _spec_state=None, _new_name='', _new_parent=None, - _spec_as_instance=False, _eat_self=None, **kwargs + _spec_as_instance=False, _eat_self=None, unsafe=False, **kwargs ): if _new_parent is None: _new_parent = parent @@ -385,6 +407,7 @@ def __init__( __dict__['_mock_mock_calls'] = _CallList() __dict__['method_calls'] = _CallList() + __dict__['_mock_unsafe'] = unsafe if kwargs: self.configure_mock(**kwargs) @@ -482,7 +505,11 @@ def __get_side_effect(self): delegated = self._mock_delegate if delegated is None: return self._mock_side_effect - return delegated.side_effect + sf = delegated.side_effect + if sf is not None and not callable(sf) and not isinstance(sf, _MockIter): + sf = _MockIter(sf) + delegated.side_effect = sf + return sf def __set_side_effect(self, value): value = _try_iter(value) @@ -537,13 +564,16 @@ def configure_mock(self, **kwargs): def __getattr__(self, name): - if name == '_mock_methods': + if name in {'_mock_methods', '_mock_unsafe'}: raise AttributeError(name) elif self._mock_methods is not None: if name not in self._mock_methods or name in _all_magics: raise AttributeError("Mock object has no attribute %r" % name) elif _is_magic(name): raise AttributeError(name) + if not self._mock_unsafe: + if name.startswith(('assert', 'assret')): + raise AttributeError(name) result = self._mock_children.get(name) if result is _deleted: @@ -726,6 +756,14 @@ def _call_matcher(self, _call): else: return _call + def assert_not_called(_mock_self): + """assert that the mock was never called. + """ + self = _mock_self + if self.call_count != 0: + msg = ("Expected '%s' to not have been called. Called %s times." % + (self._mock_name or 'mock', self.call_count)) + raise AssertionError(msg) def assert_called_with(_mock_self, *args, **kwargs): """assert that the mock was called with the specified arguments. @@ -1026,7 +1064,7 @@ def _is_started(patcher): class _patch(object): attribute_name = None - _active_patches = set() + _active_patches = [] def __init__( self, getter, attribute, new, spec, create, @@ -1142,6 +1180,9 @@ def get_original(self): else: local = True + if name in _builtins and isinstance(target, ModuleType): + self.create = True + if not self.create and original is DEFAULT: raise AttributeError( "%s does not have the attribute %r" % (target, name) @@ -1299,13 +1340,18 @@ def __exit__(self, *exc_info): def start(self): """Activate a patch, returning any created mock.""" result = self.__enter__() - self._active_patches.add(self) + self._active_patches.append(self) return result def stop(self): """Stop an active patch.""" - self._active_patches.discard(self) + try: + self._active_patches.remove(self) + except ValueError: + # If the patch hasn't been started this will fail + pass + return self.__exit__() @@ -1598,8 +1644,8 @@ def _clear_dict(in_dict): def _patch_stopall(): - """Stop all active patches.""" - for patch in list(_patch._active_patches): + """Stop all active patches. LIFO to unroll nested patches.""" + for patch in reversed(_patch._active_patches): patch.stop() @@ -1621,7 +1667,9 @@ def _patch_stopall(): "bool next " ) -numerics = "add sub mul div floordiv mod lshift rshift and xor or pow " +numerics = ( + "add sub mul div floordiv mod lshift rshift and xor or pow truediv" +) inplace = ' '.join('i%s' % n for n in numerics.split()) right = ' '.join('r%s' % n for n in numerics.split()) @@ -1629,11 +1677,12 @@ def _patch_stopall(): # (as they are metaclass methods) # __del__ is not supported at all as it causes problems if it exists -_non_defaults = set('__%s__' % method for method in [ - 'get', 'set', 'delete', 'reversed', 'missing', 'reduce', 'reduce_ex', - 'getinitargs', 'getnewargs', 'getstate', 'setstate', 'getformat', - 'setformat', 'repr', 'dir', 'subclasses', 'format', -]) +_non_defaults = { + '__get__', '__set__', '__delete__', '__reversed__', '__missing__', + '__reduce__', '__reduce_ex__', '__getinitargs__', '__getnewargs__', + '__getstate__', '__setstate__', '__getformat__', '__setformat__', + '__repr__', '__dir__', '__subclasses__', '__format__', +} def _get_method(name, func): @@ -1644,19 +1693,19 @@ def method(self, *args, **kw): return method -_magics = set( +_magics = { '__%s__' % method for method in ' '.join([magic_methods, numerics, inplace, right]).split() -) +} _all_magics = _magics | _non_defaults -_unsupported_magics = set([ +_unsupported_magics = { '__getattr__', '__setattr__', '__init__', '__new__', '__prepare__' '__instancecheck__', '__subclasscheck__', '__del__' -]) +} _calculate_return_value = { '__hash__': lambda self: object.__hash__(self), @@ -1844,7 +1893,7 @@ def _format_call_signature(name, args, kwargs): formatted_args = '' args_string = ', '.join([repr(arg) for arg in args]) kwargs_string = ', '.join([ - '%s=%r' % (key, value) for key, value in kwargs.items() + '%s=%r' % (key, value) for key, value in sorted(kwargs.items()) ]) if args_string: formatted_args = args_string @@ -1966,10 +2015,6 @@ def __eq__(self, other): return (other_args, other_kwargs) == (self_args, self_kwargs) - def __ne__(self, other): - return not self.__eq__(other) - - def __call__(self, *args, **kwargs): if self.name is None: return _Call(('', args, kwargs), name='()') @@ -1985,6 +2030,12 @@ def __getattr__(self, attr): return _Call(name=name, parent=self, from_kall=False) + def count(self, *args, **kwargs): + return self.__getattr__('count')(*args, **kwargs) + + def index(self, *args, **kwargs): + return self.__getattr__('index')(*args, **kwargs) + def __repr__(self): if not self.from_kall: name = self.name or 'call' @@ -2070,6 +2121,8 @@ def create_autospec(spec, spec_set=False, instance=False, _parent=None, elif is_type and instance and not _instance_callable(spec): Klass = NonCallableMagicMock + _name = _kwargs.pop('name', _name) + _new_name = _name if _parent is None: # for a top level object no _new_name should be set diff --git a/Lib/unittest/result.py b/Lib/unittest/result.py index f3f4b676a30f..8e0a64322bbe 100644 --- a/Lib/unittest/result.py +++ b/Lib/unittest/result.py @@ -121,7 +121,6 @@ def addFailure(self, test, err): self.failures.append((test, self._exc_info_to_string(err, test))) self._mirrorOutput = True - @failfast def addSubTest(self, test, subtest, err): """Called at the end of a subtest. 'err' is None if the subtest ended successfully, otherwise it's a @@ -130,6 +129,8 @@ def addSubTest(self, test, subtest, err): # By default, we don't do anything with successful subtests, but # more sophisticated test results might want to record them. if err is not None: + if getattr(self, 'failfast', False): + self.stop() if issubclass(err[0], test.failureException): errors = self.failures else: @@ -156,11 +157,16 @@ def addUnexpectedSuccess(self, test): self.unexpectedSuccesses.append(test) def wasSuccessful(self): - "Tells whether or not this result was a success" - return len(self.failures) == len(self.errors) == 0 + """Tells whether or not this result was a success.""" + # The hasattr check is for test_result's OldResult test. That + # way this method works on objects that lack the attribute. + # (where would such result intances come from? old stored pickles?) + return ((len(self.failures) == len(self.errors) == 0) and + (not hasattr(self, 'unexpectedSuccesses') or + len(self.unexpectedSuccesses) == 0)) def stop(self): - "Indicates that the tests should be aborted" + """Indicates that the tests should be aborted.""" self.shouldStop = True def _exc_info_to_string(self, err, test): diff --git a/Lib/unittest/suite.py b/Lib/unittest/suite.py index ca82765b9c72..76c472514e3f 100644 --- a/Lib/unittest/suite.py +++ b/Lib/unittest/suite.py @@ -20,6 +20,7 @@ class BaseTestSuite(object): def __init__(self, tests=()): self._tests = [] + self._removed_tests = 0 self.addTests(tests) def __repr__(self): @@ -30,16 +31,14 @@ def __eq__(self, other): return NotImplemented return list(self) == list(other) - def __ne__(self, other): - return not self == other - def __iter__(self): return iter(self._tests) def countTestCases(self): - cases = 0 + cases = self._removed_tests for test in self: - cases += test.countTestCases() + if test: + cases += test.countTestCases() return cases def addTest(self, test): @@ -70,10 +69,16 @@ def run(self, result): def _removeTestAtIndex(self, index): """Stop holding a reference to the TestCase at index.""" try: - self._tests[index] = None + test = self._tests[index] except TypeError: - # support for suite implementations that have overriden self._test + # support for suite implementations that have overriden self._tests pass + else: + # Some unittest tests add non TestCase/TestSuite objects to + # the suite. + if hasattr(test, 'countTestCases'): + self._removed_tests += test.countTestCases() + self._tests[index] = None def __call__(self, *args, **kwds): return self.run(*args, **kwds) diff --git a/Lib/unittest/test/test_assertions.py b/Lib/unittest/test/test_assertions.py index af08d5ad65a8..c349a95794f7 100644 --- a/Lib/unittest/test/test_assertions.py +++ b/Lib/unittest/test/test_assertions.py @@ -1,5 +1,6 @@ import datetime import warnings +import weakref import unittest from itertools import product @@ -97,6 +98,36 @@ def _raise(e): else: self.fail("assertRaises() didn't let exception pass through") + def test_assertRaises_frames_survival(self): + # Issue #9815: assertRaises should avoid keeping local variables + # in a traceback alive. + class A: + pass + wr = None + + class Foo(unittest.TestCase): + + def foo(self): + nonlocal wr + a = A() + wr = weakref.ref(a) + try: + raise IOError + except IOError: + raise ValueError + + def test_functional(self): + self.assertRaises(ValueError, self.foo) + + def test_with(self): + with self.assertRaises(ValueError): + self.foo() + + Foo("test_functional").run() + self.assertIsNone(wr()) + Foo("test_with").run() + self.assertIsNone(wr()) + def testAssertNotRegex(self): self.assertNotRegex('Ala ma kota', r'r+') try: diff --git a/Lib/unittest/test/test_case.py b/Lib/unittest/test/test_case.py index 4b931793356a..503ad2fb111b 100644 --- a/Lib/unittest/test/test_case.py +++ b/Lib/unittest/test/test_case.py @@ -14,7 +14,7 @@ import unittest -from .support import ( +from unittest.test.support import ( TestEquality, TestHashing, LoggingResult, LegacyLoggingResult, ResultWithNoStartTestRunStopTestRun ) @@ -397,6 +397,34 @@ def test(self): Foo(events).run(result) self.assertEqual(events, expected) + def test_subtests_failfast(self): + # Ensure proper test flow with subtests and failfast (issue #22894) + events = [] + + class Foo(unittest.TestCase): + def test_a(self): + with self.subTest(): + events.append('a1') + events.append('a2') + + def test_b(self): + with self.subTest(): + events.append('b1') + with self.subTest(): + self.fail('failure') + events.append('b2') + + def test_c(self): + events.append('c') + + result = unittest.TestResult() + result.failfast = True + suite = unittest.makeSuite(Foo) + suite.run(result) + + expected = ['a1', 'a2', 'b1'] + self.assertEqual(events, expected) + # "This class attribute gives the exception raised by the test() method. # If a test framework needs to use a specialized exception, possibly to # carry additional information, it must subclass this exception in @@ -876,8 +904,6 @@ def testAssertEqual_shorten(self): with self.assertRaises(self.failureException) as cm: self.assertEqual(s1, s2) c = 'xxxx[85 chars]xxxxxxxxxxx' - #print() - #print(str(cm.exception)) self.assertEqual(str(cm.exception), "'%sa%s' != '%sb%s'" % (c, p, c, p)) p = 'y' * 100 @@ -1077,12 +1103,9 @@ def testAssertMultiLineEqual(self): except self.failureException as e: # need to remove the first line of the error message error = str(e).split('\n', 1)[1] + self.assertEqual(sample_text_error, error) - # no fair testing ourself with ourself, and assertEqual is used for strings - # so can't use assertEqual either. Just use assertTrue. - self.assertTrue(sample_text_error == error) - - def testAsertEqualSingleLine(self): + def testAssertEqualSingleLine(self): sample_text = "laden swallows fly slowly" revised_sample_text = "unladen swallows fly quickly" sample_text_error = """\ @@ -1094,8 +1117,9 @@ def testAsertEqualSingleLine(self): try: self.assertEqual(sample_text, revised_sample_text) except self.failureException as e: + # need to remove the first line of the error message error = str(e).split('\n', 1)[1] - self.assertTrue(sample_text_error == error) + self.assertEqual(sample_text_error, error) def testAssertIsNone(self): self.assertIsNone(None) @@ -1128,6 +1152,18 @@ def testAssertNotRaisesRegex(self): self.assertRaisesRegex, Exception, 'x', lambda: None) + def testAssertRaisesRegexInvalidRegex(self): + # Issue 20145. + class MyExc(Exception): + pass + self.assertRaises(TypeError, self.assertRaisesRegex, MyExc, lambda: True) + + def testAssertWarnsRegexInvalidRegex(self): + # Issue 20145. + class MyWarn(Warning): + pass + self.assertRaises(TypeError, self.assertWarnsRegex, MyWarn, lambda: True) + def testAssertRaisesRegexMismatch(self): def Stub(): raise Exception('Unexpected') @@ -1339,7 +1375,7 @@ def testAssertLogsPerLevel(self): self.checkAssertLogsPerLevel('ERROR') def checkAssertLogsPerLogger(self, logger): - # Check per-logger fitering + # Check per-logger filtering with self.assertNoStderr(): with self.assertLogs(level='DEBUG') as outer_cm: with self.assertLogs(logger, level='DEBUG') as cm: @@ -1533,6 +1569,32 @@ def testNoCycles(self): del case self.assertFalse(wr()) + def test_no_exception_leak(self): + # Issue #19880: TestCase.run() should not keep a reference + # to the exception + class MyException(Exception): + ninstance = 0 + + def __init__(self): + MyException.ninstance += 1 + Exception.__init__(self) + + def __del__(self): + MyException.ninstance -= 1 + + class TestCase(unittest.TestCase): + def test1(self): + raise MyException() + + @unittest.expectedFailure + def test2(self): + raise MyException() + + for method_name in ('test1', 'test2'): + testcase = TestCase(method_name) + testcase.run() + self.assertEqual(MyException.ninstance, 0) + if __name__ == "__main__": unittest.main() diff --git a/Lib/unittest/test/test_discovery.py b/Lib/unittest/test/test_discovery.py index 6b7b1280f8b2..4f61314ec6fa 100644 --- a/Lib/unittest/test/test_discovery.py +++ b/Lib/unittest/test/test_discovery.py @@ -1,4 +1,5 @@ -import os +import os.path +from os.path import abspath import re import sys import types @@ -6,6 +7,7 @@ from test import support import unittest +import unittest.test class TestableTestProgram(unittest.TestProgram): @@ -67,7 +69,13 @@ def isfile(path): self.addCleanup(restore_isfile) loader._get_module_from_name = lambda path: path + ' module' - loader.loadTestsFromModule = lambda module: module + ' tests' + orig_load_tests = loader.loadTestsFromModule + def loadTestsFromModule(module, pattern=None): + # This is where load_tests is called. + base = orig_load_tests(module, pattern=pattern) + return base + [module + ' tests'] + loader.loadTestsFromModule = loadTestsFromModule + loader.suiteClass = lambda thing: thing top_level = os.path.abspath('/foo') loader._top_level_dir = top_level @@ -75,9 +83,9 @@ def isfile(path): # The test suites found should be sorted alphabetically for reliable # execution order. - expected = [name + ' module tests' for name in - ('test1', 'test2')] - expected.extend([('test_dir.%s' % name) + ' module tests' for name in + expected = [[name + ' module tests'] for name in + ('test1', 'test2', 'test_dir')] + expected.extend([[('test_dir.%s' % name) + ' module tests'] for name in ('test3', 'test4')]) self.assertEqual(suite, expected) @@ -115,34 +123,204 @@ def __init__(self, path): if os.path.basename(path) == 'test_directory': def load_tests(loader, tests, pattern): self.load_tests_args.append((loader, tests, pattern)) - return 'load_tests' + return [self.path + ' load_tests'] self.load_tests = load_tests def __eq__(self, other): return self.path == other.path loader._get_module_from_name = lambda name: Module(name) - def loadTestsFromModule(module, use_load_tests): - if use_load_tests: - raise self.failureException('use_load_tests should be False for packages') - return module.path + ' module tests' + orig_load_tests = loader.loadTestsFromModule + def loadTestsFromModule(module, pattern=None): + # This is where load_tests is called. + base = orig_load_tests(module, pattern=pattern) + return base + [module.path + ' module tests'] loader.loadTestsFromModule = loadTestsFromModule + loader.suiteClass = lambda thing: thing loader._top_level_dir = '/foo' # this time no '.py' on the pattern so that it can match # a test package suite = list(loader._find_tests('/foo', 'test*')) - # We should have loaded tests from the test_directory package by calling load_tests - # and directly from the test_directory2 package + # We should have loaded tests from the a_directory and test_directory2 + # directly and via load_tests for the test_directory package, which + # still calls the baseline module loader. self.assertEqual(suite, - ['load_tests', 'test_directory2' + ' module tests']) + [['a_directory module tests'], + ['test_directory load_tests', + 'test_directory module tests'], + ['test_directory2 module tests']]) + + # The test module paths should be sorted for reliable execution order - self.assertEqual(Module.paths, ['test_directory', 'test_directory2']) + self.assertEqual(Module.paths, + ['a_directory', 'test_directory', 'test_directory2']) # load_tests should have been called once with loader, tests and pattern + # (but there are no tests in our stub module itself, so thats [] at the + # time of call. + self.assertEqual(Module.load_tests_args, + [(loader, [], 'test*')]) + + def test_find_tests_default_calls_package_load_tests(self): + loader = unittest.TestLoader() + + original_listdir = os.listdir + def restore_listdir(): + os.listdir = original_listdir + original_isfile = os.path.isfile + def restore_isfile(): + os.path.isfile = original_isfile + original_isdir = os.path.isdir + def restore_isdir(): + os.path.isdir = original_isdir + + directories = ['a_directory', 'test_directory', 'test_directory2'] + path_lists = [directories, [], [], []] + os.listdir = lambda path: path_lists.pop(0) + self.addCleanup(restore_listdir) + + os.path.isdir = lambda path: True + self.addCleanup(restore_isdir) + + os.path.isfile = lambda path: os.path.basename(path) not in directories + self.addCleanup(restore_isfile) + + class Module(object): + paths = [] + load_tests_args = [] + + def __init__(self, path): + self.path = path + self.paths.append(path) + if os.path.basename(path) == 'test_directory': + def load_tests(loader, tests, pattern): + self.load_tests_args.append((loader, tests, pattern)) + return [self.path + ' load_tests'] + self.load_tests = load_tests + + def __eq__(self, other): + return self.path == other.path + + loader._get_module_from_name = lambda name: Module(name) + orig_load_tests = loader.loadTestsFromModule + def loadTestsFromModule(module, pattern=None): + # This is where load_tests is called. + base = orig_load_tests(module, pattern=pattern) + return base + [module.path + ' module tests'] + loader.loadTestsFromModule = loadTestsFromModule + loader.suiteClass = lambda thing: thing + + loader._top_level_dir = '/foo' + # this time no '.py' on the pattern so that it can match + # a test package + suite = list(loader._find_tests('/foo', 'test*.py')) + + # We should have loaded tests from the a_directory and test_directory2 + # directly and via load_tests for the test_directory package, which + # still calls the baseline module loader. + self.assertEqual(suite, + [['a_directory module tests'], + ['test_directory load_tests', + 'test_directory module tests'], + ['test_directory2 module tests']]) + # The test module paths should be sorted for reliable execution order + self.assertEqual(Module.paths, + ['a_directory', 'test_directory', 'test_directory2']) + + + # load_tests should have been called once with loader, tests and pattern + self.assertEqual(Module.load_tests_args, + [(loader, [], 'test*.py')]) + + def test_find_tests_customise_via_package_pattern(self): + # This test uses the example 'do-nothing' load_tests from + # https://docs.python.org/3/library/unittest.html#load-tests-protocol + # to make sure that that actually works. + # Housekeeping + original_listdir = os.listdir + def restore_listdir(): + os.listdir = original_listdir + self.addCleanup(restore_listdir) + original_isfile = os.path.isfile + def restore_isfile(): + os.path.isfile = original_isfile + self.addCleanup(restore_isfile) + original_isdir = os.path.isdir + def restore_isdir(): + os.path.isdir = original_isdir + self.addCleanup(restore_isdir) + self.addCleanup(sys.path.remove, abspath('/foo')) + + # Test data: we expect the following: + # a listdir to find our package, and a isfile and isdir check on it. + # a module-from-name call to turn that into a module + # followed by load_tests. + # then our load_tests will call discover() which is messy + # but that finally chains into find_tests again for the child dir - + # which is why we don't have a infinite loop. + # We expect to see: + # the module load tests for both package and plain module called, + # and the plain module result nested by the package module load_tests + # indicating that it was processed and could have been mutated. + vfs = {abspath('/foo'): ['my_package'], + abspath('/foo/my_package'): ['__init__.py', 'test_module.py']} + def list_dir(path): + return list(vfs[path]) + os.listdir = list_dir + os.path.isdir = lambda path: not path.endswith('.py') + os.path.isfile = lambda path: path.endswith('.py') + + class Module(object): + paths = [] + load_tests_args = [] + + def __init__(self, path): + self.path = path + self.paths.append(path) + if path.endswith('test_module'): + def load_tests(loader, tests, pattern): + self.load_tests_args.append((loader, tests, pattern)) + return [self.path + ' load_tests'] + else: + def load_tests(loader, tests, pattern): + self.load_tests_args.append((loader, tests, pattern)) + # top level directory cached on loader instance + __file__ = '/foo/my_package/__init__.py' + this_dir = os.path.dirname(__file__) + pkg_tests = loader.discover( + start_dir=this_dir, pattern=pattern) + return [self.path + ' load_tests', tests + ] + pkg_tests + self.load_tests = load_tests + + def __eq__(self, other): + return self.path == other.path + + loader = unittest.TestLoader() + loader._get_module_from_name = lambda name: Module(name) + loader.suiteClass = lambda thing: thing + + loader._top_level_dir = abspath('/foo') + # this time no '.py' on the pattern so that it can match + # a test package + suite = list(loader._find_tests(abspath('/foo'), 'test*.py')) + + # We should have loaded tests from both my_package and + # my_pacakge.test_module, and also run the load_tests hook in both. + # (normally this would be nested TestSuites.) + self.assertEqual(suite, + [['my_package load_tests', [], + ['my_package.test_module load_tests']]]) + # Parents before children. + self.assertEqual(Module.paths, + ['my_package', 'my_package.test_module']) + + # load_tests should have been called twice with loader, tests and pattern self.assertEqual(Module.load_tests_args, - [(loader, 'test_directory' + ' module tests', 'test*')]) + [(loader, [], 'test*.py'), + (loader, [], 'test*.py')]) def test_discover(self): loader = unittest.TestLoader() @@ -190,6 +368,51 @@ def _find_tests(start_dir, pattern, namespace=None): self.assertEqual(_find_tests_args, [(start_dir, 'pattern')]) self.assertIn(top_level_dir, sys.path) + def test_discover_start_dir_is_package_calls_package_load_tests(self): + # This test verifies that the package load_tests in a package is indeed + # invoked when the start_dir is a package (and not the top level). + # http://bugs.python.org/issue22457 + + # Test data: we expect the following: + # an isfile to verify the package, then importing and scanning + # as per _find_tests' normal behaviour. + # We expect to see our load_tests hook called once. + vfs = {abspath('/toplevel'): ['startdir'], + abspath('/toplevel/startdir'): ['__init__.py']} + def list_dir(path): + return list(vfs[path]) + self.addCleanup(setattr, os, 'listdir', os.listdir) + os.listdir = list_dir + self.addCleanup(setattr, os.path, 'isfile', os.path.isfile) + os.path.isfile = lambda path: path.endswith('.py') + self.addCleanup(setattr, os.path, 'isdir', os.path.isdir) + os.path.isdir = lambda path: not path.endswith('.py') + self.addCleanup(sys.path.remove, abspath('/toplevel')) + + class Module(object): + paths = [] + load_tests_args = [] + + def __init__(self, path): + self.path = path + + def load_tests(self, loader, tests, pattern): + return ['load_tests called ' + self.path] + + def __eq__(self, other): + return self.path == other.path + + loader = unittest.TestLoader() + loader._get_module_from_name = lambda name: Module(name) + loader.suiteClass = lambda thing: thing + + suite = loader.discover('/toplevel/startdir', top_level_dir='/toplevel') + + # We should have loaded tests from the package __init__. + # (normally this would be nested TestSuites.) + self.assertEqual(suite, + [['load_tests called startdir']]) + def setup_import_issue_tests(self, fakefile): listdir = os.listdir os.listdir = lambda _: [fakefile] @@ -202,6 +425,17 @@ def restore(): sys.path[:] = orig_sys_path self.addCleanup(restore) + def setup_import_issue_package_tests(self, vfs): + self.addCleanup(setattr, os, 'listdir', os.listdir) + self.addCleanup(setattr, os.path, 'isfile', os.path.isfile) + self.addCleanup(setattr, os.path, 'isdir', os.path.isdir) + self.addCleanup(sys.path.__setitem__, slice(None), list(sys.path)) + def list_dir(path): + return list(vfs[path]) + os.listdir = list_dir + os.path.isdir = lambda path: not path.endswith('.py') + os.path.isfile = lambda path: path.endswith('.py') + def test_discover_with_modules_that_fail_to_import(self): loader = unittest.TestLoader() @@ -210,11 +444,44 @@ def test_discover_with_modules_that_fail_to_import(self): suite = loader.discover('.') self.assertIn(os.getcwd(), sys.path) self.assertEqual(suite.countTestCases(), 1) + # Errors loading the suite are also captured for introspection. + self.assertNotEqual([], loader.errors) + self.assertEqual(1, len(loader.errors)) + error = loader.errors[0] + self.assertTrue( + 'Failed to import test module: test_this_does_not_exist' in error, + 'missing error string in %r' % error) test = list(list(suite)[0])[0] # extract test from suite with self.assertRaises(ImportError): test.test_this_does_not_exist() + def test_discover_with_init_modules_that_fail_to_import(self): + vfs = {abspath('/foo'): ['my_package'], + abspath('/foo/my_package'): ['__init__.py', 'test_module.py']} + self.setup_import_issue_package_tests(vfs) + import_calls = [] + def _get_module_from_name(name): + import_calls.append(name) + raise ImportError("Cannot import Name") + loader = unittest.TestLoader() + loader._get_module_from_name = _get_module_from_name + suite = loader.discover(abspath('/foo')) + + self.assertIn(abspath('/foo'), sys.path) + self.assertEqual(suite.countTestCases(), 1) + # Errors loading the suite are also captured for introspection. + self.assertNotEqual([], loader.errors) + self.assertEqual(1, len(loader.errors)) + error = loader.errors[0] + self.assertTrue( + 'Failed to import test module: my_package' in error, + 'missing error string in %r' % error) + test = list(list(suite)[0])[0] # extract test from suite + with self.assertRaises(ImportError): + test.my_package() + self.assertEqual(import_calls, ['my_package']) + def test_discover_with_module_that_raises_SkipTest_on_import(self): loader = unittest.TestLoader() @@ -231,6 +498,26 @@ def _get_module_from_name(name): suite.run(result) self.assertEqual(len(result.skipped), 1) + def test_discover_with_init_module_that_raises_SkipTest_on_import(self): + vfs = {abspath('/foo'): ['my_package'], + abspath('/foo/my_package'): ['__init__.py', 'test_module.py']} + self.setup_import_issue_package_tests(vfs) + import_calls = [] + def _get_module_from_name(name): + import_calls.append(name) + raise unittest.SkipTest('skipperoo') + loader = unittest.TestLoader() + loader._get_module_from_name = _get_module_from_name + suite = loader.discover(abspath('/foo')) + + self.assertIn(abspath('/foo'), sys.path) + self.assertEqual(suite.countTestCases(), 1) + result = unittest.TestResult() + suite.run(result) + self.assertEqual(len(result.skipped), 1) + self.assertEqual(result.testsRun, 1) + self.assertEqual(import_calls, ['my_package']) + def test_command_line_handling_parseArgs(self): program = TestableTestProgram() diff --git a/Lib/unittest/test/test_functiontestcase.py b/Lib/unittest/test/test_functiontestcase.py index d7fe07a53b9b..c5f2bcbe741b 100644 --- a/Lib/unittest/test/test_functiontestcase.py +++ b/Lib/unittest/test/test_functiontestcase.py @@ -1,6 +1,6 @@ import unittest -from .support import LoggingResult +from unittest.test.support import LoggingResult class Test_FunctionTestCase(unittest.TestCase): diff --git a/Lib/unittest/test/test_loader.py b/Lib/unittest/test/test_loader.py index b62a1b5c5411..68f103611188 100644 --- a/Lib/unittest/test/test_loader.py +++ b/Lib/unittest/test/test_loader.py @@ -1,12 +1,36 @@ import sys import types - +import warnings import unittest +# Decorator used in the deprecation tests to reset the warning registry for +# test isolation and reproducibility. +def warningregistry(func): + def wrapper(*args, **kws): + missing = object() + saved = getattr(warnings, '__warningregistry__', missing).copy() + try: + return func(*args, **kws) + finally: + if saved is missing: + try: + del warnings.__warningregistry__ + except AttributeError: + pass + else: + warnings.__warningregistry__ = saved + class Test_TestLoader(unittest.TestCase): + ### Basic object tests + ################################################################ + + def test___init__(self): + loader = unittest.TestLoader() + self.assertEqual([], loader.errors) + ### Tests for TestLoader.loadTestsFromTestCase ################################################################ @@ -150,6 +174,7 @@ class NotAModule(object): # Check that loadTestsFromModule honors (or not) a module # with a load_tests function. + @warningregistry def test_loadTestsFromModule__load_tests(self): m = types.ModuleType('m') class MyTestCase(unittest.TestCase): @@ -168,10 +193,144 @@ def load_tests(loader, tests, pattern): suite = loader.loadTestsFromModule(m) self.assertIsInstance(suite, unittest.TestSuite) self.assertEqual(load_tests_args, [loader, suite, None]) + # With Python 3.5, the undocumented and unofficial use_load_tests is + # ignored (and deprecated). + load_tests_args = [] + with warnings.catch_warnings(record=False): + warnings.simplefilter('never') + suite = loader.loadTestsFromModule(m, use_load_tests=False) + self.assertEqual(load_tests_args, [loader, suite, None]) + + @warningregistry + def test_loadTestsFromModule__use_load_tests_deprecated_positional(self): + m = types.ModuleType('m') + class MyTestCase(unittest.TestCase): + def test(self): + pass + m.testcase_1 = MyTestCase + + load_tests_args = [] + def load_tests(loader, tests, pattern): + self.assertIsInstance(tests, unittest.TestSuite) + load_tests_args.extend((loader, tests, pattern)) + return tests + m.load_tests = load_tests + # The method still works. + loader = unittest.TestLoader() + # use_load_tests=True as a positional argument. + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always') + suite = loader.loadTestsFromModule(m, False) + self.assertIsInstance(suite, unittest.TestSuite) + # load_tests was still called because use_load_tests is deprecated + # and ignored. + self.assertEqual(load_tests_args, [loader, suite, None]) + # We got a warning. + self.assertIs(w[-1].category, DeprecationWarning) + self.assertEqual(str(w[-1].message), + 'use_load_tests is deprecated and ignored') + + @warningregistry + def test_loadTestsFromModule__use_load_tests_deprecated_keyword(self): + m = types.ModuleType('m') + class MyTestCase(unittest.TestCase): + def test(self): + pass + m.testcase_1 = MyTestCase + + load_tests_args = [] + def load_tests(loader, tests, pattern): + self.assertIsInstance(tests, unittest.TestSuite) + load_tests_args.extend((loader, tests, pattern)) + return tests + m.load_tests = load_tests + # The method still works. + loader = unittest.TestLoader() + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always') + suite = loader.loadTestsFromModule(m, use_load_tests=False) + self.assertIsInstance(suite, unittest.TestSuite) + # load_tests was still called because use_load_tests is deprecated + # and ignored. + self.assertEqual(load_tests_args, [loader, suite, None]) + # We got a warning. + self.assertIs(w[-1].category, DeprecationWarning) + self.assertEqual(str(w[-1].message), + 'use_load_tests is deprecated and ignored') + + @warningregistry + def test_loadTestsFromModule__too_many_positional_args(self): + m = types.ModuleType('m') + class MyTestCase(unittest.TestCase): + def test(self): + pass + m.testcase_1 = MyTestCase load_tests_args = [] - suite = loader.loadTestsFromModule(m, use_load_tests=False) - self.assertEqual(load_tests_args, []) + def load_tests(loader, tests, pattern): + self.assertIsInstance(tests, unittest.TestSuite) + load_tests_args.extend((loader, tests, pattern)) + return tests + m.load_tests = load_tests + loader = unittest.TestLoader() + with self.assertRaises(TypeError) as cm, \ + warnings.catch_warning(record=True) as w: + loader.loadTestsFromModule(m, False, 'testme.*') + # We still got the deprecation warning. + self.assertIs(w[-1].category, DeprecationWarning) + self.assertEqual(str(w[-1].message), + 'use_load_tests is deprecated and ignored') + # We also got a TypeError for too many positional arguments. + self.assertEqual(type(cm.exception), TypeError) + self.assertEqual( + str(cm.exception), + 'loadTestsFromModule() takes 1 positional argument but 3 were given') + + @warningregistry + def test_loadTestsFromModule__use_load_tests_other_bad_keyword(self): + m = types.ModuleType('m') + class MyTestCase(unittest.TestCase): + def test(self): + pass + m.testcase_1 = MyTestCase + + load_tests_args = [] + def load_tests(loader, tests, pattern): + self.assertIsInstance(tests, unittest.TestSuite) + load_tests_args.extend((loader, tests, pattern)) + return tests + m.load_tests = load_tests + loader = unittest.TestLoader() + with warnings.catch_warnings(): + warnings.simplefilter('never') + with self.assertRaises(TypeError) as cm: + loader.loadTestsFromModule( + m, use_load_tests=False, very_bad=True, worse=False) + self.assertEqual(type(cm.exception), TypeError) + # The error message names the first bad argument alphabetically, + # however use_load_tests (which sorts first) is ignored. + self.assertEqual( + str(cm.exception), + "loadTestsFromModule() got an unexpected keyword argument 'very_bad'") + + def test_loadTestsFromModule__pattern(self): + m = types.ModuleType('m') + class MyTestCase(unittest.TestCase): + def test(self): + pass + m.testcase_1 = MyTestCase + + load_tests_args = [] + def load_tests(loader, tests, pattern): + self.assertIsInstance(tests, unittest.TestSuite) + load_tests_args.extend((loader, tests, pattern)) + return tests + m.load_tests = load_tests + + loader = unittest.TestLoader() + suite = loader.loadTestsFromModule(m, pattern='testme.*') + self.assertIsInstance(suite, unittest.TestSuite) + self.assertEqual(load_tests_args, [loader, suite, 'testme.*']) def test_loadTestsFromModule__faulty_load_tests(self): m = types.ModuleType('m') @@ -184,6 +343,13 @@ def load_tests(loader, tests, pattern): suite = loader.loadTestsFromModule(m) self.assertIsInstance(suite, unittest.TestSuite) self.assertEqual(suite.countTestCases(), 1) + # Errors loading the suite are also captured for introspection. + self.assertNotEqual([], loader.errors) + self.assertEqual(1, len(loader.errors)) + error = loader.errors[0] + self.assertTrue( + 'Failed to call load_tests:' in error, + 'missing error string in %r' % error) test = list(suite)[0] self.assertRaisesRegex(TypeError, "some failure", test.m) @@ -219,15 +385,15 @@ def test_loadTestsFromName__empty_name(self): def test_loadTestsFromName__malformed_name(self): loader = unittest.TestLoader() - # XXX Should this raise ValueError or ImportError? - try: - loader.loadTestsFromName('abc () //') - except ValueError: - pass - except ImportError: - pass - else: - self.fail("TestLoader.loadTestsFromName failed to raise ValueError") + suite = loader.loadTestsFromName('abc () //') + error, test = self.check_deferred_error(loader, suite) + expected = "Failed to import test module: abc () //" + expected_regex = "Failed to import test module: abc \(\) //" + self.assertIn( + expected, error, + 'missing error string in %r' % error) + self.assertRaisesRegex( + ImportError, expected_regex, getattr(test, 'abc () //')) # "The specifier name is a ``dotted name'' that may resolve ... to a # module" @@ -236,28 +402,47 @@ def test_loadTestsFromName__malformed_name(self): def test_loadTestsFromName__unknown_module_name(self): loader = unittest.TestLoader() - try: - loader.loadTestsFromName('sdasfasfasdf') - except ImportError as e: - self.assertEqual(str(e), "No module named 'sdasfasfasdf'") - else: - self.fail("TestLoader.loadTestsFromName failed to raise ImportError") + suite = loader.loadTestsFromName('sdasfasfasdf') + expected = "No module named 'sdasfasfasdf'" + error, test = self.check_deferred_error(loader, suite) + self.assertIn( + expected, error, + 'missing error string in %r' % error) + self.assertRaisesRegex(ImportError, expected, test.sdasfasfasdf) # "The specifier name is a ``dotted name'' that may resolve either to # a module, a test case class, a TestSuite instance, a test method # within a test case class, or a callable object which returns a # TestCase or TestSuite instance." # - # What happens when the module is found, but the attribute can't? - def test_loadTestsFromName__unknown_attr_name(self): + # What happens when the module is found, but the attribute isn't? + def test_loadTestsFromName__unknown_attr_name_on_module(self): loader = unittest.TestLoader() - try: - loader.loadTestsFromName('unittest.sdasfasfasdf') - except AttributeError as e: - self.assertEqual(str(e), "'module' object has no attribute 'sdasfasfasdf'") - else: - self.fail("TestLoader.loadTestsFromName failed to raise AttributeError") + suite = loader.loadTestsFromName('unittest.loader.sdasfasfasdf') + expected = "module 'unittest.loader' has no attribute 'sdasfasfasdf'" + error, test = self.check_deferred_error(loader, suite) + self.assertIn( + expected, error, + 'missing error string in %r' % error) + self.assertRaisesRegex(AttributeError, expected, test.sdasfasfasdf) + + # "The specifier name is a ``dotted name'' that may resolve either to + # a module, a test case class, a TestSuite instance, a test method + # within a test case class, or a callable object which returns a + # TestCase or TestSuite instance." + # + # What happens when the module is found, but the attribute isn't? + def test_loadTestsFromName__unknown_attr_name_on_package(self): + loader = unittest.TestLoader() + + suite = loader.loadTestsFromName('unittest.sdasfasfasdf') + expected = "No module named 'unittest.sdasfasfasdf'" + error, test = self.check_deferred_error(loader, suite) + self.assertIn( + expected, error, + 'missing error string in %r' % error) + self.assertRaisesRegex(ImportError, expected, test.sdasfasfasdf) # "The specifier name is a ``dotted name'' that may resolve either to # a module, a test case class, a TestSuite instance, a test method @@ -269,12 +454,13 @@ def test_loadTestsFromName__unknown_attr_name(self): def test_loadTestsFromName__relative_unknown_name(self): loader = unittest.TestLoader() - try: - loader.loadTestsFromName('sdasfasfasdf', unittest) - except AttributeError as e: - self.assertEqual(str(e), "'module' object has no attribute 'sdasfasfasdf'") - else: - self.fail("TestLoader.loadTestsFromName failed to raise AttributeError") + suite = loader.loadTestsFromName('sdasfasfasdf', unittest) + expected = "module 'unittest' has no attribute 'sdasfasfasdf'" + error, test = self.check_deferred_error(loader, suite) + self.assertIn( + expected, error, + 'missing error string in %r' % error) + self.assertRaisesRegex(AttributeError, expected, test.sdasfasfasdf) # "The specifier name is a ``dotted name'' that may resolve either to # a module, a test case class, a TestSuite instance, a test method @@ -290,12 +476,13 @@ def test_loadTestsFromName__relative_unknown_name(self): def test_loadTestsFromName__relative_empty_name(self): loader = unittest.TestLoader() - try: - loader.loadTestsFromName('', unittest) - except AttributeError as e: - pass - else: - self.fail("Failed to raise AttributeError") + suite = loader.loadTestsFromName('', unittest) + error, test = self.check_deferred_error(loader, suite) + expected = "has no attribute ''" + self.assertIn( + expected, error, + 'missing error string in %r' % error) + self.assertRaisesRegex(AttributeError, expected, getattr(test, '')) # "The specifier name is a ``dotted name'' that may resolve either to # a module, a test case class, a TestSuite instance, a test method @@ -310,14 +497,15 @@ def test_loadTestsFromName__relative_malformed_name(self): loader = unittest.TestLoader() # XXX Should this raise AttributeError or ValueError? - try: - loader.loadTestsFromName('abc () //', unittest) - except ValueError: - pass - except AttributeError: - pass - else: - self.fail("TestLoader.loadTestsFromName failed to raise ValueError") + suite = loader.loadTestsFromName('abc () //', unittest) + error, test = self.check_deferred_error(loader, suite) + expected = "module 'unittest' has no attribute 'abc () //'" + expected_regex = "module 'unittest' has no attribute 'abc \(\) //'" + self.assertIn( + expected, error, + 'missing error string in %r' % error) + self.assertRaisesRegex( + AttributeError, expected_regex, getattr(test, 'abc () //')) # "The method optionally resolves name relative to the given module" # @@ -423,12 +611,13 @@ def test(self): m.testcase_1 = MyTestCase loader = unittest.TestLoader() - try: - loader.loadTestsFromName('testcase_1.testfoo', m) - except AttributeError as e: - self.assertEqual(str(e), "type object 'MyTestCase' has no attribute 'testfoo'") - else: - self.fail("Failed to raise AttributeError") + suite = loader.loadTestsFromName('testcase_1.testfoo', m) + expected = "type object 'MyTestCase' has no attribute 'testfoo'" + error, test = self.check_deferred_error(loader, suite) + self.assertIn( + expected, error, + 'missing error string in %r' % error) + self.assertRaisesRegex(AttributeError, expected, test.testfoo) # "The specifier name is a ``dotted name'' that may resolve ... to # ... a callable object which returns a ... TestSuite instance" @@ -546,6 +735,23 @@ def test_loadTestsFromName__module_not_loaded(self): ### Tests for TestLoader.loadTestsFromNames() ################################################################ + def check_deferred_error(self, loader, suite): + """Helper function for checking that errors in loading are reported. + + :param loader: A loader with some errors. + :param suite: A suite that should have a late bound error. + :return: The first error message from the loader and the test object + from the suite. + """ + self.assertIsInstance(suite, unittest.TestSuite) + self.assertEqual(suite.countTestCases(), 1) + # Errors loading the suite are also captured for introspection. + self.assertNotEqual([], loader.errors) + self.assertEqual(1, len(loader.errors)) + error = loader.errors[0] + test = list(suite)[0] + return error, test + # "Similar to loadTestsFromName(), but takes a sequence of names rather # than a single name." # @@ -598,14 +804,15 @@ def test_loadTestsFromNames__malformed_name(self): loader = unittest.TestLoader() # XXX Should this raise ValueError or ImportError? - try: - loader.loadTestsFromNames(['abc () //']) - except ValueError: - pass - except ImportError: - pass - else: - self.fail("TestLoader.loadTestsFromNames failed to raise ValueError") + suite = loader.loadTestsFromNames(['abc () //']) + error, test = self.check_deferred_error(loader, list(suite)[0]) + expected = "Failed to import test module: abc () //" + expected_regex = "Failed to import test module: abc \(\) //" + self.assertIn( + expected, error, + 'missing error string in %r' % error) + self.assertRaisesRegex( + ImportError, expected_regex, getattr(test, 'abc () //')) # "The specifier name is a ``dotted name'' that may resolve either to # a module, a test case class, a TestSuite instance, a test method @@ -616,12 +823,13 @@ def test_loadTestsFromNames__malformed_name(self): def test_loadTestsFromNames__unknown_module_name(self): loader = unittest.TestLoader() - try: - loader.loadTestsFromNames(['sdasfasfasdf']) - except ImportError as e: - self.assertEqual(str(e), "No module named 'sdasfasfasdf'") - else: - self.fail("TestLoader.loadTestsFromNames failed to raise ImportError") + suite = loader.loadTestsFromNames(['sdasfasfasdf']) + error, test = self.check_deferred_error(loader, list(suite)[0]) + expected = "Failed to import test module: sdasfasfasdf" + self.assertIn( + expected, error, + 'missing error string in %r' % error) + self.assertRaisesRegex(ImportError, expected, test.sdasfasfasdf) # "The specifier name is a ``dotted name'' that may resolve either to # a module, a test case class, a TestSuite instance, a test method @@ -632,12 +840,14 @@ def test_loadTestsFromNames__unknown_module_name(self): def test_loadTestsFromNames__unknown_attr_name(self): loader = unittest.TestLoader() - try: - loader.loadTestsFromNames(['unittest.sdasfasfasdf', 'unittest']) - except AttributeError as e: - self.assertEqual(str(e), "'module' object has no attribute 'sdasfasfasdf'") - else: - self.fail("TestLoader.loadTestsFromNames failed to raise AttributeError") + suite = loader.loadTestsFromNames( + ['unittest.loader.sdasfasfasdf', 'unittest.test.dummy']) + error, test = self.check_deferred_error(loader, list(suite)[0]) + expected = "module 'unittest.loader' has no attribute 'sdasfasfasdf'" + self.assertIn( + expected, error, + 'missing error string in %r' % error) + self.assertRaisesRegex(AttributeError, expected, test.sdasfasfasdf) # "The specifier name is a ``dotted name'' that may resolve either to # a module, a test case class, a TestSuite instance, a test method @@ -651,12 +861,13 @@ def test_loadTestsFromNames__unknown_attr_name(self): def test_loadTestsFromNames__unknown_name_relative_1(self): loader = unittest.TestLoader() - try: - loader.loadTestsFromNames(['sdasfasfasdf'], unittest) - except AttributeError as e: - self.assertEqual(str(e), "'module' object has no attribute 'sdasfasfasdf'") - else: - self.fail("TestLoader.loadTestsFromName failed to raise AttributeError") + suite = loader.loadTestsFromNames(['sdasfasfasdf'], unittest) + error, test = self.check_deferred_error(loader, list(suite)[0]) + expected = "module 'unittest' has no attribute 'sdasfasfasdf'" + self.assertIn( + expected, error, + 'missing error string in %r' % error) + self.assertRaisesRegex(AttributeError, expected, test.sdasfasfasdf) # "The specifier name is a ``dotted name'' that may resolve either to # a module, a test case class, a TestSuite instance, a test method @@ -670,12 +881,13 @@ def test_loadTestsFromNames__unknown_name_relative_1(self): def test_loadTestsFromNames__unknown_name_relative_2(self): loader = unittest.TestLoader() - try: - loader.loadTestsFromNames(['TestCase', 'sdasfasfasdf'], unittest) - except AttributeError as e: - self.assertEqual(str(e), "'module' object has no attribute 'sdasfasfasdf'") - else: - self.fail("TestLoader.loadTestsFromName failed to raise AttributeError") + suite = loader.loadTestsFromNames(['TestCase', 'sdasfasfasdf'], unittest) + error, test = self.check_deferred_error(loader, list(suite)[1]) + expected = "module 'unittest' has no attribute 'sdasfasfasdf'" + self.assertIn( + expected, error, + 'missing error string in %r' % error) + self.assertRaisesRegex(AttributeError, expected, test.sdasfasfasdf) # "The specifier name is a ``dotted name'' that may resolve either to # a module, a test case class, a TestSuite instance, a test method @@ -691,12 +903,13 @@ def test_loadTestsFromNames__unknown_name_relative_2(self): def test_loadTestsFromNames__relative_empty_name(self): loader = unittest.TestLoader() - try: - loader.loadTestsFromNames([''], unittest) - except AttributeError: - pass - else: - self.fail("Failed to raise ValueError") + suite = loader.loadTestsFromNames([''], unittest) + error, test = self.check_deferred_error(loader, list(suite)[0]) + expected = "has no attribute ''" + self.assertIn( + expected, error, + 'missing error string in %r' % error) + self.assertRaisesRegex(AttributeError, expected, getattr(test, '')) # "The specifier name is a ``dotted name'' that may resolve either to # a module, a test case class, a TestSuite instance, a test method @@ -710,14 +923,15 @@ def test_loadTestsFromNames__relative_malformed_name(self): loader = unittest.TestLoader() # XXX Should this raise AttributeError or ValueError? - try: - loader.loadTestsFromNames(['abc () //'], unittest) - except AttributeError: - pass - except ValueError: - pass - else: - self.fail("TestLoader.loadTestsFromNames failed to raise ValueError") + suite = loader.loadTestsFromNames(['abc () //'], unittest) + error, test = self.check_deferred_error(loader, list(suite)[0]) + expected = "module 'unittest' has no attribute 'abc () //'" + expected_regex = "module 'unittest' has no attribute 'abc \(\) //'" + self.assertIn( + expected, error, + 'missing error string in %r' % error) + self.assertRaisesRegex( + AttributeError, expected_regex, getattr(test, 'abc () //')) # "The method optionally resolves name relative to the given module" # @@ -835,12 +1049,13 @@ def test(self): m.testcase_1 = MyTestCase loader = unittest.TestLoader() - try: - loader.loadTestsFromNames(['testcase_1.testfoo'], m) - except AttributeError as e: - self.assertEqual(str(e), "type object 'MyTestCase' has no attribute 'testfoo'") - else: - self.fail("Failed to raise AttributeError") + suite = loader.loadTestsFromNames(['testcase_1.testfoo'], m) + error, test = self.check_deferred_error(loader, list(suite)[0]) + expected = "type object 'MyTestCase' has no attribute 'testfoo'" + self.assertIn( + expected, error, + 'missing error string in %r' % error) + self.assertRaisesRegex(AttributeError, expected, test.testfoo) # "The specifier name is a ``dotted name'' that may resolve ... to # ... a callable object which returns a ... TestSuite instance" diff --git a/Lib/unittest/test/test_program.py b/Lib/unittest/test/test_program.py index 32942980306f..725d67fdaf86 100644 --- a/Lib/unittest/test/test_program.py +++ b/Lib/unittest/test/test_program.py @@ -4,6 +4,7 @@ import sys from test import support import unittest +import unittest.test class Test_TestProgram(unittest.TestCase): diff --git a/Lib/unittest/test/test_runner.py b/Lib/unittest/test/test_runner.py index ef1c1af9f102..7c0bd51d7985 100644 --- a/Lib/unittest/test/test_runner.py +++ b/Lib/unittest/test/test_runner.py @@ -7,7 +7,8 @@ import unittest from unittest.case import _Outcome -from .support import LoggingResult, ResultWithNoStartTestRunStopTestRun +from unittest.test.support import (LoggingResult, + ResultWithNoStartTestRunStopTestRun) class TestCleanUp(unittest.TestCase): diff --git a/Lib/unittest/test/test_setups.py b/Lib/unittest/test/test_setups.py index 392f95efc071..2df703ed9348 100644 --- a/Lib/unittest/test/test_setups.py +++ b/Lib/unittest/test/test_setups.py @@ -111,7 +111,7 @@ def test_two(self): self.assertEqual(len(result.errors), 1) error, _ = result.errors[0] self.assertEqual(str(error), - 'setUpClass (%s.BrokenTest)' % __name__) + 'setUpClass (%s.%s)' % (__name__, BrokenTest.__qualname__)) def test_error_in_teardown_class(self): class Test(unittest.TestCase): @@ -144,7 +144,7 @@ def test_two(self): error, _ = result.errors[0] self.assertEqual(str(error), - 'tearDownClass (%s.Test)' % __name__) + 'tearDownClass (%s.%s)' % (__name__, Test.__qualname__)) def test_class_not_torndown_when_setup_fails(self): class Test(unittest.TestCase): @@ -414,7 +414,8 @@ def test_two(self): self.assertEqual(len(result.errors), 0) self.assertEqual(len(result.skipped), 1) skipped = result.skipped[0][0] - self.assertEqual(str(skipped), 'setUpClass (%s.Test)' % __name__) + self.assertEqual(str(skipped), + 'setUpClass (%s.%s)' % (__name__, Test.__qualname__)) def test_skiptest_in_setupmodule(self): class Test(unittest.TestCase): diff --git a/Lib/unittest/test/test_skipping.py b/Lib/unittest/test/test_skipping.py index e18caa48ba4d..807510f15f3e 100644 --- a/Lib/unittest/test/test_skipping.py +++ b/Lib/unittest/test/test_skipping.py @@ -1,6 +1,6 @@ import unittest -from .support import LoggingResult +from unittest.test.support import LoggingResult class Test_TestSkipping(unittest.TestCase): @@ -158,7 +158,7 @@ def test_die(self): ['startTest', 'addUnexpectedSuccess', 'stopTest']) self.assertFalse(result.failures) self.assertEqual(result.unexpectedSuccesses, [test]) - self.assertTrue(result.wasSuccessful()) + self.assertFalse(result.wasSuccessful()) def test_unexpected_success_subtests(self): # Success in all subtests counts as the unexpected success of @@ -182,7 +182,7 @@ def test_die(self): 'addUnexpectedSuccess', 'stopTest']) self.assertFalse(result.failures) self.assertEqual(result.unexpectedSuccesses, [test]) - self.assertTrue(result.wasSuccessful()) + self.assertFalse(result.wasSuccessful()) def test_skip_doesnt_run_setup(self): class Foo(unittest.TestCase): diff --git a/Lib/unittest/test/test_suite.py b/Lib/unittest/test/test_suite.py index 54cec6ecbab2..0551a1699672 100644 --- a/Lib/unittest/test/test_suite.py +++ b/Lib/unittest/test/test_suite.py @@ -3,7 +3,7 @@ import gc import sys import weakref -from .support import LoggingResult, TestEquality +from unittest.test.support import LoggingResult, TestEquality ### Support code for Test_TestSuite @@ -51,6 +51,9 @@ def test_init__tests_optional(self): suite = unittest.TestSuite() self.assertEqual(suite.countTestCases(), 0) + # countTestCases() still works after tests are run + suite.run(unittest.TestResult()) + self.assertEqual(suite.countTestCases(), 0) # "class TestSuite([tests])" # ... @@ -63,6 +66,9 @@ def test_init__empty_tests(self): suite = unittest.TestSuite([]) self.assertEqual(suite.countTestCases(), 0) + # countTestCases() still works after tests are run + suite.run(unittest.TestResult()) + self.assertEqual(suite.countTestCases(), 0) # "class TestSuite([tests])" # ... @@ -84,6 +90,14 @@ def tests(): suite_3 = unittest.TestSuite(set(suite_1)) self.assertEqual(suite_3.countTestCases(), 2) + # countTestCases() still works after tests are run + suite_1.run(unittest.TestResult()) + self.assertEqual(suite_1.countTestCases(), 2) + suite_2.run(unittest.TestResult()) + self.assertEqual(suite_2.countTestCases(), 2) + suite_3.run(unittest.TestResult()) + self.assertEqual(suite_3.countTestCases(), 2) + # "class TestSuite([tests])" # ... # "If tests is given, it must be an iterable of individual test cases @@ -99,6 +113,9 @@ def tests(): suite = unittest.TestSuite(tests()) self.assertEqual(suite.countTestCases(), 2) + # countTestCases() still works after tests are run + suite.run(unittest.TestResult()) + self.assertEqual(suite.countTestCases(), 2) ################################################################ ### /Tests for TestSuite.__init__ @@ -145,6 +162,9 @@ def test_countTestCases_simple(self): suite = unittest.TestSuite((test1, test2)) self.assertEqual(suite.countTestCases(), 2) + # countTestCases() still works after tests are run + suite.run(unittest.TestResult()) + self.assertEqual(suite.countTestCases(), 2) # "Return the number of tests represented by the this test object. # ...this method is also implemented by the TestSuite class, which can @@ -162,6 +182,10 @@ def test2(self): pass parent = unittest.TestSuite((test3, child, Test1('test1'))) self.assertEqual(parent.countTestCases(), 4) + # countTestCases() still works after tests are run + parent.run(unittest.TestResult()) + self.assertEqual(parent.countTestCases(), 4) + self.assertEqual(child.countTestCases(), 2) # "Run the tests associated with this suite, collecting the result into # the test result object passed as result." @@ -220,6 +244,9 @@ def test(self): pass self.assertEqual(suite.countTestCases(), 1) self.assertEqual(list(suite), [test]) + # countTestCases() still works after tests are run + suite.run(unittest.TestResult()) + self.assertEqual(suite.countTestCases(), 1) # "Add a ... TestSuite to the suite" def test_addTest__TestSuite(self): @@ -233,6 +260,9 @@ def test(self): pass self.assertEqual(suite.countTestCases(), 1) self.assertEqual(list(suite), [suite_2]) + # countTestCases() still works after tests are run + suite.run(unittest.TestResult()) + self.assertEqual(suite.countTestCases(), 1) # "Add all the tests from an iterable of TestCase and TestSuite # instances to this test suite." @@ -392,6 +422,7 @@ def tearDownModule(): self.assertEqual(len(result.errors), 1) self.assertEqual(len(result.failures), 0) self.assertEqual(result.testsRun, 2) + self.assertEqual(suite.countTestCases(), 2) def test_overriding_call(self): diff --git a/Lib/unittest/test/testmock/testmagicmethods.py b/Lib/unittest/test/testmock/testmagicmethods.py index 5ff158dd12a3..cc0e707ece65 100644 --- a/Lib/unittest/test/testmock/testmagicmethods.py +++ b/Lib/unittest/test/testmock/testmagicmethods.py @@ -126,6 +126,31 @@ def iadd(mock): self.assertEqual(7 + mock, mock) self.assertEqual(mock.value, 16) + def test_division(self): + original = mock = Mock() + mock.value = 32 + self.assertRaises(TypeError, lambda: mock / 2) + + def truediv(self, other): + mock.value /= other + return self + mock.__truediv__ = truediv + self.assertEqual(mock / 2, mock) + self.assertEqual(mock.value, 16) + + del mock.__truediv__ + def itruediv(mock): + mock /= 4 + self.assertRaises(TypeError, itruediv, mock) + mock.__itruediv__ = truediv + mock /= 8 + self.assertEqual(mock, original) + self.assertEqual(mock.value, 2) + + self.assertRaises(TypeError, lambda: 8 / mock) + mock.__rtruediv__ = truediv + self.assertEqual(0.5 / mock, mock) + self.assertEqual(mock.value, 4) def test_hash(self): mock = Mock() diff --git a/Lib/unittest/test/testmock/testmock.py b/Lib/unittest/test/testmock/testmock.py index 20cc6541e66b..3a104cb2b9d6 100644 --- a/Lib/unittest/test/testmock/testmock.py +++ b/Lib/unittest/test/testmock/testmock.py @@ -154,6 +154,24 @@ def side_effect(): mock = Mock(side_effect=side_effect, return_value=sentinel.RETURN) self.assertEqual(mock(), sentinel.RETURN) + def test_autospec_side_effect(self): + # Test for issue17826 + results = [1, 2, 3] + def effect(): + return results.pop() + def f(): + pass + + mock = create_autospec(f) + mock.side_effect = [1, 2, 3] + self.assertEqual([mock(), mock(), mock()], [1, 2, 3], + "side effect not used correctly in create_autospec") + # Test where side effect is a callable + results = [1, 2, 3] + mock = create_autospec(f) + mock.side_effect = effect + self.assertEqual([mock(), mock(), mock()], [3, 2, 1], + "callable side effect not used correctly") @unittest.skipUnless('java' in sys.platform, 'This test only applies to Jython') @@ -1164,6 +1182,46 @@ def f(a, b): func.mock_calls, [call(1, 2), call(3, 4)] ) + #Issue21222 + def test_create_autospec_with_name(self): + m = mock.create_autospec(object(), name='sweet_func') + self.assertIn('sweet_func', repr(m)) + + #Issue21238 + def test_mock_unsafe(self): + m = Mock() + with self.assertRaises(AttributeError): + m.assert_foo_call() + with self.assertRaises(AttributeError): + m.assret_foo_call() + m = Mock(unsafe=True) + m.assert_foo_call() + m.assret_foo_call() + + #Issue21262 + def test_assert_not_called(self): + m = Mock() + m.hello.assert_not_called() + m.hello() + with self.assertRaises(AssertionError): + m.hello.assert_not_called() + + #Issue21256 printout of keyword args should be in deterministic order + def test_sorted_call_signature(self): + m = Mock() + m.hello(name='hello', daddy='hero') + text = "call(daddy='hero', name='hello')" + self.assertEqual(repr(m.hello.call_args), text) + + #Issue21270 overrides tuple methods for mock.call objects + def test_override_tuple_methods(self): + c = call.count() + i = call.index(132,'hello') + m = Mock() + m.count() + m.index(132,"hello") + self.assertEqual(m.method_calls[0], c) + self.assertEqual(m.method_calls[1], i) def test_mock_add_spec(self): class _One(object): diff --git a/Lib/unittest/test/testmock/testpatch.py b/Lib/unittest/test/testmock/testpatch.py index c1bc34fa8c92..28fe86b0de99 100644 --- a/Lib/unittest/test/testmock/testpatch.py +++ b/Lib/unittest/test/testmock/testpatch.py @@ -12,7 +12,7 @@ from unittest.mock import ( NonCallableMock, CallableMixin, patch, sentinel, MagicMock, Mock, NonCallableMagicMock, patch, _patch, - DEFAULT, call, _get_target + DEFAULT, call, _get_target, _patch ) @@ -377,7 +377,7 @@ def test(): def test_patchobject_wont_create_by_default(self): try: - @patch.object(SomeClass, 'frooble', sentinel.Frooble) + @patch.object(SomeClass, 'ord', sentinel.Frooble) def test(): self.fail('Patching non existent attributes should fail') @@ -386,7 +386,27 @@ def test(): pass else: self.fail('Patching non existent attributes should fail') - self.assertFalse(hasattr(SomeClass, 'frooble')) + self.assertFalse(hasattr(SomeClass, 'ord')) + + + def test_patch_builtins_without_create(self): + @patch(__name__+'.ord') + def test_ord(mock_ord): + mock_ord.return_value = 101 + return ord('c') + + @patch(__name__+'.open') + def test_open(mock_open): + m = mock_open.return_value + m.read.return_value = 'abcd' + + fobj = open('doesnotexists.txt') + data = fobj.read() + fobj.close() + return data + + self.assertEqual(test_ord(), 101) + self.assertEqual(test_open(), 'abcd') def test_patch_with_static_methods(self): @@ -1779,6 +1799,23 @@ def patched(mock_path): patched() self.assertIs(os.path, path) + def test_stopall_lifo(self): + stopped = [] + class thing(object): + one = two = three = None + + def get_patch(attribute): + class mypatch(_patch): + def stop(self): + stopped.append(attribute) + return super(mypatch, self).stop() + return mypatch(lambda: thing, attribute, None, None, + False, None, None, None, {}) + [get_patch(val).start() for val in ("one", "two", "three")] + patch.stopall() + + self.assertEqual(stopped, ["three", "two", "one"]) + if __name__ == '__main__': unittest.main() diff --git a/Lib/unittest/util.py b/Lib/unittest/util.py index aee498fd0be1..45485dcb0df2 100644 --- a/Lib/unittest/util.py +++ b/Lib/unittest/util.py @@ -52,7 +52,7 @@ def safe_repr(obj, short=False): return result[:_MAX_LENGTH] + ' [truncated]...' def strclass(cls): - return "%s.%s" % (cls.__module__, cls.__name__) + return "%s.%s" % (cls.__module__, cls.__qualname__) def sorted_list_difference(expected, actual): """Finds elements in only one or the other of two, sorted input lists. diff --git a/Lib/urllib/parse.py b/Lib/urllib/parse.py index 5328b9d3298f..821dae62e32d 100644 --- a/Lib/urllib/parse.py +++ b/Lib/urllib/parse.py @@ -182,10 +182,10 @@ def _hostinfo(self): _, have_open_br, bracketed = hostinfo.partition('[') if have_open_br: hostname, _, port = bracketed.partition(']') - _, have_port, port = port.partition(':') + _, _, port = port.partition(':') else: - hostname, have_port, port = hostinfo.partition(':') - if not have_port: + hostname, _, port = hostinfo.partition(':') + if not port: port = None return hostname, port @@ -212,10 +212,10 @@ def _hostinfo(self): _, have_open_br, bracketed = hostinfo.partition(b'[') if have_open_br: hostname, _, port = bracketed.partition(b']') - _, have_port, port = port.partition(b':') + _, _, port = port.partition(b':') else: - hostname, have_port, port = hostinfo.partition(b':') - if not have_port: + hostname, _, port = hostinfo.partition(b':') + if not port: port = None return hostname, port @@ -409,11 +409,13 @@ def urljoin(base, url, allow_fragments=True): return url if not url: return base + base, url, _coerce_result = _coerce_args(base, url) bscheme, bnetloc, bpath, bparams, bquery, bfragment = \ urlparse(base, '', allow_fragments) scheme, netloc, path, params, query, fragment = \ urlparse(url, bscheme, allow_fragments) + if scheme != bscheme or scheme not in uses_relative: return _coerce_result(url) if scheme in uses_netloc: @@ -421,9 +423,7 @@ def urljoin(base, url, allow_fragments=True): return _coerce_result(urlunparse((scheme, netloc, path, params, query, fragment))) netloc = bnetloc - if path[:1] == '/': - return _coerce_result(urlunparse((scheme, netloc, path, - params, query, fragment))) + if not path and not params: path = bpath params = bparams @@ -431,29 +431,46 @@ def urljoin(base, url, allow_fragments=True): query = bquery return _coerce_result(urlunparse((scheme, netloc, path, params, query, fragment))) - segments = bpath.split('/')[:-1] + path.split('/') - # XXX The stuff below is bogus in various ways... - if segments[-1] == '.': - segments[-1] = '' - while '.' in segments: - segments.remove('.') - while 1: - i = 1 - n = len(segments) - 1 - while i < n: - if (segments[i] == '..' - and segments[i-1] not in ('', '..')): - del segments[i-1:i+1] - break - i = i+1 + + base_parts = bpath.split('/') + if base_parts[-1] != '': + # the last item is not a directory, so will not be taken into account + # in resolving the relative path + del base_parts[-1] + + # for rfc3986, ignore all base path should the first character be root. + if path[:1] == '/': + segments = path.split('/') + else: + segments = base_parts + path.split('/') + # filter out elements that would cause redundant slashes on re-joining + # the resolved_path + segments = segments[0:1] + [ + s for s in segments[1:-1] if len(s) > 0] + segments[-1:] + + resolved_path = [] + + for seg in segments: + if seg == '..': + try: + resolved_path.pop() + except IndexError: + # ignore any .. segments that would otherwise cause an IndexError + # when popped from resolved_path if resolving for rfc3986 + pass + elif seg == '.': + continue else: - break - if segments == ['', '..']: - segments[-1] = '' - elif len(segments) >= 2 and segments[-1] == '..': - segments[-2:] = [''] - return _coerce_result(urlunparse((scheme, netloc, '/'.join(segments), - params, query, fragment))) + resolved_path.append(seg) + + if segments[-1] in ('.', '..'): + # do some post-processing here. if the last segment was a relative dir, + # then we need to append the trailing '/' + resolved_path.append('') + + return _coerce_result(urlunparse((scheme, netloc, '/'.join( + resolved_path) or '/', params, query, fragment))) + def urldefrag(url): """Removes any existing fragment from URL. @@ -472,8 +489,7 @@ def urldefrag(url): return _coerce_result(DefragResult(defrag, frag)) _hexdig = '0123456789ABCDEFabcdef' -_hextobyte = {(a + b).encode(): bytes([int(a + b, 16)]) - for a in _hexdig for b in _hexdig} +_hextobyte = None def unquote_to_bytes(string): """unquote_to_bytes('abc%20def') -> b'abc def'.""" @@ -490,6 +506,12 @@ def unquote_to_bytes(string): return string res = [bits[0]] append = res.append + # Delay the initialization of the table to not waste memory + # if the function is never called + global _hextobyte + if _hextobyte is None: + _hextobyte = {(a + b).encode(): bytes([int(a + b, 16)]) + for a in _hexdig for b in _hexdig} for item in bits[1:]: try: append(_hextobyte[item[:2]]) @@ -636,7 +658,7 @@ def __init__(self, safe): def __repr__(self): # Without this, will just display as a defaultdict - return "" % dict(self) + return "<%s %r>" % (self.__class__.__name__, dict(self)) def __missing__(self, b): # Handle a cache miss. Store quoted string in cache and return. @@ -665,8 +687,8 @@ def quote(string, safe='/', encoding=None, errors=None): called on a path where the existing slash characters are used as reserved characters. - string and safe may be either str or bytes objects. encoding must - not be specified if string is a str. + string and safe may be either str or bytes objects. encoding and errors + must not be specified if string is a bytes object. The optional encoding and errors parameters specify how to deal with non-ASCII characters, as accepted by the str.encode method. @@ -738,8 +760,9 @@ def urlencode(query, doseq=False, safe='', encoding=None, errors=None): input. The components of a query arg may each be either a string or a bytes type. - When a component is a string, the safe, encoding and error parameters are - sent to the quote_plus function for encoding. + + The safe, encoding, and errors parameters are passed down to quote_plus() + (encoding and errors only if a component is a str). """ if hasattr(query, "items"): @@ -898,10 +921,13 @@ def splitport(host): """splitport('host:port') --> 'host', 'port'.""" global _portprog if _portprog is None: - _portprog = re.compile('^(.*):([0-9]+)$') + _portprog = re.compile('^(.*):([0-9]*)$') match = _portprog.match(host) - if match: return match.group(1, 2) + if match: + host, port = match.groups() + if port: + return host, port return host, None _nportprog = None @@ -917,12 +943,12 @@ def splitnport(host, defport=-1): match = _nportprog.match(host) if match: host, port = match.group(1, 2) - try: - if not port: raise ValueError("no digits") - nport = int(port) - except ValueError: - nport = None - return host, nport + if port: + try: + nport = int(port) + except ValueError: + nport = None + return host, nport return host, defport _queryprog = None diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py index 5995cbe24f0d..3ba7c01eb00a 100644 --- a/Lib/urllib/request.py +++ b/Lib/urllib/request.py @@ -136,15 +136,23 @@ _opener = None def urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, - *, cafile=None, capath=None, cadefault=False): + *, cafile=None, capath=None, cadefault=False, context=None): global _opener if cafile or capath or cadefault: + if context is not None: + raise ValueError( + "You can't pass both context and any of cafile, capath, and " + "cadefault" + ) if not _have_ssl: raise ValueError('SSL support not available') - context = ssl._create_stdlib_context(cert_reqs=ssl.CERT_REQUIRED, + context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH, cafile=cafile, capath=capath) - https_handler = HTTPSHandler(context=context, check_hostname=True) + https_handler = HTTPSHandler(context=context) + opener = build_opener(https_handler) + elif context: + https_handler = HTTPSHandler(context=context) opener = build_opener(https_handler) elif _opener is None: _opener = opener = build_opener() @@ -511,9 +519,6 @@ def build_opener(*handlers): If any of the handlers passed as arguments are subclasses of the default handlers, the default handlers will not be used. """ - def isclass(obj): - return isinstance(obj, type) or hasattr(obj, "__bases__") - opener = OpenerDirector() default_classes = [ProxyHandler, UnknownHandler, HTTPHandler, HTTPDefaultErrorHandler, HTTPRedirectHandler, @@ -524,7 +529,7 @@ def isclass(obj): skip = set() for klass in default_classes: for check in handlers: - if isclass(check): + if isinstance(check, type): if issubclass(check, klass): skip.add(klass) elif isinstance(check, klass): @@ -536,7 +541,7 @@ def isclass(obj): opener.add_handler(klass()) for h in handlers: - if isclass(h): + if isinstance(h, type): h = h() opener.add_handler(h) return opener @@ -690,50 +695,7 @@ def _parse_proxy(proxy): If a URL is supplied, it must have an authority (host:port) component. According to RFC 3986, having an authority component means the URL must - have two slashes after the scheme: - - >>> _parse_proxy('file:/ftp.example.com/') - Traceback (most recent call last): - ValueError: proxy URL with no authority: 'file:/ftp.example.com/' - - The first three items of the returned tuple may be None. - - Examples of authority parsing: - - >>> _parse_proxy('proxy.example.com') - (None, None, None, 'proxy.example.com') - >>> _parse_proxy('proxy.example.com:3128') - (None, None, None, 'proxy.example.com:3128') - - The authority component may optionally include userinfo (assumed to be - username:password): - - >>> _parse_proxy('joe:password@proxy.example.com') - (None, 'joe', 'password', 'proxy.example.com') - >>> _parse_proxy('joe:password@proxy.example.com:3128') - (None, 'joe', 'password', 'proxy.example.com:3128') - - Same examples, but with URLs instead: - - >>> _parse_proxy('http://proxy.example.com/') - ('http', None, None, 'proxy.example.com') - >>> _parse_proxy('http://proxy.example.com:3128/') - ('http', None, None, 'proxy.example.com:3128') - >>> _parse_proxy('http://joe:password@proxy.example.com/') - ('http', 'joe', 'password', 'proxy.example.com') - >>> _parse_proxy('http://joe:password@proxy.example.com:3128') - ('http', 'joe', 'password', 'proxy.example.com:3128') - - Everything after the authority is ignored: - - >>> _parse_proxy('ftp://joe:password@proxy.example.com/rubbish:3128') - ('ftp', 'joe', 'password', 'proxy.example.com') - - Test for no trailing '/' case: - - >>> _parse_proxy('http://joe:password@proxy.example.com') - ('http', 'joe', 'password', 'proxy.example.com') - + have two slashes after the scheme. """ scheme, r_scheme = splittype(proxy) if not r_scheme.startswith("/"): @@ -892,10 +854,6 @@ def __init__(self, password_mgr=None): password_mgr = HTTPPasswordMgr() self.passwd = password_mgr self.add_password = self.passwd.add_password - self.retried = 0 - - def reset_retry_count(self): - self.retried = 0 def http_error_auth_reqed(self, authreq, host, req, headers): # host may be an authority (without userinfo) or a URL with an @@ -903,13 +861,6 @@ def http_error_auth_reqed(self, authreq, host, req, headers): # XXX could be multiple headers authreq = headers.get(authreq, None) - if self.retried > 5: - # retry sending the username:password 5 times before failing. - raise HTTPError(req.get_full_url(), 401, "basic auth failed", - headers, None) - else: - self.retried += 1 - if authreq: scheme = authreq.split()[0] if scheme.lower() != 'basic': @@ -924,17 +875,14 @@ def http_error_auth_reqed(self, authreq, host, req, headers): warnings.warn("Basic Auth Realm was unquoted", UserWarning, 2) if scheme.lower() == 'basic': - response = self.retry_http_basic_auth(host, req, realm) - if response and response.code != 401: - self.retried = 0 - return response + return self.retry_http_basic_auth(host, req, realm) def retry_http_basic_auth(self, host, req, realm): user, pw = self.passwd.find_user_password(realm, host) if pw is not None: raw = "%s:%s" % (user, pw) auth = "Basic " + base64.b64encode(raw.encode()).decode("ascii") - if req.headers.get(self.auth_header, None) == auth: + if req.get_header(self.auth_header, None) == auth: return None req.add_unredirected_header(self.auth_header, auth) return self.parent.open(req, timeout=req.timeout) @@ -950,7 +898,6 @@ def http_error_401(self, req, fp, code, msg, headers): url = req.full_url response = self.http_error_auth_reqed('www-authenticate', url, req, headers) - self.reset_retry_count() return response @@ -966,10 +913,24 @@ def http_error_407(self, req, fp, code, msg, headers): authority = req.host response = self.http_error_auth_reqed('proxy-authenticate', authority, req, headers) - self.reset_retry_count() return response +class HTTPBasicPriorAuthHandler(HTTPBasicAuthHandler): + handler_order = 400 + + def http_request(self, req): + if not req.has_header('Authorization'): + user, passwd = self.passwd.find_user_password(None, req.host) + credentials = '{0}:{1}'.format(user, passwd).encode() + auth_str = base64.standard_b64encode(credentials).decode() + req.add_unredirected_header('Authorization', + 'Basic {}'.format(auth_str.strip())) + return req + + https_request = http_request + + # Return n random bytes. _randombytes = os.urandom @@ -1232,18 +1193,21 @@ def do_open(self, http_class, req, **http_conn_args): h.set_tunnel(req._tunnel_host, headers=tunnel_headers) try: - h.request(req.get_method(), req.selector, req.data, headers) - except OSError as err: # timeout error - h.close() - raise URLError(err) - else: + try: + h.request(req.get_method(), req.selector, req.data, headers) + except OSError as err: # timeout error + raise URLError(err) r = h.getresponse() - # If the server does not send us a 'Connection: close' header, - # HTTPConnection assumes the socket should be left open. Manually - # mark the socket to be closed when this response object goes away. - if h.sock: - h.sock.close() - h.sock = None + except: + h.close() + raise + + # If the server does not send us a 'Connection: close' header, + # HTTPConnection assumes the socket should be left open. Manually + # mark the socket to be closed when this response object goes away. + if h.sock: + h.sock.close() + h.sock = None r.url = req.get_full_url() # This line replaces the .msg attribute of the HTTPResponse @@ -1361,7 +1325,7 @@ def file_open(self, req): url = req.selector if url[:2] == '//' and url[2:3] != '/' and (req.host and req.host != 'localhost'): - if not req.host is self.get_names(): + if not req.host in self.get_names(): raise URLError("file:// scheme is supported only on localhost") else: return self.open_local_file(req) @@ -1957,7 +1921,7 @@ def open_ftp(self, url): # XXX thread unsafe! if len(self.ftpcache) > MAXFTPCACHE: # Prune the cache, rather arbitrarily - for k in self.ftpcache.keys(): + for k in list(self.ftpcache): if k != key: v = self.ftpcache[k] del self.ftpcache[k] diff --git a/Lib/urllib/response.py b/Lib/urllib/response.py index 1cf1d1aaeda2..4a143b03e676 100644 --- a/Lib/urllib/response.py +++ b/Lib/urllib/response.py @@ -6,60 +6,39 @@ headers and a geturl() method that returns the url. """ -class addbase(object): - """Base class for addinfo and addclosehook.""" +import tempfile + +__all__ = ['addbase', 'addclosehook', 'addinfo', 'addinfourl'] + + +class addbase(tempfile._TemporaryFileWrapper): + """Base class for addinfo and addclosehook. Is a good idea for garbage collection.""" # XXX Add a method to expose the timeout on the underlying socket? def __init__(self, fp): - # TODO(jhylton): Is there a better way to delegate using io? + super(addbase, self).__init__(fp, '', delete=False) + # Keep reference around as this was part of the original API. self.fp = fp - self.read = self.fp.read - self.readline = self.fp.readline - # TODO(jhylton): Make sure an object with readlines() is also iterable - if hasattr(self.fp, "readlines"): - self.readlines = self.fp.readlines - if hasattr(self.fp, "fileno"): - self.fileno = self.fp.fileno - else: - self.fileno = lambda: None - - def __iter__(self): - # Assigning `__iter__` to the instance doesn't work as intended - # because the iter builtin does something like `cls.__iter__(obj)` - # and thus fails to find the _bound_ method `obj.__iter__`. - # Returning just `self.fp` works for built-in file objects but - # might not work for general file-like objects. - return iter(self.fp) def __repr__(self): return '<%s at %r whose fp = %r>' % (self.__class__.__name__, - id(self), self.fp) - - def close(self): - if self.fp: - self.fp.close() - self.fp = None - self.read = None - self.readline = None - self.readlines = None - self.fileno = None - self.__iter__ = None - self.__next__ = None + id(self), self.file) def __enter__(self): - if self.fp is None: + if self.fp.closed: raise ValueError("I/O operation on closed file") return self def __exit__(self, type, value, traceback): self.close() + class addclosehook(addbase): """Class to add a close hook to an open file.""" def __init__(self, fp, closehook, *hookargs): - addbase.__init__(self, fp) + super(addclosehook, self).__init__(fp) self.closehook = closehook self.hookargs = hookargs @@ -68,30 +47,28 @@ def close(self): self.closehook(*self.hookargs) self.closehook = None self.hookargs = None - addbase.close(self) + super(addclosehook, self).close() + class addinfo(addbase): """class to add an info() method to an open file.""" def __init__(self, fp, headers): - addbase.__init__(self, fp) + super(addinfo, self).__init__(fp) self.headers = headers def info(self): return self.headers -class addinfourl(addbase): + +class addinfourl(addinfo): """class to add info() and geturl() methods to an open file.""" def __init__(self, fp, headers, url, code=None): - addbase.__init__(self, fp) - self.headers = headers + super(addinfourl, self).__init__(fp, headers) self.url = url self.code = code - def info(self): - return self.headers - def getcode(self): return self.code diff --git a/Lib/urllib/robotparser.py b/Lib/urllib/robotparser.py index 978ba58d84a6..4fbb0cb995ff 100644 --- a/Lib/urllib/robotparser.py +++ b/Lib/urllib/robotparser.py @@ -7,7 +7,7 @@ 2) PSF license for Python 2.2 The robots.txt Exclusion Protocol is implemented as specified in - http://info.webcrawler.com/mak/projects/robots/norobots-rfc.html + http://www.robotstxt.org/norobots-rfc.txt """ import urllib.parse, urllib.request @@ -57,7 +57,7 @@ def read(self): except urllib.error.HTTPError as err: if err.code in (401, 403): self.disallow_all = True - elif err.code >= 400: + elif err.code >= 400 and err.code < 500: self.allow_all = True else: raw = f.read() @@ -85,6 +85,7 @@ def parse(self, lines): state = 0 entry = Entry() + self.modified() for line in lines: if not line: if state == 1: @@ -129,6 +130,12 @@ def can_fetch(self, useragent, url): return False if self.allow_all: return True + # Until the robots.txt file has been read or found not + # to exist, we must assume that no url is allowable. + # This prevents false positives when a user erronenously + # calls can_fetch() before calling read(). + if not self.last_checked: + return False # search for given user agent matches # the first match counts parsed_url = urllib.parse.urlparse(urllib.parse.unquote(url)) @@ -165,7 +172,7 @@ def applies_to(self, filename): return self.path == "*" or filename.startswith(self.path) def __str__(self): - return (self.allowance and "Allow" or "Disallow") + ": " + self.path + return ("Allow" if self.allowance else "Disallow") + ": " + self.path class Entry: diff --git a/Lib/uuid.py b/Lib/uuid.py index 385fb9b0876f..e627573969cb 100644 --- a/Lib/uuid.py +++ b/Lib/uuid.py @@ -139,10 +139,8 @@ def __init__(self, hex=None, bytes=None, bytes_le=None, fields=None, if bytes_le is not None: if len(bytes_le) != 16: raise ValueError('bytes_le is not a 16-char string') - bytes = (bytes_(reversed(bytes_le[0:4])) + - bytes_(reversed(bytes_le[4:6])) + - bytes_(reversed(bytes_le[6:8])) + - bytes_le[8:]) + bytes = (bytes_le[4-1::-1] + bytes_le[6-1:4-1:-1] + + bytes_le[8-1:6-1:-1] + bytes_le[8:]) if bytes is not None: if len(bytes) != 16: raise ValueError('bytes is not a 16-char string') @@ -187,11 +185,6 @@ def __eq__(self, other): return self.int == other.int return NotImplemented - def __ne__(self, other): - if isinstance(other, UUID): - return self.int != other.int - return NotImplemented - # Q. What's the value of being able to sort UUIDs? # A. Use them as keys in a B-Tree or similar mapping. @@ -222,7 +215,7 @@ def __int__(self): return self.int def __repr__(self): - return 'UUID(%r)' % str(self) + return '%s(%r)' % (self.__class__.__name__, str(self)) def __setattr__(self, name, value): raise TypeError('UUID objects are immutable') @@ -234,17 +227,12 @@ def __str__(self): @property def bytes(self): - bytes = bytearray() - for shift in range(0, 128, 8): - bytes.insert(0, (self.int >> shift) & 0xff) - return bytes_(bytes) + return self.int.to_bytes(16, 'big') @property def bytes_le(self): bytes = self.bytes - return (bytes_(reversed(bytes[0:4])) + - bytes_(reversed(bytes[4:6])) + - bytes_(reversed(bytes[6:8])) + + return (bytes[4-1::-1] + bytes[6-1:4-1:-1] + bytes[8-1:6-1:-1] + bytes[8:]) @property @@ -311,59 +299,106 @@ def version(self): if self.variant == RFC_4122: return int((self.int >> 76) & 0xf) -def _find_mac(command, args, hw_identifiers, get_index): - import os - for dir in ['', '/sbin/', '/usr/sbin']: - executable = os.path.join(dir, command) - if not os.path.exists(executable): - continue +def _popen(command, *args): + import os, shutil, subprocess + executable = shutil.which(command) + if executable is None: + path = os.pathsep.join(('/sbin', '/usr/sbin')) + executable = shutil.which(command, path=path) + if executable is None: + return None + # LC_ALL=C to ensure English output, stderr=DEVNULL to prevent output + # on stderr (Note: we don't have an example where the words we search + # for are actually localized, but in theory some system could do so.) + env = dict(os.environ) + env['LC_ALL'] = 'C' + proc = subprocess.Popen((executable,) + args, + stdout=subprocess.PIPE, + stderr=subprocess.DEVNULL, + env=env) + return proc - try: - # LC_ALL to get English output, 2>/dev/null to - # prevent output on stderr - cmd = 'LC_ALL=C %s %s 2>/dev/null' % (executable, args) - with os.popen(cmd) as pipe: - for line in pipe: - words = line.lower().split() - for i in range(len(words)): - if words[i] in hw_identifiers: - try: - return int( - words[get_index(i)].replace(':', ''), 16) - except (ValueError, IndexError): - # Virtual interfaces, such as those provided by - # VPNs, do not have a colon-delimited MAC address - # as expected, but a 16-byte HWAddr separated by - # dashes. These should be ignored in favor of a - # real MAC address - pass - except OSError: - continue - return None +def _find_mac(command, args, hw_identifiers, get_index): + try: + proc = _popen(command, *args.split()) + if not proc: + return + with proc: + for line in proc.stdout: + words = line.lower().rstrip().split() + for i in range(len(words)): + if words[i] in hw_identifiers: + try: + word = words[get_index(i)] + mac = int(word.replace(b':', b''), 16) + if mac: + return mac + except (ValueError, IndexError): + # Virtual interfaces, such as those provided by + # VPNs, do not have a colon-delimited MAC address + # as expected, but a 16-byte HWAddr separated by + # dashes. These should be ignored in favor of a + # real MAC address + pass + except OSError: + pass def _ifconfig_getnode(): """Get the hardware address on Unix by running ifconfig.""" - # This works on Linux ('' or '-a'), Tru64 ('-av'), but not all Unixes. for args in ('', '-a', '-av'): - mac = _find_mac('ifconfig', args, ['hwaddr', 'ether'], lambda i: i+1) + mac = _find_mac('ifconfig', args, [b'hwaddr', b'ether'], lambda i: i+1) if mac: return mac - import socket - ip_addr = socket.gethostbyname(socket.gethostname()) - - # Try getting the MAC addr from arp based on our IP address (Solaris). - mac = _find_mac('arp', '-an', [ip_addr], lambda i: -1) +def _ip_getnode(): + """Get the hardware address on Unix by running ip.""" + # This works on Linux with iproute2. + mac = _find_mac('ip', 'link list', [b'link/ether'], lambda i: i+1) if mac: return mac +def _arp_getnode(): + """Get the hardware address on Unix by running arp.""" + import os, socket + try: + ip_addr = socket.gethostbyname(socket.gethostname()) + except OSError: + return None + + # Try getting the MAC addr from arp based on our IP address (Solaris). + return _find_mac('arp', '-an', [os.fsencode(ip_addr)], lambda i: -1) + +def _lanscan_getnode(): + """Get the hardware address on Unix by running lanscan.""" # This might work on HP-UX. - mac = _find_mac('lanscan', '-ai', ['lan0'], lambda i: 0) - if mac: - return mac + return _find_mac('lanscan', '-ai', [b'lan0'], lambda i: 0) - return None +def _netstat_getnode(): + """Get the hardware address on Unix by running netstat.""" + # This might work on AIX, Tru64 UNIX and presumably on IRIX. + try: + proc = _popen('netstat', '-ia') + if not proc: + return + with proc: + words = proc.stdout.readline().rstrip().split() + try: + i = words.index(b'Address') + except ValueError: + return + for line in proc.stdout: + try: + words = line.rstrip().split() + word = words[i] + if len(word) == 17 and word.count(b':') == 5: + mac = int(word.replace(b':', b''), 16) + if mac: + return mac + except (ValueError, IndexError): + pass + except OSError: + pass def _ipconfig_getnode(): """Get the hardware address on Windows by running ipconfig.exe.""" @@ -381,13 +416,11 @@ def _ipconfig_getnode(): pipe = os.popen(os.path.join(dir, 'ipconfig') + ' /all') except OSError: continue - else: + with pipe: for line in pipe: value = line.split(':')[-1].strip().lower() if re.match('([0-9a-f][0-9a-f]-){5}[0-9a-f][0-9a-f]', value): return int(value.replace('-', ''), 16) - finally: - pipe.close() def _netbios_getnode(): """Get the hardware address on Windows using NetBIOS calls. @@ -414,9 +447,10 @@ def _netbios_getnode(): if win32wnet.Netbios(ncb) != 0: continue status._unpack() - bytes = status.adapter_address - return ((bytes[0]<<40) + (bytes[1]<<32) + (bytes[2]<<24) + - (bytes[3]<<16) + (bytes[4]<<8) + bytes[5]) + bytes = status.adapter_address[:6] + if len(bytes) != 6: + continue + return int.from_bytes(bytes, 'big') # Thanks to Thomas Heller for ctypes and for his help with its use here. @@ -485,7 +519,7 @@ def _windll_getnode(): def _random_getnode(): """Get a random node ID, with eighth bit set as suggested by RFC 4122.""" import random - return random.randrange(0, 1<<48) | 0x010000000000 + return random.getrandbits(48) | 0x010000000000 _node = None @@ -506,7 +540,8 @@ def getnode(): if sys.platform == 'win32': getters = [_windll_getnode, _netbios_getnode, _ipconfig_getnode] else: - getters = [_unixdll_getnode, _ifconfig_getnode] + getters = [_unixdll_getnode, _ifconfig_getnode, _ip_getnode, + _arp_getnode, _lanscan_getnode, _netstat_getnode] for getter in getters + [_random_getnode]: try: @@ -542,7 +577,7 @@ def uuid1(node=None, clock_seq=None): _last_timestamp = timestamp if clock_seq is None: import random - clock_seq = random.randrange(1<<14) # instead of stable storage + clock_seq = random.getrandbits(14) # instead of stable storage time_low = timestamp & 0xffffffff time_mid = (timestamp >> 32) & 0xffff time_hi_version = (timestamp >> 48) & 0x0fff @@ -574,8 +609,7 @@ def uuid4(): return UUID(bytes=os.urandom(16), version=4) except: import random - bytes = bytes_(random.randrange(256) for i in range(16)) - return UUID(bytes=bytes, version=4) + return UUID(int=random.getrandbits(128), version=4) def uuid5(namespace, name): """Generate a UUID from the SHA-1 hash of a namespace UUID and a name.""" diff --git a/Lib/venv/__init__.py b/Lib/venv/__init__.py index 3b5f5fab81ee..3d606ef89c32 100644 --- a/Lib/venv/__init__.py +++ b/Lib/venv/__init__.py @@ -1,7 +1,7 @@ """ Virtual environment (venv) package for Python. Based on PEP 405. -Copyright (C) 2011-2012 Vinay Sajip. +Copyright (C) 2011-2014 Vinay Sajip. Licensed to the PSF under a contributor agreement. usage: python -m venv [-h] [--system-site-packages] [--symlinks] [--clear] @@ -32,7 +32,6 @@ import shutil import subprocess import sys -import sysconfig import types logger = logging.getLogger(__name__) @@ -133,10 +132,18 @@ def create_if_needed(d): else: binname = 'bin' incpath = 'include' - libpath = os.path.join(env_dir, 'lib', 'python%d.%d' % sys.version_info[:2], 'site-packages') + libpath = os.path.join(env_dir, 'lib', + 'python%d.%d' % sys.version_info[:2], + 'site-packages') context.inc_path = path = os.path.join(env_dir, incpath) create_if_needed(path) create_if_needed(libpath) + # Issue 21197: create lib64 as a symlink to lib on 64-bit non-OS X POSIX + if ((sys.maxsize > 2**32) and (os.name == 'posix') and + (sys.platform != 'darwin')): + link_path = os.path.join(env_dir, 'lib64') + if not os.path.exists(link_path): # Issue #21643 + os.symlink('lib', link_path) context.bin_path = binpath = os.path.join(env_dir, binname) context.bin_name = binname context.env_exe = os.path.join(binpath, exename) @@ -170,7 +177,7 @@ def include_binary(self, f): result = f.startswith('python') and f.endswith('.exe') return result - def symlink_or_copy(self, src, dst): + def symlink_or_copy(self, src, dst, relative_symlinks_ok=False): """ Try symlinking a file, and if that fails, fall back to copying. """ @@ -178,7 +185,11 @@ def symlink_or_copy(self, src, dst): if not force_copy: try: if not os.path.islink(dst): # can't link to itself! - os.symlink(src, dst) + if relative_symlinks_ok: + assert os.path.dirname(src) == os.path.dirname(dst) + os.symlink(os.path.basename(src), dst) + else: + os.symlink(src, dst) except Exception: # may need to use a more specific exception logger.warning('Unable to symlink %r to %r', src, dst) force_copy = True @@ -193,7 +204,6 @@ def setup_python(self, context): being processed. """ binpath = context.bin_path - exename = context.python_exe path = context.env_exe copier = self.symlink_or_copy copier(context.executable, path) @@ -204,7 +214,11 @@ def setup_python(self, context): for suffix in ('python', 'python3'): path = os.path.join(binpath, suffix) if not os.path.exists(path): - os.symlink(exename, path) + # Issue 18807: make copies if + # symlinks are not wanted + copier(context.env_exe, path, relative_symlinks_ok=True) + if not os.path.islink(path): + os.chmod(path, 0o755) else: subdir = 'DLLs' include = self.include_binary @@ -226,7 +240,8 @@ def setup_python(self, context): if 'init.tcl' in files: tcldir = os.path.basename(root) tcldir = os.path.join(context.env_dir, 'Lib', tcldir) - os.makedirs(tcldir) + if not os.path.exists(tcldir): + os.makedirs(tcldir) src = os.path.join(root, 'init.tcl') dst = os.path.join(tcldir, 'init.tcl') shutil.copyfile(src, dst) diff --git a/Lib/warnings.py b/Lib/warnings.py index a427e3510eca..5ca4b9c1604b 100644 --- a/Lib/warnings.py +++ b/Lib/warnings.py @@ -2,7 +2,8 @@ import sys -__all__ = ["warn", "showwarning", "formatwarning", "filterwarnings", +__all__ = ["warn", "warn_explicit", "showwarning", + "formatwarning", "filterwarnings", "simplefilter", "resetwarnings", "catch_warnings"] @@ -10,6 +11,9 @@ def showwarning(message, category, filename, lineno, file=None, line=None): """Hook to write a warning to a file; replace if you like.""" if file is None: file = sys.stderr + if file is None: + # sys.stderr is None when run with pythonw.exe - warnings get lost + return try: file.write(formatwarning(message, category, filename, lineno, line)) except OSError: @@ -52,6 +56,7 @@ def filterwarnings(action, message="", category=Warning, module="", lineno=0, filters.append(item) else: filters.insert(0, item) + _filters_mutated() def simplefilter(action, category=Warning, lineno=0, append=False): """Insert a simple entry into the list of warnings filters (at the front). @@ -72,10 +77,12 @@ def simplefilter(action, category=Warning, lineno=0, append=False): filters.append(item) else: filters.insert(0, item) + _filters_mutated() def resetwarnings(): """Clear the list of warning filters, so that no filters are active.""" filters[:] = [] + _filters_mutated() class _OptionError(Exception): """Exception used by option processing helpers.""" @@ -162,7 +169,9 @@ def warn(message, category=None, stacklevel=1): # Check category argument if category is None: category = UserWarning - assert issubclass(category, Warning) + if not (isinstance(category, type) and issubclass(category, Warning)): + raise TypeError("category must be a Warning subclass, " + "not '{:s}'".format(type(category).__name__)) # Get context information try: caller = sys._getframe(stacklevel) @@ -203,6 +212,9 @@ def warn_explicit(message, category, filename, lineno, module = module[:-3] # XXX What about leading pathname? if registry is None: registry = {} + if registry.get('version', 0) != _filters_version: + registry.clear() + registry['version'] = _filters_version if isinstance(message, Warning): text = str(message) category = message.__class__ @@ -328,6 +340,7 @@ def __enter__(self): self._entered = True self._filters = self._module.filters self._module.filters = self._filters[:] + self._module._filters_mutated() self._showwarning = self._module.showwarning if self._record: log = [] @@ -342,6 +355,7 @@ def __exit__(self, *exc_info): if not self._entered: raise RuntimeError("Cannot exit %r without entering first" % self) self._module.filters = self._filters + self._module._filters_mutated() self._module.showwarning = self._showwarning @@ -356,15 +370,22 @@ def __exit__(self, *exc_info): _warnings_defaults = False try: from _warnings import (filters, _defaultaction, _onceregistry, - warn, warn_explicit) + warn, warn_explicit, _filters_mutated) defaultaction = _defaultaction onceregistry = _onceregistry _warnings_defaults = True + except ImportError: filters = [] defaultaction = "default" onceregistry = {} + _filters_version = 1 + + def _filters_mutated(): + global _filters_version + _filters_version += 1 + # Module initialization _processoptions(sys.warnoptions) diff --git a/Lib/weakref.py b/Lib/weakref.py index f6a40ca4bf7d..a4ecadc5b608 100644 --- a/Lib/weakref.py +++ b/Lib/weakref.py @@ -144,7 +144,7 @@ def __contains__(self, key): return o is not None def __repr__(self): - return "" % id(self) + return "<%s at %#x>" % (self.__class__.__name__, id(self)) def __setitem__(self, key, value): if self._pending_removals: @@ -322,6 +322,7 @@ def remove(k, selfref=ref(self)): # A list of dead weakrefs (keys to be removed) self._pending_removals = [] self._iterating = set() + self._dirty_len = False if dict is not None: self.update(dict) @@ -338,17 +339,27 @@ def _commit_removals(self): except KeyError: pass + def _scrub_removals(self): + d = self.data + self._pending_removals = [k for k in self._pending_removals if k in d] + self._dirty_len = False + def __delitem__(self, key): + self._dirty_len = True del self.data[ref(key)] def __getitem__(self, key): return self.data[ref(key)] def __len__(self): + if self._dirty_len and self._pending_removals: + # self._pending_removals may still contain keys which were + # explicitly removed, we have to scrub them (see issue #21173). + self._scrub_removals() return len(self.data) - len(self._pending_removals) def __repr__(self): - return "" % id(self) + return "<%s at %#x>" % (self.__class__.__name__, id(self)) def __setitem__(self, key, value): self.data[ref(key, self._remove)] = value @@ -417,6 +428,7 @@ def keyrefs(self): return list(self.data) def popitem(self): + self._dirty_len = True while True: key, value = self.data.popitem() o = key() @@ -424,6 +436,7 @@ def popitem(self): return o, value def pop(self, key, *args): + self._dirty_len = True return self.data.pop(ref(key), *args) def setdefault(self, key, default=None): diff --git a/Lib/webbrowser.py b/Lib/webbrowser.py old mode 100644 new mode 100755 index 2714bd144e38..845f1d004c0b --- a/Lib/webbrowser.py +++ b/Lib/webbrowser.py @@ -2,14 +2,11 @@ """Interfaces for launching and remotely controlling Web browsers.""" # Maintained by Georg Brandl. -import io import os import shlex import shutil import sys -import stat import subprocess -import time __all__ = ["Error", "open", "open_new", "open_new_tab", "get", "register"] @@ -162,10 +159,8 @@ def open(self, url, new=0, autoraise=True): if sys.platform[:3] == 'win': p = subprocess.Popen(cmdline) else: - setsid = getattr(os, 'setsid', None) - if not setsid: - setsid = getattr(os, 'setpgrp', None) - p = subprocess.Popen(cmdline, close_fds=True, preexec_fn=setsid) + p = subprocess.Popen(cmdline, close_fds=True, + start_new_session=True) return (p.poll() is None) except OSError: return False @@ -324,11 +319,6 @@ def open(self, url, new=0, autoraise=True): action = "openURL" devnull = subprocess.DEVNULL - # if possible, put browser in separate process group, so - # keyboard interrupts don't affect browser as well as Python - setsid = getattr(os, 'setsid', None) - if not setsid: - setsid = getattr(os, 'setpgrp', None) try: p = subprocess.Popen(["kfmclient", action, url], @@ -346,7 +336,7 @@ def open(self, url, new=0, autoraise=True): p = subprocess.Popen(["konqueror", "--silent", url], close_fds=True, stdin=devnull, stdout=devnull, stderr=devnull, - preexec_fn=setsid) + start_new_session=True) except OSError: # fall through to next variant pass @@ -359,7 +349,7 @@ def open(self, url, new=0, autoraise=True): p = subprocess.Popen(["kfm", "-d", url], close_fds=True, stdin=devnull, stdout=devnull, stderr=devnull, - preexec_fn=setsid) + start_new_session=True) except OSError: return False else: diff --git a/Lib/wsgiref/__init__.py b/Lib/wsgiref/__init__.py index 46c579f8ecec..1efbba01a306 100644 --- a/Lib/wsgiref/__init__.py +++ b/Lib/wsgiref/__init__.py @@ -1,4 +1,4 @@ -"""wsgiref -- a WSGI (PEP 333) Reference Library +"""wsgiref -- a WSGI (PEP 3333) Reference Library Current Contents: diff --git a/Lib/wsgiref/headers.py b/Lib/wsgiref/headers.py index d93962831aed..7e670b3caf1c 100644 --- a/Lib/wsgiref/headers.py +++ b/Lib/wsgiref/headers.py @@ -26,10 +26,10 @@ def _formatparam(param, value=None, quote=1): class Headers: - """Manage a collection of HTTP response headers""" - def __init__(self,headers): + def __init__(self, headers=None): + headers = headers if headers is not None else [] if type(headers) is not list: raise TypeError("Headers must be a list of name/value tuples") self._headers = headers @@ -131,7 +131,7 @@ def items(self): return self._headers[:] def __repr__(self): - return "Headers(%r)" % self._headers + return "%s(%r)" % (self.__class__.__name__, self._headers) def __str__(self): """str() returns the formatted headers, complete with end line, diff --git a/Lib/wsgiref/simple_server.py b/Lib/wsgiref/simple_server.py index cd9751a6551b..378b316bbd45 100644 --- a/Lib/wsgiref/simple_server.py +++ b/Lib/wsgiref/simple_server.py @@ -115,7 +115,14 @@ def get_stderr(self): def handle(self): """Handle a single HTTP request""" - self.raw_requestline = self.rfile.readline() + self.raw_requestline = self.rfile.readline(65537) + if len(self.raw_requestline) > 65536: + self.requestline = '' + self.request_version = '' + self.command = '' + self.send_error(414) + return + if not self.parse_request(): # An error code has been sent, just exit return diff --git a/Lib/wsgiref/util.py b/Lib/wsgiref/util.py index 1f1e6cce1798..516fe898d014 100644 --- a/Lib/wsgiref/util.py +++ b/Lib/wsgiref/util.py @@ -57,14 +57,14 @@ def application_uri(environ): if environ['SERVER_PORT'] != '80': url += ':' + environ['SERVER_PORT'] - url += quote(environ.get('SCRIPT_NAME') or '/') + url += quote(environ.get('SCRIPT_NAME') or '/', encoding='latin1') return url def request_uri(environ, include_query=True): """Return the full request URI, optionally including the query string""" url = application_uri(environ) from urllib.parse import quote - path_info = quote(environ.get('PATH_INFO',''),safe='/;=,') + path_info = quote(environ.get('PATH_INFO',''), safe='/;=,', encoding='latin1') if not environ.get('SCRIPT_NAME'): url += path_info[1:] else: diff --git a/Lib/xdrlib.py b/Lib/xdrlib.py index c05cf87e4a1d..d6e1aeb52726 100644 --- a/Lib/xdrlib.py +++ b/Lib/xdrlib.py @@ -6,6 +6,7 @@ import struct from io import BytesIO +from functools import wraps __all__ = ["Error", "Packer", "Unpacker", "ConversionError"] @@ -31,6 +32,16 @@ def __str__(self): class ConversionError(Error): pass +def raise_conversion_error(function): + """ Wrap any raised struct.errors in a ConversionError. """ + + @wraps(function) + def result(self, value): + try: + return function(self, value) + except struct.error as e: + raise ConversionError(e.args[0]) from None + return result class Packer: @@ -47,9 +58,11 @@ def get_buffer(self): # backwards compatibility get_buf = get_buffer + @raise_conversion_error def pack_uint(self, x): self.__buf.write(struct.pack('>L', x)) + @raise_conversion_error def pack_int(self, x): self.__buf.write(struct.pack('>l', x)) @@ -60,20 +73,24 @@ def pack_bool(self, x): else: self.__buf.write(b'\0\0\0\0') def pack_uhyper(self, x): - self.pack_uint(x>>32 & 0xffffffff) - self.pack_uint(x & 0xffffffff) + try: + self.pack_uint(x>>32 & 0xffffffff) + except (TypeError, struct.error) as e: + raise ConversionError(e.args[0]) from None + try: + self.pack_uint(x & 0xffffffff) + except (TypeError, struct.error) as e: + raise ConversionError(e.args[0]) from None pack_hyper = pack_uhyper + @raise_conversion_error def pack_float(self, x): - try: self.__buf.write(struct.pack('>f', x)) - except struct.error as msg: - raise ConversionError(msg) + self.__buf.write(struct.pack('>f', x)) + @raise_conversion_error def pack_double(self, x): - try: self.__buf.write(struct.pack('>d', x)) - except struct.error as msg: - raise ConversionError(msg) + self.__buf.write(struct.pack('>d', x)) def pack_fstring(self, n, s): if n < 0: diff --git a/Lib/xml/dom/expatbuilder.py b/Lib/xml/dom/expatbuilder.py index 81e2df70d7a4..897614434067 100644 --- a/Lib/xml/dom/expatbuilder.py +++ b/Lib/xml/dom/expatbuilder.py @@ -121,10 +121,12 @@ def _parse_ns_name(builder, name): qname = "%s:%s" % (prefix, localname) qname = intern(qname, qname) localname = intern(localname, localname) - else: + elif len(parts) == 2: uri, localname = parts prefix = EMPTY_PREFIX qname = localname = intern(localname, localname) + else: + raise ValueError("Unsupported syntax: spaces in URIs not supported: %r" % name) return intern(uri, uri), localname, prefix, qname diff --git a/Lib/xml/dom/minidom.py b/Lib/xml/dom/minidom.py index 6f716314647d..a5d813f932ac 100644 --- a/Lib/xml/dom/minidom.py +++ b/Lib/xml/dom/minidom.py @@ -545,9 +545,6 @@ def __le__(self, other): def __lt__(self, other): return self._cmp(other) < 0 - def __ne__(self, other): - return self._cmp(other) != 0 - def __getitem__(self, attname_or_tuple): if isinstance(attname_or_tuple, tuple): return self._attrsNS[attname_or_tuple] @@ -648,9 +645,10 @@ def __init__(self, namespace, name): def __repr__(self): if self.namespace: - return "" % (self.name, self.namespace) + return "<%s %r (from %r)>" % (self.__class__.__name__, self.name, + self.namespace) else: - return "" % self.name + return "<%s %r>" % (self.__class__.__name__, self.name) def _get_name(self): return self.name @@ -976,7 +974,7 @@ def __init__(self, target, data): def _get_nodeValue(self): return self.data def _set_nodeValue(self, value): - self.data = data + self.data = value nodeValue = property(_get_nodeValue, _set_nodeValue) # nodeName is an alias for target diff --git a/Lib/xml/etree/ElementInclude.py b/Lib/xml/etree/ElementInclude.py index 73e491e5d9e1..963470e3b15c 100644 --- a/Lib/xml/etree/ElementInclude.py +++ b/Lib/xml/etree/ElementInclude.py @@ -76,14 +76,13 @@ class FatalIncludeError(SyntaxError): def default_loader(href, parse, encoding=None): if parse == "xml": - file = open(href, 'rb') - data = ElementTree.parse(file).getroot() + with open(href, 'rb') as file: + data = ElementTree.parse(file).getroot() else: if not encoding: encoding = 'UTF-8' - file = open(href, 'r', encoding=encoding) - data = file.read() - file.close() + with open(href, 'r', encoding=encoding) as file: + data = file.read() return data ## diff --git a/Lib/xml/etree/ElementPath.py b/Lib/xml/etree/ElementPath.py index d914ddb67239..5de42324c295 100644 --- a/Lib/xml/etree/ElementPath.py +++ b/Lib/xml/etree/ElementPath.py @@ -114,7 +114,10 @@ def select(context, result): return select def prepare_descendant(next, token): - token = next() + try: + token = next() + except StopIteration: + return if token[0] == "*": tag = "*" elif not token[0]: @@ -148,7 +151,10 @@ def prepare_predicate(next, token): signature = [] predicate = [] while 1: - token = next() + try: + token = next() + except StopIteration: + return if token[0] == "]": break if token[0] and token[0][:1] in "'\"": @@ -261,7 +267,10 @@ def iterfind(elem, path, namespaces=None): if path[:1] == "/": raise SyntaxError("cannot use absolute path on element") next = iter(xpath_tokenizer(path, namespaces)).__next__ - token = next() + try: + token = next() + except StopIteration: + return selector = [] while 1: try: @@ -286,10 +295,7 @@ def iterfind(elem, path, namespaces=None): # Find first matching object. def find(elem, path, namespaces=None): - try: - return next(iterfind(elem, path, namespaces)) - except StopIteration: - return None + return next(iterfind(elem, path, namespaces), None) ## # Find all matching objects. diff --git a/Lib/xml/etree/ElementTree.py b/Lib/xml/etree/ElementTree.py index cab415cb3b98..4c109a2f612f 100644 --- a/Lib/xml/etree/ElementTree.py +++ b/Lib/xml/etree/ElementTree.py @@ -125,7 +125,7 @@ class Element: This class is the reference implementation of the Element interface. An element's length is its number of subelements. That means if you - you want to check if an element is truly empty, you should check BOTH + want to check if an element is truly empty, you should check BOTH its length AND its text attribute. The element tag, attribute names, and attribute values can be either @@ -174,7 +174,7 @@ def __init__(self, tag, attrib={}, **extra): self._children = [] def __repr__(self): - return "" % (repr(self.tag), id(self)) + return "<%s %r at %#x>" % (self.__class__.__name__, self.tag, id(self)) def makeelement(self, tag, attrib): """Create a new element with the same type. @@ -509,7 +509,7 @@ def __init__(self, text_or_uri, tag=None): def __str__(self): return self.text def __repr__(self): - return '' % (self.text,) + return '<%s %r>' % (self.__class__.__name__, self.text) def __hash__(self): return hash(self.text) def __le__(self, other): @@ -532,10 +532,6 @@ def __eq__(self, other): if isinstance(other, QName): return self.text == other.text return self.text == other - def __ne__(self, other): - if isinstance(other, QName): - return self.text != other.text - return self.text != other # -------------------------------------------------------------------- @@ -1251,7 +1247,7 @@ def close(self): self._close_and_return_root() def read_events(self): - """Iterate over currently available (event, elem) pairs. + """Return an iterator over currently available (event, elem) pairs. Events are consumed from the internal event queue as they are retrieved from the iterator. diff --git a/Lib/xml/sax/saxutils.py b/Lib/xml/sax/saxutils.py index 74de9b07fc11..1d3d0ecc5f98 100644 --- a/Lib/xml/sax/saxutils.py +++ b/Lib/xml/sax/saxutils.py @@ -346,7 +346,7 @@ def prepare_input_source(source, base=""): f = source source = xmlreader.InputSource() source.setByteStream(f) - if hasattr(f, "name"): + if hasattr(f, "name") and isinstance(f.name, str): source.setSystemId(f.name) if source.getByteStream() is None: diff --git a/Lib/xmlrpc/client.py b/Lib/xmlrpc/client.py index 9e0f0691bf92..047929a8611d 100644 --- a/Lib/xmlrpc/client.py +++ b/Lib/xmlrpc/client.py @@ -49,6 +49,7 @@ # 2003-07-12 gp Correct marshalling of Faults # 2003-10-31 mvl Add multicall support # 2004-08-20 mvl Bump minimum supported Python version to 2.1 +# 2014-12-02 ch/doko Add workaround for gzip bomb vulnerability # # Copyright (c) 1999-2002 by Secret Labs AB. # Copyright (c) 1999-2002 by Fredrik Lundh. @@ -134,7 +135,6 @@ import http.client import urllib.parse from xml.parsers import expat -import socket import errno from io import BytesIO try: @@ -208,8 +208,8 @@ def __init__(self, url, errcode, errmsg, headers): self.headers = headers def __repr__(self): return ( - "" % - (self.url, self.errcode, self.errmsg) + "<%s for %s: %s %s>" % + (self.__class__.__name__, self.url, self.errcode, self.errmsg) ) ## @@ -237,7 +237,8 @@ def __init__(self, faultCode, faultString, **extra): self.faultCode = faultCode self.faultString = faultString def __repr__(self): - return "" % (self.faultCode, self.faultString) + return "<%s %s: %r>" % (self.__class__.__name__, + self.faultCode, self.faultString) # -------------------------------------------------------------------- # Special values @@ -339,10 +340,6 @@ def __eq__(self, other): s, o = self.make_comparable(other) return s == o - def __ne__(self, other): - s, o = self.make_comparable(other) - return s != o - def timetuple(self): return time.strptime(self.value, "%Y%m%dT%H:%M:%S") @@ -355,7 +352,7 @@ def __str__(self): return self.value def __repr__(self): - return "" % (self.value, id(self)) + return "<%s %r at %#x>" % (self.__class__.__name__, self.value, id(self)) def decode(self, data): self.value = str(data).strip() @@ -406,11 +403,6 @@ def __eq__(self, other): other = other.data return self.data == other - def __ne__(self, other): - if isinstance(other, Binary): - other = other.data - return self.data != other - def decode(self, data): self.data = base64.decodebytes(data) @@ -847,7 +839,7 @@ def __init__(self, server): self.__call_list = [] def __repr__(self): - return "" % id(self) + return "<%s at %#x>" % (self.__class__.__name__, id(self)) __str__ = __repr__ @@ -1031,10 +1023,13 @@ def gzip_encode(data): # in the HTTP header, as described in RFC 1952 # # @param data The encoded data +# @keyparam max_decode Maximum bytes to decode (20MB default), use negative +# values for unlimited decoding # @return the unencoded data # @raises ValueError if data is not correctly coded. +# @raises ValueError if max gzipped payload length exceeded -def gzip_decode(data): +def gzip_decode(data, max_decode=20971520): """gzip encoded data -> unencoded data Decode data using the gzip content encoding as described in RFC 1952 @@ -1044,11 +1039,16 @@ def gzip_decode(data): f = BytesIO(data) gzf = gzip.GzipFile(mode="rb", fileobj=f) try: - decoded = gzf.read() + if max_decode < 0: # no limit + decoded = gzf.read() + else: + decoded = gzf.read(max_decode + 1) except OSError: raise ValueError("invalid data") f.close() gzf.close() + if max_decode >= 0 and len(decoded) > max_decode: + raise ValueError("max gzipped payload length exceeded") return decoded ## @@ -1324,6 +1324,11 @@ def parse_response(self, response): class SafeTransport(Transport): """Handles an HTTPS transaction to an XML-RPC server.""" + def __init__(self, use_datetime=False, use_builtin_types=False, *, + context=None): + super().__init__(use_datetime=use_datetime, use_builtin_types=use_builtin_types) + self.context = context + # FIXME: mostly untested def make_connection(self, host): @@ -1337,7 +1342,7 @@ def make_connection(self, host): # host may be a string, or a (host, x509-dict) tuple chost, self._extra_headers, x509 = self.get_host_info(host) self._connection = host, http.client.HTTPSConnection(chost, - None, **(x509 or {})) + None, context=self.context, **(x509 or {})) return self._connection[1] ## @@ -1380,7 +1385,8 @@ class ServerProxy: """ def __init__(self, uri, transport=None, encoding=None, verbose=False, - allow_none=False, use_datetime=False, use_builtin_types=False): + allow_none=False, use_datetime=False, use_builtin_types=False, + *, context=None): # establish a "logical" server connection # get the url @@ -1394,10 +1400,13 @@ def __init__(self, uri, transport=None, encoding=None, verbose=False, if transport is None: if type == "https": handler = SafeTransport + extra_kwargs = {"context": context} else: handler = Transport + extra_kwargs = {} transport = handler(use_datetime=use_datetime, - use_builtin_types=use_builtin_types) + use_builtin_types=use_builtin_types, + **extra_kwargs) self.__transport = transport self.__encoding = encoding or 'utf-8' @@ -1427,8 +1436,8 @@ def __request(self, methodname, params): def __repr__(self): return ( - "" % - (self.__host, self.__handler) + "<%s for %s%s>" % + (self.__class__.__name__, self.__host, self.__handler) ) __str__ = __repr__ @@ -1450,6 +1459,12 @@ def __call__(self, attr): return self.__transport raise AttributeError("Attribute %r not found" % (attr,)) + def __enter__(self): + return self + + def __exit__(self, *args): + self.__close() + # compatibility Server = ServerProxy @@ -1461,18 +1476,18 @@ def __call__(self, attr): # simple test program (from the XML-RPC specification) - # server = ServerProxy("http://localhost:8000") # local server - server = ServerProxy("http://time.xmlrpc.com/RPC2") + # local server, available from Lib/xmlrpc/server.py + server = ServerProxy("http://localhost:8000") try: print(server.currentTime.getCurrentTime()) except Error as v: print("ERROR", v) - # The server at xmlrpc.com doesn't seem to support multicall anymore. multi = MultiCall(server) - multi.currentTime.getCurrentTime() - multi.currentTime.getCurrentTime() + multi.getData() + multi.pow(2,9) + multi.add(1,2) try: for response in multi(): print(response) diff --git a/Lib/xmlrpc/server.py b/Lib/xmlrpc/server.py index d914282917d1..304e218c008e 100644 --- a/Lib/xmlrpc/server.py +++ b/Lib/xmlrpc/server.py @@ -960,10 +960,24 @@ def __init__(self): if __name__ == '__main__': + import datetime + + class ExampleService: + def getData(self): + return '42' + + class currentTime: + @staticmethod + def getCurrentTime(): + return datetime.datetime.now() + server = SimpleXMLRPCServer(("localhost", 8000)) server.register_function(pow) server.register_function(lambda x,y: x+y, 'add') + server.register_instance(ExampleService(), allow_dotted_names=True) + server.register_multicall_functions() print('Serving XML-RPC on localhost port 8000') + print('It is advisable to run this example server within a secure, closed network.') try: server.serve_forever() except KeyboardInterrupt: diff --git a/Lib/zipfile.py b/Lib/zipfile.py index fad52a246d5a..8c2950f53331 100644 --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -13,6 +13,7 @@ import shutil import struct import binascii +import threading try: @@ -50,7 +51,7 @@ class LargeZipFile(Exception): ZIP64_LIMIT = (1 << 31) - 1 -ZIP_FILECOUNT_LIMIT = 1 << 16 +ZIP_FILECOUNT_LIMIT = (1 << 16) - 1 ZIP_MAX_COMMENT = (1 << 16) - 1 # constants for Zip file compression methods @@ -355,6 +356,28 @@ def __init__(self, filename="NoName", date_time=(1980,1,1,0,0,0)): # compress_size Size of the compressed file # file_size Size of the uncompressed file + def __repr__(self): + result = ['<%s filename=%r' % (self.__class__.__name__, self.filename)] + if self.compress_type != ZIP_STORED: + result.append(' compress_type=%s' % + compressor_names.get(self.compress_type, + self.compress_type)) + hi = self.external_attr >> 16 + lo = self.external_attr & 0xFFFF + if hi: + result.append(' filemode=%r' % stat.filemode(hi)) + if lo: + result.append(' external_attr=%#x' % lo) + isdir = self.filename[-1:] == '/' + if not isdir or self.file_size: + result.append(' file_size=%r' % self.file_size) + if ((not isdir or self.compress_size) and + (self.compress_type != ZIP_STORED or + self.file_size != self.compress_size)): + result.append(' compress_size=%r' % self.compress_size) + result.append('>') + return ''.join(result) + def FileHeader(self, zip64=None): """Return the per-file header as a string.""" dt = self.date_time @@ -411,7 +434,7 @@ def _decodeExtra(self): # Try to decode the extra field. extra = self.extra unpack = struct.unpack - while extra: + while len(extra) >= 4: tp, ln = unpack('= 24: @@ -475,13 +498,15 @@ def _GenerateCRCTable(): crc = ((crc >> 1) & 0x7FFFFFFF) table[i] = crc return table - crctable = _GenerateCRCTable() + crctable = None def _crc32(self, ch, crc): """Compute the CRC32 primitive on one byte.""" return ((crc >> 8) & 0xffffff) ^ self.crctable[(crc ^ ch) & 0xff] def __init__(self, pwd): + if _ZipDecrypter.crctable is None: + _ZipDecrypter.crctable = _ZipDecrypter._GenerateCRCTable() self.key0 = 305419896 self.key1 = 591751049 self.key2 = 878082192 @@ -622,6 +647,27 @@ def _get_decompressor(compress_type): raise NotImplementedError("compression type %d" % (compress_type,)) +class _SharedFile: + def __init__(self, file, pos, close, lock): + self._file = file + self._pos = pos + self._close = close + self._lock = lock + + def read(self, n=-1): + with self._lock: + self._file.seek(self._pos) + data = self._file.read(n) + self._pos = self._file.tell() + return data + + def close(self): + if self._file is not None: + fileobj = self._file + self._file = None + self._close(fileobj) + + class ZipExtFile(io.BufferedIOBase): """File-like object for reading an archive member. Is returned by ZipFile.open(). @@ -669,6 +715,20 @@ def __init__(self, fileobj, mode, zipinfo, decrypter=None, else: self._expected_crc = None + def __repr__(self): + result = ['<%s.%s' % (self.__class__.__module__, + self.__class__.__qualname__)] + if not self.closed: + result.append(' name=%r mode=%r' % (self.name, self.mode)) + if self._compress_type != ZIP_STORED: + result.append(' compress_type=%s' % + compressor_names.get(self._compress_type, + self._compress_type)) + else: + result.append(' [closed]') + result.append('>') + return ''.join(result) + def readline(self, limit=-1): """Read and return a line from the stream. @@ -860,6 +920,8 @@ def _read2(self, n): data = self._fileobj.read(n) self._compress_left -= len(data) + if not data: + raise EOFError if self._decrypter is not None: data = bytes(map(self._decrypter, data)) @@ -905,7 +967,7 @@ def __init__(self, file, mode="r", compression=ZIP_STORED, allowZip64=True): self.NameToInfo = {} # Find file info given name self.filelist = [] # List of ZipInfo instances for archive self.compression = compression # Method of compression - self.mode = key = mode.replace('b', '')[0] + self.mode = mode self.pwd = None self._comment = b'' @@ -914,28 +976,34 @@ def __init__(self, file, mode="r", compression=ZIP_STORED, allowZip64=True): # No, it's a filename self._filePassed = 0 self.filename = file - modeDict = {'r' : 'rb', 'w': 'wb', 'a' : 'r+b'} - try: - self.fp = io.open(file, modeDict[mode]) - except OSError: - if mode == 'a': - mode = key = 'w' - self.fp = io.open(file, modeDict[mode]) - else: + modeDict = {'r' : 'rb', 'w': 'w+b', 'a' : 'r+b', + 'r+b': 'w+b', 'w+b': 'wb'} + filemode = modeDict[mode] + while True: + try: + self.fp = io.open(file, filemode) + except OSError: + if filemode in modeDict: + filemode = modeDict[filemode] + continue raise + break else: self._filePassed = 1 self.fp = file self.filename = getattr(file, 'name', None) + self._fileRefCnt = 1 + self._lock = threading.RLock() try: - if key == 'r': + if mode == 'r': self._RealGetContents() - elif key == 'w': + elif mode == 'w': # set the modified flag so central directory gets written # even if no files are added to the archive self._didModify = True - elif key == 'a': + self.start_dir = self.fp.tell() + elif mode == 'a': try: # See if file is a zip file self._RealGetContents() @@ -948,13 +1016,13 @@ def __init__(self, file, mode="r", compression=ZIP_STORED, allowZip64=True): # set the modified flag so central directory gets written # even if no files are added to the archive self._didModify = True + self.start_dir = self.fp.tell() else: raise RuntimeError('Mode must be "r", "w" or "a"') except: fp = self.fp self.fp = None - if not self._filePassed: - fp.close() + self._fpclose(fp) raise def __enter__(self): @@ -963,6 +1031,20 @@ def __enter__(self): def __exit__(self, type, value, traceback): self.close() + def __repr__(self): + result = ['<%s.%s' % (self.__class__.__module__, + self.__class__.__qualname__)] + if self.fp is not None: + if self._filePassed: + result.append(' file=%r' % self.fp) + elif self.filename is not None: + result.append(' filename=%r' % self.filename) + result.append(' mode=%r' % self.mode) + else: + result.append(' [closed]') + result.append('>') + return ''.join(result) + def _RealGetContents(self): """Read in the table of contents for the ZIP file.""" fp = self.fp @@ -1100,10 +1182,10 @@ def comment(self, comment): if not isinstance(comment, bytes): raise TypeError("comment: expected bytes, got %s" % type(comment)) # check for valid comment length - if len(comment) >= ZIP_MAX_COMMENT: - if self.debug: - print('Archive comment is too long; truncating to %d bytes' - % ZIP_MAX_COMMENT) + if len(comment) > ZIP_MAX_COMMENT: + import warnings + warnings.warn('Archive comment is too long; truncating to %d bytes' + % ZIP_MAX_COMMENT, stacklevel=2) comment = comment[:ZIP_MAX_COMMENT] self._comment = comment self._didModify = True @@ -1127,23 +1209,17 @@ def open(self, name, mode="r", pwd=None): raise RuntimeError( "Attempt to read ZIP archive that was already closed") - # Only open a new file for instances where we were not - # given a file object in the constructor - if self._filePassed: - zef_file = self.fp + # Make sure we have an info object + if isinstance(name, ZipInfo): + # 'name' is already an info object + zinfo = name else: - zef_file = io.open(self.filename, 'rb') + # Get info object for name + zinfo = self.getinfo(name) + self._fileRefCnt += 1 + zef_file = _SharedFile(self.fp, zinfo.header_offset, self._fpclose, self._lock) try: - # Make sure we have an info object - if isinstance(name, ZipInfo): - # 'name' is already an info object - zinfo = name - else: - # Get info object for name - zinfo = self.getinfo(name) - zef_file.seek(zinfo.header_offset, 0) - # Skip the file header: fheader = zef_file.read(sizeFileHeader) if len(fheader) != sizeFileHeader: @@ -1202,11 +1278,9 @@ def open(self, name, mode="r", pwd=None): if h[11] != check_byte: raise RuntimeError("Bad password for file", name) - return ZipExtFile(zef_file, mode, zinfo, zd, - close_fileobj=not self._filePassed) + return ZipExtFile(zef_file, mode, zinfo, zd, True) except: - if not self._filePassed: - zef_file.close() + zef_file.close() raise def extract(self, member, path=None, pwd=None): @@ -1292,21 +1366,25 @@ def _extract_member(self, member, targetpath, pwd): def _writecheck(self, zinfo): """Check for errors before writing a file to the archive.""" if zinfo.filename in self.NameToInfo: - if self.debug: # Warning for duplicate names - print("Duplicate name:", zinfo.filename) + import warnings + warnings.warn('Duplicate name: %r' % zinfo.filename, stacklevel=3) if self.mode not in ("w", "a"): raise RuntimeError('write() requires mode "w" or "a"') if not self.fp: raise RuntimeError( "Attempt to write ZIP archive that was already closed") _check_compression(zinfo.compress_type) - if zinfo.file_size > ZIP64_LIMIT: - if not self._allowZip64: - raise LargeZipFile("Filesize would require ZIP64 extensions") - if zinfo.header_offset > ZIP64_LIMIT: - if not self._allowZip64: - raise LargeZipFile( - "Zipfile size would require ZIP64 extensions") + if not self._allowZip64: + requires_zip64 = None + if len(self.filelist) >= ZIP_FILECOUNT_LIMIT: + requires_zip64 = "Files count" + elif zinfo.file_size > ZIP64_LIMIT: + requires_zip64 = "Filesize" + elif zinfo.header_offset > ZIP64_LIMIT: + requires_zip64 = "Zipfile size" + if requires_zip64: + raise LargeZipFile(requires_zip64 + + " would require ZIP64 extensions") def write(self, filename, arcname=None, compress_type=None): """Put the bytes from filename into the archive under the name @@ -1336,65 +1414,69 @@ def write(self, filename, arcname=None, compress_type=None): zinfo.file_size = st.st_size zinfo.flag_bits = 0x00 - zinfo.header_offset = self.fp.tell() # Start of header bytes - if zinfo.compress_type == ZIP_LZMA: - # Compressed data includes an end-of-stream (EOS) marker - zinfo.flag_bits |= 0x02 - - self._writecheck(zinfo) - self._didModify = True - - if isdir: - zinfo.file_size = 0 - zinfo.compress_size = 0 - zinfo.CRC = 0 + with self._lock: + self.fp.seek(self.start_dir, 0) + zinfo.header_offset = self.fp.tell() # Start of header bytes + if zinfo.compress_type == ZIP_LZMA: + # Compressed data includes an end-of-stream (EOS) marker + zinfo.flag_bits |= 0x02 + + self._writecheck(zinfo) + self._didModify = True + + if isdir: + zinfo.file_size = 0 + zinfo.compress_size = 0 + zinfo.CRC = 0 + zinfo.external_attr |= 0x10 # MS-DOS directory flag + self.filelist.append(zinfo) + self.NameToInfo[zinfo.filename] = zinfo + self.fp.write(zinfo.FileHeader(False)) + self.start_dir = self.fp.tell() + return + + cmpr = _get_compressor(zinfo.compress_type) + with open(filename, "rb") as fp: + # Must overwrite CRC and sizes with correct data later + zinfo.CRC = CRC = 0 + zinfo.compress_size = compress_size = 0 + # Compressed size can be larger than uncompressed size + zip64 = self._allowZip64 and \ + zinfo.file_size * 1.05 > ZIP64_LIMIT + self.fp.write(zinfo.FileHeader(zip64)) + file_size = 0 + while 1: + buf = fp.read(1024 * 8) + if not buf: + break + file_size = file_size + len(buf) + CRC = crc32(buf, CRC) & 0xffffffff + if cmpr: + buf = cmpr.compress(buf) + compress_size = compress_size + len(buf) + self.fp.write(buf) + if cmpr: + buf = cmpr.flush() + compress_size = compress_size + len(buf) + self.fp.write(buf) + zinfo.compress_size = compress_size + else: + zinfo.compress_size = file_size + zinfo.CRC = CRC + zinfo.file_size = file_size + if not zip64 and self._allowZip64: + if file_size > ZIP64_LIMIT: + raise RuntimeError('File size has increased during compressing') + if compress_size > ZIP64_LIMIT: + raise RuntimeError('Compressed size larger than uncompressed size') + # Seek backwards and write file header (which will now include + # correct CRC and file sizes) + self.start_dir = self.fp.tell() # Preserve current position in file + self.fp.seek(zinfo.header_offset, 0) + self.fp.write(zinfo.FileHeader(zip64)) + self.fp.seek(self.start_dir, 0) self.filelist.append(zinfo) self.NameToInfo[zinfo.filename] = zinfo - self.fp.write(zinfo.FileHeader(False)) - return - - cmpr = _get_compressor(zinfo.compress_type) - with open(filename, "rb") as fp: - # Must overwrite CRC and sizes with correct data later - zinfo.CRC = CRC = 0 - zinfo.compress_size = compress_size = 0 - # Compressed size can be larger than uncompressed size - zip64 = self._allowZip64 and \ - zinfo.file_size * 1.05 > ZIP64_LIMIT - self.fp.write(zinfo.FileHeader(zip64)) - file_size = 0 - while 1: - buf = fp.read(1024 * 8) - if not buf: - break - file_size = file_size + len(buf) - CRC = crc32(buf, CRC) & 0xffffffff - if cmpr: - buf = cmpr.compress(buf) - compress_size = compress_size + len(buf) - self.fp.write(buf) - if cmpr: - buf = cmpr.flush() - compress_size = compress_size + len(buf) - self.fp.write(buf) - zinfo.compress_size = compress_size - else: - zinfo.compress_size = file_size - zinfo.CRC = CRC - zinfo.file_size = file_size - if not zip64 and self._allowZip64: - if file_size > ZIP64_LIMIT: - raise RuntimeError('File size has increased during compressing') - if compress_size > ZIP64_LIMIT: - raise RuntimeError('Compressed size larger than uncompressed size') - # Seek backwards and write file header (which will now include - # correct CRC and file sizes) - position = self.fp.tell() # Preserve current position in file - self.fp.seek(zinfo.header_offset, 0) - self.fp.write(zinfo.FileHeader(zip64)) - self.fp.seek(position, 0) - self.filelist.append(zinfo) - self.NameToInfo[zinfo.filename] = zinfo def writestr(self, zinfo_or_arcname, data, compress_type=None): """Write a file into the archive. The contents is 'data', which @@ -1408,7 +1490,11 @@ def writestr(self, zinfo_or_arcname, data, compress_type=None): zinfo = ZipInfo(filename=zinfo_or_arcname, date_time=time.localtime(time.time())[:6]) zinfo.compress_type = self.compression - zinfo.external_attr = 0o600 << 16 + if zinfo.filename[-1] == '/': + zinfo.external_attr = 0o40775 << 16 # drwxrwxr-x + zinfo.external_attr |= 0x10 # MS-DOS directory flag + else: + zinfo.external_attr = 0o600 << 16 # ?rw------- else: zinfo = zinfo_or_arcname @@ -1417,36 +1503,46 @@ def writestr(self, zinfo_or_arcname, data, compress_type=None): "Attempt to write to ZIP archive that was already closed") zinfo.file_size = len(data) # Uncompressed size - zinfo.header_offset = self.fp.tell() # Start of header data - if compress_type is not None: - zinfo.compress_type = compress_type - if zinfo.compress_type == ZIP_LZMA: - # Compressed data includes an end-of-stream (EOS) marker - zinfo.flag_bits |= 0x02 - - self._writecheck(zinfo) - self._didModify = True - zinfo.CRC = crc32(data) & 0xffffffff # CRC-32 checksum - co = _get_compressor(zinfo.compress_type) - if co: - data = co.compress(data) + co.flush() - zinfo.compress_size = len(data) # Compressed size - else: - zinfo.compress_size = zinfo.file_size - zip64 = zinfo.file_size > ZIP64_LIMIT or \ - zinfo.compress_size > ZIP64_LIMIT - if zip64 and not self._allowZip64: - raise LargeZipFile("Filesize would require ZIP64 extensions") - self.fp.write(zinfo.FileHeader(zip64)) - self.fp.write(data) - if zinfo.flag_bits & 0x08: - # Write CRC and file sizes after the file data - fmt = ' ZIP64_LIMIT or \ + zinfo.compress_size > ZIP64_LIMIT + if zip64 and not self._allowZip64: + raise LargeZipFile("Filesize would require ZIP64 extensions") + self.fp.write(zinfo.FileHeader(zip64)) + self.fp.write(data) + if zinfo.flag_bits & 0x08: + # Write CRC and file sizes after the file data + fmt = ' ZIP64_LIMIT \ - or zinfo.compress_size > ZIP64_LIMIT: - extra.append(zinfo.file_size) - extra.append(zinfo.compress_size) - file_size = 0xffffffff - compress_size = 0xffffffff - else: - file_size = zinfo.file_size - compress_size = zinfo.compress_size - - if zinfo.header_offset > ZIP64_LIMIT: - extra.append(zinfo.header_offset) - header_offset = 0xffffffff - else: - header_offset = zinfo.header_offset - - extra_data = zinfo.extra - min_version = 0 - if extra: - # Append a ZIP64 field to the extra's - extra_data = struct.pack( - '= ZIP_FILECOUNT_LIMIT or - centDirOffset > ZIP64_LIMIT or - centDirSize > ZIP64_LIMIT): - # Need to write the ZIP64 end-of-archive records - zip64endrec = struct.pack( - structEndArchive64, stringEndArchive64, - 44, 45, 45, 0, 0, centDirCount, centDirCount, - centDirSize, centDirOffset) - self.fp.write(zip64endrec) - - zip64locrec = struct.pack( - structEndArchive64Locator, - stringEndArchive64Locator, 0, pos2, 1) - self.fp.write(zip64locrec) - centDirCount = min(centDirCount, 0xFFFF) - centDirSize = min(centDirSize, 0xFFFFFFFF) - centDirOffset = min(centDirOffset, 0xFFFFFFFF) - - endrec = struct.pack(structEndArchive, stringEndArchive, - 0, 0, centDirCount, centDirCount, - centDirSize, centDirOffset, len(self._comment)) - self.fp.write(endrec) - self.fp.write(self._comment) - self.fp.flush() + self.fp.seek(self.start_dir) + except (AttributeError, io.UnsupportedOperation): + # Some file-like objects can provide tell() but not seek() + pass + self._write_end_record() finally: fp = self.fp self.fp = None - if not self._filePassed: - fp.close() + self._fpclose(fp) + + def _write_end_record(self): + for zinfo in self.filelist: # write central directory + dt = zinfo.date_time + dosdate = (dt[0] - 1980) << 9 | dt[1] << 5 | dt[2] + dostime = dt[3] << 11 | dt[4] << 5 | (dt[5] // 2) + extra = [] + if zinfo.file_size > ZIP64_LIMIT \ + or zinfo.compress_size > ZIP64_LIMIT: + extra.append(zinfo.file_size) + extra.append(zinfo.compress_size) + file_size = 0xffffffff + compress_size = 0xffffffff + else: + file_size = zinfo.file_size + compress_size = zinfo.compress_size + + if zinfo.header_offset > ZIP64_LIMIT: + extra.append(zinfo.header_offset) + header_offset = 0xffffffff + else: + header_offset = zinfo.header_offset + + extra_data = zinfo.extra + min_version = 0 + if extra: + # Append a ZIP64 field to the extra's + extra_data = struct.pack( + ' ZIP_FILECOUNT_LIMIT: + requires_zip64 = "Files count" + elif centDirOffset > ZIP64_LIMIT: + requires_zip64 = "Central directory offset" + elif centDirSize > ZIP64_LIMIT: + requires_zip64 = "Central directory size" + if requires_zip64: + # Need to write the ZIP64 end-of-archive records + if not self._allowZip64: + raise LargeZipFile(requires_zip64 + + " would require ZIP64 extensions") + zip64endrec = struct.pack( + structEndArchive64, stringEndArchive64, + 44, 45, 45, 0, 0, centDirCount, centDirCount, + centDirSize, centDirOffset) + self.fp.write(zip64endrec) + + zip64locrec = struct.pack( + structEndArchive64Locator, + stringEndArchive64Locator, 0, pos2, 1) + self.fp.write(zip64locrec) + centDirCount = min(centDirCount, 0xFFFF) + centDirSize = min(centDirSize, 0xFFFFFFFF) + centDirOffset = min(centDirOffset, 0xFFFFFFFF) + + endrec = struct.pack(structEndArchive, stringEndArchive, + 0, 0, centDirCount, centDirCount, + centDirSize, centDirOffset, len(self._comment)) + self.fp.write(endrec) + self.fp.write(self._comment) + self.fp.flush() + + def _fpclose(self, fp): + assert self._fileRefCnt > 0 + self._fileRefCnt -= 1 + if not self._fileRefCnt and not self._filePassed: + fp.close() class PyZipFile(ZipFile): @@ -1760,18 +1875,7 @@ def main(args = None): sys.exit(1) with ZipFile(args[1], 'r') as zf: - out = args[2] - for path in zf.namelist(): - if path.startswith('./'): - tgt = os.path.join(out, path[2:]) - else: - tgt = os.path.join(out, path) - - tgtdir = os.path.dirname(tgt) - if not os.path.exists(tgtdir): - os.makedirs(tgtdir) - with open(tgt, 'wb') as fp: - fp.write(zf.read(path)) + zf.extractall(args[2]) elif args[0] == '-c': if len(args) < 3: @@ -1782,14 +1886,21 @@ def addToZip(zf, path, zippath): if os.path.isfile(path): zf.write(path, zippath, ZIP_DEFLATED) elif os.path.isdir(path): + if zippath: + zf.write(path, zippath) for nm in os.listdir(path): addToZip(zf, os.path.join(path, nm), os.path.join(zippath, nm)) # else: ignore with ZipFile(args[1], 'w') as zf: - for src in args[2:]: - addToZip(zf, src, os.path.basename(src)) + for path in args[2:]: + zippath = os.path.basename(path) + if not zippath: + zippath = os.path.basename(os.path.dirname(path)) + if zippath in ('', os.curdir, os.pardir): + zippath = '' + addToZip(zf, path, zippath) if __name__ == "__main__": main() diff --git a/Mac/BuildScript/README.txt b/Mac/BuildScript/README.txt index 0a6b54455764..3ced06643188 100644 --- a/Mac/BuildScript/README.txt +++ b/Mac/BuildScript/README.txt @@ -12,9 +12,9 @@ For Python 3.4.0, PSF practice is to build two installer variants for each release. 1. 32-bit-only, i386 and PPC universal, capable on running on all machines - supported by Mac OS X 10.5 through (at least) 10.8:: + supported by Mac OS X 10.5 through (at least) 10.9:: - /usr/bin/python build-installer.py \ + /path/to/bootstrap/python2.7 build-installer.py \ --sdk-path=/Developer/SDKs/MacOSX10.5.sdk \ --universal-archs=32-bit \ --dep-target=10.5 @@ -22,14 +22,14 @@ for each release. - builds the following third-party libraries * NCurses 5.9 (http://bugs.python.org/issue15037) - * SQLite 3.8.1 + * SQLite 3.8.3.1 * XZ 5.0.5 - uses system-supplied versions of third-party libraries * readline module links with Apple BSD editline (libedit) - - requires ActiveState ``Tcl/Tk 8.4`` (currently 8.4.19) to be installed for building + - requires ActiveState ``Tcl/Tk 8.4`` (currently 8.4.20) to be installed for building - recommended build environment: @@ -38,7 +38,8 @@ for each release. * ``MacOSX10.5`` SDK * ``MACOSX_DEPLOYMENT_TARGET=10.5`` * Apple ``gcc-4.2`` - * system Python 2.5 for documentation build with Sphinx + * bootstrap non-framework Python 2.7 for documentation build with + Sphinx (as of 3.4.1) - alternate build environments: @@ -48,7 +49,7 @@ for each release. 2. 64-bit / 32-bit, x86_64 and i386 universal, for OS X 10.6 (and later):: - /usr/bin/python build-installer.py \ + /path/to/bootstrap/python2.7 build-installer.py \ --sdk-path=/Developer/SDKs/MacOSX10.6.sdk \ --universal-archs=intel \ --dep-target=10.6 @@ -56,14 +57,14 @@ for each release. - builds the following third-party libraries * NCurses 5.9 (http://bugs.python.org/issue15037) - * SQLite 3.8.1 + * SQLite 3.8.3.1 * XZ 5.0.5 - uses system-supplied versions of third-party libraries * readline module links with Apple BSD editline (libedit) - - requires ActiveState Tcl/Tk 8.5.15 (or later) to be installed for building + - requires ActiveState Tcl/Tk 8.5.15.1 (or later) to be installed for building - recommended build environment: @@ -72,7 +73,8 @@ for each release. * ``MacOSX10.6`` SDK * ``MACOSX_DEPLOYMENT_TARGET=10.6`` * Apple ``gcc-4.2`` - * system Python 2.6 for documentation build with Sphinx + * bootstrap non-framework Python 2.7 for documentation build with + Sphinx (as of 3.4.1) - alternate build environments: @@ -82,10 +84,10 @@ for each release. considered a migration aid by Apple and is not likely to be fixed, its use should be avoided. The other compiler, ``clang``, has been undergoing rapid development. While it appears to have become - production-ready in the most recent Xcode 4 releases (Xcode 4.6.3 - as of this writing), there are still some open issues when - building Python and there has not yet been the level of exposure in - production environments that the Xcode 3 gcc-4.2 compiler has had. + production-ready in the most recent Xcode 5 releases, the versions + available on the deprecated Xcode 4.x for 10.6 were early releases + and did not receive the level of exposure in production environments + that the Xcode 3 gcc-4.2 compiler has had. * For Python 2.7.x and 3.2.x, the 32-bit-only installer was configured to @@ -111,7 +113,7 @@ for each release. * Zlib 1.2.3 * Oracle Sleepycat DB 4.8 (Python 2.x only) - - requires ActiveState ``Tcl/Tk 8.4`` (currently 8.4.19) to be installed for building + - requires ActiveState ``Tcl/Tk 8.4`` (currently 8.4.20) to be installed for building - recommended build environment: @@ -137,7 +139,13 @@ General Prerequisites interfere with the build. * The documentation for the release is built using Sphinx - because it is included in the installer. + because it is included in the installer. For 2.7.x and 3.x.x up to and + including 3.4.0, the ``Doc/Makefile`` uses ``svn`` to download repos of + ``Sphinx`` and its dependencies. Beginning with 3.4.1, the ``Doc/Makefile`` + assumes there is an externally-provided ``sphinx-build`` and requires at + least Python 2.6 to run. Because of this, it is no longer possible to + build a 3.4.1 or later installer on OS X 10.5 using the Apple-supplied + Python 2.5. * It is safest to start each variant build with an empty source directory populated with a fresh copy of the untarred source. @@ -195,8 +203,8 @@ Ideally, the resulting binaries should be installed and the test suite run on all supported OS X releases and architectures. As a practical matter, that is generally not possible. At a minimum, variant 1 should be run on a PPC G4 system with OS X 10.5 and at least one Intel system running OS X -10.8, 10.7, 10.6, or 10.5. Variant 2 should be run on 10.8, 10.7, and 10.6 -systems in both 32-bit and 64-bit modes.:: +10.9, 10.8, 10.7, 10.6, or 10.5. Variant 2 should be run on 10.9, 10.8, +10.7, and 10.6 systems in both 32-bit and 64-bit modes.:: /usr/local/bin/pythonn.n -m test -w -u all,-largefile /usr/local/bin/pythonn.n-32 -m test -w -u all @@ -207,7 +215,7 @@ to be generated at several points during a test run. These are normal during testing and can be ignored. It is also recommend to launch IDLE and verify that it is at least -functional. Double-click on the IDLE app icon in ``/Applications/Pythonn.n``. +functional. Double-click on the IDLE app icon in ``/Applications/Python n.n``. It should also be tested from the command line:: /usr/local/bin/idlen.n diff --git a/Mac/BuildScript/build-installer.py b/Mac/BuildScript/build-installer.py index f01258731eb7..16576d579288 100755 --- a/Mac/BuildScript/build-installer.py +++ b/Mac/BuildScript/build-installer.py @@ -8,7 +8,9 @@ Please ensure that this script keeps working with Python 2.5, to avoid bootstrap issues (/usr/bin/python is Python 2.5 on OSX 10.5). Sphinx, which is used to build the documentation, currently requires at least -Python 2.4. +Python 2.4. However, as of Python 3.4.1, Doc builds require an external +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 @@ -21,8 +23,8 @@ 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 svn (for the documentation -build). +(2.5 is needed for Python parser updates), hg, 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. """ @@ -60,11 +62,16 @@ def shellQuote(value): return "'%s'"%(value.replace("'", "'\"'\"'")) def grepValue(fn, variable): + """ + Return the unquoted value of a variable from a file.. + QUOTED_VALUE='quotes' -> str('quotes') + UNQUOTED_VALUE=noquotes -> str('noquotes') + """ variable = variable + '=' for ln in open(fn, 'r'): if ln.startswith(variable): value = ln[len(variable):].strip() - return value[1:-1] + return value.strip("\"'") raise RuntimeError("Cannot find variable %s" % variable[:-1]) _cache_getVersion = None @@ -76,9 +83,6 @@ def getVersion(): os.path.join(SRCDIR, 'configure'), 'PACKAGE_VERSION') return _cache_getVersion -def getVersionTuple(): - return tuple([int(n) for n in getVersion().split('.')]) - def getVersionMajorMinor(): return tuple([int(n) for n in getVersion().split('.', 2)]) @@ -95,6 +99,9 @@ def getFullVersion(): return _cache_getFullVersion raise RuntimeError("Cannot find full version??") +FW_PREFIX = ["Library", "Frameworks", "Python.framework"] +FW_VERSION_PREFIX = "--undefined--" # initialized in parseOptions + # The directory we'll use to create the build (will be erased and recreated) WORKDIR = "/tmp/_py" @@ -148,19 +155,21 @@ def getFullVersion(): # $MACOSX_DEPLOYMENT_TARGET -> minimum OS X level DEPTARGET = '10.3' -target_cc_map = { +def getDeptargetTuple(): + return tuple([int(n) for n in DEPTARGET.split('.')[0:2]]) + +def getTargetCompilers(): + target_cc_map = { '10.3': ('gcc-4.0', 'g++-4.0'), '10.4': ('gcc-4.0', 'g++-4.0'), '10.5': ('gcc-4.2', 'g++-4.2'), '10.6': ('gcc-4.2', 'g++-4.2'), - '10.7': ('clang', 'clang++'), - '10.8': ('clang', 'clang++'), - '10.9': ('clang', 'clang++'), -} + } + return target_cc_map.get(DEPTARGET, ('clang', 'clang++') ) -CC, CXX = target_cc_map[DEPTARGET] +CC, CXX = getTargetCompilers() -PYTHON_3 = getVersionTuple() >= (3, 0) +PYTHON_3 = getVersionMajorMinor() >= (3, 0) USAGE = textwrap.dedent("""\ Usage: build_python [options] @@ -184,6 +193,10 @@ def getFullVersion(): # '/Library/Frameworks/Tk.framework/Versions/8.5/Tk'] EXPECTED_SHARED_LIBS = {} +# List of names of third party software built with this installer. +# The names will be inserted into the rtf version of the License. +THIRD_PARTY_LIBS = [] + # Instructions for building libraries that are necessary for building a # batteries included python. # [The recipes are defined here for convenience but instantiated later after @@ -191,10 +204,53 @@ def getFullVersion(): def library_recipes(): result = [] - LT_10_5 = bool(DEPTARGET < '10.5') + LT_10_5 = bool(getDeptargetTuple() < (10, 5)) + + if getDeptargetTuple() < (10, 6): + # The OpenSSL libs shipped with OS X 10.5 and earlier are + # hopelessly out-of-date and do not include Apple's tie-in to + # the root certificates in the user and system keychains via TEA + # that was introduced in OS X 10.6. Note that this applies to + # programs built and linked with a 10.5 SDK even when run on + # newer versions of OS X. + # + # Dealing with CAs is messy. For now, just supply a + # local libssl and libcrypto for the older installer variants + # (e.g. the python.org 10.5+ 32-bit-only installer) that use the + # same default ssl certfile location as the system libs do: + # /System/Library/OpenSSL/cert.pem + # Then at least TLS connections can be negotiated with sites that + # use sha-256 certs like python.org, assuming the proper CA certs + # have been supplied. The default CA cert management issues for + # 10.5 and earlier builds are the same as before, other than it is + # now more obvious with cert checking enabled by default in the + # standard library. + # + # For builds with 10.6+ SDKs, continue to use the deprecated but + # less out-of-date Apple 0.9.8 libs for now. While they are less + # secure than using an up-to-date 1.0.1 version, doing so + # avoids the big problems of forcing users to have to manage + # default CAs themselves, thanks to the Apple libs using private TEA + # APIs for cert validation from keychains if validation using the + # standard OpenSSL locations (/System/Library/OpenSSL, normally empty) + # fails. + + result.extend([ + dict( + name="OpenSSL 1.0.1l", + url="https://www.openssl.org/source/openssl-1.0.1l.tar.gz", + checksum='cdb22925fc9bc97ccbf1e007661f2aa6', + patches=[ + "openssl_sdk_makedepend.patch", + ], + buildrecipe=build_universal_openssl, + configure=None, + install=None, + ), + ]) # Disable for now - if (DEPTARGET > '10.5') and (getVersionTuple() >= (3, 5)): + if False: # if getDeptargetTuple() > (10, 5): result.extend([ dict( name="Tcl 8.5.15", @@ -235,7 +291,7 @@ def library_recipes(): ), ]) - if getVersionTuple() >= (3, 3): + if PYTHON_3: result.extend([ dict( name="XZ 5.0.5", @@ -283,9 +339,9 @@ def library_recipes(): ), ), dict( - name="SQLite 3.8.1", - url="http://www.sqlite.org/2013/sqlite-autoconf-3080100.tar.gz", - checksum='8b5a0a02dfcb0c7daf90856a5cfd485a', + name="SQLite 3.8.3.1", + url="http://www.sqlite.org/2014/sqlite-autoconf-3080301.tar.gz", + checksum='509ff98d8dc9729b618b7e96612079c6', extra_cflags=('-Os ' '-DSQLITE_ENABLE_FTS4 ' '-DSQLITE_ENABLE_FTS3_PARENTHESIS ' @@ -302,7 +358,7 @@ def library_recipes(): ), ]) - if DEPTARGET < '10.5': + if getDeptargetTuple() < (10, 5): result.extend([ dict( name="Bzip2 1.0.6", @@ -365,7 +421,6 @@ def library_recipes(): # Instructions for building packages inside the .mpkg. def pkg_recipes(): unselected_for_python3 = ('selected', 'unselected')[PYTHON_3] - unselected_for_lt_python34 = ('selected', 'unselected')[getVersionTuple() < (3, 4)] result = [ dict( name="PythonFramework", @@ -434,28 +489,24 @@ def pkg_recipes(): topdir="/Library/Frameworks/Python.framework", source="/empty-dir", required=False, - selected=unselected_for_lt_python34, + selected='selected', + ), + dict( + name="PythonInstallPip", + long_name="Install or upgrade pip", + readme="""\ + This package installs (or upgrades from an earlier version) + pip, a tool for installing and managing Python packages. + """, + postflight="scripts/postflight.ensurepip", + topdir="/Library/Frameworks/Python.framework", + source="/empty-dir", + required=False, + selected='selected', ), ] - if getVersionTuple() >= (3, 4): - result.append( - dict( - name="PythonInstallPip", - long_name="Install or upgrade pip", - readme="""\ - This package installs (or upgrades from an earlier version) - pip, a tool for installing and managing Python packages. - """, - postflight="scripts/postflight.ensurepip", - topdir="/Library/Frameworks/Python.framework", - source="/empty-dir", - required=False, - selected='selected', - ) - ) - - if DEPTARGET < '10.4' and not PYTHON_3: + if getDeptargetTuple() < (10, 4) and not PYTHON_3: result.append( dict( name="PythonSystemFixes", @@ -607,7 +658,10 @@ 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. + # You may have to create links in /usr/bin for them. + runCommand('hg --version') + runCommand('sphinx-build --version') def parseOptions(args=None): """ @@ -615,6 +669,7 @@ def parseOptions(args=None): """ global WORKDIR, DEPSRC, SDKPATH, SRCDIR, DEPTARGET global UNIVERSALOPTS, UNIVERSALARCHS, ARCHLIST, CC, CXX + global FW_VERSION_PREFIX if args is None: args = sys.argv[1:] @@ -672,21 +727,23 @@ def parseOptions(args=None): SDKPATH=os.path.abspath(SDKPATH) DEPSRC=os.path.abspath(DEPSRC) - CC, CXX=target_cc_map[DEPTARGET] - - print("Settings:") - print(" * Source directory:", SRCDIR) - print(" * Build directory: ", WORKDIR) - print(" * SDK location: ", SDKPATH) - print(" * Third-party source:", DEPSRC) - print(" * Deployment target:", DEPTARGET) - print(" * Universal architectures:", ARCHLIST) - print(" * C compiler:", CC) - print(" * C++ compiler:", CXX) - print("") - + CC, CXX = getTargetCompilers() + FW_VERSION_PREFIX = FW_PREFIX[:] + ["Versions", getVersion()] + print("-- Settings:") + print(" * Source directory: %s" % SRCDIR) + print(" * Build directory: %s" % WORKDIR) + print(" * SDK location: %s" % SDKPATH) + print(" * Third-party source: %s" % DEPSRC) + print(" * Deployment target: %s" % DEPTARGET) + print(" * Universal archs: %s" % str(ARCHLIST)) + print(" * C compiler: %s" % CC) + print(" * C++ compiler: %s" % CXX) + print("") + print(" -- Building a Python %s framework at patch level %s" + % (getVersion(), getFullVersion())) + print("") def extractArchive(builddir, archiveName): """ @@ -778,6 +835,132 @@ def verifyThirdPartyFile(url, checksum, fname): % (shellQuote(fname), checksum) ): fatal('MD5 checksum mismatch for file %s' % fname) +def build_universal_openssl(basedir, archList): + """ + Special case build recipe for universal build of openssl. + + The upstream OpenSSL build system does not directly support + OS X universal builds. We need to build each architecture + separately then lipo them together into fat libraries. + """ + + # OpenSSL fails to build with Xcode 2.5 (on OS X 10.4). + # If we are building on a 10.4.x or earlier system, + # unilaterally disable assembly code building to avoid the problem. + no_asm = int(platform.release().split(".")[0]) < 9 + + def build_openssl_arch(archbase, arch): + "Build one architecture of openssl" + arch_opts = { + "i386": ["darwin-i386-cc"], + "x86_64": ["darwin64-x86_64-cc", "enable-ec_nistp_64_gcc_128"], + "ppc": ["darwin-ppc-cc"], + "ppc64": ["darwin64-ppc-cc"], + } + configure_opts = [ + "no-krb5", + "no-idea", + "no-mdc2", + "no-rc5", + "no-zlib", + "enable-tlsext", + "no-ssl2", + "no-ssl3", + "no-ssl3-method", + # "enable-unit-test", + "shared", + "--install_prefix=%s"%shellQuote(archbase), + "--prefix=%s"%os.path.join("/", *FW_VERSION_PREFIX), + "--openssldir=/System/Library/OpenSSL", + ] + if no_asm: + configure_opts.append("no-asm") + runCommand(" ".join(["perl", "Configure"] + + arch_opts[arch] + configure_opts)) + runCommand("make depend OSX_SDK=%s" % SDKPATH) + runCommand("make all OSX_SDK=%s" % SDKPATH) + runCommand("make install_sw OSX_SDK=%s" % SDKPATH) + # runCommand("make test") + return + + srcdir = os.getcwd() + universalbase = os.path.join(srcdir, "..", + os.path.basename(srcdir) + "-universal") + os.mkdir(universalbase) + archbasefws = [] + for arch in archList: + # fresh copy of the source tree + archsrc = os.path.join(universalbase, arch, "src") + shutil.copytree(srcdir, archsrc, symlinks=True) + # install base for this arch + archbase = os.path.join(universalbase, arch, "root") + os.mkdir(archbase) + # Python framework base within install_prefix: + # the build will install into this framework.. + # This is to ensure that the resulting shared libs have + # the desired real install paths built into them. + archbasefw = os.path.join(archbase, *FW_VERSION_PREFIX) + + # build one architecture + os.chdir(archsrc) + build_openssl_arch(archbase, arch) + os.chdir(srcdir) + archbasefws.append(archbasefw) + + # copy arch-independent files from last build into the basedir framework + basefw = os.path.join(basedir, *FW_VERSION_PREFIX) + shutil.copytree( + os.path.join(archbasefw, "include", "openssl"), + os.path.join(basefw, "include", "openssl") + ) + + shlib_version_number = grepValue(os.path.join(archsrc, "Makefile"), + "SHLIB_VERSION_NUMBER") + # e.g. -> "1.0.0" + libcrypto = "libcrypto.dylib" + libcrypto_versioned = libcrypto.replace(".", "."+shlib_version_number+".") + # e.g. -> "libcrypto.1.0.0.dylib" + libssl = "libssl.dylib" + libssl_versioned = libssl.replace(".", "."+shlib_version_number+".") + # e.g. -> "libssl.1.0.0.dylib" + + try: + os.mkdir(os.path.join(basefw, "lib")) + except OSError: + pass + + # merge the individual arch-dependent shared libs into a fat shared lib + archbasefws.insert(0, basefw) + for (lib_unversioned, lib_versioned) in [ + (libcrypto, libcrypto_versioned), + (libssl, libssl_versioned) + ]: + runCommand("lipo -create -output " + + " ".join(shellQuote( + os.path.join(fw, "lib", lib_versioned)) + for fw in archbasefws)) + # and create an unversioned symlink of it + os.symlink(lib_versioned, os.path.join(basefw, "lib", lib_unversioned)) + + # Create links in the temp include and lib dirs that will be injected + # into the Python build so that setup.py can find them while building + # and the versioned links so that the setup.py post-build import test + # does not fail. + relative_path = os.path.join("..", "..", "..", *FW_VERSION_PREFIX) + for fn in [ + ["include", "openssl"], + ["lib", libcrypto], + ["lib", libssl], + ["lib", libcrypto_versioned], + ["lib", libssl_versioned], + ]: + os.symlink( + os.path.join(relative_path, *fn), + os.path.join(basedir, "usr", "local", *fn) + ) + + return + def buildRecipe(recipe, basedir, archList): """ Build software using a recipe. This function does the @@ -787,8 +970,10 @@ def buildRecipe(recipe, basedir, archList): curdir = os.getcwd() name = recipe['name'] + THIRD_PARTY_LIBS.append(name) url = recipe['url'] configure = recipe.get('configure', './configure') + buildrecipe = recipe.get('buildrecipe', None) install = recipe.get('install', 'make && make install DESTDIR=%s'%( shellQuote(basedir))) @@ -860,7 +1045,7 @@ def buildRecipe(recipe, basedir, archList): ' -arch '.join(archList), shellQuote(SDKPATH)[1:-1], shellQuote(basedir)[1:-1],), - "LDFLAGS=-mmacosx-version-min=%s -syslibroot,%s -L%s/usr/local/lib -arch %s"%( + "LDFLAGS=-mmacosx-version-min=%s -isysroot %s -L%s/usr/local/lib -arch %s"%( DEPTARGET, shellQuote(SDKPATH)[1:-1], shellQuote(basedir)[1:-1], @@ -886,8 +1071,13 @@ def buildRecipe(recipe, basedir, archList): print("Running configure for %s"%(name,)) runCommand(' '.join(configure_args) + ' 2>&1') - print("Running install for %s"%(name,)) - runCommand('{ ' + install + ' ;} 2>&1') + if buildrecipe is not None: + # call special-case build recipe, e.g. for openssl + buildrecipe(basedir, archList) + + if install is not None: + print("Running install for %s"%(name,)) + runCommand('{ ' + install + ' ;} 2>&1') print("Done %s"%(name,)) print("") @@ -920,8 +1110,10 @@ def buildPythonDocs(): docdir = os.path.join(rootDir, 'pydocs') curDir = os.getcwd() os.chdir(buildDir) - runCommand('make update') - runCommand("make html PYTHON='%s'" % os.path.abspath(sys.executable)) + # The Doc build changed for 3.4 (technically, for 3.4.1) and for 2.7.9 + runCommand('make clean') + # Assume sphinx-build is on our PATH, checked in checkEnvironment + runCommand('make html') os.chdir(curDir) if not os.path.exists(docdir): os.mkdir(docdir) @@ -967,10 +1159,13 @@ def buildPython(): shellQuote(os.path.join(SRCDIR, 'configure')), shellQuote(SDKPATH), UNIVERSALARCHS, (' ', '--with-computed-gotos ')[PYTHON_3], - (' ', '--without-ensurepip ')[getVersionTuple() >= (3, 4)], + (' ', '--without-ensurepip ')[PYTHON_3], shellQuote(WORKDIR)[1:-1], shellQuote(WORKDIR)[1:-1])) + print("Running make touch") + runCommand("make touch") + print("Running make") runCommand("make") @@ -1138,6 +1333,7 @@ def patchFile(inPath, outPath): data = data.replace('$MACOSX_DEPLOYMENT_TARGET', ''.join((DEPTARGET, ' or later'))) data = data.replace('$ARCHITECTURES', ", ".join(universal_opts_map[UNIVERSALARCHS])) data = data.replace('$INSTALL_SIZE', installSize()) + data = data.replace('$THIRD_PARTY_LIBS', "\\\n".join(THIRD_PARTY_LIBS)) # This one is not handy as a template variable data = data.replace('$PYTHONFRAMEWORKINSTALLDIR', '/Library/Frameworks/Python.framework') @@ -1146,7 +1342,9 @@ def patchFile(inPath, outPath): fp.close() def patchScript(inPath, outPath): + major, minor = getVersionMajorMinor() data = fileContents(inPath) + data = data.replace('@PYMAJOR@', str(major)) data = data.replace('@PYVER@', getVersion()) fp = open(outPath, 'w') fp.write(data) @@ -1318,8 +1516,6 @@ def buildInstaller(): else: patchFile(os.path.join('resources', fn), os.path.join(rsrcDir, fn)) - shutil.copy("../../LICENSE", os.path.join(rsrcDir, 'License.txt')) - def installSize(clear=False, _saved=[]): if clear: @@ -1427,12 +1623,14 @@ def main(): # Prepare the applications folder - fn = os.path.join(WORKDIR, "_root", "Applications", - "Python %s"%(getVersion(),), "Update Shell Profile.command") - patchScript("scripts/postflight.patch-profile", fn) - folder = os.path.join(WORKDIR, "_root", "Applications", "Python %s"%( getVersion(),)) + fn = os.path.join(folder, "License.rtf") + patchFile("resources/License.rtf", fn) + fn = os.path.join(folder, "ReadMe.rtf") + patchFile("resources/ReadMe.rtf", fn) + fn = os.path.join(folder, "Update Shell Profile.command") + patchScript("scripts/postflight.patch-profile", fn) os.chmod(folder, STAT_0o755) setIcon(folder, "../Icons/Python Folder.icns") @@ -1440,10 +1638,12 @@ def main(): buildInstaller() # And copy the readme into the directory containing the installer - patchFile('resources/ReadMe.txt', os.path.join(WORKDIR, 'installer', 'ReadMe.txt')) + patchFile('resources/ReadMe.rtf', + os.path.join(WORKDIR, 'installer', 'ReadMe.rtf')) # Ditto for the license file. - shutil.copy('../../LICENSE', os.path.join(WORKDIR, 'installer', 'License.txt')) + patchFile('resources/License.rtf', + os.path.join(WORKDIR, 'installer', 'License.rtf')) fp = open(os.path.join(WORKDIR, 'installer', 'Build.txt'), 'w') fp.write("# BUILD INFO\n") diff --git a/Mac/BuildScript/openssl_sdk_makedepend.patch b/Mac/BuildScript/openssl_sdk_makedepend.patch new file mode 100644 index 000000000000..a72f5a395dcf --- /dev/null +++ b/Mac/BuildScript/openssl_sdk_makedepend.patch @@ -0,0 +1,50 @@ +# openssl_sdk_makedepend.patch +# +# using openssl 1.0.1k +# +# - support building with an OS X SDK +# - allow "make depend" to use compilers with names other than "gcc" + +diff Configure + +diff -r 99ae439a07f1 Configure +--- a/Configure Fri Jan 09 12:50:43 2015 -0800 ++++ b/Configure Fri Jan 09 12:53:52 2015 -0800 +@@ -577,11 +577,11 @@ + + ##### MacOS X (a.k.a. Rhapsody or Darwin) setup + "rhapsody-ppc-cc","cc:-O3 -DB_ENDIAN::(unknown):MACOSX_RHAPSODY::BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${no_asm}::", +-"darwin-ppc-cc","cc:-arch ppc -O3 -DB_ENDIAN -Wa,-force_cpusubtype_ALL::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${ppc32_asm}:osx32:dlfcn:darwin-shared:-fPIC -fno-common:-arch ppc -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib", +-"darwin64-ppc-cc","cc:-arch ppc64 -O3 -DB_ENDIAN::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${ppc64_asm}:osx64:dlfcn:darwin-shared:-fPIC -fno-common:-arch ppc64 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib", +-"darwin-i386-cc","cc:-arch i386 -O3 -fomit-frame-pointer -DL_ENDIAN::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:BN_LLONG RC4_INT RC4_CHUNK DES_UNROLL BF_PTR:".eval{my $asm=$x86_asm;$asm=~s/cast\-586\.o//;$asm}.":macosx:dlfcn:darwin-shared:-fPIC -fno-common:-arch i386 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib", +-"debug-darwin-i386-cc","cc:-arch i386 -g3 -DL_ENDIAN::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:BN_LLONG RC4_INT RC4_CHUNK DES_UNROLL BF_PTR:${x86_asm}:macosx:dlfcn:darwin-shared:-fPIC -fno-common:-arch i386 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib", +-"darwin64-x86_64-cc","cc:-arch x86_64 -O3 -DL_ENDIAN -Wall::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL:".eval{my $asm=$x86_64_asm;$asm=~s/rc4\-[^:]+//;$asm}.":macosx:dlfcn:darwin-shared:-fPIC -fno-common:-arch x86_64 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib", ++"darwin-ppc-cc","cc:-arch ppc -isysroot \$(OSX_SDK) -O3 -DB_ENDIAN -Wa,-force_cpusubtype_ALL::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${ppc32_asm}:osx32:dlfcn:darwin-shared:-fPIC -fno-common:-arch ppc -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib", ++"darwin64-ppc-cc","cc:-arch ppc64 -isysroot \$(OSX_SDK) -O3 -DB_ENDIAN::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${ppc64_asm}:osx64:dlfcn:darwin-shared:-fPIC -fno-common:-arch ppc64 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib", ++"darwin-i386-cc","cc:-arch i386 -isysroot \$(OSX_SDK) -O3 -fomit-frame-pointer -DL_ENDIAN::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:BN_LLONG RC4_INT RC4_CHUNK DES_UNROLL BF_PTR:".eval{my $asm=$x86_asm;$asm=~s/cast\-586\.o//;$asm}.":macosx:dlfcn:darwin-shared:-fPIC -fno-common:-arch i386 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib", ++"debug-darwin-i386-cc","cc:-arch i386 -isysroot \$(OSX_SDK) -g3 -DL_ENDIAN::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:BN_LLONG RC4_INT RC4_CHUNK DES_UNROLL BF_PTR:${x86_asm}:macosx:dlfcn:darwin-shared:-fPIC -fno-common:-arch i386 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib", ++"darwin64-x86_64-cc","cc:-arch x86_64 -isysroot \$(OSX_SDK) -O3 -DL_ENDIAN -Wall::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL:".eval{my $asm=$x86_64_asm;$asm=~s/rc4\-[^:]+//;$asm}.":macosx:dlfcn:darwin-shared:-fPIC -fno-common:-arch x86_64 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib", + "debug-darwin-ppc-cc","cc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG -DB_ENDIAN -g -Wall -O::-D_REENTRANT:MACOSX::BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${ppc32_asm}:osx32:dlfcn:darwin-shared:-fPIC:-dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib", + # iPhoneOS/iOS + "iphoneos-cross","llvm-gcc:-O3 -isysroot \$(CROSS_TOP)/SDKs/\$(CROSS_SDK) -fomit-frame-pointer -fno-common::-D_REENTRANT:iOS:-Wl,-search_paths_first%:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${no_asm}:dlfcn:darwin-shared:-fPIC -fno-common:-dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib", +@@ -1629,7 +1629,7 @@ + s/^CC=.*$/CC= $cc/; + s/^AR=\s*ar/AR= $ar/; + s/^RANLIB=.*/RANLIB= $ranlib/; +- s/^MAKEDEPPROG=.*$/MAKEDEPPROG= $cc/ if $cc eq "gcc"; ++ s/^MAKEDEPPROG=.*$/MAKEDEPPROG= $cc/; + } + s/^CFLAG=.*$/CFLAG= $cflags/; + s/^DEPFLAG=.*$/DEPFLAG=$depflags/; +diff -r 99ae439a07f1 util/domd +--- a/util/domd Fri Jan 09 12:50:43 2015 -0800 ++++ b/util/domd Fri Jan 09 12:53:52 2015 -0800 +@@ -14,7 +14,7 @@ + cp Makefile Makefile.save + # fake the presence of Kerberos + touch $TOP/krb5.h +-if expr "$MAKEDEPEND" : '.*gcc$' > /dev/null; then ++if true ; then # was: if expr "$MAKEDEPEND" : '.*gcc$' > /dev/null; then + args="" + while [ $# -gt 0 ]; do + if [ "$1" != "--" ]; then args="$args $1"; fi diff --git a/Mac/BuildScript/resources/License.rtf b/Mac/BuildScript/resources/License.rtf new file mode 100644 index 000000000000..fff4d5b97e52 --- /dev/null +++ b/Mac/BuildScript/resources/License.rtf @@ -0,0 +1,142 @@ +{\rtf1\ansi\ansicpg1252\cocoartf1343\cocoasubrtf160 +{\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fmodern\fcharset0 CourierNewPS-BoldMT;\f2\fmodern\fcharset0 CourierNewPSMT; +} +{\colortbl;\red255\green255\blue255;} +\margl1440\margr1440\vieww14620\viewh13380\viewkind0 +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural + +\f0\b\fs36 \cf0 \ul \ulc0 HISTORY AND LICENSE\ + +\fs24 \ +HISTORY OF THE SOFTWARE\ + +\b0 \ulnone \ +Python was created in the early 1990s by Guido van Rossum at Stichting Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands as a successor of a language called ABC. Guido remains Python's principal author, although it includes many contributions from others.\ +\ +In 1995, Guido continued his work on Python at the Corporation for National Research Initiatives (CNRI, see http://www.cnri.reston.va.us) in Reston, Virginia where he released several versions of the software.\ +\ +In May 2000, Guido and the Python core development team moved to BeOpen.com to form the BeOpen PythonLabs team. In October of the same year, the PythonLabs team moved to Digital Creations (now Zope Corporation, see http://www.zope.com). In 2001, the Python Software Foundation (PSF, see http://www.python.org/psf/) was formed, a non-profit organization created specifically to own Python-related Intellectual Property. Zope Corporation is a sponsoring member of the PSF.\ +\ +All Python releases are Open Source (see http://www.opensource.org for the Open Source Definition). Historically, most, but not all, Python releases have also been GPL-compatible; the table below summarizes the various releases.\ +\ + +\f1\b Release Derived Year Owner GPL-\ + from compatible?\ + +\f2\b0 \ +0.9.0 thru 1.2 n/a 1991-1995 CWI yes\ +1.3 thru 1.5.2 1.2 1995-1999 CNRI yes\ +1.6 1.5.2 2000 CNRI no\ +2.0 1.6 2000 BeOpen.com no\ +1.6.1 1.6 2001 CNRI no\ +2.1 2.0+1.6.1 2001 PSF no\ +2.0.1 2.0+1.6.1 2001 PSF yes\ +2.1.1 2.1+2.0.1 2001 PSF yes\ +2.1.2 2.1.1 2002 PSF yes\ +2.1.3 2.1.2 2002 PSF yes\ +2.2 and above 2.1.1 2001-now PSF yes\ + +\f0 \ + +\b Note: +\b0 GPL-compatible doesn't mean that we're distributing Python under the GPL. All Python licenses, unlike the GPL, let you distribute a modified version without making your changes open source. The GPL-compatible licenses make it possible to combine Python with other software that is released under the GPL; the others don't.\ +\ +Thanks to the many outside volunteers who have worked under Guido's direction to make these releases possible.\ +\ +\ + +\b \ul TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON\ + +\b0 \ulnone \ + +\b PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2\ + +\b0 \ +1. This LICENSE AGREEMENT is between the Python Software Foundation ("PSF"), and the Individual or Organization ("Licensee") accessing and otherwise using this software ("Python") in source or binary form and its associated documentation.\ +\ +2. Subject to the terms and conditions of this License Agreement, PSF hereby grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python alone or in any derivative version, provided, however, that PSF's License Agreement and PSF's notice of copyright, i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 Python Software Foundation; All Rights Reserved" are retained in Python alone or in any derivative version prepared by Licensee.\ +\ +3. In the event Licensee prepares a derivative work that is based on or incorporates Python or any part thereof, and wants to make the derivative work available to others as provided herein, then Licensee hereby agrees to include in any such work a brief summary of the changes made to Python.\ +\ +4. PSF is making Python available to Licensee on an "AS IS" basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.\ +\ +5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.\ +\ +6. This License Agreement will automatically terminate upon a material breach of its terms and conditions.\ +\ +7. Nothing in this License Agreement shall be deemed to create any relationship of agency, partnership, or joint venture between PSF and Licensee. This License Agreement does not grant permission to use PSF trademarks or trade name in a trademark sense to endorse or promote products or services of Licensee, or any third party.\ +\ +8. By copying, installing or otherwise using Python, Licensee agrees to be bound by the terms and conditions of this License Agreement.\ +\ +\ + +\b BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0\ + +\b0 \ +BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1\ +\ +1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the Individual or Organization ("Licensee") accessing and otherwise using this software in source or binary form and its associated documentation ("the Software").\ +\ +2. Subject to the terms and conditions of this BeOpen Python License Agreement, BeOpen hereby grants Licensee a non-exclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use the Software alone or in any derivative version, provided, however, that the BeOpen Python License is retained in the Software, alone or in any derivative version prepared by Licensee.\ +\ +3. BeOpen is making the Software available to Licensee on an "AS IS" basis. BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.\ +\ +4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.\ +\ +5. This License Agreement will automatically terminate upon a material breach of its terms and conditions.\ +\ +6. This License Agreement shall be governed by and interpreted in all respects by the law of the State of California, excluding conflict of law provisions. Nothing in this License Agreement shall be deemed to create any relationship of agency, partnership, or joint venture between BeOpen and Licensee. This License Agreement does not grant permission to use BeOpen trademarks or trade names in a trademark sense to endorse or promote products or services of Licensee, or any third party. As an exception, the "BeOpen Python" logos available at http://www.pythonlabs.com/logos.html may be used according to the permissions granted on that web page.\ +\ +7. By copying, installing or otherwise using the software, Licensee agrees to be bound by the terms and conditions of this License Agreement.\ +\ +\ + +\b CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1\ + +\b0 \ +1. This LICENSE AGREEMENT is between the Corporation for National Research Initiatives, having an office at 1895 Preston White Drive, Reston, VA 20191 ("CNRI"), and the Individual or Organization ("Licensee") accessing and otherwise using Python 1.6.1 software in source or binary form and its associated documentation.\ +\ +2. Subject to the terms and conditions of this License Agreement, CNRI hereby grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python 1.6.1 alone or in any derivative version, provided, however, that CNRI's License Agreement and CNRI's notice of copyright, i.e., "Copyright (c) 1995-2001 Corporation for National Research Initiatives; All Rights Reserved" are retained in Python 1.6.1 alone or in any derivative version prepared by Licensee. Alternately, in lieu of CNRI's License Agreement, Licensee may substitute the following text (omitting the quotes): "Python 1.6.1 is made available subject to the terms and conditions in CNRI's License Agreement. This Agreement together with Python 1.6.1 may be located on the Internet using the following unique, persistent identifier (known as a handle): 1895.22/1013. This Agreement may also be obtained from a proxy server on the Internet using the following URL: http://hdl.handle.net/1895.22/1013".\ +\ +3. In the event Licensee prepares a derivative work that is based on or incorporates Python 1.6.1 or any part thereof, and wants to make the derivative work available to others as provided herein, then Licensee hereby agrees to include in any such work a brief summary of the changes made to Python 1.6.1.\ +\ +4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS" basis. CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.\ +\ +5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON 1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.\ +\ +6. This License Agreement will automatically terminate upon a material breach of its terms and conditions.\ +\ +7. This License Agreement shall be governed by the federal intellectual property law of the United States, including without limitation the federal copyright law, and, to the extent such U.S. federal law does not apply, by the law of the Commonwealth of Virginia, excluding Virginia's conflict of law provisions. Notwithstanding the foregoing, with regard to derivative works based on Python 1.6.1 that incorporate non-separable material that was previously distributed under the GNU General Public License (GPL), the law of the Commonwealth of Virginia shall govern this License Agreement only as to issues arising under or with respect to Paragraphs 4, 5, and 7 of this License Agreement. Nothing in this License Agreement shall be deemed to create any relationship of agency, partnership, or joint venture between CNRI and Licensee. This License Agreement does not grant permission to use CNRI trademarks or trade name in a trademark sense to endorse or promote products or services of Licensee, or any third party.\ +\ +8. By clicking on the "ACCEPT" button where indicated, or by copying, installing or otherwise using Python 1.6.1, Licensee agrees to be bound by the terms and conditions of this License Agreement.\ +\ + ACCEPT\ +\ +\ + +\b CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2\ + +\b0 \ +Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam, The Netherlands. All rights reserved.\ +\ +Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of Stichting Mathematisch Centrum or CWI not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission.\ +\ +STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\ +\ +\ + +\b \ul LICENSES AND ACKNOWLEDGEMENTS FOR INCORPORATED SOFTWARE\ + +\b0 \ulnone \ +This installer incorporates portions of the following third-party software:\ +\ + +\f2 $THIRD_PARTY_LIBS\ +\ + +\f0 For licenses and acknowledgements for these and other third-party software incorporated in this Python distribution, please refer to the on-line documentation {\field{\*\fldinst{HYPERLINK "https://docs.python.org/$VERSION/license.html#licenses-and-acknowledgements-for-incorporated-software"}}{\fldrslt here}}.\ +\ +\ +\ +\ +} \ No newline at end of file diff --git a/Mac/BuildScript/resources/ReadMe.rtf b/Mac/BuildScript/resources/ReadMe.rtf new file mode 100644 index 000000000000..e2404485b290 --- /dev/null +++ b/Mac/BuildScript/resources/ReadMe.rtf @@ -0,0 +1,67 @@ +{\rtf1\ansi\ansicpg1252\cocoartf1343\cocoasubrtf160 +{\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fmodern\fcharset0 CourierNewPSMT;} +{\colortbl;\red255\green255\blue255;} +\margl1440\margr1440\vieww13380\viewh14600\viewkind0 +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural + +\f0\fs24 \cf0 This package will install Python $FULL_VERSION for Mac OS X $MACOSX_DEPLOYMENT_TARGET for the following architecture(s): $ARCHITECTURES.\ +\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural + +\b \cf0 \ul \ulc0 Which installer variant should I use? +\b0 \ulnone \ +\ +Python.org provides two installer variants for download: one that installs a +\i 64-bit/32-bit Intel +\i0 Python capable of running on +\i Mac OS X 10.6 (Snow Leopard) +\i0 or later; and one that installs a +\i 32-bit-only (Intel and PPC) +\i0 Python capable of running on +\i Mac OS X 10.5 (Leopard) +\i0 or later. This ReadMe was installed with the +\i $MACOSX_DEPLOYMENT_TARGET +\i0 variant. Unless you are installing to an 10.5 system or you need to build applications that can run on 10.5 systems, use the 10.6 variant if possible. There are some additional operating system functions that are supported starting with 10.6 and you may see better performance using 64-bit mode. By default, Python will automatically run in 64-bit mode if your system supports it. Also see +\i Certificate verification and OpenSSL +\i0 below. +\b \ul \ +\ +Update your version of Tcl/Tk to use IDLE or other Tk applications +\b0 \ulnone \ +\ +To use IDLE or other programs that use the Tkinter graphical user interface toolkit, you need to install a newer third-party version of the +\i Tcl/Tk +\i0 frameworks. Visit {\field{\*\fldinst{HYPERLINK "https://www.python.org/download/mac/tcltk/"}}{\fldrslt https://www.python.org/download/mac/tcltk/}} for current information about supported and recommended versions of +\i Tcl/Tk +\i0 for this version of Python and of Mac OS X.\ + +\b \ul \ +Python 3 and Python 2 Co-existence\ + +\b0 \ulnone \ +Python.org Python $VERSION and 2.7.x versions can both be installed on your system and will not conflict. Command names for Python 3 contain a 3 in them, +\f1 python3 +\f0 (or +\f1 python$VERSION +\f0 ), +\f1 idle3 +\f0 (or i +\f1 dle$VERSION +\f0 ), +\f1 pip3 +\f0 (or +\f1 pip$VERSION +\f0 ), etc. Python 2.7 command names contain a 2 or no digit: +\f1 python2 +\f0 (or +\f1 python2.7 +\f0 or +\f1 python +\f0 ), +\f1 idle2 +\f0 (or +\f1 idle2.7 +\f0 or +\f1 idle +\f0 ), etc.\ +} \ No newline at end of file diff --git a/Mac/BuildScript/resources/ReadMe.txt b/Mac/BuildScript/resources/ReadMe.txt deleted file mode 100644 index e061a06350ba..000000000000 --- a/Mac/BuildScript/resources/ReadMe.txt +++ /dev/null @@ -1,92 +0,0 @@ -This package will install Python $FULL_VERSION for Mac OS X -$MACOSX_DEPLOYMENT_TARGET for the following architecture(s): -$ARCHITECTURES. - - **** IMPORTANT **** - -Installing on OS X 10.8 (Mountain Lion) or later systems -======================================================== - -If you are attempting to install on an OS X 10.8+ system, you may -see a message that Python can't be installed because it is from an -unidentified developer. This is because this Python installer -package is not yet compatible with the Gatekeeper security feature -introduced in OS X 10.8. To allow Python to be installed, you -can override the Gatekeeper policy for this install. In the Finder, -instead of double-clicking, control-click or right click the "Python" -installer package icon. Then select "Open using ... Installer" from -the contextual menu that appears. - - **** IMPORTANT **** - -Update your version of Tcl/Tk to use IDLE or other Tk applications -================================================================== - -To use IDLE or other programs that use the Tkinter graphical user -interface toolkit, you may need to install a newer third-party version -of the Tcl/Tk frameworks. Visit http://www.python.org/download/mac/tcltk/ -for current information about supported and recommended versions of -Tcl/Tk for this version of Python and of Mac OS X. - - **NEW* As of Python 3.4.0b1: - -New Installation Options and Defaults -===================================== - -The Python installer now includes an option to automatically install -or upgrade pip, a tool for installing and managing Python packages. -This option is enabled by default and no Internet access is required. -If you do not want the installer to do this, select the "Customize" -option at the "Installation Type" step and uncheck the "Install or -ugprade pip" option. - -To make it easier to use scripts installed by third-party Python -packages, with pip or by other means, the "Shell profile updater" -option is now enabled by default, as has been the case with Python -2.7.x installers. You can also turn this option off by selecting -"Customize" and unchecking the "Shell profile updater" option. You -can also update your shell profile later by launching the "Update -Shell Profile" command found in the /Applications/Python $VERSION -folder. You may need to start a new terminal window for the -changes to take effect. - -Python.org Python $VERSION and 2.7.x versions can both be installed and -will not conflict. Command names for Python 3 contain a 3 in them, -python3 (or python$VERSION), idle3 (or idle$VERSION), pip3 (or pip$VERSION), etc. -Python 2.7 command names contain a 2 or no digit: python2 (or -python2.7 or python), idle2 (or idle2.7 or idle), etc. If you want to -use pip with Python 2.7.x, you will need to download and install a -separate copy of it from the Python Package Index -(https://pypi.python.org/pypi). - -Using this version of Python on OS X -==================================== - -Python consists of the Python programming language interpreter, plus -a set of programs to allow easy access to it for Mac users including -an integrated development environment, IDLE, plus a set of pre-built -extension modules that open up specific Macintosh technologies to -Python programs. - -The installer puts applications, an "Update Shell Profile" command, -and a link to the optionally installed Python Documentation into the -"Python $VERSION" subfolder of the system Applications folder, -and puts the underlying machinery into the folder -$PYTHONFRAMEWORKINSTALLDIR. It can -optionally place links to the command-line tools in /usr/local/bin as -well. Double-click on the "Update Shell Profile" command to add the -"bin" directory inside the framework to your shell's search path. - -You must install onto your current boot disk, even though the -installer may not enforce this, otherwise things will not work. - -You can verify the integrity of the disk image file containing the -installer package and this ReadMe file by comparing its md5 checksum -and size with the values published on the release page linked at -http://www.python.org/download/ - -Installation requires approximately $INSTALL_SIZE MB of disk space, -ignore the message that it will take zero bytes. - -More information on Python in general can be found at -http://www.python.org. diff --git a/Mac/BuildScript/resources/Welcome.rtf b/Mac/BuildScript/resources/Welcome.rtf index 886ebfecabb4..dfb75d854dc9 100644 --- a/Mac/BuildScript/resources/Welcome.rtf +++ b/Mac/BuildScript/resources/Welcome.rtf @@ -1,7 +1,7 @@ -{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf400 -\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fmodern\fcharset0 CourierNewPSMT;} +{\rtf1\ansi\ansicpg1252\cocoartf1343\cocoasubrtf160 +\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} -\paperw11905\paperh16837\margl1440\margr1440\vieww9640\viewh10620\viewkind0 +\paperw11905\paperh16837\margl1440\margr1440\vieww12200\viewh10880\viewkind0 \pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640 \f0\fs24 \cf0 This package will install @@ -14,19 +14,7 @@ \b Python for Mac OS X \b0 consists of the Python programming language interpreter, plus a set of programs to allow easy access to it for Mac OS X users including an integrated development environment \b IDLE -\b0 and a set of pre-built extension modules that open up specific Macintosh technologies to Python programs.\ -\ - -\b NEW for Python 3.4: -\b0 This package now updates your shell profile by default to make $FULL_VERSION the default Python 3 version. This version can co-exist with other installed versions of Python 3 and Python 2. This package also installs a version of -\f1 pip -\f0 , the recommended tool for installing and managing Python packages. Type\ -\ - -\f1 pip3.4 --help -\f0 \ -\ -for an overview. See the ReadMe file and the Python documentation for more information.\ +\b0 .\ \ \b IMPORTANT: @@ -36,4 +24,4 @@ for an overview. See the ReadMe file and the Python documentation for more info \b tkinter \b0 graphical user interface toolkit require specific versions of the \b Tcl/Tk -\b0 platform independent windowing toolkit. Visit {\field{\*\fldinst{HYPERLINK "http://www.python.org/download/mac/tcltk/"}}{\fldrslt http://www.python.org/download/mac/tcltk/}} for current information on supported and recommended versions of Tcl/Tk for this version of Python and Mac OS X.} \ No newline at end of file +\b0 platform independent windowing toolkit. Visit {\field{\*\fldinst{HYPERLINK "https://www.python.org/download/mac/tcltk/"}}{\fldrslt https://www.python.org/download/mac/tcltk/}} for current information on supported and recommended versions of Tcl/Tk for this version of Python and Mac OS X.} \ No newline at end of file diff --git a/Mac/BuildScript/scripts/postflight.ensurepip b/Mac/BuildScript/scripts/postflight.ensurepip index 3b97c4759eca..bf893d1da616 100755 --- a/Mac/BuildScript/scripts/postflight.ensurepip +++ b/Mac/BuildScript/scripts/postflight.ensurepip @@ -4,7 +4,7 @@ # PYVER="@PYVER@" -PYMAJOR="3" +PYMAJOR="@PYMAJOR@" FWK="/Library/Frameworks/Python.framework/Versions/${PYVER}" RELFWKBIN="../../..${FWK}/bin" @@ -34,32 +34,36 @@ chmod -R g+w "${FWK}/lib/python${PYVER}/site-packages" "${FWK}/bin" if [ -d /usr/local/bin ] ; then ( + install_links_if_our_fw() { + if [ "$(readlink -n ./$1)" = "${RELFWKBIN}/$1" ] ; then + shift + for fn ; + do + if [ -e "${RELFWKBIN}/${fn}" ] ; then + rm -f ./${fn} + ln -s "${RELFWKBIN}/${fn}" "./${fn}" + chgrp -h admin "./${fn}" + chmod -h g+w "./${fn}" + fi + done + fi + } + cd /usr/local/bin + # Create pipx.y and easy_install-x.y links if /usr/local/bin/pythonx.y # is linked to this framework version - if [ "$(readlink -n ./python${PYVER})" = "${RELFWKBIN}/python${PYVER}" ] ; then - for fn in "pip${PYVER}" "easy_install-${PYVER}" ; - do - if [ -e "${RELFWKBIN}/${fn}" ] ; then - rm -f ./${fn} - ln -s "${RELFWKBIN}/${fn}" "./${fn}" - chgrp -h admin "./${fn}" - chmod -h g+w "./${fn}" - fi - done - fi + install_links_if_our_fw "python${PYVER}" \ + "pip${PYVER}" "easy_install-${PYVER}" + # Create pipx link if /usr/local/bin/pythonx is linked to this version - if [ "$(readlink -n ./python${PYMAJOR})" = "${RELFWKBIN}/python${PYMAJOR}" ] ; then - for fn in "pip${PYMAJOR}" ; - do - if [ -e "${RELFWKBIN}/${fn}" ] ; then - rm -f ./${fn} - ln -s "${RELFWKBIN}/${fn}" "./${fn}" - chgrp -h admin "./${fn}" - chmod -h g+w "./${fn}" - fi - done - fi + install_links_if_our_fw "python${PYMAJOR}" \ + "pip${PYMAJOR}" + + # Create pip and easy_install link if /usr/local/bin/python + # is linked to this version + install_links_if_our_fw "python" \ + "pip" "easy_install" ) fi exit 0 diff --git a/Mac/IDLE/IDLE.app/Contents/Info.plist b/Mac/IDLE/IDLE.app/Contents/Info.plist index 81daff3dc9ce..9538c069809e 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-2013 Python Software Foundation + %version%, © 2001-2015 Python Software Foundation CFBundleIconFile IDLE.icns CFBundleIdentifier diff --git a/Mac/PythonLauncher/FileSettings.h b/Mac/PythonLauncher/FileSettings.h old mode 100755 new mode 100644 diff --git a/Mac/PythonLauncher/FileSettings.m b/Mac/PythonLauncher/FileSettings.m old mode 100755 new mode 100644 diff --git a/Mac/PythonLauncher/Info.plist.in b/Mac/PythonLauncher/Info.plist.in index c21676621996..b4ade1dd233a 100644 --- a/Mac/PythonLauncher/Info.plist.in +++ b/Mac/PythonLauncher/Info.plist.in @@ -1,5 +1,5 @@ - + CFBundleDevelopmentRegion @@ -38,9 +38,9 @@ CFBundleExecutable - PythonLauncher + Python Launcher CFBundleGetInfoString - %VERSION%, © 2001-2013 Python Software Foundation + %VERSION%, © 2001-2015 Python Software Foundation CFBundleIconFile PythonLauncher.icns CFBundleIdentifier diff --git a/Mac/PythonLauncher/Makefile.in b/Mac/PythonLauncher/Makefile.in index 970b83f31490..4c05f26e8358 100644 --- a/Mac/PythonLauncher/Makefile.in +++ b/Mac/PythonLauncher/Makefile.in @@ -15,12 +15,10 @@ BUILDPYTHON= $(builddir)/python$(BUILDEXE) PYTHONFRAMEWORK=@PYTHONFRAMEWORK@ # Deployment target selected during configure, to be checked -# by distutils +# by distutils MACOSX_DEPLOYMENT_TARGET=@CONFIGURE_MACOSX_DEPLOYMENT_TARGET@ @EXPORT_MACOSX_DEPLOYMENT_TARGET@export MACOSX_DEPLOYMENT_TARGET -BUNDLEBULDER=$(srcdir)/../Tools/bundlebuilder.py - PYTHONAPPSDIR=@FRAMEWORKINSTALLAPPSPREFIX@/$(PYTHONFRAMEWORK) $(VERSION) OBJECTS=FileSettings.o MyAppDelegate.o MyDocument.o PreferencesWindowController.o doscript.o main.o @@ -30,10 +28,10 @@ install: Python\ Launcher.app /bin/cp -r "Python Launcher.app" "$(DESTDIR)$(PYTHONAPPSDIR)" touch "$(DESTDIR)$(PYTHONAPPSDIR)/Python Launcher.app" - clean: rm -f *.o "Python Launcher" rm -rf "Python Launcher.app" + rm -f Info.plist Python\ Launcher.app: Info.plist \ Python\ Launcher $(srcdir)/../Icons/PythonLauncher.icns \ @@ -41,20 +39,17 @@ Python\ Launcher.app: Info.plist \ $(srcdir)/../Icons/PythonCompiled.icns \ $(srcdir)/factorySettings.plist rm -fr "Python Launcher.app" - $(RUNSHARED) $(BUILDPYTHON) $(BUNDLEBULDER) \ - --builddir=. \ - --name="Python Launcher" \ - --executable="Python Launcher" \ - --iconfile=$(srcdir)/../Icons/PythonLauncher.icns \ - --bundle-id=org.python.PythonLauncher \ - --resource=$(srcdir)/../Icons/PythonSource.icns \ - --resource=$(srcdir)/../Icons/PythonCompiled.icns \ - --resource=$(srcdir)/English.lproj \ - --resource=$(srcdir)/factorySettings.plist \ - --plist Info.plist \ - build - find "Python Launcher.app" -name '.svn' -print0 | xargs -0 rm -r - + mkdir "Python Launcher.app" + mkdir "Python Launcher.app/Contents" + mkdir "Python Launcher.app/Contents/MacOS" + mkdir "Python Launcher.app/Contents/Resources" + cp "Python Launcher" "Python Launcher.app/Contents/MacOS" + cp Info.plist "Python Launcher.app/Contents" + cp $(srcdir)/../Icons/PythonLauncher.icns "Python Launcher.app/Contents/Resources" + cp $(srcdir)/../Icons/PythonSource.icns "Python Launcher.app/Contents/Resources" + cp $(srcdir)/../Icons/PythonCompiled.icns "Python Launcher.app/Contents/Resources" + cp $(srcdir)/factorySettings.plist "Python Launcher.app/Contents/Resources" + cp -R $(srcdir)/English.lproj "Python Launcher.app/Contents/Resources" FileSettings.o: $(srcdir)/FileSettings.m $(CC) $(CFLAGS) -o $@ -c $(srcdir)/FileSettings.m diff --git a/Mac/PythonLauncher/MyDocument.m b/Mac/PythonLauncher/MyDocument.m old mode 100755 new mode 100644 diff --git a/Mac/PythonLauncher/main.m b/Mac/PythonLauncher/main.m old mode 100755 new mode 100644 diff --git a/Mac/README b/Mac/README index 61634e9c2abf..0a313d178fdd 100644 --- a/Mac/README +++ b/Mac/README @@ -12,6 +12,9 @@ Python on Mac OS X README This document provides a quick overview of some Mac OS X specific features in the Python distribution. +OS X specific arguments to configure +==================================== + * ``--enable-framework[=DIR]`` If this argument is specified the build will create a Python.framework rather @@ -86,6 +89,13 @@ unix build. Universal builds were first supported with OS X 10.4 with Xcode 2.1 and the 10.4u SDK. Starting with Xcode 3 and OS X 10.5, more configurations are available. +In general, universal builds depend on specific features provided by the +Apple-supplied compilers and other build tools included in Apple's Xcode +development tools. You should install Xcode and the command line tools +component appropriate for the OS X release you are running on. See the +Python Developer's Guide (http://docs.python.org/devguide/setup.html) +for more information. + 2.1 Flavors of universal binaries ................................. @@ -114,7 +124,7 @@ on a system running OS X 10.5 or later. The ``all`` and ``64-bit`` flavors can only be built with an 10.5 SDK because ``ppc64`` support was only included with OS X 10.5. Although legacy ``ppc`` support was included with Xcode 3 on OS X 10.6, it was removed in Xcode 4, versions of which were released on OS X 10.6 -and which is the current standard for OS X 10.7 and 10.8. To summarize, the +and which is the standard for OS X 10.7. To summarize, the following combinations of SDKs and universal-archs flavors are available: * 10.4u SDK with Xcode 2 supports ``32-bit`` only @@ -127,6 +137,8 @@ following combinations of SDKs and universal-archs flavors are available: * 10.7 and 10.8 SDKs with Xcode 4 support ``intel`` only + * 10.8 and 10.9 SDKs with Xcode 5 support ``intel`` only + The makefile for a framework build will also install ``python3.4-32`` binaries when the universal architecture includes at least one 32-bit architecture (that is, for all flavors but ``64-bit``). @@ -154,7 +166,6 @@ subprocesses also run in 32-bit-mode if the main interpreter does, use a ``python3.4-32`` binary and use the value of ``sys.executable`` as the ``subprocess`` ``Popen`` executable value. - Building and using a framework-based Python on Mac OS X. ======================================================== @@ -164,7 +175,7 @@ Building and using a framework-based Python on Mac OS X. The main reason is because you want to create GUI programs in Python. With the exception of X11/XDarwin-based GUI toolkits all GUI programs need to be run -from a Mac OSX application bundle (".app"). +from a Mac OS X application bundle (".app"). While it is technically possible to create a .app without using frameworks you will have to do the work yourself if you really want this. @@ -189,7 +200,7 @@ Versions/Current and you will see the familiar bin and lib directories. 3. Do I need extra packages? ---------------------------- -Yes, probably. If you want Tkinter support you need to get the OSX AquaTk +Yes, probably. If you want Tkinter support you need to get the OS X AquaTk distribution, this is installed by default on Mac OS X 10.4 or later. Be aware, though, that the Cocoa-based AquaTk's supplied starting with OS X 10.6 have proven to be unstable. If possible, you should consider @@ -205,9 +216,9 @@ If you want Cocoa you need to get PyObjC. ------------------------------------- This directory contains a Makefile that will create a couple of python-related -applications (full-blown OSX .app applications, that is) in +applications (full-blown OS X .app applications, that is) in "/Applications/Python ", and a hidden helper application Python.app -inside the Python.framework, and unix tools "python" and "pythonw" into +inside the Python.framework, and unix tools including "python" into /usr/local/bin. In addition it has a target "installmacsubtree" that installs the relevant portions of the Mac subtree into the Python.framework. @@ -245,18 +256,18 @@ What do all these programs do? "IDLE.app" is an integrated development environment for Python: editor, debugger, etc. -"PythonLauncher.app" is a helper application that will handle things when you +"Python Launcher.app" is a helper application that will handle things when you double-click a .py, .pyc or .pyw file. For the first two it creates a Terminal window and runs the scripts with the normal command-line Python. For the latter it runs the script in the Python.app interpreter so the script can do GUI-things. Keep the ``Option`` key depressed while dragging or double-clicking a script to set runtime options. These options can be set persistently -through PythonLauncher's preferences dialog. +through Python Launcher's preferences dialog. -The program ``pythonx.x`` runs python scripts from the command line. Various -compatibility aliases are also installed, including ``pythonwx.x`` which -in early releases of Python on OS X was required to run GUI programs. In -current releases, the ``pythonx.x`` and ``pythonwx.x`` commands are identical. +The program ``pythonx.x`` runs python scripts from the command line. +Previously, various compatibility aliases were also installed, including +``pythonwx.x`` which in early releases of Python on OS X was required to run +GUI programs. As of 3.4.0, the ``pythonwx.x`` aliases are no longer installed. How do I create a binary distribution? ====================================== @@ -301,7 +312,7 @@ The configure script sometimes emits warnings like the one below:: configure: WARNING: libintl.h: check for missing prerequisite headers? configure: WARNING: libintl.h: see the Autoconf documentation configure: WARNING: libintl.h: section "Present But Cannot Be Compiled" - configure: WARNING: libintl.h: proceeding with the preprocessor's result + configure: WARNING: libintl.h: proceeding with the preprocessor's result configure: WARNING: libintl.h: in the future, the compiler will take precedence configure: WARNING: ## -------------------------------------- ## configure: WARNING: ## Report this to http://bugs.python.org/ ## diff --git a/Mac/Resources/app/Info.plist.in b/Mac/Resources/app/Info.plist.in index 8af5efcdfaf5..cb7e8d74855c 100644 --- a/Mac/Resources/app/Info.plist.in +++ b/Mac/Resources/app/Info.plist.in @@ -20,7 +20,7 @@ CFBundleExecutable Python CFBundleGetInfoString - %version%, (c) 2004-2013 Python Software Foundation. + %version%, (c) 2001-2015 Python Software Foundation. CFBundleHelpBookFolder Documentation @@ -37,7 +37,7 @@ CFBundleInfoDictionaryVersion 6.0 CFBundleLongVersionString - %version%, (c) 2004-2013 Python Software Foundation. + %version%, (c) 2001-2015 Python Software Foundation. CFBundleName Python CFBundlePackageType @@ -55,7 +55,7 @@ NSAppleScriptEnabled NSHumanReadableCopyright - (c) 2013 Python Software Foundation. + (c) 2001-2015 Python Software Foundation. NSHighResolutionCapable diff --git a/Mac/Resources/framework/Info.plist.in b/Mac/Resources/framework/Info.plist.in index 6c3bdc1ca932..a97cc1fd7e91 100644 --- a/Mac/Resources/framework/Info.plist.in +++ b/Mac/Resources/framework/Info.plist.in @@ -17,9 +17,9 @@ CFBundlePackageType FMWK CFBundleShortVersionString - %VERSION%, (c) 2004-2013 Python Software Foundation. + %VERSION%, (c) 2001-2015 Python Software Foundation. CFBundleLongVersionString - %VERSION%, (c) 2004-2013 Python Software Foundation. + %VERSION%, (c) 2001-2015 Python Software Foundation. CFBundleSignature ???? CFBundleVersion diff --git a/Mac/Tools/bundlebuilder.py b/Mac/Tools/bundlebuilder.py deleted file mode 100644 index f5679d3bd14f..000000000000 --- a/Mac/Tools/bundlebuilder.py +++ /dev/null @@ -1,934 +0,0 @@ -#! /usr/bin/env python - -"""\ -bundlebuilder.py -- Tools to assemble MacOS X (application) bundles. - -This module contains two classes to build so called "bundles" for -MacOS X. BundleBuilder is a general tool, AppBuilder is a subclass -specialized in building application bundles. - -[Bundle|App]Builder objects are instantiated with a bunch of keyword -arguments, and have a build() method that will do all the work. See -the class doc strings for a description of the constructor arguments. - -The module contains a main program that can be used in two ways: - - % python bundlebuilder.py [options] build - % python buildapp.py [options] build - -Where "buildapp.py" is a user-supplied setup.py-like script following -this model: - - from bundlebuilder import buildapp - buildapp() - -""" - - -__all__ = ["BundleBuilder", "BundleBuilderError", "AppBuilder", "buildapp"] - - -import sys -import os, errno, shutil -import imp, marshal -import re -from copy import deepcopy -import getopt -from plistlib import Plist -from types import FunctionType as function - -class BundleBuilderError(Exception): pass - - -class Defaults: - - """Class attributes that don't start with an underscore and are - not functions or classmethods are (deep)copied to self.__dict__. - This allows for mutable default values. - """ - - def __init__(self, **kwargs): - defaults = self._getDefaults() - defaults.update(kwargs) - self.__dict__.update(defaults) - - def _getDefaults(cls): - defaults = {} - for base in cls.__bases__: - if hasattr(base, "_getDefaults"): - defaults.update(base._getDefaults()) - for name, value in list(cls.__dict__.items()): - if name[0] != "_" and not isinstance(value, - (function, classmethod)): - defaults[name] = deepcopy(value) - return defaults - _getDefaults = classmethod(_getDefaults) - - -class BundleBuilder(Defaults): - - """BundleBuilder is a barebones class for assembling bundles. It - knows nothing about executables or icons, it only copies files - and creates the PkgInfo and Info.plist files. - """ - - # (Note that Defaults.__init__ (deep)copies these values to - # instance variables. Mutable defaults are therefore safe.) - - # Name of the bundle, with or without extension. - name = None - - # The property list ("plist") - plist = Plist(CFBundleDevelopmentRegion = "English", - CFBundleInfoDictionaryVersion = "6.0") - - # The type of the bundle. - type = "BNDL" - # The creator code of the bundle. - creator = None - - # the CFBundleIdentifier (this is used for the preferences file name) - bundle_id = None - - # List of files that have to be copied to /Contents/Resources. - resources = [] - - # List of (src, dest) tuples; dest should be a path relative to the bundle - # (eg. "Contents/Resources/MyStuff/SomeFile.ext). - files = [] - - # List of shared libraries (dylibs, Frameworks) to bundle with the app - # will be placed in Contents/Frameworks - libs = [] - - # Directory where the bundle will be assembled. - builddir = "build" - - # Make symlinks instead copying files. This is handy during debugging, but - # makes the bundle non-distributable. - symlink = 0 - - # Verbosity level. - verbosity = 1 - - # Destination root directory - destroot = "" - - def setup(self): - # XXX rethink self.name munging, this is brittle. - self.name, ext = os.path.splitext(self.name) - if not ext: - ext = ".bundle" - bundleextension = ext - # misc (derived) attributes - self.bundlepath = pathjoin(self.builddir, self.name + bundleextension) - - plist = self.plist - plist.CFBundleName = self.name - plist.CFBundlePackageType = self.type - if self.creator is None: - if hasattr(plist, "CFBundleSignature"): - self.creator = plist.CFBundleSignature - else: - self.creator = "????" - plist.CFBundleSignature = self.creator - if self.bundle_id: - plist.CFBundleIdentifier = self.bundle_id - elif not hasattr(plist, "CFBundleIdentifier"): - plist.CFBundleIdentifier = self.name - - def build(self): - """Build the bundle.""" - builddir = self.builddir - if builddir and not os.path.exists(builddir): - os.mkdir(builddir) - self.message("Building %s" % repr(self.bundlepath), 1) - if os.path.exists(self.bundlepath): - shutil.rmtree(self.bundlepath) - if os.path.exists(self.bundlepath + '~'): - shutil.rmtree(self.bundlepath + '~') - bp = self.bundlepath - - # Create the app bundle in a temporary location and then - # rename the completed bundle. This way the Finder will - # never see an incomplete bundle (where it might pick up - # and cache the wrong meta data) - self.bundlepath = bp + '~' - try: - os.mkdir(self.bundlepath) - self.preProcess() - self._copyFiles() - self._addMetaFiles() - self.postProcess() - os.rename(self.bundlepath, bp) - finally: - self.bundlepath = bp - self.message("Done.", 1) - - def preProcess(self): - """Hook for subclasses.""" - pass - def postProcess(self): - """Hook for subclasses.""" - pass - - def _addMetaFiles(self): - contents = pathjoin(self.bundlepath, "Contents") - makedirs(contents) - # - # Write Contents/PkgInfo - assert len(self.type) == len(self.creator) == 4, \ - "type and creator must be 4-byte strings." - pkginfo = pathjoin(contents, "PkgInfo") - f = open(pkginfo, "wb") - f.write((self.type + self.creator).encode('latin1')) - f.close() - # - # Write Contents/Info.plist - infoplist = pathjoin(contents, "Info.plist") - self.plist.write(infoplist) - - def _copyFiles(self): - files = self.files[:] - for path in self.resources: - files.append((path, pathjoin("Contents", "Resources", - os.path.basename(path)))) - for path in self.libs: - files.append((path, pathjoin("Contents", "Frameworks", - os.path.basename(path)))) - if self.symlink: - self.message("Making symbolic links", 1) - msg = "Making symlink from" - else: - self.message("Copying files", 1) - msg = "Copying" - files.sort() - for src, dst in files: - if os.path.isdir(src): - self.message("%s %s/ to %s/" % (msg, src, dst), 2) - else: - self.message("%s %s to %s" % (msg, src, dst), 2) - dst = pathjoin(self.bundlepath, dst) - if self.symlink: - symlink(src, dst, mkdirs=1) - else: - copy(src, dst, mkdirs=1) - - def message(self, msg, level=0): - if level <= self.verbosity: - indent = "" - if level > 1: - indent = (level - 1) * " " - sys.stderr.write(indent + msg + "\n") - - def report(self): - # XXX something decent - pass - - -if __debug__: - PYC_EXT = ".pyc" -else: - PYC_EXT = ".pyo" - -MAGIC = imp.get_magic() -USE_ZIPIMPORT = "zipimport" in sys.builtin_module_names - -# For standalone apps, we have our own minimal site.py. We don't need -# all the cruft of the real site.py. -SITE_PY = """\ -import sys -if not %(semi_standalone)s: - del sys.path[1:] # sys.path[0] is Contents/Resources/ -""" - -if USE_ZIPIMPORT: - ZIP_ARCHIVE = "Modules.zip" - SITE_PY += "sys.path.append(sys.path[0] + '/%s')\n" % ZIP_ARCHIVE - def getPycData(fullname, code, ispkg): - if ispkg: - fullname += ".__init__" - path = fullname.replace(".", os.sep) + PYC_EXT - return path, MAGIC + '\0\0\0\0' + marshal.dumps(code) - -# -# Extension modules can't be in the modules zip archive, so a placeholder -# is added instead, that loads the extension from a specified location. -# -EXT_LOADER = """\ -def __load(): - import imp, sys, os - for p in sys.path: - path = os.path.join(p, "%(filename)s") - if os.path.exists(path): - break - else: - assert 0, "file not found: %(filename)s" - mod = imp.load_dynamic("%(name)s", path) - -__load() -del __load -""" - -MAYMISS_MODULES = ['mac', 'nt', 'ntpath', 'dos', 'dospath', - 'win32api', 'ce', '_winreg', 'nturl2path', 'sitecustomize', - 'org.python.core', 'riscos', 'riscosenviron', 'riscospath' -] - -STRIP_EXEC = "/usr/bin/strip" - -# -# We're using a stock interpreter to run the app, yet we need -# a way to pass the Python main program to the interpreter. The -# bootstrapping script fires up the interpreter with the right -# arguments. os.execve() is used as OSX doesn't like us to -# start a real new process. Also, the executable name must match -# the CFBundleExecutable value in the Info.plist, so we lie -# deliberately with argv[0]. The actual Python executable is -# passed in an environment variable so we can "repair" -# sys.executable later. -# -BOOTSTRAP_SCRIPT = """\ -#!%(hashbang)s - -import sys, os -execdir = os.path.dirname(sys.argv[0]) -executable = os.path.join(execdir, "%(executable)s") -resdir = os.path.join(os.path.dirname(execdir), "Resources") -libdir = os.path.join(os.path.dirname(execdir), "Frameworks") -mainprogram = os.path.join(resdir, "%(mainprogram)s") - -sys.argv.insert(1, mainprogram) -if %(standalone)s or %(semi_standalone)s: - os.environ["PYTHONPATH"] = resdir - if %(standalone)s: - os.environ["PYTHONHOME"] = resdir -else: - pypath = os.getenv("PYTHONPATH", "") - if pypath: - pypath = ":" + pypath - os.environ["PYTHONPATH"] = resdir + pypath -os.environ["PYTHONEXECUTABLE"] = executable -os.environ["DYLD_LIBRARY_PATH"] = libdir -os.environ["DYLD_FRAMEWORK_PATH"] = libdir -os.execve(executable, sys.argv, os.environ) -""" - - -# -# Optional wrapper that converts "dropped files" into sys.argv values. -# -ARGV_EMULATOR = """\ -import argvemulator, os - -argvemulator.ArgvCollector().mainloop() -execfile(os.path.join(os.path.split(__file__)[0], "%(realmainprogram)s")) -""" - -# -# When building a standalone app with Python.framework, we need to copy -# a subset from Python.framework to the bundle. The following list -# specifies exactly what items we'll copy. -# -PYTHONFRAMEWORKGOODIES = [ - "Python", # the Python core library - "Resources/English.lproj", - "Resources/Info.plist", - "Resources/version.plist", -] - -def isFramework(): - return sys.exec_prefix.find("Python.framework") > 0 - - -LIB = os.path.join(sys.prefix, "lib", "python" + sys.version[:3]) -SITE_PACKAGES = os.path.join(LIB, "site-packages") - - -class AppBuilder(BundleBuilder): - - # Override type of the bundle. - type = "APPL" - - # platform, name of the subfolder of Contents that contains the executable. - platform = "MacOS" - - # A Python main program. If this argument is given, the main - # executable in the bundle will be a small wrapper that invokes - # the main program. (XXX Discuss why.) - mainprogram = None - - # The main executable. If a Python main program is specified - # the executable will be copied to Resources and be invoked - # by the wrapper program mentioned above. Otherwise it will - # simply be used as the main executable. - executable = None - - # The name of the main nib, for Cocoa apps. *Must* be specified - # when building a Cocoa app. - nibname = None - - # The name of the icon file to be copied to Resources and used for - # the Finder icon. - iconfile = None - - # Symlink the executable instead of copying it. - symlink_exec = 0 - - # If True, build standalone app. - standalone = 0 - - # If True, build semi-standalone app (only includes third-party modules). - semi_standalone = 0 - - # If set, use this for #! lines in stead of sys.executable - python = None - - # If True, add a real main program that emulates sys.argv before calling - # mainprogram - argv_emulation = 0 - - # The following attributes are only used when building a standalone app. - - # Exclude these modules. - excludeModules = [] - - # Include these modules. - includeModules = [] - - # Include these packages. - includePackages = [] - - # Strip binaries from debug info. - strip = 0 - - # Found Python modules: [(name, codeobject, ispkg), ...] - pymodules = [] - - # Modules that modulefinder couldn't find: - missingModules = [] - maybeMissingModules = [] - - def setup(self): - if ((self.standalone or self.semi_standalone) - and self.mainprogram is None): - raise BundleBuilderError("must specify 'mainprogram' when " - "building a standalone application.") - if self.mainprogram is None and self.executable is None: - raise BundleBuilderError("must specify either or both of " - "'executable' and 'mainprogram'") - - self.execdir = pathjoin("Contents", self.platform) - - if self.name is not None: - pass - elif self.mainprogram is not None: - self.name = os.path.splitext(os.path.basename(self.mainprogram))[0] - elif executable is not None: - self.name = os.path.splitext(os.path.basename(self.executable))[0] - if self.name[-4:] != ".app": - self.name += ".app" - - if self.executable is None: - if not self.standalone and not isFramework(): - self.symlink_exec = 1 - if self.python: - self.executable = self.python - else: - self.executable = sys.executable - - if self.nibname: - self.plist.NSMainNibFile = self.nibname - if not hasattr(self.plist, "NSPrincipalClass"): - self.plist.NSPrincipalClass = "NSApplication" - - if self.standalone and isFramework(): - self.addPythonFramework() - - BundleBuilder.setup(self) - - self.plist.CFBundleExecutable = self.name - - if self.standalone or self.semi_standalone: - self.findDependencies() - - def preProcess(self): - resdir = "Contents/Resources" - if self.executable is not None: - if self.mainprogram is None: - execname = self.name - else: - execname = os.path.basename(self.executable) - execpath = pathjoin(self.execdir, execname) - if not self.symlink_exec: - self.files.append((self.destroot + self.executable, execpath)) - self.execpath = execpath - - if self.mainprogram is not None: - mainprogram = os.path.basename(self.mainprogram) - self.files.append((self.mainprogram, pathjoin(resdir, mainprogram))) - if self.argv_emulation: - # Change the main program, and create the helper main program (which - # does argv collection and then calls the real main). - # Also update the included modules (if we're creating a standalone - # program) and the plist - realmainprogram = mainprogram - mainprogram = '__argvemulator_' + mainprogram - resdirpath = pathjoin(self.bundlepath, resdir) - mainprogrampath = pathjoin(resdirpath, mainprogram) - makedirs(resdirpath) - open(mainprogrampath, "w").write(ARGV_EMULATOR % locals()) - if self.standalone or self.semi_standalone: - self.includeModules.append("argvemulator") - self.includeModules.append("os") - if "CFBundleDocumentTypes" not in self.plist: - self.plist["CFBundleDocumentTypes"] = [ - { "CFBundleTypeOSTypes" : [ - "****", - "fold", - "disk"], - "CFBundleTypeRole": "Viewer"}] - # Write bootstrap script - executable = os.path.basename(self.executable) - execdir = pathjoin(self.bundlepath, self.execdir) - bootstrappath = pathjoin(execdir, self.name) - makedirs(execdir) - if self.standalone or self.semi_standalone: - # XXX we're screwed when the end user has deleted - # /usr/bin/python - hashbang = "/usr/bin/python" - elif self.python: - hashbang = self.python - else: - hashbang = os.path.realpath(sys.executable) - standalone = self.standalone - semi_standalone = self.semi_standalone - open(bootstrappath, "w").write(BOOTSTRAP_SCRIPT % locals()) - os.chmod(bootstrappath, 0o775) - - if self.iconfile is not None: - iconbase = os.path.basename(self.iconfile) - self.plist.CFBundleIconFile = iconbase - self.files.append((self.iconfile, pathjoin(resdir, iconbase))) - - def postProcess(self): - if self.standalone or self.semi_standalone: - self.addPythonModules() - if self.strip and not self.symlink: - self.stripBinaries() - - if self.symlink_exec and self.executable: - self.message("Symlinking executable %s to %s" % (self.executable, - self.execpath), 2) - dst = pathjoin(self.bundlepath, self.execpath) - makedirs(os.path.dirname(dst)) - os.symlink(os.path.abspath(self.executable), dst) - - if self.missingModules or self.maybeMissingModules: - self.reportMissing() - - def addPythonFramework(self): - # If we're building a standalone app with Python.framework, - # include a minimal subset of Python.framework, *unless* - # Python.framework was specified manually in self.libs. - for lib in self.libs: - if os.path.basename(lib) == "Python.framework": - # a Python.framework was specified as a library - return - - frameworkpath = sys.exec_prefix[:sys.exec_prefix.find( - "Python.framework") + len("Python.framework")] - - version = sys.version[:3] - frameworkpath = pathjoin(frameworkpath, "Versions", version) - destbase = pathjoin("Contents", "Frameworks", "Python.framework", - "Versions", version) - for item in PYTHONFRAMEWORKGOODIES: - src = pathjoin(frameworkpath, item) - dst = pathjoin(destbase, item) - self.files.append((src, dst)) - - def _getSiteCode(self): - return compile(SITE_PY % {"semi_standalone": self.semi_standalone}, - "<-bundlebuilder.py->", "exec") - - def addPythonModules(self): - self.message("Adding Python modules", 1) - - if USE_ZIPIMPORT: - # Create a zip file containing all modules as pyc. - import zipfile - relpath = pathjoin("Contents", "Resources", ZIP_ARCHIVE) - abspath = pathjoin(self.bundlepath, relpath) - zf = zipfile.ZipFile(abspath, "w", zipfile.ZIP_DEFLATED) - for name, code, ispkg in self.pymodules: - self.message("Adding Python module %s" % name, 2) - path, pyc = getPycData(name, code, ispkg) - zf.writestr(path, pyc) - zf.close() - # add site.pyc - sitepath = pathjoin(self.bundlepath, "Contents", "Resources", - "site" + PYC_EXT) - writePyc(self._getSiteCode(), sitepath) - else: - # Create individual .pyc files. - for name, code, ispkg in self.pymodules: - if ispkg: - name += ".__init__" - path = name.split(".") - path = pathjoin("Contents", "Resources", *path) + PYC_EXT - - if ispkg: - self.message("Adding Python package %s" % path, 2) - else: - self.message("Adding Python module %s" % path, 2) - - abspath = pathjoin(self.bundlepath, path) - makedirs(os.path.dirname(abspath)) - writePyc(code, abspath) - - def stripBinaries(self): - if not os.path.exists(STRIP_EXEC): - self.message("Error: can't strip binaries: no strip program at " - "%s" % STRIP_EXEC, 0) - else: - import stat - self.message("Stripping binaries", 1) - def walk(top): - for name in os.listdir(top): - path = pathjoin(top, name) - if os.path.islink(path): - continue - if os.path.isdir(path): - walk(path) - else: - mod = os.stat(path)[stat.ST_MODE] - if not (mod & 0o100): - continue - relpath = path[len(self.bundlepath):] - self.message("Stripping %s" % relpath, 2) - inf, outf = os.popen4("%s -S \"%s\"" % - (STRIP_EXEC, path)) - output = outf.read().strip() - if output: - # usually not a real problem, like when we're - # trying to strip a script - self.message("Problem stripping %s:" % relpath, 3) - self.message(output, 3) - walk(self.bundlepath) - - def findDependencies(self): - self.message("Finding module dependencies", 1) - import modulefinder - mf = modulefinder.ModuleFinder(excludes=self.excludeModules) - if USE_ZIPIMPORT: - # zipimport imports zlib, must add it manually - mf.import_hook("zlib") - # manually add our own site.py - site = mf.add_module("site") - site.__code__ = self._getSiteCode() - mf.scan_code(site.__code__, site) - - # warnings.py gets imported implicitly from C - mf.import_hook("warnings") - - includeModules = self.includeModules[:] - for name in self.includePackages: - includeModules.extend(list(findPackageContents(name).keys())) - for name in includeModules: - try: - mf.import_hook(name) - except ImportError: - self.missingModules.append(name) - - mf.run_script(self.mainprogram) - modules = list(mf.modules.items()) - modules.sort() - for name, mod in modules: - path = mod.__file__ - if path and self.semi_standalone: - # skip the standard library - if path.startswith(LIB) and not path.startswith(SITE_PACKAGES): - continue - if path and mod.__code__ is None: - # C extension - filename = os.path.basename(path) - pathitems = name.split(".")[:-1] + [filename] - dstpath = pathjoin(*pathitems) - if USE_ZIPIMPORT: - if name != "zlib": - # neatly pack all extension modules in a subdirectory, - # except zlib, since it's necessary for bootstrapping. - dstpath = pathjoin("ExtensionModules", dstpath) - # Python modules are stored in a Zip archive, but put - # extensions in Contents/Resources/. Add a tiny "loader" - # program in the Zip archive. Due to Thomas Heller. - source = EXT_LOADER % {"name": name, "filename": dstpath} - code = compile(source, "" % name, "exec") - mod.__code__ = code - self.files.append((path, pathjoin("Contents", "Resources", dstpath))) - if mod.__code__ is not None: - ispkg = mod.__path__ is not None - if not USE_ZIPIMPORT or name != "site": - # Our site.py is doing the bootstrapping, so we must - # include a real .pyc file if USE_ZIPIMPORT is True. - self.pymodules.append((name, mod.__code__, ispkg)) - - if hasattr(mf, "any_missing_maybe"): - missing, maybe = mf.any_missing_maybe() - else: - missing = mf.any_missing() - maybe = [] - self.missingModules.extend(missing) - self.maybeMissingModules.extend(maybe) - - def reportMissing(self): - missing = [name for name in self.missingModules - if name not in MAYMISS_MODULES] - if self.maybeMissingModules: - maybe = self.maybeMissingModules - else: - maybe = [name for name in missing if "." in name] - missing = [name for name in missing if "." not in name] - missing.sort() - maybe.sort() - if maybe: - self.message("Warning: couldn't find the following submodules:", 1) - self.message(" (Note that these could be false alarms -- " - "it's not always", 1) - self.message(" possible to distinguish between \"from package " - "import submodule\" ", 1) - self.message(" and \"from package import name\")", 1) - for name in maybe: - self.message(" ? " + name, 1) - if missing: - self.message("Warning: couldn't find the following modules:", 1) - for name in missing: - self.message(" ? " + name, 1) - - def report(self): - # XXX something decent - import pprint - pprint.pprint(self.__dict__) - if self.standalone or self.semi_standalone: - self.reportMissing() - -# -# Utilities. -# - -SUFFIXES = [_suf for _suf, _mode, _tp in imp.get_suffixes()] -identifierRE = re.compile(r"[_a-zA-z][_a-zA-Z0-9]*$") - -def findPackageContents(name, searchpath=None): - head = name.split(".")[-1] - if identifierRE.match(head) is None: - return {} - try: - fp, path, (ext, mode, tp) = imp.find_module(head, searchpath) - except ImportError: - return {} - modules = {name: None} - if tp == imp.PKG_DIRECTORY and path: - files = os.listdir(path) - for sub in files: - sub, ext = os.path.splitext(sub) - fullname = name + "." + sub - if sub != "__init__" and fullname not in modules: - modules.update(findPackageContents(fullname, [path])) - return modules - -def writePyc(code, path): - f = open(path, "wb") - f.write(MAGIC) - f.write("\0" * 4) # don't bother about a time stamp - marshal.dump(code, f) - f.close() - -def copy(src, dst, mkdirs=0): - """Copy a file or a directory.""" - if mkdirs: - makedirs(os.path.dirname(dst)) - if os.path.isdir(src): - shutil.copytree(src, dst, symlinks=1) - else: - shutil.copy2(src, dst) - -def copytodir(src, dstdir): - """Copy a file or a directory to an existing directory.""" - dst = pathjoin(dstdir, os.path.basename(src)) - copy(src, dst) - -def makedirs(dir): - """Make all directories leading up to 'dir' including the leaf - directory. Don't moan if any path element already exists.""" - try: - os.makedirs(dir) - except OSError as why: - if why.errno != errno.EEXIST: - raise - -def symlink(src, dst, mkdirs=0): - """Copy a file or a directory.""" - if not os.path.exists(src): - raise IOError("No such file or directory: '%s'" % src) - if mkdirs: - makedirs(os.path.dirname(dst)) - os.symlink(os.path.abspath(src), dst) - -def pathjoin(*args): - """Safe wrapper for os.path.join: asserts that all but the first - argument are relative paths.""" - for seg in args[1:]: - assert seg[0] != "/" - return os.path.join(*args) - - -cmdline_doc = """\ -Usage: - python bundlebuilder.py [options] command - python mybuildscript.py [options] command - -Commands: - build build the application - report print a report - -Options: - -b, --builddir=DIR the build directory; defaults to "build" - -n, --name=NAME application name - -r, --resource=FILE extra file or folder to be copied to Resources - -f, --file=SRC:DST extra file or folder to be copied into the bundle; - DST must be a path relative to the bundle root - -e, --executable=FILE the executable to be used - -m, --mainprogram=FILE the Python main program - -a, --argv add a wrapper main program to create sys.argv - -p, --plist=FILE .plist file (default: generate one) - --nib=NAME main nib name - -c, --creator=CCCC 4-char creator code (default: '????') - --iconfile=FILE filename of the icon (an .icns file) to be used - as the Finder icon - --bundle-id=ID the CFBundleIdentifier, in reverse-dns format - (eg. org.python.BuildApplet; this is used for - the preferences file name) - -l, --link symlink files/folder instead of copying them - --link-exec symlink the executable instead of copying it - --standalone build a standalone application, which is fully - independent of a Python installation - --semi-standalone build a standalone application, which depends on - an installed Python, yet includes all third-party - modules. - --python=FILE Python to use in #! line in stead of current Python - --lib=FILE shared library or framework to be copied into - the bundle - -x, --exclude=MODULE exclude module (with --(semi-)standalone) - -i, --include=MODULE include module (with --(semi-)standalone) - --package=PACKAGE include a whole package (with --(semi-)standalone) - --strip strip binaries (remove debug info) - -v, --verbose increase verbosity level - -q, --quiet decrease verbosity level - -h, --help print this message -""" - -def usage(msg=None): - if msg: - print(msg) - print(cmdline_doc) - sys.exit(1) - -def main(builder=None): - if builder is None: - builder = AppBuilder(verbosity=1) - - shortopts = "b:n:r:f:e:m:c:p:lx:i:hvqa" - longopts = ("builddir=", "name=", "resource=", "file=", "executable=", - "mainprogram=", "creator=", "nib=", "plist=", "link", - "link-exec", "help", "verbose", "quiet", "argv", "standalone", - "exclude=", "include=", "package=", "strip", "iconfile=", - "lib=", "python=", "semi-standalone", "bundle-id=", "destroot=") - - try: - options, args = getopt.getopt(sys.argv[1:], shortopts, longopts) - except getopt.error: - usage() - - for opt, arg in options: - if opt in ('-b', '--builddir'): - builder.builddir = arg - elif opt in ('-n', '--name'): - builder.name = arg - elif opt in ('-r', '--resource'): - builder.resources.append(os.path.normpath(arg)) - elif opt in ('-f', '--file'): - srcdst = arg.split(':') - if len(srcdst) != 2: - usage("-f or --file argument must be two paths, " - "separated by a colon") - builder.files.append(srcdst) - elif opt in ('-e', '--executable'): - builder.executable = arg - elif opt in ('-m', '--mainprogram'): - builder.mainprogram = arg - elif opt in ('-a', '--argv'): - builder.argv_emulation = 1 - elif opt in ('-c', '--creator'): - builder.creator = arg - elif opt == '--bundle-id': - builder.bundle_id = arg - elif opt == '--iconfile': - builder.iconfile = arg - elif opt == "--lib": - builder.libs.append(os.path.normpath(arg)) - elif opt == "--nib": - builder.nibname = arg - elif opt in ('-p', '--plist'): - builder.plist = Plist.fromFile(arg) - elif opt in ('-l', '--link'): - builder.symlink = 1 - elif opt == '--link-exec': - builder.symlink_exec = 1 - elif opt in ('-h', '--help'): - usage() - elif opt in ('-v', '--verbose'): - builder.verbosity += 1 - elif opt in ('-q', '--quiet'): - builder.verbosity -= 1 - elif opt == '--standalone': - builder.standalone = 1 - elif opt == '--semi-standalone': - builder.semi_standalone = 1 - elif opt == '--python': - builder.python = arg - elif opt in ('-x', '--exclude'): - builder.excludeModules.append(arg) - elif opt in ('-i', '--include'): - builder.includeModules.append(arg) - elif opt == '--package': - builder.includePackages.append(arg) - elif opt == '--strip': - builder.strip = 1 - elif opt == '--destroot': - builder.destroot = arg - - if len(args) != 1: - usage("Must specify one command ('build', 'report' or 'help')") - command = args[0] - - if command == "build": - builder.setup() - builder.build() - elif command == "report": - builder.setup() - builder.report() - elif command == "help": - usage() - else: - usage("Unknown command '%s'" % command) - - -def buildapp(**kwargs): - builder = AppBuilder(**kwargs) - main(builder) - - -if __name__ == "__main__": - main() diff --git a/Mac/Tools/plistlib_generate_testdata.py b/Mac/Tools/plistlib_generate_testdata.py old mode 100644 new mode 100755 index da1d97645d49..057b61765b8a --- a/Mac/Tools/plistlib_generate_testdata.py +++ b/Mac/Tools/plistlib_generate_testdata.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -from Cocoa import NSMutableDictionary, NSMutableArray, NSString, NSDate +from Cocoa import NSMutableDictionary, NSMutableArray, NSString, NSDate, NSNumber from Cocoa import NSPropertyListSerialization, NSPropertyListOpenStepFormat from Cocoa import NSPropertyListXMLFormat_v1_0, NSPropertyListBinaryFormat_v1_0 from Cocoa import CFUUIDCreateFromString, NSNull, NSUUID, CFPropertyListCreateData @@ -23,7 +23,14 @@ def nsstr(value): def main(): pl = OrderedDict() + # Note: pl is an OrderedDict to control the order + # of keys, and hence have some control on the structure + # of the output file. + # New keys should be added in alphabetical order. + seconds = datetime.datetime(2004, 10, 26, 10, 33, 33, tzinfo=datetime.timezone(datetime.timedelta(0))).timestamp() + pl[nsstr('aBigInt')] = 2 ** 63 - 44 + pl[nsstr('aBigInt2')] = NSNumber.numberWithUnsignedLongLong_(2 ** 63 + 44) pl[nsstr('aDate')] = NSDate.dateWithTimeIntervalSince1970_(seconds) pl[nsstr('aDict')] = d = OrderedDict() @@ -52,6 +59,8 @@ def main(): aa.append(2) aa.append(3) + pl[nsstr('aNegativeBigInt')] = -80000000000 + pl[nsstr('aNegativeInt')] = -5 pl[nsstr('aString')] = nsstr('Doodah') pl[nsstr('anEmptyDict')] = NSMutableDictionary.alloc().init() diff --git a/Makefile.pre.in b/Makefile.pre.in index f843aa5cb0e1..d9ee7770852c 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -71,12 +71,17 @@ OPT= @OPT@ BASECFLAGS= @BASECFLAGS@ BASECPPFLAGS= @BASECPPFLAGS@ CONFIGURE_CFLAGS= @CFLAGS@ +# CFLAGS_NODIST is used for building the interpreter and stdlib C extensions. +# Use it when a compiler flag should _not_ be part of the distutils CFLAGS +# once Python is installed (Issue #21121). +CONFIGURE_CFLAGS_NODIST=@CFLAGS_NODIST@ CONFIGURE_CPPFLAGS= @CPPFLAGS@ CONFIGURE_LDFLAGS= @LDFLAGS@ # Avoid assigning CFLAGS, LDFLAGS, etc. so users can use them on the # command line to append to these values without stomping the pre-set # values. PY_CFLAGS= $(BASECFLAGS) $(OPT) $(CONFIGURE_CFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) +PY_CFLAGS_NODIST=$(CONFIGURE_CFLAGS_NODIST) $(CFLAGS_NODIST) # Both CPPFLAGS and LDFLAGS need to contain the shell's value for setup.py to # be able to build extension modules using the directories specified in the # environment variables @@ -91,7 +96,7 @@ ARFLAGS= @ARFLAGS@ # Extra C flags added for building the interpreter object files. CFLAGSFORSHARED=@CFLAGSFORSHARED@ # C flags used for building the interpreter object files -PY_CORE_CFLAGS= $(PY_CFLAGS) $(PY_CPPFLAGS) $(CFLAGSFORSHARED) -DPy_BUILD_CORE +PY_CORE_CFLAGS= $(PY_CFLAGS) $(PY_CFLAGS_NODIST) $(PY_CPPFLAGS) $(CFLAGSFORSHARED) -DPy_BUILD_CORE # Machine-dependent subdirectories @@ -322,6 +327,13 @@ PARSER_HEADERS= \ PGENSRCS= $(PSRCS) $(PGSRCS) PGENOBJS= $(POBJS) $(PGOBJS) +########################################################################## +# opcode.h generation +OPCODE_H_DIR= $(srcdir)/Include +OPCODE_H_SCRIPT= $(srcdir)/Tools/scripts/generate_opcode_h.py +OPCODE_H= $(OPCODE_H_DIR)/opcode.h +OPCODE_H_GEN= @OPCODEHGEN@ $(OPCODE_H_SCRIPT) $(srcdir)/Lib/opcode.py $(OPCODE_H) +# ########################################################################## # AST AST_H_DIR= Include @@ -331,7 +343,8 @@ AST_C= $(AST_C_DIR)/Python-ast.c AST_ASDL= $(srcdir)/Parser/Python.asdl ASDLGEN_FILES= $(srcdir)/Parser/asdl.py $(srcdir)/Parser/asdl_c.py -# XXX Note that a build now requires Python exist before the build starts +# Note that a build now requires Python to exist before the build starts. +# Use "hg touch" to fix up screwed up file mtimes in a checkout. ASDLGEN= @ASDLGEN@ $(srcdir)/Parser/asdl_c.py ########################################################################## @@ -376,6 +389,7 @@ PYTHON_OBJS= \ Python/pyctype.o \ Python/pyfpe.o \ Python/pyhash.o \ + Python/pylifecycle.o \ Python/pymath.o \ Python/pystate.o \ Python/pythonrun.o \ @@ -459,7 +473,7 @@ LIBRARY_OBJS= \ # Default target all: build_all -build_all: $(BUILDPYTHON) oldsharedmods sharedmods gdbhooks Modules/_testembed python-config +build_all: $(BUILDPYTHON) oldsharedmods sharedmods gdbhooks Programs/_testembed python-config # Compile a binary with gcc profile guided optimization. profile-opt: @@ -474,14 +488,14 @@ profile-opt: $(MAKE) build_all_use_profile build_all_generate_profile: - $(MAKE) all CFLAGS="$(CFLAGS) -fprofile-generate" LIBS="$(LIBS) -lgcov" + $(MAKE) all CFLAGS_NODIST="$(CFLAGS) -fprofile-generate" LDFLAGS="-fprofile-generate" LIBS="$(LIBS) -lgcov" run_profile_task: : # FIXME: can't run for a cross build $(RUNSHARED) ./$(BUILDPYTHON) $(PROFILE_TASK) build_all_use_profile: - $(MAKE) all CFLAGS="$(CFLAGS) -fprofile-use -fprofile-correction" + $(MAKE) all CFLAGS_NODIST="$(CFLAGS) -fprofile-use -fprofile-correction" # Compile and run with gcov .PHONY=coverage coverage-lcov coverage-report @@ -501,7 +515,6 @@ coverage-lcov: : # remove 3rd party modules and system headers @lcov --remove $(COVERAGE_INFO) \ '*/Modules/_ctypes/libffi*/*' \ - '*/Modules/_sha3/keccak/*' \ '*/Modules/_decimal/libmpdec/*' \ '*/Modules/expat/*' \ '*/Modules/zlib/*' \ @@ -533,8 +546,8 @@ clinic: $(BUILDPYTHON) $(RUNSHARED) $(PYTHON_FOR_BUILD) ./Tools/clinic/clinic.py --make # Build the interpreter -$(BUILDPYTHON): Modules/python.o $(LIBRARY) $(LDLIBRARY) $(PY3LIBRARY) - $(LINKCC) $(PY_LDFLAGS) $(LINKFORSHARED) -o $@ Modules/python.o $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST) +$(BUILDPYTHON): Programs/python.o $(LIBRARY) $(LDLIBRARY) $(PY3LIBRARY) + $(LINKCC) $(PY_LDFLAGS) $(LINKFORSHARED) -o $@ Programs/python.o $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST) platform: $(BUILDPYTHON) pybuilddir.txt $(RUNSHARED) $(PYTHON_FOR_BUILD) -c 'import sys ; from sysconfig import get_platform ; print(get_platform()+"-"+sys.version[0:3])' >platform @@ -542,8 +555,18 @@ platform: $(BUILDPYTHON) pybuilddir.txt # Create build directory and generate the sysconfig build-time data there. # pybuilddir.txt contains the name of the build dir and is used for # sys.path fixup -- see Modules/getpath.c. +# Since this step runs before shared modules are built, try to avoid bootstrap +# problems by creating a dummy pybuilddir.txt just to allow interpreter +# initialization to succeed. It will be overwritten by generate-posix-vars +# or removed in case of failure. pybuilddir.txt: $(BUILDPYTHON) - $(RUNSHARED) $(PYTHON_FOR_BUILD) -S -m sysconfig --generate-posix-vars + @echo "none" > ./pybuilddir.txt + $(RUNSHARED) $(PYTHON_FOR_BUILD) -S -m sysconfig --generate-posix-vars ;\ + if test $$? -ne 0 ; then \ + echo "generate-posix-vars failed" ; \ + rm -f ./pybuilddir.txt ; \ + exit 1 ; \ + fi # Build the shared modules # Under GNU make, MAKEFLAGS are sorted and normalized; the 's' for @@ -659,18 +682,19 @@ Modules/Setup: $(srcdir)/Modules/Setup.dist echo "-----------------------------------------------"; \ fi -Modules/_testembed: Modules/_testembed.o $(LIBRARY) $(LDLIBRARY) $(PY3LIBRARY) - $(LINKCC) $(PY_LDFLAGS) $(LINKFORSHARED) -o $@ Modules/_testembed.o $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST) +Programs/_testembed: Programs/_testembed.o $(LIBRARY) $(LDLIBRARY) $(PY3LIBRARY) + $(LINKCC) $(PY_LDFLAGS) $(LINKFORSHARED) -o $@ Programs/_testembed.o $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST) ############################################################################ # Importlib -Modules/_freeze_importlib: Modules/_freeze_importlib.o $(LIBRARY_OBJS_OMIT_FROZEN) - $(LINKCC) $(PY_LDFLAGS) -o $@ Modules/_freeze_importlib.o $(LIBRARY_OBJS_OMIT_FROZEN) $(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST) +Programs/_freeze_importlib.o: Programs/_freeze_importlib.c -Python/importlib.h: $(srcdir)/Lib/importlib/_bootstrap.py Modules/_freeze_importlib.c - $(MAKE) Modules/_freeze_importlib - ./Modules/_freeze_importlib \ +Programs/_freeze_importlib: Programs/_freeze_importlib.o $(LIBRARY_OBJS_OMIT_FROZEN) + $(LINKCC) $(PY_LDFLAGS) -o $@ Programs/_freeze_importlib.o $(LIBRARY_OBJS_OMIT_FROZEN) $(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST) + +Python/importlib.h: $(srcdir)/Lib/importlib/_bootstrap.py Programs/_freeze_importlib + ./Programs/_freeze_importlib \ $(srcdir)/Lib/importlib/_bootstrap.py Python/importlib.h @@ -698,11 +722,11 @@ Modules/getpath.o: $(srcdir)/Modules/getpath.c Makefile -DVPATH='"$(VPATH)"' \ -o $@ $(srcdir)/Modules/getpath.c -Modules/python.o: $(srcdir)/Modules/python.c - $(MAINCC) -c $(PY_CORE_CFLAGS) -o $@ $(srcdir)/Modules/python.c +Programs/python.o: $(srcdir)/Programs/python.c + $(MAINCC) -c $(PY_CORE_CFLAGS) -o $@ $(srcdir)/Programs/python.c -Modules/_testembed.o: $(srcdir)/Modules/_testembed.c - $(MAINCC) -c $(PY_CORE_CFLAGS) -o $@ $(srcdir)/Modules/_testembed.c +Programs/_testembed.o: $(srcdir)/Programs/_testembed.c + $(MAINCC) -c $(PY_CORE_CFLAGS) -o $@ $(srcdir)/Programs/_testembed.c Modules/_sre.o: $(srcdir)/Modules/_sre.c $(srcdir)/Modules/sre.h $(srcdir)/Modules/sre_constants.h $(srcdir)/Modules/sre_lib.h @@ -731,15 +755,13 @@ Python/sysmodule.o: $(srcdir)/Python/sysmodule.c Makefile $(IO_OBJS): $(IO_H) -$(GRAMMAR_H): $(GRAMMAR_INPUT) $(PGENSRCS) +$(GRAMMAR_H): $(GRAMMAR_INPUT) $(PGEN) @$(MKDIR_P) Include - $(MAKE) $(PGEN) $(PGEN) $(GRAMMAR_INPUT) $(GRAMMAR_H) $(GRAMMAR_C) -$(GRAMMAR_C): $(GRAMMAR_H) $(GRAMMAR_INPUT) $(PGENSRCS) - $(MAKE) $(GRAMMAR_H) +$(GRAMMAR_C): $(GRAMMAR_H) touch $(GRAMMAR_C) -$(PGEN): $(PGENOBJS) +$(PGEN): $(PGENOBJS) $(CC) $(OPT) $(PY_LDFLAGS) $(PGENOBJS) $(LIBS) -o $(PGEN) Parser/grammar.o: $(srcdir)/Parser/grammar.c \ @@ -761,6 +783,9 @@ $(AST_C): $(AST_H) $(AST_ASDL) $(ASDLGEN_FILES) $(MKDIR_P) $(AST_C_DIR) $(ASDLGEN) -c $(AST_C_DIR) $(AST_ASDL) +$(OPCODE_H): $(srcdir)/Lib/opcode.py $(OPCODE_H_SCRIPT) + $(OPCODE_H_GEN) + Python/compile.o Python/symtable.o Python/ast.o: $(GRAMMAR_H) $(AST_H) Python/getplatform.o: $(srcdir)/Python/getplatform.c @@ -872,7 +897,7 @@ PYTHON_HEADERS= \ $(srcdir)/Include/node.h \ $(srcdir)/Include/object.h \ $(srcdir)/Include/objimpl.h \ - $(srcdir)/Include/opcode.h \ + $(OPCODE_H) \ $(srcdir)/Include/osdefs.h \ $(srcdir)/Include/patchlevel.h \ $(srcdir)/Include/pgen.h \ @@ -885,6 +910,7 @@ PYTHON_HEADERS= \ $(srcdir)/Include/pyerrors.h \ $(srcdir)/Include/pyfpe.h \ $(srcdir)/Include/pyhash.h \ + $(srcdir)/Include/pylifecycle.h \ $(srcdir)/Include/pymath.h \ $(srcdir)/Include/pygetopt.h \ $(srcdir)/Include/pymacro.h \ @@ -910,9 +936,10 @@ PYTHON_HEADERS= \ $(srcdir)/Include/warnings.h \ $(srcdir)/Include/weakrefobject.h \ pyconfig.h \ - $(PARSER_HEADERS) + $(PARSER_HEADERS) \ + $(AST_H) -$(LIBRARY_OBJS) $(MODOBJS) Modules/python.o: $(PYTHON_HEADERS) +$(LIBRARY_OBJS) $(MODOBJS) Programs/python.o: $(PYTHON_HEADERS) ###################################################################### @@ -1116,28 +1143,34 @@ LIBSUBDIRS= tkinter tkinter/test tkinter/test/test_tkinter \ test/audiodata \ test/capath test/data \ test/cjkencodings test/decimaltestdata test/xmltestdata \ + test/eintrdata \ + test/imghdrdata \ test/subprocessdata test/sndhdrdata test/support \ test/tracedmodules test/encoded_modules \ - test/namespace_pkgs \ - test/namespace_pkgs/both_portions \ - test/namespace_pkgs/both_portions/foo \ - test/namespace_pkgs/not_a_namespace_pkg \ - test/namespace_pkgs/not_a_namespace_pkg/foo \ - test/namespace_pkgs/portion1 \ - test/namespace_pkgs/portion1/foo \ - test/namespace_pkgs/portion2 \ - test/namespace_pkgs/portion2/foo \ - test/namespace_pkgs/project1 \ - test/namespace_pkgs/project1/parent \ - test/namespace_pkgs/project1/parent/child \ - test/namespace_pkgs/project2 \ - test/namespace_pkgs/project2/parent \ - test/namespace_pkgs/project2/parent/child \ - test/namespace_pkgs/project3 \ - test/namespace_pkgs/project3/parent \ - test/namespace_pkgs/project3/parent/child \ - test/namespace_pkgs/module_and_namespace_package \ - test/namespace_pkgs/module_and_namespace_package/a_test \ + test/test_import \ + test/test_import/data \ + test/test_import/data/circular_imports \ + test/test_import/data/circular_imports/subpkg \ + test/test_importlib/namespace_pkgs \ + test/test_importlib/namespace_pkgs/both_portions \ + test/test_importlib/namespace_pkgs/both_portions/foo \ + test/test_importlib/namespace_pkgs/not_a_namespace_pkg \ + test/test_importlib/namespace_pkgs/not_a_namespace_pkg/foo \ + test/test_importlib/namespace_pkgs/portion1 \ + test/test_importlib/namespace_pkgs/portion1/foo \ + test/test_importlib/namespace_pkgs/portion2 \ + test/test_importlib/namespace_pkgs/portion2/foo \ + test/test_importlib/namespace_pkgs/project1 \ + test/test_importlib/namespace_pkgs/project1/parent \ + test/test_importlib/namespace_pkgs/project1/parent/child \ + test/test_importlib/namespace_pkgs/project2 \ + test/test_importlib/namespace_pkgs/project2/parent \ + test/test_importlib/namespace_pkgs/project2/parent/child \ + test/test_importlib/namespace_pkgs/project3 \ + test/test_importlib/namespace_pkgs/project3/parent \ + test/test_importlib/namespace_pkgs/project3/parent/child \ + test/test_importlib/namespace_pkgs/module_and_namespace_package \ + test/test_importlib/namespace_pkgs/module_and_namespace_package/a_test \ asyncio \ test/test_asyncio \ collections concurrent concurrent/futures encodings \ @@ -1321,7 +1354,7 @@ libainstall: all python-config fi; \ fi $(INSTALL_DATA) Modules/config.c $(DESTDIR)$(LIBPL)/config.c - $(INSTALL_DATA) Modules/python.o $(DESTDIR)$(LIBPL)/python.o + $(INSTALL_DATA) Programs/python.o $(DESTDIR)$(LIBPL)/python.o $(INSTALL_DATA) $(srcdir)/Modules/config.c.in $(DESTDIR)$(LIBPL)/config.c.in $(INSTALL_DATA) Makefile $(DESTDIR)$(LIBPL)/Makefile $(INSTALL_DATA) Modules/Setup $(DESTDIR)$(LIBPL)/Setup @@ -1332,10 +1365,10 @@ libainstall: all python-config $(INSTALL_SCRIPT) $(srcdir)/install-sh $(DESTDIR)$(LIBPL)/install-sh $(INSTALL_SCRIPT) python-config.py $(DESTDIR)$(LIBPL)/python-config.py $(INSTALL_SCRIPT) python-config $(DESTDIR)$(BINDIR)/python$(LDVERSION)-config - @if [ -s Modules/python.exp -a \ + @if [ -s Programs/python.exp -a \ "`echo $(MACHDEP) | sed 's/^\(...\).*/\1/'`" = "aix" ]; then \ echo; echo "Installing support files for building shared extension modules on AIX:"; \ - $(INSTALL_DATA) Modules/python.exp \ + $(INSTALL_DATA) Programs/python.exp \ $(DESTDIR)$(LIBPL)/python.exp; \ echo; echo "$(LIBPL)/python.exp"; \ $(INSTALL_SCRIPT) $(srcdir)/Modules/makexp_aix \ @@ -1484,8 +1517,12 @@ TAGS:: etags Include/*.h; \ for i in $(SRCDIRS); do etags -a $$i/*.[ch]; done -# Touch generated files +# This fixes up the mtimes of checked-in generated files, assuming that they +# only *appear* to be outdated because of checkout order. +# This is run while preparing a source release tarball, and can be run manually +# to avoid bootstrap issues. touch: + cd $(srcdir); \ hg --config extensions.touch=Tools/hg/hgtouch.py touch -v # Sanitation targets -- clean leaves libraries, executables and tags @@ -1514,7 +1551,7 @@ clean: pycremoval find build -name '*.py[co]' -exec rm -f {} ';' || true -rm -f pybuilddir.txt -rm -f Lib/lib2to3/*Grammar*.pickle - -rm -f Modules/_testembed Modules/_freeze_importlib + -rm -f Programs/_testembed Programs/_freeze_importlib profile-removal: find . -name '*.gc??' -exec rm -f {} ';' @@ -1538,7 +1575,7 @@ distclean: clobber done -rm -f core Makefile Makefile.pre config.status \ Modules/Setup Modules/Setup.local Modules/Setup.config \ - Modules/ld_so_aix Modules/python.exp Misc/python.pc + Modules/ld_so_aix Programs/python.exp Misc/python.pc -rm -f python*-gdb.py find $(srcdir)/[a-zA-Z]* '(' -name '*.fdc' -o -name '*~' \ -o -name '[@,#]*' -o -name '*.old' \ diff --git a/Misc/ACKS b/Misc/ACKS index 5e60f9b4ef32..f66baa38d4fc 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -16,20 +16,27 @@ Michael Abbott Rajiv Abraham David Abrahams Marc Abramowitz +Eldar Abusalimov Ron Adam +Anton Afanasyev Ali Afshar +Nitika Agarwal Jim Ahlstrom Farhan Ahmad Matthew Ahrens Nir Aides +Akira Yaniv Aknin Jyrki Alakuijala Steve Alexander Fred Allen +Jeff Allen Ray Allen Billy G. Allie Kevin Altis +Skyler Leigh Amador Joe Amenta +Rose Ames A. Amoroso Mark Anacker Shashwat Anand @@ -39,7 +46,9 @@ Pehr Anderson Erik Andersén Oliver Andrich Ross Andrus +Fabrice Aneche Juancarlo Añez +Chris Angelico Jérémy Anger Ankur Ankan Jon Anglin @@ -71,6 +80,7 @@ Michael J. Barber Daniel Barclay Nicolas Bareil Chris Barker +Steven Barker Anton Barkovsky Nick Barnes Quentin Barnes @@ -80,6 +90,7 @@ Richard Barran Cesar Eduardo Barros Des Barry Ulf Bartelt +Campbell Barton Don Bashford Pior Bastida Nick Bastin @@ -91,10 +102,12 @@ Mike Bayer Samuel L. Bayer Donald Beaudry David Beazley +Ingolf Becker Neal Becker Robin Becker Torsten Becker Bill Bedford +Ian Beer Stefan Behnel Reimer Behrends Ben Bell @@ -131,6 +144,7 @@ Martin Bless Pablo Bleyer Erik van Blokland Eric Blossom +Sergey Bobrov Finn Bock Paul Boddie Matthew Boedicker @@ -167,6 +181,7 @@ Keith Briggs Tobias Brink Richard Brodie Michael Broghton +Ammar Brohi Daniel Brotsky Jean Brouwers Gary S. Brown @@ -190,7 +205,9 @@ Roger Burnham Alastair Burt Tarn Weisner Burton Lee Busby +Katherine Busch Ralph Butler +Zach Byrne Nicolas Cadou Jp Calderone Arnaud Calmettes @@ -202,6 +219,7 @@ Pierre Carrier Terry Carroll Edward Catmur Lorenzo M. Catucci +Bruno Cauet Donn Cave Charles Cazabon Jesús Cea Avión @@ -209,6 +227,7 @@ Per Cederqvist Matej Cepl Carl Cerecke Octavian Cerna +Michael Cetrulo Dave Chambers Pascal Chambon John Chandler @@ -218,23 +237,28 @@ Godefroid Chapelle Brad Chapman Greg Chapman Mitch Chapman +Matt Chaput Yogesh Chaudhari David Chaum Nicolas Chauvat Jerry Chen Michael Chermside Ingrid Cheung +Terry Chia Albert Chin-A-Young Adal Chiriliuc Matt Chisholm +Lita Cho Anders Chrigström Tom Christiansen +Renee Chu Vadim Chugunov Mauro Cicognini David Cinege Craig Citro Gilles Civario Chris Clark +Diana Clarke Laurie Clark-Michalek Mike Clarkson Andrew Clegg @@ -256,11 +280,13 @@ Denver Coneybeare Phil Connell Juan José Conti Matt Conway +Devin Cook David M. Cooke Jason R. Coombs Garrett Cooper Greg Copeland Aldo Cortesi +Ian Cordasco David Costanzo Scott Cotton Greg Couch @@ -279,6 +305,7 @@ Drew Csillag Joaquin Cuenca Abela John Cugini Tom Culliton +Raúl Cumplido Antonio Cuni Brian Curtin Lisandro Dalcin @@ -293,12 +320,14 @@ Kushal Das Jonathan Dasteel Pierre-Yves David A. Jesse Jiryu Davis +Merlijn van Deen John DeGood Ned Deily Vincent Delft Arnaud Delobelle Konrad Delong Erik Demaine +Martin Dengler John Dennis L. Peter Deutsch Roger Dev @@ -337,6 +366,7 @@ Virgil Dupras Bruno Dupuis Andy Dustman Gary Duzan +Karmen Dykstra Eugene Dvurechenski Josip Dzolonga Maxim Dzumanenko @@ -385,17 +415,20 @@ Mark Favas Boris Feld Thomas Fenzl Niels Ferguson +Francisco Fernández Castaño Sebastian Fernandez Florian Festi John Feuerstein Carl Feynman Vincent Fiack +Anastasia Filatova Tomer Filiba Jeffrey Finkelstein Russell Finn Dan Finnie Nils Fischbeck Frederik Fix +Tom Flanagan Matt Fleming Hernán Martínez Foffani Artem Fokin @@ -403,6 +436,7 @@ Arnaud Fontaine Michael Foord Amaury Forgeot d'Arc Doug Fort +Chris Foster John Fouhy Andrew Francis Stefan Franke @@ -440,6 +474,7 @@ Stephen M. Gava Xavier de Gaye Harry Henry Gebel Marius Gedminas +Jan-Philip Gehrcke Thomas Gellekum Gabriel Genellina Christos Georgiou @@ -455,6 +490,7 @@ Yannick Gingras Matt Giuca Wim Glenn Michael Goderbauer +Karan Goel Jeroen Van Goey Christoph Gohlke Tim Golden @@ -464,16 +500,20 @@ Chris Gonnerman Shelley Gooch David Goodger Hans de Graaff +Tim Graham +Kim Gräsman Nathaniel Gray Eddy De Greef Grant Griffin Andrea Griffini Duncan Grisby +Olivier Grisel Fabian Groffen Eric Groo Dag Gruneau Filip GruszczyÅ„ski Thomas Guettler +Yuyang Guo Anuj Gupta Michael Guravage Lars Gustäbel @@ -501,6 +541,7 @@ Barry Hantman Lynda Hardman Derek Harland Jason Harper +David Harrigan Brian Harring Jonathan Hartley Travis B. Hartwell @@ -531,8 +572,10 @@ Bernhard Herzog Magnus L. Hetland Raymond Hettinger Kevan Heydon +Wouter van Heyst Kelsey Hightower Jason Hildebrand +Aaron Hill Richie Hindle Konrad Hinsen David Hobley @@ -544,6 +587,7 @@ Stefan Hoffmeister Albert Hofkamp Tomas Hoger Jonathan Hogg +Kamilla Holanda Steve Holden Akintayo Holder Thomas Holenstein @@ -561,9 +605,12 @@ Randall Hopper Nadav Horesh Alon Horev Jan Hosang +Jonathan Hosmer +Alan Hourihane Ken Howard Brad Howes Mike Hoy +Ben Hoyt Chih-Hao Huang Christian Hudon Lawrence Hudson @@ -571,6 +618,7 @@ Michael Hudson Jim Hugunin Greg Humphreys Eric Huss +Nehal Hussain Taihyun Hwang Jeremy Hylton Ludwig Hähne @@ -582,7 +630,9 @@ Ali Ikinci Aaron Iles Lars Immisch Bobby Impollonia +Naoki Inada Meador Inge +Peter Ingebretson Tony Ingraldi John Interrante Bob Ippolito @@ -604,6 +654,7 @@ Juhana Jauhiainen Rajagopalasarma Jayakrishnan Zbigniew JÄ™drzejewski-Szmek Julien Jehannet +Muhammad Jehanzeb Drew Jenkins Flemming Kjær Jensen Philip H. Jensen @@ -623,6 +674,7 @@ Thomas Jollans Nicolas Joly Brian K. Jones Evan Jones +Glenn Jones Jeremy Jones Richard Jones Irmen de Jong @@ -642,6 +694,7 @@ Kurt B. Kaiser Tamito Kajiyama Jan Kaliszewski Peter van Kampen +Jan Kanis Rafe Kaplan Jacob Kaplan-Moss Janne Karila @@ -649,6 +702,7 @@ Per Øyvind Karlsen Anton Kasyanov Lou Kates Hiroaki Kawai +Brian Kearns Sebastien Keim Ryan Kelly Dan Kenigsberg @@ -663,6 +717,8 @@ Mads Kiilerich Jason Killen Jan Kim Taek Joo Kim +Sam Kimbrel +James King W. Trevor King Paul Kippes Steve Kirsch @@ -710,6 +766,7 @@ Steven Kryskalla Andrew Kuchling Dave Kuhlman Jon Kuhn +Toshio Kuratomi Vladimir Kushnir Erno Kuusela Ross Lagerwall @@ -722,6 +779,7 @@ Ronan Lamy Torsten Landschoff Åukasz Langa Tino Lange +Glenn Langford Andrew Langmead Detlef Lannert Soren Larsen @@ -733,6 +791,8 @@ Julia Lawall Chris Lawrence Brian Leair Mathieu Leduc-Hamel +Amandine Lee +Antony Lee Christopher Lee Inyeol Lee James Lee @@ -766,6 +826,7 @@ Ross Light Shawn Ligocki Martin Ligr Gediminas Liktaras +Vitor de Lima Grant Limberg Christopher Lindblad Ulf A. Lindgren @@ -803,6 +864,7 @@ Tim MacKenzie Nick Maclaren Don MacMillen Tomasz Maćkowiak +Wolfgang Maier Steve Majewski Marek Majkowski Grzegorz Makarewicz @@ -834,6 +896,7 @@ Madison May Lucas Maystre Arnaud Mazin Matt McClure +Jack McCracken Rebecca McCreary Kirk McDonald Chris McDonough @@ -940,11 +1003,13 @@ Nigel O'Brian John O'Connor Kevin O'Connor Tim O'Malley +Dan O'Reilly Zooko O'Whielacronx Aaron Oakley James Oakley Elena Oat Jon Oberheide +Milan Oberkirch Pascal Oberndoerfer Jeffrey Ollie Adam Olsen @@ -954,6 +1019,7 @@ Piet van Oostrum Tomas Oppelstrup Jason Orendorff Douglas Orr +William Orr Michele Orrù Oleg Oshmyan Denis S. Otkidach @@ -969,12 +1035,15 @@ Mike Pall Todd R. Palmer Juan David Ibáñez Palomar Jan Palus +Yongzhi Pan +Martin Panter Mathias Panzenböck M. Papillon Peter Parente Alexandre Parenteau Dan Parisien William Park +Claude Paroz Heikki Partanen Harri Pasanen Gaël Pasgrimaud @@ -1020,6 +1089,7 @@ Antoine Pitrou Jean-François Piéronne Oleg Plakhotnyuk Remi Pointel +Jon Poler Ariel Poliak Guilherme Polo Illia Polosukhin @@ -1046,10 +1116,12 @@ Thomas Rachel Ram Rachum Jérôme Radix Burton Radons +Shorya Raj Jeff Ramnani Brodie Rao Senko Rasic Antti Rasinen +Nikolaus Rath Sridhar Ratnakumar Ysj Ray Eric S. Raymond @@ -1075,6 +1147,7 @@ Francesco Ricciardi Tim Rice Jan Pieter Riegel Armin Rigo +Martin Richard Arc Riley Nicholas Riley Jean-Claude Rimbault @@ -1085,11 +1158,13 @@ Juan M. Bello Rivas Davide Rizzo Anthony Roach Carl Robben +Ben Roberts Mark Roberts Andy Robinson Jim Robinson Mark Roddy Kevin Rodgers +Sean Rodman Giampaolo Rodola Elson Rodriguez Adi Roiban @@ -1099,12 +1174,14 @@ Armin Ronacher Case Roole Timothy Roscoe Erik Rose +Josh Rosenberg Jim Roskind Brian Rosner Guido van Rossum Just van Rossum Hugo van Rossum Saskia van Rossum +Clement Rouault Donald Wallace Rouse II Liam Routt Todd Rovito @@ -1128,16 +1205,19 @@ Sébastien Sablé Suman Saha Hajime Saitou George Sakkis +Victor Salgado Rich Salz Kevin Samborn Adrian Sampson James Sanders Ilya Sandler Rafael Santos +Simon Sapin Mark Sapiro Ty Sarna Hugh Sasse Bob Savage +Dave Sawyer Ben Sayer sbt Marco Scataglini @@ -1159,6 +1239,7 @@ Robin Schreiber Chad J. Schroeder Christian Schubert Sam Schulenburg +Andreas Schwab Stefan Schwarzer Dietmar Schwertberger Federico Schwindt @@ -1180,6 +1261,7 @@ Daniel Shahaf Ha Shao Mark Shannon Richard Shapiro +Varun Sharma Vlad Shcherbina Justin Sheehy Charlie Shepherd @@ -1215,6 +1297,7 @@ Eric V. Smith Gregory P. Smith Mark Smith Roy Smith +Ryan Smith-Roberts Rafal Smotrzyk Eric Snow Dirk Soede @@ -1222,6 +1305,7 @@ Paul Sokolovsky Evgeny Sologubov Cody Somerville Edoardo Spadolini +Geoffrey Spear Clay Spence Stefan Sperling Nicholas Spies @@ -1237,6 +1321,7 @@ Joel Stanley Anthony Starks Oliver Steele Greg Stein +Marek Stepniowski Baruch Sterin Chris Stern Alex Stewart @@ -1261,8 +1346,10 @@ Hisao Suzuki Kalle Svensson Andrew Svetlov Paul Swartz +Al Sweigart Thenault Sylvain Péter Szabó +John Szakmeister Amir Szekely Arfrever Frehtes Taifersar Arahesis Hideaki Takahashi @@ -1276,6 +1363,7 @@ Steven Taschuk Amy Taylor Monty Taylor Anatoly Techtonik +Gustavo Temple Mikhail Terekhov Victor Terrón Richard M. Tew @@ -1308,6 +1396,7 @@ David Townshend Nathan Trapuzzano Laurence Tratt Alberto Trevino +Mayank Tripathi Matthias Troffaes Tom Tromey John Tromp @@ -1329,6 +1418,7 @@ Roger Upole Daniel Urban Michael Urman Hector Urtubia +Lukas Vacek Ville Vainio Andi Vajda Case Van Horsen @@ -1353,9 +1443,11 @@ Norman Vine Pauli Virtanen Frank Visser Johannes Vogel +Radu Voicilas Alex Volkov Martijn Vries Sjoerd de Vries +Guido Vranken Niki W. Waibel Wojtek Walczak Charles Waldman @@ -1374,6 +1466,7 @@ Bob Watson David Watson Aaron Watters Henrik Weber +Leon Weber Corran Webster Glyn Webster Phil Webster @@ -1399,8 +1492,10 @@ Gerald S. Williams Jason Williams John Williams Sue Williams +Carol Willing Steven Willis Frank Willison +David Wilson Geoff Wilson Greg V. Wilson J Derek Wilson @@ -1410,6 +1505,7 @@ Collin Winter Dik Winter Blake Winton Jean-Claude Wippler +Stéphane Wirtel Lars Wirzenius John Wiseman Chris Withers @@ -1425,6 +1521,7 @@ Gordon Worley Darren Worrall Thomas Wouters Daniel Wozniak +Wei Wu Heiko Wundram Doug Wyatt Robert Xiao @@ -1453,4 +1550,6 @@ Uwe Zessin Cheng Zhang Kai Zhu Tarek Ziadé +Gennadiy Zlobin +Doug Zongker Peter Ã…strand diff --git a/Misc/HISTORY b/Misc/HISTORY index 4280764d18f2..2b4760d57a1f 100644 --- a/Misc/HISTORY +++ b/Misc/HISTORY @@ -18,13 +18,13 @@ Core and Builtins - Issue #16046: Fix loading sourceless legacy .pyo files. -- Issue #16060: Fix refcounting bug when __trunc__ returns an object - whose __int__ gives a non-integer. Patch by Serhiy Storchaka. +- Issue #16060: Fix refcounting bug when `__trunc__()` returns an object whose + `__int__()` gives a non-integer. Patch by Serhiy Storchaka. Extension Modules ----------------- -- Issue #16012: Fix a regression in pyexpat. The parser's UseForeignDTD() +- Issue #16012: Fix a regression in pyexpat. The parser's `UseForeignDTD()` method doesn't require an argument again. @@ -36,26 +36,26 @@ What's New in Python 3.3.0 Release Candidate 3? Core and Builtins ----------------- -- Issue #15900: Fix reference leak in PyUnicode_TranslateCharmap(). +- Issue #15900: Fix reference leak in `PyUnicode_TranslateCharmap()`. - Issue #15926: Fix crash after multiple reinitializations of the interpreter. - Issue #15895: Fix FILE pointer leak in one error branch of - PyRun_SimpleFileExFlags() when filename points to a pyc/pyo file, closeit - is false an and set_main_loader() fails. + `PyRun_SimpleFileExFlags()` when filename points to a pyc/pyo file, closeit is + false an and set_main_loader() fails. - Fixes for a few crash and memory leak regressions found by Coverity. Library ------- -- Issue #15882: Change _decimal to accept any coefficient tuple when - constructing infinities. This is done for backwards compatibility - with decimal.py: Infinity coefficients are undefined in _decimal - (in accordance with the specification). +- Issue #15882: Change `_decimal` to accept any coefficient tuple when + constructing infinities. This is done for backwards compatibility with + decimal.py: Infinity coefficients are undefined in _decimal (in accordance + with the specification). -- Issue #15925: Fix a regression in email.util where the parsedate() and - parsedate_tz() functions did not return None anymore when the argument could +- Issue #15925: Fix a regression in `email.util` where the `parsedate()` and + `parsedate_tz()` functions did not return None anymore when the argument could not be parsed. Extension Modules @@ -67,7 +67,7 @@ Extension Modules - Issue #15977: Fix memory leak in Modules/_ssl.c when the function _set_npn_protocols() is called multiple times, thanks to Daniel Sommermann. -- Issue #15969: faulthandler module: rename dump_tracebacks_later() to +- Issue #15969: `faulthandler` module: rename dump_tracebacks_later() to dump_traceback_later() and cancel_dump_tracebacks_later() to cancel_dump_traceback_later(). @@ -83,35 +83,37 @@ Core and Builtins ----------------- - Issue #13992: The trashcan mechanism is now thread-safe. This eliminates - sporadic crashes in multi-thread programs when several long deallocator - chains ran concurrently and involved subclasses of built-in container - types. + sporadic crashes in multi-thread programs when several long deallocator chains + ran concurrently and involved subclasses of built-in container types. -- Issue #15784: Modify OSError.__str__() to better distinguish between - errno error numbers and Windows error numbers. +- Issue #15784: Modify `OSError`.__str__() to better distinguish between errno + error numbers and Windows error numbers. - Issue #15781: Fix two small race conditions in import's module locking. Library ------- -- Issue #15847: Fix a regression in argparse, which did not accept tuples - as argument lists anymore. +- Issue #17158: Add 'symbols' to help() welcome message; clarify + 'modules spam' messages. + +- Issue #15847: Fix a regression in argparse, which did not accept tuples as + argument lists anymore. -- Issue #15828: Restore support for C extensions in imp.load_module(). +- Issue #15828: Restore support for C extensions in `imp.load_module()`. -- Issue #15340: Fix importing the random module when /dev/urandom cannot - be opened. This was a regression caused by the hash randomization patch. +- Issue #15340: Fix importing the random module when ``/dev/urandom`` cannot be + opened. This was a regression caused by the hash randomization patch. -- Issue #10650: Deprecate the watchexp parameter of the Decimal.quantize() +- Issue #10650: Deprecate the watchexp parameter of the `Decimal.quantize()` method. -- Issue #15785: Modify window.get_wch() API of the curses module: return - a character for most keys, and an integer for special keys, instead of - always returning an integer. So it is now possible to distinguish special - keys like keypad keys. +- Issue #15785: Modify `window.get_wch()` API of the curses module: return a + character for most keys, and an integer for special keys, instead of always + returning an integer. So it is now possible to distinguish special keys like + keypad keys. -- Issue #14223: Fix window.addch() of the curses module for special characters +- Issue #14223: Fix `window.addch()` of the curses module for special characters like curses.ACS_HLINE: the Python function addch(int) and addch(bytes) is now calling the C function waddch()/mvwaddch() (as it was done in Python 3.2), instead of wadd_wch()/mvwadd_wch(). The Python function addch(str) is still @@ -127,10 +129,10 @@ Build Documentation ------------- -- Issue #15814: The memoryview enhancements in 3.3.0 accidentally permitted - the hashing of multi-dimensional memorviews and memoryviews with multi-byte - item formats. The intended restrictions have now been documented - they - will be correctly enforced in 3.3.1 +- Issue #15814: The memoryview enhancements in 3.3.0 accidentally permitted the + hashing of multi-dimensional memorviews and memoryviews with multi-byte item + formats. The intended restrictions have now been documented - they will be + correctly enforced in 3.3.1. What's New in Python 3.3.0 Release Candidate 1? @@ -144,131 +146,123 @@ Core and Builtins - Issue #15573: memoryview comparisons are now performed by value with full support for any valid struct module format definition. -- Issue #15316: When an item in the fromlist for __import__ doesn't exist, +- Issue #15316: When an item in the fromlist for `__import__()` doesn't exist, don't raise an error, but if an exception is raised as part of an import do let that propagate. -- Issue #15778: ensure that str(ImportError(msg)) returns a str - even when msg isn't a str. +- Issue #15778: Ensure that ``str(ImportError(msg))`` returns a str even when + msg isn't a str. -- Issue #2051: Source file permission bits are once again correctly - copied to the cached bytecode file. (The migration to importlib - reintroduced this problem because these was no regression test. A test - has been added as part of this patch) +- Issue #2051: Source file permission bits are once again correctly copied to + the cached bytecode file. (The migration to importlib reintroduced this + problem because these was no regression test. A test has been added as part of + this patch) -- Issue #15761: Fix crash when PYTHONEXECUTABLE is set on Mac OS X. +- Issue #15761: Fix crash when ``PYTHONEXECUTABLE`` is set on Mac OS X. -- Issue #15726: Fix incorrect bounds checking in PyState_FindModule. - Patch by Robin Schreiber. +- Issue #15726: Fix incorrect bounds checking in PyState_FindModule. Patch by + Robin Schreiber. -- Issue #15604: Update uses of PyObject_IsTrue() to check for and handle +- Issue #15604: Update uses of `PyObject_IsTrue()` to check for and handle errors correctly. Patch by Serhiy Storchaka. -- Issue #14846: importlib.FileFinder now handles the case where the - directory being searched is removed after a previous import attempt +- Issue #14846: `importlib.FileFinder` now handles the case where the directory + being searched is removed after a previous import attempt. Library ------- -- Issue #13370: Ensure that ctypes works on Mac OS X when Python is - compiled using the clang compiler +- Issue #13370: Ensure that ctypes works on Mac OS X when Python is compiled + using the clang compiler. -- Issue #13072: The array module's 'u' format code is now deprecated and - will be removed in Python 4.0. +- Issue #13072: The array module's 'u' format code is now deprecated and will be + removed in Python 4.0. - Issue #15544: Fix Decimal.__float__ to work with payload-carrying NaNs. -- Issue #15249: BytesGenerator now correctly mangles From lines (when +- Issue #15776: Allow pyvenv to work in existing directory with --clean. + +- Issue #15249: email's BytesGenerator now correctly mangles From lines (when requested) even if the body contains undecodable bytes. - Issue #15777: Fix a refleak in _posixsubprocess. -- Issue ##665194: Update email.utils.localtime to use datetime.astimezone and +- Issue ##665194: Update `email.utils.localtime` to use datetime.astimezone and correctly handle historic changes in UTC offsets. - Issue #15199: Fix JavaScript's default MIME type to application/javascript. Patch by Bohuslav Kabrda. -- Issue #12643: code.InteractiveConsole now respects sys.excepthook when - displaying exceptions (Patch by Aaron Iles) - -- Issue #13579: string.Formatter now understands the 'a' conversion specifier. +- Issue #12643: `code.InteractiveConsole` now respects `sys.excepthook` when + displaying exceptions. Patch by Aaron Iles. -- Issue #15793: Stack corruption in ssl.RAND_egd(). - Patch by Serhiy Storchaka. +- Issue #13579: `string.Formatter` now understands the 'a' conversion specifier. -- Issue #15595: Fix subprocess.Popen(universal_newlines=True) - for certain locales (utf-16 and utf-32 family). Patch by Chris Jerdonek. +- Issue #15595: Fix ``subprocess.Popen(universal_newlines=True)`` for certain + locales (utf-16 and utf-32 family). Patch by Chris Jerdonek. - Issue #15477: In cmath and math modules, add workaround for platforms whose system-supplied log1p function doesn't respect signs of zeros. -- Issue #15715: importlib.__import__() will silence an ImportError when the use - of fromlist leads to a failed import. +- Issue #15715: `importlib.__import__()` will silence an ImportError when the + use of fromlist leads to a failed import. -- Issue #14669: Fix pickling of connections and sockets on MacOSX - by sending/receiving an acknowledgment after file descriptor transfer. - TestPicklingConnection has been reenabled for MacOSX. +- Issue #14669: Fix pickling of connections and sockets on Mac OS X by + sending/receiving an acknowledgment after file descriptor transfer. + TestPicklingConnection has been reenabled for Mac OS X. - Issue #11062: Fix adding a message from file to Babyl mailbox. -- Issue #15646: Prevent equivalent of a fork bomb when using - multiprocessing on Windows without the "if __name__ == '__main__'" - idiom. +- Issue #15646: Prevent equivalent of a fork bomb when using `multiprocessing` + on Windows without the ``if __name__ == '__main__'`` idiom. -- Issue #15678: Fix IDLE menus when started from OS X command line - (3.3.0b2 regression). - -C API ------ - -Extension Modules ------------------ +IDLE +---- -Tools/Demos ------------ +- Issue #15678: Fix IDLE menus when started from OS X command line (3.3.0b2 + regression). Documentation ------------- -- Issue #14674: Add a discussion of the json module's standard compliance. +- Touched up the Python 2 to 3 porting guide. + +- Issue #14674: Add a discussion of the `json` module's standard compliance. Patch by Chris Rebert. - Create a 'Concurrent Execution' section in the docs, and split up the 'Optional Operating System Services' section to use a more user-centric - classification scheme (splitting them across the new CE section, IPC and - text processing). Operating system limitatons can be reflected with - the Sphinx ``:platform:`` tag, it doesn't make sense as part of the Table of - Contents. + classification scheme (splitting them across the new CE section, IPC and text + processing). Operating system limitations can be reflected with the Sphinx + ``:platform:`` tag, it doesn't make sense as part of the Table of Contents. -- Issue #4966: Bring the sequence docs up to date for the Py3k transition - and the many language enhancements since they were original written +- Issue #4966: Bring the sequence docs up to date for the Py3k transition and + the many language enhancements since they were original written. - The "path importer" misnomer has been replaced with Eric Snow's - more-awkward-but-at-least-not-wrong suggestion of "path based finder" in - the import system reference docs + more-awkward-but-at-least-not-wrong suggestion of "path based finder" in the + import system reference docs. -- Issue #15640: Document importlib.abc.Finder as deprecated. +- Issue #15640: Document `importlib.abc.Finder` as deprecated. -- Issue #15630: Add an example for "continue" stmt in the tutorial. Patch by +- Issue #15630: Add an example for "continue" stmt in the tutorial. Patch by Daniel Ellis. Tests ----- - Issue #15747: ZFS always returns EOPNOTSUPP when attempting to set the - UF_IMMUTABLE flag (via either chflags or lchflags); refactor affected - tests in test_posix.py to account for this. + UF_IMMUTABLE flag (via either chflags or lchflags); refactor affected tests in + test_posix.py to account for this. -- Issue #15285: Refactor the approach for testing connect timeouts using - two external hosts that have been configured specifically for this type - of test. +- Issue #15285: Refactor the approach for testing connect timeouts using two + external hosts that have been configured specifically for this type of test. -- Issue #15743: Remove the deprecated method usage in urllib tests. Patch by +- Issue #15743: Remove the deprecated method usage in `urllib` tests. Patch by Jeff Knupp. -- Issue #15615: Add some tests for the json module's handling of invalid - input data. Patch by Kushal Das. +- Issue #15615: Add some tests for the `json` module's handling of invalid input + data. Patch by Kushal Das. Build ----- @@ -277,11 +271,11 @@ Build - Pick up 32-bit launcher from PGO directory on 64-bit PGO build. -- Drop PC\python_nt.h as it's not used. Add input dependency on custom +- Drop ``PC\python_nt.h`` as it's not used. Add input dependency on custom build step. -- Issue #15511: Drop explicit dependency on pythonxy.lib from _decimal - amd64 configuration. +- Issue #15511: Drop explicit dependency on pythonxy.lib from _decimal amd64 + configuration. - Add missing PGI/PGO configurations for pywlauncher. @@ -296,15 +290,15 @@ What's New in Python 3.3.0 Beta 2? Core and Builtins ----------------- -- Issue #15568: Fix the return value of "yield from" when StopIteration is +- Issue #15568: Fix the return value of ``yield from`` when StopIteration is raised by a custom iterator. -- Issue #13119: sys.stdout and sys.stderr are now using "\r\n" newline on +- Issue #13119: `sys.stdout` and `sys.stderr` are now using "\r\n" newline on Windows, as Python 2. - Issue #15534: Fix the fast-search function for non-ASCII Unicode strings. -- Issue #15508: Fix the docstring for __import__ to have the proper default +- Issue #15508: Fix the docstring for `__import__()` to have the proper default value of 0 for 'level' and to not mention negative levels since they are not supported. @@ -317,17 +311,17 @@ Core and Builtins byte code files) equal between 32-bit and 64-bit systems. - Issue #1692335: Move initial exception args assignment to - "BaseException.__new__" to help pickling of naive subclasses. + `BaseException.__new__()` to help pickling of naive subclasses. -- Issue #12834: Fix PyBuffer_ToContiguous() for non-contiguous arrays. +- Issue #12834: Fix `PyBuffer_ToContiguous()` for non-contiguous arrays. -- Issue #15456: Fix code __sizeof__ after #12399 change. Patch by Serhiy +- Issue #15456: Fix code `__sizeof__()` after #12399 change. Patch by Serhiy Storchaka. - Issue #15404: Refleak in PyMethodObject repr. -- Issue #15394: An issue in PyModule_Create that caused references to be leaked - on some error paths has been fixed. Patch by Julia Lawall. +- Issue #15394: An issue in `PyModule_Create()` that caused references to be + leaked on some error paths has been fixed. Patch by Julia Lawall. - Issue #15368: An issue that caused bytecode generation to be non-deterministic has been fixed. @@ -335,7 +329,7 @@ Core and Builtins - Issue #15202: Consistently use the name "follow_symlinks" for new parameters in os and shutil functions. -- Issue #15314: __main__.__loader__ is now set correctly during interpreter +- Issue #15314: ``__main__.__loader__`` is now set correctly during interpreter startup. - Issue #15111: When a module imported using 'from import' has an ImportError @@ -350,57 +344,62 @@ Core and Builtins - Issue #15110: Fix the tracebacks generated by "import xxx" to not show the importlib stack frames. +- Issue #16369: Global PyTypeObjects not initialized with PyType_Ready(...). + - Issue #15020: The program name used to search for Python's path is now "python3" under Unix, not "python". -- Issue #15033: Fix the exit status bug when modules invoked using -m swith, +- Issue #15897: zipimport.c doesn't check return value of fseek(). + Patch by Felipe Cruz. + +- Issue #15033: Fix the exit status bug when modules invoked using -m switch, return the proper failure return value (1). Patch contributed by Jeff Knupp. -- Issue #15229: An OSError subclass whose __init__ doesn't call back +- Issue #15229: An `OSError` subclass whose __init__ doesn't call back OSError.__init__ could produce incomplete instances, leading to crashes when calling str() on them. -- Issue 15307: Virtual environments now use symlinks with framework builds on +- Issue #15307: Virtual environments now use symlinks with framework builds on Mac OS X, like other POSIX builds. Library ------- -- Issue #15424: Add a __sizeof__ implementation for array objects. Patch by +- Issue #14590: configparser now correctly strips inline comments when delimiter + occurs earlier without preceding space. + +- Issue #15424: Add a `__sizeof__()` implementation for array objects. Patch by Ludwig Hähne. - Issue #15576: Allow extension modules to act as a package's __init__ module. -- Issue #15502: Have importlib.invalidate_caches() work on sys.meta_path instead - of sys.path_importer_cache. +- Issue #15502: Have `importlib.invalidate_caches()` work on `sys.meta_path` + instead of `sys.path_importer_cache`. - Issue #15163: Pydoc shouldn't list __loader__ as module data. - Issue #15471: Do not use mutable objects as defaults for - importlib.__import__(). + `importlib.__import__()`. - Issue #15559: To avoid a problematic failure mode when passed to the bytes - constructor, objects in the ipaddress module no longer implement __index__ - (they still implement __int__ as appropriate) + constructor, objects in the ipaddress module no longer implement `__index__()` + (they still implement `__int__()` as appropriate). - Issue #15546: Fix handling of pathological input data in the peek() and read1() methods of the BZ2File, GzipFile and LZMAFile classes. -- Issue #13052: Fix IDLE crashing when replace string in Search/Replace dialog - ended with '\'. Patch by Roger Serwy. - -- Issue #12655: Instead of requiring a custom type, os.sched_getaffinity and - os.sched_setaffinity now use regular sets of integers to represent the CPUs a - process is restricted to. +- Issue #12655: Instead of requiring a custom type, `os.sched_getaffinity()` and + `os.sched_setaffinity()` now use regular sets of integers to represent the + CPUs a process is restricted to. -- Issue #15538: Fix compilation of the getnameinfo() / getaddrinfo() emulation - code. Patch by Philipp Hagemeister. +- Issue #15538: Fix compilation of the `socket.getnameinfo()` / + `socket.getaddrinfo()` emulation code. Patch by Philipp Hagemeister. - Issue #15519: Properly expose WindowsRegistryFinder in importlib (and use the - correct term for it). Original patch by Eric Snow. + correct term for it). Original patch by Eric Snow. - Issue #15502: Bring the importlib ABCs into line with the current state of the - import protocols given PEP 420. Original patch by Eric Snow. + import protocols given PEP 420. Original patch by Eric Snow. - Issue #15499: Launching a webbrowser in Unix used to sleep for a few seconds. Original patch by Anton Barkovsky. @@ -408,37 +407,36 @@ Library - Issue #15463: The faulthandler module truncates strings to 500 characters, instead of 100, to be able to display long file paths. -- Issue #6056: Make multiprocessing use setblocking(True) on the sockets it +- Issue #6056: Make `multiprocessing` use setblocking(True) on the sockets it uses. Original patch by J Derek Wilson. - Issue #15364: Fix sysconfig.get_config_var('srcdir') to be an absolute path. -- Issue #15041: Update "see also" list in tkinter documentation. - -- Issue #15413: os.times() had disappeared under Windows. +- Issue #15413: `os.times()` had disappeared under Windows. -- Issue #15402: An issue in the struct module that caused sys.getsizeof to +- Issue #15402: An issue in the struct module that caused `sys.getsizeof()` to return incorrect results for struct.Struct instances has been fixed. Initial patch by Serhiy Storchaka. -- Issue #15232: When mangle_from is True, email.Generator now correctly mangles - lines that start with 'From ' that occur in a MIME preamble or epilogue. +- Issue #15232: When mangle_from is True, `email.Generator` now correctly + mangles lines that start with 'From ' that occur in a MIME preamble or + epilogue. - Issue #15094: Incorrectly placed #endif in _tkinter.c. Patch by Serhiy Storchaka. -- Issue #13922: argparse no longer incorrectly strips '--'s that appear after +- Issue #13922: `argparse` no longer incorrectly strips '--'s that appear after the first one. -- Issue #12353: argparse now correctly handles null argument values. +- Issue #12353: `argparse` now correctly handles null argument values. - Issue #10017, issue #14998: Fix TypeError using pprint on dictionaries with user-defined types as keys or other unorderable keys. -- Issue #15397: inspect.getmodulename() is now based directly on importlib via a - new importlib.machinery.all_suffixes() API. +- Issue #15397: `inspect.getmodulename()` is now based directly on importlib via + a new `importlib.machinery.all_suffixes()` API. -- Issue #14635: telnetlib will use poll() rather than select() when possible to +- Issue #14635: `telnetlib` will use poll() rather than select() when possible to avoid failing due to the select() file descriptor limit. - Issue #15180: Clarify posixpath.join() error message when mixing str & bytes. @@ -455,7 +453,7 @@ Library - Issue #15233: Python now guarantees that callables registered with the atexit module will be called in a deterministic order. -- Issue #15238: shutil.copystat now copies Linux "extended attributes". +- Issue #15238: `shutil.copystat()` now copies Linux "extended attributes". - Issue #15230: runpy.run_path now correctly sets __package__ as described in the documentation. @@ -465,42 +463,42 @@ Library - Issue #15294: Fix a regression in pkgutil.extend_path()'s handling of nested namespace packages. -- Issue #15056: imp.cache_from_source() and source_from_cache() raise - NotImplementedError when sys.implementation.cache_tag is set to None. +- Issue #15056: `imp.cache_from_source()` and `imp.source_from_cache()` raise + NotImplementedError when `sys.implementation.cache_tag` is set to None. -- Issue #15256: Grammatical mistake in exception raised by imp.find_module(). +- Issue #15256: Grammatical mistake in exception raised by `imp.find_module()`. -- Issue #5931: wsgiref environ variable SERVER_SOFTWARE will specify an +- Issue #5931: `wsgiref` environ variable SERVER_SOFTWARE will specify an implementation specific term like CPython, Jython instead of generic "Python". - Issue #13248: Remove obsolete argument "max_buffer_size" of BufferedWriter and BufferedRWPair, from the io module. -- Issue #13248: Remove obsolete argument "version" of argparse.ArgumentParser. +- Issue #13248: Remove obsolete argument "version" of `argparse.ArgumentParser`. - Issue #14814: Implement more consistent ordering and sorting behaviour for ipaddress objects. -- Issue #14814: ipaddress network objects correctly return NotImplemented when +- Issue #14814: `ipaddress` network objects correctly return NotImplemented when compared to arbitrary objects instead of raising TypeError. - Issue #14990: Correctly fail with SyntaxError on invalid encoding declaration. -- Issue #14814: ipaddress now provides more informative error messages when +- Issue #14814: `ipaddress` now provides more informative error messages when constructing instances directly (changes permitted during beta due to provisional API status). -- Issue #15247: FileIO now raises an error when given a file descriptor pointing - to a directory. +- Issue #15247: `io.FileIO` now raises an error when given a file descriptor + pointing to a directory. - Issue #15261: Stop os.stat(fd) crashing on Windows when fd not open. -- Issue #15166: Implement imp.get_tag() using sys.implementation.cache_tag. +- Issue #15166: Implement `imp.get_tag()` using `sys.implementation.cache_tag`. -- Issue #15210: Catch KeyError when importlib.__init__ can't find +- Issue #15210: Catch KeyError when `importlib.__init__()` can't find _frozen_importlib in sys.modules, not ImportError. -- Issue #15030: importlib.abc.PyPycLoader now supports the new source size +- Issue #15030: `importlib.abc.PyPycLoader` now supports the new source size header field in .pyc files. - Issue #5346: Preserve permissions of mbox, MMDF and Babyl mailbox files on @@ -513,7 +511,7 @@ Library renamed over the old file when flush() is called on an mbox, MMDF or Babyl mailbox. -- Issue 10924: Fixed crypt.mksalt() to use a RNG that is suitable for +- Issue #10924: Fixed `crypt.mksalt()` to use a RNG that is suitable for cryptographic purpose. - Issue #15184: Ensure consistent results of OS X configuration tailoring for @@ -524,10 +522,10 @@ Library C API ----- -- Issue #15610: PyImport_ImportModuleEx() now uses a 'level' of 0 instead of -1. +- Issue #15610: `PyImport_ImportModuleEx()` now uses a 'level' of 0 instead of -1. -- Issues #15169, #14599: Strip out the C implementation of - imp.source_from_cache() used by PyImport_ExecCodeModuleWithPathnames() and +- Issue #15169, issue #14599: Strip out the C implementation of + `imp.source_from_cache()` used by PyImport_ExecCodeModuleWithPathnames() and used the Python code instead. Leads to PyImport_ExecCodeModuleObject() to not try to infer the source path from the bytecode path as PyImport_ExecCodeModuleWithPathnames() does. @@ -535,14 +533,17 @@ C API Extension Modules ----------------- -- Issue #15676: Now "mmap" check for empty files before doing the - offset check. Patch by Steven Willis. - -- Issue #6493: An issue in ctypes on Windows that caused structure bitfields - of type ctypes.c_uint32 and width 32 to incorrectly be set has been fixed. +- Issue #6493: An issue in ctypes on Windows that caused structure bitfields of + type `ctypes.c_uint32` and width 32 to incorrectly be set has been fixed. - Issue #15194: Update libffi to the 3.0.11 release. +IDLE +---- + +- Issue #13052: Fix IDLE crashing when replace string in Search/Replace dialog + ended with ``\``. Patch by Roger Serwy. + Tools/Demos ----------- @@ -562,8 +563,10 @@ Tools/Demos Documentation ------------- -- Issue #15444: Use proper spelling for non-ASCII contributor names. Patch - by Serhiy Storchaka. +- Issue #15041: Update "see also" list in tkinter documentation. + +- Issue #15444: Use proper spelling for non-ASCII contributor names. Patch by + Serhiy Storchaka. - Issue #15295: Reorganize and rewrite the documentation on the import system. @@ -578,25 +581,29 @@ Documentation "changed" since they will no longer work with modules directly imported by import itself. -- Issue #13557: Clarify effect of giving two different namespaces to exec or - execfile(). +- Issue #13557: Clarify effect of giving two different namespaces to `exec()` or + `execfile()`. -- Issue #15250: Document that filecmp.dircmp compares files shallowly. Patch +- Issue #15250: Document that `filecmp.dircmp()` compares files shallowly. Patch contributed by Chris Jerdonek. +- Issue #15442: Expose the default list of directories ignored by + `filecmp.dircmp()` as a module attribute, and expand the list to more modern + values. + Tests ----- -- Issue #15467: Move helpers for __sizeof__ tests into test_support. Patch by - Serhiy Storchaka. +- Issue #15467: Move helpers for `__sizeof__()` tests into test_support. Patch + by Serhiy Storchaka. - Issue #15320: Make iterating the list of tests thread-safe when running tests in multiprocess mode. Patch by Chris Jerdonek. -- Issue #15168: Move importlib.test to test.test_importlib. +- Issue #15168: Move `importlib.test` to `test.test_importlib`. - Issue #15091: Reactivate a test on UNIX which was failing thanks to a - forgotten importlib.invalidate_caches() call. + forgotten `importlib.invalidate_caches()` call. - Issue #15230: Adopted a more systematic approach in the runpy tests. @@ -629,6 +636,8 @@ Build - Issue #14018: Fix OS X Tcl/Tk framework checking when using OS X SDKs. +- Issue #16256: OS X installer now sets correct permissions for doc directory. + - Issue #15431: Add _freeze_importlib project to regenerate importlib.h on Windows. Patch by Kristján Valur Jónsson. @@ -664,14 +673,9 @@ Core and Builtins - Issue #11626: Add _SizeT functions to stable ABI. -- Issue #15146: Add PyType_FromSpecWithBases. Patch by Robin Schreiber. - - Issue #15142: Fix reference leak when deallocating instances of types created using PyType_FromSpec(). -- Issue #15042: Add PyState_AddModule and PyState_RemoveModule. Add version - guard for Py_LIMITED_API additions. Patch by Robin Schreiber. - - Issue #10053: Don't close FDs when FileIO.__init__ fails. Loosely based on the work by Hirokazu Yamamoto. @@ -699,9 +703,6 @@ Core and Builtins Library ------- -- Issue #9803: Don't close IDLE on saving if breakpoint is open. - Patch by Roger Serwy. - - Issue #12288: Consider '0' and '0.0' as valid initialvalue for tkinter SimpleDialog. @@ -720,14 +721,8 @@ Library - Issue #15514: Correct __sizeof__ support for cpu_set. Patch by Serhiy Storchaka. -- Issue #15187: Bugfix: remove temporary directories test_shutil was leaving - behind. - - Issue #15177: Added dir_fd parameter to os.fwalk(). -- Issue #15176: Clarified behavior, documentation, and implementation - of os.listdir(). - - Issue #15061: Re-implemented hmac.compare_digest() in C to prevent further timing analysis and to support all buffer protocol aware objects as well as ASCII only str instances safely. @@ -811,7 +806,7 @@ Library - Issue #14772: Return destination values from some shutil functions. -- Issue #15064: Implement context manager protocol for multiprocessing types +- Issue #15064: Implement context management protocol for multiprocessing types - Issue #15101: Make pool finalizer avoid joining current thread. @@ -827,10 +822,6 @@ Library - Issue #15006: Allow equality comparison between naive and aware time or datetime objects. -- Issue #14982: Document that pkgutil's iteration functions require the - non-standard iter_modules() method to be defined by an importer (something - the importlib importers do not define). - - Issue #15036: Mailbox no longer throws an error if a flush is done between operations when removing or changing multiple items in mbox, MMDF, or Babyl mailboxes. @@ -898,9 +889,6 @@ Library - Issue #14969: Better handling of exception chaining in contextlib.ExitStack -- Issue #14962: Update text coloring in IDLE shell window after changing - options. Patch by Roger Serwy. - - Issue #14963: Convert contextlib.ExitStack.__exit__ to use an iterative algorithm (Patch by Alon Horev) @@ -913,6 +901,11 @@ Library C-API ----- +- Issue #15146: Add PyType_FromSpecWithBases. Patch by Robin Schreiber. + +- Issue #15042: Add PyState_AddModule and PyState_RemoveModule. Add version + guard for Py_LIMITED_API additions. Patch by Robin Schreiber. + - Issue #13783: Inadvertent additions to the public C API in the PEP 380 implementation have either been removed or marked as private interfaces. @@ -921,9 +914,25 @@ Extension Modules - Issue #15000: Support the "unique" x32 architecture in _posixsubprocess.c. +IDLE +---- + +- Issue #9803: Don't close IDLE on saving if breakpoint is open. + Patch by Roger Serwy. + +- Issue #14962: Update text coloring in IDLE shell window after changing + options. Patch by Roger Serwy. + Documentation ------------- +- Issue #15176: Clarified behavior, documentation, and implementation + of os.listdir(). + +- Issue #14982: Document that pkgutil's iteration functions require the + non-standard iter_modules() method to be defined by an importer (something + the importlib importers do not define). + - Issue #15081: Document PyState_FindModule. Patch by Robin Schreiber. @@ -932,6 +941,9 @@ Documentation Tests ----- +- Issue #15187: Bugfix: remove temporary directories test_shutil was leaving + behind. + - Issue #14769: test_capi now has SkipitemTest, which cleverly checks for "parity" between PyArg_ParseTuple() and the Python/getargs.c static function skipitem() for all possible "format units". @@ -1020,34 +1032,18 @@ Core and Builtins - Issue #14700: Fix two broken and undefined-behaviour-inducing overflow checks in old-style string formatting. -- Issue #14705: The PyArg_Parse() family of functions now support the 'p' format - unit, which accepts a "boolean predicate" argument. It converts any Python - value into an integer--0 if it is "false", and 1 otherwise. - Library ------- - Issue #14690: Use monotonic clock instead of system clock in the sched, subprocess and trace modules. -- Issue #14958: Change IDLE systax highlighting to recognize all string and - byte literals supported in Python 3.3. - -- Issue #10997: Prevent a duplicate entry in IDLE's "Recent Files" menu. - - Issue #14443: Tell rpmbuild to use the correct version of Python in bdist_rpm. Initial patch by Ross Lagerwall. -- Issue #14929: Stop Idle 3.x from closing on Unicode decode errors when - grepping. Patch by Roger Serwy. - - Issue #12515: email now registers a defect if it gets to EOF while parsing a MIME part without seeing the closing MIME boundary. -- Issue #12510: Attempting to get invalid tooltip no longer closes Idle. - Other tooltipss have been corrected or improved and the number of tests - has been tripled. Original patch by Roger Serwy. - - Issue #1672568: email now always decodes base64 payloads, adding padding and ignoring non-base64-alphabet characters if needed, and registering defects for any such problems. @@ -1081,9 +1077,6 @@ Library - Issue #14548: Make multiprocessing finalizers check pid before running to cope with possibility of gc running just after fork. -- Issue #14863: Update the documentation of os.fdopen() to reflect the - fact that it's only a thin wrapper around open() anymore. - - Issue #14036: Add an additional check to validate that port in urlparse does not go in illegal range and returns None. @@ -1210,6 +1203,21 @@ Library - Issue #14127 and #10148: shutil.copystat now preserves exact mtime and atime on filesystems providing nanosecond resolution. +IDLE +---- + +- Issue #14958: Change IDLE systax highlighting to recognize all string and + byte literals supported in Python 3.3. + +- Issue #10997: Prevent a duplicate entry in IDLE's "Recent Files" menu. + +- Issue #14929: Stop IDLE 3.x from closing on Unicode decode errors when + grepping. Patch by Roger Serwy. + +- Issue #12510: Attempting to get invalid tooltip no longer closes IDLE. + Other tooltipss have been corrected or improved and the number of tests + has been tripled. Original patch by Roger Serwy. + Tools/Demos ----------- @@ -1228,9 +1236,19 @@ Build - Issue #13210: Windows build now uses VS2010, ported from VS2008. +C-API +----- + +- Issue #14705: The PyArg_Parse() family of functions now support the 'p' format + unit, which accepts a "boolean predicate" argument. It converts any Python + value into an integer--0 if it is "false", and 1 otherwise. + Documentation ------------- +- Issue #14863: Update the documentation of os.fdopen() to reflect the + fact that it's only a thin wrapper around open() anymore. + - Issue #14588: The language reference now accurately documents the Python 3 class definition process. Patch by Nick Coghlan. @@ -1279,9 +1297,6 @@ Core and Builtins - Issue #14339: Speed improvements to bin, oct and hex functions. Patch by Serhiy Storchaka. -- Issue #14098: New functions PyErr_GetExcInfo and PyErr_SetExcInfo. - Patch by Stefan Behnel. - - Issue #14385: It is now possible to use a custom type for the __builtins__ namespace, instead of a dict. It can be used for sandboxing for example. Raise also a NameError instead of ImportError if __build_class__ name if not @@ -1431,12 +1446,6 @@ Library - Don't Py_DECREF NULL variable in io.IncrementalNewlineDecoder. -- Issue #8515: Set __file__ when run file in IDLE. - Initial patch by Bruce Frederiksen. - -- Issue #14496: Fix wrong name in idlelib/tabbedpages.py. - Patch by Popa Claudiu. - - Issue #3033: Add displayof parameter to tkinter font. Patch by Guilherme Polo. - Issue #14482: Raise a ValueError, not a NameError, when trying to create @@ -1472,6 +1481,15 @@ Tests - Issue #14355: Regrtest now supports the standard unittest test loading, and will use it if a test file contains no `test_main` method. +IDLE +---- + +- Issue #8515: Set __file__ when run file in IDLE. + Initial patch by Bruce Frederiksen. + +- Issue #14496: Fix wrong name in idlelib/tabbedpages.py. + Patch by Popa Claudiu. + Tools / Demos ------------- @@ -1481,6 +1499,12 @@ Tools / Demos - Issue #13165: stringbench is now available in the Tools/stringbench folder. It used to live in its own SVN project. +C-API +----- + +- Issue #14098: New functions PyErr_GetExcInfo and PyErr_SetExcInfo. + Patch by Stefan Behnel. + What's New in Python 3.3.0 Alpha 2? =================================== @@ -1532,16 +1556,9 @@ Library - Issue #5136: deprecate old, unused functions from tkinter. -- Issue #14409: IDLE now properly executes commands in the Shell window - when it cannot read the normal config files on startup and - has to use the built-in default key bindings. - There was previously a bug in one of the defaults. - - Issue #14416: syslog now defines the LOG_ODELAY and LOG_AUTHPRIV constants if they are defined in . -- IDLE can be launched as python -m idlelib - - Issue #14295: Add unittest.mock - Issue #7652: Add --with-system-libmpdec option to configure for linking @@ -1567,9 +1584,6 @@ Library up the decimal module. Performance gains of the new C implementation are between 10x and 100x, depending on the application. -- Issue #3573: IDLE hangs when passing invalid command line args - (directory(ies) instead of file(s)) (Patch by Guilherme Polo) - - Issue #14269: SMTPD now conforms to the RFC and requires a HELO command before MAIL, RCPT, or DATA. @@ -1601,8 +1615,6 @@ Library denial of service due to hash collisions. Patch by David Malcolm with some modifications by the expat project. -- Issue #14200: Idle shell crash on printing non-BMP unicode character. - - Issue #12818: format address no longer needlessly \ escapes ()s in names when the name ends up being quoted. @@ -1618,8 +1630,6 @@ Library - Issue #989712: Support using Tk without a mainloop. -- Issue #5219: Prevent event handler cascade in IDLE. - - Issue #3835: Refuse to use unthreaded Tcl in threaded Python. - Issue #2843: Add new Tk API to Tkinter. @@ -1848,10 +1858,6 @@ Core and Builtins on POSIX systems supporting anonymous memory mappings. Patch by Charles-François Natali. -- Issue #13452: PyUnicode_EncodeDecimal() doesn't support error handlers - different than "strict" anymore. The caller was unable to compute the - size of the output buffer: it depends on the error handler. - - PEP 3155 / issue #13448: Qualified name for classes and functions. - Issue #13436: Fix a bogus error message when an AST object was passed @@ -1942,10 +1948,6 @@ Core and Builtins - PEP 3151 / issue #12555: reworking the OS and IO exception hierarchy. -- Issue #13560: Add PyUnicode_DecodeLocale(), PyUnicode_DecodeLocaleAndSize() - and PyUnicode_EncodeLocale() functions to the C API to decode/encode from/to - the current locale encoding. - - Add internal API for static strings (_Py_identifier et al.). - Issue #13063: the Windows error ERROR_NO_DATA (numbered 232 and described @@ -2028,7 +2030,7 @@ Core and Builtins deallocator calls one of the methods on the type (e.g. when subclassing IOBase). Diagnosis and patch by Davide Rizzo. -- Issue #9611, #9015: FileIO.read() clamps the length to INT_MAX on Windows. +- Issue #9611, Issue #9015: FileIO.read() clamps the length to INT_MAX on Windows. - Issue #9642: Uniformize the tests on the availability of the mbcs codec, add a new HAVE_MBCS define. @@ -2191,17 +2193,11 @@ Core and Builtins PyUnicode_AsUTF8String() and PyUnicode_AsEncodedString(unicode, "utf-8", NULL). -- Issue #10831: PyUnicode_FromFormat() supports %li, %lli and %zi formats. - - Issue #10829: Refactor PyUnicode_FromFormat(), use the same function to parse the format string in the 3 steps, fix crashs on invalid format strings. - Issue #13007: whichdb should recognize gdbm 1.9 magic numbers. -- Issue #11246: Fix PyUnicode_FromFormat("%V") to decode the byte string from - UTF-8 (with replace error handler) instead of ISO-8859-1 (in strict mode). - Patch written by Ray Allen. - - Issue #11286: Raise a ValueError from calling PyMemoryView_FromBuffer with a buffer struct having a NULL data pointer. @@ -2211,9 +2207,6 @@ Core and Builtins - Issue #11828: startswith and endswith now accept None as slice index. Patch by Torsten Becker. -- Issue #10830: Fix PyUnicode_FromFormatV("%c") for non-BMP characters on - narrow build. - - Issue #11168: Remove filename debug variable from PyEval_EvalFrameEx(). It encoded the Unicode filename to UTF-8, but the encoding fails on undecodable filename (on surrogate characters) which raises an unexpected @@ -2255,15 +2248,9 @@ Library are dead or dying. Moreover, the implementation is now O(1) rather than O(n). -- Issue #13125: Silence spurious test_lib2to3 output when in non-verbose mode. - Patch by Mikhail Novikov. - - Issue #11841: Fix comparison bug with 'rc' versions in packaging.version. Patch by Filip GruszczyÅ„ski. -- Issue #13447: Add a test file to host regression tests for bugs in the - scripts found in the Tools directory. - - Issue #6884: Fix long-standing bugs with MANIFEST.in parsing in distutils on Windows. Also fixed in packaging. @@ -2319,9 +2306,6 @@ Library authenticating (since the result may change, according to RFC 4643). Patch by Hynek Schlawack. -- Issue #13989: Document that GzipFile does not support text mode, and give a - more helpful error message when opened with an invalid mode string. - - Issue #13590: On OS X 10.7 and 10.6 with Xcode 4.2, building Distutils-based packages with C extension modules may fail because Apple has removed gcc-4.2, the version used to build python.org @@ -2338,10 +2322,6 @@ Library - Issue #13960: HTMLParser is now able to handle broken comments when strict=False. -- Issue #13921: Undocument and clean up sqlite3.OptimizedUnicode, - which is obsolete in Python 3.x. It's now aliased to str for - backwards compatibility. - - When '' is a path (e.g. in sys.path), make sure __file__ uses the current working directory instead of '' in importlib. @@ -2363,11 +2343,6 @@ Library - Issue #10811: Fix recursive usage of cursors. Instead of crashing, raise a ProgrammingError now. -- Issue #10881: Fix test_site failure with OS X framework builds. - -- Issue #964437: Make IDLE help window non-modal. - Patch by Guilherme Polo and Roger Serwy. - - Issue #13734: Add os.fwalk(), a directory walking function yielding file descriptors. @@ -2377,16 +2352,8 @@ Library - Issue #11805: package_data in setup.cfg should allow more than one value. -- Issue #13933: IDLE auto-complete did not work with some imported - module, like hashlib. (Patch by Roger Serwy) - -- Issue #13901: Prevent test_distutils failures on OS X with --enable-shared. - - Issue #13676: Handle strings with embedded zeros correctly in sqlite3. -- Issue #13506: Add '' to path for IDLE Shell when started and restarted with Restart Shell. - Original patches by Marco Scataglini and Roger Serwy. - - Issue #8828: Add new function os.replace(), for cross-platform renaming with overwriting. @@ -2407,12 +2374,6 @@ Library OSError if localtime() failed. time.clock() now raises a RuntimeError if the processor time used is not available or its value cannot be represented -- Issue #13862: Fix spurious failure in test_zlib due to runtime/compile time - minor versions not matching. - -- Issue #12804: Fix test_socket and test_urllib2net failures when running tests - on a system without internet access. - - Issue #13772: In os.symlink() under Windows, do not try to guess the link target's type (file or directory). The detection was buggy and made the call non-atomic (therefore prone to race conditions). @@ -2439,9 +2400,6 @@ Library - Issue #13642: Unquote before b64encoding user:password during Basic Authentication. Patch contributed by Joonas Kuorilehto. -- Issue #13726: Fix the ambiguous -S flag in regrtest. It is -o/--slow for slow - tests. - - Issue #12364: Fix a hang in concurrent.futures.ProcessPoolExecutor. The hang would occur when retrieving the result of a scheduled future after the executor had been shut down. @@ -2524,10 +2482,6 @@ Library - Issue #13591: A bug in importlib has been fixed that caused import_module to load a module twice. -- Issue #4625: If IDLE cannot write to its recent file or breakpoint files, - display a message popup and continue rather than crash. Original patch by - Roger Serwy. - - Issue #13449 sched.scheduler.run() method has a new "blocking" parameter which when set to False makes run() execute the scheduled events due to expire soonest (if any) and then return. Patch by Giampaolo Rodolà. @@ -2544,12 +2498,9 @@ Library 'importlib.abc.PyPycLoader', 'nntplib.NNTP.xgtitle', 'nntplib.NNTP.xpath', and private attributes of 'smtpd.SMTPChannel'. -- Issue #5905, #13560: time.strftime() is now using the current locale +- Issue #5905, Issue #13560: time.strftime() is now using the current locale encoding, instead of UTF-8, if the wcsftime() function is not available. -- Issue #8641: Update IDLE 3 syntax coloring to recognize b".." and not u"..". - Patch by Tal Einat. - - Issue #13464: Add a readinto() method to http.client.HTTPResponse. Patch by Jon Kuhn. @@ -2661,9 +2612,6 @@ Library - Issue #10817: Fix urlretrieve function to raise ContentTooShortError even when reporthook is None. Patch by Jyrki Pulliainen. -- Issue #13296: Fix IDLE to clear compile __future__ flags on shell restart. - (Patch by Roger Serwy) - - Fix the xmlrpc.client user agent to return something similar to urllib.request user agent: "Python-xmlrpc/3.3". @@ -2766,10 +2714,6 @@ Library - Issue #13034: When decoding some SSL certificates, the subjectAltName extension could be unreported. -- Issue #9871: Prevent IDLE 3 crash when given byte stings - with invalid hex escape sequences, like b'\x0'. - (Original patch by Claudiu Popa.) - - Issue #12306: Expose the runtime version of the zlib C library as a constant, ZLIB_RUNTIME_VERSION, in the zlib module. Patch by Torsten Landschoff. @@ -2798,8 +2742,6 @@ Library - Issue #12878: Expose a __dict__ attribute on io.IOBase and its subclasses. -- Issue #12636: IDLE reads the coding cookie when executing a Python script. - - Issue #12494: On error, call(), check_call(), check_output() and getstatusoutput() functions of the subprocess module now kill the process, read its status (to avoid zombis) and close pipes. @@ -2869,9 +2811,6 @@ Library - Issue #10087: Fix the html output format of the calendar module. -- Issue #12540: Prevent zombie IDLE processes on Windows due to changes - in os.kill(). - - Issue #13121: add support for inplace math operators to collections.Counter. - Add support for unary plus and unary minus to collections.Counter. @@ -2903,7 +2842,7 @@ Library Condition, etc.) used to be factory functions returning instances of hidden classes (_Event, _Condition, etc.), because (if Guido recalls correctly) this code pre-dates the ability to subclass extension types. It is now possible - to inherit from these classes without having to import the private + to inherit from these classes, without having to import the private underscored names like multiprocessing did. - Issue #9723: Add shlex.quote functions, to escape filenames and command @@ -2917,14 +2856,8 @@ Library - Issue #12607: In subprocess, fix issue where if stdin, stdout or stderr is given as a low fd, it gets overwritten. -- Issue #12590: IDLE editor window now always displays the first line - when opening a long file. With Tk 8.5, the first line was hidden. - - Issue #12576: Fix urlopen behavior on sites which do not send (or obfuscates) - Connection:close header. - -- Issue #12102: Document that buffered files must be flushed before being used - with mmap. Patch by Steffen Daode Nurpmeso. + ``Connection: close`` header. - Issue #12560: Build libpython.so on OpenBSD. Patch by Stefan Sperling. @@ -3179,7 +3112,7 @@ Library - Issue #12175: FileIO.readall() now raises a ValueError instead of an IOError if the file is closed. -- Issue #11109: New service_action method for BaseServer, used by ForkingMixIn +- Issue #11109: New service_action method for BaseServer, used by ForkingMixin class for cleanup. Initial Patch by Justin Warkentin. - Issue #12045: Avoid duplicate execution of command in @@ -3224,9 +3157,6 @@ Library passing a ``context`` argument pointing to an ssl.SSLContext instance. Patch by Kasun Herath. -- Issue #11088: don't crash when using F5 to run a script in IDLE on MacOSX - with Tk 8.5. - - Issue #9516: Issue #9516: avoid errors in sysconfig when MACOSX_DEPLOYMENT_TARGET is set in shell. @@ -3246,10 +3176,6 @@ Library - Issue #9971: Write an optimized implementation of BufferedReader.readinto(). Patch by John O'Connor. -- Issue #1028: Tk returns invalid Unicode null in %A: UnicodeDecodeError. - With Tk < 8.5 _tkinter.c:PythonCmd() raised UnicodeDecodeError, caused - IDLE to exit. Converted to valid Unicode null in PythonCmd(). - - Issue #11799: urllib.request Authentication Handlers will raise a ValueError when presented with an unsupported Authentication Scheme. Patch contributed by Yuval Greenfield. @@ -3486,12 +3412,12 @@ Library - Issue #7639: Fix short file name generation in bdist_msi -- Issue #11659: Fix ResourceWarning in test_subprocess introduced by #11459. - Patch by Ben Hayden. - - Issue #11635: Don't use polling in worker threads and processes launched by concurrent.futures. +- Issue #5845: Automatically read readline configuration to enable completion + in interactive mode. + - Issue #6811: Allow importlib to change a code object's co_filename attribute to match the path to where the source code currently is, not where the code object originally came from. @@ -3526,7 +3452,7 @@ Library - Issue #11127: Raise a TypeError when trying to pickle a socket object. -- Issue #11563: Connection:close header is sent by requests using URLOpener +- Issue #11563: ``Connection: close`` header is sent by requests using URLOpener class which helps in closing of sockets after connection is over. Patch contributions by Jeff McNeil and Nadeem Vawda. @@ -3541,8 +3467,6 @@ Library - Issue #10979: unittest stdout buffering now works with class and module setup and teardown. -- Issue #11577: fix ResourceWarning triggered by improved binhex test coverage - - Issue #11243: fix the parameter querying methods of Message to work if the headers contain un-encoded non-ASCII data. @@ -3575,9 +3499,6 @@ Library - Issue #11554: Fixed support for Japanese codecs; previously the body output encoding was not done if euc-jp or shift-jis was specified as the charset. -- Issue #11509: Significantly increase test coverage of fileinput. - Patch by Denver Coneybeare at PyCon 2011 Sprints. - - Issue #11407: `TestCase.run` returns the result object used or created. Contributed by Janathan Hartley. @@ -3606,7 +3527,7 @@ Library ``mmap.PROT_READ|mmap.PROT_EXEC`` would segfault instead of raising a TypeError. Patch by Charles-François Natali. -- Issue #9795: add context manager protocol support for nntplib.NNTP class. +- Issue #9795: add context management protocol support for nntplib.NNTP class. - Issue #11306: mailbox in certain cases adapts to an inability to open certain files in read-write mode. Previously it detected this by @@ -3700,11 +3621,6 @@ Library - Issue #9348: Raise an early error if argparse nargs and metavar don't match. -- Issue #8982: Improve the documentation for the argparse Namespace object. - -- Issue #9343: Document that argparse parent parsers must be configured before - their children. - - Issue #9026: Fix order of argparse sub-commands in help messages. - Issue #9347: Fix formatting for tuples in argparse type= error messages. @@ -3757,10 +3673,61 @@ Build - Issue #11495: OSF support is eliminated. It was deprecated in Python 3.2. - IDLE ---- +- Issue #14409: IDLE now properly executes commands in the Shell window + when it cannot read the normal config files on startup and + has to use the built-in default key bindings. + There was previously a bug in one of the defaults. + +- IDLE can be launched as python -m idlelib + +- Issue #3573: IDLE hangs when passing invalid command line args + (directory(ies) instead of file(s)) (Patch by Guilherme Polo) + +- Issue #14200: IDLE shell crash on printing non-BMP unicode character. + +- Issue #5219: Prevent event handler cascade in IDLE. + +- Issue #964437: Make IDLE help window non-modal. + Patch by Guilherme Polo and Roger Serwy. + +- Issue #13933: IDLE auto-complete did not work with some imported + module, like hashlib. (Patch by Roger Serwy) + +- Issue #13506: Add '' to path for IDLE Shell when started and restarted with Restart Shell. + Original patches by Marco Scataglini and Roger Serwy. + +- Issue #4625: If IDLE cannot write to its recent file or breakpoint files, + display a message popup and continue rather than crash. Original patch by + Roger Serwy. + +- Issue #8641: Update IDLE 3 syntax coloring to recognize b".." and not u"..". + Patch by Tal Einat. + +- Issue #13296: Fix IDLE to clear compile __future__ flags on shell restart. + (Patch by Roger Serwy) + +- Issue #9871: Prevent IDLE 3 crash when given byte stings + with invalid hex escape sequences, like b'\x0'. + (Original patch by Claudiu Popa.) + +- Issue #12636: IDLE reads the coding cookie when executing a Python script. + +- Issue #12540: Prevent zombie IDLE processes on Windows due to changes + in os.kill(). + +- Issue #12590: IDLE editor window now always displays the first line + when opening a long file. With Tk 8.5, the first line was hidden. + +- Issue #11088: don't crash when using F5 to run a script in IDLE on MacOSX + with Tk 8.5. + +- Issue #1028: Tk returns invalid Unicode null in %A: UnicodeDecodeError. + With Tk < 8.5 _tkinter.c:PythonCmd() raised UnicodeDecodeError, caused + IDLE to exit. Converted to valid Unicode null in PythonCmd(). + - Issue #11718: IDLE's open module dialog couldn't find the __init__.py file in a package. @@ -3790,6 +3757,10 @@ Tools/Demos Extension Modules ----------------- +- Issue #16847: Fixed improper use of _PyUnicode_CheckConsistency() in + non-pydebug builds. Several extension modules now compile cleanly when + assert()s are enabled in standard builds (-DDEBUG flag). + - Issue #13840: The error message produced by ctypes.create_string_buffer when given a Unicode string has been fixed. @@ -3852,6 +3823,33 @@ Extension Modules Tests ----- +- Issue #13125: Silence spurious test_lib2to3 output when in non-verbose mode. + Patch by Mikhail Novikov. + +- Issue #13447: Add a test file to host regression tests for bugs in the + scripts found in the Tools directory. + +- Issue #10881: Fix test_site failure with OS X framework builds. + +- Issue #13901: Prevent test_distutils failures on OS X with --enable-shared. + +- Issue #13862: Fix spurious failure in test_zlib due to runtime/compile time + minor versions not matching. + +- Issue #12804: Fix test_socket and test_urllib2net failures when running tests + on a system without internet access. + +- Issue #13726: Fix the ambiguous -S flag in regrtest. It is -o/--slow for slow + tests. + +- Issue #11659: Fix ResourceWarning in test_subprocess introduced by #11459. + Patch by Ben Hayden. + +- Issue #11577: fix ResourceWarning triggered by improved binhex test coverage + +- Issue #11509: Significantly increase test coverage of fileinput. + Patch by Denver Coneybeare at PyCon 2011 Sprints. + - Issue #11689: Fix a variable scoping error in an sqlite3 test - Issue #13786: Remove unimplemented 'trace' long option from regrtest.py. @@ -3972,7 +3970,7 @@ Tests - Issue #12041: Make test_wait3 more robust. - Issue #11873: Change regex in test_compileall to fix occasional failures when - when the randomly generated temporary path happened to match the regex. + the randomly generated temporary path happened to match the regex. - Issue #11958: Fix FTP tests for IPv6, bind to "::1" instead of "localhost". Patch written by Charles-Francois Natali. @@ -4030,7 +4028,7 @@ Tests - Issue #11505: improves test coverage of string.py. Patch by Alicia Arlen -- Issue #11490: test_subprocess:test_leaking_fds_on_error no longer gives a +- Issue #11490: test_subprocess.test_leaking_fds_on_error no longer gives a false positive if the last directory in the path is inaccessible. - Issue #11223: Fix test_threadsignals to fail, not hang, when the @@ -4054,6 +4052,23 @@ Tests C-API ----- +- Issue #13452: PyUnicode_EncodeDecimal() doesn't support error handlers + different than "strict" anymore. The caller was unable to compute the + size of the output buffer: it depends on the error handler. + +- Issue #13560: Add PyUnicode_DecodeLocale(), PyUnicode_DecodeLocaleAndSize() + and PyUnicode_EncodeLocale() functions to the C API to decode/encode from/to + the current locale encoding. + +- Issue #10831: PyUnicode_FromFormat() supports %li, %lli and %zi formats. + +- Issue #11246: Fix PyUnicode_FromFormat("%V") to decode the byte string from + UTF-8 (with replace error handler) instead of ISO-8859-1 (in strict mode). + Patch written by Ray Allen. + +- Issue #10830: Fix PyUnicode_FromFormatV("%c") for non-BMP characters on + narrow build. + - Add PyObject_GenericGetDict and PyObject_GeneriSetDict. They are generic implementations for the getter and setter of a ``__dict__`` descriptor of C types. @@ -4079,6 +4094,24 @@ C-API Documentation ------------- +- Issue #13989: Document that GzipFile does not support text mode, and give a + more helpful error message when opened with an invalid mode string. + +- Issue #13921: Undocument and clean up sqlite3.OptimizedUnicode, + which is obsolete in Python 3.x. It's now aliased to str for + backwards compatibility. + +- Issue #12102: Document that buffered files must be flushed before being used + with mmap. Patch by Steffen Daode Nurpmeso. + +- Issue #8982: Improve the documentation for the argparse Namespace object. + +- Issue #9343: Document that argparse parent parsers must be configured before + their children. + +- Issue #13498: Clarify docs of os.makedirs()'s exist_ok argument. Done with + great native-speaker help from R. David Murray. + - Issues #13491 and #13995: Fix many errors in sqlite3 documentation. Initial patch for #13491 by Johannes Vogel. @@ -4804,7 +4837,7 @@ Library - Issue #1486713: HTMLParser now has an optional tolerant mode where it tries to guess at the correct parsing of invalid html. -- Issue #10554: Add context manager support to subprocess.Popen objects. +- Issue #10554: Add context management protocol support to subprocess.Popen objects. - Issue #8989: email.utils.make_msgid now has a domain parameter that can override the domain name used in the generated msgid. @@ -5166,7 +5199,7 @@ Library - Issue #10253: FileIO leaks a file descriptor when trying to open a file for append that isn't seekable. Patch by Brian Brazil. -- Support context manager protocol for file-like objects returned by mailbox +- Support context management protocol for file-like objects returned by mailbox ``get_file()`` methods. - Issue #10246: uu.encode didn't close file objects explicitly when filenames @@ -5300,7 +5333,7 @@ Extension Modules - Issue #10143: Update "os.pathconf" values. -- Issue #6518: Support context manager protcol for ossaudiodev types. +- Issue #6518: Support context management protocol for ossaudiodev types. - Issue #678250: Make mmap flush a noop on ACCESS_READ and ACCESS_COPY. @@ -5909,7 +5942,7 @@ Extension Modules - Issue #8105: Validate file descriptor passed to mmap.mmap on Windows. -- Issue #8046: Add context manager protocol support and .closed property to mmap +- Issue #8046: Add context management protocol support and .closed property to mmap objects. Library @@ -6916,7 +6949,7 @@ Library - The audioop module now supports sound fragments of length greater than 2**31 bytes on 64-bit machines, and is PY_SSIZE_T_CLEAN. -- Issue #4972: Add support for the context manager protocol to the ftplib.FTP +- Issue #4972: Add support for the context management protocol to the ftplib.FTP class. - Issue #8664: In py_compile, create __pycache__ when the compiled path is @@ -7204,7 +7237,7 @@ Library - Issue #7494: fix a crash in _lsprof (cProfile) after clearing the profiler, reset also the pointer to the current pointer context. -- Issue #7232: Add support for the context manager protocol to the TarFile +- Issue #7232: Add support for the context management protocol to the TarFile class. - Issue #7250: Fix info leak of os.environ across multi-run uses of @@ -9242,7 +9275,7 @@ Library - Issue #1696199: Add collections.Counter() for rapid and convenient counting. -- Issue #3860: GzipFile and BZ2File now support the context manager protocol. +- Issue #3860: GzipFile and BZ2File now support the context management protocol. - Issue #4867: Fixed a crash in ctypes when passing a string to a function without defining argtypes. @@ -9652,7 +9685,7 @@ Core and Builtins - Issue #1210: Fixed imaplib and its documentation. -- Issue #4233: Changed semantic of ``_fileio.FileIO``'s ``close()`` +- Issue #4233: Changed semantic of ``_fileio.FileIO``'s ``close()`` method on file objects with closefd=False. The file descriptor is still kept open but the file object behaves like a closed file. The ``FileIO`` object also got a new readonly attribute ``closefd``. @@ -9796,13 +9829,13 @@ Core and Builtins cyclic garbage collection. - Issue #3668: Fix a memory leak with the "s*" argument parser in - PyArg_ParseTuple and friends, which occurred when the argument for "s*" + PyArg_ParseTuple and friends, which occurred when the argument for "s*" was correctly parsed but parsing of subsequent arguments failed. - Issue #3611: An exception __context__ could be cleared in a complex pattern involving a __del__ method re-raising an exception. -- Issue #2534: speed up isinstance() and issubclass() by 50-70%, so as to +- Issue #2534: speed up isinstance() and issubclass() by 50-70%, so as to match Python 2.5 speed despite the __instancecheck__ / __subclasscheck__ mechanism. In the process, fix a bug where isinstance() and issubclass(), when given a tuple of classes as second argument, were looking up @@ -9880,7 +9913,7 @@ Library - The deprecation warnings for the camelCase threading API names were removed. -- Issue #3110: multiprocessing fails to compiel on solaris 10 due to missing +- Issue #3110: multiprocessing fails to compiel on solaris 10 due to missing SEM_VALUE_MAX. Extension Modules @@ -14018,7 +14051,7 @@ Core and builtins - When method objects have an attribute that can be satisfied either by the function object or by the method object, the function object's attribute usually wins. Christian Tismer pointed out that - that this is really a mistake, because this only happens for special + this is really a mistake, because this only happens for special methods (like __reduce__) where the method object's version is really more appropriate than the function's attribute. So from now on, all method attributes will have precedence over function @@ -21593,7 +21626,7 @@ New or improved ports - Improved BeOS support. -- Support dynamic loading of shared libraries on NetBSD platforms that +- Support dynamic loading of shared libraries on NetBSD platforms that use ELF (i.e., MIPS and Alpha systems). Configuration/build changes @@ -21810,7 +21843,7 @@ provide its own version of this function, while still sharing the higher-level classes in code.py. - turtle.py is a new module for simple turtle graphics. I'm still -working on it; let me know if you use this to teach Python to children +working on it; let me know if you use this to teach Python to children or other novices without prior programming experience. Obsoleted library modules @@ -21942,7 +21975,7 @@ control pseudo-device, per audio(7I). Changes to tools ---------------- -- New, improved version of Barry Warsaw's Misc/python-mode.el (editing +- New, improved version of Barry Warsaw's Misc/python-mode.el (editing support for Emacs). - tabnanny.py: added a -q ('quiet') option to tabnanny, which causes @@ -22217,7 +22250,7 @@ Windows Installer ----------------- - Install zlib.dll in the DLLs directory instead of in the win32 -system directory, to avoid conflicts with other applications that have +system directory, to avoid conflicts with other applications that have their own zlib.dll. Test Suite @@ -22297,7 +22330,7 @@ General so that a symlink to a symlink can work. - Added a hack so that when you type 'quit' or 'exit' at the -interpreter, you get a friendly explanation of how to press Ctrl-D (or +interpreter, you get a friendly explanation of how to press Ctrl-D (or Ctrl-Z) to exit. - New and improved Misc/python-mode.el (Python mode for Emacs). @@ -22470,13 +22503,13 @@ problem that randint() was accidentally defined as taking an inclusive range. Also, randint(a, b) is now redefined as randrange(a, b+1), adding extra range and type checking to its arguments! -- Add some semi-thread-safety to random.gauss() (it used to be able to +- Add some semi-thread-safety to random.gauss() (it used to be able to crash when invoked from separate threads; now the worst it can do is give a duplicate result occasionally). - Some restructuring and generalization done to cmd.py. -- Major upgrade to ConfigParser.py; converted to using 're', added new +- Major upgrade to ConfigParser.py; converted to using 're', added new exceptions, support underscore in section header and option name. No longer add 'name' option to every section; instead, add '__name__'. @@ -22673,7 +22706,7 @@ Windows Installer ----------------- - The registry key used is now "1.5" instead of "1.5.x" -- so future -versions of 1.5 and Mark Hammond's win32all installer don't need to be +versions of 1.5 and Mark Hammond's win32all installer don't need to be resynchronized. Windows Tools @@ -22740,7 +22773,7 @@ objects. dynamically add one or many entries to the table of built-in modules. - New macro Py_InitModule3(name, methods, doc) which calls -Py_InitModule4() with appropriate arguments. (The -4 variant requires +Py_InitModule4() with appropriate arguments. (The -4 variant requires you to pass an obscure version number constant which is always the same.) - New APIs PySys_WriteStdout() and PySys_WriteStderr() to write to @@ -22812,7 +22845,7 @@ less common scenario in practice. Syntax change ------------- -- The raise statement can now be used without arguments, to re-raise +- The raise statement can now be used without arguments, to re-raise a previously set exception. This should be used after catching an exception with an except clause only, either in the except clause or later in the same function. @@ -22871,7 +22904,7 @@ of a tab. The preferred module is tabnanny.py (by Tim Peters). Demo/tkinter/guido/paint.py -- Dave Mitchell Demo/sockets/unixserver.py -- Piet van Oostrum - + - Much better freeze support. The freeze script can now freeze hierarchical module names (with a corresponding change to import.c), @@ -23010,7 +23043,7 @@ certain locales). - New command supported by the ftplib module: rmd(); also fixed some minor bugs. -- The profile module now uses a different timer function by default -- +- The profile module now uses a different timer function by default -- time.clock() is generally better than os.times(). This makes it work better on Windows NT, too. @@ -23049,14 +23082,14 @@ module. Courtesy Barry Warsaw. - In the multifile module, support the optional second parameter to seek() when possible. -- Several fixes to the gopherlib module by Lars Marius Garshol. Also, +- Several fixes to the gopherlib module by Lars Marius Garshol. Also, urlparse now correctly handles Gopher URLs with query strings. - Fixed a tiny bug in format_exception() in the traceback module. Also rewrite tb_lineno() to be compatible with JPython (and not disturb the current exception!); by Jim Hugunin. -- The httplib module is more robust when servers send a short response +- The httplib module is more robust when servers send a short response -- courtesy Tim O'Malley. Tkinter and friends @@ -23071,7 +23104,7 @@ application only). no longer use the default root. - The interfaces for the bind*() and unbind() widget methods have been -redesigned; the bind*() methods now return the name of the Tcl command +redesigned; the bind*() methods now return the name of the Tcl command created for the callback, and this can be passed as a optional argument to unbind() in order to delete the command (normally, such commands are automatically unbound when the widget is destroyed, but @@ -23107,7 +23140,7 @@ intended for storing thread-local global variables. dictionary to allow recursive container types to detect recursion in their repr(), str() and print implementations. -- New function PyObject_Not(x) calculates (not x) according to Python's +- New function PyObject_Not(x) calculates (not x) according to Python's standard rules (basically, it negates the outcome PyObject_IsTrue(x). - New function _PyModule_Clear(), which clears a module's dictionary @@ -23268,7 +23301,7 @@ defined in packages correctly. The same change applies to copying instances with copy.py. The cPickle.c changes and some pickle.py changes are courtesy Jim Fulton. -- Locale support in he "re" (Perl regular expressions) module. Use +- Locale support in he "re" (Perl regular expressions) module. Use the flag re.L (or re.LOCALE) to enable locale-specific matching rules for \w and \b. The in-line syntax for this flag is (?L). @@ -23334,7 +23367,7 @@ don't know how to deal with those. - Some improvements to the _tkinter build line suggested by Case Roole. -- A full suite of platform specific files for NetBSD 1.x, submitted by +- A full suite of platform specific files for NetBSD 1.x, submitted by Anders Andersen. - New Solaris specific header STROPTS.py. @@ -23404,7 +23437,7 @@ after studying the GNU libg++ quicksort. This should be much faster if there are lots of duplicates, and otherwise at least as good. - Added "uue" as an alias for "uuencode" to mimetools.py. (Hm, the -uudecode bug where it complaints about trailing garbage is still there +uudecode bug where it complaints about trailing garbage is still there :-( ). - pickle.py requires integers in text mode to be in decimal notation @@ -24180,7 +24213,7 @@ the C and the Python variety) and for floating point numbers. The Python/C API for frames is changed (you shouldn't be using this anyway). -- Significant speedup by inlining some common opcodes for common operand +- Significant speedup by inlining some common opcodes for common operand types (e.g. i+i, i-i, and list[i]). Fredrik Lundh. - Small speedup by reordering the method tables of some common @@ -24206,34 +24239,34 @@ pressure to document their own contributed modules :-). Note that printing the documentation now kills fewer trees -- the margins have been reduced. -- I have started documenting the Python/C API. Unfortunately this project -hasn't been completed yet. It will be complete before the final release of -Python 1.5, though. At the moment, it's better to read the LaTeX source +- I have started documenting the Python/C API. Unfortunately this project +hasn't been completed yet. It will be complete before the final release of +Python 1.5, though. At the moment, it's better to read the LaTeX source than to attempt to run it through LaTeX and print the resulting dvi file. -- The posix module (and hence os.py) now has doc strings! Thanks to Neil -Schemenauer. I received a few other contributions of doc strings. In most +- The posix module (and hence os.py) now has doc strings! Thanks to Neil +Schemenauer. I received a few other contributions of doc strings. In most other places, doc strings are still wishful thinking... Language changes ---------------- -- Private variables with leading double underscore are now a permanent -feature of the language. (These were experimental in release 1.4. I have -favorable experience using them; I can't label them "experimental" +- Private variables with leading double underscore are now a permanent +feature of the language. (These were experimental in release 1.4. I have +favorable experience using them; I can't label them "experimental" forever.) -- There's new string literal syntax for "raw strings". Prefixing a string -literal with the letter r (or R) disables all escape processing in the -string; for example, r'\n' is a two-character string consisting of a -backslash followed by the letter n. This combines with all forms of string -quotes; it is actually useful for triple quoted doc strings which might -contain references to \n or \t. An embedded quote prefixed with a -backslash does not terminate the string, but the backslash is still -included in the string; for example, r'\'' is a two-character string -consisting of a backslash and a quote. (Raw strings are also -affectionately known as Robin strings, after their inventor, Robin +- There's new string literal syntax for "raw strings". Prefixing a string +literal with the letter r (or R) disables all escape processing in the +string; for example, r'\n' is a two-character string consisting of a +backslash followed by the letter n. This combines with all forms of string +quotes; it is actually useful for triple quoted doc strings which might +contain references to \n or \t. An embedded quote prefixed with a +backslash does not terminate the string, but the backslash is still +included in the string; for example, r'\'' is a two-character string +consisting of a backslash and a quote. (Raw strings are also +affectionately known as Robin strings, after their inventor, Robin Friedrich.) - There's a simple assert statement, and a new exception @@ -24262,10 +24295,10 @@ patches to catch floating point exceptions, at the moment). - The obsolete exception ConflictError (presumably used by the long obsolete access statement) has been deleted. -- There's a new function sys.exc_info() which returns the tuple +- There's a new function sys.exc_info() which returns the tuple (sys.exc_type, sys.exc_value, sys.exc_traceback) in a thread-safe way. -- There's a new variable sys.executable, pointing to the executable file +- There's a new variable sys.executable, pointing to the executable file for the Python interpreter. - The sort() methods for lists no longer uses the C library qsort(); I @@ -24291,11 +24324,11 @@ caught an exception are kept alive until another exception is caught returning from a function that caught an exception. - There's a new "buffer" interface. Certain objects (e.g. strings and -arrays) now support the "buffer" protocol. Buffer objects are acceptable -whenever formerly a string was required for a write operation; mutable +arrays) now support the "buffer" protocol. Buffer objects are acceptable +whenever formerly a string was required for a write operation; mutable buffer objects can be the target of a read operation using the call -f.readinto(buffer). A cool feature is that regular expression matching now -also work on array objects. Contribution by Jack Jansen. (Needs +f.readinto(buffer). A cool feature is that regular expression matching now +also work on array objects. Contribution by Jack Jansen. (Needs documentation.) - String interning: dictionary lookups are faster when the lookup @@ -24587,7 +24620,7 @@ Wirzenius, and RFC 850 dates (Chris Lawrence). of message sequence specifiers without invoking a subprocess. Also added a createmessage() method by Lars Wirzenius. -- The StringIO.StringIO class now supports readline(nbytes). (Lars +- The StringIO.StringIO class now supports readline(nbytes). (Lars Wirzenius.) (Of course, you should be using cStringIO for performance.) - UserDict.py supports the new dictionary methods as well. @@ -24635,8 +24668,8 @@ command line utilities. - Various small fixes to the nntplib.py module that I can't bother to document in detail. -- Sjoerd Mullender's mimify.py module now supports base64 encoding and -includes functions to handle the funny encoding you sometimes see in mail +- Sjoerd Mullender's mimify.py module now supports base64 encoding and +includes functions to handle the funny encoding you sometimes see in mail headers. It is now documented. - mailbox.py: Added BabylMailbox. Improved the way the mailbox is @@ -24987,23 +25020,23 @@ Windows (NT and 95) NT (the old VC++ 4.2 Makefile is also still supported, but will eventually be withdrawn due to its bulkiness). -- See the note on the new module search path in the "Miscellaneous" section +- See the note on the new module search path in the "Miscellaneous" section above. - Support for Win32s (the 32-bit Windows API under Windows 3.1) is basically withdrawn. If it still works for you, you're lucky. -- There's a new extension module, msvcrt.c, which provides various -low-level operations defined in the Microsoft Visual C++ Runtime Library. -These include locking(), setmode(), get_osfhandle(), set_osfhandle(), and +- There's a new extension module, msvcrt.c, which provides various +low-level operations defined in the Microsoft Visual C++ Runtime Library. +These include locking(), setmode(), get_osfhandle(), set_osfhandle(), and console I/O functions like kbhit(), getch() and putch(). - The -u option not only sets the standard I/O streams to unbuffered status, but also sets them in binary mode. (This can also be done using msvcrt.setmode(), by the way.) -- The, sys.prefix and sys.exec_prefix variables point to the directory -where Python is installed, or to the top of the source tree, if it was run +- The, sys.prefix and sys.exec_prefix variables point to the directory +where Python is installed, or to the top of the source tree, if it was run from there. - The various os.path modules (posixpath, ntpath, macpath) now support @@ -25011,7 +25044,7 @@ passing more than two arguments to the join() function, so os.path.join(a, b, c) is the same as os.path.join(a, os.path.join(b, c)). -- The ntpath module (normally used as os.path) supports ~ to $HOME +- The ntpath module (normally used as os.path) supports ~ to $HOME expansion in expanduser(). - The freeze tool now works on Windows. @@ -25309,47 +25342,47 @@ output directory. - New module whichdb recognizes dbm, gdbm and bsddb/dbhash files. -- The Doc/Makefile targets have been reorganized somewhat to remove the +- The Doc/Makefile targets have been reorganized somewhat to remove the insistence on always generating PostScript. - The texinfo to html filter (Doc/texi2html.py) has been improved somewhat. -- "errors.h" has been renamed to "pyerrors.h" to resolve a long-standing +- "errors.h" has been renamed to "pyerrors.h" to resolve a long-standing name conflict on the Mac. -- Linking a module compiled with a different setting for Py_TRACE_REFS now +- Linking a module compiled with a different setting for Py_TRACE_REFS now generates a linker error rather than a core dump. -- The cgi module has a new convenience function print_exception(), which -formats a python exception using HTML. It also fixes a bug in the -compatibility code and adds a dubious feature which makes it possible to +- The cgi module has a new convenience function print_exception(), which +formats a python exception using HTML. It also fixes a bug in the +compatibility code and adds a dubious feature which makes it possible to have two query strings, one in the URL and one in the POST data. -- A subtle change in the unpickling of class instances makes it possible -to unpickle in restricted execution mode, where the __dict__ attribute is +- A subtle change in the unpickling of class instances makes it possible +to unpickle in restricted execution mode, where the __dict__ attribute is not available (but setattr() is). -- Documentation for os.path.splitext() (== posixpath.splitext()) has been +- Documentation for os.path.splitext() (== posixpath.splitext()) has been cleared up. It splits at the *last* dot. - posixfile locking is now also correctly supported on AIX. -- The tempfile module once again honors an initial setting of tmpdir. It +- The tempfile module once again honors an initial setting of tmpdir. It now works on Windows, too. -- The traceback module has some new functions to extract, format and print +- The traceback module has some new functions to extract, format and print the active stack. -- Some translation functions in the urllib module have been made a little +- Some translation functions in the urllib module have been made a little less sluggish. -- The addtag_* methods for Canvas widgets in Tkinter as well as in the -separate Canvas class have been fixed so they actually do something +- The addtag_* methods for Canvas widgets in Tkinter as well as in the +separate Canvas class have been fixed so they actually do something meaningful. - A tiny _test() function has been added to Tkinter.py. -- A generic Makefile for dynamically loaded modules is provided in the Misc +- A generic Makefile for dynamically loaded modules is provided in the Misc subdirectory (Misc/gMakefile). - A new version of python-mode.el for Emacs is provided. See @@ -25357,25 +25390,25 @@ http://www.python.org/ftp/emacs/pmdetails.html for details. The separate file pyimenu.el is no longer needed, imenu support is folded into python-mode.el. -- The configure script can finally correctly find the readline library in a -non-standard location. The LDFLAGS variable is passed on the Makefiles +- The configure script can finally correctly find the readline library in a +non-standard location. The LDFLAGS variable is passed on the Makefiles from the configure script. -- Shared libraries are now installed as programs (i.e. with executable +- Shared libraries are now installed as programs (i.e. with executable permission). This is required on HP-UX and won't hurt on other systems. -- The objc.c module is no longer part of the distribution. Objective-C +- The objc.c module is no longer part of the distribution. Objective-C support may become available as contributed software on the ftp site. - The sybase module is no longer part of the distribution. A much improved sybase module is available as contributed software from the ftp site. -- _tkinter is now compatible with Tcl 7.5 / Tk 4.1 patch1 on Windows and -Mac (don't use unpatched Tcl/Tk!). The default line in the Setup.in file +- _tkinter is now compatible with Tcl 7.5 / Tk 4.1 patch1 on Windows and +Mac (don't use unpatched Tcl/Tk!). The default line in the Setup.in file now links with Tcl 7.5 / Tk 4.1 rather than 7.4/4.0. -- In Setup, you can now write "*shared*" instead of "*noconfig*", and you +- In Setup, you can now write "*shared*" instead of "*noconfig*", and you can use *.so and *.sl as shared libraries. - Some more fidgeting for AIX shared libraries. @@ -25384,81 +25417,81 @@ can use *.so and *.sl as shared libraries. (Note -- a complete replacement by Niels Mo"ller, called gpmodule, is available from the contrib directory on the ftp site.) -- A warning is written to sys.stderr when a __del__ method raises an +- A warning is written to sys.stderr when a __del__ method raises an exception (formerly, such exceptions were completely ignored). -- The configure script now defines HAVE_OLD_CPP if the C preprocessor is +- The configure script now defines HAVE_OLD_CPP if the C preprocessor is incapable of ANSI style token concatenation and stringification. -- All source files (except a few platform specific modules) are once again +- All source files (except a few platform specific modules) are once again compatible with K&R C compilers as well as ANSI compilers. In particular, -ANSI-isms have been removed or made conditional in complexobject.c, +ANSI-isms have been removed or made conditional in complexobject.c, getargs.c and operator.c. -- The abstract object API has three new functions, PyObject_DelItem, +- The abstract object API has three new functions, PyObject_DelItem, PySequence_DelItem, and PySequence_DelSlice. -- The operator module has new functions delitem and delslice, and the -functions "or" and "and" are renamed to "or_" and "and_" (since "or" and +- The operator module has new functions delitem and delslice, and the +functions "or" and "and" are renamed to "or_" and "and_" (since "or" and "and" are reserved words). ("__or__" and "__and__" are unchanged.) -- The environment module is no longer supported; putenv() is now a function +- The environment module is no longer supported; putenv() is now a function in posixmodule (also under NT). - Error in filter(, "") has been fixed. - Unrecognized keyword arguments raise TypeError, not KeyError. -- Better portability, fewer bugs and memory leaks, fewer compiler warnings, +- Better portability, fewer bugs and memory leaks, fewer compiler warnings, some more documentation. -- Bug in float power boundary case (0.0 to the negative integer power) +- Bug in float power boundary case (0.0 to the negative integer power) fixed. -- The test of negative number to the float power has been moved from the -built-in pow() functin to floatobject.c (so complex numbers can yield the +- The test of negative number to the float power has been moved from the +built-in pow() functin to floatobject.c (so complex numbers can yield the correct result). -- The bug introduced in beta2 where shared libraries loaded (using +- The bug introduced in beta2 where shared libraries loaded (using dlopen()) from the current directory would fail, has been fixed. -- Modules imported as shared libraries now also have a __file__ attribute, -giving the filename from which they were loaded. The only modules without +- Modules imported as shared libraries now also have a __file__ attribute, +giving the filename from which they were loaded. The only modules without a __file__ attribute now are built-in modules. -- On the Mac, dynamically loaded modules can end in either ".slb" or -"..slb" where is either "CFM68K" or "ppc". The ".slb" +- On the Mac, dynamically loaded modules can end in either ".slb" or +"..slb" where is either "CFM68K" or "ppc". The ".slb" extension should only be used for "fat" binaries. -- C API addition: marshal.c now supports +- C API addition: marshal.c now supports PyMarshal_WriteObjectToString(object). - C API addition: getargs.c now supports PyArg_ParseTupleAndKeywords(args, kwdict, format, kwnames, ...) to parse keyword arguments. -- The PC versioning scheme (sys.winver) has changed once again. the -version number is now "...", where the -first three s are the Python version (e.g. "1.4.0" for Python 1.4, -"1.4.1" for Python 1.4.1 -- the beta level is not included) and +- The PC versioning scheme (sys.winver) has changed once again. the +version number is now "...", where the +first three s are the Python version (e.g. "1.4.0" for Python 1.4, +"1.4.1" for Python 1.4.1 -- the beta level is not included) and is the four-digit PYTHON_API_VERSION (currently 1005). - h2py.py accepts whitespace before the # in CPP directives -- On Solaris 2.5, it should now be possible to use either Posix threads or -Solaris threads (XXX: how do you select which is used???). (Note: the -Python pthreads interface doesn't fully support semaphores yet -- anyone +- On Solaris 2.5, it should now be possible to use either Posix threads or +Solaris threads (XXX: how do you select which is used???). (Note: the +Python pthreads interface doesn't fully support semaphores yet -- anyone care to fix this?) -- Thread support should now work on AIX, using either DCE threads or +- Thread support should now work on AIX, using either DCE threads or pthreads. - New file Demo/sockets/unicast.py -- Working Mac port, with CFM68K support, with Tk 4.1 support (though not +- Working Mac port, with CFM68K support, with Tk 4.1 support (though not both) (XXX) -- New project setup for PC port, now compatible with PythonWin, with +- New project setup for PC port, now compatible with PythonWin, with _tkinter and NumPy support (XXX) - New module site.py (XXX) @@ -25475,7 +25508,7 @@ _tkinter and NumPy support (XXX) - string.atoi c.s. now raise an exception for an empty input string. -- At last, it is no longer necessary to define HAVE_CONFIG_H in order to +- At last, it is no longer necessary to define HAVE_CONFIG_H in order to have config.h included at various places. - Unrecognized keyword arguments now raise TypeError rather than KeyError. @@ -25483,25 +25516,25 @@ have config.h included at various places. - The makesetup script recognizes files with extension .so or .sl as (shared) libraries. -- 'access' is no longer a reserved word, and all code related to its -implementation is gone (or at least #ifdef'ed out). This should make +- 'access' is no longer a reserved word, and all code related to its +implementation is gone (or at least #ifdef'ed out). This should make Python a little speedier too! -- Performance enhancements suggested by Sjoerd Mullender. This includes -the introduction of two new optional function pointers in type object, -getattro and setattro, which are like getattr and setattr but take a +- Performance enhancements suggested by Sjoerd Mullender. This includes +the introduction of two new optional function pointers in type object, +getattro and setattro, which are like getattr and setattr but take a string object instead of a C string pointer. -- New operations in string module: lstrip(s) and rstrip(s) strip whitespace -only on the left or only on the right, A new optional third argument to -split() specifies the maximum number of separators honored (so -splitfields(s, sep, n) returns a list of at most n+1 elements). (Since +- New operations in string module: lstrip(s) and rstrip(s) strip whitespace +only on the left or only on the right, A new optional third argument to +split() specifies the maximum number of separators honored (so +splitfields(s, sep, n) returns a list of at most n+1 elements). (Since 1.3, splitfields(s, None) is totally equivalent to split(s).) -string.capwords() has an optional second argument specifying the +string.capwords() has an optional second argument specifying the separator (which is passed to split()). -- regsub.split() has the same addition as string.split(). regsub.splitx(s, -sep, maxsep) implements the functionality that was regsub.split(s, 1) in +- regsub.split() has the same addition as string.split(). regsub.splitx(s, +sep, maxsep) implements the functionality that was regsub.split(s, 1) in 1.4beta2 (return a list containing the delimiters as well as the words). - Final touch for AIX loading, rewritten Misc/AIX-NOTES. @@ -25545,11 +25578,11 @@ What's new in 1.4beta2 (since beta1)? meaningful value (a few things were botched in beta 1). Lib/dos_8x3 is now a standard part of the distribution (alas). -- More improvements to the installation procedure. Typing "make install" -now inserts the version number in the pathnames of almost everything -installed, and creates the machine dependent modules (FCNTL.py etc.) if not -supplied by the distribution. (XXX There's still a problem with the latter -because the "regen" script requires that Python is installed. Some manual +- More improvements to the installation procedure. Typing "make install" +now inserts the version number in the pathnames of almost everything +installed, and creates the machine dependent modules (FCNTL.py etc.) if not +supplied by the distribution. (XXX There's still a problem with the latter +because the "regen" script requires that Python is installed. Some manual intervention may still be required.) (This has been fixed in 1.4beta3.) - New modules: errno, operator (XXX). @@ -25612,8 +25645,8 @@ What's new in 1.4beta1 (since 1.3)? - Added sys.platform and sys.exec_platform for Bill Janssen. -- Installation has been completely overhauled. "make install" now installs -everything, not just the python binary. Installation uses the install-sh +- Installation has been completely overhauled. "make install" now installs +everything, not just the python binary. Installation uses the install-sh script (borrowed from X11) to install each file. - New functions in the posix module: mkfifo, plock, remove (== unlink), @@ -25623,59 +25656,59 @@ and ftruncate. More functions are also available under NT. - Shared library support for FreeBSD. -- The --with-readline option can now be used without a DIRECTORY argument, -for systems where libreadline.* is in one of the standard places. It is +- The --with-readline option can now be used without a DIRECTORY argument, +for systems where libreadline.* is in one of the standard places. It is also possible for it to be a shared library. -- The extension tkinter has been renamed to _tkinter, to avoid confusion -with Tkinter.py oncase insensitive file systems. It now supports Tk 4.1 as +- The extension tkinter has been renamed to _tkinter, to avoid confusion +with Tkinter.py oncase insensitive file systems. It now supports Tk 4.1 as well as 4.0. -- Author's change of address from CWI in Amsterdam, The Netherlands, to +- Author's change of address from CWI in Amsterdam, The Netherlands, to CNRI in Reston, VA, USA. -- The math.hypot() function is now always available (if it isn't found in +- The math.hypot() function is now always available (if it isn't found in the C math library, Python provides its own implementation). -- The latex documentation is now compatible with latex2e, thanks to David +- The latex documentation is now compatible with latex2e, thanks to David Ascher. - The expression x**y is now equivalent to pow(x, y). - The indexing expression x[a, b, c] is now equivalent to x[(a, b, c)]. -- Complex numbers are now supported. Imaginary constants are written with -a 'j' or 'J' prefix, general complex numbers can be formed by adding a real -part to an imaginary part, like 3+4j. Complex numbers are always stored in -floating point form, so this is equivalent to 3.0+4.0j. It is also -possible to create complex numbers with the new built-in function -complex(re, [im]). For the footprint-conscious, complex number support can +- Complex numbers are now supported. Imaginary constants are written with +a 'j' or 'J' prefix, general complex numbers can be formed by adding a real +part to an imaginary part, like 3+4j. Complex numbers are always stored in +floating point form, so this is equivalent to 3.0+4.0j. It is also +possible to create complex numbers with the new built-in function +complex(re, [im]). For the footprint-conscious, complex number support can be disabled by defining the symbol WITHOUT_COMPLEX. - New built-in function list() is the long-awaited counterpart of tuple(). -- There's a new "cmath" module which provides the same functions as the -"math" library but with complex arguments and results. (There are very -good reasons why math.sqrt(-1) still raises an exception -- you have to use +- There's a new "cmath" module which provides the same functions as the +"math" library but with complex arguments and results. (There are very +good reasons why math.sqrt(-1) still raises an exception -- you have to use cmath.sqrt(-1) to get 1j for an answer.) -- The Python.h header file (which is really the same as allobjects.h except -it disables support for old style names) now includes several more files, +- The Python.h header file (which is really the same as allobjects.h except +it disables support for old style names) now includes several more files, so you have to have fewer #include statements in the average extension. -- The NDEBUG symbol is no longer used. Code that used to be dependent on -the presence of NDEBUG is now present on the absence of DEBUG. TRACE_REFS -and REF_DEBUG have been renamed to Py_TRACE_REFS and Py_REF_DEBUG, -respectively. At long last, the source actually compiles and links without +- The NDEBUG symbol is no longer used. Code that used to be dependent on +the presence of NDEBUG is now present on the absence of DEBUG. TRACE_REFS +and REF_DEBUG have been renamed to Py_TRACE_REFS and Py_REF_DEBUG, +respectively. At long last, the source actually compiles and links without errors when this symbol is defined. -- Several symbols that didn't follow the new naming scheme have been -renamed (usually by adding to rename2.h) to use a Py or _Py prefix. There -are no external symbols left without a Py or _Py prefix, not even those -defined by sources that were incorporated from elsewhere (regexpr.c, +- Several symbols that didn't follow the new naming scheme have been +renamed (usually by adding to rename2.h) to use a Py or _Py prefix. There +are no external symbols left without a Py or _Py prefix, not even those +defined by sources that were incorporated from elsewhere (regexpr.c, md5c.c). (Macros are a different story...) -- There are now typedefs for the structures defined in config.c and +- There are now typedefs for the structures defined in config.c and frozen.c. - New PYTHON_API_VERSION value and .pyc file magic number. @@ -25689,125 +25722,125 @@ frozen.c. - The binhex and binascii modules now actually work. - The cgi module has been almost totally rewritten and documented. -It now supports file upload and a new data type to handle forms more +It now supports file upload and a new data type to handle forms more flexibly. - The formatter module (for use with htmllib) has been overhauled (again). - The ftplib module now supports passive mode and has doc strings. -- In (ideally) all places where binary files are read or written, the file -is now correctly opened in binary mode ('rb' or 'wb') so the code will work +- In (ideally) all places where binary files are read or written, the file +is now correctly opened in binary mode ('rb' or 'wb') so the code will work on Mac or PC. -- Dummy versions of os.path.expandvars() and expanduser() are now provided +- Dummy versions of os.path.expandvars() and expanduser() are now provided on non-Unix platforms. -- Module urllib now has two new functions url2pathname and pathname2url -which turn local filenames into "file:..." URLs using the same rules as -Netscape (why be different). it also supports urlretrieve() with a -pathname parameter, and honors the proxy environment variables (http_proxy +- Module urllib now has two new functions url2pathname and pathname2url +which turn local filenames into "file:..." URLs using the same rules as +Netscape (why be different). it also supports urlretrieve() with a +pathname parameter, and honors the proxy environment variables (http_proxy etc.). The URL parsing has been improved somewhat, too. -- Micro improvements to urlparse. Added urlparse.urldefrag() which +- Micro improvements to urlparse. Added urlparse.urldefrag() which removes a trailing ``#fragment'' if any. - The mailbox module now supports MH style message delimiters as well. -- The mhlib module contains some new functionality: setcontext() to set the -current folder and parsesequence() to parse a sequence as commonly passed +- The mhlib module contains some new functionality: setcontext() to set the +current folder and parsesequence() to parse a sequence as commonly passed to MH commands (e.g. 1-10 or last:5). -- New module mimify for conversion to and from MIME format of email +- New module mimify for conversion to and from MIME format of email messages. -- Module ni now automatically installs itself when first imported -- this -is against the normal rule that modules should define classes and functions -but not invoke them, but appears more useful in the case that two +- Module ni now automatically installs itself when first imported -- this +is against the normal rule that modules should define classes and functions +but not invoke them, but appears more useful in the case that two different, independent modules want to use ni's features. - Some small performance enhancements in module pickle. -- Small interface change to the profile.run*() family of functions -- more +- Small interface change to the profile.run*() family of functions -- more sensible handling of return values. -- The officially registered Mac creator for Python files is 'Pyth'. This +- The officially registered Mac creator for Python files is 'Pyth'. This replaces 'PYTH' which was used before but never registered. - Added regsub.capwords(). (XXX) -- Added string.capwords(), string.capitalize() and string.translate(). +- Added string.capwords(), string.capitalize() and string.translate(). (XXX) -- Fixed an interface bug in the rexec module: it was impossible to pass a -hooks instance to the RExec class. rexec now also supports the dynamic -loading of modules from shared libraries. Some other interfaces have been +- Fixed an interface bug in the rexec module: it was impossible to pass a +hooks instance to the RExec class. rexec now also supports the dynamic +loading of modules from shared libraries. Some other interfaces have been added too. -- Module rfc822 now caches the headers in a dictionary for more efficient +- Module rfc822 now caches the headers in a dictionary for more efficient lookup. -- The sgmllib module now understands a limited number of SGML "shorthands" +- The sgmllib module now understands a limited number of SGML "shorthands" like .... (It's not clear that this was a good idea...) -- The tempfile module actually tries a number of different places to find a -usable temporary directory. (This was prompted by certain Linux -installations that appear to be missing a /usr/tmp directory.) [A bug in -the implementation that would ignore a pre-existing tmpdir global has been +- The tempfile module actually tries a number of different places to find a +usable temporary directory. (This was prompted by certain Linux +installations that appear to be missing a /usr/tmp directory.) [A bug in +the implementation that would ignore a pre-existing tmpdir global has been fixed in beta3.] - Much improved and enhanved FileDialog module for Tkinter. -- Many small changes to Tkinter, to bring it more in line with Tk 4.0 (as +- Many small changes to Tkinter, to bring it more in line with Tk 4.0 (as well as Tk 4.1). -- New socket interfaces include ntohs(), ntohl(), htons(), htonl(), and -s.dup(). Sockets now work correctly on Windows. On Windows, the built-in -extension is called _socket and a wrapper module win/socket.py provides -"makefile()" and "dup()" functionality. On Windows, the select module +- New socket interfaces include ntohs(), ntohl(), htons(), htonl(), and +s.dup(). Sockets now work correctly on Windows. On Windows, the built-in +extension is called _socket and a wrapper module win/socket.py provides +"makefile()" and "dup()" functionality. On Windows, the select module works only with socket objects. - Bugs in bsddb module fixed (e.g. missing default argument values). - The curses extension now includes when available. -- The gdbm module now supports opening databases in "fast" mode by +- The gdbm module now supports opening databases in "fast" mode by specifying 'f' as the second character or the mode string. -- new variables sys.prefix and sys.exec_prefix pass corresponding +- new variables sys.prefix and sys.exec_prefix pass corresponding configuration options / Makefile variables to the Python programmer. -- The ``new'' module now supports creating new user-defined classes as well +- The ``new'' module now supports creating new user-defined classes as well as instances thereof. -- The soundex module now sports get_soundex() to get the soundex value for an -arbitrary string (formerly it would only do soundex-based string +- The soundex module now sports get_soundex() to get the soundex value for an +arbitrary string (formerly it would only do soundex-based string comparison) as well as doc strings. -- New object type "cobject" to safely wrap void pointers for passing them +- New object type "cobject" to safely wrap void pointers for passing them between various extension modules. - More efficient computation of float**smallint. -- The mysterious bug whereby "x.x" (two occurrences of the same -one-character name) typed from the commandline would sometimes fail +- The mysterious bug whereby "x.x" (two occurrences of the same +one-character name) typed from the commandline would sometimes fail mysteriously. -- The initialization of the readline function can now be invoked by a C +- The initialization of the readline function can now be invoked by a C extension through PyOS_ReadlineInit(). -- There's now an externally visible pointer PyImport_FrozenModules which +- There's now an externally visible pointer PyImport_FrozenModules which can be changed by an embedding application. -- The argument parsing functions now support a new format character 'D' to +- The argument parsing functions now support a new format character 'D' to specify complex numbers. - Various memory leaks plugged and bugs fixed. -- Improved support for posix threads (now that real implementations are +- Improved support for posix threads (now that real implementations are beginning to apepar). Still no fully functioning semaphores. -- Some various and sundry improvements and new entries in the Tools +- Some various and sundry improvements and new entries in the Tools directory. @@ -27417,7 +27450,7 @@ it's now about 38). The limit on the size of the *run-time* stack has completely been removed -- this means that tuple or list displays can contain any number of elements (formerly more than 50 would crash the -interpreter). +interpreter). Changes to existing built-in functions and methods diff --git a/Misc/NEWS b/Misc/NEWS index 39785a78411e..ad03e0a7e492 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -1,7458 +1,6164 @@ -+++++++++++ ++++++++++++ Python News +++++++++++ -What's New in Python 3.4.0 Beta 2? -================================== +What's New in Python 3.5 alpha 2? +================================= -Release date: 2014-01-05 +Release date: 2015-03-08 Core and Builtins ----------------- -- Issue #19729: In str.format(), fix recursive expansion in format spec. - -- Issue #19638: Fix possible crash / undefined behaviour from huge (more than 2 - billion characters) input strings in _Py_dg_strtod. - Library ------- -- Issue #19781: ftplib now supports SSLContext.check_hostname and server name - indication for TLS/SSL connections. +- Issues #814253, #9179: Group references and conditional group references now + work in lookbehind assertions in regular expressions. -- Issue #19509: Add SSLContext.check_hostname to match the peer's certificate - with server_hostname on handshake. +- 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 #15798: Fixed subprocess.Popen() to no longer fail if file - descriptor 0, 1 or 2 is closed. +- Issue #5700: io.FileIO() called flush() after closing the file. + flush() was not called in close() if closefd=False. -- Issue #17897: Optimized unpickle prefetching. +- Issue #23374: Fixed pydoc failure with non-ASCII files when stdout encoding + differs from file system encoding (e.g. on Mac OS). -- Issue #3693: Make the error message more helpful when the array.array() - constructor is given a str. Move the array module typecode documentation to - the docstring of the constructor. +- Issue #23481: Remove RC4 from the SSL module's default cipher list. -- Issue #19088: Fixed incorrect caching of the copyreg module in - object.__reduce__() and object.__reduce_ex__(). +- Issue #21548: Fix pydoc.synopsis() and pydoc.apropos() on modules with empty + docstrings. -- Issue #19698: Removed exec_module() methods from - importlib.machinery.BuiltinImporter and ExtensionFileLoader. +- Issue #22885: Fixed arbitrary code execution vulnerability in the dbm.dumb + module. Original patch by Claudiu Popa. -- Fixed _pickle.Unpickler to not fail when loading empty strings as - persistent IDs. +- Issue #23239: ssl.match_hostname() now supports matching of IP addresses. -- Issue #11480: Fixed copy.copy to work with classes with custom metaclasses. - Patch by Daniel Urban. +- Issue #23146: Fix mishandling of absolute Windows paths with forward + slashes in pathlib. -- Issue #6477: Added support for pickling the types of built-in singletons - (i.e., Ellipsis, NotImplemented, None). +- Issue #23096: Pickle representation of floats with protocol 0 now is the same + for both Python and C implementations. -- ssl.create_default_context() sets OP_NO_COMPRESSION to prevent CRIME. +- Issue #19105: pprint now more efficiently uses free space at the right. -- Issue #19802: Add socket.SO_PRIORITY. +- Issue #14910: Add allow_abbrev parameter to argparse.ArgumentParser. Patch by + Jonathan Paugh, Steven Bethard, paul j3 and Daniel Eriksson. -- Issue #11508: Fixed uuid.getnode() and uuid.uuid1() on environment with - virtual interface. Original patch by Kent Frazier. +- Issue #21717: tarfile.open() now supports 'x' (exclusive creation) mode. -- Issue #11489: JSON decoder now accepts lone surrogates. +- Issue #23344: marshal.dumps() is now 20-25% faster on average. -- Issue #19545: Avoid chained exceptions while passing stray % to - time.strptime(). Initial patch by Claudiu Popa. +- Issue #20416: marshal.dumps() with protocols 3 and 4 is now 40-50% faster on + average. -Tests ------ +- Issue #23421: Fixed compression in tarfile CLI. Patch by wdv4758h. -- Issue #19595: Re-enabled a long-disabled test in test_winsound. +- Issue #23361: Fix possible overflow in Windows subprocess creation code. -- Issue #19588: Fixed tests in test_random that were silently skipped most - of the time. Patch by Julian Gindi. +- logging.handlers.QueueListener now takes a respect_handler_level keyword + argument which, if set to True, will pass messages to handlers taking handler + levels into account. Build ----- -- Issue #19788: kill_python(_d).exe is now run as a PreBuildEvent on the - pythoncore sub-project. This should prevent build errors due a previous - build's python(_d).exe still running. - -Documentation -------------- +- Issue #23445: pydebug builds now use "gcc -Og" where possible, to make + the resulting executable faster. -- Issue #19845: Updated the Compiling Python on Windows section. +Windows +------- -- Issue #19795: Improved markup of True/False constants. +- Issue #23437: Make user scripts directory versioned on Windows. Patch by Paul + Moore. -What's New in Python 3.4.0 Beta 1? -================================== +What's New in Python 3.5 alpha 1? +================================= -Release date: 2013-11-24 +Release date: 2015-02-08 Core and Builtins ----------------- -- Use the repr of a module name in more places in import, especially - exceptions. +- Issue #23285: PEP 475 - EINTR handling. -- Issue #19619: str.encode, bytes.decode and bytearray.decode now use an - internal API to throw LookupError for known non-text encodings, rather - than attempting the encoding or decoding operation and then throwing a - TypeError for an unexpected output type. (The latter mechanism remains - in place for third party non-text encodings) +- Issue #22735: Fix many edge cases (including crashes) involving custom mro() + implementations. -- Issue #19183: Implement PEP 456 'secure and interchangeable hash algorithm'. - Python now uses SipHash24 on all major platforms. +- Issue #22896: Avoid using PyObject_AsCharBuffer(), PyObject_AsReadBuffer() + and PyObject_AsWriteBuffer(). -- Issue #12892: The utf-16* and utf-32* encoders no longer allow surrogate code - points (U+D800-U+DFFF) to be encoded. The utf-32* decoders no longer decode - byte sequences that correspond to surrogate code points. The surrogatepass - error handler now works with the utf-16* and utf-32* codecs. Based on - patches by Victor Stinner and Kang-Hao (Kenny) Lu. +- Issue #21295: Revert some changes (issue #16795) to AST line numbers and + column offsets that constituted a regression. -- Issue #17806: Added keyword-argument support for "tabsize" to - str/bytes.expandtabs(). +- Issue #22986: Allow changing an object's __class__ between a dynamic type and + static type in some cases. -- Issue #17828: Output type errors in str.encode(), bytes.decode() and - bytearray.decode() now direct users to codecs.encode() or codecs.decode() - as appropriate. +- Issue #15859: PyUnicode_EncodeFSDefault(), PyUnicode_EncodeMBCS() and + PyUnicode_EncodeCodePage() now raise an exception if the object is not an + Unicode object. For PyUnicode_EncodeFSDefault(), it was already the case on + platforms other than Windows. Patch written by Campbell Barton. -- Issue #17828: The interpreter now attempts to chain errors that occur in - codec processing with a replacement exception of the same type that - includes the codec name in the error message. It ensures it only does this - when the creation of the replacement exception won't lose any information. +- Issue #21408: The default __ne__() now returns NotImplemented if __eq__() + returned NotImplemented. Original patch by Martin Panter. -- Issue #19466: Clear the frames of daemon threads earlier during the - Python shutdown to call objects destructors. So "unclosed file" resource - warnings are now corretly emitted for daemon threads. +- Issue #23321: Fixed a crash in str.decode() when error handler returned + replacment string longer than mailformed input data. -- Issue #19514: Deduplicate some _Py_IDENTIFIER declarations. - Patch by Andrei Dorian Duma. +- Issue #22286: The "backslashreplace" error handlers now works with + decoding and translating. -- Issue #17936: Fix O(n**2) behaviour when adding or removing many subclasses - of a given type. +- Issue #23253: Delay-load ShellExecute[AW] in os.startfile for reduced + startup overhead on Windows. -- Issue #19428: zipimport now handles errors when reading truncated or invalid - ZIP archive. +- Issue #22038: pyatomic.h now uses stdatomic.h or GCC built-in functions for + atomic memory access if available. Patch written by Vitor de Lima and Gustavo + Temple. -- Issue #18408: Add a new PyFrame_FastToLocalsWithError() function to handle - exceptions when merging fast locals into f_locals of a frame. - PyEval_GetLocals() now raises an exception and return NULL on failure. +- Issue #20284: %-interpolation (aka printf) formatting added for bytes and + bytearray. -- Issue #19369: Optimized the usage of __length_hint__(). +- Issue #23048: Fix jumping out of an infinite while loop in the pdb. -- Issue #18603: Ensure that PyOS_mystricmp and PyOS_mystrnicmp are in the - Python executable and not removed by the linker's optimizer. +- Issue #20335: bytes constructor now raises TypeError when encoding or errors + is specified with non-string argument. Based on patch by Renaud Blanch. -- Issue #19306: Add extra hints to the faulthandler module's stack - dumps that these are "upside down". +- Issue #22834: If the current working directory ends up being set to a + non-existent directory then import will no longer raise FileNotFoundError. -Library -------- +- Issue #22869: Move the interpreter startup & shutdown code to a new + dedicated pylifecycle.c module -- Issue #3158: doctest can now find doctests in functions and methods - written in C. +- Issue #22847: Improve method cache efficiency. -- Issue #13477: Added command line interface to the tarfile module. - Original patch by Berker Peksag. +- Issue #22335: Fix crash when trying to enlarge a bytearray to 0x7fffffff + bytes on a 32-bit platform. -- Issue #19674: inspect.signature() now produces a correct signature - for some builtins. +- Issue #22653: Fix an assertion failure in debug mode when doing a reentrant + dict insertion in debug mode. -- Issue #19722: Added opcode.stack_effect(), which - computes the stack effect of bytecode instructions. +- Issue #22643: Fix integer overflow in Unicode case operations (upper, lower, + title, swapcase, casefold). -- Issue #19735: Implement private function ssl._create_stdlib_context() to - create SSLContext objects in Python's stdlib module. It provides a single - configuration point and makes use of SSLContext.load_default_certs(). +- Issue #17636: Circular imports involving relative imports are now + supported. -- Issue #16203: Add re.fullmatch() function and regex.fullmatch() method, - which anchor the pattern at both ends of the string to match. - Original patch by Matthew Barnett. +- Issue #22604: Fix assertion error in debug mode when dividing a complex + number by (nan+0j). -- Issue #13592: Improved the repr for regular expression pattern objects. - Based on patch by Hugo Lopes Tavares. +- Issue #21052: Do not raise ImportWarning when sys.path_hooks or sys.meta_path + are set to None. -- Issue #19641: Added the audioop.byteswap() function to convert big-endian - samples to little-endian and vice versa. +- Issue #16518: Use 'bytes-like object required' in error messages that + previously used the far more cryptic "'x' does not support the buffer + protocol. -- Issue #15204: Deprecated the 'U' mode in file-like objects. +- Issue #22470: Fixed integer overflow issues in "backslashreplace", + "xmlcharrefreplace", and "surrogatepass" error handlers. -- Issue #17810: Implement PEP 3154, pickle protocol 4. +- Issue #22540: speed up `PyObject_IsInstance` and `PyObject_IsSubclass` in the + common case that the second argument has metaclass `type`. -- Issue #19668: Added support for the cp1125 encoding. +- Issue #18711: Add a new `PyErr_FormatV` function, similar to `PyErr_Format` + but accepting a `va_list` argument. -- Issue #19689: Add ssl.create_default_context() factory function. It creates - a new SSLContext object with secure default settings. +- Issue #22520: Fix overflow checking when generating the repr of a unicode + object. -- Issue #19727: os.utime(..., None) is now potentially more precise - under Windows. +- Issue #22519: Fix overflow checking in PyBytes_Repr. -- Issue #17201: ZIP64 extensions now are enabled by default. Patch by - William Mallard. +- Issue #22518: Fix integer overflow issues in latin-1 encoding. -- Issue #19292: Add SSLContext.load_default_certs() to load default root CA - certificates from default stores or system stores. By default the method - loads CA certs for authentication of server certs. +- Issue #16324: _charset parameter of MIMEText now also accepts + email.charset.Charset instances. Initial patch by Claude Paroz. -- Issue #19673: Add pathlib to the stdlib as a provisional module (PEP 428). +- Issue #1764286: Fix inspect.getsource() to support decorated functions. + Patch by Claudiu Popa. -- Issue #16596: pdb in a generator now properly skips over yield and - yield from rather than stepping out of the generator into its - caller. (This is essential for stepping through asyncio coroutines.) +- Issue #18554: os.__all__ includes posix functions. -- Issue #17916: Added dis.Bytecode.from_traceback() and - dis.Bytecode.current_offset to easily display "current instruction" - markers in the new disassembly API (Patch by Claudiu Popa). +- Issue #21391: Use os.path.abspath in the shutil module. -- Issue #19552: venv now supports bootstrapping pip into virtual environments +- Issue #11471: avoid generating a JUMP_FORWARD instruction at the end of + an if-block if there is no else-clause. Original patch by Eugene Toder. -- Issue #17134: Finalize interface to Windows' certificate store. Cert and - CRL enumeration are now two functions. enum_certificates() also returns - purpose flags as set of OIDs. +- Issue #22215: Now ValueError is raised instead of TypeError when str or bytes + argument contains not permitted null character or byte. -- Issue #19555: Restore sysconfig.get_config_var('SO'), (and the distutils - equivalent) with a DeprecationWarning pointing people at $EXT_SUFFIX. +- Issue #22258: Fix 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 #8813: Add SSLContext.verify_flags to change the verification flags - of the context in order to enable certification revocation list (CRL) - checks or strict X509 rules. +- Issue #21389: Displaying the __qualname__ of the underlying function in the + repr of a bound method. -- Issue #18294: Fix the zlib module to make it 64-bit safe. +- Issue #22206: Using pthread, PyThread_create_key() now sets errno to ENOMEM + and returns -1 (error) on integer overflow. -- Issue #19682: Fix compatibility issue with old version of OpenSSL that - was introduced by Issue #18379. +- Issue #20184: Argument Clinic based signature introspection added for + 30 of the builtin functions. -- Issue #14455: plistlib now supports binary plists and has an updated API. +- Issue #22116: C functions and methods (of the 'builtin_function_or_method' + type) can now be weakref'ed. Patch by Wei Wu. -- Issue #19633: Fixed writing not compressed 16- and 32-bit wave files on - big-endian platforms. +- Issue #22077: Improve index error messages for bytearrays, bytes, lists, + and tuples by adding 'or slices'. Added ', not sp_namp, and sp_pwd->sp_pwdp. The old names are kept as extra - structseq members, for backward compatibility. +- Issue #23399: pyvenv creates relative symlinks where possible. -- Issue #6157: Fixed tkinter.Text.debug(). tkinter.Text.bbox() now raises - TypeError instead of TclError on wrong number of arguments. Original patch - by Guilherme Polo. +- Issue #20289: cgi.FieldStorage() now supports the context management + protocol. -- Issue #10197: Rework subprocess.get[status]output to use subprocess - functionality and thus to work on Windows. Patch by Nick Coghlan +- Issue #13128: Print response headers for CONNECT requests when debuglevel + > 0. Patch by Demian Brecht. -- Issue #6160: The bbox() method of tkinter.Spinbox now returns a tuple of - integers instead of a string. Based on patch by Guilherme Polo. +- Issue #15381: Optimized io.BytesIO to make less allocations and copyings. -- Issue #19403: contextlib.redirect_stdout is now reentrant +- Issue #22818: Splitting on a pattern that could match an empty string now + raises a warning. Patterns that can only match empty strings are now + rejected. -- Issue #19286: Directories in ``package_data`` are no longer added to - the filelist, preventing failure outlined in the ticket. +- Issue #23099: Closing io.BytesIO with exported buffer is rejected now to + prevent corrupting exported buffer. -- Issue #19480: HTMLParser now accepts all valid start-tag names as defined - by the HTML5 standard. +- Issue #23326: Removed __ne__ implementations. Since fixing default __ne__ + implementation in issue #21408 they are redundant. -- Issue #15114: The html.parser module now raises a DeprecationWarning when the - strict argument of HTMLParser or the HTMLParser.error method are used. +- Issue #23363: Fix possible overflow in itertools.permutations. -- Issue #19410: Undo the special-casing removal of '' for - importlib.machinery.FileFinder. +- Issue #23364: Fix possible overflow in itertools.product. -- Issue #19424: Fix the warnings module to accept filename containing surrogate - characters. +- Issue #23366: Fixed possible integer overflow in itertools.combinations. -- Issue #19435: Fix directory traversal attack on CGIHttpRequestHandler. +- Issue #23366: Fixed possible integer overflow in itertools.combinations. -- Issue #19227: Remove pthread_atfork() handler. The handler was added to - solve #18747 but has caused issues. +- Issue #23369: Fixed possible integer overflow in + _json.encode_basestring_ascii. -- Issue #19420: Fix reference leak in module initalization code of - _hashopenssl.c +- 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 #19329: Optimized compiling charsets in regular expressions. +- Issue #14099: Restored support of writing ZIP files to tellable but + non-seekable streams. -- Issue #19227: Try to fix deadlocks caused by re-seeding then OpenSSL - pseudo-random number generator on fork(). +- Issue #14099: Writing to ZipFile and reading multiple ZipExtFiles is + threadsafe now. -- Issue #16037: HTTPMessage.readheaders() raises an HTTPException when more than - 100 headers are read. Adapted from patch by Jyrki Pulliainen. +- Issue #19361: JSON decoder now raises JSONDecodeError instead of ValueError. -- Issue #16040: CVE-2013-1752: nntplib: Limit maximum line lengths to 2048 to - prevent readline() calls from consuming too much memory. Patch by Jyrki - Pulliainen. +- Issue #18518: timeit now rejects statements which can't be compiled outside + a function or a loop (e.g. "return" or "break"). -- Issue #16041: CVE-2013-1752: poplib: Limit maximum line lengths to 2048 to - prevent readline() calls from consuming too much memory. Patch by Jyrki - Pulliainen. +- Issue #23094: Fixed readline with frames in Python implementation of pickle. -- Issue #17997: Change behavior of ``ssl.match_hostname()`` to follow RFC 6125, - for security reasons. It now doesn't match multiple wildcards nor wildcards - inside IDN fragments. +- Issue #23268: Fixed bugs in the comparison of ipaddress classes. -- Issue #16039: CVE-2013-1752: Change use of readline in imaplib module to limit - line length. Patch by Emil Lind. +- Issue #21408: Removed incorrect implementations of __ne__() which didn't + returned NotImplemented if __eq__() returned NotImplemented. The default + __ne__() now works correctly. -- Issue #19330: the unnecessary wrapper functions have been removed from the - implementations of the new contextlib.redirect_stdout and - contextlib.suppress context managers, which also ensures they provide - reasonable help() output on instances +- Issue #19996: :class:`email.feedparser.FeedParser` now handles (malformed) + headers with no key rather than amusing the body has started. -- Issue #19393: Fix symtable.symtable function to not be confused when there are - functions or classes named "top". +- Issue #20188: Support Application-Layer Protocol Negotiation (ALPN) in the ssl + module. -- Issue #18685: Restore re performance to pre-PEP 393 levels. +- Issue #23133: Pickling of ipaddress objects now produces more compact and + portable representation. -- Issue #19339: telnetlib module is now using time.monotonic() when available - to compute timeout. +- Issue #23248: Update ssl error codes from latest OpenSSL git master. -- Issue #19399: fix sporadic test_subprocess failure. +- Issue #23266: Much faster implementation of ipaddress.collapse_addresses() + when there are many non-consecutive addresses. -- Issue #13234: Fix os.listdir to work with extended paths on Windows. - Patch by Santoso Wijaya. +- Issue #23098: 64-bit dev_t is now supported in the os module. -- Issue #19375: The site module adding a "site-python" directory to sys.path, - if it exists, is now deprecated. +- Issue #21817: When an exception is raised in a task submitted to a + ProcessPoolExecutor, the remote traceback is now displayed in the + parent process. Patch by Claudiu Popa. -- Issue #19379: Lazily import linecache in the warnings module, to make - startup with warnings faster until a warning gets printed. +- Issue #15955: Add an option to limit output size when decompressing LZMA + data. Patch by Nikolaus Rath and Martin Panter. -- Issue #19288: Fixed the "in" operator of dbm.gnu databases for string - argument. Original patch by Arfrever Frehtes Taifersar Arahesis. +- Issue #23250: In the http.cookies module, capitalize "HttpOnly" and "Secure" + as they are written in the standard. -- Issue #19287: Fixed the "in" operator of dbm.ndbm databases for string - argument. Original patch by Arfrever Frehtes Taifersar Arahesis. +- Issue #23063: In the disutils' check command, fix parsing of reST with code or + code-block directives. -- Issue #19327: Fixed the working of regular expressions with too big charset. +- Issue #23209, #23225: selectors.BaseSelector.get_key() now raises a + RuntimeError if the selector is closed. And selectors.BaseSelector.close() + now clears its internal reference to the selector mapping to break a + reference cycle. Initial patch written by Martin Richard. -- Issue #17400: New 'is_global' attribute for ipaddress to tell if an address - is allocated by IANA for global or private networks. +- Issue #19777: Provide a home() classmethod on Path objects. Contributed + by Victor Salgado and Mayank Tripathi. -- Issue #19350: Increasing the test coverage of macurl2path. Patch by Colin - Williams. +- Issue #23206: Make ``json.dumps(..., ensure_ascii=False)`` as fast as the + default case of ``ensure_ascii=True``. Patch by Naoki Inada. -- Issue #19365: Optimized the parsing of long replacement string in re.sub*() - functions. +- Issue #23185: Add math.inf and math.nan constants. -- Issue #19352: Fix unittest discovery when a module can be reached - through several paths (e.g. under Debian/Ubuntu with virtualenv). +- Issue #23186: Add ssl.SSLObject.shared_ciphers() and + ssl.SSLSocket.shared_ciphers() to fetch the client's list ciphers sent at + handshake. -- Issue #15207: Fix mimetypes to read from correct part of Windows registry - Original patch by Dave Chambers +- Issue #23143: Remove compatibility with OpenSSLs older than 0.9.8. -- Issue #16595: Add prlimit() to resource module. +- Issue #23132: Improve performance and introspection support of comparison + methods created by functool.total_ordering. -- Issue #19324: Expose Linux-specific constants in resource module. +- Issue #19776: Add a expanduser() method on Path objects. -- Issue #17400: ipaddress should make it easy to identify rfc6598 addresses. +- Issue #23112: Fix SimpleHTTPServer to correctly carry the query string and + fragment when it redirects to add a trailing slash. -- Load SSL's error strings in hashlib. +- Issue #21793: Added http.HTTPStatus enums (i.e. HTTPStatus.OK, + HTTPStatus.NOT_FOUND). Patch by Demian Brecht. -- Issue #18527: Upgrade internal copy of zlib to 1.2.8. +- Issue #23093: In the io, module allow more operations to work on detached + streams. -- Issue #19274: Add a filterfunc parameter to PyZipFile.writepy. +- Issue #23111: In the ftplib, make ssl.PROTOCOL_SSLv23 the default protocol + version. -- Issue #8964: fix platform._sys_version to handle IronPython 2.6+. - Patch by Martin Matusiak. +- Issue #22585: On OpenBSD 5.6 and newer, os.urandom() now calls getentropy(), + instead of reading /dev/urandom, to get pseudo-random bytes. -- Issue #19413: Restore pre-3.3 reload() semantics of re-finding modules. +- Issue #19104: pprint now produces evaluable output for wrapped strings. -- Issue #18958: Improve error message for json.load(s) while passing a string - that starts with a UTF-8 BOM. +- Issue #23071: Added missing names to codecs.__all__. Patch by Martin Panter. -- Issue #19307: Improve error message for json.load(s) while passing objects - of the wrong type. +- Issue #22783: Pickling now uses the NEWOBJ opcode instead of the NEWOBJ_EX + opcode if possible. -- Issue #16038: CVE-2013-1752: ftplib: Limit amount of data read by - limiting the call to readline(). Original patch by MichaÅ‚ - JastrzÄ™bski and Giampaolo Rodola. +- Issue #15513: Added a __sizeof__ implementation for pickle classes. -- Issue #17087: Improved the repr for regular expression match objects. +- 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. -Tests ------ +- 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 #19664: test_userdict's repr test no longer depends on the order - of dict elements. +- Issue #23016: A warning no longer produces an AttributeError when the program + is run with pythonw.exe. -- Issue #19440: Clean up test_capi by removing an unnecessary __future__ - import, converting from test_main to unittest.main, and running the - _testcapi module tests as subTests of a unittest TestCase method. +- 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 #19378: the main dis module tests are now run with both stdout - redirection *and* passing an explicit file parameter +- Issue #1218234: Fix inspect.getsource() to load updated source of + reloaded module. Initial patch by Berker Peksag. -- Issue #19378: removed the not-actually-helpful assertInstructionMatches - and assertBytecodeExactlyMatches helpers from bytecode_helper +- Issue #21740: Support wrapped callables in doctest. Patch by Claudiu Popa. -- Issue #18702: All skipped tests now reported as skipped. +- Issue #23009: Make sure selectors.EpollSelecrtor.select() works when no + FD is registered. -- Issue #19439: interpreter embedding tests are now executed on Windows - (Patch by Zachary Ware) +- Issue #22959: In the constructor of http.client.HTTPSConnection, prefer the + context's check_hostname attribute over the *check_hostname* parameter. -- Issue #19085: Added basic tests for all tkinter widget options. +- Issue #22696: Add function :func:`sys.is_finalizing` to know about + interpreter shutdown. -- Issue 19384: Fix test_py_compile for root user, patch by Claudiu Popa. +- Issue #16043: Add a default limit for the amount of data xmlrpclib.gzip_decode + will return. This resolves CVE-2013-1753. -Documentation -------------- +- Issue #14099: ZipFile.open() no longer reopen the underlying file. Objects + returned by ZipFile.open() can now operate independently of the ZipFile even + if the ZipFile was created by passing in a file-like object as the first + argument to the constructor. -- Issue #18326: Clarify that list.sort's arguments are keyword-only. Also, - attempt to reduce confusion in the glossary by not saying there are - different "types" of arguments and parameters. +- 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. -Build ------ +- Issue #21971: Update turtledemo doc and add module to the index. -- Issue #19358: "make clinic" now runs the Argument Clinic preprocessor - over all CPython source files. +- Issue #21032. Fixed socket leak if HTTPConnection.getresponse() fails. + Original patch by Martin Panter. -- Update SQLite to 3.8.1, xz to 5.0.5, and Tcl/Tk to 8.6.1 on Windows. +- Issue #22407: Deprecated the use of re.LOCALE flag with str patterns or + re.ASCII. It was newer worked. -- Issue #16632: Enable DEP and ASLR on Windows. +- Issue #22902: The "ip" command is now used on Linux to determine MAC address + in uuid.getnode(). Pach by Bruno Cauet. -- Issue #17791: Drop PREFIX and EXEC_PREFIX definitions from PC/pyconfig.h +- Issue #22960: Add a context argument to xmlrpclib.ServerProxy constructor. -- Add workaround for VS 2010 nmake clean issue. VS 2010 doesn't set up PATH - for nmake.exe correctly. +- Issue #22389: Add contextlib.redirect_stderr(). -- Issue #19550: Implement Windows installer changes of PEP 453 (ensurepip). +- 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 #19520: Fix compiler warning in the _sha3 module on 32bit Windows. +- Issue #22915: SAX parser now supports files opened with file descriptor or + bytes path. -- Issue #19356: Avoid using a C variabled named "_self", it's a reserved - word in some C compilers. +- Issue #22609: Constructors and update methods of mapping classes in the + collections module now accept the self keyword argument. -- Issue #15792: Correct build options on Win64. Patch by Jeremy Kloth. +- Issue #22940: Add readline.append_history_file. -- Issue #19373: Apply upstream change to Tk 8.5.15 fixing OS X 10.9 - screen refresh problem for OS X installer build. +- Issue #19676: Added the "namereplace" error handler. -- Issue #19649: On OS X, the same set of file names are now installed - in bin directories for all configurations: non-framework vs framework, - and single arch vs universal builds. pythonx.y-32 is now always - installed for 64-bit/32-bit universal builds. The obsolete and - undocumented pythonw* symlinks are no longer installed anywhere. +- Issue #22788: Add *context* parameter to logging.handlers.HTTPHandler. -- Issue #19553: PEP 453 - "make install" and "make altinstall" now install or - upgrade pip by default, using the bundled pip provided by the new ensurepip - module. A new configure option, --with-ensurepip[=upgrade|install|no], is - available to override the default ensurepip "--upgrade" option. The option - can also be set with "make [alt]install ENSUREPIP=[upgrade|install\no]". +- Issue #22921: Allow SSLContext to take the *hostname* parameter even if + OpenSSL doesn't support SNI. -- Issue #19551: PEP 453 - the OS X installer now installs pip by default. +- Issue #22894: TestCase.subTest() would cause the test suite to be stopped + when in failfast mode, even in the absence of failures. -- Update third-party libraries for OS X installers: - xz 5.0.3 -> 5.0.5 - SQLite 3.7.13 -> 3.8.1 +- Issue #22796: HTTP cookie parsing is now stricter, in order to protect + against potential injection attacks. -- Issue #15663: Revert OS X installer built-in Tcl/Tk support for 3.4.0b1. - Some third-party projects, such as Matplotlib and PIL/Pillow, - depended on being able to build with Tcl and Tk frameworks in - /Library/Frameworks. +- Issue #22370: Windows detection in pathlib is now more robust. -Tools/Demos ------------ +- Issue #22841: Reject coroutines in asyncio add_signal_handler(). + Patch by Ludovic.Gasc. -- Issue #19730: Argument Clinic now supports all the existing PyArg - "format units" as legacy converters, as well as two new features: - "self converters" and the "version" directive. +- Issue #19494: Added urllib.request.HTTPBasicPriorAuthHandler. Patch by + Matej Cepl. -- Issue #19552: pyvenv now bootstraps pip into virtual environments by - default (pass --without-pip to request the old behaviour) +- Issue #22578: Added attributes to the re.error class. -- Issue #19390: Argument Clinic no longer accepts malformed Python - and C ids. +- Issue #22849: Fix possible double free in the io.TextIOWrapper constructor. -What's New in Python 3.4.0 Alpha 4? -=================================== +- Issue #12728: Different Unicode characters having the same uppercase but + different lowercase are now matched in case-insensitive regular expressions. -Release date: 2013-10-20 +- Issue #22821: Fixed fcntl() with integer argument on 64-bit big-endian + platforms. -Core and Builtins ------------------ +- Issue #21650: Add an `--sort-keys` option to json.tool CLI. -- Issue #19301: Give classes and functions that are explicitly marked global a - global qualname. +- Issue #22824: Updated reprlib output format for sets to use set literals. + Patch contributed by Berker Peksag. -- Issue #19279: UTF-7 decoder no longer produces illegal strings. +- Issue #22824: Updated reprlib output format for arrays to display empty + arrays without an unnecessary empty list. Suggested by Serhiy Storchaka. -- Issue #16612: Add "Argument Clinic", a compile-time preprocessor for - C files to generate argument parsing code. (See PEP 436.) +- Issue #22406: Fixed the uu_codec codec incorrectly ported to 3.x. + Based on patch by Martin Panter. -- Issue #18810: Shift stat calls in importlib.machinery.FileFinder such that - the code is optimistic that if something exists in a directory named exactly - like the possible package being searched for that it's in actuality a - directory. +- Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat. + Based on patch by Aivars KalvÄns. -- Issue #18416: importlib.machinery.PathFinder now treats '' as the cwd and - importlib.machinery.FileFinder no longer special-cases '' to '.'. This leads - to modules imported from cwd to now possess an absolute file path for - __file__ (this does not affect modules specified by path on the CLI but it - does affect -m/runpy). It also allows FileFinder to be more consistent by not - having an edge case. +- Issue #22769: Fixed ttk.Treeview.tag_has() when called without arguments. -- Issue #4555: All exported C symbols are now prefixed with either - "Py" or "_Py". +- Issue #22417: Verify certificates by default in httplib (PEP 476). -- Issue #19219: Speed up marshal.loads(), and make pyc files slightly - (5% to 10%) smaller. +- Issue #22775: Fixed unpickling of http.cookies.SimpleCookie with protocol 2 + and above. Patch by Tim Graham. -- Issue #19221: Upgrade Unicode database to version 6.3.0. +- Issue #22776: Brought excluded code into the scope of a try block in + SysLogHandler.emit(). -- Issue #16742: The result of the C callback PyOS_ReadlineFunctionPointer must - now be a string allocated by PyMem_RawMalloc() or PyMem_RawRealloc() (or NULL - if an error occurred), instead of a string allocated by PyMem_Malloc() or - PyMem_Realloc(). +- Issue #22665: Add missing get_terminal_size and SameFileError to + shutil.__all__. -- Issue #19199: Remove ``PyThreadState.tick_counter`` field +- Issue #6623: Remove deprecated Netrc class in the ftplib module. Patch by + Matt Chaput. -- Fix macro expansion of _PyErr_OCCURRED(), and make sure to use it in at - least one place so as to avoid regressions. +- Issue #17381: Fixed handling of case-insensitive ranges in regular + expressions. -- Issue #19087: Improve bytearray allocation in order to allow cheap popping - of data at the front (slice deletion). +- Issue #22410: Module level functions in the re module now cache compiled + locale-dependent regular expressions taking into account the locale. -- Issue #19014: memoryview.cast() is now allowed on zero-length views. +- Issue #22759: Query methods on pathlib.Path() (exists(), is_dir(), etc.) + now return False when the underlying stat call raises NotADirectoryError. -- Issue #18690: memoryview is now automatically registered with - collections.abc.Sequence +- 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 #19078: memoryview now correctly supports the reversed builtin - (Patch by Claudiu Popa) +- Issue #22217: Implemented reprs of classes in the zipfile module. -Library -------- +- Issue #22457: Honour load_tests in the start_dir of discovery. -- Issue #17457: unittest test discovery now works with namespace packages. - Patch by Claudiu Popa. +- Issue #18216: gettext now raises an error when a .mo file has an + unsupported major version number. Patch by Aaron Hill. -- Issue #18235: Fix the sysconfig variables LDSHARED and BLDSHARED under AIX. - Patch by David Edelsohn. +- Issue #13918: Provide a locale.delocalize() function which can remove + locale-specific number formatting from a string representing a number, + without then converting it to a specific type. Patch by Cédric Krier. -- Issue #18606: Add the new "statistics" module (PEP 450). Contributed - by Steven D'Aprano. +- Issue #22676: Make the pickling of global objects which don't have a + __module__ attribute less slow. -- Issue #12866: The audioop module now supports 24-bit samples. +- Issue #18853: Fixed ResourceWarning in shlex.__nain__. -- Issue #19254: Provide an optimized Python implementation of pbkdf2_hmac. +- Issue #9351: Defaults set with set_defaults on an argparse subparser + are no longer ignored when also set on the parent parser. -- Issues #19201, #19222, #19223: Add "x" mode (exclusive creation) in opening - file to bz2, gzip and lzma modules. Patches by Tim Heaney and Vajrasky Kok. +- Issue #7559: unittest test loading ImportErrors are reported as import errors + with their import exception rather than as attribute errors after the import + has already failed. -- Fix a reference count leak in _sre. +- Issue #19746: Make it possible to examine the errors from unittest + discovery without executing the test suite. The new `errors` attribute + on TestLoader exposes these non-fatal errors encountered during discovery. -- Issue #19262: Initial check in of the 'asyncio' package (a.k.a. Tulip, - a.k.a. PEP 3156). There are no docs yet, and the PEP is slightly - out of date with the code. This module will have *provisional* status - in Python 3.4. +- 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 #19276: Fixed the wave module on 64-bit big-endian platforms. +- Issue #22638: SSLv3 is now disabled throughout the standard library. + It can still be enabled by instantiating a SSLContext manually. -- Issue #19266: Rename the new-in-3.4 ``contextlib.ignore`` context manager - to ``contextlib.suppress`` in order to be more consistent with existing - descriptions of that operation elsewhere in the language and standard - library documentation (Patch by Zero Piraeus). +- Issue #22641: In asyncio, the default SSL context for client connections + is now created using ssl.create_default_context(), for stronger security. -- Issue #18891: Completed the new email package (provisional) API additions - by adding new classes EmailMessage, MIMEPart, and ContentManager. +- Issue #17401: Include closefd in io.FileIO repr. -- Issue #18281: Unused stat constants removed from `tarfile`. +- Issue #21338: Add silent mode for compileall. quiet parameters of + compile_{dir, file, path} functions now have a multilevel value. Also, + -q option of the CLI now have a multilevel value. Patch by Thomas Kluyver. -- Issue #18468: The re.split, re.findall, and re.sub functions and the group() - and groups() methods of match object now always return a string or a bytes - object. +- Issue #20152: Convert the array and cmath modules to Argument Clinic. -- Issue #18725: The textwrap module now supports truncating multiline text. +- Issue #18643: Add socket.socketpair() on Windows. -- Issue #18776: atexit callbacks now display their full traceback when they - raise an exception. +- Issue #22435: Fix a file descriptor leak when SocketServer bind fails. -- Issue #17827: Add the missing documentation for ``codecs.encode`` and - ``codecs.decode``. +- Issue #13096: Fixed segfault in CTypes POINTER handling of large + values. -- Issue #19218: Rename collections.abc to _collections_abc in order to - speed up interpreter start. +- Issue #11694: Raise ConversionError in xdrlib as documented. Patch + by Filip GruszczyÅ„ski and Claudiu Popa. -- Issue #18582: Add 'pbkdf2_hmac' to the hashlib module. It implements PKCS#5 - password-based key derivation functions with HMAC as pseudorandom function. +- Issue #19380: Optimized parsing of regular expressions. -- Issue #19131: The aifc module now correctly reads and writes sampwidth of - compressed streams. +- Issue #1519638: Now unmatched groups are replaced with empty strings in re.sub() + and re.subn(). -- Issue #19209: Remove import of copyreg from the os module to speed up - interpreter startup. stat_result and statvfs_result are now hard-coded to - reside in the os module. +- Issue #18615: sndhdr.what/whathdr now return a namedtuple. -- Issue #19205: Don't import the 're' module in site and sysconfig module to - to speed up interpreter start. +- Issue #22462: Fix pyexpat's creation of a dummy frame to make it + appear in exception tracebacks. -- Issue #9548: Add a minimal "_bootlocale" module that is imported by the - _io module instead of the full locale module. +- Issue #21965: Add support for in-memory SSL to the ssl module. Patch + by Geert Jansen. -- Issue #18764: remove the 'print' alias for the PDB 'p' command so that it no - longer shadows the print function. +- Issue #21173: Fix len() on a WeakKeyDictionary when .clear() was called + with an iterator alive. -- Issue #19158: a rare race in BoundedSemaphore could allow .release() too - often. +- Issue #11866: Eliminated race condition in the computation of names + for new threads. -- Issue #15805: Add contextlib.redirect_stdout(). +- Issue #21905: Avoid RuntimeError in pickle.whichmodule() when sys.modules + is mutated while iterating. Patch by Olivier Grisel. -- Issue #18716: Deprecate the formatter module. +- Issue #11271: concurrent.futures.Executor.map() now takes a *chunksize* + argument to allow batching of tasks in child processes and improve + performance of ProcessPoolExecutor. Patch by Dan O'Reilly. -- Issue #10712: 2to3 has a new "asserts" fixer that replaces deprecated names - of unittest methods (e.g. failUnlessEqual -> assertEqual). +- Issue #21883: os.path.join() and os.path.relpath() now raise a TypeError with + more helpful error message for unsupported or mismatched types of arguments. -- Issue #18037: 2to3 now escapes '\u' and '\U' in native strings. +- Issue #22219: The zipfile module CLI now adds entries for directories + (including empty directories) in ZIP file. -- Issue #17839: base64.decodebytes and base64.encodebytes now accept any - object that exports a 1 dimensional array of bytes (this means the same - is now also true for base64_codec) +- Issue #22449: In the ssl.SSLContext.load_default_certs, consult the + enviromental variables SSL_CERT_DIR and SSL_CERT_FILE on Windows. -- Issue #19132: The pprint module now supports compact mode. +- Issue #22508: The email.__version__ variable has been removed; the email + code is no longer shipped separately from the stdlib, and __version__ + hasn't been updated in several releases. -- Issue #19137: The pprint module now correctly formats instances of set and - frozenset subclasses. +- Issue #20076: Added non derived UTF-8 aliases to locale aliases table. -- Issue #10042: functools.total_ordering now correctly handles - NotImplemented being returned by the underlying comparison function (Patch - by Katie Miller) +- Issue #20079: Added locales supported in glibc 2.18 to locale alias table. -- Issue #19092: contextlib.ExitStack now correctly reraises exceptions - from the __exit__ callbacks of inner context managers (Patch by Hrvoje - NikÅ¡ić) +- Issue #20218: Added convenience methods read_text/write_text and read_bytes/ + write_bytes to pathlib.Path objects. -- Issue #12641: Avoid passing "-mno-cygwin" to the mingw32 compiler, except - when necessary. Patch by Oscar Benjamin. +- Issue #22437: Number of capturing groups in regular expression is no longer + limited by 100. -- Issue #5845: In site.py, only load readline history from ~/.python_history - if no history has been read already. This avoids double writes to the - history file at shutdown. +- Issue #17442: InteractiveInterpreter now displays the full chained traceback + in its showtraceback method, to match the built in interactive interpreter. -- Properly initialize all fields of a SSL object after allocation. +- Issue #23392: Added tests for marshal C API that works with FILE*. -- Issue #19095: SSLSocket.getpeercert() now raises ValueError when the - SSL handshake hasn't been done. +- Issue #10510: distutils register and upload methods now use HTML standards + compliant CRLF line endings. -- Issue #4366: Fix building extensions on all platforms when --enable-shared - is used. +- Issue #9850: Fixed macpath.join() for empty first component. Patch by + Oleg Oshmyan. -- Issue #19030: Fixed `inspect.getmembers` and `inspect.classify_class_attrs` - to attempt activating descriptors before falling back to a __dict__ search - for faulty descriptors. `inspect.classify_class_attrs` no longer returns - Attributes whose home class is None. +- Issue #5309: distutils' build and build_ext commands now accept a ``-j`` + option to enable parallel building of extension modules. -C API ------ +- Issue #22448: Improve canceled timer handles cleanup to prevent + unbound memory usage. Patch by Joshua Moore-Oliva. -- Issue #1772673: The type of `char*` arguments now changed to `const char*`. +- Issue #22427: TemporaryDirectory no longer attempts to clean up twice when + used in the with statement in generator. -- Issue #16129: Added a `Py_SetStandardStreamEncoding` pre-initialization API - to allow embedding applications like Blender to force a particular - encoding and error handler for the standard IO streams (initial patch by - Bastien Montagne) +- Issue #22362: Forbidden ambiguous octal escapes out of range 0-0o377 in + regular expressions. -Tests ------ +- Issue #20912: Now directories added to ZIP file have correct Unix and MS-DOS + directory attributes. -- Issue #19275: Fix test_site on AMD64 Snow Leopard +- Issue #21866: ZipFile.close() no longer writes ZIP64 central directory + records if allowZip64 is false. -- Issue #14407: Fix unittest test discovery in test_concurrent_futures. +- Issue #22278: Fix urljoin problem with relative urls, a regression observed + after changes to issue22118 were submitted. -- Issue #18919: Unified and extended tests for audio modules: aifc, sunau and - wave. +- Issue #22415: Fixed debugging output of the GROUPREF_EXISTS opcode in the re + module. Removed trailing spaces in debugging output. -- Issue #18714: Added tests for ``pdb.find_function()``. +- Issue #22423: Unhandled exception in thread no longer causes unhandled + AttributeError when sys.stderr is None. -Documentation -------------- +- Issue #21332: Ensure that ``bufsize=1`` in subprocess.Popen() selects + line buffering, rather than block buffering. Patch by Akira Li. -- Issue #18758: Fixed and improved cross-references. +- Issue #21091: Fix API bug: email.message.EmailMessage.is_attachment is now + a method. -- Issue #18972: Modernize email examples and use the argparse module in them. +- Issue #21079: Fix email.message.EmailMessage.is_attachment to return the + correct result when the header has parameters as well as a value. -Build ------ +- Issue #22247: Add NNTPError to nntplib.__all__. -- Issue #19130: Correct PCbuild/readme.txt, Python 3.3 and 3.4 require VS 2010. +- 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 #15663: Update OS X 10.6+ installer to use Tcl/Tk 8.5.15. +- Issue #4180: The warnings registries are now reset when the filters + are modified. -- Issue #14499: Fix several problems with OS X universal build support: - 1. ppc arch detection for extension module builds broke with Xcode 5 - 2. ppc arch detection in configure did not work on OS X 10.4 - 3. -sysroot and -arch flags were unnecessarily duplicated - 4. there was no obvious way to configure an intel-32 only build. +- 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. -- Issue #19019: Change the OS X installer build script to use CFLAGS instead - of OPT for special build options. By setting OPT, some compiler-specific - options like -fwrapv were overridden and thus not used, which could result - in broken interpreters when building with clang. +- 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. -What's New in Python 3.4.0 Alpha 3? -=================================== +- Issue #20537: logging methods now accept an exception instance as well as a + Boolean value or exception tuple. Thanks to Yury Selivanov for the patch. -Release date: 2013-09-29 +- Issue #22384: An exception in Tkinter callback no longer crashes the program + when it is run with pythonw.exe. -Core and Builtins ------------------ +- Issue #22168: Prevent turtle AttributeError with non-default Canvas on OS X. -- Issue #18818: The "encodingname" part of PYTHONIOENCODING is now optional. +- 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 #19098: Prevent overflow in the compiler when the recursion limit is set - absurdly high. +- Issue #13968: The glob module now supports recursive search in + subdirectories using the "**" pattern. -Library -------- +- Issue #21951: Fixed a crash in Tkinter on AIX when called Tcl command with + empty string or tuple argument. -- Issue #18929: `inspect.classify_class_attrs()` now correctly finds class - attributes returned by `dir()` that are located in the metaclass. +- Issue #21951: Tkinter now most likely raises MemoryError instead of crash + if the memory allocation fails. -- Issue #18950: Fix miscellaneous bugs in the sunau module. - Au_read.readframes() now updates current file position and reads correct - number of frames from multichannel stream. Au_write.writeframesraw() now - correctly updates current file position. Au_read.getnframes() now returns an - integer (as in Python 2). Au_read and Au_write now correctly works with file - object if start file position is not a zero. +- Issue #22338: Fix a crash in the json module on memory allocation failure. -- Issue #18594: The fast path for collections.Counter() was never taken - due to an over-restrictive type check. +- Issue #12410: imaplib.IMAP4 now supports the context management protocol. + Original patch by Tarek Ziadé. -- Issue #19053: ZipExtFile.read1() with non-zero argument no more returns empty - bytes until end of data. +- Issue #21270: We now override tuple methods in mock.call objects so that + they can be used as normal call attributes. -- logging: added support for Unix domain sockets to SocketHandler and - DatagramHandler. +- Issue #16662: load_tests() is now unconditionally run when it is present in + a package's __init__.py. TestLoader.loadTestsFromModule() still accepts + use_load_tests, but it is deprecated and ignored. A new keyword-only + attribute `pattern` is added and documented. Patch given by Robert Collins, + tweaked by Barry Warsaw. -- Issue #18996: TestCase.assertEqual() now more cleverly shorten differing - strings in error report. +- Issue #22226: First letter no longer is stripped from the "status" key in + the result of Treeview.heading(). -- Issue #19034: repr() for tkinter.Tcl_Obj now exposes string reperesentation. +- Issue #19524: Fixed resource leak in the HTTP connection when an invalid + response is received. Patch by Martin Panter. -- Issue #18978: ``urllib.request.Request`` now allows the method to be - indicated on the class and no longer sets it to None in ``__init__``. +- Issue #20421: Add a .version() method to SSL sockets exposing the actual + protocol version in use. -- Issue #18626: the inspect module now offers a basic command line - introspection interface (Initial patch by Claudiu Popa) +- Issue #19546: configparser exceptions no longer expose implementation details. + Chained KeyErrors are removed, which leads to cleaner tracebacks. Patch by + Claudiu Popa. -- Issue #3015: Fixed tkinter with wantobject=False. Any Tcl command call - returned empty string. +- 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 #19037: The mailbox module now makes all changes to maildir files - before moving them into place, to avoid race conditions with other programs - that may be accessing the maildir directory. +- 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 #14984: On POSIX systems, when netrc is called without a filename - argument (and therefore is reading the user's $HOME/.netrc file), it now - enforces the same security rules as typical ftp clients: the .netrc file must - be owned by the user that owns the process and must not be readable by any - other user. +- 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 #18873: The tokenize module now detects Python source code encoding - only in comment lines. +- Issue #18132: Turtledemo buttons no longer disappear when the window is + shrunk. Original patches by Jan Kanis and Lita Cho. -- Issue #17764: Enable http.server to bind to a user specified network - interface. Patch contributed by Malte Swart. +- Issue #22043: time.monotonic() is now always available. + ``threading.Lock.acquire()``, ``threading.RLock.acquire()`` and socket + operations now use a monotonic clock, instead of the system clock, when a + timeout is used. -- Issue #18937: Add an assertLogs() context manager to unittest.TestCase - to ensure that a block of code emits a message using the logging module. +- Issue #21527: Add a default number of workers to ThreadPoolExecutor equal + to 5 times the number of CPUs. Patch by Claudiu Popa. -- Issue #17324: Fix http.server's request handling case on trailing '/'. Patch - contributed by Vajrasky Kok. +- 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 #19018: The heapq.merge() function no longer suppresses IndexError - in the underlying iterables. +- Issue #22098: ctypes' BigEndianStructure and LittleEndianStructure now + define an empty __slots__ so that subclasses don't always get an instance + dict. Patch by Claudiu Popa. -- Issue #18784: The uuid module no more attempts to load libc via ctypes.CDLL, - if all necessary functions are already found in libuuid. - Patch by Evgeny Sologubov. +- 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. -- The :envvar:`PYTHONFAULTHANDLER` environment variable now only enables the - faulthandler module if the variable is non-empty. Same behaviour than other - variables like :envvar:`PYTHONDONTWRITEBYTECODE`. +- Issue #22287: On UNIX, _PyTime_gettimeofday() now uses + clock_gettime(CLOCK_REALTIME) if available. As a side effect, Python now + depends on the librt library on Solaris and on Linux (only with glibc older + than 2.17). -- Issue #1565525: New function ``traceback.clear_frames`` will clear - the local variables of all the stack frames referenced by a traceback - object. +- Issue #22182: Use e.args to unpack exceptions correctly in + distutils.file_util.move_file. Patch by Claudiu Popa. -Tests ------ +- The webbrowser module now uses subprocess's start_new_session=True rather + than a potentially risky preexec_fn=os.setsid call. -- Issue #18952: Fix regression in support data downloads introduced when - test.support was converted to a package. Regression noticed by Zachary - Ware. +- Issue #22042: signal.set_wakeup_fd(fd) now raises an exception if the file + descriptor is in blocking mode. -IDLE ----- +- Issue #16808: inspect.stack() now returns a named tuple instead of a tuple. + Patch by Daniel Shahaf. -- Issue #18873: IDLE now detects Python source code encoding only in comment - lines. +- Issue #22236: Fixed Tkinter images copying operations in NoDefaultRoot mode. -- Issue #18988: The "Tab" key now works when a word is already autocompleted. +- Issue #2527: Add a *globals* argument to timeit functions, in order to + override the globals namespace in which the timed code is executed. + Patch by Ben Roberts. -Documentation -------------- +- Issue #22118: Switch urllib.parse to use RFC 3986 semantics for the + resolution of relative URLs, rather than RFCs 1808 and 2396. + Patch by Demian Brecht. -- Issue #17003: Unified the size argument names in the io module with common - practice. +- Issue #21549: Added the "members" parameter to TarFile.list(). -Build ------ +- Issue #19628: Allow compileall recursion depth to be specified with a -r + option. -- Issue #18596: Support the use of address sanity checking in recent versions - of clang and GCC by appropriately marking known false alarms in the small - object allocator. Patch contributed by Dhiru Kholia. +- Issue #15696: Add a __sizeof__ implementation for mmap objects on Windows. -Tools/Demos ------------ +- Issue #22068: Avoided reference loops with Variables and Fonts in Tkinter. -- Issue #18873: 2to3 and the findnocoding.py script now detect Python source - code encoding only in comment lines. +- Issue #22165: SimpleHTTPRequestHandler now supports undecodable file names. +- Issue #15381: Optimized line reading in io.BytesIO. -What's New in Python 3.4.0 Alpha 2? -=================================== +- Issue #8797: Raise HTTPError on failed Basic Authentication immediately. + Initial patch by Sam Bull. -Release date: 2013-09-09 +- Issue #20729: Restored the use of lazy iterkeys()/itervalues()/iteritems() + in the mailbox module. -Core and Builtins ------------------ +- Issue #21448: Changed FeedParser feed() to avoid O(N**2) behavior when + parsing long line. Original patch by Raymond Hettinger. -- Issue #18942: sys._debugmallocstats() output was damaged on Windows. +- Issue #22184: The functools LRU Cache decorator factory now gives an earlier + and clearer error message when the user forgets the required parameters. -- Issue #18780: %-formatting now prints value instead of str for - int subclasses when using %d, %i, and %u codes. +- Issue #17923: glob() patterns ending with a slash no longer match non-dirs on + AIX. Based on patch by Delhallt. -- Issue #18571: Implementation of the PEP 446: file descriptors and file - handles are now created non-inheritable; add functions - os.get/set_inheritable(), os.get/set_handle_inheritable() and - socket.socket.get/set_inheritable(). +- Issue #21725: Added support for RFC 6531 (SMTPUTF8) in smtpd. -- Issue #11619: The parser and the import machinery do not encode Unicode - filenames anymore on Windows. +- 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. -- Issue #18808: Non-daemon threads are now automatically joined when - a sub-interpreter is shutdown (it would previously dump a fatal error). +- Issue #5411: Added support for the "xztar" format in the shutil module. -- Remove supporting for compiling on systems without getcwd(). +- Issue #21121: Don't force 3rd party C extensions to be built with + -Werror=declaration-after-statement. -- Issue #18774: Remove last bits of GNU PTH thread code and thread_pth.h. +- 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 #18771: Add optimization to set object lookups to reduce the cost - of hash collisions. The core idea is to inspect a second key/hash pair - for each cache line retrieved. +- Issue #20170: Convert posixmodule to use Argument Clinic. -- Issue #16105: When a signal handler fails to write to the file descriptor - registered with ``signal.set_wakeup_fd()``, report an exception instead - of ignoring the error. +- Issue #21539: Add a *exists_ok* argument to `Pathlib.mkdir()` to mimic + `mkdir -p` and `os.makedirs()` functionality. When true, ignore + FileExistsErrors. Patch by Berker Peksag. -- Issue #18722: Remove uses of the "register" keyword in C code. +- Issue #22127: Bypass IDNA for pure-ASCII host names in the socket module + (in particular for numeric IPs). -- Issue #18667: Add missing "HAVE_FCHOWNAT" symbol to posix._have_functions. +- Issue #21047: set the default value for the *convert_charrefs* argument + of HTMLParser to True. Patch by Berker Peksag. -- Issue #16499: Add command line option for isolated mode. +- Add an __all__ to html.entities. -- Issue #15301: Parsing fd, uid, and gid parameters for builtins - in Modules/posixmodule.c is now far more robust. +- Issue #15114: the strict mode and argument of HTMLParser, HTMLParser.error, + and the HTMLParserError exception have been removed. -- Issue #18368: PyOS_StdioReadline() no longer leaks memory when realloc() - fail. +- Issue #22085: Dropped support of Tk 8.3 in Tkinter. -- Issue #17934: Add a clear() method to frame objects, to help clean up - expensive details (local variables) and break reference cycles. +- Issue #21580: Now Tkinter correctly handles bytes arguments passed to Tk. + In particular this allows to initialize images from binary data. -- Issue #18780: %-formatting codes %d, %i, and %u now treat int-subclasses - as int (displays value of int-subclass instead of str(int-subclass) ). +- Issue #22003: When initialized from a bytes object, io.BytesIO() now + defers making a copy until it is mutated, improving performance and + memory use on some use cases. Patch by David Wilson. -Library -------- +- Issue #22018: On Windows, signal.set_wakeup_fd() now also supports sockets. + A side effect is that Python depends to the WinSock library. -- Issue #18808: Thread.join() now waits for the underlying thread state to - be destroyed before returning. This prevents unpredictable aborts in - Py_EndInterpreter() when some non-daemon threads are still running. +- Issue #22054: Add os.get_blocking() and os.set_blocking() functions to get + and set the blocking mode of a file descriptor (False if the O_NONBLOCK flag + is set, True otherwise). These functions are not available on Windows. -- Issue #18458: Prevent crashes with newer versions of libedit. Its readline - emulation has changed from 0-based indexing to 1-based like gnu readline. +- Issue #17172: Make turtledemo start as active on OS X even when run with + subprocess. Patch by Lita Cho. -- Issue #18852: Handle case of ``readline.__doc__`` being ``None`` in the new - readline activation code in ``site.py``. +- Issue #21704: Fix build error for _multiprocessing when semaphores + are not available. Patch by Arfrever Frehtes Taifersar Arahesis. -- Issue #18672: Fixed format specifiers for Py_ssize_t in debugging output in - the _sre module. +- Issue #20173: Convert sha1, sha256, sha512 and md5 to ArgumentClinic. + Patch by Vajrasky Kok. -- Issue #18830: inspect.getclasstree() no more produces duplicated entries even - when input list contains duplicates. +- Fix repr(_socket.socket) on Windows 64-bit: don't fail with OverflowError + on closed socket. repr(socket.socket) already works fine. -- Issue #18878: sunau.open now supports the context manager protocol. Based on - patches by Claudiu Popa and R. David Murray. +- Issue #22033: Reprs of most Python implemened classes now contain actual + class name instead of hardcoded one. -- Issue #18909: Fix _tkinter.tkapp.interpaddr() on Windows 64-bit, don't cast - 64-bit pointer to long (32 bits). +- Issue #21947: The dis module can now disassemble generator-iterator + objects based on their gi_code attribute. Patch by Clement Rouault. -- Issue #18876: The FileIO.mode attribute now better reflects the actual mode - under which the file was opened. Patch by Erik Bray. +- Issue #16133: The asynchat.async_chat.handle_read() method now ignores + BlockingIOError exceptions. -- Issue #16853: Add new selectors module. +- Issue #22044: Fixed premature DECREF in call_tzinfo_method. + Patch by Tom Flanagan. -- Issue #18882: Add threading.main_thread() function. +- 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 #18901: The sunau getparams method now returns a namedtuple rather than - a plain tuple. Patch by Claudiu Popa. +- Issue #4350: Removed a number of out-of-dated and non-working for a long time + Tkinter methods. -- Issue #17487: The result of the wave getparams method now is pickleable again. - Patch by Claudiu Popa. +- Issue #6167: Scrollbar.activate() now returns the name of active element if + the argument is not specified. Scrollbar.set() now always accepts only 2 + arguments. -- Issue #18756: os.urandom() now uses a lazily-opened persistent file - descriptor, so as to avoid using many file descriptors when run in - parallel from multiple threads. +- Issue #15275: Clean up and speed up the ntpath module. -- Issue #18418: After fork(), reinit all threads states, not only active ones. - Patch by A. Jesse Jiryu Davis. +- Issue #21888: plistlib's load() and loads() now work if the fmt parameter is + specified. -- Issue #17974: Switch unittest from using getopt to using argparse. +- Issue #22032: __qualname__ instead of __name__ is now always used to format + fully qualified class names of Python implemented classes. -- Issue #11798: TestSuite now drops references to own tests after execution. +- Issue #22031: Reprs now always use hexadecimal format with the "0x" prefix + when contain an id in form " at 0x...". -- Issue #16611: http.cookie now correctly parses the 'secure' and 'httponly' - cookie flags. +- Issue #22018: signal.set_wakeup_fd() now raises an OSError instead of a + ValueError on ``fstat()`` failure. -- Issue #11973: Fix a problem in kevent. The flags and fflags fields are now - properly handled as unsigned. +- Issue #21044: tarfile.open() now handles fileobj with an integer 'name' + attribute. Based on patch by Antoine Pietri. -- Issue #18807: ``pyvenv`` now takes a --copies argument allowing copies - instead of symlinks even where symlinks are available and the default. +- Issue #21966: Respect -q command-line option when code module is ran. -- Issue #18538: ``python -m dis`` now uses argparse for argument processing. - Patch by Michele Orrù. +- Issue #19076: Don't pass the redundant 'file' argument to self.error(). -- Issue #18394: Close cgi.FieldStorage's optional file. +- Issue #16382: Improve exception message of warnings.warn() for bad + category. Initial patch by Phil Elson. -- Issue #17702: On error, os.environb now removes suppress the except context - when raising a new KeyError with the original key. +- Issue #21932: os.read() now uses a :c:func:`Py_ssize_t` type instead of + :c:type:`int` for the size to support reading more than 2 GB at once. On + Windows, the size is truncted to INT_MAX. As any call to os.read(), the OS + may read less bytes than the number of requested bytes. -- Issue #16809: Fixed some tkinter incompabilities with Tcl/Tk 8.6. +- Issue #21942: Fixed source file viewing in pydoc's server mode on Windows. -- Issue #16809: Tkinter's splitlist() and split() methods now accept Tcl_Obj - argument. +- Issue #11259: asynchat.async_chat().set_terminator() now raises a ValueError + if the number of received bytes is negative. -- Issue #18324: set_payload now correctly handles binary input. This also - supersedes the previous fixes for #14360, #1717, and #16564. +- Issue #12523: asynchat.async_chat.push() now raises a TypeError if it doesn't + get a bytes string -- Issue #18794: Add a fileno() method and a closed attribute to select.devpoll - objects. +- Issue #21707: Add missing kwonlyargcount argument to + ModuleFinder.replace_paths_in_code(). -- Issue #17119: Fixed integer overflows when processing large strings and tuples - in the tkinter module. +- Issue #20639: calling Path.with_suffix('') allows removing the suffix + again. Patch by July Tikhonov. -- 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. +- Issue #21714: Disallow the construction of invalid paths using + Path.with_name(). Original patch by Antony Lee. -- Issue #8865: Concurrent invocation of select.poll.poll() now raises a - RuntimeError exception. Patch by Christian Schubert. +- Issue #15014: Added 'auth' method to smtplib to make implementing auth + mechanisms simpler, and used it internally in the login method. -- Issue #18777: The ssl module now uses the new CRYPTO_THREADID API of - OpenSSL 1.0.0+ instead of the deprecated CRYPTO id callback function. +- 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 #18768: Correct doc string of RAND_edg(). Patch by Vajrasky Kok. +- 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 #18178: Fix ctypes on BSD. dlmalloc.c was compiled twice which broke - malloc weak symbols. +- Issue #5800: headers parameter of wsgiref.headers.Headers is now optional. + Initial patch by Pablo Torres Navarrete and SilentGhost. -- 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 represention of ASN.1 - strings for ``rfc822Name`` (email), ``dNSName`` (DNS) and - ``uniformResourceIdentifier`` (URI). +- Issue #21781: ssl.RAND_add() now supports strings longer than 2 GB. -- Issue #18701: Remove support of old CPython versions (<3.0) from C code. +- Issue #21679: Prevent extraneous fstat() calls during open(). Patch by + Bohuslav Kabrda. -- Issue #18756: Improve error reporting in os.urandom() when the failure - is due to something else than /dev/urandom not existing (for example, - exhausting the file descriptor limit). +- Issue #21863: cProfile now displays the module name of C extension functions, + in addition to their own name. -- Issue #18673: Add O_TMPFILE to os module. O_TMPFILE requires Linux kernel - 3.11 or newer. It's only defined on system with 3.11 uapi headers, too. +- 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 #18532: Change the builtin hash algorithms' names to lower case names - as promised by hashlib's documentation. +- Issue #21858: Better handling of Python exceptions in the sqlite3 module. -- Issue #18405: Improve the entropy of crypt.mksalt(). +- Issue #21476: Make sure the email.parser.BytesParser TextIOWrapper is + discarded after parsing, so the input file isn't unexpectedly closed. -- Issue #12015: The tempfile module now uses a suffix of 8 random characters - instead of 6, to reduce the risk of filename collision. The entropy was - reduced when uppercase letters were removed from the charset used to generate - random characters. +- Issue #20295: imghdr now recognizes OpenEXR format images. -- Issue #18585: Add :func:`textwrap.shorten` to collapse and truncate a - piece of text to a given length. +- Issue #21729: Used the "with" statement in the dbm.dumb module to ensure + files closing. Patch by Claudiu Popa. -- Issue #18598: Tweak exception message for importlib.import_module() to - include the module name when a key argument is missing. +- Issue #21491: socketserver: Fix a race condition in child processes reaping. -- Issue #19151: Fix docstring and use of _get_supported_file_loaders() to - reflect 2-tuples. +- Issue #21719: Added the ``st_file_attributes`` field to os.stat_result on + Windows. -- Issue #19152: Add ExtensionFileLoader.get_filename(). +- Issue #21832: Require named tuple inputs to be exact strings. -- Issue #18676: Change 'positive' to 'non-negative' in queue.py put and get - docstrings and ValueError messages. Patch by Zhongyue Luo +- Issue #21722: The distutils "upload" command now exits with a non-zero + return code when uploading fails. Patch by Martin Dengler. -- Fix refcounting issue with extension types in tkinter. +- Issue #21723: asyncio.Queue: support any type of number (ex: float) for the + maximum size. Patch written by Vajrasky Kok. -- Issue #8112: xlmrpc.server's DocXMLRPCServer server no longer raises an error - if methods have annotations; it now correctly displays the annotations. +- Issue #21711: support for "site-python" directories has now been removed + from the site module (it was deprecated in 3.4). -- Issue #18600: Added policy argument to email.message.Message.as_string, - and as_bytes and __bytes__ methods to Message. +- Issue #17552: new socket.sendfile() method allowing to send a file over a + socket by using high-performance os.sendfile() on UNIX. + Patch by Giampaolo Rodola'. -- Issue #18671: Output more information when logging exceptions occur. +- Issue #18039: dbm.dump.open() now always creates a new database when the + flag has the value 'n'. Patch by Claudiu Popa. -- Issue #18621: Prevent the site module's patched builtins from keeping - too many references alive for too long. +- 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 #4885: Add weakref support to mmap objects. Patch by Valerie Lambert. +- Issue #21766: Prevent a security hole in CGIHTTPServer by URL unquoting paths + before checking for a CGI script at that path. -- Issue #8860: Fixed rounding in timedelta constructor. +- Issue #21310: Fixed possible resource leak in failed open(). -- Issue #18849: Fixed a Windows-specific tempfile bug where collision with an - existing directory caused mkstemp and related APIs to fail instead of - retrying. Report and fix by Vlad Shcherbina. +- Issue #21256: Printout of keyword args should be in deterministic order in + a mock function call. This will help to write better doctests. -- Issue #18920: argparse's default destination for the version action (-v, - --version) has also been changed to stdout, to match the Python executable. +- Issue #21677: Fixed chaining nonnormalized exceptions in io close() methods. -Tests ------ +- Issue #11709: Fix the pydoc.help function to not fail when sys.stdin is not a + valid file. -- Issue #18623: Factor out the _SuppressCoreFiles context manager into - test.support. Patch by Valerie Lambert. +- Issue #21515: tempfile.TemporaryFile now uses os.O_TMPFILE flag is available. -- Issue #12037: Fix test_email for desktop Windows. +- Issue #13223: Fix pydoc.writedoc so that the HTML documentation for methods + that use 'self' in the example code is generated correctly. -- Issue #15507: test_subprocess's test_send_signal could fail if the test - runner were run in an environment where the process inherited an ignore - setting for SIGINT. Restore the SIGINT handler to the desired - KeyboardInterrupt raising one during that test. +- Issue #21463: In urllib.request, fix pruning of the FTP cache. -- Issue #16799: Switched from getopt to argparse style in regrtest's argument - parsing. Added more tests for regrtest's argument parsing. +- 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 #18792: Use "127.0.0.1" or "::1" instead of "localhost" as much as - possible, since "localhost" goes through a DNS lookup under recent Windows - versions. +- Issue #20383: Introduce importlib.util.module_from_spec() as the preferred way + to create a new module. -IDLE ----- +- Issue #21552: Fixed possible integer overflow of too long string lengths in + the tkinter module on 64-bit platforms. -- Issue #18489: Add tests for SearchEngine. Original patch by Phil Webster. +- 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. -Documentation -------------- +- Issue #13742: Added "key" and "reverse" parameters to heapq.merge(). + (First draft of patch contributed by Simon Sapin.) -- Issue #18743: Fix references to non-existant "StringIO" module. +- Issue #21402: tkinter.ttk now works when default root window is not set. -- Issue #18783: Removed existing mentions of Python long type in docstrings, - error messages and comments. +- Issue #3015: _tkinter.create() now creates tkapp object with wantobject=1 by + default. -Build ------ +- Issue #10203: sqlite3.Row now truly supports sequence protocol. In particulr + it supports reverse() and negative indices. Original patch by Claudiu Popa. -- Issue #1584: Provide configure options to override default search paths for - Tcl and Tk when building _tkinter. +- 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 #15663: Tcl/Tk 8.5.14 is now included with the OS X 10.6+ 64-/32-bit - installer. It is no longer necessary to install a third-party version of - Tcl/Tk 8.5 to work around the problems in the Apple-supplied Tcl/Tk 8.5 - shipped in OS X 10.6 and later releases. +- Issue #20197: Added support for the WebP image type in the imghdr module. + Patch by Fabrice Aneche and Claudiu Popa. -Tools/Demos ------------ +- Issue #21513: Speedup some properties of IP addresses (IPv4Address, + IPv6Address) such as .is_private or .is_multicast. -- Issue #18922: Now The Lib/smtpd.py and Tools/i18n/msgfmt.py scripts write - their version strings to stdout, and not to sderr. +- Issue #21137: Improve the repr for threading.Lock() and its variants + by showing the "locked" or "unlocked" status. Patch by Berker Peksag. -What's New in Python 3.4.0 Alpha 1? -=================================== +- Issue #21538: The plistlib module now supports loading of binary plist files + when reference or offset size is not a power of two. -Release date: 2013-08-03 +- Issue #21455: Add a default backlog to socket.listen(). -Core and Builtins ------------------ +- Issue #21525: Most Tkinter methods which accepted tuples now accept lists too. -- Issue #16741: Fix an error reporting in int(). +- 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 #17899: Fix rare file descriptor leak in os.listdir(). +- Issue #22236: Tkinter tests now don't reuse default root window. New root + window is created for every test class. -- Issue #10241: Clear extension module dict copies at interpreter shutdown. - Patch by Neil Schemenauer, minimally modified. +- Issue #10744: Fix PEP 3118 format strings on ctypes objects with a nontrivial + shape. -- Issue #9035: ismount now recognises volumes mounted below a drive root - on Windows. Original patch by Atsuo Ishimoto. +- Issue #20826: Optimize ipaddress.collapse_addresses(). -- Issue #18214: Improve finalization of Python modules to avoid setting - their globals to None, in most cases. +- Issue #21487: Optimize ipaddress.summarize_address_range() and + ipaddress.{IPv4Network,IPv6Network}.subnets(). -- Issue #18112: PEP 442 implementation (safe object finalization). +- Issue #21486: Optimize parsing of netmasks in ipaddress.IPv4Network and + ipaddress.IPv6Network. -- Issue #18552: Check return value of PyArena_AddPyObject() in - obj2ast_object(). +- Issue #13916: Disallowed the surrogatepass error handler for non UTF-* + encodings. -- Issue #18560: Fix potential NULL pointer dereference in sum(). +- Issue #20998: Fixed re.fullmatch() of repeated single character pattern + with ignore case. Original patch by Matthew Barnett. -- Issue #18520: Add a new PyStructSequence_InitType2() function, same than - PyStructSequence_InitType() except that it has a return value (0 on success, - -1 on error). +- Issue #21075: fileinput.FileInput now reads bytes from standard stream if + binary mode is specified. Patch by Sam Kimbrel. -- Issue #15905: Fix theoretical buffer overflow in handling of sys.argv[0], - prefix and exec_prefix if the operation system does not obey MAXPATHLEN. +- Issue #19775: Add a samefile() method to pathlib Path objects. Initial + patch by Vajrasky Kok. -- Issue #18408: Fix many various bugs in code handling errors, especially - on memory allocation failure (MemoryError). +- Issue #21226: Set up modules properly in PyImport_ExecCodeModuleObject + (and friends). -- Issue #18344: Fix potential ref-leaks in _bufferedreader_read_all(). +- Issue #21398: Fix an unicode error in the pydoc pager when the documentation + contains characters not encodable to the stdout encoding. -- Issue #18342: Use the repr of a module name when an import fails when using - ``from ... import ...``. +- Issue #16531: ipaddress.IPv4Network and ipaddress.IPv6Network now accept + an (address, netmask) tuple argument, so as to easily construct network + objects from existing addresses. -- Issue #17872: Fix a segfault in marshal.load() when input stream returns - more bytes than requested. +- Issue #21156: importlib.abc.InspectLoader.source_to_code() is now a + staticmethod. -- Issue #18338: `python --version` now prints version string to stdout, and - not to stderr. Patch by Berker Peksag and Michael Dickens. +- Issue #21424: Simplified and optimized heaqp.nlargest() and nmsmallest() + to make fewer tuple comparisons. -- Issue #18426: Fix NULL pointer dereference in C extension import when - PyModule_GetDef() returns an error. +- Issue #21396: Fix TextIOWrapper(..., write_through=True) to not force a + flush() on the underlying binary stream. Patch by akira. -- Issue #17206: On Windows, increase the stack size from 2 MB to 4.2 MB to fix - a stack overflow in the marshal module (fix a crash in test_marshal). - Patch written by Jeremy Kloth. +- Issue #18314: Unlink now removes junctions on Windows. Patch by Kim Gräsman -- Issue #3329: Implement the PEP 445: Add new APIs to customize Python memory - allocators. +- Issue #21088: Bugfix for curses.window.addch() regression in 3.4.0. + In porting to Argument Clinic, the first two arguments were reversed. -- Issue #18328: Reorder ops in PyThreadState_Delete*() functions. Now the - tstate is first removed from TLS and then deallocated. +- Issue #21407: _decimal: The module now supports function signatures. -- Issue #13483: Use VirtualAlloc in obmalloc on Windows. +- Issue #10650: Remove the non-standard 'watchexp' parameter from the + Decimal.quantize() method in the Python version. It had never been + present in the C version. -- Issue #18184: PyUnicode_FromFormat() and PyUnicode_FromFormatV() now raise - OverflowError when an argument of %c format is out of range. +- 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 #18111: The min() and max() functions now support a default argument - to be returned instead of raising a ValueError on an empty sequence. - (Contributed by Julian Berman.) +- Issue #19414: Have the OrderedDict mark deleted links as unusable. + This gives an early failure if the link is deleted during iteration. -- Issue #18137: Detect integer overflow on precision in float.__format__() - and complex.__format__(). +- Issue #21421: Add __slots__ to the MappingViews ABC. + Patch by Josh Rosenberg. -- Issue #18183: Fix various unicode operations on strings with large unicode - codepoints. +- Issue #21101: Eliminate double hashing in the C speed-up code for + collections.Counter(). -- Issue #18180: Fix ref leak in _PyImport_GetDynLoadWindows(). +- Issue #21321: itertools.islice() now releases the reference to the source + iterator when the slice is exhausted. Patch by Anton Afanasyev. -- Issue #18038: SyntaxError raised during compilation sources with illegal - encoding now always contains an encoding name. +- Issue #21057: TextIOWrapper now allows the underlying binary stream's + read() or read1() method to return an arbitrary bytes-like object + (such as a memoryview). Patch by Nikolaus Rath. -- Issue #17931: Resolve confusion on Windows between pids and process - handles. +- Issue #20951: SSLSocket.send() now raises either SSLWantReadError or + SSLWantWriteError on a non-blocking socket if the operation would block. + Previously, it would return 0. Patch by Nikolaus Rath. -- Tweak the exception message when the magic number or size value in a bytecode - file is truncated. +- Issue #13248: removed previously deprecated asyncore.dispatcher __getattr__ + cheap inheritance hack. -- Issue #17932: Fix an integer overflow issue on Windows 64-bit in iterators: - change the C type of seqiterobject.it_index from long to Py_ssize_t. +- Issue #9815: assertRaises now tries to clear references to local variables + in the exception's traceback. -- Issue #18065: Don't set __path__ to the package name for frozen packages. +- Issue #19940: ssl.cert_time_to_seconds() now interprets the given time + string in the UTC timezone (as specified in RFC 5280), not the local + timezone. -- Issue #18088: When reloading a module, unconditionally reset all relevant - attributes on the module (e.g. __name__, __loader__, __package__, __file__, - __cached__). +- Issue #13204: Calling sys.flags.__new__ would crash the interpreter, + now it raises a TypeError. -- Issue #17937: Try harder to collect cyclic garbage at shutdown. +- Issue #19385: Make operations on a closed dbm.dumb database always raise the + same exception. -- Issue #12370: Prevent class bodies from interfering with the __class__ - closure. +- Issue #21207: Detect when the os.urandom cached fd has been closed or + replaced, and open it anew. -- Issue #17644: Fix a crash in str.format when curly braces are used in square - brackets. +- 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 #17237: Fix crash in the ASCII decoder on m68k. +- Issue #21127: Path objects can now be instantiated from str subclass + instances (such as ``numpy.str_``). -- Issue #17927: Frame objects kept arguments alive if they had been - copied into a cell, even if the cell was cleared. +- 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 #1545463: At shutdown, defer finalization of codec modules so - that stderr remains usable. +- 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 #7330: Implement width and precision (ex: "%5.3s") for the format - string of PyUnicode_FromFormat() function, original patch written by Ysj Ray. +- Issue #21068: The ssl.PROTOCOL* constants are now enum members. -- Issue #1545463: Global variables caught in reference cycles are now - garbage-collected at shutdown. +- Issue #21276: posixmodule: Don't define USE_XATTRS on KFreeBSD and the Hurd. -- Issue #17094: Clear stale thread states after fork(). Note that this - is a potentially disruptive change since it may release some system - resources which would otherwise remain perpetually alive (e.g. database - connections kept in thread-local storage). +- Issue #21262: New method assert_not_called for Mock. + It raises AssertionError if the mock has been called. -- Issue #17408: Avoid using an obsolete instance of the copyreg module when - the interpreter is shutdown and then started again. +- Issue #21238: New keyword argument `unsafe` to Mock. It raises + `AttributeError` incase of an attribute startswith assert or assret. -- Issue #5845: Enable tab-completion in the interactive interpreter by - default, thanks to a new sys.__interactivehook__. +- Issue #20896: ssl.get_server_certificate() now uses PROTOCOL_SSLv23, not + PROTOCOL_SSLv3, for maximum compatibility. -- Issue #17115,17116: Module initialization now includes setting __package__ and - __loader__ attributes to None. +- Issue #21239: patch.stopall() didn't work deterministically when the same + name was patched more than once. -- Issue #17853: Ensure locals of a class that shadow free variables always win - over the closures. +- Issue #21203: Updated fileConfig and dictConfig to remove inconsistencies. + Thanks to Jure Koren for the patch. -- Issue #17863: In the interactive console, don't loop forever if the encoding - can't be fetched from stdin. +- Issue #21222: Passing name keyword argument to mock.create_autospec now + works. -- Issue #17867: Raise an ImportError if __import__ is not found in __builtins__. +- Issue #21197: Add lib64 -> lib symlink in venvs on 64-bit non-OS X POSIX. -- Issue #18698: Ensure importlib.reload() returns the module out of sys.modules. +- 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 #17857: Prevent build failures with pre-3.5.0 versions of sqlite3, - such as was shipped with Centos 5 and Mac OS X 10.4. +- Issue #17826: setting an iterable side_effect on a mock function created by + create_autospec now works. Patch by Kushal Das. -- Issue #17413: sys.settrace callbacks were being passed a string instead of an - exception instance for the 'value' element of the arg tuple if the exception - originated from C code; now an exception instance is always provided. +- Issue #7776: Fix ``Host:`` header and reconnection when using + http.client.HTTPConnection.set_tunnel(). Patch by Nikolaus Rath. -- Issue #17782: Fix undefined behaviour on platforms where - ``struct timespec``'s "tv_nsec" member is not a C long. +- Issue #20968: unittest.mock.MagicMock now supports division. + Patch by Johannes Baiter. -- Issue #17722: When looking up __round__, resolve descriptors. +- Fix arbitrary memory access in JSONDecoder.raw_decode with a negative second + parameter. Bug reported by Guido Vranken. -- Issue #16061: Speed up str.replace() for replacing 1-character strings. +- Issue #21169: getpass now handles non-ascii characters that the + input stream encoding cannot encode by re-encoding using the + replace error handler. -- Issue #17715: Fix segmentation fault from raising an exception in a __trunc__ - method. +- Issue #21171: Fixed undocumented filter API of the rot13 codec. + Patch by Berker Peksag. -- Issue #17643: Add __callback__ attribute to weakref.ref. +- Issue #20539: Improved math.factorial error message for large positive inputs + and changed exception type (OverflowError -> ValueError) for large negative + inputs. -- Issue #16447: Fixed potential segmentation fault when setting __name__ on a - class. +- Issue #21172: isinstance check relaxed from dict to collections.Mapping. -- Issue #17669: Fix crash involving finalization of generators using yield from. +- Issue #21155: asyncio.EventLoop.create_unix_server() now raises a ValueError + if path and sock are specified at the same time. -- Issue #14439: Python now prints the traceback on runpy failure at startup. +- Issue #21136: Avoid unnecessary normalization of Fractions resulting from + power and other operations. Patch by Raymond Hettinger. -- Issue #17469: Fix _Py_GetAllocatedBlocks() and sys.getallocatedblocks() - when running on valgrind. +- Issue #17621: Introduce importlib.util.LazyLoader. -- Issue #17619: Make input() check for Ctrl-C correctly on Windows. +- Issue #21076: signal module constants were turned into enums. + Patch by Giampaolo Rodola'. -- Issue #17357: Add missing verbosity messages for -v/-vv that were lost during - the importlib transition. +- Issue #20636: Improved the repr of Tkinter widgets. -- Issue #17610: Don't rely on non-standard behavior of the C qsort() function. +- Issue #19505: The items, keys, and values views of OrderedDict now support + reverse iteration using reversed(). -- Issue #17323: The "[X refs, Y blocks]" printed by debug builds has been - disabled by default. It can be re-enabled with the `-X showrefcount` option. +- Issue #21149: Improved thread-safety in logging cleanup during interpreter + shutdown. Thanks to Devin Jeanpierre for the patch. -- Issue #17328: Fix possible refleak in dict.setdefault. +- Issue #21058: Fix a leak of file descriptor in + :func:`tempfile.NamedTemporaryFile`, close the file descriptor if + :func:`io.open` fails -- Issue #17275: Corrected class name in init error messages of the C version of - BufferedWriter and BufferedRandom. +- Issue #21200: Return None from pkgutil.get_loader() when __spec__ is missing. -- Issue #7963: Fixed misleading error message that issued when object is - called without arguments. +- Issue #21013: Enhance ssl.create_default_context() when used for server side + sockets to provide better security by default. -- Issue #8745: Small speed up zipimport on Windows. Patch by Catalin Iacob. +- Issue #20145: `assertRaisesRegex` and `assertWarnsRegex` now raise a + TypeError if the second argument is not a string or compiled regex. -- Issue #5308: Raise ValueError when marshalling too large object (a sequence - with size >= 2**31), instead of producing illegal marshal data. +- Issue #20633: Replace relative import by absolute import. -- Issue #12983: Bytes literals with invalid \x escape now raise a SyntaxError - and a full traceback including line number. +- Issue #20980: Stop wrapping exception when using ThreadPool. -- Issue #16967: In function definition, evaluate positional defaults before - keyword-only defaults. +- Issue #21082: In os.makedirs, do not set the process-wide umask. Note this + changes behavior of makedirs when exist_ok=True. -- Issue #17173: Remove uses of locale-dependent C functions (isalpha() etc.) - in the interpreter. +- Issue #20990: Fix issues found by pyflakes for multiprocessing. -- Issue #17137: When an Unicode string is resized, the internal wide character - string (wstr) format is now cleared. +- 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 #17043: The unicode-internal decoder no longer read past the end of - input buffer. +- Issue #21000: Improve the command-line interface of json.tool. -- Issue #17098: All modules now have __loader__ set even if they pre-exist the - bootstrapping of importlib. +- Issue #20995: Enhance default ciphers used by the ssl module to enable + better security an prioritize perfect forward secrecy. -- Issue #16979: Fix error handling bugs in the unicode-escape-decode decoder. +- Issue #20884: Don't assume that __file__ is defined on importlib.__init__. -- Issue #16772: The base argument to the int constructor no longer accepts - floats, or other non-integer objects with an __int__ method. Objects - with an __index__ method are now accepted. +- Issue #21499: Ignore __builtins__ in several test_importlib.test_api tests. -- Issue #10156: In the interpreter's initialization phase, unicode globals - are now initialized dynamically as needed. +- Issue #20627: xmlrpc.client.ServerProxy is now a context manager. -- Issue #16980: Fix processing of escaped non-ascii bytes in the - unicode-escape-decode decoder. +- Issue #19165: The formatter module now raises DeprecationWarning instead of + PendingDeprecationWarning. -- Issue #16975: Fix error handling bug in the escape-decode bytes decoder. +- Issue #13936: Remove the ability of datetime.time instances to be considered + false in boolean contexts. -- Issue #14850: Now a charmap decoder treats U+FFFE as "undefined mapping" - in any mapping, not only in a string. +- Issue 18931: selectors module now supports /dev/poll on Solaris. + Patch by Giampaolo Rodola'. -- Issue #16730: importlib.machinery.FileFinder now no longers raises an - exception when trying to populate its cache and it finds out the directory is - unreadable or has turned into a file. Reported and diagnosed by - David Pritchard. +- Issue #19977: When the ``LC_TYPE`` locale is the POSIX locale (``C`` locale), + :py:data:`sys.stdin` and :py:data:`sys.stdout` are now using the + ``surrogateescape`` error handler, instead of the ``strict`` error handler. -- Issue #16906: Fix a logic error that prevented most static strings from being - cleared. +- Issue #20574: Implement incremental decoder for cp65001 code (Windows code + page 65001, Microsoft UTF-8). -- Issue #11461: Fix the incremental UTF-16 decoder. Original patch by - Amaury Forgeot d'Arc. +- 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 #16856: Fix a segmentation fault from calling repr() on a dict with - a key whose repr raise an exception. +- Issue #19157: Include the broadcast address in the usuable hosts for IPv6 + in ipaddress. -- Issue #16367: Fix FileIO.readall() on Windows for files larger than 2 GB. +- 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 #16761: Calling int() with base argument only now raises TypeError. +- Issue #4931: distutils should not produce unhelpful "error: None" messages + anymore. distutils.util.grok_environment_error is kept but doc-deprecated. -- Issue #16759: Support the full DWORD (unsigned long) range in Reg2Py - when retrieving a REG_DWORD value. This corrects functions like - winreg.QueryValueEx that may have been returning truncated values. +- Issue #20875: Prevent possible gzip "'read' is not defined" NameError. + Patch by Claudiu Popa. -- Issue #14420: Support the full DWORD (unsigned long) range in Py2Reg - when passed a REG_DWORD value. Fixes OverflowError in winreg.SetValueEx. +- 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 #11939: Set the st_dev attribute of stat_result to allow Windows to - take advantage of the os.path.samefile/sameopenfile/samestat implementations - used by other platforms. +- 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 #16772: The int() constructor's second argument (base) no longer - accepts non integer values. Consistent with the behavior in Python 2. +- Issue #20778: Fix modulefinder to work with bytecode-only modules. -- Issue #14470: Remove w9xpopen support per PEP 11. +- Issue #20791: copy.copy() now doesn't make a copy when the input is + a bytes object. Initial patch by Peter Otten. -- Issue #9856: Replace deprecation warning with raising TypeError - in object.__format__. Patch by Florent Xicluna. +- Issue #19748: On AIX, time.mktime() now raises an OverflowError for year + outsize range [1902; 2037]. -- Issue #16597: In buffered and text IO, call close() on the underlying stream - if invoking flush() fails. +- Issue #19573: inspect.signature: Use enum for parameter kind constants. -- Issue #16722: In the bytes() constructor, try to call __bytes__ on the - argument before __index__. +- Issue #20726: inspect.signature: Make Signature and Parameter picklable. -- Issue #16421: loading multiple modules from one shared object is now - handled correctly (previously, the first module loaded from that file - was silently returned). Patch by Václav Å milauer. +- Issue #17373: Add inspect.Signature.from_callable method. -- Issue #16602: When a weakref's target was part of a long deallocation - chain, the object could remain reachable through its weakref even though - its refcount had dropped to zero. +- Issue #20378: Improve repr of inspect.Signature and inspect.Parameter. -- Issue #16495: Remove extraneous NULL encoding check from bytes_decode(). +- Issue #20816: Fix inspect.getcallargs() to raise correct TypeError for + missing keyword-only arguments. Patch by Jeremiah Lowin. -- Issue #16619: Create NameConstant AST class to represent None, True, and False - literals. As a result, these constants are never loaded at runtime from - builtins. +- Issue #20817: Fix inspect.getcallargs() to fail correctly if more + than 3 arguments are missing. Patch by Jeremiah Lowin. -- Issue #16455: On FreeBSD and Solaris, if the locale is C, the - ASCII/surrogateescape codec is now used, instead of the locale encoding, to - decode the command line arguments. This change fixes inconsistencies with - os.fsencode() and os.fsdecode() because these operating systems announces an - ASCII locale encoding, whereas the ISO-8859-1 encoding is used in practice. +- 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 #16562: Optimize dict equality testing. Patch by Serhiy Storchaka. +- 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 #16588: Silence unused-but-set warnings in Python/thread_pthread +- Issue #20334: inspect.Signature and inspect.Parameter are now hashable. + Thanks to Antony Lee for bug reports and suggestions. -- Issue #16592: stringlib_bytes_join doesn't raise MemoryError on allocation - failure. +- Issue #15916: doctest.DocTestSuite returns an empty unittest.TestSuite instead + of raising ValueError if it finds no tests -- Issue #16546: Fix: ast.YieldFrom argument is now mandatory. +- Issue #21209: Fix asyncio.tasks.CoroWrapper to workaround a bug + in yield-from implementation in CPythons prior to 3.4.1. -- Issue #16514: Fix regression causing a traceback when sys.path[0] is None - (actually, any non-string or non-bytes type). +- asyncio: Add gi_{frame,running,code} properties to CoroWrapper + (upstream issue #163). -- Issue #16306: Fix multiple error messages when unknown command line - parameters where passed to the interpreter. Patch by Hieu Nguyen. +- Issue #21311: Avoid exception in _osx_support with non-standard compiler + configurations. Patch by John Szakmeister. -- Issue #16215: Fix potential double memory free in str.replace(). Patch - by Serhiy Storchaka. +- Issue #11571: Ensure that the turtle window becomes the topmost window + when launched on OS X. -- Issue #16290: A float return value from the __complex__ special method is no - longer accepted in the complex() constructor. +- Issue #21801: Validate that __signature__ is None or an instance of Signature. -- Issue #16416: On Mac OS X, operating system data are now always - encoded/decoded to/from UTF-8/surrogateescape, instead of the locale encoding - (which may be ASCII if no locale environment variable is set), to avoid - inconsistencies with os.fsencode() and os.fsdecode() functions which are - already using UTF-8/surrogateescape. +- Issue #21923: Prevent AttributeError in distutils.sysconfig.customize_compiler + due to possible uninitialized _config_vars. -- Issue #16453: Fix equality testing of dead weakref objects. +- Issue #21323: Fix http.server to again handle scripts in CGI subdirectories, + broken by the fix for security issue #19435. Patch by Zach Byrne. -- Issue #9535: Fix pending signals that have been received but not yet - handled by Python to not persist after os.fork() in the child process. +- Issue #22733: Fix ffi_prep_args not zero-extending argument values correctly + on 64-bit Windows. -- Issue #14794: Fix slice.indices to return correct results for huge values, - rather than raising OverflowError. +- Issue #23302: Default to TCP_NODELAY=1 upon establishing an HTTPConnection. + Removed use of hard-coded MSS as it's an optimization that's no longer needed + with Nagle disabled. -- Issue #15001: fix segfault on "del sys.modules['__main__']". Patch by Victor - Stinner. +IDLE +---- -- Issue #8271: the utf-8 decoder now outputs the correct number of U+FFFD - characters when used with the 'replace' error handler on invalid utf-8 - sequences. Patch by Serhiy Storchaka, tests by Ezio Melotti. +- 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 #5765: Apply a hard recursion limit in the compiler instead of - blowing the stack and segfaulting. Initial patch by Andrea Griffini. +- Issue #16893: Update Idle doc chapter to match current Idle and add new + information. -- Issue #16402: When slicing a range, fix shadowing of exceptions from - __index__. +- 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 #16336: fix input checking in the surrogatepass error handler. - Patch by Serhiy Storchaka. +- Issue #16233: A module browser (File : Class Browser, Alt+C) requires a + 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 #8401: assigning an int to a bytearray slice (e.g. b[3:4] = 5) now - raises an error. +- 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 #7317: Display full tracebacks when an error occurs asynchronously. - Patch by Alon Horev with update by Alexey Kachayev. +- 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 #16309: Make PYTHONPATH="" behavior the same as if PYTHONPATH - not set at all. +- Issue #17390: Adjust Editor window title; remove 'Python', + move version to end. -- Issue #10189: Improve the error reporting of SyntaxErrors related to global - and nonlocal statements. +- Issue #14105: Idle debugger breakpoints no longer disappear + when inseting or deleting lines. -- Fix segfaults on setting __qualname__ on builtin types and attempting to - delete it on any type. +- 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 #14625: Rewrite the UTF-32 decoder. It is now 3x to 4x faster. Patch - written by Serhiy Storchaka. +- Issue #21765: Add support for non-ascii identifiers to HyperParser. -- Issue #16345: Fix an infinite loop when ``fromkeys`` on a dict subclass - received a nonempty dict from the constructor. +- Issue #21940: Add unittest for WidgetRedirector. Initial patch by Saimadhav + Heblikar. -- Issue #16271: Fix strange bugs that resulted from __qualname__ appearing in a - class's __dict__ and on type. +- Issue #18592: Add unittest for SearchDialogBase. Patch by Phil Webster. -- Issue #12805: Make bytes.join and bytearray.join faster when the separator - is empty. Patch by Serhiy Storchaka. +- Issue #21694: Add unittest for ParenMatch. Patch by Saimadhav Heblikar. -- Issue #6074: Ensure cached bytecode files can always be updated by the - user that created them, even when the source file is read-only. +- Issue #21686: add unittest for HyperParser. Original patch by Saimadhav + Heblikar. -- Issue #15958: bytes.join and bytearray.join now accept arbitrary buffer - objects. +- 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 #14783: Improve int() docstring and switch docstrings for str(), - range(), and slice() to use multi-line signatures. +- Issue #21695: Closing a Find-in-files output window while the search is + still in progress no longer closes Idle. -- Issue #16160: Subclass support now works for types.SimpleNamespace. +- Issue #18910: Add unittest for textView. Patch by Phil Webster. -- Upgrade Unicode data (UCD) to version 6.2. +- Issue #18292: Add unittest for AutoExpand. Patch by Saihadhav Heblikar. -- Issue #15379: Fix passing of non-BMP characters as integers for the charmap - decoder (already working as unicode strings). Patch by Serhiy Storchaka. +- Issue #18409: Add unittest for AutoComplete. Patch by Phil Webster. -- Issue #15144: Fix possible integer overflow when handling pointers as integer - values, by using `Py_uintptr_t` instead of `size_t`. Patch by Serhiy - Storchaka. +- Issue #21477: htest.py - Improve framework, complete set of tests. + Patches by Saimadhav Heblikar -- Issue #15965: Explicitly cast `AT_FDCWD` as (int). Required on Solaris 10 - (which defines `AT_FDCWD` as ``0xffd19553``), harmless on other platforms. +- 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. -- Issue #15839: Convert SystemErrors in `super()` to RuntimeErrors. +- Issue #21139: Change default paragraph width to 72, the PEP 8 recommendation. -- Issue #15448: Buffered IO now frees the buffer when closed, instead - of when deallocating. +- Issue #21284: Paragraph reformat test passes after user changes reformat width. -- Issue #15846: Fix SystemError which happened when using `ast.parse()` in an - exception handler on code with syntax errors. +- Issue #17654: Ensure IDLE menus are customized properly on OS X for + non-framework builds and for all variants of Tk. -- Issue #15897: zipimport.c doesn't check return value of fseek(). - Patch by Felipe Cruz. +- Issue #23180: Rename IDLE "Windows" menu item to "Window". + Patch by Al Sweigart. -- Issue #15801: Make sure mappings passed to '%' formatting are actually - subscriptable. +Build +----- -- Issue #15111: __import__ should propagate ImportError when raised as a - side-effect of a module triggered from using fromlist. +- Issue #15506: Use standard PKG_PROG_PKG_CONFIG autoconf macro in the configure + script. -- Issue #15022: Add pickle and comparison support to types.SimpleNamespace. +- Issue #22935: Allow the ssl module to be compiled if openssl doesn't support + SSL 3. -Library -------- +- Issue #22592: Drop support of the Borland C compiler to build Python. The + distutils module still supports it to build extensions. -- Issue #4331: Added functools.partialmethod (Initial patch by Alon Horev) +- Issue #22591: Drop support of MS-DOS, especially of the DJGPP compiler + (MS-DOS port of GCC). -- Issue #13461: Fix a crash in the TextIOWrapper.tell method on 64-bit - platforms. Patch by Yogesh Chaudhari. +- Issue #16537: Check whether self.extensions is empty in setup.py. Patch by + Jonathan Hosmer. -- Issue #18681: Fix a NameError in importlib.reload() (noticed by Weizhao Li). +- Issue #22359: Remove incorrect uses of recursive make. Patch by Jonas + Wagner. -- Issue #14323: Expanded the number of digits in the coefficients for the - RGB -- YIQ conversions so that they match the FCC NTSC versions. +- Issue #21958: Define HAVE_ROUND when building with Visual Studio 2013 and + above. Patch by Zachary Turner. -- Issue #17998: Fix an internal error in regular expression engine. +- Issue #18093: the programs that embed the CPython runtime are now in a + separate "Programs" directory, rather than being kept in the Modules + directory. -- Issue #17557: Fix os.getgroups() to work with the modified behavior of - getgroups(2) on OS X 10.8. Original patch by Mateusz Lenik. +- Issue #15759: "make suspicious", "make linkcheck" and "make doctest" in Doc/ + now display special message when and only when there are failures. -- Issue #18608: Avoid keeping a strong reference to the locale module - inside the _io module. +- Issue #21141: The Windows build process no longer attempts to find Perl, + instead relying on OpenSSL source being configured and ready to build. The + ``PCbuild\build_ssl.py`` script has been re-written and re-named to + ``PCbuild\prepare_ssl.py``, and takes care of configuring OpenSSL source + for both 32 and 64 bit platforms. OpenSSL sources obtained from + svn.python.org will always be pre-configured and ready to build. -- Issue #18619: Fix atexit leaking callbacks registered from sub-interpreters, - and make it GC-aware. +- Issue #21037: Add a build option to enable AddressSanitizer support. -- Issue #15699: The readline module now uses PEP 3121-style module - initialization, so as to reclaim allocated resources (Python callbacks) - at shutdown. Original patch by Robin Schreiber. +- Issue #19962: The Windows build process now creates "python.bat" in the + root of the source tree, which passes all arguments through to the most + recently built interpreter. -- Issue #17616: wave.open now supports the context manager protocol. +- Issue #21285: Refactor and fix curses configure check to always search + in a ncursesw directory. -- Issue #18599: Fix name attribute of _sha1.sha1() object. It now returns - 'SHA1' instead of 'SHA'. +- 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 #13266: Added inspect.unwrap to easily unravel __wrapped__ chains - (initial patch by Daniel Urban and Aaron Iles) +- Issue #17861: Tools/scripts/generate_opcode_h.py automatically regenerates + Include/opcode.h from Lib/opcode.py if the later gets any change. -- Issue #18561: Skip name in ctypes' _build_callargs() if name is NULL. +- 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. -- Issue #18559: Fix NULL pointer dereference error in _pickle module +- Issue #20022: Eliminate use of deprecated bundlebuilder in OS X builds. -- Issue #18556: Check the return type of PyUnicode_AsWideChar() in ctype's - U_set(). +- Issue #15968: Incorporated Tcl, Tk, and Tix builds into the Windows build + solution. -- Issue #17818: aifc.getparams now returns a namedtuple. +- Issue #17095: Fix Modules/Setup *shared* support. -- Issue #18549: Eliminate dead code in socket_ntohl() +- Issue #21811: Anticipated fixes to support OS X versions > 10.9. -- Issue #18530: Remove additional stat call from posixpath.ismount. - Patch by Alex Gaynor. +- Issue #21166: Prevent possible segfaults and other random failures of + python --generate-posix-vars in pybuilddir.txt build target. -- Issue #18514: Fix unreachable Py_DECREF() call in PyCData_FromBaseObj() +- Issue #18096: Fix library order returned by python-config. -- Issue #9177: Calling read() or write() now raises ValueError, not - AttributeError, on a closed SSL socket. Patch by Senko Rasic. +- Issue #17219: Add library build dir for Python extension cross-builds. -- Issue #18513: Fix behaviour of cmath.rect w.r.t. signed zeros on OS X 10.8 + - gcc. +- Issue #22919: Windows build updated to support VC 14.0 (Visual Studio 2015), + which will be used for the official release. -- Issue #18479: Changed venv Activate.ps1 to make deactivate a function, and - removed Deactivate.ps1. +- Issue #21236: Build _msi.pyd with cabinet.lib instead of fci.lib -- Issue #18480: Add missing call to PyType_Ready to the _elementtree extension. +- Issue #17128: Use private version of OpenSSL for OS X 10.5+ installer. -- Issue #17778: Fix test discovery for test_multiprocessing. (Patch by - Zachary Ware.) +C API +----- -- Issue #18393: The private module _gestalt and private functions - platform._mac_ver_gestalt, platform._mac_ver_lookup and - platform._bcd2str have been removed. This does not affect the public - interface of the platform module. +- Issue #14203: Remove obsolete support for view==NULL in PyBuffer_FillInfo(), + bytearray_getbuffer(), bytesiobuf_getbuffer() and array_buffer_getbuf(). + All functions now raise BufferError in that case. -- Issue #17482: functools.update_wrapper (and functools.wraps) now set the - __wrapped__ attribute correctly even if the underlying function has a - __wrapped__ attribute set. +- Issue #22445: PyBuffer_IsContiguous() now implements precise contiguity + tests, compatible with NumPy's NPY_RELAXED_STRIDES_CHECKING compilation + flag. Previously the function reported false negatives for corner cases. -- Issue #18431: The new email header parser now decodes RFC2047 encoded words - in structured headers. +- Issue #22079: PyType_Ready() now checks that statically allocated type has + no dynamically allocated bases. -- Issue #18432: The sched module's queue method was incorrectly returning - an iterator instead of a list. +- Issue #22453: Removed non-documented macro PyObject_REPR(). -- Issue #18044: The new email header parser was mis-parsing encoded words where - an encoded character immediately followed the '?' that follows the CTE - character, resulting in a decoding failure. They are now decoded correctly. +- Issue #18395: Rename ``_Py_char2wchar()`` to :c:func:`Py_DecodeLocale`, + rename ``_Py_wchar2char()`` to :c:func:`Py_EncodeLocale`, and document + these functions. -- Issue #18101: Tcl.split() now process strings nested in a tuple as it - do with byte strings. +- Issue #21233: Add new C functions: PyMem_RawCalloc(), PyMem_Calloc(), + PyObject_Calloc(), _PyObject_GC_Calloc(). bytes(int) is now using + ``calloc()`` instead of ``malloc()`` for large objects which is faster and + use less memory. -- Issue #18116: getpass was always getting an error when testing /dev/tty, - and thus was always falling back to stdin. It also leaked an open file - when it did so. Both of these issues are now fixed. +- 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(). -- Issue #17198: Fix a NameError in the dbm module. Patch by Valentina - Mukhamedzhanova. +Documentation +------------- -- Issue #18013: Fix cgi.FieldStorage to parse the W3C sample form. +- 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 #18020: improve html.escape speed by an order of magnitude. - Patch by Matt Bryant. +- Issue #22394: Doc/Makefile now supports ``make venv PYTHON=../python`` to + create a venv for generating the documentation, e.g., + ``make html PYTHON=venv/bin/python3``. -- Issue #18347: ElementTree's html serializer now preserves the case of - closing tags. +- Issue #21514: The documentation of the json module now refers to new JSON RFC + 7159 instead of obsoleted RFC 4627. -- Issue #17261: Ensure multiprocessing's proxies use proper address. +- 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. -- Issue #18343: faulthandler.register() now keeps the previous signal handler - when the function is called twice, so faulthandler.unregister() restores - correctly the original signal handler. +- Issue #6916: undocument deprecated asynchat.fifo class. -- Issue #17097: Make multiprocessing ignore EINTR. +- Issue #17386: Expanded functionality of the ``Doc/make.bat`` script to make + it much more comparable to ``Doc/Makefile``. -- Issue #18339: Negative ints keys in unpickler.memo dict no longer cause a - segfault inside the _pickle C extension. +- Issue #21312: Update the thread_foobar.h template file to include newer + threading APIs. Patch by Jack McCracken. -- Issue 18240: The HMAC module is no longer restricted to bytes and accepts - any bytes-like object, e.g. memoryview. Original patch by Jonas Borgström. +- Issue #21043: Remove the recommendation for specific CA organizations and to + mention the ability to load the OS certificates. -- Issue #18224: Removed pydoc script from created venv, as it causes problems - on Windows and adds no value over and above python -m pydoc ... +- Issue #20765: Add missing documentation for PurePath.with_name() and + PurePath.with_suffix(). -- Issue #18155: The csv module now correctly handles csv files that use - a delimter character that has a special meaning in regexes, instead of - throwing an exception. +- 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 #14360: encode_quopri can now be successfully used as an encoder - when constructing a MIMEApplication object. +- Issue #19697: Document cases where __main__.__spec__ is None. -- Issue #11390: Add -o and -f command line options to the doctest CLI to - specify doctest options (and convert it to using argparse). +Tests +----- -- Issue #18135: ssl.SSLSocket.write() now raises an OverflowError if the input - string in longer than 2 gigabytes, and ssl.SSLContext.load_cert_chain() - raises a ValueError if the password is longer than 2 gigabytes. The ssl - module does not support partial write. +- Issue #18982: Add tests for CLI of the calendar module. -- Issue #11016: Add C implementation of the stat module as _stat. +- Issue #19548: Added some additional checks to test_codecs to ensure that + statements in the updated documentation remain accurate. Patch by Martin + Panter. -- Issue #18248: Fix libffi build on AIX. +- Issue #22838: All test_re tests now work with unittest test discovery. -- Issue #18259: Declare sethostname in socketmodule.c for AIX +- Issue #22173: Update lib2to3 tests to use unittest test discovery. -- Issue #18147: Add diagnostic functions to ssl.SSLContext(). get_ca_list() - lists all loaded CA certificates and cert_store_stats() returns amount of - loaded X.509 certs, X.509 CA certs and CRLs. +- Issue #16000: Convert test_curses to use unittest. -- Issue #18167: cgi.FieldStorage no longer fails to handle multipart/form-data - when \r\n appears at end of 65535 bytes without other newlines. +- Issue #21456: Skip two tests in test_urllib2net.py if _ssl module not + present. Patch by Remi Pointel. -- Issue #18076: Introduce importlib.util.decode_source(). -- Issue #18357: add tests for dictview set difference. - Patch by Fraser Tweedale. +- Issue #20746: Fix test_pdb to run in refleak mode (-R). Patch by Xavier + de Gaye. -- importlib.abc.SourceLoader.get_source() no longer changes SyntaxError or - UnicodeDecodeError into ImportError. +- Issue #22060: test_ctypes has been somewhat cleaned up and simplified; it + now uses unittest test discovery to find its tests. -- Issue #18058, 18057: Make the namespace package loader meet the - importlib.abc.InspectLoader ABC, allowing for namespace packages to work with - runpy. +- 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 #17177: The imp module is pending deprecation. +- Issue #22111: Assorted cleanups in test_imaplib. Patch by Milan Oberkirch. -- subprocess: Prevent a possible double close of parent pipe fds when the - subprocess exec runs into an error. Prevent a regular multi-close of the - /dev/null fd when any of stdin, stdout and stderr was set to DEVNULL. +- 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 #18194: Introduce importlib.util.cache_from_source() and - source_from_cache() while documenting the equivalent functions in imp as - deprecated. +- Issue #21976: Fix test_ssl to accept LibreSSL version strings. Thanks + to William Orr. -- Issue #17907: Document imp.new_module() as deprecated in favour of - types.ModuleType. +- Issue #21918: Converted test_tools from a module to a package containing + separate test files for each tested script. -- Issue #18192: Introduce importlib.util.MAGIC_NUMBER and document as deprecated - imp.get_magic(). +- Issue #9554: Use modern unittest features in test_argparse. Initial patch by + Denver Coneybeare and Radu Voicilas. -- Issue #18149: Add filecmp.clear_cache() to manually clear the filecmp cache. - Patch by Mark Levitt +- 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 #18193: Add importlib.reload(). +- Issue #19493: Refactored the ctypes test package to skip tests explicitly + rather than silently. -- Issue #18157: Stop using imp.load_module() in pydoc. +- Issue #18492: All resources are now allowed when tests are not run by + regrtest.py. -- Issue #16102: Make uuid._netbios_getnode() work again on Python 3. +- 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 #17134: Add ssl.enum_cert_store() as interface to Windows' cert store. +- Issue #21605: Added tests for Tkinter images. -- Issue #18143: Implement ssl.get_default_verify_paths() in order to debug - the default locations for cafile and capath. +- Issue #21493: Added test for ntpath.expanduser(). Original patch by + Claudiu Popa. -- Issue #17314: Move multiprocessing.forking over to importlib. +- Issue #19925: Added tests for the spwd module. Original patch by Vajrasky Kok. -- Issue #11959: SMTPServer and SMTPChannel now take an optional map, use of - which avoids affecting global state. +- Issue #21522: Added Tkinter tests for Listbox.itemconfigure(), + PanedWindow.paneconfigure(), and Menu.entryconfigure(). -- Issue #18109: os.uname() now decodes fields from the locale encoding, and - socket.gethostname() now decodes the hostname from the locale encoding, - instead of using the UTF-8 encoding in strict mode. +- Issue #17756: Fix test_code test when run from the installed location. -- Issue #18089: Implement importlib.abc.InspectLoader.load_module. +- Issue #17752: Fix distutils tests when run from the installed location. -- Issue #18088: Introduce importlib.abc.Loader.init_module_attrs for setting - module attributes. Leads to the pending deprecation of - importlib.util.module_for_loader. +- 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 #17403: urllib.parse.robotparser normalizes the urls before adding to - ruleline. This helps in handling certain types invalid urls in a conservative - manner. Patch contributed by Mher Movsisyan. +- Issue #21275: Fix a socket test on KFreeBSD. -- Issue #18070: Have importlib.util.module_for_loader() set attributes - unconditionally in order to properly support reloading. +- Issue #21223: Pass test_site/test_startup_imports when some of the extensions + are built as builtins. -- Added importlib.util.module_to_load to return a context manager to provide the - proper module object to load. +- Issue #20635: Added tests for Tk geometry managers. -- Issue #18025: Fixed a segfault in io.BufferedIOBase.readinto() when raw - stream's read() returns more bytes than requested. +- Add test case for freeze. -- Issue #18011: base64.b32decode() now raises a binascii.Error if there are - non-alphabet characters present in the input string to conform a docstring. - Updated the module documentation. +- Issue #20743: Fix a reference leak in test_tcl. -- Issue #18072: Implement importlib.abc.InspectLoader.get_code() and - importlib.abc.ExecutionLoader.get_code(). +- Issue #21097: Move test_namespace_pkgs into test_importlib. -- Issue #8240: Set the SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER flag on SSL - sockets. +- Issue #21503: Use test_both() consistently in test_importlib. -- Issue #17269: Workaround for socket.getaddrinfo crash on MacOS X - with port None or "0" and flags AI_NUMERICSERV. +- 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 #16986: ElementTree now correctly parses a string input not only when - an internal XML encoding is UTF-8 or US-ASCII. +- Issue #20668: asyncio tests no longer rely on tests.txt file. + (Patch by Vajrasky Kok) -- Issue #17996: socket module now exposes AF_LINK constant on BSD and OSX. +- Issue #21093: Prevent failures of ctypes test_macholib on OS X if a + copy of libz exists in $HOME/lib or /usr/local/lib. -- Issue #17900: Allowed pickling of recursive OrderedDicts. Decreased pickled - size and pickling time. +- Issue #22770: Prevent some Tk segfaults on OS X when running gui tests. -- Issue #17914: Add os.cpu_count(). Patch by Yogesh Chaudhari, based on an - initial patch by Trent Nelson. +- Issue #23211: Workaround test_logging failure on some OS X 10.6 systems. -- Issue #17812: Fixed quadratic complexity of base64.b32encode(). - Optimize base64.b32encode() and base64.b32decode() (speed up to 3x). +- Issue #23345: Prevent test_ssl failures with large OpenSSL patch level + values (like 0.9.8zc). -- Issue #17980: Fix possible abuse of ssl.match_hostname() for denial of - service using certificates with many wildcards (CVE-2013-2099). +Tools/Demos +----------- -- Issue #15758: Fix FileIO.readall() so it no longer has O(n**2) complexity. +- Issue #22314: pydoc now works when the LINES environment variable is set. -- Issue #14596: The struct.Struct() objects now use more compact implementation. +- Issue #22615: Argument Clinic now supports the "type" argument for the + int converter. This permits using the int converter with enums and + typedefs. -- Issue #17981: Closed socket on error in SysLogHandler. +- Issue #20076: The makelocalealias.py script no longer ignores UTF-8 mapping. -- Issue #17964: Fix os.sysconf(): the return type of the C sysconf() function - is long, not int. +- Issue #20079: The makelocalealias.py script now can parse the SUPPORTED file + from glibc sources and supports command line options for source paths. -- Fix typos in the multiprocessing module. +- Issue #22201: Command-line interface of the zipfile module now correctly + extracts ZIP files with directory entries. Patch by Ryan Wilson. -- Issue #17754: Make ctypes.util.find_library() independent of the locale. +- Issue #22120: For functions using an unsigned integer return converter, + Argument Clinic now generates a cast to that type for the comparison + to -1 in the generated code. (This supresses a compilation warning.) -- Issue #17968: Fix memory leak in os.listxattr(). +- Issue #18974: Tools/scripts/diff.py now uses argparse instead of optparse. -- Issue #17606: Fixed support of encoded byte strings in the XMLGenerator - characters() and ignorableWhitespace() methods. Original patch by Sebastian - Ortiz Vasquez. +- Issue #21906: Make Tools/scripts/md5sum.py work in Python 3. + Patch by Zachary Ware. -- Issue #17732: Ignore distutils.cfg options pertaining to install paths if a - virtual environment is active. +- Issue #21629: Fix Argument Clinic's "--converters" feature. -- Issue #17915: Fix interoperability of xml.sax with file objects returned by - codecs.open(). +- Add support for ``yield from`` to 2to3. -- Issue #16601: Restarting iteration over tarfile no more continues from where - it left off. Patch by Michael Birtwell. +- Add support for the PEP 465 matrix multiplication operator to 2to3. -- Issue #17289: The readline module now plays nicer with external modules - or applications changing the rl_completer_word_break_characters global - variable. Initial patch by Bradley Froehle. +- Issue #16047: Fix module exception list and __file__ handling in freeze. + Patch by Meador Inge. -- Issue #12181: select module: Fix struct kevent definition on OpenBSD 64-bit - platforms. Patch by Federico Schwindt. +- Issue #11824: Consider ABI tags in freeze. Patch by Meador Inge. -- Issue #11816: multiple improvements to the dis module: get_instructions - generator, ability to redirect output to a file, Bytecode and Instruction - abstractions. Patch by Nick Coghlan, Ryan Kelly and Thomas Kluyver. +- Issue #20535: PYTHONWARNING no longer affects the run_tests.py script. + Patch by Arfrever Frehtes Taifersar Arahesis. -- Issue #13831: Embed stringification of remote traceback in local - traceback raised when pool task raises an exception. +Windows +------- -- Issue #15528: Add weakref.finalize to support finalization using - weakref callbacks. +- Issue #23260: Update Windows installer -- Issue #14173: Avoid crashing when reading a signal handler during - interpreter shutdown. +- The bundled version of Tcl/Tk has been updated to 8.6.3. The most visible + result of this change is the addition of new native file dialogs when + running on Windows Vista or newer. See Tcl/Tk's TIP 432 for more + information. Also, this version of Tcl/Tk includes support for Windows 10. -- Issue #15902: Fix imp.load_module() accepting None as a file when loading an - extension module. +- Issue #17896: The Windows build scripts now expect external library sources + to be in ``PCbuild\..\externals`` rather than ``PCbuild\..\..``. -- Issue #13721: SSLSocket.getpeercert() and SSLSocket.do_handshake() now - raise an OSError with ENOTCONN, instead of an AttributeError, when the - SSLSocket is not connected. +- Issue #17717: The Windows build scripts now use a copy of NASM pulled from + svn.python.org to build OpenSSL. -- Issue #14679: add an __all__ (that contains only HTMLParser) to html.parser. +- Issue #21907: Improved the batch scripts provided for building Python. -- Issue #17802: Fix an UnboundLocalError in html.parser. Initial tests by - Thomas Barlow. +- Issue #22644: The bundled version of OpenSSL has been updated to 1.0.1j. -- Issue #17358: Modules loaded by imp.load_source() and load_compiled() (and by - extention load_module()) now have a better chance of working when reloaded. +- Issue #10747: Use versioned labels in the Windows start menu. + Patch by Olive Kilburn. -- Issue #17804: New function ``struct.iter_unpack`` allows for streaming - struct unpacking. +- Issue #22980: .pyd files with a version and platform tag (for example, + ".cp35-win32.pyd") will now be loaded in preference to those without tags. -- Issue #17830: When keyword.py is used to update a keyword file, it now - preserves the line endings of the original file. +What's New in Python 3.4.0? +=========================== -- Issue #17272: Making the urllib.request's Request.full_url a descriptor. - Fixes bugs with assignment to full_url. Patch by Demian Brecht. +Release date: 2014-03-16 -- Issue #17353: Plistlib emitted empty data tags with deeply nested datastructures +Library +------- -- Issue #11714: Use 'with' statements to assure a Semaphore releases a - condition variable. Original patch by Thomas Rachel. +- Issue #20939: Fix test_geturl failure in test_urllibnet due to + new redirect of http://www.python.org/ to https://www.python.org. -- Issue #16624: `subprocess.check_output` now accepts an `input` argument, - allowing the subprocess's stdin to be provided as a (byte) string. - Patch by Zack Weinberg. +Documentation +------------- -- Issue #17795: Reverted backwards-incompatible change in SysLogHandler with - Unix domain sockets. +- Merge in all documentation changes since branching 3.4.0rc1. -- Issue #16694: Add a pure Python implementation of the operator module. - Patch by Zachary Ware. -- Issue #11182: remove the unused and undocumented pydoc.Scanner class. - Patch by Martin Morrison. +What's New in Python 3.4.0 release candidate 3? +=============================================== -- Issue #17741: Add ElementTree.IncrementalParser, an event-driven parser - for non-blocking applications. +Release date: 2014-03-09 -- Issue #17555: Fix ForkAwareThreadLock so that size of after fork - registry does not grow exponentially with generation of process. +Core and Builtins +----------------- -- Issue #17707: multiprocessing.Queue's get() method does not block for short - timeouts. +- Issue #20786: Fix signatures for dict.__delitem__ and + property.__delete__ builtins. -- Isuse #17720: Fix the Python implementation of pickle.Unpickler to correctly - process the APPENDS opcode when it is used on non-list objects. +Library +------- -- Issue #17012: shutil.which() no longer fallbacks to the PATH environment - variable if empty path argument is specified. Patch by Serhiy Storchaka. +- Issue #20839: Don't trigger a DeprecationWarning in the still supported + pkgutil.get_loader() API when __loader__ isn't set on a module (nor + when pkgutil.find_loader() is called directly). -- Issue #17710: Fix pickle raising a SystemError on bogus input. +Build +----- -- Issue #17341: Include the invalid name in the error messages from re about - invalid group names. +- Issue #14512: Launch pydoc -b instead of pydocgui.pyw on Windows. -- Issue #17702: os.environ now raises KeyError with the original environment - variable name (str on UNIX), instead of using the encoded name (bytes on - UNIX). +- Issue #20748: Uninstalling pip does not leave behind the pyc of + the uninstaller anymore. -- Issue #16163: Make the importlib based version of pkgutil.iter_importers - work for submodules. Initial patch by Berker Peksag. +- Issue #20568: The Windows installer now installs the unversioned ``pip`` + command in addition to the versioned ``pip3`` and ``pip3.4`` commands. -- Issue #16804: Fix a bug in the 'site' module that caused running - 'python -S -m site' to incorrectly throw an exception. +- Issue #20757: The ensurepip helper for the Windows uninstaller now skips + uninstalling pip (rather than failing) if the user has updated pip to a + different version from the one bundled with ensurepip. -- Issue #15480: Remove the deprecated and unused TYPE_INT64 code from marshal. - Initial patch by Daniel Riti. +- Issue #20465: Update OS X and Windows installer builds to use + SQLite 3.8.3.1. -- Issue #2118: SMTPException is now a subclass of IOError. -- Issue #17016: Get rid of possible pointer wraparounds and integer overflows - in the re module. Patch by Nickolai Zeldovich. +What's New in Python 3.4.0 release candidate 2? +=============================================== -- Issue #16658: add missing return to HTTPConnection.send() - Patch by Jeff Knupp. +Release date: 2014-02-23 -- Issue #9556: Allowed specifying a time-of-day for a TimedRotatingFileHandler - to rotate. +Core and Builtins +----------------- -- Issue #14971: unittest test discovery no longer gets confused when a function - has a different __name__ than its name in the TestCase class dictionary. +- Issue #20625: Parameter names in __annotations__ were not mangled properly. + Discovered by Jonas Wielicki, patch by Yury Selivanov. -- Issue #17487: The wave getparams method now returns a namedtuple rather than - a plain tuple. +- Issue #20261: In pickle, lookup __getnewargs__ and __getnewargs_ex__ on the + type of the object. -- Issue #17675: socket repr() provides local and remote addresses (if any). - Patch by Giampaolo Rodola' +- Issue #20619: Give the AST nodes of keyword-only arguments a column and line + number. -- Issue #17093: Make the ABCs in importlib.abc provide default values or raise - reasonable exceptions for their methods to make them more amenable to super() - calls. +- Issue #20526: Revert changes of issue #19466 which introduces a regression: + don't clear anymore the state of Python threads early during the Python + shutdown. -- Issue #17566: Make importlib.abc.Loader.module_repr() optional instead of an - abstractmethod and raising NotImplementedError so as to be ignored by default. +Library +------- -- Issue #17678: Remove the use of deprecated method in http/cookiejar.py. - Changing the usage of get_origin_req_host() to origin_req_host. +- Issue #20710: The pydoc summary line no longer displays the "self" parameter + for bound methods. -- Issue #17666: Fix reading gzip files with an extra field. +- Issue #20566: Change asyncio.as_completed() to use a Queue, to + avoid O(N**2) behavior. -- Issue #16475: Support object instancing, recursion and interned strings - in marshal +- Issue #20704: Implement new debug API in asyncio. Add new methods + BaseEventLoop.set_debug() and BaseEventLoop.get_debug(). + Add support for setting 'asyncio.tasks._DEBUG' variable with + 'PYTHONASYNCIODEBUG' environment variable. -- Issue #17502: Process DEFAULT values in mock side_effect that returns iterator. +- asyncio: Refactoring and fixes: BaseEventLoop.sock_connect() raises an + error if the address is not resolved; use __slots__ in Handle and + TimerHandle; as_completed() and wait() raise TypeError if the passed + list of Futures is a single Future; call_soon() and other 'call_*()' + functions raise TypeError if the passed callback is a coroutine + function; _ProactorBasePipeTransport uses _FlowControlMixin; + WriteTransport.set_write_buffer_size() calls _maybe_pause_protocol() + to consider pausing receiving if the watermark limits have changed; + fix _check_resolved_address() for IPv6 address; and other minor + improvements, along with multiple documentation updates. -- Issue #16795: On the ast.arguments object, unify vararg with varargannotation - and kwarg and kwargannotation. Change the column offset of ast.Attribute to be - at the attribute name. +- Issue #20684: Fix inspect.getfullargspec() to not to follow __wrapped__ + chains. Make its behaviour consistent with bound methods first argument. + Patch by Nick Coghlan and Yury Selivanov. -- Issue #17434: Properly raise a SyntaxError when a string occurs between future - imports. +- Issue #20681: Add new error handling API in asyncio. New APIs: + loop.set_exception_handler(), loop.default_exception_handler(), and + loop.call_exception_handler(). -- Issue #17117: Import and @importlib.util.set_loader now set __loader__ when - it has a value of None or the attribute doesn't exist. +- Issue #20673: Implement support for UNIX Domain Sockets in asyncio. + New APIs: loop.create_unix_connection(), loop.create_unix_server(), + streams.open_unix_connection(), and streams.start_unix_server(). -- Issue #17032: The "global" in the "NameError: global name 'x' is not defined" - error message has been removed. Patch by Ram Rachum. +- Issue #20616: Add a format() method to tracemalloc.Traceback. -- Issue #18080: When building a C extension module on OS X, if the compiler - is overriden with the CC environment variable, use the new compiler as - the default for linking if LDSHARED is not also overriden. This restores - Distutils behavior introduced in 3.2.3 and inadvertently dropped in 3.3.0. +- Issue #19744: the ensurepip installation step now just prints a warning to + stderr rather than failing outright if SSL/TLS is unavailable. This allows + local installation of POSIX builds without SSL/TLS support. -- Issue #18113: Fixed a refcount leak in the curses.panel module's - set_userptr() method. Reported by Atsuo Ishimoto. +- Issue #20594: Avoid name clash with the libc function posix_close. -- Implement PEP 443 "Single-dispatch generic functions". +Build +----- -- Implement PEP 435 "Adding an Enum type to the Python standard library". +- Issue #20641: Run MSI custom actions (pip installation, pyc compilation) + with the NoImpersonate flag, to support elevated execution (UAC). -- Issue #15596: Faster pickling of unicode strings. +- Issue #20221: Removed conflicting (or circular) hypot definition when + compiled with VS 2010 or above. Initial patch by Tabrez Mohammed. -- Issue #17572: Avoid chained exceptions while passing bad directives to - time.strptime(). Initial patch by Claudiu Popa. +- Issue #20609: Restored the ability to build 64-bit Windows binaries on + 32-bit Windows, which was broken by the change in issue #19788. -- Issue #17435: threading.Timer's __init__ method no longer uses mutable - default values for the args and kwargs parameters. -- Issue #17526: fix an IndexError raised while passing code without filename to - inspect.findsource(). Initial patch by Tyler Doyle. +What's New in Python 3.4.0 release candidate 1? +=============================================== -- Issue #17540: Added style to formatter configuration by dict. +Release date: 2014-02-10 -- Issue #16692: The ssl module now supports TLS 1.1 and TLS 1.2. Initial - patch by Michele Orrù. +Core and Builtins +----------------- -- Issue #17025: multiprocessing: Reduce Queue and SimpleQueue contention. +- Issue #19255: The builtins module is restored to initial value before + cleaning other modules. The sys and builtins modules are cleaned last. -- Issue #17536: Add to webbrowser's browser list: www-browser, x-www-browser, - iceweasel, iceape. +- Issue #20588: Make Python-ast.c C89 compliant. -- Issue #17150: pprint now uses line continuations to wrap long string - literals. +- Issue #20437: Fixed 22 potential bugs when deleting objects references. -- Issue #17488: Change the subprocess.Popen bufsize parameter default value - from unbuffered (0) to buffering (-1) to match the behavior existing code - expects and match the behavior of the subprocess module in Python 2 to avoid - introducing hard to track down bugs. +- Issue #20500: Displaying an exception at interpreter shutdown no longer + risks triggering an assertion failure in PyObject_Str. -- Issue #17521: Corrected non-enabling of logger following two calls to - fileConfig(). +- Issue #20538: UTF-7 incremental decoder produced inconsistent string when + input was truncated in BASE64 section. -- Issue #17508: Corrected MemoryHandler configuration in dictConfig() where - the target handler wasn't configured first. +- Issue #20404: io.TextIOWrapper (and hence the open() builtin) now uses the + internal codec marking system added for issue #19619 to throw LookupError + for known non-text encodings at stream construction time. The existing + output type checks remain in place to deal with unmarked third party + codecs. -- Issue #17209: curses.window.get_wch() now handles correctly KeyboardInterrupt - (CTRL+c). +- Issue #17162: Add PyType_GetSlot. -- Issue #5713: smtplib now handles 421 (closing connection) error codes when - sending mail by closing the socket and reporting the 421 error code via the - exception appropriate to the command that received the error response. +- Issue #20162: Fix an alignment issue in the siphash24() hash function which + caused a crash on PowerPC 64-bit (ppc64). -- Issue #16997: unittest.TestCase now provides a subTest() context manager - to procedurally generate, in an easy way, small test instances. +Library +------- -- Issue #17485: Also delete the Request Content-Length header if the data - attribute is deleted. (Follow on to issue 16464). +- Issue #20530: The signatures for slot builtins have been updated + to reflect the fact that they only accept positional-only arguments. -- Issue #15927: CVS now correctly parses escaped newlines and carriage - when parsing with quoting turned off. +- Issue #20517: Functions in the os module that accept two filenames + now register both filenames in the exception on failure. -- Issue #17467: add readline and readlines support to mock_open in - unittest.mock. +- Issue #20563: The ipaddress module API is now considered stable. -- Issue #17192: Update the ctypes module's libffi to v3.0.13. This - specifically addresses a stack misalignment issue on x86 and issues on - some more recent platforms. +- Issue #14983: email.generator now always adds a line end after each MIME + boundary marker, instead of doing so only when there is an epilogue. This + fixes an RFC compliance bug and solves an issue with signed MIME parts. -- Issue #8862: Fixed curses cleanup when getkey is interrputed by a signal. +- Issue #20540: Fix a performance regression (vs. Python 3.2) when layering + a multiprocessing Connection over a TCP socket. For small payloads, Nagle's + algorithm would introduce idle delays before the entire transmission of a + message. -- Issue #17443: imaplib.IMAP4_stream was using the default unbuffered IO - in subprocess, but the imap code assumes buffered IO. In Python2 this - worked by accident. IMAP4_stream now explicitly uses buffered IO. +- Issue #16983: the new email header parsing code will now decode encoded words + that are (incorrectly) surrounded by quotes, and register a defect. -- Issue #17476: Fixed regression relative to Python2 in undocumented pydoc - 'allmethods'; it was missing unbound methods on the class. +- Issue #19772: email.generator no longer mutates the message object when + doing a down-transform from 8bit to 7bit CTEs. -- Issue #17474: Remove the deprecated methods of Request class. +- Issue #20536: the statistics module now correctly handle Decimal instances + with positive exponents -- Issue #16709: unittest discover order is no-longer filesystem specific. Patch - by Jeff Ramnani. +- Issue #18805: the netmask/hostmask parsing in ipaddress now more reliably + filters out illegal values and correctly allows any valid prefix length. -- Use the HTTPS PyPI url for upload, overriding any plain HTTP URL in pypirc. +- Issue #20481: For at least Python 3.4, the statistics module will require + that all inputs for a single operation be of a single consistent type, or + else a mixed of ints and a single other consistent type. This avoids + some interoperability issues that arose with the previous approach of + coercing to a suitable common type. -- Issue #5024: sndhdr.whichhdr now returns the frame count for WAV files - rather than -1. +- Issue #20478: the statistics module now treats collections.Counter inputs + like any other iterable. -- Issue #17460: Remove the strict argument of HTTPConnection and removing the - DeprecationWarning being issued from 3.2 onwards. +- Issue #17369: get_filename was raising an exception if the filename + parameter's RFC2231 encoding was broken in certain ways. This was + a regression relative to python2. -- Issue #16880: Do not assume _imp.load_dynamic() is defined in the imp module. +- Issue #20013: Some imap servers disconnect if the current mailbox is + deleted, and imaplib did not handle that case gracefully. Now it + handles the 'bye' correctly. -- Issue #16389: Fixed a performance regression relative to Python 3.1 in the - caching of compiled regular expressions. +- Issue #20531: Revert 3.4 version of fix for #19063, and apply the 3.3 + version. That is, do *not* raise an error if unicode is passed to + email.message.Message.set_payload. -- Added missing FeedParser and BytesFeedParser to email.parser.__all__. +- Issue #20476: If a non-compat32 policy is used with any of the email parsers, + EmailMessage is now used as the factory class. The factory class should + really come from the policy; that will get fixed in 3.5. -- Issue #17431: Fix missing import of BytesFeedParser in email.parser. +- Issue #19920: TarFile.list() no longer fails when outputs a listing + containing non-encodable characters. Based on patch by Vajrasky Kok. -- Issue #12921: http.server's send_error takes an explain argument to send more - information in response. Patch contributed by Karl. +- Issue #20515: Fix NULL pointer dereference introduced by issue #20368. -- Issue #17414: Add timeit, repeat, and default_timer to timeit.__all__. +- Issue #19186: Restore namespacing of expat symbols inside the pyexpat module. -- Issue #1285086: Get rid of the refcounting hack and speed up - urllib.parse.unquote() and urllib.parse.unquote_to_bytes(). +- Issue #20053: ensurepip (and hence venv) are no longer affected by the + settings in the default pip configuration file. -- Issue #17099: Have importlib.find_loader() raise ValueError when __loader__ - is not set, harmonizing with what happens when the attribute is set to None. +- Issue #20426: When passing the re.DEBUG flag, re.compile() displays the + debug output every time it is called, regardless of the compilation cache. -- Expose the O_PATH constant in the os module if it is available. +- Issue #20368: The null character now correctly passed from Tcl to Python. + Improved error handling in variables-related commands. -- Issue #17368: Fix an off-by-one error in the Python JSON decoder that caused - a failure while decoding empty object literals when object_pairs_hook was - specified. +- Issue #20435: Fix _pyio.StringIO.getvalue() to take into account newline + translation settings. -- Issue #17385: Fix quadratic behavior in threading.Condition. The FIFO - queue now uses a deque instead of a list. +- tracemalloc: Fix slicing traces and fix slicing a traceback. -- Issue #15806: Add contextlib.ignore(). This creates a context manager to - ignore specified exceptions, replacing the "except SomeException: pass" idiom. +- Issue #20354: Fix an alignment issue in the tracemalloc module on 64-bit + platforms. Bug seen on 64-bit Linux when using "make profile-opt". -- Issue #14645: The email generator classes now produce output using the - specified linesep throughout. Previously if the prolog, epilog, or - body were stored with a different linesep, that linesep was used. This - fix corrects an RFC non-compliance issue with smtplib.send_message. +- Issue #17159: inspect.signature now accepts duck types of functions, + which adds support for Cython functions. Initial patch by Stefan Behnel. -- Issue #17278: Fix a crash in heapq.heappush() and heapq.heappop() when - the list is being resized concurrently. +- Issue #18801: Fix inspect.classify_class_attrs to correctly classify + object.__new__ and object.__init__. -- Issue #16962: Use getdents64 instead of the obsolete getdents syscall - in the subprocess module on Linux. +- Fixed cmath.isinf's name in its argument parsing code. -- Issue #16935: unittest now counts the module as skipped if it raises SkipTest, - instead of counting it as an error. Patch by Zachary Ware. +- Issue #20311, #20452: poll and epoll now round the timeout away from zero, + instead of rounding towards zero, in select and selectors modules: + select.epoll.poll(), selectors.PollSelector.poll() and + selectors.EpollSelector.poll(). For example, a timeout of one microsecond + (1e-6) is now rounded to one millisecondi (1e-3), instead of being rounded to + zero. However, the granularity property and asyncio's resolution feature + were removed again. -- Issue #17018: Make Process.join() retry if os.waitpid() fails with EINTR. +- asyncio: Some refactoring; various fixes; add write flow control to + unix pipes; Future.set_exception() instantiates the exception + argument if it is a class; improved proactor pipe transport; support + wait_for(f, None); don't log broken/disconnected pipes; use + ValueError instead of assert for forbidden subprocess_{shell,exec} + arguments; added a convenience API for subprocess management; added + StreamReader.at_eof(); properly handle duplicate coroutines/futures + in gather(), wait(), as_completed(); use a bytearray for buffering + in StreamReader; and more. -- Issue #17223: array module: Fix a crasher when converting an array containing - invalid characters (outside range [U+0000; U+10ffff]) to Unicode: - repr(array), str(array) and array.tounicode(). Patch written by Manuel Jacob. +- Issue #20288: fix handling of invalid numeric charrefs in HTMLParser. -- Issue #17197: profile/cProfile modules refactored so that code of run() and - runctx() utility functions is not duplicated in both modules. +- Issue #20424: Python implementation of io.StringIO now supports lone surrogates. -- Issue #14720: sqlite3: Convert datetime microseconds correctly. - Patch by Lowe Thiderman. +- Issue #20308: inspect.signature now works on classes without user-defined + __init__ or __new__ methods. -- Issue #15132: Allow a list for the defaultTest argument of - unittest.TestProgram. Patch by Jyrki Pulliainen. +- Issue #20372: inspect.getfile (and a bunch of other inspect functions that + use it) doesn't crash with unexpected AttributeError on classes defined in C + without __module__. -- Issue #17225: JSON decoder now counts columns in the first line starting - with 1, as in other lines. +- Issue #20356: inspect.signature formatting uses '/' to separate + positional-only parameters from others. -- Issue #6623: Added explicit DeprecationWarning for ftplib.netrc, which has - been deprecated and undocumented for a long time. +- Issue #20223: inspect.signature now supports methods defined with + functools.partialmethods. -- Issue #13700: Fix byte/string handling in imaplib authentication when an - authobject is specified. +- Issue #19456: ntpath.join() now joins relative paths correctly when a drive + is present. -- Issue #13153: Tkinter functions now raise TclError instead of ValueError when - a string argument contains non-BMP character. +- Issue #19077: tempfile.TemporaryDirectory cleanup no longer fails when + called during shutdown. Emitting resource warning in __del__ no longer fails. + Original patch by Antoine Pitrou. -- Issue #9669: Protect re against infinite loops on zero-width matching in - non-greedy repeat. Patch by Matthew Barnett. +- Issue #20394: Silence Coverity warning in audioop module. -- Issue #13169: The maximal repetition number in a regular expression has been - increased from 65534 to 2147483647 (on 32-bit platform) or 4294967294 (on - 64-bit). +- Issue #20367: Fix behavior of concurrent.futures.as_completed() for + duplicate arguments. Patch by Glenn Langford. -- Issue #17143: Fix a missing import in the trace module. Initial patch by - Berker Peksag. +- Issue #8260: The read(), readline() and readlines() methods of + codecs.StreamReader returned incomplete data when were called after + readline() or read(size). Based on patch by Amaury Forgeot d'Arc. -- Issue #15220: email.feedparser's line splitting algorithm is now simpler and - faster. +- Issue #20105: the codec exception chaining now correctly sets the + traceback of the original exception as its __traceback__ attribute. -- Issue #16743: Fix mmap overflow check on 32 bit Windows. +- Issue #17481: inspect.getfullargspec() now uses inspect.signature() API. -- Issue #16996: webbrowser module now uses shutil.which() to find a - web-browser on the executable search path. +- Issue #15304: concurrent.futures.wait() can block forever even if + Futures have completed. Patch by Glenn Langford. -- Issue #16800: tempfile.gettempdir() no longer left temporary files when - the disk is full. Original patch by Amir Szekely. +- Issue #14455: plistlib: fix serializing integers in the range + of an unsigned long long but outside of the range of signed long long for + binary plist files. -- Issue #17192: Import libffi-3.0.12. +IDLE +---- -- Issue #16564: Fixed regression relative to Python2 in the operation of - email.encoders.encode_7or8bit when used with binary data. +- Issue #20406: Use Python application icons for Idle window title bars. + Patch mostly by Serhiy Storchaka. -- Issue #17052: unittest discovery should use self.testLoader. +- Update the python.gif icon for the Idle classbrowser and pathbowser + from the old green snake to the new blue and yellow snakes. -- Issue #4591: Uid and gid values larger than 2**31 are supported now. +- Issue #17721: Remove non-functional configuration dialog help button until we + make it actually gives some help when clicked. Patch by Guilherme Simões. -- Issue #17141: random.vonmisesvariate() no more hangs for large kappas. +Tests +----- -- Issue #17149: Fix random.vonmisesvariate to always return results in - [0, 2*math.pi]. +- Issue #20532: Tests which use _testcapi now are marked as CPython only. -- Issue #1470548: XMLGenerator now works with binary output streams. +- Issue #19920: Added tests for TarFile.list(). Based on patch by Vajrasky Kok. -- Issue #6975: os.path.realpath() now correctly resolves multiple nested - symlinks on POSIX platforms. +- Issue #19990: Added tests for the imghdr module. Based on patch by + Claudiu Popa. -- Issue #13773: sqlite3.connect() gets a new `uri` parameter to pass the - filename as a URI, allowing to pass custom options. +- Issue #20474: Fix test_socket "unexpected success" failures on OS X 10.7+. -- Issue #16564: Fixed regression relative to Python2 in the operation of - email.encoders.encode_noop when used with binary data. +Tools/Demos +----------- -- Issue #10355: In SpooledTemporaryFile class mode, name, encoding and - newlines properties now work for unrolled files. Obsoleted and never - working on Python 3 xreadline method now removed. +- Issue #20530: Argument Clinic's signature format has been revised again. + The new syntax is highly human readable while still preventing false + positives. The syntax also extends Python syntax to denote "self" and + positional-only parameters, allowing inspect.Signature objects to be + totally accurate for all supported builtins in Python 3.4. -- Issue #16686: Fixed a lot of bugs in audioop module. Fixed crashes in - avgpp(), maxpp() and ratecv(). Fixed an integer overflow in add(), bias(), - and ratecv(). reverse(), lin2lin() and ratecv() no more lose precision for - 32-bit samples. max() and rms() no more returns a negative result and - various other functions now work correctly with 32-bit sample -0x80000000. +- Issue #20456: Argument Clinic now observes the C preprocessor conditional + compilation statements of the C files it parses. When a Clinic block is + inside a conditional code, it adjusts its output to match, including + automatically generating an empty methoddef macro. -- Issue #17073: Fix some integer overflows in sqlite3 module. +- Issue #20456: Cloned functions in Argument Clinic now use the correct + name, not the name of the function they were cloned from, for text + strings inside generated code. -- Issue #16723: httplib.HTTPResponse no longer marked closed when the connection - is automatically closed. +- Issue #20456: Fixed Argument Clinic's test suite and "--converters" feature. -- Issue #15359: Add CAN_BCM protocol support to the socket module. Patch by - Brian Thorne. +- Issue #20456: Argument Clinic now allows specifying different names + for a parameter in Python and C, using "as" on the parameter line. -- Issue #16948: Fix quoted printable body encoding for non-latin1 character - sets in the email package. +- Issue #20326: Argument Clinic now uses a simple, unique signature to + annotate text signatures in docstrings, resulting in fewer false + positives. "self" parameters are also explicitly marked, allowing + inspect.Signature() to authoritatively detect (and skip) said parameters. -- Issue #16811: Fix folding of headers with no value in the provisional email - policies. +- Issue #20326: Argument Clinic now generates separate checksums for the + input and output sections of the block, allowing external tools to verify + that the input has not changed (and thus the output is not out-of-date). -- Issue #17132: Update symbol for "yield from" grammar changes. +Build +----- -- Issue #17076: Make copying of xattrs more permissive of missing FS support. - Patch by Thomas Wouters. +- Issue #20465: Update SQLite shipped with OS X installer to 3.8.3. -- Issue #17089: Expat parser now correctly works with string input not only when - an internal XML encoding is UTF-8 or US-ASCII. It now accepts bytes and - strings larger than 2 GiB. +C-API +----- -- Issue #6083: Fix multiple segmentation faults occured when PyArg_ParseTuple - parses nested mutating sequence. +- Issue #20517: Added new functions allowing OSError exceptions to reference + two filenames instead of one: PyErr_SetFromErrnoWithFilenameObjects() and + PyErr_SetExcFromWindowsErrWithFilenameObjects(). -- Issue #5289: Fix ctypes.util.find_library on Solaris. +Documentation +------------- -- Issue #17106: Fix a segmentation fault in io.TextIOWrapper when an underlying - stream or a decoder produces data of an unexpected type (i.e. when - io.TextIOWrapper initialized with text stream or use bytes-to-bytes codec). +- Issue #20488: Change wording to say importlib is *the* implementation of + import instead of just *an* implementation. -- Issue #17015: When it has a spec, a Mock object now inspects its signature - when matching calls, so that arguments can be matched positionally or - by name. +- Issue #6386: Clarify in the tutorial that specifying a symlink to execute + means the directory containing the executed script and not the symlink is + added to sys.path. -- Issue #15633: httplib.HTTPResponse is now mark closed when the server - sends less than the advertised Content-Length. -- Issue #12268: The io module file object write methods no longer abort early - when one of its write system calls is interrupted (EINTR). +What's New in Python 3.4.0 Beta 3? +================================== -- Issue #6972: The zipfile module no longer overwrites files outside of - its destination path when extracting malicious zip files. +Release date: 2014-01-26 -- Issue #4844: ZipFile now raises BadZipFile when opens a ZIP file with an - incomplete "End of Central Directory" record. Original patch by Guilherme - Polo and Alan McIntyre. +Core and Builtins +----------------- -- Issue #17071: Signature.bind() now works when one of the keyword arguments - is named ``self``. +- Issue #20189: Four additional builtin types (PyTypeObject, + PyMethodDescr_Type, _PyMethodWrapper_Type, and PyWrapperDescr_Type) + have been modified to provide introspection information for builtins. -- Issue #12004: Fix an internal error in PyZipFile when writing an invalid - Python file. Patch by Ben Morgan. +- Issue #17825: Cursor "^" is correctly positioned for SyntaxError and + IndentationError. -- Have py_compile use importlib as much as possible to avoid code duplication. - Code now raises FileExistsError if the file path to be used for the - byte-compiled file is a symlink or non-regular file as a warning that import - will not keep the file path type if it writes to that path. +- Issue #2382: SyntaxError cursor "^" is now written at correct position in most + cases when multibyte characters are in line (before "^"). This still not + works correctly with wide East Asian characters. -- Issue #180022: Have site.addpackage() consider already known paths even when - none are explicitly passed in. Bug report and fix by Kirill. +- Issue #18960: The first line of Python script could be executed twice when + the source encoding was specified on the second line. Now the source encoding + declaration on the second line isn't effective if the first line contains + anything except a comment. 'python -x' works now again with files with the + source encoding declarations, and can be used to make Python batch files + on Windows. -- Issue #1602133: on Mac OS X a shared library build (``--enable-shared``) - now fills the ``os.environ`` variable correctly. +Library +------- -- Issue #15505: `unittest.installHandler` no longer assumes SIGINT handler is - set to a callable object. +- asyncio: Various improvements and small changes not all covered by + issues listed below. E.g. wait_for() now cancels the inner task if + the timeout occcurs; tweaked the set of exported symbols; renamed + Empty/Full to QueueEmpty/QueueFull; "with (yield from lock)" now + uses a separate context manager; readexactly() raises if not enough + data was read; PTY support tweaks. -- Issue #13454: Fix a crash when deleting an iterator created by itertools.tee() - if all other iterators were very advanced before. +- Issue #20311: asyncio: Add a granularity attribute to BaseEventLoop: maximum + between the resolution of the BaseEventLoop.time() method and the resolution + of the selector. The granuarility is used in the scheduler to round time and + deadline. -- Issue #12411: Fix to cgi.parse_multipart to correctly use bytes boundaries - and bytes data. Patch by Jonas Wagner. +- Issue #20311: selectors: Add a resolution attribute to BaseSelector. -- Issue #16957: shutil.which() no longer searches a bare file name in the - current directory on Unix and no longer searches a relative file path with - a directory part in PATH directories. Patch by Thomas Kluyver. +- Issue #20189: unittest.mock now no longer assumes that any object for + which it could get an inspect.Signature is a callable written in Python. + Fix courtesy of Michael Foord. -- Issue #1159051: GzipFile now raises EOFError when reading a corrupted file - with truncated header or footer. +- Issue #20317: ExitStack.__exit__ could create a self-referential loop if an + exception raised by a cleanup operation already had its context set + correctly (for example, by the @contextmanager decorator). The infinite + loop this caused is now avoided by checking if the expected context is + already set before trying to fix it. -- Issue #16993: shutil.which() now preserves the case of the path and extension - on Windows. +- Issue #20374: Fix build with GNU readline >= 6.3. -- Issue #16992: On Windows in signal.set_wakeup_fd, validate the file - descriptor argument. +- Issue #20262: Warnings are raised now when duplicate names are added in the + ZIP file or too long ZIP file comment is truncated. -- Issue #16422: For compatibility with the Python version, the C version of - decimal now uses strings instead of integers for rounding mode constants. +- Issue #20165: The unittest module no longer considers tests marked with + @expectedFailure successful if they pass. -- Issue #15861: tkinter now correctly works with lists and tuples containing - strings with whitespaces, backslashes or unbalanced braces. +- Issue #18574: Added missing newline in 100-Continue reply from + http.server.BaseHTTPRequestHandler. Patch by Nikolaus Rath. -- Issue #9720: zipfile now writes correct local headers for files larger than - 4 GiB. +- Issue #20270: urllib.urlparse now supports empty ports. -- Issue #16955: Fix the poll() method for multiprocessing's socket - connections on Windows. +- Issue #20243: TarFile no longer raise ReadError when opened in write mode. -- SSLContext.load_dh_params() now properly closes the input file. +- Issue #20238: TarFile opened with external fileobj and "w:gz" mode didn't + write complete output on close. -- Issue #15031: Refactor some .pyc management code to cut down on code - duplication. Thanks to Ronan Lamy for the report and taking an initial stab - at the problem. +- Issue #20245: The open functions in the tarfile module now correctly handle + empty mode. -- Issue #16398: Optimize deque.rotate() so that it only moves pointers - and doesn't touch the underlying data with increfs and decrefs. +- Issue #20242: Fixed basicConfig() format strings for the alternative + formatting styles. Thanks to kespindler for the bug report and patch. -- Issue #16900: Issue a ResourceWarning when an ssl socket is left unclosed. +- Issue #20246: Fix buffer overflow in socket.recvfrom_into. -- Issue #13899: \A, \Z, and \B now correctly match the A, Z, and B literals - when used inside character classes (e.g. '[\A]'). Patch by Matthew Barnett. +- Issues #20206 and #5803: Fix edge case in email.quoprimime.encode where it + truncated lines ending in a character needing encoding but no newline by + using a more efficient algorithm that doesn't have the bug. -- Issue #15545: Fix regression in sqlite3's iterdump method where it was - failing if the connection used a row factory (such as sqlite3.Row) that - produced unsortable objects. (Regression was introduced by fix for 9750). +- Issue #19082: Working xmlrpc.server and xmlrpc.client examples. Both in + modules and in documentation. Initial patch contributed by Vajrasky Kok. -- fcntl: add F_DUPFD_CLOEXEC constant, available on Linux 2.6.24+. +- Issue #20138: The wsgiref.application_uri() and wsgiref.request_uri() + functions now conform to PEP 3333 when handle non-ASCII URLs. -- Issue #15972: Fix error messages when os functions expecting a file name or - file descriptor receive the incorrect type. +- Issue #19097: Raise the correct Exception when cgi.FieldStorage is given an + invalid fileobj. -- Issue #8109: The ssl module now has support for server-side SNI, thanks - to a :meth:`SSLContext.set_servername_callback` method. Patch by Daniel - Black. +- Issue #20152: Ported Python/import.c over to Argument Clinic. -- Issue #16860: In tempfile, use O_CLOEXEC when available to set the - close-on-exec flag atomically. +- Issue #13107: argparse and optparse no longer raises an exception when output + a help on environment with too small COLUMNS. Based on patch by + Elazar Gershuni. -- Issue #16674: random.getrandbits() is now 20-40% faster for small integers. +- Issue #20207: Always disable SSLv2 except when PROTOCOL_SSLv2 is explicitly + asked for. -- Issue #16009: JSON error messages now provide more information. +- Issue #18960: The tokenize module now ignore the source encoding declaration + on the second line if the first line contains anything except a comment. -- Issue #16828: Fix error incorrectly raised by bz2.compress(b'') and - bz2.BZ2Compressor.compress(b''). Initial patch by Martin Packman. +- Issue #20078: Reading malformed zipfiles no longer hangs with 100% CPU + consumption. -- Issue #16833: In http.client.HTTPConnection, do not concatenate the request - headers and body when the payload exceeds 16 KB, since it can consume more - memory for no benefit. Patch by Benno Leslie. +- Issue #20113: os.readv() and os.writev() now raise an OSError exception on + error instead of returning -1. -- Issue #16541: tk_setPalette() now works with keyword arguments. +- Issue #19719: Make importlib.abc.MetaPathFinder.find_module(), + PathEntryFinder.find_loader(), and Loader.load_module() use PEP 451 APIs to + help with backwards-compatibility. -- Issue #16820: In configparser, `parser.popitem()` no longer raises ValueError. - This makes `parser.clean()` work correctly. +- Issue #20144: inspect.Signature now supports parsing simple symbolic + constants as parameter default values in __text_signature__. -- Issue #16820: In configparser, ``parser['section'] = {}`` now preserves - section order within the parser. This makes `parser.update()` preserve section - order as well. +- Issue #20072: Fixed multiple errors in tkinter with wantobjects is False. -- Issue #16820: In configparser, ``parser['DEFAULT'] = {}`` now correctly - clears previous values stored in the default section. Same goes for - ``parser.update({'DEFAULT': {}})``. +- Issue #20229: Avoid plistlib deprecation warning in platform.mac_ver(). -- Issue #9586: Redefine SEM_FAILED on MacOSX to keep compiler happy. +- Issue #14455: Fix some problems with the new binary plist support in plistlib. -- Issue #16787: Increase asyncore and asynchat default output buffers size, to - decrease CPU usage and increase throughput. +IDLE +---- -- Issue #10527: make multiprocessing use poll() instead of select() if available. +- Issue #17390: Add Python version to Idle editor window title bar. + Original patches by Edmond Burnett and Kent Johnson. -- Issue #16688: Now regexes contained backreferences correctly work with - non-ASCII strings. Patch by Matthew Barnett. +- Issue #18960: IDLE now ignores the source encoding declaration on the second + line if the first line contains anything except a comment. -- Issue #16486: Make aifc files act as context managers. +Tests +----- -- Issue #16485: Now file descriptors are closed if file header patching failed - on closing an aifc file. +- Issue #20358: Tests for curses.window.overlay and curses.window.overwrite + no longer specify min{row,col} > max{row,col}. -- Issue #16640: Run less code under a lock in sched module. +- Issue #19804: The test_find_mac test in test_uuid is now skipped if the + ifconfig executable is not available. -- Issue #16165: sched.scheduler.run() no longer blocks a scheduler for other - threads. +- Issue #19886: Use better estimated memory requirements for bigmem tests. -- Issue #16641: Default values of sched.scheduler.enter() are no longer - modifiable. +Tools/Demos +----------- -- Issue #16618: Make glob.glob match consistently across strings and bytes - regarding leading dots. Patch by Serhiy Storchaka. +- Issue #20390: Argument Clinic's "file" output preset now defaults to + "{dirname}/clinic/{basename}.h". -- Issue #16788: Add samestat to Lib/ntpath.py +- Issue #20390: Argument Clinic's "class" directive syntax has been extended + with two new required arguments: "typedef" and "type_object". -- Issue #16713: Parsing of 'tel' urls using urlparse separates params from - path. +- Issue #20390: Argument Clinic: If __new__ or __init__ functions didn't use + kwargs (or args), the PyArg_NoKeywords (or PyArg_NoPositional) calls + generated are only run when the type object is an exact match. -- Issue #16443: Add docstrings to regular expression match objects. - Patch by Anton Kasyanov. +- Issue #20390: Argument Clinic now fails if you have required parameters after + optional parameters. -- Issue #15701: Fix HTTPError info method call to return the headers information. +- Issue #20390: Argument Clinic converters now have a new template they can + inject code into: "modifiers". Code put there is run in the parsing + function after argument parsing but before the call to the impl. -- Issue #16752: Add a missing import to modulefinder. Patch by Berker Peksag. +- Issue #20376: Argument Clinic now escapes backslashes in docstrings. -- Issue #16646: ftplib.FTP.makeport() might lose socket error details. - (patch by Serhiy Storchaka) +- Issue #20381: Argument Clinic now sanity checks the default argument when + c_default is also specified, providing a nice failure message for + disallowed values. -- Issue #16626: Fix infinite recursion in glob.glob() on Windows when the - pattern contains a wildcard in the drive or UNC path. Patch by Serhiy - Storchaka. +- Issue #20189: Argument Clinic now ensures that parser functions for + __new__ are always of type newfunc, the type of the tp_new slot. + Similarly, parser functions for __init__ are now always of type initproc, + the type of tp_init. -- Issue #15783: Except for the number methods, the C version of decimal now - supports all None default values present in decimal.py. These values were - largely undocumented. +- Issue #20189: Argument Clinic now suppresses the docstring for __new__ + and __init__ functions if no docstring is provided in the input. -- Issue #11175: argparse.FileType now accepts encoding and errors - arguments. Patch by Lucas Maystre. +- Issue #20189: Argument Clinic now suppresses the "self" parameter in the + impl for @staticmethod functions. -- Issue #16488: epoll() objects now support the `with` statement. Patch - by Serhiy Storchaka. +- Issue #20294: Argument Clinic now supports argument parsing for __new__ and + __init__ functions. -- Issue #16298: In HTTPResponse.read(), close the socket when there is no - Content-Length and the incoming stream is finished. Patch by Eran - Rundstein. +- Issue #20299: Argument Clinic custom converters may now change the default + value of c_default and py_default with a class member. -- Add abc.ABC class to use inheritance rather than a direct invocation of - ABCMeta metaclass. Patch by Bruno Dupuis. +- Issue #20287: Argument Clinic's output is now configurable, allowing + delaying its output or even redirecting it to a separate file. -- Expose the TCP_FASTOPEN and MSG_FASTOPEN flags in socket when they're - available. +- Issue #20226: Argument Clinic now permits simple expressions + (e.g. "sys.maxsize - 1") as default values for parameters. -- Issue #15701: Add a .headers attribute to urllib.error.HTTPError. Patch - contributed by Berker Peksag. +- Issue #19936: Added executable bits or shebang lines to Python scripts which + requires them. Disable executable bits and shebang lines in test and + benchmark files in order to prevent using a random system python, and in + source files of modules which don't provide command line interface. Fixed + shebang lines in the unittestgui and checkpip scripts. -- Issue #15872: Fix 3.3 regression introduced by the new fd-based shutil.rmtree - that caused it to not ignore certain errors when ignore_errors was set. - Patch by Alessandro Moura and Serhiy Storchaka. +- Issue #20268: Argument Clinic now supports cloning the parameters and + return converter of existing functions. -- Issue #16248: Disable code execution from the user's home directory by - tkinter when the -E flag is passed to Python. Patch by Zachary Ware. +- Issue #20228: Argument Clinic now has special support for class special + methods. -- Issue #13390: New function :func:`sys.getallocatedblocks()` returns the - number of memory blocks currently allocated. +- Issue #20214: Fixed a number of small issues and documentation errors in + Argument Clinic (see issue for details). -- Issue #16628: Fix a memory leak in ctypes.resize(). +- Issue #20196: Fixed a bug where Argument Clinic did not generate correct + parsing code for functions with positional-only parameters where all arguments + are optional. -- Issue #13614: Fix setup.py register failure with invalid rst in description. - Patch by Julien Courteau and Pierre Paul Lefebvre. +- Issue #18960: 2to3 and the findnocoding.py script now ignore the source + encoding declaration on the second line if the first line contains anything + except a comment. -- Issue #13512: Create ~/.pypirc securely (CVE-2011-4944). Initial patch by - Philip Jenvey, tested by Mageia and Debian. +- Issue #19723: The marker comments Argument Clinic uses have been changed + to improve readability. -- Issue #7719: Make distutils ignore ``.nfs*`` files instead of choking later - on. Initial patch by SilentGhost and Jeff Ramnani. +- Issue #20157: When Argument Clinic renames a parameter because its name + collides with a C keyword, it no longer exposes that rename to PyArg_Parse. -- Issue #13120: Allow to call pdb.set_trace() from thread. - Patch by Ilya Sandler. +- Issue #20141: Improved Argument Clinic's support for the PyArg_Parse "O!" + format unit. -- Issue #16585: Make CJK encoders support error handlers that return bytes per - PEP 383. +- Issue #20144: Argument Clinic now supports simple symbolic constants + as parameter default values. -- Issue #10182: The re module doesn't truncate indices to 32 bits anymore. - Patch by Serhiy Storchaka. +- Issue #20143: The line numbers reported in Argument Clinic errors are + now more accurate. -- Issue #16333: use (",", ": ") as default separator when indent is specified - to avoid trailing whitespace. Patch by Serhiy Storchaka. +- Issue #20142: Py_buffer variables generated by Argument Clinic are now + initialized with a default value. -- Issue #16573: In 2to3, treat enumerate() like a consuming call, so superfluous - list() calls aren't added to filter(), map(), and zip() which are directly - passed enumerate(). +Build +----- -- Issue #12848: The pure Python pickle implementation now treats object - lengths as unsigned 32-bit integers, like the C implementation does. - Patch by Serhiy Storchaka. +- Issue #12837: Silence a tautological comparison warning on OS X under Clang in + socketmodule.c. -- Issue #16423: urllib.request now has support for ``data:`` URLs. Patch by - Mathias Panzenböck. +What's New in Python 3.4.0 Beta 2? +================================== -- Issue #4473: Add a POP3.stls() to switch a clear-text POP3 session into - an encrypted POP3 session, on supported servers. Patch by Lorenzo Catucci. +Release date: 2014-01-05 -- Issue #4473: Add a POP3.capa() method to query the capabilities advertised - by the POP3 server. Patch by Lorenzo Catucci. +Core and Builtins +----------------- -- Issue #4473: Ensure the socket is shutdown cleanly in POP3.close(). - Patch by Lorenzo Catucci. +- Issue #17432: Drop UCS2 from names of Unicode functions in python3.def. -- Issue #16522: added FAIL_FAST flag to doctest. +- Issue #19526: Exclude all new API from the stable ABI. Exceptions can be + made if a need is demonstrated. -- Issue #15627: Add the importlib.abc.InspectLoader.source_to_code() method. +- Issue #19969: PyBytes_FromFormatV() now raises an OverflowError if "%c" + argument is not in range [0; 255]. -- Issue #16408: Fix file descriptors not being closed in error conditions - in the zipfile module. Patch by Serhiy Storchaka. +- Issue #19995: %c, %o, %x, and %X now issue a DeprecationWarning on non-integer + input; reworded docs to clarify that an integer type should define both __int__ + and __index__. -- Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak - references to bound methods. +- Issue #19787: PyThread_set_key_value() now always set the value. In Python + 3.3, the function did nothing if the key already exists (if the current value + is a non-NULL pointer). -- Issue #16469: Fix exceptions from float -> Fraction and Decimal -> Fraction - conversions for special values to be consistent with those for float -> int - and Decimal -> int. Patch by Alexey Kachayev. +- Issue #14432: Remove the thread state field from the frame structure. Fix a + crash when a generator is created in a C thread that is destroyed while the + generator is still used. The issue was that a generator contains a frame, and + the frame kept a reference to the Python state of the destroyed C thread. The + crash occurs when a trace function is setup. -- Issue #16481: multiprocessing no longer leaks process handles on Windows. +- Issue #19576: PyGILState_Ensure() now initializes threads. At startup, Python + has no concrete GIL. If PyGILState_Ensure() is called from a new thread for + the first time and PyEval_InitThreads() was not called yet, a GIL needs to be + created. -- Issue #12428: Add a pure Python implementation of functools.partial(). - Patch by Brian Thorne. +- Issue #17576: Deprecation warning emitted now when __int__() or __index__() + return not int instance. -- Issue #16140: The subprocess module no longer double closes its child - subprocess.PIPE parent file descriptors on child error prior to exec(). +- Issue #19932: Fix typo in import.h, missing whitespaces in function prototypes. -- Remove a bare print to stdout from the subprocess module that could have - happened if the child process wrote garbage to its pre-exec error pipe. +- Issue #19736: Add module-level statvfs constants defined for GNU/glibc + based systems. -- The subprocess module now raises its own SubprocessError instead of a - RuntimeError in various error situations which should not normally happen. +- Issue #20097: Fix bad use of "self" in importlib's WindowsRegistryFinder. -- Issue #16327: The subprocess module no longer leaks file descriptors - used for stdin/stdout/stderr pipes to the child when fork() fails. +- Issue #19729: In str.format(), fix recursive expansion in format spec. -- Issue #14396: Handle the odd rare case of waitpid returning 0 when not - expected in subprocess.Popen.wait(). +- Issue #19638: Fix possible crash / undefined behaviour from huge (more than 2 + billion characters) input strings in _Py_dg_strtod. -- Issue #16411: Fix a bug where zlib.decompressobj().flush() might try to access - previously-freed memory. Patch by Serhiy Storchaka. +Library +------- -- Issue #16357: fix calling accept() on a SSLSocket created through - SSLContext.wrap_socket(). Original patch by Jeff McNeil. +- Issue #20154: Deadlock in asyncio.StreamReader.readexactly(). -- Issue #16409: The reporthook callback made by the legacy - urllib.request.urlretrieve API now properly supplies a constant non-zero - block_size as it did in Python 3.2 and 2.7. This matches the behavior of - urllib.request.URLopener.retrieve. +- Issue #16113: Remove sha3 module again. -- Issue #16431: Use the type information when constructing a Decimal subtype - from a Decimal argument. +- Issue #20111: pathlib.Path.with_suffix() now sanity checks the given suffix. -- Issue #15641: Clean up deprecated classes from importlib - Patch by Taras Lyapun. +- Fix breakage in TestSuite.countTestCases() introduced by issue #11798. -- Issue #16350: zlib.decompressobj().decompress() now accumulates data from - successive calls after EOF in unused_data, instead of only saving the argument - to the last call. decompressobj().flush() now correctly sets unused_data and - unconsumed_tail. A bug in the handling of MemoryError when setting the - unconsumed_tail attribute has also been fixed. Patch by Serhiy Storchaka. +- Issue #20108: Avoid parameter name clash in inspect.getcallargs(). -- Issue #12759: sre_parse now raises a proper error when the name of the group - is missing. Initial patch by Serhiy Storchaka. +- Issue #19918: Fix PurePath.relative_to() under Windows. -- Issue #16152: fix tokenize to ignore whitespace at the end of the code when - no newline is found. Patch by Ned Batchelder. +- Issue #19422: Explicitly disallow non-SOCK_STREAM sockets in the ssl + module, rather than silently let them emit clear text data. -- Issue #16284: Prevent keeping unnecessary references to worker functions - in concurrent.futures ThreadPoolExecutor. +- Issue #20046: Locale alias table no longer contains entities which can be + calculated. Generalized support of the euro modifier. -- Issue #16230: Fix a crash in select.select() when one the lists changes - size while iterated on. Patch by Serhiy Storchaka. +- Issue #20027: Fixed locale aliases for devanagari locales. -- Issue #16228: Fix a crash in the json module where a list changes size - while it is being encoded. Patch by Serhiy Storchaka. +- Issue #20067: Tkinter variables now work when wantobjects is false. -- Issue #16351: New function gc.get_stats() returns per-generation collection - statistics. +- Issue #19020: Tkinter now uses splitlist() instead of split() in configure + methods. -- Issue #14897: Enhance error messages of struct.pack and - struct.pack_into. Patch by Matti Mäki. +- Issue #19744: ensurepip now provides a better error message when Python is + built without SSL/TLS support (pip currently requires that support to run, + even if only operating with local wheel files) -- Issue #16316: mimetypes now recognizes the .xz and .txz (.tar.xz) extensions. - Patch by Serhiy Storchaka. +- Issue #19734: ensurepip now ignores all pip environment variables to avoid + odd behaviour based on user configuration settings -- Issue #12890: cgitb no longer prints spurious

tags in text - mode when the logdir option is specified. +- Fix TypeError on "setup.py upload --show-response". -- Issue #16307: Fix multiprocessing.Pool.map_async not calling its callbacks. - Patch by Janne Karila. +- Issue #20045: Fix "setup.py register --list-classifiers". -- Issue #16305: Fix a segmentation fault occurring when interrupting - math.factorial. +- Issue #18879: When a method is looked up on a temporary file, avoid closing + the file before the method is possibly called. -- Issue #16116: Fix include and library paths to be correct when building C - extensions in venvs. +- Issue #20037: Avoid crashes when opening a text file late at interpreter + shutdown. -- Issue #16245: Fix the value of a few entities in html.entities.html5. +- Issue #19967: Thanks to the PEP 442, asyncio.Future now uses a + destructor to log uncaught exceptions, instead of the dedicated + _TracebackLogger class. -- Issue #16301: Fix the localhost verification in urllib/request.py for file:// - urls. +- Added a Task.current_task() class method to asyncio. -- Issue #16250: Fix the invocations of URLError which had misplaced filename - attribute for exception. +- Issue #19850: Set SA_RESTART in asyncio when registering a signal + handler to limit EINTR occurrences. -- Issue #10836: Fix exception raised when file not found in urlretrieve - Initial patch by Ezio Melotti. +- Implemented write flow control in asyncio for proactor event loop (Windows). -- Issue #14398: Fix size truncation and overflow bugs in the bz2 module. +- Change write buffer in asyncio use to avoid O(N**2) behavior. Make + write()/sendto() accept bytearray/memoryview. -- Issue #12692: Fix resource leak in urllib.request when talking to an HTTP - server that does not include a ``Connection: close`` header in its responses. +- Issue #20034: Updated alias mapping to most recent locale.alias file + from X.org distribution using makelocalealias.py. -- Issue #12034: Fix bogus caching of result in check_GetFinalPathNameByHandle. - Patch by Atsuo Ishimoto. +- Issue #5815: Fixed support for locales with modifiers. Fixed support for + locale encodings with hyphens. -- Improve performance of `lzma.LZMAFile`. +- Issue #20026: Fix the sqlite module to handle correctly invalid isolation + level (wrong type). -- Issue #16220: wsgiref now always calls close() on an iterable response. - Patch by Brent Tubbs. +- Issue #18829: csv.Dialect() now checks type for delimiter, escapechar and + quotechar fields. Original patch by Vajrasky Kok. -- Issue #16270: urllib may hang when used for retrieving files via FTP by using - a context manager. Patch by Giampaolo Rodola'. +- Issue #19855: uuid.getnode() on Unix now looks on the PATH for the + executables used to find the mac address, with /sbin and /usr/sbin as + fallbacks. -- Issue #16461: Wave library should be able to deal with 4GB wav files, - and sample rate of 44100 Hz. +- Issue #20007: HTTPResponse.read(0) no more prematurely closes connection. + Original patch by Simon Sapin. -- Issue #16176: Properly identify Windows 8 via platform.platform() +- Issue #19946: multiprocessing now uses runpy to initialize __main__ in + child processes when necessary, allowing it to correctly handle scripts + without suffixes and submodules that use explicit relative imports or + otherwise rely on parent modules being correctly imported prior to + execution. -- Issue #16088: BaseHTTPRequestHandler's send_error method includes a - Content-Length header in it's response now. Patch by Antoine Pitrou. +- Issue #19921: When Path.mkdir() is called with parents=True, any missing + parent is created with the default permissions, ignoring the mode argument + (mimicking the POSIX "mkdir -p" command). -- 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 - keyword arguments specified a path that did not exist. +- Issue #19887: Improve the Path.resolve() algorithm to support certain + symlink chains. -- Issue #16169: Fix ctypes.WinError()'s confusion between errno and winerror. +- Issue #19912: Fixed numerous bugs in ntpath.splitunc(). -- Issue #1492704: shutil.copyfile() raises a distinct SameFileError now if - source and destination are the same file. Patch by Atsuo Ishimoto. +- Issue #19911: ntpath.splitdrive() now correctly processes the 'İ' character + (U+0130, LATIN CAPITAL LETTER I WITH DOT ABOVE). -- Issue #13896: Make shelf instances work with 'with' as context managers. - Original patch by Filip Gruszczyński. +- Issue #19532: python -m compileall with no filename/directory arguments now + respects the -f and -q flags instead of ignoring them. -- Issue #15417: Add support for csh and fish in venv activation scripts. +- Issue #19623: Fixed writing to unseekable files in the aifc module. -- Issue #14377: ElementTree.write and some of the module-level functions have - a new parameter - *short_empty_elements*. It controls how elements with no - contents are emitted. +- Issue #19946: multiprocessing.spawn now raises ImportError when the module to + be used as the main module cannot be imported. -- Issue #16089: Allow ElementTree.TreeBuilder to work again with a non-Element - element_factory (fixes a regression in SimpleTAL). +- Issue #17919: select.poll.register() again works with poll.POLLNVAL on AIX. + Fixed integer overflow in the eventmask parameter. -- Issue #9650: List commonly used format codes in time.strftime and - time.strptime docsttings. Original patch by Mike Hoy. +- Issue #19063: if a Charset's body_encoding was set to None, the email + package would generate a message claiming the Content-Transfer-Encoding + was 7bit, and produce garbage output for the content. This now works. + A couple of other set_payload mishandlings of non-ASCII are also fixed. + In addition, calling set_payload with a string argument without + specifying a charset now raises an error (this is a new error in 3.4). -- Issue #16034: Fix performance regressions in the new `bz2.BZ2File` - implementation. Initial patch by Serhiy Storchaka. +- Issue #15475: Add __sizeof__ implementations for itertools objects. -- `pty.spawn()` now returns the child process status returned by `os.waitpid()`. +- Issue #19944: Fix importlib.find_spec() so it imports parents as needed + and move the function to importlib.util. -- Issue #15756: `subprocess.poll()` now properly handles `errno.ECHILD` to - return a returncode of 0 when the child has already exited or cannot be waited - on. +- Issue #19880: Fix a reference leak in unittest.TestCase. Explicitly break + reference cycles between frames and the _Outcome instance. -- Issue #15323: Improve failure message of `Mock.assert_called_once_with()`. +- Issue #17429: platform.linux_distribution() now decodes files from the UTF-8 + encoding with the surrogateescape error handler, instead of decoding from the + locale encoding in strict mode. It fixes the function on Fedora 19 which is + probably the first major distribution release with a non-ASCII name. Patch + written by Toshio Kuratomi. -- Issue #16064: ``unittest -m`` claims executable is "python", not "python3". +- Issue #19343: Expose FreeBSD-specific APIs in resource module. Original + patch by Koobs. -- Issue #12376: Pass on parameters in `TextTestResult.__init__()` super call. +- Issue #19929: Call os.read with 32768 within subprocess.Popen.communicate + rather than 4096 for efficiency. A microbenchmark shows Linux and OS X + both using ~50% less cpu time this way. -- Issue #15222: Insert blank line after each message in mbox mailboxes. +- Issue #19506: Use a memoryview to avoid a data copy when piping data + to stdin within subprocess.Popen.communicate. 5-10% less cpu usage. -- Issue #16013: Fix `csv.Reader` parsing issue with ending quote characters. - Patch by Serhiy Storchaka. +- Issue #19876: selectors unregister() no longer raises ValueError or OSError + if the FD is closed (as long as it was registered). -- Issue #15421: Fix an OverflowError in `Calendar.itermonthdates()` after - `datetime.MAXYEAR`. Patch by Cédric Krier. +- Issue #19908: pathlib now joins relative Windows paths correctly when a drive + is present. Original patch by Antoine Pitrou. -- Issue #16112: platform.architecture does not correctly escape argument to - /usr/bin/file. Patch by David Benjamin. +- Issue #19296: Silence compiler warning in dbm_open -- Issue #15970: `xml.etree.ElementTree` now serializes correctly the empty HTML - elements 'meta' and 'param'. - -- Issue #15842: The `SocketIO.{readable,writable,seekable}` methods now raise - ValueError when the file-like object is closed. Patch by Alessandro Moura. - -- Issue #15876: Fix a refleak in the `curses` module: window.encoding. - -- Issue #15881: Fix `atexit` hook in `multiprocessing`. Original patch by Chris - McDonough. - -- Issue #15841: The readable(), writable() and seekable() methods of - `io.BytesIO` and `io.StringIO` objects now raise ValueError when the object - has been closed. Patch by Alessandro Moura. - -- Issue #15447: Use `subprocess.DEVNULL` in webbrowser, instead of opening - `os.devnull` explicitly and leaving it open. - -- Issue #15509: `webbrowser.UnixBrowser` no longer passes empty arguments to - Popen when ``%action`` substitutions produce empty strings. - -- Issue #12776, issue #11839: Call `argparse` type function (specified by - add_argument) only once. Before, the type function was called twice in the - case where the default was specified and the argument was given as well. This - was especially problematic for the FileType type, as a default file would - always be opened, even if a file argument was specified on the command line. - -- Issue #15906: Fix a regression in argparse caused by the preceding change, - when ``action='append'``, ``type='str'`` and ``default=[]``. - -- Issue #16113: Added sha3 module based on the Keccak reference implementation - 3.2. The `hashlib` module has four additional hash algorithms: `sha3_224`, - `sha3_256`, `sha3_384` and `sha3_512`. As part of the patch some common - code was moved from _hashopenssl.c to hashlib.h. - -- ctypes.call_commethod was removed, since its only usage was in the defunct - samples directory. - -- Issue #16692: Added TLSv1.1 and TLSv1.2 support for the ssl modules. - -- Issue #16832: add abc.get_cache_token() to expose cache validity checking - support in ABCMeta. - -IDLE ----- - -- Issue #18429: Format / Format Paragraph, now works when comment blocks - are selected. As with text blocks, this works best when the selection - only includes complete lines. - -- Issue #18226: Add docstrings and unittests for FormatParagraph.py. - Original patches by Todd Rovito and Phil Webster. - -- Issue #18279: Format - Strip trailing whitespace no longer marks a file as - changed when it has not been changed. This fix followed the addition of a - test file originally written by Phil Webster (the issue's main goal). - -- Issue #7136: In the Idle File menu, "New Window" is renamed "New File". - Patch by Tal Einat, Roget Serwy, and Todd Rovito. - -- Remove dead imports of imp. - -- Issue #18196: Avoid displaying spurious SystemExit tracebacks. - -- Issue #5492: Avoid traceback when exiting IDLE caused by a race condition. - -- Issue #17511: Keep IDLE find dialog open after clicking "Find Next". - Original patch by Sarah K. - -- Issue #18055: Move IDLE off of imp and on to importlib. - -- Issue #15392: Create a unittest framework for IDLE. - Initial patch by Rajagopalasarma Jayakrishnan. - See Lib/idlelib/idle_test/README.txt for how to run Idle tests. - -- Issue #14146: Highlight source line while debugging on Windows. - -- Issue #17838: Allow sys.stdin to be reassigned. - -- Issue #13495: Avoid loading the color delegator twice in IDLE. - -- Issue #17798: Allow IDLE to edit new files when specified on command line. - -- Issue #14735: Update IDLE docs to omit "Control-z on Windows". - -- Issue #17532: Always include Options menu for IDLE on OS X. - Patch by Guilherme Simões. - -- Issue #17585: Fixed IDLE regression. Now closes when using exit() or quit(). - -- Issue #17657: Show full Tk version in IDLE's about dialog. - Patch by Todd Rovito. - -- Issue #17613: Prevent traceback when removing syntax colorizer in IDLE. - -- Issue #1207589: Backwards-compatibility patch for right-click menu in IDLE. - -- Issue #16887: IDLE now accepts Cancel in tabify/untabify dialog box. - -- Issue #17625: In IDLE, close the replace dialog after it is used. - -- Issue #14254: IDLE now handles readline correctly across shell restarts. - -- Issue #17614: IDLE no longer raises exception when quickly closing a file. - -- Issue #6698: IDLE now opens just an editor window when configured to do so. - -- Issue #8900: Using keyboard shortcuts in IDLE to open a file no longer - raises an exception. - -- Issue #6649: Fixed missing exit status in IDLE. Patch by Guilherme Polo. - -- Issue #17114: IDLE now uses non-strict config parser. - -- Issue #9290: In IDLE the sys.std* streams now implement io.TextIOBase - interface and support all mandatory methods and properties. - -- Issue #5066: Update IDLE docs. Patch by Todd Rovito. - -- Issue #16829: IDLE printing no longer fails if there are spaces or other - special characters in the file path. - -- Issue #16491: IDLE now prints chained exception tracebacks. - -- Issue #16819: IDLE method completion now correctly works for bytes literals. - -- Issue #16504: IDLE now catches SyntaxErrors raised by tokenizer. Patch by - Roger Serwy. - -- Issue #16511: Use default IDLE width and height if config param is not valid. - Patch Serhiy Storchaka. - -- Issue #1207589: Add Cut/Copy/Paste items to IDLE right click Context Menu - Patch by Todd Rovito. - -- Issue #16123: IDLE - deprecate running without a subprocess. - Patch by Roger Serwy. - -Tests ------ - -- Issue #1666318: Add a test that shutil.copytree() retains directory - permissions. Patch by Catherine Devlin. - -- Issue #18273: move the tests in Lib/test/json_tests to Lib/test/test_json - and make them discoverable by unittest. Patch by Zachary Ware. - -- Fix a fcntl test case on KFreeBSD, Debian #708653 (Petr Salinger). - -- Issue #18396: Fix spurious test failure in test_signal on Windows when - faulthandler is enabled (Patch by Jeremy Kloth) - -- Issue #17046: Fix broken test_executable_without_cwd in test_subprocess. - -- Issue #15415: Add new temp_dir() and change_cwd() context managers to - test.support, and refactor temp_cwd() to use them. Patch by Chris Jerdonek. - -- Issue #15494: test.support is now a package rather than a module (Initial - patch by Indra Talip) - -- Issue #17944: test_zipfile now discoverable and uses subclassing to - generate tests for different compression types. Fixed a bug with skipping - some tests due to use of exhausted iterators. - -- Issue #18266: test_largefile now works with unittest test discovery and - supports running only selected tests. Patch by Zachary Ware. - -- Issue #17767: test_locale now works with unittest test discovery. - Original patch by Zachary Ware. - -- Issue #18375: Assume --randomize when --randseed is used for running the - testsuite. - -- Issue #11185: Fix test_wait4 under AIX. Patch by Sébastien Sablé. - -- Issue #18207: Fix test_ssl for some versions of OpenSSL that ignore seconds - in ASN1_TIME fields. - -- Issue #18094: test_uuid no more reports skipped tests as passed. - -- Issue #17992: Add timeouts to asyncore and asynchat tests so that they won't - accidentally hang. - -- Issue #17833: Fix test_gdb failures seen on machines where debug symbols - for glibc are available (seen on PPC64 Linux). - -- Issue #7855: Add tests for ctypes/winreg for issues found in IronPython. - Initial patch by Dino Viehland. - -- Issue #11078: test___all__ now checks for duplicates in __all__. - Initial patch by R. David Murray. - -- Issue #17712: Fix test_gdb failures on Ubuntu 13.04. - -- Issue #17835: Fix test_io when the default OS pipe buffer size is larger - than one million bytes. - -- Issue #17065: Use process-unique key for winreg tests to avoid failures if - test is run multiple times in parallel (eg: on a buildbot host). - -- Issue #12820: add tests for the xml.dom.minicompat module. - Patch by John Chandler and Phil Connell. - -- Issue #17691: test_univnewlines now works with unittest test discovery. - Patch by Zachary Ware. - -- Issue #17790: test_set now works with unittest test discovery. - Patch by Zachary Ware. - -- Issue #17789: test_random now works with unittest test discovery. - Patch by Zachary Ware. - -- Issue #17779: test_osx_env now works with unittest test discovery. - Patch by Zachary Ware. - -- Issue #17766: test_iterlen now works with unittest test discovery. - Patch by Zachary Ware. - -- Issue #17690: test_time now works with unittest test discovery. - Patch by Zachary Ware. - -- Issue #17692: test_sqlite now works with unittest test discovery. - Patch by Zachary Ware. - -- Issue #11995: test_pydoc doesn't import all sys.path modules anymore. - -- Issue #17448: test_sax now skips if there are no xml parsers available - instead of raising an ImportError. - -- Issue #11420: make test suite pass with -B/DONTWRITEBYTECODE set. - Initial patch by Thomas Wouters. - -- Issue #10652: make tcl/tk tests run after __all__ test, patch by - Zachary Ware. - -- Issue #11963: remove human verification from test_parser and test_subprocess. - -- Issue #11732: add a new suppress_crash_popup() context manager to test.support - that disables crash popups on Windows and use it in test_faulthandler and - test_capi. - -- Issue #13898: test_ssl no longer prints a spurious stack trace on Ubuntu. - -- Issue #17283: Share code between `__main__.py` and `regrtest.py` in - `Lib/test`. - -- Issue #17249: convert a test in test_capi to use unittest and reap threads. - -- Issue #17107: Test client-side SNI support in urllib.request thanks to - the new server-side SNI support in the ssl module. Initial patch by - Daniel Black. - -- Issue #17041: Fix testing when Python is configured with the - --without-doc-strings. - -- Issue #16923: Fix ResourceWarnings in test_ssl. - -- Issue #15539: Added regression tests for Tools/scripts/pindent.py. - -- Issue #16836: Enable IPv6 support even if IPv6 is disabled on the build host. - -- Issue #17479: test_io now works with unittest test discovery. - Patch by Zachary Ware. - -- Issue #17066: test_robotparser now works with unittest test discovery. - Patch by Zachary Ware. - -- Issue #17334: test_index now works with unittest test discovery. - Patch by Zachary Ware. - -- Issue #17333: test_imaplib now works with unittest test discovery. - Patch by Zachary Ware. - -- Issue #17082: test_dbm* now work with unittest test discovery. - Patch by Zachary Ware. - -- Issue #17079: test_ctypes now works with unittest test discovery. - Patch by Zachary Ware. - -- Issue #17304: test_hash now works with unittest test discovery. - Patch by Zachary Ware. - -- Issue #17303: test_future* now work with unittest test discovery. - Patch by Zachary Ware. - -- Issue #17163: test_file now works with unittest test discovery. - Patch by Zachary Ware. - -- Issue #16925: test_configparser now works with unittest test discovery. - Patch by Zachary Ware. - -- Issue #16918: test_codecs now works with unittest test discovery. - Patch by Zachary Ware. - -- Issue #16919: test_crypt now works with unittest test discovery. - Patch by Zachary Ware. - -- Issue #16910: test_bytes, test_unicode, and test_userstring now work with - unittest test discovery. Patch by Zachary Ware. - -- Issue #16905: test_warnings now works with unittest test discovery. - Initial patch by Berker Peksag. - -- Issue #16898: test_bufio now works with unittest test discovery. - Patch by Zachary Ware. - -- Issue #16888: test_array now works with unittest test discovery. - Patch by Zachary Ware. - -- Issue #16896: test_asyncore now works with unittest test discovery. - Patch by Zachary Ware. - -- Issue #16897: test_bisect now works with unittest test discovery. - Initial patch by Zachary Ware. - -- Issue #16852: test_genericpath, test_posixpath, test_ntpath, and test_macpath - now work with unittest test discovery. Patch by Zachary Ware. - -- Issue #16748: test_heapq now works with unittest test discovery. - -- Issue #10646: Tests rearranged for os.samefile/samestat to check for not - just symlinks but also hard links. - -- Issue #15302: Switch regrtest from using getopt to using argparse. - -- Issue #15324: Fix regrtest parsing of --fromfile, --match, and --randomize - options. - -- Issue #16702: test_urllib2_localnet tests now correctly ignores proxies for - localhost tests. - -- Issue #16664: Add regression tests for glob's behaviour concerning entries - starting with a ".". Patch by Sebastian Kreft. - -- Issue #13390: The ``-R`` option to regrtest now also checks for memory - allocation leaks, using :func:`sys.getallocatedblocks()`. - -- Issue #16559: Add more tests for the json module, including some from the - official test suite at json.org. Patch by Serhiy Storchaka. - -- Issue #16661: Fix the `os.getgrouplist()` test by not assuming that it gives - the same output as :command:`id -G`. - -- Issue #16115: Add some tests for the executable argument to - subprocess.Popen(). Initial patch by Kushal Das. - -- Issue #16126: PyErr_Format format mismatch in _testcapimodule.c. - Patch by Serhiy Storchaka. - -- Issue #15304: Fix warning message when `os.chdir()` fails inside - `test.support.temp_cwd()`. Patch by Chris Jerdonek. - -- Issue #15802: Fix test logic in `TestMaildir.test_create_tmp()`. Patch by - Serhiy Storchaka. - -- Issue #15557: Added a test suite for the webbrowser module, thanks to Anton - Barkovsky. - -- Issue #16698: Skip posix test_getgroups when built with OS X - deployment target prior to 10.6. - -Build ------ - -- Issue #16067: Add description into MSI file to replace installer's - temporary name. - -- Issue #18257: Fix readlink usage in python-config. Install the python - version again on Darwin. - -- Issue #18481: Add C coverage reporting with gcov and lcov. A new make target - "coverage-report" creates an instrumented Python build, runs unit tests - and creates a HTML. The report can be updated with "make coverage-lcov". - -- Issue #17845: Clarified the message printed when some module are not built. - -- Issue #18256: Compilation fix for recent AIX releases. Patch by - David Edelsohn. - -- Issue #17547: In configure, explicitly pass -Wformat for the benefit for GCC - 4.8. - -- Issue #15172: Document NASM 2.10+ as requirement for building OpenSSL 1.0.1 - on Windows. - -- Issue #17591: Use lowercase filenames when including Windows header files. - Patch by Roumen Petrov. - -- Issue #17550: Fix the --enable-profiling configure switch. - -- Issue #17425: Build with openssl 1.0.1d on Windows. - -- Issue #16754: Fix the incorrect shared library extension on linux. Introduce - two makefile macros SHLIB_SUFFIX and EXT_SUFFIX. SO now has the value of - SHLIB_SUFFIX again (as in 2.x and 3.1). The SO macro is removed in 3.4. - -- Issue #5033: Fix building of the sqlite3 extension module when the - SQLite library version has "beta" in it. Patch by Andreas Pelme. - -- Issue #17228: Fix building without pymalloc. - -- Issue #3718: Use AC_ARG_VAR to set MACHDEP in configure.ac. - -- Issue #16235: Implement python-config as a shell script. - -- Issue #16769: Remove outdated Visual Studio projects. - -- Issue #17031: Fix running regen in cross builds. - -- Issue #3754: fix typo in pthread AC_CACHE_VAL. - -- Issue #15484: Fix _PYTHON_PROJECT_BASE for srcdir != builddir builds; - use _PYTHON_PROJECT_BASE in distutils/sysconfig.py. - -- Drop support for Windows 2000. - -- Issue #17029: Let h2py search the multiarch system include directory. - -- Issue #16953: Fix socket module compilation on platforms with - HAVE_BROKEN_POLL. Patch by Jeffrey Armstrong. - -- Issue #16320: Remove redundant Makefile dependencies for strings and bytes. - -- Cross compiling needs host and build settings. configure no longer - creates a broken PYTHON_FOR_BUILD variable when --build is missing. - -- Fix cross compiling issue in setup.py, ensure that lib_dirs and inc_dirs are - defined in cross compiling mode, too. - -- Issue #16593: Have BSD 'make -s' do the right thing, thanks to Daniel Shahaf - -- Issue #16262: fix out-of-src-tree builds, if mercurial is not installed. - -- Issue #15298: ensure _sysconfigdata is generated in build directory, not - source directory. - -- Issue #15833: Fix a regression in 3.3 that resulted in exceptions being - raised if importlib failed to write byte-compiled files. This affected - attempts to build Python out-of-tree from a read-only source directory. - -- Issue #15923: Fix a mistake in ``asdl_c.py`` that resulted in a TypeError - after 2801bf875a24 (see #15801). - -- Issue #16135: Remove OS/2 support. - -- Issue #15819: Make sure we can build Python out-of-tree from a read-only - source directory. (Somewhat related to issue #9860.) - -- Issue #15587: Enable Tk high-resolution text rendering on Macs with - Retina displays. Applies to Tkinter apps, such as IDLE, on OS X - framework builds linked with Cocoa Tk 8.5. - -- Issue #17161: make install now also installs a python3 man page. - -C-API ------ - -- Issue #18351: Fix various issues in a function in importlib provided to help - PyImport_ExecCodeModuleWithPathnames() (and thus by extension - PyImport_ExecCodeModule() and PyImport_ExecCodeModuleEx()). - -- 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. - -- Issue #17206: Py_CLEAR(), Py_DECREF(), Py_XINCREF() and Py_XDECREF() now - expand their arguments once instead of multiple times. Patch written by Illia - Polosukhin. - -- Issue #17522: Add the PyGILState_Check() API. - -- Issue #17327: Add PyDict_SetDefault. - -- Issue #16881: Fix Py_ARRAY_LENGTH macro for GCC < 3.1. - -- Issue #16505: Remove unused Py_TPFLAGS_INT_SUBCLASS. - -- Issue #16086: PyTypeObject.tp_flags and PyType_Spec.flags are now unsigned - (unsigned long and unsigned int) to avoid an undefined behaviour with - Py_TPFLAGS_TYPE_SUBCLASS ((1 << 31). PyType_GetFlags() result type is - now unsigned too (unsigned long, instead of long). - -- Issue #16166: Add PY_LITTLE_ENDIAN and PY_BIG_ENDIAN macros and unified - endianness detection and handling. - -Documentation -------------- - -- Issue #17701: Improving strftime documentation. - -- Issue #18440: Clarify that `hash()` can truncate the value returned from an - object's custom `__hash__()` method. - -- Issue #17844: Add links to encoders and decoders for bytes-to-bytes codecs. - -- Issue #14097: improve the "introduction" page of the tutorial. - -- Issue #17977: The documentation for the cadefault argument's default value - in urllib.request.urlopen() is fixed to match the code. - -- Issue #6696: add documentation for the Profile objects, and improve - profile/cProfile docs. Patch by Tom Pinckney. - -- Issue #15940: Specify effect of locale on time functions. - -- Issue 17538: Document XML vulnerabilties - -- Issue #16642: sched.scheduler timefunc initial default is time.monotonic. - Patch by Ramchandra Apte - -- Issue #17047: remove doubled words in docs and docstrings - reported by Serhiy Storchaka and Matthew Barnett. - -- Issue #15465: Document the versioning macros in the C API docs rather than - the standard library docs. Patch by Kushal Das. - -- Issue #16406: Combine the pages for uploading and registering to PyPI. - -- Issue #16403: Document how distutils uses the maintainer field in - PKG-INFO. Patch by Jyrki Pulliainen. - -- Issue #16695: Document how glob handles filenames starting with a - dot. Initial patch by Jyrki Pulliainen. - -- Issue #8890: Stop advertising an insecure practice by replacing uses - of the /tmp directory with better alternatives in the documentation. - Patch by Geoff Wilson. - -- Issue #17203: add long option names to unittest discovery docs. - -- Issue #13094: add "Why do lambdas defined in a loop with different values - all return the same result?" programming FAQ. - -- Issue #14901: Update portions of the Windows FAQ. - Patch by Ashish Nitin Patil. - -- Issue #16267: Better document the 3.3+ approach to combining - @abstractmethod with @staticmethod, @classmethod and @property - -- Issue #15209: Clarify exception chaining description in exceptions module - documentation - -- Issue #15990: Improve argument/parameter documentation. - -- Issue #16209: Move the documentation for the str built-in function to a new - str class entry in the "Text Sequence Type" section. - -- Issue #13538: Improve str() and object.__str__() documentation. - -- Issue #16489: Make it clearer that importlib.find_loader() needs parent - packages to be explicitly imported. - -- Issue #16400: Update the description of which versions of a given package - PyPI displays. - -- Issue #15677: Document that zlib and gzip accept a compression level of 0 to - mean 'no compression'. Patch by Brian Brazil. - -- Issue #16197: Update winreg docstrings and documentation to match code. - Patch by Zachary Ware. - -- Issue #8040: added a version switcher to the documentation. Patch by - Yury Selivanov. - -- Issue #16241: Document -X faulthandler command line option. - Patch by Marek Šuppa. - -- Additional comments and some style changes in the concurrent.futures URL - retrieval example - -- Issue #16115: Improve subprocess.Popen() documentation around args, shell, - and executable arguments. - -- Issue #13498: Clarify docs of os.makedirs()'s exist_ok argument. Done with - great native-speaker help from R. David Murray. - -- Issue #15533: Clarify docs and add tests for `subprocess.Popen()`'s cwd - argument. - -- Issue #15979: Improve timeit documentation. - -- Issue #16036: Improve documentation of built-in `int()`'s signature and - arguments. - -- Issue #15935: Clarification of `argparse` docs, re: add_argument() type and - default arguments. Patch contributed by Chris Jerdonek. - -- Issue #11964: Document a change in v3.2 to the behavior of the indent - parameter of json encoding operations. - -- Issue #15116: Remove references to appscript as it is no longer being - supported. - -Tools/Demos ------------ - -- Issue #18817: Fix a resource warning in Lib/aifc.py demo. Patch by - Vajrasky Kok. - -- Issue #18439: Make patchcheck work on Windows for ACKS, NEWS. - -- Issue #18448: Fix a typo in Tools/demo/eiffel.py. - -- Issue #18457: Fixed saving of formulas and complex numbers in - Tools/demo/ss1.py. - -- Issue #18449: Make Tools/demo/ss1.py work again on Python 3. Patch by - Févry Thibault. - -- Issue #12990: The "Python Launcher" on OSX could not launch python scripts - that have paths that include wide characters. - -- Issue #15239: Make mkstringprep.py work again on Python 3. - -- Issue #17028: Allowed Python arguments to be supplied to the Windows - launcher. - -- Issue #17156: pygettext.py now uses an encoding of source file and correctly - writes and escapes non-ascii characters. - -- Issue #15539: Fix a number of bugs in Tools/scripts/pindent.py. Now - pindent.py works with a "with" statement. pindent.py no longer produces - improper indentation. pindent.py now works with continued lines broken after - "class" or "def" keywords and with continuations at the start of line. - -- Issue #11797: Add a 2to3 fixer that maps reload() to imp.reload(). - -- Issue #10966: Remove the concept of unexpected skipped tests. - -- Issue #9893: Removed the Misc/Vim directory. - -- Removed the Misc/TextMate directory. - -- Issue #16245: Add the Tools/scripts/parse_html5_entities.py script to parse - the list of HTML5 entities and update the html.entities.html5 dictionary. - -- Issue #15378: Fix Tools/unicode/comparecodecs.py. Patch by Serhiy Storchaka. - -- Issue #16549: Make json.tool work again on Python 3 and add tests. - Initial patch by Berker Peksag and Serhiy Storchaka. - -- Issue #13301: use ast.literal_eval() instead of eval() in Tools/i18n/msgfmt.py - Patch by Serhiy Storchaka. - -Windows -------- - -- Issue #18569: The installer now adds .py to the PATHEXT variable when extensions - are registered. Patch by Paul Moore. - - -What's New in Python 3.3.0? -=========================== - -*Release date: 29-Sep-2012* - -Core and Builtins ------------------ - -- Issue #16046: Fix loading sourceless legacy .pyo files. - -- Issue #16060: Fix refcounting bug when `__trunc__()` returns an object whose - `__int__()` gives a non-integer. Patch by Serhiy Storchaka. - -Extension Modules ------------------ - -- Issue #16012: Fix a regression in pyexpat. The parser's `UseForeignDTD()` - method doesn't require an argument again. - - -What's New in Python 3.3.0 Release Candidate 3? -=============================================== - -*Release date: 23-Sep-2012* - -Core and Builtins ------------------ - -- Issue #15900: Fix reference leak in `PyUnicode_TranslateCharmap()`. - -- Issue #15926: Fix crash after multiple reinitializations of the interpreter. - -- Issue #15895: Fix FILE pointer leak in one error branch of - `PyRun_SimpleFileExFlags()` when filename points to a pyc/pyo file, closeit is - false an and set_main_loader() fails. - -- Fixes for a few crash and memory leak regressions found by Coverity. - -Library -------- - -- Issue #15882: Change `_decimal` to accept any coefficient tuple when - constructing infinities. This is done for backwards compatibility with - decimal.py: Infinity coefficients are undefined in _decimal (in accordance - with the specification). - -- Issue #15925: Fix a regression in `email.util` where the `parsedate()` and - `parsedate_tz()` functions did not return None anymore when the argument could - not be parsed. - -Extension Modules ------------------ - -- Issue #15973: Fix a segmentation fault when comparing datetime timezone - objects. - -- Issue #15977: Fix memory leak in Modules/_ssl.c when the function - _set_npn_protocols() is called multiple times, thanks to Daniel Sommermann. - -- Issue #15969: `faulthandler` module: rename dump_tracebacks_later() to - dump_traceback_later() and cancel_dump_tracebacks_later() to - cancel_dump_traceback_later(). - -- _decimal module: use only C 89 style comments. - - -What's New in Python 3.3.0 Release Candidate 2? -=============================================== - -*Release date: 09-Sep-2012* - -Core and Builtins ------------------ - -- Issue #13992: The trashcan mechanism is now thread-safe. This eliminates - sporadic crashes in multi-thread programs when several long deallocator chains - ran concurrently and involved subclasses of built-in container types. - -- Issue #15784: Modify `OSError`.__str__() to better distinguish between errno - error numbers and Windows error numbers. - -- Issue #15781: Fix two small race conditions in import's module locking. - -Library -------- - -- Issue #17158: Add 'symbols' to help() welcome message; clarify - 'modules spam' messages. - -- Issue #15847: Fix a regression in argparse, which did not accept tuples as - argument lists anymore. - -- Issue #15828: Restore support for C extensions in `imp.load_module()`. - -- Issue #15340: Fix importing the random module when ``/dev/urandom`` cannot be - opened. This was a regression caused by the hash randomization patch. - -- Issue #10650: Deprecate the watchexp parameter of the `Decimal.quantize()` - method. - -- Issue #15785: Modify `window.get_wch()` API of the curses module: return a - character for most keys, and an integer for special keys, instead of always - returning an integer. So it is now possible to distinguish special keys like - keypad keys. - -- Issue #14223: Fix `window.addch()` of the curses module for special characters - like curses.ACS_HLINE: the Python function addch(int) and addch(bytes) is now - calling the C function waddch()/mvwaddch() (as it was done in Python 3.2), - instead of wadd_wch()/mvwadd_wch(). The Python function addch(str) is still - calling the C function wadd_wch()/mvwadd_wch() if the Python curses is linked - to libncursesw. - -Build ------ - -- Issue #15822: Really ensure 2to3 grammar pickles are properly installed - (replaces fixes for Issue #15645). - -Documentation -------------- - -- Issue #15814: The memoryview enhancements in 3.3.0 accidentally permitted the - hashing of multi-dimensional memorviews and memoryviews with multi-byte item - formats. The intended restrictions have now been documented - they will be - correctly enforced in 3.3.1. - - -What's New in Python 3.3.0 Release Candidate 1? -=============================================== - -*Release date: 25-Aug-2012* - -Core and Builtins ------------------ - -- Issue #15573: memoryview comparisons are now performed by value with full - support for any valid struct module format definition. - -- Issue #15316: When an item in the fromlist for `__import__()` doesn't exist, - don't raise an error, but if an exception is raised as part of an import do - let that propagate. - -- Issue #15778: Ensure that ``str(ImportError(msg))`` returns a str even when - msg isn't a str. - -- Issue #2051: Source file permission bits are once again correctly copied to - the cached bytecode file. (The migration to importlib reintroduced this - problem because these was no regression test. A test has been added as part of - this patch) - -- Issue #15761: Fix crash when ``PYTHONEXECUTABLE`` is set on Mac OS X. - -- Issue #15726: Fix incorrect bounds checking in PyState_FindModule. Patch by - Robin Schreiber. - -- Issue #15604: Update uses of `PyObject_IsTrue()` to check for and handle - errors correctly. Patch by Serhiy Storchaka. - -- Issue #14846: `importlib.FileFinder` now handles the case where the directory - being searched is removed after a previous import attempt. - -Library -------- - -- Issue #13248: removed deprecated and undocumented difflib.isbjunk, isbpopular. - -- Issue #13370: Ensure that ctypes works on Mac OS X when Python is compiled - using the clang compiler. - -- Issue #13072: The array module's 'u' format code is now deprecated and will be - removed in Python 4.0. - -- Issue #15544: Fix Decimal.__float__ to work with payload-carrying NaNs. - -- Issue #15776: Allow pyvenv to work in existing directory with --clean. - -- Issue #15249: email's BytesGenerator now correctly mangles From lines (when - requested) even if the body contains undecodable bytes. - -- Issue #15777: Fix a refleak in _posixsubprocess. - -- Issue ##665194: Update `email.utils.localtime` to use datetime.astimezone and - correctly handle historic changes in UTC offsets. - -- Issue #15199: Fix JavaScript's default MIME type to application/javascript. - Patch by Bohuslav Kabrda. - -- Issue #12643: `code.InteractiveConsole` now respects `sys.excepthook` when - displaying exceptions. Patch by Aaron Iles. - -- Issue #13579: `string.Formatter` now understands the 'a' conversion specifier. - -- Issue #15595: Fix ``subprocess.Popen(universal_newlines=True)`` for certain - locales (utf-16 and utf-32 family). Patch by Chris Jerdonek. - -- Issue #15477: In cmath and math modules, add workaround for platforms whose - system-supplied log1p function doesn't respect signs of zeros. - -- Issue #15715: `importlib.__import__()` will silence an ImportError when the - use of fromlist leads to a failed import. - -- Issue #14669: Fix pickling of connections and sockets on Mac OS X by - sending/receiving an acknowledgment after file descriptor transfer. - TestPicklingConnection has been reenabled for Mac OS X. - -- Issue #11062: Fix adding a message from file to Babyl mailbox. - -- Issue #15646: Prevent equivalent of a fork bomb when using `multiprocessing` - on Windows without the ``if __name__ == '__main__'`` idiom. - -IDLE ----- - -- Issue #15678: Fix IDLE menus when started from OS X command line (3.3.0b2 - regression). - -Documentation -------------- - -- Touched up the Python 2 to 3 porting guide. - -- Issue #14674: Add a discussion of the `json` module's standard compliance. - Patch by Chris Rebert. - -- Create a 'Concurrent Execution' section in the docs, and split up the - 'Optional Operating System Services' section to use a more user-centric - classification scheme (splitting them across the new CE section, IPC and text - processing). Operating system limitations can be reflected with the Sphinx - ``:platform:`` tag, it doesn't make sense as part of the Table of Contents. - -- Issue #4966: Bring the sequence docs up to date for the Py3k transition and - the many language enhancements since they were original written. - -- The "path importer" misnomer has been replaced with Eric Snow's - more-awkward-but-at-least-not-wrong suggestion of "path based finder" in the - import system reference docs. - -- Issue #15640: Document `importlib.abc.Finder` as deprecated. - -- Issue #15630: Add an example for "continue" stmt in the tutorial. Patch by - Daniel Ellis. - -Tests ------ - -- Issue #15747: ZFS always returns EOPNOTSUPP when attempting to set the - UF_IMMUTABLE flag (via either chflags or lchflags); refactor affected tests in - test_posix.py to account for this. - -- Issue #15285: Refactor the approach for testing connect timeouts using two - external hosts that have been configured specifically for this type of test. - -- Issue #15743: Remove the deprecated method usage in `urllib` tests. Patch by - Jeff Knupp. - -- Issue #15615: Add some tests for the `json` module's handling of invalid input - data. Patch by Kushal Das. - -Build ------ - -- Output lib files for PGO build into PGO directory. - -- Pick up 32-bit launcher from PGO directory on 64-bit PGO build. - -- Drop ``PC\python_nt.h`` as it's not used. Add input dependency on custom - build step. - -- Issue #15511: Drop explicit dependency on pythonxy.lib from _decimal amd64 - configuration. - -- Add missing PGI/PGO configurations for pywlauncher. - -- Issue #15645: Ensure 2to3 grammar pickles are properly installed. - - -What's New in Python 3.3.0 Beta 2? -================================== - -*Release date: 12-Aug-2012* - -Core and Builtins ------------------ - -- Issue #15568: Fix the return value of ``yield from`` when StopIteration is - raised by a custom iterator. - -- Issue #13119: `sys.stdout` and `sys.stderr` are now using "\r\n" newline on - Windows, as Python 2. - -- Issue #15534: Fix the fast-search function for non-ASCII Unicode strings. - -- Issue #15508: Fix the docstring for `__import__()` to have the proper default - value of 0 for 'level' and to not mention negative levels since they are not - supported. - -- Issue #15425: Eliminated traceback noise from more situations involving - importlib. - -- Issue #14578: Support modules registered in the Windows registry again. - -- Issue #15466: Stop using TYPE_INT64 in marshal, to make importlib.h (and other - byte code files) equal between 32-bit and 64-bit systems. - -- Issue #1692335: Move initial exception args assignment to - `BaseException.__new__()` to help pickling of naive subclasses. - -- Issue #12834: Fix `PyBuffer_ToContiguous()` for non-contiguous arrays. - -- Issue #15456: Fix code `__sizeof__()` after #12399 change. Patch by Serhiy - Storchaka. +- Issue #6784: Strings from Python 2 can now be unpickled as bytes + objects by setting the encoding argument of Unpickler to be 'bytes'. + Initial patch by Merlijn van Deen. -- Issue #15404: Refleak in PyMethodObject repr. +- Issue #19839: Fix regression in bz2 module's handling of non-bzip2 data at + EOF, and analogous bug in lzma module. -- Issue #15394: An issue in `PyModule_Create()` that caused references to be - leaked on some error paths has been fixed. Patch by Julia Lawall. +- Issue #19881: Fix pickling bug where cpickle would emit bad pickle data for + large bytes string (i.e., with size greater than 2**32-1). -- Issue #15368: An issue that caused bytecode generation to be non-deterministic - has been fixed. +- Issue #19138: doctest's IGNORE_EXCEPTION_DETAIL now allows a match when + no exception detail exists (no colon following the exception's name, or + a colon does follow but no text follows the colon). -- Issue #15202: Consistently use the name "follow_symlinks" for new parameters - in os and shutil functions. +- Issue #19927: Add __eq__ to path-based loaders in importlib. -- Issue #15314: ``__main__.__loader__`` is now set correctly during interpreter - startup. +- Issue #19827: On UNIX, setblocking() and settimeout() methods of + socket.socket can now avoid a second syscall if the ioctl() function can be + used, or if the non-blocking flag of the socket is unchanged. -- Issue #15111: When a module imported using 'from import' has an ImportError - inside itself, don't mask that fact behind a generic ImportError for the - module itself. - -- Issue #15293: Add GC support to the AST base node type. - -- Issue #15291: Fix a memory leak where AST nodes where not properly - deallocated. - -- Issue #15110: Fix the tracebacks generated by "import xxx" to not show the - importlib stack frames. - -- Issue #16369: Global PyTypeObjects not initialized with PyType_Ready(...). - -- Issue #15020: The program name used to search for Python's path is now - "python3" under Unix, not "python". - -- Issue #15897: zipimport.c doesn't check return value of fseek(). - Patch by Felipe Cruz. - -- Issue #15033: Fix the exit status bug when modules invoked using -m switch, - return the proper failure return value (1). Patch contributed by Jeff Knupp. - -- Issue #15229: An `OSError` subclass whose __init__ doesn't call back - OSError.__init__ could produce incomplete instances, leading to crashes when - calling str() on them. - -- Issue #15307: Virtual environments now use symlinks with framework builds on - Mac OS X, like other POSIX builds. - -Library -------- - -- Issue #14590: configparser now correctly strips inline comments when delimiter - occurs earlier without preceding space. - -- Issue #15424: Add a `__sizeof__()` implementation for array objects. Patch by - Ludwig Hähne. - -- Issue #15576: Allow extension modules to act as a package's __init__ module. - -- Issue #15502: Have `importlib.invalidate_caches()` work on `sys.meta_path` - instead of `sys.path_importer_cache`. - -- Issue #15163: Pydoc shouldn't list __loader__ as module data. - -- Issue #15471: Do not use mutable objects as defaults for - `importlib.__import__()`. - -- Issue #15559: To avoid a problematic failure mode when passed to the bytes - constructor, objects in the ipaddress module no longer implement `__index__()` - (they still implement `__int__()` as appropriate). - -- Issue #15546: Fix handling of pathological input data in the peek() and - read1() methods of the BZ2File, GzipFile and LZMAFile classes. - -- Issue #12655: Instead of requiring a custom type, `os.sched_getaffinity()` and - `os.sched_setaffinity()` now use regular sets of integers to represent the - CPUs a process is restricted to. - -- Issue #15538: Fix compilation of the `socket.getnameinfo()` / - `socket.getaddrinfo()` emulation code. Patch by Philipp Hagemeister. +- Issue #19785: smtplib now supports SSLContext.check_hostname and server name + indication for TLS/SSL connections. -- Issue #15519: Properly expose WindowsRegistryFinder in importlib (and use the - correct term for it). Original patch by Eric Snow. +- Issue #19784: poplib now supports SSLContext.check_hostname and server name + indication for TLS/SSL connections. -- Issue #15502: Bring the importlib ABCs into line with the current state of the - import protocols given PEP 420. Original patch by Eric Snow. +- Issue #19783: nntplib now supports SSLContext.check_hostname and server name + indication for TLS/SSL connections. -- Issue #15499: Launching a webbrowser in Unix used to sleep for a few seconds. - Original patch by Anton Barkovsky. +- Issue #19782: imaplib now supports SSLContext.check_hostname and server name + indication for TLS/SSL connections. -- Issue #15463: The faulthandler module truncates strings to 500 characters, - instead of 100, to be able to display long file paths. +- Issue 20123: Fix pydoc.synopsis() for "binary" modules. -- Issue #6056: Make `multiprocessing` use setblocking(True) on the sockets it - uses. Original patch by J Derek Wilson. +- Issue #19834: Support unpickling of exceptions pickled by Python 2. -- Issue #15364: Fix sysconfig.get_config_var('srcdir') to be an absolute path. +- Issue #19781: ftplib now supports SSLContext.check_hostname and server name + indication for TLS/SSL connections. -- Issue #15413: `os.times()` had disappeared under Windows. +- Issue #19509: Add SSLContext.check_hostname to match the peer's certificate + with server_hostname on handshake. -- Issue #15402: An issue in the struct module that caused `sys.getsizeof()` to - return incorrect results for struct.Struct instances has been fixed. Initial - patch by Serhiy Storchaka. +- Issue #15798: Fixed subprocess.Popen() to no longer fail if file + descriptor 0, 1 or 2 is closed. -- Issue #15232: When mangle_from is True, `email.Generator` now correctly - mangles lines that start with 'From ' that occur in a MIME preamble or - epilogue. +- Issue #17897: Optimized unpickle prefetching. -- Issue #15094: Incorrectly placed #endif in _tkinter.c. Patch by Serhiy - Storchaka. +- Issue #3693: Make the error message more helpful when the array.array() + constructor is given a str. Move the array module typecode documentation to + the docstring of the constructor. -- Issue #13922: `argparse` no longer incorrectly strips '--'s that appear after - the first one. +- Issue #19088: Fixed incorrect caching of the copyreg module in + object.__reduce__() and object.__reduce_ex__(). -- Issue #12353: `argparse` now correctly handles null argument values. +- Issue #19698: Removed exec_module() methods from + importlib.machinery.BuiltinImporter and ExtensionFileLoader. -- Issue #10017, issue #14998: Fix TypeError using pprint on dictionaries with - user-defined types as keys or other unorderable keys. +- Issue #18864: Added a setter for ModuleSpec.has_location. -- Issue #15397: `inspect.getmodulename()` is now based directly on importlib via - a new `importlib.machinery.all_suffixes()` API. +- Fixed _pickle.Unpickler to not fail when loading empty strings as + persistent IDs. -- Issue #14635: `telnetlib` will use poll() rather than select() when possible to - avoid failing due to the select() file descriptor limit. +- Issue #11480: Fixed copy.copy to work with classes with custom metaclasses. + Patch by Daniel Urban. -- Issue #15180: Clarify posixpath.join() error message when mixing str & bytes. +- Issue #6477: Added support for pickling the types of built-in singletons + (i.e., Ellipsis, NotImplemented, None). -- Issue #15343: pkgutil now includes an iter_importer_modules implementation for - importlib.machinery.FileFinder (similar to the way it already handled - zipimport.zipimporter). +- Issue #19713: Add remaining PEP 451-related deprecations and move away + from using find_module/find_loaer/load_module. -- Issue #15314: runpy now sets __main__.__loader__ correctly. +- Issue #19708: Update pkgutil to use the new importer APIs. -- Issue #15357: The import emulation in pkgutil is now deprecated. pkgutil uses - importlib internally rather than the emulation. +- Issue #19703: Update pydoc to use the new importer APIs. -- Issue #15233: Python now guarantees that callables registered with the atexit - module will be called in a deterministic order. +- Issue #19851: Fixed a regression in reloading sub-modules. -- Issue #15238: `shutil.copystat()` now copies Linux "extended attributes". +- ssl.create_default_context() sets OP_NO_COMPRESSION to prevent CRIME. -- Issue #15230: runpy.run_path now correctly sets __package__ as described in - the documentation. +- Issue #19802: Add socket.SO_PRIORITY. -- Issue #15315: Support VS 2010 in distutils cygwincompiler. +- Issue #11508: Fixed uuid.getnode() and uuid.uuid1() on environment with + virtual interface. Original patch by Kent Frazier. -- Issue #15294: Fix a regression in pkgutil.extend_path()'s handling of nested - namespace packages. +- Issue #11489: JSON decoder now accepts lone surrogates. -- Issue #15056: `imp.cache_from_source()` and `imp.source_from_cache()` raise - NotImplementedError when `sys.implementation.cache_tag` is set to None. +- Issue #19545: Avoid chained exceptions while passing stray % to + time.strptime(). Initial patch by Claudiu Popa. -- Issue #15256: Grammatical mistake in exception raised by `imp.find_module()`. +IDLE +---- -- Issue #5931: `wsgiref` environ variable SERVER_SOFTWARE will specify an - implementation specific term like CPython, Jython instead of generic "Python". +- Issue #20058: sys.stdin.readline() in IDLE now always returns only one line. -- Issue #13248: Remove obsolete argument "max_buffer_size" of BufferedWriter and - BufferedRWPair, from the io module. +- Issue #19481: print() of string subclass instance in IDLE no longer hangs. -- Issue #13248: Remove obsolete argument "version" of `argparse.ArgumentParser`. +- Issue #18270: Prevent possible IDLE AttributeError on OS X when no initial + shell window is present. -- Issue #14814: Implement more consistent ordering and sorting behaviour for - ipaddress objects. +Tests +----- -- Issue #14814: `ipaddress` network objects correctly return NotImplemented when - compared to arbitrary objects instead of raising TypeError. +- Issue #20055: Fix test_shutil under Windows with symlink privileges held. + Patch by Vajrasky Kok. -- Issue #14990: Correctly fail with SyntaxError on invalid encoding declaration. +- Issue #20070: Don't run test_urllib2net when network resources are not + enabled. -- Issue #14814: `ipaddress` now provides more informative error messages when - constructing instances directly (changes permitted during beta due to - provisional API status). +- Issue #19938: Re-enabled test_bug_1333982 in test_dis, which had been + disabled since 3.0 due to the changes in listcomp handling. -- Issue #15247: `io.FileIO` now raises an error when given a file descriptor - pointing to a directory. +- Issue #19320: test_tcl no longer fails when wantobjects is false. -- Issue #15261: Stop os.stat(fd) crashing on Windows when fd not open. +- Issue #19919: Fix flaky SSL test. connect_ex() sometimes returns + EWOULDBLOCK on Windows or VMs hosted on Windows. -- Issue #15166: Implement `imp.get_tag()` using `sys.implementation.cache_tag`. +- Issue #19912: Added tests for ntpath.splitunc(). -- Issue #15210: Catch KeyError when `importlib.__init__()` can't find - _frozen_importlib in sys.modules, not ImportError. +- Issue #19828: Fixed test_site when the whole suite is run with -S. -- Issue #15030: `importlib.abc.PyPycLoader` now supports the new source size - header field in .pyc files. +- Issue #19928: Implemented a test for repr() of cell objects. -- Issue #5346: Preserve permissions of mbox, MMDF and Babyl mailbox files on - flush(). +- Issue #19535: Fixed test_docxmlrpc, test_functools, test_inspect, and + test_statistics when python is run with -OO. -- Issue #10571: Fix the "--sign" option of distutils' upload command. Patch by - Jakub Wilk. +- Issue #19926: Removed unneeded test_main from test_abstract_numbers. + Patch by Vajrasky Kok. -- Issue #9559: If messages were only added, a new file is no longer created and - renamed over the old file when flush() is called on an mbox, MMDF or Babyl - mailbox. +- Issue #19572: More skipped tests explicitly marked as skipped. -- Issue #10924: Fixed `crypt.mksalt()` to use a RNG that is suitable for - cryptographic purpose. +- Issue #19595, #19987: Re-enabled a long-disabled test in test_winsound. -- Issue #15184: Ensure consistent results of OS X configuration tailoring for - universal builds by factoring out common OS X-specific customizations from - sysconfig, distutils.sysconfig, distutils.util, and distutils.unixccompiler - into a new module _osx_support. +- Issue #19588: Fixed tests in test_random that were silently skipped most + of the time. Patch by Julian Gindi. -C API +Build ----- -- Issue #15610: `PyImport_ImportModuleEx()` now uses a 'level' of 0 instead of -1. +- Issue #19728: Enable pip installation by default on Windows. -- Issue #15169, issue #14599: Strip out the C implementation of - `imp.source_from_cache()` used by PyImport_ExecCodeModuleWithPathnames() and - used the Python code instead. Leads to PyImport_ExecCodeModuleObject() to not - try to infer the source path from the bytecode path as - PyImport_ExecCodeModuleWithPathnames() does. +- Issue #16136: Remove VMS support -Extension Modules ------------------ - -- Issue #6493: An issue in ctypes on Windows that caused structure bitfields of - type `ctypes.c_uint32` and width 32 to incorrectly be set has been fixed. - -- Issue #15194: Update libffi to the 3.0.11 release. - -IDLE ----- - -- Issue #13052: Fix IDLE crashing when replace string in Search/Replace dialog - ended with ``\``. Patch by Roger Serwy. - -Tools/Demos ------------ - -- Issue #15458: python-config gets a new option --configdir to print the $LIBPL - value. - -- Move importlib.test.benchmark to Tools/importbench. +- Issue #18215: Add script Tools/ssl/test_multiple_versions.py to compile and + run Python's unit tests with multiple versions of OpenSSL. -- Issue #12605: The gdb hooks for debugging CPython (within Tools/gdb) have been - enhanced to show information on more C frames relevant to CPython within the - "py-bt" and "py-bt-full" commands: +- Issue #19922: define _INCLUDE__STDC_A1_SOURCE in HP-UX to include mbstate_t + for mbrtowc(). - * C frames that are waiting on the GIL - * C frames that are garbage-collecting - * C frames that are due to the invocation of a PyCFunction +- Issue #19788: kill_python(_d).exe is now run as a PreBuildEvent on the + pythoncore sub-project. This should prevent build errors due a previous + build's python(_d).exe still running. Documentation ------------- -- Issue #15041: Update "see also" list in tkinter documentation. - -- Issue #15444: Use proper spelling for non-ASCII contributor names. Patch by - Serhiy Storchaka. - -- Issue #15295: Reorganize and rewrite the documentation on the import system. - -- Issue #15230: Clearly document some of the limitations of the runpy module and - nudge readers towards importlib when appropriate. - -- Issue #15053: Copy Python 3.3 import lock change notice to all relevant - functions in imp instead of just at the top of the relevant section. - -- Issue #15288: Link to the term "loader" in notes in pkgutil about how things - won't work as expected in Python 3.3 and mark the requisite functions as - "changed" since they will no longer work with modules directly imported by - import itself. - -- Issue #13557: Clarify effect of giving two different namespaces to `exec()` or - `execfile()`. - -- Issue #15250: Document that `filecmp.dircmp()` compares files shallowly. Patch - contributed by Chris Jerdonek. - -- Issue #15442: Expose the default list of directories ignored by - `filecmp.dircmp()` as a module attribute, and expand the list to more modern - values. - -Tests ------ - -- Issue #15467: Move helpers for `__sizeof__()` tests into test_support. Patch - by Serhiy Storchaka. - -- Issue #15320: Make iterating the list of tests thread-safe when running tests - in multiprocess mode. Patch by Chris Jerdonek. - -- Issue #15168: Move `importlib.test` to `test.test_importlib`. +- Issue #20265: Updated some parts of the Using Windows document. -- Issue #15091: Reactivate a test on UNIX which was failing thanks to a - forgotten `importlib.invalidate_caches()` call. +- Issue #20266: Updated some parts of the Windows FAQ. -- Issue #15230: Adopted a more systematic approach in the runpy tests. +- Issue #20255: Updated the about and bugs pages. -- Issue #15300: Ensure the temporary test working directories are in the same - parent folder when running tests in multiprocess mode from a Python build. - Patch by Chris Jerdonek. +- Issue #20253: Fixed a typo in the ipaddress docs that advertised an + illegal attribute name. Found by INADA Naoki. -- Issue #15284: Skip {send,recv}msg tests in test_socket when IPv6 is not - enabled. Patch by Brian Brazil. +- Issue #18840: Introduce the json module in the tutorial, and de-emphasize + the pickle module. -- Issue #15277: Fix a resource leak in support.py when IPv6 is disabled. Patch - by Brian Brazil. - -Build ------ - -- Issue #11715: Fix multiarch detection without having Debian development tools - (dpkg-dev) installed. - -- Issue #15037: Build OS X installers with local copy of ncurses 5.9 libraries - to avoid curses.unget_wch bug present in older versions of ncurses such as - those shipped with OS X. - -- Issue #15560: Fix building _sqlite3 extension on OS X with an SDK. Also, for - OS X installers, ensure consistent sqlite3 behavior and feature availability - by building a local copy of libsqlite3 rather than depending on the wide range - of versions supplied with various OS X releases. - -- Issue #8847: Disable COMDAT folding in Windows PGO builds. - -- Issue #14018: Fix OS X Tcl/Tk framework checking when using OS X SDKs. - -- Issue #16256: OS X installer now sets correct permissions for doc directory. - -- Issue #15431: Add _freeze_importlib project to regenerate importlib.h on - Windows. Patch by Kristján Valur Jónsson. - -- Issue #14197: For OS X framework builds, ensure links to the shared library - are created with the proper ABI suffix. +- Issue #19845: Updated the Compiling Python on Windows section. -- Issue #14330: For cross builds, don't use host python, use host search paths - for host compiler. +- Issue #19795: Improved markup of True/False constants. -- Issue #15235: Allow Berkley DB versions up to 5.3 to build the dbm module. +Tools/Demos +----------- -- Issue #15268: Search curses.h in /usr/include/ncursesw. +- Issue #19659: Added documentation for Argument Clinic. +- Issue #19976: Argument Clinic METH_NOARGS functions now always + take two parameters. -What's New in Python 3.3.0 Beta 1? +What's New in Python 3.4.0 Beta 1? ================================== -*Release date: 27-Jun-2012* +Release date: 2013-11-24 Core and Builtins ----------------- -- Fix a (most likely) very rare memory leak when calling main() and not being - able to decode a command-line argument. - -- Issue #14815: Use Py_ssize_t instead of long for the object hash, to - preserve all 64 bits of hash on Win64. - -- Issue #12268: File readline, readlines and read() or readall() methods - no longer lose data when an underlying read system call is interrupted. - IOError is no longer raised due to a read system call returning EINTR - from within these methods. - -- Issue #11626: Add _SizeT functions to stable ABI. - -- Issue #15142: Fix reference leak when deallocating instances of types - created using PyType_FromSpec(). - -- Issue #10053: Don't close FDs when FileIO.__init__ fails. Loosely based on - the work by Hirokazu Yamamoto. - -- Issue #15096: Removed support for ur'' as the raw notation isn't - compatible with Python 2.x's raw unicode strings. - -- Issue #13783: Generator objects now use the identifier APIs internally - -- Issue #14874: Restore charmap decoding speed to pre-PEP 393 levels. - Patch by Serhiy Storchaka. - -- Issue #15026: utf-16 encoding is now significantly faster (up to 10x). - Patch by Serhiy Storchaka. - -- Issue #11022: open() and io.TextIOWrapper are now calling - locale.getpreferredencoding(False) instead of locale.getpreferredencoding() - in text mode if the encoding is not specified. Don't change temporary the - locale encoding using locale.setlocale(), use the current locale encoding - instead of the user preferred encoding. - -- Issue #14673: Add Eric Snow's sys.implementation implementation. - -- Issue #15038: Optimize python Locks on Windows. - -Library -------- - -- Issue #12288: Consider '0' and '0.0' as valid initialvalue - for tkinter SimpleDialog. - -- Issue #15512: Add a __sizeof__ implementation for parser. - Patch by Serhiy Storchaka. - -- Issue #15469: Add a __sizeof__ implementation for deque objects. - Patch by Serhiy Storchaka. - -- Issue #15489: Add a __sizeof__ implementation for BytesIO objects. - Patch by Serhiy Storchaka. - -- Issue #15487: Add a __sizeof__ implementation for buffered I/O objects. - Patch by Serhiy Storchaka. - -- Issue #15514: Correct __sizeof__ support for cpu_set. - Patch by Serhiy Storchaka. - -- Issue #15177: Added dir_fd parameter to os.fwalk(). - -- Issue #15061: Re-implemented hmac.compare_digest() in C to prevent further - timing analysis and to support all buffer protocol aware objects as well as - ASCII only str instances safely. - -- Issue #15164: Change return value of platform.uname() from a - plain tuple to a collections.namedtuple. - -- Support Mageia Linux in the platform module. - -- Issue #11678: Support Arch linux in the platform module. - -- Issue #15118: Change return value of os.uname() and os.times() from - plain tuples to immutable iterable objects with named attributes - (structseq objects). - -- Speed up _decimal by another 10-15% by caching the thread local context - that was last accessed. In the pi benchmark (64-bit platform, prec=9), - _decimal is now only 1.5x slower than float. - -- Remove the packaging module, which is not ready for prime time. - -- Issue #15154: Add "dir_fd" parameter to os.rmdir, remove "rmdir" - parameter from os.remove / os.unlink. - -- Issue #4489: Add a shutil.rmtree that isn't susceptible to symlink attacks. - It is used automatically on platforms supporting the necessary os.openat() - and os.unlinkat() functions. Main code by Martin von Löwis. - -- Issue #15156: HTMLParser now uses the new "html.entities.html5" dictionary. - -- Issue #11113: add a new "html5" dictionary containing the named character - references defined by the HTML5 standard and the equivalent Unicode - character(s) to the html.entities module. +- Use the repr of a module name in more places in import, especially + exceptions. -- Issue #15114: the strict mode of HTMLParser and the HTMLParseError exception - are deprecated now that the parser is able to parse invalid markup. +- Issue #19619: str.encode, bytes.decode and bytearray.decode now use an + internal API to throw LookupError for known non-text encodings, rather + than attempting the encoding or decoding operation and then throwing a + TypeError for an unexpected output type. (The latter mechanism remains + in place for third party non-text encodings) -- Issue #3665: \u and \U escapes are now supported in unicode regular - expressions. Patch by Serhiy Storchaka. +- Issue #19183: Implement PEP 456 'secure and interchangeable hash algorithm'. + Python now uses SipHash24 on all major platforms. -- Issue #15153: Added inspect.getgeneratorlocals to simplify white box - testing of generator state updates +- Issue #12892: The utf-16* and utf-32* encoders no longer allow surrogate code + points (U+D800-U+DFFF) to be encoded. The utf-32* decoders no longer decode + byte sequences that correspond to surrogate code points. The surrogatepass + error handler now works with the utf-16* and utf-32* codecs. Based on + patches by Victor Stinner and Kang-Hao (Kenny) Lu. -- Issue #13062: Added inspect.getclosurevars to simplify testing stateful - closures +- Issue #17806: Added keyword-argument support for "tabsize" to + str/bytes.expandtabs(). -- Issue #11024: Fixes and additional tests for Time2Internaldate. +- Issue #17828: Output type errors in str.encode(), bytes.decode() and + bytearray.decode() now direct users to codecs.encode() or codecs.decode() + as appropriate. -- Issue #14626: Large refactoring of functions / parameters in the os module. - Many functions now support "dir_fd" and "follow_symlinks" parameters; - some also support accepting an open file descriptor in place of a path - string. Added os.support_* collections as LBYL helpers. Removed many - functions only previously seen in 3.3 alpha releases (often starting with - "f" or "l", or ending with "at"). Originally suggested by Serhiy Storchaka; - implemented by Larry Hastings. +- Issue #17828: The interpreter now attempts to chain errors that occur in + codec processing with a replacement exception of the same type that + includes the codec name in the error message. It ensures it only does this + when the creation of the replacement exception won't lose any information. -- Issue #15008: Implement PEP 362 "Signature Objects". - Patch by Yury Selivanov. +- Issue #19466: Clear the frames of daemon threads earlier during the + Python shutdown to call objects destructors. So "unclosed file" resource + warnings are now corretly emitted for daemon threads. -- Issue: #15138: base64.urlsafe_{en,de}code() are now 3-4x faster. +- Issue #19514: Deduplicate some _Py_IDENTIFIER declarations. + Patch by Andrei Dorian Duma. -- Issue #444582: Add shutil.which, for finding programs on the system path. - Original patch by Erik Demaine, with later iterations by Jan Killian - and Brian Curtin. +- Issue #17936: Fix O(n**2) behaviour when adding or removing many subclasses + of a given type. -- Issue #14837: SSL errors now have ``library`` and ``reason`` attributes - describing precisely what happened and in which OpenSSL submodule. The - str() of a SSLError is also enhanced accordingly. +- Issue #19428: zipimport now handles errors when reading truncated or invalid + ZIP archive. -- Issue #9527: datetime.astimezone() method will now supply a class - timezone instance corresponding to the system local timezone when - called with no arguments. +- Issue #18408: Add a new PyFrame_FastToLocalsWithError() function to handle + exceptions when merging fast locals into f_locals of a frame. + PyEval_GetLocals() now raises an exception and return NULL on failure. -- Issue #14653: email.utils.mktime_tz() no longer relies on system - mktime() when timezone offest is supplied. +- Issue #19369: Optimized the usage of __length_hint__(). -- Issue #14684: zlib.compressobj() and zlib.decompressobj() now support the use - of predefined compression dictionaries. Original patch by Sam Rushing. +- Issue #18603: Ensure that PyOS_mystricmp and PyOS_mystrnicmp are in the + Python executable and not removed by the linker's optimizer. -- Fix GzipFile's handling of filenames given as bytes objects. +- Issue #19306: Add extra hints to the faulthandler module's stack + dumps that these are "upside down". -- Issue #14772: Return destination values from some shutil functions. +Library +------- -- Issue #15064: Implement context manager protocol for multiprocessing types +- Issue #3158: doctest can now find doctests in functions and methods + written in C. -- Issue #15101: Make pool finalizer avoid joining current thread. +- Issue #13477: Added command line interface to the tarfile module. + Original patch by Berker Peksag. -- Issue #14657: The frozen instance of importlib used for bootstrap is now - also the module imported as importlib._bootstrap. +- Issue #19674: inspect.signature() now produces a correct signature + for some builtins. -- Issue #14055: Add __sizeof__ support to _elementtree. +- Issue #19722: Added opcode.stack_effect(), which + computes the stack effect of bytecode instructions. -- Issue #15054: A bug in tokenize.tokenize that caused string literals - with 'b' prefixes to be incorrectly tokenized has been fixed. - Patch by Serhiy Storchaka. +- Issue #19735: Implement private function ssl._create_stdlib_context() to + create SSLContext objects in Python's stdlib module. It provides a single + configuration point and makes use of SSLContext.load_default_certs(). -- Issue #15006: Allow equality comparison between naive and aware - time or datetime objects. +- Issue #16203: Add re.fullmatch() function and regex.fullmatch() method, + which anchor the pattern at both ends of the string to match. + Original patch by Matthew Barnett. -- Issue #15036: Mailbox no longer throws an error if a flush is done - between operations when removing or changing multiple items in mbox, - MMDF, or Babyl mailboxes. +- Issue #13592: Improved the repr for regular expression pattern objects. + Based on patch by Hugo Lopes Tavares. -- Issue #14059: Implement multiprocessing.Barrier. +- Issue #19641: Added the audioop.byteswap() function to convert big-endian + samples to little-endian and vice versa. -- Issue #15061: The inappropriately named hmac.secure_compare has been - renamed to hmac.compare_digest, restricted to operating on bytes inputs - only and had its documentation updated to more accurately reflect both its - intent and its limitations +- Issue #15204: Deprecated the 'U' mode in file-like objects. -- Issue #13841: Make child processes exit using sys.exit() on Windows. +- Issue #17810: Implement PEP 3154, pickle protocol 4. -- Issue #14936: curses_panel was converted to PEP 3121 and PEP 384 API. - Patch by Robin Schreiber. +- Issue #19668: Added support for the cp1125 encoding. -- Issue #1667546: On platforms supporting tm_zone and tm_gmtoff fields - in struct tm, time.struct_time objects returned by time.gmtime(), - time.localtime() and time.strptime() functions now have tm_zone and - tm_gmtoff attributes. Original patch by Paul Boddie. +- Issue #19689: Add ssl.create_default_context() factory function. It creates + a new SSLContext object with secure default settings. -- Rename adjusted attribute to adjustable in time.get_clock_info() result. +- Issue #19727: os.utime(..., None) is now potentially more precise + under Windows. -- Issue #3518: Remove references to non-existent BaseManager.from_address() - method. +- Issue #17201: ZIP64 extensions now are enabled by default. Patch by + William Mallard. -- Issue #13857: Added textwrap.indent() function (initial patch by Ezra - Berch) +- Issue #19292: Add SSLContext.load_default_certs() to load default root CA + certificates from default stores or system stores. By default the method + loads CA certs for authentication of server certs. -- Issue #2736: Added datetime.timestamp() method. +- Issue #19673: Add pathlib to the stdlib as a provisional module (PEP 428). -- Issue #13854: Make multiprocessing properly handle non-integer - non-string argument to SystemExit. +- Issue #16596: pdb in a generator now properly skips over yield and + yield from rather than stepping out of the generator into its + caller. (This is essential for stepping through asyncio coroutines.) -- Issue #12157: Make pool.map() empty iterables correctly. Initial - patch by mouad. +- Issue #17916: Added dis.Bytecode.from_traceback() and + dis.Bytecode.current_offset to easily display "current instruction" + markers in the new disassembly API (Patch by Claudiu Popa). -- Issue #11823: disassembly now shows argument counts on calls with keyword args. +- Issue #19552: venv now supports bootstrapping pip into virtual environments -- Issue #14711: os.stat_float_times() has been deprecated. +- Issue #17134: Finalize interface to Windows' certificate store. Cert and + CRL enumeration are now two functions. enum_certificates() also returns + purpose flags as set of OIDs. -- LZMAFile now accepts the modes "rb"/"wb"/"ab" as synonyms of "r"/"w"/"a". +- Issue #19555: Restore sysconfig.get_config_var('SO'), (and the distutils + equivalent) with a DeprecationWarning pointing people at $EXT_SUFFIX. -- The bz2 and lzma modules now each contain an open() function, allowing - compressed files to readily be opened in text mode as well as binary mode. +- Issue #8813: Add SSLContext.verify_flags to change the verification flags + of the context in order to enable certification revocation list (CRL) + checks or strict X509 rules. -- BZ2File.__init__() and LZMAFile.__init__() now accept a file object as their - first argument, rather than requiring a separate "fileobj" argument. +- Issue #18294: Fix the zlib module to make it 64-bit safe. -- gzip.open() now accepts file objects as well as filenames. +- Issue #19682: Fix compatibility issue with old version of OpenSSL that + was introduced by Issue #18379. -- Issue #14992: os.makedirs(path, exist_ok=True) would raise an OSError - when the path existed and had the S_ISGID mode bit set when it was - not explicitly asked for. This is no longer an exception as mkdir - cannot control if the OS sets that bit for it or not. +- Issue #14455: plistlib now supports binary plists and has an updated API. -- Issue #14989: Make the CGI enable option to http.server available via command - line. +- Issue #19633: Fixed writing not compressed 16- and 32-bit wave files on + big-endian platforms. -- Issue #14987: Add a missing import statement to inspect. +- Issue #18379: SSLSocket.getpeercert() returns CA issuer AIA fields, OCSP + and CRL distribution points. -- Issue #1079: email.header.decode_header now correctly parses all the examples - in RFC2047. There is a necessary visible behavior change: the leading and/or - trailing whitespace on ASCII parts is now preserved. +- Issue #18138: Implement cadata argument of SSLContext.load_verify_location() + to load CA certificates and CRL from memory. It supports PEM and DER + encoded strings. -- Issue #14969: Better handling of exception chaining in contextlib.ExitStack +- Issue #18775: Add name and block_size attribute to HMAC object. They now + provide the same API elements as non-keyed cryptographic hash functions. -- Issue #14963: Convert contextlib.ExitStack.__exit__ to use an iterative - algorithm (Patch by Alon Horev) +- Issue #17276: MD5 as default digestmod for HMAC is deprecated. The HMAC + module supports digestmod names, e.g. hmac.HMAC('sha1'). -- Issue #14785: Add sys._debugmallocstats() to help debug low-level memory - allocation issues +- Issue #19449: in csv's writerow, handle non-string keys when generating the + error message that certain keys are not in the 'fieldnames' list. -- Issue #14443: Ensure that .py files are byte-compiled with the correct Python - executable within bdist_rpm even on older versions of RPM +- Issue #13633: Added a new convert_charrefs keyword arg to HTMLParser that, + when True, automatically converts all character references. -C-API ------ +- Issue #2927: Added the unescape() function to the html module. -- Issue #15146: Add PyType_FromSpecWithBases. Patch by Robin Schreiber. +- Issue #8402: Added the escape() function to the glob module. -- Issue #15042: Add PyState_AddModule and PyState_RemoveModule. Add version - guard for Py_LIMITED_API additions. Patch by Robin Schreiber. +- Issue #17618: Add Base85 and Ascii85 encoding/decoding to the base64 module. -- Issue #13783: Inadvertent additions to the public C API in the PEP 380 - implementation have either been removed or marked as private interfaces. +- Issue #19634: time.strftime("%y") now raises a ValueError on AIX when given a + year before 1900. -Extension Modules ------------------ +- Fix test.support.bind_port() to not cause an error when Python was compiled + on a system with SO_REUSEPORT defined in the headers but run on a system + with an OS kernel that does not support that reasonably new socket option. -- Issue #15000: Support the "unique" x32 architecture in _posixsubprocess.c. +- Fix compilation error under gcc of the ctypes module bundled libffi for arm. -IDLE ----- +- Issue #19448: Add private API to SSL module to lookup ASN.1 objects by OID, + NID, short name and long name. -- Issue #9803: Don't close IDLE on saving if breakpoint is open. - Patch by Roger Serwy. +- Issue #19282: dbm.open now supports the context management protocol. (Inital + patch by Claudiu Popa) -- Issue #14962: Update text coloring in IDLE shell window after changing - options. Patch by Roger Serwy. +- Issue #8311: Added support for writing any bytes-like objects in the aifc, + sunau, and wave modules. -Documentation -------------- +- Issue #5202: Added support for unseekable files in the wave module. -- Issue #15176: Clarified behavior, documentation, and implementation - of os.listdir(). +- Issue #19544 and Issue #1180: Restore global option to ignore + ~/.pydistutils.cfg in Distutils, accidentally removed in backout of + distutils2 changes. -- Issue #14982: Document that pkgutil's iteration functions require the - non-standard iter_modules() method to be defined by an importer (something - the importlib importers do not define). +- Issue #19523: Closed FileHandler leak which occurred when delay was set. -- Issue #15081: Document PyState_FindModule. - Patch by Robin Schreiber. +- Issue #19544 and Issue #6516: Restore support for --user and --group + parameters to sdist command accidentally rolled back as part of the + distutils2 rollback. -- Issue #14814: Added first draft of ipaddress module API reference +- Issue #13674: Prevented time.strftime from crashing on Windows when given + a year before 1900 and a format of %y. -Tests ------ +- Issue #19406: implementation of the ensurepip module (part of PEP 453). + Patch by Donald Stufft and Nick Coghlan. -- Issue #15187: Bugfix: remove temporary directories test_shutil was leaving - behind. +- Issue #19544 and Issue #6286: Restore use of urllib over http allowing use + of http_proxy for Distutils upload command, a feature accidentally lost + in the rollback of distutils2. -- Issue #14769: test_capi now has SkipitemTest, which cleverly checks - for "parity" between PyArg_ParseTuple() and the Python/getargs.c static - function skipitem() for all possible "format units". +- Issue #19544 and Issue #7457: Restore the read_pkg_file method to + distutils.dist.DistributionMetadata accidentally removed in the undo of + distutils2. -- test_nntplib now tolerates being run from behind NNTP gateways that add - "X-Antivirus" headers to articles +- Issue #16685: Added support for any bytes-like objects in the audioop module. + Removed support for strings. -- Issue #15043: test_gdb is now skipped entirely if gdb security settings - block loading of the gdb hooks +- Issue #7171: Add Windows implementation of ``inet_ntop`` and ``inet_pton`` + to socket module. Patch by Atsuo Ishimoto. -- Issue #14963: Add test cases for exception handling behaviour - in contextlib.ExitStack (Initial patch by Alon Horev) +- Issue #19261: Added support for writing 24-bit samples in the sunau module. -Build ------ +- Issue #1097797: Added CP273 encoding, used on IBM mainframes in + Germany and Austria. Mapping provided by Michael Bierenfeld. -- Issue #13590: Improve support for OS X Xcode 4: - * Try to avoid building Python or extension modules with problematic - llvm-gcc compiler. - * Since Xcode 4 removes ppc support, extension module builds now - check for ppc compiler support and automatically remove ppc and - ppc64 archs when not available. - * Since Xcode 4 no longer install SDKs in default locations, - extension module builds now revert to using installed headers - and libs if the SDK used to build the interpreter is not - available. - * Update ./configure to use better defaults for universal builds; - in particular, --enable-universalsdk=yes uses the Xcode default - SDK and --with-universal-archs now defaults to "intel" if ppc - not available. +- Issue #1575020: Fixed support of 24-bit wave files on big-endian platforms. -- Issue #14225: Fix Unicode support for curses (#12567) on OS X +- Issue #19378: Fixed a number of cases in the dis module where the new + "file" parameter was not being honoured correctly -- Issue #14928: Fix importlib bootstrap issues by using a custom executable - (Modules/_freeze_importlib) to build Python/importlib.h. +- Issue #19378: Removed the "dis.Bytecode.show_info" method +- Issue #19378: Renamed the "dis.Bytecode.display_code" method to + "dis.Bytecode.dis" and converted it to returning a string rather than + printing output. -What's New in Python 3.3.0 Alpha 4? -=================================== +- Issue #19378: the "line_offset" parameter in the new "dis.get_instructions" + API has been renamed to "first_line" (and the default value and usage + changed accordingly). This should reduce confusion with the more common use + of "offset" in the dis docs to refer to bytecode offsets. -*Release date: 31-May-2012* +- Issue #18678: Corrected spwd struct member names in spwd module: + sp_nam->sp_namp, and sp_pwd->sp_pwdp. The old names are kept as extra + structseq members, for backward compatibility. -Core and Builtins ------------------ +- Issue #6157: Fixed tkinter.Text.debug(). tkinter.Text.bbox() now raises + TypeError instead of TclError on wrong number of arguments. Original patch + by Guilherme Polo. -- Issue #14835: Make plistlib output empty arrays & dicts like OS X. - Patch by Sidney San Martín. +- Issue #10197: Rework subprocess.get[status]output to use subprocess + functionality and thus to work on Windows. Patch by Nick Coghlan -- Issue #14744: Use the new _PyUnicodeWriter internal API to speed up - str%args and str.format(args). +- Issue #6160: The bbox() method of tkinter.Spinbox now returns a tuple of + integers instead of a string. Based on patch by Guilherme Polo. -- Issue #14930: Make memoryview objects weakrefable. +- Issue #19403: contextlib.redirect_stdout is now reentrant -- Issue #14775: Fix a potential quadratic dict build-up due to the garbage - collector repeatedly trying to untrack dicts. +- Issue #19286: Directories in ``package_data`` are no longer added to + the filelist, preventing failure outlined in the ticket. -- Issue #14857: fix regression in references to PEP 3135 implicit __class__ - closure variable (Reopens issue #12370) +- Issue #19480: HTMLParser now accepts all valid start-tag names as defined + by the HTML5 standard. -- Issue #14712 (PEP 405): Virtual environments. Implemented by Vinay Sajip. +- Issue #15114: The html.parser module now raises a DeprecationWarning when the + strict argument of HTMLParser or the HTMLParser.error method are used. -- Issue #14660 (PEP 420): Namespace packages. Implemented by Eric Smith. +- Issue #19410: Undo the special-casing removal of '' for + importlib.machinery.FileFinder. -- Issue #14494: Fix __future__.py and its documentation to note that - absolute imports are the default behavior in 3.0 instead of 2.7. - Patch by Sven Marnach. +- Issue #19424: Fix the warnings module to accept filename containing surrogate + characters. -- Issue #9260: A finer-grained import lock. Most of the import sequence - now uses per-module locks rather than the global import lock, eliminating - well-known issues with threads and imports. +- Issue #19435: Fix directory traversal attack on CGIHttpRequestHandler. -- Issue #14624: UTF-16 decoding is now 3x to 4x faster on various inputs. - Patch by Serhiy Storchaka. +- Issue #19227: Remove pthread_atfork() handler. The handler was added to + solve #18747 but has caused issues. -- asdl_seq and asdl_int_seq are now Py_ssize_t sized. +- Issue #19420: Fix reference leak in module initalization code of + _hashopenssl.c -- Issue #14133 (PEP 415): Implement suppression of __context__ display with an - attribute on BaseException. This replaces the original mechanism of PEP 409. +- Issue #19329: Optimized compiling charsets in regular expressions. -- Issue #14417: Mutating a dict during lookup now restarts the lookup instead - of raising a RuntimeError (undoes issue #14205). +- Issue #19227: Try to fix deadlocks caused by re-seeding then OpenSSL + pseudo-random number generator on fork(). -- Issue #14738: Speed-up UTF-8 decoding on non-ASCII data. Patch by Serhiy - Storchaka. +- Issue #16037: HTTPMessage.readheaders() raises an HTTPException when more than + 100 headers are read. Adapted from patch by Jyrki Pulliainen. -- Issue #14700: Fix two broken and undefined-behaviour-inducing overflow checks - in old-style string formatting. +- Issue #16040: CVE-2013-1752: nntplib: Limit maximum line lengths to 2048 to + prevent readline() calls from consuming too much memory. Patch by Jyrki + Pulliainen. -Library -------- +- Issue #16041: CVE-2013-1752: poplib: Limit maximum line lengths to 2048 to + prevent readline() calls from consuming too much memory. Patch by Jyrki + Pulliainen. -- Issue #14690: Use monotonic clock instead of system clock in the sched, - subprocess and trace modules. +- Issue #17997: Change behavior of ``ssl.match_hostname()`` to follow RFC 6125, + for security reasons. It now doesn't match multiple wildcards nor wildcards + inside IDN fragments. -- Issue #14443: Tell rpmbuild to use the correct version of Python in - bdist_rpm. Initial patch by Ross Lagerwall. +- Issue #16039: CVE-2013-1752: Change use of readline in imaplib module to limit + line length. Patch by Emil Lind. -- Issue #12515: email now registers a defect if it gets to EOF while parsing - a MIME part without seeing the closing MIME boundary. +- Issue #19330: the unnecessary wrapper functions have been removed from the + implementations of the new contextlib.redirect_stdout and + contextlib.suppress context managers, which also ensures they provide + reasonable help() output on instances -- Issue #1672568: email now always decodes base64 payloads, adding padding and - ignoring non-base64-alphabet characters if needed, and registering defects - for any such problems. +- Issue #19393: Fix symtable.symtable function to not be confused when there are + functions or classes named "top". -- Issue #14925: email now registers a defect when the parser decides that there - is a missing header/body separator line. MalformedHeaderDefect, which the - existing code would never actually generate, is deprecated. +- Issue #18685: Restore re performance to pre-PEP 393 levels. -- Issue #10365: File open dialog now works instead of crashing even when - the parent window is closed before the dialog. Patch by Roger Serwy. +- Issue #19339: telnetlib module is now using time.monotonic() when available + to compute timeout. -- Issue #8739: Updated smtpd to support RFC 5321, and added support for the - RFC 1870 SIZE extension. +- Issue #19399: fix sporadic test_subprocess failure. -- Issue #665194: Added a localtime function to email.utils to provide an - aware local datetime for use in setting Date headers. +- Issue #13234: Fix os.listdir to work with extended paths on Windows. + Patch by Santoso Wijaya. -- Issue #12586: Added new provisional policies that implement convenient - unicode support for email headers. See What's New for details. +- Issue #19375: The site module adding a "site-python" directory to sys.path, + if it exists, is now deprecated. -- Issue #14731: Refactored email Policy framework to support full backward - compatibility with Python 3.2 by default yet allow for the introduction of - new features through new policies. Note that Policy.must_be_7bit is renamed - to cte_type. +- Issue #19379: Lazily import linecache in the warnings module, to make + startup with warnings faster until a warning gets printed. -- Issue #14876: Use user-selected font for highlight configuration. +- Issue #19288: Fixed the "in" operator of dbm.gnu databases for string + argument. Original patch by Arfrever Frehtes Taifersar Arahesis. -- Issue #14920: Fix the help(urllib.parse) failure on locale C on terminals. - Have ascii characters in help. +- Issue #19287: Fixed the "in" operator of dbm.ndbm databases for string + argument. Original patch by Arfrever Frehtes Taifersar Arahesis. -- Issue #14548: Make multiprocessing finalizers check pid before - running to cope with possibility of gc running just after fork. +- Issue #19327: Fixed the working of regular expressions with too big charset. -- Issue #14036: Add an additional check to validate that port in urlparse does - not go in illegal range and returns None. +- Issue #17400: New 'is_global' attribute for ipaddress to tell if an address + is allocated by IANA for global or private networks. -- Issue #14862: Add missing names to os.__all__ +- Issue #19350: Increasing the test coverage of macurl2path. Patch by Colin + Williams. -- Issue #14875: Use float('inf') instead of float('1e66666') in the json module. +- Issue #19365: Optimized the parsing of long replacement string in re.sub*() + functions. -- Issue #13585: Added contextlib.ExitStack +- Issue #19352: Fix unittest discovery when a module can be reached + through several paths (e.g. under Debian/Ubuntu with virtualenv). -- PEP 3144, Issue #14814: Added the ipaddress module +- Issue #15207: Fix mimetypes to read from correct part of Windows registry + Original patch by Dave Chambers -- Issue #14426: Correct the Date format in Expires attribute of Set-Cookie - Header in Cookie.py. +- Issue #16595: Add prlimit() to resource module. -- Issue #14588: The types module now provide new_class() and prepare_class() - functions to support PEP 3115 compliant dynamic class creation. Patch by - Daniel Urban and Nick Coghlan. +- Issue #19324: Expose Linux-specific constants in resource module. -- Issue #13152: Allow to specify a custom tabsize for expanding tabs in - textwrap. Patch by John Feuerstein. +- Load SSL's error strings in hashlib. -- Issue #14721: Send the correct 'Content-length: 0' header when the body is an - empty string ''. Initial Patch contributed by Arve Knudsen. +- Issue #18527: Upgrade internal copy of zlib to 1.2.8. -- Issue #14072: Fix parsing of 'tel' URIs in urlparse by making the check for - ports stricter. +- Issue #19274: Add a filterfunc parameter to PyZipFile.writepy. -- Issue #9374: Generic parsing of query and fragment portions of url for any - scheme. Supported both by RFC3986 and RFC2396. +- Issue #8964: fix platform._sys_version to handle IronPython 2.6+. + Patch by Martin Matusiak. -- Issue #14798: Fix the functions in pyclbr to raise an ImportError - when the first part of a dotted name is not a package. Patch by - Xavier de Gaye. +- Issue #19413: Restore pre-3.3 reload() semantics of re-finding modules. -- Issue #12098: multiprocessing on Windows now starts child processes - using the same sys.flags as the current process. Initial patch by - Sergey Mezentsev. +- Issue #18958: Improve error message for json.load(s) while passing a string + that starts with a UTF-8 BOM. -- Issue #13031: Small speed-up for tarfile when unzipping tarfiles. - Patch by Justin Peel. +- Issue #19307: Improve error message for json.load(s) while passing objects + of the wrong type. -- Issue #14780: urllib.request.urlopen() now has a ``cadefault`` argument - to use the default certificate store. Initial patch by James Oakley. +- Issue #16038: CVE-2013-1752: ftplib: Limit amount of data read by + limiting the call to readline(). Original patch by Michał + Jastrzębski and Giampaolo Rodola. -- Issue #14829: Fix bisect and range() indexing with large indices - (>= 2 ** 32) under 64-bit Windows. +- Issue #17087: Improved the repr for regular expression match objects. -- Issue #14732: The _csv module now uses PEP 3121 module initialization. - Patch by Robin Schreiber. +Tests +----- -- Issue #14809: Add HTTP status codes introduced by RFC 6585 to http.server - and http.client. Patch by EungJun Yi. +- Issue #19664: test_userdict's repr test no longer depends on the order + of dict elements. -- Issue #14777: tkinter may return undecoded UTF-8 bytes as a string when - accessing the Tk clipboard. Modify clipboad_get() to first request type - UTF8_STRING when no specific type is requested in an X11 windowing - environment, falling back to the current default type STRING if that fails. - Original patch by Thomas Kluyver. +- Issue #19440: Clean up test_capi by removing an unnecessary __future__ + import, converting from test_main to unittest.main, and running the + _testcapi module tests as subTests of a unittest TestCase method. -- Issue #14773: Fix os.fwalk() failing on dangling symlinks. +- Issue #19378: the main dis module tests are now run with both stdout + redirection *and* passing an explicit file parameter -- Issue #12541: Be lenient with quotes around Realm field of HTTP Basic - Authentation in urllib2. +- Issue #19378: removed the not-actually-helpful assertInstructionMatches + and assertBytecodeExactlyMatches helpers from bytecode_helper -- Issue #14807: move undocumented tarfile.filemode() to stat.filemode() and add - doc entry. Add tarfile.filemode alias with deprecation warning. +- Issue #18702: All skipped tests now reported as skipped. -- Issue #13815: TarFile.extractfile() now returns io.BufferedReader objects. +- Issue #19439: interpreter embedding tests are now executed on Windows + (Patch by Zachary Ware) -- Issue #14532: Add a secure_compare() helper to the hmac module, to mitigate - timing attacks. Patch by Jon Oberheide. +- Issue #19085: Added basic tests for all tkinter widget options. -- Add importlib.util.resolve_name(). +- Issue #19384: Fix test_py_compile for root user, patch by Claudiu Popa. -- Issue #14366: Support lzma compression in zip files. - Patch by Serhiy Storchaka. +Documentation +------------- -- Issue #13959: Introduce importlib.find_loader() and document - imp.find_module/load_module as deprecated. +- Issue #18326: Clarify that list.sort's arguments are keyword-only. Also, + attempt to reduce confusion in the glossary by not saying there are + different "types" of arguments and parameters. -- Issue #14082: shutil.copy2() now copies extended attributes, if possible. - Patch by Hynek Schlawack. +Build +----- -- Issue #13959: Make importlib.abc.FileLoader.load_module()/get_filename() and - importlib.machinery.ExtensionFileLoader.load_module() have their single - argument be optional. Allows for the replacement (and thus deprecation) of - imp.load_source()/load_package()/load_compiled(). +- Issue #19358: "make clinic" now runs the Argument Clinic preprocessor + over all CPython source files. -- Issue #13959: imp.get_suffixes() has been deprecated in favour of the new - attributes on importlib.machinery: SOURCE_SUFFIXES, DEBUG_BYTECODE_SUFFIXES, - OPTIMIZED_BYTECODE_SUFFIXES, BYTECODE_SUFFIXES, and EXTENSION_SUFFIXES. This - led to an indirect deprecation of inspect.getmoduleinfo(). +- Update SQLite to 3.8.1, xz to 5.0.5, and Tcl/Tk to 8.6.1 on Windows. -- Issue #14662: Prevent shutil failures on OS X when destination does not - support chflag operations. Patch by Hynek Schlawack. +- Issue #16632: Enable DEP and ASLR on Windows. -- Issue #14157: Fix time.strptime failing without a year on February 29th. - Patch by Hynek Schlawack. +- Issue #17791: Drop PREFIX and EXEC_PREFIX definitions from PC/pyconfig.h -- Issue #14753: Make multiprocessing's handling of negative timeouts - the same as it was in Python 3.2. +- Add workaround for VS 2010 nmake clean issue. VS 2010 doesn't set up PATH + for nmake.exe correctly. -- Issue #14583: Fix importlib bug when a package's __init__.py would first - import one of its modules then raise an error. +- Issue #19550: Implement Windows installer changes of PEP 453 (ensurepip). -- Issue #14741: Fix missing support for Ellipsis ('...') in parser module. +- Issue #19520: Fix compiler warning in the _sha3 module on 32bit Windows. -- Issue #14697: Fix missing support for set displays and set comprehensions in - parser module. +- Issue #19356: Avoid using a C variabled named "_self", it's a reserved + word in some C compilers. -- Issue #14701: Fix missing support for 'raise ... from' in parser module. +- Issue #15792: Correct build options on Win64. Patch by Jeremy Kloth. -- Add support for timeouts to the acquire() methods of - multiprocessing's lock/semaphore/condition proxies. +- Issue #19373: Apply upstream change to Tk 8.5.15 fixing OS X 10.9 + screen refresh problem for OS X installer build. -- Issue #13989: Add support for text mode to gzip.open(). +- Issue #19649: On OS X, the same set of file names are now installed + in bin directories for all configurations: non-framework vs framework, + and single arch vs universal builds. pythonx.y-32 is now always + installed for 64-bit/32-bit universal builds. The obsolete and + undocumented pythonw* symlinks are no longer installed anywhere. -- Issue #14127: The os.stat() result object now provides three additional - fields: st_ctime_ns, st_mtime_ns, and st_atime_ns, providing those times as an - integer with nanosecond resolution. The functions os.utime(), os.lutimes(), - and os.futimes() now accept a new parameter, ns, which accepts mtime and atime - as integers with nanosecond resolution. +- Issue #19553: PEP 453 - "make install" and "make altinstall" now install or + upgrade pip by default, using the bundled pip provided by the new ensurepip + module. A new configure option, --with-ensurepip[=upgrade|install|no], is + available to override the default ensurepip "--upgrade" option. The option + can also be set with "make [alt]install ENSUREPIP=[upgrade|install\no]". -- Issue #14127 and #10148: shutil.copystat now preserves exact mtime and atime - on filesystems providing nanosecond resolution. +- Issue #19551: PEP 453 - the OS X installer now installs pip by default. -IDLE ----- +- Update third-party libraries for OS X installers: xz 5.0.3 -> 5.0.5, + SQLite 3.7.13 -> 3.8.1 -- Issue #14958: Change IDLE systax highlighting to recognize all string and - byte literals supported in Python 3.3. +- Issue #15663: Revert OS X installer built-in Tcl/Tk support for 3.4.0b1. + Some third-party projects, such as Matplotlib and PIL/Pillow, + depended on being able to build with Tcl and Tk frameworks in + /Library/Frameworks. -- Issue #10997: Prevent a duplicate entry in IDLE's "Recent Files" menu. +Tools/Demos +----------- -- Issue #14929: Stop IDLE 3.x from closing on Unicode decode errors when - grepping. Patch by Roger Serwy. +- Issue #19730: Argument Clinic now supports all the existing PyArg + "format units" as legacy converters, as well as two new features: + "self converters" and the "version" directive. -- Issue #12510: Attempting to get invalid tooltip no longer closes IDLE. - Other tooltipss have been corrected or improved and the number of tests - has been tripled. Original patch by Roger Serwy. +- Issue #19552: pyvenv now bootstraps pip into virtual environments by + default (pass --without-pip to request the old behaviour) -Tools/Demos ------------ +- Issue #19390: Argument Clinic no longer accepts malformed Python + and C ids. -- Issue #14695: Bring Tools/parser/unparse.py support up to date with - the Python 3.3 Grammar. +What's New in Python 3.4.0 Alpha 4? +=================================== -Build ------ +Release date: 2013-10-20 -- Issue #14472: Update .gitignore. Patch by Matej Cepl. +Core and Builtins +----------------- -- Upgrade Windows library versions: bzip 1.0.6, OpenSSL 1.0.1c. +- Issue #19301: Give classes and functions that are explicitly marked global a + global qualname. -- Issue #14693: Under non-Windows platforms, hashlib's fallback modules are - always compiled, even if OpenSSL is present at build time. +- Issue #19279: UTF-7 decoder no longer produces illegal strings. -- Issue #13210: Windows build now uses VS2010, ported from VS2008. +- Issue #16612: Add "Argument Clinic", a compile-time preprocessor for + C files to generate argument parsing code. (See PEP 436.) -C-API ------ +- Issue #18810: Shift stat calls in importlib.machinery.FileFinder such that + the code is optimistic that if something exists in a directory named exactly + like the possible package being searched for that it's in actuality a + directory. -- Issue #14705: The PyArg_Parse() family of functions now support the 'p' format - unit, which accepts a "boolean predicate" argument. It converts any Python - value into an integer--0 if it is "false", and 1 otherwise. +- Issue #18416: importlib.machinery.PathFinder now treats '' as the cwd and + importlib.machinery.FileFinder no longer special-cases '' to '.'. This leads + to modules imported from cwd to now possess an absolute file path for + __file__ (this does not affect modules specified by path on the CLI but it + does affect -m/runpy). It also allows FileFinder to be more consistent by not + having an edge case. -Documentation -------------- +- Issue #4555: All exported C symbols are now prefixed with either + "Py" or "_Py". -- Issue #14863: Update the documentation of os.fdopen() to reflect the - fact that it's only a thin wrapper around open() anymore. +- Issue #19219: Speed up marshal.loads(), and make pyc files slightly + (5% to 10%) smaller. -- Issue #14588: The language reference now accurately documents the Python 3 - class definition process. Patch by Nick Coghlan. +- Issue #19221: Upgrade Unicode database to version 6.3.0. -- Issue #14943: Correct a default argument value for winreg.OpenKey - and correctly list the argument names in the function's explanation. +- Issue #16742: The result of the C callback PyOS_ReadlineFunctionPointer must + now be a string allocated by PyMem_RawMalloc() or PyMem_RawRealloc() (or NULL + if an error occurred), instead of a string allocated by PyMem_Malloc() or + PyMem_Realloc(). +- Issue #19199: Remove ``PyThreadState.tick_counter`` field -What's New in Python 3.3.0 Alpha 3? -=================================== +- Fix macro expansion of _PyErr_OCCURRED(), and make sure to use it in at + least one place so as to avoid regressions. -*Release date: 01-May-2012* +- Issue #19087: Improve bytearray allocation in order to allow cheap popping + of data at the front (slice deletion). -Core and Builtins ------------------ +- Issue #19014: memoryview.cast() is now allowed on zero-length views. -- Issue #14699: Fix calling the classmethod descriptor directly. +- Issue #18690: memoryview is now automatically registered with + collections.abc.Sequence -- Issue #14433: Prevent msvcrt crash in interactive prompt when stdin is closed. +- Issue #19078: memoryview now correctly supports the reversed builtin + (Patch by Claudiu Popa) -- Issue #14521: Make result of float('nan') and float('-nan') more consistent - across platforms. +Library +------- -- Issue #14646: __import__() sets __loader__ if the loader did not. +- Issue #17457: unittest test discovery now works with namespace packages. + Patch by Claudiu Popa. -- Issue #14605: No longer have implicit entries in sys.meta_path. If - sys.meta_path is found to be empty, raise ImportWarning. +- Issue #18235: Fix the sysconfig variables LDSHARED and BLDSHARED under AIX. + Patch by David Edelsohn. -- Issue #14605: No longer have implicit entries in sys.path_hooks. If - sys.path_hooks is found to be empty, a warning will be raised. None is now - inserted into sys.path_importer_cache if no finder was discovered. This also - means imp.NullImporter is no longer implicitly used. +- Issue #18606: Add the new "statistics" module (PEP 450). Contributed + by Steven D'Aprano. -- Issue #13903: Implement PEP 412. Individual dictionary instances can now share - their keys with other dictionaries. Classes take advantage of this to share - their instance dictionary keys for improved memory and performance. +- Issue #12866: The audioop module now supports 24-bit samples. -- Issue #11603 (again): Setting __repr__ to __str__ now raises a RuntimeError - when repr() or str() is called on such an object. +- Issue #19254: Provide an optimized Python implementation of pbkdf2_hmac. -- Issue #14658: Fix binding a special method to a builtin implementation of a - special method with a different name. +- Issues #19201, Issue #19222, Issue #19223: Add "x" mode (exclusive creation) + in opening file to bz2, gzip and lzma modules. Patches by Tim Heaney and + Vajrasky Kok. -- Issue #14630: Fix a memory access bug for instances of a subclass of int - with value 0. +- Fix a reference count leak in _sre. -- Issue #14339: Speed improvements to bin, oct and hex functions. Patch by - Serhiy Storchaka. +- Issue #19262: Initial check in of the 'asyncio' package (a.k.a. Tulip, + a.k.a. PEP 3156). There are no docs yet, and the PEP is slightly + out of date with the code. This module will have *provisional* status + in Python 3.4. -- Issue #14385: It is now possible to use a custom type for the __builtins__ - namespace, instead of a dict. It can be used for sandboxing for example. - Raise also a NameError instead of ImportError if __build_class__ name if not - found in __builtins__. +- Issue #19276: Fixed the wave module on 64-bit big-endian platforms. -- Issue #12599: Be more strict in accepting None compared to a false-like - object for importlib.util.module_for_loader and - importlib.machinery.PathFinder. +- Issue #19266: Rename the new-in-3.4 ``contextlib.ignore`` context manager + to ``contextlib.suppress`` in order to be more consistent with existing + descriptions of that operation elsewhere in the language and standard + library documentation (Patch by Zero Piraeus). -- Issue #14612: Fix jumping around with blocks by setting f_lineno. +- Issue #18891: Completed the new email package (provisional) API additions + by adding new classes EmailMessage, MIMEPart, and ContentManager. -- Issue #14592: Attempting a relative import w/o __package__ or __name__ set in - globals raises a KeyError. +- Issue #18281: Unused stat constants removed from `tarfile`. -- Issue #14607: Fix keyword-only arguments which started with ``__``. +- Issue #18999: Multiprocessing now supports 'contexts' with the same API + as the module, but bound to specified start methods. -- Issue #10854: The ImportError raised when an extension module on Windows - fails to import now uses the new path and name attributes from - Issue #1559549. +- Issue #18468: The re.split, re.findall, and re.sub functions and the group() + and groups() methods of match object now always return a string or a bytes + object. -- Issue #13889: Check and (if necessary) set FPU control word before calling - any of the dtoa.c string <-> float conversion functions, on MSVC builds of - Python. This fixes issues when embedding Python in a Delphi app. +- Issue #18725: The textwrap module now supports truncating multiline text. -- __import__() now matches PEP 328 and documentation by defaulting 'index' to 0 - instead of -1 and removing support for negative values. +- Issue #18776: atexit callbacks now display their full traceback when they + raise an exception. -- Issue #2377: Make importlib the implementation of __import__(). +- Issue #17827: Add the missing documentation for ``codecs.encode`` and + ``codecs.decode``. -- Issue #1559549: ImportError now has 'name' and 'path' attributes that are set - using keyword arguments to its constructor. They are currently not set by - import as they are meant for use by importlib. +- Issue #19218: Rename collections.abc to _collections_abc in order to + speed up interpreter start. -- Issue #14474: Save and restore exception state in thread.start_new_thread() - while writing error message if the thread leaves a unhandled exception. +- Issue #18582: Add 'pbkdf2_hmac' to the hashlib module. It implements PKCS#5 + password-based key derivation functions with HMAC as pseudorandom function. -- Issue #13019: Fix potential reference leaks in bytearray.extend(). Patch - by Suman Saha. +- Issue #19131: The aifc module now correctly reads and writes sampwidth of + compressed streams. -Library -------- +- Issue #19209: Remove import of copyreg from the os module to speed up + interpreter startup. stat_result and statvfs_result are now hard-coded to + reside in the os module. -- Issue #14768: os.path.expanduser('~/a') doesn't works correctly when HOME is '/'. +- Issue #19205: Don't import the 're' module in site and sysconfig module to + speed up interpreter start. -- Issue #14371: Support bzip2 in zipfile module. Patch by Serhiy Storchaka. +- Issue #9548: Add a minimal "_bootlocale" module that is imported by the + _io module instead of the full locale module. -- Issue #13183: Fix pdb skipping frames after hitting a breakpoint and running - step. Patch by Xavier de Gaye. +- Issue #18764: remove the 'print' alias for the PDB 'p' command so that it no + longer shadows the print function. -- Issue #14696: Fix parser module to understand 'nonlocal' declarations. +- Issue #19158: a rare race in BoundedSemaphore could allow .release() too + often. -- Issue #10941: Fix imaplib.Internaldate2tuple to produce correct result near - the DST transition. Patch by Joe Peterson. +- Issue #15805: Add contextlib.redirect_stdout(). -- Issue #9154: Fix parser module to understand function annotations. +- Issue #18716: Deprecate the formatter module. -- Issue #6085: In http.server.py SimpleHTTPServer.address_string returns the - client ip address instead client hostname. Patch by Charles-François Natali. +- Issue #10712: 2to3 has a new "asserts" fixer that replaces deprecated names + of unittest methods (e.g. failUnlessEqual -> assertEqual). -- Issue #14309: Deprecate time.clock(), use time.perf_counter() or - time.process_time() instead. +- Issue #18037: 2to3 now escapes '\u' and '\U' in native strings. -- Issue #14428: Implement the PEP 418. Add time.get_clock_info(), - time.perf_counter() and time.process_time() functions, and rename - time.steady() to time.monotonic(). +- Issue #17839: base64.decodebytes and base64.encodebytes now accept any + object that exports a 1 dimensional array of bytes (this means the same + is now also true for base64_codec) -- Issue #14646: importlib.util.module_for_loader() now sets __loader__ and - __package__ (when possible). +- Issue #19132: The pprint module now supports compact mode. -- Issue #14664: It is now possible to use @unittest.skip{If,Unless} on a - test class that doesn't inherit from TestCase (i.e. a mixin). +- Issue #19137: The pprint module now correctly formats instances of set and + frozenset subclasses. -- Issue #4892: multiprocessing Connections can now be transferred over - multiprocessing Connections. Patch by Richard Oudkerk (sbt). +- Issue #10042: functools.total_ordering now correctly handles + NotImplemented being returned by the underlying comparison function (Patch + by Katie Miller) -- Issue #14160: TarFile.extractfile() failed to resolve symbolic links when - the links were not located in an archive subdirectory. +- Issue #19092: contextlib.ExitStack now correctly reraises exceptions + from the __exit__ callbacks of inner context managers (Patch by Hrvoje + Nikšić) -- Issue #14638: pydoc now treats non-string __name__ values as if they - were missing, instead of raising an error. +- Issue #12641: Avoid passing "-mno-cygwin" to the mingw32 compiler, except + when necessary. Patch by Oscar Benjamin. -- Issue #13684: Fix httplib tunnel issue of infinite loops for certain sites - which send EOF without trailing \r\n. +- Issue #5845: In site.py, only load readline history from ~/.python_history + if no history has been read already. This avoids double writes to the + history file at shutdown. -- Issue #14605: Add importlib.abc.FileLoader, importlib.machinery.(FileFinder, - SourceFileLoader, SourcelessFileLoader, ExtensionFileLoader). +- Properly initialize all fields of a SSL object after allocation. -- Issue #13959: imp.cache_from_source()/source_from_cache() now follow - os.path.join()/split() semantics for path manipulation instead of its prior, - custom semantics of caring the right-most path separator forward in path - joining. +- Issue #19095: SSLSocket.getpeercert() now raises ValueError when the + SSL handshake hasn't been done. -- Issue #2193: Allow ":" character in Cookie NAME values. +- Issue #4366: Fix building extensions on all platforms when --enable-shared + is used. -- Issue #14629: tokenizer.detect_encoding will specify the filename in the - SyntaxError exception if found at readline.__self__.name. +- Issue #19030: Fixed `inspect.getmembers` and `inspect.classify_class_attrs` + to attempt activating descriptors before falling back to a __dict__ search + for faulty descriptors. `inspect.classify_class_attrs` no longer returns + Attributes whose home class is None. -- Issue #14629: Raise SyntaxError in tokenizer.detect_encoding if the - first two lines have non-UTF-8 characters without an encoding declaration. +C API +----- -- Issue #14308: Fix an exception when a "dummy" thread is in the threading - module's active list after a fork(). +- Issue #1772673: The type of `char*` arguments now changed to `const char*`. -- Issue #11750: The Windows API functions scattered in the _subprocess and - _multiprocessing.win32 modules now live in a single module "_winapi". - Patch by sbt. +- Issue #16129: Added a `Py_SetStandardStreamEncoding` pre-initialization API + to allow embedding applications like Blender to force a particular + encoding and error handler for the standard IO streams (initial patch by + Bastien Montagne) -- Issue #14087: multiprocessing: add Condition.wait_for(). Patch by sbt. +Tests +----- -- Issue #14538: HTMLParser can now parse correctly start tags that contain - a bare '/'. +- Issue #19275: Fix test_site on AMD64 Snow Leopard -- Issue #14452: SysLogHandler no longer inserts a UTF-8 BOM into the message. +- Issue #14407: Fix unittest test discovery in test_concurrent_futures. -- Issue #14386: Expose the dict_proxy internal type as types.MappingProxyType. +- Issue #18919: Unified and extended tests for audio modules: aifc, sunau and + wave. -- Issue #13959: Make imp.reload() always use a module's __loader__ to perform - the reload. +- Issue #18714: Added tests for ``pdb.find_function()``. -- Issue #13959: Add imp.py and rename the built-in module to _imp, allowing for - re-implementing parts of the module in pure Python. +Documentation +------------- -- Issue #13496: Fix potential overflow in bisect.bisect algorithm when applied - to a collection of size > sys.maxsize / 2. +- Issue #18758: Fixed and improved cross-references. -- Have importlib take advantage of ImportError's new 'name' and 'path' - attributes. +- Issue #18972: Modernize email examples and use the argparse module in them. -- Issue #14399: zipfile now recognizes that the archive has been modified even - if only the comment is changed. In addition, the TypeError that results from - trying to set a non-binary value as a comment is now raised at the time - the comment is set rather than at the time the zipfile is written. +Build +----- -- trace.CoverageResults.is_ignored_filename() now ignores any name that starts - with "<" and ends with ">" instead of special-casing "" and - ". +Core and Builtins +----------------- -- Issue #14295: Add unittest.mock +- Issue #18942: sys._debugmallocstats() output was damaged on Windows. -- Issue #7652: Add --with-system-libmpdec option to configure for linking - the _decimal module against an installed libmpdec. +- Issue #18571: Implementation of the PEP 446: file descriptors and file + handles are now created non-inheritable; add functions + os.get/set_inheritable(), os.get/set_handle_inheritable() and + socket.socket.get/set_inheritable(). -- Issue #14380: MIMEText now defaults to utf-8 when passed non-ASCII unicode - with no charset specified. +- Issue #11619: The parser and the import machinery do not encode Unicode + filenames anymore on Windows. -- Issue #10340: asyncore - properly handle EINVAL in dispatcher constructor on - OSX; avoid to call handle_connect in case of a disconnected socket which - was not meant to connect. +- Issue #18808: Non-daemon threads are now automatically joined when + a sub-interpreter is shutdown (it would previously dump a fatal error). -- Issue #14204: The ssl module now has support for the Next Protocol - Negotiation extension, if available in the underlying OpenSSL library. - Patch by Colin Marc. +- Remove support for compiling on systems without getcwd(). -- Issue #3035: Unused functions from tkinter are marked as pending deprecated. +- Issue #18774: Remove last bits of GNU PTH thread code and thread_pth.h. -- Issue #12757: Fix the skipping of doctests when python is run with -OO so - that it works in unittest's verbose mode as well as non-verbose mode. +- Issue #18771: Add optimization to set object lookups to reduce the cost + of hash collisions. The core idea is to inspect a second key/hash pair + for each cache line retrieved. -- Issue #7652: Integrate the decimal floating point libmpdec library to speed - up the decimal module. Performance gains of the new C implementation are - between 10x and 100x, depending on the application. +- Issue #16105: When a signal handler fails to write to the file descriptor + registered with ``signal.set_wakeup_fd()``, report an exception instead + of ignoring the error. -- Issue #14269: SMTPD now conforms to the RFC and requires a HELO command - before MAIL, RCPT, or DATA. +- Issue #18722: Remove uses of the "register" keyword in C code. -- Issue #13694: asynchronous connect in asyncore.dispatcher does not set addr - attribute. +- Issue #18667: Add missing "HAVE_FCHOWNAT" symbol to posix._have_functions. -- Issue #14344: fixed the repr of email.policy objects. +- Issue #16499: Add command line option for isolated mode. -- Issue #11686: Added missing entries to email package __all__ lists - (mostly the new Bytes classes). +- Issue #15301: Parsing fd, uid, and gid parameters for builtins + in Modules/posixmodule.c is now far more robust. -- Issue #14335: multiprocessing's custom Pickler subclass now inherits from - the C-accelerated implementation. Patch by sbt. +- Issue #18368: PyOS_StdioReadline() no longer leaks memory when realloc() + fail. -- Issue #10484: Fix the CGIHTTPServer's PATH_INFO handling problem. +- Issue #17934: Add a clear() method to frame objects, to help clean up + expensive details (local variables) and break reference cycles. -- Issue #11199: Fix the with urllib which hangs on particular ftp urls. +- Issue #18780: %-formatting codes %d, %i, and %u now treat int-subclasses + as int (displays value of int-subclass instead of str(int-subclass) ). -- Improve the memory utilization and speed of functools.lru_cache. +Library +------- -- Issue #14222: Use the new time.steady() function instead of time.time() for - timeout in queue and threading modules to not be affected of system time - update. +- Issue #18808: Thread.join() now waits for the underlying thread state to + be destroyed before returning. This prevents unpredictable aborts in + Py_EndInterpreter() when some non-daemon threads are still running. -- Issue #13248: Remove lib2to3.pytree.Base.get_prefix/set_prefix. +- Issue #18458: Prevent crashes with newer versions of libedit. Its readline + emulation has changed from 0-based indexing to 1-based like gnu readline. -- Issue #14234: CVE-2012-0876: Randomize hashes of xml attributes in the hash - table internal to the pyexpat module's copy of the expat library to avoid a - denial of service due to hash collisions. Patch by David Malcolm with some - modifications by the expat project. +- Issue #18852: Handle case of ``readline.__doc__`` being ``None`` in the new + readline activation code in ``site.py``. -- Issue #12818: format address no longer needlessly \ escapes ()s in names when - the name ends up being quoted. +- Issue #18672: Fixed format specifiers for Py_ssize_t in debugging output in + the _sre module. -- Issue #14062: BytesGenerator now correctly folds Header objects, - including using linesep when folding. +- Issue #18830: inspect.getclasstree() no longer produces duplicate entries even + when input list contains duplicates. -- Issue #13839: When invoked on the command-line, the pstats module now - accepts several filenames of profile stat files and merges them all. - Patch by Matt Joiner. +- Issue #18878: sunau.open now supports the context management protocol. Based on + patches by Claudiu Popa and R. David Murray. -- Issue #14291: Email now defaults to utf-8 for non-ASCII unicode headers - instead of raising an error. This fixes a regression relative to 2.7. +- Issue #18909: Fix _tkinter.tkapp.interpaddr() on Windows 64-bit, don't cast + 64-bit pointer to long (32 bits). -- Issue #989712: Support using Tk without a mainloop. +- Issue #18876: The FileIO.mode attribute now better reflects the actual mode + under which the file was opened. Patch by Erik Bray. -- Issue #3835: Refuse to use unthreaded Tcl in threaded Python. +- Issue #16853: Add new selectors module. -- Issue #2843: Add new Tk API to Tkinter. +- Issue #18882: Add threading.main_thread() function. -- Issue #14184: Increase the default stack size for secondary threads on - Mac OS X to avoid interpreter crashes when using threads on 10.7. +- Issue #18901: The sunau getparams method now returns a namedtuple rather than + a plain tuple. Patch by Claudiu Popa. -- Issue #14180: datetime.date.fromtimestamp(), - datetime.datetime.fromtimestamp() and datetime.datetime.utcfromtimestamp() - now raise an OSError instead of ValueError if localtime() or gmtime() failed. +- Issue #17487: The result of the wave getparams method now is pickleable again. + Patch by Claudiu Popa. -- Issue #14180: time.ctime(), gmtime(), time.localtime(), - datetime.date.fromtimestamp(), datetime.datetime.fromtimestamp() and - datetime.datetime.utcfromtimestamp() now raises an OverflowError, instead of - a ValueError, if the timestamp does not fit in time_t. +- Issue #18756: os.urandom() now uses a lazily-opened persistent file + descriptor, so as to avoid using many file descriptors when run in + parallel from multiple threads. -- Issue #14180: datetime.datetime.fromtimestamp() and - datetime.datetime.utcfromtimestamp() now round microseconds towards zero - instead of rounding to nearest with ties going away from zero. +- Issue #18418: After fork(), reinit all threads states, not only active ones. + Patch by A. Jesse Jiryu Davis. -- Issue #10543: Fix unittest test discovery with Jython bytecode files. +- Issue #17974: Switch unittest from using getopt to using argparse. -- Issue #1178863: Separate initialisation from setting when initializing - Tkinter.Variables; harmonize exceptions to ValueError; only delete variables - that have not been deleted; assert that variable names are strings. +- Issue #11798: TestSuite now drops references to own tests after execution. -- Issue #14104: Implement time.monotonic() on Mac OS X, patch written by - Nicholas Riley. +- Issue #16611: http.cookie now correctly parses the 'secure' and 'httponly' + cookie flags. -- Issue #13394: the aifc module now uses warnings.warn() to signal warnings. +- Issue #11973: Fix a problem in kevent. The flags and fflags fields are now + properly handled as unsigned. -- Issue #14252: Fix subprocess.Popen.terminate() to not raise an error under - Windows when the child process has already exited. +- Issue #18807: ``pyvenv`` now takes a --copies argument allowing copies + instead of symlinks even where symlinks are available and the default. -- Issue #14223: curses.addch() is no more limited to the range 0-255 when the - Python curses is not linked to libncursesw. It was a regression introduced - in Python 3.3a1. +- Issue #18538: ``python -m dis`` now uses argparse for argument processing. + Patch by Michele Orrù. -- Issue #14168: Check for presence of Element._attrs in minidom before - accessing it. +- Issue #18394: Close cgi.FieldStorage's optional file. -- Issue #12328: Fix multiprocessing's use of overlapped I/O on Windows. - Also, add a multiprocessing.connection.wait(rlist, timeout=None) function - for polling multiple objects at once. Patch by sbt. +- Issue #17702: On error, os.environb now suppresses the exception context + when raising a new KeyError with the original key. -- Issue #14007: Accept incomplete TreeBuilder objects (missing start, end, - data or close method) for the Python implementation as well. - Drop the no-op TreeBuilder().xml() method from the C implementation. +- Issue #16809: Fixed some tkinter incompabilities with Tcl/Tk 8.6. -- Issue #14210: pdb now has tab-completion not only for command names, but - also for their arguments, wherever possible. +- Issue #16809: Tkinter's splitlist() and split() methods now accept Tcl_Obj + argument. -- Issue #14310: Sockets can now be with other processes on Windows using - the api socket.socket.share() and socket.fromshare(). +- Issue #18324: set_payload now correctly handles binary input. This also + supersedes the previous fixes for #14360, #1717, and #16564. -- Issue #10576: The gc module now has a 'callbacks' member that will get - called when garbage collection takes place. +- Issue #18794: Add a fileno() method and a closed attribute to select.devpoll + objects. -Build ------ +- Issue #17119: Fixed integer overflows when processing large strings and tuples + in the tkinter module. -- Issue #14557: Fix extensions build on HP-UX. Patch by Adi Roiban. +- 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. -- Issue #14387: Do not include accu.h from Python.h. +- Issue #8865: Concurrent invocation of select.poll.poll() now raises a + RuntimeError exception. Patch by Christian Schubert. -- Issue #14359: Only use O_CLOEXEC in _posixmodule.c if it is defined. - Based on patch from Hervé Coatanhay. +- Issue #18777: The ssl module now uses the new CRYPTO_THREADID API of + OpenSSL 1.0.0+ instead of the deprecated CRYPTO id callback function. -- Issue #14321: Do not run pgen during the build if files are up to date. +- Issue #18768: Correct doc string of RAND_edg(). Patch by Vajrasky Kok. -Documentation -------------- +- Issue #18178: Fix ctypes on BSD. dlmalloc.c was compiled twice which broke + malloc weak symbols. -- Issue #14034: added the argparse tutorial. +- 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 represention of ASN.1 + strings for ``rfc822Name`` (email), ``dNSName`` (DNS) and + ``uniformResourceIdentifier`` (URI). -- Issue #14324: Fix configure tests for cross builds. +- Issue #18701: Remove support of old CPython versions (<3.0) from C code. -- Issue #14327: Call AC_CANONICAL_HOST in configure.ac and check in - config.{guess,sub}. Don't use uname calls for cross builds. +- Issue #18756: Improve error reporting in os.urandom() when the failure + is due to something else than /dev/urandom not existing (for example, + exhausting the file descriptor limit). -Extension Modules ------------------ +- Issue #18673: Add O_TMPFILE to os module. O_TMPFILE requires Linux kernel + 3.11 or newer. It's only defined on system with 3.11 uapi headers, too. -- Issue #9041: An issue in ctypes.c_longdouble, ctypes.c_double, and - ctypes.c_float that caused an incorrect exception to be returned in the - case of overflow has been fixed. +- Issue #18532: Change the builtin hash algorithms' names to lower case names + as promised by hashlib's documentation. -- Issue #14212: The re module didn't retain a reference to buffers it was - scanning, resulting in segfaults. +- Issue #8713: add new spwan and forkserver start methods, and new functions + get_all_start_methods, get_start_method, and set_start_method, to + multiprocessing. -- Issue #14259: The finditer() method of re objects did not take any - keyword arguments, contrary to the documentation. +- Issue #18405: Improve the entropy of crypt.mksalt(). -- Issue #10142: Support for SEEK_HOLE/SEEK_DATA (for example, under ZFS). +- Issue #12015: The tempfile module now uses a suffix of 8 random characters + instead of 6, to reduce the risk of filename collision. The entropy was + reduced when uppercase letters were removed from the charset used to generate + random characters. -Tests ------ +- Issue #18585: Add :func:`textwrap.shorten` to collapse and truncate a + piece of text to a given length. -- Issue #14442: Add missing errno import in test_smtplib. +- Issue #18598: Tweak exception message for importlib.import_module() to + include the module name when a key argument is missing. -- Issue #8315: (partial fix) python -m unittest test.test_email now works. +- Issue #19151: Fix docstring and use of _get_supported_file_loaders() to + reflect 2-tuples. +- Issue #19152: Add ExtensionFileLoader.get_filename(). -What's New in Python 3.3.0 Alpha 1? -=================================== +- Issue #18676: Change 'positive' to 'non-negative' in queue.py put and get + docstrings and ValueError messages. Patch by Zhongyue Luo -*Release date: 05-Mar-2012* +- Fix refcounting issue with extension types in tkinter. -Core and Builtins ------------------ +- Issue #8112: xlmrpc.server's DocXMLRPCServer server no longer raises an error + if methods have annotations; it now correctly displays the annotations. -- Issue #14172: Fix reference leak when marshalling a buffer-like object - (other than a bytes object). +- Issue #18600: Added policy argument to email.message.Message.as_string, + and as_bytes and __bytes__ methods to Message. -- Issue #13521: dict.setdefault() now does only one lookup for the given key, - making it "atomic" for many purposes. Patch by Filip Gruszczyński. +- Issue #18671: Output more information when logging exceptions occur. -- PEP 409, Issue #6210: "raise X from None" is now supported as a means of - suppressing the display of the chained exception context. The chained - context still remains available as the __context__ attribute. +- Issue #18621: Prevent the site module's patched builtins from keeping + too many references alive for too long. -- Issue #10181: New memoryview implementation fixes multiple ownership - and lifetime issues of dynamically allocated Py_buffer members (#9990) - as well as crashes (#8305, #7433). Many new features have been added - (See whatsnew/3.3), and the documentation has been updated extensively. - The ndarray test object from _testbuffer.c implements all aspects of - PEP-3118, so further development towards the complete implementation - of the PEP can proceed in a test-driven manner. +- Issue #4885: Add weakref support to mmap objects. Patch by Valerie Lambert. - Thanks to Nick Coghlan, Antoine Pitrou and Pauli Virtanen for review - and many ideas. +- Issue #8860: Fixed rounding in timedelta constructor. -- Issue #12834: Fix incorrect results of memoryview.tobytes() for - non-contiguous arrays. +- Issue #18849: Fixed a Windows-specific tempfile bug where collision with an + existing directory caused mkstemp and related APIs to fail instead of + retrying. Report and fix by Vlad Shcherbina. -- Issue #5231: Introduce memoryview.cast() method that allows changing - format and shape without making a copy of the underlying memory. +- Issue #18920: argparse's default destination for the version action (-v, + --version) has also been changed to stdout, to match the Python executable. -- Issue #14084: Fix a file descriptor leak when importing a module with a - bad encoding. +Tests +----- -- Upgrade Unicode data to Unicode 6.1. +- Issue #18623: Factor out the _SuppressCoreFiles context manager into + test.support. Patch by Valerie Lambert. -- Issue #14040: Remove rarely used file name suffixes for C extensions - (under POSIX mainly). +- Issue #12037: Fix test_email for desktop Windows. -- Issue #14051: Allow arbitrary attributes to be set of classmethod and - staticmethod. +- Issue #15507: test_subprocess's test_send_signal could fail if the test + runner were run in an environment where the process inherited an ignore + setting for SIGINT. Restore the SIGINT handler to the desired + KeyboardInterrupt raising one during that test. -- Issue #13703: oCERT-2011-003: Randomize hashes of str and bytes to protect - against denial of service attacks due to hash collisions within the dict and - set types. Patch by David Malcolm, based on work by Victor Stinner. +- Issue #16799: Switched from getopt to argparse style in regrtest's argument + parsing. Added more tests for regrtest's argument parsing. -- Issue #13020: Fix a reference leak when allocating a structsequence object - fails. Patch by Suman Saha. +- Issue #18792: Use "127.0.0.1" or "::1" instead of "localhost" as much as + possible, since "localhost" goes through a DNS lookup under recent Windows + versions. -- Issue #13908: Ready types returned from PyType_FromSpec. +IDLE +---- -- Issue #11235: Fix OverflowError when trying to import a source file whose - modification time doesn't fit in a 32-bit timestamp. +- Issue #18489: Add tests for SearchEngine. Original patch by Phil Webster. -- Issue #12705: A SyntaxError exception is now raised when attempting to - compile multiple statements as a single interactive statement. +Documentation +------------- -- Fix the builtin module initialization code to store the init function for - future reinitialization. +- Issue #18743: Fix references to non-existant "StringIO" module. -- Issue #8052: The posix subprocess module would take a long time closing - all possible file descriptors in the child process rather than just open - file descriptors. It now closes only the open fds if possible for the - default close_fds=True behavior. +- Issue #18783: Removed existing mentions of Python long type in docstrings, + error messages and comments. -- Issue #13629: Renumber the tokens in token.h so that they match the indexes - into _PyParser_TokenNames. +Build +----- -- Issue #13752: Add a casefold() method to str. +- Issue #1584: Provide configure options to override default search paths for + Tcl and Tk when building _tkinter. -- Issue #13761: Add a "flush" keyword argument to the print() function, - used to ensure flushing the output stream. +- Issue #15663: Tcl/Tk 8.5.14 is now included with the OS X 10.6+ 64-/32-bit + installer. It is no longer necessary to install a third-party version of + Tcl/Tk 8.5 to work around the problems in the Apple-supplied Tcl/Tk 8.5 + shipped in OS X 10.6 and later releases. -- Issue #13645: pyc files now contain the size of the corresponding source - code, to avoid timestamp collisions (especially on filesystems with a low - timestamp resolution) when checking for freshness of the bytecode. +Tools/Demos +----------- -- PEP 380, Issue #11682: Add "yield from " to support easy delegation to - subgenerators (initial patch by Greg Ewing, integration into 3.3 by - Renaud Blanch, Ryan Kelly, Zbigniew Jędrzejewski-Szmek and Nick Coghlan) +- Issue #18922: Now The Lib/smtpd.py and Tools/i18n/msgfmt.py scripts write + their version strings to stdout, and not to sderr. -- Issue #13748: Raw bytes literals can now be written with the ``rb`` prefix - as well as ``br``. +What's New in Python 3.4.0 Alpha 1? +=================================== -- Issue #12736: Use full unicode case mappings for upper, lower, and title case. +Release date: 2013-08-03 -- Issue #12760: Add a create mode to open(). Patch by David Townshend. +Core and Builtins +----------------- -- Issue #13738: Simplify implementation of bytes.lower() and bytes.upper(). +- Issue #16741: Fix an error reporting in int(). -- Issue #13577: Built-in methods and functions now have a __qualname__. - Patch by sbt. +- Issue #17899: Fix rare file descriptor leak in os.listdir(). -- Issue #6695: Full garbage collection runs now clear the freelist of set - objects. Initial patch by Matthias Troffaes. +- Issue #10241: Clear extension module dict copies at interpreter shutdown. + Patch by Neil Schemenauer, minimally modified. -- Fix OSError.__init__ and OSError.__new__ so that each of them can be - overriden and take additional arguments (followup to issue #12555). +- Issue #9035: ismount now recognises volumes mounted below a drive root + on Windows. Original patch by Atsuo Ishimoto. -- Fix the fix for issue #12149: it was incorrect, although it had the side - effect of appearing to resolve the issue. Thanks to Mark Shannon for - noticing. +- Issue #18214: Improve finalization of Python modules to avoid setting + their globals to None, in most cases. -- Issue #13505: Pickle bytes objects in a way that is compatible with - Python 2 when using protocols <= 2. +- Issue #18112: PEP 442 implementation (safe object finalization). -- Issue #11147: Fix an unused argument in _Py_ANNOTATE_MEMORY_ORDER. (Fix - given by Campbell Barton). +- Issue #18552: Check return value of PyArena_AddPyObject() in + obj2ast_object(). -- Issue #13503: Use a more efficient reduction format for bytearrays with - pickle protocol >= 3. The old reduction format is kept with older protocols - in order to allow unpickling under Python 2. Patch by Irmen de Jong. +- Issue #18560: Fix potential NULL pointer dereference in sum(). -- Issue #7111: Python can now be run without a stdin, stdout or stderr - stream. It was already the case with Python 2. However, the corresponding - sys module entries are now set to None (instead of an unusable file object). +- Issue #18520: Add a new PyStructSequence_InitType2() function, same than + PyStructSequence_InitType() except that it has a return value (0 on success, + -1 on error). -- Issue #11849: Ensure that free()d memory arenas are really released - on POSIX systems supporting anonymous memory mappings. Patch by - Charles-François Natali. +- Issue #15905: Fix theoretical buffer overflow in handling of sys.argv[0], + prefix and exec_prefix if the operation system does not obey MAXPATHLEN. -- PEP 3155 / issue #13448: Qualified name for classes and functions. +- Issue #18408: Fix many various bugs in code handling errors, especially + on memory allocation failure (MemoryError). -- Issue #13436: Fix a bogus error message when an AST object was passed - an invalid integer value. +- Issue #18344: Fix potential ref-leaks in _bufferedreader_read_all(). -- Issue #13411: memoryview objects are now hashable when the underlying - object is hashable. +- Issue #18342: Use the repr of a module name when an import fails when using + ``from ... import ...``. -- Issue #13338: Handle all enumerations in _Py_ANNOTATE_MEMORY_ORDER - to allow compiling extension modules with -Wswitch-enum on gcc. - Initial patch by Floris Bruynooghe. +- Issue #17872: Fix a segfault in marshal.load() when input stream returns + more bytes than requested. -- Issue #10227: Add an allocation cache for a single slice object. Patch by - Stefan Behnel. +- Issue #18338: `python --version` now prints version string to stdout, and + not to stderr. Patch by Berker Peksag and Michael Dickens. -- Issue #13393: BufferedReader.read1() now asks the full requested size to - the raw stream instead of limiting itself to the buffer size. +- Issue #18426: Fix NULL pointer dereference in C extension import when + PyModule_GetDef() returns an error. -- Issue #13392: Writing a pyc file should now be atomic under Windows as well. +- Issue #17206: On Windows, increase the stack size from 2 MB to 4.2 MB to fix + a stack overflow in the marshal module (fix a crash in test_marshal). + Patch written by Jeremy Kloth. -- Issue #13333: The UTF-7 decoder now accepts lone surrogates (the encoder - already accepts them). +- Issue #3329: Implement the PEP 445: Add new APIs to customize Python memory + allocators. -- Issue #13389: Full garbage collection passes now clear the freelists for - list and dict objects. They already cleared other freelists in the - interpreter. +- Issue #18328: Reorder ops in PyThreadState_Delete*() functions. Now the + tstate is first removed from TLS and then deallocated. -- Issue #13327: Remove the need for an explicit None as the second argument - to os.utime, os.lutimes, os.futimes, os.futimens, os.futimesat, in - order to update to the current time. Also added keyword argument - handling to os.utimensat in order to remove the need for explicit None. +- Issue #13483: Use VirtualAlloc in obmalloc on Windows. -- Issue #13350: Simplify some C code by replacing most usages of - PyUnicode_Format by PyUnicode_FromFormat. +- Issue #18184: PyUnicode_FromFormat() and PyUnicode_FromFormatV() now raise + OverflowError when an argument of %c format is out of range. -- Issue #13342: input() used to ignore sys.stdin's and sys.stdout's unicode - error handler in interactive mode (when calling into PyOS_Readline()). +- Issue #18111: The min() and max() functions now support a default argument + to be returned instead of raising a ValueError on an empty sequence. + (Contributed by Julian Berman.) -- Issue #9896: Add start, stop, and step attributes to range objects. +- Issue #18137: Detect integer overflow on precision in float.__format__() + and complex.__format__(). -- Issue #13343: Fix a SystemError when a lambda expression uses a global - variable in the default value of a keyword-only argument: ``lambda *, - arg=GLOBAL_NAME: None`` +- Issue #18183: Fix various unicode operations on strings with large unicode + codepoints. -- Issue #12797: Added custom opener parameter to builtin open() and - FileIO.open(). +- Issue #18180: Fix ref leak in _PyImport_GetDynLoadWindows(). -- Issue #10519: Avoid unnecessary recursive function calls in - setobject.c. +- Issue #18038: SyntaxError raised during compilation sources with illegal + encoding now always contains an encoding name. -- Issue #10363: Deallocate global locks in Py_Finalize(). +- Issue #17931: Resolve confusion on Windows between pids and process + handles. -- Issue #13018: Fix reference leaks in error paths in dictobject.c. - Patch by Suman Saha. +- Tweak the exception message when the magic number or size value in a bytecode + file is truncated. -- Issue #13201: Define '==' and '!=' to compare range objects based on - the sequence of values they define (instead of comparing based on - object identity). +- Issue #17932: Fix an integer overflow issue on Windows 64-bit in iterators: + change the C type of seqiterobject.it_index from long to Py_ssize_t. -- Issue #1294232: In a few cases involving metaclass inheritance, the - interpreter would sometimes invoke the wrong metaclass when building a new - class object. These cases now behave correctly. Patch by Daniel Urban. +- Issue #18065: Don't set __path__ to the package name for frozen packages. -- Issue #12753: Add support for Unicode name aliases and named sequences. - Both ``unicodedata.lookup()`` and '\N{...}' now resolve aliases, - and ``unicodedata.lookup()`` resolves named sequences too. +- Issue #18088: When reloading a module, unconditionally reset all relevant + attributes on the module (e.g. __name__, __loader__, __package__, __file__, + __cached__). -- Issue #12170: The count(), find(), rfind(), index() and rindex() methods - of bytes and bytearray objects now accept an integer between 0 and 255 - as their first argument. Patch by Petri Lehtinen. +- Issue #17937: Try harder to collect cyclic garbage at shutdown. -- Issue #12604: VTRACE macro expanded to no-op in _sre.c to avoid compiler - warnings. Patch by Josh Triplett and Petri Lehtinen. +- Issue #12370: Prevent class bodies from interfering with the __class__ + closure. -- Issue #12281: Rewrite the MBCS codec to handle correctly replace and ignore - error handlers on all Windows versions. The MBCS codec is now supporting all - error handlers, instead of only replace to encode and ignore to decode. +- Issue #17644: Fix a crash in str.format when curly braces are used in square + brackets. -- Issue #13188: When called without an explicit traceback argument, - generator.throw() now gets the traceback from the passed exception's - ``__traceback__`` attribute. Patch by Petri Lehtinen. +- Issue #17237: Fix crash in the ASCII decoder on m68k. -- Issue #13146: Writing a pyc file is now atomic under POSIX. +- Issue #17927: Frame objects kept arguments alive if they had been + copied into a cell, even if the cell was cleared. -- Issue #7833: Extension modules built using distutils on Windows will no - longer include a "manifest" to prevent them failing at import time in some - embedded situations. +- Issue #1545463: At shutdown, defer finalization of codec modules so + that stderr remains usable. -- PEP 3151 / issue #12555: reworking the OS and IO exception hierarchy. +- Issue #7330: Implement width and precision (ex: "%5.3s") for the format + string of PyUnicode_FromFormat() function, original patch written by Ysj Ray. -- Add internal API for static strings (_Py_identifier et al.). +- Issue #1545463: Global variables caught in reference cycles are now + garbage-collected at shutdown. -- Issue #13063: the Windows error ERROR_NO_DATA (numbered 232 and described - as "The pipe is being closed") is now mapped to POSIX errno EPIPE - (previously EINVAL). +- Issue #17094: Clear stale thread states after fork(). Note that this + is a potentially disruptive change since it may release some system + resources which would otherwise remain perpetually alive (e.g. database + connections kept in thread-local storage). -- Issue #12911: Fix memory consumption when calculating the repr() of huge - tuples or lists. +- Issue #17408: Avoid using an obsolete instance of the copyreg module when + the interpreter is shutdown and then started again. -- PEP 393: flexible string representation. Thanks to Torsten Becker for the - initial implementation, and Victor Stinner for various bug fixes. +- Issue #5845: Enable tab-completion in the interactive interpreter by + default, thanks to a new sys.__interactivehook__. -- Issue #14081: The 'sep' and 'maxsplit' parameter to str.split, bytes.split, - and bytearray.split may now be passed as keyword arguments. +- Issue #17115,17116: Module initialization now includes setting __package__ and + __loader__ attributes to None. -- Issue #13012: The 'keepends' parameter to str.splitlines may now be passed - as a keyword argument: "my_string.splitlines(keepends=True)". The same - change also applies to bytes.splitlines and bytearray.splitlines. +- Issue #17853: Ensure locals of a class that shadow free variables always win + over the closures. -- Issue #7732: Don't open a directory as a file anymore while importing a - module. Ignore the direcotry if its name matchs the module name (e.g. - "__init__.py") and raise a ImportError instead. +- Issue #17863: In the interactive console, don't loop forever if the encoding + can't be fetched from stdin. -- Issue #13021: Missing decref on an error path. Thanks to Suman Saha for - finding the bug and providing a patch. +- Issue #17867: Raise an ImportError if __import__ is not found in __builtins__. -- Issue #12973: Fix overflow checks that relied on undefined behaviour in - list_repeat (listobject.c) and islice_next (itertoolsmodule.c). These bugs - caused test failures with recent versions of Clang. +- Issue #18698: Ensure importlib.reload() returns the module out of sys.modules. -- Issue #12904: os.utime, os.futimes, os.lutimes, and os.futimesat now write - atime and mtime with nanosecond precision on modern POSIX platforms. +- Issue #17857: Prevent build failures with pre-3.5.0 versions of sqlite3, + such as was shipped with Centos 5 and Mac OS X 10.4. -- Issue #12802: the Windows error ERROR_DIRECTORY (numbered 267) is now - mapped to POSIX errno ENOTDIR (previously EINVAL). +- Issue #17413: sys.settrace callbacks were being passed a string instead of an + exception instance for the 'value' element of the arg tuple if the exception + originated from C code; now an exception instance is always provided. -- Issue #9200: The str.is* methods now work with strings that contain non-BMP - characters even in narrow Unicode builds. +- Issue #17782: Fix undefined behaviour on platforms where + ``struct timespec``'s "tv_nsec" member is not a C long. -- Issue #12791: Break reference cycles early when a generator exits with - an exception. +- Issue #17722: When looking up __round__, resolve descriptors. -- Issue #12773: Make __doc__ mutable on user-defined classes. +- Issue #16061: Speed up str.replace() for replacing 1-character strings. -- Issue #12766: Raise a ValueError when creating a class with a class variable - that conflicts with a name in __slots__. +- Issue #17715: Fix segmentation fault from raising an exception in a __trunc__ + method. -- Issue #12266: Fix str.capitalize() to correctly uppercase/lowercase - titlecased and cased non-letter characters. +- Issue #17643: Add __callback__ attribute to weakref.ref. -- Issue #12732: In narrow unicode builds, allow Unicode identifiers which fall - outside the BMP. +- Issue #16447: Fixed potential segmentation fault when setting __name__ on a + class. -- Issue #12575: Validate user-generated AST before it is compiled. +- Issue #17669: Fix crash involving finalization of generators using yield from. -- Make type(None), type(Ellipsis), and type(NotImplemented) callable. They - return the respective singleton instances. +- Issue #14439: Python now prints the traceback on runpy failure at startup. -- Forbid summing bytes with sum(). +- Issue #17469: Fix _Py_GetAllocatedBlocks() and sys.getallocatedblocks() + when running on valgrind. -- Verify the types of AST strings and identifiers provided by the user before - compiling them. +- Issue #17619: Make input() check for Ctrl-C correctly on Windows. -- Issue #12647: The None object now has a __bool__() method that returns False. - Formerly, bool(None) returned False only because of special case logic - in PyObject_IsTrue(). +- Issue #17357: Add missing verbosity messages for -v/-vv that were lost during + the importlib transition. -- Issue #12579: str.format_map() now raises a ValueError if used on a - format string that contains positional fields. Initial patch by - Julian Berman. +- Issue #17610: Don't rely on non-standard behavior of the C qsort() function. -- Issue #10271: Allow warnings.showwarning() be any callable. +- Issue #17323: The "[X refs, Y blocks]" printed by debug builds has been + disabled by default. It can be re-enabled with the `-X showrefcount` option. -- Issue #11627: Fix segfault when __new__ on a exception returns a - non-exception class. +- Issue #17328: Fix possible refleak in dict.setdefault. -- Issue #12149: Update the method cache after a type's dictionary gets - cleared by the garbage collector. This fixes a segfault when an instance - and its type get caught in a reference cycle, and the instance's - deallocator calls one of the methods on the type (e.g. when subclassing - IOBase). Diagnosis and patch by Davide Rizzo. +- Issue #17275: Corrected class name in init error messages of the C version of + BufferedWriter and BufferedRandom. -- Issue #9611, #9015: FileIO.read() clamps the length to INT_MAX on Windows. +- Issue #7963: Fixed misleading error message that issued when object is + called without arguments. -- Issue #9642: Uniformize the tests on the availability of the mbcs codec, add - a new HAVE_MBCS define. +- Issue #8745: Small speed up zipimport on Windows. Patch by Catalin Iacob. -- Issue #9642: Fix filesystem encoding initialization: use the ANSI code page - on Windows if the mbcs codec is not available, and fail with a fatal error if - we cannot get the locale encoding (if nl_langinfo(CODESET) is not available) - instead of using UTF-8. +- Issue #5308: Raise ValueError when marshalling too large object (a sequence + with size >= 2**31), instead of producing illegal marshal data. -- When a generator yields, do not retain the caller's exception state on the - generator. +- Issue #12983: Bytes literals with invalid \x escape now raise a SyntaxError + and a full traceback including line number. -- Issue #12475: Prevent generators from leaking their exception state into the - caller's frame as they return for the last time. +- Issue #16967: In function definition, evaluate positional defaults before + keyword-only defaults. -- Issue #12291: You can now load multiple marshalled objects from a stream, - with other data interleaved between marshalled objects. +- Issue #17173: Remove uses of locale-dependent C functions (isalpha() etc.) + in the interpreter. -- Issue #12356: When required positional or keyword-only arguments are not - given, produce a informative error message which includes the name(s) of the - missing arguments. +- Issue #17137: When an Unicode string is resized, the internal wide character + string (wstr) format is now cleared. -- Issue #12370: Fix super with no arguments when __class__ is overriden in the - class body. +- Issue #17043: The unicode-internal decoder no longer read past the end of + input buffer. -- Issue #12084: os.stat on Windows now works properly with relative symbolic - links when called from any directory. +- Issue #17098: All modules now have __loader__ set even if they pre-exist the + bootstrapping of importlib. -- Loosen type restrictions on the __dir__ method. __dir__ can now return any - sequence, which will be converted to a list and sorted by dir(). +- Issue #16979: Fix error handling bugs in the unicode-escape-decode decoder. -- Issue #12265: Make error messages produced by passing an invalid set of - arguments to a function more informative. +- Issue #16772: The base argument to the int constructor no longer accepts + floats, or other non-integer objects with an __int__ method. Objects + with an __index__ method are now accepted. -- Issue #12225: Still allow Python to build if Python is not in its hg repo or - mercurial is not installed. +- Issue #10156: In the interpreter's initialization phase, unicode globals + are now initialized dynamically as needed. -- Issue #1195: my_fgets() now always clears errors before calling fgets(). Fix - the following case: sys.stdin.read() stopped with CTRL+d (end of file), - raw_input() interrupted by CTRL+c. +- Issue #16980: Fix processing of escaped non-ascii bytes in the + unicode-escape-decode decoder. -- Issue #12216: Allow unexpected EOF errors to happen on any line of the file. +- Issue #16975: Fix error handling bug in the escape-decode bytes decoder. -- Issue #12199: The TryExcept and TryFinally and AST nodes have been unified - into a Try node. +- Issue #14850: Now a charmap decoder treats U+FFFE as "undefined mapping" + in any mapping, not only in a string. -- Issue #9670: Increase the default stack size for secondary threads on - Mac OS X and FreeBSD to reduce the chances of a crash instead of a - "maximum recursion depth" RuntimeError exception. - (patch by Ronald Oussoren) +- Issue #16613: Add *m* argument to ``collections.Chainmap.new_child`` to + allow the new child map to be specified explicitly. -- Issue #12106: The use of the multiple-with shorthand syntax is now reflected - in the AST. +- Issue #16730: importlib.machinery.FileFinder now no longers raises an + exception when trying to populate its cache and it finds out the directory is + unreadable or has turned into a file. Reported and diagnosed by + David Pritchard. -- Issue #12190: Try to use the same filename object when compiling unmarshalling - a code objects in the same file. +- Issue #16906: Fix a logic error that prevented most static strings from being + cleared. -- Issue #12166: Move implementations of dir() specialized for various types into - the __dir__() methods of those types. +- Issue #11461: Fix the incremental UTF-16 decoder. Original patch by + Amaury Forgeot d'Arc. -- Issue #5715: In socketserver, close the server socket in the child process. +- Issue #16856: Fix a segmentation fault from calling repr() on a dict with + a key whose repr raise an exception. -- Correct lookup of __dir__ on objects. Among other things, this causes errors - besides AttributeError found on lookup to be propagated. +- Issue #16367: Fix FileIO.readall() on Windows for files larger than 2 GB. -- Issue #12060: Use sig_atomic_t type and volatile keyword in the signal - module. Patch written by Charles-François Natali. +- Issue #16761: Calling int() with base argument only now raises TypeError. -- Issue #1746656: Added the if_nameindex, if_indextoname, if_nametoindex - methods to the socket module. +- Issue #16759: Support the full DWORD (unsigned long) range in Reg2Py + when retrieving a REG_DWORD value. This corrects functions like + winreg.QueryValueEx that may have been returning truncated values. -- Issue #12044: Fixed subprocess.Popen when used as a context manager to - wait for the process to end when exiting the context to avoid unintentionally - leaving zombie processes around. +- Issue #14420: Support the full DWORD (unsigned long) range in Py2Reg + when passed a REG_DWORD value. Fixes OverflowError in winreg.SetValueEx. -- Issue #1195: Fix input() if it is interrupted by CTRL+d and then CTRL+c, - clear the end-of-file indicator after CTRL+d. +- Issue #11939: Set the st_dev attribute of stat_result to allow Windows to + take advantage of the os.path.samefile/sameopenfile/samestat implementations + used by other platforms. -- Issue #1856: Avoid crashes and lockups when daemon threads run while the - interpreter is shutting down; instead, these threads are now killed when - they try to take the GIL. +- Issue #16772: The int() constructor's second argument (base) no longer + accepts non integer values. Consistent with the behavior in Python 2. -- Issue #9756: When calling a method descriptor or a slot wrapper descriptor, - the check of the object type doesn't read the __class__ attribute anymore. - Fix a crash if a class override its __class__ attribute (e.g. a proxy of the - str type). Patch written by Andreas Stührk. +- Issue #14470: Remove w9xpopen support per PEP 11. -- Issue #10517: After fork(), reinitialize the TLS used by the PyGILState_* - APIs, to avoid a crash with the pthread implementation in RHEL 5. Patch - by Charles-François Natali. +- Issue #9856: Replace deprecation warning with raising TypeError + in object.__format__. Patch by Florent Xicluna. -- Issue #10914: Initialize correctly the filesystem codec when creating a new - subinterpreter to fix a bootstrap issue with codecs implemented in Python, as - the ISO-8859-15 codec. +- Issue #16597: In buffered and text IO, call close() on the underlying stream + if invoking flush() fails. -- Issue #11918: OS/2 and VMS are no more supported because of the lack of - maintainer. +- Issue #16722: In the bytes() constructor, try to call __bytes__ on the + argument before __index__. -- Issue #6780: fix starts/endswith error message to mention that tuples are - accepted too. +- Issue #16421: loading multiple modules from one shared object is now + handled correctly (previously, the first module loaded from that file + was silently returned). Patch by Václav Šmilauer. -- Issue #5057: fix a bug in the peepholer that led to non-portable pyc files - between narrow and wide builds while optimizing BINARY_SUBSCR on non-BMP - chars (e.g. "\U00012345"[0]). +- Issue #16602: When a weakref's target was part of a long deallocation + chain, the object could remain reachable through its weakref even though + its refcount had dropped to zero. -- Issue #11845: Fix typo in rangeobject.c that caused a crash in - compute_slice_indices. Patch by Daniel Urban. +- Issue #16495: Remove extraneous NULL encoding check from bytes_decode(). -- Issue #5673: Added a `timeout` keyword argument to subprocess.Popen.wait, - subprocess.Popen.communicated, subprocess.call, subprocess.check_call, and - subprocess.check_output. If the blocking operation takes more than `timeout` - seconds, the `subprocess.TimeoutExpired` exception is raised. +- Issue #16619: Create NameConstant AST class to represent None, True, and False + literals. As a result, these constants are never loaded at runtime from + builtins. -- Issue #11650: PyOS_StdioReadline() retries fgets() if it was interrupted - (EINTR), for example if the program is stopped with CTRL+z on Mac OS X. Patch - written by Charles-Francois Natali. +- Issue #16455: On FreeBSD and Solaris, if the locale is C, the + ASCII/surrogateescape codec is now used (instead of the locale encoding) to + decode the command line arguments. This change fixes inconsistencies with + os.fsencode() and os.fsdecode(), because these operating systems announce an + ASCII locale encoding, but actually use the ISO-8859-1 encoding in practice. -- Issue #9319: Include the filename in "Non-UTF8 code ..." syntax error. +- Issue #16562: Optimize dict equality testing. Patch by Serhiy Storchaka. -- Issue #10785: Store the filename as Unicode in the Python parser. +- Issue #16588: Silence unused-but-set warnings in Python/thread_pthread -- Issue #11619: _PyImport_LoadDynamicModule() doesn't encode the path to bytes - on Windows. +- Issue #16592: stringlib_bytes_join doesn't raise MemoryError on allocation + failure. -- Issue #10998: Remove mentions of -Q, sys.flags.division_warning and - Py_DivisionWarningFlag left over from Python 2. +- Issue #16546: Fix: ast.YieldFrom argument is now mandatory. -- Issue #11244: Remove an unnecessary peepholer check that was preventing - negative zeros from being constant-folded properly. +- Issue #16514: Fix regression causing a traceback when sys.path[0] is None + (actually, any non-string or non-bytes type). -- Issue #11395: io.FileIO().write() clamps the data length to 32,767 bytes on - Windows if the file is a TTY to workaround a Windows bug. The Windows console - returns an error (12: not enough space error) on writing into stdout if - stdout mode is binary and the length is greater than 66,000 bytes (or less, - depending on heap usage). +- Issue #16306: Fix multiple error messages when unknown command line + parameters where passed to the interpreter. Patch by Hieu Nguyen. -- Issue #11320: fix bogus memory management in Modules/getpath.c, leading to - a possible crash when calling Py_SetPath(). +- Issue #16215: Fix potential double memory free in str.replace(). Patch + by Serhiy Storchaka. -- Issue #11432: A bug was introduced in subprocess.Popen on posix systems with - 3.2.0 where the stdout or stderr file descriptor being the same as the stdin - file descriptor would raise an exception. webbrowser.open would fail. fixed. +- Issue #16290: A float return value from the __complex__ special method is no + longer accepted in the complex() constructor. -- Issue #9856: Change object.__format__ with a non-empty format string - to be a DeprecationWarning. In 3.2 it was a PendingDeprecationWarning. - In 3.4 it will be a TypeError. +- Issue #16416: On Mac OS X, operating system data are now always + encoded/decoded to/from UTF-8/surrogateescape, instead of the locale encoding + (which may be ASCII if no locale environment variable is set), to avoid + inconsistencies with os.fsencode() and os.fsdecode() functions which are + already using UTF-8/surrogateescape. -- Issue #11244: The peephole optimizer is now able to constant-fold - arbitrarily complex expressions. This also fixes a 3.2 regression where - operations involving negative numbers were not constant-folded. +- Issue #16453: Fix equality testing of dead weakref objects. -- Issue #11450: Don't truncate hg version info in Py_GetBuildInfo() when - there are many tags (e.g. when using mq). Patch by Nadeem Vawda. +- Issue #9535: Fix pending signals that have been received but not yet + handled by Python to not persist after os.fork() in the child process. -- Issue #11335: Fixed a memory leak in list.sort when the key function - throws an exception. +- Issue #14794: Fix slice.indices to return correct results for huge values, + rather than raising OverflowError. -- Issue #8923: When a string is encoded to UTF-8 in strict mode, the result is - cached into the object. Examples: str.encode(), str.encode('utf-8'), - PyUnicode_AsUTF8String() and PyUnicode_AsEncodedString(unicode, "utf-8", - NULL). +- Issue #15001: fix segfault on "del sys.modules['__main__']". Patch by Victor + Stinner. -- Issue #10829: Refactor PyUnicode_FromFormat(), use the same function to parse - the format string in the 3 steps, fix crashs on invalid format strings. +- Issue #8271: the utf-8 decoder now outputs the correct number of U+FFFD + characters when used with the 'replace' error handler on invalid utf-8 + sequences. Patch by Serhiy Storchaka, tests by Ezio Melotti. -- Issue #13007: whichdb should recognize gdbm 1.9 magic numbers. +- Issue #5765: Apply a hard recursion limit in the compiler instead of + blowing the stack and segfaulting. Initial patch by Andrea Griffini. -- Issue #11286: Raise a ValueError from calling PyMemoryView_FromBuffer with - a buffer struct having a NULL data pointer. +- Issue #16402: When slicing a range, fix shadowing of exceptions from + __index__. -- Issue #11272: On Windows, input() strips '\r' (and not only '\n'), and - sys.stdin uses universal newline (replace '\r\n' by '\n'). +- Issue #16336: fix input checking in the surrogatepass error handler. + Patch by Serhiy Storchaka. -- Issue #11828: startswith and endswith now accept None as slice index. - Patch by Torsten Becker. +- Issue #8401: assigning an int to a bytearray slice (e.g. b[3:4] = 5) now + raises an error. -- Issue #11168: Remove filename debug variable from PyEval_EvalFrameEx(). - It encoded the Unicode filename to UTF-8, but the encoding fails on - undecodable filename (on surrogate characters) which raises an unexpected - UnicodeEncodeError on recursion limit. +- Issue #7317: Display full tracebacks when an error occurs asynchronously. + Patch by Alon Horev with update by Alexey Kachayev. -- Issue #11187: Remove bootstrap code (use ASCII) of - PyUnicode_AsEncodedString(), it was replaced by a better fallback (use the - locale encoding) in PyUnicode_EncodeFSDefault(). +- Issue #16309: Make PYTHONPATH="" behavior the same as if PYTHONPATH + not set at all. -- Check for NULL result in PyType_FromSpec. +- Issue #10189: Improve the error reporting of SyntaxErrors related to global + and nonlocal statements. -- Issue #10516: New copy() and clear() methods for lists and bytearrays. +- Fix segfaults on setting __qualname__ on builtin types and attempting to + delete it on any type. -- Issue #11386: bytearray.pop() now throws IndexError when the bytearray is - empty, instead of OverflowError. +- Issue #14625: Rewrite the UTF-32 decoder. It is now 3x to 4x faster. Patch + written by Serhiy Storchaka. -- Issue #12380: The rjust, ljust and center methods of bytes and bytearray - now accept a bytearray argument. +- Issue #16345: Fix an infinite loop when ``fromkeys`` on a dict subclass + received a nonempty dict from the constructor. -Library -------- +- Issue #16271: Fix strange bugs that resulted from __qualname__ appearing in a + class's __dict__ and on type. -- Issue #14195: An issue that caused weakref.WeakSet instances to incorrectly - return True for a WeakSet instance 'a' in both 'a < a' and 'a > a' has been - fixed. +- Issue #12805: Make bytes.join and bytearray.join faster when the separator + is empty. Patch by Serhiy Storchaka. -- Issue #14166: Pickler objects now have an optional ``dispatch_table`` - attribute which allows to set custom per-pickler reduction functions. - Patch by sbt. +- Issue #6074: Ensure cached bytecode files can always be updated by the + user that created them, even when the source file is read-only. -- Issue #14177: marshal.loads() now raises TypeError when given an unicode - string. Patch by Guilherme Gonçalves. +- Issue #15958: bytes.join and bytearray.join now accept arbitrary buffer + objects. -- Issue #13550: Remove the debug machinery from the threading module: remove - verbose arguments from all threading classes and functions. +- Issue #14783: Improve int() docstring and switch docstrings for str(), + range(), and slice() to use multi-line signatures. -- Issue #14159: Fix the len() of weak containers (WeakSet, WeakKeyDictionary, - WeakValueDictionary) to return a better approximation when some objects - are dead or dying. Moreover, the implementation is now O(1) rather than - O(n). +- Issue #16160: Subclass support now works for types.SimpleNamespace. -- Issue #11841: Fix comparison bug with 'rc' versions in packaging.version. - Patch by Filip Gruszczyński. +- Issue #16148: Implement PEP 424, adding operator.length_hint and + PyObject_LengthHint. -- Issue #6884: Fix long-standing bugs with MANIFEST.in parsing in distutils - on Windows. Also fixed in packaging. +- Upgrade Unicode data (UCD) to version 6.2. -- Issue #8033: sqlite3: Fix 64-bit integer handling in user functions - on 32-bit architectures. Initial patch by Philippe Devalkeneer. +- Issue #15379: Fix passing of non-BMP characters as integers for the charmap + decoder (already working as unicode strings). Patch by Serhiy Storchaka. -- HTMLParser is now able to handle slashes in the start tag. +- Issue #15144: Fix possible integer overflow when handling pointers as integer + values, by using `Py_uintptr_t` instead of `size_t`. Patch by Serhiy + Storchaka. -- Issue #13641: Decoding functions in the base64 module now accept ASCII-only - unicode strings. Patch by Catalin Iacob. +- Issue #15965: Explicitly cast `AT_FDCWD` as (int). Required on Solaris 10 + (which defines `AT_FDCWD` as ``0xffd19553``), harmless on other platforms. -- Issue #14043: Speed up importlib's _FileFinder by at least 8x, and add a - new importlib.invalidate_caches() function. +- Issue #15839: Convert SystemErrors in `super()` to RuntimeErrors. -- Issue #14001: CVE-2012-0845: xmlrpc: Fix an endless loop in - SimpleXMLRPCServer upon malformed POST request. +- Issue #15448: Buffered IO now frees the buffer when closed, instead + of when deallocating. -- Issue #13961: Move importlib over to using os.replace() for atomic renaming. +- Issue #15846: Fix SystemError which happened when using `ast.parse()` in an + exception handler on code with syntax errors. -- Do away with ambiguous level values (as suggested by PEP 328) in - importlib.__import__() by raising ValueError when level < 0. +- Issue #15897: zipimport.c doesn't check return value of fseek(). + Patch by Felipe Cruz. -- Issue #2489: pty.spawn could consume 100% cpu when it encountered an EOF. +- Issue #15801: Make sure mappings passed to '%' formatting are actually + subscriptable. -- Issue #13014: Fix a possible reference leak in SSLSocket.getpeercert(). +- Issue #15111: __import__ should propagate ImportError when raised as a + side-effect of a module triggered from using fromlist. -- Issue #13777: Add PF_SYSTEM sockets on OS X. - Patch by Michael Goderbauer. +- Issue #15022: Add pickle and comparison support to types.SimpleNamespace. -- Issue #13015: Fix a possible reference leak in defaultdict.__repr__. - Patch by Suman Saha. +Library +------- -- Issue #1326113: distutils' and packaging's build_ext commands option now - correctly parses multiple values (separated by whitespace or commas) given - to their --libraries option. +- Issue #4331: Added functools.partialmethod (Initial patch by Alon Horev) -- Issue #10287: nntplib now queries the server's CAPABILITIES first before - sending MODE READER, and only sends it if not already in READER mode. - Patch by Hynek Schlawack. +- Issue #13461: Fix a crash in the TextIOWrapper.tell method on 64-bit + platforms. Patch by Yogesh Chaudhari. -- Issue #13993: HTMLParser is now able to handle broken end tags when - strict=False. +- Issue #18681: Fix a NameError in importlib.reload() (noticed by Weizhao Li). -- Issue #13930: lib2to3 now supports writing converted output files to another - directory tree as well as copying unchanged files and altering the file - suffix. +- Issue #14323: Expanded the number of digits in the coefficients for the + RGB -- YIQ conversions so that they match the FCC NTSC versions. -- Issue #9750: Fix sqlite3.Connection.iterdump on tables and fields - with a name that is a keyword or contains quotes. Patch by Marko - Kohtala. +- Issue #17998: Fix an internal error in regular expression engine. -- Issue #10287: nntplib now queries the server's CAPABILITIES again after - authenticating (since the result may change, according to RFC 4643). - Patch by Hynek Schlawack. +- Issue #17557: Fix os.getgroups() to work with the modified behavior of + getgroups(2) on OS X 10.8. Original patch by Mateusz Lenik. -- Issue #13590: On OS X 10.7 and 10.6 with Xcode 4.2, building - Distutils-based packages with C extension modules may fail because - Apple has removed gcc-4.2, the version used to build python.org - 64-bit/32-bit Pythons. If the user does not explicitly override - the default C compiler by setting the CC environment variable, - Distutils will now attempt to compile extension modules with clang - if gcc-4.2 is required but not found. Also as a convenience, if - the user does explicitly set CC, substitute its value as the default - compiler in the Distutils LDSHARED configuration variable for OS X. - (Note, the python.org 32-bit-only Pythons use gcc-4.0 and the 10.4u - SDK, neither of which are available in Xcode 4. This change does not - attempt to override settings to support their use with Xcode 4.) +- Issue #18608: Avoid keeping a strong reference to the locale module + inside the _io module. -- Issue #13960: HTMLParser is now able to handle broken comments when - strict=False. +- Issue #18619: Fix atexit leaking callbacks registered from sub-interpreters, + and make it GC-aware. -- When '' is a path (e.g. in sys.path), make sure __file__ uses the current - working directory instead of '' in importlib. +- Issue #15699: The readline module now uses PEP 3121-style module + initialization, so as to reclaim allocated resources (Python callbacks) + at shutdown. Original patch by Robin Schreiber. -- Issue #13609: Add two functions to query the terminal size: - os.get_terminal_size (low level) and shutil.get_terminal_size (high level). - Patch by Zbigniew Jędrzejewski-Szmek. +- Issue #17616: wave.open now supports the context management protocol. -- Issue #13845: On Windows, time.time() now uses GetSystemTimeAsFileTime() - instead of ftime() to have a resolution of 100 ns instead of 1 ms (the clock - accuracy is between 0.5 ms and 15 ms). +- Issue #18599: Fix name attribute of _sha1.sha1() object. It now returns + 'SHA1' instead of 'SHA'. -- Issue #13846: Add time.monotonic(), monotonic clock. +- Issue #13266: Added inspect.unwrap to easily unravel __wrapped__ chains + (initial patch by Daniel Urban and Aaron Iles) -- Issue #8184: multiprocessing: On Windows, don't set SO_REUSEADDR on - Connection sockets, and set FILE_FLAG_FIRST_PIPE_INSTANCE on named pipes, to - make sure two listeners can't bind to the same socket/pipe (or any existing - socket/pipe). +- Issue #18561: Skip name in ctypes' _build_callargs() if name is NULL. -- Issue #10811: Fix recursive usage of cursors. Instead of crashing, - raise a ProgrammingError now. +- Issue #18559: Fix NULL pointer dereference error in _pickle module -- Issue #13734: Add os.fwalk(), a directory walking function yielding file - descriptors. +- Issue #18556: Check the return type of PyUnicode_AsWideChar() in ctype's + U_set(). -- Issue #2945: Make the distutils upload command aware of bdist_rpm products. +- Issue #17818: aifc.getparams now returns a namedtuple. -- Issue #13712: pysetup create should not convert package_data to extra_files. +- Issue #18549: Eliminate dead code in socket_ntohl() -- Issue #11805: package_data in setup.cfg should allow more than one value. +- Issue #18530: Remove additional stat call from posixpath.ismount. + Patch by Alex Gaynor. -- Issue #13676: Handle strings with embedded zeros correctly in sqlite3. +- Issue #18514: Fix unreachable Py_DECREF() call in PyCData_FromBaseObj() -- Issue #8828: Add new function os.replace(), for cross-platform renaming - with overwriting. +- Issue #9177: Calling read() or write() now raises ValueError, not + AttributeError, on a closed SSL socket. Patch by Senko Rasic. -- Issue #13848: open() and the FileIO constructor now check for NUL - characters in the file name. Patch by Hynek Schlawack. +- Issue #18513: Fix behaviour of cmath.rect w.r.t. signed zeros on OS X 10.8 + + gcc. -- Issue #13806: The size check in audioop decompression functions was too - strict and could reject valid compressed data. Patch by Oleg Plakhotnyuk. +- Issue #18479: Changed venv Activate.ps1 to make deactivate a function, and + removed Deactivate.ps1. -- Issue #13812: When a multiprocessing Process child raises an exception, - flush stderr after printing the exception traceback. +- Issue #18480: Add missing call to PyType_Ready to the _elementtree extension. -- Issue #13885: CVE-2011-3389: the _ssl module would always disable the CBC - IV attack countermeasure. +- Issue #17778: Fix test discovery for test_multiprocessing. (Patch by + Zachary Ware.) -- Issue #13847: time.localtime() and time.gmtime() now raise an OSError instead - of ValueError on failure. time.ctime() and time.asctime() now raises an - OSError if localtime() failed. time.clock() now raises a RuntimeError if the - processor time used is not available or its value cannot be represented +- Issue #18393: The private module _gestalt and private functions + platform._mac_ver_gestalt, platform._mac_ver_lookup and + platform._bcd2str have been removed. This does not affect the public + interface of the platform module. -- Issue #13772: In os.symlink() under Windows, do not try to guess the link - target's type (file or directory). The detection was buggy and made the - call non-atomic (therefore prone to race conditions). +- Issue #17482: functools.update_wrapper (and functools.wraps) now set the + __wrapped__ attribute correctly even if the underlying function has a + __wrapped__ attribute set. -- Issue #6631: Disallow relative file paths in urllib urlopen methods. +- Issue #18431: The new email header parser now decodes RFC2047 encoded words + in structured headers. -- Issue #13722: Avoid silencing ImportErrors when initializing the codecs - registry. +- Issue #18432: The sched module's queue method was incorrectly returning + an iterator instead of a list. -- Issue #13781: Fix GzipFile bug that caused an exception to be raised when - opening for writing using a fileobj returned by os.fdopen(). +- Issue #18044: The new email header parser was mis-parsing encoded words where + an encoded character immediately followed the '?' that follows the CTE + character, resulting in a decoding failure. They are now decoded correctly. -- Issue #13803: Under Solaris, distutils doesn't include bitness - in the directory name. +- Issue #18101: Tcl.split() now process strings nested in a tuple as it + do with byte strings. -- Issue #10278: Add time.wallclock() function, monotonic clock. +- Issue #18116: getpass was always getting an error when testing /dev/tty, + and thus was always falling back to stdin, and would then raise an exception + if stdin could not be used (such as /dev/null). It also leaked an open file. + All of these issues are now fixed. -- Issue #13809: Fix regression where bz2 module wouldn't work when threads are - disabled. Original patch by Amaury Forgeot d'Arc. +- Issue #17198: Fix a NameError in the dbm module. Patch by Valentina + Mukhamedzhanova. -- Issue #13589: Fix some serialization primitives in the aifc module. - Patch by Oleg Plakhotnyuk. +- Issue #18013: Fix cgi.FieldStorage to parse the W3C sample form. -- Issue #13642: Unquote before b64encoding user:password during Basic - Authentication. Patch contributed by Joonas Kuorilehto. +- Issue #18020: improve html.escape speed by an order of magnitude. + Patch by Matt Bryant. -- Issue #12364: Fix a hang in concurrent.futures.ProcessPoolExecutor. - The hang would occur when retrieving the result of a scheduled future after - the executor had been shut down. +- Issue #18347: ElementTree's html serializer now preserves the case of + closing tags. -- Issue #13502: threading: Fix a race condition in Event.wait() that made it - return False when the event was set and cleared right after. +- Issue #17261: Ensure multiprocessing's proxies use proper address. -- Issue #9993: When the source and destination are on different filesystems, - and the source is a symlink, shutil.move() now recreates a symlink on the - destination instead of copying the file contents. Patch by Jonathan Niehof - and Hynek Schlawack. +- Issue #18343: faulthandler.register() now keeps the previous signal handler + when the function is called twice, so faulthandler.unregister() restores + correctly the original signal handler. -- Issue #12926: Fix a bug in tarfile's link extraction. +- Issue #17097: Make multiprocessing ignore EINTR. -- Issue #13696: Fix the 302 Relative URL Redirection problem. +- Issue #18339: Negative ints keys in unpickler.memo dict no longer cause a + segfault inside the _pickle C extension. -- Issue #13636: Weak ciphers are now disabled by default in the ssl module - (except when SSLv2 is explicitly asked for). +- Issue #18240: The HMAC module is no longer restricted to bytes and accepts + any bytes-like object, e.g. memoryview. Original patch by Jonas Borgström. -- Issue #12715: Add an optional symlinks argument to shutil functions - (copyfile, copymode, copystat, copy, copy2). When that parameter is - true, symlinks aren't dereferenced and the operation instead acts on the - symlink itself (or creates one, if relevant). Patch by Hynek Schlawack. +- Issue #18224: Removed pydoc script from created venv, as it causes problems + on Windows and adds no value over and above python -m pydoc ... -- Add a flags parameter to select.epoll. +- Issue #18155: The csv module now correctly handles csv files that use + a delimter character that has a special meaning in regexes, instead of + throwing an exception. -- Issue #13626: Add support for SSL Diffie-Hellman key exchange, through the - SSLContext.load_dh_params() method and the ssl.OP_SINGLE_DH_USE option. +- Issue #14360: encode_quopri can now be successfully used as an encoder + when constructing a MIMEApplication object. -- Issue #11006: Don't issue low level warning in subprocess when pipe2() fails. +- Issue #11390: Add -o and -f command line options to the doctest CLI to + specify doctest options (and convert it to using argparse). -- Issue #13620: Support for Chrome browser in webbrowser. Patch contributed - by Arnaud Calmettes. +- Issue #18135: ssl.SSLSocket.write() now raises an OverflowError if the input + string in longer than 2 gigabytes, and ssl.SSLContext.load_cert_chain() + raises a ValueError if the password is longer than 2 gigabytes. The ssl + module does not support partial write. -- Issue #11829: Fix code execution holes in inspect.getattr_static for - metaclasses with metaclasses. Patch by Andreas Stührk. +- Issue #11016: Add C implementation of the stat module as _stat. -- Issue #12708: Add starmap() and starmap_async() methods (similar to - itertools.starmap()) to multiprocessing.Pool. Patch by Hynek Schlawack. +- Issue #18248: Fix libffi build on AIX. -- Issue #1785: Fix inspect and pydoc with misbehaving descriptors. +- Issue #18259: Declare sethostname in socketmodule.c for AIX -- Issue #13637: "a2b" functions in the binascii module now accept ASCII-only - unicode strings. +- Issue #18147: Add diagnostic functions to ssl.SSLContext(). get_ca_list() + lists all loaded CA certificates and cert_store_stats() returns amount of + loaded X.509 certs, X.509 CA certs and CRLs. -- Issue #13634: Add support for querying and disabling SSL compression. +- Issue #18167: cgi.FieldStorage no longer fails to handle multipart/form-data + when \r\n appears at end of 65535 bytes without other newlines. -- Issue #13627: Add support for SSL Elliptic Curve-based Diffie-Hellman - key exchange, through the SSLContext.set_ecdh_curve() method and the - ssl.OP_SINGLE_ECDH_USE option. +- Issue #18076: Introduce importlib.util.decode_source(). +- Issue #18357: add tests for dictview set difference. + Patch by Fraser Tweedale. -- Issue #13635: Add ssl.OP_CIPHER_SERVER_PREFERENCE, so that SSL servers - choose the cipher based on their own preferences, rather than on the - client's. +- importlib.abc.SourceLoader.get_source() no longer changes SyntaxError or + UnicodeDecodeError into ImportError. -- Issue #11813: Fix inspect.getattr_static for modules. Patch by Andreas - Stührk. +- Issue #18058, 18057: Make the namespace package loader meet the + importlib.abc.InspectLoader ABC, allowing for namespace packages to work with + runpy. -- Issue #7502: Fix equality comparison for DocTestCase instances. Patch by - Cédric Krier. +- Issue #17177: The imp module is pending deprecation. -- Issue #11870: threading: Properly reinitialize threads internal locks and - condition variables to avoid deadlocks in child processes. +- subprocess: Prevent a possible double close of parent pipe fds when the + subprocess exec runs into an error. Prevent a regular multi-close of the + /dev/null fd when any of stdin, stdout and stderr was set to DEVNULL. -- Issue #8035: urllib: Fix a bug where the client could remain stuck after a - redirection or an error. +- Issue #18194: Introduce importlib.util.cache_from_source() and + source_from_cache() while documenting the equivalent functions in imp as + deprecated. -- Issue #13560: os.strerror() now uses the current locale encoding instead of - UTF-8. +- Issue #17907: Document imp.new_module() as deprecated in favour of + types.ModuleType. -- Issue #8373: The filesystem path of AF_UNIX sockets now uses the filesystem - encoding and the surrogateescape error handler, rather than UTF-8. Patch - by David Watson. +- Issue #18192: Introduce importlib.util.MAGIC_NUMBER and document as deprecated + imp.get_magic(). -- Issue #10350: Read and save errno before calling a function which might - overwrite it. Original patch by Hallvard B Furuseth. +- Issue #18149: Add filecmp.clear_cache() to manually clear the filecmp cache. + Patch by Mark Levitt -- Issue #11610: Introduce a more general way to declare abstract properties. +- Issue #18193: Add importlib.reload(). -- Issue #13591: A bug in importlib has been fixed that caused import_module - to load a module twice. +- Issue #18157: Stop using imp.load_module() in pydoc. -- Issue #13449 sched.scheduler.run() method has a new "blocking" parameter which - when set to False makes run() execute the scheduled events due to expire - soonest (if any) and then return. Patch by Giampaolo Rodolà. +- Issue #16102: Make uuid._netbios_getnode() work again on Python 3. -- Issue #8684 sched.scheduler class can be safely used in multi-threaded - environments. Patch by Josiah Carlson and Giampaolo Rodolà. +- Issue #17134: Add ssl.enum_cert_store() as interface to Windows' cert store. -- Alias resource.error to OSError ala PEP 3151. +- Issue #18143: Implement ssl.get_default_verify_paths() in order to debug + the default locations for cafile and capath. -- Issue #5689: Add support for lzma compression to the tarfile module. +- Issue #17314: Move multiprocessing.forking over to importlib. -- Issue #13248: Turn 3.2's PendingDeprecationWarning into 3.3's - DeprecationWarning. It covers 'cgi.escape', 'importlib.abc.PyLoader', - 'importlib.abc.PyPycLoader', 'nntplib.NNTP.xgtitle', 'nntplib.NNTP.xpath', - and private attributes of 'smtpd.SMTPChannel'. +- Issue #11959: SMTPServer and SMTPChannel now take an optional map, use of + which avoids affecting global state. -- Issue #5905, #13560: time.strftime() is now using the current locale - encoding, instead of UTF-8, if the wcsftime() function is not available. +- Issue #18109: os.uname() now decodes fields from the locale encoding, and + socket.gethostname() now decodes the hostname from the locale encoding, + instead of using the UTF-8 encoding in strict mode. -- Issue #13464: Add a readinto() method to http.client.HTTPResponse. Patch - by Jon Kuhn. +- Issue #18089: Implement importlib.abc.InspectLoader.load_module. -- tarfile.py: Correctly detect bzip2 compressed streams with blocksizes - other than 900k. +- Issue #18088: Introduce importlib.abc.Loader.init_module_attrs for setting + module attributes. Leads to the pending deprecation of + importlib.util.module_for_loader. -- Issue #13439: Fix many errors in turtle docstrings. +- Issue #17403: urllib.parse.robotparser normalizes the urls before adding to + ruleline. This helps in handling certain types invalid urls in a conservative + manner. Patch contributed by Mher Movsisyan. -- Issue #6715: Add a module 'lzma' for compression using the LZMA algorithm. - Thanks to Per Øyvind Karlsen for the initial implementation. +- Issue #18070: Have importlib.util.module_for_loader() set attributes + unconditionally in order to properly support reloading. -- Issue #13487: Make inspect.getmodule robust against changes done to - sys.modules while it is iterating over it. +- Added importlib.util.module_to_load to return a context manager to provide the + proper module object to load. -- Issue #12618: Fix a bug that prevented py_compile from creating byte - compiled files in the current directory. Initial patch by Sjoerd de Vries. +- Issue #18025: Fixed a segfault in io.BufferedIOBase.readinto() when raw + stream's read() returns more bytes than requested. -- Issue #13444: When stdout has been closed explicitly, we should not attempt - to flush it at shutdown and print an error. +- Issue #18011: As was originally intended, base64.b32decode() now raises a + binascii.Error if there are non-b32-alphabet characters present in the input + string, instead of a TypeError. -- Issue #12567: The curses module uses Unicode functions for Unicode arguments - when it is linked to the ncurses library. It encodes also Unicode strings to - the locale encoding instead of UTF-8. +- Issue #18072: Implement importlib.abc.InspectLoader.get_code() and + importlib.abc.ExecutionLoader.get_code(). -- Issue #12856: Ensure child processes do not inherit the parent's random - seed for filename generation in the tempfile module. Patch by Brian - Harring. +- Issue #8240: Set the SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER flag on SSL + sockets. -- Issue #9957: SpooledTemporaryFile.truncate() now accepts an optional size - parameter, as other file-like objects. Patch by Ryan Kelly. +- Issue #17269: Workaround for socket.getaddrinfo crash on MacOS X + with port None or "0" and flags AI_NUMERICSERV. -- Issue #13458: Fix a memory leak in the ssl module when decoding a - certificate with a subjectAltName. Patch by Robert Xiao. +- Issue #16986: ElementTree now correctly works with string input when the + internal XML encoding is not UTF-8 or US-ASCII. -- Issue #13415: os.unsetenv() doesn't ignore errors anymore. +- Issue #17996: socket module now exposes AF_LINK constant on BSD and OSX. -- Issue #13245: sched.scheduler class constructor's timefunc and - delayfunct parameters are now optional. - scheduler.enter and scheduler.enterabs methods gained a new kwargs parameter. - Patch contributed by Chris Clark. +- Issue #17900: Allowed pickling of recursive OrderedDicts. Decreased pickled + size and pickling time. -- Issue #12328: Under Windows, refactor handling of Ctrl-C events and - make _multiprocessing.win32.WaitForMultipleObjects interruptible when - the wait_flag parameter is false. Patch by sbt. +- Issue #17914: Add os.cpu_count(). Patch by Yogesh Chaudhari, based on an + initial patch by Trent Nelson. -- Issue #13322: Fix BufferedWriter.write() to ensure that BlockingIOError is - raised when the wrapped raw file is non-blocking and the write would block. - Previous code assumed that the raw write() would raise BlockingIOError, but - RawIOBase.write() is defined to returned None when the call would block. - Patch by sbt. +- Issue #17812: Fixed quadratic complexity of base64.b32encode(). + Optimize base64.b32encode() and base64.b32decode() (speed up to 3x). -- Issue #13358: HTMLParser now calls handle_data only once for each CDATA. +- Issue #17980: Fix possible abuse of ssl.match_hostname() for denial of + service using certificates with many wildcards (CVE-2013-2099). -- Issue #4147: minidom's toprettyxml no longer adds whitespace around a text - node when it is the only child of an element. Initial patch by Dan - Kenigsberg. +- Issue #15758: Fix FileIO.readall() so it no longer has O(n**2) complexity. -- Issue #13374: The Windows bytes API has been deprecated in the os module. Use - Unicode filenames instead of bytes filenames to not depend on the ANSI code - page anymore and to support any filename. +- Issue #14596: The struct.Struct() objects now use a more compact + implementation. -- Issue #13297: Use bytes type to send and receive binary data through XMLRPC. +- Issue #17981: logging's SysLogHandler now closes the socket when it catches + socket OSErrors. -- Issue #6397: Support "/dev/poll" polling objects in select module, - under Solaris & derivatives. +- Issue #17964: Fix os.sysconf(): the return type of the C sysconf() function + is long, not int. -- Issues #1745761, #755670, #13357, #12629, #1200313: HTMLParser now correctly - handles non-valid attributes, including adjacent and unquoted attributes. +- Fix typos in the multiprocessing module. -- Issue #13193: Fix distutils.filelist.FileList and packaging.manifest.Manifest - under Windows. +- Issue #17754: Make ctypes.util.find_library() independent of the locale. -- Issue #13384: Remove unnecessary __future__ import in Lib/random.py +- Issue #17968: Fix memory leak in os.listxattr(). -- Issue #13149: Speed up append-only StringIO objects. +- Issue #17606: Fixed support of encoded byte strings in the XMLGenerator + characters() and ignorableWhitespace() methods. Original patch by Sebastian + Ortiz Vasquez. -- Issue #13373: multiprocessing.Queue.get() could sometimes block indefinitely - when called with a timeout. Patch by Arnaud Ysmal. +- Issue #17732: Ignore distutils.cfg options pertaining to install paths if a + virtual environment is active. -- Issue #13254: Fix Maildir initialization so that maildir contents - are read correctly. +- Issue #17915: Fix interoperability of xml.sax with file objects returned by + codecs.open(). -- Issue #3067: locale.setlocale() now raises TypeError if the second - argument is an invalid iterable. Its documentation and docstring - were also updated. Initial patch by Jyrki Pulliainen. +- Issue #16601: Restarting iteration over tarfile really restarts rather + than continuing from where it left off. Patch by Michael Birtwell. -- Issue #13140: Fix the daemon_threads attribute of ThreadingMixIn. +- Issue #17289: The readline module now plays nicer with external modules + or applications changing the rl_completer_word_break_characters global + variable. Initial patch by Bradley Froehle. -- Issue #13339: Fix compile error in posixmodule.c due to missing semicolon. - Thanks to Robert Xiao. +- Issue #12181: select module: Fix struct kevent definition on OpenBSD 64-bit + platforms. Patch by Federico Schwindt. -- Byte compilation in packaging is now isolated from the calling Python -B or - -O options, instead of being disallowed under -B or buggy under -O. +- Issue #11816: multiple improvements to the dis module: get_instructions + generator, ability to redirect output to a file, Bytecode and Instruction + abstractions. Patch by Nick Coghlan, Ryan Kelly and Thomas Kluyver. -- Issue #10570: curses.putp() and curses.tparm() are now expecting a byte - string, instead of a Unicode string. +- Issue #13831: Embed stringification of remote traceback in local + traceback raised when pool task raises an exception. -- Issue #13295: http.server now produces valid HTML 4.01 strict. +- Issue #15528: Add weakref.finalize to support finalization using + weakref callbacks. -- Issue #2892: preserve iterparse events in case of SyntaxError. +- Issue #14173: Avoid crashing when reading a signal handler during + interpreter shutdown. -- Issue #13287: urllib.request and urllib.error now contains an __all__ - attribute to expose only relevant classes and functions. Patch by Florent - Xicluna. +- Issue #15902: Fix imp.load_module() accepting None as a file when loading an + extension module. -- Issue #670664: Fix HTMLParser to correctly handle the content of - ```` and ````. +- Issue #13721: SSLSocket.getpeercert() and SSLSocket.do_handshake() now + raise an OSError with ENOTCONN, instead of an AttributeError, when the + SSLSocket is not connected. -- Issue #10817: Fix urlretrieve function to raise ContentTooShortError even - when reporthook is None. Patch by Jyrki Pulliainen. +- Issue #14679: add an __all__ (that contains only HTMLParser) to html.parser. -- Fix the xmlrpc.client user agent to return something similar to - urllib.request user agent: "Python-xmlrpc/3.3". +- Issue #17802: Fix an UnboundLocalError in html.parser. Initial tests by + Thomas Barlow. -- Issue #13293: Better error message when trying to marshal bytes using - xmlrpc.client. +- Issue #17358: Modules loaded by imp.load_source() and load_compiled() (and by + extention load_module()) now have a better chance of working when reloaded. -- Issue #13291: NameError in xmlrpc package. +- Issue #17804: New function ``struct.iter_unpack`` allows for streaming + struct unpacking. -- Issue #13258: Use callable() built-in in the standard library. +- Issue #17830: When keyword.py is used to update a keyword file, it now + preserves the line endings of the original file. -- Issue #13273: fix a bug that prevented HTMLParser to properly detect some - tags when strict=False. +- Issue #17272: Making the urllib.request's Request.full_url a descriptor. + Fixes bugs with assignment to full_url. Patch by Demian Brecht. -- Issue #11183: Add finer-grained exceptions to the ssl module, so that - you don't have to inspect the exception's attributes in the common case. +- Issue #17353: Plistlib emitted empty data tags with deeply nested datastructures -- Issue #13216: Add cp65001 codec, the Windows UTF-8 (CP_UTF8). +- Issue #11714: Use 'with' statements to assure a Semaphore releases a + condition variable. Original patch by Thomas Rachel. -- Issue #13226: Add RTLD_xxx constants to the os module. These constants can be - used with sys.setdlopenflags(). +- Issue #16624: `subprocess.check_output` now accepts an `input` argument, + allowing the subprocess's stdin to be provided as a (byte) string. + Patch by Zack Weinberg. -- Issue #10278: Add clock_getres(), clock_gettime() and CLOCK_xxx constants to - the time module. time.clock_gettime(time.CLOCK_MONOTONIC) provides a - monotonic clock +- Issue #17795: Reverted backwards-incompatible change in SysLogHandler with + Unix domain sockets. -- Issue #10332: multiprocessing: fix a race condition when a Pool is closed - before all tasks have completed. +- Issue #16694: Add a pure Python implementation of the operator module. + Patch by Zachary Ware. -- Issue #13255: wrong docstrings in array module. +- Issue #11182: remove the unused and undocumented pydoc.Scanner class. + Patch by Martin Morrison. -- Issue #8540: Remove deprecated Context._clamp attribute in Decimal module. +- Issue #17741: Add ElementTree.XMLPullParser, an event-driven parser for + non-blocking applications. -- Issue #13235: Added DeprecationWarning to logging.warn() method and function. +- Issue #17555: Fix ForkAwareThreadLock so that size of after fork + registry does not grow exponentially with generation of process. -- Issue #9168: now smtpd is able to bind privileged port. +- Issue #17707: fix regression in multiprocessing.Queue's get() method where + it did not block for short timeouts. -- Issue #12529: fix cgi.parse_header issue on strings with double-quotes and - semicolons together. Patch by Ben Darnell and Petri Lehtinen. +- Issue #17720: Fix the Python implementation of pickle.Unpickler to correctly + process the APPENDS opcode when it is used on non-list objects. -- Issue #13227: functools.lru_cache() now has a option to distinguish - calls with different argument types. +- Issue #17012: shutil.which() no longer falls back to the PATH environment + variable if an empty path argument is specified. Patch by Serhiy Storchaka. -- Issue #6090: zipfile raises a ValueError when a document with a timestamp - earlier than 1980 is provided. Patch contributed by Petri Lehtinen. +- Issue #17710: Fix pickle raising a SystemError on bogus input. -- Issue #13150: sysconfig no longer parses the Makefile and config.h files - when imported, instead doing it at build time. This makes importing - sysconfig faster and reduces Python startup time by 20%. +- Issue #17341: Include the invalid name in the error messages from re about + invalid group names. -- Issue #12448: smtplib now flushes stdout while running ``python -m smtplib`` - in order to display the prompt correctly. +- Issue #17702: os.environ now raises KeyError with the original environment + variable name (str on UNIX), instead of using the encoded name (bytes on + UNIX). -- Issue #12454: The mailbox module is now using ASCII, instead of the locale - encoding, to read and write .mh_sequences files. +- Issue #16163: Make the importlib based version of pkgutil.iter_importers + work for submodules. Initial patch by Berker Peksag. -- Issue #13194: zlib.compressobj().copy() and zlib.decompressobj().copy() are - now available on Windows. +- Issue #16804: Fix a bug in the 'site' module that caused running + 'python -S -m site' to incorrectly throw an exception. -- Issue #1673007: urllib.request now supports HEAD request via new method argument. - Patch contributions by David Stanek, Patrick Westerhoff and Ezio Melotti. +- Issue #15480: Remove the deprecated and unused TYPE_INT64 code from marshal. + Initial patch by Daniel Riti. -- Issue #12386: packaging does not fail anymore when writing the RESOURCES - file. +- Issue #2118: SMTPException is now a subclass of OSError. -- Issue #13158: Fix decoding and encoding of GNU tar specific base-256 number - fields in tarfile. +- Issue #17016: Get rid of possible pointer wraparounds and integer overflows + in the re module. Patch by Nickolai Zeldovich. -- Issue #13025: mimetypes is now reading MIME types using the UTF-8 encoding, - instead of the locale encoding. +- Issue #16658: add missing return to HTTPConnection.send() + Patch by Jeff Knupp. -- Issue #10653: On Windows, use strftime() instead of wcsftime() because - wcsftime() doesn't format time zone correctly. +- Issue #9556: the logging package now allows specifying a time-of-day for a + TimedRotatingFileHandler to rotate. -- Issue #13150: The tokenize module doesn't compile large regular expressions - at startup anymore. +- Issue #14971: unittest test discovery no longer gets confused when a function + has a different __name__ than its name in the TestCase class dictionary. -- Issue #11171: Fix distutils.sysconfig.get_makefile_filename when Python was - configured with different prefix and exec-prefix. +- Issue #17487: The wave getparams method now returns a namedtuple rather than + a plain tuple. -- Issue #11254: Teach distutils and packaging to compile .pyc and .pyo files in - PEP 3147-compliant __pycache__ directories. +- Issue #17675: socket repr() provides local and remote addresses (if any). + Patch by Giampaolo Rodola' -- Issue #7367: Fix pkgutil.walk_paths to skip directories whose - contents cannot be read. +- Issue #17093: Make the ABCs in importlib.abc provide default values or raise + reasonable exceptions for their methods to make them more amenable to super() + calls. -- Issue #3163: The struct module gets new format characters 'n' and 'N' - supporting C integer types ``ssize_t`` and ``size_t``, respectively. +- Issue #17566: Make importlib.abc.Loader.module_repr() optional instead of an + abstractmethod; now it raises NotImplementedError so as to be ignored by default. -- Issue #13099: Fix sqlite3.Cursor.lastrowid under a Turkish locale. - Reported and diagnosed by Thomas Kluyver. +- Issue #17678: Remove the use of deprecated method in http/cookiejar.py by + changing the call to get_origin_req_host() to origin_req_host. -- Issue #13087: BufferedReader.seek() now always raises UnsupportedOperation - if the underlying raw stream is unseekable, even if the seek could be - satisfied using the internal buffer. Patch by John O'Connor. +- Issue #17666: Fix reading gzip files with an extra field. -- Issue #7689: Allow pickling of dynamically created classes when their - metaclass is registered with copyreg. Patch by Nicolas M. Thiéry and Craig - Citro. +- Issue #16475: Support object instancing, recursion and interned strings + in marshal -- Issue #13034: When decoding some SSL certificates, the subjectAltName - extension could be unreported. +- Issue #17502: Process DEFAULT values in mock side_effect that returns iterator. -- Issue #12306: Expose the runtime version of the zlib C library as a constant, - ZLIB_RUNTIME_VERSION, in the zlib module. Patch by Torsten Landschoff. +- Issue #16795: On the ast.arguments object, unify vararg with varargannotation + and kwarg and kwargannotation. Change the column offset of ast.Attribute to be + at the attribute name. -- Issue #12959: Add collections.ChainMap to collections.__all__. +- Issue #17434: Properly raise a SyntaxError when a string occurs between future + imports. -- Issue #8933: distutils' PKG-INFO files and packaging's METADATA files will - now correctly report Metadata-Version: 1.1 instead of 1.0 if a Classifier or - Download-URL field is present. +- Issue #17117: Import and @importlib.util.set_loader now set __loader__ when + it has a value of None or the attribute doesn't exist. -- Issue #12567: Add curses.unget_wch() function. Push a character so the next - get_wch() will return it. +- Issue #17032: The "global" in the "NameError: global name 'x' is not defined" + error message has been removed. Patch by Ram Rachum. -- Issue #9561: distutils and packaging now writes egg-info files using UTF-8, - instead of the locale encoding. +- Issue #18080: When building a C extension module on OS X, if the compiler + is overriden with the CC environment variable, use the new compiler as + the default for linking if LDSHARED is not also overriden. This restores + Distutils behavior introduced in 3.2.3 and inadvertently dropped in 3.3.0. -- Issue #8286: The distutils command sdist will print a warning message instead - of crashing when an invalid path is given in the manifest template. +- Issue #18113: Fixed a refcount leak in the curses.panel module's + set_userptr() method. Reported by Atsuo Ishimoto. -- Issue #12841: tarfile unnecessarily checked the existence of numerical user - and group ids on extraction. If one of them did not exist the respective id - of the current user (i.e. root) was used for the file and ownership - information was lost. +- Implement PEP 443 "Single-dispatch generic functions". -- Issue #12888: Fix a bug in HTMLParser.unescape that prevented it to escape - more than 128 entities. Patch by Peter Otten. +- Implement PEP 435 "Adding an Enum type to the Python standard library". -- Issue #12878: Expose a __dict__ attribute on io.IOBase and its subclasses. +- Issue #15596: Faster pickling of unicode strings. -- Issue #12494: On error, call(), check_call(), check_output() and - getstatusoutput() functions of the subprocess module now kill the process, - read its status (to avoid zombis) and close pipes. +- Issue #17572: Avoid chained exceptions when passing bad directives to + time.strptime(). Initial patch by Claudiu Popa. -- Issue #12720: Expose low-level Linux extended file attribute functions in os. +- Issue #17435: threading.Timer's __init__ method no longer uses mutable + default values for the args and kwargs parameters. -- Issue #10946: The distutils commands bdist_dumb, bdist_wininst and bdist_msi - now respect a --skip-build option given to bdist. The packaging commands - were fixed too. +- Issue #17526: fix an IndexError raised while passing code without filename to + inspect.findsource(). Initial patch by Tyler Doyle. -- Issue #12847: Fix a crash with negative PUT and LONG_BINPUT arguments in - the C pickle implementation. +- Issue #17540: Added style parameter to logging formatter configuration by dict. -- Issue #11564: Avoid crashes when trying to pickle huge objects or containers - (more than 2**31 items). Instead, in most cases, an OverflowError is raised. +- Issue #16692: The ssl module now supports TLS 1.1 and TLS 1.2. Initial + patch by Michele Orrù. -- Issue #12287: Fix a stack corruption in ossaudiodev module when the FD is - greater than FD_SETSIZE. +- Issue #17025: multiprocessing: Reduce Queue and SimpleQueue contention. -- Issue #12839: Fix crash in zlib module due to version mismatch. - Fix by Richard M. Tew. +- Issue #17536: Add to webbrowser's browser list: www-browser, x-www-browser, + iceweasel, iceape. -- Issue #9923: The mailcap module now correctly uses the platform path - separator for the MAILCAP environment variable on non-POSIX platforms. +- Issue #17150: pprint now uses line continuations to wrap long string + literals. -- Issue #12835: Follow up to #6560 that unconditionally prevents use of the - unencrypted sendmsg/recvmsg APIs on SSL wrapped sockets. Patch by David - Watson. +- Issue #17488: Change the subprocess.Popen bufsize parameter default value + from unbuffered (0) to buffering (-1) to match the behavior existing code + expects and match the behavior of the subprocess module in Python 2 to avoid + introducing hard to track down bugs. -- Issue #12803: SSLContext.load_cert_chain() now accepts a password argument - to be used if the private key is encrypted. Patch by Adam Simpkins. +- Issue #17521: Corrected non-enabling of logger following two calls to + fileConfig(). -- Issue #11657: Fix sending file descriptors over 255 over a multiprocessing - Pipe. +- Issue #17508: Corrected logging MemoryHandler configuration in dictConfig() + where the target handler wasn't configured first. -- Issue #12811: tabnanny.check() now promptly closes checked files. Patch by - Anthony Briggs. +- Issue #17209: curses.window.get_wch() now correctly handles KeyboardInterrupt + (CTRL+c). -- Issue #6560: The sendmsg/recvmsg API is now exposed by the socket module - when provided by the underlying platform, supporting processing of - ancillary data in pure Python code. Patch by David Watson and Heiko Wundram. +- Issue #5713: smtplib now handles 421 (closing connection) error codes when + sending mail by closing the socket and reporting the 421 error code via the + exception appropriate to the command that received the error response. -- Issue #12326: On Linux, sys.platform doesn't contain the major version - anymore. It is now always 'linux', instead of 'linux2' or 'linux3' depending - on the Linux version used to build Python. +- Issue #16997: unittest.TestCase now provides a subTest() context manager + to procedurally generate, in an easy way, small test instances. -- Issue #12213: Fix a buffering bug with interleaved reads and writes that - could appear on BufferedRandom streams. +- Issue #17485: Also delete the Request Content-Length header if the data + attribute is deleted. (Follow on to issue Issue #16464). -- Issue #12778: Reduce memory consumption when JSON-encoding a large - container of many small objects. +- Issue #15927: CVS now correctly parses escaped newlines and carriage + when parsing with quoting turned off. -- Issue #12650: Fix a race condition where a subprocess.Popen could leak - resources (FD/zombie) when killed at the wrong time. +- Issue #17467: add readline and readlines support to mock_open in + unittest.mock. -- Issue #12744: Fix inefficient representation of integers between 2**31 and - 2**63 on systems with a 64-bit C "long". +- Issue #13248: removed deprecated and undocumented difflib.isbjunk, + isbpopular. -- Issue #12646: Add an 'eof' attribute to zlib.Decompress, to make it easier to - detect truncated input streams. +- Issue #17192: Update the ctypes module's libffi to v3.0.13. This + specifically addresses a stack misalignment issue on x86 and issues on + some more recent platforms. -- Issue #11513: Fix exception handling ``tarfile.TarFile.gzopen()`` when - the file cannot be opened. +- Issue #8862: Fixed curses cleanup when getkey is interrputed by a signal. -- Issue #12687: Fix a possible buffering bug when unpickling text mode - (protocol 0, mostly) pickles. +- Issue #17443: imaplib.IMAP4_stream was using the default unbuffered IO + in subprocess, but the imap code assumes buffered IO. In Python2 this + worked by accident. IMAP4_stream now explicitly uses buffered IO. -- Issue #10087: Fix the html output format of the calendar module. +- Issue #17476: Fixed regression relative to Python2 in undocumented pydoc + 'allmethods'; it was missing unbound methods on the class. -- Issue #13121: add support for inplace math operators to collections.Counter. +- Issue #17474: Remove the deprecated methods of Request class. -- Add support for unary plus and unary minus to collections.Counter. +- Issue #16709: unittest discover order is no-longer filesystem specific. Patch + by Jeff Ramnani. -- Issue #12683: urlparse updated to include svn as schemes that uses relative - paths. (svn from 1.5 onwards support relative path). +- Use the HTTPS PyPI url for upload, overriding any plain HTTP URL in pypirc. -- Issue #12655: Expose functions from sched.h in the os module: sched_yield(), - sched_setscheduler(), sched_getscheduler(), sched_setparam(), - sched_get_min_priority(), sched_get_max_priority(), sched_rr_get_interval(), - sched_getaffinity(), sched_setaffinity(). +- Issue #5024: sndhdr.whichhdr now returns the frame count for WAV files + rather than -1. -- Add ThreadError to threading.__all__. +- Issue #17460: Remove the strict argument of HTTPConnection and removing the + DeprecationWarning being issued from 3.2 onwards. -- Issues #11104, #8688: Fix the behavior of distutils' sdist command with - manually-maintained MANIFEST files. +- Issue #16880: Do not assume _imp.load_dynamic() is defined in the imp module. -- Issue #11281: smtplib.STMP gets source_address parameter, which adds the - ability to bind to specific source address on a machine with multiple - interfaces. Patch by Paulo Scardine. +- Issue #16389: Fixed a performance regression relative to Python 3.1 in the + caching of compiled regular expressions. -- Issue #12464: tempfile.TemporaryDirectory.cleanup() should not follow - symlinks: fix it. Patch by Petri Lehtinen. +- Added missing FeedParser and BytesFeedParser to email.parser.__all__. -- Issue #8887: "pydoc somebuiltin.somemethod" (or help('somebuiltin.somemethod') - in Python code) now finds the doc of the method. +- Issue #17431: Fix missing import of BytesFeedParser in email.parser. -- Issue #10968: Remove indirection in threading. The public names (Event, - Condition, etc.) used to be factory functions returning instances of hidden - classes (_Event, _Condition, etc.), because (if Guido recalls correctly) this - code pre-dates the ability to subclass extension types. It is now possible - to inherit from these classes, without having to import the private - underscored names like multiprocessing did. +- Issue #12921: http.server's send_error takes an explain argument to send more + information in response. Patch contributed by Karl. -- Issue #9723: Add shlex.quote functions, to escape filenames and command - lines. +- Issue #17414: Add timeit, repeat, and default_timer to timeit.__all__. -- Issue #12603: Fix pydoc.synopsis() on files with non-negative st_mtime. +- Issue #1285086: Get rid of the refcounting hack and speed up + urllib.parse.unquote() and urllib.parse.unquote_to_bytes(). -- Issue #12514: Use try/finally to assure the timeit module restores garbage - collections when it is done. +- Issue #17099: Have importlib.find_loader() raise ValueError when __loader__ + is not set, harmonizing with what happens when the attribute is set to None. -- Issue #12607: In subprocess, fix issue where if stdin, stdout or stderr is - given as a low fd, it gets overwritten. +- Expose the O_PATH constant in the os module if it is available. -- Issue #12576: Fix urlopen behavior on sites which do not send (or obfuscates) - ``Connection: close`` header. +- Issue #17368: Fix an off-by-one error in the Python JSON decoder that caused + a failure while decoding empty object literals when object_pairs_hook was + specified. -- Issue #12560: Build libpython.so on OpenBSD. Patch by Stefan Sperling. +- Issue #17385: Fix quadratic behavior in threading.Condition. The FIFO + queue now uses a deque instead of a list. -- Issue #1813: Fix codec lookup under Turkish locales. +- Issue #15806: Add contextlib.ignore(). This creates a context manager to + ignore specified exceptions, replacing the "except SomeException: pass" idiom. -- Issue #12591: Improve support of "universal newlines" in the subprocess - module: the piped streams can now be properly read from or written to. +- Issue #14645: The email generator classes now produce output using the + specified linesep throughout. Previously if the prolog, epilog, or + body were stored with a different linesep, that linesep was used. This + fix corrects an RFC non-compliance issue with smtplib.send_message. -- Issue #12591: Allow io.TextIOWrapper to work with raw IO objects (without - a read1() method), and add a *write_through* parameter to mandate - unbuffered writes. +- Issue #17278: Fix a crash in heapq.heappush() and heapq.heappop() when + the list is being resized concurrently. -- Issue #10883: Fix socket leaks in urllib.request when using FTP. +- Issue #16962: Use getdents64 instead of the obsolete getdents syscall + in the subprocess module on Linux. -- Issue #12592: Make Python build on OpenBSD 5 (and future major releases). +- Issue #16935: unittest now counts the module as skipped if it raises SkipTest, + instead of counting it as an error. Patch by Zachary Ware. -- Issue #12372: POSIX semaphores are broken on AIX: don't use them. +- Issue #17018: Make Process.join() retry if os.waitpid() fails with EINTR. -- Issue #12551: Provide a get_channel_binding() method on SSL sockets so as - to get channel binding data for the current SSL session (only the - "tls-unique" channel binding is implemented). This allows the implementation - of certain authentication mechanisms such as SCRAM-SHA-1-PLUS. Patch by - Jacek Konieczny. +- Issue #17223: array module: Fix a crasher when converting an array containing + invalid characters (outside range [U+0000; U+10ffff]) to Unicode: + repr(array), str(array) and array.tounicode(). Patch written by Manuel Jacob. -- Issue #665194: email.utils now has format_datetime and parsedate_to_datetime - functions, allowing for round tripping of RFC2822 format dates. +- Issue #17197: profile/cProfile modules refactored so that code of run() and + runctx() utility functions is not duplicated in both modules. -- Issue #12571: Add a plat-linux3 directory mirroring the plat-linux2 - directory, so that "import DLFCN" and other similar imports work on - Linux 3.0. +- Issue #14720: sqlite3: Convert datetime microseconds correctly. + Patch by Lowe Thiderman. -- Issue #7484: smtplib no longer puts <> around addresses in VRFY and EXPN - commands; they aren't required and in fact postfix doesn't support that form. +- Issue #15132: Allow a list for the defaultTest argument of + unittest.TestProgram. Patch by Jyrki Pulliainen. -- Issue #12273: Remove ast.__version__. AST changes can be accounted for by - checking sys.version_info or sys._mercurial. +- Issue #17225: JSON decoder now counts columns in the first line starting + with 1, as in other lines. -- Silence spurious "broken pipe" tracebacks when shutting down a - ProcessPoolExecutor. +- Issue #6623: Added explicit DeprecationWarning for ftplib.netrc, which has + been deprecated and undocumented for a long time. -- Fix potential resource leaks in concurrent.futures.ProcessPoolExecutor - by joining all queues and processes when shutdown() is called. +- Issue #13700: Fix byte/string handling in imaplib authentication when an + authobject is specified. -- Issue #11603: Fix a crash when __str__ is rebound as __repr__. Patch by - Andreas Stührk. +- Issue #13153: Tkinter functions now raise TclError instead of ValueError when + a string argument contains non-BMP character. -- Issue #11321: Fix a crash with multiple imports of the _pickle module when - embedding Python. Patch by Andreas Stührk. +- Issue #9669: Protect re against infinite loops on zero-width matching in + non-greedy repeat. Patch by Matthew Barnett. -- Issue #6755: Add get_wch() method to curses.window class. Patch by Iñigo - Serna. +- Issue #13169: The maximal repetition number in a regular expression has been + increased from 65534 to 2147483647 (on 32-bit platform) or 4294967294 (on + 64-bit). -- Add cgi.closelog() function to close the log file. +- Issue #17143: Fix a missing import in the trace module. Initial patch by + Berker Peksag. -- Issue #12502: asyncore: fix polling loop with AF_UNIX sockets. +- Issue #15220: email.feedparser's line splitting algorithm is now simpler and + faster. -- Issue #4376: ctypes now supports nested structures in a endian different than - the parent structure. Patch by Vlad Riscutia. +- Issue #16743: Fix mmap overflow check on 32 bit Windows. -- Raise ValueError when attempting to set the _CHUNK_SIZE attribute of a - TextIOWrapper to a huge value, not TypeError. +- Issue #16996: webbrowser module now uses shutil.which() to find a + web-browser on the executable search path. -- Issue #12504: Close file handles in a timely manner in packaging.database. - This fixes a bug with the remove (uninstall) feature on Windows. +- Issue #16800: tempfile.gettempdir() no longer left temporary files when + the disk is full. Original patch by Amir Szekely. -- Issues #12169 and #10510: Factor out code used by various packaging commands - to make HTTP POST requests, and make sure it uses CRLF. +- Issue #17192: Import libffi-3.0.12. -- Issue #12016: Multibyte CJK decoders now resynchronize faster. They only - ignore the first byte of an invalid byte sequence. For example, - b'\xff\n'.decode('gb2312', 'replace') gives '\ufffd\n' instead of '\ufffd'. +- Issue #16564: Fixed regression relative to Python2 in the operation of + email.encoders.encode_7or8bit when used with binary data. -- Issue #12459: time.sleep() now raises a ValueError if the sleep length is - negative, instead of an infinite sleep on Windows or raising an IOError on - Linux for example, to have the same behaviour on all platforms. +- Issue #17052: unittest discovery should use self.testLoader. -- Issue #12451: pydoc: html_getfile() now uses tokenize.open() to support - Python scripts using a encoding different than UTF-8 (read the coding cookie - of the script). +- Issue #4591: Uid and gid values larger than 2**31 are supported now. -- Issue #12493: subprocess: Popen.communicate() now also handles EINTR errors - if the process has only one pipe. +- Issue #17141: random.vonmisesvariate() no longer hangs for large kappas. -- Issue #12467: warnings: fix a race condition if a warning is emitted at - shutdown, if globals()['__file__'] is None. +- Issue #17149: Fix random.vonmisesvariate to always return results in + [0, 2*math.pi]. -- Issue #12451: pydoc: importfile() now opens the Python script in binary mode, - instead of text mode using the locale encoding, to avoid encoding issues. +- Issue #1470548: XMLGenerator now works with binary output streams. -- Issue #12451: runpy: run_path() now opens the Python script in binary mode, - instead of text mode using the locale encoding, to support other encodings - than UTF-8 (scripts using the coding cookie). +- Issue #6975: os.path.realpath() now correctly resolves multiple nested + symlinks on POSIX platforms. -- Issue #12451: xml.dom.pulldom: parse() now opens files in binary mode instead - of the text mode (using the locale encoding) to avoid encoding issues. +- Issue #13773: sqlite3.connect() gets a new `uri` parameter to pass the + filename as a URI, allowing to pass custom options. -- Issue #12147: Adjust the new-in-3.2 smtplib.send_message method for better - conformance to the RFCs: correctly handle Sender and Resent- headers. +- Issue #16564: Fixed regression relative to Python2 in the operation of + email.encoders.encode_noop when used with binary data. -- Issue #12352: Fix a deadlock in multiprocessing.Heap when a block is freed by - the garbage collector while the Heap lock is held. +- Issue #10355: The mode, name, encoding and newlines properties now work on + SpooledTemporaryFile objects even when they have not yet rolled over. + Obsolete method xreadline (which has never worked in Python 3) has been + removed. -- Issue #12462: time.sleep() now immediately calls the (Python) signal handler - if it is interrupted by a signal, instead of having to wait until the next - instruction. +- Issue #16686: Fixed a lot of bugs in audioop module. Fixed crashes in + avgpp(), maxpp() and ratecv(). Fixed an integer overflow in add(), bias(), + and ratecv(). reverse(), lin2lin() and ratecv() no more lose precision for + 32-bit samples. max() and rms() no more returns a negative result and + various other functions now work correctly with 32-bit sample -0x80000000. -- Issue #12442: new shutil.disk_usage function, providing total, used and free - disk space statistics. +- Issue #17073: Fix some integer overflows in sqlite3 module. -- Issue #12451: The XInclude default loader of xml.etree now decodes files from - UTF-8 instead of the locale encoding if the encoding is not specified. It now - also opens XML files for the parser in binary mode instead of the text mode - to avoid encoding issues. +- Issue #16723: httplib.HTTPResponse no longer marked closed when the connection + is automatically closed. -- Issue #12451: doctest.debug_script() doesn't create a temporary file - anymore to avoid encoding issues. +- Issue #15359: Add CAN_BCM protocol support to the socket module. Patch by + Brian Thorne. -- Issue #12451: pydoc.synopsis() now reads the encoding cookie if available, - to read the Python script from the right encoding. +- Issue #16948: Fix quoted printable body encoding for non-latin1 character + sets in the email package. -- Issue #12451: distutils now opens the setup script in binary mode to read the - encoding cookie, instead of opening it in UTF-8. +- Issue #16811: Fix folding of headers with no value in the provisional email + policies. -- Issue #9516: On Mac OS X, change Distutils to no longer globally attempt to - check or set the MACOSX_DEPLOYMENT_TARGET environment variable for the - interpreter process. This could cause failures in non-Distutils subprocesses - and was unreliable since tests or user programs could modify the interpreter - environment after Distutils set it. Instead, have Distutils set the - deployment target only in the environment of each build subprocess. It is - still possible to globally override the default by setting - MACOSX_DEPLOYMENT_TARGET before launching the interpreter; its value must be - greater or equal to the default value, the value with which the interpreter - was built. Also, implement the same handling in packaging. +- Issue #17132: Update symbol for "yield from" grammar changes. -- Issue #12422: In the copy module, don't store objects that are their own copy - in the memo dict. +- Issue #17076: Make copying of xattrs more tolerant of missing FS support. + Patch by Thomas Wouters. -- Issue #12303: Add sigwaitinfo() and sigtimedwait() to the signal module. +- Issue #17089: Expat parser now correctly works with string input when the + internal XML encoding is not UTF-8 or US-ASCII. It also now accepts bytes + and strings larger than 2 GiB. -- Issue #12404: Remove C89 incompatible code from mmap module. Patch by Akira - Kitada. +- Issue #6083: Fix multiple segmentation faults occured when PyArg_ParseTuple + parses nested mutating sequence. -- Issue #1874: email now detects and reports as a defect the presence of - any CTE other than 7bit, 8bit, or binary on a multipart. +- Issue #5289: Fix ctypes.util.find_library on Solaris. -- Issue #12383: Fix subprocess module with env={}: don't copy the environment - variables, start with an empty environment. +- Issue #17106: Fix a segmentation fault in io.TextIOWrapper when an underlying + stream or a decoder produces data of an unexpected type (i.e. when + io.TextIOWrapper initialized with text stream or use bytes-to-bytes codec). -- Issue #11637: Fix support for importing packaging setup hooks from the - project directory. +- Issue #17015: When it has a spec, a Mock object now inspects its signature + when matching calls, so that arguments can be matched positionally or + by name. -- Issue #6771: Moved the curses.wrapper function from the single-function - wrapper module into __init__, eliminating the module. Since __init__ was - already importing the function to curses.wrapper, there is no API change. +- Issue #15633: httplib.HTTPResponse is now mark closed when the server + sends less than the advertised Content-Length. -- Issue #11584: email.header.decode_header no longer fails if the header - passed to it is a Header object, and Header/make_header no longer fail - if given binary unknown-8bit input. +- Issue #12268: The io module file object write methods no longer abort early + when one of its write system calls is interrupted (EINTR). -- Issue #11700: mailbox proxy object close methods can now be called multiple - times without error. +- Issue #6972: The zipfile module no longer overwrites files outside of + its destination path when extracting malicious zip files. -- Issue #11767: Correct file descriptor leak in mailbox's __getitem__ method. +- Issue #4844: ZipFile now raises BadZipFile when opens a ZIP file with an + incomplete "End of Central Directory" record. Original patch by Guilherme + Polo and Alan McIntyre. -- Issue #12133: AbstractHTTPHandler.do_open() of urllib.request closes the HTTP - connection if its getresponse() method fails with a socket error. Patch - written by Ezio Melotti. +- Issue #17071: Signature.bind() now works when one of the keyword arguments + is named ``self``. -- Issue #12240: Allow multiple setup hooks in packaging's setup.cfg files. - Original patch by Erik Bray. +- Issue #12004: Fix an internal error in PyZipFile when writing an invalid + Python file. Patch by Ben Morgan. -- Issue #9284: Allow inspect.findsource() to find the source of doctest - functions. +- Have py_compile use importlib as much as possible to avoid code duplication. + Code now raises FileExistsError if the file path to be used for the + byte-compiled file is a symlink or non-regular file as a warning that import + will not keep the file path type if it writes to that path. -- Issue #11595: Fix assorted bugs in packaging.util.cfg_to_args, a - compatibility helper for the distutils-packaging transition. Original patch - by Erik Bray. +- Issue #16972: Have site.addpackage() consider already known paths even when + none are explicitly passed in. Bug report and fix by Kirill. -- Issue #12287: In ossaudiodev, check that the device isn't closed in several - methods. +- Issue #1602133: on Mac OS X a shared library build (``--enable-shared``) + now fills the ``os.environ`` variable correctly. -- Issue #12009: Fixed regression in netrc file comment handling. +- Issue #15505: `unittest.installHandler` no longer assumes SIGINT handler is + set to a callable object. -- Issue #12246: Warn and fail when trying to install a third-party project from - an uninstalled Python (built in a source checkout). Original patch by - Tshepang Lekhonkhobe. +- Issue #13454: Fix a crash when deleting an iterator created by itertools.tee() + if all other iterators were very advanced before. -- Issue #10694: zipfile now ignores garbage at the end of a zipfile. +- Issue #12411: Fix to cgi.parse_multipart to correctly use bytes boundaries + and bytes data. Patch by Jonas Wagner. -- Issue #12283: Fixed regression in smtplib quoting of leading dots in DATA. +- Issue #16957: shutil.which() no longer searches a bare file name in the + current directory on Unix and no longer searches a relative file path with + a directory part in PATH directories. Patch by Thomas Kluyver. -- Issue #10424: Argparse now includes the names of the missing required - arguments in the missing arguments error message. +- Issue #1159051: GzipFile now raises EOFError when reading a corrupted file + with truncated header or footer. -- Issue #12168: SysLogHandler now allows NUL termination to be controlled using - a new 'append_nul' attribute on the handler. +- Issue #16993: shutil.which() now preserves the case of the path and extension + on Windows. -- Issue #11583: Speed up os.path.isdir on Windows by using GetFileAttributes - instead of os.stat. +- Issue #16992: On Windows in signal.set_wakeup_fd, validate the file + descriptor argument. -- Issue #12021: Make mmap's read() method argument optional. Patch by Petri - Lehtinen. +- Issue #16422: For compatibility with the Python version, the C version of + decimal now uses strings instead of integers for rounding mode constants. -- Issue #9205: concurrent.futures.ProcessPoolExecutor now detects killed - children and raises BrokenProcessPool in such a situation. Previously it - would reliably freeze/deadlock. +- Issue #15861: tkinter now correctly works with lists and tuples containing + strings with whitespaces, backslashes or unbalanced braces. -- Issue #12040: Expose a new attribute ``sentinel`` on instances of - ``multiprocessing.Process``. Also, fix Process.join() to not use polling - anymore, when given a timeout. +- Issue #9720: zipfile now writes correct local headers for files larger than + 4 GiB. -- Issue #11893: Remove obsolete internal wrapper class ``SSLFakeFile`` in the - smtplib module. Patch by Catalin Iacob. +- Issue #16955: Fix the poll() method for multiprocessing's socket + connections on Windows. -- Issue #12080: Fix a Decimal.power() case that took an unreasonably long time - to compute. +- SSLContext.load_dh_params() now properly closes the input file. -- Issue #12221: Remove __version__ attributes from pyexpat, pickle, tarfile, - pydoc, tkinter, and xml.parsers.expat. This were useless version constants - left over from the Mercurial transition +- Issue #15031: Refactor some .pyc management code to cut down on code + duplication. Thanks to Ronan Lamy for the report and taking an initial stab + at the problem. -- Named tuples now work correctly with vars(). +- Issue #16398: Optimize deque.rotate() so that it only moves pointers + and doesn't touch the underlying data with increfs and decrefs. -- Issue #12085: Fix an attribute error in subprocess.Popen destructor if the - constructor has failed, e.g. because of an undeclared keyword argument. Patch - written by Oleg Oshmyan. +- Issue #16900: Issue a ResourceWarning when an ssl socket is left unclosed. -- Issue #12028: Make threading._get_ident() public, rename it to - threading.get_ident() and document it. This function was already used using - _thread.get_ident(). +- Issue #13899: \A, \Z, and \B now correctly match the A, Z, and B literals + when used inside character classes (e.g. '[\A]'). Patch by Matthew Barnett. -- Issue #12171: IncrementalEncoder.reset() of CJK codecs (multibytecodec) calls - encreset() instead of decreset(). +- Issue #15545: Fix regression in sqlite3's iterdump method where it was + failing if the connection used a row factory (such as sqlite3.Row) that + produced unsortable objects. (Regression was introduced by fix for 9750). -- Issue #12218: Removed wsgiref.egg-info. +- fcntl: add F_DUPFD_CLOEXEC constant, available on Linux 2.6.24+. -- Issue #12196: Add pipe2() to the os module. +- Issue #15972: Fix error messages when os functions expecting a file name or + file descriptor receive the incorrect type. -- Issue #985064: Make plistlib more resilient to faulty input plists. - Patch by Mher Movsisyan. +- Issue #8109: The ssl module now has support for server-side SNI, thanks + to a :meth:`SSLContext.set_servername_callback` method. Patch by Daniel + Black. -- Issue #1625: BZ2File and bz2.decompress() now support multi-stream files. - Initial patch by Nir Aides. +- Issue #16860: In tempfile, use O_CLOEXEC when available to set the + close-on-exec flag atomically. -- Issue #12175: BufferedReader.read(-1) now calls raw.readall() if available. +- Issue #16674: random.getrandbits() is now 20-40% faster for small integers. -- Issue #12175: FileIO.readall() now only reads the file position and size - once. +- Issue #16009: JSON error messages now provide more information. -- Issue #12175: RawIOBase.readall() now returns None if read() returns None. +- Issue #16828: Fix error incorrectly raised by bz2.compress(b'') and + bz2.BZ2Compressor.compress(b''). Initial patch by Martin Packman. -- Issue #12175: FileIO.readall() now raises a ValueError instead of an IOError - if the file is closed. +- Issue #16833: In http.client.HTTPConnection, do not concatenate the request + headers and body when the payload exceeds 16 KB, since it can consume more + memory for no benefit. Patch by Benno Leslie. -- Issue #11109: New service_action method for BaseServer, used by ForkingMixin - class for cleanup. Initial Patch by Justin Warkentin. +- Issue #16541: tk_setPalette() now works with keyword arguments. -- Issue #12045: Avoid duplicate execution of command in - ctypes.util._get_soname(). Patch by Sijin Joseph. +- Issue #16820: In configparser, `parser.popitem()` no longer raises ValueError. + This makes `parser.clean()` work correctly. -- Issue #10818: Remove the Tk GUI and the serve() function of the pydoc module, - pydoc -g has been deprecated in Python 3.2 and it has a new enhanced web - server. +- Issue #16820: In configparser, ``parser['section'] = {}`` now preserves + section order within the parser. This makes `parser.update()` preserve section + order as well. -- Issue #1441530: In imaplib, read the data in one chunk to speed up large - reads and simplify code. +- Issue #16820: In configparser, ``parser['DEFAULT'] = {}`` now correctly + clears previous values stored in the default section. Same goes for + ``parser.update({'DEFAULT': {}})``. -- Issue #12070: Fix the Makefile parser of the sysconfig module to handle - correctly references to "bogus variable" (e.g. "prefix=$/opt/python"). +- Issue #9586: Redefine SEM_FAILED on MacOSX to keep compiler happy. -- Issue #12100: Don't reset incremental encoders of CJK codecs at each call to - their encode() method anymore, but continue to call the reset() method if the - final argument is True. +- Issue #16787: Increase asyncore and asynchat default output buffers size, to + decrease CPU usage and increase throughput. -- Issue #12049: Add RAND_bytes() and RAND_pseudo_bytes() functions to the ssl - module. +- Issue #10527: make multiprocessing use poll() instead of select() if available. -- Issue #6501: os.device_encoding() returns None on Windows if the application - has no console. +- Issue #16688: Now regexes contained backreferences correctly work with + non-ASCII strings. Patch by Matthew Barnett. -- Issue #12105: Add O_CLOEXEC to the os module. +- Issue #16486: Make aifc files act as context managers. -- Issue #12079: Decimal('Infinity').fma(Decimal('0'), (3.91224318126786e+19+0j)) - now raises TypeError (reflecting the invalid type of the 3rd argument) rather - than Decimal.InvalidOperation. +- Issue #16485: Now file descriptors are closed if file header patching failed + on closing an aifc file. -- Issue #12124: zipimport doesn't keep a reference to zlib.decompress() anymore - to be able to unload the module. +- Issue #16640: Run less code under a lock in sched module. -- Add the packaging module, an improved fork of distutils (also known as - distutils2). +- Issue #16165: sched.scheduler.run() no longer blocks a scheduler for other + threads. -- Issue #12065: connect_ex() on an SSL socket now returns the original errno - when the socket's timeout expires (it used to return None). +- Issue #16641: Default values of sched.scheduler.enter() are no longer + modifiable. -- Issue #8809: The SMTP_SSL constructor and SMTP.starttls() now support - passing a ``context`` argument pointing to an ssl.SSLContext instance. - Patch by Kasun Herath. +- Issue #16618: Make glob.glob match consistently across strings and bytes + regarding leading dots. Patch by Serhiy Storchaka. -- Issue #9516: Issue #9516: avoid errors in sysconfig when MACOSX_DEPLOYMENT_TARGET - is set in shell. +- Issue #16788: Add samestat to Lib/ntpath.py -- Issue #8650: Make zlib module 64-bit clean. compress(), decompress() and - their incremental counterparts now raise OverflowError if given an input - larger than 4GB, instead of silently truncating the input and returning - an incorrect result. +- Issue #16713: Parsing of 'tel' urls using urlparse separates params from + path. -- Issue #12050: zlib.decompressobj().decompress() now clears the unconsumed_tail - attribute when called without a max_length argument. +- Issue #16443: Add docstrings to regular expression match objects. + Patch by Anton Kasyanov. -- Issue #12062: Fix a flushing bug when doing a certain type of I/O sequence - on a file opened in read+write mode (namely: reading, seeking a bit forward, - writing, then seeking before the previous write but still within buffered - data, and writing again). +- Issue #15701: Fix HTTPError info method call to return the headers information. -- Issue #9971: Write an optimized implementation of BufferedReader.readinto(). - Patch by John O'Connor. +- Issue #16752: Add a missing import to modulefinder. Patch by Berker Peksag. -- Issue #11799: urllib.request Authentication Handlers will raise a ValueError - when presented with an unsupported Authentication Scheme. Patch contributed - by Yuval Greenfield. +- Issue #16646: ftplib.FTP.makeport() might lose socket error details. + (patch by Serhiy Storchaka) -- Issue #10419, #6011: build_scripts command of distutils handles correctly - non-ASCII path (path to the Python executable). Open and write the script in - binary mode, but ensure that the shebang is decodable from UTF-8 and from the - encoding of the script. +- Issue #16626: Fix infinite recursion in glob.glob() on Windows when the + pattern contains a wildcard in the drive or UNC path. Patch by Serhiy + Storchaka. -- Issue #8498: In socket.accept(), allow to specify 0 as a backlog value in - order to accept exactly one connection. Patch by Daniel Evers. +- Issue #15783: Except for the number methods, the C version of decimal now + supports all None default values present in decimal.py. These values were + largely undocumented. -- Issue #12011: signal.signal() and signal.siginterrupt() raise an OSError, - instead of a RuntimeError: OSError has an errno attribute. +- Issue #11175: argparse.FileType now accepts encoding and errors + arguments. Patch by Lucas Maystre. -- Issue #3709: add a flush_headers method to BaseHTTPRequestHandler, which - manages the sending of headers to output stream and flushing the internal - headers buffer. Patch contribution by Andrew Schaaf +- Issue #16488: epoll() objects now support the `with` statement. Patch + by Serhiy Storchaka. -- Issue #11743: Rewrite multiprocessing connection classes in pure Python. +- Issue #16298: In HTTPResponse.read(), close the socket when there is no + Content-Length and the incoming stream is finished. Patch by Eran + Rundstein. -- Issue #11164: Stop trying to use _xmlplus in the xml module. +- Issue #16049: Add abc.ABC class to enable the use of inheritance to create + ABCs, rather than the more cumbersome metaclass=ABCMeta. Patch by Bruno + Dupuis. -- Issue #11888: Add log2 function to math module. Patch written by Mark - Dickinson. +- Expose the TCP_FASTOPEN and MSG_FASTOPEN flags in socket when they're + available. -- Issue #12012: ssl.PROTOCOL_SSLv2 becomes optional. +- Issue #15701: Add a .headers attribute to urllib.error.HTTPError. Patch + contributed by Berker Peksag. -- Issue #8407: The signal handler writes the signal number as a single byte - instead of a nul byte into the wakeup file descriptor. So it is possible to - wait more than one signal and know which signals were raised. +- Issue #15872: Fix 3.3 regression introduced by the new fd-based shutil.rmtree + that caused it to not ignore certain errors when ignore_errors was set. + Patch by Alessandro Moura and Serhiy Storchaka. -- Issue #8407: Add pthread_kill(), sigpending() and sigwait() functions to the - signal module. +- Issue #16248: Disable code execution from the user's home directory by + tkinter when the -E flag is passed to Python. Patch by Zachary Ware. -- Issue #11927: SMTP_SSL now uses port 465 by default as documented. Patch - by Kasun Herath. +- Issue #13390: New function :func:`sys.getallocatedblocks()` returns the + number of memory blocks currently allocated. -- Issue #12002: ftplib's abort() method raises TypeError. +- Issue #16628: Fix a memory leak in ctypes.resize(). -- Issue #11916: Add a number of MacOSX specific definitions to the errno module. - Patch by Pierre Carrier. +- Issue #13614: Fix setup.py register failure with invalid rst in description. + Patch by Julien Courteau and Pierre Paul Lefebvre. -- Issue #11999: fixed sporadic sync failure mailbox.Maildir due to its trying to - detect mtime changes by comparing to the system clock instead of to the - previous value of the mtime. +- Issue #13512: Create ~/.pypirc securely (CVE-2011-4944). Initial patch by + Philip Jenvey, tested by Mageia and Debian. -- Issue #11072: added MLSD command (RFC-3659) support to ftplib. +- Issue #7719: Make distutils ignore ``.nfs*`` files instead of choking later + on. Initial patch by SilentGhost and Jeff Ramnani. -- Issue #8808: The IMAP4_SSL constructor now allows passing an SSLContext - parameter to control parameters of the secure channel. Patch by Sijin - Joseph. +- Issue #13120: Allow to call pdb.set_trace() from thread. + Patch by Ilya Sandler. -- ntpath.samefile failed to notice that "a.txt" and "A.TXT" refer to the same - file on Windows XP. As noticed in issue #10684. +- Issue #16585: Make CJK encoders support error handlers that return bytes per + PEP 383. -- Issue #12000: When a SSL certificate has a subjectAltName without any - dNSName entry, ssl.match_hostname() should use the subject's commonName. - Patch by Nicolas Bareil. +- Issue #10182: The re module doesn't truncate indices to 32 bits anymore. + Patch by Serhiy Storchaka. -- Issue #10775: assertRaises, assertRaisesRegex, assertWarns, and - assertWarnsRegex now accept a keyword argument 'msg' when used as context - managers. Initial patch by Winston Ewert. +- Issue #16333: use (",", ": ") as default separator in json when indent is + specified, to avoid trailing whitespace. Patch by Serhiy Storchaka. -- Issue #10684: shutil.move used to delete a folder on case insensitive - filesystems when the source and destination name where the same except - for the case. +- Issue #16573: In 2to3, treat enumerate() like a consuming call, so superfluous + list() calls aren't added to filter(), map(), and zip() which are directly + passed enumerate(). -- Issue #11647: objects created using contextlib.contextmanager now support - more than one call to the function when used as a decorator. Initial patch - by Ysj Ray. +- Issue #16464: Reset the Content-Length header when a urllib Request is reused + with new data. -- Issue #11930: Removed deprecated time.accept2dyear variable. - Removed year >= 1000 restriction from datetime.strftime. +- Issue #12848: The pure Python pickle implementation now treats object + lengths as unsigned 32-bit integers, like the C implementation does. + Patch by Serhiy Storchaka. -- logging: don't define QueueListener if Python has no thread support. +- Issue #16423: urllib.request now has support for ``data:`` URLs. Patch by + Mathias Panzenböck. -- functools.cmp_to_key() now works with collections.Hashable(). +- Issue #4473: Add a POP3.stls() to switch a clear-text POP3 session into + an encrypted POP3 session, on supported servers. Patch by Lorenzo Catucci. -- Issue #11277: mmap.mmap() calls fcntl(fd, F_FULLFSYNC) on Mac OS X to get - around a mmap bug with sparse files. Patch written by Steffen Daode Nurpmeso. +- Issue #4473: Add a POP3.capa() method to query the capabilities advertised + by the POP3 server. Patch by Lorenzo Catucci. -- Issue #8407: Add signal.pthread_sigmask() function to fetch and/or change the - signal mask of the calling thread. +- Issue #4473: Ensure the socket is shutdown cleanly in POP3.close(). + Patch by Lorenzo Catucci. -- Issue #11858: configparser.ExtendedInterpolation expected lower-case section - names. +- Issue #16522: added FAIL_FAST flag to doctest. -- Issue #11324: ConfigParser(interpolation=None) now works correctly. +- Issue #15627: Add the importlib.abc.InspectLoader.source_to_code() method. -- Issue #11811: ssl.get_server_certificate() is now IPv6-compatible. Patch - by Charles-François Natali. +- Issue #16408: Fix file descriptors not being closed in error conditions + in the zipfile module. Patch by Serhiy Storchaka. -- Issue #11763: don't use difflib in TestCase.assertMultiLineEqual if the - strings are too long. +- Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak + references to bound methods. -- Issue #11236: getpass.getpass responds to ctrl-c or ctrl-z on terminal. +- Issue #16469: Fix exceptions from float -> Fraction and Decimal -> Fraction + conversions for special values to be consistent with those for float -> int + and Decimal -> int. Patch by Alexey Kachayev. -- Issue #11856: Speed up parsing of JSON numbers. +- Issue #16481: multiprocessing no longer leaks process handles on Windows. -- Issue #11005: threading.RLock()._release_save() raises a RuntimeError if the - lock was not acquired. +- Issue #12428: Add a pure Python implementation of functools.partial(). + Patch by Brian Thorne. -- Issue #11258: Speed up ctypes.util.find_library() under Linux by a factor - of 5 to 10. Initial patch by Jonas H. +- Issue #16140: The subprocess module no longer double closes its child + subprocess.PIPE parent file descriptors on child error prior to exec(). -- Issue #11382: Trivial system calls, such as dup() or pipe(), needn't - release the GIL. Patch by Charles-François Natali. +- Remove a bare print to stdout from the subprocess module that could have + happened if the child process wrote garbage to its pre-exec error pipe. -- Issue #11223: Add threading._info() function providing informations about - the thread implementation. +- The subprocess module now raises its own SubprocessError instead of a + RuntimeError in various error situations which should not normally happen. -- Issue #11731: simplify/enhance email parser/generator API by introducing - policy objects. +- Issue #16327: The subprocess module no longer leaks file descriptors + used for stdin/stdout/stderr pipes to the child when fork() fails. -- Issue #11768: The signal handler of the signal module only calls - Py_AddPendingCall() for the first signal to fix a deadlock on reentrant or - parallel calls. PyErr_SetInterrupt() writes also into the wake up file. +- Issue #14396: Handle the odd rare case of waitpid returning 0 when not + expected in subprocess.Popen.wait(). -- Issue #11492: fix several issues with header folding in the email package. +- Issue #16411: Fix a bug where zlib.decompressobj().flush() might try to access + previously-freed memory. Patch by Serhiy Storchaka. -- Issue #11852: Add missing imports and update tests. +- Issue #16357: fix calling accept() on a SSLSocket created through + SSLContext.wrap_socket(). Original patch by Jeff McNeil. -- Issue #11875: collections.OrderedDict's __reduce__ was temporarily - mutating the object instead of just working on a copy. +- Issue #16409: The reporthook callback made by the legacy + urllib.request.urlretrieve API now properly supplies a constant non-zero + block_size as it did in Python 3.2 and 2.7. This matches the behavior of + urllib.request.URLopener.retrieve. -- Issue #11467: Fix urlparse behavior when handling urls which contains scheme - specific part only digits. Patch by Santoso Wijaya. +- Issue #16431: Use the type information when constructing a Decimal subtype + from a Decimal argument. -- collections.Counter().copy() now works correctly for subclasses. +- Issue #15641: Clean up deprecated classes from importlib + Patch by Taras Lyapun. -- Issue #11474: Fix the bug with url2pathname() handling of '/C|/' on Windows. - Patch by Santoso Wijaya. +- Issue #16350: zlib.decompressobj().decompress() now accumulates data from + successive calls after EOF in unused_data, instead of only saving the argument + to the last call. decompressobj().flush() now correctly sets unused_data and + unconsumed_tail. A bug in the handling of MemoryError when setting the + unconsumed_tail attribute has also been fixed. Patch by Serhiy Storchaka. -- Issue #11684: complete email.parser bytes API by adding BytesHeaderParser. +- Issue #12759: sre_parse now raises a proper error when the name of the group + is missing. Initial patch by Serhiy Storchaka. -- The bz2 module now handles 4GiB+ input buffers correctly. +- Issue #16152: fix tokenize to ignore whitespace at the end of the code when + no newline is found. Patch by Ned Batchelder. -- Issue #9233: Fix json.loads('{}') to return a dict (instead of a list), when - _json is not available. +- Issue #16284: Prevent keeping unnecessary references to worker functions + in concurrent.futures ThreadPoolExecutor. -- Issue #11830: Remove unnecessary introspection code in the decimal module. +- Issue #16230: Fix a crash in select.select() when one the lists changes + size while iterated on. Patch by Serhiy Storchaka. -- Issue #11703: urllib2.geturl() does not return correct url when the original - url contains #fragment. +- Issue #16228: Fix a crash in the json module where a list changes size + while it is being encoded. Patch by Serhiy Storchaka. -- Issue #10019: Fixed regression in json module where an indent of 0 stopped - adding newlines and acted instead like 'None'. +- Issue #16351: New function gc.get_stats() returns per-generation collection + statistics. -- Issue #11186: pydoc ignores a module if its name contains a surrogate - character in the index of modules. +- Issue #14897: Enhance error messages of struct.pack and + struct.pack_into. Patch by Matti Mäki. -- Issue #11815: Use a light-weight SimpleQueue for the result queue in - concurrent.futures.ProcessPoolExecutor. +- Issue #16316: mimetypes now recognizes the .xz and .txz (.tar.xz) extensions. + Patch by Serhiy Storchaka. -- Issue #5162: Treat services like frozen executables to allow child spawning - from multiprocessing.forking on Windows. +- Issue #12890: cgitb no longer prints spurious

tags in text + mode when the logdir option is specified. -- logging.basicConfig now supports an optional 'handlers' argument taking an - iterable of handlers to be added to the root logger. Additional parameter - checks were also added to basicConfig. +- Issue #16307: Fix multiprocessing.Pool.map_async not calling its callbacks. + Patch by Janne Karila. -- Issue #11814: Fix likely typo in multiprocessing.Pool._terminate(). +- Issue #16305: Fix a segmentation fault occurring when interrupting + math.factorial. -- Issue #11747: Fix range formatting in difflib.context_diff() and - difflib.unified_diff(). +- Issue #16116: Fix include and library paths to be correct when building C + extensions in venvs. -- Issue #8428: Fix a race condition in multiprocessing.Pool when terminating - worker processes: new processes would be spawned while the pool is being - shut down. Patch by Charles-François Natali. +- Issue #16245: Fix the value of a few entities in html.entities.html5. -- Issue #2650: re.escape() no longer escapes the '_'. +- Issue #16301: Fix the localhost verification in urllib/request.py for file:// + urls. -- Issue #11757: select.select() now raises ValueError when a negative timeout - is passed (previously, a select.error with EINVAL would be raised). Patch - by Charles-François Natali. +- Issue #16250: Fix the invocations of URLError which had misplaced filename + attribute for exception. -- Issue #7311: fix html.parser to accept non-ASCII attribute values. +- Issue #10836: Fix exception raised when file not found in urlretrieve + Initial patch by Ezio Melotti. -- Issue #11605: email.parser.BytesFeedParser was incorrectly converting - multipart subparts with an 8-bit CTE into unicode instead of preserving the - bytes. +- Issue #14398: Fix size truncation and overflow bugs in the bz2 module. -- Issue #1690608: email.util.formataddr is now RFC 2047 aware: it now has a - charset parameter that defaults to utf-8 and is used as the charset for RFC - 2047 encoding when the realname contains non-ASCII characters. +- Issue #12692: Fix resource leak in urllib.request when talking to an HTTP + server that does not include a ``Connection: close`` header in its responses. -- Issue #10963: Ensure that subprocess.communicate() never raises EPIPE. +- Issue #12034: Fix bogus caching of result in check_GetFinalPathNameByHandle. + Patch by Atsuo Ishimoto. -- Issue #10791: Implement missing method GzipFile.read1(), allowing GzipFile - to be wrapped in a TextIOWrapper. Patch by Nadeem Vawda. +- Improve performance of `lzma.LZMAFile` (see also issue #16034). -- Issue #11707: Added a fast C version of functools.cmp_to_key(). - Patch by Filip Gruszczyński. +- Issue #16220: wsgiref now always calls close() on an iterable response. + Patch by Brent Tubbs. -- Issue #11688: Add sqlite3.Connection.set_trace_callback(). Patch by - Torsten Landschoff. +- Issue #16270: urllib may hang when used for retrieving files via FTP by using + a context manager. Patch by Giampaolo Rodola'. -- Issue #11746: Fix SSLContext.load_cert_chain() to accept elliptic curve - private keys. +- Issue #16461: Wave library should be able to deal with 4GB wav files, + and sample rate of 44100 Hz. -- Issue #5863: Rewrite BZ2File in pure Python, and allow it to accept - file-like objects using a new ``fileobj`` constructor argument. Patch by - Nadeem Vawda. +- Issue #16176: Properly identify Windows 8 via platform.platform() -- unittest.TestCase.assertSameElements has been removed. +- Issue #16088: BaseHTTPRequestHandler's send_error method includes a + Content-Length header in it's response now. Patch by Antoine Pitrou. -- sys.getfilesystemencoding() raises a RuntimeError if initfsencoding() was not - called yet: detect bootstrap (startup) issues earlier. +- 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 + keyword arguments specified a path that did not exist. -- Issue #11393: Add the new faulthandler module. +- Issue #16169: Fix ctypes.WinError()'s confusion between errno and winerror. -- Issue #11618: Fix the timeout logic in threading.Lock.acquire() under Windows. +- Issue #16110: logging.fileConfig now accepts a pre-initialised ConfigParser + instance. -- Removed the 'strict' argument to email.parser.Parser, which has been - deprecated since Python 2.4. +- Issue #1492704: shutil.copyfile() raises a distinct SameFileError now if + source and destination are the same file. Patch by Atsuo Ishimoto. -- Issue #11256: Fix inspect.getcallargs on functions that take only keyword - arguments. +- Issue #13896: Make shelf instances work with 'with' as context managers. + Original patch by Filip Gruszczyński. -- Issue #11696: Fix ID generation in msilib. +- Issue #15417: Add support for csh and fish in venv activation scripts. -- itertools.accumulate now supports an optional *func* argument for - a user-supplied binary function. +- Issue #14377: ElementTree.write and some of the module-level functions have + a new parameter - *short_empty_elements*. It controls how elements with no + contents are emitted. -- Issue #11692: Remove unnecessary demo functions in subprocess module. +- Issue #16089: Allow ElementTree.TreeBuilder to work again with a non-Element + element_factory (fixes a regression in SimpleTAL). -- Issue #9696: Fix exception incorrectly raised by xdrlib.Packer.pack_int when - trying to pack a negative (in-range) integer. +- Issue #9650: List commonly used format codes in time.strftime and + time.strptime docsttings. Original patch by Mike Hoy. -- Issue #11675: multiprocessing.[Raw]Array objects created from an integer size - are now zeroed on creation. This matches the behaviour specified by the - documentation. +- Issue #15452: logging configuration socket listener now has a verify option + that allows an application to apply a verification function to the + received configuration data before it is acted upon. -- Issue #7639: Fix short file name generation in bdist_msi +- Issue #16034: Fix performance regressions in the new `bz2.BZ2File` + implementation. Initial patch by Serhiy Storchaka. -- Issue #11635: Don't use polling in worker threads and processes launched by - concurrent.futures. +- `pty.spawn()` now returns the child process status returned by `os.waitpid()`. -- Issue #5845: Automatically read readline configuration to enable completion - in interactive mode. +- Issue #15756: `subprocess.poll()` now properly handles `errno.ECHILD` to + return a returncode of 0 when the child has already exited or cannot be waited + on. -- Issue #6811: Allow importlib to change a code object's co_filename attribute - to match the path to where the source code currently is, not where the code - object originally came from. +- Issue #15323: Improve failure message of `Mock.assert_called_once_with()`. -- Issue #8754: Have importlib use the repr of a module name in error messages. +- Issue #16064: ``unittest -m`` claims executable is "python", not "python3". -- Issue #11591: Prevent "import site" from modifying sys.path when python - was started with -S. +- Issue #12376: Pass on parameters in `TextTestResult.__init__()` super call. -- collections.namedtuple() now adds a _source attribute to the generated - class. This make the source more accessible than the outdated - "verbose" option which prints to stdout but doesn't make the source - string available. +- Issue #15222: Insert blank line after each message in mbox mailboxes. -- Issue #11371: Mark getopt error messages as localizable. Patch by Filip - Gruszczyński. +- Issue #16013: Fix `csv.Reader` parsing issue with ending quote characters. + Patch by Serhiy Storchaka. -- Issue #11333: Add __slots__ to collections ABCs. +- Issue #15421: Fix an OverflowError in `Calendar.itermonthdates()` after + `datetime.MAXYEAR`. Patch by Cédric Krier. -- Issue #11628: cmp_to_key generated class should use __slots__. +- Issue #16112: platform.architecture does not correctly escape argument to + /usr/bin/file. Patch by David Benjamin. -- Issue #11666: let help() display named tuple attributes and methods - that start with a leading underscore. +- Issue #15970: `xml.etree.ElementTree` now serializes correctly the empty HTML + elements 'meta' and 'param'. -- Issue #11662: Make urllib and urllib2 ignore redirections if the - scheme is not HTTP, HTTPS or FTP (CVE-2011-1521). +- Issue #15842: The `SocketIO.{readable,writable,seekable}` methods now raise + ValueError when the file-like object is closed. Patch by Alessandro Moura. -- Issue #5537: Fix time2isoz() and time2netscape() functions of - httplib.cookiejar for expiration year greater than 2038 on 32-bit systems. +- Issue #15876: Fix a refleak in the `curses` module: window.encoding. -- Issue #4391: Use proper gettext plural forms in optparse. +- Issue #15881: Fix `atexit` hook in `multiprocessing`. Original patch by Chris + McDonough. -- Issue #11127: Raise a TypeError when trying to pickle a socket object. +- Issue #15841: The readable(), writable() and seekable() methods of + `io.BytesIO` and `io.StringIO` objects now raise ValueError when the object + has been closed. Patch by Alessandro Moura. -- Issue #11563: ``Connection: close`` header is sent by requests using URLOpener - class which helps in closing of sockets after connection is over. Patch - contributions by Jeff McNeil and Nadeem Vawda. +- Issue #15447: Use `subprocess.DEVNULL` in webbrowser, instead of opening + `os.devnull` explicitly and leaving it open. -- Issue #11459: A ``bufsize`` value of 0 in subprocess.Popen() really creates - unbuffered pipes, such that select() works properly on them. +- Issue #15509: `webbrowser.UnixBrowser` no longer passes empty arguments to + Popen when ``%action`` substitutions produce empty strings. -- Issue #5421: Fix misleading error message when one of socket.sendto()'s - arguments has the wrong type. Patch by Nikita Vetoshkin. +- Issue #12776, issue #11839: Call `argparse` type function (specified by + add_argument) only once. Before, the type function was called twice in the + case where the default was specified and the argument was given as well. This + was especially problematic for the FileType type, as a default file would + always be opened, even if a file argument was specified on the command line. -- Issue #10812: Add some extra posix functions to the os module. +- Issue #15906: Fix a regression in argparse caused by the preceding change, + when ``action='append'``, ``type='str'`` and ``default=[]``. -- Issue #10979: unittest stdout buffering now works with class and module - setup and teardown. +- Issue #16113: Added sha3 module based on the Keccak reference implementation + 3.2. The `hashlib` module has four additional hash algorithms: `sha3_224`, + `sha3_256`, `sha3_384` and `sha3_512`. As part of the patch some common + code was moved from _hashopenssl.c to hashlib.h. -- Issue #11243: fix the parameter querying methods of Message to work if - the headers contain un-encoded non-ASCII data. +- ctypes.call_commethod was removed, since its only usage was in the defunct + samples directory. -- Issue #11401: fix handling of headers with no value; this fixes a regression - relative to Python2 and the result is now the same as it was in Python2. +- Issue #16692: Added TLSv1.1 and TLSv1.2 support for the ssl modules. -- Issue #9298: base64 bodies weren't being folded to line lengths less than 78, - which was a regression relative to Python2. Unlike Python2, the last line - of the folded body now ends with a carriage return. +- Issue #16832: add abc.get_cache_token() to expose cache validity checking + support in ABCMeta. -- Issue #11560: shutil.unpack_archive now correctly handles the format - parameter. Patch by Evan Dandrea. +IDLE +---- -- Issue #5870: Add `subprocess.DEVNULL` constant. +- Issue #18429: Format / Format Paragraph, now works when comment blocks + are selected. As with text blocks, this works best when the selection + only includes complete lines. -- Issue #11133: fix two cases where inspect.getattr_static can trigger code - execution. Patch by Andreas Stührk. +- Issue #18226: Add docstrings and unittests for FormatParagraph.py. + Original patches by Todd Rovito and Phil Webster. -- Issue #11569: use absolute path to the sysctl command in multiprocessing to - ensure that it will be found regardless of the shell PATH. This ensures - that multiprocessing.cpu_count works on default installs of MacOSX. +- Issue #18279: Format - Strip trailing whitespace no longer marks a file as + changed when it has not been changed. This fix followed the addition of a + test file originally written by Phil Webster (the issue's main goal). -- Issue #11501: disutils.archive_utils.make_zipfile no longer fails if zlib is - not installed. Instead, the zipfile.ZIP_STORED compression is used to create - the ZipFile. Patch by Natalia B. Bidart. +- Issue #7136: In the Idle File menu, "New Window" is renamed "New File". + Patch by Tal Einat, Roget Serwy, and Todd Rovito. -- Issue #11289: `smtp.SMTP` class is now a context manager so it can be used - in a `with` statement. Contributed by Giampaolo Rodola. +- Remove dead imports of imp. -- Issue #11554: Fixed support for Japanese codecs; previously the body output - encoding was not done if euc-jp or shift-jis was specified as the charset. +- Issue #18196: Avoid displaying spurious SystemExit tracebacks. -- Issue #11407: `TestCase.run` returns the result object used or created. - Contributed by Janathan Hartley. +- Issue #5492: Avoid traceback when exiting IDLE caused by a race condition. -- Issue #11500: Fixed a bug in the OS X proxy bypass code for fully qualified - IP addresses in the proxy exception list. +- Issue #17511: Keep IDLE find dialog open after clicking "Find Next". + Original patch by Sarah K. -- Issue #11491: dbm.error is no longer raised when dbm.open is called with - the "n" as the flag argument and the file exists. The behavior matches - the documentation and general logic. +- Issue #18055: Move IDLE off of imp and on to importlib. -- Issue #1162477: Postel Principle adjustment to email date parsing: handle the - fact that some non-compliant MUAs use '.' instead of ':' in time specs. +- Issue #15392: Create a unittest framework for IDLE. + Initial patch by Rajagopalasarma Jayakrishnan. + See Lib/idlelib/idle_test/README.txt for how to run Idle tests. -- Issue #11131: Fix sign of zero in decimal.Decimal plus and minus - operations when the rounding mode is ROUND_FLOOR. +- Issue #14146: Highlight source line while debugging on Windows. -- Issue #9935: Speed up pickling of instances of user-defined classes. +- Issue #17838: Allow sys.stdin to be reassigned. -- Issue #5622: Fix curses.wrapper to raise correct exception if curses - initialization fails. +- Issue #13495: Avoid loading the color delegator twice in IDLE. -- Issue #11408: In threading.Lock.acquire(), only call gettimeofday() when - really necessary. Patch by Charles-François Natali. +- Issue #17798: Allow IDLE to edit new files when specified on command line. -- Issue #11391: Writing to a mmap object created with - ``mmap.PROT_READ|mmap.PROT_EXEC`` would segfault instead of raising a - TypeError. Patch by Charles-François Natali. +- Issue #14735: Update IDLE docs to omit "Control-z on Windows". -- Issue #9795: add context manager protocol support for nntplib.NNTP class. +- Issue #17532: Always include Options menu for IDLE on OS X. + Patch by Guilherme Simões. -- Issue #11306: mailbox in certain cases adapts to an inability to open - certain files in read-write mode. Previously it detected this by - checking for EACCES, now it also checks for EROFS. +- Issue #17585: Fixed IDLE regression. Now closes when using exit() or quit(). -- Issue #11265: asyncore now correctly handles EPIPE, EBADF and EAGAIN errors - on accept(), send() and recv(). +- Issue #17657: Show full Tk version in IDLE's about dialog. + Patch by Todd Rovito. -- Issue #11377: Deprecate platform.popen() and reimplement it with os.popen(). +- Issue #17613: Prevent traceback when removing syntax colorizer in IDLE. -- Issue #8513: On UNIX, subprocess supports bytes command string. +- Issue #1207589: Backwards-compatibility patch for right-click menu in IDLE. -- Issue #10866: Add socket.sethostname(). Initial patch by Ross Lagerwall. +- Issue #16887: IDLE now accepts Cancel in tabify/untabify dialog box. -- Issue #11140: Lock.release() now raises a RuntimeError when attempting - to release an unacquired lock, as claimed in the threading documentation. - The _thread.error exception is now an alias of RuntimeError. Patch by - Filip Gruszczyński. Patch for _dummy_thread by Aymeric Augustin. +- Issue #17625: In IDLE, close the replace dialog after it is used. -- Issue #8594: ftplib now provides a source_address parameter to specify which - (address, port) to bind to before connecting. +- Issue #14254: IDLE now handles readline correctly across shell restarts. -- Issue #11326: Add the missing connect_ex() implementation for SSL sockets, - and make it work for non-blocking connects. +- Issue #17614: IDLE no longer raises exception when quickly closing a file. -- Issue #11297: Add collections.ChainMap(). +- Issue #6698: IDLE now opens just an editor window when configured to do so. -- Issue #10755: Add the posix.flistdir() function. Patch by Ross Lagerwall. +- Issue #8900: Using keyboard shortcuts in IDLE to open a file no longer + raises an exception. -- Issue #4761: Add the ``*at()`` family of functions (openat(), etc.) to the - posix module. Patch by Ross Lagerwall. +- Issue #6649: Fixed missing exit status in IDLE. Patch by Guilherme Polo. -- Issue #7322: Trying to read from a socket's file-like object after a timeout - occurred now raises an error instead of silently losing data. +- Issue #17114: IDLE now uses non-strict config parser. -- Issue #11291: poplib.POP no longer suppresses errors on quit(). +- Issue #9290: In IDLE the sys.std* streams now implement io.TextIOBase + interface and support all mandatory methods and properties. -- Issue #11177: asyncore's create_socket() arguments can now be omitted. +- Issue #5066: Update IDLE docs. Patch by Todd Rovito. -- Issue #6064: Add a ``daemon`` keyword argument to the threading.Thread - and multiprocessing.Process constructors in order to override the - default behaviour of inheriting the daemonic property from the current - thread/process. +- Issue #16829: IDLE printing no longer fails if there are spaces or other + special characters in the file path. -- Issue #10956: Buffered I/O classes retry reading or writing after a signal - has arrived and the handler returned successfully. +- Issue #16491: IDLE now prints chained exception tracebacks. -- Issue #10784: New os.getpriority() and os.setpriority() functions. +- Issue #16819: IDLE method completion now correctly works for bytes literals. -- Issue #11114: Fix catastrophic performance of tell() on text files (up - to 1000x faster in some cases). It is still one to two order of magnitudes - slower than binary tell(). +- Issue #16504: IDLE now catches SyntaxErrors raised by tokenizer. Patch by + Roger Serwy. -- Issue #10882: Add os.sendfile function. +- Issue #16511: Use default IDLE width and height if config param is not valid. + Patch Serhiy Storchaka. -- Issue #10868: Allow usage of the register method of an ABC as a class - decorator. +- Issue #1207589: Add Cut/Copy/Paste items to IDLE right click Context Menu + Patch by Todd Rovito. -- Issue #11224: Fixed a regression in tarfile that affected the file-like - objects returned by TarFile.extractfile() regarding performance, memory - consumption and failures with the stream interface. +- Issue #16123: IDLE - deprecate running without a subprocess. + Patch by Roger Serwy. -- Issue #10924: Adding salt and Modular Crypt Format to crypt library. - Moved old C wrapper to _crypt, and added a Python wrapper with - enhanced salt generation and simpler API for password generation. +Tests +----- -- Issue #11074: Make 'tokenize' so it can be reloaded. +- Issue #1666318: Add a test that shutil.copytree() retains directory + permissions. Patch by Catherine Devlin. -- Issue #11085: Moved collections abstract base classes into a separate - module called collections.abc, following the pattern used by importlib.abc. - For backwards compatibility, the names are imported into the collections - module. +- Issue #18273: move the tests in Lib/test/json_tests to Lib/test/test_json + and make them discoverable by unittest. Patch by Zachary Ware. -- Issue #4681: Allow mmap() to work on file sizes and offsets larger than - 4GB, even on 32-bit builds. Initial patch by Ross Lagerwall, adapted for - 32-bit Windows. +- Fix a fcntl test case on KFreeBSD, Debian #708653 (Petr Salinger). -- Issue #11169: compileall module uses repr() to format filenames and paths to - escape surrogate characters and show spaces. +- Issue #18396: Fix spurious test failure in test_signal on Windows when + faulthandler is enabled (Patch by Jeremy Kloth) -- Issue #11089: Fix performance issue limiting the use of ConfigParser() - with large config files. +- Issue #17046: Fix broken test_executable_without_cwd in test_subprocess. -- Issue #10276: Fix the results of zlib.crc32() and zlib.adler32() on buffers - larger than 4GB. Patch by Nadeem Vawda. +- Issue #15415: Add new temp_dir() and change_cwd() context managers to + test.support, and refactor temp_cwd() to use them. Patch by Chris Jerdonek. -- Issue #11388: Added a clear() method to MutableSequence +- Issue #15494: test.support is now a package rather than a module (Initial + patch by Indra Talip) -- Issue #11174: Add argparse.MetavarTypeHelpFormatter, which uses type names - for the names of optional and positional arguments in help messages. +- Issue #17944: test_zipfile now discoverable and uses subclassing to + generate tests for different compression types. Fixed a bug with skipping + some tests due to use of exhausted iterators. -- Issue #9348: Raise an early error if argparse nargs and metavar don't match. +- Issue #18266: test_largefile now works with unittest test discovery and + supports running only selected tests. Patch by Zachary Ware. -- Issue #9026: Fix order of argparse sub-commands in help messages. +- Issue #17767: test_locale now works with unittest test discovery. + Original patch by Zachary Ware. -- Issue #9347: Fix formatting for tuples in argparse type= error messages. +- Issue #18375: Assume --randomize when --randseed is used for running the + testsuite. -- Issue #12191: Added shutil.chown() to change user and/or group owner of a - given path also specifying their names. +- Issue #11185: Fix test_wait4 under AIX. Patch by Sébastien Sablé. -- Issue #13988: The _elementtree accelerator is used whenever available. - Now xml.etree.cElementTree becomes a deprecated alias to ElementTree. +- Issue #18207: Fix test_ssl for some versions of OpenSSL that ignore seconds + in ASN1_TIME fields. -Build ------ +- Issue #18094: test_uuid no longer reports skipped tests as passed. -- Issue #6807: Run msisupport.mak earlier. +- Issue #17992: Add timeouts to asyncore and asynchat tests so that they won't + accidentally hang. -- Issue #10580: Minor grammar change in Windows installer. +- Issue #17833: Fix test_gdb failures seen on machines where debug symbols + for glibc are available (seen on PPC64 Linux). -- Issue #13326: Clean __pycache__ directories correctly on OpenBSD. +- Issue #7855: Add tests for ctypes/winreg for issues found in IronPython. + Initial patch by Dino Viehland. -- PEP 393: the configure option --with-wide-unicode is removed. +- Issue #11078: test___all__ now checks for duplicates in __all__. + Initial patch by R. David Murray. -- Issue #12852: Set _XOPEN_SOURCE to 700, instead of 600, to get POSIX 2008 - functions on OpenBSD (e.g. fdopendir). +- Issue #17712: Fix test_gdb failures on Ubuntu 13.04. -- Issue #11863: Remove support for legacy systems deprecated in Python 3.2 - (following PEP 11). These systems are systems using Mach C Threads, - SunOS lightweight processes, GNU pth threads and IRIX threads. +- Issue #17835: Fix test_io when the default OS pipe buffer size is larger + than one million bytes. -- Issue #8746: Correct faulty configure checks so that os.chflags() and - os.lchflags() are once again built on systems that support these - functions (BSD and OS X). Also add new stat file flags for OS X - (UF_HIDDEN and UF_COMPRESSED). +- Issue #17065: Use process-unique key for winreg tests to avoid failures if + test is run multiple times in parallel (eg: on a buildbot host). -- Issue #10645: Installing Python no longer creates a - Python-X.Y.Z-pyX.Y.egg-info file in the lib-dynload directory. +- Issue #12820: add tests for the xml.dom.minicompat module. + Patch by John Chandler and Phil Connell. -- Do not accidentally include the directory containing sqlite.h twice when - building sqlite3. +- Issue #17691: test_univnewlines now works with unittest test discovery. + Patch by Zachary Ware. -- Issue #11217: For 64-bit/32-bit Mac OS X universal framework builds, - ensure "make install" creates symlinks in --prefix bin for the "-32" - files in the framework bin directory like the installer does. +- Issue #17790: test_set now works with unittest test discovery. + Patch by Zachary Ware. -- Issue #11347: Use --no-as-needed when linking libpython3.so. +- Issue #17789: test_random now works with unittest test discovery. + Patch by Zachary Ware. -- Issue #11411: Fix 'make DESTDIR=' with a relative destination. +- Issue #17779: test_osx_env now works with unittest test discovery. + Patch by Zachary Ware. -- Issue #11268: Prevent Mac OS X Installer failure if Documentation - package had previously been installed. +- Issue #17766: test_iterlen now works with unittest test discovery. + Patch by Zachary Ware. -- Issue #11495: OSF support is eliminated. It was deprecated in Python 3.2. +- Issue #17690: test_time now works with unittest test discovery. + Patch by Zachary Ware. -IDLE ----- +- Issue #17692: test_sqlite now works with unittest test discovery. + Patch by Zachary Ware. -- Issue #14409: IDLE now properly executes commands in the Shell window - when it cannot read the normal config files on startup and - has to use the built-in default key bindings. - There was previously a bug in one of the defaults. +- Issue #11995: test_pydoc doesn't import all sys.path modules anymore. -- IDLE can be launched as python -m idlelib +- Issue #17448: test_sax now skips if there are no xml parsers available + instead of raising an ImportError. -- Issue #3573: IDLE hangs when passing invalid command line args - (directory(ies) instead of file(s)) (Patch by Guilherme Polo) +- Issue #11420: make test suite pass with -B/DONTWRITEBYTECODE set. + Initial patch by Thomas Wouters. -- Issue #14200: IDLE shell crash on printing non-BMP unicode character. +- Issue #10652: make tcl/tk tests run after __all__ test, patch by + Zachary Ware. -- Issue #5219: Prevent event handler cascade in IDLE. +- Issue #11963: remove human verification from test_parser and test_subprocess. -- Issue #964437: Make IDLE help window non-modal. - Patch by Guilherme Polo and Roger Serwy. +- Issue #11732: add a new suppress_crash_popup() context manager to test.support + that disables crash popups on Windows and use it in test_faulthandler and + test_capi. -- Issue #13933: IDLE auto-complete did not work with some imported - module, like hashlib. (Patch by Roger Serwy) +- Issue #13898: test_ssl no longer prints a spurious stack trace on Ubuntu. -- Issue #13506: Add '' to path for IDLE Shell when started and restarted with Restart Shell. - Original patches by Marco Scataglini and Roger Serwy. +- Issue #17283: Share code between `__main__.py` and `regrtest.py` in + `Lib/test`. -- Issue #4625: If IDLE cannot write to its recent file or breakpoint files, - display a message popup and continue rather than crash. Original patch by - Roger Serwy. +- Issue #17249: convert a test in test_capi to use unittest and reap threads. -- Issue #8641: Update IDLE 3 syntax coloring to recognize b".." and not u"..". - Patch by Tal Einat. +- Issue #17107: Test client-side SNI support in urllib.request thanks to + the new server-side SNI support in the ssl module. Initial patch by + Daniel Black. -- Issue #13296: Fix IDLE to clear compile __future__ flags on shell restart. - (Patch by Roger Serwy) +- Issue #17041: Fix testing when Python is configured with the + --without-doc-strings. -- Issue #9871: Prevent IDLE 3 crash when given byte stings - with invalid hex escape sequences, like b'\x0'. - (Original patch by Claudiu Popa.) +- Issue #16923: Fix ResourceWarnings in test_ssl. -- Issue #12636: IDLE reads the coding cookie when executing a Python script. +- Issue #15539: Added regression tests for Tools/scripts/pindent.py. -- Issue #12540: Prevent zombie IDLE processes on Windows due to changes - in os.kill(). +- Issue #17479: test_io now works with unittest test discovery. + Patch by Zachary Ware. -- Issue #12590: IDLE editor window now always displays the first line - when opening a long file. With Tk 8.5, the first line was hidden. +- Issue #17066: test_robotparser now works with unittest test discovery. + Patch by Zachary Ware. -- Issue #11088: don't crash when using F5 to run a script in IDLE on MacOSX - with Tk 8.5. +- Issue #17334: test_index now works with unittest test discovery. + Patch by Zachary Ware. -- Issue #1028: Tk returns invalid Unicode null in %A: UnicodeDecodeError. - With Tk < 8.5 _tkinter.c:PythonCmd() raised UnicodeDecodeError, caused - IDLE to exit. Converted to valid Unicode null in PythonCmd(). +- Issue #17333: test_imaplib now works with unittest test discovery. + Patch by Zachary Ware. -- Issue #11718: IDLE's open module dialog couldn't find the __init__.py - file in a package. +- Issue #17082: test_dbm* now work with unittest test discovery. + Patch by Zachary Ware. -Tools/Demos ------------ +- Issue #17079: test_ctypes now works with unittest test discovery. + Patch by Zachary Ware. -- Issue #14053: patchcheck.py ("make patchcheck") now works with MQ patches. - Patch by Francisco Martín Brugué. +- Issue #17304: test_hash now works with unittest test discovery. + Patch by Zachary Ware. -- Issue #13930: 2to3 is now able to write its converted output files to another - directory tree as well as copying unchanged files and altering the file - suffix. See its new -o, -W and --add-suffix options. This makes it more - useful in many automated code translation workflows. +- Issue #17303: test_future* now work with unittest test discovery. + Patch by Zachary Ware. -- Issue #13628: python-gdb.py is now able to retrieve more frames in the Python - traceback if Python is optimized. +- Issue #17163: test_file now works with unittest test discovery. + Patch by Zachary Ware. -- Issue #11996: libpython (gdb), replace "py-bt" command by "py-bt-full" and - add a smarter "py-bt" command printing a classic Python traceback. +- Issue #16925: test_configparser now works with unittest test discovery. + Patch by Zachary Ware. -- Issue #11179: Make ccbench work under Python 3.1 and 2.7 again. +- Issue #16918: test_codecs now works with unittest test discovery. + Patch by Zachary Ware. -- Issue #10639: reindent.py no longer converts newlines and will raise - an error if attempting to convert a file with mixed newlines. - "--newline" option added to specify new line character. +- Issue #16919: test_crypt now works with unittest test discovery. + Patch by Zachary Ware. -Extension Modules ------------------ +- Issue #16910: test_bytes, test_unicode, and test_userstring now work with + unittest test discovery. Patch by Zachary Ware. -- Issue #16847: Fixed improper use of _PyUnicode_CheckConsistency() in - non-pydebug builds. Several extension modules now compile cleanly when - assert()s are enabled in standard builds (-DDEBUG flag). +- Issue #16905: test_warnings now works with unittest test discovery. + Initial patch by Berker Peksag. -- Issue #13840: The error message produced by ctypes.create_string_buffer - when given a Unicode string has been fixed. +- Issue #16898: test_bufio now works with unittest test discovery. + Patch by Zachary Ware. -- Issue #9975: socket: Fix incorrect use of flowinfo and scope_id. Patch by - Vilmos Nebehaj. +- Issue #16888: test_array now works with unittest test discovery. + Patch by Zachary Ware. -- Issue #7777: socket: Add Reliable Datagram Sockets (PF_RDS) support. +- Issue #16896: test_asyncore now works with unittest test discovery. + Patch by Zachary Ware. -- Issue #13159: FileIO and BZ2Compressor/BZ2Decompressor now use a linear-time - buffer growth strategy instead of a quadratic-time one. +- Issue #16897: test_bisect now works with unittest test discovery. + Initial patch by Zachary Ware. -- Issue #10141: socket: Add SocketCAN (PF_CAN) support. Initial patch by - Matthias Fuchs, updated by Tiago Gonçalves. +- Issue #16852: test_genericpath, test_posixpath, test_ntpath, and test_macpath + now work with unittest test discovery. Patch by Zachary Ware. -- Issue #13070: Fix a crash when a TextIOWrapper caught in a reference cycle - would be finalized after the reference to its underlying BufferedRWPair's - writer got cleared by the GC. +- Issue #16748: test_heapq now works with unittest test discovery. -- Issue #12881: ctypes: Fix segfault with large structure field names. +- Issue #10646: Tests rearranged for os.samefile/samestat to check for not + just symlinks but also hard links. -- Issue #13058: ossaudiodev: fix a file descriptor leak on error. Patch by - Thomas Jarosch. +- Issue #15302: Switch regrtest from using getopt to using argparse. -- Issue #13013: ctypes: Fix a reference leak in PyCArrayType_from_ctype. - Thanks to Suman Saha for finding the bug and providing a patch. +- Issue #15324: Fix regrtest parsing of --fromfile, --match, and --randomize + options. -- Issue #13022: Fix: _multiprocessing.recvfd() doesn't check that - file descriptor was actually received. +- Issue #16702: test_urllib2_localnet tests now correctly ignores proxies for + localhost tests. -- Issue #1172711: Add 'long long' support to the array module. - Initial patch by Oren Tirosh and Hirokazu Yamamoto. +- Issue #16664: Add regression tests for glob's behaviour concerning entries + starting with a ".". Patch by Sebastian Kreft. -- Issue #12483: ctypes: Fix a crash when the destruction of a callback - object triggers the garbage collector. +- Issue #13390: The ``-R`` option to regrtest now also checks for memory + allocation leaks, using :func:`sys.getallocatedblocks()`. -- Issue #12950: Fix passing file descriptors in multiprocessing, under - OpenIndiana/Illumos. +- Issue #16559: Add more tests for the json module, including some from the + official test suite at json.org. Patch by Serhiy Storchaka. -- Issue #12764: Fix a crash in ctypes when the name of a Structure field is not - a string. +- Issue #16661: Fix the `os.getgrouplist()` test by not assuming that it gives + the same output as :command:`id -G`. -- Issue #11241: subclasses of ctypes.Array can now be subclassed. +- Issue #16115: Add some tests for the executable argument to + subprocess.Popen(). Initial patch by Kushal Das. -- Issue #9651: Fix a crash when ctypes.create_string_buffer(0) was passed to - some functions like file.write(). +- Issue #16126: PyErr_Format format mismatch in _testcapimodule.c. + Patch by Serhiy Storchaka. -- Issue #10309: Define _GNU_SOURCE so that mremap() gets the proper - signature. Without this, architectures where sizeof void* != sizeof int are - broken. Patch given by Hallvard B Furuseth. +- Issue #15304: Fix warning message when `os.chdir()` fails inside + `test.support.temp_cwd()`. Patch by Chris Jerdonek. -- Issue #12051: Fix segfault in json.dumps() while encoding highly-nested - objects using the C accelerations. +- Issue #15802: Fix test logic in `TestMaildir.test_create_tmp()`. Patch by + Serhiy Storchaka. -- Issue #12017: Fix segfault in json.loads() while decoding highly-nested - objects using the C accelerations. +- Issue #15557: Added a test suite for the webbrowser module, thanks to Anton + Barkovsky. -- Issue #1838: Prevent segfault in ctypes, when _as_parameter_ on a class is set - to an instance of the class. +- Issue #16698: Skip posix test_getgroups when built with OS X + deployment target prior to 10.6. -Tests +Build ----- -- Issue #13125: Silence spurious test_lib2to3 output when in non-verbose mode. - Patch by Mikhail Novikov. - -- Issue #13447: Add a test file to host regression tests for bugs in the - scripts found in the Tools directory. - -- Issue #10881: Fix test_site failure with OS X framework builds. - -- Issue #13901: Prevent test_distutils failures on OS X with --enable-shared. +- Issue #16067: Add description into MSI file to replace installer's + temporary name. -- Issue #13862: Fix spurious failure in test_zlib due to runtime/compile time - minor versions not matching. +- Issue #18257: Fix readlink usage in python-config. Install the python + version again on Darwin. -- Issue #12804: Fix test_socket and test_urllib2net failures when running tests - on a system without internet access. +- Issue #18481: Add C coverage reporting with gcov and lcov. A new make target + "coverage-report" creates an instrumented Python build, runs unit tests + and creates a HTML. The report can be updated with "make coverage-lcov". -- Issue #13726: Fix the ambiguous -S flag in regrtest. It is -o/--slow for slow - tests. +- Issue #17845: Clarified the message printed when some module are not built. -- Issue #11659: Fix ResourceWarning in test_subprocess introduced by #11459. - Patch by Ben Hayden. +- Issue #18256: Compilation fix for recent AIX releases. Patch by + David Edelsohn. -- Issue #11577: fix ResourceWarning triggered by improved binhex test coverage +- Issue #17547: In configure, explicitly pass -Wformat for the benefit for GCC + 4.8. -- Issue #11509: Significantly increase test coverage of fileinput. - Patch by Denver Coneybeare at PyCon 2011 Sprints. +- Issue #15172: Document NASM 2.10+ as requirement for building OpenSSL 1.0.1 + on Windows. -- Issue #11689: Fix a variable scoping error in an sqlite3 test +- Issue #17591: Use lowercase filenames when including Windows header files. + Patch by Roumen Petrov. -- Issue #13786: Remove unimplemented 'trace' long option from regrtest.py. +- Issue #17550: Fix the --enable-profiling configure switch. -- Issue #13725: Fix regrtest to recognize the documented -d flag. - Patch by Erno Tukia. +- Issue #17425: Build with openssl 1.0.1d on Windows. -- Issue #13304: Skip test case if user site-packages disabled (-s or - PYTHONNOUSERSITE). (Patch by Carl Meyer) +- Issue #16754: Fix the incorrect shared library extension on linux. Introduce + two makefile macros SHLIB_SUFFIX and EXT_SUFFIX. SO now has the value of + SHLIB_SUFFIX again (as in 2.x and 3.1). The SO macro is removed in 3.4. -- Issue #5661: Add a test for ECONNRESET/EPIPE handling to test_asyncore. Patch - by Xavier de Gaye. +- Issue #5033: Fix building of the sqlite3 extension module when the + SQLite library version has "beta" in it. Patch by Andreas Pelme. -- Issue #13218: Fix test_ssl failures on Debian/Ubuntu. +- Issue #17228: Fix building without pymalloc. -- Re-enable lib2to3's test_parser.py tests, though with an expected failure - (see issue 13125). +- Issue #3718: Use AC_ARG_VAR to set MACHDEP in configure.ac. -- Issue #12656: Add tests for IPv6 and Unix sockets to test_asyncore. +- Issue #16235: Implement python-config as a shell script. -- Issue #6484: Add unit tests for mailcap module (patch by Gregory Nofi) +- Issue #16769: Remove outdated Visual Studio projects. -- Issue #11651: Improve the Makefile test targets to run more of the test suite - more quickly. The --multiprocess option is now enabled by default, reducing - the amount of time needed to run the tests. "make test" and "make quicktest" - now include some resource-intensive tests, but no longer run the test suite - twice to check for bugs in .pyc generation. Tools/scripts/run_test.py provides - an easy platform-independent way to run test suite with sensible defaults. +- Issue #17031: Fix running regen in cross builds. -- Issue #12331: The test suite for the packaging module can now run from an - installed Python. +- Issue #3754: fix typo in pthread AC_CACHE_VAL. -- Issue #12331: The test suite for lib2to3 can now run from an installed - Python. +- Issue #15484: Fix _PYTHON_PROJECT_BASE for srcdir != builddir builds; + use _PYTHON_PROJECT_BASE in distutils/sysconfig.py. -- Issue #12626: In regrtest, allow to filter tests using a glob filter - with the ``-m`` (or ``--match``) option. This works with all test cases - using the unittest module. This is useful with long test suites - such as test_io or test_subprocess. +- Drop support for Windows 2000 (changeset e52df05b496a). -- Issue #12624: It is now possible to fail after the first failure when - running in verbose mode (``-v`` or ``-W``), by using the ``--failfast`` - (or ``-G``) option to regrtest. This is useful with long test suites - such as test_io or test_subprocess. +- Issue #17029: Let h2py search the multiarch system include directory. -- Issue #12587: Correct faulty test file and reference in test_tokenize. - (Patch by Robert Xiao) +- Issue #16953: Fix socket module compilation on platforms with + HAVE_BROKEN_POLL. Patch by Jeffrey Armstrong. -- Issue #12573: Add resource checks for dangling Thread and Process objects. +- Issue #16320: Remove redundant Makefile dependencies for strings and bytes. -- Issue #12549: Correct test_platform to not fail when OS X returns 'x86_64' - as the processor type on some Mac systems. +- Cross compiling needs host and build settings. configure no longer + creates a broken PYTHON_FOR_BUILD variable when --build is missing. -- Skip network tests when getaddrinfo() returns EAI_AGAIN, meaning a temporary - failure in name resolution. +- Fix cross compiling issue in setup.py, ensure that lib_dirs and inc_dirs are + defined in cross compiling mode, too. -- Issue #11812: Solve transient socket failure to connect to 'localhost' - in test_telnetlib.py. +- Issue #16836: Enable IPv6 support even if IPv6 is disabled on the build host. -- Solved a potential deadlock in test_telnetlib.py. Related to issue #11812. +- Issue #16593: Have BSD 'make -s' do the right thing, thanks to Daniel Shahaf -- Avoid failing in test_robotparser when mueblesmoraleda.com is flaky and - an overzealous DNS service (e.g. OpenDNS) redirects to a placeholder - Web site. +- Issue #16262: fix out-of-src-tree builds, if mercurial is not installed. -- Avoid failing in test_urllibnet.test_bad_address when some overzealous - DNS service (e.g. OpenDNS) resolves a non-existent domain name. The test - is now skipped instead. +- Issue #15298: ensure _sysconfigdata is generated in build directory, not + source directory. -- Issue #12440: When testing whether some bits in SSLContext.options can be - reset, check the version of the OpenSSL headers Python was compiled against, - rather than the runtime version of the OpenSSL library. +- Issue #15833: Fix a regression in 3.3 that resulted in exceptions being + raised if importlib failed to write byte-compiled files. This affected + attempts to build Python out-of-tree from a read-only source directory. -- Issue #11512: Add a test suite for the cgitb module. Patch by Robbie Clemons. +- Issue #15923: Fix a mistake in ``asdl_c.py`` that resulted in a TypeError + after 2801bf875a24 (see #15801). -- Issue #12497: Install test/data to prevent failures of the various codecmaps - tests. +- Issue #16135: Remove OS/2 support. -- Issue #12496: Install test/capath directory to prevent test_connect_capath - testcase failure in test_ssl. +- Issue #15819: Make sure we can build Python out-of-tree from a read-only + source directory. (Somewhat related to issue #9860.) -- Issue #12469: Run wakeup and pending signal tests in a subprocess to run the - test in a fresh process with only one thread and to not change signal - handling of the parent process. +- Issue #15587: Enable Tk high-resolution text rendering on Macs with + Retina displays. Applies to Tkinter apps, such as IDLE, on OS X + framework builds linked with Cocoa Tk 8.5. -- Issue #8716: Avoid crashes caused by Aqua Tk on OSX when attempting to run - test_tk or test_ttk_guionly under a username that is not currently logged - in to the console windowserver (as may be the case under buildbot or ssh). +- Issue #17161: make install now also installs a python3 man page. -- Issue #12407: Explicitly skip test_capi.EmbeddingTest under Windows. +C-API +----- -- Issue #12400: regrtest -W doesn't rerun the tests twice anymore, but captures - the output and displays it on failure instead. regrtest -v doesn't print the - error twice anymore if there is only one error. +- Issue #18351: Fix various issues in a function in importlib provided to help + PyImport_ExecCodeModuleWithPathnames() (and thus by extension + PyImport_ExecCodeModule() and PyImport_ExecCodeModuleEx()). -- Issue #12141: Install copies of template C module file so that - test_build_ext of test_distutils and test_command_build_ext of - test_packaging are no longer silently skipped when - run outside of a build directory. +- 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. -- Issue #8746: Add additional tests for os.chflags() and os.lchflags(). - Patch by Garrett Cooper. +- Issue #17206: Py_CLEAR(), Py_DECREF(), Py_XINCREF() and Py_XDECREF() now + expand their arguments once instead of multiple times. Patch written by Illia + Polosukhin. -- Issue #10736: Fix test_ttk test_widgets failures with Cocoa Tk 8.5.9 - 2.8 + on Mac OS X. (Patch by Ronald Oussoren) +- Issue #17522: Add the PyGILState_Check() API. -- Issue #12057: Add tests for ISO 2022 codecs (iso2022_jp, iso2022_jp_2, - iso2022_kr). +- Issue #17327: Add PyDict_SetDefault. -- Issue #12096: Fix a race condition in test_threading.test_waitfor(). Patch - written by Charles-François Natali. +- Issue #16881: Fix Py_ARRAY_LENGTH macro for GCC < 3.1. -- Issue #11614: import __hello__ prints "Hello World!". Patch written by - Andreas Stührk. +- Issue #16505: Remove unused Py_TPFLAGS_INT_SUBCLASS. -- Issue #5723: Improve json tests to be executed with and without accelerations. +- Issue #16086: PyTypeObject.tp_flags and PyType_Spec.flags are now unsigned + (unsigned long and unsigned int) to avoid an undefined behaviour with + Py_TPFLAGS_TYPE_SUBCLASS ((1 << 31). PyType_GetFlags() result type is + now unsigned too (unsigned long, instead of long). -- Issue #12041: Make test_wait3 more robust. +- Issue #16166: Add PY_LITTLE_ENDIAN and PY_BIG_ENDIAN macros and unified + endianness detection and handling. -- Issue #11873: Change regex in test_compileall to fix occasional failures when - when the randomly generated temporary path happened to match the regex. +Documentation +------------- -- Issue #11958: Fix FTP tests for IPv6, bind to "::1" instead of "localhost". - Patch written by Charles-Francois Natali. +- 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 #8407, #11859: Fix tests of test_io using threads and an alarm: use - pthread_sigmask() to ensure that the SIGALRM signal is received by the main - thread. +- Issue #17701: Improving strftime documentation. -- Issue #11811: Factor out detection of IPv6 support on the current host - and make it available as ``test.support.IPV6_ENABLED``. Patch by - Charles-François Natali. +- Issue #18440: Clarify that `hash()` can truncate the value returned from an + object's custom `__hash__()` method. -- Issue #10914: Add a minimal embedding test to test_capi. +- Issue #17844: Add links to encoders and decoders for bytes-to-bytes codecs. -- Issue #11223: Skip test_lock_acquire_interruption() and - test_rlock_acquire_interruption() of test_threadsignals if a thread lock is - implemented using a POSIX mutex and a POSIX condition variable. A POSIX - condition variable cannot be interrupted by a signal (e.g. on Linux, the - futex system call is restarted). +- Issue #14097: improve the "introduction" page of the tutorial. -- Issue #11790: Fix sporadic failures in test_multiprocessing.WithProcessesTestCondition. +- Issue #17977: The documentation for the cadefault argument's default value + in urllib.request.urlopen() is fixed to match the code. -- Fix possible "file already exists" error when running the tests in parallel. +- Issue #6696: add documentation for the Profile objects, and improve + profile/cProfile docs. Patch by Tom Pinckney. -- Issue #11719: Fix message about unexpected test_msilib skip on non-Windows - platforms. Patch by Nadeem Vawda. +- Issue #15940: Specify effect of locale on time functions. -- Issue #11727: Add a --timeout option to regrtest: if a test takes more than - TIMEOUT seconds, dumps the traceback of all threads and exits. +- Issue 17538: Document XML vulnerabilties -- Issue #11653: fix -W with -j in regrtest. +- Issue #16642: sched.scheduler timefunc initial default is time.monotonic. + Patch by Ramchandra Apte -- The email test suite now lives in the Lib/test/test_email package. The test - harness code has also been modernized to allow use of new unittest features. +- Issue #17047: remove doubled words in docs and docstrings + reported by Serhiy Storchaka and Matthew Barnett. -- regrtest now discovers test packages as well as test modules. +- Issue #15465: Document the versioning macros in the C API docs rather than + the standard library docs. Patch by Kushal Das. -- Issue #11577: improve test coverage of binhex.py. Patch by Arkady Koplyarov. +- Issue #16406: Combine the pages for uploading and registering to PyPI. -- New test_crashers added to exercise the scripts in the Lib/test/crashers - directory and confirm they fail as expected +- Issue #16403: Document how distutils uses the maintainer field in + PKG-INFO. Patch by Jyrki Pulliainen. -- Issue #11578: added test for the timeit module. Patch by Michael Henry. +- Issue #16695: Document how glob handles filenames starting with a + dot. Initial patch by Jyrki Pulliainen. -- Issue #11503: improve test coverage of posixpath.py. Patch by Evan Dandrea. +- Issue #8890: Stop advertising an insecure practice by replacing uses + of the /tmp directory with better alternatives in the documentation. + Patch by Geoff Wilson. -- Issue #11505: improves test coverage of string.py, increases granularity of - string.Formatter tests. Initial patch by Alicia Arlen. +- Issue #17203: add long option names to unittest discovery docs. -- Issue #11548: Improve test coverage of the shutil module. Patch by - Evan Dandrea. +- Issue #13094: add "Why do lambdas defined in a loop with different values + all return the same result?" programming FAQ. -- Issue #11554: Reactivated test_email_codecs. +- Issue #14901: Update portions of the Windows FAQ. + Patch by Ashish Nitin Patil. -- Issue #11505: improves test coverage of string.py. Patch by Alicia - Arlen +- Issue #16267: Better document the 3.3+ approach to combining + @abstractmethod with @staticmethod, @classmethod and @property -- Issue #11490: test_subprocess.test_leaking_fds_on_error no longer gives a - false positive if the last directory in the path is inaccessible. +- Issue #15209: Clarify exception chaining description in exceptions module + documentation -- Issue #11223: Fix test_threadsignals to fail, not hang, when the - non-semaphore implementation of locks is used under POSIX. +- Issue #15990: Improve argument/parameter documentation. -- Issue #10911: Add tests on CGI with non-ASCII characters. Patch written by - Pierre Quentel. +- Issue #16209: Move the documentation for the str built-in function to a new + str class entry in the "Text Sequence Type" section. -- Issue #9931: Fix hangs in GUI tests under Windows in certain conditions. - Patch by Hirokazu Yamamoto. +- Issue #13538: Improve str() and object.__str__() documentation. -- Issue #10512: Properly close sockets under test.test_cgi. +- Issue #16489: Make it clearer that importlib.find_loader() needs parent + packages to be explicitly imported. -- Issue #10992: Make tests pass under coverage. +- Issue #16400: Update the description of which versions of a given package + PyPI displays. -- Issue #10826: Prevent sporadic failure in test_subprocess on Solaris due - to open door files. +- Issue #15677: Document that zlib and gzip accept a compression level of 0 to + mean 'no compression'. Patch by Brian Brazil. -- Issue #10990: Prevent tests from clobbering a set trace function. +- Issue #16197: Update winreg docstrings and documentation to match code. + Patch by Zachary Ware. -C-API ------ +- Issue #8040: added a version switcher to the documentation. Patch by + Yury Selivanov. -- Issue #13452: PyUnicode_EncodeDecimal() doesn't support error handlers - different than "strict" anymore. The caller was unable to compute the - size of the output buffer: it depends on the error handler. +- Issue #16241: Document -X faulthandler command line option. + Patch by Marek Šuppa. -- Issue #13560: Add PyUnicode_DecodeLocale(), PyUnicode_DecodeLocaleAndSize() - and PyUnicode_EncodeLocale() functions to the C API to decode/encode from/to - the current locale encoding. +- Additional comments and some style changes in the concurrent.futures URL + retrieval example -- Issue #10831: PyUnicode_FromFormat() supports %li, %lli and %zi formats. +- Issue #16115: Improve subprocess.Popen() documentation around args, shell, + and executable arguments. -- Issue #11246: Fix PyUnicode_FromFormat("%V") to decode the byte string from - UTF-8 (with replace error handler) instead of ISO-8859-1 (in strict mode). - Patch written by Ray Allen. +- Issue #13498: Clarify docs of os.makedirs()'s exist_ok argument. Done with + great native-speaker help from R. David Murray. -- Issue #10830: Fix PyUnicode_FromFormatV("%c") for non-BMP characters on - narrow build. +- Issue #15533: Clarify docs and add tests for `subprocess.Popen()`'s cwd + argument. -- Add PyObject_GenericGetDict and PyObject_GeneriSetDict. They are generic - implementations for the getter and setter of a ``__dict__`` descriptor of C - types. +- Issue #15979: Improve timeit documentation. -- Issue #13727: Add 3 macros to access PyDateTime_Delta members: - PyDateTime_DELTA_GET_DAYS, PyDateTime_DELTA_GET_SECONDS, - PyDateTime_DELTA_GET_MICROSECONDS. +- Issue #16036: Improve documentation of built-in `int()`'s signature and + arguments. -- Issue #10542: Add 4 macros to work with surrogates: Py_UNICODE_IS_SURROGATE, - Py_UNICODE_IS_HIGH_SURROGATE, Py_UNICODE_IS_LOW_SURROGATE, - Py_UNICODE_JOIN_SURROGATES. +- Issue #15935: Clarification of `argparse` docs, re: add_argument() type and + default arguments. Patch contributed by Chris Jerdonek. -- Issue #12724: Add Py_RETURN_NOTIMPLEMENTED macro for returning NotImplemented. +- Issue #11964: Document a change in v3.2 to the behavior of the indent + parameter of json encoding operations. -- PY_PATCHLEVEL_REVISION has been removed, since it's meaningless with - Mercurial. +- Issue #15116: Remove references to appscript as it is no longer being + supported. -- Issue #12173: The first argument of PyImport_ImportModuleLevel is now `const - char *` instead of `char *`. +Tools/Demos +----------- -- Issue #12380: PyArg_ParseTuple now accepts a bytearray for the 'c' format. +- Issue #18817: Fix a resource warning in Lib/aifc.py demo. Patch by + Vajrasky Kok. -Documentation -------------- +- Issue #18439: Make patchcheck work on Windows for ACKS, NEWS. -- Issue #13989: Document that GzipFile does not support text mode, and give a - more helpful error message when opened with an invalid mode string. +- Issue #18448: Fix a typo in Tools/demo/eiffel.py. -- Issue #13921: Undocument and clean up sqlite3.OptimizedUnicode, - which is obsolete in Python 3.x. It's now aliased to str for - backwards compatibility. +- Issue #18457: Fixed saving of formulas and complex numbers in + Tools/demo/ss1.py. -- Issue #12102: Document that buffered files must be flushed before being used - with mmap. Patch by Steffen Daode Nurpmeso. +- Issue #18449: Make Tools/demo/ss1.py work again on Python 3. Patch by + Févry Thibault. -- Issue #8982: Improve the documentation for the argparse Namespace object. +- Issue #12990: The "Python Launcher" on OSX could not launch python scripts + that have paths that include wide characters. -- Issue #9343: Document that argparse parent parsers must be configured before - their children. +- Issue #15239: Make mkstringprep.py work again on Python 3. -- Issue #13498: Clarify docs of os.makedirs()'s exist_ok argument. Done with - great native-speaker help from R. David Murray. +- Issue #17028: Allowed Python arguments to be supplied to the Windows + launcher. -- Issues #13491 and #13995: Fix many errors in sqlite3 documentation. - Initial patch for #13491 by Johannes Vogel. +- Issue #17156: pygettext.py now detects the encoding of source files and + correctly writes and escapes non-ascii characters. -- Issue #13402: Document absoluteness of sys.executable. +- Issue #15539: Fix a number of bugs in Tools/scripts/pindent.py. Now + pindent.py works with a "with" statement. pindent.py no longer produces + improper indentation. pindent.py now works with continued lines broken after + "class" or "def" keywords and with continuations at the start of line. -- Issue #13883: PYTHONCASEOK also works on OS X. +- Issue #11797: Add a 2to3 fixer that maps reload() to imp.reload(). -- Issue #9021: Add an introduction to the copy module documentation. +- Issue #10966: Remove the concept of unexpected skipped tests. -- Issue #6005: Examples in the socket library documentation use sendall, where - relevant, instead send method. +- Issue #9893: Removed the Misc/Vim directory. -- Issue #12798: Updated the mimetypes documentation. +- Removed the Misc/TextMate directory. -- Issue #12949: Document the kwonlyargcount argument for the PyCode_New - C API function. +- Issue #16245: Add the Tools/scripts/parse_html5_entities.py script to parse + the list of HTML5 entities and update the html.entities.html5 dictionary. -- Issue #13513: Fix io.IOBase documentation to correctly link to the - io.IOBase.readline method instead of the readline module. +- Issue #15378: Fix Tools/unicode/comparecodecs.py. Patch by Serhiy Storchaka. -- Issue #13237: Reorganise subprocess documentation to emphasise convenience - functions and the most commonly needed arguments to Popen. +- Issue #16549: Make json.tool work again on Python 3 and add tests. + Initial patch by Berker Peksag and Serhiy Storchaka. -- Issue #13141: Demonstrate recommended style for socketserver examples. +- Issue #13301: use ast.literal_eval() instead of eval() in Tools/i18n/msgfmt.py + Patch by Serhiy Storchaka. -- Issue #11818: Fix tempfile examples for Python 3. +Windows +------- +- Issue #18569: The installer now adds .py to the PATHEXT variable when extensions + are registered. Patch by Paul Moore. **(For information about older versions, consult the HISTORY file.)** diff --git a/Misc/README b/Misc/README index e7780a2f315d..ddb8f3f97590 100644 --- a/Misc/README +++ b/Misc/README @@ -21,7 +21,6 @@ README The file you're reading now README.AIX Information about using Python on AIX README.coverity Information about running Coverity's Prevent on Python README.valgrind Information for Valgrind users, see valgrind-python.supp -RPM (Old) tools to build RPMs SpecialBuilds.txt Describes extra symbols you can set for debug builds svnmap.txt Map of old SVN revs and branches to hg changeset ids valgrind-python.supp Valgrind suppression file, see README.valgrind diff --git a/Misc/RPM/README b/Misc/RPM/README deleted file mode 100644 index d883c95e85b9..000000000000 --- a/Misc/RPM/README +++ /dev/null @@ -1,33 +0,0 @@ -This directory contains support file used to build RPM releases of -Python. Its contents are maintained by Sean Reifschneider -. - -If you wish to build RPMs from the base Python release tar-file, note -that you will have to download the -"doc//html-.tar.bz2" -file from python.org and place it into your "SOURCES" directory for -the build to complete. This is the same directory that you place the -Python-2.3.1 release tar-file in. You can then use the ".spec" file in -this directory to build RPMs. - -You may also wish to pursue RPMs provided by distribution makers to see if -they have one suitable for your uses. If, for example, you just want a -slightly newer version of Python than what the distro provides, you could -pick up the closest SRPM your distro provides, and then modify it to -the newer version, and build that. It may be as simple as just changing -the "version" information in the spec file (or it may require fixing -patches). - -NOTE: I am *NOT* recommending just using the binary RPM, and never do an -install with "--force" or "--nodeps". - -Also worth pursuing may be newer versions provided by similar distros. For -example, a Python 3 SRPM from Fedora may be a good baseline to try building -on CentOS. - -Many newer SRPMs won't install on older distros because of format changes. -You can manually extract these SRPMS with: - - mkdir foo - cd foo - rpm2cpio <../python3-*.src.rpm | cpio -ivd diff --git a/Misc/RPM/python-3.4.spec b/Misc/RPM/python-3.4.spec deleted file mode 100644 index 16e009c58c06..000000000000 --- a/Misc/RPM/python-3.4.spec +++ /dev/null @@ -1,389 +0,0 @@ -########################## -# User-modifiable configs -########################## - -# Is the resulting package and the installed binary named "python" or -# "python2"? -#WARNING: Commenting out doesn't work. Last line is what's used. -%define config_binsuffix none -%define config_binsuffix 2.6 - -# Build tkinter? "auto" enables it if /usr/bin/wish exists. -#WARNING: Commenting out doesn't work. Last line is what's used. -%define config_tkinter no -%define config_tkinter yes -%define config_tkinter auto - -# Use pymalloc? The last line (commented or not) determines wether -# pymalloc is used. -#WARNING: Commenting out doesn't work. Last line is what's used. -%define config_pymalloc no -%define config_pymalloc yes - -# Enable IPV6? -#WARNING: Commenting out doesn't work. Last line is what's used. -%define config_ipv6 yes -%define config_ipv6 no - -# Build shared libraries or .a library? -#WARNING: Commenting out doesn't work. Last line is what's used. -%define config_sharedlib no -%define config_sharedlib yes - -# Location of the HTML directory. -%define config_htmldir /var/www/html/python - -################################# -# End of user-modifiable configs -################################# - -%define name python -#--start constants-- -%define version 3.4.0b1 -%define libvers 3.4 -#--end constants-- -%define release 1pydotorg -%define __prefix /usr - -# kludge to get around rpm define weirdness -%define ipv6 %(if [ "%{config_ipv6}" = yes ]; then echo --enable-ipv6; else echo --disable-ipv6; fi) -%define pymalloc %(if [ "%{config_pymalloc}" = yes ]; then echo --with-pymalloc; else echo --without-pymalloc; fi) -%define binsuffix %(if [ "%{config_binsuffix}" = none ]; then echo ; else echo "%{config_binsuffix}"; fi) -%define include_tkinter %(if [ \\( "%{config_tkinter}" = auto -a -f /usr/bin/wish \\) -o "%{config_tkinter}" = yes ]; then echo 1; else echo 0; fi) -%define libdirname %(( uname -m | egrep -q '_64$' && [ -d /usr/lib64 ] && echo lib64 ) || echo lib) -%define sharedlib %(if [ "%{config_sharedlib}" = yes ]; then echo --enable-shared; else echo ; fi) -%define include_sharedlib %(if [ "%{config_sharedlib}" = yes ]; then echo 1; else echo 0; fi) - -# detect if documentation is available -%define include_docs %(if [ -f "%{_sourcedir}/html-%{version}.tar.bz2" ]; then echo 1; else echo 0; fi) - -Summary: An interpreted, interactive, object-oriented programming language. -Name: %{name}%{binsuffix} -Version: %{version} -Release: %{release} -License: PSF -Group: Development/Languages -Source: Python-%{version}.tar.bz2 -%if %{include_docs} -Source1: html-%{version}.tar.bz2 -%endif -BuildRoot: %{_tmppath}/%{name}-%{version}-root -BuildPrereq: expat-devel -BuildPrereq: db4-devel -BuildPrereq: gdbm-devel -BuildPrereq: sqlite-devel -Prefix: %{__prefix} -Packager: Sean Reifschneider - -%description -Python is an interpreted, interactive, object-oriented programming -language. It incorporates modules, exceptions, dynamic typing, very high -level dynamic data types, and classes. Python combines remarkable power -with very clear syntax. It has interfaces to many system calls and -libraries, as well as to various window systems, and is extensible in C or -C++. It is also usable as an extension language for applications that need -a programmable interface. Finally, Python is portable: it runs on many -brands of UNIX, on PCs under Windows, MS-DOS, and on the Mac. - -%package devel -Summary: The libraries and header files needed for Python extension development. -Prereq: python%{binsuffix} = %{PACKAGE_VERSION} -Group: Development/Libraries - -%description devel -The Python programming language's interpreter can be extended with -dynamically loaded extensions and can be embedded in other programs. -This package contains the header files and libraries needed to do -these types of tasks. - -Install python-devel if you want to develop Python extensions. The -python package will also need to be installed. You'll probably also -want to install the python-docs package, which contains Python -documentation. - -%if %{include_tkinter} -%package tkinter -Summary: A graphical user interface for the Python scripting language. -Group: Development/Languages -Prereq: python%{binsuffix} = %{PACKAGE_VERSION}-%{release} - -%description tkinter -The Tkinter (Tk interface) program is an graphical user interface for -the Python scripting language. - -You should install the tkinter package if you'd like to use a graphical -user interface for Python programming. -%endif - -%package tools -Summary: A collection of development tools included with Python. -Group: Development/Tools -Prereq: python%{binsuffix} = %{PACKAGE_VERSION}-%{release} - -%description tools -The Python package includes several development tools that are used -to build python programs. This package contains a selection of those -tools, including the IDLE Python IDE. - -Install python-tools if you want to use these tools to develop -Python programs. You will also need to install the python and -tkinter packages. - -%if %{include_docs} -%package docs -Summary: Python-related documentation. -Group: Development/Documentation - -%description docs -Documentation relating to the Python programming language in HTML and info -formats. -%endif - -%changelog -* Mon Dec 20 2004 Sean Reifschneider [2.4-2pydotorg] -- Changing the idle wrapper so that it passes arguments to idle. - -* Tue Oct 19 2004 Sean Reifschneider [2.4b1-1pydotorg] -- Updating to 2.4. - -* Thu Jul 22 2004 Sean Reifschneider [2.3.4-3pydotorg] -- Paul Tiemann fixes for %{prefix}. -- Adding permission changes for directory as suggested by reimeika.ca -- Adding code to detect when it should be using lib64. -- Adding a define for the location of /var/www/html for docs. - -* Thu May 27 2004 Sean Reifschneider [2.3.4-2pydotorg] -- Including changes from Ian Holsman to build under Red Hat 7.3. -- Fixing some problems with the /usr/local path change. - -* Sat Mar 27 2004 Sean Reifschneider [2.3.2-3pydotorg] -- Being more agressive about finding the paths to fix for - #!/usr/local/bin/python. - -* Sat Feb 07 2004 Sean Reifschneider [2.3.3-2pydotorg] -- Adding code to remove "#!/usr/local/bin/python" from particular files and - causing the RPM build to terminate if there are any unexpected files - which have that line in them. - -* Mon Oct 13 2003 Sean Reifschneider [2.3.2-1pydotorg] -- Adding code to detect wether documentation is available to build. - -* Fri Sep 19 2003 Sean Reifschneider [2.3.1-1pydotorg] -- Updating to the 2.3.1 release. - -* Mon Feb 24 2003 Sean Reifschneider [2.3b1-1pydotorg] -- Updating to 2.3b1 release. - -* Mon Feb 17 2003 Sean Reifschneider [2.3a1-1] -- Updating to 2.3 release. - -* Sun Dec 23 2001 Sean Reifschneider -[Release 2.2-2] -- Added -docs package. -- Added "auto" config_tkinter setting which only enables tk if - /usr/bin/wish exists. - -* Sat Dec 22 2001 Sean Reifschneider -[Release 2.2-1] -- Updated to 2.2. -- Changed the extension to "2" from "2.2". - -* Tue Nov 18 2001 Sean Reifschneider -[Release 2.2c1-1] -- Updated to 2.2c1. - -* Thu Nov 1 2001 Sean Reifschneider -[Release 2.2b1-3] -- Changed the way the sed for fixing the #! in pydoc works. - -* Wed Oct 24 2001 Sean Reifschneider -[Release 2.2b1-2] -- Fixed missing "email" package, thanks to anonymous report on sourceforge. -- Fixed missing "compiler" package. - -* Mon Oct 22 2001 Sean Reifschneider -[Release 2.2b1-1] -- Updated to 2.2b1. - -* Mon Oct 9 2001 Sean Reifschneider -[Release 2.2a4-4] -- otto@balinor.mat.unimi.it mentioned that the license file is missing. - -* Sun Sep 30 2001 Sean Reifschneider -[Release 2.2a4-3] -- Ignacio Vazquez-Abrams pointed out that I had a spruious double-quote in - the spec files. Thanks. - -* Wed Jul 25 2001 Sean Reifschneider -[Release 2.2a1-1] -- Updated to 2.2a1 release. -- Changed idle and pydoc to use binsuffix macro - -####### -# PREP -####### -%prep -%setup -n Python-%{version} - -######## -# BUILD -######## -%build -echo "Setting for ipv6: %{ipv6}" -echo "Setting for pymalloc: %{pymalloc}" -echo "Setting for binsuffix: %{binsuffix}" -echo "Setting for include_tkinter: %{include_tkinter}" -echo "Setting for libdirname: %{libdirname}" -echo "Setting for sharedlib: %{sharedlib}" -echo "Setting for include_sharedlib: %{include_sharedlib}" -./configure --enable-unicode=ucs4 %{sharedlib} %{ipv6} %{pymalloc} --prefix=%{__prefix} -make - -########## -# INSTALL -########## -%install -# set the install path -echo '[install_scripts]' >setup.cfg -echo 'install_dir='"${RPM_BUILD_ROOT}%{__prefix}/bin" >>setup.cfg - -[ -d "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT -mkdir -p $RPM_BUILD_ROOT%{__prefix}/%{libdirname}/python%{libvers}/lib-dynload -make prefix=$RPM_BUILD_ROOT%{__prefix} install - -# REPLACE PATH IN PYDOC -if [ ! -z "%{binsuffix}" ] -then - ( - cd $RPM_BUILD_ROOT%{__prefix}/bin - mv pydoc pydoc.old - sed 's|#!.*|#!%{__prefix}/bin/env python'%{binsuffix}'|' \ - pydoc.old >pydoc - chmod 755 pydoc - rm -f pydoc.old - ) -fi - -# add the binsuffix -if [ ! -z "%{binsuffix}" ] -then - rm -f $RPM_BUILD_ROOT%{__prefix}/bin/python[0-9a-zA-Z]* - ( cd $RPM_BUILD_ROOT%{__prefix}/bin; - for file in *; do mv "$file" "$file"%{binsuffix}; done ) - ( cd $RPM_BUILD_ROOT%{_mandir}/man1; mv python.1 python%{binsuffix}.1 ) -fi - -######## -# Tools -echo '#!%{__prefix}/bin/env python%{binsuffix}' >${RPM_BUILD_ROOT}%{__prefix}/bin/idle%{binsuffix} -echo 'import os, sys' >>${RPM_BUILD_ROOT}%{__prefix}/bin/idle%{binsuffix} -echo 'os.execvp("%{__prefix}/bin/python%{binsuffix}", ["%{__prefix}/bin/python%{binsuffix}", "%{__prefix}/lib/python%{libvers}/idlelib/idle.py"] + sys.argv[1:])' >>${RPM_BUILD_ROOT}%{__prefix}/bin/idle%{binsuffix} -echo 'print "Failed to exec Idle"' >>${RPM_BUILD_ROOT}%{__prefix}/bin/idle%{binsuffix} -echo 'sys.exit(1)' >>${RPM_BUILD_ROOT}%{__prefix}/bin/idle%{binsuffix} -chmod 755 $RPM_BUILD_ROOT%{__prefix}/bin/idle%{binsuffix} -cp -a Tools $RPM_BUILD_ROOT%{__prefix}/%{libdirname}/python%{libvers} - -# MAKE FILE LISTS -rm -f mainpkg.files -find "$RPM_BUILD_ROOT""%{__prefix}"/%{libdirname}/python%{libvers} -type f | - sed "s|^${RPM_BUILD_ROOT}|/|" | - grep -v -e '/python%{libvers}/config$' -e '_tkinter.so$' >mainpkg.files -find "$RPM_BUILD_ROOT""%{__prefix}"/bin -type f -o -type l | - sed "s|^${RPM_BUILD_ROOT}|/|" | - grep -v -e '/bin/2to3%{binsuffix}$' | - grep -v -e '/bin/pydoc%{binsuffix}$' | - grep -v -e '/bin/smtpd.py%{binsuffix}$' | - grep -v -e '/bin/idle%{binsuffix}$' >>mainpkg.files - -rm -f tools.files -find "$RPM_BUILD_ROOT""%{__prefix}"/%{libdirname}/python%{libvers}/idlelib \ - "$RPM_BUILD_ROOT""%{__prefix}"/%{libdirname}/python%{libvers}/Tools -type f | - sed "s|^${RPM_BUILD_ROOT}|/|" >tools.files -echo "%{__prefix}"/bin/2to3%{binsuffix} >>tools.files -echo "%{__prefix}"/bin/pydoc%{binsuffix} >>tools.files -echo "%{__prefix}"/bin/smtpd.py%{binsuffix} >>tools.files -echo "%{__prefix}"/bin/idle%{binsuffix} >>tools.files - -###### -# Docs -%if %{include_docs} -mkdir -p "$RPM_BUILD_ROOT"%{config_htmldir} -( - cd "$RPM_BUILD_ROOT"%{config_htmldir} - bunzip2 < %{SOURCE1} | tar x -) -%endif - -# fix the #! line in installed files -find "$RPM_BUILD_ROOT" -type f -print0 | - xargs -0 grep -l /usr/local/bin/python | while read file -do - FIXFILE="$file" - sed 's|^#!.*python|#!%{__prefix}/bin/env python'"%{binsuffix}"'|' \ - "$FIXFILE" >/tmp/fix-python-path.$$ - cat /tmp/fix-python-path.$$ >"$FIXFILE" - rm -f /tmp/fix-python-path.$$ -done - -# check to see if there are any straggling #! lines -find "$RPM_BUILD_ROOT" -type f | xargs egrep -n '^#! */usr/local/bin/python' \ - | grep ':1:#!' >/tmp/python-rpm-files.$$ || true -if [ -s /tmp/python-rpm-files.$$ ] -then - echo '*****************************************************' - cat /tmp/python-rpm-files.$$ - cat <<@EOF - ***************************************************** - There are still files referencing /usr/local/bin/python in the - install directory. They are listed above. Please fix the .spec - file and try again. If you are an end-user, you probably want - to report this to jafo-rpms@tummy.com as well. - ***************************************************** -@EOF - rm -f /tmp/python-rpm-files.$$ - exit 1 -fi -rm -f /tmp/python-rpm-files.$$ - -######## -# CLEAN -######## -%clean -[ -n "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf $RPM_BUILD_ROOT -rm -f mainpkg.files tools.files - -######## -# FILES -######## -%files -f mainpkg.files -%defattr(-,root,root) -%doc Misc/README Misc/cheatsheet Misc/Porting -%doc LICENSE Misc/ACKS Misc/HISTORY Misc/NEWS -%{_mandir}/man1/python%{binsuffix}.1* - -%attr(755,root,root) %dir %{__prefix}/include/python%{libvers} -%attr(755,root,root) %dir %{__prefix}/%{libdirname}/python%{libvers}/ -%if %{include_sharedlib} -%{__prefix}/%{libdirname}/libpython* -%endif - -%files devel -%defattr(-,root,root) -%{__prefix}/include/python%{libvers}/*.h -%{__prefix}/%{libdirname}/python%{libvers}/config - -%files -f tools.files tools -%defattr(-,root,root) - -%if %{include_tkinter} -%files tkinter -%defattr(-,root,root) -%{__prefix}/%{libdirname}/python%{libvers}/tkinter -%{__prefix}/%{libdirname}/python%{libvers}/lib-dynload/_tkinter.so* -%endif - -%if %{include_docs} -%files docs -%defattr(-,root,root) -%{config_htmldir}/* -%endif diff --git a/Misc/SpecialBuilds.txt b/Misc/SpecialBuilds.txt index 646ac2344cb3..732cb00178e7 100644 --- a/Misc/SpecialBuilds.txt +++ b/Misc/SpecialBuilds.txt @@ -13,12 +13,14 @@ Py_REF_DEBUG ------------ Turn on aggregate reference counting. This arranges that extern _Py_RefTotal -hold a count of all references, the sum of ob_refcnt across all objects. In a -debug-mode build, this is where the "8288" comes from in +hold a count of all references, the sum of ob_refcnt across all objects. +Passing ``-X showrefcount`` on the command line causes the interactive +interpreter to print the reference count total as well the number of memory +blocks allocated after each statement: >>> 23 23 - [8288 refs] + [8288 refs, 14332 blocks] >>> Note that if this count increases when you're not storing away new objects, diff --git a/Misc/coverity_model.c b/Misc/coverity_model.c index 57f3aeb11adf..421d54d4191d 100644 --- a/Misc/coverity_model.c +++ b/Misc/coverity_model.c @@ -85,7 +85,7 @@ PyObject *PyErr_SetFromErrnoWithFilename(PyObject *exc, const char *filename) } /* Python/fileutils.c */ -wchar_t *_Py_char2wchar(const char* arg, size_t *size) +wchar_t *Py_DecodeLocale(const char* arg, size_t *size) { wchar_t *w; __coverity_tainted_data_sink__(arg); diff --git a/Misc/python-config.in b/Misc/python-config.in index 0b9b5dc4413f..e13da7543c9f 100644 --- a/Misc/python-config.in +++ b/Misc/python-config.in @@ -47,8 +47,9 @@ for opt in opt_flags: print(' '.join(flags)) elif opt in ('--libs', '--ldflags'): - libs = getvar('LIBS').split() + getvar('SYSLIBS').split() - libs.append('-lpython' + pyver + sys.abiflags) + libs = ['-lpython' + pyver + sys.abiflags] + libs += getvar('LIBS').split() + libs += getvar('SYSLIBS').split() # add the prefix/lib/pythonX.Y/config dir, but only if there is no # shared library in prefix/lib/. if opt == '--ldflags': diff --git a/Misc/python-config.sh.in b/Misc/python-config.sh.in index f5a3dbebeaa2..64c81e5f74b2 100644 --- a/Misc/python-config.sh.in +++ b/Misc/python-config.sh.in @@ -40,7 +40,7 @@ LIBM="@LIBM@" LIBC="@LIBC@" SYSLIBS="$LIBM $LIBC" ABIFLAGS="@ABIFLAGS@" -LIBS="@LIBS@ $SYSLIBS -lpython${VERSION}${ABIFLAGS}" +LIBS="-lpython${VERSION}${ABIFLAGS} @LIBS@ $SYSLIBS" BASECFLAGS="@BASECFLAGS@" LDLIBRARY="@LDLIBRARY@" LINKFORSHARED="@LINKFORSHARED@" diff --git a/Misc/python.man b/Misc/python.man index 52aedee5bf0b..048a68a31963 100644 --- a/Misc/python.man +++ b/Misc/python.man @@ -384,11 +384,6 @@ You can also change the prompts and .I sys.ps2 in this file. -.IP PYTHONY2K -Set this to a non-empty string to cause the \fItime\fP module to -require dates specified as strings to include 4-digit years, otherwise -2-digit years are converted based on rules described in the \fItime\fP -module documentation. .IP PYTHONOPTIMIZE If this is set to a non-empty string it is equivalent to specifying the \fB\-O\fP option. If set to an integer, it is equivalent to diff --git a/Modules/README b/Modules/README new file mode 100644 index 000000000000..9b79f538892f --- /dev/null +++ b/Modules/README @@ -0,0 +1,2 @@ +Source files for standard library extension modules, +and former extension modules that are now builtin modules. diff --git a/Modules/Setup.config.in b/Modules/Setup.config.in index 5ac2404bf8a1..adac030b6a0a 100644 --- a/Modules/Setup.config.in +++ b/Modules/Setup.config.in @@ -7,7 +7,7 @@ @USE_THREAD_MODULE@_thread _threadmodule.c # The signal module -@USE_SIGNAL_MODULE@signal signalmodule.c +@USE_SIGNAL_MODULE@_signal signalmodule.c # The rest of the modules previously listed in this file are built # by the setup.py script in Python 2.1 and later. diff --git a/Modules/Setup.dist b/Modules/Setup.dist index 01fb85ffc368..ee84df466e89 100644 --- a/Modules/Setup.dist +++ b/Modules/Setup.dist @@ -118,6 +118,7 @@ _collections _collectionsmodule.c # Container types itertools itertoolsmodule.c # Functions creating iterators for efficient looping atexit atexitmodule.c # Register functions to be run at interpreter-shutdown _stat _stat.c # stat.h interface +time timemodule.c # time module # access to ISO C locale support _locale _localemodule.c # -lintl diff --git a/Modules/_bz2module.c b/Modules/_bz2module.c index fd05de0a27c6..4f2afda0976b 100644 --- a/Modules/_bz2module.c +++ b/Modules/_bz2module.c @@ -56,6 +56,8 @@ typedef struct { #endif } BZ2Decompressor; +static PyTypeObject BZ2Compressor_Type; +static PyTypeObject BZ2Decompressor_Type; /* Helper functions. */ @@ -186,7 +188,7 @@ compress(BZ2Compressor *c, char *data, size_t len, int action) if (action == BZ_FINISH && bzerror == BZ_STREAM_END) break; } - if (data_size != PyBytes_GET_SIZE(result)) + if (data_size != (size_t)PyBytes_GET_SIZE(result)) if (_PyBytes_Resize(&result, data_size) < 0) goto error; return result; @@ -196,44 +198,58 @@ compress(BZ2Compressor *c, char *data, size_t len, int action) return NULL; } -PyDoc_STRVAR(BZ2Compressor_compress__doc__, -"compress(data) -> bytes\n" -"\n" -"Provide data to the compressor object. Returns a chunk of\n" -"compressed data if possible, or b'' otherwise.\n" -"\n" -"When you have finished providing data to the compressor, call the\n" -"flush() method to finish the compression process.\n"); +/*[clinic input] +output preset file +module _bz2 +class _bz2.BZ2Compressor "BZ2Compressor *" "&BZ2Compressor_Type" +class _bz2.BZ2Decompressor "BZ2Decompressor *" "&BZ2Decompressor_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=e3b139924f5e18cc]*/ + +#include "clinic/_bz2module.c.h" + +/*[clinic input] +_bz2.BZ2Compressor.compress + + data: Py_buffer + / + +Provide data to the compressor object. + +Returns a chunk of compressed data if possible, or b'' otherwise. + +When you have finished providing data to the compressor, call the +flush() method to finish the compression process. +[clinic start generated code]*/ static PyObject * -BZ2Compressor_compress(BZ2Compressor *self, PyObject *args) +_bz2_BZ2Compressor_compress_impl(BZ2Compressor *self, Py_buffer *data) +/*[clinic end generated code: output=59365426e941fbcc input=85c963218070fc4c]*/ { - Py_buffer buffer; PyObject *result = NULL; - if (!PyArg_ParseTuple(args, "y*:compress", &buffer)) - return NULL; - ACQUIRE_LOCK(self); if (self->flushed) PyErr_SetString(PyExc_ValueError, "Compressor has been flushed"); else - result = compress(self, buffer.buf, buffer.len, BZ_RUN); + result = compress(self, data->buf, data->len, BZ_RUN); RELEASE_LOCK(self); - PyBuffer_Release(&buffer); return result; } -PyDoc_STRVAR(BZ2Compressor_flush__doc__, -"flush() -> bytes\n" -"\n" -"Finish the compression process. Returns the compressed data left\n" -"in internal buffers.\n" -"\n" -"The compressor object may not be used after this method is called.\n"); +/*[clinic input] +_bz2.BZ2Compressor.flush + +Finish the compression process. + +Returns the compressed data left in internal buffers. + +The compressor object may not be used after this method is called. +[clinic start generated code]*/ static PyObject * -BZ2Compressor_flush(BZ2Compressor *self, PyObject *noargs) +_bz2_BZ2Compressor_flush_impl(BZ2Compressor *self) +/*[clinic end generated code: output=3ef03fc1b092a701 input=d64405d3c6f76691]*/ { PyObject *result = NULL; @@ -274,14 +290,24 @@ BZ2_Free(void* ctx, void *ptr) PyMem_RawFree(ptr); } +/*[clinic input] +_bz2.BZ2Compressor.__init__ + + compresslevel: int = 9 + Compression level, as a number between 1 and 9. + / + +Create a compressor object for compressing data incrementally. + +For one-shot compression, use the compress() function instead. +[clinic start generated code]*/ + static int -BZ2Compressor_init(BZ2Compressor *self, PyObject *args, PyObject *kwargs) +_bz2_BZ2Compressor___init___impl(BZ2Compressor *self, int compresslevel) +/*[clinic end generated code: output=c4e6adfd02963827 input=4e1ff7b8394b6e9a]*/ { - int compresslevel = 9; int bzerror; - if (!PyArg_ParseTuple(args, "|i:BZ2Compressor", &compresslevel)) - return -1; if (!(1 <= compresslevel && compresslevel <= 9)) { PyErr_SetString(PyExc_ValueError, "compresslevel must be between 1 and 9"); @@ -325,22 +351,12 @@ BZ2Compressor_dealloc(BZ2Compressor *self) } static PyMethodDef BZ2Compressor_methods[] = { - {"compress", (PyCFunction)BZ2Compressor_compress, METH_VARARGS, - BZ2Compressor_compress__doc__}, - {"flush", (PyCFunction)BZ2Compressor_flush, METH_NOARGS, - BZ2Compressor_flush__doc__}, + _BZ2_BZ2COMPRESSOR_COMPRESS_METHODDEF + _BZ2_BZ2COMPRESSOR_FLUSH_METHODDEF {"__getstate__", (PyCFunction)BZ2Compressor_getstate, METH_NOARGS}, {NULL} }; -PyDoc_STRVAR(BZ2Compressor__doc__, -"BZ2Compressor(compresslevel=9)\n" -"\n" -"Create a compressor object for compressing data incrementally.\n" -"\n" -"compresslevel, if given, must be a number between 1 and 9.\n" -"\n" -"For one-shot compression, use the compress() function instead.\n"); static PyTypeObject BZ2Compressor_Type = { PyVarObject_HEAD_INIT(NULL, 0) @@ -363,7 +379,7 @@ static PyTypeObject BZ2Compressor_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ - BZ2Compressor__doc__, /* tp_doc */ + _bz2_BZ2Compressor___init____doc__, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ @@ -378,7 +394,7 @@ static PyTypeObject BZ2Compressor_Type = { 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ - (initproc)BZ2Compressor_init, /* tp_init */ + _bz2_BZ2Compressor___init__, /* tp_init */ 0, /* tp_alloc */ PyType_GenericNew, /* tp_new */ }; @@ -441,7 +457,7 @@ decompress(BZ2Decompressor *d, char *data, size_t len) d->bzs.avail_out = (unsigned int)Py_MIN(buffer_left, UINT_MAX); } } - if (data_size != PyBytes_GET_SIZE(result)) + if (data_size != (size_t)PyBytes_GET_SIZE(result)) if (_PyBytes_Resize(&result, data_size) < 0) goto error; return result; @@ -451,32 +467,33 @@ decompress(BZ2Decompressor *d, char *data, size_t len) return NULL; } -PyDoc_STRVAR(BZ2Decompressor_decompress__doc__, -"decompress(data) -> bytes\n" -"\n" -"Provide data to the decompressor object. Returns a chunk of\n" -"decompressed data if possible, or b'' otherwise.\n" -"\n" -"Attempting to decompress data after the end of stream is reached\n" -"raises an EOFError. Any data found after the end of the stream\n" -"is ignored and saved in the unused_data attribute.\n"); +/*[clinic input] +_bz2.BZ2Decompressor.decompress + + data: Py_buffer + / + +Provide data to the decompressor object. + +Returns a chunk of decompressed data if possible, or b'' otherwise. + +Attempting to decompress data after the end of stream is reached +raises an EOFError. Any data found after the end of the stream +is ignored and saved in the unused_data attribute. +[clinic start generated code]*/ static PyObject * -BZ2Decompressor_decompress(BZ2Decompressor *self, PyObject *args) +_bz2_BZ2Decompressor_decompress_impl(BZ2Decompressor *self, Py_buffer *data) +/*[clinic end generated code: output=086e4b99e60cb3f6 input=616c2a6db5269961]*/ { - Py_buffer buffer; PyObject *result = NULL; - if (!PyArg_ParseTuple(args, "y*:decompress", &buffer)) - return NULL; - ACQUIRE_LOCK(self); if (self->eof) PyErr_SetString(PyExc_EOFError, "End of stream already reached"); else - result = decompress(self, buffer.buf, buffer.len); + result = decompress(self, data->buf, data->len); RELEASE_LOCK(self); - PyBuffer_Release(&buffer); return result; } @@ -488,14 +505,20 @@ BZ2Decompressor_getstate(BZ2Decompressor *self, PyObject *noargs) return NULL; } +/*[clinic input] +_bz2.BZ2Decompressor.__init__ + +Create a decompressor object for decompressing data incrementally. + +For one-shot decompression, use the decompress() function instead. +[clinic start generated code]*/ + static int -BZ2Decompressor_init(BZ2Decompressor *self, PyObject *args, PyObject *kwargs) +_bz2_BZ2Decompressor___init___impl(BZ2Decompressor *self) +/*[clinic end generated code: output=e4d2b9bb866ab8f1 input=95f6500dcda60088]*/ { int bzerror; - if (!PyArg_ParseTuple(args, ":BZ2Decompressor")) - return -1; - #ifdef WITH_THREAD self->lock = PyThread_allocate_lock(); if (self->lock == NULL) { @@ -536,8 +559,7 @@ BZ2Decompressor_dealloc(BZ2Decompressor *self) } static PyMethodDef BZ2Decompressor_methods[] = { - {"decompress", (PyCFunction)BZ2Decompressor_decompress, METH_VARARGS, - BZ2Decompressor_decompress__doc__}, + _BZ2_BZ2DECOMPRESSOR_DECOMPRESS_METHODDEF {"__getstate__", (PyCFunction)BZ2Decompressor_getstate, METH_NOARGS}, {NULL} }; @@ -556,13 +578,6 @@ static PyMemberDef BZ2Decompressor_members[] = { {NULL} }; -PyDoc_STRVAR(BZ2Decompressor__doc__, -"BZ2Decompressor()\n" -"\n" -"Create a decompressor object for decompressing data incrementally.\n" -"\n" -"For one-shot decompression, use the decompress() function instead.\n"); - static PyTypeObject BZ2Decompressor_Type = { PyVarObject_HEAD_INIT(NULL, 0) "_bz2.BZ2Decompressor", /* tp_name */ @@ -584,7 +599,7 @@ static PyTypeObject BZ2Decompressor_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ - BZ2Decompressor__doc__, /* tp_doc */ + _bz2_BZ2Decompressor___init____doc__, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ @@ -599,7 +614,7 @@ static PyTypeObject BZ2Decompressor_Type = { 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ - (initproc)BZ2Decompressor_init, /* tp_init */ + _bz2_BZ2Decompressor___init__, /* tp_init */ 0, /* tp_alloc */ PyType_GenericNew, /* tp_new */ }; diff --git a/Modules/_codecsmodule.c b/Modules/_codecsmodule.c index 0b093ab19fcb..bf408afeca98 100644 --- a/Modules/_codecsmodule.c +++ b/Modules/_codecsmodule.c @@ -42,15 +42,21 @@ Copyright (c) Corporation for National Research Initiatives. #include #endif +/*[clinic input] +module _codecs +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=e1390e3da3cb9deb]*/ + + /* --- Registry ----------------------------------------------------------- */ PyDoc_STRVAR(register__doc__, "register(search_function)\n\ \n\ Register a codec search function. Search functions are expected to take\n\ -one argument, the encoding name in all lower case letters, and return\n\ -a tuple of functions (encoder, decoder, stream_reader, stream_writer)\n\ -(or a CodecInfo object)."); +one argument, the encoding name in all lower case letters, and either\n\ +return None, or a tuple of functions (encoder, decoder, stream_reader,\n\ +stream_writer) (or a CodecInfo object)."); static PyObject *codec_register(PyObject *self, PyObject *search_function) @@ -89,13 +95,15 @@ a ValueError. Other possible values are 'ignore', 'replace' and\n\ codecs.register_error that can handle ValueErrors."); static PyObject * -codec_encode(PyObject *self, PyObject *args) +codec_encode(PyObject *self, PyObject *args, PyObject *kwargs) { + static char *kwlist[] = {"obj", "encoding", "errors", NULL}; const char *encoding = NULL; const char *errors = NULL; PyObject *v; - if (!PyArg_ParseTuple(args, "O|ss:encode", &v, &encoding, &errors)) + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|ss:encode", kwlist, + &v, &encoding, &errors)) return NULL; if (encoding == NULL) @@ -116,13 +124,15 @@ as well as any other name registered with codecs.register_error that is\n\ able to handle ValueErrors."); static PyObject * -codec_decode(PyObject *self, PyObject *args) +codec_decode(PyObject *self, PyObject *args, PyObject *kwargs) { + static char *kwlist[] = {"obj", "encoding", "errors", NULL}; const char *encoding = NULL; const char *errors = NULL; PyObject *v; - if (!PyArg_ParseTuple(args, "O|ss:decode", &v, &encoding, &errors)) + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|ss:decode", kwlist, + &v, &encoding, &errors)) return NULL; if (encoding == NULL) @@ -134,6 +144,53 @@ codec_decode(PyObject *self, PyObject *args) /* --- Helpers ------------------------------------------------------------ */ +/*[clinic input] +_codecs._forget_codec + + encoding: str + / + +Purge the named codec from the internal codec lookup cache +[clinic start generated code]*/ + +PyDoc_STRVAR(_codecs__forget_codec__doc__, +"_forget_codec($module, encoding, /)\n" +"--\n" +"\n" +"Purge the named codec from the internal codec lookup cache"); + +#define _CODECS__FORGET_CODEC_METHODDEF \ + {"_forget_codec", (PyCFunction)_codecs__forget_codec, METH_VARARGS, _codecs__forget_codec__doc__}, + +static PyObject * +_codecs__forget_codec_impl(PyModuleDef *module, const char *encoding); + +static PyObject * +_codecs__forget_codec(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + const char *encoding; + + if (!PyArg_ParseTuple(args, + "s:_forget_codec", + &encoding)) + goto exit; + return_value = _codecs__forget_codec_impl(module, encoding); + +exit: + return return_value; +} + +static PyObject * +_codecs__forget_codec_impl(PyModuleDef *module, const char *encoding) +/*[clinic end generated code: output=a75e631591702a5c input=18d5d92d0e386c38]*/ +{ + if (_PyCodec_Forget(encoding) < 0) { + return NULL; + }; + Py_RETURN_NONE; +} + static PyObject *codec_tuple(PyObject *unicode, Py_ssize_t len) @@ -231,8 +288,6 @@ unicode_internal_decode(PyObject *self, { PyObject *obj; const char *errors = NULL; - const char *data; - Py_ssize_t size; if (!PyArg_ParseTuple(args, "O|z:unicode_internal_decode", &obj, &errors)) @@ -245,11 +300,16 @@ unicode_internal_decode(PyObject *self, return codec_tuple(obj, PyUnicode_GET_LENGTH(obj)); } else { - if (PyObject_AsReadBuffer(obj, (const void **)&data, &size)) + Py_buffer view; + PyObject *result; + if (PyObject_GetBuffer(obj, &view, PyBUF_SIMPLE) != 0) return NULL; - return codec_tuple(_PyUnicode_DecodeUnicodeInternal(data, size, errors), - size); + result = codec_tuple( + _PyUnicode_DecodeUnicodeInternal(view.buf, view.len, errors), + view.len); + PyBuffer_Release(&view); + return result; } } @@ -674,8 +734,6 @@ unicode_internal_encode(PyObject *self, { PyObject *obj; const char *errors = NULL; - const char *data; - Py_ssize_t len, size; if (PyErr_WarnEx(PyExc_DeprecationWarning, "unicode_internal codec has been deprecated", @@ -688,6 +746,7 @@ unicode_internal_encode(PyObject *self, if (PyUnicode_Check(obj)) { Py_UNICODE *u; + Py_ssize_t len, size; if (PyUnicode_READY(obj) < 0) return NULL; @@ -695,16 +754,20 @@ unicode_internal_encode(PyObject *self, u = PyUnicode_AsUnicodeAndSize(obj, &len); if (u == NULL) return NULL; - if (len > PY_SSIZE_T_MAX / sizeof(Py_UNICODE)) + if ((size_t)len > (size_t)PY_SSIZE_T_MAX / sizeof(Py_UNICODE)) return PyErr_NoMemory(); size = len * sizeof(Py_UNICODE); return codec_tuple(PyBytes_FromStringAndSize((const char*)u, size), PyUnicode_GET_LENGTH(obj)); } else { - if (PyObject_AsReadBuffer(obj, (const void **)&data, &size)) + Py_buffer view; + PyObject *result; + if (PyObject_GetBuffer(obj, &view, PyBUF_SIMPLE) != 0) return NULL; - return codec_tuple(PyBytes_FromStringAndSize(data, size), size); + result = codec_tuple(PyBytes_FromStringAndSize(view.buf, view.len), view.len); + PyBuffer_Release(&view); + return result; } } @@ -1120,9 +1183,9 @@ static PyMethodDef _codecs_functions[] = { register__doc__}, {"lookup", codec_lookup, METH_VARARGS, lookup__doc__}, - {"encode", codec_encode, METH_VARARGS, + {"encode", (PyCFunction)codec_encode, METH_VARARGS|METH_KEYWORDS, encode__doc__}, - {"decode", codec_decode, METH_VARARGS, + {"decode", (PyCFunction)codec_decode, METH_VARARGS|METH_KEYWORDS, decode__doc__}, {"escape_encode", escape_encode, METH_VARARGS}, {"escape_decode", escape_decode, METH_VARARGS}, @@ -1168,6 +1231,7 @@ static PyMethodDef _codecs_functions[] = { register_error__doc__}, {"lookup_error", lookup_error, METH_VARARGS, lookup_error__doc__}, + _CODECS__FORGET_CODEC_METHODDEF {NULL, NULL} /* sentinel */ }; diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c index 310e67207e7b..d3b0287abdf4 100644 --- a/Modules/_collectionsmodule.c +++ b/Modules/_collectionsmodule.c @@ -3,7 +3,7 @@ /* collections module implementation of a deque() datatype Written and maintained by Raymond D. Hettinger - Copyright (c) 2004-2013 Python Software Foundation. + Copyright (c) 2004-2015 Python Software Foundation. All rights reserved. */ @@ -145,6 +145,12 @@ typedef struct { static PyTypeObject deque_type; +/* XXX Todo: + If aligned memory allocations become available, make the + deque object 64 byte aligned so that all of the fields + can be retrieved or updated in a single cache line. +*/ + static PyObject * deque_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { @@ -454,6 +460,31 @@ deque_inplace_concat(dequeobject *deque, PyObject *other) return (PyObject *)deque; } +/* The rotate() method is part of the public API and is used internally +as a primitive for other methods. + +Rotation by 1 or -1 is a common case, so any optimizations for high +volume rotations should take care not to penalize the common case. + +Conceptually, a rotate by one is equivalent to a pop on one side and an +append on the other. However, a pop/append pair is unnecessarily slow +because it requires a incref/decref pair for an object located randomly +in memory. It is better to just move the object pointer from one block +to the next without changing the reference count. + +When moving batches of pointers, it is tempting to use memcpy() but that +proved to be slower than a simple loop for a variety of reasons. +Memcpy() cannot know in advance that we're copying pointers instead of +bytes, that the source and destination are pointer aligned and +non-overlapping, that moving just one pointer is a common case, that we +never need to move more than BLOCKLEN pointers, and that at least one +pointer is always moved. + +For high volume rotations, newblock() and freeblock() are never called +more than once. Previously emptied blocks are immediately reused as a +destination block. If a block is left-over at the end, it is freed. +*/ + static int _deque_rotate(dequeobject *deque, Py_ssize_t n) { @@ -503,13 +534,13 @@ _deque_rotate(dequeobject *deque, Py_ssize_t n) if (m > leftindex) m = leftindex; assert (m > 0 && m <= len); - src = &rightblock->data[rightindex]; - dest = &leftblock->data[leftindex - 1]; rightindex -= m; leftindex -= m; + src = &rightblock->data[rightindex + 1]; + dest = &leftblock->data[leftindex]; n -= m; do { - *(dest--) = *(src--); + *(dest++) = *(src++); } while (--m); } if (rightindex == -1) { @@ -1699,11 +1730,13 @@ defdict_init(PyObject *self, PyObject *args, PyObject *kwds) } PyDoc_STRVAR(defdict_doc, -"defaultdict(default_factory) --> dict with default factory\n\ +"defaultdict(default_factory[, ...]) --> dict with default factory\n\ \n\ The default factory is called without arguments to produce\n\ a new value when a key is not present, in __getitem__ only.\n\ A defaultdict compares equal to a dict with the same items.\n\ +All remaining arguments are treated the same as if they were\n\ +passed to the dict constructor, including keyword arguments.\n\ "); /* See comment in xxsubtype.c */ @@ -1798,19 +1831,40 @@ _count_elements(PyObject *self, PyObject *args) if (mapping_get != NULL && mapping_get == dict_get && mapping_setitem != NULL && mapping_setitem == dict_setitem) { while (1) { + /* Fast path advantages: + 1. Eliminate double hashing + (by re-using the same hash for both the get and set) + 2. Avoid argument overhead of PyObject_CallFunctionObjArgs + (argument tuple creation and parsing) + 3. Avoid indirection through a bound method object + (creates another argument tuple) + 4. Avoid initial increment from zero + (reuse an existing one-object instead) + */ + Py_hash_t hash; + key = PyIter_Next(it); if (key == NULL) break; - oldval = PyDict_GetItem(mapping, key); + + if (!PyUnicode_CheckExact(key) || + (hash = ((PyASCIIObject *) key)->hash) == -1) + { + hash = PyObject_Hash(key); + if (hash == -1) + goto done; + } + + oldval = _PyDict_GetItem_KnownHash(mapping, key, hash); if (oldval == NULL) { - if (PyDict_SetItem(mapping, key, one) == -1) - break; + if (_PyDict_SetItem_KnownHash(mapping, key, one, hash) == -1) + goto done; } else { newval = PyNumber_Add(oldval, one); if (newval == NULL) - break; - if (PyDict_SetItem(mapping, key, newval) == -1) - break; + goto done; + if (_PyDict_SetItem_KnownHash(mapping, key, newval, hash) == -1) + goto done; Py_CLEAR(newval); } Py_DECREF(key); diff --git a/Modules/_cryptmodule.c b/Modules/_cryptmodule.c index 51007889bf82..da44ef34eeab 100644 --- a/Modules/_cryptmodule.c +++ b/Modules/_cryptmodule.c @@ -5,40 +5,76 @@ #include -#ifdef __VMS -#include -#endif - /* Module crypt */ +/*[clinic input] +module crypt +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=c6252cf4f2f2ae81]*/ + + +/*[clinic input] +crypt.crypt + + word: 's' + salt: 's' + / + +Hash a *word* with the given *salt* and return the hashed password. + +*word* will usually be a user's password. *salt* (either a random 2 or 16 +character string, possibly prefixed with $digit$ to indicate the method) +will be used to perturb the encryption algorithm and produce distinct +results for a given *word*. + +[clinic start generated code]*/ + +PyDoc_STRVAR(crypt_crypt__doc__, +"crypt($module, word, salt, /)\n" +"--\n" +"\n" +"Hash a *word* with the given *salt* and return the hashed password.\n" +"\n" +"*word* will usually be a user\'s password. *salt* (either a random 2 or 16\n" +"character string, possibly prefixed with $digit$ to indicate the method)\n" +"will be used to perturb the encryption algorithm and produce distinct\n" +"results for a given *word*."); + +#define CRYPT_CRYPT_METHODDEF \ + {"crypt", (PyCFunction)crypt_crypt, METH_VARARGS, crypt_crypt__doc__}, -static PyObject *crypt_crypt(PyObject *self, PyObject *args) +static PyObject * +crypt_crypt_impl(PyModuleDef *module, const char *word, const char *salt); + +static PyObject * +crypt_crypt(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + const char *word; + const char *salt; + + if (!PyArg_ParseTuple(args, + "ss:crypt", + &word, &salt)) + goto exit; + return_value = crypt_crypt_impl(module, word, salt); + +exit: + return return_value; +} + +static PyObject * +crypt_crypt_impl(PyModuleDef *module, const char *word, const char *salt) +/*[clinic end generated code: output=3eaacdf994a6ff23 input=4d93b6d0f41fbf58]*/ { - char *word, *salt; -#ifndef __VMS - extern char * crypt(const char *, const char *); -#endif - - if (!PyArg_ParseTuple(args, "ss:crypt", &word, &salt)) { - return NULL; - } /* On some platforms (AtheOS) crypt returns NULL for an invalid salt. Return None in that case. XXX Maybe raise an exception? */ return Py_BuildValue("s", crypt(word, salt)); - } -PyDoc_STRVAR(crypt_crypt__doc__, -"crypt(word, salt) -> string\n\ -word will usually be a user's password. salt is a 2-character string\n\ -which will be used to select one of 4096 variations of DES. The characters\n\ -in salt must be either \".\", \"/\", or an alphanumeric character. Returns\n\ -the hashed password as a string, which will be composed of characters from\n\ -the same alphabet as the salt."); - static PyMethodDef crypt_methods[] = { - {"crypt", crypt_crypt, METH_VARARGS, crypt_crypt__doc__}, + CRYPT_CRYPT_METHODDEF {NULL, NULL} /* sentinel */ }; diff --git a/Modules/_csv.c b/Modules/_csv.c index 183a9a5edb4d..ade35e5bf71d 100644 --- a/Modules/_csv.c +++ b/Modules/_csv.c @@ -239,10 +239,16 @@ _set_char(const char *name, Py_UCS4 *target, PyObject *src, Py_UCS4 dflt) *target = '\0'; if (src != Py_None) { Py_ssize_t len; + if (!PyUnicode_Check(src)) { + PyErr_Format(PyExc_TypeError, + "\"%s\" must be string, not %.200s", name, + src->ob_type->tp_name); + return -1; + } len = PyUnicode_GetLength(src); if (len > 1) { PyErr_Format(PyExc_TypeError, - "\"%s\" must be an 1-character string", + "\"%s\" must be a 1-character string", name); return -1; } @@ -284,7 +290,7 @@ dialect_check_quoting(int quoting) StyleDesc *qs; for (qs = quote_styles; qs->name; qs++) { - if (qs->style == quoting) + if ((int)qs->style == quoting) return 0; } PyErr_Format(PyExc_TypeError, "bad \"quoting\" value"); @@ -425,7 +431,8 @@ dialect_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) if (dialect_check_quoting(self->quoting)) goto err; if (self->delimiter == 0) { - PyErr_SetString(PyExc_TypeError, "delimiter must be set"); + PyErr_SetString(PyExc_TypeError, + "\"delimiter\" must be a 1-character string"); goto err; } if (quotechar == Py_None && quoting == NULL) diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 820a6060950a..23b8e93b4629 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -159,10 +159,8 @@ _DictRemover_call(PyObject *myself, PyObject *args, PyObject *kw) if (-1 == PyDict_DelItem(self->dict, self->key)) /* XXX Error context */ PyErr_WriteUnraisable(Py_None); - Py_DECREF(self->key); - self->key = NULL; - Py_DECREF(self->dict); - self->dict = NULL; + Py_CLEAR(self->key); + Py_CLEAR(self->dict); } Py_INCREF(Py_None); return Py_None; @@ -290,6 +288,48 @@ _ctypes_alloc_format_string(const char *prefix, const char *suffix) return result; } +/* + Allocate a memory block for a pep3118 format string, adding + the given prefix (if non-null), an additional shape prefix, and a suffix. + Returns NULL on failure, with the error indicator set. If called with + a suffix of NULL the error indicator must already be set. + */ +char * +_ctypes_alloc_format_string_with_shape(int ndim, const Py_ssize_t *shape, + const char *prefix, const char *suffix) +{ + char *new_prefix; + char *result; + char buf[32]; + Py_ssize_t prefix_len; + int k; + + prefix_len = 32 * ndim + 3; + if (prefix) + prefix_len += strlen(prefix); + new_prefix = PyMem_Malloc(prefix_len); + if (new_prefix == NULL) + return NULL; + new_prefix[0] = '\0'; + if (prefix) + strcpy(new_prefix, prefix); + if (ndim > 0) { + /* Add the prefix "(shape[0],shape[1],...,shape[ndim-1])" */ + strcat(new_prefix, "("); + for (k = 0; k < ndim; ++k) { + if (k < ndim-1) { + sprintf(buf, "%"PY_FORMAT_SIZE_T"d,", shape[k]); + } else { + sprintf(buf, "%"PY_FORMAT_SIZE_T"d)", shape[k]); + } + strcat(new_prefix, buf); + } + } + result = _ctypes_alloc_format_string(new_prefix, suffix); + PyMem_Free(new_prefix); + return result; +} + /* PyCStructType_Type - a meta type/class. Creating a new class using this one as __metaclass__ will call the contructor StructUnionType_new. It replaces the @@ -423,39 +463,45 @@ KeepRef(CDataObject *target, Py_ssize_t index, PyObject *keep); static PyObject * CDataType_from_buffer(PyObject *type, PyObject *args) { - void *buffer; - Py_ssize_t buffer_len; + Py_buffer buffer; Py_ssize_t offset = 0; - PyObject *obj, *result; + PyObject *result, *mv; StgDictObject *dict = PyType_stgdict(type); assert (dict); - if (!PyArg_ParseTuple(args, "O|n:from_buffer", &obj, &offset)) - return NULL; - - if (-1 == PyObject_AsWriteBuffer(obj, &buffer, &buffer_len)) + if (!PyArg_ParseTuple(args, "w*|n:from_buffer", &buffer, &offset)) return NULL; if (offset < 0) { PyErr_SetString(PyExc_ValueError, "offset cannot be negative"); + PyBuffer_Release(&buffer); return NULL; } - if (dict->size > buffer_len - offset) { + if (dict->size > buffer.len - offset) { PyErr_Format(PyExc_ValueError, "Buffer size too small (%zd instead of at least %zd bytes)", - buffer_len, dict->size + offset); + buffer.len, dict->size + offset); + PyBuffer_Release(&buffer); return NULL; } - result = PyCData_AtAddress(type, (char *)buffer + offset); - if (result == NULL) + result = PyCData_AtAddress(type, (char *)buffer.buf + offset); + if (result == NULL) { + PyBuffer_Release(&buffer); return NULL; + } - Py_INCREF(obj); - if (-1 == KeepRef((CDataObject *)result, -1, obj)) { + mv = PyMemoryView_FromBuffer(&buffer); + if (mv == NULL) { + PyBuffer_Release(&buffer); return NULL; } + /* Hack the memoryview so that it will release the buffer. */ + ((PyMemoryViewObject *)mv)->mbuf->master.obj = buffer.obj; + ((PyMemoryViewObject *)mv)->view.obj = buffer.obj; + if (-1 == KeepRef((CDataObject *)result, -1, mv)) + result = NULL; return result; } @@ -468,37 +514,36 @@ GenericPyCData_new(PyTypeObject *type, PyObject *args, PyObject *kwds); static PyObject * CDataType_from_buffer_copy(PyObject *type, PyObject *args) { - const void *buffer; - Py_ssize_t buffer_len; + Py_buffer buffer; Py_ssize_t offset = 0; - PyObject *obj, *result; + PyObject *result; StgDictObject *dict = PyType_stgdict(type); assert (dict); - if (!PyArg_ParseTuple(args, "O|n:from_buffer", &obj, &offset)) - return NULL; - - if (-1 == PyObject_AsReadBuffer(obj, (const void**)&buffer, &buffer_len)) + if (!PyArg_ParseTuple(args, "y*|n:from_buffer", &buffer, &offset)) return NULL; if (offset < 0) { PyErr_SetString(PyExc_ValueError, "offset cannot be negative"); + PyBuffer_Release(&buffer); return NULL; } - if (dict->size > buffer_len - offset) { + if (dict->size > buffer.len - offset) { PyErr_Format(PyExc_ValueError, "Buffer size too small (%zd instead of at least %zd bytes)", - buffer_len, dict->size + offset); + buffer.len, dict->size + offset); + PyBuffer_Release(&buffer); return NULL; } result = GenericPyCData_new((PyTypeObject *)type, NULL, NULL); - if (result == NULL) - return NULL; - memcpy(((CDataObject *)result)->b_ptr, - (char *)buffer+offset, dict->size); + if (result != NULL) { + memcpy(((CDataObject *)result)->b_ptr, + (char *)buffer.buf + offset, dict->size); + } + PyBuffer_Release(&buffer); return result; } @@ -862,14 +907,21 @@ PyCPointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (proto) { StgDictObject *itemdict = PyType_stgdict(proto); + const char *current_format; assert(itemdict); /* If itemdict->format is NULL, then this is a pointer to an incomplete type. We create a generic format string 'pointer to bytes' in this case. XXX Better would be to fix the format string later... */ - stgdict->format = _ctypes_alloc_format_string("&", - itemdict->format ? itemdict->format : "B"); + current_format = itemdict->format ? itemdict->format : "B"; + if (itemdict->shape != NULL) { + /* pointer to an array: the shape needs to be prefixed */ + stgdict->format = _ctypes_alloc_format_string_with_shape( + itemdict->ndim, itemdict->shape, "&", current_format); + } else { + stgdict->format = _ctypes_alloc_format_string("&", current_format); + } if (stgdict->format == NULL) { Py_DECREF((PyObject *)stgdict); return NULL; @@ -1033,7 +1085,7 @@ CharArray_set_raw(CDataObject *self, PyObject *value) ptr = view.buf; if (size > self->b_size) { PyErr_SetString(PyExc_ValueError, - "string too long"); + "byte string too long"); goto fail; } @@ -1085,7 +1137,7 @@ CharArray_set_value(CDataObject *self, PyObject *value) size = PyBytes_GET_SIZE(value); if (size > self->b_size) { PyErr_SetString(PyExc_ValueError, - "string too long"); + "byte string too long"); Py_DECREF(value); return -1; } @@ -1247,7 +1299,6 @@ PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) long length; int overflow; Py_ssize_t itemsize, itemalign; - char buf[32]; /* create the new instance (which is a class, since we are a metatype!) */ @@ -1297,13 +1348,7 @@ PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } assert(itemdict->format); - if (itemdict->format[0] == '(') { - sprintf(buf, "(%ld,", length); - stgdict->format = _ctypes_alloc_format_string(buf, itemdict->format+1); - } else { - sprintf(buf, "(%ld)", length); - stgdict->format = _ctypes_alloc_format_string(buf, itemdict->format); - } + stgdict->format = _ctypes_alloc_format_string(NULL, itemdict->format); if (stgdict->format == NULL) goto error; stgdict->ndim = itemdict->ndim + 1; @@ -1431,7 +1476,7 @@ c_wchar_p_from_param(PyObject *type, PyObject *value) Py_INCREF(Py_None); return Py_None; } - if (PyUnicode_Check(value) || PyBytes_Check(value)) { + if (PyUnicode_Check(value)) { PyCArgObject *parg; struct fielddesc *fd = _ctypes_get_fielddesc("Z"); @@ -1583,25 +1628,8 @@ c_void_p_from_param(PyObject *type, PyObject *value) return (PyObject *)parg; } /* XXX struni: remove later */ -/* string */ - if (PyBytes_Check(value)) { - PyCArgObject *parg; - struct fielddesc *fd = _ctypes_get_fielddesc("z"); - - parg = PyCArgObject_new(); - if (parg == NULL) - return NULL; - parg->pffi_type = &ffi_type_pointer; - parg->tag = 'z'; - parg->obj = fd->setfunc(&parg->value, value, 0); - if (parg->obj == NULL) { - Py_DECREF(parg); - return NULL; - } - return (PyObject *)parg; - } /* bytes */ - if (PyByteArray_Check(value)) { + if (PyBytes_Check(value)) { PyCArgObject *parg; struct fielddesc *fd = _ctypes_get_fielddesc("z"); @@ -2934,10 +2962,8 @@ static int PyCFuncPtr_set_restype(PyCFuncPtrObject *self, PyObject *ob) { if (ob == NULL) { - Py_XDECREF(self->restype); - self->restype = NULL; - Py_XDECREF(self->checker); - self->checker = NULL; + Py_CLEAR(self->restype); + Py_CLEAR(self->checker); return 0; } if (ob != Py_None && !PyType_stgdict(ob) && !PyCallable_Check(ob)) { @@ -2980,10 +3006,8 @@ PyCFuncPtr_set_argtypes(PyCFuncPtrObject *self, PyObject *ob) PyObject *converters; if (ob == NULL || ob == Py_None) { - Py_XDECREF(self->converters); - self->converters = NULL; - Py_XDECREF(self->argtypes); - self->argtypes = NULL; + Py_CLEAR(self->converters); + Py_CLEAR(self->argtypes); } else { converters = converters_from_argtypes(ob); if (!converters) @@ -3182,7 +3206,7 @@ _get_name(PyObject *obj, char **pname) return *pname ? 1 : 0; } PyErr_SetString(PyExc_TypeError, - "function name must be string or integer"); + "function name must be string, bytes object or integer"); return 0; } @@ -4281,8 +4305,11 @@ Array_subscript(PyObject *myself, PyObject *item) slicelen); } - dest = (wchar_t *)PyMem_Malloc( - slicelen * sizeof(wchar_t)); + dest = PyMem_New(wchar_t, slicelen); + if (dest == NULL) { + PyErr_NoMemory(); + return NULL; + } for (cur = start, i = 0; i < slicelen; cur += step, i++) { @@ -4811,7 +4838,7 @@ Pointer_set_contents(CDataObject *self, PyObject *value, void *closure) *(void **)self->b_ptr = dst->b_ptr; /* - A Pointer instance must keep a the value it points to alive. So, a + A Pointer instance must keep the value it points to alive. So, a pointer instance has b_length set to 2 instead of 1, and we set 'value' itself as the second item of the b_objects list, additionally. */ @@ -4962,7 +4989,7 @@ Pointer_subscript(PyObject *myself, PyObject *item) return PyUnicode_FromWideChar(ptr + start, len); } - dest = (wchar_t *)PyMem_Malloc(len * sizeof(wchar_t)); + dest = PyMem_New(wchar_t, len); if (dest == NULL) return PyErr_NoMemory(); for (cur = start, i = 0; i < len; cur += step, i++) { diff --git a/Modules/_ctypes/_ctypes_test.c b/Modules/_ctypes/_ctypes_test.c index 3a6845f39bb6..f957e02f1fd7 100644 --- a/Modules/_ctypes/_ctypes_test.c +++ b/Modules/_ctypes/_ctypes_test.c @@ -527,6 +527,49 @@ EXPORT(int) PointInRect(RECT *prc, POINT pt) return 1; } +EXPORT(long left = 10); +EXPORT(long top = 20); +EXPORT(long right = 30); +EXPORT(long bottom = 40); + +EXPORT(RECT) ReturnRect(int i, RECT ar, RECT* br, POINT cp, RECT dr, + RECT *er, POINT fp, RECT gr) +{ + /*Check input */ + if (ar.left + br->left + dr.left + er->left + gr.left != left * 5) + { + ar.left = 100; + return ar; + } + if (ar.right + br->right + dr.right + er->right + gr.right != right * 5) + { + ar.right = 100; + return ar; + } + if (cp.x != fp.x) + { + ar.left = -100; + } + if (cp.y != fp.y) + { + ar.left = -200; + } + switch(i) + { + case 0: + return ar; + break; + case 1: + return dr; + break; + case 2: + return gr; + break; + + } + return ar; +} + typedef struct { short x; short y; diff --git a/Modules/_ctypes/callbacks.c b/Modules/_ctypes/callbacks.c index ec8fd12a8969..7cd61640f819 100644 --- a/Modules/_ctypes/callbacks.c +++ b/Modules/_ctypes/callbacks.c @@ -92,49 +92,6 @@ PrintError(char *msg, ...) } -/* after code that pyrex generates */ -void _ctypes_add_traceback(char *funcname, char *filename, int lineno) -{ - PyObject *py_globals = 0; - PyCodeObject *py_code = 0; - PyFrameObject *py_frame = 0; - PyObject *exception, *value, *tb; - - /* (Save and) Clear the current exception. Python functions must not be - called with an exception set. Calling Python functions happens when - the codec of the filesystem encoding is implemented in pure Python. */ - PyErr_Fetch(&exception, &value, &tb); - - py_globals = PyDict_New(); - if (!py_globals) - goto bad; - py_code = PyCode_NewEmpty(filename, funcname, lineno); - if (!py_code) - goto bad; - py_frame = PyFrame_New( - PyThreadState_Get(), /*PyThreadState *tstate,*/ - py_code, /*PyCodeObject *code,*/ - py_globals, /*PyObject *globals,*/ - 0 /*PyObject *locals*/ - ); - if (!py_frame) - goto bad; - py_frame->f_lineno = lineno; - - PyErr_Restore(exception, value, tb); - PyTraceBack_Here(py_frame); - - Py_DECREF(py_globals); - Py_DECREF(py_code); - Py_DECREF(py_frame); - return; - - bad: - Py_XDECREF(py_globals); - Py_XDECREF(py_code); - Py_XDECREF(py_frame); -} - #ifdef MS_WIN32 /* * We must call AddRef() on non-NULL COM pointers we receive as arguments @@ -254,7 +211,7 @@ static void _CallPythonObject(void *mem, } #define CHECK(what, x) \ -if (x == NULL) _ctypes_add_traceback(what, "_ctypes/callbacks.c", __LINE__ - 1), PyErr_Print() +if (x == NULL) _PyTraceback_Add(what, "_ctypes/callbacks.c", __LINE__ - 1), PyErr_Print() if (flags & (FUNCFLAG_USE_ERRNO | FUNCFLAG_USE_LASTERROR)) { error_object = _ctypes_get_errobj(&space); diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c index 74119a3b4d08..03a911fa0698 100644 --- a/Modules/_ctypes/callproc.c +++ b/Modules/_ctypes/callproc.c @@ -919,7 +919,7 @@ static PyObject *GetResult(PyObject *restype, void *result, PyObject *checker) v = PyObject_CallFunctionObjArgs(checker, retval, NULL); if (v == NULL) - _ctypes_add_traceback("GetResult", "_ctypes/callproc.c", __LINE__-2); + _PyTraceback_Add("GetResult", "_ctypes/callproc.c", __LINE__-2); Py_DECREF(retval); return v; } @@ -1140,9 +1140,6 @@ PyObject *_ctypes_callproc(PPROC pProc, for (i = 0; i < argcount; ++i) { atypes[i] = args[i].ffi_type; if (atypes[i]->type == FFI_TYPE_STRUCT -#ifdef _WIN64 - && atypes[i]->size <= sizeof(void *) -#endif ) avalues[i] = (void *)args[i].value.p; else @@ -1606,7 +1603,7 @@ resize(PyObject *self, PyObject *args) "Memory cannot be resized because this object doesn't own it"); return NULL; } - if (size <= sizeof(obj->b_value)) { + if ((size_t)size <= sizeof(obj->b_value)) { /* internal default buffer is large enough */ obj->b_size = size; goto done; @@ -1672,24 +1669,30 @@ POINTER(PyObject *self, PyObject *cls) } if (PyUnicode_CheckExact(cls)) { char *name = _PyUnicode_AsString(cls); - buf = alloca(strlen(name) + 3 + 1); + buf = PyMem_Malloc(strlen(name) + 3 + 1); + if (buf == NULL) + return PyErr_NoMemory(); sprintf(buf, "LP_%s", name); result = PyObject_CallFunction((PyObject *)Py_TYPE(&PyCPointer_Type), "s(O){}", buf, &PyCPointer_Type); + PyMem_Free(buf); if (result == NULL) return result; key = PyLong_FromVoidPtr(result); } else if (PyType_Check(cls)) { typ = (PyTypeObject *)cls; - buf = alloca(strlen(typ->tp_name) + 3 + 1); + buf = PyMem_Malloc(strlen(typ->tp_name) + 3 + 1); + if (buf == NULL) + return PyErr_NoMemory(); sprintf(buf, "LP_%s", typ->tp_name); result = PyObject_CallFunction((PyObject *)Py_TYPE(&PyCPointer_Type), "s(O){sO}", buf, &PyCPointer_Type, "_type_", cls); + PyMem_Free(buf); if (result == NULL) return result; Py_INCREF(cls); diff --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c index 65772cfa45a4..2078291731df 100644 --- a/Modules/_ctypes/cfield.c +++ b/Modules/_ctypes/cfield.c @@ -1160,7 +1160,7 @@ c_set(void *ptr, PyObject *value, Py_ssize_t size) } error: PyErr_Format(PyExc_TypeError, - "one character string expected"); + "one character bytes, bytearray or integer expected"); return NULL; } @@ -1295,7 +1295,7 @@ s_set(void *ptr, PyObject *value, Py_ssize_t length) Py_INCREF(value); } else { PyErr_Format(PyExc_TypeError, - "expected string, %s found", + "expected bytes, %s found", value->ob_type->tp_name); return NULL; } @@ -1311,7 +1311,7 @@ s_set(void *ptr, PyObject *value, Py_ssize_t length) ++size; } else if (size > length) { PyErr_Format(PyExc_ValueError, - "string too long (%zd, maximum length %zd)", + "bytes too long (%zd, maximum length %zd)", size, length); Py_DECREF(value); return NULL; @@ -1640,9 +1640,9 @@ typedef struct { char c; void *x; } s_void_p; /* #define CHAR_ALIGN (sizeof(s_char) - sizeof(char)) #define SHORT_ALIGN (sizeof(s_short) - sizeof(short)) -#define INT_ALIGN (sizeof(s_int) - sizeof(int)) #define LONG_ALIGN (sizeof(s_long) - sizeof(long)) */ +#define INT_ALIGN (sizeof(s_int) - sizeof(int)) #define FLOAT_ALIGN (sizeof(s_float) - sizeof(float)) #define DOUBLE_ALIGN (sizeof(s_double) - sizeof(double)) #define LONGDOUBLE_ALIGN (sizeof(s_long_double) - sizeof(long double)) @@ -1684,8 +1684,8 @@ ffi_type ffi_type_sint8 = { 1, 1, FFI_TYPE_SINT8 }; ffi_type ffi_type_uint16 = { 2, 2, FFI_TYPE_UINT16 }; ffi_type ffi_type_sint16 = { 2, 2, FFI_TYPE_SINT16 }; -ffi_type ffi_type_uint32 = { 4, 4, FFI_TYPE_UINT32 }; -ffi_type ffi_type_sint32 = { 4, 4, FFI_TYPE_SINT32 }; +ffi_type ffi_type_uint32 = { 4, INT_ALIGN, FFI_TYPE_UINT32 }; +ffi_type ffi_type_sint32 = { 4, INT_ALIGN, FFI_TYPE_SINT32 }; ffi_type ffi_type_uint64 = { 8, LONG_LONG_ALIGN, FFI_TYPE_UINT64 }; ffi_type ffi_type_sint64 = { 8, LONG_LONG_ALIGN, FFI_TYPE_SINT64 }; diff --git a/Modules/_ctypes/ctypes.h b/Modules/_ctypes/ctypes.h index 5237ac23d6d1..de6c76491177 100644 --- a/Modules/_ctypes/ctypes.h +++ b/Modules/_ctypes/ctypes.h @@ -353,10 +353,11 @@ extern char *_ctypes_conversion_errors; extern void _ctypes_free_closure(void *); extern void *_ctypes_alloc_closure(void); -extern void _ctypes_add_traceback(char *, char *, int); - extern PyObject *PyCData_FromBaseObj(PyObject *type, PyObject *base, Py_ssize_t index, char *adr); extern char *_ctypes_alloc_format_string(const char *prefix, const char *suffix); +extern char *_ctypes_alloc_format_string_with_shape(int ndim, + const Py_ssize_t *shape, + const char *prefix, const char *suffix); extern int _ctypes_simple_instance(PyObject *obj); diff --git a/Modules/_ctypes/libffi.diff b/Modules/_ctypes/libffi.diff index ade28e5f9e27..ffa7bafe0e09 100644 --- a/Modules/_ctypes/libffi.diff +++ b/Modules/_ctypes/libffi.diff @@ -1,8 +1,7 @@ -diff -r -N -u libffi.orig/autom4te.cache/output.0 libffi/autom4te.cache/output.0 -diff -r -N -u libffi.orig/configure libffi/configure ---- libffi.orig/configure 2013-03-17 15:37:50.000000000 -0700 -+++ libffi/configure 2013-03-18 15:11:39.611575163 -0700 -@@ -13368,6 +13368,10 @@ +diff -urN libffi-3.1/configure libffi/configure +--- libffi-3.1/configure 2014-05-19 15:44:03.000000000 +0200 ++++ libffi/configure 2014-08-09 21:51:07.877871443 +0200 +@@ -17236,6 +17236,10 @@ fi ;; @@ -13,22 +12,22 @@ diff -r -N -u libffi.orig/configure libffi/configure x86_64-*-darwin*) TARGET=X86_DARWIN; TARGETDIR=x86 ;; -@@ -13426,12 +13430,12 @@ +@@ -17298,12 +17302,12 @@ ;; mips-sgi-irix5.* | mips-sgi-irix6.* | mips*-*-rtems*) - TARGET=MIPS; TARGETDIR=mips + TARGET=MIPS_IRIX; TARGETDIR=mips ;; - mips*-*-linux* | mips*-*-openbsd*) + mips*-*linux* | mips*-*-openbsd*) # Support 128-bit long double for NewABI. HAVE_LONG_DOUBLE='defined(__mips64)' - TARGET=MIPS; TARGETDIR=mips -+ TARGET=MIPS_IRIX; TARGETDIR=mips ++ TARGET=MIPS_LINUX; TARGETDIR=mips ;; - powerpc*-*-linux* | powerpc-*-sysv*) -@@ -13491,7 +13495,7 @@ + nios2*-linux*) +@@ -17373,7 +17377,7 @@ as_fn_error $? "\"libffi has not been ported to $host.\"" "$LINENO" 5 fi @@ -37,7 +36,7 @@ diff -r -N -u libffi.orig/configure libffi/configure MIPS_TRUE= MIPS_FALSE='#' else -@@ -14862,6 +14866,12 @@ +@@ -18814,6 +18818,12 @@ ac_config_files="$ac_config_files include/Makefile include/ffi.h Makefile testsuite/Makefile man/Makefile libffi.pc" @@ -50,7 +49,7 @@ diff -r -N -u libffi.orig/configure libffi/configure cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure -@@ -16047,6 +16057,8 @@ +@@ -20126,6 +20136,8 @@ "testsuite/Makefile") CONFIG_FILES="$CONFIG_FILES testsuite/Makefile" ;; "man/Makefile") CONFIG_FILES="$CONFIG_FILES man/Makefile" ;; "libffi.pc") CONFIG_FILES="$CONFIG_FILES libffi.pc" ;; @@ -59,9 +58,9 @@ diff -r -N -u libffi.orig/configure libffi/configure *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac -diff -r -N -u libffi.orig/configure.ac libffi/configure.ac ---- libffi.orig/configure.ac 2013-03-17 15:37:50.000000000 -0700 -+++ libffi/configure.ac 2013-03-18 15:11:11.392989136 -0700 +diff -urN libffi-3.1/configure.ac libffi/configure.ac +--- libffi-3.1/configure.ac 2014-05-11 15:57:49.000000000 +0200 ++++ libffi/configure.ac 2014-08-09 21:51:07.877871443 +0200 @@ -1,4 +1,7 @@ dnl Process this with autoconf to create configure +# @@ -70,33 +69,32 @@ diff -r -N -u libffi.orig/configure.ac libffi/configure.ac AC_PREREQ(2.68) -@@ -146,6 +149,10 @@ - fi +@@ -144,6 +147,9 @@ + AM_LTLDFLAGS='-no-undefined -bindir "$(bindir)"'; + fi ;; - + i*86-*-nto-qnx*) + TARGET=X86; TARGETDIR=x86 + ;; -+ - x86_64-*-darwin*) + i?86-*-darwin*) TARGET=X86_DARWIN; TARGETDIR=x86 ;; -@@ -204,12 +211,12 @@ +@@ -218,12 +224,12 @@ ;; mips-sgi-irix5.* | mips-sgi-irix6.* | mips*-*-rtems*) - TARGET=MIPS; TARGETDIR=mips + TARGET=MIPS_IRIX; TARGETDIR=mips ;; - mips*-*-linux* | mips*-*-openbsd*) + mips*-*linux* | mips*-*-openbsd*) # Support 128-bit long double for NewABI. HAVE_LONG_DOUBLE='defined(__mips64)' - TARGET=MIPS; TARGETDIR=mips -+ TARGET=MIPS_IRIX; TARGETDIR=mips ++ TARGET=MIPS_LINUX; TARGETDIR=mips ;; - powerpc*-*-linux* | powerpc-*-sysv*) -@@ -269,7 +276,7 @@ + nios2*-linux*) +@@ -293,7 +299,7 @@ AC_MSG_ERROR(["libffi has not been ported to $host."]) fi @@ -105,7 +103,7 @@ diff -r -N -u libffi.orig/configure.ac libffi/configure.ac AM_CONDITIONAL(BFIN, test x$TARGET = xBFIN) AM_CONDITIONAL(SPARC, test x$TARGET = xSPARC) AM_CONDITIONAL(X86, test x$TARGET = xX86) -@@ -567,4 +574,8 @@ +@@ -617,4 +623,8 @@ AC_CONFIG_FILES(include/Makefile include/ffi.h Makefile testsuite/Makefile man/Makefile libffi.pc) @@ -114,19 +112,19 @@ diff -r -N -u libffi.orig/configure.ac libffi/configure.ac +AC_CONFIG_FILES(fficonfig.py) + AC_OUTPUT ---- libffi-3.0.11/fficonfig.py.in 1970-01-01 01:00:00.000000000 +0100 -+++ libffi/fficonfig.py.in 2012-03-15 01:04:27.000000000 +0100 +diff -urN libffi-3.1/fficonfig.py.in libffi/fficonfig.py.in +--- libffi-3.1/fficonfig.py.in 1970-01-01 01:00:00.000000000 +0100 ++++ libffi/fficonfig.py.in 2014-08-09 21:43:25.229871827 +0200 @@ -0,0 +1,35 @@ +ffi_sources = """ +src/prep_cif.c +src/closures.c -+src/dlmalloc.c +""".split() + +ffi_platforms = { + 'MIPS_IRIX': ['src/mips/ffi.c', 'src/mips/o32.S', 'src/mips/n32.S'], + 'MIPS_LINUX': ['src/mips/ffi.c', 'src/mips/o32.S'], -+ 'X86': ['src/x86/ffi.c', 'src/x86/sysv.S'], ++ 'X86': ['src/x86/ffi.c', 'src/x86/sysv.S', 'src/x86/win32.S'], + 'X86_FREEBSD': ['src/x86/ffi.c', 'src/x86/freebsd.S'], + 'X86_WIN32': ['src/x86/ffi.c', 'src/x86/win32.S'], + 'SPARC': ['src/sparc/ffi.c', 'src/sparc/v8.S', 'src/sparc/v9.S'], @@ -134,9 +132,10 @@ diff -r -N -u libffi.orig/configure.ac libffi/configure.ac + 'IA64': ['src/ia64/ffi.c', 'src/ia64/unix.S'], + 'M32R': ['src/m32r/sysv.S', 'src/m32r/ffi.c'], + 'M68K': ['src/m68k/ffi.c', 'src/m68k/sysv.S'], -+ 'POWERPC': ['src/powerpc/ffi.c', 'src/powerpc/sysv.S', 'src/powerpc/ppc_closure.S', 'src/powerpc/linux64.S', 'src/powerpc/linux64_closure.S'], ++ 'POWERPC': ['src/powerpc/ffi.c', 'src/powerpc/ffi_sysv.c', 'src/powerpc/ffi_linux64.c', 'src/powerpc/sysv.S', 'src/powerpc/ppc_closure.S', 'src/powerpc/linux64.S', 'src/powerpc/linux64_closure.S'], + 'POWERPC_AIX': ['src/powerpc/ffi_darwin.c', 'src/powerpc/aix.S', 'src/powerpc/aix_closure.S'], + 'POWERPC_FREEBSD': ['src/powerpc/ffi.c', 'src/powerpc/sysv.S', 'src/powerpc/ppc_closure.S'], ++ 'AARCH64': ['src/aarch64/sysv.S', 'src/aarch64/ffi.c'], + 'ARM': ['src/arm/sysv.S', 'src/arm/ffi.c'], + 'LIBFFI_CRIS': ['src/cris/sysv.S', 'src/cris/ffi.c'], + 'FRV': ['src/frv/eabi.S', 'src/frv/ffi.c'], @@ -152,9 +151,9 @@ diff -r -N -u libffi.orig/configure.ac libffi/configure.ac +ffi_sources += ffi_platforms['@TARGET@'] + +ffi_cflags = '@CFLAGS@' -diff -urN libffi-3.0.11/src/dlmalloc.c libffi/src/dlmalloc.c ---- libffi-3.0.11/src/dlmalloc.c 2012-04-12 04:46:06.000000000 +0200 -+++ libffi/src/dlmalloc.c 2012-06-26 15:15:58.949547461 +0200 +diff -urN libffi-3.1/src/dlmalloc.c libffi/src/dlmalloc.c +--- libffi-3.1/src/dlmalloc.c 2014-04-25 19:45:13.000000000 +0200 ++++ libffi/src/dlmalloc.c 2014-08-09 21:51:07.881871443 +0200 @@ -457,6 +457,11 @@ #define LACKS_ERRNO_H #define MALLOC_FAILURE_ACTION @@ -167,3 +166,44 @@ diff -urN libffi-3.0.11/src/dlmalloc.c libffi/src/dlmalloc.c #endif /* WIN32 */ #ifdef __OS2__ +@@ -4497,7 +4502,7 @@ + char* tbase = (char*)(CALL_MMAP(tsize)); + if (tbase != CMFAIL) { + m = init_user_mstate(tbase, tsize); +- set_segment_flags(&m->seg, IS_MMAPPED_BIT); ++ (void)set_segment_flags(&m->seg, IS_MMAPPED_BIT); + set_lock(m, locked); + } + } +@@ -4512,7 +4517,7 @@ + if (capacity > msize + TOP_FOOT_SIZE && + capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) { + m = init_user_mstate((char*)base, capacity); +- set_segment_flags(&m->seg, EXTERN_BIT); ++ (void)set_segment_flags(&m->seg, EXTERN_BIT); + set_lock(m, locked); + } + return (mspace)m; +diff -urN libffi-3.1/src/arm/ffi.c libffi/src/arm/ffi.c +--- libffi-3.1/src/arm/ffi.c Sat Aug 09 23:52:34 2014 +0200 ++++ libffi/src/arm/ffi.c Sat Aug 09 23:58:38 2014 +0200 +@@ -154,9 +154,6 @@ + + int ffi_prep_args_VFP(char *stack, extended_cif *ecif, float *vfp_space) + { +- // make sure we are using FFI_VFP +- FFI_ASSERT(ecif->cif->abi == FFI_VFP); +- + register unsigned int i, vi = 0; + register void **p_argv; + register char *argp, *regp, *eo_regp; +@@ -165,6 +162,9 @@ + char done_with_regs = 0; + char is_vfp_type; + ++ // make sure we are using FFI_VFP ++ FFI_ASSERT(ecif->cif->abi == FFI_VFP); ++ + /* the first 4 words on the stack are used for values passed in core + * registers. */ + regp = stack; diff --git a/Modules/_ctypes/libffi/.gitignore b/Modules/_ctypes/libffi/.gitignore deleted file mode 100644 index 6af76ac33c99..000000000000 --- a/Modules/_ctypes/libffi/.gitignore +++ /dev/null @@ -1,21 +0,0 @@ -.libs -.deps -*.o -*.lo -.dirstamp -*.la -Makefile -config.log -config.status -*~ -fficonfig.h -include/ffi.h -include/ffitarget.h -libffi.pc -libtool -stamp-h1 -libffi*gz -autom4te.cache -libffi.xcodeproj/xcuserdata -libffi.xcodeproj/project.xcworkspace -ios/ diff --git a/Modules/_ctypes/libffi/.travis.yml b/Modules/_ctypes/libffi/.travis.yml deleted file mode 100644 index 1a6a425c066e..000000000000 --- a/Modules/_ctypes/libffi/.travis.yml +++ /dev/null @@ -1,8 +0,0 @@ -language: c -compiler: - - gcc - - clang - -before_script: sudo apt-get install dejagnu - -script: ./configure && make && make check diff --git a/Modules/_ctypes/libffi/ChangeLog b/Modules/_ctypes/libffi/ChangeLog index e0b057c79a49..c85cbe621acc 100644 --- a/Modules/_ctypes/libffi/ChangeLog +++ b/Modules/_ctypes/libffi/ChangeLog @@ -1,5509 +1,5105 @@ -2013-03-17 Anthony Green +commit 0403f332b1f478696c30d3d8a0e2f6eef24aaf88 +Author: Anthony Green +Date: Mon May 19 09:41:32 2014 -0400 - * README: Update for 3.0.13. - * configure.ac: Ditto. - * configure: Rebuilt. - * doc/*: Update version. + Update date. Annoucing 3.1 today. -2013-03-17 Dave Korn +commit 94ac0c168ee7b115409121d88b25a4979446c8da +Author: Anthony Green +Date: Mon May 19 09:37:21 2014 -0400 - * src/closures.c (is_emutramp_enabled - [!FFI_MMAP_EXEC_EMUTRAMP_PAX]): Move default definition outside - enclosing #if scope. + Increment libtool library revision number -2013-03-17 Anthony Green +commit 57465744b6e1295d7202de5a7734df589518f1c8 +Author: Anthony Green +Date: Sun May 11 10:30:22 2014 -0400 - * configure.ac: Only modify toolexecdir in certain cases. - * configure: Rebuilt. + Update to version 3.1 -2013-03-16 Gilles Talis +commit 0c2251a42df5108b6d9ebe5fe1cf83d0bcdf660e +Author: Anthony Green +Date: Sun May 11 10:22:30 2014 -0400 - * src/powerpc/ffi.c (ffi_prep_args_SYSV): Don't use - fparg_count,etc on __NO_FPRS__ targets. + Support versions of git older than 1.8.5 -2013-03-16 Alan Hourihane +commit 70c303cb88e23aaee91c87c56b108c50ab4f3c2f +Author: Anthony Green +Date: Sun May 11 09:56:40 2014 -0400 - * src/m68k/sysv.S (epilogue): Don't use extb instruction on - m680000 machines. + Fix testsuite for GCC 4.9.0 -2013-03-16 Alex Gaynor +commit 52b3457093ed19b2a7c5fcf243c4014c90ce6225 +Author: Magnus Granberg +Date: Sun May 11 09:55:28 2014 -0400 - * src/x86/ffi.c (ffi_prep_cif_machdep): Always align stack. + Check /proc/self/status for PaX status. -2013-03-13 Markos Chandras +commit 7ba4c5d72aa440a4b21fb57e999e67c5957761da +Author: Dominik Vogt +Date: Sun May 11 09:52:47 2014 -0400 - * configure.ac: Add support for Imagination Technologies Meta. - * Makefile.am: Likewise. - * README: Add Imagination Technologies Meta details. - * src/metag/ffi.c: New. - * src/metag/ffitarget.h: Likewise. - * src/metag/sysv.S: Likewise. + Use to get correct dir -2013-02-24 Andreas Schwab +commit 31e0d4ecff6dc2a6c75a066ee099b52a43f6ba27 +Merge: 1c0e9a7 99909eb +Author: Anthony Green +Date: Wed Apr 23 19:24:47 2014 -0400 - * doc/libffi.texi (Structures): Fix missing category argument of - @deftp. + Merge pull request #119 from joshtriplett/fastcall-fastball + + src/x86/win32.S: Define ffi_closure_FASTCALL in the MASM section, too -2013-02-11 Anthony Green +commit 99909eb6184b62408d88b6b4e7ab38e84e6d0bf3 +Author: Josh Triplett +Date: Tue Apr 22 21:17:52 2014 -0700 - * configure.ac: Update release number to 3.0.12. - * configure: Rebuilt. - * README: Update release info. + src/x86/win32.S: Define ffi_closure_FASTCALL in the MASM section, too -2013-02-10 Anthony Green +commit 1c0e9a7297ced15413c2d2d5d35f6c650c4b46c9 +Merge: 93a24f2 d369522 +Author: Anthony Green +Date: Mon Apr 21 12:41:56 2014 -0400 - * README: Add Moxie. - * src/moxie/ffi.c: Created. - * src/moxie/eabi.S: Created. - * src/moxie/ffitarget.h: Created. - * Makefile.am (nodist_libffi_la_SOURCES): Add Moxie. - * Makefile.in: Rebuilt. - * configure.ac: Add Moxie. - * configure: Rebuilt. - * testsuite/libffi.call/huge_struct.c: Disable format string - warnings for moxie*-*-elf tests. + Merge pull request #101 from joshtriplett/fastcall-closures + + Support closures for fastcall -2013-02-10 Anthony Green +commit d36952273d4fafbda91ecc205fc0824f7cc65e70 +Author: Josh Triplett +Date: Sun Apr 20 12:03:25 2014 -0700 - * Makefile.am (LTLDFLAGS): Fix reference. - * Makefile.in: Rebuilt. + Support fastcall closures + + libffi on 32-bit x86 now supports closures for all supported ABIs. + Thus, rewrite the last remaining duplicated-by-ABI test (closure_stdcall + and closure_thiscall) to use the generic ABI_NUM/ABI_ATTR mechanism. -2013-02-10 Anthony Green +commit 93a24f216bcdd1018b976d697179c6d49004015a +Merge: dd11a04 2349fec +Author: Anthony Green +Date: Sat Apr 12 19:38:07 2014 -0400 - * README: Update supported platforms. Update test results link. + Merge pull request #80 from ueno/devel + + Fix typo in doc -2013-02-09 Anthony Green +commit dd11a04061cb49ce1d702545693c24eb1267d648 +Merge: 8fa2812 03ca880 +Author: Anthony Green +Date: Sat Apr 12 19:37:21 2014 -0400 - * testsuite/libffi.call/negint.c: Remove forced -O2. - * testsuite/libffi.call/many2.c (foo): Remove GCCism. - * testsuite/libffi.call/ffitest.h: Add default PRIuPTR definition. + Merge pull request #86 from joshtriplett/testsuite-CC-CXX + + testsuite ignores CC parameter supplied to configure or make - * src/sparc/v8.S (ffi_closure_v8): Import ancient ulonglong - closure return type fix developed by Martin v. Löwis for cpython - fork. +commit 8fa2812355e685a42abf9a62fbc674d616b2edee +Merge: 8a58e6b 419503f +Author: Anthony Green +Date: Sat Apr 12 19:32:08 2014 -0400 -2013-02-08 Andreas Tobler + Merge pull request #116 from frida/fix/darwin-aarch64-variadic + + Fix handling of variadic calls on Darwin/AArch64 - * src/powerpc/ffi.c (ffi_prep_cif_machdep): Fix small struct - support. - * src/powerpc/sysv.S: Ditto. +commit 8a58e6b7805b736def197b8baf8e465a2a3f6913 +Merge: 30b77c5 a539f7f +Author: Anthony Green +Date: Sat Apr 12 19:30:18 2014 -0400 -2013-02-08 Anthony Green + Merge pull request #115 from frida/fix/darwin-aarch64-alignment + + Fix alignment of AArch64 assembler functions - * testsuite/libffi.call/cls_longdouble.c: Remove xfail for - arm*-*-*. +commit 30b77c56f95c63ecd83399aafdbad7b07330f2fd +Merge: dc33cb3 3e2b84d +Author: Anthony Green +Date: Sat Apr 12 19:29:13 2014 -0400 -2013-02-08 Anthony Green + Merge pull request #117 from frida/fix/windows-regression + + Fix Windows regression - * src/sparc/ffi.c (ffi_prep_closure_loc): Fix cache flushing for GCC. +commit 3e2b84d295531720917bf46afc532fc6d877e3ec +Author: Ole André Vadla Ravnås +Date: Sat Apr 12 01:04:04 2014 +0200 -2013-02-08 Matthias Klose + Fix Windows regression + + Introduced by b5fed601948237037513a9b7f967c8fc6c9ff1f6. - * man/ffi_prep_cif.3: Clean up for debian linter. +commit 419503f409c321fe31ff59d963ef34bb913420d0 +Author: Ole André Vadla Ravnås +Date: Sun Apr 6 20:54:13 2014 +0200 -2013-02-08 Peter Bergner + Fix handling of variadic calls on Darwin/AArch64 - * src/powerpc/ffi.c (ffi_prep_args_SYSV): Account for FP args pushed - on the stack. +commit a539f7ffd6783aa11353d13265520e453c565fb4 +Author: Ole André Vadla Ravnås +Date: Sun Apr 6 20:53:02 2014 +0200 -2013-02-08 Anthony Green + Fix alignment of AArch64 assembler functions + +commit dc33cb3c998da521a960385c1269c3aef552f69f +Merge: c860a99 b5fed60 +Author: Anthony Green +Date: Sat Apr 5 23:41:22 2014 -0400 - * Makefile.am (EXTRA_DIST): Add missing files. - * testsuite/Makefile.am (EXTRA_DIST): Ditto. - * Makefile.in: Rebuilt. + Merge pull request #114 from joshtriplett/bounce-on-a-tiny-trampoline + + Fix ABI on 32-bit non-Windows x86: go back to trampoline size 10 + +commit b5fed601948237037513a9b7f967c8fc6c9ff1f6 +Author: Josh Triplett +Date: Sat Apr 5 17:33:42 2014 -0700 + + Fix ABI on 32-bit non-Windows x86: go back to trampoline size 10 + + The trampoline size is part of the ABI, so it cannot change. Move the + logic from the stdcall and thiscall trampolines to the functions they + call, to reduce them both to 10 bytes. + + This drops the previously added support for raw THISCALL closures on + non-Windows. (Non-raw THISCALL closures still work.) + +commit 03ca880081b22efab09ba72268270f83017d3d7b +Author: Josh Triplett +Date: Thu Mar 27 08:44:34 2014 -0700 + + README: Note the testsuite changes to respect $CC and $CXX + +commit d74df8c5d8c6722ecb908da98c86cc8e2c755b84 +Author: Josh Triplett +Date: Thu Mar 27 00:44:12 2014 -0700 + + README: Update Windows example to set both CC and CXX -2013-02-08 Anthony Green +commit 7d698125b1f05173f3656a89755a2eb58813b002 +Author: Josh Triplett +Date: Wed Mar 26 23:17:56 2014 -0700 - * configure.ac: Move sparc asm config checks to within functions - for compatibility with sun tools. - * configure: Rebuilt. - * src/sparc/ffi.c (ffi_prep_closure_loc): Flush cache on v9 - systems. - * src/sparc/v8.S (ffi_flush_icache): Implement a sparc v9 cache - flusher. + Use the proper C++ compiler to run C++ tests + + Running the C compiler with -shared-libgcc -lstdc++ does not work on + non-GCC compilers. -2013-02-08 Nathan Rossi +commit fa5e88f170cb37c7b2b9bb015c8c5b854ffd8a3e +Author: Josh Triplett +Date: Wed Mar 26 23:53:57 2014 -0700 - * src/microblaze/ffi.c (ffi_closure_call_SYSV): Fix handling of - small big-endian structures. - (ffi_prep_args): Ditto. + .travis.yml: Make the build command more readable by splitting at && + + "script" can contain multiple commands to run in sequence. -2013-02-07 Anthony Green +commit 0c3824702d3d59d37f8c177d646303f546187683 +Author: Josh Triplett +Date: Wed Mar 26 14:51:32 2014 -0700 + + Always set CC_FOR_TARGET for dejagnu, to make the testsuite respect $CC + + This fixes cross-compilation and compilation with CC="gcc -m32". + +commit 9946a92af31b30cb7760150d1f8ca6c11b01aeea +Author: Josh Triplett +Date: Wed Mar 26 20:18:58 2014 -0700 + + Stop looking for expect and runtest above top_builddir + + Users wishing to test hand-compiled versions of expect and runtest can + easily enough put them in their path or set EXPECT and RUNTEST + themselves. - * src/sparc/v8.S (ffi_call_v8): Fix typo from last patch - (effectively hiding ffi_call_v8). +commit acb202325215058639234efb7af1f04c1c8a1f44 +Author: Josh Triplett +Date: Wed Mar 26 20:18:41 2014 -0700 + + Stop setting an empty AM_RUNTESTFLAGS -2013-02-07 Anthony Green +commit c860a992fef5d7cd7bb0975b1632d17a9fafe007 +Author: Anthony Green +Date: Tue Mar 25 17:02:51 2014 -0400 - * configure.ac: Update bug reporting address. - * configure.in: Rebuild. + Upgrade version to 3.1-rc1 + +commit 9837073e6203048a162a226798c5d252600219ed +Author: Anthony Green +Date: Tue Mar 25 16:24:14 2014 -0400 + + Update copyright date and clean up README notes. - * src/sparc/v8.S (ffi_flush_icache): Out-of-line cache flusher for - Sun compiler. - * src/sparc/ffi.c (ffi_call): Remove warning. - Call ffi_flush_icache for non-GCC builds. - (ffi_prep_closure_loc): Use ffi_flush_icache. +commit 18d3baa9f597b026675baa1b4e5a5eeef7577a08 +Merge: afee537 f0c8a31 +Author: Anthony Green +Date: Tue Mar 25 16:12:53 2014 -0400 + + Merge pull request #108 from joshtriplett/freebsd + + [3.1 blocker] Fix FreeBSD support + +commit afee53738a995e23bd2f89fd0f7b30b380566106 +Merge: 7d24785 b2d610e +Author: Anthony Green +Date: Tue Mar 25 16:12:35 2014 -0400 + + Merge pull request #106 from joshtriplett/darwin-award + + [3.1 blocker] Update OS X build system to include win32.S on 32-bit + +commit 7d2478568ed9f03cbf57627f449a2d2cf4d1571c +Merge: beab5f3 56be47f +Author: Anthony Green +Date: Tue Mar 25 16:12:17 2014 -0400 + + Merge pull request #110 from joshtriplett/w64 + + Fix 64-bit Windows support + +commit beab5f334d9ec5b8b91d1cc727d1029b40358e7e +Merge: 28fb197 ef5890e +Author: Anthony Green +Date: Tue Mar 25 16:07:47 2014 -0400 + + Merge pull request #105 from joshtriplett/win32-relocations + + [3.1 blocker] win32.S needs to handle relocations/GOT + +commit f0c8a31577172104049283f0a80c723084a5bd77 +Author: Josh Triplett +Date: Mon Mar 24 22:14:26 2014 -0700 + + Compile win32.S on FreeBSD + +commit b2d610e028b5ce48d1ad7e5d0debc9c321d891b2 +Author: Josh Triplett +Date: Fri Mar 21 11:10:13 2014 -0700 + + Compile win32.S on 32-bit Darwin as well + +commit be50b87a490e794362cb4a27ada2fbaab202adb8 +Author: Josh Triplett +Date: Mon Mar 24 21:44:13 2014 -0700 + + Always use configure to detect whether global symbols need underscores + + 64-bit Windows already used this check; make it universal, and use it in + place of an ifdef on X86_WIN32, to handle non-Windows platforms that use + the underscore, such as Darwin. + +commit 56be47f87629e31afbcb0774aa65735f539ee972 +Author: Josh Triplett +Date: Mon Mar 24 21:24:53 2014 -0700 + + Fix a warning on 64-bit Windows + + When sizeof(size_t) != sizeof(unsigned), adding a size_t to cif->bytes + produces a "possible loss of data" warning. However, the size_t in + question refers to the size of a single parameter. Use a cast to avoid + the warning. + +commit 48a8eda74aad8a21b6f26df5df08fe64c043d208 +Author: Josh Triplett +Date: Mon Mar 24 21:21:12 2014 -0700 + + Avoid referencing undefined ABIs on 64-bit Windows builds + + 64-bit Windows does not have FFI_STDCALL, FFI_THISCALL, or FFI_FASTCALL. + +commit f0f4138f90345d7d67dfa6783a7e1c7cc30d3c6f +Author: Josh Triplett +Date: Sat Mar 22 10:00:53 2014 -0700 + + win32.S: Add handling for position-independent code on Darwin + + Newer versions of Darwin generate the necessary stub functions + automatically and just need a call instruction, but accomodating older + versions as well requires adding the stub. + +commit ef5890ebafb7cd2fbf9acf161edb55fe1382871c +Author: Josh Triplett +Date: Fri Mar 21 11:01:39 2014 -0700 + + win32.S: Use shifting for multiplication rather than repeated addition + + The jump table code added a register to itself twice to multiply by 4; + shift the register left by 2 instead. + +commit 4fca48901e7e4f53bf490ed22607b2d2d8f4bfcc +Author: Josh Triplett +Date: Fri Mar 21 11:00:41 2014 -0700 + + win32.S: Make the jump tables position-independent + + Now that non-Windows platforms include win32.S, it needs to support + building as position-independent code. This fixes build failures on + target platforms that do not allow text relocations. + +commit 2087dcf736274286f76c69d3988fb6d7cc4fd0f5 +Author: Josh Triplett +Date: Fri Mar 21 10:57:06 2014 -0700 + + win32.S: Make calls to ffi_closure_SYSV_inner position-independent + + Now that non-Windows platforms include win32.S, it needs to support + building as position-independent code. This fixes one source of build + failures on target platforms that do not allow text relocations. + +commit 28fb197079cf1d11da4eef7c8c243ab05590c528 +Merge: c697472 c3dd0a1 +Author: Anthony Green +Date: Tue Mar 18 12:19:36 2014 -0400 + + Merge pull request #107 from rvandermeulen/msvcc + + Various compatibility fixes and improvements to msvcc.sh. + +commit c3dd0a1a0245fc174361a70876e88ae24285f861 +Author: Ryan VanderMeulen +Date: Tue Mar 18 12:09:45 2014 -0400 + + Various compatibility fixes and improvements to msvcc.sh. + + * Don't try to mix incompatible optimization flags in debug builds. + * Workaround ax_cc_maxopt.m4 not supporting MSVC and change -O3 to -O2. + * Fix MSVC warning by properly passing linker flags to compiler. + * Make msvcc.sh return 1 if invalid command line options are used rather than silently eating them. + * Add more comments. + +commit c697472fccfbb5b87b007c053cda9ef014b346b9 +Merge: 83fd2bc e48918e +Author: Anthony Green +Date: Mon Mar 17 00:32:42 2014 -0400 + + Merge pull request #102 from joshtriplett/test-generic + + Add ABIs to the test matrix; unify many bits of the testsuite + +commit e48918ecf876bc85d040fc50a232059c566553a8 +Author: Josh Triplett +Date: Sun Mar 16 20:29:27 2014 -0700 + + testsuite: Add ABIs to the test matrix; unify tests across ABIs + + This eliminates all the *_win32.c tests in favor of the tests they were + branched from, and expands test coverage to run many more tests on + stdcall, thiscall, and fastcall. + + This same mechanism also supports testing any other target that has + multiple ABIs. + +commit 4d4d368e5a55d9443c4c53b1b70d58ab6d8c941c +Author: Josh Triplett +Date: Sun Mar 16 17:02:05 2014 -0700 + + testsuite: Replace ffitestcxx.h with ffitest.h + + ffitest.h contains a superset of the functionality of ffitestcxx.h; + make the C++ tests include ffitest.h instead, and remove ffitestcxx.h. + +commit 3f97cf3413c46caf2a79f32ac9cda4620972c2d7 +Author: Josh Triplett +Date: Sun Mar 16 16:53:42 2014 -0700 + + testsuite: Unify the C and C++ testsuites + + These two testsuites differ only in the source file glob and a couple of + additional compiler options; unify the remaining bits. + +commit 0d9cce8edb937bbe771a6cdd25f671edf06d2128 +Author: Josh Triplett +Date: Sun Mar 16 16:22:58 2014 -0700 + + testsuite: ffitest.h: Parenthesize the CHECK macro + +commit 5695ec1444c5323e48fe4314f8c8f027625e67df +Author: Josh Triplett +Date: Sun Mar 16 16:04:58 2014 -0700 + + testsuite: Factor out a function to run a matrix of tests + + This commons up code from libffi.call/call.exp and + libffi.special/special.exp, unifies the optimization option matrix + between the two, and makes it easier to add more axes to the matrix + in the future. + +commit dfdb02cc869855d3b68571e5f7aa77ae8c9d254a +Author: Josh Triplett +Date: Sun Mar 16 15:26:26 2014 -0700 + + testsuite: Introduce a __THISCALL__ compiler-specific macro + +commit 83fd2bce0456224483435d4b764063f4513fd464 +Merge: 3658a07 06ff924 +Author: Anthony Green +Date: Sun Mar 16 22:03:29 2014 -0400 + + Merge pull request #99 from joshtriplett/gitignore + + .gitignore: Ignore more generated files + +commit 3658a0700a50d37a2fdba04fd9d79ad2f706d9f5 +Merge: d948d0a 46c5d3c +Author: Anthony Green +Date: Sun Mar 16 21:37:42 2014 -0400 + + Merge pull request #100 from rvandermeulen/bug-756740 + + Change double quotes in Makefile.am to single quotes. + +commit 46c5d3c30fdc2b43c076ad955078d7c5f1e75b37 +Author: Ryan VanderMeulen +Date: Sun Mar 16 21:16:08 2014 -0400 + + Change double quotes in Makefile.am to single quotes. + + This was originally done in PR #84, except the change was made to Makefile.in instead of Makefile.am and was therefore reverted the next time the files were regenerated. + +commit 06ff924215a2f9739efa2c059dc595bc4ec1c851 +Author: Josh Triplett +Date: Sun Mar 16 16:19:46 2014 -0700 + + .gitignore: Ignore more generated files + + The build process generates doc/libffi.info and fficonfig.h.in, so add + them to .gitignore. + +commit bad8948346e9b8813023a0cc78a3b6eb8d9c14c6 +Author: Josh Triplett +Date: Sun Mar 16 15:16:18 2014 -0700 - * Makefile.am (EXTRA_DIST): Add libtool-ldflags. - * Makefile.in: Rebuilt. - * libtool-ldflags: New file. + testsuite: Introduce a __STDCALL__ compiler-specific macro + + Several tests want to use stdcall, which differs in syntax by compiler, + so introduce a macro for it in ffitest.h. -2013-02-07 Daniel Schepler +commit 98a793fa36a4ab3ba24d059cb80a2891cdb940e1 +Author: Josh Triplett +Date: Sun Mar 16 15:20:36 2014 -0700 - * configure.ac: Correctly identify x32 systems as 64-bit. - * m4/libtool.m4: Remove libtool expr error. - * aclocal.m4, configure: Rebuilt. + testsuite: Common up the ifdef blocks for compiler-specific macros -2013-02-07 Anthony Green +commit d948d0a729c934b0224749338a3ba0a2c8f51c45 +Merge: b61b472 a86bd31 +Author: Anthony Green +Date: Sun Mar 16 10:53:48 2014 -0400 - * configure.ac: Fix GCC usage test. - * configure: Rebuilt. - * README: Mention LLVM/GCC x86_64 issue. - * testsuite/Makefile.in: Rebuilt. + Merge pull request #98 from joshtriplett/unconfigure.host + + Merge configure.host into configure.ac -2013-02-07 Anthony Green +commit a86bd318e2424d879d784ee7b29d6536d7a17c18 +Author: Josh Triplett +Date: Sun Mar 16 06:58:59 2014 -0700 - * testsuite/libffi.call/cls_double_va.c (main): Replace // style - comments with /* */ for xlc compiler. - * testsuite/libffi.call/stret_large.c (main): Ditto. - * testsuite/libffi.call/stret_large2.c (main): Ditto. - * testsuite/libffi.call/nested_struct1.c (main): Ditto. - * testsuite/libffi.call/huge_struct.c (main): Ditto. - * testsuite/libffi.call/float_va.c (main): Ditto. - * testsuite/libffi.call/cls_struct_va1.c (main): Ditto. - * testsuite/libffi.call/cls_pointer_stack.c (main): Ditto. - * testsuite/libffi.call/cls_pointer.c (main): Ditto. - * testsuite/libffi.call/cls_longdouble_va.c (main): Ditto. + Merge configure.host into configure.ac + + configure.host only has a single entry, and shows no signs of needing + more added. -2013-02-06 Anthony Green +commit b61b472bd0647006d6685238721002017f1d119c +Author: Anthony Green +Date: Sun Mar 16 09:45:55 2014 -0400 - * man/ffi_prep_cif.3: Clean up for debian lintian checker. + Update version to 3.1-rc0. Clean up README. -2013-02-06 Anthony Green +commit 7a64e7dbba54e6e9f69954adfb943be1856ff928 +Merge: 11a5c5c eef2e02 +Author: Anthony Green +Date: Sun Mar 16 09:39:08 2014 -0400 - * Makefile.am (pkgconfigdir): Add missing pkgconfig install bits. - * Makefile.in: Rebuild. + Merge pull request #97 from joshtriplett/remove-more-generated-files + + Remove more generated files -2013-02-02 Mark H Weaver +commit 11a5c5c39f5861011f6c5ddf795da3a32b5f0082 +Merge: 9a62a21 1c68c07 +Author: Anthony Green +Date: Sun Mar 16 09:38:47 2014 -0400 + + Merge pull request #96 from joshtriplett/sawing-changelogs + + Generate ChangeLog from git in make dist; remove it from version control - * src/x86/ffi64.c (ffi_call): Sign-extend integer arguments passed - via general purpose registers. +commit eef2e02a13d7d1c8145d47a64467f654406a3548 +Author: Josh Triplett +Date: Sun Mar 16 06:26:03 2014 -0700 -2013-01-21 Nathan Rossi + doc: Remove autogenerated info file and stamp - * README: Add MicroBlaze details. - * Makefile.am: Add MicroBlaze support. - * configure.ac: Likewise. - * src/microblaze/ffi.c: New. - * src/microblaze/ffitarget.h: Likewise. - * src/microblaze/sysv.S: Likewise. +commit 9fb403d3c5d9643e0f561cab6d4a07b1e54907ff +Author: Josh Triplett +Date: Sun Mar 16 06:25:52 2014 -0700 + + fficonfig.h.in: Remove, configure generates it + +commit 1c68c07217fda78a779778c1480fedef7a58d5b4 +Author: Josh Triplett +Date: Sun Mar 16 06:11:58 2014 -0700 + + Generate ChangeLog from git in make dist + + Archive the existing ChangeLog to ChangeLog.libffi-3.1 -2013-01-21 Nathan Rossi - * testsuite/libffi.call/return_uc.c: Fixed issue. +commit c65ed55e655711e008282edbdd82ce95d008b4f6 +Author: Josh Triplett +Date: Sun Mar 16 05:52:00 2014 -0700 + + ChangeLog.v1: Fix typo in explanatory header. -2013-01-21 Chris Zankel +commit 9a62a21f5c3a8e1da463229f3170c8ab3031d920 +Author: Anthony Green +Date: Sun Mar 16 09:03:57 2014 -0400 - * README: Add Xtensa support. - * Makefile.am: Likewise. - * configure.ac: Likewise. - * Makefile.in Regenerate. - * configure: Likewise. - * src/prep_cif.c: Handle Xtensa. - * src/xtensa: New directory. - * src/xtensa/ffi.c: New file. - * src/xtensa/ffitarget.h: Ditto. - * src/xtensa/sysv.S: Ditto. + Add missing ChangeLog entry. Clean up some entries. + +commit 9bc704c58cb7a049d867837e3a11e2e31886ec66 +Merge: 694447a e892e58 +Author: Anthony Green +Date: Sun Mar 16 08:41:00 2014 -0400 -2013-01-11 Anthony Green + Merge pull request #95 from joshtriplett/news + + README: Update news for 3.0.14 - * src/powerpc/ffi_darwin.c (ffi_prep_args): Replace // style - comments with /* */ for xlc compiler. - * src/powerpc/aix.S (ffi_call_AIX): Ditto. - * testsuite/libffi.call/ffitest.h (allocate_mmap): Delete - deprecated inline function. - * testsuite/libffi.special/ffitestcxx.h: Ditto. - * README: Add update for AIX support. +commit e892e581d1838a06c18c7ecd50ebd79915cff92b +Author: Josh Triplett +Date: Sun Mar 16 05:38:24 2014 -0700 -2013-01-11 Anthony Green + README: Update news for 3.0.14 - * configure.ac: Robustify pc relative reloc check. - * m4/ax_cc_maxopt.m4: Don't -malign-double. This is an ABI - changing option for 32-bit x86. - * aclocal.m4, configure: Rebuilt. - * README: Update supported target list. +commit 694447aa29deadd571efb4e9a26ee3f68ede1493 +Merge: fdc87f3 45a6c21 +Author: Anthony Green +Date: Sun Mar 16 08:32:05 2014 -0400 -2013-01-10 Anthony Green + Merge pull request #93 from joshtriplett/travis-dist + + Make Travis check "make dist" + +commit 45a6c21efa944b520842e631dc54919b04884744 +Author: Josh Triplett +Date: Sun Mar 16 05:29:08 2014 -0700 + + .travis.yml: Test "make dist" too. + +commit fdc87f3b2ea37b58a4a9ae6c35083f544909fe3c +Merge: 7412b83 e1911f7 +Author: Anthony Green +Date: Sun Mar 16 08:05:51 2014 -0400 + + Merge pull request #85 from joshtriplett/stdcall + + stdcall support on Linux + +commit e1911f78df113ca58738b66089a070d4cf747de7 +Author: Josh Triplett +Date: Sun Mar 16 03:25:53 2014 -0700 + + Add support for stdcall, thiscall, and fastcall on non-Windows x86-32 + + Linux supports the stdcall calling convention, either via functions + explicitly declared with the stdcall attribute, or via code compiled + with -mrtd which effectively makes stdcall the default. + + This introduces FFI_STDCALL, FFI_THISCALL, and FFI_FASTCALL on + non-Windows x86-32 platforms, as non-default calling conventions. + +commit 7412b838d543aae4fa925862bd5702d3dacbc29a +Merge: c0cc5fd 9531d05 +Author: Anthony Green +Date: Sun Mar 16 07:58:16 2014 -0400 + + Merge pull request #90 from joshtriplett/win32-unifdef + + prep_cif.c: Remove unnecessary ifdef for X86_WIN32 + +commit c0cc5fdaa237b67e86f22d2f6e13f3b42d9aae33 +Merge: 98b5296 b3a5da0 +Author: Anthony Green +Date: Sun Mar 16 07:57:59 2014 -0400 + + Merge pull request #89 from joshtriplett/travis32 + + .travis.yml: Test on both 32-bit and 64-bit + +commit 9531d05f64c2a674e0197158ffad68d69f177bd0 +Author: Josh Triplett +Date: Sun Mar 16 01:50:02 2014 -0700 + + prep_cif.c: Remove unnecessary ifdef for X86_WIN32 + + ffi_prep_cif_core had a special case for X86_WIN32, checking for + FFI_THISCALL in addition to the FFI_FIRST_ABI-to-FFI_LAST_ABI range + before returning FFI_BAD_ABI. However, on X86_WIN32, FFI_THISCALL + already falls in that range, making the special case unnecessary. + Remove it. + +commit b3a5da068abd2f2983d9e67adbf41b0e0f34e37f +Author: Josh Triplett +Date: Sat Mar 15 23:27:56 2014 -0700 + + .travis.yml: Test on both 32-bit and 64-bit + +commit 98b52960485a261399f081915f36063de3854a5f +Merge: 134ce4c f6dd184 +Author: Anthony Green +Date: Sun Mar 16 07:51:33 2014 -0400 + + Merge pull request #94 from joshtriplett/esp-extra-stackery-perception + + ChangeLog: Document testsuite changes to remove fragile stack pointer checks + +commit f6dd1845434dd53e22129becdfa092c082df307c +Author: Josh Triplett +Date: Sun Mar 16 04:49:36 2014 -0700 + + ChangeLog: Document testsuite changes to remove fragile stack pointer checks + +commit 134ce4c0266bf994f07518fc534de53f1d3c8de8 +Merge: 2680e9e 9c27932 +Author: Anthony Green +Date: Sun Mar 16 07:47:17 2014 -0400 + + Merge pull request #91 from joshtriplett/esp-extra-stackery-perception + + testsuite: Remove fragile stack pointer checks + +commit 9c279328ee12fc869adff63ca81f1230977bd42b +Author: Josh Triplett +Date: Sun Mar 16 02:31:19 2014 -0700 + + testsuite: Remove fragile stack pointer checks + + testsuite/libffi.call/closure_stdcall.c and + testsuite/libffi.call/closure_thiscall.c include inline assembly to save + the stack pointer before and after the call, and compare the values. + However, compilers can and do leave the stack in different states for + these two pieces of inline assembly, such as by saving a temporary value + on the stack across the call; observed with gcc -Os, and verified as + spurious through careful inspection of disassembly. + +commit 2680e9ea9b4c87ea8042a61e551bd667493d4bd3 +Merge: 071eab3 82f8cb2 +Author: Anthony Green +Date: Sun Mar 16 07:44:08 2014 -0400 + + Merge pull request #88 from joshtriplett/such-precision-many-fail-wow + + testsuite/libffi.call/many.c: Avoid spurious failure due to excess precision + +commit 82f8cb24a1d976db35ae31a4b86cec8926da327d +Author: Josh Triplett +Date: Sun Mar 16 04:27:32 2014 -0700 + + ChangeLog: Document many.c and many_win32.c changes to avoid spurious failures + +commit 88d562a8b5912e99306063fe3bc289bab6ca6ebe +Author: Josh Triplett +Date: Sat Mar 15 22:08:19 2014 -0700 + + testsuite/libffi.call/many_win32.c: Avoid spurious failure due to excess precision + + The test case testsuite/libffi.call/many_win32.c can spuriously fail due + to excess floating-point precision. Instrumenting it with some printf + calls shows differences well above FLT_EPSILON. (Note when + instrumenting it that multiple computations of the difference, such as + one in a print and another in the conditional, may produce different + results.) + + Rather than complicating the test suite with architecture-specific flags + to avoid excess precision, just simplify the floating-point computation + to avoid a dependency on potential excess precision. + +commit c00a49ecd165b2d06c1c9b249d212dc843fa116f +Author: Josh Triplett +Date: Sat Mar 15 22:08:19 2014 -0700 + + testsuite/libffi.call/many.c: Avoid spurious failure due to excess precision + + The test case testsuite/libffi.call/many.c can spuriously fail due to + excess floating-point precision. Instrumenting it with some printf + calls shows differences well above FLT_EPSILON. (Note when + instrumenting it that multiple computations of the difference, such as + one in a print and another in the conditional, may produce different + results.) + + Rather than complicating the test suite with architecture-specific flags + to avoid excess precision, just simplify the floating-point computation + to avoid a dependency on potential excess precision. + +commit 071eab32a7f9fbbef46c0d8f37d9985bc9cceb37 +Merge: 2228c7a 2f44952 +Author: Anthony Green +Date: Sun Mar 16 07:36:52 2014 -0400 + + Merge pull request #92 from joshtriplett/autogen + + Re-add libtool-ldflags + +commit 2f44952c95765c1486fad66f57235f8d459a9748 +Author: Josh Triplett +Date: Sun Mar 16 04:35:12 2014 -0700 + + Re-add libtool-ldflags + +commit 2228c7ab190f3c529b9018495467b841fa21cba2 +Merge: 76d19d0 35634db +Author: Anthony Green +Date: Sun Mar 16 07:25:18 2014 -0400 + + Merge pull request #87 from joshtriplett/autogen + + Remove autogenerated files from the repository + +commit 35634dbceaac0a1544f7385addc01d21ef1ef6a8 +Author: Josh Triplett +Date: Sat Mar 15 18:11:16 2014 -0700 + + Remove autogenerated files from the repository + + Add an autogen.sh to regenerate them. + +commit 76d19d004e36e99d261ee78261e2f52cea5e4ab1 +Merge: c86d9b6 a1a6f71 +Author: Anthony Green +Date: Fri Mar 14 16:54:31 2014 -0400 + + Ensure the linker supports @unwind sections in libffi. + +commit c86d9b6cc6e16ee262844a33b40441374400758c +Merge: 4efb7db f8cdf11 +Author: Anthony Green +Date: Fri Mar 14 16:51:20 2014 -0400 + + Fix merge + +commit 4efb7dbfd9427c478a948cd0d464210123db8de8 +Merge: 634a475 18eb81d +Author: Anthony Green +Date: Fri Mar 14 16:47:57 2014 -0400 + + Merge pull request #81 from rvandermeulen/bug-756740 + + Allow building for mipsel with Android NDK r8. + +commit a1a6f71bfe4199293043b2e4cfb4c8d3cb1112f9 +Author: Ryan VanderMeulen +Date: Mon Mar 10 15:12:47 2014 -0400 + + Remove stray hunk that shouldn't have been included in this patch. + +commit f8cdf11467181f2a9a6b7e748167569aa58e3a81 +Author: Ryan VanderMeulen +Date: Mon Mar 10 15:04:58 2014 -0400 + + Replace double quotes with single quotes in Makefile.in to improve compatibility between some versions of MSYS and gmake. From Mozilla bug 943728. + https://bugzilla.mozilla.org/show_bug.cgi?id=943728 + +commit dfa3738732e1bc3a7f4130395ae4bab55fcebb99 +Author: Ryan VanderMeulen +Date: Mon Mar 10 14:53:48 2014 -0400 + + Ensure the linker supports @unwind sections in libffi. From Mozilla bug 756740. + https://bugzilla.mozilla.org/show_bug.cgi?id=778414 + + Also tracked as issue #42. + https://github.com/atgreen/libffi/issues/42 + +commit 18eb81d032f29d645d0498ba92bddfd651f009ae +Author: Ryan VanderMeulen +Date: Mon Mar 10 14:43:37 2014 -0400 - * README (tested): Add Compiler column to table. + Allow building for mipsel with Android NDK r8. From Mozilla bug 756740. + https://bugzilla.mozilla.org/show_bug.cgi?id=756740 -2013-01-10 Anthony Green +commit 2349fec9a818fb52fd2f294bcbc7b3156cd113de +Author: Daiki Ueno +Date: Wed Mar 5 17:53:02 2014 +0900 - * src/x86/ffi64.c (struct register_args): Make sse array and array - of unions for sunpro compiler compatibility. + Fix typo in doc -2013-01-10 Anthony Green +commit 634a475eaf1bee31c09f7d519e31c13b64cd24df +Author: Anthony Green +Date: Sat Mar 1 18:37:29 2014 -0500 - * configure.ac: Test target platform size_t size. Handle both 32 - and 64-bit builds for x86_64-* and i?86-* targets (allowing for - CFLAG option to change default settings). - * configure, aclocal.m4: Rebuilt. + Update Makefile for new darwin scripts -2013-01-10 Anthony Green +commit c7b67e874bb89859f9a07d1cf9606052b6c0dcc1 +Author: Anthony Green +Date: Sat Mar 1 18:34:18 2014 -0500 - * testsuite/libffi.special/special.exp: Only run exception - handling tests when using GNU compiler. + Add README note - * m4/ax_compiler_vendor.m4: New file. - * configure.ac: Test for compiler vendor and don't use - AX_CFLAGS_WARN_ALL with the sun compiler. - * aclocal.m4, configure: Rebuilt. +commit a04e30ba3dc303133d459c1ac273ceefe4d49b32 +Author: Anthony Green +Date: Fri Feb 28 17:20:59 2014 -0500 -2013-01-10 Anthony Green + Add missing -DFFI_DEBUG flag - * include/ffi_common.h: Don't use GCCisms to define types when - building with the SUNPRO compiler. +commit 934dc1b5c8d6a9e727bedc72342831eb7d62c35f +Merge: 11d7aa9 67fbef3 +Author: Anthony Green +Date: Fri Feb 28 01:10:17 2014 -0500 -2013-01-10 Anthony Green + Merge branch 'master' of github.com:/atgreen/libffi - * configure.ac: Put local.exp in the right place. - * configure: Rebuilt. +commit 11d7aa9d7a4bbe642944edc0f07cf96db9b270b6 +Merge: b40aeda 3b44d41 +Author: Anthony Green +Date: Fri Feb 28 01:06:48 2014 -0500 - * src/x86/ffi.c: Update comment about regparm function attributes. - * src/x86/sysv.S (ffi_closure_SYSV): The SUNPRO compiler requires - that all function arguments be passed on the stack (no regparm - support). + Merge pull request #46 from makotokato/android-clang + + Fix build failure when using clang for Android -2013-01-08 Anthony Green +commit 67fbef3b56ff0ef88f9b1a7fe48cb77222fa6cec +Merge: b40aeda 3b44d41 +Author: Anthony Green +Date: Fri Feb 28 01:06:48 2014 -0500 - * configure.ac: Generate local.exp. This sets CC_FOR_TARGET - when we are using the vendor compiler. - * testsuite/Makefile.am (EXTRA_DEJAGNU_SITE_CONFIG): Point to - ../local.exp. - * configure, testsuite/Makefile.in: Rebuilt. + Merge pull request #46 from makotokato/android-clang + + Fix build failure when using clang for Android - * testsuite/libffi.call/call.exp: Run tests with different - options, depending on whether or not we are using gcc or the - vendor compiler. - * testsuite/lib/libffi.exp (libffi-init): Set using_gcc based on - whether or not we are building/testing with gcc. +commit b40aeda31a74d95a37c723b6243aabac466e67c4 +Merge: 20698ab 53ceaf1 +Author: Anthony Green +Date: Fri Feb 28 01:01:29 2014 -0500 -2013-01-08 Anthony Green + Merge branch 'master' of github.com:/atgreen/libffi - * configure.ac: Switch x86 solaris target to X86 by default. - * configure: Rebuilt. +commit 53ceaf14c5eeb16ba09745f0ca87cca367d41a90 +Merge: 860fe66 cc9b518 +Author: Anthony Green +Date: Fri Feb 28 01:01:02 2014 -0500 -2013-01-08 Anthony Green + Merge pull request #40 from wojdyr/master + + Correct the -L flag in libffi.pc.in - * configure.ac: Fix test for read-only eh_frame. - * configure: Rebuilt. +commit 20698abc6a00092fd7fd3e434a3a29dc0f048f1e +Merge: 64bd069 1a0b01e +Author: Anthony Green +Date: Fri Feb 28 00:56:27 2014 -0500 -2013-01-08 Anthony Green + Merge pull request #66 from ppizarro/master + + BlackFin fixes - Fatal error when calling a function defined in a shared library from within the function called by FFI - * src/x86/sysv.S, src/x86/unix64.S: Only emit DWARF unwind info - when building with the GNU toolchain. - * testsuite/libffi.call/ffitest.h (CHECK): Fix for Solaris vendor - compiler. +commit 860fe6646f5ae603e99a8d1d722ddddba8b75769 +Merge: 64bd069 1a0b01e +Author: Anthony Green +Date: Fri Feb 28 00:56:27 2014 -0500 -2013-01-07 Thorsten Glaser + Merge pull request #66 from ppizarro/master + + BlackFin fixes - Fatal error when calling a function defined in a shared library from within the function called by FFI - * testsuite/libffi.call/cls_uchar_va.c, - testsuite/libffi.call/cls_ushort_va.c, - testsuite/libffi.call/va_1.c: Testsuite fixes. +commit 64bd06990a7accf72271516a2110b86cdccd8df4 +Author: Anthony Green +Date: Fri Feb 28 00:52:56 2014 -0500 -2013-01-07 Thorsten Glaser + Add ChangeLog entry for Josh's change - * src/m68k/ffi.c (CIF_FLAGS_SINT8, CIF_FLAGS_SINT16): Define. - (ffi_prep_cif_machdep): Fix 8-bit and 16-bit signed calls. - * src/m68k/sysv.S (ffi_call_SYSV, ffi_closure_SYSV): Ditto. +commit edf29c5169b06fcfc241445e152e325bc3c50e0e +Merge: 33c9954 3998d26 +Author: Anthony Green +Date: Fri Feb 28 00:50:25 2014 -0500 -2013-01-04 Anthony Green + Merge pull request #75 from joshtriplett/longdouble + + Fix build error on x86 without distinct long double - * Makefile.am (AM_CFLAGS): Don't automatically add -fexceptions - and -Wall. This is set in the configure script after testing for - GCC. - * Makefile.in: Rebuilt. +commit 33c9954f2eec539011a0f93270aaf013318837ae +Author: Anthony Green +Date: Fri Feb 28 00:38:41 2014 -0500 -2013-01-02 rofl0r + Rebuilt with new libtool - * src/powerpc/ffi.c (ffi_prep_cif_machdep): Fix build error on ppc - when long double == double. +commit 926b6989fbd08488b9105943293353d45ac527e0 +Merge: 5a88c85 cc82051 +Author: Anthony Green +Date: Fri Feb 28 00:26:57 2014 -0500 -2013-01-02 Reini Urban + Merge branch 'master' of github.com:/atgreen/libffi + + Conflicts: + ChangeLog - * Makefile.am (libffi_la_LDFLAGS): Add -no-undefined to LDFLAGS - (required for shared libs on cygwin/mingw). - * Makefile.in: Rebuilt. +commit 5a88c85fde304052bed1581ed0b6452ac2c68838 +Author: Anthony Green +Date: Fri Feb 28 00:23:04 2014 -0500 -2012-10-31 Alan Modra + Fix spelling errors - * src/powerpc/linux64_closure.S: Add new ABI support. - * src/powerpc/linux64.S: Likewise. +commit cc82051c7e80cea772c4b72da026eb7e68d598fc +Author: Anthony Green +Date: Fri Feb 28 00:23:04 2014 -0500 -2012-10-30 Magnus Granberg - Pavel Labushev + Fix spelling errors - * configure.ac: New options pax_emutramp - * configure, fficonfig.h.in: Regenerated - * src/closures.c: New function emutramp_enabled_check() and - checks. +commit 001aaf4b1b56349596bb6f6b5c1613dcbbd84ea8 +Author: Anthony Green +Date: Fri Feb 28 00:20:17 2014 -0500 -2012-10-30 Frederick Cheung + When no VFP arguments are present the IP register is used + uninitialized. Initialize it to the value of FP. + + This fixes a number of testsuite failures when configured for + armv7l-unknown-linux-gnueabihf - * configure.ac: Enable FFI_MAP_EXEC_WRIT for Darwin 12 (mountain - lion) and future version. - * configure: Rebuild. +commit 49f7729c3ce697c12408c42ccb29cdf4eb66bb85 +Author: Anthony Green +Date: Fri Feb 28 00:17:16 2014 -0500 -2012-10-30 James Greenhalgh - Marcus Shawcroft + aarch64 fix - * README: Add details of aarch64 port. - * src/aarch64/ffi.c: New. - * src/aarch64/ffitarget.h: Likewise. - * src/aarch64/sysv.S: Likewise. - * Makefile.am: Support aarch64. - * configure.ac: Support aarch64. - * Makefile.in, configure: Rebuilt. +commit 447483d51c6aa9df7116f346a73fc1cf795f4c2b +Merge: 51377bd b4df9cf +Author: Anthony Green +Date: Thu Feb 27 15:42:41 2014 -0500 -2012-10-30 James Greenhalgh - Marcus Shawcroft + Fix ChangeLog merge - * testsuite/lib/libffi.exp: Add support for aarch64. - * testsuite/libffi.call/cls_struct_va1.c: New. - * testsuite/libffi.call/cls_uchar_va.c: Likewise. - * testsuite/libffi.call/cls_uint_va.c: Likewise. - * testsuite/libffi.call/cls_ulong_va.c: Likewise. - * testsuite/libffi.call/cls_ushort_va.c: Likewise. - * testsuite/libffi.call/nested_struct11.c: Likewise. - * testsuite/libffi.call/uninitialized.c: Likewise. - * testsuite/libffi.call/va_1.c: Likewise. - * testsuite/libffi.call/va_struct1.c: Likewise. - * testsuite/libffi.call/va_struct2.c: Likewise. - * testsuite/libffi.call/va_struct3.c: Likewise. +commit 3998d2604b5c0d45a098ff3119a9fd9710ef429d +Author: Josh Triplett +Date: Mon Feb 17 11:20:33 2014 -0800 -2012-10-12 Walter Lee + Fix build error on x86 without distinct long double + + src/x86/ffi64.c: In function 'classify_argument': + src/x86/ffi64.c:205:5: error: duplicate case value + case FFI_TYPE_LONGDOUBLE: + ^ + src/x86/ffi64.c:202:5: error: previously used here + case FFI_TYPE_DOUBLE: + ^ - * Makefile.am: Add TILE-Gx/TILEPro support. - * configure.ac: Likewise. - * Makefile.in: Regenerate. - * configure: Likewise. - * src/prep_cif.c (ffi_prep_cif_core): Handle TILE-Gx/TILEPro. - * src/tile: New directory. - * src/tile/ffi.c: New file. - * src/tile/ffitarget.h: Ditto. - * src/tile/tile.S: Ditto. +commit 51377bda9aed0b2c1309c818460cab9d9ab3d46e +Merge: f08da54 40927bd +Author: Anthony Green +Date: Sat Feb 15 08:06:29 2014 -0500 -2012-10-12 Matthias Klose + Merge pull request #72 from heiher/devel + + MIPS N32: Fix call floating point va function - * generate-osx-source-and-headers.py: Normalize whitespace. +commit f08da5465463e60a28f5e921f23ebf2ba984c148 +Merge: 3dc3f32 fa5f25c +Author: Anthony Green +Date: Sat Feb 15 08:06:11 2014 -0500 -2012-09-14 David Edelsohn + Merge pull request #68 from zeldin/master + + Linux/ppc64: Remove assumption on contents of r11 in closure - * configure: Regenerated. +commit 40927bd3e1e7c6007025ba10854fd8a0664e47df +Author: Heiher +Date: Tue Jan 21 23:18:27 2014 +0800 -2012-08-26 Andrew Pinski + Fix call floating point va function + + I'm not sure floating-point arguments in GPR or FPR before calling + variable number arguments function. so, load all arguments to GPR and + FPR. - PR libffi/53014 - * src/mips/ffi.c (ffi_prep_closure_loc): Allow n32 with soft-float and n64 with - soft-float. +commit b4df9cf9cc4a9a9401a53fd6bea1f3c2c283b97b +Author: Zachary Waldowski +Date: Wed Feb 5 14:22:52 2014 -0500 -2012-08-08 Uros Bizjak + AArch64: Fix void fall-through case when assertions are enabled - * src/s390/ffi.c (ffi_prep_closure_loc): Don't ASSERT ABI test, - just return FFI_BAD_ABI when things are wrong. +commit f466aad0d91a117e42571d1d6fb434fa0433c930 +Author: Zachary Waldowski +Date: Tue Jan 21 16:38:31 2014 -0500 -2012-07-18 H.J. Lu + AArch64: Fix missing semicolons when assertions are enabled - PR libffi/53982 - PR libffi/53973 - * src/x86/ffitarget.h: Check __ILP32__ instead of __LP64__ for x32. - (FFI_SIZEOF_JAVA_RAW): Defined to 4 for x32. +commit 7ea677733bd98917241852b8901a6b7580728895 +Author: Anthony Green +Date: Sat Nov 30 20:58:31 2013 -0500 -2012-05-16 H.J. Lu + Remove build-ios from Makefile + + Conflicts: + ChangeLog - * configure: Regenerated. +commit 6ae046cc59c12b2cd40158d6bcb96f4a59886159 +Author: Anthony Green +Date: Sat Nov 30 21:06:51 2013 -0500 -2012-05-05 Nicolas Lelong + Mention Aarch64 on iOS - * libffi.xcodeproj/project.pbxproj: Fixes. - * README: Update for iOS builds. +commit bfc06b3fdb32abe90ce0749aedfec649df85a7ef +Author: Zachary Waldowski +Date: Mon Dec 30 17:36:39 2013 -0500 -2012-04-23 Alexandre Keunecke I. de Mendonca + Update ChangeLog - * configure.ac: Add Blackfin/sysv support - * Makefile.am: Add Blackfin/sysv support - * src/bfin/ffi.c: Add Blackfin/sysv support - * src/bfin/ffitarget.h: Add Blackfin/sysv support +commit 0a0f12ce1f7be81006b08a3c81a636926d283a9b +Author: Zachary Waldowski +Date: Thu Jan 9 13:50:17 2014 -0500 -2012-04-11 Anthony Green + AArch64: Remove duplicitous element_count call. + + This inhibits an analyzer warning by Clang. - * Makefile.am (EXTRA_DIST): Add new script. - * Makefile.in: Rebuilt. +commit 4330fdcd92e67c816288d64ab230237065768206 +Author: Zachary Waldowski +Date: Thu Jan 9 13:53:30 2014 -0500 -2012-04-11 Zachary Waldowski + Darwin/aarch64: Respect iOS ABI re: stack argument alignment - * generate-ios-source-and-headers.py, - libffi.xcodeproj/project.pbxproj: Support a Mac static library via - Xcode. Set iOS compatibility to 4.0. Move iOS trampoline - generation into an Xcode "run script" phase. Include both as - Xcode build scripts. Don't always regenerate config files. +commit 0a333d6c3973935d4fe02aae76b10e39d3c88e07 +Author: Zachary Waldowski +Date: Thu Jan 9 14:03:29 2014 -0500 -2012-04-10 Anthony Green + Darwin/aarch64: Fix size_t assumptions - * src/powerpc/ffi_darwin.c (ffi_prep_args): Add missing semicolon. +commit 2c18e3c76aad1b426617db05a4384e7c3a920176 +Author: Zachary Waldowski +Date: Mon Dec 30 16:14:02 2013 -0500 -2012-04-06 Anthony Green + Darwin/aarch64: Fix "shadows declaration" warnings - * Makefile.am (EXTRA_DIST): Add new iOS/xcode files. - * Makefile.in: Rebuilt. +commit 1b8a8e20e344f3c55495ab6eb46bd14e843d4b3e +Author: Zachary Waldowski +Date: Thu Jan 9 13:55:21 2014 -0500 -2012-04-06 Mike Lewis + Darwin/aarch64: Use Clang cache invalidation builtin - * generate-ios-source-and-headers.py: New file. - * libffi.xcodeproj/project.pbxproj: New file. - * README: Update instructions on building iOS binary. - * build-ios.sh: Delete. +commit 6030cdcae776f8fb5876a53168f7d1e75d28a242 +Author: Zachary Waldowski +Date: Mon Dec 30 15:45:51 2013 -0500 -2012-04-06 Anthony Green + Darwin/aarch64: Account for long double being equal to double - * src/x86/ffi64.c (UINT128): Define differently for Intel and GNU - compilers, then use it. +commit 5658b0892683d2e24e4d5842978c184a7ad33858 +Author: Zachary Waldowski +Date: Mon Dec 30 16:33:47 2013 -0500 -2012-04-06 H.J. Lu + Darwin/aarch64: Use CNAME, restrict .size like ARM - * m4/libtool.m4 (_LT_ENABLE_LOCK): Support x32. +commit 07175780802acec5dc49fdedd6d20a62409a6707 +Author: Zachary Waldowski +Date: Mon Dec 30 17:48:22 2013 -0500 -2012-04-06 Anthony Green + Darwin/aarch64: Fix invalid reference in assembly - * testsuite/Makefile.am (EXTRA_DIST): Add missing test cases. - * testsuite/Makefile.in: Rebuilt. +commit 9da28b44277fea3aeb827c35dd63d609d2524a8b +Author: Zachary Waldowski +Date: Mon Dec 30 16:23:21 2013 -0500 -2012-04-05 Zachary Waldowski + Darwin/x86_64: Fix 64-bit type shortening warnings - * include/ffi.h.in: Add missing trampoline table fields. - * src/arm/sysv.S: Fix ENTRY definition, and wrap symbol references - in CNAME. - * src/x86/ffi.c: Wrap Windows specific code in ifdefs. +commit 821d398f08bd1d540a5b235507812ffeee49b580 +Author: Zachary Waldowski +Date: Thu Jan 9 13:15:06 2014 -0500 -2012-04-02 Peter Bergner + Darwin: Merge build scripts, redo project, incl. arm64 - * src/powerpc/ffi.c (ffi_prep_args_SYSV): Declare double_tmp. - Silence casting pointer to integer of different size warning. - Delete goto to previously deleted label. - (ffi_call): Silence possibly undefined warning. - (ffi_closure_helper_SYSV): Declare variable type. +commit 6eff9ff9e72463b9783be2514f944b6f05692054 +Author: Zachary Waldowski +Date: Mon Dec 30 17:48:10 2013 -0500 -2012-04-02 Peter Rosin + Darwin/iOS: Improve unified syntax use for LLVM - * src/x86/win32.S (ffi_call_win32): Sign/zero extend the return - value in the Intel version as is already done for the AT&T version. - (ffi_closure_SYSV): Likewise. - (ffi_closure_raw_SYSV): Likewise. - (ffi_closure_STDCALL): Likewise. +commit ba0ea99c82aadd5957386a031e3122011bd36d52 +Author: Zachary Waldowski +Date: Mon Dec 30 15:27:44 2013 -0500 -2012-03-29 Peter Rosin + Fix dlmalloc warnings due to set_segment_flags, sizeof(size_t) - * src/x86/win32.S (ffi_closure_raw_THISCALL): Unify the frame - generation, fix the ENDP label and remove the surplus third arg - from the 'lea' insn. +commit 994be3a5c1d0d17b19103396103e128517fd62f9 +Author: Zachary Waldowski +Date: Mon Dec 30 15:27:14 2013 -0500 -2012-03-29 Peter Rosin - - * src/x86/win32.S (ffi_closure_raw_SYSV): Make the 'stubraw' label - visible outside the PROC, so that ffi_closure_raw_THISCALL can see - it. Also instruct the assembler to add a frame to the function. - -2012-03-23 Peter Rosin - - * Makefile.am (AM_CPPFLAGS): Add -DFFI_BUILDING. - * Makefile.in: Rebuilt. - * include/ffi.h.in [MSVC]: Add __declspec(dllimport) decorations - to all data exports, when compiling libffi clients using MSVC. - -2012-03-29 Peter Rosin - - * src/x86/ffitarget.h (ffi_abi): Add new ABI FFI_MS_CDECL and - make it the default for MSVC. - (FFI_TYPE_MS_STRUCT): New structure return convention. - * src/x86/ffi.c (ffi_prep_cif_machdep): Tweak the structure - return convention for FFI_MS_CDECL to be FFI_TYPE_MS_STRUCT - instead of an ordinary FFI_TYPE_STRUCT. - (ffi_prep_args): Treat FFI_TYPE_MS_STRUCT as FFI_TYPE_STRUCT. - (ffi_call): Likewise. - (ffi_prep_incoming_args_SYSV): Likewise. - (ffi_raw_call): Likewise. - (ffi_prep_closure_loc): Treat FFI_MS_CDECL as FFI_SYSV. - * src/x86/win32.S (ffi_closure_SYSV): For FFI_TYPE_MS_STRUCT, - return a pointer to the result structure in eax and don't pop - that pointer from the stack, the caller takes care of it. - (ffi_call_win32): Treat FFI_TYPE_MS_STRUCT as FFI_TYPE_STRUCT. - (ffi_closure_raw_SYSV): Likewise. - -2012-03-22 Peter Rosin - - * testsuite/libffi.call/closure_stdcall.c [MSVC]: Add inline - assembly version with Intel syntax. - * testsuite/libffi.call/closure_thiscall.c [MSVC]: Likewise. - -2012-03-23 Peter Rosin - - * testsuite/libffi.call/ffitest.h: Provide abstration of - __attribute__((fastcall)) in the form of a __FASTCALL__ - define. Define it to __fastcall for MSVC. - * testsuite/libffi.call/fastthis1_win32.c: Use the above. - * testsuite/libffi.call/fastthis2_win32.c: Likewise. - * testsuite/libffi.call/fastthis3_win32.c: Likewise. - * testsuite/libffi.call/strlen2_win32.c: Likewise. - * testsuite/libffi.call/struct1_win32.c: Likewise. - * testsuite/libffi.call/struct2_win32.c: Likewise. - -2012-03-22 Peter Rosin - - * src/x86/win32.S [MSVC] (ffi_closure_THISCALL): Remove the manual - frame on function entry, MASM adds one automatically. - -2012-03-22 Peter Rosin - - * testsuite/libffi.call/ffitest.h [MSVC]: Add kludge for missing - bits in the MSVC headers. - -2012-03-22 Peter Rosin - - * testsuite/libffi.call/cls_12byte.c: Adjust to the C89 style - with no declarations after statements. - * testsuite/libffi.call/cls_16byte.c: Likewise. - * testsuite/libffi.call/cls_18byte.c: Likewise. - * testsuite/libffi.call/cls_19byte.c: Likewise. - * testsuite/libffi.call/cls_1_1byte.c: Likewise. - * testsuite/libffi.call/cls_20byte.c: Likewise. - * testsuite/libffi.call/cls_20byte1.c: Likewise. - * testsuite/libffi.call/cls_24byte.c: Likewise. - * testsuite/libffi.call/cls_2byte.c: Likewise. - * testsuite/libffi.call/cls_3_1byte.c: Likewise. - * testsuite/libffi.call/cls_3byte1.c: Likewise. - * testsuite/libffi.call/cls_3byte2.c: Likewise. - * testsuite/libffi.call/cls_4_1byte.c: Likewise. - * testsuite/libffi.call/cls_4byte.c: Likewise. - * testsuite/libffi.call/cls_5_1_byte.c: Likewise. - * testsuite/libffi.call/cls_5byte.c: Likewise. - * testsuite/libffi.call/cls_64byte.c: Likewise. - * testsuite/libffi.call/cls_6_1_byte.c: Likewise. - * testsuite/libffi.call/cls_6byte.c: Likewise. - * testsuite/libffi.call/cls_7_1_byte.c: Likewise. - * testsuite/libffi.call/cls_7byte.c: Likewise. - * testsuite/libffi.call/cls_8byte.c: Likewise. - * testsuite/libffi.call/cls_9byte1.c: Likewise. - * testsuite/libffi.call/cls_9byte2.c: Likewise. - * testsuite/libffi.call/cls_align_double.c: Likewise. - * testsuite/libffi.call/cls_align_float.c: Likewise. - * testsuite/libffi.call/cls_align_longdouble.c: Likewise. - * testsuite/libffi.call/cls_align_longdouble_split.c: Likewise. - * testsuite/libffi.call/cls_align_longdouble_split2.c: Likewise. - * testsuite/libffi.call/cls_align_pointer.c: Likewise. - * testsuite/libffi.call/cls_align_sint16.c: Likewise. - * testsuite/libffi.call/cls_align_sint32.c: Likewise. - * testsuite/libffi.call/cls_align_sint64.c: Likewise. - * testsuite/libffi.call/cls_align_uint16.c: Likewise. - * testsuite/libffi.call/cls_align_uint32.c: Likewise. - * testsuite/libffi.call/cls_align_uint64.c: Likewise. - * testsuite/libffi.call/cls_dbls_struct.c: Likewise. - * testsuite/libffi.call/cls_pointer_stack.c: Likewise. - * testsuite/libffi.call/err_bad_typedef.c: Likewise. - * testsuite/libffi.call/huge_struct.c: Likewise. - * testsuite/libffi.call/nested_struct.c: Likewise. - * testsuite/libffi.call/nested_struct1.c: Likewise. - * testsuite/libffi.call/nested_struct10.c: Likewise. - * testsuite/libffi.call/nested_struct2.c: Likewise. - * testsuite/libffi.call/nested_struct3.c: Likewise. - * testsuite/libffi.call/nested_struct4.c: Likewise. - * testsuite/libffi.call/nested_struct5.c: Likewise. - * testsuite/libffi.call/nested_struct6.c: Likewise. - * testsuite/libffi.call/nested_struct7.c: Likewise. - * testsuite/libffi.call/nested_struct8.c: Likewise. - * testsuite/libffi.call/nested_struct9.c: Likewise. - * testsuite/libffi.call/stret_large.c: Likewise. - * testsuite/libffi.call/stret_large2.c: Likewise. - * testsuite/libffi.call/stret_medium.c: Likewise. - * testsuite/libffi.call/stret_medium2.c: Likewise. - * testsuite/libffi.call/struct1.c: Likewise. - * testsuite/libffi.call/struct1_win32.c: Likewise. - * testsuite/libffi.call/struct2.c: Likewise. - * testsuite/libffi.call/struct2_win32.c: Likewise. - * testsuite/libffi.call/struct3.c: Likewise. - * testsuite/libffi.call/struct4.c: Likewise. - * testsuite/libffi.call/struct5.c: Likewise. - * testsuite/libffi.call/struct6.c: Likewise. - * testsuite/libffi.call/struct7.c: Likewise. - * testsuite/libffi.call/struct8.c: Likewise. - * testsuite/libffi.call/struct9.c: Likewise. - * testsuite/libffi.call/testclosure.c: Likewise. - -2012-03-21 Peter Rosin - - * testsuite/libffi.call/float_va.c (float_va_fn): Use %f when - printing doubles (%lf is for long doubles). - (main): Likewise. - -2012-03-21 Peter Rosin - - * testsuite/lib/target-libpath.exp [*-*-cygwin*, *-*-mingw*] - (set_ld_library_path_env_vars): Add the library search dir to PATH - (and save PATH for later). - (restore_ld_library_path_env_vars): Restore PATH. - -2012-03-21 Peter Rosin - - * testsuite/lib/target-libpath.exp [*-*-cygwin*, *-*-mingw*] - (set_ld_library_path_env_vars): Add the library search dir to PATH - (and save PATH for later). - (restore_ld_library_path_env_vars): Restore PATH. - -2012-03-20 Peter Rosin - - * testsuite/libffi.call/strlen2_win32.c (main): Remove bug. - * src/x86/win32.S [MSVC] (ffi_closure_SYSV): Make the 'stub' label - visible outside the PROC, so that ffi_closure_THISCALL can see it. - -2012-03-20 Peter Rosin - - * testsuite/libffi.call/strlen2_win32.c (main): Remove bug. - * src/x86/win32.S [MSVC] (ffi_closure_SYSV): Make the 'stub' label - visible outside the PROC, so that ffi_closure_THISCALL can see it. - -2012-03-19 Alan Hourihane - - * src/m68k/ffi.c: Add MINT support. - * src/m68k/sysv.S: Ditto. - -2012-03-06 Chung-Lin Tang - - * src/arm/ffi.c (ffi_call): Add __ARM_EABI__ guard around call to - ffi_call_VFP(). - (ffi_prep_closure_loc): Add __ARM_EABI__ guard around use of - ffi_closure_VFP. - * src/arm/sysv.S: Add __ARM_EABI__ guard around VFP code. - -2012-03-19 chennam - - * src/powerpc/ffi_darwin.c (ffi_prep_closure_loc): Fix AIX closure - support. - -2012-03-13 Kaz Kojima - - * src/sh/ffi.c (ffi_prep_closure_loc): Don't ASSERT ABI test, - just return FFI_BAD_ABI when things are wrong. - * src/sh64/ffi.c (ffi_prep_closure_loc): Ditto. - -2012-03-09 David Edelsohn - - * src/powerpc/aix_closure.S (ffi_closure_ASM): Adjust for Darwin64 - change to return value of ffi_closure_helper_DARWIN and load type - from return type. - -2012-03-03 H.J. Lu - - * src/x86/ffi64.c (ffi_call): Cast the return value to unsigned - long. - (ffi_prep_closure_loc): Cast to 64bit address in trampoline. - (ffi_closure_unix64_inner): Cast return pointer to unsigned long - first. + Darwin/iOS: Fix mis-typing of vfp_reg_free - * src/x86/ffitarget.h (FFI_SIZEOF_ARG): Defined to 8 for x32. - (ffi_arg): Set to unsigned long long for x32. - (ffi_sarg): Set to long long for x32. +commit a8e0a835ab1f62d03ad6391760e3e8b7732d24f8 +Author: Zachary Waldowski +Date: Mon Dec 30 15:26:20 2013 -0500 -2012-03-03 H.J. Lu + Darwin/ARM: Assert on NULL dereference + + This inhibits an analyzer warning by Clang on all platforms. - * src/prep_cif.c (ffi_prep_cif_core): Properly check bad ABI. +commit 13675341581c489ed9df8ba390c8e08a732decb2 +Author: Zachary Waldowski +Date: Thu Jan 9 13:42:08 2014 -0500 -2012-03-03 Andoni Morales Alastruey + Darwin/i386: Inhibit Clang previous prototype warnings - * configure.ac: Add -no-undefined for both 32- and 64-bit x86 - windows-like hosts. - * configure: Rebuilt. +commit 66469c381e2e2cc96e7d409266dea0ffe177eeca +Author: Zachary Waldowski +Date: Thu Jan 9 13:41:45 2014 -0500 -2012-02-27 Mikael Pettersson + Darwin/ARM: Inhibit Clang previous prototype warnings - PR libffi/52223 - * Makefile.am (FLAGS_TO_PASS): Define. - * Makefile.in: Regenerate. +commit 5bfe62a00d2d659eec9f19b39802b6e69844fc27 +Author: Zachary Waldowski +Date: Thu Jan 9 13:41:27 2014 -0500 -2012-02-23 Anthony Green + Darwin/AArch64: Inhibit Clang previous prototype warnings - * src/*/ffitarget.h: Ensure that users never include ffitarget.h - directly. +commit fa5f25c20f76a6ef5e950a7ccbce826672c8a620 +Author: Marcus Comstedt +Date: Sat Jan 4 19:00:08 2014 +0100 -2012-02-23 Kai Tietz + Linux/ppc64: Remove assumption on contents of r11 in closure - PR libffi/52221 - * src/x86/ffi.c (ffi_closure_raw_THISCALL): New - prototype. - (ffi_prep_raw_closure_loc): Use ffi_closure_raw_THISCALL for - thiscall-convention. - (ffi_raw_call): Use ffi_prep_args_raw. - * src/x86/win32.S (ffi_closure_raw_THISCALL): Add - implementation for stub. +commit 1a0b01e171e9c750437cef2f18917f5a6e32c498 +Author: Paulo Pizarro +Date: Thu Jan 2 16:17:59 2014 -0200 -2012-02-10 Kai Tietz + When the function called by the ffi called a function defined in a shared library generate a fatal error + The correction was to take into consideration the GOT. - * configure.ac (AM_LTLDFLAGS): Add -no-undefine for x64 - windows target. - * configure: Regenerated. +commit 3dc3f32c35db5ab995a835225f6815369735ceb7 +Author: Anthony Green +Date: Thu Dec 5 16:23:25 2013 -0500 -2012-02-08 Kai Tietz + Undo iOS ARM64 changes. - * src/prep_cif.c (ffi_prep_cif): Allow for X86_WIN32 - also FFI_THISCALL. - * src/x86/ffi.c (ffi_closure_THISCALL): Add prototype. - (FFI_INIT_TRAMPOLINE_THISCALL): New trampoline code. - (ffi_prep_closure_loc): Add FFI_THISCALL support. - * src/x86/ffitarget.h (FFI_TRAMPOLINE_SIZE): Adjust size. - * src/x86/win32.S (ffi_closure_THISCALL): New closure code - for thiscall-calling convention. - * testsuite/libffi.call/closure_thiscall.c: New test. +commit 356b2cbc304bfe5bdc28b8d1c68d1ff084e9ec37 +Merge: 484a758 07345a3 +Author: Anthony Green +Date: Sat Nov 30 22:38:13 2013 -0500 -2012-01-28 Kai Tietz + Merge branch 'master' of github.com:/atgreen/libffi - * src/libffi/src/x86/ffi.c (ffi_call_win32): Add new - argument to prototype for specify calling-convention. - (ffi_call): Add support for stdcall/thiscall convention. - (ffi_prep_args): Likewise. - (ffi_raw_call): Likewise. - * src/x86/ffitarget.h (ffi_abi): Add FFI_THISCALL and - FFI_FASTCALL. - * src/x86/win32.S (_ffi_call_win32): Add support for - fastcall/thiscall calling-convention calls. - * testsuite/libffi.call/fastthis1_win32.c: New test. - * testsuite/libffi.call/fastthis2_win32.c: New test. - * testsuite/libffi.call/fastthis3_win32.c: New test. - * testsuite/libffi.call/strlen2_win32.c: New test. - * testsuite/libffi.call/many2_win32.c: New test. - * testsuite/libffi.call/struct1_win32.c: New test. - * testsuite/libffi.call/struct2_win32.c: New test. +commit 484a7584260e2fbb399ce90083046834271bf9ff +Author: Anthony Green +Date: Sat Nov 30 21:06:51 2013 -0500 -2012-01-23 Uros Bizjak + Mention Aarch64 on iOS - * src/alpha/ffi.c (ffi_prep_closure_loc): Check for bad ABI. +commit 07345a30ec0a2fa45a7c363d301f57723690cfa0 +Author: Anthony Green +Date: Sat Nov 30 21:06:51 2013 -0500 -2012-01-23 Anthony Green - Chris Young + Mention Aarch64 on iOS - * configure.ac: Add Amiga support. - * configure: Rebuilt. +commit d4b931c1b872378c35f12ddbb9a6d55e7f17c65e +Author: Anthony Green +Date: Sat Nov 30 20:58:31 2013 -0500 -2012-01-23 Dmitry Nadezhin + Remove build-ios from Makefile - * include/ffi_common.h (LIKELY, UNLIKELY): Fix definitions. +commit dfbf236d70fc1ec68e6ff193584a154353508e2f +Merge: 852ac3b bb9740e +Author: Anthony Green +Date: Sat Nov 30 20:54:54 2013 -0500 -2012-01-23 Andreas Schwab + Merge branch 'master' of github.com:/atgreen/libffi + Add ChangeLog entry. - * src/m68k/sysv.S (ffi_call_SYSV): Properly test for plain - mc68000. Test for __HAVE_68881__ in addition to __MC68881__. +commit bb9740e545205f93a525c77aa6d1cbf4ca9371f3 +Merge: ac75368 4d701e0 +Author: Anthony Green +Date: Sat Nov 30 17:54:39 2013 -0800 -2012-01-19 Jakub Jelinek + Merge pull request #60 from zwaldowski/ios-redo + + Mac/iOS support, including aarch64 port - PR rtl-optimization/48496 - * src/ia64/ffi.c (ffi_call): Fix up aliasing violations. +commit 4d701e03faa475a5eb3b54b90046114a1e27b813 +Author: Zachary Waldowski +Date: Sat Nov 30 13:25:27 2013 -0500 -2012-01-09 Rainer Orth + Darwin: Properly export headers from Xcode project - * configure.ac (i?86-*-*): Set TARGET to X86_64. - * configure: Regenerate. +commit 022f12eb9ad2264e838fa5fb453733f5177888f4 +Author: Zachary Waldowski +Date: Sat Nov 30 12:21:38 2013 -0500 -2011-12-07 Andrew Pinski + Darwin: Freshen gen scripts, remove old build-ios.sh - PR libffi/50051 - * src/mips/n32.S: Add ".set mips4". +commit e820fe2025d7ad3df7584407946dfaad2af69599 +Author: Zachary Waldowski +Date: Sat Nov 30 12:03:51 2013 -0500 -2011-11-21 Andreas Tobler + Darwin/iOS: Include x86_64+aarch64 pieces in library - * configure: Regenerate. +commit 0278284e470ec91db7cdc15ac3dcd64683305848 +Author: Zachary Waldowski +Date: Sat Nov 30 03:03:37 2013 -0500 -2011-11-12 David Gilbert + Darwin/aarch64: size_t assumptions - * doc/libffi.texi, include/ffi.h.in, include/ffi_common.h, - man/Makefile.am, man/ffi.3, man/ffi_prep_cif.3, - man/ffi_prep_cif_var.3, src/arm/ffi.c, src/arm/ffitarget.h, - src/cris/ffi.c, src/prep_cif.c, - testsuite/libffi.call/cls_double_va.c, - testsuite/libffi.call/cls_longdouble_va.c, - testsuite/libffi.call/float_va.c: Many changes to support variadic - function calls. +commit 9775446b6441c91cd9059215c106aa3bcf949767 +Author: Zachary Waldowski +Date: Sat Nov 30 02:39:34 2013 -0500 -2011-11-12 Kyle Moffett + Darwin/aarch64: Fix “shadows declaration†warnings - * src/powerpc/ffi.c, src/powerpc/ffitarget.h, - src/powerpc/ppc_closure.S, src/powerpc/sysv.S: Many changes for - softfloat powerpc variants. +commit 4260badc37705d3618e774dfe61184ac709881c1 +Author: Zachary Waldowski +Date: Sat Nov 30 02:08:14 2013 -0500 -2011-11-12 Petr Salinger + Darwin/aarch64: Use Clang cache invalidation builtin - * configure.ac (FFI_EXEC_TRAMPOLINE_TABLE): Fix kfreebsd support. - * configure: Rebuilt. +commit 9fa7998d5f9250908cbf12a671479852ebadf9d1 +Author: Zachary Waldowski +Date: Sat Nov 30 02:07:48 2013 -0500 -2011-11-12 Timothy Wall + Darwin/aarch64: Inhibit Xcode warning - * src/arm/ffi.c (ffi_prep_args, ffi_prep_incoming_args_SYSV): Max - alignment of 4 for wince on ARM. +commit 0e832048a93830575b0976406444e134e649a4f7 +Author: Zachary Waldowski +Date: Sat Nov 30 02:07:34 2013 -0500 -2011-11-12 Kyle Moffett - Anthony Green + Darwin/aarch64: double == long double - * src/ppc/sysv.S, src/ppc/ffi.c: Remove use of ppc string - instructions (not available on some cores, like the PPC440). +commit 602dc22d76931092610234cf063f9f1b8dbc1a51 +Author: Zachary Waldowski +Date: Sat Nov 30 02:06:00 2013 -0500 -2011-11-12 Kimura Wataru + Darwin/iOS prep script: try and compile for arm64 - * m4/ax_enable_builddir: Change from string comparison to numeric - comparison for wc output. - * configure.ac: Enable FFI_MMAP_EXEC_WRIT for darwin11 aka Mac OS - X 10.7. - * configure: Rebuilt. +commit b513dfe79de4725e8a717325a9e3b5b9f69f63dc +Author: Zachary Waldowski +Date: Sat Nov 30 02:05:22 2013 -0500 -2011-11-12 Anthony Green + Darwin/aarch64: Restrict .size to ELF like arm32. - * Makefile.am (AM_CCASFLAGS): Add -g option to build assembly - files with debug info. - * Makefile.in: Rebuilt. +commit bc978099bf2812de755c076b67ef9c2547607572 +Author: Zachary Waldowski +Date: Sat Nov 30 02:04:57 2013 -0500 -2011-11-12 Jasper Lievisse Adriaanse + Darwin/aarch64: Potentially(?) fix compile error - * README: Update list of supported OpenBSD systems. +commit d6bb9314467c6e0683156559d23ca341c43fa3c8 +Author: Zachary Waldowski +Date: Sat Nov 30 02:04:22 2013 -0500 -2011-11-12 Anthony Green + Darwin/aarch64: Use CNAME refs - * libtool-version: Update. - * Makefile.am (nodist_libffi_la_SOURCES): Add src/debug.c if - FFI_DEBUG. - (libffi_la_SOURCES): Remove src/debug.c - (EXTRA_DIST): Add src/debug.c - * Makefile.in: Rebuilt. - * README: Update for 3.0.11. +commit 33c46ce5680eea28d3437c8771ec1d137e226b45 +Author: Zachary Waldowski +Date: Sat Nov 30 04:13:42 2013 -0500 -2011-11-10 Richard Henderson + Darwin/Mac: Fix 64/32 shortening warnings - * configure.ac (GCC_AS_CFI_PSEUDO_OP): Use it instead of inline check. - * configure, aclocal.m4: Rebuild. +commit 0612081e6c161d9d820742f995975d35da2adbc2 +Author: Zachary Waldowski +Date: Sat Nov 30 03:03:00 2013 -0500 -2011-09-04 Iain Sandoe + Darwin: Misc size_t warnings - PR libffi/49594 - * src/powerpc/darwin_closure.S (stubs): Make the stub binding - helper reference track the architecture pointer size. +commit 6a6247d179ec3859311c2d8775841b884f309f66 +Author: Zachary Waldowski +Date: Sat Nov 30 02:55:48 2013 -0500 -2011-08-25 Andrew Haley + Darwin: Fix dlmalloc warnings due to sizeof(size_t) - * src/arm/ffi.c (FFI_INIT_TRAMPOLINE): Remove hard-coded assembly - instructions. - * src/arm/sysv.S (ffi_arm_trampoline): Put them here instead. +commit 4d60d9e1e32de6166ffd63bbe9ce54cf961c78fc +Author: Zachary Waldowski +Date: Sat Nov 30 04:09:30 2013 -0500 -2011-07-11 Andrew Haley + Darwin: Rebuild Xcode project - * src/arm/ffi.c (FFI_INIT_TRAMPOLINE): Clear icache. +commit cb719a5c1c2eb391d6a5f5e02484ba4aa990a51b +Author: Zachary Waldowski +Date: Sat Nov 30 04:09:18 2013 -0500 -2011-06-29 Rainer Orth + Darwin/iOS: Fix LLVM 3.3 warning re: memcpy. - * testsuite/libffi.call/cls_double_va.c: Move PR number to comment. - * testsuite/libffi.call/cls_longdouble_va.c: Likewise. +commit 21bde92c9abb378f9c456a9d95e6f9b99ef8c920 +Author: Zachary Waldowski +Date: Sat Nov 30 03:43:42 2013 -0500 -2011-06-29 Rainer Orth + Darwin: Clean up, modernize generator scripts - PR libffi/46660 - * testsuite/libffi.call/cls_double_va.c: xfail dg-output on - mips-sgi-irix6*. - * testsuite/libffi.call/cls_longdouble_va.c: Likewise. +commit fd54eab74cef7891e4acaaafb71e783142ecb69e +Author: Zachary Waldowski +Date: Sat Nov 30 03:38:02 2013 -0500 -2011-06-14 Rainer Orth + Darwin/Mac: Also exclude OS X generated source - * testsuite/libffi.call/huge_struct.c (test_large_fn): Use PRIu8, - PRId8 instead of %hhu, %hhd. - * testsuite/libffi.call/ffitest.h [__alpha__ && __osf__] (PRId8, - PRIu8): Define. - [__sgi__] (PRId8, PRIu8): Define. +commit 953b6f14c655141f9e7d82550a312c3eeb961091 +Author: Zachary Waldowski +Date: Tue Apr 24 11:16:20 2012 -0400 -2011-04-29 Rainer Orth + Darwin/iOS: More unified syntax support w/ Clang. + + Signed-off-by: Zachary Waldowski - * src/alpha/osf.S (UA_SI, FDE_ENCODING, FDE_ENCODE, FDE_ARANGE): - Define. - Use them to handle ELF vs. ECOFF differences. - [__osf__] (_GLOBAL__F_ffi_call_osf): Define. +commit c713a55379481c339877f2e0003d97cb8d9ed80e +Author: Zachary Waldowski +Date: Tue Apr 24 10:25:29 2012 -0400 -2011-03-30 Timothy Wall + Darwin/iOS: Simplify RETLDM arguments for LLVM 3.1 + + Signed-off-by: Zachary Waldowski - * src/powerpc/darwin.S: Fix unknown FDE encoding. - * src/powerpc/darwin_closure.S: ditto. +commit 16ba1b80028db5cb71cf86e5f79f5e48317f83c8 +Author: Zachary Waldowski +Date: Wed Apr 11 23:26:04 2012 -0400 -2011-02-25 Anthony Green + Darwin: Silence Clang warnings. - * src/powerpc/ffi.c (ffi_prep_closure_loc): Allow for more - 32-bit ABIs. +commit 852ac3bd302d6ed97b1ef65f4cbed69c258a48df +Merge: ab79d6e ac75368 +Author: Anthony Green +Date: Thu Nov 21 21:25:44 2013 -0500 -2011-02-15 Anthony Green + Merge branch 'master' of github.com:/atgreen/libffi + + Conflicts: + ChangeLog - * m4/ax_cc_maxopt.m4: Don't -malign-double or use -ffast-math. - * configure: Rebuilt. +commit ab79d6e21992dd86139ba07530ff888833b78a04 +Author: Alan Modra +Date: Thu Nov 21 06:12:35 2013 -0500 + + This separates the 32-bit sysv/linux/bsd code from the 64-bit linux + code, and makes it possible to link code compiled with different + options to those used to compile libffi. For example, a + -mlong-double-128 libffi can be used with -mlong-double-64 code. + + Using the return value area as a place to pass parameters wasn't such + a good idea, causing a failure of cls_ulonglong.c. I didn't see this + when running the mainline gcc libffi testsuite because that version of + the test is inferior to the upstreamm libffi test. + + Using NUM_FPR_ARG_REGISTERS rather than NUM_FPR_ARG_REGISTERS64 meant + that a parameter save area could be allocated before it was strictly + necessary. Wrong but harmless. Found when splitting apart ffi.c + into 32-bit and 64-bit support. + +commit ac7536889334d4be50709006d7e23536364d7891 +Author: Alan Modra +Date: Thu Nov 21 06:12:35 2013 -0500 + + This separates the 32-bit sysv/linux/bsd code from the 64-bit linux + code, and makes it possible to link code compiled with different + options to those used to compile libffi. For example, a + -mlong-double-128 libffi can be used with -mlong-double-64 code. + + Using the return value area as a place to pass parameters wasn't such + a good idea, causing a failure of cls_ulonglong.c. I didn't see this + when running the mainline gcc libffi testsuite because that version of + the test is inferior to the upstreamm libffi test. + + Using NUM_FPR_ARG_REGISTERS rather than NUM_FPR_ARG_REGISTERS64 meant + that a parameter save area could be allocated before it was strictly + necessary. Wrong but harmless. Found when splitting apart ffi.c + into 32-bit and 64-bit support. + +commit 69df91cfb4fa6bcb644350a80bff970f27478a6a +Merge: 2f45082 aa1f62c +Author: Anthony Green +Date: Mon Nov 18 06:34:04 2013 -0800 + + Merge pull request #59 from iains/powerpc-darwin-unwind-fix + + Fix PowerPC Darwin FDE encodings to use pcrel correctly. Modernise the picbase labels. + +commit aa1f62c0a093c30325dff1d4d2b6b4b22eb96929 +Author: Iain Sandoe +Date: Mon Nov 18 13:11:56 2013 +0000 + + Fix PowerPC Darwin FDE encodings to use pcrel correctly. Modernise the picbase labels. + +commit 2f450822a8698ba88441c56d152c7dc8924b127f +Author: Anthony Green +Date: Mon Nov 18 06:52:29 2013 -0500 + + Clean up code to appease modern GCC compiler. + +commit 16d56c51aded374730920a4acde76ff3d2860ae1 +Author: Alan Modra +Date: Mon Nov 18 06:36:03 2013 -0500 + + An #endif in the wrong place would cause compile failure on powerpcle. + Using bl instead of b doesn't cause runtime failures as you might think, + but does mess the processor branch prediction. + +commit 34f878a5ef28663f6b1d7fd26fb099429ea1579e +Merge: 83f65b6 1fd0457 +Author: Anthony Green +Date: Sat Nov 16 06:57:54 2013 -0500 + + Merge branch 'master' of github.com:/atgreen/libffi + + Conflicts: + ChangeLog + src/powerpc/ffi.c + +commit 83f65b63d9764a9cc7688fc5cda5ee2bd23faf54 +Author: Alan Modra +Date: Sat Nov 16 06:53:50 2013 -0500 + + Finally, this adds _CALL_ELF == 2 support. ELFv1 objects can't be + linked with ELFv2 objects, so this is one case where preprocessor + tests in ffi.c are fine. Also, there is no need to define a new + FFI_ELFv2 or somesuch value in enum ffi_abi. FFI_LINUX64 will happily + serve both ABIs. + +commit 1fd045784cac874b5d76b7fa931f67209a8280d3 +Author: Alan Modra +Date: Sat Nov 16 06:53:50 2013 -0500 + + Finally, this adds _CALL_ELF == 2 support. ELFv1 objects can't be + linked with ELFv2 objects, so this is one case where preprocessor + tests in ffi.c are fine. Also, there is no need to define a new + FFI_ELFv2 or somesuch value in enum ffi_abi. FFI_LINUX64 will happily + serve both ABIs. + +commit 362851379a49ce07d3e36e82c4e5c7b6cc16a352 +Author: Alan Modra +Date: Sat Nov 16 06:52:43 2013 -0500 + + Andreas' 2013-02-08 change reverted some breakage for struct return + values from 2011-11-12, but in so doing reintroduced string + instructions to sysv.S that are not supported on all powerpc variants. + This patch properly copies the bounce buffer to destination in C code + rather than in asm. + + I have tested this on powerpc64-linux, powerpc-linux and + powerpc-freebsd. Well, the last on powerpc-linux by lying to + configure with + + CC="gcc -m32 -msvr4-struct-return -mlong-double-64" \ + CXX="g++ -m32 -msvr4-struct-return -mlong-double-64" \ + /src/libffi-current/configure --build=powerpc-freebsd + + and then + + make && make CC="gcc -m32" CXX="g++ -m32" \ + RUNTESTFLAGS=--target_board=unix/-m32/-msvr4-struct-return/-mlong-double-64\ + check + +commit 1c06515d927d9de1582438d4eb5953890e79c5c7 +Author: Alan Modra +Date: Sat Nov 16 06:41:36 2013 -0500 + + The powerpc64 ABIs align structs passed by value, a fact ignored by + gcc for quite some time. Since gcc now does the correct alignment, + libffi needs to follow suit. This ought to be made selectable via + a new abi value, and the #ifdefs removed from ffi.c along with many + other #ifdefs present there and in assembly. I'll do that with a + followup patch sometime. + + This is a revised version of + https://sourceware.org/ml/libffi-discuss/2013/msg00162.html + +commit a97cf1fae575d8bfd5259c5c422025ad43911326 +Author: Alan Modra +Date: Sat Nov 16 06:40:13 2013 -0500 + + This patch prepares for ELFv2, where sizes of these areas change. It + also makes some minor changes to improve code efficiency. + +commit 164283f4ac5972ce2ab5e015cc2ab1014c23276c +Author: Alan Modra +Date: Sat Nov 16 06:38:55 2013 -0500 + + The powerpc64 support opted to pass floating point values both in the + fpr area and the parameter save area, necessary when the backend + doesn't know if a function argument corresponds to the ellipsis + arguments of a variadic function. This patch adds powerpc support for + variadic functions, and changes the code to only pass fp in the ABI + mandated area. ELFv2 needs this change since the parameter save area + may not exist there. + + This also fixes two faulty tests that used a non-variadic function + cast to call a variadic function, and spuriously reasoned that this is + somehow necessary for static functions.. + +commit 31257b3189f81a199bc2902c22bc5f2d7c54ccde +Author: Andrew Haley +Date: Sat Nov 16 06:35:51 2013 -0500 + + Fix sample closure code + +commit db0ace3a38496af73eae3df02ef353736d16909f +Author: Andrew Haley +Date: Sat Nov 16 06:29:25 2013 -0500 + + Fix broken test cases + +commit de10f5039ed7a53382ddcc95c368d03e535edb98 +Merge: 58c2577 f3657da +Author: Anthony Green +Date: Thu Nov 14 10:56:29 2013 -0500 + + Merge branch 'master' of https://github.com/bivab/libffi + + Conflicts: + ChangeLog + +commit f3657da278dd63afcdd8762894a9bdaea8ef028a +Author: David Schneider +Date: Thu Nov 14 13:02:16 2013 +0100 + + update Changelog + +commit 58c2577a3ff80e7416ef0434769e2af23365719c +Author: Alan Modra +Date: Wed Nov 13 16:55:36 2013 -0500 + + This enshrines the current testsuite practice of using ffi_arg for + returned values. It would be reasonable and logical to use the actual + return argument type as passed to ffi_prep_cif, but this would mean + changing a large number of tests that use ffi_arg and all backends + that write results to an ffi_arg. + +commit 8af42f9944f7ed72c81ae360aac6a84dc11f89dc +Author: Anthony Green +Date: Wed Nov 13 16:40:28 2013 -0500 + + Respect HAVE_ALLOCA_H + +commit cdf405d574f479b782454516366bd4f4b9b3415e +Author: David Schneider +Date: Wed Nov 13 15:50:21 2013 +0100 + + add a testcase for the double/float issue on ARMHF + +commit 77f823e31ffb557a466b24f7fba845fbf7831798 +Author: David Schneider +Date: Wed Nov 13 14:26:57 2013 +0100 -2011-02-13 Ralf Wildenhues + stop trying to assing vfp regs once we are done with the registers - * configure: Regenerate. +commit 37067ec5036f2a6ed7a4799f83f8f53160460344 +Author: David Schneider +Date: Tue Nov 12 19:49:01 2013 +0100 -2011-02-13 Anthony Green + mark all vfp registers as used when done. + + To avoid assigning registers the would fit, once arguments have been on + the stack, we mark all registers as used once we do not find a free + register for the first time. - * include/ffi_common.h (UNLIKELY, LIKELY): Define. - * src/x86/ffi64.c (UNLIKELY, LIKELY): Remove definition. - * src/prep_cif.c (UNLIKELY, LIKELY): Remove definition. +commit 2f5b7ce545473a7f6e41193edc29407cbebe82d5 +Author: Anthony Green +Date: Sat Nov 9 06:16:32 2013 -0500 - * src/prep_cif.c (initialize_aggregate): Convert assertion into - FFI_BAD_TYPEDEF return. Initialize arg size and alignment to 0. + UltraSPARC IIi fix. Update README and build configury. - * src/pa/ffi.c (ffi_prep_closure_loc): Don't ASSERT ABI test, - just return FFI_BAD_ABI when things are wrong. - * src/arm/ffi.c (ffi_prep_closure_loc): Ditto. - * src/powerpc/ffi.c (ffi_prep_closure_loc): Ditto. - * src/mips/ffi.c (ffi_prep_closure_loc): Ditto. - * src/ia64/ffi.c (ffi_prep_closure_loc): Ditto. - * src/avr32/ffi.c (ffi_prep_closure_loc): Ditto. +commit becd754434173032f426d22ffcbfe24f55b3c137 +Author: Mark Kettenis +Date: Wed Nov 6 06:43:49 2013 -0500 -2011-02-11 Anthony Green + Align the stack pointer to 16-bytes. - * src/sparc/ffi.c (ffi_prep_closure_loc): Don't ASSERT ABI test, - just return FFI_BAD_ABI when things are wrong. +commit 05c31093409f7b3e6d795fac21d2c954313d8162 +Author: Konstantin Belousov +Date: Wed Nov 6 06:40:58 2013 -0500 -2012-02-11 Eric Botcazou + Mark executable as not requiring executable stack. - * src/sparc/v9.S (STACKFRAME): Bump to 176. +commit cf6bf9818e8394cfcdb07a40c6a5e2ee6b01d333 +Author: Anthony Green +Date: Sat Nov 2 17:23:59 2013 -0400 -2011-02-09 Stuart Shelton + Fix up docs - http://bugs.gentoo.org/show_bug.cgi?id=286911 - * src/mips/ffitarget.h: Clean up error messages. - * src/java_raw_api.c (ffi_java_translate_args): Cast raw arg to - ffi_raw*. - * include/ffi.h.in: Add pragma for SGI compiler. +commit 02177176854d16fc0f1a5958aa34da2f306630ee +Merge: c242217 c265b4c +Author: Anthony Green +Date: Sat Nov 2 17:11:22 2013 -0400 -2011-02-09 Anthony Green + Merge branch 'master' of github.com:/atgreen/libffi - * configure.ac: Add powerpc64-*-darwin* support. +commit c2422174b3edc0de0b148dfd6b67087bb881c4a6 +Merge: f4b843f d918d47 +Author: Anthony Green +Date: Sat Nov 2 14:08:23 2013 -0700 -2011-02-09 Anthony Green + Merge pull request #45 from foss-for-synopsys-dwc-arc-processors/arc_support + + arc: Fix build error - * README: Mention Interix. +commit c265b4cacb9130f042699a85de9c7242b3f49cc3 +Merge: f4b843f d918d47 +Author: Anthony Green +Date: Sat Nov 2 14:08:23 2013 -0700 -2011-02-09 Jonathan Callen + Merge pull request #45 from foss-for-synopsys-dwc-arc-processors/arc_support + + arc: Fix build error - * configure.ac: Add Interix to win32/cygwin/mingw case. - * configure: Ditto. - * src/closures.c: Treat Interix like Cygwin, instead of as a - generic win32. +commit f4b843f83710ac378c48abd87fe66bb519d30d2e +Author: Anthony Green +Date: Sat Nov 2 17:01:15 2013 -0400 -2011-02-09 Anthony Green + Don't align stack for win32 - * testsuite/libffi.call/err_bad_typedef.c: Remove xfail. - * testsuite/libffi.call/err_bad_abi.c: Remove xfail. - * src/x86/ffi64.c (UNLIKELY, LIKELY): Define. - (ffi_prep_closure_loc): Check for bad ABI. - * src/prep_cif.c (UNLIKELY, LIKELY): Define. - (initialize_aggregate): Check for bad types. +commit f3cd39345713db8e414cf642b6cb65a4cfe6018c +Merge: 666f3e7 6aa1590 +Author: Anthony Green +Date: Sat Nov 2 13:17:57 2013 -0700 -2011-02-09 Landon Fuller + Merge pull request #51 from vbudovski/for_upstream + + Don't use 16 byte aligned stack for WIN32 - * Makefile.am (EXTRA_DIST): Add build-ios.sh, src/arm/gentramp.sh, - src/arm/trampoline.S. - (nodist_libffi_la_SOURCES): Add src/arc/trampoline.S. - * configure.ac (FFI_EXEC_TRAMPOLINE_TABLE): Define. - * src/arm/ffi.c (ffi_trampoline_table) - (ffi_closure_trampoline_table_page, ffi_trampoline_table_entry) - (FFI_TRAMPOLINE_CODELOC_CONFIG, FFI_TRAMPOLINE_CONFIG_PAGE_OFFSET) - (FFI_TRAMPOLINE_COUNT, ffi_trampoline_lock, ffi_trampoline_tables) - (ffi_trampoline_table_alloc, ffi_closure_alloc, ffi_closure_free): - Define for FFI_EXEC_TRAMPOLINE_TABLE case (iOS). - (ffi_prep_closure_loc): Handl FFI_EXEC_TRAMPOLINE_TABLE case - separately. - * src/arm/sysv.S: Handle Apple iOS host. - * src/closures.c: Handle FFI_EXEC_TRAMPOLINE_TABLE case. - * build-ios.sh: New file. - * fficonfig.h.in, configure, Makefile.in: Rebuilt. - * README: Mention ARM iOS. +commit 666f3e71b56d92c49fcd2d7f349b8f8ebca0f8a3 +Author: Anthony Green +Date: Sat Oct 26 09:12:42 2013 -0400 -2011-02-08 Oren Held + Add more credits to README. Tidy up. - * src/dlmalloc.c (_STRUCT_MALLINFO): Define in order to avoid - redefinition of mallinfo on HP-UX. +commit 73ada14e756bad97fad0e6915a821a3c7e079f81 +Author: Anthony Green +Date: Sat Oct 26 09:09:45 2013 -0400 -2011-02-08 Ginn Chen + Update README - * src/sparc/ffi.c (ffi_call): Make compatible with Solaris Studio - aggregate return ABI. Flush cache. - (ffi_prep_closure_loc): Flush cache. +commit d3372c54ce7117e80d389ba875dc5b6b2213c71e +Author: Mark H Weaver +Date: Sat Oct 26 08:30:06 2013 -0400 -2011-02-11 Anthony Green + Fix N32 ABI issue for MIPS. - From Tom Honermann : - * src/powerpc/aix.S (ffi_call_AIX): Support for xlc toolchain on - AIX. Declare .ffi_prep_args. Insert nops after branch - instructions so that the AIX linker can insert TOC reload - instructions. - * src/powerpc/aix_closure.S: Declare .ffi_closure_helper_DARWIN. +commit d6716aba8118eb0513885cfe557bedebb7016e8b +Author: Anthony Green +Date: Tue Oct 15 15:42:49 2013 -0400 -2011-02-08 Ed + Update travis-ci build dependencies to include texinfo - * src/powerpc/asm.h: Fix grammar nit in comment. +commit 16b93a211bcfbe4bd0efdcf94de225a71aa0ee02 +Author: Sandra Loosemore +Date: Tue Oct 15 15:33:59 2013 -0400 -2011-02-08 Uli Link + Add nios2 port. - * include/ffi.h.in (FFI_64_BIT_MAX): Define and use. +commit 2f5626ce02fce8267ab48ceb6d7d0ed7d672a75e +Author: Sandra Loosemore +Date: Tue Oct 15 15:32:16 2013 -0400 -2011-02-09 Rainer Orth + Fix testsuite bug - PR libffi/46661 - * testsuite/libffi.call/cls_pointer.c (main): Cast void * to - uintptr_t first. - * testsuite/libffi.call/cls_pointer_stack.c (main): Likewise. +commit f64e4a865557e440774436b4c2b2fd7374290e97 +Author: Marcus Shawcroft +Date: Tue Oct 15 15:20:14 2013 -0400 -2011-02-08 Rafael Avila de Espindola + Fix many.c testcase for Aarch64 - * configure.ac: Fix x86 test for pc related relocs. - * configure: Rebuilt. +commit 128cd1d2f358f26d9fa75a27cf2b30356f5dd903 +Author: Anthony Green +Date: Tue Oct 8 06:45:51 2013 -0400 -2011-02-07 Joel Sherrill + Fix spelling errors - * libffi/src/m68k/ffi.c: Add RTEMS support for cache flushing. - Handle case when CPU variant does not have long double support. - * libffi/src/m68k/sysv.S: Add support for mc68000, Coldfire, - and cores with soft floating point. - -2011-02-07 Joel Sherrill - - * configure.ac: Add mips*-*-rtems* support. - * configure: Regenerate. - * src/mips/ffitarget.h: Ensure needed constants are available - for targets which do not have sgidefs.h. - -2011-01-26 Dave Korn - - PR target/40125 - * configure.ac (AM_LTLDFLAGS): Add -bindir option for windows DLLs. - * configure: Regenerate. - -2010-12-18 Iain Sandoe - - PR libffi/29152 - PR libffi/42378 - * src/powerpc/darwin_closure.S: Provide Darwin64 implementation, - update comments. - * src/powerpc/ffitarget.h (POWERPC_DARWIN64): New, - (FFI_TRAMPOLINE_SIZE): Update for Darwin64. - * src/powerpc/darwin.S: Provide Darwin64 implementation, - update comments. - * src/powerpc/ffi_darwin.c: Likewise. - -2010-12-06 Rainer Orth - - * configure.ac (libffi_cv_as_ascii_pseudo_op): Use double - backslashes. - (libffi_cv_as_string_pseudo_op): Likewise. - * configure: Regenerate. - -2010-12-03 Chung-Lin Tang - - * src/arm/sysv.S (ffi_closure_SYSV): Add UNWIND to .pad directive. - (ffi_closure_VFP): Same. - (ffi_call_VFP): Move down to before ffi_closure_VFP. Add '.fpu vfp' - directive. - -2010-12-01 Rainer Orth - - * testsuite/libffi.call/ffitest.h [__sgi] (PRId64, PRIu64): Define. - (PRIuPTR): Define. +commit ff06269d707cafbfef2a88afb07a79c9d1480c5f +Author: Anthony Green +Date: Tue Oct 8 06:32:18 2013 -0400 -2010-11-29 Richard Henderson - Rainer Orth + Update README for M88K and VAX - * src/x86/sysv.S (FDE_ENCODING, FDE_ENCODE): Define. - (.eh_frame): Use FDE_ENCODING. - (.LASFDE1, .LASFDE2, LASFDE3): Simplify with FDE_ENCODE. +commit d2fcbcdfbea750d1f6a9f493e2e6c4d5ffa71b34 +Author: Anthony Green +Date: Tue Oct 8 06:27:46 2013 -0400 -2010-11-22 Jacek Caban + Add m88k and VAX support. Update some configury bits. - * configure.ac: Check for symbol underscores on mingw-w64. - * configure: Rebuilt. - * src/x86/win64.S: Correctly access extern symbols in respect to - underscores. +commit 6aa15900accc0a648cdebf11ec11d11697ebfffd +Author: Vitaly Budovski +Date: Thu Sep 5 12:05:06 2013 +1000 -2010-11-15 Rainer Orth + Don't use 16 byte aligned stack for WIN32 + + This fixes a crash when accessing __stdcall functions in Python ctypes. - * testsuite/lib/libffi-dg.exp: Rename ... - * testsuite/lib/libffi.exp: ... to this. - * libffi/testsuite/libffi.call/call.exp: Don't load libffi-dg.exp. - * libffi/testsuite/libffi.special/special.exp: Likewise. +commit 3b44d41156149af8da2a58825fefdfa23274ae7a +Author: Makoto Kato +Date: Wed Jul 10 15:34:53 2013 +0900 -2010-10-28 Chung-Lin Tang + Fix build failure when using clang for Android + + clang for Android generates __gnu_linux__ define, but gcc for Android doesn't. So we should add check it for Android - * src/arm/ffi.c (ffi_prep_args): Add VFP register argument handling - code, new parameter, and return value. Update comments. - (ffi_prep_cif_machdep): Add case for VFP struct return values. Add - call to layout_vfp_args(). - (ffi_call_SYSV): Update declaration. - (ffi_call_VFP): New declaration. - (ffi_call): Add VFP struct return conditions. Call ffi_call_VFP() - when ABI is FFI_VFP. - (ffi_closure_VFP): New declaration. - (ffi_closure_SYSV_inner): Add new vfp_args parameter, update call to - ffi_prep_incoming_args_SYSV(). - (ffi_prep_incoming_args_SYSV): Update parameters. Add VFP argument - case handling. - (ffi_prep_closure_loc): Pass ffi_closure_VFP to trampoline - construction under VFP hard-float. - (rec_vfp_type_p): New function. - (vfp_type_p): Same. - (place_vfp_arg): Same. - (layout_vfp_args): Same. - * src/arm/ffitarget.h (ffi_abi): Add FFI_VFP. Define FFI_DEFAULT_ABI - based on __ARM_PCS_VFP. - (FFI_EXTRA_CIF_FIELDS): Define for adding VFP hard-float specific - fields. - (FFI_TYPE_STRUCT_VFP_FLOAT): Define internally used type code. - (FFI_TYPE_STRUCT_VFP_DOUBLE): Same. - * src/arm/sysv.S (ffi_call_SYSV): Change call of ffi_prep_args() to - direct call. Move function pointer load upwards. - (ffi_call_VFP): New function. - (ffi_closure_VFP): Same. +commit d918d47809c174d62283306b282749f8db93661f +Author: Mischa Jonker +Date: Mon Jul 8 15:51:36 2013 +0200 - * testsuite/lib/libffi-dg.exp (check-flags): New function. - (dg-skip-if): New function. - * testsuite/libffi.call/cls_double_va.c: Skip if target is arm*-*-* - and compiler options include -mfloat-abi=hard. - * testsuite/libffi.call/cls_longdouble_va.c: Same. + arc: Fix build error + + One part of the patch for ARC support was missing in the upstreamed + version. + + Signed-off-by: Mischa Jonker -2010-10-01 Jakub Jelinek +commit d3d099b40c122550279789200263346f120f6909 +Author: Anthony Green +Date: Tue Jul 2 16:11:38 2013 -0400 - PR libffi/45677 - * src/x86/ffi64.c (ffi_prep_cif_machdep): Ensure cif->bytes is - a multiple of 8. - * testsuite/libffi.call/many2.c: New test. + little-endian ppc64 support -2010-08-20 Mark Wielaard +commit 0f8690a84c874ec09a090c8c6adfb93c594acac6 +Author: Anthony Green +Date: Tue Jul 2 15:54:40 2013 -0400 - * src/closures.c (open_temp_exec_file_mnt): Check if getmntent_r - returns NULL. + Rebuild for ARC additions -2010-08-09 Andreas Tobler +commit f88118b345f27c46f5445d6e4832c498ff9a6d85 +Author: Anthony Green +Date: Tue Jul 2 15:51:27 2013 -0400 - * configure.ac: Add target powerpc64-*-freebsd*. - * configure: Regenerate. - * testsuite/libffi.call/cls_align_longdouble_split.c: Pass - -mlong-double-128 only to linux targets. - * testsuite/libffi.call/cls_align_longdouble_split2.c: Likewise. - * testsuite/libffi.call/cls_longdouble.c: Likewise. - * testsuite/libffi.call/huge_struct.c: Likewise. + Revert "Merge pull request #36 from abergmeier/emscripten_fix" + + This reverts commit 6a4d901dde7b3f87984c563505717cde3113d16e, reversing + changes made to b50a13b9c07ec09af4b9697e482acdad571e6961. -2010-08-05 Dan Witte +commit 6a4d901dde7b3f87984c563505717cde3113d16e +Merge: b50a13b 587002c +Author: Anthony Green +Date: Tue Jul 2 12:12:34 2013 -0700 - * Makefile.am: Pass FFI_DEBUG define to msvcc.sh for linking to the - debug CRT when --enable-debug is given. - * configure.ac: Define it. - * msvcc.sh: Translate -g and -DFFI_DEBUG appropriately. + Merge pull request #36 from abergmeier/emscripten_fix + + Fixes for building with Emscripten -2010-08-04 Dan Witte +commit b50a13b9c07ec09af4b9697e482acdad571e6961 +Merge: 767f1f9 b082e15 +Author: Anthony Green +Date: Tue Jul 2 12:10:26 2013 -0700 - * src/x86/ffitarget.h: Add X86_ANY define for all x86/x86_64 - platforms. - * src/x86/ffi.c: Remove redundant ifdef checks. - * src/prep_cif.c: Push stack space computation into src/x86/ffi.c - for X86_ANY so return value space doesn't get added twice. + Merge pull request #44 from foss-for-synopsys-dwc-arc-processors/arc_support + + Add ARC support -2010-08-03 Neil Rashbrooke +commit 767f1f96e5282da44d7340e6815e9820a3f78e39 +Merge: c3c40e0 b8a91d8 +Author: Anthony Green +Date: Tue Jul 2 12:08:04 2013 -0700 - * msvcc.sh: Don't pass -safeseh to ml64 because behavior is buggy. + Merge pull request #43 from JensTimmerman/__m128 + + added include for xmmintrin.h -2010-07-22 Dan Witte +commit b8a91d81be77d479327fdb6bdd9fdae6d18e6e63 +Author: Jens Timmerman +Date: Tue Jul 2 10:57:37 2013 +0200 - * src/*/ffitarget.h: Make FFI_LAST_ABI one past the last valid ABI. - * src/prep_cif.c: Fix ABI assertion. - * src/cris/ffi.c: Ditto. + added include for xmmintrin.h -2010-07-10 Evan Phoenix +commit b082e15091961373c03d10ed0251f619ebb6ed76 +Author: Mischa Jonker +Date: Mon Jun 10 16:19:33 2013 +0200 - * src/closures.c (selinux_enabled_check): Fix strncmp usage bug. + Add ARC support + + This adds support for the ARC architecture to libffi. DesignWare ARC + is a family of processors from Synopsys, Inc. + + This patch has been tested on a little-endian system and passes + the testsuite. + + Signed-off-by: Mischa Jonker -2010-07-07 Dan Horák +commit cc9b518687e46b0d1acafdd4bc3f3b281c25a3d9 +Author: Marcin Wojdyr +Date: Tue May 14 15:01:23 2013 +0200 - * include/ffi.h.in: Protect #define with #ifndef. - * src/powerpc/ffitarget.h: Ditto. - * src/s390/ffitarget.h: Ditto. - * src/sparc/ffitarget.h: Ditto. + Update libffi.pc.in + + use -L${toolexeclibdir} instead of -L${libdir} + to be consistent with Makefile.am -2010-07-07 Neil Roberts +commit 587002c092cffe6e7a8d7028f246c241d03b738c +Author: Andreas Bergmeier +Date: Fri Apr 19 17:12:24 2013 +0200 - * src/x86/sysv.S (ffi_call_SYSV): Align the stack pointer to - 16-bytes. + Enable disabling of libtool on platforms where it does not work (e.g. LLVM). + Build libraries normally then. -2010-07-02 Jakub Jelinek +commit c3c40e0290377d7cf948b072eedd8317c4bf215e +Merge: ede96e4 4750e3c +Author: Anthony Green +Date: Sat Mar 30 05:24:14 2013 -0700 - * Makefile.am (AM_MAKEFLAGS): Pass also mandir to submakes. - * Makefile.in: Regenerated. + Merge pull request #34 from davidsch/armhf + + Fix ARM hard-float support for large numbers of VFP arguments -2010-05-19 Rainer Orth +commit 4750e3c662fd9569cb3e2d28f539685fd1ca8caf +Author: David Schneider +Date: Thu Mar 28 16:56:36 2013 +0100 - * configure.ac (libffi_cv_as_x86_pcrel): Check for illegal in as - output, too. - (libffi_cv_as_ascii_pseudo_op): Check for .ascii. - (libffi_cv_as_string_pseudo_op): Check for .string. - * configure: Regenerate. - * fficonfig.h.in: Regenerate. - * src/x86/sysv.S (.eh_frame): Use .ascii, .string or error. + update changelog -2010-05-11 Dan Witte +commit 9708e7cf09f1bf815f4d6485eb1f180fabb35804 +Author: David Schneider +Date: Wed Mar 27 19:31:04 2013 +0100 - * doc/libffi.tex: Document previous change. + folow the ARM hard-float ABI in ffi_prep_incoming_args_VFP -2010-05-11 Makoto Kato +commit b41120981e5e49ca2da10b94b154775f50da5f36 +Author: David Schneider +Date: Wed Mar 27 16:38:35 2013 +0100 - * src/x86/ffi.c (ffi_call): Don't copy structs passed by value. + create separated versions of ffi_prep_incoming_args_* for SYSV and VFP ABIs. + + The different versions will be called depending on the value of cif->abi -2010-05-05 Michael Kohler +commit dd26f1f39c54861c5b91931f0f37a72942c2a072 +Author: David Schneider +Date: Thu Mar 28 15:39:01 2013 +0100 - * src/dlmalloc.c (dlfree): Fix spelling. - * src/ia64/ffi.c (ffi_prep_cif_machdep): Ditto. - * configure.ac: Ditto. - * configure: Rebuilt. + add a failing test for closures on ARM hardfloat -2010-04-13 Dan Witte +commit 3c1608613ab3c2184222b98c5482cddedd6b559b +Author: David Schneider +Date: Tue Mar 26 19:24:47 2013 +0100 - * msvcc.sh: Build with -W3 instead of -Wall. - * src/powerpc/ffi_darwin.c: Remove build warnings. - * src/x86/ffi.c: Ditto. - * src/x86/ffitarget.h: Ditto. + extend ffi_prepare_args for FFI_VFP (hard-float ABI), fixing an issue with passing VFP arguments in VFP registers and the stack, while at the same time not using all core registers. -2010-04-12 Dan Witte - Walter Meinl +commit 0f2ff2d4c92719be8936179f9ab674f4d1a3fd14 +Author: David Schneider +Date: Tue Mar 26 19:22:02 2013 +0100 - * configure.ac: Add OS/2 support. - * configure: Rebuilt. - * src/closures.c: Ditto. - * src/dlmalloc.c: Ditto. - * src/x86/win32.S: Ditto. + separate ARM ffi_prepare_args in a version implementing the simple SYSV calling convention and one for the hard-float calling convention -2010-04-07 Jakub Jelinek +commit 3a352b8a8252400a83de22c7c424bf1887b4a2ef +Author: David Schneider +Date: Tue Mar 26 14:24:04 2013 +0100 - * testsuite/libffi.call/err_bad_abi.c: Remove unused args variable. + move the hardfloat specific argument copying code to the helper function -2010-04-02 Ralf Wildenhues +commit 5df6b7944a4225b6eb329f3886be64e04e966f29 +Author: David Schneider +Date: Tue Mar 26 14:02:21 2013 +0100 - * Makefile.in: Regenerate. - * aclocal.m4: Regenerate. - * include/Makefile.in: Regenerate. - * man/Makefile.in: Regenerate. - * testsuite/Makefile.in: Regenerate. + extract setting of arguments to be passed to a helper function -2010-03-30 Dan Witte +commit 7d1048c471bb4b1f9d67a9e9f8e95f9a1d2e6d45 +Author: David Schneider +Date: Tue Mar 26 11:33:33 2013 +0100 - * msvcc.sh: Disable build warnings. - * README (tested): Clarify windows build procedure. + extract code to align the argument storage pointer to a helper function -2010-03-15 Rainer Orth +commit b9f013788f0f384c423ad963475aaacb55598135 +Author: David Schneider +Date: Mon Mar 25 13:27:36 2013 +0100 - * configure.ac (libffi_cv_as_x86_64_unwind_section_type): New test. - * configure: Regenerate. - * fficonfig.h.in: Regenerate. - * libffi/src/x86/unix64.S (.eh_frame) - [HAVE_AS_X86_64_UNWIND_SECTION_TYPE]: Use @unwind section type. + add a testcase, that on ARM hardfloat needs more than the 8 VFP argument registers to pass arguments to a call -2010-03-14 Matthias Klose +commit 2fbdb0f231cafdb77b025d3cd8afe90cda99b3ba +Author: David Schneider +Date: Mon Mar 25 13:26:02 2013 +0100 - * src/x86/ffi64.c: Fix typo in comment. - * src/x86/ffi.c: Use /* ... */ comment style. + use the absolute value to check the test result against an epsilon -2010-02-24 Rainer Orth +commit ede96e4eb660bbf3e0fe048135efa8106f48af5d +Merge: f22ab3c 9e34992 +Author: Anthony Green +Date: Sun Mar 17 18:38:21 2013 -0400 - * doc/libffi.texi (The Closure API): Fix typo. - * doc/libffi.info: Remove. + Merge branch 'master' of github.com:/atgreen/libffi -2010-02-15 Matthias Klose +commit f22ab3c6877cbdd07f058b68816b0086b1cb0e1e +Merge: 12b1886 d08124b +Author: Anthony Green +Date: Sun Mar 17 18:34:54 2013 -0400 - * src/arm/sysv.S (__ARM_ARCH__): Define for processor - __ARM_ARCH_7EM__. + Merge branch 'master' of github.com:/atgreen/libffi -2010-01-15 Anthony Green +commit 9e34992a5ea2fda1dba5875bf96dc91a7230f51f +Merge: 12b1886 d08124b +Author: Anthony Green +Date: Sun Mar 17 18:34:54 2013 -0400 - * README: Add notes on building with Microsoft Visual C++. + Merge branch 'master' of github.com:/atgreen/libffi -2010-01-15 Daniel Witte +commit 12b1886d7b1f8aa264b1d348bfa47a0e14712df4 +Author: Anthony Green +Date: Sun Mar 17 18:32:12 2013 -0400 - * msvcc.sh: New file. + cygwin fix & updates for 3.0.13 - * src/x86/win32.S: Port assembly routines to MSVC and #ifdef. - * src/x86/ffi.c: Tweak function declaration and remove excess - parens. - * include/ffi.h.in: Add __declspec(align(8)) to typedef struct - ffi_closure. +commit d08124bedf2c6d61874fe215404783aeb9f6f1ac +Author: Anthony Green +Date: Sun Mar 17 18:32:12 2013 -0400 - * src/x86/ffi.c: Merge ffi_call_SYSV and ffi_call_STDCALL into new - function ffi_call_win32 on X86_WIN32. - * src/x86/win32.S (ffi_call_SYSV): Rename to ffi_call_win32. - (ffi_call_STDCALL): Remove. + cygwin fix & updates for 3.0.13 - * src/prep_cif.c (ffi_prep_cif): Move stack space allocation code - to ffi_prep_cif_machdep for x86. - * src/x86/ffi.c (ffi_prep_cif_machdep): To here. +commit cb32c812d04d1dfa72002cc04924e7e4fef89e02 +Author: Anthony Green +Date: Sun Mar 17 09:27:55 2013 -0400 -2010-01-15 Oliver Kiddle + Fix lib install dir - * src/x86/ffitarget.h (ffi_abi): Check for __i386 and __amd64 for - Sun Studio compiler compatibility. +commit efd7866a361a6f636bae8400d26c6811e56ca207 +Author: Anthony Green +Date: Sat Mar 16 08:35:57 2013 -0400 -2010-01-12 Conrad Irwin + 2.0.13rc1 - * doc/libffi.texi: Add closure example. +commit ff647ad4dff2f07dd153f295a1f70b1d906cd6ca +Merge: 4acf005 d9dd417 +Author: Anthony Green +Date: Sat Mar 16 08:20:40 2013 -0400 -2010-01-07 Rainer Orth + Merge branch 'master' of github.com:/atgreen/libffi + + Conflicts: + ChangeLog - PR libffi/40701 - * testsuite/libffi.call/ffitest.h [__alpha__ && __osf__] (PRIdLL, - PRIuLL, PRId64, PRIu64, PRIuPTR): Define. - * testsuite/libffi.call/cls_align_sint64.c: Add -Wno-format on - alpha*-dec-osf*. - * testsuite/libffi.call/cls_align_uint64.c: Likewise. - * testsuite/libffi.call/cls_ulonglong.c: Likewise. - * testsuite/libffi.call/return_ll1.c: Likewise. - * testsuite/libffi.call/stret_medium2.c: Likewise. - * testsuite/libffi.special/ffitestcxx.h (allocate_mmap): Cast - MAP_FAILED to char *. +commit 4acf0056f55c757490dae6c29a65b0321327ea8a +Author: Anthony Green +Date: Sat Mar 16 08:18:45 2013 -0400 -2010-01-06 Rainer Orth + Build fix for soft-float power targets - * src/mips/n32.S: Use .abicalls and .eh_frame with __GNUC__. +commit 675c9839224e4268187f1ec6f512127f9db555d0 +Author: Anthony Green +Date: Sat Mar 16 08:12:38 2013 -0400 -2009-12-31 Anthony Green + Documentation fix - * README: Update for libffi 3.0.9. +commit 8a286f570ccd41db81f74ea7f248da62241d898a +Author: Anthony Green +Date: Sat Mar 16 08:01:19 2013 -0400 -2009-12-27 Matthias Klose + Fix for m68000 systems - * configure.ac (HAVE_LONG_DOUBLE): Define for mips when - appropriate. - * configure: Rebuilt. +commit d9dd417b09566af55b7b3000bb53ccaf2e1d6c92 +Author: Anthony Green +Date: Sat Mar 16 08:01:19 2013 -0400 -2009-12-26 Anthony Green + Fix for m68000 systems - * testsuite/libffi.call/cls_longdouble_va.c: Mark as xfail for - avr32*-*-*. - * testsuite/libffi.call/cls_double_va.c: Ditto. +commit 215763d012a944d95406b394d6013b80d220e870 +Author: Anthony Green +Date: Sat Mar 16 07:57:35 2013 -0400 -2009-12-26 Andreas Tobler + Update configury. - * testsuite/libffi.call/ffitest.h: Conditionally include stdint.h - and inttypes.h. - * testsuite/libffi.special/unwindtest.cc: Ditto. +commit 9180d8f39c9b6afe17b78277c2711a5d9948e824 +Merge: 2fb527a 7e1b326 +Author: Anthony Green +Date: Sat Mar 16 07:46:55 2013 -0400 -2009-12-26 Andreas Tobler + Merge branch 'master' of github.com:/atgreen/libffi - * configure.ac: Add amd64-*-openbsd*. - * configure: Rebuilt. - * testsuite/lib/libffi-dg.exp (libffi_target_compile): Link - openbsd programs with -lpthread. +commit 2fb527a017a4943e176a489ff103231b86464b59 +Author: Anthony Green +Date: Sat Mar 16 07:46:38 2013 -0400 -2009-12-26 Anthony Green + Add Meta processor support - * testsuite/libffi.call/cls_double_va.c, - testsuite/libffi.call/cls_longdouble.c, - testsuite/libffi.call/cls_longdouble_va.c, - testsuite/libffi.call/cls_pointer.c, - testsuite/libffi.call/cls_pointer_stack.c: Remove xfail for - mips*-*-* and arm*-*-*. - * testsuite/libffi.call/cls_align_longdouble_split.c, - testsuite/libffi.call/cls_align_longdouble_split2.c, - testsuite/libffi.call/stret_medium2.c, - testsuite/libffi.call/stret_medium.c, - testsuite/libffi.call/stret_large.c, - testsuite/libffi.call/stret_large2.c: Remove xfail for arm*-*-*. +commit 211a9ebf4d1a9801e15e103566aed2b8c42790be +Merge: f308faf ee18766 +Author: Anthony Green +Date: Sat Mar 16 04:24:40 2013 -0700 -2009-12-31 Kay Tietz + Merge pull request #32 from alex/patch-1 + + Fix for a crasher due to misaligned stack on x86-32. - * testsuite/libffi.call/ffitest.h, - testsuite/libffi.special/ffitestcxx.h (PRIdLL, PRuLL): Fix - definitions. +commit 7e1b32649efd24814e86172e196f390566f9e970 +Merge: f308faf ee18766 +Author: Anthony Green +Date: Sat Mar 16 04:24:40 2013 -0700 -2009-12-31 Carlo Bramini + Merge pull request #32 from alex/patch-1 + + Fix for a crasher due to misaligned stack on x86-32. - * configure.ac (AM_LTLDFLAGS): Define for windows hosts. - * Makefile.am (libffi_la_LDFLAGS): Add AM_LTLDFLAGS. - * configure: Rebuilt. - * Makefile.in: Rebuilt. +commit ee18766b169811426c14b011fbb46d81e344f926 +Author: Alex Gaynor +Date: Thu Mar 14 15:00:33 2013 -0700 -2009-12-31 Anthony Green - Blake Chaffin. + Fix for a crasher due to misaligned stack on x86-32. + + Full information on reproduction (using Python's ctypes available here: http://bugs.python.org/issue17423) - * testsuite/libffi.call/huge_struct.c: New test case from Blake - Chaffin @ Apple. +commit f308faf1eabaf8dc24966ab17fbf94368f46b9c7 +Author: Anthony Green +Date: Mon Feb 11 14:25:13 2013 -0500 -2009-12-28 David Edelsohn + Add moxie support. Release 3.0.12. - * src/powerpc/ffi_darwin.c (ffi_prep_args): Copy abi and nargs to - local variables. - (aix_adjust_aggregate_sizes): New function. - (ffi_prep_cif_machdep): Call it. +commit 4ea22e54e3b143fe05c413f6dddd236af6bcbfb2 +Author: Anthony Green +Date: Sun Feb 10 08:48:38 2013 -0500 -2009-12-26 Andreas Tobler + Update README - * configure.ac: Define FFI_MMAP_EXEC_WRIT for the given targets. - * configure: Regenerate. - * fficonfig.h.in: Likewise. - * src/closures.c: Remove the FFI_MMAP_EXEC_WRIT definition for - Solaris/x86. +commit 10e77227b6ae85f46f28590bfb09ca3608554358 +Author: Anthony Green +Date: Sun Feb 10 08:47:26 2013 -0500 -2009-12-26 Andreas Schwab + mend - * src/powerpc/ffi.c (ffi_prep_args_SYSV): Advance intarg_count - when a float arguments is passed in memory. - (ffi_closure_helper_SYSV): Mark general registers as used up when - a 64bit or soft-float long double argument is passed in memory. +commit a9521411a53d58f2bf88199242200ceb0d4dae3a +Author: Anthony Green +Date: Sat Feb 9 06:54:40 2013 -0500 -2009-12-25 Matthias Klose + sparc v8 and testsuite fixes - * man/ffi_call.3: Fix #include in examples. - * doc/libffi.texi: Add dircategory. +commit 70b11b47eea93bf43627588d494d0b3b0d062481 +Author: Anthony Green +Date: Fri Feb 8 16:12:19 2013 -0500 -2009-12-25 Frank Everdij + Fix small struct passing on ppc - * include/ffi.h.in: Placed '__GNUC__' ifdef around - '__attribute__((aligned(8)))' in ffi_closure, fixes compile for - IRIX MIPSPro c99. - * include/ffi_common.h: Added '__sgi' define to non - '__attribute__((__mode__()))' integer typedefs. - * src/mips/ffi.c (ffi_call, ffi_closure_mips_inner_O32, - ffi_closure_mips_inner_N32): Added 'defined(_MIPSEB)' to BE check. - (ffi_closure_mips_inner_O32, ffi_closure_mips_inner_N32): Added - FFI_LONGDOUBLE support and alignment(N32 only). - * src/mips/ffitarget.h: Corrected '#include ' for IRIX and - fixed non '__attribute__((__mode__()))' integer typedefs. - * src/mips/n32.S: Put '#ifdef linux' around '.abicalls' and '.eh_frame' - since they are Linux/GNU Assembler specific. +commit 63ba1fa79f7c4ce42de848debe233aab31aecb51 +Author: Anthony Green +Date: Fri Feb 8 15:18:19 2013 -0500 -2009-12-25 Bradley Smith + Remove xfail for arm*-*-*. - * configure.ac, Makefile.am, src/avr32/ffi.c, - src/avr32/ffitarget.h, - src/avr32/sysv.S: Add AVR32 port. - * configure, Makefile.in: Rebuilt. +commit 24fbca4c1d57d4ea628c0a8ba643684daf54a37e +Author: Anthony Green +Date: Fri Feb 8 14:19:56 2013 -0500 -2009-12-21 Andreas Tobler + Fix typo - * configure.ac: Make i?86 build on FreeBSD and OpenBSD. - * configure: Regenerate. +commit b0fa11cb0a94ce6baca058eab9b10e40475e71d6 +Author: Anthony Green +Date: Fri Feb 8 14:17:13 2013 -0500 -2009-12-15 John David Anglin + More man page cleanup - * testsuite/libffi.call/ffitest.h: Define PRIuPTR on PA HP-UX. +commit 8bd15d139a58a6e46dc90a1cb2d89f59f32f06c7 +Author: Anthony Green +Date: Fri Feb 8 13:56:37 2013 -0500 -2009-12-13 John David Anglin + Fix many.c testcase for ppc - * src/pa/ffi.c (ffi_closure_inner_pa32): Handle FFI_TYPE_LONGDOUBLE - type on HP-UX. +commit 7aab825cf198be85490d3cd80e778d415d85ad9b +Author: Anthony Green +Date: Fri Feb 8 13:26:21 2013 -0500 -2012-02-13 Kai Tietz + Add missing files to dist - PR libffi/52221 - * src/x86/ffi.c (ffi_prep_raw_closure_loc): Add thiscall - support for X86_WIN32. - (FFI_INIT_TRAMPOLINE_THISCALL): Fix displacement. +commit cb03ea8f4eb08024e44abe4392edc77b89fbfbad +Author: Anthony Green +Date: Fri Feb 8 12:25:18 2013 -0500 -2009-12-11 Eric Botcazou + sparc v9 fixes for sun tools - * src/sparc/ffi.c (ffi_closure_sparc_inner_v9): Properly align 'long - double' arguments. +commit 35ee8d44f31dd3d3b88083c837dc351593e13cc2 +Author: Anthony Green +Date: Fri Feb 8 07:12:41 2013 -0500 -2009-12-11 Eric Botcazou + Fix microblaze big-endian struct issue - * testsuite/libffi.call/ffitest.h: Define PRIuPTR on Solaris < 10. +commit 9db7e1a958fc484ba149efe027008b9a170395fb +Author: Anthony Green +Date: Thu Feb 7 21:06:08 2013 -0500 -2009-12-10 Rainer Orth + Fix botched sparc patch. Update version. - PR libffi/40700 - * src/closures.c [X86_64 && __sun__ && __svr4__] - (FFI_MMAP_EXEC_WRIT): Define. +commit ce0138e61455f268af326e26908b9680ec2c4bea +Author: Anthony Green +Date: Thu Feb 7 18:04:01 2013 -0500 -2009-12-08 David Daney + Update bug report address. rc2. - * testsuite/libffi.call/stret_medium.c: Remove xfail for mips*-*-* - * testsuite/libffi.call/cls_align_longdouble_split2.c: Same. - * testsuite/libffi.call/stret_large.c: Same. - * testsuite/libffi.call/cls_align_longdouble_split.c: Same. - * testsuite/libffi.call/stret_large2.c: Same. - * testsuite/libffi.call/stret_medium2.c: Same. +commit fd07c9e40451e0ec1d0475cd54a83d45ccaea2c0 +Author: Anthony Green +Date: Thu Feb 7 18:00:36 2013 -0500 -2009-12-07 David Edelsohn + Add cache flushing routine for sun compiler on sparc solaris 2.8 - * src/powerpc/aix_closure.S (libffi_closure_ASM): Fix tablejump - typo. +commit ed6ae9501b2bab45daf93b4935eb0c977635b763 +Author: Anthony Green +Date: Thu Feb 7 16:43:36 2013 -0500 -2009-12-05 David Edelsohn + Add libtool-ldflags. Define toolexeclibdir for non-GCC builds. - * src/powerpc/aix.S: Update AIX32 code to be consistent with AIX64 - code. - * src/powerpc/aix_closure.S: Same. +commit ffef2e046aaec853be356f0b8770a335185ea9cf +Author: Anthony Green +Date: Thu Feb 7 15:47:01 2013 -0500 -2009-12-05 Ralf Wildenhues + x32 and libtool fixes - * Makefile.in: Regenerate. - * configure: Regenerate. - * include/Makefile.in: Regenerate. - * man/Makefile.in: Regenerate. - * testsuite/Makefile.in: Regenerate. +commit 95eecebb2858dc6f1495a61072ff36d0a8127144 +Author: Anthony Green +Date: Thu Feb 7 15:32:46 2013 -0500 -2009-12-04 David Edelsohn + Remove a.out cruft from dist - * src/powerpc/aix_closure.S: Reorganize 64-bit code to match - linux64_closure.S. +commit 176aa9d2e23d9cd57d6f250692d910b408f9a651 +Author: Anthony Green +Date: Thu Feb 7 15:29:22 2013 -0500 -2009-12-04 Uros Bizjak + Fix GCC usage test and update README - PR libffi/41908 - * src/x86/ffi64.c (classify_argument): Update from - gcc/config/i386/i386.c. - (ffi_closure_unix64_inner): Do not use the address of two consecutive - SSE registers directly. - * testsuite/libffi.call/cls_dbls_struct.c (main): Remove xfail - for x86_64 linux targets. +commit f3a4f3fdde89b04d66983a42a25d09161c5d4d54 +Author: Anthony Green +Date: Thu Feb 7 09:57:20 2013 -0500 -2009-12-04 David Edelsohn + Fixes for AIX xlc compiler. - * src/powerpc/ffi_darwin.c (ffi_closure_helper_DARWIN): Increment - pfr for long double split between fpr13 and stack. +commit 522f8fef49848927482bc63c94afaea5b84e5ec1 +Author: Anthony Green +Date: Wed Feb 6 20:31:31 2013 -0500 -2009-12-03 David Edelsohn + Fix man page. Clean out junk. - * src/powerpc/ffi_darwin.c (ffi_prep_args): Increment next_arg and - fparg_count twice for long double. +commit c4dfa259eb4e8e6f4c397868d7fee80aa0bb6a12 +Author: Anthony Green +Date: Wed Feb 6 17:43:24 2013 -0500 -2009-12-03 David Edelsohn + Bump soversion - PR libffi/42243 - * src/powerpc/ffi_darwin.c (ffi_prep_args): Remove extra parentheses. +commit f62bd63fe6123cadedb8b2b2c72eb549c40fbce9 +Author: Anthony Green +Date: Wed Feb 6 17:38:32 2013 -0500 -2009-12-03 Uros Bizjak + Release candidate 1 - * testsuite/libffi.call/cls_longdouble_va.c (main): Fix format string. - Remove xfails for x86 linux targets. +commit f7cd61e9e68a4a51147df04d75bfe5b91b9d9286 +Author: Anthony Green +Date: Wed Feb 6 17:38:04 2013 -0500 -2009-12-02 David Edelsohn + Fix pkgconfig install bits - * src/powerpc/ffi_darwin.c (ffi_prep_args): Fix typo in INT64 - case. +commit 6a790129427121f7db2d876e7218a3104e6d2741 +Author: Anthony Green +Date: Wed Feb 6 17:37:15 2013 -0500 -2009-12-01 David Edelsohn + Work around LLVM ABI problem on x86-64 - * src/powerpc/aix.S (ffi_call_AIX): Convert to more standard - register usage. Call ffi_prep_args directly. Add long double - return value support. - * src/powerpc/ffi_darwin.c (ffi_prep_args): Double arg increment - applies to FFI_TYPE_DOUBLE. Correct fpr_base increment typo. - Separate FFI_TYPE_SINT32 and FFI_TYPE_UINT32 cases. - (ffi_prep_cif_machdep): Only 16 byte stack alignment in 64 bit - mode. - (ffi_closure_helper_DARWIN): Remove nf and ng counters. Move temp - into case. - * src/powerpc/aix_closure.S: Maintain 16 byte stack alignment. - Allocate result area between params and FPRs. +commit 370112938e705128fd5dd4017fc1a1210bd0271a +Merge: bada2e3 bcc0c28 +Author: Anthony Green +Date: Sun Jan 27 05:09:04 2013 -0800 -2009-11-30 David Edelsohn + Merge pull request #28 from jralls/master + + Reorder x86_64 checks - PR target/35484 - * src/powerpc/ffitarget.h (POWERPC64): Define for PPC64 Linux and - AIX64. - * src/powerpc/aix.S: Implement AIX64 version. - * src/powerpc/aix_closure.S: Implement AIX64 version. - (ffi_closure_ASM): Use extsb, lha and displament addresses. - * src/powerpc/ffi_darwin.c (ffi_prep_args): Implement AIX64 - support. - (ffi_prep_cif_machdep): Same. - (ffi_call): Same. - (ffi_closure_helper_DARWIN): Same. +commit bcc0c28001b6d427d5cd8037d2e3c892babc6b4c +Author: John Ralls +Date: Sat Jan 26 15:21:14 2013 -0800 -2009-11-02 Andreas Tobler + Reorder x86_64 tests + + So that darwin and cygwin/mingw are tested before the generic check -- + which allows them to actually be set. - PR libffi/41908 - * testsuite/libffi.call/testclosure.c: New test. +commit bada2e326d9a9acf3ae40cfa4f5d7a9ba97b2ea8 +Author: Anthony Green +Date: Mon Jan 21 08:02:07 2013 -0500 -2009-09-28 Kai Tietz + Update README - * src/x86/win64.S (_ffi_call_win64 stack): Remove for gnu - assembly version use of ___chkstk. +commit 655bb8f3690feba8e840a5f1854b1d78ed08f692 +Merge: 1035ffb 840f975 +Author: Anthony Green +Date: Mon Jan 21 08:01:24 2013 -0500 -2009-09-23 Matthias Klose + Merge branch 'master' of github.com:/atgreen/libffi - PR libffi/40242, PR libffi/41443 - * src/arm/sysv.S (__ARM_ARCH__): Define for processors - __ARM_ARCH_6T2__, __ARM_ARCH_6M__, __ARM_ARCH_7__, - __ARM_ARCH_7A__, __ARM_ARCH_7R__, __ARM_ARCH_7M__. - Change the conditionals to __SOFTFP__ || __ARM_EABI__ - for -mfloat-abi=softfp to work. +commit 1035ffb2f468e1a1c401d58cff7e7abb69838e68 +Merge: aeb8719 4086024 +Author: Anthony Green +Date: Mon Jan 21 07:55:53 2013 -0500 -2009-09-17 Loren J. Rittle + Update README - PR testsuite/32843 (strikes again) - * src/x86/ffi.c (ffi_prep_cif_machdep): Add X86_FREEBSD to - enable proper extension on char and short. +commit 840f975866052fdd91b2c224d56e01ae5900b60d +Merge: aeb8719 4086024 +Author: Anthony Green +Date: Mon Jan 21 07:55:53 2013 -0500 -2009-09-15 David Daney + Merge branch 'master' of github.com:/atgreen/libffi - * src/java_raw_api.c (ffi_java_raw_to_rvalue): Remove special - handling for FFI_TYPE_POINTER. - * src/mips/ffitarget.h (FFI_TYPE_STRUCT_D_SOFT, - FFI_TYPE_STRUCT_F_SOFT, FFI_TYPE_STRUCT_DD_SOFT, - FFI_TYPE_STRUCT_FF_SOFT, FFI_TYPE_STRUCT_FD_SOFT, - FFI_TYPE_STRUCT_DF_SOFT, FFI_TYPE_STRUCT_SOFT): New defines. - (FFI_N32_SOFT_FLOAT, FFI_N64_SOFT_FLOAT): New ffi_abi enumerations. - (enum ffi_abi): Set FFI_DEFAULT_ABI for soft-float. - * src/mips/n32.S (ffi_call_N32): Add handling for soft-float - structure and pointer returns. - (ffi_closure_N32): Add handling for pointer returns. - * src/mips/ffi.c (ffi_prep_args, calc_n32_struct_flags, - calc_n32_return_struct_flags): Handle soft-float. - (ffi_prep_cif_machdep): Handle soft-float, fix pointer handling. - (ffi_call_N32): Declare proper argument types. - (ffi_call, copy_struct_N32, ffi_closure_mips_inner_N32): Handle - soft-float. +commit aeb8719a34756969970603fca4568530d56708af +Author: Anthony Green +Date: Mon Jan 21 07:37:30 2013 -0500 -2009-08-24 Ralf Wildenhues + New microblaze support - * configure.ac (AC_PREREQ): Bump to 2.64. +commit 40860245a4fd91a1b88adc9171ec993c549e45d5 +Author: Anthony Green +Date: Mon Jan 21 07:37:30 2013 -0500 -2009-08-22 Ralf Wildenhues + New microblaze support - * Makefile.am (install-html, install-pdf): Remove. - * Makefile.in: Regenerate. +commit 20cae32b152b43679ae65a85db9a1c6bb8a143dd +Author: Anthony Green +Date: Mon Jan 21 07:07:38 2013 -0500 - * Makefile.in: Regenerate. - * aclocal.m4: Regenerate. - * configure: Regenerate. - * fficonfig.h.in: Regenerate. - * include/Makefile.in: Regenerate. - * man/Makefile.in: Regenerate. - * testsuite/Makefile.in: Regenerate. + Xtensa support -2011-08-22 Jasper Lievisse Adriaanse +commit 9742f91782faef4a15941508a22c408fb7d1d227 +Author: Anthony Green +Date: Mon Jan 21 07:03:41 2013 -0500 - * configure.ac: Add OpenBSD/hppa and OpenBSD/powerpc support. - * configure: Rebuilt. + Mention IBM XL compiler support on AIX. -2009-07-30 Ralf Wildenhues +commit f03eab08248f122ce3b623a18df9e19fae1b6e98 +Author: Anthony Green +Date: Fri Jan 11 17:14:11 2013 -0500 - * configure.ac (_AC_ARG_VAR_PRECIOUS): Use m4_rename_force. + Remove obsolete inline test functions -2009-07-24 Dave Korn - - PR libffi/40807 - * src/x86/ffi.c (ffi_prep_cif_machdep): Also use sign/zero-extending - return types for X86_WIN32. - * src/x86/win32.S (_ffi_call_SYSV): Handle omitted return types. - (_ffi_call_STDCALL, _ffi_closure_SYSV, _ffi_closure_raw_SYSV, - _ffi_closure_STDCALL): Likewise. - - * src/closures.c (is_selinux_enabled): Define to const 0 for Cygwin. - (dlmmap, dlmunmap): Also use these functions on Cygwin. - -2009-07-11 Richard Sandiford - - PR testsuite/40699 - PR testsuite/40707 - PR testsuite/40709 - * testsuite/lib/libffi-dg.exp: Revert 2009-07-02, 2009-07-01 and - 2009-06-30 commits. - -2009-07-01 Richard Sandiford - - * testsuite/lib/libffi-dg.exp (libffi-init): Set ld_library_path - to "" before adding paths. (This reinstates an assignment that - was removed by my 2009-06-30 commit, but changes the initial - value from "." to "".) - -2009-07-01 H.J. Lu - - PR testsuite/40601 - * testsuite/lib/libffi-dg.exp (libffi-init): Properly set - gccdir. Adjust ld_library_path for gcc only if gccdir isn't - empty. - -2009-06-30 Richard Sandiford - - * testsuite/lib/libffi-dg.exp (libffi-init): Don't add "." - to ld_library_path. Use add_path. Add just find_libgcc_s - to ld_library_path, not every libgcc multilib directory. - -2009-06-16 Wim Lewis - - * src/powerpc/ffi.c: Avoid clobbering cr3 and cr4, which are - supposed to be callee-saved. - * src/powerpc/sysv.S (small_struct_return_value): Fix overrun of - return buffer for odd-size structs. - -2009-06-16 Andreas Tobler - - PR libffi/40444 - * testsuite/lib/libffi-dg.exp (libffi_target_compile): Add - allow_stack_execute for Darwin. - -2009-06-16 Andrew Haley - - * configure.ac (TARGETDIR): Add missing blank lines. - * configure: Regenerate. - -2009-06-16 Andrew Haley - - * testsuite/libffi.call/cls_align_sint64.c, - testsuite/libffi.call/cls_align_uint64.c, - testsuite/libffi.call/cls_longdouble_va.c, - testsuite/libffi.call/cls_ulonglong.c, - testsuite/libffi.call/return_ll1.c, - testsuite/libffi.call/stret_medium2.c: Fix printf format - specifiers. - * testsuite/libffi.call/ffitest.h, - testsuite/libffi.special/ffitestcxx.h (PRIdLL, PRIuLL): Define. - -2009-06-15 Andrew Haley - - * testsuite/libffi.call/err_bad_typedef.c: xfail everywhere. - * testsuite/libffi.call/err_bad_abi.c: Likewise. - -2009-06-12 Andrew Haley - - * Makefile.am: Remove info_TEXINFOS. - -2009-06-12 Andrew Haley - - * ChangeLog.libffi: testsuite/libffi.call/cls_align_sint64.c, - testsuite/libffi.call/cls_align_uint64.c, - testsuite/libffi.call/cls_ulonglong.c, - testsuite/libffi.call/return_ll1.c, - testsuite/libffi.call/stret_medium2.c: Fix printf format - specifiers. - testsuite/libffi.special/unwindtest.cc: include stdint.h. - -2009-06-11 Timothy Wall - - * Makefile.am, - configure.ac, - include/ffi.h.in, - include/ffi_common.h, - src/closures.c, - src/dlmalloc.c, - src/x86/ffi.c, - src/x86/ffitarget.h, - src/x86/win64.S (new), - README: Added win64 support (mingw or MSVC) - * Makefile.in, - include/Makefile.in, - man/Makefile.in, - testsuite/Makefile.in, - configure, - aclocal.m4: Regenerated - * ltcf-c.sh: properly escape cygwin/w32 path - * man/ffi_call.3: Clarify size requirements for return value. - * src/x86/ffi64.c: Fix filename in comment. - * src/x86/win32.S: Remove unused extern. - - * testsuite/libffi.call/closure_fn0.c, - testsuite/libffi.call/closure_fn1.c, - testsuite/libffi.call/closure_fn2.c, - testsuite/libffi.call/closure_fn3.c, - testsuite/libffi.call/closure_fn4.c, - testsuite/libffi.call/closure_fn5.c, - testsuite/libffi.call/closure_fn6.c, - testsuite/libffi.call/closure_stdcall.c, - testsuite/libffi.call/cls_12byte.c, - testsuite/libffi.call/cls_16byte.c, - testsuite/libffi.call/cls_18byte.c, - testsuite/libffi.call/cls_19byte.c, - testsuite/libffi.call/cls_1_1byte.c, - testsuite/libffi.call/cls_20byte.c, - testsuite/libffi.call/cls_20byte1.c, - testsuite/libffi.call/cls_24byte.c, - testsuite/libffi.call/cls_2byte.c, - testsuite/libffi.call/cls_3_1byte.c, - testsuite/libffi.call/cls_3byte1.c, - testsuite/libffi.call/cls_3byte2.c, - testsuite/libffi.call/cls_4_1byte.c, - testsuite/libffi.call/cls_4byte.c, - testsuite/libffi.call/cls_5_1_byte.c, - testsuite/libffi.call/cls_5byte.c, - testsuite/libffi.call/cls_64byte.c, - testsuite/libffi.call/cls_6_1_byte.c, - testsuite/libffi.call/cls_6byte.c, - testsuite/libffi.call/cls_7_1_byte.c, - testsuite/libffi.call/cls_7byte.c, - testsuite/libffi.call/cls_8byte.c, - testsuite/libffi.call/cls_9byte1.c, - testsuite/libffi.call/cls_9byte2.c, - testsuite/libffi.call/cls_align_double.c, - testsuite/libffi.call/cls_align_float.c, - testsuite/libffi.call/cls_align_longdouble.c, - testsuite/libffi.call/cls_align_longdouble_split.c, - testsuite/libffi.call/cls_align_longdouble_split2.c, - testsuite/libffi.call/cls_align_pointer.c, - testsuite/libffi.call/cls_align_sint16.c, - testsuite/libffi.call/cls_align_sint32.c, - testsuite/libffi.call/cls_align_sint64.c, - testsuite/libffi.call/cls_align_uint16.c, - testsuite/libffi.call/cls_align_uint32.c, - testsuite/libffi.call/cls_align_uint64.c, - testsuite/libffi.call/cls_dbls_struct.c, - testsuite/libffi.call/cls_double.c, - testsuite/libffi.call/cls_double_va.c, - testsuite/libffi.call/cls_float.c, - testsuite/libffi.call/cls_longdouble.c, - testsuite/libffi.call/cls_longdouble_va.c, - testsuite/libffi.call/cls_multi_schar.c, - testsuite/libffi.call/cls_multi_sshort.c, - testsuite/libffi.call/cls_multi_sshortchar.c, - testsuite/libffi.call/cls_multi_uchar.c, - testsuite/libffi.call/cls_multi_ushort.c, - testsuite/libffi.call/cls_multi_ushortchar.c, - testsuite/libffi.call/cls_pointer.c, - testsuite/libffi.call/cls_pointer_stack.c, - testsuite/libffi.call/cls_schar.c, - testsuite/libffi.call/cls_sint.c, - testsuite/libffi.call/cls_sshort.c, - testsuite/libffi.call/cls_uchar.c, - testsuite/libffi.call/cls_uint.c, - testsuite/libffi.call/cls_ulonglong.c, - testsuite/libffi.call/cls_ushort.c, - testsuite/libffi.call/err_bad_abi.c, - testsuite/libffi.call/err_bad_typedef.c, - testsuite/libffi.call/float2.c, - testsuite/libffi.call/huge_struct.c, - testsuite/libffi.call/nested_struct.c, - testsuite/libffi.call/nested_struct1.c, - testsuite/libffi.call/nested_struct10.c, - testsuite/libffi.call/nested_struct2.c, - testsuite/libffi.call/nested_struct3.c, - testsuite/libffi.call/nested_struct4.c, - testsuite/libffi.call/nested_struct5.c, - testsuite/libffi.call/nested_struct6.c, - testsuite/libffi.call/nested_struct7.c, - testsuite/libffi.call/nested_struct8.c, - testsuite/libffi.call/nested_struct9.c, - testsuite/libffi.call/problem1.c, - testsuite/libffi.call/return_ldl.c, - testsuite/libffi.call/return_ll1.c, - testsuite/libffi.call/stret_large.c, - testsuite/libffi.call/stret_large2.c, - testsuite/libffi.call/stret_medium.c, - testsuite/libffi.call/stret_medium2.c, - testsuite/libffi.special/unwindtest.cc: use ffi_closure_alloc instead - of checking for MMAP. Use intptr_t instead of long casts. - -2009-06-11 Kaz Kojima - - * testsuite/libffi.call/cls_longdouble_va.c: Add xfail sh*-*-linux-*. - * testsuite/libffi.call/err_bad_abi.c: Add xfail sh*-*-*. - * testsuite/libffi.call/err_bad_typedef.c: Likewise. - -2009-06-09 Andrew Haley - - * src/x86/freebsd.S: Add missing file. - -2009-06-08 Andrew Haley - - Import from libffi 3.0.8: - - * doc/libffi.texi: New file. - * doc/libffi.info: Likewise. - * doc/stamp-vti: Likewise. - * man/Makefile.am: New file. - * man/ffi_call.3: New file. - - * Makefile.am (EXTRA_DIST): Add src/x86/darwin64.S, - src/dlmalloc.c. - (nodist_libffi_la_SOURCES): Add X86_FREEBSD. - - * configure.ac: Bump version to 3.0.8. - parisc*-*-linux*: Add. - i386-*-freebsd* | i386-*-openbsd*: Add. - powerpc-*-beos*: Add. - AM_CONDITIONAL X86_FREEBSD: Add. - AC_CONFIG_FILES: Add man/Makefile. - - * include/ffi.h.in (FFI_FN): Change void (*)() to void (*)(void). - -2009-06-08 Andrew Haley - - * README: Import from libffi 3.0.8. - -2009-06-08 Andrew Haley - - * testsuite/libffi.call/err_bad_abi.c: Add xfails. - * testsuite/libffi.call/cls_longdouble_va.c: Add xfails. - * testsuite/libffi.call/cls_dbls_struct.c: Add xfail x86_64-*-linux-*. - * testsuite/libffi.call/err_bad_typedef.c: Add xfails. - - * testsuite/libffi.call/stret_medium2.c: Add __UNUSED__ to args. - * testsuite/libffi.call/stret_medium.c: Likewise. - * testsuite/libffi.call/stret_large2.c: Likewise. - * testsuite/libffi.call/stret_large.c: Likewise. - -2008-12-26 Timothy Wall - - * testsuite/libffi.call/cls_longdouble.c, - testsuite/libffi.call/cls_longdouble_va.c, - testsuite/libffi.call/cls_align_longdouble.c, - testsuite/libffi.call/cls_align_longdouble_split.c, - testsuite/libffi.call/cls_align_longdouble_split2.c: mark expected - failures on x86_64 cygwin/mingw. - -2008-12-22 Timothy Wall - - * testsuite/libffi.call/closure_fn0.c, - testsuite/libffi.call/closure_fn1.c, - testsuite/libffi.call/closure_fn2.c, - testsuite/libffi.call/closure_fn3.c, - testsuite/libffi.call/closure_fn4.c, - testsuite/libffi.call/closure_fn5.c, - testsuite/libffi.call/closure_fn6.c, - testsuite/libffi.call/closure_loc_fn0.c, - testsuite/libffi.call/closure_stdcall.c, - testsuite/libffi.call/cls_align_pointer.c, - testsuite/libffi.call/cls_pointer.c, - testsuite/libffi.call/cls_pointer_stack.c: use portable cast from - pointer to integer (intptr_t). - * testsuite/libffi.call/cls_longdouble.c: disable for win64. - -2008-07-24 Anthony Green - - * testsuite/libffi.call/cls_dbls_struct.c, - testsuite/libffi.call/cls_double_va.c, - testsuite/libffi.call/cls_longdouble.c, - testsuite/libffi.call/cls_longdouble_va.c, - testsuite/libffi.call/cls_pointer.c, - testsuite/libffi.call/cls_pointer_stack.c, - testsuite/libffi.call/err_bad_abi.c: Clean up failures from - compiler warnings. - -2008-03-04 Anthony Green - Blake Chaffin - hos@tamanegi.org - - * testsuite/libffi.call/cls_align_longdouble_split2.c - testsuite/libffi.call/cls_align_longdouble_split.c - testsuite/libffi.call/cls_dbls_struct.c - testsuite/libffi.call/cls_double_va.c - testsuite/libffi.call/cls_longdouble.c - testsuite/libffi.call/cls_longdouble_va.c - testsuite/libffi.call/cls_pointer.c - testsuite/libffi.call/cls_pointer_stack.c - testsuite/libffi.call/err_bad_abi.c - testsuite/libffi.call/err_bad_typedef.c - testsuite/libffi.call/stret_large2.c - testsuite/libffi.call/stret_large.c - testsuite/libffi.call/stret_medium2.c - testsuite/libffi.call/stret_medium.c: New tests from Apple. - -2009-06-05 Andrew Haley - - * src/x86/ffitarget.h, src/x86/ffi.c: Merge stdcall changes from - libffi. - -2009-06-04 Andrew Haley - - * src/x86/ffitarget.h, src/x86/win32.S, src/x86/ffi.c: Back out - stdcall changes. - -2008-02-26 Anthony Green - Thomas Heller - - * src/x86/ffi.c (ffi_closure_SYSV_inner): Change C++ comment to C - comment. - -2008-02-03 Timothy Wall - - * src/x86/ffi.c (FFI_INIT_TRAMPOLINE_STDCALL): Calculate jump return - offset based on code pointer, not data pointer. - -2008-01-31 Timothy Wall - - * testsuite/libffi.call/closure_stdcall.c: Add test for stdcall - closures. - * src/x86/ffitarget.h: Increase size of trampoline for stdcall - closures. - * src/x86/win32.S: Add assembly for stdcall closure. - * src/x86/ffi.c: Initialize stdcall closure trampoline. - -2009-06-04 Andrew Haley - - * include/ffi.h.in: Change void (*)() to void (*)(void). - * src/x86/ffi.c: Likewise. - -2009-06-04 Andrew Haley - - * src/powerpc/ppc_closure.S: Insert licence header. - * src/powerpc/linux64_closure.S: Likewise. - * src/m68k/sysv.S: Likewise. - - * src/sh64/ffi.c: Change void (*)() to void (*)(void). - * src/powerpc/ffi.c: Likewise. - * src/powerpc/ffi_darwin.c: Likewise. - * src/m32r/ffi.c: Likewise. - * src/sh64/ffi.c: Likewise. - * src/x86/ffi64.c: Likewise. - * src/alpha/ffi.c: Likewise. - * src/alpha/osf.S: Likewise. - * src/frv/ffi.c: Likewise. - * src/s390/ffi.c: Likewise. - * src/pa/ffi.c: Likewise. - * src/pa/hpux32.S: Likewise. - * src/ia64/unix.S: Likewise. - * src/ia64/ffi.c: Likewise. - * src/sparc/ffi.c: Likewise. - * src/mips/ffi.c: Likewise. - * src/sh/ffi.c: Likewise. - -2008-02-15 David Daney - - * src/mips/ffi.c (USE__BUILTIN___CLEAR_CACHE): - Define (conditionally), and use it to include cachectl.h. - (ffi_prep_closure_loc): Fix cache flushing. - * src/mips/ffitarget.h (_ABIN32, _ABI64, _ABIO32): Define. - -2009-06-04 Andrew Haley - - include/ffi.h.in, - src/arm/ffitarget.h, - src/arm/ffi.c, - src/arm/sysv.S, - src/powerpc/ffitarget.h, - src/closures.c, - src/sh64/ffitarget.h, - src/sh64/ffi.c, - src/sh64/sysv.S, - src/types.c, - src/x86/ffi64.c, - src/x86/ffitarget.h, - src/x86/win32.S, - src/x86/darwin.S, - src/x86/ffi.c, - src/x86/sysv.S, - src/x86/unix64.S, - src/alpha/ffitarget.h, - src/alpha/ffi.c, - src/alpha/osf.S, - src/m68k/ffitarget.h, - src/frv/ffitarget.h, - src/frv/ffi.c, - src/s390/ffitarget.h, - src/s390/sysv.S, - src/cris/ffitarget.h, - src/pa/linux.S, - src/pa/ffitarget.h, - src/pa/ffi.c, - src/raw_api.c, - src/ia64/ffitarget.h, - src/ia64/unix.S, - src/ia64/ffi.c, - src/ia64/ia64_flags.h, - src/java_raw_api.c, - src/debug.c, - src/sparc/v9.S, - src/sparc/ffitarget.h, - src/sparc/ffi.c, - src/sparc/v8.S, - src/mips/ffitarget.h, - src/mips/n32.S, - src/mips/o32.S, - src/mips/ffi.c, - src/prep_cif.c, - src/sh/ffitarget.h, - src/sh/ffi.c, - src/sh/sysv.S: Update license text. - -2009-05-22 Dave Korn - - * src/x86/win32.S (_ffi_closure_STDCALL): New function. - (.eh_frame): Add FDE for it. - -2009-05-22 Dave Korn - - * configure.ac: Also check if assembler supports pc-relative - relocs on X86_WIN32 targets. - * configure: Regenerate. - * src/x86/win32.S (ffi_prep_args): Declare extern, not global. - (_ffi_call_SYSV): Add missing function type symbol .def and - add EH markup labels. - (_ffi_call_STDCALL): Likewise. - (_ffi_closure_SYSV): Likewise. - (_ffi_closure_raw_SYSV): Likewise. - (.eh_frame): Add hand-crafted EH data. - -2009-04-09 Jakub Jelinek - - * testsuite/lib/libffi-dg.exp: Change copyright header to refer to - version 3 of the GNU General Public License and to point readers - at the COPYING3 file and the FSF's license web page. - * testsuite/libffi.call/call.exp: Likewise. - * testsuite/libffi.special/special.exp: Likewise. - -2009-03-01 Ralf Wildenhues - - * configure: Regenerate. - -2008-12-18 Rainer Orth - - PR libffi/26048 - * configure.ac (HAVE_AS_X86_PCREL): New test. - * configure: Regenerate. - * fficonfig.h.in: Regenerate. - * src/x86/sysv.S [!FFI_NO_RAW_API]: Precalculate - RAW_CLOSURE_CIF_OFFSET, RAW_CLOSURE_FUN_OFFSET, - RAW_CLOSURE_USER_DATA_OFFSET for the Solaris 10/x86 assembler. - (.eh_frame): Only use SYMBOL-. iff HAVE_AS_X86_PCREL. - * src/x86/unix64.S (.Lstore_table): Move to .text section. - (.Lload_table): Likewise. - (.eh_frame): Only use SYMBOL-. iff HAVE_AS_X86_PCREL. - -2008-12-18 Ralf Wildenhues - - * configure: Regenerate. - -2008-11-21 Eric Botcazou - - * src/sparc/ffi.c (ffi_prep_cif_machdep): Add support for - signed/unsigned int8/16 return values. - * src/sparc/v8.S (ffi_call_v8): Likewise. - (ffi_closure_v8): Likewise. - -2008-09-26 Peter O'Gorman - Steve Ellcey - - * configure: Regenerate for new libtool. - * Makefile.in: Ditto. - * include/Makefile.in: Ditto. - * aclocal.m4: Ditto. - -2008-08-25 Andreas Tobler - - * src/powerpc/ffitarget.h (ffi_abi): Add FFI_LINUX and - FFI_LINUX_SOFT_FLOAT to the POWERPC_FREEBSD enum. - Add note about flag bits used for FFI_SYSV_TYPE_SMALL_STRUCT. - Adjust copyright notice. - * src/powerpc/ffi.c: Add two new flags to indicate if we have one - register or two register to use for FFI_SYSV structs. - (ffi_prep_cif_machdep): Pass the right register flag introduced above. - (ffi_closure_helper_SYSV): Fix the return type for - FFI_SYSV_TYPE_SMALL_STRUCT. Comment. - Adjust copyright notice. - -2008-07-16 Kaz Kojima - - * src/sh/ffi.c (ffi_prep_closure_loc): Turn INSN into an unsigned - int. +commit 05fbe1faedc7b2580d5f14010d00e9e3cee73951 +Author: Anthony Green +Date: Fri Jan 11 16:54:40 2013 -0500 -2008-06-17 Ralf Wildenhues + xlc compiler support - * configure: Regenerate. - * include/Makefile.in: Regenerate. - * testsuite/Makefile.in: Regenerate. +commit 0b4986a7889ed1864674192228f1162c1b5770a8 +Author: Anthony Green +Date: Fri Jan 11 11:19:52 2013 -0500 -2008-06-07 Joseph Myers + [travis] install dejagnu with sudo - * configure.ac (parisc*-*-linux*, powerpc-*-sysv*, - powerpc-*-beos*): Remove. - * configure: Regenerate. +commit 3c337eef51ab9a4993fc875bfa26289dd6a08881 +Author: Anthony Green +Date: Fri Jan 11 11:18:14 2013 -0500 -2008-05-09 Julian Brown + [travis] install dejagnu - * Makefile.am (LTLDFLAGS): New. - (libffi_la_LDFLAGS): Use above. - * Makefile.in: Regenerate. +commit 90720962ce1baf9fc35d1bde1738102bcd5bd5ed +Author: Anthony Green +Date: Fri Jan 11 10:57:30 2013 -0500 -2008-04-18 Paolo Bonzini + Add first travis config file - PR bootstrap/35457 - * aclocal.m4: Regenerate. - * configure: Regenerate. +commit bff052d9cd5be41ba9e47c76114054af487d3c30 +Author: Anthony Green +Date: Fri Jan 11 10:24:32 2013 -0500 -2008-03-26 Kaz Kojima + 32-bit x86 fix and more - * src/sh/sysv.S: Add .note.GNU-stack on Linux. - * src/sh64/sysv.S: Likewise. - -2008-03-26 Daniel Jacobowitz +commit cd41aeab6176f839167955c016ecc19f65f75df3 +Author: Anthony Green +Date: Thu Jan 10 17:25:45 2013 -0500 - * src/arm/sysv.S: Fix ARM comment marker. + Add compiler column to table -2008-03-26 Jakub Jelinek +commit 8bf987d4df7c4d21435b9211f6cc86abf5904b42 +Author: Anthony Green +Date: Thu Jan 10 17:24:51 2013 -0500 - * src/alpha/osf.S: Add .note.GNU-stack on Linux. - * src/s390/sysv.S: Likewise. - * src/powerpc/ppc_closure.S: Likewise. - * src/powerpc/sysv.S: Likewise. - * src/x86/unix64.S: Likewise. - * src/x86/sysv.S: Likewise. - * src/sparc/v8.S: Likewise. - * src/sparc/v9.S: Likewise. - * src/m68k/sysv.S: Likewise. - * src/arm/sysv.S: Likewise. + Fix for sunpro compiler on Solaris -2008-03-16 Ralf Wildenhues - - * aclocal.m4: Regenerate. - * configure: Likewise. - * Makefile.in: Likewise. - * include/Makefile.in: Likewise. - * testsuite/Makefile.in: Likewise. - -2008-02-12 Bjoern Koenig - Andreas Tobler - - * configure.ac: Add amd64-*-freebsd* target. - * configure: Regenerate. - -2008-01-30 H.J. Lu +commit 3ee74fd6dc8ccd32b608bbff73526838fc34f70b +Author: Anthony Green +Date: Thu Jan 10 17:15:03 2013 -0500 - PR libffi/34612 - * src/x86/sysv.S (ffi_closure_SYSV): Pop 4 byte from stack when - returning struct. - - * testsuite/libffi.call/call.exp: Add "-O2 -fomit-frame-pointer" - tests. - -2008-01-24 David Edelsohn - - * configure: Regenerate. - -2008-01-06 Andreas Tobler - - * src/x86/ffi.c (ffi_prep_cif_machdep): Fix thinko. - -2008-01-05 Andreas Tobler - - PR testsuite/32843 - * src/x86/ffi.c (ffi_prep_cif_machdep): Add code for - signed/unsigned int8/16 for X86_DARWIN. - Updated copyright info. - Handle one and two byte structs with special cif->flags. - * src/x86/ffitarget.h: Add special types for one and two byte structs. - Updated copyright info. - * src/x86/darwin.S (ffi_call_SYSV): Rewrite to use a jump table like - sysv.S - Remove code to pop args from the stack after call. - Special-case signed/unsigned for int8/16, one and two byte structs. - (ffi_closure_raw_SYSV): Handle FFI_TYPE_UINT8, - FFI_TYPE_SINT8, FFI_TYPE_UINT16, FFI_TYPE_SINT16, FFI_TYPE_UINT32, - FFI_TYPE_SINT32. - Updated copyright info. + Update documentation version. -2007-12-08 David Daney +commit 13e2d7b92557a9511a0414df82bf2df3edc55cba +Author: Anthony Green +Date: Thu Jan 10 10:52:02 2013 -0500 - * src/mips/n32.S (ffi_call_N32): Replace dadd with ADDU, dsub with - SUBU, add with ADDU and use smaller code sequences. + Handle both 32 and 64-bit x86 builds regardless of target triple -2007-12-07 David Daney - - * src/mips/ffi.c (ffi_prep_cif_machdep): Handle long double return - type. +commit 5141543000fc86a3d49a907a2313713ee79e504d +Author: Anthony Green +Date: Thu Jan 10 07:35:53 2013 -0500 -2007-12-06 David Daney + Don't run EH tests with non-GNU compiler - * include/ffi.h.in (FFI_SIZEOF_JAVA_RAW): Define if not already - defined. - (ffi_java_raw): New typedef. - (ffi_java_raw_call, ffi_java_ptrarray_to_raw, - ffi_java_raw_to_ptrarray): Change parameter types from ffi_raw to - ffi_java_raw. - (ffi_java_raw_closure) : Same. - (ffi_prep_java_raw_closure, ffi_prep_java_raw_closure_loc): Change - parameter types. - * src/java_raw_api.c (ffi_java_raw_size): Replace FFI_SIZEOF_ARG with - FFI_SIZEOF_JAVA_RAW. - (ffi_java_raw_to_ptrarray): Change type of raw to ffi_java_raw. - Replace FFI_SIZEOF_ARG with FFI_SIZEOF_JAVA_RAW. Use - sizeof(ffi_java_raw) for alignment calculations. - (ffi_java_ptrarray_to_raw): Same. - (ffi_java_rvalue_to_raw): Add special handling for FFI_TYPE_POINTER - if FFI_SIZEOF_JAVA_RAW == 4. - (ffi_java_raw_to_rvalue): Same. - (ffi_java_raw_call): Change type of raw to ffi_java_raw. - (ffi_java_translate_args): Same. - (ffi_prep_java_raw_closure_loc, ffi_prep_java_raw_closure): Change - parameter types. - * src/mips/ffitarget.h (FFI_SIZEOF_JAVA_RAW): Define for N32 ABI. - -2007-12-06 David Daney - - * src/mips/n32.S (ffi_closure_N32): Use 64-bit add instruction on - pointer values. - -2007-12-01 Andreas Tobler - - PR libffi/31937 - * src/powerpc/ffitarget.h: Introduce new ABI FFI_LINUX_SOFT_FLOAT. - Add local FFI_TYPE_UINT128 to handle soft-float long-double-128. - * src/powerpc/ffi.c: Distinguish between __NO_FPRS__ and not and - set the NUM_FPR_ARG_REGISTERS according to. - Add support for potential soft-float support under hard-float - architecture. - (ffi_prep_args_SYSV): Set NUM_FPR_ARG_REGISTERS to 0 in case of - FFI_LINUX_SOFT_FLOAT, handle float, doubles and long-doubles according - to the FFI_LINUX_SOFT_FLOAT ABI. - (ffi_prep_cif_machdep): Likewise. - (ffi_closure_helper_SYSV): Likewise. - * src/powerpc/ppc_closure.S: Make sure not to store float/double - on archs where __NO_FPRS__ is true. - Add FFI_TYPE_UINT128 support. - * src/powerpc/sysv.S: Add support for soft-float long-double-128. - Adjust copyright notice. - -2007-11-25 Andreas Tobler - - * src/closures.c: Move defintion of MAYBE_UNUSED from here to ... - * include/ffi_common.h: ... here. - Update copyright. - -2007-11-17 Andreas Tobler - - * src/powerpc/sysv.S: Load correct cr to compare if we have long double. - * src/powerpc/linux64.S: Likewise. - * src/powerpc/ffi.c: Add a comment to show which part goes into cr6. - * testsuite/libffi.call/return_ldl.c: New test. - -2007-09-04 - - * src/arm/sysv.S (UNWIND): New. - (Whole file): Conditionally compile unwinder directives. - * src/arm/sysv.S: Add unwinder directives. - - * src/arm/ffi.c (ffi_prep_args): Align structs by at least 4 bytes. - Only treat r0 as a struct address if we're actually returning a - struct by address. - Only copy the bytes that are actually within a struct. - (ffi_prep_cif_machdep): A Composite Type not larger than 4 bytes - is returned in r0, not passed by address. - (ffi_call): Allocate a word-sized temporary for the case where - a composite is returned in r0. - (ffi_prep_incoming_args_SYSV): Align as necessary. - -2007-08-05 Steven Newbury - - * src/arm/ffi.c (FFI_INIT_TRAMPOLINE): Use __clear_cache instead of - directly using the sys_cacheflush syscall. - -2007-07-27 Andrew Haley - - * src/arm/sysv.S (ffi_closure_SYSV): Add soft-float. - -2007-09-03 Maciej W. Rozycki - - * Makefile.am: Unify MIPS_IRIX and MIPS_LINUX into MIPS. - * configure.ac: Likewise. - * Makefile.in: Regenerate. - * include/Makefile.in: Likewise. - * testsuite/Makefile.in: Likewise. - * configure: Likewise. - -2007-08-24 David Daney - - * testsuite/libffi.call/return_sl.c: New test. - -2007-08-10 David Daney - - * testsuite/libffi.call/cls_multi_ushort.c, - testsuite/libffi.call/cls_align_uint16.c, - testsuite/libffi.call/nested_struct1.c, - testsuite/libffi.call/nested_struct3.c, - testsuite/libffi.call/cls_7_1_byte.c, - testsuite/libffi.call/nested_struct5.c, - testsuite/libffi.call/cls_double.c, - testsuite/libffi.call/nested_struct7.c, - testsuite/libffi.call/cls_sint.c, - testsuite/libffi.call/nested_struct9.c, - testsuite/libffi.call/cls_20byte1.c, - testsuite/libffi.call/cls_multi_sshortchar.c, - testsuite/libffi.call/cls_align_sint64.c, - testsuite/libffi.call/cls_3byte2.c, - testsuite/libffi.call/cls_multi_schar.c, - testsuite/libffi.call/cls_multi_uchar.c, - testsuite/libffi.call/cls_19byte.c, - testsuite/libffi.call/cls_9byte1.c, - testsuite/libffi.call/cls_align_float.c, - testsuite/libffi.call/closure_fn1.c, - testsuite/libffi.call/problem1.c, - testsuite/libffi.call/closure_fn3.c, - testsuite/libffi.call/cls_sshort.c, - testsuite/libffi.call/closure_fn5.c, - testsuite/libffi.call/cls_align_double.c, - testsuite/libffi.call/nested_struct.c, - testsuite/libffi.call/cls_2byte.c, - testsuite/libffi.call/nested_struct10.c, - testsuite/libffi.call/cls_4byte.c, - testsuite/libffi.call/cls_6byte.c, - testsuite/libffi.call/cls_8byte.c, - testsuite/libffi.call/cls_multi_sshort.c, - testsuite/libffi.call/cls_align_sint16.c, - testsuite/libffi.call/cls_align_uint32.c, - testsuite/libffi.call/cls_20byte.c, - testsuite/libffi.call/cls_float.c, - testsuite/libffi.call/nested_struct2.c, - testsuite/libffi.call/cls_5_1_byte.c, - testsuite/libffi.call/nested_struct4.c, - testsuite/libffi.call/cls_24byte.c, - testsuite/libffi.call/nested_struct6.c, - testsuite/libffi.call/cls_64byte.c, - testsuite/libffi.call/nested_struct8.c, - testsuite/libffi.call/cls_uint.c, - testsuite/libffi.call/cls_multi_ushortchar.c, - testsuite/libffi.call/cls_schar.c, - testsuite/libffi.call/cls_uchar.c, - testsuite/libffi.call/cls_align_uint64.c, - testsuite/libffi.call/cls_ulonglong.c, - testsuite/libffi.call/cls_align_longdouble.c, - testsuite/libffi.call/cls_1_1byte.c, - testsuite/libffi.call/cls_12byte.c, - testsuite/libffi.call/cls_3_1byte.c, - testsuite/libffi.call/cls_3byte1.c, - testsuite/libffi.call/cls_4_1byte.c, - testsuite/libffi.call/cls_6_1_byte.c, - testsuite/libffi.call/cls_16byte.c, - testsuite/libffi.call/cls_18byte.c, - testsuite/libffi.call/closure_fn0.c, - testsuite/libffi.call/cls_9byte2.c, - testsuite/libffi.call/closure_fn2.c, - testsuite/libffi.call/closure_fn4.c, - testsuite/libffi.call/cls_ushort.c, - testsuite/libffi.call/closure_fn6.c, - testsuite/libffi.call/cls_5byte.c, - testsuite/libffi.call/cls_align_pointer.c, - testsuite/libffi.call/cls_7byte.c, - testsuite/libffi.call/cls_align_sint32.c, - testsuite/libffi.special/unwindtest_ffi_call.cc, - testsuite/libffi.special/unwindtest.cc: Remove xfail for mips64*-*-*. - -2007-08-10 David Daney - - PR libffi/28313 - * configure.ac: Don't treat mips64 as a special case. - * Makefile.am (nodist_libffi_la_SOURCES): Add n32.S. - * configure: Regenerate - * Makefile.in: Ditto. - * fficonfig.h.in: Ditto. - * src/mips/ffitarget.h (REG_L, REG_S, SUBU, ADDU, SRL, LI): Indent. - (LA, EH_FRAME_ALIGN, FDE_ADDR_BYTES): New preprocessor macros. - (FFI_DEFAULT_ABI): Set for n64 case. - (FFI_CLOSURES, FFI_TRAMPOLINE_SIZE): Define for n32 and n64 cases. - * src/mips/n32.S (ffi_call_N32): Add debug macros and labels for FDE. - (ffi_closure_N32): New function. - (.eh_frame): New section - * src/mips/o32.S: Clean up comments. - (ffi_closure_O32): Pass ffi_closure parameter in $12. - * src/mips/ffi.c: Use FFI_MIPS_N32 instead of - _MIPS_SIM == _ABIN32 throughout. - (FFI_MIPS_STOP_HERE): New, use in place of - ffi_stop_here. - (ffi_prep_args): Use unsigned long to hold pointer values. Rewrite - to support n32/n64 ABIs. - (calc_n32_struct_flags): Rewrite. - (calc_n32_return_struct_flags): Remove unused variable. Reverse - position of flag bits. - (ffi_prep_cif_machdep): Rewrite n32 portion. - (ffi_call): Enable for n64. Add special handling for small structure - return values. - (ffi_prep_closure_loc): Add n32 and n64 support. - (ffi_closure_mips_inner_O32): Add cast to silence warning. - (copy_struct_N32, ffi_closure_mips_inner_N32): New functions. - -2007-08-08 David Daney - - * testsuite/libffi.call/ffitest.h (ffi_type_mylong): Remove definition. - * testsuite/libffi.call/cls_align_uint16.c (main): Use correct type - specifiers. - * testsuite/libffi.call/nested_struct1.c (main): Ditto. - * testsuite/libffi.call/cls_sint.c (main): Ditto. - * testsuite/libffi.call/nested_struct9.c (main): Ditto. - * testsuite/libffi.call/cls_20byte1.c (main): Ditto. - * testsuite/libffi.call/cls_9byte1.c (main): Ditto. - * testsuite/libffi.call/closure_fn1.c (main): Ditto. - * testsuite/libffi.call/closure_fn3.c (main): Ditto. - * testsuite/libffi.call/return_dbl2.c (main): Ditto. - * testsuite/libffi.call/cls_sshort.c (main): Ditto. - * testsuite/libffi.call/return_fl3.c (main): Ditto. - * testsuite/libffi.call/closure_fn5.c (main): Ditto. - * testsuite/libffi.call/nested_struct.c (main): Ditto. - * testsuite/libffi.call/nested_struct10.c (main): Ditto. - * testsuite/libffi.call/return_ll1.c (main): Ditto. - * testsuite/libffi.call/cls_8byte.c (main): Ditto. - * testsuite/libffi.call/cls_align_uint32.c (main): Ditto. - * testsuite/libffi.call/cls_align_sint16.c (main): Ditto. - * testsuite/libffi.call/cls_20byte.c (main): Ditto. - * testsuite/libffi.call/nested_struct2.c (main): Ditto. - * testsuite/libffi.call/cls_24byte.c (main): Ditto. - * testsuite/libffi.call/nested_struct6.c (main): Ditto. - * testsuite/libffi.call/cls_uint.c (main): Ditto. - * testsuite/libffi.call/cls_12byte.c (main): Ditto. - * testsuite/libffi.call/cls_16byte.c (main): Ditto. - * testsuite/libffi.call/closure_fn0.c (main): Ditto. - * testsuite/libffi.call/cls_9byte2.c (main): Ditto. - * testsuite/libffi.call/closure_fn2.c (main): Ditto. - * testsuite/libffi.call/return_dbl1.c (main): Ditto. - * testsuite/libffi.call/closure_fn4.c (main): Ditto. - * testsuite/libffi.call/closure_fn6.c (main): Ditto. - * testsuite/libffi.call/cls_align_sint32.c (main): Ditto. - -2007-08-07 Andrew Haley - - * src/x86/sysv.S (ffi_closure_raw_SYSV): Fix typo in previous - checkin. - -2007-08-06 Andrew Haley - - PR testsuite/32843 - * src/x86/sysv.S (ffi_closure_raw_SYSV): Handle FFI_TYPE_UINT8, - FFI_TYPE_SINT8, FFI_TYPE_UINT16, FFI_TYPE_SINT16, FFI_TYPE_UINT32, - FFI_TYPE_SINT32. - -2007-08-02 David Daney - - * testsuite/libffi.call/return_ul.c (main): Define return type as - ffi_arg. Use proper printf conversion specifier. - -2007-07-30 Andrew Haley - - PR testsuite/32843 - * src/x86/ffi.c (ffi_prep_cif_machdep): in x86 case, add code for - signed/unsigned int8/16. - * src/x86/sysv.S (ffi_call_SYSV): Rewrite to: - Use a jump table. - Remove code to pop args from the stack after call. - Special-case signed/unsigned int8/16. - * testsuite/libffi.call/return_sc.c (main): Revert. - -2007-07-26 Richard Guenther - - PR testsuite/32843 - * testsuite/libffi.call/return_sc.c (main): Verify call - result as signed char, not ffi_arg. - -2007-07-16 Rainer Orth - - * configure.ac (i?86-*-solaris2.1[0-9]): Set TARGET to X86_64. - * configure: Regenerate. - -2007-07-11 David Daney - - * src/mips/ffi.c: Don't include sys/cachectl.h. - (ffi_prep_closure_loc): Use __builtin___clear_cache() instead of - cacheflush(). - -2007-05-18 Aurelien Jarno - - * src/arm/ffi.c (ffi_prep_closure_loc): Renamed and ajusted - from (ffi_prep_closure): ... this. - (FFI_INIT_TRAMPOLINE): Adjust. - -2005-12-31 Phil Blundell - - * src/arm/ffi.c (ffi_prep_incoming_args_SYSV, - ffi_closure_SYSV_inner, ffi_prep_closure): New, add closure support. - * src/arm/sysv.S(ffi_closure_SYSV): Likewise. - * src/arm/ffitarget.h (FFI_TRAMPOLINE_SIZE): Likewise. - (FFI_CLOSURES): Enable closure support. - -2007-07-03 Andrew Haley - - * testsuite/libffi.call/cls_multi_ushort.c, - testsuite/libffi.call/cls_align_uint16.c, - testsuite/libffi.call/nested_struct1.c, - testsuite/libffi.call/nested_struct3.c, - testsuite/libffi.call/cls_7_1_byte.c, - testsuite/libffi.call/cls_double.c, - testsuite/libffi.call/nested_struct5.c, - testsuite/libffi.call/nested_struct7.c, - testsuite/libffi.call/cls_sint.c, - testsuite/libffi.call/nested_struct9.c, - testsuite/libffi.call/cls_20byte1.c, - testsuite/libffi.call/cls_multi_sshortchar.c, - testsuite/libffi.call/cls_align_sint64.c, - testsuite/libffi.call/cls_3byte2.c, - testsuite/libffi.call/cls_multi_schar.c, - testsuite/libffi.call/cls_multi_uchar.c, - testsuite/libffi.call/cls_19byte.c, - testsuite/libffi.call/cls_9byte1.c, - testsuite/libffi.call/cls_align_float.c, - testsuite/libffi.call/closure_fn1.c, - testsuite/libffi.call/problem1.c, - testsuite/libffi.call/closure_fn3.c, - testsuite/libffi.call/cls_sshort.c, - testsuite/libffi.call/closure_fn5.c, - testsuite/libffi.call/cls_align_double.c, - testsuite/libffi.call/cls_2byte.c, - testsuite/libffi.call/nested_struct.c, - testsuite/libffi.call/nested_struct10.c, - testsuite/libffi.call/cls_4byte.c, - testsuite/libffi.call/cls_6byte.c, - testsuite/libffi.call/cls_8byte.c, - testsuite/libffi.call/cls_multi_sshort.c, - testsuite/libffi.call/cls_align_uint32.c, - testsuite/libffi.call/cls_align_sint16.c, - testsuite/libffi.call/cls_float.c, - testsuite/libffi.call/cls_20byte.c, - testsuite/libffi.call/cls_5_1_byte.c, - testsuite/libffi.call/nested_struct2.c, - testsuite/libffi.call/cls_24byte.c, - testsuite/libffi.call/nested_struct4.c, - testsuite/libffi.call/nested_struct6.c, - testsuite/libffi.call/cls_64byte.c, - testsuite/libffi.call/nested_struct8.c, - testsuite/libffi.call/cls_uint.c, - testsuite/libffi.call/cls_multi_ushortchar.c, - testsuite/libffi.call/cls_schar.c, - testsuite/libffi.call/cls_uchar.c, - testsuite/libffi.call/cls_align_uint64.c, - testsuite/libffi.call/cls_ulonglong.c, - testsuite/libffi.call/cls_align_longdouble.c, - testsuite/libffi.call/cls_1_1byte.c, - testsuite/libffi.call/cls_12byte.c, - testsuite/libffi.call/cls_3_1byte.c, - testsuite/libffi.call/cls_3byte1.c, - testsuite/libffi.call/cls_4_1byte.c, - testsuite/libffi.call/cls_6_1_byte.c, - testsuite/libffi.call/cls_16byte.c, - testsuite/libffi.call/cls_18byte.c, - testsuite/libffi.call/closure_fn0.c, - testsuite/libffi.call/cls_9byte2.c, - testsuite/libffi.call/closure_fn2.c, - testsuite/libffi.call/closure_fn4.c, - testsuite/libffi.call/cls_ushort.c, - testsuite/libffi.call/closure_fn6.c, - testsuite/libffi.call/cls_5byte.c, - testsuite/libffi.call/cls_align_pointer.c, - testsuite/libffi.call/cls_7byte.c, - testsuite/libffi.call/cls_align_sint32.c, - testsuite/libffi.special/unwindtest_ffi_call.cc, - testsuite/libffi.special/unwindtest.cc: Enable for ARM. - -2007-07-05 H.J. Lu - - * aclocal.m4: Regenerated. - -2007-06-02 Paolo Bonzini - - * configure: Regenerate. - -2007-05-23 Steve Ellcey - - * Makefile.in: Regenerate. - * configure: Regenerate. - * aclocal.m4: Regenerate. - * include/Makefile.in: Regenerate. - * testsuite/Makefile.in: Regenerate. - -2007-05-10 Roman Zippel - - * src/m68k/ffi.c (ffi_prep_incoming_args_SYSV, - ffi_closure_SYSV_inner,ffi_prep_closure): New, add closure support. - * src/m68k/sysv.S(ffi_closure_SYSV,ffi_closure_struct_SYSV): Likewise. - * src/m68k/ffitarget.h (FFI_TRAMPOLINE_SIZE): Likewise. - (FFI_CLOSURES): Enable closure support. - -2007-05-10 Roman Zippel - - * configure.ac (HAVE_AS_CFI_PSEUDO_OP): New test. - * configure: Regenerate. - * fficonfig.h.in: Regenerate. - * src/m68k/sysv.S (CFI_STARTPROC,CFI_ENDPROC, - CFI_OFFSET,CFI_DEF_CFA): New macros. - (ffi_call_SYSV): Add callframe annotation. - -2007-05-10 Roman Zippel - - * src/m68k/ffi.c (ffi_prep_args,ffi_prep_cif_machdep): Fix - numerous test suite failures. - * src/m68k/sysv.S (ffi_call_SYSV): Likewise. - -2007-04-11 Paolo Bonzini - - * Makefile.am (EXTRA_DIST): Bring up to date. - * Makefile.in: Regenerate. - * src/frv/eabi.S: Remove RCS keyword. - -2007-04-06 Richard Henderson - - * configure.ac: Tidy target case. - (HAVE_LONG_DOUBLE): Allow the target to override. - * configure: Regenerate. - * include/ffi.h.in: Don't define ffi_type_foo if - LIBFFI_HIDE_BASIC_TYPES is defined. - (ffi_type_longdouble): If not HAVE_LONG_DOUBLE, define - to ffi_type_double. - * types.c (LIBFFI_HIDE_BASIC_TYPES): Define. - (FFI_TYPEDEF, ffi_type_void): Mark the data const. - (ffi_type_longdouble): Special case for Alpha. Don't define - if long double == double. - - * src/alpha/ffi.c (FFI_TYPE_LONGDOUBLE): Assert unique value. - (ffi_prep_cif_machdep): Handle it as the 128-bit type. - (ffi_call, ffi_closure_osf_inner): Likewise. - (ffi_closure_osf_inner): Likewise. Mark hidden. - (ffi_call_osf, ffi_closure_osf): Mark hidden. - * src/alpha/ffitarget.h (FFI_LAST_ABI): Tidy definition. - * src/alpha/osf.S (ffi_call_osf, ffi_closure_osf): Mark hidden. - (load_table): Handle 128-bit long double. - - * testsuite/libffi.call/float4.c: Add -mieee for alpha. - -2007-04-06 Tom Tromey - - PR libffi/31491: - * README: Fixed bug in example. - -2007-04-03 Jakub Jelinek - - * src/closures.c: Include sys/statfs.h. - (_GNU_SOURCE): Define on Linux. - (FFI_MMAP_EXEC_SELINUX): Define. - (selinux_enabled): New variable. - (selinux_enabled_check): New function. - (is_selinux_enabled): Define. - (dlmmap): Use it. - -2007-03-24 Uros Bizjak - - * testsuite/libffi.call/return_fl2.c (return_fl): Mark as static. - Use 'volatile float sum' to create sum of floats to avoid false - negative due to excess precision on ix86 targets. - (main): Ditto. - -2007-03-08 Alexandre Oliva - - * src/powerpc/ffi.c (flush_icache): Fix left-over from previous - patch. - (ffi_prep_closure_loc): Remove unneeded casts. Add needed ones. - -2007-03-07 Alexandre Oliva - - * include/ffi.h.in (ffi_closure_alloc, ffi_closure_free): New. - (ffi_prep_closure_loc): New. - (ffi_prep_raw_closure_loc): New. - (ffi_prep_java_raw_closure_loc): New. - * src/closures.c: New file. - * src/dlmalloc.c [FFI_MMAP_EXEC_WRIT] (struct malloc_segment): - Replace sflags with exec_offset. - [FFI_MMAP_EXEC_WRIT] (mmap_exec_offset, add_segment_exec_offset, - sub_segment_exec_offset): New macros. - (get_segment_flags, set_segment_flags, check_segment_merge): New - macros. - (is_mmapped_segment, is_extern_segment): Use get_segment_flags. - (add_segment, sys_alloc, create_mspace, create_mspace_with_base, - destroy_mspace): Use new macros. - (sys_alloc): Silence warning. - * Makefile.am (libffi_la_SOURCES): Add src/closures.c. - * Makefile.in: Rebuilt. - * src/prep_cif [FFI_CLOSURES] (ffi_prep_closure): Implement in - terms of ffi_prep_closure_loc. - * src/raw_api.c (ffi_prep_raw_closure_loc): Renamed and adjusted - from... - (ffi_prep_raw_closure): ... this. Re-implement in terms of the - renamed version. - * src/java_raw_api (ffi_prep_java_raw_closure_loc): Renamed and - adjusted from... - (ffi_prep_java_raw_closure): ... this. Re-implement in terms of - the renamed version. - * src/alpha/ffi.c (ffi_prep_closure_loc): Renamed from - (ffi_prep_closure): ... this. - * src/pa/ffi.c: Likewise. - * src/cris/ffi.c: Likewise. Adjust. - * src/frv/ffi.c: Likewise. - * src/ia64/ffi.c: Likewise. - * src/mips/ffi.c: Likewise. - * src/powerpc/ffi_darwin.c: Likewise. - * src/s390/ffi.c: Likewise. - * src/sh/ffi.c: Likewise. - * src/sh64/ffi.c: Likewise. - * src/sparc/ffi.c: Likewise. - * src/x86/ffi64.c: Likewise. - * src/x86/ffi.c: Likewise. - (FFI_INIT_TRAMPOLINE): Adjust. - (ffi_prep_raw_closure_loc): Renamed and adjusted from... - (ffi_prep_raw_closure): ... this. - * src/powerpc/ffi.c (ffi_prep_closure_loc): Renamed from - (ffi_prep_closure): ... this. - (flush_icache): Adjust. - -2007-03-07 Alexandre Oliva - - * src/dlmalloc.c: New file, imported version 2.8.3 of Doug - Lea's malloc. - -2007-03-01 Brooks Moses - - * Makefile.am: Add dummy install-pdf target. - * Makefile.in: Regenerate - -2007-02-13 Andreas Krebbel - - * src/s390/ffi.c (ffi_prep_args, ffi_prep_cif_machdep, - ffi_closure_helper_SYSV): Add long double handling. - -2007-02-02 Jakub Jelinek - - * src/powerpc/linux64.S (ffi_call_LINUX64): Move restore of r2 - immediately after bctrl instruction. - -2007-01-18 Alexandre Oliva - - * Makefile.am (all-recursive, install-recursive, - mostlyclean-recursive, clean-recursive, distclean-recursive, - maintainer-clean-recursive): Add missing targets. - * Makefile.in: Rebuilt. - -2006-12-14 Andreas Tobler - - * configure.ac: Add TARGET for x86_64-*-darwin*. - * Makefile.am (nodist_libffi_la_SOURCES): Add rules for 64-bit sources - for X86_DARWIN. - * src/x86/ffitarget.h: Set trampoline size for x86_64-*-darwin*. - * src/x86/darwin64.S: New file for x86_64-*-darwin* support. - * configure: Regenerate. - * Makefile.in: Regenerate. - * include/Makefile.in: Regenerate. - * testsuite/Makefile.in: Regenerate. - * testsuite/libffi.special/unwindtest_ffi_call.cc: New test case for - ffi_call only. - -2006-12-13 Andreas Tobler - - * aclocal.m4: Regenerate with aclocal -I .. as written in the - Makefile.am. - -2006-10-31 Geoffrey Keating - - * src/powerpc/ffi_darwin.c (darwin_adjust_aggregate_sizes): New. - (ffi_prep_cif_machdep): Call darwin_adjust_aggregate_sizes for - Darwin. - * testsuite/libffi.call/nested_struct4.c: Remove Darwin XFAIL. - * testsuite/libffi.call/nested_struct6.c: Remove Darwin XFAIL. - -2006-10-10 Paolo Bonzini - Sandro Tolaini - - * configure.ac [i*86-*-darwin*]: Set X86_DARWIN symbol and - conditional. - * configure: Regenerated. - * Makefile.am (nodist_libffi_la_SOURCES) [X86_DARWIN]: New case. - (EXTRA_DIST): Add src/x86/darwin.S. - * Makefile.in: Regenerated. - * include/Makefile.in: Regenerated. - * testsuite/Makefile.in: Regenerated. - - * src/x86/ffi.c (ffi_prep_cif_machdep) [X86_DARWIN]: Treat like - X86_WIN32, and additionally align stack to 16 bytes. - * src/x86/darwin.S: New, based on sysv.S. - * src/prep_cif.c (ffi_prep_cif) [X86_DARWIN]: Align > 8-byte structs. - -2006-09-12 David Daney - - PR libffi/23935 - * include/Makefile.am: Install both ffi.h and ffitarget.h in - $(libdir)/gcc/$(target_alias)/$(gcc_version)/include. - * aclocal.m4: Regenerated for automake 1.9.6. - * Makefile.in: Regenerated. - * include/Makefile.in: Regenerated. - * testsuite/Makefile.in: Regenerated. - -2006-08-17 Andreas Tobler - - * include/ffi_common.h (struct): Revert accidental commit. - -2006-08-15 Andreas Tobler - - * include/ffi_common.h: Remove lint directives. - * include/ffi.h.in: Likewise. - -2006-07-25 Torsten Schoenfeld - - * include/ffi.h.in (ffi_type_ulong, ffi_type_slong): Define correctly - for 32-bit architectures. - * testsuite/libffi.call/return_ul.c: New test case. - -2006-07-19 David Daney - - * testsuite/libffi.call/closure_fn6.c: Remove xfail for mips, - xfail remains for mips64. - -2006-05-23 Carlos O'Donell - - * Makefile.am: Add install-html target. Add install-html to .PHONY - * Makefile.in: Regenerate. - * aclocal.m4: Regenerate. - * include/Makefile.in: Regenerate. - * testsuite/Makefile.in: Regenerate. - -2006-05-18 John David Anglin - - * pa/ffi.c (ffi_prep_args_pa32): Load floating point arguments from - stack slot. - -2006-04-22 Andreas Tobler - - * README: Remove notice about 'Crazy Comments'. - * src/debug.c: Remove lint directives. Cleanup white spaces. - * src/java_raw_api.c: Likewise. - * src/prep_cif.c: Likewise. - * src/raw_api.c: Likewise. - * src/ffitest.c: Delete. No longer needed, all test cases migrated - to the testsuite. - * src/arm/ffi.c: Remove lint directives. - * src/m32r/ffi.c: Likewise. - * src/pa/ffi.c: Likewise. - * src/powerpc/ffi.c: Likewise. - * src/powerpc/ffi_darwin.c: Likewise. - * src/sh/ffi.c: Likewise. - * src/sh64/ffi.c: Likewise. - * src/x86/ffi.c: Likewise. - * testsuite/libffi.call/float2.c: Likewise. - * testsuite/libffi.call/promotion.c: Likewise. - * testsuite/libffi.call/struct1.c: Likewise. - -2006-04-13 Andreas Tobler - - * src/pa/hpux32.S: Correct unwind offset calculation for - ffi_closure_pa32. - * src/pa/linux.S: Likewise. - -2006-04-12 James E Wilson - - PR libgcj/26483 - * src/ia64/ffi.c (stf_spill, ldf_fill): Rewrite as macros. - (hfa_type_load): Call stf_spill. - (hfa_type_store): Call ldf_fill. - (ffi_call): Adjust calls to above routines. Add local temps for - macro result. - -2006-04-10 Matthias Klose - - * testsuite/lib/libffi-dg.exp (libffi-init): Recognize multilib - directory names containing underscores. - -2006-04-07 James E Wilson - - * testsuite/libffi.call/float4.c: New testcase. - -2006-04-05 John David Anglin - Andreas Tobler - - * Makefile.am: Add PA_HPUX port. - * Makefile.in: Regenerate. - * include/Makefile.in: Likewise. - * testsuite/Makefile.in: Likewise. - * configure.ac: Add PA_HPUX rules. - * configure: Regenerate. - * src/pa/ffitarget.h: Rename linux target to PA_LINUX. - Add PA_HPUX and PA64_HPUX. - Rename FFI_LINUX ABI to FFI_PA32 ABI. - (FFI_TRAMPOLINE_SIZE): Define for 32-bit HP-UX targets. - (FFI_TYPE_SMALL_STRUCT2): Define. - (FFI_TYPE_SMALL_STRUCT4): Likewise. - (FFI_TYPE_SMALL_STRUCT8): Likewise. - (FFI_TYPE_SMALL_STRUCT3): Redefine. - (FFI_TYPE_SMALL_STRUCT5): Likewise. - (FFI_TYPE_SMALL_STRUCT6): Likewise. - (FFI_TYPE_SMALL_STRUCT7): Likewise. - * src/pa/ffi.c (ROUND_DOWN): Delete. - (fldw, fstw, fldd, fstd): Use '__asm__'. - (ffi_struct_type): Add support for FFI_TYPE_SMALL_STRUCT2, - FFI_TYPE_SMALL_STRUCT4 and FFI_TYPE_SMALL_STRUCT8. - (ffi_prep_args_LINUX): Rename to ffi_prep_args_pa32. Update comment. - Simplify incrementing of stack slot variable. Change type of local - 'n' to unsigned int. - (ffi_size_stack_LINUX): Rename to ffi_size_stack_pa32. Handle long - double on PA_HPUX. - (ffi_prep_cif_machdep): Likewise. - (ffi_call): Likewise. - (ffi_closure_inner_LINUX): Rename to ffi_closure_inner_pa32. Change - return type to ffi_status. Simplify incrementing of stack slot - variable. Only copy floating point argument registers when PA_LINUX - is true. Reformat debug statement. - Add support for FFI_TYPE_SMALL_STRUCT2, FFI_TYPE_SMALL_STRUCT4 and - FFI_TYPE_SMALL_STRUCT8. - (ffi_closure_LINUX): Rename to ffi_closure_pa32. Add 'extern' to - declaration. - (ffi_prep_closure): Make linux trampoline conditional on PA_LINUX. - Add nops to cache flush. Add trampoline for PA_HPUX. - * src/pa/hpux32.S: New file. - * src/pa/linux.S (ffi_call_LINUX): Rename to ffi_call_pa32. Rename - ffi_prep_args_LINUX to ffi_prep_args_pa32. - Localize labels. Add support for 2, 4 and 8-byte small structs. Handle - unaligned destinations in 3, 5, 6 and 7-byte small structs. Order - argument type checks so that common argument types appear first. - (ffi_closure_LINUX): Rename to ffi_closure_pa32. Rename - ffi_closure_inner_LINUX to ffi_closure_inner_pa32. - -2006-03-24 Alan Modra - - * src/powerpc/ffitarget.h (enum ffi_abi): Add FFI_LINUX. Default - for 32-bit using IBM extended double format. Fix FFI_LAST_ABI. - * src/powerpc/ffi.c (ffi_prep_args_SYSV): Handle linux variant of - FFI_TYPE_LONGDOUBLE. - (ffi_prep_args64): Assert using IBM extended double. - (ffi_prep_cif_machdep): Don't munge FFI_TYPE_LONGDOUBLE type. - Handle FFI_LINUX FFI_TYPE_LONGDOUBLE return and args. - (ffi_call): Handle FFI_LINUX. - (ffi_closure_helper_SYSV): Non FFI_LINUX long double return needs - gpr3 return pointer as for struct return. Handle FFI_LINUX - FFI_TYPE_LONGDOUBLE return and args. Don't increment "nf" - unnecessarily. - * src/powerpc/ppc_closure.S (ffi_closure_SYSV): Load both f1 and f2 - for FFI_TYPE_LONGDOUBLE. Move epilogue insns into case table. - Don't use r6 as pointer to results, instead use sp offset. Don't - make a special call to load lr with case table address, instead - use offset from previous call. - * src/powerpc/sysv.S (ffi_call_SYSV): Save long double return. - * src/powerpc/linux64.S (ffi_call_LINUX64): Simplify long double - return. - -2006-03-15 Kaz Kojima - - * src/sh64/ffi.c (ffi_prep_cif_machdep): Handle float arguments - passed with FP registers correctly. - (ffi_closure_helper_SYSV): Likewise. - * src/sh64/sysv.S: Likewise. - -2006-03-01 Andreas Tobler - - * testsuite/libffi.special/unwindtest.cc (closure_test_fn): Mark cif, - args and userdata unused. - (closure_test_fn1): Mark cif and userdata unused. - (main): Remove unused res. - -2006-02-28 Andreas Tobler - - * testsuite/libffi.call/call.exp: Adjust FSF address. Add test runs for - -O2, -O3, -Os and the warning flags -W -Wall. - * testsuite/libffi.special/special.exp: Likewise. - * testsuite/libffi.call/ffitest.h: Add an __UNUSED__ macro to mark - unused parameter unused for gcc or else do nothing. - * testsuite/libffi.special/ffitestcxx.h: Likewise. - * testsuite/libffi.call/cls_12byte.c (cls_struct_12byte_gn): Mark cif - and userdata unused. - * testsuite/libffi.call/cls_16byte.c (cls_struct_16byte_gn): Likewise. - * testsuite/libffi.call/cls_18byte.c (cls_struct_18byte_gn): Likewise. - * testsuite/libffi.call/cls_19byte.c (cls_struct_19byte_gn): Likewise. - * testsuite/libffi.call/cls_1_1byte.c (cls_struct_1_1byte_gn): Likewise. - * testsuite/libffi.call/cls_20byte.c (cls_struct_20byte_gn): Likewise. - * testsuite/libffi.call/cls_20byte1.c (cls_struct_20byte_gn): Likewise. - * testsuite/libffi.call/cls_24byte.c (cls_struct_24byte_gn): Likewise. - * testsuite/libffi.call/cls_2byte.c (cls_struct_2byte_gn): Likewise. - * testsuite/libffi.call/cls_3_1byte.c (cls_struct_3_1byte_gn): Likewise. - * testsuite/libffi.call/cls_3byte1.c (cls_struct_3byte_gn): Likewise. - * testsuite/libffi.call/cls_3byte2.c (cls_struct_3byte_gn1): Likewise. - * testsuite/libffi.call/cls_4_1byte.c (cls_struct_4_1byte_gn): Likewise. - * testsuite/libffi.call/cls_4byte.c (cls_struct_4byte_gn): Likewise. - * testsuite/libffi.call/cls_5_1_byte.c (cls_struct_5byte_gn): Likewise. - * testsuite/libffi.call/cls_5byte.c (cls_struct_5byte_gn): Likewise. - * testsuite/libffi.call/cls_64byte.c (cls_struct_64byte_gn): Likewise. - * testsuite/libffi.call/cls_6_1_byte.c (cls_struct_6byte_gn): Likewise. - * testsuite/libffi.call/cls_6byte.c (cls_struct_6byte_gn): Likewise. - * testsuite/libffi.call/cls_7_1_byte.c (cls_struct_7byte_gn): Likewise. - * testsuite/libffi.call/cls_7byte.c (cls_struct_7byte_gn): Likewise. - * testsuite/libffi.call/cls_8byte.c (cls_struct_8byte_gn): Likewise. - * testsuite/libffi.call/cls_9byte1.c (cls_struct_9byte_gn): Likewise. - * testsuite/libffi.call/cls_9byte2.c (cls_struct_9byte_gn): Likewise. - * testsuite/libffi.call/cls_align_double.c (cls_struct_align_gn): - Likewise. - * testsuite/libffi.call/cls_align_float.c (cls_struct_align_gn): - Likewise. - * testsuite/libffi.call/cls_align_longdouble.c (cls_struct_align_gn): - Likewise. - * testsuite/libffi.call/cls_align_pointer.c (cls_struct_align_fn): Cast - void* to avoid compiler warning. - (main): Likewise. - (cls_struct_align_gn): Mark cif and userdata unused. - * testsuite/libffi.call/cls_align_sint16.c (cls_struct_align_gn): - Likewise. - * testsuite/libffi.call/cls_align_sint32.c (cls_struct_align_gn): - Likewise. - * testsuite/libffi.call/cls_align_sint64.c (cls_struct_align_gn): - Likewise. - * testsuite/libffi.call/cls_align_uint16.c (cls_struct_align_gn): - Likewise. - * testsuite/libffi.call/cls_align_uint32.c (cls_struct_align_gn): - Likewise. - * testsuite/libffi.call/cls_double.c (cls_ret_double_fn): Likewise. - * testsuite/libffi.call/cls_float.c (cls_ret_float_fn): Likewise. - * testsuite/libffi.call/cls_multi_schar.c (test_func_gn): Mark cif and - data unused. - (main): Cast res_call to silence gcc. - * testsuite/libffi.call/cls_multi_sshort.c (test_func_gn): Mark cif and - data unused. - (main): Cast res_call to silence gcc. - * testsuite/libffi.call/cls_multi_sshortchar.c (test_func_gn): Mark cif - and data unused. - (main): Cast res_call to silence gcc. - * testsuite/libffi.call/cls_multi_uchar.c (test_func_gn): Mark cif and - data unused. - (main): Cast res_call to silence gcc. - * testsuite/libffi.call/cls_multi_ushort.c (test_func_gn): Mark cif and - data unused. - (main): Cast res_call to silence gcc. - * testsuite/libffi.call/cls_multi_ushortchar.c (test_func_gn): Mark cif - and data unused. - (main): Cast res_call to silence gcc. - * testsuite/libffi.call/cls_schar.c (cls_ret_schar_fn): Mark cif and - userdata unused. - (cls_ret_schar_fn): Cast printf parameter to silence gcc. - * testsuite/libffi.call/cls_sint.c (cls_ret_sint_fn): Mark cif and - userdata unused. - (cls_ret_sint_fn): Cast printf parameter to silence gcc. - * testsuite/libffi.call/cls_sshort.c (cls_ret_sshort_fn): Mark cif and - userdata unused. - (cls_ret_sshort_fn): Cast printf parameter to silence gcc. - * testsuite/libffi.call/cls_uchar.c (cls_ret_uchar_fn): Mark cif and - userdata unused. - (cls_ret_uchar_fn): Cast printf parameter to silence gcc. - * testsuite/libffi.call/cls_uint.c (cls_ret_uint_fn): Mark cif and - userdata unused. - (cls_ret_uint_fn): Cast printf parameter to silence gcc. - * testsuite/libffi.call/cls_ulonglong.c (cls_ret_ulonglong_fn): Mark cif - and userdata unused. - * testsuite/libffi.call/cls_ushort.c (cls_ret_ushort_fn): Mark cif and - userdata unused. - (cls_ret_ushort_fn): Cast printf parameter to silence gcc. - * testsuite/libffi.call/float.c (floating): Remove unused parameter e. - * testsuite/libffi.call/float1.c (main): Remove unused variable i. - Cleanup white spaces. - * testsuite/libffi.call/negint.c (checking): Remove unused variable i. - * testsuite/libffi.call/nested_struct.c (cls_struct_combined_gn): Mark - cif and userdata unused. - * testsuite/libffi.call/nested_struct1.c (cls_struct_combined_gn): - Likewise. - * testsuite/libffi.call/nested_struct10.c (B_gn): Likewise. - * testsuite/libffi.call/nested_struct2.c (B_fn): Adjust printf - formatters to silence gcc. - (B_gn): Mark cif and userdata unused. - * testsuite/libffi.call/nested_struct3.c (B_gn): Mark cif and userdata - unused. - * testsuite/libffi.call/nested_struct4.c: Mention related PR. - (B_gn): Mark cif and userdata unused. - * testsuite/libffi.call/nested_struct5.c (B_gn): Mark cif and userdata - unused. - * testsuite/libffi.call/nested_struct6.c: Mention related PR. - (B_gn): Mark cif and userdata unused. - * testsuite/libffi.call/nested_struct7.c (B_gn): Mark cif and userdata - unused. - * testsuite/libffi.call/nested_struct8.c (B_gn): Likewise. - * testsuite/libffi.call/nested_struct9.c (B_gn): Likewise. - * testsuite/libffi.call/problem1.c (stub): Likewise. - * testsuite/libffi.call/pyobjc-tc.c (main): Cast the result to silence - gcc. - * testsuite/libffi.call/return_fl2.c (return_fl): Add the note mentioned - in the last commit for this test case in the test case itself. - * testsuite/libffi.call/closure_fn0.c (closure_test_fn0): Mark cif as - unused. - * testsuite/libffi.call/closure_fn1.c (closure_test_fn1): Likewise. - * testsuite/libffi.call/closure_fn2.c (closure_test_fn2): Likewise. - * testsuite/libffi.call/closure_fn3.c (closure_test_fn3): Likewise. - * testsuite/libffi.call/closure_fn4.c (closure_test_fn0): Likewise. - * testsuite/libffi.call/closure_fn5.c (closure_test_fn5): Likewise. - * testsuite/libffi.call/closure_fn6.c (closure_test_fn0): Likewise. - -2006-02-22 Kaz Kojima - - * src/sh/sysv.S: Fix register numbers in the FDE for - ffi_closure_SYSV. - -2006-02-20 Andreas Tobler - - * testsuite/libffi.call/return_fl2.c (return_fl): Remove static - declaration to avoid a false negative on ix86. See PR323. - -2006-02-18 Kaz Kojima - - * src/sh/ffi.c (ffi_closure_helper_SYSV): Remove unused variable - and cast integer to void * if needed. Update the pointer to - the FP register saved area correctly. - -2006-02-17 Andreas Tobler - - * testsuite/libffi.call/nested_struct6.c: XFAIL this test until PR25630 - is fixed. - * testsuite/libffi.call/nested_struct4.c: Likewise. - -2006-02-16 Andreas Tobler - - * testsuite/libffi.call/return_dbl.c: New test case. - * testsuite/libffi.call/return_dbl1.c: Likewise. - * testsuite/libffi.call/return_dbl2.c: Likewise. - * testsuite/libffi.call/return_fl.c: Likewise. - * testsuite/libffi.call/return_fl1.c: Likewise. - * testsuite/libffi.call/return_fl2.c: Likewise. - * testsuite/libffi.call/return_fl3.c: Likewise. - * testsuite/libffi.call/closure_fn6.c: Likewise. - - * testsuite/libffi.call/nested_struct2.c: Remove ffi_type_mylong - definition. - * testsuite/libffi.call/ffitest.h: Add ffi_type_mylong definition - here to be used by other test cases too. - - * testsuite/libffi.call/nested_struct10.c: New test case. - * testsuite/libffi.call/nested_struct9.c: Likewise. - * testsuite/libffi.call/nested_struct8.c: Likewise. - * testsuite/libffi.call/nested_struct7.c: Likewise. - * testsuite/libffi.call/nested_struct6.c: Likewise. - * testsuite/libffi.call/nested_struct5.c: Likewise. - * testsuite/libffi.call/nested_struct4.c: Likewise. - -2006-01-21 Andreas Tobler - - * configure.ac: Enable libffi for sparc64-*-freebsd*. - * configure: Rebuilt. - -2006-01-18 Jakub Jelinek - - * src/powerpc/sysv.S (smst_two_register): Don't call __ashldi3, - instead do the shifting inline. - * src/powerpc/ppc_closure.S (ffi_closure_SYSV): Don't compute %r5 - shift count unconditionally. Simplify load sequences for 1, 2, 3, 4 - and 8 byte structs, for the remaining struct sizes don't call - __lshrdi3, instead do the shifting inline. - -2005-12-07 Thiemo Seufer - - * src/mips/ffitarget.h: Remove obsolete sgidefs.h include. Add - missing parentheses. - * src/mips/o32.S (ffi_call_O32): Code formatting. Define - and use A3_OFF, FP_OFF, RA_OFF. Micro-optimizations. - (ffi_closure_O32): Likewise, but with newly defined A3_OFF2, - A2_OFF2, A1_OFF2, A0_OFF2, RA_OFF2, FP_OFF2, S0_OFF2, GP_OFF2, - V1_OFF2, V0_OFF2, FA_1_1_OFF2, FA_1_0_OFF2, FA_0_1_OFF2, - FA_0_0_OFF2. - * src/mips/ffi.c (ffi_prep_args): Code formatting. Fix - endianness bugs. - (ffi_prep_closure): Improve trampoline instruction scheduling. - (ffi_closure_mips_inner_O32): Fix endianness bugs. - -2005-12-03 Alan Modra - - * src/powerpc/ffi.c: Formatting. - (ffi_prep_args_SYSV): Avoid possible aliasing problems by using unions. - (ffi_prep_args64): Likewise. - -2005-09-30 Geoffrey Keating - - * testsuite/lib/libffi-dg.exp (libffi_target_compile): For - darwin, use -shared-libgcc not -lgcc_s, and explain why. - -2005-09-26 Tom Tromey - - * testsuite/libffi.call/float1.c (value_type): New typedef. - (CANARY): New define. - (main): Check for result buffer overflow. - * src/powerpc/linux64.S: Handle linux64 long double returns. - * src/powerpc/ffi.c (FLAG_RETURNS_128BITS): New constant. - (ffi_prep_cif_machdep): Handle linux64 long double returns. - -2005-08-25 Alan Modra - - PR target/23404 - * src/powerpc/ffi.c (ffi_prep_args_SYSV): Correct placement of stack - homed fp args. - (ffi_status ffi_prep_cif_machdep): Correct stack sizing for same. - -2005-08-11 Jakub Jelinek - - * configure.ac (HAVE_HIDDEN_VISIBILITY_ATTRIBUTE): New test. - (AH_BOTTOM): Add FFI_HIDDEN definition. - * configure: Rebuilt. - * fficonfig.h.in: Rebuilt. - * src/powerpc/ffi.c (hidden): Remove. - (ffi_closure_LINUX64, ffi_prep_args64, ffi_call_LINUX64, - ffi_closure_helper_LINUX64): Use FFI_HIDDEN instead of hidden. - * src/powerpc/linux64_closure.S (ffi_closure_LINUX64, - .ffi_closure_LINUX64): Use FFI_HIDDEN instead of .hidden. - * src/x86/ffi.c (ffi_closure_SYSV, ffi_closure_raw_SYSV): Remove, - add FFI_HIDDEN to its prototype. - (ffi_closure_SYSV_inner): New. - * src/x86/sysv.S (ffi_closure_SYSV, ffi_closure_raw_SYSV): New. - * src/x86/win32.S (ffi_closure_SYSV, ffi_closure_raw_SYSV): New. - -2005-08-10 Alfred M. Szmidt - - PR libffi/21819: - * configure: Rebuilt. - * configure.ac: Handle i*86-*-gnu*. - -2005-08-09 Jakub Jelinek - - * src/powerpc/ppc_closure.S (ffi_closure_SYSV): Use - DW_CFA_offset_extended_sf rather than - DW_CFA_GNU_negative_offset_extended. - * src/powerpc/sysv.S (ffi_call_SYSV): Likewise. - -2005-07-22 SUGIOKA Toshinobu - - * src/sh/sysv.S (ffi_call_SYSV): Stop argument popping correctly - on sh3. - (ffi_closure_SYSV): Change the stack layout for sh3 struct argument. - * src/sh/ffi.c (ffi_prep_args): Fix sh3 argument copy, when it is - partially on register. - (ffi_closure_helper_SYSV): Likewise. - (ffi_prep_cif_machdep): Don't set too many cif->flags. - -2005-07-20 Kaz Kojima - - * src/sh/ffi.c (ffi_call): Handle small structures correctly. - Remove empty line. - * src/sh64/ffi.c (simple_type): Remove. - (return_type): Handle small structures correctly. - (ffi_prep_args): Likewise. - (ffi_call): Likewise. - (ffi_closure_helper_SYSV): Likewise. - * src/sh64/sysv.S (ffi_call_SYSV): Handle 1, 2 and 4-byte return. - Emit position independent code if PIC and remove wrong datalabel - prefixes from EH data. - -2005-07-19 Andreas Tobler - - * Makefile.am (nodist_libffi_la_SOURCES): Add POWERPC_FREEBSD. - * Makefile.in: Regenerate. - * include/Makefile.in: Likewise. - * testsuite/Makefile.in: Likewise. - * configure.ac: Add POWERPC_FREEBSD rules. - * configure: Regenerate. - * src/powerpc/ffitarget.h: Add POWERPC_FREEBSD rules. - (FFI_SYSV_TYPE_SMALL_STRUCT): Define. - * src/powerpc/ffi.c: Add flags to handle small structure returns - in ffi_call_SYSV. - (ffi_prep_cif_machdep): Handle small structures for SYSV 4 ABI. - Aka FFI_SYSV. - (ffi_closure_helper_SYSV): Likewise. - * src/powerpc/ppc_closure.S: Add return types for small structures. - * src/powerpc/sysv.S: Add bits to handle small structures for - final SYSV 4 ABI. - -2005-07-10 Andreas Tobler - - * testsuite/libffi.call/cls_5_1_byte.c: New test file. - * testsuite/libffi.call/cls_6_1_byte.c: Likewise. - * testsuite/libffi.call/cls_7_1_byte.c: Likewise. - -2005-07-05 Randolph Chung - - * src/pa/ffi.c (ffi_struct_type): Rename FFI_TYPE_SMALL_STRUCT1 - as FFI_TYPE_SMALL_STRUCT3. Break out handling for 5-7 byte - structures. Kill compilation warnings. - (ffi_closure_inner_LINUX): Print return values as hex in debug - message. Rename FFI_TYPE_SMALL_STRUCT1 as FFI_TYPE_SMALL_STRUCT3. - Properly handle 5-7 byte structure returns. - * src/pa/ffitarget.h (FFI_TYPE_SMALL_STRUCT1) - (FFI_TYPE_SMALL_STRUCT2): Remove. - (FFI_TYPE_SMALL_STRUCT3, FFI_TYPE_SMALL_STRUCT5) - (FFI_TYPE_SMALL_STRUCT6, FFI_TYPE_SMALL_STRUCT7): Define. - * src/pa/linux.S: Mark source file as using PA1.1 assembly. - (checksmst1, checksmst2): Remove. - (checksmst3): Optimize handling of 3-byte struct returns. - (checksmst567): Properly handle 5-7 byte struct returns. - -2005-06-15 Rainer Orth - - PR libgcj/21943 - * src/mips/n32.S: Enforce PIC code. - * src/mips/o32.S: Likewise. - -2005-06-15 Rainer Orth - - * configure.ac: Treat i*86-*-solaris2.10 and up as X86_64. - * configure: Regenerate. +commit 56ba8d86f47937a0afb81a2b9e77c9d235d9db45 +Author: Anthony Green +Date: Thu Jan 10 07:25:10 2013 -0500 -2005-06-01 Alan Modra + Don't use warning checking macro with sun compiler - * src/powerpc/ppc_closure.S (ffi_closure_SYSV): Don't use JUMPTARGET - to call ffi_closure_helper_SYSV. Append @local instead. - * src/powerpc/sysv.S (ffi_call_SYSV): Likewise for ffi_prep_args_SYSV. +commit 6a028caec1b2c7904feb4c4f9cb7e1125e1d1b60 +Author: Anthony Green +Date: Thu Jan 10 01:19:43 2013 -0500 -2005-05-17 Kelley Cook + Don't use GCCisms to define types when + + building with the SUNPRO compiler. - * configure.ac: Use AC_C_BIGENDIAN instead of AC_C_BIGENDIAN_CROSS. - Use AC_CHECK_SIZEOF instead of AC_COMPILE_CHECK_SIZEOF. - * Makefile.am (ACLOCAL_AMFLAGS): Remove -I ../config. - * aclocal.m4, configure, fficonfig.h.in, Makefile.in, - include/Makefile.in, testsuite/Makefile.in: Regenerate. +commit 2d9b3939751b3ef9739049509d353ade10b32a8f +Author: Anthony Green +Date: Wed Jan 9 21:14:54 2013 -0500 -2005-05-09 Mike Stump + Fix for closures with sunpro compiler - * configure: Regenerate. +commit 8308984e479e3274a36e98e8272b5adbb6b774c2 +Author: Anthony Green +Date: Tue Jan 8 15:14:21 2013 -0500 -2005-05-08 Richard Henderson + Make sure we're running dejagnu tests with the right compiler. - PR libffi/21285 - * src/alpha/osf.S: Update unwind into to match code. +commit f26c7ca67147450db2fe25ea932944e6cf145d5c +Author: Anthony Green +Date: Tue Jan 8 14:47:05 2013 -0500 -2005-05-04 Andreas Degert - Richard Henderson + Make compiler options in dejagnu runs compiler specific - * src/x86/ffi64.c (ffi_prep_cif_machdep): Save sse-used flag in - bit 11 of flags. - (ffi_call): Mask return type field. Pass ssecount to ffi_call_unix64. - (ffi_prep_closure): Set carry bit if sse-used flag set. - * src/x86/unix64.S (ffi_call_unix64): Add ssecount argument. - Only load sse registers if ssecount non-zero. - (ffi_closure_unix64): Only save sse registers if carry set on entry. +commit 74c776e21907fc2e59257c021f23077f8b7966cb +Author: Anthony Green +Date: Tue Jan 8 12:25:54 2013 -0500 -2005-04-29 Ralf Corsepius + Switch x86 Solaris to X86 from X86_64 - * configure.ac: Add i*86-*-rtems*, sparc*-*-rtems*, - powerpc-*rtems*, arm*-*-rtems*, sh-*-rtems*. - * configure: Regenerate. +commit 8962c8c8d06803e310bac0ffc8e84ea15daeff3f +Author: Anthony Green +Date: Tue Jan 8 12:22:24 2013 -0500 -2005-04-20 Hans-Peter Nilsson + Fix read-only eh_frame test - * testsuite/lib/libffi-dg.exp (libffi-dg-test-1): In regsub use, - have Tcl8.3-compatible intermediate variable. +commit 35ddb69c2b49746d940e919ca226ecc1be94f14a +Author: Anthony Green +Date: Tue Jan 8 07:53:37 2013 -0500 -2005-04-18 Simon Posnjak - Hans-Peter Nilsson + Only emit DWARF unwind info when building with GCC - * Makefile.am: Add CRIS support. - * configure.ac: Likewise. - * Makefile.in, configure, testsuite/Makefile.in, - include/Makefile.in: Regenerate. - * src/cris: New directory. - * src/cris/ffi.c, src/cris/sysv.S, src/cris/ffitarget.h: New files. - * src/prep_cif.c (ffi_prep_cif): Wrap in #ifndef __CRIS__. +commit f7879bc3f3a8d0bbfcc38771732c160a58ba9cd8 +Author: Anthony Green +Date: Tue Jan 8 07:30:28 2013 -0500 - * testsuite/lib/libffi-dg.exp (libffi-dg-test-1): Replace \n with - \r?\n in output tests. + Testsuite fix for Solaris vendor compiler -2005-04-12 Mike Stump +commit 67cea90fc0897021466fd102671019d30db474cd +Author: Anthony Green +Date: Mon Jan 7 06:30:24 2013 -0500 - * configure: Regenerate. + mend -2005-03-30 Hans Boehm +commit 0de3277b18cf54be3b81d509b9be9b47d9bc1e82 +Author: Thorsten Glaser +Date: Mon Dec 3 00:02:31 2012 +0000 - * src/ia64/ffitarget.h (ffi_arg): Use long long instead of DI. + Testsuite fixes (was Re: [PATCH] Fix libffi on m68k-linux-gnu, completely) + + Dixi quod… + + >although I believe some 3.0.11 checks to be broken: + + And indeed, with a few minor changes on top of git master, + I still get a full run of PASS plus one XPASS on amd64-linux! + + With the other patches (from this message’s parent) and + these applied, I get a full PASS on m68k-linux as well. + + So, please git am these three diffs ☺ + + bye, + //mirabilos + -- + FWIW, I'm quite impressed with mksh interactively. I thought it was much + *much* more bare bones. But it turns out it beats the living hell out of + ksh93 in that respect. I'd even consider it for my daily use if I hadn't + wasted half my life on my zsh setup. :-) -- Frank Terbeck in #!/bin/mksh + From 5cb15a3bad1f0fb360520dd48bfc938c821cdcca Mon Sep 17 00:00:00 2001 + From: Thorsten Glaser + Date: Sun, 2 Dec 2012 23:20:56 +0000 + Subject: [PATCH 1/2] Fix tests writing to a closure retval via pointer casts + + As explained in + all other tests that do the same cast to an ffi_arg pointer instead. + + PASS on amd64-linux (Xen domU) and m68k-linux (ARAnyM) + + Signed-off-by: Thorsten Glaser -2005-03-30 Steve Ellcey +commit 8f4772f383abd71cfa141c8a70ba11c1aa4ebe2c +Author: Anthony Green +Date: Mon Jan 7 06:14:53 2013 -0500 - * src/ia64/ffitarget.h (ffi_arg) ADD DI attribute. - (ffi_sarg) Ditto. - * src/ia64/unix.S (ffi_closure_unix): Extend gp - to 64 bits in ILP32 mode. - Load 64 bits even for short data. + m68k fixes for signed 8 and 16-bit calls. -2005-03-23 Mike Stump +commit ea7f8440d58afbebb181e295ff564fdf3d6590a0 +Author: Anthony Green +Date: Fri Jan 4 09:09:32 2013 -0500 - * src/powerpc/darwin.S: Update for -m64 multilib. - * src/powerpc/darwin_closure.S: Likewise. + remove gcc-ism -2005-03-21 Zack Weinberg +commit f06c0f10377ac04eeba5e632dbe5c62c629df4e6 +Author: Anthony Green +Date: Wed Jan 2 09:39:17 2013 -0500 - * configure.ac: Do not invoke TL_AC_GCC_VERSION. - Do not set tool_include_dir. - * aclocal.m4, configure, Makefile.in, testsuite/Makefile.in: - Regenerate. - * include/Makefile.am: Set gcc_version and toollibffidir. - * include/Makefile.in: Regenerate. + Add missing ChangeLog entry and generated files. -2005-02-22 Andrew Haley +commit 1f8675d4c101d19d67ca0a55ff2ba973349558ad +Merge: 335f419 f6b58d2 +Author: Anthony Green +Date: Wed Jan 2 06:34:38 2013 -0800 - * src/powerpc/ffi.c (ffi_prep_cif_machdep): Bump alignment to - odd-numbered register pairs for 64-bit integer types. + Merge pull request #26 from rofl0r/master + + fix build error on ppc when long double == double -2005-02-23 Andreas Tobler +commit 335f419a86090cda9f215d149572f9481c3ad034 +Merge: 53236d5 6d6f711 +Author: Anthony Green +Date: Wed Jan 2 06:30:03 2013 -0800 - PR libffi/20104 - * testsuite/libffi.call/return_ll1.c: New test case. + Merge pull request #23 from rurban/master + + cygwin/mingw shared libs need libtool LDFLAGS = -no-undefined -2005-02-11 Janis Johnson +commit 53236d5061034cc0a7f4647fc1bd05ba1aeb3d2a +Author: Anthony Green +Date: Wed Jan 2 09:24:55 2013 -0500 - * testsuite/libffi.call/cls_align_longdouble.c: Remove dg-options. - * testsuite/libffi.call/float.c: Ditto. - * testsuite/libffi.call/float2.c: Ditto. - * testsuite/libffi.call/float3.c: Ditto. + Regenerate files -2005-02-08 Andreas Tobler +commit 72222ca3fbe560e13c8dc89ca441b28b7cc74daf +Author: Anthony Green +Date: Wed Jan 2 09:06:38 2013 -0500 - * src/frv/ffitarget.h: Remove PPC stuff which does not belong to frv. + Update texinfo.tex -2005-01-12 Eric Botcazou +commit 1e326c95431fc9896422fa36659f3e833852579c +Author: Anthony Green +Date: Wed Jan 2 09:05:02 2013 -0500 - * testsuite/libffi.special/special.exp (cxx_options): Add - -shared-libgcc. + Update config.guess and config.sub -2004-12-31 Richard Henderson +commit cb6671f5b8a9596ff968c6b6c304f70adf71b368 +Author: Anthony Green +Date: Wed Jan 2 08:56:07 2013 -0500 - * src/types.c (FFI_AGGREGATE_TYPEDEF): Remove. - (FFI_TYPEDEF): Rename from FFI_INTEGRAL_TYPEDEF. Replace size and - offset parameters with a type parameter; deduce size and structure - alignment. Update all users. + Missing .gitignore changes for xcode support -2004-12-31 Richard Henderson +commit ebbe77966855395a2a47ed2c09a38f93eb0481cf +Author: Anthony Green +Date: Wed Jan 2 08:54:05 2013 -0500 - * src/types.c (FFI_TYPE_POINTER): Define with sizeof. - (FFI_TYPE_LONGDOUBLE): Fix for ia64. - * src/ia64/ffitarget.h (struct ffi_ia64_trampoline_struct): Move - into ffi_prep_closure. - * src/ia64/ia64_flags.h, src/ia64/ffi.c, src/ia64/unix.S: Rewrite - from scratch. + missed x32 libtool patch. -2004-12-27 Richard Henderson +commit 4394096da0aca0dd422b479a043c18b4f05c5770 +Author: Anthony Green +Date: Wed Jan 2 08:51:35 2013 -0500 - * src/x86/unix64.S: Fix typo in unwind info. + missed trampoline_table patch. Move to GCC. -2004-12-25 Richard Henderson +commit ed7a59c3ff7c84bd95c374a5aff21599f705e6dc +Author: Anthony Green +Date: Wed Jan 2 08:48:01 2013 -0500 - * src/x86/ffi64.c (struct register_args): Rename from stackLayout. - (enum x86_64_reg_class): Add X86_64_COMPLEX_X87_CLASS. - (merge_classes): Check for it. - (SSE_CLASS_P): New. - (classify_argument): Pass byte_offset by value; perform all updates - inside struct case. - (examine_argument): Add classes argument; handle - X86_64_COMPLEX_X87_CLASS. - (ffi_prep_args): Merge into ... - (ffi_call): ... here. Share stack frame with ffi_call_unix64. - (ffi_prep_cif_machdep): Setup cif->flags for proper structure return. - (ffi_fill_return_value): Remove. - (ffi_prep_closure): Remove dead assert. - (ffi_closure_unix64_inner): Rename from ffi_closure_UNIX64_inner. - Rewrite to use struct register_args instead of va_list. Create - flags for handling structure returns. - * src/x86/unix64.S: Remove dead strings. - (ffi_call_unix64): Rename from ffi_call_UNIX64. Rewrite to share - stack frame with ffi_call. Handle structure returns properly. - (float2sse, floatfloat2sse, double2sse): Remove. - (sse2float, sse2double, sse2floatfloat): Remove. - (ffi_closure_unix64): Rename from ffi_closure_UNIX64. Rewrite - to handle structure returns properly. + Windows symbol export fix. Move to GCC. -2004-12-08 David Edelsohn +commit ccee09a4ff843b11c7d8b6819776f57d187305c7 +Author: Anthony Green +Date: Wed Jan 2 08:41:55 2013 -0500 - * Makefile.am (AM_MAKEFLAGS): Remove duplicate LIBCFLAGS and - PICFLAG. - * Makefile.in: Regenerated. + +2012-03-21 Peter Rosin + + + + * testsuite/lib/target-libpath.exp [*-*-cygwin*, *-*-mingw*] + + (set_ld_library_path_env_vars): Add the library search dir to PATH + + (and save PATH for later). + + (restore_ld_library_path_env_vars): Restore PATH. -2004-12-02 Richard Sandiford +commit 089dbce7cc0889eb26444d89ae062c73c69f26f0 +Author: Anthony Green +Date: Wed Jan 2 08:37:35 2013 -0500 - * configure.ac: Use TL_AC_GCC_VERSION to set gcc_version. - * configure, aclocal.m4, Makefile.in: Regenerate. - * include/Makefile.in, testsuite/Makefile.in: Regenerate. + med -2004-11-29 Kelley Cook +commit 980a334c42b4b0eff32e55929ec6727d1326b05d +Author: Anthony Green +Date: Wed Jan 2 07:36:42 2013 -0500 - * configure: Regenerate for libtool change. + Test GCC update -2004-11-25 Kelley Cook +commit 8bad679ade5000e57cdc9cacde22e8b99840930f +Author: Anthony Green +Date: Wed Jan 2 08:28:35 2013 -0500 - * configure: Regenerate for libtool reversion. + New stand-alone patch -2004-11-24 Kelley Cook +commit 981c32ee115e9f0d6546a74592875e138222a9d1 +Author: Anthony Green +Date: Wed Jan 2 07:34:03 2013 -0500 - * configure: Regenerate for libtool change. + Merge with GCC. Eliminate quilt bits. -2004-11-23 John David Anglin +commit 61a054929517fb80c437ba71c91f3e20cfff581a +Author: Anthony Green +Date: Wed Nov 28 06:07:41 2012 -0500 - * testsuite/lib/libffi-dg.exp: Use new procs in target-libpath.exp. + Refresh config.guess and config.sub -2004-11-23 Richard Sandiford +commit f6b58d2bdc0a24ce94dedce59802f091979df265 +Author: rofl0r +Date: Thu Nov 22 16:26:21 2012 +0100 - * src/mips/o32.S (ffi_call_O32, ffi_closure_O32): Use jalr instead - of jal. Use an absolute encoding for the frame information. + fix build on ppc when long double == double -2004-11-23 Kelley Cook +commit 69da33a0761aeac73f9e9646269da61c906d6020 +Author: Anthony Green +Date: Mon Nov 12 15:25:47 2012 -0500 - * Makefile.am: Remove no-dependencies. Add ACLOCAL_AMFLAGS. - * acinclude.m4: Delete logic for sincludes. - * aclocal.m4, Makefile.in, configure: Regenerate. - * include/Makefile: Likewise. - * testsuite/Makefile: Likewise. + Pull in config.sub for aarch64 support and more -2004-11-22 Eric Botcazou +commit f680b598b7bdde325ac9349e8c35151c228bf2df +Author: Anthony Green +Date: Tue Nov 6 16:00:40 2012 -0500 - * src/sparc/ffi.c (ffi_prep_closure): Align doubles and 64-bit integers - on a 8-byte boundary. - * src/sparc/v8.S (ffi_closure_v8): Reserve frame space for arguments. + Add missing aarch64 configury bits -2004-10-27 Richard Earnshaw +commit dfadfb19853c57c8623c436d0ef2bdafab24b433 +Author: Anthony Green +Date: Wed Oct 31 06:46:41 2012 -0400 - * src/arm/ffi.c (ffi_prep_cif_machdep): Handle functions that return - long long values. Round stack allocation to a multiple of 8 bytes - for ATPCS compatibility. - * src/arm/sysv.S (ffi_call_SYSV): Rework to avoid use of APCS register - names. Handle returning long long types. Add Thumb and interworking - support. Improve soft-float code. + Rebase for ppc64 fix -2004-10-27 Richard Earnshaw +commit e944b8c7eb1e2eeb9c0f3b9742b4d7f476860ce1 +Author: Anthony Green +Date: Tue Oct 30 14:06:09 2012 -0400 - * testsuite/lib/libffi-db.exp (load_gcc_lib): New function. - (libffi_exit): New function. - (libffi_init): Build the testglue wrapper if needed. + Add PaX work-around -2004-10-25 Eric Botcazou +commit 9ccd51be1fdeb99f8b4f42f905166c2abbba8ac0 +Merge: f342996 fa5d747 +Author: Anthony Green +Date: Tue Oct 30 13:37:37 2012 -0400 - PR other/18138 - * testsuite/lib/libffi-dg.exp: Accept more than one multilib libgcc. + Fix commit conflicts -2004-10-25 Kazuhiro Inaoka +commit f342996cb50eb23b868afcff5ac0cdbb6b505d63 +Author: Anthony Green +Date: Tue Oct 30 07:42:27 2012 -0400 - * src/m32r/libffitarget.h (FFI_CLOSURES): Set to 0. + Darwin12 fix -2004-10-20 Kaz Kojima +commit 58e8b66f70cef2e3c9b0e5a707b45d634cbbf5d9 +Author: Anthony Green +Date: Tue Oct 30 07:07:19 2012 -0400 - * src/sh/sysv.S (ffi_call_SYSV): Don't align for double data. - * testsuite/libffi.call/float3.c: New test case. - -2004-10-18 Kaz Kojima - - * src/sh/ffi.c (ffi_prep_closure): Set T bit in trampoline for - the function returning a structure pointed with R2. - * src/sh/sysv.S (ffi_closure_SYSV): Use R2 as the pointer to - the structure return value if T bit set. Emit position - independent code and EH data if PIC. - -2004-10-13 Kazuhiro Inaoka - - * Makefile.am: Add m32r support. - * configure.ac: Likewise. - * Makefile.in: Regenerate. - * confiugre: Regenerate. - * src/types.c: Add m32r port to FFI_INTERNAL_TYPEDEF - (uint64, sint64, double, longdouble) - * src/m32r: New directory. - * src/m32r/ffi.c: New file. - * src/m32r/sysv.S: Likewise. - * src/m32r/ffitarget.h: Likewise. - -2004-10-02 Kaz Kojima - - * testsuite/libffi.call/negint.c: New test case. - -2004-09-14 H.J. Lu - - PR libgcj/17465 - * testsuite/lib/libffi-dg.exp: Don't use global ld_library_path. - Set up LD_LIBRARY_PATH, SHLIB_PATH, LD_LIBRARYN32_PATH, - LD_LIBRARY64_PATH, LD_LIBRARY_PATH_32, LD_LIBRARY_PATH_64 and - DYLD_LIBRARY_PATH. - -2004-09-05 Andreas Tobler - - * testsuite/libffi.call/many_win32.c: Remove whitespaces. - * testsuite/libffi.call/promotion.c: Likewise. - * testsuite/libffi.call/return_ll.c: Remove unused var. Cleanup - whitespaces. - * testsuite/libffi.call/return_sc.c: Likewise. - * testsuite/libffi.call/return_uc.c: Likewise. - -2004-09-05 Andreas Tobler - - * src/powerpc/darwin.S: Fix comments and identation. - * src/powerpc/darwin_closure.S: Likewise. - -2004-09-02 Andreas Tobler - - * src/powerpc/ffi_darwin.c: Add flag for longdouble return values. - (ffi_prep_args): Handle longdouble arguments. - (ffi_prep_cif_machdep): Set flags for longdouble. Calculate space for - longdouble. - (ffi_closure_helper_DARWIN): Add closure handling for longdouble. - * src/powerpc/darwin.S (_ffi_call_DARWIN): Add handling of longdouble - values. - * src/powerpc/darwin_closure.S (_ffi_closure_ASM): Likewise. - * src/types.c: Defined longdouble size and alignment for darwin. - -2004-09-02 Andreas Tobler - - * src/powerpc/aix.S: Remove whitespaces. - * src/powerpc/aix_closure.S: Likewise. - * src/powerpc/asm.h: Likewise. - * src/powerpc/ffi.c: Likewise. - * src/powerpc/ffitarget.h: Likewise. - * src/powerpc/linux64.S: Likewise. - * src/powerpc/linux64_closure.S: Likewise. - * src/powerpc/ppc_closure.S: Likewise. - * src/powerpc/sysv.S: Likewise. - -2004-08-30 Anthony Green - - * Makefile.am: Add frv support. - * Makefile.in, testsuite/Makefile.in: Rebuilt. - * configure.ac: Read configure.host. - * configure.in: Read configure.host. - * configure.host: New file. frv-elf needs libgloss. - * include/ffi.h.in: Force ffi_closure to have a nice big (8) - alignment. This is needed to frv and shouldn't harm the others. - * include/ffi_common.h (ALIGN_DOWN): New macro. - * src/frv/ffi.c, src/frv/ffitarget.h, src/frv/eabi.S: New files. - -2004-08-24 David Daney - - * testsuite/libffi.call/closure_fn0.c: Xfail mips64* instead of mips*. - * testsuite/libffi.call/closure_fn1.c: Likewise. - * testsuite/libffi.call/closure_fn2.c Likewise. - * testsuite/libffi.call/closure_fn3.c: Likewise. - * testsuite/libffi.call/closure_fn4.c: Likewise. - * testsuite/libffi.call/closure_fn5.c: Likewise. - * testsuite/libffi.call/cls_18byte.c: Likewise. - * testsuite/libffi.call/cls_19byte.c: Likewise. - * testsuite/libffi.call/cls_1_1byte.c: Likewise. - * testsuite/libffi.call/cls_20byte.c: Likewise. - * testsuite/libffi.call/cls_20byte1.c: Likewise. - * testsuite/libffi.call/cls_24byte.c: Likewise. - * testsuite/libffi.call/cls_2byte.c: Likewise. - * testsuite/libffi.call/cls_3_1byte.c: Likewise. - * testsuite/libffi.call/cls_3byte1.c: Likewise. - * testsuite/libffi.call/cls_3byte2.c: Likewise. - * testsuite/libffi.call/cls_4_1byte.c: Likewise. - * testsuite/libffi.call/cls_4byte.c: Likewise. - * testsuite/libffi.call/cls_64byte.c: Likewise. - * testsuite/libffi.call/cls_6byte.c: Likewise. - * testsuite/libffi.call/cls_7byte.c: Likewise. - * testsuite/libffi.call/cls_8byte.c: Likewise. - * testsuite/libffi.call/cls_9byte1.c: Likewise. - * testsuite/libffi.call/cls_9byte2.c: Likewise. - * testsuite/libffi.call/cls_align_double.c: Likewise. - * testsuite/libffi.call/cls_align_float.c: Likewise. - * testsuite/libffi.call/cls_align_longdouble.c: Likewise. - * testsuite/libffi.call/cls_align_pointer.c: Likewise. - * testsuite/libffi.call/cls_align_sint16.c: Likewise. - * testsuite/libffi.call/cls_align_sint32.c: Likewise. - * testsuite/libffi.call/cls_align_sint64.c: Likewise. - * testsuite/libffi.call/cls_align_uint16.c: Likewise. - * testsuite/libffi.call/cls_align_uint32.c: Likewise. - * testsuite/libffi.call/cls_align_uint64.c: Likewise. - * testsuite/libffi.call/cls_double.c: Likewise. - * testsuite/libffi.call/cls_float.c: Likewise. - * testsuite/libffi.call/cls_multi_schar.c: Likewise. - * testsuite/libffi.call/cls_multi_sshort.c: Likewise. - * testsuite/libffi.call/cls_multi_sshortchar.c: Likewise. - * testsuite/libffi.call/cls_multi_uchar.c: Likewise. - * testsuite/libffi.call/cls_multi_ushort.c: Likewise. - * testsuite/libffi.call/cls_multi_ushortchar.c: Likewise. - * testsuite/libffi.call/cls_schar.c: Likewise. - * testsuite/libffi.call/cls_sint.c: Likewise. - * testsuite/libffi.call/cls_sshort.c: Likewise. - * testsuite/libffi.call/cls_uchar.c: Likewise. - * testsuite/libffi.call/cls_uint.c: Likewise. - * testsuite/libffi.call/cls_ulonglong.c: Likewise. - * testsuite/libffi.call/cls_ushort.c: Likewise. - * testsuite/libffi.call/nested_struct.c: Likewise. - * testsuite/libffi.call/nested_struct1.c: Likewise. - * testsuite/libffi.call/nested_struct2.c: Likewise. - * testsuite/libffi.call/nested_struct3.c: Likewise. - * testsuite/libffi.call/problem1.c: Likewise. - * testsuite/libffi.special/unwindtest.cc: Likewise. - * testsuite/libffi.call/cls_12byte.c: Likewise and set return value - to zero. - * testsuite/libffi.call/cls_16byte.c: Likewise. - * testsuite/libffi.call/cls_5byte.c: Likewise. - -2004-08-23 David Daney - - PR libgcj/13141 - * src/mips/ffitarget.h (FFI_O32_SOFT_FLOAT): New ABI. - * src/mips/ffi.c (ffi_prep_args): Fix alignment calculation. - (ffi_prep_cif_machdep): Handle FFI_O32_SOFT_FLOAT floating point - parameters and return types. - (ffi_call): Handle FFI_O32_SOFT_FLOAT ABI. - (ffi_prep_closure): Ditto. - (ffi_closure_mips_inner_O32): Handle FFI_O32_SOFT_FLOAT ABI, fix - alignment calculations. - * src/mips/o32.S (ffi_closure_O32): Don't use floating point - instructions if FFI_O32_SOFT_FLOAT, make stack frame ABI compliant. - -2004-08-14 Casey Marshall - - * src/mips/ffi.c (ffi_pref_cif_machdep): set `cif->flags' to - contain `FFI_TYPE_UINT64' as return type for any 64-bit - integer (O32 ABI only). - (ffi_prep_closure): new function. - (ffi_closure_mips_inner_O32): new function. - * src/mips/ffitarget.h: Define `FFI_CLOSURES' and - `FFI_TRAMPOLINE_SIZE' appropriately if the ABI is o32. - * src/mips/o32.S (ffi_call_O32): add labels for .eh_frame. Return - 64 bit integers correctly. - (ffi_closure_O32): new function. - Added DWARF-2 unwind info for both functions. - -2004-08-10 Andrew Haley - - * src/x86/ffi64.c (ffi_prep_args ): 8-align all stack arguments. - -2004-08-01 Robert Millan - - * configure.ac: Detect knetbsd-gnu and kfreebsd-gnu. - * configure: Regenerate. - -2004-07-30 Maciej W. Rozycki - - * acinclude.m4 (AC_FUNC_MMAP_BLACKLIST): Check for - and mmap() explicitly instead of relying on preset autoconf cache - variables. - * aclocal.m4: Regenerate. - * configure: Regenerate. - -2004-07-11 Ulrich Weigand - - * src/s390/ffi.c (ffi_prep_args): Fix C aliasing violation. - (ffi_check_float_struct): Remove unused prototype. - -2004-06-30 Geoffrey Keating - - * src/powerpc/ffi_darwin.c (flush_icache): ';' is a comment - character on Darwin, use '\n\t' instead. - -2004-06-26 Matthias Klose - - * libtool-version: Fix typo in revision/age. - -2004-06-17 Matthias Klose - - * libtool-version: New. - * Makefile.am (libffi_la_LDFLAGS): Use -version-info for soname. - * Makefile.in: Regenerate. - -2004-06-15 Paolo Bonzini - - * Makefile.am: Remove useless multilib rules. - * Makefile.in: Regenerate. - * aclocal.m4: Regenerate with automake 1.8.5. - * configure.ac: Remove useless multilib configury. - * configure: Regenerate. - -2004-06-15 Paolo Bonzini - - * .cvsignore: New file. - -2004-06-10 Jakub Jelinek - - * src/ia64/unix.S (ffi_call_unix): Insert group barrier break - fp_done. - (ffi_closure_UNIX): Fix f14/f15 adjustment if FLOAT_SZ is ever - changed from 8. - -2004-06-06 Sean McNeil - - * configure.ac: Add x86_64-*-freebsd* support. - * configure: Regenerate. + AArch64 port -2004-04-26 Joe Buck +commit fa5d747905472571fd472c07d4726017624f66b3 +Author: Anthony Green +Date: Tue Oct 30 07:07:19 2012 -0400 - Bug 15093 - * configure.ac: Test for existence of mmap and sys/mman.h before - checking blacklist. Fix suggested by Jim Wilson. - * configure: Regenerate. + AArch64 port -2004-04-26 Matt Austern +commit 6993a6686f43f2313b18142c1e96189a27db2aa3 +Author: Anthony Green +Date: Tue Oct 30 06:59:32 2012 -0400 - * src/powerpc/darwin.S: Go through a non-lazy pointer for initial - FDE location. - * src/powerpc/darwin_closure.S: Likewise. + Fix autoconf macros -2004-04-24 Andreas Tobler +commit 70084e70ddb13b29dd05c751b1904de206bbe790 +Author: Anthony Green +Date: Fri Oct 12 23:55:06 2012 -0400 - * testsuite/libffi.call/cls_multi_schar.c (main): Fix initialization - error. Reported by Thomas Heller . - * testsuite/libffi.call/cls_multi_sshort.c (main): Likewise. - * testsuite/libffi.call/cls_multi_ushort.c (main): Likewise. + Update Tile* port info -2004-03-20 Matthias Klose +commit 9c00a3f6742d61404b31268cc773e7130ff43331 +Author: Anthony Green +Date: Fri Oct 12 16:46:06 2012 -0400 - * src/pa/linux.S: Fix typo. + TILE-Gx/TILEPro support -2004-03-19 Matthias Klose +commit 048d2f41c3a6664b4b64bf21e804686662da4160 +Author: Anthony Green +Date: Thu Oct 11 10:55:25 2012 -0400 - * Makefile.am: Update. - * Makefile.in: Regenerate. - * src/pa/ffi.h.in: Remove. - * src/pa/ffitarget.h: New file. + Rebase -2004-02-10 Randolph Chung +commit 6d6f71108064f5069edd7bf771059d3b82640135 +Author: Reini Urban +Date: Sat Jul 7 12:42:00 2012 -0500 - * Makefile.am: Add PA support. - * Makefile.in: Regenerate. - * include/Makefile.in: Regenerate. - * configure.ac: Add PA target. - * configure: Regenerate. - * src/pa/ffi.c: New file. - * src/pa/ffi.h.in: Add PA support. - * src/pa/linux.S: New file. - * prep_cif.c: Add PA support. + cygwin/mingw shared libs need libtool LDFLAGS = -no-undefined + + otherwise only static libs are created. -2004-03-16 Hosaka Yuji +commit d330f19292da8f39a78a9e2b0ba08df8094e3bc5 +Author: Nicolas Lelong +Date: Sat May 5 09:37:02 2012 -0400 - * src/types.c: Fix alignment size of X86_WIN32 case int64 and - double. - * src/x86/ffi.c (ffi_prep_args): Replace ecif->cif->rtype->type - with ecif->cif->flags. - (ffi_call, ffi_prep_incoming_args_SYSV): Replace cif->rtype->type - with cif->flags. - (ffi_prep_cif_machdep): Add X86_WIN32 struct case. - (ffi_closure_SYSV): Add 1 or 2-bytes struct case for X86_WIN32. - * src/x86/win32.S (retstruct1b, retstruct2b, sc_retstruct1b, - sc_retstruct2b): Add for 1 or 2-bytes struct case. + iOS build fixes. -2004-03-15 Kelley Cook +commit 09b23cfc1d6d15361eee18818851fd3cacb26559 +Author: Anthony Green +Date: Fri Apr 27 08:29:48 2012 -0400 - * configure.in: Rename file to ... - * configure.ac: ... this. - * fficonfig.h.in: Regenerate. - * Makefile.in: Regenerate. - * include/Makefile.in: Regenerate. - * testsuite/Makefile.in: Regenerate. - -2004-03-12 Matt Austern - - * src/powerpc/darwin.S: Fix EH information so it corresponds to - changes in EH format resulting from addition of linkonce support. - * src/powerpc/darwin_closure.S: Likewise. - -2004-03-11 Andreas Tobler - Paolo Bonzini - - * Makefile.am (AUTOMAKE_OPTIONS): Set them. - Remove VPATH. Remove rules for object files. Remove multilib support. - (AM_CCASFLAGS): Add. - * configure.in (AC_CONFIG_HEADERS): Relace AM_CONFIG_HEADER. - (AC_PREREQ): Bump version to 2.59. - (AC_INIT): Fill with version info and bug address. - (ORIGINAL_LD_FOR_MULTILIBS): Remove. - (AM_ENABLE_MULTILIB): Use this instead of AC_ARG_ENABLE. - De-precious CC so that the right flags are passed down to multilibs. - (AC_MSG_ERROR): Replace obsolete macro AC_ERROR. - (AC_CONFIG_FILES): Replace obsolete macro AC_LINK_FILES. - (AC_OUTPUT): Reorganize the output with AC_CONFIG_COMMANDS. - * configure: Rebuilt. - * aclocal.m4: Likewise. - * Makefile.in, include/Makefile.in, testsuite/Makefile.in: Likewise. - * fficonfig.h.in: Likewise. - -2004-03-11 Andreas Schwab - - * src/ia64/ffi.c (ffi_prep_incoming_args_UNIX): Get floating point - arguments from fp registers only for the first 8 parameter slots. - Don't convert a float parameter when passed in memory. + Update README with Blackfin/uClinux support -2004-03-09 Hans-Peter Nilsson - - * configure: Regenerate for config/accross.m4 correction. - -2004-02-25 Matt Kraai - - * src/powerpc/ffi.c (ffi_prep_args_SYSV): Change - ecif->cif->bytes to bytes. - (ffi_prep_cif_machdep): Add braces around nested if statement. - -2004-02-09 Alan Modra - - * src/types.c (pointer): POWERPC64 has 8 byte pointers. - - * src/powerpc/ffi.c (ffi_prep_args64): Correct long double handling. - (ffi_closure_helper_LINUX64): Fix typo. - * testsuite/libffi.call/cls_align_longdouble.c: Pass -mlong-double-128 - for powerpc64-*-*. - * testsuite/libffi.call/float.c: Likewise. - * testsuite/libffi.call/float2.c: Likewise. - -2004-02-08 Alan Modra - - * src/powerpc/ffi.c (ffi_prep_cif_machdep ): Correct - long double function return and long double arg handling. - (ffi_closure_helper_LINUX64): Formatting. Delete unused "ng" var. - Use "end_pfr" instead of "nf". Correct long double handling. - Localise "temp". - * src/powerpc/linux64.S (ffi_call_LINUX64): Save f2 long double - return value. - * src/powerpc/linux64_closure.S (ffi_closure_LINUX64): Allocate - space for long double return value. Adjust stack frame and offsets. - Load f2 long double return. - -2004-02-07 Alan Modra - - * src/types.c: Use 16 byte long double for POWERPC64. - -2004-01-25 Eric Botcazou - - * src/sparc/ffi.c (ffi_prep_args_v9): Shift the parameter array - when the structure return address is passed in %o0. - (ffi_V9_return_struct): Rename into ffi_v9_layout_struct. - (ffi_v9_layout_struct): Align the field following a nested structure - on a word boundary. Use memmove instead of memcpy. - (ffi_call): Update call to ffi_V9_return_struct. - (ffi_prep_closure): Define 'ctx' only for V8. - (ffi_closure_sparc_inner): Clone into ffi_closure_sparc_inner_v8 - and ffi_closure_sparc_inner_v9. - (ffi_closure_sparc_inner_v8): Return long doubles by reference. - Always skip the structure return address. For structures and long - doubles, copy the argument directly. - (ffi_closure_sparc_inner_v9): Skip the structure return address only - if required. Shift the maximum floating-point slot accordingly. For - big structures, copy the argument directly; otherwise, left-justify the - argument and call ffi_v9_layout_struct to lay out the structure on - the stack. - * src/sparc/v8.S: Undef STACKFRAME before defining it. - (ffi_closure_v8): Pass the structure return address. Update call to - ffi_closure_sparc_inner_v8. Short-circuit FFI_TYPE_INT handling. - Skip the 'unimp' insn when returning long doubles and structures. - * src/sparc/v9.S: Undef STACKFRAME before defining it. - (ffi_closure_v9): Increase the frame size by 2 words. Short-circuit - FFI_TYPE_INT handling. Load structures both in integers and - floating-point registers on return. - * README: Update status of the SPARC port. - -2004-01-24 Andreas Tobler - - * testsuite/libffi.call/pyobjc-tc.c (main): Treat result value - as of type ffi_arg. - * testsuite/libffi.call/struct3.c (main): Fix CHECK. - -2004-01-22 Ulrich Weigand - - * testsuite/libffi.call/cls_uint.c (cls_ret_uint_fn): Treat result - value as of type ffi_arg, not unsigned int. - -2004-01-21 Michael Ritzert - - * ffi64.c (ffi_prep_args): Cast the RHS of an assignment instead - of the LHS. - -2004-01-12 Andreas Tobler - - * testsuite/lib/libffi-dg.exp: Set LD_LIBRARY_PATH_32 for - Solaris. - -2004-01-08 Rainer Orth - - * testsuite/libffi.call/ffitest.h (allocate_mmap): Cast MAP_FAILED - to void *. - -2003-12-10 Richard Henderson - - * testsuite/libffi.call/cls_align_pointer.c: Cast pointers to - size_t instead of int. - -2003-12-04 Hosaka Yuji - - * testsuite/libffi.call/many_win32.c: Include . - * testsuite/libffi.call/many_win32.c (main): Replace variable - int i with unsigned long ul. - - * testsuite/libffi.call/cls_align_uint64.c: New test case. - * testsuite/libffi.call/cls_align_sint64.c: Likewise. - * testsuite/libffi.call/cls_align_uint32.c: Likewise. - * testsuite/libffi.call/cls_align_sint32.c: Likewise. - * testsuite/libffi.call/cls_align_uint16.c: Likewise. - * testsuite/libffi.call/cls_align_sint16.c: Likewise. - * testsuite/libffi.call/cls_align_float.c: Likewise. - * testsuite/libffi.call/cls_align_double.c: Likewise. - * testsuite/libffi.call/cls_align_longdouble.c: Likewise. - * testsuite/libffi.call/cls_align_pointer.c: Likewise. - -2003-12-02 Hosaka Yuji - - PR other/13221 - * src/x86/ffi.c (ffi_prep_args, ffi_prep_incoming_args_SYSV): - Align arguments to 32 bits. - -2003-12-01 Andreas Tobler - - PR other/13221 - * testsuite/libffi.call/cls_multi_sshort.c: New test case. - * testsuite/libffi.call/cls_multi_sshortchar.c: Likewise. - * testsuite/libffi.call/cls_multi_uchar.c: Likewise. - * testsuite/libffi.call/cls_multi_schar.c: Likewise. - * testsuite/libffi.call/cls_multi_ushortchar.c: Likewise. - * testsuite/libffi.call/cls_multi_ushort.c: Likewise. - - * testsuite/libffi.special/unwindtest.cc: Cosmetics. - -2003-11-26 Kaveh R. Ghazi - - * testsuite/libffi.call/ffitest.h: Include . - * testsuite/libffi.special/ffitestcxx.h: Likewise. - -2003-11-22 Andreas Tobler - - * Makefile.in: Rebuilt. - * configure: Likewise. - * testsuite/libffi.special/unwindtest.cc: Convert the mmap to - the right type. - -2003-11-21 Andreas Jaeger - Andreas Tobler - - * acinclude.m4: Add AC_FUNC_MMAP_BLACKLIST. - * configure.in: Call AC_FUNC_MMAP_BLACKLIST. - * Makefile.in: Rebuilt. - * aclocal.m4: Likewise. - * configure: Likewise. - * fficonfig.h.in: Likewise. - * testsuite/lib/libffi-dg.exp: Add include dir. - * testsuite/libffi.call/ffitest.h: Add MMAP definitions. - * testsuite/libffi.special/ffitestcxx.h: Likewise. - * testsuite/libffi.call/closure_fn0.c: Use MMAP functionality - for ffi_closure if available. - * testsuite/libffi.call/closure_fn1.c: Likewise. - * testsuite/libffi.call/closure_fn2.c: Likewise. - * testsuite/libffi.call/closure_fn3.c: Likewise. - * testsuite/libffi.call/closure_fn4.c: Likewise. - * testsuite/libffi.call/closure_fn5.c: Likewise. - * testsuite/libffi.call/cls_12byte.c: Likewise. - * testsuite/libffi.call/cls_16byte.c: Likewise. - * testsuite/libffi.call/cls_18byte.c: Likewise. - * testsuite/libffi.call/cls_19byte.c: Likewise. - * testsuite/libffi.call/cls_1_1byte.c: Likewise. - * testsuite/libffi.call/cls_20byte.c: Likewise. - * testsuite/libffi.call/cls_20byte1.c: Likewise. - * testsuite/libffi.call/cls_24byte.c: Likewise. - * testsuite/libffi.call/cls_2byte.c: Likewise. - * testsuite/libffi.call/cls_3_1byte.c: Likewise. - * testsuite/libffi.call/cls_3byte1.c: Likewise. - * testsuite/libffi.call/cls_3byte2.c: Likewise. - * testsuite/libffi.call/cls_4_1byte.c: Likewise. - * testsuite/libffi.call/cls_4byte.c: Likewise. - * testsuite/libffi.call/cls_5byte.c: Likewise. - * testsuite/libffi.call/cls_64byte.c: Likewise. - * testsuite/libffi.call/cls_6byte.c: Likewise. - * testsuite/libffi.call/cls_7byte.c: Likewise. - * testsuite/libffi.call/cls_8byte.c: Likewise. - * testsuite/libffi.call/cls_9byte1.c: Likewise. - * testsuite/libffi.call/cls_9byte2.c: Likewise. - * testsuite/libffi.call/cls_double.c: Likewise. - * testsuite/libffi.call/cls_float.c: Likewise. - * testsuite/libffi.call/cls_schar.c: Likewise. - * testsuite/libffi.call/cls_sint.c: Likewise. - * testsuite/libffi.call/cls_sshort.c: Likewise. - * testsuite/libffi.call/cls_uchar.c: Likewise. - * testsuite/libffi.call/cls_uint.c: Likewise. - * testsuite/libffi.call/cls_ulonglong.c: Likewise. - * testsuite/libffi.call/cls_ushort.c: Likewise. - * testsuite/libffi.call/nested_struct.c: Likewise. - * testsuite/libffi.call/nested_struct1.c: Likewise. - * testsuite/libffi.call/nested_struct2.c: Likewise. - * testsuite/libffi.call/nested_struct3.c: Likewise. - * testsuite/libffi.call/problem1.c: Likewise. - * testsuite/libffi.special/unwindtest.cc: Likewise. - -2003-11-20 Andreas Tobler - - * testsuite/lib/libffi-dg.exp: Make the -lgcc_s conditional. - -2003-11-19 Andreas Tobler - - * testsuite/lib/libffi-dg.exp: Add DYLD_LIBRARY_PATH for darwin. - Add -lgcc_s to additional flags. - -2003-11-12 Andreas Tobler - - * configure.in, include/Makefile.am: PR libgcj/11147, install - the ffitarget.h header file in a gcc versioned and target - dependent place. - * configure: Regenerated. - * Makefile.in, include/Makefile.in: Likewise. - * testsuite/Makefile.in: Likewise. - -2003-11-09 Andreas Tobler - - * testsuite/libffi.call/closure_fn0.c: Print result and check - with dg-output to make debugging easier. - * testsuite/libffi.call/closure_fn1.c: Likewise. - * testsuite/libffi.call/closure_fn2.c: Likewise. - * testsuite/libffi.call/closure_fn3.c: Likewise. - * testsuite/libffi.call/closure_fn4.c: Likewise. - * testsuite/libffi.call/closure_fn5.c: Likewise. - * testsuite/libffi.call/cls_12byte.c: Likewise. - * testsuite/libffi.call/cls_16byte.c: Likewise. - * testsuite/libffi.call/cls_18byte.c: Likewise. - * testsuite/libffi.call/cls_19byte.c: Likewise. - * testsuite/libffi.call/cls_1_1byte.c: Likewise. - * testsuite/libffi.call/cls_20byte.c: Likewise. - * testsuite/libffi.call/cls_20byte1.c: Likewise. - * testsuite/libffi.call/cls_24byte.c: Likewise. - * testsuite/libffi.call/cls_2byte.c: Likewise. - * testsuite/libffi.call/cls_3_1byte.c: Likewise. - * testsuite/libffi.call/cls_3byte1.c: Likewise. - * testsuite/libffi.call/cls_3byte2.c: Likewise. - * testsuite/libffi.call/cls_4_1byte.c: Likewise. - * testsuite/libffi.call/cls_4byte.c: Likewise. - * testsuite/libffi.call/cls_5byte.c: Likewise. - * testsuite/libffi.call/cls_64byte.c: Likewise. - * testsuite/libffi.call/cls_6byte.c: Likewise. - * testsuite/libffi.call/cls_7byte.c: Likewise. - * testsuite/libffi.call/cls_8byte.c: Likewise. - * testsuite/libffi.call/cls_9byte1.c: Likewise. - * testsuite/libffi.call/cls_9byte2.c: Likewise. - * testsuite/libffi.call/cls_double.c: Likewise. - * testsuite/libffi.call/cls_float.c: Likewise. - * testsuite/libffi.call/cls_schar.c: Likewise. - * testsuite/libffi.call/cls_sint.c: Likewise. - * testsuite/libffi.call/cls_sshort.c: Likewise. - * testsuite/libffi.call/cls_uchar.c: Likewise. - * testsuite/libffi.call/cls_uint.c: Likewise. - * testsuite/libffi.call/cls_ulonglong.c: Likewise. - * testsuite/libffi.call/cls_ushort.c: Likewise. - * testsuite/libffi.call/problem1.c: Likewise. - - * testsuite/libffi.special/unwindtest.cc: Make ffi_closure - static. - -2003-11-08 Andreas Tobler - - * testsuite/libffi.call/cls_9byte2.c: New test case. - * testsuite/libffi.call/cls_9byte1.c: Likewise. - * testsuite/libffi.call/cls_64byte.c: Likewise. - * testsuite/libffi.call/cls_20byte1.c: Likewise. - * testsuite/libffi.call/cls_19byte.c: Likewise. - * testsuite/libffi.call/cls_18byte.c: Likewise. - * testsuite/libffi.call/closure_fn4.c: Likewise. - * testsuite/libffi.call/closure_fn5.c: Likewise. - * testsuite/libffi.call/cls_schar.c: Likewise. - * testsuite/libffi.call/cls_sint.c: Likewise. - * testsuite/libffi.call/cls_sshort.c: Likewise. - * testsuite/libffi.call/nested_struct2.c: Likewise. - * testsuite/libffi.call/nested_struct3.c: Likewise. - -2003-11-08 Andreas Tobler - - * testsuite/libffi.call/cls_double.c: Do a check on the result. - * testsuite/libffi.call/cls_uchar.c: Likewise. - * testsuite/libffi.call/cls_uint.c: Likewise. - * testsuite/libffi.call/cls_ulonglong.c: Likewise. - * testsuite/libffi.call/cls_ushort.c: Likewise. - * testsuite/libffi.call/return_sc.c: Cleanup whitespaces. - -2003-11-06 Andreas Tobler - - * src/prep_cif.c (ffi_prep_cif): Move the validity check after - the initialization. - -2003-10-23 Andreas Tobler - - * src/java_raw_api.c (ffi_java_ptrarray_to_raw): Replace - FFI_ASSERT(FALSE) with FFI_ASSERT(0). - -2003-10-22 David Daney - - * src/mips/ffitarget.h: Replace undefined UINT32 and friends with - __attribute__((__mode__(__SI__))) and friends. - -2003-10-22 Andreas Schwab - - * src/ia64/ffi.c: Replace FALSE/TRUE with false/true. - -2003-10-21 Andreas Tobler - - * configure.in: AC_LINK_FILES(ffitarget.h). - * configure: Regenerate. - * Makefile.in: Likewise. - * include/Makefile.in: Likewise. - * testsuite/Makefile.in: Likewise. - * fficonfig.h.in: Likewise. - -2003-10-21 Paolo Bonzini - Richard Henderson - - Avoid that ffi.h includes fficonfig.h. - - * Makefile.am (EXTRA_DIST): Include ffitarget.h files - (TARGET_SRC_MIPS_GCC): Renamed to TARGET_SRC_MIPS_IRIX. - (TARGET_SRC_MIPS_SGI): Removed. - (MIPS_GCC): Renamed to TARGET_SRC_MIPS_IRIX. - (MIPS_SGI): Removed. - (CLEANFILES): Removed. - (mostlyclean-am, clean-am, mostlyclean-sub, clean-sub): New - targets. - * acconfig.h: Removed. - * configure.in: Compute sizeofs only for double and long double. - Use them to define and subst HAVE_LONG_DOUBLE. Include comments - into AC_DEFINE instead of using acconfig.h. Create - include/ffitarget.h instead of include/fficonfig.h. Rename - MIPS_GCC to MIPS_IRIX, drop MIPS_SGI since we are in gcc's tree. - AC_DEFINE EH_FRAME_FLAGS. - * include/Makefile.am (DISTCLEANFILES): New automake macro. - (hack_DATA): Add ffitarget.h. - * include/ffi.h.in: Remove all system specific definitions. - Declare raw API even if it is not installed, why bother? - Use limits.h instead of SIZEOF_* to define ffi_type_*. Do - not define EH_FRAME_FLAGS, it is in fficonfig.h now. Include - ffitarget.h instead of fficonfig.h. Remove ALIGN macro. - (UINT_ARG, INT_ARG): Removed, use ffi_arg and ffi_sarg instead. - * include/ffi_common.h (bool): Do not define. - (ffi_assert): Accept failed assertion. - (ffi_type_test): Return void and accept file/line. - (FFI_ASSERT): Pass stringized failed assertion. - (FFI_ASSERT_AT): New macro. - (FFI_ASSERT_VALID_TYPE): New macro. - (UINT8, SINT8, UINT16, SINT16, UINT32, SINT32, - UINT64, SINT64): Define here with gcc's __attribute__ macro - instead of in ffi.h - (FLOAT32, ALIGN): Define here instead of in ffi.h - * include/ffi-mips.h: Removed. Its content moved to - src/mips/ffitarget.h after separating assembly and C sections. - * src/alpha/ffi.c, src/alpha/ffi.c, src/java_raw_api.c - src/prep_cif.c, src/raw_api.c, src/ia64/ffi.c, - src/mips/ffi.c, src/mips/n32.S, src/mips/o32.S, - src/mips/ffitarget.h, src/sparc/ffi.c, src/x86/ffi64.c: - SIZEOF_ARG -> FFI_SIZEOF_ARG. - * src/ia64/ffi.c: Include stdbool.h (provided by GCC 2.95+). - * src/debug.c (ffi_assert): Accept stringized failed assertion. - (ffi_type_test): Rewritten. - * src/prep-cif.c (initialize_aggregate, ffi_prep_cif): Call - FFI_ASSERT_VALID_TYPE. - * src/alpha/ffitarget.h, src/arm/ffitarget.h, - src/ia64/ffitarget.h, src/m68k/ffitarget.h, - src/mips/ffitarget.h, src/powerpc/ffitarget.h, - src/s390/ffitarget.h, src/sh/ffitarget.h, - src/sh64/ffitarget.h, src/sparc/ffitarget.h, - src/x86/ffitarget.h: New files. - * src/alpha/osf.S, src/arm/sysv.S, src/ia64/unix.S, - src/m68k/sysv.S, src/mips/n32.S, src/mips/o32.S, - src/powerpc/aix.S, src/powerpc/darwin.S, - src/powerpc/ffi_darwin.c, src/powerpc/linux64.S, - src/powerpc/linux64_closure.S, src/powerpc/ppc_closure.S, - src/powerpc/sysv.S, src/s390/sysv.S, src/sh/sysv.S, - src/sh64/sysv.S, src/sparc/v8.S, src/sparc/v9.S, - src/x86/sysv.S, src/x86/unix64.S, src/x86/win32.S: - include fficonfig.h - -2003-10-20 Rainer Orth - - * src/mips/ffi.c: Use _ABIN32, _ABIO32 instead of external - _MIPS_SIM_NABI32, _MIPS_SIM_ABI32. - -2003-10-19 Andreas Tobler - - * src/powerpc/ffi_darwin.c (ffi_prep_args): Declare bytes again. - Used when FFI_DEBUG = 1. - -2003-10-14 Alan Modra - - * src/types.c (double, longdouble): Default POWERPC64 to 8 byte size - and align. - -2003-10-06 Rainer Orth - - * include/ffi_mips.h: Define FFI_MIPS_N32 for N32/N64 ABIs, - FFI_MIPS_O32 for O32 ABI. - -2003-10-01 Andreas Tobler - - * testsuite/lib/libffi-dg.exp: Set LD_LIBRARY_PATH_64 for - SPARC64. Cleanup whitespaces. - -2003-09-19 Andreas Tobler - - * testsuite/libffi.call/closure_fn0.c: Xfail mips, arm, - strongarm, xscale. Cleanup whitespaces. - * testsuite/libffi.call/closure_fn1.c: Likewise. - * testsuite/libffi.call/closure_fn2.c: Likewise. - * testsuite/libffi.call/closure_fn3.c: Likewise. - * testsuite/libffi.call/cls_12byte.c: Likewise. - * testsuite/libffi.call/cls_16byte.c: Likewise. - * testsuite/libffi.call/cls_1_1byte.c: Likewise. - * testsuite/libffi.call/cls_20byte.c: Likewise. - * testsuite/libffi.call/cls_24byte.c: Likewise. - * testsuite/libffi.call/cls_2byte.c: Likewise. - * testsuite/libffi.call/cls_3_1byte.c: Likewise. - * testsuite/libffi.call/cls_3byte1.c: Likewise. - * testsuite/libffi.call/cls_3byte2.c: Likewise. - * testsuite/libffi.call/cls_4_1byte.c: Likewise. - * testsuite/libffi.call/cls_4byte.c: Likewise. - * testsuite/libffi.call/cls_5byte.c: Likewise. - * testsuite/libffi.call/cls_6byte.c: Likewise. - * testsuite/libffi.call/cls_7byte.c: Likewise. - * testsuite/libffi.call/cls_8byte.c: Likewise. - * testsuite/libffi.call/cls_double.c: Likewise. - * testsuite/libffi.call/cls_float.c: Likewise. - * testsuite/libffi.call/cls_uchar.c: Likewise. - * testsuite/libffi.call/cls_uint.c: Likewise. - * testsuite/libffi.call/cls_ulonglong.c: Likewise. - * testsuite/libffi.call/cls_ushort.c: Likewise. - * testsuite/libffi.call/nested_struct.c: Likewise. - * testsuite/libffi.call/nested_struct1.c: Likewise. - * testsuite/libffi.call/problem1.c: Likewise. - * testsuite/libffi.special/unwindtest.cc: Likewise. - * testsuite/libffi.call/pyobjc-tc.c: Cleanup whitespaces. - -2003-09-18 David Edelsohn - - * src/powerpc/aix.S: Cleanup whitespaces. - * src/powerpc/aix_closure.S: Likewise. - -2003-09-18 Andreas Tobler - - * src/powerpc/darwin.S: Cleanup whitespaces, comment formatting. - * src/powerpc/darwin_closure.S: Likewise. - * src/powerpc/ffi_darwin.c: Likewise. - -2003-09-18 Andreas Tobler - David Edelsohn - - * src/types.c (double): Add AIX and Darwin to the right TYPEDEF. - * src/powerpc/aix_closure.S: Remove the pointer to the outgoing - parameter stack. - * src/powerpc/darwin_closure.S: Likewise. - * src/powerpc/ffi_darwin.c (ffi_prep_args): Handle structures - according to the Darwin/AIX ABI. - (ffi_prep_cif_machdep): Likewise. - (ffi_closure_helper_DARWIN): Likewise. - Remove the outgoing parameter stack logic. Simplify the evaluation - of the different CASE types. - (ffi_prep_clousure): Avoid the casts on lvalues. Change the branch - statement in the trampoline code. - -2003-09-18 Kaz Kojima - - * src/sh/ffi.c (ffi_prep_args): Take account into the alignement - for the register size. - (ffi_closure_helper_SYSV): Handle the structure return value - address correctly. - (ffi_closure_helper_SYSV): Return the appropriate type when - the registers are used for the structure return value. - * src/sh/sysv.S (ffi_closure_SYSV): Fix the stack layout for - the 64-bit return value. Update copyright years. - -2003-09-17 Rainer Orth - - * testsuite/lib/libffi-dg.exp (libffi_target_compile): Search in - srcdir for ffi_mips.h. - -2003-09-12 Alan Modra - - * src/prep_cif.c (initialize_aggregate): Include tail padding in - structure size. - * src/powerpc/linux64_closure.S (ffi_closure_LINUX64): Correct - placement of float result. - * testsuite/libffi.special/unwindtest.cc (closure_test_fn1): Correct - cast of "resp" for big-endian 64 bit machines. - -2003-09-11 Alan Modra - - * src/types.c (double, longdouble): Merge identical SH and ARM - typedefs, and add POWERPC64. - * src/powerpc/ffi.c (ffi_prep_args64): Correct next_arg calc for - struct split over gpr and rest. - (ffi_prep_cif_machdep): Correct intarg_count for structures. - * src/powerpc/linux64.S (ffi_call_LINUX64): Fix gpr offsets. - -2003-09-09 Andreas Tobler - - * src/powerpc/ffi.c (ffi_closure_helper_SYSV) Handle struct - passing correctly. - -2003-09-09 Alan Modra - - * configure: Regenerate. - -2003-09-04 Andreas Tobler - - * Makefile.am: Remove build rules for ffitest. - * Makefile.in: Rebuilt. - -2003-09-04 Andreas Tobler - - * src/java_raw_api.c: Include to fix compiler warning - about implicit declaration of abort(). - -2003-09-04 Andreas Tobler - - * Makefile.am: Add dejagnu test framework. Fixes PR other/11411. - * Makefile.in: Rebuilt. - * configure.in: Add dejagnu test framework. - * configure: Rebuilt. - - * testsuite/Makefile.am: New file. - * testsuite/Makefile.in: Built - * testsuite/lib/libffi-dg.exp: New file. - * testsuite/config/default.exp: Likewise. - * testsuite/libffi.call/call.exp: Likewise. - * testsuite/libffi.call/ffitest.h: Likewise. - * testsuite/libffi.call/closure_fn0.c: Likewise. - * testsuite/libffi.call/closure_fn1.c: Likewise. - * testsuite/libffi.call/closure_fn2.c: Likewise. - * testsuite/libffi.call/closure_fn3.c: Likewise. - * testsuite/libffi.call/cls_1_1byte.c: Likewise. - * testsuite/libffi.call/cls_3_1byte.c: Likewise. - * testsuite/libffi.call/cls_4_1byte.c: Likewise. - * testsuite/libffi.call/cls_2byte.c: Likewise. - * testsuite/libffi.call/cls_3byte1.c: Likewise. - * testsuite/libffi.call/cls_3byte2.c: Likewise. - * testsuite/libffi.call/cls_4byte.c: Likewise. - * testsuite/libffi.call/cls_5byte.c: Likewise. - * testsuite/libffi.call/cls_6byte.c: Likewise. - * testsuite/libffi.call/cls_7byte.c: Likewise. - * testsuite/libffi.call/cls_8byte.c: Likewise. - * testsuite/libffi.call/cls_12byte.c: Likewise. - * testsuite/libffi.call/cls_16byte.c: Likewise. - * testsuite/libffi.call/cls_20byte.c: Likewise. - * testsuite/libffi.call/cls_24byte.c: Likewise. - * testsuite/libffi.call/cls_double.c: Likewise. - * testsuite/libffi.call/cls_float.c: Likewise. - * testsuite/libffi.call/cls_uchar.c: Likewise. - * testsuite/libffi.call/cls_uint.c: Likewise. - * testsuite/libffi.call/cls_ulonglong.c: Likewise. - * testsuite/libffi.call/cls_ushort.c: Likewise. - * testsuite/libffi.call/float.c: Likewise. - * testsuite/libffi.call/float1.c: Likewise. - * testsuite/libffi.call/float2.c: Likewise. - * testsuite/libffi.call/many.c: Likewise. - * testsuite/libffi.call/many_win32.c: Likewise. - * testsuite/libffi.call/nested_struct.c: Likewise. - * testsuite/libffi.call/nested_struct1.c: Likewise. - * testsuite/libffi.call/pyobjc-tc.c: Likewise. - * testsuite/libffi.call/problem1.c: Likewise. - * testsuite/libffi.call/promotion.c: Likewise. - * testsuite/libffi.call/return_ll.c: Likewise. - * testsuite/libffi.call/return_sc.c: Likewise. - * testsuite/libffi.call/return_uc.c: Likewise. - * testsuite/libffi.call/strlen.c: Likewise. - * testsuite/libffi.call/strlen_win32.c: Likewise. - * testsuite/libffi.call/struct1.c: Likewise. - * testsuite/libffi.call/struct2.c: Likewise. - * testsuite/libffi.call/struct3.c: Likewise. - * testsuite/libffi.call/struct4.c: Likewise. - * testsuite/libffi.call/struct5.c: Likewise. - * testsuite/libffi.call/struct6.c: Likewise. - * testsuite/libffi.call/struct7.c: Likewise. - * testsuite/libffi.call/struct8.c: Likewise. - * testsuite/libffi.call/struct9.c: Likewise. - * testsuite/libffi.special/special.exp: New file. - * testsuite/libffi.special/ffitestcxx.h: Likewise. - * testsuite/libffi.special/unwindtest.cc: Likewise. - - -2003-08-13 Kaz Kojima - - * src/sh/ffi.c (OFS_INT16): Set 0 for little endian case. Update - copyright years. - -2003-08-02 Alan Modra - - * src/powerpc/ffi.c (ffi_prep_args64): Modify for changed gcc - structure passing. - (ffi_closure_helper_LINUX64): Likewise. - * src/powerpc/linux64.S: Remove code writing to parm save area. - * src/powerpc/linux64_closure.S (ffi_closure_LINUX64): Use return - address in lr from ffi_closure_helper_LINUX64 call to calculate - table address. Optimize function tail. - -2003-07-28 Andreas Tobler - - * src/sparc/ffi.c: Handle all floating point registers. - * src/sparc/v9.S: Likewise. Fixes second part of PR target/11410. - -2003-07-11 Gerald Pfeifer - - * README: Note that libffi is not part of GCC. Update the project - URL and status. - -2003-06-19 Franz Sirl - - * src/powerpc/ppc_closure.S: Include ffi.h. - -2003-06-13 Rainer Orth - - * src/x86/sysv.S: Avoid gas-only .uleb128/.sleb128 directives. - Use C style comments. - -2003-06-13 Kaz Kojima - - * Makefile.am: Add SHmedia support. Fix a typo of SH support. - * Makefile.in: Regenerate. - * configure.in (sh64-*-linux*, sh5*-*-linux*): Add target. - * configure: Regenerate. - * include/ffi.h.in: Add SHmedia support. - * src/sh64/ffi.c: New file. - * src/sh64/sysv.S: New file. - -2003-05-16 Jakub Jelinek - - * configure.in (HAVE_RO_EH_FRAME): Check whether .eh_frame section - should be read-only. - * configure: Rebuilt. - * fficonfig.h.in: Rebuilt. - * include/ffi.h.in (EH_FRAME_FLAGS): Define. - * src/alpha/osf.S: Use EH_FRAME_FLAGS. - * src/powerpc/linux64.S: Likewise. - * src/powerpc/linux64_closure.S: Likewise. Include ffi.h. - * src/powerpc/sysv.S: Use EH_FRAME_FLAGS. Use pcrel encoding - if -fpic/-fPIC/-mrelocatable. - * src/powerpc/powerpc_closure.S: Likewise. - * src/sparc/v8.S: If HAVE_RO_EH_FRAME is defined, don't include - #write in .eh_frame flags. - * src/sparc/v9.S: Likewise. - * src/x86/unix64.S: Use EH_FRAME_FLAGS. - * src/x86/sysv.S: Likewise. Use pcrel encoding if -fpic/-fPIC. - * src/s390/sysv.S: Use EH_FRAME_FLAGS. Include ffi.h. - -2003-05-07 Jeff Sturm - - Fixes PR bootstrap/10656 - * configure.in (HAVE_AS_REGISTER_PSEUDO_OP): Test assembler - support for .register pseudo-op. - * src/sparc/v8.S: Use it. - * fficonfig.h.in: Rebuilt. - * configure: Rebuilt. - -2003-04-18 Jakub Jelinek - - * include/ffi.h.in (POWERPC64): Define if 64-bit. - (enum ffi_abi): Add FFI_LINUX64 on POWERPC. - Make it the default on POWERPC64. - (FFI_TRAMPOLINE_SIZE): Define to 24 on POWERPC64. - * configure.in: Change powerpc-*-linux* into powerpc*-*-linux*. - * configure: Rebuilt. - * src/powerpc/ffi.c (hidden): Define. - (ffi_prep_args_SYSV): Renamed from - ffi_prep_args. Cast pointers to unsigned long to shut up warnings. - (NUM_GPR_ARG_REGISTERS64, NUM_FPR_ARG_REGISTERS64, - ASM_NEEDS_REGISTERS64): New. - (ffi_prep_args64): New function. - (ffi_prep_cif_machdep): Handle FFI_LINUX64 ABI. - (ffi_call): Likewise. - (ffi_prep_closure): Likewise. - (flush_icache): Surround by #ifndef POWERPC64. - (ffi_dblfl): New union type. - (ffi_closure_helper_SYSV): Use it to avoid aliasing problems. - (ffi_closure_helper_LINUX64): New function. - * src/powerpc/ppc_closure.S: Surround whole file by #ifndef - __powerpc64__. - * src/powerpc/sysv.S: Likewise. - (ffi_call_SYSV): Rename ffi_prep_args to ffi_prep_args_SYSV. - * src/powerpc/linux64.S: New file. - * src/powerpc/linux64_closure.S: New file. - * Makefile.am (EXTRA_DIST): Add src/powerpc/linux64.S and - src/powerpc/linux64_closure.S. - (TARGET_SRC_POWERPC): Likewise. +commit 213ed15c70e72d666154c08e2b41dae3f61f20d3 +Author: Anthony Green +Date: Fri Apr 27 01:34:15 2012 -0400 - * src/ffitest.c (closure_test_fn, closure_test_fn1, closure_test_fn2, - closure_test_fn3): Fix result printing on big-endian 64-bit - machines. - (main): Print tst2_arg instead of uninitialized tst2_result. + Add blackfin supprt from Alexandre Keunecke. - * src/ffitest.c (main): Hide what closure pointer really points to - from the compiler. +commit ff3d76fd427382ce7d2b2ed54acdd0bce470ca4f +Author: Anthony Green +Date: Wed Apr 11 23:16:48 2012 -0400 -2003-04-16 Richard Earnshaw + 3.0.11 - * configure.in (arm-*-netbsdelf*): Add configuration. - (configure): Regenerated. +commit 7e0a412c4fd9cbe77b467a9bf86f56aea62632c3 +Author: Anthony Green +Date: Wed Apr 11 22:47:44 2012 -0400 -2003-04-04 Loren J. Rittle + Update files to ship - * include/Makefile.in: Regenerate. +commit 39e6a5860416f7bad992149817e1da1ba7c460d4 +Author: Zachary Waldowski +Date: Wed Apr 11 22:39:46 2012 -0400 -2003-03-21 Zdenek Dvorak + More mac/ios build improvements - * libffi/include/ffi.h.in: Define X86 instead of X86_64 in 32 - bit mode. - * libffi/src/x86/ffi.c (ffi_closure_SYSV, ffi_closure_raw_SYSV): - Receive closure pointer through parameter, read args using - __builtin_dwarf_cfa. - (FFI_INIT_TRAMPOLINE): Send closure reference through eax. +commit 853cc722a16f8d1254573ef3bb73c7b8f3d8a110 +Author: Anthony Green +Date: Tue Apr 10 06:33:33 2012 -0400 -2003-03-12 Andreas Schwab + Fix typo for darwin targets - * configure.in: Avoid trailing /. in toolexeclibdir. - * configure: Rebuilt. +commit 3f5023068cda07a3dd6dacbaa875a5b5fc96d4bb +Author: Anthony Green +Date: Fri Apr 6 20:34:51 2012 -0400 -2003-03-03 Andreas Tobler + mend - * src/powerpc/darwin_closure.S: Recode to fit dynamic libraries. +commit ebb8e8945681ce0af7a5c47a980287e8ece84b84 +Author: Mike Lewis +Date: Fri Apr 6 20:02:08 2012 -0400 -2003-02-06 Andreas Tobler + Build iOS library with xcode - * libffi/src/powerpc/darwin_closure.S: - Fix alignement bug, allocate 8 bytes for the result. - * libffi/src/powerpc/aix_closure.S: - Likewise. - * libffi/src/powerpc/ffi_darwin.c: - Update stackframe description for aix/darwin_closure.S. +commit a098b44f4c592c2192fcdef4fad6108eb3f4301c +Author: Anthony Green +Date: Fri Apr 6 17:04:35 2012 -0400 -2003-02-06 Jakub Jelinek + Reapply missing testsuite changes for arm - * src/s390/ffi.c (ffi_closure_helper_SYSV): Add hidden visibility - attribute. +commit 10d1e51393f08c14045db85843208f44f9f1e9ba +Author: Anthony Green +Date: Fri Apr 6 11:57:14 2012 -0400 -2003-01-31 Christian Cornelssen , - Andreas Schwab + Update to rc4. Upgrade autoconf version. - * configure.in: Adjust command to source config-ml.in to account - for changes to the libffi_basedir definition. - (libffi_basedir): Remove ${srcdir} from value and include trailing - slash if nonempty. +commit 9bcc884276dc0a807b2605e510b11b1740dd9aa2 +Author: Anthony Green +Date: Fri Apr 6 11:53:07 2012 -0400 - * configure: Regenerate. + Fix Linux/x32 reference in README -2003-01-29 Franz Sirl +commit a044a56b1cd2a0924f5ec0d6b5a5089d14fcd1a1 +Author: Anthony Green +Date: Fri Apr 6 10:39:10 2012 -0400 - * src/powerpc/ppc_closure.S: Recode to fit shared libs. + Linux/x32 libtool fix -2003-01-28 Andrew Haley +commit 59bb61a36661b972e8443531d3b7bc736e131a4b +Author: Anthony Green +Date: Fri Apr 6 08:26:14 2012 -0400 - * include/ffi.h.in: Enable FFI_CLOSURES for x86_64. - * src/x86/ffi64.c (ffi_prep_closure): New. - (ffi_closure_UNIX64_inner): New. - * src/x86/unix64.S (ffi_closure_UNIX64): New. + Update libtool version, README, tests dists -2003-01-27 Alexandre Oliva +commit f2981454cbe25cf9411b710f46c5f5552003a123 +Author: Anthony Green +Date: Thu Apr 5 15:45:19 2012 -0400 - * configure.in (toolexecdir, toolexeclibdir): Set and AC_SUBST. - Remove USE_LIBDIR conditional. - * Makefile.am (toolexecdir, toolexeclibdir): Don't override. - * Makefile.in, configure: Rebuilt. + Revert debug code changes -2003-01027 David Edelsohn +commit 39dccddb606f6fdb8dcb177d416e884041da6e30 +Author: Zachary Waldowski +Date: Thu Apr 5 12:32:41 2012 -0400 - * Makefile.am (TARGET_SRC_POWERPC_AIX): Fix typo. - * Makefile.in: Regenerate. + Fix building with Clang for Darwin (OS X 10.6+ and iOS + 4.0+) -2003-01-22 Andrew Haley +commit 3afaa9a34a81a305227ae8cf4f12b9d0484d055e +Author: Peter Rosin +Date: Tue Apr 3 07:40:31 2012 -0400 - * src/powerpc/darwin.S (_ffi_call_AIX): Add Augmentation size to - unwind info. + Fix return_uc.c test case on windows. -2003-01-21 Andreas Tobler +commit 65f40c35a2873d8328359ec4512bd0736dbe32c7 +Author: Anthony Green +Date: Tue Apr 3 07:35:59 2012 -0400 - * src/powerpc/darwin.S: Add unwind info. - * src/powerpc/darwin_closure.S: Likewise. + Repair ppc build regression. -2003-01-14 Andrew Haley +commit 0a1ab12a8d15caa894116a82249551f23ef65612 +Author: Peter Rosin +Date: Fri Mar 30 08:14:08 2012 -0400 - * src/x86/ffi64.c (ffi_prep_args): Check for void retval. - (ffi_prep_cif_machdep): Likewise. - * src/x86/unix64.S: Add unwind info. + Various MSVC-related changes. -2003-01-14 Andreas Jaeger +commit e1539266e6c6dde3c99832323586f33f977d1dc0 +Author: Anthony Green +Date: Fri Mar 30 00:40:18 2012 -0400 - * src/ffitest.c (main): Only use ffi_closures if those are - supported. + ARM VFP fix for old toolchains -2003-01-13 Andreas Tobler +commit 7c5e60b5f47d725036a72162f136272bc407e3a1 +Author: Anthony Green +Date: Thu Mar 29 08:48:22 2012 -0400 - * libffi/src/ffitest.c - add closure testcases + Rebase on fixed GCC sources -2003-01-13 Kevin B. Hendricks +commit e72ed5eeaa9cfb0fdc86f6b3422734177b659f96 +Author: Anthony Green +Date: Wed Mar 21 09:52:28 2012 -0400 - * libffi/src/powerpc/ffi.c - fix alignment bug for float (4 byte aligned iso 8 byte) + Fix vararg float test -2003-01-09 Geoffrey Keating +commit bd78c9c3311244dd5f877c915b0dff91621dd253 +Author: Anthony Green +Date: Wed Mar 21 08:09:30 2012 -0400 - * src/powerpc/ffi_darwin.c: Remove RCS version string. - * src/powerpc/darwin.S: Remove RCS version string. + More cygwin fixes -2003-01-03 Jeff Sturm +commit 84d3253f86dad6b4f261231935675d35fd964b05 +Author: Anthony Green +Date: Mon Mar 19 23:07:35 2012 -0400 - * include/ffi.h.in: Add closure defines for SPARC, SPARC64. - * src/ffitest.c (main): Use static storage for closure. - * src/sparc/ffi.c (ffi_prep_closure, ffi_closure_sparc_inner): New. - * src/sparc/v8.S (ffi_closure_v8): New. - * src/sparc/v9.S (ffi_closure_v9): New. + Rebase post GCC merge -2002-11-10 Ranjit Mathew +commit 964c5b93f80dcaacf73056b7d15a4d2b4b7a217c +Author: Anthony Green +Date: Sat Mar 3 14:46:20 2012 -0500 - * include/ffi.h.in: Added FFI_STDCALL ffi_type - enumeration for X86_WIN32. - * src/x86/win32.S: Added ffi_call_STDCALL function - definition. - * src/x86/ffi.c (ffi_call/ffi_raw_call): Added - switch cases for recognising FFI_STDCALL and - calling ffi_call_STDCALL if target is X86_WIN32. - * src/ffitest.c (my_stdcall_strlen/stdcall_many): - stdcall versions of the "my_strlen" and "many" - test functions (for X86_WIN32). - Added test cases to test stdcall invocation using - these functions. + abi check fixes and Linux/x32 support -2002-12-02 Kaz Kojima +commit 6c194233a5f6f1d274669afc5924a9e1f69d4876 +Author: Anthony Green +Date: Sat Mar 3 14:17:54 2012 -0500 - * src/sh/sysv.S: Add DWARF2 unwind info. + Add -no-undefined for both 32- and 64-bit x86 + windows-like hosts. -2002-11-27 Ulrich Weigand +commit 8360bf1cd0aba8db5582266da70467de7e89a57a +Author: Anthony Green +Date: Thu Feb 23 07:01:13 2012 -0500 - * src/s390/sysv.S (.eh_frame section): Make section read-only. + Ensure that users don't include ffitarget.h directly -2002-11-26 Jim Wilson +commit d578b89619cf3d2baff027b203619dc307fc12e3 +Author: Anthony Green +Date: Wed Feb 15 00:18:18 2012 -0500 - * src/types.c (FFI_TYPE_POINTER): Has size 8 on IA64. + Fix ABI check regression -2002-11-23 H.J. Lu +commit dee20f8e45c486f5018f31e09bb362992aa498c3 +Author: Anthony Green +Date: Fri Feb 10 13:06:46 2012 -0500 - * acinclude.m4: Add dummy AM_PROG_LIBTOOL. - Include ../config/accross.m4. - * aclocal.m4; Rebuild. - * configure: Likewise. + Rebased from gcc -2002-11-15 Ulrich Weigand +commit 4130e1972d001143e5e9f3c6b65f2a6f9524169e +Author: Anthony Green +Date: Fri Feb 3 13:18:27 2012 -0600 - * src/s390/sysv.S (.eh_frame section): Adapt to pcrel FDE encoding. + Refresh autoconf-archive m4 scripts -2002-11-11 DJ Delorie +commit 1ff9c604bb214b5a305064af1049577ef783730a +Author: Anthony Green +Date: Wed Feb 1 16:34:30 2012 -0600 - * configure.in: Look for common files in the right place. + Rebase from GCC -2002-10-08 Ulrich Weigand +commit 211060eb8f714af0e935430efa6bb45e8e3ffc5d +Author: Anthony Green +Date: Mon Jan 23 14:24:01 2012 -0500 - * src/java_raw_api.c (ffi_java_raw_to_ptrarray): Interpret - raw data as _Jv_word values, not ffi_raw. - (ffi_java_ptrarray_to_raw): Likewise. - (ffi_java_rvalue_to_raw): New function. - (ffi_java_raw_call): Call it. - (ffi_java_raw_to_rvalue): New function. - (ffi_java_translate_args): Call it. - * src/ffitest.c (closure_test_fn): Interpret return value - as ffi_arg, not int. - * src/s390/ffi.c (ffi_prep_cif_machdep): Add missing - FFI_TYPE_POINTER case. - (ffi_closure_helper_SYSV): Likewise. Also, assume return - values extended to word size. + Alpha fix -2002-10-02 Andreas Jaeger +commit 78d9c638ba0de6edfbc603fd65d19c6562663248 +Author: Anthony Green +Date: Mon Jan 23 14:17:24 2012 -0500 - * src/x86/ffi64.c (ffi_prep_cif_machdep): Remove debug output. + mend -2002-10-01 Bo Thorsen +commit afaf3381604bd81803d8a5f3bf4d462299f1aac3 +Author: Anthony Green +Date: Mon Jan 23 14:17:13 2012 -0500 - * include/ffi.h.in: Fix i386 win32 compilation. + mend -2002-09-30 Ulrich Weigand +commit 9e9c4aeb77de5608d602109f22100c1c0c79faad +Author: Anthony Green +Date: Mon Jan 23 14:11:23 2012 -0500 - * configure.in: Add s390x-*-linux-* target. - * configure: Regenerate. - * include/ffi.h.in: Define S390X for s390x targets. - (FFI_CLOSURES): Define for s390/s390x. - (FFI_TRAMPOLINE_SIZE): Likewise. - (FFI_NATIVE_RAW_API): Likewise. - * src/prep_cif.c (ffi_prep_cif): Do not compute stack space for s390. - * src/types.c (FFI_TYPE_POINTER): Use 8-byte pointers on s390x. - * src/s390/ffi.c: Major rework of existing code. Add support for - s390x targets. Add closure support. - * src/s390/sysv.S: Likewise. + Add Amiga support -2002-09-29 Richard Earnshaw +commit 8efc0b1f4027d5a3cbf205e55d422d94e60f3226 +Author: Anthony Green +Date: Mon Jan 23 13:47:38 2012 -0500 - * src/arm/sysv.S: Fix typo. + Unlikely fixes -2002-09-28 Richard Earnshaw +commit 1df51398ae183dc208ba4599ee867278b04d13d3 +Author: Anthony Green +Date: Mon Jan 23 13:43:59 2012 -0500 - * src/arm/sysv.S: If we don't have machine/asm.h and the pre-processor - has defined __USER_LABEL_PREFIX__, then use it in CNAME. - (ffi_call_SYSV): Handle soft-float. + mend -2002-09-27 Bo Thorsen +commit cd2277cc796b96b149cd284ae85326529fe7fb9c +Author: Anthony Green +Date: Mon Jan 23 13:43:38 2012 -0500 - * include/ffi.h.in: Fix multilib x86-64 support. + mend -2002-09-22 Kaveh R. Ghazi +commit 164e6fe04b189746c8bd5810c6e3e919770bb9d4 +Author: Anthony Green +Date: Mon Jan 23 12:41:06 2012 -0500 - * Makefile.am (all-multi): Fix multilib parallel build. + m68k fixes -2002-07-19 Kaz Kojima +commit c365ee7577bef00cb3c2c0b5224147aea04138d8 +Author: Anthony Green +Date: Mon Jan 23 11:13:18 2012 -0500 - * configure.in (sh[34]*-*-linux*): Add brackets. - * configure: Regenerate. + Refresh -2002-07-18 Kaz Kojima +commit f22c38bbd93bcc0c04bf26c3e414556b3177c385 +Author: Anthony Green +Date: Fri Nov 18 15:13:41 2011 -0500 - * Makefile.am: Add SH support. - * Makefile.in: Regenerate. - * configure.in (sh-*-linux*, sh[34]*-*-linux*): Add target. - * configure: Regenerate. - * include/ffi.h.in: Add SH support. - * src/sh/ffi.c: New file. - * src/sh/sysv.S: New file. - * src/types.c: Add SH support. + Update variadic patch -2002-07-16 Bo Thorsen +commit 03e9ee321a3c208f88d2432587ce40b2bb2430ba +Author: Anthony Green +Date: Fri Nov 18 15:13:00 2011 -0500 - * src/x86/ffi64.c: New file that adds x86-64 support. - * src/x86/unix64.S: New file that handles argument setup for - x86-64. - * src/x86/sysv.S: Don't use this on x86-64. - * src/x86/ffi.c: Don't use this on x86-64. - Remove unused vars. - * src/prep_cif.c (ffi_prep_cif): Don't do stack size calculation - for x86-64. - * src/ffitest.c (struct6): New test that tests a special case in - the x86-64 ABI. - (struct7): Likewise. - (struct8): Likewise. - (struct9): Likewise. - (closure_test_fn): Silence warning about this when it's not used. - (main): Add the new tests. - (main): Fix a couple of wrong casts and silence some compiler warnings. - * include/ffi.h.in: Add x86-64 ABI definition. - * fficonfig.h.in: Regenerate. - * Makefile.am: Add x86-64 support. - * configure.in: Likewise. - * Makefile.in: Regenerate. - * configure: Likewise. + Fix cls_double_va.c and update docs -2002-06-24 Bo Thorsen +commit 95f31151ec792809cfb80d385350f9f56d95aa25 +Author: Anthony Green +Date: Sat Nov 12 23:46:05 2011 -0500 - * src/types.c: Merge settings for similar architectures. - Add x86-64 sizes and alignments. + Rerun automake -2002-06-23 Bo Thorsen +commit 198ed1ef85cf18342627f8d44bc3f12c9975a49d +Author: Anthony Green +Date: Sat Nov 12 23:45:20 2011 -0500 - * src/arm/ffi.c (ffi_prep_args): Remove unused vars. - * src/sparc/ffi.c (ffi_prep_args_v8): Likewise. - * src/mips/ffi.c (ffi_prep_args): Likewise. - * src/m68k/ffi.c (ffi_prep_args): Likewise. + Update version number -2002-07-18 H.J. Lu (hjl@gnu.org) +commit 4f17e1f142e805b13959ba2594ee735eae439f4e +Author: Anthony Green +Date: Sat Nov 12 17:22:24 2011 -0500 - * Makefile.am (TARGET_SRC_MIPS_LINUX): New. - (libffi_la_SOURCES): Support MIPS_LINUX. - (libffi_convenience_la_SOURCES): Likewise. - * Makefile.in: Regenerated. + Fix last patch - * configure.in (mips64*-*): Skip. - (mips*-*-linux*): New. - * configure: Regenerated. +commit ff9454da44859716a5bd4eaa344499288c79694f +Author: Anthony Green +Date: Sat Nov 12 17:18:51 2011 -0500 - * src/mips/ffi.c: Include . + Add David Gilbert's variadic function call support -2002-06-06 Ulrich Weigand +commit ea14ae85e8f54ff046b7fb8a9cfe349475272044 +Author: Anthony Green +Date: Sat Nov 12 16:36:59 2011 -0500 - * src/s390/sysv.S: Save/restore %r6. Add DWARF-2 unwind info. + clean up -2002-05-27 Roger Sayle +commit 52891f8a93f9b8de801cca4cf05639422dc9773e +Author: Anthony Green +Date: Sat Nov 12 16:35:55 2011 -0500 - * src/x86/ffi.c (ffi_prep_args): Remove reference to avn. + Add powerpc soft float support -2002-05-27 Bo Thorsen +commit c8f1bde8e2566c5a87474b4d08aa934d6d28ee75 +Author: Anthony Green +Date: Sat Nov 12 16:21:02 2011 -0500 - * src/x86/ffi.c (ffi_prep_args): Remove unused variable and - fix formatting. + Remove junk file -2002-05-13 Andreas Tobler +commit 6a6e7f862f3cc677e19131587caa619e7f9c7ffd +Author: Anthony Green +Date: Sat Nov 12 16:20:42 2011 -0500 - * src/powerpc/ffi_darwin.c (ffi_prep_closure): Declare fd at - beginning of function (for older apple cc). + Fix kfreebsd -2002-05-08 Alexandre Oliva +commit d52fbed05ccbdee9ed8b9c911cbb4f85b0ff0f2a +Author: Anthony Green +Date: Sat Nov 12 16:13:41 2011 -0500 - * configure.in (ORIGINAL_LD_FOR_MULTILIBS): Preserve LD at - script entry, and set LD to it when configuring multilibs. - * configure: Rebuilt. + Add missing ChangeLog entry -2002-05-05 Jason Thorpe +commit 322052ce65c4fdac85bedc24726fd0e0094ba521 +Author: Anthony Green +Date: Sat Nov 12 16:11:49 2011 -0500 - * configure.in (sparc64-*-netbsd*): Add target. - (sparc-*-netbsdelf*): Likewise. - * configure: Regenerate. + Fix arm wince alignment issue -2002-04-28 David S. Miller +commit af18df2bc2f52df81e7b5c619bd86db8489dc873 +Author: Anthony Green +Date: Sat Nov 12 15:52:08 2011 -0500 - * configure.in, configure: Fix SPARC test in previous change. + Remove use of ppc string instructions -2002-04-29 Gerhard Tonn +commit 236c9391321f83ad40daf03f40c35c9ebc1da6b3 +Author: Anthony Green +Date: Sat Nov 12 07:37:40 2011 -0500 - * Makefile.am: Add Linux for S/390 support. - * Makefile.in: Regenerate. - * configure.in: Add Linux for S/390 support. - * configure: Regenerate. - * include/ffi.h.in: Add Linux for S/390 support. - * src/s390/ffi.c: New file from libffi CVS tree. - * src/s390/sysv.S: New file from libffi CVS tree. + Fix darwin11 build problem -2002-04-28 Jakub Jelinek +commit c411f140f305ebb00d33c92b7cb2742bcd241b6a +Author: Anthony Green +Date: Sat Nov 12 07:32:36 2011 -0500 - * configure.in (HAVE_AS_SPARC_UA_PCREL): Check for working - %r_disp32(). - * src/sparc/v8.S: Use it. - * src/sparc/v9.S: Likewise. - * fficonfig.h.in: Rebuilt. - * configure: Rebuilt. + Fix ax_enable_builddir macro on BSD systems -2002-04-08 Hans Boehm +commit 3d56106b07735abef6ae9f032e94f560a0ed2f30 +Author: Anthony Green +Date: Sat Nov 12 07:20:24 2011 -0500 - * src/java_raw_api.c (ffi_java_raw_size): Handle FFI_TYPE_DOUBLE - correctly. - * src/ia64/unix.S: Add unwind information. Fix comments. - Save sp in a way that's compatible with unwind info. - (ffi_call_unix): Correctly restore sp in all cases. - * src/ia64/ffi.c: Add, fix comments. + Rebase -2002-04-08 Jakub Jelinek +commit 8c01954c50bf8ef2e00a3db166060a1b8f83a20d +Author: Anthony Green +Date: Tue Sep 6 14:26:32 2011 -0400 - * src/sparc/v8.S: Make .eh_frame dependent on target word size. + Build assembly files with debug info -2002-04-06 Jason Thorpe +commit fed646a2078969f4ce89c29107f1e72e03f4a977 +Author: Anthony Green +Date: Tue Sep 6 09:50:20 2011 -0400 - * configure.in (alpha*-*-netbsd*): Add target. - * configure: Regenerate. + Regenerate configury with missing m4 macros -2002-04-04 Jeff Sturm +commit d76441cf71216f8f1e62e7ec852a7f4e21371ec8 +Author: Anthony Green +Date: Wed Aug 24 10:14:23 2011 -0400 - * src/sparc/v8.S: Add unwind info. - * src/sparc/v9.S: Likewise. + Update list of supported OpenBSD systems -2002-03-30 Krister Walfridsson +commit ee6696fdf4768ba6dd037fb6dd99435afa13816e +Author: Anthony Green +Date: Tue Aug 23 12:30:29 2011 -0400 - * configure.in: Enable i*86-*-netbsdelf*. - * configure: Rebuilt. + 3.0.11-rc1. soname bump. -2002-03-29 David Billinghurst +commit c6265c36a91eab8175d0e72db84d8225418f2379 +Author: Anthony Green +Date: Tue Aug 23 10:31:33 2011 -0400 - PR other/2620 - * src/mips/n32.s: Delete - * src/mips/o32.s: Delete + Version 3.0.10 -2002-03-21 Loren J. Rittle +commit cc5e41bf32d18a14dbdd653d52eacdbdc934c392 +Author: Anthony Green +Date: Mon Aug 22 16:34:24 2011 -0400 - * configure.in: Enable alpha*-*-freebsd*. - * configure: Rebuilt. + Fix use of autoconf macros -2002-03-17 Bryce McKinlay +commit 049d8386ff52399e69a530b55b9feedc8a2589d2 +Author: Anthony Green +Date: Mon Aug 22 14:50:10 2011 -0400 - * Makefile.am: libfficonvenience -> libffi_convenience. - * Makefile.in: Rebuilt. + Many new patches - * Makefile.am: Define ffitest_OBJECTS. - * Makefile.in: Rebuilt. +commit 3b7efa4e74f0dcebf70b447391987aedd3473306 +Author: Anthony Green +Date: Mon Aug 15 13:25:13 2011 -0400 -2002-03-07 Andreas Tobler - David Edelsohn + Revert remove-debug-code patch temporarily (for ARM Fedora release) - * Makefile.am (EXTRA_DIST): Add Darwin and AIX closure files. - (TARGET_SRC_POWERPC_AIX): Add aix_closure.S. - (TARGET_SRC_POWERPC_DARWIN): Add darwin_closure.S. - * Makefile.in: Regenerate. - * include/ffi.h.in: Add AIX and Darwin closure definitions. - * src/powerpc/ffi_darwin.c (ffi_prep_closure): New function. - (flush_icache, flush_range): New functions. - (ffi_closure_helper_DARWIN): New function. - * src/powerpc/aix_closure.S: New file. - * src/powerpc/darwin_closure.S: New file. +commit d992ac54a2a9e7e064ffebcb91e05e7cb86185c7 +Author: Anthony Green +Date: Fri Jul 29 17:32:53 2011 -0400 -2002-02-24 Jeff Sturm + Refresh from GCC - * include/ffi.h.in: Add typedef for ffi_arg. - * src/ffitest.c (main): Declare rint with ffi_arg. +commit 2d3fb36420e09304220ee6c0652bae5eccdb965d +Author: Anthony Green +Date: Wed Mar 30 16:54:42 2011 -0400 -2002-02-21 Andreas Tobler + Fix darwin EH - * src/powerpc/ffi_darwin.c (ffi_prep_args): Skip appropriate - number of GPRs for floating-point arguments. +commit 30ff28e1d8cd9ed5319f1fbe9c7cccacc8161fb3 +Author: Anthony Green +Date: Mon Feb 28 15:36:23 2011 -0500 -2002-01-31 Anthony Green + Fix permissions - * configure: Rebuilt. - * configure.in: Replace CHECK_SIZEOF and endian tests with - cross-compiler friendly macros. - * aclocal.m4 (AC_COMPILE_CHECK_SIZEOF, AC_C_BIGENDIAN_CROSS): New - macros. +commit 09f8f310f4f53a24289682d3d28f4399d7bafc3b +Author: Anthony Green +Date: Mon Feb 28 15:36:07 2011 -0500 -2002-01-18 David Edelsohn + More AIX fixes. rc9. - * src/powerpc/darwin.S (_ffi_call_AIX): New. - * src/powerpc/aix.S (ffi_call_DARWIN): New. +commit 53d7b165642c220aa5166ba350b490802f359b54 +Merge: 18dd85d 3000dc2 +Author: Anthony Green +Date: Mon Feb 28 15:23:31 2011 -0500 -2002-01-17 David Edelsohn + Merge branch 'master' of https://github.com/landonf/libffi-ios - * Makefile.am (EXTRA_DIST): Add Darwin and AIX files. - (TARGET_SRC_POWERPC_AIX): New. - (POWERPC_AIX): New stanza. - * Makefile.in: Regenerate. - * configure.in: Add AIX case. - * configure: Regenerate. - * include/ffi.h.in (ffi_abi): Add FFI_AIX. - * src/powerpc/ffi_darwin.c (ffi_status): Use "long" to scale frame - size. Fix "long double" support. - (ffi_call): Add FFI_AIX case. - * src/powerpc/aix.S: New. +commit 18dd85d6cb9f3f3eea2a3b70eb4e150045905c55 +Author: Anthony Green +Date: Fri Feb 25 16:23:04 2011 -0500 -2001-10-09 John Hornkvist + rc8. fix last patch. - Implement Darwin PowerPC ABI. - * configure.in: Handle powerpc-*-darwin*. - * Makefile.am: Set source files for POWERPC_DARWIN. - * configure: Rebuilt. - * Makefile.in: Rebuilt. - * include/ffi.h.in: Define FFI_DARWIN and FFI_DEFAULT_ABI for - POWERPC_DARWIN. - * src/powerpc/darwin.S: New file. - * src/powerpc/ffi_darwin.c: New file. +commit 74ee6ea8b42e60d44a3ae8938b1e42a38c1e66b4 +Author: Anthony Green +Date: Fri Feb 25 15:52:14 2011 -0500 -2001-10-07 Joseph S. Myers + rc7. More AIX fixes. - * src/x86/ffi.c: Fix spelling error of "separate" as "seperate". +commit 2541679dbd3db0014890f42192dbf8008ab923fa +Author: Anthony Green +Date: Fri Feb 25 15:09:13 2011 -0500 -2001-07-16 Rainer Orth + Fix ppc32 bug - * src/x86/sysv.S: Avoid gas-only .balign directive. - Use C style comments. +commit cbb062cc35c518004f1ab45c847f8ec4f66069ad +Author: Anthony Green +Date: Thu Feb 17 20:39:21 2011 -0500 -2001-07-16 Rainer Orth + Another non-GCC configury fix - * src/alpha/ffi.c (ffi_prep_closure): Avoid gas-only mnemonic. - Fixes PR bootstrap/3563. +commit 8cf8878425e9971866fa6b27a3e4914729ad3960 +Author: Anthony Green +Date: Tue Feb 15 15:19:49 2011 -0500 -2001-06-26 Rainer Orth + Fix ax_cc_maxopt.m4 - * src/alpha/osf.S (ffi_closure_osf): Use .rdata for ECOFF. +commit 24b72070c0937f9000744c77a636f07e04786b6a +Author: Anthony Green +Date: Mon Feb 14 15:30:57 2011 -0500 -2001-06-25 Rainer Orth + Fix warning and msvcc patches - * configure.in: Recognize sparc*-sun-* host. - * configure: Regenerate. +commit d72c49e556a8c516e97f6722d1be2f1209c21207 +Author: Anthony Green +Date: Sun Feb 13 11:41:05 2011 -0500 -2001-06-06 Andrew Haley + Add missing msvcc.sh - * src/alpha/osf.S (__FRAME_BEGIN__): Conditionalize for ELF. +commit 3000dc237f6017a7445d8404097a4f46b73fdd29 +Merge: 55e4a5a 1fbf9dc +Author: Landon Fuller +Date: Sun Feb 13 08:55:53 2011 -0500 -2001-06-03 Andrew Haley + Merge remote branch 'upstream/master' - * src/alpha/osf.S: Add unwind info. - * src/powerpc/sysv.S: Add unwind info. - * src/powerpc/ppc_closure.S: Likewise. +commit 1fbf9dc44feea564e84ad7406d17c5d5906ce0e0 +Author: Anthony Green +Date: Sun Feb 13 08:06:39 2011 -0500 -2000-05-31 Jeff Sturm + Fix bad_abi test. rc5. - * configure.in: Fix AC_ARG_ENABLE usage. - * configure: Rebuilt. +commit 90af15ef5c1614b76370c4d13954586fabf9e8e3 +Author: Anthony Green +Date: Sat Feb 12 12:29:36 2011 -0500 -2001-05-06 Bryce McKinlay + iOS fixes - * configure.in: Remove warning about beta code. - * configure: Rebuilt. +commit 55e4a5aa1568558a04aa40f16fc022e459af53e3 +Author: Landon Fuller +Date: Sat Feb 12 12:13:46 2011 -0500 -2001-04-25 Hans Boehm + Add support for building a full armv6/armv7/i386 universal iOS library - * src/ia64/unix.S: Restore stack pointer when returning from - ffi_closure_UNIX. - * src/ia64/ffi.c: Fix typo in comment. +commit a0c80f279b8733d001cb5e5c5a3289ecb7a6e56a +Author: Landon Fuller +Date: Sat Feb 12 11:43:49 2011 -0500 -2001-04-18 Jim Wilson + Update my e-mail address. - * src/ia64/unix.S: Delete unnecessary increment and decrement of loc2 - to eliminate RAW DV. +commit 8195e0e11df7a53fa474caa9375f73ca1136ed66 +Author: Landon Fuller +Date: Sat Feb 12 11:27:00 2011 -0500 -2001-04-12 Bryce McKinlay + Fix symbol prefixes on Darwin. - * Makefile.am: Make a libtool convenience library. - * Makefile.in: Rebuilt. +commit 56b3f8cef0f28cefaa0f40fe0cf7c524adef131d +Author: Landon Fuller +Date: Sat Feb 12 11:14:54 2011 -0500 -2001-03-29 Bryce McKinlay + Modify the ffi_closure structures to hold table/table entry pointers instead of a code buffer. + + This re-integrates commit da2773e02ab26cc11a7f. - * configure.in: Use different syntax for subdirectory creation. - * configure: Rebuilt. +commit 28a00f61ff3f64c4eb2269ce2aea3d493274469e +Author: Landon Fuller +Date: Sat Feb 12 11:01:48 2011 -0500 -2001-03-27 Jon Beniston + Apple assembler support; fixed most gas/ELF-isms. - * configure.in: Added X86_WIN32 target (Win32, CygWin, MingW). - * configure: Rebuilt. - * Makefile.am: Added X86_WIN32 target support. - * Makefile.in: Rebuilt. +commit 7f2ea33a80bfced5e48ed7292f3b8f057d54ff8f +Author: Landon Fuller +Date: Sat Feb 12 10:39:18 2011 -0500 - * include/ffi.h.in: Added X86_WIN32 target support. + Replace RETLDM macro. + + The macro is incompatible with Apple's assembler; switch to + a simple inline version. - * src/ffitest.c: Doesn't run structure tests for X86_WIN32 targets. - * src/types.c: Added X86_WIN32 target support. +commit 92ff23e77fa586455b427b71f49e1d9502470e6e +Author: Landon Fuller +Date: Sat Feb 12 10:24:49 2011 -0500 - * src/x86/win32.S: New file. Based on sysv.S, but with EH - stuff removed and made to work with CygWin's gas. + Switch to the current iOS 4.2 SDK. -2001-03-26 Bryce McKinlay +commit 58fb8ca2dfb89ad70284bb9678d3d4dbb658c8a7 +Merge: cc3fbd9 71c792f +Author: Landon Fuller +Date: Sat Feb 12 10:23:19 2011 -0500 - * configure.in: Make target subdirectory in build dir. - * Makefile.am: Override suffix based rules to specify correct output - subdirectory. - * Makefile.in: Rebuilt. - * configure: Rebuilt. + Merge remote branch 'upstream/master' -2001-03-23 Kevin B Hendricks +commit cc3fbd975ce9366d4c40a6ff6c108f664867bd7c +Merge: e449a43 f6ab3ed +Author: Landon Fuller +Date: Sat Feb 12 10:21:02 2011 -0500 - * src/powerpc/ppc_closure.S: New file. - * src/powerpc/ffi.c (ffi_prep_args): Fixed ABI compatibility bug - involving long long and register pairs. - (ffi_prep_closure): New function. - (flush_icache): Likewise. - (ffi_closure_helper_SYSV): Likewise. - * include/ffi.h.in (FFI_CLOSURES): Define on PPC. - (FFI_TRAMPOLINE_SIZE): Likewise. - (FFI_NATIVE_RAW_API): Likewise. - * Makefile.in: Rebuilt. - * Makefile.am (EXTRA_DIST): Added src/powerpc/ppc_closure.S. - (TARGET_SRC_POWERPC): Likewise. + Merge branch 'master' of github.com:landonf/libffi-ios -2001-03-19 Tom Tromey +commit e449a43bbe12f8119399928db1ae26adc71dde14 +Author: Landon Fuller +Date: Sat Feb 12 10:20:42 2011 -0500 - * Makefile.in: Rebuilt. - * Makefile.am (ffitest_LDFLAGS): New macro. + Allow specification of the minimum supported iOS version. -2001-03-02 Nick Clifton +commit 71c792f51bcf3e2f334e5ea1fb1a8b667cb3aedb +Author: Anthony Green +Date: Sat Feb 12 09:33:11 2011 -0500 - * include/ffi.h.in: Remove RCS ident string. - * include/ffi_mips.h: Remove RCS ident string. - * src/debug.c: Remove RCS ident string. - * src/ffitest.c: Remove RCS ident string. - * src/prep_cif.c: Remove RCS ident string. - * src/types.c: Remove RCS ident string. - * src/alpha/ffi.c: Remove RCS ident string. - * src/alpha/osf.S: Remove RCS ident string. - * src/arm/ffi.c: Remove RCS ident string. - * src/arm/sysv.S: Remove RCS ident string. - * src/mips/ffi.c: Remove RCS ident string. - * src/mips/n32.S: Remove RCS ident string. - * src/mips/o32.S: Remove RCS ident string. - * src/sparc/ffi.c: Remove RCS ident string. - * src/sparc/v8.S: Remove RCS ident string. - * src/sparc/v9.S: Remove RCS ident string. - * src/x86/ffi.c: Remove RCS ident string. - * src/x86/sysv.S: Remove RCS ident string. - -2001-02-08 Joseph S. Myers - - * include/ffi.h.in: Change sourceware.cygnus.com references to - gcc.gnu.org. - -2000-12-09 Richard Henderson - - * src/alpha/ffi.c (ffi_call): Simplify struct return test. - (ffi_closure_osf_inner): Index rather than increment avalue - and arg_types. Give ffi_closure_osf the raw return value type. - * src/alpha/osf.S (ffi_closure_osf): Handle return value type - promotion. - -2000-12-07 Richard Henderson - - * src/raw_api.c (ffi_translate_args): Fix typo. - (ffi_prep_closure): Likewise. - - * include/ffi.h.in [ALPHA]: Define FFI_CLOSURES and - FFI_TRAMPOLINE_SIZE. - * src/alpha/ffi.c (ffi_prep_cif_machdep): Adjust minimal - cif->bytes for new ffi_call_osf implementation. - (ffi_prep_args): Absorb into ... - (ffi_call): ... here. Do all stack allocation here and - avoid a callback function. - (ffi_prep_closure, ffi_closure_osf_inner): New. - * src/alpha/osf.S (ffi_call_osf): Reimplement with no callback. - (ffi_closure_osf): New. - -2000-09-10 Alexandre Oliva - - * config.guess, config.sub, install-sh: Removed. - * ltconfig, ltmain.sh, missing, mkinstalldirs: Likewise. - * Makefile.in: Rebuilt. - - * acinclude.m4: Include libtool macros from the top level. - * aclocal.m4, configure: Rebuilt. - -2000-08-22 Alexandre Oliva - - * configure.in [i*86-*-freebsd*] (TARGET, TARGETDIR): Set. - * configure: Rebuilt. - -2000-05-11 Scott Bambrough - - * libffi/src/arm/sysv.S (ffi_call_SYSV): Doubles are not saved to - memory correctly. Use conditional instructions, not branches where - possible. - -2000-05-04 Tom Tromey - - * configure: Rebuilt. - * configure.in: Match `arm*-*-linux-*'. - From Chris Dornan . - -2000-04-28 Jakub Jelinek - - * Makefile.am (SUBDIRS): Define. - (AM_MAKEFLAGS): Likewise. - (Multilib support.): Add section. - * Makefile.in: Rebuilt. - * ltconfig (extra_compiler_flags, extra_compiler_flags_value): - New variables. Set for gcc using -print-multi-lib. Export them - to libtool. - (sparc64-*-linux-gnu*): Use libsuff 64 for search paths. - * ltmain.sh (B|b|V): Don't throw away gcc's -B, -b and -V options - for -shared links. - (extra_compiler_flags_value, extra_compiler_flags): Check these - for extra compiler options which need to be passed down in - compiler_flags. - -2000-04-16 Anthony Green - - * configure: Rebuilt. - * configure.in: Change i*86-pc-linux* to i*86-*-linux*. - -2000-04-14 Jakub Jelinek - - * include/ffi.h.in (SPARC64): Define for 64bit SPARC builds. - Set SPARC FFI_DEFAULT_ABI based on SPARC64 define. - * src/sparc/ffi.c (ffi_prep_args_v8): Renamed from ffi_prep_args. - Replace all void * sizeofs with sizeof(int). - Only compare type with FFI_TYPE_LONGDOUBLE if LONGDOUBLE is - different than DOUBLE. - Remove FFI_TYPE_SINT32 and FFI_TYPE_UINT32 cases (handled elsewhere). - (ffi_prep_args_v9): New function. - (ffi_prep_cif_machdep): Handle V9 ABI and long long on V8. - (ffi_V9_return_struct): New function. - (ffi_call): Handle FFI_V9 ABI from 64bit code and FFI_V8 ABI from - 32bit code (not yet cross-arch calls). - * src/sparc/v8.S: Add struct return delay nop. - Handle long long. - * src/sparc/v9.S: New file. - * src/prep_cif.c (ffi_prep_cif): Return structure pointer - is used on sparc64 only for structures larger than 32 bytes. - Pass by reference for structures is done for structure arguments - larger than 16 bytes. - * src/ffitest.c (main): Use 64bit rint on sparc64. - Run long long tests on sparc. - * src/types.c (FFI_TYPE_POINTER): Pointer is 64bit on alpha and - sparc64. - (FFI_TYPE_LONGDOUBLE): long double is 128 bit aligned to 128 bits - on sparc64. - * configure.in (sparc-*-linux*): New supported target. - (sparc64-*-linux*): Likewise. - * configure: Rebuilt. - * Makefile.am: Add v9.S to SPARC files. - * Makefile.in: Likewise. - (LINK): Surround $(CCLD) into double quotes, so that multilib - compiles work correctly. - -2000-04-04 Alexandre Petit-Bianco - - * configure: Rebuilt. - * configure.in: (i*86-*-solaris*): New libffi target. Patch - proposed by Bryce McKinlay. - -2000-03-20 Tom Tromey - - * Makefile.in: Hand edit for java_raw_api.lo. - -2000-03-08 Bryce McKinlay + rc4 - * config.guess, config.sub: Update from the gcc tree. - Fix for PR libgcj/168. +commit 7c7c9f327299331022f6000603a35f2310dfe308 +Author: Anthony Green +Date: Sat Feb 12 09:29:29 2011 -0500 -2000-03-03 Tom Tromey + ungccify parts of the build - * Makefile.in: Fixed ia64 by hand. +commit ed62e48b95a0fa60b685f647cb73c9e190eec35c +Author: Anthony Green +Date: Fri Feb 11 12:23:58 2011 -0500 - * configure: Rebuilt. - * configure.in (--enable-multilib): New option. - (libffi_basedir): New subst. - (AC_OUTPUT): Added multilib code. + Fix permissions -2000-03-02 Tom Tromey +commit 17d9e9e68ddb1b915a0b9751713033861b598575 +Author: Anthony Green +Date: Fri Feb 11 12:23:20 2011 -0500 - * Makefile.in: Rebuilt. - * Makefile.am (TARGET_SRC_IA64): Use `ia64', not `alpha', as - directory name. + Use newer autotools. Only build debug.c when --enable-debug. -2000-02-25 Hans Boehm +commit 6972a4ffda75761eaab7dfbe0fb1516b255e8e0c +Author: Anthony Green +Date: Fri Feb 11 07:32:51 2011 -0500 - * src/ia64/ffi.c, src/ia64/ia64_flags.h, src/ia64/unix.S: New - files. - * src/raw_api.c (ffi_translate_args): Fixed typo in argument - list. - (ffi_prep_raw_closure): Use ffi_translate_args, not - ffi_closure_translate. - * src/java_raw_api.c: New file. - * src/ffitest.c (closure_test_fn): New function. - (main): Define `rint' as long long on IA64. Added new test when - FFI_CLOSURES is defined. - * include/ffi.h.in (ALIGN): Use size_t, not unsigned. - (ffi_abi): Recognize IA64. - (ffi_raw): Added `flt' field. - Added "Java raw API" code. - * configure.in: Recognize ia64. - * Makefile.am (TARGET_SRC_IA64): New macro. - (libffi_la_common_SOURCES): Added java_raw_api.c. - (libffi_la_SOURCES): Define in IA64 case. + Fix xlc build on AIX -2000-01-04 Tom Tromey +commit 1833aa0fb9831eb0725b63e35886c0f6d35df480 +Author: Anthony Green +Date: Fri Feb 11 07:11:04 2011 -0500 - * Makefile.in: Rebuilt with newer automake. + sparc ABI test fix. -1999-12-31 Tom Tromey +commit f1fb139b4e283fffdcf205a903943d5e9d2bb2a2 +Author: Anthony Green +Date: Wed Feb 9 18:30:02 2011 -0500 - * Makefile.am (INCLUDES): Added -I$(top_srcdir)/src. + Fix tests -1999-09-01 Tom Tromey +commit 5cb470331d181c84d5d621e88868327a324a5898 +Author: Anthony Green +Date: Wed Feb 9 15:23:06 2011 -0500 - * include/ffi.h.in: Removed PACKAGE and VERSION defines and - undefs. - * fficonfig.h.in: Rebuilt. - * configure: Rebuilt. - * configure.in: Pass 3rd argument to AM_INIT_AUTOMAKE. - Use AM_PROG_LIBTOOL (automake 1.4 compatibility). - * acconfig.h: Don't #undef PACKAGE or VERSION. + Fix permissions -1999-08-09 Anthony Green +commit 269deef6dbbb426695919d3398357fada3bb288c +Author: Anthony Green +Date: Wed Feb 9 15:22:23 2011 -0500 - * include/ffi.h.in: Try to work around messy header problem - with PACKAGE and VERSION. + rc3 - * configure: Rebuilt. - * configure.in: Change version to 2.00-beta. +commit 42695e72504f647444b8e8e9b90bd24f1e3220e1 +Author: Anthony Green +Date: Wed Feb 9 15:12:35 2011 -0500 - * fficonfig.h.in: Rebuilt. - * acconfig.h (FFI_NO_STRUCTS, FFI_NO_RAW_API): Define. + Fix IRIX support - * src/x86/ffi.c (ffi_raw_call): Rename. +commit a6e56b97f62a3feeb3301c24a2e4cae55e546021 +Author: Anthony Green +Date: Wed Feb 9 15:00:42 2011 -0500 -1999-08-02 Kresten Krab Thorup + Add powerpc64-*-darwin* support - * src/x86/ffi.c (ffi_closure_SYSV): New function. - (ffi_prep_incoming_args_SYSV): Ditto. - (ffi_prep_closure): Ditto. - (ffi_closure_raw_SYSV): Ditto. - (ffi_prep_raw_closure): More ditto. - (ffi_call_raw): Final ditto. +commit 747d6c32d4abb07c10c3a1f93579c3929aaa2487 +Author: Anthony Green +Date: Wed Feb 9 14:56:23 2011 -0500 - * include/ffi.h.in: Add definitions for closure and raw API. + Add Interix support - * src/x86/ffi.c (ffi_prep_cif_machdep): Added case for - FFI_TYPE_UINT64. +commit eab6e41cde382aa07de6c011d514a14c0d62eb47 +Author: Anthony Green +Date: Wed Feb 9 10:15:02 2011 -0500 - * Makefile.am (libffi_la_common_SOURCES): Added raw_api.c + Remove README.markdown form libffi-ios - * src/raw_api.c: New file. +commit 69dbe845f4ee3e6ce8999f17a1e4f2179ef7da89 +Author: Anthony Green +Date: Wed Feb 9 07:38:43 2011 -0500 - * include/ffi.h.in (ffi_raw): New type. - (UINT_ARG, SINT_ARG): New defines. - (ffi_closure, ffi_raw_closure): New types. - (ffi_prep_closure, ffi_prep_raw_closure): New declarations. + Fix xfails - * configure.in: Add check for endianness and sizeof void*. +commit f498318c07b95137fe259d86bdbe15347588b84a +Author: Anthony Green +Date: Wed Feb 9 06:26:46 2011 -0500 - * src/x86/sysv.S (ffi_call_SYSV): Call fixup routine via argument, - instead of directly. + Update README for iOS again - * configure: Rebuilt. +commit 630b9c0ac43c7edcbfd892e23c09fb26724f4ac0 +Author: Anthony Green +Date: Wed Feb 9 06:24:23 2011 -0500 -Thu Jul 8 14:28:42 1999 Anthony Green + Update to rc2 - * configure.in: Add x86 and powerpc BeOS configurations. - From Makoto Kato . +commit 0cad4386fa4c9ea5f8ca88b16247db4e5c8fea90 +Author: Anthony Green +Date: Wed Feb 9 06:11:46 2011 -0500 -1999-05-09 Anthony Green + Add ChangeLog entry. Fix copyright headers. - * configure.in: Add warning about this being beta code. - Remove src/Makefile.am from the picture. - * configure: Rebuilt. +commit 09cb76f2645bd2c151846e9249d8ea707ba01e8c +Author: Anthony Green +Date: Tue Feb 8 20:39:51 2011 -0500 - * Makefile.am: Move logic from src/Makefile.am. Add changes - to support libffi as a target library. - * Makefile.in: Rebuilt. + Add missing change - * aclocal.m4, config.guess, config.sub, ltconfig, ltmain.sh: - Upgraded to new autoconf, automake, libtool. +commit 2e3a48ccdd54340983c46a29a0b41985e3e789ac +Author: Anthony Green +Date: Tue Feb 8 20:37:26 2011 -0500 - * README: Tweaks. + Fix make dist - * LICENSE: Update copyright date. +commit 5e4814d9928e236a2a4afe84d6e1d4fdaa473206 +Author: Anthony Green +Date: Tue Feb 8 19:46:28 2011 -0500 - * src/Makefile.am, src/Makefile.in: Removed. + fix permissions -1998-11-29 Anthony Green +commit 5c0cc6f1536aa1738795a97303810a823c7fa2cb +Author: Anthony Green +Date: Tue Feb 8 19:45:59 2011 -0500 - * include/ChangeLog: Removed. - * src/ChangeLog: Removed. - * src/mips/ChangeLog: Removed. - * src/sparc/ChangeLog: Remboved. - * src/x86/ChangeLog: Removed. + 3.0.10rc1 - * ChangeLog.v1: Created. +commit 857fe3de46d2286afa2fe772920ecf4aefa1688f +Author: Anthony Green +Date: Tue Feb 8 19:39:20 2011 -0500 + + Clean ups + +commit e2214f8adb5577c247452e2cc9f4cbe304d7ca9f +Author: Anthony Green +Date: Tue Feb 8 19:22:56 2011 -0500 + + Update README + +commit 1106229a5721a659da5c231ec0e8211119615394 +Merge: bc9d0be f6ab3ed +Author: Anthony Green +Date: Tue Feb 8 19:20:09 2011 -0500 + + Add iOS support + +commit bc9d0be2958ce475757f34dd2c878948aa77a39f +Author: Anthony Green +Date: Tue Feb 8 17:04:26 2011 -0500 + + 3.0.10rc0 changes + +commit 3b836249feae6d08d3e6887486e4b9961ddafa09 +Author: Anthony Green +Date: Tue Feb 8 14:28:59 2011 -0500 + + Rebase from GCC + +commit a26e3940619faeba6de54824c9540c90b1aab513 +Author: Anthony Green +Date: Tue Feb 8 13:56:12 2011 -0500 + + copyright updates patch + +commit b8099539f00e224107594101e9760b6dc081a056 +Author: Anthony Green +Date: Tue Feb 8 13:50:43 2011 -0500 + + Fix msvcc.sh botch + +commit dc411e8f99113a34656bfd2d3ae51259972488cc +Author: Anthony Green +Date: Tue Feb 8 10:49:29 2011 -0500 + + Fix HP-UX build + +commit 404585d1348e30ac58203bbd876d9131e5aed874 +Author: Anthony Green +Date: Tue Feb 8 10:44:36 2011 -0500 + + Fix sparc v8 aggregate type returns for sun's compiler + +commit 19ce713188e193e4522740d24c20170411883d2d +Author: Anthony Green +Date: Tue Feb 8 10:34:23 2011 -0500 + + grammar fix + +commit 89284fe55f1a8ad3bddbea796ee00d0e3ba411ce +Author: Anthony Green +Date: Tue Feb 8 10:19:19 2011 -0500 + + Fix AIX build with IBM XLC + +commit ba022c338af97cb18d9f8ed5a607fd483a61c09c +Author: Anthony Green +Date: Tue Feb 8 10:12:48 2011 -0500 + + fix win64-underscore patch + +commit 097e5f3924ee92a3ba6cd72f787da8a3eb14fea3 +Author: Anthony Green +Date: Tue Feb 8 10:11:00 2011 -0500 + + x86 pcrel test part 2 + +commit ed2c518d960b91d444be74e5a55779a9c4602f3b +Author: Anthony Green +Date: Tue Feb 8 10:10:07 2011 -0500 + + x86 pcrel test + +commit 0e5843995f46900ef212531281e08b224464f413 +Author: Anthony Green +Date: Tue Feb 8 07:52:40 2011 -0500 + + Refresh from GCC + +commit 5b9cd52784339a42e417174a55e310e214d435f9 +Author: Anthony Green +Date: Mon Nov 22 15:19:57 2010 -0500 + + win64-underscore patch + +commit 2db72615b50eb5c0f29725c02c740a2f0d7fc7d9 +Author: Anthony Green +Date: Sun Nov 21 10:50:56 2010 -0500 + + Rebase + +commit f6ab3edc23dc8fc7c47a31c896044150c23f04b5 +Author: Landon Fuller +Date: Wed Oct 27 19:34:51 2010 -0400 + + Include the license header in the generated output. + +commit cef619462887fa0f360e3ee702d1e04f112b5b38 +Author: Landon Fuller +Date: Wed Oct 27 13:59:30 2010 -0400 + + Add missing copyright/license header. + +commit 53f387b203413c9aa6e31f49dbb70d37d816330b +Author: Landon Fuller +Date: Sun Sep 19 19:57:17 2010 -0700 + + Minor README fix. + +commit 4fbcb5b5fbce11f4b168060e00639db33c85b75b +Author: Landon Fuller +Date: Sun Sep 19 19:50:37 2010 -0700 + + Minor README fix. + +commit 8e7652ef6acab5db7a29f786686a54f05cdbdc7d +Author: Landon Fuller +Date: Sun Sep 19 19:49:39 2010 -0700 + + Add a libffi-ios-specific github README. + +commit 83038cf24aa1a92b62b91ffee1dcc25d79243484 +Author: Landon Fuller +Date: Sun Sep 19 14:36:45 2010 -0700 + + Implement FFI_EXEC_TRAMPOLINE_TABLE allocator for iOS/ARM. + + This provides working closure support on iOS/ARM devices where + PROT_WRITE|PROT_EXEC is not permitted. The code passes basic + smoke tests, but requires further review. + +commit b00ff3e98fdde622cef617030e14d5356dff988f +Author: Landon Fuller +Date: Sun Sep 19 14:22:26 2010 -0700 + + Rename the generated symbol + +commit da2773e02ab26cc11a7fe87e985599f35cdf0649 +Author: Landon Fuller +Date: Sun Sep 19 14:21:37 2010 -0700 + + Modify the ffi_closure structures to hold table/table entry pointers instead of a code buffer. + +commit 01d71b7bed41844f80cb9feef20dcc5ece5ba2d0 +Author: Landon Fuller +Date: Sun Sep 19 14:21:14 2010 -0700 + + Regenerated the autoconf script + +commit 19afda0069c42e51c81dca7b10a5cf884b4cdce0 +Author: Landon Fuller +Date: Sun Sep 19 14:20:52 2010 -0700 + + Enable AC_SUBST for FFI_EXEC_TRAMPOLINE_TABLE + +commit 9e1196444e78aef20028c18891f44ebe39a815fd +Author: Landon Fuller +Date: Sun Sep 19 10:43:06 2010 -0700 + + Add a hard-coded FFI_EXEC_TRAMPOLINE_TABLE arm implementation. + + This implements support for re-mapping a shared table of executable + trampolines directly in front of a writable configuration page, working + around PROT_WRITE restrictions for sandboxed applications on Apple's + iOS. + + This implementation is for testing purposes; a proper allocator is still + necessary, and ARM-specific code needs to be moved out of + src/closures.c. + +commit f38364b399184e682fc3e785084bd497827bc5af +Author: Landon Fuller +Date: Sun Sep 19 10:42:36 2010 -0700 + + Fix symbol prefix for ffi_closure_SYSV_inner on Darwin. + +commit 36849e7716b77aa25e4175d1f4be1b93dbf47aac +Author: Landon Fuller +Date: Sun Sep 19 09:35:04 2010 -0700 + + Whitespace/comment fixes. + +commit b764162526854686e579a48b6ac5981f4eb886a3 +Author: Landon Fuller +Date: Sun Sep 19 09:04:34 2010 -0700 + + Fix the script name (build-iphone.sh -> build-ios.sh) + +commit a3d9aa85013341451ea97766485b7a11852d32b2 +Author: Landon Fuller +Date: Sun Sep 19 09:03:52 2010 -0700 + + Update the autogenerated autoconf/automake files. + +commit c71480eaf839f26bbdfcd8965f65ac4d8defddc0 +Author: Landon Fuller +Date: Sun Sep 19 09:02:05 2010 -0700 + + Update automake/autoconf to conditionally build src/arm/trampoline.S if FFI_EXEC_TRAMPOLINE_TABLE is enabled. + +commit 9af9291b73bc5e27ecd949bec8157f20426d65b8 +Author: Landon Fuller +Date: Sun Sep 19 08:52:33 2010 -0700 + + Add the trampoline table generated by gentramp.sh + +commit 68ce0c383ece84f69945d1c8c3fed03f7f9cb5d6 +Author: Landon Fuller +Date: Sun Sep 19 08:38:19 2010 -0700 + + Add a shell script that generates the ARM trampoline page. + + This generates a page of 340 trampolines, aligned within one page. The + trampolines use pc-relative addressing to reference config data + (context, jump address) from a page placed directly prior to the + trampoline page. This can be used on systems -- such as iOS -- that do not + support writable, executable memory by remapping the executable page + containing the trampolines directly above a newly allocated writable + config page. + +commit 75af086be8830a8eafe9b1ebda199d788bcb0c62 +Author: Landon Fuller +Date: Sat Sep 18 18:12:19 2010 -0700 + + Update autoconf files + +commit 1ac92cca9b02ef8d6a769f0de1adccd5c9630355 +Author: Landon Fuller +Date: Sat Sep 18 18:08:14 2010 -0700 + + Add autoconf check for W^X platforms that require a trampoline table. + + This adds the FFI_EXEC_TRAMPOLINE_TABLE. The flag is enabled for + arm-apple-darwin, where PROT_EXEC on writable (or formerly writable) pages is + not permitted for sandboxed binaries. + +commit be72fbab29b7190c702d8e1ac3d149855e95879d +Author: Landon Fuller +Date: Sat Sep 18 18:02:25 2010 -0700 + + Use the correct host triple for arm/darwin + +commit 70150bdf4509269965c72f2032bf74f285767afe +Author: Landon Fuller +Date: Sat Sep 18 16:38:03 2010 -0700 + + Add missing UNWIND entry; disables .pad on non-EABI targets. + +commit 6b452bafaec498df975ba8ac4c99de174e5f74f7 +Author: Landon Fuller +Date: Sat Sep 18 16:21:32 2010 -0700 + + Apple assembler support; fixed most gas/ELF-isms. + +commit 8ddac835b6f8b54ede764d0ea977dee4c82e2d67 +Author: Landon Fuller +Date: Sat Sep 18 15:38:06 2010 -0700 + + Fix placement of the __APPLE__ macro. + +commit 69043d02936bb0579ac59b4ee1ed8dec38c38db7 +Author: Landon Fuller +Date: Sat Sep 18 15:32:08 2010 -0700 + + Work-around libffi's FP ABI detection. + + On iOS, we must use the AAPCS floating point return value calling + conventions. libffi's ARM implementation will only use these conventions + if __SOFTFP__ is defined, which is not the case when GCC's + -mfloat-abi defaults to 'softfp' instead of 'soft'. To work around this + we manually define __SOFTFP__ for Apple platforms in the ARM-specific + sysv.S. + + See also: + http://developer.apple.com/library/ios/#documentation/Xcode/Conceptual/iPhoneOSABIReference/Introduction/Introduction.html + http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042d/IHI0042D_aapcs.pdf + +commit a82e6c354ea805114642a6e440abd0832cb1d23f +Author: Landon Fuller +Date: Sat Sep 18 14:44:24 2010 -0700 + + Add a stub iOS build script to drive autoconf + +commit 84e8de6e9fc19388f6f1102c013b7d0d52940ecc +Author: Anthony Green +Date: Fri Aug 6 01:35:12 2010 -0400 + + Restore execute permissions + +commit 3aeecc9eb1a6feba6549849cdd335c926415a4fc +Author: Anthony Green +Date: Thu Aug 5 15:19:00 2010 -0400 + + Fix win64-struct-args patch + +commit 00d0b59cd13f89ab8b44bd894eb7f0a131fcb472 +Author: Anthony Green +Date: Thu Aug 5 14:56:53 2010 -0400 + + Fix debug build for windows + +commit bda487e87064f27965155459a62dc52a744778d0 +Author: Anthony Green +Date: Thu Aug 5 09:02:41 2010 -0400 + + Don't use -safeseh with ml64 + +commit c1d28ba8d5029795af313ffeb81c97efc6d4c847 +Author: Anthony Green +Date: Thu Aug 5 08:48:16 2010 -0400 + + stdcall-x86-closure-fix + +commit 5feacad4a56c85b3f23a267a30b2cf424cd59548 +Author: Anthony Green +Date: Thu Aug 5 08:30:04 2010 -0400 + + define generic symbols carefully + +commit 10ea848900bc3018ac213cef52b44cacbe5cbebc +Author: Anthony Green +Date: Thu Aug 5 08:24:27 2010 -0400 + + don't copy win64 struct args + +commit d14178be4c49c3ada44a9fe9efe11d444372ddab +Author: Anthony Green +Date: Fri Jul 23 09:14:00 2010 -0400 + + FFI_LAST_ABI fix + +commit 3f5b1375ab1e2b8e3d593e21b27097a4a50f9b83 +Author: Anthony Green +Date: Mon Jul 12 14:39:18 2010 -0400 + + rebase + +commit eaf444eabc4c78703c0f98ac0197b1619c1b1bef +Author: Anthony Green +Date: Sat Jul 10 08:59:09 2010 -0400 + + Fix selinux test + +commit 630974152247f100ece4d44f10c3721bb4599fbf +Author: Anthony Green +Date: Wed May 5 20:14:56 2010 -0400 + + Micharl Kohler's spelling fixes + +commit 9dc9a293f3d4589fcaf02dd4288c8cebaefa508e +Author: Anthony Green +Date: Tue Apr 13 10:33:52 2010 -0400 + + Rebase to latest GCC sources + +commit f2c2a4fce9b3eca9f39b4f3545118bc256da4a73 +Author: Anthony Green +Date: Tue Apr 13 10:19:28 2010 -0400 + + Remove warnings and add OS/2 support + +commit c0b69e57d529e33d18b658cc5572a21e3663247c +Author: Anthony Green +Date: Tue Mar 30 08:30:22 2010 -0400 + + Dan Witte's windows build fixes. + +commit 59a259f4d348f593b45f452309f4d020a28051c4 +Author: Anthony Green +Date: Mon Mar 15 05:57:51 2010 -0400 + + Remove junk file + +commit 3de1eb36d37a66829e606421939874d0d60d816d +Author: Anthony Green +Date: Mon Mar 15 05:57:24 2010 -0400 + + fix-comments patch + +commit c3813b6d7f8a777700f4c5862190c0db148d4de8 +Author: Anthony Green +Date: Tue Jan 26 16:48:56 2010 -0500 + + Rebuild Makefiles with automake 1.11.1 for CVE-2009-4029. + +commit 8d27f68baa365bf883b6053c5f6bc819646d5434 +Author: Anthony Green +Date: Fri Jan 15 11:35:37 2010 -0500 + + Mention recent changes in README + +commit ff3cd68b8cf2d9a28cad7aa9beff46236eacec8c +Author: Anthony Green +Date: Fri Jan 15 11:27:24 2010 -0500 + + Add msvc.sh wrapper + +commit cadeba6cb53414a1253582f1719c286665de7b6c +Author: Anthony Green +Date: Fri Jan 15 10:46:51 2010 -0500 + + Microsoft Visual C port + +commit 0739e7dc00db766eb64f502ec4137b817638c9a1 +Author: Anthony Green +Date: Fri Jan 15 09:48:33 2010 -0500 + + Add x86 Sun Studio compiler support + +commit edfdfd2e85b8d01d2455934f1d7f4d7eb2f3cf1c +Author: Anthony Green +Date: Wed Jan 13 02:56:19 2010 -0500 + + Add closure example doc + +commit 7b7a42f221cf171e8d09df34cac6dc1fd8458cc3 +Author: Anthony Green +Date: Tue Jan 12 09:14:14 2010 -0500 + + Rebase from GCC + +commit 4b18d1f73dc7733137869e4ab5725cb90c1c8fde +Author: Anthony Green +Date: Fri Jan 1 10:24:27 2010 -0500 + + Add x86-64 MingW to README + +commit c3042afaf3f84abbbe9c91bf9bc9896b0d9eb003 +Author: Anthony Green +Date: Fri Jan 1 08:08:02 2010 -0500 + + Reset quilt patches post 3.0.9 merge with GCC + +commit b0304e9679bdfec6ac45a57b5c96542697249418 +Author: Anthony Green +Date: Thu Dec 31 11:32:40 2009 -0500 + + Update version + +commit 2e7e03d014d9c9bf40e97ce75cba089ad052fa6b +Author: Anthony Green +Date: Thu Dec 31 07:43:22 2009 -0500 + + Final updates before 3.0.9 + +commit aea706c52825c8eee677ffa7fdbdd3aed1725492 +Author: Anthony Green +Date: Tue Dec 29 10:09:31 2009 -0500 + + really 3.0.9rc12 + +commit 0cfe60e9d13f132b88995cfee41f2156344f6fa2 +Author: Anthony Green +Date: Tue Dec 29 10:06:04 2009 -0500 + + 3.0.9rc12 + +commit 14e2e92e8645804b6940b3e96c98e9f7f384a6b2 +Author: Anthony Green +Date: Sun Dec 27 21:03:33 2009 -0500 + + 3.0.9rc11 + +commit 884402787bf8eaf7ec207085037cf8ace2f660ec +Author: Anthony Green +Date: Sat Dec 26 12:57:23 2009 -0500 + + HPUX support and avr32 test fixes. + +commit 01c78756aff22efb1f122f8e93e068d7bf2185c7 +Author: Anthony Green +Date: Sat Dec 26 10:05:18 2009 -0500 + + 3.0.9rc9 + +commit 70868464651320268d79c6894db5a50fdc11032a +Author: Anthony Green +Date: Sat Dec 26 09:58:03 2009 -0500 + + Remove xfails for mips and arm + +commit 838d4ad920ec85cf5ca3b511221d67f6d9a99024 +Author: Anthony Green +Date: Sat Dec 26 09:57:27 2009 -0500 + + Remove a bunch of xfails. + +commit 7e37eaaf772f48906e69618c773b0a36c3927de9 +Author: Anthony Green +Date: Sat Dec 26 07:46:50 2009 -0500 + + Fix huge_struct for solaris + +commit 07cc7a37194bc34064ebed7f2724333a798411c8 +Author: Anthony Green +Date: Sat Dec 26 07:23:04 2009 -0500 + + 3.0.9rc8 + +commit 2b9be16ffabc81326128bc1bbdddff8ddc5d13d3 +Author: Anthony Green +Date: Sat Dec 26 07:04:45 2009 -0500 + + 3.0.9rc8 + +commit 9458d88f676e9a21ab8993a54e16754b11687419 +Author: Anthony Green +Date: Sat Dec 26 07:02:27 2009 -0500 + + Rebase from GCC + +commit 6a3412417593f068a04dc6163f4269cb295ad5ca +Author: Anthony Green +Date: Sat Dec 26 06:51:33 2009 -0500 + + Add Andreas Schwab's powerpc fix + +commit 39c8792ece1043f41f4c395a2ce71f4cf0ff4674 +Author: Anthony Green +Date: Fri Dec 25 21:52:28 2009 -0500 + + 3.0.9rc7 + +commit 1d04af52e3e24db69f742064694c22f8df5cc70e +Author: Anthony Green +Date: Fri Dec 25 09:50:36 2009 -0500 + + Updated some mips XFAILs + +commit 26e9509c9b7929bc4fcf697071699051a652b1fd +Author: Anthony Green +Date: Fri Dec 25 02:19:23 2009 -0500 + + Clean up ChangeLog.libffi for older patches. + +commit 9c157d3215e4393777f83eb6fa801df6528f40d7 +Author: Anthony Green +Date: Fri Dec 25 02:15:40 2009 -0500 + + Clean up undefine_AC_ARG_VAR_PRECIOUS patch. + +commit d22de05b0bfc480766bc1240615ce2830eee71b8 +Author: Anthony Green +Date: Fri Dec 25 02:04:23 2009 -0500 + + Fix patches + +commit 1fe3dc7c20dc4dbd8fed0d19c8618027d44ed971 +Author: Anthony Green +Date: Fri Dec 25 01:39:00 2009 -0500 + + Add windows support patch. + +commit f7c0bc613a88f7dbc2d18b345c10fa438833c170 +Author: Anthony Green +Date: Fri Dec 25 01:22:11 2009 -0500 + + 3.0.9rc6 + +commit c7fa2da8260258c11ab1dc7ac06fb611a2c1b50f +Author: Anthony Green +Date: Thu Dec 24 07:22:44 2009 -0500 + + 3.0.9rc6 + +commit da11bece0fde66fc0268db3a01207dda857e25d2 +Author: Anthony Green +Date: Thu Dec 24 05:34:46 2009 -0500 + + Release 3.0.9rc5 + +commit e3399b11edeab546b066bfc18574f3edb905d0dc +Author: Anthony Green +Date: Thu Dec 24 01:09:32 2009 -0500 + + Update README + +commit 115ab36fceee69740a01ce49bc27e1908cc237b1 +Author: Anthony Green +Date: Thu Dec 24 00:22:00 2009 -0500 + + Update missing changes for 3.0.9r4. + +commit f8c7a245bf5a80bd7e730ec03fcad17c8dcfcb07 +Author: Anthony Green +Date: Wed Dec 23 23:46:22 2009 -0500 + + Switch to quilt. Rebase to latest GCC. + +commit ce806772f02387b9a74f6496a263a368bccd5d59 +Merge: cd98813 dcc1f6b +Author: Anthony Green +Date: Mon Oct 5 00:41:35 2009 -0400 + + Merge branch 'master' of git@github.com:atgreen/libffi + +commit dcc1f6b4f1ffd2713bf68b791a13f85d455c8b1b +Author: Anthony Green +Date: Mon Oct 5 00:29:33 2009 -0400 + + More clean up. + +commit 2829f5941a223b9d851d8ab6318318e6197d7e01 +Author: Anthony Green +Date: Mon Oct 5 00:28:03 2009 -0400 + + Clean up + +commit cd98813de517ea64041637e3e78d27a001d6d3b4 +Author: Anthony Green +Date: Mon Oct 5 00:25:29 2009 -0400 + + From Jens Rehsack. Fix for 64-bit AIX. + +commit e4a91de766acc47f6c50f13cc11719a65e23ecba +Author: Anthony Green +Date: Mon Oct 5 00:16:17 2009 -0400 + + From Abdulaziz Ghuloum. Adds special case for Snow Leopard. + +commit 3425a763bcdaadb8b430226f427ec833afdcc96a +Author: Anthony Green +Date: Sun Oct 4 23:57:29 2009 -0400 + + Fix detection of free/openbsd. From Alexis Ballier. + +commit 2340e7a777902de61499d47823ad8d5e0eeb6203 +Author: Anthony Green +Date: Sun Oct 4 23:53:17 2009 -0400 + + AVR support + +commit 5cbe2058c128e848446ae79fe15ee54260a90559 +Author: Anthony Green +Date: Sun Oct 4 23:53:11 2009 -0400 + + Initial stand-alone patch. + +commit c6dddbd02bad9654ed58cdb0feb360934d105dec +Author: Anthony Green +Date: Sun Oct 4 08:11:33 2009 -0400 + + Initial commit + +commit 5ffc0c37486fb1538bccc0ca7acc807d4f1af932 +Author: Anthony Green +Date: Sun Oct 4 07:58:22 2009 -0400 + + Update version to 3.0.9rc1. Add more useful things to .gitignore. + +commit bd29f83ee9f6fa6b65adee9d3f57834f364d9887 +Author: Anthony Green +Date: Tue Sep 29 12:07:26 2009 -0400 + + Add .gitignore + +commit 9474f853f83e3f0167c1b306177321bfcc93e56d +Author: Anthony Green +Date: Tue Sep 29 11:13:02 2009 -0400 + + Remove old CVSROOT files. + +commit 0c25275ec24bfe2c2c25a000465f0950ef9dd51b +Author: twall +Date: Wed Aug 19 12:57:34 2009 +0000 + + Apply Dave Korn's cygwin/GCC changes + +commit 39228c27ed3f677a95b46380a8d31602b5777e1a +Author: aph +Date: Tue Jun 16 18:00:47 2009 +0000 + + 2009-06-16 Wim Lewis + + * src/powerpc/ffi.c: Avoid clobbering cr3 and cr4, which are + supposed to be callee-saved. + * src/powerpc/sysv.S (small_struct_return_value): Fix overrun of + return buffer for odd-size structs. + +commit 5e93cc704d127c2c8ae7f5d2cef621145d43e777 +Author: aph +Date: Tue Jun 16 17:41:47 2009 +0000 + + 2009-06-16 Andreas Tobler + + PR libffi/40444 + * testsuite/lib/libffi-dg.exp (libffi_target_compile): Add + allow_stack_execute for Darwin. + +commit b509af8959dc371b92392c623522ea6f4946a71d +Author: aph +Date: Tue Jun 16 16:17:52 2009 +0000 + + 2009-06-16 Andrew Haley + + * configure.ac (TARGETDIR): Add missing blank lines. + * configure: Regenerate. + +commit d57e96dc56ee76fbbb9b59d73aeaa92354db5ecb +Author: aph +Date: Tue Jun 16 09:59:02 2009 +0000 + + 2009-06-16 Andrew Haley + + * testsuite/libffi.call/cls_align_sint64.c, + testsuite/libffi.call/cls_align_uint64.c, + testsuite/libffi.call/cls_longdouble_va.c, + testsuite/libffi.call/cls_ulonglong.c, + testsuite/libffi.call/return_ll1.c, + testsuite/libffi.call/stret_medium2.c: Fix printf format + specifiers. + * testsuite/libffi.call/huge_struct.c: Ad x86 XFAILs. + * testsuite/libffi.call/float2.c: Fix dg-excess-errors. + * testsuite/libffi.call/ffitest.h, + testsuite/libffi.special/ffitestcxx.h (PRIdLL, PRIuLL): Define. + +commit b01d6d1982c9e020507029bfd5a58a8c60d111fa +Author: aph +Date: Tue Jun 16 09:44:54 2009 +0000 + + 2009-06-16 Andrew Haley + + * testsuite/libffi.call/err_bad_typedef.c: xfail everywhere. + * testsuite/libffi.call/err_bad_abi.c: Likewise. + +commit 35b6ded138591900a88055a8a8ac1fadc29a76d6 +Author: aph +Date: Fri Jun 12 15:29:20 2009 +0000 + + 2009-06-11 Kaz Kojima + + * testsuite/libffi.call/cls_longdouble_va.c: Add xfail sh*-*-linux-*. + * testsuite/libffi.call/err_bad_abi.c: Add xfail sh*-*-*. + * testsuite/libffi.call/err_bad_typedef.c: Likewise. + +commit acc46605f2d95d67d69398e7644610f10a157ce3 +Author: aph +Date: Fri Jun 12 14:21:28 2009 +0000 + + 2009-06-12 Andrew Haley + + * ChangeLog.libffi: testsuite/libffi.call/cls_align_sint64.c, + testsuite/libffi.call/cls_align_uint64.c, + testsuite/libffi.call/cls_ulonglong.c, + testsuite/libffi.call/return_ll1.c, + testsuite/libffi.call/stret_medium2.c: Fix printf format + specifiers. + testsuite/libffi.special/unwindtest.cc: include stdint.h. + +commit 16d1996ed0797bd7c11aca2b0fe7e7748751aaf6 +Author: twall +Date: Thu Jun 11 14:27:42 2009 +0000 + + update changelog + +commit 92a515c33efe91be3cb0258f01c63aff208489c7 +Author: twall +Date: Thu Jun 11 14:27:28 2009 +0000 + + use ffi_closure_alloc instead of stack-based closure + +commit e4363160ba9e50167f9ca0a7399d537a1d2cd0ce +Author: twall +Date: Thu Jun 11 14:26:23 2009 +0000 + + remove unused extern + +commit 1dc2781d2ba38f5f000ff70069d617fb21e1d2af +Author: twall +Date: Thu Jun 11 11:36:16 2009 +0000 + + remove not-yet-applied changelog entries + +commit bb27735fe689dac97ec0dc847ed8d3d519620109 +Author: twall +Date: Wed Jun 10 10:42:36 2009 +0000 + + add win64 support + +commit b2a54c100c74854a409820817d54617fdda39eb8 +Author: aph +Date: Mon Jun 8 16:50:49 2009 +0000 + + 2009-06-08 Andrew Haley + + * testsuite/libffi.call/err_bad_abi.c: Add xfails. + * testsuite/libffi.call/cls_longdouble_va.c: Add xfails. + * testsuite/libffi.call/cls_dbls_struct.c: Add xfail x86_64-*-linux-*. + * testsuite/libffi.call/err_bad_typedef.c: Add xfails. + + * testsuite/libffi.call/stret_medium2.c: Add __UNUSED__ to args. + * testsuite/libffi.call/stret_medium.c: Likewise. + * testsuite/libffi.call/stret_large2.c: Likewise. + * testsuite/libffi.call/stret_large.c: Likewise. + +commit 25723e7141f73d3736d7244b980c89d97db852b6 +Author: aph +Date: Fri Jun 5 13:03:40 2009 +0000 + + 2009-06-05 Andrew Haley + + * src/x86/win32.S (_ffi_closure_STDCALL): Import from gcc. + +commit 70758199c7cd41f411987360ccb302b497a56dc9 +Author: aph +Date: Thu Jun 4 16:29:58 2009 +0000 + + 2009-06-04 Andrew Haley + + * src/powerpc/ffitarget.h: Fix misapplied merge from gcc. + +commit e8bb12563f9aa23ddf36fa6a5b92b16b5c3e1a7f +Author: aph +Date: Thu Jun 4 14:59:18 2009 +0000 + + 2009-06-04 Andrew Haley + + * src/mips/o32.S, + src/mips/n32.S: Fix licence formatting. + +commit d66a8e32c3671479e3ce0f6819673e5932ba6b7f +Author: aph +Date: Thu Jun 4 14:43:40 2009 +0000 + + 2009-06-04 Andrew Haley + + * src/x86/darwin.S: Fix licence formatting. + src/x86/win32.S: Likewise. + src/sh64/sysv.S: Likewise. + src/sh/sysv.S: Likewise. + +commit 7c3b7fd6b5db746b5b09a718f3044f811372f941 +Author: aph +Date: Thu Jun 4 14:39:20 2009 +0000 + + 2009-06-04 Andrew Haley + + * src/sh64/ffi.c: Remove lint directives. Was missing from merge + of Andreas Tobler's patch from 2006-04-22. + +commit 1a2f93a8b362db13638afd9fcb3f2650180bfa17 +Author: aph +Date: Thu Jun 4 10:45:51 2009 +0000 + + 2009-06-04 Andrew Haley + + * src/sh/ffi.c: Apply missing hunk from Alexandre Oliva's patch of + 2007-03-07. + +commit 944c95cf7aaaaf7c5fa368cda4673dd38f45020e +Author: aph +Date: Wed Jun 3 17:42:56 2009 +0000 + + 2009-05-22 Dave Korn + + * src/x86/win32.S (_ffi_closure_STDCALL): New function. + (.eh_frame): Add FDE for it. + + 2009-05-22 Dave Korn + + * configure.ac: Also check if assembler supports pc-relative + relocs on X86_WIN32 targets. + * configure: Regenerate. + * src/x86/win32.S (ffi_prep_args): Declare extern, not global. + (_ffi_call_SYSV): Add missing function type symbol .def and + add EH markup labels. + (_ffi_call_STDCALL): Likewise. + (_ffi_closure_SYSV): Likewise. + (_ffi_closure_raw_SYSV): Likewise. + (.eh_frame): Add hand-crafted EH data. + + 2008-11-21 Eric Botcazou + + * src/sparc/ffi.c (ffi_prep_cif_machdep): Add support for + signed/unsigned int8/16 return values. + * src/sparc/v8.S (ffi_call_v8): Likewise. + (ffi_closure_v8): Likewise. + + 2008-03-26 Kaz Kojima + + * src/sh/sysv.S: Add .note.GNU-stack on Linux. + * src/sh64/sysv.S: Likewise. + + 2008-03-26 Daniel Jacobowitz + + * src/arm/sysv.S: Fix ARM comment marker. + +commit 00fa972430bb1535a4b34bf029ebcad500027b0c +Author: twall +Date: Sat Dec 27 16:59:05 2008 +0000 + + properly glob-match + +commit f5179e6794ac35af26fe86e468b8508a7a570c55 +Author: twall +Date: Fri Dec 26 19:06:28 2008 +0000 + + Mark XFAIL on longdouble tests for x86_64/mingw + +commit 80e2b5a749208c8a18f994ec5bee84594d051cc8 +Author: twall +Date: Mon Dec 22 15:21:15 2008 +0000 + + clean up tests for win64 use + +commit 7063d9996f742576095c7b0eb5016c0f9a670aec +Author: green +Date: Fri Dec 19 16:13:46 2008 +0000 + + Version 3.0.8 with x86-solaris support + +commit bdfeb13f0df0a63b19d62597517237b54d92228b +Author: green +Date: Fri Dec 19 15:47:44 2008 +0000 + + Bump to 3.0.7 + +commit 69205de17d6ac4c11d4ba92d6a5b40a0c5f246b2 +Author: green +Date: Thu Jul 24 18:03:48 2008 +0000 + + Many test fixes (failures due to excessive compiler warnings). + +commit 260d513fea00b3613fe957a44a157fe72c4ca29e +Author: green +Date: Thu Jul 17 13:13:52 2008 +0000 + + Version 3.0.6. sh/sh64 fixes. + +commit 3704031875feabb74e3655ed03cff4c2b3c76ac6 +Author: green +Date: Thu Apr 3 18:57:57 2008 +0000 + + Rev 3.0.5. + +commit 8406f5f48f7f58a1c982a93a95d521cf82b3241f +Author: green +Date: Thu Apr 3 18:57:34 2008 +0000 + + 3.0.5 + +commit 23a9e73212b62f9684cedb0ce70e92c59cfdaffa +Author: green +Date: Wed Mar 5 00:07:02 2008 +0000 + + 2008-03-04 Anthony Green + Blake Chaffin + hos@tamanegi.org + + * testsuite/libffi.call/cls_align_longdouble_split2.c + testsuite/libffi.call/cls_align_longdouble_split.c + testsuite/libffi.call/cls_dbls_struct.c + testsuite/libffi.call/cls_double_va.c + testsuite/libffi.call/cls_longdouble.c + testsuite/libffi.call/cls_longdouble_va.c + testsuite/libffi.call/cls_pointer.c + testsuite/libffi.call/cls_pointer_stack.c + testsuite/libffi.call/err_bad_abi.c + testsuite/libffi.call/err_bad_typedef.c + testsuite/libffi.call/huge_struct.c + testsuite/libffi.call/stret_large2.c + testsuite/libffi.call/stret_large.c + testsuite/libffi.call/stret_medium2.c + testsuite/libffi.call/stret_medium.c: New tests from Apple. + +commit 429e37d3ad653e52e75bf725c883ab79e859f89a +Author: green +Date: Thu Feb 28 04:50:19 2008 +0000 + + clicky + +commit 51e79c428348c033314f54bcb30f7e388c59e347 +Author: green +Date: Thu Feb 28 04:47:35 2008 +0000 + + getclicky + +commit affcab04e280efeace45a72c4dc6152c0e4f1b7f +Author: green +Date: Tue Feb 26 19:01:53 2008 +0000 + + 2008-02-26 Jakub Jelinek + Anthony Green + + * src/alpha/osf.S: Add .note.GNU-stack on Linux. + * src/s390/sysv.S: Likewise. + * src/powerpc/linux64.S: Likewise. + * src/powerpc/linux64_closure.S: Likewise. + * src/powerpc/ppc_closure.S: Likewise. + * src/powerpc/sysv.S: Likewise. + * src/x86/unix64.S: Likewise. + * src/x86/sysv.S: Likewise. + * src/sparc/v8.S: Likewise. + * src/sparc/v9.S: Likewise. + * src/m68k/sysv.S: Likewise. + * src/ia64/unix.S: Likewise. + * src/arm/sysv.S: Likewise. + +commit 59689d5522c159a3ac967adb6b891cf5f22c890f +Author: green +Date: Tue Feb 26 17:40:51 2008 +0000 + + 2008-02-26 Anthony Green + Thomas Heller + + * src/x86/ffi.c (ffi_closure_SYSV_inner): Change C++ comment to C + comment. + +commit b13c84cf4668828ff8429ba4a2f94cd1eb574ae0 +Author: green +Date: Tue Feb 26 17:38:15 2008 +0000 + + 2008-02-26 Anthony Green + Thomas Heller + + * include/ffi.h.in: Change void (*)() to void (*)(void). + +commit 265289f679ffd24a88ae1aa2cef0e4aa14703cd8 +Author: green +Date: Tue Feb 26 17:34:36 2008 +0000 + + 2008-02-26 Anthony Green + + * src/alpha/ffi.c: Change void (*)() to void (*)(void). + src/alpha/osf.S, src/arm/ffi.c, src/frv/ffi.c, src/ia64/ffi.c, + src/ia64/unix.S, src/java_raw_api.c, src/m32r/ffi.c, + src/mips/ffi.c, src/pa/ffi.c, src/pa/hpux32.S, src/pa/linux.S, + src/powerpc/ffi.c, src/powerpc/ffi_darwin.c, src/raw_api.c, + src/s390/ffi.c, src/sh/ffi.c, src/sh64/ffi.c, src/sparc/ffi.c, + src/x86/ffi.c, src/x86/unix64.S, src/x86/darwin64.S,> src/x86/ffi64.c: Ditto. + +commit fb5036cd6d0f909918e90f7d2d9fd80d46682d5d +Author: green +Date: Sun Feb 24 17:25:25 2008 +0000 + + fix date + +commit 40bec108e7d0181e6c9928aa7a33187bcc0f3d6f +Author: green +Date: Sun Feb 24 17:25:02 2008 +0000 + + New release + +commit b922048fa82ea109a4af269ee47bbc2a586bbac2 +Author: green +Date: Sun Feb 24 17:24:00 2008 +0000 + + 2008-02-24 Anthony Green + + * configure.ac: Accept openbsd*, not just openbsd. + Bump version to 3.0.4. + * configure, doc/stamp-vti, doc/version.texi: Rebuilt. + * libtool-version: Increment revision. + * README: Update for new release. + +commit affca4b92d06e5554784c7e9b233029ef83f7d8a +Author: green +Date: Fri Feb 22 21:53:29 2008 +0000 + + sync readme with web page. + +commit 3e53d8752ea74859b4c64fbbf935e62a937c4d78 +Author: green +Date: Fri Feb 22 21:52:38 2008 +0000 + + New release + +commit 4d92f6c8e78fe084be65f3e8b58b859901ba796d +Author: green +Date: Fri Feb 22 21:49:46 2008 +0000 + + 2008-02-22 Anthony Green + + * configure.ac: Bump version to 3.0.3. + * configure, doc/stamp-vti, doc/version.texi: Rebuilt. + * libtool-version: Increment revision. + * README: Update for new release. Clean up test docs. + +commit 0e185fa11a01f816824ba2687ed3715ab6219bef +Author: green +Date: Fri Feb 22 21:43:18 2008 +0000 + + Update configure script. + +commit f73986bd211cfbbaa593d1309504d0dc68626191 +Author: green +Date: Fri Feb 22 21:40:53 2008 +0000 + + 2008-02-22 Bjoern Koenig + Andreas Tobler + + * configure.ac: Add amd64-*-freebsd* target. + * configure: Regenerate. + +commit 0208f68fe5de30c33e7f70ebc281635917013f5a +Author: green +Date: Fri Feb 22 21:15:44 2008 +0000 + + 2008-02-22 Thomas Heller + + * configure.ac: Add x86 OpenBSD support. + * configure: Rebuilt. + +commit 01adb0e638a86cf0d5e668ed8e08be9b0cd2505f +Author: green +Date: Thu Feb 21 16:17:26 2008 +0000 + + Fix README. + +commit 1edd4563225981a14f7d4fb9919b1ed88e38082f +Author: green +Date: Thu Feb 21 13:39:01 2008 +0000 + + 3.0.2 + +commit c9b542800864e2204db6e83f3843a17813ba6165 +Author: green +Date: Thu Feb 21 13:36:43 2008 +0000 + + add missing file + +commit d5fa5633d5c8d3c212a2267cfa38fba4091baa2c +Author: green +Date: Thu Feb 21 13:36:19 2008 +0000 + + 2008-02-21 Anthony Green + + * configure.ac: Bump version to 3.0.2. + * configure, doc/stamp-vti, doc/version.texi: Rebuilt. + * libtool-version: Increment revision. + * README: Update for new release. + + 2008-02-21 Björn König + + * src/x86/freebsd.S: New file. + * configure.ac: Add x86 FreeBSD support. + * Makefile.am: Ditto. + +commit ac35bfc6fcadd8880c1efce36724820f9074b318 +Author: green +Date: Sat Feb 16 01:03:56 2008 +0000 + + Updated + +commit f7942975fee7b0162647dd79e2652615b737e98e +Author: green +Date: Sat Feb 16 01:02:00 2008 +0000 + + 2008-02-15 Anthony Green + + * configure.ac: Bump version to 3.0.1. + * configure, doc/stamp-vti, doc/version.texi: Rebuilt. + * libtool-version: Increment revision. + * README: Update for new release. + + 2008-02-15 David Daney + + * src/mips/ffi.c: Remove extra '>' from include directive. + (ffi_prep_closure_loc): Use clear_location instead of tramp. + +commit 59aa6bb1bfc86a610ac1a8b123443efd75854dd1 +Author: green +Date: Fri Feb 15 20:52:26 2008 +0000 + + Add more platforms. + +commit 45a45ab99074448be0ae1a8d2ade50d28b60f8de +Author: green +Date: Fri Feb 15 19:16:36 2008 +0000 + + 3.0 notes + +commit 4db74cbea888c9f1251b85baf00d99b83d3b994d +Author: green +Date: Fri Feb 15 19:10:26 2008 +0000 + + Update + +commit c3e1101ffabf44d8a2ee46e03ba9ab582050a825 +Author: green +Date: Fri Feb 15 18:43:40 2008 +0000 + + 2008-02-15 Anthony Green + + * configure.ac: Bump version to 3.0.0, + * configure, doc/stamp-vti, doc/version.texi: Rebuilt. + + 2008-02-15 David Daney + + * src/mips/ffi.c (USE__BUILTIN___CLEAR_CACHE): + Define (conditionally), and use it to include cachectl.h. + (ffi_prep_closure_loc): Fix cache flushing. + * src/mips/ffitarget.h (_ABIN32, _ABI64, _ABIO32): Define. + +commit 7e0cc12e9233ad285db41ce8dbdda61ed2a7fb06 +Author: green +Date: Fri Feb 15 15:51:03 2008 +0000 + + New release + +commit 2d7dc885ec40d53866f29984d595511942c8b686 +Author: green +Date: Fri Feb 15 15:30:26 2008 +0000 + + * man/ffi_call.3, man/ffi_prep_cif.3, man/ffi.3: + Update dates and remove all references to ffi_prep_closure. + * configure.ac: Bump version to 2.99.9. + * configure, doc/stamp-vti, doc/version.texi: Rebuilt. + +commit a0525f03eeaaed33b1eac80e0c016455cee3615d +Author: green +Date: Fri Feb 15 15:14:30 2008 +0000 + + New release. + +commit 2b30dfb3146ee26ad956d00ee05eb835ca1a95b4 +Author: green +Date: Fri Feb 15 15:12:43 2008 +0000 + + * man/ffi_prep_closure.3: Delete. + * man/Makefile.am (EXTRA_DIST): Remove ffi_prep_closure.3. + (man_MANS): Ditto. + * man/Makefile.in: Rebuilt. + * configure.ac: Bump version to 2.99.8. + * configure, doc/stamp-vti, doc/version.texi: Rebuilt. + +commit bf41e64840ebcb6cc31a6f028253c1fde82705d8 +Author: green +Date: Fri Feb 15 01:56:50 2008 +0000 + + Update. + +commit 4d39ddee677bbb61d621893b91e11eac5e7c4af7 +Author: green +Date: Fri Feb 15 01:24:06 2008 +0000 + + * configure.ac: Bump version to 2.99.7. + * configure, doc/stamp-vti, doc/version.texi: Rebuilt. + * include/ffi.h.in LICENSE src/debug.c src/closures.c + src/ffitest.c src/s390/sysv.S src/s390/ffitarget.h + src/types.c src/m68k/ffitarget.h src/raw_api.c src/frv/ffi.c + src/frv/ffitarget.h src/sh/ffi.c src/sh/sysv.S + src/sh/ffitarget.h src/powerpc/ffitarget.h src/pa/ffi.c + src/pa/ffitarget.h src/pa/linux.S src/java_raw_api.c + src/cris/ffitarget.h src/x86/ffi.c src/x86/sysv.S + src/x86/unix64.S src/x86/win32.S src/x86/ffitarget.h + src/x86/ffi64.c src/x86/darwin.S src/ia64/ffi.c + src/ia64/ffitarget.h src/ia64/ia64_flags.h src/ia64/unix.S + src/sparc/ffi.c src/sparc/v9.S src/sparc/ffitarget.h + src/sparc/v8.S src/alpha/ffi.c src/alpha/ffitarget.h + src/alpha/osf.S src/sh64/ffi.c src/sh64/sysv.S + src/sh64/ffitarget.h src/mips/ffi.c src/mips/ffitarget.h + src/mips/n32.S src/mips/o32.S src/arm/ffi.c src/arm/sysv.S + src/arm/ffitarget.h src/prep_cif.c: Update license text. + +commit d58b032b41a12bd3d72148da6822ab59dd698ff9 +Author: green +Date: Fri Feb 15 00:59:25 2008 +0000 + + New release + +commit 91e5478df6d5ac63efbb10f025807b4606afab56 +Author: green +Date: Fri Feb 15 00:50:30 2008 +0000 + + Update supported platforms. Bump version. + +commit bd0768f877c8f7fd0d36af2191b203d4d057b1ce +Author: green +Date: Fri Feb 15 00:45:33 2008 +0000 + + * configure.ac: Bump version to 2.99.5. + * configure: Rebuilt. + * Makefile.am (EXTRA_DIST): Add darwin64.S + * Makefile.in: Rebuilt. + * testsuite/lib/libffi-dg.exp: Remove libstdc++ bits from GCC tree. + * LICENSE: Update WARRANTY. + +commit 49d345f767bd2cfee951bceaab6a1a07986cf293 +Author: green +Date: Thu Feb 14 23:43:27 2008 +0000 + + update license reference + +commit 12ac48fc79b515db7c9accd9fcaa87b0dcefccdb +Author: green +Date: Thu Feb 14 23:42:08 2008 +0000 + + Update WARRANTY + +commit 6b91c41da87e78552f2990dfc504a0a3349f340b +Author: green +Date: Thu Feb 14 23:38:27 2008 +0000 + + fix tarball reference + +commit 2b59579e3533334bee4788e076b4e520c2ab518c +Author: green +Date: Thu Feb 14 23:35:58 2008 +0000 + + First update in 5 years! + +commit 6cbdf3f3a3777a93382a2d508ddef1c353ff0955 +Author: green +Date: Thu Feb 14 22:44:06 2008 +0000 + + Fix .pc file bug and bump version + +commit 1d1dc81104b209df3cfef0840735c59efae2f655 +Author: green +Date: Thu Feb 14 22:03:37 2008 +0000 + + Add man files and info file. Update README. Tag as 2.99.3. + +commit f045a2367f793fa8b01534cf2e25bcc46afc8fa1 +Author: tromey +Date: Thu Feb 14 20:46:57 2008 +0000 + + Move entry from ChangeLog to ChangeLog.libffi + +commit 6257f07d1a9efd27fa83639cfba281f5d3188731 +Author: tromey +Date: Thu Feb 14 20:33:17 2008 +0000 + + * aclocal.m4, Makefile.in, configure, fficonfig.h.in: Rebuilt. + * mdate-sh, texinfo.tex: New files. + * Makefile.am (info_TEXINFOS): New variable. + * doc/libffi.texi: New file. + * doc/version.texi: Likewise. + +commit 4232af563c5509c3760a33e3684a2b958be755e1 +Author: green +Date: Thu Feb 14 16:19:21 2008 +0000 + + * Makefile.am (AM_CFLAGS): Don't compile with -D. + (lib_LTLIBRARIES): Define. + (toolexeclib_LIBRARIES): Undefine. + * Makefile.in: Rebuilt. + * configure.ac: Reset version to 2.99.1. + * configure.in: Rebuilt. + +commit 961543615c31f092b578a4b4cda914db64f9d0fa +Author: green +Date: Thu Feb 14 15:57:40 2008 +0000 + + Fix typo. + +commit aeb0abab87222f637fbf352d4effd3b76b52ed26 +Author: green +Date: Thu Feb 14 15:54:27 2008 +0000 + + * libffi.pc.in: Usse @PACKAGE_NAME@ and @PACKAGE_VERSION@. + * configure.ac: Reset version to 2.99.1. + * configure.in: Rebuilt. + * Makefile.am (EXTRA_DIST): Add ChangeLog.libffi. + * Makefile.in: Rebuilt. + * LICENSE: Update copyright notice. + +commit 77fe243556433eae119d8bd7469bfccdd5bd8a1a +Author: green +Date: Thu Feb 14 15:37:00 2008 +0000 + + Fix make dist again + +commit d4970cf4529459bf0f0e43c602cac396786c6802 +Author: green +Date: Thu Feb 14 15:18:56 2008 +0000 + + Fix make dist + +commit f0b1462f2d3024922ad71421bd5c4311fcb16da5 +Author: green +Date: Thu Feb 14 15:01:41 2008 +0000 + + Use pkgconfig. Increment libtool CURRENT version. + +commit 27e52f33baa069012a5adb2a3807f9ca1f2165ab +Author: green +Date: Sun Feb 3 13:59:48 2008 +0000 + + Fix header installs when using DESTDIR. + +commit fadab28eb6e33fb6dcdd7b9323e147142216d548 +Author: twall +Date: Sun Feb 3 12:32:22 2008 +0000 + + update changelog + +commit b5e44c8dfa92c87b99762c303cf5574a16db8f27 +Author: twall +Date: Sun Feb 3 01:12:32 2008 +0000 + + offset from code base address, not data base address + +commit f359848d1a995c0e44566d815f218729dc996e22 +Author: green +Date: Fri Feb 1 21:29:43 2008 +0000 + + Fix header installs. + +commit c30df49e157c7bfc8e19e3f8a72b9464fe225e54 +Author: green +Date: Fri Feb 1 21:13:55 2008 +0000 + + Revert my broken changes to twall's patch. + +commit 675561bb9aa0732c76698df10dd3007b5d0ec759 +Author: green +Date: Thu Jan 31 13:44:25 2008 +0000 + + Fix make dist . + +commit abc0bbf3813dc43e23d4c23e6fe794dbf287639b +Author: green +Date: Thu Jan 31 11:58:57 2008 +0000 + + Add Tim Wall's x86 windows patch. + +commit e332366d15a31198735b593ec8f7fc0558d783b8 +Author: green +Date: Wed Jan 30 13:21:02 2008 +0000 + + Add HJ's -fomit-frame-pointer struct return fix + +commit d4204240392af5b7750a08671b08e9c22dff5e93 +Author: green +Date: Wed Jan 30 12:42:34 2008 +0000 + + Clean up for new automake. + +commit f4932dd020df574637c9fb3fc1bb18e5a8f304cc +Author: green +Date: Wed Jan 30 12:40:25 2008 +0000 + + Fixes to run testsuite + +commit 085520ddc8db6a916bfc416b871fcb2d00074d40 +Author: green +Date: Tue Jan 29 15:16:43 2008 +0000 + + New files from gcc tree. + +commit 77175b3f7234e4875a4ef554ed1fe9fdc4133794 +Author: green +Date: Tue Jan 29 15:15:20 2008 +0000 + + Latest gcc svn sources + +commit 2544e45a0b2b634053df02da3a2ed9680eeed2a1 +Author: green +Date: Tue Jan 29 14:28:13 2008 +0000 + + Install ffitarget.h in $prefix/include. + +commit 6002211b1cc4daeb587d054b4f83968bda2c981e +Author: green +Date: Tue Jan 29 12:30:10 2008 +0000 + + Add new files. + +commit ccabd2b16be883cd03e5f0cd88ccfdd6ca39239d +Author: green +Date: Tue Jan 29 12:28:15 2008 +0000 + + Merge from gcc + +commit e680ecfbfca1da8d1823e48bc89b8375e66e128b +Author: tromey +Date: Sun Dec 24 23:12:15 2006 +0000 + + Pulled in libffi from gcc trunk. + Fixed build and install for standalone use. + +commit e7ba08965942ce872fdbc69f70f9848cc3d0bad6 +Author: root +Date: Sun Jun 4 23:22:24 2006 +0000 + + sourcware.org + +commit 0cd4aa24e21aaa964dfbdebc25ec5c8188049375 +Author: root +Date: Sun May 30 01:51:57 2004 +0000 + + Add LockDir + +commit 5826120fbd940d26cca76ed2522187505581e1ed +Author: green +Date: Tue Nov 4 06:09:08 2003 +0000 + + Add link to Gianni's web site. + +commit 220aa4b27db42d7ffaac5056000d5179f00d5ea3 +Author: jsm +Date: Tue Jan 21 08:07:42 2003 +0000 + + Newer, better, increased from before! (list of acceptable anon usernames) + +commit 1c3adc892cc1403dc4d3d7003a2385899836612e +Author: green +Date: Fri Dec 6 01:28:03 2002 +0000 + + Fixed Cygnus references. + +commit 4af66bb62fab9a8e318af3bf01e5486596a0c8d4 +Author: green +Date: Sun Oct 21 19:18:42 2001 +0000 + + Testsuite fixes. + +commit 5435965f9015ce40584c98d3816c3d05e7de1d21 +Author: green +Date: Mon Apr 23 00:32:03 2001 +0000 + + * include/ffi_common.h: Delete, after moving contents to... + * include/ffi_private.h: Subsume contents of ffi_common.h. + * include/Makefile.am (noinst_HEADERS): Remove ffi_common.h. + * include/Makefile.in: Rebuilt. + * arm/ffi.c, m68k/ffi.c, mips/ffi.c, powerpc/ffi.c, s390/ffi.c, + ia64/ffi.c: Include ffi_private.h, not ffi_common.h. + * alpha/ffi.c, sparc/ffi.c, x86/ffi.c: Don't include ffi_common.h. + * types.c, raw_api.c, java_raw_api.c, prep_cif.c: Don't include + ffi_common.h. + * debug.c: Include ffi_private.h instead of ffi_common.h. + + * mips/ffi.c (calc_n32_struct_flags): Make static. + (FIX_ARGP): Remove call to debugging routine ffi_stop_here. + + * mips/n32.S: Include ffi_private.h. + * mips/o32.S: Include ffi_private.h. + +commit 6fdb7de0fe3b7385e1fd78812ae69d9b3069d994 +Author: green +Date: Sun Apr 22 19:38:34 2001 +0000 + + * README: Update some comments. + + * Makefile.am (SUBDIRS): Add include so ffi.h gets installed. + * Makefile.in: Rebuilt. + + * include/ffi.h: Change ALPHA to __alpha__ and SPARC to __sparc__. + * types.c: Ditto. + * prep_cif.c (ffi_prep_cif): Ditto. + + * alpha/ffi.c, alpha/osf.S, sparc/ffi.c, sparc/v8.S, sparc/v9.S: + Include ffi_private.h. + + * include/ffi_private.h (FFI_TYPE_LAST): Define. + +commit bc7144b01b9707ef35f1a2e3e6996e005e82953a +Author: green +Date: Sun Apr 22 18:28:36 2001 +0000 + + Moved files from old home + +commit e57279831e20368c1aa1d2b35462b8629be73959 +Author: green +Date: Sun Apr 22 18:23:47 2001 +0000 + + These are dead. + +commit 7247436b5fe71767b29dc02b4da0fe18b08082e6 +Author: green +Date: Sun Apr 22 18:22:43 2001 +0000 + + All these files live somewhere else now. + +commit a8b0d40ff908e275028f676870c31d0d70274a98 +Author: green +Date: Sun Apr 22 18:17:14 2001 +0000 + + Many changes. Not quite there yet. + +commit f893d2273355710a290a26faebf5f12c3a34d0e3 +Author: green +Date: Sun Apr 22 18:13:22 2001 +0000 + + Moved m68k files + +commit 688ddfeced89cbb9d37b53005e1f7f2b9c78a8d7 +Author: green +Date: Sun Apr 22 18:12:33 2001 +0000 + + New, target indepentent, header + +commit f9e40776d488d5ecf43b3ae21444a1a2f6eca528 +Author: green +Date: Sun Apr 22 18:11:57 2001 +0000 + + Many changes. + +commit 8c1d2eb47f6bc314c431b75c85c107e8e43c4a76 +Author: green +Date: Sun Apr 22 18:10:47 2001 +0000 + + Many changes + +commit 1359dfc6582680a158b3caa3efb7a368da4aa12d +Author: green +Date: Sun Apr 22 18:10:20 2001 +0000 + + Moved ia64 files + +commit 6e2de5eee316a4579869aff50c7c5f6f478582d8 +Author: green +Date: Sun Apr 22 18:08:11 2001 +0000 + + Moved arm files + +commit 8807355af34cba8ffe87aee51152dfccec2771fa +Author: green +Date: Mon Apr 9 00:58:38 2001 +0000 + + Many many updates. Merge from gcc and then some. + +commit f7e9f91adec4ff1c2e7a13b3de81d2c5a3f55e7e +Author: green +Date: Mon Apr 17 03:32:37 2000 +0000 + + Mnay fixes. + +commit c4860de618f4956283f5c8230a2544e403dfe390 +Author: green +Date: Mon Apr 17 03:18:46 2000 +0000 + + Merge from libgcj. Merged patches from net. See ChangeLog for details. + +commit c578b58314990c3853429297c38ba14015fec5fa +Author: jsm +Date: Sat Oct 9 20:18:16 1999 +0000 + + 1999-10-09 Jason Molenda (jsm@bugshack.cygnus.com) + + * CVSROOT/auto_checkout, CVSROOT/commit_prep, CVSROOT/log_accum: + Deleted; generic versions now used for all repositories. + + * CVSROOT/commitinfo, CVSROOT/loginfo: Change pathnames to + generic versions. + + * CVSROOT/checkoutlist: Don't try to check out the removed + files any longer. + +commit acdb20051207fed7652dd9f122f65de5458c474c +Author: jsm +Date: Sat Oct 9 20:18:15 1999 +0000 + + 1999-10-09 Jason Molenda (jsm@bugshack.cygnus.com) + + * CVSROOT/auto_checkout, CVSROOT/commit_prep, CVSROOT/log_accum: + Deleted; generic versions now used for all repositories. + + * CVSROOT/commitinfo, CVSROOT/loginfo: Change pathnames to + generic versions. + + * CVSROOT/checkoutlist: Don't try to check out the removed + files any longer. + +commit e75be655ceedf7ab24c4e99d75eec9efeb979bc7 +Author: green +Date: Sun Aug 8 13:16:41 1999 +0000 + + New configury + +commit d6669a0dd5b266005325bbf6d5a8ff34574d809e +Author: green +Date: Sun Aug 8 13:05:12 1999 +0000 + + * include/ffi.h.in: Try to work around messy header problem + with PACKAGE and VERSION. + + * configure: Rebuilt. + * configure.in: Change version to 2.00-beta. + + * fficonfig.h.in: Rebuilt. + * acconfig.h (FFI_NO_STRUCTS, FFI_NO_RAW_API): Define. + + * src/x86/ffi.c (ffi_raw_call): Rename. + +commit 4819d52b007934a40d6d29a75ee30e857c4a93ae +Author: green +Date: Wed Aug 4 18:02:34 1999 +0000 + + New file for Kresten's closure work + +commit 2dbf801eb427cbf5021a9e1e512b5fc523524700 +Author: green +Date: Wed Aug 4 18:00:05 1999 +0000 + + Kresten's closure work. Initial checkin. + +commit d170961701b0f2bf7e824d7caba2ebe10002ed84 +Author: green +Date: Thu Jul 8 14:36:52 1999 +0000 + + * configure.in: Add x86 and powerpc BeOS configurations. + From Makoto Kato . + +commit c7747d976924ec6f2229cbcfbbdb98d364e10de9 +Author: jsm +Date: Wed May 12 23:32:16 1999 +0000 + + 1999-05-12 Jason Molenda (jsm@bugshack.cygnus.com) + * index.html: Add links to libffi* mail list archives. + +commit dd2aa9a8de22e26df3bbc85d068358641f6202f7 +Author: green +Date: Thu May 6 05:34:36 1999 +0000 + + * configure.in: Add warning about this being beta code. + Remove src/Makefile.am from the picture. + * configure: Rebuilt. + * Makefile.am: Move logic from src/Makefile.am. Add changes + to support libffi as a target library. + * Makefile.in: Rebuilt. + * aclocal.m4, config.guess, config.sub, ltconfig, ltmain.sh: + Upgraded to new autoconf, automake, libtool. + * README: Tweaks. + * LICENSE: Update copyright date. + * src/Makefile.am, src/Makefile.in: Removed. + +commit 4e9452abed58a3058ccdb446f96a29d50dda1f34 +Author: green +Date: Wed May 5 22:06:13 1999 +0000 + + Updated to new automake, libtool, autoconf - nothing works :-) + +commit 6d3b2bddaf4967fba8b8656c01bfc77ec0f2800c +Author: jsm +Date: Mon Apr 26 15:55:28 1999 +0000 + + 1999-04-26 Jason Molenda (jsm@bugshack.cygnus.com) + * index.html: Missed a reference to libffi-discuss@cygnus.com. Fixed. + +commit ebc6a9c28af831d3d187af8ff17319f0f309bd98 +Author: jsm +Date: Mon Apr 26 15:53:29 1999 +0000 + + 1999-04-26 Jason Molenda (jsm@bugshack.cygnus.com) + * index.html: Change links to ftp directory to point to sourceware + directory. + Change mailing list subscription forms to point to sourceware lists. + +commit 78ffc52a8b257061348c576ccb6fbbf8b48b0fff +Author: jsm +Date: Sun Apr 18 01:33:21 1999 +0000 + + Standard sourceware setup. + +commit b4d77e827d7ebef7e57ebcd71e71c15c62f1e0a8 +Author: jsm +Date: Mon Nov 30 11:11:25 1998 +0000 + + Small typeo. (I wouldn't bother except that it made the sentence hard + for me to parse on a casual read.) + +commit bfb73f08fdc987e37070c5fb0b196fbd28872888 +Author: jsm +Date: Mon Nov 30 10:44:55 1998 +0000 + + A few cleanups. Most notably, point to the correct subscribe cgi-bin + script. + +commit af8b7f037ccee3b7939ee226a1a2bbc2f057b35c +Author: green +Date: Mon Nov 30 06:20:05 1998 +0000 + + * index.html: Reformatted and updated to reflect hosting on + sourceware.cygnus.com (new mailing lists, etc). + +commit 334f0b060942aff8d26badaf7dde7830450dc5da +Author: green +Date: Sun Nov 29 16:56:12 1998 +0000 + + initial snapshot of documentation + +commit 3ab5cb4a1dcc7ecd7e773c97582b0099976c4753 +Author: green +Date: Sun Nov 29 16:56:10 1998 +0000 + + Initial revision + +commit d2a9eb5a8b7cbc8b769809cad59c82b975c178e2 +Merge: d3782ec bc75c54 +Author: green +Date: Sun Nov 29 16:48:16 1998 +0000 + + This commit was generated by cvs2svn to compensate for changes in r7, which + included commits to RCS files with non-trunk default branches. + +commit bc75c54bd311658005b065f1bf201b204c81cbca +Author: green +Date: Sun Nov 29 16:48:16 1998 +0000 + + Import of v1 code. + +commit d3782ec8160c644421dcea17b605fec6e328f14e +Author: jsm +Date: Fri Nov 20 20:18:00 1998 +0000 + + Send commit messages to mailing lists. + +commit 8d8d3843c484c2bb70d8375b2b799f75eb03f709 +Author: jsm +Date: Thu Oct 1 22:08:36 1998 +0000 + + initial checkin + +commit 49634f3bf221cc1939abafc788f7e4e31293fe73 +Author: jsm +Date: Thu Oct 1 22:08:35 1998 +0000 + + Add standard setup. + +commit c64a84c7693f8cd400fb94bba3c9bcfd9ad1fc36 +Author: jsm +Date: Thu Oct 1 22:08:34 1998 +0000 + + Add readers and standard modules file. + +commit 9813273b07fd082da573b3b6bfb8d23809b59eea +Author: jsm +Date: Thu Oct 1 22:08:33 1998 +0000 + + initial checkin diff --git a/Modules/_ctypes/libffi/ChangeLog.libffi-3.1 b/Modules/_ctypes/libffi/ChangeLog.libffi-3.1 new file mode 100644 index 000000000000..8f7f50d6f993 --- /dev/null +++ b/Modules/_ctypes/libffi/ChangeLog.libffi-3.1 @@ -0,0 +1,6000 @@ +2014-03-16 Josh Triplett + + * ChangeLog: Archive to ChangeLog.libffi-3.1 and delete. Future + changelogs will come from git, with autogenerated snapshots shipped in + distributed tarballs. + +2014-03-16 Josh Triplett + + Add support for stdcall, thiscall, and fastcall on non-Windows + x86-32. + + Linux supports the stdcall calling convention, either via + functions explicitly declared with the stdcall attribute, or via + code compiled with -mrtd which effectively makes stdcall the + default. + + This introduces FFI_STDCALL, FFI_THISCALL, and FFI_FASTCALL on + non-Windows x86-32 platforms, as non-default calling conventions. + + * Makefile.am: Compile in src/x86/win32.S on non-Windows x86-32. + * src/x86/ffitarget.h: Add FFI_STDCALL, FFI_THISCALL, and + FFI_FASTCALL on non-Windows x86-32. Increase trampoline size to + accomodate these calling conventions, and unify some ifdeffery. + * src/x86/ffi.c: Add support for FFI_STDCALL, FFI_THISCALL, and + FFI_FASTCALL on non-Windows x86-32 platforms; update ifdeffery. + * src/x86/win32.S: Support compiling on non-Windows x86-32 + platforms. On those platforms, avoid redefining the SYSV symbols + already provided by src/x86/sysv.S. + * testsuite/libffi.call/closure_stdcall.c: Run on non-Windows. + #define __stdcall if needed. + * testsuite/libffi.call/closure_thiscall.c: Run on non-Windows. + #define __fastcall if needed. + * testsuite/libffi.call/fastthis1_win32.c: Run on non-Windows. + * testsuite/libffi.call/fastthis2_win32.c: Ditto. + * testsuite/libffi.call/fastthis3_win32.c: Ditto. + * testsuite/libffi.call/many2_win32.c: Ditto. + * testsuite/libffi.call/many_win32.c: Ditto. + * testsuite/libffi.call/strlen2_win32.c: Ditto. + * testsuite/libffi.call/strlen_win32.c: Ditto. + * testsuite/libffi.call/struct1_win32.c: Ditto. + * testsuite/libffi.call/struct2_win32.c: Ditto. + +2014-03-16 Josh Triplett + + * prep_cif.c: Remove unnecessary ifdef for X86_WIN32. + ffi_prep_cif_core had a special case for X86_WIN32, checking for + FFI_THISCALL in addition to the FFI_FIRST_ABI-to-FFI_LAST_ABI + range before returning FFI_BAD_ABI. However, on X86_WIN32, + FFI_THISCALL already falls in that range, making the special case + unnecessary. Remove it. + +2014-03-16 Josh Triplett + + * testsuite/libffi.call/closure_stdcall.c, + testsuite/libffi.call/closure_thiscall.c: Remove fragile stack + pointer checks. These files included inline assembly to save the + stack pointer before and after the call, and compare the values. + However, compilers can and do leave the stack in different states + for these two pieces of inline assembly, such as by saving a + temporary value on the stack across the call; observed with gcc + -Os, and verified as spurious through careful inspection of + disassembly. + +2014-03-16 Josh Triplett + + * testsuite/libffi.call/many.c: Avoid spurious failure due to + excess floating-point precision. + * testsuite/libffi.call/many_win32.c: Ditto. + +2014-03-16 Josh Triplett + + * libtool-ldflags: Re-add. + +2014-03-16 Josh Triplett + + * Makefile.in, aclocal.m4, compile, config.guess, config.sub, + configure, depcomp, include/Makefile.in, install-sh, + libtool-ldflags, ltmain.sh, m4/libtool.m4, m4/ltoptions.m4, + m4/ltsugar.m4, m4/ltversion.m4, m4/lt~obsolete.m4, + man/Makefile.in, mdate-sh, missing, testsuite/Makefile.in: Delete + autogenerated files from version control. + * .gitignore: Add autogenerated files. + * autogen.sh: New script to generate the autogenerated files. + * README: Document requirement to run autogen.sh when building + directly from version control. + * .travis.yml: Run autogen.sh + +2014-03-14 Anthony Green + + * configure, Makefile.in: Rebuilt. + +2014-03-10 Mike Hommey + + * configure.ac: Allow building for mipsel with Android NDK r8. + * Makefile.am (AM_MAKEFLAGS): Replace double quotes with single + quotes. + +2014-03-10 Landry Breuil + + * configure.ac: Ensure the linker supports @unwind sections in libffi. + +2014-03-01 Anthony Green + + * Makefile.am (EXTRA_DIST): Replace old scripts with + generate-darwin-source-and-headers.py. + * Makefile.in: Rebuilt. + +2014-02-28 Anthony Green + + * Makefile.am (AM_CFLAGS): Reintroduce missing -DFFI_DEBUG for + --enable-debug builds. + * Makefile.in: Rebuilt. + +2014-02-28 Makoto Kato + + * src/closures.c: Fix build failure when using clang for Android. + +2014-02-28 Marcin Wojdyr + + * libffi.pc.in (toolexeclibdir): use -L${toolexeclibdir} instead + of -L${libdir}. + +2014-02-28 Paulo Pizarro + + * src/bfin/sysv.S: Calling functions in shared libraries requires + considering the GOT. + +2014-02-28 Josh Triplett + + * src/x86/ffi64.c (classify_argument): Handle case where + FFI_TYPE_LONGDOUBLE == FFI_TYPE_DOUBLE. + +2014-02-28 Anthony Green + + * ltmain.sh: Generate with libtool-2.4.2.418. + * m4/libtool.m4, m4/ltoptions.m4, m4/ltversion.m4: Ditto. + * configure: Rebuilt. + +2014-02-28 Dominik Vogt + + * configure.ac (AC_ARG_ENABLE struct): Fix typo in help + message. + (AC_ARG_ENABLE raw_api): Ditto. + * configure, fficonfig.h.in: Rebuilt. + +2014-02-28 Will Newton + + * src/arm/sysv.S: Initialize IP register with FP. + +2014-02-28 Yufeng Zhang + + * src/aarch64/sysv.S (ffi_closure_SYSV): Use x29 as the + main CFA reg; update cfi_rel_offset. + +2014-02-15 Marcus Comstedt + + * src/powerpc/ffi_linux64.c, src/powerpc/linux64_closure.S: Remove + assumption on contents of r11 in closure. + +2014-02-09 Heiher + + * src/mips/n32.S: Fix call floating point va function. + +2014-01-21 Zachary Waldowski + + * src/aarch64/ffi.c: Fix missing semicolons on assertions under + debug mode. + +2013-12-30 Zachary Waldowski + + * .gitignore: Exclude darwin_* generated source and build_* trees. + * src/aarch64/ffi.c, src/arm/ffi.c, src/x86/ffi.c: Inhibit Clang + previous prototype warnings. + * src/arm/ffi.c: Prevent NULL dereference, fix short type warning + * src/dlmalloc.c: Fix warnings from set_segment_flags return type, + and the native use of size_t for malloc on platforms + * src/arm/sysv.S: Use unified syntax. Clang clean-ups for + ARM_FUNC_START. + * generate-osx-source-and-headers.py: Remove. + * build-ios.sh: Remove. + * libffi.xcodeproj/project.pbxproj: Rebuild targets. Include + x86_64+aarch64 pieces in library. Export headers properly. + * src/x86/ffi64.c: More Clang warning clean-ups. + * src/closures.c (open_temp_exec_file_dir): Use size_t. + * src/prep_cif.c (ffi_prep_cif_core): Cast ALIGN result. + * src/aarch64/sysv.S: Use CNAME for global symbols. Only use + .size for ELF targets. + * src/aarch64/ffi.c: Clean up for double == long double. Clean up + from Clang warnings. Use Clang cache invalidation builtin. Use + size_t in place of unsigned in many places. Accommodate for + differences in Apple AArch64 ABI. + +2013-12-02 Daniel Rodríguez Troitiño + + * generate-darwin-source-and-headers.py: Clean up, modernize, + merged version of previous scripts. + +2013-11-21 Anthony Green + + * configure, Makefile.in, include/Makefile.in, include/ffi.h.in, + man/Makefile.in, testsuite/Makefile.in, fficonfig.h.in: Rebuilt. + +2013-11-21 Alan Modra + + * Makefile.am (EXTRA_DIST): Add new src/powerpc files. + (nodist_libffi_la_SOURCES ): Likewise. + * configure.ac (HAVE_LONG_DOUBLE_VARIANT): Define for powerpc. + * include/ffi.h.in (ffi_prep_types): Declare. + * src/prep_cif.c (ffi_prep_cif_core): Call ffi_prep_types. + * src/types.c (FFI_NONCONST_TYPEDEF): Define and use for + HAVE_LONG_DOUBLE_VARIANT. + * src/powerpc/ffi_powerpc.h: New file. + * src/powerpc/ffi.c: Split into.. + * src/powerpc/ffi_sysv.c: ..new file, and.. + * src/powerpc/ffi_linux64.c: ..new file, rewriting parts. + * src/powerpc/ffitarget.h (enum ffi_abi): Rewrite powerpc ABI + selection as bits controlling features. + * src/powerpc/linux64.S: For consistency, use POWERPC64 rather + than __powerpc64__. + * src/powerpc/linux64_closure.S: Likewise. + * src/powerpc/ppc_closure.S: Likewise. Move .note.FNU-stack + inside guard. + * src/powerpc/sysv.S: Likewise. + * configure: Regenerate. + * fficonfig.h.in: Regenerate. + * Makefile.in: Regenerate. + +2013-11-20 Alan Modra + + * src/powerpc/ffi.c (ffi_prep_cif_machdep_core): Use + NUM_FPR_ARG_REGISTERS64 and NUM_GPR_ARG_REGISTERS64 not their + 32-bit versions for 64-bit code. + * src/powerpc/linux64_closure.S: Don't use the return value area + as a parameter save area on ELFv2. + +2013-11-18 Iain Sandoe + + * src/powerpc/darwin.S (EH): Correct use of pcrel FDE encoding. + * src/powerpc/darwin_closure.S (EH): Likewise. Modernise picbase + labels. + +2013-11-18 Anthony Green + + * src/arm/ffi.c (ffi_call): Hoist declaration of temp to top of + function. + * src/arm/ffi.c (ffi_closure_inner): Moderize function declaration + to appease compiler. + Thanks for Gregory P. Smith . + +2013-11-18 Anthony Green + + * README (tested): Mention PowerPC ELFv2. + +2013-11-16 Alan Modra + + * src/powerpc/ppc_closure.S: Move errant #endif to where it belongs. + Don't bl .Luint128. + +2013-11-16 Alan Modra + + * src/powerpc/ffi.c (ffi_prep_cif_machdep_core): Use #if _CALL_ELF + test to select parameter save sizing for ELFv2 vs. ELFv1. + * src/powerpc/ffitarget.h (FFI_V2_TYPE_FLOAT_HOMOG, + FFI_V2_TYPE_DOUBLE_HOMOG, FFI_V2_TYPE_SMALL_STRUCT): Define. + (FFI_TRAMPOLINE_SIZE): Define variant for ELFv2. + * src/powerpc/ffi.c (FLAG_ARG_NEEDS_PSAVE): Define. + (discover_homogeneous_aggregate): New function. + (ffi_prep_args64): Adjust start of param save area for ELFv2. + Handle homogenous floating point struct parms. + (ffi_prep_cif_machdep_core): Adjust space calculation for ELFv2. + Handle ELFv2 return values. Set FLAG_ARG_NEEDS_PSAVE. Handle + homogenous floating point structs. + (ffi_call): Increase size of smst_buffer for ELFv2. Handle ELFv2. + (flush_icache): Compile for ELFv2. + (ffi_prep_closure_loc): Set up ELFv2 trampoline. + (ffi_closure_helper_LINUX64): Don't return all structs directly + to caller. Handle homogenous floating point structs. Handle + ELFv2 struct return values. + * src/powerpc/linux64.S (ffi_call_LINUX64): Set up r2 for + ELFv2. Adjust toc save location. Call function pointer using + r12. Handle FLAG_RETURNS_SMST. Don't predict branches. + * src/powerpc/linux64_closure.S (ffi_closure_LINUX64): Set up r2 + for ELFv2. Define ELFv2 versions of STACKFRAME, PARMSAVE, and + RETVAL. Handle possibly missing parameter save area. Handle + ELFv2 return values. + (.note.GNU-stack): Move inside outer #ifdef. + +2013-11-16 Alan Modra + + * src/powerpc/ffi.c (ffi_prep_cif_machdep): Revert 2013-02-08 + change. Do not consume an int arg when returning a small struct + for FFI_SYSV ABI. + (ffi_call): Only use bounce buffer when FLAG_RETURNS_SMST. + Properly copy bounce buffer to destination. + * src/powerpc/sysv.S: Revert 2013-02-08 change. + * src/powerpc/ppc_closure.S: Remove stray '+'. + +2013-11-16 Alan Modra + + * src/powerpc/ffi.c (ffi_prep_args64): Align struct parameters + according to __STRUCT_PARM_ALIGN__. + (ffi_prep_cif_machdep_core): Likewise. + (ffi_closure_helper_LINUX64): Likewise. + +2013-11-16 Alan Modra + + * src/powerpc/linux64.S (ffi_call_LINUX64): Tweak restore of r28. + (.note.GNU-stack): Move inside outer #ifdef. + * src/powerpc/linux64_closure.S (STACKFRAME, PARMSAVE, + RETVAL): Define and use throughout. + (ffi_closure_LINUX64): Save fprs before buying stack. + (.note.GNU-stack): Move inside outer #ifdef. + +2013-11-16 Alan Modra + + * src/powerpc/ffitarget.h (FFI_TARGET_SPECIFIC_VARIADIC): Define. + (FFI_EXTRA_CIF_FIELDS): Define. + * src/powerpc/ffi.c (ffi_prep_args64): Save fprs as per the + ABI, not to both fpr and param save area. + (ffi_prep_cif_machdep_core): Renamed from ffi_prep_cif_machdep. + Keep initial flags. Formatting. Remove dead FFI_LINUX_SOFT_FLOAT + code. + (ffi_prep_cif_machdep, ffi_prep_cif_machdep_var): New functions. + (ffi_closure_helper_LINUX64): Pass floating point as per ABI, + not to both fpr and parameter save areas. + + * libffi/testsuite/libffi.call/cls_double_va.c (main): Correct + function cast and don't call ffi_prep_cif. + * libffi/testsuite/libffi.call/cls_longdouble_va.c (main): Likewise. + +2013-11-15 Andrew Haley + + * doc/libffi.texi (Closure Example): Fix the sample code. + * doc/libffi.info, doc/stamp-vti, doc/version.texi: Rebuilt. + +2013-11-15 Andrew Haley + + * testsuite/libffi.call/va_struct1.c (main): Fix broken test. + * testsuite/libffi.call/cls_uint_va.c (cls_ret_T_fn): Likewise + * testsuite/libffi.call/cls_struct_va1.c (test_fn): Likewise. + * testsuite/libffi.call/va_1.c (main): Likewise. + +2013-11-14 David Schneider + + * src/arm/ffi.c: Fix register allocation for mixed float and + doubles. + * testsuite/libffi.call/cls_many_mixed_float_double.c: Testcase + for many mixed float and double arguments. + +2013-11-13 Alan Modra + + * doc/libffi.texi (Simple Example): Correct example code. + * doc/libffi.info, doc/stamp-vti, doc/version.texi: Rebuilt. + +2013-11-13 Anthony Green + + * include/ffi_common.h: Respect HAVE_ALLOCA_H for GNU compiler + based build. (Thanks to tmr111116 on github) + +2013-11-09 Anthony Green + + * m4/libtool.m4: Refresh. + * configure, Makefile.in: Rebuilt. + * README: Add more notes about next release. + +2013-11-09 Shigeharu TAKENO + + * m4/ax_gcc_archflag.m4 (ax_gcc_arch): Don't recognize + UltraSPARC-IIi as ultrasparc3. + +2013-11-06 Mark Kettenis + + * src/x86/freebsd.S (ffi_call_SYSV): Align the stack pointer to + 16-bytes. + +2013-11-06 Konstantin Belousov + + * src/x86/freebsd.S (ffi_closure_raw_SYSV): Mark the assembler + source as not requiring executable stack. + +2013-11-02 Anthony Green + + * doc/libffi.texi (The Basics): Clarify return value buffer size + requirements. Also, NULL result buffer pointers are no longer + supported. + * doc/libffi.info: Rebuilt. + +2013-11-02 Mischa Jonker + + * Makefile.am (nodist_libffi_la_SOURCES): Fix build error. + * Makefile.in: Rebuilt. + +2013-11-02 David Schneider + + * src/arm/ffi.c: more robust argument handling for closures on arm hardfloat + * testsuite/libffi.call/many_mixed.c: New file. + * testsuite/libffi.call/cls_many_mixed_args.c: More tests. + +2013-11-02 Vitaly Budovski + + * src/x86/ffi.c (ffi_prep_cif_machdep): Don't align stack for win32. + +2013-10-23 Mark H Weaver + + * src/mips/ffi.c: Fix handling of uint32_t arguments on the + MIPS N32 ABI. + +2013-10-13 Sandra Loosemore + + * README: Add Nios II to table of supported platforms. + * Makefile.am (EXTRA_DIST): Add nios2 files. + (nodist_libffi_la_SOURCES): Likewise. + * Makefile.in: Regenerated. + * configure.ac (nios2*-linux*): New host. + (NIOS2): Add AM_CONDITIONAL. + * configure: Regenerated. + * src/nios2/ffi.c: New. + * src/nios2/ffitarget.h: New. + * src/nios2/sysv.S: New. + * src/prep_cif.c (initialize_aggregate): Handle extra structure + alignment via FFI_AGGREGATE_ALIGNMENT. + (ffi_prep_cif_core): Conditionalize structure return for NIOS2. + +2013-10-10 Sandra Loosemore + + * testsuite/libffi.call/cls_many_mixed_args.c (cls_ret_double_fn): + Fix uninitialized variable. + +2013-10-11 Marcus Shawcroft + + * testsuite/libffi.call/many.c (many): Replace * with +. + +2013-10-08 Ondřej Bílka + + * src/aarch64/ffi.c, src/aarch64/sysv.S, src/arm/ffi.c, + src/arm/gentramp.sh, src/bfin/sysv.S, src/closures.c, + src/dlmalloc.c, src/ia64/ffi.c, src/microblaze/ffi.c, + src/microblaze/sysv.S, src/powerpc/darwin_closure.S, + src/powerpc/ffi.c, src/powerpc/ffi_darwin.c, src/sh/ffi.c, + src/tile/tile.S, testsuite/libffi.call/nested_struct11.c: Fix + spelling errors. + +2013-10-08 Anthony Green + + * aclocal.m4, compile, config.guess, config.sub, depcomp, + install-sh, mdate-sh, missing, texinfo.tex: Update from upstream. + * configure.ac: Update version to 3.0.14-rc0. + * Makefile.in, configure, Makefile.in, include/Makefile.in, + man/Makefile.in, testsuite/Makefile.in: Rebuilt. + * README: Mention M88K and VAX. + +2013-07-15 Miod Vallat + + * Makefile.am, + configure.ac, + src/m88k/ffi.c, + src/m88k/ffitarget.h, + src/m88k/obsd.S, + src/vax/elfbsd.S, + src/vax/ffi.c, + src/vax/ffitarget.h: Add m88k and vax support. + +2013-06-24 Alan Modra + + * src/powerpc/ffi.c (ffi_prep_args_SYSV): Move var declaration + before statements. + (ffi_prep_args64): Support little-endian. + (ffi_closure_helper_SYSV, ffi_closure_helper_LINUX64): Likewise. + * src/powerpc/linux64_closure.S (ffi_closure_LINUX64): Likewise. + * src/powerpc/ppc_closure.S (ffi_closure_SYSV): Likewise. + +2013-06-12 Mischa Jonker + + * configure.ac: Add support for ARC. + * Makefile.am: Likewise. + * README: Add ARC details. + * src/arc/arcompact.S: New. + * src/arc/ffi.c: Likewise. + * src/arc/ffitarget.h: Likewise. + +2013-03-28 David Schneider + + * src/arm/ffi.c: Fix support for ARM hard-float calling convention. + * src/arm/sysv.S: call different methods for SYSV and VFP ABIs. + * testsuite/libffi.call/cls_many_mixed_args.c: testcase for a closure with + mixed arguments, many doubles. + * testsuite/libffi.call/many_double.c: testcase for calling a function using + more than 8 doubles. + * testcase/libffi.call/many.c: use absolute value to check result against an + epsilon + +2013-03-17 Anthony Green + + * README: Update for 3.0.13. + * configure.ac: Ditto. + * configure: Rebuilt. + * doc/*: Update version. + +2013-03-17 Dave Korn + + * src/closures.c (is_emutramp_enabled + [!FFI_MMAP_EXEC_EMUTRAMP_PAX]): Move default definition outside + enclosing #if scope. + +2013-03-17 Anthony Green + + * configure.ac: Only modify toolexecdir in certain cases. + * configure: Rebuilt. + +2013-03-16 Gilles Talis + + * src/powerpc/ffi.c (ffi_prep_args_SYSV): Don't use + fparg_count,etc on __NO_FPRS__ targets. + +2013-03-16 Alan Hourihane + + * src/m68k/sysv.S (epilogue): Don't use extb instruction on + m680000 machines. + +2013-03-16 Alex Gaynor + + * src/x86/ffi.c (ffi_prep_cif_machdep): Always align stack. + +2013-03-13 Markos Chandras + + * configure.ac: Add support for Imagination Technologies Meta. + * Makefile.am: Likewise. + * README: Add Imagination Technologies Meta details. + * src/metag/ffi.c: New. + * src/metag/ffitarget.h: Likewise. + * src/metag/sysv.S: Likewise. + +2013-02-24 Andreas Schwab + + * doc/libffi.texi (Structures): Fix missing category argument of + @deftp. + +2013-02-11 Anthony Green + + * configure.ac: Update release number to 3.0.12. + * configure: Rebuilt. + * README: Update release info. + +2013-02-10 Anthony Green + + * README: Add Moxie. + * src/moxie/ffi.c: Created. + * src/moxie/eabi.S: Created. + * src/moxie/ffitarget.h: Created. + * Makefile.am (nodist_libffi_la_SOURCES): Add Moxie. + * Makefile.in: Rebuilt. + * configure.ac: Add Moxie. + * configure: Rebuilt. + * testsuite/libffi.call/huge_struct.c: Disable format string + warnings for moxie*-*-elf tests. + +2013-02-10 Anthony Green + + * Makefile.am (LTLDFLAGS): Fix reference. + * Makefile.in: Rebuilt. + +2013-02-10 Anthony Green + + * README: Update supported platforms. Update test results link. + +2013-02-09 Anthony Green + + * testsuite/libffi.call/negint.c: Remove forced -O2. + * testsuite/libffi.call/many2.c (foo): Remove GCCism. + * testsuite/libffi.call/ffitest.h: Add default PRIuPTR definition. + + * src/sparc/v8.S (ffi_closure_v8): Import ancient ulonglong + closure return type fix developed by Martin v. Löwis for cpython + fork. + +2013-02-08 Andreas Tobler + + * src/powerpc/ffi.c (ffi_prep_cif_machdep): Fix small struct + support. + * src/powerpc/sysv.S: Ditto. + +2013-02-08 Anthony Green + + * testsuite/libffi.call/cls_longdouble.c: Remove xfail for + arm*-*-*. + +2013-02-08 Anthony Green + + * src/sparc/ffi.c (ffi_prep_closure_loc): Fix cache flushing for GCC. + +2013-02-08 Matthias Klose + + * man/ffi_prep_cif.3: Clean up for debian linter. + +2013-02-08 Peter Bergner + + * src/powerpc/ffi.c (ffi_prep_args_SYSV): Account for FP args pushed + on the stack. + +2013-02-08 Anthony Green + + * Makefile.am (EXTRA_DIST): Add missing files. + * testsuite/Makefile.am (EXTRA_DIST): Ditto. + * Makefile.in: Rebuilt. + +2013-02-08 Anthony Green + + * configure.ac: Move sparc asm config checks to within functions + for compatibility with sun tools. + * configure: Rebuilt. + * src/sparc/ffi.c (ffi_prep_closure_loc): Flush cache on v9 + systems. + * src/sparc/v8.S (ffi_flush_icache): Implement a sparc v9 cache + flusher. + +2013-02-08 Nathan Rossi + + * src/microblaze/ffi.c (ffi_closure_call_SYSV): Fix handling of + small big-endian structures. + (ffi_prep_args): Ditto. + +2013-02-07 Anthony Green + + * src/sparc/v8.S (ffi_call_v8): Fix typo from last patch + (effectively hiding ffi_call_v8). + +2013-02-07 Anthony Green + + * configure.ac: Update bug reporting address. + * configure.in: Rebuild. + + * src/sparc/v8.S (ffi_flush_icache): Out-of-line cache flusher for + Sun compiler. + * src/sparc/ffi.c (ffi_call): Remove warning. + Call ffi_flush_icache for non-GCC builds. + (ffi_prep_closure_loc): Use ffi_flush_icache. + + * Makefile.am (EXTRA_DIST): Add libtool-ldflags. + * Makefile.in: Rebuilt. + * libtool-ldflags: New file. + +2013-02-07 Daniel Schepler + + * configure.ac: Correctly identify x32 systems as 64-bit. + * m4/libtool.m4: Remove libtool expr error. + * aclocal.m4, configure: Rebuilt. + +2013-02-07 Anthony Green + + * configure.ac: Fix GCC usage test. + * configure: Rebuilt. + * README: Mention LLVM/GCC x86_64 issue. + * testsuite/Makefile.in: Rebuilt. + +2013-02-07 Anthony Green + + * testsuite/libffi.call/cls_double_va.c (main): Replace // style + comments with /* */ for xlc compiler. + * testsuite/libffi.call/stret_large.c (main): Ditto. + * testsuite/libffi.call/stret_large2.c (main): Ditto. + * testsuite/libffi.call/nested_struct1.c (main): Ditto. + * testsuite/libffi.call/huge_struct.c (main): Ditto. + * testsuite/libffi.call/float_va.c (main): Ditto. + * testsuite/libffi.call/cls_struct_va1.c (main): Ditto. + * testsuite/libffi.call/cls_pointer_stack.c (main): Ditto. + * testsuite/libffi.call/cls_pointer.c (main): Ditto. + * testsuite/libffi.call/cls_longdouble_va.c (main): Ditto. + +2013-02-06 Anthony Green + + * man/ffi_prep_cif.3: Clean up for debian lintian checker. + +2013-02-06 Anthony Green + + * Makefile.am (pkgconfigdir): Add missing pkgconfig install bits. + * Makefile.in: Rebuild. + +2013-02-02 Mark H Weaver + + * src/x86/ffi64.c (ffi_call): Sign-extend integer arguments passed + via general purpose registers. + +2013-01-21 Nathan Rossi + + * README: Add MicroBlaze details. + * Makefile.am: Add MicroBlaze support. + * configure.ac: Likewise. + * src/microblaze/ffi.c: New. + * src/microblaze/ffitarget.h: Likewise. + * src/microblaze/sysv.S: Likewise. + +2013-01-21 Nathan Rossi + * testsuite/libffi.call/return_uc.c: Fixed issue. + +2013-01-21 Chris Zankel + + * README: Add Xtensa support. + * Makefile.am: Likewise. + * configure.ac: Likewise. + * Makefile.in Regenerate. + * configure: Likewise. + * src/prep_cif.c: Handle Xtensa. + * src/xtensa: New directory. + * src/xtensa/ffi.c: New file. + * src/xtensa/ffitarget.h: Ditto. + * src/xtensa/sysv.S: Ditto. + +2013-01-11 Anthony Green + + * src/powerpc/ffi_darwin.c (ffi_prep_args): Replace // style + comments with /* */ for xlc compiler. + * src/powerpc/aix.S (ffi_call_AIX): Ditto. + * testsuite/libffi.call/ffitest.h (allocate_mmap): Delete + deprecated inline function. + * testsuite/libffi.special/ffitestcxx.h: Ditto. + * README: Add update for AIX support. + +2013-01-11 Anthony Green + + * configure.ac: Robustify pc relative reloc check. + * m4/ax_cc_maxopt.m4: Don't -malign-double. This is an ABI + changing option for 32-bit x86. + * aclocal.m4, configure: Rebuilt. + * README: Update supported target list. + +2013-01-10 Anthony Green + + * README (tested): Add Compiler column to table. + +2013-01-10 Anthony Green + + * src/x86/ffi64.c (struct register_args): Make sse array and array + of unions for sunpro compiler compatibility. + +2013-01-10 Anthony Green + + * configure.ac: Test target platform size_t size. Handle both 32 + and 64-bit builds for x86_64-* and i?86-* targets (allowing for + CFLAG option to change default settings). + * configure, aclocal.m4: Rebuilt. + +2013-01-10 Anthony Green + + * testsuite/libffi.special/special.exp: Only run exception + handling tests when using GNU compiler. + + * m4/ax_compiler_vendor.m4: New file. + * configure.ac: Test for compiler vendor and don't use + AX_CFLAGS_WARN_ALL with the sun compiler. + * aclocal.m4, configure: Rebuilt. + +2013-01-10 Anthony Green + + * include/ffi_common.h: Don't use GCCisms to define types when + building with the SUNPRO compiler. + +2013-01-10 Anthony Green + + * configure.ac: Put local.exp in the right place. + * configure: Rebuilt. + + * src/x86/ffi.c: Update comment about regparm function attributes. + * src/x86/sysv.S (ffi_closure_SYSV): The SUNPRO compiler requires + that all function arguments be passed on the stack (no regparm + support). + +2013-01-08 Anthony Green + + * configure.ac: Generate local.exp. This sets CC_FOR_TARGET + when we are using the vendor compiler. + * testsuite/Makefile.am (EXTRA_DEJAGNU_SITE_CONFIG): Point to + ../local.exp. + * configure, testsuite/Makefile.in: Rebuilt. + + * testsuite/libffi.call/call.exp: Run tests with different + options, depending on whether or not we are using gcc or the + vendor compiler. + * testsuite/lib/libffi.exp (libffi-init): Set using_gcc based on + whether or not we are building/testing with gcc. + +2013-01-08 Anthony Green + + * configure.ac: Switch x86 solaris target to X86 by default. + * configure: Rebuilt. + +2013-01-08 Anthony Green + + * configure.ac: Fix test for read-only eh_frame. + * configure: Rebuilt. + +2013-01-08 Anthony Green + + * src/x86/sysv.S, src/x86/unix64.S: Only emit DWARF unwind info + when building with the GNU toolchain. + * testsuite/libffi.call/ffitest.h (CHECK): Fix for Solaris vendor + compiler. + +2013-01-07 Thorsten Glaser + + * testsuite/libffi.call/cls_uchar_va.c, + testsuite/libffi.call/cls_ushort_va.c, + testsuite/libffi.call/va_1.c: Testsuite fixes. + +2013-01-07 Thorsten Glaser + + * src/m68k/ffi.c (CIF_FLAGS_SINT8, CIF_FLAGS_SINT16): Define. + (ffi_prep_cif_machdep): Fix 8-bit and 16-bit signed calls. + * src/m68k/sysv.S (ffi_call_SYSV, ffi_closure_SYSV): Ditto. + +2013-01-04 Anthony Green + + * Makefile.am (AM_CFLAGS): Don't automatically add -fexceptions + and -Wall. This is set in the configure script after testing for + GCC. + * Makefile.in: Rebuilt. + +2013-01-02 rofl0r + + * src/powerpc/ffi.c (ffi_prep_cif_machdep): Fix build error on ppc + when long double == double. + +2013-01-02 Reini Urban + + * Makefile.am (libffi_la_LDFLAGS): Add -no-undefined to LDFLAGS + (required for shared libs on cygwin/mingw). + * Makefile.in: Rebuilt. + +2012-10-31 Alan Modra + + * src/powerpc/linux64_closure.S: Add new ABI support. + * src/powerpc/linux64.S: Likewise. + +2012-10-30 Magnus Granberg + Pavel Labushev + + * configure.ac: New options pax_emutramp + * configure, fficonfig.h.in: Regenerated + * src/closures.c: New function emutramp_enabled_check() and + checks. + +2012-10-30 Frederick Cheung + + * configure.ac: Enable FFI_MAP_EXEC_WRIT for Darwin 12 (mountain + lion) and future version. + * configure: Rebuild. + +2012-10-30 James Greenhalgh + Marcus Shawcroft + + * README: Add details of aarch64 port. + * src/aarch64/ffi.c: New. + * src/aarch64/ffitarget.h: Likewise. + * src/aarch64/sysv.S: Likewise. + * Makefile.am: Support aarch64. + * configure.ac: Support aarch64. + * Makefile.in, configure: Rebuilt. + +2012-10-30 James Greenhalgh + Marcus Shawcroft + + * testsuite/lib/libffi.exp: Add support for aarch64. + * testsuite/libffi.call/cls_struct_va1.c: New. + * testsuite/libffi.call/cls_uchar_va.c: Likewise. + * testsuite/libffi.call/cls_uint_va.c: Likewise. + * testsuite/libffi.call/cls_ulong_va.c: Likewise. + * testsuite/libffi.call/cls_ushort_va.c: Likewise. + * testsuite/libffi.call/nested_struct11.c: Likewise. + * testsuite/libffi.call/uninitialized.c: Likewise. + * testsuite/libffi.call/va_1.c: Likewise. + * testsuite/libffi.call/va_struct1.c: Likewise. + * testsuite/libffi.call/va_struct2.c: Likewise. + * testsuite/libffi.call/va_struct3.c: Likewise. + +2012-10-12 Walter Lee + + * Makefile.am: Add TILE-Gx/TILEPro support. + * configure.ac: Likewise. + * Makefile.in: Regenerate. + * configure: Likewise. + * src/prep_cif.c (ffi_prep_cif_core): Handle TILE-Gx/TILEPro. + * src/tile: New directory. + * src/tile/ffi.c: New file. + * src/tile/ffitarget.h: Ditto. + * src/tile/tile.S: Ditto. + +2012-10-12 Matthias Klose + + * generate-osx-source-and-headers.py: Normalize whitespace. + +2012-09-14 David Edelsohn + + * configure: Regenerated. + +2012-08-26 Andrew Pinski + + PR libffi/53014 + * src/mips/ffi.c (ffi_prep_closure_loc): Allow n32 with soft-float and n64 with + soft-float. + +2012-08-08 Uros Bizjak + + * src/s390/ffi.c (ffi_prep_closure_loc): Don't ASSERT ABI test, + just return FFI_BAD_ABI when things are wrong. + +2012-07-18 H.J. Lu + + PR libffi/53982 + PR libffi/53973 + * src/x86/ffitarget.h: Check __ILP32__ instead of __LP64__ for x32. + (FFI_SIZEOF_JAVA_RAW): Defined to 4 for x32. + +2012-05-16 H.J. Lu + + * configure: Regenerated. + +2012-05-05 Nicolas Lelong + + * libffi.xcodeproj/project.pbxproj: Fixes. + * README: Update for iOS builds. + +2012-04-23 Alexandre Keunecke I. de Mendonca + + * configure.ac: Add Blackfin/sysv support + * Makefile.am: Add Blackfin/sysv support + * src/bfin/ffi.c: Add Blackfin/sysv support + * src/bfin/ffitarget.h: Add Blackfin/sysv support + +2012-04-11 Anthony Green + + * Makefile.am (EXTRA_DIST): Add new script. + * Makefile.in: Rebuilt. + +2012-04-11 Zachary Waldowski + + * generate-ios-source-and-headers.py, + libffi.xcodeproj/project.pbxproj: Support a Mac static library via + Xcode. Set iOS compatibility to 4.0. Move iOS trampoline + generation into an Xcode "run script" phase. Include both as + Xcode build scripts. Don't always regenerate config files. + +2012-04-10 Anthony Green + + * src/powerpc/ffi_darwin.c (ffi_prep_args): Add missing semicolon. + +2012-04-06 Anthony Green + + * Makefile.am (EXTRA_DIST): Add new iOS/xcode files. + * Makefile.in: Rebuilt. + +2012-04-06 Mike Lewis + + * generate-ios-source-and-headers.py: New file. + * libffi.xcodeproj/project.pbxproj: New file. + * README: Update instructions on building iOS binary. + * build-ios.sh: Delete. + +2012-04-06 Anthony Green + + * src/x86/ffi64.c (UINT128): Define differently for Intel and GNU + compilers, then use it. + +2012-04-06 H.J. Lu + + * m4/libtool.m4 (_LT_ENABLE_LOCK): Support x32. + +2012-04-06 Anthony Green + + * testsuite/Makefile.am (EXTRA_DIST): Add missing test cases. + * testsuite/Makefile.in: Rebuilt. + +2012-04-05 Zachary Waldowski + + * include/ffi.h.in: Add missing trampoline table fields. + * src/arm/sysv.S: Fix ENTRY definition, and wrap symbol references + in CNAME. + * src/x86/ffi.c: Wrap Windows specific code in ifdefs. + +2012-04-02 Peter Bergner + + * src/powerpc/ffi.c (ffi_prep_args_SYSV): Declare double_tmp. + Silence casting pointer to integer of different size warning. + Delete goto to previously deleted label. + (ffi_call): Silence possibly undefined warning. + (ffi_closure_helper_SYSV): Declare variable type. + +2012-04-02 Peter Rosin + + * src/x86/win32.S (ffi_call_win32): Sign/zero extend the return + value in the Intel version as is already done for the AT&T version. + (ffi_closure_SYSV): Likewise. + (ffi_closure_raw_SYSV): Likewise. + (ffi_closure_STDCALL): Likewise. + +2012-03-29 Peter Rosin + + * src/x86/win32.S (ffi_closure_raw_THISCALL): Unify the frame + generation, fix the ENDP label and remove the surplus third arg + from the 'lea' insn. + +2012-03-29 Peter Rosin + + * src/x86/win32.S (ffi_closure_raw_SYSV): Make the 'stubraw' label + visible outside the PROC, so that ffi_closure_raw_THISCALL can see + it. Also instruct the assembler to add a frame to the function. + +2012-03-23 Peter Rosin + + * Makefile.am (AM_CPPFLAGS): Add -DFFI_BUILDING. + * Makefile.in: Rebuilt. + * include/ffi.h.in [MSVC]: Add __declspec(dllimport) decorations + to all data exports, when compiling libffi clients using MSVC. + +2012-03-29 Peter Rosin + + * src/x86/ffitarget.h (ffi_abi): Add new ABI FFI_MS_CDECL and + make it the default for MSVC. + (FFI_TYPE_MS_STRUCT): New structure return convention. + * src/x86/ffi.c (ffi_prep_cif_machdep): Tweak the structure + return convention for FFI_MS_CDECL to be FFI_TYPE_MS_STRUCT + instead of an ordinary FFI_TYPE_STRUCT. + (ffi_prep_args): Treat FFI_TYPE_MS_STRUCT as FFI_TYPE_STRUCT. + (ffi_call): Likewise. + (ffi_prep_incoming_args_SYSV): Likewise. + (ffi_raw_call): Likewise. + (ffi_prep_closure_loc): Treat FFI_MS_CDECL as FFI_SYSV. + * src/x86/win32.S (ffi_closure_SYSV): For FFI_TYPE_MS_STRUCT, + return a pointer to the result structure in eax and don't pop + that pointer from the stack, the caller takes care of it. + (ffi_call_win32): Treat FFI_TYPE_MS_STRUCT as FFI_TYPE_STRUCT. + (ffi_closure_raw_SYSV): Likewise. + +2012-03-22 Peter Rosin + + * testsuite/libffi.call/closure_stdcall.c [MSVC]: Add inline + assembly version with Intel syntax. + * testsuite/libffi.call/closure_thiscall.c [MSVC]: Likewise. + +2012-03-23 Peter Rosin + + * testsuite/libffi.call/ffitest.h: Provide abstration of + __attribute__((fastcall)) in the form of a __FASTCALL__ + define. Define it to __fastcall for MSVC. + * testsuite/libffi.call/fastthis1_win32.c: Use the above. + * testsuite/libffi.call/fastthis2_win32.c: Likewise. + * testsuite/libffi.call/fastthis3_win32.c: Likewise. + * testsuite/libffi.call/strlen2_win32.c: Likewise. + * testsuite/libffi.call/struct1_win32.c: Likewise. + * testsuite/libffi.call/struct2_win32.c: Likewise. + +2012-03-22 Peter Rosin + + * src/x86/win32.S [MSVC] (ffi_closure_THISCALL): Remove the manual + frame on function entry, MASM adds one automatically. + +2012-03-22 Peter Rosin + + * testsuite/libffi.call/ffitest.h [MSVC]: Add kludge for missing + bits in the MSVC headers. + +2012-03-22 Peter Rosin + + * testsuite/libffi.call/cls_12byte.c: Adjust to the C89 style + with no declarations after statements. + * testsuite/libffi.call/cls_16byte.c: Likewise. + * testsuite/libffi.call/cls_18byte.c: Likewise. + * testsuite/libffi.call/cls_19byte.c: Likewise. + * testsuite/libffi.call/cls_1_1byte.c: Likewise. + * testsuite/libffi.call/cls_20byte.c: Likewise. + * testsuite/libffi.call/cls_20byte1.c: Likewise. + * testsuite/libffi.call/cls_24byte.c: Likewise. + * testsuite/libffi.call/cls_2byte.c: Likewise. + * testsuite/libffi.call/cls_3_1byte.c: Likewise. + * testsuite/libffi.call/cls_3byte1.c: Likewise. + * testsuite/libffi.call/cls_3byte2.c: Likewise. + * testsuite/libffi.call/cls_4_1byte.c: Likewise. + * testsuite/libffi.call/cls_4byte.c: Likewise. + * testsuite/libffi.call/cls_5_1_byte.c: Likewise. + * testsuite/libffi.call/cls_5byte.c: Likewise. + * testsuite/libffi.call/cls_64byte.c: Likewise. + * testsuite/libffi.call/cls_6_1_byte.c: Likewise. + * testsuite/libffi.call/cls_6byte.c: Likewise. + * testsuite/libffi.call/cls_7_1_byte.c: Likewise. + * testsuite/libffi.call/cls_7byte.c: Likewise. + * testsuite/libffi.call/cls_8byte.c: Likewise. + * testsuite/libffi.call/cls_9byte1.c: Likewise. + * testsuite/libffi.call/cls_9byte2.c: Likewise. + * testsuite/libffi.call/cls_align_double.c: Likewise. + * testsuite/libffi.call/cls_align_float.c: Likewise. + * testsuite/libffi.call/cls_align_longdouble.c: Likewise. + * testsuite/libffi.call/cls_align_longdouble_split.c: Likewise. + * testsuite/libffi.call/cls_align_longdouble_split2.c: Likewise. + * testsuite/libffi.call/cls_align_pointer.c: Likewise. + * testsuite/libffi.call/cls_align_sint16.c: Likewise. + * testsuite/libffi.call/cls_align_sint32.c: Likewise. + * testsuite/libffi.call/cls_align_sint64.c: Likewise. + * testsuite/libffi.call/cls_align_uint16.c: Likewise. + * testsuite/libffi.call/cls_align_uint32.c: Likewise. + * testsuite/libffi.call/cls_align_uint64.c: Likewise. + * testsuite/libffi.call/cls_dbls_struct.c: Likewise. + * testsuite/libffi.call/cls_pointer_stack.c: Likewise. + * testsuite/libffi.call/err_bad_typedef.c: Likewise. + * testsuite/libffi.call/huge_struct.c: Likewise. + * testsuite/libffi.call/nested_struct.c: Likewise. + * testsuite/libffi.call/nested_struct1.c: Likewise. + * testsuite/libffi.call/nested_struct10.c: Likewise. + * testsuite/libffi.call/nested_struct2.c: Likewise. + * testsuite/libffi.call/nested_struct3.c: Likewise. + * testsuite/libffi.call/nested_struct4.c: Likewise. + * testsuite/libffi.call/nested_struct5.c: Likewise. + * testsuite/libffi.call/nested_struct6.c: Likewise. + * testsuite/libffi.call/nested_struct7.c: Likewise. + * testsuite/libffi.call/nested_struct8.c: Likewise. + * testsuite/libffi.call/nested_struct9.c: Likewise. + * testsuite/libffi.call/stret_large.c: Likewise. + * testsuite/libffi.call/stret_large2.c: Likewise. + * testsuite/libffi.call/stret_medium.c: Likewise. + * testsuite/libffi.call/stret_medium2.c: Likewise. + * testsuite/libffi.call/struct1.c: Likewise. + * testsuite/libffi.call/struct1_win32.c: Likewise. + * testsuite/libffi.call/struct2.c: Likewise. + * testsuite/libffi.call/struct2_win32.c: Likewise. + * testsuite/libffi.call/struct3.c: Likewise. + * testsuite/libffi.call/struct4.c: Likewise. + * testsuite/libffi.call/struct5.c: Likewise. + * testsuite/libffi.call/struct6.c: Likewise. + * testsuite/libffi.call/struct7.c: Likewise. + * testsuite/libffi.call/struct8.c: Likewise. + * testsuite/libffi.call/struct9.c: Likewise. + * testsuite/libffi.call/testclosure.c: Likewise. + +2012-03-21 Peter Rosin + + * testsuite/libffi.call/float_va.c (float_va_fn): Use %f when + printing doubles (%lf is for long doubles). + (main): Likewise. + +2012-03-21 Peter Rosin + + * testsuite/lib/target-libpath.exp [*-*-cygwin*, *-*-mingw*] + (set_ld_library_path_env_vars): Add the library search dir to PATH + (and save PATH for later). + (restore_ld_library_path_env_vars): Restore PATH. + +2012-03-21 Peter Rosin + + * testsuite/lib/target-libpath.exp [*-*-cygwin*, *-*-mingw*] + (set_ld_library_path_env_vars): Add the library search dir to PATH + (and save PATH for later). + (restore_ld_library_path_env_vars): Restore PATH. + +2012-03-20 Peter Rosin + + * testsuite/libffi.call/strlen2_win32.c (main): Remove bug. + * src/x86/win32.S [MSVC] (ffi_closure_SYSV): Make the 'stub' label + visible outside the PROC, so that ffi_closure_THISCALL can see it. + +2012-03-20 Peter Rosin + + * testsuite/libffi.call/strlen2_win32.c (main): Remove bug. + * src/x86/win32.S [MSVC] (ffi_closure_SYSV): Make the 'stub' label + visible outside the PROC, so that ffi_closure_THISCALL can see it. + +2012-03-19 Alan Hourihane + + * src/m68k/ffi.c: Add MINT support. + * src/m68k/sysv.S: Ditto. + +2012-03-06 Chung-Lin Tang + + * src/arm/ffi.c (ffi_call): Add __ARM_EABI__ guard around call to + ffi_call_VFP(). + (ffi_prep_closure_loc): Add __ARM_EABI__ guard around use of + ffi_closure_VFP. + * src/arm/sysv.S: Add __ARM_EABI__ guard around VFP code. + +2012-03-19 chennam + + * src/powerpc/ffi_darwin.c (ffi_prep_closure_loc): Fix AIX closure + support. + +2012-03-13 Kaz Kojima + + * src/sh/ffi.c (ffi_prep_closure_loc): Don't ASSERT ABI test, + just return FFI_BAD_ABI when things are wrong. + * src/sh64/ffi.c (ffi_prep_closure_loc): Ditto. + +2012-03-09 David Edelsohn + + * src/powerpc/aix_closure.S (ffi_closure_ASM): Adjust for Darwin64 + change to return value of ffi_closure_helper_DARWIN and load type + from return type. + +2012-03-03 H.J. Lu + + * src/x86/ffi64.c (ffi_call): Cast the return value to unsigned + long. + (ffi_prep_closure_loc): Cast to 64bit address in trampoline. + (ffi_closure_unix64_inner): Cast return pointer to unsigned long + first. + + * src/x86/ffitarget.h (FFI_SIZEOF_ARG): Defined to 8 for x32. + (ffi_arg): Set to unsigned long long for x32. + (ffi_sarg): Set to long long for x32. + +2012-03-03 H.J. Lu + + * src/prep_cif.c (ffi_prep_cif_core): Properly check bad ABI. + +2012-03-03 Andoni Morales Alastruey + + * configure.ac: Add -no-undefined for both 32- and 64-bit x86 + windows-like hosts. + * configure: Rebuilt. + +2012-02-27 Mikael Pettersson + + PR libffi/52223 + * Makefile.am (FLAGS_TO_PASS): Define. + * Makefile.in: Regenerate. + +2012-02-23 Anthony Green + + * src/*/ffitarget.h: Ensure that users never include ffitarget.h + directly. + +2012-02-23 Kai Tietz + + PR libffi/52221 + * src/x86/ffi.c (ffi_closure_raw_THISCALL): New + prototype. + (ffi_prep_raw_closure_loc): Use ffi_closure_raw_THISCALL for + thiscall-convention. + (ffi_raw_call): Use ffi_prep_args_raw. + * src/x86/win32.S (ffi_closure_raw_THISCALL): Add + implementation for stub. + +2012-02-10 Kai Tietz + + * configure.ac (AM_LTLDFLAGS): Add -no-undefine for x64 + windows target. + * configure: Regenerated. + +2012-02-08 Kai Tietz + + * src/prep_cif.c (ffi_prep_cif): Allow for X86_WIN32 + also FFI_THISCALL. + * src/x86/ffi.c (ffi_closure_THISCALL): Add prototype. + (FFI_INIT_TRAMPOLINE_THISCALL): New trampoline code. + (ffi_prep_closure_loc): Add FFI_THISCALL support. + * src/x86/ffitarget.h (FFI_TRAMPOLINE_SIZE): Adjust size. + * src/x86/win32.S (ffi_closure_THISCALL): New closure code + for thiscall-calling convention. + * testsuite/libffi.call/closure_thiscall.c: New test. + +2012-01-28 Kai Tietz + + * src/libffi/src/x86/ffi.c (ffi_call_win32): Add new + argument to prototype for specify calling-convention. + (ffi_call): Add support for stdcall/thiscall convention. + (ffi_prep_args): Likewise. + (ffi_raw_call): Likewise. + * src/x86/ffitarget.h (ffi_abi): Add FFI_THISCALL and + FFI_FASTCALL. + * src/x86/win32.S (_ffi_call_win32): Add support for + fastcall/thiscall calling-convention calls. + * testsuite/libffi.call/fastthis1_win32.c: New test. + * testsuite/libffi.call/fastthis2_win32.c: New test. + * testsuite/libffi.call/fastthis3_win32.c: New test. + * testsuite/libffi.call/strlen2_win32.c: New test. + * testsuite/libffi.call/many2_win32.c: New test. + * testsuite/libffi.call/struct1_win32.c: New test. + * testsuite/libffi.call/struct2_win32.c: New test. + +2012-01-23 Uros Bizjak + + * src/alpha/ffi.c (ffi_prep_closure_loc): Check for bad ABI. + +2012-01-23 Anthony Green + Chris Young + + * configure.ac: Add Amiga support. + * configure: Rebuilt. + +2012-01-23 Dmitry Nadezhin + + * include/ffi_common.h (LIKELY, UNLIKELY): Fix definitions. + +2012-01-23 Andreas Schwab + + * src/m68k/sysv.S (ffi_call_SYSV): Properly test for plain + mc68000. Test for __HAVE_68881__ in addition to __MC68881__. + +2012-01-19 Jakub Jelinek + + PR rtl-optimization/48496 + * src/ia64/ffi.c (ffi_call): Fix up aliasing violations. + +2012-01-09 Rainer Orth + + * configure.ac (i?86-*-*): Set TARGET to X86_64. + * configure: Regenerate. + +2011-12-07 Andrew Pinski + + PR libffi/50051 + * src/mips/n32.S: Add ".set mips4". + +2011-11-21 Andreas Tobler + + * configure: Regenerate. + +2011-11-12 David Gilbert + + * doc/libffi.texi, include/ffi.h.in, include/ffi_common.h, + man/Makefile.am, man/ffi.3, man/ffi_prep_cif.3, + man/ffi_prep_cif_var.3, src/arm/ffi.c, src/arm/ffitarget.h, + src/cris/ffi.c, src/prep_cif.c, + testsuite/libffi.call/cls_double_va.c, + testsuite/libffi.call/cls_longdouble_va.c, + testsuite/libffi.call/float_va.c: Many changes to support variadic + function calls. + +2011-11-12 Kyle Moffett + + * src/powerpc/ffi.c, src/powerpc/ffitarget.h, + src/powerpc/ppc_closure.S, src/powerpc/sysv.S: Many changes for + softfloat powerpc variants. + +2011-11-12 Petr Salinger + + * configure.ac (FFI_EXEC_TRAMPOLINE_TABLE): Fix kfreebsd support. + * configure: Rebuilt. + +2011-11-12 Timothy Wall + + * src/arm/ffi.c (ffi_prep_args, ffi_prep_incoming_args_SYSV): Max + alignment of 4 for wince on ARM. + +2011-11-12 Kyle Moffett + Anthony Green + + * src/ppc/sysv.S, src/ppc/ffi.c: Remove use of ppc string + instructions (not available on some cores, like the PPC440). + +2011-11-12 Kimura Wataru + + * m4/ax_enable_builddir: Change from string comparison to numeric + comparison for wc output. + * configure.ac: Enable FFI_MMAP_EXEC_WRIT for darwin11 aka Mac OS + X 10.7. + * configure: Rebuilt. + +2011-11-12 Anthony Green + + * Makefile.am (AM_CCASFLAGS): Add -g option to build assembly + files with debug info. + * Makefile.in: Rebuilt. + +2011-11-12 Jasper Lievisse Adriaanse + + * README: Update list of supported OpenBSD systems. + +2011-11-12 Anthony Green + + * libtool-version: Update. + * Makefile.am (nodist_libffi_la_SOURCES): Add src/debug.c if + FFI_DEBUG. + (libffi_la_SOURCES): Remove src/debug.c + (EXTRA_DIST): Add src/debug.c + * Makefile.in: Rebuilt. + * README: Update for 3.0.11. + +2011-11-10 Richard Henderson + + * configure.ac (GCC_AS_CFI_PSEUDO_OP): Use it instead of inline check. + * configure, aclocal.m4: Rebuild. + +2011-09-04 Iain Sandoe + + PR libffi/49594 + * src/powerpc/darwin_closure.S (stubs): Make the stub binding + helper reference track the architecture pointer size. + +2011-08-25 Andrew Haley + + * src/arm/ffi.c (FFI_INIT_TRAMPOLINE): Remove hard-coded assembly + instructions. + * src/arm/sysv.S (ffi_arm_trampoline): Put them here instead. + +2011-07-11 Andrew Haley + + * src/arm/ffi.c (FFI_INIT_TRAMPOLINE): Clear icache. + +2011-06-29 Rainer Orth + + * testsuite/libffi.call/cls_double_va.c: Move PR number to comment. + * testsuite/libffi.call/cls_longdouble_va.c: Likewise. + +2011-06-29 Rainer Orth + + PR libffi/46660 + * testsuite/libffi.call/cls_double_va.c: xfail dg-output on + mips-sgi-irix6*. + * testsuite/libffi.call/cls_longdouble_va.c: Likewise. + +2011-06-14 Rainer Orth + + * testsuite/libffi.call/huge_struct.c (test_large_fn): Use PRIu8, + PRId8 instead of %hhu, %hhd. + * testsuite/libffi.call/ffitest.h [__alpha__ && __osf__] (PRId8, + PRIu8): Define. + [__sgi__] (PRId8, PRIu8): Define. + +2011-04-29 Rainer Orth + + * src/alpha/osf.S (UA_SI, FDE_ENCODING, FDE_ENCODE, FDE_ARANGE): + Define. + Use them to handle ELF vs. ECOFF differences. + [__osf__] (_GLOBAL__F_ffi_call_osf): Define. + +2011-03-30 Timothy Wall + + * src/powerpc/darwin.S: Fix unknown FDE encoding. + * src/powerpc/darwin_closure.S: ditto. + +2011-02-25 Anthony Green + + * src/powerpc/ffi.c (ffi_prep_closure_loc): Allow for more + 32-bit ABIs. + +2011-02-15 Anthony Green + + * m4/ax_cc_maxopt.m4: Don't -malign-double or use -ffast-math. + * configure: Rebuilt. + +2011-02-13 Ralf Wildenhues + + * configure: Regenerate. + +2011-02-13 Anthony Green + + * include/ffi_common.h (UNLIKELY, LIKELY): Define. + * src/x86/ffi64.c (UNLIKELY, LIKELY): Remove definition. + * src/prep_cif.c (UNLIKELY, LIKELY): Remove definition. + + * src/prep_cif.c (initialize_aggregate): Convert assertion into + FFI_BAD_TYPEDEF return. Initialize arg size and alignment to 0. + + * src/pa/ffi.c (ffi_prep_closure_loc): Don't ASSERT ABI test, + just return FFI_BAD_ABI when things are wrong. + * src/arm/ffi.c (ffi_prep_closure_loc): Ditto. + * src/powerpc/ffi.c (ffi_prep_closure_loc): Ditto. + * src/mips/ffi.c (ffi_prep_closure_loc): Ditto. + * src/ia64/ffi.c (ffi_prep_closure_loc): Ditto. + * src/avr32/ffi.c (ffi_prep_closure_loc): Ditto. + +2011-02-11 Anthony Green + + * src/sparc/ffi.c (ffi_prep_closure_loc): Don't ASSERT ABI test, + just return FFI_BAD_ABI when things are wrong. + +2012-02-11 Eric Botcazou + + * src/sparc/v9.S (STACKFRAME): Bump to 176. + +2011-02-09 Stuart Shelton + + http://bugs.gentoo.org/show_bug.cgi?id=286911 + * src/mips/ffitarget.h: Clean up error messages. + * src/java_raw_api.c (ffi_java_translate_args): Cast raw arg to + ffi_raw*. + * include/ffi.h.in: Add pragma for SGI compiler. + +2011-02-09 Anthony Green + + * configure.ac: Add powerpc64-*-darwin* support. + +2011-02-09 Anthony Green + + * README: Mention Interix. + +2011-02-09 Jonathan Callen + + * configure.ac: Add Interix to win32/cygwin/mingw case. + * configure: Ditto. + * src/closures.c: Treat Interix like Cygwin, instead of as a + generic win32. + +2011-02-09 Anthony Green + + * testsuite/libffi.call/err_bad_typedef.c: Remove xfail. + * testsuite/libffi.call/err_bad_abi.c: Remove xfail. + * src/x86/ffi64.c (UNLIKELY, LIKELY): Define. + (ffi_prep_closure_loc): Check for bad ABI. + * src/prep_cif.c (UNLIKELY, LIKELY): Define. + (initialize_aggregate): Check for bad types. + +2011-02-09 Landon Fuller + + * Makefile.am (EXTRA_DIST): Add build-ios.sh, src/arm/gentramp.sh, + src/arm/trampoline.S. + (nodist_libffi_la_SOURCES): Add src/arc/trampoline.S. + * configure.ac (FFI_EXEC_TRAMPOLINE_TABLE): Define. + * src/arm/ffi.c (ffi_trampoline_table) + (ffi_closure_trampoline_table_page, ffi_trampoline_table_entry) + (FFI_TRAMPOLINE_CODELOC_CONFIG, FFI_TRAMPOLINE_CONFIG_PAGE_OFFSET) + (FFI_TRAMPOLINE_COUNT, ffi_trampoline_lock, ffi_trampoline_tables) + (ffi_trampoline_table_alloc, ffi_closure_alloc, ffi_closure_free): + Define for FFI_EXEC_TRAMPOLINE_TABLE case (iOS). + (ffi_prep_closure_loc): Handl FFI_EXEC_TRAMPOLINE_TABLE case + separately. + * src/arm/sysv.S: Handle Apple iOS host. + * src/closures.c: Handle FFI_EXEC_TRAMPOLINE_TABLE case. + * build-ios.sh: New file. + * fficonfig.h.in, configure, Makefile.in: Rebuilt. + * README: Mention ARM iOS. + +2011-02-08 Oren Held + + * src/dlmalloc.c (_STRUCT_MALLINFO): Define in order to avoid + redefinition of mallinfo on HP-UX. + +2011-02-08 Ginn Chen + + * src/sparc/ffi.c (ffi_call): Make compatible with Solaris Studio + aggregate return ABI. Flush cache. + (ffi_prep_closure_loc): Flush cache. + +2011-02-11 Anthony Green + + From Tom Honermann : + * src/powerpc/aix.S (ffi_call_AIX): Support for xlc toolchain on + AIX. Declare .ffi_prep_args. Insert nops after branch + instructions so that the AIX linker can insert TOC reload + instructions. + * src/powerpc/aix_closure.S: Declare .ffi_closure_helper_DARWIN. + +2011-02-08 Ed + + * src/powerpc/asm.h: Fix grammar nit in comment. + +2011-02-08 Uli Link + + * include/ffi.h.in (FFI_64_BIT_MAX): Define and use. + +2011-02-09 Rainer Orth + + PR libffi/46661 + * testsuite/libffi.call/cls_pointer.c (main): Cast void * to + uintptr_t first. + * testsuite/libffi.call/cls_pointer_stack.c (main): Likewise. + +2011-02-08 Rafael Avila de Espindola + + * configure.ac: Fix x86 test for pc related relocs. + * configure: Rebuilt. + +2011-02-07 Joel Sherrill + + * libffi/src/m68k/ffi.c: Add RTEMS support for cache flushing. + Handle case when CPU variant does not have long double support. + * libffi/src/m68k/sysv.S: Add support for mc68000, Coldfire, + and cores with soft floating point. + +2011-02-07 Joel Sherrill + + * configure.ac: Add mips*-*-rtems* support. + * configure: Regenerate. + * src/mips/ffitarget.h: Ensure needed constants are available + for targets which do not have sgidefs.h. + +2011-01-26 Dave Korn + + PR target/40125 + * configure.ac (AM_LTLDFLAGS): Add -bindir option for windows DLLs. + * configure: Regenerate. + +2010-12-18 Iain Sandoe + + PR libffi/29152 + PR libffi/42378 + * src/powerpc/darwin_closure.S: Provide Darwin64 implementation, + update comments. + * src/powerpc/ffitarget.h (POWERPC_DARWIN64): New, + (FFI_TRAMPOLINE_SIZE): Update for Darwin64. + * src/powerpc/darwin.S: Provide Darwin64 implementation, + update comments. + * src/powerpc/ffi_darwin.c: Likewise. + +2010-12-06 Rainer Orth + + * configure.ac (libffi_cv_as_ascii_pseudo_op): Use double + backslashes. + (libffi_cv_as_string_pseudo_op): Likewise. + * configure: Regenerate. + +2010-12-03 Chung-Lin Tang + + * src/arm/sysv.S (ffi_closure_SYSV): Add UNWIND to .pad directive. + (ffi_closure_VFP): Same. + (ffi_call_VFP): Move down to before ffi_closure_VFP. Add '.fpu vfp' + directive. + +2010-12-01 Rainer Orth + + * testsuite/libffi.call/ffitest.h [__sgi] (PRId64, PRIu64): Define. + (PRIuPTR): Define. + +2010-11-29 Richard Henderson + Rainer Orth + + * src/x86/sysv.S (FDE_ENCODING, FDE_ENCODE): Define. + (.eh_frame): Use FDE_ENCODING. + (.LASFDE1, .LASFDE2, LASFDE3): Simplify with FDE_ENCODE. + +2010-11-22 Jacek Caban + + * configure.ac: Check for symbol underscores on mingw-w64. + * configure: Rebuilt. + * src/x86/win64.S: Correctly access extern symbols in respect to + underscores. + +2010-11-15 Rainer Orth + + * testsuite/lib/libffi-dg.exp: Rename ... + * testsuite/lib/libffi.exp: ... to this. + * libffi/testsuite/libffi.call/call.exp: Don't load libffi-dg.exp. + * libffi/testsuite/libffi.special/special.exp: Likewise. + +2010-10-28 Chung-Lin Tang + + * src/arm/ffi.c (ffi_prep_args): Add VFP register argument handling + code, new parameter, and return value. Update comments. + (ffi_prep_cif_machdep): Add case for VFP struct return values. Add + call to layout_vfp_args(). + (ffi_call_SYSV): Update declaration. + (ffi_call_VFP): New declaration. + (ffi_call): Add VFP struct return conditions. Call ffi_call_VFP() + when ABI is FFI_VFP. + (ffi_closure_VFP): New declaration. + (ffi_closure_SYSV_inner): Add new vfp_args parameter, update call to + ffi_prep_incoming_args_SYSV(). + (ffi_prep_incoming_args_SYSV): Update parameters. Add VFP argument + case handling. + (ffi_prep_closure_loc): Pass ffi_closure_VFP to trampoline + construction under VFP hard-float. + (rec_vfp_type_p): New function. + (vfp_type_p): Same. + (place_vfp_arg): Same. + (layout_vfp_args): Same. + * src/arm/ffitarget.h (ffi_abi): Add FFI_VFP. Define FFI_DEFAULT_ABI + based on __ARM_PCS_VFP. + (FFI_EXTRA_CIF_FIELDS): Define for adding VFP hard-float specific + fields. + (FFI_TYPE_STRUCT_VFP_FLOAT): Define internally used type code. + (FFI_TYPE_STRUCT_VFP_DOUBLE): Same. + * src/arm/sysv.S (ffi_call_SYSV): Change call of ffi_prep_args() to + direct call. Move function pointer load upwards. + (ffi_call_VFP): New function. + (ffi_closure_VFP): Same. + + * testsuite/lib/libffi-dg.exp (check-flags): New function. + (dg-skip-if): New function. + * testsuite/libffi.call/cls_double_va.c: Skip if target is arm*-*-* + and compiler options include -mfloat-abi=hard. + * testsuite/libffi.call/cls_longdouble_va.c: Same. + +2010-10-01 Jakub Jelinek + + PR libffi/45677 + * src/x86/ffi64.c (ffi_prep_cif_machdep): Ensure cif->bytes is + a multiple of 8. + * testsuite/libffi.call/many2.c: New test. + +2010-08-20 Mark Wielaard + + * src/closures.c (open_temp_exec_file_mnt): Check if getmntent_r + returns NULL. + +2010-08-09 Andreas Tobler + + * configure.ac: Add target powerpc64-*-freebsd*. + * configure: Regenerate. + * testsuite/libffi.call/cls_align_longdouble_split.c: Pass + -mlong-double-128 only to linux targets. + * testsuite/libffi.call/cls_align_longdouble_split2.c: Likewise. + * testsuite/libffi.call/cls_longdouble.c: Likewise. + * testsuite/libffi.call/huge_struct.c: Likewise. + +2010-08-05 Dan Witte + + * Makefile.am: Pass FFI_DEBUG define to msvcc.sh for linking to the + debug CRT when --enable-debug is given. + * configure.ac: Define it. + * msvcc.sh: Translate -g and -DFFI_DEBUG appropriately. + +2010-08-04 Dan Witte + + * src/x86/ffitarget.h: Add X86_ANY define for all x86/x86_64 + platforms. + * src/x86/ffi.c: Remove redundant ifdef checks. + * src/prep_cif.c: Push stack space computation into src/x86/ffi.c + for X86_ANY so return value space doesn't get added twice. + +2010-08-03 Neil Rashbrooke + + * msvcc.sh: Don't pass -safeseh to ml64 because behavior is buggy. + +2010-07-22 Dan Witte + + * src/*/ffitarget.h: Make FFI_LAST_ABI one past the last valid ABI. + * src/prep_cif.c: Fix ABI assertion. + * src/cris/ffi.c: Ditto. + +2010-07-10 Evan Phoenix + + * src/closures.c (selinux_enabled_check): Fix strncmp usage bug. + +2010-07-07 Dan Horák + + * include/ffi.h.in: Protect #define with #ifndef. + * src/powerpc/ffitarget.h: Ditto. + * src/s390/ffitarget.h: Ditto. + * src/sparc/ffitarget.h: Ditto. + +2010-07-07 Neil Roberts + + * src/x86/sysv.S (ffi_call_SYSV): Align the stack pointer to + 16-bytes. + +2010-07-02 Jakub Jelinek + + * Makefile.am (AM_MAKEFLAGS): Pass also mandir to submakes. + * Makefile.in: Regenerated. + +2010-05-19 Rainer Orth + + * configure.ac (libffi_cv_as_x86_pcrel): Check for illegal in as + output, too. + (libffi_cv_as_ascii_pseudo_op): Check for .ascii. + (libffi_cv_as_string_pseudo_op): Check for .string. + * configure: Regenerate. + * fficonfig.h.in: Regenerate. + * src/x86/sysv.S (.eh_frame): Use .ascii, .string or error. + +2010-05-11 Dan Witte + + * doc/libffi.tex: Document previous change. + +2010-05-11 Makoto Kato + + * src/x86/ffi.c (ffi_call): Don't copy structs passed by value. + +2010-05-05 Michael Kohler + + * src/dlmalloc.c (dlfree): Fix spelling. + * src/ia64/ffi.c (ffi_prep_cif_machdep): Ditto. + * configure.ac: Ditto. + * configure: Rebuilt. + +2010-04-13 Dan Witte + + * msvcc.sh: Build with -W3 instead of -Wall. + * src/powerpc/ffi_darwin.c: Remove build warnings. + * src/x86/ffi.c: Ditto. + * src/x86/ffitarget.h: Ditto. + +2010-04-12 Dan Witte + Walter Meinl + + * configure.ac: Add OS/2 support. + * configure: Rebuilt. + * src/closures.c: Ditto. + * src/dlmalloc.c: Ditto. + * src/x86/win32.S: Ditto. + +2010-04-07 Jakub Jelinek + + * testsuite/libffi.call/err_bad_abi.c: Remove unused args variable. + +2010-04-02 Ralf Wildenhues + + * Makefile.in: Regenerate. + * aclocal.m4: Regenerate. + * include/Makefile.in: Regenerate. + * man/Makefile.in: Regenerate. + * testsuite/Makefile.in: Regenerate. + +2010-03-30 Dan Witte + + * msvcc.sh: Disable build warnings. + * README (tested): Clarify windows build procedure. + +2010-03-15 Rainer Orth + + * configure.ac (libffi_cv_as_x86_64_unwind_section_type): New test. + * configure: Regenerate. + * fficonfig.h.in: Regenerate. + * libffi/src/x86/unix64.S (.eh_frame) + [HAVE_AS_X86_64_UNWIND_SECTION_TYPE]: Use @unwind section type. + +2010-03-14 Matthias Klose + + * src/x86/ffi64.c: Fix typo in comment. + * src/x86/ffi.c: Use /* ... */ comment style. + +2010-02-24 Rainer Orth + + * doc/libffi.texi (The Closure API): Fix typo. + * doc/libffi.info: Remove. + +2010-02-15 Matthias Klose + + * src/arm/sysv.S (__ARM_ARCH__): Define for processor + __ARM_ARCH_7EM__. + +2010-01-15 Anthony Green + + * README: Add notes on building with Microsoft Visual C++. + +2010-01-15 Daniel Witte + + * msvcc.sh: New file. + + * src/x86/win32.S: Port assembly routines to MSVC and #ifdef. + * src/x86/ffi.c: Tweak function declaration and remove excess + parens. + * include/ffi.h.in: Add __declspec(align(8)) to typedef struct + ffi_closure. + + * src/x86/ffi.c: Merge ffi_call_SYSV and ffi_call_STDCALL into new + function ffi_call_win32 on X86_WIN32. + * src/x86/win32.S (ffi_call_SYSV): Rename to ffi_call_win32. + (ffi_call_STDCALL): Remove. + + * src/prep_cif.c (ffi_prep_cif): Move stack space allocation code + to ffi_prep_cif_machdep for x86. + * src/x86/ffi.c (ffi_prep_cif_machdep): To here. + +2010-01-15 Oliver Kiddle + + * src/x86/ffitarget.h (ffi_abi): Check for __i386 and __amd64 for + Sun Studio compiler compatibility. + +2010-01-12 Conrad Irwin + + * doc/libffi.texi: Add closure example. + +2010-01-07 Rainer Orth + + PR libffi/40701 + * testsuite/libffi.call/ffitest.h [__alpha__ && __osf__] (PRIdLL, + PRIuLL, PRId64, PRIu64, PRIuPTR): Define. + * testsuite/libffi.call/cls_align_sint64.c: Add -Wno-format on + alpha*-dec-osf*. + * testsuite/libffi.call/cls_align_uint64.c: Likewise. + * testsuite/libffi.call/cls_ulonglong.c: Likewise. + * testsuite/libffi.call/return_ll1.c: Likewise. + * testsuite/libffi.call/stret_medium2.c: Likewise. + * testsuite/libffi.special/ffitestcxx.h (allocate_mmap): Cast + MAP_FAILED to char *. + +2010-01-06 Rainer Orth + + * src/mips/n32.S: Use .abicalls and .eh_frame with __GNUC__. + +2009-12-31 Anthony Green + + * README: Update for libffi 3.0.9. + +2009-12-27 Matthias Klose + + * configure.ac (HAVE_LONG_DOUBLE): Define for mips when + appropriate. + * configure: Rebuilt. + +2009-12-26 Anthony Green + + * testsuite/libffi.call/cls_longdouble_va.c: Mark as xfail for + avr32*-*-*. + * testsuite/libffi.call/cls_double_va.c: Ditto. + +2009-12-26 Andreas Tobler + + * testsuite/libffi.call/ffitest.h: Conditionally include stdint.h + and inttypes.h. + * testsuite/libffi.special/unwindtest.cc: Ditto. + +2009-12-26 Andreas Tobler + + * configure.ac: Add amd64-*-openbsd*. + * configure: Rebuilt. + * testsuite/lib/libffi-dg.exp (libffi_target_compile): Link + openbsd programs with -lpthread. + +2009-12-26 Anthony Green + + * testsuite/libffi.call/cls_double_va.c, + testsuite/libffi.call/cls_longdouble.c, + testsuite/libffi.call/cls_longdouble_va.c, + testsuite/libffi.call/cls_pointer.c, + testsuite/libffi.call/cls_pointer_stack.c: Remove xfail for + mips*-*-* and arm*-*-*. + * testsuite/libffi.call/cls_align_longdouble_split.c, + testsuite/libffi.call/cls_align_longdouble_split2.c, + testsuite/libffi.call/stret_medium2.c, + testsuite/libffi.call/stret_medium.c, + testsuite/libffi.call/stret_large.c, + testsuite/libffi.call/stret_large2.c: Remove xfail for arm*-*-*. + +2009-12-31 Kay Tietz + + * testsuite/libffi.call/ffitest.h, + testsuite/libffi.special/ffitestcxx.h (PRIdLL, PRuLL): Fix + definitions. + +2009-12-31 Carlo Bramini + + * configure.ac (AM_LTLDFLAGS): Define for windows hosts. + * Makefile.am (libffi_la_LDFLAGS): Add AM_LTLDFLAGS. + * configure: Rebuilt. + * Makefile.in: Rebuilt. + +2009-12-31 Anthony Green + Blake Chaffin. + + * testsuite/libffi.call/huge_struct.c: New test case from Blake + Chaffin @ Apple. + +2009-12-28 David Edelsohn + + * src/powerpc/ffi_darwin.c (ffi_prep_args): Copy abi and nargs to + local variables. + (aix_adjust_aggregate_sizes): New function. + (ffi_prep_cif_machdep): Call it. + +2009-12-26 Andreas Tobler + + * configure.ac: Define FFI_MMAP_EXEC_WRIT for the given targets. + * configure: Regenerate. + * fficonfig.h.in: Likewise. + * src/closures.c: Remove the FFI_MMAP_EXEC_WRIT definition for + Solaris/x86. + +2009-12-26 Andreas Schwab + + * src/powerpc/ffi.c (ffi_prep_args_SYSV): Advance intarg_count + when a float arguments is passed in memory. + (ffi_closure_helper_SYSV): Mark general registers as used up when + a 64bit or soft-float long double argument is passed in memory. + +2009-12-25 Matthias Klose + + * man/ffi_call.3: Fix #include in examples. + * doc/libffi.texi: Add dircategory. + +2009-12-25 Frank Everdij + + * include/ffi.h.in: Placed '__GNUC__' ifdef around + '__attribute__((aligned(8)))' in ffi_closure, fixes compile for + IRIX MIPSPro c99. + * include/ffi_common.h: Added '__sgi' define to non + '__attribute__((__mode__()))' integer typedefs. + * src/mips/ffi.c (ffi_call, ffi_closure_mips_inner_O32, + ffi_closure_mips_inner_N32): Added 'defined(_MIPSEB)' to BE check. + (ffi_closure_mips_inner_O32, ffi_closure_mips_inner_N32): Added + FFI_LONGDOUBLE support and alignment(N32 only). + * src/mips/ffitarget.h: Corrected '#include ' for IRIX and + fixed non '__attribute__((__mode__()))' integer typedefs. + * src/mips/n32.S: Put '#ifdef linux' around '.abicalls' and '.eh_frame' + since they are Linux/GNU Assembler specific. + +2009-12-25 Bradley Smith + + * configure.ac, Makefile.am, src/avr32/ffi.c, + src/avr32/ffitarget.h, + src/avr32/sysv.S: Add AVR32 port. + * configure, Makefile.in: Rebuilt. + +2009-12-21 Andreas Tobler + + * configure.ac: Make i?86 build on FreeBSD and OpenBSD. + * configure: Regenerate. + +2009-12-15 John David Anglin + + * testsuite/libffi.call/ffitest.h: Define PRIuPTR on PA HP-UX. + +2009-12-13 John David Anglin + + * src/pa/ffi.c (ffi_closure_inner_pa32): Handle FFI_TYPE_LONGDOUBLE + type on HP-UX. + +2012-02-13 Kai Tietz + + PR libffi/52221 + * src/x86/ffi.c (ffi_prep_raw_closure_loc): Add thiscall + support for X86_WIN32. + (FFI_INIT_TRAMPOLINE_THISCALL): Fix displacement. + +2009-12-11 Eric Botcazou + + * src/sparc/ffi.c (ffi_closure_sparc_inner_v9): Properly align 'long + double' arguments. + +2009-12-11 Eric Botcazou + + * testsuite/libffi.call/ffitest.h: Define PRIuPTR on Solaris < 10. + +2009-12-10 Rainer Orth + + PR libffi/40700 + * src/closures.c [X86_64 && __sun__ && __svr4__] + (FFI_MMAP_EXEC_WRIT): Define. + +2009-12-08 David Daney + + * testsuite/libffi.call/stret_medium.c: Remove xfail for mips*-*-* + * testsuite/libffi.call/cls_align_longdouble_split2.c: Same. + * testsuite/libffi.call/stret_large.c: Same. + * testsuite/libffi.call/cls_align_longdouble_split.c: Same. + * testsuite/libffi.call/stret_large2.c: Same. + * testsuite/libffi.call/stret_medium2.c: Same. + +2009-12-07 David Edelsohn + + * src/powerpc/aix_closure.S (libffi_closure_ASM): Fix tablejump + typo. + +2009-12-05 David Edelsohn + + * src/powerpc/aix.S: Update AIX32 code to be consistent with AIX64 + code. + * src/powerpc/aix_closure.S: Same. + +2009-12-05 Ralf Wildenhues + + * Makefile.in: Regenerate. + * configure: Regenerate. + * include/Makefile.in: Regenerate. + * man/Makefile.in: Regenerate. + * testsuite/Makefile.in: Regenerate. + +2009-12-04 David Edelsohn + + * src/powerpc/aix_closure.S: Reorganize 64-bit code to match + linux64_closure.S. + +2009-12-04 Uros Bizjak + + PR libffi/41908 + * src/x86/ffi64.c (classify_argument): Update from + gcc/config/i386/i386.c. + (ffi_closure_unix64_inner): Do not use the address of two consecutive + SSE registers directly. + * testsuite/libffi.call/cls_dbls_struct.c (main): Remove xfail + for x86_64 linux targets. + +2009-12-04 David Edelsohn + + * src/powerpc/ffi_darwin.c (ffi_closure_helper_DARWIN): Increment + pfr for long double split between fpr13 and stack. + +2009-12-03 David Edelsohn + + * src/powerpc/ffi_darwin.c (ffi_prep_args): Increment next_arg and + fparg_count twice for long double. + +2009-12-03 David Edelsohn + + PR libffi/42243 + * src/powerpc/ffi_darwin.c (ffi_prep_args): Remove extra parentheses. + +2009-12-03 Uros Bizjak + + * testsuite/libffi.call/cls_longdouble_va.c (main): Fix format string. + Remove xfails for x86 linux targets. + +2009-12-02 David Edelsohn + + * src/powerpc/ffi_darwin.c (ffi_prep_args): Fix typo in INT64 + case. + +2009-12-01 David Edelsohn + + * src/powerpc/aix.S (ffi_call_AIX): Convert to more standard + register usage. Call ffi_prep_args directly. Add long double + return value support. + * src/powerpc/ffi_darwin.c (ffi_prep_args): Double arg increment + applies to FFI_TYPE_DOUBLE. Correct fpr_base increment typo. + Separate FFI_TYPE_SINT32 and FFI_TYPE_UINT32 cases. + (ffi_prep_cif_machdep): Only 16 byte stack alignment in 64 bit + mode. + (ffi_closure_helper_DARWIN): Remove nf and ng counters. Move temp + into case. + * src/powerpc/aix_closure.S: Maintain 16 byte stack alignment. + Allocate result area between params and FPRs. + +2009-11-30 David Edelsohn + + PR target/35484 + * src/powerpc/ffitarget.h (POWERPC64): Define for PPC64 Linux and + AIX64. + * src/powerpc/aix.S: Implement AIX64 version. + * src/powerpc/aix_closure.S: Implement AIX64 version. + (ffi_closure_ASM): Use extsb, lha and displament addresses. + * src/powerpc/ffi_darwin.c (ffi_prep_args): Implement AIX64 + support. + (ffi_prep_cif_machdep): Same. + (ffi_call): Same. + (ffi_closure_helper_DARWIN): Same. + +2009-11-02 Andreas Tobler + + PR libffi/41908 + * testsuite/libffi.call/testclosure.c: New test. + +2009-09-28 Kai Tietz + + * src/x86/win64.S (_ffi_call_win64 stack): Remove for gnu + assembly version use of ___chkstk. + +2009-09-23 Matthias Klose + + PR libffi/40242, PR libffi/41443 + * src/arm/sysv.S (__ARM_ARCH__): Define for processors + __ARM_ARCH_6T2__, __ARM_ARCH_6M__, __ARM_ARCH_7__, + __ARM_ARCH_7A__, __ARM_ARCH_7R__, __ARM_ARCH_7M__. + Change the conditionals to __SOFTFP__ || __ARM_EABI__ + for -mfloat-abi=softfp to work. + +2009-09-17 Loren J. Rittle + + PR testsuite/32843 (strikes again) + * src/x86/ffi.c (ffi_prep_cif_machdep): Add X86_FREEBSD to + enable proper extension on char and short. + +2009-09-15 David Daney + + * src/java_raw_api.c (ffi_java_raw_to_rvalue): Remove special + handling for FFI_TYPE_POINTER. + * src/mips/ffitarget.h (FFI_TYPE_STRUCT_D_SOFT, + FFI_TYPE_STRUCT_F_SOFT, FFI_TYPE_STRUCT_DD_SOFT, + FFI_TYPE_STRUCT_FF_SOFT, FFI_TYPE_STRUCT_FD_SOFT, + FFI_TYPE_STRUCT_DF_SOFT, FFI_TYPE_STRUCT_SOFT): New defines. + (FFI_N32_SOFT_FLOAT, FFI_N64_SOFT_FLOAT): New ffi_abi enumerations. + (enum ffi_abi): Set FFI_DEFAULT_ABI for soft-float. + * src/mips/n32.S (ffi_call_N32): Add handling for soft-float + structure and pointer returns. + (ffi_closure_N32): Add handling for pointer returns. + * src/mips/ffi.c (ffi_prep_args, calc_n32_struct_flags, + calc_n32_return_struct_flags): Handle soft-float. + (ffi_prep_cif_machdep): Handle soft-float, fix pointer handling. + (ffi_call_N32): Declare proper argument types. + (ffi_call, copy_struct_N32, ffi_closure_mips_inner_N32): Handle + soft-float. + +2009-08-24 Ralf Wildenhues + + * configure.ac (AC_PREREQ): Bump to 2.64. + +2009-08-22 Ralf Wildenhues + + * Makefile.am (install-html, install-pdf): Remove. + * Makefile.in: Regenerate. + + * Makefile.in: Regenerate. + * aclocal.m4: Regenerate. + * configure: Regenerate. + * fficonfig.h.in: Regenerate. + * include/Makefile.in: Regenerate. + * man/Makefile.in: Regenerate. + * testsuite/Makefile.in: Regenerate. + +2011-08-22 Jasper Lievisse Adriaanse + + * configure.ac: Add OpenBSD/hppa and OpenBSD/powerpc support. + * configure: Rebuilt. + +2009-07-30 Ralf Wildenhues + + * configure.ac (_AC_ARG_VAR_PRECIOUS): Use m4_rename_force. + +2009-07-24 Dave Korn + + PR libffi/40807 + * src/x86/ffi.c (ffi_prep_cif_machdep): Also use sign/zero-extending + return types for X86_WIN32. + * src/x86/win32.S (_ffi_call_SYSV): Handle omitted return types. + (_ffi_call_STDCALL, _ffi_closure_SYSV, _ffi_closure_raw_SYSV, + _ffi_closure_STDCALL): Likewise. + + * src/closures.c (is_selinux_enabled): Define to const 0 for Cygwin. + (dlmmap, dlmunmap): Also use these functions on Cygwin. + +2009-07-11 Richard Sandiford + + PR testsuite/40699 + PR testsuite/40707 + PR testsuite/40709 + * testsuite/lib/libffi-dg.exp: Revert 2009-07-02, 2009-07-01 and + 2009-06-30 commits. + +2009-07-01 Richard Sandiford + + * testsuite/lib/libffi-dg.exp (libffi-init): Set ld_library_path + to "" before adding paths. (This reinstates an assignment that + was removed by my 2009-06-30 commit, but changes the initial + value from "." to "".) + +2009-07-01 H.J. Lu + + PR testsuite/40601 + * testsuite/lib/libffi-dg.exp (libffi-init): Properly set + gccdir. Adjust ld_library_path for gcc only if gccdir isn't + empty. + +2009-06-30 Richard Sandiford + + * testsuite/lib/libffi-dg.exp (libffi-init): Don't add "." + to ld_library_path. Use add_path. Add just find_libgcc_s + to ld_library_path, not every libgcc multilib directory. + +2009-06-16 Wim Lewis + + * src/powerpc/ffi.c: Avoid clobbering cr3 and cr4, which are + supposed to be callee-saved. + * src/powerpc/sysv.S (small_struct_return_value): Fix overrun of + return buffer for odd-size structs. + +2009-06-16 Andreas Tobler + + PR libffi/40444 + * testsuite/lib/libffi-dg.exp (libffi_target_compile): Add + allow_stack_execute for Darwin. + +2009-06-16 Andrew Haley + + * configure.ac (TARGETDIR): Add missing blank lines. + * configure: Regenerate. + +2009-06-16 Andrew Haley + + * testsuite/libffi.call/cls_align_sint64.c, + testsuite/libffi.call/cls_align_uint64.c, + testsuite/libffi.call/cls_longdouble_va.c, + testsuite/libffi.call/cls_ulonglong.c, + testsuite/libffi.call/return_ll1.c, + testsuite/libffi.call/stret_medium2.c: Fix printf format + specifiers. + * testsuite/libffi.call/ffitest.h, + testsuite/libffi.special/ffitestcxx.h (PRIdLL, PRIuLL): Define. + +2009-06-15 Andrew Haley + + * testsuite/libffi.call/err_bad_typedef.c: xfail everywhere. + * testsuite/libffi.call/err_bad_abi.c: Likewise. + +2009-06-12 Andrew Haley + + * Makefile.am: Remove info_TEXINFOS. + +2009-06-12 Andrew Haley + + * ChangeLog.libffi: testsuite/libffi.call/cls_align_sint64.c, + testsuite/libffi.call/cls_align_uint64.c, + testsuite/libffi.call/cls_ulonglong.c, + testsuite/libffi.call/return_ll1.c, + testsuite/libffi.call/stret_medium2.c: Fix printf format + specifiers. + testsuite/libffi.special/unwindtest.cc: include stdint.h. + +2009-06-11 Timothy Wall + + * Makefile.am, + configure.ac, + include/ffi.h.in, + include/ffi_common.h, + src/closures.c, + src/dlmalloc.c, + src/x86/ffi.c, + src/x86/ffitarget.h, + src/x86/win64.S (new), + README: Added win64 support (mingw or MSVC) + * Makefile.in, + include/Makefile.in, + man/Makefile.in, + testsuite/Makefile.in, + configure, + aclocal.m4: Regenerated + * ltcf-c.sh: properly escape cygwin/w32 path + * man/ffi_call.3: Clarify size requirements for return value. + * src/x86/ffi64.c: Fix filename in comment. + * src/x86/win32.S: Remove unused extern. + + * testsuite/libffi.call/closure_fn0.c, + testsuite/libffi.call/closure_fn1.c, + testsuite/libffi.call/closure_fn2.c, + testsuite/libffi.call/closure_fn3.c, + testsuite/libffi.call/closure_fn4.c, + testsuite/libffi.call/closure_fn5.c, + testsuite/libffi.call/closure_fn6.c, + testsuite/libffi.call/closure_stdcall.c, + testsuite/libffi.call/cls_12byte.c, + testsuite/libffi.call/cls_16byte.c, + testsuite/libffi.call/cls_18byte.c, + testsuite/libffi.call/cls_19byte.c, + testsuite/libffi.call/cls_1_1byte.c, + testsuite/libffi.call/cls_20byte.c, + testsuite/libffi.call/cls_20byte1.c, + testsuite/libffi.call/cls_24byte.c, + testsuite/libffi.call/cls_2byte.c, + testsuite/libffi.call/cls_3_1byte.c, + testsuite/libffi.call/cls_3byte1.c, + testsuite/libffi.call/cls_3byte2.c, + testsuite/libffi.call/cls_4_1byte.c, + testsuite/libffi.call/cls_4byte.c, + testsuite/libffi.call/cls_5_1_byte.c, + testsuite/libffi.call/cls_5byte.c, + testsuite/libffi.call/cls_64byte.c, + testsuite/libffi.call/cls_6_1_byte.c, + testsuite/libffi.call/cls_6byte.c, + testsuite/libffi.call/cls_7_1_byte.c, + testsuite/libffi.call/cls_7byte.c, + testsuite/libffi.call/cls_8byte.c, + testsuite/libffi.call/cls_9byte1.c, + testsuite/libffi.call/cls_9byte2.c, + testsuite/libffi.call/cls_align_double.c, + testsuite/libffi.call/cls_align_float.c, + testsuite/libffi.call/cls_align_longdouble.c, + testsuite/libffi.call/cls_align_longdouble_split.c, + testsuite/libffi.call/cls_align_longdouble_split2.c, + testsuite/libffi.call/cls_align_pointer.c, + testsuite/libffi.call/cls_align_sint16.c, + testsuite/libffi.call/cls_align_sint32.c, + testsuite/libffi.call/cls_align_sint64.c, + testsuite/libffi.call/cls_align_uint16.c, + testsuite/libffi.call/cls_align_uint32.c, + testsuite/libffi.call/cls_align_uint64.c, + testsuite/libffi.call/cls_dbls_struct.c, + testsuite/libffi.call/cls_double.c, + testsuite/libffi.call/cls_double_va.c, + testsuite/libffi.call/cls_float.c, + testsuite/libffi.call/cls_longdouble.c, + testsuite/libffi.call/cls_longdouble_va.c, + testsuite/libffi.call/cls_multi_schar.c, + testsuite/libffi.call/cls_multi_sshort.c, + testsuite/libffi.call/cls_multi_sshortchar.c, + testsuite/libffi.call/cls_multi_uchar.c, + testsuite/libffi.call/cls_multi_ushort.c, + testsuite/libffi.call/cls_multi_ushortchar.c, + testsuite/libffi.call/cls_pointer.c, + testsuite/libffi.call/cls_pointer_stack.c, + testsuite/libffi.call/cls_schar.c, + testsuite/libffi.call/cls_sint.c, + testsuite/libffi.call/cls_sshort.c, + testsuite/libffi.call/cls_uchar.c, + testsuite/libffi.call/cls_uint.c, + testsuite/libffi.call/cls_ulonglong.c, + testsuite/libffi.call/cls_ushort.c, + testsuite/libffi.call/err_bad_abi.c, + testsuite/libffi.call/err_bad_typedef.c, + testsuite/libffi.call/float2.c, + testsuite/libffi.call/huge_struct.c, + testsuite/libffi.call/nested_struct.c, + testsuite/libffi.call/nested_struct1.c, + testsuite/libffi.call/nested_struct10.c, + testsuite/libffi.call/nested_struct2.c, + testsuite/libffi.call/nested_struct3.c, + testsuite/libffi.call/nested_struct4.c, + testsuite/libffi.call/nested_struct5.c, + testsuite/libffi.call/nested_struct6.c, + testsuite/libffi.call/nested_struct7.c, + testsuite/libffi.call/nested_struct8.c, + testsuite/libffi.call/nested_struct9.c, + testsuite/libffi.call/problem1.c, + testsuite/libffi.call/return_ldl.c, + testsuite/libffi.call/return_ll1.c, + testsuite/libffi.call/stret_large.c, + testsuite/libffi.call/stret_large2.c, + testsuite/libffi.call/stret_medium.c, + testsuite/libffi.call/stret_medium2.c, + testsuite/libffi.special/unwindtest.cc: use ffi_closure_alloc instead + of checking for MMAP. Use intptr_t instead of long casts. + +2009-06-11 Kaz Kojima + + * testsuite/libffi.call/cls_longdouble_va.c: Add xfail sh*-*-linux-*. + * testsuite/libffi.call/err_bad_abi.c: Add xfail sh*-*-*. + * testsuite/libffi.call/err_bad_typedef.c: Likewise. + +2009-06-09 Andrew Haley + + * src/x86/freebsd.S: Add missing file. + +2009-06-08 Andrew Haley + + Import from libffi 3.0.8: + + * doc/libffi.texi: New file. + * doc/libffi.info: Likewise. + * doc/stamp-vti: Likewise. + * man/Makefile.am: New file. + * man/ffi_call.3: New file. + + * Makefile.am (EXTRA_DIST): Add src/x86/darwin64.S, + src/dlmalloc.c. + (nodist_libffi_la_SOURCES): Add X86_FREEBSD. + + * configure.ac: Bump version to 3.0.8. + parisc*-*-linux*: Add. + i386-*-freebsd* | i386-*-openbsd*: Add. + powerpc-*-beos*: Add. + AM_CONDITIONAL X86_FREEBSD: Add. + AC_CONFIG_FILES: Add man/Makefile. + + * include/ffi.h.in (FFI_FN): Change void (*)() to void (*)(void). + +2009-06-08 Andrew Haley + + * README: Import from libffi 3.0.8. + +2009-06-08 Andrew Haley + + * testsuite/libffi.call/err_bad_abi.c: Add xfails. + * testsuite/libffi.call/cls_longdouble_va.c: Add xfails. + * testsuite/libffi.call/cls_dbls_struct.c: Add xfail x86_64-*-linux-*. + * testsuite/libffi.call/err_bad_typedef.c: Add xfails. + + * testsuite/libffi.call/stret_medium2.c: Add __UNUSED__ to args. + * testsuite/libffi.call/stret_medium.c: Likewise. + * testsuite/libffi.call/stret_large2.c: Likewise. + * testsuite/libffi.call/stret_large.c: Likewise. + +2008-12-26 Timothy Wall + + * testsuite/libffi.call/cls_longdouble.c, + testsuite/libffi.call/cls_longdouble_va.c, + testsuite/libffi.call/cls_align_longdouble.c, + testsuite/libffi.call/cls_align_longdouble_split.c, + testsuite/libffi.call/cls_align_longdouble_split2.c: mark expected + failures on x86_64 cygwin/mingw. + +2008-12-22 Timothy Wall + + * testsuite/libffi.call/closure_fn0.c, + testsuite/libffi.call/closure_fn1.c, + testsuite/libffi.call/closure_fn2.c, + testsuite/libffi.call/closure_fn3.c, + testsuite/libffi.call/closure_fn4.c, + testsuite/libffi.call/closure_fn5.c, + testsuite/libffi.call/closure_fn6.c, + testsuite/libffi.call/closure_loc_fn0.c, + testsuite/libffi.call/closure_stdcall.c, + testsuite/libffi.call/cls_align_pointer.c, + testsuite/libffi.call/cls_pointer.c, + testsuite/libffi.call/cls_pointer_stack.c: use portable cast from + pointer to integer (intptr_t). + * testsuite/libffi.call/cls_longdouble.c: disable for win64. + +2008-07-24 Anthony Green + + * testsuite/libffi.call/cls_dbls_struct.c, + testsuite/libffi.call/cls_double_va.c, + testsuite/libffi.call/cls_longdouble.c, + testsuite/libffi.call/cls_longdouble_va.c, + testsuite/libffi.call/cls_pointer.c, + testsuite/libffi.call/cls_pointer_stack.c, + testsuite/libffi.call/err_bad_abi.c: Clean up failures from + compiler warnings. + +2008-03-04 Anthony Green + Blake Chaffin + hos@tamanegi.org + + * testsuite/libffi.call/cls_align_longdouble_split2.c + testsuite/libffi.call/cls_align_longdouble_split.c + testsuite/libffi.call/cls_dbls_struct.c + testsuite/libffi.call/cls_double_va.c + testsuite/libffi.call/cls_longdouble.c + testsuite/libffi.call/cls_longdouble_va.c + testsuite/libffi.call/cls_pointer.c + testsuite/libffi.call/cls_pointer_stack.c + testsuite/libffi.call/err_bad_abi.c + testsuite/libffi.call/err_bad_typedef.c + testsuite/libffi.call/stret_large2.c + testsuite/libffi.call/stret_large.c + testsuite/libffi.call/stret_medium2.c + testsuite/libffi.call/stret_medium.c: New tests from Apple. + +2009-06-05 Andrew Haley + + * src/x86/ffitarget.h, src/x86/ffi.c: Merge stdcall changes from + libffi. + +2009-06-04 Andrew Haley + + * src/x86/ffitarget.h, src/x86/win32.S, src/x86/ffi.c: Back out + stdcall changes. + +2008-02-26 Anthony Green + Thomas Heller + + * src/x86/ffi.c (ffi_closure_SYSV_inner): Change C++ comment to C + comment. + +2008-02-03 Timothy Wall + + * src/x86/ffi.c (FFI_INIT_TRAMPOLINE_STDCALL): Calculate jump return + offset based on code pointer, not data pointer. + +2008-01-31 Timothy Wall + + * testsuite/libffi.call/closure_stdcall.c: Add test for stdcall + closures. + * src/x86/ffitarget.h: Increase size of trampoline for stdcall + closures. + * src/x86/win32.S: Add assembly for stdcall closure. + * src/x86/ffi.c: Initialize stdcall closure trampoline. + +2009-06-04 Andrew Haley + + * include/ffi.h.in: Change void (*)() to void (*)(void). + * src/x86/ffi.c: Likewise. + +2009-06-04 Andrew Haley + + * src/powerpc/ppc_closure.S: Insert licence header. + * src/powerpc/linux64_closure.S: Likewise. + * src/m68k/sysv.S: Likewise. + + * src/sh64/ffi.c: Change void (*)() to void (*)(void). + * src/powerpc/ffi.c: Likewise. + * src/powerpc/ffi_darwin.c: Likewise. + * src/m32r/ffi.c: Likewise. + * src/sh64/ffi.c: Likewise. + * src/x86/ffi64.c: Likewise. + * src/alpha/ffi.c: Likewise. + * src/alpha/osf.S: Likewise. + * src/frv/ffi.c: Likewise. + * src/s390/ffi.c: Likewise. + * src/pa/ffi.c: Likewise. + * src/pa/hpux32.S: Likewise. + * src/ia64/unix.S: Likewise. + * src/ia64/ffi.c: Likewise. + * src/sparc/ffi.c: Likewise. + * src/mips/ffi.c: Likewise. + * src/sh/ffi.c: Likewise. + +2008-02-15 David Daney + + * src/mips/ffi.c (USE__BUILTIN___CLEAR_CACHE): + Define (conditionally), and use it to include cachectl.h. + (ffi_prep_closure_loc): Fix cache flushing. + * src/mips/ffitarget.h (_ABIN32, _ABI64, _ABIO32): Define. + +2009-06-04 Andrew Haley + + include/ffi.h.in, + src/arm/ffitarget.h, + src/arm/ffi.c, + src/arm/sysv.S, + src/powerpc/ffitarget.h, + src/closures.c, + src/sh64/ffitarget.h, + src/sh64/ffi.c, + src/sh64/sysv.S, + src/types.c, + src/x86/ffi64.c, + src/x86/ffitarget.h, + src/x86/win32.S, + src/x86/darwin.S, + src/x86/ffi.c, + src/x86/sysv.S, + src/x86/unix64.S, + src/alpha/ffitarget.h, + src/alpha/ffi.c, + src/alpha/osf.S, + src/m68k/ffitarget.h, + src/frv/ffitarget.h, + src/frv/ffi.c, + src/s390/ffitarget.h, + src/s390/sysv.S, + src/cris/ffitarget.h, + src/pa/linux.S, + src/pa/ffitarget.h, + src/pa/ffi.c, + src/raw_api.c, + src/ia64/ffitarget.h, + src/ia64/unix.S, + src/ia64/ffi.c, + src/ia64/ia64_flags.h, + src/java_raw_api.c, + src/debug.c, + src/sparc/v9.S, + src/sparc/ffitarget.h, + src/sparc/ffi.c, + src/sparc/v8.S, + src/mips/ffitarget.h, + src/mips/n32.S, + src/mips/o32.S, + src/mips/ffi.c, + src/prep_cif.c, + src/sh/ffitarget.h, + src/sh/ffi.c, + src/sh/sysv.S: Update license text. + +2009-05-22 Dave Korn + + * src/x86/win32.S (_ffi_closure_STDCALL): New function. + (.eh_frame): Add FDE for it. + +2009-05-22 Dave Korn + + * configure.ac: Also check if assembler supports pc-relative + relocs on X86_WIN32 targets. + * configure: Regenerate. + * src/x86/win32.S (ffi_prep_args): Declare extern, not global. + (_ffi_call_SYSV): Add missing function type symbol .def and + add EH markup labels. + (_ffi_call_STDCALL): Likewise. + (_ffi_closure_SYSV): Likewise. + (_ffi_closure_raw_SYSV): Likewise. + (.eh_frame): Add hand-crafted EH data. + +2009-04-09 Jakub Jelinek + + * testsuite/lib/libffi-dg.exp: Change copyright header to refer to + version 3 of the GNU General Public License and to point readers + at the COPYING3 file and the FSF's license web page. + * testsuite/libffi.call/call.exp: Likewise. + * testsuite/libffi.special/special.exp: Likewise. + +2009-03-01 Ralf Wildenhues + + * configure: Regenerate. + +2008-12-18 Rainer Orth + + PR libffi/26048 + * configure.ac (HAVE_AS_X86_PCREL): New test. + * configure: Regenerate. + * fficonfig.h.in: Regenerate. + * src/x86/sysv.S [!FFI_NO_RAW_API]: Precalculate + RAW_CLOSURE_CIF_OFFSET, RAW_CLOSURE_FUN_OFFSET, + RAW_CLOSURE_USER_DATA_OFFSET for the Solaris 10/x86 assembler. + (.eh_frame): Only use SYMBOL-. iff HAVE_AS_X86_PCREL. + * src/x86/unix64.S (.Lstore_table): Move to .text section. + (.Lload_table): Likewise. + (.eh_frame): Only use SYMBOL-. iff HAVE_AS_X86_PCREL. + +2008-12-18 Ralf Wildenhues + + * configure: Regenerate. + +2008-11-21 Eric Botcazou + + * src/sparc/ffi.c (ffi_prep_cif_machdep): Add support for + signed/unsigned int8/16 return values. + * src/sparc/v8.S (ffi_call_v8): Likewise. + (ffi_closure_v8): Likewise. + +2008-09-26 Peter O'Gorman + Steve Ellcey + + * configure: Regenerate for new libtool. + * Makefile.in: Ditto. + * include/Makefile.in: Ditto. + * aclocal.m4: Ditto. + +2008-08-25 Andreas Tobler + + * src/powerpc/ffitarget.h (ffi_abi): Add FFI_LINUX and + FFI_LINUX_SOFT_FLOAT to the POWERPC_FREEBSD enum. + Add note about flag bits used for FFI_SYSV_TYPE_SMALL_STRUCT. + Adjust copyright notice. + * src/powerpc/ffi.c: Add two new flags to indicate if we have one + register or two register to use for FFI_SYSV structs. + (ffi_prep_cif_machdep): Pass the right register flag introduced above. + (ffi_closure_helper_SYSV): Fix the return type for + FFI_SYSV_TYPE_SMALL_STRUCT. Comment. + Adjust copyright notice. + +2008-07-16 Kaz Kojima + + * src/sh/ffi.c (ffi_prep_closure_loc): Turn INSN into an unsigned + int. + +2008-06-17 Ralf Wildenhues + + * configure: Regenerate. + * include/Makefile.in: Regenerate. + * testsuite/Makefile.in: Regenerate. + +2008-06-07 Joseph Myers + + * configure.ac (parisc*-*-linux*, powerpc-*-sysv*, + powerpc-*-beos*): Remove. + * configure: Regenerate. + +2008-05-09 Julian Brown + + * Makefile.am (LTLDFLAGS): New. + (libffi_la_LDFLAGS): Use above. + * Makefile.in: Regenerate. + +2008-04-18 Paolo Bonzini + + PR bootstrap/35457 + * aclocal.m4: Regenerate. + * configure: Regenerate. + +2008-03-26 Kaz Kojima + + * src/sh/sysv.S: Add .note.GNU-stack on Linux. + * src/sh64/sysv.S: Likewise. + +2008-03-26 Daniel Jacobowitz + + * src/arm/sysv.S: Fix ARM comment marker. + +2008-03-26 Jakub Jelinek + + * src/alpha/osf.S: Add .note.GNU-stack on Linux. + * src/s390/sysv.S: Likewise. + * src/powerpc/ppc_closure.S: Likewise. + * src/powerpc/sysv.S: Likewise. + * src/x86/unix64.S: Likewise. + * src/x86/sysv.S: Likewise. + * src/sparc/v8.S: Likewise. + * src/sparc/v9.S: Likewise. + * src/m68k/sysv.S: Likewise. + * src/arm/sysv.S: Likewise. + +2008-03-16 Ralf Wildenhues + + * aclocal.m4: Regenerate. + * configure: Likewise. + * Makefile.in: Likewise. + * include/Makefile.in: Likewise. + * testsuite/Makefile.in: Likewise. + +2008-02-12 Bjoern Koenig + Andreas Tobler + + * configure.ac: Add amd64-*-freebsd* target. + * configure: Regenerate. + +2008-01-30 H.J. Lu + + PR libffi/34612 + * src/x86/sysv.S (ffi_closure_SYSV): Pop 4 byte from stack when + returning struct. + + * testsuite/libffi.call/call.exp: Add "-O2 -fomit-frame-pointer" + tests. + +2008-01-24 David Edelsohn + + * configure: Regenerate. + +2008-01-06 Andreas Tobler + + * src/x86/ffi.c (ffi_prep_cif_machdep): Fix thinko. + +2008-01-05 Andreas Tobler + + PR testsuite/32843 + * src/x86/ffi.c (ffi_prep_cif_machdep): Add code for + signed/unsigned int8/16 for X86_DARWIN. + Updated copyright info. + Handle one and two byte structs with special cif->flags. + * src/x86/ffitarget.h: Add special types for one and two byte structs. + Updated copyright info. + * src/x86/darwin.S (ffi_call_SYSV): Rewrite to use a jump table like + sysv.S + Remove code to pop args from the stack after call. + Special-case signed/unsigned for int8/16, one and two byte structs. + (ffi_closure_raw_SYSV): Handle FFI_TYPE_UINT8, + FFI_TYPE_SINT8, FFI_TYPE_UINT16, FFI_TYPE_SINT16, FFI_TYPE_UINT32, + FFI_TYPE_SINT32. + Updated copyright info. + +2007-12-08 David Daney + + * src/mips/n32.S (ffi_call_N32): Replace dadd with ADDU, dsub with + SUBU, add with ADDU and use smaller code sequences. + +2007-12-07 David Daney + + * src/mips/ffi.c (ffi_prep_cif_machdep): Handle long double return + type. + +2007-12-06 David Daney + + * include/ffi.h.in (FFI_SIZEOF_JAVA_RAW): Define if not already + defined. + (ffi_java_raw): New typedef. + (ffi_java_raw_call, ffi_java_ptrarray_to_raw, + ffi_java_raw_to_ptrarray): Change parameter types from ffi_raw to + ffi_java_raw. + (ffi_java_raw_closure) : Same. + (ffi_prep_java_raw_closure, ffi_prep_java_raw_closure_loc): Change + parameter types. + * src/java_raw_api.c (ffi_java_raw_size): Replace FFI_SIZEOF_ARG with + FFI_SIZEOF_JAVA_RAW. + (ffi_java_raw_to_ptrarray): Change type of raw to ffi_java_raw. + Replace FFI_SIZEOF_ARG with FFI_SIZEOF_JAVA_RAW. Use + sizeof(ffi_java_raw) for alignment calculations. + (ffi_java_ptrarray_to_raw): Same. + (ffi_java_rvalue_to_raw): Add special handling for FFI_TYPE_POINTER + if FFI_SIZEOF_JAVA_RAW == 4. + (ffi_java_raw_to_rvalue): Same. + (ffi_java_raw_call): Change type of raw to ffi_java_raw. + (ffi_java_translate_args): Same. + (ffi_prep_java_raw_closure_loc, ffi_prep_java_raw_closure): Change + parameter types. + * src/mips/ffitarget.h (FFI_SIZEOF_JAVA_RAW): Define for N32 ABI. + +2007-12-06 David Daney + + * src/mips/n32.S (ffi_closure_N32): Use 64-bit add instruction on + pointer values. + +2007-12-01 Andreas Tobler + + PR libffi/31937 + * src/powerpc/ffitarget.h: Introduce new ABI FFI_LINUX_SOFT_FLOAT. + Add local FFI_TYPE_UINT128 to handle soft-float long-double-128. + * src/powerpc/ffi.c: Distinguish between __NO_FPRS__ and not and + set the NUM_FPR_ARG_REGISTERS according to. + Add support for potential soft-float support under hard-float + architecture. + (ffi_prep_args_SYSV): Set NUM_FPR_ARG_REGISTERS to 0 in case of + FFI_LINUX_SOFT_FLOAT, handle float, doubles and long-doubles according + to the FFI_LINUX_SOFT_FLOAT ABI. + (ffi_prep_cif_machdep): Likewise. + (ffi_closure_helper_SYSV): Likewise. + * src/powerpc/ppc_closure.S: Make sure not to store float/double + on archs where __NO_FPRS__ is true. + Add FFI_TYPE_UINT128 support. + * src/powerpc/sysv.S: Add support for soft-float long-double-128. + Adjust copyright notice. + +2007-11-25 Andreas Tobler + + * src/closures.c: Move defintion of MAYBE_UNUSED from here to ... + * include/ffi_common.h: ... here. + Update copyright. + +2007-11-17 Andreas Tobler + + * src/powerpc/sysv.S: Load correct cr to compare if we have long double. + * src/powerpc/linux64.S: Likewise. + * src/powerpc/ffi.c: Add a comment to show which part goes into cr6. + * testsuite/libffi.call/return_ldl.c: New test. + +2007-09-04 + + * src/arm/sysv.S (UNWIND): New. + (Whole file): Conditionally compile unwinder directives. + * src/arm/sysv.S: Add unwinder directives. + + * src/arm/ffi.c (ffi_prep_args): Align structs by at least 4 bytes. + Only treat r0 as a struct address if we're actually returning a + struct by address. + Only copy the bytes that are actually within a struct. + (ffi_prep_cif_machdep): A Composite Type not larger than 4 bytes + is returned in r0, not passed by address. + (ffi_call): Allocate a word-sized temporary for the case where + a composite is returned in r0. + (ffi_prep_incoming_args_SYSV): Align as necessary. + +2007-08-05 Steven Newbury + + * src/arm/ffi.c (FFI_INIT_TRAMPOLINE): Use __clear_cache instead of + directly using the sys_cacheflush syscall. + +2007-07-27 Andrew Haley + + * src/arm/sysv.S (ffi_closure_SYSV): Add soft-float. + +2007-09-03 Maciej W. Rozycki + + * Makefile.am: Unify MIPS_IRIX and MIPS_LINUX into MIPS. + * configure.ac: Likewise. + * Makefile.in: Regenerate. + * include/Makefile.in: Likewise. + * testsuite/Makefile.in: Likewise. + * configure: Likewise. + +2007-08-24 David Daney + + * testsuite/libffi.call/return_sl.c: New test. + +2007-08-10 David Daney + + * testsuite/libffi.call/cls_multi_ushort.c, + testsuite/libffi.call/cls_align_uint16.c, + testsuite/libffi.call/nested_struct1.c, + testsuite/libffi.call/nested_struct3.c, + testsuite/libffi.call/cls_7_1_byte.c, + testsuite/libffi.call/nested_struct5.c, + testsuite/libffi.call/cls_double.c, + testsuite/libffi.call/nested_struct7.c, + testsuite/libffi.call/cls_sint.c, + testsuite/libffi.call/nested_struct9.c, + testsuite/libffi.call/cls_20byte1.c, + testsuite/libffi.call/cls_multi_sshortchar.c, + testsuite/libffi.call/cls_align_sint64.c, + testsuite/libffi.call/cls_3byte2.c, + testsuite/libffi.call/cls_multi_schar.c, + testsuite/libffi.call/cls_multi_uchar.c, + testsuite/libffi.call/cls_19byte.c, + testsuite/libffi.call/cls_9byte1.c, + testsuite/libffi.call/cls_align_float.c, + testsuite/libffi.call/closure_fn1.c, + testsuite/libffi.call/problem1.c, + testsuite/libffi.call/closure_fn3.c, + testsuite/libffi.call/cls_sshort.c, + testsuite/libffi.call/closure_fn5.c, + testsuite/libffi.call/cls_align_double.c, + testsuite/libffi.call/nested_struct.c, + testsuite/libffi.call/cls_2byte.c, + testsuite/libffi.call/nested_struct10.c, + testsuite/libffi.call/cls_4byte.c, + testsuite/libffi.call/cls_6byte.c, + testsuite/libffi.call/cls_8byte.c, + testsuite/libffi.call/cls_multi_sshort.c, + testsuite/libffi.call/cls_align_sint16.c, + testsuite/libffi.call/cls_align_uint32.c, + testsuite/libffi.call/cls_20byte.c, + testsuite/libffi.call/cls_float.c, + testsuite/libffi.call/nested_struct2.c, + testsuite/libffi.call/cls_5_1_byte.c, + testsuite/libffi.call/nested_struct4.c, + testsuite/libffi.call/cls_24byte.c, + testsuite/libffi.call/nested_struct6.c, + testsuite/libffi.call/cls_64byte.c, + testsuite/libffi.call/nested_struct8.c, + testsuite/libffi.call/cls_uint.c, + testsuite/libffi.call/cls_multi_ushortchar.c, + testsuite/libffi.call/cls_schar.c, + testsuite/libffi.call/cls_uchar.c, + testsuite/libffi.call/cls_align_uint64.c, + testsuite/libffi.call/cls_ulonglong.c, + testsuite/libffi.call/cls_align_longdouble.c, + testsuite/libffi.call/cls_1_1byte.c, + testsuite/libffi.call/cls_12byte.c, + testsuite/libffi.call/cls_3_1byte.c, + testsuite/libffi.call/cls_3byte1.c, + testsuite/libffi.call/cls_4_1byte.c, + testsuite/libffi.call/cls_6_1_byte.c, + testsuite/libffi.call/cls_16byte.c, + testsuite/libffi.call/cls_18byte.c, + testsuite/libffi.call/closure_fn0.c, + testsuite/libffi.call/cls_9byte2.c, + testsuite/libffi.call/closure_fn2.c, + testsuite/libffi.call/closure_fn4.c, + testsuite/libffi.call/cls_ushort.c, + testsuite/libffi.call/closure_fn6.c, + testsuite/libffi.call/cls_5byte.c, + testsuite/libffi.call/cls_align_pointer.c, + testsuite/libffi.call/cls_7byte.c, + testsuite/libffi.call/cls_align_sint32.c, + testsuite/libffi.special/unwindtest_ffi_call.cc, + testsuite/libffi.special/unwindtest.cc: Remove xfail for mips64*-*-*. + +2007-08-10 David Daney + + PR libffi/28313 + * configure.ac: Don't treat mips64 as a special case. + * Makefile.am (nodist_libffi_la_SOURCES): Add n32.S. + * configure: Regenerate + * Makefile.in: Ditto. + * fficonfig.h.in: Ditto. + * src/mips/ffitarget.h (REG_L, REG_S, SUBU, ADDU, SRL, LI): Indent. + (LA, EH_FRAME_ALIGN, FDE_ADDR_BYTES): New preprocessor macros. + (FFI_DEFAULT_ABI): Set for n64 case. + (FFI_CLOSURES, FFI_TRAMPOLINE_SIZE): Define for n32 and n64 cases. + * src/mips/n32.S (ffi_call_N32): Add debug macros and labels for FDE. + (ffi_closure_N32): New function. + (.eh_frame): New section + * src/mips/o32.S: Clean up comments. + (ffi_closure_O32): Pass ffi_closure parameter in $12. + * src/mips/ffi.c: Use FFI_MIPS_N32 instead of + _MIPS_SIM == _ABIN32 throughout. + (FFI_MIPS_STOP_HERE): New, use in place of + ffi_stop_here. + (ffi_prep_args): Use unsigned long to hold pointer values. Rewrite + to support n32/n64 ABIs. + (calc_n32_struct_flags): Rewrite. + (calc_n32_return_struct_flags): Remove unused variable. Reverse + position of flag bits. + (ffi_prep_cif_machdep): Rewrite n32 portion. + (ffi_call): Enable for n64. Add special handling for small structure + return values. + (ffi_prep_closure_loc): Add n32 and n64 support. + (ffi_closure_mips_inner_O32): Add cast to silence warning. + (copy_struct_N32, ffi_closure_mips_inner_N32): New functions. + +2007-08-08 David Daney + + * testsuite/libffi.call/ffitest.h (ffi_type_mylong): Remove definition. + * testsuite/libffi.call/cls_align_uint16.c (main): Use correct type + specifiers. + * testsuite/libffi.call/nested_struct1.c (main): Ditto. + * testsuite/libffi.call/cls_sint.c (main): Ditto. + * testsuite/libffi.call/nested_struct9.c (main): Ditto. + * testsuite/libffi.call/cls_20byte1.c (main): Ditto. + * testsuite/libffi.call/cls_9byte1.c (main): Ditto. + * testsuite/libffi.call/closure_fn1.c (main): Ditto. + * testsuite/libffi.call/closure_fn3.c (main): Ditto. + * testsuite/libffi.call/return_dbl2.c (main): Ditto. + * testsuite/libffi.call/cls_sshort.c (main): Ditto. + * testsuite/libffi.call/return_fl3.c (main): Ditto. + * testsuite/libffi.call/closure_fn5.c (main): Ditto. + * testsuite/libffi.call/nested_struct.c (main): Ditto. + * testsuite/libffi.call/nested_struct10.c (main): Ditto. + * testsuite/libffi.call/return_ll1.c (main): Ditto. + * testsuite/libffi.call/cls_8byte.c (main): Ditto. + * testsuite/libffi.call/cls_align_uint32.c (main): Ditto. + * testsuite/libffi.call/cls_align_sint16.c (main): Ditto. + * testsuite/libffi.call/cls_20byte.c (main): Ditto. + * testsuite/libffi.call/nested_struct2.c (main): Ditto. + * testsuite/libffi.call/cls_24byte.c (main): Ditto. + * testsuite/libffi.call/nested_struct6.c (main): Ditto. + * testsuite/libffi.call/cls_uint.c (main): Ditto. + * testsuite/libffi.call/cls_12byte.c (main): Ditto. + * testsuite/libffi.call/cls_16byte.c (main): Ditto. + * testsuite/libffi.call/closure_fn0.c (main): Ditto. + * testsuite/libffi.call/cls_9byte2.c (main): Ditto. + * testsuite/libffi.call/closure_fn2.c (main): Ditto. + * testsuite/libffi.call/return_dbl1.c (main): Ditto. + * testsuite/libffi.call/closure_fn4.c (main): Ditto. + * testsuite/libffi.call/closure_fn6.c (main): Ditto. + * testsuite/libffi.call/cls_align_sint32.c (main): Ditto. + +2007-08-07 Andrew Haley + + * src/x86/sysv.S (ffi_closure_raw_SYSV): Fix typo in previous + checkin. + +2007-08-06 Andrew Haley + + PR testsuite/32843 + * src/x86/sysv.S (ffi_closure_raw_SYSV): Handle FFI_TYPE_UINT8, + FFI_TYPE_SINT8, FFI_TYPE_UINT16, FFI_TYPE_SINT16, FFI_TYPE_UINT32, + FFI_TYPE_SINT32. + +2007-08-02 David Daney + + * testsuite/libffi.call/return_ul.c (main): Define return type as + ffi_arg. Use proper printf conversion specifier. + +2007-07-30 Andrew Haley + + PR testsuite/32843 + * src/x86/ffi.c (ffi_prep_cif_machdep): in x86 case, add code for + signed/unsigned int8/16. + * src/x86/sysv.S (ffi_call_SYSV): Rewrite to: + Use a jump table. + Remove code to pop args from the stack after call. + Special-case signed/unsigned int8/16. + * testsuite/libffi.call/return_sc.c (main): Revert. + +2007-07-26 Richard Guenther + + PR testsuite/32843 + * testsuite/libffi.call/return_sc.c (main): Verify call + result as signed char, not ffi_arg. + +2007-07-16 Rainer Orth + + * configure.ac (i?86-*-solaris2.1[0-9]): Set TARGET to X86_64. + * configure: Regenerate. + +2007-07-11 David Daney + + * src/mips/ffi.c: Don't include sys/cachectl.h. + (ffi_prep_closure_loc): Use __builtin___clear_cache() instead of + cacheflush(). + +2007-05-18 Aurelien Jarno + + * src/arm/ffi.c (ffi_prep_closure_loc): Renamed and ajusted + from (ffi_prep_closure): ... this. + (FFI_INIT_TRAMPOLINE): Adjust. + +2005-12-31 Phil Blundell + + * src/arm/ffi.c (ffi_prep_incoming_args_SYSV, + ffi_closure_SYSV_inner, ffi_prep_closure): New, add closure support. + * src/arm/sysv.S(ffi_closure_SYSV): Likewise. + * src/arm/ffitarget.h (FFI_TRAMPOLINE_SIZE): Likewise. + (FFI_CLOSURES): Enable closure support. + +2007-07-03 Andrew Haley + + * testsuite/libffi.call/cls_multi_ushort.c, + testsuite/libffi.call/cls_align_uint16.c, + testsuite/libffi.call/nested_struct1.c, + testsuite/libffi.call/nested_struct3.c, + testsuite/libffi.call/cls_7_1_byte.c, + testsuite/libffi.call/cls_double.c, + testsuite/libffi.call/nested_struct5.c, + testsuite/libffi.call/nested_struct7.c, + testsuite/libffi.call/cls_sint.c, + testsuite/libffi.call/nested_struct9.c, + testsuite/libffi.call/cls_20byte1.c, + testsuite/libffi.call/cls_multi_sshortchar.c, + testsuite/libffi.call/cls_align_sint64.c, + testsuite/libffi.call/cls_3byte2.c, + testsuite/libffi.call/cls_multi_schar.c, + testsuite/libffi.call/cls_multi_uchar.c, + testsuite/libffi.call/cls_19byte.c, + testsuite/libffi.call/cls_9byte1.c, + testsuite/libffi.call/cls_align_float.c, + testsuite/libffi.call/closure_fn1.c, + testsuite/libffi.call/problem1.c, + testsuite/libffi.call/closure_fn3.c, + testsuite/libffi.call/cls_sshort.c, + testsuite/libffi.call/closure_fn5.c, + testsuite/libffi.call/cls_align_double.c, + testsuite/libffi.call/cls_2byte.c, + testsuite/libffi.call/nested_struct.c, + testsuite/libffi.call/nested_struct10.c, + testsuite/libffi.call/cls_4byte.c, + testsuite/libffi.call/cls_6byte.c, + testsuite/libffi.call/cls_8byte.c, + testsuite/libffi.call/cls_multi_sshort.c, + testsuite/libffi.call/cls_align_uint32.c, + testsuite/libffi.call/cls_align_sint16.c, + testsuite/libffi.call/cls_float.c, + testsuite/libffi.call/cls_20byte.c, + testsuite/libffi.call/cls_5_1_byte.c, + testsuite/libffi.call/nested_struct2.c, + testsuite/libffi.call/cls_24byte.c, + testsuite/libffi.call/nested_struct4.c, + testsuite/libffi.call/nested_struct6.c, + testsuite/libffi.call/cls_64byte.c, + testsuite/libffi.call/nested_struct8.c, + testsuite/libffi.call/cls_uint.c, + testsuite/libffi.call/cls_multi_ushortchar.c, + testsuite/libffi.call/cls_schar.c, + testsuite/libffi.call/cls_uchar.c, + testsuite/libffi.call/cls_align_uint64.c, + testsuite/libffi.call/cls_ulonglong.c, + testsuite/libffi.call/cls_align_longdouble.c, + testsuite/libffi.call/cls_1_1byte.c, + testsuite/libffi.call/cls_12byte.c, + testsuite/libffi.call/cls_3_1byte.c, + testsuite/libffi.call/cls_3byte1.c, + testsuite/libffi.call/cls_4_1byte.c, + testsuite/libffi.call/cls_6_1_byte.c, + testsuite/libffi.call/cls_16byte.c, + testsuite/libffi.call/cls_18byte.c, + testsuite/libffi.call/closure_fn0.c, + testsuite/libffi.call/cls_9byte2.c, + testsuite/libffi.call/closure_fn2.c, + testsuite/libffi.call/closure_fn4.c, + testsuite/libffi.call/cls_ushort.c, + testsuite/libffi.call/closure_fn6.c, + testsuite/libffi.call/cls_5byte.c, + testsuite/libffi.call/cls_align_pointer.c, + testsuite/libffi.call/cls_7byte.c, + testsuite/libffi.call/cls_align_sint32.c, + testsuite/libffi.special/unwindtest_ffi_call.cc, + testsuite/libffi.special/unwindtest.cc: Enable for ARM. + +2007-07-05 H.J. Lu + + * aclocal.m4: Regenerated. + +2007-06-02 Paolo Bonzini + + * configure: Regenerate. + +2007-05-23 Steve Ellcey + + * Makefile.in: Regenerate. + * configure: Regenerate. + * aclocal.m4: Regenerate. + * include/Makefile.in: Regenerate. + * testsuite/Makefile.in: Regenerate. + +2007-05-10 Roman Zippel + + * src/m68k/ffi.c (ffi_prep_incoming_args_SYSV, + ffi_closure_SYSV_inner,ffi_prep_closure): New, add closure support. + * src/m68k/sysv.S(ffi_closure_SYSV,ffi_closure_struct_SYSV): Likewise. + * src/m68k/ffitarget.h (FFI_TRAMPOLINE_SIZE): Likewise. + (FFI_CLOSURES): Enable closure support. + +2007-05-10 Roman Zippel + + * configure.ac (HAVE_AS_CFI_PSEUDO_OP): New test. + * configure: Regenerate. + * fficonfig.h.in: Regenerate. + * src/m68k/sysv.S (CFI_STARTPROC,CFI_ENDPROC, + CFI_OFFSET,CFI_DEF_CFA): New macros. + (ffi_call_SYSV): Add callframe annotation. + +2007-05-10 Roman Zippel + + * src/m68k/ffi.c (ffi_prep_args,ffi_prep_cif_machdep): Fix + numerous test suite failures. + * src/m68k/sysv.S (ffi_call_SYSV): Likewise. + +2007-04-11 Paolo Bonzini + + * Makefile.am (EXTRA_DIST): Bring up to date. + * Makefile.in: Regenerate. + * src/frv/eabi.S: Remove RCS keyword. + +2007-04-06 Richard Henderson + + * configure.ac: Tidy target case. + (HAVE_LONG_DOUBLE): Allow the target to override. + * configure: Regenerate. + * include/ffi.h.in: Don't define ffi_type_foo if + LIBFFI_HIDE_BASIC_TYPES is defined. + (ffi_type_longdouble): If not HAVE_LONG_DOUBLE, define + to ffi_type_double. + * types.c (LIBFFI_HIDE_BASIC_TYPES): Define. + (FFI_TYPEDEF, ffi_type_void): Mark the data const. + (ffi_type_longdouble): Special case for Alpha. Don't define + if long double == double. + + * src/alpha/ffi.c (FFI_TYPE_LONGDOUBLE): Assert unique value. + (ffi_prep_cif_machdep): Handle it as the 128-bit type. + (ffi_call, ffi_closure_osf_inner): Likewise. + (ffi_closure_osf_inner): Likewise. Mark hidden. + (ffi_call_osf, ffi_closure_osf): Mark hidden. + * src/alpha/ffitarget.h (FFI_LAST_ABI): Tidy definition. + * src/alpha/osf.S (ffi_call_osf, ffi_closure_osf): Mark hidden. + (load_table): Handle 128-bit long double. + + * testsuite/libffi.call/float4.c: Add -mieee for alpha. + +2007-04-06 Tom Tromey + + PR libffi/31491: + * README: Fixed bug in example. + +2007-04-03 Jakub Jelinek + + * src/closures.c: Include sys/statfs.h. + (_GNU_SOURCE): Define on Linux. + (FFI_MMAP_EXEC_SELINUX): Define. + (selinux_enabled): New variable. + (selinux_enabled_check): New function. + (is_selinux_enabled): Define. + (dlmmap): Use it. + +2007-03-24 Uros Bizjak + + * testsuite/libffi.call/return_fl2.c (return_fl): Mark as static. + Use 'volatile float sum' to create sum of floats to avoid false + negative due to excess precision on ix86 targets. + (main): Ditto. + +2007-03-08 Alexandre Oliva + + * src/powerpc/ffi.c (flush_icache): Fix left-over from previous + patch. + (ffi_prep_closure_loc): Remove unneeded casts. Add needed ones. + +2007-03-07 Alexandre Oliva + + * include/ffi.h.in (ffi_closure_alloc, ffi_closure_free): New. + (ffi_prep_closure_loc): New. + (ffi_prep_raw_closure_loc): New. + (ffi_prep_java_raw_closure_loc): New. + * src/closures.c: New file. + * src/dlmalloc.c [FFI_MMAP_EXEC_WRIT] (struct malloc_segment): + Replace sflags with exec_offset. + [FFI_MMAP_EXEC_WRIT] (mmap_exec_offset, add_segment_exec_offset, + sub_segment_exec_offset): New macros. + (get_segment_flags, set_segment_flags, check_segment_merge): New + macros. + (is_mmapped_segment, is_extern_segment): Use get_segment_flags. + (add_segment, sys_alloc, create_mspace, create_mspace_with_base, + destroy_mspace): Use new macros. + (sys_alloc): Silence warning. + * Makefile.am (libffi_la_SOURCES): Add src/closures.c. + * Makefile.in: Rebuilt. + * src/prep_cif [FFI_CLOSURES] (ffi_prep_closure): Implement in + terms of ffi_prep_closure_loc. + * src/raw_api.c (ffi_prep_raw_closure_loc): Renamed and adjusted + from... + (ffi_prep_raw_closure): ... this. Re-implement in terms of the + renamed version. + * src/java_raw_api (ffi_prep_java_raw_closure_loc): Renamed and + adjusted from... + (ffi_prep_java_raw_closure): ... this. Re-implement in terms of + the renamed version. + * src/alpha/ffi.c (ffi_prep_closure_loc): Renamed from + (ffi_prep_closure): ... this. + * src/pa/ffi.c: Likewise. + * src/cris/ffi.c: Likewise. Adjust. + * src/frv/ffi.c: Likewise. + * src/ia64/ffi.c: Likewise. + * src/mips/ffi.c: Likewise. + * src/powerpc/ffi_darwin.c: Likewise. + * src/s390/ffi.c: Likewise. + * src/sh/ffi.c: Likewise. + * src/sh64/ffi.c: Likewise. + * src/sparc/ffi.c: Likewise. + * src/x86/ffi64.c: Likewise. + * src/x86/ffi.c: Likewise. + (FFI_INIT_TRAMPOLINE): Adjust. + (ffi_prep_raw_closure_loc): Renamed and adjusted from... + (ffi_prep_raw_closure): ... this. + * src/powerpc/ffi.c (ffi_prep_closure_loc): Renamed from + (ffi_prep_closure): ... this. + (flush_icache): Adjust. + +2007-03-07 Alexandre Oliva + + * src/dlmalloc.c: New file, imported version 2.8.3 of Doug + Lea's malloc. + +2007-03-01 Brooks Moses + + * Makefile.am: Add dummy install-pdf target. + * Makefile.in: Regenerate + +2007-02-13 Andreas Krebbel + + * src/s390/ffi.c (ffi_prep_args, ffi_prep_cif_machdep, + ffi_closure_helper_SYSV): Add long double handling. + +2007-02-02 Jakub Jelinek + + * src/powerpc/linux64.S (ffi_call_LINUX64): Move restore of r2 + immediately after bctrl instruction. + +2007-01-18 Alexandre Oliva + + * Makefile.am (all-recursive, install-recursive, + mostlyclean-recursive, clean-recursive, distclean-recursive, + maintainer-clean-recursive): Add missing targets. + * Makefile.in: Rebuilt. + +2006-12-14 Andreas Tobler + + * configure.ac: Add TARGET for x86_64-*-darwin*. + * Makefile.am (nodist_libffi_la_SOURCES): Add rules for 64-bit sources + for X86_DARWIN. + * src/x86/ffitarget.h: Set trampoline size for x86_64-*-darwin*. + * src/x86/darwin64.S: New file for x86_64-*-darwin* support. + * configure: Regenerate. + * Makefile.in: Regenerate. + * include/Makefile.in: Regenerate. + * testsuite/Makefile.in: Regenerate. + * testsuite/libffi.special/unwindtest_ffi_call.cc: New test case for + ffi_call only. + +2006-12-13 Andreas Tobler + + * aclocal.m4: Regenerate with aclocal -I .. as written in the + Makefile.am. + +2006-10-31 Geoffrey Keating + + * src/powerpc/ffi_darwin.c (darwin_adjust_aggregate_sizes): New. + (ffi_prep_cif_machdep): Call darwin_adjust_aggregate_sizes for + Darwin. + * testsuite/libffi.call/nested_struct4.c: Remove Darwin XFAIL. + * testsuite/libffi.call/nested_struct6.c: Remove Darwin XFAIL. + +2006-10-10 Paolo Bonzini + Sandro Tolaini + + * configure.ac [i*86-*-darwin*]: Set X86_DARWIN symbol and + conditional. + * configure: Regenerated. + * Makefile.am (nodist_libffi_la_SOURCES) [X86_DARWIN]: New case. + (EXTRA_DIST): Add src/x86/darwin.S. + * Makefile.in: Regenerated. + * include/Makefile.in: Regenerated. + * testsuite/Makefile.in: Regenerated. + + * src/x86/ffi.c (ffi_prep_cif_machdep) [X86_DARWIN]: Treat like + X86_WIN32, and additionally align stack to 16 bytes. + * src/x86/darwin.S: New, based on sysv.S. + * src/prep_cif.c (ffi_prep_cif) [X86_DARWIN]: Align > 8-byte structs. + +2006-09-12 David Daney + + PR libffi/23935 + * include/Makefile.am: Install both ffi.h and ffitarget.h in + $(libdir)/gcc/$(target_alias)/$(gcc_version)/include. + * aclocal.m4: Regenerated for automake 1.9.6. + * Makefile.in: Regenerated. + * include/Makefile.in: Regenerated. + * testsuite/Makefile.in: Regenerated. + +2006-08-17 Andreas Tobler + + * include/ffi_common.h (struct): Revert accidental commit. + +2006-08-15 Andreas Tobler + + * include/ffi_common.h: Remove lint directives. + * include/ffi.h.in: Likewise. + +2006-07-25 Torsten Schoenfeld + + * include/ffi.h.in (ffi_type_ulong, ffi_type_slong): Define correctly + for 32-bit architectures. + * testsuite/libffi.call/return_ul.c: New test case. + +2006-07-19 David Daney + + * testsuite/libffi.call/closure_fn6.c: Remove xfail for mips, + xfail remains for mips64. + +2006-05-23 Carlos O'Donell + + * Makefile.am: Add install-html target. Add install-html to .PHONY + * Makefile.in: Regenerate. + * aclocal.m4: Regenerate. + * include/Makefile.in: Regenerate. + * testsuite/Makefile.in: Regenerate. + +2006-05-18 John David Anglin + + * pa/ffi.c (ffi_prep_args_pa32): Load floating point arguments from + stack slot. + +2006-04-22 Andreas Tobler + + * README: Remove notice about 'Crazy Comments'. + * src/debug.c: Remove lint directives. Cleanup white spaces. + * src/java_raw_api.c: Likewise. + * src/prep_cif.c: Likewise. + * src/raw_api.c: Likewise. + * src/ffitest.c: Delete. No longer needed, all test cases migrated + to the testsuite. + * src/arm/ffi.c: Remove lint directives. + * src/m32r/ffi.c: Likewise. + * src/pa/ffi.c: Likewise. + * src/powerpc/ffi.c: Likewise. + * src/powerpc/ffi_darwin.c: Likewise. + * src/sh/ffi.c: Likewise. + * src/sh64/ffi.c: Likewise. + * src/x86/ffi.c: Likewise. + * testsuite/libffi.call/float2.c: Likewise. + * testsuite/libffi.call/promotion.c: Likewise. + * testsuite/libffi.call/struct1.c: Likewise. + +2006-04-13 Andreas Tobler + + * src/pa/hpux32.S: Correct unwind offset calculation for + ffi_closure_pa32. + * src/pa/linux.S: Likewise. + +2006-04-12 James E Wilson + + PR libgcj/26483 + * src/ia64/ffi.c (stf_spill, ldf_fill): Rewrite as macros. + (hfa_type_load): Call stf_spill. + (hfa_type_store): Call ldf_fill. + (ffi_call): Adjust calls to above routines. Add local temps for + macro result. + +2006-04-10 Matthias Klose + + * testsuite/lib/libffi-dg.exp (libffi-init): Recognize multilib + directory names containing underscores. + +2006-04-07 James E Wilson + + * testsuite/libffi.call/float4.c: New testcase. + +2006-04-05 John David Anglin + Andreas Tobler + + * Makefile.am: Add PA_HPUX port. + * Makefile.in: Regenerate. + * include/Makefile.in: Likewise. + * testsuite/Makefile.in: Likewise. + * configure.ac: Add PA_HPUX rules. + * configure: Regenerate. + * src/pa/ffitarget.h: Rename linux target to PA_LINUX. + Add PA_HPUX and PA64_HPUX. + Rename FFI_LINUX ABI to FFI_PA32 ABI. + (FFI_TRAMPOLINE_SIZE): Define for 32-bit HP-UX targets. + (FFI_TYPE_SMALL_STRUCT2): Define. + (FFI_TYPE_SMALL_STRUCT4): Likewise. + (FFI_TYPE_SMALL_STRUCT8): Likewise. + (FFI_TYPE_SMALL_STRUCT3): Redefine. + (FFI_TYPE_SMALL_STRUCT5): Likewise. + (FFI_TYPE_SMALL_STRUCT6): Likewise. + (FFI_TYPE_SMALL_STRUCT7): Likewise. + * src/pa/ffi.c (ROUND_DOWN): Delete. + (fldw, fstw, fldd, fstd): Use '__asm__'. + (ffi_struct_type): Add support for FFI_TYPE_SMALL_STRUCT2, + FFI_TYPE_SMALL_STRUCT4 and FFI_TYPE_SMALL_STRUCT8. + (ffi_prep_args_LINUX): Rename to ffi_prep_args_pa32. Update comment. + Simplify incrementing of stack slot variable. Change type of local + 'n' to unsigned int. + (ffi_size_stack_LINUX): Rename to ffi_size_stack_pa32. Handle long + double on PA_HPUX. + (ffi_prep_cif_machdep): Likewise. + (ffi_call): Likewise. + (ffi_closure_inner_LINUX): Rename to ffi_closure_inner_pa32. Change + return type to ffi_status. Simplify incrementing of stack slot + variable. Only copy floating point argument registers when PA_LINUX + is true. Reformat debug statement. + Add support for FFI_TYPE_SMALL_STRUCT2, FFI_TYPE_SMALL_STRUCT4 and + FFI_TYPE_SMALL_STRUCT8. + (ffi_closure_LINUX): Rename to ffi_closure_pa32. Add 'extern' to + declaration. + (ffi_prep_closure): Make linux trampoline conditional on PA_LINUX. + Add nops to cache flush. Add trampoline for PA_HPUX. + * src/pa/hpux32.S: New file. + * src/pa/linux.S (ffi_call_LINUX): Rename to ffi_call_pa32. Rename + ffi_prep_args_LINUX to ffi_prep_args_pa32. + Localize labels. Add support for 2, 4 and 8-byte small structs. Handle + unaligned destinations in 3, 5, 6 and 7-byte small structs. Order + argument type checks so that common argument types appear first. + (ffi_closure_LINUX): Rename to ffi_closure_pa32. Rename + ffi_closure_inner_LINUX to ffi_closure_inner_pa32. + +2006-03-24 Alan Modra + + * src/powerpc/ffitarget.h (enum ffi_abi): Add FFI_LINUX. Default + for 32-bit using IBM extended double format. Fix FFI_LAST_ABI. + * src/powerpc/ffi.c (ffi_prep_args_SYSV): Handle linux variant of + FFI_TYPE_LONGDOUBLE. + (ffi_prep_args64): Assert using IBM extended double. + (ffi_prep_cif_machdep): Don't munge FFI_TYPE_LONGDOUBLE type. + Handle FFI_LINUX FFI_TYPE_LONGDOUBLE return and args. + (ffi_call): Handle FFI_LINUX. + (ffi_closure_helper_SYSV): Non FFI_LINUX long double return needs + gpr3 return pointer as for struct return. Handle FFI_LINUX + FFI_TYPE_LONGDOUBLE return and args. Don't increment "nf" + unnecessarily. + * src/powerpc/ppc_closure.S (ffi_closure_SYSV): Load both f1 and f2 + for FFI_TYPE_LONGDOUBLE. Move epilogue insns into case table. + Don't use r6 as pointer to results, instead use sp offset. Don't + make a special call to load lr with case table address, instead + use offset from previous call. + * src/powerpc/sysv.S (ffi_call_SYSV): Save long double return. + * src/powerpc/linux64.S (ffi_call_LINUX64): Simplify long double + return. + +2006-03-15 Kaz Kojima + + * src/sh64/ffi.c (ffi_prep_cif_machdep): Handle float arguments + passed with FP registers correctly. + (ffi_closure_helper_SYSV): Likewise. + * src/sh64/sysv.S: Likewise. + +2006-03-01 Andreas Tobler + + * testsuite/libffi.special/unwindtest.cc (closure_test_fn): Mark cif, + args and userdata unused. + (closure_test_fn1): Mark cif and userdata unused. + (main): Remove unused res. + +2006-02-28 Andreas Tobler + + * testsuite/libffi.call/call.exp: Adjust FSF address. Add test runs for + -O2, -O3, -Os and the warning flags -W -Wall. + * testsuite/libffi.special/special.exp: Likewise. + * testsuite/libffi.call/ffitest.h: Add an __UNUSED__ macro to mark + unused parameter unused for gcc or else do nothing. + * testsuite/libffi.special/ffitestcxx.h: Likewise. + * testsuite/libffi.call/cls_12byte.c (cls_struct_12byte_gn): Mark cif + and userdata unused. + * testsuite/libffi.call/cls_16byte.c (cls_struct_16byte_gn): Likewise. + * testsuite/libffi.call/cls_18byte.c (cls_struct_18byte_gn): Likewise. + * testsuite/libffi.call/cls_19byte.c (cls_struct_19byte_gn): Likewise. + * testsuite/libffi.call/cls_1_1byte.c (cls_struct_1_1byte_gn): Likewise. + * testsuite/libffi.call/cls_20byte.c (cls_struct_20byte_gn): Likewise. + * testsuite/libffi.call/cls_20byte1.c (cls_struct_20byte_gn): Likewise. + * testsuite/libffi.call/cls_24byte.c (cls_struct_24byte_gn): Likewise. + * testsuite/libffi.call/cls_2byte.c (cls_struct_2byte_gn): Likewise. + * testsuite/libffi.call/cls_3_1byte.c (cls_struct_3_1byte_gn): Likewise. + * testsuite/libffi.call/cls_3byte1.c (cls_struct_3byte_gn): Likewise. + * testsuite/libffi.call/cls_3byte2.c (cls_struct_3byte_gn1): Likewise. + * testsuite/libffi.call/cls_4_1byte.c (cls_struct_4_1byte_gn): Likewise. + * testsuite/libffi.call/cls_4byte.c (cls_struct_4byte_gn): Likewise. + * testsuite/libffi.call/cls_5_1_byte.c (cls_struct_5byte_gn): Likewise. + * testsuite/libffi.call/cls_5byte.c (cls_struct_5byte_gn): Likewise. + * testsuite/libffi.call/cls_64byte.c (cls_struct_64byte_gn): Likewise. + * testsuite/libffi.call/cls_6_1_byte.c (cls_struct_6byte_gn): Likewise. + * testsuite/libffi.call/cls_6byte.c (cls_struct_6byte_gn): Likewise. + * testsuite/libffi.call/cls_7_1_byte.c (cls_struct_7byte_gn): Likewise. + * testsuite/libffi.call/cls_7byte.c (cls_struct_7byte_gn): Likewise. + * testsuite/libffi.call/cls_8byte.c (cls_struct_8byte_gn): Likewise. + * testsuite/libffi.call/cls_9byte1.c (cls_struct_9byte_gn): Likewise. + * testsuite/libffi.call/cls_9byte2.c (cls_struct_9byte_gn): Likewise. + * testsuite/libffi.call/cls_align_double.c (cls_struct_align_gn): + Likewise. + * testsuite/libffi.call/cls_align_float.c (cls_struct_align_gn): + Likewise. + * testsuite/libffi.call/cls_align_longdouble.c (cls_struct_align_gn): + Likewise. + * testsuite/libffi.call/cls_align_pointer.c (cls_struct_align_fn): Cast + void* to avoid compiler warning. + (main): Likewise. + (cls_struct_align_gn): Mark cif and userdata unused. + * testsuite/libffi.call/cls_align_sint16.c (cls_struct_align_gn): + Likewise. + * testsuite/libffi.call/cls_align_sint32.c (cls_struct_align_gn): + Likewise. + * testsuite/libffi.call/cls_align_sint64.c (cls_struct_align_gn): + Likewise. + * testsuite/libffi.call/cls_align_uint16.c (cls_struct_align_gn): + Likewise. + * testsuite/libffi.call/cls_align_uint32.c (cls_struct_align_gn): + Likewise. + * testsuite/libffi.call/cls_double.c (cls_ret_double_fn): Likewise. + * testsuite/libffi.call/cls_float.c (cls_ret_float_fn): Likewise. + * testsuite/libffi.call/cls_multi_schar.c (test_func_gn): Mark cif and + data unused. + (main): Cast res_call to silence gcc. + * testsuite/libffi.call/cls_multi_sshort.c (test_func_gn): Mark cif and + data unused. + (main): Cast res_call to silence gcc. + * testsuite/libffi.call/cls_multi_sshortchar.c (test_func_gn): Mark cif + and data unused. + (main): Cast res_call to silence gcc. + * testsuite/libffi.call/cls_multi_uchar.c (test_func_gn): Mark cif and + data unused. + (main): Cast res_call to silence gcc. + * testsuite/libffi.call/cls_multi_ushort.c (test_func_gn): Mark cif and + data unused. + (main): Cast res_call to silence gcc. + * testsuite/libffi.call/cls_multi_ushortchar.c (test_func_gn): Mark cif + and data unused. + (main): Cast res_call to silence gcc. + * testsuite/libffi.call/cls_schar.c (cls_ret_schar_fn): Mark cif and + userdata unused. + (cls_ret_schar_fn): Cast printf parameter to silence gcc. + * testsuite/libffi.call/cls_sint.c (cls_ret_sint_fn): Mark cif and + userdata unused. + (cls_ret_sint_fn): Cast printf parameter to silence gcc. + * testsuite/libffi.call/cls_sshort.c (cls_ret_sshort_fn): Mark cif and + userdata unused. + (cls_ret_sshort_fn): Cast printf parameter to silence gcc. + * testsuite/libffi.call/cls_uchar.c (cls_ret_uchar_fn): Mark cif and + userdata unused. + (cls_ret_uchar_fn): Cast printf parameter to silence gcc. + * testsuite/libffi.call/cls_uint.c (cls_ret_uint_fn): Mark cif and + userdata unused. + (cls_ret_uint_fn): Cast printf parameter to silence gcc. + * testsuite/libffi.call/cls_ulonglong.c (cls_ret_ulonglong_fn): Mark cif + and userdata unused. + * testsuite/libffi.call/cls_ushort.c (cls_ret_ushort_fn): Mark cif and + userdata unused. + (cls_ret_ushort_fn): Cast printf parameter to silence gcc. + * testsuite/libffi.call/float.c (floating): Remove unused parameter e. + * testsuite/libffi.call/float1.c (main): Remove unused variable i. + Cleanup white spaces. + * testsuite/libffi.call/negint.c (checking): Remove unused variable i. + * testsuite/libffi.call/nested_struct.c (cls_struct_combined_gn): Mark + cif and userdata unused. + * testsuite/libffi.call/nested_struct1.c (cls_struct_combined_gn): + Likewise. + * testsuite/libffi.call/nested_struct10.c (B_gn): Likewise. + * testsuite/libffi.call/nested_struct2.c (B_fn): Adjust printf + formatters to silence gcc. + (B_gn): Mark cif and userdata unused. + * testsuite/libffi.call/nested_struct3.c (B_gn): Mark cif and userdata + unused. + * testsuite/libffi.call/nested_struct4.c: Mention related PR. + (B_gn): Mark cif and userdata unused. + * testsuite/libffi.call/nested_struct5.c (B_gn): Mark cif and userdata + unused. + * testsuite/libffi.call/nested_struct6.c: Mention related PR. + (B_gn): Mark cif and userdata unused. + * testsuite/libffi.call/nested_struct7.c (B_gn): Mark cif and userdata + unused. + * testsuite/libffi.call/nested_struct8.c (B_gn): Likewise. + * testsuite/libffi.call/nested_struct9.c (B_gn): Likewise. + * testsuite/libffi.call/problem1.c (stub): Likewise. + * testsuite/libffi.call/pyobjc-tc.c (main): Cast the result to silence + gcc. + * testsuite/libffi.call/return_fl2.c (return_fl): Add the note mentioned + in the last commit for this test case in the test case itself. + * testsuite/libffi.call/closure_fn0.c (closure_test_fn0): Mark cif as + unused. + * testsuite/libffi.call/closure_fn1.c (closure_test_fn1): Likewise. + * testsuite/libffi.call/closure_fn2.c (closure_test_fn2): Likewise. + * testsuite/libffi.call/closure_fn3.c (closure_test_fn3): Likewise. + * testsuite/libffi.call/closure_fn4.c (closure_test_fn0): Likewise. + * testsuite/libffi.call/closure_fn5.c (closure_test_fn5): Likewise. + * testsuite/libffi.call/closure_fn6.c (closure_test_fn0): Likewise. + +2006-02-22 Kaz Kojima + + * src/sh/sysv.S: Fix register numbers in the FDE for + ffi_closure_SYSV. + +2006-02-20 Andreas Tobler + + * testsuite/libffi.call/return_fl2.c (return_fl): Remove static + declaration to avoid a false negative on ix86. See PR323. + +2006-02-18 Kaz Kojima + + * src/sh/ffi.c (ffi_closure_helper_SYSV): Remove unused variable + and cast integer to void * if needed. Update the pointer to + the FP register saved area correctly. + +2006-02-17 Andreas Tobler + + * testsuite/libffi.call/nested_struct6.c: XFAIL this test until PR25630 + is fixed. + * testsuite/libffi.call/nested_struct4.c: Likewise. + +2006-02-16 Andreas Tobler + + * testsuite/libffi.call/return_dbl.c: New test case. + * testsuite/libffi.call/return_dbl1.c: Likewise. + * testsuite/libffi.call/return_dbl2.c: Likewise. + * testsuite/libffi.call/return_fl.c: Likewise. + * testsuite/libffi.call/return_fl1.c: Likewise. + * testsuite/libffi.call/return_fl2.c: Likewise. + * testsuite/libffi.call/return_fl3.c: Likewise. + * testsuite/libffi.call/closure_fn6.c: Likewise. + + * testsuite/libffi.call/nested_struct2.c: Remove ffi_type_mylong + definition. + * testsuite/libffi.call/ffitest.h: Add ffi_type_mylong definition + here to be used by other test cases too. + + * testsuite/libffi.call/nested_struct10.c: New test case. + * testsuite/libffi.call/nested_struct9.c: Likewise. + * testsuite/libffi.call/nested_struct8.c: Likewise. + * testsuite/libffi.call/nested_struct7.c: Likewise. + * testsuite/libffi.call/nested_struct6.c: Likewise. + * testsuite/libffi.call/nested_struct5.c: Likewise. + * testsuite/libffi.call/nested_struct4.c: Likewise. + +2006-01-21 Andreas Tobler + + * configure.ac: Enable libffi for sparc64-*-freebsd*. + * configure: Rebuilt. + +2006-01-18 Jakub Jelinek + + * src/powerpc/sysv.S (smst_two_register): Don't call __ashldi3, + instead do the shifting inline. + * src/powerpc/ppc_closure.S (ffi_closure_SYSV): Don't compute %r5 + shift count unconditionally. Simplify load sequences for 1, 2, 3, 4 + and 8 byte structs, for the remaining struct sizes don't call + __lshrdi3, instead do the shifting inline. + +2005-12-07 Thiemo Seufer + + * src/mips/ffitarget.h: Remove obsolete sgidefs.h include. Add + missing parentheses. + * src/mips/o32.S (ffi_call_O32): Code formatting. Define + and use A3_OFF, FP_OFF, RA_OFF. Micro-optimizations. + (ffi_closure_O32): Likewise, but with newly defined A3_OFF2, + A2_OFF2, A1_OFF2, A0_OFF2, RA_OFF2, FP_OFF2, S0_OFF2, GP_OFF2, + V1_OFF2, V0_OFF2, FA_1_1_OFF2, FA_1_0_OFF2, FA_0_1_OFF2, + FA_0_0_OFF2. + * src/mips/ffi.c (ffi_prep_args): Code formatting. Fix + endianness bugs. + (ffi_prep_closure): Improve trampoline instruction scheduling. + (ffi_closure_mips_inner_O32): Fix endianness bugs. + +2005-12-03 Alan Modra + + * src/powerpc/ffi.c: Formatting. + (ffi_prep_args_SYSV): Avoid possible aliasing problems by using unions. + (ffi_prep_args64): Likewise. + +2005-09-30 Geoffrey Keating + + * testsuite/lib/libffi-dg.exp (libffi_target_compile): For + darwin, use -shared-libgcc not -lgcc_s, and explain why. + +2005-09-26 Tom Tromey + + * testsuite/libffi.call/float1.c (value_type): New typedef. + (CANARY): New define. + (main): Check for result buffer overflow. + * src/powerpc/linux64.S: Handle linux64 long double returns. + * src/powerpc/ffi.c (FLAG_RETURNS_128BITS): New constant. + (ffi_prep_cif_machdep): Handle linux64 long double returns. + +2005-08-25 Alan Modra + + PR target/23404 + * src/powerpc/ffi.c (ffi_prep_args_SYSV): Correct placement of stack + homed fp args. + (ffi_status ffi_prep_cif_machdep): Correct stack sizing for same. + +2005-08-11 Jakub Jelinek + + * configure.ac (HAVE_HIDDEN_VISIBILITY_ATTRIBUTE): New test. + (AH_BOTTOM): Add FFI_HIDDEN definition. + * configure: Rebuilt. + * fficonfig.h.in: Rebuilt. + * src/powerpc/ffi.c (hidden): Remove. + (ffi_closure_LINUX64, ffi_prep_args64, ffi_call_LINUX64, + ffi_closure_helper_LINUX64): Use FFI_HIDDEN instead of hidden. + * src/powerpc/linux64_closure.S (ffi_closure_LINUX64, + .ffi_closure_LINUX64): Use FFI_HIDDEN instead of .hidden. + * src/x86/ffi.c (ffi_closure_SYSV, ffi_closure_raw_SYSV): Remove, + add FFI_HIDDEN to its prototype. + (ffi_closure_SYSV_inner): New. + * src/x86/sysv.S (ffi_closure_SYSV, ffi_closure_raw_SYSV): New. + * src/x86/win32.S (ffi_closure_SYSV, ffi_closure_raw_SYSV): New. + +2005-08-10 Alfred M. Szmidt + + PR libffi/21819: + * configure: Rebuilt. + * configure.ac: Handle i*86-*-gnu*. + +2005-08-09 Jakub Jelinek + + * src/powerpc/ppc_closure.S (ffi_closure_SYSV): Use + DW_CFA_offset_extended_sf rather than + DW_CFA_GNU_negative_offset_extended. + * src/powerpc/sysv.S (ffi_call_SYSV): Likewise. + +2005-07-22 SUGIOKA Toshinobu + + * src/sh/sysv.S (ffi_call_SYSV): Stop argument popping correctly + on sh3. + (ffi_closure_SYSV): Change the stack layout for sh3 struct argument. + * src/sh/ffi.c (ffi_prep_args): Fix sh3 argument copy, when it is + partially on register. + (ffi_closure_helper_SYSV): Likewise. + (ffi_prep_cif_machdep): Don't set too many cif->flags. + +2005-07-20 Kaz Kojima + + * src/sh/ffi.c (ffi_call): Handle small structures correctly. + Remove empty line. + * src/sh64/ffi.c (simple_type): Remove. + (return_type): Handle small structures correctly. + (ffi_prep_args): Likewise. + (ffi_call): Likewise. + (ffi_closure_helper_SYSV): Likewise. + * src/sh64/sysv.S (ffi_call_SYSV): Handle 1, 2 and 4-byte return. + Emit position independent code if PIC and remove wrong datalabel + prefixes from EH data. + +2005-07-19 Andreas Tobler + + * Makefile.am (nodist_libffi_la_SOURCES): Add POWERPC_FREEBSD. + * Makefile.in: Regenerate. + * include/Makefile.in: Likewise. + * testsuite/Makefile.in: Likewise. + * configure.ac: Add POWERPC_FREEBSD rules. + * configure: Regenerate. + * src/powerpc/ffitarget.h: Add POWERPC_FREEBSD rules. + (FFI_SYSV_TYPE_SMALL_STRUCT): Define. + * src/powerpc/ffi.c: Add flags to handle small structure returns + in ffi_call_SYSV. + (ffi_prep_cif_machdep): Handle small structures for SYSV 4 ABI. + Aka FFI_SYSV. + (ffi_closure_helper_SYSV): Likewise. + * src/powerpc/ppc_closure.S: Add return types for small structures. + * src/powerpc/sysv.S: Add bits to handle small structures for + final SYSV 4 ABI. + +2005-07-10 Andreas Tobler + + * testsuite/libffi.call/cls_5_1_byte.c: New test file. + * testsuite/libffi.call/cls_6_1_byte.c: Likewise. + * testsuite/libffi.call/cls_7_1_byte.c: Likewise. + +2005-07-05 Randolph Chung + + * src/pa/ffi.c (ffi_struct_type): Rename FFI_TYPE_SMALL_STRUCT1 + as FFI_TYPE_SMALL_STRUCT3. Break out handling for 5-7 byte + structures. Kill compilation warnings. + (ffi_closure_inner_LINUX): Print return values as hex in debug + message. Rename FFI_TYPE_SMALL_STRUCT1 as FFI_TYPE_SMALL_STRUCT3. + Properly handle 5-7 byte structure returns. + * src/pa/ffitarget.h (FFI_TYPE_SMALL_STRUCT1) + (FFI_TYPE_SMALL_STRUCT2): Remove. + (FFI_TYPE_SMALL_STRUCT3, FFI_TYPE_SMALL_STRUCT5) + (FFI_TYPE_SMALL_STRUCT6, FFI_TYPE_SMALL_STRUCT7): Define. + * src/pa/linux.S: Mark source file as using PA1.1 assembly. + (checksmst1, checksmst2): Remove. + (checksmst3): Optimize handling of 3-byte struct returns. + (checksmst567): Properly handle 5-7 byte struct returns. + +2005-06-15 Rainer Orth + + PR libgcj/21943 + * src/mips/n32.S: Enforce PIC code. + * src/mips/o32.S: Likewise. + +2005-06-15 Rainer Orth + + * configure.ac: Treat i*86-*-solaris2.10 and up as X86_64. + * configure: Regenerate. + +2005-06-01 Alan Modra + + * src/powerpc/ppc_closure.S (ffi_closure_SYSV): Don't use JUMPTARGET + to call ffi_closure_helper_SYSV. Append @local instead. + * src/powerpc/sysv.S (ffi_call_SYSV): Likewise for ffi_prep_args_SYSV. + +2005-05-17 Kelley Cook + + * configure.ac: Use AC_C_BIGENDIAN instead of AC_C_BIGENDIAN_CROSS. + Use AC_CHECK_SIZEOF instead of AC_COMPILE_CHECK_SIZEOF. + * Makefile.am (ACLOCAL_AMFLAGS): Remove -I ../config. + * aclocal.m4, configure, fficonfig.h.in, Makefile.in, + include/Makefile.in, testsuite/Makefile.in: Regenerate. + +2005-05-09 Mike Stump + + * configure: Regenerate. + +2005-05-08 Richard Henderson + + PR libffi/21285 + * src/alpha/osf.S: Update unwind into to match code. + +2005-05-04 Andreas Degert + Richard Henderson + + * src/x86/ffi64.c (ffi_prep_cif_machdep): Save sse-used flag in + bit 11 of flags. + (ffi_call): Mask return type field. Pass ssecount to ffi_call_unix64. + (ffi_prep_closure): Set carry bit if sse-used flag set. + * src/x86/unix64.S (ffi_call_unix64): Add ssecount argument. + Only load sse registers if ssecount non-zero. + (ffi_closure_unix64): Only save sse registers if carry set on entry. + +2005-04-29 Ralf Corsepius + + * configure.ac: Add i*86-*-rtems*, sparc*-*-rtems*, + powerpc-*rtems*, arm*-*-rtems*, sh-*-rtems*. + * configure: Regenerate. + +2005-04-20 Hans-Peter Nilsson + + * testsuite/lib/libffi-dg.exp (libffi-dg-test-1): In regsub use, + have Tcl8.3-compatible intermediate variable. + +2005-04-18 Simon Posnjak + Hans-Peter Nilsson + + * Makefile.am: Add CRIS support. + * configure.ac: Likewise. + * Makefile.in, configure, testsuite/Makefile.in, + include/Makefile.in: Regenerate. + * src/cris: New directory. + * src/cris/ffi.c, src/cris/sysv.S, src/cris/ffitarget.h: New files. + * src/prep_cif.c (ffi_prep_cif): Wrap in #ifndef __CRIS__. + + * testsuite/lib/libffi-dg.exp (libffi-dg-test-1): Replace \n with + \r?\n in output tests. + +2005-04-12 Mike Stump + + * configure: Regenerate. + +2005-03-30 Hans Boehm + + * src/ia64/ffitarget.h (ffi_arg): Use long long instead of DI. + +2005-03-30 Steve Ellcey + + * src/ia64/ffitarget.h (ffi_arg) ADD DI attribute. + (ffi_sarg) Ditto. + * src/ia64/unix.S (ffi_closure_unix): Extend gp + to 64 bits in ILP32 mode. + Load 64 bits even for short data. + +2005-03-23 Mike Stump + + * src/powerpc/darwin.S: Update for -m64 multilib. + * src/powerpc/darwin_closure.S: Likewise. + +2005-03-21 Zack Weinberg + + * configure.ac: Do not invoke TL_AC_GCC_VERSION. + Do not set tool_include_dir. + * aclocal.m4, configure, Makefile.in, testsuite/Makefile.in: + Regenerate. + * include/Makefile.am: Set gcc_version and toollibffidir. + * include/Makefile.in: Regenerate. + +2005-02-22 Andrew Haley + + * src/powerpc/ffi.c (ffi_prep_cif_machdep): Bump alignment to + odd-numbered register pairs for 64-bit integer types. + +2005-02-23 Andreas Tobler + + PR libffi/20104 + * testsuite/libffi.call/return_ll1.c: New test case. + +2005-02-11 Janis Johnson + + * testsuite/libffi.call/cls_align_longdouble.c: Remove dg-options. + * testsuite/libffi.call/float.c: Ditto. + * testsuite/libffi.call/float2.c: Ditto. + * testsuite/libffi.call/float3.c: Ditto. + +2005-02-08 Andreas Tobler + + * src/frv/ffitarget.h: Remove PPC stuff which does not belong to frv. + +2005-01-12 Eric Botcazou + + * testsuite/libffi.special/special.exp (cxx_options): Add + -shared-libgcc. + +2004-12-31 Richard Henderson + + * src/types.c (FFI_AGGREGATE_TYPEDEF): Remove. + (FFI_TYPEDEF): Rename from FFI_INTEGRAL_TYPEDEF. Replace size and + offset parameters with a type parameter; deduce size and structure + alignment. Update all users. + +2004-12-31 Richard Henderson + + * src/types.c (FFI_TYPE_POINTER): Define with sizeof. + (FFI_TYPE_LONGDOUBLE): Fix for ia64. + * src/ia64/ffitarget.h (struct ffi_ia64_trampoline_struct): Move + into ffi_prep_closure. + * src/ia64/ia64_flags.h, src/ia64/ffi.c, src/ia64/unix.S: Rewrite + from scratch. + +2004-12-27 Richard Henderson + + * src/x86/unix64.S: Fix typo in unwind info. + +2004-12-25 Richard Henderson + + * src/x86/ffi64.c (struct register_args): Rename from stackLayout. + (enum x86_64_reg_class): Add X86_64_COMPLEX_X87_CLASS. + (merge_classes): Check for it. + (SSE_CLASS_P): New. + (classify_argument): Pass byte_offset by value; perform all updates + inside struct case. + (examine_argument): Add classes argument; handle + X86_64_COMPLEX_X87_CLASS. + (ffi_prep_args): Merge into ... + (ffi_call): ... here. Share stack frame with ffi_call_unix64. + (ffi_prep_cif_machdep): Setup cif->flags for proper structure return. + (ffi_fill_return_value): Remove. + (ffi_prep_closure): Remove dead assert. + (ffi_closure_unix64_inner): Rename from ffi_closure_UNIX64_inner. + Rewrite to use struct register_args instead of va_list. Create + flags for handling structure returns. + * src/x86/unix64.S: Remove dead strings. + (ffi_call_unix64): Rename from ffi_call_UNIX64. Rewrite to share + stack frame with ffi_call. Handle structure returns properly. + (float2sse, floatfloat2sse, double2sse): Remove. + (sse2float, sse2double, sse2floatfloat): Remove. + (ffi_closure_unix64): Rename from ffi_closure_UNIX64. Rewrite + to handle structure returns properly. + +2004-12-08 David Edelsohn + + * Makefile.am (AM_MAKEFLAGS): Remove duplicate LIBCFLAGS and + PICFLAG. + * Makefile.in: Regenerated. + +2004-12-02 Richard Sandiford + + * configure.ac: Use TL_AC_GCC_VERSION to set gcc_version. + * configure, aclocal.m4, Makefile.in: Regenerate. + * include/Makefile.in, testsuite/Makefile.in: Regenerate. + +2004-11-29 Kelley Cook + + * configure: Regenerate for libtool change. + +2004-11-25 Kelley Cook + + * configure: Regenerate for libtool reversion. + +2004-11-24 Kelley Cook + + * configure: Regenerate for libtool change. + +2004-11-23 John David Anglin + + * testsuite/lib/libffi-dg.exp: Use new procs in target-libpath.exp. + +2004-11-23 Richard Sandiford + + * src/mips/o32.S (ffi_call_O32, ffi_closure_O32): Use jalr instead + of jal. Use an absolute encoding for the frame information. + +2004-11-23 Kelley Cook + + * Makefile.am: Remove no-dependencies. Add ACLOCAL_AMFLAGS. + * acinclude.m4: Delete logic for sincludes. + * aclocal.m4, Makefile.in, configure: Regenerate. + * include/Makefile: Likewise. + * testsuite/Makefile: Likewise. + +2004-11-22 Eric Botcazou + + * src/sparc/ffi.c (ffi_prep_closure): Align doubles and 64-bit integers + on a 8-byte boundary. + * src/sparc/v8.S (ffi_closure_v8): Reserve frame space for arguments. + +2004-10-27 Richard Earnshaw + + * src/arm/ffi.c (ffi_prep_cif_machdep): Handle functions that return + long long values. Round stack allocation to a multiple of 8 bytes + for ATPCS compatibility. + * src/arm/sysv.S (ffi_call_SYSV): Rework to avoid use of APCS register + names. Handle returning long long types. Add Thumb and interworking + support. Improve soft-float code. + +2004-10-27 Richard Earnshaw + + * testsuite/lib/libffi-db.exp (load_gcc_lib): New function. + (libffi_exit): New function. + (libffi_init): Build the testglue wrapper if needed. + +2004-10-25 Eric Botcazou + + PR other/18138 + * testsuite/lib/libffi-dg.exp: Accept more than one multilib libgcc. + +2004-10-25 Kazuhiro Inaoka + + * src/m32r/libffitarget.h (FFI_CLOSURES): Set to 0. + +2004-10-20 Kaz Kojima + + * src/sh/sysv.S (ffi_call_SYSV): Don't align for double data. + * testsuite/libffi.call/float3.c: New test case. + +2004-10-18 Kaz Kojima + + * src/sh/ffi.c (ffi_prep_closure): Set T bit in trampoline for + the function returning a structure pointed with R2. + * src/sh/sysv.S (ffi_closure_SYSV): Use R2 as the pointer to + the structure return value if T bit set. Emit position + independent code and EH data if PIC. + +2004-10-13 Kazuhiro Inaoka + + * Makefile.am: Add m32r support. + * configure.ac: Likewise. + * Makefile.in: Regenerate. + * confiugre: Regenerate. + * src/types.c: Add m32r port to FFI_INTERNAL_TYPEDEF + (uint64, sint64, double, longdouble) + * src/m32r: New directory. + * src/m32r/ffi.c: New file. + * src/m32r/sysv.S: Likewise. + * src/m32r/ffitarget.h: Likewise. + +2004-10-02 Kaz Kojima + + * testsuite/libffi.call/negint.c: New test case. + +2004-09-14 H.J. Lu + + PR libgcj/17465 + * testsuite/lib/libffi-dg.exp: Don't use global ld_library_path. + Set up LD_LIBRARY_PATH, SHLIB_PATH, LD_LIBRARYN32_PATH, + LD_LIBRARY64_PATH, LD_LIBRARY_PATH_32, LD_LIBRARY_PATH_64 and + DYLD_LIBRARY_PATH. + +2004-09-05 Andreas Tobler + + * testsuite/libffi.call/many_win32.c: Remove whitespaces. + * testsuite/libffi.call/promotion.c: Likewise. + * testsuite/libffi.call/return_ll.c: Remove unused var. Cleanup + whitespaces. + * testsuite/libffi.call/return_sc.c: Likewise. + * testsuite/libffi.call/return_uc.c: Likewise. + +2004-09-05 Andreas Tobler + + * src/powerpc/darwin.S: Fix comments and identation. + * src/powerpc/darwin_closure.S: Likewise. + +2004-09-02 Andreas Tobler + + * src/powerpc/ffi_darwin.c: Add flag for longdouble return values. + (ffi_prep_args): Handle longdouble arguments. + (ffi_prep_cif_machdep): Set flags for longdouble. Calculate space for + longdouble. + (ffi_closure_helper_DARWIN): Add closure handling for longdouble. + * src/powerpc/darwin.S (_ffi_call_DARWIN): Add handling of longdouble + values. + * src/powerpc/darwin_closure.S (_ffi_closure_ASM): Likewise. + * src/types.c: Defined longdouble size and alignment for darwin. + +2004-09-02 Andreas Tobler + + * src/powerpc/aix.S: Remove whitespaces. + * src/powerpc/aix_closure.S: Likewise. + * src/powerpc/asm.h: Likewise. + * src/powerpc/ffi.c: Likewise. + * src/powerpc/ffitarget.h: Likewise. + * src/powerpc/linux64.S: Likewise. + * src/powerpc/linux64_closure.S: Likewise. + * src/powerpc/ppc_closure.S: Likewise. + * src/powerpc/sysv.S: Likewise. + +2004-08-30 Anthony Green + + * Makefile.am: Add frv support. + * Makefile.in, testsuite/Makefile.in: Rebuilt. + * configure.ac: Read configure.host. + * configure.in: Read configure.host. + * configure.host: New file. frv-elf needs libgloss. + * include/ffi.h.in: Force ffi_closure to have a nice big (8) + alignment. This is needed to frv and shouldn't harm the others. + * include/ffi_common.h (ALIGN_DOWN): New macro. + * src/frv/ffi.c, src/frv/ffitarget.h, src/frv/eabi.S: New files. + +2004-08-24 David Daney + + * testsuite/libffi.call/closure_fn0.c: Xfail mips64* instead of mips*. + * testsuite/libffi.call/closure_fn1.c: Likewise. + * testsuite/libffi.call/closure_fn2.c Likewise. + * testsuite/libffi.call/closure_fn3.c: Likewise. + * testsuite/libffi.call/closure_fn4.c: Likewise. + * testsuite/libffi.call/closure_fn5.c: Likewise. + * testsuite/libffi.call/cls_18byte.c: Likewise. + * testsuite/libffi.call/cls_19byte.c: Likewise. + * testsuite/libffi.call/cls_1_1byte.c: Likewise. + * testsuite/libffi.call/cls_20byte.c: Likewise. + * testsuite/libffi.call/cls_20byte1.c: Likewise. + * testsuite/libffi.call/cls_24byte.c: Likewise. + * testsuite/libffi.call/cls_2byte.c: Likewise. + * testsuite/libffi.call/cls_3_1byte.c: Likewise. + * testsuite/libffi.call/cls_3byte1.c: Likewise. + * testsuite/libffi.call/cls_3byte2.c: Likewise. + * testsuite/libffi.call/cls_4_1byte.c: Likewise. + * testsuite/libffi.call/cls_4byte.c: Likewise. + * testsuite/libffi.call/cls_64byte.c: Likewise. + * testsuite/libffi.call/cls_6byte.c: Likewise. + * testsuite/libffi.call/cls_7byte.c: Likewise. + * testsuite/libffi.call/cls_8byte.c: Likewise. + * testsuite/libffi.call/cls_9byte1.c: Likewise. + * testsuite/libffi.call/cls_9byte2.c: Likewise. + * testsuite/libffi.call/cls_align_double.c: Likewise. + * testsuite/libffi.call/cls_align_float.c: Likewise. + * testsuite/libffi.call/cls_align_longdouble.c: Likewise. + * testsuite/libffi.call/cls_align_pointer.c: Likewise. + * testsuite/libffi.call/cls_align_sint16.c: Likewise. + * testsuite/libffi.call/cls_align_sint32.c: Likewise. + * testsuite/libffi.call/cls_align_sint64.c: Likewise. + * testsuite/libffi.call/cls_align_uint16.c: Likewise. + * testsuite/libffi.call/cls_align_uint32.c: Likewise. + * testsuite/libffi.call/cls_align_uint64.c: Likewise. + * testsuite/libffi.call/cls_double.c: Likewise. + * testsuite/libffi.call/cls_float.c: Likewise. + * testsuite/libffi.call/cls_multi_schar.c: Likewise. + * testsuite/libffi.call/cls_multi_sshort.c: Likewise. + * testsuite/libffi.call/cls_multi_sshortchar.c: Likewise. + * testsuite/libffi.call/cls_multi_uchar.c: Likewise. + * testsuite/libffi.call/cls_multi_ushort.c: Likewise. + * testsuite/libffi.call/cls_multi_ushortchar.c: Likewise. + * testsuite/libffi.call/cls_schar.c: Likewise. + * testsuite/libffi.call/cls_sint.c: Likewise. + * testsuite/libffi.call/cls_sshort.c: Likewise. + * testsuite/libffi.call/cls_uchar.c: Likewise. + * testsuite/libffi.call/cls_uint.c: Likewise. + * testsuite/libffi.call/cls_ulonglong.c: Likewise. + * testsuite/libffi.call/cls_ushort.c: Likewise. + * testsuite/libffi.call/nested_struct.c: Likewise. + * testsuite/libffi.call/nested_struct1.c: Likewise. + * testsuite/libffi.call/nested_struct2.c: Likewise. + * testsuite/libffi.call/nested_struct3.c: Likewise. + * testsuite/libffi.call/problem1.c: Likewise. + * testsuite/libffi.special/unwindtest.cc: Likewise. + * testsuite/libffi.call/cls_12byte.c: Likewise and set return value + to zero. + * testsuite/libffi.call/cls_16byte.c: Likewise. + * testsuite/libffi.call/cls_5byte.c: Likewise. + +2004-08-23 David Daney + + PR libgcj/13141 + * src/mips/ffitarget.h (FFI_O32_SOFT_FLOAT): New ABI. + * src/mips/ffi.c (ffi_prep_args): Fix alignment calculation. + (ffi_prep_cif_machdep): Handle FFI_O32_SOFT_FLOAT floating point + parameters and return types. + (ffi_call): Handle FFI_O32_SOFT_FLOAT ABI. + (ffi_prep_closure): Ditto. + (ffi_closure_mips_inner_O32): Handle FFI_O32_SOFT_FLOAT ABI, fix + alignment calculations. + * src/mips/o32.S (ffi_closure_O32): Don't use floating point + instructions if FFI_O32_SOFT_FLOAT, make stack frame ABI compliant. + +2004-08-14 Casey Marshall + + * src/mips/ffi.c (ffi_pref_cif_machdep): set `cif->flags' to + contain `FFI_TYPE_UINT64' as return type for any 64-bit + integer (O32 ABI only). + (ffi_prep_closure): new function. + (ffi_closure_mips_inner_O32): new function. + * src/mips/ffitarget.h: Define `FFI_CLOSURES' and + `FFI_TRAMPOLINE_SIZE' appropriately if the ABI is o32. + * src/mips/o32.S (ffi_call_O32): add labels for .eh_frame. Return + 64 bit integers correctly. + (ffi_closure_O32): new function. + Added DWARF-2 unwind info for both functions. + +2004-08-10 Andrew Haley + + * src/x86/ffi64.c (ffi_prep_args ): 8-align all stack arguments. + +2004-08-01 Robert Millan + + * configure.ac: Detect knetbsd-gnu and kfreebsd-gnu. + * configure: Regenerate. + +2004-07-30 Maciej W. Rozycki + + * acinclude.m4 (AC_FUNC_MMAP_BLACKLIST): Check for + and mmap() explicitly instead of relying on preset autoconf cache + variables. + * aclocal.m4: Regenerate. + * configure: Regenerate. + +2004-07-11 Ulrich Weigand + + * src/s390/ffi.c (ffi_prep_args): Fix C aliasing violation. + (ffi_check_float_struct): Remove unused prototype. + +2004-06-30 Geoffrey Keating + + * src/powerpc/ffi_darwin.c (flush_icache): ';' is a comment + character on Darwin, use '\n\t' instead. + +2004-06-26 Matthias Klose + + * libtool-version: Fix typo in revision/age. + +2004-06-17 Matthias Klose + + * libtool-version: New. + * Makefile.am (libffi_la_LDFLAGS): Use -version-info for soname. + * Makefile.in: Regenerate. + +2004-06-15 Paolo Bonzini + + * Makefile.am: Remove useless multilib rules. + * Makefile.in: Regenerate. + * aclocal.m4: Regenerate with automake 1.8.5. + * configure.ac: Remove useless multilib configury. + * configure: Regenerate. + +2004-06-15 Paolo Bonzini + + * .cvsignore: New file. + +2004-06-10 Jakub Jelinek + + * src/ia64/unix.S (ffi_call_unix): Insert group barrier break + fp_done. + (ffi_closure_UNIX): Fix f14/f15 adjustment if FLOAT_SZ is ever + changed from 8. + +2004-06-06 Sean McNeil + + * configure.ac: Add x86_64-*-freebsd* support. + * configure: Regenerate. + +2004-04-26 Joe Buck + + Bug 15093 + * configure.ac: Test for existence of mmap and sys/mman.h before + checking blacklist. Fix suggested by Jim Wilson. + * configure: Regenerate. + +2004-04-26 Matt Austern + + * src/powerpc/darwin.S: Go through a non-lazy pointer for initial + FDE location. + * src/powerpc/darwin_closure.S: Likewise. + +2004-04-24 Andreas Tobler + + * testsuite/libffi.call/cls_multi_schar.c (main): Fix initialization + error. Reported by Thomas Heller . + * testsuite/libffi.call/cls_multi_sshort.c (main): Likewise. + * testsuite/libffi.call/cls_multi_ushort.c (main): Likewise. + +2004-03-20 Matthias Klose + + * src/pa/linux.S: Fix typo. + +2004-03-19 Matthias Klose + + * Makefile.am: Update. + * Makefile.in: Regenerate. + * src/pa/ffi.h.in: Remove. + * src/pa/ffitarget.h: New file. + +2004-02-10 Randolph Chung + + * Makefile.am: Add PA support. + * Makefile.in: Regenerate. + * include/Makefile.in: Regenerate. + * configure.ac: Add PA target. + * configure: Regenerate. + * src/pa/ffi.c: New file. + * src/pa/ffi.h.in: Add PA support. + * src/pa/linux.S: New file. + * prep_cif.c: Add PA support. + +2004-03-16 Hosaka Yuji + + * src/types.c: Fix alignment size of X86_WIN32 case int64 and + double. + * src/x86/ffi.c (ffi_prep_args): Replace ecif->cif->rtype->type + with ecif->cif->flags. + (ffi_call, ffi_prep_incoming_args_SYSV): Replace cif->rtype->type + with cif->flags. + (ffi_prep_cif_machdep): Add X86_WIN32 struct case. + (ffi_closure_SYSV): Add 1 or 2-bytes struct case for X86_WIN32. + * src/x86/win32.S (retstruct1b, retstruct2b, sc_retstruct1b, + sc_retstruct2b): Add for 1 or 2-bytes struct case. + +2004-03-15 Kelley Cook + + * configure.in: Rename file to ... + * configure.ac: ... this. + * fficonfig.h.in: Regenerate. + * Makefile.in: Regenerate. + * include/Makefile.in: Regenerate. + * testsuite/Makefile.in: Regenerate. + +2004-03-12 Matt Austern + + * src/powerpc/darwin.S: Fix EH information so it corresponds to + changes in EH format resulting from addition of linkonce support. + * src/powerpc/darwin_closure.S: Likewise. + +2004-03-11 Andreas Tobler + Paolo Bonzini + + * Makefile.am (AUTOMAKE_OPTIONS): Set them. + Remove VPATH. Remove rules for object files. Remove multilib support. + (AM_CCASFLAGS): Add. + * configure.in (AC_CONFIG_HEADERS): Relace AM_CONFIG_HEADER. + (AC_PREREQ): Bump version to 2.59. + (AC_INIT): Fill with version info and bug address. + (ORIGINAL_LD_FOR_MULTILIBS): Remove. + (AM_ENABLE_MULTILIB): Use this instead of AC_ARG_ENABLE. + De-precious CC so that the right flags are passed down to multilibs. + (AC_MSG_ERROR): Replace obsolete macro AC_ERROR. + (AC_CONFIG_FILES): Replace obsolete macro AC_LINK_FILES. + (AC_OUTPUT): Reorganize the output with AC_CONFIG_COMMANDS. + * configure: Rebuilt. + * aclocal.m4: Likewise. + * Makefile.in, include/Makefile.in, testsuite/Makefile.in: Likewise. + * fficonfig.h.in: Likewise. + +2004-03-11 Andreas Schwab + + * src/ia64/ffi.c (ffi_prep_incoming_args_UNIX): Get floating point + arguments from fp registers only for the first 8 parameter slots. + Don't convert a float parameter when passed in memory. + +2004-03-09 Hans-Peter Nilsson + + * configure: Regenerate for config/accross.m4 correction. + +2004-02-25 Matt Kraai + + * src/powerpc/ffi.c (ffi_prep_args_SYSV): Change + ecif->cif->bytes to bytes. + (ffi_prep_cif_machdep): Add braces around nested if statement. + +2004-02-09 Alan Modra + + * src/types.c (pointer): POWERPC64 has 8 byte pointers. + + * src/powerpc/ffi.c (ffi_prep_args64): Correct long double handling. + (ffi_closure_helper_LINUX64): Fix typo. + * testsuite/libffi.call/cls_align_longdouble.c: Pass -mlong-double-128 + for powerpc64-*-*. + * testsuite/libffi.call/float.c: Likewise. + * testsuite/libffi.call/float2.c: Likewise. + +2004-02-08 Alan Modra + + * src/powerpc/ffi.c (ffi_prep_cif_machdep ): Correct + long double function return and long double arg handling. + (ffi_closure_helper_LINUX64): Formatting. Delete unused "ng" var. + Use "end_pfr" instead of "nf". Correct long double handling. + Localise "temp". + * src/powerpc/linux64.S (ffi_call_LINUX64): Save f2 long double + return value. + * src/powerpc/linux64_closure.S (ffi_closure_LINUX64): Allocate + space for long double return value. Adjust stack frame and offsets. + Load f2 long double return. + +2004-02-07 Alan Modra + + * src/types.c: Use 16 byte long double for POWERPC64. + +2004-01-25 Eric Botcazou + + * src/sparc/ffi.c (ffi_prep_args_v9): Shift the parameter array + when the structure return address is passed in %o0. + (ffi_V9_return_struct): Rename into ffi_v9_layout_struct. + (ffi_v9_layout_struct): Align the field following a nested structure + on a word boundary. Use memmove instead of memcpy. + (ffi_call): Update call to ffi_V9_return_struct. + (ffi_prep_closure): Define 'ctx' only for V8. + (ffi_closure_sparc_inner): Clone into ffi_closure_sparc_inner_v8 + and ffi_closure_sparc_inner_v9. + (ffi_closure_sparc_inner_v8): Return long doubles by reference. + Always skip the structure return address. For structures and long + doubles, copy the argument directly. + (ffi_closure_sparc_inner_v9): Skip the structure return address only + if required. Shift the maximum floating-point slot accordingly. For + big structures, copy the argument directly; otherwise, left-justify the + argument and call ffi_v9_layout_struct to lay out the structure on + the stack. + * src/sparc/v8.S: Undef STACKFRAME before defining it. + (ffi_closure_v8): Pass the structure return address. Update call to + ffi_closure_sparc_inner_v8. Short-circuit FFI_TYPE_INT handling. + Skip the 'unimp' insn when returning long doubles and structures. + * src/sparc/v9.S: Undef STACKFRAME before defining it. + (ffi_closure_v9): Increase the frame size by 2 words. Short-circuit + FFI_TYPE_INT handling. Load structures both in integers and + floating-point registers on return. + * README: Update status of the SPARC port. + +2004-01-24 Andreas Tobler + + * testsuite/libffi.call/pyobjc-tc.c (main): Treat result value + as of type ffi_arg. + * testsuite/libffi.call/struct3.c (main): Fix CHECK. + +2004-01-22 Ulrich Weigand + + * testsuite/libffi.call/cls_uint.c (cls_ret_uint_fn): Treat result + value as of type ffi_arg, not unsigned int. + +2004-01-21 Michael Ritzert + + * ffi64.c (ffi_prep_args): Cast the RHS of an assignment instead + of the LHS. + +2004-01-12 Andreas Tobler + + * testsuite/lib/libffi-dg.exp: Set LD_LIBRARY_PATH_32 for + Solaris. + +2004-01-08 Rainer Orth + + * testsuite/libffi.call/ffitest.h (allocate_mmap): Cast MAP_FAILED + to void *. + +2003-12-10 Richard Henderson + + * testsuite/libffi.call/cls_align_pointer.c: Cast pointers to + size_t instead of int. + +2003-12-04 Hosaka Yuji + + * testsuite/libffi.call/many_win32.c: Include . + * testsuite/libffi.call/many_win32.c (main): Replace variable + int i with unsigned long ul. + + * testsuite/libffi.call/cls_align_uint64.c: New test case. + * testsuite/libffi.call/cls_align_sint64.c: Likewise. + * testsuite/libffi.call/cls_align_uint32.c: Likewise. + * testsuite/libffi.call/cls_align_sint32.c: Likewise. + * testsuite/libffi.call/cls_align_uint16.c: Likewise. + * testsuite/libffi.call/cls_align_sint16.c: Likewise. + * testsuite/libffi.call/cls_align_float.c: Likewise. + * testsuite/libffi.call/cls_align_double.c: Likewise. + * testsuite/libffi.call/cls_align_longdouble.c: Likewise. + * testsuite/libffi.call/cls_align_pointer.c: Likewise. + +2003-12-02 Hosaka Yuji + + PR other/13221 + * src/x86/ffi.c (ffi_prep_args, ffi_prep_incoming_args_SYSV): + Align arguments to 32 bits. + +2003-12-01 Andreas Tobler + + PR other/13221 + * testsuite/libffi.call/cls_multi_sshort.c: New test case. + * testsuite/libffi.call/cls_multi_sshortchar.c: Likewise. + * testsuite/libffi.call/cls_multi_uchar.c: Likewise. + * testsuite/libffi.call/cls_multi_schar.c: Likewise. + * testsuite/libffi.call/cls_multi_ushortchar.c: Likewise. + * testsuite/libffi.call/cls_multi_ushort.c: Likewise. + + * testsuite/libffi.special/unwindtest.cc: Cosmetics. + +2003-11-26 Kaveh R. Ghazi + + * testsuite/libffi.call/ffitest.h: Include . + * testsuite/libffi.special/ffitestcxx.h: Likewise. + +2003-11-22 Andreas Tobler + + * Makefile.in: Rebuilt. + * configure: Likewise. + * testsuite/libffi.special/unwindtest.cc: Convert the mmap to + the right type. + +2003-11-21 Andreas Jaeger + Andreas Tobler + + * acinclude.m4: Add AC_FUNC_MMAP_BLACKLIST. + * configure.in: Call AC_FUNC_MMAP_BLACKLIST. + * Makefile.in: Rebuilt. + * aclocal.m4: Likewise. + * configure: Likewise. + * fficonfig.h.in: Likewise. + * testsuite/lib/libffi-dg.exp: Add include dir. + * testsuite/libffi.call/ffitest.h: Add MMAP definitions. + * testsuite/libffi.special/ffitestcxx.h: Likewise. + * testsuite/libffi.call/closure_fn0.c: Use MMAP functionality + for ffi_closure if available. + * testsuite/libffi.call/closure_fn1.c: Likewise. + * testsuite/libffi.call/closure_fn2.c: Likewise. + * testsuite/libffi.call/closure_fn3.c: Likewise. + * testsuite/libffi.call/closure_fn4.c: Likewise. + * testsuite/libffi.call/closure_fn5.c: Likewise. + * testsuite/libffi.call/cls_12byte.c: Likewise. + * testsuite/libffi.call/cls_16byte.c: Likewise. + * testsuite/libffi.call/cls_18byte.c: Likewise. + * testsuite/libffi.call/cls_19byte.c: Likewise. + * testsuite/libffi.call/cls_1_1byte.c: Likewise. + * testsuite/libffi.call/cls_20byte.c: Likewise. + * testsuite/libffi.call/cls_20byte1.c: Likewise. + * testsuite/libffi.call/cls_24byte.c: Likewise. + * testsuite/libffi.call/cls_2byte.c: Likewise. + * testsuite/libffi.call/cls_3_1byte.c: Likewise. + * testsuite/libffi.call/cls_3byte1.c: Likewise. + * testsuite/libffi.call/cls_3byte2.c: Likewise. + * testsuite/libffi.call/cls_4_1byte.c: Likewise. + * testsuite/libffi.call/cls_4byte.c: Likewise. + * testsuite/libffi.call/cls_5byte.c: Likewise. + * testsuite/libffi.call/cls_64byte.c: Likewise. + * testsuite/libffi.call/cls_6byte.c: Likewise. + * testsuite/libffi.call/cls_7byte.c: Likewise. + * testsuite/libffi.call/cls_8byte.c: Likewise. + * testsuite/libffi.call/cls_9byte1.c: Likewise. + * testsuite/libffi.call/cls_9byte2.c: Likewise. + * testsuite/libffi.call/cls_double.c: Likewise. + * testsuite/libffi.call/cls_float.c: Likewise. + * testsuite/libffi.call/cls_schar.c: Likewise. + * testsuite/libffi.call/cls_sint.c: Likewise. + * testsuite/libffi.call/cls_sshort.c: Likewise. + * testsuite/libffi.call/cls_uchar.c: Likewise. + * testsuite/libffi.call/cls_uint.c: Likewise. + * testsuite/libffi.call/cls_ulonglong.c: Likewise. + * testsuite/libffi.call/cls_ushort.c: Likewise. + * testsuite/libffi.call/nested_struct.c: Likewise. + * testsuite/libffi.call/nested_struct1.c: Likewise. + * testsuite/libffi.call/nested_struct2.c: Likewise. + * testsuite/libffi.call/nested_struct3.c: Likewise. + * testsuite/libffi.call/problem1.c: Likewise. + * testsuite/libffi.special/unwindtest.cc: Likewise. + +2003-11-20 Andreas Tobler + + * testsuite/lib/libffi-dg.exp: Make the -lgcc_s conditional. + +2003-11-19 Andreas Tobler + + * testsuite/lib/libffi-dg.exp: Add DYLD_LIBRARY_PATH for darwin. + Add -lgcc_s to additional flags. + +2003-11-12 Andreas Tobler + + * configure.in, include/Makefile.am: PR libgcj/11147, install + the ffitarget.h header file in a gcc versioned and target + dependent place. + * configure: Regenerated. + * Makefile.in, include/Makefile.in: Likewise. + * testsuite/Makefile.in: Likewise. + +2003-11-09 Andreas Tobler + + * testsuite/libffi.call/closure_fn0.c: Print result and check + with dg-output to make debugging easier. + * testsuite/libffi.call/closure_fn1.c: Likewise. + * testsuite/libffi.call/closure_fn2.c: Likewise. + * testsuite/libffi.call/closure_fn3.c: Likewise. + * testsuite/libffi.call/closure_fn4.c: Likewise. + * testsuite/libffi.call/closure_fn5.c: Likewise. + * testsuite/libffi.call/cls_12byte.c: Likewise. + * testsuite/libffi.call/cls_16byte.c: Likewise. + * testsuite/libffi.call/cls_18byte.c: Likewise. + * testsuite/libffi.call/cls_19byte.c: Likewise. + * testsuite/libffi.call/cls_1_1byte.c: Likewise. + * testsuite/libffi.call/cls_20byte.c: Likewise. + * testsuite/libffi.call/cls_20byte1.c: Likewise. + * testsuite/libffi.call/cls_24byte.c: Likewise. + * testsuite/libffi.call/cls_2byte.c: Likewise. + * testsuite/libffi.call/cls_3_1byte.c: Likewise. + * testsuite/libffi.call/cls_3byte1.c: Likewise. + * testsuite/libffi.call/cls_3byte2.c: Likewise. + * testsuite/libffi.call/cls_4_1byte.c: Likewise. + * testsuite/libffi.call/cls_4byte.c: Likewise. + * testsuite/libffi.call/cls_5byte.c: Likewise. + * testsuite/libffi.call/cls_64byte.c: Likewise. + * testsuite/libffi.call/cls_6byte.c: Likewise. + * testsuite/libffi.call/cls_7byte.c: Likewise. + * testsuite/libffi.call/cls_8byte.c: Likewise. + * testsuite/libffi.call/cls_9byte1.c: Likewise. + * testsuite/libffi.call/cls_9byte2.c: Likewise. + * testsuite/libffi.call/cls_double.c: Likewise. + * testsuite/libffi.call/cls_float.c: Likewise. + * testsuite/libffi.call/cls_schar.c: Likewise. + * testsuite/libffi.call/cls_sint.c: Likewise. + * testsuite/libffi.call/cls_sshort.c: Likewise. + * testsuite/libffi.call/cls_uchar.c: Likewise. + * testsuite/libffi.call/cls_uint.c: Likewise. + * testsuite/libffi.call/cls_ulonglong.c: Likewise. + * testsuite/libffi.call/cls_ushort.c: Likewise. + * testsuite/libffi.call/problem1.c: Likewise. + + * testsuite/libffi.special/unwindtest.cc: Make ffi_closure + static. + +2003-11-08 Andreas Tobler + + * testsuite/libffi.call/cls_9byte2.c: New test case. + * testsuite/libffi.call/cls_9byte1.c: Likewise. + * testsuite/libffi.call/cls_64byte.c: Likewise. + * testsuite/libffi.call/cls_20byte1.c: Likewise. + * testsuite/libffi.call/cls_19byte.c: Likewise. + * testsuite/libffi.call/cls_18byte.c: Likewise. + * testsuite/libffi.call/closure_fn4.c: Likewise. + * testsuite/libffi.call/closure_fn5.c: Likewise. + * testsuite/libffi.call/cls_schar.c: Likewise. + * testsuite/libffi.call/cls_sint.c: Likewise. + * testsuite/libffi.call/cls_sshort.c: Likewise. + * testsuite/libffi.call/nested_struct2.c: Likewise. + * testsuite/libffi.call/nested_struct3.c: Likewise. + +2003-11-08 Andreas Tobler + + * testsuite/libffi.call/cls_double.c: Do a check on the result. + * testsuite/libffi.call/cls_uchar.c: Likewise. + * testsuite/libffi.call/cls_uint.c: Likewise. + * testsuite/libffi.call/cls_ulonglong.c: Likewise. + * testsuite/libffi.call/cls_ushort.c: Likewise. + * testsuite/libffi.call/return_sc.c: Cleanup whitespaces. + +2003-11-06 Andreas Tobler + + * src/prep_cif.c (ffi_prep_cif): Move the validity check after + the initialization. + +2003-10-23 Andreas Tobler + + * src/java_raw_api.c (ffi_java_ptrarray_to_raw): Replace + FFI_ASSERT(FALSE) with FFI_ASSERT(0). + +2003-10-22 David Daney + + * src/mips/ffitarget.h: Replace undefined UINT32 and friends with + __attribute__((__mode__(__SI__))) and friends. + +2003-10-22 Andreas Schwab + + * src/ia64/ffi.c: Replace FALSE/TRUE with false/true. + +2003-10-21 Andreas Tobler + + * configure.in: AC_LINK_FILES(ffitarget.h). + * configure: Regenerate. + * Makefile.in: Likewise. + * include/Makefile.in: Likewise. + * testsuite/Makefile.in: Likewise. + * fficonfig.h.in: Likewise. + +2003-10-21 Paolo Bonzini + Richard Henderson + + Avoid that ffi.h includes fficonfig.h. + + * Makefile.am (EXTRA_DIST): Include ffitarget.h files + (TARGET_SRC_MIPS_GCC): Renamed to TARGET_SRC_MIPS_IRIX. + (TARGET_SRC_MIPS_SGI): Removed. + (MIPS_GCC): Renamed to TARGET_SRC_MIPS_IRIX. + (MIPS_SGI): Removed. + (CLEANFILES): Removed. + (mostlyclean-am, clean-am, mostlyclean-sub, clean-sub): New + targets. + * acconfig.h: Removed. + * configure.in: Compute sizeofs only for double and long double. + Use them to define and subst HAVE_LONG_DOUBLE. Include comments + into AC_DEFINE instead of using acconfig.h. Create + include/ffitarget.h instead of include/fficonfig.h. Rename + MIPS_GCC to MIPS_IRIX, drop MIPS_SGI since we are in gcc's tree. + AC_DEFINE EH_FRAME_FLAGS. + * include/Makefile.am (DISTCLEANFILES): New automake macro. + (hack_DATA): Add ffitarget.h. + * include/ffi.h.in: Remove all system specific definitions. + Declare raw API even if it is not installed, why bother? + Use limits.h instead of SIZEOF_* to define ffi_type_*. Do + not define EH_FRAME_FLAGS, it is in fficonfig.h now. Include + ffitarget.h instead of fficonfig.h. Remove ALIGN macro. + (UINT_ARG, INT_ARG): Removed, use ffi_arg and ffi_sarg instead. + * include/ffi_common.h (bool): Do not define. + (ffi_assert): Accept failed assertion. + (ffi_type_test): Return void and accept file/line. + (FFI_ASSERT): Pass stringized failed assertion. + (FFI_ASSERT_AT): New macro. + (FFI_ASSERT_VALID_TYPE): New macro. + (UINT8, SINT8, UINT16, SINT16, UINT32, SINT32, + UINT64, SINT64): Define here with gcc's __attribute__ macro + instead of in ffi.h + (FLOAT32, ALIGN): Define here instead of in ffi.h + * include/ffi-mips.h: Removed. Its content moved to + src/mips/ffitarget.h after separating assembly and C sections. + * src/alpha/ffi.c, src/alpha/ffi.c, src/java_raw_api.c + src/prep_cif.c, src/raw_api.c, src/ia64/ffi.c, + src/mips/ffi.c, src/mips/n32.S, src/mips/o32.S, + src/mips/ffitarget.h, src/sparc/ffi.c, src/x86/ffi64.c: + SIZEOF_ARG -> FFI_SIZEOF_ARG. + * src/ia64/ffi.c: Include stdbool.h (provided by GCC 2.95+). + * src/debug.c (ffi_assert): Accept stringized failed assertion. + (ffi_type_test): Rewritten. + * src/prep-cif.c (initialize_aggregate, ffi_prep_cif): Call + FFI_ASSERT_VALID_TYPE. + * src/alpha/ffitarget.h, src/arm/ffitarget.h, + src/ia64/ffitarget.h, src/m68k/ffitarget.h, + src/mips/ffitarget.h, src/powerpc/ffitarget.h, + src/s390/ffitarget.h, src/sh/ffitarget.h, + src/sh64/ffitarget.h, src/sparc/ffitarget.h, + src/x86/ffitarget.h: New files. + * src/alpha/osf.S, src/arm/sysv.S, src/ia64/unix.S, + src/m68k/sysv.S, src/mips/n32.S, src/mips/o32.S, + src/powerpc/aix.S, src/powerpc/darwin.S, + src/powerpc/ffi_darwin.c, src/powerpc/linux64.S, + src/powerpc/linux64_closure.S, src/powerpc/ppc_closure.S, + src/powerpc/sysv.S, src/s390/sysv.S, src/sh/sysv.S, + src/sh64/sysv.S, src/sparc/v8.S, src/sparc/v9.S, + src/x86/sysv.S, src/x86/unix64.S, src/x86/win32.S: + include fficonfig.h + +2003-10-20 Rainer Orth + + * src/mips/ffi.c: Use _ABIN32, _ABIO32 instead of external + _MIPS_SIM_NABI32, _MIPS_SIM_ABI32. + +2003-10-19 Andreas Tobler + + * src/powerpc/ffi_darwin.c (ffi_prep_args): Declare bytes again. + Used when FFI_DEBUG = 1. + +2003-10-14 Alan Modra + + * src/types.c (double, longdouble): Default POWERPC64 to 8 byte size + and align. + +2003-10-06 Rainer Orth + + * include/ffi_mips.h: Define FFI_MIPS_N32 for N32/N64 ABIs, + FFI_MIPS_O32 for O32 ABI. + +2003-10-01 Andreas Tobler + + * testsuite/lib/libffi-dg.exp: Set LD_LIBRARY_PATH_64 for + SPARC64. Cleanup whitespaces. + +2003-09-19 Andreas Tobler + + * testsuite/libffi.call/closure_fn0.c: Xfail mips, arm, + strongarm, xscale. Cleanup whitespaces. + * testsuite/libffi.call/closure_fn1.c: Likewise. + * testsuite/libffi.call/closure_fn2.c: Likewise. + * testsuite/libffi.call/closure_fn3.c: Likewise. + * testsuite/libffi.call/cls_12byte.c: Likewise. + * testsuite/libffi.call/cls_16byte.c: Likewise. + * testsuite/libffi.call/cls_1_1byte.c: Likewise. + * testsuite/libffi.call/cls_20byte.c: Likewise. + * testsuite/libffi.call/cls_24byte.c: Likewise. + * testsuite/libffi.call/cls_2byte.c: Likewise. + * testsuite/libffi.call/cls_3_1byte.c: Likewise. + * testsuite/libffi.call/cls_3byte1.c: Likewise. + * testsuite/libffi.call/cls_3byte2.c: Likewise. + * testsuite/libffi.call/cls_4_1byte.c: Likewise. + * testsuite/libffi.call/cls_4byte.c: Likewise. + * testsuite/libffi.call/cls_5byte.c: Likewise. + * testsuite/libffi.call/cls_6byte.c: Likewise. + * testsuite/libffi.call/cls_7byte.c: Likewise. + * testsuite/libffi.call/cls_8byte.c: Likewise. + * testsuite/libffi.call/cls_double.c: Likewise. + * testsuite/libffi.call/cls_float.c: Likewise. + * testsuite/libffi.call/cls_uchar.c: Likewise. + * testsuite/libffi.call/cls_uint.c: Likewise. + * testsuite/libffi.call/cls_ulonglong.c: Likewise. + * testsuite/libffi.call/cls_ushort.c: Likewise. + * testsuite/libffi.call/nested_struct.c: Likewise. + * testsuite/libffi.call/nested_struct1.c: Likewise. + * testsuite/libffi.call/problem1.c: Likewise. + * testsuite/libffi.special/unwindtest.cc: Likewise. + * testsuite/libffi.call/pyobjc-tc.c: Cleanup whitespaces. + +2003-09-18 David Edelsohn + + * src/powerpc/aix.S: Cleanup whitespaces. + * src/powerpc/aix_closure.S: Likewise. + +2003-09-18 Andreas Tobler + + * src/powerpc/darwin.S: Cleanup whitespaces, comment formatting. + * src/powerpc/darwin_closure.S: Likewise. + * src/powerpc/ffi_darwin.c: Likewise. + +2003-09-18 Andreas Tobler + David Edelsohn + + * src/types.c (double): Add AIX and Darwin to the right TYPEDEF. + * src/powerpc/aix_closure.S: Remove the pointer to the outgoing + parameter stack. + * src/powerpc/darwin_closure.S: Likewise. + * src/powerpc/ffi_darwin.c (ffi_prep_args): Handle structures + according to the Darwin/AIX ABI. + (ffi_prep_cif_machdep): Likewise. + (ffi_closure_helper_DARWIN): Likewise. + Remove the outgoing parameter stack logic. Simplify the evaluation + of the different CASE types. + (ffi_prep_clousure): Avoid the casts on lvalues. Change the branch + statement in the trampoline code. + +2003-09-18 Kaz Kojima + + * src/sh/ffi.c (ffi_prep_args): Take account into the alignement + for the register size. + (ffi_closure_helper_SYSV): Handle the structure return value + address correctly. + (ffi_closure_helper_SYSV): Return the appropriate type when + the registers are used for the structure return value. + * src/sh/sysv.S (ffi_closure_SYSV): Fix the stack layout for + the 64-bit return value. Update copyright years. + +2003-09-17 Rainer Orth + + * testsuite/lib/libffi-dg.exp (libffi_target_compile): Search in + srcdir for ffi_mips.h. + +2003-09-12 Alan Modra + + * src/prep_cif.c (initialize_aggregate): Include tail padding in + structure size. + * src/powerpc/linux64_closure.S (ffi_closure_LINUX64): Correct + placement of float result. + * testsuite/libffi.special/unwindtest.cc (closure_test_fn1): Correct + cast of "resp" for big-endian 64 bit machines. + +2003-09-11 Alan Modra + + * src/types.c (double, longdouble): Merge identical SH and ARM + typedefs, and add POWERPC64. + * src/powerpc/ffi.c (ffi_prep_args64): Correct next_arg calc for + struct split over gpr and rest. + (ffi_prep_cif_machdep): Correct intarg_count for structures. + * src/powerpc/linux64.S (ffi_call_LINUX64): Fix gpr offsets. + +2003-09-09 Andreas Tobler + + * src/powerpc/ffi.c (ffi_closure_helper_SYSV) Handle struct + passing correctly. + +2003-09-09 Alan Modra + + * configure: Regenerate. + +2003-09-04 Andreas Tobler + + * Makefile.am: Remove build rules for ffitest. + * Makefile.in: Rebuilt. + +2003-09-04 Andreas Tobler + + * src/java_raw_api.c: Include to fix compiler warning + about implicit declaration of abort(). + +2003-09-04 Andreas Tobler + + * Makefile.am: Add dejagnu test framework. Fixes PR other/11411. + * Makefile.in: Rebuilt. + * configure.in: Add dejagnu test framework. + * configure: Rebuilt. + + * testsuite/Makefile.am: New file. + * testsuite/Makefile.in: Built + * testsuite/lib/libffi-dg.exp: New file. + * testsuite/config/default.exp: Likewise. + * testsuite/libffi.call/call.exp: Likewise. + * testsuite/libffi.call/ffitest.h: Likewise. + * testsuite/libffi.call/closure_fn0.c: Likewise. + * testsuite/libffi.call/closure_fn1.c: Likewise. + * testsuite/libffi.call/closure_fn2.c: Likewise. + * testsuite/libffi.call/closure_fn3.c: Likewise. + * testsuite/libffi.call/cls_1_1byte.c: Likewise. + * testsuite/libffi.call/cls_3_1byte.c: Likewise. + * testsuite/libffi.call/cls_4_1byte.c: Likewise. + * testsuite/libffi.call/cls_2byte.c: Likewise. + * testsuite/libffi.call/cls_3byte1.c: Likewise. + * testsuite/libffi.call/cls_3byte2.c: Likewise. + * testsuite/libffi.call/cls_4byte.c: Likewise. + * testsuite/libffi.call/cls_5byte.c: Likewise. + * testsuite/libffi.call/cls_6byte.c: Likewise. + * testsuite/libffi.call/cls_7byte.c: Likewise. + * testsuite/libffi.call/cls_8byte.c: Likewise. + * testsuite/libffi.call/cls_12byte.c: Likewise. + * testsuite/libffi.call/cls_16byte.c: Likewise. + * testsuite/libffi.call/cls_20byte.c: Likewise. + * testsuite/libffi.call/cls_24byte.c: Likewise. + * testsuite/libffi.call/cls_double.c: Likewise. + * testsuite/libffi.call/cls_float.c: Likewise. + * testsuite/libffi.call/cls_uchar.c: Likewise. + * testsuite/libffi.call/cls_uint.c: Likewise. + * testsuite/libffi.call/cls_ulonglong.c: Likewise. + * testsuite/libffi.call/cls_ushort.c: Likewise. + * testsuite/libffi.call/float.c: Likewise. + * testsuite/libffi.call/float1.c: Likewise. + * testsuite/libffi.call/float2.c: Likewise. + * testsuite/libffi.call/many.c: Likewise. + * testsuite/libffi.call/many_win32.c: Likewise. + * testsuite/libffi.call/nested_struct.c: Likewise. + * testsuite/libffi.call/nested_struct1.c: Likewise. + * testsuite/libffi.call/pyobjc-tc.c: Likewise. + * testsuite/libffi.call/problem1.c: Likewise. + * testsuite/libffi.call/promotion.c: Likewise. + * testsuite/libffi.call/return_ll.c: Likewise. + * testsuite/libffi.call/return_sc.c: Likewise. + * testsuite/libffi.call/return_uc.c: Likewise. + * testsuite/libffi.call/strlen.c: Likewise. + * testsuite/libffi.call/strlen_win32.c: Likewise. + * testsuite/libffi.call/struct1.c: Likewise. + * testsuite/libffi.call/struct2.c: Likewise. + * testsuite/libffi.call/struct3.c: Likewise. + * testsuite/libffi.call/struct4.c: Likewise. + * testsuite/libffi.call/struct5.c: Likewise. + * testsuite/libffi.call/struct6.c: Likewise. + * testsuite/libffi.call/struct7.c: Likewise. + * testsuite/libffi.call/struct8.c: Likewise. + * testsuite/libffi.call/struct9.c: Likewise. + * testsuite/libffi.special/special.exp: New file. + * testsuite/libffi.special/ffitestcxx.h: Likewise. + * testsuite/libffi.special/unwindtest.cc: Likewise. + + +2003-08-13 Kaz Kojima + + * src/sh/ffi.c (OFS_INT16): Set 0 for little endian case. Update + copyright years. + +2003-08-02 Alan Modra + + * src/powerpc/ffi.c (ffi_prep_args64): Modify for changed gcc + structure passing. + (ffi_closure_helper_LINUX64): Likewise. + * src/powerpc/linux64.S: Remove code writing to parm save area. + * src/powerpc/linux64_closure.S (ffi_closure_LINUX64): Use return + address in lr from ffi_closure_helper_LINUX64 call to calculate + table address. Optimize function tail. + +2003-07-28 Andreas Tobler + + * src/sparc/ffi.c: Handle all floating point registers. + * src/sparc/v9.S: Likewise. Fixes second part of PR target/11410. + +2003-07-11 Gerald Pfeifer + + * README: Note that libffi is not part of GCC. Update the project + URL and status. + +2003-06-19 Franz Sirl + + * src/powerpc/ppc_closure.S: Include ffi.h. + +2003-06-13 Rainer Orth + + * src/x86/sysv.S: Avoid gas-only .uleb128/.sleb128 directives. + Use C style comments. + +2003-06-13 Kaz Kojima + + * Makefile.am: Add SHmedia support. Fix a typo of SH support. + * Makefile.in: Regenerate. + * configure.in (sh64-*-linux*, sh5*-*-linux*): Add target. + * configure: Regenerate. + * include/ffi.h.in: Add SHmedia support. + * src/sh64/ffi.c: New file. + * src/sh64/sysv.S: New file. + +2003-05-16 Jakub Jelinek + + * configure.in (HAVE_RO_EH_FRAME): Check whether .eh_frame section + should be read-only. + * configure: Rebuilt. + * fficonfig.h.in: Rebuilt. + * include/ffi.h.in (EH_FRAME_FLAGS): Define. + * src/alpha/osf.S: Use EH_FRAME_FLAGS. + * src/powerpc/linux64.S: Likewise. + * src/powerpc/linux64_closure.S: Likewise. Include ffi.h. + * src/powerpc/sysv.S: Use EH_FRAME_FLAGS. Use pcrel encoding + if -fpic/-fPIC/-mrelocatable. + * src/powerpc/powerpc_closure.S: Likewise. + * src/sparc/v8.S: If HAVE_RO_EH_FRAME is defined, don't include + #write in .eh_frame flags. + * src/sparc/v9.S: Likewise. + * src/x86/unix64.S: Use EH_FRAME_FLAGS. + * src/x86/sysv.S: Likewise. Use pcrel encoding if -fpic/-fPIC. + * src/s390/sysv.S: Use EH_FRAME_FLAGS. Include ffi.h. + +2003-05-07 Jeff Sturm + + Fixes PR bootstrap/10656 + * configure.in (HAVE_AS_REGISTER_PSEUDO_OP): Test assembler + support for .register pseudo-op. + * src/sparc/v8.S: Use it. + * fficonfig.h.in: Rebuilt. + * configure: Rebuilt. + +2003-04-18 Jakub Jelinek + + * include/ffi.h.in (POWERPC64): Define if 64-bit. + (enum ffi_abi): Add FFI_LINUX64 on POWERPC. + Make it the default on POWERPC64. + (FFI_TRAMPOLINE_SIZE): Define to 24 on POWERPC64. + * configure.in: Change powerpc-*-linux* into powerpc*-*-linux*. + * configure: Rebuilt. + * src/powerpc/ffi.c (hidden): Define. + (ffi_prep_args_SYSV): Renamed from + ffi_prep_args. Cast pointers to unsigned long to shut up warnings. + (NUM_GPR_ARG_REGISTERS64, NUM_FPR_ARG_REGISTERS64, + ASM_NEEDS_REGISTERS64): New. + (ffi_prep_args64): New function. + (ffi_prep_cif_machdep): Handle FFI_LINUX64 ABI. + (ffi_call): Likewise. + (ffi_prep_closure): Likewise. + (flush_icache): Surround by #ifndef POWERPC64. + (ffi_dblfl): New union type. + (ffi_closure_helper_SYSV): Use it to avoid aliasing problems. + (ffi_closure_helper_LINUX64): New function. + * src/powerpc/ppc_closure.S: Surround whole file by #ifndef + __powerpc64__. + * src/powerpc/sysv.S: Likewise. + (ffi_call_SYSV): Rename ffi_prep_args to ffi_prep_args_SYSV. + * src/powerpc/linux64.S: New file. + * src/powerpc/linux64_closure.S: New file. + * Makefile.am (EXTRA_DIST): Add src/powerpc/linux64.S and + src/powerpc/linux64_closure.S. + (TARGET_SRC_POWERPC): Likewise. + + * src/ffitest.c (closure_test_fn, closure_test_fn1, closure_test_fn2, + closure_test_fn3): Fix result printing on big-endian 64-bit + machines. + (main): Print tst2_arg instead of uninitialized tst2_result. + + * src/ffitest.c (main): Hide what closure pointer really points to + from the compiler. + +2003-04-16 Richard Earnshaw + + * configure.in (arm-*-netbsdelf*): Add configuration. + (configure): Regenerated. + +2003-04-04 Loren J. Rittle + + * include/Makefile.in: Regenerate. + +2003-03-21 Zdenek Dvorak + + * libffi/include/ffi.h.in: Define X86 instead of X86_64 in 32 + bit mode. + * libffi/src/x86/ffi.c (ffi_closure_SYSV, ffi_closure_raw_SYSV): + Receive closure pointer through parameter, read args using + __builtin_dwarf_cfa. + (FFI_INIT_TRAMPOLINE): Send closure reference through eax. + +2003-03-12 Andreas Schwab + + * configure.in: Avoid trailing /. in toolexeclibdir. + * configure: Rebuilt. + +2003-03-03 Andreas Tobler + + * src/powerpc/darwin_closure.S: Recode to fit dynamic libraries. + +2003-02-06 Andreas Tobler + + * libffi/src/powerpc/darwin_closure.S: + Fix alignement bug, allocate 8 bytes for the result. + * libffi/src/powerpc/aix_closure.S: + Likewise. + * libffi/src/powerpc/ffi_darwin.c: + Update stackframe description for aix/darwin_closure.S. + +2003-02-06 Jakub Jelinek + + * src/s390/ffi.c (ffi_closure_helper_SYSV): Add hidden visibility + attribute. + +2003-01-31 Christian Cornelssen , + Andreas Schwab + + * configure.in: Adjust command to source config-ml.in to account + for changes to the libffi_basedir definition. + (libffi_basedir): Remove ${srcdir} from value and include trailing + slash if nonempty. + + * configure: Regenerate. + +2003-01-29 Franz Sirl + + * src/powerpc/ppc_closure.S: Recode to fit shared libs. + +2003-01-28 Andrew Haley + + * include/ffi.h.in: Enable FFI_CLOSURES for x86_64. + * src/x86/ffi64.c (ffi_prep_closure): New. + (ffi_closure_UNIX64_inner): New. + * src/x86/unix64.S (ffi_closure_UNIX64): New. + +2003-01-27 Alexandre Oliva + + * configure.in (toolexecdir, toolexeclibdir): Set and AC_SUBST. + Remove USE_LIBDIR conditional. + * Makefile.am (toolexecdir, toolexeclibdir): Don't override. + * Makefile.in, configure: Rebuilt. + +2003-01027 David Edelsohn + + * Makefile.am (TARGET_SRC_POWERPC_AIX): Fix typo. + * Makefile.in: Regenerate. + +2003-01-22 Andrew Haley + + * src/powerpc/darwin.S (_ffi_call_AIX): Add Augmentation size to + unwind info. + +2003-01-21 Andreas Tobler + + * src/powerpc/darwin.S: Add unwind info. + * src/powerpc/darwin_closure.S: Likewise. + +2003-01-14 Andrew Haley + + * src/x86/ffi64.c (ffi_prep_args): Check for void retval. + (ffi_prep_cif_machdep): Likewise. + * src/x86/unix64.S: Add unwind info. + +2003-01-14 Andreas Jaeger + + * src/ffitest.c (main): Only use ffi_closures if those are + supported. + +2003-01-13 Andreas Tobler + + * libffi/src/ffitest.c + add closure testcases + +2003-01-13 Kevin B. Hendricks + + * libffi/src/powerpc/ffi.c + fix alignment bug for float (4 byte aligned iso 8 byte) + +2003-01-09 Geoffrey Keating + + * src/powerpc/ffi_darwin.c: Remove RCS version string. + * src/powerpc/darwin.S: Remove RCS version string. + +2003-01-03 Jeff Sturm + + * include/ffi.h.in: Add closure defines for SPARC, SPARC64. + * src/ffitest.c (main): Use static storage for closure. + * src/sparc/ffi.c (ffi_prep_closure, ffi_closure_sparc_inner): New. + * src/sparc/v8.S (ffi_closure_v8): New. + * src/sparc/v9.S (ffi_closure_v9): New. + +2002-11-10 Ranjit Mathew + + * include/ffi.h.in: Added FFI_STDCALL ffi_type + enumeration for X86_WIN32. + * src/x86/win32.S: Added ffi_call_STDCALL function + definition. + * src/x86/ffi.c (ffi_call/ffi_raw_call): Added + switch cases for recognising FFI_STDCALL and + calling ffi_call_STDCALL if target is X86_WIN32. + * src/ffitest.c (my_stdcall_strlen/stdcall_many): + stdcall versions of the "my_strlen" and "many" + test functions (for X86_WIN32). + Added test cases to test stdcall invocation using + these functions. + +2002-12-02 Kaz Kojima + + * src/sh/sysv.S: Add DWARF2 unwind info. + +2002-11-27 Ulrich Weigand + + * src/s390/sysv.S (.eh_frame section): Make section read-only. + +2002-11-26 Jim Wilson + + * src/types.c (FFI_TYPE_POINTER): Has size 8 on IA64. + +2002-11-23 H.J. Lu + + * acinclude.m4: Add dummy AM_PROG_LIBTOOL. + Include ../config/accross.m4. + * aclocal.m4; Rebuild. + * configure: Likewise. + +2002-11-15 Ulrich Weigand + + * src/s390/sysv.S (.eh_frame section): Adapt to pcrel FDE encoding. + +2002-11-11 DJ Delorie + + * configure.in: Look for common files in the right place. + +2002-10-08 Ulrich Weigand + + * src/java_raw_api.c (ffi_java_raw_to_ptrarray): Interpret + raw data as _Jv_word values, not ffi_raw. + (ffi_java_ptrarray_to_raw): Likewise. + (ffi_java_rvalue_to_raw): New function. + (ffi_java_raw_call): Call it. + (ffi_java_raw_to_rvalue): New function. + (ffi_java_translate_args): Call it. + * src/ffitest.c (closure_test_fn): Interpret return value + as ffi_arg, not int. + * src/s390/ffi.c (ffi_prep_cif_machdep): Add missing + FFI_TYPE_POINTER case. + (ffi_closure_helper_SYSV): Likewise. Also, assume return + values extended to word size. + +2002-10-02 Andreas Jaeger + + * src/x86/ffi64.c (ffi_prep_cif_machdep): Remove debug output. + +2002-10-01 Bo Thorsen + + * include/ffi.h.in: Fix i386 win32 compilation. + +2002-09-30 Ulrich Weigand + + * configure.in: Add s390x-*-linux-* target. + * configure: Regenerate. + * include/ffi.h.in: Define S390X for s390x targets. + (FFI_CLOSURES): Define for s390/s390x. + (FFI_TRAMPOLINE_SIZE): Likewise. + (FFI_NATIVE_RAW_API): Likewise. + * src/prep_cif.c (ffi_prep_cif): Do not compute stack space for s390. + * src/types.c (FFI_TYPE_POINTER): Use 8-byte pointers on s390x. + * src/s390/ffi.c: Major rework of existing code. Add support for + s390x targets. Add closure support. + * src/s390/sysv.S: Likewise. + +2002-09-29 Richard Earnshaw + + * src/arm/sysv.S: Fix typo. + +2002-09-28 Richard Earnshaw + + * src/arm/sysv.S: If we don't have machine/asm.h and the pre-processor + has defined __USER_LABEL_PREFIX__, then use it in CNAME. + (ffi_call_SYSV): Handle soft-float. + +2002-09-27 Bo Thorsen + + * include/ffi.h.in: Fix multilib x86-64 support. + +2002-09-22 Kaveh R. Ghazi + + * Makefile.am (all-multi): Fix multilib parallel build. + +2002-07-19 Kaz Kojima + + * configure.in (sh[34]*-*-linux*): Add brackets. + * configure: Regenerate. + +2002-07-18 Kaz Kojima + + * Makefile.am: Add SH support. + * Makefile.in: Regenerate. + * configure.in (sh-*-linux*, sh[34]*-*-linux*): Add target. + * configure: Regenerate. + * include/ffi.h.in: Add SH support. + * src/sh/ffi.c: New file. + * src/sh/sysv.S: New file. + * src/types.c: Add SH support. + +2002-07-16 Bo Thorsen + + * src/x86/ffi64.c: New file that adds x86-64 support. + * src/x86/unix64.S: New file that handles argument setup for + x86-64. + * src/x86/sysv.S: Don't use this on x86-64. + * src/x86/ffi.c: Don't use this on x86-64. + Remove unused vars. + * src/prep_cif.c (ffi_prep_cif): Don't do stack size calculation + for x86-64. + * src/ffitest.c (struct6): New test that tests a special case in + the x86-64 ABI. + (struct7): Likewise. + (struct8): Likewise. + (struct9): Likewise. + (closure_test_fn): Silence warning about this when it's not used. + (main): Add the new tests. + (main): Fix a couple of wrong casts and silence some compiler warnings. + * include/ffi.h.in: Add x86-64 ABI definition. + * fficonfig.h.in: Regenerate. + * Makefile.am: Add x86-64 support. + * configure.in: Likewise. + * Makefile.in: Regenerate. + * configure: Likewise. + +2002-06-24 Bo Thorsen + + * src/types.c: Merge settings for similar architectures. + Add x86-64 sizes and alignments. + +2002-06-23 Bo Thorsen + + * src/arm/ffi.c (ffi_prep_args): Remove unused vars. + * src/sparc/ffi.c (ffi_prep_args_v8): Likewise. + * src/mips/ffi.c (ffi_prep_args): Likewise. + * src/m68k/ffi.c (ffi_prep_args): Likewise. + +2002-07-18 H.J. Lu (hjl@gnu.org) + + * Makefile.am (TARGET_SRC_MIPS_LINUX): New. + (libffi_la_SOURCES): Support MIPS_LINUX. + (libffi_convenience_la_SOURCES): Likewise. + * Makefile.in: Regenerated. + + * configure.in (mips64*-*): Skip. + (mips*-*-linux*): New. + * configure: Regenerated. + + * src/mips/ffi.c: Include . + +2002-06-06 Ulrich Weigand + + * src/s390/sysv.S: Save/restore %r6. Add DWARF-2 unwind info. + +2002-05-27 Roger Sayle + + * src/x86/ffi.c (ffi_prep_args): Remove reference to avn. + +2002-05-27 Bo Thorsen + + * src/x86/ffi.c (ffi_prep_args): Remove unused variable and + fix formatting. + +2002-05-13 Andreas Tobler + + * src/powerpc/ffi_darwin.c (ffi_prep_closure): Declare fd at + beginning of function (for older apple cc). + +2002-05-08 Alexandre Oliva + + * configure.in (ORIGINAL_LD_FOR_MULTILIBS): Preserve LD at + script entry, and set LD to it when configuring multilibs. + * configure: Rebuilt. + +2002-05-05 Jason Thorpe + + * configure.in (sparc64-*-netbsd*): Add target. + (sparc-*-netbsdelf*): Likewise. + * configure: Regenerate. + +2002-04-28 David S. Miller + + * configure.in, configure: Fix SPARC test in previous change. + +2002-04-29 Gerhard Tonn + + * Makefile.am: Add Linux for S/390 support. + * Makefile.in: Regenerate. + * configure.in: Add Linux for S/390 support. + * configure: Regenerate. + * include/ffi.h.in: Add Linux for S/390 support. + * src/s390/ffi.c: New file from libffi CVS tree. + * src/s390/sysv.S: New file from libffi CVS tree. + +2002-04-28 Jakub Jelinek + + * configure.in (HAVE_AS_SPARC_UA_PCREL): Check for working + %r_disp32(). + * src/sparc/v8.S: Use it. + * src/sparc/v9.S: Likewise. + * fficonfig.h.in: Rebuilt. + * configure: Rebuilt. + +2002-04-08 Hans Boehm + + * src/java_raw_api.c (ffi_java_raw_size): Handle FFI_TYPE_DOUBLE + correctly. + * src/ia64/unix.S: Add unwind information. Fix comments. + Save sp in a way that's compatible with unwind info. + (ffi_call_unix): Correctly restore sp in all cases. + * src/ia64/ffi.c: Add, fix comments. + +2002-04-08 Jakub Jelinek + + * src/sparc/v8.S: Make .eh_frame dependent on target word size. + +2002-04-06 Jason Thorpe + + * configure.in (alpha*-*-netbsd*): Add target. + * configure: Regenerate. + +2002-04-04 Jeff Sturm + + * src/sparc/v8.S: Add unwind info. + * src/sparc/v9.S: Likewise. + +2002-03-30 Krister Walfridsson + + * configure.in: Enable i*86-*-netbsdelf*. + * configure: Rebuilt. + +2002-03-29 David Billinghurst + + PR other/2620 + * src/mips/n32.s: Delete + * src/mips/o32.s: Delete + +2002-03-21 Loren J. Rittle + + * configure.in: Enable alpha*-*-freebsd*. + * configure: Rebuilt. + +2002-03-17 Bryce McKinlay + + * Makefile.am: libfficonvenience -> libffi_convenience. + * Makefile.in: Rebuilt. + + * Makefile.am: Define ffitest_OBJECTS. + * Makefile.in: Rebuilt. + +2002-03-07 Andreas Tobler + David Edelsohn + + * Makefile.am (EXTRA_DIST): Add Darwin and AIX closure files. + (TARGET_SRC_POWERPC_AIX): Add aix_closure.S. + (TARGET_SRC_POWERPC_DARWIN): Add darwin_closure.S. + * Makefile.in: Regenerate. + * include/ffi.h.in: Add AIX and Darwin closure definitions. + * src/powerpc/ffi_darwin.c (ffi_prep_closure): New function. + (flush_icache, flush_range): New functions. + (ffi_closure_helper_DARWIN): New function. + * src/powerpc/aix_closure.S: New file. + * src/powerpc/darwin_closure.S: New file. + +2002-02-24 Jeff Sturm + + * include/ffi.h.in: Add typedef for ffi_arg. + * src/ffitest.c (main): Declare rint with ffi_arg. + +2002-02-21 Andreas Tobler + + * src/powerpc/ffi_darwin.c (ffi_prep_args): Skip appropriate + number of GPRs for floating-point arguments. + +2002-01-31 Anthony Green + + * configure: Rebuilt. + * configure.in: Replace CHECK_SIZEOF and endian tests with + cross-compiler friendly macros. + * aclocal.m4 (AC_COMPILE_CHECK_SIZEOF, AC_C_BIGENDIAN_CROSS): New + macros. + +2002-01-18 David Edelsohn + + * src/powerpc/darwin.S (_ffi_call_AIX): New. + * src/powerpc/aix.S (ffi_call_DARWIN): New. + +2002-01-17 David Edelsohn + + * Makefile.am (EXTRA_DIST): Add Darwin and AIX files. + (TARGET_SRC_POWERPC_AIX): New. + (POWERPC_AIX): New stanza. + * Makefile.in: Regenerate. + * configure.in: Add AIX case. + * configure: Regenerate. + * include/ffi.h.in (ffi_abi): Add FFI_AIX. + * src/powerpc/ffi_darwin.c (ffi_status): Use "long" to scale frame + size. Fix "long double" support. + (ffi_call): Add FFI_AIX case. + * src/powerpc/aix.S: New. + +2001-10-09 John Hornkvist + + Implement Darwin PowerPC ABI. + * configure.in: Handle powerpc-*-darwin*. + * Makefile.am: Set source files for POWERPC_DARWIN. + * configure: Rebuilt. + * Makefile.in: Rebuilt. + * include/ffi.h.in: Define FFI_DARWIN and FFI_DEFAULT_ABI for + POWERPC_DARWIN. + * src/powerpc/darwin.S: New file. + * src/powerpc/ffi_darwin.c: New file. + +2001-10-07 Joseph S. Myers + + * src/x86/ffi.c: Fix spelling error of "separate" as "seperate". + +2001-07-16 Rainer Orth + + * src/x86/sysv.S: Avoid gas-only .balign directive. + Use C style comments. + +2001-07-16 Rainer Orth + + * src/alpha/ffi.c (ffi_prep_closure): Avoid gas-only mnemonic. + Fixes PR bootstrap/3563. + +2001-06-26 Rainer Orth + + * src/alpha/osf.S (ffi_closure_osf): Use .rdata for ECOFF. + +2001-06-25 Rainer Orth + + * configure.in: Recognize sparc*-sun-* host. + * configure: Regenerate. + +2001-06-06 Andrew Haley + + * src/alpha/osf.S (__FRAME_BEGIN__): Conditionalize for ELF. + +2001-06-03 Andrew Haley + + * src/alpha/osf.S: Add unwind info. + * src/powerpc/sysv.S: Add unwind info. + * src/powerpc/ppc_closure.S: Likewise. + +2000-05-31 Jeff Sturm + + * configure.in: Fix AC_ARG_ENABLE usage. + * configure: Rebuilt. + +2001-05-06 Bryce McKinlay + + * configure.in: Remove warning about beta code. + * configure: Rebuilt. + +2001-04-25 Hans Boehm + + * src/ia64/unix.S: Restore stack pointer when returning from + ffi_closure_UNIX. + * src/ia64/ffi.c: Fix typo in comment. + +2001-04-18 Jim Wilson + + * src/ia64/unix.S: Delete unnecessary increment and decrement of loc2 + to eliminate RAW DV. + +2001-04-12 Bryce McKinlay + + * Makefile.am: Make a libtool convenience library. + * Makefile.in: Rebuilt. + +2001-03-29 Bryce McKinlay + + * configure.in: Use different syntax for subdirectory creation. + * configure: Rebuilt. + +2001-03-27 Jon Beniston + + * configure.in: Added X86_WIN32 target (Win32, CygWin, MingW). + * configure: Rebuilt. + * Makefile.am: Added X86_WIN32 target support. + * Makefile.in: Rebuilt. + + * include/ffi.h.in: Added X86_WIN32 target support. + + * src/ffitest.c: Doesn't run structure tests for X86_WIN32 targets. + * src/types.c: Added X86_WIN32 target support. + + * src/x86/win32.S: New file. Based on sysv.S, but with EH + stuff removed and made to work with CygWin's gas. + +2001-03-26 Bryce McKinlay + + * configure.in: Make target subdirectory in build dir. + * Makefile.am: Override suffix based rules to specify correct output + subdirectory. + * Makefile.in: Rebuilt. + * configure: Rebuilt. + +2001-03-23 Kevin B Hendricks + + * src/powerpc/ppc_closure.S: New file. + * src/powerpc/ffi.c (ffi_prep_args): Fixed ABI compatibility bug + involving long long and register pairs. + (ffi_prep_closure): New function. + (flush_icache): Likewise. + (ffi_closure_helper_SYSV): Likewise. + * include/ffi.h.in (FFI_CLOSURES): Define on PPC. + (FFI_TRAMPOLINE_SIZE): Likewise. + (FFI_NATIVE_RAW_API): Likewise. + * Makefile.in: Rebuilt. + * Makefile.am (EXTRA_DIST): Added src/powerpc/ppc_closure.S. + (TARGET_SRC_POWERPC): Likewise. + +2001-03-19 Tom Tromey + + * Makefile.in: Rebuilt. + * Makefile.am (ffitest_LDFLAGS): New macro. + +2001-03-02 Nick Clifton + + * include/ffi.h.in: Remove RCS ident string. + * include/ffi_mips.h: Remove RCS ident string. + * src/debug.c: Remove RCS ident string. + * src/ffitest.c: Remove RCS ident string. + * src/prep_cif.c: Remove RCS ident string. + * src/types.c: Remove RCS ident string. + * src/alpha/ffi.c: Remove RCS ident string. + * src/alpha/osf.S: Remove RCS ident string. + * src/arm/ffi.c: Remove RCS ident string. + * src/arm/sysv.S: Remove RCS ident string. + * src/mips/ffi.c: Remove RCS ident string. + * src/mips/n32.S: Remove RCS ident string. + * src/mips/o32.S: Remove RCS ident string. + * src/sparc/ffi.c: Remove RCS ident string. + * src/sparc/v8.S: Remove RCS ident string. + * src/sparc/v9.S: Remove RCS ident string. + * src/x86/ffi.c: Remove RCS ident string. + * src/x86/sysv.S: Remove RCS ident string. + +2001-02-08 Joseph S. Myers + + * include/ffi.h.in: Change sourceware.cygnus.com references to + gcc.gnu.org. + +2000-12-09 Richard Henderson + + * src/alpha/ffi.c (ffi_call): Simplify struct return test. + (ffi_closure_osf_inner): Index rather than increment avalue + and arg_types. Give ffi_closure_osf the raw return value type. + * src/alpha/osf.S (ffi_closure_osf): Handle return value type + promotion. + +2000-12-07 Richard Henderson + + * src/raw_api.c (ffi_translate_args): Fix typo. + (ffi_prep_closure): Likewise. + + * include/ffi.h.in [ALPHA]: Define FFI_CLOSURES and + FFI_TRAMPOLINE_SIZE. + * src/alpha/ffi.c (ffi_prep_cif_machdep): Adjust minimal + cif->bytes for new ffi_call_osf implementation. + (ffi_prep_args): Absorb into ... + (ffi_call): ... here. Do all stack allocation here and + avoid a callback function. + (ffi_prep_closure, ffi_closure_osf_inner): New. + * src/alpha/osf.S (ffi_call_osf): Reimplement with no callback. + (ffi_closure_osf): New. + +2000-09-10 Alexandre Oliva + + * config.guess, config.sub, install-sh: Removed. + * ltconfig, ltmain.sh, missing, mkinstalldirs: Likewise. + * Makefile.in: Rebuilt. + + * acinclude.m4: Include libtool macros from the top level. + * aclocal.m4, configure: Rebuilt. + +2000-08-22 Alexandre Oliva + + * configure.in [i*86-*-freebsd*] (TARGET, TARGETDIR): Set. + * configure: Rebuilt. + +2000-05-11 Scott Bambrough + + * libffi/src/arm/sysv.S (ffi_call_SYSV): Doubles are not saved to + memory correctly. Use conditional instructions, not branches where + possible. + +2000-05-04 Tom Tromey + + * configure: Rebuilt. + * configure.in: Match `arm*-*-linux-*'. + From Chris Dornan . + +2000-04-28 Jakub Jelinek + + * Makefile.am (SUBDIRS): Define. + (AM_MAKEFLAGS): Likewise. + (Multilib support.): Add section. + * Makefile.in: Rebuilt. + * ltconfig (extra_compiler_flags, extra_compiler_flags_value): + New variables. Set for gcc using -print-multi-lib. Export them + to libtool. + (sparc64-*-linux-gnu*): Use libsuff 64 for search paths. + * ltmain.sh (B|b|V): Don't throw away gcc's -B, -b and -V options + for -shared links. + (extra_compiler_flags_value, extra_compiler_flags): Check these + for extra compiler options which need to be passed down in + compiler_flags. + +2000-04-16 Anthony Green + + * configure: Rebuilt. + * configure.in: Change i*86-pc-linux* to i*86-*-linux*. + +2000-04-14 Jakub Jelinek + + * include/ffi.h.in (SPARC64): Define for 64bit SPARC builds. + Set SPARC FFI_DEFAULT_ABI based on SPARC64 define. + * src/sparc/ffi.c (ffi_prep_args_v8): Renamed from ffi_prep_args. + Replace all void * sizeofs with sizeof(int). + Only compare type with FFI_TYPE_LONGDOUBLE if LONGDOUBLE is + different than DOUBLE. + Remove FFI_TYPE_SINT32 and FFI_TYPE_UINT32 cases (handled elsewhere). + (ffi_prep_args_v9): New function. + (ffi_prep_cif_machdep): Handle V9 ABI and long long on V8. + (ffi_V9_return_struct): New function. + (ffi_call): Handle FFI_V9 ABI from 64bit code and FFI_V8 ABI from + 32bit code (not yet cross-arch calls). + * src/sparc/v8.S: Add struct return delay nop. + Handle long long. + * src/sparc/v9.S: New file. + * src/prep_cif.c (ffi_prep_cif): Return structure pointer + is used on sparc64 only for structures larger than 32 bytes. + Pass by reference for structures is done for structure arguments + larger than 16 bytes. + * src/ffitest.c (main): Use 64bit rint on sparc64. + Run long long tests on sparc. + * src/types.c (FFI_TYPE_POINTER): Pointer is 64bit on alpha and + sparc64. + (FFI_TYPE_LONGDOUBLE): long double is 128 bit aligned to 128 bits + on sparc64. + * configure.in (sparc-*-linux*): New supported target. + (sparc64-*-linux*): Likewise. + * configure: Rebuilt. + * Makefile.am: Add v9.S to SPARC files. + * Makefile.in: Likewise. + (LINK): Surround $(CCLD) into double quotes, so that multilib + compiles work correctly. + +2000-04-04 Alexandre Petit-Bianco + + * configure: Rebuilt. + * configure.in: (i*86-*-solaris*): New libffi target. Patch + proposed by Bryce McKinlay. + +2000-03-20 Tom Tromey + + * Makefile.in: Hand edit for java_raw_api.lo. + +2000-03-08 Bryce McKinlay + + * config.guess, config.sub: Update from the gcc tree. + Fix for PR libgcj/168. + +2000-03-03 Tom Tromey + + * Makefile.in: Fixed ia64 by hand. + + * configure: Rebuilt. + * configure.in (--enable-multilib): New option. + (libffi_basedir): New subst. + (AC_OUTPUT): Added multilib code. + +2000-03-02 Tom Tromey + + * Makefile.in: Rebuilt. + * Makefile.am (TARGET_SRC_IA64): Use `ia64', not `alpha', as + directory name. + +2000-02-25 Hans Boehm + + * src/ia64/ffi.c, src/ia64/ia64_flags.h, src/ia64/unix.S: New + files. + * src/raw_api.c (ffi_translate_args): Fixed typo in argument + list. + (ffi_prep_raw_closure): Use ffi_translate_args, not + ffi_closure_translate. + * src/java_raw_api.c: New file. + * src/ffitest.c (closure_test_fn): New function. + (main): Define `rint' as long long on IA64. Added new test when + FFI_CLOSURES is defined. + * include/ffi.h.in (ALIGN): Use size_t, not unsigned. + (ffi_abi): Recognize IA64. + (ffi_raw): Added `flt' field. + Added "Java raw API" code. + * configure.in: Recognize ia64. + * Makefile.am (TARGET_SRC_IA64): New macro. + (libffi_la_common_SOURCES): Added java_raw_api.c. + (libffi_la_SOURCES): Define in IA64 case. + +2000-01-04 Tom Tromey + + * Makefile.in: Rebuilt with newer automake. + +1999-12-31 Tom Tromey + + * Makefile.am (INCLUDES): Added -I$(top_srcdir)/src. + +1999-09-01 Tom Tromey + + * include/ffi.h.in: Removed PACKAGE and VERSION defines and + undefs. + * fficonfig.h.in: Rebuilt. + * configure: Rebuilt. + * configure.in: Pass 3rd argument to AM_INIT_AUTOMAKE. + Use AM_PROG_LIBTOOL (automake 1.4 compatibility). + * acconfig.h: Don't #undef PACKAGE or VERSION. + +1999-08-09 Anthony Green + + * include/ffi.h.in: Try to work around messy header problem + with PACKAGE and VERSION. + + * configure: Rebuilt. + * configure.in: Change version to 2.00-beta. + + * fficonfig.h.in: Rebuilt. + * acconfig.h (FFI_NO_STRUCTS, FFI_NO_RAW_API): Define. + + * src/x86/ffi.c (ffi_raw_call): Rename. + +1999-08-02 Kresten Krab Thorup + + * src/x86/ffi.c (ffi_closure_SYSV): New function. + (ffi_prep_incoming_args_SYSV): Ditto. + (ffi_prep_closure): Ditto. + (ffi_closure_raw_SYSV): Ditto. + (ffi_prep_raw_closure): More ditto. + (ffi_call_raw): Final ditto. + + * include/ffi.h.in: Add definitions for closure and raw API. + + * src/x86/ffi.c (ffi_prep_cif_machdep): Added case for + FFI_TYPE_UINT64. + + * Makefile.am (libffi_la_common_SOURCES): Added raw_api.c + + * src/raw_api.c: New file. + + * include/ffi.h.in (ffi_raw): New type. + (UINT_ARG, SINT_ARG): New defines. + (ffi_closure, ffi_raw_closure): New types. + (ffi_prep_closure, ffi_prep_raw_closure): New declarations. + + * configure.in: Add check for endianness and sizeof void*. + + * src/x86/sysv.S (ffi_call_SYSV): Call fixup routine via argument, + instead of directly. + + * configure: Rebuilt. + +Thu Jul 8 14:28:42 1999 Anthony Green + + * configure.in: Add x86 and powerpc BeOS configurations. + From Makoto Kato . + +1999-05-09 Anthony Green + + * configure.in: Add warning about this being beta code. + Remove src/Makefile.am from the picture. + * configure: Rebuilt. + + * Makefile.am: Move logic from src/Makefile.am. Add changes + to support libffi as a target library. + * Makefile.in: Rebuilt. + + * aclocal.m4, config.guess, config.sub, ltconfig, ltmain.sh: + Upgraded to new autoconf, automake, libtool. + + * README: Tweaks. + + * LICENSE: Update copyright date. + + * src/Makefile.am, src/Makefile.in: Removed. + +1998-11-29 Anthony Green + + * include/ChangeLog: Removed. + * src/ChangeLog: Removed. + * src/mips/ChangeLog: Removed. + * src/sparc/ChangeLog: Remboved. + * src/x86/ChangeLog: Removed. + + * ChangeLog.v1: Created. diff --git a/Modules/_ctypes/libffi/ChangeLog.v1 b/Modules/_ctypes/libffi/ChangeLog.v1 index 369820cbdb02..af3a37756868 100644 --- a/Modules/_ctypes/libffi/ChangeLog.v1 +++ b/Modules/_ctypes/libffi/ChangeLog.v1 @@ -2,7 +2,7 @@ The libffi version 1 ChangeLog archive. Version 1 of libffi had per-directory ChangeLogs. Current and future versions have a single ChangeLog file in the root directory. The -version 1 ChangeLogs have all been concatonated into this file for +version 1 ChangeLogs have all been concatenated into this file for future reference only. --- libffi ---------------------------------------------------------------- diff --git a/Modules/_ctypes/libffi/LICENSE b/Modules/_ctypes/libffi/LICENSE index aa60342dfcc1..a66fab4f25a0 100644 --- a/Modules/_ctypes/libffi/LICENSE +++ b/Modules/_ctypes/libffi/LICENSE @@ -1,4 +1,4 @@ -libffi - Copyright (c) 1996-2012 Anthony Green, Red Hat, Inc and others. +libffi - Copyright (c) 1996-2014 Anthony Green, Red Hat, Inc and others. See source files for details. Permission is hereby granted, free of charge, to any person obtaining diff --git a/Modules/_ctypes/libffi/Makefile.am b/Modules/_ctypes/libffi/Makefile.am index bf0156fc170a..1dcdc8110e69 100644 --- a/Modules/_ctypes/libffi/Makefile.am +++ b/Modules/_ctypes/libffi/Makefile.am @@ -6,10 +6,11 @@ ACLOCAL_AMFLAGS = -I m4 SUBDIRS = include testsuite man -EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host \ +EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj \ src/aarch64/ffi.c src/aarch64/ffitarget.h src/aarch64/sysv.S \ - build-ios.sh src/alpha/ffi.c src/alpha/osf.S \ - src/alpha/ffitarget.h src/arm/ffi.c src/arm/sysv.S \ + src/alpha/ffi.c src/alpha/osf.S \ + src/alpha/ffitarget.h src/arc/ffi.c src/arc/arcompact.S \ + src/arc/ffitarget.h src/arm/ffi.c src/arm/sysv.S \ src/arm/ffitarget.h src/avr32/ffi.c src/avr32/sysv.S \ src/avr32/ffitarget.h src/cris/ffi.c src/cris/sysv.S \ src/cris/ffitarget.h src/ia64/ffi.c src/ia64/ffitarget.h \ @@ -19,8 +20,12 @@ EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host \ src/moxie/ffitarget.h src/moxie/eabi.S src/mips/ffitarget.h \ src/m32r/ffi.c src/m32r/sysv.S src/m32r/ffitarget.h \ src/m68k/ffi.c src/m68k/sysv.S src/m68k/ffitarget.h \ + src/m88k/ffi.c src/m88k/obsd.S src/m88k/ffitarget.h \ src/microblaze/ffi.c src/microblaze/sysv.S \ - src/microblaze/ffitarget.h src/powerpc/ffi.c \ + src/microblaze/ffitarget.h \ + src/nios2/ffi.c src/nios2/ffitarget.h src/nios2/sysv.S \ + src/powerpc/ffi.c src/powerpc/ffi_powerpc.h \ + src/powerpc/ffi_sysv.c src/powerpc/ffi_linux64.c \ src/powerpc/sysv.S src/powerpc/linux64.S \ src/powerpc/linux64_closure.S src/powerpc/ppc_closure.S \ src/powerpc/asm.h src/powerpc/aix.S src/powerpc/darwin.S \ @@ -38,14 +43,14 @@ EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host \ src/bfin/ffitarget.h src/bfin/sysv.S src/frv/eabi.S \ src/frv/ffitarget.h src/dlmalloc.c src/tile/ffi.c \ src/tile/ffitarget.h src/tile/tile.S libtool-version \ + src/vax/ffi.c src/vax/ffitarget.h src/vax/elfbsd.S \ src/xtensa/ffitarget.h src/xtensa/ffi.c src/xtensa/sysv.S \ ChangeLog.libffi m4/libtool.m4 m4/lt~obsolete.m4 \ m4/ltoptions.m4 m4/ltsugar.m4 m4/ltversion.m4 \ m4/ltversion.m4 src/arm/gentramp.sh src/debug.c msvcc.sh \ - generate-ios-source-and-headers.py \ - generate-osx-source-and-headers.py \ + generate-darwin-source-and-headers.py \ libffi.xcodeproj/project.pbxproj src/arm/trampoline.S \ - libtool-ldflags + libtool-ldflags ChangeLog.libffi-3.1 info_TEXINFOS = doc/libffi.texi @@ -59,39 +64,39 @@ info_TEXINFOS = doc/libffi.texi # values defined in terms of make variables, as is the case for CC and # friends when we are called from the top level Makefile. AM_MAKEFLAGS = \ - "AR_FLAGS=$(AR_FLAGS)" \ - "CC_FOR_BUILD=$(CC_FOR_BUILD)" \ - "CFLAGS=$(CFLAGS)" \ - "CXXFLAGS=$(CXXFLAGS)" \ - "CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \ - "CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \ - "INSTALL=$(INSTALL)" \ - "INSTALL_DATA=$(INSTALL_DATA)" \ - "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \ - "INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \ - "JC1FLAGS=$(JC1FLAGS)" \ - "LDFLAGS=$(LDFLAGS)" \ - "LIBCFLAGS=$(LIBCFLAGS)" \ - "LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \ - "MAKE=$(MAKE)" \ - "MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \ - "PICFLAG=$(PICFLAG)" \ - "PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" \ - "RUNTESTFLAGS=$(RUNTESTFLAGS)" \ - "SHELL=$(SHELL)" \ - "exec_prefix=$(exec_prefix)" \ - "infodir=$(infodir)" \ - "libdir=$(libdir)" \ - "mandir=$(mandir)" \ - "prefix=$(prefix)" \ - "AR=$(AR)" \ - "AS=$(AS)" \ - "CC=$(CC)" \ - "CXX=$(CXX)" \ - "LD=$(LD)" \ - "NM=$(NM)" \ - "RANLIB=$(RANLIB)" \ - "DESTDIR=$(DESTDIR)" + 'AR_FLAGS=$(AR_FLAGS)' \ + 'CC_FOR_BUILD=$(CC_FOR_BUILD)' \ + 'CFLAGS=$(CFLAGS)' \ + 'CXXFLAGS=$(CXXFLAGS)' \ + 'CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)' \ + 'CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)' \ + 'INSTALL=$(INSTALL)' \ + 'INSTALL_DATA=$(INSTALL_DATA)' \ + 'INSTALL_PROGRAM=$(INSTALL_PROGRAM)' \ + 'INSTALL_SCRIPT=$(INSTALL_SCRIPT)' \ + 'JC1FLAGS=$(JC1FLAGS)' \ + 'LDFLAGS=$(LDFLAGS)' \ + 'LIBCFLAGS=$(LIBCFLAGS)' \ + 'LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)' \ + 'MAKE=$(MAKE)' \ + 'MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)' \ + 'PICFLAG=$(PICFLAG)' \ + 'PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)' \ + 'RUNTESTFLAGS=$(RUNTESTFLAGS)' \ + 'SHELL=$(SHELL)' \ + 'exec_prefix=$(exec_prefix)' \ + 'infodir=$(infodir)' \ + 'libdir=$(libdir)' \ + 'mandir=$(mandir)' \ + 'prefix=$(prefix)' \ + 'AR=$(AR)' \ + 'AS=$(AS)' \ + 'CC=$(CC)' \ + 'CXX=$(CXX)' \ + 'LD=$(LD)' \ + 'NM=$(NM)' \ + 'RANLIB=$(RANLIB)' \ + 'DESTDIR=$(DESTDIR)' # Subdir rules rely on $(FLAGS_TO_PASS) FLAGS_TO_PASS = $(AM_MAKEFLAGS) @@ -120,10 +125,10 @@ if BFIN nodist_libffi_la_SOURCES += src/bfin/ffi.c src/bfin/sysv.S endif if X86 -nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/sysv.S +nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/sysv.S src/x86/win32.S endif if X86_FREEBSD -nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/freebsd.S +nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/freebsd.S src/x86/win32.S endif if X86_WIN32 nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/win32.S @@ -133,6 +138,9 @@ nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/win64.S endif if X86_DARWIN nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/darwin.S src/x86/ffi64.c src/x86/darwin64.S +if X86_DARWIN32 +nodist_libffi_la_SOURCES += src/x86/win32.S +endif endif if SPARC nodist_libffi_la_SOURCES += src/sparc/ffi.c src/sparc/v8.S src/sparc/v9.S @@ -149,14 +157,20 @@ endif if M68K nodist_libffi_la_SOURCES += src/m68k/ffi.c src/m68k/sysv.S endif +if M88K +nodist_libffi_la_SOURCES += src/m88k/ffi.c src/m88k/obsd.S +endif if MOXIE nodist_libffi_la_SOURCES += src/moxie/ffi.c src/moxie/eabi.S endif if MICROBLAZE nodist_libffi_la_SOURCES += src/microblaze/ffi.c src/microblaze/sysv.S endif +if NIOS2 +nodist_libffi_la_SOURCES += src/nios2/sysv.S src/nios2/ffi.c +endif if POWERPC -nodist_libffi_la_SOURCES += src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S src/powerpc/linux64.S src/powerpc/linux64_closure.S +nodist_libffi_la_SOURCES += src/powerpc/ffi.c src/powerpc/ffi_sysv.c src/powerpc/ffi_linux64.c src/powerpc/sysv.S src/powerpc/ppc_closure.S src/powerpc/linux64.S src/powerpc/linux64_closure.S endif if POWERPC_AIX nodist_libffi_la_SOURCES += src/powerpc/ffi_darwin.c src/powerpc/aix.S src/powerpc/aix_closure.S @@ -165,11 +179,14 @@ if POWERPC_DARWIN nodist_libffi_la_SOURCES += src/powerpc/ffi_darwin.c src/powerpc/darwin.S src/powerpc/darwin_closure.S endif if POWERPC_FREEBSD -nodist_libffi_la_SOURCES += src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S +nodist_libffi_la_SOURCES += src/powerpc/ffi.c src/powerpc/ffi_sysv.c src/powerpc/sysv.S src/powerpc/ppc_closure.S endif if AARCH64 nodist_libffi_la_SOURCES += src/aarch64/sysv.S src/aarch64/ffi.c endif +if ARC +nodist_libffi_la_SOURCES += src/arc/arcompact.S src/arc/ffi.c +endif if ARM nodist_libffi_la_SOURCES += src/arm/sysv.S src/arm/ffi.c if FFI_EXEC_TRAMPOLINE_TABLE @@ -212,14 +229,26 @@ endif if METAG nodist_libffi_la_SOURCES += src/metag/sysv.S src/metag/ffi.c endif +if VAX +nodist_libffi_la_SOURCES += src/vax/elfbsd.S src/vax/ffi.c +endif libffi_convenience_la_SOURCES = $(libffi_la_SOURCES) nodist_libffi_convenience_la_SOURCES = $(nodist_libffi_la_SOURCES) LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/libtool-ldflags $(LDFLAGS)) +AM_CFLAGS = +if FFI_DEBUG +# Build debug. Define FFI_DEBUG on the commandline so that, when building with +# MSVC, it can link against the debug CRT. +AM_CFLAGS += -DFFI_DEBUG +endif + libffi_la_LDFLAGS = -no-undefined -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(LTLDFLAGS) $(AM_LTLDFLAGS) AM_CPPFLAGS = -I. -I$(top_srcdir)/include -Iinclude -I$(top_srcdir)/src AM_CCASFLAGS = $(AM_CPPFLAGS) +dist-hook: + if [ -d $(top_srcdir)/.git ] ; then (cd $(top_srcdir); git log --no-decorate) ; else echo 'See git log for history.' ; fi > $(distdir)/ChangeLog diff --git a/Modules/_ctypes/libffi/Makefile.in b/Modules/_ctypes/libffi/Makefile.in index 4b6abe5d901c..4a57abd3c11d 100644 --- a/Modules/_ctypes/libffi/Makefile.in +++ b/Modules/_ctypes/libffi/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.12.2 from Makefile.am. +# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2012 Free Software Foundation, Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -16,23 +16,51 @@ VPATH = @srcdir@ -am__make_dryrun = \ - { \ - am__dry=no; \ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ - echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ - | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ - *) \ - for am__flg in $$MAKEFLAGS; do \ - case $$am__flg in \ - *=*|--*) ;; \ - *n*) am__dry=yes; break;; \ - esac; \ - done;; \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ - test $$am__dry = yes; \ - } + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -55,44 +83,52 @@ target_triplet = @target@ @FFI_DEBUG_TRUE@am__append_1 = src/debug.c @MIPS_TRUE@am__append_2 = src/mips/ffi.c src/mips/o32.S src/mips/n32.S @BFIN_TRUE@am__append_3 = src/bfin/ffi.c src/bfin/sysv.S -@X86_TRUE@am__append_4 = src/x86/ffi.c src/x86/sysv.S -@X86_FREEBSD_TRUE@am__append_5 = src/x86/ffi.c src/x86/freebsd.S +@X86_TRUE@am__append_4 = src/x86/ffi.c src/x86/sysv.S src/x86/win32.S +@X86_FREEBSD_TRUE@am__append_5 = src/x86/ffi.c src/x86/freebsd.S src/x86/win32.S @X86_WIN32_TRUE@am__append_6 = src/x86/ffi.c src/x86/win32.S @X86_WIN64_TRUE@am__append_7 = src/x86/ffi.c src/x86/win64.S @X86_DARWIN_TRUE@am__append_8 = src/x86/ffi.c src/x86/darwin.S src/x86/ffi64.c src/x86/darwin64.S -@SPARC_TRUE@am__append_9 = src/sparc/ffi.c src/sparc/v8.S src/sparc/v9.S -@ALPHA_TRUE@am__append_10 = src/alpha/ffi.c src/alpha/osf.S -@IA64_TRUE@am__append_11 = src/ia64/ffi.c src/ia64/unix.S -@M32R_TRUE@am__append_12 = src/m32r/sysv.S src/m32r/ffi.c -@M68K_TRUE@am__append_13 = src/m68k/ffi.c src/m68k/sysv.S -@MOXIE_TRUE@am__append_14 = src/moxie/ffi.c src/moxie/eabi.S -@MICROBLAZE_TRUE@am__append_15 = src/microblaze/ffi.c src/microblaze/sysv.S -@POWERPC_TRUE@am__append_16 = src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S src/powerpc/linux64.S src/powerpc/linux64_closure.S -@POWERPC_AIX_TRUE@am__append_17 = src/powerpc/ffi_darwin.c src/powerpc/aix.S src/powerpc/aix_closure.S -@POWERPC_DARWIN_TRUE@am__append_18 = src/powerpc/ffi_darwin.c src/powerpc/darwin.S src/powerpc/darwin_closure.S -@POWERPC_FREEBSD_TRUE@am__append_19 = src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S -@AARCH64_TRUE@am__append_20 = src/aarch64/sysv.S src/aarch64/ffi.c -@ARM_TRUE@am__append_21 = src/arm/sysv.S src/arm/ffi.c -@ARM_TRUE@@FFI_EXEC_TRAMPOLINE_TABLE_TRUE@am__append_22 = src/arm/trampoline.S -@AVR32_TRUE@am__append_23 = src/avr32/sysv.S src/avr32/ffi.c -@LIBFFI_CRIS_TRUE@am__append_24 = src/cris/sysv.S src/cris/ffi.c -@FRV_TRUE@am__append_25 = src/frv/eabi.S src/frv/ffi.c -@S390_TRUE@am__append_26 = src/s390/sysv.S src/s390/ffi.c -@X86_64_TRUE@am__append_27 = src/x86/ffi64.c src/x86/unix64.S src/x86/ffi.c src/x86/sysv.S -@SH_TRUE@am__append_28 = src/sh/sysv.S src/sh/ffi.c -@SH64_TRUE@am__append_29 = src/sh64/sysv.S src/sh64/ffi.c -@PA_LINUX_TRUE@am__append_30 = src/pa/linux.S src/pa/ffi.c -@PA_HPUX_TRUE@am__append_31 = src/pa/hpux32.S src/pa/ffi.c -@TILE_TRUE@am__append_32 = src/tile/tile.S src/tile/ffi.c -@XTENSA_TRUE@am__append_33 = src/xtensa/sysv.S src/xtensa/ffi.c -@METAG_TRUE@am__append_34 = src/metag/sysv.S src/metag/ffi.c +@X86_DARWIN32_TRUE@@X86_DARWIN_TRUE@am__append_9 = src/x86/win32.S +@SPARC_TRUE@am__append_10 = src/sparc/ffi.c src/sparc/v8.S src/sparc/v9.S +@ALPHA_TRUE@am__append_11 = src/alpha/ffi.c src/alpha/osf.S +@IA64_TRUE@am__append_12 = src/ia64/ffi.c src/ia64/unix.S +@M32R_TRUE@am__append_13 = src/m32r/sysv.S src/m32r/ffi.c +@M68K_TRUE@am__append_14 = src/m68k/ffi.c src/m68k/sysv.S +@M88K_TRUE@am__append_15 = src/m88k/ffi.c src/m88k/obsd.S +@MOXIE_TRUE@am__append_16 = src/moxie/ffi.c src/moxie/eabi.S +@MICROBLAZE_TRUE@am__append_17 = src/microblaze/ffi.c src/microblaze/sysv.S +@NIOS2_TRUE@am__append_18 = src/nios2/sysv.S src/nios2/ffi.c +@POWERPC_TRUE@am__append_19 = src/powerpc/ffi.c src/powerpc/ffi_sysv.c src/powerpc/ffi_linux64.c src/powerpc/sysv.S src/powerpc/ppc_closure.S src/powerpc/linux64.S src/powerpc/linux64_closure.S +@POWERPC_AIX_TRUE@am__append_20 = src/powerpc/ffi_darwin.c src/powerpc/aix.S src/powerpc/aix_closure.S +@POWERPC_DARWIN_TRUE@am__append_21 = src/powerpc/ffi_darwin.c src/powerpc/darwin.S src/powerpc/darwin_closure.S +@POWERPC_FREEBSD_TRUE@am__append_22 = src/powerpc/ffi.c src/powerpc/ffi_sysv.c src/powerpc/sysv.S src/powerpc/ppc_closure.S +@AARCH64_TRUE@am__append_23 = src/aarch64/sysv.S src/aarch64/ffi.c +@ARC_TRUE@am__append_24 = src/arc/arcompact.S src/arc/ffi.c +@ARM_TRUE@am__append_25 = src/arm/sysv.S src/arm/ffi.c +@ARM_TRUE@@FFI_EXEC_TRAMPOLINE_TABLE_TRUE@am__append_26 = src/arm/trampoline.S +@AVR32_TRUE@am__append_27 = src/avr32/sysv.S src/avr32/ffi.c +@LIBFFI_CRIS_TRUE@am__append_28 = src/cris/sysv.S src/cris/ffi.c +@FRV_TRUE@am__append_29 = src/frv/eabi.S src/frv/ffi.c +@S390_TRUE@am__append_30 = src/s390/sysv.S src/s390/ffi.c +@X86_64_TRUE@am__append_31 = src/x86/ffi64.c src/x86/unix64.S src/x86/ffi.c src/x86/sysv.S +@SH_TRUE@am__append_32 = src/sh/sysv.S src/sh/ffi.c +@SH64_TRUE@am__append_33 = src/sh64/sysv.S src/sh64/ffi.c +@PA_LINUX_TRUE@am__append_34 = src/pa/linux.S src/pa/ffi.c +@PA_HPUX_TRUE@am__append_35 = src/pa/hpux32.S src/pa/ffi.c +@TILE_TRUE@am__append_36 = src/tile/tile.S src/tile/ffi.c +@XTENSA_TRUE@am__append_37 = src/xtensa/sysv.S src/xtensa/ffi.c +@METAG_TRUE@am__append_38 = src/metag/sysv.S src/metag/ffi.c +@VAX_TRUE@am__append_39 = src/vax/elfbsd.S src/vax/ffi.c +# Build debug. Define FFI_DEBUG on the commandline so that, when building with +# MSVC, it can link against the debug CRT. +@FFI_DEBUG_TRUE@am__append_40 = -DFFI_DEBUG subdir = . -DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ - $(srcdir)/Makefile.in $(srcdir)/doc/stamp-vti \ - $(srcdir)/doc/version.texi $(srcdir)/fficonfig.h.in \ - $(srcdir)/libffi.pc.in $(top_srcdir)/configure ChangeLog \ - compile config.guess config.sub depcomp install-sh ltmain.sh \ - mdate-sh missing texinfo.tex +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/configure $(am__configure_deps) \ + $(srcdir)/fficonfig.h.in $(srcdir)/libffi.pc.in depcomp \ + mdate-sh $(srcdir)/doc/version.texi $(srcdir)/doc/stamp-vti \ + texinfo.tex README compile config.guess config.sub install-sh \ + missing ltmain.sh ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/asmcfi.m4 \ $(top_srcdir)/m4/ax_append_flag.m4 \ @@ -154,50 +190,60 @@ am_libffi_la_OBJECTS = src/prep_cif.lo src/types.lo src/raw_api.lo \ @MIPS_TRUE@am__objects_2 = src/mips/ffi.lo src/mips/o32.lo \ @MIPS_TRUE@ src/mips/n32.lo @BFIN_TRUE@am__objects_3 = src/bfin/ffi.lo src/bfin/sysv.lo -@X86_TRUE@am__objects_4 = src/x86/ffi.lo src/x86/sysv.lo -@X86_FREEBSD_TRUE@am__objects_5 = src/x86/ffi.lo src/x86/freebsd.lo +@X86_TRUE@am__objects_4 = src/x86/ffi.lo src/x86/sysv.lo \ +@X86_TRUE@ src/x86/win32.lo +@X86_FREEBSD_TRUE@am__objects_5 = src/x86/ffi.lo src/x86/freebsd.lo \ +@X86_FREEBSD_TRUE@ src/x86/win32.lo @X86_WIN32_TRUE@am__objects_6 = src/x86/ffi.lo src/x86/win32.lo @X86_WIN64_TRUE@am__objects_7 = src/x86/ffi.lo src/x86/win64.lo @X86_DARWIN_TRUE@am__objects_8 = src/x86/ffi.lo src/x86/darwin.lo \ @X86_DARWIN_TRUE@ src/x86/ffi64.lo src/x86/darwin64.lo -@SPARC_TRUE@am__objects_9 = src/sparc/ffi.lo src/sparc/v8.lo \ +@X86_DARWIN32_TRUE@@X86_DARWIN_TRUE@am__objects_9 = src/x86/win32.lo +@SPARC_TRUE@am__objects_10 = src/sparc/ffi.lo src/sparc/v8.lo \ @SPARC_TRUE@ src/sparc/v9.lo -@ALPHA_TRUE@am__objects_10 = src/alpha/ffi.lo src/alpha/osf.lo -@IA64_TRUE@am__objects_11 = src/ia64/ffi.lo src/ia64/unix.lo -@M32R_TRUE@am__objects_12 = src/m32r/sysv.lo src/m32r/ffi.lo -@M68K_TRUE@am__objects_13 = src/m68k/ffi.lo src/m68k/sysv.lo -@MOXIE_TRUE@am__objects_14 = src/moxie/ffi.lo src/moxie/eabi.lo -@MICROBLAZE_TRUE@am__objects_15 = src/microblaze/ffi.lo \ +@ALPHA_TRUE@am__objects_11 = src/alpha/ffi.lo src/alpha/osf.lo +@IA64_TRUE@am__objects_12 = src/ia64/ffi.lo src/ia64/unix.lo +@M32R_TRUE@am__objects_13 = src/m32r/sysv.lo src/m32r/ffi.lo +@M68K_TRUE@am__objects_14 = src/m68k/ffi.lo src/m68k/sysv.lo +@M88K_TRUE@am__objects_15 = src/m88k/ffi.lo src/m88k/obsd.lo +@MOXIE_TRUE@am__objects_16 = src/moxie/ffi.lo src/moxie/eabi.lo +@MICROBLAZE_TRUE@am__objects_17 = src/microblaze/ffi.lo \ @MICROBLAZE_TRUE@ src/microblaze/sysv.lo -@POWERPC_TRUE@am__objects_16 = src/powerpc/ffi.lo src/powerpc/sysv.lo \ +@NIOS2_TRUE@am__objects_18 = src/nios2/sysv.lo src/nios2/ffi.lo +@POWERPC_TRUE@am__objects_19 = src/powerpc/ffi.lo \ +@POWERPC_TRUE@ src/powerpc/ffi_sysv.lo \ +@POWERPC_TRUE@ src/powerpc/ffi_linux64.lo src/powerpc/sysv.lo \ @POWERPC_TRUE@ src/powerpc/ppc_closure.lo \ @POWERPC_TRUE@ src/powerpc/linux64.lo \ @POWERPC_TRUE@ src/powerpc/linux64_closure.lo -@POWERPC_AIX_TRUE@am__objects_17 = src/powerpc/ffi_darwin.lo \ +@POWERPC_AIX_TRUE@am__objects_20 = src/powerpc/ffi_darwin.lo \ @POWERPC_AIX_TRUE@ src/powerpc/aix.lo \ @POWERPC_AIX_TRUE@ src/powerpc/aix_closure.lo -@POWERPC_DARWIN_TRUE@am__objects_18 = src/powerpc/ffi_darwin.lo \ +@POWERPC_DARWIN_TRUE@am__objects_21 = src/powerpc/ffi_darwin.lo \ @POWERPC_DARWIN_TRUE@ src/powerpc/darwin.lo \ @POWERPC_DARWIN_TRUE@ src/powerpc/darwin_closure.lo -@POWERPC_FREEBSD_TRUE@am__objects_19 = src/powerpc/ffi.lo \ +@POWERPC_FREEBSD_TRUE@am__objects_22 = src/powerpc/ffi.lo \ +@POWERPC_FREEBSD_TRUE@ src/powerpc/ffi_sysv.lo \ @POWERPC_FREEBSD_TRUE@ src/powerpc/sysv.lo \ @POWERPC_FREEBSD_TRUE@ src/powerpc/ppc_closure.lo -@AARCH64_TRUE@am__objects_20 = src/aarch64/sysv.lo src/aarch64/ffi.lo -@ARM_TRUE@am__objects_21 = src/arm/sysv.lo src/arm/ffi.lo -@ARM_TRUE@@FFI_EXEC_TRAMPOLINE_TABLE_TRUE@am__objects_22 = src/arm/trampoline.lo -@AVR32_TRUE@am__objects_23 = src/avr32/sysv.lo src/avr32/ffi.lo -@LIBFFI_CRIS_TRUE@am__objects_24 = src/cris/sysv.lo src/cris/ffi.lo -@FRV_TRUE@am__objects_25 = src/frv/eabi.lo src/frv/ffi.lo -@S390_TRUE@am__objects_26 = src/s390/sysv.lo src/s390/ffi.lo -@X86_64_TRUE@am__objects_27 = src/x86/ffi64.lo src/x86/unix64.lo \ +@AARCH64_TRUE@am__objects_23 = src/aarch64/sysv.lo src/aarch64/ffi.lo +@ARC_TRUE@am__objects_24 = src/arc/arcompact.lo src/arc/ffi.lo +@ARM_TRUE@am__objects_25 = src/arm/sysv.lo src/arm/ffi.lo +@ARM_TRUE@@FFI_EXEC_TRAMPOLINE_TABLE_TRUE@am__objects_26 = src/arm/trampoline.lo +@AVR32_TRUE@am__objects_27 = src/avr32/sysv.lo src/avr32/ffi.lo +@LIBFFI_CRIS_TRUE@am__objects_28 = src/cris/sysv.lo src/cris/ffi.lo +@FRV_TRUE@am__objects_29 = src/frv/eabi.lo src/frv/ffi.lo +@S390_TRUE@am__objects_30 = src/s390/sysv.lo src/s390/ffi.lo +@X86_64_TRUE@am__objects_31 = src/x86/ffi64.lo src/x86/unix64.lo \ @X86_64_TRUE@ src/x86/ffi.lo src/x86/sysv.lo -@SH_TRUE@am__objects_28 = src/sh/sysv.lo src/sh/ffi.lo -@SH64_TRUE@am__objects_29 = src/sh64/sysv.lo src/sh64/ffi.lo -@PA_LINUX_TRUE@am__objects_30 = src/pa/linux.lo src/pa/ffi.lo -@PA_HPUX_TRUE@am__objects_31 = src/pa/hpux32.lo src/pa/ffi.lo -@TILE_TRUE@am__objects_32 = src/tile/tile.lo src/tile/ffi.lo -@XTENSA_TRUE@am__objects_33 = src/xtensa/sysv.lo src/xtensa/ffi.lo -@METAG_TRUE@am__objects_34 = src/metag/sysv.lo src/metag/ffi.lo +@SH_TRUE@am__objects_32 = src/sh/sysv.lo src/sh/ffi.lo +@SH64_TRUE@am__objects_33 = src/sh64/sysv.lo src/sh64/ffi.lo +@PA_LINUX_TRUE@am__objects_34 = src/pa/linux.lo src/pa/ffi.lo +@PA_HPUX_TRUE@am__objects_35 = src/pa/hpux32.lo src/pa/ffi.lo +@TILE_TRUE@am__objects_36 = src/tile/tile.lo src/tile/ffi.lo +@XTENSA_TRUE@am__objects_37 = src/xtensa/sysv.lo src/xtensa/ffi.lo +@METAG_TRUE@am__objects_38 = src/metag/sysv.lo src/metag/ffi.lo +@VAX_TRUE@am__objects_39 = src/vax/elfbsd.lo src/vax/ffi.lo nodist_libffi_la_OBJECTS = $(am__objects_1) $(am__objects_2) \ $(am__objects_3) $(am__objects_4) $(am__objects_5) \ $(am__objects_6) $(am__objects_7) $(am__objects_8) \ @@ -209,17 +255,23 @@ nodist_libffi_la_OBJECTS = $(am__objects_1) $(am__objects_2) \ $(am__objects_24) $(am__objects_25) $(am__objects_26) \ $(am__objects_27) $(am__objects_28) $(am__objects_29) \ $(am__objects_30) $(am__objects_31) $(am__objects_32) \ - $(am__objects_33) $(am__objects_34) + $(am__objects_33) $(am__objects_34) $(am__objects_35) \ + $(am__objects_36) $(am__objects_37) $(am__objects_38) \ + $(am__objects_39) libffi_la_OBJECTS = $(am_libffi_la_OBJECTS) \ $(nodist_libffi_la_OBJECTS) -libffi_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libffi_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libffi_la_LDFLAGS) $(LDFLAGS) -o $@ libffi_convenience_la_LIBADD = -am__objects_35 = src/prep_cif.lo src/types.lo src/raw_api.lo \ +am__objects_40 = src/prep_cif.lo src/types.lo src/raw_api.lo \ src/java_raw_api.lo src/closures.lo -am_libffi_convenience_la_OBJECTS = $(am__objects_35) -am__objects_36 = $(am__objects_1) $(am__objects_2) $(am__objects_3) \ +am_libffi_convenience_la_OBJECTS = $(am__objects_40) +am__objects_41 = $(am__objects_1) $(am__objects_2) $(am__objects_3) \ $(am__objects_4) $(am__objects_5) $(am__objects_6) \ $(am__objects_7) $(am__objects_8) $(am__objects_9) \ $(am__objects_10) $(am__objects_11) $(am__objects_12) \ @@ -230,32 +282,87 @@ am__objects_36 = $(am__objects_1) $(am__objects_2) $(am__objects_3) \ $(am__objects_25) $(am__objects_26) $(am__objects_27) \ $(am__objects_28) $(am__objects_29) $(am__objects_30) \ $(am__objects_31) $(am__objects_32) $(am__objects_33) \ - $(am__objects_34) -nodist_libffi_convenience_la_OBJECTS = $(am__objects_36) + $(am__objects_34) $(am__objects_35) $(am__objects_36) \ + $(am__objects_37) $(am__objects_38) $(am__objects_39) +nodist_libffi_convenience_la_OBJECTS = $(am__objects_41) libffi_convenience_la_OBJECTS = $(am_libffi_convenience_la_OBJECTS) \ $(nodist_libffi_convenience_la_OBJECTS) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CPPASCOMPILE = $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS) -LTCPPASCOMPILE = $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=compile $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS) +LTCPPASCOMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CCAS) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CCASFLAGS) $(CCASFLAGS) +AM_V_CPPAS = $(am__v_CPPAS_@AM_V@) +am__v_CPPAS_ = $(am__v_CPPAS_@AM_DEFAULT_V@) +am__v_CPPAS_0 = @echo " CPPAS " $@; +am__v_CPPAS_1 = COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = CCLD = $(CC) -LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = SOURCES = $(libffi_la_SOURCES) $(nodist_libffi_la_SOURCES) \ $(libffi_convenience_la_SOURCES) \ $(nodist_libffi_convenience_la_SOURCES) DIST_SOURCES = $(libffi_la_SOURCES) $(libffi_convenience_la_SOURCES) +AM_V_DVIPS = $(am__v_DVIPS_@AM_V@) +am__v_DVIPS_ = $(am__v_DVIPS_@AM_DEFAULT_V@) +am__v_DVIPS_0 = @echo " DVIPS " $@; +am__v_DVIPS_1 = +AM_V_MAKEINFO = $(am__v_MAKEINFO_@AM_V@) +am__v_MAKEINFO_ = $(am__v_MAKEINFO_@AM_DEFAULT_V@) +am__v_MAKEINFO_0 = @echo " MAKEINFO" $@; +am__v_MAKEINFO_1 = +AM_V_INFOHTML = $(am__v_INFOHTML_@AM_V@) +am__v_INFOHTML_ = $(am__v_INFOHTML_@AM_DEFAULT_V@) +am__v_INFOHTML_0 = @echo " INFOHTML" $@; +am__v_INFOHTML_1 = +AM_V_TEXI2DVI = $(am__v_TEXI2DVI_@AM_V@) +am__v_TEXI2DVI_ = $(am__v_TEXI2DVI_@AM_DEFAULT_V@) +am__v_TEXI2DVI_0 = @echo " TEXI2DVI" $@; +am__v_TEXI2DVI_1 = +AM_V_TEXI2PDF = $(am__v_TEXI2PDF_@AM_V@) +am__v_TEXI2PDF_ = $(am__v_TEXI2PDF_@AM_DEFAULT_V@) +am__v_TEXI2PDF_0 = @echo " TEXI2PDF" $@; +am__v_TEXI2PDF_1 = +AM_V_texinfo = $(am__v_texinfo_@AM_V@) +am__v_texinfo_ = $(am__v_texinfo_@AM_DEFAULT_V@) +am__v_texinfo_0 = -q +am__v_texinfo_1 = +AM_V_texidevnull = $(am__v_texidevnull_@AM_V@) +am__v_texidevnull_ = $(am__v_texidevnull_@AM_DEFAULT_V@) +am__v_texidevnull_0 = > /dev/null +am__v_texidevnull_1 = INFO_DEPS = $(srcdir)/doc/libffi.info am__TEXINFO_TEX_DIR = $(srcdir) DVIS = doc/libffi.dvi @@ -268,13 +375,14 @@ TEXI2PDF = $(TEXI2DVI) --pdf --batch MAKEINFOHTML = $(MAKEINFO) --html AM_MAKEINFOHTMLFLAGS = $(AM_MAKEINFOFLAGS) DVIPS = dvips -RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ - html-recursive info-recursive install-data-recursive \ - install-dvi-recursive install-exec-recursive \ - install-html-recursive install-info-recursive \ - install-pdf-recursive install-ps-recursive install-recursive \ - installcheck-recursive installdirs-recursive pdf-recursive \ - ps-recursive uninstall-recursive +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -283,9 +391,30 @@ am__can_run_installinfo = \ DATA = $(pkgconfig_DATA) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive -AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ - $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ cscope distdir dist dist-all distcheck +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ + $(LISP)fficonfig.h.in +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags CSCOPE = cscope @@ -335,6 +464,7 @@ distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LTLDFLAGS = @AM_LTLDFLAGS@ AM_RUNTESTFLAGS = @AM_RUNTESTFLAGS@ AR = @AR@ @@ -350,6 +480,10 @@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ @@ -365,6 +499,7 @@ FFI_EXEC_TRAMPOLINE_TABLE = @FFI_EXEC_TRAMPOLINE_TABLE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_LONG_DOUBLE = @HAVE_LONG_DOUBLE@ +HAVE_LONG_DOUBLE_VARIANT = @HAVE_LONG_DOUBLE_VARIANT@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ @@ -411,6 +546,7 @@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ @@ -468,10 +604,11 @@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = foreign subdir-objects ACLOCAL_AMFLAGS = -I m4 SUBDIRS = include testsuite man -EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host \ +EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj \ src/aarch64/ffi.c src/aarch64/ffitarget.h src/aarch64/sysv.S \ - build-ios.sh src/alpha/ffi.c src/alpha/osf.S \ - src/alpha/ffitarget.h src/arm/ffi.c src/arm/sysv.S \ + src/alpha/ffi.c src/alpha/osf.S \ + src/alpha/ffitarget.h src/arc/ffi.c src/arc/arcompact.S \ + src/arc/ffitarget.h src/arm/ffi.c src/arm/sysv.S \ src/arm/ffitarget.h src/avr32/ffi.c src/avr32/sysv.S \ src/avr32/ffitarget.h src/cris/ffi.c src/cris/sysv.S \ src/cris/ffitarget.h src/ia64/ffi.c src/ia64/ffitarget.h \ @@ -481,8 +618,12 @@ EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host \ src/moxie/ffitarget.h src/moxie/eabi.S src/mips/ffitarget.h \ src/m32r/ffi.c src/m32r/sysv.S src/m32r/ffitarget.h \ src/m68k/ffi.c src/m68k/sysv.S src/m68k/ffitarget.h \ + src/m88k/ffi.c src/m88k/obsd.S src/m88k/ffitarget.h \ src/microblaze/ffi.c src/microblaze/sysv.S \ - src/microblaze/ffitarget.h src/powerpc/ffi.c \ + src/microblaze/ffitarget.h \ + src/nios2/ffi.c src/nios2/ffitarget.h src/nios2/sysv.S \ + src/powerpc/ffi.c src/powerpc/ffi_powerpc.h \ + src/powerpc/ffi_sysv.c src/powerpc/ffi_linux64.c \ src/powerpc/sysv.S src/powerpc/linux64.S \ src/powerpc/linux64_closure.S src/powerpc/ppc_closure.S \ src/powerpc/asm.h src/powerpc/aix.S src/powerpc/darwin.S \ @@ -500,14 +641,14 @@ EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host \ src/bfin/ffitarget.h src/bfin/sysv.S src/frv/eabi.S \ src/frv/ffitarget.h src/dlmalloc.c src/tile/ffi.c \ src/tile/ffitarget.h src/tile/tile.S libtool-version \ + src/vax/ffi.c src/vax/ffitarget.h src/vax/elfbsd.S \ src/xtensa/ffitarget.h src/xtensa/ffi.c src/xtensa/sysv.S \ ChangeLog.libffi m4/libtool.m4 m4/lt~obsolete.m4 \ m4/ltoptions.m4 m4/ltsugar.m4 m4/ltversion.m4 \ m4/ltversion.m4 src/arm/gentramp.sh src/debug.c msvcc.sh \ - generate-ios-source-and-headers.py \ - generate-osx-source-and-headers.py \ + generate-darwin-source-and-headers.py \ libffi.xcodeproj/project.pbxproj src/arm/trampoline.S \ - libtool-ldflags + libtool-ldflags ChangeLog.libffi-3.1 info_TEXINFOS = doc/libffi.texi @@ -515,39 +656,39 @@ info_TEXINFOS = doc/libffi.texi # values defined in terms of make variables, as is the case for CC and # friends when we are called from the top level Makefile. AM_MAKEFLAGS = \ - "AR_FLAGS=$(AR_FLAGS)" \ - "CC_FOR_BUILD=$(CC_FOR_BUILD)" \ - "CFLAGS=$(CFLAGS)" \ - "CXXFLAGS=$(CXXFLAGS)" \ - "CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \ - "CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \ - "INSTALL=$(INSTALL)" \ - "INSTALL_DATA=$(INSTALL_DATA)" \ - "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \ - "INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \ - "JC1FLAGS=$(JC1FLAGS)" \ - "LDFLAGS=$(LDFLAGS)" \ - "LIBCFLAGS=$(LIBCFLAGS)" \ - "LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \ - "MAKE=$(MAKE)" \ - "MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \ - "PICFLAG=$(PICFLAG)" \ - "PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" \ - "RUNTESTFLAGS=$(RUNTESTFLAGS)" \ - "SHELL=$(SHELL)" \ - "exec_prefix=$(exec_prefix)" \ - "infodir=$(infodir)" \ - "libdir=$(libdir)" \ - "mandir=$(mandir)" \ - "prefix=$(prefix)" \ - "AR=$(AR)" \ - "AS=$(AS)" \ - "CC=$(CC)" \ - "CXX=$(CXX)" \ - "LD=$(LD)" \ - "NM=$(NM)" \ - "RANLIB=$(RANLIB)" \ - "DESTDIR=$(DESTDIR)" + 'AR_FLAGS=$(AR_FLAGS)' \ + 'CC_FOR_BUILD=$(CC_FOR_BUILD)' \ + 'CFLAGS=$(CFLAGS)' \ + 'CXXFLAGS=$(CXXFLAGS)' \ + 'CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)' \ + 'CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)' \ + 'INSTALL=$(INSTALL)' \ + 'INSTALL_DATA=$(INSTALL_DATA)' \ + 'INSTALL_PROGRAM=$(INSTALL_PROGRAM)' \ + 'INSTALL_SCRIPT=$(INSTALL_SCRIPT)' \ + 'JC1FLAGS=$(JC1FLAGS)' \ + 'LDFLAGS=$(LDFLAGS)' \ + 'LIBCFLAGS=$(LIBCFLAGS)' \ + 'LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)' \ + 'MAKE=$(MAKE)' \ + 'MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)' \ + 'PICFLAG=$(PICFLAG)' \ + 'PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)' \ + 'RUNTESTFLAGS=$(RUNTESTFLAGS)' \ + 'SHELL=$(SHELL)' \ + 'exec_prefix=$(exec_prefix)' \ + 'infodir=$(infodir)' \ + 'libdir=$(libdir)' \ + 'mandir=$(mandir)' \ + 'prefix=$(prefix)' \ + 'AR=$(AR)' \ + 'AS=$(AS)' \ + 'CC=$(CC)' \ + 'CXX=$(CXX)' \ + 'LD=$(LD)' \ + 'NM=$(NM)' \ + 'RANLIB=$(RANLIB)' \ + 'DESTDIR=$(DESTDIR)' # Subdir rules rely on $(FLAGS_TO_PASS) @@ -571,10 +712,13 @@ nodist_libffi_la_SOURCES = $(am__append_1) $(am__append_2) \ $(am__append_24) $(am__append_25) $(am__append_26) \ $(am__append_27) $(am__append_28) $(am__append_29) \ $(am__append_30) $(am__append_31) $(am__append_32) \ - $(am__append_33) $(am__append_34) + $(am__append_33) $(am__append_34) $(am__append_35) \ + $(am__append_36) $(am__append_37) $(am__append_38) \ + $(am__append_39) libffi_convenience_la_SOURCES = $(libffi_la_SOURCES) nodist_libffi_convenience_la_SOURCES = $(nodist_libffi_la_SOURCES) LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/libtool-ldflags $(LDFLAGS)) +AM_CFLAGS = $(am__append_40) libffi_la_LDFLAGS = -no-undefined -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(LTLDFLAGS) $(AM_LTLDFLAGS) AM_CPPFLAGS = -I. -I$(top_srcdir)/include -Iinclude -I$(top_srcdir)/src AM_CCASFLAGS = $(AM_CPPFLAGS) @@ -645,6 +789,7 @@ clean-noinstLTLIBRARIES: echo rm -f $${locs}; \ rm -f $${locs}; \ } + install-toolexeclibLTLIBRARIES: $(toolexeclib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(toolexeclib_LTLIBRARIES)'; test -n "$(toolexeclibdir)" || list=; \ @@ -723,10 +868,10 @@ src/x86/ffi.lo: src/x86/$(am__dirstamp) \ src/x86/$(DEPDIR)/$(am__dirstamp) src/x86/sysv.lo: src/x86/$(am__dirstamp) \ src/x86/$(DEPDIR)/$(am__dirstamp) -src/x86/freebsd.lo: src/x86/$(am__dirstamp) \ - src/x86/$(DEPDIR)/$(am__dirstamp) src/x86/win32.lo: src/x86/$(am__dirstamp) \ src/x86/$(DEPDIR)/$(am__dirstamp) +src/x86/freebsd.lo: src/x86/$(am__dirstamp) \ + src/x86/$(DEPDIR)/$(am__dirstamp) src/x86/win64.lo: src/x86/$(am__dirstamp) \ src/x86/$(DEPDIR)/$(am__dirstamp) src/x86/darwin.lo: src/x86/$(am__dirstamp) \ @@ -787,6 +932,16 @@ src/m68k/ffi.lo: src/m68k/$(am__dirstamp) \ src/m68k/$(DEPDIR)/$(am__dirstamp) src/m68k/sysv.lo: src/m68k/$(am__dirstamp) \ src/m68k/$(DEPDIR)/$(am__dirstamp) +src/m88k/$(am__dirstamp): + @$(MKDIR_P) src/m88k + @: > src/m88k/$(am__dirstamp) +src/m88k/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/m88k/$(DEPDIR) + @: > src/m88k/$(DEPDIR)/$(am__dirstamp) +src/m88k/ffi.lo: src/m88k/$(am__dirstamp) \ + src/m88k/$(DEPDIR)/$(am__dirstamp) +src/m88k/obsd.lo: src/m88k/$(am__dirstamp) \ + src/m88k/$(DEPDIR)/$(am__dirstamp) src/moxie/$(am__dirstamp): @$(MKDIR_P) src/moxie @: > src/moxie/$(am__dirstamp) @@ -807,6 +962,16 @@ src/microblaze/ffi.lo: src/microblaze/$(am__dirstamp) \ src/microblaze/$(DEPDIR)/$(am__dirstamp) src/microblaze/sysv.lo: src/microblaze/$(am__dirstamp) \ src/microblaze/$(DEPDIR)/$(am__dirstamp) +src/nios2/$(am__dirstamp): + @$(MKDIR_P) src/nios2 + @: > src/nios2/$(am__dirstamp) +src/nios2/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/nios2/$(DEPDIR) + @: > src/nios2/$(DEPDIR)/$(am__dirstamp) +src/nios2/sysv.lo: src/nios2/$(am__dirstamp) \ + src/nios2/$(DEPDIR)/$(am__dirstamp) +src/nios2/ffi.lo: src/nios2/$(am__dirstamp) \ + src/nios2/$(DEPDIR)/$(am__dirstamp) src/powerpc/$(am__dirstamp): @$(MKDIR_P) src/powerpc @: > src/powerpc/$(am__dirstamp) @@ -815,6 +980,10 @@ src/powerpc/$(DEPDIR)/$(am__dirstamp): @: > src/powerpc/$(DEPDIR)/$(am__dirstamp) src/powerpc/ffi.lo: src/powerpc/$(am__dirstamp) \ src/powerpc/$(DEPDIR)/$(am__dirstamp) +src/powerpc/ffi_sysv.lo: src/powerpc/$(am__dirstamp) \ + src/powerpc/$(DEPDIR)/$(am__dirstamp) +src/powerpc/ffi_linux64.lo: src/powerpc/$(am__dirstamp) \ + src/powerpc/$(DEPDIR)/$(am__dirstamp) src/powerpc/sysv.lo: src/powerpc/$(am__dirstamp) \ src/powerpc/$(DEPDIR)/$(am__dirstamp) src/powerpc/ppc_closure.lo: src/powerpc/$(am__dirstamp) \ @@ -843,6 +1012,16 @@ src/aarch64/sysv.lo: src/aarch64/$(am__dirstamp) \ src/aarch64/$(DEPDIR)/$(am__dirstamp) src/aarch64/ffi.lo: src/aarch64/$(am__dirstamp) \ src/aarch64/$(DEPDIR)/$(am__dirstamp) +src/arc/$(am__dirstamp): + @$(MKDIR_P) src/arc + @: > src/arc/$(am__dirstamp) +src/arc/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/arc/$(DEPDIR) + @: > src/arc/$(DEPDIR)/$(am__dirstamp) +src/arc/arcompact.lo: src/arc/$(am__dirstamp) \ + src/arc/$(DEPDIR)/$(am__dirstamp) +src/arc/ffi.lo: src/arc/$(am__dirstamp) \ + src/arc/$(DEPDIR)/$(am__dirstamp) src/arm/$(am__dirstamp): @$(MKDIR_P) src/arm @: > src/arm/$(am__dirstamp) @@ -957,10 +1136,22 @@ src/metag/sysv.lo: src/metag/$(am__dirstamp) \ src/metag/$(DEPDIR)/$(am__dirstamp) src/metag/ffi.lo: src/metag/$(am__dirstamp) \ src/metag/$(DEPDIR)/$(am__dirstamp) +src/vax/$(am__dirstamp): + @$(MKDIR_P) src/vax + @: > src/vax/$(am__dirstamp) +src/vax/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/vax/$(DEPDIR) + @: > src/vax/$(DEPDIR)/$(am__dirstamp) +src/vax/elfbsd.lo: src/vax/$(am__dirstamp) \ + src/vax/$(DEPDIR)/$(am__dirstamp) +src/vax/ffi.lo: src/vax/$(am__dirstamp) \ + src/vax/$(DEPDIR)/$(am__dirstamp) + libffi.la: $(libffi_la_OBJECTS) $(libffi_la_DEPENDENCIES) $(EXTRA_libffi_la_DEPENDENCIES) - $(libffi_la_LINK) -rpath $(toolexeclibdir) $(libffi_la_OBJECTS) $(libffi_la_LIBADD) $(LIBS) + $(AM_V_CCLD)$(libffi_la_LINK) -rpath $(toolexeclibdir) $(libffi_la_OBJECTS) $(libffi_la_LIBADD) $(LIBS) + libffi_convenience.la: $(libffi_convenience_la_OBJECTS) $(libffi_convenience_la_DEPENDENCIES) $(EXTRA_libffi_convenience_la_DEPENDENCIES) - $(LINK) $(libffi_convenience_la_OBJECTS) $(libffi_convenience_la_LIBADD) $(LIBS) + $(AM_V_CCLD)$(LINK) $(libffi_convenience_la_OBJECTS) $(libffi_convenience_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -970,6 +1161,8 @@ mostlyclean-compile: -rm -f src/aarch64/*.lo -rm -f src/alpha/*.$(OBJEXT) -rm -f src/alpha/*.lo + -rm -f src/arc/*.$(OBJEXT) + -rm -f src/arc/*.lo -rm -f src/arm/*.$(OBJEXT) -rm -f src/arm/*.lo -rm -f src/avr32/*.$(OBJEXT) @@ -986,6 +1179,8 @@ mostlyclean-compile: -rm -f src/m32r/*.lo -rm -f src/m68k/*.$(OBJEXT) -rm -f src/m68k/*.lo + -rm -f src/m88k/*.$(OBJEXT) + -rm -f src/m88k/*.lo -rm -f src/metag/*.$(OBJEXT) -rm -f src/metag/*.lo -rm -f src/microblaze/*.$(OBJEXT) @@ -994,6 +1189,8 @@ mostlyclean-compile: -rm -f src/mips/*.lo -rm -f src/moxie/*.$(OBJEXT) -rm -f src/moxie/*.lo + -rm -f src/nios2/*.$(OBJEXT) + -rm -f src/nios2/*.lo -rm -f src/pa/*.$(OBJEXT) -rm -f src/pa/*.lo -rm -f src/powerpc/*.$(OBJEXT) @@ -1008,6 +1205,8 @@ mostlyclean-compile: -rm -f src/sparc/*.lo -rm -f src/tile/*.$(OBJEXT) -rm -f src/tile/*.lo + -rm -f src/vax/*.$(OBJEXT) + -rm -f src/vax/*.lo -rm -f src/x86/*.$(OBJEXT) -rm -f src/x86/*.lo -rm -f src/xtensa/*.$(OBJEXT) @@ -1026,6 +1225,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/aarch64/$(DEPDIR)/sysv.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/alpha/$(DEPDIR)/ffi.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/alpha/$(DEPDIR)/osf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/arc/$(DEPDIR)/arcompact.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/arc/$(DEPDIR)/ffi.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/arm/$(DEPDIR)/ffi.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/arm/$(DEPDIR)/sysv.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/arm/$(DEPDIR)/trampoline.Plo@am__quote@ @@ -1043,6 +1244,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/m32r/$(DEPDIR)/sysv.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/m68k/$(DEPDIR)/ffi.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/m68k/$(DEPDIR)/sysv.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/m88k/$(DEPDIR)/ffi.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/m88k/$(DEPDIR)/obsd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/metag/$(DEPDIR)/ffi.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/metag/$(DEPDIR)/sysv.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/microblaze/$(DEPDIR)/ffi.Plo@am__quote@ @@ -1052,6 +1255,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/mips/$(DEPDIR)/o32.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/moxie/$(DEPDIR)/eabi.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/moxie/$(DEPDIR)/ffi.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/nios2/$(DEPDIR)/ffi.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/nios2/$(DEPDIR)/sysv.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/pa/$(DEPDIR)/ffi.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/pa/$(DEPDIR)/hpux32.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/pa/$(DEPDIR)/linux.Plo@am__quote@ @@ -1061,6 +1266,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/powerpc/$(DEPDIR)/darwin_closure.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/powerpc/$(DEPDIR)/ffi.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/powerpc/$(DEPDIR)/ffi_darwin.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/powerpc/$(DEPDIR)/ffi_linux64.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/powerpc/$(DEPDIR)/ffi_sysv.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/powerpc/$(DEPDIR)/linux64.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/powerpc/$(DEPDIR)/linux64_closure.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/powerpc/$(DEPDIR)/ppc_closure.Plo@am__quote@ @@ -1076,6 +1283,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/sparc/$(DEPDIR)/v9.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tile/$(DEPDIR)/ffi.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tile/$(DEPDIR)/tile.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/vax/$(DEPDIR)/elfbsd.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/vax/$(DEPDIR)/ffi.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/x86/$(DEPDIR)/darwin.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/x86/$(DEPDIR)/darwin64.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/x86/$(DEPDIR)/ffi.Plo@am__quote@ @@ -1089,52 +1298,52 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/xtensa/$(DEPDIR)/sysv.Plo@am__quote@ .S.o: -@am__fastdepCCAS_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCCAS_TRUE@ $(CPPASCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCCAS_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCCAS_FALSE@ $(CPPASCOMPILE) -c -o $@ $< +@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS@am__nodep@)$(CPPASCOMPILE) -c -o $@ $< .S.obj: -@am__fastdepCCAS_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCCAS_TRUE@ $(CPPASCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCCAS_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCCAS_FALSE@ $(CPPASCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS@am__nodep@)$(CPPASCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .S.lo: -@am__fastdepCCAS_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCCAS_TRUE@ $(LTCPPASCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCCAS_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo -@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCCAS_FALSE@ $(LTCPPASCOMPILE) -c -o $@ $< +@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS@am__nodep@)$(LTCPPASCOMPILE) -c -o $@ $< .c.o: -@am__fastdepCC_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: -@am__fastdepCC_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: -@am__fastdepCC_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo @@ -1144,6 +1353,7 @@ clean-libtool: -rm -rf src/.libs src/_libs -rm -rf src/aarch64/.libs src/aarch64/_libs -rm -rf src/alpha/.libs src/alpha/_libs + -rm -rf src/arc/.libs src/arc/_libs -rm -rf src/arm/.libs src/arm/_libs -rm -rf src/avr32/.libs src/avr32/_libs -rm -rf src/bfin/.libs src/bfin/_libs @@ -1152,10 +1362,12 @@ clean-libtool: -rm -rf src/ia64/.libs src/ia64/_libs -rm -rf src/m32r/.libs src/m32r/_libs -rm -rf src/m68k/.libs src/m68k/_libs + -rm -rf src/m88k/.libs src/m88k/_libs -rm -rf src/metag/.libs src/metag/_libs -rm -rf src/microblaze/.libs src/microblaze/_libs -rm -rf src/mips/.libs src/mips/_libs -rm -rf src/moxie/.libs src/moxie/_libs + -rm -rf src/nios2/.libs src/nios2/_libs -rm -rf src/pa/.libs src/pa/_libs -rm -rf src/powerpc/.libs src/powerpc/_libs -rm -rf src/s390/.libs src/s390/_libs @@ -1163,6 +1375,7 @@ clean-libtool: -rm -rf src/sh64/.libs src/sh64/_libs -rm -rf src/sparc/.libs src/sparc/_libs -rm -rf src/tile/.libs src/tile/_libs + -rm -rf src/vax/.libs src/vax/_libs -rm -rf src/x86/.libs src/x86/_libs -rm -rf src/xtensa/.libs src/xtensa/_libs @@ -1173,7 +1386,7 @@ doc/$(am__dirstamp): @: > doc/$(am__dirstamp) $(srcdir)/doc/libffi.info: doc/libffi.texi $(srcdir)/doc/version.texi - restore=: && backupdir="$(am__leading_dot)am$$$$" && \ + $(AM_V_MAKEINFO)restore=: && backupdir="$(am__leading_dot)am$$$$" && \ am__cwd=`pwd` && $(am__cd) $(srcdir) && \ rm -rf $$backupdir && mkdir $$backupdir && \ if ($(MAKEINFO) --version) >/dev/null 2>&1; then \ @@ -1195,18 +1408,20 @@ $(srcdir)/doc/libffi.info: doc/libffi.texi $(srcdir)/doc/version.texi rm -rf $$backupdir; exit $$rc doc/libffi.dvi: doc/libffi.texi $(srcdir)/doc/version.texi doc/$(am__dirstamp) - TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ + $(AM_V_TEXI2DVI)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I doc -I $(srcdir)/doc' \ - $(TEXI2DVI) --clean -o $@ `test -f 'doc/libffi.texi' || echo '$(srcdir)/'`doc/libffi.texi + $(TEXI2DVI) $(AM_V_texinfo) --build-dir=$(@:.dvi=.t2d) -o $@ $(AM_V_texidevnull) \ + `test -f 'doc/libffi.texi' || echo '$(srcdir)/'`doc/libffi.texi doc/libffi.pdf: doc/libffi.texi $(srcdir)/doc/version.texi doc/$(am__dirstamp) - TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ + $(AM_V_TEXI2PDF)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I doc -I $(srcdir)/doc' \ - $(TEXI2PDF) --clean -o $@ `test -f 'doc/libffi.texi' || echo '$(srcdir)/'`doc/libffi.texi + $(TEXI2PDF) $(AM_V_texinfo) --build-dir=$(@:.pdf=.t2p) -o $@ $(AM_V_texidevnull) \ + `test -f 'doc/libffi.texi' || echo '$(srcdir)/'`doc/libffi.texi doc/libffi.html: doc/libffi.texi $(srcdir)/doc/version.texi doc/$(am__dirstamp) - rm -rf $(@:.html=.htp) - if $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I doc -I $(srcdir)/doc \ + $(AM_V_MAKEINFO)rm -rf $(@:.html=.htp) + $(AM_V_at)if $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I doc -I $(srcdir)/doc \ -o $(@:.html=.htp) `test -f 'doc/libffi.texi' || echo '$(srcdir)/'`doc/libffi.texi; \ then \ rm -rf $@; \ @@ -1238,8 +1453,8 @@ mostlyclean-vti: maintainer-clean-vti: @MAINTAINER_MODE_TRUE@ -rm -f $(srcdir)/doc/stamp-vti $(srcdir)/doc/version.texi .dvi.ps: - TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ - $(DVIPS) -o $@ $< + $(AM_V_DVIPS)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ + $(DVIPS) $(AM_V_texinfo) -o $@ $< uninstall-dvi-am: @$(NORMAL_UNINSTALL) @@ -1318,8 +1533,7 @@ dist-info: $(INFO_DEPS) done mostlyclean-aminfo: - -rm -rf libffi.aux libffi.cp libffi.cps libffi.fn libffi.ky libffi.log \ - libffi.pg libffi.tmp libffi.toc libffi.tp libffi.vr + -rm -rf doc/libffi.t2d doc/libffi.t2p clean-aminfo: -test -z "doc/libffi.dvi doc/libffi.pdf doc/libffi.ps doc/libffi.html" \ @@ -1359,14 +1573,13 @@ uninstall-pkgconfigDATA: # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. -$(RECURSIVE_TARGETS) $(RECURSIVE_CLEAN_TARGETS): - @fail= failcom='exit 1'; \ - for f in x $$MAKEFLAGS; do \ - case $$f in \ - *=* | --[!k]*);; \ - *k*) failcom='fail=yes';; \ - esac; \ - done; \ +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ @@ -1387,31 +1600,13 @@ $(RECURSIVE_TARGETS) $(RECURSIVE_CLEAN_TARGETS): if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" -tags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ - done -ctags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ - done -cscopelist-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) cscopelist); \ - done -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: tags-recursive $(HEADERS) $(SOURCES) fficonfig.h.in $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ @@ -1427,12 +1622,7 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES) fficonfig.h.in $(TAGS_DEPENDENCIES) \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ - list='$(SOURCES) $(HEADERS) fficonfig.h.in $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ + $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ @@ -1444,15 +1634,11 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES) fficonfig.h.in $(TAGS_DEPENDENCIES) \ $$unique; \ fi; \ fi -ctags: CTAGS -CTAGS: ctags-recursive $(HEADERS) $(SOURCES) fficonfig.h.in $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) fficonfig.h.in $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique @@ -1461,18 +1647,16 @@ GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" - cscope: cscope.files test ! -s cscope.files \ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) - clean-cscope: -rm -f cscope.files +cscope.files: clean-cscope cscopelist +cscopelist: cscopelist-recursive -cscope.files: clean-cscope cscopelist-recursive cscopelist - -cscopelist: cscopelist-recursive $(HEADERS) $(SOURCES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP)'; \ +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ @@ -1548,7 +1732,7 @@ distdir: $(DISTFILES) done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ - dist-info + dist-info dist-hook -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ @@ -1609,9 +1793,9 @@ distcheck: dist *.zip*) \ unzip $(distdir).zip ;;\ esac - chmod -R a-w $(distdir); chmod u+w $(distdir) - mkdir $(distdir)/_build - mkdir $(distdir)/_inst + chmod -R a-w $(distdir) + chmod u+w $(distdir) + mkdir $(distdir)/_build $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ @@ -1714,6 +1898,8 @@ distclean-generic: -rm -f src/aarch64/$(am__dirstamp) -rm -f src/alpha/$(DEPDIR)/$(am__dirstamp) -rm -f src/alpha/$(am__dirstamp) + -rm -f src/arc/$(DEPDIR)/$(am__dirstamp) + -rm -f src/arc/$(am__dirstamp) -rm -f src/arm/$(DEPDIR)/$(am__dirstamp) -rm -f src/arm/$(am__dirstamp) -rm -f src/avr32/$(DEPDIR)/$(am__dirstamp) @@ -1730,6 +1916,8 @@ distclean-generic: -rm -f src/m32r/$(am__dirstamp) -rm -f src/m68k/$(DEPDIR)/$(am__dirstamp) -rm -f src/m68k/$(am__dirstamp) + -rm -f src/m88k/$(DEPDIR)/$(am__dirstamp) + -rm -f src/m88k/$(am__dirstamp) -rm -f src/metag/$(DEPDIR)/$(am__dirstamp) -rm -f src/metag/$(am__dirstamp) -rm -f src/microblaze/$(DEPDIR)/$(am__dirstamp) @@ -1738,6 +1926,8 @@ distclean-generic: -rm -f src/mips/$(am__dirstamp) -rm -f src/moxie/$(DEPDIR)/$(am__dirstamp) -rm -f src/moxie/$(am__dirstamp) + -rm -f src/nios2/$(DEPDIR)/$(am__dirstamp) + -rm -f src/nios2/$(am__dirstamp) -rm -f src/pa/$(DEPDIR)/$(am__dirstamp) -rm -f src/pa/$(am__dirstamp) -rm -f src/powerpc/$(DEPDIR)/$(am__dirstamp) @@ -1752,6 +1942,8 @@ distclean-generic: -rm -f src/sparc/$(am__dirstamp) -rm -f src/tile/$(DEPDIR)/$(am__dirstamp) -rm -f src/tile/$(am__dirstamp) + -rm -f src/vax/$(DEPDIR)/$(am__dirstamp) + -rm -f src/vax/$(am__dirstamp) -rm -f src/x86/$(DEPDIR)/$(am__dirstamp) -rm -f src/x86/$(am__dirstamp) -rm -f src/xtensa/$(DEPDIR)/$(am__dirstamp) @@ -1768,7 +1960,7 @@ clean-am: clean-aminfo clean-generic clean-libtool \ distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -rf src/$(DEPDIR) src/aarch64/$(DEPDIR) src/alpha/$(DEPDIR) src/arm/$(DEPDIR) src/avr32/$(DEPDIR) src/bfin/$(DEPDIR) src/cris/$(DEPDIR) src/frv/$(DEPDIR) src/ia64/$(DEPDIR) src/m32r/$(DEPDIR) src/m68k/$(DEPDIR) src/metag/$(DEPDIR) src/microblaze/$(DEPDIR) src/mips/$(DEPDIR) src/moxie/$(DEPDIR) src/pa/$(DEPDIR) src/powerpc/$(DEPDIR) src/s390/$(DEPDIR) src/sh/$(DEPDIR) src/sh64/$(DEPDIR) src/sparc/$(DEPDIR) src/tile/$(DEPDIR) src/x86/$(DEPDIR) src/xtensa/$(DEPDIR) + -rm -rf src/$(DEPDIR) src/aarch64/$(DEPDIR) src/alpha/$(DEPDIR) src/arc/$(DEPDIR) src/arm/$(DEPDIR) src/avr32/$(DEPDIR) src/bfin/$(DEPDIR) src/cris/$(DEPDIR) src/frv/$(DEPDIR) src/ia64/$(DEPDIR) src/m32r/$(DEPDIR) src/m68k/$(DEPDIR) src/m88k/$(DEPDIR) src/metag/$(DEPDIR) src/microblaze/$(DEPDIR) src/mips/$(DEPDIR) src/moxie/$(DEPDIR) src/nios2/$(DEPDIR) src/pa/$(DEPDIR) src/powerpc/$(DEPDIR) src/s390/$(DEPDIR) src/sh/$(DEPDIR) src/sh64/$(DEPDIR) src/sparc/$(DEPDIR) src/tile/$(DEPDIR) src/vax/$(DEPDIR) src/x86/$(DEPDIR) src/xtensa/$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-hdr distclean-libtool distclean-tags @@ -1907,7 +2099,7 @@ installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache - -rm -rf src/$(DEPDIR) src/aarch64/$(DEPDIR) src/alpha/$(DEPDIR) src/arm/$(DEPDIR) src/avr32/$(DEPDIR) src/bfin/$(DEPDIR) src/cris/$(DEPDIR) src/frv/$(DEPDIR) src/ia64/$(DEPDIR) src/m32r/$(DEPDIR) src/m68k/$(DEPDIR) src/metag/$(DEPDIR) src/microblaze/$(DEPDIR) src/mips/$(DEPDIR) src/moxie/$(DEPDIR) src/pa/$(DEPDIR) src/powerpc/$(DEPDIR) src/s390/$(DEPDIR) src/sh/$(DEPDIR) src/sh64/$(DEPDIR) src/sparc/$(DEPDIR) src/tile/$(DEPDIR) src/x86/$(DEPDIR) src/xtensa/$(DEPDIR) + -rm -rf src/$(DEPDIR) src/aarch64/$(DEPDIR) src/alpha/$(DEPDIR) src/arc/$(DEPDIR) src/arm/$(DEPDIR) src/avr32/$(DEPDIR) src/bfin/$(DEPDIR) src/cris/$(DEPDIR) src/frv/$(DEPDIR) src/ia64/$(DEPDIR) src/m32r/$(DEPDIR) src/m68k/$(DEPDIR) src/m88k/$(DEPDIR) src/metag/$(DEPDIR) src/microblaze/$(DEPDIR) src/mips/$(DEPDIR) src/moxie/$(DEPDIR) src/nios2/$(DEPDIR) src/pa/$(DEPDIR) src/powerpc/$(DEPDIR) src/s390/$(DEPDIR) src/sh/$(DEPDIR) src/sh64/$(DEPDIR) src/sparc/$(DEPDIR) src/tile/$(DEPDIR) src/vax/$(DEPDIR) src/x86/$(DEPDIR) src/xtensa/$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-aminfo \ maintainer-clean-generic maintainer-clean-vti @@ -1929,35 +2121,35 @@ uninstall-am: uninstall-dvi-am uninstall-html-am uninstall-info-am \ uninstall-pdf-am uninstall-pkgconfigDATA uninstall-ps-am \ uninstall-toolexeclibLTLIBRARIES -.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all \ - cscopelist-recursive ctags-recursive install-am install-strip \ - tags-recursive - -.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ - all all-am am--refresh check check-am clean clean-aminfo \ - clean-cscope clean-generic clean-libtool \ - clean-noinstLTLIBRARIES clean-toolexeclibLTLIBRARIES cscope \ - cscopelist cscopelist-recursive ctags ctags-recursive dist \ - dist-all dist-bzip2 dist-gzip dist-info dist-lzip dist-shar \ - dist-tarZ dist-xz dist-zip distcheck distclean \ - distclean-compile distclean-generic distclean-hdr \ - distclean-libtool distclean-tags distcleancheck distdir \ - distuninstallcheck dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-pkgconfigDATA install-ps \ - install-ps-am install-strip install-toolexeclibLTLIBRARIES \ - installcheck installcheck-am installdirs installdirs-am \ - maintainer-clean maintainer-clean-aminfo \ - maintainer-clean-generic maintainer-clean-vti mostlyclean \ - mostlyclean-aminfo mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool mostlyclean-vti pdf pdf-am ps ps-am tags \ - tags-recursive uninstall uninstall-am uninstall-dvi-am \ - uninstall-html-am uninstall-info-am uninstall-pdf-am \ - uninstall-pkgconfigDATA uninstall-ps-am \ - uninstall-toolexeclibLTLIBRARIES - +.MAKE: $(am__recursive_targets) all install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ + am--refresh check check-am clean clean-aminfo clean-cscope \ + clean-generic clean-libtool clean-noinstLTLIBRARIES \ + clean-toolexeclibLTLIBRARIES cscope cscopelist-am ctags \ + ctags-am dist dist-all dist-bzip2 dist-gzip dist-hook \ + dist-info dist-lzip dist-shar dist-tarZ dist-xz dist-zip \ + distcheck distclean distclean-compile distclean-generic \ + distclean-hdr distclean-libtool distclean-tags distcleancheck \ + distdir distuninstallcheck dvi dvi-am html html-am info \ + info-am install install-am install-data install-data-am \ + install-dvi install-dvi-am install-exec install-exec-am \ + install-html install-html-am install-info install-info-am \ + install-man install-pdf install-pdf-am install-pkgconfigDATA \ + install-ps install-ps-am install-strip \ + install-toolexeclibLTLIBRARIES installcheck installcheck-am \ + installdirs installdirs-am maintainer-clean \ + maintainer-clean-aminfo maintainer-clean-generic \ + maintainer-clean-vti mostlyclean mostlyclean-aminfo \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + mostlyclean-vti pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-dvi-am uninstall-html-am \ + uninstall-info-am uninstall-pdf-am uninstall-pkgconfigDATA \ + uninstall-ps-am uninstall-toolexeclibLTLIBRARIES + + +dist-hook: + if [ -d $(top_srcdir)/.git ] ; then (cd $(top_srcdir); git log --no-decorate) ; else echo 'See git log for history.' ; fi > $(distdir)/ChangeLog # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/Modules/_ctypes/libffi/README b/Modules/_ctypes/libffi/README index 19156fe56e1e..84b942677adb 100644 --- a/Modules/_ctypes/libffi/README +++ b/Modules/_ctypes/libffi/README @@ -1,8 +1,8 @@ Status ====== -libffi-3.0.13 was released on March 17, 2013. Check the libffi web -page for updates: . +libffi-3.1 was released on May 19, 2014. Check the libffi web page +for updates: . What is libffi? @@ -43,7 +43,7 @@ Libffi has been ported to many different platforms. For specific configuration details and testing status, please refer to the wiki page here: - http://www.moxielogic.org/wiki/index.php?title=Libffi_3.0.13 + http://www.moxielogic.org/wiki/index.php?title=Libffi_3.1 At the time of release, the following basic configurations have been tested: @@ -51,9 +51,11 @@ tested: |-----------------+------------------+-------------------------| | Architecture | Operating System | Compiler | |-----------------+------------------+-------------------------| +| AArch64 (ARM64) | iOS | Clang | | AArch64 | Linux | GCC | | Alpha | Linux | GCC | | Alpha | Tru64 | GCC | +| ARC | Linux | GCC | | ARM | Linux | GCC | | ARM | iOS | GCC | | AVR32 | Linux | GCC | @@ -61,15 +63,17 @@ tested: | HPPA | HPUX | GCC | | IA-64 | Linux | GCC | | M68K | FreeMiNT | GCC | -| M68K | Linux | GCC | +| M68K | Linux | GCC | | M68K | RTEMS | GCC | +| M88K | OpenBSD/mvme88k | GCC | | Meta | Linux | GCC | | MicroBlaze | Linux | GCC | | MIPS | IRIX | GCC | | MIPS | Linux | GCC | | MIPS | RTEMS | GCC | | MIPS64 | Linux | GCC | -| Moxie | Bare metal | GCC +| Moxie | Bare metal | GCC | +| Nios II | Linux | GCC | | PowerPC 32-bit | AIX | IBM XL C | | PowerPC 64-bit | AIX | IBM XL C | | PowerPC | AMIGA | GCC | @@ -77,7 +81,8 @@ tested: | PowerPC | Mac OSX | GCC | | PowerPC | FreeBSD | GCC | | PowerPC 64-bit | FreeBSD | GCC | -| PowerPC 64-bit | Linux | GCC | +| PowerPC 64-bit | Linux ELFv1 | GCC | +| PowerPC 64-bit | Linux ELFv2 | GCC | | S390 | Linux | GCC | | S390X | Linux | GCC | | SPARC | Linux | GCC | @@ -87,6 +92,7 @@ tested: | SPARC64 | FreeBSD | GCC | | SPARC64 | Solaris | Oracle Solaris Studio C | | TILE-Gx/TILEPro | Linux | GCC | +| VAX | OpenBSD/vax | GCC | | X86 | FreeBSD | GCC | | X86 | GNU HURD | GCC | | X86 | Interix | GCC | @@ -120,6 +126,9 @@ system. Go to the directory you wish to build libffi in and run the "configure" program found in the root directory of the libffi source distribution. +If you're building libffi directly from version control, configure won't +exist yet; run ./autogen.sh first. + You may want to tell configure where to install the libffi library and header files. To do that, use the --prefix configure switch. Libffi will install under /usr/local by default. @@ -137,13 +146,16 @@ It's also possible to build libffi on Windows platforms with Microsoft's Visual C++ compiler. In this case, use the msvcc.sh wrapper script during configuration like so: -path/to/configure CC=path/to/msvcc.sh LD=link CPP=\"cl -nologo -EP\" +path/to/configure CC=path/to/msvcc.sh CXX=path/to/msvcc.sh LD=link CPP=\"cl -nologo -EP\" + +For 64-bit Windows builds, use CC="path/to/msvcc.sh -m64" and +CXX="path/to/msvcc.sh -m64". You may also need to specify --build +appropriately. -For 64-bit Windows builds, use CC="path/to/msvcc.sh -m64". -You may also need to specify --build appropriately. When building with MSVC -under a MingW environment, you may need to remove the line in configure -that sets 'fix_srcfile_path' to a 'cygpath' command. ('cygpath' is not -present in MingW, and is not required when using MingW-style paths.) +When building with MSVC under a MingW environment, you may need to +remove the line in configure that sets 'fix_srcfile_path' to a 'cygpath' +command. ('cygpath' is not present in MingW, and is not required when +using MingW-style paths.) For iOS builds, the 'libffi.xcodeproj' Xcode project is available. @@ -161,7 +173,20 @@ To install the library and header files, type "make install". History ======= -See the ChangeLog files for details. +See the git log for details at http://github.com/atgreen/libffi. + +3.1 May-19-14 + Add AArch64 (ARM64) iOS support. + Add Nios II support. + Add m88k and DEC VAX support. + Add support for stdcall, thiscall, and fastcall on non-Windows + 32-bit x86 targets such as Linux. + Various Android, MIPS N32, x86, FreeBSD and UltraSPARC IIi + fixes. + Make the testsuite more robust: eliminate several spurious + failures, and respect the $CC and $CXX environment variables. + Archive off the manually maintained ChangeLog in favor of git + log. 3.0.13 Mar-17-13 Add Meta support. @@ -187,7 +212,6 @@ See the ChangeLog files for details. 3.0.11 Apr-11-12 Lots of build fixes. - Add Amiga newer MacOS support. Add support for variadic functions (ffi_prep_cif_var). Add Linux/x32 support. Add thiscall, fastcall and MSVC cdecl support on Windows. @@ -339,7 +363,7 @@ See the ChangeLog files for details. Authors & Credits ================= -libffi was originally written by Anthony Green . +libffi was originally written by Anthony Green . The developers of the GNU Compiler Collection project have made innumerable valuable contributions. See the ChangeLog file for @@ -363,10 +387,12 @@ frv Anthony Green ia64 Hans Boehm m32r Kazuhiro Inaoka m68k Andreas Schwab +m88k Miod Vallat microblaze Nathan Rossi mips Anthony Green, Casey Marshall mips64 David Daney moxie Anthony Green +nios ii Sandra Loosemore pa Randolph Chung, Dave Anglin, Andreas Tobler powerpc Geoffrey Keating, Andreas Tobler, David Edelsohn, John Hornkvist @@ -376,6 +402,7 @@ sh Kaz Kojima sh64 Kaz Kojima sparc Anthony Green, Gordon Irlam tile-gx/tilepro Walter Lee +vax Miod Vallat x86 Anthony Green, Jon Beniston x86-64 Bo Thorsen xtensa Chris Zankel diff --git a/Modules/_ctypes/libffi/aclocal.m4 b/Modules/_ctypes/libffi/aclocal.m4 index c3ab272061d9..6292fbab7aa0 100644 --- a/Modules/_ctypes/libffi/aclocal.m4 +++ b/Modules/_ctypes/libffi/aclocal.m4 @@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.12.2 -*- Autoconf -*- +# generated automatically by aclocal 1.13.4 -*- Autoconf -*- -# Copyright (C) 1996-2012 Free Software Foundation, Inc. +# Copyright (C) 1996-2013 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -11,6 +11,7 @@ # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. +m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, @@ -837,24 +838,22 @@ AU_ALIAS([AC_LTDL_DLSYM_USCORE], [LT_FUNC_DLSYM_USCORE]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LTDL_DLSYM_USCORE], []) -# Copyright (C) 2002-2012 Free Software Foundation, Inc. +# Copyright (C) 2002-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 8 - # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], -[am__api_version='1.12' +[am__api_version='1.13' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.12.2], [], +m4_if([$1], [1.13.4], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -870,21 +869,19 @@ m4_define([_AM_AUTOCONF_VERSION], []) # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.12.2])dnl +[AM_AUTOMAKE_VERSION([1.13.4])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # Figure out how to run the assembler. -*- Autoconf -*- -# Copyright (C) 2001-2012 Free Software Foundation, Inc. +# Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 5 - # AM_PROG_AS # ---------- AC_DEFUN([AM_PROG_AS], @@ -899,14 +896,12 @@ _AM_IF_OPTION([no-dependencies],, [_AM_DEPENDENCIES([CCAS])])dnl # AM_AUX_DIR_EXPAND -*- Autoconf -*- -# Copyright (C) 2001-2012 Free Software Foundation, Inc. +# Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 2 - # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to # '$srcdir', '$srcdir/..', or '$srcdir/../..'. @@ -954,14 +949,12 @@ am_aux_dir=`cd $ac_aux_dir && pwd` # AM_CONDITIONAL -*- Autoconf -*- -# Copyright (C) 1997-2012 Free Software Foundation, Inc. +# Copyright (C) 1997-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 10 - # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. @@ -987,13 +980,12 @@ AC_CONFIG_COMMANDS_PRE( Usually this means the macro was only invoked conditionally.]]) fi])]) -# Copyright (C) 1999-2012 Free Software Foundation, Inc. +# Copyright (C) 1999-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 17 # There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, @@ -1179,19 +1171,18 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl # Generate code to set up dependency tracking. -*- Autoconf -*- -# Copyright (C) 1999-2012 Free Software Foundation, Inc. +# Copyright (C) 1999-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 6 # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ - # Autoconf 2.62 quotes --file arguments for eval, but not when files + # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in @@ -1220,7 +1211,7 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "am__include" && continue + test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the @@ -1256,14 +1247,12 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], # Do all the work for Automake. -*- Autoconf -*- -# Copyright (C) 1996-2012 Free Software Foundation, Inc. +# Copyright (C) 1996-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 19 - # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. @@ -1279,7 +1268,7 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], -[AC_PREREQ([2.62])dnl +[AC_PREREQ([2.65])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl @@ -1309,8 +1298,7 @@ AC_SUBST([CYGPATH_W]) dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [AC_DIAGNOSE([obsolete], -[$0: two- and three-arguments forms are deprecated. For more info, see: -http://www.gnu.org/software/automake/manual/automake.html#Modernize-AM_INIT_AUTOMAKE-invocation]) + [$0: two- and three-arguments forms are deprecated.]) m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], @@ -1364,18 +1352,15 @@ AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES([OBJC])], [m4_define([AC_PROG_OBJC], m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl -dnl Support for Objective C++ was only introduced in Autoconf 2.65, -dnl but we still cater to Autoconf 2.62. -m4_ifdef([AC_PROG_OBJCXX], -[AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], +AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], [_AM_DEPENDENCIES([OBJCXX])], [m4_define([AC_PROG_OBJCXX], - m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])])dnl + m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl ]) -_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl -dnl The 'parallel-tests' driver may need to know about EXEEXT, so add the -dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro -dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_REQUIRE([AM_SILENT_RULES])dnl +dnl The testsuite driver may need to know about EXEEXT, so add the +dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This +dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl @@ -1409,14 +1394,12 @@ for _am_header in $config_headers :; do done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) -# Copyright (C) 2001-2012 Free Software Foundation, Inc. +# Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 8 - # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. @@ -1432,14 +1415,12 @@ if test x"${install_sh}" != xset; then fi AC_SUBST([install_sh])]) -# Copyright (C) 2003-2012 Free Software Foundation, Inc. +# Copyright (C) 2003-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 2 - # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], @@ -1456,14 +1437,12 @@ AC_SUBST([am__leading_dot])]) # Add --enable-maintainer-mode option to configure. -*- Autoconf -*- # From Jim Meyering -# Copyright (C) 1996-2012 Free Software Foundation, Inc. +# Copyright (C) 1996-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 7 - # AM_MAINTAINER_MODE([DEFAULT-MODE]) # ---------------------------------- # Control maintainer-specific portions of Makefiles. @@ -1491,18 +1470,14 @@ AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) ] ) -AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE]) - # Check to see how 'make' treats includes. -*- Autoconf -*- -# Copyright (C) 2001-2012 Free Software Foundation, Inc. +# Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 5 - # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. @@ -1545,14 +1520,12 @@ AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) -# Copyright (C) 1999-2012 Free Software Foundation, Inc. +# Copyright (C) 1999-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 6 - # AM_PROG_CC_C_O # -------------- # Like AC_PROG_CC_C_O, but changed for automake. @@ -1581,14 +1554,12 @@ m4_define([AC_PROG_CC], # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- -# Copyright (C) 1997-2012 Free Software Foundation, Inc. +# Copyright (C) 1997-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 7 - # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], @@ -1596,11 +1567,10 @@ AC_DEFUN([AM_MISSING_PROG], $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) - # AM_MISSING_HAS_RUN # ------------------ -# Define MISSING if not defined so far and test if it supports --run. -# If it does, set am_missing_run to use it, otherwise, to nothing. +# Define MISSING if not defined so far and test if it is modern enough. +# If it is, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl @@ -1613,8 +1583,8 @@ if test x"${MISSING+set}" != xset; then esac fi # Use eval to expand $SHELL -if eval "$MISSING --run true"; then - am_missing_run="$MISSING --run " +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " else am_missing_run= AC_MSG_WARN(['missing' script is too old or missing]) @@ -1623,14 +1593,12 @@ fi # Helper functions for option handling. -*- Autoconf -*- -# Copyright (C) 2001-2012 Free Software Foundation, Inc. +# Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 6 - # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], @@ -1656,14 +1624,12 @@ AC_DEFUN([_AM_IF_OPTION], # Check to make sure that the build environment is sane. -*- Autoconf -*- -# Copyright (C) 1996-2012 Free Software Foundation, Inc. +# Copyright (C) 1996-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 9 - # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], @@ -1739,13 +1705,71 @@ AC_CONFIG_COMMANDS_PRE( rm -f conftest.file ]) -# Copyright (C) 2001-2012 Free Software Foundation, Inc. +# Copyright (C) 2009-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 2 +# AM_SILENT_RULES([DEFAULT]) +# -------------------------- +# Enable less verbose build rules; with the default set to DEFAULT +# ("yes" being less verbose, "no" or empty being verbose). +AC_DEFUN([AM_SILENT_RULES], +[AC_ARG_ENABLE([silent-rules], [dnl +AS_HELP_STRING( + [--enable-silent-rules], + [less verbose build output (undo: "make V=1")]) +AS_HELP_STRING( + [--disable-silent-rules], + [verbose build output (undo: "make V=0")])dnl +]) +case $enable_silent_rules in @%:@ ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; +esac +dnl +dnl A few 'make' implementations (e.g., NonStop OS and NextStep) +dnl do not support nested variable expansions. +dnl See automake bug#9928 and bug#10237. +am_make=${MAKE-make} +AC_CACHE_CHECK([whether $am_make supports nested variables], + [am_cv_make_support_nested_variables], + [if AS_ECHO([['TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi]) +if test $am_cv_make_support_nested_variables = yes; then + dnl Using '$V' instead of '$(V)' breaks IRIX make. + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AC_SUBST([AM_V])dnl +AM_SUBST_NOTMAKE([AM_V])dnl +AC_SUBST([AM_DEFAULT_V])dnl +AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl +AC_SUBST([AM_DEFAULT_VERBOSITY])dnl +AM_BACKSLASH='\' +AC_SUBST([AM_BACKSLASH])dnl +_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl +]) + +# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- @@ -1769,14 +1793,12 @@ fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) -# Copyright (C) 2006-2012 Free Software Foundation, Inc. +# Copyright (C) 2006-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 3 - # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. @@ -1790,14 +1812,12 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- -# Copyright (C) 2004-2012 Free Software Foundation, Inc. +# Copyright (C) 2004-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 3 - # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. @@ -1811,76 +1831,114 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar +# AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AC_SUBST([AMTAR], ['$${TAR-tar}']) -m4_if([$1], [v7], - [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], - [m4_case([$1], [ustar],, [pax],, - [m4_fatal([Unknown tar format])]) -AC_MSG_CHECKING([how to create a $1 tar archive]) -# Loop over all known methods to create a tar archive until one works. + +# We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' -_am_tools=${am_cv_prog_tar_$1-$_am_tools} -# Do not fold the above two line into one, because Tru64 sh and -# Solaris sh will not grok spaces in the rhs of '-'. -for _am_tool in $_am_tools -do - case $_am_tool in - gnutar) - for _am_tar in tar gnutar gtar; - do - AM_RUN_LOG([$_am_tar --version]) && break - done - am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' - am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' - am__untar="$_am_tar -xf -" - ;; - plaintar) - # Must skip GNU tar: if it does not support --format= it doesn't create - # ustar tarball either. - (tar --version) >/dev/null 2>&1 && continue - am__tar='tar chf - "$$tardir"' - am__tar_='tar chf - "$tardir"' - am__untar='tar xf -' - ;; - pax) - am__tar='pax -L -x $1 -w "$$tardir"' - am__tar_='pax -L -x $1 -w "$tardir"' - am__untar='pax -r' - ;; - cpio) - am__tar='find "$$tardir" -print | cpio -o -H $1 -L' - am__tar_='find "$tardir" -print | cpio -o -H $1 -L' - am__untar='cpio -i -H $1 -d' - ;; - none) - am__tar=false - am__tar_=false - am__untar=false - ;; - esac - # If the value was cached, stop now. We just wanted to have am__tar - # and am__untar set. - test -n "${am_cv_prog_tar_$1}" && break +m4_if([$1], [v7], + [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], + + [m4_case([$1], + [ustar], + [# The POSIX 1988 'ustar' format is defined with fixed-size fields. + # There is notably a 21 bits limit for the UID and the GID. In fact, + # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 + # and bug#13588). + am_max_uid=2097151 # 2^21 - 1 + am_max_gid=$am_max_uid + # The $UID and $GID variables are not portable, so we need to resort + # to the POSIX-mandated id(1) utility. Errors in the 'id' calls + # below are definitely unexpected, so allow the users to see them + # (that is, avoid stderr redirection). + am_uid=`id -u || echo unknown` + am_gid=`id -g || echo unknown` + AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) + if test $am_uid -le $am_max_uid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi + AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) + if test $am_gid -le $am_max_gid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi], + + [pax], + [], - # tar/untar a dummy directory, and stop if the command works - rm -rf conftest.dir - mkdir conftest.dir - echo GrepMe > conftest.dir/file - AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + [m4_fatal([Unknown tar format])]) + + AC_MSG_CHECKING([how to create a $1 tar archive]) + + # Go ahead even if we have the value already cached. We do so because we + # need to set the values for the 'am__tar' and 'am__untar' variables. + _am_tools=${am_cv_prog_tar_$1-$_am_tools} + + for _am_tool in $_am_tools; do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works. + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi + done rm -rf conftest.dir - if test -s conftest.tar; then - AM_RUN_LOG([$am__untar /dev/null 2>&1 && break - fi -done -rm -rf conftest.dir -AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) -AC_MSG_RESULT([$am_cv_prog_tar_$1])]) + AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) + AC_MSG_RESULT([$am_cv_prog_tar_$1])]) + AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR diff --git a/Modules/_ctypes/libffi/build-ios.sh b/Modules/_ctypes/libffi/build-ios.sh deleted file mode 100644 index 3dea242255ee..000000000000 --- a/Modules/_ctypes/libffi/build-ios.sh +++ /dev/null @@ -1,67 +0,0 @@ -#!/bin/sh - -PLATFORM_IOS=/Developer/Platforms/iPhoneOS.platform/ -PLATFORM_IOS_SIM=/Developer/Platforms/iPhoneSimulator.platform/ -SDK_IOS_VERSION="4.2" -MIN_IOS_VERSION="3.0" -OUTPUT_DIR="universal-ios" - -build_target () { - local platform=$1 - local sdk=$2 - local arch=$3 - local triple=$4 - local builddir=$5 - - mkdir -p "${builddir}" - pushd "${builddir}" - export CC="${platform}"/Developer/usr/bin/gcc-4.2 - export CFLAGS="-arch ${arch} -isysroot ${sdk} -miphoneos-version-min=${MIN_IOS_VERSION}" - ../configure --host=${triple} && make - popd -} - -# Build all targets -build_target "${PLATFORM_IOS}" "${PLATFORM_IOS}/Developer/SDKs/iPhoneOS${SDK_IOS_VERSION}.sdk/" armv6 arm-apple-darwin10 armv6-ios -build_target "${PLATFORM_IOS}" "${PLATFORM_IOS}/Developer/SDKs/iPhoneOS${SDK_IOS_VERSION}.sdk/" armv7 arm-apple-darwin10 armv7-ios -build_target "${PLATFORM_IOS_SIM}" "${PLATFORM_IOS_SIM}/Developer/SDKs/iPhoneSimulator${SDK_IOS_VERSION}.sdk/" i386 i386-apple-darwin10 i386-ios-sim - -# Create universal output directories -mkdir -p "${OUTPUT_DIR}" -mkdir -p "${OUTPUT_DIR}/include" -mkdir -p "${OUTPUT_DIR}/include/armv6" -mkdir -p "${OUTPUT_DIR}/include/armv7" -mkdir -p "${OUTPUT_DIR}/include/i386" - -# Create the universal binary -lipo -create armv6-ios/.libs/libffi.a armv7-ios/.libs/libffi.a i386-ios-sim/.libs/libffi.a -output "${OUTPUT_DIR}/libffi.a" - -# Copy in the headers -copy_headers () { - local src=$1 - local dest=$2 - - # Fix non-relative header reference - sed 's//"ffitarget.h"/' < "${src}/include/ffi.h" > "${dest}/ffi.h" - cp "${src}/include/ffitarget.h" "${dest}" -} - -copy_headers armv6-ios "${OUTPUT_DIR}/include/armv6" -copy_headers armv7-ios "${OUTPUT_DIR}/include/armv7" -copy_headers i386-ios-sim "${OUTPUT_DIR}/include/i386" - -# Create top-level header -( -cat << EOF -#ifdef __arm__ - #include - #ifdef _ARM_ARCH_6 - #include "include/armv6/ffi.h" - #elif _ARM_ARCH_7 - #include "include/armv7/ffi.h" - #endif -#elif defined(__i386__) - #include "include/i386/ffi.h" -#endif -EOF -) > "${OUTPUT_DIR}/ffi.h" diff --git a/Modules/_ctypes/libffi/compile b/Modules/_ctypes/libffi/compile index c0096a7b5632..531136b068ef 100755 --- a/Modules/_ctypes/libffi/compile +++ b/Modules/_ctypes/libffi/compile @@ -1,10 +1,9 @@ #! /bin/sh -# Wrapper for compilers which do not understand `-c -o'. +# Wrapper for compilers which do not understand '-c -o'. -scriptversion=2009-10-06.20; # UTC +scriptversion=2012-10-14.11; # UTC -# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2009 Free Software -# Foundation, Inc. +# Copyright (C) 1999-2013 Free Software Foundation, Inc. # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify @@ -29,21 +28,224 @@ scriptversion=2009-10-06.20; # UTC # bugs to or send patches to # . +nl=' +' + +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent tools from complaining about whitespace usage. +IFS=" "" $nl" + +file_conv= + +# func_file_conv build_file lazy +# Convert a $build file to $host form and store it in $file +# Currently only supports Windows hosts. If the determined conversion +# type is listed in (the comma separated) LAZY, no conversion will +# take place. +func_file_conv () +{ + file=$1 + case $file in + / | /[!/]*) # absolute file, and not a UNC file + if test -z "$file_conv"; then + # lazily determine how to convert abs files + case `uname -s` in + MINGW*) + file_conv=mingw + ;; + CYGWIN*) + file_conv=cygwin + ;; + *) + file_conv=wine + ;; + esac + fi + case $file_conv/,$2, in + *,$file_conv,*) + ;; + mingw/*) + file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` + ;; + cygwin/*) + file=`cygpath -m "$file" || echo "$file"` + ;; + wine/*) + file=`winepath -w "$file" || echo "$file"` + ;; + esac + ;; + esac +} + +# func_cl_dashL linkdir +# Make cl look for libraries in LINKDIR +func_cl_dashL () +{ + func_file_conv "$1" + if test -z "$lib_path"; then + lib_path=$file + else + lib_path="$lib_path;$file" + fi + linker_opts="$linker_opts -LIBPATH:$file" +} + +# func_cl_dashl library +# Do a library search-path lookup for cl +func_cl_dashl () +{ + lib=$1 + found=no + save_IFS=$IFS + IFS=';' + for dir in $lib_path $LIB + do + IFS=$save_IFS + if $shared && test -f "$dir/$lib.dll.lib"; then + found=yes + lib=$dir/$lib.dll.lib + break + fi + if test -f "$dir/$lib.lib"; then + found=yes + lib=$dir/$lib.lib + break + fi + if test -f "$dir/lib$lib.a"; then + found=yes + lib=$dir/lib$lib.a + break + fi + done + IFS=$save_IFS + + if test "$found" != yes; then + lib=$lib.lib + fi +} + +# func_cl_wrapper cl arg... +# Adjust compile command to suit cl +func_cl_wrapper () +{ + # Assume a capable shell + lib_path= + shared=: + linker_opts= + for arg + do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + eat=1 + case $2 in + *.o | *.[oO][bB][jJ]) + func_file_conv "$2" + set x "$@" -Fo"$file" + shift + ;; + *) + func_file_conv "$2" + set x "$@" -Fe"$file" + shift + ;; + esac + ;; + -I) + eat=1 + func_file_conv "$2" mingw + set x "$@" -I"$file" + shift + ;; + -I*) + func_file_conv "${1#-I}" mingw + set x "$@" -I"$file" + shift + ;; + -l) + eat=1 + func_cl_dashl "$2" + set x "$@" "$lib" + shift + ;; + -l*) + func_cl_dashl "${1#-l}" + set x "$@" "$lib" + shift + ;; + -L) + eat=1 + func_cl_dashL "$2" + ;; + -L*) + func_cl_dashL "${1#-L}" + ;; + -static) + shared=false + ;; + -Wl,*) + arg=${1#-Wl,} + save_ifs="$IFS"; IFS=',' + for flag in $arg; do + IFS="$save_ifs" + linker_opts="$linker_opts $flag" + done + IFS="$save_ifs" + ;; + -Xlinker) + eat=1 + linker_opts="$linker_opts $2" + ;; + -*) + set x "$@" "$1" + shift + ;; + *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) + func_file_conv "$1" + set x "$@" -Tp"$file" + shift + ;; + *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) + func_file_conv "$1" mingw + set x "$@" "$file" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift + done + if test -n "$linker_opts"; then + linker_opts="-link$linker_opts" + fi + exec "$@" $linker_opts + exit 1 +} + +eat= + case $1 in '') - echo "$0: No command. Try \`$0 --help' for more information." 1>&2 + echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: compile [--help] [--version] PROGRAM [ARGS] -Wrapper for compilers which do not understand `-c -o'. -Remove `-o dest.o' from ARGS, run PROGRAM with the remaining +Wrapper for compilers which do not understand '-c -o'. +Remove '-o dest.o' from ARGS, run PROGRAM with the remaining arguments, and rename the output as expected. If you are trying to build a whole package this is not the -right script to run: please start by reading the file `INSTALL'. +right script to run: please start by reading the file 'INSTALL'. Report bugs to . EOF @@ -53,11 +255,13 @@ EOF echo "compile $scriptversion" exit $? ;; + cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) + func_cl_wrapper "$@" # Doesn't return... + ;; esac ofile= cfile= -eat= for arg do @@ -66,8 +270,8 @@ do else case $1 in -o) - # configure might choose to run compile as `compile cc -o foo foo.c'. - # So we strip `-o arg' only if arg is an object. + # configure might choose to run compile as 'compile cc -o foo foo.c'. + # So we strip '-o arg' only if arg is an object. eat=1 case $2 in *.o | *.obj) @@ -94,10 +298,10 @@ do done if test -z "$ofile" || test -z "$cfile"; then - # If no `-o' option was seen then we might have been invoked from a + # If no '-o' option was seen then we might have been invoked from a # pattern rule where we don't need one. That is ok -- this is a # normal compilation that the losing compiler can handle. If no - # `.c' file was seen then we are probably linking. That is also + # '.c' file was seen then we are probably linking. That is also # ok. exec "$@" fi @@ -106,7 +310,7 @@ fi cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` # Create the lock directory. -# Note: use `[/\\:.-]' here to ensure that we don't use the same name +# Note: use '[/\\:.-]' here to ensure that we don't use the same name # that we are using for the .o file. Also, base the name on the expected # object file name, since that is what matters with a parallel build. lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d diff --git a/Modules/_ctypes/libffi/config.guess b/Modules/_ctypes/libffi/config.guess index 1804e9fcdcbc..b79252d6b103 100755 --- a/Modules/_ctypes/libffi/config.guess +++ b/Modules/_ctypes/libffi/config.guess @@ -1,10 +1,8 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, -# 2011, 2012, 2013 Free Software Foundation, Inc. +# Copyright 1992-2013 Free Software Foundation, Inc. -timestamp='2012-12-29' +timestamp='2013-06-10' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -26,7 +24,7 @@ timestamp='2012-12-29' # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # -# Originally written by Per Bothner. +# Originally written by Per Bothner. # # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD @@ -52,9 +50,7 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, -2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, -2012, 2013 Free Software Foundation, Inc. +Copyright 1992-2013 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -136,6 +132,27 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown +case "${UNAME_SYSTEM}" in +Linux|GNU|GNU/*) + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + LIBC=gnu + + eval $set_cc_for_build + cat <<-EOF > $dummy.c + #include + #if defined(__UCLIBC__) + LIBC=uclibc + #elif defined(__dietlibc__) + LIBC=dietlibc + #else + LIBC=gnu + #endif + EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` + ;; +esac + # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in @@ -857,21 +874,21 @@ EOF exit ;; *:GNU:*:*) # the GNU system - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; aarch64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in @@ -884,59 +901,54 @@ EOF EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 - if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi - echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + if test "$?" = 0 ; then LIBC="gnulibc1" ; fi + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + arc:Linux:*:* | arceb:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then - echo ${UNAME_MACHINE}-unknown-linux-gnueabi + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi else - echo ${UNAME_MACHINE}-unknown-linux-gnueabihf + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf fi fi exit ;; avr32*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; cris:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-gnu + echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; crisv32:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-gnu + echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; frv:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; hexagon:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:Linux:*:*) - LIBC=gnu - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #ifdef __dietlibc__ - LIBC=dietlibc - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` - echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + echo ${UNAME_MACHINE}-pc-linux-${LIBC} exit ;; ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build @@ -955,54 +967,63 @@ EOF #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } ;; + or1k:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; or32:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; padre:Linux:*:*) - echo sparc-unknown-linux-gnu + echo sparc-unknown-linux-${LIBC} exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-gnu + echo hppa64-unknown-linux-${LIBC} exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-gnu ;; - PA8*) echo hppa2.0-unknown-linux-gnu ;; - *) echo hppa-unknown-linux-gnu ;; + PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; + PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; + *) echo hppa-unknown-linux-${LIBC} ;; esac exit ;; ppc64:Linux:*:*) - echo powerpc64-unknown-linux-gnu + echo powerpc64-unknown-linux-${LIBC} exit ;; ppc:Linux:*:*) - echo powerpc-unknown-linux-gnu + echo powerpc-unknown-linux-${LIBC} + exit ;; + ppc64le:Linux:*:*) + echo powerpc64le-unknown-linux-${LIBC} + exit ;; + ppcle:Linux:*:*) + echo powerpcle-unknown-linux-${LIBC} exit ;; s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux + echo ${UNAME_MACHINE}-ibm-linux-${LIBC} exit ;; sh64*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; tile*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; vax:Linux:*:*) - echo ${UNAME_MACHINE}-dec-linux-gnu + echo ${UNAME_MACHINE}-dec-linux-${LIBC} exit ;; x86_64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; xtensa*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. @@ -1235,19 +1256,21 @@ EOF exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - case $UNAME_PROCESSOR in - i386) - eval $set_cc_for_build - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then - if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - UNAME_PROCESSOR="x86_64" - fi - fi ;; - unknown) UNAME_PROCESSOR=powerpc ;; - esac + eval $set_cc_for_build + if test "$UNAME_PROCESSOR" = unknown ; then + UNAME_PROCESSOR=powerpc + fi + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + fi echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) diff --git a/Modules/_ctypes/libffi/config.sub b/Modules/_ctypes/libffi/config.sub index 802a224de605..c765b34b7b0e 100755 --- a/Modules/_ctypes/libffi/config.sub +++ b/Modules/_ctypes/libffi/config.sub @@ -1,10 +1,8 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, -# 2011, 2012, 2013 Free Software Foundation, Inc. +# Copyright 1992-2013 Free Software Foundation, Inc. -timestamp='2012-12-29' +timestamp='2013-04-24' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -70,9 +68,7 @@ Report bugs and patches to ." version="\ GNU config.sub ($timestamp) -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, -2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, -2012, 2013 Free Software Foundation, Inc. +Copyright 1992-2013 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -256,7 +252,7 @@ case $basic_machine in | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ - | arc \ + | arc | arceb \ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ | avr | avr32 \ | be32 | be64 \ @@ -290,16 +286,17 @@ case $basic_machine in | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ + | mipsr5900 | mipsr5900el \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ - | nios | nios2 \ + | nios | nios2 | nios2eb | nios2el \ | ns16k | ns32k \ | open8 \ - | or32 \ + | or1k | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ @@ -369,7 +366,7 @@ case $basic_machine in | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ - | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | be32-* | be64-* \ @@ -407,12 +404,13 @@ case $basic_machine in | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipsr5900-* | mipsr5900el-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ - | nios-* | nios2-* \ + | nios-* | nios2-* | nios2eb-* | nios2el-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ | orion-* \ @@ -1008,7 +1006,7 @@ case $basic_machine in ;; ppc64) basic_machine=powerpc64-unknown ;; - ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ppc64-* | ppc64p7-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown @@ -1354,7 +1352,7 @@ case $os in -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ - | -sym* | -kopensolaris* \ + | -sym* | -kopensolaris* | -plan9* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ @@ -1500,9 +1498,6 @@ case $os in -aros*) os=-aros ;; - -kaos*) - os=-kaos - ;; -zvmoe) os=-zvmoe ;; @@ -1594,6 +1589,9 @@ case $basic_machine in mips*-*) os=-elf ;; + or1k-*) + os=-elf + ;; or32-*) os=-coff ;; diff --git a/Modules/_ctypes/libffi/configure b/Modules/_ctypes/libffi/configure index 823083063f07..75f62a7c4ca2 100755 --- a/Modules/_ctypes/libffi/configure +++ b/Modules/_ctypes/libffi/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for libffi 3.0.13. +# Generated by GNU Autoconf 2.69 for libffi 3.1. # # Report bugs to . # @@ -590,8 +590,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='libffi' PACKAGE_TARNAME='libffi' -PACKAGE_VERSION='3.0.13' -PACKAGE_STRING='libffi 3.0.13' +PACKAGE_VERSION='3.1' +PACKAGE_STRING='libffi 3.1' PACKAGE_BUGREPORT='http://github.com/atgreen/libffi/issues' PACKAGE_URL='' @@ -645,10 +645,13 @@ FFI_EXEC_TRAMPOLINE_TABLE FFI_EXEC_TRAMPOLINE_TABLE_FALSE FFI_EXEC_TRAMPOLINE_TABLE_TRUE sys_symbol_underscore +HAVE_LONG_DOUBLE_VARIANT HAVE_LONG_DOUBLE ALLOCA XTENSA_FALSE XTENSA_TRUE +VAX_FALSE +VAX_TRUE TILE_FALSE TILE_TRUE PA64_HPUX_FALSE @@ -673,6 +676,8 @@ AVR32_FALSE AVR32_TRUE ARM_FALSE ARM_TRUE +ARC_FALSE +ARC_TRUE AARCH64_FALSE AARCH64_TRUE POWERPC_FREEBSD_FALSE @@ -683,12 +688,16 @@ POWERPC_AIX_FALSE POWERPC_AIX_TRUE POWERPC_FALSE POWERPC_TRUE +NIOS2_FALSE +NIOS2_TRUE MOXIE_FALSE MOXIE_TRUE METAG_FALSE METAG_TRUE MICROBLAZE_FALSE MICROBLAZE_TRUE +M88K_FALSE +M88K_TRUE M68K_FALSE M68K_TRUE M32R_FALSE @@ -697,6 +706,10 @@ IA64_FALSE IA64_TRUE ALPHA_FALSE ALPHA_TRUE +X86_DARWIN64_FALSE +X86_DARWIN64_TRUE +X86_DARWIN32_FALSE +X86_DARWIN32_TRUE X86_DARWIN_FALSE X86_DARWIN_TRUE X86_WIN64_FALSE @@ -721,6 +734,7 @@ MAINT MAINTAINER_MODE_FALSE MAINTAINER_MODE_TRUE PRTDIAG +CXXCPP CPP OTOOL64 OTOOL @@ -748,6 +762,12 @@ am__fastdepCCAS_TRUE CCASDEPMODE CCASFLAGS CCAS +am__fastdepCXX_FALSE +am__fastdepCXX_TRUE +CXXDEPMODE +ac_ct_CXX +CXXFLAGS +CXX am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE @@ -765,6 +785,10 @@ CPPFLAGS LDFLAGS CFLAGS CC +AM_BACKSLASH +AM_DEFAULT_VERBOSITY +AM_DEFAULT_V +AM_V am__untar am__tar AMTAR @@ -843,6 +867,7 @@ ac_subst_files='' ac_user_opts=' enable_option_checking enable_builddir +enable_silent_rules enable_dependency_tracking enable_shared enable_static @@ -866,7 +891,8 @@ target_alias CCAS CCASFLAGS CPP -CPPFLAGS' +CPPFLAGS +CXXCPP' # Initialize some variables set by options. @@ -1407,7 +1433,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures libffi 3.0.13 to adapt to many kinds of systems. +\`configure' configures libffi 3.1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1478,7 +1504,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of libffi 3.0.13:";; + short | recursive ) echo "Configuration of libffi 3.1:";; esac cat <<\_ACEOF @@ -1488,6 +1514,8 @@ Optional Features: --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --disable-builddir disable automatic build in subdir of sources + --enable-silent-rules less verbose build output (undo: "make V=1") + --disable-silent-rules verbose build output (undo: "make V=0") --enable-dependency-tracking do not reject slow dependency extractors --disable-dependency-tracking @@ -1515,8 +1543,8 @@ Optional Packages: --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use both] --with-gnu-ld assume the C compiler uses GNU ld [default=no] - --with-sysroot=DIR Search for dependent libraries within DIR - (or the compiler's sysroot if not specified). + --with-sysroot[=DIR] Search for dependent libraries within DIR (or the + compiler's sysroot if not specified). --with-gcc-arch= use architecture for gcc -march/-mtune, instead of guessing @@ -1528,9 +1556,12 @@ Some influential environment variables: LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory + CXX C++ compiler command + CXXFLAGS C++ compiler flags CCAS assembler compiler command (defaults to CC) CCASFLAGS assembler compiler flags (defaults to CFLAGS) CPP C preprocessor + CXXCPP C++ preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. @@ -1598,7 +1629,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -libffi configure 3.0.13 +libffi configure 3.1 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1650,6 +1681,44 @@ fi } # ac_fn_c_try_compile +# ac_fn_cxx_try_compile LINENO +# ---------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_compile + # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. @@ -1873,6 +1942,89 @@ $as_echo "$ac_res" >&6; } } # ac_fn_c_check_func +# ac_fn_cxx_try_cpp LINENO +# ------------------------ +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_cpp + +# ac_fn_cxx_try_link LINENO +# ------------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_link + # ac_fn_c_compute_int LINENO EXPR VAR INCLUDES # -------------------------------------------- # Tries to find the compile-time value of EXPR in a program that includes @@ -2204,7 +2356,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by libffi $as_me 3.0.13, which was +It was created by libffi $as_me 3.1, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2697,7 +2849,11 @@ test -n "$target_alias" && target_alias=${target_alias-$host_alias} -. ${srcdir}/configure.host +case "${host}" in + frv*-elf) + LDFLAGS=`echo $LDFLAGS | sed "s/\-B^ *libgloss\/frv\///"`\ -B`pwd`/../libgloss/frv/ + ;; +esac # [$]@ is unsable in 2.60+ but earlier autoconf had no ac_configure_args @@ -2803,7 +2959,7 @@ ax_enable_builddir_auxdir="$am_aux_dir" ac_config_commands="$ac_config_commands buildir" -am__api_version='1.12' +am__api_version='1.13' # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or @@ -2984,8 +3140,8 @@ if test x"${MISSING+set}" != xset; then esac fi # Use eval to expand $SHELL -if eval "$MISSING --run true"; then - am_missing_run="$MISSING --run " +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " else am_missing_run= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 @@ -3225,6 +3381,45 @@ else fi rmdir .tst 2>/dev/null +# Check whether --enable-silent-rules was given. +if test "${enable_silent_rules+set}" = set; then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in # ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=1;; +esac +am_make=${MAKE-make} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +$as_echo_n "checking whether $am_make supports nested variables... " >&6; } +if ${am_cv_make_support_nested_variables+:} false; then : + $as_echo_n "(cached) " >&6 +else + if $as_echo 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +$as_echo "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." @@ -3247,7 +3442,7 @@ fi # Define the identity of the package. PACKAGE='libffi' - VERSION='3.0.13' + VERSION='3.1' cat >>confdefs.h <<_ACEOF @@ -3287,6 +3482,10 @@ mkdir_p='$(MKDIR_P)' # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar pax cpio none' + am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' @@ -3294,6 +3493,7 @@ am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' + # The same as in boehm-gc and libstdc++. Have to borrow it from there. # We must force CC to /not/ be precious variables; otherwise # the wrong, non-multilib-adjusted value will be used in multilibs. @@ -4284,54 +4484,439 @@ else fi -CFLAGS=$save_CFLAGS - +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; 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_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +$as_echo "$CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; 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_ac_ct_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS -# By default we simply use the C compiler to build assembly code. +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 +$as_echo "$ac_ct_CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi -test "${CCAS+set}" = set || CCAS=$CC -test "${CCASFLAGS+set}" = set || CCASFLAGS=$CFLAGS + test -n "$ac_ct_CXX" && break +done + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi -depcc="$CCAS" am_compiler_list= + fi +fi +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 -$as_echo_n "checking dependency style of $depcc... " >&6; } -if ${am_cv_CCAS_dependencies_compiler_type+:} false; then : +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 +$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } +if ${ac_cv_cxx_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else - if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then - # We make a subdir and do the tests there. Otherwise we can end up - # making bogus files that we don't know about and never remove. For - # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named 'D' -- because '-MD' means "put the output - # in D". - rm -rf conftest.dir - mkdir conftest.dir - # Copy depcomp to subdir because otherwise we won't find it if we're - # using a relative directory. - cp "$am_depcomp" conftest.dir - cd conftest.dir - # We will build objects and dependencies in a subdirectory because - # it helps to detect inapplicable dependency modes. For instance - # both Tru64's cc and ICC support -MD to output dependencies as a - # side effect of compilation, but ICC will put the dependencies in - # the current directory while Tru64 will put them in the object - # directory. - mkdir sub - - am_cv_CCAS_dependencies_compiler_type=none - if test "$am_compiler_list" = ""; then - am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` - fi - am__universal=false - + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ - for depmode in $am_compiler_list; do +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 +$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GXX=yes +else + GXX= +fi +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 +$as_echo_n "checking whether $CXX accepts -g... " >&6; } +if ${ac_cv_prog_cxx_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +else + CXXFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 +$as_echo "$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +depcc="$CXX" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CXX_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CXX_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CXX_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CXX_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } +CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then + am__fastdepCXX_TRUE= + am__fastdepCXX_FALSE='#' +else + am__fastdepCXX_TRUE='#' + am__fastdepCXX_FALSE= +fi + + +CFLAGS=$save_CFLAGS + + + + + +# By default we simply use the C compiler to build assembly code. + +test "${CCAS+set}" = set || CCAS=$CC +test "${CCASFLAGS+set}" = set || CCASFLAGS=$CFLAGS + + + +depcc="$CCAS" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CCAS_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CCAS_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + + + for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. @@ -4557,8 +5142,8 @@ esac -macro_version='2.4.2' -macro_revision='1.3337' +macro_version='2.4.2.418' +macro_revision='2.4.2.418' @@ -4572,7 +5157,7 @@ macro_revision='1.3337' -ltmain="$ac_aux_dir/ltmain.sh" +ltmain=$ac_aux_dir/ltmain.sh # Backslashify metacharacters that are still active within # double-quoted strings. @@ -4621,7 +5206,7 @@ func_echo_all () $ECHO "" } -case "$ECHO" in +case $ECHO in printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 $as_echo "printf" >&6; } ;; print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 @@ -4944,19 +5529,19 @@ test -z "$GREP" && GREP=grep # Check whether --with-gnu-ld was given. if test "${with_gnu_ld+set}" = set; then : - withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes + withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes else with_gnu_ld=no fi ac_prog=ld -if test "$GCC" = yes; then +if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 $as_echo_n "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) - # gcc leaves a trailing carriage return which upsets mingw + # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; @@ -4970,7 +5555,7 @@ $as_echo_n "checking for ld used by $CC... " >&6; } while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done - test -z "$LD" && LD="$ac_prog" + test -z "$LD" && LD=$ac_prog ;; "") # If it fails, then pretend we aren't using GCC. @@ -4981,7 +5566,7 @@ $as_echo_n "checking for ld used by $CC... " >&6; } with_gnu_ld=unknown ;; esac -elif test "$with_gnu_ld" = yes; then +elif test yes = "$with_gnu_ld"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } else @@ -4992,32 +5577,32 @@ if ${lt_cv_path_LD+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$LD"; then - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - lt_cv_path_LD="$ac_dir/$ac_prog" + lt_cv_path_LD=$ac_dir/$ac_prog # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 $as_echo "$LD" >&6; } @@ -5060,33 +5645,33 @@ if ${lt_cv_path_NM+:} false; then : else if test -n "$NM"; then # Let the user override the test. - lt_cv_path_NM="$NM" + lt_cv_path_NM=$NM else - lt_nm_to_check="${ac_tool_prefix}nm" + lt_nm_to_check=${ac_tool_prefix}nm if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. - tmp_nm="$ac_dir/$lt_tmp_nm" - if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + tmp_nm=$ac_dir/$lt_tmp_nm + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then # Check to see if the nm accepts a BSD-compat flag. - # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # Adding the 'sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" - break + break 2 ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" - break + break 2 ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but @@ -5097,15 +5682,15 @@ else esac fi done - IFS="$lt_save_ifs" + IFS=$lt_save_ifs done : ${lt_cv_path_NM=no} fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 $as_echo "$lt_cv_path_NM" >&6; } -if test "$lt_cv_path_NM" != "no"; then - NM="$lt_cv_path_NM" +if test no != "$lt_cv_path_NM"; then + NM=$lt_cv_path_NM else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : @@ -5211,9 +5796,9 @@ esac fi fi - case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in + case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in *COFF*) - DUMPBIN="$DUMPBIN -symbols" + DUMPBIN="$DUMPBIN -symbols -headers" ;; *) DUMPBIN=: @@ -5221,8 +5806,8 @@ fi esac fi - if test "$DUMPBIN" != ":"; then - NM="$DUMPBIN" + if test : != "$DUMPBIN"; then + NM=$DUMPBIN fi fi test -z "$NM" && NM=nm @@ -5273,7 +5858,7 @@ if ${lt_cv_sys_max_cmd_len+:} false; then : $as_echo_n "(cached) " >&6 else i=0 - teststring="ABCD" + teststring=ABCD case $build_os in msdosdjgpp*) @@ -5313,7 +5898,7 @@ else lt_cv_sys_max_cmd_len=8192; ;; - netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` @@ -5364,22 +5949,22 @@ else *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len" && \ - test undefined != "$lt_cv_sys_max_cmd_len"; then + test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. - for i in 1 2 3 4 5 6 7 8 ; do + for i in 1 2 3 4 5 6 7 8; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. - while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ + while { test X`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && - test $i != 17 # 1/2 MB should be enough + test 17 != "$i" # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring @@ -5397,7 +5982,7 @@ else fi -if test -n $lt_cv_sys_max_cmd_len ; then +if test -n "$lt_cv_sys_max_cmd_len"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 $as_echo "$lt_cv_sys_max_cmd_len" >&6; } else @@ -5415,30 +6000,6 @@ max_cmd_len=$lt_cv_sys_max_cmd_len : ${MV="mv -f"} : ${RM="rm -f"} -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 -$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } -# Try some XSI features -xsi_shell=no -( _lt_dummy="a/b/c" - test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ - = c,a/b,b/c, \ - && eval 'test $(( 1 + 1 )) -eq 2 \ - && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ - && xsi_shell=yes -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 -$as_echo "$xsi_shell" >&6; } - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 -$as_echo_n "checking whether the shell understands \"+=\"... " >&6; } -lt_shell_append=no -( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ - >/dev/null 2>&1 \ - && lt_shell_append=yes -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 -$as_echo "$lt_shell_append" >&6; } - - if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else @@ -5561,13 +6122,13 @@ esac reload_cmds='$LD$reload_flag -o $output$reload_objs' case $host_os in cygwin* | mingw* | pw32* | cegcc*) - if test "$GCC" != yes; then + if test yes != "$GCC"; then reload_cmds=false fi ;; darwin*) - if test "$GCC" = yes; then - reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' + if test yes = "$GCC"; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs' else reload_cmds='$LD$reload_flag -o $output$reload_objs' fi @@ -5695,13 +6256,13 @@ lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. -# `unknown' -- same as none, but documents that we really don't know. +# 'unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path -# which responds to the $file_magic_cmd with a given extended regex. -# If you have `file' or equivalent on your system and you're not sure -# whether `pass_all' will *always* work, you probably want this one. +# that responds to the $file_magic_cmd with a given extended regex. +# If you have 'file' or equivalent on your system and you're not sure +# whether 'pass_all' will *always* work, you probably want this one. case $host_os in aix[4-9]*) @@ -5728,8 +6289,7 @@ mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. - # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. - if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then + if ( file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else @@ -5765,10 +6325,6 @@ freebsd* | dragonfly*) fi ;; -gnu*) - lt_cv_deplibs_check_method=pass_all - ;; - haiku*) lt_cv_deplibs_check_method=pass_all ;; @@ -5807,7 +6363,7 @@ irix5* | irix6* | nonstopux*) ;; # This must be glibc/ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu) +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; @@ -5829,8 +6385,8 @@ newos6*) lt_cv_deplibs_check_method=pass_all ;; -openbsd*) - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then +openbsd* | bitrig*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' @@ -6040,8 +6596,8 @@ else case $host_os in cygwin* | mingw* | pw32* | cegcc*) - # two different shell functions defined in ltmain.sh - # decide which to use based on capabilities of $DLLTOOL + # two different shell functions defined in ltmain.sh; + # decide which one to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib @@ -6053,7 +6609,7 @@ cygwin* | mingw* | pw32* | cegcc*) ;; *) # fallback: assume linklib IS sharedlib - lt_cv_sharedlib_from_linklib_cmd="$ECHO" + lt_cv_sharedlib_from_linklib_cmd=$ECHO ;; esac @@ -6208,7 +6764,7 @@ if ac_fn_c_try_compile "$LINENO"; then : ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } - if test "$ac_status" -eq 0; then + if test 0 -eq "$ac_status"; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 @@ -6216,7 +6772,7 @@ if ac_fn_c_try_compile "$LINENO"; then : ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } - if test "$ac_status" -ne 0; then + if test 0 -ne "$ac_status"; then lt_cv_ar_at_file=@ fi fi @@ -6229,7 +6785,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 $as_echo "$lt_cv_ar_at_file" >&6; } -if test "x$lt_cv_ar_at_file" = xno; then +if test no = "$lt_cv_ar_at_file"; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file @@ -6446,7 +7002,7 @@ old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in - openbsd*) + bitrig* | openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) @@ -6536,7 +7092,7 @@ cygwin* | mingw* | pw32* | cegcc*) symcode='[ABCDGISTW]' ;; hpux*) - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then symcode='[ABCDEGRST]' fi ;; @@ -6569,14 +7125,44 @@ case `$NM -V 2>&1` in symcode='[ABCDGIRSTW]' ;; esac +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Gets list of data symbols to import. + lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" + # Adjust the below global symbol transforms to fixup imported variables. + lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" + lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" + lt_c_name_lib_hook="\ + -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ + -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" +else + # Disable hooks by default. + lt_cv_sys_global_symbol_to_import= + lt_cdecl_hook= + lt_c_name_hook= + lt_c_name_lib_hook= +fi + # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. -lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" +lt_cv_sys_global_symbol_to_cdecl="sed -n"\ +$lt_cdecl_hook\ +" -e 's/^T .* \(.*\)$/extern int \1();/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address -lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ +$lt_c_name_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" + +# Transform an extracted symbol line into symbol name with lib prefix and +# symbol address. +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ +$lt_c_name_lib_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" # Handle CRLF in mingw tool chain opt_cr= @@ -6594,21 +7180,24 @@ for ac_symprfx in "" "_"; do # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then - # Fake it for dumpbin and say T for any non-static function - # and D for any global variable. + # Fake it for dumpbin and say T for any non-static function, + # D for any global variable and I for any imported variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK '"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ +" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ +" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ -" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ -" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ -" s[1]~/^[@?]/{print s[1], s[1]; next};"\ -" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ +" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ +" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" @@ -6656,11 +7245,11 @@ _LT_EOF if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ -#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) -/* DATA imports from DLLs on WIN32 con't be const, because runtime +#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE +/* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST -#elif defined(__osf__) +#elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else @@ -6686,7 +7275,7 @@ lt__PROGRAM__LTX_preloaded_symbols[] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF - $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; @@ -6706,13 +7295,13 @@ _LT_EOF mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS - LIBS="conftstm.$ac_objext" + LIBS=conftstm.$ac_objext CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s conftest${ac_exeext}; then + test $ac_status = 0; } && test -s conftest$ac_exeext; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS @@ -6733,7 +7322,7 @@ _LT_EOF rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. - if test "$pipe_works" = yes; then + if test yes = "$pipe_works"; then break else lt_cv_sys_global_symbol_pipe= @@ -6786,21 +7375,31 @@ fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 -$as_echo_n "checking for sysroot... " >&6; } -# Check whether --with-sysroot was given. -if test "${with_sysroot+set}" = set; then : - withval=$with_sysroot; + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 +$as_echo_n "checking for sysroot... " >&6; } + +# Check whether --with-sysroot was given. +if test "${with_sysroot+set}" = set; then : + withval=$with_sysroot; else with_sysroot=no fi lt_sysroot= -case ${with_sysroot} in #( +case $with_sysroot in #( yes) - if test "$GCC" = yes; then + if test yes = "$GCC"; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( @@ -6810,8 +7409,8 @@ case ${with_sysroot} in #( no|'') ;; #( *) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5 -$as_echo "${with_sysroot}" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5 +$as_echo "$with_sysroot" >&6; } as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 ;; esac @@ -6828,13 +7427,14 @@ if test "${enable_libtool_lock+set}" = set; then : enableval=$enable_libtool_lock; fi -test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes +test no = "$enable_libtool_lock" || enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) - # Find out which ABI we are using. + # Find out what ABI is being produced by ac_compile, and set mode + # options accordingly. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 @@ -6843,24 +7443,25 @@ ia64-*-hpux*) test $ac_status = 0; }; then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) - HPUX_IA64_MODE="32" + HPUX_IA64_MODE=32 ;; *ELF-64*) - HPUX_IA64_MODE="64" + HPUX_IA64_MODE=64 ;; esac fi rm -rf conftest* ;; *-*-irix6*) - # Find out which ABI we are using. + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - if test "$lt_cv_prog_gnu_ld" = yes; then + if test yes = "$lt_cv_prog_gnu_ld"; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" @@ -6889,9 +7490,50 @@ ia64-*-hpux*) rm -rf conftest* ;; -x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +mips64*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + emul=elf + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + emul="${emul}32" + ;; + *64-bit*) + emul="${emul}64" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *MSB*) + emul="${emul}btsmip" + ;; + *LSB*) + emul="${emul}ltsmip" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *N32*) + emul="${emul}n32" + ;; + esac + LD="${LD-ld} -m $emul" + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) - # Find out which ABI we are using. + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. Note that the listed cases only cover the + # situations where additional linker options are needed (such as when + # doing 32-bit compilation for a host where ld defaults to 64-bit, or + # vice versa); the common cases where no linker options are needed do + # not appear in the list. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 @@ -6907,14 +7549,17 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) x86_64-*linux*) case `/usr/bin/file conftest.o` in *x86-64*) - LD="${LD-ld} -m elf32_x86_64" - ;; + LD="${LD-ld} -m elf32_x86_64" + ;; *) - LD="${LD-ld} -m elf_i386" - ;; + LD="${LD-ld} -m elf_i386" + ;; esac ;; - ppc64-*linux*|powerpc64-*linux*) + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) @@ -6933,7 +7578,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; - ppc*-*linux*|powerpc*-*linux*) + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) @@ -6951,7 +7599,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. - SAVE_CFLAGS="$CFLAGS" + SAVE_CFLAGS=$CFLAGS CFLAGS="$CFLAGS -belf" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 $as_echo_n "checking whether the C compiler needs -belf... " >&6; } @@ -6991,13 +7639,14 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 $as_echo "$lt_cv_cc_needs_belf" >&6; } - if test x"$lt_cv_cc_needs_belf" != x"yes"; then + if test yes != "$lt_cv_cc_needs_belf"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf - CFLAGS="$SAVE_CFLAGS" + CFLAGS=$SAVE_CFLAGS fi ;; *-*solaris*) - # Find out which ABI we are using. + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 @@ -7009,7 +7658,7 @@ $as_echo "$lt_cv_cc_needs_belf" >&6; } case $lt_cv_prog_gnu_ld in yes*) case $host in - i?86-*-solaris*) + i?86-*-solaris*|x86_64-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) @@ -7018,7 +7667,7 @@ $as_echo "$lt_cv_cc_needs_belf" >&6; } esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then - LD="${LD-ld}_sol2" + LD=${LD-ld}_sol2 fi ;; *) @@ -7034,7 +7683,7 @@ $as_echo "$lt_cv_cc_needs_belf" >&6; } ;; esac -need_locks="$enable_libtool_lock" +need_locks=$enable_libtool_lock if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. @@ -7145,7 +7794,7 @@ else fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 $as_echo "$lt_cv_path_mainfest_tool" >&6; } -if test "x$lt_cv_path_mainfest_tool" != xyes; then +if test yes != "$lt_cv_path_mainfest_tool"; then MANIFEST_TOOL=: fi @@ -7648,7 +8297,7 @@ if ${lt_cv_apple_cc_single_mod+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_apple_cc_single_mod=no - if test -z "${LT_MULTI_MODULE}"; then + if test -z "$LT_MULTI_MODULE"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the @@ -7666,7 +8315,7 @@ else cat conftest.err >&5 # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. - elif test -f libconftest.dylib && test $_lt_result -eq 0; then + elif test -f libconftest.dylib && test 0 = "$_lt_result"; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&5 @@ -7705,7 +8354,7 @@ else fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext - LDFLAGS="$save_LDFLAGS" + LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 @@ -7734,7 +8383,7 @@ _LT_EOF _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&5 - elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then + elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then lt_cv_ld_force_load=yes else cat conftest.err >&5 @@ -7747,32 +8396,32 @@ fi $as_echo "$lt_cv_ld_force_load" >&6; } case $host_os in rhapsody* | darwin1.[012]) - _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[91]*) - _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; 10.[012]*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; 10.*) - _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; esac - if test "$lt_cv_apple_cc_single_mod" = "yes"; then + if test yes = "$lt_cv_apple_cc_single_mod"; then _lt_dar_single_mod='$single_module' fi - if test "$lt_cv_ld_exported_symbols_list" = "yes"; then - _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + if test yes = "$lt_cv_ld_exported_symbols_list"; then + _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' else - _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' fi - if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then + if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= @@ -8063,6 +8712,17 @@ done +func_stripname_cnf () +{ + case $2 in + .*) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%\\\\$2\$%%"`;; + *) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%$2\$%%"`;; + esac +} # func_stripname_cnf + + + + # Set options @@ -8083,14 +8743,14 @@ if test "${enable_shared+set}" = set; then : *) enable_shared=no # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_shared=yes fi done - IFS="$lt_save_ifs" + IFS=$lt_save_ifs ;; esac else @@ -8114,14 +8774,14 @@ if test "${enable_static+set}" = set; then : *) enable_static=no # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_static=yes fi done - IFS="$lt_save_ifs" + IFS=$lt_save_ifs ;; esac else @@ -8145,14 +8805,14 @@ if test "${with_pic+set}" = set; then : *) pic_mode=default # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for lt_pkg in $withval; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done - IFS="$lt_save_ifs" + IFS=$lt_save_ifs ;; esac else @@ -8160,8 +8820,6 @@ else fi -test -z "$pic_mode" && pic_mode=default - @@ -8177,14 +8835,14 @@ if test "${enable_fast_install+set}" = set; then : *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done - IFS="$lt_save_ifs" + IFS=$lt_save_ifs ;; esac else @@ -8202,7 +8860,7 @@ fi # This can be used to rebuild libtool when needed -LIBTOOL_DEPS="$ltmain" +LIBTOOL_DEPS=$ltmain # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' @@ -8251,7 +8909,7 @@ test -z "$LN_S" && LN_S="ln -s" -if test -n "${ZSH_VERSION+set}" ; then +if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi @@ -8290,7 +8948,7 @@ aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. - if test "X${COLLECT_NAMES+set}" != Xset; then + if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi @@ -8301,14 +8959,14 @@ esac ofile=libtool can_build_shared=yes -# All known linkers require a `.a' archive for static linking (except MSVC, +# All known linkers require a '.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a -with_gnu_ld="$lt_cv_prog_gnu_ld" +with_gnu_ld=$lt_cv_prog_gnu_ld -old_CC="$CC" -old_CFLAGS="$CFLAGS" +old_CC=$CC +old_CFLAGS=$CFLAGS # Set sane defaults for various variables test -z "$CC" && CC=cc @@ -8340,22 +8998,22 @@ if ${lt_cv_path_MAGIC_CMD+:} false; then : else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) - lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) - lt_save_MAGIC_CMD="$MAGIC_CMD" - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/${ac_tool_prefix}file; then - lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" + if test -f "$ac_dir/${ac_tool_prefix}file"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` - MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : @@ -8378,13 +9036,13 @@ _LT_EOF break fi done - IFS="$lt_save_ifs" - MAGIC_CMD="$lt_save_MAGIC_CMD" + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac fi -MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } @@ -8406,22 +9064,22 @@ if ${lt_cv_path_MAGIC_CMD+:} false; then : else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) - lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) - lt_save_MAGIC_CMD="$MAGIC_CMD" - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/file; then - lt_cv_path_MAGIC_CMD="$ac_dir/file" + if test -f "$ac_dir/file"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` - MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : @@ -8444,13 +9102,13 @@ _LT_EOF break fi done - IFS="$lt_save_ifs" - MAGIC_CMD="$lt_save_MAGIC_CMD" + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac fi -MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } @@ -8471,7 +9129,7 @@ esac # Use C for the default configuration in the libtool script -lt_save_CC="$CC" +lt_save_CC=$CC ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -8533,7 +9191,7 @@ if test -n "$compiler"; then lt_prog_compiler_no_builtin_flag= -if test "$GCC" = yes; then +if test yes = "$GCC"; then case $cc_basename in nvcc*) lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; @@ -8549,7 +9207,7 @@ else lt_cv_prog_compiler_rtti_exceptions=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="-fno-rtti -fno-exceptions" + lt_compiler_flag="-fno-rtti -fno-exceptions" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins @@ -8579,7 +9237,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 $as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } -if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then +if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" else : @@ -8597,17 +9255,18 @@ lt_prog_compiler_pic= lt_prog_compiler_static= - if test "$GCC" = yes; then + if test yes = "$GCC"; then lt_prog_compiler_wl='-Wl,' lt_prog_compiler_static='-static' case $host_os in aix*) # All AIX code is PIC. - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' fi + lt_prog_compiler_pic='-fPIC' ;; amigaos*) @@ -8618,8 +9277,8 @@ lt_prog_compiler_static= ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' ;; esac @@ -8705,7 +9364,7 @@ lt_prog_compiler_static= case $host_os in aix*) lt_prog_compiler_wl='-Wl,' - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' else @@ -8713,6 +9372,20 @@ lt_prog_compiler_static= fi ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + case $cc_basename in + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + esac + ;; + mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). @@ -8732,7 +9405,7 @@ lt_prog_compiler_static= ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? - lt_prog_compiler_static='${wl}-a ${wl}archive' + lt_prog_compiler_static='$wl-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) @@ -8741,9 +9414,9 @@ lt_prog_compiler_static= lt_prog_compiler_static='-non_shared' ;; - linux* | k*bsd*-gnu | kopensolaris*-gnu) + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in - # old Intel for x86_64 which still supported -KPIC. + # old Intel for x86_64, which still supported -KPIC. ecc*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' @@ -8768,6 +9441,12 @@ lt_prog_compiler_static= lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) @@ -8865,7 +9544,7 @@ lt_prog_compiler_static= ;; sysv4*MP*) - if test -d /usr/nec ;then + if test -d /usr/nec; then lt_prog_compiler_pic='-Kconform_pic' lt_prog_compiler_static='-Bstatic' fi @@ -8894,7 +9573,7 @@ lt_prog_compiler_static= fi case $host_os in - # For platforms which do not support PIC, -DPIC is meaningless: + # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic= ;; @@ -8926,7 +9605,7 @@ else lt_cv_prog_compiler_pic_works=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="$lt_prog_compiler_pic -DPIC" + lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins @@ -8956,7 +9635,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 $as_echo "$lt_cv_prog_compiler_pic_works" >&6; } -if test x"$lt_cv_prog_compiler_pic_works" = xyes; then +if test yes = "$lt_cv_prog_compiler_pic_works"; then case $lt_prog_compiler_pic in "" | " "*) ;; *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; @@ -8988,7 +9667,7 @@ if ${lt_cv_prog_compiler_static_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_static_works=no - save_LDFLAGS="$LDFLAGS" + save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then @@ -9007,13 +9686,13 @@ else fi fi $RM -r conftest* - LDFLAGS="$save_LDFLAGS" + LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 $as_echo "$lt_cv_prog_compiler_static_works" >&6; } -if test x"$lt_cv_prog_compiler_static_works" = xyes; then +if test yes = "$lt_cv_prog_compiler_static_works"; then : else lt_prog_compiler_static= @@ -9133,8 +9812,8 @@ $as_echo "$lt_cv_prog_compiler_c_o" >&6; } -hard_links="nottested" -if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then +hard_links=nottested +if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 $as_echo_n "checking if we can lock with hard links... " >&6; } @@ -9146,9 +9825,9 @@ $as_echo_n "checking if we can lock with hard links... " >&6; } ln conftest.a conftest.b 2>/dev/null && hard_links=no { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 $as_echo "$hard_links" >&6; } - if test "$hard_links" = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 -$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + if test no = "$hard_links"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} need_locks=warn fi else @@ -9191,9 +9870,9 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie # included in the symbol list include_expsyms= # exclude_expsyms can be an extended regexp of symbols to exclude - # it will be wrapped by ` (' and `)$', so one must not match beginning or - # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', - # as well as any symbol that contains `d'. + # it will be wrapped by ' (' and ')$', so one must not match beginning or + # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', + # as well as any symbol that contains 'd'. exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if @@ -9208,7 +9887,7 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. - if test "$GCC" != yes; then + if test yes != "$GCC"; then with_gnu_ld=no fi ;; @@ -9216,7 +9895,7 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; - openbsd*) + openbsd* | bitrig*) with_gnu_ld=no ;; esac @@ -9226,7 +9905,7 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no - if test "$with_gnu_ld" = yes; then + if test yes = "$with_gnu_ld"; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility @@ -9248,24 +9927,24 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie esac fi - if test "$lt_use_gnu_ld_interface" = yes; then + if test yes = "$lt_use_gnu_ld_interface"; then # If archive_cmds runs LD, not CC, wlarc should be empty - wlarc='${wl}' + wlarc='$wl' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - export_dynamic_flag_spec='${wl}--export-dynamic' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + export_dynamic_flag_spec='$wl--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then - whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else whole_archive_flag_spec= fi supports_anon_versioning=no - case `$LD -v 2>&1` in + case `$LD -v | $SED -e 's/(^)\+)\s\+//' 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... @@ -9278,7 +9957,7 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie case $host_os in aix[3-9]*) # On AIX/PPC, the GNU linker is very broken - if test "$host_cpu" != ia64; then + if test ia64 != "$host_cpu"; then ld_shlibs=no cat <<_LT_EOF 1>&2 @@ -9297,7 +9976,7 @@ _LT_EOF case $host_cpu in powerpc) # see comment about AmigaOS4 .so support - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) @@ -9313,7 +9992,7 @@ _LT_EOF allow_undefined_flag=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME - archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else ld_shlibs=no fi @@ -9323,7 +10002,7 @@ _LT_EOF # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' - export_dynamic_flag_spec='${wl}--export-all-symbols' + export_dynamic_flag_spec='$wl--export-all-symbols' allow_undefined_flag=unsupported always_export_symbols=no enable_shared_with_static_runtimes=yes @@ -9331,61 +10010,61 @@ _LT_EOF exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs=no fi ;; haiku*) - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' link_all_deplibs=yes ;; interix[3-9]*) hardcode_direct=no hardcode_shlibpath_var=no - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - export_dynamic_flag_spec='${wl}-E' + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + export_dynamic_flag_spec='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no - if test "$host_os" = linux-dietlibc; then + if test linux-dietlibc = "$host_os"; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ - && test "$tmp_diet" = no + && test no = "$tmp_diet" then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler - whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers - whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; @@ -9396,42 +10075,44 @@ _LT_EOF lf95*) # Lahey Fortran 8.1 whole_archive_flag_spec= tmp_sharedflag='--shared' ;; + nagfor*) # NAGFOR 5.3 + tmp_sharedflag='-Wl,-shared' ;; xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 - whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 - whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac - archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - if test "x$supports_anon_versioning" = xyes; then + if test yes = "$supports_anon_versioning"; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi case $cc_basename in xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' - if test "x$supports_anon_versioning" = xyes; then + if test yes = "$supports_anon_versioning"; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac @@ -9445,8 +10126,8 @@ _LT_EOF archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' fi ;; @@ -9464,8 +10145,8 @@ _LT_EOF _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi @@ -9477,7 +10158,7 @@ _LT_EOF ld_shlibs=no cat <<_LT_EOF 1>&2 -*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify @@ -9492,9 +10173,9 @@ _LT_EOF # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi @@ -9511,15 +10192,15 @@ _LT_EOF *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac - if test "$ld_shlibs" = no; then + if test no = "$ld_shlibs"; then runpath_var= hardcode_libdir_flag_spec= export_dynamic_flag_spec= @@ -9535,7 +10216,7 @@ _LT_EOF # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes - if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported @@ -9543,12 +10224,12 @@ _LT_EOF ;; aix[4-9]*) - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' - no_entry_flag="" + no_entry_flag= else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm @@ -9566,7 +10247,7 @@ _LT_EOF # need to do runtime linking. case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do - if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then aix_use_runtimelinking=yes break fi @@ -9589,13 +10270,13 @@ _LT_EOF hardcode_direct_absolute=yes hardcode_libdir_separator=':' link_all_deplibs=yes - file_list_spec='${wl}-f,' + file_list_spec='$wl-f,' - if test "$GCC" = yes; then + if test yes = "$GCC"; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` + collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then @@ -9614,35 +10295,35 @@ _LT_EOF ;; esac shared_flag='-shared' - if test "$aix_use_runtimelinking" = yes; then - shared_flag="$shared_flag "'${wl}-G' + if test yes = "$aix_use_runtimelinking"; then + shared_flag="$shared_flag "'$wl-G' fi else # not using gcc - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' else - shared_flag='${wl}-bM:SRE' + shared_flag='$wl-bM:SRE' fi fi fi - export_dynamic_flag_spec='${wl}-bexpall' + export_dynamic_flag_spec='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. always_export_symbols=yes - if test "$aix_use_runtimelinking" = yes; then + if test yes = "$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag='-berok' # Determine the default libpath from the value encoded in an # empty executable. - if test "${lt_cv_aix_libpath+set}" = set; then + if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : @@ -9677,7 +10358,7 @@ fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then - lt_cv_aix_libpath_="/usr/lib:/lib" + lt_cv_aix_libpath_=/usr/lib:/lib fi fi @@ -9685,17 +10366,17 @@ fi aix_libpath=$lt_cv_aix_libpath_ fi - hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" - archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else - if test "$host_cpu" = ia64; then - hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + if test ia64 = "$host_cpu"; then + hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib' allow_undefined_flag="-z nodefs" - archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. - if test "${lt_cv_aix_libpath+set}" = set; then + if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : @@ -9730,7 +10411,7 @@ fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then - lt_cv_aix_libpath_="/usr/lib:/lib" + lt_cv_aix_libpath_=/usr/lib:/lib fi fi @@ -9738,21 +10419,21 @@ fi aix_libpath=$lt_cv_aix_libpath_ fi - hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. - no_undefined_flag=' ${wl}-bernotok' - allow_undefined_flag=' ${wl}-berok' - if test "$with_gnu_ld" = yes; then + no_undefined_flag=' $wl-bernotok' + allow_undefined_flag=' $wl-berok' + if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. - whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec='$convenience' fi archive_cmds_need_lc=yes # This is similar to how AIX traditionally builds its shared libraries. - archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $wl-bnoentry $compiler_flags $wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; @@ -9761,7 +10442,7 @@ fi case $host_cpu in powerpc) # see comment about AmigaOS4 .so support - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) @@ -9791,16 +10472,17 @@ fi # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" + shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. - archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' - archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; - else - sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; - fi~ - $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ - linknames=' + archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, )='true' enable_shared_with_static_runtimes=yes @@ -9809,18 +10491,18 @@ fi # Don't use ranlib old_postinstall_cmds='chmod 644 $oldlib' postlink_cmds='lt_outputfile="@OUTPUT@"~ - lt_tool_outputfile="@TOOL_OUTPUT@"~ - case $lt_outputfile in - *.exe|*.EXE) ;; - *) - lt_outputfile="$lt_outputfile.exe" - lt_tool_outputfile="$lt_tool_outputfile.exe" - ;; - esac~ - if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then - $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; - $RM "$lt_outputfile.manifest"; - fi' + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' ;; *) # Assume MSVC wrapper @@ -9829,7 +10511,7 @@ fi # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" + shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. @@ -9848,24 +10530,24 @@ fi hardcode_direct=no hardcode_automatic=yes hardcode_shlibpath_var=unsupported - if test "$lt_cv_ld_force_load" = "yes"; then - whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + if test yes = "$lt_cv_ld_force_load"; then + whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec='' fi link_all_deplibs=yes - allow_undefined_flag="$_lt_dar_allow_undefined" + allow_undefined_flag=$_lt_dar_allow_undefined case $cc_basename in - ifort*) _lt_dar_can_shared=yes ;; + ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac - if test "$_lt_dar_can_shared" = "yes"; then + if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all - archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" - module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" - archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" - module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" + archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + module_expsym_cmds="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" else ld_shlibs=no @@ -9907,33 +10589,33 @@ fi ;; hpux9*) - if test "$GCC" = yes; then - archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + if test yes = "$GCC"; then + archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else - archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' fi - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes - export_dynamic_flag_spec='${wl}-E' + export_dynamic_flag_spec='$wl-E' ;; hpux10*) - if test "$GCC" = yes && test "$with_gnu_ld" = no; then - archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + if test yes,no = "$GCC,$with_gnu_ld"; then + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi - if test "$with_gnu_ld" = no; then - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: hardcode_direct=yes hardcode_direct_absolute=yes - export_dynamic_flag_spec='${wl}-E' + export_dynamic_flag_spec='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes @@ -9941,25 +10623,25 @@ fi ;; hpux11*) - if test "$GCC" = yes && test "$with_gnu_ld" = no; then + if test yes,no = "$GCC,$with_gnu_ld"; then case $host_cpu in hppa*64*) - archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) - archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) - archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) - archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) - archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) @@ -9971,7 +10653,7 @@ if ${lt_cv_prog_compiler__b+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler__b=no - save_LDFLAGS="$LDFLAGS" + save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -b" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then @@ -9990,14 +10672,14 @@ else fi fi $RM -r conftest* - LDFLAGS="$save_LDFLAGS" + LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 $as_echo "$lt_cv_prog_compiler__b" >&6; } -if test x"$lt_cv_prog_compiler__b" = xyes; then - archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' +if test yes = "$lt_cv_prog_compiler__b"; then + archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi @@ -10005,8 +10687,8 @@ fi ;; esac fi - if test "$with_gnu_ld" = no; then - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: case $host_cpu in @@ -10017,7 +10699,7 @@ fi *) hardcode_direct=yes hardcode_direct_absolute=yes - export_dynamic_flag_spec='${wl}-E' + export_dynamic_flag_spec='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. @@ -10028,8 +10710,8 @@ fi ;; irix5* | irix6* | nonstopux*) - if test "$GCC" = yes; then - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + if test yes = "$GCC"; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. @@ -10039,8 +10721,8 @@ $as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " > if ${lt_cv_irix_exported_symbol+:} false; then : $as_echo_n "(cached) " >&6 else - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int foo (void) { return 0; } @@ -10052,19 +10734,19 @@ else fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext - LDFLAGS="$save_LDFLAGS" + LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 $as_echo "$lt_cv_irix_exported_symbol" >&6; } - if test "$lt_cv_irix_exported_symbol" = yes; then - archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + if test yes = "$lt_cv_irix_exported_symbol"; then + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' fi else - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' fi archive_cmds_need_lc='no' - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: inherit_rpath=yes link_all_deplibs=yes @@ -10084,7 +10766,7 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; } newsos6) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: hardcode_shlibpath_var=no ;; @@ -10092,27 +10774,19 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; } *nto* | *qnx*) ;; - openbsd*) + openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then hardcode_direct=yes hardcode_shlibpath_var=no hardcode_direct_absolute=yes - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - export_dynamic_flag_spec='${wl}-E' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + export_dynamic_flag_spec='$wl-E' else - case $host_os in - openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec='-R$libdir' - ;; - *) - archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - ;; - esac + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='$wl-rpath,$libdir' fi else ld_shlibs=no @@ -10128,28 +10802,28 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; } ;; osf3*) - if test "$GCC" = yes; then - allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + if test yes = "$GCC"; then + allow_undefined_flag=' $wl-expect_unresolved $wl\*' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else allow_undefined_flag=' -expect_unresolved \*' - archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' fi archive_cmds_need_lc='no' - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag - if test "$GCC" = yes; then - allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + if test yes = "$GCC"; then + allow_undefined_flag=' $wl-expect_unresolved $wl\*' + archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' else allow_undefined_flag=' -expect_unresolved \*' - archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ - $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly hardcode_libdir_flag_spec='-rpath $libdir' @@ -10160,24 +10834,24 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; } solaris*) no_undefined_flag=' -z defs' - if test "$GCC" = yes; then - wlarc='${wl}' - archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + if test yes = "$GCC"; then + wlarc='$wl' + archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' - archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) - wlarc='${wl}' - archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' + wlarc='$wl' + archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi @@ -10187,11 +10861,11 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; } solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, - # but understands `-z linker_flag'. GCC discards it without `$wl', + # but understands '-z linker_flag'. GCC discards it without '$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) - if test "$GCC" = yes; then - whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + if test yes = "$GCC"; then + whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' else whole_archive_flag_spec='-z allextract$convenience -z defaultextract' fi @@ -10201,10 +10875,10 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; } ;; sunos4*) - if test "x$host_vendor" = xsequent; then + if test sequent = "$host_vendor"; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. - archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi @@ -10253,43 +10927,43 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; } ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) - no_undefined_flag='${wl}-z,text' + no_undefined_flag='$wl-z,text' archive_cmds_need_lc=no hardcode_shlibpath_var=no runpath_var='LD_RUN_PATH' - if test "$GCC" = yes; then - archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + if test yes = "$GCC"; then + archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else - archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) - # Note: We can NOT use -z defs as we might desire, because we do not + # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. - no_undefined_flag='${wl}-z,text' - allow_undefined_flag='${wl}-z,nodefs' + no_undefined_flag='$wl-z,text' + allow_undefined_flag='$wl-z,nodefs' archive_cmds_need_lc=no hardcode_shlibpath_var=no - hardcode_libdir_flag_spec='${wl}-R,$libdir' + hardcode_libdir_flag_spec='$wl-R,$libdir' hardcode_libdir_separator=':' link_all_deplibs=yes - export_dynamic_flag_spec='${wl}-Bexport' + export_dynamic_flag_spec='$wl-Bexport' runpath_var='LD_RUN_PATH' - if test "$GCC" = yes; then - archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + if test yes = "$GCC"; then + archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else - archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; @@ -10304,10 +10978,10 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; } ;; esac - if test x$host_vendor = xsni; then + if test sni = "$host_vendor"; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - export_dynamic_flag_spec='${wl}-Blargedynsym' + export_dynamic_flag_spec='$wl-Blargedynsym' ;; esac fi @@ -10315,7 +10989,7 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 $as_echo "$ld_shlibs" >&6; } -test "$ld_shlibs" = no && can_build_shared=no +test no = "$ld_shlibs" && can_build_shared=no with_gnu_ld=$with_gnu_ld @@ -10341,7 +11015,7 @@ x|xyes) # Assume -lc should be added archive_cmds_need_lc=yes - if test "$enable_shared" = yes && test "$GCC" = yes; then + if test yes,yes = "$GCC,$enable_shared"; then case $archive_cmds in *'~'*) # FIXME: we may have to deal with multi-command sequences. @@ -10556,14 +11230,14 @@ esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 $as_echo_n "checking dynamic linker characteristics... " >&6; } -if test "$GCC" = yes; then +if test yes = "$GCC"; then case $host_os in - darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; - *) lt_awk_arg="/^libraries:/" ;; + darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; + *) lt_awk_arg='/^libraries:/' ;; esac case $host_os in - mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;; - *) lt_sed_strip_eq="s,=/,/,g" ;; + mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;; + *) lt_sed_strip_eq='s|=/|/|g' ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in @@ -10579,28 +11253,35 @@ if test "$GCC" = yes; then ;; esac # Ok, now we have the path, separated by spaces, we can step through it - # and add multilib dir if necessary. + # and add multilib dir if necessary... lt_tmp_lt_search_path_spec= - lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + # ...but if some path component already ends with the multilib dir we assume + # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). + case "$lt_multi_os_dir; $lt_search_path_spec " in + "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) + lt_multi_os_dir= + ;; + esac for lt_sys_path in $lt_search_path_spec; do - if test -d "$lt_sys_path/$lt_multi_os_dir"; then - lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" - else + if test -d "$lt_sys_path$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" + elif test -n "$lt_multi_os_dir"; then test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' -BEGIN {RS=" "; FS="/|\n";} { - lt_foo=""; - lt_count=0; +BEGIN {RS = " "; FS = "/|\n";} { + lt_foo = ""; + lt_count = 0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { - lt_foo="/" $lt_i lt_foo; + lt_foo = "/" $lt_i lt_foo; } else { lt_count--; } @@ -10614,7 +11295,7 @@ BEGIN {RS=" "; FS="/|\n";} { # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ - $SED 's,/\([A-Za-z]:\),\1,g'` ;; + $SED 's|/\([A-Za-z]:\)|\1|g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else @@ -10623,7 +11304,7 @@ fi library_names_spec= libname_spec='lib$name' soname_spec= -shrext_cmds=".so" +shrext_cmds=.so postinstall_cmds= postuninstall_cmds= finish_cmds= @@ -10643,11 +11324,11 @@ need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + library_names_spec='$libname$release$shared_ext$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. - soname_spec='${libname}${release}${shared_ext}$major' + soname_spec='$libname$release$shared_ext$major' ;; aix[4-9]*) @@ -10655,40 +11336,40 @@ aix[4-9]*) need_lib_prefix=no need_version=no hardcode_into_libs=yes - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # AIX 5 supports IA64 - library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with - # the line `#! .'. This would cause the generated library to - # depend on `.', always an invalid library. This was fixed in + # the line '#! .'. This would cause the generated library to + # depend on '.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' - echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac - # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. - if test "$aix_use_runtimelinking" = yes; then + if test yes = "$aix_use_runtimelinking"; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. - library_names_spec='${libname}${release}.a $libname.a' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' fi shlibpath_var=LIBPATH fi @@ -10699,18 +11380,18 @@ amigaos*) powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. - finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) - library_names_spec='${libname}${shared_ext}' + library_names_spec='$libname$shared_ext' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; @@ -10718,8 +11399,8 @@ beos*) bsdi[45]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" @@ -10731,7 +11412,7 @@ bsdi[45]*) cygwin* | mingw* | pw32* | cegcc*) version_type=windows - shrext_cmds=".dll" + shrext_cmds=.dll need_version=no need_lib_prefix=no @@ -10740,8 +11421,8 @@ cygwin* | mingw* | pw32* | cegcc*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ @@ -10757,17 +11438,17 @@ cygwin* | mingw* | pw32* | cegcc*) case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' - soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix - soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' @@ -10776,8 +11457,8 @@ cygwin* | mingw* | pw32* | cegcc*) *,cl*) # Native MSVC libname_spec='$name' - soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - library_names_spec='${libname}.dll.lib' + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + library_names_spec='$libname.dll.lib' case $build_os in mingw*) @@ -10804,7 +11485,7 @@ cygwin* | mingw* | pw32* | cegcc*) sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) - sys_lib_search_path_spec="$LIB" + sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` @@ -10817,8 +11498,8 @@ cygwin* | mingw* | pw32* | cegcc*) esac # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' @@ -10831,7 +11512,7 @@ cygwin* | mingw* | pw32* | cegcc*) *) # Assume MSVC wrapper - library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac @@ -10844,8 +11525,8 @@ darwin* | rhapsody*) version_type=darwin need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' - soname_spec='${libname}${release}${major}$shared_ext' + library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' + soname_spec='$libname$release$major$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' @@ -10858,8 +11539,8 @@ dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; @@ -10877,12 +11558,12 @@ freebsd* | dragonfly*) version_type=freebsd-$objformat case $version_type in freebsd-elf*) - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' need_version=no need_lib_prefix=no ;; freebsd-*) - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' need_version=yes ;; esac @@ -10907,26 +11588,15 @@ freebsd* | dragonfly*) esac ;; -gnu*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH - shlibpath_overrides_runpath=yes + shlibpath_overrides_runpath=no sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; @@ -10944,9 +11614,9 @@ hpux9* | hpux10* | hpux11*) dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - if test "X$HPUX_IA64_MODE" = X32; then + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + if test 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" @@ -10959,8 +11629,8 @@ hpux9* | hpux10* | hpux11*) dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; @@ -10969,8 +11639,8 @@ hpux9* | hpux10* | hpux11*) dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... @@ -10983,8 +11653,8 @@ interix[3-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no @@ -10995,7 +11665,7 @@ irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) - if test "$lt_cv_prog_gnu_ld" = yes; then + if test yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix @@ -11003,8 +11673,8 @@ irix5* | irix6* | nonstopux*) esac need_lib_prefix=no need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= @@ -11023,8 +11693,8 @@ irix5* | irix6* | nonstopux*) esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" + sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" hardcode_into_libs=yes ;; @@ -11033,13 +11703,33 @@ linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; +linux*android*) + version_type=none # Android doesn't support versioned libraries. + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + dynamic_linker='Android linker' + # Don't embed -rpath directories since the linker doesn't support them. + hardcode_libdir_flag_spec='-L$libdir' + ;; + # This must be glibc/ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu) +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no @@ -11083,14 +11773,10 @@ fi # before this can be enabled. hardcode_into_libs=yes - # Add ABI-specific directories to the system library path. - sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib" - # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` - sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra" - + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on @@ -11107,12 +11793,12 @@ netbsd*) need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH @@ -11122,7 +11808,7 @@ netbsd*) newsos6) version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; @@ -11131,45 +11817,34 @@ newsos6) version_type=qnx need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; -openbsd*) +openbsd* | bitrig*) version_type=sunos - sys_lib_dlsearch_path_spec="/usr/lib" + sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no - # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. - case $host_os in - openbsd3.3 | openbsd3.3.*) need_version=yes ;; - *) need_version=no ;; - esac - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - shlibpath_var=LD_LIBRARY_PATH - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - case $host_os in - openbsd2.[89] | openbsd2.[89].*) - shlibpath_overrides_runpath=no - ;; - *) - shlibpath_overrides_runpath=yes - ;; - esac + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + need_version=no else - shlibpath_overrides_runpath=yes + need_version=yes fi + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' - shrext_cmds=".dll" + shrext_cmds=.dll need_lib_prefix=no - library_names_spec='$libname${shared_ext} $libname.a' + library_names_spec='$libname$shared_ext $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; @@ -11178,11 +11853,11 @@ osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" - sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; rdos*) @@ -11193,8 +11868,8 @@ solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes @@ -11204,11 +11879,11 @@ solaris*) sunos4*) version_type=sunos - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes - if test "$with_gnu_ld" = yes; then + if test yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes @@ -11216,8 +11891,8 @@ sunos4*) sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) @@ -11238,10 +11913,10 @@ sysv4 | sysv4.3*) ;; sysv4*MP*) - if test -d /usr/nec ;then + if test -d /usr/nec; then version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' - soname_spec='$libname${shared_ext}.$major' + library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' + soname_spec='$libname$shared_ext.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; @@ -11250,12 +11925,12 @@ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes - if test "$with_gnu_ld" = yes; then + if test yes = "$with_gnu_ld"; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' @@ -11273,7 +11948,7 @@ tpf*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes @@ -11281,8 +11956,8 @@ tpf*) uts4*) version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; @@ -11292,18 +11967,18 @@ uts4*) esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 $as_echo "$dynamic_linker" >&6; } -test "$dynamic_linker" = no && can_build_shared=no +test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then +if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi -if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then - sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then + sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi -if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then - sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then + sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi @@ -11402,15 +12077,15 @@ $as_echo_n "checking how to hardcode library paths into programs... " >&6; } hardcode_action= if test -n "$hardcode_libdir_flag_spec" || test -n "$runpath_var" || - test "X$hardcode_automatic" = "Xyes" ; then + test yes = "$hardcode_automatic"; then # We can hardcode non-existent directories. - if test "$hardcode_direct" != no && + if test no != "$hardcode_direct" && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one - ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && - test "$hardcode_minus_L" != no; then + ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" && + test no != "$hardcode_minus_L"; then # Linking always hardcodes the temporary library directory. hardcode_action=relink else @@ -11425,12 +12100,12 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 $as_echo "$hardcode_action" >&6; } -if test "$hardcode_action" = relink || - test "$inherit_rpath" = yes; then +if test relink = "$hardcode_action" || + test yes = "$inherit_rpath"; then # Fast installation is not supported enable_fast_install=no -elif test "$shlibpath_overrides_runpath" = yes || - test "$enable_shared" = no; then +elif test yes = "$shlibpath_overrides_runpath" || + test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi @@ -11440,7 +12115,7 @@ fi - if test "x$enable_dlopen" != xyes; then + if test yes != "$enable_dlopen"; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown @@ -11450,23 +12125,23 @@ else case $host_os in beos*) - lt_cv_dlopen="load_add_on" + lt_cv_dlopen=load_add_on lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) - lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen=LoadLibrary lt_cv_dlopen_libs= ;; cygwin*) - lt_cv_dlopen="dlopen" + lt_cv_dlopen=dlopen lt_cv_dlopen_libs= ;; darwin*) - # if libdl is installed we need to link against it + # if libdl is installed we need to link against it { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : @@ -11504,10 +12179,10 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl else - lt_cv_dlopen="dyld" + lt_cv_dlopen=dyld lt_cv_dlopen_libs= lt_cv_dlopen_self=yes @@ -11515,10 +12190,18 @@ fi ;; + tpf*) + # Don't try to run any link tests for TPF. We know it's impossible + # because TPF is a cross-compiler, and we know how we open DSOs. + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + lt_cv_dlopen_self=no + ;; + *) ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" if test "x$ac_cv_func_shl_load" = xyes; then : - lt_cv_dlopen="shl_load" + lt_cv_dlopen=shl_load else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 $as_echo_n "checking for shl_load in -ldld... " >&6; } @@ -11557,11 +12240,11 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 $as_echo "$ac_cv_lib_dld_shl_load" >&6; } if test "x$ac_cv_lib_dld_shl_load" = xyes; then : - lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" + lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld else ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" if test "x$ac_cv_func_dlopen" = xyes; then : - lt_cv_dlopen="dlopen" + lt_cv_dlopen=dlopen else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } @@ -11600,7 +12283,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 $as_echo_n "checking for dlopen in -lsvld... " >&6; } @@ -11639,7 +12322,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 $as_echo "$ac_cv_lib_svld_dlopen" >&6; } if test "x$ac_cv_lib_svld_dlopen" = xyes; then : - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 $as_echo_n "checking for dld_link in -ldld... " >&6; } @@ -11678,7 +12361,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 $as_echo "$ac_cv_lib_dld_dld_link" >&6; } if test "x$ac_cv_lib_dld_dld_link" = xyes; then : - lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" + lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld fi @@ -11699,21 +12382,21 @@ fi ;; esac - if test "x$lt_cv_dlopen" != xno; then - enable_dlopen=yes - else + if test no = "$lt_cv_dlopen"; then enable_dlopen=no + else + enable_dlopen=yes fi case $lt_cv_dlopen in dlopen) - save_CPPFLAGS="$CPPFLAGS" - test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + save_CPPFLAGS=$CPPFLAGS + test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" - save_LDFLAGS="$LDFLAGS" + save_LDFLAGS=$LDFLAGS wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" - save_LIBS="$LIBS" + save_LIBS=$LIBS LIBS="$lt_cv_dlopen_libs $LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 @@ -11721,7 +12404,7 @@ $as_echo_n "checking whether a program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self+:} false; then : $as_echo_n "(cached) " >&6 else - if test "$cross_compiling" = yes; then : + if test yes = "$cross_compiling"; then : lt_cv_dlopen_self=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 @@ -11770,7 +12453,7 @@ else /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ -#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif @@ -11800,7 +12483,7 @@ _LT_EOF (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in @@ -11820,14 +12503,14 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 $as_echo "$lt_cv_dlopen_self" >&6; } - if test "x$lt_cv_dlopen_self" = xyes; then + if test yes = "$lt_cv_dlopen_self"; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 $as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self_static+:} false; then : $as_echo_n "(cached) " >&6 else - if test "$cross_compiling" = yes; then : + if test yes = "$cross_compiling"; then : lt_cv_dlopen_self_static=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 @@ -11876,7 +12559,7 @@ else /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ -#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif @@ -11906,7 +12589,7 @@ _LT_EOF (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in @@ -11923,26 +12606,3214 @@ rm -fr conftest* fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 -$as_echo "$lt_cv_dlopen_self_static" >&6; } - fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 +$as_echo "$lt_cv_dlopen_self_static" >&6; } + fi + + CPPFLAGS=$save_CPPFLAGS + LDFLAGS=$save_LDFLAGS + LIBS=$save_LIBS + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + + + + + + + + + + + + + + + + +striplib= +old_striplib= +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 +$as_echo_n "checking whether stripping libraries is possible... " >&6; } +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP"; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + { $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 + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + ;; + esac +fi + + + + + + + + + + + + + # Report what library types will actually be built + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 +$as_echo_n "checking if libtool supports shared libraries... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 +$as_echo "$can_build_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 +$as_echo_n "checking whether to build shared libraries... " >&6; } + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[4-9]*) + if test ia64 != "$host_cpu" && test no = "$aix_use_runtimelinking"; then + test yes = "$enable_shared" && enable_static=no + fi + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 +$as_echo "$enable_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 +$as_echo_n "checking whether to build static libraries... " >&6; } + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 +$as_echo "$enable_static" >&6; } + + + + +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC=$lt_save_CC + + if test -n "$CXX" && ( test no != "$CXX" && + ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || + (test g++ != "$CXX"))); then + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 +$as_echo_n "checking how to run the C++ preprocessor... " >&6; } +if test -z "$CXXCPP"; then + if ${ac_cv_prog_CXXCPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CXXCPP needs to be expanded + for CXXCPP in "$CXX -E" "/lib/cpp" + do + ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CXXCPP=$CXXCPP + +fi + CXXCPP=$ac_cv_prog_CXXCPP +else + ac_cv_prog_CXXCPP=$CXXCPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 +$as_echo "$CXXCPP" >&6; } +ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +else + _lt_caught_CXX_error=yes +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +archive_cmds_need_lc_CXX=no +allow_undefined_flag_CXX= +always_export_symbols_CXX=no +archive_expsym_cmds_CXX= +compiler_needs_object_CXX=no +export_dynamic_flag_spec_CXX= +hardcode_direct_CXX=no +hardcode_direct_absolute_CXX=no +hardcode_libdir_flag_spec_CXX= +hardcode_libdir_separator_CXX= +hardcode_minus_L_CXX=no +hardcode_shlibpath_var_CXX=unsupported +hardcode_automatic_CXX=no +inherit_rpath_CXX=no +module_cmds_CXX= +module_expsym_cmds_CXX= +link_all_deplibs_CXX=unknown +old_archive_cmds_CXX=$old_archive_cmds +reload_flag_CXX=$reload_flag +reload_cmds_CXX=$reload_cmds +no_undefined_flag_CXX= +whole_archive_flag_spec_CXX= +enable_shared_with_static_runtimes_CXX=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +objext_CXX=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test yes != "$_lt_caught_CXX_error"; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + + # save warnings/boilerplate of simple test code + ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + + ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_CFLAGS=$CFLAGS + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + CFLAGS=$CXXFLAGS + compiler=$CC + compiler_CXX=$CC + for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` + + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test yes = "$GXX"; then + lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' + else + lt_prog_compiler_no_builtin_flag_CXX= + fi + + if test yes = "$GXX"; then + # Set up default GNU C++ configuration + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test yes = "$GCC"; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return, which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD=$ac_prog + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test yes = "$with_gnu_ld"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${lt_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD=$ac_dir/$ac_prog + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${lt_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test yes = "$with_gnu_ld"; then + archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='$wl' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + whole_archive_flag_spec_CXX= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + ld_shlibs_CXX=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aix[4-9]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds_CXX='' + hardcode_direct_CXX=yes + hardcode_direct_absolute_CXX=yes + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + file_list_spec_CXX='$wl-f,' + + if test yes = "$GXX"; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`$CC -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct_CXX=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L_CXX=yes + hardcode_libdir_flag_spec_CXX='-L$libdir' + hardcode_libdir_separator_CXX= + fi + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag=$shared_flag' $wl-G' + fi + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + fi + fi + + export_dynamic_flag_spec_CXX='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + always_export_symbols_CXX=yes + if test yes = "$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag_CXX='-berok' + # Determine the default libpath from the value encoded in an empty + # executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath__CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath__CXX +fi + + hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath" + + archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + hardcode_libdir_flag_spec_CXX='$wl-R $libdir:/usr/lib:/lib' + allow_undefined_flag_CXX="-z nodefs" + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath__CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath__CXX +fi + + hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag_CXX=' $wl-bernotok' + allow_undefined_flag_CXX=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec_CXX='$convenience' + fi + archive_cmds_need_lc_CXX=yes + # This is similar to how AIX traditionally builds its shared + # libraries. + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $wl-bnoentry $compiler_flags $wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag_CXX=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + ld_shlibs_CXX=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + case $GXX,$cc_basename in + ,cl* | no,cl*) + # Native MSVC + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec_CXX=' ' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=yes + file_list_spec_CXX='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + archive_expsym_cmds_CXX='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true' + enable_shared_with_static_runtimes_CXX=yes + # Don't use ranlib + old_postinstall_cmds_CXX='chmod 644 $oldlib' + postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # g++ + # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec_CXX='-L$libdir' + export_dynamic_flag_spec_CXX='$wl--export-all-symbols' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=no + enable_shared_with_static_runtimes_CXX=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + archive_expsym_cmds_CXX='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs_CXX=no + fi + ;; + esac + ;; + darwin* | rhapsody*) + + + archive_cmds_need_lc_CXX=no + hardcode_direct_CXX=no + hardcode_automatic_CXX=yes + hardcode_shlibpath_var_CXX=unsupported + if test yes = "$lt_cv_ld_force_load"; then + whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + + else + whole_archive_flag_spec_CXX='' + fi + link_all_deplibs_CXX=yes + allow_undefined_flag_CXX=$_lt_dar_allow_undefined + case $cc_basename in + ifort*|nagfor*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test yes = "$_lt_dar_can_shared"; then + output_verbose_link_cmd=func_echo_all + archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" + module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" + archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + module_expsym_cmds_CXX="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" + if test yes != "$lt_cv_apple_cc_single_mod"; then + archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" + archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" + fi + + else + ld_shlibs_CXX=no + fi + + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + freebsd2.*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + ld_shlibs_CXX=no + ;; + + freebsd-elf*) + archive_cmds_need_lc_CXX=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + ld_shlibs_CXX=yes + ;; + + haiku*) + archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + link_all_deplibs_CXX=yes + ;; + + hpux9*) + hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir' + hardcode_libdir_separator_CXX=: + export_dynamic_flag_spec_CXX='$wl-E' + hardcode_direct_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes = "$GXX"; then + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir' + hardcode_libdir_separator_CXX=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + export_dynamic_flag_spec_CXX='$wl-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + ;; + *) + hardcode_direct_CXX=yes + hardcode_direct_absolute_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + interix[3-9]*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + export_dynamic_flag_spec_CXX='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_CXX='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' + fi + fi + link_all_deplibs_CXX=yes + ;; + esac + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + hardcode_libdir_separator_CXX=: + inherit_rpath_CXX=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + archive_cmds_need_lc_CXX=no + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [1-5].* | *pgcpp\ [1-5].*) + prelink_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + old_archive_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' + archive_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 6 and above use weak symbols + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + + hardcode_libdir_flag_spec_CXX='$wl--rpath $wl$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + whole_archive_flag_spec_CXX='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + ;; + cxx*) + # Compaq C++ + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + ;; + xl* | mpixl* | bgxl*) + # IBM XL 8.0 on PPC, with GNU ld + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + if test yes = "$supports_anon_versioning"; then + archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' + hardcode_libdir_flag_spec_CXX='-R$libdir' + whole_archive_flag_spec_CXX='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + compiler_needs_object_CXX=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + ld_shlibs_CXX=yes + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + hardcode_direct_absolute_CXX=yes + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' + export_dynamic_flag_spec_CXX='$wl-E' + whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + fi + output_verbose_link_cmd=func_echo_all + else + ld_shlibs_CXX=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + hardcode_libdir_separator_CXX=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + cxx*) + case $host in + osf3*) + allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*' + archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + ;; + *) + allow_undefined_flag_CXX=' -expect_unresolved \*' + archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ + $RM $lib.exp' + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + ;; + esac + + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes,no = "$GXX,$with_gnu_ld"; then + allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*' + case $host in + osf3*) + archive_cmds_CXX='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + ;; + *) + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + ;; + esac + + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + archive_cmds_need_lc_CXX=yes + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_shlibpath_var_CXX=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract' + ;; + esac + link_all_deplibs_CXX=yes + + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test yes,no = "$GXX,$with_gnu_ld"; then + no_undefined_flag_CXX=' $wl-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + else + # g++ 2.7 appears to require '-G' NOT '-shared' on this + # platform. + archive_cmds_CXX='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + fi + + hardcode_libdir_flag_spec_CXX='$wl-R $wl$libdir' + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + whole_archive_flag_spec_CXX='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag_CXX='$wl-z,text' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag_CXX='$wl-z,text' + allow_undefined_flag_CXX='$wl-z,nodefs' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='$wl-R,$libdir' + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + export_dynamic_flag_spec_CXX='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~ + '"$old_archive_cmds_CXX" + reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~ + '"$reload_cmds_CXX" + ;; + *) + archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 +$as_echo "$ld_shlibs_CXX" >&6; } + test no = "$ld_shlibs_CXX" && can_build_shared=no + + GCC_CXX=$GXX + LD_CXX=$LD + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + # Dependencies to place before and after the object being linked: +predep_objects_CXX= +postdep_objects_CXX= +predeps_CXX= +postdeps_CXX= +compiler_lib_search_path_CXX= + +cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF + + +_lt_libdeps_save_CFLAGS=$CFLAGS +case "$CC $CFLAGS " in #( +*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; +esac + +if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case $prev$p in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test x-L = "$p" || + test x-R = "$p"; then + prev=$p + continue + fi + + # Expand the sysroot to ease extracting the directories later. + if test -z "$prev"; then + case $p in + -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; + -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; + -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; + esac + fi + case $p in + =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; + esac + if test no = "$pre_test_object_deps_done"; then + case $prev in + -L | -R) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$compiler_lib_search_path_CXX"; then + compiler_lib_search_path_CXX=$prev$p + else + compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} $prev$p" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$postdeps_CXX"; then + postdeps_CXX=$prev$p + else + postdeps_CXX="${postdeps_CXX} $prev$p" + fi + fi + prev= + ;; + + *.lto.$objext) ;; # Ignore GCC LTO objects + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test no = "$pre_test_object_deps_done"; then + if test -z "$predep_objects_CXX"; then + predep_objects_CXX=$p + else + predep_objects_CXX="$predep_objects_CXX $p" + fi + else + if test -z "$postdep_objects_CXX"; then + postdep_objects_CXX=$p + else + postdep_objects_CXX="$postdep_objects_CXX $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling CXX test program" +fi + +$RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS + +# PORTME: override above test on systems where it is broken +case $host_os in +interix[3-9]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + predep_objects_CXX= + postdep_objects_CXX= + postdeps_CXX= + ;; + +linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + if test yes != "$solaris_use_stlport4"; then + postdeps_CXX='-library=Cstd -library=Crun' + fi + ;; + esac + ;; + +solaris*) + case $cc_basename in + CC* | sunCC*) + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + if test yes != "$solaris_use_stlport4"; then + postdeps_CXX='-library=Cstd -library=Crun' + fi + ;; + esac + ;; +esac + + +case " $postdeps_CXX " in +*" -lc "*) archive_cmds_need_lc_CXX=no ;; +esac + compiler_lib_search_dirs_CXX= +if test -n "${compiler_lib_search_path_CXX}"; then + compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | $SED -e 's! -L! !g' -e 's!^ !!'` +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + lt_prog_compiler_wl_CXX= +lt_prog_compiler_pic_CXX= +lt_prog_compiler_static_CXX= + + + # C++ specific cases for pic, static, wl, etc. + if test yes = "$GXX"; then + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + fi + lt_prog_compiler_pic_CXX='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic_CXX='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic_CXX='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + lt_prog_compiler_pic_CXX= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static_CXX= + ;; + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic_CXX=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + else + case $host_os in + aix[4-9]*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + else + lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + ;; + dgux*) + case $cc_basename in + ec++*) + lt_prog_compiler_pic_CXX='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='$wl-a ${wl}archive' + if test ia64 != "$host_cpu"; then + lt_prog_compiler_pic_CXX='+Z' + fi + ;; + aCC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='$wl-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_CXX='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + KCC*) + # KAI C++ Compiler + lt_prog_compiler_wl_CXX='--backend -Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64, which still supported -KPIC. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + lt_prog_compiler_static_CXX='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fpic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + xlc* | xlC* | bgxl[cC]* | mpixl[cC]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-qpic' + lt_prog_compiler_static_CXX='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + lt_prog_compiler_pic_CXX='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd*) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + lt_prog_compiler_wl_CXX='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + lt_prog_compiler_pic_CXX='-pic' + ;; + cxx*) + # Digital/Compaq C++ + lt_prog_compiler_wl_CXX='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + lt_prog_compiler_pic_CXX='-pic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + lcc*) + # Lucid + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + lt_prog_compiler_pic_CXX='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + lt_prog_compiler_can_build_shared_CXX=no + ;; + esac + fi + +case $host_os in + # For platforms that do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic_CXX= + ;; + *) + lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } +if ${lt_cv_prog_compiler_pic_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_pic_CXX" >&6; } +lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; } +if ${lt_cv_prog_compiler_pic_works_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works_CXX=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works_CXX=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; } + +if test yes = "$lt_cv_prog_compiler_pic_works_CXX"; then + case $lt_prog_compiler_pic_CXX in + "" | " "*) ;; + *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; + esac +else + lt_prog_compiler_pic_CXX= + lt_prog_compiler_can_build_shared_CXX=no +fi + +fi + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if ${lt_cv_prog_compiler_static_works_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works_CXX=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works_CXX=yes + fi + else + lt_cv_prog_compiler_static_works_CXX=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; } + +if test yes = "$lt_cv_prog_compiler_static_works_CXX"; then + : +else + lt_prog_compiler_static_CXX= +fi + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } + + + + +hard_links=nottested +if test no = "$lt_cv_prog_compiler_c_o_CXX" && test no != "$need_locks"; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test no = "$hard_links"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + case $host_os in + aix[4-9]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global defined + # symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + export_symbols_cmds_CXX=$ltdll_cmds + ;; + cygwin* | mingw* | cegcc*) + case $cc_basename in + cl*) + exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + ;; + *) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + ;; + esac + ;; + *) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 +$as_echo "$ld_shlibs_CXX" >&6; } +test no = "$ld_shlibs_CXX" && can_build_shared=no + +with_gnu_ld_CXX=$with_gnu_ld + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc_CXX" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc_CXX=yes + + if test yes,yes = "$GCC,$enable_shared"; then + case $archive_cmds_CXX in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +if ${lt_cv_archive_cmds_need_lc_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl_CXX + pic_flag=$lt_prog_compiler_pic_CXX + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag_CXX + allow_undefined_flag_CXX= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc_CXX=no + else + lt_cv_archive_cmds_need_lc_CXX=yes + fi + allow_undefined_flag_CXX=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5 +$as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; } + archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=.so +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='$libname$release$shared_ext$major' + ;; + +aix[4-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test ia64 = "$host_cpu"; then + # AIX 5 supports IA64 + library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line '#! .'. This would cause the generated library to + # depend on '.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test yes = "$aix_use_runtimelinking"; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='$libname$shared_ext' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + library_names_spec='$libname.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec=$LIB + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' + soname_spec='$libname$release$major$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[23].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=no + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + if test 32 = "$HPUX_IA64_MODE"; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test yes = "$lt_cv_prog_gnu_ld"; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" + sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +linux*android*) + version_type=none # Android doesn't support versioned libraries. + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + dynamic_linker='Android linker' + # Don't embed -rpath directories since the linker doesn't support them. + hardcode_libdir_flag_spec_CXX='-L$libdir' + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if ${lt_cv_shlibpath_overrides_runpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd* | bitrig*) + version_type=sunos + sys_lib_dlsearch_path_spec=/usr/lib + need_lib_prefix=no + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + need_version=no + else + need_version=yes + fi + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +os2*) + libname_spec='$name' + shrext_cmds=.dll + need_lib_prefix=no + library_names_spec='$libname$shared_ext $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test yes = "$with_gnu_ld"; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec; then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' + soname_spec='$libname$shared_ext.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test yes = "$with_gnu_ld"; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test no = "$dynamic_linker" && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test yes = "$GCC"; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then + sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec +fi +if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then + sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec +fi - CPPFLAGS="$save_CPPFLAGS" - LDFLAGS="$save_LDFLAGS" - LIBS="$save_LIBS" - ;; - esac - case $lt_cv_dlopen_self in - yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; - *) enable_dlopen_self=unknown ;; - esac - case $lt_cv_dlopen_self_static in - yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; - *) enable_dlopen_self_static=unknown ;; - esac -fi @@ -11960,35 +15831,6 @@ fi -striplib= -old_striplib= -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 -$as_echo_n "checking whether stripping libraries is possible... " >&6; } -if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP" ; then - striplib="$STRIP -x" - old_striplib="$STRIP -S" - { $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 - ;; - *) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - ;; - esac -fi @@ -12001,55 +15843,76 @@ fi - # Report which library types will actually be built - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 -$as_echo_n "checking if libtool supports shared libraries... " >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 -$as_echo "$can_build_shared" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 -$as_echo_n "checking whether to build shared libraries... " >&6; } - test "$can_build_shared" = "no" && enable_shared=no - # On AIX, shared libraries and static libraries use the same namespace, and - # are all built from PIC. - case $host_os in - aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - aix[4-9]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no - fi - ;; - esac - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 -$as_echo "$enable_shared" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 -$as_echo_n "checking whether to build static libraries... " >&6; } - # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 -$as_echo "$enable_static" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action_CXX= +if test -n "$hardcode_libdir_flag_spec_CXX" || + test -n "$runpath_var_CXX" || + test yes = "$hardcode_automatic_CXX"; then + # We can hardcode non-existent directories. + if test no != "$hardcode_direct_CXX" && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" && + test no != "$hardcode_minus_L_CXX"; then + # Linking always hardcodes the temporary library directory. + hardcode_action_CXX=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action_CXX=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action_CXX=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5 +$as_echo "$hardcode_action_CXX" >&6; } +if test relink = "$hardcode_action_CXX" || + test yes = "$inherit_rpath_CXX"; then + # Fast installation is not supported + enable_fast_install=no +elif test yes = "$shlibpath_overrides_runpath" || + test no = "$enable_shared"; then + # Fast installation is not necessary + enable_fast_install=needless fi + + + + + + + + fi # test -n "$compiler" + + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test yes != "$_lt_caught_CXX_error" + ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu -CC="$lt_save_CC" - @@ -12811,7 +16674,7 @@ fi cputype=`(((grep cpu /proc/cpuinfo | cut -d: -f2) ; ($PRTDIAG -v |grep -i sparc) ; grep -i cpu /var/run/dmesg.boot ) | head -n 1) 2> /dev/null` - cputype=`echo "$cputype" | tr -d ' -' |tr $as_cr_LETTERS $as_cr_letters` + cputype=`echo "$cputype" | tr -d ' -' | sed 's/SPARCIIi/SPARCII/' | tr $as_cr_LETTERS $as_cr_letters` case $cputype in *ultrasparciv*) ax_gcc_arch="ultrasparc4 ultrasparc3 ultrasparc v9" ;; *ultrasparciii*) ax_gcc_arch="ultrasparc3 ultrasparc v9" ;; @@ -13082,12 +16945,12 @@ fi if test "x$GCC" = "xyes"; then CFLAGS="$CFLAGS -fexceptions" - touch local.exp -else - cat > local.exp < local.exp <&5 @@ -13288,6 +17151,7 @@ fi TARGETDIR="unknown" +HAVE_LONG_DOUBLE_VARIANT=0 case "$host" in aarch64*-*-*) TARGET=AARCH64; TARGETDIR=aarch64 @@ -13299,6 +17163,10 @@ case "$host" in HAVE_LONG_DOUBLE='defined(__LONG_DOUBLE_128__)' ;; + arc*-*-*) + TARGET=ARC; TARGETDIR=arc + ;; + arm*-*-*) TARGET=ARM; TARGETDIR=arm ;; @@ -13417,6 +17285,10 @@ case "$host" in TARGET=M68K; TARGETDIR=m68k ;; + m88k-*-*) + TARGET=M88K; TARGETDIR=m88k + ;; + microblaze*-*-*) TARGET=MICROBLAZE; TARGETDIR=microblaze ;; @@ -13432,14 +17304,19 @@ case "$host" in mips-sgi-irix5.* | mips-sgi-irix6.* | mips*-*-rtems*) TARGET=MIPS_IRIX; TARGETDIR=mips ;; - mips*-*-linux* | mips*-*-openbsd*) + mips*-*linux* | mips*-*-openbsd*) # Support 128-bit long double for NewABI. HAVE_LONG_DOUBLE='defined(__mips64)' - TARGET=MIPS_IRIX; TARGETDIR=mips + TARGET=MIPS_LINUX; TARGETDIR=mips + ;; + + nios2*-linux*) + TARGET=NIOS2; TARGETDIR=nios2 ;; powerpc*-*-linux* | powerpc-*-sysv*) TARGET=POWERPC; TARGETDIR=powerpc + HAVE_LONG_DOUBLE_VARIANT=1 ;; powerpc-*-amigaos*) TARGET=POWERPC; TARGETDIR=powerpc @@ -13455,6 +17332,7 @@ case "$host" in ;; powerpc-*-freebsd* | powerpc-*-openbsd*) TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc + HAVE_LONG_DOUBLE_VARIANT=1 ;; powerpc64-*-freebsd*) TARGET=POWERPC; TARGETDIR=powerpc @@ -13482,6 +17360,10 @@ case "$host" in TARGET=TILE; TARGETDIR=tile ;; + vax-*-*) + TARGET=VAX; TARGETDIR=vax + ;; + xtensa*-*) TARGET=XTENSA; TARGETDIR=xtensa ;; @@ -13559,6 +17441,22 @@ else X86_DARWIN_FALSE= fi + if test x$TARGET = xX86_DARWIN && test $ac_cv_sizeof_size_t = 4; then + X86_DARWIN32_TRUE= + X86_DARWIN32_FALSE='#' +else + X86_DARWIN32_TRUE='#' + X86_DARWIN32_FALSE= +fi + + if test x$TARGET = xX86_DARWIN && test $ac_cv_sizeof_size_t = 8; then + X86_DARWIN64_TRUE= + X86_DARWIN64_FALSE='#' +else + X86_DARWIN64_TRUE='#' + X86_DARWIN64_FALSE= +fi + if test x$TARGET = xALPHA; then ALPHA_TRUE= ALPHA_FALSE='#' @@ -13591,6 +17489,14 @@ else M68K_FALSE= fi + if test x$TARGET = xM88K; then + M88K_TRUE= + M88K_FALSE='#' +else + M88K_TRUE='#' + M88K_FALSE= +fi + if test x$TARGET = xMICROBLAZE; then MICROBLAZE_TRUE= MICROBLAZE_FALSE='#' @@ -13615,6 +17521,14 @@ else MOXIE_FALSE= fi + if test x$TARGET = xNIOS2; then + NIOS2_TRUE= + NIOS2_FALSE='#' +else + NIOS2_TRUE='#' + NIOS2_FALSE= +fi + if test x$TARGET = xPOWERPC; then POWERPC_TRUE= POWERPC_FALSE='#' @@ -13655,6 +17569,14 @@ else AARCH64_FALSE= fi + if test x$TARGET = xARC; then + ARC_TRUE= + ARC_FALSE='#' +else + ARC_TRUE='#' + ARC_FALSE= +fi + if test x$TARGET = xARM; then ARM_TRUE= ARM_FALSE='#' @@ -13751,6 +17673,14 @@ else TILE_FALSE= fi + if test x$TARGET = xVAX; then + VAX_TRUE= + VAX_FALSE='#' +else + VAX_TRUE='#' + VAX_FALSE= +fi + if test x$TARGET = xXTENSA; then XTENSA_TRUE= XTENSA_FALSE='#' @@ -14151,17 +18081,25 @@ _ACEOF # Also AC_SUBST this variable for ffi.h. if test -z "$HAVE_LONG_DOUBLE"; then HAVE_LONG_DOUBLE=0 - if test $ac_cv_sizeof_double != $ac_cv_sizeof_long_double; then - if test $ac_cv_sizeof_long_double != 0; then + if test $ac_cv_sizeof_long_double != 0; then + if test $HAVE_LONG_DOUBLE_VARIANT != 0; then + +$as_echo "#define HAVE_LONG_DOUBLE_VARIANT 1" >>confdefs.h + HAVE_LONG_DOUBLE=1 + else + if test $ac_cv_sizeof_double != $ac_cv_sizeof_long_double; then + HAVE_LONG_DOUBLE=1 $as_echo "#define HAVE_LONG_DOUBLE 1" >>confdefs.h + fi fi fi fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 $as_echo_n "checking whether byte ordering is bigendian... " >&6; } if ${ac_cv_c_bigendian+:} false; then : @@ -14602,8 +18540,7 @@ $as_echo "#define FFI_MMAP_EXEC_EMUTRAMP_PAX 1" >>confdefs.h fi -if test x$TARGET = xX86_WIN64; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _ prefix in compiled symbols" >&5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for _ prefix in compiled symbols" >&5 $as_echo_n "checking for _ prefix in compiled symbols... " >&6; } if ${lt_cv_sys_symbol_underscore+:} false; then : $as_echo_n "(cached) " >&6 @@ -14650,11 +18587,10 @@ $as_echo "$lt_cv_sys_symbol_underscore" >&6; } sys_symbol_underscore=$lt_cv_sys_symbol_underscore - if test "x$sys_symbol_underscore" = xyes; then +if test "x$sys_symbol_underscore" = xyes; then $as_echo "#define SYMBOL_UNDERSCORE 1" >>confdefs.h - fi fi FFI_EXEC_TRAMPOLINE_TABLE=0 @@ -14682,16 +18618,32 @@ fi if test x$TARGET = xX86_64; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler supports unwind section type" >&5 -$as_echo_n "checking assembler supports unwind section type... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking toolchain supports unwind section type" >&5 +$as_echo_n "checking toolchain supports unwind section type... " >&6; } if ${libffi_cv_as_x86_64_unwind_section_type+:} false; then : $as_echo_n "(cached) " >&6 else - libffi_cv_as_x86_64_unwind_section_type=yes - echo '.section .eh_frame,"a",@unwind' > conftest.s - if $CC $CFLAGS -c conftest.s 2>&1 | grep -i warning > /dev/null; then - libffi_cv_as_x86_64_unwind_section_type=no + cat > conftest1.s << EOF +.text +.globl foo +foo: +jmp bar +.section .eh_frame,"a",@unwind +bar: +EOF + + cat > conftest2.c << EOF +extern void foo(); +int main(){foo();} +EOF + + libffi_cv_as_x86_64_unwind_section_type=no + # we ensure that we can compile _and_ link an assembly file containing an @unwind section + # since the compiler can support it and not the linker (ie old binutils) + if $CC -Wa,--fatal-warnings $CFLAGS -c conftest1.s > /dev/null 2>&1 && \ + $CC conftest2.c conftest1.o > /dev/null 2>&1 ; then + libffi_cv_as_x86_64_unwind_section_type=yes fi fi @@ -14844,7 +18796,7 @@ if test "x$GCC" = "xyes"; then toolexecdir='$(libdir)/gcc-lib/$(target_alias)' toolexeclibdir='$(libdir)' fi - multi_os_directory=`$CC -print-multi-os-directory` + multi_os_directory=`$CC $CFLAGS -print-multi-os-directory` case $multi_os_directory in .) ;; # Avoid trailing /. ../*) toolexeclibdir=$toolexeclibdir/$multi_os_directory ;; @@ -15005,6 +18957,10 @@ if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${am__fastdepCCAS_TRUE}" && test -z "${am__fastdepCCAS_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCCAS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -15049,6 +19005,14 @@ if test -z "${X86_DARWIN_TRUE}" && test -z "${X86_DARWIN_FALSE}"; then as_fn_error $? "conditional \"X86_DARWIN\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${X86_DARWIN32_TRUE}" && test -z "${X86_DARWIN32_FALSE}"; then + as_fn_error $? "conditional \"X86_DARWIN32\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${X86_DARWIN64_TRUE}" && test -z "${X86_DARWIN64_FALSE}"; then + as_fn_error $? "conditional \"X86_DARWIN64\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${ALPHA_TRUE}" && test -z "${ALPHA_FALSE}"; then as_fn_error $? "conditional \"ALPHA\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -15065,6 +19029,10 @@ if test -z "${M68K_TRUE}" && test -z "${M68K_FALSE}"; then as_fn_error $? "conditional \"M68K\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${M88K_TRUE}" && test -z "${M88K_FALSE}"; then + as_fn_error $? "conditional \"M88K\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${MICROBLAZE_TRUE}" && test -z "${MICROBLAZE_FALSE}"; then as_fn_error $? "conditional \"MICROBLAZE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -15077,6 +19045,10 @@ if test -z "${MOXIE_TRUE}" && test -z "${MOXIE_FALSE}"; then as_fn_error $? "conditional \"MOXIE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${NIOS2_TRUE}" && test -z "${NIOS2_FALSE}"; then + as_fn_error $? "conditional \"NIOS2\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${POWERPC_TRUE}" && test -z "${POWERPC_FALSE}"; then as_fn_error $? "conditional \"POWERPC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -15097,6 +19069,10 @@ if test -z "${AARCH64_TRUE}" && test -z "${AARCH64_FALSE}"; then as_fn_error $? "conditional \"AARCH64\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${ARC_TRUE}" && test -z "${ARC_FALSE}"; then + as_fn_error $? "conditional \"ARC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${ARM_TRUE}" && test -z "${ARM_FALSE}"; then as_fn_error $? "conditional \"ARM\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -15145,6 +19121,10 @@ if test -z "${TILE_TRUE}" && test -z "${TILE_FALSE}"; then as_fn_error $? "conditional \"TILE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${VAX_TRUE}" && test -z "${VAX_FALSE}"; then + as_fn_error $? "conditional \"VAX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${XTENSA_TRUE}" && test -z "${XTENSA_FALSE}"; then as_fn_error $? "conditional \"XTENSA\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -15559,7 +19539,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by libffi $as_me 3.0.13, which was +This file was extended by libffi $as_me 3.1, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -15629,7 +19609,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -libffi config.status 3.0.13 +libffi config.status 3.1 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -15821,8 +19801,10 @@ compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' +lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`' nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' @@ -15896,6 +19878,60 @@ enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_sub enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`' +predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`' +postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`' +predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`' +postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`' +LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`' +reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`' +reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' +compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`' +GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`' +archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' +module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' +with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' +no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`' +inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`' +link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`' +always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`' +exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`' +include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`' +prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`' +postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`' +file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`' +predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`' +postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`' +predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`' +postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`' LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' @@ -15940,8 +19976,10 @@ CFLAGS \ compiler \ lt_cv_sys_global_symbol_pipe \ lt_cv_sys_global_symbol_to_cdecl \ +lt_cv_sys_global_symbol_to_import \ lt_cv_sys_global_symbol_to_c_name_address \ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ +lt_cv_nm_interface \ nm_file_list_spec \ lt_prog_compiler_no_builtin_flag \ lt_prog_compiler_pic \ @@ -15974,10 +20012,41 @@ soname_spec \ install_override_mode \ finish_eval \ old_striplib \ -striplib; do +striplib \ +compiler_lib_search_dirs \ +predep_objects \ +postdep_objects \ +predeps \ +postdeps \ +compiler_lib_search_path \ +LD_CXX \ +reload_flag_CXX \ +compiler_CXX \ +lt_prog_compiler_no_builtin_flag_CXX \ +lt_prog_compiler_pic_CXX \ +lt_prog_compiler_wl_CXX \ +lt_prog_compiler_static_CXX \ +lt_cv_prog_compiler_c_o_CXX \ +export_dynamic_flag_spec_CXX \ +whole_archive_flag_spec_CXX \ +compiler_needs_object_CXX \ +with_gnu_ld_CXX \ +allow_undefined_flag_CXX \ +no_undefined_flag_CXX \ +hardcode_libdir_flag_spec_CXX \ +hardcode_libdir_separator_CXX \ +exclude_expsyms_CXX \ +include_expsyms_CXX \ +file_list_spec_CXX \ +compiler_lib_search_dirs_CXX \ +predep_objects_CXX \ +postdep_objects_CXX \ +predeps_CXX \ +postdeps_CXX \ +compiler_lib_search_path_CXX; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" @@ -16004,10 +20073,21 @@ postinstall_cmds \ postuninstall_cmds \ finish_cmds \ sys_lib_search_path_spec \ -sys_lib_dlsearch_path_spec; do +sys_lib_dlsearch_path_spec \ +reload_cmds_CXX \ +old_archive_cmds_CXX \ +old_archive_from_new_cmds_CXX \ +old_archive_from_expsyms_cmds_CXX \ +archive_cmds_CXX \ +archive_expsym_cmds_CXX \ +module_cmds_CXX \ +module_expsym_cmds_CXX \ +export_symbols_cmds_CXX \ +prelink_cmds_CXX \ +postlink_cmds_CXX; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" @@ -16016,24 +20096,23 @@ sys_lib_dlsearch_path_spec; do done ac_aux_dir='$ac_aux_dir' -xsi_shell='$xsi_shell' -lt_shell_append='$lt_shell_append' -# See if we are running on zsh, and set the options which allow our +# See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes INIT. -if test -n "\${ZSH_VERSION+set}" ; then +if test -n "\${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi PACKAGE='$PACKAGE' VERSION='$VERSION' - TIMESTAMP='$TIMESTAMP' RM='$RM' ofile='$ofile' + + TARGETDIR="$TARGETDIR" _ACEOF @@ -16831,7 +20910,7 @@ $as_echo "$as_me: build in $ax_enable_builddir (HOST=$ax_enable_builddir_host)" fi ;; "depfiles":C) test x"$AMDEP_TRUE" != x"" || { - # Autoconf 2.62 quotes --file arguments for eval, but not when files + # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in @@ -16882,7 +20961,7 @@ $as_echo X"$mf" | DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "am__include" && continue + test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the @@ -16925,13 +21004,13 @@ $as_echo X"$file" | ;; "libtool":C) - # See if we are running on zsh, and set the options which allow our + # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes. - if test -n "${ZSH_VERSION+set}" ; then + if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi - cfgfile="${ofile}T" + cfgfile=${ofile}T trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" @@ -16939,7 +21018,7 @@ $as_echo X"$file" | #! $SHELL # `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. -# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Generated automatically by $as_me ($PACKAGE) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # @@ -16973,7 +21052,7 @@ $as_echo X"$file" | # The names of the tagged configurations supported by this script. -available_tags="" +available_tags='CXX ' # ### BEGIN LIBTOOL CONFIG @@ -17110,16 +21189,22 @@ global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration. global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl +# Transform the output of nm into a list of symbols to manually relocate. +global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import + # Transform the output of nm in a C name address pair. global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # Transform the output of nm in a C name address pair when lib prefix is needed. global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix +# The name lister interface. +nm_interface=$lt_lt_cv_nm_interface + # Specify filename containing input files for \$NM. nm_file_list_spec=$lt_nm_file_list_spec -# The root where to search for dependent libraries,and in which our libraries should be installed. +# The root where to search for dependent libraries,and where our libraries should be installed. lt_sysroot=$lt_sysroot # The name of the directory that contains temporary libtool files. @@ -17306,13 +21391,13 @@ hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator -# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct -# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary and the resulting library dependency is -# "absolute",i.e impossible to change by setting \${shlibpath_var} if the +# "absolute",i.e impossible to change by setting \$shlibpath_var if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute @@ -17360,6 +21445,20 @@ file_list_spec=$lt_file_list_spec # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects +postdep_objects=$lt_postdep_objects +predeps=$lt_predeps +postdeps=$lt_postdeps + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path + # ### END LIBTOOL CONFIG _LT_EOF @@ -17370,7 +21469,7 @@ _LT_EOF # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. -if test "X${COLLECT_NAMES+set}" != Xset; then +if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi @@ -17379,7 +21478,7 @@ _LT_EOF esac -ltmain="$ac_aux_dir/ltmain.sh" +ltmain=$ac_aux_dir/ltmain.sh # We use sed instead of cat because bash on DJGPP gets confused if @@ -17389,169 +21488,163 @@ ltmain="$ac_aux_dir/ltmain.sh" sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) - if test x"$xsi_shell" = xyes; then - sed -e '/^func_dirname ()$/,/^} # func_dirname /c\ -func_dirname ()\ -{\ -\ case ${1} in\ -\ */*) func_dirname_result="${1%/*}${2}" ;;\ -\ * ) func_dirname_result="${3}" ;;\ -\ esac\ -} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_basename ()$/,/^} # func_basename /c\ -func_basename ()\ -{\ -\ func_basename_result="${1##*/}"\ -} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\ -func_dirname_and_basename ()\ -{\ -\ case ${1} in\ -\ */*) func_dirname_result="${1%/*}${2}" ;;\ -\ * ) func_dirname_result="${3}" ;;\ -\ esac\ -\ func_basename_result="${1##*/}"\ -} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_stripname ()$/,/^} # func_stripname /c\ -func_stripname ()\ -{\ -\ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\ -\ # positional parameters, so assign one to ordinary parameter first.\ -\ func_stripname_result=${3}\ -\ func_stripname_result=${func_stripname_result#"${1}"}\ -\ func_stripname_result=${func_stripname_result%"${2}"}\ -} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\ -func_split_long_opt ()\ -{\ -\ func_split_long_opt_name=${1%%=*}\ -\ func_split_long_opt_arg=${1#*=}\ -} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\ -func_split_short_opt ()\ -{\ -\ func_split_short_opt_arg=${1#??}\ -\ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\ -} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\ -func_lo2o ()\ -{\ -\ case ${1} in\ -\ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\ -\ *) func_lo2o_result=${1} ;;\ -\ esac\ -} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_xform ()$/,/^} # func_xform /c\ -func_xform ()\ -{\ - func_xform_result=${1%.*}.lo\ -} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_arith ()$/,/^} # func_arith /c\ -func_arith ()\ -{\ - func_arith_result=$(( $* ))\ -} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_len ()$/,/^} # func_len /c\ -func_len ()\ -{\ - func_len_result=${#1}\ -} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - -fi - -if test x"$lt_shell_append" = xyes; then - sed -e '/^func_append ()$/,/^} # func_append /c\ -func_append ()\ -{\ - eval "${1}+=\\${2}"\ -} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\ -func_append_quoted ()\ -{\ -\ func_quote_for_eval "${2}"\ -\ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\ -} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - # Save a `func_append' function call where possible by direct use of '+=' - sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") - test 0 -eq $? || _lt_function_replace_fail=: -else - # Save a `func_append' function call even when '+=' is not available - sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") - test 0 -eq $? || _lt_function_replace_fail=: -fi - -if test x"$_lt_function_replace_fail" = x":"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5 -$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;} -fi - - mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" + + cat <<_LT_EOF >> "$ofile" + +# ### BEGIN LIBTOOL TAG CONFIG: CXX + +# The linker used to build libraries. +LD=$lt_LD_CXX + +# How to create reloadable object files. +reload_flag=$lt_reload_flag_CXX +reload_cmds=$lt_reload_cmds_CXX + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds_CXX + +# A language specific compiler. +CC=$lt_compiler_CXX + +# Is the compiler the GNU compiler? +with_gcc=$GCC_CXX + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_CXX + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_CXX + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_CXX + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_CXX + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object_CXX + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds_CXX +archive_expsym_cmds=$lt_archive_expsym_cmds_CXX + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds_CXX +module_expsym_cmds=$lt_module_expsym_cmds_CXX + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld_CXX + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_CXX + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_CXX + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct_CXX + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \$shlibpath_var if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute_CXX + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L_CXX + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic_CXX + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath_CXX + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_CXX + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols_CXX + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_CXX + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_CXX + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_CXX + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds_CXX + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds_CXX + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec_CXX + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_CXX + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects_CXX +postdep_objects=$lt_postdep_objects_CXX +predeps=$lt_predeps_CXX +postdeps=$lt_postdeps_CXX + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path_CXX + +# ### END LIBTOOL TAG CONFIG: CXX +_LT_EOF + ;; "include":C) test -d include || mkdir include ;; "src":C) diff --git a/Modules/_ctypes/libffi/configure.ac b/Modules/_ctypes/libffi/configure.ac index 7fe5ff5f8d80..5c8885fa634b 100644 --- a/Modules/_ctypes/libffi/configure.ac +++ b/Modules/_ctypes/libffi/configure.ac @@ -5,13 +5,17 @@ dnl Process this with autoconf to create configure AC_PREREQ(2.68) -AC_INIT([libffi], [3.0.13], [http://github.com/atgreen/libffi/issues]) +AC_INIT([libffi], [3.1], [http://github.com/atgreen/libffi/issues]) AC_CONFIG_HEADERS([fficonfig.h]) AC_CANONICAL_SYSTEM target_alias=${target_alias-$host_alias} -. ${srcdir}/configure.host +case "${host}" in + frv*-elf) + LDFLAGS=`echo $LDFLAGS | sed "s/\-B[^ ]*libgloss\/frv\///"`\ -B`pwd`/../libgloss/frv/ + ;; +esac AX_ENABLE_BUILDDIR @@ -28,6 +32,7 @@ m4_rename([_AC_ARG_VAR_PRECIOUS],[real_PRECIOUS]) m4_define([_AC_ARG_VAR_PRECIOUS],[]) save_CFLAGS=$CFLAGS AC_PROG_CC +AC_PROG_CXX CFLAGS=$save_CFLAGS m4_undefine([_AC_ARG_VAR_PRECIOUS]) m4_rename_force([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS]) @@ -52,12 +57,12 @@ fi if test "x$GCC" = "xyes"; then CFLAGS="$CFLAGS -fexceptions" - touch local.exp -else - cat > local.exp < local.exp < conftest.s - if $CC $CFLAGS -c conftest.s 2>&1 | grep -i warning > /dev/null; then - libffi_cv_as_x86_64_unwind_section_type=no + cat > conftest1.s << EOF +.text +.globl foo +foo: +jmp bar +.section .eh_frame,"a",@unwind +bar: +EOF + + cat > conftest2.c << EOF +extern void foo(); +int main(){foo();} +EOF + + libffi_cv_as_x86_64_unwind_section_type=no + # we ensure that we can compile _and_ link an assembly file containing an @unwind section + # since the compiler can support it and not the linker (ie old binutils) + if $CC -Wa,--fatal-warnings $CFLAGS -c conftest1.s > /dev/null 2>&1 && \ + $CC conftest2.c conftest1.o > /dev/null 2>&1 ; then + libffi_cv_as_x86_64_unwind_section_type=yes fi ]) if test "x$libffi_cv_as_x86_64_unwind_section_type" = xyes; then @@ -526,14 +575,14 @@ AM_CONDITIONAL(FFI_DEBUG, test "$enable_debug" = "yes") AC_ARG_ENABLE(structs, [ --disable-structs omit code for struct support], if test "$enable_structs" = "no"; then - AC_DEFINE(FFI_NO_STRUCTS, 1, [Define this is you do not want support for aggregate types.]) + AC_DEFINE(FFI_NO_STRUCTS, 1, [Define this if you do not want support for aggregate types.]) fi) AM_CONDITIONAL(FFI_DEBUG, test "$enable_debug" = "yes") AC_ARG_ENABLE(raw-api, [ --disable-raw-api make the raw api unavailable], if test "$enable_raw_api" = "no"; then - AC_DEFINE(FFI_NO_RAW_API, 1, [Define this is you do not want support for the raw API.]) + AC_DEFINE(FFI_NO_RAW_API, 1, [Define this if you do not want support for the raw API.]) fi) AC_ARG_ENABLE(purify-safety, @@ -553,7 +602,7 @@ if test "x$GCC" = "xyes"; then toolexecdir='$(libdir)/gcc-lib/$(target_alias)' toolexeclibdir='$(libdir)' fi - multi_os_directory=`$CC -print-multi-os-directory` + multi_os_directory=`$CC $CFLAGS -print-multi-os-directory` case $multi_os_directory in .) ;; # Avoid trailing /. ../*) toolexeclibdir=$toolexeclibdir/$multi_os_directory ;; diff --git a/Modules/_ctypes/libffi/configure.host b/Modules/_ctypes/libffi/configure.host deleted file mode 100644 index f52457b39fd4..000000000000 --- a/Modules/_ctypes/libffi/configure.host +++ /dev/null @@ -1,11 +0,0 @@ -# configure.host -# -# This shell script handles all host based configuration for libffi. -# - -# THIS TABLE IS SORTED. KEEP IT THAT WAY. -case "${host}" in - frv*-elf) - LDFLAGS=`echo $LDFLAGS | sed "s/\-B[^ ]*libgloss\/frv\///"`\ -B`pwd`/../libgloss/frv/ - ;; -esac diff --git a/Modules/_ctypes/libffi/depcomp b/Modules/_ctypes/libffi/depcomp index df8eea7e4ce8..4ebd5b3a2f2d 100755 --- a/Modules/_ctypes/libffi/depcomp +++ b/Modules/_ctypes/libffi/depcomp @@ -1,10 +1,9 @@ #! /bin/sh # depcomp - compile a program generating dependencies as side-effects -scriptversion=2009-04-28.21; # UTC +scriptversion=2013-05-30.07; # UTC -# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009 Free -# Software Foundation, Inc. +# Copyright (C) 1999-2013 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -28,9 +27,9 @@ scriptversion=2009-04-28.21; # UTC case $1 in '') - echo "$0: No command. Try \`$0 --help' for more information." 1>&2 - exit 1; - ;; + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] @@ -40,11 +39,11 @@ as side-effects. Environment variables: depmode Dependency tracking mode. - source Source file read by `PROGRAMS ARGS'. - object Object file output by `PROGRAMS ARGS'. + source Source file read by 'PROGRAMS ARGS'. + object Object file output by 'PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. - tmpdepfile Temporary file to use when outputing dependencies. + tmpdepfile Temporary file to use when outputting dependencies. libtool Whether libtool is used (yes/no). Report bugs to . @@ -57,6 +56,66 @@ EOF ;; esac +# Get the directory component of the given path, and save it in the +# global variables '$dir'. Note that this directory component will +# be either empty or ending with a '/' character. This is deliberate. +set_dir_from () +{ + case $1 in + */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; + *) dir=;; + esac +} + +# Get the suffix-stripped basename of the given path, and save it the +# global variable '$base'. +set_base_from () +{ + base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` +} + +# If no dependency file was actually created by the compiler invocation, +# we still have to create a dummy depfile, to avoid errors with the +# Makefile "include basename.Plo" scheme. +make_dummy_depfile () +{ + echo "#dummy" > "$depfile" +} + +# Factor out some common post-processing of the generated depfile. +# Requires the auxiliary global variable '$tmpdepfile' to be set. +aix_post_process_depfile () +{ + # If the compiler actually managed to produce a dependency file, + # post-process it. + if test -f "$tmpdepfile"; then + # Each line is of the form 'foo.o: dependency.h'. + # Do two passes, one to just change these to + # $object: dependency.h + # and one to simply output + # dependency.h: + # which is needed to avoid the deleted-header problem. + { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" + sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" + } > "$depfile" + rm -f "$tmpdepfile" + else + make_dummy_depfile + fi +} + +# A tabulation character. +tab=' ' +# A newline character. +nl=' +' +# Character ranges might be problematic outside the C locale. +# These definitions help. +upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ +lower=abcdefghijklmnopqrstuvwxyz +digits=0123456789 +alpha=${upper}${lower} + if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 @@ -69,6 +128,9 @@ tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" +# Avoid interferences from the environment. +gccflag= dashmflag= + # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case @@ -80,18 +142,32 @@ if test "$depmode" = hp; then fi if test "$depmode" = dashXmstdout; then - # This is just like dashmstdout with a different argument. - dashmflag=-xM - depmode=dashmstdout + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout fi cygpath_u="cygpath -u -f -" if test "$depmode" = msvcmsys; then - # This is just like msvisualcpp but w/o cygpath translation. - # Just convert the backslash-escaped backslashes to single forward - # slashes to satisfy depend.m4 - cygpath_u="sed s,\\\\\\\\,/,g" - depmode=msvisualcpp + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvisualcpp +fi + +if test "$depmode" = msvc7msys; then + # This is just like msvc7 but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvc7 +fi + +if test "$depmode" = xlc; then + # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. + gccflag=-qmakedep=gcc,-MF + depmode=gcc fi case "$depmode" in @@ -114,8 +190,7 @@ gcc3) done "$@" stat=$? - if test $stat -eq 0; then : - else + if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi @@ -123,13 +198,17 @@ gcc3) ;; gcc) +## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. +## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. +## (see the conditional assignment to $gccflag above). ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like -## -MM, not -M (despite what the docs say). +## -MM, not -M (despite what the docs say). Also, it might not be +## supported by the other compilers which use the 'gcc' depmode. ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then @@ -137,31 +216,31 @@ gcc) fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? - if test $stat -eq 0; then : - else + if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" - alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz -## The second -e expression handles DOS-style file names with drive letters. + # The second -e expression handles DOS-style file names with drive + # letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" -## This next piece of magic avoids the `deleted header file' problem. +## This next piece of magic avoids the "deleted header file" problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. - tr ' ' ' -' < "$tmpdepfile" | -## Some versions of gcc put a space before the `:'. On the theory +## Some versions of gcc put a space before the ':'. On the theory ## that the space means something, we add a space to the output as -## well. +## well. hp depmode also adds that space, but also prefixes the VPATH +## to the object. Take care to not repeat it in the output. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; @@ -179,8 +258,7 @@ sgi) "$@" -MDupdate "$tmpdepfile" fi stat=$? - if test $stat -eq 0; then : - else + if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi @@ -188,43 +266,41 @@ sgi) if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" - # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; - # the IRIX cc adds comments like `#:fec' to the end of the + # the IRIX cc adds comments like '#:fec' to the end of the # dependency line. - tr ' ' ' -' < "$tmpdepfile" \ - | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ - tr ' -' ' ' >> "$depfile" + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ + | tr "$nl" ' ' >> "$depfile" echo >> "$depfile" - # The second pass generates a dummy entry for each header file. - tr ' ' ' -' < "$tmpdepfile" \ - | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ - >> "$depfile" + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" else - # The sourcefile does not contain any dependencies, so just - # store a dummy comment line, to avoid errors with the Makefile - # "include basename.Plo" scheme. - echo "#dummy" > "$depfile" + make_dummy_depfile fi rm -f "$tmpdepfile" ;; +xlc) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the - # current directory. Also, the AIX compiler puts `$object:' at the + # current directory. Also, the AIX compiler puts '$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. - dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` - test "x$dir" = "x$object" && dir= - base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + set_dir_from "$object" + set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.u tmpdepfile2=$base.u @@ -237,9 +313,7 @@ aix) "$@" -M fi stat=$? - - if test $stat -eq 0; then : - else + if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi @@ -248,44 +322,100 @@ aix) do test -f "$tmpdepfile" && break done - if test -f "$tmpdepfile"; then - # Each line is of the form `foo.o: dependent.h'. - # Do two passes, one to just change these to - # `$object: dependent.h' and one to simply `dependent.h:'. - sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" - # That's a tab and a space in the []. - sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" - else - # The sourcefile does not contain any dependencies, so just - # store a dummy comment line, to avoid errors with the Makefile - # "include basename.Plo" scheme. - echo "#dummy" > "$depfile" + aix_post_process_depfile + ;; + +tcc) + # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 + # FIXME: That version still under development at the moment of writing. + # Make that this statement remains true also for stable, released + # versions. + # It will wrap lines (doesn't matter whether long or short) with a + # trailing '\', as in: + # + # foo.o : \ + # foo.c \ + # foo.h \ + # + # It will put a trailing '\' even on the last line, and will use leading + # spaces rather than leading tabs (at least since its commit 0394caf7 + # "Emit spaces for -MD"). + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat fi + rm -f "$depfile" + # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. + # We have to change lines of the first kind to '$object: \'. + sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" + # And for each line of the second kind, we have to emit a 'dep.h:' + # dummy dependency, to avoid the deleted-header problem. + sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" rm -f "$tmpdepfile" ;; -icc) - # Intel's C compiler understands `-MD -MF file'. However on - # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c - # ICC 7.0 will fill foo.d with something like - # foo.o: sub/foo.c - # foo.o: sub/foo.h - # which is wrong. We want: - # sub/foo.o: sub/foo.c - # sub/foo.o: sub/foo.h - # sub/foo.c: - # sub/foo.h: - # ICC 7.1 will output +## The order of this option in the case statement is important, since the +## shell code in configure will try each of these formats in the order +## listed in this file. A plain '-MD' option would be understood by many +## compilers, so we must ensure this comes after the gcc and icc options. +pgcc) + # Portland's C compiler understands '-MD'. + # Will always output deps to 'file.d' where file is the root name of the + # source file under compilation, even if file resides in a subdirectory. + # The object file name does not affect the name of the '.d' file. + # pgcc 10.2 will output # foo.o: sub/foo.c sub/foo.h - # and will wrap long lines using \ : + # and will wrap long lines using '\' : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... + set_dir_from "$object" + # Use the source, not the object, to determine the base name, since + # that's sadly what pgcc will do too. + set_base_from "$source" + tmpdepfile=$base.d + + # For projects that build the same source file twice into different object + # files, the pgcc approach of using the *source* file root name can cause + # problems in parallel builds. Use a locking strategy to avoid stomping on + # the same $tmpdepfile. + lockdir=$base.d-lock + trap " + echo '$0: caught signal, cleaning up...' >&2 + rmdir '$lockdir' + exit 1 + " 1 2 13 15 + numtries=100 + i=$numtries + while test $i -gt 0; do + # mkdir is a portable test-and-set. + if mkdir "$lockdir" 2>/dev/null; then + # This process acquired the lock. + "$@" -MD + stat=$? + # Release the lock. + rmdir "$lockdir" + break + else + # If the lock is being held by a different process, wait + # until the winning process is done or we timeout. + while test -d "$lockdir" && test $i -gt 0; do + sleep 1 + i=`expr $i - 1` + done + fi + i=`expr $i - 1` + done + trap - 1 2 13 15 + if test $i -le 0; then + echo "$0: failed to acquire lock after $numtries attempts" >&2 + echo "$0: check lockdir '$lockdir'" >&2 + exit 1 + fi - "$@" -MD -MF "$tmpdepfile" - stat=$? - if test $stat -eq 0; then : - else + if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi @@ -297,8 +427,8 @@ icc) sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. - sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | - sed -e 's/$/ :/' >> "$depfile" + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ + | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; @@ -309,9 +439,8 @@ hp2) # 'foo.d', which lands next to the object file, wherever that # happens to be. # Much of this is similar to the tru64 case; see comments there. - dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` - test "x$dir" = "x$object" && dir= - base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + set_dir_from "$object" + set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.d tmpdepfile2=$dir.libs/$base.d @@ -322,8 +451,7 @@ hp2) "$@" +Maked fi stat=$? - if test $stat -eq 0; then : - else + if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi @@ -333,77 +461,107 @@ hp2) test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then - sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" - # Add `dependent.h:' lines. + sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" + # Add 'dependent.h:' lines. sed -ne '2,${ - s/^ *// - s/ \\*$// - s/$/:/ - p - }' "$tmpdepfile" >> "$depfile" + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" else - echo "#dummy" > "$depfile" + make_dummy_depfile fi rm -f "$tmpdepfile" "$tmpdepfile2" ;; tru64) - # The Tru64 compiler uses -MD to generate dependencies as a side - # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. - # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put - # dependencies in `foo.d' instead, so we check for that too. - # Subdirectories are respected. - dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` - test "x$dir" = "x$object" && dir= - base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` - - if test "$libtool" = yes; then - # With Tru64 cc, shared objects can also be used to make a - # static library. This mechanism is used in libtool 1.4 series to - # handle both shared and static libraries in a single compilation. - # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. - # - # With libtool 1.5 this exception was removed, and libtool now - # generates 2 separate objects for the 2 libraries. These two - # compilations output dependencies in $dir.libs/$base.o.d and - # in $dir$base.o.d. We have to check for both files, because - # one of the two compilations can be disabled. We should prefer - # $dir$base.o.d over $dir.libs/$base.o.d because the latter is - # automatically cleaned when .libs/ is deleted, while ignoring - # the former would cause a distcleancheck panic. - tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 - tmpdepfile2=$dir$base.o.d # libtool 1.5 - tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 - tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 - "$@" -Wc,-MD - else - tmpdepfile1=$dir$base.o.d - tmpdepfile2=$dir$base.d - tmpdepfile3=$dir$base.d - tmpdepfile4=$dir$base.d - "$@" -MD - fi - - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" - exit $stat - fi - - for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" - do - test -f "$tmpdepfile" && break - done - if test -f "$tmpdepfile"; then - sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" - # That's a tab and a space in the []. - sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" - else - echo "#dummy" > "$depfile" - fi - rm -f "$tmpdepfile" - ;; + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in 'foo.d' instead, so we check for that too. + # Subdirectories are respected. + set_dir_from "$object" + set_base_from "$object" + + if test "$libtool" = yes; then + # Libtool generates 2 separate objects for the 2 libraries. These + # two compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir$base.o.d # libtool 1.5 + tmpdepfile2=$dir.libs/$base.o.d # Likewise. + tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + # Same post-processing that is required for AIX mode. + aix_post_process_depfile + ;; + +msvc7) + if test "$libtool" = yes; then + showIncludes=-Wc,-showIncludes + else + showIncludes=-showIncludes + fi + "$@" $showIncludes > "$tmpdepfile" + stat=$? + grep -v '^Note: including file: ' "$tmpdepfile" + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The first sed program below extracts the file names and escapes + # backslashes for cygpath. The second sed program outputs the file + # name when reading, but also accumulates all include files in the + # hold buffer in order to output them again at the end. This only + # works with sed implementations that can handle large buffers. + sed < "$tmpdepfile" -n ' +/^Note: including file: *\(.*\)/ { + s//\1/ + s/\\/\\\\/g + p +}' | $cygpath_u | sort -u | sed -n ' +s/ /\\ /g +s/\(.*\)/'"$tab"'\1 \\/p +s/.\(.*\) \\/\1:/ +H +$ { + s/.*/'"$tab"'/ + G + p +}' >> "$depfile" + echo >> "$depfile" # make sure the fragment doesn't end with a backslash + rm -f "$tmpdepfile" + ;; + +msvc7msys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; #nosideeffect) # This comment above is used by automake to tell side-effect @@ -422,7 +580,7 @@ dashmstdout) shift fi - # Remove `-o $object'. + # Remove '-o $object'. IFS=" " for arg do @@ -442,18 +600,18 @@ dashmstdout) done test -z "$dashmflag" && dashmflag=-M - # Require at least two characters before searching for `:' + # Require at least two characters before searching for ':' # in the target name. This is to cope with DOS-style filenames: - # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. + # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. "$@" $dashmflag | - sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" + sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" - tr ' ' ' -' < "$tmpdepfile" | \ -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + # Some versions of the HPUX 10.20 sed can't process this sed invocation + # correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; @@ -503,12 +661,15 @@ makedepend) touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" - cat < "$tmpdepfile" > "$depfile" - sed '1,2d' "$tmpdepfile" | tr ' ' ' -' | \ -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + # makedepend may prepend the VPATH from the source file name to the object. + # No need to regex-escape $object, excess matching of '.' is harmless. + sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process the last invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed '1,2d' "$tmpdepfile" \ + | tr ' ' "$nl" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; @@ -525,7 +686,7 @@ cpp) shift fi - # Remove `-o $object'. + # Remove '-o $object'. IFS=" " for arg do @@ -544,10 +705,10 @@ cpp) esac done - "$@" -E | - sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ - -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | - sed '$ s: \\$::' > "$tmpdepfile" + "$@" -E \ + | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" @@ -579,23 +740,23 @@ msvisualcpp) shift ;; "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") - set fnord "$@" - shift - shift - ;; + set fnord "$@" + shift + shift + ;; *) - set fnord "$@" "$arg" - shift - shift - ;; + set fnord "$@" "$arg" + shift + shift + ;; esac done "$@" -E 2>/dev/null | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" - sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" - echo " " >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" + echo "$tab" >> "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; diff --git a/Modules/_ctypes/libffi/doc/libffi.info b/Modules/_ctypes/libffi/doc/libffi.info index 6d5acf830ac9..3990939473b5 100644 --- a/Modules/_ctypes/libffi/doc/libffi.info +++ b/Modules/_ctypes/libffi/doc/libffi.info @@ -1,5 +1,4 @@ -This is ../libffi/doc/libffi.info, produced by makeinfo version 4.13 -from ../libffi/doc/libffi.texi. +This is libffi.info, produced by makeinfo version 5.1 from libffi.texi. This manual is for Libffi, a portable foreign-function interface library. @@ -8,10 +7,9 @@ library. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2, or - (at your option) any later version. A copy of the license is - included in the section entitled "GNU General Public License". - + published by the Free Software Foundation; either version 2, or (at + your option) any later version. A copy of the license is included + in the section entitled "GNU General Public License". INFO-DIR-SECTION Development START-INFO-DIR-ENTRY @@ -31,10 +29,9 @@ library. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2, or - (at your option) any later version. A copy of the license is - included in the section entitled "GNU General Public License". - + published by the Free Software Foundation; either version 2, or (at + your option) any later version. A copy of the license is included + in the section entitled "GNU General Public License". * Menu: @@ -56,25 +53,25 @@ The calling convention is a set of assumptions made by the compiler about where function arguments will be found on entry to a function. A calling convention also specifies where the return value for a function is found. The calling convention is also sometimes called the "ABI" or -"Application Binary Interface". +"Application Binary Interface". Some programs may not know at the time of compilation what arguments are to be passed to a function. For instance, an interpreter may be told at run-time about the number and types of arguments used to call a -given function. `Libffi' can be used in such programs to provide a +given function. 'Libffi' can be used in such programs to provide a bridge from the interpreter program to compiled code. - The `libffi' library provides a portable, high level programming + The 'libffi' library provides a portable, high level programming interface to various calling conventions. This allows a programmer to call any function specified by a call interface description at run time. FFI stands for Foreign Function Interface. A foreign function -interface is the popular name for the interface that allows code -written in one language to call code written in another language. The -`libffi' library really only provides the lowest, machine dependent -layer of a fully featured foreign function interface. A layer must -exist above `libffi' that handles type conversions for values passed -between the two languages. +interface is the popular name for the interface that allows code written +in one language to call code written in another language. The 'libffi' +library really only provides the lowest, machine dependent layer of a +fully featured foreign function interface. A layer must exist above +'libffi' that handles type conversions for values passed between the two +languages.  File: libffi.info, Node: Using libffi, Next: Missing Features, Prev: Introduction, Up: Top @@ -97,45 +94,45 @@ File: libffi.info, Node: The Basics, Next: Simple Example, Up: Using libffi 2.1 The Basics ============== -`Libffi' assumes that you have a pointer to the function you wish to +'Libffi' assumes that you have a pointer to the function you wish to call and that you know the number and types of arguments to pass it, as well as the return type of the function. - The first thing you must do is create an `ffi_cif' object that + The first thing you must do is create an 'ffi_cif' object that matches the signature of the function you wish to call. This is a -separate step because it is common to make multiple calls using a -single `ffi_cif'. The "cif" in `ffi_cif' stands for Call InterFace. -To prepare a call interface object, use the function `ffi_prep_cif'. +separate step because it is common to make multiple calls using a single +'ffi_cif'. The "cif" in 'ffi_cif' stands for Call InterFace. To +prepare a call interface object, use the function 'ffi_prep_cif'. -- Function: ffi_status ffi_prep_cif (ffi_cif *CIF, ffi_abi ABI, unsigned int NARGS, ffi_type *RTYPE, ffi_type **ARGTYPES) This initializes CIF according to the given parameters. - ABI is the ABI to use; normally `FFI_DEFAULT_ABI' is what you - want. *note Multiple ABIs:: for more information. + ABI is the ABI to use; normally 'FFI_DEFAULT_ABI' is what you want. + *note Multiple ABIs:: for more information. NARGS is the number of arguments that this function accepts. - RTYPE is a pointer to an `ffi_type' structure that describes the + RTYPE is a pointer to an 'ffi_type' structure that describes the return type of the function. *Note Types::. - ARGTYPES is a vector of `ffi_type' pointers. ARGTYPES must have + ARGTYPES is a vector of 'ffi_type' pointers. ARGTYPES must have NARGS elements. If NARGS is 0, this argument is ignored. - `ffi_prep_cif' returns a `libffi' status code, of type - `ffi_status'. This will be either `FFI_OK' if everything worked - properly; `FFI_BAD_TYPEDEF' if one of the `ffi_type' objects is - incorrect; or `FFI_BAD_ABI' if the ABI parameter is invalid. + 'ffi_prep_cif' returns a 'libffi' status code, of type + 'ffi_status'. This will be either 'FFI_OK' if everything worked + properly; 'FFI_BAD_TYPEDEF' if one of the 'ffi_type' objects is + incorrect; or 'FFI_BAD_ABI' if the ABI parameter is invalid. If the function being called is variadic (varargs) then -`ffi_prep_cif_var' must be used instead of `ffi_prep_cif'. +'ffi_prep_cif_var' must be used instead of 'ffi_prep_cif'. - -- Function: ffi_status ffi_prep_cif_var (ffi_cif *CIF, ffi_abi - varabi, unsigned int NFIXEDARGS, unsigned int varntotalargs, - ffi_type *RTYPE, ffi_type **ARGTYPES) + -- Function: ffi_status ffi_prep_cif_var (ffi_cif *CIF, ffi_abi varabi, + unsigned int NFIXEDARGS, unsigned int varntotalargs, ffi_type + *RTYPE, ffi_type **ARGTYPES) This initializes CIF according to the given parameters for a call to a variadic function. In general it's operation is the same as - for `ffi_prep_cif' except that: + for 'ffi_prep_cif' except that: NFIXEDARGS is the number of fixed arguments, prior to any variadic arguments. It must be greater than zero. @@ -146,27 +143,26 @@ To prepare a call interface object, use the function `ffi_prep_cif'. Note that, different cif's must be prepped for calls to the same function when different numbers of arguments are passed. - Also note that a call to `ffi_prep_cif_var' with + Also note that a call to 'ffi_prep_cif_var' with NFIXEDARGS=NOTOTALARGS is NOT equivalent to a call to - `ffi_prep_cif'. + 'ffi_prep_cif'. - - To call a function using an initialized `ffi_cif', use the -`ffi_call' function: + To call a function using an initialized 'ffi_cif', use the 'ffi_call' +function: -- Function: void ffi_call (ffi_cif *CIF, void *FN, void *RVALUE, void **AVALUES) This calls the function FN according to the description given in - CIF. CIF must have already been prepared using `ffi_prep_cif'. + CIF. CIF must have already been prepared using 'ffi_prep_cif'. RVALUE is a pointer to a chunk of memory that will hold the result of the function call. This must be large enough to hold the - result and must be suitably aligned; it is the caller's + result, no smaller than the system register size (generally 32 or + 64 bits), and must be suitably aligned; it is the caller's responsibility to ensure this. If CIF declares that the function - returns `void' (using `ffi_type_void'), then RVALUE is ignored. - If RVALUE is `NULL', then the return value is discarded. + returns 'void' (using 'ffi_type_void'), then RVALUE is ignored. - AVALUES is a vector of `void *' pointers that point to the memory + AVALUES is a vector of 'void *' pointers that point to the memory locations holding the argument values for a call. If CIF declares that the function has no arguments (i.e., NARGS was 0), then AVALUES is ignored. Note that argument values may be modified by @@ -179,7 +175,7 @@ File: libffi.info, Node: Simple Example, Next: Types, Prev: The Basics, Up: 2.2 Simple Example ================== -Here is a trivial example that calls `puts' a few times. +Here is a trivial example that calls 'puts' a few times. #include #include @@ -190,7 +186,7 @@ Here is a trivial example that calls `puts' a few times. ffi_type *args[1]; void *values[1]; char *s; - int rc; + ffi_arg rc; /* Initialize the argument info vectors */ args[0] = &ffi_type_pointer; @@ -198,7 +194,7 @@ Here is a trivial example that calls `puts' a few times. /* Initialize the cif */ if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, - &ffi_type_uint, args) == FFI_OK) + &ffi_type_sint, args) == FFI_OK) { s = "Hello World!"; ffi_call(&cif, puts, &rc, values); @@ -232,80 +228,80 @@ File: libffi.info, Node: Primitive Types, Next: Structures, Up: Types 2.3.1 Primitive Types --------------------- -`Libffi' provides a number of built-in type descriptors that can be -used to describe argument and return types: +'Libffi' provides a number of built-in type descriptors that can be used +to describe argument and return types: -`ffi_type_void' - The type `void'. This cannot be used for argument types, only for +'ffi_type_void' + The type 'void'. This cannot be used for argument types, only for return values. -`ffi_type_uint8' +'ffi_type_uint8' An unsigned, 8-bit integer type. -`ffi_type_sint8' +'ffi_type_sint8' A signed, 8-bit integer type. -`ffi_type_uint16' +'ffi_type_uint16' An unsigned, 16-bit integer type. -`ffi_type_sint16' +'ffi_type_sint16' A signed, 16-bit integer type. -`ffi_type_uint32' +'ffi_type_uint32' An unsigned, 32-bit integer type. -`ffi_type_sint32' +'ffi_type_sint32' A signed, 32-bit integer type. -`ffi_type_uint64' +'ffi_type_uint64' An unsigned, 64-bit integer type. -`ffi_type_sint64' +'ffi_type_sint64' A signed, 64-bit integer type. -`ffi_type_float' - The C `float' type. +'ffi_type_float' + The C 'float' type. -`ffi_type_double' - The C `double' type. +'ffi_type_double' + The C 'double' type. -`ffi_type_uchar' - The C `unsigned char' type. +'ffi_type_uchar' + The C 'unsigned char' type. -`ffi_type_schar' - The C `signed char' type. (Note that there is not an exact - equivalent to the C `char' type in `libffi'; ordinarily you should - either use `ffi_type_schar' or `ffi_type_uchar' depending on - whether `char' is signed.) +'ffi_type_schar' + The C 'signed char' type. (Note that there is not an exact + equivalent to the C 'char' type in 'libffi'; ordinarily you should + either use 'ffi_type_schar' or 'ffi_type_uchar' depending on + whether 'char' is signed.) -`ffi_type_ushort' - The C `unsigned short' type. +'ffi_type_ushort' + The C 'unsigned short' type. -`ffi_type_sshort' - The C `short' type. +'ffi_type_sshort' + The C 'short' type. -`ffi_type_uint' - The C `unsigned int' type. +'ffi_type_uint' + The C 'unsigned int' type. -`ffi_type_sint' - The C `int' type. +'ffi_type_sint' + The C 'int' type. -`ffi_type_ulong' - The C `unsigned long' type. +'ffi_type_ulong' + The C 'unsigned long' type. -`ffi_type_slong' - The C `long' type. +'ffi_type_slong' + The C 'long' type. -`ffi_type_longdouble' - On platforms that have a C `long double' type, this is defined. - On other platforms, it is not. +'ffi_type_longdouble' + On platforms that have a C 'long double' type, this is defined. On + other platforms, it is not. -`ffi_type_pointer' - A generic `void *' pointer. You should use this for all pointers, +'ffi_type_pointer' + A generic 'void *' pointer. You should use this for all pointers, regardless of their real type. - Each of these is of type `ffi_type', so you must take the address -when passing to `ffi_prep_cif'. + Each of these is of type 'ffi_type', so you must take the address +when passing to 'ffi_prep_cif'.  File: libffi.info, Node: Structures, Next: Type Example, Prev: Primitive Types, Up: Types @@ -313,24 +309,24 @@ File: libffi.info, Node: Structures, Next: Type Example, Prev: Primitive Type 2.3.2 Structures ---------------- -Although `libffi' has no special support for unions or bit-fields, it -is perfectly happy passing structures back and forth. You must first -describe the structure to `libffi' by creating a new `ffi_type' object +Although 'libffi' has no special support for unions or bit-fields, it is +perfectly happy passing structures back and forth. You must first +describe the structure to 'libffi' by creating a new 'ffi_type' object for it. -- Data type: ffi_type - The `ffi_type' has the following members: - `size_t size' - This is set by `libffi'; you should initialize it to zero. + The 'ffi_type' has the following members: + 'size_t size' + This is set by 'libffi'; you should initialize it to zero. - `unsigned short alignment' - This is set by `libffi'; you should initialize it to zero. + 'unsigned short alignment' + This is set by 'libffi'; you should initialize it to zero. - `unsigned short type' - For a structure, this should be set to `FFI_TYPE_STRUCT'. + 'unsigned short type' + For a structure, this should be set to 'FFI_TYPE_STRUCT'. - `ffi_type **elements' - This is a `NULL'-terminated array of pointers to `ffi_type' + 'ffi_type **elements' + This is a 'NULL'-terminated array of pointers to 'ffi_type' objects. There is one element per field of the struct.  @@ -339,8 +335,8 @@ File: libffi.info, Node: Type Example, Prev: Structures, Up: Types 2.3.3 Type Example ------------------ -The following example initializes a `ffi_type' object representing the -`tm' struct from Linux's `time.h'. +The following example initializes a 'ffi_type' object representing the +'tm' struct from Linux's 'time.h'. Here is how the struct is defined: @@ -359,7 +355,7 @@ The following example initializes a `ffi_type' object representing the __const char *__tm_zone__; }; - Here is the corresponding code to describe this struct to `libffi': + Here is the corresponding code to describe this struct to 'libffi': { ffi_type tm_type; @@ -367,6 +363,7 @@ The following example initializes a `ffi_type' object representing the int i; tm_type.size = tm_type.alignment = 0; + tm_type.type = FFI_TYPE_STRUCT; tm_type.elements = &tm_type_elements; for (i = 0; i < 9; i++) @@ -387,9 +384,9 @@ File: libffi.info, Node: Multiple ABIs, Next: The Closure API, Prev: Types, ================= A given platform may provide multiple different ABIs at once. For -instance, the x86 platform has both `stdcall' and `fastcall' functions. +instance, the x86 platform has both 'stdcall' and 'fastcall' functions. - `libffi' provides some support for this. However, this is + 'libffi' provides some support for this. However, this is necessarily platform-specific.  @@ -398,32 +395,32 @@ File: libffi.info, Node: The Closure API, Next: Closure Example, Prev: Multip 2.5 The Closure API =================== -`libffi' also provides a way to write a generic function - a function +'libffi' also provides a way to write a generic function - a function that can accept and decode any combination of arguments. This can be -useful when writing an interpreter, or to provide wrappers for -arbitrary functions. +useful when writing an interpreter, or to provide wrappers for arbitrary +functions. - This facility is called the "closure API". Closures are not -supported on all platforms; you can check the `FFI_CLOSURES' define to -determine whether they are supported on the current platform. + This facility is called the "closure API". Closures are not supported +on all platforms; you can check the 'FFI_CLOSURES' define to determine +whether they are supported on the current platform. Because closures work by assembling a tiny function at runtime, they -require special allocation on platforms that have a non-executable -heap. Memory management for closures is handled by a pair of functions: +require special allocation on platforms that have a non-executable heap. +Memory management for closures is handled by a pair of functions: -- Function: void *ffi_closure_alloc (size_t SIZE, void **CODE) Allocate a chunk of memory holding SIZE bytes. This returns a pointer to the writable address, and sets *CODE to the corresponding executable address. - SIZE should be sufficient to hold a `ffi_closure' object. + SIZE should be sufficient to hold a 'ffi_closure' object. -- Function: void ffi_closure_free (void *WRITABLE) - Free memory allocated using `ffi_closure_alloc'. The argument is + Free memory allocated using 'ffi_closure_alloc'. The argument is the writable address that was returned. Once you have allocated the memory for a closure, you must construct -a `ffi_cif' describing the function call. Finally you can prepare the +a 'ffi_cif' describing the function call. Finally you can prepare the closure function: -- Function: ffi_status ffi_prep_closure_loc (ffi_closure *CLOSURE, @@ -431,40 +428,40 @@ closure function: **ARGS, void *USER_DATA), void *USER_DATA, void *CODELOC) Prepare a closure function. - CLOSURE is the address of a `ffi_closure' object; this is the - writable address returned by `ffi_closure_alloc'. + CLOSURE is the address of a 'ffi_closure' object; this is the + writable address returned by 'ffi_closure_alloc'. - CIF is the `ffi_cif' describing the function parameters. + CIF is the 'ffi_cif' describing the function parameters. USER_DATA is an arbitrary datum that is passed, uninterpreted, to your closure function. - CODELOC is the executable address returned by `ffi_closure_alloc'. + CODELOC is the executable address returned by 'ffi_closure_alloc'. FUN is the function which will be called when the closure is invoked. It is called with the arguments: - CIF - The `ffi_cif' passed to `ffi_prep_closure_loc'. + CIF + The 'ffi_cif' passed to 'ffi_prep_closure_loc'. - RET + RET A pointer to the memory used for the function's return value. FUN must fill this, unless the function is declared as - returning `void'. + returning 'void'. - ARGS + ARGS A vector of pointers to memory holding the arguments to the function. - USER_DATA - The same USER_DATA that was passed to `ffi_prep_closure_loc'. + USER_DATA + The same USER_DATA that was passed to 'ffi_prep_closure_loc'. - `ffi_prep_closure_loc' will return `FFI_OK' if everything went ok, + 'ffi_prep_closure_loc' will return 'FFI_OK' if everything went ok, and something else on error. - After calling `ffi_prep_closure_loc', you can cast CODELOC to the + After calling 'ffi_prep_closure_loc', you can cast CODELOC to the appropriate pointer-to-function type. - You may see old code referring to `ffi_prep_closure'. This function + You may see old code referring to 'ffi_prep_closure'. This function is deprecated, as it cannot handle the need for separate writable and executable addresses. @@ -474,26 +471,28 @@ File: libffi.info, Node: Closure Example, Prev: The Closure API, Up: Using li 2.6 Closure Example =================== -A trivial example that creates a new `puts' by binding `fputs' with -`stdin'. +A trivial example that creates a new 'puts' by binding 'fputs' with +'stdout'. #include #include /* Acts like puts with the file given at time of enclosure. */ - void puts_binding(ffi_cif *cif, unsigned int *ret, void* args[], - FILE *stream) + void puts_binding(ffi_cif *cif, void *ret, void* args[], + void *stream) { - *ret = fputs(*(char **)args[0], stream); + *(ffi_arg *)ret = fputs(*(char **)args[0], (FILE *)stream); } + typedef int (*puts_t)(char *); + int main() { ffi_cif cif; ffi_type *args[1]; ffi_closure *closure; - int (*bound_puts)(char *); + void *bound_puts; int rc; /* Allocate closure and bound_puts */ @@ -506,13 +505,13 @@ A trivial example that creates a new `puts' by binding `fputs' with /* Initialize the cif */ if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, - &ffi_type_uint, args) == FFI_OK) + &ffi_type_sint, args) == FFI_OK) { /* Initialize the closure, setting stream to stdout */ if (ffi_prep_closure_loc(closure, &cif, puts_binding, stdout, bound_puts) == FFI_OK) { - rc = bound_puts("Hello World!"); + rc = ((puts_t)bound_puts)("Hello World!"); /* rc now holds the result of the call to fputs */ } } @@ -530,7 +529,7 @@ File: libffi.info, Node: Missing Features, Next: Index, Prev: Using libffi, 3 Missing Features ****************** -`libffi' is missing a few features. We welcome patches to add support +'libffi' is missing a few features. We welcome patches to add support for these. * Variadic closures. @@ -560,16 +559,18 @@ Index * closure API: The Closure API. (line 13) * closures: The Closure API. (line 13) * FFI: Introduction. (line 31) -* ffi_call: The Basics. (line 63) +* ffi_call: The Basics. (line 62) +* FFI_CLOSURES: The Closure API. (line 13) * ffi_closure_alloc: The Closure API. (line 19) * ffi_closure_free: The Closure API. (line 26) -* FFI_CLOSURES: The Closure API. (line 13) * ffi_prep_cif: The Basics. (line 16) * ffi_prep_cif_var: The Basics. (line 39) * ffi_prep_closure_loc: The Closure API. (line 34) -* ffi_status <1>: The Closure API. (line 37) -* ffi_status: The Basics. (line 18) +* ffi_status: The Basics. (line 16) +* ffi_status <1>: The Basics. (line 39) +* ffi_status <2>: The Closure API. (line 34) * ffi_type: Structures. (line 11) +* ffi_type <1>: Structures. (line 11) * ffi_type_double: Primitive Types. (line 41) * ffi_type_float: Primitive Types. (line 38) * ffi_type_longdouble: Primitive Types. (line 71) @@ -592,25 +593,26 @@ Index * ffi_type_ushort: Primitive Types. (line 53) * ffi_type_void: Primitive Types. (line 10) * Foreign Function Interface: Introduction. (line 31) -* void <1>: The Closure API. (line 20) -* void: The Basics. (line 65) +* void: The Basics. (line 62) +* void <1>: The Closure API. (line 19) +* void <2>: The Closure API. (line 26)  Tag Table: -Node: Top712 -Node: Introduction1460 -Node: Using libffi3096 -Node: The Basics3582 -Node: Simple Example7224 -Node: Types8251 -Node: Primitive Types8534 -Node: Structures10354 -Node: Type Example11224 -Node: Multiple ABIs12447 -Node: The Closure API12818 -Node: Closure Example15762 -Node: Missing Features17321 -Node: Index17774 +Node: Top682 +Node: Introduction1429 +Node: Using libffi3061 +Node: The Basics3547 +Node: Simple Example7198 +Node: Types8229 +Node: Primitive Types8512 +Node: Structures10333 +Node: Type Example11207 +Node: Multiple ABIs12473 +Node: The Closure API12844 +Node: Closure Example15788 +Node: Missing Features17397 +Node: Index17850  End Tag Table diff --git a/Modules/_ctypes/libffi/doc/libffi.texi b/Modules/_ctypes/libffi/doc/libffi.texi index 5c0552b0c973..a2b1242802d7 100644 --- a/Modules/_ctypes/libffi/doc/libffi.texi +++ b/Modules/_ctypes/libffi/doc/libffi.texi @@ -184,11 +184,11 @@ This calls the function @var{fn} according to the description given in @var{rvalue} is a pointer to a chunk of memory that will hold the result of the function call. This must be large enough to hold the -result and must be suitably aligned; it is the caller's responsibility +result, no smaller than the system register size (generally 32 or 64 +bits), and must be suitably aligned; it is the caller's responsibility to ensure this. If @var{cif} declares that the function returns @code{void} (using @code{ffi_type_void}), then @var{rvalue} is -ignored. If @var{rvalue} is @samp{NULL}, then the return value is -discarded. +ignored. @var{avalues} is a vector of @code{void *} pointers that point to the memory locations holding the argument values for a call. If @var{cif} @@ -214,7 +214,7 @@ int main() ffi_type *args[1]; void *values[1]; char *s; - int rc; + ffi_arg rc; /* Initialize the argument info vectors */ args[0] = &ffi_type_pointer; @@ -222,7 +222,7 @@ int main() /* Initialize the cif */ if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, - &ffi_type_uint, args) == FFI_OK) + &ffi_type_sint, args) == FFI_OK) @{ s = "Hello World!"; ffi_call(&cif, puts, &rc, values); @@ -414,6 +414,7 @@ Here is the corresponding code to describe this struct to int i; tm_type.size = tm_type.alignment = 0; + tm_type.type = FFI_TYPE_STRUCT; tm_type.elements = &tm_type_elements; for (i = 0; i < 9; i++) @@ -533,28 +534,30 @@ writable and executable addresses. @section Closure Example A trivial example that creates a new @code{puts} by binding -@code{fputs} with @code{stdin}. +@code{fputs} with @code{stdout}. @example #include #include /* Acts like puts with the file given at time of enclosure. */ -void puts_binding(ffi_cif *cif, unsigned int *ret, void* args[], - FILE *stream) +void puts_binding(ffi_cif *cif, void *ret, void* args[], + void *stream) @{ - *ret = fputs(*(char **)args[0], stream); + *(ffi_arg *)ret = fputs(*(char **)args[0], (FILE *)stream); @} +typedef int (*puts_t)(char *); + int main() @{ ffi_cif cif; ffi_type *args[1]; ffi_closure *closure; - int (*bound_puts)(char *); + void *bound_puts; int rc; - + /* Allocate closure and bound_puts */ closure = ffi_closure_alloc(sizeof(ffi_closure), &bound_puts); @@ -565,13 +568,13 @@ int main() /* Initialize the cif */ if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, - &ffi_type_uint, args) == FFI_OK) + &ffi_type_sint, args) == FFI_OK) @{ /* Initialize the closure, setting stream to stdout */ - if (ffi_prep_closure_loc(closure, &cif, puts_binding, + if (ffi_prep_closure_loc(closure, &cif, puts_binding, stdout, bound_puts) == FFI_OK) @{ - rc = bound_puts("Hello World!"); + rc = ((puts_t)bound_puts)("Hello World!"); /* rc now holds the result of the call to fputs */ @} @} diff --git a/Modules/_ctypes/libffi/doc/stamp-vti b/Modules/_ctypes/libffi/doc/stamp-vti index 54255ba45d81..378595332fdc 100644 --- a/Modules/_ctypes/libffi/doc/stamp-vti +++ b/Modules/_ctypes/libffi/doc/stamp-vti @@ -1,4 +1,4 @@ -@set UPDATED 16 March 2013 -@set UPDATED-MONTH March 2013 -@set EDITION 3.0.13 -@set VERSION 3.0.13 +@set UPDATED 25 April 2014 +@set UPDATED-MONTH April 2014 +@set EDITION 3.1 +@set VERSION 3.1 diff --git a/Modules/_ctypes/libffi/doc/version.texi b/Modules/_ctypes/libffi/doc/version.texi index 54255ba45d81..378595332fdc 100644 --- a/Modules/_ctypes/libffi/doc/version.texi +++ b/Modules/_ctypes/libffi/doc/version.texi @@ -1,4 +1,4 @@ -@set UPDATED 16 March 2013 -@set UPDATED-MONTH March 2013 -@set EDITION 3.0.13 -@set VERSION 3.0.13 +@set UPDATED 25 April 2014 +@set UPDATED-MONTH April 2014 +@set EDITION 3.1 +@set VERSION 3.1 diff --git a/Modules/_ctypes/libffi/fficonfig.h.in b/Modules/_ctypes/libffi/fficonfig.h.in index c77585da4b45..cdef91b88feb 100644 --- a/Modules/_ctypes/libffi/fficonfig.h.in +++ b/Modules/_ctypes/libffi/fficonfig.h.in @@ -26,10 +26,10 @@ /* Cannot use malloc on this target, so, we revert to alternative means */ #undef FFI_MMAP_EXEC_WRIT -/* Define this is you do not want support for the raw API. */ +/* Define this if you do not want support for the raw API. */ #undef FFI_NO_RAW_API -/* Define this is you do not want support for aggregate types. */ +/* Define this if you do not want support for aggregate types. */ #undef FFI_NO_STRUCTS /* Define to 1 if you have `alloca', as a function or macro. */ @@ -73,6 +73,9 @@ /* Define if you have the long double type and it is bigger than a double */ #undef HAVE_LONG_DOUBLE +/* Define if you support more than one size of the long double type */ +#undef HAVE_LONG_DOUBLE_VARIANT + /* Define to 1 if you have the `memcpy' function. */ #undef HAVE_MEMCPY @@ -118,8 +121,7 @@ /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H -/* Define to the sub-directory in which libtool stores uninstalled libraries. - */ +/* Define to the sub-directory where libtool stores uninstalled libraries. */ #undef LT_OBJDIR /* Define to 1 if your C compiler doesn't accept -c and -o together. */ @@ -152,6 +154,9 @@ /* The size of `long double', as computed by sizeof. */ #undef SIZEOF_LONG_DOUBLE +/* The size of `size_t', as computed by sizeof. */ +#undef SIZEOF_SIZE_T + /* If using the C implementation of alloca, define if you know the direction of stack growth for your system; otherwise it will be automatically deduced at runtime. diff --git a/Modules/_ctypes/libffi/fficonfig.py.in b/Modules/_ctypes/libffi/fficonfig.py.in index 35be29cb3a69..d10249866d3c 100644 --- a/Modules/_ctypes/libffi/fficonfig.py.in +++ b/Modules/_ctypes/libffi/fficonfig.py.in @@ -6,7 +6,7 @@ src/closures.c ffi_platforms = { 'MIPS_IRIX': ['src/mips/ffi.c', 'src/mips/o32.S', 'src/mips/n32.S'], 'MIPS_LINUX': ['src/mips/ffi.c', 'src/mips/o32.S'], - 'X86': ['src/x86/ffi.c', 'src/x86/sysv.S'], + 'X86': ['src/x86/ffi.c', 'src/x86/sysv.S', 'src/x86/win32.S'], 'X86_FREEBSD': ['src/x86/ffi.c', 'src/x86/freebsd.S'], 'X86_WIN32': ['src/x86/ffi.c', 'src/x86/win32.S'], 'SPARC': ['src/sparc/ffi.c', 'src/sparc/v8.S', 'src/sparc/v9.S'], @@ -14,9 +14,10 @@ ffi_platforms = { 'IA64': ['src/ia64/ffi.c', 'src/ia64/unix.S'], 'M32R': ['src/m32r/sysv.S', 'src/m32r/ffi.c'], 'M68K': ['src/m68k/ffi.c', 'src/m68k/sysv.S'], - 'POWERPC': ['src/powerpc/ffi.c', 'src/powerpc/sysv.S', 'src/powerpc/ppc_closure.S', 'src/powerpc/linux64.S', 'src/powerpc/linux64_closure.S'], + 'POWERPC': ['src/powerpc/ffi.c', 'src/powerpc/ffi_sysv.c', 'src/powerpc/ffi_linux64.c', 'src/powerpc/sysv.S', 'src/powerpc/ppc_closure.S', 'src/powerpc/linux64.S', 'src/powerpc/linux64_closure.S'], 'POWERPC_AIX': ['src/powerpc/ffi_darwin.c', 'src/powerpc/aix.S', 'src/powerpc/aix_closure.S'], 'POWERPC_FREEBSD': ['src/powerpc/ffi.c', 'src/powerpc/sysv.S', 'src/powerpc/ppc_closure.S'], + 'AARCH64': ['src/aarch64/sysv.S', 'src/aarch64/ffi.c'], 'ARM': ['src/arm/sysv.S', 'src/arm/ffi.c'], 'LIBFFI_CRIS': ['src/cris/sysv.S', 'src/cris/ffi.c'], 'FRV': ['src/frv/eabi.S', 'src/frv/ffi.c'], diff --git a/Modules/_ctypes/libffi/generate-darwin-source-and-headers.py b/Modules/_ctypes/libffi/generate-darwin-source-and-headers.py new file mode 100644 index 000000000000..964e861d43c8 --- /dev/null +++ b/Modules/_ctypes/libffi/generate-darwin-source-and-headers.py @@ -0,0 +1,209 @@ +#!/usr/bin/env python +import subprocess +import os +import errno +import collections +import glob +import argparse + +class Platform(object): + pass + +class simulator_platform(Platform): + directory = 'darwin_ios' + sdk = 'iphonesimulator' + arch = 'i386' + triple = 'i386-apple-darwin11' + version_min = '-miphoneos-version-min=5.1.1' + + prefix = "#ifdef __i386__\n\n" + suffix = "\n\n#endif" + src_dir = 'x86' + src_files = ['darwin.S', 'win32.S', 'ffi.c'] + + +class simulator64_platform(Platform): + directory = 'darwin_ios' + sdk = 'iphonesimulator' + arch = 'x86_64' + triple = 'x86_64-apple-darwin13' + version_min = '-miphoneos-version-min=7.0' + + prefix = "#ifdef __x86_64__\n\n" + suffix = "\n\n#endif" + src_dir = 'x86' + src_files = ['darwin64.S', 'ffi64.c'] + + +class device_platform(Platform): + directory = 'darwin_ios' + sdk = 'iphoneos' + arch = 'armv7' + triple = 'arm-apple-darwin11' + version_min = '-miphoneos-version-min=5.1.1' + + prefix = "#ifdef __arm__\n\n" + suffix = "\n\n#endif" + src_dir = 'arm' + src_files = ['sysv.S', 'trampoline.S', 'ffi.c'] + + +class device64_platform(Platform): + directory = 'darwin_ios' + sdk = 'iphoneos' + arch = 'arm64' + triple = 'aarch64-apple-darwin13' + version_min = '-miphoneos-version-min=7.0' + + prefix = "#ifdef __arm64__\n\n" + suffix = "\n\n#endif" + src_dir = 'aarch64' + src_files = ['sysv.S', 'ffi.c'] + + +class desktop32_platform(Platform): + directory = 'darwin_osx' + sdk = 'macosx' + arch = 'i386' + triple = 'i386-apple-darwin10' + version_min = '-mmacosx-version-min=10.6' + src_dir = 'x86' + src_files = ['darwin.S', 'win32.S', 'ffi.c'] + + prefix = "#ifdef __i386__\n\n" + suffix = "\n\n#endif" + + +class desktop64_platform(Platform): + directory = 'darwin_osx' + sdk = 'macosx' + arch = 'x86_64' + triple = 'x86_64-apple-darwin10' + version_min = '-mmacosx-version-min=10.6' + + prefix = "#ifdef __x86_64__\n\n" + suffix = "\n\n#endif" + src_dir = 'x86' + src_files = ['darwin64.S', 'ffi64.c'] + + +def mkdir_p(path): + try: + os.makedirs(path) + except OSError as exc: # Python >2.5 + if exc.errno == errno.EEXIST: + pass + else: + raise + + +def move_file(src_dir, dst_dir, filename, file_suffix=None, prefix='', suffix=''): + mkdir_p(dst_dir) + out_filename = filename + + if file_suffix: + split_name = os.path.splitext(filename) + out_filename = "%s_%s%s" % (split_name[0], file_suffix, split_name[1]) + + with open(os.path.join(src_dir, filename)) as in_file: + with open(os.path.join(dst_dir, out_filename), 'w') as out_file: + if prefix: + out_file.write(prefix) + + out_file.write(in_file.read()) + + if suffix: + out_file.write(suffix) + + +def list_files(src_dir, pattern=None, filelist=None): + if pattern: filelist = glob.iglob(os.path.join(src_dir, pattern)) + for file in filelist: + yield os.path.basename(file) + + +def copy_files(src_dir, dst_dir, pattern=None, filelist=None, file_suffix=None, prefix=None, suffix=None): + for filename in list_files(src_dir, pattern=pattern, filelist=filelist): + move_file(src_dir, dst_dir, filename, file_suffix=file_suffix, prefix=prefix, suffix=suffix) + + +def copy_src_platform_files(platform): + src_dir = os.path.join('src', platform.src_dir) + dst_dir = os.path.join(platform.directory, 'src', platform.src_dir) + copy_files(src_dir, dst_dir, filelist=platform.src_files, file_suffix=platform.arch, prefix=platform.prefix, suffix=platform.suffix) + + +def build_target(platform, platform_headers): + def xcrun_cmd(cmd): + return 'xcrun -sdk %s %s -arch %s' % (platform.sdk, cmd, platform.arch) + + tag='%s-%s' % (platform.sdk, platform.arch) + build_dir = 'build_%s' % tag + mkdir_p(build_dir) + env = dict(CC=xcrun_cmd('clang'), + LD=xcrun_cmd('ld'), + CFLAGS='%s' % (platform.version_min)) + working_dir = os.getcwd() + try: + os.chdir(build_dir) + subprocess.check_call(['../configure', '-host', platform.triple], env=env) + finally: + os.chdir(working_dir) + + for src_dir in [build_dir, os.path.join(build_dir, 'include')]: + copy_files(src_dir, + os.path.join(platform.directory, 'include'), + pattern='*.h', + file_suffix=platform.arch, + prefix=platform.prefix, + suffix=platform.suffix) + + for filename in list_files(src_dir, pattern='*.h'): + platform_headers[filename].add((platform.prefix, platform.arch, platform.suffix)) + + +def make_tramp(): + with open('src/arm/trampoline.S', 'w') as tramp_out: + p = subprocess.Popen(['bash', 'src/arm/gentramp.sh'], stdout=tramp_out) + p.wait() + + +def generate_source_and_headers(generate_osx=True, generate_ios=True): + copy_files('src', 'darwin_common/src', pattern='*.c') + copy_files('include', 'darwin_common/include', pattern='*.h') + + if generate_ios: + make_tramp() + copy_src_platform_files(simulator_platform) + copy_src_platform_files(simulator64_platform) + copy_src_platform_files(device_platform) + copy_src_platform_files(device64_platform) + if generate_osx: + copy_src_platform_files(desktop32_platform) + copy_src_platform_files(desktop64_platform) + + platform_headers = collections.defaultdict(set) + + if generate_ios: + build_target(simulator_platform, platform_headers) + build_target(simulator64_platform, platform_headers) + build_target(device_platform, platform_headers) + build_target(device64_platform, platform_headers) + if generate_osx: + build_target(desktop32_platform, platform_headers) + build_target(desktop64_platform, platform_headers) + + mkdir_p('darwin_common/include') + for header_name, tag_tuples in platform_headers.iteritems(): + basename, suffix = os.path.splitext(header_name) + with open(os.path.join('darwin_common/include', header_name), 'w') as header: + for tag_tuple in tag_tuples: + header.write('%s#include <%s_%s%s>\n%s\n' % (tag_tuple[0], basename, tag_tuple[1], suffix, tag_tuple[2])) + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument('--only-ios', action='store_true', default=False) + parser.add_argument('--only-osx', action='store_true', default=False) + args = parser.parse_args() + + generate_source_and_headers(generate_osx=not args.only_ios, generate_ios=not args.only_osx) diff --git a/Modules/_ctypes/libffi/generate-ios-source-and-headers.py b/Modules/_ctypes/libffi/generate-ios-source-and-headers.py deleted file mode 100644 index c2bca734ef17..000000000000 --- a/Modules/_ctypes/libffi/generate-ios-source-and-headers.py +++ /dev/null @@ -1,160 +0,0 @@ -#!/usr/bin/env python - -import subprocess -import re -import os -import errno -import collections -import sys - -class Platform(object): - pass - -sdk_re = re.compile(r'.*-sdk ([a-zA-Z0-9.]*)') - -def sdkinfo(sdkname): - ret = {} - for line in subprocess.Popen(['xcodebuild', '-sdk', sdkname, '-version'], stdout=subprocess.PIPE).stdout: - kv = line.strip().split(': ', 1) - if len(kv) == 2: - k,v = kv - ret[k] = v - return ret - -sim_sdk_info = sdkinfo('iphonesimulator') -device_sdk_info = sdkinfo('iphoneos') - -def latest_sdks(): - latest_sim = None - latest_device = None - for line in subprocess.Popen(['xcodebuild', '-showsdks'], stdout=subprocess.PIPE).stdout: - match = sdk_re.match(line) - if match: - if 'Simulator' in line: - latest_sim = match.group(1) - elif 'iOS' in line: - latest_device = match.group(1) - - return latest_sim, latest_device - -sim_sdk, device_sdk = latest_sdks() - -class simulator_platform(Platform): - sdk='iphonesimulator' - arch = 'i386' - name = 'simulator' - triple = 'i386-apple-darwin10' - sdkroot = sim_sdk_info['Path'] - - prefix = "#if !defined(__arm__) && defined(__i386__)\n\n" - suffix = "\n\n#endif" - -class device_platform(Platform): - sdk='iphoneos' - name = 'ios' - arch = 'armv7' - triple = 'arm-apple-darwin10' - sdkroot = device_sdk_info['Path'] - - prefix = "#ifdef __arm__\n\n" - suffix = "\n\n#endif" - - -def move_file(src_dir, dst_dir, filename, file_suffix=None, prefix='', suffix=''): - if not os.path.exists(dst_dir): - os.makedirs(dst_dir) - - out_filename = filename - - if file_suffix: - split_name = os.path.splitext(filename) - out_filename = "%s_%s%s" % (split_name[0], file_suffix, split_name[1]) - - with open(os.path.join(src_dir, filename)) as in_file: - with open(os.path.join(dst_dir, out_filename), 'w') as out_file: - if prefix: - out_file.write(prefix) - - out_file.write(in_file.read()) - - if suffix: - out_file.write(suffix) - -headers_seen = collections.defaultdict(set) - -def move_source_tree(src_dir, dest_dir, dest_include_dir, arch=None, prefix=None, suffix=None): - for root, dirs, files in os.walk(src_dir, followlinks=True): - relroot = os.path.relpath(root,src_dir) - - def move_dir(arch, prefix='', suffix='', files=[]): - for file in files: - file_suffix = None - if file.endswith('.h'): - if dest_include_dir: - file_suffix = arch - if arch: - headers_seen[file].add(arch) - move_file(root, dest_include_dir, file, arch, prefix=prefix, suffix=suffix) - - elif dest_dir: - outroot = os.path.join(dest_dir, relroot) - move_file(root, outroot, file, prefix=prefix, suffix=suffix) - - if relroot == '.': - move_dir(arch=arch, - files=files, - prefix=prefix, - suffix=suffix) - elif relroot == 'arm': - move_dir(arch='arm', - prefix="#ifdef __arm__\n\n", - suffix="\n\n#endif", - files=files) - elif relroot == 'x86': - move_dir(arch='i386', - prefix="#if !defined(__arm__) && defined(__i386__)\n\n", - suffix="\n\n#endif", - files=files) - -def build_target(platform): - def xcrun_cmd(cmd): - return subprocess.check_output(['xcrun', '-sdk', platform.sdkroot, '-find', cmd]).strip() - - build_dir = 'build_' + platform.name - if not os.path.exists(build_dir): - os.makedirs(build_dir) - env = dict(CC=xcrun_cmd('clang'), - LD=xcrun_cmd('ld'), - CFLAGS='-arch %s -isysroot %s -miphoneos-version-min=4.0' % (platform.arch, platform.sdkroot)) - working_dir=os.getcwd() - try: - os.chdir(build_dir) - subprocess.check_call(['../configure', '-host', platform.triple], env=env) - move_source_tree('.', None, '../ios/include', - arch=platform.arch, - prefix=platform.prefix, - suffix=platform.suffix) - move_source_tree('./include', None, '../ios/include', - arch=platform.arch, - prefix=platform.prefix, - suffix=platform.suffix) - finally: - os.chdir(working_dir) - - for header_name, archs in headers_seen.iteritems(): - basename, suffix = os.path.splitext(header_name) - -def main(): - move_source_tree('src', 'ios/src', 'ios/include') - move_source_tree('include', None, 'ios/include') - build_target(simulator_platform) - build_target(device_platform) - - for header_name, archs in headers_seen.iteritems(): - basename, suffix = os.path.splitext(header_name) - with open(os.path.join('ios/include', header_name), 'w') as header: - for arch in archs: - header.write('#include <%s_%s%s>\n' % (basename, arch, suffix)) - -if __name__ == '__main__': - main() diff --git a/Modules/_ctypes/libffi/generate-osx-source-and-headers.py b/Modules/_ctypes/libffi/generate-osx-source-and-headers.py deleted file mode 100644 index 64313c1a3640..000000000000 --- a/Modules/_ctypes/libffi/generate-osx-source-and-headers.py +++ /dev/null @@ -1,153 +0,0 @@ -#!/usr/bin/env python -import subprocess -import re -import os -import errno -import collections -import sys - -class Platform(object): - pass - -sdk_re = re.compile(r'.*-sdk ([a-zA-Z0-9.]*)') - -def sdkinfo(sdkname): - ret = {} - for line in subprocess.Popen(['xcodebuild', '-sdk', sdkname, '-version'], stdout=subprocess.PIPE).stdout: - kv = line.strip().split(': ', 1) - if len(kv) == 2: - k,v = kv - ret[k] = v - return ret - -desktop_sdk_info = sdkinfo('macosx') - -def latest_sdks(): - latest_desktop = None - for line in subprocess.Popen(['xcodebuild', '-showsdks'], stdout=subprocess.PIPE).stdout: - match = sdk_re.match(line) - if match: - if 'OS X' in line: - latest_desktop = match.group(1) - - return latest_desktop - -desktop_sdk = latest_sdks() - -class desktop_platform_32(Platform): - sdk='macosx' - arch = 'i386' - name = 'mac32' - triple = 'i386-apple-darwin10' - sdkroot = desktop_sdk_info['Path'] - - prefix = "#if defined(__i386__) && !defined(__x86_64__)\n\n" - suffix = "\n\n#endif" - -class desktop_platform_64(Platform): - sdk='macosx' - arch = 'x86_64' - name = 'mac' - triple = 'x86_64-apple-darwin10' - sdkroot = desktop_sdk_info['Path'] - - prefix = "#if !defined(__i386__) && defined(__x86_64__)\n\n" - suffix = "\n\n#endif" - -def move_file(src_dir, dst_dir, filename, file_suffix=None, prefix='', suffix=''): - if not os.path.exists(dst_dir): - os.makedirs(dst_dir) - - out_filename = filename - - if file_suffix: - split_name = os.path.splitext(filename) - out_filename = "%s_%s%s" % (split_name[0], file_suffix, split_name[1]) - - with open(os.path.join(src_dir, filename)) as in_file: - with open(os.path.join(dst_dir, out_filename), 'w') as out_file: - if prefix: - out_file.write(prefix) - - out_file.write(in_file.read()) - - if suffix: - out_file.write(suffix) - -headers_seen = collections.defaultdict(set) - -def move_source_tree(src_dir, dest_dir, dest_include_dir, arch=None, prefix=None, suffix=None): - for root, dirs, files in os.walk(src_dir, followlinks=True): - relroot = os.path.relpath(root,src_dir) - - def move_dir(arch, prefix='', suffix='', files=[]): - for file in files: - file_suffix = None - if file.endswith('.h'): - if dest_include_dir: - file_suffix = arch - if arch: - headers_seen[file].add(arch) - move_file(root, dest_include_dir, file, arch, prefix=prefix, suffix=suffix) - - elif dest_dir: - outroot = os.path.join(dest_dir, relroot) - move_file(root, outroot, file, prefix=prefix, suffix=suffix) - - if relroot == '.': - move_dir(arch=arch, - files=files, - prefix=prefix, - suffix=suffix) - elif relroot == 'x86': - move_dir(arch='i386', - prefix="#if defined(__i386__) && !defined(__x86_64__)\n\n", - suffix="\n\n#endif", - files=files) - move_dir(arch='x86_64', - prefix="#if !defined(__i386__) && defined(__x86_64__)\n\n", - suffix="\n\n#endif", - files=files) - -def build_target(platform): - def xcrun_cmd(cmd): - return subprocess.check_output(['xcrun', '-sdk', platform.sdkroot, '-find', cmd]).strip() - - build_dir = 'build_' + platform.name - if not os.path.exists(build_dir): - os.makedirs(build_dir) - env = dict(CC=xcrun_cmd('clang'), - LD=xcrun_cmd('ld'), - CFLAGS='-arch %s -isysroot %s -mmacosx-version-min=10.6' % (platform.arch, platform.sdkroot)) - working_dir=os.getcwd() - try: - os.chdir(build_dir) - subprocess.check_call(['../configure', '-host', platform.triple], env=env) - move_source_tree('.', None, '../osx/include', - arch=platform.arch, - prefix=platform.prefix, - suffix=platform.suffix) - move_source_tree('./include', None, '../osx/include', - arch=platform.arch, - prefix=platform.prefix, - suffix=platform.suffix) - finally: - os.chdir(working_dir) - - for header_name, archs in headers_seen.iteritems(): - basename, suffix = os.path.splitext(header_name) - -def main(): - move_source_tree('src', 'osx/src', 'osx/include') - move_source_tree('include', None, 'osx/include') - build_target(desktop_platform_32) - build_target(desktop_platform_64) - - for header_name, archs in headers_seen.iteritems(): - basename, suffix = os.path.splitext(header_name) - with open(os.path.join('osx/include', header_name), 'w') as header: - for arch in archs: - header.write('#include <%s_%s%s>\n' % (basename, arch, suffix)) - -if __name__ == '__main__': - main() diff --git a/Modules/_ctypes/libffi/include/Makefile.in b/Modules/_ctypes/libffi/include/Makefile.in index 2c36e36d07bb..9d747e80e54e 100644 --- a/Modules/_ctypes/libffi/include/Makefile.in +++ b/Modules/_ctypes/libffi/include/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.12.2 from Makefile.am. +# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2012 Free Software Foundation, Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -15,23 +15,51 @@ @SET_MAKE@ VPATH = @srcdir@ -am__make_dryrun = \ - { \ - am__dry=no; \ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ - echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ - | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ - *) \ - for am__flg in $$MAKEFLAGS; do \ - case $$am__flg in \ - *=*|--*) ;; \ - *n*) am__dry=yes; break;; \ - esac; \ - done;; \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ - test $$am__dry = yes; \ - } + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -52,7 +80,7 @@ build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = include -DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(srcdir)/ffi.h.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/asmcfi.m4 \ @@ -75,6 +103,18 @@ mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/fficonfig.h CONFIG_CLEAN_FILES = ffi.h ffitarget.h CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ @@ -111,12 +151,30 @@ am__uninstall_files_from_dir = { \ } am__installdirs = "$(DESTDIR)$(includesdir)" HEADERS = $(nodist_includes_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LTLDFLAGS = @AM_LTLDFLAGS@ AM_RUNTESTFLAGS = @AM_RUNTESTFLAGS@ AR = @AR@ @@ -132,6 +190,10 @@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ @@ -147,6 +209,7 @@ FFI_EXEC_TRAMPOLINE_TABLE = @FFI_EXEC_TRAMPOLINE_TABLE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_LONG_DOUBLE = @HAVE_LONG_DOUBLE@ +HAVE_LONG_DOUBLE_VARIANT = @HAVE_LONG_DOUBLE_VARIANT@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ @@ -193,6 +256,7 @@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ @@ -315,26 +379,15 @@ uninstall-nodist_includesHEADERS: files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(includesdir)'; $(am__uninstall_files_from_dir) -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ + $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ @@ -346,15 +399,11 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $$unique; \ fi; \ fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique @@ -363,9 +412,10 @@ GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am -cscopelist: $(HEADERS) $(SOURCES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP)'; \ +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ @@ -517,18 +567,19 @@ uninstall-am: uninstall-nodist_includesHEADERS .MAKE: install-am install-strip -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ - clean-libtool cscopelist ctags distclean distclean-generic \ - distclean-libtool distclean-tags distdir dvi dvi-am html \ - html-am info info-am install install-am install-data \ - install-data-am install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-man install-nodist_includesHEADERS \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags uninstall uninstall-am uninstall-nodist_includesHEADERS +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool cscopelist-am ctags ctags-am distclean \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man \ + install-nodist_includesHEADERS install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-nodist_includesHEADERS # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/Modules/_ctypes/libffi/include/ffi.h.in b/Modules/_ctypes/libffi/include/ffi.h.in index a51583bcd326..93c776fbbee3 100644 --- a/Modules/_ctypes/libffi/include/ffi.h.in +++ b/Modules/_ctypes/libffi/include/ffi.h.in @@ -221,6 +221,11 @@ typedef struct { #endif } ffi_cif; +#if HAVE_LONG_DOUBLE_VARIANT +/* Used to adjust size/alignment of ffi types. */ +void ffi_prep_types (ffi_abi abi); +# endif + /* Used internally, but overridden by some architectures */ ffi_status ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi, diff --git a/Modules/_ctypes/libffi/include/ffi_common.h b/Modules/_ctypes/libffi/include/ffi_common.h index 650ca6997df9..37f5a9e92494 100644 --- a/Modules/_ctypes/libffi/include/ffi_common.h +++ b/Modules/_ctypes/libffi/include/ffi_common.h @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------- - ffi_common.h - Copyright (C) 2011, 2012 Anthony Green + ffi_common.h - Copyright (C) 2011, 2012, 2013 Anthony Green Copyright (C) 2007 Free Software Foundation, Inc Copyright (c) 1996 Red Hat, Inc. @@ -19,10 +19,14 @@ extern "C" { /* Do not move this. Some versions of AIX are very picky about where this is positioned. */ #ifdef __GNUC__ -/* mingw64 defines this already in malloc.h. */ -#ifndef alloca -# define alloca __builtin_alloca -#endif +# if HAVE_ALLOCA_H +# include +# else + /* mingw64 defines this already in malloc.h. */ +# ifndef alloca +# define alloca __builtin_alloca +# endif +# endif # define MAYBE_UNUSED __attribute__((__unused__)) #else # define MAYBE_UNUSED @@ -30,17 +34,17 @@ extern "C" { # include # else # ifdef _AIX - #pragma alloca +# pragma alloca # else # ifndef alloca /* predefined by HP cc +Olibcalls */ # ifdef _MSC_VER # define alloca _alloca # else char *alloca (); -# endif # endif # endif # endif +# endif #endif /* Check for the existence of memcpy. */ diff --git a/Modules/_ctypes/libffi/install-sh b/Modules/_ctypes/libffi/install-sh index 6781b987bdbc..377bb8687ffe 100755 --- a/Modules/_ctypes/libffi/install-sh +++ b/Modules/_ctypes/libffi/install-sh @@ -1,7 +1,7 @@ #!/bin/sh # install - install a program, script, or datafile -scriptversion=2009-04-28.21; # UTC +scriptversion=2011-11-20.07; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the @@ -35,7 +35,7 @@ scriptversion=2009-04-28.21; # UTC # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent -# `make' implicit rules from creating a file called install from it +# 'make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written @@ -156,6 +156,10 @@ while test $# -ne 0; do -s) stripcmd=$stripprog;; -t) dst_arg=$2 + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac shift;; -T) no_target_directory=true;; @@ -186,6 +190,10 @@ if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then fi shift # arg dst_arg=$arg + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac done fi @@ -194,13 +202,17 @@ if test $# -eq 0; then echo "$0: no input file specified." >&2 exit 1 fi - # It's OK to call `install-sh -d' without argument. + # It's OK to call 'install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then - trap '(exit $?); exit' 1 2 13 15 + do_exit='(exit $ret); exit $ret' + trap "ret=129; $do_exit" 1 + trap "ret=130; $do_exit" 2 + trap "ret=141; $do_exit" 13 + trap "ret=143; $do_exit" 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. @@ -228,9 +240,9 @@ fi for src do - # Protect names starting with `-'. + # Protect names problematic for 'test' and other utilities. case $src in - -*) src=./$src;; + -* | [=\(\)!]) src=./$src;; esac if test -n "$dir_arg"; then @@ -252,12 +264,7 @@ do echo "$0: no destination specified." >&2 exit 1 fi - dst=$dst_arg - # Protect names starting with `-'. - case $dst in - -*) dst=./$dst;; - esac # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. @@ -347,7 +354,7 @@ do if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or - # other-writeable bit of parent directory when it shouldn't. + # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. ls_ld_tmpdir=`ls -ld "$tmpdir"` case $ls_ld_tmpdir in @@ -385,7 +392,7 @@ do case $dstdir in /*) prefix='/';; - -*) prefix='./';; + [-=\(\)!]*) prefix='./';; *) prefix='';; esac @@ -403,7 +410,7 @@ do for d do - test -z "$d" && continue + test X"$d" = X && continue prefix=$prefix$d if test -d "$prefix"; then diff --git a/Modules/_ctypes/libffi/libffi.pc.in b/Modules/_ctypes/libffi/libffi.pc.in index c2e1c7b33cdf..edf6fde5e2be 100644 --- a/Modules/_ctypes/libffi/libffi.pc.in +++ b/Modules/_ctypes/libffi/libffi.pc.in @@ -1,10 +1,11 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ +toolexeclibdir=@toolexeclibdir@ includedir=${libdir}/@PACKAGE_NAME@-@PACKAGE_VERSION@/include Name: @PACKAGE_NAME@ Description: Library supporting Foreign Function Interfaces Version: @PACKAGE_VERSION@ -Libs: -L${libdir} -lffi +Libs: -L${toolexeclibdir} -lffi Cflags: -I${includedir} diff --git a/Modules/_ctypes/libffi/libffi.xcodeproj/project.pbxproj b/Modules/_ctypes/libffi/libffi.xcodeproj/project.pbxproj index 14c39a2a4e13..1cf396ffa1e4 100644 --- a/Modules/_ctypes/libffi/libffi.xcodeproj/project.pbxproj +++ b/Modules/_ctypes/libffi/libffi.xcodeproj/project.pbxproj @@ -7,473 +7,448 @@ objects = { /* Begin PBXBuildFile section */ - 6C43CBDC1534F76F00162364 /* ffi.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CBBD1534F76F00162364 /* ffi.c */; }; - 6C43CBDD1534F76F00162364 /* sysv.S in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CBBF1534F76F00162364 /* sysv.S */; }; - 6C43CBDE1534F76F00162364 /* trampoline.S in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CBC01534F76F00162364 /* trampoline.S */; }; - 6C43CBE61534F76F00162364 /* darwin.S in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CBC91534F76F00162364 /* darwin.S */; }; - 6C43CBE81534F76F00162364 /* ffi.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CBCB1534F76F00162364 /* ffi.c */; }; - 6C43CC1F1534F77800162364 /* darwin.S in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC051534F77800162364 /* darwin.S */; }; - 6C43CC201534F77800162364 /* darwin64.S in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC061534F77800162364 /* darwin64.S */; }; - 6C43CC211534F77800162364 /* ffi.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC071534F77800162364 /* ffi.c */; }; - 6C43CC221534F77800162364 /* ffi64.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC081534F77800162364 /* ffi64.c */; }; - 6C43CC2F1534F7BE00162364 /* closures.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC281534F7BE00162364 /* closures.c */; }; - 6C43CC301534F7BE00162364 /* closures.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC281534F7BE00162364 /* closures.c */; }; - 6C43CC351534F7BE00162364 /* java_raw_api.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC2B1534F7BE00162364 /* java_raw_api.c */; }; - 6C43CC361534F7BE00162364 /* java_raw_api.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC2B1534F7BE00162364 /* java_raw_api.c */; }; - 6C43CC371534F7BE00162364 /* prep_cif.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC2C1534F7BE00162364 /* prep_cif.c */; }; - 6C43CC381534F7BE00162364 /* prep_cif.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC2C1534F7BE00162364 /* prep_cif.c */; }; - 6C43CC391534F7BE00162364 /* raw_api.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC2D1534F7BE00162364 /* raw_api.c */; }; - 6C43CC3A1534F7BE00162364 /* raw_api.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC2D1534F7BE00162364 /* raw_api.c */; }; - 6C43CC3B1534F7BE00162364 /* types.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC2E1534F7BE00162364 /* types.c */; }; - 6C43CC3C1534F7BE00162364 /* types.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC2E1534F7BE00162364 /* types.c */; }; - 6C43CC971535032600162364 /* ffi.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC8D1535032600162364 /* ffi.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6C43CC981535032600162364 /* ffi_common.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC8E1535032600162364 /* ffi_common.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6C43CC991535032600162364 /* ffi_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC8F1535032600162364 /* ffi_i386.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6C43CC9A1535032600162364 /* ffi_x86_64.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC901535032600162364 /* ffi_x86_64.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6C43CC9B1535032600162364 /* fficonfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC911535032600162364 /* fficonfig.h */; }; - 6C43CC9C1535032600162364 /* fficonfig_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC921535032600162364 /* fficonfig_i386.h */; }; - 6C43CC9D1535032600162364 /* fficonfig_x86_64.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC931535032600162364 /* fficonfig_x86_64.h */; }; - 6C43CC9E1535032600162364 /* ffitarget.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC941535032600162364 /* ffitarget.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6C43CC9F1535032600162364 /* ffitarget_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC951535032600162364 /* ffitarget_i386.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6C43CCA01535032600162364 /* ffitarget_x86_64.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC961535032600162364 /* ffitarget_x86_64.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6C43CCAD1535039600162364 /* ffi.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCA21535039600162364 /* ffi.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6C43CCAE1535039600162364 /* ffi_armv7.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCA31535039600162364 /* ffi_armv7.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6C43CCAF1535039600162364 /* ffi_common.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCA41535039600162364 /* ffi_common.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6C43CCB01535039600162364 /* ffi_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCA51535039600162364 /* ffi_i386.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6C43CCB11535039600162364 /* fficonfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCA61535039600162364 /* fficonfig.h */; }; - 6C43CCB21535039600162364 /* fficonfig_armv7.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCA71535039600162364 /* fficonfig_armv7.h */; }; - 6C43CCB31535039600162364 /* fficonfig_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCA81535039600162364 /* fficonfig_i386.h */; }; - 6C43CCB41535039600162364 /* ffitarget.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCA91535039600162364 /* ffitarget.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6C43CCB51535039600162364 /* ffitarget_arm.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCAA1535039600162364 /* ffitarget_arm.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6C43CCB61535039600162364 /* ffitarget_armv7.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCAB1535039600162364 /* ffitarget_armv7.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6C43CCB71535039600162364 /* ffitarget_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCAC1535039600162364 /* ffitarget_i386.h */; settings = {ATTRIBUTES = (Public, ); }; }; + DBFA714A187F1D8600A76262 /* ffi.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA713E187F1D8600A76262 /* ffi.h */; }; + DBFA714B187F1D8600A76262 /* ffi_common.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA713F187F1D8600A76262 /* ffi_common.h */; }; + DBFA714C187F1D8600A76262 /* fficonfig.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA7140187F1D8600A76262 /* fficonfig.h */; }; + DBFA714D187F1D8600A76262 /* ffitarget.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA7141187F1D8600A76262 /* ffitarget.h */; }; + DBFA714E187F1D8600A76262 /* closures.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7143187F1D8600A76262 /* closures.c */; }; + DBFA714F187F1D8600A76262 /* closures.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7143187F1D8600A76262 /* closures.c */; }; + DBFA7156187F1D8600A76262 /* prep_cif.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7147187F1D8600A76262 /* prep_cif.c */; }; + DBFA7157187F1D8600A76262 /* prep_cif.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7147187F1D8600A76262 /* prep_cif.c */; }; + DBFA7158187F1D8600A76262 /* raw_api.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7148187F1D8600A76262 /* raw_api.c */; }; + DBFA7159187F1D8600A76262 /* raw_api.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7148187F1D8600A76262 /* raw_api.c */; }; + DBFA715A187F1D8600A76262 /* types.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7149187F1D8600A76262 /* types.c */; }; + DBFA715B187F1D8600A76262 /* types.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7149187F1D8600A76262 /* types.c */; }; + DBFA7177187F1D9B00A76262 /* ffi_arm64.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA716C187F1D9B00A76262 /* ffi_arm64.c */; }; + DBFA7178187F1D9B00A76262 /* sysv_arm64.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA716D187F1D9B00A76262 /* sysv_arm64.S */; }; + DBFA7179187F1D9B00A76262 /* ffi_armv7.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA716F187F1D9B00A76262 /* ffi_armv7.c */; }; + DBFA717A187F1D9B00A76262 /* sysv_armv7.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7170187F1D9B00A76262 /* sysv_armv7.S */; }; + DBFA717B187F1D9B00A76262 /* trampoline_armv7.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7171187F1D9B00A76262 /* trampoline_armv7.S */; }; + DBFA717C187F1D9B00A76262 /* darwin64_x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7173187F1D9B00A76262 /* darwin64_x86_64.S */; }; + DBFA717D187F1D9B00A76262 /* darwin_i386.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7174187F1D9B00A76262 /* darwin_i386.S */; }; + DBFA717E187F1D9B00A76262 /* ffi64_x86_64.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7175187F1D9B00A76262 /* ffi64_x86_64.c */; }; + DBFA717F187F1D9B00A76262 /* ffi_i386.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7176187F1D9B00A76262 /* ffi_i386.c */; }; + DBFA718E187F1DA100A76262 /* ffi_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA7182187F1DA100A76262 /* ffi_i386.h */; }; + DBFA718F187F1DA100A76262 /* ffi_x86_64.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA7183187F1DA100A76262 /* ffi_x86_64.h */; }; + DBFA7190187F1DA100A76262 /* fficonfig_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA7184187F1DA100A76262 /* fficonfig_i386.h */; }; + DBFA7191187F1DA100A76262 /* fficonfig_x86_64.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA7185187F1DA100A76262 /* fficonfig_x86_64.h */; }; + DBFA7192187F1DA100A76262 /* ffitarget_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA7186187F1DA100A76262 /* ffitarget_i386.h */; }; + DBFA7193187F1DA100A76262 /* ffitarget_x86_64.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA7187187F1DA100A76262 /* ffitarget_x86_64.h */; }; + DBFA7194187F1DA100A76262 /* darwin64_x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA718A187F1DA100A76262 /* darwin64_x86_64.S */; }; + DBFA7195187F1DA100A76262 /* darwin_i386.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA718B187F1DA100A76262 /* darwin_i386.S */; }; + DBFA7196187F1DA100A76262 /* ffi64_x86_64.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA718C187F1DA100A76262 /* ffi64_x86_64.c */; }; + DBFA7197187F1DA100A76262 /* ffi_i386.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA718D187F1DA100A76262 /* ffi_i386.c */; }; /* End PBXBuildFile section */ +/* Begin PBXCopyFilesBuildPhase section */ + DB13B1641849DF1E0010F42D /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 8; + dstPath = "include/$(PRODUCT_NAME)"; + dstSubfolderSpec = 16; + files = ( + ); + runOnlyForDeploymentPostprocessing = 1; + }; +/* End PBXCopyFilesBuildPhase section */ + /* Begin PBXFileReference section */ - 6C43CB3D1534E9D100162364 /* libffi.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libffi.a; sourceTree = BUILT_PRODUCTS_DIR; }; - 6C43CBBD1534F76F00162364 /* ffi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi.c; sourceTree = ""; }; - 6C43CBBF1534F76F00162364 /* sysv.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = sysv.S; sourceTree = ""; }; - 6C43CBC01534F76F00162364 /* trampoline.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = trampoline.S; sourceTree = ""; }; - 6C43CBC91534F76F00162364 /* darwin.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = darwin.S; sourceTree = ""; }; - 6C43CBCB1534F76F00162364 /* ffi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi.c; sourceTree = ""; }; - 6C43CC051534F77800162364 /* darwin.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = darwin.S; sourceTree = ""; }; - 6C43CC061534F77800162364 /* darwin64.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = darwin64.S; sourceTree = ""; }; - 6C43CC071534F77800162364 /* ffi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi.c; sourceTree = ""; }; - 6C43CC081534F77800162364 /* ffi64.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi64.c; sourceTree = ""; }; - 6C43CC281534F7BE00162364 /* closures.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = closures.c; path = src/closures.c; sourceTree = SOURCE_ROOT; }; - 6C43CC2B1534F7BE00162364 /* java_raw_api.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = java_raw_api.c; path = src/java_raw_api.c; sourceTree = SOURCE_ROOT; }; - 6C43CC2C1534F7BE00162364 /* prep_cif.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = prep_cif.c; path = src/prep_cif.c; sourceTree = SOURCE_ROOT; }; - 6C43CC2D1534F7BE00162364 /* raw_api.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = raw_api.c; path = src/raw_api.c; sourceTree = SOURCE_ROOT; }; - 6C43CC2E1534F7BE00162364 /* types.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = types.c; path = src/types.c; sourceTree = SOURCE_ROOT; }; - 6C43CC8D1535032600162364 /* ffi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi.h; sourceTree = ""; }; - 6C43CC8E1535032600162364 /* ffi_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_common.h; sourceTree = ""; }; - 6C43CC8F1535032600162364 /* ffi_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_i386.h; sourceTree = ""; }; - 6C43CC901535032600162364 /* ffi_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_x86_64.h; sourceTree = ""; }; - 6C43CC911535032600162364 /* fficonfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig.h; sourceTree = ""; }; - 6C43CC921535032600162364 /* fficonfig_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_i386.h; sourceTree = ""; }; - 6C43CC931535032600162364 /* fficonfig_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_x86_64.h; sourceTree = ""; }; - 6C43CC941535032600162364 /* ffitarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget.h; sourceTree = ""; }; - 6C43CC951535032600162364 /* ffitarget_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_i386.h; sourceTree = ""; }; - 6C43CC961535032600162364 /* ffitarget_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_x86_64.h; sourceTree = ""; }; - 6C43CCA21535039600162364 /* ffi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi.h; sourceTree = ""; }; - 6C43CCA31535039600162364 /* ffi_armv7.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_armv7.h; sourceTree = ""; }; - 6C43CCA41535039600162364 /* ffi_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_common.h; sourceTree = ""; }; - 6C43CCA51535039600162364 /* ffi_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_i386.h; sourceTree = ""; }; - 6C43CCA61535039600162364 /* fficonfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig.h; sourceTree = ""; }; - 6C43CCA71535039600162364 /* fficonfig_armv7.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_armv7.h; sourceTree = ""; }; - 6C43CCA81535039600162364 /* fficonfig_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_i386.h; sourceTree = ""; }; - 6C43CCA91535039600162364 /* ffitarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget.h; sourceTree = ""; }; - 6C43CCAA1535039600162364 /* ffitarget_arm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_arm.h; sourceTree = ""; }; - 6C43CCAB1535039600162364 /* ffitarget_armv7.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_armv7.h; sourceTree = ""; }; - 6C43CCAC1535039600162364 /* ffitarget_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_i386.h; sourceTree = ""; }; - F6F980BA147386130008F121 /* libffi.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libffi.a; sourceTree = BUILT_PRODUCTS_DIR; }; + DB13B1661849DF1E0010F42D /* libffi.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libffi.a; sourceTree = BUILT_PRODUCTS_DIR; }; + DB13B1911849DF510010F42D /* ffi.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = ffi.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; + DBFA713E187F1D8600A76262 /* ffi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi.h; sourceTree = ""; }; + DBFA713F187F1D8600A76262 /* ffi_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_common.h; sourceTree = ""; }; + DBFA7140187F1D8600A76262 /* fficonfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig.h; sourceTree = ""; }; + DBFA7141187F1D8600A76262 /* ffitarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget.h; sourceTree = ""; }; + DBFA7143187F1D8600A76262 /* closures.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = closures.c; sourceTree = ""; }; + DBFA7145187F1D8600A76262 /* dlmalloc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dlmalloc.c; sourceTree = ""; }; + DBFA7147187F1D8600A76262 /* prep_cif.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = prep_cif.c; sourceTree = ""; }; + DBFA7148187F1D8600A76262 /* raw_api.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = raw_api.c; sourceTree = ""; }; + DBFA7149187F1D8600A76262 /* types.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = types.c; sourceTree = ""; }; + DBFA715E187F1D9B00A76262 /* ffi_arm64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_arm64.h; sourceTree = ""; }; + DBFA715F187F1D9B00A76262 /* ffi_armv7.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_armv7.h; sourceTree = ""; }; + DBFA7160187F1D9B00A76262 /* ffi_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_i386.h; sourceTree = ""; }; + DBFA7161187F1D9B00A76262 /* ffi_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_x86_64.h; sourceTree = ""; }; + DBFA7162187F1D9B00A76262 /* fficonfig_arm64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_arm64.h; sourceTree = ""; }; + DBFA7163187F1D9B00A76262 /* fficonfig_armv7.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_armv7.h; sourceTree = ""; }; + DBFA7164187F1D9B00A76262 /* fficonfig_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_i386.h; sourceTree = ""; }; + DBFA7165187F1D9B00A76262 /* fficonfig_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_x86_64.h; sourceTree = ""; }; + DBFA7166187F1D9B00A76262 /* ffitarget_arm64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_arm64.h; sourceTree = ""; }; + DBFA7167187F1D9B00A76262 /* ffitarget_armv7.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_armv7.h; sourceTree = ""; }; + DBFA7168187F1D9B00A76262 /* ffitarget_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_i386.h; sourceTree = ""; }; + DBFA7169187F1D9B00A76262 /* ffitarget_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_x86_64.h; sourceTree = ""; }; + DBFA716C187F1D9B00A76262 /* ffi_arm64.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi_arm64.c; sourceTree = ""; }; + DBFA716D187F1D9B00A76262 /* sysv_arm64.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = sysv_arm64.S; sourceTree = ""; }; + DBFA716F187F1D9B00A76262 /* ffi_armv7.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi_armv7.c; sourceTree = ""; }; + DBFA7170187F1D9B00A76262 /* sysv_armv7.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = sysv_armv7.S; sourceTree = ""; }; + DBFA7171187F1D9B00A76262 /* trampoline_armv7.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = trampoline_armv7.S; sourceTree = ""; }; + DBFA7173187F1D9B00A76262 /* darwin64_x86_64.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = darwin64_x86_64.S; sourceTree = ""; }; + DBFA7174187F1D9B00A76262 /* darwin_i386.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = darwin_i386.S; sourceTree = ""; }; + DBFA7175187F1D9B00A76262 /* ffi64_x86_64.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi64_x86_64.c; sourceTree = ""; }; + DBFA7176187F1D9B00A76262 /* ffi_i386.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi_i386.c; sourceTree = ""; }; + DBFA7182187F1DA100A76262 /* ffi_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_i386.h; sourceTree = ""; }; + DBFA7183187F1DA100A76262 /* ffi_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_x86_64.h; sourceTree = ""; }; + DBFA7184187F1DA100A76262 /* fficonfig_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_i386.h; sourceTree = ""; }; + DBFA7185187F1DA100A76262 /* fficonfig_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_x86_64.h; sourceTree = ""; }; + DBFA7186187F1DA100A76262 /* ffitarget_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_i386.h; sourceTree = ""; }; + DBFA7187187F1DA100A76262 /* ffitarget_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_x86_64.h; sourceTree = ""; }; + DBFA718A187F1DA100A76262 /* darwin64_x86_64.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = darwin64_x86_64.S; sourceTree = ""; }; + DBFA718B187F1DA100A76262 /* darwin_i386.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = darwin_i386.S; sourceTree = ""; }; + DBFA718C187F1DA100A76262 /* ffi64_x86_64.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi64_x86_64.c; sourceTree = ""; }; + DBFA718D187F1DA100A76262 /* ffi_i386.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi_i386.c; sourceTree = ""; }; /* End PBXFileReference section */ -/* Begin PBXFrameworksBuildPhase section */ - 6C43CB3A1534E9D100162364 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( +/* Begin PBXGroup section */ + DB13B15B1849DEB70010F42D = { + isa = PBXGroup; + children = ( + DBFA713C187F1D8600A76262 /* darwin_common */, + DBFA715C187F1D9B00A76262 /* darwin_ios */, + DBFA7180187F1DA100A76262 /* darwin_osx */, + DB13B1671849DF1E0010F42D /* Products */, ); - runOnlyForDeploymentPostprocessing = 0; + sourceTree = ""; }; - F6F980B7147386130008F121 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( + DB13B1671849DF1E0010F42D /* Products */ = { + isa = PBXGroup; + children = ( + DB13B1661849DF1E0010F42D /* libffi.a */, + DB13B1911849DF510010F42D /* ffi.dylib */, ); - runOnlyForDeploymentPostprocessing = 0; + name = Products; + sourceTree = ""; }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 6C43CBAF1534F76F00162364 /* iOS */ = { + DBFA713C187F1D8600A76262 /* darwin_common */ = { isa = PBXGroup; children = ( - 6C43CCA11535039600162364 /* include */, - 6C43CBBB1534F76F00162364 /* src */, + DBFA713D187F1D8600A76262 /* include */, + DBFA7142187F1D8600A76262 /* src */, ); - name = iOS; - path = ios; + path = "darwin_common"; sourceTree = ""; }; - 6C43CBBB1534F76F00162364 /* src */ = { + DBFA713D187F1D8600A76262 /* include */ = { isa = PBXGroup; children = ( - 6C43CBC81534F76F00162364 /* x86 */, - 6C43CBBC1534F76F00162364 /* arm */, + DBFA713E187F1D8600A76262 /* ffi.h */, + DBFA713F187F1D8600A76262 /* ffi_common.h */, + DBFA7140187F1D8600A76262 /* fficonfig.h */, + DBFA7141187F1D8600A76262 /* ffitarget.h */, ); - path = src; + path = include; sourceTree = ""; }; - 6C43CBBC1534F76F00162364 /* arm */ = { + DBFA7142187F1D8600A76262 /* src */ = { isa = PBXGroup; children = ( - 6C43CBBD1534F76F00162364 /* ffi.c */, - 6C43CBBF1534F76F00162364 /* sysv.S */, - 6C43CBC01534F76F00162364 /* trampoline.S */, + DBFA7143187F1D8600A76262 /* closures.c */, + DBFA7145187F1D8600A76262 /* dlmalloc.c */, + DBFA7147187F1D8600A76262 /* prep_cif.c */, + DBFA7148187F1D8600A76262 /* raw_api.c */, + DBFA7149187F1D8600A76262 /* types.c */, ); - path = arm; + path = src; sourceTree = ""; }; - 6C43CBC81534F76F00162364 /* x86 */ = { + DBFA715C187F1D9B00A76262 /* darwin_ios */ = { isa = PBXGroup; children = ( - 6C43CBC91534F76F00162364 /* darwin.S */, - 6C43CBCB1534F76F00162364 /* ffi.c */, + DBFA715D187F1D9B00A76262 /* include */, + DBFA716A187F1D9B00A76262 /* src */, ); - path = x86; + path = "darwin_ios"; sourceTree = ""; }; - 6C43CBF01534F77800162364 /* OS X */ = { + DBFA715D187F1D9B00A76262 /* include */ = { isa = PBXGroup; children = ( - 6C43CC8C1535032600162364 /* include */, - 6C43CBFC1534F77800162364 /* src */, + DBFA715E187F1D9B00A76262 /* ffi_arm64.h */, + DBFA715F187F1D9B00A76262 /* ffi_armv7.h */, + DBFA7160187F1D9B00A76262 /* ffi_i386.h */, + DBFA7161187F1D9B00A76262 /* ffi_x86_64.h */, + DBFA7162187F1D9B00A76262 /* fficonfig_arm64.h */, + DBFA7163187F1D9B00A76262 /* fficonfig_armv7.h */, + DBFA7164187F1D9B00A76262 /* fficonfig_i386.h */, + DBFA7165187F1D9B00A76262 /* fficonfig_x86_64.h */, + DBFA7166187F1D9B00A76262 /* ffitarget_arm64.h */, + DBFA7167187F1D9B00A76262 /* ffitarget_armv7.h */, + DBFA7168187F1D9B00A76262 /* ffitarget_i386.h */, + DBFA7169187F1D9B00A76262 /* ffitarget_x86_64.h */, ); - name = "OS X"; - path = osx; + path = include; sourceTree = ""; }; - 6C43CBFC1534F77800162364 /* src */ = { + DBFA716A187F1D9B00A76262 /* src */ = { isa = PBXGroup; children = ( - 6C43CC041534F77800162364 /* x86 */, + DBFA716B187F1D9B00A76262 /* aarch64 */, + DBFA716E187F1D9B00A76262 /* arm */, + DBFA7172187F1D9B00A76262 /* x86 */, ); path = src; sourceTree = ""; }; - 6C43CC041534F77800162364 /* x86 */ = { + DBFA716B187F1D9B00A76262 /* aarch64 */ = { isa = PBXGroup; children = ( - 6C43CC051534F77800162364 /* darwin.S */, - 6C43CC061534F77800162364 /* darwin64.S */, - 6C43CC071534F77800162364 /* ffi.c */, - 6C43CC081534F77800162364 /* ffi64.c */, + DBFA716C187F1D9B00A76262 /* ffi_arm64.c */, + DBFA716D187F1D9B00A76262 /* sysv_arm64.S */, ); - path = x86; + path = aarch64; sourceTree = ""; }; - 6C43CC3D1534F7C400162364 /* src */ = { + DBFA716E187F1D9B00A76262 /* arm */ = { isa = PBXGroup; children = ( - 6C43CC281534F7BE00162364 /* closures.c */, - 6C43CC2B1534F7BE00162364 /* java_raw_api.c */, - 6C43CC2C1534F7BE00162364 /* prep_cif.c */, - 6C43CC2D1534F7BE00162364 /* raw_api.c */, - 6C43CC2E1534F7BE00162364 /* types.c */, - ); - name = src; - path = ios; + DBFA716F187F1D9B00A76262 /* ffi_armv7.c */, + DBFA7170187F1D9B00A76262 /* sysv_armv7.S */, + DBFA7171187F1D9B00A76262 /* trampoline_armv7.S */, + ); + path = arm; sourceTree = ""; }; - 6C43CC8C1535032600162364 /* include */ = { + DBFA7172187F1D9B00A76262 /* x86 */ = { isa = PBXGroup; children = ( - 6C43CC8D1535032600162364 /* ffi.h */, - 6C43CC8E1535032600162364 /* ffi_common.h */, - 6C43CC8F1535032600162364 /* ffi_i386.h */, - 6C43CC901535032600162364 /* ffi_x86_64.h */, - 6C43CC911535032600162364 /* fficonfig.h */, - 6C43CC921535032600162364 /* fficonfig_i386.h */, - 6C43CC931535032600162364 /* fficonfig_x86_64.h */, - 6C43CC941535032600162364 /* ffitarget.h */, - 6C43CC951535032600162364 /* ffitarget_i386.h */, - 6C43CC961535032600162364 /* ffitarget_x86_64.h */, + DBFA7173187F1D9B00A76262 /* darwin64_x86_64.S */, + DBFA7174187F1D9B00A76262 /* darwin_i386.S */, + DBFA7175187F1D9B00A76262 /* ffi64_x86_64.c */, + DBFA7176187F1D9B00A76262 /* ffi_i386.c */, ); - path = include; + path = x86; + sourceTree = ""; + }; + DBFA7180187F1DA100A76262 /* darwin_osx */ = { + isa = PBXGroup; + children = ( + DBFA7181187F1DA100A76262 /* include */, + DBFA7188187F1DA100A76262 /* src */, + ); + path = "darwin_osx"; sourceTree = ""; }; - 6C43CCA11535039600162364 /* include */ = { + DBFA7181187F1DA100A76262 /* include */ = { isa = PBXGroup; children = ( - 6C43CCA21535039600162364 /* ffi.h */, - 6C43CCA31535039600162364 /* ffi_armv7.h */, - 6C43CCA41535039600162364 /* ffi_common.h */, - 6C43CCA51535039600162364 /* ffi_i386.h */, - 6C43CCA61535039600162364 /* fficonfig.h */, - 6C43CCA71535039600162364 /* fficonfig_armv7.h */, - 6C43CCA81535039600162364 /* fficonfig_i386.h */, - 6C43CCA91535039600162364 /* ffitarget.h */, - 6C43CCAA1535039600162364 /* ffitarget_arm.h */, - 6C43CCAB1535039600162364 /* ffitarget_armv7.h */, - 6C43CCAC1535039600162364 /* ffitarget_i386.h */, + DBFA7182187F1DA100A76262 /* ffi_i386.h */, + DBFA7183187F1DA100A76262 /* ffi_x86_64.h */, + DBFA7184187F1DA100A76262 /* fficonfig_i386.h */, + DBFA7185187F1DA100A76262 /* fficonfig_x86_64.h */, + DBFA7186187F1DA100A76262 /* ffitarget_i386.h */, + DBFA7187187F1DA100A76262 /* ffitarget_x86_64.h */, ); path = include; sourceTree = ""; }; - F6B0839514721EE50031D8A1 = { + DBFA7188187F1DA100A76262 /* src */ = { isa = PBXGroup; children = ( - 6C43CC3D1534F7C400162364 /* src */, - 6C43CBAF1534F76F00162364 /* iOS */, - 6C43CBF01534F77800162364 /* OS X */, - F6F980C6147386260008F121 /* Products */, + DBFA7189187F1DA100A76262 /* x86 */, ); + path = src; sourceTree = ""; }; - F6F980C6147386260008F121 /* Products */ = { + DBFA7189187F1DA100A76262 /* x86 */ = { isa = PBXGroup; children = ( - F6F980BA147386130008F121 /* libffi.a */, - 6C43CB3D1534E9D100162364 /* libffi.a */, + DBFA718A187F1DA100A76262 /* darwin64_x86_64.S */, + DBFA718B187F1DA100A76262 /* darwin_i386.S */, + DBFA718C187F1DA100A76262 /* ffi64_x86_64.c */, + DBFA718D187F1DA100A76262 /* ffi_i386.c */, ); - name = Products; - path = ../..; - sourceTree = BUILT_PRODUCTS_DIR; + path = x86; + sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ - 6C43CB3B1534E9D100162364 /* Headers */ = { + DB13B18F1849DF510010F42D /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 6C43CC971535032600162364 /* ffi.h in Headers */, - 6C43CC981535032600162364 /* ffi_common.h in Headers */, - 6C43CC991535032600162364 /* ffi_i386.h in Headers */, - 6C43CC9A1535032600162364 /* ffi_x86_64.h in Headers */, - 6C43CC9E1535032600162364 /* ffitarget.h in Headers */, - 6C43CC9F1535032600162364 /* ffitarget_i386.h in Headers */, - 6C43CCA01535032600162364 /* ffitarget_x86_64.h in Headers */, - 6C43CC9B1535032600162364 /* fficonfig.h in Headers */, - 6C43CC9C1535032600162364 /* fficonfig_i386.h in Headers */, - 6C43CC9D1535032600162364 /* fficonfig_x86_64.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - F6F980B8147386130008F121 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 6C43CCAD1535039600162364 /* ffi.h in Headers */, - 6C43CCAE1535039600162364 /* ffi_armv7.h in Headers */, - 6C43CCAF1535039600162364 /* ffi_common.h in Headers */, - 6C43CCB01535039600162364 /* ffi_i386.h in Headers */, - 6C43CCB41535039600162364 /* ffitarget.h in Headers */, - 6C43CCB51535039600162364 /* ffitarget_arm.h in Headers */, - 6C43CCB61535039600162364 /* ffitarget_armv7.h in Headers */, - 6C43CCB71535039600162364 /* ffitarget_i386.h in Headers */, - 6C43CCB11535039600162364 /* fficonfig.h in Headers */, - 6C43CCB21535039600162364 /* fficonfig_armv7.h in Headers */, - 6C43CCB31535039600162364 /* fficonfig_i386.h in Headers */, + DBFA714C187F1D8600A76262 /* fficonfig.h in Headers */, + DBFA714D187F1D8600A76262 /* ffitarget.h in Headers */, + DBFA714A187F1D8600A76262 /* ffi.h in Headers */, + DBFA718F187F1DA100A76262 /* ffi_x86_64.h in Headers */, + DBFA7191187F1DA100A76262 /* fficonfig_x86_64.h in Headers */, + DBFA718E187F1DA100A76262 /* ffi_i386.h in Headers */, + DBFA7190187F1DA100A76262 /* fficonfig_i386.h in Headers */, + DBFA714B187F1D8600A76262 /* ffi_common.h in Headers */, + DBFA7193187F1DA100A76262 /* ffitarget_x86_64.h in Headers */, + DBFA7192187F1DA100A76262 /* ffitarget_i386.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ - 6C43CB3C1534E9D100162364 /* libffi OS X */ = { + DB13B1651849DF1E0010F42D /* libffi-iOS */ = { isa = PBXNativeTarget; - buildConfigurationList = 6C43CB4A1534E9D100162364 /* Build configuration list for PBXNativeTarget "libffi OS X" */; + buildConfigurationList = DB13B18B1849DF1E0010F42D /* Build configuration list for PBXNativeTarget "libffi-iOS" */; buildPhases = ( - 6C43CC401534FF3B00162364 /* Generate Source and Headers */, - 6C43CB391534E9D100162364 /* Sources */, - 6C43CB3A1534E9D100162364 /* Frameworks */, - 6C43CB3B1534E9D100162364 /* Headers */, + DB13B3051849E01C0010F42D /* ShellScript */, + DB13B1621849DF1E0010F42D /* Sources */, + DB13B1641849DF1E0010F42D /* CopyFiles */, ); buildRules = ( ); dependencies = ( ); - name = "libffi OS X"; - productName = "ffi OS X"; - productReference = 6C43CB3D1534E9D100162364 /* libffi.a */; + name = "libffi-iOS"; + productName = ffi; + productReference = DB13B1661849DF1E0010F42D /* libffi.a */; productType = "com.apple.product-type.library.static"; }; - F6F980B9147386130008F121 /* libffi iOS */ = { + DB13B1901849DF510010F42D /* libffi-Mac */ = { isa = PBXNativeTarget; - buildConfigurationList = F6F980C4147386130008F121 /* Build configuration list for PBXNativeTarget "libffi iOS" */; + buildConfigurationList = DB13B1B01849DF520010F42D /* Build configuration list for PBXNativeTarget "libffi-Mac" */; buildPhases = ( - 6C43CC3E1534F8E200162364 /* Generate Trampoline */, - 6C43CC3F1534FF1B00162364 /* Generate Source and Headers */, - F6F980B6147386130008F121 /* Sources */, - F6F980B7147386130008F121 /* Frameworks */, - F6F980B8147386130008F121 /* Headers */, + DB13B3061849E0490010F42D /* ShellScript */, + DB13B18D1849DF510010F42D /* Sources */, + DB13B18F1849DF510010F42D /* Headers */, ); buildRules = ( ); dependencies = ( ); - name = "libffi iOS"; + name = "libffi-Mac"; productName = ffi; - productReference = F6F980BA147386130008F121 /* libffi.a */; - productType = "com.apple.product-type.library.static"; + productReference = DB13B1911849DF510010F42D /* ffi.dylib */; + productType = "com.apple.product-type.library.dynamic"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ - F6B0839714721EE50031D8A1 /* Project object */ = { + DB13B15C1849DEB70010F42D /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0430; + LastUpgradeCheck = 0510; }; - buildConfigurationList = F6B0839A14721EE50031D8A1 /* Build configuration list for PBXProject "libffi" */; + buildConfigurationList = DB13B15F1849DEB70010F42D /* Build configuration list for PBXProject "libffi" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( en, ); - mainGroup = F6B0839514721EE50031D8A1; - productRefGroup = F6B0839514721EE50031D8A1; + mainGroup = DB13B15B1849DEB70010F42D; + productRefGroup = DB13B1671849DF1E0010F42D /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( - F6F980B9147386130008F121 /* libffi iOS */, - 6C43CB3C1534E9D100162364 /* libffi OS X */, + DB13B1651849DF1E0010F42D /* libffi-iOS */, + DB13B1901849DF510010F42D /* libffi-Mac */, ); }; /* End PBXProject section */ /* Begin PBXShellScriptBuildPhase section */ - 6C43CC3E1534F8E200162364 /* Generate Trampoline */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Generate Trampoline"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /usr/bin/python; - shellScript = "import subprocess\nimport re\nimport os\nimport errno\nimport sys\n\ndef main():\n with open('src/arm/trampoline.S', 'w') as tramp_out:\n p = subprocess.Popen(['bash', 'src/arm/gentramp.sh'], stdout=tramp_out)\n p.wait()\n\nif __name__ == '__main__':\n main()"; - }; - 6C43CC3F1534FF1B00162364 /* Generate Source and Headers */ = { + DB13B3051849E01C0010F42D /* ShellScript */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); - name = "Generate Source and Headers"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "/usr/bin/python generate-ios-source-and-headers.py"; + shellScript = "/usr/bin/python generate-darwin-source-and-headers.py --only-ios"; }; - 6C43CC401534FF3B00162364 /* Generate Source and Headers */ = { + DB13B3061849E0490010F42D /* ShellScript */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); - name = "Generate Source and Headers"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "/usr/bin/python generate-osx-source-and-headers.py"; + shellScript = "/usr/bin/python generate-darwin-source-and-headers.py --only-osx"; }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ - 6C43CB391534E9D100162364 /* Sources */ = { + DB13B1621849DF1E0010F42D /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 6C43CC1F1534F77800162364 /* darwin.S in Sources */, - 6C43CC201534F77800162364 /* darwin64.S in Sources */, - 6C43CC211534F77800162364 /* ffi.c in Sources */, - 6C43CC221534F77800162364 /* ffi64.c in Sources */, - 6C43CC301534F7BE00162364 /* closures.c in Sources */, - 6C43CC361534F7BE00162364 /* java_raw_api.c in Sources */, - 6C43CC381534F7BE00162364 /* prep_cif.c in Sources */, - 6C43CC3A1534F7BE00162364 /* raw_api.c in Sources */, - 6C43CC3C1534F7BE00162364 /* types.c in Sources */, + DBFA717E187F1D9B00A76262 /* ffi64_x86_64.c in Sources */, + DBFA7179187F1D9B00A76262 /* ffi_armv7.c in Sources */, + DBFA717B187F1D9B00A76262 /* trampoline_armv7.S in Sources */, + DBFA714E187F1D8600A76262 /* closures.c in Sources */, + DBFA717A187F1D9B00A76262 /* sysv_armv7.S in Sources */, + DBFA717D187F1D9B00A76262 /* darwin_i386.S in Sources */, + DBFA7156187F1D8600A76262 /* prep_cif.c in Sources */, + DBFA717F187F1D9B00A76262 /* ffi_i386.c in Sources */, + DBFA7158187F1D8600A76262 /* raw_api.c in Sources */, + DBFA7178187F1D9B00A76262 /* sysv_arm64.S in Sources */, + DBFA717C187F1D9B00A76262 /* darwin64_x86_64.S in Sources */, + DBFA715A187F1D8600A76262 /* types.c in Sources */, + DBFA7177187F1D9B00A76262 /* ffi_arm64.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - F6F980B6147386130008F121 /* Sources */ = { + DB13B18D1849DF510010F42D /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 6C43CBDC1534F76F00162364 /* ffi.c in Sources */, - 6C43CBDD1534F76F00162364 /* sysv.S in Sources */, - 6C43CBDE1534F76F00162364 /* trampoline.S in Sources */, - 6C43CBE61534F76F00162364 /* darwin.S in Sources */, - 6C43CBE81534F76F00162364 /* ffi.c in Sources */, - 6C43CC2F1534F7BE00162364 /* closures.c in Sources */, - 6C43CC351534F7BE00162364 /* java_raw_api.c in Sources */, - 6C43CC371534F7BE00162364 /* prep_cif.c in Sources */, - 6C43CC391534F7BE00162364 /* raw_api.c in Sources */, - 6C43CC3B1534F7BE00162364 /* types.c in Sources */, + DBFA7196187F1DA100A76262 /* ffi64_x86_64.c in Sources */, + DBFA7195187F1DA100A76262 /* darwin_i386.S in Sources */, + DBFA7157187F1D8600A76262 /* prep_cif.c in Sources */, + DBFA7197187F1DA100A76262 /* ffi_i386.c in Sources */, + DBFA715B187F1D8600A76262 /* types.c in Sources */, + DBFA7159187F1D8600A76262 /* raw_api.c in Sources */, + DBFA714F187F1D8600A76262 /* closures.c in Sources */, + DBFA7194187F1DA100A76262 /* darwin64_x86_64.S in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin XCBuildConfiguration section */ - 6C43CB4B1534E9D100162364 /* Debug */ = { + DB13B1601849DEB70010F42D /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; - DSTROOT = /tmp/ffi.dst; - FRAMEWORK_SEARCH_PATHS = ( + HEADER_SEARCH_PATHS = ( "$(inherited)", - "\"$(SYSTEM_APPS_DIR)/Xcode.app/Contents/Developer/Library/Frameworks\"", + "darwin_common/include", ); - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_VERSION = com.apple.compilers.llvm.clang.1_0; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - MACOSX_DEPLOYMENT_TARGET = 10.6; ONLY_ACTIVE_ARCH = YES; - PRODUCT_NAME = ffi; - SDKROOT = macosx; }; name = Debug; }; - 6C43CB4C1534E9D100162364 /* Release */ = { + DB13B1611849DEB70010F42D /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DSTROOT = /tmp/ffi.dst; - FRAMEWORK_SEARCH_PATHS = ( + HEADER_SEARCH_PATHS = ( "$(inherited)", - "\"$(SYSTEM_APPS_DIR)/Xcode.app/Contents/Developer/Library/Frameworks\"", + "darwin_common/include", ); - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_VERSION = com.apple.compilers.llvm.clang.1_0; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - MACOSX_DEPLOYMENT_TARGET = 10.6; - PRODUCT_NAME = ffi; - SDKROOT = macosx; }; name = Release; }; - F6B083AB14721EE50031D8A1 /* Debug */ = { + DB13B1871849DF1E0010F42D /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; + DSTROOT = /tmp/ffi.dst; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; @@ -482,98 +457,181 @@ "$(inherited)", ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VALUE = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - HEADER_SEARCH_PATHS = ios/include; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "darwin_ios/include", + ); + IPHONEOS_DEPLOYMENT_TARGET = 5.0; + "IPHONEOS_DEPLOYMENT_TARGET[arch=arm64]" = 7.0; + OTHER_LDFLAGS = "-ObjC"; + PRODUCT_NAME = ffi; SDKROOT = iphoneos; + SKIP_INSTALL = YES; }; name = Debug; }; - F6B083AC14721EE50031D8A1 /* Release */ = { + DB13B1881849DF1E0010F42D /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = YES; + DSTROOT = /tmp/ffi.dst; + ENABLE_NS_ASSERTIONS = NO; GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_PREPROCESSOR_DEFINITIONS = ""; - GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VALUE = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - HEADER_SEARCH_PATHS = ios/include; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "darwin_ios/include", + ); + IPHONEOS_DEPLOYMENT_TARGET = 5.0; + "IPHONEOS_DEPLOYMENT_TARGET[arch=arm64]" = 7.0; + OTHER_LDFLAGS = "-ObjC"; + PRODUCT_NAME = ffi; SDKROOT = iphoneos; + SKIP_INSTALL = YES; VALIDATE_PRODUCT = YES; }; name = Release; }; - F6F980C2147386130008F121 /* Debug */ = { + DB13B1B11849DF520010F42D /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - armv6, - armv7, + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", ); - DSTROOT = /tmp/ffi.dst; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_THUMB_SUPPORT = NO; - IPHONEOS_DEPLOYMENT_TARGET = 4.0; - OTHER_LDFLAGS = "-ObjC"; + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "darwin_osx/include", + ); + MACOSX_DEPLOYMENT_TARGET = 10.6; + ONLY_ACTIVE_ARCH = YES; + OTHER_LDFLAGS = "-Wl,-no_compact_unwind"; PRODUCT_NAME = ffi; - SKIP_INSTALL = YES; + SDKROOT = macosx; }; name = Debug; }; - F6F980C3147386130008F121 /* Release */ = { + DB13B1B21849DF520010F42D /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - armv6, - armv7, + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + ENABLE_NS_ASSERTIONS = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "darwin_osx/include", ); - DSTROOT = /tmp/ffi.dst; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_THUMB_SUPPORT = NO; - IPHONEOS_DEPLOYMENT_TARGET = 4.0; - OTHER_LDFLAGS = "-ObjC"; + MACOSX_DEPLOYMENT_TARGET = 10.6; + OTHER_LDFLAGS = "-Wl,-no_compact_unwind"; PRODUCT_NAME = ffi; - SKIP_INSTALL = YES; + SDKROOT = macosx; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 6C43CB4A1534E9D100162364 /* Build configuration list for PBXNativeTarget "libffi OS X" */ = { + DB13B15F1849DEB70010F42D /* Build configuration list for PBXProject "libffi" */ = { isa = XCConfigurationList; buildConfigurations = ( - 6C43CB4B1534E9D100162364 /* Debug */, - 6C43CB4C1534E9D100162364 /* Release */, + DB13B1601849DEB70010F42D /* Debug */, + DB13B1611849DEB70010F42D /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - F6B0839A14721EE50031D8A1 /* Build configuration list for PBXProject "libffi" */ = { + DB13B18B1849DF1E0010F42D /* Build configuration list for PBXNativeTarget "libffi-iOS" */ = { isa = XCConfigurationList; buildConfigurations = ( - F6B083AB14721EE50031D8A1 /* Debug */, - F6B083AC14721EE50031D8A1 /* Release */, + DB13B1871849DF1E0010F42D /* Debug */, + DB13B1881849DF1E0010F42D /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - F6F980C4147386130008F121 /* Build configuration list for PBXNativeTarget "libffi iOS" */ = { + DB13B1B01849DF520010F42D /* Build configuration list for PBXNativeTarget "libffi-Mac" */ = { isa = XCConfigurationList; buildConfigurations = ( - F6F980C2147386130008F121 /* Debug */, - F6F980C3147386130008F121 /* Release */, + DB13B1B11849DF520010F42D /* Debug */, + DB13B1B21849DF520010F42D /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; - rootObject = F6B0839714721EE50031D8A1 /* Project object */; + rootObject = DB13B15C1849DEB70010F42D /* Project object */; } diff --git a/Modules/_ctypes/libffi/libtool-version b/Modules/_ctypes/libffi/libtool-version index e784fc48fb73..d4f501c4d094 100644 --- a/Modules/_ctypes/libffi/libtool-version +++ b/Modules/_ctypes/libffi/libtool-version @@ -26,4 +26,4 @@ # release, then set age to 0. # # CURRENT:REVISION:AGE -6:1:0 +6:2:0 diff --git a/Modules/_ctypes/libffi/ltmain.sh b/Modules/_ctypes/libffi/ltmain.sh old mode 100755 new mode 100644 index 63ae69dc6fec..a50a21a67ca5 --- a/Modules/_ctypes/libffi/ltmain.sh +++ b/Modules/_ctypes/libffi/ltmain.sh @@ -1,9 +1,10 @@ +#! /bin/sh -# libtool (GNU libtool) 2.4.2 +# libtool (GNU libtool) 2.4.2.418 +# Provide generalized library-building support services. # Written by Gordon Matzigkeit , 1996 -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, -# 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. +# Copyright (C) 1996-2013 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. @@ -23,881 +24,2013 @@ # General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with GNU Libtool; see the file COPYING. If not, a copy -# can be downloaded from http://www.gnu.org/licenses/gpl.html, -# or obtained by writing to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# along with this program. If not, see . -# Usage: $progname [OPTION]... [MODE-ARG]... -# -# Provide generalized library-building support services. -# -# --config show all configuration variables -# --debug enable verbose shell tracing -# -n, --dry-run display commands without modifying any files -# --features display basic configuration information and exit -# --mode=MODE use operation mode MODE -# --preserve-dup-deps don't remove duplicate dependency libraries -# --quiet, --silent don't print informational messages -# --no-quiet, --no-silent -# print informational messages (default) -# --no-warn don't display warning messages -# --tag=TAG use configuration variables from tag TAG -# -v, --verbose print more informational messages than default -# --no-verbose don't print the extra informational messages -# --version print version information -# -h, --help, --help-all print short, long, or detailed help message -# -# MODE must be one of the following: -# -# clean remove files from the build directory -# compile compile a source file into a libtool object -# execute automatically set library path, then run a program -# finish complete the installation of libtool libraries -# install install libraries or executables -# link create a library or an executable -# uninstall remove libraries from an installed directory -# -# MODE-ARGS vary depending on the MODE. When passed as first option, -# `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that. -# Try `$progname --help --mode=MODE' for a more detailed description of MODE. -# -# When reporting a bug, please describe a test case to reproduce it and -# include the following information: -# -# host-triplet: $host -# shell: $SHELL -# compiler: $LTCC -# compiler flags: $LTCFLAGS -# linker: $LD (gnu? $with_gnu_ld) -# $progname: (GNU libtool) 2.4.2 -# automake: $automake_version -# autoconf: $autoconf_version -# -# Report bugs to . -# GNU libtool home page: . -# General help using GNU software: . PROGRAM=libtool PACKAGE=libtool -VERSION=2.4.2 -TIMESTAMP="" -package_revision=1.3337 +VERSION=2.4.2.418 +package_revision=2.4.2.418 -# Be Bourne compatible -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + +## ------ ## +## Usage. ## +## ------ ## + +# Run './libtool --help' for help with using this script from the +# command line. + + +## ------------------------------- ## +## User overridable command paths. ## +## ------------------------------- ## + +# After configure completes, it has a better idea of some of the +# shell tools we need than the defaults used by the functions shared +# with bootstrap, so set those here where they can still be over- +# ridden by the user, but otherwise take precedence. + +: ${AUTOCONF="autoconf"} +: ${AUTOMAKE="automake"} + + +## -------------------------- ## +## Source external libraries. ## +## -------------------------- ## + +# Much of our low-level functionality needs to be sourced from external +# libraries, which are installed to $pkgauxdir. + +# Set a version string for this script. +scriptversion=2013-08-23.20; # UTC + +# General shell script boiler plate, and helper functions. +# Written by Gary V. Vaughan, 2004 + +# Copyright (C) 2004-2013 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. + +# As a special exception to the GNU General Public License, if you distribute +# this file as part of a program or library that is built using GNU Libtool, +# you may include this file under the same distribution terms that you use +# for the rest of that program. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Please report bugs or propose patches to gary@gnu.org. + + +## ------ ## +## Usage. ## +## ------ ## + +# Evaluate this file near the top of your script to gain access to +# the functions and variables defined here: +# +# . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh +# +# If you need to override any of the default environment variable +# settings, do that before evaluating this file. + + +## -------------------- ## +## Shell normalisation. ## +## -------------------- ## + +# Some shells need a little help to be as Bourne compatible as possible. +# Before doing anything else, make sure all that help has been provided! + +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else - case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac + case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi -BIN_SH=xpg4; export BIN_SH # for Tru64 -DUALCASE=1; export DUALCASE # for MKS sh - -# A function that is used when there is no print builtin or printf. -func_fallback_echo () -{ - eval 'cat <<_LTECHO_EOF -$1 -_LTECHO_EOF' -} -# NLS nuisances: We save the old values to restore during execute mode. -lt_user_locale= -lt_safe_locale= -for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES +# NLS nuisances: We save the old values in case they are required later. +_G_user_locale= +_G_safe_locale= +for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do - eval "if test \"\${$lt_var+set}\" = set; then - save_$lt_var=\$$lt_var - $lt_var=C - export $lt_var - lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" - lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" + eval "if test set = \"\${$_G_var+set}\"; then + save_$_G_var=\$$_G_var + $_G_var=C + export $_G_var + _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\" + _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\" fi" done -LC_ALL=C -LANGUAGE=C -export LANGUAGE LC_ALL -$lt_unset CDPATH +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH +# Make sure IFS has a sensible default +sp=' ' +nl=' +' +IFS="$sp $nl" + +# There are still modern systems that have problems with 'echo' mis- +# handling backslashes, among others, so make sure $bs_echo is set to a +# command that correctly interprets backslashes. +# (this code from Autoconf 2.68) + +# Printing a long string crashes Solaris 7 /usr/bin/printf. +bs_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +bs_echo=$bs_echo$bs_echo$bs_echo$bs_echo$bs_echo +bs_echo=$bs_echo$bs_echo$bs_echo$bs_echo$bs_echo$bs_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $bs_echo`" = "X$bs_echo") 2>/dev/null; then + bs_echo='print -r --' + bs_echo_n='print -rn --' +elif (test "X`printf %s $bs_echo`" = "X$bs_echo") 2>/dev/null; then + bs_echo='printf %s\n' + bs_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $bs_echo) 2>/dev/null`" = "X-n $bs_echo"; then + bs_echo_body='eval /usr/ucb/echo -n "$1$nl"' + bs_echo_n='/usr/ucb/echo -n' + else + bs_echo_body='eval expr "X$1" : "X\\(.*\\)"' + bs_echo_n_body='eval + arg=$1; + case $arg in #( + *"$nl"*) + expr "X$arg" : "X\\(.*\\)$nl"; + arg=`expr "X$arg" : ".*$nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$nl" + ' + export bs_echo_n_body + bs_echo_n='sh -c $bs_echo_n_body bs_echo' + fi + export bs_echo_body + bs_echo='sh -c $bs_echo_body bs_echo' +fi -# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh -# is ksh but when the shell is invoked as "sh" and the current value of -# the _XPG environment variable is not equal to 1 (one), the special -# positional parameter $0, within a function call, is the name of the -# function. -progpath="$0" +## ------------------------------- ## +## User overridable command paths. ## +## ------------------------------- ## +# All uppercase variable names are used for environment variables. These +# variables can be overridden by the user before calling a script that +# uses them if a suitable command of that name is not already available +# in the command search PATH. : ${CP="cp -f"} -test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'} +: ${ECHO="$bs_echo"} +: ${EGREP="grep -E"} +: ${FGREP="grep -F"} +: ${GREP="grep"} +: ${LN_S="ln -s"} : ${MAKE="make"} : ${MKDIR="mkdir"} : ${MV="mv -f"} : ${RM="rm -f"} +: ${SED="sed"} : ${SHELL="${CONFIG_SHELL-/bin/sh}"} -: ${Xsed="$SED -e 1s/^X//"} - -# Global variables: -EXIT_SUCCESS=0 -EXIT_FAILURE=1 -EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. -EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. - -exit_status=$EXIT_SUCCESS - -# Make sure IFS has a sensible default -lt_nl=' -' -IFS=" $lt_nl" -dirname="s,/[^/]*$,," -basename="s,^.*/,," -# func_dirname file append nondir_replacement -# Compute the dirname of FILE. If nonempty, add APPEND to the result, -# otherwise set result to NONDIR_REPLACEMENT. -func_dirname () -{ - func_dirname_result=`$ECHO "${1}" | $SED "$dirname"` - if test "X$func_dirname_result" = "X${1}"; then - func_dirname_result="${3}" - else - func_dirname_result="$func_dirname_result${2}" - fi -} # func_dirname may be replaced by extended shell implementation +## -------------------- ## +## Useful sed snippets. ## +## -------------------- ## +sed_dirname='s|/[^/]*$||' +sed_basename='s|^.*/||' -# func_basename file -func_basename () -{ - func_basename_result=`$ECHO "${1}" | $SED "$basename"` -} # func_basename may be replaced by extended shell implementation +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='s|\([`"$\\]\)|\\\1|g' +# Same as above, but do not quote variable references. +sed_double_quote_subst='s/\(["`\\]\)/\\\1/g' -# func_dirname_and_basename file append nondir_replacement -# perform func_basename and func_dirname in a single function -# call: -# dirname: Compute the dirname of FILE. If nonempty, -# add APPEND to the result, otherwise set result -# to NONDIR_REPLACEMENT. -# value returned in "$func_dirname_result" -# basename: Compute filename of FILE. -# value retuned in "$func_basename_result" -# Implementation must be kept synchronized with func_dirname -# and func_basename. For efficiency, we do not delegate to -# those functions but instead duplicate the functionality here. -func_dirname_and_basename () -{ - # Extract subdirectory from the argument. - func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"` - if test "X$func_dirname_result" = "X${1}"; then - func_dirname_result="${3}" - else - func_dirname_result="$func_dirname_result${2}" - fi - func_basename_result=`$ECHO "${1}" | $SED -e "$basename"` -} # func_dirname_and_basename may be replaced by extended shell implementation +# Sed substitution that turns a string into a regex matching for the +# string literally. +sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g' +# Sed substitution that converts a w32 file name or path +# that contains forward slashes, into one that contains +# (escaped) backslashes. A very naive implementation. +sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' + +# Re-'\' parameter expansions in output of sed_double_quote_subst that +# were '\'-ed in input to the same. If an odd number of '\' preceded a +# '$' in input to sed_double_quote_subst, that '$' was protected from +# expansion. Since each input '\' is now two '\'s, look for any number +# of runs of four '\'s followed by two '\'s and then a '$'. '\' that '$'. +_G_bs='\\' +_G_bs2='\\\\' +_G_bs4='\\\\\\\\' +_G_dollar='\$' +sed_double_backslash="\ + s/$_G_bs4/&\\ +/g + s/^$_G_bs2$_G_dollar/$_G_bs&/ + s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g + s/\n//g" -# func_stripname prefix suffix name -# strip PREFIX and SUFFIX off of NAME. -# PREFIX and SUFFIX must not contain globbing or regex special -# characters, hashes, percent signs, but SUFFIX may contain a leading -# dot (in which case that matches only a dot). -# func_strip_suffix prefix name -func_stripname () -{ - case ${2} in - .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; - *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; - esac -} # func_stripname may be replaced by extended shell implementation +## ----------------- ## +## Global variables. ## +## ----------------- ## -# These SED scripts presuppose an absolute path with a trailing slash. -pathcar='s,^/\([^/]*\).*$,\1,' -pathcdr='s,^/[^/]*,,' -removedotparts=':dotsl - s@/\./@/@g - t dotsl - s,/\.$,/,' -collapseslashes='s@/\{1,\}@/@g' -finalslash='s,/*$,/,' +# Except for the global variables explicitly listed below, the following +# functions in the '^func_' namespace, and the '^require_' namespace +# variables initialised in the 'Resource management' section, sourcing +# this file will not pollute your global namespace with anything +# else. There's no portable way to scope variables in Bourne shell +# though, so actually running these functions will sometimes place +# results into a variable named after the function, and often use +# temporary variables in the '^_G_' namespace. If you are careful to +# avoid using those namespaces casually in your sourcing script, things +# should continue to work as you expect. And, of course, you can freely +# overwrite any of the functions or variables defined here before +# calling anything to customize them. -# func_normal_abspath PATH -# Remove doubled-up and trailing slashes, "." path components, -# and cancel out any ".." path components in PATH after making -# it an absolute path. -# value returned in "$func_normal_abspath_result" -func_normal_abspath () -{ - # Start from root dir and reassemble the path. - func_normal_abspath_result= - func_normal_abspath_tpath=$1 - func_normal_abspath_altnamespace= - case $func_normal_abspath_tpath in - "") - # Empty path, that just means $cwd. - func_stripname '' '/' "`pwd`" - func_normal_abspath_result=$func_stripname_result - return - ;; - # The next three entries are used to spot a run of precisely - # two leading slashes without using negated character classes; - # we take advantage of case's first-match behaviour. - ///*) - # Unusual form of absolute path, do nothing. - ;; - //*) - # Not necessarily an ordinary path; POSIX reserves leading '//' - # and for example Cygwin uses it to access remote file shares - # over CIFS/SMB, so we conserve a leading double slash if found. - func_normal_abspath_altnamespace=/ - ;; - /*) - # Absolute path, do nothing. - ;; - *) - # Relative path, prepend $cwd. - func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath - ;; - esac - # Cancel out all the simple stuff to save iterations. We also want - # the path to end with a slash for ease of parsing, so make sure - # there is one (and only one) here. - func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ - -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"` - while :; do - # Processed it all yet? - if test "$func_normal_abspath_tpath" = / ; then - # If we ascended to the root using ".." the result may be empty now. - if test -z "$func_normal_abspath_result" ; then - func_normal_abspath_result=/ - fi - break - fi - func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ - -e "$pathcar"` - func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ - -e "$pathcdr"` - # Figure out what to do with it - case $func_normal_abspath_tcomponent in - "") - # Trailing empty path component, ignore it. - ;; - ..) - # Parent dir; strip last assembled component from result. - func_dirname "$func_normal_abspath_result" - func_normal_abspath_result=$func_dirname_result - ;; - *) - # Actual path component, append it. - func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent - ;; - esac - done - # Restore leading double-slash if one was found on entry. - func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result -} +EXIT_SUCCESS=0 +EXIT_FAILURE=1 +EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. +EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. -# func_relative_path SRCDIR DSTDIR -# generates a relative path from SRCDIR to DSTDIR, with a trailing -# slash if non-empty, suitable for immediately appending a filename -# without needing to append a separator. -# value returned in "$func_relative_path_result" -func_relative_path () -{ - func_relative_path_result= - func_normal_abspath "$1" - func_relative_path_tlibdir=$func_normal_abspath_result - func_normal_abspath "$2" - func_relative_path_tbindir=$func_normal_abspath_result - - # Ascend the tree starting from libdir - while :; do - # check if we have found a prefix of bindir - case $func_relative_path_tbindir in - $func_relative_path_tlibdir) - # found an exact match - func_relative_path_tcancelled= - break - ;; - $func_relative_path_tlibdir*) - # found a matching prefix - func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" - func_relative_path_tcancelled=$func_stripname_result - if test -z "$func_relative_path_result"; then - func_relative_path_result=. - fi - break - ;; - *) - func_dirname $func_relative_path_tlibdir - func_relative_path_tlibdir=${func_dirname_result} - if test "x$func_relative_path_tlibdir" = x ; then - # Have to descend all the way to the root! - func_relative_path_result=../$func_relative_path_result - func_relative_path_tcancelled=$func_relative_path_tbindir - break - fi - func_relative_path_result=../$func_relative_path_result - ;; - esac - done +# Allow overriding, eg assuming that you follow the convention of +# putting '$debug_cmd' at the start of all your functions, you can get +# bash to show function call trace with: +# +# debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name +debug_cmd=${debug_cmd-":"} +exit_cmd=: - # Now calculate path; take care to avoid doubling-up slashes. - func_stripname '' '/' "$func_relative_path_result" - func_relative_path_result=$func_stripname_result - func_stripname '/' '/' "$func_relative_path_tcancelled" - if test "x$func_stripname_result" != x ; then - func_relative_path_result=${func_relative_path_result}/${func_stripname_result} - fi +# By convention, finish your script with: +# +# exit $exit_status +# +# so that you can set exit_status to non-zero if you want to indicate +# something went wrong during execution without actually bailing out at +# the point of failure. +exit_status=$EXIT_SUCCESS - # Normalisation. If bindir is libdir, return empty string, - # else relative path ending with a slash; either way, target - # file name can be directly appended. - if test ! -z "$func_relative_path_result"; then - func_stripname './' '' "$func_relative_path_result/" - func_relative_path_result=$func_stripname_result - fi -} +# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh +# is ksh but when the shell is invoked as "sh" and the current value of +# the _XPG environment variable is not equal to 1 (one), the special +# positional parameter $0, within a function call, is the name of the +# function. +progpath=$0 -# The name of this program: -func_dirname_and_basename "$progpath" -progname=$func_basename_result +# The name of this program. +progname=`$bs_echo "$progpath" |$SED "$sed_basename"` -# Make sure we have an absolute path for reexecution: +# Make sure we have an absolute progpath for reexecution: case $progpath in [\\/]*|[A-Za-z]:\\*) ;; *[\\/]*) - progdir=$func_dirname_result + progdir=`$bs_echo "$progpath" |$SED "$sed_dirname"` progdir=`cd "$progdir" && pwd` - progpath="$progdir/$progname" + progpath=$progdir/$progname ;; *) - save_IFS="$IFS" + _G_IFS=$IFS IFS=${PATH_SEPARATOR-:} for progdir in $PATH; do - IFS="$save_IFS" + IFS=$_G_IFS test -x "$progdir/$progname" && break done - IFS="$save_IFS" + IFS=$_G_IFS test -n "$progdir" || progdir=`pwd` - progpath="$progdir/$progname" + progpath=$progdir/$progname ;; esac -# Sed substitution that helps us do robust quoting. It backslashifies -# metacharacters that are still active within double-quoted strings. -Xsed="${SED}"' -e 1s/^X//' -sed_quote_subst='s/\([`"$\\]\)/\\\1/g' - -# Same as above, but do not quote variable references. -double_quote_subst='s/\(["`\\]\)/\\\1/g' -# Sed substitution that turns a string into a regex matching for the -# string literally. -sed_make_literal_regex='s,[].[^$\\*\/],\\&,g' +## ----------------- ## +## Standard options. ## +## ----------------- ## -# Sed substitution that converts a w32 file name or path -# which contains forward slashes, into one that contains -# (escaped) backslashes. A very naive implementation. -lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' - -# Re-`\' parameter expansions in output of double_quote_subst that were -# `\'-ed in input to the same. If an odd number of `\' preceded a '$' -# in input to double_quote_subst, that '$' was protected from expansion. -# Since each input `\' is now two `\'s, look for any number of runs of -# four `\'s followed by two `\'s and then a '$'. `\' that '$'. -bs='\\' -bs2='\\\\' -bs4='\\\\\\\\' -dollar='\$' -sed_double_backslash="\ - s/$bs4/&\\ -/g - s/^$bs2$dollar/$bs&/ - s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g - s/\n//g" +# The following options affect the operation of the functions defined +# below, and should be set appropriately depending on run-time para- +# meters passed on the command line. -# Standard options: opt_dry_run=false -opt_help=false opt_quiet=false opt_verbose=false -opt_warning=: -# func_echo arg... -# Echo program name prefixed message, along with the current mode -# name if it has been set yet. -func_echo () +# Categories 'all' and 'none' are always available. Append any others +# you will pass as the first argument to func_warning from your own +# code. +warning_categories= + +# By default, display warnings according to 'opt_warning_types'. Set +# 'warning_func' to ':' to elide all warnings, or func_fatal_error to +# treat the next displayed warning as a fatal error. +warning_func=func_warn_and_continue + +# Set to 'all' to display all warnings, 'none' to suppress all +# warnings, or a space delimited list of some subset of +# 'warning_categories' to display only the listed warnings. +opt_warning_types=all + + +## -------------------- ## +## Resource management. ## +## -------------------- ## + +# This section contains definitions for functions that each ensure a +# particular resource (a file, or a non-empty configuration variable for +# example) is available, and if appropriate to extract default values +# from pertinent package files. Call them using their associated +# 'require_*' variable to ensure that they are executed, at most, once. +# +# It's entirely deliberate that calling these functions can set +# variables that don't obey the namespace limitations obeyed by the rest +# of this file, in order that that they be as useful as possible to +# callers. + + +# require_term_colors +# ------------------- +# Allow display of bold text on terminals that support it. +require_term_colors=func_require_term_colors +func_require_term_colors () { - $ECHO "$progname: ${opt_mode+$opt_mode: }$*" + $debug_cmd + + test -t 1 && { + # COLORTERM and USE_ANSI_COLORS environment variables take + # precedence, because most terminfo databases neglect to describe + # whether color sequences are supported. + test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"} + + if test 1 = "$USE_ANSI_COLORS"; then + # Standard ANSI escape sequences + tc_reset='' + tc_bold=''; tc_standout='' + tc_red=''; tc_green='' + tc_blue=''; tc_cyan='' + else + # Otherwise trust the terminfo database after all. + test -n "`tput sgr0 2>/dev/null`" && { + tc_reset=`tput sgr0` + test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold` + tc_standout=$tc_bold + test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso` + test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1` + test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2` + test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4` + test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5` + } + fi + } + + require_term_colors=: } -# func_verbose arg... -# Echo program name prefixed message in verbose mode only. -func_verbose () + +## ----------------- ## +## Function library. ## +## ----------------- ## + +# This section contains a variety of useful functions to call in your +# scripts. Take note of the portable wrappers for features provided by +# some modern shells, which will fall back to slower equivalents on +# less featureful shells. + + +# func_append VAR VALUE +# --------------------- +# Append VALUE onto the existing contents of VAR. + + # We should try to minimise forks, especially on Windows where they are + # unreasonably slow, so skip the feature probes when bash or zsh are + # being used: + if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then + : ${_G_HAVE_ARITH_OP="yes"} + : ${_G_HAVE_XSI_OPS="yes"} + # The += operator was introduced in bash 3.1 + case $BASH_VERSION in + [12].* | 3.0 | 3.0*) ;; + *) + : ${_G_HAVE_PLUSEQ_OP="yes"} + ;; + esac + fi + + # _G_HAVE_PLUSEQ_OP + # Can be empty, in which case the shell is probed, "yes" if += is + # useable or anything else if it does not work. + test -z "$_G_HAVE_PLUSEQ_OP" \ + && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \ + && _G_HAVE_PLUSEQ_OP=yes + +if test yes = "$_G_HAVE_PLUSEQ_OP" +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_append () + { + $debug_cmd + + eval "$1+=\$2" + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_append () + { + $debug_cmd + + eval "$1=\$$1\$2" + } +fi + + +# func_append_quoted VAR VALUE +# ---------------------------- +# Quote VALUE and append to the end of shell variable VAR, separated +# by a space. +if test yes = "$_G_HAVE_PLUSEQ_OP"; then + eval 'func_append_quoted () + { + $debug_cmd + + func_quote_for_eval "$2" + eval "$1+=\\ \$func_quote_for_eval_result" + }' +else + func_append_quoted () + { + $debug_cmd + + func_quote_for_eval "$2" + eval "$1=\$$1\\ \$func_quote_for_eval_result" + } +fi + + +# func_append_uniq VAR VALUE +# -------------------------- +# Append unique VALUE onto the existing contents of VAR, assuming +# entries are delimited by the first character of VALUE. For example: +# +# func_append_uniq options " --another-option option-argument" +# +# will only append to $options if " --another-option option-argument " +# is not already present somewhere in $options already (note spaces at +# each end implied by leading space in second argument). +func_append_uniq () { - $opt_verbose && func_echo ${1+"$@"} + $debug_cmd - # A bug in bash halts the script if the last line of a function - # fails when set -e is in force, so we need another command to - # work around that: - : + eval _G_current_value='`$bs_echo $'$1'`' + _G_delim=`expr "$2" : '\(.\)'` + + case $_G_delim$_G_current_value$_G_delim in + *"$2$_G_delim"*) ;; + *) func_append "$@" ;; + esac } -# func_echo_all arg... -# Invoke $ECHO with all args, space-separated. -func_echo_all () + +# func_arith TERM... +# ------------------ +# Set func_arith_result to the result of evaluating TERMs. + test -z "$_G_HAVE_ARITH_OP" \ + && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \ + && _G_HAVE_ARITH_OP=yes + +if test yes = "$_G_HAVE_ARITH_OP"; then + eval 'func_arith () + { + $debug_cmd + + func_arith_result=$(( $* )) + }' +else + func_arith () + { + $debug_cmd + + func_arith_result=`expr "$@"` + } +fi + + +# func_basename FILE +# ------------------ +# Set func_basename_result to FILE with everything up to and including +# the last / stripped. +if test yes = "$_G_HAVE_XSI_OPS"; then + # If this shell supports suffix pattern removal, then use it to avoid + # forking. Hide the definitions single quotes in case the shell chokes + # on unsupported syntax... + _b='func_basename_result=${1##*/}' + _d='case $1 in + */*) func_dirname_result=${1%/*}$2 ;; + * ) func_dirname_result=$3 ;; + esac' + +else + # ...otherwise fall back to using sed. + _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`' + _d='func_dirname_result=`$ECHO "$1" |$SED "$sed_dirname"` + if test "X$func_dirname_result" = "X$1"; then + func_dirname_result=$3 + else + func_append func_dirname_result "$2" + fi' +fi + +eval 'func_basename () { - $ECHO "$*" -} + $debug_cmd + + '"$_b"' +}' + + +# func_dirname FILE APPEND NONDIR_REPLACEMENT +# ------------------------------------------- +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +eval 'func_dirname () +{ + $debug_cmd + + '"$_d"' +}' + + +# func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT +# -------------------------------------------------------- +# Perform func_basename and func_dirname in a single function +# call: +# dirname: Compute the dirname of FILE. If nonempty, +# add APPEND to the result, otherwise set result +# to NONDIR_REPLACEMENT. +# value returned in "$func_dirname_result" +# basename: Compute filename of FILE. +# value retuned in "$func_basename_result" +# For efficiency, we do not delegate to the functions above but instead +# duplicate the functionality here. +eval 'func_dirname_and_basename () +{ + $debug_cmd + + '"$_b"' + '"$_d"' +}' + + +# func_echo ARG... +# ---------------- +# Echo program name prefixed message. +func_echo () +{ + $debug_cmd + + _G_message=$* + + func_echo_IFS=$IFS + IFS=$nl + for _G_line in $_G_message; do + IFS=$func_echo_IFS + $bs_echo "$progname: $_G_line" + done + IFS=$func_echo_IFS +} + + +# func_echo_all ARG... +# -------------------- +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + + +# func_echo_infix_1 INFIX ARG... +# ------------------------------ +# Echo program name, followed by INFIX on the first line, with any +# additional lines not showing INFIX. +func_echo_infix_1 () +{ + $debug_cmd + + $require_term_colors + + _G_infix=$1; shift + _G_indent=$_G_infix + _G_prefix="$progname: $_G_infix: " + _G_message=$* + + # Strip color escape sequences before counting printable length + for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan" + do + test -n "$_G_tc" && { + _G_esc_tc=`$bs_echo "$_G_tc" | sed "$sed_make_literal_regex"` + _G_indent=`$bs_echo "$_G_indent" | sed "s|$_G_esc_tc||g"` + } + done + _G_indent="$progname: "`echo "$_G_indent" | sed 's|.| |g'`" " ## exclude from sc_prohibit_nested_quotes + + func_echo_infix_1_IFS=$IFS + IFS=$nl + for _G_line in $_G_message; do + IFS=$func_echo_infix_1_IFS + $bs_echo "$_G_prefix$tc_bold$_G_line$tc_reset" >&2 + _G_prefix=$_G_indent + done + IFS=$func_echo_infix_1_IFS +} + + +# func_error ARG... +# ----------------- +# Echo program name prefixed message to standard error. +func_error () +{ + $debug_cmd + + $require_term_colors + + func_echo_infix_1 " $tc_standout${tc_red}error$tc_reset" "$*" >&2 +} + + +# func_fatal_error ARG... +# ----------------------- +# Echo program name prefixed message to standard error, and exit. +func_fatal_error () +{ + $debug_cmd + + func_error "$*" + exit $EXIT_FAILURE +} + + +# func_grep EXPRESSION FILENAME +# ----------------------------- +# Check whether EXPRESSION matches any line of FILENAME, without output. +func_grep () +{ + $debug_cmd + + $GREP "$1" "$2" >/dev/null 2>&1 +} + + +# func_len STRING +# --------------- +# Set func_len_result to the length of STRING. STRING may not +# start with a hyphen. + test -z "$_G_HAVE_XSI_OPS" \ + && (eval 'x=a/b/c; + test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ + && _G_HAVE_XSI_OPS=yes + +if test yes = "$_G_HAVE_XSI_OPS"; then + eval 'func_len () + { + $debug_cmd + + func_len_result=${#1} + }' +else + func_len () + { + $debug_cmd + + func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` + } +fi + + +# func_mkdir_p DIRECTORY-PATH +# --------------------------- +# Make sure the entire path to DIRECTORY-PATH is available. +func_mkdir_p () +{ + $debug_cmd + + _G_directory_path=$1 + _G_dir_list= + + if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then + + # Protect directory names starting with '-' + case $_G_directory_path in + -*) _G_directory_path=./$_G_directory_path ;; + esac + + # While some portion of DIR does not yet exist... + while test ! -d "$_G_directory_path"; do + # ...make a list in topmost first order. Use a colon delimited + # list incase some portion of path contains whitespace. + _G_dir_list=$_G_directory_path:$_G_dir_list + + # If the last portion added has no slash in it, the list is done + case $_G_directory_path in */*) ;; *) break ;; esac + + # ...otherwise throw away the child directory and loop + _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"` + done + _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'` + + func_mkdir_p_IFS=$IFS; IFS=: + for _G_dir in $_G_dir_list; do + IFS=$func_mkdir_p_IFS + # mkdir can fail with a 'File exist' error if two processes + # try to create one of the directories concurrently. Don't + # stop in that case! + $MKDIR "$_G_dir" 2>/dev/null || : + done + IFS=$func_mkdir_p_IFS + + # Bail out if we (or some other process) failed to create a directory. + test -d "$_G_directory_path" || \ + func_fatal_error "Failed to create '$1'" + fi +} + + +# func_mktempdir [BASENAME] +# ------------------------- +# Make a temporary directory that won't clash with other running +# libtool processes, and avoids race conditions if possible. If +# given, BASENAME is the basename for that directory. +func_mktempdir () +{ + $debug_cmd + + _G_template=${TMPDIR-/tmp}/${1-$progname} + + if test : = "$opt_dry_run"; then + # Return a directory name, but don't create it in dry-run mode + _G_tmpdir=$_G_template-$$ + else + + # If mktemp works, use that first and foremost + _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null` + + if test ! -d "$_G_tmpdir"; then + # Failing that, at least try and use $RANDOM to avoid a race + _G_tmpdir=$_G_template-${RANDOM-0}$$ + + func_mktempdir_umask=`umask` + umask 0077 + $MKDIR "$_G_tmpdir" + umask $func_mktempdir_umask + fi + + # If we're not in dry-run mode, bomb out on failure + test -d "$_G_tmpdir" || \ + func_fatal_error "cannot create temporary directory '$_G_tmpdir'" + fi + + $ECHO "$_G_tmpdir" +} + + +# func_normal_abspath PATH +# ------------------------ +# Remove doubled-up and trailing slashes, "." path components, +# and cancel out any ".." path components in PATH after making +# it an absolute path. +func_normal_abspath () +{ + $debug_cmd + + # These SED scripts presuppose an absolute path with a trailing slash. + _G_pathcar='s|^/\([^/]*\).*$|\1|' + _G_pathcdr='s|^/[^/]*||' + _G_removedotparts=':dotsl + s|/\./|/|g + t dotsl + s|/\.$|/|' + _G_collapseslashes='s|/\{1,\}|/|g' + _G_finalslash='s|/*$|/|' + + # Start from root dir and reassemble the path. + func_normal_abspath_result= + func_normal_abspath_tpath=$1 + func_normal_abspath_altnamespace= + case $func_normal_abspath_tpath in + "") + # Empty path, that just means $cwd. + func_stripname '' '/' "`pwd`" + func_normal_abspath_result=$func_stripname_result + return + ;; + # The next three entries are used to spot a run of precisely + # two leading slashes without using negated character classes; + # we take advantage of case's first-match behaviour. + ///*) + # Unusual form of absolute path, do nothing. + ;; + //*) + # Not necessarily an ordinary path; POSIX reserves leading '//' + # and for example Cygwin uses it to access remote file shares + # over CIFS/SMB, so we conserve a leading double slash if found. + func_normal_abspath_altnamespace=/ + ;; + /*) + # Absolute path, do nothing. + ;; + *) + # Relative path, prepend $cwd. + func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath + ;; + esac + + # Cancel out all the simple stuff to save iterations. We also want + # the path to end with a slash for ease of parsing, so make sure + # there is one (and only one) here. + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"` + while :; do + # Processed it all yet? + if test / = "$func_normal_abspath_tpath"; then + # If we ascended to the root using ".." the result may be empty now. + if test -z "$func_normal_abspath_result"; then + func_normal_abspath_result=/ + fi + break + fi + func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$_G_pathcar"` + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$_G_pathcdr"` + # Figure out what to do with it + case $func_normal_abspath_tcomponent in + "") + # Trailing empty path component, ignore it. + ;; + ..) + # Parent dir; strip last assembled component from result. + func_dirname "$func_normal_abspath_result" + func_normal_abspath_result=$func_dirname_result + ;; + *) + # Actual path component, append it. + func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent" + ;; + esac + done + # Restore leading double-slash if one was found on entry. + func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result +} + + +# func_notquiet ARG... +# -------------------- +# Echo program name prefixed message only when not in quiet mode. +func_notquiet () +{ + $debug_cmd + + $opt_quiet || func_echo ${1+"$@"} + + # A bug in bash halts the script if the last line of a function + # fails when set -e is in force, so we need another command to + # work around that: + : +} + + +# func_relative_path SRCDIR DSTDIR +# -------------------------------- +# Set func_relative_path_result to the relative path from SRCDIR to DSTDIR. +func_relative_path () +{ + $debug_cmd + + func_relative_path_result= + func_normal_abspath "$1" + func_relative_path_tlibdir=$func_normal_abspath_result + func_normal_abspath "$2" + func_relative_path_tbindir=$func_normal_abspath_result + + # Ascend the tree starting from libdir + while :; do + # check if we have found a prefix of bindir + case $func_relative_path_tbindir in + $func_relative_path_tlibdir) + # found an exact match + func_relative_path_tcancelled= + break + ;; + $func_relative_path_tlibdir*) + # found a matching prefix + func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" + func_relative_path_tcancelled=$func_stripname_result + if test -z "$func_relative_path_result"; then + func_relative_path_result=. + fi + break + ;; + *) + func_dirname $func_relative_path_tlibdir + func_relative_path_tlibdir=$func_dirname_result + if test -z "$func_relative_path_tlibdir"; then + # Have to descend all the way to the root! + func_relative_path_result=../$func_relative_path_result + func_relative_path_tcancelled=$func_relative_path_tbindir + break + fi + func_relative_path_result=../$func_relative_path_result + ;; + esac + done + + # Now calculate path; take care to avoid doubling-up slashes. + func_stripname '' '/' "$func_relative_path_result" + func_relative_path_result=$func_stripname_result + func_stripname '/' '/' "$func_relative_path_tcancelled" + if test -n "$func_stripname_result"; then + func_append func_relative_path_result "/$func_stripname_result" + fi + + # Normalisation. If bindir is libdir, return '.' else relative path. + if test -n "$func_relative_path_result"; then + func_stripname './' '' "$func_relative_path_result" + func_relative_path_result=$func_stripname_result + fi + + test -n "$func_relative_path_result" || func_relative_path_result=. + + : +} + + +# func_quote_for_eval ARG... +# -------------------------- +# Aesthetically quote ARGs to be evaled later. +# This function returns two values: +# i) func_quote_for_eval_result +# double-quoted, suitable for a subsequent eval +# ii) func_quote_for_eval_unquoted_result +# has all characters that are still active within double +# quotes backslashified. +func_quote_for_eval () +{ + $debug_cmd + + func_quote_for_eval_unquoted_result= + func_quote_for_eval_result= + while test 0 -lt $#; do + case $1 in + *[\\\`\"\$]*) + _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;; + *) + _G_unquoted_arg=$1 ;; + esac + if test -n "$func_quote_for_eval_unquoted_result"; then + func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg" + else + func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg" + fi + + case $_G_unquoted_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting, command substitution and variable expansion + # for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + _G_quoted_arg=\"$_G_unquoted_arg\" + ;; + *) + _G_quoted_arg=$_G_unquoted_arg + ;; + esac + + if test -n "$func_quote_for_eval_result"; then + func_append func_quote_for_eval_result " $_G_quoted_arg" + else + func_append func_quote_for_eval_result "$_G_quoted_arg" + fi + shift + done +} + + +# func_quote_for_expand ARG +# ------------------------- +# Aesthetically quote ARG to be evaled later; same as above, +# but do not quote variable references. +func_quote_for_expand () +{ + $debug_cmd + + case $1 in + *[\\\`\"]*) + _G_arg=`$ECHO "$1" | $SED \ + -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;; + *) + _G_arg=$1 ;; + esac + + case $_G_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting and command substitution for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + _G_arg=\"$_G_arg\" + ;; + esac + + func_quote_for_expand_result=$_G_arg +} + + +# func_stripname PREFIX SUFFIX NAME +# --------------------------------- +# strip PREFIX and SUFFIX from NAME, and store in func_stripname_result. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +if test yes = "$_G_HAVE_XSI_OPS"; then + eval 'func_stripname () + { + $debug_cmd + + # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are + # positional parameters, so assign one to ordinary variable first. + func_stripname_result=$3 + func_stripname_result=${func_stripname_result#"$1"} + func_stripname_result=${func_stripname_result%"$2"} + }' +else + func_stripname () + { + $debug_cmd + + case $2 in + .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;; + *) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;; + esac + } +fi + + +# func_show_eval CMD [FAIL_EXP] +# ----------------------------- +# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. +func_show_eval () +{ + $debug_cmd + + _G_cmd=$1 + _G_fail_exp=${2-':'} + + func_quote_for_expand "$_G_cmd" + eval "func_notquiet $func_quote_for_expand_result" + + $opt_dry_run || { + eval "$_G_cmd" + _G_status=$? + if test 0 -ne "$_G_status"; then + eval "(exit $_G_status); $_G_fail_exp" + fi + } +} + + +# func_show_eval_locale CMD [FAIL_EXP] +# ------------------------------------ +# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. Use the saved locale for evaluation. +func_show_eval_locale () +{ + $debug_cmd + + _G_cmd=$1 + _G_fail_exp=${2-':'} + + $opt_quiet || { + func_quote_for_expand "$_G_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + $opt_dry_run || { + eval "$_G_user_locale + $_G_cmd" + _G_status=$? + eval "$_G_safe_locale" + if test 0 -ne "$_G_status"; then + eval "(exit $_G_status); $_G_fail_exp" + fi + } +} + + +# func_tr_sh +# ---------- +# Turn $1 into a string suitable for a shell variable name. +# Result is stored in $func_tr_sh_result. All characters +# not in the set a-zA-Z0-9_ are replaced with '_'. Further, +# if $1 begins with a digit, a '_' is prepended as well. +func_tr_sh () +{ + $debug_cmd + + case $1 in + [0-9]* | *[!a-zA-Z0-9_]*) + func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'` + ;; + * ) + func_tr_sh_result=$1 + ;; + esac +} + + +# func_verbose ARG... +# ------------------- +# Echo program name prefixed message in verbose mode only. +func_verbose () +{ + $debug_cmd + + $opt_verbose && func_echo "$*" + + : +} + + +# func_warn_and_continue ARG... +# ----------------------------- +# Echo program name prefixed warning message to standard error. +func_warn_and_continue () +{ + $debug_cmd + + $require_term_colors + + func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2 +} + + +# func_warning CATEGORY ARG... +# ---------------------------- +# Echo program name prefixed warning message to standard error. Warning +# messages can be filtered according to CATEGORY, where this function +# elides messages where CATEGORY is not listed in the global variable +# 'opt_warning_types'. +func_warning () +{ + $debug_cmd + + # CATEGORY must be in the warning_categories list! + case " $warning_categories " in + *" $1 "*) ;; + *) func_internal_error "invalid warning category '$1'" ;; + esac + + _G_category=$1 + shift + + case " $opt_warning_types " in + *" $_G_category "*) $warning_func ${1+"$@"} ;; + esac +} + + +# func_sort_ver VER1 VER2 +# ----------------------- +# 'sort -V' is not generally available. +# Note this deviates from the version comparison in automake +# in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a +# but this should suffice as we won't be specifying old +# version formats or redundant trailing .0 in bootstrap.conf. +# If we did want full compatibility then we should probably +# use m4_version_compare from autoconf. +func_sort_ver () +{ + $debug_cmd + + ver1=$1 + ver2=$2 + + # Split on '.' and compare each component. + i=1 + while :; do + p1=`echo "$ver1" |cut -d. -f$i` + p2=`echo "$ver2" |cut -d. -f$i` + if test ! "$p1"; then + echo "$1 $2" + break + elif test ! "$p2"; then + echo "$2 $1" + break + elif test ! "$p1" = "$p2"; then + if test "$p1" -gt "$p2" 2>/dev/null; then # numeric comparison + echo "$2 $1" + elif test "$p2" -gt "$p1" 2>/dev/null; then # numeric comparison + echo "$1 $2" + else # numeric, then lexicographic comparison + lp=`printf "$p1\n$p2\n" |sort -n |tail -n1` + if test "$lp" = "$p2"; then + echo "$1 $2" + else + echo "$2 $1" + fi + fi + break + fi + i=`expr $i + 1` + done +} + + +# Local variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" +# time-stamp-time-zone: "UTC" +# End: +#! /bin/sh + +# Set a version string for this script. +scriptversion=2012-10-21.11; # UTC + +# A portable, pluggable option parser for Bourne shell. +# Written by Gary V. Vaughan, 2010 + +# Copyright (C) 2010-2013 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Please report bugs or propose patches to gary@gnu.org. + + +## ------ ## +## Usage. ## +## ------ ## + +# This file is a library for parsing options in your shell scripts along +# with assorted other useful supporting features that you can make use +# of too. +# +# For the simplest scripts you might need only: +# +# #!/bin/sh +# . relative/path/to/funclib.sh +# . relative/path/to/options-parser +# scriptversion=1.0 +# func_options ${1+"$@"} +# eval set dummy "$func_options_result"; shift +# ...rest of your script... +# +# In order for the '--version' option to work, you will need to have a +# suitably formatted comment like the one at the top of this file +# starting with '# Written by ' and ending with '# warranty; '. +# +# For '-h' and '--help' to work, you will also need a one line +# description of your script's purpose in a comment directly above the +# '# Written by ' line, like the one at the top of this file. +# +# The default options also support '--debug', which will turn on shell +# execution tracing (see the comment above debug_cmd below for another +# use), and '--verbose' and the func_verbose function to allow your script +# to display verbose messages only when your user has specified +# '--verbose'. +# +# After sourcing this file, you can plug processing for additional +# options by amending the variables from the 'Configuration' section +# below, and following the instructions in the 'Option parsing' +# section further down. + +## -------------- ## +## Configuration. ## +## -------------- ## + +# You should override these variables in your script after sourcing this +# file so that they reflect the customisations you have added to the +# option parser. + +# The usage line for option parsing errors and the start of '-h' and +# '--help' output messages. You can embed shell variables for delayed +# expansion at the time the message is displayed, but you will need to +# quote other shell meta-characters carefully to prevent them being +# expanded when the contents are evaled. +usage='$progpath [OPTION]...' + +# Short help message in response to '-h' and '--help'. Add to this or +# override it after sourcing this library to reflect the full set of +# options your script accepts. +usage_message="\ + --debug enable verbose shell tracing + -W, --warnings=CATEGORY + report the warnings falling in CATEGORY [all] + -v, --verbose verbosely report processing + --version print version information and exit + -h, --help print short or long help message and exit +" + +# Additional text appended to 'usage_message' in response to '--help'. +long_help_message=" +Warning categories include: + 'all' show all warnings + 'none' turn off all the warnings + 'error' warnings are treated as fatal errors" + +# Help message printed before fatal option parsing errors. +fatal_help="Try '\$progname --help' for more information." + + + +## ------------------------- ## +## Hook function management. ## +## ------------------------- ## + +# This section contains functions for adding, removing, and running hooks +# to the main code. A hook is just a named list of of function, that can +# be run in order later on. + +# func_hookable FUNC_NAME +# ----------------------- +# Declare that FUNC_NAME will run hooks added with +# 'func_add_hook FUNC_NAME ...'. +func_hookable () +{ + $debug_cmd + + func_append hookable_fns " $1" +} + + +# func_add_hook FUNC_NAME HOOK_FUNC +# --------------------------------- +# Request that FUNC_NAME call HOOK_FUNC before it returns. FUNC_NAME must +# first have been declared "hookable" by a call to 'func_hookable'. +func_add_hook () +{ + $debug_cmd + + case " $hookable_fns " in + *" $1 "*) ;; + *) func_fatal_error "'$1' does not accept hook functions." ;; + esac + + eval func_append ${1}_hooks '" $2"' +} + + +# func_remove_hook FUNC_NAME HOOK_FUNC +# ------------------------------------ +# Remove HOOK_FUNC from the list of functions called by FUNC_NAME. +func_remove_hook () +{ + $debug_cmd + + eval ${1}_hooks='`$bs_echo "\$'$1'_hooks" |$SED "s| '$2'||"`' +} + + +# func_run_hooks FUNC_NAME [ARG]... +# --------------------------------- +# Run all hook functions registered to FUNC_NAME. +# It is assumed that the list of hook functions contains nothing more +# than a whitespace-delimited list of legal shell function names, and +# no effort is wasted trying to catch shell meta-characters or preserve +# whitespace. +func_run_hooks () +{ + $debug_cmd + + case " $hookable_fns " in + *" $1 "*) ;; + *) func_fatal_error "'$1' does not support hook funcions.n" ;; + esac + + eval _G_hook_fns=\$$1_hooks; shift + + for _G_hook in $_G_hook_fns; do + eval $_G_hook '"$@"' + + # store returned options list back into positional + # parameters for next 'cmd' execution. + eval _G_hook_result=\$${_G_hook}_result + eval set dummy "$_G_hook_result"; shift + done + + func_quote_for_eval ${1+"$@"} + func_run_hooks_result=$func_quote_for_eval_result +} + + + +## --------------- ## +## Option parsing. ## +## --------------- ## + +# In order to add your own option parsing hooks, you must accept the +# full positional parameter list in your hook function, remove any +# options that you action, and then pass back the remaining unprocessed +# options in '_result', escaped suitably for +# 'eval'. Like this: +# +# my_options_prep () +# { +# $debug_cmd +# +# # Extend the existing usage message. +# usage_message=$usage_message' +# -s, --silent don'\''t print informational messages +# ' +# +# func_quote_for_eval ${1+"$@"} +# my_options_prep_result=$func_quote_for_eval_result +# } +# func_add_hook func_options_prep my_options_prep +# +# +# my_silent_option () +# { +# $debug_cmd +# +# # Note that for efficiency, we parse as many options as we can +# # recognise in a loop before passing the remainder back to the +# # caller on the first unrecognised argument we encounter. +# while test $# -gt 0; do +# opt=$1; shift +# case $opt in +# --silent|-s) opt_silent=: ;; +# # Separate non-argument short options: +# -s*) func_split_short_opt "$_G_opt" +# set dummy "$func_split_short_opt_name" \ +# "-$func_split_short_opt_arg" ${1+"$@"} +# shift +# ;; +# *) set dummy "$_G_opt" "$*"; shift; break ;; +# esac +# done +# +# func_quote_for_eval ${1+"$@"} +# my_silent_option_result=$func_quote_for_eval_result +# } +# func_add_hook func_parse_options my_silent_option +# +# +# my_option_validation () +# { +# $debug_cmd +# +# $opt_silent && $opt_verbose && func_fatal_help "\ +# '--silent' and '--verbose' options are mutually exclusive." +# +# func_quote_for_eval ${1+"$@"} +# my_option_validation_result=$func_quote_for_eval_result +# } +# func_add_hook func_validate_options my_option_validation +# +# You'll alse need to manually amend $usage_message to reflect the extra +# options you parse. It's preferable to append if you can, so that +# multiple option parsing hooks can be added safely. -# func_error arg... -# Echo program name prefixed message to standard error. -func_error () -{ - $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2 -} -# func_warning arg... -# Echo program name prefixed warning message to standard error. -func_warning () +# func_options [ARG]... +# --------------------- +# All the functions called inside func_options are hookable. See the +# individual implementations for details. +func_hookable func_options +func_options () { - $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2 + $debug_cmd - # bash bug again: - : -} + func_options_prep ${1+"$@"} + eval func_parse_options \ + ${func_options_prep_result+"$func_options_prep_result"} + eval func_validate_options \ + ${func_parse_options_result+"$func_parse_options_result"} -# func_fatal_error arg... -# Echo program name prefixed message to standard error, and exit. -func_fatal_error () -{ - func_error ${1+"$@"} - exit $EXIT_FAILURE -} + eval func_run_hooks func_options \ + ${func_validate_options_result+"$func_validate_options_result"} -# func_fatal_help arg... -# Echo program name prefixed message to standard error, followed by -# a help hint, and exit. -func_fatal_help () -{ - func_error ${1+"$@"} - func_fatal_error "$help" + # save modified positional parameters for caller + func_options_result=$func_run_hooks_result } -help="Try \`$progname --help' for more information." ## default -# func_grep expression filename -# Check whether EXPRESSION matches any line of FILENAME, without output. -func_grep () +# func_options_prep [ARG]... +# -------------------------- +# All initialisations required before starting the option parse loop. +# Note that when calling hook functions, we pass through the list of +# positional parameters. If a hook function modifies that list, and +# needs to propogate that back to rest of this script, then the complete +# modified list must be put in 'func_run_hooks_result' before +# returning. +func_hookable func_options_prep +func_options_prep () { - $GREP "$1" "$2" >/dev/null 2>&1 + $debug_cmd + + # Option defaults: + opt_verbose=false + opt_warning_types= + + func_run_hooks func_options_prep ${1+"$@"} + + # save modified positional parameters for caller + func_options_prep_result=$func_run_hooks_result } -# func_mkdir_p directory-path -# Make sure the entire path to DIRECTORY-PATH is available. -func_mkdir_p () +# func_parse_options [ARG]... +# --------------------------- +# The main option parsing loop. +func_hookable func_parse_options +func_parse_options () { - my_directory_path="$1" - my_dir_list= + $debug_cmd - if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then + func_parse_options_result= - # Protect directory names starting with `-' - case $my_directory_path in - -*) my_directory_path="./$my_directory_path" ;; - esac + # this just eases exit handling + while test $# -gt 0; do + # Defer to hook functions for initial option parsing, so they + # get priority in the event of reusing an option name. + func_run_hooks func_parse_options ${1+"$@"} - # While some portion of DIR does not yet exist... - while test ! -d "$my_directory_path"; do - # ...make a list in topmost first order. Use a colon delimited - # list incase some portion of path contains whitespace. - my_dir_list="$my_directory_path:$my_dir_list" + # Adjust func_parse_options positional parameters to match + eval set dummy "$func_run_hooks_result"; shift - # If the last portion added has no slash in it, the list is done - case $my_directory_path in */*) ;; *) break ;; esac + # Break out of the loop if we already parsed every option. + test $# -gt 0 || break - # ...otherwise throw away the child directory and loop - my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"` - done - my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'` + _G_opt=$1 + shift + case $_G_opt in + --debug|-x) debug_cmd='set -x' + func_echo "enabling shell trace mode" + $debug_cmd + ;; + + --no-warnings|--no-warning|--no-warn) + set dummy --warnings none ${1+"$@"} + shift + ;; - save_mkdir_p_IFS="$IFS"; IFS=':' - for my_dir in $my_dir_list; do - IFS="$save_mkdir_p_IFS" - # mkdir can fail with a `File exist' error if two processes - # try to create one of the directories concurrently. Don't - # stop in that case! - $MKDIR "$my_dir" 2>/dev/null || : - done - IFS="$save_mkdir_p_IFS" + --warnings|--warning|-W) + test $# = 0 && func_missing_arg $_G_opt && break + case " $warning_categories $1" in + *" $1 "*) + # trailing space prevents matching last $1 above + func_append_uniq opt_warning_types " $1" + ;; + *all) + opt_warning_types=$warning_categories + ;; + *none) + opt_warning_types=none + warning_func=: + ;; + *error) + opt_warning_types=$warning_categories + warning_func=func_fatal_error + ;; + *) + func_fatal_error \ + "unsupported warning category: '$1'" + ;; + esac + shift + ;; + + --verbose|-v) opt_verbose=: ;; + --version) func_version ;; + -\?|-h) func_usage ;; + --help) func_help ;; + + # Separate optargs to long options (plugins may need this): + --*=*) func_split_equals "$_G_opt" + set dummy "$func_split_equals_lhs" \ + "$func_split_equals_rhs" ${1+"$@"} + shift + ;; + + # Separate optargs to short options: + -W*) + func_split_short_opt "$_G_opt" + set dummy "$func_split_short_opt_name" \ + "$func_split_short_opt_arg" ${1+"$@"} + shift + ;; + + # Separate non-argument short options: + -\?*|-h*|-v*|-x*) + func_split_short_opt "$_G_opt" + set dummy "$func_split_short_opt_name" \ + "-$func_split_short_opt_arg" ${1+"$@"} + shift + ;; + + --) break ;; + -*) func_fatal_help "unrecognised option: '$_G_opt'" ;; + *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; + esac + done - # Bail out if we (or some other process) failed to create a directory. - test -d "$my_directory_path" || \ - func_fatal_error "Failed to create \`$1'" - fi + # save modified positional parameters for caller + func_quote_for_eval ${1+"$@"} + func_parse_options_result=$func_quote_for_eval_result } -# func_mktempdir [string] -# Make a temporary directory that won't clash with other running -# libtool processes, and avoids race conditions if possible. If -# given, STRING is the basename for that directory. -func_mktempdir () +# func_validate_options [ARG]... +# ------------------------------ +# Perform any sanity checks on option settings and/or unconsumed +# arguments. +func_hookable func_validate_options +func_validate_options () { - my_template="${TMPDIR-/tmp}/${1-$progname}" + $debug_cmd - if test "$opt_dry_run" = ":"; then - # Return a directory name, but don't create it in dry-run mode - my_tmpdir="${my_template}-$$" - else + # Display all warnings if -W was not given. + test -n "$opt_warning_types" || opt_warning_types=" $warning_categories" - # If mktemp works, use that first and foremost - my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` + func_run_hooks func_validate_options ${1+"$@"} - if test ! -d "$my_tmpdir"; then - # Failing that, at least try and use $RANDOM to avoid a race - my_tmpdir="${my_template}-${RANDOM-0}$$" + # Bail if the options were screwed! + $exit_cmd $EXIT_FAILURE - save_mktempdir_umask=`umask` - umask 0077 - $MKDIR "$my_tmpdir" - umask $save_mktempdir_umask - fi + # save modified positional parameters for caller + func_validate_options_result=$func_run_hooks_result +} - # If we're not in dry-run mode, bomb out on failure - test -d "$my_tmpdir" || \ - func_fatal_error "cannot create temporary directory \`$my_tmpdir'" - fi - $ECHO "$my_tmpdir" -} +## ------------------## +## Helper functions. ## +## ------------------## -# func_quote_for_eval arg -# Aesthetically quote ARG to be evaled later. -# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT -# is double-quoted, suitable for a subsequent eval, whereas -# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters -# which are still active within double quotes backslashified. -func_quote_for_eval () +# This section contains the helper functions used by the rest of the +# hookable option parser framework in ascii-betical order. + + +# func_fatal_help ARG... +# ---------------------- +# Echo program name prefixed message to standard error, followed by +# a help hint, and exit. +func_fatal_help () { - case $1 in - *[\\\`\"\$]*) - func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;; - *) - func_quote_for_eval_unquoted_result="$1" ;; - esac + $debug_cmd - case $func_quote_for_eval_unquoted_result in - # Double-quote args containing shell metacharacters to delay - # word splitting, command substitution and and variable - # expansion for a subsequent eval. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" - ;; - *) - func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" - esac + eval \$bs_echo \""Usage: $usage"\" + eval \$bs_echo \""$fatal_help"\" + func_error ${1+"$@"} + exit $EXIT_FAILURE } -# func_quote_for_expand arg -# Aesthetically quote ARG to be evaled later; same as above, -# but do not quote variable references. -func_quote_for_expand () +# func_help +# --------- +# Echo long help message to standard output and exit. +func_help () { - case $1 in - *[\\\`\"]*) - my_arg=`$ECHO "$1" | $SED \ - -e "$double_quote_subst" -e "$sed_double_backslash"` ;; - *) - my_arg="$1" ;; - esac - - case $my_arg in - # Double-quote args containing shell metacharacters to delay - # word splitting and command substitution for a subsequent eval. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - my_arg="\"$my_arg\"" - ;; - esac + $debug_cmd - func_quote_for_expand_result="$my_arg" + func_usage_message + $bs_echo "$long_help_message" + exit 0 } -# func_show_eval cmd [fail_exp] -# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is -# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP -# is given, then evaluate it. -func_show_eval () +# func_missing_arg ARGNAME +# ------------------------ +# Echo program name prefixed message to standard error and set global +# exit_cmd. +func_missing_arg () { - my_cmd="$1" - my_fail_exp="${2-:}" - - ${opt_silent-false} || { - func_quote_for_expand "$my_cmd" - eval "func_echo $func_quote_for_expand_result" - } + $debug_cmd - if ${opt_dry_run-false}; then :; else - eval "$my_cmd" - my_status=$? - if test "$my_status" -eq 0; then :; else - eval "(exit $my_status); $my_fail_exp" - fi - fi + func_error "Missing argument for '$1'." + exit_cmd=exit } -# func_show_eval_locale cmd [fail_exp] -# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is -# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP -# is given, then evaluate it. Use the saved locale for evaluation. -func_show_eval_locale () -{ - my_cmd="$1" - my_fail_exp="${2-:}" +# func_split_equals STRING +# ------------------------ +# Set func_split_equals_lhs and func_split_equals_rhs shell variables after +# splitting STRING at the '=' sign. +test -z "$_G_HAVE_XSI_OPS" \ + && (eval 'x=a/b/c; + test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ + && _G_HAVE_XSI_OPS=yes - ${opt_silent-false} || { - func_quote_for_expand "$my_cmd" - eval "func_echo $func_quote_for_expand_result" - } +if test yes = "$_G_HAVE_XSI_OPS" +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_split_equals () + { + $debug_cmd - if ${opt_dry_run-false}; then :; else - eval "$lt_user_locale - $my_cmd" - my_status=$? - eval "$lt_safe_locale" - if test "$my_status" -eq 0; then :; else - eval "(exit $my_status); $my_fail_exp" - fi - fi -} + func_split_equals_lhs=${1%%=*} + func_split_equals_rhs=${1#*=} + test "x$func_split_equals_lhs" = "x$1" \ + && func_split_equals_rhs= + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_split_equals () + { + $debug_cmd -# func_tr_sh -# Turn $1 into a string suitable for a shell variable name. -# Result is stored in $func_tr_sh_result. All characters -# not in the set a-zA-Z0-9_ are replaced with '_'. Further, -# if $1 begins with a digit, a '_' is prepended as well. -func_tr_sh () -{ - case $1 in - [0-9]* | *[!a-zA-Z0-9_]*) - func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'` - ;; - * ) - func_tr_sh_result=$1 - ;; - esac -} + func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'` + func_split_equals_rhs= + test "x$func_split_equals_lhs" = "x$1" \ + || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'` + } +fi #func_split_equals -# func_version -# Echo version message to standard output and exit. -func_version () -{ - $opt_debug +# func_split_short_opt SHORTOPT +# ----------------------------- +# Set func_split_short_opt_name and func_split_short_opt_arg shell +# variables after splitting SHORTOPT after the 2nd character. +if test yes = "$_G_HAVE_XSI_OPS" +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_split_short_opt () + { + $debug_cmd + + func_split_short_opt_arg=${1#??} + func_split_short_opt_name=${1%"$func_split_short_opt_arg"} + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_split_short_opt () + { + $debug_cmd + + func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'` + func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'` + } +fi #func_split_short_opt - $SED -n '/(C)/!b go - :more - /\./!{ - N - s/\n# / / - b more - } - :go - /^# '$PROGRAM' (GNU /,/# warranty; / { - s/^# // - s/^# *$// - s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ - p - }' < "$progpath" - exit $? -} # func_usage +# ---------- # Echo short help message to standard output and exit. func_usage () { - $opt_debug + $debug_cmd - $SED -n '/^# Usage:/,/^# *.*--help/ { - s/^# // - s/^# *$// - s/\$progname/'$progname'/ - p - }' < "$progpath" - echo - $ECHO "run \`$progname --help | more' for full usage" - exit $? + func_usage_message + $bs_echo "Run '$progname --help |${PAGER-more}' for full usage" + exit 0 } -# func_help [NOEXIT] -# Echo long help message to standard output and exit, -# unless 'noexit' is passed as argument. -func_help () + +# func_usage_message +# ------------------ +# Echo short help message to standard output. +func_usage_message () { - $opt_debug - - $SED -n '/^# Usage:/,/# Report bugs to/ { - :print - s/^# // - s/^# *$// - s*\$progname*'$progname'* - s*\$host*'"$host"'* - s*\$SHELL*'"$SHELL"'* - s*\$LTCC*'"$LTCC"'* - s*\$LTCFLAGS*'"$LTCFLAGS"'* - s*\$LD*'"$LD"'* - s/\$with_gnu_ld/'"$with_gnu_ld"'/ - s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/ - s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/ - p - d - } - /^# .* home page:/b print - /^# General help using/b print - ' < "$progpath" - ret=$? - if test -z "$1"; then - exit $ret - fi + $debug_cmd + + eval \$bs_echo \""Usage: $usage"\" + echo + $SED -n 's|^# || + /^Written by/{ + x;p;x + } + h + /^Written by/q' < "$progpath" + echo + eval \$bs_echo \""$usage_message"\" } -# func_missing_arg argname -# Echo program name prefixed message to standard error and set global -# exit_cmd. -func_missing_arg () + +# func_version +# ------------ +# Echo version message to standard output and exit. +func_version () { - $opt_debug + $debug_cmd + + printf '%s\n' "$progname $scriptversion" + $SED -n '/^##/q + /(C)/!b go + :more + /\./!{ + N + s|\n# | | + b more + } + :go + /^# Written by /,/# warranty; / { + s|^# || + s|^# *$|| + s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2| + p + } + /^# Written by / { + s|^# || + p + } + /^warranty; /q' < "$progpath" - func_error "missing argument for $1." - exit_cmd=exit + exit $? } -# func_split_short_opt shortopt -# Set func_split_short_opt_name and func_split_short_opt_arg shell -# variables after splitting SHORTOPT after the 2nd character. -func_split_short_opt () -{ - my_sed_short_opt='1s/^\(..\).*$/\1/;q' - my_sed_short_rest='1s/^..\(.*\)$/\1/;q' +# Local variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" +# time-stamp-time-zone: "UTC" +# End: - func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"` - func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"` -} # func_split_short_opt may be replaced by extended shell implementation +# Set a version string. +scriptversion='(GNU libtool) 2.4.2.418' -# func_split_long_opt longopt -# Set func_split_long_opt_name and func_split_long_opt_arg shell -# variables after splitting LONGOPT at the `=' sign. -func_split_long_opt () +# func_echo ARG... +# ---------------- +# Libtool also displays the current mode in messages, so override +# funclib.sh func_echo with this custom definition. +func_echo () { - my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q' - my_sed_long_arg='1s/^--[^=]*=//' + $debug_cmd - func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"` - func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"` -} # func_split_long_opt may be replaced by extended shell implementation + _G_message=$* -exit_cmd=: + func_echo_IFS=$IFS + IFS=$nl + for _G_line in $_G_message; do + IFS=$func_echo_IFS + $bs_echo "$progname${opt_mode+: $opt_mode}: $_G_line" + done + IFS=$func_echo_IFS +} +# func_warning ARG... +# ------------------- +# Libtool warnings are not categorized, so override funclib.sh +# func_warning with this simpler definition. +func_warning () +{ + $debug_cmd + $warning_func ${1+"$@"} +} -magic="%%%MAGIC variable%%%" -magic_exe="%%%MAGIC EXE variable%%%" +## ---------------- ## +## Options parsing. ## +## ---------------- ## + +# Hook in the functions to make sure our own options are parsed during +# the option parsing loop. + +usage='$progpath [OPTION]... [MODE-ARG]...' + +# Short help message in response to '-h'. +usage_message="Options: + --config show all configuration variables + --debug enable verbose shell tracing + -n, --dry-run display commands without modifying any files + --features display basic configuration information and exit + --mode=MODE use operation mode MODE + --no-warnings equivalent to '-Wnone' + --preserve-dup-deps don't remove duplicate dependency libraries + --quiet, --silent don't print informational messages + --tag=TAG use configuration variables from tag TAG + -v, --verbose print more informational messages than default + --version print version information + -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] + -h, --help, --help-all print short, long, or detailed help message +" -# Global variables. -nonopt= -preserve_args= -lo2o="s/\\.lo\$/.${objext}/" -o2lo="s/\\.${objext}\$/.lo/" -extracted_archives= -extracted_serial=0 +# Additional text appended to 'usage_message' in response to '--help'. +long_help_message=$long_help_message" -# If this variable is set in any of the actions, the command in it -# will be execed at the end. This prevents here-documents from being -# left over by shells. -exec_cmd= +MODE must be one of the following: -# func_append var value -# Append VALUE to the end of shell variable VAR. -func_append () -{ - eval "${1}=\$${1}\${2}" -} # func_append may be replaced by extended shell implementation + clean remove files from the build directory + compile compile a source file into a libtool object + execute automatically set library path, then run a program + finish complete the installation of libtool libraries + install install libraries or executables + link create a library or an executable + uninstall remove libraries from an installed directory -# func_append_quoted var value -# Quote VALUE and append to the end of shell variable VAR, separated -# by a space. -func_append_quoted () -{ - func_quote_for_eval "${2}" - eval "${1}=\$${1}\\ \$func_quote_for_eval_result" -} # func_append_quoted may be replaced by extended shell implementation +MODE-ARGS vary depending on the MODE. When passed as first option, +'--mode=MODE' may be abbreviated as 'MODE' or a unique abbreviation of that. +Try '$progname --help --mode=MODE' for a more detailed description of MODE. +When reporting a bug, please describe a test case to reproduce it and +include the following information: -# func_arith arithmetic-term... -func_arith () -{ - func_arith_result=`expr "${@}"` -} # func_arith may be replaced by extended shell implementation + host-triplet: $host + shell: $SHELL + compiler: $LTCC + compiler flags: $LTCFLAGS + linker: $LD (gnu? $with_gnu_ld) + version: $progname (GNU libtool) 2.4.2.418 + automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q` + autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q` +Report bugs to . +GNU libtool home page: . +General help using GNU software: ." -# func_len string -# STRING may not start with a hyphen. -func_len () -{ - func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len` -} # func_len may be replaced by extended shell implementation +# func_lo2o OBJECT-NAME +# --------------------- +# Transform OBJECT-NAME from a '.lo' suffix to the platform specific +# object suffix. -# func_lo2o object -func_lo2o () -{ - func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` -} # func_lo2o may be replaced by extended shell implementation +lo2o=s/\\.lo\$/.$objext/ +o2lo=s/\\.$objext\$/.lo/ + +if test yes = "$_G_HAVE_XSI_OPS"; then + eval 'func_lo2o () + { + case $1 in + *.lo) func_lo2o_result=${1%.lo}.$objext ;; + * ) func_lo2o_result=$1 ;; + esac + }' + # func_xform LIBOBJ-OR-SOURCE + # --------------------------- + # Transform LIBOBJ-OR-SOURCE from a '.o' or '.c' (or otherwise) + # suffix to a '.lo' libtool-object suffix. + eval 'func_xform () + { + func_xform_result=${1%.*}.lo + }' +else + # ...otherwise fall back to using sed. + func_lo2o () + { + func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"` + } -# func_xform libobj-or-source -func_xform () -{ - func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'` -} # func_xform may be replaced by extended shell implementation + func_xform () + { + func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'` + } +fi -# func_fatal_configuration arg... +# func_fatal_configuration ARG... +# ------------------------------- # Echo program name prefixed message to standard error, followed by # a configuration failure hint, and exit. func_fatal_configuration () { - func_error ${1+"$@"} - func_error "See the $PACKAGE documentation for more information." - func_fatal_error "Fatal configuration error." + func__fatal_error ${1+"$@"} \ + "See the $PACKAGE documentation for more information." \ + "Fatal configuration error." } # func_config +# ----------- # Display the configuration for all the tags in this script. func_config () { @@ -915,17 +2048,19 @@ func_config () exit $? } + # func_features +# ------------- # Display the features supported by this script. func_features () { echo "host: $host" - if test "$build_libtool_libs" = yes; then + if test yes = "$build_libtool_libs"; then echo "enable shared libraries" else echo "disable shared libraries" fi - if test "$build_old_libs" = yes; then + if test yes = "$build_old_libs"; then echo "enable static libraries" else echo "disable static libraries" @@ -934,289 +2069,295 @@ func_features () exit $? } -# func_enable_tag tagname + +# func_enable_tag TAGNAME +# ----------------------- # Verify that TAGNAME is valid, and either flag an error and exit, or # enable the TAGNAME tag. We also add TAGNAME to the global $taglist # variable here. func_enable_tag () { - # Global variable: - tagname="$1" + # Global variable: + tagname=$1 - re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" - re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" - sed_extractcf="/$re_begincf/,/$re_endcf/p" + re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" + re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" + sed_extractcf=/$re_begincf/,/$re_endcf/p - # Validate tagname. - case $tagname in - *[!-_A-Za-z0-9,/]*) - func_fatal_error "invalid tag name: $tagname" - ;; - esac + # Validate tagname. + case $tagname in + *[!-_A-Za-z0-9,/]*) + func_fatal_error "invalid tag name: $tagname" + ;; + esac - # Don't test for the "default" C tag, as we know it's - # there but not specially marked. - case $tagname in - CC) ;; + # Don't test for the "default" C tag, as we know it's + # there but not specially marked. + case $tagname in + CC) ;; *) - if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then - taglist="$taglist $tagname" - - # Evaluate the configuration. Be careful to quote the path - # and the sed script, to avoid splitting on whitespace, but - # also don't use non-portable quotes within backquotes within - # quotes we have to do it in 2 steps: - extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` - eval "$extractedcf" - else - func_error "ignoring unknown tag $tagname" - fi - ;; - esac + if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then + taglist="$taglist $tagname" + + # Evaluate the configuration. Be careful to quote the path + # and the sed script, to avoid splitting on whitespace, but + # also don't use non-portable quotes within backquotes within + # quotes we have to do it in 2 steps: + extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` + eval "$extractedcf" + else + func_error "ignoring unknown tag $tagname" + fi + ;; + esac } + # func_check_version_match +# ------------------------ # Ensure that we are using m4 macros, and libtool script from the same # release of libtool. func_check_version_match () { - if test "$package_revision" != "$macro_revision"; then - if test "$VERSION" != "$macro_version"; then - if test -z "$macro_version"; then - cat >&2 <<_LT_EOF + if test "$package_revision" != "$macro_revision"; then + if test "$VERSION" != "$macro_version"; then + if test -z "$macro_version"; then + cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from an older release. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF - else - cat >&2 <<_LT_EOF + else + cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from $PACKAGE $macro_version. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF - fi - else - cat >&2 <<_LT_EOF + fi + else + cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, $progname: but the definition of this LT_INIT comes from revision $macro_revision. $progname: You should recreate aclocal.m4 with macros from revision $package_revision $progname: of $PACKAGE $VERSION and run autoconf again. _LT_EOF - fi + fi - exit $EXIT_MISMATCH - fi + exit $EXIT_MISMATCH + fi } -# Shorthand for --mode=foo, only valid as the first argument -case $1 in -clean|clea|cle|cl) - shift; set dummy --mode clean ${1+"$@"}; shift - ;; -compile|compil|compi|comp|com|co|c) - shift; set dummy --mode compile ${1+"$@"}; shift - ;; -execute|execut|execu|exec|exe|ex|e) - shift; set dummy --mode execute ${1+"$@"}; shift - ;; -finish|finis|fini|fin|fi|f) - shift; set dummy --mode finish ${1+"$@"}; shift - ;; -install|instal|insta|inst|ins|in|i) - shift; set dummy --mode install ${1+"$@"}; shift - ;; -link|lin|li|l) - shift; set dummy --mode link ${1+"$@"}; shift - ;; -uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) - shift; set dummy --mode uninstall ${1+"$@"}; shift - ;; -esac +# libtool_options_prep [ARG]... +# ----------------------------- +# Preparation for options parsed by libtool. +libtool_options_prep () +{ + $debug_mode + # Option defaults: + opt_config=false + opt_dlopen= + opt_dry_run=false + opt_help=false + opt_mode= + opt_preserve_dup_deps=false + opt_quiet=false + nonopt= + preserve_args= -# Option defaults: -opt_debug=: -opt_dry_run=false -opt_config=false -opt_preserve_dup_deps=false -opt_features=false -opt_finish=false -opt_help=false -opt_help_all=false -opt_silent=: -opt_warning=: -opt_verbose=: -opt_silent=false -opt_verbose=false + # Shorthand for --mode=foo, only valid as the first argument + case $1 in + clean|clea|cle|cl) + shift; set dummy --mode clean ${1+"$@"}; shift + ;; + compile|compil|compi|comp|com|co|c) + shift; set dummy --mode compile ${1+"$@"}; shift + ;; + execute|execut|execu|exec|exe|ex|e) + shift; set dummy --mode execute ${1+"$@"}; shift + ;; + finish|finis|fini|fin|fi|f) + shift; set dummy --mode finish ${1+"$@"}; shift + ;; + install|instal|insta|inst|ins|in|i) + shift; set dummy --mode install ${1+"$@"}; shift + ;; + link|lin|li|l) + shift; set dummy --mode link ${1+"$@"}; shift + ;; + uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) + shift; set dummy --mode uninstall ${1+"$@"}; shift + ;; + esac + + # Pass back the list of options. + func_quote_for_eval ${1+"$@"} + libtool_options_prep_result=$func_quote_for_eval_result +} +func_add_hook func_options_prep libtool_options_prep -# Parse options once, thoroughly. This comes as soon as possible in the -# script to make things like `--version' happen as quickly as we can. +# libtool_parse_options [ARG]... +# --------------------------------- +# Provide handling for libtool specific options. +libtool_parse_options () { - # this just eases exit handling - while test $# -gt 0; do - opt="$1" - shift - case $opt in - --debug|-x) opt_debug='set -x' - func_echo "enabling shell trace mode" - $opt_debug - ;; - --dry-run|--dryrun|-n) - opt_dry_run=: - ;; - --config) - opt_config=: -func_config - ;; - --dlopen|-dlopen) - optarg="$1" - opt_dlopen="${opt_dlopen+$opt_dlopen -}$optarg" - shift - ;; - --preserve-dup-deps) - opt_preserve_dup_deps=: - ;; - --features) - opt_features=: -func_features - ;; - --finish) - opt_finish=: -set dummy --mode finish ${1+"$@"}; shift - ;; - --help) - opt_help=: - ;; - --help-all) - opt_help_all=: -opt_help=': help-all' - ;; - --mode) - test $# = 0 && func_missing_arg $opt && break - optarg="$1" - opt_mode="$optarg" -case $optarg in - # Valid mode arguments: - clean|compile|execute|finish|install|link|relink|uninstall) ;; - - # Catch anything else as an error - *) func_error "invalid argument for $opt" - exit_cmd=exit - break - ;; -esac - shift - ;; - --no-silent|--no-quiet) - opt_silent=false -func_append preserve_args " $opt" - ;; - --no-warning|--no-warn) - opt_warning=false -func_append preserve_args " $opt" - ;; - --no-verbose) - opt_verbose=false -func_append preserve_args " $opt" - ;; - --silent|--quiet) - opt_silent=: -func_append preserve_args " $opt" - opt_verbose=false - ;; - --verbose|-v) - opt_verbose=: -func_append preserve_args " $opt" -opt_silent=false - ;; - --tag) - test $# = 0 && func_missing_arg $opt && break - optarg="$1" - opt_tag="$optarg" -func_append preserve_args " $opt $optarg" -func_enable_tag "$optarg" - shift - ;; - - -\?|-h) func_usage ;; - --help) func_help ;; - --version) func_version ;; - - # Separate optargs to long options: - --*=*) - func_split_long_opt "$opt" - set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"} - shift - ;; - - # Separate non-argument short options: - -\?*|-h*|-n*|-v*) - func_split_short_opt "$opt" - set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"} - shift - ;; - - --) break ;; - -*) func_fatal_help "unrecognized option \`$opt'" ;; - *) set dummy "$opt" ${1+"$@"}; shift; break ;; - esac - done + $debug_cmd + + # Perform our own loop to consume as many options as possible in + # each iteration. + while test $# -gt 0; do + _G_opt=$1 + shift + case $_G_opt in + --dry-run|--dryrun|-n) + opt_dry_run=: + ;; + + --config) func_config ;; + + --dlopen|-dlopen) + opt_dlopen="${opt_dlopen+$opt_dlopen +}$1" + shift + ;; + + --preserve-dup-deps) + opt_preserve_dup_deps=: ;; + + --features) func_features ;; + + --finish) set dummy --mode finish ${1+"$@"}; shift ;; + + --help) opt_help=: ;; + + --help-all) opt_help=': help-all' ;; + + --mode) test $# = 0 && func_missing_arg $_G_opt && break + opt_mode=$1 + case $1 in + # Valid mode arguments: + clean|compile|execute|finish|install|link|relink|uninstall) ;; + + # Catch anything else as an error + *) func_error "invalid argument for $_G_opt" + exit_cmd=exit + break + ;; + esac + shift + ;; + + --no-silent|--no-quiet) + opt_quiet=false + func_append preserve_args " $_G_opt" + ;; + + --no-warnings|--no-warning|--no-warn) + opt_warning=false + func_append preserve_args " $_G_opt" + ;; + + --no-verbose) + opt_verbose=false + func_append preserve_args " $_G_opt" + ;; + + --silent|--quiet) + opt_quiet=: + opt_verbose=false + func_append preserve_args " $_G_opt" + ;; + + --tag) test $# = 0 && func_missing_arg $_G_opt && break + opt_tag=$1 + func_append preserve_args " $_G_opt $1" + func_enable_tag "$1" + shift + ;; + + --verbose|-v) opt_quiet=false + opt_verbose=: + func_append preserve_args " $_G_opt" + ;; + + # An option not handled by this hook function: + *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; + esac + done + + + # save modified positional parameters for caller + func_quote_for_eval ${1+"$@"} + libtool_parse_options_result=$func_quote_for_eval_result +} +func_add_hook func_parse_options libtool_parse_options - # Validate options: - # save first non-option argument - if test "$#" -gt 0; then - nonopt="$opt" - shift - fi - # preserve --debug - test "$opt_debug" = : || func_append preserve_args " --debug" +# libtool_validate_options [ARG]... +# --------------------------------- +# Perform any sanity checks on option settings and/or unconsumed +# arguments. +libtool_validate_options () +{ + # save first non-option argument + if test 0 -lt $#; then + nonopt=$1 + shift + fi - case $host in - *cygwin* | *mingw* | *pw32* | *cegcc*) - # don't eliminate duplications in $postdeps and $predeps - opt_duplicate_compiler_generated_deps=: - ;; - *) - opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps - ;; - esac + # preserve --debug + test : = "$debug_cmd" || func_append preserve_args " --debug" - $opt_help || { - # Sanity checks first: - func_check_version_match + case $host in + *cygwin* | *mingw* | *pw32* | *cegcc*) + # don't eliminate duplications in $postdeps and $predeps + opt_duplicate_compiler_generated_deps=: + ;; + *) + opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps + ;; + esac - if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then - func_fatal_configuration "not configured to build any kind of library" - fi + $opt_help || { + # Sanity checks first: + func_check_version_match - # Darwin sucks - eval std_shrext=\"$shrext_cmds\" + test yes != "$build_libtool_libs" \ + && test yes != "$build_old_libs" \ + && func_fatal_configuration "not configured to build any kind of library" - # Only execute mode is allowed to have -dlopen flags. - if test -n "$opt_dlopen" && test "$opt_mode" != execute; then - func_error "unrecognized option \`-dlopen'" - $ECHO "$help" 1>&2 - exit $EXIT_FAILURE - fi + # Darwin sucks + eval std_shrext=\"$shrext_cmds\" - # Change the help message to a mode-specific one. - generic_help="$help" - help="Try \`$progname --help --mode=$opt_mode' for more information." - } + # Only execute mode is allowed to have -dlopen flags. + if test -n "$opt_dlopen" && test execute != "$opt_mode"; then + func_error "unrecognized option '-dlopen'" + $ECHO "$help" 1>&2 + exit $EXIT_FAILURE + fi + # Change the help message to a mode-specific one. + generic_help=$help + help="Try '$progname --help --mode=$opt_mode' for more information." + } - # Bail if the options were screwed - $exit_cmd $EXIT_FAILURE + # Pass back the unparsed argument list + func_quote_for_eval ${1+"$@"} + libtool_validate_options_result=$func_quote_for_eval_result } +func_add_hook func_validate_options libtool_validate_options + +# Process options as early as possible so that --help and --version +# can return quickly. +func_options ${1+"$@"} +eval set dummy "$func_options_result"; shift @@ -1224,8 +2365,29 @@ func_enable_tag "$optarg" ## Main. ## ## ----------- ## +magic='%%%MAGIC variable%%%' +magic_exe='%%%MAGIC EXE variable%%%' + +# Global variables. +extracted_archives= +extracted_serial=0 + +# If this variable is set in any of the actions, the command in it +# will be execed at the end. This prevents here-documents from being +# left over by shells. +exec_cmd= + + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' +} + # func_lalib_p file -# True iff FILE is a libtool `.la' library or `.lo' object file. +# True iff FILE is a libtool '.la' library or '.lo' object file. # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_lalib_p () @@ -1236,12 +2398,12 @@ func_lalib_p () } # func_lalib_unsafe_p file -# True iff FILE is a libtool `.la' library or `.lo' object file. +# True iff FILE is a libtool '.la' library or '.lo' object file. # This function implements the same check as func_lalib_p without # resorting to external programs. To this end, it redirects stdin and # closes it afterwards, without saving the original file descriptor. # As a safety measure, use it only where a negative result would be -# fatal anyway. Works if `file' does not exist. +# fatal anyway. Works if 'file' does not exist. func_lalib_unsafe_p () { lalib_p=no @@ -1249,13 +2411,13 @@ func_lalib_unsafe_p () for lalib_p_l in 1 2 3 4 do read lalib_p_line - case "$lalib_p_line" in + case $lalib_p_line in \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; esac done exec 0<&5 5<&- fi - test "$lalib_p" = yes + test yes = "$lalib_p" } # func_ltwrapper_script_p file @@ -1289,7 +2451,7 @@ func_ltwrapper_scriptname () { func_dirname_and_basename "$1" "" "." func_stripname '' '.exe' "$func_basename_result" - func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" + func_ltwrapper_scriptname_result=$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper } # func_ltwrapper_p file @@ -1308,11 +2470,13 @@ func_ltwrapper_p () # FAIL_CMD may read-access the current command in variable CMD! func_execute_cmds () { - $opt_debug + $debug_cmd + save_ifs=$IFS; IFS='~' for cmd in $1; do - IFS=$save_ifs + IFS=$sp$nl eval cmd=\"$cmd\" + IFS=$save_ifs func_show_eval "$cmd" "${2-:}" done IFS=$save_ifs @@ -1324,10 +2488,11 @@ func_execute_cmds () # Note that it is not necessary on cygwin/mingw to append a dot to # FILE even if both FILE and FILE.exe exist: automatic-append-.exe # behavior happens only for exec(3), not for open(2)! Also, sourcing -# `FILE.' does not work on cygwin managed mounts. +# 'FILE.' does not work on cygwin managed mounts. func_source () { - $opt_debug + $debug_cmd + case $1 in */* | *\\*) . "$1" ;; *) . "./$1" ;; @@ -1354,10 +2519,10 @@ func_resolve_sysroot () # store the result into func_replace_sysroot_result. func_replace_sysroot () { - case "$lt_sysroot:$1" in + case $lt_sysroot:$1 in ?*:"$lt_sysroot"*) func_stripname "$lt_sysroot" '' "$1" - func_replace_sysroot_result="=$func_stripname_result" + func_replace_sysroot_result='='$func_stripname_result ;; *) # Including no sysroot. @@ -1374,7 +2539,8 @@ func_replace_sysroot () # arg is usually of the form 'gcc ...' func_infer_tag () { - $opt_debug + $debug_cmd + if test -n "$available_tags" && test -z "$tagname"; then CC_quoted= for arg in $CC; do @@ -1393,7 +2559,7 @@ func_infer_tag () for z in $available_tags; do if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then # Evaluate the configuration. - eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" + eval "`$SED -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" CC_quoted= for arg in $CC; do # Double-quote args containing other shell metacharacters. @@ -1418,7 +2584,7 @@ func_infer_tag () # line option must be used. if test -z "$tagname"; then func_echo "unable to infer tagged configuration" - func_fatal_error "specify a tag with \`--tag'" + func_fatal_error "specify a tag with '--tag'" # else # func_verbose "using $tagname tagged configuration" fi @@ -1434,15 +2600,15 @@ func_infer_tag () # but don't create it if we're doing a dry run. func_write_libtool_object () { - write_libobj=${1} - if test "$build_libtool_libs" = yes; then - write_lobj=\'${2}\' + write_libobj=$1 + if test yes = "$build_libtool_libs"; then + write_lobj=\'$2\' else write_lobj=none fi - if test "$build_old_libs" = yes; then - write_oldobj=\'${3}\' + if test yes = "$build_old_libs"; then + write_oldobj=\'$3\' else write_oldobj=none fi @@ -1450,7 +2616,7 @@ func_write_libtool_object () $opt_dry_run || { cat >${write_libobj}T </dev/null` - if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then + if test "$?" -eq 0 && test -n "$func_convert_core_file_wine_to_w32_tmp"; then func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | - $SED -e "$lt_sed_naive_backslashify"` + $SED -e "$sed_naive_backslashify"` else func_convert_core_file_wine_to_w32_result= fi @@ -1514,18 +2681,19 @@ func_convert_core_file_wine_to_w32 () # are convertible, then the result may be empty. func_convert_core_path_wine_to_w32 () { - $opt_debug + $debug_cmd + # unfortunately, winepath doesn't convert paths, only file names - func_convert_core_path_wine_to_w32_result="" + func_convert_core_path_wine_to_w32_result= if test -n "$1"; then oldIFS=$IFS IFS=: for func_convert_core_path_wine_to_w32_f in $1; do IFS=$oldIFS func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" - if test -n "$func_convert_core_file_wine_to_w32_result" ; then + if test -n "$func_convert_core_file_wine_to_w32_result"; then if test -z "$func_convert_core_path_wine_to_w32_result"; then - func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result" + func_convert_core_path_wine_to_w32_result=$func_convert_core_file_wine_to_w32_result else func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" fi @@ -1554,7 +2722,8 @@ func_convert_core_path_wine_to_w32 () # environment variable; do not put it in $PATH. func_cygpath () { - $opt_debug + $debug_cmd + if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` if test "$?" -ne 0; then @@ -1563,7 +2732,7 @@ func_cygpath () fi else func_cygpath_result= - func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'" + func_error "LT_CYGPATH is empty or specifies non-existent file: '$LT_CYGPATH'" fi } #end: func_cygpath @@ -1574,10 +2743,11 @@ func_cygpath () # result in func_convert_core_msys_to_w32_result. func_convert_core_msys_to_w32 () { - $opt_debug + $debug_cmd + # awkward: cmd appends spaces to result func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | - $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"` + $SED -e 's/[ ]*$//' -e "$sed_naive_backslashify"` } #end: func_convert_core_msys_to_w32 @@ -1588,13 +2758,14 @@ func_convert_core_msys_to_w32 () # func_to_host_file_result to ARG1). func_convert_file_check () { - $opt_debug - if test -z "$2" && test -n "$1" ; then + $debug_cmd + + if test -z "$2" && test -n "$1"; then func_error "Could not determine host file name corresponding to" - func_error " \`$1'" + func_error " '$1'" func_error "Continuing, but uninstalled executables may not work." # Fallback: - func_to_host_file_result="$1" + func_to_host_file_result=$1 fi } # end func_convert_file_check @@ -1606,10 +2777,11 @@ func_convert_file_check () # func_to_host_file_result to a simplistic fallback value (see below). func_convert_path_check () { - $opt_debug + $debug_cmd + if test -z "$4" && test -n "$3"; then func_error "Could not determine the host path corresponding to" - func_error " \`$3'" + func_error " '$3'" func_error "Continuing, but uninstalled executables may not work." # Fallback. This is a deliberately simplistic "conversion" and # should not be "improved". See libtool.info. @@ -1618,7 +2790,7 @@ func_convert_path_check () func_to_host_path_result=`echo "$3" | $SED -e "$lt_replace_pathsep_chars"` else - func_to_host_path_result="$3" + func_to_host_path_result=$3 fi fi } @@ -1630,9 +2802,10 @@ func_convert_path_check () # and appending REPL if ORIG matches BACKPAT. func_convert_path_front_back_pathsep () { - $opt_debug + $debug_cmd + case $4 in - $1 ) func_to_host_path_result="$3$func_to_host_path_result" + $1 ) func_to_host_path_result=$3$func_to_host_path_result ;; esac case $4 in @@ -1646,7 +2819,7 @@ func_convert_path_front_back_pathsep () ################################################## # $build to $host FILE NAME CONVERSION FUNCTIONS # ################################################## -# invoked via `$to_host_file_cmd ARG' +# invoked via '$to_host_file_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # Result will be available in $func_to_host_file_result. @@ -1657,7 +2830,8 @@ func_convert_path_front_back_pathsep () # in func_to_host_file_result. func_to_host_file () { - $opt_debug + $debug_cmd + $to_host_file_cmd "$1" } # end func_to_host_file @@ -1669,7 +2843,8 @@ func_to_host_file () # in (the comma separated) LAZY, no conversion takes place. func_to_tool_file () { - $opt_debug + $debug_cmd + case ,$2, in *,"$to_tool_file_cmd",*) func_to_tool_file_result=$1 @@ -1687,7 +2862,7 @@ func_to_tool_file () # Copy ARG to func_to_host_file_result. func_convert_file_noop () { - func_to_host_file_result="$1" + func_to_host_file_result=$1 } # end func_convert_file_noop @@ -1698,11 +2873,12 @@ func_convert_file_noop () # func_to_host_file_result. func_convert_file_msys_to_w32 () { - $opt_debug - func_to_host_file_result="$1" + $debug_cmd + + func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_msys_to_w32 "$1" - func_to_host_file_result="$func_convert_core_msys_to_w32_result" + func_to_host_file_result=$func_convert_core_msys_to_w32_result fi func_convert_file_check "$1" "$func_to_host_file_result" } @@ -1714,8 +2890,9 @@ func_convert_file_msys_to_w32 () # func_to_host_file_result. func_convert_file_cygwin_to_w32 () { - $opt_debug - func_to_host_file_result="$1" + $debug_cmd + + func_to_host_file_result=$1 if test -n "$1"; then # because $build is cygwin, we call "the" cygpath in $PATH; no need to use # LT_CYGPATH in this case. @@ -1731,11 +2908,12 @@ func_convert_file_cygwin_to_w32 () # and a working winepath. Returns result in func_to_host_file_result. func_convert_file_nix_to_w32 () { - $opt_debug - func_to_host_file_result="$1" + $debug_cmd + + func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_file_wine_to_w32 "$1" - func_to_host_file_result="$func_convert_core_file_wine_to_w32_result" + func_to_host_file_result=$func_convert_core_file_wine_to_w32_result fi func_convert_file_check "$1" "$func_to_host_file_result" } @@ -1747,12 +2925,13 @@ func_convert_file_nix_to_w32 () # Returns result in func_to_host_file_result. func_convert_file_msys_to_cygwin () { - $opt_debug - func_to_host_file_result="$1" + $debug_cmd + + func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_cygpath -u "$func_convert_core_msys_to_w32_result" - func_to_host_file_result="$func_cygpath_result" + func_to_host_file_result=$func_cygpath_result fi func_convert_file_check "$1" "$func_to_host_file_result" } @@ -1765,13 +2944,14 @@ func_convert_file_msys_to_cygwin () # in func_to_host_file_result. func_convert_file_nix_to_cygwin () { - $opt_debug - func_to_host_file_result="$1" + $debug_cmd + + func_to_host_file_result=$1 if test -n "$1"; then # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. func_convert_core_file_wine_to_w32 "$1" func_cygpath -u "$func_convert_core_file_wine_to_w32_result" - func_to_host_file_result="$func_cygpath_result" + func_to_host_file_result=$func_cygpath_result fi func_convert_file_check "$1" "$func_to_host_file_result" } @@ -1781,7 +2961,7 @@ func_convert_file_nix_to_cygwin () ############################################# # $build to $host PATH CONVERSION FUNCTIONS # ############################################# -# invoked via `$to_host_path_cmd ARG' +# invoked via '$to_host_path_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # The result will be available in $func_to_host_path_result. @@ -1805,10 +2985,11 @@ func_convert_file_nix_to_cygwin () to_host_path_cmd= func_init_to_host_path_cmd () { - $opt_debug + $debug_cmd + if test -z "$to_host_path_cmd"; then func_stripname 'func_convert_file_' '' "$to_host_file_cmd" - to_host_path_cmd="func_convert_path_${func_stripname_result}" + to_host_path_cmd=func_convert_path_$func_stripname_result fi } @@ -1818,7 +2999,8 @@ func_init_to_host_path_cmd () # in func_to_host_path_result. func_to_host_path () { - $opt_debug + $debug_cmd + func_init_to_host_path_cmd $to_host_path_cmd "$1" } @@ -1829,7 +3011,7 @@ func_to_host_path () # Copy ARG to func_to_host_path_result. func_convert_path_noop () { - func_to_host_path_result="$1" + func_to_host_path_result=$1 } # end func_convert_path_noop @@ -1840,8 +3022,9 @@ func_convert_path_noop () # func_to_host_path_result. func_convert_path_msys_to_w32 () { - $opt_debug - func_to_host_path_result="$1" + $debug_cmd + + func_to_host_path_result=$1 if test -n "$1"; then # Remove leading and trailing path separator characters from ARG. MSYS # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; @@ -1849,7 +3032,7 @@ func_convert_path_msys_to_w32 () func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" - func_to_host_path_result="$func_convert_core_msys_to_w32_result" + func_to_host_path_result=$func_convert_core_msys_to_w32_result func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" @@ -1863,8 +3046,9 @@ func_convert_path_msys_to_w32 () # func_to_host_file_result. func_convert_path_cygwin_to_w32 () { - $opt_debug - func_to_host_path_result="$1" + $debug_cmd + + func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" @@ -1883,14 +3067,15 @@ func_convert_path_cygwin_to_w32 () # a working winepath. Returns result in func_to_host_file_result. func_convert_path_nix_to_w32 () { - $opt_debug - func_to_host_path_result="$1" + $debug_cmd + + func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" - func_to_host_path_result="$func_convert_core_path_wine_to_w32_result" + func_to_host_path_result=$func_convert_core_path_wine_to_w32_result func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" @@ -1904,15 +3089,16 @@ func_convert_path_nix_to_w32 () # Returns result in func_to_host_file_result. func_convert_path_msys_to_cygwin () { - $opt_debug - func_to_host_path_result="$1" + $debug_cmd + + func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_msys_to_w32_result" - func_to_host_path_result="$func_cygpath_result" + func_to_host_path_result=$func_cygpath_result func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" @@ -1927,8 +3113,9 @@ func_convert_path_msys_to_cygwin () # func_to_host_file_result. func_convert_path_nix_to_cygwin () { - $opt_debug - func_to_host_path_result="$1" + $debug_cmd + + func_to_host_path_result=$1 if test -n "$1"; then # Remove leading and trailing path separator characters from # ARG. msys behavior is inconsistent here, cygpath turns them @@ -1937,7 +3124,7 @@ func_convert_path_nix_to_cygwin () func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" - func_to_host_path_result="$func_cygpath_result" + func_to_host_path_result=$func_cygpath_result func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" @@ -1946,13 +3133,31 @@ func_convert_path_nix_to_cygwin () # end func_convert_path_nix_to_cygwin +# func_dll_def_p FILE +# True iff FILE is a Windows DLL '.def' file. +# Keep in sync with _LT_DLL_DEF_P in libtool.m4 +func_dll_def_p () +{ + $debug_cmd + + func_dll_def_p_tmp=`$SED -n \ + -e 's/^[ ]*//' \ + -e '/^\(;.*\)*$/d' \ + -e 's/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p' \ + -e q \ + "$1"` + test DEF = "$func_dll_def_p_tmp" +} + + # func_mode_compile arg... func_mode_compile () { - $opt_debug + $debug_cmd + # Get the compilation command and the source file. base_compile= - srcfile="$nonopt" # always keep a non-empty value in "srcfile" + srcfile=$nonopt # always keep a non-empty value in "srcfile" suppress_opt=yes suppress_output= arg_mode=normal @@ -1965,12 +3170,12 @@ func_mode_compile () case $arg_mode in arg ) # do not "continue". Instead, add this to base_compile - lastarg="$arg" + lastarg=$arg arg_mode=normal ;; target ) - libobj="$arg" + libobj=$arg arg_mode=normal continue ;; @@ -1980,7 +3185,7 @@ func_mode_compile () case $arg in -o) test -n "$libobj" && \ - func_fatal_error "you cannot specify \`-o' more than once" + func_fatal_error "you cannot specify '-o' more than once" arg_mode=target continue ;; @@ -2009,12 +3214,12 @@ func_mode_compile () func_stripname '-Wc,' '' "$arg" args=$func_stripname_result lastarg= - save_ifs="$IFS"; IFS=',' + save_ifs=$IFS; IFS=, for arg in $args; do - IFS="$save_ifs" + IFS=$save_ifs func_append_quoted lastarg "$arg" done - IFS="$save_ifs" + IFS=$save_ifs func_stripname ' ' '' "$lastarg" lastarg=$func_stripname_result @@ -2027,8 +3232,8 @@ func_mode_compile () # Accept the current argument as the source file. # The previous "srcfile" becomes the current argument. # - lastarg="$srcfile" - srcfile="$arg" + lastarg=$srcfile + srcfile=$arg ;; esac # case $arg ;; @@ -2043,13 +3248,13 @@ func_mode_compile () func_fatal_error "you must specify an argument for -Xcompile" ;; target) - func_fatal_error "you must specify a target with \`-o'" + func_fatal_error "you must specify a target with '-o'" ;; *) # Get the name of the library object. test -z "$libobj" && { func_basename "$srcfile" - libobj="$func_basename_result" + libobj=$func_basename_result } ;; esac @@ -2069,7 +3274,7 @@ func_mode_compile () case $libobj in *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; *) - func_fatal_error "cannot determine name of library object from \`$libobj'" + func_fatal_error "cannot determine name of library object from '$libobj'" ;; esac @@ -2078,8 +3283,8 @@ func_mode_compile () for arg in $later; do case $arg in -shared) - test "$build_libtool_libs" != yes && \ - func_fatal_configuration "can not build a shared library" + test yes = "$build_libtool_libs" \ + || func_fatal_configuration "cannot build a shared library" build_old_libs=no continue ;; @@ -2105,17 +3310,17 @@ func_mode_compile () func_quote_for_eval "$libobj" test "X$libobj" != "X$func_quote_for_eval_result" \ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ - && func_warning "libobj name \`$libobj' may not contain shell special characters." + && func_warning "libobj name '$libobj' may not contain shell special characters." func_dirname_and_basename "$obj" "/" "" - objname="$func_basename_result" - xdir="$func_dirname_result" - lobj=${xdir}$objdir/$objname + objname=$func_basename_result + xdir=$func_dirname_result + lobj=$xdir$objdir/$objname test -z "$base_compile" && \ func_fatal_help "you must specify a compilation command" # Delete any leftover library objects. - if test "$build_old_libs" = yes; then + if test yes = "$build_old_libs"; then removelist="$obj $lobj $libobj ${libobj}T" else removelist="$lobj $libobj ${libobj}T" @@ -2127,16 +3332,16 @@ func_mode_compile () pic_mode=default ;; esac - if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then + if test no = "$pic_mode" && test pass_all != "$deplibs_check_method"; then # non-PIC code in shared libraries is not supported pic_mode=default fi # Calculate the filename of the output object if compiler does # not support -o with -c - if test "$compiler_c_o" = no; then - output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext} - lockfile="$output_obj.lock" + if test no = "$compiler_c_o"; then + output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.$objext + lockfile=$output_obj.lock else output_obj= need_locks=no @@ -2145,12 +3350,12 @@ func_mode_compile () # Lock this critical section if it is needed # We use this script file to make the link, it avoids creating a new file - if test "$need_locks" = yes; then + if test yes = "$need_locks"; then until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done - elif test "$need_locks" = warn; then + elif test warn = "$need_locks"; then if test -f "$lockfile"; then $ECHO "\ *** ERROR, $lockfile exists and contains: @@ -2158,7 +3363,7 @@ func_mode_compile () This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you +your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." @@ -2180,11 +3385,11 @@ compiler." qsrcfile=$func_quote_for_eval_result # Only build a PIC object if we are building libtool libraries. - if test "$build_libtool_libs" = yes; then + if test yes = "$build_libtool_libs"; then # Without this assignment, base_compile gets emptied. fbsd_hideous_sh_bug=$base_compile - if test "$pic_mode" != no; then + if test no != "$pic_mode"; then command="$base_compile $qsrcfile $pic_flag" else # Don't build PIC code @@ -2201,7 +3406,7 @@ compiler." func_show_eval_locale "$command" \ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' - if test "$need_locks" = warn && + if test warn = "$need_locks" && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: @@ -2212,7 +3417,7 @@ $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you +your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." @@ -2228,20 +3433,20 @@ compiler." fi # Allow error messages only from the first compilation. - if test "$suppress_opt" = yes; then + if test yes = "$suppress_opt"; then suppress_output=' >/dev/null 2>&1' fi fi # Only build a position-dependent object if we build old libraries. - if test "$build_old_libs" = yes; then - if test "$pic_mode" != yes; then + if test yes = "$build_old_libs"; then + if test yes != "$pic_mode"; then # Don't build PIC code command="$base_compile $qsrcfile$pie_flag" else command="$base_compile $qsrcfile $pic_flag" fi - if test "$compiler_c_o" = yes; then + if test yes = "$compiler_c_o"; then func_append command " -o $obj" fi @@ -2250,7 +3455,7 @@ compiler." func_show_eval_locale "$command" \ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' - if test "$need_locks" = warn && + if test warn = "$need_locks" && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: @@ -2261,7 +3466,7 @@ $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you +your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." @@ -2281,7 +3486,7 @@ compiler." func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" # Unlock the critical section if it was locked - if test "$need_locks" != no; then + if test no != "$need_locks"; then removelist=$lockfile $RM "$lockfile" fi @@ -2291,7 +3496,7 @@ compiler." } $opt_help || { - test "$opt_mode" = compile && func_mode_compile ${1+"$@"} + test compile = "$opt_mode" && func_mode_compile ${1+"$@"} } func_mode_help () @@ -2311,7 +3516,7 @@ func_mode_help () Remove files from the build directory. RM is the name of the program to use to delete files associated with each FILE -(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +(typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed to RM. If FILE is a libtool library, object or program, all the files associated @@ -2330,16 +3535,16 @@ This mode accepts the following additional options: -no-suppress do not suppress compiler output for multiple passes -prefer-pic try to build PIC objects only -prefer-non-pic try to build non-PIC objects only - -shared do not build a \`.o' file suitable for static linking - -static only build a \`.o' file suitable for static linking + -shared do not build a '.o' file suitable for static linking + -static only build a '.o' file suitable for static linking -Wc,FLAG pass FLAG directly to the compiler -COMPILE-COMMAND is a command to be used in creating a \`standard' object file +COMPILE-COMMAND is a command to be used in creating a 'standard' object file from the given SOURCEFILE. The output file name is determined by removing the directory component from -SOURCEFILE, then substituting the C source code suffix \`.c' with the -library object suffix, \`.lo'." +SOURCEFILE, then substituting the C source code suffix '.c' with the +library object suffix, '.lo'." ;; execute) @@ -2352,7 +3557,7 @@ This mode accepts the following additional options: -dlopen FILE add the directory containing FILE to the library path -This mode sets the library path environment variable according to \`-dlopen' +This mode sets the library path environment variable according to '-dlopen' flags. If any of the ARGS are libtool executable wrappers, then they are translated @@ -2371,7 +3576,7 @@ Complete the installation of libtool libraries. Each LIBDIR is a directory that contains libtool libraries. The commands that this mode executes may require superuser privileges. Use -the \`--dry-run' option if you just want to see what would be executed." +the '--dry-run' option if you just want to see what would be executed." ;; install) @@ -2381,7 +3586,7 @@ the \`--dry-run' option if you just want to see what would be executed." Install executables or libraries. INSTALL-COMMAND is the installation command. The first component should be -either the \`install' or \`cp' program. +either the 'install' or 'cp' program. The following components of INSTALL-COMMAND are treated specially: @@ -2407,7 +3612,7 @@ The following components of LINK-COMMAND are treated specially: -avoid-version do not add a version suffix if possible -bindir BINDIR specify path to binaries directory (for systems where libraries must be found in the PATH setting at runtime) - -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime + -dlopen FILE '-dlpreopen' FILE if it cannot be dlopened at runtime -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) -export-symbols SYMFILE @@ -2441,20 +3646,20 @@ The following components of LINK-COMMAND are treated specially: -Xlinker FLAG pass linker-specific FLAG directly to the linker -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) -All other options (arguments beginning with \`-') are ignored. +All other options (arguments beginning with '-') are ignored. -Every other argument is treated as a filename. Files ending in \`.la' are +Every other argument is treated as a filename. Files ending in '.la' are treated as uninstalled libtool libraries, other files are standard or library object files. -If the OUTPUT-FILE ends in \`.la', then a libtool library is created, -only library objects (\`.lo' files) may be specified, and \`-rpath' is +If the OUTPUT-FILE ends in '.la', then a libtool library is created, +only library objects ('.lo' files) may be specified, and '-rpath' is required, except when creating a convenience library. -If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created -using \`ar' and \`ranlib', or on Windows using \`lib'. +If OUTPUT-FILE ends in '.a' or '.lib', then a standard library is created +using 'ar' and 'ranlib', or on Windows using 'lib'. -If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file +If OUTPUT-FILE ends in '.lo' or '.$objext', then a reloadable object file is created, otherwise an executable program is created." ;; @@ -2465,7 +3670,7 @@ is created, otherwise an executable program is created." Remove libraries from an installation directory. RM is the name of the program to use to delete files associated with each FILE -(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +(typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed to RM. If FILE is a libtool library, all the files associated with it are deleted. @@ -2473,17 +3678,17 @@ Otherwise, only FILE itself is deleted using RM." ;; *) - func_fatal_help "invalid operation mode \`$opt_mode'" + func_fatal_help "invalid operation mode '$opt_mode'" ;; esac echo - $ECHO "Try \`$progname --help' for more information about other modes." + $ECHO "Try '$progname --help' for more information about other modes." } # Now that we've collected a possible --mode arg, show help if necessary if $opt_help; then - if test "$opt_help" = :; then + if test : = "$opt_help"; then func_mode_help else { @@ -2516,16 +3721,17 @@ fi # func_mode_execute arg... func_mode_execute () { - $opt_debug + $debug_cmd + # The first argument is the command name. - cmd="$nonopt" + cmd=$nonopt test -z "$cmd" && \ func_fatal_help "you must specify a COMMAND" # Handle -dlopen flags immediately. for file in $opt_dlopen; do test -f "$file" \ - || func_fatal_help "\`$file' is not a file" + || func_fatal_help "'$file' is not a file" dir= case $file in @@ -2535,7 +3741,7 @@ func_mode_execute () # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ - || func_fatal_help "\`$lib' is not a valid libtool archive" + || func_fatal_help "'$lib' is not a valid libtool archive" # Read the libtool library. dlname= @@ -2546,18 +3752,18 @@ func_mode_execute () if test -z "$dlname"; then # Warn if it was a shared library. test -n "$library_names" && \ - func_warning "\`$file' was not linked with \`-export-dynamic'" + func_warning "'$file' was not linked with '-export-dynamic'" continue fi func_dirname "$file" "" "." - dir="$func_dirname_result" + dir=$func_dirname_result if test -f "$dir/$objdir/$dlname"; then func_append dir "/$objdir" else if test ! -f "$dir/$dlname"; then - func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" + func_fatal_error "cannot find '$dlname' in '$dir' or '$dir/$objdir'" fi fi ;; @@ -2565,18 +3771,18 @@ func_mode_execute () *.lo) # Just add the directory containing the .lo file. func_dirname "$file" "" "." - dir="$func_dirname_result" + dir=$func_dirname_result ;; *) - func_warning "\`-dlopen' is ignored for non-libtool libraries and objects" + func_warning "'-dlopen' is ignored for non-libtool libraries and objects" continue ;; esac # Get the absolute pathname. absdir=`cd "$dir" && pwd` - test -n "$absdir" && dir="$absdir" + test -n "$absdir" && dir=$absdir # Now add the directory to shlibpath_var. if eval "test -z \"\$$shlibpath_var\""; then @@ -2588,7 +3794,7 @@ func_mode_execute () # This variable tells wrapper scripts just to set shlibpath_var # rather than running their programs. - libtool_execute_magic="$magic" + libtool_execute_magic=$magic # Check if any of the arguments is a wrapper script. args= @@ -2601,12 +3807,12 @@ func_mode_execute () if func_ltwrapper_script_p "$file"; then func_source "$file" # Transform arg to wrapped name. - file="$progdir/$program" + file=$progdir/$program elif func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" func_source "$func_ltwrapper_scriptname_result" # Transform arg to wrapped name. - file="$progdir/$program" + file=$progdir/$program fi ;; esac @@ -2614,7 +3820,15 @@ func_mode_execute () func_append_quoted args "$file" done - if test "X$opt_dry_run" = Xfalse; then + if $opt_dry_run; then + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" + echo "export $shlibpath_var" + fi + $ECHO "$cmd$args" + exit $EXIT_SUCCESS + else if test -n "$shlibpath_var"; then # Export the shlibpath_var. eval "export $shlibpath_var" @@ -2631,25 +3845,18 @@ func_mode_execute () done # Now prepare to actually exec the command. - exec_cmd="\$cmd$args" - else - # Display what would be done. - if test -n "$shlibpath_var"; then - eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" - echo "export $shlibpath_var" - fi - $ECHO "$cmd$args" - exit $EXIT_SUCCESS + exec_cmd=\$cmd$args fi } -test "$opt_mode" = execute && func_mode_execute ${1+"$@"} +test execute = "$opt_mode" && func_mode_execute ${1+"$@"} # func_mode_finish arg... func_mode_finish () { - $opt_debug + $debug_cmd + libs= libdirs= admincmds= @@ -2663,11 +3870,11 @@ func_mode_finish () if func_lalib_unsafe_p "$opt"; then func_append libs " $opt" else - func_warning "\`$opt' is not a valid libtool archive" + func_warning "'$opt' is not a valid libtool archive" fi else - func_fatal_error "invalid argument \`$opt'" + func_fatal_error "invalid argument '$opt'" fi done @@ -2682,12 +3889,12 @@ func_mode_finish () # Remove sysroot references if $opt_dry_run; then for lib in $libs; do - echo "removing references to $lt_sysroot and \`=' prefixes from $lib" + echo "removing references to $lt_sysroot and '=' prefixes from $lib" done else tmpdir=`func_mktempdir` for lib in $libs; do - sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ + sed -e "$sysroot_cmd s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ > $tmpdir/tmp-la mv -f $tmpdir/tmp-la $lib done @@ -2712,7 +3919,7 @@ func_mode_finish () fi # Exit here if they wanted silent mode. - $opt_silent && exit $EXIT_SUCCESS + $opt_quiet && exit $EXIT_SUCCESS if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then echo "----------------------------------------------------------------------" @@ -2723,27 +3930,27 @@ func_mode_finish () echo echo "If you ever happen to want to link against installed libraries" echo "in a given directory, LIBDIR, you must either use libtool, and" - echo "specify the full pathname of the library, or use the \`-LLIBDIR'" + echo "specify the full pathname of the library, or use the '-LLIBDIR'" echo "flag during linking and do at least one of the following:" if test -n "$shlibpath_var"; then - echo " - add LIBDIR to the \`$shlibpath_var' environment variable" + echo " - add LIBDIR to the '$shlibpath_var' environment variable" echo " during execution" fi if test -n "$runpath_var"; then - echo " - add LIBDIR to the \`$runpath_var' environment variable" + echo " - add LIBDIR to the '$runpath_var' environment variable" echo " during linking" fi if test -n "$hardcode_libdir_flag_spec"; then libdir=LIBDIR eval flag=\"$hardcode_libdir_flag_spec\" - $ECHO " - use the \`$flag' linker flag" + $ECHO " - use the '$flag' linker flag" fi if test -n "$admincmds"; then $ECHO " - have your system administrator run these commands:$admincmds" fi if test -f /etc/ld.so.conf; then - echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" + echo " - have your system administrator add LIBDIR to '/etc/ld.so.conf'" fi echo @@ -2762,18 +3969,20 @@ func_mode_finish () exit $EXIT_SUCCESS } -test "$opt_mode" = finish && func_mode_finish ${1+"$@"} +test finish = "$opt_mode" && func_mode_finish ${1+"$@"} # func_mode_install arg... func_mode_install () { - $opt_debug + $debug_cmd + # There may be an optional sh(1) argument at the beginning of # install_prog (especially on Windows NT). - if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || + if test "$SHELL" = "$nonopt" || test /bin/sh = "$nonopt" || # Allow the use of GNU shtool's install command. - case $nonopt in *shtool*) :;; *) false;; esac; then + case $nonopt in *shtool*) :;; *) false;; esac + then # Aesthetically quote it. func_quote_for_eval "$nonopt" install_prog="$func_quote_for_eval_result " @@ -2800,7 +4009,7 @@ func_mode_install () opts= prev= install_type= - isdir=no + isdir=false stripme= no_mode=: for arg @@ -2813,7 +4022,7 @@ func_mode_install () fi case $arg in - -d) isdir=yes ;; + -d) isdir=: ;; -f) if $install_cp; then :; else prev=$arg @@ -2831,7 +4040,7 @@ func_mode_install () *) # If the previous option needed an argument, then skip it. if test -n "$prev"; then - if test "x$prev" = x-m && test -n "$install_override_mode"; then + if test X-m = "X$prev" && test -n "$install_override_mode"; then arg2=$install_override_mode no_mode=false fi @@ -2856,7 +4065,7 @@ func_mode_install () func_fatal_help "you must specify an install program" test -n "$prev" && \ - func_fatal_help "the \`$prev' option requires an argument" + func_fatal_help "the '$prev' option requires an argument" if test -n "$install_override_mode" && $no_mode; then if $install_cp; then :; else @@ -2878,19 +4087,19 @@ func_mode_install () dest=$func_stripname_result # Check to see that the destination is a directory. - test -d "$dest" && isdir=yes - if test "$isdir" = yes; then - destdir="$dest" + test -d "$dest" && isdir=: + if $isdir; then + destdir=$dest destname= else func_dirname_and_basename "$dest" "" "." - destdir="$func_dirname_result" - destname="$func_basename_result" + destdir=$func_dirname_result + destname=$func_basename_result # Not a directory, so check to see that there is only one file specified. set dummy $files; shift test "$#" -gt 1 && \ - func_fatal_help "\`$dest' is not a directory" + func_fatal_help "'$dest' is not a directory" fi case $destdir in [\\/]* | [A-Za-z]:[\\/]*) ;; @@ -2899,7 +4108,7 @@ func_mode_install () case $file in *.lo) ;; *) - func_fatal_help "\`$destdir' must be an absolute directory name" + func_fatal_help "'$destdir' must be an absolute directory name" ;; esac done @@ -2908,7 +4117,7 @@ func_mode_install () # This variable tells wrapper scripts just to set variables rather # than running their programs. - libtool_install_magic="$magic" + libtool_install_magic=$magic staticlibs= future_libdirs= @@ -2928,7 +4137,7 @@ func_mode_install () # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ - || func_fatal_help "\`$file' is not a valid libtool archive" + || func_fatal_help "'$file' is not a valid libtool archive" library_names= old_library= @@ -2950,7 +4159,7 @@ func_mode_install () fi func_dirname "$file" "/" "" - dir="$func_dirname_result" + dir=$func_dirname_result func_append dir "$objdir" if test -n "$relink_command"; then @@ -2964,7 +4173,7 @@ func_mode_install () # are installed into $libdir/../bin (currently, that works fine) # but it's something to keep an eye on. test "$inst_prefix_dir" = "$destdir" && \ - func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir" + func_fatal_error "error: cannot install '$file' to a directory not ending in $libdir" if test -n "$inst_prefix_dir"; then # Stick the inst_prefix_dir data into the link command. @@ -2973,29 +4182,29 @@ func_mode_install () relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` fi - func_warning "relinking \`$file'" + func_warning "relinking '$file'" func_show_eval "$relink_command" \ - 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"' + 'func_fatal_error "error: relink '\''$file'\'' with the above command before installing it"' fi # See the names of the shared library. set dummy $library_names; shift if test -n "$1"; then - realname="$1" + realname=$1 shift - srcname="$realname" - test -n "$relink_command" && srcname="$realname"T + srcname=$realname + test -n "$relink_command" && srcname=${realname}T # Install the shared library and build the symlinks. func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ 'exit $?' - tstripme="$stripme" + tstripme=$stripme case $host_os in cygwin* | mingw* | pw32* | cegcc*) case $realname in *.dll.a) - tstripme="" + tstripme= ;; esac ;; @@ -3006,7 +4215,7 @@ func_mode_install () if test "$#" -gt 0; then # Delete the old symlinks, and create new ones. - # Try `ln -sf' first, because the `ln' binary might depend on + # Try 'ln -sf' first, because the 'ln' binary might depend on # the symlink we replace! Solaris /bin/ln does not understand -f, # so we also need to try rm && ln -s. for linkname @@ -3017,14 +4226,14 @@ func_mode_install () fi # Do each command in the postinstall commands. - lib="$destdir/$realname" + lib=$destdir/$realname func_execute_cmds "$postinstall_cmds" 'exit $?' fi # Install the pseudo-library for information purposes. func_basename "$file" - name="$func_basename_result" - instname="$dir/$name"i + name=$func_basename_result + instname=$dir/${name}i func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' # Maybe install the static library, too. @@ -3036,11 +4245,11 @@ func_mode_install () # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then - destfile="$destdir/$destname" + destfile=$destdir/$destname else func_basename "$file" - destfile="$func_basename_result" - destfile="$destdir/$destfile" + destfile=$func_basename_result + destfile=$destdir/$destfile fi # Deduce the name of the destination old-style object file. @@ -3050,11 +4259,11 @@ func_mode_install () staticdest=$func_lo2o_result ;; *.$objext) - staticdest="$destfile" + staticdest=$destfile destfile= ;; *) - func_fatal_help "cannot copy a libtool object to \`$destfile'" + func_fatal_help "cannot copy a libtool object to '$destfile'" ;; esac @@ -3063,7 +4272,7 @@ func_mode_install () func_show_eval "$install_prog $file $destfile" 'exit $?' # Install the old object if enabled. - if test "$build_old_libs" = yes; then + if test yes = "$build_old_libs"; then # Deduce the name of the old-style object file. func_lo2o "$file" staticobj=$func_lo2o_result @@ -3075,23 +4284,23 @@ func_mode_install () *) # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then - destfile="$destdir/$destname" + destfile=$destdir/$destname else func_basename "$file" - destfile="$func_basename_result" - destfile="$destdir/$destfile" + destfile=$func_basename_result + destfile=$destdir/$destfile fi # If the file is missing, and there is a .exe on the end, strip it # because it is most likely a libtool script we actually want to # install - stripped_ext="" + stripped_ext= case $file in *.exe) if test ! -f "$file"; then func_stripname '' '.exe' "$file" file=$func_stripname_result - stripped_ext=".exe" + stripped_ext=.exe fi ;; esac @@ -3119,19 +4328,19 @@ func_mode_install () # Check the variables that should have been set. test -z "$generated_by_libtool_version" && \ - func_fatal_error "invalid libtool wrapper script \`$wrapper'" + func_fatal_error "invalid libtool wrapper script '$wrapper'" - finalize=yes + finalize=: for lib in $notinst_deplibs; do # Check to see that each library is installed. libdir= if test -f "$lib"; then func_source "$lib" fi - libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test + libfile=$libdir/`$ECHO "$lib" | $SED 's%^.*/%%g'` if test -n "$libdir" && test ! -f "$libfile"; then - func_warning "\`$lib' has not been installed in \`$libdir'" - finalize=no + func_warning "'$lib' has not been installed in '$libdir'" + finalize=false fi done @@ -3139,29 +4348,29 @@ func_mode_install () func_source "$wrapper" outputname= - if test "$fast_install" = no && test -n "$relink_command"; then + if test no = "$fast_install" && test -n "$relink_command"; then $opt_dry_run || { - if test "$finalize" = yes; then + if $finalize; then tmpdir=`func_mktempdir` func_basename "$file$stripped_ext" - file="$func_basename_result" - outputname="$tmpdir/$file" + file=$func_basename_result + outputname=$tmpdir/$file # Replace the output file specification. relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` - $opt_silent || { + $opt_quiet || { func_quote_for_expand "$relink_command" eval "func_echo $func_quote_for_expand_result" } if eval "$relink_command"; then : else - func_error "error: relink \`$file' with the above command before installing it" + func_error "error: relink '$file' with the above command before installing it" $opt_dry_run || ${RM}r "$tmpdir" continue fi - file="$outputname" + file=$outputname else - func_warning "cannot relink \`$file'" + func_warning "cannot relink '$file'" fi } else @@ -3198,10 +4407,10 @@ func_mode_install () for file in $staticlibs; do func_basename "$file" - name="$func_basename_result" + name=$func_basename_result # Set up the ranlib parameters. - oldlib="$destdir/$name" + oldlib=$destdir/$name func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result @@ -3216,18 +4425,18 @@ func_mode_install () done test -n "$future_libdirs" && \ - func_warning "remember to run \`$progname --finish$future_libdirs'" + func_warning "remember to run '$progname --finish$future_libdirs'" if test -n "$current_libdirs"; then # Maybe just do a dry run. $opt_dry_run && current_libdirs=" -n$current_libdirs" - exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' + exec_cmd='$SHELL "$progpath" $preserve_args --finish$current_libdirs' else exit $EXIT_SUCCESS fi } -test "$opt_mode" = install && func_mode_install ${1+"$@"} +test install = "$opt_mode" && func_mode_install ${1+"$@"} # func_generate_dlsyms outputname originator pic_p @@ -3235,16 +4444,17 @@ test "$opt_mode" = install && func_mode_install ${1+"$@"} # a dlpreopen symbol table. func_generate_dlsyms () { - $opt_debug - my_outputname="$1" - my_originator="$2" - my_pic_p="${3-no}" + $debug_cmd + + my_outputname=$1 + my_originator=$2 + my_pic_p=${3-false} my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` my_dlsyms= - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then if test -n "$NM" && test -n "$global_symbol_pipe"; then - my_dlsyms="${my_outputname}S.c" + my_dlsyms=${my_outputname}S.c else func_error "not configured to extract global symbols from dlpreopened files" fi @@ -3255,7 +4465,7 @@ func_generate_dlsyms () "") ;; *.c) # Discover the nlist of each of the dlfiles. - nlist="$output_objdir/${my_outputname}.nm" + nlist=$output_objdir/$my_outputname.nm func_show_eval "$RM $nlist ${nlist}S ${nlist}T" @@ -3263,34 +4473,36 @@ func_generate_dlsyms () func_verbose "creating $output_objdir/$my_dlsyms" $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ -/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */ -/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */ +/* $my_dlsyms - symbol resolution table for '$my_outputname' dlsym emulation. */ +/* Generated by $PROGRAM (GNU $PACKAGE) $VERSION */ #ifdef __cplusplus extern \"C\" { #endif -#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) +#if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) #pragma GCC diagnostic ignored \"-Wstrict-prototypes\" #endif /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ -#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) -/* DATA imports from DLLs on WIN32 con't be const, because runtime +#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE +/* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST -#elif defined(__osf__) +#elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif +#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) + /* External symbol declarations for the compiler. */\ " - if test "$dlself" = yes; then - func_verbose "generating symbol list for \`$output'" + if test yes = "$dlself"; then + func_verbose "generating symbol list for '$output'" $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" @@ -3298,7 +4510,7 @@ extern \"C\" { progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` for progfile in $progfiles; do func_to_tool_file "$progfile" func_convert_file_msys_to_w32 - func_verbose "extracting global C symbols from \`$func_to_tool_file_result'" + func_verbose "extracting global C symbols from '$func_to_tool_file_result'" $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" done @@ -3318,10 +4530,10 @@ extern \"C\" { # Prepare the list of exported symbols if test -z "$export_symbols"; then - export_symbols="$output_objdir/$outputname.exp" + export_symbols=$output_objdir/$outputname.exp $opt_dry_run || { $RM $export_symbols - eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' @@ -3331,7 +4543,7 @@ extern \"C\" { } else $opt_dry_run || { - eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' + eval "$SED -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' case $host in @@ -3345,22 +4557,22 @@ extern \"C\" { fi for dlprefile in $dlprefiles; do - func_verbose "extracting global C symbols from \`$dlprefile'" + func_verbose "extracting global C symbols from '$dlprefile'" func_basename "$dlprefile" - name="$func_basename_result" + name=$func_basename_result case $host in *cygwin* | *mingw* | *cegcc* ) # if an import library, we need to obtain dlname if func_win32_import_lib_p "$dlprefile"; then func_tr_sh "$dlprefile" eval "curr_lafile=\$libfile_$func_tr_sh_result" - dlprefile_dlbasename="" + dlprefile_dlbasename= if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then # Use subshell, to avoid clobbering current variable values dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` - if test -n "$dlprefile_dlname" ; then + if test -n "$dlprefile_dlname"; then func_basename "$dlprefile_dlname" - dlprefile_dlbasename="$func_basename_result" + dlprefile_dlbasename=$func_basename_result else # no lafile. user explicitly requested -dlpreopen . $sharedlib_from_linklib_cmd "$dlprefile" @@ -3368,7 +4580,7 @@ extern \"C\" { fi fi $opt_dry_run || { - if test -n "$dlprefile_dlbasename" ; then + if test -n "$dlprefile_dlbasename"; then eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' else func_warning "Could not compute DLL name from $name" @@ -3424,6 +4636,11 @@ extern \"C\" { echo '/* NONE */' >> "$output_objdir/$my_dlsyms" fi + func_show_eval '$RM "${nlist}I"' + if test -n "$global_symbol_to_import"; then + eval "$global_symbol_to_import"' < "$nlist"S > "$nlist"I' + fi + echo >> "$output_objdir/$my_dlsyms" "\ /* The mapping between symbol names and symbols. */ @@ -3432,11 +4649,30 @@ typedef struct { void *address; } lt_dlsymlist; extern LT_DLSYM_CONST lt_dlsymlist -lt_${my_prefix}_LTX_preloaded_symbols[]; +lt_${my_prefix}_LTX_preloaded_symbols[];\ +" + + if test -s "$nlist"I; then + echo >> "$output_objdir/$my_dlsyms" "\ +static void lt_syminit(void) +{ + LT_DLSYM_CONST lt_dlsymlist *symbol = lt_${my_prefix}_LTX_preloaded_symbols; + for (; symbol->name; ++symbol) + {" + $SED 's/.*/ if (STREQ (symbol->name, \"&\")) symbol->address = (void *) \&&;/' < "$nlist"I >> "$output_objdir/$my_dlsyms" + echo >> "$output_objdir/$my_dlsyms" "\ + } +}" + fi + echo >> "$output_objdir/$my_dlsyms" "\ LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[] = -{\ - { \"$my_originator\", (void *) 0 }," +{ {\"$my_originator\", (void *) 0}," + + if test -s "$nlist"I; then + echo >> "$output_objdir/$my_dlsyms" "\ + {\"@INIT@\", (void *) <_syminit}," + fi case $need_lib_prefix in no) @@ -3478,9 +4714,7 @@ static const void *lt_preloaded_setup() { *-*-hpux*) pic_flag_for_symtable=" $pic_flag" ;; *) - if test "X$my_pic_p" != Xno; then - pic_flag_for_symtable=" $pic_flag" - fi + $my_pic_p && pic_flag_for_symtable=" $pic_flag" ;; esac ;; @@ -3497,10 +4731,10 @@ static const void *lt_preloaded_setup() { func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' # Clean up the generated files. - func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"' + func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T" "${nlist}I"' # Transform the symbol file into the correct name. - symfileobj="$output_objdir/${my_outputname}S.$objext" + symfileobj=$output_objdir/${my_outputname}S.$objext case $host in *cygwin* | *mingw* | *cegcc* ) if test -f "$output_objdir/$my_outputname.def"; then @@ -3518,7 +4752,7 @@ static const void *lt_preloaded_setup() { esac ;; *) - func_fatal_error "unknown suffix for \`$my_dlsyms'" + func_fatal_error "unknown suffix for '$my_dlsyms'" ;; esac else @@ -3532,6 +4766,32 @@ static const void *lt_preloaded_setup() { fi } +# func_cygming_gnu_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is a GNU/binutils-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_gnu_implib_p () +{ + $debug_cmd + + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` + test -n "$func_cygming_gnu_implib_tmp" +} + +# func_cygming_ms_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is an MS-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_ms_implib_p () +{ + $debug_cmd + + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` + test -n "$func_cygming_ms_implib_tmp" +} + # func_win32_libid arg # return the library type of file 'arg' # @@ -3541,8 +4801,9 @@ static const void *lt_preloaded_setup() { # Despite the name, also deal with 64 bit binaries. func_win32_libid () { - $opt_debug - win32_libid_type="unknown" + $debug_cmd + + win32_libid_type=unknown win32_fileres=`file -L $1 2>/dev/null` case $win32_fileres in *ar\ archive\ import\ library*) # definitely import @@ -3552,16 +4813,29 @@ func_win32_libid () # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then - func_to_tool_file "$1" func_convert_file_msys_to_w32 - win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | - $SED -n -e ' + case $nm_interface in + "MS dumpbin") + if func_cygming_ms_implib_p "$1" || + func_cygming_gnu_implib_p "$1" + then + win32_nmres=import + else + win32_nmres= + fi + ;; + *) + func_to_tool_file "$1" func_convert_file_msys_to_w32 + win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | + $SED -n -e ' 1,100{ / I /{ - s,.*,import, + s|.*|import| p q } }'` + ;; + esac case $win32_nmres in import*) win32_libid_type="x86 archive import";; *) win32_libid_type="x86 archive static";; @@ -3593,7 +4867,8 @@ func_win32_libid () # $sharedlib_from_linklib_result func_cygming_dll_for_implib () { - $opt_debug + $debug_cmd + sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` } @@ -3610,7 +4885,8 @@ func_cygming_dll_for_implib () # specified import library. func_cygming_dll_for_implib_fallback_core () { - $opt_debug + $debug_cmd + match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` $OBJDUMP -s --section "$1" "$2" 2>/dev/null | $SED '/^Contents of section '"$match_literal"':/{ @@ -3646,8 +4922,8 @@ func_cygming_dll_for_implib_fallback_core () /./p' | # we now have a list, one entry per line, of the stringified # contents of the appropriate section of all members of the - # archive which possess that section. Heuristic: eliminate - # all those which have a first or second character that is + # archive that possess that section. Heuristic: eliminate + # all those that have a first or second character that is # a '.' (that is, objdump's representation of an unprintable # character.) This should work for all archives with less than # 0x302f exports -- but will fail for DLLs whose name actually @@ -3658,30 +4934,6 @@ func_cygming_dll_for_implib_fallback_core () $SED -e '/^\./d;/^.\./d;q' } -# func_cygming_gnu_implib_p ARG -# This predicate returns with zero status (TRUE) if -# ARG is a GNU/binutils-style import library. Returns -# with nonzero status (FALSE) otherwise. -func_cygming_gnu_implib_p () -{ - $opt_debug - func_to_tool_file "$1" func_convert_file_msys_to_w32 - func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` - test -n "$func_cygming_gnu_implib_tmp" -} - -# func_cygming_ms_implib_p ARG -# This predicate returns with zero status (TRUE) if -# ARG is an MS-style import library. Returns -# with nonzero status (FALSE) otherwise. -func_cygming_ms_implib_p () -{ - $opt_debug - func_to_tool_file "$1" func_convert_file_msys_to_w32 - func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` - test -n "$func_cygming_ms_implib_tmp" -} - # func_cygming_dll_for_implib_fallback ARG # Platform-specific function to extract the # name of the DLL associated with the specified @@ -3695,16 +4947,17 @@ func_cygming_ms_implib_p () # $sharedlib_from_linklib_result func_cygming_dll_for_implib_fallback () { - $opt_debug - if func_cygming_gnu_implib_p "$1" ; then + $debug_cmd + + if func_cygming_gnu_implib_p "$1"; then # binutils import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` - elif func_cygming_ms_implib_p "$1" ; then + elif func_cygming_ms_implib_p "$1"; then # ms-generated import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` else # unknown - sharedlib_from_linklib_result="" + sharedlib_from_linklib_result= fi } @@ -3712,10 +4965,11 @@ func_cygming_dll_for_implib_fallback () # func_extract_an_archive dir oldlib func_extract_an_archive () { - $opt_debug - f_ex_an_ar_dir="$1"; shift - f_ex_an_ar_oldlib="$1" - if test "$lock_old_archive_extraction" = yes; then + $debug_cmd + + f_ex_an_ar_dir=$1; shift + f_ex_an_ar_oldlib=$1 + if test yes = "$lock_old_archive_extraction"; then lockfile=$f_ex_an_ar_oldlib.lock until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" @@ -3724,7 +4978,7 @@ func_extract_an_archive () fi func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ 'stat=$?; rm -f "$lockfile"; exit $stat' - if test "$lock_old_archive_extraction" = yes; then + if test yes = "$lock_old_archive_extraction"; then $opt_dry_run || rm -f "$lockfile" fi if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then @@ -3738,22 +4992,23 @@ func_extract_an_archive () # func_extract_archives gentop oldlib ... func_extract_archives () { - $opt_debug - my_gentop="$1"; shift + $debug_cmd + + my_gentop=$1; shift my_oldlibs=${1+"$@"} - my_oldobjs="" - my_xlib="" - my_xabs="" - my_xdir="" + my_oldobjs= + my_xlib= + my_xabs= + my_xdir= for my_xlib in $my_oldlibs; do # Extract the objects. case $my_xlib in - [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; + [\\/]* | [A-Za-z]:[\\/]*) my_xabs=$my_xlib ;; *) my_xabs=`pwd`"/$my_xlib" ;; esac func_basename "$my_xlib" - my_xlib="$func_basename_result" + my_xlib=$func_basename_result my_xlib_u=$my_xlib while :; do case " $extracted_archives " in @@ -3765,7 +5020,7 @@ func_extract_archives () esac done extracted_archives="$extracted_archives $my_xlib_u" - my_xdir="$my_gentop/$my_xlib_u" + my_xdir=$my_gentop/$my_xlib_u func_mkdir_p "$my_xdir" @@ -3778,19 +5033,20 @@ func_extract_archives () cd $my_xdir || exit $? darwin_archive=$my_xabs darwin_curdir=`pwd` - darwin_base_archive=`basename "$darwin_archive"` + func_basename "$darwin_archive" + darwin_base_archive=$func_basename_result darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` if test -n "$darwin_arches"; then darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` darwin_arch= func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" - for darwin_arch in $darwin_arches ; do - func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}" - $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" - cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" - func_extract_an_archive "`pwd`" "${darwin_base_archive}" + for darwin_arch in $darwin_arches; do + func_mkdir_p "unfat-$$/$darwin_base_archive-$darwin_arch" + $LIPO -thin $darwin_arch -output "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" "$darwin_archive" + cd "unfat-$$/$darwin_base_archive-$darwin_arch" + func_extract_an_archive "`pwd`" "$darwin_base_archive" cd "$darwin_curdir" - $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" + $RM "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" done # $darwin_arches ## Okay now we've a bunch of thin objects, gotta fatten them up :) darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u` @@ -3815,7 +5071,7 @@ func_extract_archives () my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` done - func_extract_archives_result="$my_oldobjs" + func_extract_archives_result=$my_oldobjs } @@ -3830,7 +5086,7 @@ func_extract_archives () # # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR # variable will take. If 'yes', then the emitted script -# will assume that the directory in which it is stored is +# will assume that the directory where it is stored is # the $objdir directory. This is a cygwin/mingw-specific # behavior. func_emit_wrapper () @@ -3841,7 +5097,7 @@ func_emit_wrapper () #! $SHELL # $output - temporary wrapper script for $objdir/$outputname -# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# Generated by $PROGRAM (GNU $PACKAGE) $VERSION # # The $output program cannot be directly executed until all the libtool # libraries that it depends on are installed. @@ -3898,9 +5154,9 @@ _LTECHO_EOF' # Very basic option parsing. These options are (a) specific to # the libtool wrapper, (b) are identical between the wrapper -# /script/ and the wrapper /executable/ which is used only on +# /script/ and the wrapper /executable/ that is used only on # windows platforms, and (c) all begin with the string "--lt-" -# (application programs are unlikely to have options which match +# (application programs are unlikely to have options that match # this pattern). # # There are only two supported options: --lt-debug and @@ -3933,7 +5189,7 @@ func_parse_lt_options () # Print the debug banner immediately: if test -n \"\$lt_option_debug\"; then - echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2 + echo \"$outputname:$output:\$LINENO: libtool wrapper (GNU $PACKAGE) $VERSION\" 1>&2 fi } @@ -3944,7 +5200,7 @@ func_lt_dump_args () lt_dump_args_N=1; for lt_arg do - \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\" + \$ECHO \"$outputname:$output:\$LINENO: newargv[\$lt_dump_args_N]: \$lt_arg\" lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` done } @@ -3958,7 +5214,7 @@ func_exec_program_core () *-*-mingw | *-*-os2* | *-cegcc*) $ECHO "\ if test -n \"\$lt_option_debug\"; then - \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2 + \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} @@ -3968,7 +5224,7 @@ func_exec_program_core () *) $ECHO "\ if test -n \"\$lt_option_debug\"; then - \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2 + \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir/\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir/\$program\" \${1+\"\$@\"} @@ -4043,13 +5299,13 @@ func_exec_program () test -n \"\$absdir\" && thisdir=\"\$absdir\" " - if test "$fast_install" = yes; then + if test yes = "$fast_install"; then $ECHO "\ program=lt-'$outputname'$exeext progdir=\"\$thisdir/$objdir\" if test ! -f \"\$progdir/\$program\" || - { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | $SED 1q\`; \\ test \"X\$file\" != \"X\$progdir/\$program\"; }; then file=\"\$\$-\$program\" @@ -4101,7 +5357,7 @@ func_exec_program () fi # Export our shlibpath_var if we have one. - if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then $ECHO "\ # Add our own library path to $shlibpath_var $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" @@ -4121,7 +5377,7 @@ func_exec_program () fi else # The program doesn't exist. - \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 + \$ECHO \"\$0: error: '\$progdir/\$program' does not exist\" 1>&2 \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 exit 1 @@ -4140,7 +5396,7 @@ func_emit_cwrapperexe_src () cat < #include +#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) + /* declarations of non-ANSI functions */ -#if defined(__MINGW32__) +#if defined __MINGW32__ # ifdef __STRICT_ANSI__ int _putenv (const char *); # endif -#elif defined(__CYGWIN__) +#elif defined __CYGWIN__ # ifdef __STRICT_ANSI__ char *realpath (const char *, char *); int putenv (char *); int setenv (const char *, const char *, int); # endif -/* #elif defined (other platforms) ... */ +/* #elif defined other_platform || defined ... */ #endif /* portability defines, excluding path handling macros */ -#if defined(_MSC_VER) +#if defined _MSC_VER # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv # define S_IXUSR _S_IEXEC -# ifndef _INTPTR_T_DEFINED -# define _INTPTR_T_DEFINED -# define intptr_t int -# endif -#elif defined(__MINGW32__) +#elif defined __MINGW32__ # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv -#elif defined(__CYGWIN__) +#elif defined __CYGWIN__ # define HAVE_SETENV # define FOPEN_WB "wb" -/* #elif defined (other platforms) ... */ +/* #elif defined other platforms ... */ #endif -#if defined(PATH_MAX) +#if defined PATH_MAX # define LT_PATHMAX PATH_MAX -#elif defined(MAXPATHLEN) +#elif defined MAXPATHLEN # define LT_PATHMAX MAXPATHLEN #else # define LT_PATHMAX 1024 @@ -4234,8 +5488,8 @@ int setenv (const char *, const char *, int); # define PATH_SEPARATOR ':' #endif -#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ - defined (__OS2__) +#if defined _WIN32 || defined __MSDOS__ || defined __DJGPP__ || \ + defined __OS2__ # define HAVE_DOS_BASED_FILE_SYSTEM # define FOPEN_WB "wb" # ifndef DIR_SEPARATOR_2 @@ -4268,10 +5522,10 @@ int setenv (const char *, const char *, int); #define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) #define XFREE(stale) do { \ - if (stale) { free ((void *) stale); stale = 0; } \ + if (stale) { free (stale); stale = 0; } \ } while (0) -#if defined(LT_DEBUGWRAPPER) +#if defined LT_DEBUGWRAPPER static int lt_debug = 1; #else static int lt_debug = 0; @@ -4304,7 +5558,7 @@ volatile const char * MAGIC_EXE = "$magic_exe"; const char * LIB_PATH_VARNAME = "$shlibpath_var"; EOF - if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then func_to_host_path "$temp_rpath" cat < 0) && IS_PATH_SEPARATOR (new_value[len-1])) + size_t len = strlen (new_value); + while ((len > 0) && IS_PATH_SEPARATOR (new_value[len-1])) { - new_value[len-1] = '\0'; + new_value[--len] = '\0'; } lt_setenv (name, new_value); XFREE (new_value); @@ -5082,7 +6336,8 @@ EOF # True if ARG is an import lib, as indicated by $file_magic_cmd func_win32_import_lib_p () { - $opt_debug + $debug_cmd + case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in *import*) : ;; *) false ;; @@ -5092,17 +6347,18 @@ func_win32_import_lib_p () # func_mode_link arg... func_mode_link () { - $opt_debug + $debug_cmd + case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) # It is impossible to link a dll without this setting, and # we shouldn't force the makefile maintainer to figure out - # which system we are compiling for in order to pass an extra + # what system we are compiling for in order to pass an extra # flag for every libtool invocation. # allow_undefined=no # FIXME: Unfortunately, there are problems with the above when trying - # to make a dll which has undefined symbols, in which case not + # to make a dll that has undefined symbols, in which case not # even a static library is built. For now, we need to specify # -no-undefined on the libtool link line when we can be certain # that all symbols are satisfied, otherwise we get a static library. @@ -5149,7 +6405,7 @@ func_mode_link () non_pic_objects= precious_files_regex= prefer_static_libs=no - preload=no + preload=false prev= prevarg= release= @@ -5161,7 +6417,7 @@ func_mode_link () vinfo= vinfo_number=no weak_libs= - single_module="${wl}-single_module" + single_module=$wl-single_module func_infer_tag $base_compile # We need to know -static, to get the right output filenames. @@ -5169,15 +6425,15 @@ func_mode_link () do case $arg in -shared) - test "$build_libtool_libs" != yes && \ - func_fatal_configuration "can not build a shared library" + test yes != "$build_libtool_libs" \ + && func_fatal_configuration "cannot build a shared library" build_old_libs=no break ;; -all-static | -static | -static-libtool-libs) case $arg in -all-static) - if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then + if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then func_warning "complete static linking is impossible in this configuration" fi if test -n "$link_static_flag"; then @@ -5210,7 +6466,7 @@ func_mode_link () # Go through the arguments, transforming them on the way. while test "$#" -gt 0; do - arg="$1" + arg=$1 shift func_quote_for_eval "$arg" qarg=$func_quote_for_eval_unquoted_result @@ -5227,21 +6483,21 @@ func_mode_link () case $prev in bindir) - bindir="$arg" + bindir=$arg prev= continue ;; dlfiles|dlprefiles) - if test "$preload" = no; then + $preload || { # Add the symbol object into the linking commands. func_append compile_command " @SYMFILE@" func_append finalize_command " @SYMFILE@" - preload=yes - fi + preload=: + } case $arg in *.la | *.lo) ;; # We handle these cases below. force) - if test "$dlself" = no; then + if test no = "$dlself"; then dlself=needless export_dynamic=yes fi @@ -5249,9 +6505,9 @@ func_mode_link () continue ;; self) - if test "$prev" = dlprefiles; then + if test dlprefiles = "$prev"; then dlself=yes - elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then + elif test dlfiles = "$prev" && test yes != "$dlopen_self"; then dlself=yes else dlself=needless @@ -5261,7 +6517,7 @@ func_mode_link () continue ;; *) - if test "$prev" = dlfiles; then + if test dlfiles = "$prev"; then func_append dlfiles " $arg" else func_append dlprefiles " $arg" @@ -5272,14 +6528,14 @@ func_mode_link () esac ;; expsyms) - export_symbols="$arg" + export_symbols=$arg test -f "$arg" \ - || func_fatal_error "symbol file \`$arg' does not exist" + || func_fatal_error "symbol file '$arg' does not exist" prev= continue ;; expsyms_regex) - export_symbols_regex="$arg" + export_symbols_regex=$arg prev= continue ;; @@ -5297,7 +6553,13 @@ func_mode_link () continue ;; inst_prefix) - inst_prefix_dir="$arg" + inst_prefix_dir=$arg + prev= + continue + ;; + mllvm) + # Clang does not use LLVM to link, so we can simply discard any + # '-mllvm $arg' options when doing the link step. prev= continue ;; @@ -5321,21 +6583,21 @@ func_mode_link () if test -z "$pic_object" || test -z "$non_pic_object" || - test "$pic_object" = none && - test "$non_pic_object" = none; then - func_fatal_error "cannot find name of object for \`$arg'" + test none = "$pic_object" && + test none = "$non_pic_object"; then + func_fatal_error "cannot find name of object for '$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" - xdir="$func_dirname_result" + xdir=$func_dirname_result - if test "$pic_object" != none; then + if test none != "$pic_object"; then # Prepend the subdirectory the object is found in. - pic_object="$xdir$pic_object" + pic_object=$xdir$pic_object - if test "$prev" = dlfiles; then - if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + if test dlfiles = "$prev"; then + if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then func_append dlfiles " $pic_object" prev= continue @@ -5346,7 +6608,7 @@ func_mode_link () fi # CHECK ME: I think I busted this. -Ossama - if test "$prev" = dlprefiles; then + if test dlprefiles = "$prev"; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= @@ -5354,23 +6616,23 @@ func_mode_link () # A PIC object. func_append libobjs " $pic_object" - arg="$pic_object" + arg=$pic_object fi # Non-PIC object. - if test "$non_pic_object" != none; then + if test none != "$non_pic_object"; then # Prepend the subdirectory the object is found in. - non_pic_object="$xdir$non_pic_object" + non_pic_object=$xdir$non_pic_object # A standard non-PIC object func_append non_pic_objects " $non_pic_object" - if test -z "$pic_object" || test "$pic_object" = none ; then - arg="$non_pic_object" + if test -z "$pic_object" || test none = "$pic_object"; then + arg=$non_pic_object fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. - non_pic_object="$pic_object" + non_pic_object=$pic_object func_append non_pic_objects " $non_pic_object" fi else @@ -5378,7 +6640,7 @@ func_mode_link () if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" - xdir="$func_dirname_result" + xdir=$func_dirname_result func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result @@ -5386,24 +6648,24 @@ func_mode_link () func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else - func_fatal_error "\`$arg' is not a valid libtool object" + func_fatal_error "'$arg' is not a valid libtool object" fi fi done else - func_fatal_error "link input file \`$arg' does not exist" + func_fatal_error "link input file '$arg' does not exist" fi arg=$save_arg prev= continue ;; precious_regex) - precious_files_regex="$arg" + precious_files_regex=$arg prev= continue ;; release) - release="-$arg" + release=-$arg prev= continue ;; @@ -5415,7 +6677,7 @@ func_mode_link () func_fatal_error "only absolute run-paths are allowed" ;; esac - if test "$prev" = rpath; then + if test rpath = "$prev"; then case "$rpath " in *" $arg "*) ;; *) func_append rpath " $arg" ;; @@ -5430,7 +6692,7 @@ func_mode_link () continue ;; shrext) - shrext_cmds="$arg" + shrext_cmds=$arg prev= continue ;; @@ -5470,7 +6732,7 @@ func_mode_link () esac fi # test -n "$prev" - prevarg="$arg" + prevarg=$arg case $arg in -all-static) @@ -5484,7 +6746,7 @@ func_mode_link () -allow-undefined) # FIXME: remove this flag sometime in the future. - func_fatal_error "\`-allow-undefined' must not be used because it is the default" + func_fatal_error "'-allow-undefined' must not be used because it is the default" ;; -avoid-version) @@ -5516,7 +6778,7 @@ func_mode_link () if test -n "$export_symbols" || test -n "$export_symbols_regex"; then func_fatal_error "more than one -exported-symbols argument is not allowed" fi - if test "X$arg" = "X-export-symbols"; then + if test X-export-symbols = "X$arg"; then prev=expsyms else prev=expsyms_regex @@ -5550,9 +6812,9 @@ func_mode_link () func_stripname "-L" '' "$arg" if test -z "$func_stripname_result"; then if test "$#" -gt 0; then - func_fatal_error "require no space between \`-L' and \`$1'" + func_fatal_error "require no space between '-L' and '$1'" else - func_fatal_error "need path for \`-L' option" + func_fatal_error "need path for '-L' option" fi fi func_resolve_sysroot "$func_stripname_result" @@ -5563,8 +6825,8 @@ func_mode_link () *) absdir=`cd "$dir" && pwd` test -z "$absdir" && \ - func_fatal_error "cannot determine absolute directory name of \`$dir'" - dir="$absdir" + func_fatal_error "cannot determine absolute directory name of '$dir'" + dir=$absdir ;; esac case "$deplibs " in @@ -5599,7 +6861,7 @@ func_mode_link () ;; -l*) - if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then + if test X-lc = "X$arg" || test X-lm = "X$arg"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) # These systems don't actually have a C or math library (as such) @@ -5607,11 +6869,11 @@ func_mode_link () ;; *-*-os2*) # These systems don't actually have a C library (as such) - test "X$arg" = "X-lc" && continue + test X-lc = "X$arg" && continue ;; - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) # Do not include libc due to us having libc/libc_r. - test "X$arg" = "X-lc" && continue + test X-lc = "X$arg" && continue ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C and math libraries are in the System framework @@ -5620,16 +6882,16 @@ func_mode_link () ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype - test "X$arg" = "X-lc" && continue + test X-lc = "X$arg" && continue ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work - test "X$arg" = "X-lc" && continue + test X-lc = "X$arg" && continue ;; esac - elif test "X$arg" = "X-lc_r"; then + elif test X-lc_r = "X$arg"; then case $host in - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) # Do not include libc_r directly, use -pthread flag. continue ;; @@ -5639,6 +6901,11 @@ func_mode_link () continue ;; + -mllvm) + prev=mllvm + continue + ;; + -module) module=yes continue @@ -5668,7 +6935,7 @@ func_mode_link () ;; -multi_module) - single_module="${wl}-multi_module" + single_module=$wl-multi_module continue ;; @@ -5682,8 +6949,8 @@ func_mode_link () *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) # The PATH hackery in wrapper scripts is required on Windows # and Darwin in order for the loader to find any dlls it needs. - func_warning "\`-no-install' is ignored for $host" - func_warning "assuming \`-no-fast-install' instead" + func_warning "'-no-install' is ignored for $host" + func_warning "assuming '-no-fast-install' instead" fast_install=no ;; *) no_install=yes ;; @@ -5788,14 +7055,14 @@ func_mode_link () func_stripname '-Wc,' '' "$arg" args=$func_stripname_result arg= - save_ifs="$IFS"; IFS=',' + save_ifs=$IFS; IFS=, for flag in $args; do - IFS="$save_ifs" + IFS=$save_ifs func_quote_for_eval "$flag" func_append arg " $func_quote_for_eval_result" func_append compiler_flags " $func_quote_for_eval_result" done - IFS="$save_ifs" + IFS=$save_ifs func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; @@ -5804,15 +7071,15 @@ func_mode_link () func_stripname '-Wl,' '' "$arg" args=$func_stripname_result arg= - save_ifs="$IFS"; IFS=',' + save_ifs=$IFS; IFS=, for flag in $args; do - IFS="$save_ifs" + IFS=$save_ifs func_quote_for_eval "$flag" func_append arg " $wl$func_quote_for_eval_result" func_append compiler_flags " $wl$func_quote_for_eval_result" func_append linker_flags " $func_quote_for_eval_result" done - IFS="$save_ifs" + IFS=$save_ifs func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; @@ -5835,7 +7102,7 @@ func_mode_link () # -msg_* for osf cc -msg_*) func_quote_for_eval "$arg" - arg="$func_quote_for_eval_result" + arg=$func_quote_for_eval_result ;; # Flags to be passed through unchanged, with rationale: @@ -5850,12 +7117,13 @@ func_mode_link () # @file GCC response files # -tp=* Portland pgcc target processor selection # --sysroot=* for sysroot support - # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization + # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization + # -stdlib=* select c++ std lib with clang -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ - -O*|-flto*|-fwhopr*|-fuse-linker-plugin) + -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-stdlib=*) func_quote_for_eval "$arg" - arg="$func_quote_for_eval_result" + arg=$func_quote_for_eval_result func_append compile_command " $arg" func_append finalize_command " $arg" func_append compiler_flags " $arg" @@ -5865,7 +7133,7 @@ func_mode_link () # Some other compiler flag. -* | +*) func_quote_for_eval "$arg" - arg="$func_quote_for_eval_result" + arg=$func_quote_for_eval_result ;; *.$objext) @@ -5886,21 +7154,21 @@ func_mode_link () if test -z "$pic_object" || test -z "$non_pic_object" || - test "$pic_object" = none && - test "$non_pic_object" = none; then - func_fatal_error "cannot find name of object for \`$arg'" + test none = "$pic_object" && + test none = "$non_pic_object"; then + func_fatal_error "cannot find name of object for '$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" - xdir="$func_dirname_result" + xdir=$func_dirname_result - if test "$pic_object" != none; then + test none = "$pic_object" || { # Prepend the subdirectory the object is found in. - pic_object="$xdir$pic_object" + pic_object=$xdir$pic_object - if test "$prev" = dlfiles; then - if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + if test dlfiles = "$prev"; then + if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then func_append dlfiles " $pic_object" prev= continue @@ -5911,7 +7179,7 @@ func_mode_link () fi # CHECK ME: I think I busted this. -Ossama - if test "$prev" = dlprefiles; then + if test dlprefiles = "$prev"; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= @@ -5919,23 +7187,23 @@ func_mode_link () # A PIC object. func_append libobjs " $pic_object" - arg="$pic_object" - fi + arg=$pic_object + } # Non-PIC object. - if test "$non_pic_object" != none; then + if test none != "$non_pic_object"; then # Prepend the subdirectory the object is found in. - non_pic_object="$xdir$non_pic_object" + non_pic_object=$xdir$non_pic_object # A standard non-PIC object func_append non_pic_objects " $non_pic_object" - if test -z "$pic_object" || test "$pic_object" = none ; then - arg="$non_pic_object" + if test -z "$pic_object" || test none = "$pic_object"; then + arg=$non_pic_object fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. - non_pic_object="$pic_object" + non_pic_object=$pic_object func_append non_pic_objects " $non_pic_object" fi else @@ -5943,7 +7211,7 @@ func_mode_link () if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" - xdir="$func_dirname_result" + xdir=$func_dirname_result func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result @@ -5951,7 +7219,7 @@ func_mode_link () func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else - func_fatal_error "\`$arg' is not a valid libtool object" + func_fatal_error "'$arg' is not a valid libtool object" fi fi ;; @@ -5967,11 +7235,11 @@ func_mode_link () # A libtool-controlled library. func_resolve_sysroot "$arg" - if test "$prev" = dlfiles; then + if test dlfiles = "$prev"; then # This library was specified with -dlopen. func_append dlfiles " $func_resolve_sysroot_result" prev= - elif test "$prev" = dlprefiles; then + elif test dlprefiles = "$prev"; then # The library was specified with -dlpreopen. func_append dlprefiles " $func_resolve_sysroot_result" prev= @@ -5986,7 +7254,7 @@ func_mode_link () # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. func_quote_for_eval "$arg" - arg="$func_quote_for_eval_result" + arg=$func_quote_for_eval_result ;; esac # arg @@ -5998,9 +7266,9 @@ func_mode_link () done # argument parsing loop test -n "$prev" && \ - func_fatal_help "the \`$prevarg' option requires an argument" + func_fatal_help "the '$prevarg' option requires an argument" - if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then + if test yes = "$export_dynamic" && test -n "$export_dynamic_flag_spec"; then eval arg=\"$export_dynamic_flag_spec\" func_append compile_command " $arg" func_append finalize_command " $arg" @@ -6009,12 +7277,12 @@ func_mode_link () oldlibs= # calculate the name of the file, without its directory func_basename "$output" - outputname="$func_basename_result" - libobjs_save="$libobjs" + outputname=$func_basename_result + libobjs_save=$libobjs if test -n "$shlibpath_var"; then # get the directories listed in $shlibpath_var - eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\` + eval shlib_search_path=\`\$ECHO \"\$$shlibpath_var\" \| \$SED \'s/:/ /g\'\` else shlib_search_path= fi @@ -6022,7 +7290,7 @@ func_mode_link () eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" func_dirname "$output" "/" "" - output_objdir="$func_dirname_result$objdir" + output_objdir=$func_dirname_result$objdir func_to_tool_file "$output_objdir/" tool_output_objdir=$func_to_tool_file_result # Create the object directory. @@ -6045,7 +7313,7 @@ func_mode_link () # Find all interdependent deplibs by searching for libraries # that are linked more than once (e.g. -la -lb -la) for deplib in $deplibs; do - if $opt_preserve_dup_deps ; then + if $opt_preserve_dup_deps; then case "$libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac @@ -6053,7 +7321,7 @@ func_mode_link () func_append libs " $deplib" done - if test "$linkmode" = lib; then + if test lib = "$linkmode"; then libs="$predeps $libs $compiler_lib_search_path $postdeps" # Compute libraries that are listed more than once in $predeps @@ -6085,7 +7353,7 @@ func_mode_link () case $file in *.la) ;; *) - func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" + func_fatal_help "libraries can '-dlopen' only libtool libraries: $file" ;; esac done @@ -6093,7 +7361,7 @@ func_mode_link () prog) compile_deplibs= finalize_deplibs= - alldeplibs=no + alldeplibs=false newdlfiles= newdlprefiles= passes="conv scan dlopen dlpreopen link" @@ -6105,29 +7373,29 @@ func_mode_link () for pass in $passes; do # The preopen pass in lib mode reverses $deplibs; put it back here # so that -L comes before libs that need it for instance... - if test "$linkmode,$pass" = "lib,link"; then + if test lib,link = "$linkmode,$pass"; then ## FIXME: Find the place where the list is rebuilt in the wrong ## order, and fix it there properly tmp_deplibs= for deplib in $deplibs; do tmp_deplibs="$deplib $tmp_deplibs" done - deplibs="$tmp_deplibs" + deplibs=$tmp_deplibs fi - if test "$linkmode,$pass" = "lib,link" || - test "$linkmode,$pass" = "prog,scan"; then - libs="$deplibs" + if test lib,link = "$linkmode,$pass" || + test prog,scan = "$linkmode,$pass"; then + libs=$deplibs deplibs= fi - if test "$linkmode" = prog; then + if test prog = "$linkmode"; then case $pass in - dlopen) libs="$dlfiles" ;; - dlpreopen) libs="$dlprefiles" ;; + dlopen) libs=$dlfiles ;; + dlpreopen) libs=$dlprefiles ;; link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; esac fi - if test "$linkmode,$pass" = "lib,dlpreopen"; then + if test lib,dlpreopen = "$linkmode,$pass"; then # Collect and forward deplibs of preopened libtool libs for lib in $dlprefiles; do # Ignore non-libtool-libs @@ -6148,26 +7416,26 @@ func_mode_link () esac done done - libs="$dlprefiles" + libs=$dlprefiles fi - if test "$pass" = dlopen; then + if test dlopen = "$pass"; then # Collect dlpreopened libraries - save_deplibs="$deplibs" + save_deplibs=$deplibs deplibs= fi for deplib in $libs; do lib= - found=no + found=false case $deplib in -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) - if test "$linkmode,$pass" = "prog,link"; then + if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append compiler_flags " $deplib" - if test "$linkmode" = lib ; then + if test lib = "$linkmode"; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; @@ -6177,13 +7445,13 @@ func_mode_link () continue ;; -l*) - if test "$linkmode" != lib && test "$linkmode" != prog; then - func_warning "\`-l' is ignored for archives/objects" + if test lib != "$linkmode" && test prog != "$linkmode"; then + func_warning "'-l' is ignored for archives/objects" continue fi func_stripname '-l' '' "$deplib" name=$func_stripname_result - if test "$linkmode" = lib; then + if test lib = "$linkmode"; then searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" else searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" @@ -6191,31 +7459,22 @@ func_mode_link () for searchdir in $searchdirs; do for search_ext in .la $std_shrext .so .a; do # Search the libtool library - lib="$searchdir/lib${name}${search_ext}" + lib=$searchdir/lib$name$search_ext if test -f "$lib"; then - if test "$search_ext" = ".la"; then - found=yes + if test .la = "$search_ext"; then + found=: else - found=no + found=false fi break 2 fi done done - if test "$found" != yes; then - # deplib doesn't seem to be a libtool library - if test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - deplibs="$deplib $deplibs" - test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" - fi - continue - else # deplib is a libtool library + if $found; then + # deplib is a libtool library # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, # We need to do some special things here, and not later. - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + if test yes = "$allow_libtool_libs_with_static_runtimes"; then case " $predeps $postdeps " in *" $deplib "*) if func_lalib_p "$lib"; then @@ -6223,19 +7482,19 @@ func_mode_link () old_library= func_source "$lib" for l in $old_library $library_names; do - ll="$l" + ll=$l done - if test "X$ll" = "X$old_library" ; then # only static version available - found=no + if test "X$ll" = "X$old_library"; then # only static version available + found=false func_dirname "$lib" "" "." - ladir="$func_dirname_result" + ladir=$func_dirname_result lib=$ladir/$old_library - if test "$linkmode,$pass" = "prog,link"; then + if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" - test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" fi continue fi @@ -6244,15 +7503,25 @@ func_mode_link () *) ;; esac fi + else + # deplib doesn't seem to be a libtool library + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" + fi + continue fi ;; # -l *.ltframework) - if test "$linkmode,$pass" = "prog,link"; then + if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" - if test "$linkmode" = lib ; then + if test lib = "$linkmode"; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; @@ -6265,18 +7534,18 @@ func_mode_link () case $linkmode in lib) deplibs="$deplib $deplibs" - test "$pass" = conv && continue + test conv = "$pass" && continue newdependency_libs="$deplib $newdependency_libs" func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; prog) - if test "$pass" = conv; then + if test conv = "$pass"; then deplibs="$deplib $deplibs" continue fi - if test "$pass" = scan; then + if test scan = "$pass"; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" @@ -6287,13 +7556,13 @@ func_mode_link () func_append newlib_search_path " $func_resolve_sysroot_result" ;; *) - func_warning "\`-L' is ignored for archives/objects" + func_warning "'-L' is ignored for archives/objects" ;; esac # linkmode continue ;; # -L -R*) - if test "$pass" = link; then + if test link = "$pass"; then func_stripname '-R' '' "$deplib" func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result @@ -6311,7 +7580,7 @@ func_mode_link () lib=$func_resolve_sysroot_result ;; *.$libext) - if test "$pass" = conv; then + if test conv = "$pass"; then deplibs="$deplib $deplibs" continue fi @@ -6322,21 +7591,26 @@ func_mode_link () case " $dlpreconveniencelibs " in *" $deplib "*) ;; *) - valid_a_lib=no + valid_a_lib=false case $deplibs_check_method in match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ | $EGREP "$match_pattern_regex" > /dev/null; then - valid_a_lib=yes + valid_a_lib=: fi ;; pass_all) - valid_a_lib=yes + valid_a_lib=: ;; esac - if test "$valid_a_lib" != yes; then + if $valid_a_lib; then + echo + $ECHO "*** Warning: Linking the shared library $output against the" + $ECHO "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + else echo $ECHO "*** Warning: Trying to link with static lib archive $deplib." echo "*** I have the capability to make that library automatically link in when" @@ -6344,18 +7618,13 @@ func_mode_link () echo "*** shared version of the library, which you do not appear to have" echo "*** because the file extensions .$libext of this argument makes me believe" echo "*** that it is just a static archive that I should not use here." - else - echo - $ECHO "*** Warning: Linking the shared library $output against the" - $ECHO "*** static library $deplib is not portable!" - deplibs="$deplib $deplibs" fi ;; esac continue ;; prog) - if test "$pass" != link; then + if test link != "$pass"; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" @@ -6366,10 +7635,10 @@ func_mode_link () esac # linkmode ;; # *.$libext *.lo | *.$objext) - if test "$pass" = conv; then + if test conv = "$pass"; then deplibs="$deplib $deplibs" - elif test "$linkmode" = prog; then - if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + elif test prog = "$linkmode"; then + if test dlpreopen = "$pass" || test yes != "$dlopen_support" || test no = "$build_libtool_libs"; then # If there is no dlopen support or we're linking statically, # we need to preload. func_append newdlprefiles " $deplib" @@ -6382,22 +7651,20 @@ func_mode_link () continue ;; %DEPLIBS%) - alldeplibs=yes + alldeplibs=: continue ;; esac # case $deplib - if test "$found" = yes || test -f "$lib"; then : - else - func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" - fi + $found || test -f "$lib" \ + || func_fatal_error "cannot find the library '$lib' or unhandled argument '$deplib'" # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$lib" \ - || func_fatal_error "\`$lib' is not a valid libtool archive" + || func_fatal_error "'$lib' is not a valid libtool archive" func_dirname "$lib" "" "." - ladir="$func_dirname_result" + ladir=$func_dirname_result dlname= dlopen= @@ -6427,30 +7694,30 @@ func_mode_link () done fi dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` - if test "$linkmode,$pass" = "lib,link" || - test "$linkmode,$pass" = "prog,scan" || - { test "$linkmode" != prog && test "$linkmode" != lib; }; then + if test lib,link = "$linkmode,$pass" || + test prog,scan = "$linkmode,$pass" || + { test prog != "$linkmode" && test lib != "$linkmode"; }; then test -n "$dlopen" && func_append dlfiles " $dlopen" test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" fi - if test "$pass" = conv; then + if test conv = "$pass"; then # Only check for convenience libraries deplibs="$lib $deplibs" if test -z "$libdir"; then if test -z "$old_library"; then - func_fatal_error "cannot find name of link library for \`$lib'" + func_fatal_error "cannot find name of link library for '$lib'" fi # It is a libtool convenience library, so add in its objects. func_append convenience " $ladir/$objdir/$old_library" func_append old_convenience " $ladir/$objdir/$old_library" - elif test "$linkmode" != prog && test "$linkmode" != lib; then - func_fatal_error "\`$lib' is not a convenience library" + elif test prog != "$linkmode" && test lib != "$linkmode"; then + func_fatal_error "'$lib' is not a convenience library" fi tmp_libs= for deplib in $dependency_libs; do deplibs="$deplib $deplibs" - if $opt_preserve_dup_deps ; then + if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac @@ -6464,26 +7731,26 @@ func_mode_link () # Get the name of the library we link against. linklib= if test -n "$old_library" && - { test "$prefer_static_libs" = yes || - test "$prefer_static_libs,$installed" = "built,no"; }; then + { test yes = "$prefer_static_libs" || + test built,no = "$prefer_static_libs,$installed"; }; then linklib=$old_library else for l in $old_library $library_names; do - linklib="$l" + linklib=$l done fi if test -z "$linklib"; then - func_fatal_error "cannot find name of link library for \`$lib'" + func_fatal_error "cannot find name of link library for '$lib'" fi # This library was specified with -dlopen. - if test "$pass" = dlopen; then - if test -z "$libdir"; then - func_fatal_error "cannot -dlopen a convenience library: \`$lib'" - fi + if test dlopen = "$pass"; then + test -z "$libdir" \ + && func_fatal_error "cannot -dlopen a convenience library: '$lib'" if test -z "$dlname" || - test "$dlopen_support" != yes || - test "$build_libtool_libs" = no; then + test yes != "$dlopen_support" || + test no = "$build_libtool_libs" + then # If there is no dlname, no dlopen support or we're linking # statically, we need to preload. We also need to preload any # dependent libraries so libltdl's deplib preloader doesn't @@ -6497,40 +7764,40 @@ func_mode_link () # We need an absolute path. case $ladir in - [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir=$ladir ;; *) abs_ladir=`cd "$ladir" && pwd` if test -z "$abs_ladir"; then - func_warning "cannot determine absolute directory name of \`$ladir'" + func_warning "cannot determine absolute directory name of '$ladir'" func_warning "passing it literally to the linker, although it might fail" - abs_ladir="$ladir" + abs_ladir=$ladir fi ;; esac func_basename "$lib" - laname="$func_basename_result" + laname=$func_basename_result # Find the relevant object directory and library name. - if test "X$installed" = Xyes; then + if test yes = "$installed"; then if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then - func_warning "library \`$lib' was moved." - dir="$ladir" - absdir="$abs_ladir" - libdir="$abs_ladir" + func_warning "library '$lib' was moved." + dir=$ladir + absdir=$abs_ladir + libdir=$abs_ladir else - dir="$lt_sysroot$libdir" - absdir="$lt_sysroot$libdir" + dir=$lt_sysroot$libdir + absdir=$lt_sysroot$libdir fi - test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes + test yes = "$hardcode_automatic" && avoidtemprpath=yes else if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then - dir="$ladir" - absdir="$abs_ladir" + dir=$ladir + absdir=$abs_ladir # Remove this search path later func_append notinst_path " $abs_ladir" else - dir="$ladir/$objdir" - absdir="$abs_ladir/$objdir" + dir=$ladir/$objdir + absdir=$abs_ladir/$objdir # Remove this search path later func_append notinst_path " $abs_ladir" fi @@ -6539,11 +7806,11 @@ func_mode_link () name=$func_stripname_result # This library was specified with -dlpreopen. - if test "$pass" = dlpreopen; then - if test -z "$libdir" && test "$linkmode" = prog; then - func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" + if test dlpreopen = "$pass"; then + if test -z "$libdir" && test prog = "$linkmode"; then + func_fatal_error "only libraries may -dlpreopen a convenience library: '$lib'" fi - case "$host" in + case $host in # special handling for platforms with PE-DLLs. *cygwin* | *mingw* | *cegcc* ) # Linker will automatically link against shared library if both @@ -6587,9 +7854,9 @@ func_mode_link () if test -z "$libdir"; then # Link the convenience library - if test "$linkmode" = lib; then + if test lib = "$linkmode"; then deplibs="$dir/$old_library $deplibs" - elif test "$linkmode,$pass" = "prog,link"; then + elif test prog,link = "$linkmode,$pass"; then compile_deplibs="$dir/$old_library $compile_deplibs" finalize_deplibs="$dir/$old_library $finalize_deplibs" else @@ -6599,14 +7866,14 @@ func_mode_link () fi - if test "$linkmode" = prog && test "$pass" != link; then + if test prog = "$linkmode" && test link != "$pass"; then func_append newlib_search_path " $ladir" deplibs="$lib $deplibs" - linkalldeplibs=no - if test "$link_all_deplibs" != no || test -z "$library_names" || - test "$build_libtool_libs" = no; then - linkalldeplibs=yes + linkalldeplibs=false + if test no != "$link_all_deplibs" || test -z "$library_names" || + test no = "$build_libtool_libs"; then + linkalldeplibs=: fi tmp_libs= @@ -6618,14 +7885,14 @@ func_mode_link () ;; esac # Need to link against all dependency_libs? - if test "$linkalldeplibs" = yes; then + if $linkalldeplibs; then deplibs="$deplib $deplibs" else # Need to hardcode shared library paths # or/and link against static libraries newdependency_libs="$deplib $newdependency_libs" fi - if $opt_preserve_dup_deps ; then + if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac @@ -6635,15 +7902,15 @@ func_mode_link () continue fi # $linkmode = prog... - if test "$linkmode,$pass" = "prog,link"; then + if test prog,link = "$linkmode,$pass"; then if test -n "$library_names" && - { { test "$prefer_static_libs" = no || - test "$prefer_static_libs,$installed" = "built,yes"; } || + { { test no = "$prefer_static_libs" || + test built,yes = "$prefer_static_libs,$installed"; } || test -z "$old_library"; }; then # We need to hardcode the library path - if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then + if test -n "$shlibpath_var" && test -z "$avoidtemprpath"; then # Make sure the rpath contains only unique directories. - case "$temp_rpath:" in + case $temp_rpath: in *"$absdir:"*) ;; *) func_append temp_rpath "$absdir:" ;; esac @@ -6672,9 +7939,9 @@ func_mode_link () esac fi # $linkmode,$pass = prog,link... - if test "$alldeplibs" = yes && - { test "$deplibs_check_method" = pass_all || - { test "$build_libtool_libs" = yes && + if $alldeplibs && + { test pass_all = "$deplibs_check_method" || + { test yes = "$build_libtool_libs" && test -n "$library_names"; }; }; then # We only need to search for static libraries continue @@ -6683,11 +7950,11 @@ func_mode_link () link_static=no # Whether the deplib will be linked statically use_static_libs=$prefer_static_libs - if test "$use_static_libs" = built && test "$installed" = yes; then + if test built = "$use_static_libs" && test yes = "$installed"; then use_static_libs=no fi if test -n "$library_names" && - { test "$use_static_libs" = no || test -z "$old_library"; }; then + { test no = "$use_static_libs" || test -z "$old_library"; }; then case $host in *cygwin* | *mingw* | *cegcc*) # No point in relinking DLLs because paths are not encoded @@ -6695,7 +7962,7 @@ func_mode_link () need_relink=no ;; *) - if test "$installed" = no; then + if test no = "$installed"; then func_append notinst_deplibs " $lib" need_relink=yes fi @@ -6705,24 +7972,24 @@ func_mode_link () # Warn about portability, can't link against -module's on some # systems (darwin). Don't bleat about dlopened modules though! - dlopenmodule="" + dlopenmodule= for dlpremoduletest in $dlprefiles; do if test "X$dlpremoduletest" = "X$lib"; then - dlopenmodule="$dlpremoduletest" + dlopenmodule=$dlpremoduletest break fi done - if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then + if test -z "$dlopenmodule" && test yes = "$shouldnotlink" && test link = "$pass"; then echo - if test "$linkmode" = prog; then + if test prog = "$linkmode"; then $ECHO "*** Warning: Linking the executable $output against the loadable module" else $ECHO "*** Warning: Linking the shared library $output against the loadable module" fi $ECHO "*** $linklib is not portable!" fi - if test "$linkmode" = lib && - test "$hardcode_into_libs" = yes; then + if test lib = "$linkmode" && + test yes = "$hardcode_into_libs"; then # Hardcode the library path. # Skip directories that are in the system default run-time # search path. @@ -6750,43 +8017,43 @@ func_mode_link () # figure out the soname set dummy $library_names shift - realname="$1" + realname=$1 shift libname=`eval "\\$ECHO \"$libname_spec\""` # use dlname if we got it. it's perfectly good, no? if test -n "$dlname"; then - soname="$dlname" + soname=$dlname elif test -n "$soname_spec"; then # bleh windows case $host in *cygwin* | mingw* | *cegcc*) func_arith $current - $age major=$func_arith_result - versuffix="-$major" + versuffix=-$major ;; esac eval soname=\"$soname_spec\" else - soname="$realname" + soname=$realname fi # Make a new name for the extract_expsyms_cmds to use - soroot="$soname" + soroot=$soname func_basename "$soroot" - soname="$func_basename_result" + soname=$func_basename_result func_stripname 'lib' '.dll' "$soname" newlib=libimp-$func_stripname_result.a # If the library has no export list, then create one now if test -f "$output_objdir/$soname-def"; then : else - func_verbose "extracting exported symbol list from \`$soname'" + func_verbose "extracting exported symbol list from '$soname'" func_execute_cmds "$extract_expsyms_cmds" 'exit $?' fi # Create $newlib if test -f "$output_objdir/$newlib"; then :; else - func_verbose "generating import library for \`$soname'" + func_verbose "generating import library for '$soname'" func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' fi # make sure the library variables are pointing to the new library @@ -6794,58 +8061,58 @@ func_mode_link () linklib=$newlib fi # test -n "$old_archive_from_expsyms_cmds" - if test "$linkmode" = prog || test "$opt_mode" != relink; then + if test prog = "$linkmode" || test relink != "$opt_mode"; then add_shlibpath= add_dir= add= lib_linked=yes case $hardcode_action in immediate | unsupported) - if test "$hardcode_direct" = no; then - add="$dir/$linklib" + if test no = "$hardcode_direct"; then + add=$dir/$linklib case $host in - *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; - *-*-sysv4*uw2*) add_dir="-L$dir" ;; + *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;; + *-*-sysv4*uw2*) add_dir=-L$dir ;; *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ - *-*-unixware7*) add_dir="-L$dir" ;; + *-*-unixware7*) add_dir=-L$dir ;; *-*-darwin* ) - # if the lib is a (non-dlopened) module then we can not + # if the lib is a (non-dlopened) module then we cannot # link against it, someone is ignoring the earlier warnings if /usr/bin/file -L $add 2> /dev/null | - $GREP ": [^:]* bundle" >/dev/null ; then + $GREP ": [^:]* bundle" >/dev/null; then if test "X$dlopenmodule" != "X$lib"; then $ECHO "*** Warning: lib $linklib is a module, not a shared library" - if test -z "$old_library" ; then + if test -z "$old_library"; then echo echo "*** And there doesn't seem to be a static archive available" echo "*** The link will probably fail, sorry" else - add="$dir/$old_library" + add=$dir/$old_library fi elif test -n "$old_library"; then - add="$dir/$old_library" + add=$dir/$old_library fi fi esac - elif test "$hardcode_minus_L" = no; then + elif test no = "$hardcode_minus_L"; then case $host in - *-*-sunos*) add_shlibpath="$dir" ;; + *-*-sunos*) add_shlibpath=$dir ;; esac - add_dir="-L$dir" - add="-l$name" - elif test "$hardcode_shlibpath_var" = no; then - add_shlibpath="$dir" - add="-l$name" + add_dir=-L$dir + add=-l$name + elif test no = "$hardcode_shlibpath_var"; then + add_shlibpath=$dir + add=-l$name else lib_linked=no fi ;; relink) - if test "$hardcode_direct" = yes && - test "$hardcode_direct_absolute" = no; then - add="$dir/$linklib" - elif test "$hardcode_minus_L" = yes; then - add_dir="-L$absdir" + if test yes = "$hardcode_direct" && + test no = "$hardcode_direct_absolute"; then + add=$dir/$linklib + elif test yes = "$hardcode_minus_L"; then + add_dir=-L$absdir # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in @@ -6854,10 +8121,10 @@ func_mode_link () ;; esac fi - add="-l$name" - elif test "$hardcode_shlibpath_var" = yes; then - add_shlibpath="$dir" - add="-l$name" + add=-l$name + elif test yes = "$hardcode_shlibpath_var"; then + add_shlibpath=$dir + add=-l$name else lib_linked=no fi @@ -6865,7 +8132,7 @@ func_mode_link () *) lib_linked=no ;; esac - if test "$lib_linked" != yes; then + if test yes != "$lib_linked"; then func_fatal_configuration "unsupported hardcode properties" fi @@ -6875,15 +8142,15 @@ func_mode_link () *) func_append compile_shlibpath "$add_shlibpath:" ;; esac fi - if test "$linkmode" = prog; then + if test prog = "$linkmode"; then test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" test -n "$add" && compile_deplibs="$add $compile_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" - if test "$hardcode_direct" != yes && - test "$hardcode_minus_L" != yes && - test "$hardcode_shlibpath_var" = yes; then + if test yes != "$hardcode_direct" && + test yes != "$hardcode_minus_L" && + test yes = "$hardcode_shlibpath_var"; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; @@ -6892,33 +8159,33 @@ func_mode_link () fi fi - if test "$linkmode" = prog || test "$opt_mode" = relink; then + if test prog = "$linkmode" || test relink = "$opt_mode"; then add_shlibpath= add_dir= add= # Finalize command for both is simple: just hardcode it. - if test "$hardcode_direct" = yes && - test "$hardcode_direct_absolute" = no; then - add="$libdir/$linklib" - elif test "$hardcode_minus_L" = yes; then - add_dir="-L$libdir" - add="-l$name" - elif test "$hardcode_shlibpath_var" = yes; then + if test yes = "$hardcode_direct" && + test no = "$hardcode_direct_absolute"; then + add=$libdir/$linklib + elif test yes = "$hardcode_minus_L"; then + add_dir=-L$libdir + add=-l$name + elif test yes = "$hardcode_shlibpath_var"; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac - add="-l$name" - elif test "$hardcode_automatic" = yes; then + add=-l$name + elif test yes = "$hardcode_automatic"; then if test -n "$inst_prefix_dir" && - test -f "$inst_prefix_dir$libdir/$linklib" ; then - add="$inst_prefix_dir$libdir/$linklib" + test -f "$inst_prefix_dir$libdir/$linklib"; then + add=$inst_prefix_dir$libdir/$linklib else - add="$libdir/$linklib" + add=$libdir/$linklib fi else # We cannot seem to hardcode it, guess we'll fake it. - add_dir="-L$libdir" + add_dir=-L$libdir # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in @@ -6927,10 +8194,10 @@ func_mode_link () ;; esac fi - add="-l$name" + add=-l$name fi - if test "$linkmode" = prog; then + if test prog = "$linkmode"; then test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" test -n "$add" && finalize_deplibs="$add $finalize_deplibs" else @@ -6938,43 +8205,43 @@ func_mode_link () test -n "$add" && deplibs="$add $deplibs" fi fi - elif test "$linkmode" = prog; then + elif test prog = "$linkmode"; then # Here we assume that one of hardcode_direct or hardcode_minus_L # is not unsupported. This is valid on all known static and # shared platforms. - if test "$hardcode_direct" != unsupported; then - test -n "$old_library" && linklib="$old_library" + if test unsupported != "$hardcode_direct"; then + test -n "$old_library" && linklib=$old_library compile_deplibs="$dir/$linklib $compile_deplibs" finalize_deplibs="$dir/$linklib $finalize_deplibs" else compile_deplibs="-l$name -L$dir $compile_deplibs" finalize_deplibs="-l$name -L$dir $finalize_deplibs" fi - elif test "$build_libtool_libs" = yes; then + elif test yes = "$build_libtool_libs"; then # Not a shared library - if test "$deplibs_check_method" != pass_all; then + if test pass_all != "$deplibs_check_method"; then # We're trying link a shared library against a static one # but the system doesn't support it. # Just print a warning and add the library to dependency_libs so # that the program can be linked against the static library. echo - $ECHO "*** Warning: This system can not link to static lib archive $lib." + $ECHO "*** Warning: This system cannot link to static lib archive $lib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have." - if test "$module" = yes; then + if test yes = "$module"; then echo "*** But as you try to build a module library, libtool will still create " echo "*** a static module, that should work as long as the dlopening application" echo "*** is linked with the -dlopen flag to resolve symbols at runtime." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" - echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** lists from a program, using 'nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." - echo "*** \`nm' from GNU binutils and a full rebuild may help." + echo "*** 'nm' from GNU binutils and a full rebuild may help." fi - if test "$build_old_libs" = no; then + if test no = "$build_old_libs"; then build_libtool_libs=module build_old_libs=yes else @@ -6987,11 +8254,11 @@ func_mode_link () fi fi # link shared/static library? - if test "$linkmode" = lib; then + if test lib = "$linkmode"; then if test -n "$dependency_libs" && - { test "$hardcode_into_libs" != yes || - test "$build_old_libs" = yes || - test "$link_static" = yes; }; then + { test yes != "$hardcode_into_libs" || + test yes = "$build_old_libs" || + test yes = "$link_static"; }; then # Extract -R from dependency_libs temp_deplibs= for libdir in $dependency_libs; do @@ -7005,12 +8272,12 @@ func_mode_link () *) func_append temp_deplibs " $libdir";; esac done - dependency_libs="$temp_deplibs" + dependency_libs=$temp_deplibs fi func_append newlib_search_path " $absdir" # Link against this library - test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + test no = "$link_static" && newdependency_libs="$abs_ladir/$laname $newdependency_libs" # ... and its dependency_libs tmp_libs= for deplib in $dependency_libs; do @@ -7020,7 +8287,7 @@ func_mode_link () func_resolve_sysroot "$func_stripname_result";; *) func_resolve_sysroot "$deplib" ;; esac - if $opt_preserve_dup_deps ; then + if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $func_resolve_sysroot_result "*) func_append specialdeplibs " $func_resolve_sysroot_result" ;; @@ -7029,12 +8296,12 @@ func_mode_link () func_append tmp_libs " $func_resolve_sysroot_result" done - if test "$link_all_deplibs" != no; then + if test no != "$link_all_deplibs"; then # Add the search paths of all dependency libraries for deplib in $dependency_libs; do path= case $deplib in - -L*) path="$deplib" ;; + -L*) path=$deplib ;; *.la) func_resolve_sysroot "$deplib" deplib=$func_resolve_sysroot_result @@ -7042,12 +8309,12 @@ func_mode_link () dir=$func_dirname_result # We need an absolute path. case $dir in - [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; + [\\/]* | [A-Za-z]:[\\/]*) absdir=$dir ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then - func_warning "cannot determine absolute directory name of \`$dir'" - absdir="$dir" + func_warning "cannot determine absolute directory name of '$dir'" + absdir=$dir fi ;; esac @@ -7055,35 +8322,35 @@ func_mode_link () case $host in *-*-darwin*) depdepl= - eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` - if test -n "$deplibrary_names" ; then - for tmp in $deplibrary_names ; do + eval deplibrary_names=`$SED -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` + if test -n "$deplibrary_names"; then + for tmp in $deplibrary_names; do depdepl=$tmp done - if test -f "$absdir/$objdir/$depdepl" ; then - depdepl="$absdir/$objdir/$depdepl" - darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + if test -f "$absdir/$objdir/$depdepl"; then + depdepl=$absdir/$objdir/$depdepl + darwin_install_name=`$OTOOL -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` if test -z "$darwin_install_name"; then - darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + darwin_install_name=`$OTOOL64 -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` fi - func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" - func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}" + func_append compiler_flags " $wl-dylib_file $wl$darwin_install_name:$depdepl" + func_append linker_flags " -dylib_file $darwin_install_name:$depdepl" path= fi fi ;; *) - path="-L$absdir/$objdir" + path=-L$absdir/$objdir ;; esac else - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` test -z "$libdir" && \ - func_fatal_error "\`$deplib' is not a valid libtool archive" + func_fatal_error "'$deplib' is not a valid libtool archive" test "$absdir" != "$libdir" && \ - func_warning "\`$deplib' seems to be moved" + func_warning "'$deplib' seems to be moved" - path="-L$absdir" + path=-L$absdir fi ;; esac @@ -7095,23 +8362,23 @@ func_mode_link () fi # link_all_deplibs != no fi # linkmode = lib done # for deplib in $libs - if test "$pass" = link; then - if test "$linkmode" = "prog"; then + if test link = "$pass"; then + if test prog = "$linkmode"; then compile_deplibs="$new_inherited_linker_flags $compile_deplibs" finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" else compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` fi fi - dependency_libs="$newdependency_libs" - if test "$pass" = dlpreopen; then + dependency_libs=$newdependency_libs + if test dlpreopen = "$pass"; then # Link the dlpreopened libraries before other libraries for deplib in $save_deplibs; do deplibs="$deplib $deplibs" done fi - if test "$pass" != dlopen; then - if test "$pass" != conv; then + if test dlopen != "$pass"; then + test conv = "$pass" || { # Make sure lib_search_path contains only unique directories. lib_search_path= for dir in $newlib_search_path; do @@ -7121,12 +8388,12 @@ func_mode_link () esac done newlib_search_path= - fi + } - if test "$linkmode,$pass" != "prog,link"; then - vars="deplibs" - else + if test prog,link = "$linkmode,$pass"; then vars="compile_deplibs finalize_deplibs" + else + vars=deplibs fi for var in $vars dependency_libs; do # Add libraries to $var in reverse order @@ -7187,59 +8454,59 @@ func_mode_link () # Last step: remove runtime libs from dependency_libs # (they stay in deplibs) tmp_libs= - for i in $dependency_libs ; do + for i in $dependency_libs; do case " $predeps $postdeps $compiler_lib_search_path " in *" $i "*) - i="" + i= ;; esac - if test -n "$i" ; then + if test -n "$i"; then func_append tmp_libs " $i" fi done dependency_libs=$tmp_libs done # for pass - if test "$linkmode" = prog; then - dlfiles="$newdlfiles" + if test prog = "$linkmode"; then + dlfiles=$newdlfiles fi - if test "$linkmode" = prog || test "$linkmode" = lib; then - dlprefiles="$newdlprefiles" + if test prog = "$linkmode" || test lib = "$linkmode"; then + dlprefiles=$newdlprefiles fi case $linkmode in oldlib) - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - func_warning "\`-dlopen' is ignored for archives" + if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then + func_warning "'-dlopen' is ignored for archives" fi case " $deplibs" in *\ -l* | *\ -L*) - func_warning "\`-l' and \`-L' are ignored for archives" ;; + func_warning "'-l' and '-L' are ignored for archives" ;; esac test -n "$rpath" && \ - func_warning "\`-rpath' is ignored for archives" + func_warning "'-rpath' is ignored for archives" test -n "$xrpath" && \ - func_warning "\`-R' is ignored for archives" + func_warning "'-R' is ignored for archives" test -n "$vinfo" && \ - func_warning "\`-version-info/-version-number' is ignored for archives" + func_warning "'-version-info/-version-number' is ignored for archives" test -n "$release" && \ - func_warning "\`-release' is ignored for archives" + func_warning "'-release' is ignored for archives" test -n "$export_symbols$export_symbols_regex" && \ - func_warning "\`-export-symbols' is ignored for archives" + func_warning "'-export-symbols' is ignored for archives" # Now set the variables for building old libraries. build_libtool_libs=no - oldlibs="$output" + oldlibs=$output func_append objs "$old_deplibs" ;; lib) - # Make sure we only generate libraries of the form `libNAME.la'. + # Make sure we only generate libraries of the form 'libNAME.la'. case $outputname in lib*) func_stripname 'lib' '.la' "$outputname" @@ -7248,10 +8515,10 @@ func_mode_link () eval libname=\"$libname_spec\" ;; *) - test "$module" = no && \ - func_fatal_help "libtool library \`$output' must begin with \`lib'" + test no = "$module" \ + && func_fatal_help "libtool library '$output' must begin with 'lib'" - if test "$need_lib_prefix" != no; then + if test no != "$need_lib_prefix"; then # Add the "lib" prefix for modules if required func_stripname '' '.la' "$outputname" name=$func_stripname_result @@ -7265,8 +8532,8 @@ func_mode_link () esac if test -n "$objs"; then - if test "$deplibs_check_method" != pass_all; then - func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs" + if test pass_all != "$deplibs_check_method"; then + func_fatal_error "cannot build libtool library '$output' from non-libtool objects on this host:$objs" else echo $ECHO "*** Warning: Linking the shared library $output against the non-libtool" @@ -7275,21 +8542,21 @@ func_mode_link () fi fi - test "$dlself" != no && \ - func_warning "\`-dlopen self' is ignored for libtool libraries" + test no = "$dlself" \ + || func_warning "'-dlopen self' is ignored for libtool libraries" set dummy $rpath shift - test "$#" -gt 1 && \ - func_warning "ignoring multiple \`-rpath's for a libtool library" + test 1 -lt "$#" \ + && func_warning "ignoring multiple '-rpath's for a libtool library" - install_libdir="$1" + install_libdir=$1 oldlibs= if test -z "$rpath"; then - if test "$build_libtool_libs" = yes; then + if test yes = "$build_libtool_libs"; then # Building a libtool convenience library. - # Some compilers have problems with a `.al' extension so + # Some compilers have problems with a '.al' extension so # convenience libraries should have the same extension an # archive normally would. oldlibs="$output_objdir/$libname.$libext $oldlibs" @@ -7298,20 +8565,20 @@ func_mode_link () fi test -n "$vinfo" && \ - func_warning "\`-version-info/-version-number' is ignored for convenience libraries" + func_warning "'-version-info/-version-number' is ignored for convenience libraries" test -n "$release" && \ - func_warning "\`-release' is ignored for convenience libraries" + func_warning "'-release' is ignored for convenience libraries" else # Parse the version information argument. - save_ifs="$IFS"; IFS=':' + save_ifs=$IFS; IFS=: set dummy $vinfo 0 0 0 shift - IFS="$save_ifs" + IFS=$save_ifs test -n "$7" && \ - func_fatal_help "too many parameters to \`-version-info'" + func_fatal_help "too many parameters to '-version-info'" # convert absolute version numbers to libtool ages # this retains compatibility with .la files and attempts @@ -7319,42 +8586,42 @@ func_mode_link () case $vinfo_number in yes) - number_major="$1" - number_minor="$2" - number_revision="$3" + number_major=$1 + number_minor=$2 + number_revision=$3 # # There are really only two kinds -- those that # use the current revision as the major version # and those that subtract age and use age as # a minor version. But, then there is irix - # which has an extra 1 added just for fun + # that has an extra 1 added just for fun # case $version_type in # correct linux to gnu/linux during the next big refactor darwin|linux|osf|windows|none) func_arith $number_major + $number_minor current=$func_arith_result - age="$number_minor" - revision="$number_revision" + age=$number_minor + revision=$number_revision ;; freebsd-aout|freebsd-elf|qnx|sunos) - current="$number_major" - revision="$number_minor" - age="0" + current=$number_major + revision=$number_minor + age=0 ;; irix|nonstopux) func_arith $number_major + $number_minor current=$func_arith_result - age="$number_minor" - revision="$number_minor" + age=$number_minor + revision=$number_minor lt_irix_increment=no ;; esac ;; no) - current="$1" - revision="$2" - age="$3" + current=$1 + revision=$2 + age=$3 ;; esac @@ -7362,30 +8629,30 @@ func_mode_link () case $current in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) - func_error "CURRENT \`$current' must be a nonnegative integer" - func_fatal_error "\`$vinfo' is not valid version information" + func_error "CURRENT '$current' must be a nonnegative integer" + func_fatal_error "'$vinfo' is not valid version information" ;; esac case $revision in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) - func_error "REVISION \`$revision' must be a nonnegative integer" - func_fatal_error "\`$vinfo' is not valid version information" + func_error "REVISION '$revision' must be a nonnegative integer" + func_fatal_error "'$vinfo' is not valid version information" ;; esac case $age in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) - func_error "AGE \`$age' must be a nonnegative integer" - func_fatal_error "\`$vinfo' is not valid version information" + func_error "AGE '$age' must be a nonnegative integer" + func_fatal_error "'$vinfo' is not valid version information" ;; esac if test "$age" -gt "$current"; then - func_error "AGE \`$age' is greater than the current interface number \`$current'" - func_fatal_error "\`$vinfo' is not valid version information" + func_error "AGE '$age' is greater than the current interface number '$current'" + func_fatal_error "'$vinfo' is not valid version information" fi # Calculate the version variables. @@ -7400,26 +8667,35 @@ func_mode_link () # verstring for coding it into the library header func_arith $current - $age major=.$func_arith_result - versuffix="$major.$age.$revision" + versuffix=$major.$age.$revision # Darwin ld doesn't like 0 for these options... func_arith $current + 1 minor_current=$func_arith_result - xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" + xlcverstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + # On Darwin other compilers + case $CC in + nagfor*) + verstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" + ;; + *) + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + esac ;; freebsd-aout) - major=".$current" - versuffix=".$current.$revision"; + major=.$current + versuffix=.$current.$revision ;; freebsd-elf) - major=".$current" - versuffix=".$current" + major=.$current + versuffix=.$current ;; irix | nonstopux) - if test "X$lt_irix_increment" = "Xno"; then + if test no = "$lt_irix_increment"; then func_arith $current - $age else func_arith $current - $age + 1 @@ -7430,69 +8706,69 @@ func_mode_link () nonstopux) verstring_prefix=nonstopux ;; *) verstring_prefix=sgi ;; esac - verstring="$verstring_prefix$major.$revision" + verstring=$verstring_prefix$major.$revision # Add in all the interfaces that we are compatible with. loop=$revision - while test "$loop" -ne 0; do + while test 0 -ne "$loop"; do func_arith $revision - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result - verstring="$verstring_prefix$major.$iface:$verstring" + verstring=$verstring_prefix$major.$iface:$verstring done - # Before this point, $major must not contain `.'. + # Before this point, $major must not contain '.'. major=.$major - versuffix="$major.$revision" + versuffix=$major.$revision ;; linux) # correct to gnu/linux during the next big refactor func_arith $current - $age major=.$func_arith_result - versuffix="$major.$age.$revision" + versuffix=$major.$age.$revision ;; osf) func_arith $current - $age major=.$func_arith_result - versuffix=".$current.$age.$revision" - verstring="$current.$age.$revision" + versuffix=.$current.$age.$revision + verstring=$current.$age.$revision # Add in all the interfaces that we are compatible with. loop=$age - while test "$loop" -ne 0; do + while test 0 -ne "$loop"; do func_arith $current - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result - verstring="$verstring:${iface}.0" + verstring=$verstring:$iface.0 done # Make executables depend on our current version. - func_append verstring ":${current}.0" + func_append verstring ":$current.0" ;; qnx) - major=".$current" - versuffix=".$current" + major=.$current + versuffix=.$current ;; sunos) - major=".$current" - versuffix=".$current.$revision" + major=.$current + versuffix=.$current.$revision ;; windows) # Use '-' rather than '.', since we only want one - # extension on DOS 8.3 filesystems. + # extension on DOS 8.3 file systems. func_arith $current - $age major=$func_arith_result - versuffix="-$major" + versuffix=-$major ;; *) - func_fatal_configuration "unknown library version type \`$version_type'" + func_fatal_configuration "unknown library version type '$version_type'" ;; esac @@ -7506,42 +8782,45 @@ func_mode_link () verstring= ;; *) - verstring="0.0" + verstring=0.0 ;; esac - if test "$need_version" = no; then + if test no = "$need_version"; then versuffix= else - versuffix=".0.0" + versuffix=.0.0 fi fi # Remove version info from name if versioning should be avoided - if test "$avoid_version" = yes && test "$need_version" = no; then + if test yes,no = "$avoid_version,$need_version"; then major= versuffix= - verstring="" + verstring= fi # Check to see if the archive will have undefined symbols. - if test "$allow_undefined" = yes; then - if test "$allow_undefined_flag" = unsupported; then - func_warning "undefined symbols not allowed in $host shared libraries" - build_libtool_libs=no - build_old_libs=yes + if test yes = "$allow_undefined"; then + if test unsupported = "$allow_undefined_flag"; then + if test yes = "$build_old_libs"; then + func_warning "undefined symbols not allowed in $host shared libraries; building static only" + build_libtool_libs=no + else + func_fatal_error "can't build $host shared library unless -no-undefined is specified" + fi fi else # Don't allow undefined symbols. - allow_undefined_flag="$no_undefined_flag" + allow_undefined_flag=$no_undefined_flag fi fi - func_generate_dlsyms "$libname" "$libname" "yes" + func_generate_dlsyms "$libname" "$libname" : func_append libobjs " $symfileobj" - test "X$libobjs" = "X " && libobjs= + test " " = "$libobjs" && libobjs= - if test "$opt_mode" != relink; then + if test relink != "$opt_mode"; then # Remove our outputs, but don't remove object files since they # may have been created when compiling PIC objects. removelist= @@ -7550,8 +8829,8 @@ func_mode_link () case $p in *.$objext | *.gcno) ;; - $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) - if test "X$precious_files_regex" != "X"; then + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/$libname$release.*) + if test -n "$precious_files_regex"; then if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 then continue @@ -7567,11 +8846,11 @@ func_mode_link () fi # Now set the variables for building old libraries. - if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then + if test yes = "$build_old_libs" && test convenience != "$build_libtool_libs"; then func_append oldlibs " $output_objdir/$libname.$libext" # Transform .lo files to .o files. - oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP` + oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; $lo2o" | $NL2SP` fi # Eliminate all temporary directories. @@ -7592,13 +8871,13 @@ func_mode_link () *) func_append finalize_rpath " $libdir" ;; esac done - if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then + if test yes != "$hardcode_into_libs" || test yes = "$build_old_libs"; then dependency_libs="$temp_xrpath $dependency_libs" fi fi # Make sure dlfiles contains only unique files that won't be dlpreopened - old_dlfiles="$dlfiles" + old_dlfiles=$dlfiles dlfiles= for lib in $old_dlfiles; do case " $dlprefiles $dlfiles " in @@ -7608,7 +8887,7 @@ func_mode_link () done # Make sure dlprefiles contains only unique files - old_dlprefiles="$dlprefiles" + old_dlprefiles=$dlprefiles dlprefiles= for lib in $old_dlprefiles; do case "$dlprefiles " in @@ -7617,7 +8896,7 @@ func_mode_link () esac done - if test "$build_libtool_libs" = yes; then + if test yes = "$build_libtool_libs"; then if test -n "$rpath"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) @@ -7641,7 +8920,7 @@ func_mode_link () ;; *) # Add libc to deplibs on all other systems if necessary. - if test "$build_libtool_need_lc" = "yes"; then + if test yes = "$build_libtool_need_lc"; then func_append deplibs " -lc" fi ;; @@ -7657,9 +8936,9 @@ func_mode_link () # I'm not sure if I'm treating the release correctly. I think # release should show up in the -l (ie -lgmp5) so we don't want to # add it in twice. Is that correct? - release="" - versuffix="" - major="" + release= + versuffix= + major= newdeplibs= droppeddeps=no case $deplibs_check_method in @@ -7688,20 +8967,20 @@ EOF -l*) func_stripname -l '' "$i" name=$func_stripname_result - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + if test yes = "$allow_libtool_libs_with_static_runtimes"; then case " $predeps $postdeps " in *" $i "*) func_append newdeplibs " $i" - i="" + i= ;; esac fi - if test -n "$i" ; then + if test -n "$i"; then libname=`eval "\\$ECHO \"$libname_spec\""` deplib_matches=`eval "\\$ECHO \"$library_names_spec\""` set dummy $deplib_matches; shift deplib_match=$1 - if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then + if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0; then func_append newdeplibs " $i" else droppeddeps=yes @@ -7731,20 +9010,20 @@ EOF $opt_dry_run || $RM conftest if $LTCC $LTCFLAGS -o conftest conftest.c $i; then ldd_output=`ldd conftest` - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + if test yes = "$allow_libtool_libs_with_static_runtimes"; then case " $predeps $postdeps " in *" $i "*) func_append newdeplibs " $i" - i="" + i= ;; esac fi - if test -n "$i" ; then + if test -n "$i"; then libname=`eval "\\$ECHO \"$libname_spec\""` deplib_matches=`eval "\\$ECHO \"$library_names_spec\""` set dummy $deplib_matches; shift deplib_match=$1 - if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then + if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0; then func_append newdeplibs " $i" else droppeddeps=yes @@ -7781,24 +9060,24 @@ EOF -l*) func_stripname -l '' "$a_deplib" name=$func_stripname_result - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + if test yes = "$allow_libtool_libs_with_static_runtimes"; then case " $predeps $postdeps " in *" $a_deplib "*) func_append newdeplibs " $a_deplib" - a_deplib="" + a_deplib= ;; esac fi - if test -n "$a_deplib" ; then + if test -n "$a_deplib"; then libname=`eval "\\$ECHO \"$libname_spec\""` if test -n "$file_magic_glob"; then libnameglob=`func_echo_all "$libname" | $SED -e $file_magic_glob` else libnameglob=$libname fi - test "$want_nocaseglob" = yes && nocaseglob=`shopt -p nocaseglob` + test yes = "$want_nocaseglob" && nocaseglob=`shopt -p nocaseglob` for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do - if test "$want_nocaseglob" = yes; then + if test yes = "$want_nocaseglob"; then shopt -s nocaseglob potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` $nocaseglob @@ -7816,25 +9095,25 @@ EOF # We might still enter an endless loop, since a link # loop can be closed while we follow links, # but so what? - potlib="$potent_lib" + potlib=$potent_lib while test -h "$potlib" 2>/dev/null; do - potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` + potliblink=`ls -ld $potlib | $SED 's/.* -> //'` case $potliblink in - [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; - *) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";; + [\\/]* | [A-Za-z]:[\\/]*) potlib=$potliblink;; + *) potlib=`$ECHO "$potlib" | $SED 's|[^/]*$||'`"$potliblink";; esac done if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | $SED -e 10q | $EGREP "$file_magic_regex" > /dev/null; then func_append newdeplibs " $a_deplib" - a_deplib="" + a_deplib= break 2 fi done done fi - if test -n "$a_deplib" ; then + if test -n "$a_deplib"; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." @@ -7842,7 +9121,7 @@ EOF echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" - if test -z "$potlib" ; then + if test -z "$potlib"; then $ECHO "*** with $libname but no candidates were found. (...for file magic test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" @@ -7865,30 +9144,30 @@ EOF -l*) func_stripname -l '' "$a_deplib" name=$func_stripname_result - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + if test yes = "$allow_libtool_libs_with_static_runtimes"; then case " $predeps $postdeps " in *" $a_deplib "*) func_append newdeplibs " $a_deplib" - a_deplib="" + a_deplib= ;; esac fi - if test -n "$a_deplib" ; then + if test -n "$a_deplib"; then libname=`eval "\\$ECHO \"$libname_spec\""` for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do potential_libs=`ls $i/$libname[.-]* 2>/dev/null` for potent_lib in $potential_libs; do - potlib="$potent_lib" # see symlink-check above in file_magic test + potlib=$potent_lib # see symlink-check above in file_magic test if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ $EGREP "$match_pattern_regex" > /dev/null; then func_append newdeplibs " $a_deplib" - a_deplib="" + a_deplib= break 2 fi done done fi - if test -n "$a_deplib" ; then + if test -n "$a_deplib"; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." @@ -7896,7 +9175,7 @@ EOF echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" - if test -z "$potlib" ; then + if test -z "$potlib"; then $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" @@ -7912,18 +9191,18 @@ EOF done # Gone through all deplibs. ;; none | unknown | *) - newdeplibs="" + newdeplibs= tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then - for i in $predeps $postdeps ; do + if test yes = "$allow_libtool_libs_with_static_runtimes"; then + for i in $predeps $postdeps; do # can't use Xsed below, because $i might contain '/' - tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"` + tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s|$i||"` done fi case $tmp_deplibs in *[!\ \ ]*) echo - if test "X$deplibs_check_method" = "Xnone"; then + if test none = "$deplibs_check_method"; then echo "*** Warning: inter-library dependencies are not supported in this platform." else echo "*** Warning: inter-library dependencies are not known to be supported." @@ -7947,8 +9226,8 @@ EOF ;; esac - if test "$droppeddeps" = yes; then - if test "$module" = yes; then + if test yes = "$droppeddeps"; then + if test yes = "$module"; then echo echo "*** Warning: libtool could not satisfy all declared inter-library" $ECHO "*** dependencies of module $libname. Therefore, libtool will create" @@ -7957,12 +9236,12 @@ EOF if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" - echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** lists from a program, using 'nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." - echo "*** \`nm' from GNU binutils and a full rebuild may help." + echo "*** 'nm' from GNU binutils and a full rebuild may help." fi - if test "$build_old_libs" = no; then - oldlibs="$output_objdir/$libname.$libext" + if test no = "$build_old_libs"; then + oldlibs=$output_objdir/$libname.$libext build_libtool_libs=module build_old_libs=yes else @@ -7973,14 +9252,14 @@ EOF echo "*** automatically added whenever a program is linked with this library" echo "*** or is declared to -dlopen it." - if test "$allow_undefined" = no; then + if test no = "$allow_undefined"; then echo echo "*** Since this library must not contain undefined symbols," echo "*** because either the platform does not support them or" echo "*** it was explicitly requested with -no-undefined," echo "*** libtool will only create a static version of it." - if test "$build_old_libs" = no; then - oldlibs="$output_objdir/$libname.$libext" + if test no = "$build_old_libs"; then + oldlibs=$output_objdir/$libname.$libext build_libtool_libs=module build_old_libs=yes else @@ -8026,7 +9305,7 @@ EOF *) func_append new_libs " $deplib" ;; esac done - deplibs="$new_libs" + deplibs=$new_libs # All the library-specific variables (install_libdir is set above). library_names= @@ -8034,25 +9313,25 @@ EOF dlname= # Test again, we may have decided not to build it any more - if test "$build_libtool_libs" = yes; then - # Remove ${wl} instances when linking with ld. + if test yes = "$build_libtool_libs"; then + # Remove $wl instances when linking with ld. # FIXME: should test the right _cmds variable. case $archive_cmds in *\$LD\ *) wl= ;; esac - if test "$hardcode_into_libs" = yes; then + if test yes = "$hardcode_into_libs"; then # Hardcode the library paths hardcode_libdirs= dep_rpath= - rpath="$finalize_rpath" - test "$opt_mode" != relink && rpath="$compile_rpath$rpath" + rpath=$finalize_rpath + test relink = "$opt_mode" || rpath=$compile_rpath$rpath for libdir in $rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then func_replace_sysroot "$libdir" libdir=$func_replace_sysroot_result if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" + hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in @@ -8077,7 +9356,7 @@ EOF # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" + libdir=$hardcode_libdirs eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" fi if test -n "$runpath_var" && test -n "$perm_rpath"; then @@ -8091,8 +9370,8 @@ EOF test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" fi - shlibpath="$finalize_shlibpath" - test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath" + shlibpath=$finalize_shlibpath + test relink = "$opt_mode" || shlibpath=$compile_shlibpath$shlibpath if test -n "$shlibpath"; then eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" fi @@ -8102,19 +9381,19 @@ EOF eval library_names=\"$library_names_spec\" set dummy $library_names shift - realname="$1" + realname=$1 shift if test -n "$soname_spec"; then eval soname=\"$soname_spec\" else - soname="$realname" + soname=$realname fi if test -z "$dlname"; then dlname=$soname fi - lib="$output_objdir/$realname" + lib=$output_objdir/$realname linknames= for link do @@ -8128,7 +9407,7 @@ EOF delfiles= if test -n "$export_symbols" && test -n "$include_expsyms"; then $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" - export_symbols="$output_objdir/$libname.uexp" + export_symbols=$output_objdir/$libname.uexp func_append delfiles " $export_symbols" fi @@ -8137,31 +9416,31 @@ EOF cygwin* | mingw* | cegcc*) if test -n "$export_symbols" && test -z "$export_symbols_regex"; then # exporting using user supplied symfile - if test "x`$SED 1q $export_symbols`" != xEXPORTS; then + func_dll_def_p "$export_symbols" || { # and it's NOT already a .def file. Must figure out # which of the given symbols are data symbols and tag # them as such. So, trigger use of export_symbols_cmds. # export_symbols gets reassigned inside the "prepare # the list of exported symbols" if statement, so the # include_expsyms logic still works. - orig_export_symbols="$export_symbols" + orig_export_symbols=$export_symbols export_symbols= always_export_symbols=yes - fi + } fi ;; esac # Prepare the list of exported symbols if test -z "$export_symbols"; then - if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then - func_verbose "generating symbol list for \`$libname.la'" - export_symbols="$output_objdir/$libname.exp" + if test yes = "$always_export_symbols" || test -n "$export_symbols_regex"; then + func_verbose "generating symbol list for '$libname.la'" + export_symbols=$output_objdir/$libname.exp $opt_dry_run || $RM $export_symbols cmds=$export_symbols_cmds - save_ifs="$IFS"; IFS='~' + save_ifs=$IFS; IFS='~' for cmd1 in $cmds; do - IFS="$save_ifs" + IFS=$save_ifs # Take the normal branch if the nm_file_list_spec branch # doesn't work or if tool conversion is not needed. case $nm_file_list_spec~$to_tool_file_cmd in @@ -8175,7 +9454,7 @@ EOF try_normal_branch=no ;; esac - if test "$try_normal_branch" = yes \ + if test yes = "$try_normal_branch" \ && { test "$len" -lt "$max_cmd_len" \ || test "$max_cmd_len" -le -1; } then @@ -8186,7 +9465,7 @@ EOF output_la=$func_basename_result save_libobjs=$libobjs save_output=$output - output=${output_objdir}/${output_la}.nm + output=$output_objdir/$output_la.nm func_to_tool_file "$output" libobjs=$nm_file_list_spec$func_to_tool_file_result func_append delfiles " $output" @@ -8209,8 +9488,8 @@ EOF break fi done - IFS="$save_ifs" - if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then + IFS=$save_ifs + if test -n "$export_symbols_regex" && test : != "$skipped_export"; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi @@ -8218,16 +9497,16 @@ EOF fi if test -n "$export_symbols" && test -n "$include_expsyms"; then - tmp_export_symbols="$export_symbols" - test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" + tmp_export_symbols=$export_symbols + test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi - if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then + if test : != "$skipped_export" && test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. - func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" + func_verbose "filter symbol list for '$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of - # 's' commands which not all seds can handle. GNU sed should be fine + # 's' commands, which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. @@ -8246,11 +9525,11 @@ EOF ;; esac done - deplibs="$tmp_deplibs" + deplibs=$tmp_deplibs if test -n "$convenience"; then if test -n "$whole_archive_flag_spec" && - test "$compiler_needs_object" = yes && + test yes = "$compiler_needs_object" && test -z "$libobjs"; then # extract the archives, so we have objects to list. # TODO: could optimize this to just extract one archive. @@ -8261,7 +9540,7 @@ EOF eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= else - gentop="$output_objdir/${outputname}x" + gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $convenience @@ -8270,18 +9549,18 @@ EOF fi fi - if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then + if test yes = "$thread_safe" && test -n "$thread_safe_flag_spec"; then eval flag=\"$thread_safe_flag_spec\" func_append linker_flags " $flag" fi # Make a backup of the uninstalled library when relinking - if test "$opt_mode" = relink; then + if test relink = "$opt_mode"; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? fi # Do each of the archive commands. - if test "$module" = yes && test -n "$module_cmds" ; then + if test yes = "$module" && test -n "$module_cmds"; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then eval test_cmds=\"$module_expsym_cmds\" cmds=$module_expsym_cmds @@ -8299,7 +9578,7 @@ EOF fi fi - if test "X$skipped_export" != "X:" && + if test : != "$skipped_export" && func_len " $test_cmds" && len=$func_len_result && test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then @@ -8332,8 +9611,8 @@ EOF last_robj= k=1 - if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then - output=${output_objdir}/${output_la}.lnkscript + if test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then + output=$output_objdir/$output_la.lnkscript func_verbose "creating GNU ld script: $output" echo 'INPUT (' > $output for obj in $save_libobjs @@ -8345,14 +9624,14 @@ EOF func_append delfiles " $output" func_to_tool_file "$output" output=$func_to_tool_file_result - elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then - output=${output_objdir}/${output_la}.lnk + elif test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then + output=$output_objdir/$output_la.lnk func_verbose "creating linker input file list: $output" : > $output set x $save_libobjs shift firstobj= - if test "$compiler_needs_object" = yes; then + if test yes = "$compiler_needs_object"; then firstobj="$1 " shift fi @@ -8367,7 +9646,7 @@ EOF else if test -n "$save_libobjs"; then func_verbose "creating reloadable object files..." - output=$output_objdir/$output_la-${k}.$objext + output=$output_objdir/$output_la-$k.$objext eval test_cmds=\"$reload_cmds\" func_len " $test_cmds" len0=$func_len_result @@ -8379,13 +9658,13 @@ EOF func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result - if test "X$objlist" = X || + if test -z "$objlist" || test "$len" -lt "$max_cmd_len"; then func_append objlist " $obj" else # The command $test_cmds is almost too long, add a # command to the queue. - if test "$k" -eq 1 ; then + if test 1 -eq "$k"; then # The first file doesn't have a previous command to add. reload_objs=$objlist eval concat_cmds=\"$reload_cmds\" @@ -8395,10 +9674,10 @@ EOF reload_objs="$objlist $last_robj" eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" fi - last_robj=$output_objdir/$output_la-${k}.$objext + last_robj=$output_objdir/$output_la-$k.$objext func_arith $k + 1 k=$func_arith_result - output=$output_objdir/$output_la-${k}.$objext + output=$output_objdir/$output_la-$k.$objext objlist=" $obj" func_len " $last_robj" func_arith $len0 + $func_len_result @@ -8410,9 +9689,9 @@ EOF # files will link in the last one created. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ reload_objs="$objlist $last_robj" - eval concat_cmds=\"\${concat_cmds}$reload_cmds\" + eval concat_cmds=\"\$concat_cmds$reload_cmds\" if test -n "$last_robj"; then - eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" + eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi func_append delfiles " $output" @@ -8420,9 +9699,9 @@ EOF output= fi - if ${skipped_export-false}; then - func_verbose "generating symbol list for \`$libname.la'" - export_symbols="$output_objdir/$libname.exp" + ${skipped_export-false} && { + func_verbose "generating symbol list for '$libname.la'" + export_symbols=$output_objdir/$libname.exp $opt_dry_run || $RM $export_symbols libobjs=$output # Append the command to create the export file. @@ -8431,16 +9710,16 @@ EOF if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi - fi + } test -n "$save_libobjs" && func_verbose "creating a temporary reloadable object file: $output" # Loop through the commands generated above and execute them. - save_ifs="$IFS"; IFS='~' + save_ifs=$IFS; IFS='~' for cmd in $concat_cmds; do - IFS="$save_ifs" - $opt_silent || { + IFS=$save_ifs + $opt_quiet || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } @@ -8448,7 +9727,7 @@ EOF lt_exit=$? # Restore the uninstalled library and exit - if test "$opt_mode" = relink; then + if test relink = "$opt_mode"; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) @@ -8457,7 +9736,7 @@ EOF exit $lt_exit } done - IFS="$save_ifs" + IFS=$save_ifs if test -n "$export_symbols_regex" && ${skipped_export-false}; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' @@ -8465,18 +9744,18 @@ EOF fi fi - if ${skipped_export-false}; then + ${skipped_export-false} && { if test -n "$export_symbols" && test -n "$include_expsyms"; then - tmp_export_symbols="$export_symbols" - test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" + tmp_export_symbols=$export_symbols + test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. - func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" + func_verbose "filter symbol list for '$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of - # 's' commands which not all seds can handle. GNU sed should be fine + # 's' commands, which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. @@ -8485,7 +9764,7 @@ EOF export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi - fi + } libobjs=$output # Restore the value of output. @@ -8499,7 +9778,7 @@ EOF # value of $libobjs for piecewise linking. # Do each of the archive commands. - if test "$module" = yes && test -n "$module_cmds" ; then + if test yes = "$module" && test -n "$module_cmds"; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then cmds=$module_expsym_cmds else @@ -8521,7 +9800,7 @@ EOF # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then - gentop="$output_objdir/${outputname}x" + gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $dlprefiles @@ -8529,11 +9808,12 @@ EOF test "X$libobjs" = "X " && libobjs= fi - save_ifs="$IFS"; IFS='~' + save_ifs=$IFS; IFS='~' for cmd in $cmds; do - IFS="$save_ifs" + IFS=$sp$nl eval cmd=\"$cmd\" - $opt_silent || { + IFS=$save_ifs + $opt_quiet || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } @@ -8541,7 +9821,7 @@ EOF lt_exit=$? # Restore the uninstalled library and exit - if test "$opt_mode" = relink; then + if test relink = "$opt_mode"; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) @@ -8550,10 +9830,10 @@ EOF exit $lt_exit } done - IFS="$save_ifs" + IFS=$save_ifs # Restore the uninstalled library and exit - if test "$opt_mode" = relink; then + if test relink = "$opt_mode"; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? if test -n "$convenience"; then @@ -8573,39 +9853,39 @@ EOF done # If -module or -export-dynamic was specified, set the dlname. - if test "$module" = yes || test "$export_dynamic" = yes; then + if test yes = "$module" || test yes = "$export_dynamic"; then # On all known operating systems, these are identical. - dlname="$soname" + dlname=$soname fi fi ;; obj) - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - func_warning "\`-dlopen' is ignored for objects" + if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then + func_warning "'-dlopen' is ignored for objects" fi case " $deplibs" in *\ -l* | *\ -L*) - func_warning "\`-l' and \`-L' are ignored for objects" ;; + func_warning "'-l' and '-L' are ignored for objects" ;; esac test -n "$rpath" && \ - func_warning "\`-rpath' is ignored for objects" + func_warning "'-rpath' is ignored for objects" test -n "$xrpath" && \ - func_warning "\`-R' is ignored for objects" + func_warning "'-R' is ignored for objects" test -n "$vinfo" && \ - func_warning "\`-version-info' is ignored for objects" + func_warning "'-version-info' is ignored for objects" test -n "$release" && \ - func_warning "\`-release' is ignored for objects" + func_warning "'-release' is ignored for objects" case $output in *.lo) test -n "$objs$old_deplibs" && \ - func_fatal_error "cannot build library object \`$output' from non-libtool objects" + func_fatal_error "cannot build library object '$output' from non-libtool objects" libobj=$output func_lo2o "$libobj" @@ -8613,7 +9893,7 @@ EOF ;; *) libobj= - obj="$output" + obj=$output ;; esac @@ -8636,7 +9916,7 @@ EOF eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` else - gentop="$output_objdir/${obj}x" + gentop=$output_objdir/${obj}x func_append generated " $gentop" func_extract_archives $gentop $convenience @@ -8645,12 +9925,12 @@ EOF fi # If we're not building shared, we need to use non_pic_objs - test "$build_libtool_libs" != yes && libobjs="$non_pic_objects" + test yes = "$build_libtool_libs" || libobjs=$non_pic_objects # Create the old-style object. - reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test + reload_objs=$objs$old_deplibs' '`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; /\.lib$/d; $lo2o" | $NL2SP`' '$reload_conv_objs - output="$obj" + output=$obj func_execute_cmds "$reload_cmds" 'exit $?' # Exit if we aren't doing a library object file. @@ -8662,7 +9942,7 @@ EOF exit $EXIT_SUCCESS fi - if test "$build_libtool_libs" != yes; then + test yes = "$build_libtool_libs" || { if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi @@ -8672,12 +9952,12 @@ EOF # $show "echo timestamp > $libobj" # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? exit $EXIT_SUCCESS - fi + } - if test -n "$pic_flag" || test "$pic_mode" != default; then + if test -n "$pic_flag" || test default != "$pic_mode"; then # Only do commands if we really have different PIC objects. reload_objs="$libobjs $reload_conv_objs" - output="$libobj" + output=$libobj func_execute_cmds "$reload_cmds" 'exit $?' fi @@ -8694,16 +9974,14 @@ EOF output=$func_stripname_result.exe;; esac test -n "$vinfo" && \ - func_warning "\`-version-info' is ignored for programs" + func_warning "'-version-info' is ignored for programs" test -n "$release" && \ - func_warning "\`-release' is ignored for programs" + func_warning "'-release' is ignored for programs" - test "$preload" = yes \ - && test "$dlopen_support" = unknown \ - && test "$dlopen_self" = unknown \ - && test "$dlopen_self_static" = unknown && \ - func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support." + $preload \ + && test unknown,unknown,unknown = "$dlopen_support,$dlopen_self,$dlopen_self_static" \ + && func_warning "'LT_INIT([dlopen])' not used. Assuming no dlopen support." case $host in *-*-rhapsody* | *-*-darwin1.[012]) @@ -8717,11 +9995,11 @@ EOF *-*-darwin*) # Don't allow lazy linking, it breaks C++ global constructors # But is supposedly fixed on 10.4 or later (yay!). - if test "$tagname" = CXX ; then + if test CXX = "$tagname"; then case ${MACOSX_DEPLOYMENT_TARGET-10.0} in 10.[0123]) - func_append compile_command " ${wl}-bind_at_load" - func_append finalize_command " ${wl}-bind_at_load" + func_append compile_command " $wl-bind_at_load" + func_append finalize_command " $wl-bind_at_load" ;; esac fi @@ -8757,7 +10035,7 @@ EOF *) func_append new_libs " $deplib" ;; esac done - compile_deplibs="$new_libs" + compile_deplibs=$new_libs func_append compile_command " $compile_deplibs" @@ -8781,7 +10059,7 @@ EOF if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" + hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in @@ -8804,7 +10082,7 @@ EOF fi case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) - testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` + testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'` case :$dllsearchpath: in *":$libdir:"*) ;; ::) dllsearchpath=$libdir;; @@ -8821,10 +10099,10 @@ EOF # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" + libdir=$hardcode_libdirs eval rpath=\" $hardcode_libdir_flag_spec\" fi - compile_rpath="$rpath" + compile_rpath=$rpath rpath= hardcode_libdirs= @@ -8832,7 +10110,7 @@ EOF if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" + hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in @@ -8857,45 +10135,43 @@ EOF # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" + libdir=$hardcode_libdirs eval rpath=\" $hardcode_libdir_flag_spec\" fi - finalize_rpath="$rpath" + finalize_rpath=$rpath - if test -n "$libobjs" && test "$build_old_libs" = yes; then + if test -n "$libobjs" && test yes = "$build_old_libs"; then # Transform all the library objects into standard objects. compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` fi - func_generate_dlsyms "$outputname" "@PROGRAM@" "no" + func_generate_dlsyms "$outputname" "@PROGRAM@" false # template prelinking step if test -n "$prelink_cmds"; then func_execute_cmds "$prelink_cmds" 'exit $?' fi - wrappers_required=yes + wrappers_required=: case $host in *cegcc* | *mingw32ce*) # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. - wrappers_required=no + wrappers_required=false ;; *cygwin* | *mingw* ) - if test "$build_libtool_libs" != yes; then - wrappers_required=no - fi + test yes = "$build_libtool_libs" || wrappers_required=false ;; *) - if test "$need_relink" = no || test "$build_libtool_libs" != yes; then - wrappers_required=no + if test no = "$need_relink" || test yes != "$build_libtool_libs"; then + wrappers_required=false fi ;; esac - if test "$wrappers_required" = no; then + $wrappers_required || { # Replace the output file specification. compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` - link_command="$compile_command$compile_rpath" + link_command=$compile_command$compile_rpath # We have no uninstalled library dependencies, so finalize right now. exit_status=0 @@ -8908,12 +10184,12 @@ EOF fi # Delete the generated files. - if test -f "$output_objdir/${outputname}S.${objext}"; then - func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' + if test -f "$output_objdir/${outputname}S.$objext"; then + func_show_eval '$RM "$output_objdir/${outputname}S.$objext"' fi exit $exit_status - fi + } if test -n "$compile_shlibpath$finalize_shlibpath"; then compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" @@ -8943,9 +10219,9 @@ EOF fi fi - if test "$no_install" = yes; then + if test yes = "$no_install"; then # We don't need to create a wrapper script. - link_command="$compile_var$compile_command$compile_rpath" + link_command=$compile_var$compile_command$compile_rpath # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` # Delete the old output file. @@ -8962,27 +10238,28 @@ EOF exit $EXIT_SUCCESS fi - if test "$hardcode_action" = relink; then - # Fast installation is not supported - link_command="$compile_var$compile_command$compile_rpath" - relink_command="$finalize_var$finalize_command$finalize_rpath" + case $hardcode_action,$fast_install in + relink,*) + # Fast installation is not supported + link_command=$compile_var$compile_command$compile_rpath + relink_command=$finalize_var$finalize_command$finalize_rpath - func_warning "this platform does not like uninstalled shared libraries" - func_warning "\`$output' will be relinked during installation" - else - if test "$fast_install" != no; then - link_command="$finalize_var$compile_command$finalize_rpath" - if test "$fast_install" = yes; then - relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` - else - # fast_install is set to needless - relink_command= - fi - else - link_command="$compile_var$compile_command$compile_rpath" - relink_command="$finalize_var$finalize_command$finalize_rpath" - fi - fi + func_warning "this platform does not like uninstalled shared libraries" + func_warning "'$output' will be relinked during installation" + ;; + *,yes) + link_command=$finalize_var$compile_command$finalize_rpath + relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` + ;; + *,no) + link_command=$compile_var$compile_command$compile_rpath + relink_command=$finalize_var$finalize_command$finalize_rpath + ;; + *,needless) + link_command=$finalize_var$compile_command$finalize_rpath + relink_command= + ;; + esac # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` @@ -9039,8 +10316,8 @@ EOF func_dirname_and_basename "$output" "" "." output_name=$func_basename_result output_path=$func_dirname_result - cwrappersource="$output_path/$objdir/lt-$output_name.c" - cwrapper="$output_path/$output_name.exe" + cwrappersource=$output_path/$objdir/lt-$output_name.c + cwrapper=$output_path/$output_name.exe $RM $cwrappersource $cwrapper trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 @@ -9061,7 +10338,7 @@ EOF trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 $opt_dry_run || { # note: this script will not be executed, so do not chmod. - if test "x$build" = "x$host" ; then + if test "x$build" = "x$host"; then $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result else func_emit_wrapper no > $func_ltwrapper_scriptname_result @@ -9084,25 +10361,27 @@ EOF # See if we need to build an old-fashioned archive. for oldlib in $oldlibs; do - if test "$build_libtool_libs" = convenience; then - oldobjs="$libobjs_save $symfileobj" - addlibs="$convenience" - build_libtool_libs=no - else - if test "$build_libtool_libs" = module; then - oldobjs="$libobjs_save" + case $build_libtool_libs in + convenience) + oldobjs="$libobjs_save $symfileobj" + addlibs=$convenience build_libtool_libs=no - else + ;; + module) + oldobjs=$libobjs_save + addlibs=$old_convenience + build_libtool_libs=no + ;; + *) oldobjs="$old_deplibs $non_pic_objects" - if test "$preload" = yes && test -f "$symfileobj"; then - func_append oldobjs " $symfileobj" - fi - fi - addlibs="$old_convenience" - fi + $preload && test -f "$symfileobj" \ + && func_append oldobjs " $symfileobj" + addlibs=$old_convenience + ;; + esac if test -n "$addlibs"; then - gentop="$output_objdir/${outputname}x" + gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $addlibs @@ -9110,13 +10389,13 @@ EOF fi # Do each command in the archive commands. - if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + if test -n "$old_archive_from_new_cmds" && test yes = "$build_libtool_libs"; then cmds=$old_archive_from_new_cmds else # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then - gentop="$output_objdir/${outputname}x" + gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $dlprefiles @@ -9137,7 +10416,7 @@ EOF : else echo "copying selected object files to avoid basename conflicts..." - gentop="$output_objdir/${outputname}x" + gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_mkdir_p "$gentop" save_oldobjs=$oldobjs @@ -9146,7 +10425,7 @@ EOF for obj in $save_oldobjs do func_basename "$obj" - objbase="$func_basename_result" + objbase=$func_basename_result case " $oldobjs " in " ") oldobjs=$obj ;; *[\ /]"$objbase "*) @@ -9215,18 +10494,18 @@ EOF else # the above command should be used before it gets too long oldobjs=$objlist - if test "$obj" = "$last_oldobj" ; then + if test "$obj" = "$last_oldobj"; then RANLIB=$save_RANLIB fi test -z "$concat_cmds" || concat_cmds=$concat_cmds~ - eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" + eval concat_cmds=\"\$concat_cmds$old_archive_cmds\" objlist= len=$len0 fi done RANLIB=$save_RANLIB oldobjs=$objlist - if test "X$oldobjs" = "X" ; then + if test -z "$oldobjs"; then eval cmds=\"\$concat_cmds\" else eval cmds=\"\$concat_cmds~\$old_archive_cmds\" @@ -9243,7 +10522,7 @@ EOF case $output in *.la) old_library= - test "$build_old_libs" = yes && old_library="$libname.$libext" + test yes = "$build_old_libs" && old_library=$libname.$libext func_verbose "creating $output" # Preserve any variables that may affect compiler behavior @@ -9258,31 +10537,31 @@ EOF fi done # Quote the link command for shipping. - relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` - if test "$hardcode_automatic" = yes ; then + if test yes = "$hardcode_automatic"; then relink_command= fi # Only create the output if not a dry run. $opt_dry_run || { for installed in no yes; do - if test "$installed" = yes; then + if test yes = "$installed"; then if test -z "$install_libdir"; then break fi - output="$output_objdir/$outputname"i + output=$output_objdir/${outputname}i # Replace all uninstalled libtool libraries with the installed ones newdependency_libs= for deplib in $dependency_libs; do case $deplib in *.la) func_basename "$deplib" - name="$func_basename_result" + name=$func_basename_result func_resolve_sysroot "$deplib" - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` test -z "$libdir" && \ - func_fatal_error "\`$deplib' is not a valid libtool archive" + func_fatal_error "'$deplib' is not a valid libtool archive" func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" ;; -L*) @@ -9298,23 +10577,23 @@ EOF *) func_append newdependency_libs " $deplib" ;; esac done - dependency_libs="$newdependency_libs" + dependency_libs=$newdependency_libs newdlfiles= for lib in $dlfiles; do case $lib in *.la) func_basename "$lib" - name="$func_basename_result" - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + name=$func_basename_result + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ - func_fatal_error "\`$lib' is not a valid libtool archive" + func_fatal_error "'$lib' is not a valid libtool archive" func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" ;; *) func_append newdlfiles " $lib" ;; esac done - dlfiles="$newdlfiles" + dlfiles=$newdlfiles newdlprefiles= for lib in $dlprefiles; do case $lib in @@ -9324,34 +10603,34 @@ EOF # didn't already link the preopened objects directly into # the library: func_basename "$lib" - name="$func_basename_result" - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + name=$func_basename_result + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ - func_fatal_error "\`$lib' is not a valid libtool archive" + func_fatal_error "'$lib' is not a valid libtool archive" func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" ;; esac done - dlprefiles="$newdlprefiles" + dlprefiles=$newdlprefiles else newdlfiles= for lib in $dlfiles; do case $lib in - [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlfiles " $abs" done - dlfiles="$newdlfiles" + dlfiles=$newdlfiles newdlprefiles= for lib in $dlprefiles; do case $lib in - [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlprefiles " $abs" done - dlprefiles="$newdlprefiles" + dlprefiles=$newdlprefiles fi $RM $output # place dlname in correct position for cygwin @@ -9367,10 +10646,9 @@ EOF case $host,$output,$installed,$module,$dlname in *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) # If a -bindir argument was supplied, place the dll there. - if test "x$bindir" != x ; - then + if test -n "$bindir"; then func_relative_path "$install_libdir" "$bindir" - tdlname=$func_relative_path_result$dlname + tdlname=$func_relative_path_result/$dlname else # Otherwise fall back on heuristic. tdlname=../bin/$dlname @@ -9379,7 +10657,7 @@ EOF esac $ECHO > $output "\ # $outputname - a libtool library file -# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# Generated by $PROGRAM (GNU $PACKAGE) $VERSION # # Please DO NOT delete this file! # It is necessary for linking the library. @@ -9393,7 +10671,7 @@ library_names='$library_names' # The name of the static archive. old_library='$old_library' -# Linker flags that can not go in dependency_libs. +# Linker flags that cannot go in dependency_libs. inherited_linker_flags='$new_inherited_linker_flags' # Libraries that this one depends upon. @@ -9419,7 +10697,7 @@ dlpreopen='$dlprefiles' # Directory that this library needs to be installed in: libdir='$install_libdir'" - if test "$installed" = no && test "$need_relink" = yes; then + if test no,yes = "$installed,$need_relink"; then $ECHO >> $output "\ relink_command=\"$relink_command\"" fi @@ -9434,27 +10712,29 @@ relink_command=\"$relink_command\"" exit $EXIT_SUCCESS } -{ test "$opt_mode" = link || test "$opt_mode" = relink; } && - func_mode_link ${1+"$@"} +if test link = "$opt_mode" || test relink = "$opt_mode"; then + func_mode_link ${1+"$@"} +fi # func_mode_uninstall arg... func_mode_uninstall () { - $opt_debug - RM="$nonopt" + $debug_cmd + + RM=$nonopt files= - rmforce= + rmforce=false exit_status=0 # This variable tells wrapper scripts just to set variables rather # than running their programs. - libtool_install_magic="$magic" + libtool_install_magic=$magic for arg do case $arg in - -f) func_append RM " $arg"; rmforce=yes ;; + -f) func_append RM " $arg"; rmforce=: ;; -*) func_append RM " $arg" ;; *) func_append files " $arg" ;; esac @@ -9467,18 +10747,18 @@ func_mode_uninstall () for file in $files; do func_dirname "$file" "" "." - dir="$func_dirname_result" - if test "X$dir" = X.; then - odir="$objdir" + dir=$func_dirname_result + if test . = "$dir"; then + odir=$objdir else - odir="$dir/$objdir" + odir=$dir/$objdir fi func_basename "$file" - name="$func_basename_result" - test "$opt_mode" = uninstall && odir="$dir" + name=$func_basename_result + test uninstall = "$opt_mode" && odir=$dir # Remember odir for removal later, being careful to avoid duplicates - if test "$opt_mode" = clean; then + if test clean = "$opt_mode"; then case " $rmdirs " in *" $odir "*) ;; *) func_append rmdirs " $odir" ;; @@ -9493,11 +10773,11 @@ func_mode_uninstall () elif test -d "$file"; then exit_status=1 continue - elif test "$rmforce" = yes; then + elif $rmforce; then continue fi - rmfiles="$file" + rmfiles=$file case $name in *.la) @@ -9511,7 +10791,7 @@ func_mode_uninstall () done test -n "$old_library" && func_append rmfiles " $odir/$old_library" - case "$opt_mode" in + case $opt_mode in clean) case " $library_names " in *" $dlname "*) ;; @@ -9522,12 +10802,12 @@ func_mode_uninstall () uninstall) if test -n "$library_names"; then # Do each command in the postuninstall commands. - func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' + func_execute_cmds "$postuninstall_cmds" '$rmforce || exit_status=1' fi if test -n "$old_library"; then # Do each command in the old_postuninstall commands. - func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' + func_execute_cmds "$old_postuninstall_cmds" '$rmforce || exit_status=1' fi # FIXME: should reinstall the best remaining shared library. ;; @@ -9543,21 +10823,19 @@ func_mode_uninstall () func_source $dir/$name # Add PIC object to the list of files to remove. - if test -n "$pic_object" && - test "$pic_object" != none; then + if test -n "$pic_object" && test none != "$pic_object"; then func_append rmfiles " $dir/$pic_object" fi # Add non-PIC object to the list of files to remove. - if test -n "$non_pic_object" && - test "$non_pic_object" != none; then + if test -n "$non_pic_object" && test none != "$non_pic_object"; then func_append rmfiles " $dir/$non_pic_object" fi fi ;; *) - if test "$opt_mode" = clean ; then + if test clean = "$opt_mode"; then noexename=$name case $file in *.exe) @@ -9584,12 +10862,12 @@ func_mode_uninstall () # note $name still contains .exe if it was in $file originally # as does the version of $file that was added into $rmfiles - func_append rmfiles " $odir/$name $odir/${name}S.${objext}" - if test "$fast_install" = yes && test -n "$relink_command"; then + func_append rmfiles " $odir/$name $odir/${name}S.$objext" + if test yes = "$fast_install" && test -n "$relink_command"; then func_append rmfiles " $odir/lt-$name" fi - if test "X$noexename" != "X$name" ; then - func_append rmfiles " $odir/lt-${noexename}.c" + if test "X$noexename" != "X$name"; then + func_append rmfiles " $odir/lt-$noexename.c" fi fi fi @@ -9598,7 +10876,7 @@ func_mode_uninstall () func_show_eval "$RM $rmfiles" 'exit_status=1' done - # Try to remove the ${objdir}s in the directories where we deleted files + # Try to remove the $objdir's in the directories where we deleted files for dir in $rmdirs; do if test -d "$dir"; then func_show_eval "rmdir $dir >/dev/null 2>&1" @@ -9608,16 +10886,17 @@ func_mode_uninstall () exit $exit_status } -{ test "$opt_mode" = uninstall || test "$opt_mode" = clean; } && - func_mode_uninstall ${1+"$@"} +if test uninstall = "$opt_mode" || test clean = "$opt_mode"; then + func_mode_uninstall ${1+"$@"} +fi test -z "$opt_mode" && { - help="$generic_help" + help=$generic_help func_fatal_help "you must specify a MODE" } test -z "$exec_cmd" && \ - func_fatal_help "invalid operation mode \`$opt_mode'" + func_fatal_help "invalid operation mode '$opt_mode'" if test -n "$exec_cmd"; then eval exec "$exec_cmd" @@ -9628,7 +10907,7 @@ exit $exit_status # The TAGs below are defined such that we never get into a situation -# in which we disable both kinds of libraries. Given conflicting +# where we disable both kinds of libraries. Given conflicting # choices, we go for a static library, that is the most portable, # since we can't tell whether shared libraries were disabled because # the user asked for that or because the platform doesn't support @@ -9651,5 +10930,3 @@ build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` # mode:shell-script # sh-indentation:2 # End: -# vi:sw=2 - diff --git a/Modules/_ctypes/libffi/m4/ax_gcc_archflag.m4 b/Modules/_ctypes/libffi/m4/ax_gcc_archflag.m4 index 3fd050e7a95d..aab2661c3066 100644 --- a/Modules/_ctypes/libffi/m4/ax_gcc_archflag.m4 +++ b/Modules/_ctypes/libffi/m4/ax_gcc_archflag.m4 @@ -155,7 +155,7 @@ case $host_cpu in sparc*) AC_PATH_PROG([PRTDIAG], [prtdiag], [prtdiag], [$PATH:/usr/platform/`uname -i`/sbin/:/usr/platform/`uname -m`/sbin/]) cputype=`(((grep cpu /proc/cpuinfo | cut -d: -f2) ; ($PRTDIAG -v |grep -i sparc) ; grep -i cpu /var/run/dmesg.boot ) | head -n 1) 2> /dev/null` - cputype=`echo "$cputype" | tr -d ' -' |tr $as_cr_LETTERS $as_cr_letters` + cputype=`echo "$cputype" | tr -d ' -' | sed 's/SPARCIIi/SPARCII/' | tr $as_cr_LETTERS $as_cr_letters` case $cputype in *ultrasparciv*) ax_gcc_arch="ultrasparc4 ultrasparc3 ultrasparc v9" ;; *ultrasparciii*) ax_gcc_arch="ultrasparc3 ultrasparc v9" ;; diff --git a/Modules/_ctypes/libffi/m4/libtool.m4 b/Modules/_ctypes/libffi/m4/libtool.m4 index 3318f27a46b2..4bc6b22c80fc 100644 --- a/Modules/_ctypes/libffi/m4/libtool.m4 +++ b/Modules/_ctypes/libffi/m4/libtool.m4 @@ -1,8 +1,6 @@ # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, -# 2006, 2007, 2008, 2009, 2010, 2011 Free Software -# Foundation, Inc. +# Copyright (C) 1996-2001, 2003-2013 Free Software Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is free software; the Free Software Foundation gives @@ -39,7 +37,7 @@ m4_define([_LT_COPYING], [dnl # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ]) -# serial 57 LT_INIT +# serial 58 LT_INIT # LT_PREREQ(VERSION) @@ -91,7 +89,7 @@ dnl Parse OPTIONS _LT_SET_OPTIONS([$0], [$1]) # This can be used to rebuild libtool when needed -LIBTOOL_DEPS="$ltmain" +LIBTOOL_DEPS=$ltmain # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' @@ -130,7 +128,7 @@ cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` # _LT_FILEUTILS_DEFAULTS # ---------------------- # It is okay to use these file commands and assume they have been set -# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. +# sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'. m4_defun([_LT_FILEUTILS_DEFAULTS], [: ${CP="cp -f"} : ${MV="mv -f"} @@ -179,13 +177,13 @@ m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_WITH_SYSROOT])dnl _LT_CONFIG_LIBTOOL_INIT([ -# See if we are running on zsh, and set the options which allow our +# See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes INIT. -if test -n "\${ZSH_VERSION+set}" ; then +if test -n "\${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi ]) -if test -n "${ZSH_VERSION+set}" ; then +if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi @@ -198,7 +196,7 @@ aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. - if test "X${COLLECT_NAMES+set}" != Xset; then + if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi @@ -209,14 +207,14 @@ esac ofile=libtool can_build_shared=yes -# All known linkers require a `.a' archive for static linking (except MSVC, +# All known linkers require a '.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a -with_gnu_ld="$lt_cv_prog_gnu_ld" +with_gnu_ld=$lt_cv_prog_gnu_ld -old_CC="$CC" -old_CFLAGS="$CFLAGS" +old_CC=$CC +old_CFLAGS=$CFLAGS # Set sane defaults for various variables test -z "$CC" && CC=cc @@ -269,14 +267,14 @@ no_glob_subst='s/\*/\\\*/g' # _LT_PROG_LTMAIN # --------------- -# Note that this code is called both from `configure', and `config.status' +# Note that this code is called both from 'configure', and 'config.status' # now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, -# `config.status' has no value for ac_aux_dir unless we are using Automake, +# 'config.status' has no value for ac_aux_dir unless we are using Automake, # so we pass a copy along to make sure it has a sensible value anyway. m4_defun([_LT_PROG_LTMAIN], [m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl _LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) -ltmain="$ac_aux_dir/ltmain.sh" +ltmain=$ac_aux_dir/ltmain.sh ])# _LT_PROG_LTMAIN @@ -286,7 +284,7 @@ ltmain="$ac_aux_dir/ltmain.sh" # So that we can recreate a full libtool script including additional # tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS -# in macros and then make a single call at the end using the `libtool' +# in macros and then make a single call at the end using the 'libtool' # label. @@ -421,8 +419,8 @@ m4_define([_lt_decl_all_varnames], # _LT_CONFIG_STATUS_DECLARE([VARNAME]) # ------------------------------------ -# Quote a variable value, and forward it to `config.status' so that its -# declaration there will have the same value as in `configure'. VARNAME +# Quote a variable value, and forward it to 'config.status' so that its +# declaration there will have the same value as in 'configure'. VARNAME # must have a single quote delimited value for this to work. m4_define([_LT_CONFIG_STATUS_DECLARE], [$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) @@ -446,7 +444,7 @@ m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], # Output comment and list of tags supported by the script m4_defun([_LT_LIBTOOL_TAGS], [_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl -available_tags="_LT_TAGS"dnl +available_tags='_LT_TAGS'dnl ]) @@ -474,7 +472,7 @@ m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl # _LT_LIBTOOL_CONFIG_VARS # ----------------------- # Produce commented declarations of non-tagged libtool config variables -# suitable for insertion in the LIBTOOL CONFIG section of the `libtool' +# suitable for insertion in the LIBTOOL CONFIG section of the 'libtool' # script. Tagged libtool config variables (even for the LIBTOOL CONFIG # section) are produced by _LT_LIBTOOL_TAG_VARS. m4_defun([_LT_LIBTOOL_CONFIG_VARS], @@ -500,8 +498,8 @@ m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) # Send accumulated output to $CONFIG_STATUS. Thanks to the lists of # variables for single and double quote escaping we saved from calls # to _LT_DECL, we can put quote escaped variables declarations -# into `config.status', and then the shell code to quote escape them in -# for loops in `config.status'. Finally, any additional code accumulated +# into 'config.status', and then the shell code to quote escape them in +# for loops in 'config.status'. Finally, any additional code accumulated # from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. m4_defun([_LT_CONFIG_COMMANDS], [AC_PROVIDE_IFELSE([LT_OUTPUT], @@ -547,7 +545,7 @@ for var in lt_decl_all_varnames([[ \ ]], lt_decl_quote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" @@ -560,7 +558,7 @@ for var in lt_decl_all_varnames([[ \ ]], lt_decl_dquote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" @@ -576,7 +574,7 @@ _LT_OUTPUT_LIBTOOL_INIT # Generate a child script FILE with all initialization necessary to # reuse the environment learned by the parent script, and make the # file executable. If COMMENT is supplied, it is inserted after the -# `#!' sequence but before initialization text begins. After this +# '#!' sequence but before initialization text begins. After this # macro, additional text can be appended to FILE to form the body of # the child script. The macro ends with non-zero status if the # file could not be fully written (such as if the disk is full). @@ -598,7 +596,7 @@ AS_SHELL_SANITIZE _AS_PREPARE exec AS_MESSAGE_FD>&1 _ASEOF -test $lt_write_fail = 0 && chmod +x $1[]dnl +test 0 = "$lt_write_fail" && chmod +x $1[]dnl m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT # LT_OUTPUT @@ -621,7 +619,7 @@ exec AS_MESSAGE_LOG_FD>>config.log } >&AS_MESSAGE_LOG_FD lt_cl_help="\ -\`$as_me' creates a local libtool stub from the current configuration, +'$as_me' creates a local libtool stub from the current configuration, for use in further configure time tests before the real libtool is generated. @@ -643,7 +641,7 @@ Copyright (C) 2011 Free Software Foundation, Inc. This config.lt script is free software; the Free Software Foundation gives unlimited permision to copy, distribute and modify it." -while test $[#] != 0 +while test 0 != $[#] do case $[1] in --version | --v* | -V ) @@ -656,10 +654,10 @@ do lt_cl_silent=: ;; -*) AC_MSG_ERROR([unrecognized option: $[1] -Try \`$[0] --help' for more information.]) ;; +Try '$[0] --help' for more information.]) ;; *) AC_MSG_ERROR([unrecognized argument: $[1] -Try \`$[0] --help' for more information.]) ;; +Try '$[0] --help' for more information.]) ;; esac shift done @@ -685,7 +683,7 @@ chmod +x "$CONFIG_LT" # open by configure. Here we exec the FD to /dev/null, effectively closing # config.log, so it can be properly (re)opened and appended to by config.lt. lt_cl_success=: -test "$silent" = yes && +test yes = "$silent" && lt_config_lt_args="$lt_config_lt_args --quiet" exec AS_MESSAGE_LOG_FD>/dev/null $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false @@ -705,13 +703,13 @@ m4_defun([_LT_CONFIG], _LT_CONFIG_SAVE_COMMANDS([ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl m4_if(_LT_TAG, [C], [ - # See if we are running on zsh, and set the options which allow our + # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes. - if test -n "${ZSH_VERSION+set}" ; then + if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi - cfgfile="${ofile}T" + cfgfile=${ofile}T trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" @@ -719,7 +717,7 @@ _LT_CONFIG_SAVE_COMMANDS([ #! $SHELL # `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. -# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Generated automatically by $as_me ($PACKAGE) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # @@ -739,7 +737,7 @@ _LT_EOF # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. -if test "X${COLLECT_NAMES+set}" != Xset; then +if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi @@ -756,8 +754,6 @@ _LT_EOF sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) - _LT_PROG_REPLACE_SHELLFNS - mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" @@ -775,7 +771,6 @@ _LT_EOF [m4_if([$1], [], [ PACKAGE='$PACKAGE' VERSION='$VERSION' - TIMESTAMP='$TIMESTAMP' RM='$RM' ofile='$ofile'], []) ])dnl /_LT_CONFIG_SAVE_COMMANDS @@ -974,7 +969,7 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], [lt_cv_apple_cc_single_mod=no - if test -z "${LT_MULTI_MODULE}"; then + if test -z "$LT_MULTI_MODULE"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the @@ -992,7 +987,7 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ cat conftest.err >&AS_MESSAGE_LOG_FD # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. - elif test -f libconftest.dylib && test $_lt_result -eq 0; then + elif test -f libconftest.dylib && test 0 = "$_lt_result"; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&AS_MESSAGE_LOG_FD @@ -1010,7 +1005,7 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [lt_cv_ld_exported_symbols_list=yes], [lt_cv_ld_exported_symbols_list=no]) - LDFLAGS="$save_LDFLAGS" + LDFLAGS=$save_LDFLAGS ]) AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], @@ -1032,7 +1027,7 @@ _LT_EOF _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD - elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then + elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then lt_cv_ld_force_load=yes else cat conftest.err >&AS_MESSAGE_LOG_FD @@ -1042,32 +1037,32 @@ _LT_EOF ]) case $host_os in rhapsody* | darwin1.[[012]]) - _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) - _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; 10.[[012]]*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; 10.*) - _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; esac - if test "$lt_cv_apple_cc_single_mod" = "yes"; then + if test yes = "$lt_cv_apple_cc_single_mod"; then _lt_dar_single_mod='$single_module' fi - if test "$lt_cv_ld_exported_symbols_list" = "yes"; then - _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + if test yes = "$lt_cv_ld_exported_symbols_list"; then + _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' else - _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' fi - if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then + if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= @@ -1087,29 +1082,29 @@ m4_defun([_LT_DARWIN_LINKER_FEATURES], _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported - if test "$lt_cv_ld_force_load" = "yes"; then - _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + if test yes = "$lt_cv_ld_force_load"; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) else _LT_TAGVAR(whole_archive_flag_spec, $1)='' fi _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" + _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined case $cc_basename in - ifort*) _lt_dar_can_shared=yes ;; + ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac - if test "$_lt_dar_can_shared" = "yes"; then + if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all - _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" - _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" - _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" - _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" + _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" m4_if([$1], [CXX], -[ if test "$lt_cv_apple_cc_single_mod" != "yes"; then - _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" - _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" +[ if test yes != "$lt_cv_apple_cc_single_mod"; then + _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" fi ],[]) else @@ -1129,7 +1124,7 @@ m4_defun([_LT_DARWIN_LINKER_FEATURES], # Allow to override them for all tags through lt_cv_aix_libpath. m4_defun([_LT_SYS_MODULE_PATH_AIX], [m4_require([_LT_DECL_SED])dnl -if test "${lt_cv_aix_libpath+set}" = set; then +if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], @@ -1147,7 +1142,7 @@ else _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi],[]) if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then - _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib" + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib fi ]) aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) @@ -1167,8 +1162,8 @@ m4_define([_LT_SHELL_INIT], # ----------------------- # Find how we can fake an echo command that does not interpret backslash. # In particular, with Autoconf 2.60 or later we add some code to the start -# of the generated configure script which will find a shell with a builtin -# printf (which we can use as an echo command). +# of the generated configure script that will find a shell with a builtin +# printf (that we can use as an echo command). m4_defun([_LT_PROG_ECHO_BACKSLASH], [ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO @@ -1196,10 +1191,10 @@ fi # Invoke $ECHO with all args, space-separated. func_echo_all () { - $ECHO "$*" + $ECHO "$*" } -case "$ECHO" in +case $ECHO in printf*) AC_MSG_RESULT([printf]) ;; print*) AC_MSG_RESULT([print -r]) ;; *) AC_MSG_RESULT([cat]) ;; @@ -1225,16 +1220,17 @@ _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) AC_DEFUN([_LT_WITH_SYSROOT], [AC_MSG_CHECKING([for sysroot]) AC_ARG_WITH([sysroot], -[ --with-sysroot[=DIR] Search for dependent libraries within DIR - (or the compiler's sysroot if not specified).], +[AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@], + [Search for dependent libraries within DIR (or the compiler's sysroot + if not specified).])], [], [with_sysroot=no]) dnl lt_sysroot will always be passed unquoted. We quote it here dnl in case the user passed a directory name. lt_sysroot= -case ${with_sysroot} in #( +case $with_sysroot in #( yes) - if test "$GCC" = yes; then + if test yes = "$GCC"; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( @@ -1244,14 +1240,14 @@ case ${with_sysroot} in #( no|'') ;; #( *) - AC_MSG_RESULT([${with_sysroot}]) + AC_MSG_RESULT([$with_sysroot]) AC_MSG_ERROR([The sysroot must be an absolute path.]) ;; esac AC_MSG_RESULT([${lt_sysroot:-no}]) _LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl -[dependent libraries, and in which our libraries should be installed.])]) +[dependent libraries, and where our libraries should be installed.])]) # _LT_ENABLE_LOCK # --------------- @@ -1259,31 +1255,33 @@ m4_defun([_LT_ENABLE_LOCK], [AC_ARG_ENABLE([libtool-lock], [AS_HELP_STRING([--disable-libtool-lock], [avoid locking (might break parallel builds)])]) -test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes +test no = "$enable_libtool_lock" || enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) - # Find out which ABI we are using. + # Find out what ABI is being produced by ac_compile, and set mode + # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) - HPUX_IA64_MODE="32" + HPUX_IA64_MODE=32 ;; *ELF-64*) - HPUX_IA64_MODE="64" + HPUX_IA64_MODE=64 ;; esac fi rm -rf conftest* ;; *-*-irix6*) - # Find out which ABI we are using. + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then - if test "$lt_cv_prog_gnu_ld" = yes; then + if test yes = "$lt_cv_prog_gnu_ld"; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" @@ -1312,9 +1310,46 @@ ia64-*-hpux*) rm -rf conftest* ;; -x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +mips64*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + emul=elf + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + emul="${emul}32" + ;; + *64-bit*) + emul="${emul}64" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *MSB*) + emul="${emul}btsmip" + ;; + *LSB*) + emul="${emul}ltsmip" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *N32*) + emul="${emul}n32" + ;; + esac + LD="${LD-ld} -m $emul" + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) - # Find out which ABI we are using. + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. Note that the listed cases only cover the + # situations where additional linker options are needed (such as when + # doing 32-bit compilation for a host where ld defaults to 64-bit, or + # vice versa); the common cases where no linker options are needed do + # not appear in the list. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in @@ -1326,14 +1361,17 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) x86_64-*linux*) case `/usr/bin/file conftest.o` in *x86-64*) - LD="${LD-ld} -m elf32_x86_64" - ;; + LD="${LD-ld} -m elf32_x86_64" + ;; *) - LD="${LD-ld} -m elf_i386" - ;; + LD="${LD-ld} -m elf_i386" + ;; esac ;; - ppc64-*linux*|powerpc64-*linux*) + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) @@ -1352,7 +1390,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; - ppc*-*linux*|powerpc*-*linux*) + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) @@ -1370,19 +1411,20 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. - SAVE_CFLAGS="$CFLAGS" + SAVE_CFLAGS=$CFLAGS CFLAGS="$CFLAGS -belf" AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, [AC_LANG_PUSH(C) AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) AC_LANG_POP]) - if test x"$lt_cv_cc_needs_belf" != x"yes"; then + if test yes != "$lt_cv_cc_needs_belf"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf - CFLAGS="$SAVE_CFLAGS" + CFLAGS=$SAVE_CFLAGS fi ;; *-*solaris*) - # Find out which ABI we are using. + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in @@ -1390,7 +1432,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) case $lt_cv_prog_gnu_ld in yes*) case $host in - i?86-*-solaris*) + i?86-*-solaris*|x86_64-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) @@ -1399,7 +1441,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then - LD="${LD-ld}_sol2" + LD=${LD-ld}_sol2 fi ;; *) @@ -1415,7 +1457,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) ;; esac -need_locks="$enable_libtool_lock" +need_locks=$enable_libtool_lock ])# _LT_ENABLE_LOCK @@ -1434,11 +1476,11 @@ AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], [echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([lt_ar_try]) - if test "$ac_status" -eq 0; then + if test 0 -eq "$ac_status"; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a AC_TRY_EVAL([lt_ar_try]) - if test "$ac_status" -ne 0; then + if test 0 -ne "$ac_status"; then lt_cv_ar_at_file=@ fi fi @@ -1446,7 +1488,7 @@ AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], ]) ]) -if test "x$lt_cv_ar_at_file" = xno; then +if test no = "$lt_cv_ar_at_file"; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file @@ -1477,7 +1519,7 @@ old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in - openbsd*) + bitrig* | openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) @@ -1513,7 +1555,7 @@ AC_CACHE_CHECK([$1], [$2], [$2=no m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) echo "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="$3" + lt_compiler_flag="$3" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins @@ -1540,7 +1582,7 @@ AC_CACHE_CHECK([$1], [$2], $RM conftest* ]) -if test x"[$]$2" = xyes; then +if test yes = "[$]$2"; then m4_if([$5], , :, [$5]) else m4_if([$6], , :, [$6]) @@ -1562,7 +1604,7 @@ AC_DEFUN([_LT_LINKER_OPTION], m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no - save_LDFLAGS="$LDFLAGS" + save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $3" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then @@ -1581,10 +1623,10 @@ AC_CACHE_CHECK([$1], [$2], fi fi $RM -r conftest* - LDFLAGS="$save_LDFLAGS" + LDFLAGS=$save_LDFLAGS ]) -if test x"[$]$2" = xyes; then +if test yes = "[$]$2"; then m4_if([$4], , :, [$4]) else m4_if([$5], , :, [$5]) @@ -1605,7 +1647,7 @@ AC_DEFUN([LT_CMD_MAX_LEN], AC_MSG_CHECKING([the maximum length of command line arguments]) AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl i=0 - teststring="ABCD" + teststring=ABCD case $build_os in msdosdjgpp*) @@ -1645,7 +1687,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl lt_cv_sys_max_cmd_len=8192; ;; - netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` @@ -1696,22 +1738,22 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len" && \ - test undefined != "$lt_cv_sys_max_cmd_len"; then + test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. - for i in 1 2 3 4 5 6 7 8 ; do + for i in 1 2 3 4 5 6 7 8; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. - while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ + while { test X`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && - test $i != 17 # 1/2 MB should be enough + test 17 != "$i" # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring @@ -1727,7 +1769,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl ;; esac ]) -if test -n $lt_cv_sys_max_cmd_len ; then +if test -n "$lt_cv_sys_max_cmd_len"; then AC_MSG_RESULT($lt_cv_sys_max_cmd_len) else AC_MSG_RESULT(none) @@ -1755,7 +1797,7 @@ m4_defun([_LT_HEADER_DLFCN], # ---------------------------------------------------------------- m4_defun([_LT_TRY_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl -if test "$cross_compiling" = yes; then : +if test yes = "$cross_compiling"; then : [$4] else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 @@ -1804,7 +1846,7 @@ else /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ -#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif @@ -1830,7 +1872,7 @@ int main () return status; }] _LT_EOF - if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then + if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null lt_status=$? case x$lt_status in @@ -1851,7 +1893,7 @@ rm -fr conftest* # ------------------ AC_DEFUN([LT_SYS_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl -if test "x$enable_dlopen" != xyes; then +if test yes != "$enable_dlopen"; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown @@ -1861,44 +1903,52 @@ else case $host_os in beos*) - lt_cv_dlopen="load_add_on" + lt_cv_dlopen=load_add_on lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) - lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen=LoadLibrary lt_cv_dlopen_libs= ;; cygwin*) - lt_cv_dlopen="dlopen" + lt_cv_dlopen=dlopen lt_cv_dlopen_libs= ;; darwin*) - # if libdl is installed we need to link against it + # if libdl is installed we need to link against it AC_CHECK_LIB([dl], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ - lt_cv_dlopen="dyld" + [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[ + lt_cv_dlopen=dyld lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ]) ;; + tpf*) + # Don't try to run any link tests for TPF. We know it's impossible + # because TPF is a cross-compiler, and we know how we open DSOs. + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + lt_cv_dlopen_self=no + ;; + *) AC_CHECK_FUNC([shl_load], - [lt_cv_dlopen="shl_load"], + [lt_cv_dlopen=shl_load], [AC_CHECK_LIB([dld], [shl_load], - [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], + [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld], [AC_CHECK_FUNC([dlopen], - [lt_cv_dlopen="dlopen"], + [lt_cv_dlopen=dlopen], [AC_CHECK_LIB([dl], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], + [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl], [AC_CHECK_LIB([svld], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld], [AC_CHECK_LIB([dld], [dld_link], - [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) + [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld]) ]) ]) ]) @@ -1907,21 +1957,21 @@ else ;; esac - if test "x$lt_cv_dlopen" != xno; then - enable_dlopen=yes - else + if test no = "$lt_cv_dlopen"; then enable_dlopen=no + else + enable_dlopen=yes fi case $lt_cv_dlopen in dlopen) - save_CPPFLAGS="$CPPFLAGS" - test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + save_CPPFLAGS=$CPPFLAGS + test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" - save_LDFLAGS="$LDFLAGS" + save_LDFLAGS=$LDFLAGS wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" - save_LIBS="$LIBS" + save_LIBS=$LIBS LIBS="$lt_cv_dlopen_libs $LIBS" AC_CACHE_CHECK([whether a program can dlopen itself], @@ -1931,7 +1981,7 @@ else lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) ]) - if test "x$lt_cv_dlopen_self" = xyes; then + if test yes = "$lt_cv_dlopen_self"; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" AC_CACHE_CHECK([whether a statically linked program can dlopen itself], lt_cv_dlopen_self_static, [dnl @@ -1941,9 +1991,9 @@ else ]) fi - CPPFLAGS="$save_CPPFLAGS" - LDFLAGS="$save_LDFLAGS" - LIBS="$save_LIBS" + CPPFLAGS=$save_CPPFLAGS + LDFLAGS=$save_LDFLAGS + LIBS=$save_LIBS ;; esac @@ -2035,8 +2085,8 @@ m4_defun([_LT_COMPILER_FILE_LOCKS], m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_COMPILER_C_O([$1]) -hard_links="nottested" -if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then +hard_links=nottested +if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user AC_MSG_CHECKING([if we can lock with hard links]) hard_links=yes @@ -2046,8 +2096,8 @@ if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no AC_MSG_RESULT([$hard_links]) - if test "$hard_links" = no; then - AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) + if test no = "$hard_links"; then + AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe]) need_locks=warn fi else @@ -2074,8 +2124,8 @@ objdir=$lt_cv_objdir _LT_DECL([], [objdir], [0], [The name of the directory that contains temporary libtool files])dnl m4_pattern_allow([LT_OBJDIR])dnl -AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", - [Define to the sub-directory in which libtool stores uninstalled libraries.]) +AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/", + [Define to the sub-directory where libtool stores uninstalled libraries.]) ])# _LT_CHECK_OBJDIR @@ -2087,15 +2137,15 @@ m4_defun([_LT_LINKER_HARDCODE_LIBPATH], _LT_TAGVAR(hardcode_action, $1)= if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || test -n "$_LT_TAGVAR(runpath_var, $1)" || - test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then + test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then # We can hardcode non-existent directories. - if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && + if test no != "$_LT_TAGVAR(hardcode_direct, $1)" && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one - ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && - test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then + ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" && + test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then # Linking always hardcodes the temporary library directory. _LT_TAGVAR(hardcode_action, $1)=relink else @@ -2109,12 +2159,12 @@ else fi AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) -if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || - test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then +if test relink = "$_LT_TAGVAR(hardcode_action, $1)" || + test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then # Fast installation is not supported enable_fast_install=no -elif test "$shlibpath_overrides_runpath" = yes || - test "$enable_shared" = no; then +elif test yes = "$shlibpath_overrides_runpath" || + test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi @@ -2138,7 +2188,7 @@ else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) - if test -n "$STRIP" ; then + if test -n "$STRIP"; then striplib="$STRIP -x" old_striplib="$STRIP -S" AC_MSG_RESULT([yes]) @@ -2169,14 +2219,14 @@ m4_require([_LT_CHECK_SHELL_FEATURES])dnl AC_MSG_CHECKING([dynamic linker characteristics]) m4_if([$1], [], [ -if test "$GCC" = yes; then +if test yes = "$GCC"; then case $host_os in - darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; - *) lt_awk_arg="/^libraries:/" ;; + darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; + *) lt_awk_arg='/^libraries:/' ;; esac case $host_os in - mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;; - *) lt_sed_strip_eq="s,=/,/,g" ;; + mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;; + *) lt_sed_strip_eq='s|=/|/|g' ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in @@ -2192,28 +2242,35 @@ if test "$GCC" = yes; then ;; esac # Ok, now we have the path, separated by spaces, we can step through it - # and add multilib dir if necessary. + # and add multilib dir if necessary... lt_tmp_lt_search_path_spec= - lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + # ...but if some path component already ends with the multilib dir we assume + # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). + case "$lt_multi_os_dir; $lt_search_path_spec " in + "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) + lt_multi_os_dir= + ;; + esac for lt_sys_path in $lt_search_path_spec; do - if test -d "$lt_sys_path/$lt_multi_os_dir"; then - lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" - else + if test -d "$lt_sys_path$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" + elif test -n "$lt_multi_os_dir"; then test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' -BEGIN {RS=" "; FS="/|\n";} { - lt_foo=""; - lt_count=0; +BEGIN {RS = " "; FS = "/|\n";} { + lt_foo = ""; + lt_count = 0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { - lt_foo="/" $lt_i lt_foo; + lt_foo = "/" $lt_i lt_foo; } else { lt_count--; } @@ -2227,7 +2284,7 @@ BEGIN {RS=" "; FS="/|\n";} { # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ - $SED 's,/\([[A-Za-z]]:\),\1,g'` ;; + $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else @@ -2236,7 +2293,7 @@ fi]) library_names_spec= libname_spec='lib$name' soname_spec= -shrext_cmds=".so" +shrext_cmds=.so postinstall_cmds= postuninstall_cmds= finish_cmds= @@ -2256,11 +2313,11 @@ need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + library_names_spec='$libname$release$shared_ext$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. - soname_spec='${libname}${release}${shared_ext}$major' + soname_spec='$libname$release$shared_ext$major' ;; aix[[4-9]]*) @@ -2268,40 +2325,40 @@ aix[[4-9]]*) need_lib_prefix=no need_version=no hardcode_into_libs=yes - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # AIX 5 supports IA64 - library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with - # the line `#! .'. This would cause the generated library to - # depend on `.', always an invalid library. This was fixed in + # the line '#! .'. This would cause the generated library to + # depend on '.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[[01]] | aix4.[[01]].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' - echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac - # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. - if test "$aix_use_runtimelinking" = yes; then + if test yes = "$aix_use_runtimelinking"; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. - library_names_spec='${libname}${release}.a $libname.a' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' fi shlibpath_var=LIBPATH fi @@ -2312,18 +2369,18 @@ amigaos*) powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. - finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) - library_names_spec='${libname}${shared_ext}' + library_names_spec='$libname$shared_ext' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; @@ -2331,8 +2388,8 @@ beos*) bsdi[[45]]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" @@ -2344,7 +2401,7 @@ bsdi[[45]]*) cygwin* | mingw* | pw32* | cegcc*) version_type=windows - shrext_cmds=".dll" + shrext_cmds=.dll need_version=no need_lib_prefix=no @@ -2353,8 +2410,8 @@ cygwin* | mingw* | pw32* | cegcc*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ @@ -2370,17 +2427,17 @@ cygwin* | mingw* | pw32* | cegcc*) case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' - soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix - soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' @@ -2389,8 +2446,8 @@ m4_if([$1], [],[ *,cl*) # Native MSVC libname_spec='$name' - soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - library_names_spec='${libname}.dll.lib' + soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + library_names_spec='$libname.dll.lib' case $build_os in mingw*) @@ -2417,7 +2474,7 @@ m4_if([$1], [],[ sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) - sys_lib_search_path_spec="$LIB" + sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` @@ -2430,8 +2487,8 @@ m4_if([$1], [],[ esac # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' @@ -2444,7 +2501,7 @@ m4_if([$1], [],[ *) # Assume MSVC wrapper - library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' + library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac @@ -2457,8 +2514,8 @@ darwin* | rhapsody*) version_type=darwin need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' - soname_spec='${libname}${release}${major}$shared_ext' + library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' + soname_spec='$libname$release$major$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' @@ -2471,8 +2528,8 @@ dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; @@ -2490,12 +2547,12 @@ freebsd* | dragonfly*) version_type=freebsd-$objformat case $version_type in freebsd-elf*) - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' need_version=no need_lib_prefix=no ;; freebsd-*) - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' need_version=yes ;; esac @@ -2520,26 +2577,15 @@ freebsd* | dragonfly*) esac ;; -gnu*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH - shlibpath_overrides_runpath=yes + shlibpath_overrides_runpath=no sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; @@ -2557,9 +2603,9 @@ hpux9* | hpux10* | hpux11*) dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - if test "X$HPUX_IA64_MODE" = X32; then + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + if test 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" @@ -2572,8 +2618,8 @@ hpux9* | hpux10* | hpux11*) dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; @@ -2582,8 +2628,8 @@ hpux9* | hpux10* | hpux11*) dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... @@ -2596,8 +2642,8 @@ interix[[3-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no @@ -2608,7 +2654,7 @@ irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) - if test "$lt_cv_prog_gnu_ld" = yes; then + if test yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix @@ -2616,8 +2662,8 @@ irix5* | irix6* | nonstopux*) esac need_lib_prefix=no need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= @@ -2636,8 +2682,8 @@ irix5* | irix6* | nonstopux*) esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" + sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" hardcode_into_libs=yes ;; @@ -2646,13 +2692,33 @@ linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; +linux*android*) + version_type=none # Android doesn't support versioned libraries. + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + dynamic_linker='Android linker' + # Don't embed -rpath directories since the linker doesn't support them. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + ;; + # This must be glibc/ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu) +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no @@ -2677,14 +2743,10 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu) # before this can be enabled. hardcode_into_libs=yes - # Add ABI-specific directories to the system library path. - sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib" - # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` - sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra" - + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on @@ -2701,12 +2763,12 @@ netbsd*) need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH @@ -2716,7 +2778,7 @@ netbsd*) newsos6) version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; @@ -2725,45 +2787,34 @@ newsos6) version_type=qnx need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; -openbsd*) +openbsd* | bitrig*) version_type=sunos - sys_lib_dlsearch_path_spec="/usr/lib" + sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no - # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. - case $host_os in - openbsd3.3 | openbsd3.3.*) need_version=yes ;; - *) need_version=no ;; - esac - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - shlibpath_var=LD_LIBRARY_PATH - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - case $host_os in - openbsd2.[[89]] | openbsd2.[[89]].*) - shlibpath_overrides_runpath=no - ;; - *) - shlibpath_overrides_runpath=yes - ;; - esac + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + need_version=no else - shlibpath_overrides_runpath=yes + need_version=yes fi + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' - shrext_cmds=".dll" + shrext_cmds=.dll need_lib_prefix=no - library_names_spec='$libname${shared_ext} $libname.a' + library_names_spec='$libname$shared_ext $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; @@ -2772,11 +2823,11 @@ osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" - sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; rdos*) @@ -2787,8 +2838,8 @@ solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes @@ -2798,11 +2849,11 @@ solaris*) sunos4*) version_type=sunos - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes - if test "$with_gnu_ld" = yes; then + if test yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes @@ -2810,8 +2861,8 @@ sunos4*) sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) @@ -2832,10 +2883,10 @@ sysv4 | sysv4.3*) ;; sysv4*MP*) - if test -d /usr/nec ;then + if test -d /usr/nec; then version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' - soname_spec='$libname${shared_ext}.$major' + library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' + soname_spec='$libname$shared_ext.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; @@ -2844,12 +2895,12 @@ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes - if test "$with_gnu_ld" = yes; then + if test yes = "$with_gnu_ld"; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' @@ -2867,7 +2918,7 @@ tpf*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes @@ -2875,8 +2926,8 @@ tpf*) uts4*) version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; @@ -2885,18 +2936,18 @@ uts4*) ;; esac AC_MSG_RESULT([$dynamic_linker]) -test "$dynamic_linker" = no && can_build_shared=no +test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then +if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi -if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then - sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then + sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi -if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then - sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then + sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi _LT_DECL([], [variables_saved_for_relink], [1], @@ -2938,32 +2989,32 @@ _LT_DECL([], [sys_lib_dlsearch_path_spec], [2], # _LT_PATH_TOOL_PREFIX(TOOL) # -------------------------- -# find a file program which can recognize shared library +# find a file program that can recognize shared library AC_DEFUN([_LT_PATH_TOOL_PREFIX], [m4_require([_LT_DECL_EGREP])dnl AC_MSG_CHECKING([for $1]) AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, [case $MAGIC_CMD in [[\\/*] | ?:[\\/]*]) - lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) - lt_save_MAGIC_CMD="$MAGIC_CMD" - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR dnl $ac_dummy forces splitting on constant user-supplied paths. dnl POSIX.2 word splitting is done only on the output of word expansions, dnl not every word. This closes a longstanding sh security hole. ac_dummy="m4_if([$2], , $PATH, [$2])" for ac_dir in $ac_dummy; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$1; then - lt_cv_path_MAGIC_CMD="$ac_dir/$1" + if test -f "$ac_dir/$1"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"$1" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` - MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : @@ -2986,11 +3037,11 @@ _LT_EOF break fi done - IFS="$lt_save_ifs" - MAGIC_CMD="$lt_save_MAGIC_CMD" + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac]) -MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then AC_MSG_RESULT($MAGIC_CMD) else @@ -3008,7 +3059,7 @@ dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) # _LT_PATH_MAGIC # -------------- -# find a file program which can recognize a shared library +# find a file program that can recognize a shared library m4_defun([_LT_PATH_MAGIC], [_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) if test -z "$lt_cv_path_MAGIC_CMD"; then @@ -3035,16 +3086,16 @@ m4_require([_LT_PROG_ECHO_BACKSLASH])dnl AC_ARG_WITH([gnu-ld], [AS_HELP_STRING([--with-gnu-ld], [assume the C compiler uses GNU ld @<:@default=no@:>@])], - [test "$withval" = no || with_gnu_ld=yes], + [test no = "$withval" || with_gnu_ld=yes], [with_gnu_ld=no])dnl ac_prog=ld -if test "$GCC" = yes; then +if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by $CC]) case $host in *-*-mingw*) - # gcc leaves a trailing carriage return which upsets mingw + # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; @@ -3058,7 +3109,7 @@ if test "$GCC" = yes; then while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done - test -z "$LD" && LD="$ac_prog" + test -z "$LD" && LD=$ac_prog ;; "") # If it fails, then pretend we aren't using GCC. @@ -3069,37 +3120,37 @@ if test "$GCC" = yes; then with_gnu_ld=unknown ;; esac -elif test "$with_gnu_ld" = yes; then +elif test yes = "$with_gnu_ld"; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL(lt_cv_path_LD, [if test -z "$LD"; then - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - lt_cv_path_LD="$ac_dir/$ac_prog" + lt_cv_path_LD=$ac_dir/$ac_prog # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 /dev/null 2>&1; then + if ( file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else @@ -3255,10 +3305,6 @@ freebsd* | dragonfly*) fi ;; -gnu*) - lt_cv_deplibs_check_method=pass_all - ;; - haiku*) lt_cv_deplibs_check_method=pass_all ;; @@ -3297,7 +3343,7 @@ irix5* | irix6* | nonstopux*) ;; # This must be glibc/ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu) +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; @@ -3319,8 +3365,8 @@ newos6*) lt_cv_deplibs_check_method=pass_all ;; -openbsd*) - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then +openbsd* | bitrig*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' @@ -3413,33 +3459,33 @@ AC_DEFUN([LT_PATH_NM], AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, [if test -n "$NM"; then # Let the user override the test. - lt_cv_path_NM="$NM" + lt_cv_path_NM=$NM else - lt_nm_to_check="${ac_tool_prefix}nm" + lt_nm_to_check=${ac_tool_prefix}nm if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. - tmp_nm="$ac_dir/$lt_tmp_nm" - if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + tmp_nm=$ac_dir/$lt_tmp_nm + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then # Check to see if the nm accepts a BSD-compat flag. - # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # Adding the 'sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" - break + break 2 ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" - break + break 2 ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but @@ -3450,21 +3496,21 @@ else esac fi done - IFS="$lt_save_ifs" + IFS=$lt_save_ifs done : ${lt_cv_path_NM=no} fi]) -if test "$lt_cv_path_NM" != "no"; then - NM="$lt_cv_path_NM" +if test no != "$lt_cv_path_NM"; then + NM=$lt_cv_path_NM else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) - case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in + case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in *COFF*) - DUMPBIN="$DUMPBIN -symbols" + DUMPBIN="$DUMPBIN -symbols -headers" ;; *) DUMPBIN=: @@ -3472,8 +3518,8 @@ else esac fi AC_SUBST([DUMPBIN]) - if test "$DUMPBIN" != ":"; then - NM="$DUMPBIN" + if test : != "$DUMPBIN"; then + NM=$DUMPBIN fi fi test -z "$NM" && NM=nm @@ -3519,8 +3565,8 @@ lt_cv_sharedlib_from_linklib_cmd, case $host_os in cygwin* | mingw* | pw32* | cegcc*) - # two different shell functions defined in ltmain.sh - # decide which to use based on capabilities of $DLLTOOL + # two different shell functions defined in ltmain.sh; + # decide which one to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib @@ -3532,7 +3578,7 @@ cygwin* | mingw* | pw32* | cegcc*) ;; *) # fallback: assume linklib IS sharedlib - lt_cv_sharedlib_from_linklib_cmd="$ECHO" + lt_cv_sharedlib_from_linklib_cmd=$ECHO ;; esac ]) @@ -3559,13 +3605,28 @@ AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool lt_cv_path_mainfest_tool=yes fi rm -f conftest*]) -if test "x$lt_cv_path_mainfest_tool" != xyes; then +if test yes != "$lt_cv_path_mainfest_tool"; then MANIFEST_TOOL=: fi _LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl ])# _LT_PATH_MANIFEST_TOOL +# _LT_DLL_DEF_P([FILE]) +# --------------------- +# True iff FILE is a Windows DLL '.def' file. +# Keep in sync with func_dll_def_p in the libtool script +AC_DEFUN([_LT_DLL_DEF_P], +[dnl + test DEF = "`$SED -n dnl + -e '\''s/^[[ ]]*//'\'' dnl Strip leading whitespace + -e '\''/^\(;.*\)*$/d'\'' dnl Delete empty lines and comments + -e '\''s/^\(EXPORTS\|LIBRARY\)\([[ ]].*\)*$/DEF/p'\'' dnl + -e q dnl Only consider the first "real" line + $1`" dnl +])# _LT_DLL_DEF_P + + # LT_LIB_M # -------- # check for math library @@ -3577,11 +3638,11 @@ case $host in # These system don't have libm, or don't need it ;; *-ncr-sysv4.3*) - AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw) AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") ;; *) - AC_CHECK_LIB(m, cos, LIBM="-lm") + AC_CHECK_LIB(m, cos, LIBM=-lm) ;; esac AC_SUBST([LIBM]) @@ -3600,7 +3661,7 @@ m4_defun([_LT_COMPILER_NO_RTTI], _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= -if test "$GCC" = yes; then +if test yes = "$GCC"; then case $cc_basename in nvcc*) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; @@ -3652,7 +3713,7 @@ cygwin* | mingw* | pw32* | cegcc*) symcode='[[ABCDGISTW]]' ;; hpux*) - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then symcode='[[ABCDEGRST]]' fi ;; @@ -3685,14 +3746,44 @@ case `$NM -V 2>&1` in symcode='[[ABCDGIRSTW]]' ;; esac +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Gets list of data symbols to import. + lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" + # Adjust the below global symbol transforms to fixup imported variables. + lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" + lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" + lt_c_name_lib_hook="\ + -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ + -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" +else + # Disable hooks by default. + lt_cv_sys_global_symbol_to_import= + lt_cdecl_hook= + lt_c_name_hook= + lt_c_name_lib_hook= +fi + # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. -lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" +lt_cv_sys_global_symbol_to_cdecl="sed -n"\ +$lt_cdecl_hook\ +" -e 's/^T .* \(.*\)$/extern int \1();/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address -lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ +$lt_c_name_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" + +# Transform an extracted symbol line into symbol name with lib prefix and +# symbol address. +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ +$lt_c_name_lib_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" # Handle CRLF in mingw tool chain opt_cr= @@ -3710,21 +3801,24 @@ for ac_symprfx in "" "_"; do # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then - # Fake it for dumpbin and say T for any non-static function - # and D for any global variable. + # Fake it for dumpbin and say T for any non-static function, + # D for any global variable and I for any imported variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ +" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ +" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ -" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ -" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ -" s[1]~/^[@?]/{print s[1], s[1]; next};"\ -" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ +" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ +" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx]" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" @@ -3764,11 +3858,11 @@ _LT_EOF if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ -#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) -/* DATA imports from DLLs on WIN32 con't be const, because runtime +#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE +/* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT@&t@_DLSYM_CONST -#elif defined(__osf__) +#elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT@&t@_DLSYM_CONST #else @@ -3794,7 +3888,7 @@ lt__PROGRAM__LTX_preloaded_symbols[[]] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF - $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; @@ -3814,9 +3908,9 @@ _LT_EOF mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS - LIBS="conftstm.$ac_objext" + LIBS=conftstm.$ac_objext CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" - if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then + if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS @@ -3837,7 +3931,7 @@ _LT_EOF rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. - if test "$pipe_works" = yes; then + if test yes = "$pipe_works"; then break else lt_cv_sys_global_symbol_pipe= @@ -3864,12 +3958,16 @@ _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], [Take the output of nm and produce a listing of raw symbols and C names]) _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], [Transform the output of nm in a proper C declaration]) +_LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1], + [Transform the output of nm into a list of symbols to manually relocate]) _LT_DECL([global_symbol_to_c_name_address], [lt_cv_sys_global_symbol_to_c_name_address], [1], [Transform the output of nm in a C name address pair]) _LT_DECL([global_symbol_to_c_name_address_lib_prefix], [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], [Transform the output of nm in a C name address pair when lib prefix is needed]) +_LT_DECL([nm_interface], [lt_cv_nm_interface], [1], + [The name lister interface]) _LT_DECL([], [nm_file_list_spec], [1], [Specify filename containing input files for $NM]) ]) # _LT_CMD_GLOBAL_SYMBOLS @@ -3885,17 +3983,18 @@ _LT_TAGVAR(lt_prog_compiler_static, $1)= m4_if([$1], [CXX], [ # C++ specific cases for pic, static, wl, etc. - if test "$GXX" = yes; then + if test yes = "$GXX"; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; amigaos*) @@ -3906,8 +4005,8 @@ m4_if([$1], [CXX], [ ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac @@ -3972,7 +4071,7 @@ m4_if([$1], [CXX], [ case $host_os in aix[[4-9]]*) # All AIX code is PIC. - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else @@ -4013,14 +4112,14 @@ m4_if([$1], [CXX], [ case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' - if test "$host_cpu" != ia64; then + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' + if test ia64 != "$host_cpu"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' fi ;; aCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default @@ -4049,7 +4148,7 @@ m4_if([$1], [CXX], [ ;; esac ;; - linux* | k*bsd*-gnu | kopensolaris*-gnu) + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # KAI C++ Compiler @@ -4057,7 +4156,7 @@ m4_if([$1], [CXX], [ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; ecpc* ) - # old Intel C++ for x86_64 which still supported -KPIC. + # old Intel C++ for x86_64, which still supported -KPIC. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' @@ -4202,17 +4301,18 @@ m4_if([$1], [CXX], [ fi ], [ - if test "$GCC" = yes; then + if test yes = "$GCC"; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; amigaos*) @@ -4223,8 +4323,8 @@ m4_if([$1], [CXX], [ ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac @@ -4311,7 +4411,7 @@ m4_if([$1], [CXX], [ case $host_os in aix*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else @@ -4319,6 +4419,20 @@ m4_if([$1], [CXX], [ fi ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + case $cc_basename in + nagfor*) + # NAG Fortran compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). @@ -4339,7 +4453,7 @@ m4_if([$1], [CXX], [ ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? - _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) @@ -4348,9 +4462,9 @@ m4_if([$1], [CXX], [ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; - linux* | k*bsd*-gnu | kopensolaris*-gnu) + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in - # old Intel for x86_64 which still supported -KPIC. + # old Intel for x86_64, which still supported -KPIC. ecc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' @@ -4375,6 +4489,12 @@ m4_if([$1], [CXX], [ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) @@ -4472,7 +4592,7 @@ m4_if([$1], [CXX], [ ;; sysv4*MP*) - if test -d /usr/nec ;then + if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi @@ -4501,7 +4621,7 @@ m4_if([$1], [CXX], [ fi ]) case $host_os in - # For platforms which do not support PIC, -DPIC is meaningless: + # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; @@ -4577,7 +4697,7 @@ m4_if([$1], [CXX], [ fi ;; pw32*) - _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" + _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds ;; cygwin* | mingw* | cegcc*) case $cc_basename in @@ -4623,9 +4743,9 @@ m4_if([$1], [CXX], [ # included in the symbol list _LT_TAGVAR(include_expsyms, $1)= # exclude_expsyms can be an extended regexp of symbols to exclude - # it will be wrapped by ` (' and `)$', so one must not match beginning or - # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', - # as well as any symbol that contains `d'. + # it will be wrapped by ' (' and ')$', so one must not match beginning or + # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', + # as well as any symbol that contains 'd'. _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if @@ -4641,7 +4761,7 @@ dnl Note also adjust exclude_expsyms for C++ above. # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. - if test "$GCC" != yes; then + if test yes != "$GCC"; then with_gnu_ld=no fi ;; @@ -4649,7 +4769,7 @@ dnl Note also adjust exclude_expsyms for C++ above. # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; - openbsd*) + openbsd* | bitrig*) with_gnu_ld=no ;; esac @@ -4659,7 +4779,7 @@ dnl Note also adjust exclude_expsyms for C++ above. # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no - if test "$with_gnu_ld" = yes; then + if test yes = "$with_gnu_ld"; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility @@ -4681,24 +4801,24 @@ dnl Note also adjust exclude_expsyms for C++ above. esac fi - if test "$lt_use_gnu_ld_interface" = yes; then + if test yes = "$lt_use_gnu_ld_interface"; then # If archive_cmds runs LD, not CC, wlarc should be empty - wlarc='${wl}' + wlarc='$wl' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then - _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi supports_anon_versioning=no - case `$LD -v 2>&1` in + case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... @@ -4711,7 +4831,7 @@ dnl Note also adjust exclude_expsyms for C++ above. case $host_os in aix[[3-9]]*) # On AIX/PPC, the GNU linker is very broken - if test "$host_cpu" != ia64; then + if test ia64 != "$host_cpu"; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 @@ -4730,7 +4850,7 @@ _LT_EOF case $host_cpu in powerpc) # see comment about AmigaOS4 .so support - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) @@ -4746,7 +4866,7 @@ _LT_EOF _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME - _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi @@ -4756,7 +4876,7 @@ _LT_EOF # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes @@ -4764,61 +4884,61 @@ _LT_EOF _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; haiku*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no - if test "$host_os" = linux-dietlibc; then + if test linux-dietlibc = "$host_os"; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ - && test "$tmp_diet" = no + && test no = "$tmp_diet" then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; @@ -4829,42 +4949,44 @@ _LT_EOF lf95*) # Lahey Fortran 8.1 _LT_TAGVAR(whole_archive_flag_spec, $1)= tmp_sharedflag='--shared' ;; + nagfor*) # NAGFOR 5.3 + tmp_sharedflag='-Wl,-shared' ;; xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac - _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - if test "x$supports_anon_versioning" = xyes; then + if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi case $cc_basename in xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' - if test "x$supports_anon_versioning" = xyes; then + if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac @@ -4878,8 +5000,8 @@ _LT_EOF _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' fi ;; @@ -4897,8 +5019,8 @@ _LT_EOF _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi @@ -4910,7 +5032,7 @@ _LT_EOF _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 -*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify @@ -4925,9 +5047,9 @@ _LT_EOF # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi @@ -4944,15 +5066,15 @@ _LT_EOF *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac - if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then + if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then runpath_var= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= @@ -4968,7 +5090,7 @@ _LT_EOF # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. _LT_TAGVAR(hardcode_minus_L, $1)=yes - if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. _LT_TAGVAR(hardcode_direct, $1)=unsupported @@ -4976,12 +5098,12 @@ _LT_EOF ;; aix[[4-9]]*) - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' - no_entry_flag="" + no_entry_flag= else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm @@ -4999,7 +5121,7 @@ _LT_EOF # need to do runtime linking. case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do - if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then aix_use_runtimelinking=yes break fi @@ -5022,13 +5144,13 @@ _LT_EOF _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' + _LT_TAGVAR(file_list_spec, $1)='$wl-f,' - if test "$GCC" = yes; then + if test yes = "$GCC"; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` + collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then @@ -5047,61 +5169,61 @@ _LT_EOF ;; esac shared_flag='-shared' - if test "$aix_use_runtimelinking" = yes; then - shared_flag="$shared_flag "'${wl}-G' + if test yes = "$aix_use_runtimelinking"; then + shared_flag="$shared_flag "'$wl-G' fi else # not using gcc - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' else - shared_flag='${wl}-bM:SRE' + shared_flag='$wl-bM:SRE' fi fi fi - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. _LT_TAGVAR(always_export_symbols, $1)=yes - if test "$aix_use_runtimelinking" = yes; then + if test yes = "$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else - if test "$host_cpu" = ia64; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + if test ia64 = "$host_cpu"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' - if test "$with_gnu_ld" = yes; then + _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' + if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared libraries. - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $wl-bnoentry $compiler_flags $wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; @@ -5110,7 +5232,7 @@ _LT_EOF case $host_cpu in powerpc) # see comment about AmigaOS4 .so support - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) @@ -5140,16 +5262,17 @@ _LT_EOF # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" + shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. - _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; - else - sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; - fi~ - $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ - linknames=' + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes @@ -5158,18 +5281,18 @@ _LT_EOF # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ - lt_tool_outputfile="@TOOL_OUTPUT@"~ - case $lt_outputfile in - *.exe|*.EXE) ;; - *) - lt_outputfile="$lt_outputfile.exe" - lt_tool_outputfile="$lt_tool_outputfile.exe" - ;; - esac~ - if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then - $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; - $RM "$lt_outputfile.manifest"; - fi' + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' ;; *) # Assume MSVC wrapper @@ -5178,7 +5301,7 @@ _LT_EOF # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" + shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. @@ -5228,33 +5351,33 @@ _LT_EOF ;; hpux9*) - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ;; hpux10*) - if test "$GCC" = yes && test "$with_gnu_ld" = no; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + if test yes,no = "$GCC,$with_gnu_ld"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi - if test "$with_gnu_ld" = no; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes @@ -5262,25 +5385,25 @@ _LT_EOF ;; hpux11*) - if test "$GCC" = yes && test "$with_gnu_ld" = no; then + if test yes,no = "$GCC,$with_gnu_ld"; then case $host_cpu in hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) m4_if($1, [], [ @@ -5288,14 +5411,14 @@ _LT_EOF # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) _LT_LINKER_OPTION([if $CC understands -b], _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], - [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], - [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) + [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) ;; esac fi - if test "$with_gnu_ld" = no; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in @@ -5306,7 +5429,7 @@ _LT_EOF *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. @@ -5317,16 +5440,16 @@ _LT_EOF ;; irix5* | irix6* | nonstopux*) - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], [lt_cv_irix_exported_symbol], - [save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + [save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" AC_LINK_IFELSE( [AC_LANG_SOURCE( [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], @@ -5339,16 +5462,16 @@ _LT_EOF end]])])], [lt_cv_irix_exported_symbol=yes], [lt_cv_irix_exported_symbol=no]) - LDFLAGS="$save_LDFLAGS"]) - if test "$lt_cv_irix_exported_symbol" = yes; then - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + LDFLAGS=$save_LDFLAGS]) + if test yes = "$lt_cv_irix_exported_symbol"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' fi else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes _LT_TAGVAR(link_all_deplibs, $1)=yes @@ -5368,7 +5491,7 @@ _LT_EOF newsos6) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; @@ -5376,27 +5499,19 @@ _LT_EOF *nto* | *qnx*) ;; - openbsd*) + openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' else - case $host_os in - openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - ;; - esac + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' fi else _LT_TAGVAR(ld_shlibs, $1)=no @@ -5412,28 +5527,28 @@ _LT_EOF ;; osf3*) - if test "$GCC" = yes; then - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + if test yes = "$GCC"; then + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag - if test "$GCC" = yes; then - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + if test yes = "$GCC"; then + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ - $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' @@ -5444,24 +5559,24 @@ _LT_EOF solaris*) _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' - if test "$GCC" = yes; then - wlarc='${wl}' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + if test yes = "$GCC"; then + wlarc='$wl' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' - _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) - wlarc='${wl}' - _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' + wlarc='$wl' + _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi @@ -5471,11 +5586,11 @@ _LT_EOF solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, - # but understands `-z linker_flag'. GCC discards it without `$wl', + # but understands '-z linker_flag'. GCC discards it without '$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) - if test "$GCC" = yes; then - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + if test yes = "$GCC"; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' else _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' fi @@ -5485,10 +5600,10 @@ _LT_EOF ;; sunos4*) - if test "x$host_vendor" = xsequent; then + if test sequent = "$host_vendor"; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi @@ -5537,43 +5652,43 @@ _LT_EOF ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) - # Note: We can NOT use -z defs as we might desire, because we do not + # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' - _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' runpath_var='LD_RUN_PATH' - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; @@ -5588,17 +5703,17 @@ _LT_EOF ;; esac - if test x$host_vendor = xsni; then + if test sni = "$host_vendor"; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym' ;; esac fi fi ]) AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) -test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no +test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no _LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld @@ -5615,7 +5730,7 @@ x|xyes) # Assume -lc should be added _LT_TAGVAR(archive_cmds_need_lc, $1)=yes - if test "$enable_shared" = yes && test "$GCC" = yes; then + if test yes,yes = "$GCC,$enable_shared"; then case $_LT_TAGVAR(archive_cmds, $1) in *'~'*) # FIXME: we may have to deal with multi-command sequences. @@ -5695,12 +5810,12 @@ _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], _LT_TAGDECL([], [hardcode_libdir_separator], [1], [Whether we need a single "-rpath" flag with a separated argument]) _LT_TAGDECL([], [hardcode_direct], [0], - [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes + [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_direct_absolute], [0], - [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes + [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes DIR into the resulting binary and the resulting library dependency is - "absolute", i.e impossible to change by setting ${shlibpath_var} if the + "absolute", i.e impossible to change by setting $shlibpath_var if the library is relocated]) _LT_TAGDECL([], [hardcode_minus_L], [0], [Set to "yes" if using the -LDIR flag during linking hardcodes DIR @@ -5741,10 +5856,10 @@ dnl [Compiler flag to generate thread safe objects]) # ------------------------ # Ensure that the configuration variables for a C compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write -# the compiler configuration to `libtool'. +# the compiler configuration to 'libtool'. m4_defun([_LT_LANG_C_CONFIG], [m4_require([_LT_DECL_EGREP])dnl -lt_save_CC="$CC" +lt_save_CC=$CC AC_LANG_PUSH(C) # Source file extension for C test sources. @@ -5784,18 +5899,18 @@ if test -n "$compiler"; then LT_SYS_DLOPEN_SELF _LT_CMD_STRIPLIB - # Report which library types will actually be built + # Report what library types will actually be built AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) - test "$can_build_shared" = "no" && enable_shared=no + test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) - test "$enable_shared" = yes && enable_static=no + test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' @@ -5803,8 +5918,8 @@ if test -n "$compiler"; then ;; aix[[4-9]]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no + if test ia64 != "$host_cpu" && test no = "$aix_use_runtimelinking"; then + test yes = "$enable_shared" && enable_static=no fi ;; esac @@ -5812,13 +5927,13 @@ if test -n "$compiler"; then AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes + test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_CONFIG($1) fi AC_LANG_POP -CC="$lt_save_CC" +CC=$lt_save_CC ])# _LT_LANG_C_CONFIG @@ -5826,14 +5941,14 @@ CC="$lt_save_CC" # -------------------------- # Ensure that the configuration variables for a C++ compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write -# the compiler configuration to `libtool'. +# the compiler configuration to 'libtool'. m4_defun([_LT_LANG_CXX_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl -if test -n "$CXX" && ( test "X$CXX" != "Xno" && - ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || - (test "X$CXX" != "Xg++"))) ; then +if test -n "$CXX" && ( test no != "$CXX" && + ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || + (test g++ != "$CXX"))); then AC_PROG_CXXCPP else _lt_caught_CXX_error=yes @@ -5875,7 +5990,7 @@ _LT_TAGVAR(objext, $1)=$objext # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. -if test "$_lt_caught_CXX_error" != yes; then +if test yes != "$_lt_caught_CXX_error"; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" @@ -5917,35 +6032,35 @@ if test "$_lt_caught_CXX_error" != yes; then if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately - if test "$GXX" = yes; then + if test yes = "$GXX"; then _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' else _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= fi - if test "$GXX" = yes; then + if test yes = "$GXX"; then # Set up default GNU C++ configuration LT_PATH_LD # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. - if test "$with_gnu_ld" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + if test yes = "$with_gnu_ld"; then + _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) - wlarc='${wl}' + wlarc='$wl' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then - _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi @@ -5981,12 +6096,12 @@ if test "$_lt_caught_CXX_error" != yes; then _LT_TAGVAR(ld_shlibs, $1)=no ;; aix[[4-9]]*) - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' - no_entry_flag="" + no_entry_flag= else aix_use_runtimelinking=no @@ -6020,13 +6135,13 @@ if test "$_lt_caught_CXX_error" != yes; then _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' + _LT_TAGVAR(file_list_spec, $1)='$wl-f,' - if test "$GXX" = yes; then + if test yes = "$GXX"; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` + collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then @@ -6044,56 +6159,56 @@ if test "$_lt_caught_CXX_error" != yes; then fi esac shared_flag='-shared' - if test "$aix_use_runtimelinking" = yes; then - shared_flag="$shared_flag "'${wl}-G' + if test yes = "$aix_use_runtimelinking"; then + shared_flag=$shared_flag' $wl-G' fi else # not using gcc - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' else - shared_flag='${wl}-bM:SRE' + shared_flag='$wl-bM:SRE' fi fi fi - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. _LT_TAGVAR(always_export_symbols, $1)=yes - if test "$aix_use_runtimelinking" = yes; then + if test yes = "$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an empty # executable. _LT_SYS_MODULE_PATH_AIX([$1]) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else - if test "$host_cpu" = ia64; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + if test ia64 = "$host_cpu"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' - if test "$with_gnu_ld" = yes; then + _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' + if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' @@ -6101,7 +6216,7 @@ if test "$_lt_caught_CXX_error" != yes; then _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared # libraries. - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $wl-bnoentry $compiler_flags $wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; @@ -6111,7 +6226,7 @@ if test "$_lt_caught_CXX_error" != yes; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME - _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi @@ -6139,57 +6254,58 @@ if test "$_lt_caught_CXX_error" != yes; then # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" + shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. - _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; - else - $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; - fi~ - $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ - linknames=' + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ - lt_tool_outputfile="@TOOL_OUTPUT@"~ - case $lt_outputfile in - *.exe|*.EXE) ;; - *) - lt_outputfile="$lt_outputfile.exe" - lt_tool_outputfile="$lt_tool_outputfile.exe" - ;; - esac~ - func_to_tool_file "$lt_outputfile"~ - if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then - $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; - $RM "$lt_outputfile.manifest"; - fi' + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi @@ -6234,18 +6350,15 @@ if test "$_lt_caught_CXX_error" != yes; then _LT_TAGVAR(ld_shlibs, $1)=yes ;; - gnu*) - ;; - haiku*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; hpux9*) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default @@ -6257,7 +6370,7 @@ if test "$_lt_caught_CXX_error" != yes; then _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. @@ -6266,11 +6379,11 @@ if test "$_lt_caught_CXX_error" != yes; then # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) - if test "$GXX" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + if test yes = "$GXX"; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no @@ -6280,15 +6393,15 @@ if test "$_lt_caught_CXX_error" != yes; then ;; hpux10*|hpux11*) - if test $with_gnu_ld = no; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) ;; *) - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ;; esac fi @@ -6314,13 +6427,13 @@ if test "$_lt_caught_CXX_error" != yes; then aCC*) case $host_cpu in hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists @@ -6331,20 +6444,20 @@ if test "$_lt_caught_CXX_error" != yes; then # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) - if test "$GXX" = yes; then - if test $with_gnu_ld = no; then + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then case $host_cpu in hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi @@ -6359,22 +6472,22 @@ if test "$_lt_caught_CXX_error" != yes; then interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is @@ -6383,22 +6496,22 @@ if test "$_lt_caught_CXX_error" != yes; then _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) - if test "$GXX" = yes; then - if test "$with_gnu_ld" = no; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' fi fi _LT_TAGVAR(link_all_deplibs, $1)=yes ;; esac - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes ;; - linux* | k*bsd*-gnu | kopensolaris*-gnu) + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler @@ -6406,8 +6519,8 @@ if test "$_lt_caught_CXX_error" != yes; then # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. - _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. @@ -6416,10 +6529,10 @@ if test "$_lt_caught_CXX_error" != yes; then # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. @@ -6433,59 +6546,59 @@ if test "$_lt_caught_CXX_error" != yes; then # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac - _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ - compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ - $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ - $RANLIB $oldlib' + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ - $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ - $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' ;; cxx*) # Compaq C++ - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' @@ -6499,18 +6612,18 @@ if test "$_lt_caught_CXX_error" != yes; then # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi ;; *) @@ -6518,10 +6631,10 @@ if test "$_lt_caught_CXX_error" != yes; then *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' - _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' + _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes # Not sure whether something based on @@ -6579,22 +6692,17 @@ if test "$_lt_caught_CXX_error" != yes; then _LT_TAGVAR(ld_shlibs, $1)=yes ;; - openbsd2*) - # C++ shared libraries are fairly broken - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - openbsd*) + openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else @@ -6610,9 +6718,9 @@ if test "$_lt_caught_CXX_error" != yes; then # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. - _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Archives containing C++ object files must be created using @@ -6630,17 +6738,17 @@ if test "$_lt_caught_CXX_error" != yes; then cxx*) case $host in osf3*) - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ;; *) _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ - echo "-hidden">> $lib.exp~ - $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ - $RM $lib.exp' + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ + $RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ;; esac @@ -6655,21 +6763,21 @@ if test "$_lt_caught_CXX_error" != yes; then # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + if test yes,no = "$GXX,$with_gnu_ld"; then + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' case $host in osf3*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; esac - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists @@ -6715,9 +6823,9 @@ if test "$_lt_caught_CXX_error" != yes; then # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' - _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no @@ -6725,7 +6833,7 @@ if test "$_lt_caught_CXX_error" != yes; then solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, - # but understands `-z linker_flag'. + # but understands '-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; @@ -6742,30 +6850,30 @@ if test "$_lt_caught_CXX_error" != yes; then ;; gcx*) # Green Hills C++ Compiler - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' + if test yes,no = "$GXX,$with_gnu_ld"; then + _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else - # g++ 2.7 appears to require `-G' NOT `-shared' on this + # g++ 2.7 appears to require '-G' NOT '-shared' on this # platform. - _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when @@ -6773,11 +6881,11 @@ if test "$_lt_caught_CXX_error" != yes; then output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir' case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' ;; esac fi @@ -6786,52 +6894,52 @@ if test "$_lt_caught_CXX_error" != yes; then ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) - # Note: We can NOT use -z defs as we might desire, because we do not + # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' - _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ - '"$_LT_TAGVAR(old_archive_cmds, $1)" + '"$_LT_TAGVAR(old_archive_cmds, $1)" _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ - '"$_LT_TAGVAR(reload_cmds, $1)" + '"$_LT_TAGVAR(reload_cmds, $1)" ;; *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; @@ -6862,10 +6970,10 @@ if test "$_lt_caught_CXX_error" != yes; then esac AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) - test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no - _LT_TAGVAR(GCC, $1)="$GXX" - _LT_TAGVAR(LD, $1)="$LD" + _LT_TAGVAR(GCC, $1)=$GXX + _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change @@ -6892,7 +7000,7 @@ if test "$_lt_caught_CXX_error" != yes; then lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld -fi # test "$_lt_caught_CXX_error" != yes +fi # test yes != "$_lt_caught_CXX_error" AC_LANG_POP ])# _LT_LANG_CXX_CONFIG @@ -6914,9 +7022,9 @@ AC_REQUIRE([_LT_DECL_SED]) AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) func_stripname_cnf () { - case ${2} in - .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; - *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; + case @S|@2 in + .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;; + *) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;; esac } # func_stripname_cnf ])# _LT_FUNC_STRIPNAME_CNF @@ -7004,13 +7112,13 @@ if AC_TRY_EVAL(ac_compile); then pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do - case ${prev}${p} in + case $prev$p in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. - if test $p = "-L" || - test $p = "-R"; then + if test x-L = "$p" || + test x-R = "$p"; then prev=$p continue fi @@ -7026,16 +7134,16 @@ if AC_TRY_EVAL(ac_compile); then case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac - if test "$pre_test_object_deps_done" = no; then - case ${prev} in + if test no = "$pre_test_object_deps_done"; then + case $prev in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then - _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" + _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p else - _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" + _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p" fi ;; # The "-l" case would never come before the object being @@ -7043,9 +7151,9 @@ if AC_TRY_EVAL(ac_compile); then esac else if test -z "$_LT_TAGVAR(postdeps, $1)"; then - _LT_TAGVAR(postdeps, $1)="${prev}${p}" + _LT_TAGVAR(postdeps, $1)=$prev$p else - _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" + _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p" fi fi prev= @@ -7060,15 +7168,15 @@ if AC_TRY_EVAL(ac_compile); then continue fi - if test "$pre_test_object_deps_done" = no; then + if test no = "$pre_test_object_deps_done"; then if test -z "$_LT_TAGVAR(predep_objects, $1)"; then - _LT_TAGVAR(predep_objects, $1)="$p" + _LT_TAGVAR(predep_objects, $1)=$p else _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" fi else if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then - _LT_TAGVAR(postdep_objects, $1)="$p" + _LT_TAGVAR(postdep_objects, $1)=$p else _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" fi @@ -7115,7 +7223,7 @@ linux*) ;; esac - if test "$solaris_use_stlport4" != yes; then + if test yes != "$solaris_use_stlport4"; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; @@ -7138,7 +7246,7 @@ solaris*) # Adding this requires a known-good setup of shared libraries for # Sun compiler versions before 5.6, else PIC objects from an old # archive will be linked into the output, leading to subtle bugs. - if test "$solaris_use_stlport4" != yes; then + if test yes != "$solaris_use_stlport4"; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; @@ -7152,7 +7260,7 @@ case " $_LT_TAGVAR(postdeps, $1) " in esac _LT_TAGVAR(compiler_lib_search_dirs, $1)= if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then - _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` + _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'` fi _LT_TAGDECL([], [compiler_lib_search_dirs], [1], [The directories searched by this compiler when creating a shared library]) @@ -7172,10 +7280,10 @@ _LT_TAGDECL([], [compiler_lib_search_path], [1], # -------------------------- # Ensure that the configuration variables for a Fortran 77 compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. +# to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_F77_CONFIG], [AC_LANG_PUSH(Fortran 77) -if test -z "$F77" || test "X$F77" = "Xno"; then +if test -z "$F77" || test no = "$F77"; then _lt_disable_F77=yes fi @@ -7212,7 +7320,7 @@ _LT_TAGVAR(objext, $1)=$objext # the F77 compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. -if test "$_lt_disable_F77" != yes; then +if test yes != "$_lt_disable_F77"; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t @@ -7234,7 +7342,7 @@ if test "$_lt_disable_F77" != yes; then _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. - lt_save_CC="$CC" + lt_save_CC=$CC lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${F77-"f77"} @@ -7248,21 +7356,21 @@ if test "$_lt_disable_F77" != yes; then AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) - test "$can_build_shared" = "no" && enable_shared=no + test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) - test "$enable_shared" = yes && enable_static=no + test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no + if test ia64 != "$host_cpu" && test no = "$aix_use_runtimelinking"; then + test yes = "$enable_shared" && enable_static=no fi ;; esac @@ -7270,11 +7378,11 @@ if test "$_lt_disable_F77" != yes; then AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes + test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) - _LT_TAGVAR(GCC, $1)="$G77" - _LT_TAGVAR(LD, $1)="$LD" + _LT_TAGVAR(GCC, $1)=$G77 + _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change @@ -7291,9 +7399,9 @@ if test "$_lt_disable_F77" != yes; then fi # test -n "$compiler" GCC=$lt_save_GCC - CC="$lt_save_CC" - CFLAGS="$lt_save_CFLAGS" -fi # test "$_lt_disable_F77" != yes + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS +fi # test yes != "$_lt_disable_F77" AC_LANG_POP ])# _LT_LANG_F77_CONFIG @@ -7303,11 +7411,11 @@ AC_LANG_POP # ------------------------- # Ensure that the configuration variables for a Fortran compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. +# to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_FC_CONFIG], [AC_LANG_PUSH(Fortran) -if test -z "$FC" || test "X$FC" = "Xno"; then +if test -z "$FC" || test no = "$FC"; then _lt_disable_FC=yes fi @@ -7344,7 +7452,7 @@ _LT_TAGVAR(objext, $1)=$objext # the FC compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. -if test "$_lt_disable_FC" != yes; then +if test yes != "$_lt_disable_FC"; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t @@ -7366,7 +7474,7 @@ if test "$_lt_disable_FC" != yes; then _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. - lt_save_CC="$CC" + lt_save_CC=$CC lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${FC-"f95"} @@ -7382,21 +7490,21 @@ if test "$_lt_disable_FC" != yes; then AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) - test "$can_build_shared" = "no" && enable_shared=no + test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) - test "$enable_shared" = yes && enable_static=no + test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no + if test ia64 != "$host_cpu" && test no = "$aix_use_runtimelinking"; then + test yes = "$enable_shared" && enable_static=no fi ;; esac @@ -7404,11 +7512,11 @@ if test "$_lt_disable_FC" != yes; then AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes + test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) - _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" - _LT_TAGVAR(LD, $1)="$LD" + _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu + _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change @@ -7428,7 +7536,7 @@ if test "$_lt_disable_FC" != yes; then GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS -fi # test "$_lt_disable_FC" != yes +fi # test yes != "$_lt_disable_FC" AC_LANG_POP ])# _LT_LANG_FC_CONFIG @@ -7438,7 +7546,7 @@ AC_LANG_POP # -------------------------- # Ensure that the configuration variables for the GNU Java Compiler compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. +# to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_GCJ_CONFIG], [AC_REQUIRE([LT_PROG_GCJ])dnl AC_LANG_SAVE @@ -7472,7 +7580,7 @@ CC=${GCJ-"gcj"} CFLAGS=$GCJFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC -_LT_TAGVAR(LD, $1)="$LD" +_LT_TAGVAR(LD, $1)=$LD _LT_CC_BASENAME([$compiler]) # GCJ did not exist at the time GCC didn't implicitly link libc in. @@ -7509,7 +7617,7 @@ CFLAGS=$lt_save_CFLAGS # -------------------------- # Ensure that the configuration variables for the GNU Go compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. +# to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_GO_CONFIG], [AC_REQUIRE([LT_PROG_GO])dnl AC_LANG_SAVE @@ -7543,7 +7651,7 @@ CC=${GOC-"gccgo"} CFLAGS=$GOFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC -_LT_TAGVAR(LD, $1)="$LD" +_LT_TAGVAR(LD, $1)=$LD _LT_CC_BASENAME([$compiler]) # Go did not exist at the time GCC didn't implicitly link libc in. @@ -7580,7 +7688,7 @@ CFLAGS=$lt_save_CFLAGS # ------------------------- # Ensure that the configuration variables for the Windows resource compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. +# to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_RC_CONFIG], [AC_REQUIRE([LT_PROG_RC])dnl AC_LANG_SAVE @@ -7596,7 +7704,7 @@ _LT_TAGVAR(objext, $1)=$objext lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' # Code to be used in simple link tests -lt_simple_link_test_code="$lt_simple_compile_test_code" +lt_simple_link_test_code=$lt_simple_compile_test_code # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER @@ -7606,7 +7714,7 @@ _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. -lt_save_CC="$CC" +lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC= @@ -7635,7 +7743,7 @@ AC_DEFUN([LT_PROG_GCJ], [m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], [AC_CHECK_TOOL(GCJ, gcj,) - test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" + test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2" AC_SUBST(GCJFLAGS)])])[]dnl ]) @@ -7746,7 +7854,7 @@ lt_ac_count=0 # Add /usr/xpg4/bin/sed as it is typically found on Solaris # along with /bin/sed that truncates output. for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do - test ! -f $lt_ac_sed && continue + test ! -f "$lt_ac_sed" && continue cat /dev/null > conftest.in lt_ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >conftest.in @@ -7763,9 +7871,9 @@ for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break cmp -s conftest.out conftest.nl || break # 10000 chars as input seems more than enough - test $lt_ac_count -gt 10 && break + test 10 -lt "$lt_ac_count" && break lt_ac_count=`expr $lt_ac_count + 1` - if test $lt_ac_count -gt $lt_ac_max; then + if test "$lt_ac_count" -gt "$lt_ac_max"; then lt_ac_max=$lt_ac_count lt_cv_path_SED=$lt_ac_sed fi @@ -7789,27 +7897,7 @@ dnl AC_DEFUN([LT_AC_PROG_SED], []) # Find out whether the shell is Bourne or XSI compatible, # or has some other useful features. m4_defun([_LT_CHECK_SHELL_FEATURES], -[AC_MSG_CHECKING([whether the shell understands some XSI constructs]) -# Try some XSI features -xsi_shell=no -( _lt_dummy="a/b/c" - test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ - = c,a/b,b/c, \ - && eval 'test $(( 1 + 1 )) -eq 2 \ - && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ - && xsi_shell=yes -AC_MSG_RESULT([$xsi_shell]) -_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) - -AC_MSG_CHECKING([whether the shell understands "+="]) -lt_shell_append=no -( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ - >/dev/null 2>&1 \ - && lt_shell_append=yes -AC_MSG_RESULT([$lt_shell_append]) -_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) - -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then +[if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false @@ -7833,102 +7921,9 @@ _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl ])# _LT_CHECK_SHELL_FEATURES -# _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY) -# ------------------------------------------------------ -# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and -# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY. -m4_defun([_LT_PROG_FUNCTION_REPLACE], -[dnl { -sed -e '/^$1 ()$/,/^} # $1 /c\ -$1 ()\ -{\ -m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1]) -} # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: -]) - - -# _LT_PROG_REPLACE_SHELLFNS -# ------------------------- -# Replace existing portable implementations of several shell functions with -# equivalent extended shell implementations where those features are available.. -m4_defun([_LT_PROG_REPLACE_SHELLFNS], -[if test x"$xsi_shell" = xyes; then - _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl - case ${1} in - */*) func_dirname_result="${1%/*}${2}" ;; - * ) func_dirname_result="${3}" ;; - esac]) - - _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl - func_basename_result="${1##*/}"]) - - _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl - case ${1} in - */*) func_dirname_result="${1%/*}${2}" ;; - * ) func_dirname_result="${3}" ;; - esac - func_basename_result="${1##*/}"]) - - _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl - # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are - # positional parameters, so assign one to ordinary parameter first. - func_stripname_result=${3} - func_stripname_result=${func_stripname_result#"${1}"} - func_stripname_result=${func_stripname_result%"${2}"}]) - - _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl - func_split_long_opt_name=${1%%=*} - func_split_long_opt_arg=${1#*=}]) - - _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl - func_split_short_opt_arg=${1#??} - func_split_short_opt_name=${1%"$func_split_short_opt_arg"}]) - - _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl - case ${1} in - *.lo) func_lo2o_result=${1%.lo}.${objext} ;; - *) func_lo2o_result=${1} ;; - esac]) - - _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo]) - - _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))]) - - _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}]) -fi - -if test x"$lt_shell_append" = xyes; then - _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"]) - - _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl - func_quote_for_eval "${2}" -dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \ - eval "${1}+=\\\\ \\$func_quote_for_eval_result"]) - - # Save a `func_append' function call where possible by direct use of '+=' - sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") - test 0 -eq $? || _lt_function_replace_fail=: -else - # Save a `func_append' function call even when '+=' is not available - sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") - test 0 -eq $? || _lt_function_replace_fail=: -fi - -if test x"$_lt_function_replace_fail" = x":"; then - AC_MSG_WARN([Unable to substitute extended shell functions in $ofile]) -fi -]) - # _LT_PATH_CONVERSION_FUNCTIONS # ----------------------------- -# Determine which file name conversion functions should be used by +# Determine what file name conversion functions should be used by # func_to_host_file (and, implicitly, by func_to_host_path). These are needed # for certain cross-compile configurations and native mingw. m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], diff --git a/Modules/_ctypes/libffi/m4/ltoptions.m4 b/Modules/_ctypes/libffi/m4/ltoptions.m4 index 5d9acd8e23bc..50c77236c688 100644 --- a/Modules/_ctypes/libffi/m4/ltoptions.m4 +++ b/Modules/_ctypes/libffi/m4/ltoptions.m4 @@ -1,14 +1,14 @@ # Helper functions for option handling. -*- Autoconf -*- # -# Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, -# Inc. +# Copyright (C) 2004-2005, 2007-2009, 2011-2013 Free Software +# Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. -# serial 7 ltoptions.m4 +# serial 8 ltoptions.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) @@ -29,7 +29,7 @@ m4_define([_LT_SET_OPTION], [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), _LT_MANGLE_DEFUN([$1], [$2]), - [m4_warning([Unknown $1 option `$2'])])[]dnl + [m4_warning([Unknown $1 option '$2'])])[]dnl ]) @@ -75,13 +75,13 @@ m4_if([$1],[LT_INIT],[ dnl dnl If no reference was made to various pairs of opposing options, then dnl we run the default mode handler for the pair. For example, if neither - dnl `shared' nor `disable-shared' was passed, we enable building of shared + dnl 'shared' nor 'disable-shared' was passed, we enable building of shared dnl archives by default: _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], - [_LT_ENABLE_FAST_INSTALL]) + [_LT_ENABLE_FAST_INSTALL]) ]) ])# _LT_SET_OPTIONS @@ -112,7 +112,7 @@ AU_DEFUN([AC_LIBTOOL_DLOPEN], [_LT_SET_OPTION([LT_INIT], [dlopen]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you -put the `dlopen' option into LT_INIT's first parameter.]) +put the 'dlopen' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: @@ -148,7 +148,7 @@ AU_DEFUN([AC_LIBTOOL_WIN32_DLL], _LT_SET_OPTION([LT_INIT], [win32-dll]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you -put the `win32-dll' option into LT_INIT's first parameter.]) +put the 'win32-dll' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: @@ -157,9 +157,9 @@ dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) # _LT_ENABLE_SHARED([DEFAULT]) # ---------------------------- -# implement the --enable-shared flag, and supports the `shared' and -# `disable-shared' LT_INIT options. -# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +# implement the --enable-shared flag, and supports the 'shared' and +# 'disable-shared' LT_INIT options. +# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_SHARED], [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([shared], @@ -172,14 +172,14 @@ AC_ARG_ENABLE([shared], *) enable_shared=no # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_shared=yes fi done - IFS="$lt_save_ifs" + IFS=$lt_save_ifs ;; esac], [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) @@ -211,9 +211,9 @@ dnl AC_DEFUN([AM_DISABLE_SHARED], []) # _LT_ENABLE_STATIC([DEFAULT]) # ---------------------------- -# implement the --enable-static flag, and support the `static' and -# `disable-static' LT_INIT options. -# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +# implement the --enable-static flag, and support the 'static' and +# 'disable-static' LT_INIT options. +# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_STATIC], [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([static], @@ -226,14 +226,14 @@ AC_ARG_ENABLE([static], *) enable_static=no # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_static=yes fi done - IFS="$lt_save_ifs" + IFS=$lt_save_ifs ;; esac], [enable_static=]_LT_ENABLE_STATIC_DEFAULT) @@ -265,9 +265,9 @@ dnl AC_DEFUN([AM_DISABLE_STATIC], []) # _LT_ENABLE_FAST_INSTALL([DEFAULT]) # ---------------------------------- -# implement the --enable-fast-install flag, and support the `fast-install' -# and `disable-fast-install' LT_INIT options. -# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +# implement the --enable-fast-install flag, and support the 'fast-install' +# and 'disable-fast-install' LT_INIT options. +# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_FAST_INSTALL], [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([fast-install], @@ -280,14 +280,14 @@ AC_ARG_ENABLE([fast-install], *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done - IFS="$lt_save_ifs" + IFS=$lt_save_ifs ;; esac], [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) @@ -304,14 +304,14 @@ AU_DEFUN([AC_ENABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put -the `fast-install' option into LT_INIT's first parameter.]) +the 'fast-install' option into LT_INIT's first parameter.]) ]) AU_DEFUN([AC_DISABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], [disable-fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put -the `disable-fast-install' option into LT_INIT's first parameter.]) +the 'disable-fast-install' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: @@ -321,9 +321,9 @@ dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) # _LT_WITH_PIC([MODE]) # -------------------- -# implement the --with-pic flag, and support the `pic-only' and `no-pic' +# implement the --with-pic flag, and support the 'pic-only' and 'no-pic' # LT_INIT options. -# MODE is either `yes' or `no'. If omitted, it defaults to `both'. +# MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'. m4_define([_LT_WITH_PIC], [AC_ARG_WITH([pic], [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], @@ -334,19 +334,17 @@ m4_define([_LT_WITH_PIC], *) pic_mode=default # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for lt_pkg in $withval; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done - IFS="$lt_save_ifs" + IFS=$lt_save_ifs ;; esac], - [pic_mode=default]) - -test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) + [pic_mode=m4_default([$1], [default])]) _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl ])# _LT_WITH_PIC @@ -359,7 +357,7 @@ AU_DEFUN([AC_LIBTOOL_PICMODE], [_LT_SET_OPTION([LT_INIT], [pic-only]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you -put the `pic-only' option into LT_INIT's first parameter.]) +put the 'pic-only' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: diff --git a/Modules/_ctypes/libffi/m4/ltsugar.m4 b/Modules/_ctypes/libffi/m4/ltsugar.m4 index 9000a057d31d..7cbc638b699a 100644 --- a/Modules/_ctypes/libffi/m4/ltsugar.m4 +++ b/Modules/_ctypes/libffi/m4/ltsugar.m4 @@ -1,6 +1,7 @@ # ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # -# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. +# Copyright (C) 2004-2005, 2007-2008, 2011-2013 Free Software +# Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives @@ -33,7 +34,7 @@ m4_define([_lt_join], # ------------ # Manipulate m4 lists. # These macros are necessary as long as will still need to support -# Autoconf-2.59 which quotes differently. +# Autoconf-2.59, which quotes differently. m4_define([lt_car], [[$1]]) m4_define([lt_cdr], [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], @@ -44,7 +45,7 @@ m4_define([lt_unquote], $1) # lt_append(MACRO-NAME, STRING, [SEPARATOR]) # ------------------------------------------ -# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. +# Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'. # Note that neither SEPARATOR nor STRING are expanded; they are appended # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). # No SEPARATOR is output if MACRO-NAME was previously undefined (different diff --git a/Modules/_ctypes/libffi/m4/ltversion.m4 b/Modules/_ctypes/libffi/m4/ltversion.m4 index 07a8602d48d6..daeb0af7af79 100644 --- a/Modules/_ctypes/libffi/m4/ltversion.m4 +++ b/Modules/_ctypes/libffi/m4/ltversion.m4 @@ -1,6 +1,6 @@ # ltversion.m4 -- version numbers -*- Autoconf -*- # -# Copyright (C) 2004 Free Software Foundation, Inc. +# Copyright (C) 2004, 2011-2013 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004 # # This file is free software; the Free Software Foundation gives @@ -9,15 +9,15 @@ # @configure_input@ -# serial 3337 ltversion.m4 +# serial 4038 ltversion.m4 # This file is part of GNU Libtool -m4_define([LT_PACKAGE_VERSION], [2.4.2]) -m4_define([LT_PACKAGE_REVISION], [1.3337]) +m4_define([LT_PACKAGE_VERSION], [2.4.2.418]) +m4_define([LT_PACKAGE_REVISION], [2.4.2.418]) AC_DEFUN([LTVERSION_VERSION], -[macro_version='2.4.2' -macro_revision='1.3337' +[macro_version='2.4.2.418' +macro_revision='2.4.2.418' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) diff --git a/Modules/_ctypes/libffi/m4/lt~obsolete.m4 b/Modules/_ctypes/libffi/m4/lt~obsolete.m4 index c573da90c5cc..59461e458cc9 100644 --- a/Modules/_ctypes/libffi/m4/lt~obsolete.m4 +++ b/Modules/_ctypes/libffi/m4/lt~obsolete.m4 @@ -1,6 +1,7 @@ # lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- # -# Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. +# Copyright (C) 2004-2005, 2007, 2009, 2011-2013 Free Software +# Foundation, Inc. # Written by Scott James Remnant, 2004. # # This file is free software; the Free Software Foundation gives @@ -11,7 +12,7 @@ # These exist entirely to fool aclocal when bootstrapping libtool. # -# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) +# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN), # which have later been changed to m4_define as they aren't part of the # exported API, or moved to Autoconf or Automake where they belong. # @@ -25,7 +26,7 @@ # included after everything else. This provides aclocal with the # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything # because those macros already exist, or will be overwritten later. -# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. +# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. # # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. # Yes, that means every name once taken will need to remain here until diff --git a/Modules/_ctypes/libffi/man/Makefile.in b/Modules/_ctypes/libffi/man/Makefile.in index c02e1f26a206..d92af74fb692 100644 --- a/Modules/_ctypes/libffi/man/Makefile.in +++ b/Modules/_ctypes/libffi/man/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.12.2 from Makefile.am. +# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2012 Free Software Foundation, Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -14,23 +14,51 @@ @SET_MAKE@ VPATH = @srcdir@ -am__make_dryrun = \ - { \ - am__dry=no; \ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ - echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ - | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ - *) \ - for am__flg in $$MAKEFLAGS; do \ - case $$am__flg in \ - *=*|--*) ;; \ - *n*) am__dry=yes; break;; \ - esac; \ - done;; \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ - test $$am__dry = yes; \ - } + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -51,7 +79,7 @@ build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = man -DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/asmcfi.m4 \ $(top_srcdir)/m4/ax_append_flag.m4 \ @@ -73,6 +101,18 @@ mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/fficonfig.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ @@ -111,10 +151,12 @@ man3dir = $(mandir)/man3 am__installdirs = "$(DESTDIR)$(man3dir)" NROFF = nroff MANS = $(man_MANS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LTLDFLAGS = @AM_LTLDFLAGS@ AM_RUNTESTFLAGS = @AM_RUNTESTFLAGS@ AR = @AR@ @@ -130,6 +172,10 @@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ @@ -145,6 +191,7 @@ FFI_EXEC_TRAMPOLINE_TABLE = @FFI_EXEC_TRAMPOLINE_TABLE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_LONG_DOUBLE = @HAVE_LONG_DOUBLE@ +HAVE_LONG_DOUBLE_VARIANT = @HAVE_LONG_DOUBLE_VARIANT@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ @@ -191,6 +238,7 @@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ @@ -330,29 +378,14 @@ uninstall-man3: } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man3dir)'; $(am__uninstall_files_from_dir) -tags: TAGS -TAGS: +tags TAGS: -ctags: CTAGS -CTAGS: +ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) - @list='$(MANS)'; if test -n "$$list"; then \ - list=`for p in $$list; do \ - if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ - if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \ - if test -n "$$list" && \ - grep 'ab help2man is required to generate this page' $$list >/dev/null; then \ - echo "error: found man pages containing the 'missing help2man' replacement text:" >&2; \ - grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \ - echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \ - echo " typically 'make maintainer-clean' will remove them" >&2; \ - exit 1; \ - else :; fi; \ - else :; fi @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ @@ -490,16 +523,17 @@ uninstall-man: uninstall-man3 .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ - distclean distclean-generic distclean-libtool distdir dvi \ - dvi-am html html-am info info-am install install-am \ - install-data install-data-am install-dvi install-dvi-am \ - install-exec install-exec-am install-html install-html-am \ - install-info install-info-am install-man install-man3 \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - uninstall uninstall-am uninstall-man uninstall-man3 + cscopelist-am ctags-am distclean distclean-generic \ + distclean-libtool distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-man3 install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am tags-am uninstall uninstall-am uninstall-man \ + uninstall-man3 # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/Modules/_ctypes/libffi/mdate-sh b/Modules/_ctypes/libffi/mdate-sh index cd916c0a3400..b3719cf76191 100755 --- a/Modules/_ctypes/libffi/mdate-sh +++ b/Modules/_ctypes/libffi/mdate-sh @@ -1,10 +1,9 @@ #!/bin/sh # Get modification time of a file or directory and pretty-print it. -scriptversion=2005-06-29.22 +scriptversion=2010-08-21.06; # UTC -# Copyright (C) 1995, 1996, 1997, 2003, 2004, 2005 Free Software -# Foundation, Inc. +# Copyright (C) 1995-2013 Free Software Foundation, Inc. # written by Ulrich Drepper , June 1995 # # This program is free software; you can redistribute it and/or modify @@ -18,8 +17,7 @@ scriptversion=2005-06-29.22 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -30,16 +28,26 @@ scriptversion=2005-06-29.22 # bugs to or send patches to # . +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +fi + case $1 in '') - echo "$0: No file. Try \`$0 --help' for more information." 1>&2 + echo "$0: No file. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: mdate-sh [--help] [--version] FILE -Pretty-print the modification time of FILE. +Pretty-print the modification day of FILE, in the format: +1 January 1970 Report bugs to . EOF @@ -51,6 +59,13 @@ EOF ;; esac +error () +{ + echo "$0: $1" >&2 + exit 1 +} + + # Prevent date giving response in another language. LANG=C export LANG @@ -60,7 +75,7 @@ LC_TIME=C export LC_TIME # GNU ls changes its time format in response to the TIME_STYLE -# variable. Since we cannot assume `unset' works, revert this +# variable. Since we cannot assume 'unset' works, revert this # variable to its documented default. if test "${TIME_STYLE+set}" = set; then TIME_STYLE=posix-long-iso @@ -75,27 +90,32 @@ if ls -L /dev/null 1>/dev/null 2>&1; then else ls_command='ls -l -d' fi +# Avoid user/group names that might have spaces, when possible. +if ls -n /dev/null 1>/dev/null 2>&1; then + ls_command="$ls_command -n" +fi -# A `ls -l' line looks as follows on OS/2. +# A 'ls -l' line looks as follows on OS/2. # drwxrwx--- 0 Aug 11 2001 foo # This differs from Unix, which adds ownership information. # drwxrwx--- 2 root root 4096 Aug 11 2001 foo # # To find the date, we split the line on spaces and iterate on words # until we find a month. This cannot work with files whose owner is a -# user named `Jan', or `Feb', etc. However, it's unlikely that `/' +# user named "Jan", or "Feb", etc. However, it's unlikely that '/' # will be owned by a user whose name is a month. So we first look at # the extended ls output of the root directory to decide how many # words should be skipped to get the date. # On HPUX /bin/sh, "set" interprets "-rw-r--r--" as options, so the "x" below. -set x`ls -l -d /` +set x`$ls_command /` # Find which argument is the month. month= command= until test $month do + test $# -gt 0 || error "failed parsing '$ls_command /' output" shift # Add another shift to the command. command="$command shift;" @@ -115,8 +135,10 @@ do esac done +test -n "$month" || error "failed parsing '$ls_command /' output" + # Get the extended ls output of the file or directory. -set dummy x`eval "$ls_command \"\$save_arg1\""` +set dummy x`eval "$ls_command \"\\\$save_arg1\""` # Remove all preceding arguments eval $command @@ -197,5 +219,6 @@ echo $day $month $year # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-end: "$" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" # End: diff --git a/Modules/_ctypes/libffi/missing b/Modules/_ctypes/libffi/missing index 28055d2ae6f2..cdea514931f5 100755 --- a/Modules/_ctypes/libffi/missing +++ b/Modules/_ctypes/libffi/missing @@ -1,11 +1,10 @@ #! /bin/sh -# Common stub for a few missing GNU programs while installing. +# Common wrapper for a few potentially missing GNU programs. -scriptversion=2009-04-28.21; # UTC +scriptversion=2012-06-26.16; # UTC -# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, -# 2008, 2009 Free Software Foundation, Inc. -# Originally by Fran,cois Pinard , 1996. +# Copyright (C) 1996-2013 Free Software Foundation, Inc. +# Originally written by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -26,69 +25,40 @@ scriptversion=2009-04-28.21; # UTC # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then - echo 1>&2 "Try \`$0 --help' for more information" + echo 1>&2 "Try '$0 --help' for more information" exit 1 fi -run=: -sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' -sed_minuso='s/.* -o \([^ ]*\).*/\1/p' - -# In the cases where this matters, `missing' is being run in the -# srcdir already. -if test -f configure.ac; then - configure_ac=configure.ac -else - configure_ac=configure.in -fi +case $1 in -msg="missing on your system" + --is-lightweight) + # Used by our autoconf macros to check whether the available missing + # script is modern enough. + exit 0 + ;; -case $1 in ---run) - # Try to run requested program, and just exit if it succeeds. - run= - shift - "$@" && exit 0 - # Exit code 63 means version mismatch. This often happens - # when the user try to use an ancient version of a tool on - # a file that requires a minimum version. In this case we - # we should proceed has if the program had been absent, or - # if --run hadn't been passed. - if test $? = 63; then - run=: - msg="probably too old" - fi - ;; + --run) + # Back-compat with the calling convention used by older automake. + shift + ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... -Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an -error status if there is no known handling for PROGRAM. +Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due +to PROGRAM being missing or too old. Options: -h, --help display this help and exit -v, --version output version information and exit - --run try to run the given command, and emulate it if it fails Supported PROGRAM values: - aclocal touch file \`aclocal.m4' - autoconf touch file \`configure' - autoheader touch file \`config.h.in' - autom4te touch the output file, or create a stub one - automake touch all \`Makefile.in' files - bison create \`y.tab.[ch]', if possible, from existing .[ch] - flex create \`lex.yy.c', if possible, from existing .c - help2man touch the output file - lex create \`lex.yy.c', if possible, from existing .c - makeinfo touch the output file - tar try tar, gnutar, gtar, then tar without non-portable flags - yacc create \`y.tab.[ch]', if possible, from existing .[ch] + aclocal autoconf autoheader autom4te automake makeinfo + bison yacc flex lex help2man -Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and -\`g' are ignored when checking the name. +Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and +'g' are ignored when checking the name. Send bug reports to ." exit $? @@ -100,272 +70,141 @@ Send bug reports to ." ;; -*) - echo 1>&2 "$0: Unknown \`$1' option" - echo 1>&2 "Try \`$0 --help' for more information" + echo 1>&2 "$0: unknown '$1' option" + echo 1>&2 "Try '$0 --help' for more information" exit 1 ;; esac -# normalize program name to check for. -program=`echo "$1" | sed ' - s/^gnu-//; t - s/^gnu//; t - s/^g//; t'` - -# Now exit if we have it, but it failed. Also exit now if we -# don't have it and --version was passed (most likely to detect -# the program). This is about non-GNU programs, so use $1 not -# $program. -case $1 in - lex*|yacc*) - # Not GNU programs, they don't have --version. - ;; - - tar*) - if test -n "$run"; then - echo 1>&2 "ERROR: \`tar' requires --run" - exit 1 - elif test "x$2" = "x--version" || test "x$2" = "x--help"; then - exit 1 - fi - ;; - - *) - if test -z "$run" && ($1 --version) > /dev/null 2>&1; then - # We have it, but it failed. - exit 1 - elif test "x$2" = "x--version" || test "x$2" = "x--help"; then - # Could not run --version or --help. This is probably someone - # running `$TOOL --version' or `$TOOL --help' to check whether - # $TOOL exists and not knowing $TOOL uses missing. - exit 1 - fi - ;; -esac - -# If it does not exist, or fails to run (possibly an outdated version), -# try to emulate it. -case $program in - aclocal*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`acinclude.m4' or \`${configure_ac}'. You might want - to install the \`Automake' and \`Perl' packages. Grab them from - any GNU archive site." - touch aclocal.m4 - ;; - - autoconf*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`${configure_ac}'. You might want to install the - \`Autoconf' and \`GNU m4' packages. Grab them from any GNU - archive site." - touch configure - ;; - - autoheader*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`acconfig.h' or \`${configure_ac}'. You might want - to install the \`Autoconf' and \`GNU m4' packages. Grab them - from any GNU archive site." - files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` - test -z "$files" && files="config.h" - touch_files= - for f in $files; do - case $f in - *:*) touch_files="$touch_files "`echo "$f" | - sed -e 's/^[^:]*://' -e 's/:.*//'`;; - *) touch_files="$touch_files $f.in";; - esac - done - touch $touch_files - ;; - - automake*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. - You might want to install the \`Automake' and \`Perl' packages. - Grab them from any GNU archive site." - find . -type f -name Makefile.am -print | - sed 's/\.am$/.in/' | - while read f; do touch "$f"; done - ;; - - autom4te*) - echo 1>&2 "\ -WARNING: \`$1' is needed, but is $msg. - You might have modified some files without having the - proper tools for further handling them. - You can get \`$1' as part of \`Autoconf' from any GNU - archive site." - - file=`echo "$*" | sed -n "$sed_output"` - test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` - if test -f "$file"; then - touch $file - else - test -z "$file" || exec >$file - echo "#! /bin/sh" - echo "# Created by GNU Automake missing as a replacement of" - echo "# $ $@" - echo "exit 0" - chmod +x $file - exit 1 - fi - ;; - - bison*|yacc*) - echo 1>&2 "\ -WARNING: \`$1' $msg. You should only need it if - you modified a \`.y' file. You may need the \`Bison' package - in order for those modifications to take effect. You can get - \`Bison' from any GNU archive site." - rm -f y.tab.c y.tab.h - if test $# -ne 1; then - eval LASTARG="\${$#}" - case $LASTARG in - *.y) - SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` - if test -f "$SRCFILE"; then - cp "$SRCFILE" y.tab.c - fi - SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` - if test -f "$SRCFILE"; then - cp "$SRCFILE" y.tab.h - fi - ;; - esac - fi - if test ! -f y.tab.h; then - echo >y.tab.h - fi - if test ! -f y.tab.c; then - echo 'main() { return 0; }' >y.tab.c - fi - ;; - - lex*|flex*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified a \`.l' file. You may need the \`Flex' package - in order for those modifications to take effect. You can get - \`Flex' from any GNU archive site." - rm -f lex.yy.c - if test $# -ne 1; then - eval LASTARG="\${$#}" - case $LASTARG in - *.l) - SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` - if test -f "$SRCFILE"; then - cp "$SRCFILE" lex.yy.c - fi - ;; - esac - fi - if test ! -f lex.yy.c; then - echo 'main() { return 0; }' >lex.yy.c - fi - ;; - - help2man*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified a dependency of a manual page. You may need the - \`Help2man' package in order for those modifications to take - effect. You can get \`Help2man' from any GNU archive site." - - file=`echo "$*" | sed -n "$sed_output"` - test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` - if test -f "$file"; then - touch $file - else - test -z "$file" || exec >$file - echo ".ab help2man is required to generate this page" - exit $? - fi - ;; - - makeinfo*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified a \`.texi' or \`.texinfo' file, or any other file - indirectly affecting the aspect of the manual. The spurious - call might also be the consequence of using a buggy \`make' (AIX, - DU, IRIX). You might want to install the \`Texinfo' package or - the \`GNU make' package. Grab either from any GNU archive site." - # The file to touch is that specified with -o ... - file=`echo "$*" | sed -n "$sed_output"` - test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` - if test -z "$file"; then - # ... or it is the one specified with @setfilename ... - infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` - file=`sed -n ' - /^@setfilename/{ - s/.* \([^ ]*\) *$/\1/ - p - q - }' $infile` - # ... or it is derived from the source name (dir/f.texi becomes f.info) - test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info - fi - # If the file does not exist, the user really needs makeinfo; - # let's fail without touching anything. - test -f $file || exit 1 - touch $file - ;; - - tar*) - shift - - # We have already tried tar in the generic part. - # Look for gnutar/gtar before invocation to avoid ugly error - # messages. - if (gnutar --version > /dev/null 2>&1); then - gnutar "$@" && exit 0 - fi - if (gtar --version > /dev/null 2>&1); then - gtar "$@" && exit 0 - fi - firstarg="$1" - if shift; then - case $firstarg in - *o*) - firstarg=`echo "$firstarg" | sed s/o//` - tar "$firstarg" "$@" && exit 0 - ;; - esac - case $firstarg in - *h*) - firstarg=`echo "$firstarg" | sed s/h//` - tar "$firstarg" "$@" && exit 0 - ;; - esac - fi - - echo 1>&2 "\ -WARNING: I can't seem to be able to run \`tar' with the given arguments. - You may want to install GNU tar or Free paxutils, or check the - command line arguments." - exit 1 - ;; - - *) - echo 1>&2 "\ -WARNING: \`$1' is needed, and is $msg. - You might have modified some files without having the - proper tools for further handling them. Check the \`README' file, - it often tells you about the needed prerequisites for installing - this package. You may also peek at any GNU archive site, in case - some other package would contain this missing \`$1' program." - exit 1 - ;; -esac +# Run the given program, remember its exit status. +"$@"; st=$? + +# If it succeeded, we are done. +test $st -eq 0 && exit 0 + +# Also exit now if we it failed (or wasn't found), and '--version' was +# passed; such an option is passed most likely to detect whether the +# program is present and works. +case $2 in --version|--help) exit $st;; esac + +# Exit code 63 means version mismatch. This often happens when the user +# tries to use an ancient version of a tool on a file that requires a +# minimum version. +if test $st -eq 63; then + msg="probably too old" +elif test $st -eq 127; then + # Program was missing. + msg="missing on your system" +else + # Program was found and executed, but failed. Give up. + exit $st +fi -exit 0 +perl_URL=http://www.perl.org/ +flex_URL=http://flex.sourceforge.net/ +gnu_software_URL=http://www.gnu.org/software + +program_details () +{ + case $1 in + aclocal|automake) + echo "The '$1' program is part of the GNU Automake package:" + echo "<$gnu_software_URL/automake>" + echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/autoconf>" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + autoconf|autom4te|autoheader) + echo "The '$1' program is part of the GNU Autoconf package:" + echo "<$gnu_software_URL/autoconf/>" + echo "It also requires GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + esac +} + +give_advice () +{ + # Normalize program name to check for. + normalized_program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + + printf '%s\n' "'$1' is $msg." + + configure_deps="'configure.ac' or m4 files included by 'configure.ac'" + case $normalized_program in + autoconf*) + echo "You should only need it if you modified 'configure.ac'," + echo "or m4 files included by it." + program_details 'autoconf' + ;; + autoheader*) + echo "You should only need it if you modified 'acconfig.h' or" + echo "$configure_deps." + program_details 'autoheader' + ;; + automake*) + echo "You should only need it if you modified 'Makefile.am' or" + echo "$configure_deps." + program_details 'automake' + ;; + aclocal*) + echo "You should only need it if you modified 'acinclude.m4' or" + echo "$configure_deps." + program_details 'aclocal' + ;; + autom4te*) + echo "You might have modified some maintainer files that require" + echo "the 'automa4te' program to be rebuilt." + program_details 'autom4te' + ;; + bison*|yacc*) + echo "You should only need it if you modified a '.y' file." + echo "You may want to install the GNU Bison package:" + echo "<$gnu_software_URL/bison/>" + ;; + lex*|flex*) + echo "You should only need it if you modified a '.l' file." + echo "You may want to install the Fast Lexical Analyzer package:" + echo "<$flex_URL>" + ;; + help2man*) + echo "You should only need it if you modified a dependency" \ + "of a man page." + echo "You may want to install the GNU Help2man package:" + echo "<$gnu_software_URL/help2man/>" + ;; + makeinfo*) + echo "You should only need it if you modified a '.texi' file, or" + echo "any other file indirectly affecting the aspect of the manual." + echo "You might want to install the Texinfo package:" + echo "<$gnu_software_URL/texinfo/>" + echo "The spurious makeinfo call might also be the consequence of" + echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" + echo "want to install GNU make:" + echo "<$gnu_software_URL/make/>" + ;; + *) + echo "You might have modified some files without having the proper" + echo "tools for further handling them. Check the 'README' file, it" + echo "often tells you about the needed prerequisites for installing" + echo "this package. You may also peek at any GNU archive site, in" + echo "case some other package contains this missing '$1' program." + ;; + esac +} + +give_advice "$1" | sed -e '1s/^/WARNING: /' \ + -e '2,$s/^/ /' >&2 + +# Propagate the correct exit status (expected to be 127 for a program +# not found, 63 for a program that failed due to version mismatch). +exit $st # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) diff --git a/Modules/_ctypes/libffi/msvcc.sh b/Modules/_ctypes/libffi/msvcc.sh old mode 100644 new mode 100755 index dcdbeab16aea..7440deb34036 --- a/Modules/_ctypes/libffi/msvcc.sh +++ b/Modules/_ctypes/libffi/msvcc.sh @@ -42,6 +42,7 @@ # format and translated into something sensible for cl or ml. # +args_orig=$@ args="-nologo -W3" md=-MD cl="cl" @@ -72,14 +73,35 @@ do shift 1 ;; -O*) - # If we're optimizing, make sure we explicitly turn on some optimizations - # that are implicitly disabled by debug symbols (-Zi). - args="$args $1 -OPT:REF -OPT:ICF -INCREMENTAL:NO" + # Runtime error checks (enabled by setting -RTC1 in the -DFFI_DEBUG + # case below) are not compatible with optimization flags and will + # cause the build to fail. Therefore, drop the optimization flag if + # -DFFI_DEBUG is also set. + case $args_orig in + *-DFFI_DEBUG*) + args="$args" + ;; + *) + # The ax_cc_maxopt.m4 macro from the upstream autoconf-archive + # project doesn't support MSVC and therefore ends up trying to + # use -O3. Use the equivalent "max optimization" flag for MSVC + # instead of erroring out. + case $1 in + -O3) + args="$args -O2" + ;; + *) + args="$args $1" + ;; + esac + opt="true" + ;; + esac shift 1 ;; -g) # Enable debug symbol generation. - args="$args -Zi -DEBUG" + args="$args -Zi" shift 1 ;; -DFFI_DEBUG) @@ -126,6 +148,10 @@ do # to do here. shift 1 ;; + -pedantic) + # libffi tests -pedantic with -Wall, so drop it also. + shift 1 + ;; -Werror) args="$args -WX" shift 1 @@ -170,6 +196,13 @@ do esac done +# If -Zi is specified, certain optimizations are implicitly disabled +# by MSVC. Add back those optimizations if this is an optimized build. +# NOTE: These arguments must come after all others. +if [ -n "$opt" ]; then + args="$args -link -OPT:REF -OPT:ICF -INCREMENTAL:NO" +fi + if [ -n "$assembly" ]; then if [ -z "$outdir" ]; then outdir="." @@ -189,7 +222,10 @@ if [ -n "$assembly" ]; then else args="$md $args" echo "$cl $args" - eval "\"$cl\" $args" + # Return an error code of 1 if an invalid command line parameter is passed + # instead of just ignoring it. + eval "(\"$cl\" $args 2>&1 1>&3 | \ + awk '{print \$0} /D9002/ {error=1} END{exit error}' >&2) 3>&1" result=$? fi diff --git a/Modules/_ctypes/libffi/src/aarch64/ffi.c b/Modules/_ctypes/libffi/src/aarch64/ffi.c index 140566569511..b807a2d3813e 100644 --- a/Modules/_ctypes/libffi/src/aarch64/ffi.c +++ b/Modules/_ctypes/libffi/src/aarch64/ffi.c @@ -27,7 +27,11 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include /* Stack alignment requirement in bytes */ +#if defined (__APPLE__) +#define AARCH64_STACK_ALIGN 1 +#else #define AARCH64_STACK_ALIGN 16 +#endif #define N_X_ARG_REG 8 #define N_V_ARG_REG 8 @@ -49,6 +53,23 @@ struct call_context } v [AARCH64_N_VREG]; }; +#if defined (__clang__) && defined (__APPLE__) +extern void +sys_icache_invalidate (void *start, size_t len); +#endif + +static inline void +ffi_clear_cache (void *start, void *end) +{ +#if defined (__clang__) && defined (__APPLE__) + sys_icache_invalidate (start, (char *)end - (char *)start); +#elif defined (__GNUC__) + __builtin___clear_cache (start, end); +#else +#error "Missing builtin to flush instruction cache" +#endif +} + static void * get_x_addr (struct call_context *context, unsigned n) { @@ -94,8 +115,10 @@ get_basic_type_addr (unsigned short type, struct call_context *context, return get_s_addr (context, n); case FFI_TYPE_DOUBLE: return get_d_addr (context, n); +#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE case FFI_TYPE_LONGDOUBLE: return get_v_addr (context, n); +#endif case FFI_TYPE_UINT8: case FFI_TYPE_SINT8: case FFI_TYPE_UINT16: @@ -107,6 +130,8 @@ get_basic_type_addr (unsigned short type, struct call_context *context, case FFI_TYPE_UINT64: case FFI_TYPE_SINT64: return get_x_addr (context, n); + case FFI_TYPE_VOID: + return NULL; default: FFI_ASSERT (0); return NULL; @@ -123,15 +148,26 @@ get_basic_type_alignment (unsigned short type) case FFI_TYPE_FLOAT: case FFI_TYPE_DOUBLE: return sizeof (UINT64); +#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE case FFI_TYPE_LONGDOUBLE: return sizeof (long double); +#endif case FFI_TYPE_UINT8: case FFI_TYPE_SINT8: +#if defined (__APPLE__) + return sizeof (UINT8); +#endif case FFI_TYPE_UINT16: case FFI_TYPE_SINT16: +#if defined (__APPLE__) + return sizeof (UINT16); +#endif case FFI_TYPE_UINT32: case FFI_TYPE_INT: case FFI_TYPE_SINT32: +#if defined (__APPLE__) + return sizeof (UINT32); +#endif case FFI_TYPE_POINTER: case FFI_TYPE_UINT64: case FFI_TYPE_SINT64: @@ -154,8 +190,10 @@ get_basic_type_size (unsigned short type) return sizeof (UINT32); case FFI_TYPE_DOUBLE: return sizeof (UINT64); +#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE case FFI_TYPE_LONGDOUBLE: return sizeof (long double); +#endif case FFI_TYPE_UINT8: return sizeof (UINT8); case FFI_TYPE_SINT8: @@ -186,7 +224,7 @@ ffi_call_SYSV (unsigned (*)(struct call_context *context, unsigned char *, extended_cif *), struct call_context *context, extended_cif *, - unsigned, + size_t, void (*fn)(void)); extern void @@ -305,7 +343,9 @@ is_register_candidate (ffi_type *ty) case FFI_TYPE_VOID: case FFI_TYPE_FLOAT: case FFI_TYPE_DOUBLE: +#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE case FFI_TYPE_LONGDOUBLE: +#endif case FFI_TYPE_UINT8: case FFI_TYPE_UINT16: case FFI_TYPE_UINT32: @@ -367,16 +407,24 @@ struct arg_state { unsigned ngrn; /* Next general-purpose register number. */ unsigned nsrn; /* Next vector register number. */ - unsigned nsaa; /* Next stack offset. */ + size_t nsaa; /* Next stack offset. */ + +#if defined (__APPLE__) + unsigned allocating_variadic; +#endif }; /* Initialize a procedure call argument marshalling state. */ static void -arg_init (struct arg_state *state, unsigned call_frame_size) +arg_init (struct arg_state *state, size_t call_frame_size) { state->ngrn = 0; state->nsrn = 0; state->nsaa = 0; + +#if defined (__APPLE__) + state->allocating_variadic = 0; +#endif } /* Return the number of available consecutive core argument @@ -400,35 +448,35 @@ available_v (struct arg_state *state) static void * allocate_to_x (struct call_context *context, struct arg_state *state) { - FFI_ASSERT (state->ngrn < N_X_ARG_REG) + FFI_ASSERT (state->ngrn < N_X_ARG_REG); return get_x_addr (context, (state->ngrn)++); } static void * allocate_to_s (struct call_context *context, struct arg_state *state) { - FFI_ASSERT (state->nsrn < N_V_ARG_REG) + FFI_ASSERT (state->nsrn < N_V_ARG_REG); return get_s_addr (context, (state->nsrn)++); } static void * allocate_to_d (struct call_context *context, struct arg_state *state) { - FFI_ASSERT (state->nsrn < N_V_ARG_REG) + FFI_ASSERT (state->nsrn < N_V_ARG_REG); return get_d_addr (context, (state->nsrn)++); } static void * allocate_to_v (struct call_context *context, struct arg_state *state) { - FFI_ASSERT (state->nsrn < N_V_ARG_REG) + FFI_ASSERT (state->nsrn < N_V_ARG_REG); return get_v_addr (context, (state->nsrn)++); } /* Allocate an aligned slot on the stack and return a pointer to it. */ static void * -allocate_to_stack (struct arg_state *state, void *stack, unsigned alignment, - unsigned size) +allocate_to_stack (struct arg_state *state, void *stack, size_t alignment, + size_t size) { void *allocation; @@ -436,7 +484,12 @@ allocate_to_stack (struct arg_state *state, void *stack, unsigned alignment, alignment of the argument's type. */ state->nsaa = ALIGN (state->nsaa, alignment); state->nsaa = ALIGN (state->nsaa, alignment); +#if defined (__APPLE__) + if (state->allocating_variadic) + state->nsaa = ALIGN (state->nsaa, 8); +#else state->nsaa = ALIGN (state->nsaa, 8); +#endif allocation = stack + state->nsaa; @@ -447,7 +500,7 @@ allocate_to_stack (struct arg_state *state, void *stack, unsigned alignment, static void copy_basic_type (void *dest, void *source, unsigned short type) { - /* This is neccessary to ensure that basic types are copied + /* This is necessary to ensure that basic types are copied sign extended to 64-bits as libffi expects. */ switch (type) { @@ -457,9 +510,11 @@ copy_basic_type (void *dest, void *source, unsigned short type) case FFI_TYPE_DOUBLE: *(double *) dest = *(double *) source; break; +#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE case FFI_TYPE_LONGDOUBLE: *(long double *) dest = *(long double *) source; break; +#endif case FFI_TYPE_UINT8: *(ffi_arg *) dest = *(UINT8 *) source; break; @@ -486,6 +541,8 @@ copy_basic_type (void *dest, void *source, unsigned short type) case FFI_TYPE_SINT64: *(ffi_sarg *) dest = *(SINT64 *) source; break; + case FFI_TYPE_VOID: + break; default: FFI_ASSERT (0); @@ -514,7 +571,6 @@ copy_hfa_to_reg_or_stack (void *memory, { int i; unsigned short type = get_homogeneous_type (ty); - unsigned elems = element_count (ty); for (i = 0; i < elems; i++) { void *reg = allocate_to_v (context, state); @@ -548,11 +604,13 @@ allocate_to_register_or_stack (struct call_context *context, return allocate_to_d (context, state); state->nsrn = N_V_ARG_REG; break; +#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE case FFI_TYPE_LONGDOUBLE: if (state->nsrn < N_V_ARG_REG) return allocate_to_v (context, state); state->nsrn = N_V_ARG_REG; break; +#endif case FFI_TYPE_UINT8: case FFI_TYPE_SINT8: case FFI_TYPE_UINT16: @@ -615,7 +673,9 @@ aarch64_prep_args (struct call_context *context, unsigned char *stack, appropriate register, or if none are available, to the stack. */ case FFI_TYPE_FLOAT: case FFI_TYPE_DOUBLE: +#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE case FFI_TYPE_LONGDOUBLE: +#endif case FFI_TYPE_UINT8: case FFI_TYPE_SINT8: case FFI_TYPE_UINT16: @@ -676,6 +736,16 @@ aarch64_prep_args (struct call_context *context, unsigned char *stack, FFI_ASSERT (0); break; } + +#if defined (__APPLE__) + if (i + 1 == ecif->cif->aarch64_nfixedargs) + { + state.ngrn = N_X_ARG_REG; + state.nsrn = N_V_ARG_REG; + + state.allocating_variadic = 1; + } +#endif } return ecif->cif->aarch64_flags; @@ -712,6 +782,20 @@ ffi_prep_cif_machdep (ffi_cif *cif) return FFI_OK; } +#if defined (__APPLE__) + +/* Perform Apple-specific cif processing for variadic calls */ +ffi_status ffi_prep_cif_machdep_var(ffi_cif *cif, + unsigned int nfixedargs, + unsigned int ntotalargs) +{ + cif->aarch64_nfixedargs = nfixedargs; + + return ffi_prep_cif_machdep(cif); +} + +#endif + /* Call a function with the provided arguments and capture the return value. */ void @@ -728,7 +812,7 @@ ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) case FFI_SYSV: { struct call_context context; - unsigned stack_bytes; + size_t stack_bytes; /* Figure out the total amount of stack space we need, the above call frame space needs to be 16 bytes aligned to @@ -745,7 +829,9 @@ ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) case FFI_TYPE_VOID: case FFI_TYPE_FLOAT: case FFI_TYPE_DOUBLE: +#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE case FFI_TYPE_LONGDOUBLE: +#endif case FFI_TYPE_UINT8: case FFI_TYPE_SINT8: case FFI_TYPE_UINT16: @@ -778,7 +864,7 @@ ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) } else if ((cif->rtype->size + 7) / 8 < N_X_ARG_REG) { - unsigned size = ALIGN (cif->rtype->size, sizeof (UINT64)); + size_t size = ALIGN (cif->rtype->size, sizeof (UINT64)); memcpy (rvalue, get_x_addr (&context, 0), size); } else @@ -824,7 +910,7 @@ static unsigned char trampoline [] = memcpy (__tramp + 12, &__fun, sizeof (__fun)); \ memcpy (__tramp + 20, &__ctx, sizeof (__ctx)); \ memcpy (__tramp + 28, &__flags, sizeof (__flags)); \ - __clear_cache(__tramp, __tramp + FFI_TRAMPOLINE_SIZE); \ + ffi_clear_cache(__tramp, __tramp + FFI_TRAMPOLINE_SIZE); \ }) ffi_status @@ -857,13 +943,13 @@ ffi_prep_closure_loc (ffi_closure* closure, the stack at the point ffi_closure_SYSV() was invoked. On the return path the assembler wrapper will reload call context - regsiters. + registers. ffi_closure_SYSV_inner() marshalls the call context into ffi value - desriptors, invokes the wrapped function, then marshalls the return + descriptors, invokes the wrapped function, then marshalls the return value back into the call context. */ -void +void FFI_HIDDEN ffi_closure_SYSV_inner (ffi_closure *closure, struct call_context *context, void *stack) { @@ -897,10 +983,12 @@ ffi_closure_SYSV_inner (ffi_closure *closure, struct call_context *context, case FFI_TYPE_SINT64: case FFI_TYPE_FLOAT: case FFI_TYPE_DOUBLE: +#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE case FFI_TYPE_LONGDOUBLE: avalue[i] = allocate_to_register_or_stack (context, stack, &state, ty->type); break; +#endif case FFI_TYPE_STRUCT: if (is_hfa (ty)) @@ -924,7 +1012,7 @@ ffi_closure_SYSV_inner (ffi_closure *closure, struct call_context *context, therefore the structure is not represented as a contiguous sequence of bytes in our saved register context. We need to fake up a copy - of the structure layed out in memory + of the structure laid out in memory correctly. The fake can be tossed once the closure function has returned hence alloca() is sufficient. */ @@ -945,7 +1033,7 @@ ffi_closure_SYSV_inner (ffi_closure *closure, struct call_context *context, therefore the structure is not represented as a contiguous sequence of bytes in our saved register context. We need to fake up a copy - of the structure layed out in memory + of the structure laid out in memory correctly. The fake can be tossed once the closure function has returned hence alloca() is sufficient. */ @@ -958,11 +1046,13 @@ ffi_closure_SYSV_inner (ffi_closure *closure, struct call_context *context, break; } +#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE case FFI_TYPE_LONGDOUBLE: memcpy (&avalue[i], allocate_to_v (context, &state), sizeof (*avalue)); break; +#endif default: FFI_ASSERT (0); @@ -1033,7 +1123,9 @@ ffi_closure_SYSV_inner (ffi_closure *closure, struct call_context *context, case FFI_TYPE_SINT64: case FFI_TYPE_FLOAT: case FFI_TYPE_DOUBLE: +#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE case FFI_TYPE_LONGDOUBLE: +#endif { void *addr = get_basic_type_addr (cif->rtype->type, context, 0); copy_basic_type (addr, rvalue, cif->rtype->type); @@ -1042,19 +1134,19 @@ ffi_closure_SYSV_inner (ffi_closure *closure, struct call_context *context, case FFI_TYPE_STRUCT: if (is_hfa (cif->rtype)) { - int i; + int j; unsigned short type = get_homogeneous_type (cif->rtype); unsigned elems = element_count (cif->rtype); - for (i = 0; i < elems; i++) + for (j = 0; j < elems; j++) { - void *reg = get_basic_type_addr (type, context, i); + void *reg = get_basic_type_addr (type, context, j); copy_basic_type (reg, rvalue, type); rvalue += get_basic_type_size (type); } } else if ((cif->rtype->size + 7) / 8 < N_X_ARG_REG) { - unsigned size = ALIGN (cif->rtype->size, sizeof (UINT64)) ; + size_t size = ALIGN (cif->rtype->size, sizeof (UINT64)) ; memcpy (get_x_addr (context, 0), rvalue, size); } else diff --git a/Modules/_ctypes/libffi/src/aarch64/ffitarget.h b/Modules/_ctypes/libffi/src/aarch64/ffitarget.h index 6f1a348f5322..4bbced26f005 100644 --- a/Modules/_ctypes/libffi/src/aarch64/ffitarget.h +++ b/Modules/_ctypes/libffi/src/aarch64/ffitarget.h @@ -47,8 +47,12 @@ typedef enum ffi_abi /* ---- Internal ---- */ - +#if defined (__APPLE__) +#define FFI_TARGET_SPECIFIC_VARIADIC +#define FFI_EXTRA_CIF_FIELDS unsigned aarch64_flags; unsigned aarch64_nfixedargs +#else #define FFI_EXTRA_CIF_FIELDS unsigned aarch64_flags +#endif #define AARCH64_FFI_WITH_V_BIT 0 diff --git a/Modules/_ctypes/libffi/src/aarch64/sysv.S b/Modules/_ctypes/libffi/src/aarch64/sysv.S index b8cd421a8a5c..169eab804e17 100644 --- a/Modules/_ctypes/libffi/src/aarch64/sysv.S +++ b/Modules/_ctypes/libffi/src/aarch64/sysv.S @@ -23,14 +23,33 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include #include +#ifdef HAVE_MACHINE_ASM_H +#include +#else +#ifdef __USER_LABEL_PREFIX__ +#define CONCAT1(a, b) CONCAT2(a, b) +#define CONCAT2(a, b) a ## b + +/* Use the right prefix for global labels. */ +#define CNAME(x) CONCAT1 (__USER_LABEL_PREFIX__, x) +#else +#define CNAME(x) x +#endif +#endif + #define cfi_adjust_cfa_offset(off) .cfi_adjust_cfa_offset off #define cfi_rel_offset(reg, off) .cfi_rel_offset reg, off #define cfi_restore(reg) .cfi_restore reg #define cfi_def_cfa_register(reg) .cfi_def_cfa_register reg .text - .globl ffi_call_SYSV - .type ffi_call_SYSV, #function + .globl CNAME(ffi_call_SYSV) +#ifdef __ELF__ + .type CNAME(ffi_call_SYSV), #function +#endif +#ifdef __APPLE__ + .align 2 +#endif /* ffi_call_SYSV() @@ -53,7 +72,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ extended_cif *), struct call_context *context, extended_cif *, - unsigned required_stack_size, + size_t required_stack_size, void (*fn)(void)); Therefore on entry we have: @@ -82,7 +101,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define ffi_call_SYSV_FS (8 * 4) .cfi_startproc -ffi_call_SYSV: +CNAME(ffi_call_SYSV): stp x29, x30, [sp, #-16]! cfi_adjust_cfa_offset (16) cfi_rel_offset (x29, 0) @@ -92,11 +111,11 @@ ffi_call_SYSV: cfi_def_cfa_register (x29) sub sp, sp, #ffi_call_SYSV_FS - stp x21, x22, [sp, 0] + stp x21, x22, [sp, #0] cfi_rel_offset (x21, 0 - ffi_call_SYSV_FS) cfi_rel_offset (x22, 8 - ffi_call_SYSV_FS) - stp x23, x24, [sp, 16] + stp x23, x24, [sp, #16] cfi_rel_offset (x23, 16 - ffi_call_SYSV_FS) cfi_rel_offset (x24, 24 - ffi_call_SYSV_FS) @@ -180,7 +199,9 @@ ffi_call_SYSV: ret .cfi_endproc - .size ffi_call_SYSV, .-ffi_call_SYSV +#ifdef __ELF__ + .size CNAME(ffi_call_SYSV), .-CNAME(ffi_call_SYSV) +#endif #define ffi_closure_SYSV_FS (8 * 2 + AARCH64_CALL_CONTEXT_SIZE) @@ -222,22 +243,25 @@ ffi_call_SYSV: Voila! */ .text - .globl ffi_closure_SYSV + .globl CNAME(ffi_closure_SYSV) +#ifdef __APPLE__ + .align 2 +#endif .cfi_startproc -ffi_closure_SYSV: +CNAME(ffi_closure_SYSV): stp x29, x30, [sp, #-16]! cfi_adjust_cfa_offset (16) cfi_rel_offset (x29, 0) cfi_rel_offset (x30, 8) mov x29, sp + cfi_def_cfa_register (x29) sub sp, sp, #ffi_closure_SYSV_FS - cfi_adjust_cfa_offset (ffi_closure_SYSV_FS) stp x21, x22, [x29, #-16] - cfi_rel_offset (x21, 0) - cfi_rel_offset (x22, 8) + cfi_rel_offset (x21, -16) + cfi_rel_offset (x22, -8) /* Load x21 with &call_context. */ mov x21, sp @@ -270,7 +294,7 @@ ffi_closure_SYSV: trampoline was called. */ add x2, x29, #16 - bl ffi_closure_SYSV_inner + bl CNAME(ffi_closure_SYSV_inner) /* Figure out if we should touch the vector registers. */ ldr x0, [x22, #8] @@ -287,7 +311,7 @@ ffi_closure_SYSV: ldp x2, x3, [x21, #16] ldp x4, x5, [x21, #32] ldp x6, x7, [x21, #48] - /* Note nothing usefull is returned in x8. */ + /* Note nothing useful is returned in x8. */ /* We are done, unwind our frame. */ ldp x21, x22, [x29, #-16] @@ -295,7 +319,7 @@ ffi_closure_SYSV: cfi_restore (x22) mov sp, x29 - cfi_adjust_cfa_offset (-ffi_closure_SYSV_FS) + cfi_def_cfa_register (sp) ldp x29, x30, [sp], #16 cfi_adjust_cfa_offset (-16) @@ -304,4 +328,6 @@ ffi_closure_SYSV: ret .cfi_endproc - .size ffi_closure_SYSV, .-ffi_closure_SYSV +#ifdef __ELF__ + .size CNAME(ffi_closure_SYSV), .-CNAME(ffi_closure_SYSV) +#endif diff --git a/Modules/_ctypes/libffi/src/arc/arcompact.S b/Modules/_ctypes/libffi/src/arc/arcompact.S new file mode 100644 index 000000000000..03715fde49f7 --- /dev/null +++ b/Modules/_ctypes/libffi/src/arc/arcompact.S @@ -0,0 +1,135 @@ +/* ----------------------------------------------------------------------- + arcompact.S - Copyright (c) 2013 Synposys, Inc. (www.synopsys.com) + + ARCompact Foreign Function Interface + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL RENESAS TECHNOLOGY BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + ----------------------------------------------------------------------- */ + +#define LIBFFI_ASM +#include +#include +#ifdef HAVE_MACHINE_ASM_H +#include +#else +#define CNAME(x) x +#define ENTRY(x) .globl CNAME(x)` .type CNAME(x),%function` CNAME(x): +#endif + +.text + + /* R0: ffi_prep_args */ + /* R1: &ecif */ + /* R2: cif->bytes */ + /* R3: fig->flags */ + /* R4: ecif.rvalue */ + /* R5: fn */ +ENTRY(ffi_call_ARCompact) + /* Save registers. */ + st.a fp, [sp, -4] /* fp + 20, fp */ + push_s blink /* fp + 16, blink */ + st.a r4, [sp, -4] /* fp + 12, ecif.rvalue */ + push_s r3 /* fp + 8, fig->flags */ + st.a r5, [sp, -4] /* fp + 4, fn */ + push_s r2 /* fp + 0, cif->bytes */ + mov fp, sp + + /* Make room for all of the new args. */ + sub sp, sp, r2 + + /* Place all of the ffi_prep_args in position. */ + /* ffi_prep_args(char *stack, extended_cif *ecif) */ + /* R1 already set. */ + + /* And call. */ + jl_s.d [r0] + mov_s r0, sp + + ld.ab r12, [fp, 4] /* cif->bytes */ + ld.ab r11, [fp, 4] /* fn */ + + /* Move first 8 parameters in registers... */ + ld_s r0, [sp] + ld_s r1, [sp, 4] + ld_s r2, [sp, 8] + ld_s r3, [sp, 12] + ld r4, [sp, 16] + ld r5, [sp, 20] + ld r6, [sp, 24] + ld r7, [sp, 28] + + /* ...and adjust the stack. */ + min r12, r12, 32 + + /* Call the function. */ + jl.d [r11] + add sp, sp, r12 + + mov sp, fp + pop_s r3 /* fig->flags, return type */ + pop_s r2 /* ecif.rvalue, pointer for return value */ + + /* If the return value pointer is NULL, assume no return value. */ + breq.d r2, 0, epilogue + pop_s blink + + /* Return INT. */ + brne r3, FFI_TYPE_INT, return_double + b.d epilogue + st_s r0, [r2] + +return_double: + brne r3, FFI_TYPE_DOUBLE, epilogue + st_s r0, [r2] + st_s r1, [r2,4] + +epilogue: + j_s.d [blink] + ld.ab fp, [sp, 4] + +ENTRY(ffi_closure_ARCompact) + st.a r0, [sp, -32] + st_s r1, [sp, 4] + st_s r2, [sp, 8] + st_s r3, [sp, 12] + st r4, [sp, 16] + st r5, [sp, 20] + st r6, [sp, 24] + st r7, [sp, 28] + + /* pointer to arguments */ + mov_s r2, sp + + /* return value goes here */ + sub sp, sp, 8 + mov_s r1, sp + + push_s blink + + bl.d ffi_closure_inner_ARCompact + mov_s r0, r8 /* codeloc, set by trampoline */ + + pop_s blink + + /* set return value to r1:r0 */ + pop_s r0 + pop_s r1 + j_s.d [blink] + add_s sp, sp, 32 diff --git a/Modules/_ctypes/libffi/src/arc/ffi.c b/Modules/_ctypes/libffi/src/arc/ffi.c new file mode 100644 index 000000000000..32f82a7d5bb5 --- /dev/null +++ b/Modules/_ctypes/libffi/src/arc/ffi.c @@ -0,0 +1,268 @@ +/* ----------------------------------------------------------------------- + ffi.c - Copyright (c) 2013 Synopsys, Inc. (www.synopsys.com) + + ARC Foreign Function Interface + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL RENESAS TECHNOLOGY BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + ----------------------------------------------------------------------- */ + +#include +#include + +#include +#include + +#include + +/* for little endian ARC, the code is in fact stored as mixed endian for + performance reasons */ +#if __BIG_ENDIAN__ +#define CODE_ENDIAN(x) (x) +#else +#define CODE_ENDIAN(x) ( (((uint32_t) (x)) << 16) | (((uint32_t) (x)) >> 16)) +#endif + +/* ffi_prep_args is called by the assembly routine once stack + space has been allocated for the function's arguments. */ + +void +ffi_prep_args (char *stack, extended_cif * ecif) +{ + unsigned int i; + int tmp; + void **p_argv; + char *argp; + ffi_type **p_arg; + + tmp = 0; + argp = stack; + + if (ecif->cif->rtype->type == FFI_TYPE_STRUCT) + { + *(void **) argp = ecif->rvalue; + argp += 4; + } + + p_argv = ecif->avalue; + + for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; + (i != 0); i--, p_arg++) + { + size_t z; + int alignment; + + /* align alignment to 4 */ + alignment = (((*p_arg)->alignment - 1) | 3) + 1; + + /* Align if necessary. */ + if ((alignment - 1) & (unsigned) argp) + argp = (char *) ALIGN (argp, alignment); + + z = (*p_arg)->size; + if (z < sizeof (int)) + { + z = sizeof (int); + + switch ((*p_arg)->type) + { + case FFI_TYPE_SINT8: + *(signed int *) argp = (signed int) *(SINT8 *) (*p_argv); + break; + + case FFI_TYPE_UINT8: + *(unsigned int *) argp = (unsigned int) *(UINT8 *) (*p_argv); + break; + + case FFI_TYPE_SINT16: + *(signed int *) argp = (signed int) *(SINT16 *) (*p_argv); + break; + + case FFI_TYPE_UINT16: + *(unsigned int *) argp = (unsigned int) *(UINT16 *) (*p_argv); + break; + + case FFI_TYPE_STRUCT: + memcpy (argp, *p_argv, (*p_arg)->size); + break; + + default: + FFI_ASSERT (0); + } + } + else if (z == sizeof (int)) + { + *(unsigned int *) argp = (unsigned int) *(UINT32 *) (*p_argv); + } + else + { + if ((*p_arg)->type == FFI_TYPE_STRUCT) + { + memcpy (argp, *p_argv, z); + } + else + { + /* Double or long long 64bit. */ + memcpy (argp, *p_argv, z); + } + } + p_argv++; + argp += z; + } + + return; +} + +/* Perform machine dependent cif processing. */ +ffi_status +ffi_prep_cif_machdep (ffi_cif * cif) +{ + /* Set the return type flag. */ + switch (cif->rtype->type) + { + case FFI_TYPE_VOID: + cif->flags = (unsigned) cif->rtype->type; + break; + + case FFI_TYPE_STRUCT: + cif->flags = (unsigned) cif->rtype->type; + break; + + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + case FFI_TYPE_DOUBLE: + cif->flags = FFI_TYPE_DOUBLE; + break; + + case FFI_TYPE_FLOAT: + default: + cif->flags = FFI_TYPE_INT; + break; + } + + return FFI_OK; +} + +extern void ffi_call_ARCompact (void (*)(char *, extended_cif *), + extended_cif *, unsigned, unsigned, + unsigned *, void (*fn) (void)); + +void +ffi_call (ffi_cif * cif, void (*fn) (void), void *rvalue, void **avalue) +{ + extended_cif ecif; + + ecif.cif = cif; + ecif.avalue = avalue; + + /* If the return value is a struct and we don't have + a return value address then we need to make one. */ + if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT)) + { + ecif.rvalue = alloca (cif->rtype->size); + } + else + ecif.rvalue = rvalue; + + switch (cif->abi) + { + case FFI_ARCOMPACT: + ffi_call_ARCompact (ffi_prep_args, &ecif, cif->bytes, + cif->flags, ecif.rvalue, fn); + break; + + default: + FFI_ASSERT (0); + break; + } +} + +int +ffi_closure_inner_ARCompact (ffi_closure * closure, void *rvalue, + ffi_arg * args) +{ + void **arg_area, **p_argv; + ffi_cif *cif = closure->cif; + char *argp = (char *) args; + ffi_type **p_argt; + int i; + + arg_area = (void **) alloca (cif->nargs * sizeof (void *)); + + /* handle hidden argument */ + if (cif->flags == FFI_TYPE_STRUCT) + { + rvalue = *(void **) argp; + argp += 4; + } + + p_argv = arg_area; + + for (i = 0, p_argt = cif->arg_types; i < cif->nargs; + i++, p_argt++, p_argv++) + { + size_t z; + int alignment; + + /* align alignment to 4 */ + alignment = (((*p_argt)->alignment - 1) | 3) + 1; + + /* Align if necessary. */ + if ((alignment - 1) & (unsigned) argp) + argp = (char *) ALIGN (argp, alignment); + + z = (*p_argt)->size; + *p_argv = (void *) argp; + argp += z; + } + + (closure->fun) (cif, rvalue, arg_area, closure->user_data); + + return cif->flags; +} + +extern void ffi_closure_ARCompact (void); + +ffi_status +ffi_prep_closure_loc (ffi_closure * closure, ffi_cif * cif, + void (*fun) (ffi_cif *, void *, void **, void *), + void *user_data, void *codeloc) +{ + uint32_t *tramp = (uint32_t *) & (closure->tramp[0]); + + switch (cif->abi) + { + case FFI_ARCOMPACT: + FFI_ASSERT (tramp == codeloc); + tramp[0] = CODE_ENDIAN (0x200a1fc0); /* mov r8, pcl */ + tramp[1] = CODE_ENDIAN (0x20200f80); /* j [long imm] */ + tramp[2] = CODE_ENDIAN (ffi_closure_ARCompact); + break; + + default: + return FFI_BAD_ABI; + } + + closure->cif = cif; + closure->fun = fun; + closure->user_data = user_data; + cacheflush (codeloc, FFI_TRAMPOLINE_SIZE, BCACHE); + + return FFI_OK; +} diff --git a/Modules/_ctypes/libffi/src/arc/ffitarget.h b/Modules/_ctypes/libffi/src/arc/ffitarget.h new file mode 100644 index 000000000000..bf8311bc832c --- /dev/null +++ b/Modules/_ctypes/libffi/src/arc/ffitarget.h @@ -0,0 +1,53 @@ +/* ----------------------------------------------------------------------- + ffitarget.h - Copyright (c) 2012 Anthony Green + Copyright (c) 2013 Synopsys, Inc. (www.synopsys.com) + Target configuration macros for ARC. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL RENESAS TECHNOLOGY BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + + ----------------------------------------------------------------------- */ + +#ifndef LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +#ifndef LIBFFI_H +#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." +#endif + +/* ---- Generic type definitions ----------------------------------------- */ + +#ifndef LIBFFI_ASM +typedef unsigned long ffi_arg; +typedef signed long ffi_sarg; + +typedef enum ffi_abi +{ + FFI_FIRST_ABI = 0, + FFI_ARCOMPACT, + FFI_LAST_ABI, + FFI_DEFAULT_ABI = FFI_ARCOMPACT +} ffi_abi; +#endif + +#define FFI_CLOSURES 1 +#define FFI_TRAMPOLINE_SIZE 12 +#define FFI_NATIVE_RAW_API 0 + +#endif diff --git a/Modules/_ctypes/libffi/src/arm/ffi.c b/Modules/_ctypes/libffi/src/arm/ffi.c index 7fd7f44c4d4c..6691ab57daa2 100644 --- a/Modules/_ctypes/libffi/src/arm/ffi.c +++ b/Modules/_ctypes/libffi/src/arm/ffi.c @@ -4,8 +4,8 @@ Copyright (c) 2011 Anthony Green Copyright (c) 2011 Free Software Foundation Copyright (c) 1998, 2008, 2011 Red Hat, Inc. - - ARM Foreign Function Interface + + ARM Foreign Function Interface Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the @@ -37,6 +37,87 @@ static int vfp_type_p (ffi_type *); static void layout_vfp_args (ffi_cif *); +int ffi_prep_args_SYSV(char *stack, extended_cif *ecif, float *vfp_space); +int ffi_prep_args_VFP(char *stack, extended_cif *ecif, float *vfp_space); + +static char* ffi_align(ffi_type **p_arg, char *argp) +{ + /* Align if necessary */ + register size_t alignment = (*p_arg)->alignment; + if (alignment < 4) + { + alignment = 4; + } +#ifdef _WIN32_WCE + if (alignment > 4) + { + alignment = 4; + } +#endif + if ((alignment - 1) & (unsigned) argp) + { + argp = (char *) ALIGN(argp, alignment); + } + + if ((*p_arg)->type == FFI_TYPE_STRUCT) + { + argp = (char *) ALIGN(argp, 4); + } + return argp; +} + +static size_t ffi_put_arg(ffi_type **arg_type, void **arg, char *stack) +{ + register char* argp = stack; + register ffi_type **p_arg = arg_type; + register void **p_argv = arg; + register size_t z = (*p_arg)->size; + if (z < sizeof(int)) + { + z = sizeof(int); + switch ((*p_arg)->type) + { + case FFI_TYPE_SINT8: + *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv); + break; + + case FFI_TYPE_UINT8: + *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv); + break; + + case FFI_TYPE_SINT16: + *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv); + break; + + case FFI_TYPE_UINT16: + *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv); + break; + + case FFI_TYPE_STRUCT: + memcpy(argp, *p_argv, (*p_arg)->size); + break; + + default: + FFI_ASSERT(0); + } + } + else if (z == sizeof(int)) + { + if ((*p_arg)->type == FFI_TYPE_FLOAT) + *(float *) argp = *(float *)(* p_argv); + else + *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); + } + else if (z == sizeof(double) && (*p_arg)->type == FFI_TYPE_DOUBLE) + { + *(double *) argp = *(double *)(* p_argv); + } + else + { + memcpy(argp, *p_argv, z); + } + return z; +} /* ffi_prep_args is called by the assembly routine once stack space has been allocated for the function's arguments @@ -44,14 +125,14 @@ static void layout_vfp_args (ffi_cif *); value is cif->vfp_used (word bitset of VFP regs used for passing arguments). These are only used for the VFP hard-float ABI. */ -int ffi_prep_args(char *stack, extended_cif *ecif, float *vfp_space) +int ffi_prep_args_SYSV(char *stack, extended_cif *ecif, float *vfp_space) { - register unsigned int i, vi = 0; + register unsigned int i; register void **p_argv; register char *argp; register ffi_type **p_arg; - argp = stack; + if ( ecif->cif->flags == FFI_TYPE_STRUCT ) { *(void **) argp = ecif->rvalue; @@ -62,81 +143,89 @@ int ffi_prep_args(char *stack, extended_cif *ecif, float *vfp_space) for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; (i != 0); - i--, p_arg++) + i--, p_arg++, p_argv++) { - size_t z; - size_t alignment; + argp = ffi_align(p_arg, argp); + argp += ffi_put_arg(p_arg, p_argv, argp); + } - /* Allocated in VFP registers. */ - if (ecif->cif->abi == FFI_VFP - && vi < ecif->cif->vfp_nargs && vfp_type_p (*p_arg)) - { - float* vfp_slot = vfp_space + ecif->cif->vfp_args[vi++]; - if ((*p_arg)->type == FFI_TYPE_FLOAT) - *((float*)vfp_slot) = *((float*)*p_argv); - else if ((*p_arg)->type == FFI_TYPE_DOUBLE) - *((double*)vfp_slot) = *((double*)*p_argv); - else - memcpy(vfp_slot, *p_argv, (*p_arg)->size); - p_argv++; - continue; - } + return 0; +} - /* Align if necessary */ - alignment = (*p_arg)->alignment; -#ifdef _WIN32_WCE - if (alignment > 4) - alignment = 4; -#endif - if ((alignment - 1) & (unsigned) argp) { - argp = (char *) ALIGN(argp, alignment); - } +int ffi_prep_args_VFP(char *stack, extended_cif *ecif, float *vfp_space) +{ + register unsigned int i, vi = 0; + register void **p_argv; + register char *argp, *regp, *eo_regp; + register ffi_type **p_arg; + char stack_used = 0; + char done_with_regs = 0; + char is_vfp_type; - if ((*p_arg)->type == FFI_TYPE_STRUCT) - argp = (char *) ALIGN(argp, 4); + // make sure we are using FFI_VFP + FFI_ASSERT(ecif->cif->abi == FFI_VFP); - z = (*p_arg)->size; - if (z < sizeof(int)) - { - z = sizeof(int); - switch ((*p_arg)->type) - { - case FFI_TYPE_SINT8: - *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv); - break; - - case FFI_TYPE_UINT8: - *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv); - break; - - case FFI_TYPE_SINT16: - *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv); - break; - - case FFI_TYPE_UINT16: - *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv); - break; - - case FFI_TYPE_STRUCT: - memcpy(argp, *p_argv, (*p_arg)->size); - break; - - default: - FFI_ASSERT(0); - } - } - else if (z == sizeof(int)) - { - *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); - } - else - { - memcpy(argp, *p_argv, z); - } - p_argv++; - argp += z; - } + /* the first 4 words on the stack are used for values passed in core + * registers. */ + regp = stack; + eo_regp = argp = regp + 16; + + /* if the function returns an FFI_TYPE_STRUCT in memory, that address is + * passed in r0 to the function */ + if ( ecif->cif->flags == FFI_TYPE_STRUCT ) { + *(void **) regp = ecif->rvalue; + regp += 4; + } + + p_argv = ecif->avalue; + + for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; + (i != 0); + i--, p_arg++, p_argv++) + { + is_vfp_type = vfp_type_p (*p_arg); + + /* Allocated in VFP registers. */ + if(vi < ecif->cif->vfp_nargs && is_vfp_type) + { + char *vfp_slot = (char *)(vfp_space + ecif->cif->vfp_args[vi++]); + ffi_put_arg(p_arg, p_argv, vfp_slot); + continue; + } + /* Try allocating in core registers. */ + else if (!done_with_regs && !is_vfp_type) + { + char *tregp = ffi_align(p_arg, regp); + size_t size = (*p_arg)->size; + size = (size < 4)? 4 : size; // pad + /* Check if there is space left in the aligned register area to place + * the argument */ + if(tregp + size <= eo_regp) + { + regp = tregp + ffi_put_arg(p_arg, p_argv, tregp); + done_with_regs = (regp == argp); + // ensure we did not write into the stack area + FFI_ASSERT(regp <= argp); + continue; + } + /* In case there are no arguments in the stack area yet, + the argument is passed in the remaining core registers and on the + stack. */ + else if (!stack_used) + { + stack_used = 1; + done_with_regs = 1; + argp = tregp + ffi_put_arg(p_arg, p_argv, tregp); + FFI_ASSERT(eo_regp < argp); + continue; + } + } + /* Base case, arguments are passed on the stack */ + stack_used = 1; + argp = ffi_align(p_arg, argp); + argp += ffi_put_arg(p_arg, p_argv, argp); + } /* Indicate the VFP registers used. */ return ecif->cif->vfp_used; } @@ -227,7 +316,7 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) ecif.avalue = avalue; /* If the return value is a struct and we don't have a return */ - /* value address then we need to make one */ + /* value address then we need to make one */ if ((rvalue == NULL) && (cif->flags == FFI_TYPE_STRUCT)) @@ -261,9 +350,17 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) break; } if (small_struct) - memcpy (rvalue, &temp, cif->rtype->size); + { + FFI_ASSERT(rvalue != NULL); + memcpy (rvalue, &temp, cif->rtype->size); + } + else if (vfp_struct) - memcpy (rvalue, ecif.rvalue, cif->rtype->size); + { + FFI_ASSERT(rvalue != NULL); + memcpy (rvalue, ecif.rvalue, cif->rtype->size); + } + } /** private members **/ @@ -271,18 +368,18 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) static void ffi_prep_incoming_args_SYSV (char *stack, void **ret, void** args, ffi_cif* cif, float *vfp_stack); +static void ffi_prep_incoming_args_VFP (char *stack, void **ret, + void** args, ffi_cif* cif, float *vfp_stack); + void ffi_closure_SYSV (ffi_closure *); void ffi_closure_VFP (ffi_closure *); /* This function is jumped to by the trampoline */ -unsigned int -ffi_closure_SYSV_inner( - ffi_closure *closure, - void **respp, - void *args, - void *vfp_args) +unsigned int FFI_HIDDEN +ffi_closure_inner (ffi_closure *closure, + void **respp, void *args, void *vfp_args) { // our various things... ffi_cif *cif; @@ -296,8 +393,10 @@ ffi_closure_SYSV_inner( * value on the stack; and if the function returns * a structure, it will re-set RESP to point to the * structure return address. */ - - ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif, vfp_args); + if (cif->abi == FFI_VFP) + ffi_prep_incoming_args_VFP(args, respp, arg_area, cif, vfp_args); + else + ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif, vfp_args); (closure->fun) (cif, *respp, arg_area, closure->user_data); @@ -312,7 +411,7 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, float *vfp_stack) /*@=exportheader@*/ { - register unsigned int i, vi = 0; + register unsigned int i; register void **p_argv; register char *argp; register ffi_type **p_arg; @@ -329,27 +428,8 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++) { size_t z; - size_t alignment; - - if (cif->abi == FFI_VFP - && vi < cif->vfp_nargs && vfp_type_p (*p_arg)) - { - *p_argv++ = (void*)(vfp_stack + cif->vfp_args[vi++]); - continue; - } - alignment = (*p_arg)->alignment; - if (alignment < 4) - alignment = 4; -#ifdef _WIN32_WCE - else - if (alignment > 4) - alignment = 4; -#endif - /* Align if necessary */ - if ((alignment - 1) & (unsigned) argp) { - argp = (char *) ALIGN(argp, alignment); - } + argp = ffi_align(p_arg, argp); z = (*p_arg)->size; @@ -364,6 +444,95 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, return; } +/*@-exportheader@*/ +static void +ffi_prep_incoming_args_VFP(char *stack, void **rvalue, + void **avalue, ffi_cif *cif, + /* Used only under VFP hard-float ABI. */ + float *vfp_stack) +/*@=exportheader@*/ +{ + register unsigned int i, vi = 0; + register void **p_argv; + register char *argp, *regp, *eo_regp; + register ffi_type **p_arg; + char done_with_regs = 0; + char stack_used = 0; + char is_vfp_type; + + FFI_ASSERT(cif->abi == FFI_VFP); + regp = stack; + eo_regp = argp = regp + 16; + + if ( cif->flags == FFI_TYPE_STRUCT ) { + *rvalue = *(void **) regp; + regp += 4; + } + + p_argv = avalue; + + for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++) + { + size_t z; + is_vfp_type = vfp_type_p (*p_arg); + + if(vi < cif->vfp_nargs && is_vfp_type) + { + *p_argv++ = (void*)(vfp_stack + cif->vfp_args[vi++]); + continue; + } + else if (!done_with_regs && !is_vfp_type) + { + char* tregp = ffi_align(p_arg, regp); + + z = (*p_arg)->size; + z = (z < 4)? 4 : z; // pad + + /* if the arguments either fits into the registers or uses registers + * and stack, while we haven't read other things from the stack */ + if(tregp + z <= eo_regp || !stack_used) + { + /* because we're little endian, this is what it turns into. */ + *p_argv = (void*) tregp; + + p_argv++; + regp = tregp + z; + // if we read past the last core register, make sure we have not read + // from the stack before and continue reading after regp + if(regp > eo_regp) + { + if(stack_used) + { + abort(); // we should never read past the end of the register + // are if the stack is already in use + } + argp = regp; + } + if(regp >= eo_regp) + { + done_with_regs = 1; + stack_used = 1; + } + continue; + } + } + stack_used = 1; + + argp = ffi_align(p_arg, argp); + + z = (*p_arg)->size; + + /* because we're little endian, this is what it turns into. */ + + *p_argv = (void*) argp; + + p_argv++; + argp += z; + } + + return; +} + /* How to make a trampoline. */ extern unsigned int ffi_arm_trampoline[3]; @@ -381,7 +550,7 @@ typedef struct ffi_trampoline_table ffi_trampoline_table; typedef struct ffi_trampoline_table_entry ffi_trampoline_table_entry; struct ffi_trampoline_table { - /* contigious writable and executable pages */ + /* contiguous writable and executable pages */ vm_address_t config_page; vm_address_t trampoline_page; @@ -421,7 +590,7 @@ ffi_trampoline_table_alloc () { ffi_trampoline_table *table = NULL; - /* Loop until we can allocate two contigious pages */ + /* Loop until we can allocate two contiguous pages */ while (table == NULL) { vm_address_t config_page = 0x0; kern_return_t kt; @@ -617,7 +786,7 @@ ffi_prep_closure_loc (ffi_closure* closure, #endif else return FFI_BAD_ABI; - + #if FFI_EXEC_TRAMPOLINE_TABLE void **config = FFI_TRAMPOLINE_CODELOC_CONFIG(codeloc); config[0] = closure; @@ -700,9 +869,9 @@ static int vfp_type_p (ffi_type *t) return 0; } -static void place_vfp_arg (ffi_cif *cif, ffi_type *t) +static int place_vfp_arg (ffi_cif *cif, ffi_type *t) { - int reg = cif->vfp_reg_free; + short reg = cif->vfp_reg_free; int nregs = t->size / sizeof (float); int align = ((t->type == FFI_TYPE_STRUCT_VFP_FLOAT || t->type == FFI_TYPE_FLOAT) ? 1 : 2); @@ -733,9 +902,13 @@ static void place_vfp_arg (ffi_cif *cif, ffi_type *t) reg += 1; cif->vfp_reg_free = reg; } - return; + return 0; next_reg: ; } + // done, mark all regs as used + cif->vfp_reg_free = 16; + cif->vfp_used = 0xFFFF; + return 1; } static void layout_vfp_args (ffi_cif *cif) @@ -750,7 +923,9 @@ static void layout_vfp_args (ffi_cif *cif) for (i = 0; i < cif->nargs; i++) { ffi_type *t = cif->arg_types[i]; - if (vfp_type_p (t)) - place_vfp_arg (cif, t); + if (vfp_type_p (t) && place_vfp_arg (cif, t) == 1) + { + break; + } } } diff --git a/Modules/_ctypes/libffi/src/arm/gentramp.sh b/Modules/_ctypes/libffi/src/arm/gentramp.sh old mode 100644 new mode 100755 index 74f0b867daec..05c43a30fc49 --- a/Modules/_ctypes/libffi/src/arm/gentramp.sh +++ b/Modules/_ctypes/libffi/src/arm/gentramp.sh @@ -84,7 +84,7 @@ EOF } -# WARNING - Don't modify the trampoline code size without also updating the relevent libffi code +# WARNING - Don't modify the trampoline code size without also updating the relevant libffi code trampoline () { cat << END diff --git a/Modules/_ctypes/libffi/src/arm/sysv.S b/Modules/_ctypes/libffi/src/arm/sysv.S index fb38cd6406ad..541bbe923002 100644 --- a/Modules/_ctypes/libffi/src/arm/sysv.S +++ b/Modules/_ctypes/libffi/src/arm/sysv.S @@ -109,42 +109,27 @@ #define UNWIND @ #endif - +.syntax unified + #if defined(__thumb__) && !defined(__THUMB_INTERWORK__) -.macro ARM_FUNC_START name - .text - .align 0 - .thumb - .thumb_func -#ifdef __APPLE__ - ENTRY($0) +#define ARM_FUNC_START(name) \ + .text; \ + .align 2; \ + .thumb; \ + .thumb_func; \ + ENTRY(name); \ + bx pc; \ + nop; \ + .arm; \ + UNWIND .fnstart; \ +_L__##name: #else - ENTRY(\name) -#endif - bx pc - nop - .arm +#define ARM_FUNC_START(name) \ + .text; \ + .align 2; \ + .arm; \ + ENTRY(name); \ UNWIND .fnstart -/* A hook to tell gdb that we've switched to ARM mode. Also used to call - directly from other local arm routines. */ -#ifdef __APPLE__ -_L__$0: -#else -_L__\name: -#endif -.endm -#else -.macro ARM_FUNC_START name - .text - .align 0 - .arm -#ifdef __APPLE__ - ENTRY($0) -#else - ENTRY(\name) -#endif - UNWIND .fnstart -.endm #endif .macro RETLDM regs=, cond=, dirn=ia @@ -171,7 +156,7 @@ _L__\name: @ sp+0: ecif.rvalue @ This assumes we are using gas. -ARM_FUNC_START ffi_call_SYSV +ARM_FUNC_START(ffi_call_SYSV) @ Save registers stmfd sp!, {r0-r3, fp, lr} UNWIND .save {r0-r3, fp, lr} @@ -187,7 +172,7 @@ ARM_FUNC_START ffi_call_SYSV @ r1 already set @ Call ffi_prep_args(stack, &ecif) - bl CNAME(ffi_prep_args) + bl CNAME(ffi_prep_args_SYSV) @ move first 4 parameters in registers ldmia sp, {r0-r3} @@ -228,7 +213,7 @@ ARM_FUNC_START ffi_call_SYSV #if defined(__SOFTFP__) || defined(__ARM_EABI__) cmpne r3, #FFI_TYPE_DOUBLE #endif - stmeqia r2, {r0, r1} + stmiaeq r2, {r0, r1} #if !defined(__SOFTFP__) && !defined(__ARM_EABI__) beq LSYM(Lepilogue) @@ -260,13 +245,13 @@ LSYM(Lepilogue): /* unsigned int FFI_HIDDEN - ffi_closure_SYSV_inner (closure, respp, args) + ffi_closure_inner (closure, respp, args) ffi_closure *closure; void **respp; void *args; */ -ARM_FUNC_START ffi_closure_SYSV +ARM_FUNC_START(ffi_closure_SYSV) UNWIND .pad #16 add ip, sp, #16 stmfd sp!, {ip, lr} @@ -276,7 +261,7 @@ ARM_FUNC_START ffi_closure_SYSV sub sp, sp, #16 str sp, [sp, #8] add r1, sp, #8 - bl CNAME(ffi_closure_SYSV_inner) + bl CNAME(ffi_closure_inner) cmp r0, #FFI_TYPE_INT beq .Lretint @@ -345,7 +330,7 @@ ARM_FUNC_START ffi_closure_SYSV @ r3: fig->flags @ sp+0: ecif.rvalue -ARM_FUNC_START ffi_call_VFP +ARM_FUNC_START(ffi_call_VFP) @ Save registers stmfd sp!, {r0-r3, fp, lr} UNWIND .save {r0-r3, fp, lr} @@ -364,10 +349,11 @@ ARM_FUNC_START ffi_call_VFP sub r2, fp, #64 @ VFP scratch space @ Call ffi_prep_args(stack, &ecif, vfp_space) - bl CNAME(ffi_prep_args) + bl CNAME(ffi_prep_args_VFP) @ Load VFP register args if needed cmp r0, #0 + mov ip, fp beq LSYM(Lbase_args) @ Load only d0 if possible @@ -433,7 +419,7 @@ LSYM(Lepilogue_vfp): .size CNAME(ffi_call_VFP),.ffi_call_VFP_end-CNAME(ffi_call_VFP) -ARM_FUNC_START ffi_closure_VFP +ARM_FUNC_START(ffi_closure_VFP) fstmfdd sp!, {d0-d7} @ r0-r3, then d0-d7 UNWIND .pad #80 @@ -446,7 +432,7 @@ ARM_FUNC_START ffi_closure_VFP sub sp, sp, #72 str sp, [sp, #64] add r1, sp, #64 - bl CNAME(ffi_closure_SYSV_inner) + bl CNAME(ffi_closure_inner) cmp r0, #FFI_TYPE_INT beq .Lretint_vfp diff --git a/Modules/_ctypes/libffi/src/bfin/ffi.c b/Modules/_ctypes/libffi/src/bfin/ffi.c index 0beccc14c932..22a2acdac192 100644 --- a/Modules/_ctypes/libffi/src/bfin/ffi.c +++ b/Modules/_ctypes/libffi/src/bfin/ffi.c @@ -1,5 +1,6 @@ /* ----------------------------------------------------------------------- - ffi.c - Copyright (c) 2012 Alexandre K. I. de Mendonca + ffi.c - Copyright (c) 2012 Alexandre K. I. de Mendonca , + Paulo Pizarro Blackfin Foreign Function Interface diff --git a/Modules/_ctypes/libffi/src/bfin/sysv.S b/Modules/_ctypes/libffi/src/bfin/sysv.S index ae7a1529b123..f4278be2426d 100644 --- a/Modules/_ctypes/libffi/src/bfin/sysv.S +++ b/Modules/_ctypes/libffi/src/bfin/sysv.S @@ -1,5 +1,6 @@ /* ----------------------------------------------------------------------- - sysv.S - Copyright (c) 2012 Alexandre K. I. de Mendonca + sysv.S - Copyright (c) 2012 Alexandre K. I. de Mendonca , + Paulo Pizarro Blackfin Foreign Function Interface @@ -32,7 +33,7 @@ .align 4 /* - There is a "feature" in the bfin toolchain that it puts a _ before funcion names + There is a "feature" in the bfin toolchain that it puts a _ before function names that's why the function here it's called _ffi_call_SYSV and not ffi_call_SYSV */ .global _ffi_call_SYSV; @@ -40,25 +41,26 @@ .func ffi_call_SYSV /* - cif->bytes = R0 (fp+8) - &ecif = R1 (fp+12) - ffi_prep_args = R2 (fp+16) - ret_type = stack (fp+20) - ecif.rvalue = stack (fp+24) - fn = stack (fp+28) - got (fp+32) - There is room for improvement here (we can use temporary registers + cif->bytes = R0 (fp+8) + &ecif = R1 (fp+12) + ffi_prep_args = R2 (fp+16) + ret_type = stack (fp+20) + ecif.rvalue = stack (fp+24) + fn = stack (fp+28) + got (fp+32) + + There is room for improvement here (we can use temporary registers instead of saving the values in the memory) - REGS: - P5 => Stack pointer (function arguments) - R5 => cif->bytes - R4 => ret->type - - FP-20 = P3 - FP-16 = SP (parameters area) - FP-12 = SP (temp) - FP-08 = function return part 1 [R0] - FP-04 = function return part 2 [R1] + REGS: + P5 => Stack pointer (function arguments) + R5 => cif->bytes + R4 => ret->type + + FP-20 = P3 + FP-16 = SP (parameters area) + FP-12 = SP (temp) + FP-08 = function return part 1 [R0] + FP-04 = function return part 2 [R1] */ _ffi_call_SYSV: diff --git a/Modules/_ctypes/libffi/src/closures.c b/Modules/_ctypes/libffi/src/closures.c index 6298d6f0c4de..c7863f3d0ae1 100644 --- a/Modules/_ctypes/libffi/src/closures.c +++ b/Modules/_ctypes/libffi/src/closures.c @@ -34,7 +34,7 @@ #include #if !FFI_MMAP_EXEC_WRIT && !FFI_EXEC_TRAMPOLINE_TABLE -# if __gnu_linux__ +# if __gnu_linux__ && !defined(__ANDROID__) /* This macro indicates it may be forbidden to map anonymous memory with both write and execute permission. Code compiled when this option is defined will attempt to map such pages once, but if it @@ -181,10 +181,26 @@ static int emutramp_enabled = -1; static int emutramp_enabled_check (void) { - if (getenv ("FFI_DISABLE_EMUTRAMP") == NULL) - return 1; - else + char *buf = NULL; + size_t len = 0; + FILE *f; + int ret; + f = fopen ("/proc/self/status", "r"); + if (f == NULL) return 0; + ret = 0; + + while (getline (&buf, &len, f) != -1) + if (!strncmp (buf, "PaX:", 4)) + { + char emutramp; + if (sscanf (buf, "%*s %*c%c", &emutramp) == 1) + ret = (emutramp == 'E'); + break; + } + free (buf); + fclose (f); + return ret; } #define is_emutramp_enabled() (emutramp_enabled >= 0 ? emutramp_enabled \ @@ -264,7 +280,7 @@ static int open_temp_exec_file_dir (const char *dir) { static const char suffix[] = "/ffiXXXXXX"; - int lendir = strlen (dir); + size_t lendir = strlen (dir); char *tempname = __builtin_alloca (lendir + sizeof (suffix)); if (!tempname) @@ -382,7 +398,7 @@ open_temp_exec_file_opts_next (void) } /* Return a file descriptor of a temporary zero-sized file in a - writable and exexutable filesystem. */ + writable and executable filesystem. */ static int open_temp_exec_file (void) { diff --git a/Modules/_ctypes/libffi/src/dlmalloc.c b/Modules/_ctypes/libffi/src/dlmalloc.c index 2773953590e5..6e474b7c4f02 100644 --- a/Modules/_ctypes/libffi/src/dlmalloc.c +++ b/Modules/_ctypes/libffi/src/dlmalloc.c @@ -1260,7 +1260,7 @@ extern void* sbrk(ptrdiff_t); #define SIZE_T_BITSIZE (sizeof(size_t) << 3) /* Some constants coerced to size_t */ -/* Annoying but necessary to avoid errors on some plaftorms */ +/* Annoying but necessary to avoid errors on some platforms */ #define SIZE_T_ZERO ((size_t)0) #define SIZE_T_ONE ((size_t)1) #define SIZE_T_TWO ((size_t)2) @@ -1414,7 +1414,7 @@ static int win32munmap(void* ptr, size_t size) { #define CALL_MORECORE(S) MFAIL #endif /* HAVE_MORECORE */ -/* mstate bit set if continguous morecore disabled or failed */ +/* mstate bit set if contiguous morecore disabled or failed */ #define USE_NONCONTIGUOUS_BIT (4U) /* segment bit set in create_mspace_with_base */ @@ -1666,7 +1666,7 @@ struct malloc_chunk { typedef struct malloc_chunk mchunk; typedef struct malloc_chunk* mchunkptr; typedef struct malloc_chunk* sbinptr; /* The type of bins of chunks */ -typedef unsigned int bindex_t; /* Described below */ +typedef size_t bindex_t; /* Described below */ typedef unsigned int binmap_t; /* Described below */ typedef unsigned int flag_t; /* The type of various bit flag sets */ @@ -3095,8 +3095,8 @@ static void internal_malloc_stats(mstate m) { and choose its bk node as its replacement. 2. If x was the last node of its size, but not a leaf node, it must be replaced with a leaf node (not merely one with an open left or - right), to make sure that lefts and rights of descendents - correspond properly to bit masks. We use the rightmost descendent + right), to make sure that lefts and rights of descendants + correspond properly to bit masks. We use the rightmost descendant of x. We could use any other leaf, but this is easy to locate and tends to counteract removal of leftmosts elsewhere, and so keeps paths shorter than minimally guaranteed. This doesn't loop much @@ -3393,7 +3393,7 @@ static void add_segment(mstate m, char* tbase, size_t tsize, flag_t mmapped) { *ss = m->seg; /* Push current record */ m->seg.base = tbase; m->seg.size = tsize; - set_segment_flags(&m->seg, mmapped); + (void)set_segment_flags(&m->seg, mmapped); m->seg.next = ss; /* Insert trailing fenceposts */ @@ -3553,7 +3553,7 @@ static void* sys_alloc(mstate m, size_t nb) { if (!is_initialized(m)) { /* first-time initialization */ m->seg.base = m->least_addr = tbase; m->seg.size = tsize; - set_segment_flags(&m->seg, mmap_flag); + (void)set_segment_flags(&m->seg, mmap_flag); m->magic = mparams.magic; init_bins(m); if (is_global(m)) @@ -4502,7 +4502,7 @@ mspace create_mspace(size_t capacity, int locked) { char* tbase = (char*)(CALL_MMAP(tsize)); if (tbase != CMFAIL) { m = init_user_mstate(tbase, tsize); - set_segment_flags(&m->seg, IS_MMAPPED_BIT); + (void)set_segment_flags(&m->seg, IS_MMAPPED_BIT); set_lock(m, locked); } } @@ -4517,7 +4517,7 @@ mspace create_mspace_with_base(void* base, size_t capacity, int locked) { if (capacity > msize + TOP_FOOT_SIZE && capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) { m = init_user_mstate((char*)base, capacity); - set_segment_flags(&m->seg, EXTERN_BIT); + (void)set_segment_flags(&m->seg, EXTERN_BIT); set_lock(m, locked); } return (mspace)m; @@ -5096,10 +5096,10 @@ int mspace_mallopt(int param_number, int value) { Wolfram Gloger (Gloger@lrz.uni-muenchen.de). * Use last_remainder in more cases. * Pack bins using idea from colin@nyx10.cs.du.edu - * Use ordered bins instead of best-fit threshhold + * Use ordered bins instead of best-fit threshold * Eliminate block-local decls to simplify tracing and debugging. * Support another case of realloc via move into top - * Fix error occuring when initial sbrk_base not word-aligned. + * Fix error occurring when initial sbrk_base not word-aligned. * Rely on page size for units instead of SBRK_UNIT to avoid surprises about sbrk alignment conventions. * Add mallinfo, mallopt. Thanks to Raymond Nijssen diff --git a/Modules/_ctypes/libffi/src/ia64/ffi.c b/Modules/_ctypes/libffi/src/ia64/ffi.c index 9533ef68b584..b77a836ddcf7 100644 --- a/Modules/_ctypes/libffi/src/ia64/ffi.c +++ b/Modules/_ctypes/libffi/src/ia64/ffi.c @@ -401,7 +401,7 @@ ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) the closure (in the "trampoline" area), but we replace the gp pointer with a pointer to the closure itself. We also add the real gp pointer to the closure. This allows the function entry code to - both retrieve the user data, and to restire the correct gp pointer. */ + both retrieve the user data, and to restore the correct gp pointer. */ extern void ffi_closure_unix (); diff --git a/Modules/_ctypes/libffi/src/m88k/ffi.c b/Modules/_ctypes/libffi/src/m88k/ffi.c new file mode 100644 index 000000000000..68df494955e4 --- /dev/null +++ b/Modules/_ctypes/libffi/src/m88k/ffi.c @@ -0,0 +1,400 @@ +/* + * Copyright (c) 2013 Miodrag Vallat. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * ``Software''), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * m88k Foreign Function Interface + * + * This file attempts to provide all the FFI entry points which can reliably + * be implemented in C. + * + * Only OpenBSD/m88k is currently supported; other platforms (such as + * Motorola's SysV/m88k) could be supported with the following tweaks: + * + * - non-OpenBSD systems use an `outgoing parameter area' as part of the + * 88BCS calling convention, which is not supported under OpenBSD from + * release 3.6 onwards. Supporting it should be as easy as taking it + * into account when adjusting the stack, in the assembly code. + * + * - the logic deciding whether a function argument gets passed through + * registers, or on the stack, has changed several times in OpenBSD in + * edge cases (especially for structs larger than 32 bytes being passed + * by value). The code below attemps to match the logic used by the + * system compiler of OpenBSD 5.3, i.e. gcc 3.3.6 with many m88k backend + * fixes. + */ + +#include +#include + +#include +#include + +void ffi_call_OBSD (unsigned int, extended_cif *, unsigned int, void *, + void (*fn) ()); +void *ffi_prep_args (void *, extended_cif *); +void ffi_closure_OBSD (ffi_closure *); +void ffi_closure_struct_OBSD (ffi_closure *); +unsigned int ffi_closure_OBSD_inner (ffi_closure *, void *, unsigned int *, + char *); +void ffi_cacheflush_OBSD (unsigned int, unsigned int); + +#define CIF_FLAGS_INT (1 << 0) +#define CIF_FLAGS_DINT (1 << 1) + +/* + * Foreign Function Interface API + */ + +/* ffi_prep_args is called by the assembly routine once stack space has + been allocated for the function's arguments. */ + +void * +ffi_prep_args (void *stack, extended_cif *ecif) +{ + unsigned int i; + void **p_argv; + char *argp, *stackp; + unsigned int *regp; + unsigned int regused; + ffi_type **p_arg; + void *struct_value_ptr; + + regp = (unsigned int *)stack; + stackp = (char *)(regp + 8); + regused = 0; + + if (ecif->cif->rtype->type == FFI_TYPE_STRUCT + && !ecif->cif->flags) + struct_value_ptr = ecif->rvalue; + else + struct_value_ptr = NULL; + + p_argv = ecif->avalue; + + for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; i != 0; i--, p_arg++) + { + size_t z; + unsigned short t, a; + + z = (*p_arg)->size; + t = (*p_arg)->type; + a = (*p_arg)->alignment; + + /* + * Figure out whether the argument can be passed through registers + * or on the stack. + * The rule is that registers can only receive simple types not larger + * than 64 bits, or structs the exact size of a register and aligned to + * the size of a register. + */ + if (t == FFI_TYPE_STRUCT) + { + if (z == sizeof (int) && a == sizeof (int) && regused < 8) + argp = (char *)regp; + else + argp = stackp; + } + else + { + if (z > sizeof (int) && regused < 8 - 1) + { + /* align to an even register pair */ + if (regused & 1) + { + regp++; + regused++; + } + } + if (regused < 8) + argp = (char *)regp; + else + argp = stackp; + } + + /* Enforce proper stack alignment of 64-bit types */ + if (argp == stackp && a > sizeof (int)) + { + stackp = (char *) ALIGN(stackp, a); + argp = stackp; + } + + switch (t) + { + case FFI_TYPE_SINT8: + *(signed int *) argp = (signed int) *(SINT8 *) *p_argv; + break; + + case FFI_TYPE_UINT8: + *(unsigned int *) argp = (unsigned int) *(UINT8 *) *p_argv; + break; + + case FFI_TYPE_SINT16: + *(signed int *) argp = (signed int) *(SINT16 *) *p_argv; + break; + + case FFI_TYPE_UINT16: + *(unsigned int *) argp = (unsigned int) *(UINT16 *) *p_argv; + break; + + case FFI_TYPE_INT: + case FFI_TYPE_FLOAT: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT32: + case FFI_TYPE_POINTER: + *(unsigned int *) argp = *(unsigned int *) *p_argv; + break; + + case FFI_TYPE_DOUBLE: + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + case FFI_TYPE_STRUCT: + memcpy (argp, *p_argv, z); + break; + + default: + FFI_ASSERT (0); + } + + /* Align if necessary. */ + if ((sizeof (int) - 1) & z) + z = ALIGN(z, sizeof (int)); + + p_argv++; + + /* Be careful, once all registers are filled, and about to continue + on stack, regp == stackp. Therefore the check for regused as well. */ + if (argp == (char *)regp && regused < 8) + { + regp += z / sizeof (int); + regused += z / sizeof (int); + } + else + stackp += z; + } + + return struct_value_ptr; +} + +/* Perform machine dependent cif processing */ +ffi_status +ffi_prep_cif_machdep (ffi_cif *cif) +{ + /* Set the return type flag */ + switch (cif->rtype->type) + { + case FFI_TYPE_VOID: + cif->flags = 0; + break; + + case FFI_TYPE_STRUCT: + if (cif->rtype->size == sizeof (int) && + cif->rtype->alignment == sizeof (int)) + cif->flags = CIF_FLAGS_INT; + else + cif->flags = 0; + break; + + case FFI_TYPE_DOUBLE: + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + cif->flags = CIF_FLAGS_DINT; + break; + + default: + cif->flags = CIF_FLAGS_INT; + break; + } + + return FFI_OK; +} + +void +ffi_call (ffi_cif *cif, void (*fn) (), void *rvalue, void **avalue) +{ + extended_cif ecif; + + ecif.cif = cif; + ecif.avalue = avalue; + + /* If the return value is a struct and we don't have a return value + address then we need to make one. */ + + if (rvalue == NULL + && cif->rtype->type == FFI_TYPE_STRUCT + && (cif->rtype->size != sizeof (int) + || cif->rtype->alignment != sizeof (int))) + ecif.rvalue = alloca (cif->rtype->size); + else + ecif.rvalue = rvalue; + + switch (cif->abi) + { + case FFI_OBSD: + ffi_call_OBSD (cif->bytes, &ecif, cif->flags, ecif.rvalue, fn); + break; + + default: + FFI_ASSERT (0); + break; + } +} + +/* + * Closure API + */ + +static void +ffi_prep_closure_args_OBSD (ffi_cif *cif, void **avalue, unsigned int *regp, + char *stackp) +{ + unsigned int i; + void **p_argv; + char *argp; + unsigned int regused; + ffi_type **p_arg; + + regused = 0; + + p_argv = avalue; + + for (i = cif->nargs, p_arg = cif->arg_types; i != 0; i--, p_arg++) + { + size_t z; + unsigned short t, a; + + z = (*p_arg)->size; + t = (*p_arg)->type; + a = (*p_arg)->alignment; + + /* + * Figure out whether the argument has been passed through registers + * or on the stack. + * The rule is that registers can only receive simple types not larger + * than 64 bits, or structs the exact size of a register and aligned to + * the size of a register. + */ + if (t == FFI_TYPE_STRUCT) + { + if (z == sizeof (int) && a == sizeof (int) && regused < 8) + argp = (char *)regp; + else + argp = stackp; + } + else + { + if (z > sizeof (int) && regused < 8 - 1) + { + /* align to an even register pair */ + if (regused & 1) + { + regp++; + regused++; + } + } + if (regused < 8) + argp = (char *)regp; + else + argp = stackp; + } + + /* Enforce proper stack alignment of 64-bit types */ + if (argp == stackp && a > sizeof (int)) + { + stackp = (char *) ALIGN(stackp, a); + argp = stackp; + } + + if (z < sizeof (int) && t != FFI_TYPE_STRUCT) + *p_argv = (void *) (argp + sizeof (int) - z); + else + *p_argv = (void *) argp; + + /* Align if necessary */ + if ((sizeof (int) - 1) & z) + z = ALIGN(z, sizeof (int)); + + p_argv++; + + /* Be careful, once all registers are exhausted, and about to fetch from + stack, regp == stackp. Therefore the check for regused as well. */ + if (argp == (char *)regp && regused < 8) + { + regp += z / sizeof (int); + regused += z / sizeof (int); + } + else + stackp += z; + } +} + +unsigned int +ffi_closure_OBSD_inner (ffi_closure *closure, void *resp, unsigned int *regp, + char *stackp) +{ + ffi_cif *cif; + void **arg_area; + + cif = closure->cif; + arg_area = (void**) alloca (cif->nargs * sizeof (void *)); + + ffi_prep_closure_args_OBSD(cif, arg_area, regp, stackp); + + (closure->fun) (cif, resp, arg_area, closure->user_data); + + return cif->flags; +} + +ffi_status +ffi_prep_closure_loc (ffi_closure* closure, ffi_cif* cif, + void (*fun)(ffi_cif*,void*,void**,void*), + void *user_data, void *codeloc) +{ + unsigned int *tramp = (unsigned int *) codeloc; + void *fn; + + FFI_ASSERT (cif->abi == FFI_OBSD); + + if (cif->rtype->type == FFI_TYPE_STRUCT && !cif->flags) + fn = &ffi_closure_struct_OBSD; + else + fn = &ffi_closure_OBSD; + + /* or.u %r10, %r0, %hi16(fn) */ + tramp[0] = 0x5d400000 | (((unsigned int)fn) >> 16); + /* or.u %r13, %r0, %hi16(closure) */ + tramp[1] = 0x5da00000 | ((unsigned int)closure >> 16); + /* or %r10, %r10, %lo16(fn) */ + tramp[2] = 0x594a0000 | (((unsigned int)fn) & 0xffff); + /* jmp.n %r10 */ + tramp[3] = 0xf400c40a; + /* or %r13, %r13, %lo16(closure) */ + tramp[4] = 0x59ad0000 | ((unsigned int)closure & 0xffff); + + ffi_cacheflush_OBSD((unsigned int)codeloc, FFI_TRAMPOLINE_SIZE); + + closure->cif = cif; + closure->user_data = user_data; + closure->fun = fun; + + return FFI_OK; +} diff --git a/Modules/_ctypes/libffi/src/m88k/ffitarget.h b/Modules/_ctypes/libffi/src/m88k/ffitarget.h new file mode 100644 index 000000000000..e52bf9fa30a4 --- /dev/null +++ b/Modules/_ctypes/libffi/src/m88k/ffitarget.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013 Miodrag Vallat. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * ``Software''), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * m88k Foreign Function Interface + */ + +#ifndef LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +#ifndef LIBFFI_ASM +typedef unsigned long ffi_arg; +typedef signed long ffi_sarg; + +typedef enum ffi_abi { + FFI_FIRST_ABI = 0, + FFI_OBSD, + FFI_DEFAULT_ABI = FFI_OBSD, + FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 +} ffi_abi; +#endif + +/* ---- Definitions for closures ----------------------------------------- */ + +#define FFI_CLOSURES 1 +#define FFI_TRAMPOLINE_SIZE 0x14 +#define FFI_NATIVE_RAW_API 0 + +#endif diff --git a/Modules/_ctypes/libffi/src/m88k/obsd.S b/Modules/_ctypes/libffi/src/m88k/obsd.S new file mode 100644 index 000000000000..1944a23de424 --- /dev/null +++ b/Modules/_ctypes/libffi/src/m88k/obsd.S @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2013 Miodrag Vallat. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * ``Software''), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * m88k Foreign Function Interface + */ + +#define LIBFFI_ASM +#include +#include + + .text + +/* + * ffi_cacheflush_OBSD(unsigned int addr, %r2 + * unsigned int size); %r3 + */ + .align 4 + .globl ffi_cacheflush_OBSD + .type ffi_cacheflush_OBSD,@function +ffi_cacheflush_OBSD: + tb0 0, %r0, 451 + or %r0, %r0, %r0 + jmp %r1 + .size ffi_cacheflush_OBSD, . - ffi_cacheflush_OBSD + +/* + * ffi_call_OBSD(unsigned bytes, %r2 + * extended_cif *ecif, %r3 + * unsigned flags, %r4 + * void *rvalue, %r5 + * void (*fn)()); %r6 + */ + .align 4 + .globl ffi_call_OBSD + .type ffi_call_OBSD,@function +ffi_call_OBSD: + subu %r31, %r31, 32 + st %r30, %r31, 4 + st %r1, %r31, 0 + addu %r30, %r31, 32 + + | Save the few arguments we'll need after ffi_prep_args() + st.d %r4, %r31, 8 + st %r6, %r31, 16 + + | Allocate room for the image of r2-r9, and the stack space for + | the args (rounded to a 16-byte boundary) + addu %r2, %r2, (8 * 4) + 15 + clr %r2, %r2, 4<0> + subu %r31, %r31, %r2 + + | Fill register and stack image + or %r2, %r31, %r0 +#ifdef PIC + bsr ffi_prep_args#plt +#else + bsr ffi_prep_args +#endif + + | Save pointer to return struct address, if any + or %r12, %r2, %r0 + + | Get function pointer + subu %r4, %r30, 32 + ld %r1, %r4, 16 + + | Fetch the register arguments + ld.d %r2, %r31, (0 * 4) + ld.d %r4, %r31, (2 * 4) + ld.d %r6, %r31, (4 * 4) + ld.d %r8, %r31, (6 * 4) + addu %r31, %r31, (8 * 4) + + | Invoke the function + jsr %r1 + + | Restore stack now that we don't need the args anymore + subu %r31, %r30, 32 + + | Figure out what to return as the function's return value + ld %r5, %r31, 12 | rvalue + ld %r4, %r31, 8 | flags + + bcnd eq0, %r5, 9f + + bb0 0, %r4, 1f | CIF_FLAGS_INT + st %r2, %r5, 0 + br 9f + +1: + bb0 1, %r4, 1f | CIF_FLAGS_DINT + st.d %r2, %r5, 0 + br 9f + +1: +9: + ld %r1, %r31, 0 + ld %r30, %r31, 4 + jmp.n %r1 + addu %r31, %r31, 32 + .size ffi_call_OBSD, . - ffi_call_OBSD + +/* + * ffi_closure_OBSD(ffi_closure *closure); %r13 + */ + .align 4 + .globl ffi_closure_OBSD + .type ffi_closure_OBSD, @function +ffi_closure_OBSD: + subu %r31, %r31, 16 + st %r30, %r31, 4 + st %r1, %r31, 0 + addu %r30, %r31, 16 + + | Make room on the stack for saved register arguments and return + | value + subu %r31, %r31, (8 * 4) + (2 * 4) + st.d %r2, %r31, (0 * 4) + st.d %r4, %r31, (2 * 4) + st.d %r6, %r31, (4 * 4) + st.d %r8, %r31, (6 * 4) + + | Invoke the closure function + or %r5, %r30, 0 | calling stack + addu %r4, %r31, 0 | saved registers + addu %r3, %r31, (8 * 4) | return value + or %r2, %r13, %r0 | closure +#ifdef PIC + bsr ffi_closure_OBSD_inner#plt +#else + bsr ffi_closure_OBSD_inner +#endif + + | Figure out what to return as the function's return value + bb0 0, %r2, 1f | CIF_FLAGS_INT + ld %r2, %r31, (8 * 4) + br 9f + +1: + bb0 1, %r2, 1f | CIF_FLAGS_DINT + ld.d %r2, %r31, (8 * 4) + br 9f + +1: +9: + subu %r31, %r30, 16 + ld %r1, %r31, 0 + ld %r30, %r31, 4 + jmp.n %r1 + addu %r31, %r31, 16 + .size ffi_closure_OBSD,.-ffi_closure_OBSD + +/* + * ffi_closure_struct_OBSD(ffi_closure *closure); %r13 + */ + .align 4 + .globl ffi_closure_struct_OBSD + .type ffi_closure_struct_OBSD, @function +ffi_closure_struct_OBSD: + subu %r31, %r31, 16 + st %r30, %r31, 4 + st %r1, %r31, 0 + addu %r30, %r31, 16 + + | Make room on the stack for saved register arguments + subu %r31, %r31, (8 * 4) + st.d %r2, %r31, (0 * 4) + st.d %r4, %r31, (2 * 4) + st.d %r6, %r31, (4 * 4) + st.d %r8, %r31, (6 * 4) + + | Invoke the closure function + or %r5, %r30, 0 | calling stack + addu %r4, %r31, 0 | saved registers + or %r3, %r12, 0 | return value + or %r2, %r13, %r0 | closure +#ifdef PIC + bsr ffi_closure_OBSD_inner#plt +#else + bsr ffi_closure_OBSD_inner +#endif + + subu %r31, %r30, 16 + ld %r1, %r31, 0 + ld %r30, %r31, 4 + jmp.n %r1 + addu %r31, %r31, 16 + .size ffi_closure_struct_OBSD,.-ffi_closure_struct_OBSD diff --git a/Modules/_ctypes/libffi/src/microblaze/ffi.c b/Modules/_ctypes/libffi/src/microblaze/ffi.c index 5c155c5bc5d8..ea962ea4837d 100644 --- a/Modules/_ctypes/libffi/src/microblaze/ffi.c +++ b/Modules/_ctypes/libffi/src/microblaze/ffi.c @@ -183,7 +183,7 @@ void ffi_closure_call_SYSV(void* register_args, void* stack_args, ffi_type** arg_types = cif->arg_types; /* re-allocate data for the args. This needs to be done in order to keep - * multi-word objects (e.g. structs) in contigious memory. Callers are not + * multi-word objects (e.g. structs) in contiguous memory. Callers are not * required to store the value of args in the lower 6 words in the stack * (although they are allocated in the stack). */ diff --git a/Modules/_ctypes/libffi/src/microblaze/sysv.S b/Modules/_ctypes/libffi/src/microblaze/sysv.S index 7a195a634c2f..ea43e9d54539 100644 --- a/Modules/_ctypes/libffi/src/microblaze/sysv.S +++ b/Modules/_ctypes/libffi/src/microblaze/sysv.S @@ -134,7 +134,7 @@ ffi_call_SYSV: rsubi r11, r23, 8 beqi r11, ffi_call_SYSV_store64 - /* Didnt match anything */ + /* Didn't match anything */ bri ffi_call_SYSV_end ffi_call_SYSV_store64: @@ -210,7 +210,7 @@ ffi_closure_SYSV: addik r7, r12, 0 /* closure object */ addik r1, r1, -8 /* allocate return value */ addik r8, r1, 0 /* void* rvalue */ - addik r1, r1, -8 /* allocate for reutrn type/size values */ + addik r1, r1, -8 /* allocate for return type/size values */ addik r9, r1, 0 /* void* rtype */ addik r10, r1, 4 /* void* rsize */ @@ -247,7 +247,7 @@ ffi_closure_SYSV_prepare_return: rsubi r11, r10, 8 beqi r11, ffi_closure_SYSV_store64 - /* Didnt match anything */ + /* Didn't match anything */ bri ffi_closure_SYSV_end ffi_closure_SYSV_store64: diff --git a/Modules/_ctypes/libffi/src/mips/ffi.c b/Modules/_ctypes/libffi/src/mips/ffi.c index 03121e39222e..5d0dd70cb328 100644 --- a/Modules/_ctypes/libffi/src/mips/ffi.c +++ b/Modules/_ctypes/libffi/src/mips/ffi.c @@ -170,7 +170,14 @@ static void ffi_prep_args(char *stack, break; case FFI_TYPE_UINT32: +#ifdef FFI_MIPS_N32 + /* The N32 ABI requires that 32-bit integers + be sign-extended to 64-bits, regardless of + whether they are signed or unsigned. */ + *(ffi_arg *)argp = *(SINT32 *)(* p_argv); +#else *(ffi_arg *)argp = *(UINT32 *)(* p_argv); +#endif break; /* This can only happen with 64bit slots. */ diff --git a/Modules/_ctypes/libffi/src/mips/n32.S b/Modules/_ctypes/libffi/src/mips/n32.S index ff4bbce1decb..c6985d30a6f6 100644 --- a/Modules/_ctypes/libffi/src/mips/n32.S +++ b/Modules/_ctypes/libffi/src/mips/n32.S @@ -108,10 +108,8 @@ loadregs: REG_L t6, 3*FFI_SIZEOF_ARG($fp) # load the flags word into t6. and t4, t6, ((1< +#include + +#include + +/* The Nios II Processor Reference Handbook defines the procedure call + ABI as follows. + + Arguments are passed as if a structure containing the types of + the arguments were constructed. The first 16 bytes are passed in r4 + through r7, the remainder on the stack. The first 16 bytes of a function + taking variable arguments are passed in r4-r7 in the same way. + + Return values of types up to 8 bytes are returned in r2 and r3. For + return values greater than 8 bytes, the caller must allocate memory for + the result and pass the address as if it were argument 0. + + While this isn't specified explicitly in the ABI documentation, GCC + promotes integral arguments smaller than int size to 32 bits. + + Also of note, the ABI specifies that all structure objects are + aligned to 32 bits even if all their fields have a smaller natural + alignment. See FFI_AGGREGATE_ALIGNMENT. */ + + +/* Declare the assembly language hooks. */ + +extern UINT64 ffi_call_sysv (void (*) (char *, extended_cif *), + extended_cif *, + unsigned, + void (*fn) (void)); +extern void ffi_closure_sysv (void); + +/* Perform machine-dependent cif processing. */ + +ffi_status ffi_prep_cif_machdep (ffi_cif *cif) +{ + /* We always want at least 16 bytes in the parameter block since it + simplifies the low-level call function. Also round the parameter + block size up to a multiple of 4 bytes to preserve + 32-bit alignment of the stack pointer. */ + if (cif->bytes < 16) + cif->bytes = 16; + else + cif->bytes = (cif->bytes + 3) & ~3; + + return FFI_OK; +} + + +/* ffi_prep_args is called by the assembly routine to transfer arguments + to the stack using the pointers in the ecif array. + Note that the stack buffer is big enough to fit all the arguments, + but the first 16 bytes will be copied to registers for the actual + call. */ + +void ffi_prep_args (char *stack, extended_cif *ecif) +{ + char *argp = stack; + unsigned int i; + + /* The implicit return value pointer is passed as if it were a hidden + first argument. */ + if (ecif->cif->rtype->type == FFI_TYPE_STRUCT + && ecif->cif->rtype->size > 8) + { + (*(void **) argp) = ecif->rvalue; + argp += 4; + } + + for (i = 0; i < ecif->cif->nargs; i++) + { + void *avalue = ecif->avalue[i]; + ffi_type *atype = ecif->cif->arg_types[i]; + size_t size = atype->size; + size_t alignment = atype->alignment; + + /* Align argp as appropriate for the argument type. */ + if ((alignment - 1) & (unsigned) argp) + argp = (char *) ALIGN (argp, alignment); + + /* Copy the argument, promoting integral types smaller than a + word to word size. */ + if (size < sizeof (int)) + { + size = sizeof (int); + switch (atype->type) + { + case FFI_TYPE_SINT8: + *(signed int *) argp = (signed int) *(SINT8 *) avalue; + break; + + case FFI_TYPE_UINT8: + *(unsigned int *) argp = (unsigned int) *(UINT8 *) avalue; + break; + + case FFI_TYPE_SINT16: + *(signed int *) argp = (signed int) *(SINT16 *) avalue; + break; + + case FFI_TYPE_UINT16: + *(unsigned int *) argp = (unsigned int) *(UINT16 *) avalue; + break; + + case FFI_TYPE_STRUCT: + memcpy (argp, avalue, atype->size); + break; + + default: + FFI_ASSERT(0); + } + } + else if (size == sizeof (int)) + *(unsigned int *) argp = (unsigned int) *(UINT32 *) avalue; + else + memcpy (argp, avalue, size); + argp += size; + } +} + + +/* Call FN using the prepared CIF. RVALUE points to space allocated by + the caller for the return value, and AVALUE is an array of argument + pointers. */ + +void ffi_call (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue) +{ + + extended_cif ecif; + UINT64 result; + + /* If bigret is true, this is the case where a return value of larger + than 8 bytes is handled by being passed by reference as an implicit + argument. */ + int bigret = (cif->rtype->type == FFI_TYPE_STRUCT + && cif->rtype->size > 8); + + ecif.cif = cif; + ecif.avalue = avalue; + + /* Allocate space for return value if this is the pass-by-reference case + and the caller did not provide a buffer. */ + if (rvalue == NULL && bigret) + ecif.rvalue = alloca (cif->rtype->size); + else + ecif.rvalue = rvalue; + + result = ffi_call_sysv (ffi_prep_args, &ecif, cif->bytes, fn); + + /* Now result contains the 64 bit contents returned from fn in + r2 and r3. Copy the value of the appropriate size to the user-provided + rvalue buffer. */ + if (rvalue && !bigret) + switch (cif->rtype->size) + { + case 1: + *(UINT8 *)rvalue = (UINT8) result; + break; + case 2: + *(UINT16 *)rvalue = (UINT16) result; + break; + case 4: + *(UINT32 *)rvalue = (UINT32) result; + break; + case 8: + *(UINT64 *)rvalue = (UINT64) result; + break; + default: + memcpy (rvalue, (void *)&result, cif->rtype->size); + break; + } +} + +/* This function is invoked from the closure trampoline to invoke + CLOSURE with argument block ARGS. Parse ARGS according to + CLOSURE->cfi and invoke CLOSURE->fun. */ + +static UINT64 +ffi_closure_helper (unsigned char *args, + ffi_closure *closure) +{ + ffi_cif *cif = closure->cif; + unsigned char *argp = args; + void **parsed_args = alloca (cif->nargs * sizeof (void *)); + UINT64 result; + void *retptr; + unsigned int i; + + /* First figure out what to do about the return type. If this is the + big-structure-return case, the first arg is the hidden return buffer + allocated by the caller. */ + if (cif->rtype->type == FFI_TYPE_STRUCT + && cif->rtype->size > 8) + { + retptr = *((void **) argp); + argp += 4; + } + else + retptr = (void *) &result; + + /* Fill in the array of argument pointers. */ + for (i = 0; i < cif->nargs; i++) + { + size_t size = cif->arg_types[i]->size; + size_t alignment = cif->arg_types[i]->alignment; + + /* Align argp as appropriate for the argument type. */ + if ((alignment - 1) & (unsigned) argp) + argp = (char *) ALIGN (argp, alignment); + + /* Arguments smaller than an int are promoted to int. */ + if (size < sizeof (int)) + size = sizeof (int); + + /* Store the pointer. */ + parsed_args[i] = argp; + argp += size; + } + + /* Call the user-supplied function. */ + (closure->fun) (cif, retptr, parsed_args, closure->user_data); + return result; +} + + +/* Initialize CLOSURE with a trampoline to call FUN with + CIF and USER_DATA. */ +ffi_status +ffi_prep_closure_loc (ffi_closure* closure, + ffi_cif* cif, + void (*fun) (ffi_cif*, void*, void**, void*), + void *user_data, + void *codeloc) +{ + unsigned int *tramp = (unsigned int *) &closure->tramp[0]; + int i; + + if (cif->abi != FFI_SYSV) + return FFI_BAD_ABI; + + /* The trampoline looks like: + movhi r8, %hi(ffi_closure_sysv) + ori r8, r8, %lo(ffi_closure_sysv) + movhi r9, %hi(ffi_closure_helper) + ori r0, r9, %lo(ffi_closure_helper) + movhi r10, %hi(closure) + ori r10, r10, %lo(closure) + jmp r8 + and then ffi_closure_sysv retrieves the closure pointer out of r10 + in addition to the arguments passed in the normal way for the call, + and invokes ffi_closure_helper. We encode the pointer to + ffi_closure_helper in the trampoline because making a PIC call + to it in ffi_closure_sysv would be messy (it would have to indirect + through the GOT). */ + +#define HI(x) ((((unsigned int) (x)) >> 16) & 0xffff) +#define LO(x) (((unsigned int) (x)) & 0xffff) + tramp[0] = (0 << 27) | (8 << 22) | (HI (ffi_closure_sysv) << 6) | 0x34; + tramp[1] = (8 << 27) | (8 << 22) | (LO (ffi_closure_sysv) << 6) | 0x14; + tramp[2] = (0 << 27) | (9 << 22) | (HI (ffi_closure_helper) << 6) | 0x34; + tramp[3] = (9 << 27) | (9 << 22) | (LO (ffi_closure_helper) << 6) | 0x14; + tramp[4] = (0 << 27) | (10 << 22) | (HI (closure) << 6) | 0x34; + tramp[5] = (10 << 27) | (10 << 22) | (LO (closure) << 6) | 0x14; + tramp[6] = (8 << 27) | (0x0d << 11) | 0x3a; +#undef HI +#undef LO + + /* Flush the caches. + See Example 9-4 in the Nios II Software Developer's Handbook. */ + for (i = 0; i < 7; i++) + asm volatile ("flushd 0(%0); flushi %0" :: "r"(tramp + i) : "memory"); + asm volatile ("flushp" ::: "memory"); + + closure->cif = cif; + closure->fun = fun; + closure->user_data = user_data; + + return FFI_OK; +} + diff --git a/Modules/_ctypes/libffi/src/nios2/ffitarget.h b/Modules/_ctypes/libffi/src/nios2/ffitarget.h new file mode 100644 index 000000000000..134d118c12a2 --- /dev/null +++ b/Modules/_ctypes/libffi/src/nios2/ffitarget.h @@ -0,0 +1,52 @@ +/* libffi target includes for Altera Nios II. + + Copyright (c) 2013 Mentor Graphics. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + + +#ifndef LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +#ifndef LIBFFI_H +#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." +#endif + +#ifndef LIBFFI_ASM +typedef unsigned long ffi_arg; +typedef signed long ffi_sarg; + +typedef enum ffi_abi { + FFI_FIRST_ABI = 0, + FFI_SYSV, + FFI_LAST_ABI, + FFI_DEFAULT_ABI = FFI_SYSV +} ffi_abi; +#endif + +/* Structures have a 4-byte alignment even if all the fields have lesser + alignment requirements. */ +#define FFI_AGGREGATE_ALIGNMENT 4 + +#define FFI_CLOSURES 1 +#define FFI_TRAMPOLINE_SIZE 28 /* 7 instructions */ +#define FFI_NATIVE_RAW_API 0 + +#endif diff --git a/Modules/_ctypes/libffi/src/nios2/sysv.S b/Modules/_ctypes/libffi/src/nios2/sysv.S new file mode 100644 index 000000000000..75f442bbeeb9 --- /dev/null +++ b/Modules/_ctypes/libffi/src/nios2/sysv.S @@ -0,0 +1,136 @@ +/* Low-level libffi support for Altera Nios II. + + Copyright (c) 2013 Mentor Graphics. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +/* This function is declared on the C side as + + extern UINT64 ffi_call_sysv (void (*arghook) (char *, extended_cif *), + extended_cif *ecif, + unsigned nbytes, + void (*fn) (void)); + + On input, the arguments appear as + r4 = arghook + r5 = ecif + r6 = nbytes + r7 = fn +*/ + + .section .text + .align 2 + .global ffi_call_sysv + .type ffi_call_sysv, @function + +ffi_call_sysv: + .cfi_startproc + + /* Create the stack frame, saving r16 so we can use it locally. */ + addi sp, sp, -12 + .cfi_def_cfa_offset 12 + stw ra, 8(sp) + stw fp, 4(sp) + stw r16, 0(sp) + .cfi_offset 31, -4 + .cfi_offset 28, -8 + .cfi_offset 16, -12 + mov fp, sp + .cfi_def_cfa_register 28 + mov r16, r7 + + /* Adjust the stack pointer to create the argument buffer + nbytes long. */ + sub sp, sp, r6 + + /* Call the arghook function. */ + mov r2, r4 /* fn */ + mov r4, sp /* argbuffer */ + callr r2 /* r5 already contains ecif */ + + /* Pop off the first 16 bytes of the argument buffer on the stack, + transferring the contents to the argument registers. */ + ldw r4, 0(sp) + ldw r5, 4(sp) + ldw r6, 8(sp) + ldw r7, 12(sp) + addi sp, sp, 16 + + /* Call the user function, which leaves its result in r2 and r3. */ + callr r16 + + /* Pop off the stack frame. */ + mov sp, fp + ldw ra, 8(sp) + ldw fp, 4(sp) + ldw r16, 0(sp) + addi sp, sp, 12 + ret + .cfi_endproc + .size ffi_call_sysv, .-ffi_call_sysv + + +/* Closure trampolines jump here after putting the C helper address + in r9 and the closure pointer in r10. The user-supplied arguments + to the closure are in the normal places, in r4-r7 and on the + stack. Push the register arguments on the stack too and then call the + C helper function to deal with them. */ + + .section .text + .align 2 + .global ffi_closure_sysv + .type ffi_closure_sysv, @function + +ffi_closure_sysv: + .cfi_startproc + + /* Create the stack frame, pushing the register args on the stack + just below the stack args. This is the same trick illustrated + in Figure 7-3 in the Nios II Processor Reference Handbook, used + for variable arguments and structures passed by value. */ + addi sp, sp, -20 + .cfi_def_cfa_offset 20 + stw ra, 0(sp) + .cfi_offset 31, -20 + stw r4, 4(sp) + .cfi_offset 4, -16 + stw r5, 8(sp) + .cfi_offset 5, -12 + stw r6, 12(sp) + .cfi_offset 6, -8 + stw r7, 16(sp) + .cfi_offset 7, -4 + + /* Call the helper. + r4 = pointer to arguments on stack + r5 = closure pointer (loaded in r10 by the trampoline) + r9 = address of helper function (loaded by trampoline) */ + addi r4, sp, 4 + mov r5, r10 + callr r9 + + /* Pop the stack and return. */ + ldw ra, 0(sp) + addi sp, sp, 20 + .cfi_def_cfa_offset -20 + ret + .cfi_endproc + .size ffi_closure_sysv, .-ffi_closure_sysv + diff --git a/Modules/_ctypes/libffi/src/powerpc/darwin.S b/Modules/_ctypes/libffi/src/powerpc/darwin.S index 4f987dc74824..066eb82efe93 100644 --- a/Modules/_ctypes/libffi/src/powerpc/darwin.S +++ b/Modules/_ctypes/libffi/src/powerpc/darwin.S @@ -318,11 +318,6 @@ _ffi_call_AIX: #define EH_DATA_ALIGN_FACT MODE_CHOICE(0x7c,0x78) - .static_data - .align LOG2_GPR_BYTES -LLFB0$non_lazy_ptr: - .g_long Lstartcode - .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support EH_frame1: .set L$set$0,LECIE1-LSCIE1 @@ -335,7 +330,7 @@ LSCIE1: .byte EH_DATA_ALIGN_FACT ; sleb128 -4; CIE Data Alignment Factor .byte 0x41 ; CIE RA Column .byte 0x1 ; uleb128 0x1; Augmentation size - .byte 0x10 ; FDE Encoding (indirect pcrel) + .byte 0x10 ; FDE Encoding (pcrel) .byte 0xc ; DW_CFA_def_cfa .byte 0x1 ; uleb128 0x1 .byte 0x0 ; uleb128 0x0 @@ -349,7 +344,7 @@ LSFDE1: .long L$set$1 ; FDE Length LASFDE1: .long LASFDE1-EH_frame1 ; FDE CIE offset - .g_long LLFB0$non_lazy_ptr-. ; FDE initial location + .g_long Lstartcode-. ; FDE initial location .set L$set$3,LFE1-Lstartcode .g_long L$set$3 ; FDE address range .byte 0x0 ; uleb128 0x0; Augmentation size diff --git a/Modules/_ctypes/libffi/src/powerpc/darwin_closure.S b/Modules/_ctypes/libffi/src/powerpc/darwin_closure.S index 3f6790f6bb39..c7734d419861 100644 --- a/Modules/_ctypes/libffi/src/powerpc/darwin_closure.S +++ b/Modules/_ctypes/libffi/src/powerpc/darwin_closure.S @@ -192,7 +192,7 @@ LCFI1: lg r0,0(r3) ; size => r0 lhz r3,FFI_TYPE_TYPE(r3) ; type => r3 - /* The helper will have intercepted struture returns and inserted + /* The helper will have intercepted structure returns and inserted the caller`s destination address for structs returned by ref. */ /* r3 contains the return type so use it to look up in a table @@ -467,11 +467,6 @@ Lendcode: #define EH_FRAME_OFFSETA MODE_CHOICE(176,0x90) #define EH_FRAME_OFFSETB MODE_CHOICE(1,3) - .static_data - .align LOG2_GPR_BYTES -LLFB1$non_lazy_ptr: - .g_long Lstartcode - .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support EH_frame1: .set L$set$0,LECIE1-LSCIE1 @@ -484,7 +479,7 @@ LSCIE1: .byte EH_DATA_ALIGN_FACT ; sleb128 -4; CIE Data Alignment Factor .byte 0x41 ; CIE RA Column .byte 0x1 ; uleb128 0x1; Augmentation size - .byte 0x10 ; FDE Encoding (indirect pcrel) + .byte 0x10 ; FDE Encoding (pcrel) .byte 0xc ; DW_CFA_def_cfa .byte 0x1 ; uleb128 0x1 .byte 0x0 ; uleb128 0x0 @@ -498,7 +493,7 @@ LSFDE1: LASFDE1: .long LASFDE1-EH_frame1 ; FDE CIE offset - .g_long LLFB1$non_lazy_ptr-. ; FDE initial location + .g_long Lstartcode-. ; FDE initial location .set L$set$3,LFE1-Lstartcode .g_long L$set$3 ; FDE address range .byte 0x0 ; uleb128 0x0; Augmentation size @@ -523,12 +518,12 @@ LEFDE1: L_ffi_closure_helper_DARWIN$stub: .indirect_symbol _ffi_closure_helper_DARWIN mflr r0 - bcl 20,31,"L00000000001$spb" -"L00000000001$spb": + bcl 20,31,"L1$spb" +"L1$spb": mflr r11 - addis r11,r11,ha16(L_ffi_closure_helper_DARWIN$lazy_ptr-"L00000000001$spb") + addis r11,r11,ha16(L_ffi_closure_helper_DARWIN$lazy_ptr-"L1$spb") mtlr r0 - lwzu r12,lo16(L_ffi_closure_helper_DARWIN$lazy_ptr-"L00000000001$spb")(r11) + lwzu r12,lo16(L_ffi_closure_helper_DARWIN$lazy_ptr-"L1$spb")(r11) mtctr r12 bctr .lazy_symbol_pointer @@ -542,12 +537,12 @@ L_ffi_closure_helper_DARWIN$lazy_ptr: L_darwin64_struct_ret_by_value_p$stub: .indirect_symbol _darwin64_struct_ret_by_value_p mflr r0 - bcl 20,31,"L00000000002$spb" -"L00000000002$spb": + bcl 20,31,"L2$spb" +"L2$spb": mflr r11 - addis r11,r11,ha16(L_darwin64_struct_ret_by_value_p$lazy_ptr-"L00000000002$spb") + addis r11,r11,ha16(L_darwin64_struct_ret_by_value_p$lazy_ptr-"L2$spb") mtlr r0 - lwzu r12,lo16(L_darwin64_struct_ret_by_value_p$lazy_ptr-"L00000000002$spb")(r11) + lwzu r12,lo16(L_darwin64_struct_ret_by_value_p$lazy_ptr-"L2$spb")(r11) mtctr r12 bctr .lazy_symbol_pointer @@ -560,12 +555,12 @@ L_darwin64_struct_ret_by_value_p$lazy_ptr: L_darwin64_pass_struct_floats$stub: .indirect_symbol _darwin64_pass_struct_floats mflr r0 - bcl 20,31,"L00000000003$spb" -"L00000000003$spb": + bcl 20,31,"L3$spb" +"L3$spb": mflr r11 - addis r11,r11,ha16(L_darwin64_pass_struct_floats$lazy_ptr-"L00000000003$spb") + addis r11,r11,ha16(L_darwin64_pass_struct_floats$lazy_ptr-"L3$spb") mtlr r0 - lwzu r12,lo16(L_darwin64_pass_struct_floats$lazy_ptr-"L00000000003$spb")(r11) + lwzu r12,lo16(L_darwin64_pass_struct_floats$lazy_ptr-"L3$spb")(r11) mtctr r12 bctr .lazy_symbol_pointer diff --git a/Modules/_ctypes/libffi/src/powerpc/ffi.c b/Modules/_ctypes/libffi/src/powerpc/ffi.c index 5381d3d10d22..efb441bbfc03 100644 --- a/Modules/_ctypes/libffi/src/powerpc/ffi.c +++ b/Modules/_ctypes/libffi/src/powerpc/ffi.c @@ -1,5 +1,6 @@ /* ----------------------------------------------------------------------- - ffi.c - Copyright (C) 2011 Anthony Green + ffi.c - Copyright (C) 2013 IBM + Copyright (C) 2011 Anthony Green Copyright (C) 2011 Kyle Moffett Copyright (C) 2008 Red Hat, Inc Copyright (C) 2007, 2008 Free Software Foundation, Inc @@ -27,993 +28,104 @@ OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------------------------------- */ -#include -#include - -#include -#include - - -extern void ffi_closure_SYSV (void); -extern void FFI_HIDDEN ffi_closure_LINUX64 (void); - -enum { - /* The assembly depends on these exact flags. */ - FLAG_RETURNS_SMST = 1 << (31-31), /* Used for FFI_SYSV small structs. */ - FLAG_RETURNS_NOTHING = 1 << (31-30), /* These go in cr7 */ -#ifndef __NO_FPRS__ - FLAG_RETURNS_FP = 1 << (31-29), -#endif - FLAG_RETURNS_64BITS = 1 << (31-28), - - FLAG_RETURNS_128BITS = 1 << (31-27), /* cr6 */ - - FLAG_SYSV_SMST_R4 = 1 << (31-26), /* use r4 for FFI_SYSV 8 byte - structs. */ - FLAG_SYSV_SMST_R3 = 1 << (31-25), /* use r3 for FFI_SYSV 4 byte - structs. */ - - FLAG_ARG_NEEDS_COPY = 1 << (31- 7), -#ifndef __NO_FPRS__ - FLAG_FP_ARGUMENTS = 1 << (31- 6), /* cr1.eq; specified by ABI */ -#endif - FLAG_4_GPR_ARGUMENTS = 1 << (31- 5), - FLAG_RETVAL_REFERENCE = 1 << (31- 4) -}; - -/* About the SYSV ABI. */ -#define ASM_NEEDS_REGISTERS 4 -#define NUM_GPR_ARG_REGISTERS 8 -#ifndef __NO_FPRS__ -# define NUM_FPR_ARG_REGISTERS 8 -#endif - -/* ffi_prep_args_SYSV is called by the assembly routine once stack space - has been allocated for the function's arguments. - - The stack layout we want looks like this: - - | Return address from ffi_call_SYSV 4bytes | higher addresses - |--------------------------------------------| - | Previous backchain pointer 4 | stack pointer here - |--------------------------------------------|<+ <<< on entry to - | Saved r28-r31 4*4 | | ffi_call_SYSV - |--------------------------------------------| | - | GPR registers r3-r10 8*4 | | ffi_call_SYSV - |--------------------------------------------| | - | FPR registers f1-f8 (optional) 8*8 | | - |--------------------------------------------| | stack | - | Space for copied structures | | grows | - |--------------------------------------------| | down V - | Parameters that didn't fit in registers | | - |--------------------------------------------| | lower addresses - | Space for callee's LR 4 | | - |--------------------------------------------| | stack pointer here - | Current backchain pointer 4 |-/ during - |--------------------------------------------| <<< ffi_call_SYSV - -*/ - -void -ffi_prep_args_SYSV (extended_cif *ecif, unsigned *const stack) -{ - const unsigned bytes = ecif->cif->bytes; - const unsigned flags = ecif->cif->flags; - - typedef union { - char *c; - unsigned *u; - long long *ll; - float *f; - double *d; - } valp; - - /* 'stacktop' points at the previous backchain pointer. */ - valp stacktop; - - /* 'gpr_base' points at the space for gpr3, and grows upwards as - we use GPR registers. */ - valp gpr_base; - int intarg_count; - -#ifndef __NO_FPRS__ - /* 'fpr_base' points at the space for fpr1, and grows upwards as - we use FPR registers. */ - valp fpr_base; - int fparg_count; -#endif - - /* 'copy_space' grows down as we put structures in it. It should - stay 16-byte aligned. */ - valp copy_space; - - /* 'next_arg' grows up as we put parameters in it. */ - valp next_arg; - - int i; - ffi_type **ptr; - union { - void **v; - char **c; - signed char **sc; - unsigned char **uc; - signed short **ss; - unsigned short **us; - unsigned int **ui; - long long **ll; - float **f; - double **d; - } p_argv; - size_t struct_copy_size; - unsigned gprvalue; -#ifndef __NO_FPRS__ - double double_tmp; -#endif - - stacktop.c = (char *) stack + bytes; - gpr_base.u = stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS; - intarg_count = 0; -#ifndef __NO_FPRS__ - fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS; - fparg_count = 0; - copy_space.c = ((flags & FLAG_FP_ARGUMENTS) ? fpr_base.c : gpr_base.c); -#else - copy_space.c = gpr_base.c; -#endif - next_arg.u = stack + 2; - - /* Check that everything starts aligned properly. */ - FFI_ASSERT (((unsigned long) (char *) stack & 0xF) == 0); - FFI_ASSERT (((unsigned long) copy_space.c & 0xF) == 0); - FFI_ASSERT (((unsigned long) stacktop.c & 0xF) == 0); - FFI_ASSERT ((bytes & 0xF) == 0); - FFI_ASSERT (copy_space.c >= next_arg.c); - - /* Deal with return values that are actually pass-by-reference. */ - if (flags & FLAG_RETVAL_REFERENCE) - { - *gpr_base.u++ = (unsigned long) (char *) ecif->rvalue; - intarg_count++; - } - - /* Now for the arguments. */ - p_argv.v = ecif->avalue; - for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs; - i > 0; - i--, ptr++, p_argv.v++) - { - unsigned short typenum = (*ptr)->type; - - /* We may need to handle some values depending on ABI */ - if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT) { - if (typenum == FFI_TYPE_FLOAT) - typenum = FFI_TYPE_UINT32; - if (typenum == FFI_TYPE_DOUBLE) - typenum = FFI_TYPE_UINT64; - if (typenum == FFI_TYPE_LONGDOUBLE) - typenum = FFI_TYPE_UINT128; - } else if (ecif->cif->abi != FFI_LINUX) { -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - if (typenum == FFI_TYPE_LONGDOUBLE) - typenum = FFI_TYPE_STRUCT; -#endif - } - - /* Now test the translated value */ - switch (typenum) { -#ifndef __NO_FPRS__ - case FFI_TYPE_FLOAT: - /* With FFI_LINUX_SOFT_FLOAT floats are handled like UINT32. */ - double_tmp = **p_argv.f; - if (fparg_count >= NUM_FPR_ARG_REGISTERS) - { - *next_arg.f = (float) double_tmp; - next_arg.u += 1; - intarg_count++; - } - else - *fpr_base.d++ = double_tmp; - fparg_count++; - FFI_ASSERT (flags & FLAG_FP_ARGUMENTS); - break; - - case FFI_TYPE_DOUBLE: - /* With FFI_LINUX_SOFT_FLOAT doubles are handled like UINT64. */ - double_tmp = **p_argv.d; - - if (fparg_count >= NUM_FPR_ARG_REGISTERS) - { - if (intarg_count >= NUM_GPR_ARG_REGISTERS - && intarg_count % 2 != 0) - { - intarg_count++; - next_arg.u++; - } - *next_arg.d = double_tmp; - next_arg.u += 2; - } - else - *fpr_base.d++ = double_tmp; - fparg_count++; - FFI_ASSERT (flags & FLAG_FP_ARGUMENTS); - break; - -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - case FFI_TYPE_LONGDOUBLE: - double_tmp = (*p_argv.d)[0]; - - if (fparg_count >= NUM_FPR_ARG_REGISTERS - 1) - { - if (intarg_count >= NUM_GPR_ARG_REGISTERS - && intarg_count % 2 != 0) - { - intarg_count++; - next_arg.u++; - } - *next_arg.d = double_tmp; - next_arg.u += 2; - double_tmp = (*p_argv.d)[1]; - *next_arg.d = double_tmp; - next_arg.u += 2; - } - else - { - *fpr_base.d++ = double_tmp; - double_tmp = (*p_argv.d)[1]; - *fpr_base.d++ = double_tmp; - } - - fparg_count += 2; - FFI_ASSERT (flags & FLAG_FP_ARGUMENTS); - break; -#endif -#endif /* have FPRs */ - - /* - * The soft float ABI for long doubles works like this, a long double - * is passed in four consecutive GPRs if available. A maximum of 2 - * long doubles can be passed in gprs. If we do not have 4 GPRs - * left, the long double is passed on the stack, 4-byte aligned. - */ - case FFI_TYPE_UINT128: { - unsigned int int_tmp = (*p_argv.ui)[0]; - unsigned int ii; - if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3) { - if (intarg_count < NUM_GPR_ARG_REGISTERS) - intarg_count += NUM_GPR_ARG_REGISTERS - intarg_count; - *(next_arg.u++) = int_tmp; - for (ii = 1; ii < 4; ii++) { - int_tmp = (*p_argv.ui)[ii]; - *(next_arg.u++) = int_tmp; - } - } else { - *(gpr_base.u++) = int_tmp; - for (ii = 1; ii < 4; ii++) { - int_tmp = (*p_argv.ui)[ii]; - *(gpr_base.u++) = int_tmp; - } - } - intarg_count += 4; - break; - } - - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: - if (intarg_count == NUM_GPR_ARG_REGISTERS-1) - intarg_count++; - if (intarg_count >= NUM_GPR_ARG_REGISTERS) - { - if (intarg_count % 2 != 0) - { - intarg_count++; - next_arg.u++; - } - *next_arg.ll = **p_argv.ll; - next_arg.u += 2; - } - else - { - /* whoops: abi states only certain register pairs - * can be used for passing long long int - * specifically (r3,r4), (r5,r6), (r7,r8), - * (r9,r10) and if next arg is long long but - * not correct starting register of pair then skip - * until the proper starting register - */ - if (intarg_count % 2 != 0) - { - intarg_count ++; - gpr_base.u++; - } - *gpr_base.ll++ = **p_argv.ll; - } - intarg_count += 2; - break; - - case FFI_TYPE_STRUCT: - struct_copy_size = ((*ptr)->size + 15) & ~0xF; - copy_space.c -= struct_copy_size; - memcpy (copy_space.c, *p_argv.c, (*ptr)->size); - - gprvalue = (unsigned long) copy_space.c; - - FFI_ASSERT (copy_space.c > next_arg.c); - FFI_ASSERT (flags & FLAG_ARG_NEEDS_COPY); - goto putgpr; - - case FFI_TYPE_UINT8: - gprvalue = **p_argv.uc; - goto putgpr; - case FFI_TYPE_SINT8: - gprvalue = **p_argv.sc; - goto putgpr; - case FFI_TYPE_UINT16: - gprvalue = **p_argv.us; - goto putgpr; - case FFI_TYPE_SINT16: - gprvalue = **p_argv.ss; - goto putgpr; - - case FFI_TYPE_INT: - case FFI_TYPE_UINT32: - case FFI_TYPE_SINT32: - case FFI_TYPE_POINTER: - - gprvalue = **p_argv.ui; - - putgpr: - if (intarg_count >= NUM_GPR_ARG_REGISTERS) - *next_arg.u++ = gprvalue; - else - *gpr_base.u++ = gprvalue; - intarg_count++; - break; - } - } - - /* Check that we didn't overrun the stack... */ - FFI_ASSERT (copy_space.c >= next_arg.c); - FFI_ASSERT (gpr_base.u <= stacktop.u - ASM_NEEDS_REGISTERS); - /* The assert below is testing that the number of integer arguments agrees - with the number found in ffi_prep_cif_machdep(). However, intarg_count - is incremeneted whenever we place an FP arg on the stack, so account for - that before our assert test. */ -#ifndef __NO_FPRS__ - if (fparg_count > NUM_FPR_ARG_REGISTERS) - intarg_count -= fparg_count - NUM_FPR_ARG_REGISTERS; - FFI_ASSERT (fpr_base.u - <= stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS); -#endif - FFI_ASSERT (flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4); -} - -/* About the LINUX64 ABI. */ -enum { - NUM_GPR_ARG_REGISTERS64 = 8, - NUM_FPR_ARG_REGISTERS64 = 13 -}; -enum { ASM_NEEDS_REGISTERS64 = 4 }; - -/* ffi_prep_args64 is called by the assembly routine once stack space - has been allocated for the function's arguments. - - The stack layout we want looks like this: - - | Ret addr from ffi_call_LINUX64 8bytes | higher addresses - |--------------------------------------------| - | CR save area 8bytes | - |--------------------------------------------| - | Previous backchain pointer 8 | stack pointer here - |--------------------------------------------|<+ <<< on entry to - | Saved r28-r31 4*8 | | ffi_call_LINUX64 - |--------------------------------------------| | - | GPR registers r3-r10 8*8 | | - |--------------------------------------------| | - | FPR registers f1-f13 (optional) 13*8 | | - |--------------------------------------------| | - | Parameter save area | | - |--------------------------------------------| | - | TOC save area 8 | | - |--------------------------------------------| | stack | - | Linker doubleword 8 | | grows | - |--------------------------------------------| | down V - | Compiler doubleword 8 | | - |--------------------------------------------| | lower addresses - | Space for callee's LR 8 | | - |--------------------------------------------| | - | CR save area 8 | | - |--------------------------------------------| | stack pointer here - | Current backchain pointer 8 |-/ during - |--------------------------------------------| <<< ffi_call_LINUX64 - -*/ +#include "ffi.h" +#include "ffi_common.h" +#include "ffi_powerpc.h" +#if HAVE_LONG_DOUBLE_VARIANT +/* Adjust ffi_type_longdouble. */ void FFI_HIDDEN -ffi_prep_args64 (extended_cif *ecif, unsigned long *const stack) +ffi_prep_types (ffi_abi abi) { - const unsigned long bytes = ecif->cif->bytes; - const unsigned long flags = ecif->cif->flags; - - typedef union { - char *c; - unsigned long *ul; - float *f; - double *d; - } valp; - - /* 'stacktop' points at the previous backchain pointer. */ - valp stacktop; - - /* 'next_arg' points at the space for gpr3, and grows upwards as - we use GPR registers, then continues at rest. */ - valp gpr_base; - valp gpr_end; - valp rest; - valp next_arg; - - /* 'fpr_base' points at the space for fpr3, and grows upwards as - we use FPR registers. */ - valp fpr_base; - int fparg_count; - - int i, words; - ffi_type **ptr; - double double_tmp; - union { - void **v; - char **c; - signed char **sc; - unsigned char **uc; - signed short **ss; - unsigned short **us; - signed int **si; - unsigned int **ui; - unsigned long **ul; - float **f; - double **d; - } p_argv; - unsigned long gprvalue; - - stacktop.c = (char *) stack + bytes; - gpr_base.ul = stacktop.ul - ASM_NEEDS_REGISTERS64 - NUM_GPR_ARG_REGISTERS64; - gpr_end.ul = gpr_base.ul + NUM_GPR_ARG_REGISTERS64; - rest.ul = stack + 6 + NUM_GPR_ARG_REGISTERS64; - fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS64; - fparg_count = 0; - next_arg.ul = gpr_base.ul; - - /* Check that everything starts aligned properly. */ - FFI_ASSERT (((unsigned long) (char *) stack & 0xF) == 0); - FFI_ASSERT (((unsigned long) stacktop.c & 0xF) == 0); - FFI_ASSERT ((bytes & 0xF) == 0); - - /* Deal with return values that are actually pass-by-reference. */ - if (flags & FLAG_RETVAL_REFERENCE) - *next_arg.ul++ = (unsigned long) (char *) ecif->rvalue; - - /* Now for the arguments. */ - p_argv.v = ecif->avalue; - for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs; - i > 0; - i--, ptr++, p_argv.v++) - { - switch ((*ptr)->type) - { - case FFI_TYPE_FLOAT: - double_tmp = **p_argv.f; - *next_arg.f = (float) double_tmp; - if (++next_arg.ul == gpr_end.ul) - next_arg.ul = rest.ul; - if (fparg_count < NUM_FPR_ARG_REGISTERS64) - *fpr_base.d++ = double_tmp; - fparg_count++; - FFI_ASSERT (flags & FLAG_FP_ARGUMENTS); - break; - - case FFI_TYPE_DOUBLE: - double_tmp = **p_argv.d; - *next_arg.d = double_tmp; - if (++next_arg.ul == gpr_end.ul) - next_arg.ul = rest.ul; - if (fparg_count < NUM_FPR_ARG_REGISTERS64) - *fpr_base.d++ = double_tmp; - fparg_count++; - FFI_ASSERT (flags & FLAG_FP_ARGUMENTS); - break; - -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - case FFI_TYPE_LONGDOUBLE: - double_tmp = (*p_argv.d)[0]; - *next_arg.d = double_tmp; - if (++next_arg.ul == gpr_end.ul) - next_arg.ul = rest.ul; - if (fparg_count < NUM_FPR_ARG_REGISTERS64) - *fpr_base.d++ = double_tmp; - fparg_count++; - double_tmp = (*p_argv.d)[1]; - *next_arg.d = double_tmp; - if (++next_arg.ul == gpr_end.ul) - next_arg.ul = rest.ul; - if (fparg_count < NUM_FPR_ARG_REGISTERS64) - *fpr_base.d++ = double_tmp; - fparg_count++; - FFI_ASSERT (__LDBL_MANT_DIG__ == 106); - FFI_ASSERT (flags & FLAG_FP_ARGUMENTS); - break; -#endif - - case FFI_TYPE_STRUCT: - words = ((*ptr)->size + 7) / 8; - if (next_arg.ul >= gpr_base.ul && next_arg.ul + words > gpr_end.ul) - { - size_t first = gpr_end.c - next_arg.c; - memcpy (next_arg.c, *p_argv.c, first); - memcpy (rest.c, *p_argv.c + first, (*ptr)->size - first); - next_arg.c = rest.c + words * 8 - first; - } - else - { - char *where = next_arg.c; - - /* Structures with size less than eight bytes are passed - left-padded. */ - if ((*ptr)->size < 8) - where += 8 - (*ptr)->size; - - memcpy (where, *p_argv.c, (*ptr)->size); - next_arg.ul += words; - if (next_arg.ul == gpr_end.ul) - next_arg.ul = rest.ul; - } - break; - - case FFI_TYPE_UINT8: - gprvalue = **p_argv.uc; - goto putgpr; - case FFI_TYPE_SINT8: - gprvalue = **p_argv.sc; - goto putgpr; - case FFI_TYPE_UINT16: - gprvalue = **p_argv.us; - goto putgpr; - case FFI_TYPE_SINT16: - gprvalue = **p_argv.ss; - goto putgpr; - case FFI_TYPE_UINT32: - gprvalue = **p_argv.ui; - goto putgpr; - case FFI_TYPE_INT: - case FFI_TYPE_SINT32: - gprvalue = **p_argv.si; - goto putgpr; - - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: - case FFI_TYPE_POINTER: - gprvalue = **p_argv.ul; - putgpr: - *next_arg.ul++ = gprvalue; - if (next_arg.ul == gpr_end.ul) - next_arg.ul = rest.ul; - break; - } - } - - FFI_ASSERT (flags & FLAG_4_GPR_ARGUMENTS - || (next_arg.ul >= gpr_base.ul - && next_arg.ul <= gpr_base.ul + 4)); +# if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE +# ifdef POWERPC64 + ffi_prep_types_linux64 (abi); +# else + ffi_prep_types_sysv (abi); +# endif +# endif } - - +#endif /* Perform machine dependent cif processing */ -ffi_status +ffi_status FFI_HIDDEN ffi_prep_cif_machdep (ffi_cif *cif) { - /* All this is for the SYSV and LINUX64 ABI. */ - int i; - ffi_type **ptr; - unsigned bytes; - int fparg_count = 0, intarg_count = 0; - unsigned flags = 0; - unsigned struct_copy_size = 0; - unsigned type = cif->rtype->type; - unsigned size = cif->rtype->size; - - if (cif->abi != FFI_LINUX64) - { - /* All the machine-independent calculation of cif->bytes will be wrong. - Redo the calculation for SYSV. */ - - /* Space for the frame pointer, callee's LR, and the asm's temp regs. */ - bytes = (2 + ASM_NEEDS_REGISTERS) * sizeof (int); - - /* Space for the GPR registers. */ - bytes += NUM_GPR_ARG_REGISTERS * sizeof (int); - } - else - { - /* 64-bit ABI. */ - - /* Space for backchain, CR, LR, cc/ld doubleword, TOC and the asm's temp - regs. */ - bytes = (6 + ASM_NEEDS_REGISTERS64) * sizeof (long); - - /* Space for the mandatory parm save area and general registers. */ - bytes += 2 * NUM_GPR_ARG_REGISTERS64 * sizeof (long); - } - - /* Return value handling. The rules for SYSV are as follows: - - 32-bit (or less) integer values are returned in gpr3; - - Structures of size <= 4 bytes also returned in gpr3; - - 64-bit integer values and structures between 5 and 8 bytes are returned - in gpr3 and gpr4; - - Single/double FP values are returned in fpr1; - - Larger structures are allocated space and a pointer is passed as - the first argument. - - long doubles (if not equivalent to double) are returned in - fpr1,fpr2 for Linux and as for large structs for SysV. - For LINUX64: - - integer values in gpr3; - - Structures/Unions by reference; - - Single/double FP values in fpr1, long double in fpr1,fpr2. - - soft-float float/doubles are treated as UINT32/UINT64 respectivley. - - soft-float long doubles are returned in gpr3-gpr6. */ - /* First translate for softfloat/nonlinux */ - if (cif->abi == FFI_LINUX_SOFT_FLOAT) { - if (type == FFI_TYPE_FLOAT) - type = FFI_TYPE_UINT32; - if (type == FFI_TYPE_DOUBLE) - type = FFI_TYPE_UINT64; - if (type == FFI_TYPE_LONGDOUBLE) - type = FFI_TYPE_UINT128; - } else if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX64) { -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - if (type == FFI_TYPE_LONGDOUBLE) - type = FFI_TYPE_STRUCT; -#endif - } - - switch (type) - { -#ifndef __NO_FPRS__ -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - case FFI_TYPE_LONGDOUBLE: - flags |= FLAG_RETURNS_128BITS; - /* Fall through. */ -#endif - case FFI_TYPE_DOUBLE: - flags |= FLAG_RETURNS_64BITS; - /* Fall through. */ - case FFI_TYPE_FLOAT: - flags |= FLAG_RETURNS_FP; - break; -#endif - - case FFI_TYPE_UINT128: - flags |= FLAG_RETURNS_128BITS; - /* Fall through. */ - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: - flags |= FLAG_RETURNS_64BITS; - break; - - case FFI_TYPE_STRUCT: - if (cif->abi == FFI_SYSV) - { - /* The final SYSV ABI says that structures smaller or equal 8 bytes - are returned in r3/r4. The FFI_GCC_SYSV ABI instead returns them - in memory. */ - - /* Treat structs with size <= 8 bytes. */ - if (size <= 8) - { - flags |= FLAG_RETURNS_SMST; - /* These structs are returned in r3. We pack the type and the - precalculated shift value (needed in the sysv.S) into flags. - The same applies for the structs returned in r3/r4. */ - if (size <= 4) - { - flags |= FLAG_SYSV_SMST_R3; - flags |= 8 * (4 - size) << 8; - break; - } - /* These structs are returned in r3 and r4. See above. */ - if (size <= 8) - { - flags |= FLAG_SYSV_SMST_R3 | FLAG_SYSV_SMST_R4; - flags |= 8 * (8 - size) << 8; - break; - } - } - } - - intarg_count++; - flags |= FLAG_RETVAL_REFERENCE; - /* Fall through. */ - case FFI_TYPE_VOID: - flags |= FLAG_RETURNS_NOTHING; - break; - - default: - /* Returns 32-bit integer, or similar. Nothing to do here. */ - break; - } - - if (cif->abi != FFI_LINUX64) - /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the - first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest - goes on the stack. Structures and long doubles (if not equivalent - to double) are passed as a pointer to a copy of the structure. - Stuff on the stack needs to keep proper alignment. */ - for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++) - { - unsigned short typenum = (*ptr)->type; - - /* We may need to handle some values depending on ABI */ - if (cif->abi == FFI_LINUX_SOFT_FLOAT) { - if (typenum == FFI_TYPE_FLOAT) - typenum = FFI_TYPE_UINT32; - if (typenum == FFI_TYPE_DOUBLE) - typenum = FFI_TYPE_UINT64; - if (typenum == FFI_TYPE_LONGDOUBLE) - typenum = FFI_TYPE_UINT128; - } else if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX64) { -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - if (typenum == FFI_TYPE_LONGDOUBLE) - typenum = FFI_TYPE_STRUCT; -#endif - } - - switch (typenum) { -#ifndef __NO_FPRS__ - case FFI_TYPE_FLOAT: - fparg_count++; - /* floating singles are not 8-aligned on stack */ - break; - -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - case FFI_TYPE_LONGDOUBLE: - fparg_count++; - /* Fall thru */ -#endif - case FFI_TYPE_DOUBLE: - fparg_count++; - /* If this FP arg is going on the stack, it must be - 8-byte-aligned. */ - if (fparg_count > NUM_FPR_ARG_REGISTERS - && intarg_count >= NUM_GPR_ARG_REGISTERS - && intarg_count % 2 != 0) - intarg_count++; - break; -#endif - case FFI_TYPE_UINT128: - /* - * A long double in FFI_LINUX_SOFT_FLOAT can use only a set - * of four consecutive gprs. If we do not have enough, we - * have to adjust the intarg_count value. - */ - if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3 - && intarg_count < NUM_GPR_ARG_REGISTERS) - intarg_count = NUM_GPR_ARG_REGISTERS; - intarg_count += 4; - break; - - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: - /* 'long long' arguments are passed as two words, but - either both words must fit in registers or both go - on the stack. If they go on the stack, they must - be 8-byte-aligned. - - Also, only certain register pairs can be used for - passing long long int -- specifically (r3,r4), (r5,r6), - (r7,r8), (r9,r10). - */ - if (intarg_count == NUM_GPR_ARG_REGISTERS-1 - || intarg_count % 2 != 0) - intarg_count++; - intarg_count += 2; - break; - - case FFI_TYPE_STRUCT: - /* We must allocate space for a copy of these to enforce - pass-by-value. Pad the space up to a multiple of 16 - bytes (the maximum alignment required for anything under - the SYSV ABI). */ - struct_copy_size += ((*ptr)->size + 15) & ~0xF; - /* Fall through (allocate space for the pointer). */ - - case FFI_TYPE_POINTER: - case FFI_TYPE_INT: - case FFI_TYPE_UINT32: - case FFI_TYPE_SINT32: - case FFI_TYPE_UINT16: - case FFI_TYPE_SINT16: - case FFI_TYPE_UINT8: - case FFI_TYPE_SINT8: - /* Everything else is passed as a 4-byte word in a GPR, either - the object itself or a pointer to it. */ - intarg_count++; - break; - default: - FFI_ASSERT (0); - } - } - else - for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++) - { - switch ((*ptr)->type) - { -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - case FFI_TYPE_LONGDOUBLE: - if (cif->abi == FFI_LINUX_SOFT_FLOAT) - intarg_count += 4; - else - { - fparg_count += 2; - intarg_count += 2; - } - break; -#endif - case FFI_TYPE_FLOAT: - case FFI_TYPE_DOUBLE: - fparg_count++; - intarg_count++; - break; - - case FFI_TYPE_STRUCT: - intarg_count += ((*ptr)->size + 7) / 8; - break; - - case FFI_TYPE_POINTER: - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: - case FFI_TYPE_INT: - case FFI_TYPE_UINT32: - case FFI_TYPE_SINT32: - case FFI_TYPE_UINT16: - case FFI_TYPE_SINT16: - case FFI_TYPE_UINT8: - case FFI_TYPE_SINT8: - /* Everything else is passed as a 8-byte word in a GPR, either - the object itself or a pointer to it. */ - intarg_count++; - break; - default: - FFI_ASSERT (0); - } - } - -#ifndef __NO_FPRS__ - if (fparg_count != 0) - flags |= FLAG_FP_ARGUMENTS; -#endif - if (intarg_count > 4) - flags |= FLAG_4_GPR_ARGUMENTS; - if (struct_copy_size != 0) - flags |= FLAG_ARG_NEEDS_COPY; - - if (cif->abi != FFI_LINUX64) - { -#ifndef __NO_FPRS__ - /* Space for the FPR registers, if needed. */ - if (fparg_count != 0) - bytes += NUM_FPR_ARG_REGISTERS * sizeof (double); +#ifdef POWERPC64 + return ffi_prep_cif_linux64 (cif); +#else + return ffi_prep_cif_sysv (cif); #endif +} - /* Stack space. */ - if (intarg_count > NUM_GPR_ARG_REGISTERS) - bytes += (intarg_count - NUM_GPR_ARG_REGISTERS) * sizeof (int); -#ifndef __NO_FPRS__ - if (fparg_count > NUM_FPR_ARG_REGISTERS) - bytes += (fparg_count - NUM_FPR_ARG_REGISTERS) * sizeof (double); -#endif - } - else - { -#ifndef __NO_FPRS__ - /* Space for the FPR registers, if needed. */ - if (fparg_count != 0) - bytes += NUM_FPR_ARG_REGISTERS64 * sizeof (double); +ffi_status FFI_HIDDEN +ffi_prep_cif_machdep_var (ffi_cif *cif, + unsigned int nfixedargs MAYBE_UNUSED, + unsigned int ntotalargs MAYBE_UNUSED) +{ +#ifdef POWERPC64 + return ffi_prep_cif_linux64_var (cif, nfixedargs, ntotalargs); +#else + return ffi_prep_cif_sysv (cif); #endif - - /* Stack space. */ - if (intarg_count > NUM_GPR_ARG_REGISTERS64) - bytes += (intarg_count - NUM_GPR_ARG_REGISTERS64) * sizeof (long); - } - - /* The stack space allocated needs to be a multiple of 16 bytes. */ - bytes = (bytes + 15) & ~0xF; - - /* Add in the space for the copied structures. */ - bytes += struct_copy_size; - - cif->flags = flags; - cif->bytes = bytes; - - return FFI_OK; } -extern void ffi_call_SYSV(extended_cif *, unsigned, unsigned, unsigned *, - void (*fn)(void)); -extern void FFI_HIDDEN ffi_call_LINUX64(extended_cif *, unsigned long, - unsigned long, unsigned long *, - void (*fn)(void)); - void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) { - /* - * The final SYSV ABI says that structures smaller or equal 8 bytes - * are returned in r3/r4. The FFI_GCC_SYSV ABI instead returns them - * in memory. - * - * Just to keep things simple for the assembly code, we will always - * bounce-buffer struct return values less than or equal to 8 bytes. - * This allows the ASM to handle SYSV small structures by directly - * writing r3 and r4 to memory without worrying about struct size. - */ - unsigned int smst_buffer[2]; + /* The final SYSV ABI says that structures smaller or equal 8 bytes + are returned in r3/r4. A draft ABI used by linux instead returns + them in memory. + + We bounce-buffer SYSV small struct return values so that sysv.S + can write r3 and r4 to memory without worrying about struct size. + + For ELFv2 ABI, use a bounce buffer for homogeneous structs too, + for similar reasons. */ + unsigned long smst_buffer[8]; extended_cif ecif; - unsigned int rsize = 0; ecif.cif = cif; ecif.avalue = avalue; - /* Ensure that we have a valid struct return value */ ecif.rvalue = rvalue; - if (cif->rtype->type == FFI_TYPE_STRUCT) { - rsize = cif->rtype->size; - if (rsize <= 8) - ecif.rvalue = smst_buffer; - else if (!rvalue) - ecif.rvalue = alloca(rsize); - } + if ((cif->flags & FLAG_RETURNS_SMST) != 0) + ecif.rvalue = smst_buffer; + /* Ensure that we have a valid struct return value. + FIXME: Isn't this just papering over a user problem? */ + else if (!rvalue && cif->rtype->type == FFI_TYPE_STRUCT) + ecif.rvalue = alloca (cif->rtype->size); - switch (cif->abi) - { -#ifndef POWERPC64 -# ifndef __NO_FPRS__ - case FFI_SYSV: - case FFI_GCC_SYSV: - case FFI_LINUX: -# endif - case FFI_LINUX_SOFT_FLOAT: - ffi_call_SYSV (&ecif, -cif->bytes, cif->flags, ecif.rvalue, fn); - break; +#ifdef POWERPC64 + ffi_call_LINUX64 (&ecif, -(long) cif->bytes, cif->flags, ecif.rvalue, fn); #else - case FFI_LINUX64: - ffi_call_LINUX64 (&ecif, -(long) cif->bytes, cif->flags, ecif.rvalue, fn); - break; + ffi_call_SYSV (&ecif, -cif->bytes, cif->flags, ecif.rvalue, fn); #endif - default: - FFI_ASSERT (0); - break; - } /* Check for a bounce-buffered return value */ if (rvalue && ecif.rvalue == smst_buffer) - memcpy(rvalue, smst_buffer, rsize); + { + unsigned int rsize = cif->rtype->size; +#ifndef __LITTLE_ENDIAN__ + /* The SYSV ABI returns a structure of up to 4 bytes in size + left-padded in r3. */ +# ifndef POWERPC64 + if (rsize <= 4) + memcpy (rvalue, (char *) smst_buffer + 4 - rsize, rsize); + else +# endif + /* The SYSV ABI returns a structure of up to 8 bytes in size + left-padded in r3/r4, and the ELFv2 ABI similarly returns a + structure of up to 8 bytes in size left-padded in r3. */ + if (rsize <= 8) + memcpy (rvalue, (char *) smst_buffer + 8 - rsize, rsize); + else +#endif + memcpy (rvalue, smst_buffer, rsize); + } } -#ifndef POWERPC64 -#define MIN_CACHE_LINE_SIZE 8 - -static void -flush_icache (char *wraddr, char *xaddr, int size) -{ - int i; - for (i = 0; i < size; i += MIN_CACHE_LINE_SIZE) - __asm__ volatile ("icbi 0,%0;" "dcbf 0,%1;" - : : "r" (xaddr + i), "r" (wraddr + i) : "memory"); - __asm__ volatile ("icbi 0,%0;" "dcbf 0,%1;" "sync;" "isync;" - : : "r"(xaddr + size - 1), "r"(wraddr + size - 1) - : "memory"); -} -#endif - ffi_status ffi_prep_closure_loc (ffi_closure *closure, ffi_cif *cif, @@ -1022,480 +134,8 @@ ffi_prep_closure_loc (ffi_closure *closure, void *codeloc) { #ifdef POWERPC64 - void **tramp = (void **) &closure->tramp[0]; - - if (cif->abi != FFI_LINUX64) - return FFI_BAD_ABI; - /* Copy function address and TOC from ffi_closure_LINUX64. */ - memcpy (tramp, (char *) ffi_closure_LINUX64, 16); - tramp[2] = codeloc; + return ffi_prep_closure_loc_linux64 (closure, cif, fun, user_data, codeloc); #else - unsigned int *tramp; - - if (! (cif->abi == FFI_GCC_SYSV - || cif->abi == FFI_SYSV - || cif->abi == FFI_LINUX - || cif->abi == FFI_LINUX_SOFT_FLOAT)) - return FFI_BAD_ABI; - - tramp = (unsigned int *) &closure->tramp[0]; - tramp[0] = 0x7c0802a6; /* mflr r0 */ - tramp[1] = 0x4800000d; /* bl 10 */ - tramp[4] = 0x7d6802a6; /* mflr r11 */ - tramp[5] = 0x7c0803a6; /* mtlr r0 */ - tramp[6] = 0x800b0000; /* lwz r0,0(r11) */ - tramp[7] = 0x816b0004; /* lwz r11,4(r11) */ - tramp[8] = 0x7c0903a6; /* mtctr r0 */ - tramp[9] = 0x4e800420; /* bctr */ - *(void **) &tramp[2] = (void *) ffi_closure_SYSV; /* function */ - *(void **) &tramp[3] = codeloc; /* context */ - - /* Flush the icache. */ - flush_icache ((char *)tramp, (char *)codeloc, FFI_TRAMPOLINE_SIZE); -#endif - - closure->cif = cif; - closure->fun = fun; - closure->user_data = user_data; - - return FFI_OK; -} - -typedef union -{ - float f; - double d; -} ffi_dblfl; - -int ffi_closure_helper_SYSV (ffi_closure *, void *, unsigned long *, - ffi_dblfl *, unsigned long *); - -/* Basically the trampoline invokes ffi_closure_SYSV, and on - * entry, r11 holds the address of the closure. - * After storing the registers that could possibly contain - * parameters to be passed into the stack frame and setting - * up space for a return value, ffi_closure_SYSV invokes the - * following helper function to do most of the work - */ - -int -ffi_closure_helper_SYSV (ffi_closure *closure, void *rvalue, - unsigned long *pgr, ffi_dblfl *pfr, - unsigned long *pst) -{ - /* rvalue is the pointer to space for return value in closure assembly */ - /* pgr is the pointer to where r3-r10 are stored in ffi_closure_SYSV */ - /* pfr is the pointer to where f1-f8 are stored in ffi_closure_SYSV */ - /* pst is the pointer to outgoing parameter stack in original caller */ - - void ** avalue; - ffi_type ** arg_types; - long i, avn; -#ifndef __NO_FPRS__ - long nf = 0; /* number of floating registers already used */ -#endif - long ng = 0; /* number of general registers already used */ - - ffi_cif *cif = closure->cif; - unsigned size = cif->rtype->size; - unsigned short rtypenum = cif->rtype->type; - - avalue = alloca (cif->nargs * sizeof (void *)); - - /* First translate for softfloat/nonlinux */ - if (cif->abi == FFI_LINUX_SOFT_FLOAT) { - if (rtypenum == FFI_TYPE_FLOAT) - rtypenum = FFI_TYPE_UINT32; - if (rtypenum == FFI_TYPE_DOUBLE) - rtypenum = FFI_TYPE_UINT64; - if (rtypenum == FFI_TYPE_LONGDOUBLE) - rtypenum = FFI_TYPE_UINT128; - } else if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX64) { -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - if (rtypenum == FFI_TYPE_LONGDOUBLE) - rtypenum = FFI_TYPE_STRUCT; + return ffi_prep_closure_loc_sysv (closure, cif, fun, user_data, codeloc); #endif - } - - - /* Copy the caller's structure return value address so that the closure - returns the data directly to the caller. - For FFI_SYSV the result is passed in r3/r4 if the struct size is less - or equal 8 bytes. */ - if (rtypenum == FFI_TYPE_STRUCT && ((cif->abi != FFI_SYSV) || (size > 8))) { - rvalue = (void *) *pgr; - ng++; - pgr++; - } - - i = 0; - avn = cif->nargs; - arg_types = cif->arg_types; - - /* Grab the addresses of the arguments from the stack frame. */ - while (i < avn) { - unsigned short typenum = arg_types[i]->type; - - /* We may need to handle some values depending on ABI */ - if (cif->abi == FFI_LINUX_SOFT_FLOAT) { - if (typenum == FFI_TYPE_FLOAT) - typenum = FFI_TYPE_UINT32; - if (typenum == FFI_TYPE_DOUBLE) - typenum = FFI_TYPE_UINT64; - if (typenum == FFI_TYPE_LONGDOUBLE) - typenum = FFI_TYPE_UINT128; - } else if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX64) { -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - if (typenum == FFI_TYPE_LONGDOUBLE) - typenum = FFI_TYPE_STRUCT; -#endif - } - - switch (typenum) { -#ifndef __NO_FPRS__ - case FFI_TYPE_FLOAT: - /* unfortunately float values are stored as doubles - * in the ffi_closure_SYSV code (since we don't check - * the type in that routine). - */ - - /* there are 8 64bit floating point registers */ - - if (nf < 8) - { - double temp = pfr->d; - pfr->f = (float) temp; - avalue[i] = pfr; - nf++; - pfr++; - } - else - { - /* FIXME? here we are really changing the values - * stored in the original calling routines outgoing - * parameter stack. This is probably a really - * naughty thing to do but... - */ - avalue[i] = pst; - pst += 1; - } - break; - - case FFI_TYPE_DOUBLE: - /* On the outgoing stack all values are aligned to 8 */ - /* there are 8 64bit floating point registers */ - - if (nf < 8) - { - avalue[i] = pfr; - nf++; - pfr++; - } - else - { - if (((long) pst) & 4) - pst++; - avalue[i] = pst; - pst += 2; - } - break; - -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - case FFI_TYPE_LONGDOUBLE: - if (nf < 7) - { - avalue[i] = pfr; - pfr += 2; - nf += 2; - } - else - { - if (((long) pst) & 4) - pst++; - avalue[i] = pst; - pst += 4; - nf = 8; - } - break; -#endif -#endif /* have FPRS */ - - case FFI_TYPE_UINT128: - /* - * Test if for the whole long double, 4 gprs are available. - * otherwise the stuff ends up on the stack. - */ - if (ng < 5) { - avalue[i] = pgr; - pgr += 4; - ng += 4; - } else { - avalue[i] = pst; - pst += 4; - ng = 8+4; - } - break; - - case FFI_TYPE_SINT8: - case FFI_TYPE_UINT8: - /* there are 8 gpr registers used to pass values */ - if (ng < 8) - { - avalue[i] = (char *) pgr + 3; - ng++; - pgr++; - } - else - { - avalue[i] = (char *) pst + 3; - pst++; - } - break; - - case FFI_TYPE_SINT16: - case FFI_TYPE_UINT16: - /* there are 8 gpr registers used to pass values */ - if (ng < 8) - { - avalue[i] = (char *) pgr + 2; - ng++; - pgr++; - } - else - { - avalue[i] = (char *) pst + 2; - pst++; - } - break; - - case FFI_TYPE_SINT32: - case FFI_TYPE_UINT32: - case FFI_TYPE_POINTER: - /* there are 8 gpr registers used to pass values */ - if (ng < 8) - { - avalue[i] = pgr; - ng++; - pgr++; - } - else - { - avalue[i] = pst; - pst++; - } - break; - - case FFI_TYPE_STRUCT: - /* Structs are passed by reference. The address will appear in a - gpr if it is one of the first 8 arguments. */ - if (ng < 8) - { - avalue[i] = (void *) *pgr; - ng++; - pgr++; - } - else - { - avalue[i] = (void *) *pst; - pst++; - } - break; - - case FFI_TYPE_SINT64: - case FFI_TYPE_UINT64: - /* passing long long ints are complex, they must - * be passed in suitable register pairs such as - * (r3,r4) or (r5,r6) or (r6,r7), or (r7,r8) or (r9,r10) - * and if the entire pair aren't available then the outgoing - * parameter stack is used for both but an alignment of 8 - * must will be kept. So we must either look in pgr - * or pst to find the correct address for this type - * of parameter. - */ - if (ng < 7) - { - if (ng & 0x01) - { - /* skip r4, r6, r8 as starting points */ - ng++; - pgr++; - } - avalue[i] = pgr; - ng += 2; - pgr += 2; - } - else - { - if (((long) pst) & 4) - pst++; - avalue[i] = pst; - pst += 2; - ng = 8; - } - break; - - default: - FFI_ASSERT (0); - } - - i++; - } - - - (closure->fun) (cif, rvalue, avalue, closure->user_data); - - /* Tell ffi_closure_SYSV how to perform return type promotions. - Because the FFI_SYSV ABI returns the structures <= 8 bytes in r3/r4 - we have to tell ffi_closure_SYSV how to treat them. We combine the base - type FFI_SYSV_TYPE_SMALL_STRUCT - 1 with the size of the struct. - So a one byte struct gets the return type 16. Return type 1 to 15 are - already used and we never have a struct with size zero. That is the reason - for the subtraction of 1. See the comment in ffitarget.h about ordering. - */ - if (cif->abi == FFI_SYSV && rtypenum == FFI_TYPE_STRUCT && size <= 8) - return (FFI_SYSV_TYPE_SMALL_STRUCT - 1) + size; - return rtypenum; -} - -int FFI_HIDDEN ffi_closure_helper_LINUX64 (ffi_closure *, void *, - unsigned long *, ffi_dblfl *); - -int FFI_HIDDEN -ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue, - unsigned long *pst, ffi_dblfl *pfr) -{ - /* rvalue is the pointer to space for return value in closure assembly */ - /* pst is the pointer to parameter save area - (r3-r10 are stored into its first 8 slots by ffi_closure_LINUX64) */ - /* pfr is the pointer to where f1-f13 are stored in ffi_closure_LINUX64 */ - - void **avalue; - ffi_type **arg_types; - long i, avn; - ffi_cif *cif; - ffi_dblfl *end_pfr = pfr + NUM_FPR_ARG_REGISTERS64; - - cif = closure->cif; - avalue = alloca (cif->nargs * sizeof (void *)); - - /* Copy the caller's structure return value address so that the closure - returns the data directly to the caller. */ - if (cif->rtype->type == FFI_TYPE_STRUCT) - { - rvalue = (void *) *pst; - pst++; - } - - i = 0; - avn = cif->nargs; - arg_types = cif->arg_types; - - /* Grab the addresses of the arguments from the stack frame. */ - while (i < avn) - { - switch (arg_types[i]->type) - { - case FFI_TYPE_SINT8: - case FFI_TYPE_UINT8: - avalue[i] = (char *) pst + 7; - pst++; - break; - - case FFI_TYPE_SINT16: - case FFI_TYPE_UINT16: - avalue[i] = (char *) pst + 6; - pst++; - break; - - case FFI_TYPE_SINT32: - case FFI_TYPE_UINT32: - avalue[i] = (char *) pst + 4; - pst++; - break; - - case FFI_TYPE_SINT64: - case FFI_TYPE_UINT64: - case FFI_TYPE_POINTER: - avalue[i] = pst; - pst++; - break; - - case FFI_TYPE_STRUCT: - /* Structures with size less than eight bytes are passed - left-padded. */ - if (arg_types[i]->size < 8) - avalue[i] = (char *) pst + 8 - arg_types[i]->size; - else - avalue[i] = pst; - pst += (arg_types[i]->size + 7) / 8; - break; - - case FFI_TYPE_FLOAT: - /* unfortunately float values are stored as doubles - * in the ffi_closure_LINUX64 code (since we don't check - * the type in that routine). - */ - - /* there are 13 64bit floating point registers */ - - if (pfr < end_pfr) - { - double temp = pfr->d; - pfr->f = (float) temp; - avalue[i] = pfr; - pfr++; - } - else - avalue[i] = pst; - pst++; - break; - - case FFI_TYPE_DOUBLE: - /* On the outgoing stack all values are aligned to 8 */ - /* there are 13 64bit floating point registers */ - - if (pfr < end_pfr) - { - avalue[i] = pfr; - pfr++; - } - else - avalue[i] = pst; - pst++; - break; - -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - case FFI_TYPE_LONGDOUBLE: - if (pfr + 1 < end_pfr) - { - avalue[i] = pfr; - pfr += 2; - } - else - { - if (pfr < end_pfr) - { - /* Passed partly in f13 and partly on the stack. - Move it all to the stack. */ - *pst = *(unsigned long *) pfr; - pfr++; - } - avalue[i] = pst; - } - pst += 2; - break; -#endif - - default: - FFI_ASSERT (0); - } - - i++; - } - - - (closure->fun) (cif, rvalue, avalue, closure->user_data); - - /* Tell ffi_closure_LINUX64 how to perform return type promotions. */ - return cif->rtype->type; } diff --git a/Modules/_ctypes/libffi/src/powerpc/ffi_darwin.c b/Modules/_ctypes/libffi/src/powerpc/ffi_darwin.c index 1d1d48c2ec33..cf6fb6d4b7ca 100644 --- a/Modules/_ctypes/libffi/src/powerpc/ffi_darwin.c +++ b/Modules/_ctypes/libffi/src/powerpc/ffi_darwin.c @@ -593,7 +593,7 @@ darwin_adjust_aggregate_sizes (ffi_type *s) /* Natural alignment for all items. */ align = p->alignment; #else - /* Natrual alignment for the first item... */ + /* Natural alignment for the first item... */ if (i == 0) align = p->alignment; else if (p->alignment == 16 || p->alignment < 4) diff --git a/Modules/_ctypes/libffi/src/powerpc/ffi_linux64.c b/Modules/_ctypes/libffi/src/powerpc/ffi_linux64.c new file mode 100644 index 000000000000..b087af8c607b --- /dev/null +++ b/Modules/_ctypes/libffi/src/powerpc/ffi_linux64.c @@ -0,0 +1,943 @@ +/* ----------------------------------------------------------------------- + ffi_linux64.c - Copyright (C) 2013 IBM + Copyright (C) 2011 Anthony Green + Copyright (C) 2011 Kyle Moffett + Copyright (C) 2008 Red Hat, Inc + Copyright (C) 2007, 2008 Free Software Foundation, Inc + Copyright (c) 1998 Geoffrey Keating + + PowerPC Foreign Function Interface + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + ----------------------------------------------------------------------- */ + +#include "ffi.h" + +#ifdef POWERPC64 +#include "ffi_common.h" +#include "ffi_powerpc.h" + + +/* About the LINUX64 ABI. */ +enum { + NUM_GPR_ARG_REGISTERS64 = 8, + NUM_FPR_ARG_REGISTERS64 = 13 +}; +enum { ASM_NEEDS_REGISTERS64 = 4 }; + + +#if HAVE_LONG_DOUBLE_VARIANT && FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE +/* Adjust size of ffi_type_longdouble. */ +void FFI_HIDDEN +ffi_prep_types_linux64 (ffi_abi abi) +{ + if ((abi & (FFI_LINUX | FFI_LINUX_LONG_DOUBLE_128)) == FFI_LINUX) + { + ffi_type_longdouble.size = 8; + ffi_type_longdouble.alignment = 8; + } + else + { + ffi_type_longdouble.size = 16; + ffi_type_longdouble.alignment = 16; + } +} +#endif + + +#if _CALL_ELF == 2 +static unsigned int +discover_homogeneous_aggregate (const ffi_type *t, unsigned int *elnum) +{ + switch (t->type) + { + case FFI_TYPE_FLOAT: + case FFI_TYPE_DOUBLE: + *elnum = 1; + return (int) t->type; + + case FFI_TYPE_STRUCT:; + { + unsigned int base_elt = 0, total_elnum = 0; + ffi_type **el = t->elements; + while (*el) + { + unsigned int el_elt, el_elnum = 0; + el_elt = discover_homogeneous_aggregate (*el, &el_elnum); + if (el_elt == 0 + || (base_elt && base_elt != el_elt)) + return 0; + base_elt = el_elt; + total_elnum += el_elnum; + if (total_elnum > 8) + return 0; + el++; + } + *elnum = total_elnum; + return base_elt; + } + + default: + return 0; + } +} +#endif + + +/* Perform machine dependent cif processing */ +static ffi_status +ffi_prep_cif_linux64_core (ffi_cif *cif) +{ + ffi_type **ptr; + unsigned bytes; + unsigned i, fparg_count = 0, intarg_count = 0; + unsigned flags = cif->flags; +#if _CALL_ELF == 2 + unsigned int elt, elnum; +#endif + +#if FFI_TYPE_LONGDOUBLE == FFI_TYPE_DOUBLE + /* If compiled without long double support.. */ + if ((cif->abi & FFI_LINUX_LONG_DOUBLE_128) != 0) + return FFI_BAD_ABI; +#endif + + /* The machine-independent calculation of cif->bytes doesn't work + for us. Redo the calculation. */ +#if _CALL_ELF == 2 + /* Space for backchain, CR, LR, TOC and the asm's temp regs. */ + bytes = (4 + ASM_NEEDS_REGISTERS64) * sizeof (long); + + /* Space for the general registers. */ + bytes += NUM_GPR_ARG_REGISTERS64 * sizeof (long); +#else + /* Space for backchain, CR, LR, cc/ld doubleword, TOC and the asm's temp + regs. */ + bytes = (6 + ASM_NEEDS_REGISTERS64) * sizeof (long); + + /* Space for the mandatory parm save area and general registers. */ + bytes += 2 * NUM_GPR_ARG_REGISTERS64 * sizeof (long); +#endif + + /* Return value handling. */ + switch (cif->rtype->type) + { +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + case FFI_TYPE_LONGDOUBLE: + if ((cif->abi & FFI_LINUX_LONG_DOUBLE_128) != 0) + flags |= FLAG_RETURNS_128BITS; + /* Fall through. */ +#endif + case FFI_TYPE_DOUBLE: + flags |= FLAG_RETURNS_64BITS; + /* Fall through. */ + case FFI_TYPE_FLOAT: + flags |= FLAG_RETURNS_FP; + break; + + case FFI_TYPE_UINT128: + flags |= FLAG_RETURNS_128BITS; + /* Fall through. */ + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + flags |= FLAG_RETURNS_64BITS; + break; + + case FFI_TYPE_STRUCT: +#if _CALL_ELF == 2 + elt = discover_homogeneous_aggregate (cif->rtype, &elnum); + if (elt) + { + if (elt == FFI_TYPE_DOUBLE) + flags |= FLAG_RETURNS_64BITS; + flags |= FLAG_RETURNS_FP | FLAG_RETURNS_SMST; + break; + } + if (cif->rtype->size <= 16) + { + flags |= FLAG_RETURNS_SMST; + break; + } +#endif + intarg_count++; + flags |= FLAG_RETVAL_REFERENCE; + /* Fall through. */ + case FFI_TYPE_VOID: + flags |= FLAG_RETURNS_NOTHING; + break; + + default: + /* Returns 32-bit integer, or similar. Nothing to do here. */ + break; + } + + for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++) + { + unsigned int align; + + switch ((*ptr)->type) + { +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + case FFI_TYPE_LONGDOUBLE: + if ((cif->abi & FFI_LINUX_LONG_DOUBLE_128) != 0) + { + fparg_count++; + intarg_count++; + } + /* Fall through. */ +#endif + case FFI_TYPE_DOUBLE: + case FFI_TYPE_FLOAT: + fparg_count++; + intarg_count++; + if (fparg_count > NUM_FPR_ARG_REGISTERS64) + flags |= FLAG_ARG_NEEDS_PSAVE; + break; + + case FFI_TYPE_STRUCT: + if ((cif->abi & FFI_LINUX_STRUCT_ALIGN) != 0) + { + align = (*ptr)->alignment; + if (align > 16) + align = 16; + align = align / 8; + if (align > 1) + intarg_count = ALIGN (intarg_count, align); + } + intarg_count += ((*ptr)->size + 7) / 8; +#if _CALL_ELF == 2 + elt = discover_homogeneous_aggregate (*ptr, &elnum); + if (elt) + { + fparg_count += elnum; + if (fparg_count > NUM_FPR_ARG_REGISTERS64) + flags |= FLAG_ARG_NEEDS_PSAVE; + } + else +#endif + { + if (intarg_count > NUM_GPR_ARG_REGISTERS64) + flags |= FLAG_ARG_NEEDS_PSAVE; + } + break; + + case FFI_TYPE_POINTER: + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + case FFI_TYPE_INT: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT8: + case FFI_TYPE_SINT8: + /* Everything else is passed as a 8-byte word in a GPR, either + the object itself or a pointer to it. */ + intarg_count++; + if (intarg_count > NUM_GPR_ARG_REGISTERS64) + flags |= FLAG_ARG_NEEDS_PSAVE; + break; + default: + FFI_ASSERT (0); + } + } + + if (fparg_count != 0) + flags |= FLAG_FP_ARGUMENTS; + if (intarg_count > 4) + flags |= FLAG_4_GPR_ARGUMENTS; + + /* Space for the FPR registers, if needed. */ + if (fparg_count != 0) + bytes += NUM_FPR_ARG_REGISTERS64 * sizeof (double); + + /* Stack space. */ +#if _CALL_ELF == 2 + if ((flags & FLAG_ARG_NEEDS_PSAVE) != 0) + bytes += intarg_count * sizeof (long); +#else + if (intarg_count > NUM_GPR_ARG_REGISTERS64) + bytes += (intarg_count - NUM_GPR_ARG_REGISTERS64) * sizeof (long); +#endif + + /* The stack space allocated needs to be a multiple of 16 bytes. */ + bytes = (bytes + 15) & ~0xF; + + cif->flags = flags; + cif->bytes = bytes; + + return FFI_OK; +} + +ffi_status FFI_HIDDEN +ffi_prep_cif_linux64 (ffi_cif *cif) +{ + if ((cif->abi & FFI_LINUX) != 0) + cif->nfixedargs = cif->nargs; +#if _CALL_ELF != 2 + else if (cif->abi == FFI_COMPAT_LINUX64) + { + /* This call is from old code. Don't touch cif->nfixedargs + since old code will be using a smaller cif. */ + cif->flags |= FLAG_COMPAT; + /* Translate to new abi value. */ + cif->abi = FFI_LINUX | FFI_LINUX_LONG_DOUBLE_128; + } +#endif + else + return FFI_BAD_ABI; + return ffi_prep_cif_linux64_core (cif); +} + +ffi_status FFI_HIDDEN +ffi_prep_cif_linux64_var (ffi_cif *cif, + unsigned int nfixedargs, + unsigned int ntotalargs MAYBE_UNUSED) +{ + if ((cif->abi & FFI_LINUX) != 0) + cif->nfixedargs = nfixedargs; +#if _CALL_ELF != 2 + else if (cif->abi == FFI_COMPAT_LINUX64) + { + /* This call is from old code. Don't touch cif->nfixedargs + since old code will be using a smaller cif. */ + cif->flags |= FLAG_COMPAT; + /* Translate to new abi value. */ + cif->abi = FFI_LINUX | FFI_LINUX_LONG_DOUBLE_128; + } +#endif + else + return FFI_BAD_ABI; +#if _CALL_ELF == 2 + cif->flags |= FLAG_ARG_NEEDS_PSAVE; +#endif + return ffi_prep_cif_linux64_core (cif); +} + + +/* ffi_prep_args64 is called by the assembly routine once stack space + has been allocated for the function's arguments. + + The stack layout we want looks like this: + + | Ret addr from ffi_call_LINUX64 8bytes | higher addresses + |--------------------------------------------| + | CR save area 8bytes | + |--------------------------------------------| + | Previous backchain pointer 8 | stack pointer here + |--------------------------------------------|<+ <<< on entry to + | Saved r28-r31 4*8 | | ffi_call_LINUX64 + |--------------------------------------------| | + | GPR registers r3-r10 8*8 | | + |--------------------------------------------| | + | FPR registers f1-f13 (optional) 13*8 | | + |--------------------------------------------| | + | Parameter save area | | + |--------------------------------------------| | + | TOC save area 8 | | + |--------------------------------------------| | stack | + | Linker doubleword 8 | | grows | + |--------------------------------------------| | down V + | Compiler doubleword 8 | | + |--------------------------------------------| | lower addresses + | Space for callee's LR 8 | | + |--------------------------------------------| | + | CR save area 8 | | + |--------------------------------------------| | stack pointer here + | Current backchain pointer 8 |-/ during + |--------------------------------------------| <<< ffi_call_LINUX64 + +*/ + +void FFI_HIDDEN +ffi_prep_args64 (extended_cif *ecif, unsigned long *const stack) +{ + const unsigned long bytes = ecif->cif->bytes; + const unsigned long flags = ecif->cif->flags; + + typedef union + { + char *c; + unsigned long *ul; + float *f; + double *d; + size_t p; + } valp; + + /* 'stacktop' points at the previous backchain pointer. */ + valp stacktop; + + /* 'next_arg' points at the space for gpr3, and grows upwards as + we use GPR registers, then continues at rest. */ + valp gpr_base; + valp gpr_end; + valp rest; + valp next_arg; + + /* 'fpr_base' points at the space for fpr3, and grows upwards as + we use FPR registers. */ + valp fpr_base; + unsigned int fparg_count; + + unsigned int i, words, nargs, nfixedargs; + ffi_type **ptr; + double double_tmp; + union + { + void **v; + char **c; + signed char **sc; + unsigned char **uc; + signed short **ss; + unsigned short **us; + signed int **si; + unsigned int **ui; + unsigned long **ul; + float **f; + double **d; + } p_argv; + unsigned long gprvalue; + unsigned long align; + + stacktop.c = (char *) stack + bytes; + gpr_base.ul = stacktop.ul - ASM_NEEDS_REGISTERS64 - NUM_GPR_ARG_REGISTERS64; + gpr_end.ul = gpr_base.ul + NUM_GPR_ARG_REGISTERS64; +#if _CALL_ELF == 2 + rest.ul = stack + 4 + NUM_GPR_ARG_REGISTERS64; +#else + rest.ul = stack + 6 + NUM_GPR_ARG_REGISTERS64; +#endif + fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS64; + fparg_count = 0; + next_arg.ul = gpr_base.ul; + + /* Check that everything starts aligned properly. */ + FFI_ASSERT (((unsigned long) (char *) stack & 0xF) == 0); + FFI_ASSERT (((unsigned long) stacktop.c & 0xF) == 0); + FFI_ASSERT ((bytes & 0xF) == 0); + + /* Deal with return values that are actually pass-by-reference. */ + if (flags & FLAG_RETVAL_REFERENCE) + *next_arg.ul++ = (unsigned long) (char *) ecif->rvalue; + + /* Now for the arguments. */ + p_argv.v = ecif->avalue; + nargs = ecif->cif->nargs; +#if _CALL_ELF != 2 + nfixedargs = (unsigned) -1; + if ((flags & FLAG_COMPAT) == 0) +#endif + nfixedargs = ecif->cif->nfixedargs; + for (ptr = ecif->cif->arg_types, i = 0; + i < nargs; + i++, ptr++, p_argv.v++) + { +#if _CALL_ELF == 2 + unsigned int elt, elnum; +#endif + + switch ((*ptr)->type) + { +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + case FFI_TYPE_LONGDOUBLE: + if ((ecif->cif->abi & FFI_LINUX_LONG_DOUBLE_128) != 0) + { + double_tmp = (*p_argv.d)[0]; + if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs) + { + *fpr_base.d++ = double_tmp; +# if _CALL_ELF != 2 + if ((flags & FLAG_COMPAT) != 0) + *next_arg.d = double_tmp; +# endif + } + else + *next_arg.d = double_tmp; + if (++next_arg.ul == gpr_end.ul) + next_arg.ul = rest.ul; + fparg_count++; + double_tmp = (*p_argv.d)[1]; + if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs) + { + *fpr_base.d++ = double_tmp; +# if _CALL_ELF != 2 + if ((flags & FLAG_COMPAT) != 0) + *next_arg.d = double_tmp; +# endif + } + else + *next_arg.d = double_tmp; + if (++next_arg.ul == gpr_end.ul) + next_arg.ul = rest.ul; + fparg_count++; + FFI_ASSERT (__LDBL_MANT_DIG__ == 106); + FFI_ASSERT (flags & FLAG_FP_ARGUMENTS); + break; + } + /* Fall through. */ +#endif + case FFI_TYPE_DOUBLE: + double_tmp = **p_argv.d; + if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs) + { + *fpr_base.d++ = double_tmp; +#if _CALL_ELF != 2 + if ((flags & FLAG_COMPAT) != 0) + *next_arg.d = double_tmp; +#endif + } + else + *next_arg.d = double_tmp; + if (++next_arg.ul == gpr_end.ul) + next_arg.ul = rest.ul; + fparg_count++; + FFI_ASSERT (flags & FLAG_FP_ARGUMENTS); + break; + + case FFI_TYPE_FLOAT: + double_tmp = **p_argv.f; + if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs) + { + *fpr_base.d++ = double_tmp; +#if _CALL_ELF != 2 + if ((flags & FLAG_COMPAT) != 0) + *next_arg.f = (float) double_tmp; +#endif + } + else + *next_arg.f = (float) double_tmp; + if (++next_arg.ul == gpr_end.ul) + next_arg.ul = rest.ul; + fparg_count++; + FFI_ASSERT (flags & FLAG_FP_ARGUMENTS); + break; + + case FFI_TYPE_STRUCT: + if ((ecif->cif->abi & FFI_LINUX_STRUCT_ALIGN) != 0) + { + align = (*ptr)->alignment; + if (align > 16) + align = 16; + if (align > 1) + next_arg.p = ALIGN (next_arg.p, align); + } +#if _CALL_ELF == 2 + elt = discover_homogeneous_aggregate (*ptr, &elnum); + if (elt) + { + union { + void *v; + float *f; + double *d; + } arg; + + arg.v = *p_argv.v; + if (elt == FFI_TYPE_FLOAT) + { + do + { + double_tmp = *arg.f++; + if (fparg_count < NUM_FPR_ARG_REGISTERS64 + && i < nfixedargs) + *fpr_base.d++ = double_tmp; + else + *next_arg.f = (float) double_tmp; + if (++next_arg.f == gpr_end.f) + next_arg.f = rest.f; + fparg_count++; + } + while (--elnum != 0); + if ((next_arg.p & 3) != 0) + { + if (++next_arg.f == gpr_end.f) + next_arg.f = rest.f; + } + } + else + do + { + double_tmp = *arg.d++; + if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs) + *fpr_base.d++ = double_tmp; + else + *next_arg.d = double_tmp; + if (++next_arg.d == gpr_end.d) + next_arg.d = rest.d; + fparg_count++; + } + while (--elnum != 0); + } + else +#endif + { + words = ((*ptr)->size + 7) / 8; + if (next_arg.ul >= gpr_base.ul && next_arg.ul + words > gpr_end.ul) + { + size_t first = gpr_end.c - next_arg.c; + memcpy (next_arg.c, *p_argv.c, first); + memcpy (rest.c, *p_argv.c + first, (*ptr)->size - first); + next_arg.c = rest.c + words * 8 - first; + } + else + { + char *where = next_arg.c; + +#ifndef __LITTLE_ENDIAN__ + /* Structures with size less than eight bytes are passed + left-padded. */ + if ((*ptr)->size < 8) + where += 8 - (*ptr)->size; +#endif + memcpy (where, *p_argv.c, (*ptr)->size); + next_arg.ul += words; + if (next_arg.ul == gpr_end.ul) + next_arg.ul = rest.ul; + } + } + break; + + case FFI_TYPE_UINT8: + gprvalue = **p_argv.uc; + goto putgpr; + case FFI_TYPE_SINT8: + gprvalue = **p_argv.sc; + goto putgpr; + case FFI_TYPE_UINT16: + gprvalue = **p_argv.us; + goto putgpr; + case FFI_TYPE_SINT16: + gprvalue = **p_argv.ss; + goto putgpr; + case FFI_TYPE_UINT32: + gprvalue = **p_argv.ui; + goto putgpr; + case FFI_TYPE_INT: + case FFI_TYPE_SINT32: + gprvalue = **p_argv.si; + goto putgpr; + + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + case FFI_TYPE_POINTER: + gprvalue = **p_argv.ul; + putgpr: + *next_arg.ul++ = gprvalue; + if (next_arg.ul == gpr_end.ul) + next_arg.ul = rest.ul; + break; + } + } + + FFI_ASSERT (flags & FLAG_4_GPR_ARGUMENTS + || (next_arg.ul >= gpr_base.ul + && next_arg.ul <= gpr_base.ul + 4)); +} + + +#if _CALL_ELF == 2 +#define MIN_CACHE_LINE_SIZE 8 + +static void +flush_icache (char *wraddr, char *xaddr, int size) +{ + int i; + for (i = 0; i < size; i += MIN_CACHE_LINE_SIZE) + __asm__ volatile ("icbi 0,%0;" "dcbf 0,%1;" + : : "r" (xaddr + i), "r" (wraddr + i) : "memory"); + __asm__ volatile ("icbi 0,%0;" "dcbf 0,%1;" "sync;" "isync;" + : : "r"(xaddr + size - 1), "r"(wraddr + size - 1) + : "memory"); +} +#endif + +ffi_status +ffi_prep_closure_loc_linux64 (ffi_closure *closure, + ffi_cif *cif, + void (*fun) (ffi_cif *, void *, void **, void *), + void *user_data, + void *codeloc) +{ +#if _CALL_ELF == 2 + unsigned int *tramp = (unsigned int *) &closure->tramp[0]; + + if (cif->abi < FFI_LINUX || cif->abi >= FFI_LAST_ABI) + return FFI_BAD_ABI; + + tramp[0] = 0xe96c0018; /* 0: ld 11,2f-0b(12) */ + tramp[1] = 0xe98c0010; /* ld 12,1f-0b(12) */ + tramp[2] = 0x7d8903a6; /* mtctr 12 */ + tramp[3] = 0x4e800420; /* bctr */ + /* 1: .quad function_addr */ + /* 2: .quad context */ + *(void **) &tramp[4] = (void *) ffi_closure_LINUX64; + *(void **) &tramp[6] = codeloc; + flush_icache ((char *)tramp, (char *)codeloc, FFI_TRAMPOLINE_SIZE); +#else + void **tramp = (void **) &closure->tramp[0]; + + if (cif->abi < FFI_LINUX || cif->abi >= FFI_LAST_ABI) + return FFI_BAD_ABI; + + /* Copy function address and TOC from ffi_closure_LINUX64. */ + memcpy (tramp, (char *) ffi_closure_LINUX64, 16); + tramp[2] = tramp[1]; + tramp[1] = codeloc; +#endif + + closure->cif = cif; + closure->fun = fun; + closure->user_data = user_data; + + return FFI_OK; +} + + +int FFI_HIDDEN +ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue, + unsigned long *pst, ffi_dblfl *pfr) +{ + /* rvalue is the pointer to space for return value in closure assembly */ + /* pst is the pointer to parameter save area + (r3-r10 are stored into its first 8 slots by ffi_closure_LINUX64) */ + /* pfr is the pointer to where f1-f13 are stored in ffi_closure_LINUX64 */ + + void **avalue; + ffi_type **arg_types; + unsigned long i, avn, nfixedargs; + ffi_cif *cif; + ffi_dblfl *end_pfr = pfr + NUM_FPR_ARG_REGISTERS64; + unsigned long align; + + cif = closure->cif; + avalue = alloca (cif->nargs * sizeof (void *)); + + /* Copy the caller's structure return value address so that the + closure returns the data directly to the caller. */ + if (cif->rtype->type == FFI_TYPE_STRUCT + && (cif->flags & FLAG_RETURNS_SMST) == 0) + { + rvalue = (void *) *pst; + pst++; + } + + i = 0; + avn = cif->nargs; +#if _CALL_ELF != 2 + nfixedargs = (unsigned) -1; + if ((cif->flags & FLAG_COMPAT) == 0) +#endif + nfixedargs = cif->nfixedargs; + arg_types = cif->arg_types; + + /* Grab the addresses of the arguments from the stack frame. */ + while (i < avn) + { + unsigned int elt, elnum; + + switch (arg_types[i]->type) + { + case FFI_TYPE_SINT8: + case FFI_TYPE_UINT8: +#ifndef __LITTLE_ENDIAN__ + avalue[i] = (char *) pst + 7; + pst++; + break; +#endif + + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT16: +#ifndef __LITTLE_ENDIAN__ + avalue[i] = (char *) pst + 6; + pst++; + break; +#endif + + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT32: +#ifndef __LITTLE_ENDIAN__ + avalue[i] = (char *) pst + 4; + pst++; + break; +#endif + + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + case FFI_TYPE_POINTER: + avalue[i] = pst; + pst++; + break; + + case FFI_TYPE_STRUCT: + if ((cif->abi & FFI_LINUX_STRUCT_ALIGN) != 0) + { + align = arg_types[i]->alignment; + if (align > 16) + align = 16; + if (align > 1) + pst = (unsigned long *) ALIGN ((size_t) pst, align); + } + elt = 0; +#if _CALL_ELF == 2 + elt = discover_homogeneous_aggregate (arg_types[i], &elnum); +#endif + if (elt) + { + union { + void *v; + unsigned long *ul; + float *f; + double *d; + size_t p; + } to, from; + + /* Repackage the aggregate from its parts. The + aggregate size is not greater than the space taken by + the registers so store back to the register/parameter + save arrays. */ + if (pfr + elnum <= end_pfr) + to.v = pfr; + else + to.v = pst; + + avalue[i] = to.v; + from.ul = pst; + if (elt == FFI_TYPE_FLOAT) + { + do + { + if (pfr < end_pfr && i < nfixedargs) + { + *to.f = (float) pfr->d; + pfr++; + } + else + *to.f = *from.f; + to.f++; + from.f++; + } + while (--elnum != 0); + } + else + { + do + { + if (pfr < end_pfr && i < nfixedargs) + { + *to.d = pfr->d; + pfr++; + } + else + *to.d = *from.d; + to.d++; + from.d++; + } + while (--elnum != 0); + } + } + else + { +#ifndef __LITTLE_ENDIAN__ + /* Structures with size less than eight bytes are passed + left-padded. */ + if (arg_types[i]->size < 8) + avalue[i] = (char *) pst + 8 - arg_types[i]->size; + else +#endif + avalue[i] = pst; + } + pst += (arg_types[i]->size + 7) / 8; + break; + +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + case FFI_TYPE_LONGDOUBLE: + if ((cif->abi & FFI_LINUX_LONG_DOUBLE_128) != 0) + { + if (pfr + 1 < end_pfr && i + 1 < nfixedargs) + { + avalue[i] = pfr; + pfr += 2; + } + else + { + if (pfr < end_pfr && i < nfixedargs) + { + /* Passed partly in f13 and partly on the stack. + Move it all to the stack. */ + *pst = *(unsigned long *) pfr; + pfr++; + } + avalue[i] = pst; + } + pst += 2; + break; + } + /* Fall through. */ +#endif + case FFI_TYPE_DOUBLE: + /* On the outgoing stack all values are aligned to 8 */ + /* there are 13 64bit floating point registers */ + + if (pfr < end_pfr && i < nfixedargs) + { + avalue[i] = pfr; + pfr++; + } + else + avalue[i] = pst; + pst++; + break; + + case FFI_TYPE_FLOAT: + if (pfr < end_pfr && i < nfixedargs) + { + /* Float values are stored as doubles in the + ffi_closure_LINUX64 code. Fix them here. */ + pfr->f = (float) pfr->d; + avalue[i] = pfr; + pfr++; + } + else + avalue[i] = pst; + pst++; + break; + + default: + FFI_ASSERT (0); + } + + i++; + } + + + (closure->fun) (cif, rvalue, avalue, closure->user_data); + + /* Tell ffi_closure_LINUX64 how to perform return type promotions. */ + if ((cif->flags & FLAG_RETURNS_SMST) != 0) + { + if ((cif->flags & FLAG_RETURNS_FP) == 0) + return FFI_V2_TYPE_SMALL_STRUCT + cif->rtype->size - 1; + else if ((cif->flags & FLAG_RETURNS_64BITS) != 0) + return FFI_V2_TYPE_DOUBLE_HOMOG; + else + return FFI_V2_TYPE_FLOAT_HOMOG; + } + return cif->rtype->type; +} +#endif diff --git a/Modules/_ctypes/libffi/src/powerpc/ffi_powerpc.h b/Modules/_ctypes/libffi/src/powerpc/ffi_powerpc.h new file mode 100644 index 000000000000..2e61653d1a78 --- /dev/null +++ b/Modules/_ctypes/libffi/src/powerpc/ffi_powerpc.h @@ -0,0 +1,77 @@ +/* ----------------------------------------------------------------------- + ffi_powerpc.h - Copyright (C) 2013 IBM + Copyright (C) 2011 Anthony Green + Copyright (C) 2011 Kyle Moffett + Copyright (C) 2008 Red Hat, Inc + Copyright (C) 2007, 2008 Free Software Foundation, Inc + Copyright (c) 1998 Geoffrey Keating + + PowerPC Foreign Function Interface + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + ----------------------------------------------------------------------- */ + +enum { + /* The assembly depends on these exact flags. */ + /* These go in cr7 */ + FLAG_RETURNS_SMST = 1 << (31-31), /* Used for FFI_SYSV small structs. */ + FLAG_RETURNS_NOTHING = 1 << (31-30), + FLAG_RETURNS_FP = 1 << (31-29), + FLAG_RETURNS_64BITS = 1 << (31-28), + + /* This goes in cr6 */ + FLAG_RETURNS_128BITS = 1 << (31-27), + + FLAG_COMPAT = 1 << (31- 8), /* Not used by assembly */ + + /* These go in cr1 */ + FLAG_ARG_NEEDS_COPY = 1 << (31- 7), /* Used by sysv code */ + FLAG_ARG_NEEDS_PSAVE = FLAG_ARG_NEEDS_COPY, /* Used by linux64 code */ + FLAG_FP_ARGUMENTS = 1 << (31- 6), /* cr1.eq; specified by ABI */ + FLAG_4_GPR_ARGUMENTS = 1 << (31- 5), + FLAG_RETVAL_REFERENCE = 1 << (31- 4) +}; + +typedef union +{ + float f; + double d; +} ffi_dblfl; + +void FFI_HIDDEN ffi_closure_SYSV (void); +void FFI_HIDDEN ffi_call_SYSV(extended_cif *, unsigned, unsigned, unsigned *, + void (*)(void)); + +void FFI_HIDDEN ffi_prep_types_sysv (ffi_abi); +ffi_status FFI_HIDDEN ffi_prep_cif_sysv (ffi_cif *); +int FFI_HIDDEN ffi_closure_helper_SYSV (ffi_closure *, void *, unsigned long *, + ffi_dblfl *, unsigned long *); + +void FFI_HIDDEN ffi_call_LINUX64(extended_cif *, unsigned long, unsigned long, + unsigned long *, void (*)(void)); +void FFI_HIDDEN ffi_closure_LINUX64 (void); + +void FFI_HIDDEN ffi_prep_types_linux64 (ffi_abi); +ffi_status FFI_HIDDEN ffi_prep_cif_linux64 (ffi_cif *); +ffi_status FFI_HIDDEN ffi_prep_cif_linux64_var (ffi_cif *, unsigned int, + unsigned int); +void FFI_HIDDEN ffi_prep_args64 (extended_cif *, unsigned long *const); +int FFI_HIDDEN ffi_closure_helper_LINUX64 (ffi_closure *, void *, + unsigned long *, ffi_dblfl *); diff --git a/Modules/_ctypes/libffi/src/powerpc/ffi_sysv.c b/Modules/_ctypes/libffi/src/powerpc/ffi_sysv.c new file mode 100644 index 000000000000..fbe85fe91409 --- /dev/null +++ b/Modules/_ctypes/libffi/src/powerpc/ffi_sysv.c @@ -0,0 +1,931 @@ +/* ----------------------------------------------------------------------- + ffi_sysv.c - Copyright (C) 2013 IBM + Copyright (C) 2011 Anthony Green + Copyright (C) 2011 Kyle Moffett + Copyright (C) 2008 Red Hat, Inc + Copyright (C) 2007, 2008 Free Software Foundation, Inc + Copyright (c) 1998 Geoffrey Keating + + PowerPC Foreign Function Interface + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + ----------------------------------------------------------------------- */ + +#include "ffi.h" + +#ifndef POWERPC64 +#include "ffi_common.h" +#include "ffi_powerpc.h" + + +/* About the SYSV ABI. */ +#define ASM_NEEDS_REGISTERS 4 +#define NUM_GPR_ARG_REGISTERS 8 +#define NUM_FPR_ARG_REGISTERS 8 + + +#if HAVE_LONG_DOUBLE_VARIANT && FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE +/* Adjust size of ffi_type_longdouble. */ +void FFI_HIDDEN +ffi_prep_types_sysv (ffi_abi abi) +{ + if ((abi & (FFI_SYSV | FFI_SYSV_LONG_DOUBLE_128)) == FFI_SYSV) + { + ffi_type_longdouble.size = 8; + ffi_type_longdouble.alignment = 8; + } + else + { + ffi_type_longdouble.size = 16; + ffi_type_longdouble.alignment = 16; + } +} +#endif + +/* Transform long double, double and float to other types as per abi. */ +static int +translate_float (int abi, int type) +{ +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + if (type == FFI_TYPE_LONGDOUBLE + && (abi & FFI_SYSV_LONG_DOUBLE_128) == 0) + type = FFI_TYPE_DOUBLE; +#endif + if ((abi & FFI_SYSV_SOFT_FLOAT) != 0) + { + if (type == FFI_TYPE_FLOAT) + type = FFI_TYPE_UINT32; + else if (type == FFI_TYPE_DOUBLE) + type = FFI_TYPE_UINT64; +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + else if (type == FFI_TYPE_LONGDOUBLE) + type = FFI_TYPE_UINT128; + } + else if ((abi & FFI_SYSV_IBM_LONG_DOUBLE) == 0) + { + if (type == FFI_TYPE_LONGDOUBLE) + type = FFI_TYPE_STRUCT; +#endif + } + return type; +} + +/* Perform machine dependent cif processing */ +static ffi_status +ffi_prep_cif_sysv_core (ffi_cif *cif) +{ + ffi_type **ptr; + unsigned bytes; + unsigned i, fparg_count = 0, intarg_count = 0; + unsigned flags = cif->flags; + unsigned struct_copy_size = 0; + unsigned type = cif->rtype->type; + unsigned size = cif->rtype->size; + + /* The machine-independent calculation of cif->bytes doesn't work + for us. Redo the calculation. */ + + /* Space for the frame pointer, callee's LR, and the asm's temp regs. */ + bytes = (2 + ASM_NEEDS_REGISTERS) * sizeof (int); + + /* Space for the GPR registers. */ + bytes += NUM_GPR_ARG_REGISTERS * sizeof (int); + + /* Return value handling. The rules for SYSV are as follows: + - 32-bit (or less) integer values are returned in gpr3; + - Structures of size <= 4 bytes also returned in gpr3; + - 64-bit integer values and structures between 5 and 8 bytes are returned + in gpr3 and gpr4; + - Larger structures are allocated space and a pointer is passed as + the first argument. + - Single/double FP values are returned in fpr1; + - long doubles (if not equivalent to double) are returned in + fpr1,fpr2 for Linux and as for large structs for SysV. */ + + type = translate_float (cif->abi, type); + + switch (type) + { +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + case FFI_TYPE_LONGDOUBLE: + flags |= FLAG_RETURNS_128BITS; + /* Fall through. */ +#endif + case FFI_TYPE_DOUBLE: + flags |= FLAG_RETURNS_64BITS; + /* Fall through. */ + case FFI_TYPE_FLOAT: + flags |= FLAG_RETURNS_FP; +#ifdef __NO_FPRS__ + return FFI_BAD_ABI; +#endif + break; + + case FFI_TYPE_UINT128: + flags |= FLAG_RETURNS_128BITS; + /* Fall through. */ + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + flags |= FLAG_RETURNS_64BITS; + break; + + case FFI_TYPE_STRUCT: + /* The final SYSV ABI says that structures smaller or equal 8 bytes + are returned in r3/r4. A draft ABI used by linux instead + returns them in memory. */ + if ((cif->abi & FFI_SYSV_STRUCT_RET) != 0 && size <= 8) + { + flags |= FLAG_RETURNS_SMST; + break; + } + intarg_count++; + flags |= FLAG_RETVAL_REFERENCE; + /* Fall through. */ + case FFI_TYPE_VOID: + flags |= FLAG_RETURNS_NOTHING; + break; + + default: + /* Returns 32-bit integer, or similar. Nothing to do here. */ + break; + } + + /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the + first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest + goes on the stack. Structures and long doubles (if not equivalent + to double) are passed as a pointer to a copy of the structure. + Stuff on the stack needs to keep proper alignment. */ + for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++) + { + unsigned short typenum = (*ptr)->type; + + typenum = translate_float (cif->abi, typenum); + + switch (typenum) + { +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + case FFI_TYPE_LONGDOUBLE: + fparg_count++; + /* Fall thru */ +#endif + case FFI_TYPE_DOUBLE: + fparg_count++; + /* If this FP arg is going on the stack, it must be + 8-byte-aligned. */ + if (fparg_count > NUM_FPR_ARG_REGISTERS + && intarg_count >= NUM_GPR_ARG_REGISTERS + && intarg_count % 2 != 0) + intarg_count++; +#ifdef __NO_FPRS__ + return FFI_BAD_ABI; +#endif + break; + + case FFI_TYPE_FLOAT: + fparg_count++; +#ifdef __NO_FPRS__ + return FFI_BAD_ABI; +#endif + break; + + case FFI_TYPE_UINT128: + /* A long double in FFI_LINUX_SOFT_FLOAT can use only a set + of four consecutive gprs. If we do not have enough, we + have to adjust the intarg_count value. */ + if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3 + && intarg_count < NUM_GPR_ARG_REGISTERS) + intarg_count = NUM_GPR_ARG_REGISTERS; + intarg_count += 4; + break; + + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + /* 'long long' arguments are passed as two words, but + either both words must fit in registers or both go + on the stack. If they go on the stack, they must + be 8-byte-aligned. + + Also, only certain register pairs can be used for + passing long long int -- specifically (r3,r4), (r5,r6), + (r7,r8), (r9,r10). */ + if (intarg_count == NUM_GPR_ARG_REGISTERS-1 + || intarg_count % 2 != 0) + intarg_count++; + intarg_count += 2; + break; + + case FFI_TYPE_STRUCT: + /* We must allocate space for a copy of these to enforce + pass-by-value. Pad the space up to a multiple of 16 + bytes (the maximum alignment required for anything under + the SYSV ABI). */ + struct_copy_size += ((*ptr)->size + 15) & ~0xF; + /* Fall through (allocate space for the pointer). */ + + case FFI_TYPE_POINTER: + case FFI_TYPE_INT: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT8: + case FFI_TYPE_SINT8: + /* Everything else is passed as a 4-byte word in a GPR, either + the object itself or a pointer to it. */ + intarg_count++; + break; + + default: + FFI_ASSERT (0); + } + } + + if (fparg_count != 0) + flags |= FLAG_FP_ARGUMENTS; + if (intarg_count > 4) + flags |= FLAG_4_GPR_ARGUMENTS; + if (struct_copy_size != 0) + flags |= FLAG_ARG_NEEDS_COPY; + + /* Space for the FPR registers, if needed. */ + if (fparg_count != 0) + bytes += NUM_FPR_ARG_REGISTERS * sizeof (double); + + /* Stack space. */ + if (intarg_count > NUM_GPR_ARG_REGISTERS) + bytes += (intarg_count - NUM_GPR_ARG_REGISTERS) * sizeof (int); + if (fparg_count > NUM_FPR_ARG_REGISTERS) + bytes += (fparg_count - NUM_FPR_ARG_REGISTERS) * sizeof (double); + + /* The stack space allocated needs to be a multiple of 16 bytes. */ + bytes = (bytes + 15) & ~0xF; + + /* Add in the space for the copied structures. */ + bytes += struct_copy_size; + + cif->flags = flags; + cif->bytes = bytes; + + return FFI_OK; +} + +ffi_status FFI_HIDDEN +ffi_prep_cif_sysv (ffi_cif *cif) +{ + if ((cif->abi & FFI_SYSV) == 0) + { + /* This call is from old code. Translate to new ABI values. */ + cif->flags |= FLAG_COMPAT; + switch (cif->abi) + { + default: + return FFI_BAD_ABI; + + case FFI_COMPAT_SYSV: + cif->abi = FFI_SYSV | FFI_SYSV_STRUCT_RET | FFI_SYSV_LONG_DOUBLE_128; + break; + + case FFI_COMPAT_GCC_SYSV: + cif->abi = FFI_SYSV | FFI_SYSV_LONG_DOUBLE_128; + break; + + case FFI_COMPAT_LINUX: + cif->abi = (FFI_SYSV | FFI_SYSV_IBM_LONG_DOUBLE + | FFI_SYSV_LONG_DOUBLE_128); + break; + + case FFI_COMPAT_LINUX_SOFT_FLOAT: + cif->abi = (FFI_SYSV | FFI_SYSV_SOFT_FLOAT | FFI_SYSV_IBM_LONG_DOUBLE + | FFI_SYSV_LONG_DOUBLE_128); + break; + } + } + return ffi_prep_cif_sysv_core (cif); +} + +/* ffi_prep_args_SYSV is called by the assembly routine once stack space + has been allocated for the function's arguments. + + The stack layout we want looks like this: + + | Return address from ffi_call_SYSV 4bytes | higher addresses + |--------------------------------------------| + | Previous backchain pointer 4 | stack pointer here + |--------------------------------------------|<+ <<< on entry to + | Saved r28-r31 4*4 | | ffi_call_SYSV + |--------------------------------------------| | + | GPR registers r3-r10 8*4 | | ffi_call_SYSV + |--------------------------------------------| | + | FPR registers f1-f8 (optional) 8*8 | | + |--------------------------------------------| | stack | + | Space for copied structures | | grows | + |--------------------------------------------| | down V + | Parameters that didn't fit in registers | | + |--------------------------------------------| | lower addresses + | Space for callee's LR 4 | | + |--------------------------------------------| | stack pointer here + | Current backchain pointer 4 |-/ during + |--------------------------------------------| <<< ffi_call_SYSV + +*/ + +void FFI_HIDDEN +ffi_prep_args_SYSV (extended_cif *ecif, unsigned *const stack) +{ + const unsigned bytes = ecif->cif->bytes; + const unsigned flags = ecif->cif->flags; + + typedef union + { + char *c; + unsigned *u; + long long *ll; + float *f; + double *d; + } valp; + + /* 'stacktop' points at the previous backchain pointer. */ + valp stacktop; + + /* 'gpr_base' points at the space for gpr3, and grows upwards as + we use GPR registers. */ + valp gpr_base; + int intarg_count; + +#ifndef __NO_FPRS__ + /* 'fpr_base' points at the space for fpr1, and grows upwards as + we use FPR registers. */ + valp fpr_base; + int fparg_count; +#endif + + /* 'copy_space' grows down as we put structures in it. It should + stay 16-byte aligned. */ + valp copy_space; + + /* 'next_arg' grows up as we put parameters in it. */ + valp next_arg; + + int i; + ffi_type **ptr; +#ifndef __NO_FPRS__ + double double_tmp; +#endif + union + { + void **v; + char **c; + signed char **sc; + unsigned char **uc; + signed short **ss; + unsigned short **us; + unsigned int **ui; + long long **ll; + float **f; + double **d; + } p_argv; + size_t struct_copy_size; + unsigned gprvalue; + + stacktop.c = (char *) stack + bytes; + gpr_base.u = stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS; + intarg_count = 0; +#ifndef __NO_FPRS__ + fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS; + fparg_count = 0; + copy_space.c = ((flags & FLAG_FP_ARGUMENTS) ? fpr_base.c : gpr_base.c); +#else + copy_space.c = gpr_base.c; +#endif + next_arg.u = stack + 2; + + /* Check that everything starts aligned properly. */ + FFI_ASSERT (((unsigned long) (char *) stack & 0xF) == 0); + FFI_ASSERT (((unsigned long) copy_space.c & 0xF) == 0); + FFI_ASSERT (((unsigned long) stacktop.c & 0xF) == 0); + FFI_ASSERT ((bytes & 0xF) == 0); + FFI_ASSERT (copy_space.c >= next_arg.c); + + /* Deal with return values that are actually pass-by-reference. */ + if (flags & FLAG_RETVAL_REFERENCE) + { + *gpr_base.u++ = (unsigned long) (char *) ecif->rvalue; + intarg_count++; + } + + /* Now for the arguments. */ + p_argv.v = ecif->avalue; + for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs; + i > 0; + i--, ptr++, p_argv.v++) + { + unsigned int typenum = (*ptr)->type; + + typenum = translate_float (ecif->cif->abi, typenum); + + /* Now test the translated value */ + switch (typenum) + { +#ifndef __NO_FPRS__ +# if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + case FFI_TYPE_LONGDOUBLE: + double_tmp = (*p_argv.d)[0]; + + if (fparg_count >= NUM_FPR_ARG_REGISTERS - 1) + { + if (intarg_count >= NUM_GPR_ARG_REGISTERS + && intarg_count % 2 != 0) + { + intarg_count++; + next_arg.u++; + } + *next_arg.d = double_tmp; + next_arg.u += 2; + double_tmp = (*p_argv.d)[1]; + *next_arg.d = double_tmp; + next_arg.u += 2; + } + else + { + *fpr_base.d++ = double_tmp; + double_tmp = (*p_argv.d)[1]; + *fpr_base.d++ = double_tmp; + } + + fparg_count += 2; + FFI_ASSERT (flags & FLAG_FP_ARGUMENTS); + break; +# endif + case FFI_TYPE_DOUBLE: + double_tmp = **p_argv.d; + + if (fparg_count >= NUM_FPR_ARG_REGISTERS) + { + if (intarg_count >= NUM_GPR_ARG_REGISTERS + && intarg_count % 2 != 0) + { + intarg_count++; + next_arg.u++; + } + *next_arg.d = double_tmp; + next_arg.u += 2; + } + else + *fpr_base.d++ = double_tmp; + fparg_count++; + FFI_ASSERT (flags & FLAG_FP_ARGUMENTS); + break; + + case FFI_TYPE_FLOAT: + double_tmp = **p_argv.f; + if (fparg_count >= NUM_FPR_ARG_REGISTERS) + { + *next_arg.f = (float) double_tmp; + next_arg.u += 1; + intarg_count++; + } + else + *fpr_base.d++ = double_tmp; + fparg_count++; + FFI_ASSERT (flags & FLAG_FP_ARGUMENTS); + break; +#endif /* have FPRs */ + + case FFI_TYPE_UINT128: + /* The soft float ABI for long doubles works like this, a long double + is passed in four consecutive GPRs if available. A maximum of 2 + long doubles can be passed in gprs. If we do not have 4 GPRs + left, the long double is passed on the stack, 4-byte aligned. */ + { + unsigned int int_tmp; + unsigned int ii; + if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3) + { + if (intarg_count < NUM_GPR_ARG_REGISTERS) + intarg_count = NUM_GPR_ARG_REGISTERS; + for (ii = 0; ii < 4; ii++) + { + int_tmp = (*p_argv.ui)[ii]; + *next_arg.u++ = int_tmp; + } + } + else + { + for (ii = 0; ii < 4; ii++) + { + int_tmp = (*p_argv.ui)[ii]; + *gpr_base.u++ = int_tmp; + } + } + intarg_count += 4; + break; + } + + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + if (intarg_count == NUM_GPR_ARG_REGISTERS-1) + intarg_count++; + if (intarg_count >= NUM_GPR_ARG_REGISTERS) + { + if (intarg_count % 2 != 0) + { + intarg_count++; + next_arg.u++; + } + *next_arg.ll = **p_argv.ll; + next_arg.u += 2; + } + else + { + /* The abi states only certain register pairs can be + used for passing long long int specifically (r3,r4), + (r5,r6), (r7,r8), (r9,r10). If next arg is long long + but not correct starting register of pair then skip + until the proper starting register. */ + if (intarg_count % 2 != 0) + { + intarg_count ++; + gpr_base.u++; + } + *gpr_base.ll++ = **p_argv.ll; + } + intarg_count += 2; + break; + + case FFI_TYPE_STRUCT: + struct_copy_size = ((*ptr)->size + 15) & ~0xF; + copy_space.c -= struct_copy_size; + memcpy (copy_space.c, *p_argv.c, (*ptr)->size); + + gprvalue = (unsigned long) copy_space.c; + + FFI_ASSERT (copy_space.c > next_arg.c); + FFI_ASSERT (flags & FLAG_ARG_NEEDS_COPY); + goto putgpr; + + case FFI_TYPE_UINT8: + gprvalue = **p_argv.uc; + goto putgpr; + case FFI_TYPE_SINT8: + gprvalue = **p_argv.sc; + goto putgpr; + case FFI_TYPE_UINT16: + gprvalue = **p_argv.us; + goto putgpr; + case FFI_TYPE_SINT16: + gprvalue = **p_argv.ss; + goto putgpr; + + case FFI_TYPE_INT: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT32: + case FFI_TYPE_POINTER: + + gprvalue = **p_argv.ui; + + putgpr: + if (intarg_count >= NUM_GPR_ARG_REGISTERS) + *next_arg.u++ = gprvalue; + else + *gpr_base.u++ = gprvalue; + intarg_count++; + break; + } + } + + /* Check that we didn't overrun the stack... */ + FFI_ASSERT (copy_space.c >= next_arg.c); + FFI_ASSERT (gpr_base.u <= stacktop.u - ASM_NEEDS_REGISTERS); + /* The assert below is testing that the number of integer arguments agrees + with the number found in ffi_prep_cif_machdep(). However, intarg_count + is incremented whenever we place an FP arg on the stack, so account for + that before our assert test. */ +#ifndef __NO_FPRS__ + if (fparg_count > NUM_FPR_ARG_REGISTERS) + intarg_count -= fparg_count - NUM_FPR_ARG_REGISTERS; + FFI_ASSERT (fpr_base.u + <= stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS); +#endif + FFI_ASSERT (flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4); +} + +#define MIN_CACHE_LINE_SIZE 8 + +static void +flush_icache (char *wraddr, char *xaddr, int size) +{ + int i; + for (i = 0; i < size; i += MIN_CACHE_LINE_SIZE) + __asm__ volatile ("icbi 0,%0;" "dcbf 0,%1;" + : : "r" (xaddr + i), "r" (wraddr + i) : "memory"); + __asm__ volatile ("icbi 0,%0;" "dcbf 0,%1;" "sync;" "isync;" + : : "r"(xaddr + size - 1), "r"(wraddr + size - 1) + : "memory"); +} + +ffi_status FFI_HIDDEN +ffi_prep_closure_loc_sysv (ffi_closure *closure, + ffi_cif *cif, + void (*fun) (ffi_cif *, void *, void **, void *), + void *user_data, + void *codeloc) +{ + unsigned int *tramp; + + if (cif->abi < FFI_SYSV || cif->abi >= FFI_LAST_ABI) + return FFI_BAD_ABI; + + tramp = (unsigned int *) &closure->tramp[0]; + tramp[0] = 0x7c0802a6; /* mflr r0 */ + tramp[1] = 0x4800000d; /* bl 10 */ + tramp[4] = 0x7d6802a6; /* mflr r11 */ + tramp[5] = 0x7c0803a6; /* mtlr r0 */ + tramp[6] = 0x800b0000; /* lwz r0,0(r11) */ + tramp[7] = 0x816b0004; /* lwz r11,4(r11) */ + tramp[8] = 0x7c0903a6; /* mtctr r0 */ + tramp[9] = 0x4e800420; /* bctr */ + *(void **) &tramp[2] = (void *) ffi_closure_SYSV; /* function */ + *(void **) &tramp[3] = codeloc; /* context */ + + /* Flush the icache. */ + flush_icache ((char *)tramp, (char *)codeloc, FFI_TRAMPOLINE_SIZE); + + closure->cif = cif; + closure->fun = fun; + closure->user_data = user_data; + + return FFI_OK; +} + +/* Basically the trampoline invokes ffi_closure_SYSV, and on + entry, r11 holds the address of the closure. + After storing the registers that could possibly contain + parameters to be passed into the stack frame and setting + up space for a return value, ffi_closure_SYSV invokes the + following helper function to do most of the work. */ + +int +ffi_closure_helper_SYSV (ffi_closure *closure, void *rvalue, + unsigned long *pgr, ffi_dblfl *pfr, + unsigned long *pst) +{ + /* rvalue is the pointer to space for return value in closure assembly */ + /* pgr is the pointer to where r3-r10 are stored in ffi_closure_SYSV */ + /* pfr is the pointer to where f1-f8 are stored in ffi_closure_SYSV */ + /* pst is the pointer to outgoing parameter stack in original caller */ + + void ** avalue; + ffi_type ** arg_types; + long i, avn; +#ifndef __NO_FPRS__ + long nf = 0; /* number of floating registers already used */ +#endif + long ng = 0; /* number of general registers already used */ + + ffi_cif *cif = closure->cif; + unsigned size = cif->rtype->size; + unsigned short rtypenum = cif->rtype->type; + + avalue = alloca (cif->nargs * sizeof (void *)); + + /* First translate for softfloat/nonlinux */ + rtypenum = translate_float (cif->abi, rtypenum); + + /* Copy the caller's structure return value address so that the closure + returns the data directly to the caller. + For FFI_SYSV the result is passed in r3/r4 if the struct size is less + or equal 8 bytes. */ + if (rtypenum == FFI_TYPE_STRUCT + && !((cif->abi & FFI_SYSV_STRUCT_RET) != 0 && size <= 8)) + { + rvalue = (void *) *pgr; + ng++; + pgr++; + } + + i = 0; + avn = cif->nargs; + arg_types = cif->arg_types; + + /* Grab the addresses of the arguments from the stack frame. */ + while (i < avn) { + unsigned short typenum = arg_types[i]->type; + + /* We may need to handle some values depending on ABI. */ + typenum = translate_float (cif->abi, typenum); + + switch (typenum) + { +#ifndef __NO_FPRS__ + case FFI_TYPE_FLOAT: + /* Unfortunately float values are stored as doubles + in the ffi_closure_SYSV code (since we don't check + the type in that routine). */ + if (nf < NUM_FPR_ARG_REGISTERS) + { + /* FIXME? here we are really changing the values + stored in the original calling routines outgoing + parameter stack. This is probably a really + naughty thing to do but... */ + double temp = pfr->d; + pfr->f = (float) temp; + avalue[i] = pfr; + nf++; + pfr++; + } + else + { + avalue[i] = pst; + pst += 1; + } + break; + + case FFI_TYPE_DOUBLE: + if (nf < NUM_FPR_ARG_REGISTERS) + { + avalue[i] = pfr; + nf++; + pfr++; + } + else + { + if (((long) pst) & 4) + pst++; + avalue[i] = pst; + pst += 2; + } + break; + +# if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + case FFI_TYPE_LONGDOUBLE: + if (nf < NUM_FPR_ARG_REGISTERS - 1) + { + avalue[i] = pfr; + pfr += 2; + nf += 2; + } + else + { + if (((long) pst) & 4) + pst++; + avalue[i] = pst; + pst += 4; + nf = 8; + } + break; +# endif +#endif + + case FFI_TYPE_UINT128: + /* Test if for the whole long double, 4 gprs are available. + otherwise the stuff ends up on the stack. */ + if (ng < NUM_GPR_ARG_REGISTERS - 3) + { + avalue[i] = pgr; + pgr += 4; + ng += 4; + } + else + { + avalue[i] = pst; + pst += 4; + ng = 8+4; + } + break; + + case FFI_TYPE_SINT8: + case FFI_TYPE_UINT8: +#ifndef __LITTLE_ENDIAN__ + if (ng < NUM_GPR_ARG_REGISTERS) + { + avalue[i] = (char *) pgr + 3; + ng++; + pgr++; + } + else + { + avalue[i] = (char *) pst + 3; + pst++; + } + break; +#endif + + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT16: +#ifndef __LITTLE_ENDIAN__ + if (ng < NUM_GPR_ARG_REGISTERS) + { + avalue[i] = (char *) pgr + 2; + ng++; + pgr++; + } + else + { + avalue[i] = (char *) pst + 2; + pst++; + } + break; +#endif + + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT32: + case FFI_TYPE_POINTER: + if (ng < NUM_GPR_ARG_REGISTERS) + { + avalue[i] = pgr; + ng++; + pgr++; + } + else + { + avalue[i] = pst; + pst++; + } + break; + + case FFI_TYPE_STRUCT: + /* Structs are passed by reference. The address will appear in a + gpr if it is one of the first 8 arguments. */ + if (ng < NUM_GPR_ARG_REGISTERS) + { + avalue[i] = (void *) *pgr; + ng++; + pgr++; + } + else + { + avalue[i] = (void *) *pst; + pst++; + } + break; + + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + /* Passing long long ints are complex, they must + be passed in suitable register pairs such as + (r3,r4) or (r5,r6) or (r6,r7), or (r7,r8) or (r9,r10) + and if the entire pair aren't available then the outgoing + parameter stack is used for both but an alignment of 8 + must will be kept. So we must either look in pgr + or pst to find the correct address for this type + of parameter. */ + if (ng < NUM_GPR_ARG_REGISTERS - 1) + { + if (ng & 1) + { + /* skip r4, r6, r8 as starting points */ + ng++; + pgr++; + } + avalue[i] = pgr; + ng += 2; + pgr += 2; + } + else + { + if (((long) pst) & 4) + pst++; + avalue[i] = pst; + pst += 2; + ng = NUM_GPR_ARG_REGISTERS; + } + break; + + default: + FFI_ASSERT (0); + } + + i++; + } + + (closure->fun) (cif, rvalue, avalue, closure->user_data); + + /* Tell ffi_closure_SYSV how to perform return type promotions. + Because the FFI_SYSV ABI returns the structures <= 8 bytes in + r3/r4 we have to tell ffi_closure_SYSV how to treat them. We + combine the base type FFI_SYSV_TYPE_SMALL_STRUCT with the size of + the struct less one. We never have a struct with size zero. + See the comment in ffitarget.h about ordering. */ + if (rtypenum == FFI_TYPE_STRUCT + && (cif->abi & FFI_SYSV_STRUCT_RET) != 0 && size <= 8) + return FFI_SYSV_TYPE_SMALL_STRUCT - 1 + size; + return rtypenum; +} +#endif diff --git a/Modules/_ctypes/libffi/src/powerpc/ffitarget.h b/Modules/_ctypes/libffi/src/powerpc/ffitarget.h index 3c9db495f49b..b47b0f5d3a2d 100644 --- a/Modules/_ctypes/libffi/src/powerpc/ffitarget.h +++ b/Modules/_ctypes/libffi/src/powerpc/ffitarget.h @@ -60,45 +60,76 @@ typedef signed long ffi_sarg; typedef enum ffi_abi { FFI_FIRST_ABI = 0, -#ifdef POWERPC - FFI_SYSV, - FFI_GCC_SYSV, - FFI_LINUX64, - FFI_LINUX, - FFI_LINUX_SOFT_FLOAT, -# if defined(POWERPC64) - FFI_DEFAULT_ABI = FFI_LINUX64, -# elif defined(__NO_FPRS__) - FFI_DEFAULT_ABI = FFI_LINUX_SOFT_FLOAT, -# elif (__LDBL_MANT_DIG__ == 106) - FFI_DEFAULT_ABI = FFI_LINUX, -# else - FFI_DEFAULT_ABI = FFI_GCC_SYSV, -# endif -#endif - -#ifdef POWERPC_AIX +#if defined (POWERPC_AIX) FFI_AIX, FFI_DARWIN, FFI_DEFAULT_ABI = FFI_AIX, -#endif + FFI_LAST_ABI -#ifdef POWERPC_DARWIN +#elif defined (POWERPC_DARWIN) FFI_AIX, FFI_DARWIN, FFI_DEFAULT_ABI = FFI_DARWIN, -#endif + FFI_LAST_ABI + +#else + /* The FFI_COMPAT values are used by old code. Since libffi may be + a shared library we have to support old values for backwards + compatibility. */ + FFI_COMPAT_SYSV, + FFI_COMPAT_GCC_SYSV, + FFI_COMPAT_LINUX64, + FFI_COMPAT_LINUX, + FFI_COMPAT_LINUX_SOFT_FLOAT, + +# if defined (POWERPC64) + /* This bit, always set in new code, must not be set in any of the + old FFI_COMPAT values that might be used for 64-bit linux. We + only need worry about FFI_COMPAT_LINUX64, but to be safe avoid + all old values. */ + FFI_LINUX = 8, + /* This and following bits can reuse FFI_COMPAT values. */ + FFI_LINUX_STRUCT_ALIGN = 1, + FFI_LINUX_LONG_DOUBLE_128 = 2, + FFI_DEFAULT_ABI = (FFI_LINUX +# ifdef __STRUCT_PARM_ALIGN__ + | FFI_LINUX_STRUCT_ALIGN +# endif +# ifdef __LONG_DOUBLE_128__ + | FFI_LINUX_LONG_DOUBLE_128 +# endif + ), + FFI_LAST_ABI = 12 -#ifdef POWERPC_FREEBSD - FFI_SYSV, - FFI_GCC_SYSV, - FFI_LINUX64, - FFI_LINUX, - FFI_LINUX_SOFT_FLOAT, - FFI_DEFAULT_ABI = FFI_SYSV, +# else + /* This bit, always set in new code, must not be set in any of the + old FFI_COMPAT values that might be used for 32-bit linux/sysv/bsd. */ + FFI_SYSV = 8, + /* This and following bits can reuse FFI_COMPAT values. */ + FFI_SYSV_SOFT_FLOAT = 1, + FFI_SYSV_STRUCT_RET = 2, + FFI_SYSV_IBM_LONG_DOUBLE = 4, + FFI_SYSV_LONG_DOUBLE_128 = 16, + + FFI_DEFAULT_ABI = (FFI_SYSV +# ifdef __NO_FPRS__ + | FFI_SYSV_SOFT_FLOAT +# endif +# if (defined (__SVR4_STRUCT_RETURN) \ + || defined (POWERPC_FREEBSD) && !defined (__AIX_STRUCT_RETURN)) + | FFI_SYSV_STRUCT_RET +# endif +# if __LDBL_MANT_DIG__ == 106 + | FFI_SYSV_IBM_LONG_DOUBLE +# endif +# ifdef __LONG_DOUBLE_128__ + | FFI_SYSV_LONG_DOUBLE_128 +# endif + ), + FFI_LAST_ABI = 32 +# endif #endif - FFI_LAST_ABI } ffi_abi; #endif @@ -106,6 +137,10 @@ typedef enum ffi_abi { #define FFI_CLOSURES 1 #define FFI_NATIVE_RAW_API 0 +#if defined (POWERPC) || defined (POWERPC_FREEBSD) +# define FFI_TARGET_SPECIFIC_VARIADIC 1 +# define FFI_EXTRA_CIF_FIELDS unsigned nfixedargs +#endif /* For additional types like the below, take care about the order in ppc_closures.S. They must follow after the FFI_TYPE_LAST. */ @@ -113,19 +148,26 @@ typedef enum ffi_abi { /* Needed for soft-float long-double-128 support. */ #define FFI_TYPE_UINT128 (FFI_TYPE_LAST + 1) -/* Needed for FFI_SYSV small structure returns. - We use two flag bits, (FLAG_SYSV_SMST_R3, FLAG_SYSV_SMST_R4) which are - defined in ffi.c, to determine the exact return type and its size. */ +/* Needed for FFI_SYSV small structure returns. */ #define FFI_SYSV_TYPE_SMALL_STRUCT (FFI_TYPE_LAST + 2) -#if defined(POWERPC64) || defined(POWERPC_AIX) +/* Used by ELFv2 for homogenous structure returns. */ +#define FFI_V2_TYPE_FLOAT_HOMOG (FFI_TYPE_LAST + 1) +#define FFI_V2_TYPE_DOUBLE_HOMOG (FFI_TYPE_LAST + 2) +#define FFI_V2_TYPE_SMALL_STRUCT (FFI_TYPE_LAST + 3) + +#if _CALL_ELF == 2 +# define FFI_TRAMPOLINE_SIZE 32 +#else +# if defined(POWERPC64) || defined(POWERPC_AIX) # if defined(POWERPC_DARWIN64) # define FFI_TRAMPOLINE_SIZE 48 # else # define FFI_TRAMPOLINE_SIZE 24 # endif -#else /* POWERPC || POWERPC_AIX */ +# else /* POWERPC || POWERPC_AIX */ # define FFI_TRAMPOLINE_SIZE 40 +# endif #endif #ifndef LIBFFI_ASM diff --git a/Modules/_ctypes/libffi/src/powerpc/linux64.S b/Modules/_ctypes/libffi/src/powerpc/linux64.S index f28da8120b78..c4d01d8e3f7a 100644 --- a/Modules/_ctypes/libffi/src/powerpc/linux64.S +++ b/Modules/_ctypes/libffi/src/powerpc/linux64.S @@ -29,18 +29,25 @@ #include #include -#ifdef __powerpc64__ +#ifdef POWERPC64 .hidden ffi_call_LINUX64 .globl ffi_call_LINUX64 +# if _CALL_ELF == 2 + .text +ffi_call_LINUX64: + addis %r2, %r12, .TOC.-ffi_call_LINUX64@ha + addi %r2, %r2, .TOC.-ffi_call_LINUX64@l + .localentry ffi_call_LINUX64, . - ffi_call_LINUX64 +# else .section ".opd","aw" .align 3 ffi_call_LINUX64: -#ifdef _CALL_LINUX +# ifdef _CALL_LINUX .quad .L.ffi_call_LINUX64,.TOC.@tocbase,0 .type ffi_call_LINUX64,@function .text .L.ffi_call_LINUX64: -#else +# else .hidden .ffi_call_LINUX64 .globl .ffi_call_LINUX64 .quad .ffi_call_LINUX64,.TOC.@tocbase,0 @@ -48,7 +55,8 @@ ffi_call_LINUX64: .type .ffi_call_LINUX64,@function .text .ffi_call_LINUX64: -#endif +# endif +# endif .LFB1: mflr %r0 std %r28, -32(%r1) @@ -63,26 +71,35 @@ ffi_call_LINUX64: mr %r31, %r5 /* flags, */ mr %r30, %r6 /* rvalue, */ mr %r29, %r7 /* function address. */ +/* Save toc pointer, not for the ffi_prep_args64 call, but for the later + bctrl function call. */ +# if _CALL_ELF == 2 + std %r2, 24(%r1) +# else std %r2, 40(%r1) +# endif /* Call ffi_prep_args64. */ mr %r4, %r1 -#ifdef _CALL_LINUX +# if defined _CALL_LINUX || _CALL_ELF == 2 bl ffi_prep_args64 -#else +# else bl .ffi_prep_args64 -#endif +# endif - ld %r0, 0(%r29) +# if _CALL_ELF == 2 + mr %r12, %r29 +# else + ld %r12, 0(%r29) ld %r2, 8(%r29) ld %r11, 16(%r29) - +# endif /* Now do the call. */ /* Set up cr1 with bits 4-7 of the flags. */ mtcrf 0x40, %r31 /* Get the address to call into CTR. */ - mtctr %r0 + mtctr %r12 /* Load all those argument registers. */ ld %r3, -32-(8*8)(%r28) ld %r4, -32-(7*8)(%r28) @@ -117,12 +134,17 @@ ffi_call_LINUX64: /* This must follow the call immediately, the unwinder uses this to find out if r2 has been saved or not. */ +# if _CALL_ELF == 2 + ld %r2, 24(%r1) +# else ld %r2, 40(%r1) +# endif /* Now, deal with the return value. */ mtcrf 0x01, %r31 - bt- 30, .Ldone_return_value - bt- 29, .Lfp_return_value + bt 31, .Lstruct_return_value + bt 30, .Ldone_return_value + bt 29, .Lfp_return_value std %r3, 0(%r30) /* Fall through... */ @@ -130,7 +152,7 @@ ffi_call_LINUX64: /* Restore the registers we used and return. */ mr %r1, %r28 ld %r0, 16(%r28) - ld %r28, -32(%r1) + ld %r28, -32(%r28) mtlr %r0 ld %r29, -24(%r1) ld %r30, -16(%r1) @@ -147,14 +169,48 @@ ffi_call_LINUX64: .Lfloat_return_value: stfs %f1, 0(%r30) b .Ldone_return_value + +.Lstruct_return_value: + bf 29, .Lsmall_struct + bf 28, .Lfloat_homog_return_value + stfd %f1, 0(%r30) + stfd %f2, 8(%r30) + stfd %f3, 16(%r30) + stfd %f4, 24(%r30) + stfd %f5, 32(%r30) + stfd %f6, 40(%r30) + stfd %f7, 48(%r30) + stfd %f8, 56(%r30) + b .Ldone_return_value + +.Lfloat_homog_return_value: + stfs %f1, 0(%r30) + stfs %f2, 4(%r30) + stfs %f3, 8(%r30) + stfs %f4, 12(%r30) + stfs %f5, 16(%r30) + stfs %f6, 20(%r30) + stfs %f7, 24(%r30) + stfs %f8, 28(%r30) + b .Ldone_return_value + +.Lsmall_struct: + std %r3, 0(%r30) + std %r4, 8(%r30) + b .Ldone_return_value + .LFE1: .long 0 .byte 0,12,0,1,128,4,0,0 -#ifdef _CALL_LINUX +# if _CALL_ELF == 2 + .size ffi_call_LINUX64,.-ffi_call_LINUX64 +# else +# ifdef _CALL_LINUX .size ffi_call_LINUX64,.-.L.ffi_call_LINUX64 -#else +# else .size .ffi_call_LINUX64,.-.ffi_call_LINUX64 -#endif +# endif +# endif .section .eh_frame,EH_FRAME_FLAGS,@progbits .Lframe1: @@ -197,8 +253,8 @@ ffi_call_LINUX64: .uleb128 0x4 .align 3 .LEFDE1: -#endif -#if defined __ELF__ && defined __linux__ +# if (defined __ELF__ && defined __linux__) || _CALL_ELF == 2 .section .note.GNU-stack,"",@progbits +# endif #endif diff --git a/Modules/_ctypes/libffi/src/powerpc/linux64_closure.S b/Modules/_ctypes/libffi/src/powerpc/linux64_closure.S index b1e12197a2b2..bc61b5ed946b 100644 --- a/Modules/_ctypes/libffi/src/powerpc/linux64_closure.S +++ b/Modules/_ctypes/libffi/src/powerpc/linux64_closure.S @@ -30,18 +30,25 @@ .file "linux64_closure.S" -#ifdef __powerpc64__ +#ifdef POWERPC64 FFI_HIDDEN (ffi_closure_LINUX64) .globl ffi_closure_LINUX64 +# if _CALL_ELF == 2 + .text +ffi_closure_LINUX64: + addis %r2, %r12, .TOC.-ffi_closure_LINUX64@ha + addi %r2, %r2, .TOC.-ffi_closure_LINUX64@l + .localentry ffi_closure_LINUX64, . - ffi_closure_LINUX64 +# else .section ".opd","aw" .align 3 ffi_closure_LINUX64: -#ifdef _CALL_LINUX +# ifdef _CALL_LINUX .quad .L.ffi_closure_LINUX64,.TOC.@tocbase,0 .type ffi_closure_LINUX64,@function .text .L.ffi_closure_LINUX64: -#else +# else FFI_HIDDEN (.ffi_closure_LINUX64) .globl .ffi_closure_LINUX64 .quad .ffi_closure_LINUX64,.TOC.@tocbase,0 @@ -49,61 +56,105 @@ ffi_closure_LINUX64: .type .ffi_closure_LINUX64,@function .text .ffi_closure_LINUX64: -#endif +# endif +# endif + +# if _CALL_ELF == 2 +# 32 byte special reg save area + 64 byte parm save area +# + 64 byte retval area + 13*8 fpr save area + round to 16 +# define STACKFRAME 272 +# define PARMSAVE 32 +# define RETVAL PARMSAVE+64 +# else +# 48 bytes special reg save area + 64 bytes parm save area +# + 16 bytes retval area + 13*8 bytes fpr save area + round to 16 +# define STACKFRAME 240 +# define PARMSAVE 48 +# define RETVAL PARMSAVE+64 +# endif + .LFB1: - # save general regs into parm save area - std %r3, 48(%r1) - std %r4, 56(%r1) - std %r5, 64(%r1) - std %r6, 72(%r1) +# if _CALL_ELF == 2 + ld %r12, FFI_TRAMPOLINE_SIZE(%r11) # closure->cif + mflr %r0 + lwz %r12, 28(%r12) # cif->flags + mtcrf 0x40, %r12 + addi %r12, %r1, PARMSAVE + bt 7, .Lparmsave + # Our caller has not allocated a parameter save area. + # We need to allocate one here and use it to pass gprs to + # ffi_closure_helper_LINUX64. + addi %r12, %r1, -STACKFRAME+PARMSAVE +.Lparmsave: + std %r0, 16(%r1) + # Save general regs into parm save area + std %r3, 0(%r12) + std %r4, 8(%r12) + std %r5, 16(%r12) + std %r6, 24(%r12) + std %r7, 32(%r12) + std %r8, 40(%r12) + std %r9, 48(%r12) + std %r10, 56(%r12) + + # load up the pointer to the parm save area + mr %r5, %r12 +# else + # copy r2 to r11 and load TOC into r2 + mr %r11, %r2 + ld %r2, 16(%r11) + mflr %r0 + # Save general regs into parm save area + # This is the parameter save area set up by our caller. + std %r3, PARMSAVE+0(%r1) + std %r4, PARMSAVE+8(%r1) + std %r5, PARMSAVE+16(%r1) + std %r6, PARMSAVE+24(%r1) + std %r7, PARMSAVE+32(%r1) + std %r8, PARMSAVE+40(%r1) + std %r9, PARMSAVE+48(%r1) + std %r10, PARMSAVE+56(%r1) - std %r7, 80(%r1) - std %r8, 88(%r1) - std %r9, 96(%r1) - std %r10, 104(%r1) std %r0, 16(%r1) - # mandatory 48 bytes special reg save area + 64 bytes parm save area - # + 16 bytes retval area + 13*8 bytes fpr save area + round to 16 - stdu %r1, -240(%r1) -.LCFI0: + # load up the pointer to the parm save area + addi %r5, %r1, PARMSAVE +# endif # next save fpr 1 to fpr 13 - stfd %f1, 128+(0*8)(%r1) - stfd %f2, 128+(1*8)(%r1) - stfd %f3, 128+(2*8)(%r1) - stfd %f4, 128+(3*8)(%r1) - stfd %f5, 128+(4*8)(%r1) - stfd %f6, 128+(5*8)(%r1) - stfd %f7, 128+(6*8)(%r1) - stfd %f8, 128+(7*8)(%r1) - stfd %f9, 128+(8*8)(%r1) - stfd %f10, 128+(9*8)(%r1) - stfd %f11, 128+(10*8)(%r1) - stfd %f12, 128+(11*8)(%r1) - stfd %f13, 128+(12*8)(%r1) - - # set up registers for the routine that actually does the work - # get the context pointer from the trampoline - mr %r3, %r11 + stfd %f1, -104+(0*8)(%r1) + stfd %f2, -104+(1*8)(%r1) + stfd %f3, -104+(2*8)(%r1) + stfd %f4, -104+(3*8)(%r1) + stfd %f5, -104+(4*8)(%r1) + stfd %f6, -104+(5*8)(%r1) + stfd %f7, -104+(6*8)(%r1) + stfd %f8, -104+(7*8)(%r1) + stfd %f9, -104+(8*8)(%r1) + stfd %f10, -104+(9*8)(%r1) + stfd %f11, -104+(10*8)(%r1) + stfd %f12, -104+(11*8)(%r1) + stfd %f13, -104+(12*8)(%r1) - # now load up the pointer to the result storage - addi %r4, %r1, 112 + # load up the pointer to the saved fpr registers */ + addi %r6, %r1, -104 - # now load up the pointer to the parameter save area - # in the previous frame - addi %r5, %r1, 240 + 48 + # load up the pointer to the result storage + addi %r4, %r1, -STACKFRAME+RETVAL - # now load up the pointer to the saved fpr registers */ - addi %r6, %r1, 128 + stdu %r1, -STACKFRAME(%r1) +.LCFI0: + + # get the context pointer from the trampoline + mr %r3, %r11 # make the call -#ifdef _CALL_LINUX +# if defined _CALL_LINUX || _CALL_ELF == 2 bl ffi_closure_helper_LINUX64 -#else +# else bl .ffi_closure_helper_LINUX64 -#endif +# endif .Lret: # now r3 contains the return type @@ -112,10 +163,12 @@ ffi_closure_LINUX64: # look up the proper starting point in table # by using return type as offset + ld %r0, STACKFRAME+16(%r1) + cmpldi %r3, FFI_V2_TYPE_SMALL_STRUCT + bge .Lsmall mflr %r4 # move address of .Lret to r4 sldi %r3, %r3, 4 # now multiply return type by 16 addi %r4, %r4, .Lret_type0 - .Lret - ld %r0, 240+16(%r1) add %r3, %r3, %r4 # add contents of table to table address mtctr %r3 bctr # jump to it @@ -128,89 +181,175 @@ ffi_closure_LINUX64: .Lret_type0: # case FFI_TYPE_VOID mtlr %r0 - addi %r1, %r1, 240 + addi %r1, %r1, STACKFRAME blr nop # case FFI_TYPE_INT - lwa %r3, 112+4(%r1) +# ifdef __LITTLE_ENDIAN__ + lwa %r3, RETVAL+0(%r1) +# else + lwa %r3, RETVAL+4(%r1) +# endif mtlr %r0 - addi %r1, %r1, 240 + addi %r1, %r1, STACKFRAME blr # case FFI_TYPE_FLOAT - lfs %f1, 112+0(%r1) + lfs %f1, RETVAL+0(%r1) mtlr %r0 - addi %r1, %r1, 240 + addi %r1, %r1, STACKFRAME blr # case FFI_TYPE_DOUBLE - lfd %f1, 112+0(%r1) + lfd %f1, RETVAL+0(%r1) mtlr %r0 - addi %r1, %r1, 240 + addi %r1, %r1, STACKFRAME blr # case FFI_TYPE_LONGDOUBLE - lfd %f1, 112+0(%r1) + lfd %f1, RETVAL+0(%r1) mtlr %r0 - lfd %f2, 112+8(%r1) + lfd %f2, RETVAL+8(%r1) b .Lfinish # case FFI_TYPE_UINT8 - lbz %r3, 112+7(%r1) +# ifdef __LITTLE_ENDIAN__ + lbz %r3, RETVAL+0(%r1) +# else + lbz %r3, RETVAL+7(%r1) +# endif mtlr %r0 - addi %r1, %r1, 240 + addi %r1, %r1, STACKFRAME blr # case FFI_TYPE_SINT8 - lbz %r3, 112+7(%r1) +# ifdef __LITTLE_ENDIAN__ + lbz %r3, RETVAL+0(%r1) +# else + lbz %r3, RETVAL+7(%r1) +# endif extsb %r3,%r3 mtlr %r0 b .Lfinish # case FFI_TYPE_UINT16 - lhz %r3, 112+6(%r1) +# ifdef __LITTLE_ENDIAN__ + lhz %r3, RETVAL+0(%r1) +# else + lhz %r3, RETVAL+6(%r1) +# endif mtlr %r0 .Lfinish: - addi %r1, %r1, 240 + addi %r1, %r1, STACKFRAME blr # case FFI_TYPE_SINT16 - lha %r3, 112+6(%r1) +# ifdef __LITTLE_ENDIAN__ + lha %r3, RETVAL+0(%r1) +# else + lha %r3, RETVAL+6(%r1) +# endif mtlr %r0 - addi %r1, %r1, 240 + addi %r1, %r1, STACKFRAME blr # case FFI_TYPE_UINT32 - lwz %r3, 112+4(%r1) +# ifdef __LITTLE_ENDIAN__ + lwz %r3, RETVAL+0(%r1) +# else + lwz %r3, RETVAL+4(%r1) +# endif mtlr %r0 - addi %r1, %r1, 240 + addi %r1, %r1, STACKFRAME blr # case FFI_TYPE_SINT32 - lwa %r3, 112+4(%r1) +# ifdef __LITTLE_ENDIAN__ + lwa %r3, RETVAL+0(%r1) +# else + lwa %r3, RETVAL+4(%r1) +# endif mtlr %r0 - addi %r1, %r1, 240 + addi %r1, %r1, STACKFRAME blr # case FFI_TYPE_UINT64 - ld %r3, 112+0(%r1) + ld %r3, RETVAL+0(%r1) mtlr %r0 - addi %r1, %r1, 240 + addi %r1, %r1, STACKFRAME blr # case FFI_TYPE_SINT64 - ld %r3, 112+0(%r1) + ld %r3, RETVAL+0(%r1) mtlr %r0 - addi %r1, %r1, 240 + addi %r1, %r1, STACKFRAME blr # case FFI_TYPE_STRUCT mtlr %r0 - addi %r1, %r1, 240 + addi %r1, %r1, STACKFRAME blr nop # case FFI_TYPE_POINTER - ld %r3, 112+0(%r1) + ld %r3, RETVAL+0(%r1) + mtlr %r0 + addi %r1, %r1, STACKFRAME + blr +# case FFI_V2_TYPE_FLOAT_HOMOG + lfs %f1, RETVAL+0(%r1) + lfs %f2, RETVAL+4(%r1) + lfs %f3, RETVAL+8(%r1) + b .Lmorefloat +# case FFI_V2_TYPE_DOUBLE_HOMOG + lfd %f1, RETVAL+0(%r1) + lfd %f2, RETVAL+8(%r1) + lfd %f3, RETVAL+16(%r1) + lfd %f4, RETVAL+24(%r1) + mtlr %r0 + lfd %f5, RETVAL+32(%r1) + lfd %f6, RETVAL+40(%r1) + lfd %f7, RETVAL+48(%r1) + lfd %f8, RETVAL+56(%r1) + addi %r1, %r1, STACKFRAME + blr +.Lmorefloat: + lfs %f4, RETVAL+12(%r1) + mtlr %r0 + lfs %f5, RETVAL+16(%r1) + lfs %f6, RETVAL+20(%r1) + lfs %f7, RETVAL+24(%r1) + lfs %f8, RETVAL+28(%r1) + addi %r1, %r1, STACKFRAME + blr +.Lsmall: +# ifdef __LITTLE_ENDIAN__ + ld %r3,RETVAL+0(%r1) mtlr %r0 - addi %r1, %r1, 240 + ld %r4,RETVAL+8(%r1) + addi %r1, %r1, STACKFRAME blr -# esac +# else + # A struct smaller than a dword is returned in the low bits of r3 + # ie. right justified. Larger structs are passed left justified + # in r3 and r4. The return value area on the stack will have + # the structs as they are usually stored in memory. + cmpldi %r3, FFI_V2_TYPE_SMALL_STRUCT + 7 # size 8 bytes? + neg %r5, %r3 + ld %r3,RETVAL+0(%r1) + blt .Lsmalldown + mtlr %r0 + ld %r4,RETVAL+8(%r1) + addi %r1, %r1, STACKFRAME + blr +.Lsmalldown: + addi %r5, %r5, FFI_V2_TYPE_SMALL_STRUCT + 7 + mtlr %r0 + sldi %r5, %r5, 3 + addi %r1, %r1, STACKFRAME + srd %r3, %r3, %r5 + blr +# endif + .LFE1: .long 0 .byte 0,12,0,1,128,0,0,0 -#ifdef _CALL_LINUX +# if _CALL_ELF == 2 + .size ffi_closure_LINUX64,.-ffi_closure_LINUX64 +# else +# ifdef _CALL_LINUX .size ffi_closure_LINUX64,.-.L.ffi_closure_LINUX64 -#else +# else .size .ffi_closure_LINUX64,.-.ffi_closure_LINUX64 -#endif +# endif +# endif .section .eh_frame,EH_FRAME_FLAGS,@progbits .Lframe1: @@ -239,14 +378,14 @@ ffi_closure_LINUX64: .byte 0x2 # DW_CFA_advance_loc1 .byte .LCFI0-.LFB1 .byte 0xe # DW_CFA_def_cfa_offset - .uleb128 240 + .uleb128 STACKFRAME .byte 0x11 # DW_CFA_offset_extended_sf .uleb128 0x41 .sleb128 -2 .align 3 .LEFDE1: -#endif -#if defined __ELF__ && defined __linux__ +# if defined __ELF__ && defined __linux__ .section .note.GNU-stack,"",@progbits +# endif #endif diff --git a/Modules/_ctypes/libffi/src/powerpc/ppc_closure.S b/Modules/_ctypes/libffi/src/powerpc/ppc_closure.S index 41fb8851b624..075922cbb07e 100644 --- a/Modules/_ctypes/libffi/src/powerpc/ppc_closure.S +++ b/Modules/_ctypes/libffi/src/powerpc/ppc_closure.S @@ -31,7 +31,7 @@ .file "ppc_closure.S" -#ifndef __powerpc64__ +#ifndef POWERPC64 ENTRY(ffi_closure_SYSV) .LFB1: @@ -159,25 +159,41 @@ ENTRY(ffi_closure_SYSV) #endif # case FFI_TYPE_UINT8 +#ifdef __LITTLE_ENDIAN__ + lbz %r3,112+0(%r1) +#else lbz %r3,112+3(%r1) +#endif mtlr %r0 addi %r1,%r1,144 blr # case FFI_TYPE_SINT8 +#ifdef __LITTLE_ENDIAN__ + lbz %r3,112+0(%r1) +#else lbz %r3,112+3(%r1) +#endif extsb %r3,%r3 mtlr %r0 b .Lfinish # case FFI_TYPE_UINT16 +#ifdef __LITTLE_ENDIAN__ + lhz %r3,112+0(%r1) +#else lhz %r3,112+2(%r1) +#endif mtlr %r0 addi %r1,%r1,144 blr # case FFI_TYPE_SINT16 +#ifdef __LITTLE_ENDIAN__ + lha %r3,112+0(%r1) +#else lha %r3,112+2(%r1) +#endif mtlr %r0 addi %r1,%r1,144 blr @@ -222,7 +238,7 @@ ENTRY(ffi_closure_SYSV) lwz %r3,112+0(%r1) lwz %r4,112+4(%r1) lwz %r5,112+8(%r1) - bl .Luint128 + b .Luint128 # The return types below are only used when the ABI type is FFI_SYSV. # case FFI_SYSV_TYPE_SMALL_STRUCT + 1. One byte struct. @@ -239,9 +255,15 @@ ENTRY(ffi_closure_SYSV) # case FFI_SYSV_TYPE_SMALL_STRUCT + 3. Three byte struct. lwz %r3,112+0(%r1) +#ifdef __LITTLE_ENDIAN__ + mtlr %r0 + addi %r1,%r1,144 + blr +#else srwi %r3,%r3,8 mtlr %r0 b .Lfinish +#endif # case FFI_SYSV_TYPE_SMALL_STRUCT + 4. Four byte struct. lwz %r3,112+0(%r1) @@ -252,20 +274,35 @@ ENTRY(ffi_closure_SYSV) # case FFI_SYSV_TYPE_SMALL_STRUCT + 5. Five byte struct. lwz %r3,112+0(%r1) lwz %r4,112+4(%r1) +#ifdef __LITTLE_ENDIAN__ + mtlr %r0 + b .Lfinish +#else li %r5,24 b .Lstruct567 +#endif # case FFI_SYSV_TYPE_SMALL_STRUCT + 6. Six byte struct. lwz %r3,112+0(%r1) lwz %r4,112+4(%r1) +#ifdef __LITTLE_ENDIAN__ + mtlr %r0 + b .Lfinish +#else li %r5,16 b .Lstruct567 +#endif # case FFI_SYSV_TYPE_SMALL_STRUCT + 7. Seven byte struct. lwz %r3,112+0(%r1) lwz %r4,112+4(%r1) +#ifdef __LITTLE_ENDIAN__ + mtlr %r0 + b .Lfinish +#else li %r5,8 b .Lstruct567 +#endif # case FFI_SYSV_TYPE_SMALL_STRUCT + 8. Eight byte struct. lwz %r3,112+0(%r1) @@ -273,6 +310,7 @@ ENTRY(ffi_closure_SYSV) mtlr %r0 b .Lfinish +#ifndef __LITTLE_ENDIAN__ .Lstruct567: subfic %r6,%r5,32 srw %r4,%r4,%r5 @@ -282,13 +320,14 @@ ENTRY(ffi_closure_SYSV) mtlr %r0 addi %r1,%r1,144 blr +#endif .Luint128: lwz %r6,112+12(%r1) mtlr %r0 addi %r1,%r1,144 blr - + END(ffi_closure_SYSV) .section ".eh_frame",EH_FRAME_FLAGS,@progbits @@ -339,8 +378,7 @@ END(ffi_closure_SYSV) .align 2 .LEFDE1: -#endif - #if defined __ELF__ && defined __linux__ .section .note.GNU-stack,"",@progbits #endif +#endif diff --git a/Modules/_ctypes/libffi/src/powerpc/sysv.S b/Modules/_ctypes/libffi/src/powerpc/sysv.S index 5ee3a19fc189..fed2380c9fac 100644 --- a/Modules/_ctypes/libffi/src/powerpc/sysv.S +++ b/Modules/_ctypes/libffi/src/powerpc/sysv.S @@ -30,7 +30,7 @@ #include #include -#ifndef __powerpc64__ +#ifndef POWERPC64 .globl ffi_prep_args_SYSV ENTRY(ffi_call_SYSV) .LFB1: @@ -142,19 +142,14 @@ L(float_return_value): #endif L(small_struct_return_value): - extrwi %r6,%r31,2,19 /* number of bytes padding = shift/8 */ - mtcrf 0x02,%r31 /* copy flags to cr[24:27] (cr6) */ - extrwi %r5,%r31,5,19 /* r5 <- number of bits of padding */ - subfic %r6,%r6,4 /* r6 <- number of useful bytes in r3 */ - bf- 25,L(done_return_value) /* struct in r3 ? if not, done. */ -/* smst_one_register: */ - slw %r3,%r3,%r5 /* Left-justify value in r3 */ - mtxer %r6 /* move byte count to XER ... */ - stswx %r3,0,%r30 /* ... and store that many bytes */ - bf+ 26,L(done_return_value) /* struct in r3:r4 ? */ - add %r6,%r6,%r30 /* adjust pointer */ - stswi %r4,%r6,4 /* store last four bytes */ - b L(done_return_value) + /* + * The C code always allocates a properly-aligned 8-byte bounce + * buffer to make this assembly code very simple. Just write out + * r3 and r4 to the buffer to allow the C code to handle the rest. + */ + stw %r3, 0(%r30) + stw %r4, 4(%r30) + b L(done_return_value) .LFE1: END(ffi_call_SYSV) @@ -218,8 +213,8 @@ END(ffi_call_SYSV) .uleb128 0x1c .align 2 .LEFDE1: -#endif #if defined __ELF__ && defined __linux__ .section .note.GNU-stack,"",@progbits #endif +#endif diff --git a/Modules/_ctypes/libffi/src/prep_cif.c b/Modules/_ctypes/libffi/src/prep_cif.c index e8ec5cf1e6c4..55ceed8c5e70 100644 --- a/Modules/_ctypes/libffi/src/prep_cif.c +++ b/Modules/_ctypes/libffi/src/prep_cif.c @@ -76,6 +76,13 @@ static ffi_status initialize_aggregate(ffi_type *arg) total size of 3*sizeof(long). */ arg->size = ALIGN (arg->size, arg->alignment); + /* On some targets, the ABI defines that structures have an additional + alignment beyond the "natural" one based on their elements. */ +#ifdef FFI_AGGREGATE_ALIGNMENT + if (FFI_AGGREGATE_ALIGNMENT > arg->alignment) + arg->alignment = FFI_AGGREGATE_ALIGNMENT; +#endif + if (arg->size == 0) return FFI_BAD_TYPEDEF; else @@ -111,13 +118,8 @@ ffi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi, FFI_ASSERT((!isvariadic) || (nfixedargs >= 1)); FFI_ASSERT(nfixedargs <= ntotalargs); -#ifndef X86_WIN32 if (! (abi > FFI_FIRST_ABI && abi < FFI_LAST_ABI)) return FFI_BAD_ABI; -#else - if (! (abi > FFI_FIRST_ABI && abi < FFI_LAST_ABI || abi == FFI_THISCALL)) - return FFI_BAD_ABI; -#endif cif->abi = abi; cif->arg_types = atypes; @@ -126,6 +128,10 @@ ffi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi, cif->flags = 0; +#if HAVE_LONG_DOUBLE_VARIANT + ffi_prep_types (abi); +#endif + /* Initialize the return type if necessary */ if ((cif->rtype->size == 0) && (initialize_aggregate(cif->rtype) != FFI_OK)) return FFI_BAD_TYPEDEF; @@ -146,7 +152,9 @@ ffi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi, #ifdef XTENSA && (cif->rtype->size > 16) #endif - +#ifdef NIOS2 + && (cif->rtype->size > 8) +#endif ) bytes = STACK_ARG_SIZE(sizeof(void*)); #endif @@ -174,7 +182,7 @@ ffi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi, { /* Add any padding if necessary */ if (((*ptr)->alignment - 1) & bytes) - bytes = ALIGN(bytes, (*ptr)->alignment); + bytes = (unsigned)ALIGN(bytes, (*ptr)->alignment); #ifdef TILE if (bytes < 10 * FFI_SIZEOF_ARG && diff --git a/Modules/_ctypes/libffi/src/sh/ffi.c b/Modules/_ctypes/libffi/src/sh/ffi.c index 3515b91b1d07..9ec86bfb205c 100644 --- a/Modules/_ctypes/libffi/src/sh/ffi.c +++ b/Modules/_ctypes/libffi/src/sh/ffi.c @@ -41,7 +41,7 @@ #define STRUCT_VALUE_ADDRESS_WITH_ARG 0 #endif -/* If the structure has essentialy an unique element, return its type. */ +/* If the structure has essentially an unique element, return its type. */ static int simple_type (ffi_type *arg) { diff --git a/Modules/_ctypes/libffi/src/tile/tile.S b/Modules/_ctypes/libffi/src/tile/tile.S index a186e1f8f008..d1f82cb3dbfa 100644 --- a/Modules/_ctypes/libffi/src/tile/tile.S +++ b/Modules/_ctypes/libffi/src/tile/tile.S @@ -60,7 +60,7 @@ void (*fnaddr)(void)); On entry, REG_ARGS contain the outgoing register values, - and STACK_ARGS containts STACK_ARG_BYTES of additional values + and STACK_ARGS contains STACK_ARG_BYTES of additional values to be passed on the stack. If STACK_ARG_BYTES is zero, then STACK_ARGS is ignored. diff --git a/Modules/_ctypes/libffi/src/types.c b/Modules/_ctypes/libffi/src/types.c index 0a11eb0fb4b0..0de59942396c 100644 --- a/Modules/_ctypes/libffi/src/types.c +++ b/Modules/_ctypes/libffi/src/types.c @@ -44,6 +44,17 @@ const ffi_type ffi_type_##name = { \ id, NULL \ } +#define FFI_NONCONST_TYPEDEF(name, type, id) \ +struct struct_align_##name { \ + char c; \ + type x; \ +}; \ +ffi_type ffi_type_##name = { \ + sizeof(type), \ + offsetof(struct struct_align_##name, x), \ + id, NULL \ +} + /* Size and alignment are fake here. They must not be 0. */ const ffi_type ffi_type_void = { 1, 1, FFI_TYPE_VOID, NULL @@ -73,5 +84,9 @@ FFI_TYPEDEF(double, double, FFI_TYPE_DOUBLE); # endif const ffi_type ffi_type_longdouble = { 16, 16, 4, NULL }; #elif FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE +# if HAVE_LONG_DOUBLE_VARIANT +FFI_NONCONST_TYPEDEF(longdouble, long double, FFI_TYPE_LONGDOUBLE); +# else FFI_TYPEDEF(longdouble, long double, FFI_TYPE_LONGDOUBLE); +# endif #endif diff --git a/Modules/_ctypes/libffi/src/vax/elfbsd.S b/Modules/_ctypes/libffi/src/vax/elfbsd.S new file mode 100644 index 000000000000..01ca313402b2 --- /dev/null +++ b/Modules/_ctypes/libffi/src/vax/elfbsd.S @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2013 Miodrag Vallat. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * ``Software''), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * vax Foreign Function Interface + */ + +#define LIBFFI_ASM +#include +#include + + .text + +/* + * void * %r0 + * ffi_call_elfbsd(extended_cif *ecif, 4(%ap) + * unsigned bytes, 8(%ap) + * unsigned flags, 12(%ap) + * void *rvalue, 16(%ap) + * void (*fn)()); 20(%ap) + */ + .globl ffi_call_elfbsd + .type ffi_call_elfbsd,@function + .align 2 +ffi_call_elfbsd: + .word 0x00c # save R2 and R3 + + # Allocate stack space for the args + subl2 8(%ap), %sp + + # Call ffi_prep_args + pushl %sp + pushl 4(%ap) + calls $2, ffi_prep_args + + # Get function pointer + movl 20(%ap), %r1 + + # Build a CALLS frame + ashl $-2, 8(%ap), %r0 + pushl %r0 # argument stack usage + movl %sp, %r0 # future %ap + # saved registers + bbc $11, 0(%r1), 1f + pushl %r11 +1: bbc $10, 0(%r1), 1f + pushl %r10 +1: bbc $9, 0(%r1), 1f + pushl %r9 +1: bbc $8, 0(%r1), 1f + pushl %r8 +1: bbc $7, 0(%r1), 1f + pushl %r7 +1: bbc $6, 0(%r1), 1f + pushl %r6 +1: bbc $5, 0(%r1), 1f + pushl %r5 +1: bbc $4, 0(%r1), 1f + pushl %r4 +1: bbc $3, 0(%r1), 1f + pushl %r3 +1: bbc $2, 0(%r1), 1f + pushl %r2 +1: + pushal 9f + pushl %fp + pushl %ap + movl 16(%ap), %r3 # struct return address, if needed + movl %r0, %ap + movzwl 4(%fp), %r0 # previous PSW, without the saved registers mask + bisl2 $0x20000000, %r0 # calls frame + movzwl 0(%r1), %r2 + bicw2 $0xf003, %r2 # only keep R11-R2 + ashl $16, %r2, %r2 + bisl2 %r2, %r0 # saved register mask of the called function + pushl %r0 + pushl $0 + movl %sp, %fp + + # Invoke the function + pushal 2(%r1) # skip procedure entry mask + movl %r3, %r1 + bicpsw $0x000f + rsb + +9: + # Copy return value if necessary + tstl 16(%ap) + jeql 9f + movl 16(%ap), %r2 + + bbc $0, 12(%ap), 1f # CIF_FLAGS_CHAR + movb %r0, 0(%r2) + brb 9f +1: + bbc $1, 12(%ap), 1f # CIF_FLAGS_SHORT + movw %r0, 0(%r2) + brb 9f +1: + bbc $2, 12(%ap), 1f # CIF_FLAGS_INT + movl %r0, 0(%r2) + brb 9f +1: + bbc $3, 12(%ap), 1f # CIF_FLAGS_DINT + movq %r0, 0(%r2) + brb 9f +1: + movl %r1, %r0 # might have been a struct + #brb 9f + +9: + ret + +/* + * ffi_closure_elfbsd(void); + * invoked with %r0: ffi_closure *closure + */ + .globl ffi_closure_elfbsd + .type ffi_closure_elfbsd, @function + .align 2 +ffi_closure_elfbsd: + .word 0 + + # Allocate room on stack for return value + subl2 $8, %sp + + # Invoke the closure function + pushal 4(%ap) # calling stack + pushal 4(%sp) # return value + pushl %r0 # closure + calls $3, ffi_closure_elfbsd_inner + + # Copy return value if necessary + bitb $1, %r0 # CIF_FLAGS_CHAR + beql 1f + movb 0(%sp), %r0 + brb 9f +1: + bitb $2, %r0 # CIF_FLAGS_SHORT + beql 1f + movw 0(%sp), %r0 + brb 9f +1: + bitb $4, %r0 # CIF_FLAGS_INT + beql 1f + movl 0(%sp), %r0 + brb 9f +1: + bitb $8, %r0 # CIF_FLAGS_DINT + beql 1f + movq 0(%sp), %r0 + #brb 9f +1: + +9: + ret + +/* + * ffi_closure_struct_elfbsd(void); + * invoked with %r0: ffi_closure *closure + * %r1: struct return address + */ + .globl ffi_closure_struct_elfbsd + .type ffi_closure_struct_elfbsd, @function + .align 2 +ffi_closure_struct_elfbsd: + .word 0 + + # Invoke the closure function + pushal 4(%ap) # calling stack + pushl %r1 # return value + pushl %r0 # closure + calls $3, ffi_closure_elfbsd_inner + + ret diff --git a/Modules/_ctypes/libffi/src/vax/ffi.c b/Modules/_ctypes/libffi/src/vax/ffi.c new file mode 100644 index 000000000000..f4d6bbb4f404 --- /dev/null +++ b/Modules/_ctypes/libffi/src/vax/ffi.c @@ -0,0 +1,276 @@ +/* + * Copyright (c) 2013 Miodrag Vallat. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * ``Software''), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * vax Foreign Function Interface + * + * This file attempts to provide all the FFI entry points which can reliably + * be implemented in C. + */ + +#include +#include + +#include +#include + +#define CIF_FLAGS_CHAR 1 /* for struct only */ +#define CIF_FLAGS_SHORT 2 /* for struct only */ +#define CIF_FLAGS_INT 4 +#define CIF_FLAGS_DINT 8 + +/* + * Foreign Function Interface API + */ + +void ffi_call_elfbsd (extended_cif *, unsigned, unsigned, void *, + void (*) ()); +void *ffi_prep_args (extended_cif *ecif, void *stack); + +void * +ffi_prep_args (extended_cif *ecif, void *stack) +{ + unsigned int i; + void **p_argv; + char *argp; + ffi_type **p_arg; + void *struct_value_ptr; + + argp = stack; + + if (ecif->cif->rtype->type == FFI_TYPE_STRUCT + && !ecif->cif->flags) + struct_value_ptr = ecif->rvalue; + else + struct_value_ptr = NULL; + + p_argv = ecif->avalue; + + for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; + i != 0; + i--, p_arg++) + { + size_t z; + + z = (*p_arg)->size; + if (z < sizeof (int)) + { + switch ((*p_arg)->type) + { + case FFI_TYPE_SINT8: + *(signed int *) argp = (signed int) *(SINT8 *) *p_argv; + break; + + case FFI_TYPE_UINT8: + *(unsigned int *) argp = (unsigned int) *(UINT8 *) *p_argv; + break; + + case FFI_TYPE_SINT16: + *(signed int *) argp = (signed int) *(SINT16 *) *p_argv; + break; + + case FFI_TYPE_UINT16: + *(unsigned int *) argp = (unsigned int) *(UINT16 *) *p_argv; + break; + + case FFI_TYPE_STRUCT: + memcpy (argp, *p_argv, z); + break; + + default: + FFI_ASSERT (0); + } + z = sizeof (int); + } + else + { + memcpy (argp, *p_argv, z); + + /* Align if necessary. */ + if ((sizeof(int) - 1) & z) + z = ALIGN(z, sizeof(int)); + } + + p_argv++; + argp += z; + } + + return struct_value_ptr; +} + +ffi_status +ffi_prep_cif_machdep (ffi_cif *cif) +{ + /* Set the return type flag */ + switch (cif->rtype->type) + { + case FFI_TYPE_VOID: + cif->flags = 0; + break; + + case FFI_TYPE_STRUCT: + if (cif->rtype->elements[0]->type == FFI_TYPE_STRUCT && + cif->rtype->elements[1]) + { + cif->flags = 0; + break; + } + + if (cif->rtype->size == sizeof (char)) + cif->flags = CIF_FLAGS_CHAR; + else if (cif->rtype->size == sizeof (short)) + cif->flags = CIF_FLAGS_SHORT; + else if (cif->rtype->size == sizeof (int)) + cif->flags = CIF_FLAGS_INT; + else if (cif->rtype->size == 2 * sizeof (int)) + cif->flags = CIF_FLAGS_DINT; + else + cif->flags = 0; + break; + + default: + if (cif->rtype->size <= sizeof (int)) + cif->flags = CIF_FLAGS_INT; + else + cif->flags = CIF_FLAGS_DINT; + break; + } + + return FFI_OK; +} + +void +ffi_call (ffi_cif *cif, void (*fn) (), void *rvalue, void **avalue) +{ + extended_cif ecif; + + ecif.cif = cif; + ecif.avalue = avalue; + + /* If the return value is a struct and we don't have a return value + address then we need to make one. */ + + if (rvalue == NULL + && cif->rtype->type == FFI_TYPE_STRUCT + && cif->flags == 0) + ecif.rvalue = alloca (cif->rtype->size); + else + ecif.rvalue = rvalue; + + switch (cif->abi) + { + case FFI_ELFBSD: + ffi_call_elfbsd (&ecif, cif->bytes, cif->flags, ecif.rvalue, fn); + break; + + default: + FFI_ASSERT (0); + break; + } +} + +/* + * Closure API + */ + +void ffi_closure_elfbsd (void); +void ffi_closure_struct_elfbsd (void); +unsigned int ffi_closure_elfbsd_inner (ffi_closure *, void *, char *); + +static void +ffi_prep_closure_elfbsd (ffi_cif *cif, void **avalue, char *stackp) +{ + unsigned int i; + void **p_argv; + ffi_type **p_arg; + + p_argv = avalue; + + for (i = cif->nargs, p_arg = cif->arg_types; i != 0; i--, p_arg++) + { + size_t z; + + z = (*p_arg)->size; + *p_argv = stackp; + + /* Align if necessary */ + if ((sizeof (int) - 1) & z) + z = ALIGN(z, sizeof (int)); + + p_argv++; + stackp += z; + } +} + +unsigned int +ffi_closure_elfbsd_inner (ffi_closure *closure, void *resp, char *stack) +{ + ffi_cif *cif; + void **arg_area; + + cif = closure->cif; + arg_area = (void **) alloca (cif->nargs * sizeof (void *)); + + ffi_prep_closure_elfbsd (cif, arg_area, stack); + + (closure->fun) (cif, resp, arg_area, closure->user_data); + + return cif->flags; +} + +ffi_status +ffi_prep_closure_loc (ffi_closure *closure, ffi_cif *cif, + void (*fun)(ffi_cif *, void *, void **, void *), + void *user_data, void *codeloc) +{ + char *tramp = (char *) codeloc; + void *fn; + + FFI_ASSERT (cif->abi == FFI_ELFBSD); + + /* entry mask */ + *(unsigned short *)(tramp + 0) = 0x0000; + /* movl #closure, r0 */ + tramp[2] = 0xd0; + tramp[3] = 0x8f; + *(unsigned int *)(tramp + 4) = (unsigned int) closure; + tramp[8] = 0x50; + + if (cif->rtype->type == FFI_TYPE_STRUCT + && !cif->flags) + fn = &ffi_closure_struct_elfbsd; + else + fn = &ffi_closure_elfbsd; + + /* jmpl #fn */ + tramp[9] = 0x17; + tramp[10] = 0xef; + *(unsigned int *)(tramp + 11) = (unsigned int)fn + 2 - + (unsigned int)tramp - 9 - 6; + + closure->cif = cif; + closure->user_data = user_data; + closure->fun = fun; + + return FFI_OK; +} diff --git a/Modules/_ctypes/libffi/src/vax/ffitarget.h b/Modules/_ctypes/libffi/src/vax/ffitarget.h new file mode 100644 index 000000000000..2fc94881abbc --- /dev/null +++ b/Modules/_ctypes/libffi/src/vax/ffitarget.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013 Miodrag Vallat. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * ``Software''), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * vax Foreign Function Interface + */ + +#ifndef LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +#ifndef LIBFFI_ASM +typedef unsigned long ffi_arg; +typedef signed long ffi_sarg; + +typedef enum ffi_abi { + FFI_FIRST_ABI = 0, + FFI_ELFBSD, + FFI_DEFAULT_ABI = FFI_ELFBSD, + FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 +} ffi_abi; +#endif + +/* ---- Definitions for closures ----------------------------------------- */ + +#define FFI_CLOSURES 1 +#define FFI_TRAMPOLINE_SIZE 15 +#define FFI_NATIVE_RAW_API 0 + +#endif diff --git a/Modules/_ctypes/libffi/src/x86/ffi.c b/Modules/_ctypes/libffi/src/x86/ffi.c index 0600414d458e..64b19ecfd4f6 100644 --- a/Modules/_ctypes/libffi/src/x86/ffi.c +++ b/Modules/_ctypes/libffi/src/x86/ffi.c @@ -39,16 +39,18 @@ #include + /* ffi_prep_args is called by the assembly routine once stack space has been allocated for the function's arguments */ +void ffi_prep_args(char *stack, extended_cif *ecif); void ffi_prep_args(char *stack, extended_cif *ecif) { register unsigned int i; register void **p_argv; register char *argp; register ffi_type **p_arg; -#ifdef X86_WIN32 +#ifndef X86_WIN64 size_t p_stack_args[2]; void *p_stack_data[2]; char *argp2 = stack; @@ -67,7 +69,7 @@ void ffi_prep_args(char *stack, extended_cif *ecif) ) { *(void **) argp = ecif->rvalue; -#ifdef X86_WIN32 +#ifndef X86_WIN64 /* For fastcall/thiscall this is first register-passed argument. */ if (cabi == FFI_THISCALL || cabi == FFI_FASTCALL) @@ -153,7 +155,7 @@ void ffi_prep_args(char *stack, extended_cif *ecif) memcpy(argp, *p_argv, z); } -#ifdef X86_WIN32 +#ifndef X86_WIN64 /* For thiscall/fastcall convention register-passed arguments are the first two none-floating-point arguments with a size smaller or equal to sizeof (void*). */ @@ -178,7 +180,7 @@ void ffi_prep_args(char *stack, extended_cif *ecif) #endif } -#ifdef X86_WIN32 +#ifndef X86_WIN64 /* We need to move the register-passed arguments for thiscall/fastcall on top of stack, so that those can be moved to registers ecx/edx by call-handler. */ @@ -307,7 +309,7 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) { if (((*ptr)->alignment - 1) & cif->bytes) cif->bytes = ALIGN(cif->bytes, (*ptr)->alignment); - cif->bytes += ALIGN((*ptr)->size, FFI_SIZEOF_ARG); + cif->bytes += (unsigned)ALIGN((*ptr)->size, FFI_SIZEOF_ARG); } #ifdef X86_WIN64 @@ -315,7 +317,12 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) cif->bytes += 4 * sizeof(ffi_arg); #endif - cif->bytes = (cif->bytes + 15) & ~0xF; +#ifndef X86_WIN32 +#ifndef X86_WIN64 + if (cif->abi != FFI_STDCALL && cif->abi != FFI_THISCALL && cif->abi != FFI_FASTCALL) +#endif + cif->bytes = (cif->bytes + 15) & ~0xF; +#endif return FFI_OK; } @@ -324,11 +331,10 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) extern int ffi_call_win64(void (*)(char *, extended_cif *), extended_cif *, unsigned, unsigned, unsigned *, void (*fn)(void)); -#elif defined(X86_WIN32) +#else extern void ffi_call_win32(void (*)(char *, extended_cif *), extended_cif *, unsigned, unsigned, unsigned, unsigned *, void (*fn)(void)); -#else extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *, unsigned, unsigned, unsigned *, void (*fn)(void)); #endif @@ -370,10 +376,17 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) ffi_call_win64(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue, fn); break; -#elif defined(X86_WIN32) +#else +#ifndef X86_WIN32 + case FFI_SYSV: + ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue, + fn); + break; +#else case FFI_SYSV: - case FFI_STDCALL: case FFI_MS_CDECL: +#endif + case FFI_STDCALL: ffi_call_win32(ffi_prep_args, &ecif, cif->abi, cif->bytes, cif->flags, ecif.rvalue, fn); break; @@ -406,11 +419,6 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) ecif.rvalue, fn); } break; -#else - case FFI_SYSV: - ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue, - fn); - break; #endif default: FFI_ASSERT(0); @@ -434,12 +442,15 @@ void FFI_HIDDEN ffi_closure_raw_SYSV (ffi_raw_closure *) #ifdef X86_WIN32 void FFI_HIDDEN ffi_closure_raw_THISCALL (ffi_raw_closure *) __attribute__ ((regparm(1))); +#endif +#ifndef X86_WIN64 void FFI_HIDDEN ffi_closure_STDCALL (ffi_closure *) __attribute__ ((regparm(1))); void FFI_HIDDEN ffi_closure_THISCALL (ffi_closure *) __attribute__ ((regparm(1))); -#endif -#ifdef X86_WIN64 +void FFI_HIDDEN ffi_closure_FASTCALL (ffi_closure *) + __attribute__ ((regparm(1))); +#else void FFI_HIDDEN ffi_closure_win64 (ffi_closure *); #endif @@ -598,7 +609,7 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue, *(unsigned int*) &__tramp[6] = __dis; /* jmp __fun */ \ } -#define FFI_INIT_TRAMPOLINE_THISCALL(TRAMP,FUN,CTX,SIZE) \ +#define FFI_INIT_TRAMPOLINE_RAW_THISCALL(TRAMP,FUN,CTX,SIZE) \ { unsigned char *__tramp = (unsigned char*)(TRAMP); \ unsigned int __fun = (unsigned int)(FUN); \ unsigned int __ctx = (unsigned int)(CTX); \ @@ -625,18 +636,15 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue, *(unsigned short*) &__tramp[50] = (__size + 8); /* ret (__size + 8) */ \ } -#define FFI_INIT_TRAMPOLINE_STDCALL(TRAMP,FUN,CTX,SIZE) \ +#define FFI_INIT_TRAMPOLINE_STDCALL(TRAMP,FUN,CTX) \ { unsigned char *__tramp = (unsigned char*)(TRAMP); \ unsigned int __fun = (unsigned int)(FUN); \ unsigned int __ctx = (unsigned int)(CTX); \ unsigned int __dis = __fun - (__ctx + 10); \ - unsigned short __size = (unsigned short)(SIZE); \ *(unsigned char*) &__tramp[0] = 0xb8; \ *(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \ *(unsigned char *) &__tramp[5] = 0xe8; \ *(unsigned int*) &__tramp[6] = __dis; /* call __fun */ \ - *(unsigned char *) &__tramp[10] = 0xc2; \ - *(unsigned short*) &__tramp[11] = __size; /* ret __size */ \ } /* the cif must already be prep'ed */ @@ -666,20 +674,25 @@ ffi_prep_closure_loc (ffi_closure* closure, &ffi_closure_SYSV, (void*)codeloc); } -#ifdef X86_WIN32 + else if (cif->abi == FFI_FASTCALL) + { + FFI_INIT_TRAMPOLINE_STDCALL (&closure->tramp[0], + &ffi_closure_FASTCALL, + (void*)codeloc); + } else if (cif->abi == FFI_THISCALL) { - FFI_INIT_TRAMPOLINE_THISCALL (&closure->tramp[0], - &ffi_closure_THISCALL, - (void*)codeloc, - cif->bytes); + FFI_INIT_TRAMPOLINE_STDCALL (&closure->tramp[0], + &ffi_closure_THISCALL, + (void*)codeloc); } else if (cif->abi == FFI_STDCALL) { FFI_INIT_TRAMPOLINE_STDCALL (&closure->tramp[0], &ffi_closure_STDCALL, - (void*)codeloc, cif->bytes); + (void*)codeloc); } +#ifdef X86_WIN32 else if (cif->abi == FFI_MS_CDECL) { FFI_INIT_TRAMPOLINE (&closure->tramp[0], @@ -713,12 +726,12 @@ ffi_prep_raw_closure_loc (ffi_raw_closure* closure, { int i; - if (cif->abi != FFI_SYSV) { + if (cif->abi != FFI_SYSV #ifdef X86_WIN32 - if (cif->abi != FFI_THISCALL) + && cif->abi != FFI_THISCALL #endif + ) return FFI_BAD_ABI; - } /* we currently don't support certain kinds of arguments for raw closures. This should be implemented by a separate assembly @@ -741,8 +754,7 @@ ffi_prep_raw_closure_loc (ffi_raw_closure* closure, } else if (cif->abi == FFI_THISCALL) { - FFI_INIT_TRAMPOLINE_THISCALL (&closure->tramp[0], &ffi_closure_raw_THISCALL, - codeloc, cif->bytes); + FFI_INIT_TRAMPOLINE_RAW_THISCALL (&closure->tramp[0], &ffi_closure_raw_THISCALL, codeloc, cif->bytes); } #endif closure->cif = cif; @@ -787,10 +799,17 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue) switch (cif->abi) { -#ifdef X86_WIN32 +#ifndef X86_WIN32 + case FFI_SYSV: + ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags, + ecif.rvalue, fn); + break; +#else case FFI_SYSV: - case FFI_STDCALL: case FFI_MS_CDECL: +#endif +#ifndef X86_WIN64 + case FFI_STDCALL: ffi_call_win32(ffi_prep_args_raw, &ecif, cif->abi, cif->bytes, cif->flags, ecif.rvalue, fn); break; @@ -823,11 +842,6 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue) ecif.rvalue, fn); } break; -#else - case FFI_SYSV: - ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags, - ecif.rvalue, fn); - break; #endif default: FFI_ASSERT(0); diff --git a/Modules/_ctypes/libffi/src/x86/ffi64.c b/Modules/_ctypes/libffi/src/x86/ffi64.c index 2014af24c655..5a5e04383548 100644 --- a/Modules/_ctypes/libffi/src/x86/ffi64.c +++ b/Modules/_ctypes/libffi/src/x86/ffi64.c @@ -3,8 +3,8 @@ Copyright (c) 2011 Anthony Green Copyright (c) 2008, 2010 Red Hat, Inc. Copyright (c) 2002, 2007 Bo Thorsen - - x86-64 Foreign Function Interface + + x86-64 Foreign Function Interface Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the @@ -39,6 +39,7 @@ #define MAX_SSE_REGS 8 #if defined(__INTEL_COMPILER) +#include "xmmintrin.h" #define UINT128 __m128 #else #if defined(__SUNPRO_C) @@ -60,7 +61,7 @@ struct register_args { /* Registers for argument passing. */ UINT64 gpr[MAX_GPR_REGS]; - union big_int_union sse[MAX_SSE_REGS]; + union big_int_union sse[MAX_SSE_REGS]; }; extern void ffi_call_unix64 (void *args, unsigned long bytes, unsigned flags, @@ -151,7 +152,7 @@ merge_classes (enum x86_64_reg_class class1, enum x86_64_reg_class class2) See the x86-64 PS ABI for details. */ -static int +static size_t classify_argument (ffi_type *type, enum x86_64_reg_class classes[], size_t byte_offset) { @@ -167,7 +168,7 @@ classify_argument (ffi_type *type, enum x86_64_reg_class classes[], case FFI_TYPE_SINT64: case FFI_TYPE_POINTER: { - int size = byte_offset + type->size; + size_t size = byte_offset + type->size; if (size <= 4) { @@ -202,15 +203,17 @@ classify_argument (ffi_type *type, enum x86_64_reg_class classes[], case FFI_TYPE_DOUBLE: classes[0] = X86_64_SSEDF_CLASS; return 1; +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE case FFI_TYPE_LONGDOUBLE: classes[0] = X86_64_X87_CLASS; classes[1] = X86_64_X87UP_CLASS; return 2; +#endif case FFI_TYPE_STRUCT: { - const int UNITS_PER_WORD = 8; - int words = (type->size + UNITS_PER_WORD - 1) / UNITS_PER_WORD; - ffi_type **ptr; + const size_t UNITS_PER_WORD = 8; + size_t words = (type->size + UNITS_PER_WORD - 1) / UNITS_PER_WORD; + ffi_type **ptr; int i; enum x86_64_reg_class subclasses[MAX_CLASSES]; @@ -232,7 +235,7 @@ classify_argument (ffi_type *type, enum x86_64_reg_class classes[], /* Merge the fields of structure. */ for (ptr = type->elements; *ptr != NULL; ptr++) { - int num; + size_t num; byte_offset = ALIGN (byte_offset, (*ptr)->alignment); @@ -241,7 +244,7 @@ classify_argument (ffi_type *type, enum x86_64_reg_class classes[], return 0; for (i = 0; i < num; i++) { - int pos = byte_offset / 8; + size_t pos = byte_offset / 8; classes[i + pos] = merge_classes (subclasses[i], classes[i + pos]); } @@ -305,11 +308,12 @@ classify_argument (ffi_type *type, enum x86_64_reg_class classes[], class. Return zero iff parameter should be passed in memory, otherwise the number of registers. */ -static int +static size_t examine_argument (ffi_type *type, enum x86_64_reg_class classes[MAX_CLASSES], _Bool in_return, int *pngpr, int *pnsse) { - int i, n, ngpr, nsse; + size_t n; + int i, ngpr, nsse; n = classify_argument (type, classes, 0); if (n == 0) @@ -350,9 +354,9 @@ examine_argument (ffi_type *type, enum x86_64_reg_class classes[MAX_CLASSES], ffi_status ffi_prep_cif_machdep (ffi_cif *cif) { - int gprcount, ssecount, i, avn, n, ngpr, nsse, flags; + int gprcount, ssecount, i, avn, ngpr, nsse, flags; enum x86_64_reg_class classes[MAX_CLASSES]; - size_t bytes; + size_t bytes, n; gprcount = ssecount = 0; @@ -410,7 +414,7 @@ ffi_prep_cif_machdep (ffi_cif *cif) if (ssecount) flags |= 1 << 11; cif->flags = flags; - cif->bytes = ALIGN (bytes, 8); + cif->bytes = (unsigned)ALIGN (bytes, 8); return FFI_OK; } @@ -453,8 +457,7 @@ ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) for (i = 0; i < avn; ++i) { - size_t size = arg_types[i]->size; - int n; + size_t n, size = arg_types[i]->size; n = examine_argument (arg_types[i], classes, 0, &ngpr, &nsse); if (n == 0 @@ -583,7 +586,7 @@ ffi_closure_unix64_inner(ffi_closure *closure, void *rvalue, if (ret != FFI_TYPE_VOID) { enum x86_64_reg_class classes[MAX_CLASSES]; - int n = examine_argument (cif->rtype, classes, 1, &ngpr, &nsse); + size_t n = examine_argument (cif->rtype, classes, 1, &ngpr, &nsse); if (n == 0) { /* The return value goes in memory. Arrange for the closure @@ -606,11 +609,11 @@ ffi_closure_unix64_inner(ffi_closure *closure, void *rvalue, avn = cif->nargs; arg_types = cif->arg_types; - + for (i = 0; i < avn; ++i) { enum x86_64_reg_class classes[MAX_CLASSES]; - int n; + size_t n; n = examine_argument (arg_types[i], classes, 0, &ngpr, &nsse); if (n == 0 diff --git a/Modules/_ctypes/libffi/src/x86/ffitarget.h b/Modules/_ctypes/libffi/src/x86/ffitarget.h index 46f294cea723..b2afe9112372 100644 --- a/Modules/_ctypes/libffi/src/x86/ffitarget.h +++ b/Modules/_ctypes/libffi/src/x86/ffitarget.h @@ -98,6 +98,9 @@ typedef enum ffi_abi { /* ---- Intel x86 and AMD x86-64 - */ FFI_SYSV, FFI_UNIX64, /* Unix variants all use the same ABI for x86-64 */ + FFI_THISCALL, + FFI_FASTCALL, + FFI_STDCALL, FFI_LAST_ABI, #if defined(__i386__) || defined(__i386) FFI_DEFAULT_ABI = FFI_SYSV diff --git a/Modules/_ctypes/libffi/src/x86/freebsd.S b/Modules/_ctypes/libffi/src/x86/freebsd.S index afde513164e4..97e0b4eb81bc 100644 --- a/Modules/_ctypes/libffi/src/x86/freebsd.S +++ b/Modules/_ctypes/libffi/src/x86/freebsd.S @@ -49,6 +49,9 @@ ffi_call_SYSV: movl 16(%ebp),%ecx subl %ecx,%esp + /* Align the stack pointer to 16-bytes */ + andl $0xfffffff0, %esp + movl %esp,%eax /* Place all of the ffi_prep_args in position */ @@ -456,3 +459,5 @@ ffi_closure_raw_SYSV: #endif #endif /* ifndef __x86_64__ */ + + .section .note.GNU-stack,"",%progbits diff --git a/Modules/_ctypes/libffi/src/x86/win32.S b/Modules/_ctypes/libffi/src/x86/win32.S index 24b7bbd04235..daf0e799ca46 100644 --- a/Modules/_ctypes/libffi/src/x86/win32.S +++ b/Modules/_ctypes/libffi/src/x86/win32.S @@ -33,8 +33,13 @@ #include #include +#define CIF_ABI_OFFSET 0 +#define CIF_BYTES_OFFSET 16 + #ifdef _MSC_VER +#define CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) AND NOT 3) + .386 .MODEL FLAT, C @@ -188,14 +193,23 @@ ca_epilogue: ret ffi_call_win32 ENDP -ffi_closure_THISCALL PROC NEAR FORCEFRAME - sub esp, 40 - lea edx, [ebp -24] - mov [ebp - 12], edx /* resp */ - lea edx, [ebp + 12] /* account for stub return address on stack */ - jmp stub +ffi_closure_THISCALL PROC NEAR + ;; Insert the register argument on the stack as the first argument + xchg DWORD PTR [esp+4], ecx + xchg DWORD PTR [esp], ecx + push ecx + jmp ffi_closure_STDCALL ffi_closure_THISCALL ENDP +ffi_closure_FASTCALL PROC NEAR + ;; Insert the register argument on the stack as the first argument + xchg DWORD PTR [esp+4], edx + xchg DWORD PTR [esp], ecx + push edx + push ecx + jmp ffi_closure_STDCALL +ffi_closure_FASTCALL ENDP + ffi_closure_SYSV PROC NEAR FORCEFRAME ;; the ffi_closure ctx is passed in eax by the trampoline. @@ -464,8 +478,23 @@ cd_retlongdouble: jmp cd_epilogue cd_epilogue: - ;; Epilogue code is autogenerated. - ret + mov esp, ebp + pop ebp + pop ecx + pop edx + mov ecx, DWORD PTR [ecx + (CLOSURE_CIF_OFFSET-10)] + add esp, DWORD PTR [ecx + CIF_BYTES_OFFSET] + mov ecx, DWORD PTR [ecx + CIF_ABI_OFFSET] + cmp ecx, 3 + je cd_thiscall + cmp ecx, 4 + jne cd_not_fastcall + + add esp, 4 +cd_thiscall: + add esp, 4 +cd_not_fastcall: + jmp edx ffi_closure_STDCALL ENDP _TEXT ENDS @@ -473,15 +502,23 @@ END #else +#define CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3) + +#if defined(SYMBOL_UNDERSCORE) +#define USCORE_SYMBOL(x) _##x +#else +#define USCORE_SYMBOL(x) x +#endif .text # This assumes we are using gas. .balign 16 - .globl _ffi_call_win32 -#ifndef __OS2__ +FFI_HIDDEN(ffi_call_win32) + .globl USCORE_SYMBOL(ffi_call_win32) +#if defined(X86_WIN32) && !defined(__OS2__) .def _ffi_call_win32; .scl 2; .type 32; .endef #endif -_ffi_call_win32: +USCORE_SYMBOL(ffi_call_win32): .LFB1: pushl %ebp .LCFI0: @@ -542,31 +579,32 @@ _ffi_call_win32: call 1f # Do not insert anything here between the call and the jump table. .Lstore_table: - .long .Lnoretval /* FFI_TYPE_VOID */ - .long .Lretint /* FFI_TYPE_INT */ - .long .Lretfloat /* FFI_TYPE_FLOAT */ - .long .Lretdouble /* FFI_TYPE_DOUBLE */ - .long .Lretlongdouble /* FFI_TYPE_LONGDOUBLE */ - .long .Lretuint8 /* FFI_TYPE_UINT8 */ - .long .Lretsint8 /* FFI_TYPE_SINT8 */ - .long .Lretuint16 /* FFI_TYPE_UINT16 */ - .long .Lretsint16 /* FFI_TYPE_SINT16 */ - .long .Lretint /* FFI_TYPE_UINT32 */ - .long .Lretint /* FFI_TYPE_SINT32 */ - .long .Lretint64 /* FFI_TYPE_UINT64 */ - .long .Lretint64 /* FFI_TYPE_SINT64 */ - .long .Lretstruct /* FFI_TYPE_STRUCT */ - .long .Lretint /* FFI_TYPE_POINTER */ - .long .Lretstruct1b /* FFI_TYPE_SMALL_STRUCT_1B */ - .long .Lretstruct2b /* FFI_TYPE_SMALL_STRUCT_2B */ - .long .Lretstruct4b /* FFI_TYPE_SMALL_STRUCT_4B */ - .long .Lretstruct /* FFI_TYPE_MS_STRUCT */ + .long .Lnoretval-.Lstore_table /* FFI_TYPE_VOID */ + .long .Lretint-.Lstore_table /* FFI_TYPE_INT */ + .long .Lretfloat-.Lstore_table /* FFI_TYPE_FLOAT */ + .long .Lretdouble-.Lstore_table /* FFI_TYPE_DOUBLE */ + .long .Lretlongdouble-.Lstore_table /* FFI_TYPE_LONGDOUBLE */ + .long .Lretuint8-.Lstore_table /* FFI_TYPE_UINT8 */ + .long .Lretsint8-.Lstore_table /* FFI_TYPE_SINT8 */ + .long .Lretuint16-.Lstore_table /* FFI_TYPE_UINT16 */ + .long .Lretsint16-.Lstore_table /* FFI_TYPE_SINT16 */ + .long .Lretint-.Lstore_table /* FFI_TYPE_UINT32 */ + .long .Lretint-.Lstore_table /* FFI_TYPE_SINT32 */ + .long .Lretint64-.Lstore_table /* FFI_TYPE_UINT64 */ + .long .Lretint64-.Lstore_table /* FFI_TYPE_SINT64 */ + .long .Lretstruct-.Lstore_table /* FFI_TYPE_STRUCT */ + .long .Lretint-.Lstore_table /* FFI_TYPE_POINTER */ + .long .Lretstruct1b-.Lstore_table /* FFI_TYPE_SMALL_STRUCT_1B */ + .long .Lretstruct2b-.Lstore_table /* FFI_TYPE_SMALL_STRUCT_2B */ + .long .Lretstruct4b-.Lstore_table /* FFI_TYPE_SMALL_STRUCT_4B */ + .long .Lretstruct-.Lstore_table /* FFI_TYPE_MS_STRUCT */ 1: - add %ecx, %ecx - add %ecx, %ecx + shl $2, %ecx + add (%esp),%ecx + mov (%ecx),%ecx add (%esp),%ecx add $4, %esp - jmp *(%ecx) + jmp *%ecx /* Sign/zero extend as appropriate. */ .Lretsint8: @@ -644,27 +682,43 @@ _ffi_call_win32: ret .ffi_call_win32_end: .balign 16 - .globl _ffi_closure_THISCALL -#ifndef __OS2__ +FFI_HIDDEN(ffi_closure_THISCALL) + .globl USCORE_SYMBOL(ffi_closure_THISCALL) +#if defined(X86_WIN32) && !defined(__OS2__) .def _ffi_closure_THISCALL; .scl 2; .type 32; .endef #endif -_ffi_closure_THISCALL: - pushl %ebp - movl %esp, %ebp - subl $40, %esp - leal -24(%ebp), %edx - movl %edx, -12(%ebp) /* resp */ - leal 12(%ebp), %edx /* account for stub return address on stack */ - jmp .stub +USCORE_SYMBOL(ffi_closure_THISCALL): + /* Insert the register argument on the stack as the first argument */ + xchg %ecx, 4(%esp) + xchg %ecx, (%esp) + push %ecx + jmp .ffi_closure_STDCALL_internal + + .balign 16 +FFI_HIDDEN(ffi_closure_FASTCALL) + .globl USCORE_SYMBOL(ffi_closure_FASTCALL) +#if defined(X86_WIN32) && !defined(__OS2__) + .def _ffi_closure_FASTCALL; .scl 2; .type 32; .endef +#endif +USCORE_SYMBOL(ffi_closure_FASTCALL): + /* Insert the register arguments on the stack as the first two arguments */ + xchg %edx, 4(%esp) + xchg %ecx, (%esp) + push %edx + push %ecx + jmp .ffi_closure_STDCALL_internal .LFE1: # This assumes we are using gas. .balign 16 - .globl _ffi_closure_SYSV -#ifndef __OS2__ +FFI_HIDDEN(ffi_closure_SYSV) +#if defined(X86_WIN32) + .globl USCORE_SYMBOL(ffi_closure_SYSV) +#if defined(X86_WIN32) && !defined(__OS2__) .def _ffi_closure_SYSV; .scl 2; .type 32; .endef #endif -_ffi_closure_SYSV: +USCORE_SYMBOL(ffi_closure_SYSV): +#endif .LFB3: pushl %ebp .LCFI4: @@ -674,43 +728,54 @@ _ffi_closure_SYSV: leal -24(%ebp), %edx movl %edx, -12(%ebp) /* resp */ leal 8(%ebp), %edx -.stub: movl %edx, 4(%esp) /* args = __builtin_dwarf_cfa () */ leal -12(%ebp), %edx movl %edx, (%esp) /* &resp */ - call _ffi_closure_SYSV_inner +#if defined(HAVE_HIDDEN_VISIBILITY_ATTRIBUTE) || !defined(__PIC__) + call USCORE_SYMBOL(ffi_closure_SYSV_inner) +#elif defined(X86_DARWIN) + calll L_ffi_closure_SYSV_inner$stub +#else + movl %ebx, 8(%esp) + call 1f +1: popl %ebx + addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx + call ffi_closure_SYSV_inner@PLT + movl 8(%esp), %ebx +#endif movl -12(%ebp), %ecx 0: call 1f # Do not insert anything here between the call and the jump table. .Lcls_store_table: - .long .Lcls_noretval /* FFI_TYPE_VOID */ - .long .Lcls_retint /* FFI_TYPE_INT */ - .long .Lcls_retfloat /* FFI_TYPE_FLOAT */ - .long .Lcls_retdouble /* FFI_TYPE_DOUBLE */ - .long .Lcls_retldouble /* FFI_TYPE_LONGDOUBLE */ - .long .Lcls_retuint8 /* FFI_TYPE_UINT8 */ - .long .Lcls_retsint8 /* FFI_TYPE_SINT8 */ - .long .Lcls_retuint16 /* FFI_TYPE_UINT16 */ - .long .Lcls_retsint16 /* FFI_TYPE_SINT16 */ - .long .Lcls_retint /* FFI_TYPE_UINT32 */ - .long .Lcls_retint /* FFI_TYPE_SINT32 */ - .long .Lcls_retllong /* FFI_TYPE_UINT64 */ - .long .Lcls_retllong /* FFI_TYPE_SINT64 */ - .long .Lcls_retstruct /* FFI_TYPE_STRUCT */ - .long .Lcls_retint /* FFI_TYPE_POINTER */ - .long .Lcls_retstruct1 /* FFI_TYPE_SMALL_STRUCT_1B */ - .long .Lcls_retstruct2 /* FFI_TYPE_SMALL_STRUCT_2B */ - .long .Lcls_retstruct4 /* FFI_TYPE_SMALL_STRUCT_4B */ - .long .Lcls_retmsstruct /* FFI_TYPE_MS_STRUCT */ + .long .Lcls_noretval-.Lcls_store_table /* FFI_TYPE_VOID */ + .long .Lcls_retint-.Lcls_store_table /* FFI_TYPE_INT */ + .long .Lcls_retfloat-.Lcls_store_table /* FFI_TYPE_FLOAT */ + .long .Lcls_retdouble-.Lcls_store_table /* FFI_TYPE_DOUBLE */ + .long .Lcls_retldouble-.Lcls_store_table /* FFI_TYPE_LONGDOUBLE */ + .long .Lcls_retuint8-.Lcls_store_table /* FFI_TYPE_UINT8 */ + .long .Lcls_retsint8-.Lcls_store_table /* FFI_TYPE_SINT8 */ + .long .Lcls_retuint16-.Lcls_store_table /* FFI_TYPE_UINT16 */ + .long .Lcls_retsint16-.Lcls_store_table /* FFI_TYPE_SINT16 */ + .long .Lcls_retint-.Lcls_store_table /* FFI_TYPE_UINT32 */ + .long .Lcls_retint-.Lcls_store_table /* FFI_TYPE_SINT32 */ + .long .Lcls_retllong-.Lcls_store_table /* FFI_TYPE_UINT64 */ + .long .Lcls_retllong-.Lcls_store_table /* FFI_TYPE_SINT64 */ + .long .Lcls_retstruct-.Lcls_store_table /* FFI_TYPE_STRUCT */ + .long .Lcls_retint-.Lcls_store_table /* FFI_TYPE_POINTER */ + .long .Lcls_retstruct1-.Lcls_store_table /* FFI_TYPE_SMALL_STRUCT_1B */ + .long .Lcls_retstruct2-.Lcls_store_table /* FFI_TYPE_SMALL_STRUCT_2B */ + .long .Lcls_retstruct4-.Lcls_store_table /* FFI_TYPE_SMALL_STRUCT_4B */ + .long .Lcls_retmsstruct-.Lcls_store_table /* FFI_TYPE_MS_STRUCT */ 1: - add %eax, %eax - add %eax, %eax + shl $2, %eax + add (%esp),%eax + mov (%eax),%eax add (%esp),%eax add $4, %esp - jmp *(%eax) + jmp *%eax /* Sign/zero extend as appropriate. */ .Lcls_retsint8: @@ -788,12 +853,15 @@ _ffi_closure_SYSV: #define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4) #define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4) #define CIF_FLAGS_OFFSET 20 + +#ifdef X86_WIN32 .balign 16 - .globl _ffi_closure_raw_THISCALL -#ifndef __OS2__ +FFI_HIDDEN(ffi_closure_raw_THISCALL) + .globl USCORE_SYMBOL(ffi_closure_raw_THISCALL) +#if defined(X86_WIN32) && !defined(__OS2__) .def _ffi_closure_raw_THISCALL; .scl 2; .type 32; .endef #endif -_ffi_closure_raw_THISCALL: +USCORE_SYMBOL(ffi_closure_raw_THISCALL): pushl %ebp movl %esp, %ebp pushl %esi @@ -803,13 +871,17 @@ _ffi_closure_raw_THISCALL: movl %edx, 12(%esp) /* user_data */ leal 12(%ebp), %edx /* __builtin_dwarf_cfa () */ jmp .stubraw +#endif /* X86_WIN32 */ + # This assumes we are using gas. .balign 16 - .globl _ffi_closure_raw_SYSV -#ifndef __OS2__ +#if defined(X86_WIN32) + .globl USCORE_SYMBOL(ffi_closure_raw_SYSV) +#if defined(X86_WIN32) && !defined(__OS2__) .def _ffi_closure_raw_SYSV; .scl 2; .type 32; .endef #endif -_ffi_closure_raw_SYSV: +USCORE_SYMBOL(ffi_closure_raw_SYSV): +#endif /* defined(X86_WIN32) */ .LFB4: pushl %ebp .LCFI6: @@ -833,31 +905,32 @@ _ffi_closure_raw_SYSV: call 1f # Do not insert anything here between the call and the jump table. .Lrcls_store_table: - .long .Lrcls_noretval /* FFI_TYPE_VOID */ - .long .Lrcls_retint /* FFI_TYPE_INT */ - .long .Lrcls_retfloat /* FFI_TYPE_FLOAT */ - .long .Lrcls_retdouble /* FFI_TYPE_DOUBLE */ - .long .Lrcls_retldouble /* FFI_TYPE_LONGDOUBLE */ - .long .Lrcls_retuint8 /* FFI_TYPE_UINT8 */ - .long .Lrcls_retsint8 /* FFI_TYPE_SINT8 */ - .long .Lrcls_retuint16 /* FFI_TYPE_UINT16 */ - .long .Lrcls_retsint16 /* FFI_TYPE_SINT16 */ - .long .Lrcls_retint /* FFI_TYPE_UINT32 */ - .long .Lrcls_retint /* FFI_TYPE_SINT32 */ - .long .Lrcls_retllong /* FFI_TYPE_UINT64 */ - .long .Lrcls_retllong /* FFI_TYPE_SINT64 */ - .long .Lrcls_retstruct /* FFI_TYPE_STRUCT */ - .long .Lrcls_retint /* FFI_TYPE_POINTER */ - .long .Lrcls_retstruct1 /* FFI_TYPE_SMALL_STRUCT_1B */ - .long .Lrcls_retstruct2 /* FFI_TYPE_SMALL_STRUCT_2B */ - .long .Lrcls_retstruct4 /* FFI_TYPE_SMALL_STRUCT_4B */ - .long .Lrcls_retstruct /* FFI_TYPE_MS_STRUCT */ + .long .Lrcls_noretval-.Lrcls_store_table /* FFI_TYPE_VOID */ + .long .Lrcls_retint-.Lrcls_store_table /* FFI_TYPE_INT */ + .long .Lrcls_retfloat-.Lrcls_store_table /* FFI_TYPE_FLOAT */ + .long .Lrcls_retdouble-.Lrcls_store_table /* FFI_TYPE_DOUBLE */ + .long .Lrcls_retldouble-.Lrcls_store_table /* FFI_TYPE_LONGDOUBLE */ + .long .Lrcls_retuint8-.Lrcls_store_table /* FFI_TYPE_UINT8 */ + .long .Lrcls_retsint8-.Lrcls_store_table /* FFI_TYPE_SINT8 */ + .long .Lrcls_retuint16-.Lrcls_store_table /* FFI_TYPE_UINT16 */ + .long .Lrcls_retsint16-.Lrcls_store_table /* FFI_TYPE_SINT16 */ + .long .Lrcls_retint-.Lrcls_store_table /* FFI_TYPE_UINT32 */ + .long .Lrcls_retint-.Lrcls_store_table /* FFI_TYPE_SINT32 */ + .long .Lrcls_retllong-.Lrcls_store_table /* FFI_TYPE_UINT64 */ + .long .Lrcls_retllong-.Lrcls_store_table /* FFI_TYPE_SINT64 */ + .long .Lrcls_retstruct-.Lrcls_store_table /* FFI_TYPE_STRUCT */ + .long .Lrcls_retint-.Lrcls_store_table /* FFI_TYPE_POINTER */ + .long .Lrcls_retstruct1-.Lrcls_store_table /* FFI_TYPE_SMALL_STRUCT_1B */ + .long .Lrcls_retstruct2-.Lrcls_store_table /* FFI_TYPE_SMALL_STRUCT_2B */ + .long .Lrcls_retstruct4-.Lrcls_store_table /* FFI_TYPE_SMALL_STRUCT_4B */ + .long .Lrcls_retstruct-.Lrcls_store_table /* FFI_TYPE_MS_STRUCT */ 1: - add %eax, %eax - add %eax, %eax + shl $2, %eax + add (%esp),%eax + mov (%eax),%eax add (%esp),%eax add $4, %esp - jmp *(%eax) + jmp *%eax /* Sign/zero extend as appropriate. */ .Lrcls_retsint8: @@ -925,11 +998,13 @@ _ffi_closure_raw_SYSV: # This assumes we are using gas. .balign 16 - .globl _ffi_closure_STDCALL -#ifndef __OS2__ +FFI_HIDDEN(ffi_closure_STDCALL) + .globl USCORE_SYMBOL(ffi_closure_STDCALL) +#if defined(X86_WIN32) && !defined(__OS2__) .def _ffi_closure_STDCALL; .scl 2; .type 32; .endef #endif -_ffi_closure_STDCALL: +USCORE_SYMBOL(ffi_closure_STDCALL): +.ffi_closure_STDCALL_internal: .LFB5: pushl %ebp .LCFI9: @@ -942,36 +1017,48 @@ _ffi_closure_STDCALL: movl %edx, 4(%esp) /* args */ leal -12(%ebp), %edx movl %edx, (%esp) /* &resp */ - call _ffi_closure_SYSV_inner +#if defined(HAVE_HIDDEN_VISIBILITY_ATTRIBUTE) || !defined(__PIC__) + call USCORE_SYMBOL(ffi_closure_SYSV_inner) +#elif defined(X86_DARWIN) + calll L_ffi_closure_SYSV_inner$stub +#else + movl %ebx, 8(%esp) + call 1f +1: popl %ebx + addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx + call ffi_closure_SYSV_inner@PLT + movl 8(%esp), %ebx +#endif movl -12(%ebp), %ecx 0: call 1f # Do not insert anything here between the call and the jump table. .Lscls_store_table: - .long .Lscls_noretval /* FFI_TYPE_VOID */ - .long .Lscls_retint /* FFI_TYPE_INT */ - .long .Lscls_retfloat /* FFI_TYPE_FLOAT */ - .long .Lscls_retdouble /* FFI_TYPE_DOUBLE */ - .long .Lscls_retldouble /* FFI_TYPE_LONGDOUBLE */ - .long .Lscls_retuint8 /* FFI_TYPE_UINT8 */ - .long .Lscls_retsint8 /* FFI_TYPE_SINT8 */ - .long .Lscls_retuint16 /* FFI_TYPE_UINT16 */ - .long .Lscls_retsint16 /* FFI_TYPE_SINT16 */ - .long .Lscls_retint /* FFI_TYPE_UINT32 */ - .long .Lscls_retint /* FFI_TYPE_SINT32 */ - .long .Lscls_retllong /* FFI_TYPE_UINT64 */ - .long .Lscls_retllong /* FFI_TYPE_SINT64 */ - .long .Lscls_retstruct /* FFI_TYPE_STRUCT */ - .long .Lscls_retint /* FFI_TYPE_POINTER */ - .long .Lscls_retstruct1 /* FFI_TYPE_SMALL_STRUCT_1B */ - .long .Lscls_retstruct2 /* FFI_TYPE_SMALL_STRUCT_2B */ - .long .Lscls_retstruct4 /* FFI_TYPE_SMALL_STRUCT_4B */ + .long .Lscls_noretval-.Lscls_store_table /* FFI_TYPE_VOID */ + .long .Lscls_retint-.Lscls_store_table /* FFI_TYPE_INT */ + .long .Lscls_retfloat-.Lscls_store_table /* FFI_TYPE_FLOAT */ + .long .Lscls_retdouble-.Lscls_store_table /* FFI_TYPE_DOUBLE */ + .long .Lscls_retldouble-.Lscls_store_table /* FFI_TYPE_LONGDOUBLE */ + .long .Lscls_retuint8-.Lscls_store_table /* FFI_TYPE_UINT8 */ + .long .Lscls_retsint8-.Lscls_store_table /* FFI_TYPE_SINT8 */ + .long .Lscls_retuint16-.Lscls_store_table /* FFI_TYPE_UINT16 */ + .long .Lscls_retsint16-.Lscls_store_table /* FFI_TYPE_SINT16 */ + .long .Lscls_retint-.Lscls_store_table /* FFI_TYPE_UINT32 */ + .long .Lscls_retint-.Lscls_store_table /* FFI_TYPE_SINT32 */ + .long .Lscls_retllong-.Lscls_store_table /* FFI_TYPE_UINT64 */ + .long .Lscls_retllong-.Lscls_store_table /* FFI_TYPE_SINT64 */ + .long .Lscls_retstruct-.Lscls_store_table /* FFI_TYPE_STRUCT */ + .long .Lscls_retint-.Lscls_store_table /* FFI_TYPE_POINTER */ + .long .Lscls_retstruct1-.Lscls_store_table /* FFI_TYPE_SMALL_STRUCT_1B */ + .long .Lscls_retstruct2-.Lscls_store_table /* FFI_TYPE_SMALL_STRUCT_2B */ + .long .Lscls_retstruct4-.Lscls_store_table /* FFI_TYPE_SMALL_STRUCT_4B */ 1: - add %eax, %eax - add %eax, %eax + shl $2, %eax + add (%esp),%eax + mov (%eax),%eax add (%esp),%eax add $4, %esp - jmp *(%eax) + jmp *%eax /* Sign/zero extend as appropriate. */ .Lscls_retsint8: @@ -1030,11 +1117,30 @@ _ffi_closure_STDCALL: .Lscls_epilogue: movl %ebp, %esp popl %ebp - ret + popl %ecx + popl %edx + movl (CLOSURE_CIF_OFFSET-10)(%ecx), %ecx + addl CIF_BYTES_OFFSET(%ecx), %esp + movl CIF_ABI_OFFSET(%ecx), %ecx + cmpl $3, %ecx /* FFI_THISCALL */ + je 1f + cmpl $4, %ecx /* FFI_FASTCALL */ + jne 2f + + addl $4, %esp +1: addl $4, %esp +2: jmp *%edx .ffi_closure_STDCALL_end: .LFE5: -#ifndef __OS2__ +#if defined(X86_DARWIN) +.section __IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5 +L_ffi_closure_SYSV_inner$stub: + .indirect_symbol _ffi_closure_SYSV_inner + hlt ; hlt ; hlt ; hlt ; hlt +#endif + +#if defined(X86_WIN32) && !defined(__OS2__) .section .eh_frame,"w" #endif .Lframe1: @@ -1094,7 +1200,6 @@ _ffi_closure_STDCALL: .align 4 .LEFDE1: - .LSFDE3: .long .LEFDE3-.LASFDE3 /* FDE Length */ .LASFDE3: diff --git a/Modules/_ctypes/libffi/stamp-h.in b/Modules/_ctypes/libffi/stamp-h.in deleted file mode 100644 index 9788f70238c9..000000000000 --- a/Modules/_ctypes/libffi/stamp-h.in +++ /dev/null @@ -1 +0,0 @@ -timestamp diff --git a/Modules/_ctypes/libffi/testsuite/Makefile.am b/Modules/_ctypes/libffi/testsuite/Makefile.am index edc6e61ae4db..da10465d283c 100644 --- a/Modules/_ctypes/libffi/testsuite/Makefile.am +++ b/Modules/_ctypes/libffi/testsuite/Makefile.am @@ -2,17 +2,6 @@ AUTOMAKE_OPTIONS = foreign dejagnu -# Setup the testing framework, if you have one -EXPECT = `if [ -f $(top_builddir)/../expect/expect ] ; then \ - echo $(top_builddir)/../expect/expect ; \ - else echo expect ; fi` - -RUNTEST = `if [ -f $(top_srcdir)/../dejagnu/runtest ] ; then \ - echo $(top_srcdir)/../dejagnu/runtest ; \ - else echo runtest; fi` - -AM_RUNTESTFLAGS = - EXTRA_DEJAGNU_SITE_CONFIG=../local.exp CLEANFILES = *.exe core* *.log *.sum @@ -20,7 +9,7 @@ CLEANFILES = *.exe core* *.log *.sum EXTRA_DIST = config/default.exp libffi.call/cls_19byte.c \ libffi.call/cls_align_longdouble_split.c \ libffi.call/closure_loc_fn0.c libffi.call/cls_schar.c \ -libffi.call/closure_fn1.c libffi.call/many2_win32.c \ +libffi.call/closure_fn1.c \ libffi.call/return_ul.c libffi.call/cls_align_double.c \ libffi.call/return_fl2.c libffi.call/cls_1_1byte.c \ libffi.call/cls_64byte.c libffi.call/nested_struct7.c \ @@ -30,7 +19,7 @@ libffi.call/cls_multi_ushort.c libffi.call/struct3.c \ libffi.call/cls_3byte1.c libffi.call/cls_16byte.c \ libffi.call/struct8.c libffi.call/nested_struct8.c \ libffi.call/cls_multi_sshort.c libffi.call/cls_3byte2.c \ -libffi.call/fastthis2_win32.c libffi.call/cls_pointer.c \ +libffi.call/cls_pointer.c \ libffi.call/err_bad_typedef.c libffi.call/cls_4_1byte.c \ libffi.call/cls_9byte2.c libffi.call/cls_multi_schar.c \ libffi.call/stret_medium2.c libffi.call/cls_5_1_byte.c \ @@ -46,16 +35,16 @@ libffi.call/cls_align_longdouble_split2.c libffi.call/return_dbl2.c \ libffi.call/return_fl3.c libffi.call/stret_medium.c \ libffi.call/nested_struct6.c libffi.call/closure_fn3.c \ libffi.call/float3.c libffi.call/many2.c \ -libffi.call/closure_stdcall.c libffi.call/cls_align_uint16.c \ +libffi.call/closure_simple.c libffi.call/cls_align_uint16.c \ libffi.call/cls_9byte1.c libffi.call/closure_fn6.c \ libffi.call/cls_double_va.c libffi.call/cls_align_pointer.c \ libffi.call/cls_align_longdouble.c libffi.call/closure_fn2.c \ -libffi.call/cls_sshort.c libffi.call/many_win32.c \ +libffi.call/cls_sshort.c \ libffi.call/nested_struct.c libffi.call/cls_20byte.c \ libffi.call/cls_longdouble.c libffi.call/cls_multi_uchar.c \ -libffi.call/return_uc.c libffi.call/closure_thiscall.c \ +libffi.call/return_uc.c \ libffi.call/cls_18byte.c libffi.call/cls_8byte.c \ -libffi.call/promotion.c libffi.call/struct1_win32.c \ +libffi.call/promotion.c \ libffi.call/return_dbl.c libffi.call/cls_24byte.c \ libffi.call/struct4.c libffi.call/cls_6byte.c \ libffi.call/cls_align_uint32.c libffi.call/float.c \ @@ -63,7 +52,7 @@ libffi.call/float1.c libffi.call/float_va.c libffi.call/negint.c \ libffi.call/return_dbl1.c libffi.call/cls_3_1byte.c \ libffi.call/cls_align_float.c libffi.call/return_fl1.c \ libffi.call/nested_struct10.c libffi.call/nested_struct5.c \ -libffi.call/fastthis1_win32.c libffi.call/cls_align_sint64.c \ +libffi.call/cls_align_sint64.c \ libffi.call/stret_large2.c libffi.call/return_sl.c \ libffi.call/closure_fn0.c libffi.call/cls_5byte.c \ libffi.call/cls_2byte.c libffi.call/float2.c \ @@ -75,20 +64,22 @@ libffi.call/cls_float.c libffi.call/cls_pointer_stack.c \ libffi.call/pyobjc-tc.c libffi.call/cls_multi_ushortchar.c \ libffi.call/struct1.c libffi.call/nested_struct9.c \ libffi.call/huge_struct.c libffi.call/problem1.c \ -libffi.call/float4.c libffi.call/fastthis3_win32.c \ -libffi.call/return_ldl.c libffi.call/strlen2_win32.c \ -libffi.call/closure_fn5.c libffi.call/struct2_win32.c \ +libffi.call/float4.c \ +libffi.call/return_ldl.c \ +libffi.call/closure_fn5.c \ libffi.call/struct6.c libffi.call/return_ll.c libffi.call/struct9.c \ libffi.call/return_sc.c libffi.call/struct7.c \ libffi.call/cls_align_uint64.c libffi.call/cls_4byte.c \ -libffi.call/strlen_win32.c libffi.call/cls_6_1_byte.c \ -libffi.call/cls_7_1_byte.c libffi.special/unwindtest.cc \ -libffi.special/special.exp libffi.special/unwindtest_ffi_call.cc \ -libffi.special/ffitestcxx.h lib/wrapper.exp lib/target-libpath.exp \ +libffi.call/cls_6_1_byte.c \ +libffi.call/cls_7_1_byte.c libffi.call/unwindtest.cc \ +libffi.call/unwindtest_ffi_call.cc \ +lib/wrapper.exp lib/target-libpath.exp \ lib/libffi.exp libffi.call/cls_struct_va1.c \ libffi.call/cls_uchar_va.c libffi.call/cls_uint_va.c \ libffi.call/cls_ulong_va.c libffi.call/cls_ushort_va.c \ libffi.call/nested_struct11.c libffi.call/uninitialized.c \ libffi.call/va_1.c libffi.call/va_struct1.c libffi.call/va_struct2.c \ -libffi.call/va_struct3.c - +libffi.call/va_struct3.c \ +libffi.call/strlen2.c \ +libffi.call/strlen3.c \ +libffi.call/strlen4.c diff --git a/Modules/_ctypes/libffi/testsuite/Makefile.in b/Modules/_ctypes/libffi/testsuite/Makefile.in index a3ba066dfa4b..99e226c409ad 100644 --- a/Modules/_ctypes/libffi/testsuite/Makefile.in +++ b/Modules/_ctypes/libffi/testsuite/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.12.2 from Makefile.am. +# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2012 Free Software Foundation, Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -14,23 +14,51 @@ @SET_MAKE@ VPATH = @srcdir@ -am__make_dryrun = \ - { \ - am__dry=no; \ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ - echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ - | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ - *) \ - for am__flg in $$MAKEFLAGS; do \ - case $$am__flg in \ - *=*|--*) ;; \ - *n*) am__dry=yes; break;; \ - esac; \ - done;; \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ esac; \ - test $$am__dry = yes; \ - } + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -51,7 +79,7 @@ build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = testsuite -DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/asmcfi.m4 \ $(top_srcdir)/m4/ax_append_flag.m4 \ @@ -73,6 +101,18 @@ mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/fficonfig.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ @@ -80,14 +120,18 @@ am__can_run_installinfo = \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DEJATOOL = $(PACKAGE) RUNTESTDEFAULTFLAGS = --tool $$tool --srcdir $$srcdir +EXPECT = expect +RUNTEST = runtest DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LTLDFLAGS = @AM_LTLDFLAGS@ -AM_RUNTESTFLAGS = +AM_RUNTESTFLAGS = @AM_RUNTESTFLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ @@ -101,6 +145,10 @@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ @@ -116,6 +164,7 @@ FFI_EXEC_TRAMPOLINE_TABLE = @FFI_EXEC_TRAMPOLINE_TABLE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_LONG_DOUBLE = @HAVE_LONG_DOUBLE@ +HAVE_LONG_DOUBLE_VARIANT = @HAVE_LONG_DOUBLE_VARIANT@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ @@ -162,6 +211,7 @@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ @@ -217,22 +267,12 @@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = foreign dejagnu - -# Setup the testing framework, if you have one -EXPECT = `if [ -f $(top_builddir)/../expect/expect ] ; then \ - echo $(top_builddir)/../expect/expect ; \ - else echo expect ; fi` - -RUNTEST = `if [ -f $(top_srcdir)/../dejagnu/runtest ] ; then \ - echo $(top_srcdir)/../dejagnu/runtest ; \ - else echo runtest; fi` - EXTRA_DEJAGNU_SITE_CONFIG = ../local.exp CLEANFILES = *.exe core* *.log *.sum EXTRA_DIST = config/default.exp libffi.call/cls_19byte.c \ libffi.call/cls_align_longdouble_split.c \ libffi.call/closure_loc_fn0.c libffi.call/cls_schar.c \ -libffi.call/closure_fn1.c libffi.call/many2_win32.c \ +libffi.call/closure_fn1.c \ libffi.call/return_ul.c libffi.call/cls_align_double.c \ libffi.call/return_fl2.c libffi.call/cls_1_1byte.c \ libffi.call/cls_64byte.c libffi.call/nested_struct7.c \ @@ -242,7 +282,7 @@ libffi.call/cls_multi_ushort.c libffi.call/struct3.c \ libffi.call/cls_3byte1.c libffi.call/cls_16byte.c \ libffi.call/struct8.c libffi.call/nested_struct8.c \ libffi.call/cls_multi_sshort.c libffi.call/cls_3byte2.c \ -libffi.call/fastthis2_win32.c libffi.call/cls_pointer.c \ +libffi.call/cls_pointer.c \ libffi.call/err_bad_typedef.c libffi.call/cls_4_1byte.c \ libffi.call/cls_9byte2.c libffi.call/cls_multi_schar.c \ libffi.call/stret_medium2.c libffi.call/cls_5_1_byte.c \ @@ -258,16 +298,16 @@ libffi.call/cls_align_longdouble_split2.c libffi.call/return_dbl2.c \ libffi.call/return_fl3.c libffi.call/stret_medium.c \ libffi.call/nested_struct6.c libffi.call/closure_fn3.c \ libffi.call/float3.c libffi.call/many2.c \ -libffi.call/closure_stdcall.c libffi.call/cls_align_uint16.c \ +libffi.call/closure_simple.c libffi.call/cls_align_uint16.c \ libffi.call/cls_9byte1.c libffi.call/closure_fn6.c \ libffi.call/cls_double_va.c libffi.call/cls_align_pointer.c \ libffi.call/cls_align_longdouble.c libffi.call/closure_fn2.c \ -libffi.call/cls_sshort.c libffi.call/many_win32.c \ +libffi.call/cls_sshort.c \ libffi.call/nested_struct.c libffi.call/cls_20byte.c \ libffi.call/cls_longdouble.c libffi.call/cls_multi_uchar.c \ -libffi.call/return_uc.c libffi.call/closure_thiscall.c \ +libffi.call/return_uc.c \ libffi.call/cls_18byte.c libffi.call/cls_8byte.c \ -libffi.call/promotion.c libffi.call/struct1_win32.c \ +libffi.call/promotion.c \ libffi.call/return_dbl.c libffi.call/cls_24byte.c \ libffi.call/struct4.c libffi.call/cls_6byte.c \ libffi.call/cls_align_uint32.c libffi.call/float.c \ @@ -275,7 +315,7 @@ libffi.call/float1.c libffi.call/float_va.c libffi.call/negint.c \ libffi.call/return_dbl1.c libffi.call/cls_3_1byte.c \ libffi.call/cls_align_float.c libffi.call/return_fl1.c \ libffi.call/nested_struct10.c libffi.call/nested_struct5.c \ -libffi.call/fastthis1_win32.c libffi.call/cls_align_sint64.c \ +libffi.call/cls_align_sint64.c \ libffi.call/stret_large2.c libffi.call/return_sl.c \ libffi.call/closure_fn0.c libffi.call/cls_5byte.c \ libffi.call/cls_2byte.c libffi.call/float2.c \ @@ -287,22 +327,25 @@ libffi.call/cls_float.c libffi.call/cls_pointer_stack.c \ libffi.call/pyobjc-tc.c libffi.call/cls_multi_ushortchar.c \ libffi.call/struct1.c libffi.call/nested_struct9.c \ libffi.call/huge_struct.c libffi.call/problem1.c \ -libffi.call/float4.c libffi.call/fastthis3_win32.c \ -libffi.call/return_ldl.c libffi.call/strlen2_win32.c \ -libffi.call/closure_fn5.c libffi.call/struct2_win32.c \ +libffi.call/float4.c \ +libffi.call/return_ldl.c \ +libffi.call/closure_fn5.c \ libffi.call/struct6.c libffi.call/return_ll.c libffi.call/struct9.c \ libffi.call/return_sc.c libffi.call/struct7.c \ libffi.call/cls_align_uint64.c libffi.call/cls_4byte.c \ -libffi.call/strlen_win32.c libffi.call/cls_6_1_byte.c \ -libffi.call/cls_7_1_byte.c libffi.special/unwindtest.cc \ -libffi.special/special.exp libffi.special/unwindtest_ffi_call.cc \ -libffi.special/ffitestcxx.h lib/wrapper.exp lib/target-libpath.exp \ +libffi.call/cls_6_1_byte.c \ +libffi.call/cls_7_1_byte.c libffi.call/unwindtest.cc \ +libffi.call/unwindtest_ffi_call.cc \ +lib/wrapper.exp lib/target-libpath.exp \ lib/libffi.exp libffi.call/cls_struct_va1.c \ libffi.call/cls_uchar_va.c libffi.call/cls_uint_va.c \ libffi.call/cls_ulong_va.c libffi.call/cls_ushort_va.c \ libffi.call/nested_struct11.c libffi.call/uninitialized.c \ libffi.call/va_1.c libffi.call/va_struct1.c libffi.call/va_struct2.c \ -libffi.call/va_struct3.c +libffi.call/va_struct3.c \ +libffi.call/strlen2.c \ +libffi.call/strlen3.c \ +libffi.call/strlen4.c all: all-am @@ -343,11 +386,9 @@ mostlyclean-libtool: clean-libtool: -rm -rf .libs _libs -tags: TAGS -TAGS: +tags TAGS: -ctags: CTAGS -CTAGS: +ctags CTAGS: cscope cscopelist: @@ -355,13 +396,12 @@ cscope cscopelist: check-DEJAGNU: site.exp srcdir='$(srcdir)'; export srcdir; \ EXPECT=$(EXPECT); export EXPECT; \ - runtest=$(RUNTEST); \ - if $(SHELL) -c "$$runtest --version" > /dev/null 2>&1; then \ + if $(SHELL) -c "$(RUNTEST) --version" > /dev/null 2>&1; then \ exit_status=0; l='$(DEJATOOL)'; for tool in $$l; do \ - if $$runtest $(AM_RUNTESTFLAGS) $(RUNTESTDEFAULTFLAGS) $(RUNTESTFLAGS); \ + if $(RUNTEST) $(AM_RUNTESTFLAGS) $(RUNTESTDEFAULTFLAGS) $(RUNTESTFLAGS); \ then :; else exit_status=1; fi; \ done; \ - else echo "WARNING: could not find 'runtest'" 1>&2; :;\ + else echo "WARNING: could not find '$(RUNTEST)'" 1>&2; :;\ fi; \ exit $$exit_status site.exp: Makefile $(EXTRA_DEJAGNU_SITE_CONFIG) @@ -532,16 +572,17 @@ uninstall-am: .MAKE: check-am install-am install-strip .PHONY: all all-am check check-DEJAGNU check-am clean clean-generic \ - clean-libtool distclean distclean-DEJAGNU distclean-generic \ - distclean-libtool distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - uninstall uninstall-am + clean-libtool cscopelist-am ctags-am distclean \ + distclean-DEJAGNU distclean-generic distclean-libtool distdir \ + dvi dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \ + uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/Modules/_ctypes/libffi/testsuite/lib/libffi.exp b/Modules/_ctypes/libffi/testsuite/lib/libffi.exp index 1ac2c3608872..dbdd1a2f27c2 100644 --- a/Modules/_ctypes/libffi/testsuite/lib/libffi.exp +++ b/Modules/_ctypes/libffi/testsuite/lib/libffi.exp @@ -222,6 +222,10 @@ proc libffi_target_compile { source dest type options } { lappend options "libs= -lpthread" } + if { [string match "*.cc" $source] } { + lappend options "c++" + } + verbose "options: $options" return [target_compile $source $dest $type $options] } @@ -273,6 +277,46 @@ proc libffi-dg-runtest { testcases default-extra-flags } { } } +proc run-many-tests { testcases extra_flags } { + global using_gcc + if { [string match $using_gcc "yes"] } { + set common "-W -Wall" + set optimizations { "-O0" "-O2" "-O3" "-Os" "-O2 -fomit-frame-pointer" } + } else { + # Assume we are using the vendor compiler. + set common "" + set optimizations { "" } + } + + set targetabis { "" } + if [string match $using_gcc "yes"] { + if [istarget "i?86-*-*"] { + set targetabis { + "" + "-DABI_NUM=FFI_STDCALL -DABI_ATTR=__STDCALL__" + "-DABI_NUM=FFI_THISCALL -DABI_ATTR=__THISCALL__" + "-DABI_NUM=FFI_FASTCALL -DABI_ATTR=__FASTCALL__" + } + } + } + + set common [ concat $common $extra_flags ] + foreach test $testcases { + set testname [file tail $test] + if [search_for $test "ABI_NUM"] { + set abis $targetabis + } else { + set abis { "" } + } + foreach opt $optimizations { + foreach abi $abis { + set options [concat $common $opt $abi] + verbose "Testing $testname, $options" 1 + dg-test $test $options "" + } + } + } +} # Like check_conditional_xfail, but callable from a dg test. diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/call.exp b/Modules/_ctypes/libffi/testsuite/libffi.call/call.exp index c3346850a96b..36d13d8e08d7 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/call.exp +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/call.exp @@ -19,20 +19,7 @@ libffi-init global srcdir subdir -if { [string match $using_gcc "yes"] } { - - dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] "-O0 -W -Wall" "" - dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] "-O2" "" - dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] "-O3" "" - dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] "-Os" "" - dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] "-O2 -fomit-frame-pointer" "" - -} else { - - # Assume we are using the vendor compiler. - dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] "" "" - -} +run-many-tests [lsort [glob -nocomplain -- $srcdir/$subdir/*.{c,cc}]] "" dg-finish diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/closure_stdcall.c b/Modules/_ctypes/libffi/testsuite/libffi.call/closure_simple.c similarity index 55% rename from Modules/_ctypes/libffi/testsuite/libffi.call/closure_stdcall.c rename to Modules/_ctypes/libffi/testsuite/libffi.call/closure_simple.c index 1407f024c170..5a4e728d4a42 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/closure_stdcall.c +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/closure_simple.c @@ -1,15 +1,14 @@ -/* Area: closure_call (stdcall convention) - Purpose: Check handling when caller expects stdcall callee +/* Area: closure_call + Purpose: Check simple closure handling with all ABIs Limitations: none. PR: none. Originator: */ -/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */ +/* { dg-do run } */ #include "ffitest.h" static void -closure_test_stdcall(ffi_cif* cif __UNUSED__, void* resp, void** args, - void* userdata) +closure_test(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata) { *(ffi_arg*)resp = (int)*(int *)args[0] + (int)(*(int *)args[1]) @@ -23,7 +22,7 @@ closure_test_stdcall(ffi_cif* cif __UNUSED__, void* resp, void** args, } -typedef int (__stdcall *closure_test_type0)(int, int, int, int); +typedef int (ABI_ATTR *closure_test_type0)(int, int, int, int); int main (void) { @@ -32,9 +31,6 @@ int main (void) ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); ffi_type * cl_arg_types[17]; int res; - void* sp_pre; - void* sp_post; - char buf[1024]; cl_arg_types[0] = &ffi_type_uint; cl_arg_types[1] = &ffi_type_uint; @@ -43,30 +39,17 @@ int main (void) cl_arg_types[4] = NULL; /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_STDCALL, 4, + CHECK(ffi_prep_cif(&cif, ABI_NUM, 4, &ffi_type_sint, cl_arg_types) == FFI_OK); - CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_stdcall, + CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test, (void *) 3 /* userdata */, code) == FFI_OK); -#ifdef _MSC_VER - __asm { mov sp_pre, esp } -#else - asm volatile (" movl %%esp,%0" : "=g" (sp_pre)); -#endif res = (*(closure_test_type0)code)(0, 1, 2, 3); -#ifdef _MSC_VER - __asm { mov sp_post, esp } -#else - asm volatile (" movl %%esp,%0" : "=g" (sp_post)); -#endif /* { dg-output "0 1 2 3: 9" } */ printf("res: %d\n",res); /* { dg-output "\nres: 9" } */ - sprintf(buf, "mismatch: pre=%p vs post=%p", sp_pre, sp_post); - printf("stack pointer %s\n", (sp_pre == sp_post ? "match" : buf)); - /* { dg-output "\nstack pointer match" } */ exit(0); } diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/closure_thiscall.c b/Modules/_ctypes/libffi/testsuite/libffi.call/closure_thiscall.c deleted file mode 100644 index 0f93649ff752..000000000000 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/closure_thiscall.c +++ /dev/null @@ -1,72 +0,0 @@ -/* Area: closure_call (thiscall convention) - Purpose: Check handling when caller expects thiscall callee - Limitations: none. - PR: none. - Originator: */ - -/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */ -#include "ffitest.h" - -static void -closure_test_thiscall(ffi_cif* cif __UNUSED__, void* resp, void** args, - void* userdata) -{ - *(ffi_arg*)resp = - (int)*(int *)args[0] + (int)(*(int *)args[1]) - + (int)(*(int *)args[2]) + (int)(*(int *)args[3]) - + (int)(intptr_t)userdata; - - printf("%d %d %d %d: %d\n", - (int)*(int *)args[0], (int)(*(int *)args[1]), - (int)(*(int *)args[2]), (int)(*(int *)args[3]), - (int)*(ffi_arg *)resp); - -} - -typedef int (__thiscall *closure_test_type0)(int, int, int, int); - -int main (void) -{ - ffi_cif cif; - void *code; - ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); - ffi_type * cl_arg_types[17]; - int res; - void* sp_pre; - void* sp_post; - char buf[1024]; - - cl_arg_types[0] = &ffi_type_uint; - cl_arg_types[1] = &ffi_type_uint; - cl_arg_types[2] = &ffi_type_uint; - cl_arg_types[3] = &ffi_type_uint; - cl_arg_types[4] = NULL; - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_THISCALL, 4, - &ffi_type_sint, cl_arg_types) == FFI_OK); - - CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_thiscall, - (void *) 3 /* userdata */, code) == FFI_OK); - -#ifdef _MSC_VER - __asm { mov sp_pre, esp } -#else - asm volatile (" movl %%esp,%0" : "=g" (sp_pre)); -#endif - res = (*(closure_test_type0)code)(0, 1, 2, 3); -#ifdef _MSC_VER - __asm { mov sp_post, esp } -#else - asm volatile (" movl %%esp,%0" : "=g" (sp_post)); -#endif - /* { dg-output "0 1 2 3: 9" } */ - - printf("res: %d\n",res); - /* { dg-output "\nres: 9" } */ - - sprintf(buf, "mismatch: pre=%p vs post=%p", sp_pre, sp_post); - printf("stack pointer %s\n", (sp_pre == sp_post ? "match" : buf)); - /* { dg-output "\nstack pointer match" } */ - exit(0); -} diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/cls_double_va.c b/Modules/_ctypes/libffi/testsuite/libffi.call/cls_double_va.c index 43167b6f6312..e077f92b8638 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/cls_double_va.c +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/cls_double_va.c @@ -38,7 +38,7 @@ int main (void) /* This printf call is variadic */ CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2, &ffi_type_sint, - arg_types) == FFI_OK); + arg_types) == FFI_OK); args[0] = &format; args[1] = &doubleArg; @@ -49,12 +49,10 @@ int main (void) printf("res: %d\n", (int) res); /* { dg-output "\nres: 4" } */ - /* The call to cls_double_va_fn is static, so have to use a normal prep_cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_sint, arg_types) == FFI_OK); + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_double_va_fn, NULL, + code) == FFI_OK); - CHECK(ffi_prep_closure_loc(pcl, &cif, cls_double_va_fn, NULL, code) == FFI_OK); - - res = ((int(*)(char*, double))(code))(format, doubleArg); + res = ((int(*)(char*, ...))(code))(format, doubleArg); /* { dg-output "\n7.0" } */ printf("res: %d\n", (int) res); /* { dg-output "\nres: 4" } */ diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/cls_longdouble_va.c b/Modules/_ctypes/libffi/testsuite/libffi.call/cls_longdouble_va.c index 7126b13816da..39b438b289a8 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/cls_longdouble_va.c +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/cls_longdouble_va.c @@ -38,7 +38,7 @@ int main (void) /* This printf call is variadic */ CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2, &ffi_type_sint, - arg_types) == FFI_OK); + arg_types) == FFI_OK); args[0] = &format; args[1] = &ldArg; @@ -49,13 +49,10 @@ int main (void) printf("res: %d\n", (int) res); /* { dg-output "\nres: 4" } */ - /* The call to cls_longdouble_va_fn is static, so have to use a normal prep_cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_sint, - arg_types) == FFI_OK); + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_longdouble_va_fn, NULL, + code) == FFI_OK); - CHECK(ffi_prep_closure_loc(pcl, &cif, cls_longdouble_va_fn, NULL, code) == FFI_OK); - - res = ((int(*)(char*, long double))(code))(format, ldArg); + res = ((int(*)(char*, ...))(code))(format, ldArg); /* { dg-output "\n7.0" } */ printf("res: %d\n", (int) res); /* { dg-output "\nres: 4" } */ diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/cls_struct_va1.c b/Modules/_ctypes/libffi/testsuite/libffi.call/cls_struct_va1.c index 175ed9617802..6d1fdaeb606a 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/cls_struct_va1.c +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/cls_struct_va1.c @@ -35,7 +35,7 @@ test_fn (ffi_cif* cif __UNUSED__, void* resp, printf ("%d %d %d %d %d %d %d %d %d %d\n", n, s1.a, s1.b, l1.a, l1.b, l1.c, l1.d, l1.e, s2.a, s2.b); - * (int*) resp = 42; + * (ffi_arg*) resp = 42; } int diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/cls_uint_va.c b/Modules/_ctypes/libffi/testsuite/libffi.call/cls_uint_va.c index 150fddd515db..b04cfd19c2ce 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/cls_uint_va.c +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/cls_uint_va.c @@ -13,9 +13,9 @@ typedef unsigned int T; static void cls_ret_T_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata __UNUSED__) { - *(T *)resp = *(T *)args[0]; + *(ffi_arg *)resp = *(T *)args[0]; - printf("%d: %d %d\n", *(T *)resp, *(T *)args[0], *(T *)args[1]); + printf("%d: %d %d\n", (int)*(ffi_arg *)resp, *(T *)args[0], *(T *)args[1]); } typedef T (*cls_ret_T)(T, ...); diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/ffitest.h b/Modules/_ctypes/libffi/testsuite/libffi.call/ffitest.h index 136a7a6ba1d3..15d5e4412348 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/ffitest.h +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/ffitest.h @@ -15,22 +15,25 @@ #define MAX_ARGS 256 -#define CHECK(x) !(x) ? (abort(), 1) : 0 +#define CHECK(x) (void)(!(x) ? (abort(), 1) : 0) -/* Define __UNUSED__ that also other compilers than gcc can run the tests. */ +/* Define macros so that compilers other than gcc can run the tests. */ #undef __UNUSED__ #if defined(__GNUC__) #define __UNUSED__ __attribute__((__unused__)) +#define __STDCALL__ __attribute__((stdcall)) +#define __THISCALL__ __attribute__((thiscall)) +#define __FASTCALL__ __attribute__((fastcall)) #else #define __UNUSED__ +#define __STDCALL__ __stdcall +#define __THISCALL__ __thiscall +#define __FASTCALL__ __fastcall #endif -/* Define __FASTCALL__ so that other compilers than gcc can run the tests. */ -#undef __FASTCALL__ -#if defined _MSC_VER -#define __FASTCALL__ __fastcall -#else -#define __FASTCALL__ __attribute__((fastcall)) +#ifndef ABI_NUM +#define ABI_NUM FFI_DEFAULT_ABI +#define ABI_ATTR #endif /* Prefer MAP_ANON(YMOUS) to /dev/zero, since we don't need to keep a diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/many.c b/Modules/_ctypes/libffi/testsuite/libffi.call/many.c index 4869ba9dde07..336968c77a2b 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/many.c +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/many.c @@ -7,21 +7,11 @@ /* { dg-do run } */ #include "ffitest.h" +#include #include +#include -static float many(float f1, - float f2, - float f3, - float f4, - float f5, - float f6, - float f7, - float f8, - float f9, - float f10, - float f11, - float f12, - float f13) +static float ABI_ATTR many(float f1, float f2, float f3, float f4, float f5, float f6, float f7, float f8, float f9, float f10, float f11, float f12, float f13) { #if 0 printf("%f %f %f %f %f %f %f %f %f %f %f %f %f\n", @@ -30,7 +20,7 @@ static float many(float f1, (double) f11, (double) f12, (double) f13); #endif - return ((f1/f2+f3/f4+f5/f6+f7/f8+f9/f10+f11/f12) * f13); + return f1+f2+f3+f4+f5+f6+f7+f8+f9+f10+f11+f12+f13; } int main (void) @@ -50,7 +40,7 @@ int main (void) } /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 13, + CHECK(ffi_prep_cif(&cif, ABI_NUM, 13, &ffi_type_float, args) == FFI_OK); ffi_call(&cif, FFI_FN(many), &f, values); @@ -62,7 +52,7 @@ int main (void) fa[8], fa[9], fa[10],fa[11],fa[12]); - if (f - ff < FLT_EPSILON) + if (fabs(f - ff) < FLT_EPSILON) exit(0); else abort(); diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/many2.c b/Modules/_ctypes/libffi/testsuite/libffi.call/many2.c index 98eac6013a43..1c85746e4c4b 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/many2.c +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/many2.c @@ -22,7 +22,7 @@ foo (uint8_t a, uint8_t b, uint8_t c, uint8_t d, return a + b + c + d + e + f + g; } -uint8_t +uint8_t ABI_ATTR bar (uint8_t a, uint8_t b, uint8_t c, uint8_t d, uint8_t e, uint8_t f, uint8_t g) { @@ -42,7 +42,7 @@ main (void) for (i = 0; i < NARGS; ++i) ffitypes[i] = &ffi_type_uint8; - CHECK (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, NARGS, + CHECK (ffi_prep_cif (&cif, ABI_NUM, NARGS, &ffi_type_uint8, ffitypes) == FFI_OK); for (i = 0; i < NARGS; ++i) diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/many2_win32.c b/Modules/_ctypes/libffi/testsuite/libffi.call/many2_win32.c deleted file mode 100644 index 4adbe4d705f8..000000000000 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/many2_win32.c +++ /dev/null @@ -1,63 +0,0 @@ -/* Area: ffi_call - Purpose: Check stdcall many call on X86_WIN32 systems. - Limitations: none. - PR: none. - Originator: From the original ffitest.c */ - -/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */ - -#include "ffitest.h" -#include - -static float __attribute__((fastcall)) fastcall_many(float f1, - float f2, - float f3, - float f4, - float f5, - float f6, - float f7, - float f8, - float f9, - float f10, - float f11, - float f12, - float f13) -{ - return ((f1/f2+f3/f4+f5/f6+f7/f8+f9/f10+f11/f12) * f13); -} - -int main (void) -{ - ffi_cif cif; - ffi_type *args[13]; - void *values[13]; - float fa[13]; - float f, ff; - unsigned long ul; - - for (ul = 0; ul < 13; ul++) - { - args[ul] = &ffi_type_float; - values[ul] = &fa[ul]; - fa[ul] = (float) ul; - } - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_FASTCALL, 13, - &ffi_type_float, args) == FFI_OK); - - ff = fastcall_many(fa[0], fa[1], - fa[2], fa[3], - fa[4], fa[5], - fa[6], fa[7], - fa[8], fa[9], - fa[10], fa[11], fa[12]); - - ffi_call(&cif, FFI_FN(fastcall_many), &f, values); - - if (f - ff < FLT_EPSILON) - printf("fastcall many arg tests ok!\n"); - else - CHECK(0); - exit(0); -} diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/many_win32.c b/Modules/_ctypes/libffi/testsuite/libffi.call/many_win32.c deleted file mode 100644 index 1b2633227ad9..000000000000 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/many_win32.c +++ /dev/null @@ -1,63 +0,0 @@ -/* Area: ffi_call - Purpose: Check stdcall many call on X86_WIN32 systems. - Limitations: none. - PR: none. - Originator: From the original ffitest.c */ - -/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */ - -#include "ffitest.h" -#include - -static float __attribute__((stdcall)) stdcall_many(float f1, - float f2, - float f3, - float f4, - float f5, - float f6, - float f7, - float f8, - float f9, - float f10, - float f11, - float f12, - float f13) -{ - return ((f1/f2+f3/f4+f5/f6+f7/f8+f9/f10+f11/f12) * f13); -} - -int main (void) -{ - ffi_cif cif; - ffi_type *args[13]; - void *values[13]; - float fa[13]; - float f, ff; - unsigned long ul; - - for (ul = 0; ul < 13; ul++) - { - args[ul] = &ffi_type_float; - values[ul] = &fa[ul]; - fa[ul] = (float) ul; - } - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_STDCALL, 13, - &ffi_type_float, args) == FFI_OK); - - ff = stdcall_many(fa[0], fa[1], - fa[2], fa[3], - fa[4], fa[5], - fa[6], fa[7], - fa[8], fa[9], - fa[10], fa[11], fa[12]); - - ffi_call(&cif, FFI_FN(stdcall_many), &f, values); - - if (f - ff < FLT_EPSILON) - printf("stdcall many arg tests ok!\n"); - else - CHECK(0); - exit(0); -} diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/nested_struct11.c b/Modules/_ctypes/libffi/testsuite/libffi.call/nested_struct11.c index fce69481888f..351049382c62 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/nested_struct11.c +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/nested_struct11.c @@ -1,7 +1,7 @@ /* Area: ffi_call, closure_call Purpose: Check parameter passing with nested structs of a single type. This tests the special cases - for homogenous floating-point aggregates in the + for homogeneous floating-point aggregates in the AArch64 PCS. Limitations: none. PR: none. diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/strlen.c b/Modules/_ctypes/libffi/testsuite/libffi.call/strlen.c index 3de45de7aaac..35b70ea4e2e1 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/strlen.c +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/strlen.c @@ -7,7 +7,7 @@ /* { dg-do run } */ #include "ffitest.h" -static size_t my_strlen(char *s) +static size_t ABI_ATTR my_strlen(char *s) { return (strlen(s)); } @@ -24,7 +24,7 @@ int main (void) values[0] = (void*) &s; /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ffi_type_sint, args) == FFI_OK); s = "a"; diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/fastthis1_win32.c b/Modules/_ctypes/libffi/testsuite/libffi.call/strlen2.c similarity index 61% rename from Modules/_ctypes/libffi/testsuite/libffi.call/fastthis1_win32.c rename to Modules/_ctypes/libffi/testsuite/libffi.call/strlen2.c index cbc4724ef8c1..96282bc0a1fa 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/fastthis1_win32.c +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/strlen2.c @@ -1,14 +1,14 @@ /* Area: ffi_call - Purpose: Check fastcall fct call on X86_WIN32 systems. + Purpose: Check strlen function call with additional arguments. Limitations: none. PR: none. Originator: From the original ffitest.c */ -/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */ +/* { dg-do run } */ #include "ffitest.h" -static size_t __FASTCALL__ my_fastcall_f(char *s, float a) +static size_t ABI_ATTR my_f(char *s, float a) { return (size_t) ((int) strlen(s) + (int) a); } @@ -27,24 +27,23 @@ int main (void) values[1] = (void*) &v2; /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_FASTCALL, 2, + CHECK(ffi_prep_cif(&cif, ABI_NUM, 2, &ffi_type_sint, args) == FFI_OK); s = "a"; v2 = 0.0; - ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values); + ffi_call(&cif, FFI_FN(my_f), &rint, values); CHECK(rint == 1); s = "1234567"; v2 = -1.0; - ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values); + ffi_call(&cif, FFI_FN(my_f), &rint, values); CHECK(rint == 6); s = "1234567890123456789012345"; v2 = 1.0; - ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values); + ffi_call(&cif, FFI_FN(my_f), &rint, values); CHECK(rint == 26); - printf("fastcall fct1 tests passed\n"); exit(0); } diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/strlen2_win32.c b/Modules/_ctypes/libffi/testsuite/libffi.call/strlen2_win32.c deleted file mode 100644 index 0d81061e7585..000000000000 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/strlen2_win32.c +++ /dev/null @@ -1,44 +0,0 @@ -/* Area: ffi_call - Purpose: Check fastcall strlen call on X86_WIN32 systems. - Limitations: none. - PR: none. - Originator: From the original ffitest.c */ - -/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */ - -#include "ffitest.h" - -static size_t __FASTCALL__ my_fastcall_strlen(char *s) -{ - return (strlen(s)); -} - -int main (void) -{ - ffi_cif cif; - ffi_type *args[MAX_ARGS]; - void *values[MAX_ARGS]; - ffi_arg rint; - char *s; - args[0] = &ffi_type_pointer; - values[0] = (void*) &s; - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_FASTCALL, 1, - &ffi_type_sint, args) == FFI_OK); - - s = "a"; - ffi_call(&cif, FFI_FN(my_fastcall_strlen), &rint, values); - CHECK(rint == 1); - - s = "1234567"; - ffi_call(&cif, FFI_FN(my_fastcall_strlen), &rint, values); - CHECK(rint == 7); - - s = "1234567890123456789012345"; - ffi_call(&cif, FFI_FN(my_fastcall_strlen), &rint, values); - CHECK(rint == 25); - - printf("fastcall strlen tests passed\n"); - exit(0); -} diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/fastthis2_win32.c b/Modules/_ctypes/libffi/testsuite/libffi.call/strlen3.c similarity index 61% rename from Modules/_ctypes/libffi/testsuite/libffi.call/fastthis2_win32.c rename to Modules/_ctypes/libffi/testsuite/libffi.call/strlen3.c index 7bdd0e17584c..beba86e9eacf 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/fastthis2_win32.c +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/strlen3.c @@ -1,14 +1,14 @@ /* Area: ffi_call - Purpose: Check fastcall fct call on X86_WIN32 systems. + Purpose: Check strlen function call with additional arguments. Limitations: none. PR: none. Originator: From the original ffitest.c */ -/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */ +/* { dg-do run } */ #include "ffitest.h" -static size_t __FASTCALL__ my_fastcall_f(float a, char *s) +static size_t ABI_ATTR my_f(float a, char *s) { return (size_t) ((int) strlen(s) + (int) a); } @@ -27,24 +27,23 @@ int main (void) values[0] = (void*) &v2; /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_FASTCALL, 2, + CHECK(ffi_prep_cif(&cif, ABI_NUM, 2, &ffi_type_sint, args) == FFI_OK); s = "a"; v2 = 0.0; - ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values); + ffi_call(&cif, FFI_FN(my_f), &rint, values); CHECK(rint == 1); s = "1234567"; v2 = -1.0; - ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values); + ffi_call(&cif, FFI_FN(my_f), &rint, values); CHECK(rint == 6); s = "1234567890123456789012345"; v2 = 1.0; - ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values); + ffi_call(&cif, FFI_FN(my_f), &rint, values); CHECK(rint == 26); - printf("fastcall fct2 tests passed\n"); exit(0); } diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/fastthis3_win32.c b/Modules/_ctypes/libffi/testsuite/libffi.call/strlen4.c similarity index 63% rename from Modules/_ctypes/libffi/testsuite/libffi.call/fastthis3_win32.c rename to Modules/_ctypes/libffi/testsuite/libffi.call/strlen4.c index b5d606d9a15e..d5d42b4f6ddf 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/fastthis3_win32.c +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/strlen4.c @@ -1,14 +1,14 @@ /* Area: ffi_call - Purpose: Check fastcall f call on X86_WIN32 systems. + Purpose: Check strlen function call with additional arguments. Limitations: none. PR: none. Originator: From the original ffitest.c */ -/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */ +/* { dg-do run } */ #include "ffitest.h" -static size_t __FASTCALL__ my_fastcall_f(float a, char *s, int i) +static size_t ABI_ATTR my_f(float a, char *s, int i) { return (size_t) ((int) strlen(s) + (int) a + i); } @@ -30,27 +30,26 @@ int main (void) values[0] = (void*) &v2; /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_FASTCALL, 3, + CHECK(ffi_prep_cif(&cif, ABI_NUM, 3, &ffi_type_sint, args) == FFI_OK); s = "a"; v1 = 1; v2 = 0.0; - ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values); + ffi_call(&cif, FFI_FN(my_f), &rint, values); CHECK(rint == 2); s = "1234567"; v2 = -1.0; v1 = -2; - ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values); + ffi_call(&cif, FFI_FN(my_f), &rint, values); CHECK(rint == 4); s = "1234567890123456789012345"; v2 = 1.0; v1 = 2; - ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values); + ffi_call(&cif, FFI_FN(my_f), &rint, values); CHECK(rint == 28); - printf("fastcall fct3 tests passed\n"); exit(0); } diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/strlen_win32.c b/Modules/_ctypes/libffi/testsuite/libffi.call/strlen_win32.c deleted file mode 100644 index 6fbcc87400a6..000000000000 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/strlen_win32.c +++ /dev/null @@ -1,44 +0,0 @@ -/* Area: ffi_call - Purpose: Check stdcall strlen call on X86_WIN32 systems. - Limitations: none. - PR: none. - Originator: From the original ffitest.c */ - -/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */ - -#include "ffitest.h" - -static size_t __attribute__((stdcall)) my_stdcall_strlen(char *s) -{ - return (strlen(s)); -} - -int main (void) -{ - ffi_cif cif; - ffi_type *args[MAX_ARGS]; - void *values[MAX_ARGS]; - ffi_arg rint; - char *s; - args[0] = &ffi_type_pointer; - values[0] = (void*) &s; - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_STDCALL, 1, - &ffi_type_sint, args) == FFI_OK); - - s = "a"; - ffi_call(&cif, FFI_FN(my_stdcall_strlen), &rint, values); - CHECK(rint == 1); - - s = "1234567"; - ffi_call(&cif, FFI_FN(my_stdcall_strlen), &rint, values); - CHECK(rint == 7); - - s = "1234567890123456789012345"; - ffi_call(&cif, FFI_FN(my_stdcall_strlen), &rint, values); - CHECK(rint == 25); - - printf("stdcall strlen tests passed\n"); - exit(0); -} diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/struct1.c b/Modules/_ctypes/libffi/testsuite/libffi.call/struct1.c index bfc23f642cc8..c13e23f87273 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/struct1.c +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/struct1.c @@ -14,7 +14,7 @@ typedef struct unsigned int ui; } test_structure_1; -static test_structure_1 struct1(test_structure_1 ts) +static test_structure_1 ABI_ATTR struct1(test_structure_1 ts) { ts.uc++; ts.d--; @@ -50,7 +50,7 @@ int main (void) values[0] = &ts1_arg; /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts1_type, args) == FFI_OK); ts1_arg.uc = '\x01'; diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/struct1_win32.c b/Modules/_ctypes/libffi/testsuite/libffi.call/struct1_win32.c deleted file mode 100644 index b756f5ad8b52..000000000000 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/struct1_win32.c +++ /dev/null @@ -1,67 +0,0 @@ -/* Area: ffi_call - Purpose: Check structures with fastcall/thiscall convention. - Limitations: none. - PR: none. - Originator: From the original ffitest.c */ - -/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */ -#include "ffitest.h" - -typedef struct -{ - unsigned char uc; - double d; - unsigned int ui; -} test_structure_1; - -static test_structure_1 __FASTCALL__ struct1(test_structure_1 ts) -{ - ts.uc++; - ts.d--; - ts.ui++; - - return ts; -} - -int main (void) -{ - ffi_cif cif; - ffi_type *args[MAX_ARGS]; - void *values[MAX_ARGS]; - ffi_type ts1_type; - ffi_type *ts1_type_elements[4]; - - test_structure_1 ts1_arg; - - /* This is a hack to get a properly aligned result buffer */ - test_structure_1 *ts1_result = - (test_structure_1 *) malloc (sizeof(test_structure_1)); - - ts1_type.size = 0; - ts1_type.alignment = 0; - ts1_type.type = FFI_TYPE_STRUCT; - ts1_type.elements = ts1_type_elements; - ts1_type_elements[0] = &ffi_type_uchar; - ts1_type_elements[1] = &ffi_type_double; - ts1_type_elements[2] = &ffi_type_uint; - ts1_type_elements[3] = NULL; - - args[0] = &ts1_type; - values[0] = &ts1_arg; - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_FASTCALL, 1, - &ts1_type, args) == FFI_OK); - - ts1_arg.uc = '\x01'; - ts1_arg.d = 3.14159; - ts1_arg.ui = 555; - - ffi_call(&cif, FFI_FN(struct1), ts1_result, values); - - CHECK(ts1_result->ui == 556); - CHECK(ts1_result->d == 3.14159 - 1); - - free (ts1_result); - exit(0); -} diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/struct2.c b/Modules/_ctypes/libffi/testsuite/libffi.call/struct2.c index d85385e7d3f2..5077a5ee45a5 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/struct2.c +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/struct2.c @@ -13,7 +13,7 @@ typedef struct double d2; } test_structure_2; -static test_structure_2 struct2(test_structure_2 ts) +static test_structure_2 ABI_ATTR struct2(test_structure_2 ts) { ts.d1--; ts.d2--; @@ -46,7 +46,7 @@ int main (void) values[0] = &ts2_arg; /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts2_type, args) == FFI_OK); + CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts2_type, args) == FFI_OK); ts2_arg.d1 = 5.55; ts2_arg.d2 = 6.66; diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/struct2_win32.c b/Modules/_ctypes/libffi/testsuite/libffi.call/struct2_win32.c deleted file mode 100644 index 5d022855c574..000000000000 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/struct2_win32.c +++ /dev/null @@ -1,67 +0,0 @@ -/* Area: ffi_call - Purpose: Check structures in fastcall/stdcall function - Limitations: none. - PR: none. - Originator: From the original ffitest.c */ - -/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */ -#include "ffitest.h" - -typedef struct -{ - double d1; - double d2; -} test_structure_2; - -static test_structure_2 __FASTCALL__ struct2(test_structure_2 ts) -{ - ts.d1--; - ts.d2--; - - return ts; -} - -int main (void) -{ - ffi_cif cif; - ffi_type *args[MAX_ARGS]; - void *values[MAX_ARGS]; - test_structure_2 ts2_arg; - ffi_type ts2_type; - ffi_type *ts2_type_elements[3]; - - /* This is a hack to get a properly aligned result buffer */ - test_structure_2 *ts2_result = - (test_structure_2 *) malloc (sizeof(test_structure_2)); - - ts2_type.size = 0; - ts2_type.alignment = 0; - ts2_type.type = FFI_TYPE_STRUCT; - ts2_type.elements = ts2_type_elements; - ts2_type_elements[0] = &ffi_type_double; - ts2_type_elements[1] = &ffi_type_double; - ts2_type_elements[2] = NULL; - - args[0] = &ts2_type; - values[0] = &ts2_arg; - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_FASTCALL, 1, &ts2_type, args) == FFI_OK); - - ts2_arg.d1 = 5.55; - ts2_arg.d2 = 6.66; - - printf ("%g\n", ts2_arg.d1); - printf ("%g\n", ts2_arg.d2); - - ffi_call(&cif, FFI_FN(struct2), ts2_result, values); - - printf ("%g\n", ts2_result->d1); - printf ("%g\n", ts2_result->d2); - - CHECK(ts2_result->d1 == 5.55 - 1); - CHECK(ts2_result->d2 == 6.66 - 1); - - free (ts2_result); - exit(0); -} diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/struct3.c b/Modules/_ctypes/libffi/testsuite/libffi.call/struct3.c index de883c2638e0..7eba0ead6d6a 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/struct3.c +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/struct3.c @@ -12,7 +12,7 @@ typedef struct int si; } test_structure_3; -static test_structure_3 struct3(test_structure_3 ts) +static test_structure_3 ABI_ATTR struct3(test_structure_3 ts) { ts.si = -(ts.si*2); @@ -43,7 +43,7 @@ int main (void) values[0] = &ts3_arg; /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts3_type, args) == FFI_OK); ts3_arg.si = -123; diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/struct4.c b/Modules/_ctypes/libffi/testsuite/libffi.call/struct4.c index 48e03495441c..66a9551dd650 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/struct4.c +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/struct4.c @@ -14,7 +14,7 @@ typedef struct unsigned ui3; } test_structure_4; -static test_structure_4 struct4(test_structure_4 ts) +static test_structure_4 ABI_ATTR struct4(test_structure_4 ts) { ts.ui3 = ts.ui1 * ts.ui2 * ts.ui3; @@ -48,7 +48,7 @@ int main (void) values[0] = &ts4_arg; /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts4_type, args) == FFI_OK); + CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts4_type, args) == FFI_OK); ts4_arg.ui1 = 2; ts4_arg.ui2 = 3; diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/struct5.c b/Modules/_ctypes/libffi/testsuite/libffi.call/struct5.c index 28b1f0c4265e..23e2a3f745c8 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/struct5.c +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/struct5.c @@ -12,7 +12,7 @@ typedef struct char c2; } test_structure_5; -static test_structure_5 struct5(test_structure_5 ts1, test_structure_5 ts2) +static test_structure_5 ABI_ATTR struct5(test_structure_5 ts1, test_structure_5 ts2) { ts1.c1 += ts2.c1; ts1.c2 -= ts2.c2; @@ -48,7 +48,7 @@ int main (void) values[1] = &ts5_arg2; /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ts5_type, args) == FFI_OK); + CHECK(ffi_prep_cif(&cif, ABI_NUM, 2, &ts5_type, args) == FFI_OK); ts5_arg1.c1 = 2; ts5_arg1.c2 = 6; diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/struct6.c b/Modules/_ctypes/libffi/testsuite/libffi.call/struct6.c index 0e267467a7b0..173c66eb4d2b 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/struct6.c +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/struct6.c @@ -12,7 +12,7 @@ typedef struct double d; } test_structure_6; -static test_structure_6 struct6 (test_structure_6 ts) +static test_structure_6 ABI_ATTR struct6 (test_structure_6 ts) { ts.f += 1; ts.d += 1; @@ -46,7 +46,7 @@ int main (void) values[0] = &ts6_arg; /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts6_type, args) == FFI_OK); + CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts6_type, args) == FFI_OK); ts6_arg.f = 5.55f; ts6_arg.d = 6.66; diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/struct7.c b/Modules/_ctypes/libffi/testsuite/libffi.call/struct7.c index 8f2bbfd949c5..badc7e055609 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/struct7.c +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/struct7.c @@ -13,7 +13,7 @@ typedef struct double d; } test_structure_7; -static test_structure_7 struct7 (test_structure_7 ts) +static test_structure_7 ABI_ATTR struct7 (test_structure_7 ts) { ts.f1 += 1; ts.f2 += 1; @@ -49,7 +49,7 @@ int main (void) values[0] = &ts7_arg; /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts7_type, args) == FFI_OK); + CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts7_type, args) == FFI_OK); ts7_arg.f1 = 5.55f; ts7_arg.f2 = 55.5f; diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/struct8.c b/Modules/_ctypes/libffi/testsuite/libffi.call/struct8.c index 266e1f0ad606..ef204ecbbce5 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/struct8.c +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/struct8.c @@ -14,7 +14,7 @@ typedef struct float f4; } test_structure_8; -static test_structure_8 struct8 (test_structure_8 ts) +static test_structure_8 ABI_ATTR struct8 (test_structure_8 ts) { ts.f1 += 1; ts.f2 += 1; @@ -52,7 +52,7 @@ int main (void) values[0] = &ts8_arg; /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts8_type, args) == FFI_OK); + CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts8_type, args) == FFI_OK); ts8_arg.f1 = 5.55f; ts8_arg.f2 = 55.5f; diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/struct9.c b/Modules/_ctypes/libffi/testsuite/libffi.call/struct9.c index efeb7161b845..4a13b818c4ee 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/struct9.c +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/struct9.c @@ -13,7 +13,7 @@ typedef struct int i; } test_structure_9; -static test_structure_9 struct9 (test_structure_9 ts) +static test_structure_9 ABI_ATTR struct9 (test_structure_9 ts) { ts.f += 1; ts.i += 1; @@ -47,7 +47,7 @@ int main (void) values[0] = &ts9_arg; /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts9_type, args) == FFI_OK); + CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts9_type, args) == FFI_OK); ts9_arg.f = 5.55f; ts9_arg.i = 5; diff --git a/Modules/_ctypes/libffi/testsuite/libffi.special/unwindtest.cc b/Modules/_ctypes/libffi/testsuite/libffi.call/unwindtest.cc similarity index 96% rename from Modules/_ctypes/libffi/testsuite/libffi.special/unwindtest.cc rename to Modules/_ctypes/libffi/testsuite/libffi.call/unwindtest.cc index a78f4e72cdc3..67cfefeca636 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.special/unwindtest.cc +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/unwindtest.cc @@ -6,17 +6,9 @@ /* { dg-do run } */ -#include "ffitestcxx.h" +#include "ffitest.h" -#if defined HAVE_STDINT_H -#include -#endif - -#if defined HAVE_INTTYPES_H -#include -#endif - -void +void ABI_ATTR closure_test_fn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__, void** args __UNUSED__, void* userdata __UNUSED__) { diff --git a/Modules/_ctypes/libffi/testsuite/libffi.special/unwindtest_ffi_call.cc b/Modules/_ctypes/libffi/testsuite/libffi.call/unwindtest_ffi_call.cc similarity index 97% rename from Modules/_ctypes/libffi/testsuite/libffi.special/unwindtest_ffi_call.cc rename to Modules/_ctypes/libffi/testsuite/libffi.call/unwindtest_ffi_call.cc index 57191f2a607a..ec611647e3dc 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.special/unwindtest_ffi_call.cc +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/unwindtest_ffi_call.cc @@ -6,7 +6,7 @@ /* { dg-do run } */ -#include "ffitestcxx.h" +#include "ffitest.h" static int checking(int a __UNUSED__, short b __UNUSED__, signed char c __UNUSED__) diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/va_1.c b/Modules/_ctypes/libffi/testsuite/libffi.call/va_1.c index cf4dd85cedef..7f96809ea9ec 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/va_1.c +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/va_1.c @@ -94,7 +94,7 @@ main (void) struct large_tag l1; int n; - int res; + ffi_arg res; unsigned char uc; signed char sc; diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/va_struct1.c b/Modules/_ctypes/libffi/testsuite/libffi.call/va_struct1.c index 11d1f10e5c69..e6452061c1d3 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/va_struct1.c +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/va_struct1.c @@ -61,7 +61,7 @@ main (void) struct large_tag l1; int n; - int res; + ffi_arg res; s_type.size = 0; s_type.alignment = 0; diff --git a/Modules/_ctypes/libffi/testsuite/libffi.special/ffitestcxx.h b/Modules/_ctypes/libffi/testsuite/libffi.special/ffitestcxx.h deleted file mode 100644 index c6da7efd49e7..000000000000 --- a/Modules/_ctypes/libffi/testsuite/libffi.special/ffitestcxx.h +++ /dev/null @@ -1,55 +0,0 @@ -#include -#include -#include -#include -#include "fficonfig.h" - -#define MAX_ARGS 256 - - -/* Define __UNUSED__ that also other compilers than gcc can run the tests. */ -#undef __UNUSED__ -#if defined(__GNUC__) -#define __UNUSED__ __attribute__((__unused__)) -#else -#define __UNUSED__ -#endif - -#define CHECK(x) (!(x) ? abort() : (void)0) - -/* Prefer MAP_ANON(YMOUS) to /dev/zero, since we don't need to keep a - file open. */ -#ifdef HAVE_MMAP_ANON -# undef HAVE_MMAP_DEV_ZERO - -# include -# ifndef MAP_FAILED -# define MAP_FAILED -1 -# endif -# if !defined (MAP_ANONYMOUS) && defined (MAP_ANON) -# define MAP_ANONYMOUS MAP_ANON -# endif -# define USING_MMAP - -#endif - -#ifdef HAVE_MMAP_DEV_ZERO - -# include -# ifndef MAP_FAILED -# define MAP_FAILED -1 -# endif -# define USING_MMAP - -#endif - - -/* MinGW kludge. */ -#ifdef _WIN64 -#define PRIdLL "I64d" -#define PRIuLL "I64u" -#else -#define PRIdLL "lld" -#define PRIuLL "llu" -#endif - diff --git a/Modules/_ctypes/libffi/testsuite/libffi.special/special.exp b/Modules/_ctypes/libffi/testsuite/libffi.special/special.exp deleted file mode 100644 index f1a5fa6d8f5f..000000000000 --- a/Modules/_ctypes/libffi/testsuite/libffi.special/special.exp +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright (C) 2003, 2006, 2009, 2010 Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING3. If not see -# . - -dg-init -libffi-init - -global srcdir subdir - -global cxx_options - -set cxx_options " -shared-libgcc -lstdc++" - -if { [string match $using_gcc "yes"] } { - - dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.cc]] $cxx_options "-O0 -W -Wall" - dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.cc]] $cxx_options "-O2" - dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.cc]] $cxx_options "-O3" - dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.cc]] $cxx_options "-Os" - -} - -dg-finish - -# Local Variables: -# tcl-indent-level:4 -# End: diff --git a/Modules/_ctypes/libffi/texinfo.tex b/Modules/_ctypes/libffi/texinfo.tex index a5a7b2beac73..85f184cc4cbb 100644 --- a/Modules/_ctypes/libffi/texinfo.tex +++ b/Modules/_ctypes/libffi/texinfo.tex @@ -3,11 +3,11 @@ % Load plain if necessary, i.e., if running under initex. \expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi % -\def\texinfoversion{2012-06-05.14} +\def\texinfoversion{2013-02-01.11} % % Copyright 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995, % 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, -% 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. +% 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc. % % This texinfo.tex file is free software: you can redistribute it and/or % modify it under the terms of the GNU General Public License as @@ -24,7 +24,8 @@ % % As a special exception, when this file is read by TeX when processing % a Texinfo source document, you may use the result without -% restriction. (This has been our intent since Texinfo was invented.) +% restriction. This Exception is an additional permission under section 7 +% of the GNU General Public License, version 3 ("GPLv3"). % % Please try the latest version of texinfo.tex before submitting bug % reports; you can get the latest version from: @@ -594,7 +595,7 @@ \def\:{\spacefactor=1000 } % @* forces a line break. -\def\*{\hfil\break\hbox{}\ignorespaces} +\def\*{\unskip\hfil\break\hbox{}\ignorespaces} % @/ allows a line break. \let\/=\allowbreak @@ -2272,8 +2273,6 @@ \gdef\markupsetcodequoteleft{\let`\codequoteleft} \gdef\markupsetcodequoteright{\let'\codequoteright} - -\gdef\markupsetnoligaturesquoteleft{\let`\noligaturesquoteleft} } \let\markupsetuplqcode \markupsetcodequoteleft @@ -2282,6 +2281,9 @@ \let\markupsetuplqexample \markupsetcodequoteleft \let\markupsetuprqexample \markupsetcodequoteright % +\let\markupsetuplqkbd \markupsetcodequoteleft +\let\markupsetuprqkbd \markupsetcodequoteright +% \let\markupsetuplqsamp \markupsetcodequoteleft \let\markupsetuprqsamp \markupsetcodequoteright % @@ -2291,8 +2293,6 @@ \let\markupsetuplqverbatim \markupsetcodequoteleft \let\markupsetuprqverbatim \markupsetcodequoteright -\let\markupsetuplqkbd \markupsetnoligaturesquoteleft - % Allow an option to not use regular directed right quote/apostrophe % (char 0x27), but instead the undirected quote from cmtt (char 0x0d). % The undirected quote is ugly, so don't make it the default, but it @@ -2382,8 +2382,7 @@ \aftersmartic } -% like \smartslanted except unconditionally uses \ttsl, and no ic. -% @var is set to this for defun arguments. +% Unconditional use \ttsl, and no ic. @var is set to this for defuns. \def\ttslanted#1{{\ttsl #1}} % @cite is like \smartslanted except unconditionally use \sl. We never want @@ -2448,34 +2447,12 @@ % @samp. \def\samp#1{{\setupmarkupstyle{samp}\lq\tclose{#1}\rq\null}} -% definition of @key that produces a lozenge. Doesn't adjust to text size. -%\setfont\keyrm\rmshape{8}{1000}{OT1} -%\font\keysy=cmsy9 -%\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{% -% \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{% -% \vbox{\hrule\kern-0.4pt -% \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}% -% \kern-0.4pt\hrule}% -% \kern-.06em\raise0.4pt\hbox{\angleright}}}} - -% definition of @key with no lozenge. If the current font is already -% monospace, don't change it; that way, we respect @kbdinputstyle. But -% if it isn't monospace, then use \tt. -% -\def\key#1{{\setupmarkupstyle{key}% - \nohyphenation - \ifmonospace\else\tt\fi - #1}\null} - -% ctrl is no longer a Texinfo command. -\def\ctrl #1{{\tt \rawbackslash \hat}#1} - -% @file, @option are the same as @samp. -\let\file=\samp -\let\option=\samp +% @indicateurl is \samp, that is, with quotes. +\let\indicateurl=\samp -% @code is a modification of @t, -% which makes spaces the same size as normal in the surrounding text. +% @code (and similar) prints in typewriter, but with spaces the same +% size as normal in the surrounding text, without hyphenation, etc. +% This is a subroutine for that. \def\tclose#1{% {% % Change normal interword space to be same as for the current font. @@ -2500,7 +2477,7 @@ % We *must* turn on hyphenation at `-' and `_' in @code. % Otherwise, it is too hard to avoid overfull hboxes % in the Emacs manual, the Library manual, etc. - +% % Unfortunately, TeX uses one parameter (\hyphenchar) to control % both hyphenation at - and hyphenation within words. % We must therefore turn them both off (\tclose does that) @@ -2519,7 +2496,7 @@ \let-\codedash \let_\codeunder \else - \let-\realdash + \let-\normaldash \let_\realunder \fi \codex @@ -2528,7 +2505,7 @@ \def\codex #1{\tclose{#1}\endgroup} -\def\realdash{-} +\def\normaldash{-} \def\codedash{-\discretionary{}{}{}} \def\codeunder{% % this is all so @math{@code{var_name}+1} can work. In math mode, _ @@ -2543,9 +2520,9 @@ } % An additional complication: the above will allow breaks after, e.g., -% each of the four underscores in __typeof__. This is undesirable in -% some manuals, especially if they don't have long identifiers in -% general. @allowcodebreaks provides a way to control this. +% each of the four underscores in __typeof__. This is bad. +% @allowcodebreaks provides a document-level way to turn breaking at - +% and _ on and off. % \newif\ifallowcodebreaks \allowcodebreakstrue @@ -2564,6 +2541,13 @@ \fi\fi } +% For @command, @env, @file, @option quotes seem unnecessary, +% so use \code rather than \samp. +\let\command=\code +\let\env=\code +\let\file=\code +\let\option=\code + % @uref (abbreviation for `urlref') takes an optional (comma-separated) % second argument specifying the text to display and an optional third % arg as text to display instead of (rather than in addition to) the url @@ -2710,10 +2694,6 @@ \let\email=\uref \fi -% @kbd is like @code, except that if the argument is just one @key command, -% then @kbd has no effect. -\def\kbd#1{{\setupmarkupstyle{kbd}\def\look{#1}\expandafter\kbdfoo\look??\par}} - % @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always), % `example' (@kbd uses ttsl only inside of @example and friends), % or `code' (@kbd uses normal tty font always). @@ -2737,16 +2717,36 @@ % Default is `distinct'. \kbdinputstyle distinct +% @kbd is like @code, except that if the argument is just one @key command, +% then @kbd has no effect. +\def\kbd#1{{\def\look{#1}\expandafter\kbdsub\look??\par}} + \def\xkey{\key} -\def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}% -\ifx\one\xkey\ifx\threex\three \key{#2}% -\else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi -\else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi} +\def\kbdsub#1#2#3\par{% + \def\one{#1}\def\three{#3}\def\threex{??}% + \ifx\one\xkey\ifx\threex\three \key{#2}% + \else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi + \else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi +} -% For @indicateurl, @env, @command quotes seem unnecessary, so use \code. -\let\indicateurl=\code -\let\env=\code -\let\command=\code +% definition of @key that produces a lozenge. Doesn't adjust to text size. +%\setfont\keyrm\rmshape{8}{1000}{OT1} +%\font\keysy=cmsy9 +%\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{% +% \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{% +% \vbox{\hrule\kern-0.4pt +% \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}% +% \kern-0.4pt\hrule}% +% \kern-.06em\raise0.4pt\hbox{\angleright}}}} + +% definition of @key with no lozenge. If the current font is already +% monospace, don't change it; that way, we respect @kbdinputstyle. But +% if it isn't monospace, then use \tt. +% +\def\key#1{{\setupmarkupstyle{key}% + \nohyphenation + \ifmonospace\else\tt\fi + #1}\null} % @clicksequence{File @click{} Open ...} \def\clicksequence#1{\begingroup #1\endgroup} @@ -2854,6 +2854,9 @@ } } +% ctrl is no longer a Texinfo command, but leave this definition for fun. +\def\ctrl #1{{\tt \rawbackslash \hat}#1} + % @inlinefmt{FMTNAME,PROCESSED-TEXT} and @inlineraw{FMTNAME,RAW-TEXT}. % Ignore unless FMTNAME == tex; then it is like @iftex and @tex, % except specified as a normal braced arg, so no newlines to worry about. @@ -3144,12 +3147,17 @@ % hopefully nobody will notice/care. \edef\ecsize{\csname\curfontsize ecsize\endcsname}% \edef\nominalsize{\csname\curfontsize nominalsize\endcsname}% - \ifx\curfontstyle\bfstylename - % bold: - \font\thisecfont = ecb\ifusingit{i}{x}\ecsize \space at \nominalsize + \ifmonospace + % typewriter: + \font\thisecfont = ectt\ecsize \space at \nominalsize \else - % regular: - \font\thisecfont = ec\ifusingit{ti}{rm}\ecsize \space at \nominalsize + \ifx\curfontstyle\bfstylename + % bold: + \font\thisecfont = ecb\ifusingit{i}{x}\ecsize \space at \nominalsize + \else + % regular: + \font\thisecfont = ec\ifusingit{ti}{rm}\ecsize \space at \nominalsize + \fi \fi \thisecfont } @@ -3262,6 +3270,20 @@ \finishedtitlepagetrue } +% Settings used for typesetting titles: no hyphenation, no indentation, +% don't worry much about spacing, ragged right. This should be used +% inside a \vbox, and fonts need to be set appropriately first. Because +% it is always used for titles, nothing else, we call \rmisbold. \par +% should be specified before the end of the \vbox, since a vbox is a group. +% +\def\raggedtitlesettings{% + \rmisbold + \hyphenpenalty=10000 + \parindent=0pt + \tolerance=5000 + \ptexraggedright +} + % Macros to be used within @titlepage: \let\subtitlerm=\tenrm @@ -3269,7 +3291,7 @@ \parseargdef\title{% \checkenv\titlepage - \leftline{\titlefonts\rmisbold #1} + \vbox{\titlefonts \raggedtitlesettings #1\par}% % print a rule at the page bottom also. \finishedtitlepagefalse \vskip4pt \hrule height 4pt width \hsize \vskip4pt @@ -4166,7 +4188,7 @@ % ..., but we might end up with active ones in the argument if % we're called from @code, as @code{@value{foo-bar_}}, though. % So \let them to their normal equivalents. - \let-\realdash \let_\normalunderscore + \let-\normaldash \let_\normalunderscore } } @@ -4206,7 +4228,7 @@ } \def\ifsetfail{\doignore{ifset}} -% @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been +% @ifclear VAR ... @end executes the `...' iff VAR has never been % defined with @set, or has been undefined with @clear. % % The `\else' inside the `\doifset' parameter is a trick to reuse the @@ -4217,6 +4239,35 @@ \def\ifclear{\parsearg{\doifset{\else \let\next=\ifclearfail}}} \def\ifclearfail{\doignore{ifclear}} +% @ifcommandisdefined CMD ... @end executes the `...' if CMD (written +% without the @) is in fact defined. We can only feasibly check at the +% TeX level, so something like `mathcode' is going to considered +% defined even though it is not a Texinfo command. +% +\makecond{ifcommanddefined} +\def\ifcommanddefined{\parsearg{\doifcmddefined{\let\next=\ifcmddefinedfail}}} +% +\def\doifcmddefined#1#2{{% + \makevalueexpandable + \let\next=\empty + \expandafter\ifx\csname #2\endcsname\relax + #1% If not defined, \let\next as above. + \fi + \expandafter + }\next +} +\def\ifcmddefinedfail{\doignore{ifcommanddefined}} + +% @ifcommandnotdefined CMD ... handled similar to @ifclear above. +\makecond{ifcommandnotdefined} +\def\ifcommandnotdefined{% + \parsearg{\doifcmddefined{\else \let\next=\ifcmdnotdefinedfail}}} +\def\ifcmdnotdefinedfail{\doignore{ifcommandnotdefined}} + +% Set the `txicommandconditionals' variable, so documents have a way to +% test if the @ifcommand...defined conditionals are available. +\set txicommandconditionals + % @dircategory CATEGORY -- specify a category of the dir file % which this file should belong to. Ignore this in TeX. \let\dircategory=\comment @@ -5543,14 +5594,6 @@ % Define @majorheading, @heading and @subheading -% NOTE on use of \vbox for chapter headings, section headings, and such: -% 1) We use \vbox rather than the earlier \line to permit -% overlong headings to fold. -% 2) \hyphenpenalty is set to 10000 because hyphenation in a -% heading is obnoxious; this forbids it. -% 3) Likewise, headings look best if no \parindent is used, and -% if justification is not attempted. Hence \raggedright. - \def\majorheading{% {\advance\chapheadingskip by 10pt \chapbreak }% \parsearg\chapheadingzzz @@ -5558,10 +5601,8 @@ \def\chapheading{\chapbreak \parsearg\chapheadingzzz} \def\chapheadingzzz#1{% - {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 - \parindent=0pt\ptexraggedright - \rmisbold #1\hfill}}% - \bigskip \par\penalty 200\relax + \vbox{\chapfonts \raggedtitlesettings #1\par}% + \nobreak\bigskip \nobreak \suppressfirstparagraphindent } @@ -5720,8 +5761,7 @@ % % Typeset the actual heading. \nobreak % Avoid page breaks at the interline glue. - \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \ptexraggedright - \hangindent=\wd0 \centerparametersmaybe + \vbox{\raggedtitlesettings \hangindent=\wd0 \centerparametersmaybe \unhbox0 #1\par}% }% \nobreak\bigskip % no page break after a chapter title @@ -5743,18 +5783,18 @@ \def\setchapterstyle #1 {\csname CHAPF#1\endcsname} % \def\unnchfopen #1{% -\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 - \parindent=0pt\ptexraggedright - \rmisbold #1\hfill}}\bigskip \par\nobreak + \chapoddpage + \vbox{\chapfonts \raggedtitlesettings #1\par}% + \nobreak\bigskip\nobreak } \def\chfopen #1#2{\chapoddpage {\chapfonts \vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}% \par\penalty 5000 % } \def\centerchfopen #1{% -\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 - \parindent=0pt - \hfill {\rmisbold #1}\hfill}}\bigskip \par\nobreak + \chapoddpage + \vbox{\chapfonts \raggedtitlesettings \hfill #1\hfill}% + \nobreak\bigskip \nobreak } \def\CHAPFopen{% \global\let\chapmacro=\chfopen @@ -6520,16 +6560,9 @@ \makedispenvdef{quotation}{\quotationstart} % \def\quotationstart{% - {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip - \parindent=0pt - % - % @cartouche defines \nonarrowing to inhibit narrowing at next level down. + \indentedblockstart % same as \indentedblock, but increase right margin too. \ifx\nonarrowing\relax - \advance\leftskip by \lispnarrowing \advance\rightskip by \lispnarrowing - \exdentamount = \lispnarrowing - \else - \let\nonarrowing = \relax \fi \parsearg\quotationlabel } @@ -6555,6 +6588,32 @@ \fi } +% @indentedblock is like @quotation, but indents only on the left and +% has no optional argument. +% +\makedispenvdef{indentedblock}{\indentedblockstart} +% +\def\indentedblockstart{% + {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip + \parindent=0pt + % + % @cartouche defines \nonarrowing to inhibit narrowing at next level down. + \ifx\nonarrowing\relax + \advance\leftskip by \lispnarrowing + \exdentamount = \lispnarrowing + \else + \let\nonarrowing = \relax + \fi +} + +% Keep a nonzero parskip for the environment, since we're doing normal filling. +% +\def\Eindentedblock{% + \par + {\parskip=0pt \afterenvbreak}% +} +\def\Esmallindentedblock{\Eindentedblock} + % LaTeX-like @verbatim...@end verbatim and @verb{...} % If we want to allow any as delimiter, @@ -7033,7 +7092,10 @@ \df \sl \hyphenchar\font=0 % % On the other hand, if an argument has two dashes (for instance), we - % want a way to get ttsl. Let's try @var for that. + % want a way to get ttsl. We used to recommend @var for that, so + % leave the code in, but it's strange for @var to lead to typewriter. + % Nowadays we recommend @code, since the difference between a ttsl hyphen + % and a tt hyphen is pretty tiny. @code also disables ?` !`. \def\var##1{{\setupmarkupstyle{var}\ttslanted{##1}}}% #1% \sl\hyphenchar\font=45 @@ -9931,22 +9993,26 @@ @gdef@otherbackslash{@let\=@realbackslash} % Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of -% the literal character `\'. -% -@def@normalturnoffactive{% - @let"=@normaldoublequote - @let$=@normaldollar %$ font-lock fix - @let+=@normalplus - @let<=@normalless - @let>=@normalgreater - @let\=@normalbackslash - @let^=@normalcaret - @let_=@normalunderscore - @let|=@normalverticalbar - @let~=@normaltilde - @markupsetuplqdefault - @markupsetuprqdefault - @unsepspaces +% the literal character `\'. Also revert - to its normal character, in +% case the active - from code has slipped in. +% +{@catcode`- = @active + @gdef@normalturnoffactive{% + @let-=@normaldash + @let"=@normaldoublequote + @let$=@normaldollar %$ font-lock fix + @let+=@normalplus + @let<=@normalless + @let>=@normalgreater + @let\=@normalbackslash + @let^=@normalcaret + @let_=@normalunderscore + @let|=@normalverticalbar + @let~=@normaltilde + @markupsetuplqdefault + @markupsetuprqdefault + @unsepspaces + } } % Make _ and + \other characters, temporarily. diff --git a/Modules/_ctypes/libffi_msvc/ffi.c b/Modules/_ctypes/libffi_msvc/ffi.c index 6e595e9fe741..b7586c70ebc1 100644 --- a/Modules/_ctypes/libffi_msvc/ffi.c +++ b/Modules/_ctypes/libffi_msvc/ffi.c @@ -65,43 +65,71 @@ void ffi_prep_args(char *stack, extended_cif *ecif) argp = (char *) ALIGN(argp, sizeof(void *)); z = (*p_arg)->size; - if (z < sizeof(int)) + if (z < sizeof(intptr_t)) { - z = sizeof(int); + z = sizeof(intptr_t); switch ((*p_arg)->type) { case FFI_TYPE_SINT8: - *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv); + *(intptr_t *) argp = (intptr_t)*(SINT8 *)(* p_argv); break; case FFI_TYPE_UINT8: - *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv); + *(uintptr_t *) argp = (uintptr_t)*(UINT8 *)(* p_argv); break; case FFI_TYPE_SINT16: - *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv); + *(intptr_t *) argp = (intptr_t)*(SINT16 *)(* p_argv); break; case FFI_TYPE_UINT16: - *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv); + *(uintptr_t *) argp = (uintptr_t)*(UINT16 *)(* p_argv); break; case FFI_TYPE_SINT32: - *(signed int *) argp = (signed int)*(SINT32 *)(* p_argv); + *(intptr_t *) argp = (intptr_t)*(SINT32 *)(* p_argv); break; case FFI_TYPE_UINT32: - *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); + *(uintptr_t *) argp = (uintptr_t)*(UINT32 *)(* p_argv); + break; + + case FFI_TYPE_FLOAT: + *(uintptr_t *) argp = 0; + *(float *) argp = *(float *)(* p_argv); + break; + + // 64-bit value cases should never be used for x86 and AMD64 builds + case FFI_TYPE_SINT64: + *(intptr_t *) argp = (intptr_t)*(SINT64 *)(* p_argv); + break; + + case FFI_TYPE_UINT64: + *(uintptr_t *) argp = (uintptr_t)*(UINT64 *)(* p_argv); break; case FFI_TYPE_STRUCT: - *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); + *(uintptr_t *) argp = (uintptr_t)*(UINT32 *)(* p_argv); + break; + + case FFI_TYPE_DOUBLE: + *(uintptr_t *) argp = 0; + *(double *) argp = *(double *)(* p_argv); break; default: FFI_ASSERT(0); } } +#ifdef _WIN64 + else if (z > 8) + { + /* On Win64, if a single argument takes more than 8 bytes, + then it is always passed by reference. */ + *(void **)argp = *p_argv; + z = 8; + } +#endif else { memcpy(argp, *p_argv, z); @@ -124,7 +152,6 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) switch (cif->rtype->type) { case FFI_TYPE_VOID: - case FFI_TYPE_STRUCT: case FFI_TYPE_SINT64: case FFI_TYPE_FLOAT: case FFI_TYPE_DOUBLE: @@ -132,6 +159,18 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) cif->flags = (unsigned) cif->rtype->type; break; + case FFI_TYPE_STRUCT: + /* MSVC returns small structures in registers. Put in cif->flags + the value FFI_TYPE_STRUCT only if the structure is big enough; + otherwise, put the 4- or 8-bytes integer type. */ + if (cif->rtype->size <= 4) + cif->flags = FFI_TYPE_INT; + else if (cif->rtype->size <= 8) + cif->flags = FFI_TYPE_SINT64; + else + cif->flags = FFI_TYPE_STRUCT; + break; + case FFI_TYPE_UINT64: #ifdef _WIN64 case FFI_TYPE_POINTER: @@ -201,8 +240,7 @@ ffi_call(/*@dependent@*/ ffi_cif *cif, #else case FFI_SYSV: /*@-usedef@*/ - /* Function call needs at least 40 bytes stack size, on win64 AMD64 */ - return ffi_call_AMD64(ffi_prep_args, &ecif, cif->bytes ? cif->bytes : 40, + return ffi_call_AMD64(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue, fn); /*@=usedef@*/ break; @@ -227,7 +265,7 @@ void * #else static void __fastcall #endif -ffi_closure_SYSV (ffi_closure *closure, int *argp) +ffi_closure_SYSV (ffi_closure *closure, char *argp) { // this is our return value storage long double res; @@ -237,7 +275,7 @@ ffi_closure_SYSV (ffi_closure *closure, int *argp) void **arg_area; unsigned short rtype; void *resp = (void*)&res; - void *args = &argp[1]; + void *args = argp + sizeof(void*); cif = closure->cif; arg_area = (void**) alloca (cif->nargs * sizeof (void*)); diff --git a/Modules/_ctypes/libffi_msvc/prep_cif.c b/Modules/_ctypes/libffi_msvc/prep_cif.c index 2650fa05254e..b07a2e6db271 100644 --- a/Modules/_ctypes/libffi_msvc/prep_cif.c +++ b/Modules/_ctypes/libffi_msvc/prep_cif.c @@ -116,9 +116,9 @@ ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif, #if !defined M68K && !defined __x86_64__ && !defined S390 /* Make space for the return structure pointer */ if (cif->rtype->type == FFI_TYPE_STRUCT - /* MSVC returns small structures in registers. But we have a different - workaround: pretend int32 or int64 return type, and converting to - structure afterwards. */ +#ifdef _WIN32 + && (cif->rtype->size > 8) /* MSVC returns small structs in registers */ +#endif #ifdef SPARC && (cif->abi != FFI_V9 || cif->rtype->size > 32) #endif @@ -145,6 +145,10 @@ ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif, && cif->abi != FFI_V9)) bytes += sizeof(void*); else +#elif defined (_WIN64) + if ((*ptr)->type == FFI_TYPE_STRUCT && ((*ptr)->size > 8)) + bytes += sizeof(void*); + else #endif { #if !defined(_MSC_VER) && !defined(__MINGW32__) @@ -168,6 +172,12 @@ ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif, #endif } +#ifdef _WIN64 + /* Function call needs at least 40 bytes stack size, on win64 AMD64 */ + if (bytes < 40) + bytes = 40; +#endif + cif->bytes = bytes; /* Perform machine dependent cif processing */ diff --git a/Modules/_ctypes/libffi_msvc/types.c b/Modules/_ctypes/libffi_msvc/types.c index df32190d115b..4433ac28c8c8 100644 --- a/Modules/_ctypes/libffi_msvc/types.c +++ b/Modules/_ctypes/libffi_msvc/types.c @@ -43,7 +43,7 @@ FFI_INTEGRAL_TYPEDEF(sint32, 4, 4, FFI_TYPE_SINT32); FFI_INTEGRAL_TYPEDEF(float, 4, 4, FFI_TYPE_FLOAT); #if defined ALPHA || defined SPARC64 || defined X86_64 || defined S390X \ - || defined IA64 + || defined IA64 || defined _WIN64 FFI_INTEGRAL_TYPEDEF(pointer, 8, 8, FFI_TYPE_POINTER); diff --git a/Modules/_ctypes/stgdict.c b/Modules/_ctypes/stgdict.c index b95b0a423178..879afb8424fc 100644 --- a/Modules/_ctypes/stgdict.c +++ b/Modules/_ctypes/stgdict.c @@ -76,14 +76,18 @@ PyCStgDict_clone(StgDictObject *dst, StgDictObject *src) if (src->format) { dst->format = PyMem_Malloc(strlen(src->format) + 1); - if (dst->format == NULL) + if (dst->format == NULL) { + PyErr_NoMemory(); return -1; + } strcpy(dst->format, src->format); } if (src->shape) { dst->shape = PyMem_Malloc(sizeof(Py_ssize_t) * src->ndim); - if (dst->shape == NULL) + if (dst->shape == NULL) { + PyErr_NoMemory(); return -1; + } memcpy(dst->shape, src->shape, sizeof(Py_ssize_t) * src->ndim); } @@ -380,7 +384,7 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct union_size = 0; total_align = align ? align : 1; stgdict->ffi_type_pointer.type = FFI_TYPE_STRUCT; - stgdict->ffi_type_pointer.elements = PyMem_Malloc(sizeof(ffi_type *) * (basedict->length + len + 1)); + stgdict->ffi_type_pointer.elements = PyMem_New(ffi_type *, basedict->length + len + 1); if (stgdict->ffi_type_pointer.elements == NULL) { PyErr_NoMemory(); return -1; @@ -398,7 +402,7 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct union_size = 0; total_align = 1; stgdict->ffi_type_pointer.type = FFI_TYPE_STRUCT; - stgdict->ffi_type_pointer.elements = PyMem_Malloc(sizeof(ffi_type *) * (len + 1)); + stgdict->ffi_type_pointer.elements = PyMem_New(ffi_type *, len + 1); if (stgdict->ffi_type_pointer.elements == NULL) { PyErr_NoMemory(); return -1; @@ -505,7 +509,12 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct sprintf(buf, "%s:%s:", fieldfmt, fieldname); ptr = stgdict->format; - stgdict->format = _ctypes_alloc_format_string(stgdict->format, buf); + if (dict->shape != NULL) { + stgdict->format = _ctypes_alloc_format_string_with_shape( + dict->ndim, dict->shape, stgdict->format, buf); + } else { + stgdict->format = _ctypes_alloc_format_string(stgdict->format, buf); + } PyMem_Free(ptr); PyMem_Free(buf); diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c index 98b81fef6e22..6b778687e71d 100644 --- a/Modules/_cursesmodule.c +++ b/Modules/_cursesmodule.c @@ -134,11 +134,11 @@ typedef chtype attr_t; /* No attr_t type is available */ #define STRICT_SYSV_CURSES #endif -/*[clinic] +/*[clinic input] module curses -class curses.window -[clinic]*/ -/*[clinic checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ +class curses.window "PyCursesWindowObject *" "&PyCursesWindow_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=88c860abdbb50e0c]*/ /* Definition of exception curses.error */ @@ -555,15 +555,15 @@ PyCursesWindow_Dealloc(PyCursesWindowObject *wo) /* Addch, Addstr, Addnstr */ -/*[clinic] +/*[clinic input] curses.window.addch [ - x: int - X-coordinate. y: int Y-coordinate. + x: int + X-coordinate. ] ch: object @@ -581,16 +581,16 @@ Paint character ch at (y, x) with attributes attr, overwriting any character previously painted at that location. By default, the character position and attributes are the current settings for the window object. -[clinic]*/ +[clinic start generated code]*/ PyDoc_STRVAR(curses_window_addch__doc__, -"addch([x, y,] ch, [attr])\n" +"addch([y, x,] ch, [attr])\n" "Paint character ch at (y, x) with attributes attr.\n" "\n" -" x\n" -" X-coordinate.\n" " y\n" " Y-coordinate.\n" +" x\n" +" X-coordinate.\n" " ch\n" " Character to add.\n" " attr\n" @@ -605,52 +605,53 @@ PyDoc_STRVAR(curses_window_addch__doc__, {"addch", (PyCFunction)curses_window_addch, METH_VARARGS, curses_window_addch__doc__}, static PyObject * -curses_window_addch_impl(PyObject *self, int group_left_1, int x, int y, PyObject *ch, int group_right_1, long attr); +curses_window_addch_impl(PyCursesWindowObject *self, int group_left_1, int y, int x, PyObject *ch, int group_right_1, long attr); static PyObject * -curses_window_addch(PyObject *self, PyObject *args) +curses_window_addch(PyCursesWindowObject *self, PyObject *args) { PyObject *return_value = NULL; int group_left_1 = 0; - int x = 0; int y = 0; + int x = 0; PyObject *ch; int group_right_1 = 0; long attr = 0; - switch (PyTuple_Size(args)) { + switch (PyTuple_GET_SIZE(args)) { case 1: if (!PyArg_ParseTuple(args, "O:addch", &ch)) - return NULL; + goto exit; break; case 2: if (!PyArg_ParseTuple(args, "Ol:addch", &ch, &attr)) - return NULL; + goto exit; group_right_1 = 1; break; case 3: - if (!PyArg_ParseTuple(args, "iiO:addch", &x, &y, &ch)) - return NULL; + if (!PyArg_ParseTuple(args, "iiO:addch", &y, &x, &ch)) + goto exit; group_left_1 = 1; break; case 4: - if (!PyArg_ParseTuple(args, "iiOl:addch", &x, &y, &ch, &attr)) - return NULL; + if (!PyArg_ParseTuple(args, "iiOl:addch", &y, &x, &ch, &attr)) + goto exit; group_right_1 = 1; group_left_1 = 1; break; default: PyErr_SetString(PyExc_TypeError, "curses.window.addch requires 1 to 4 arguments"); - return NULL; + goto exit; } - return_value = curses_window_addch_impl(self, group_left_1, x, y, ch, group_right_1, attr); + return_value = curses_window_addch_impl(self, group_left_1, y, x, ch, group_right_1, attr); +exit: return return_value; } static PyObject * -curses_window_addch_impl(PyObject *self, int group_left_1, int x, int y, PyObject *ch, int group_right_1, long attr) -/*[clinic checksum: 44ed958b891cde91205e584c766e048f3999714f]*/ +curses_window_addch_impl(PyCursesWindowObject *self, int group_left_1, int y, int x, PyObject *ch, int group_right_1, long attr) +/*[clinic end generated code: output=d4b97cc287010c54 input=5a41efb34a2de338]*/ { PyCursesWindowObject *cwself = (PyCursesWindowObject *)self; int coordinates_group = group_left_1; @@ -1414,7 +1415,8 @@ PyCursesWindow_InsCh(PyCursesWindowObject *self, PyObject *args) static PyObject * PyCursesWindow_InCh(PyCursesWindowObject *self, PyObject *args) { - int x, y, rtn; + int x, y; + unsigned long rtn; switch (PyTuple_Size(args)) { case 0: @@ -1429,7 +1431,7 @@ PyCursesWindow_InCh(PyCursesWindowObject *self, PyObject *args) PyErr_SetString(PyExc_TypeError, "inch requires 0 or 2 arguments"); return NULL; } - return PyLong_FromLong((long) rtn); + return PyLong_FromUnsignedLong(rtn); } static PyObject * @@ -2086,8 +2088,6 @@ static PyMethodDef PyCursesWindow_Methods[] = { {"nodelay", (PyCFunction)PyCursesWindow_nodelay, METH_VARARGS}, {"notimeout", (PyCFunction)PyCursesWindow_notimeout, METH_VARARGS}, {"noutrefresh", (PyCFunction)PyCursesWindow_NoOutRefresh, METH_VARARGS}, - /* Backward compatibility alias -- remove in Python 2.3 */ - {"nooutrefresh", (PyCFunction)PyCursesWindow_NoOutRefresh, METH_VARARGS}, {"overlay", (PyCFunction)PyCursesWindow_Overlay, METH_VARARGS}, {"overwrite", (PyCFunction)PyCursesWindow_Overwrite, METH_VARARGS}, @@ -2675,7 +2675,7 @@ PyCurses_KeyName(PyObject *self, PyObject *args) } knp = keyname(ch); - return PyBytes_FromString((knp == NULL) ? "" : (char *)knp); + return PyBytes_FromString((knp == NULL) ? "" : knp); } #endif diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index e4dc1bfa73a8..701c58773b57 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -16,11 +16,11 @@ #include "datetime.h" #undef Py_BUILD_CORE -/*[clinic] +/*[clinic input] module datetime -class datetime.datetime -[clinic]*/ -/*[clinic checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ +class datetime.datetime "PyDateTime_DateTime *" "&PyDateTime_DateTimeType" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=78142cb64b9e98bc]*/ /* We require that C int be at least 32 bits, and use int virtually * everywhere. In just a few cases we use a temp long, where a Python @@ -613,7 +613,7 @@ time_alloc(PyTypeObject *type, Py_ssize_t aware) sizeof(_PyDateTime_BaseTime)); if (self == NULL) return (PyObject *)PyErr_NoMemory(); - PyObject_INIT(self, type); + (void)PyObject_INIT(self, type); return self; } @@ -628,7 +628,7 @@ datetime_alloc(PyTypeObject *type, Py_ssize_t aware) sizeof(_PyDateTime_BaseDateTime)); if (self == NULL) return (PyObject *)PyErr_NoMemory(); - PyObject_INIT(self, type); + (void)PyObject_INIT(self, type); return self; } @@ -897,11 +897,11 @@ call_tzinfo_method(PyObject *tzinfo, char *name, PyObject *tzinfoarg) } } else { - Py_DECREF(offset); PyErr_Format(PyExc_TypeError, "tzinfo.%s() must return None or " "timedelta, not '%.200s'", name, Py_TYPE(offset)->tp_name); + Py_DECREF(offset); return NULL; } @@ -2153,7 +2153,7 @@ delta_new(PyTypeObject *type, PyObject *args, PyObject *kw) * is odd. Note that x is odd when it's last bit is 1. The * code below uses bitwise and operation to check the last * bit. */ - temp = PyNumber_And(x, one); /* temp <- x & 1 */ + temp = PyNumber_And(x, one); /* temp <- x & 1 */ if (temp == NULL) { Py_DECREF(x); goto Done; @@ -2459,7 +2459,7 @@ date_local_from_object(PyObject *cls, PyObject *obj) struct tm *tm; time_t t; - if (_PyTime_ObjectToTime_t(obj, &t) == -1) + if (_PyTime_ObjectToTime_t(obj, &t, _PyTime_ROUND_DOWN) == -1) return NULL; tm = localtime(&t); @@ -3224,10 +3224,10 @@ timezone_richcompare(PyDateTime_TimeZone *self, if (op != Py_EQ && op != Py_NE) Py_RETURN_NOTIMPLEMENTED; if (Py_TYPE(other) != &PyDateTime_TimeZoneType) { - if (op == Py_EQ) - Py_RETURN_FALSE; - else - Py_RETURN_TRUE; + if (op == Py_EQ) + Py_RETURN_FALSE; + else + Py_RETURN_TRUE; } return delta_richcompare(self->offset, other->offset, op); } @@ -3805,29 +3805,6 @@ time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw) return clone; } -static int -time_bool(PyObject *self) -{ - PyObject *offset, *tzinfo; - int offsecs = 0; - - if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) { - /* Since utcoffset is in whole minutes, nothing can - * alter the conclusion that this is nonzero. - */ - return 1; - } - tzinfo = GET_TIME_TZINFO(self); - if (tzinfo != Py_None) { - offset = call_utcoffset(tzinfo, Py_None); - if (offset == NULL) - return -1; - offsecs = GET_TD_DAYS(offset)*86400 + GET_TD_SECONDS(offset); - Py_DECREF(offset); - } - return (TIME_GET_MINUTE(self)*60 - offsecs + TIME_GET_HOUR(self)*3600) != 0; -} - /* Pickle support, a simple use of __reduce__. */ /* Let basestate be the non-tzinfo data string. @@ -3895,19 +3872,6 @@ PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time All arguments are optional. tzinfo may be None, or an instance of\n\ a tzinfo subclass. The remaining arguments may be ints.\n"); -static PyNumberMethods time_as_number = { - 0, /* nb_add */ - 0, /* nb_subtract */ - 0, /* nb_multiply */ - 0, /* nb_remainder */ - 0, /* nb_divmod */ - 0, /* nb_power */ - 0, /* nb_negative */ - 0, /* nb_positive */ - 0, /* nb_absolute */ - (inquiry)time_bool, /* nb_bool */ -}; - static PyTypeObject PyDateTime_TimeType = { PyVarObject_HEAD_INIT(NULL, 0) "datetime.time", /* tp_name */ @@ -3919,7 +3883,7 @@ static PyTypeObject PyDateTime_TimeType = { 0, /* tp_setattr */ 0, /* tp_reserved */ (reprfunc)time_repr, /* tp_repr */ - &time_as_number, /* tp_as_number */ + 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ (hashfunc)time_hash, /* tp_hash */ @@ -4127,7 +4091,7 @@ datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp, time_t timet; long us; - if (_PyTime_ObjectToTimeval(timestamp, &timet, &us) == -1) + if (_PyTime_ObjectToTimeval(timestamp, &timet, &us, _PyTime_ROUND_DOWN) == -1) return NULL; return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo); } @@ -4145,7 +4109,7 @@ datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo) tzinfo); } -/*[clinic] +/*[clinic input] @classmethod datetime.datetime.now @@ -4156,10 +4120,12 @@ datetime.datetime.now Returns new datetime object representing current time local to tz. If no tz is specified, uses local timezone. -[clinic]*/ +[clinic start generated code]*/ PyDoc_STRVAR(datetime_datetime_now__doc__, -"now(tz=None)\n" +"now($type, /, tz=None)\n" +"--\n" +"\n" "Returns new datetime object representing current time local to tz.\n" "\n" " tz\n" @@ -4171,10 +4137,10 @@ PyDoc_STRVAR(datetime_datetime_now__doc__, {"now", (PyCFunction)datetime_datetime_now, METH_VARARGS|METH_KEYWORDS|METH_CLASS, datetime_datetime_now__doc__}, static PyObject * -datetime_datetime_now_impl(PyTypeObject *cls, PyObject *tz); +datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz); static PyObject * -datetime_datetime_now(PyTypeObject *cls, PyObject *args, PyObject *kwargs) +datetime_datetime_now(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; static char *_keywords[] = {"tz", NULL}; @@ -4184,15 +4150,15 @@ datetime_datetime_now(PyTypeObject *cls, PyObject *args, PyObject *kwargs) "|O:now", _keywords, &tz)) goto exit; - return_value = datetime_datetime_now_impl(cls, tz); + return_value = datetime_datetime_now_impl(type, tz); exit: return return_value; } static PyObject * -datetime_datetime_now_impl(PyTypeObject *cls, PyObject *tz) -/*[clinic checksum: ca3d26a423b3f633b260c7622e303f0915a96f7c]*/ +datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz) +/*[clinic end generated code: output=583c5637e3c843fa input=80d09869c5267d00]*/ { PyObject *self; @@ -4202,7 +4168,7 @@ datetime_datetime_now_impl(PyTypeObject *cls, PyObject *tz) if (check_tzinfo_subclass(tz) < 0) return NULL; - self = datetime_best_possible((PyObject *)cls, + self = datetime_best_possible((PyObject *)type, tz == Py_None ? localtime : gmtime, tz); if (self != NULL && tz != Py_None) { @@ -4812,7 +4778,7 @@ datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw) static char *keywords[] = {"tz", NULL}; if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:astimezone", keywords, - &tzinfo)) + &tzinfo)) return NULL; if (check_tzinfo_subclass(tzinfo) == -1) diff --git a/Modules/_dbmmodule.c b/Modules/_dbmmodule.c index 10f8fb939ee2..93ea4161a7f4 100644 --- a/Modules/_dbmmodule.c +++ b/Modules/_dbmmodule.c @@ -28,11 +28,11 @@ static char *which_dbm = "Berkeley DB"; #error "No ndbm.h available!" #endif -/*[clinic] +/*[clinic input] module dbm -class dbm.dbm -[clinic]*/ -/*[clinic checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ +class dbm.dbm "dbmobject *" "&Dbmtype" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=92450564684a69a3]*/ typedef struct { PyObject_HEAD @@ -49,13 +49,14 @@ static PyTypeObject Dbmtype; static PyObject *DbmError; -/*[python] +/*[python input] class dbmobject_converter(self_converter): type = "dbmobject *" - def converter_init(self): + def pre_render(self): + super().pre_render() self.name = 'dp' -[python]*/ -/*[python checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=6ad536357913879a]*/ static PyObject * newdbmobject(const char *file, int flags, int mode) @@ -66,7 +67,8 @@ newdbmobject(const char *file, int flags, int mode) if (dp == NULL) return NULL; dp->di_size = -1; - if ( (dp->di_dbm = dbm_open(file, flags, mode)) == 0 ) { + /* See issue #19296 */ + if ( (dp->di_dbm = dbm_open((char *)file, flags, mode)) == 0 ) { PyErr_SetFromErrno(DbmError); Py_DECREF(dp); return NULL; @@ -262,67 +264,55 @@ static PySequenceMethods dbm_as_sequence = { 0, /* sq_inplace_repeat */ }; -/*[clinic] +/*[clinic input] dbm.dbm.get self: dbmobject key: str(length=True) - [ - default: object - ] + default: object = None / Return the value for key if present, otherwise default. -[clinic]*/ +[clinic start generated code]*/ PyDoc_STRVAR(dbm_dbm_get__doc__, -"get(key, [default])\n" +"get($self, key, default=None, /)\n" +"--\n" +"\n" "Return the value for key if present, otherwise default."); #define DBM_DBM_GET_METHODDEF \ {"get", (PyCFunction)dbm_dbm_get, METH_VARARGS, dbm_dbm_get__doc__}, static PyObject * -dbm_dbm_get_impl(dbmobject *dp, const char *key, Py_ssize_clean_t key_length, int group_right_1, PyObject *default_value); +dbm_dbm_get_impl(dbmobject *dp, const char *key, Py_ssize_clean_t key_length, PyObject *default_value); static PyObject * -dbm_dbm_get(PyObject *self, PyObject *args) +dbm_dbm_get(dbmobject *dp, PyObject *args) { PyObject *return_value = NULL; const char *key; Py_ssize_clean_t key_length; - int group_right_1 = 0; - PyObject *default_value = NULL; - - switch (PyTuple_Size(args)) { - case 1: - if (!PyArg_ParseTuple(args, "s#:get", &key, &key_length)) - return NULL; - break; - case 2: - if (!PyArg_ParseTuple(args, "s#O:get", &key, &key_length, &default_value)) - return NULL; - group_right_1 = 1; - break; - default: - PyErr_SetString(PyExc_TypeError, "dbm.dbm.get requires 1 to 2 arguments"); - return NULL; - } - return_value = dbm_dbm_get_impl((dbmobject *)self, key, key_length, group_right_1, default_value); + PyObject *default_value = Py_None; + + if (!PyArg_ParseTuple(args, + "s#|O:get", + &key, &key_length, &default_value)) + goto exit; + return_value = dbm_dbm_get_impl(dp, key, key_length, default_value); +exit: return return_value; } static PyObject * -dbm_dbm_get_impl(dbmobject *dp, const char *key, Py_ssize_clean_t key_length, int group_right_1, PyObject *default_value) -/*[clinic checksum: 28cf8928811bde51e535d67ae98ea039d79df717]*/ +dbm_dbm_get_impl(dbmobject *dp, const char *key, Py_ssize_clean_t key_length, PyObject *default_value) +/*[clinic end generated code: output=452ea11394e7e92d input=aecf5efd2f2b1a3b]*/ { datum dbm_key, val; - if (!group_right_1) - default_value = Py_None; dbm_key.dptr = (char *)key; dbm_key.dsize = key_length; check_dbmobject_open(dp); @@ -439,7 +429,7 @@ static PyTypeObject Dbmtype = { /* ----------------------------------------------------------------- */ -/*[clinic] +/*[clinic input] dbm.open as dbmopen @@ -449,7 +439,7 @@ dbm.open as dbmopen flags: str="r" How to open the file. "r" for reading, "w" for writing, etc. - mode: int(doc_default="0o666") = 0o666 + mode: int(py_default="0o666") = 0o666 If creating a new file, the mode bits for the new file (e.g. os.O_RDWR). @@ -457,10 +447,12 @@ dbm.open as dbmopen Return a database object. -[clinic]*/ +[clinic start generated code]*/ PyDoc_STRVAR(dbmopen__doc__, -"open(filename, flags=\'r\', mode=0o666)\n" +"open($module, filename, flags=\'r\', mode=0o666, /)\n" +"--\n" +"\n" "Return a database object.\n" "\n" " filename\n" @@ -497,7 +489,7 @@ dbmopen(PyModuleDef *module, PyObject *args) static PyObject * dbmopen_impl(PyModuleDef *module, const char *filename, const char *flags, int mode) -/*[clinic checksum: fb265f75641553ccd963f84c143b35c11f9121fc]*/ +/*[clinic end generated code: output=9a7b725f9c4dcec2 input=6499ab0fab1333ac]*/ { int iflags; diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index ac20308953a7..169914c2f749 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -39,8 +39,8 @@ #include "memory.h" -#if MPD_MAJOR_VERSION != 2 - #error "libmpdec major version 2 required" +#if !defined(MPD_VERSION_HEX) || MPD_VERSION_HEX < 0x02040100 + #error "libmpdec version >= 2.4.1 required" #endif @@ -3542,7 +3542,7 @@ PyDec_Round(PyObject *dec, PyObject *args) } } -static PyObject *DecimalTuple = NULL; +static PyTypeObject *DecimalTuple = NULL; /* Return the DecimalTuple representation of a PyDecObject. */ static PyObject * PyDec_AsTuple(PyObject *dec, PyObject *dummy UNUSED) @@ -3625,7 +3625,7 @@ PyDec_AsTuple(PyObject *dec, PyObject *dummy UNUSED) } } - result = PyObject_CallFunctionObjArgs(DecimalTuple, + result = PyObject_CallFunctionObjArgs((PyObject *)DecimalTuple, sign, coeff, expt, NULL); out: @@ -3928,9 +3928,6 @@ nm_mpd_qdivmod(PyObject *v, PyObject *w) return ret; } -static mpd_uint_t data_zero[1] = {0}; -static const mpd_t zero = {MPD_STATIC|MPD_CONST_DATA, 0, 1, 1, 1, data_zero}; - static PyObject * nm_mpd_qpow(PyObject *base, PyObject *exp, PyObject *mod) { @@ -5565,9 +5562,14 @@ PyInit__decimal(void) /* DecimalTuple */ ASSIGN_PTR(collections, PyImport_ImportModule("collections")); - ASSIGN_PTR(DecimalTuple, PyObject_CallMethod(collections, + ASSIGN_PTR(DecimalTuple, (PyTypeObject *)PyObject_CallMethod(collections, "namedtuple", "(ss)", "DecimalTuple", "sign digits exponent")); + + ASSIGN_PTR(obj, PyUnicode_FromString("decimal")); + CHECK_INT(PyDict_SetItemString(DecimalTuple->tp_dict, "__module__", obj)); + Py_CLEAR(obj); + /* MutableMapping */ ASSIGN_PTR(MutableMapping, PyObject_GetAttrString(collections, "MutableMapping")); @@ -5594,7 +5596,7 @@ PyInit__decimal(void) CHECK_INT(PyModule_AddObject(m, "Context", (PyObject *)&PyDecContext_Type)); Py_INCREF(DecimalTuple); - CHECK_INT(PyModule_AddObject(m, "DecimalTuple", DecimalTuple)); + CHECK_INT(PyModule_AddObject(m, "DecimalTuple", (PyObject *)DecimalTuple)); /* Create top level exception */ @@ -5638,7 +5640,7 @@ PyInit__decimal(void) goto error; /* GCOV_NOT_REACHED */ } - ASSIGN_PTR(cm->ex, PyErr_NewException((char *)cm->fqname, base, NULL)); + ASSIGN_PTR(cm->ex, PyErr_NewException(cm->fqname, base, NULL)); Py_DECREF(base); /* add to module */ @@ -5670,7 +5672,7 @@ PyInit__decimal(void) goto error; /* GCOV_NOT_REACHED */ } - ASSIGN_PTR(cm->ex, PyErr_NewException((char *)cm->fqname, base, NULL)); + ASSIGN_PTR(cm->ex, PyErr_NewException(cm->fqname, base, NULL)); Py_DECREF(base); Py_INCREF(cm->ex); diff --git a/Modules/_decimal/docstrings.h b/Modules/_decimal/docstrings.h index a6490b982a3a..71029a994bbe 100644 --- a/Modules/_decimal/docstrings.h +++ b/Modules/_decimal/docstrings.h @@ -19,26 +19,30 @@ PyDoc_STRVAR(doc__decimal, "C decimal arithmetic module"); -PyDoc_STRVAR(doc_getcontext,"\n\ -getcontext() - Get the current default context.\n\ +PyDoc_STRVAR(doc_getcontext, +"getcontext($module, /)\n--\n\n\ +Get the current default context.\n\ \n"); -PyDoc_STRVAR(doc_setcontext,"\n\ -setcontext(c) - Set a new default context.\n\ +PyDoc_STRVAR(doc_setcontext, +"setcontext($module, context, /)\n--\n\n\ +Set a new default context.\n\ \n"); -PyDoc_STRVAR(doc_localcontext,"\n\ -localcontext(ctx=None) - Return a context manager that will set the default\n\ -context to a copy of ctx on entry to the with-statement and restore the\n\ -previous default context when exiting the with-statement. If no context is\n\ -specified, a copy of the current default context is used.\n\ +PyDoc_STRVAR(doc_localcontext, +"localcontext($module, /, ctx=None)\n--\n\n\ +Return a context manager that will set the default context to a copy of ctx\n\ +on entry to the with-statement and restore the previous default context when\n\ +exiting the with-statement. If no context is specified, a copy of the current\n\ +default context is used.\n\ \n"); #ifdef EXTRA_FUNCTIONALITY -PyDoc_STRVAR(doc_ieee_context,"\n\ -IEEEContext(bits) - Return a context object initialized to the proper values for\n\ -one of the IEEE interchange formats. The argument must be a multiple of 32 and\n\ -less than IEEE_CONTEXT_MAX_BITS. For the most common values, the constants\n\ +PyDoc_STRVAR(doc_ieee_context, +"IEEEContext($module, bits, /)\n--\n\n\ +Return a context object initialized to the proper values for one of the\n\ +IEEE interchange formats. The argument must be a multiple of 32 and less\n\ +than IEEE_CONTEXT_MAX_BITS. For the most common values, the constants\n\ DECIMAL32, DECIMAL64 and DECIMAL128 are provided.\n\ \n"); #endif @@ -48,32 +52,34 @@ DECIMAL32, DECIMAL64 and DECIMAL128 are provided.\n\ /* Decimal Object and Methods */ /******************************************************************************/ -PyDoc_STRVAR(doc_decimal,"\n\ -Decimal(value=\"0\", context=None): Construct a new Decimal object.\n\ -value can be an integer, string, tuple, or another Decimal object.\n\ -If no value is given, return Decimal('0'). The context does not affect\n\ -the conversion and is only passed to determine if the InvalidOperation\n\ -trap is active.\n\ +PyDoc_STRVAR(doc_decimal, +"Decimal(value=\"0\", context=None)\n--\n\n\ +Construct a new Decimal object. 'value' can be an integer, string, tuple,\n\ +or another Decimal object. If no value is given, return Decimal('0'). The\n\ +context does not affect the conversion and is only passed to determine if\n\ +the InvalidOperation trap is active.\n\ \n"); -PyDoc_STRVAR(doc_adjusted,"\n\ -adjusted() - Return the adjusted exponent of the number.\n\ -\n\ -Defined as exp + digits - 1.\n\ +PyDoc_STRVAR(doc_adjusted, +"adjusted($self, /)\n--\n\n\ +Return the adjusted exponent of the number. Defined as exp + digits - 1.\n\ \n"); -PyDoc_STRVAR(doc_as_tuple,"\n\ -as_tuple() - Return a tuple representation of the number.\n\ +PyDoc_STRVAR(doc_as_tuple, +"as_tuple($self, /)\n--\n\n\ +Return a tuple representation of the number.\n\ \n"); -PyDoc_STRVAR(doc_canonical,"\n\ -canonical() - Return the canonical encoding of the argument. Currently,\n\ -the encoding of a Decimal instance is always canonical, so this operation\n\ -returns its argument unchanged.\n\ +PyDoc_STRVAR(doc_canonical, +"canonical($self, /)\n--\n\n\ +Return the canonical encoding of the argument. Currently, the encoding\n\ +of a Decimal instance is always canonical, so this operation returns its\n\ +argument unchanged.\n\ \n"); -PyDoc_STRVAR(doc_compare,"\n\ -compare(other, context=None) - Compare self to other. Return a decimal value:\n\ +PyDoc_STRVAR(doc_compare, +"compare($self, /, other, context=None)\n--\n\n\ +Compare self to other. Return a decimal value:\n\ \n\ a or b is a NaN ==> Decimal('NaN')\n\ a < b ==> Decimal('-1')\n\ @@ -81,17 +87,18 @@ compare(other, context=None) - Compare self to other. Return a decimal value:\n\ a > b ==> Decimal('1')\n\ \n"); -PyDoc_STRVAR(doc_compare_signal,"\n\ -compare_signal(other, context=None) - Identical to compare, except that\n\ -all NaNs signal.\n\ +PyDoc_STRVAR(doc_compare_signal, +"compare_signal($self, /, other, context=None)\n--\n\n\ +Identical to compare, except that all NaNs signal.\n\ \n"); -PyDoc_STRVAR(doc_compare_total,"\n\ -compare_total(other, context=None) - Compare two operands using their\n\ -abstract representation rather than their numerical value. Similar to the\n\ -compare() method, but the result gives a total ordering on Decimal instances.\n\ -Two Decimal instances with the same numeric value but different representations\n\ -compare unequal in this ordering:\n\ +PyDoc_STRVAR(doc_compare_total, +"compare_total($self, /, other, context=None)\n--\n\n\ +Compare two operands using their abstract representation rather than\n\ +their numerical value. Similar to the compare() method, but the result\n\ +gives a total ordering on Decimal instances. Two Decimal instances with\n\ +the same numeric value but different representations compare unequal\n\ +in this ordering:\n\ \n\ >>> Decimal('12.0').compare_total(Decimal('12'))\n\ Decimal('-1')\n\ @@ -107,36 +114,39 @@ and no rounding is performed. As an exception, the C version may raise\n\ InvalidOperation if the second operand cannot be converted exactly.\n\ \n"); -PyDoc_STRVAR(doc_compare_total_mag,"\n\ -compare_total_mag(other, context=None) - Compare two operands using their\n\ -abstract representation rather than their value as in compare_total(), but\n\ -ignoring the sign of each operand. x.compare_total_mag(y) is equivalent to\n\ -x.copy_abs().compare_total(y.copy_abs()).\n\ +PyDoc_STRVAR(doc_compare_total_mag, +"compare_total_mag($self, /, other, context=None)\n--\n\n\ +Compare two operands using their abstract representation rather than their\n\ +value as in compare_total(), but ignoring the sign of each operand.\n\ +\n\ +x.compare_total_mag(y) is equivalent to x.copy_abs().compare_total(y.copy_abs()).\n\ \n\ This operation is unaffected by context and is quiet: no flags are changed\n\ and no rounding is performed. As an exception, the C version may raise\n\ InvalidOperation if the second operand cannot be converted exactly.\n\ \n"); -PyDoc_STRVAR(doc_conjugate,"\n\ -conjugate() - Return self.\n\ +PyDoc_STRVAR(doc_conjugate, +"conjugate($self, /)\n--\n\n\ +Return self.\n\ \n"); -PyDoc_STRVAR(doc_copy_abs,"\n\ -copy_abs() - Return the absolute value of the argument. This operation\n\ -is unaffected by context and is quiet: no flags are changed and no rounding\n\ -is performed.\n\ +PyDoc_STRVAR(doc_copy_abs, +"copy_abs($self, /)\n--\n\n\ +Return the absolute value of the argument. This operation is unaffected by\n\ +context and is quiet: no flags are changed and no rounding is performed.\n\ \n"); -PyDoc_STRVAR(doc_copy_negate,"\n\ -copy_negate() - Return the negation of the argument. This operation is\n\ -unaffected by context and is quiet: no flags are changed and no rounding\n\ -is performed.\n\ +PyDoc_STRVAR(doc_copy_negate, +"copy_negate($self, /)\n--\n\n\ +Return the negation of the argument. This operation is unaffected by context\n\ +and is quiet: no flags are changed and no rounding is performed.\n\ \n"); -PyDoc_STRVAR(doc_copy_sign,"\n\ -copy_sign(other, context=None) - Return a copy of the first operand with\n\ -the sign set to be the same as the sign of the second operand. For example:\n\ +PyDoc_STRVAR(doc_copy_sign, +"copy_sign($self, /, other, context=None)\n--\n\n\ +Return a copy of the first operand with the sign set to be the same as the\n\ +sign of the second operand. For example:\n\ \n\ >>> Decimal('2.3').copy_sign(Decimal('-1.5'))\n\ Decimal('-2.3')\n\ @@ -146,14 +156,16 @@ and no rounding is performed. As an exception, the C version may raise\n\ InvalidOperation if the second operand cannot be converted exactly.\n\ \n"); -PyDoc_STRVAR(doc_exp,"\n\ -exp(context=None) - Return the value of the (natural) exponential function\n\ -e**x at the given number. The function always uses the ROUND_HALF_EVEN mode\n\ -and the result is correctly rounded.\n\ +PyDoc_STRVAR(doc_exp, +"exp($self, /, context=None)\n--\n\n\ +Return the value of the (natural) exponential function e**x at the given\n\ +number. The function always uses the ROUND_HALF_EVEN mode and the result\n\ +is correctly rounded.\n\ \n"); -PyDoc_STRVAR(doc_from_float,"\n\ -from_float(f) - Class method that converts a float to a decimal number, exactly.\n\ +PyDoc_STRVAR(doc_from_float, +"from_float($type, f, /)\n--\n\n\ +Class method that converts a float to a decimal number, exactly.\n\ Since 0.1 is not exactly representable in binary floating point,\n\ Decimal.from_float(0.1) is not the same as Decimal('0.1').\n\ \n\ @@ -168,155 +180,176 @@ Decimal.from_float(0.1) is not the same as Decimal('0.1').\n\ \n\ \n"); -PyDoc_STRVAR(doc_fma,"\n\ -fma(other, third, context=None) - Fused multiply-add. Return self*other+third\n\ -with no rounding of the intermediate product self*other.\n\ +PyDoc_STRVAR(doc_fma, +"fma($self, /, other, third, context=None)\n--\n\n\ +Fused multiply-add. Return self*other+third with no rounding of the\n\ +intermediate product self*other.\n\ \n\ >>> Decimal(2).fma(3, 5)\n\ Decimal('11')\n\ \n\ \n"); -PyDoc_STRVAR(doc_is_canonical,"\n\ -is_canonical() - Return True if the argument is canonical and False otherwise.\n\ -Currently, a Decimal instance is always canonical, so this operation always\n\ -returns True.\n\ +PyDoc_STRVAR(doc_is_canonical, +"is_canonical($self, /)\n--\n\n\ +Return True if the argument is canonical and False otherwise. Currently,\n\ +a Decimal instance is always canonical, so this operation always returns\n\ +True.\n\ \n"); -PyDoc_STRVAR(doc_is_finite,"\n\ -is_finite() - Return True if the argument is a finite number, and False if the\n\ -argument is infinite or a NaN.\n\ +PyDoc_STRVAR(doc_is_finite, +"is_finite($self, /)\n--\n\n\ +Return True if the argument is a finite number, and False if the argument\n\ +is infinite or a NaN.\n\ \n"); -PyDoc_STRVAR(doc_is_infinite,"\n\ -is_infinite() - Return True if the argument is either positive or negative\n\ -infinity and False otherwise.\n\ +PyDoc_STRVAR(doc_is_infinite, +"is_infinite($self, /)\n--\n\n\ +Return True if the argument is either positive or negative infinity and\n\ +False otherwise.\n\ \n"); -PyDoc_STRVAR(doc_is_nan,"\n\ -is_nan() - Return True if the argument is a (quiet or signaling) NaN and\n\ -False otherwise.\n\ +PyDoc_STRVAR(doc_is_nan, +"is_nan($self, /)\n--\n\n\ +Return True if the argument is a (quiet or signaling) NaN and False\n\ +otherwise.\n\ \n"); -PyDoc_STRVAR(doc_is_normal,"\n\ -is_normal(context=None) - Return True if the argument is a normal finite\n\ -non-zero number with an adjusted exponent greater than or equal to Emin.\n\ -Return False if the argument is zero, subnormal, infinite or a NaN.\n\ +PyDoc_STRVAR(doc_is_normal, +"is_normal($self, /, context=None)\n--\n\n\ +Return True if the argument is a normal finite non-zero number with an\n\ +adjusted exponent greater than or equal to Emin. Return False if the\n\ +argument is zero, subnormal, infinite or a NaN.\n\ \n"); -PyDoc_STRVAR(doc_is_qnan,"\n\ -is_qnan() - Return True if the argument is a quiet NaN, and False otherwise.\n\ +PyDoc_STRVAR(doc_is_qnan, +"is_qnan($self, /)\n--\n\n\ +Return True if the argument is a quiet NaN, and False otherwise.\n\ \n"); -PyDoc_STRVAR(doc_is_signed,"\n\ -is_signed() - Return True if the argument has a negative sign and\n\ -False otherwise. Note that both zeros and NaNs can carry signs.\n\ +PyDoc_STRVAR(doc_is_signed, +"is_signed($self, /)\n--\n\n\ +Return True if the argument has a negative sign and False otherwise.\n\ +Note that both zeros and NaNs can carry signs.\n\ \n"); -PyDoc_STRVAR(doc_is_snan,"\n\ -is_snan() - Return True if the argument is a signaling NaN and False otherwise.\n\ +PyDoc_STRVAR(doc_is_snan, +"is_snan($self, /)\n--\n\n\ +Return True if the argument is a signaling NaN and False otherwise.\n\ \n"); -PyDoc_STRVAR(doc_is_subnormal,"\n\ -is_subnormal(context=None) - Return True if the argument is subnormal, and\n\ -False otherwise. A number is subnormal if it is non-zero, finite, and has an\n\ -adjusted exponent less than Emin.\n\ +PyDoc_STRVAR(doc_is_subnormal, +"is_subnormal($self, /, context=None)\n--\n\n\ +Return True if the argument is subnormal, and False otherwise. A number is\n\ +subnormal if it is non-zero, finite, and has an adjusted exponent less\n\ +than Emin.\n\ \n"); -PyDoc_STRVAR(doc_is_zero,"\n\ -is_zero() - Return True if the argument is a (positive or negative) zero and\n\ -False otherwise.\n\ +PyDoc_STRVAR(doc_is_zero, +"is_zero($self, /)\n--\n\n\ +Return True if the argument is a (positive or negative) zero and False\n\ +otherwise.\n\ \n"); -PyDoc_STRVAR(doc_ln,"\n\ -ln(context=None) - Return the natural (base e) logarithm of the operand.\n\ -The function always uses the ROUND_HALF_EVEN mode and the result is\n\ -correctly rounded.\n\ +PyDoc_STRVAR(doc_ln, +"ln($self, /, context=None)\n--\n\n\ +Return the natural (base e) logarithm of the operand. The function always\n\ +uses the ROUND_HALF_EVEN mode and the result is correctly rounded.\n\ \n"); -PyDoc_STRVAR(doc_log10,"\n\ -log10(context=None) - Return the base ten logarithm of the operand.\n\ -The function always uses the ROUND_HALF_EVEN mode and the result is\n\ -correctly rounded.\n\ +PyDoc_STRVAR(doc_log10, +"log10($self, /, context=None)\n--\n\n\ +Return the base ten logarithm of the operand. The function always uses the\n\ +ROUND_HALF_EVEN mode and the result is correctly rounded.\n\ \n"); -PyDoc_STRVAR(doc_logb,"\n\ -logb(context=None) - For a non-zero number, return the adjusted exponent\n\ -of the operand as a Decimal instance. If the operand is a zero, then\n\ -Decimal('-Infinity') is returned and the DivisionByZero condition is\n\ -raised. If the operand is an infinity then Decimal('Infinity') is returned.\n\ +PyDoc_STRVAR(doc_logb, +"logb($self, /, context=None)\n--\n\n\ +For a non-zero number, return the adjusted exponent of the operand as a\n\ +Decimal instance. If the operand is a zero, then Decimal('-Infinity') is\n\ +returned and the DivisionByZero condition is raised. If the operand is\n\ +an infinity then Decimal('Infinity') is returned.\n\ \n"); -PyDoc_STRVAR(doc_logical_and,"\n\ -logical_and(other, context=None) - Return the digit-wise and of the two\n\ -(logical) operands.\n\ +PyDoc_STRVAR(doc_logical_and, +"logical_and($self, /, other, context=None)\n--\n\n\ +Return the digit-wise 'and' of the two (logical) operands.\n\ \n"); -PyDoc_STRVAR(doc_logical_invert,"\n\ -logical_invert(context=None) - Return the digit-wise inversion of the\n\ -(logical) operand.\n\ +PyDoc_STRVAR(doc_logical_invert, +"logical_invert($self, /, context=None)\n--\n\n\ +Return the digit-wise inversion of the (logical) operand.\n\ \n"); -PyDoc_STRVAR(doc_logical_or,"\n\ -logical_or(other, context=None) - Return the digit-wise or of the two\n\ -(logical) operands.\n\ +PyDoc_STRVAR(doc_logical_or, +"logical_or($self, /, other, context=None)\n--\n\n\ +Return the digit-wise 'or' of the two (logical) operands.\n\ \n"); -PyDoc_STRVAR(doc_logical_xor,"\n\ -logical_xor(other, context=None) - Return the digit-wise exclusive or of the\n\ -two (logical) operands.\n\ +PyDoc_STRVAR(doc_logical_xor, +"logical_xor($self, /, other, context=None)\n--\n\n\ +Return the digit-wise 'exclusive or' of the two (logical) operands.\n\ \n"); -PyDoc_STRVAR(doc_max,"\n\ -max(other, context=None) - Maximum of self and other. If one operand is a\n\ -quiet NaN and the other is numeric, the numeric operand is returned.\n\ +PyDoc_STRVAR(doc_max, +"max($self, /, other, context=None)\n--\n\n\ +Maximum of self and other. If one operand is a quiet NaN and the other is\n\ +numeric, the numeric operand is returned.\n\ \n"); -PyDoc_STRVAR(doc_max_mag,"\n\ -max_mag(other, context=None) - Similar to the max() method, but the\n\ -comparison is done using the absolute values of the operands.\n\ +PyDoc_STRVAR(doc_max_mag, +"max_mag($self, /, other, context=None)\n--\n\n\ +Similar to the max() method, but the comparison is done using the absolute\n\ +values of the operands.\n\ \n"); -PyDoc_STRVAR(doc_min,"\n\ -min(other, context=None) - Minimum of self and other. If one operand is a\n\ -quiet NaN and the other is numeric, the numeric operand is returned.\n\ +PyDoc_STRVAR(doc_min, +"min($self, /, other, context=None)\n--\n\n\ +Minimum of self and other. If one operand is a quiet NaN and the other is\n\ +numeric, the numeric operand is returned.\n\ \n"); -PyDoc_STRVAR(doc_min_mag,"\n\ -min_mag(other, context=None) - Similar to the min() method, but the\n\ -comparison is done using the absolute values of the operands.\n\ +PyDoc_STRVAR(doc_min_mag, +"min_mag($self, /, other, context=None)\n--\n\n\ +Similar to the min() method, but the comparison is done using the absolute\n\ +values of the operands.\n\ \n"); -PyDoc_STRVAR(doc_next_minus,"\n\ -next_minus(context=None) - Return the largest number representable in the\n\ -given context (or in the current default context if no context is given) that\n\ -is smaller than the given operand.\n\ +PyDoc_STRVAR(doc_next_minus, +"next_minus($self, /, context=None)\n--\n\n\ +Return the largest number representable in the given context (or in the\n\ +current default context if no context is given) that is smaller than the\n\ +given operand.\n\ \n"); -PyDoc_STRVAR(doc_next_plus,"\n\ -next_plus(context=None) - Return the smallest number representable in the\n\ -given context (or in the current default context if no context is given) that\n\ -is larger than the given operand.\n\ +PyDoc_STRVAR(doc_next_plus, +"next_plus($self, /, context=None)\n--\n\n\ +Return the smallest number representable in the given context (or in the\n\ +current default context if no context is given) that is larger than the\n\ +given operand.\n\ \n"); -PyDoc_STRVAR(doc_next_toward,"\n\ -next_toward(other, context=None) - If the two operands are unequal, return\n\ -the number closest to the first operand in the direction of the second operand.\n\ -If both operands are numerically equal, return a copy of the first operand\n\ -with the sign set to be the same as the sign of the second operand.\n\ +PyDoc_STRVAR(doc_next_toward, +"next_toward($self, /, other, context=None)\n--\n\n\ +If the two operands are unequal, return the number closest to the first\n\ +operand in the direction of the second operand. If both operands are\n\ +numerically equal, return a copy of the first operand with the sign set\n\ +to be the same as the sign of the second operand.\n\ \n"); -PyDoc_STRVAR(doc_normalize,"\n\ -normalize(context=None) - Normalize the number by stripping the rightmost\n\ -trailing zeros and converting any result equal to Decimal('0') to Decimal('0e0').\n\ -Used for producing canonical values for members of an equivalence class. For\n\ -example, Decimal('32.100') and Decimal('0.321000e+2') both normalize to the\n\ -equivalent value Decimal('32.1').\n\ +PyDoc_STRVAR(doc_normalize, +"normalize($self, /, context=None)\n--\n\n\ +Normalize the number by stripping the rightmost trailing zeros and\n\ +converting any result equal to Decimal('0') to Decimal('0e0'). Used\n\ +for producing canonical values for members of an equivalence class.\n\ +For example, Decimal('32.100') and Decimal('0.321000e+2') both normalize\n\ +to the equivalent value Decimal('32.1').\n\ \n"); -PyDoc_STRVAR(doc_number_class,"\n\ -number_class(context=None) - Return a string describing the class of the\n\ -operand. The returned value is one of the following ten strings:\n\ +PyDoc_STRVAR(doc_number_class, +"number_class($self, /, context=None)\n--\n\n\ +Return a string describing the class of the operand. The returned value\n\ +is one of the following ten strings:\n\ \n\ * '-Infinity', indicating that the operand is negative infinity.\n\ * '-Normal', indicating that the operand is a negative normal number.\n\ @@ -331,9 +364,10 @@ operand. The returned value is one of the following ten strings:\n\ \n\ \n"); -PyDoc_STRVAR(doc_quantize,"\n\ -quantize(exp, rounding=None, context=None) - Return a value equal to the\n\ -first operand after rounding and having the exponent of the second operand.\n\ +PyDoc_STRVAR(doc_quantize, +"quantize($self, /, exp, rounding=None, context=None)\n--\n\n\ +Return a value equal to the first operand after rounding and having the\n\ +exponent of the second operand.\n\ \n\ >>> Decimal('1.41421356').quantize(Decimal('1.000'))\n\ Decimal('1.414')\n\ @@ -352,93 +386,98 @@ rounding argument if given, else by the given context argument; if neither\n\ argument is given, the rounding mode of the current thread's context is used.\n\ \n"); -PyDoc_STRVAR(doc_radix,"\n\ -radix() - Return Decimal(10), the radix (base) in which the Decimal class does\n\ +PyDoc_STRVAR(doc_radix, +"radix($self, /)\n--\n\n\ +Return Decimal(10), the radix (base) in which the Decimal class does\n\ all its arithmetic. Included for compatibility with the specification.\n\ \n"); -PyDoc_STRVAR(doc_remainder_near,"\n\ -remainder_near(other, context=None) - Return the remainder from dividing\n\ -self by other. This differs from self % other in that the sign of the\n\ -remainder is chosen so as to minimize its absolute value. More precisely, the\n\ -return value is self - n * other where n is the integer nearest to the exact\n\ -value of self / other, and if two integers are equally near then the even one\n\ -is chosen.\n\ +PyDoc_STRVAR(doc_remainder_near, +"remainder_near($self, /, other, context=None)\n--\n\n\ +Return the remainder from dividing self by other. This differs from\n\ +self % other in that the sign of the remainder is chosen so as to minimize\n\ +its absolute value. More precisely, the return value is self - n * other\n\ +where n is the integer nearest to the exact value of self / other, and\n\ +if two integers are equally near then the even one is chosen.\n\ \n\ If the result is zero then its sign will be the sign of self.\n\ \n"); -PyDoc_STRVAR(doc_rotate,"\n\ -rotate(other, context=None) - Return the result of rotating the digits of the\n\ -first operand by an amount specified by the second operand. The second operand\n\ -must be an integer in the range -precision through precision. The absolute\n\ -value of the second operand gives the number of places to rotate. If the second\n\ -operand is positive then rotation is to the left; otherwise rotation is to the\n\ -right. The coefficient of the first operand is padded on the left with zeros to\n\ +PyDoc_STRVAR(doc_rotate, +"rotate($self, /, other, context=None)\n--\n\n\ +Return the result of rotating the digits of the first operand by an amount\n\ +specified by the second operand. The second operand must be an integer in\n\ +the range -precision through precision. The absolute value of the second\n\ +operand gives the number of places to rotate. If the second operand is\n\ +positive then rotation is to the left; otherwise rotation is to the right.\n\ +The coefficient of the first operand is padded on the left with zeros to\n\ length precision if necessary. The sign and exponent of the first operand are\n\ unchanged.\n\ \n"); -PyDoc_STRVAR(doc_same_quantum,"\n\ -same_quantum(other, context=None) - Test whether self and other have the\n\ -same exponent or whether both are NaN.\n\ +PyDoc_STRVAR(doc_same_quantum, +"same_quantum($self, /, other, context=None)\n--\n\n\ +Test whether self and other have the same exponent or whether both are NaN.\n\ \n\ This operation is unaffected by context and is quiet: no flags are changed\n\ and no rounding is performed. As an exception, the C version may raise\n\ InvalidOperation if the second operand cannot be converted exactly.\n\ \n"); -PyDoc_STRVAR(doc_scaleb,"\n\ -scaleb(other, context=None) - Return the first operand with the exponent\n\ -adjusted the second. Equivalently, return the first operand multiplied by\n\ -10**other. The second operand must be an integer.\n\ +PyDoc_STRVAR(doc_scaleb, +"scaleb($self, /, other, context=None)\n--\n\n\ +Return the first operand with the exponent adjusted the second. Equivalently,\n\ +return the first operand multiplied by 10**other. The second operand must be\n\ +an integer.\n\ \n"); -PyDoc_STRVAR(doc_shift,"\n\ -shift(other, context=None) - Return the result of shifting the digits of\n\ -the first operand by an amount specified by the second operand. The second\n\ -operand must be an integer in the range -precision through precision. The\n\ -absolute value of the second operand gives the number of places to shift.\n\ -If the second operand is positive, then the shift is to the left; otherwise\n\ -the shift is to the right. Digits shifted into the coefficient are zeros.\n\ -The sign and exponent of the first operand are unchanged.\n\ +PyDoc_STRVAR(doc_shift, +"shift($self, /, other, context=None)\n--\n\n\ +Return the result of shifting the digits of the first operand by an amount\n\ +specified by the second operand. The second operand must be an integer in\n\ +the range -precision through precision. The absolute value of the second\n\ +operand gives the number of places to shift. If the second operand is\n\ +positive, then the shift is to the left; otherwise the shift is to the\n\ +right. Digits shifted into the coefficient are zeros. The sign and exponent\n\ +of the first operand are unchanged.\n\ \n"); -PyDoc_STRVAR(doc_sqrt,"\n\ -sqrt(context=None) - Return the square root of the argument to full precision.\n\ -The result is correctly rounded using the ROUND_HALF_EVEN rounding mode.\n\ +PyDoc_STRVAR(doc_sqrt, +"sqrt($self, /, context=None)\n--\n\n\ +Return the square root of the argument to full precision. The result is\n\ +correctly rounded using the ROUND_HALF_EVEN rounding mode.\n\ \n"); -PyDoc_STRVAR(doc_to_eng_string,"\n\ -to_eng_string(context=None) - Convert to an engineering-type string.\n\ -Engineering notation has an exponent which is a multiple of 3, so there\n\ -are up to 3 digits left of the decimal place. For example, Decimal('123E+1')\n\ -is converted to Decimal('1.23E+3').\n\ +PyDoc_STRVAR(doc_to_eng_string, +"to_eng_string($self, /, context=None)\n--\n\n\ +Convert to an engineering-type string. Engineering notation has an exponent\n\ +which is a multiple of 3, so there are up to 3 digits left of the decimal\n\ +place. For example, Decimal('123E+1') is converted to Decimal('1.23E+3').\n\ \n\ The value of context.capitals determines whether the exponent sign is lower\n\ or upper case. Otherwise, the context does not affect the operation.\n\ \n"); -PyDoc_STRVAR(doc_to_integral,"\n\ -to_integral(rounding=None, context=None) - Identical to the\n\ -to_integral_value() method. The to_integral() name has been kept\n\ -for compatibility with older versions.\n\ +PyDoc_STRVAR(doc_to_integral, +"to_integral($self, /, rounding=None, context=None)\n--\n\n\ +Identical to the to_integral_value() method. The to_integral() name has been\n\ +kept for compatibility with older versions.\n\ \n"); -PyDoc_STRVAR(doc_to_integral_exact,"\n\ -to_integral_exact(rounding=None, context=None) - Round to the nearest\n\ -integer, signaling Inexact or Rounded as appropriate if rounding occurs.\n\ -The rounding mode is determined by the rounding parameter if given, else\n\ -by the given context. If neither parameter is given, then the rounding mode\n\ -of the current default context is used.\n\ +PyDoc_STRVAR(doc_to_integral_exact, +"to_integral_exact($self, /, rounding=None, context=None)\n--\n\n\ +Round to the nearest integer, signaling Inexact or Rounded as appropriate if\n\ +rounding occurs. The rounding mode is determined by the rounding parameter\n\ +if given, else by the given context. If neither parameter is given, then the\n\ +rounding mode of the current default context is used.\n\ \n"); -PyDoc_STRVAR(doc_to_integral_value,"\n\ -to_integral_value(rounding=None, context=None) - Round to the nearest\n\ -integer without signaling Inexact or Rounded. The rounding mode is determined\n\ -by the rounding parameter if given, else by the given context. If neither\n\ -parameter is given, then the rounding mode of the current default context is\n\ -used.\n\ +PyDoc_STRVAR(doc_to_integral_value, +"to_integral_value($self, /, rounding=None, context=None)\n--\n\n\ +Round to the nearest integer without signaling Inexact or Rounded. The\n\ +rounding mode is determined by the rounding parameter if given, else by\n\ +the given context. If neither parameter is given, then the rounding mode\n\ +of the current default context is used.\n\ \n"); @@ -446,9 +485,10 @@ used.\n\ /* Context Object and Methods */ /******************************************************************************/ -PyDoc_STRVAR(doc_context,"\n\ +PyDoc_STRVAR(doc_context, +"Context(prec=None, rounding=None, Emin=None, Emax=None, capitals=None, clamp=None, flags=None, traps=None)\n--\n\n\ The context affects almost all operations and controls rounding,\n\ -Over/Underflow, raising of exceptions and much more. A new context\n\ +Over/Underflow, raising of exceptions and much more. A new context\n\ can be constructed as follows:\n\ \n\ >>> c = Context(prec=28, Emin=-425000000, Emax=425000000,\n\ @@ -460,308 +500,372 @@ can be constructed as follows:\n\ \n"); #ifdef EXTRA_FUNCTIONALITY -PyDoc_STRVAR(doc_ctx_apply,"\n\ -apply(x) - Apply self to Decimal x.\n\ +PyDoc_STRVAR(doc_ctx_apply, +"apply($self, x, /)\n--\n\n\ +Apply self to Decimal x.\n\ \n"); #endif -PyDoc_STRVAR(doc_ctx_clear_flags,"\n\ -clear_flags() - Reset all flags to False.\n\ +PyDoc_STRVAR(doc_ctx_clear_flags, +"clear_flags($self, /)\n--\n\n\ +Reset all flags to False.\n\ \n"); -PyDoc_STRVAR(doc_ctx_clear_traps,"\n\ -clear_traps() - Set all traps to False.\n\ +PyDoc_STRVAR(doc_ctx_clear_traps, +"clear_traps($self, /)\n--\n\n\ +Set all traps to False.\n\ \n"); -PyDoc_STRVAR(doc_ctx_copy,"\n\ -copy() - Return a duplicate of the context with all flags cleared.\n\ +PyDoc_STRVAR(doc_ctx_copy, +"copy($self, /)\n--\n\n\ +Return a duplicate of the context with all flags cleared.\n\ \n"); -PyDoc_STRVAR(doc_ctx_copy_decimal,"\n\ -copy_decimal(x) - Return a copy of Decimal x.\n\ +PyDoc_STRVAR(doc_ctx_copy_decimal, +"copy_decimal($self, x, /)\n--\n\n\ +Return a copy of Decimal x.\n\ \n"); -PyDoc_STRVAR(doc_ctx_create_decimal,"\n\ -create_decimal(x) - Create a new Decimal instance from x, using self as the\n\ -context. Unlike the Decimal constructor, this function observes the context\n\ -limits.\n\ +PyDoc_STRVAR(doc_ctx_create_decimal, +"create_decimal($self, num=\"0\", /)\n--\n\n\ +Create a new Decimal instance from num, using self as the context. Unlike the\n\ +Decimal constructor, this function observes the context limits.\n\ \n"); -PyDoc_STRVAR(doc_ctx_create_decimal_from_float,"\n\ -create_decimal_from_float(f) - Create a new Decimal instance from float f.\n\ -Unlike the Decimal.from_float() class method, this function observes the\n\ -context limits.\n\ +PyDoc_STRVAR(doc_ctx_create_decimal_from_float, +"create_decimal_from_float($self, f, /)\n--\n\n\ +Create a new Decimal instance from float f. Unlike the Decimal.from_float()\n\ +class method, this function observes the context limits.\n\ \n"); -PyDoc_STRVAR(doc_ctx_Etiny,"\n\ -Etiny() - Return a value equal to Emin - prec + 1, which is the minimum\n\ -exponent value for subnormal results. When underflow occurs, the exponent\n\ -is set to Etiny.\n\ +PyDoc_STRVAR(doc_ctx_Etiny, +"Etiny($self, /)\n--\n\n\ +Return a value equal to Emin - prec + 1, which is the minimum exponent value\n\ +for subnormal results. When underflow occurs, the exponent is set to Etiny.\n\ \n"); -PyDoc_STRVAR(doc_ctx_Etop,"\n\ -Etop() - Return a value equal to Emax - prec + 1. This is the maximum exponent\n\ -if the _clamp field of the context is set to 1 (IEEE clamp mode). Etop() must\n\ -not be negative.\n\ +PyDoc_STRVAR(doc_ctx_Etop, +"Etop($self, /)\n--\n\n\ +Return a value equal to Emax - prec + 1. This is the maximum exponent\n\ +if the _clamp field of the context is set to 1 (IEEE clamp mode). Etop()\n\ +must not be negative.\n\ \n"); -PyDoc_STRVAR(doc_ctx_abs,"\n\ -abs(x) - Return the absolute value of x.\n\ +PyDoc_STRVAR(doc_ctx_abs, +"abs($self, x, /)\n--\n\n\ +Return the absolute value of x.\n\ \n"); -PyDoc_STRVAR(doc_ctx_add,"\n\ -add(x, y) - Return the sum of x and y.\n\ +PyDoc_STRVAR(doc_ctx_add, +"add($self, x, y, /)\n--\n\n\ +Return the sum of x and y.\n\ \n"); -PyDoc_STRVAR(doc_ctx_canonical,"\n\ -canonical(x) - Return a new instance of x.\n\ +PyDoc_STRVAR(doc_ctx_canonical, +"canonical($self, x, /)\n--\n\n\ +Return a new instance of x.\n\ \n"); -PyDoc_STRVAR(doc_ctx_compare,"\n\ -compare(x, y) - Compare x and y numerically.\n\ +PyDoc_STRVAR(doc_ctx_compare, +"compare($self, x, y, /)\n--\n\n\ +Compare x and y numerically.\n\ \n"); -PyDoc_STRVAR(doc_ctx_compare_signal,"\n\ -compare_signal(x, y) - Compare x and y numerically. All NaNs signal.\n\ +PyDoc_STRVAR(doc_ctx_compare_signal, +"compare_signal($self, x, y, /)\n--\n\n\ +Compare x and y numerically. All NaNs signal.\n\ \n"); -PyDoc_STRVAR(doc_ctx_compare_total,"\n\ -compare_total(x, y) - Compare x and y using their abstract representation.\n\ +PyDoc_STRVAR(doc_ctx_compare_total, +"compare_total($self, x, y, /)\n--\n\n\ +Compare x and y using their abstract representation.\n\ \n"); -PyDoc_STRVAR(doc_ctx_compare_total_mag,"\n\ -compare_total_mag(x, y) - Compare x and y using their abstract representation,\n\ -ignoring sign.\n\ +PyDoc_STRVAR(doc_ctx_compare_total_mag, +"compare_total_mag($self, x, y, /)\n--\n\n\ +Compare x and y using their abstract representation, ignoring sign.\n\ \n"); -PyDoc_STRVAR(doc_ctx_copy_abs,"\n\ -copy_abs(x) - Return a copy of x with the sign set to 0.\n\ +PyDoc_STRVAR(doc_ctx_copy_abs, +"copy_abs($self, x, /)\n--\n\n\ +Return a copy of x with the sign set to 0.\n\ \n"); -PyDoc_STRVAR(doc_ctx_copy_negate,"\n\ -copy_negate(x) - Return a copy of x with the sign inverted.\n\ +PyDoc_STRVAR(doc_ctx_copy_negate, +"copy_negate($self, x, /)\n--\n\n\ +Return a copy of x with the sign inverted.\n\ \n"); -PyDoc_STRVAR(doc_ctx_copy_sign,"\n\ -copy_sign(x, y) - Copy the sign from y to x.\n\ +PyDoc_STRVAR(doc_ctx_copy_sign, +"copy_sign($self, x, y, /)\n--\n\n\ +Copy the sign from y to x.\n\ \n"); -PyDoc_STRVAR(doc_ctx_divide,"\n\ -divide(x, y) - Return x divided by y.\n\ +PyDoc_STRVAR(doc_ctx_divide, +"divide($self, x, y, /)\n--\n\n\ +Return x divided by y.\n\ \n"); -PyDoc_STRVAR(doc_ctx_divide_int,"\n\ -divide_int(x, y) - Return x divided by y, truncated to an integer.\n\ +PyDoc_STRVAR(doc_ctx_divide_int, +"divide_int($self, x, y, /)\n--\n\n\ +Return x divided by y, truncated to an integer.\n\ \n"); -PyDoc_STRVAR(doc_ctx_divmod,"\n\ -divmod(x, y) - Return quotient and remainder of the division x / y.\n\ +PyDoc_STRVAR(doc_ctx_divmod, +"divmod($self, x, y, /)\n--\n\n\ +Return quotient and remainder of the division x / y.\n\ \n"); -PyDoc_STRVAR(doc_ctx_exp,"\n\ -exp(x) - Return e ** x.\n\ +PyDoc_STRVAR(doc_ctx_exp, +"exp($self, x, /)\n--\n\n\ +Return e ** x.\n\ \n"); -PyDoc_STRVAR(doc_ctx_fma,"\n\ -fma(x, y, z) - Return x multiplied by y, plus z.\n\ +PyDoc_STRVAR(doc_ctx_fma, +"fma($self, x, y, z, /)\n--\n\n\ +Return x multiplied by y, plus z.\n\ \n"); -PyDoc_STRVAR(doc_ctx_is_canonical,"\n\ -is_canonical(x) - Return True if x is canonical, False otherwise.\n\ +PyDoc_STRVAR(doc_ctx_is_canonical, +"is_canonical($self, x, /)\n--\n\n\ +Return True if x is canonical, False otherwise.\n\ \n"); -PyDoc_STRVAR(doc_ctx_is_finite,"\n\ -is_finite(x) - Return True if x is finite, False otherwise.\n\ +PyDoc_STRVAR(doc_ctx_is_finite, +"is_finite($self, x, /)\n--\n\n\ +Return True if x is finite, False otherwise.\n\ \n"); -PyDoc_STRVAR(doc_ctx_is_infinite,"\n\ -is_infinite(x) - Return True if x is infinite, False otherwise.\n\ +PyDoc_STRVAR(doc_ctx_is_infinite, +"is_infinite($self, x, /)\n--\n\n\ +Return True if x is infinite, False otherwise.\n\ \n"); -PyDoc_STRVAR(doc_ctx_is_nan,"\n\ -is_nan(x) - Return True if x is a qNaN or sNaN, False otherwise.\n\ +PyDoc_STRVAR(doc_ctx_is_nan, +"is_nan($self, x, /)\n--\n\n\ +Return True if x is a qNaN or sNaN, False otherwise.\n\ \n"); -PyDoc_STRVAR(doc_ctx_is_normal,"\n\ -is_normal(x) - Return True if x is a normal number, False otherwise.\n\ +PyDoc_STRVAR(doc_ctx_is_normal, +"is_normal($self, x, /)\n--\n\n\ +Return True if x is a normal number, False otherwise.\n\ \n"); -PyDoc_STRVAR(doc_ctx_is_qnan,"\n\ -is_qnan(x) - Return True if x is a quiet NaN, False otherwise.\n\ +PyDoc_STRVAR(doc_ctx_is_qnan, +"is_qnan($self, x, /)\n--\n\n\ +Return True if x is a quiet NaN, False otherwise.\n\ \n"); -PyDoc_STRVAR(doc_ctx_is_signed,"\n\ -is_signed(x) - Return True if x is negative, False otherwise.\n\ +PyDoc_STRVAR(doc_ctx_is_signed, +"is_signed($self, x, /)\n--\n\n\ +Return True if x is negative, False otherwise.\n\ \n"); -PyDoc_STRVAR(doc_ctx_is_snan,"\n\ -is_snan() - Return True if x is a signaling NaN, False otherwise.\n\ +PyDoc_STRVAR(doc_ctx_is_snan, +"is_snan($self, x, /)\n--\n\n\ +Return True if x is a signaling NaN, False otherwise.\n\ \n"); -PyDoc_STRVAR(doc_ctx_is_subnormal,"\n\ -is_subnormal(x) - Return True if x is subnormal, False otherwise.\n\ +PyDoc_STRVAR(doc_ctx_is_subnormal, +"is_subnormal($self, x, /)\n--\n\n\ +Return True if x is subnormal, False otherwise.\n\ \n"); -PyDoc_STRVAR(doc_ctx_is_zero,"\n\ -is_zero(x) - Return True if x is a zero, False otherwise.\n\ +PyDoc_STRVAR(doc_ctx_is_zero, +"is_zero($self, x, /)\n--\n\n\ +Return True if x is a zero, False otherwise.\n\ \n"); -PyDoc_STRVAR(doc_ctx_ln,"\n\ -ln(x) - Return the natural (base e) logarithm of x.\n\ +PyDoc_STRVAR(doc_ctx_ln, +"ln($self, x, /)\n--\n\n\ +Return the natural (base e) logarithm of x.\n\ \n"); -PyDoc_STRVAR(doc_ctx_log10,"\n\ -log10(x) - Return the base 10 logarithm of x.\n\ +PyDoc_STRVAR(doc_ctx_log10, +"log10($self, x, /)\n--\n\n\ +Return the base 10 logarithm of x.\n\ \n"); -PyDoc_STRVAR(doc_ctx_logb,"\n\ -logb(x) - Return the exponent of the magnitude of the operand's MSD.\n\ +PyDoc_STRVAR(doc_ctx_logb, +"logb($self, x, /)\n--\n\n\ +Return the exponent of the magnitude of the operand's MSD.\n\ \n"); -PyDoc_STRVAR(doc_ctx_logical_and,"\n\ -logical_and(x, y) - Digit-wise and of x and y.\n\ +PyDoc_STRVAR(doc_ctx_logical_and, +"logical_and($self, x, y, /)\n--\n\n\ +Digit-wise and of x and y.\n\ \n"); -PyDoc_STRVAR(doc_ctx_logical_invert,"\n\ -logical_invert(x) - Invert all digits of x.\n\ +PyDoc_STRVAR(doc_ctx_logical_invert, +"logical_invert($self, x, /)\n--\n\n\ +Invert all digits of x.\n\ \n"); -PyDoc_STRVAR(doc_ctx_logical_or,"\n\ -logical_or(x, y) - Digit-wise or of x and y.\n\ +PyDoc_STRVAR(doc_ctx_logical_or, +"logical_or($self, x, y, /)\n--\n\n\ +Digit-wise or of x and y.\n\ \n"); -PyDoc_STRVAR(doc_ctx_logical_xor,"\n\ -logical_xor(x, y) - Digit-wise xor of x and y.\n\ +PyDoc_STRVAR(doc_ctx_logical_xor, +"logical_xor($self, x, y, /)\n--\n\n\ +Digit-wise xor of x and y.\n\ \n"); -PyDoc_STRVAR(doc_ctx_max,"\n\ -max(x, y) - Compare the values numerically and return the maximum.\n\ +PyDoc_STRVAR(doc_ctx_max, +"max($self, x, y, /)\n--\n\n\ +Compare the values numerically and return the maximum.\n\ \n"); -PyDoc_STRVAR(doc_ctx_max_mag,"\n\ -max_mag(x, y) - Compare the values numerically with their sign ignored.\n\ +PyDoc_STRVAR(doc_ctx_max_mag, +"max_mag($self, x, y, /)\n--\n\n\ +Compare the values numerically with their sign ignored.\n\ \n"); -PyDoc_STRVAR(doc_ctx_min,"\n\ -min(x, y) - Compare the values numerically and return the minimum.\n\ +PyDoc_STRVAR(doc_ctx_min, +"min($self, x, y, /)\n--\n\n\ +Compare the values numerically and return the minimum.\n\ \n"); -PyDoc_STRVAR(doc_ctx_min_mag,"\n\ -min_mag(x, y) - Compare the values numerically with their sign ignored.\n\ +PyDoc_STRVAR(doc_ctx_min_mag, +"min_mag($self, x, y, /)\n--\n\n\ +Compare the values numerically with their sign ignored.\n\ \n"); -PyDoc_STRVAR(doc_ctx_minus,"\n\ -minus(x) - Minus corresponds to the unary prefix minus operator in Python,\n\ -but applies the context to the result.\n\ +PyDoc_STRVAR(doc_ctx_minus, +"minus($self, x, /)\n--\n\n\ +Minus corresponds to the unary prefix minus operator in Python, but applies\n\ +the context to the result.\n\ \n"); -PyDoc_STRVAR(doc_ctx_multiply,"\n\ -multiply(x, y) - Return the product of x and y.\n\ +PyDoc_STRVAR(doc_ctx_multiply, +"multiply($self, x, y, /)\n--\n\n\ +Return the product of x and y.\n\ \n"); -PyDoc_STRVAR(doc_ctx_next_minus,"\n\ -next_minus(x) - Return the largest representable number smaller than x.\n\ +PyDoc_STRVAR(doc_ctx_next_minus, +"next_minus($self, x, /)\n--\n\n\ +Return the largest representable number smaller than x.\n\ \n"); -PyDoc_STRVAR(doc_ctx_next_plus,"\n\ -next_plus(x) - Return the smallest representable number larger than x.\n\ +PyDoc_STRVAR(doc_ctx_next_plus, +"next_plus($self, x, /)\n--\n\n\ +Return the smallest representable number larger than x.\n\ \n"); -PyDoc_STRVAR(doc_ctx_next_toward,"\n\ -next_toward(x) - Return the number closest to x, in the direction towards y.\n\ +PyDoc_STRVAR(doc_ctx_next_toward, +"next_toward($self, x, y, /)\n--\n\n\ +Return the number closest to x, in the direction towards y.\n\ \n"); -PyDoc_STRVAR(doc_ctx_normalize,"\n\ -normalize(x) - Reduce x to its simplest form. Alias for reduce(x).\n\ +PyDoc_STRVAR(doc_ctx_normalize, +"normalize($self, x, /)\n--\n\n\ +Reduce x to its simplest form. Alias for reduce(x).\n\ \n"); -PyDoc_STRVAR(doc_ctx_number_class,"\n\ -number_class(x) - Return an indication of the class of x.\n\ +PyDoc_STRVAR(doc_ctx_number_class, +"number_class($self, x, /)\n--\n\n\ +Return an indication of the class of x.\n\ \n"); -PyDoc_STRVAR(doc_ctx_plus,"\n\ -plus(x) - Plus corresponds to the unary prefix plus operator in Python,\n\ -but applies the context to the result.\n\ +PyDoc_STRVAR(doc_ctx_plus, +"plus($self, x, /)\n--\n\n\ +Plus corresponds to the unary prefix plus operator in Python, but applies\n\ +the context to the result.\n\ \n"); -PyDoc_STRVAR(doc_ctx_power,"\n\ -power(x, y) - Compute x**y. If x is negative, then y must be integral.\n\ -The result will be inexact unless y is integral and the result is finite\n\ -and can be expressed exactly in 'precision' digits. In the Python version\n\ -the result is always correctly rounded, in the C version the result is\n\ -almost always correctly rounded.\n\ +PyDoc_STRVAR(doc_ctx_power, +"power($self, /, a, b, modulo=None)\n--\n\n\ +Compute a**b. If 'a' is negative, then 'b' must be integral. The result\n\ +will be inexact unless 'a' is integral and the result is finite and can\n\ +be expressed exactly in 'precision' digits. In the Python version the\n\ +result is always correctly rounded, in the C version the result is almost\n\ +always correctly rounded.\n\ \n\ -power(x, y, m) - Compute (x**y) % m. The following restrictions hold:\n\ +If modulo is given, compute (a**b) % modulo. The following restrictions\n\ +hold:\n\ \n\ * all three arguments must be integral\n\ - * y must be nonnegative\n\ - * at least one of x or y must be nonzero\n\ - * m must be nonzero and less than 10**prec in absolute value\n\ + * 'b' must be nonnegative\n\ + * at least one of 'a' or 'b' must be nonzero\n\ + * modulo must be nonzero and less than 10**prec in absolute value\n\ \n\ \n"); -PyDoc_STRVAR(doc_ctx_quantize,"\n\ -quantize(x, y) - Return a value equal to x (rounded), having the exponent of y.\n\ +PyDoc_STRVAR(doc_ctx_quantize, +"quantize($self, x, y, /)\n--\n\n\ +Return a value equal to x (rounded), having the exponent of y.\n\ \n"); -PyDoc_STRVAR(doc_ctx_radix,"\n\ -radix() - Return 10.\n\ +PyDoc_STRVAR(doc_ctx_radix, +"radix($self, /)\n--\n\n\ +Return 10.\n\ \n"); -PyDoc_STRVAR(doc_ctx_remainder,"\n\ -remainder(x, y) - Return the remainder from integer division. The sign of\n\ -the result, if non-zero, is the same as that of the original dividend.\n\ +PyDoc_STRVAR(doc_ctx_remainder, +"remainder($self, x, y, /)\n--\n\n\ +Return the remainder from integer division. The sign of the result,\n\ +if non-zero, is the same as that of the original dividend.\n\ \n"); -PyDoc_STRVAR(doc_ctx_remainder_near,"\n\ -remainder_near(x, y) - Return x - y * n, where n is the integer nearest the\n\ -exact value of x / y (if the result is 0 then its sign will be the sign of x).\n\ +PyDoc_STRVAR(doc_ctx_remainder_near, +"remainder_near($self, x, y, /)\n--\n\n\ +Return x - y * n, where n is the integer nearest the exact value of x / y\n\ +(if the result is 0 then its sign will be the sign of x).\n\ \n"); -PyDoc_STRVAR(doc_ctx_rotate,"\n\ -rotate(x, y) - Return a copy of x, rotated by y places.\n\ +PyDoc_STRVAR(doc_ctx_rotate, +"rotate($self, x, y, /)\n--\n\n\ +Return a copy of x, rotated by y places.\n\ \n"); -PyDoc_STRVAR(doc_ctx_same_quantum,"\n\ -same_quantum(x, y) - Return True if the two operands have the same exponent.\n\ +PyDoc_STRVAR(doc_ctx_same_quantum, +"same_quantum($self, x, y, /)\n--\n\n\ +Return True if the two operands have the same exponent.\n\ \n"); -PyDoc_STRVAR(doc_ctx_scaleb,"\n\ -scaleb(x, y) - Return the first operand after adding the second value\n\ -to its exp.\n\ +PyDoc_STRVAR(doc_ctx_scaleb, +"scaleb($self, x, y, /)\n--\n\n\ +Return the first operand after adding the second value to its exp.\n\ \n"); -PyDoc_STRVAR(doc_ctx_shift,"\n\ -shift(x, y) - Return a copy of x, shifted by y places.\n\ +PyDoc_STRVAR(doc_ctx_shift, +"shift($self, x, y, /)\n--\n\n\ +Return a copy of x, shifted by y places.\n\ \n"); -PyDoc_STRVAR(doc_ctx_sqrt,"\n\ -sqrt(x) - Square root of a non-negative number to context precision.\n\ +PyDoc_STRVAR(doc_ctx_sqrt, +"sqrt($self, x, /)\n--\n\n\ +Square root of a non-negative number to context precision.\n\ \n"); -PyDoc_STRVAR(doc_ctx_subtract,"\n\ -subtract(x, y) - Return the difference between x and y.\n\ +PyDoc_STRVAR(doc_ctx_subtract, +"subtract($self, x, y, /)\n--\n\n\ +Return the difference between x and y.\n\ \n"); -PyDoc_STRVAR(doc_ctx_to_eng_string,"\n\ -to_eng_string(x) - Convert a number to a string, using engineering notation.\n\ +PyDoc_STRVAR(doc_ctx_to_eng_string, +"to_eng_string($self, x, /)\n--\n\n\ +Convert a number to a string, using engineering notation.\n\ \n"); -PyDoc_STRVAR(doc_ctx_to_integral,"\n\ -to_integral(x) - Identical to to_integral_value(x).\n\ +PyDoc_STRVAR(doc_ctx_to_integral, +"to_integral($self, x, /)\n--\n\n\ +Identical to to_integral_value(x).\n\ \n"); -PyDoc_STRVAR(doc_ctx_to_integral_exact,"\n\ -to_integral_exact(x) - Round to an integer. Signal if the result is\n\ -rounded or inexact.\n\ +PyDoc_STRVAR(doc_ctx_to_integral_exact, +"to_integral_exact($self, x, /)\n--\n\n\ +Round to an integer. Signal if the result is rounded or inexact.\n\ \n"); -PyDoc_STRVAR(doc_ctx_to_integral_value,"\n\ -to_integral_value(x) - Round to an integer.\n\ +PyDoc_STRVAR(doc_ctx_to_integral_value, +"to_integral_value($self, x, /)\n--\n\n\ +Round to an integer.\n\ \n"); -PyDoc_STRVAR(doc_ctx_to_sci_string,"\n\ -to_sci_string(x) - Convert a number to a string using scientific notation.\n\ +PyDoc_STRVAR(doc_ctx_to_sci_string, +"to_sci_string($self, x, /)\n--\n\n\ +Convert a number to a string using scientific notation.\n\ \n"); diff --git a/Modules/_decimal/libmpdec/basearith.c b/Modules/_decimal/libmpdec/basearith.c index dd21a7a885fb..35de6b828491 100644 --- a/Modules/_decimal/libmpdec/basearith.c +++ b/Modules/_decimal/libmpdec/basearith.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/Modules/_decimal/libmpdec/basearith.h b/Modules/_decimal/libmpdec/basearith.h index 114cef386036..976358a110ec 100644 --- a/Modules/_decimal/libmpdec/basearith.h +++ b/Modules/_decimal/libmpdec/basearith.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/Modules/_decimal/libmpdec/bits.h b/Modules/_decimal/libmpdec/bits.h index 949ec944ca51..b5eaa24976ae 100644 --- a/Modules/_decimal/libmpdec/bits.h +++ b/Modules/_decimal/libmpdec/bits.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/Modules/_decimal/libmpdec/constants.c b/Modules/_decimal/libmpdec/constants.c index 92f5891b56f3..2c2d5ea48103 100644 --- a/Modules/_decimal/libmpdec/constants.c +++ b/Modules/_decimal/libmpdec/constants.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/Modules/_decimal/libmpdec/constants.h b/Modules/_decimal/libmpdec/constants.h index 13df9202123d..c0febfc8772d 100644 --- a/Modules/_decimal/libmpdec/constants.h +++ b/Modules/_decimal/libmpdec/constants.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/Modules/_decimal/libmpdec/context.c b/Modules/_decimal/libmpdec/context.c index 159f88c339e6..24c7b890c1d9 100644 --- a/Modules/_decimal/libmpdec/context.c +++ b/Modules/_decimal/libmpdec/context.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/Modules/_decimal/libmpdec/convolute.c b/Modules/_decimal/libmpdec/convolute.c index b5fe131b07ce..4c62e8bd3abd 100644 --- a/Modules/_decimal/libmpdec/convolute.c +++ b/Modules/_decimal/libmpdec/convolute.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/Modules/_decimal/libmpdec/convolute.h b/Modules/_decimal/libmpdec/convolute.h index c35ed461d3b5..f30a177a6840 100644 --- a/Modules/_decimal/libmpdec/convolute.h +++ b/Modules/_decimal/libmpdec/convolute.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/Modules/_decimal/libmpdec/crt.c b/Modules/_decimal/libmpdec/crt.c index c71c4ee8f80e..4a1e80a23228 100644 --- a/Modules/_decimal/libmpdec/crt.c +++ b/Modules/_decimal/libmpdec/crt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/Modules/_decimal/libmpdec/crt.h b/Modules/_decimal/libmpdec/crt.h index 8909232231ab..f61e77293632 100644 --- a/Modules/_decimal/libmpdec/crt.h +++ b/Modules/_decimal/libmpdec/crt.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/Modules/_decimal/libmpdec/difradix2.c b/Modules/_decimal/libmpdec/difradix2.c index 4ebb0b54b0ab..06e5ab5e222e 100644 --- a/Modules/_decimal/libmpdec/difradix2.c +++ b/Modules/_decimal/libmpdec/difradix2.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/Modules/_decimal/libmpdec/difradix2.h b/Modules/_decimal/libmpdec/difradix2.h index 81aa598543fd..5e22bcf324fa 100644 --- a/Modules/_decimal/libmpdec/difradix2.h +++ b/Modules/_decimal/libmpdec/difradix2.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/Modules/_decimal/libmpdec/fnt.c b/Modules/_decimal/libmpdec/fnt.c index 93116539b9f1..7e924c85242b 100644 --- a/Modules/_decimal/libmpdec/fnt.c +++ b/Modules/_decimal/libmpdec/fnt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/Modules/_decimal/libmpdec/fnt.h b/Modules/_decimal/libmpdec/fnt.h index 1f302cccbfa1..fa2154a798d4 100644 --- a/Modules/_decimal/libmpdec/fnt.h +++ b/Modules/_decimal/libmpdec/fnt.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/Modules/_decimal/libmpdec/fourstep.c b/Modules/_decimal/libmpdec/fourstep.c index aa32c0d5cf2e..21d3e7485df4 100644 --- a/Modules/_decimal/libmpdec/fourstep.c +++ b/Modules/_decimal/libmpdec/fourstep.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/Modules/_decimal/libmpdec/fourstep.h b/Modules/_decimal/libmpdec/fourstep.h index 593f27d489f4..80dcd4be3d59 100644 --- a/Modules/_decimal/libmpdec/fourstep.h +++ b/Modules/_decimal/libmpdec/fourstep.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/Modules/_decimal/libmpdec/io.c b/Modules/_decimal/libmpdec/io.c index 36470ca0062d..a45a429dbf1d 100644 --- a/Modules/_decimal/libmpdec/io.c +++ b/Modules/_decimal/libmpdec/io.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -446,7 +446,7 @@ _mpd_to_string(char **result, const mpd_t *dec, int flags, mpd_ssize_t dplace) if (mpd_isspecial(dec)) { - mem = sizeof "-Infinity"; + mem = sizeof "-Infinity%"; if (mpd_isnan(dec) && dec->len > 0) { /* diagnostic code */ mem += dec->digits; @@ -609,10 +609,10 @@ _mpd_to_string(char **result, const mpd_t *dec, int flags, mpd_ssize_t dplace) *cp++ = (flags&MPD_FMT_UPPER) ? 'E' : 'e'; cp = exp_to_string(cp, ldigits-dplace); } + } - if (flags&MPD_FMT_PERCENT) { - *cp++ = '%'; - } + if (flags&MPD_FMT_PERCENT) { + *cp++ = '%'; } assert(cp < decstring+mem); @@ -1260,6 +1260,9 @@ mpd_qformat_spec(const mpd_t *dec, const mpd_spec_t *spec, stackspec.align = '>'; spec = &stackspec; } + if (type == '%') { + flags |= MPD_FMT_PERCENT; + } } else { uint32_t workstatus = 0; diff --git a/Modules/_decimal/libmpdec/io.h b/Modules/_decimal/libmpdec/io.h index 3dfce732aa4b..de5486a00ca5 100644 --- a/Modules/_decimal/libmpdec/io.h +++ b/Modules/_decimal/libmpdec/io.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/Modules/_decimal/libmpdec/literature/fnt.py b/Modules/_decimal/libmpdec/literature/fnt.py index bf937459f52d..6363536da648 100644 --- a/Modules/_decimal/libmpdec/literature/fnt.py +++ b/Modules/_decimal/libmpdec/literature/fnt.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2008-2012 Stefan Krah. All rights reserved. +# Copyright (c) 2008-2016 Stefan Krah. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions diff --git a/Modules/_decimal/libmpdec/literature/mulmod-64.txt b/Modules/_decimal/libmpdec/literature/mulmod-64.txt index 93bf22e9fed2..029b8de3d7c9 100644 --- a/Modules/_decimal/libmpdec/literature/mulmod-64.txt +++ b/Modules/_decimal/libmpdec/literature/mulmod-64.txt @@ -59,7 +59,7 @@ The reduction step b) preserves congruence: Maximum numbers of step b): --------------------------- -# To avoid unneccessary formalism, define: +# To avoid unnecessary formalism, define: def R(hi, lo, z): return divmod(hi * z - hi + lo, 2**64) diff --git a/Modules/_decimal/libmpdec/literature/umodarith.lisp b/Modules/_decimal/libmpdec/literature/umodarith.lisp index 008e9f4507f4..99d71c373d1a 100644 --- a/Modules/_decimal/libmpdec/literature/umodarith.lisp +++ b/Modules/_decimal/libmpdec/literature/umodarith.lisp @@ -1,5 +1,5 @@ ; -; Copyright (c) 2008-2012 Stefan Krah. All rights reserved. +; Copyright (c) 2008-2016 Stefan Krah. All rights reserved. ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions diff --git a/Modules/_decimal/libmpdec/memory.c b/Modules/_decimal/libmpdec/memory.c index bf6350f9049c..0f41fe506452 100644 --- a/Modules/_decimal/libmpdec/memory.c +++ b/Modules/_decimal/libmpdec/memory.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/Modules/_decimal/libmpdec/memory.h b/Modules/_decimal/libmpdec/memory.h index 7e73c1305933..9c98d1a4000d 100644 --- a/Modules/_decimal/libmpdec/memory.h +++ b/Modules/_decimal/libmpdec/memory.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/Modules/_decimal/libmpdec/mpdecimal.c b/Modules/_decimal/libmpdec/mpdecimal.c index 287a77ed302e..21d222277c30 100644 --- a/Modules/_decimal/libmpdec/mpdecimal.c +++ b/Modules/_decimal/libmpdec/mpdecimal.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -392,42 +392,42 @@ mpd_radix(void) /* Dynamic decimal */ ALWAYS_INLINE int -mpd_isdynamic(mpd_t *dec) +mpd_isdynamic(const mpd_t *dec) { return !(dec->flags & MPD_STATIC); } /* Static decimal */ ALWAYS_INLINE int -mpd_isstatic(mpd_t *dec) +mpd_isstatic(const mpd_t *dec) { return dec->flags & MPD_STATIC; } /* Data of decimal is dynamic */ ALWAYS_INLINE int -mpd_isdynamic_data(mpd_t *dec) +mpd_isdynamic_data(const mpd_t *dec) { return !(dec->flags & MPD_DATAFLAGS); } /* Data of decimal is static */ ALWAYS_INLINE int -mpd_isstatic_data(mpd_t *dec) +mpd_isstatic_data(const mpd_t *dec) { return dec->flags & MPD_STATIC_DATA; } /* Data of decimal is shared */ ALWAYS_INLINE int -mpd_isshared_data(mpd_t *dec) +mpd_isshared_data(const mpd_t *dec) { return dec->flags & MPD_SHARED_DATA; } /* Data of decimal is const */ ALWAYS_INLINE int -mpd_isconst_data(mpd_t *dec) +mpd_isconst_data(const mpd_t *dec) { return dec->flags & MPD_CONST_DATA; } @@ -597,7 +597,7 @@ mpd_set_sign(mpd_t *result, uint8_t sign) /* Copy sign from another decimal */ ALWAYS_INLINE void -mpd_signcpy(mpd_t *result, mpd_t *a) +mpd_signcpy(mpd_t *result, const mpd_t *a) { uint8_t sign = a->flags&MPD_NEG; @@ -3202,9 +3202,9 @@ mpd_qabs(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, } static inline void -_mpd_ptrswap(mpd_t **a, mpd_t **b) +_mpd_ptrswap(const mpd_t **a, const mpd_t **b) { - mpd_t *t = *a; + const mpd_t *t = *a; *a = *b; *b = t; } @@ -3232,7 +3232,7 @@ static void _mpd_qaddsub(mpd_t *result, const mpd_t *a, const mpd_t *b, uint8_t sign_b, const mpd_context_t *ctx, uint32_t *status) { - mpd_t *big, *small; + const mpd_t *big, *small; MPD_NEW_STATIC(big_aligned,0,0,0,0); MPD_NEW_CONST(tiny,0,0,1,1,1,1); mpd_uint_t carry; @@ -3242,7 +3242,7 @@ _mpd_qaddsub(mpd_t *result, const mpd_t *a, const mpd_t *b, uint8_t sign_b, /* compare exponents */ - big = (mpd_t *)a; small = (mpd_t *)b; + big = a; small = b; if (big->exp != small->exp) { if (small->exp > big->exp) { _mpd_ptrswap(&big, &small); @@ -4421,21 +4421,22 @@ mpd_qfma(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_t *c, const mpd_context_t *ctx, uint32_t *status) { uint32_t workstatus = 0; - mpd_t *cc = (mpd_t *)c; + mpd_t *cc = NULL; if (result == c) { if ((cc = mpd_qncopy(c)) == NULL) { mpd_seterror(result, MPD_Malloc_error, status); return; } + c = cc; } _mpd_qmul(result, a, b, ctx, &workstatus); if (!(workstatus&MPD_Invalid_operation)) { - mpd_qadd(result, result, cc, ctx, &workstatus); + mpd_qadd(result, result, c, ctx, &workstatus); } - if (cc != c) mpd_del(cc); + if (cc) mpd_del(cc); *status |= workstatus; } @@ -5727,7 +5728,7 @@ static inline void _mpd_qmul(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status) { - mpd_t *big = (mpd_t *)a, *small = (mpd_t *)b; + const mpd_t *big = a, *small = b; mpd_uint_t *rdata = NULL; mpd_uint_t rbuf[MPD_MINALLOC_MAX]; mpd_size_t rsize, i; diff --git a/Modules/_decimal/libmpdec/mpdecimal.h b/Modules/_decimal/libmpdec/mpdecimal.h index 0f31733cb75e..5ca74135bf9b 100644 --- a/Modules/_decimal/libmpdec/mpdecimal.h +++ b/Modules/_decimal/libmpdec/mpdecimal.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,6 +32,10 @@ #ifdef __cplusplus extern "C" { + #ifndef __STDC_LIMIT_MACROS + #define __STDC_LIMIT_MACROS + #define MPD_CLEAR_STDC_LIMIT_MACROS + #endif #endif @@ -55,18 +59,12 @@ extern "C" { #define MPD_HIDE_SYMBOLS_END #define EXTINLINE extern inline #else + #ifdef HAVE_STDINT_H + #include + #endif #ifdef HAVE_INTTYPES_H #include #endif - #ifdef HAVE_STDINT_H - #if defined(__cplusplus) && !defined(__STDC_LIMIT_MACROS) - #define __STDC_LIMIT_MACROS - #include - #undef __STDC_LIMIT_MACROS - #else - #include - #endif - #endif #ifndef __GNUC_STDC_INLINE__ #define __GNUC_STDC_INLINE__ 1 #endif @@ -110,9 +108,13 @@ MPD_PRAGMA(MPD_HIDE_SYMBOLS_START) #define MPD_MAJOR_VERSION 2 #define MPD_MINOR_VERSION 4 -#define MPD_MICRO_VERSION 0 +#define MPD_MICRO_VERSION 1 + +#define MPD_VERSION "2.4.1" -#define MPD_VERSION "2.4.0" +#define MPD_VERSION_HEX ((MPD_MAJOR_VERSION << 24) | \ + (MPD_MINOR_VERSION << 16) | \ + (MPD_MICRO_VERSION << 8)) const char *mpd_version(void); @@ -408,7 +410,7 @@ mpd_ssize_t mpd_to_sci_size(char **res, const mpd_t *dec, int fmt); mpd_ssize_t mpd_to_eng_size(char **res, const mpd_t *dec, int fmt); int mpd_validate_lconv(mpd_spec_t *spec); int mpd_parse_fmt_str(mpd_spec_t *spec, const char *fmt, int caps); -char * mpd_qformat_spec(const mpd_t *dec, const mpd_spec_t *spec, const mpd_context_t *ctx, uint32_t *status); +char *mpd_qformat_spec(const mpd_t *dec, const mpd_spec_t *spec, const mpd_context_t *ctx, uint32_t *status); char *mpd_qformat(const mpd_t *dec, const char *fmt, const mpd_context_t *ctx, uint32_t *status); #define MPD_NUM_FLAGS 15 @@ -467,7 +469,7 @@ int mpd_qcheck_nan(mpd_t *nanresult, const mpd_t *a, const mpd_context_t *ctx, u int mpd_qcheck_nans(mpd_t *nanresult, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status); void mpd_qfinalize(mpd_t *result, const mpd_context_t *ctx, uint32_t *status); -const char * mpd_class(const mpd_t *a, const mpd_context_t *ctx); +const char *mpd_class(const mpd_t *a, const mpd_context_t *ctx); int mpd_qcopy(mpd_t *result, const mpd_t *a, uint32_t *status); mpd_t *mpd_qncopy(const mpd_t *a); @@ -581,7 +583,7 @@ size_t mpd_qexport_u32(uint32_t **rdata, size_t rlen, uint32_t base, /* Signalling functions */ /******************************************************************************/ -char * mpd_format(const mpd_t *dec, const char *fmt, mpd_context_t *ctx); +char *mpd_format(const mpd_t *dec, const char *fmt, mpd_context_t *ctx); void mpd_import_u16(mpd_t *result, const uint16_t *srcdata, size_t srclen, uint8_t srcsign, uint32_t base, mpd_context_t *ctx); void mpd_import_u32(mpd_t *result, const uint32_t *srcdata, size_t srclen, uint8_t srcsign, uint32_t base, mpd_context_t *ctx); size_t mpd_export_u16(uint16_t **rdata, size_t rlen, uint32_t base, const mpd_t *src, mpd_context_t *ctx); @@ -752,12 +754,12 @@ EXTINLINE uint8_t mpd_sign(const mpd_t *dec); /* 1 if dec is positive, -1 if dec is negative */ EXTINLINE int mpd_arith_sign(const mpd_t *dec); EXTINLINE long mpd_radix(void); -EXTINLINE int mpd_isdynamic(mpd_t *dec); -EXTINLINE int mpd_isstatic(mpd_t *dec); -EXTINLINE int mpd_isdynamic_data(mpd_t *dec); -EXTINLINE int mpd_isstatic_data(mpd_t *dec); -EXTINLINE int mpd_isshared_data(mpd_t *dec); -EXTINLINE int mpd_isconst_data(mpd_t *dec); +EXTINLINE int mpd_isdynamic(const mpd_t *dec); +EXTINLINE int mpd_isstatic(const mpd_t *dec); +EXTINLINE int mpd_isdynamic_data(const mpd_t *dec); +EXTINLINE int mpd_isstatic_data(const mpd_t *dec); +EXTINLINE int mpd_isshared_data(const mpd_t *dec); +EXTINLINE int mpd_isconst_data(const mpd_t *dec); EXTINLINE mpd_ssize_t mpd_trail_zeros(const mpd_t *dec); @@ -769,7 +771,7 @@ EXTINLINE mpd_ssize_t mpd_trail_zeros(const mpd_t *dec); EXTINLINE void mpd_setdigits(mpd_t *result); EXTINLINE void mpd_set_sign(mpd_t *result, uint8_t sign); /* copy sign from another decimal */ -EXTINLINE void mpd_signcpy(mpd_t *result, mpd_t *a); +EXTINLINE void mpd_signcpy(mpd_t *result, const mpd_t *a); EXTINLINE void mpd_set_infinity(mpd_t *result); EXTINLINE void mpd_set_qnan(mpd_t *result); EXTINLINE void mpd_set_snan(mpd_t *result); @@ -835,6 +837,10 @@ MPD_PRAGMA(MPD_HIDE_SYMBOLS_END) /* restore previous scope rules */ #ifdef __cplusplus + #ifdef MPD_CLEAR_STDC_LIMIT_MACROS + #undef MPD_CLEAR_STDC_LIMIT_MACROS + #undef __STDC_LIMIT_MACROS + #endif } /* END extern "C" */ #endif diff --git a/Modules/_decimal/libmpdec/numbertheory.c b/Modules/_decimal/libmpdec/numbertheory.c index 10ce6dc1464c..4e035477e280 100644 --- a/Modules/_decimal/libmpdec/numbertheory.c +++ b/Modules/_decimal/libmpdec/numbertheory.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/Modules/_decimal/libmpdec/numbertheory.h b/Modules/_decimal/libmpdec/numbertheory.h index 109225461989..e94c157910c8 100644 --- a/Modules/_decimal/libmpdec/numbertheory.h +++ b/Modules/_decimal/libmpdec/numbertheory.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/Modules/_decimal/libmpdec/sixstep.c b/Modules/_decimal/libmpdec/sixstep.c index 7d0542d641dc..92d513ebe182 100644 --- a/Modules/_decimal/libmpdec/sixstep.c +++ b/Modules/_decimal/libmpdec/sixstep.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/Modules/_decimal/libmpdec/sixstep.h b/Modules/_decimal/libmpdec/sixstep.h index 0467007061b8..4a8b015e3a9b 100644 --- a/Modules/_decimal/libmpdec/sixstep.h +++ b/Modules/_decimal/libmpdec/sixstep.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/Modules/_decimal/libmpdec/transpose.c b/Modules/_decimal/libmpdec/transpose.c index 5e5d4b6625e9..55d6d8992279 100644 --- a/Modules/_decimal/libmpdec/transpose.c +++ b/Modules/_decimal/libmpdec/transpose.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -169,7 +169,7 @@ squaretrans(mpd_uint_t *buf, mpd_size_t cols) /* * Transpose 2^n * 2^n matrix. For cache efficiency, the matrix is split into * square blocks with side length 'SIDE'. First, the blocks are transposed, - * then a square tranposition is done on each individual block. + * then a square transposition is done on each individual block. */ static void squaretrans_pow2(mpd_uint_t *matrix, mpd_size_t size) diff --git a/Modules/_decimal/libmpdec/transpose.h b/Modules/_decimal/libmpdec/transpose.h index 7e349ee08df1..e1cd1fa17dd7 100644 --- a/Modules/_decimal/libmpdec/transpose.h +++ b/Modules/_decimal/libmpdec/transpose.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/Modules/_decimal/libmpdec/typearith.h b/Modules/_decimal/libmpdec/typearith.h index 614812c69e27..405237dac516 100644 --- a/Modules/_decimal/libmpdec/typearith.h +++ b/Modules/_decimal/libmpdec/typearith.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/Modules/_decimal/libmpdec/umodarith.h b/Modules/_decimal/libmpdec/umodarith.h index 436761bc4487..68d15188cb39 100644 --- a/Modules/_decimal/libmpdec/umodarith.h +++ b/Modules/_decimal/libmpdec/umodarith.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/Modules/_decimal/libmpdec/vccompat.h b/Modules/_decimal/libmpdec/vccompat.h index 276e0372cb6a..f58e023c628b 100644 --- a/Modules/_decimal/libmpdec/vccompat.h +++ b/Modules/_decimal/libmpdec/vccompat.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2016 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/Modules/_decimal/libmpdec/vcdiv64.asm b/Modules/_decimal/libmpdec/vcdiv64.asm index 31bba08b0cb0..6b6645673ab5 100644 --- a/Modules/_decimal/libmpdec/vcdiv64.asm +++ b/Modules/_decimal/libmpdec/vcdiv64.asm @@ -1,5 +1,5 @@ ; -; Copyright (c) 2008-2012 Stefan Krah. All rights reserved. +; Copyright (c) 2008-2016 Stefan Krah. All rights reserved. ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions diff --git a/Modules/_decimal/tests/bench.py b/Modules/_decimal/tests/bench.py index 7e4a210cd5a8..56566cc33905 100644 --- a/Modules/_decimal/tests/bench.py +++ b/Modules/_decimal/tests/bench.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - # # Copyright (C) 2001-2012 Python Software Foundation. All Rights Reserved. # Modified and extended by Stefan Krah. diff --git a/Modules/_decimal/tests/deccheck.py b/Modules/_decimal/tests/deccheck.py index 7a6b4109c20d..89433c083d0a 100644 --- a/Modules/_decimal/tests/deccheck.py +++ b/Modules/_decimal/tests/deccheck.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - # # Copyright (c) 2008-2012 Stefan Krah. All rights reserved. # @@ -38,6 +36,7 @@ from randdec import randfloat, all_unary, all_binary, all_ternary from randdec import unary_optarg, binary_optarg, ternary_optarg from formathelper import rand_format, rand_locale +from _pydecimal import _dec_from_triple C = import_fresh_module('decimal', fresh=['_decimal']) P = import_fresh_module('decimal', blocked=['_decimal']) @@ -372,7 +371,7 @@ def harrison_ulp(self, dec): return abs(a - b) def standard_ulp(self, dec, prec): - return P._dec_from_triple(0, '1', dec._exp+len(dec._int)-prec) + return _dec_from_triple(0, '1', dec._exp+len(dec._int)-prec) def rounding_direction(self, x, mode): """Determine the effective direction of the rounding when @@ -403,10 +402,10 @@ def check_ulpdiff(self, exact, rounded): # Convert infinities to the largest representable number + 1. x = exact if exact.is_infinite(): - x = P._dec_from_triple(exact._sign, '10', context.p.Emax) + x = _dec_from_triple(exact._sign, '10', context.p.Emax) y = rounded if rounded.is_infinite(): - y = P._dec_from_triple(rounded._sign, '10', context.p.Emax) + y = _dec_from_triple(rounded._sign, '10', context.p.Emax) # err = (rounded - exact) / ulp(rounded) self.maxctx.prec = p * 2 diff --git a/Modules/_decimal/tests/randdec.py b/Modules/_decimal/tests/randdec.py index ca0f0d17753c..d667f79f2c92 100644 --- a/Modules/_decimal/tests/randdec.py +++ b/Modules/_decimal/tests/randdec.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - # # Copyright (c) 2008-2012 Stefan Krah. All rights reserved. # diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index b3b69767086c..bf4bc4a8a24c 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -11,6 +11,8 @@ *-------------------------------------------------------------------- */ +#define PY_SSIZE_T_CLEAN + #include "Python.h" #include "structmember.h" @@ -185,8 +187,8 @@ typedef struct { PyObject* attrib; /* child elements */ - int length; /* actual number of items */ - int allocated; /* allocated items */ + Py_ssize_t length; /* actual number of items */ + Py_ssize_t allocated; /* allocated items */ /* this either points to _children or to a malloced buffer */ PyObject* *children; @@ -251,7 +253,7 @@ LOCAL(void) dealloc_extra(ElementObject* self) { ElementObjectExtra *myextra; - int i; + Py_ssize_t i; if (!self->extra) return; @@ -429,9 +431,9 @@ element_init(PyObject *self, PyObject *args, PyObject *kwds) } LOCAL(int) -element_resize(ElementObject* self, int extra) +element_resize(ElementObject* self, Py_ssize_t extra) { - int size; + Py_ssize_t size; PyObject* *children; /* make sure self->children can hold the given number of extra @@ -442,7 +444,7 @@ element_resize(ElementObject* self, int extra) return -1; } - size = self->extra->length + extra; + size = self->extra->length + extra; /* never overflows */ if (size > self->extra->allocated) { /* use Python 2.4's list growth strategy */ @@ -453,6 +455,8 @@ element_resize(ElementObject* self, int extra) * be safe. */ size = size ? size : 1; + if ((size_t)size > PY_SSIZE_T_MAX/sizeof(PyObject*)) + goto nomemory; if (self->extra->children != self->extra->_children) { /* Coverity CID #182 size_error: Allocating 1 bytes to pointer * "children", which needs at least 4 bytes. Although it's a @@ -613,7 +617,7 @@ element_gc_traverse(ElementObject *self, visitproc visit, void *arg) Py_VISIT(JOIN_OBJ(self->tail)); if (self->extra) { - int i; + Py_ssize_t i; Py_VISIT(self->extra->attrib); for (i = 0; i < self->extra->length; ++i) @@ -689,7 +693,7 @@ element_clearmethod(ElementObject* self, PyObject* args) static PyObject* element_copy(ElementObject* self, PyObject* args) { - int i; + Py_ssize_t i; ElementObject* element; if (!PyArg_ParseTuple(args, ":__copy__")) @@ -728,7 +732,7 @@ element_copy(ElementObject* self, PyObject* args) static PyObject* element_deepcopy(ElementObject* self, PyObject* args) { - int i; + Py_ssize_t i; ElementObject* element; PyObject* tag; PyObject* attrib; @@ -839,7 +843,7 @@ element_sizeof(PyObject* myself, PyObject* args) static PyObject * element_getstate(ElementObject *self) { - int i, noattrib; + Py_ssize_t i, noattrib; PyObject *instancedict = NULL, *children; /* Build a list of children. */ @@ -1077,7 +1081,7 @@ element_extend(ElementObject* self, PyObject* args) static PyObject* element_find(ElementObject *self, PyObject *args, PyObject *kwds) { - int i; + Py_ssize_t i; PyObject* tag; PyObject* namespaces = Py_None; static char *kwlist[] = {"path", "namespaces", 0}; @@ -1112,7 +1116,7 @@ element_find(ElementObject *self, PyObject *args, PyObject *kwds) static PyObject* element_findtext(ElementObject *self, PyObject *args, PyObject *kwds) { - int i; + Py_ssize_t i; PyObject* tag; PyObject* default_value = Py_None; PyObject* namespaces = Py_None; @@ -1153,7 +1157,7 @@ element_findtext(ElementObject *self, PyObject *args, PyObject *kwds) static PyObject* element_findall(ElementObject *self, PyObject *args, PyObject *kwds) { - int i; + Py_ssize_t i; PyObject* out; PyObject* tag; PyObject* namespaces = Py_None; @@ -1238,7 +1242,7 @@ element_get(ElementObject* self, PyObject* args, PyObject* kwds) static PyObject* element_getchildren(ElementObject* self, PyObject* args) { - int i; + Py_ssize_t i; PyObject* list; /* FIXME: report as deprecated? */ @@ -1310,11 +1314,9 @@ element_getitem(PyObject* self_, Py_ssize_t index) static PyObject* element_insert(ElementObject* self, PyObject* args) { - int i; - - int index; + Py_ssize_t index, i; PyObject* element; - if (!PyArg_ParseTuple(args, "iO!:insert", &index, + if (!PyArg_ParseTuple(args, "nO!:insert", &index, &Element_Type, &element)) return NULL; @@ -1402,7 +1404,7 @@ element_makeelement(PyObject* self, PyObject* args, PyObject* kw) static PyObject* element_remove(ElementObject* self, PyObject* args) { - int i; + Py_ssize_t i; PyObject* element; if (!PyArg_ParseTuple(args, "O!:remove", &Element_Type, &element)) @@ -1481,7 +1483,7 @@ static int element_setitem(PyObject* self_, Py_ssize_t index, PyObject* item) { ElementObject* self = (ElementObject*) self_; - int i; + Py_ssize_t i; PyObject* old; if (!self->extra || index < 0 || index >= self->extra->length) { @@ -2819,12 +2821,13 @@ makeuniversal(XMLParserObject* self, const char* string) * message string is the default for the given error_code. */ static void -expat_set_error(enum XML_Error error_code, int line, int column, char *message) +expat_set_error(enum XML_Error error_code, Py_ssize_t line, Py_ssize_t column, + const char *message) { PyObject *errmsg, *error, *position, *code; elementtreestate *st = ET_STATE_GLOBAL; - errmsg = PyUnicode_FromFormat("%s: line %d, column %d", + errmsg = PyUnicode_FromFormat("%s: line %zd, column %zd", message ? message : EXPAT(ErrorString)(error_code), line, column); if (errmsg == NULL) @@ -2848,7 +2851,7 @@ expat_set_error(enum XML_Error error_code, int line, int column, char *message) } Py_DECREF(code); - position = Py_BuildValue("(ii)", line, column); + position = Py_BuildValue("(nn)", line, column); if (!position) { Py_DECREF(error); return; @@ -3477,8 +3480,14 @@ xmlparser_parse_whole(XMLParserObject* self, PyObject* args) break; } + if (PyBytes_GET_SIZE(buffer) > INT_MAX) { + Py_DECREF(buffer); + Py_DECREF(reader); + PyErr_SetString(PyExc_OverflowError, "size does not fit in an int"); + return NULL; + } res = expat_parse( - self, PyBytes_AS_STRING(buffer), PyBytes_GET_SIZE(buffer), 0 + self, PyBytes_AS_STRING(buffer), (int)PyBytes_GET_SIZE(buffer), 0 ); Py_DECREF(buffer); @@ -3741,7 +3750,7 @@ PyInit__elementtree(void) if (expat_capi) { /* check that it's usable */ if (strcmp(expat_capi->magic, PyExpat_CAPI_MAGIC) != 0 || - expat_capi->size < sizeof(struct PyExpat_CAPI) || + (size_t)expat_capi->size < sizeof(struct PyExpat_CAPI) || expat_capi->MAJOR_VERSION != XML_MAJOR_VERSION || expat_capi->MINOR_VERSION != XML_MINOR_VERSION || expat_capi->MICRO_VERSION != XML_MICRO_VERSION) { diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c index a866fbf7f95d..1566b18991ec 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -31,10 +31,6 @@ #define HASH_OBJ_CONSTRUCTOR 0 #endif -/* Minimum OpenSSL version needed to support sha224 and higher. */ -#if defined(OPENSSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x00908000) -#define _OPENSSL_SUPPORTS_SHA2 -#endif typedef struct { PyObject_HEAD @@ -56,12 +52,10 @@ static PyTypeObject EVPtype; DEFINE_CONSTS_FOR_NEW(md5) DEFINE_CONSTS_FOR_NEW(sha1) -#ifdef _OPENSSL_SUPPORTS_SHA2 DEFINE_CONSTS_FOR_NEW(sha224) DEFINE_CONSTS_FOR_NEW(sha256) DEFINE_CONSTS_FOR_NEW(sha384) DEFINE_CONSTS_FOR_NEW(sha512) -#endif static EVPobject * @@ -557,6 +551,7 @@ PKCS5_PBKDF2_HMAC_fast(const char *pass, int passlen, return 1; } +/* LCOV_EXCL_START */ static PyObject * _setException(PyObject *exc) { @@ -585,6 +580,7 @@ _setException(PyObject *exc) } return NULL; } +/* LCOV_EXCL_STOP */ PyDoc_STRVAR(pbkdf2_hmac__doc__, "pbkdf2_hmac(hash_name, password, salt, iterations, dklen=None) -> key\n\ @@ -796,12 +792,10 @@ generate_hash_name_list(void) GEN_CONSTRUCTOR(md5) GEN_CONSTRUCTOR(sha1) -#ifdef _OPENSSL_SUPPORTS_SHA2 GEN_CONSTRUCTOR(sha224) GEN_CONSTRUCTOR(sha256) GEN_CONSTRUCTOR(sha384) GEN_CONSTRUCTOR(sha512) -#endif /* List of functions exported by this module */ @@ -813,12 +807,10 @@ static struct PyMethodDef EVP_functions[] = { #endif CONSTRUCTOR_METH_DEF(md5), CONSTRUCTOR_METH_DEF(sha1), -#ifdef _OPENSSL_SUPPORTS_SHA2 CONSTRUCTOR_METH_DEF(sha224), CONSTRUCTOR_METH_DEF(sha256), CONSTRUCTOR_METH_DEF(sha384), CONSTRUCTOR_METH_DEF(sha512), -#endif {NULL, NULL} /* Sentinel */ }; @@ -875,11 +867,9 @@ PyInit__hashlib(void) /* these constants are used by the convenience constructors */ INIT_CONSTRUCTOR_CONSTANTS(md5); INIT_CONSTRUCTOR_CONSTANTS(sha1); -#ifdef _OPENSSL_SUPPORTS_SHA2 INIT_CONSTRUCTOR_CONSTANTS(sha224); INIT_CONSTRUCTOR_CONSTANTS(sha256); INIT_CONSTRUCTOR_CONSTANTS(sha384); INIT_CONSTRUCTOR_CONSTANTS(sha512); -#endif return m; } diff --git a/Modules/_heapqmodule.c b/Modules/_heapqmodule.c index 96afcdc1b377..4372ad497d15 100644 --- a/Modules/_heapqmodule.c +++ b/Modules/_heapqmodule.c @@ -9,12 +9,11 @@ annotated by François Pinard, and converted to C by Raymond Hettinger. #include "Python.h" static int -_siftdown(PyListObject *heap, Py_ssize_t startpos, Py_ssize_t pos) +siftdown(PyListObject *heap, Py_ssize_t startpos, Py_ssize_t pos) { - PyObject *newitem, *parent, *olditem; + PyObject *newitem, *parent; + Py_ssize_t parentpos, size; int cmp; - Py_ssize_t parentpos; - Py_ssize_t size; assert(PyList_Check(heap)); size = PyList_GET_SIZE(heap); @@ -23,104 +22,76 @@ _siftdown(PyListObject *heap, Py_ssize_t startpos, Py_ssize_t pos) return -1; } - newitem = PyList_GET_ITEM(heap, pos); - Py_INCREF(newitem); /* Follow the path to the root, moving parents down until finding a place newitem fits. */ - while (pos > startpos){ + newitem = PyList_GET_ITEM(heap, pos); + while (pos > startpos) { parentpos = (pos - 1) >> 1; parent = PyList_GET_ITEM(heap, parentpos); cmp = PyObject_RichCompareBool(newitem, parent, Py_LT); - if (cmp == -1) { - Py_DECREF(newitem); + if (cmp == -1) return -1; - } if (size != PyList_GET_SIZE(heap)) { - Py_DECREF(newitem); PyErr_SetString(PyExc_RuntimeError, "list changed size during iteration"); return -1; } if (cmp == 0) break; - Py_INCREF(parent); - olditem = PyList_GET_ITEM(heap, pos); + parent = PyList_GET_ITEM(heap, parentpos); + newitem = PyList_GET_ITEM(heap, pos); + PyList_SET_ITEM(heap, parentpos, newitem); PyList_SET_ITEM(heap, pos, parent); - Py_DECREF(olditem); pos = parentpos; - if (size != PyList_GET_SIZE(heap)) { - PyErr_SetString(PyExc_RuntimeError, - "list changed size during iteration"); - return -1; - } } - Py_DECREF(PyList_GET_ITEM(heap, pos)); - PyList_SET_ITEM(heap, pos, newitem); return 0; } static int -_siftup(PyListObject *heap, Py_ssize_t pos) +siftup(PyListObject *heap, Py_ssize_t pos) { - Py_ssize_t startpos, endpos, childpos, rightpos; + Py_ssize_t startpos, endpos, childpos, rightpos, limit; + PyObject *tmp1, *tmp2; int cmp; - PyObject *newitem, *tmp, *olditem; - Py_ssize_t size; assert(PyList_Check(heap)); - size = PyList_GET_SIZE(heap); - endpos = size; + endpos = PyList_GET_SIZE(heap); startpos = pos; if (pos >= endpos) { PyErr_SetString(PyExc_IndexError, "index out of range"); return -1; } - newitem = PyList_GET_ITEM(heap, pos); - Py_INCREF(newitem); /* Bubble up the smaller child until hitting a leaf. */ - childpos = 2*pos + 1; /* leftmost child position */ - while (childpos < endpos) { + limit = endpos / 2; /* smallest pos that has no child */ + while (pos < limit) { /* Set childpos to index of smaller child. */ + childpos = 2*pos + 1; /* leftmost child position */ rightpos = childpos + 1; if (rightpos < endpos) { cmp = PyObject_RichCompareBool( PyList_GET_ITEM(heap, childpos), PyList_GET_ITEM(heap, rightpos), Py_LT); - if (cmp == -1) { - Py_DECREF(newitem); + if (cmp == -1) return -1; - } if (cmp == 0) childpos = rightpos; - } - if (size != PyList_GET_SIZE(heap)) { - Py_DECREF(newitem); - PyErr_SetString(PyExc_RuntimeError, - "list changed size during iteration"); - return -1; + if (endpos != PyList_GET_SIZE(heap)) { + PyErr_SetString(PyExc_RuntimeError, + "list changed size during iteration"); + return -1; + } } /* Move the smaller child up. */ - tmp = PyList_GET_ITEM(heap, childpos); - Py_INCREF(tmp); - olditem = PyList_GET_ITEM(heap, pos); - PyList_SET_ITEM(heap, pos, tmp); - Py_DECREF(olditem); + tmp1 = PyList_GET_ITEM(heap, childpos); + tmp2 = PyList_GET_ITEM(heap, pos); + PyList_SET_ITEM(heap, childpos, tmp2); + PyList_SET_ITEM(heap, pos, tmp1); pos = childpos; - childpos = 2*pos + 1; - if (size != PyList_GET_SIZE(heap)) { - PyErr_SetString(PyExc_RuntimeError, - "list changed size during iteration"); - return -1; - } } - - /* The leaf at pos is empty now. Put newitem there, and bubble - it up to its final resting place (by sifting its parents down). */ - Py_DECREF(PyList_GET_ITEM(heap, pos)); - PyList_SET_ITEM(heap, pos, newitem); - return _siftdown(heap, startpos, pos); + /* Bubble it up to its final resting place (by sifting its parents down). */ + return siftdown(heap, startpos, pos); } static PyObject * @@ -139,17 +110,16 @@ heappush(PyObject *self, PyObject *args) if (PyList_Append(heap, item) == -1) return NULL; - if (_siftdown((PyListObject *)heap, 0, PyList_GET_SIZE(heap)-1) == -1) + if (siftdown((PyListObject *)heap, 0, PyList_GET_SIZE(heap)-1) == -1) return NULL; - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } PyDoc_STRVAR(heappush_doc, "heappush(heap, item) -> None. Push item onto heap, maintaining the heap invariant."); static PyObject * -heappop(PyObject *self, PyObject *heap) +heappop_internal(PyObject *heap, int siftup_func(PyListObject *, Py_ssize_t)) { PyObject *lastelt, *returnitem; Py_ssize_t n; @@ -159,7 +129,7 @@ heappop(PyObject *self, PyObject *heap) return NULL; } - /* # raises appropriate IndexError if heap is empty */ + /* raises IndexError if the heap is empty */ n = PyList_GET_SIZE(heap); if (n == 0) { PyErr_SetString(PyExc_IndexError, "index out of range"); @@ -178,18 +148,24 @@ heappop(PyObject *self, PyObject *heap) return lastelt; returnitem = PyList_GET_ITEM(heap, 0); PyList_SET_ITEM(heap, 0, lastelt); - if (_siftup((PyListObject *)heap, 0) == -1) { + if (siftup_func((PyListObject *)heap, 0) == -1) { Py_DECREF(returnitem); return NULL; } return returnitem; } +static PyObject * +heappop(PyObject *self, PyObject *heap) +{ + return heappop_internal(heap, siftup); +} + PyDoc_STRVAR(heappop_doc, "Pop the smallest item off the heap, maintaining the heap invariant."); static PyObject * -heapreplace(PyObject *self, PyObject *args) +heapreplace_internal(PyObject *args, int siftup_func(PyListObject *, Py_ssize_t)) { PyObject *heap, *item, *returnitem; @@ -209,13 +185,19 @@ heapreplace(PyObject *self, PyObject *args) returnitem = PyList_GET_ITEM(heap, 0); Py_INCREF(item); PyList_SET_ITEM(heap, 0, item); - if (_siftup((PyListObject *)heap, 0) == -1) { + if (siftup_func((PyListObject *)heap, 0) == -1) { Py_DECREF(returnitem); return NULL; } return returnitem; } +static PyObject * +heapreplace(PyObject *self, PyObject *args) +{ + return heapreplace_internal(args, siftup); +} + PyDoc_STRVAR(heapreplace_doc, "heapreplace(heap, item) -> value. Pop and return the current smallest value, and add the new item.\n\ \n\ @@ -256,7 +238,7 @@ heappushpop(PyObject *self, PyObject *args) returnitem = PyList_GET_ITEM(heap, 0); Py_INCREF(item); PyList_SET_ITEM(heap, 0, item); - if (_siftup((PyListObject *)heap, 0) == -1) { + if (siftup((PyListObject *)heap, 0) == -1) { Py_DECREF(returnitem); return NULL; } @@ -269,7 +251,7 @@ from the heap. The combined action runs more efficiently than\n\ heappush() followed by a separate call to heappop()."); static PyObject * -heapify(PyObject *self, PyObject *heap) +heapify_internal(PyObject *heap, int siftup_func(PyListObject *, Py_ssize_t)) { Py_ssize_t i, n; @@ -287,141 +269,65 @@ heapify(PyObject *self, PyObject *heap) and that's again n//2-1. */ for (i=n/2-1 ; i>=0 ; i--) - if(_siftup((PyListObject *)heap, i) == -1) + if(siftup_func((PyListObject *)heap, i) == -1) return NULL; - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } -PyDoc_STRVAR(heapify_doc, -"Transform list into a heap, in-place, in O(len(heap)) time."); - static PyObject * -nlargest(PyObject *self, PyObject *args) +heapify(PyObject *self, PyObject *heap) { - PyObject *heap=NULL, *elem, *iterable, *sol, *it, *oldelem; - Py_ssize_t i, n; - int cmp; - - if (!PyArg_ParseTuple(args, "nO:nlargest", &n, &iterable)) - return NULL; - - it = PyObject_GetIter(iterable); - if (it == NULL) - return NULL; - - heap = PyList_New(0); - if (heap == NULL) - goto fail; - - for (i=0 ; i=0 ; i--) - if(_siftup((PyListObject *)heap, i) == -1) - goto fail; - - sol = PyList_GET_ITEM(heap, 0); - while (1) { - elem = PyIter_Next(it); - if (elem == NULL) { - if (PyErr_Occurred()) - goto fail; - else - goto sortit; - } - cmp = PyObject_RichCompareBool(sol, elem, Py_LT); - if (cmp == -1) { - Py_DECREF(elem); - goto fail; - } - if (cmp == 0) { - Py_DECREF(elem); - continue; - } - oldelem = PyList_GET_ITEM(heap, 0); - PyList_SET_ITEM(heap, 0, elem); - Py_DECREF(oldelem); - if (_siftup((PyListObject *)heap, 0) == -1) - goto fail; - sol = PyList_GET_ITEM(heap, 0); - } -sortit: - if (PyList_Sort(heap) == -1) - goto fail; - if (PyList_Reverse(heap) == -1) - goto fail; - Py_DECREF(it); - return heap; - -fail: - Py_DECREF(it); - Py_XDECREF(heap); - return NULL; + return heapify_internal(heap, siftup); } -PyDoc_STRVAR(nlargest_doc, -"Find the n largest elements in a dataset.\n\ -\n\ -Equivalent to: sorted(iterable, reverse=True)[:n]\n"); +PyDoc_STRVAR(heapify_doc, +"Transform list into a heap, in-place, in O(len(heap)) time."); static int -_siftdownmax(PyListObject *heap, Py_ssize_t startpos, Py_ssize_t pos) +siftdown_max(PyListObject *heap, Py_ssize_t startpos, Py_ssize_t pos) { PyObject *newitem, *parent; + Py_ssize_t parentpos, size; int cmp; - Py_ssize_t parentpos; assert(PyList_Check(heap)); - if (pos >= PyList_GET_SIZE(heap)) { + size = PyList_GET_SIZE(heap); + if (pos >= size) { PyErr_SetString(PyExc_IndexError, "index out of range"); return -1; } - newitem = PyList_GET_ITEM(heap, pos); - Py_INCREF(newitem); /* Follow the path to the root, moving parents down until finding a place newitem fits. */ - while (pos > startpos){ + newitem = PyList_GET_ITEM(heap, pos); + while (pos > startpos) { parentpos = (pos - 1) >> 1; parent = PyList_GET_ITEM(heap, parentpos); cmp = PyObject_RichCompareBool(parent, newitem, Py_LT); - if (cmp == -1) { - Py_DECREF(newitem); + if (cmp == -1) + return -1; + if (size != PyList_GET_SIZE(heap)) { + PyErr_SetString(PyExc_RuntimeError, + "list changed size during iteration"); return -1; } if (cmp == 0) break; - Py_INCREF(parent); - Py_DECREF(PyList_GET_ITEM(heap, pos)); + parent = PyList_GET_ITEM(heap, parentpos); + newitem = PyList_GET_ITEM(heap, pos); + PyList_SET_ITEM(heap, parentpos, newitem); PyList_SET_ITEM(heap, pos, parent); pos = parentpos; } - Py_DECREF(PyList_GET_ITEM(heap, pos)); - PyList_SET_ITEM(heap, pos, newitem); return 0; } static int -_siftupmax(PyListObject *heap, Py_ssize_t pos) +siftup_max(PyListObject *heap, Py_ssize_t pos) { - Py_ssize_t startpos, endpos, childpos, rightpos; + Py_ssize_t startpos, endpos, childpos, rightpos, limit; + PyObject *tmp1, *tmp2; int cmp; - PyObject *newitem, *tmp; assert(PyList_Check(heap)); endpos = PyList_GET_SIZE(heap); @@ -430,125 +336,62 @@ _siftupmax(PyListObject *heap, Py_ssize_t pos) PyErr_SetString(PyExc_IndexError, "index out of range"); return -1; } - newitem = PyList_GET_ITEM(heap, pos); - Py_INCREF(newitem); /* Bubble up the smaller child until hitting a leaf. */ - childpos = 2*pos + 1; /* leftmost child position */ - while (childpos < endpos) { + limit = endpos / 2; /* smallest pos that has no child */ + while (pos < limit) { /* Set childpos to index of smaller child. */ + childpos = 2*pos + 1; /* leftmost child position */ rightpos = childpos + 1; if (rightpos < endpos) { cmp = PyObject_RichCompareBool( PyList_GET_ITEM(heap, rightpos), PyList_GET_ITEM(heap, childpos), Py_LT); - if (cmp == -1) { - Py_DECREF(newitem); + if (cmp == -1) return -1; - } if (cmp == 0) childpos = rightpos; + if (endpos != PyList_GET_SIZE(heap)) { + PyErr_SetString(PyExc_RuntimeError, + "list changed size during iteration"); + return -1; + } } /* Move the smaller child up. */ - tmp = PyList_GET_ITEM(heap, childpos); - Py_INCREF(tmp); - Py_DECREF(PyList_GET_ITEM(heap, pos)); - PyList_SET_ITEM(heap, pos, tmp); + tmp1 = PyList_GET_ITEM(heap, childpos); + tmp2 = PyList_GET_ITEM(heap, pos); + PyList_SET_ITEM(heap, childpos, tmp2); + PyList_SET_ITEM(heap, pos, tmp1); pos = childpos; - childpos = 2*pos + 1; } - - /* The leaf at pos is empty now. Put newitem there, and bubble - it up to its final resting place (by sifting its parents down). */ - Py_DECREF(PyList_GET_ITEM(heap, pos)); - PyList_SET_ITEM(heap, pos, newitem); - return _siftdownmax(heap, startpos, pos); + /* Bubble it up to its final resting place (by sifting its parents down). */ + return siftdown_max(heap, startpos, pos); } static PyObject * -nsmallest(PyObject *self, PyObject *args) +heappop_max(PyObject *self, PyObject *heap) { - PyObject *heap=NULL, *elem, *iterable, *los, *it, *oldelem; - Py_ssize_t i, n; - int cmp; - - if (!PyArg_ParseTuple(args, "nO:nsmallest", &n, &iterable)) - return NULL; - - it = PyObject_GetIter(iterable); - if (it == NULL) - return NULL; - - heap = PyList_New(0); - if (heap == NULL) - goto fail; - - for (i=0 ; i=0 ; i--) - if(_siftupmax((PyListObject *)heap, i) == -1) - goto fail; - - los = PyList_GET_ITEM(heap, 0); - while (1) { - elem = PyIter_Next(it); - if (elem == NULL) { - if (PyErr_Occurred()) - goto fail; - else - goto sortit; - } - cmp = PyObject_RichCompareBool(elem, los, Py_LT); - if (cmp == -1) { - Py_DECREF(elem); - goto fail; - } - if (cmp == 0) { - Py_DECREF(elem); - continue; - } +PyDoc_STRVAR(heappop_max_doc, "Maxheap variant of heappop."); - oldelem = PyList_GET_ITEM(heap, 0); - PyList_SET_ITEM(heap, 0, elem); - Py_DECREF(oldelem); - if (_siftupmax((PyListObject *)heap, 0) == -1) - goto fail; - los = PyList_GET_ITEM(heap, 0); - } +static PyObject * +heapreplace_max(PyObject *self, PyObject *args) +{ + return heapreplace_internal(args, siftup_max); +} -sortit: - if (PyList_Sort(heap) == -1) - goto fail; - Py_DECREF(it); - return heap; +PyDoc_STRVAR(heapreplace_max_doc, "Maxheap variant of heapreplace"); -fail: - Py_DECREF(it); - Py_XDECREF(heap); - return NULL; +static PyObject * +heapify_max(PyObject *self, PyObject *heap) +{ + return heapify_internal(heap, siftup_max); } -PyDoc_STRVAR(nsmallest_doc, -"Find the n smallest elements in a dataset.\n\ -\n\ -Equivalent to: sorted(iterable)[:n]\n"); +PyDoc_STRVAR(heapify_max_doc, "Maxheap variant of heapify."); static PyMethodDef heapq_methods[] = { {"heappush", (PyCFunction)heappush, @@ -561,10 +404,12 @@ static PyMethodDef heapq_methods[] = { METH_VARARGS, heapreplace_doc}, {"heapify", (PyCFunction)heapify, METH_O, heapify_doc}, - {"nlargest", (PyCFunction)nlargest, - METH_VARARGS, nlargest_doc}, - {"nsmallest", (PyCFunction)nsmallest, - METH_VARARGS, nsmallest_doc}, + {"_heappop_max", (PyCFunction)heappop_max, + METH_O, heappop_max_doc}, + {"_heapreplace_max",(PyCFunction)heapreplace_max, + METH_VARARGS, heapreplace_max_doc}, + {"_heapify_max", (PyCFunction)heapify_max, + METH_O, heapify_max_doc}, {NULL, NULL} /* sentinel */ }; diff --git a/Modules/_io/_iomodule.c b/Modules/_io/_iomodule.c index 9866fbe82be9..e70c4b7611f2 100644 --- a/Modules/_io/_iomodule.c +++ b/Modules/_io/_iomodule.c @@ -235,11 +235,12 @@ io_open(PyObject *self, PyObject *args, PyObject *kwds) char rawmode[6], *m; int line_buffering, isatty; - PyObject *raw, *modeobj = NULL, *buffer = NULL, *wrapper = NULL; + PyObject *raw, *modeobj = NULL, *buffer, *wrapper, *result = NULL; + _Py_IDENTIFIER(_blksize); _Py_IDENTIFIER(isatty); - _Py_IDENTIFIER(fileno); _Py_IDENTIFIER(mode); + _Py_IDENTIFIER(close); if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|sizzziO:open", kwlist, &file, &mode, &buffering, @@ -354,6 +355,7 @@ io_open(PyObject *self, PyObject *args, PyObject *kwds) "OsiO", file, rawmode, closefd, opener); if (raw == NULL) return NULL; + result = raw; modeobj = PyUnicode_FromString(mode); if (modeobj == NULL) @@ -378,24 +380,14 @@ io_open(PyObject *self, PyObject *args, PyObject *kwds) line_buffering = 0; if (buffering < 0) { - buffering = DEFAULT_BUFFER_SIZE; -#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE - { - struct stat st; - long fileno; - PyObject *res = _PyObject_CallMethodId(raw, &PyId_fileno, NULL); - if (res == NULL) - goto error; - - fileno = PyLong_AsLong(res); - Py_DECREF(res); - if (fileno == -1 && PyErr_Occurred()) - goto error; - - if (fstat(fileno, &st) >= 0 && st.st_blksize > 1) - buffering = st.st_blksize; - } -#endif + PyObject *blksize_obj; + blksize_obj = _PyObject_GetAttrId(raw, &PyId__blksize); + if (blksize_obj == NULL) + goto error; + buffering = PyLong_AsLong(blksize_obj); + Py_DECREF(blksize_obj); + if (buffering == -1 && PyErr_Occurred()) + goto error; } if (buffering < 0) { PyErr_SetString(PyExc_ValueError, @@ -412,7 +404,7 @@ io_open(PyObject *self, PyObject *args, PyObject *kwds) } Py_DECREF(modeobj); - return raw; + return result; } /* wraps into a buffered file */ @@ -433,15 +425,16 @@ io_open(PyObject *self, PyObject *args, PyObject *kwds) buffer = PyObject_CallFunction(Buffered_class, "Oi", raw, buffering); } - Py_CLEAR(raw); if (buffer == NULL) goto error; + result = buffer; + Py_DECREF(raw); /* if binary, returns the buffered file */ if (binary) { Py_DECREF(modeobj); - return buffer; + return result; } /* wraps into a TextIOWrapper */ @@ -450,20 +443,26 @@ io_open(PyObject *self, PyObject *args, PyObject *kwds) buffer, encoding, errors, newline, line_buffering); - Py_CLEAR(buffer); if (wrapper == NULL) goto error; + result = wrapper; + Py_DECREF(buffer); if (_PyObject_SetAttrId(wrapper, &PyId_mode, modeobj) < 0) goto error; Py_DECREF(modeobj); - return wrapper; + return result; error: - Py_XDECREF(raw); + if (result != NULL) { + PyObject *exc, *val, *tb, *close_result; + PyErr_Fetch(&exc, &val, &tb); + close_result = _PyObject_CallMethodId(result, &PyId_close, NULL); + _PyErr_ChainExceptions(exc, val, tb); + Py_XDECREF(close_result); + Py_DECREF(result); + } Py_XDECREF(modeobj); - Py_XDECREF(buffer); - Py_XDECREF(wrapper); return NULL; } @@ -539,6 +538,20 @@ _PyIO_ConvertSsize_t(PyObject *obj, void *result) { } +_PyIO_State * +_PyIO_get_module_state(void) +{ + PyObject *mod = PyState_FindModule(&_PyIO_Module); + _PyIO_State *state; + if (mod == NULL || (state = IO_MOD_STATE(mod)) == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "could not find io module state " + "(interpreter shutdown?)"); + return NULL; + } + return state; +} + PyObject * _PyIO_get_locale_module(_PyIO_State *state) { diff --git a/Modules/_io/_iomodule.h b/Modules/_io/_iomodule.h index b90a658397de..9d5205ec3051 100644 --- a/Modules/_io/_iomodule.h +++ b/Modules/_io/_iomodule.h @@ -69,7 +69,7 @@ extern int _PyIO_trap_eintr(void); * Offset type for positioning. */ -/* Printing a variable of type off_t (with e.g., PyString_FromFormat) +/* Printing a variable of type off_t (with e.g., PyUnicode_FromFormat) correctly and without producing compiler warnings is surprisingly painful. We identify an integer type whose size matches off_t and then: (1) cast the off_t to that integer type and (2) use the appropriate conversion @@ -135,8 +135,9 @@ typedef struct { } _PyIO_State; #define IO_MOD_STATE(mod) ((_PyIO_State *)PyModule_GetState(mod)) -#define IO_STATE IO_MOD_STATE(PyState_FindModule(&_PyIO_Module)) +#define IO_STATE() _PyIO_get_module_state() +extern _PyIO_State *_PyIO_get_module_state(void); extern PyObject *_PyIO_get_locale_module(_PyIO_State *); extern PyObject *_PyIO_str_close; diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c index a04b48dd3a98..692ce41cf99a 100644 --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -24,6 +24,7 @@ _Py_IDENTIFIER(read); _Py_IDENTIFIER(read1); _Py_IDENTIFIER(readable); _Py_IDENTIFIER(readinto); +_Py_IDENTIFIER(readinto1); _Py_IDENTIFIER(writable); _Py_IDENTIFIER(write); @@ -47,17 +48,21 @@ PyDoc_STRVAR(bufferediobase_doc, ); static PyObject * -bufferediobase_readinto(PyObject *self, PyObject *args) +_bufferediobase_readinto_generic(PyObject *self, PyObject *args, char readinto1) { Py_buffer buf; Py_ssize_t len; PyObject *data; - if (!PyArg_ParseTuple(args, "w*:readinto", &buf)) { + if (!PyArg_ParseTuple(args, + readinto1 ? "w*:readinto1" : "w*:readinto", + &buf)) { return NULL; } - data = _PyObject_CallMethodId(self, &PyId_read, "n", buf.len); + data = _PyObject_CallMethodId(self, + readinto1 ? &PyId_read1 : &PyId_read, + "n", buf.len); if (data == NULL) goto error; @@ -88,10 +93,24 @@ bufferediobase_readinto(PyObject *self, PyObject *args) return NULL; } +static PyObject * +bufferediobase_readinto(PyObject *self, PyObject *args) +{ + return _bufferediobase_readinto_generic(self, args, 0); +} + +static PyObject * +bufferediobase_readinto1(PyObject *self, PyObject *args) +{ + return _bufferediobase_readinto_generic(self, args, 1); +} + static PyObject * bufferediobase_unsupported(const char *message) { - PyErr_SetString(IO_STATE->unsupported_operation, message); + _PyIO_State *state = IO_STATE(); + if (state != NULL) + PyErr_SetString(state->unsupported_operation, message); return NULL; } @@ -165,6 +184,7 @@ static PyMethodDef bufferediobase_methods[] = { {"read", bufferediobase_read, METH_VARARGS, bufferediobase_read_doc}, {"read1", bufferediobase_read1, METH_VARARGS, bufferediobase_read1_doc}, {"readinto", bufferediobase_readinto, METH_VARARGS, NULL}, + {"readinto1", bufferediobase_readinto1, METH_VARARGS, NULL}, {"write", bufferediobase_write, METH_VARARGS, bufferediobase_write_doc}, {NULL, NULL} }; @@ -541,19 +561,8 @@ buffered_close(buffered *self, PyObject *args) } if (exc != NULL) { - if (res != NULL) { - Py_CLEAR(res); - PyErr_Restore(exc, val, tb); - } - else { - PyObject *val2; - Py_DECREF(exc); - Py_XDECREF(tb); - PyErr_Fetch(&exc, &val2, &tb); - PyErr_NormalizeException(&exc, &val2, &tb); - PyException_SetContext(val2, val); - PyErr_Restore(exc, val2, tb); - } + _PyErr_ChainExceptions(exc, val, tb); + Py_CLEAR(res); } end: @@ -986,7 +995,7 @@ buffered_read1(buffered *self, PyObject *args) } static PyObject * -buffered_readinto(buffered *self, PyObject *args) +_buffered_readinto_generic(buffered *self, PyObject *args, char readinto1) { Py_buffer buf; Py_ssize_t n, written = 0, remaining; @@ -994,7 +1003,9 @@ buffered_readinto(buffered *self, PyObject *args) CHECK_INITIALIZED(self) - if (!PyArg_ParseTuple(args, "w*:readinto", &buf)) + if (!PyArg_ParseTuple(args, + readinto1 ? "w*:readinto1" : "w*:readinto", + &buf)) return NULL; n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t); @@ -1032,7 +1043,10 @@ buffered_readinto(buffered *self, PyObject *args) n = _bufferedreader_raw_read(self, (char *) buf.buf + written, remaining); } - else { + + /* In readinto1 mode, we do not want to fill the internal + buffer if we already have some data to return */ + else if (!(readinto1 && written)) { n = _bufferedreader_fill_buffer(self); if (n > 0) { if (n > remaining) @@ -1043,6 +1057,9 @@ buffered_readinto(buffered *self, PyObject *args) continue; /* short circuit */ } } + else + n = 0; + if (n == 0 || (n == -2 && written > 0)) break; if (n < 0) { @@ -1052,6 +1069,12 @@ buffered_readinto(buffered *self, PyObject *args) } goto end; } + + /* At most one read in readinto1 mode */ + if (readinto1) { + written += n; + break; + } } res = PyLong_FromSsize_t(written); @@ -1062,6 +1085,19 @@ buffered_readinto(buffered *self, PyObject *args) return res; } +static PyObject * +buffered_readinto(buffered *self, PyObject *args) +{ + return _buffered_readinto_generic(self, args, 0); +} + +static PyObject * +buffered_readinto1(buffered *self, PyObject *args) +{ + return _buffered_readinto_generic(self, args, 1); +} + + static PyObject * _buffered_readline(buffered *self, Py_ssize_t limit) { @@ -1368,7 +1404,7 @@ buffered_repr(buffered *self) nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name); if (nameobj == NULL) { - if (PyErr_ExceptionMatches(PyExc_AttributeError)) + if (PyErr_ExceptionMatches(PyExc_Exception)) PyErr_Clear(); else return NULL; @@ -1747,6 +1783,7 @@ static PyMethodDef bufferedreader_methods[] = { {"peek", (PyCFunction)buffered_peek, METH_VARARGS}, {"read1", (PyCFunction)buffered_read1, METH_VARARGS}, {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS}, + {"readinto1", (PyCFunction)buffered_readinto1, METH_VARARGS}, {"readline", (PyCFunction)buffered_readline, METH_VARARGS}, {"seek", (PyCFunction)buffered_seek, METH_VARARGS}, {"tell", (PyCFunction)buffered_tell, METH_NOARGS}, @@ -2294,6 +2331,8 @@ static void bufferedrwpair_dealloc(rwpair *self) { _PyObject_GC_UNTRACK(self); + if (self->weakreflist != NULL) + PyObject_ClearWeakRefs((PyObject *)self); Py_CLEAR(self->reader); Py_CLEAR(self->writer); Py_CLEAR(self->dict); @@ -2303,9 +2342,14 @@ bufferedrwpair_dealloc(rwpair *self) static PyObject * _forward_call(buffered *self, _Py_Identifier *name, PyObject *args) { - PyObject *func = _PyObject_GetAttrId((PyObject *)self, name); - PyObject *ret; + PyObject *func, *ret; + if (self == NULL) { + PyErr_SetString(PyExc_ValueError, + "I/O operation on uninitialized object"); + return NULL; + } + func = _PyObject_GetAttrId((PyObject *)self, name); if (func == NULL) { PyErr_SetString(PyExc_AttributeError, name->string); return NULL; @@ -2340,6 +2384,12 @@ bufferedrwpair_readinto(rwpair *self, PyObject *args) return _forward_call(self->reader, &PyId_readinto, args); } +static PyObject * +bufferedrwpair_readinto1(rwpair *self, PyObject *args) +{ + return _forward_call(self->reader, &PyId_readinto1, args); +} + static PyObject * bufferedrwpair_write(rwpair *self, PyObject *args) { @@ -2405,6 +2455,7 @@ static PyMethodDef bufferedrwpair_methods[] = { {"peek", (PyCFunction)bufferedrwpair_peek, METH_VARARGS}, {"read1", (PyCFunction)bufferedrwpair_read1, METH_VARARGS}, {"readinto", (PyCFunction)bufferedrwpair_readinto, METH_VARARGS}, + {"readinto1", (PyCFunction)bufferedrwpair_readinto1, METH_VARARGS}, {"write", (PyCFunction)bufferedrwpair_write, METH_VARARGS}, {"flush", (PyCFunction)bufferedrwpair_flush, METH_NOARGS}, @@ -2553,6 +2604,7 @@ static PyMethodDef bufferedrandom_methods[] = { {"read", (PyCFunction)buffered_read, METH_VARARGS}, {"read1", (PyCFunction)buffered_read1, METH_VARARGS}, {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS}, + {"readinto1", (PyCFunction)buffered_readinto1, METH_VARARGS}, {"readline", (PyCFunction)buffered_readline, METH_VARARGS}, {"peek", (PyCFunction)buffered_peek, METH_VARARGS}, {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS}, diff --git a/Modules/_io/bytesio.c b/Modules/_io/bytesio.c index 54840bb88a25..fc4ea74b23f3 100644 --- a/Modules/_io/bytesio.c +++ b/Modules/_io/bytesio.c @@ -4,10 +4,9 @@ typedef struct { PyObject_HEAD - char *buf; + PyObject *buf; Py_ssize_t pos; Py_ssize_t string_size; - size_t buf_size; PyObject *dict; PyObject *weakreflist; Py_ssize_t exports; @@ -18,6 +17,12 @@ typedef struct { bytesio *source; } bytesiobuf; +/* The bytesio object can be in three states: + * Py_REFCNT(buf) == 1, exports == 0. + * Py_REFCNT(buf) > 1. exports == 0, + first modification or export causes the internal buffer copying. + * exports > 0. Py_REFCNT(buf) == 1, any modifications are forbidden. +*/ #define CHECK_CLOSED(self) \ if ((self)->buf == NULL) { \ @@ -33,40 +38,60 @@ typedef struct { return NULL; \ } +#define SHARED_BUF(self) (Py_REFCNT((self)->buf) > 1) + /* Internal routine to get a line from the buffer of a BytesIO object. Returns the length between the current position to the next newline character. */ static Py_ssize_t -get_line(bytesio *self, char **output) +scan_eol(bytesio *self, Py_ssize_t len) { - char *n; - const char *str_end; - Py_ssize_t len; + const char *start, *n; + Py_ssize_t maxlen; assert(self->buf != NULL); /* Move to the end of the line, up to the end of the string, s. */ - str_end = self->buf + self->string_size; - for (n = self->buf + self->pos; - n < str_end && *n != '\n'; - n++); - - /* Skip the newline character */ - if (n < str_end) - n++; - - /* Get the length from the current position to the end of the line. */ - len = n - (self->buf + self->pos); - *output = self->buf + self->pos; - + start = PyBytes_AS_STRING(self->buf) + self->pos; + maxlen = self->string_size - self->pos; + if (len < 0 || len > maxlen) + len = maxlen; + + if (len) { + n = memchr(start, '\n', len); + if (n) + /* Get the length from the current position to the end of + the line. */ + len = n - start + 1; + } assert(len >= 0); assert(self->pos < PY_SSIZE_T_MAX - len); - self->pos += len; return len; } +/* Internal routine for detaching the shared buffer of BytesIO objects. + The caller should ensure that the 'size' argument is non-negative and + not lesser than self->string_size. Returns 0 on success, -1 otherwise. */ +static int +unshare_buffer(bytesio *self, size_t size) +{ + PyObject *new_buf, *old_buf; + assert(SHARED_BUF(self)); + assert(self->exports == 0); + assert(size >= (size_t)self->string_size); + new_buf = PyBytes_FromStringAndSize(NULL, size); + if (new_buf == NULL) + return -1; + memcpy(PyBytes_AS_STRING(new_buf), PyBytes_AS_STRING(self->buf), + self->string_size); + old_buf = self->buf; + self->buf = new_buf; + Py_DECREF(old_buf); + return 0; +} + /* Internal routine for changing the size of the buffer of BytesIO objects. The caller should ensure that the 'size' argument is non-negative. Returns 0 on success, -1 otherwise. */ @@ -75,8 +100,7 @@ resize_buffer(bytesio *self, size_t size) { /* Here, unsigned types are used to avoid dealing with signed integer overflow, which is undefined in C. */ - size_t alloc = self->buf_size; - char *new_buf = NULL; + size_t alloc = PyBytes_GET_SIZE(self->buf); assert(self->buf != NULL); @@ -104,13 +128,15 @@ resize_buffer(bytesio *self, size_t size) if (alloc > ((size_t)-1) / sizeof(char)) goto overflow; - new_buf = (char *)PyMem_Realloc(self->buf, alloc * sizeof(char)); - if (new_buf == NULL) { - PyErr_NoMemory(); - return -1; + + if (SHARED_BUF(self)) { + if (unshare_buffer(self, alloc) < 0) + return -1; + } + else { + if (_PyBytes_Resize(&self->buf, alloc) < 0) + return -1; } - self->buf_size = alloc; - self->buf = new_buf; return 0; @@ -125,12 +151,18 @@ resize_buffer(bytesio *self, size_t size) static Py_ssize_t write_bytes(bytesio *self, const char *bytes, Py_ssize_t len) { + size_t endpos; assert(self->buf != NULL); assert(self->pos >= 0); assert(len >= 0); - if ((size_t)self->pos + len > self->buf_size) { - if (resize_buffer(self, (size_t)self->pos + len) < 0) + endpos = (size_t)self->pos + len; + if (endpos > (size_t)PyBytes_GET_SIZE(self->buf)) { + if (resize_buffer(self, endpos) < 0) + return -1; + } + else if (SHARED_BUF(self)) { + if (unshare_buffer(self, Py_MAX(endpos, (size_t)self->string_size)) < 0) return -1; } @@ -143,18 +175,18 @@ write_bytes(bytesio *self, const char *bytes, Py_ssize_t len) | | <--to pad-->|<---to write---> | 0 buf position */ - memset(self->buf + self->string_size, '\0', + memset(PyBytes_AS_STRING(self->buf) + self->string_size, '\0', (self->pos - self->string_size) * sizeof(char)); } /* Copy the data to the internal buffer, overwriting some of the existing data if self->pos < self->string_size. */ - memcpy(self->buf + self->pos, bytes, len); - self->pos += len; + memcpy(PyBytes_AS_STRING(self->buf) + self->pos, bytes, len); + self->pos = endpos; /* Set the new length of the internal string if it has changed. */ - if (self->string_size < self->pos) { - self->string_size = self->pos; + if ((size_t)self->string_size < endpos) { + self->string_size = endpos; } return len; @@ -231,7 +263,22 @@ static PyObject * bytesio_getvalue(bytesio *self) { CHECK_CLOSED(self); - return PyBytes_FromStringAndSize(self->buf, self->string_size); + if (self->string_size <= 1 || self->exports > 0) + return PyBytes_FromStringAndSize(PyBytes_AS_STRING(self->buf), + self->string_size); + + if (self->string_size != PyBytes_GET_SIZE(self->buf)) { + if (SHARED_BUF(self)) { + if (unshare_buffer(self, self->string_size) < 0) + return NULL; + } + else { + if (_PyBytes_Resize(&self->buf, self->string_size) < 0) + return NULL; + } + } + Py_INCREF(self->buf); + return self->buf; } PyDoc_STRVAR(isatty_doc, @@ -257,6 +304,26 @@ bytesio_tell(bytesio *self) return PyLong_FromSsize_t(self->pos); } +static PyObject * +read_bytes(bytesio *self, Py_ssize_t size) +{ + char *output; + + assert(self->buf != NULL); + assert(size <= self->string_size); + if (size > 1 && + self->pos == 0 && size == PyBytes_GET_SIZE(self->buf) && + self->exports == 0) { + self->pos += size; + Py_INCREF(self->buf); + return self->buf; + } + + output = PyBytes_AS_STRING(self->buf) + self->pos; + self->pos += size; + return PyBytes_FromStringAndSize(output, size); +} + PyDoc_STRVAR(read_doc, "read([size]) -> read at most size bytes, returned as a string.\n" "\n" @@ -267,7 +334,6 @@ static PyObject * bytesio_read(bytesio *self, PyObject *args) { Py_ssize_t size, n; - char *output; PyObject *arg = Py_None; CHECK_CLOSED(self); @@ -298,11 +364,7 @@ bytesio_read(bytesio *self, PyObject *args) size = 0; } - assert(self->buf != NULL); - output = self->buf + self->pos; - self->pos += size; - - return PyBytes_FromStringAndSize(output, size); + return read_bytes(self, size); } @@ -336,7 +398,6 @@ static PyObject * bytesio_readline(bytesio *self, PyObject *args) { Py_ssize_t size, n; - char *output; PyObject *arg = Py_None; CHECK_CLOSED(self); @@ -359,15 +420,9 @@ bytesio_readline(bytesio *self, PyObject *args) return NULL; } - n = get_line(self, &output); + n = scan_eol(self, size); - if (size >= 0 && size < n) { - size = n - size; - n -= size; - self->pos -= size; - } - - return PyBytes_FromStringAndSize(output, n); + return read_bytes(self, n); } PyDoc_STRVAR(readlines_doc, @@ -410,7 +465,9 @@ bytesio_readlines(bytesio *self, PyObject *args) if (!result) return NULL; - while ((n = get_line(self, &output)) != 0) { + output = PyBytes_AS_STRING(self->buf) + self->pos; + while ((n = scan_eol(self, -1)) != 0) { + self->pos += n; line = PyBytes_FromStringAndSize(output, n); if (!line) goto on_error; @@ -422,6 +479,7 @@ bytesio_readlines(bytesio *self, PyObject *args) size += n; if (maxsize > 0 && size >= maxsize) break; + output += n; } return result; @@ -437,17 +495,18 @@ PyDoc_STRVAR(readinto_doc, "is set not to block as has no data to read."); static PyObject * -bytesio_readinto(bytesio *self, PyObject *buffer) +bytesio_readinto(bytesio *self, PyObject *arg) { - void *raw_buffer; + Py_buffer buffer; Py_ssize_t len, n; CHECK_CLOSED(self); - if (PyObject_AsWriteBuffer(buffer, &raw_buffer, &len) == -1) + if (!PyArg_Parse(arg, "w*", &buffer)) return NULL; /* adjust invalid sizes */ + len = buffer.len; n = self->string_size - self->pos; if (len > n) { len = n; @@ -455,10 +514,11 @@ bytesio_readinto(bytesio *self, PyObject *buffer) len = 0; } - memcpy(raw_buffer, self->buf + self->pos, len); + memcpy(buffer.buf, PyBytes_AS_STRING(self->buf) + self->pos, len); assert(self->pos + len < PY_SSIZE_T_MAX); assert(len >= 0); self->pos += len; + PyBuffer_Release(&buffer); return PyLong_FromSsize_t(len); } @@ -514,17 +574,16 @@ bytesio_truncate(bytesio *self, PyObject *args) static PyObject * bytesio_iternext(bytesio *self) { - char *next; Py_ssize_t n; CHECK_CLOSED(self); - n = get_line(self, &next); + n = scan_eol(self, -1); - if (!next || n == 0) + if (n == 0) return NULL; - return PyBytes_FromStringAndSize(next, n); + return read_bytes(self, n); } PyDoc_STRVAR(seek_doc, @@ -655,10 +714,8 @@ PyDoc_STRVAR(close_doc, static PyObject * bytesio_close(bytesio *self) { - if (self->buf != NULL) { - PyMem_Free(self->buf); - self->buf = NULL; - } + CHECK_EXPORTS(self); + Py_CLEAR(self->buf); Py_RETURN_NONE; } @@ -788,10 +845,7 @@ bytesio_dealloc(bytesio *self) "deallocated BytesIO object has exported buffers"); PyErr_Print(); } - if (self->buf != NULL) { - PyMem_Free(self->buf); - self->buf = NULL; - } + Py_CLEAR(self->buf); Py_CLEAR(self->dict); if (self->weakreflist != NULL) PyObject_ClearWeakRefs((PyObject *) self); @@ -811,7 +865,7 @@ bytesio_new(PyTypeObject *type, PyObject *args, PyObject *kwds) /* tp_alloc initializes all the fields to zero. So we don't have to initialize them here. */ - self->buf = (char *)PyMem_Malloc(0); + self->buf = PyBytes_FromStringAndSize(NULL, 0); if (self->buf == NULL) { Py_DECREF(self); return PyErr_NoMemory(); @@ -834,13 +888,26 @@ bytesio_init(bytesio *self, PyObject *args, PyObject *kwds) self->string_size = 0; self->pos = 0; + if (self->exports > 0) { + PyErr_SetString(PyExc_BufferError, + "Existing exports of data: object cannot be re-sized"); + return -1; + } if (initvalue && initvalue != Py_None) { - PyObject *res; - res = bytesio_write(self, initvalue); - if (res == NULL) - return -1; - Py_DECREF(res); - self->pos = 0; + if (PyBytes_CheckExact(initvalue)) { + Py_INCREF(initvalue); + Py_XDECREF(self->buf); + self->buf = initvalue; + self->string_size = PyBytes_GET_SIZE(initvalue); + } + else { + PyObject *res; + res = bytesio_write(self, initvalue); + if (res == NULL) + return -1; + Py_DECREF(res); + self->pos = 0; + } } return 0; @@ -852,8 +919,8 @@ bytesio_sizeof(bytesio *self, void *unused) Py_ssize_t res; res = sizeof(bytesio); - if (self->buf) - res += self->buf_size; + if (self->buf && !SHARED_BUF(self)) + res += _PySys_GetSizeOf(self->buf); return PyLong_FromSsize_t(res); } @@ -961,18 +1028,24 @@ PyTypeObject PyBytesIO_Type = { static int bytesiobuf_getbuffer(bytesiobuf *obj, Py_buffer *view, int flags) { - int ret; bytesio *b = (bytesio *) obj->source; + if (view == NULL) { - b->exports++; - return 0; + PyErr_SetString(PyExc_BufferError, + "bytesiobuf_getbuffer: view==NULL argument is obsolete"); + return -1; } - ret = PyBuffer_FillInfo(view, (PyObject*)obj, b->buf, b->string_size, - 0, flags); - if (ret >= 0) { - b->exports++; + if (SHARED_BUF(b)) { + if (unshare_buffer(b, b->string_size) < 0) + return -1; } - return ret; + + /* cannot fail if view != NULL and readonly == 0 */ + (void)PyBuffer_FillInfo(view, (PyObject*)obj, + PyBytes_AS_STRING(b->buf), b->string_size, + 0, flags); + b->exports++; + return 0; } static void diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c index 0e1e709efd94..ff88e40973d7 100644 --- a/Modules/_io/fileio.c +++ b/Modules/_io/fileio.c @@ -53,6 +53,7 @@ typedef struct { signed int seekable : 2; /* -1 means unknown */ unsigned int closefd : 1; char finalizing; + unsigned int blksize; PyObject *weakreflist; PyObject *dict; } fileio; @@ -126,11 +127,18 @@ internal_close(fileio *self) static PyObject * fileio_close(fileio *self) { + PyObject *res; + PyObject *exc, *val, *tb; + int rc; _Py_IDENTIFIER(close); + res = _PyObject_CallMethodId((PyObject*)&PyRawIOBase_Type, + &PyId_close, "O", self); if (!self->closefd) { self->fd = -1; - Py_RETURN_NONE; + return res; } + if (res == NULL) + PyErr_Fetch(&exc, &val, &tb); if (self->finalizing) { PyObject *r = fileio_dealloc_warn(self, (PyObject *) self); if (r) @@ -138,12 +146,12 @@ fileio_close(fileio *self) else PyErr_Clear(); } - errno = internal_close(self); - if (errno < 0) - return NULL; - - return _PyObject_CallMethodId((PyObject*)&PyRawIOBase_Type, - &PyId_close, "O", self); + rc = internal_close(self); + if (res == NULL) + _PyErr_ChainExceptions(exc, val, tb); + if (rc < 0) + Py_CLEAR(res); + return res; } static PyObject * @@ -161,6 +169,7 @@ fileio_new(PyTypeObject *type, PyObject *args, PyObject *kwds) self->writable = 0; self->appending = 0; self->seekable = -1; + self->blksize = 0; self->closefd = 1; self->weakreflist = NULL; } @@ -168,32 +177,12 @@ fileio_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return (PyObject *) self; } -/* On Unix, open will succeed for directories. - In Python, there should be no file objects referring to - directories, so we need a check. */ - -static int -dircheck(fileio* self, PyObject *nameobj) -{ -#if defined(HAVE_FSTAT) && defined(S_ISDIR) && defined(EISDIR) - struct stat buf; - if (self->fd < 0) - return 0; - if (fstat(self->fd, &buf) == 0 && S_ISDIR(buf.st_mode)) { - errno = EISDIR; - PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, nameobj); - return -1; - } -#endif - return 0; -} - static int check_fd(int fd) { -#if defined(HAVE_FSTAT) - struct stat buf; - if (!_PyVerify_fd(fd) || (fstat(fd, &buf) < 0 && errno == EBADF)) { +#if defined(HAVE_FSTAT) || defined(MS_WINDOWS) + struct _Py_stat_struct buf; + if (!_PyVerify_fd(fd) || (_Py_fstat(fd, &buf) < 0 && errno == EBADF)) { PyObject *exc; char *msg = strerror(EBADF); exc = PyObject_CallFunction(PyExc_OSError, "(is)", @@ -233,6 +222,10 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) #elif !defined(MS_WINDOWS) int *atomic_flag_works = NULL; #endif +#if defined(HAVE_FSTAT) || defined(MS_WINDOWS) + struct _Py_stat_struct fdfstat; +#endif + int async_err = 0; assert(PyFileIO_Check(oself)); if (self->fd >= 0) { @@ -271,7 +264,7 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) int rv = _PyUnicode_HasNULChars(nameobj); if (rv) { if (rv != -1) - PyErr_SetString(PyExc_TypeError, "embedded NUL character"); + PyErr_SetString(PyExc_ValueError, "embedded null character"); return -1; } widename = PyUnicode_AsUnicode(nameobj); @@ -375,15 +368,18 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) errno = 0; if (opener == Py_None) { - Py_BEGIN_ALLOW_THREADS + do { + Py_BEGIN_ALLOW_THREADS #ifdef MS_WINDOWS - if (widename != NULL) - self->fd = _wopen(widename, flags, 0666); - else + if (widename != NULL) + self->fd = _wopen(widename, flags, 0666); + else #endif - self->fd = open(name, flags, 0666); + self->fd = open(name, flags, 0666); - Py_END_ALLOW_THREADS + Py_END_ALLOW_THREADS + } while (self->fd < 0 && errno == EINTR && + !(async_err = PyErr_CheckSignals())); } else { PyObject *fdobj; @@ -412,7 +408,8 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) fd_is_own = 1; if (self->fd < 0) { - PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, nameobj); + if (!async_err) + PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, nameobj); goto error; } @@ -421,8 +418,28 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) goto error; #endif } - if (dircheck(self, nameobj) < 0) + + self->blksize = DEFAULT_BUFFER_SIZE; +#if defined(HAVE_FSTAT) || defined(MS_WINDOWS) + if (_Py_fstat(self->fd, &fdfstat) < 0) { + PyErr_SetFromErrno(PyExc_OSError); + goto error; + } +#if defined(S_ISDIR) && defined(EISDIR) + /* On Unix, open will succeed for directories. + In Python, there should be no file objects referring to + directories, so we need a check. */ + if (S_ISDIR(fdfstat.st_mode)) { + errno = EISDIR; + PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, nameobj); goto error; + } +#endif /* defined(S_ISDIR) */ +#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE + if (fdfstat.st_blksize > 1) + self->blksize = fdfstat.st_blksize; +#endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */ +#endif /* HAVE_FSTAT || MS_WINDOWS */ #if defined(MS_WINDOWS) || defined(__CYGWIN__) /* don't translate newlines (\r\n <=> \n) */ @@ -493,8 +510,10 @@ err_closed(void) static PyObject * err_mode(char *action) { - PyErr_Format(IO_STATE->unsupported_operation, - "File not open for %s", action); + _PyIO_State *state = IO_STATE(); + if (state != NULL) + PyErr_Format(state->unsupported_operation, + "File not open for %s", action); return NULL; } @@ -545,7 +564,7 @@ fileio_readinto(fileio *self, PyObject *args) { Py_buffer pbuf; Py_ssize_t n, len; - int err; + int err, async_err = 0; if (self->fd < 0) return err_closed(); @@ -557,16 +576,19 @@ fileio_readinto(fileio *self, PyObject *args) if (_PyVerify_fd(self->fd)) { len = pbuf.len; - Py_BEGIN_ALLOW_THREADS - errno = 0; + do { + Py_BEGIN_ALLOW_THREADS + errno = 0; #ifdef MS_WINDOWS - if (len > INT_MAX) - len = INT_MAX; - n = read(self->fd, pbuf.buf, (int)len); + if (len > INT_MAX) + len = INT_MAX; + n = read(self->fd, pbuf.buf, (int)len); #else - n = read(self->fd, pbuf.buf, len); + n = read(self->fd, pbuf.buf, len); #endif - Py_END_ALLOW_THREADS + Py_END_ALLOW_THREADS + } while (n < 0 && errno == EINTR && + !(async_err = PyErr_CheckSignals())); } else n = -1; err = errno; @@ -575,24 +597,15 @@ fileio_readinto(fileio *self, PyObject *args) if (err == EAGAIN) Py_RETURN_NONE; errno = err; - PyErr_SetFromErrno(PyExc_IOError); + if (!async_err) + PyErr_SetFromErrno(PyExc_IOError); return NULL; } return PyLong_FromSsize_t(n); } -#ifndef HAVE_FSTAT - -static PyObject * -fileio_readall(fileio *self) -{ - _Py_IDENTIFIER(readall); - return _PyObject_CallMethodId((PyObject*)&PyRawIOBase_Type, - &PyId_readall, "O", self); -} - -#else +#if defined(HAVE_FSTAT) || defined(MS_WINDOWS) static size_t new_buffersize(fileio *self, size_t currentsize) @@ -616,12 +629,13 @@ new_buffersize(fileio *self, size_t currentsize) static PyObject * fileio_readall(fileio *self) { - struct stat st; + struct _Py_stat_struct st; Py_off_t pos, end; PyObject *result; Py_ssize_t bytes_read = 0; Py_ssize_t n; size_t bufsize; + int async_err = 0; if (self->fd < 0) return err_closed(); @@ -633,7 +647,7 @@ fileio_readall(fileio *self) #else pos = lseek(self->fd, 0L, SEEK_CUR); #endif - if (fstat(self->fd, &st) == 0) + if (_Py_fstat(self->fd, &st) == 0) end = st.st_size; else end = (Py_off_t)-1; @@ -668,35 +682,32 @@ fileio_readall(fileio *self) return NULL; } } - Py_BEGIN_ALLOW_THREADS - errno = 0; - n = bufsize - bytes_read; + do { + Py_BEGIN_ALLOW_THREADS + errno = 0; + n = bufsize - bytes_read; #ifdef MS_WINDOWS - if (n > INT_MAX) - n = INT_MAX; - n = read(self->fd, PyBytes_AS_STRING(result) + bytes_read, (int)n); + if (n > INT_MAX) + n = INT_MAX; + n = read(self->fd, PyBytes_AS_STRING(result) + bytes_read, (int)n); #else - n = read(self->fd, PyBytes_AS_STRING(result) + bytes_read, n); + n = read(self->fd, PyBytes_AS_STRING(result) + bytes_read, n); #endif - Py_END_ALLOW_THREADS + Py_END_ALLOW_THREADS + } while (n < 0 && errno == EINTR && + !(async_err = PyErr_CheckSignals())); if (n == 0) break; if (n < 0) { - if (errno == EINTR) { - if (PyErr_CheckSignals()) { - Py_DECREF(result); - return NULL; - } - continue; - } - if (bytes_read > 0) - break; if (errno == EAGAIN) { + if (bytes_read > 0) + break; Py_DECREF(result); Py_RETURN_NONE; } Py_DECREF(result); - PyErr_SetFromErrno(PyExc_IOError); + if (!async_err) + PyErr_SetFromErrno(PyExc_IOError); return NULL; } bytes_read += n; @@ -710,7 +721,17 @@ fileio_readall(fileio *self) return result; } -#endif /* HAVE_FSTAT */ +#else + +static PyObject * +fileio_readall(fileio *self) +{ + _Py_IDENTIFIER(readall); + return _PyObject_CallMethodId((PyObject*)&PyRawIOBase_Type, + &PyId_readall, "O", self); +} + +#endif /* HAVE_FSTAT || MS_WINDOWS */ static PyObject * fileio_read(fileio *self, PyObject *args) @@ -718,6 +739,7 @@ fileio_read(fileio *self, PyObject *args) char *ptr; Py_ssize_t n; Py_ssize_t size = -1; + int async_err = 0; PyObject *bytes; if (self->fd < 0) @@ -742,14 +764,17 @@ fileio_read(fileio *self, PyObject *args) ptr = PyBytes_AS_STRING(bytes); if (_PyVerify_fd(self->fd)) { - Py_BEGIN_ALLOW_THREADS - errno = 0; + do { + Py_BEGIN_ALLOW_THREADS + errno = 0; #ifdef MS_WINDOWS - n = read(self->fd, ptr, (int)size); + n = read(self->fd, ptr, (int)size); #else - n = read(self->fd, ptr, size); + n = read(self->fd, ptr, size); #endif - Py_END_ALLOW_THREADS + Py_END_ALLOW_THREADS + } while (n < 0 && errno == EINTR && + !(async_err = PyErr_CheckSignals())); } else n = -1; @@ -759,7 +784,8 @@ fileio_read(fileio *self, PyObject *args) if (err == EAGAIN) Py_RETURN_NONE; errno = err; - PyErr_SetFromErrno(PyExc_IOError); + if (!async_err) + PyErr_SetFromErrno(PyExc_IOError); return NULL; } @@ -778,7 +804,7 @@ fileio_write(fileio *self, PyObject *args) { Py_buffer pbuf; Py_ssize_t n, len; - int err; + int err, async_err = 0; if (self->fd < 0) return err_closed(); @@ -789,24 +815,26 @@ fileio_write(fileio *self, PyObject *args) return NULL; if (_PyVerify_fd(self->fd)) { - Py_BEGIN_ALLOW_THREADS - errno = 0; - len = pbuf.len; + do { + Py_BEGIN_ALLOW_THREADS + errno = 0; + len = pbuf.len; #ifdef MS_WINDOWS - if (len > 32767 && isatty(self->fd)) { - /* Issue #11395: the Windows console returns an error (12: not - enough space error) on writing into stdout if stdout mode is - binary and the length is greater than 66,000 bytes (or less, - depending on heap usage). */ - len = 32767; - } - else if (len > INT_MAX) - len = INT_MAX; - n = write(self->fd, pbuf.buf, (int)len); + if (len > 32767 && isatty(self->fd)) { + /* Issue #11395: the Windows console returns an error (12: not + enough space error) on writing into stdout if stdout mode is + binary and the length is greater than 66,000 bytes (or less, + depending on heap usage). */ + len = 32767; + } else if (len > INT_MAX) + len = INT_MAX; + n = write(self->fd, pbuf.buf, (int)len); #else - n = write(self->fd, pbuf.buf, len); + n = write(self->fd, pbuf.buf, len); #endif - Py_END_ALLOW_THREADS + Py_END_ALLOW_THREADS + } while (n < 0 && errno == EINTR && + !(async_err = PyErr_CheckSignals())); } else n = -1; err = errno; @@ -817,7 +845,8 @@ fileio_write(fileio *self, PyObject *args) if (err == EAGAIN) Py_RETURN_NONE; errno = err; - PyErr_SetFromErrno(PyExc_IOError); + if (!async_err) + PyErr_SetFromErrno(PyExc_IOError); return NULL; } @@ -1049,12 +1078,14 @@ fileio_repr(fileio *self) PyErr_Clear(); else return NULL; - res = PyUnicode_FromFormat("<_io.FileIO fd=%d mode='%s'>", - self->fd, mode_string(self)); + res = PyUnicode_FromFormat( + "<_io.FileIO fd=%d mode='%s' closefd=%s>", + self->fd, mode_string(self), self->closefd ? "True" : "False"); } else { - res = PyUnicode_FromFormat("<_io.FileIO name=%R mode='%s'>", - nameobj, mode_string(self)); + res = PyUnicode_FromFormat( + "<_io.FileIO name=%R mode='%s' closefd=%s>", + nameobj, mode_string(self), self->closefd ? "True" : "False"); Py_DECREF(nameobj); } return res; @@ -1122,7 +1153,8 @@ PyDoc_STRVAR(fileno_doc, "This is needed for lower-level file interfaces, such the fcntl module."); PyDoc_STRVAR(seek_doc, -"seek(offset: int[, whence: int]) -> None. Move to new file position.\n" +"seek(offset: int[, whence: int]) -> int. Move to new file position and\n" +"return the file position.\n" "\n" "Argument offset is a byte count. Optional argument whence defaults to\n" "0 (offset from start of file, offset should be >= 0); other values are 1\n" @@ -1134,9 +1166,10 @@ PyDoc_STRVAR(seek_doc, #ifdef HAVE_FTRUNCATE PyDoc_STRVAR(truncate_doc, -"truncate([size: int]) -> None. Truncate the file to at most size bytes.\n" +"truncate([size: int]) -> int. Truncate the file to at most size bytes\n" +"and return the truncated size.\n" "\n" -"Size defaults to the current file position, as returned by tell()." +"Size defaults to the current file position, as returned by tell().\n" "The current file position is changed to the value of size."); #endif @@ -1214,6 +1247,7 @@ static PyGetSetDef fileio_getsetlist[] = { }; static PyMemberDef fileio_members[] = { + {"_blksize", T_UINT, offsetof(fileio, blksize), 0}, {"_finalizing", T_BOOL, offsetof(fileio, finalizing), 0}, {NULL} }; diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c index 1b7cb0ff7027..ef06b43ca6e8 100644 --- a/Modules/_io/iobase.c +++ b/Modules/_io/iobase.c @@ -42,8 +42,8 @@ PyDoc_STRVAR(iobase_doc, "bytes. bytearrays are accepted too, and in some cases (such as\n" "readinto) needed. Text I/O classes work with str data.\n" "\n" - "Note that calling any method (even inquiries) on a closed stream is\n" - "undefined. Implementations may raise IOError in this case.\n" + "Note that calling any method (except additional calls to close(),\n" + "which are ignored) on a closed stream should raise a ValueError.\n" "\n" "IOBase (and its subclasses) support the iterator protocol, meaning\n" "that an IOBase object can be iterated over yielding the lines in a\n" @@ -69,7 +69,9 @@ _Py_IDENTIFIER(read); static PyObject * iobase_unsupported(const char *message) { - PyErr_SetString(IO_STATE->unsupported_operation, message); + _PyIO_State *state = IO_STATE(); + if (state != NULL) + PyErr_SetString(state->unsupported_operation, message); return NULL; } diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c index fb89a17927cd..9fb4ef92c38e 100644 --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -45,7 +45,9 @@ PyDoc_STRVAR(textiobase_doc, static PyObject * _unsupported(const char *message) { - PyErr_SetString(IO_STATE->unsupported_operation, message); + _PyIO_State *state = IO_STATE(); + if (state != NULL) + PyErr_SetString(state->unsupported_operation, message); return NULL; } @@ -222,8 +224,8 @@ typedef struct { PyObject_HEAD PyObject *decoder; PyObject *errors; - signed int pendingcr: 1; - signed int translate: 1; + unsigned int pendingcr: 1; + unsigned int translate: 1; unsigned int seennl: 3; } nldecoder_object; @@ -544,7 +546,7 @@ incrementalnewlinedecoder_setstate(nldecoder_object *self, PyObject *state) if (!PyArg_Parse(state, "(OK)", &buffer, &flag)) return NULL; - self->pendingcr = (int) flag & 1; + self->pendingcr = (int) (flag & 1); flag >>= 1; if (self->decoder != Py_None) @@ -847,12 +849,12 @@ textiowrapper_init(textio *self, PyObject *args, PyObject *kwds) char *kwlist[] = {"buffer", "encoding", "errors", "newline", "line_buffering", "write_through", NULL}; - PyObject *buffer, *raw; + PyObject *buffer, *raw, *codec_info = NULL; char *encoding = NULL; char *errors = NULL; char *newline = NULL; int line_buffering = 0, write_through = 0; - _PyIO_State *state = IO_STATE; + _PyIO_State *state = NULL; PyObject *res; int r; @@ -891,6 +893,9 @@ textiowrapper_init(textio *self, PyObject *args, PyObject *kwds) if (encoding == NULL) { /* Try os.device_encoding(fileno) */ PyObject *fileno; + state = IO_STATE(); + if (state == NULL) + goto error; fileno = _PyObject_CallMethodId(buffer, &PyId_fileno, NULL); /* Ignore only AttributeError and UnsupportedOperation */ if (fileno == NULL) { @@ -956,6 +961,17 @@ textiowrapper_init(textio *self, PyObject *args, PyObject *kwds) "could not determine default encoding"); } + /* Check we have been asked for a real text encoding */ + codec_info = _PyCodec_LookupTextEncoding(encoding, "codecs.open()"); + if (codec_info == NULL) { + Py_CLEAR(self->encoding); + goto error; + } + + /* XXX: Failures beyond this point have the potential to leak elements + * of the partially constructed object (like self->encoding) + */ + if (errors == NULL) errors = "strict"; self->errors = PyBytes_FromString(errors); @@ -970,7 +986,7 @@ textiowrapper_init(textio *self, PyObject *args, PyObject *kwds) if (newline) { self->readnl = PyUnicode_FromString(newline); if (self->readnl == NULL) - return -1; + goto error; } self->writetranslate = (newline == NULL || newline[0] != '\0'); if (!self->readuniversal && self->readnl) { @@ -994,8 +1010,8 @@ textiowrapper_init(textio *self, PyObject *args, PyObject *kwds) if (r == -1) goto error; if (r == 1) { - self->decoder = PyCodec_IncrementalDecoder( - encoding, errors); + self->decoder = _PyCodecInfo_GetIncrementalDecoder(codec_info, + errors); if (self->decoder == NULL) goto error; @@ -1019,17 +1035,12 @@ textiowrapper_init(textio *self, PyObject *args, PyObject *kwds) if (r == -1) goto error; if (r == 1) { - PyObject *ci; - self->encoder = PyCodec_IncrementalEncoder( - encoding, errors); + self->encoder = _PyCodecInfo_GetIncrementalEncoder(codec_info, + errors); if (self->encoder == NULL) goto error; /* Get the normalized named of the codec */ - ci = _PyCodec_Lookup(encoding); - if (ci == NULL) - goto error; - res = _PyObject_GetAttrId(ci, &PyId_name); - Py_DECREF(ci); + res = _PyObject_GetAttrId(codec_info, &PyId_name); if (res == NULL) { if (PyErr_ExceptionMatches(PyExc_AttributeError)) PyErr_Clear(); @@ -1049,6 +1060,9 @@ textiowrapper_init(textio *self, PyObject *args, PyObject *kwds) Py_XDECREF(res); } + /* Finished sorting out the codec details */ + Py_CLEAR(codec_info); + self->buffer = buffer; Py_INCREF(buffer); @@ -1111,6 +1125,7 @@ textiowrapper_init(textio *self, PyObject *args, PyObject *kwds) return 0; error: + Py_XDECREF(codec_info); return -1; } @@ -1204,25 +1219,27 @@ textiowrapper_closed_get(textio *self, void *context); #define CHECK_INITIALIZED(self) \ if (self->ok <= 0) { \ - if (self->detached) { \ - PyErr_SetString(PyExc_ValueError, \ - "underlying buffer has been detached"); \ - } else { \ - PyErr_SetString(PyExc_ValueError, \ - "I/O operation on uninitialized object"); \ - } \ + PyErr_SetString(PyExc_ValueError, \ + "I/O operation on uninitialized object"); \ + return NULL; \ + } + +#define CHECK_ATTACHED(self) \ + CHECK_INITIALIZED(self); \ + if (self->detached) { \ + PyErr_SetString(PyExc_ValueError, \ + "underlying buffer has been detached"); \ return NULL; \ } -#define CHECK_INITIALIZED_INT(self) \ +#define CHECK_ATTACHED_INT(self) \ if (self->ok <= 0) { \ - if (self->detached) { \ - PyErr_SetString(PyExc_ValueError, \ - "underlying buffer has been detached"); \ - } else { \ - PyErr_SetString(PyExc_ValueError, \ - "I/O operation on uninitialized object"); \ - } \ + PyErr_SetString(PyExc_ValueError, \ + "I/O operation on uninitialized object"); \ + return -1; \ + } else if (self->detached) { \ + PyErr_SetString(PyExc_ValueError, \ + "underlying buffer has been detached"); \ return -1; \ } @@ -1231,7 +1248,7 @@ static PyObject * textiowrapper_detach(textio *self) { PyObject *buffer, *res; - CHECK_INITIALIZED(self); + CHECK_ATTACHED(self); res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL); if (res == NULL) return NULL; @@ -1239,7 +1256,6 @@ textiowrapper_detach(textio *self) buffer = self->buffer; self->buffer = NULL; self->detached = 1; - self->ok = 0; return buffer; } @@ -1282,9 +1298,9 @@ textiowrapper_write(textio *self, PyObject *args) PyObject *b; Py_ssize_t textlen; int haslf = 0; - int needflush = 0; + int needflush = 0, text_needflush = 0; - CHECK_INITIALIZED(self); + CHECK_ATTACHED(self); if (!PyArg_ParseTuple(args, "U:write", &text)) { return NULL; @@ -1316,8 +1332,8 @@ textiowrapper_write(textio *self, PyObject *args) } if (self->write_through) - needflush = 1; - else if (self->line_buffering && + text_needflush = 1; + if (self->line_buffering && (haslf || PyUnicode_FindChar(text, '\r', 0, PyUnicode_GET_LENGTH(text), 1) != -1)) needflush = 1; @@ -1348,7 +1364,8 @@ textiowrapper_write(textio *self, PyObject *args) } self->pending_bytes_count += PyBytes_GET_SIZE(b); Py_DECREF(b); - if (self->pending_bytes_count > self->chunk_size || needflush) { + if (self->pending_bytes_count > self->chunk_size || needflush || + text_needflush) { if (_textiowrapper_writeflush(self) < 0) return NULL; } @@ -1424,6 +1441,7 @@ textiowrapper_read_chunk(textio *self, Py_ssize_t size_hint) PyObject *dec_buffer = NULL; PyObject *dec_flags = NULL; PyObject *input_chunk = NULL; + Py_buffer input_chunk_buf; PyObject *decoded_chars, *chunk_size; Py_ssize_t nbytes, nchars; int eof; @@ -1455,6 +1473,15 @@ textiowrapper_read_chunk(textio *self, Py_ssize_t size_hint) Py_DECREF(state); return -1; } + + if (!PyBytes_Check(dec_buffer)) { + PyErr_Format(PyExc_TypeError, + "decoder getstate() should have returned a bytes " + "object, not '%.200s'", + Py_TYPE(dec_buffer)->tp_name); + Py_DECREF(state); + return -1; + } Py_INCREF(dec_buffer); Py_INCREF(dec_flags); Py_DECREF(state); @@ -1467,23 +1494,24 @@ textiowrapper_read_chunk(textio *self, Py_ssize_t size_hint) chunk_size = PyLong_FromSsize_t(Py_MAX(self->chunk_size, size_hint)); if (chunk_size == NULL) goto fail; + input_chunk = PyObject_CallMethodObjArgs(self->buffer, (self->has_read1 ? _PyIO_str_read1: _PyIO_str_read), chunk_size, NULL); Py_DECREF(chunk_size); if (input_chunk == NULL) goto fail; - if (!PyBytes_Check(input_chunk)) { + + if (PyObject_GetBuffer(input_chunk, &input_chunk_buf, 0) != 0) { PyErr_Format(PyExc_TypeError, - "underlying %s() should have returned a bytes object, " + "underlying %s() should have returned a bytes-like object, " "not '%.200s'", (self->has_read1 ? "read1": "read"), Py_TYPE(input_chunk)->tp_name); goto fail; } - nbytes = PyBytes_Size(input_chunk); + nbytes = input_chunk_buf.len; eof = (nbytes == 0); - if (Py_TYPE(self->decoder) == &PyIncrementalNewlineDecoder_Type) { decoded_chars = _PyIncrementalNewlineDecoder_decode( self->decoder, input_chunk, eof); @@ -1492,6 +1520,7 @@ textiowrapper_read_chunk(textio *self, Py_ssize_t size_hint) decoded_chars = PyObject_CallMethodObjArgs(self->decoder, _PyIO_str_decode, input_chunk, eof ? Py_True : Py_False, NULL); } + PyBuffer_Release(&input_chunk_buf); if (check_decoded(decoded_chars) < 0) goto fail; @@ -1508,18 +1537,12 @@ textiowrapper_read_chunk(textio *self, Py_ssize_t size_hint) /* At the snapshot point, len(dec_buffer) bytes before the read, the * next input to be decoded is dec_buffer + input_chunk. */ - PyObject *next_input = PyNumber_Add(dec_buffer, input_chunk); - if (next_input == NULL) - goto fail; - if (!PyBytes_Check(next_input)) { - PyErr_Format(PyExc_TypeError, - "decoder getstate() should have returned a bytes " - "object, not '%.200s'", - Py_TYPE(next_input)->tp_name); - Py_DECREF(next_input); + PyObject *next_input = dec_buffer; + PyBytes_Concat(&next_input, input_chunk); + if (next_input == NULL) { + dec_buffer = NULL; /* Reference lost to PyBytes_Concat */ goto fail; } - Py_DECREF(dec_buffer); Py_CLEAR(self->snapshot); self->snapshot = Py_BuildValue("NN", dec_flags, next_input); } @@ -1540,7 +1563,7 @@ textiowrapper_read(textio *self, PyObject *args) Py_ssize_t n = -1; PyObject *result = NULL, *chunks = NULL; - CHECK_INITIALIZED(self); + CHECK_ATTACHED(self); if (!PyArg_ParseTuple(args, "|O&:read", &_PyIO_ConvertSsize_t, &n)) return NULL; @@ -1708,7 +1731,7 @@ _PyIO_find_line_ending( else { /* Non-universal mode. */ Py_ssize_t readnl_len = PyUnicode_GET_LENGTH(readnl); - char *nl = PyUnicode_DATA(readnl); + Py_UCS1 *nl = PyUnicode_1BYTE_DATA(readnl); /* Assume that readnl is an ASCII character. */ assert(PyUnicode_KIND(readnl) == PyUnicode_1BYTE_KIND); if (readnl_len == 1) { @@ -1915,7 +1938,7 @@ textiowrapper_readline(textio *self, PyObject *args) { Py_ssize_t limit = -1; - CHECK_INITIALIZED(self); + CHECK_ATTACHED(self); if (!PyArg_ParseTuple(args, "|n:readline", &limit)) { return NULL; } @@ -2053,7 +2076,7 @@ textiowrapper_seek(textio *self, PyObject *args) PyObject *res; int cmp; - CHECK_INITIALIZED(self); + CHECK_ATTACHED(self); if (!PyArg_ParseTuple(args, "O|i:seek", &cookieObj, &whence)) return NULL; @@ -2233,7 +2256,7 @@ textiowrapper_tell(textio *self, PyObject *args) Py_ssize_t dec_buffer_len; int dec_flags; - CHECK_INITIALIZED(self); + CHECK_ATTACHED(self); CHECK_CLOSED(self); if (!self->seekable) { @@ -2436,7 +2459,7 @@ textiowrapper_truncate(textio *self, PyObject *args) PyObject *pos = Py_None; PyObject *res; - CHECK_INITIALIZED(self) + CHECK_ATTACHED(self) if (!PyArg_ParseTuple(args, "|O:truncate", &pos)) { return NULL; } @@ -2459,9 +2482,10 @@ textiowrapper_repr(textio *self) res = PyUnicode_FromString("<_io.TextIOWrapper"); if (res == NULL) return NULL; + nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name); if (nameobj == NULL) { - if (PyErr_ExceptionMatches(PyExc_AttributeError)) + if (PyErr_ExceptionMatches(PyExc_Exception)) PyErr_Clear(); else goto error; @@ -2477,7 +2501,7 @@ textiowrapper_repr(textio *self) } modeobj = _PyObject_GetAttrId((PyObject *) self, &PyId_mode); if (modeobj == NULL) { - if (PyErr_ExceptionMatches(PyExc_AttributeError)) + if (PyErr_ExceptionMatches(PyExc_Exception)) PyErr_Clear(); else goto error; @@ -2506,35 +2530,35 @@ textiowrapper_repr(textio *self) static PyObject * textiowrapper_fileno(textio *self, PyObject *args) { - CHECK_INITIALIZED(self); + CHECK_ATTACHED(self); return _PyObject_CallMethodId(self->buffer, &PyId_fileno, NULL); } static PyObject * textiowrapper_seekable(textio *self, PyObject *args) { - CHECK_INITIALIZED(self); + CHECK_ATTACHED(self); return _PyObject_CallMethodId(self->buffer, &PyId_seekable, NULL); } static PyObject * textiowrapper_readable(textio *self, PyObject *args) { - CHECK_INITIALIZED(self); + CHECK_ATTACHED(self); return _PyObject_CallMethodId(self->buffer, &PyId_readable, NULL); } static PyObject * textiowrapper_writable(textio *self, PyObject *args) { - CHECK_INITIALIZED(self); + CHECK_ATTACHED(self); return _PyObject_CallMethodId(self->buffer, &PyId_writable, NULL); } static PyObject * textiowrapper_isatty(textio *self, PyObject *args) { - CHECK_INITIALIZED(self); + CHECK_ATTACHED(self); return _PyObject_CallMethodId(self->buffer, &PyId_isatty, NULL); } @@ -2549,7 +2573,7 @@ textiowrapper_getstate(textio *self, PyObject *args) static PyObject * textiowrapper_flush(textio *self, PyObject *args) { - CHECK_INITIALIZED(self); + CHECK_ATTACHED(self); CHECK_CLOSED(self); self->telling = self->seekable; if (_textiowrapper_writeflush(self) < 0) @@ -2562,7 +2586,7 @@ textiowrapper_close(textio *self, PyObject *args) { PyObject *res; int r; - CHECK_INITIALIZED(self); + CHECK_ATTACHED(self); res = textiowrapper_closed_get(self, NULL); if (res == NULL) @@ -2592,19 +2616,8 @@ textiowrapper_close(textio *self, PyObject *args) res = _PyObject_CallMethodId(self->buffer, &PyId_close, NULL); if (exc != NULL) { - if (res != NULL) { - Py_CLEAR(res); - PyErr_Restore(exc, val, tb); - } - else { - PyObject *val2; - Py_DECREF(exc); - Py_XDECREF(tb); - PyErr_Fetch(&exc, &val2, &tb); - PyErr_NormalizeException(&exc, &val2, &tb); - PyException_SetContext(val2, val); - PyErr_Restore(exc, val2, tb); - } + _PyErr_ChainExceptions(exc, val, tb); + Py_CLEAR(res); } return res; } @@ -2615,7 +2628,7 @@ textiowrapper_iternext(textio *self) { PyObject *line; - CHECK_INITIALIZED(self); + CHECK_ATTACHED(self); self->telling = 0; if (Py_TYPE(self) == &PyTextIOWrapper_Type) { @@ -2651,14 +2664,14 @@ textiowrapper_iternext(textio *self) static PyObject * textiowrapper_name_get(textio *self, void *context) { - CHECK_INITIALIZED(self); + CHECK_ATTACHED(self); return _PyObject_GetAttrId(self->buffer, &PyId_name); } static PyObject * textiowrapper_closed_get(textio *self, void *context) { - CHECK_INITIALIZED(self); + CHECK_ATTACHED(self); return PyObject_GetAttr(self->buffer, _PyIO_str_closed); } @@ -2666,7 +2679,7 @@ static PyObject * textiowrapper_newlines_get(textio *self, void *context) { PyObject *res; - CHECK_INITIALIZED(self); + CHECK_ATTACHED(self); if (self->decoder == NULL) Py_RETURN_NONE; res = PyObject_GetAttr(self->decoder, _PyIO_str_newlines); @@ -2692,7 +2705,7 @@ textiowrapper_errors_get(textio *self, void *context) static PyObject * textiowrapper_chunk_size_get(textio *self, void *context) { - CHECK_INITIALIZED(self); + CHECK_ATTACHED(self); return PyLong_FromSsize_t(self->chunk_size); } @@ -2700,7 +2713,7 @@ static int textiowrapper_chunk_size_set(textio *self, PyObject *arg, void *context) { Py_ssize_t n; - CHECK_INITIALIZED_INT(self); + CHECK_ATTACHED_INT(self); n = PyNumber_AsSsize_t(arg, PyExc_ValueError); if (n == -1 && PyErr_Occurred()) return -1; diff --git a/Modules/_json.c b/Modules/_json.c index 125101fa7c38..076859f99cd9 100644 --- a/Modules/_json.c +++ b/Modules/_json.c @@ -47,7 +47,7 @@ typedef struct _PyEncoderObject { PyObject *item_separator; PyObject *sort_keys; PyObject *skipkeys; - int fast_encode; + PyCFunction fast_encode; int allow_nan; } PyEncoderObject; @@ -182,17 +182,24 @@ ascii_escape_unicode(PyObject *pystr) /* Compute the output size */ for (i = 0, output_size = 2; i < input_chars; i++) { Py_UCS4 c = PyUnicode_READ(kind, input, i); - if (S_CHAR(c)) - output_size++; + Py_ssize_t d; + if (S_CHAR(c)) { + d = 1; + } else { switch(c) { case '\\': case '"': case '\b': case '\f': case '\n': case '\r': case '\t': - output_size += 2; break; + d = 2; break; default: - output_size += c >= 0x10000 ? 12 : 6; + d = c >= 0x10000 ? 12 : 6; } } + if (output_size > PY_SSIZE_T_MAX - d) { + PyErr_SetString(PyExc_OverflowError, "string is too long to escape"); + return NULL; + } + output_size += d; } rval = PyUnicode_New(output_size, 127); @@ -218,26 +225,116 @@ ascii_escape_unicode(PyObject *pystr) return rval; } +static PyObject * +escape_unicode(PyObject *pystr) +{ + /* Take a PyUnicode pystr and return a new escaped PyUnicode */ + Py_ssize_t i; + Py_ssize_t input_chars; + Py_ssize_t output_size; + Py_ssize_t chars; + PyObject *rval; + void *input; + int kind; + Py_UCS4 maxchar; + + if (PyUnicode_READY(pystr) == -1) + return NULL; + + maxchar = PyUnicode_MAX_CHAR_VALUE(pystr); + input_chars = PyUnicode_GET_LENGTH(pystr); + input = PyUnicode_DATA(pystr); + kind = PyUnicode_KIND(pystr); + + /* Compute the output size */ + for (i = 0, output_size = 2; i < input_chars; i++) { + Py_UCS4 c = PyUnicode_READ(kind, input, i); + switch (c) { + case '\\': case '"': case '\b': case '\f': + case '\n': case '\r': case '\t': + output_size += 2; + break; + default: + if (c <= 0x1f) + output_size += 6; + else + output_size++; + } + } + + rval = PyUnicode_New(output_size, maxchar); + if (rval == NULL) + return NULL; + + kind = PyUnicode_KIND(rval); + +#define ENCODE_OUTPUT do { \ + chars = 0; \ + output[chars++] = '"'; \ + for (i = 0; i < input_chars; i++) { \ + Py_UCS4 c = PyUnicode_READ(kind, input, i); \ + switch (c) { \ + case '\\': output[chars++] = '\\'; output[chars++] = c; break; \ + case '"': output[chars++] = '\\'; output[chars++] = c; break; \ + case '\b': output[chars++] = '\\'; output[chars++] = 'b'; break; \ + case '\f': output[chars++] = '\\'; output[chars++] = 'f'; break; \ + case '\n': output[chars++] = '\\'; output[chars++] = 'n'; break; \ + case '\r': output[chars++] = '\\'; output[chars++] = 'r'; break; \ + case '\t': output[chars++] = '\\'; output[chars++] = 't'; break; \ + default: \ + if (c <= 0x1f) { \ + output[chars++] = '\\'; \ + output[chars++] = 'u'; \ + output[chars++] = '0'; \ + output[chars++] = '0'; \ + output[chars++] = Py_hexdigits[(c >> 4) & 0xf]; \ + output[chars++] = Py_hexdigits[(c ) & 0xf]; \ + } else { \ + output[chars++] = c; \ + } \ + } \ + } \ + output[chars++] = '"'; \ + } while (0) + + if (kind == PyUnicode_1BYTE_KIND) { + Py_UCS1 *output = PyUnicode_1BYTE_DATA(rval); + ENCODE_OUTPUT; + } else if (kind == PyUnicode_2BYTE_KIND) { + Py_UCS2 *output = PyUnicode_2BYTE_DATA(rval); + ENCODE_OUTPUT; + } else { + Py_UCS4 *output = PyUnicode_4BYTE_DATA(rval); + assert(kind == PyUnicode_4BYTE_KIND); + ENCODE_OUTPUT; + } +#undef ENCODE_OUTPUT + +#ifdef Py_DEBUG + assert(_PyUnicode_CheckConsistency(rval, 1)); +#endif + return rval; +} + static void raise_errmsg(char *msg, PyObject *s, Py_ssize_t end) { - /* Use the Python function json.decoder.errmsg to raise a nice - looking ValueError exception */ - static PyObject *errmsg_fn = NULL; - PyObject *pymsg; - if (errmsg_fn == NULL) { + /* Use JSONDecodeError exception to raise a nice looking ValueError subclass */ + static PyObject *JSONDecodeError = NULL; + PyObject *exc; + if (JSONDecodeError == NULL) { PyObject *decoder = PyImport_ImportModule("json.decoder"); if (decoder == NULL) return; - errmsg_fn = PyObject_GetAttrString(decoder, "errmsg"); + JSONDecodeError = PyObject_GetAttrString(decoder, "JSONDecodeError"); Py_DECREF(decoder); - if (errmsg_fn == NULL) + if (JSONDecodeError == NULL) return; } - pymsg = PyObject_CallFunction(errmsg_fn, "(zOn)", msg, s, end); - if (pymsg) { - PyErr_SetObject(PyExc_ValueError, pymsg); - Py_DECREF(pymsg); + exc = PyObject_CallFunction(JSONDecodeError, "(zOn)", msg, s, end); + if (exc) { + PyErr_SetObject(JSONDecodeError, exc); + Py_DECREF(exc); } } @@ -287,7 +384,7 @@ _build_rval_index_tuple(PyObject *rval, Py_ssize_t idx) { } \ } \ if (PyList_Append(chunks, chunk)) { \ - Py_DECREF(chunk); \ + Py_CLEAR(chunk); \ goto bail; \ } \ Py_CLEAR(chunk); \ @@ -530,6 +627,31 @@ py_encode_basestring_ascii(PyObject* self UNUSED, PyObject *pystr) return rval; } + +PyDoc_STRVAR(pydoc_encode_basestring, + "encode_basestring(string) -> string\n" + "\n" + "Return a JSON representation of a Python string" +); + +static PyObject * +py_encode_basestring(PyObject* self UNUSED, PyObject *pystr) +{ + PyObject *rval; + /* Return a JSON representation of a Python string */ + /* METH_O */ + if (PyUnicode_Check(pystr)) { + rval = escape_unicode(pystr); + } + else { + PyErr_Format(PyExc_TypeError, + "first argument must be a string, not %.80s", + Py_TYPE(pystr)->tp_name); + return NULL; + } + return rval; +} + static void scanner_dealloc(PyObject *self) { @@ -705,7 +827,7 @@ _parse_object_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ss static PyObject * _parse_array_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) { - /* Read a JSON array from PyString pystr. + /* Read a JSON array from PyUnicode pystr. idx is the index of the first character after the opening brace. *next_idx_ptr is a return-by-reference index to the first character after the closing brace. @@ -777,8 +899,8 @@ _parse_array_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssi } static PyObject * -_parse_constant(PyScannerObject *s, char *constant, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) { - /* Read a JSON constant from PyString pystr. +_parse_constant(PyScannerObject *s, const char *constant, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) { + /* Read a JSON constant. constant is the constant string that was found ("NaN", "Infinity", "-Infinity"). idx is the index of the first character of the constant @@ -810,7 +932,7 @@ _match_number_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t start, Py_ the number. Returns a new PyObject representation of that number: - PyInt, PyLong, or PyFloat. + PyLong, or PyFloat. May return other types if parse_int or parse_float are set */ void *str; @@ -941,6 +1063,10 @@ scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_ kind = PyUnicode_KIND(pystr); length = PyUnicode_GET_LENGTH(pystr); + if (idx < 0) { + PyErr_SetString(PyExc_ValueError, "idx cannot be negative"); + return NULL; + } if (idx >= length) { raise_stop_iteration(idx); return NULL; @@ -1219,7 +1345,14 @@ encoder_init(PyObject *self, PyObject *args, PyObject *kwds) s->item_separator = item_separator; s->sort_keys = sort_keys; s->skipkeys = skipkeys; - s->fast_encode = (PyCFunction_Check(s->encoder) && PyCFunction_GetFunction(s->encoder) == (PyCFunction)py_encode_basestring_ascii); + s->fast_encode = NULL; + if (PyCFunction_Check(s->encoder)) { + PyCFunction f = PyCFunction_GetFunction(s->encoder); + if (f == (PyCFunction)py_encode_basestring_ascii || + f == (PyCFunction)py_encode_basestring) { + s->fast_encode = f; + } + } s->allow_nan = PyObject_IsTrue(allow_nan); Py_INCREF(s->markers); @@ -1368,7 +1501,7 @@ encoder_encode_string(PyEncoderObject *s, PyObject *obj) { /* Return the JSON representation of a string */ if (s->fast_encode) - return py_encode_basestring_ascii(NULL, obj); + return s->fast_encode(NULL, obj); else return PyObject_CallFunctionObjArgs(s->encoder, obj, NULL); } @@ -1551,6 +1684,7 @@ encoder_listencode_dict(PyEncoderObject *s, _PyAccu *acc, if (item == NULL) goto bail; PyList_SET_ITEM(items, i, item); + item = NULL; Py_DECREF(key); } } @@ -1835,6 +1969,10 @@ static PyMethodDef speedups_methods[] = { (PyCFunction)py_encode_basestring_ascii, METH_O, pydoc_encode_basestring_ascii}, + {"encode_basestring", + (PyCFunction)py_encode_basestring, + METH_O, + pydoc_encode_basestring}, {"scanstring", (PyCFunction)py_scanstring, METH_VARARGS, diff --git a/Modules/_localemodule.c b/Modules/_localemodule.c index 400c3448baba..b1d6add477a6 100644 --- a/Modules/_localemodule.c +++ b/Modules/_localemodule.c @@ -254,7 +254,7 @@ PyLocale_strxfrm(PyObject* self, PyObject* args) /* assume no change in size, first */ n1 = n1 + 1; - buf = PyMem_Malloc(n1 * sizeof(wchar_t)); + buf = PyMem_New(wchar_t, n1); if (!buf) { PyErr_NoMemory(); goto exit; diff --git a/Modules/_lsprof.c b/Modules/_lsprof.c index 894788916d7e..66e534f2a843 100644 --- a/Modules/_lsprof.c +++ b/Modules/_lsprof.c @@ -202,6 +202,8 @@ normalizeUserObj(PyObject *obj) */ PyObject *self = fn->m_self; PyObject *name = PyUnicode_FromString(fn->m_ml->ml_name); + PyObject *modname = fn->m_module; + if (name != NULL) { PyObject *mo = _PyType_Lookup(Py_TYPE(self), name); Py_XINCREF(mo); @@ -213,9 +215,14 @@ normalizeUserObj(PyObject *obj) return res; } } + /* Otherwise, use __module__ */ PyErr_Clear(); - return PyUnicode_FromFormat("", - fn->m_ml->ml_name); + if (modname != NULL && PyUnicode_Check(modname)) + return PyUnicode_FromFormat("", + modname, fn->m_ml->ml_name); + else + return PyUnicode_FromFormat("", + fn->m_ml->ml_name); } } @@ -451,7 +458,6 @@ profiler_callback(PyObject *self, PyFrameObject *frame, int what, PyTrace_RETURN event will be generated, so we don't need to handle it. */ -#ifdef PyTrace_C_CALL /* not defined in Python <= 2.3 */ /* the Python function 'frame' is issuing a call to the built-in function 'arg' */ case PyTrace_C_CALL: @@ -473,7 +479,6 @@ profiler_callback(PyObject *self, PyFrameObject *frame, int what, ((PyCFunctionObject *)arg)->m_ml); } break; -#endif default: break; @@ -663,13 +668,7 @@ setBuiltins(ProfilerObject *pObj, int nvalue) if (nvalue == 0) pObj->flags &= ~POF_BUILTINS; else if (nvalue > 0) { -#ifndef PyTrace_C_CALL - PyErr_SetString(PyExc_ValueError, - "builtins=True requires Python >= 2.4"); - return -1; -#else pObj->flags |= POF_BUILTINS; -#endif } return 0; } @@ -767,11 +766,7 @@ profiler_init(ProfilerObject *pObj, PyObject *args, PyObject *kw) PyObject *timer = NULL; double timeunit = 0.0; int subcalls = 1; -#ifdef PyTrace_C_CALL int builtins = 1; -#else - int builtins = 0; -#endif static char *kwlist[] = {"timer", "timeunit", "subcalls", "builtins", 0}; diff --git a/Modules/_lzmamodule.c b/Modules/_lzmamodule.c index 1217ed4d1c09..bae7df6e1307 100644 --- a/Modules/_lzmamodule.c +++ b/Modules/_lzmamodule.c @@ -66,6 +66,9 @@ typedef struct { int check; char eof; PyObject *unused_data; + char needs_input; + uint8_t *input_buffer; + size_t input_buffer_size; #ifdef WITH_THREAD PyThread_type_lock lock; #endif @@ -142,10 +145,15 @@ PyLzma_Free(void *opaque, void *ptr) #endif static int -grow_buffer(PyObject **buf) +grow_buffer(PyObject **buf, Py_ssize_t max_length) { - size_t size = PyBytes_GET_SIZE(*buf); - return _PyBytes_Resize(buf, size + (size >> 3) + 6); + Py_ssize_t size = PyBytes_GET_SIZE(*buf); + Py_ssize_t newsize = size + (size >> 3) + 6; + + if (max_length > 0 && newsize > max_length) + newsize = max_length; + + return _PyBytes_Resize(buf, newsize); } @@ -298,36 +306,37 @@ parse_filter_spec_bcj(PyObject *spec) return options; } -static void * -parse_filter_spec(lzma_filter *f, PyObject *spec) +static int +lzma_filter_converter(PyObject *spec, void *ptr) { + lzma_filter *f = (lzma_filter *)ptr; PyObject *id_obj; if (!PyMapping_Check(spec)) { PyErr_SetString(PyExc_TypeError, "Filter specifier must be a dict or dict-like object"); - return NULL; + return 0; } id_obj = PyMapping_GetItemString(spec, "id"); if (id_obj == NULL) { if (PyErr_ExceptionMatches(PyExc_KeyError)) PyErr_SetString(PyExc_ValueError, "Filter specifier must have an \"id\" entry"); - return NULL; + return 0; } f->id = PyLong_AsUnsignedLongLong(id_obj); Py_DECREF(id_obj); if (PyErr_Occurred()) - return NULL; + return 0; switch (f->id) { case LZMA_FILTER_LZMA1: case LZMA_FILTER_LZMA2: f->options = parse_filter_spec_lzma(spec); - return f->options; + return f->options != NULL; case LZMA_FILTER_DELTA: f->options = parse_filter_spec_delta(spec); - return f->options; + return f->options != NULL; case LZMA_FILTER_X86: case LZMA_FILTER_POWERPC: case LZMA_FILTER_IA64: @@ -335,10 +344,10 @@ parse_filter_spec(lzma_filter *f, PyObject *spec) case LZMA_FILTER_ARMTHUMB: case LZMA_FILTER_SPARC: f->options = parse_filter_spec_bcj(spec); - return f->options; + return f->options != NULL; default: PyErr_Format(PyExc_ValueError, "Invalid filter ID: %llu", f->id); - return NULL; + return 0; } } @@ -369,7 +378,7 @@ parse_filter_chain_spec(lzma_filter filters[], PyObject *filterspecs) for (i = 0; i < num_filters; i++) { int ok = 1; PyObject *spec = PySequence_GetItem(filterspecs, i); - if (spec == NULL || parse_filter_spec(&filters[i], spec) == NULL) + if (spec == NULL || !lzma_filter_converter(spec, &filters[i])) ok = 0; Py_XDECREF(spec); if (!ok) { @@ -468,12 +477,42 @@ build_filter_spec(const lzma_filter *f) } +/*[clinic input] +output preset file +module _lzma +class _lzma.LZMACompressor "Compressor *" "&Compressor_type" +class _lzma.LZMADecompressor "Decompressor *" "&Decompressor_type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=f17afc786525d6c2]*/ + +#include "clinic/_lzmamodule.c.h" + +/*[python input] + +class lzma_vli_converter(CConverter): + type = 'lzma_vli' + converter = 'lzma_vli_converter' + +class lzma_filter_converter(CConverter): + type = 'lzma_filter' + converter = 'lzma_filter_converter' + c_default = c_ignored_default = "{LZMA_VLI_UNKNOWN, NULL}" + + def cleanup(self): + name = ensure_legal_c_identifier(self.name) + return ('if (%(name)s.id != LZMA_VLI_UNKNOWN)\n' + ' PyMem_Free(%(name)s.options);\n') % {'name': name} + +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=74fe7631ce377a94]*/ + + /* LZMACompressor class. */ static PyObject * compress(Compressor *c, uint8_t *data, size_t len, lzma_action action) { - size_t data_size = 0; + Py_ssize_t data_size = 0; PyObject *result; result = PyBytes_FromStringAndSize(NULL, INITIAL_BUFFER_SIZE); @@ -496,7 +535,7 @@ compress(Compressor *c, uint8_t *data, size_t len, lzma_action action) (action == LZMA_FINISH && lzret == LZMA_STREAM_END)) { break; } else if (c->lzs.avail_out == 0) { - if (grow_buffer(&result) == -1) + if (grow_buffer(&result, -1) == -1) goto error; c->lzs.next_out = (uint8_t *)PyBytes_AS_STRING(result) + data_size; c->lzs.avail_out = PyBytes_GET_SIZE(result) - data_size; @@ -512,44 +551,51 @@ compress(Compressor *c, uint8_t *data, size_t len, lzma_action action) return NULL; } -PyDoc_STRVAR(Compressor_compress_doc, -"compress(data) -> bytes\n" -"\n" -"Provide data to the compressor object. Returns a chunk of\n" -"compressed data if possible, or b\"\" otherwise.\n" -"\n" -"When you have finished providing data to the compressor, call the\n" -"flush() method to finish the conversion process.\n"); +/*[clinic input] +_lzma.LZMACompressor.compress + + self: self(type="Compressor *") + data: Py_buffer + / + +Provide data to the compressor object. + +Returns a chunk of compressed data if possible, or b'' otherwise. + +When you have finished providing data to the compressor, call the +flush() method to finish the compression process. +[clinic start generated code]*/ static PyObject * -Compressor_compress(Compressor *self, PyObject *args) +_lzma_LZMACompressor_compress_impl(Compressor *self, Py_buffer *data) +/*[clinic end generated code: output=31f615136963e00f input=8b60cb13e0ce6420]*/ { - Py_buffer buffer; PyObject *result = NULL; - if (!PyArg_ParseTuple(args, "y*:compress", &buffer)) - return NULL; - ACQUIRE_LOCK(self); if (self->flushed) PyErr_SetString(PyExc_ValueError, "Compressor has been flushed"); else - result = compress(self, buffer.buf, buffer.len, LZMA_RUN); + result = compress(self, data->buf, data->len, LZMA_RUN); RELEASE_LOCK(self); - PyBuffer_Release(&buffer); return result; } -PyDoc_STRVAR(Compressor_flush_doc, -"flush() -> bytes\n" -"\n" -"Finish the compression process. Returns the compressed data left\n" -"in internal buffers.\n" -"\n" -"The compressor object cannot be used after this method is called.\n"); +/*[clinic input] +_lzma.LZMACompressor.flush + + self: self(type="Compressor *") + +Finish the compression process. + +Returns the compressed data left in internal buffers. + +The compressor object may not be used after this method is called. +[clinic start generated code]*/ static PyObject * -Compressor_flush(Compressor *self, PyObject *noargs) +_lzma_LZMACompressor_flush_impl(Compressor *self) +/*[clinic end generated code: output=fec21f3e22504f50 input=3060fb26f9b4042c]*/ { PyObject *result = NULL; @@ -650,6 +696,39 @@ Compressor_init_raw(lzma_stream *lzs, PyObject *filterspecs) return 0; } +/*[-clinic input] +_lzma.LZMACompressor.__init__ + + self: self(type="Compressor *") + format: int(c_default="FORMAT_XZ") = FORMAT_XZ + The container format to use for the output. This can + be FORMAT_XZ (default), FORMAT_ALONE, or FORMAT_RAW. + + check: int(c_default="-1") = unspecified + The integrity check to use. For FORMAT_XZ, the default + is CHECK_CRC64. FORMAT_ALONE and FORMAT_RAW do not suport integrity + checks; for these formats, check must be omitted, or be CHECK_NONE. + + preset: object = None + If provided should be an integer in the range 0-9, optionally + OR-ed with the constant PRESET_EXTREME. + + filters: object = None + If provided should be a sequence of dicts. Each dict should + have an entry for "id" indicating the ID of the filter, plus + additional entries for options to the filter. + +Create a compressor object for compressing data incrementally. + +The settings used by the compressor can be specified either as a +preset compression level (with the 'preset' argument), or in detail +as a custom filter chain (with the 'filters' argument). For FORMAT_XZ +and FORMAT_ALONE, the default is to use the PRESET_DEFAULT preset +level. For FORMAT_RAW, the caller must always specify a filter chain; +the raw compressor does not support preset compression levels. + +For one-shot compression, use the compress() function instead. +[-clinic start generated code]*/ static int Compressor_init(Compressor *self, PyObject *args, PyObject *kwargs) { @@ -739,10 +818,8 @@ Compressor_dealloc(Compressor *self) } static PyMethodDef Compressor_methods[] = { - {"compress", (PyCFunction)Compressor_compress, METH_VARARGS, - Compressor_compress_doc}, - {"flush", (PyCFunction)Compressor_flush, METH_NOARGS, - Compressor_flush_doc}, + _LZMA_LZMACOMPRESSOR_COMPRESS_METHODDEF + _LZMA_LZMACOMPRESSOR_FLUSH_METHODDEF {"__getstate__", (PyCFunction)Compressor_getstate, METH_NOARGS}, {NULL} }; @@ -819,25 +896,33 @@ static PyTypeObject Compressor_type = { /* LZMADecompressor class. */ -static PyObject * -decompress(Decompressor *d, uint8_t *data, size_t len) +/* Decompress data of length d->lzs.avail_in in d->lzs.next_in. The output + buffer is allocated dynamically and returned. At most max_length bytes are + returned, so some of the input may not be consumed. d->lzs.next_in and + d->lzs.avail_in are updated to reflect the consumed input. */ +static PyObject* +decompress_buf(Decompressor *d, Py_ssize_t max_length) { - size_t data_size = 0; + Py_ssize_t data_size = 0; PyObject *result; - - result = PyBytes_FromStringAndSize(NULL, INITIAL_BUFFER_SIZE); + lzma_stream *lzs = &d->lzs; + + if (max_length < 0 || max_length >= INITIAL_BUFFER_SIZE) + result = PyBytes_FromStringAndSize(NULL, INITIAL_BUFFER_SIZE); + else + result = PyBytes_FromStringAndSize(NULL, max_length); if (result == NULL) return NULL; - d->lzs.next_in = data; - d->lzs.avail_in = len; - d->lzs.next_out = (uint8_t *)PyBytes_AS_STRING(result); - d->lzs.avail_out = PyBytes_GET_SIZE(result); + + lzs->next_out = (uint8_t *)PyBytes_AS_STRING(result); + lzs->avail_out = PyBytes_GET_SIZE(result); + for (;;) { lzma_ret lzret; Py_BEGIN_ALLOW_THREADS - lzret = lzma_code(&d->lzs, LZMA_RUN); - data_size = (char *)d->lzs.next_out - PyBytes_AS_STRING(result); + lzret = lzma_code(lzs, LZMA_RUN); + data_size = (char *)lzs->next_out - PyBytes_AS_STRING(result); Py_END_ALLOW_THREADS if (catch_lzma_error(lzret)) goto error; @@ -845,26 +930,131 @@ decompress(Decompressor *d, uint8_t *data, size_t len) d->check = lzma_get_check(&d->lzs); if (lzret == LZMA_STREAM_END) { d->eof = 1; - if (d->lzs.avail_in > 0) { - Py_CLEAR(d->unused_data); - d->unused_data = PyBytes_FromStringAndSize( - (char *)d->lzs.next_in, d->lzs.avail_in); - if (d->unused_data == NULL) - goto error; - } break; - } else if (d->lzs.avail_in == 0) { + } else if (lzs->avail_in == 0) { break; - } else if (d->lzs.avail_out == 0) { - if (grow_buffer(&result) == -1) + } else if (lzs->avail_out == 0) { + if (data_size == max_length) + break; + if (grow_buffer(&result, max_length) == -1) goto error; - d->lzs.next_out = (uint8_t *)PyBytes_AS_STRING(result) + data_size; - d->lzs.avail_out = PyBytes_GET_SIZE(result) - data_size; + lzs->next_out = (uint8_t *)PyBytes_AS_STRING(result) + data_size; + lzs->avail_out = PyBytes_GET_SIZE(result) - data_size; } } if (data_size != PyBytes_GET_SIZE(result)) if (_PyBytes_Resize(&result, data_size) == -1) goto error; + + return result; + +error: + Py_XDECREF(result); + return NULL; +} + +static PyObject * +decompress(Decompressor *d, uint8_t *data, size_t len, Py_ssize_t max_length) +{ + char input_buffer_in_use; + PyObject *result; + lzma_stream *lzs = &d->lzs; + + /* Prepend unconsumed input if necessary */ + if (lzs->next_in != NULL) { + size_t avail_now, avail_total; + + /* Number of bytes we can append to input buffer */ + avail_now = (d->input_buffer + d->input_buffer_size) + - (lzs->next_in + lzs->avail_in); + + /* Number of bytes we can append if we move existing + contents to beginning of buffer (overwriting + consumed input) */ + avail_total = d->input_buffer_size - lzs->avail_in; + + if (avail_total < len) { + size_t offset = lzs->next_in - d->input_buffer; + uint8_t *tmp; + size_t new_size = d->input_buffer_size + len - avail_now; + + /* Assign to temporary variable first, so we don't + lose address of allocated buffer if realloc fails */ + tmp = PyMem_Realloc(d->input_buffer, new_size); + if (tmp == NULL) { + PyErr_SetNone(PyExc_MemoryError); + return NULL; + } + d->input_buffer = tmp; + d->input_buffer_size = new_size; + + lzs->next_in = d->input_buffer + offset; + } + else if (avail_now < len) { + memmove(d->input_buffer, lzs->next_in, + lzs->avail_in); + lzs->next_in = d->input_buffer; + } + memcpy((void*)(lzs->next_in + lzs->avail_in), data, len); + lzs->avail_in += len; + input_buffer_in_use = 1; + } + else { + lzs->next_in = data; + lzs->avail_in = len; + input_buffer_in_use = 0; + } + + result = decompress_buf(d, max_length); + if(result == NULL) + return NULL; + + if (d->eof) { + d->needs_input = 0; + if (lzs->avail_in > 0) { + Py_CLEAR(d->unused_data); + d->unused_data = PyBytes_FromStringAndSize( + (char *)lzs->next_in, lzs->avail_in); + if (d->unused_data == NULL) + goto error; + } + } + else if (lzs->avail_in == 0) { + lzs->next_in = NULL; + d->needs_input = 1; + } + else { + d->needs_input = 0; + + /* If we did not use the input buffer, we now have + to copy the tail from the caller's buffer into the + input buffer */ + if (!input_buffer_in_use) { + + /* Discard buffer if it's too small + (resizing it may needlessly copy the current contents) */ + if (d->input_buffer != NULL && + d->input_buffer_size < lzs->avail_in) { + PyMem_Free(d->input_buffer); + d->input_buffer = NULL; + } + + /* Allocate if necessary */ + if (d->input_buffer == NULL) { + d->input_buffer = PyMem_Malloc(lzs->avail_in); + if (d->input_buffer == NULL) { + PyErr_SetNone(PyExc_MemoryError); + goto error; + } + d->input_buffer_size = lzs->avail_in; + } + + /* Copy tail */ + memcpy(d->input_buffer, lzs->next_in, lzs->avail_in); + lzs->next_in = d->input_buffer; + } + } + return result; error: @@ -872,32 +1062,41 @@ decompress(Decompressor *d, uint8_t *data, size_t len) return NULL; } -PyDoc_STRVAR(Decompressor_decompress_doc, -"decompress(data) -> bytes\n" -"\n" -"Provide data to the decompressor object. Returns a chunk of\n" -"decompressed data if possible, or b\"\" otherwise.\n" -"\n" -"Attempting to decompress data after the end of the stream is\n" -"reached raises an EOFError. Any data found after the end of the\n" -"stream is ignored, and saved in the unused_data attribute.\n"); +/*[clinic input] +_lzma.LZMADecompressor.decompress + + self: self(type="Decompressor *") + data: Py_buffer + max_length: Py_ssize_t=-1 + +Decompress *data*, returning uncompressed data as bytes. + +If *max_length* is nonnegative, returns at most *max_length* bytes of +decompressed data. If this limit is reached and further output can be +produced, *self.needs_input* will be set to ``False``. In this case, the next +call to *decompress()* may provide *data* as b'' to obtain more of the output. + +If all of the input data was decompressed and returned (either because this +was less than *max_length* bytes, or because *max_length* was negative), +*self.needs_input* will be set to True. + +Attempting to decompress data after the end of stream is reached raises an +EOFError. Any data found after the end of the stream is ignored and saved in +the unused_data attribute. +[clinic start generated code]*/ static PyObject * -Decompressor_decompress(Decompressor *self, PyObject *args) +_lzma_LZMADecompressor_decompress_impl(Decompressor *self, Py_buffer *data, Py_ssize_t max_length) +/*[clinic end generated code: output=1532a5bb23629001 input=f2bb902cc1caf203]*/ { - Py_buffer buffer; PyObject *result = NULL; - if (!PyArg_ParseTuple(args, "y*:decompress", &buffer)) - return NULL; - ACQUIRE_LOCK(self); if (self->eof) PyErr_SetString(PyExc_EOFError, "Already at end of stream"); else - result = decompress(self, buffer.buf, buffer.len); + result = decompress(self, data->buf, data->len, max_length); RELEASE_LOCK(self); - PyBuffer_Release(&buffer); return result; } @@ -925,38 +1124,56 @@ Decompressor_init_raw(lzma_stream *lzs, PyObject *filterspecs) return 0; } +/*[clinic input] +_lzma.LZMADecompressor.__init__ + + self: self(type="Decompressor *") + format: int(c_default="FORMAT_AUTO") = FORMAT_AUTO + Specifies the container format of the input stream. If this is + FORMAT_AUTO (the default), the decompressor will automatically detect + whether the input is FORMAT_XZ or FORMAT_ALONE. Streams created with + FORMAT_RAW cannot be autodetected. + + memlimit: object = None + Limit the amount of memory used by the decompressor. This will cause + decompression to fail if the input cannot be decompressed within the + given limit. + + filters: object = None + A custom filter chain. This argument is required for FORMAT_RAW, and + not accepted with any other format. When provided, this should be a + sequence of dicts, each indicating the ID and options for a single + filter. + +Create a decompressor object for decompressing data incrementally. + +For one-shot decompression, use the decompress() function instead. +[clinic start generated code]*/ + static int -Decompressor_init(Decompressor *self, PyObject *args, PyObject *kwargs) +_lzma_LZMADecompressor___init___impl(Decompressor *self, int format, PyObject *memlimit, PyObject *filters) +/*[clinic end generated code: output=9b119f6f2cc2d7a8 input=458ca6132ef29801]*/ { - static char *arg_names[] = {"format", "memlimit", "filters", NULL}; const uint32_t decoder_flags = LZMA_TELL_ANY_CHECK | LZMA_TELL_NO_CHECK; - int format = FORMAT_AUTO; - uint64_t memlimit = UINT64_MAX; - PyObject *memlimit_obj = Py_None; - PyObject *filterspecs = Py_None; + uint64_t memlimit_ = UINT64_MAX; lzma_ret lzret; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, - "|iOO:LZMADecompressor", arg_names, - &format, &memlimit_obj, &filterspecs)) - return -1; - - if (memlimit_obj != Py_None) { + if (memlimit != Py_None) { if (format == FORMAT_RAW) { PyErr_SetString(PyExc_ValueError, "Cannot specify memory limit with FORMAT_RAW"); return -1; } - memlimit = PyLong_AsUnsignedLongLong(memlimit_obj); + memlimit_ = PyLong_AsUnsignedLongLong(memlimit); if (PyErr_Occurred()) return -1; } - if (format == FORMAT_RAW && filterspecs == Py_None) { + if (format == FORMAT_RAW && filters == Py_None) { PyErr_SetString(PyExc_ValueError, "Must specify filters for FORMAT_RAW"); return -1; - } else if (format != FORMAT_RAW && filterspecs != Py_None) { + } else if (format != FORMAT_RAW && filters != Py_None) { PyErr_SetString(PyExc_ValueError, "Cannot specify filters except with FORMAT_RAW"); return -1; @@ -966,6 +1183,7 @@ Decompressor_init(Decompressor *self, PyObject *args, PyObject *kwargs) self->alloc.alloc = PyLzma_Malloc; self->alloc.free = PyLzma_Free; self->lzs.allocator = &self->alloc; + self->lzs.next_in = NULL; #ifdef WITH_THREAD self->lock = PyThread_allocate_lock(); @@ -976,33 +1194,36 @@ Decompressor_init(Decompressor *self, PyObject *args, PyObject *kwargs) #endif self->check = LZMA_CHECK_UNKNOWN; + self->needs_input = 1; + self->input_buffer = NULL; + self->input_buffer_size = 0; self->unused_data = PyBytes_FromStringAndSize(NULL, 0); if (self->unused_data == NULL) goto error; switch (format) { case FORMAT_AUTO: - lzret = lzma_auto_decoder(&self->lzs, memlimit, decoder_flags); + lzret = lzma_auto_decoder(&self->lzs, memlimit_, decoder_flags); if (catch_lzma_error(lzret)) break; return 0; case FORMAT_XZ: - lzret = lzma_stream_decoder(&self->lzs, memlimit, decoder_flags); + lzret = lzma_stream_decoder(&self->lzs, memlimit_, decoder_flags); if (catch_lzma_error(lzret)) break; return 0; case FORMAT_ALONE: self->check = LZMA_CHECK_NONE; - lzret = lzma_alone_decoder(&self->lzs, memlimit); + lzret = lzma_alone_decoder(&self->lzs, memlimit_); if (catch_lzma_error(lzret)) break; return 0; case FORMAT_RAW: self->check = LZMA_CHECK_NONE; - if (Decompressor_init_raw(&self->lzs, filterspecs) == -1) + if (Decompressor_init_raw(&self->lzs, filters) == -1) break; return 0; @@ -1024,6 +1245,9 @@ Decompressor_init(Decompressor *self, PyObject *args, PyObject *kwargs) static void Decompressor_dealloc(Decompressor *self) { + if(self->input_buffer != NULL) + PyMem_Free(self->input_buffer); + lzma_end(&self->lzs); Py_CLEAR(self->unused_data); #ifdef WITH_THREAD @@ -1034,8 +1258,7 @@ Decompressor_dealloc(Decompressor *self) } static PyMethodDef Decompressor_methods[] = { - {"decompress", (PyCFunction)Decompressor_decompress, METH_VARARGS, - Decompressor_decompress_doc}, + _LZMA_LZMADECOMPRESSOR_DECOMPRESS_METHODDEF {"__getstate__", (PyCFunction)Decompressor_getstate, METH_NOARGS}, {NULL} }; @@ -1046,6 +1269,9 @@ PyDoc_STRVAR(Decompressor_check_doc, PyDoc_STRVAR(Decompressor_eof_doc, "True if the end-of-stream marker has been reached."); +PyDoc_STRVAR(Decompressor_needs_input_doc, +"True if more input is needed before more decompressed data can be produced."); + PyDoc_STRVAR(Decompressor_unused_data_doc, "Data found after the end of the compressed stream."); @@ -1054,32 +1280,13 @@ static PyMemberDef Decompressor_members[] = { Decompressor_check_doc}, {"eof", T_BOOL, offsetof(Decompressor, eof), READONLY, Decompressor_eof_doc}, + {"needs_input", T_BOOL, offsetof(Decompressor, needs_input), READONLY, + Decompressor_needs_input_doc}, {"unused_data", T_OBJECT_EX, offsetof(Decompressor, unused_data), READONLY, Decompressor_unused_data_doc}, {NULL} }; -PyDoc_STRVAR(Decompressor_doc, -"LZMADecompressor(format=FORMAT_AUTO, memlimit=None, filters=None)\n" -"\n" -"Create a decompressor object for decompressing data incrementally.\n" -"\n" -"format specifies the container format of the input stream. If this is\n" -"FORMAT_AUTO (the default), the decompressor will automatically detect\n" -"whether the input is FORMAT_XZ or FORMAT_ALONE. Streams created with\n" -"FORMAT_RAW cannot be autodetected.\n" -"\n" -"memlimit can be specified to limit the amount of memory used by the\n" -"decompressor. This will cause decompression to fail if the input\n" -"cannot be decompressed within the given limit.\n" -"\n" -"filters specifies a custom filter chain. This argument is required for\n" -"FORMAT_RAW, and not accepted with any other format. When provided,\n" -"this should be a sequence of dicts, each indicating the ID and options\n" -"for a single filter.\n" -"\n" -"For one-shot decompression, use the decompress() function instead.\n"); - static PyTypeObject Decompressor_type = { PyVarObject_HEAD_INIT(NULL, 0) "_lzma.LZMADecompressor", /* tp_name */ @@ -1101,7 +1308,7 @@ static PyTypeObject Decompressor_type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ - Decompressor_doc, /* tp_doc */ + _lzma_LZMADecompressor___init____doc__, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ @@ -1116,7 +1323,7 @@ static PyTypeObject Decompressor_type = { 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ - (initproc)Decompressor_init, /* tp_init */ + _lzma_LZMADecompressor___init__, /* tp_init */ 0, /* tp_alloc */ PyType_GenericNew, /* tp_new */ }; @@ -1124,48 +1331,42 @@ static PyTypeObject Decompressor_type = { /* Module-level functions. */ -PyDoc_STRVAR(is_check_supported_doc, -"is_check_supported(check_id) -> bool\n" -"\n" -"Test whether the given integrity check is supported.\n" -"\n" -"Always returns True for CHECK_NONE and CHECK_CRC32.\n"); +/*[clinic input] +_lzma.is_check_supported + check_id: int + / -static PyObject * -is_check_supported(PyObject *self, PyObject *args) -{ - int check_id; +Test whether the given integrity check is supported. - if (!PyArg_ParseTuple(args, "i:is_check_supported", &check_id)) - return NULL; +Always returns True for CHECK_NONE and CHECK_CRC32. +[clinic start generated code]*/ +static PyObject * +_lzma_is_check_supported_impl(PyModuleDef *module, int check_id) +/*[clinic end generated code: output=bb828e90e00ad96e input=5518297b97b2318f]*/ +{ return PyBool_FromLong(lzma_check_is_supported(check_id)); } -PyDoc_STRVAR(_encode_filter_properties_doc, -"_encode_filter_properties(filter) -> bytes\n" -"\n" -"Return a bytes object encoding the options (properties) of the filter\n" -"specified by *filter* (a dict).\n" -"\n" -"The result does not include the filter ID itself, only the options.\n"); +/*[clinic input] +_lzma._encode_filter_properties + filter: lzma_filter(c_default="{LZMA_VLI_UNKNOWN, NULL}") + / + +Return a bytes object encoding the options (properties) of the filter specified by *filter* (a dict). + +The result does not include the filter ID itself, only the options. +[clinic start generated code]*/ static PyObject * -_encode_filter_properties(PyObject *self, PyObject *args) +_lzma__encode_filter_properties_impl(PyModuleDef *module, lzma_filter filter) +/*[clinic end generated code: output=b5fe690acd6b61d1 input=d4c64f1b557c77d4]*/ { - PyObject *filterspec; - lzma_filter filter; lzma_ret lzret; uint32_t encoded_size; PyObject *result = NULL; - if (!PyArg_ParseTuple(args, "O:_encode_filter_properties", &filterspec)) - return NULL; - - if (parse_filter_spec(&filter, filterspec) == NULL) - return NULL; - lzret = lzma_properties_size(&encoded_size, &filter); if (catch_lzma_error(lzret)) goto error; @@ -1179,37 +1380,36 @@ _encode_filter_properties(PyObject *self, PyObject *args) if (catch_lzma_error(lzret)) goto error; - PyMem_Free(filter.options); return result; error: Py_XDECREF(result); - PyMem_Free(filter.options); return NULL; } -PyDoc_STRVAR(_decode_filter_properties_doc, -"_decode_filter_properties(filter_id, encoded_props) -> dict\n" -"\n" -"Return a dict describing a filter with ID *filter_id*, and options\n" -"(properties) decoded from the bytes object *encoded_props*.\n"); +/*[clinic input] +_lzma._decode_filter_properties + filter_id: lzma_vli + encoded_props: Py_buffer + / + +Return a bytes object encoding the options (properties) of the filter specified by *filter* (a dict). + +The result does not include the filter ID itself, only the options. +[clinic start generated code]*/ static PyObject * -_decode_filter_properties(PyObject *self, PyObject *args) +_lzma__decode_filter_properties_impl(PyModuleDef *module, lzma_vli filter_id, Py_buffer *encoded_props) +/*[clinic end generated code: output=235f7f5345d48744 input=246410800782160c]*/ { - Py_buffer encoded_props; lzma_filter filter; lzma_ret lzret; PyObject *result = NULL; - - if (!PyArg_ParseTuple(args, "O&y*:_decode_filter_properties", - lzma_vli_converter, &filter.id, &encoded_props)) - return NULL; + filter.id = filter_id; lzret = lzma_properties_decode( - &filter, NULL, encoded_props.buf, encoded_props.len); - PyBuffer_Release(&encoded_props); + &filter, NULL, encoded_props->buf, encoded_props->len); if (catch_lzma_error(lzret)) return NULL; @@ -1225,12 +1425,9 @@ _decode_filter_properties(PyObject *self, PyObject *args) /* Module initialization. */ static PyMethodDef module_methods[] = { - {"is_check_supported", (PyCFunction)is_check_supported, - METH_VARARGS, is_check_supported_doc}, - {"_encode_filter_properties", (PyCFunction)_encode_filter_properties, - METH_VARARGS, _encode_filter_properties_doc}, - {"_decode_filter_properties", (PyCFunction)_decode_filter_properties, - METH_VARARGS, _decode_filter_properties_doc}, + _LZMA_IS_CHECK_SUPPORTED_METHODDEF + _LZMA__ENCODE_FILTER_PROPERTIES_METHODDEF + _LZMA__DECODE_FILTER_PROPERTIES_METHODDEF {NULL} }; diff --git a/Modules/_math.c b/Modules/_math.c index fe75a36ec517..a0022082908d 100644 --- a/Modules/_math.c +++ b/Modules/_math.c @@ -22,7 +22,9 @@ static const double ln2 = 6.93147180559945286227E-01; static const double two_pow_m28 = 3.7252902984619141E-09; /* 2**-28 */ static const double two_pow_p28 = 268435456.0; /* 2**28 */ +#ifndef Py_NAN static const double zero = 0.0; +#endif /* acosh(x) * Method : @@ -238,7 +240,7 @@ _Py_log1p(double x) return x; } else if (-0.5 <= x && x <= 1.) { - /* WARNING: it's possible than an overeager compiler + /* WARNING: it's possible that an overeager compiler will incorrectly optimize the following two lines to the equivalent of "return log(1.+x)". If this happens, then results from log1p will be inaccurate diff --git a/Modules/_multiprocessing/multiprocessing.c b/Modules/_multiprocessing/multiprocessing.c index 1aaf3605714e..4ae638eea5cc 100644 --- a/Modules/_multiprocessing/multiprocessing.c +++ b/Modules/_multiprocessing/multiprocessing.c @@ -128,7 +128,9 @@ static PyMethodDef module_methods[] = { {"recv", multiprocessing_recv, METH_VARARGS, ""}, {"send", multiprocessing_send, METH_VARARGS, ""}, #endif +#ifndef POSIX_SEMAPHORES_NOT_ENABLED {"sem_unlink", _PyMp_sem_unlink, METH_VARARGS, ""}, +#endif {NULL} }; diff --git a/Modules/_opcode.c b/Modules/_opcode.c index 55cffe1ab59f..fee388f59676 100644 --- a/Modules/_opcode.c +++ b/Modules/_opcode.c @@ -1,59 +1,47 @@ #include "Python.h" #include "opcode.h" -/*[clinic] +/*[clinic input] module _opcode -[clinic]*/ -/*[clinic checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=117442e66eb376e6]*/ -/*[clinic] +/*[clinic input] _opcode.stack_effect -> int opcode: int - - [ - oparg: int - ] + oparg: object = None / Compute the stack effect of the opcode. -[clinic]*/ +[clinic start generated code]*/ PyDoc_STRVAR(_opcode_stack_effect__doc__, -"stack_effect(opcode, [oparg])\n" +"stack_effect($module, opcode, oparg=None, /)\n" +"--\n" +"\n" "Compute the stack effect of the opcode."); #define _OPCODE_STACK_EFFECT_METHODDEF \ {"stack_effect", (PyCFunction)_opcode_stack_effect, METH_VARARGS, _opcode_stack_effect__doc__}, static int -_opcode_stack_effect_impl(PyModuleDef *module, int opcode, int group_right_1, int oparg); +_opcode_stack_effect_impl(PyModuleDef *module, int opcode, PyObject *oparg); static PyObject * _opcode_stack_effect(PyModuleDef *module, PyObject *args) { PyObject *return_value = NULL; int opcode; - int group_right_1 = 0; - int oparg = 0; + PyObject *oparg = Py_None; int _return_value; - switch (PyTuple_Size(args)) { - case 1: - if (!PyArg_ParseTuple(args, "i:stack_effect", &opcode)) - return NULL; - break; - case 2: - if (!PyArg_ParseTuple(args, "ii:stack_effect", &opcode, &oparg)) - return NULL; - group_right_1 = 1; - break; - default: - PyErr_SetString(PyExc_TypeError, "_opcode.stack_effect requires 1 to 2 arguments"); - return NULL; - } - _return_value = _opcode_stack_effect_impl(module, opcode, group_right_1, oparg); + if (!PyArg_ParseTuple(args, + "i|O:stack_effect", + &opcode, &oparg)) + goto exit; + _return_value = _opcode_stack_effect_impl(module, opcode, oparg); if ((_return_value == -1) && PyErr_Occurred()) goto exit; return_value = PyLong_FromLong((long)_return_value); @@ -63,23 +51,27 @@ _opcode_stack_effect(PyModuleDef *module, PyObject *args) } static int -_opcode_stack_effect_impl(PyModuleDef *module, int opcode, int group_right_1, int oparg) -/*[clinic checksum: e880e62dc7b0de73403026eaf4f8074aa106358b]*/ +_opcode_stack_effect_impl(PyModuleDef *module, int opcode, PyObject *oparg) +/*[clinic end generated code: output=9e1133f8d587bc67 input=2d0a9ee53c0418f5]*/ { int effect; - if (HAS_ARG(opcode)) { - if (!group_right_1) { + int oparg_int = 0; + if (HAS_ARG(opcode)) { + if (oparg == Py_None) { PyErr_SetString(PyExc_ValueError, "stack_effect: opcode requires oparg but oparg was not specified"); return -1; } + oparg_int = (int)PyLong_AsLong(oparg); + if ((oparg_int == -1) && PyErr_Occurred()) + return -1; } - else if (group_right_1) { + else if (oparg != Py_None) { PyErr_SetString(PyExc_ValueError, "stack_effect: opcode does not permit oparg but oparg was specified"); return -1; } - effect = PyCompile_OpcodeStackEffect(opcode, oparg); + effect = PyCompile_OpcodeStackEffect(opcode, oparg_int); if (effect == PY_INVALID_STACK_EFFECT) { PyErr_SetString(PyExc_ValueError, "invalid opcode or oparg"); diff --git a/Modules/_operator.c b/Modules/_operator.c index e8bef04f84af..8f524a6449b8 100644 --- a/Modules/_operator.c +++ b/Modules/_operator.c @@ -69,6 +69,7 @@ spami(truth , PyObject_IsTrue) spam2(op_add , PyNumber_Add) spam2(op_sub , PyNumber_Subtract) spam2(op_mul , PyNumber_Multiply) +spam2(op_matmul , PyNumber_MatrixMultiply) spam2(op_floordiv , PyNumber_FloorDivide) spam2(op_truediv , PyNumber_TrueDivide) spam2(op_mod , PyNumber_Remainder) @@ -86,6 +87,7 @@ spam2(op_or_ , PyNumber_Or) spam2(op_iadd , PyNumber_InPlaceAdd) spam2(op_isub , PyNumber_InPlaceSubtract) spam2(op_imul , PyNumber_InPlaceMultiply) +spam2(op_imatmul , PyNumber_InPlaceMatrixMultiply) spam2(op_ifloordiv , PyNumber_InPlaceFloorDivide) spam2(op_itruediv , PyNumber_InPlaceTrueDivide) spam2(op_imod , PyNumber_InPlaceRemainder) @@ -239,7 +241,7 @@ PyDoc_STRVAR(compare_digest__doc__, "Return 'a == b'. This function uses an approach designed to prevent\n" "timing analysis, making it appropriate for cryptography.\n" "a and b must both be of the same type: either str (ASCII only),\n" -"or any type that supports the buffer protocol (e.g. bytes).\n" +"or any bytes-like object.\n" "\n" "Note: If a and b are of different lengths, or if an error occurs,\n" "a timing attack could theoretically reveal information about the\n" @@ -277,7 +279,7 @@ compare_digest(PyObject *self, PyObject *args) Py_buffer view_a; Py_buffer view_b; - if ((PyObject_CheckBuffer(a) == 0) & (PyObject_CheckBuffer(b) == 0)) { + if (PyObject_CheckBuffer(a) == 0 && PyObject_CheckBuffer(b) == 0) { PyErr_Format(PyExc_TypeError, "unsupported operand types(s) or combination of types: " "'%.100s' and '%.100s'", @@ -343,6 +345,7 @@ spam2o(index, "index(a) -- Same as a.__index__()") spam2(add, "add(a, b) -- Same as a + b.") spam2(sub, "sub(a, b) -- Same as a - b.") spam2(mul, "mul(a, b) -- Same as a * b.") +spam2(matmul, "matmul(a, b) -- Same as a @ b.") spam2(floordiv, "floordiv(a, b) -- Same as a // b.") spam2(truediv, "truediv(a, b) -- Same as a / b.") spam2(mod, "mod(a, b) -- Same as a % b.") @@ -360,6 +363,7 @@ spam2(or_, "or_(a, b) -- Same as a | b.") spam2(iadd, "a = iadd(a, b) -- Same as a += b.") spam2(isub, "a = isub(a, b) -- Same as a -= b.") spam2(imul, "a = imul(a, b) -- Same as a *= b.") +spam2(imatmul, "a = imatmul(a, b) -- Same as a @= b.") spam2(ifloordiv, "a = ifloordiv(a, b) -- Same as a //= b.") spam2(itruediv, "a = itruediv(a, b) -- Same as a /= b") spam2(imod, "a = imod(a, b) -- Same as a %= b.") diff --git a/Modules/_pickle.c b/Modules/_pickle.c index c8afa8e47c3c..51e2f83ff8ff 100644 --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -4,29 +4,15 @@ PyDoc_STRVAR(pickle_module_doc, "Optimized C implementation for the Python pickle module."); -/*[clinic] +/*[clinic input] +output preset file module _pickle -class _pickle.Pickler -class _pickle.PicklerMemoProxy -class _pickle.Unpickler -class _pickle.UnpicklerMemoProxy -[clinic]*/ -/*[clinic checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ - -/*[python] -class PicklerObject_converter(self_converter): - type = "PicklerObject *" - -class PicklerMemoProxyObject_converter(self_converter): - type = "PicklerMemoProxyObject *" - -class UnpicklerObject_converter(self_converter): - type = "UnpicklerObject *" - -class UnpicklerMemoProxyObject_converter(self_converter): - type = "UnpicklerMemoProxyObject *" -[python]*/ -/*[python checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ +class _pickle.Pickler "PicklerObject *" "&Pickler_Type" +class _pickle.PicklerMemoProxy "PicklerMemoProxyObject *" "&PicklerMemoProxyType" +class _pickle.Unpickler "UnpicklerObject *" "&Unpickler_Type" +class _pickle.UnpicklerMemoProxy "UnpicklerMemoProxyObject *" "&UnpicklerMemoProxyType" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=11c45248a41dd3fc]*/ /* Bump this when new opcodes are added to the pickle protocol. */ enum { @@ -140,7 +126,7 @@ typedef struct { PyObject *PickleError; PyObject *PicklingError; PyObject *UnpicklingError; - + /* copyreg.dispatch_table, {type_object: pickling_function} */ PyObject *dispatch_table; @@ -389,7 +375,7 @@ static PyTypeObject Pdata_Type = { PyVarObject_HEAD_INIT(NULL, 0) "_pickle.Pdata", /*tp_name*/ sizeof(Pdata), /*tp_basicsize*/ - 0, /*tp_itemsize*/ + sizeof(PyObject *), /*tp_itemsize*/ (destructor)Pdata_dealloc, /*tp_dealloc*/ }; @@ -434,22 +420,22 @@ static int Pdata_grow(Pdata *self) { PyObject **data = self->data; - Py_ssize_t allocated = self->allocated; - Py_ssize_t new_allocated; + size_t allocated = (size_t)self->allocated; + size_t new_allocated; new_allocated = (allocated >> 3) + 6; /* check for integer overflow */ - if (new_allocated > PY_SSIZE_T_MAX - allocated) + if (new_allocated > (size_t)PY_SSIZE_T_MAX - allocated) goto nomemory; new_allocated += allocated; - if (new_allocated > (PY_SSIZE_T_MAX / sizeof(PyObject *))) + if (new_allocated > ((size_t)PY_SSIZE_T_MAX / sizeof(PyObject *))) goto nomemory; data = PyMem_REALLOC(data, new_allocated * sizeof(PyObject *)); if (data == NULL) goto nomemory; self->data = data; - self->allocated = new_allocated; + self->allocated = (Py_ssize_t)new_allocated; return 0; nomemory: @@ -609,12 +595,23 @@ typedef struct UnpicklerObject { the name of globals pickled by Python 2.x. */ } UnpicklerObject; +typedef struct { + PyObject_HEAD + PicklerObject *pickler; /* Pickler whose memo table we're proxying. */ +} PicklerMemoProxyObject; + +typedef struct { + PyObject_HEAD + UnpicklerObject *unpickler; +} UnpicklerMemoProxyObject; + /* Forward declarations */ static int save(PicklerObject *, PyObject *, int); static int save_reduce(PicklerObject *, PyObject *, PyObject *); static PyTypeObject Pickler_Type; static PyTypeObject Unpickler_Type; +#include "clinic/_pickle.c.h" /************************************************************************* A custom hashtable mapping void* to Python ints. This is used by the pickler @@ -853,7 +850,7 @@ _Pickler_ClearBuffer(PicklerObject *self) static void _write_size64(char *out, size_t value) { - int i; + size_t i; assert(sizeof(size_t) <= 8); @@ -1459,7 +1456,7 @@ memo_get(PicklerObject *self, PyObject *key) pdata[1] = (unsigned char)(*value & 0xff); len = 2; } - else if (*value <= 0xffffffffL) { + else if ((size_t)*value <= 0xffffffffUL) { pdata[0] = LONG_BINGET; pdata[1] = (unsigned char)(*value & 0xff); pdata[2] = (unsigned char)((*value >> 8) & 0xff); @@ -1516,7 +1513,7 @@ memo_put(PicklerObject *self, PyObject *obj) pdata[1] = (unsigned char)idx; len = 2; } - else if (idx <= 0xffffffffL) { + else if ((size_t)idx <= 0xffffffffUL) { pdata[0] = LONG_BINPUT; pdata[1] = (unsigned char)(idx & 0xff); pdata[2] = (unsigned char)((idx >> 8) & 0xff); @@ -1538,69 +1535,109 @@ memo_put(PicklerObject *self, PyObject *obj) } static PyObject * -getattribute(PyObject *obj, PyObject *name, int allow_qualname) { - PyObject *dotted_path; - Py_ssize_t i; +get_dotted_path(PyObject *obj, PyObject *name, int allow_qualname) { _Py_static_string(PyId_dot, "."); _Py_static_string(PyId_locals, ""); + PyObject *dotted_path; + Py_ssize_t i, n; dotted_path = PyUnicode_Split(name, _PyUnicode_FromId(&PyId_dot), -1); - if (dotted_path == NULL) { + if (dotted_path == NULL) return NULL; - } - assert(Py_SIZE(dotted_path) >= 1); - if (!allow_qualname && Py_SIZE(dotted_path) > 1) { - PyErr_Format(PyExc_AttributeError, - "Can't get qualified attribute %R on %R;" - "use protocols >= 4 to enable support", - name, obj); + n = PyList_GET_SIZE(dotted_path); + assert(n >= 1); + if (!allow_qualname && n > 1) { + if (obj == NULL) + PyErr_Format(PyExc_AttributeError, + "Can't pickle qualified object %R; " + "use protocols >= 4 to enable support", + name); + else + PyErr_Format(PyExc_AttributeError, + "Can't pickle qualified attribute %R on %R; " + "use protocols >= 4 to enable support", + name, obj); Py_DECREF(dotted_path); return NULL; } - Py_INCREF(obj); - for (i = 0; i < Py_SIZE(dotted_path); i++) { + for (i = 0; i < n; i++) { PyObject *subpath = PyList_GET_ITEM(dotted_path, i); - PyObject *tmp; 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) { - PyErr_Format(PyExc_AttributeError, - "Can't get local attribute %R on %R", name, obj); + if (obj == NULL) + PyErr_Format(PyExc_AttributeError, + "Can't pickle local object %R", name); + else + PyErr_Format(PyExc_AttributeError, + "Can't pickle local attribute %R on %R", name, obj); Py_DECREF(dotted_path); - Py_DECREF(obj); return NULL; } - tmp = PyObject_GetAttr(obj, subpath); + } + return dotted_path; +} + +static PyObject * +get_deep_attribute(PyObject *obj, PyObject *names) +{ + Py_ssize_t i, n; + + assert(PyList_CheckExact(names)); + Py_INCREF(obj); + n = PyList_GET_SIZE(names); + for (i = 0; i < n; i++) { + PyObject *name = PyList_GET_ITEM(names, i); + PyObject *tmp; + tmp = PyObject_GetAttr(obj, name); Py_DECREF(obj); - if (tmp == NULL) { - if (PyErr_ExceptionMatches(PyExc_AttributeError)) { - PyErr_Clear(); - PyErr_Format(PyExc_AttributeError, - "Can't get attribute %R on %R", name, obj); - } - Py_DECREF(dotted_path); + if (tmp == NULL) return NULL; - } obj = tmp; } - Py_DECREF(dotted_path); return obj; } +static void +reformat_attribute_error(PyObject *obj, PyObject *name) +{ + if (PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); + PyErr_Format(PyExc_AttributeError, + "Can't get attribute %R on %R", name, obj); + } +} + + +static PyObject * +getattribute(PyObject *obj, PyObject *name, int allow_qualname) +{ + PyObject *dotted_path, *attr; + + dotted_path = get_dotted_path(obj, name, allow_qualname); + if (dotted_path == NULL) + return NULL; + attr = get_deep_attribute(obj, dotted_path); + Py_DECREF(dotted_path); + if (attr == NULL) + reformat_attribute_error(obj, name); + return attr; +} + static PyObject * whichmodule(PyObject *global, PyObject *global_name, int allow_qualname) { PyObject *module_name; PyObject *modules_dict; PyObject *module; - PyObject *obj; - Py_ssize_t i, j; + Py_ssize_t i; _Py_IDENTIFIER(__module__); _Py_IDENTIFIER(modules); _Py_IDENTIFIER(__main__); + PyObject *dotted_path; module_name = _PyObject_GetAttrId(global, &PyId___module__); @@ -1619,43 +1656,49 @@ whichmodule(PyObject *global, PyObject *global_name, int allow_qualname) } assert(module_name == NULL); + /* Fallback on walking sys.modules */ modules_dict = _PySys_GetObjectId(&PyId_modules); if (modules_dict == NULL) { PyErr_SetString(PyExc_RuntimeError, "unable to get sys.modules"); return NULL; } + dotted_path = get_dotted_path(NULL, global_name, allow_qualname); + if (dotted_path == NULL) + return NULL; + i = 0; - while ((j = PyDict_Next(modules_dict, &i, &module_name, &module))) { - PyObject *result = PyUnicode_RichCompare( - module_name, _PyUnicode_FromId(&PyId___main__), Py_EQ); - int is_equal = (result == Py_True); - assert(PyBool_Check(result)); - Py_DECREF(result); - if (is_equal) + while (PyDict_Next(modules_dict, &i, &module_name, &module)) { + PyObject *candidate; + if (PyUnicode_Check(module_name) && + !PyUnicode_CompareWithASCIIString(module_name, "__main__")) continue; if (module == Py_None) continue; - obj = getattribute(module, global_name, allow_qualname); - if (obj == NULL) { - if (!PyErr_ExceptionMatches(PyExc_AttributeError)) + candidate = get_deep_attribute(module, dotted_path); + if (candidate == NULL) { + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) { + Py_DECREF(dotted_path); return NULL; + } PyErr_Clear(); continue; } - if (obj == global) { - Py_DECREF(obj); + if (candidate == global) { Py_INCREF(module_name); + Py_DECREF(dotted_path); + Py_DECREF(candidate); return module_name; } - Py_DECREF(obj); + Py_DECREF(candidate); } /* If no module is found, use __main__. */ module_name = _PyUnicode_FromId(&PyId___main__); Py_INCREF(module_name); + Py_DECREF(dotted_path); return module_name; } @@ -1770,7 +1813,7 @@ save_long(PicklerObject *self, PyObject *obj) else if (self->bin && (sizeof(long) <= 4 || (val <= 0x7fffffffL && val >= (-0x7fffffffL - 1)))) { - /* result fits in a signed 4-byte integer. + /* result fits in a signed 4-byte integer. Note: we can't use -0x80000000L in the above condition because some compilers (e.g., MSVC) will promote 0x80000000L to an unsigned type @@ -1936,7 +1979,7 @@ save_float(PicklerObject *self, PyObject *obj) if (_Pickler_Write(self, &op, 1) < 0) goto done; - buf = PyOS_double_to_string(x, 'g', 17, 0, NULL); + buf = PyOS_double_to_string(x, 'r', 0, Py_DTSF_ADD_DOT_0, NULL); if (!buf) { PyErr_NoMemory(); goto done; @@ -2016,7 +2059,7 @@ save_bytes(PicklerObject *self, PyObject *obj) header[1] = (unsigned char)size; len = 2; } - else if (size <= 0xffffffffL) { + else if ((size_t)size <= 0xffffffffUL) { header[0] = BINBYTES; header[1] = (unsigned char)(size & 0xff); header[2] = (unsigned char)((size >> 8) & 0xff); @@ -2027,7 +2070,7 @@ save_bytes(PicklerObject *self, PyObject *obj) else if (self->proto >= 4) { header[0] = BINBYTES8; _write_size64(header + 1, size); - len = 8; + len = 9; } else { PyErr_SetString(PyExc_OverflowError, @@ -2053,9 +2096,10 @@ save_bytes(PicklerObject *self, PyObject *obj) static PyObject * raw_unicode_escape(PyObject *obj) { - PyObject *repr, *result; + PyObject *repr; char *p; - Py_ssize_t i, size, expandsize; + Py_ssize_t i, size; + size_t expandsize; void *data; unsigned int kind; @@ -2070,15 +2114,16 @@ raw_unicode_escape(PyObject *obj) else expandsize = 6; - if (size > PY_SSIZE_T_MAX / expandsize) + if ((size_t)size > (size_t)PY_SSIZE_T_MAX / expandsize) return PyErr_NoMemory(); - repr = PyByteArray_FromStringAndSize(NULL, expandsize * size); + repr = PyBytes_FromStringAndSize(NULL, expandsize * size); if (repr == NULL) return NULL; if (size == 0) - goto done; + return repr; + assert(Py_REFCNT(repr) == 1); - p = PyByteArray_AS_STRING(repr); + p = PyBytes_AS_STRING(repr); for (i=0; i < size; i++) { Py_UCS4 ch = PyUnicode_READ(kind, data, i); /* Map 32-bit characters to '\Uxxxxxxxx' */ @@ -2107,12 +2152,10 @@ raw_unicode_escape(PyObject *obj) else *p++ = (char) ch; } - size = p - PyByteArray_AS_STRING(repr); - -done: - result = PyBytes_FromStringAndSize(PyByteArray_AS_STRING(repr), size); - Py_DECREF(repr); - return result; + size = p - PyBytes_AS_STRING(repr); + if (_PyBytes_Resize(&repr, size) < 0) + return NULL; + return repr; } static int @@ -2121,12 +2164,13 @@ write_utf8(PicklerObject *self, char *data, Py_ssize_t size) char header[9]; Py_ssize_t len; + assert(size >= 0); if (size <= 0xff && self->proto >= 4) { header[0] = SHORT_BINUNICODE; header[1] = (unsigned char)(size & 0xff); len = 2; } - else if (size <= 0xffffffffUL) { + else if ((size_t)size <= 0xffffffffUL) { header[0] = BINUNICODE; header[1] = (unsigned char)(size & 0xff); header[2] = (unsigned char)((size >> 8) & 0xff); @@ -3462,20 +3506,19 @@ save_reduce(PicklerObject *self, PyObject *args, PyObject *obj) } PyErr_Clear(); } - else if (self->proto >= 4) { - _Py_IDENTIFIER(__newobj_ex__); - use_newobj_ex = PyUnicode_Check(name) && - PyUnicode_Compare( - name, _PyUnicode_FromId(&PyId___newobj_ex__)) == 0; - Py_DECREF(name); - } - else { - _Py_IDENTIFIER(__newobj__); - use_newobj = PyUnicode_Check(name) && - PyUnicode_Compare( - name, _PyUnicode_FromId(&PyId___newobj__)) == 0; - Py_DECREF(name); + else if (PyUnicode_Check(name)) { + if (self->proto >= 4) { + _Py_IDENTIFIER(__newobj_ex__); + use_newobj_ex = PyUnicode_Compare( + name, _PyUnicode_FromId(&PyId___newobj_ex__)) == 0; + } + if (!use_newobj_ex) { + _Py_IDENTIFIER(__newobj__); + use_newobj = PyUnicode_Compare( + name, _PyUnicode_FromId(&PyId___newobj__)) == 0; + } } + Py_XDECREF(name); } if (use_newobj_ex) { @@ -3492,21 +3535,21 @@ save_reduce(PicklerObject *self, PyObject *args, PyObject *obj) cls = PyTuple_GET_ITEM(argtup, 0); if (!PyType_Check(cls)) { - PyErr_Format(st->PicklingError, + PyErr_Format(st->PicklingError, "first item from NEWOBJ_EX argument tuple must " "be a class, not %.200s", Py_TYPE(cls)->tp_name); return -1; } args = PyTuple_GET_ITEM(argtup, 1); if (!PyTuple_Check(args)) { - PyErr_Format(st->PicklingError, + PyErr_Format(st->PicklingError, "second item from NEWOBJ_EX argument tuple must " "be a tuple, not %.200s", Py_TYPE(args)->tp_name); return -1; } kwargs = PyTuple_GET_ITEM(argtup, 2); if (!PyDict_Check(kwargs)) { - PyErr_Format(st->PicklingError, + PyErr_Format(st->PicklingError, "third item from NEWOBJ_EX argument tuple must " "be a dict, not %.200s", Py_TYPE(kwargs)->tp_name); return -1; @@ -3874,35 +3917,21 @@ dump(PicklerObject *self, PyObject *obj) return 0; } -/*[clinic] +/*[clinic input] _pickle.Pickler.clear_memo - self: PicklerObject - Clears the pickler's "memo". The memo is the data structure that remembers which objects the pickler has already seen, so that shared or recursive objects are pickled by reference and not by value. This method is useful when re-using picklers. -[clinic]*/ - -PyDoc_STRVAR(_pickle_Pickler_clear_memo__doc__, -"clear_memo()\n" -"Clears the pickler\'s \"memo\".\n" -"\n" -"The memo is the data structure that remembers which objects the\n" -"pickler has already seen, so that shared or recursive objects are\n" -"pickled by reference and not by value. This method is useful when\n" -"re-using picklers."); - -#define _PICKLE_PICKLER_CLEAR_MEMO_METHODDEF \ - {"clear_memo", (PyCFunction)_pickle_Pickler_clear_memo, METH_NOARGS, _pickle_Pickler_clear_memo__doc__}, +[clinic start generated code]*/ static PyObject * -_pickle_Pickler_clear_memo(PicklerObject *self) -/*[clinic checksum: 9c32be7e7a17ff82a81aae409d0d4f469033a5b2]*/ +_pickle_Pickler_clear_memo_impl(PicklerObject *self) +/*[clinic end generated code: output=8665c8658aaa094b input=01bdad52f3d93e56]*/ { if (self->memo) PyMemoTable_Clear(self->memo); @@ -3910,27 +3939,19 @@ _pickle_Pickler_clear_memo(PicklerObject *self) Py_RETURN_NONE; } -/*[clinic] +/*[clinic input] _pickle.Pickler.dump - self: PicklerObject obj: object / Write a pickled representation of the given object to the open file. -[clinic]*/ - -PyDoc_STRVAR(_pickle_Pickler_dump__doc__, -"dump(obj)\n" -"Write a pickled representation of the given object to the open file."); - -#define _PICKLE_PICKLER_DUMP_METHODDEF \ - {"dump", (PyCFunction)_pickle_Pickler_dump, METH_O, _pickle_Pickler_dump__doc__}, +[clinic start generated code]*/ static PyObject * _pickle_Pickler_dump(PicklerObject *self, PyObject *obj) -/*[clinic checksum: b72a69ec98737fabf66dae7c5a3210178bdbd3e6]*/ +/*[clinic end generated code: output=87ecad1261e02ac7 input=552eb1c0f52260d9]*/ { /* Check whether the Pickler was initialized correctly (issue3664). Developers often forget to call __init__() in their subclasses, which @@ -3955,9 +3976,37 @@ _pickle_Pickler_dump(PicklerObject *self, PyObject *obj) Py_RETURN_NONE; } +/*[clinic input] + +_pickle.Pickler.__sizeof__ -> Py_ssize_t + +Returns size in memory, in bytes. +[clinic start generated code]*/ + +static Py_ssize_t +_pickle_Pickler___sizeof___impl(PicklerObject *self) +/*[clinic end generated code: output=106edb3123f332e1 input=8cbbec9bd5540d42]*/ +{ + Py_ssize_t res, s; + + res = sizeof(PicklerObject); + if (self->memo != NULL) { + res += sizeof(PyMemoTable); + res += self->memo->mt_allocated * sizeof(PyMemoEntry); + } + if (self->output_buffer != NULL) { + s = _PySys_GetSizeOf(self->output_buffer); + if (s == -1) + return -1; + res += s; + } + return res; +} + static struct PyMethodDef Pickler_methods[] = { _PICKLE_PICKLER_DUMP_METHODDEF _PICKLE_PICKLER_CLEAR_MEMO_METHODDEF + _PICKLE_PICKLER___SIZEOF___METHODDEF {NULL, NULL} /* sentinel */ }; @@ -4005,88 +4054,37 @@ Pickler_clear(PicklerObject *self) } -/*[clinic] +/*[clinic input] _pickle.Pickler.__init__ - self: PicklerObject file: object protocol: object = NULL fix_imports: bool = True This takes a binary file for writing a pickle data stream. -The optional protocol argument tells the pickler to use the -given protocol; supported protocols are 0, 1, 2, 3 and 4. The -default protocol is 3; a backward-incompatible protocol designed for -Python 3. +The optional *protocol* argument tells the pickler to use the given +protocol; supported protocols are 0, 1, 2, 3 and 4. The default +protocol is 3; a backward-incompatible protocol designed for Python 3. -Specifying a negative protocol version selects the highest -protocol version supported. The higher the protocol used, the -more recent the version of Python needed to read the pickle -produced. +Specifying a negative protocol version selects the highest protocol +version supported. The higher the protocol used, the more recent the +version of Python needed to read the pickle produced. -The file argument must have a write() method that accepts a single +The *file* argument must have a write() method that accepts a single bytes argument. It can thus be a file object opened for binary -writing, a io.BytesIO instance, or any other custom object that -meets this interface. - -If fix_imports is True and protocol is less than 3, pickle will try to -map the new Python 3 names to the old module names used in Python 2, -so that the pickle data stream is readable with Python 2. -[clinic]*/ - -PyDoc_STRVAR(_pickle_Pickler___init____doc__, -"__init__(file, protocol=None, fix_imports=True)\n" -"This takes a binary file for writing a pickle data stream.\n" -"\n" -"The optional protocol argument tells the pickler to use the\n" -"given protocol; supported protocols are 0, 1, 2, 3 and 4. The\n" -"default protocol is 3; a backward-incompatible protocol designed for\n" -"Python 3.\n" -"\n" -"Specifying a negative protocol version selects the highest\n" -"protocol version supported. The higher the protocol used, the\n" -"more recent the version of Python needed to read the pickle\n" -"produced.\n" -"\n" -"The file argument must have a write() method that accepts a single\n" -"bytes argument. It can thus be a file object opened for binary\n" -"writing, a io.BytesIO instance, or any other custom object that\n" -"meets this interface.\n" -"\n" -"If fix_imports is True and protocol is less than 3, pickle will try to\n" -"map the new Python 3 names to the old module names used in Python 2,\n" -"so that the pickle data stream is readable with Python 2."); - -#define _PICKLE_PICKLER___INIT___METHODDEF \ - {"__init__", (PyCFunction)_pickle_Pickler___init__, METH_VARARGS|METH_KEYWORDS, _pickle_Pickler___init____doc__}, +writing, a io.BytesIO instance, or any other custom object that meets +this interface. -static PyObject * -_pickle_Pickler___init___impl(PicklerObject *self, PyObject *file, PyObject *protocol, int fix_imports); - -static PyObject * -_pickle_Pickler___init__(PyObject *self, PyObject *args, PyObject *kwargs) -{ - PyObject *return_value = NULL; - static char *_keywords[] = {"file", "protocol", "fix_imports", NULL}; - PyObject *file; - PyObject *protocol = NULL; - int fix_imports = 1; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, - "O|Op:__init__", _keywords, - &file, &protocol, &fix_imports)) - goto exit; - return_value = _pickle_Pickler___init___impl((PicklerObject *)self, file, protocol, fix_imports); - -exit: - return return_value; -} +If *fix_imports* is True and protocol is less than 3, pickle will try +to map the new Python 3 names to the old module names used in Python +2, so that the pickle data stream is readable with Python 2. +[clinic start generated code]*/ -static PyObject * +static int _pickle_Pickler___init___impl(PicklerObject *self, PyObject *file, PyObject *protocol, int fix_imports) -/*[clinic checksum: c99ff417bd703a74affc4b708167e56e135e8969]*/ +/*[clinic end generated code: output=56e229f3b1f4332f input=b8cdeb7e3f5ee674]*/ { _Py_IDENTIFIER(persistent_id); _Py_IDENTIFIER(dispatch_table); @@ -4096,16 +4094,16 @@ _pickle_Pickler___init___impl(PicklerObject *self, PyObject *file, PyObject *pro (void)Pickler_clear(self); if (_Pickler_SetProtocol(self, protocol, fix_imports) < 0) - return NULL; + return -1; if (_Pickler_SetOutputStream(self, file) < 0) - return NULL; + return -1; /* memo and output_buffer may have already been created in _Pickler_New */ if (self->memo == NULL) { self->memo = PyMemoTable_New(); if (self->memo == NULL) - return NULL; + return -1; } self->output_len = 0; if (self->output_buffer == NULL) { @@ -4113,7 +4111,7 @@ _pickle_Pickler___init___impl(PicklerObject *self, PyObject *file, PyObject *pro self->output_buffer = PyBytes_FromStringAndSize(NULL, self->max_output_len); if (self->output_buffer == NULL) - return NULL; + return -1; } self->fast = 0; @@ -4124,31 +4122,20 @@ _pickle_Pickler___init___impl(PicklerObject *self, PyObject *file, PyObject *pro self->pers_func = _PyObject_GetAttrId((PyObject *)self, &PyId_persistent_id); if (self->pers_func == NULL) - return NULL; + return -1; } self->dispatch_table = NULL; if (_PyObject_HasAttrId((PyObject *)self, &PyId_dispatch_table)) { self->dispatch_table = _PyObject_GetAttrId((PyObject *)self, &PyId_dispatch_table); if (self->dispatch_table == NULL) - return NULL; + return -1; } - Py_RETURN_NONE; -} - -/* Wrap the Clinic generated signature to slot it in tp_init. */ -static int -Pickler_init(PyObject *self, PyObject *args, PyObject *kwargs) -{ - PyObject *result = _pickle_Pickler___init__(self, args, kwargs); - if (result == NULL) { - return -1; - } - Py_DECREF(result); return 0; } + /* Define a proxy object for the Pickler's internal memo object. This is to * avoid breaking code like: * pickler.memo.clear() @@ -4159,53 +4146,30 @@ Pickler_init(PyObject *self, PyObject *args, PyObject *kwargs) * intentional, as these should be treated as black-box implementation details. */ -typedef struct { - PyObject_HEAD - PicklerObject *pickler; /* Pickler whose memo table we're proxying. */ -} PicklerMemoProxyObject; - -/*[clinic] +/*[clinic input] _pickle.PicklerMemoProxy.clear - self: PicklerMemoProxyObject - Remove all items from memo. -[clinic]*/ - -PyDoc_STRVAR(_pickle_PicklerMemoProxy_clear__doc__, -"clear()\n" -"Remove all items from memo."); - -#define _PICKLE_PICKLERMEMOPROXY_CLEAR_METHODDEF \ - {"clear", (PyCFunction)_pickle_PicklerMemoProxy_clear, METH_NOARGS, _pickle_PicklerMemoProxy_clear__doc__}, +[clinic start generated code]*/ static PyObject * -_pickle_PicklerMemoProxy_clear(PicklerMemoProxyObject *self) -/*[clinic checksum: 507f13938721992e175a3e58b5ad02620045a1cc]*/ +_pickle_PicklerMemoProxy_clear_impl(PicklerMemoProxyObject *self) +/*[clinic end generated code: output=5fb9370d48ae8b05 input=ccc186dacd0f1405]*/ { if (self->pickler->memo) PyMemoTable_Clear(self->pickler->memo); Py_RETURN_NONE; } -/*[clinic] +/*[clinic input] _pickle.PicklerMemoProxy.copy - self: PicklerMemoProxyObject - Copy the memo to a new object. -[clinic]*/ - -PyDoc_STRVAR(_pickle_PicklerMemoProxy_copy__doc__, -"copy()\n" -"Copy the memo to a new object."); - -#define _PICKLE_PICKLERMEMOPROXY_COPY_METHODDEF \ - {"copy", (PyCFunction)_pickle_PicklerMemoProxy_copy, METH_NOARGS, _pickle_PicklerMemoProxy_copy__doc__}, +[clinic start generated code]*/ static PyObject * -_pickle_PicklerMemoProxy_copy(PicklerMemoProxyObject *self) -/*[clinic checksum: 73a5117ab354290ebdbe07bd0bf7232d0936a69d]*/ +_pickle_PicklerMemoProxy_copy_impl(PicklerMemoProxyObject *self) +/*[clinic end generated code: output=bb83a919d29225ef input=b73043485ac30b36]*/ { Py_ssize_t i; PyMemoTable *memo; @@ -4242,27 +4206,18 @@ _pickle_PicklerMemoProxy_copy(PicklerMemoProxyObject *self) return NULL; } -/*[clinic] +/*[clinic input] _pickle.PicklerMemoProxy.__reduce__ - self: PicklerMemoProxyObject - Implement pickle support. -[clinic]*/ - -PyDoc_STRVAR(_pickle_PicklerMemoProxy___reduce____doc__, -"__reduce__()\n" -"Implement pickle support."); - -#define _PICKLE_PICKLERMEMOPROXY___REDUCE___METHODDEF \ - {"__reduce__", (PyCFunction)_pickle_PicklerMemoProxy___reduce__, METH_NOARGS, _pickle_PicklerMemoProxy___reduce____doc__}, +[clinic start generated code]*/ static PyObject * -_pickle_PicklerMemoProxy___reduce__(PicklerMemoProxyObject *self) -/*[clinic checksum: 40f0bf7a9b161e77130674f0481bda0a0184dcce]*/ +_pickle_PicklerMemoProxy___reduce___impl(PicklerMemoProxyObject *self) +/*[clinic end generated code: output=bebba1168863ab1d input=2f7c540e24b7aae4]*/ { PyObject *reduce_value, *dict_args; - PyObject *contents = _pickle_PicklerMemoProxy_copy(self); + PyObject *contents = _pickle_PicklerMemoProxy_copy_impl(self); if (contents == NULL) return NULL; @@ -4514,7 +4469,7 @@ static PyTypeObject Pickler_Type = { 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ 0, /*tp_dictoffset*/ - Pickler_init, /*tp_init*/ + _pickle_Pickler___init__, /*tp_init*/ PyType_GenericAlloc, /*tp_alloc*/ PyType_GenericNew, /*tp_new*/ PyObject_GC_Del, /*tp_free*/ @@ -4624,10 +4579,10 @@ static Py_ssize_t calc_binsize(char *bytes, int nbytes) { unsigned char *s = (unsigned char *)bytes; - int i; + Py_ssize_t i; size_t x = 0; - for (i = 0; i < nbytes && i < sizeof(size_t); i++) { + for (i = 0; i < nbytes && (size_t)i < sizeof(size_t); i++) { x |= (size_t) s[i] << (8 * i); } @@ -4646,7 +4601,7 @@ static long calc_binint(char *bytes, int nbytes) { unsigned char *s = (unsigned char *)bytes; - int i; + Py_ssize_t i; long x = 0; for (i = 0; i < nbytes; i++) { @@ -4831,7 +4786,7 @@ static int load_string(UnpicklerObject *self) { PyObject *bytes; - PyObject *str = NULL; + PyObject *obj; Py_ssize_t len; char *s, *p; @@ -4857,19 +4812,28 @@ load_string(UnpicklerObject *self) bytes = PyBytes_DecodeEscape(p, len, NULL, 0, NULL); if (bytes == NULL) return -1; - str = PyUnicode_FromEncodedObject(bytes, self->encoding, self->errors); - Py_DECREF(bytes); - if (str == NULL) - return -1; - PDATA_PUSH(self->stack, str, -1); + /* Leave the Python 2.x strings as bytes if the *encoding* given to the + Unpickler was 'bytes'. Otherwise, convert them to unicode. */ + if (strcmp(self->encoding, "bytes") == 0) { + obj = bytes; + } + else { + obj = PyUnicode_FromEncodedObject(bytes, self->encoding, self->errors); + Py_DECREF(bytes); + if (obj == NULL) { + return -1; + } + } + + PDATA_PUSH(self->stack, obj, -1); return 0; } static int -load_counted_binbytes(UnpicklerObject *self, int nbytes) +load_counted_binstring(UnpicklerObject *self, int nbytes) { - PyObject *bytes; + PyObject *obj; Py_ssize_t size; char *s; @@ -4878,8 +4842,9 @@ load_counted_binbytes(UnpicklerObject *self, int nbytes) size = calc_binsize(s, nbytes); if (size < 0) { - PyErr_Format(PyExc_OverflowError, - "BINBYTES exceeds system's maximum size of %zd bytes", + PickleState *st = _Pickle_GetGlobalState(); + PyErr_Format(st->UnpicklingError, + "BINSTRING exceeds system's maximum size of %zd bytes", PY_SSIZE_T_MAX); return -1; } @@ -4887,18 +4852,26 @@ load_counted_binbytes(UnpicklerObject *self, int nbytes) if (_Unpickler_Read(self, &s, size) < 0) return -1; - bytes = PyBytes_FromStringAndSize(s, size); - if (bytes == NULL) + /* Convert Python 2.x strings to bytes if the *encoding* given to the + Unpickler was 'bytes'. Otherwise, convert them to unicode. */ + if (strcmp(self->encoding, "bytes") == 0) { + obj = PyBytes_FromStringAndSize(s, size); + } + else { + obj = PyUnicode_Decode(s, size, self->encoding, self->errors); + } + if (obj == NULL) { return -1; + } - PDATA_PUSH(self->stack, bytes, -1); + PDATA_PUSH(self->stack, obj, -1); return 0; } static int -load_counted_binstring(UnpicklerObject *self, int nbytes) +load_counted_binbytes(UnpicklerObject *self, int nbytes) { - PyObject *str; + PyObject *bytes; Py_ssize_t size; char *s; @@ -4907,21 +4880,20 @@ load_counted_binstring(UnpicklerObject *self, int nbytes) size = calc_binsize(s, nbytes); if (size < 0) { - PickleState *st = _Pickle_GetGlobalState(); - PyErr_Format(st->UnpicklingError, - "BINSTRING exceeds system's maximum size of %zd bytes", + PyErr_Format(PyExc_OverflowError, + "BINBYTES exceeds system's maximum size of %zd bytes", PY_SSIZE_T_MAX); return -1; } if (_Unpickler_Read(self, &s, size) < 0) return -1; - /* Convert Python 2.x strings to unicode. */ - str = PyUnicode_Decode(s, size, self->encoding, self->errors); - if (str == NULL) + + bytes = PyBytes_FromStringAndSize(s, size); + if (bytes == NULL) return -1; - PDATA_PUSH(self->stack, str, -1); + PDATA_PUSH(self->stack, bytes, -1); return 0; } @@ -5283,12 +5255,12 @@ load_newobj_ex(UnpicklerObject *self) Py_DECREF(args); return -1; } - + if (!PyType_Check(cls)) { Py_DECREF(kwargs); Py_DECREF(args); Py_DECREF(cls); - PyErr_Format(st->UnpicklingError, + PyErr_Format(st->UnpicklingError, "NEWOBJ_EX class argument must be a type, not %.200s", Py_TYPE(cls)->tp_name); return -1; @@ -6139,7 +6111,7 @@ static PyObject * load(UnpicklerObject *self) { PyObject *value = NULL; - char *s; + char *s = NULL; self->num_marks = 0; self->proto = 0; @@ -6252,31 +6224,20 @@ load(UnpicklerObject *self) return value; } -/*[clinic] +/*[clinic input] _pickle.Unpickler.load Load a pickle. -Read a pickled object representation from the open file object given in -the constructor, and return the reconstituted object hierarchy specified -therein. -[clinic]*/ - -PyDoc_STRVAR(_pickle_Unpickler_load__doc__, -"load()\n" -"Load a pickle.\n" -"\n" -"Read a pickled object representation from the open file object given in\n" -"the constructor, and return the reconstituted object hierarchy specified\n" -"therein."); - -#define _PICKLE_UNPICKLER_LOAD_METHODDEF \ - {"load", (PyCFunction)_pickle_Unpickler_load, METH_NOARGS, _pickle_Unpickler_load__doc__}, +Read a pickled object representation from the open file object given +in the constructor, and return the reconstituted object hierarchy +specified therein. +[clinic start generated code]*/ static PyObject * -_pickle_Unpickler_load(PyObject *self) -/*[clinic checksum: 9a30ba4e4d9221d4dcd705e1471ab11b2c9e3ac6]*/ +_pickle_Unpickler_load_impl(UnpicklerObject *self) +/*[clinic end generated code: output=fdcc488aad675b14 input=acbb91a42fa9b7b9]*/ { UnpicklerObject *unpickler = (UnpicklerObject*)self; @@ -6299,60 +6260,27 @@ _pickle_Unpickler_load(PyObject *self) function is used for loading any global (i.e., functions), not just classes. The name is kept only for backward compatibility. */ -/*[clinic] +/*[clinic input] _pickle.Unpickler.find_class - self: UnpicklerObject module_name: object global_name: object / Return an object from a specified module. -If necessary, the module will be imported. Subclasses may override this -method (e.g. to restrict unpickling of arbitrary classes and functions). +If necessary, the module will be imported. Subclasses may override +this method (e.g. to restrict unpickling of arbitrary classes and +functions). This method is called whenever a class or a function object is needed. Both arguments passed are str objects. -[clinic]*/ - -PyDoc_STRVAR(_pickle_Unpickler_find_class__doc__, -"find_class(module_name, global_name)\n" -"Return an object from a specified module.\n" -"\n" -"If necessary, the module will be imported. Subclasses may override this\n" -"method (e.g. to restrict unpickling of arbitrary classes and functions).\n" -"\n" -"This method is called whenever a class or a function object is\n" -"needed. Both arguments passed are str objects."); - -#define _PICKLE_UNPICKLER_FIND_CLASS_METHODDEF \ - {"find_class", (PyCFunction)_pickle_Unpickler_find_class, METH_VARARGS, _pickle_Unpickler_find_class__doc__}, - -static PyObject * -_pickle_Unpickler_find_class_impl(UnpicklerObject *self, PyObject *module_name, PyObject *global_name); - -static PyObject * -_pickle_Unpickler_find_class(PyObject *self, PyObject *args) -{ - PyObject *return_value = NULL; - PyObject *module_name; - PyObject *global_name; - - if (!PyArg_ParseTuple(args, - "OO:find_class", - &module_name, &global_name)) - goto exit; - return_value = _pickle_Unpickler_find_class_impl((UnpicklerObject *)self, module_name, global_name); - -exit: - return return_value; -} +[clinic start generated code]*/ static PyObject * _pickle_Unpickler_find_class_impl(UnpicklerObject *self, PyObject *module_name, PyObject *global_name) -/*[clinic checksum: b7d05d4dd8adc698e5780c1ac2be0f5062d33915]*/ +/*[clinic end generated code: output=64c77437e088e188 input=e2e6a865de093ef4]*/ { PyObject *global; PyObject *modules_dict; @@ -6435,9 +6363,37 @@ _pickle_Unpickler_find_class_impl(UnpicklerObject *self, PyObject *module_name, return global; } +/*[clinic input] + +_pickle.Unpickler.__sizeof__ -> Py_ssize_t + +Returns size in memory, in bytes. +[clinic start generated code]*/ + +static Py_ssize_t +_pickle_Unpickler___sizeof___impl(UnpicklerObject *self) +/*[clinic end generated code: output=119d9d03ad4c7651 input=13333471fdeedf5e]*/ +{ + Py_ssize_t res; + + res = sizeof(UnpicklerObject); + if (self->memo != NULL) + res += self->memo_size * sizeof(PyObject *); + if (self->marks != NULL) + res += self->marks_size * sizeof(Py_ssize_t); + if (self->input_line != NULL) + res += strlen(self->input_line) + 1; + if (self->encoding != NULL) + res += strlen(self->encoding) + 1; + if (self->errors != NULL) + res += strlen(self->errors) + 1; + return res; +} + static struct PyMethodDef Unpickler_methods[] = { _PICKLE_UNPICKLER_LOAD_METHODDEF _PICKLE_UNPICKLER_FIND_CLASS_METHODDEF + _PICKLE_UNPICKLER___SIZEOF___METHODDEF {NULL, NULL} /* sentinel */ }; @@ -6501,11 +6457,10 @@ Unpickler_clear(UnpicklerObject *self) return 0; } -/*[clinic] +/*[clinic input] _pickle.Unpickler.__init__ - self: UnpicklerObject file: object * fix_imports: bool = True @@ -6515,76 +6470,28 @@ _pickle.Unpickler.__init__ This takes a binary file for reading a pickle data stream. The protocol version of the pickle is detected automatically, so no -proto argument is needed. +protocol argument is needed. Bytes past the pickled object's +representation are ignored. -The file-like object must have two methods, a read() method -that takes an integer argument, and a readline() method that -requires no arguments. Both methods should return bytes. -Thus file-like object can be a binary file object opened for -reading, a BytesIO object, or any other custom object that -meets this interface. +The argument *file* must have two methods, a read() method that takes +an integer argument, and a readline() method that requires no +arguments. Both methods should return bytes. Thus *file* can be a +binary file object opened for reading, a io.BytesIO object, or any +other custom object that meets this interface. Optional keyword arguments are *fix_imports*, *encoding* and *errors*, which are used to control compatiblity support for pickle stream -generated by Python 2.x. If *fix_imports* is True, pickle will try to -map the old Python 2.x names to the new names used in Python 3.x. The +generated by Python 2. If *fix_imports* is True, pickle will try to +map the old Python 2 names to the new names used in Python 3. The *encoding* and *errors* tell pickle how to decode 8-bit string -instances pickled by Python 2.x; these default to 'ASCII' and -'strict', respectively. - -[clinic]*/ - -PyDoc_STRVAR(_pickle_Unpickler___init____doc__, -"__init__(file, *, fix_imports=True, encoding=\'ASCII\', errors=\'strict\')\n" -"This takes a binary file for reading a pickle data stream.\n" -"\n" -"The protocol version of the pickle is detected automatically, so no\n" -"proto argument is needed.\n" -"\n" -"The file-like object must have two methods, a read() method\n" -"that takes an integer argument, and a readline() method that\n" -"requires no arguments. Both methods should return bytes.\n" -"Thus file-like object can be a binary file object opened for\n" -"reading, a BytesIO object, or any other custom object that\n" -"meets this interface.\n" -"\n" -"Optional keyword arguments are *fix_imports*, *encoding* and *errors*,\n" -"which are used to control compatiblity support for pickle stream\n" -"generated by Python 2.x. If *fix_imports* is True, pickle will try to\n" -"map the old Python 2.x names to the new names used in Python 3.x. The\n" -"*encoding* and *errors* tell pickle how to decode 8-bit string\n" -"instances pickled by Python 2.x; these default to \'ASCII\' and\n" -"\'strict\', respectively."); - -#define _PICKLE_UNPICKLER___INIT___METHODDEF \ - {"__init__", (PyCFunction)_pickle_Unpickler___init__, METH_VARARGS|METH_KEYWORDS, _pickle_Unpickler___init____doc__}, - -static PyObject * -_pickle_Unpickler___init___impl(UnpicklerObject *self, PyObject *file, int fix_imports, const char *encoding, const char *errors); - -static PyObject * -_pickle_Unpickler___init__(PyObject *self, PyObject *args, PyObject *kwargs) -{ - PyObject *return_value = NULL; - static char *_keywords[] = {"file", "fix_imports", "encoding", "errors", NULL}; - PyObject *file; - int fix_imports = 1; - const char *encoding = "ASCII"; - const char *errors = "strict"; +instances pickled by Python 2; these default to 'ASCII' and 'strict', +respectively. The *encoding* can be 'bytes' to read these 8-bit +string instances as bytes objects. +[clinic start generated code]*/ - if (!PyArg_ParseTupleAndKeywords(args, kwargs, - "O|$pss:__init__", _keywords, - &file, &fix_imports, &encoding, &errors)) - goto exit; - return_value = _pickle_Unpickler___init___impl((UnpicklerObject *)self, file, fix_imports, encoding, errors); - -exit: - return return_value; -} - -static PyObject * +static int _pickle_Unpickler___init___impl(UnpicklerObject *self, PyObject *file, int fix_imports, const char *encoding, const char *errors) -/*[clinic checksum: bed0d8bbe1c647960ccc6f997b33bf33935fa56f]*/ +/*[clinic end generated code: output=b9ed1d84d315f3b5 input=30b4dc9e976b890c]*/ { _Py_IDENTIFIER(persistent_load); @@ -6593,20 +6500,20 @@ _pickle_Unpickler___init___impl(UnpicklerObject *self, PyObject *file, int fix_i (void)Unpickler_clear(self); if (_Unpickler_SetInputStream(self, file) < 0) - return NULL; + return -1; if (_Unpickler_SetInputEncoding(self, encoding, errors) < 0) - return NULL; + return -1; self->fix_imports = fix_imports; if (self->fix_imports == -1) - return NULL; + return -1; if (_PyObject_HasAttrId((PyObject *)self, &PyId_persistent_load)) { self->pers_func = _PyObject_GetAttrId((PyObject *)self, &PyId_persistent_load); if (self->pers_func == NULL) - return NULL; + return 1; } else { self->pers_func = NULL; @@ -6614,30 +6521,19 @@ _pickle_Unpickler___init___impl(UnpicklerObject *self, PyObject *file, int fix_i self->stack = (Pdata *)Pdata_New(); if (self->stack == NULL) - return NULL; + return 1; self->memo_size = 32; self->memo = _Unpickler_NewMemo(self->memo_size); if (self->memo == NULL) - return NULL; + return -1; self->proto = 0; - Py_RETURN_NONE; -} - -/* Wrap the Clinic generated signature to slot it in tp_init. */ -static int -Unpickler_init(PyObject *self, PyObject *args, PyObject *kwargs) -{ - PyObject *result = _pickle_Unpickler___init__(self, args, kwargs); - if (result == NULL) { - return -1; - } - Py_DECREF(result); return 0; } + /* Define a proxy object for the Unpickler's internal memo object. This is to * avoid breaking code like: * unpickler.memo.clear() @@ -6651,29 +6547,15 @@ Unpickler_init(PyObject *self, PyObject *args, PyObject *kwargs) * real-world code like cvs2svn. */ -typedef struct { - PyObject_HEAD - UnpicklerObject *unpickler; -} UnpicklerMemoProxyObject; - -/*[clinic] +/*[clinic input] _pickle.UnpicklerMemoProxy.clear - self: UnpicklerMemoProxyObject - Remove all items from memo. -[clinic]*/ - -PyDoc_STRVAR(_pickle_UnpicklerMemoProxy_clear__doc__, -"clear()\n" -"Remove all items from memo."); - -#define _PICKLE_UNPICKLERMEMOPROXY_CLEAR_METHODDEF \ - {"clear", (PyCFunction)_pickle_UnpicklerMemoProxy_clear, METH_NOARGS, _pickle_UnpicklerMemoProxy_clear__doc__}, +[clinic start generated code]*/ static PyObject * -_pickle_UnpicklerMemoProxy_clear(UnpicklerMemoProxyObject *self) -/*[clinic checksum: 46fecf4e33c0c873124f845edf6cc3a2e9864bd5]*/ +_pickle_UnpicklerMemoProxy_clear_impl(UnpicklerMemoProxyObject *self) +/*[clinic end generated code: output=d20cd43f4ba1fb1f input=b1df7c52e7afd9bd]*/ { _Unpickler_MemoCleanup(self->unpickler); self->unpickler->memo = _Unpickler_NewMemo(self->unpickler->memo_size); @@ -6682,24 +6564,15 @@ _pickle_UnpicklerMemoProxy_clear(UnpicklerMemoProxyObject *self) Py_RETURN_NONE; } -/*[clinic] +/*[clinic input] _pickle.UnpicklerMemoProxy.copy - self: UnpicklerMemoProxyObject - Copy the memo to a new object. -[clinic]*/ - -PyDoc_STRVAR(_pickle_UnpicklerMemoProxy_copy__doc__, -"copy()\n" -"Copy the memo to a new object."); - -#define _PICKLE_UNPICKLERMEMOPROXY_COPY_METHODDEF \ - {"copy", (PyCFunction)_pickle_UnpicklerMemoProxy_copy, METH_NOARGS, _pickle_UnpicklerMemoProxy_copy__doc__}, +[clinic start generated code]*/ static PyObject * -_pickle_UnpicklerMemoProxy_copy(UnpicklerMemoProxyObject *self) -/*[clinic checksum: f8856c4e8a33540886dfbb245f286af3008fa0ad]*/ +_pickle_UnpicklerMemoProxy_copy_impl(UnpicklerMemoProxyObject *self) +/*[clinic end generated code: output=e12af7e9bc1e4c77 input=97769247ce032c1d]*/ { Py_ssize_t i; PyObject *new_memo = PyDict_New(); @@ -6729,28 +6602,19 @@ _pickle_UnpicklerMemoProxy_copy(UnpicklerMemoProxyObject *self) return NULL; } -/*[clinic] +/*[clinic input] _pickle.UnpicklerMemoProxy.__reduce__ - self: UnpicklerMemoProxyObject - Implement pickling support. -[clinic]*/ - -PyDoc_STRVAR(_pickle_UnpicklerMemoProxy___reduce____doc__, -"__reduce__()\n" -"Implement pickling support."); - -#define _PICKLE_UNPICKLERMEMOPROXY___REDUCE___METHODDEF \ - {"__reduce__", (PyCFunction)_pickle_UnpicklerMemoProxy___reduce__, METH_NOARGS, _pickle_UnpicklerMemoProxy___reduce____doc__}, +[clinic start generated code]*/ static PyObject * -_pickle_UnpicklerMemoProxy___reduce__(UnpicklerMemoProxyObject *self) -/*[clinic checksum: ab5516a77659144e1191c7dd70a0c6c7455660bc]*/ +_pickle_UnpicklerMemoProxy___reduce___impl(UnpicklerMemoProxyObject *self) +/*[clinic end generated code: output=6da34ac048d94cca input=6920862413407199]*/ { PyObject *reduce_value; PyObject *constructor_args; - PyObject *contents = _pickle_UnpicklerMemoProxy_copy(self); + PyObject *contents = _pickle_UnpicklerMemoProxy_copy_impl(self); if (contents == NULL) return NULL; @@ -7014,14 +6878,14 @@ static PyTypeObject Unpickler_Type = { 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ 0, /*tp_dictoffset*/ - Unpickler_init, /*tp_init*/ + _pickle_Unpickler___init__, /*tp_init*/ PyType_GenericAlloc, /*tp_alloc*/ PyType_GenericNew, /*tp_new*/ PyObject_GC_Del, /*tp_free*/ 0, /*tp_is_gc*/ }; -/*[clinic] +/*[clinic input] _pickle.dump @@ -7033,78 +6897,30 @@ _pickle.dump Write a pickled representation of obj to the open file object file. -This is equivalent to ``Pickler(file, protocol).dump(obj)``, but may be more -efficient. - -The optional protocol argument tells the pickler to use the given protocol -supported protocols are 0, 1, 2, 3. The default protocol is 3; a -backward-incompatible protocol designed for Python 3.0. - -Specifying a negative protocol version selects the highest protocol version -supported. The higher the protocol used, the more recent the version of -Python needed to read the pickle produced. - -The file argument must have a write() method that accepts a single bytes -argument. It can thus be a file object opened for binary writing, a -io.BytesIO instance, or any other custom object that meets this interface. - -If fix_imports is True and protocol is less than 3, pickle will try to -map the new Python 3.x names to the old module names used in Python 2.x, -so that the pickle data stream is readable with Python 2.x. -[clinic]*/ - -PyDoc_STRVAR(_pickle_dump__doc__, -"dump(obj, file, protocol=None, *, fix_imports=True)\n" -"Write a pickled representation of obj to the open file object file.\n" -"\n" -"This is equivalent to ``Pickler(file, protocol).dump(obj)``, but may be more\n" -"efficient.\n" -"\n" -"The optional protocol argument tells the pickler to use the given protocol\n" -"supported protocols are 0, 1, 2, 3. The default protocol is 3; a\n" -"backward-incompatible protocol designed for Python 3.0.\n" -"\n" -"Specifying a negative protocol version selects the highest protocol version\n" -"supported. The higher the protocol used, the more recent the version of\n" -"Python needed to read the pickle produced.\n" -"\n" -"The file argument must have a write() method that accepts a single bytes\n" -"argument. It can thus be a file object opened for binary writing, a\n" -"io.BytesIO instance, or any other custom object that meets this interface.\n" -"\n" -"If fix_imports is True and protocol is less than 3, pickle will try to\n" -"map the new Python 3.x names to the old module names used in Python 2.x,\n" -"so that the pickle data stream is readable with Python 2.x."); - -#define _PICKLE_DUMP_METHODDEF \ - {"dump", (PyCFunction)_pickle_dump, METH_VARARGS|METH_KEYWORDS, _pickle_dump__doc__}, +This is equivalent to ``Pickler(file, protocol).dump(obj)``, but may +be more efficient. -static PyObject * -_pickle_dump_impl(PyModuleDef *module, PyObject *obj, PyObject *file, PyObject *protocol, int fix_imports); +The optional *protocol* argument tells the pickler to use the given +protocol supported protocols are 0, 1, 2, 3 and 4. The default +protocol is 3; a backward-incompatible protocol designed for Python 3. -static PyObject * -_pickle_dump(PyModuleDef *module, PyObject *args, PyObject *kwargs) -{ - PyObject *return_value = NULL; - static char *_keywords[] = {"obj", "file", "protocol", "fix_imports", NULL}; - PyObject *obj; - PyObject *file; - PyObject *protocol = NULL; - int fix_imports = 1; +Specifying a negative protocol version selects the highest protocol +version supported. The higher the protocol used, the more recent the +version of Python needed to read the pickle produced. - if (!PyArg_ParseTupleAndKeywords(args, kwargs, - "OO|O$p:dump", _keywords, - &obj, &file, &protocol, &fix_imports)) - goto exit; - return_value = _pickle_dump_impl(module, obj, file, protocol, fix_imports); +The *file* argument must have a write() method that accepts a single +bytes argument. It can thus be a file object opened for binary +writing, a io.BytesIO instance, or any other custom object that meets +this interface. -exit: - return return_value; -} +If *fix_imports* is True and protocol is less than 3, pickle will try +to map the new Python 3 names to the old module names used in Python +2, so that the pickle data stream is readable with Python 2. +[clinic start generated code]*/ static PyObject * _pickle_dump_impl(PyModuleDef *module, PyObject *obj, PyObject *file, PyObject *protocol, int fix_imports) -/*[clinic checksum: e442721b16052d921b5e3fbd146d0a62e94a459e]*/ +/*[clinic end generated code: output=a606e626d553850d input=e9e5fdd48de92eae]*/ { PicklerObject *pickler = _Pickler_New(); @@ -7131,7 +6947,7 @@ _pickle_dump_impl(PyModuleDef *module, PyObject *obj, PyObject *file, PyObject * return NULL; } -/*[clinic] +/*[clinic input] _pickle.dumps @@ -7142,63 +6958,22 @@ _pickle.dumps Return the pickled representation of the object as a bytes object. -The optional protocol argument tells the pickler to use the given protocol; -supported protocols are 0, 1, 2, 3. The default protocol is 3; a -backward-incompatible protocol designed for Python 3.0. - -Specifying a negative protocol version selects the highest protocol version -supported. The higher the protocol used, the more recent the version of -Python needed to read the pickle produced. - -If fix_imports is True and *protocol* is less than 3, pickle will try to -map the new Python 3.x names to the old module names used in Python 2.x, -so that the pickle data stream is readable with Python 2.x. -[clinic]*/ - -PyDoc_STRVAR(_pickle_dumps__doc__, -"dumps(obj, protocol=None, *, fix_imports=True)\n" -"Return the pickled representation of the object as a bytes object.\n" -"\n" -"The optional protocol argument tells the pickler to use the given protocol;\n" -"supported protocols are 0, 1, 2, 3. The default protocol is 3; a\n" -"backward-incompatible protocol designed for Python 3.0.\n" -"\n" -"Specifying a negative protocol version selects the highest protocol version\n" -"supported. The higher the protocol used, the more recent the version of\n" -"Python needed to read the pickle produced.\n" -"\n" -"If fix_imports is True and *protocol* is less than 3, pickle will try to\n" -"map the new Python 3.x names to the old module names used in Python 2.x,\n" -"so that the pickle data stream is readable with Python 2.x."); - -#define _PICKLE_DUMPS_METHODDEF \ - {"dumps", (PyCFunction)_pickle_dumps, METH_VARARGS|METH_KEYWORDS, _pickle_dumps__doc__}, +The optional *protocol* argument tells the pickler to use the given +protocol; supported protocols are 0, 1, 2, 3 and 4. The default +protocol is 3; a backward-incompatible protocol designed for Python 3. -static PyObject * -_pickle_dumps_impl(PyModuleDef *module, PyObject *obj, PyObject *protocol, int fix_imports); +Specifying a negative protocol version selects the highest protocol +version supported. The higher the protocol used, the more recent the +version of Python needed to read the pickle produced. -static PyObject * -_pickle_dumps(PyModuleDef *module, PyObject *args, PyObject *kwargs) -{ - PyObject *return_value = NULL; - static char *_keywords[] = {"obj", "protocol", "fix_imports", NULL}; - PyObject *obj; - PyObject *protocol = NULL; - int fix_imports = 1; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, - "O|O$p:dumps", _keywords, - &obj, &protocol, &fix_imports)) - goto exit; - return_value = _pickle_dumps_impl(module, obj, protocol, fix_imports); - -exit: - return return_value; -} +If *fix_imports* is True and *protocol* is less than 3, pickle will +try to map the new Python 3 names to the old module names used in +Python 2, so that the pickle data stream is readable with Python 2. +[clinic start generated code]*/ static PyObject * _pickle_dumps_impl(PyModuleDef *module, PyObject *obj, PyObject *protocol, int fix_imports) -/*[clinic checksum: df6262c4c487f537f47aec8a1709318204c1e174]*/ +/*[clinic end generated code: output=777f0deefe5b88ee input=293dbeda181580b7]*/ { PyObject *result; PicklerObject *pickler = _Pickler_New(); @@ -7221,7 +6996,7 @@ _pickle_dumps_impl(PyModuleDef *module, PyObject *obj, PyObject *protocol, int f return NULL; } -/*[clinic] +/*[clinic input] _pickle.load @@ -7231,80 +7006,34 @@ _pickle.load encoding: str = 'ASCII' errors: str = 'strict' -Return a reconstituted object from the pickle data stored in a file. - -This is equivalent to ``Unpickler(file).load()``, but may be more efficient. - -The protocol version of the pickle is detected automatically, so no protocol -argument is needed. Bytes past the pickled object's representation are -ignored. - -The argument file must have two methods, a read() method that takes an -integer argument, and a readline() method that requires no arguments. Both -methods should return bytes. Thus *file* can be a binary file object opened -for reading, a BytesIO object, or any other custom object that meets this -interface. - -Optional keyword arguments are fix_imports, encoding and errors, -which are used to control compatiblity support for pickle stream generated -by Python 2.x. If fix_imports is True, pickle will try to map the old -Python 2.x names to the new names used in Python 3.x. The encoding and -errors tell pickle how to decode 8-bit string instances pickled by Python -2.x; these default to 'ASCII' and 'strict', respectively. -[clinic]*/ - -PyDoc_STRVAR(_pickle_load__doc__, -"load(file, *, fix_imports=True, encoding=\'ASCII\', errors=\'strict\')\n" -"Return a reconstituted object from the pickle data stored in a file.\n" -"\n" -"This is equivalent to ``Unpickler(file).load()``, but may be more efficient.\n" -"\n" -"The protocol version of the pickle is detected automatically, so no protocol\n" -"argument is needed. Bytes past the pickled object\'s representation are\n" -"ignored.\n" -"\n" -"The argument file must have two methods, a read() method that takes an\n" -"integer argument, and a readline() method that requires no arguments. Both\n" -"methods should return bytes. Thus *file* can be a binary file object opened\n" -"for reading, a BytesIO object, or any other custom object that meets this\n" -"interface.\n" -"\n" -"Optional keyword arguments are fix_imports, encoding and errors,\n" -"which are used to control compatiblity support for pickle stream generated\n" -"by Python 2.x. If fix_imports is True, pickle will try to map the old\n" -"Python 2.x names to the new names used in Python 3.x. The encoding and\n" -"errors tell pickle how to decode 8-bit string instances pickled by Python\n" -"2.x; these default to \'ASCII\' and \'strict\', respectively."); - -#define _PICKLE_LOAD_METHODDEF \ - {"load", (PyCFunction)_pickle_load, METH_VARARGS|METH_KEYWORDS, _pickle_load__doc__}, +Read and return an object from the pickle data stored in a file. -static PyObject * -_pickle_load_impl(PyModuleDef *module, PyObject *file, int fix_imports, const char *encoding, const char *errors); +This is equivalent to ``Unpickler(file).load()``, but may be more +efficient. -static PyObject * -_pickle_load(PyModuleDef *module, PyObject *args, PyObject *kwargs) -{ - PyObject *return_value = NULL; - static char *_keywords[] = {"file", "fix_imports", "encoding", "errors", NULL}; - PyObject *file; - int fix_imports = 1; - const char *encoding = "ASCII"; - const char *errors = "strict"; +The protocol version of the pickle is detected automatically, so no +protocol argument is needed. Bytes past the pickled object's +representation are ignored. - if (!PyArg_ParseTupleAndKeywords(args, kwargs, - "O|$pss:load", _keywords, - &file, &fix_imports, &encoding, &errors)) - goto exit; - return_value = _pickle_load_impl(module, file, fix_imports, encoding, errors); +The argument *file* must have two methods, a read() method that takes +an integer argument, and a readline() method that requires no +arguments. Both methods should return bytes. Thus *file* can be a +binary file object opened for reading, a io.BytesIO object, or any +other custom object that meets this interface. -exit: - return return_value; -} +Optional keyword arguments are *fix_imports*, *encoding* and *errors*, +which are used to control compatiblity support for pickle stream +generated by Python 2. If *fix_imports* is True, pickle will try to +map the old Python 2 names to the new names used in Python 3. The +*encoding* and *errors* tell pickle how to decode 8-bit string +instances pickled by Python 2; these default to 'ASCII' and 'strict', +respectively. The *encoding* can be 'bytes' to read these 8-bit +string instances as bytes objects. +[clinic start generated code]*/ static PyObject * _pickle_load_impl(PyModuleDef *module, PyObject *file, int fix_imports, const char *encoding, const char *errors) -/*[clinic checksum: e10796f6765b22ce48dca6940f11b3933853ca35]*/ +/*[clinic end generated code: output=568c61356c172654 input=da97372e38e510a6]*/ { PyObject *result; UnpicklerObject *unpickler = _Unpickler_New(); @@ -7329,7 +7058,7 @@ _pickle_load_impl(PyModuleDef *module, PyObject *file, int fix_imports, const ch return NULL; } -/*[clinic] +/*[clinic input] _pickle.loads @@ -7339,64 +7068,25 @@ _pickle.loads encoding: str = 'ASCII' errors: str = 'strict' -Return a reconstituted object from the given pickle data. - -The protocol version of the pickle is detected automatically, so no protocol -argument is needed. Bytes past the pickled object's representation are -ignored. - -Optional keyword arguments are fix_imports, encoding and errors, which -are used to control compatiblity support for pickle stream generated -by Python 2.x. If fix_imports is True, pickle will try to map the old -Python 2.x names to the new names used in Python 3.x. The encoding and -errors tell pickle how to decode 8-bit string instances pickled by Python -2.x; these default to 'ASCII' and 'strict', respectively. -[clinic]*/ - -PyDoc_STRVAR(_pickle_loads__doc__, -"loads(data, *, fix_imports=True, encoding=\'ASCII\', errors=\'strict\')\n" -"Return a reconstituted object from the given pickle data.\n" -"\n" -"The protocol version of the pickle is detected automatically, so no protocol\n" -"argument is needed. Bytes past the pickled object\'s representation are\n" -"ignored.\n" -"\n" -"Optional keyword arguments are fix_imports, encoding and errors, which\n" -"are used to control compatiblity support for pickle stream generated\n" -"by Python 2.x. If fix_imports is True, pickle will try to map the old\n" -"Python 2.x names to the new names used in Python 3.x. The encoding and\n" -"errors tell pickle how to decode 8-bit string instances pickled by Python\n" -"2.x; these default to \'ASCII\' and \'strict\', respectively."); - -#define _PICKLE_LOADS_METHODDEF \ - {"loads", (PyCFunction)_pickle_loads, METH_VARARGS|METH_KEYWORDS, _pickle_loads__doc__}, - -static PyObject * -_pickle_loads_impl(PyModuleDef *module, PyObject *data, int fix_imports, const char *encoding, const char *errors); - -static PyObject * -_pickle_loads(PyModuleDef *module, PyObject *args, PyObject *kwargs) -{ - PyObject *return_value = NULL; - static char *_keywords[] = {"data", "fix_imports", "encoding", "errors", NULL}; - PyObject *data; - int fix_imports = 1; - const char *encoding = "ASCII"; - const char *errors = "strict"; +Read and return an object from the given pickle data. - if (!PyArg_ParseTupleAndKeywords(args, kwargs, - "O|$pss:loads", _keywords, - &data, &fix_imports, &encoding, &errors)) - goto exit; - return_value = _pickle_loads_impl(module, data, fix_imports, encoding, errors); +The protocol version of the pickle is detected automatically, so no +protocol argument is needed. Bytes past the pickled object's +representation are ignored. -exit: - return return_value; -} +Optional keyword arguments are *fix_imports*, *encoding* and *errors*, +which are used to control compatiblity support for pickle stream +generated by Python 2. If *fix_imports* is True, pickle will try to +map the old Python 2 names to the new names used in Python 3. The +*encoding* and *errors* tell pickle how to decode 8-bit string +instances pickled by Python 2; these default to 'ASCII' and 'strict', +respectively. The *encoding* can be 'bytes' to read these 8-bit +string instances as bytes objects. +[clinic start generated code]*/ static PyObject * _pickle_loads_impl(PyModuleDef *module, PyObject *data, int fix_imports, const char *encoding, const char *errors) -/*[clinic checksum: 29ee725efcbf51a3533c19cb8261a8e267b7080a]*/ +/*[clinic end generated code: output=0b3845ad110b2522 input=f57f0fdaa2b4cb8b]*/ { PyObject *result; UnpicklerObject *unpickler = _Unpickler_New(); @@ -7436,6 +7126,12 @@ pickle_clear(PyObject *m) return 0; } +static void +pickle_free(PyObject *m) +{ + _Pickle_ClearState(_Pickle_GetState(m)); +} + static int pickle_traverse(PyObject *m, visitproc visit, void *arg) { @@ -7457,14 +7153,14 @@ pickle_traverse(PyObject *m, visitproc visit, void *arg) static struct PyModuleDef _picklemodule = { PyModuleDef_HEAD_INIT, - "_pickle", /* m_name */ - pickle_module_doc, /* m_doc */ - sizeof(PickleState), /* m_size */ - pickle_methods, /* m_methods */ - NULL, /* m_reload */ - pickle_traverse, /* m_traverse */ - pickle_clear, /* m_clear */ - NULL /* m_free */ + "_pickle", /* m_name */ + pickle_module_doc, /* m_doc */ + sizeof(PickleState), /* m_size */ + pickle_methods, /* m_methods */ + NULL, /* m_reload */ + pickle_traverse, /* m_traverse */ + pickle_clear, /* m_clear */ + (freefunc)pickle_free /* m_free */ }; PyMODINIT_FUNC diff --git a/Modules/_posixsubprocess.c b/Modules/_posixsubprocess.c index a2d702299260..a8c2be223d7c 100644 --- a/Modules/_posixsubprocess.c +++ b/Modules/_posixsubprocess.c @@ -18,6 +18,12 @@ #include #endif +#if defined(__ANDROID__) && !defined(SYS_getdents64) +/* Android doesn't expose syscalls, add the definition manually. */ +# include +# define SYS_getdents64 __NR_getdents64 +#endif + #if defined(sun) /* readdir64 is used to work around Solaris 9 bug 6395699. */ # define readdir readdir64 @@ -38,10 +44,6 @@ #define POSIX_CALL(call) do { if ((call) == -1) goto error; } while (0) -/* Maximum file descriptor, initialized on module load. */ -static long max_fd; - - /* Given the gc module call gc.enable() and return 0 on success. */ static int _enable_gc(PyObject *gc_module) @@ -160,14 +162,39 @@ make_inheritable(PyObject *py_fds_to_keep, int errpipe_write) } -/* Close all file descriptors in the range start_fd inclusive to - * end_fd exclusive except for those in py_fds_to_keep. If the - * range defined by [start_fd, end_fd) is large this will take a - * long time as it calls close() on EVERY possible fd. +/* Get the maximum file descriptor that could be opened by this process. + * This function is async signal safe for use between fork() and exec(). + */ +static long +safe_get_max_fd(void) +{ + long local_max_fd; +#if defined(__NetBSD__) + local_max_fd = fcntl(0, F_MAXFD); + if (local_max_fd >= 0) + return local_max_fd; +#endif +#ifdef _SC_OPEN_MAX + local_max_fd = sysconf(_SC_OPEN_MAX); + if (local_max_fd == -1) +#endif + local_max_fd = 256; /* Matches legacy Lib/subprocess.py behavior. */ + return local_max_fd; +} + + +/* Close all file descriptors in the range from start_fd and higher + * except for those in py_fds_to_keep. If the range defined by + * [start_fd, safe_get_max_fd()) is large this will take a long + * time as it calls close() on EVERY possible fd. + * + * It isn't possible to know for sure what the max fd to go up to + * is for processes with the capability of raising their maximum. */ static void -_close_fds_by_brute_force(int start_fd, int end_fd, PyObject *py_fds_to_keep) +_close_fds_by_brute_force(long start_fd, PyObject *py_fds_to_keep) { + long end_fd = safe_get_max_fd(); Py_ssize_t num_fds_to_keep = PySequence_Length(py_fds_to_keep); Py_ssize_t keep_seq_idx; int fd_num; @@ -207,8 +234,8 @@ struct linux_dirent64 { char d_name[256]; /* Filename (null-terminated) */ }; -/* Close all open file descriptors in the range start_fd inclusive to end_fd - * exclusive. Do not close any in the sorted py_fds_to_keep list. +/* Close all open file descriptors in the range from start_fd and higher + * Do not close any in the sorted py_fds_to_keep list. * * This version is async signal safe as it does not make any unsafe C library * calls, malloc calls or handle any locks. It is _unfortunate_ to be forced @@ -223,16 +250,14 @@ struct linux_dirent64 { * it with some cpp #define magic to work on other OSes as well if you want. */ static void -_close_open_fd_range_safe(int start_fd, int end_fd, PyObject* py_fds_to_keep) +_close_open_fds_safe(int start_fd, PyObject* py_fds_to_keep) { int fd_dir_fd; - if (start_fd >= end_fd) - return; fd_dir_fd = _Py_open(FD_DIR, O_RDONLY); if (fd_dir_fd == -1) { /* No way to get a list of open fds. */ - _close_fds_by_brute_force(start_fd, end_fd, py_fds_to_keep); + _close_fds_by_brute_force(start_fd, py_fds_to_keep); return; } else { char buffer[sizeof(struct linux_dirent64)]; @@ -247,23 +272,23 @@ _close_open_fd_range_safe(int start_fd, int end_fd, PyObject* py_fds_to_keep) entry = (struct linux_dirent64 *)(buffer + offset); if ((fd = _pos_int_from_ascii(entry->d_name)) < 0) continue; /* Not a number. */ - if (fd != fd_dir_fd && fd >= start_fd && fd < end_fd && + if (fd != fd_dir_fd && fd >= start_fd && !_is_fd_in_sorted_fd_sequence(fd, py_fds_to_keep)) { while (close(fd) < 0 && errno == EINTR); } } } - close(fd_dir_fd); + while (close(fd_dir_fd) < 0 && errno == EINTR); } } -#define _close_open_fd_range _close_open_fd_range_safe +#define _close_open_fds _close_open_fds_safe #else /* NOT (defined(__linux__) && defined(HAVE_SYS_SYSCALL_H)) */ -/* Close all open file descriptors in the range start_fd inclusive to end_fd - * exclusive. Do not close any in the sorted py_fds_to_keep list. +/* Close all open file descriptors from start_fd and higher. + * Do not close any in the sorted py_fds_to_keep list. * * This function violates the strict use of async signal safe functions. :( * It calls opendir(), readdir() and closedir(). Of these, the one most @@ -276,17 +301,13 @@ _close_open_fd_range_safe(int start_fd, int end_fd, PyObject* py_fds_to_keep) * http://womble.decadent.org.uk/readdir_r-advisory.html */ static void -_close_open_fd_range_maybe_unsafe(int start_fd, int end_fd, - PyObject* py_fds_to_keep) +_close_open_fds_maybe_unsafe(long start_fd, PyObject* py_fds_to_keep) { DIR *proc_fd_dir; #ifndef HAVE_DIRFD - while (_is_fd_in_sorted_fd_sequence(start_fd, py_fds_to_keep) && - (start_fd < end_fd)) { + while (_is_fd_in_sorted_fd_sequence(start_fd, py_fds_to_keep)) { ++start_fd; } - if (start_fd >= end_fd) - return; /* Close our lowest fd before we call opendir so that it is likely to * reuse that fd otherwise we might close opendir's file descriptor in * our loop. This trick assumes that fd's are allocated on a lowest @@ -294,8 +315,6 @@ _close_open_fd_range_maybe_unsafe(int start_fd, int end_fd, while (close(start_fd) < 0 && errno == EINTR); ++start_fd; #endif - if (start_fd >= end_fd) - return; #if defined(__FreeBSD__) if (!_is_fdescfs_mounted_on_dev_fd()) @@ -305,7 +324,7 @@ _close_open_fd_range_maybe_unsafe(int start_fd, int end_fd, proc_fd_dir = opendir(FD_DIR); if (!proc_fd_dir) { /* No way to get a list of open fds. */ - _close_fds_by_brute_force(start_fd, end_fd, py_fds_to_keep); + _close_fds_by_brute_force(start_fd, py_fds_to_keep); } else { struct dirent *dir_entry; #ifdef HAVE_DIRFD @@ -318,7 +337,7 @@ _close_open_fd_range_maybe_unsafe(int start_fd, int end_fd, int fd; if ((fd = _pos_int_from_ascii(dir_entry->d_name)) < 0) continue; /* Not a number. */ - if (fd != fd_used_by_opendir && fd >= start_fd && fd < end_fd && + if (fd != fd_used_by_opendir && fd >= start_fd && !_is_fd_in_sorted_fd_sequence(fd, py_fds_to_keep)) { while (close(fd) < 0 && errno == EINTR); } @@ -326,13 +345,13 @@ _close_open_fd_range_maybe_unsafe(int start_fd, int end_fd, } if (errno) { /* readdir error, revert behavior. Highly Unlikely. */ - _close_fds_by_brute_force(start_fd, end_fd, py_fds_to_keep); + _close_fds_by_brute_force(start_fd, py_fds_to_keep); } closedir(proc_fd_dir); } } -#define _close_open_fd_range _close_open_fd_range_maybe_unsafe +#define _close_open_fds _close_open_fds_maybe_unsafe #endif /* else NOT (defined(__linux__) && defined(HAVE_SYS_SYSCALL_H)) */ @@ -451,14 +470,8 @@ child_exec(char *const exec_array[], /* close FDs after executing preexec_fn, which might open FDs */ if (close_fds) { - int local_max_fd = max_fd; -#if defined(__NetBSD__) - local_max_fd = fcntl(0, F_MAXFD); - if (local_max_fd < 0) - local_max_fd = max_fd; -#endif /* TODO HP-UX could use pstat_getproc() if anyone cares about it. */ - _close_open_fd_range(3, local_max_fd, py_fds_to_keep); + _close_open_fds(3, py_fds_to_keep); } /* This loop matches the Lib/os.py _execvpe()'s PATH search when */ @@ -525,6 +538,7 @@ subprocess_fork_exec(PyObject* self, PyObject *args) int need_to_reenable_gc = 0; char *const *exec_array, *const *argv = NULL, *const *envp = NULL; Py_ssize_t arg_num; + int import_lock_held = 0; if (!PyArg_ParseTuple( args, "OOpOOOiiiiiiiiiiO:fork_exec", @@ -577,10 +591,8 @@ subprocess_fork_exec(PyObject* self, PyObject *args) } exec_array = _PySequence_BytesToCharpArray(executable_list); - if (!exec_array) { - Py_XDECREF(gc_module); - return NULL; - } + if (!exec_array) + goto cleanup; /* Convert args and env into appropriate arguments for exec() */ /* These conversions are done in the parent process to avoid allocating @@ -622,6 +634,7 @@ subprocess_fork_exec(PyObject* self, PyObject *args) if (!preexec_fn_args_tuple) goto cleanup; _PyImport_AcquireLock(); + import_lock_held = 1; } if (cwd_obj != Py_None) { @@ -669,6 +682,7 @@ subprocess_fork_exec(PyObject* self, PyObject *args) PyErr_SetString(PyExc_RuntimeError, "not holding the import lock"); } + import_lock_held = 0; /* Parent process */ if (envp) @@ -691,18 +705,25 @@ subprocess_fork_exec(PyObject* self, PyObject *args) return PyLong_FromPid(pid); cleanup: + if (import_lock_held) + _PyImport_ReleaseLock(); if (envp) _Py_FreeCharPArray(envp); if (argv) _Py_FreeCharPArray(argv); - _Py_FreeCharPArray(exec_array); + if (exec_array) + _Py_FreeCharPArray(exec_array); Py_XDECREF(converted_args); Py_XDECREF(fast_args); Py_XDECREF(preexec_fn_args_tuple); /* Reenable gc if it was disabled. */ - if (need_to_reenable_gc) + if (need_to_reenable_gc) { + PyObject *exctype, *val, *tb; + PyErr_Fetch(&exctype, &val, &tb); _enable_gc(gc_module); + PyErr_Restore(exctype, val, tb); + } Py_XDECREF(gc_module); return NULL; } @@ -753,11 +774,5 @@ static struct PyModuleDef _posixsubprocessmodule = { PyMODINIT_FUNC PyInit__posixsubprocess(void) { -#ifdef _SC_OPEN_MAX - max_fd = sysconf(_SC_OPEN_MAX); - if (max_fd == -1) -#endif - max_fd = 256; /* Matches Lib/subprocess.py */ - return PyModule_Create(&_posixsubprocessmodule); } diff --git a/Modules/_randommodule.c b/Modules/_randommodule.c index 4377ee0cf4d9..af861820a2e5 100644 --- a/Modules/_randommodule.c +++ b/Modules/_randommodule.c @@ -78,8 +78,8 @@ typedef struct { PyObject_HEAD - unsigned long state[N]; int index; + unsigned long state[N]; } RandomObject; static PyTypeObject Random_Type; diff --git a/Modules/_sha3/cleanup.py b/Modules/_sha3/cleanup.py deleted file mode 100755 index aabcb0442cef..000000000000 --- a/Modules/_sha3/cleanup.py +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env python -# Copyright (C) 2012 Christian Heimes (christian@python.org) -# Licensed to PSF under a Contributor Agreement. -# -# cleanup Keccak sources - -import os -import re - -CPP1 = re.compile("^//(.*)") -CPP2 = re.compile("\ //(.*)") - -STATICS = ("void ", "int ", "HashReturn ", "const UINT64 ", "UINT16 ") - -HERE = os.path.dirname(os.path.abspath(__file__)) -KECCAK = os.path.join(HERE, "keccak") - -def getfiles(): - for name in os.listdir(KECCAK): - name = os.path.join(KECCAK, name) - if os.path.isfile(name): - yield name - -def cleanup(f): - buf = [] - for line in f: - # mark all functions and global data as static - if line.startswith(STATICS): - buf.append("static " + line) - continue - # remove UINT64 typedef, we have our own - if line.startswith("typedef unsigned long long int"): - buf.append("/* %s */\n" % line.strip()) - continue - # remove #include "brg_endian.h" - if "brg_endian.h" in line: - buf.append("/* %s */\n" % line.strip()) - continue - # transform C++ comments into ANSI C comments - line = CPP1.sub(r"/* \1 */", line) - line = CPP2.sub(r" /* \1 */", line) - buf.append(line) - return "".join(buf) - -for name in getfiles(): - with open(name) as f: - res = cleanup(f) - with open(name, "w") as f: - f.write(res) diff --git a/Modules/_sha3/keccak/KeccakF-1600-32-rvk.macros b/Modules/_sha3/keccak/KeccakF-1600-32-rvk.macros deleted file mode 100644 index c0c902987376..000000000000 --- a/Modules/_sha3/keccak/KeccakF-1600-32-rvk.macros +++ /dev/null @@ -1,555 +0,0 @@ -/* -The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, -Michaël Peeters and Gilles Van Assche. For more information, feedback or -questions, please refer to our website: http://keccak.noekeon.org/ - -Implementation by Ronny Van Keer, -hereby denoted as "the implementer". - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -static const UINT32 KeccakF1600RoundConstants_int2[2*24] = -{ - 0x00000001UL, 0x00000000UL, - 0x00000000UL, 0x00000089UL, - 0x00000000UL, 0x8000008bUL, - 0x00000000UL, 0x80008080UL, - 0x00000001UL, 0x0000008bUL, - 0x00000001UL, 0x00008000UL, - 0x00000001UL, 0x80008088UL, - 0x00000001UL, 0x80000082UL, - 0x00000000UL, 0x0000000bUL, - 0x00000000UL, 0x0000000aUL, - 0x00000001UL, 0x00008082UL, - 0x00000000UL, 0x00008003UL, - 0x00000001UL, 0x0000808bUL, - 0x00000001UL, 0x8000000bUL, - 0x00000001UL, 0x8000008aUL, - 0x00000001UL, 0x80000081UL, - 0x00000000UL, 0x80000081UL, - 0x00000000UL, 0x80000008UL, - 0x00000000UL, 0x00000083UL, - 0x00000000UL, 0x80008003UL, - 0x00000001UL, 0x80008088UL, - 0x00000000UL, 0x80000088UL, - 0x00000001UL, 0x00008000UL, - 0x00000000UL, 0x80008082UL -}; - -#undef rounds - -#define rounds \ -{ \ - UINT32 Da0, De0, Di0, Do0, Du0; \ - UINT32 Da1, De1, Di1, Do1, Du1; \ - UINT32 Ba, Be, Bi, Bo, Bu; \ - UINT32 Aba0, Abe0, Abi0, Abo0, Abu0; \ - UINT32 Aba1, Abe1, Abi1, Abo1, Abu1; \ - UINT32 Aga0, Age0, Agi0, Ago0, Agu0; \ - UINT32 Aga1, Age1, Agi1, Ago1, Agu1; \ - UINT32 Aka0, Ake0, Aki0, Ako0, Aku0; \ - UINT32 Aka1, Ake1, Aki1, Ako1, Aku1; \ - UINT32 Ama0, Ame0, Ami0, Amo0, Amu0; \ - UINT32 Ama1, Ame1, Ami1, Amo1, Amu1; \ - UINT32 Asa0, Ase0, Asi0, Aso0, Asu0; \ - UINT32 Asa1, Ase1, Asi1, Aso1, Asu1; \ - UINT32 Cw, Cx, Cy, Cz; \ - UINT32 Eba0, Ebe0, Ebi0, Ebo0, Ebu0; \ - UINT32 Eba1, Ebe1, Ebi1, Ebo1, Ebu1; \ - UINT32 Ega0, Ege0, Egi0, Ego0, Egu0; \ - UINT32 Ega1, Ege1, Egi1, Ego1, Egu1; \ - UINT32 Eka0, Eke0, Eki0, Eko0, Eku0; \ - UINT32 Eka1, Eke1, Eki1, Eko1, Eku1; \ - UINT32 Ema0, Eme0, Emi0, Emo0, Emu0; \ - UINT32 Ema1, Eme1, Emi1, Emo1, Emu1; \ - UINT32 Esa0, Ese0, Esi0, Eso0, Esu0; \ - UINT32 Esa1, Ese1, Esi1, Eso1, Esu1; \ - const UINT32 * pRoundConstants = KeccakF1600RoundConstants_int2; \ - UINT32 i; \ -\ - copyFromState(A, state) \ -\ - for( i = 12; i != 0; --i ) { \ - Cx = Abu0^Agu0^Aku0^Amu0^Asu0; \ - Du1 = Abe1^Age1^Ake1^Ame1^Ase1; \ - Da0 = Cx^ROL32(Du1, 1); \ - Cz = Abu1^Agu1^Aku1^Amu1^Asu1; \ - Du0 = Abe0^Age0^Ake0^Ame0^Ase0; \ - Da1 = Cz^Du0; \ -\ - Cw = Abi0^Agi0^Aki0^Ami0^Asi0; \ - Do0 = Cw^ROL32(Cz, 1); \ - Cy = Abi1^Agi1^Aki1^Ami1^Asi1; \ - Do1 = Cy^Cx; \ -\ - Cx = Aba0^Aga0^Aka0^Ama0^Asa0; \ - De0 = Cx^ROL32(Cy, 1); \ - Cz = Aba1^Aga1^Aka1^Ama1^Asa1; \ - De1 = Cz^Cw; \ -\ - Cy = Abo1^Ago1^Ako1^Amo1^Aso1; \ - Di0 = Du0^ROL32(Cy, 1); \ - Cw = Abo0^Ago0^Ako0^Amo0^Aso0; \ - Di1 = Du1^Cw; \ -\ - Du0 = Cw^ROL32(Cz, 1); \ - Du1 = Cy^Cx; \ -\ - Aba0 ^= Da0; \ - Ba = Aba0; \ - Age0 ^= De0; \ - Be = ROL32(Age0, 22); \ - Aki1 ^= Di1; \ - Bi = ROL32(Aki1, 22); \ - Amo1 ^= Do1; \ - Bo = ROL32(Amo1, 11); \ - Asu0 ^= Du0; \ - Bu = ROL32(Asu0, 7); \ - Eba0 = Ba ^((~Be)& Bi ) ^ *(pRoundConstants++); \ - Ebe0 = Be ^((~Bi)& Bo ); \ - Ebi0 = Bi ^((~Bo)& Bu ); \ - Ebo0 = Bo ^((~Bu)& Ba ); \ - Ebu0 = Bu ^((~Ba)& Be ); \ -\ - Abo0 ^= Do0; \ - Ba = ROL32(Abo0, 14); \ - Agu0 ^= Du0; \ - Be = ROL32(Agu0, 10); \ - Aka1 ^= Da1; \ - Bi = ROL32(Aka1, 2); \ - Ame1 ^= De1; \ - Bo = ROL32(Ame1, 23); \ - Asi1 ^= Di1; \ - Bu = ROL32(Asi1, 31); \ - Ega0 = Ba ^((~Be)& Bi ); \ - Ege0 = Be ^((~Bi)& Bo ); \ - Egi0 = Bi ^((~Bo)& Bu ); \ - Ego0 = Bo ^((~Bu)& Ba ); \ - Egu0 = Bu ^((~Ba)& Be ); \ -\ - Abe1 ^= De1; \ - Ba = ROL32(Abe1, 1); \ - Agi0 ^= Di0; \ - Be = ROL32(Agi0, 3); \ - Ako1 ^= Do1; \ - Bi = ROL32(Ako1, 13); \ - Amu0 ^= Du0; \ - Bo = ROL32(Amu0, 4); \ - Asa0 ^= Da0; \ - Bu = ROL32(Asa0, 9); \ - Eka0 = Ba ^((~Be)& Bi ); \ - Eke0 = Be ^((~Bi)& Bo ); \ - Eki0 = Bi ^((~Bo)& Bu ); \ - Eko0 = Bo ^((~Bu)& Ba ); \ - Eku0 = Bu ^((~Ba)& Be ); \ -\ - Abu1 ^= Du1; \ - Ba = ROL32(Abu1, 14); \ - Aga0 ^= Da0; \ - Be = ROL32(Aga0, 18); \ - Ake0 ^= De0; \ - Bi = ROL32(Ake0, 5); \ - Ami1 ^= Di1; \ - Bo = ROL32(Ami1, 8); \ - Aso0 ^= Do0; \ - Bu = ROL32(Aso0, 28); \ - Ema0 = Ba ^((~Be)& Bi ); \ - Eme0 = Be ^((~Bi)& Bo ); \ - Emi0 = Bi ^((~Bo)& Bu ); \ - Emo0 = Bo ^((~Bu)& Ba ); \ - Emu0 = Bu ^((~Ba)& Be ); \ -\ - Abi0 ^= Di0; \ - Ba = ROL32(Abi0, 31); \ - Ago1 ^= Do1; \ - Be = ROL32(Ago1, 28); \ - Aku1 ^= Du1; \ - Bi = ROL32(Aku1, 20); \ - Ama1 ^= Da1; \ - Bo = ROL32(Ama1, 21); \ - Ase0 ^= De0; \ - Bu = ROL32(Ase0, 1); \ - Esa0 = Ba ^((~Be)& Bi ); \ - Ese0 = Be ^((~Bi)& Bo ); \ - Esi0 = Bi ^((~Bo)& Bu ); \ - Eso0 = Bo ^((~Bu)& Ba ); \ - Esu0 = Bu ^((~Ba)& Be ); \ -\ - Aba1 ^= Da1; \ - Ba = Aba1; \ - Age1 ^= De1; \ - Be = ROL32(Age1, 22); \ - Aki0 ^= Di0; \ - Bi = ROL32(Aki0, 21); \ - Amo0 ^= Do0; \ - Bo = ROL32(Amo0, 10); \ - Asu1 ^= Du1; \ - Bu = ROL32(Asu1, 7); \ - Eba1 = Ba ^((~Be)& Bi ); \ - Eba1 ^= *(pRoundConstants++); \ - Ebe1 = Be ^((~Bi)& Bo ); \ - Ebi1 = Bi ^((~Bo)& Bu ); \ - Ebo1 = Bo ^((~Bu)& Ba ); \ - Ebu1 = Bu ^((~Ba)& Be ); \ -\ - Abo1 ^= Do1; \ - Ba = ROL32(Abo1, 14); \ - Agu1 ^= Du1; \ - Be = ROL32(Agu1, 10); \ - Aka0 ^= Da0; \ - Bi = ROL32(Aka0, 1); \ - Ame0 ^= De0; \ - Bo = ROL32(Ame0, 22); \ - Asi0 ^= Di0; \ - Bu = ROL32(Asi0, 30); \ - Ega1 = Ba ^((~Be)& Bi ); \ - Ege1 = Be ^((~Bi)& Bo ); \ - Egi1 = Bi ^((~Bo)& Bu ); \ - Ego1 = Bo ^((~Bu)& Ba ); \ - Egu1 = Bu ^((~Ba)& Be ); \ -\ - Abe0 ^= De0; \ - Ba = Abe0; \ - Agi1 ^= Di1; \ - Be = ROL32(Agi1, 3); \ - Ako0 ^= Do0; \ - Bi = ROL32(Ako0, 12); \ - Amu1 ^= Du1; \ - Bo = ROL32(Amu1, 4); \ - Asa1 ^= Da1; \ - Bu = ROL32(Asa1, 9); \ - Eka1 = Ba ^((~Be)& Bi ); \ - Eke1 = Be ^((~Bi)& Bo ); \ - Eki1 = Bi ^((~Bo)& Bu ); \ - Eko1 = Bo ^((~Bu)& Ba ); \ - Eku1 = Bu ^((~Ba)& Be ); \ -\ - Abu0 ^= Du0; \ - Ba = ROL32(Abu0, 13); \ - Aga1 ^= Da1; \ - Be = ROL32(Aga1, 18); \ - Ake1 ^= De1; \ - Bi = ROL32(Ake1, 5); \ - Ami0 ^= Di0; \ - Bo = ROL32(Ami0, 7); \ - Aso1 ^= Do1; \ - Bu = ROL32(Aso1, 28); \ - Ema1 = Ba ^((~Be)& Bi ); \ - Eme1 = Be ^((~Bi)& Bo ); \ - Emi1 = Bi ^((~Bo)& Bu ); \ - Emo1 = Bo ^((~Bu)& Ba ); \ - Emu1 = Bu ^((~Ba)& Be ); \ -\ - Abi1 ^= Di1; \ - Ba = ROL32(Abi1, 31); \ - Ago0 ^= Do0; \ - Be = ROL32(Ago0, 27); \ - Aku0 ^= Du0; \ - Bi = ROL32(Aku0, 19); \ - Ama0 ^= Da0; \ - Bo = ROL32(Ama0, 20); \ - Ase1 ^= De1; \ - Bu = ROL32(Ase1, 1); \ - Esa1 = Ba ^((~Be)& Bi ); \ - Ese1 = Be ^((~Bi)& Bo ); \ - Esi1 = Bi ^((~Bo)& Bu ); \ - Eso1 = Bo ^((~Bu)& Ba ); \ - Esu1 = Bu ^((~Ba)& Be ); \ -\ - Cx = Ebu0^Egu0^Eku0^Emu0^Esu0; \ - Du1 = Ebe1^Ege1^Eke1^Eme1^Ese1; \ - Da0 = Cx^ROL32(Du1, 1); \ - Cz = Ebu1^Egu1^Eku1^Emu1^Esu1; \ - Du0 = Ebe0^Ege0^Eke0^Eme0^Ese0; \ - Da1 = Cz^Du0; \ -\ - Cw = Ebi0^Egi0^Eki0^Emi0^Esi0; \ - Do0 = Cw^ROL32(Cz, 1); \ - Cy = Ebi1^Egi1^Eki1^Emi1^Esi1; \ - Do1 = Cy^Cx; \ -\ - Cx = Eba0^Ega0^Eka0^Ema0^Esa0; \ - De0 = Cx^ROL32(Cy, 1); \ - Cz = Eba1^Ega1^Eka1^Ema1^Esa1; \ - De1 = Cz^Cw; \ -\ - Cy = Ebo1^Ego1^Eko1^Emo1^Eso1; \ - Di0 = Du0^ROL32(Cy, 1); \ - Cw = Ebo0^Ego0^Eko0^Emo0^Eso0; \ - Di1 = Du1^Cw; \ -\ - Du0 = Cw^ROL32(Cz, 1); \ - Du1 = Cy^Cx; \ -\ - Eba0 ^= Da0; \ - Ba = Eba0; \ - Ege0 ^= De0; \ - Be = ROL32(Ege0, 22); \ - Eki1 ^= Di1; \ - Bi = ROL32(Eki1, 22); \ - Emo1 ^= Do1; \ - Bo = ROL32(Emo1, 11); \ - Esu0 ^= Du0; \ - Bu = ROL32(Esu0, 7); \ - Aba0 = Ba ^((~Be)& Bi ); \ - Aba0 ^= *(pRoundConstants++); \ - Abe0 = Be ^((~Bi)& Bo ); \ - Abi0 = Bi ^((~Bo)& Bu ); \ - Abo0 = Bo ^((~Bu)& Ba ); \ - Abu0 = Bu ^((~Ba)& Be ); \ -\ - Ebo0 ^= Do0; \ - Ba = ROL32(Ebo0, 14); \ - Egu0 ^= Du0; \ - Be = ROL32(Egu0, 10); \ - Eka1 ^= Da1; \ - Bi = ROL32(Eka1, 2); \ - Eme1 ^= De1; \ - Bo = ROL32(Eme1, 23); \ - Esi1 ^= Di1; \ - Bu = ROL32(Esi1, 31); \ - Aga0 = Ba ^((~Be)& Bi ); \ - Age0 = Be ^((~Bi)& Bo ); \ - Agi0 = Bi ^((~Bo)& Bu ); \ - Ago0 = Bo ^((~Bu)& Ba ); \ - Agu0 = Bu ^((~Ba)& Be ); \ -\ - Ebe1 ^= De1; \ - Ba = ROL32(Ebe1, 1); \ - Egi0 ^= Di0; \ - Be = ROL32(Egi0, 3); \ - Eko1 ^= Do1; \ - Bi = ROL32(Eko1, 13); \ - Emu0 ^= Du0; \ - Bo = ROL32(Emu0, 4); \ - Esa0 ^= Da0; \ - Bu = ROL32(Esa0, 9); \ - Aka0 = Ba ^((~Be)& Bi ); \ - Ake0 = Be ^((~Bi)& Bo ); \ - Aki0 = Bi ^((~Bo)& Bu ); \ - Ako0 = Bo ^((~Bu)& Ba ); \ - Aku0 = Bu ^((~Ba)& Be ); \ -\ - Ebu1 ^= Du1; \ - Ba = ROL32(Ebu1, 14); \ - Ega0 ^= Da0; \ - Be = ROL32(Ega0, 18); \ - Eke0 ^= De0; \ - Bi = ROL32(Eke0, 5); \ - Emi1 ^= Di1; \ - Bo = ROL32(Emi1, 8); \ - Eso0 ^= Do0; \ - Bu = ROL32(Eso0, 28); \ - Ama0 = Ba ^((~Be)& Bi ); \ - Ame0 = Be ^((~Bi)& Bo ); \ - Ami0 = Bi ^((~Bo)& Bu ); \ - Amo0 = Bo ^((~Bu)& Ba ); \ - Amu0 = Bu ^((~Ba)& Be ); \ -\ - Ebi0 ^= Di0; \ - Ba = ROL32(Ebi0, 31); \ - Ego1 ^= Do1; \ - Be = ROL32(Ego1, 28); \ - Eku1 ^= Du1; \ - Bi = ROL32(Eku1, 20); \ - Ema1 ^= Da1; \ - Bo = ROL32(Ema1, 21); \ - Ese0 ^= De0; \ - Bu = ROL32(Ese0, 1); \ - Asa0 = Ba ^((~Be)& Bi ); \ - Ase0 = Be ^((~Bi)& Bo ); \ - Asi0 = Bi ^((~Bo)& Bu ); \ - Aso0 = Bo ^((~Bu)& Ba ); \ - Asu0 = Bu ^((~Ba)& Be ); \ -\ - Eba1 ^= Da1; \ - Ba = Eba1; \ - Ege1 ^= De1; \ - Be = ROL32(Ege1, 22); \ - Eki0 ^= Di0; \ - Bi = ROL32(Eki0, 21); \ - Emo0 ^= Do0; \ - Bo = ROL32(Emo0, 10); \ - Esu1 ^= Du1; \ - Bu = ROL32(Esu1, 7); \ - Aba1 = Ba ^((~Be)& Bi ); \ - Aba1 ^= *(pRoundConstants++); \ - Abe1 = Be ^((~Bi)& Bo ); \ - Abi1 = Bi ^((~Bo)& Bu ); \ - Abo1 = Bo ^((~Bu)& Ba ); \ - Abu1 = Bu ^((~Ba)& Be ); \ -\ - Ebo1 ^= Do1; \ - Ba = ROL32(Ebo1, 14); \ - Egu1 ^= Du1; \ - Be = ROL32(Egu1, 10); \ - Eka0 ^= Da0; \ - Bi = ROL32(Eka0, 1); \ - Eme0 ^= De0; \ - Bo = ROL32(Eme0, 22); \ - Esi0 ^= Di0; \ - Bu = ROL32(Esi0, 30); \ - Aga1 = Ba ^((~Be)& Bi ); \ - Age1 = Be ^((~Bi)& Bo ); \ - Agi1 = Bi ^((~Bo)& Bu ); \ - Ago1 = Bo ^((~Bu)& Ba ); \ - Agu1 = Bu ^((~Ba)& Be ); \ -\ - Ebe0 ^= De0; \ - Ba = Ebe0; \ - Egi1 ^= Di1; \ - Be = ROL32(Egi1, 3); \ - Eko0 ^= Do0; \ - Bi = ROL32(Eko0, 12); \ - Emu1 ^= Du1; \ - Bo = ROL32(Emu1, 4); \ - Esa1 ^= Da1; \ - Bu = ROL32(Esa1, 9); \ - Aka1 = Ba ^((~Be)& Bi ); \ - Ake1 = Be ^((~Bi)& Bo ); \ - Aki1 = Bi ^((~Bo)& Bu ); \ - Ako1 = Bo ^((~Bu)& Ba ); \ - Aku1 = Bu ^((~Ba)& Be ); \ -\ - Ebu0 ^= Du0; \ - Ba = ROL32(Ebu0, 13); \ - Ega1 ^= Da1; \ - Be = ROL32(Ega1, 18); \ - Eke1 ^= De1; \ - Bi = ROL32(Eke1, 5); \ - Emi0 ^= Di0; \ - Bo = ROL32(Emi0, 7); \ - Eso1 ^= Do1; \ - Bu = ROL32(Eso1, 28); \ - Ama1 = Ba ^((~Be)& Bi ); \ - Ame1 = Be ^((~Bi)& Bo ); \ - Ami1 = Bi ^((~Bo)& Bu ); \ - Amo1 = Bo ^((~Bu)& Ba ); \ - Amu1 = Bu ^((~Ba)& Be ); \ -\ - Ebi1 ^= Di1; \ - Ba = ROL32(Ebi1, 31); \ - Ego0 ^= Do0; \ - Be = ROL32(Ego0, 27); \ - Eku0 ^= Du0; \ - Bi = ROL32(Eku0, 19); \ - Ema0 ^= Da0; \ - Bo = ROL32(Ema0, 20); \ - Ese1 ^= De1; \ - Bu = ROL32(Ese1, 1); \ - Asa1 = Ba ^((~Be)& Bi ); \ - Ase1 = Be ^((~Bi)& Bo ); \ - Asi1 = Bi ^((~Bo)& Bu ); \ - Aso1 = Bo ^((~Bu)& Ba ); \ - Asu1 = Bu ^((~Ba)& Be ); \ - } \ - copyToState(state, A) \ -} - -#define copyFromState(X, state) \ - X##ba0 = state[ 0]; \ - X##ba1 = state[ 1]; \ - X##be0 = state[ 2]; \ - X##be1 = state[ 3]; \ - X##bi0 = state[ 4]; \ - X##bi1 = state[ 5]; \ - X##bo0 = state[ 6]; \ - X##bo1 = state[ 7]; \ - X##bu0 = state[ 8]; \ - X##bu1 = state[ 9]; \ - X##ga0 = state[10]; \ - X##ga1 = state[11]; \ - X##ge0 = state[12]; \ - X##ge1 = state[13]; \ - X##gi0 = state[14]; \ - X##gi1 = state[15]; \ - X##go0 = state[16]; \ - X##go1 = state[17]; \ - X##gu0 = state[18]; \ - X##gu1 = state[19]; \ - X##ka0 = state[20]; \ - X##ka1 = state[21]; \ - X##ke0 = state[22]; \ - X##ke1 = state[23]; \ - X##ki0 = state[24]; \ - X##ki1 = state[25]; \ - X##ko0 = state[26]; \ - X##ko1 = state[27]; \ - X##ku0 = state[28]; \ - X##ku1 = state[29]; \ - X##ma0 = state[30]; \ - X##ma1 = state[31]; \ - X##me0 = state[32]; \ - X##me1 = state[33]; \ - X##mi0 = state[34]; \ - X##mi1 = state[35]; \ - X##mo0 = state[36]; \ - X##mo1 = state[37]; \ - X##mu0 = state[38]; \ - X##mu1 = state[39]; \ - X##sa0 = state[40]; \ - X##sa1 = state[41]; \ - X##se0 = state[42]; \ - X##se1 = state[43]; \ - X##si0 = state[44]; \ - X##si1 = state[45]; \ - X##so0 = state[46]; \ - X##so1 = state[47]; \ - X##su0 = state[48]; \ - X##su1 = state[49]; \ - -#define copyToState(state, X) \ - state[ 0] = X##ba0; \ - state[ 1] = X##ba1; \ - state[ 2] = X##be0; \ - state[ 3] = X##be1; \ - state[ 4] = X##bi0; \ - state[ 5] = X##bi1; \ - state[ 6] = X##bo0; \ - state[ 7] = X##bo1; \ - state[ 8] = X##bu0; \ - state[ 9] = X##bu1; \ - state[10] = X##ga0; \ - state[11] = X##ga1; \ - state[12] = X##ge0; \ - state[13] = X##ge1; \ - state[14] = X##gi0; \ - state[15] = X##gi1; \ - state[16] = X##go0; \ - state[17] = X##go1; \ - state[18] = X##gu0; \ - state[19] = X##gu1; \ - state[20] = X##ka0; \ - state[21] = X##ka1; \ - state[22] = X##ke0; \ - state[23] = X##ke1; \ - state[24] = X##ki0; \ - state[25] = X##ki1; \ - state[26] = X##ko0; \ - state[27] = X##ko1; \ - state[28] = X##ku0; \ - state[29] = X##ku1; \ - state[30] = X##ma0; \ - state[31] = X##ma1; \ - state[32] = X##me0; \ - state[33] = X##me1; \ - state[34] = X##mi0; \ - state[35] = X##mi1; \ - state[36] = X##mo0; \ - state[37] = X##mo1; \ - state[38] = X##mu0; \ - state[39] = X##mu1; \ - state[40] = X##sa0; \ - state[41] = X##sa1; \ - state[42] = X##se0; \ - state[43] = X##se1; \ - state[44] = X##si0; \ - state[45] = X##si1; \ - state[46] = X##so0; \ - state[47] = X##so1; \ - state[48] = X##su0; \ - state[49] = X##su1; \ - diff --git a/Modules/_sha3/keccak/KeccakF-1600-32-s1.macros b/Modules/_sha3/keccak/KeccakF-1600-32-s1.macros deleted file mode 100644 index 373d61df6e66..000000000000 --- a/Modules/_sha3/keccak/KeccakF-1600-32-s1.macros +++ /dev/null @@ -1,1187 +0,0 @@ -/* -Code automatically generated by KeccakTools! - -The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, -Michaël Peeters and Gilles Van Assche. For more information, feedback or -questions, please refer to our website: http://keccak.noekeon.org/ - -Implementation by the designers, -hereby denoted as "the implementer". - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#define declareABCDE \ - UINT32 Aba0, Abe0, Abi0, Abo0, Abu0; \ - UINT32 Aba1, Abe1, Abi1, Abo1, Abu1; \ - UINT32 Aga0, Age0, Agi0, Ago0, Agu0; \ - UINT32 Aga1, Age1, Agi1, Ago1, Agu1; \ - UINT32 Aka0, Ake0, Aki0, Ako0, Aku0; \ - UINT32 Aka1, Ake1, Aki1, Ako1, Aku1; \ - UINT32 Ama0, Ame0, Ami0, Amo0, Amu0; \ - UINT32 Ama1, Ame1, Ami1, Amo1, Amu1; \ - UINT32 Asa0, Ase0, Asi0, Aso0, Asu0; \ - UINT32 Asa1, Ase1, Asi1, Aso1, Asu1; \ - UINT32 Bba0, Bbe0, Bbi0, Bbo0, Bbu0; \ - UINT32 Bba1, Bbe1, Bbi1, Bbo1, Bbu1; \ - UINT32 Bga0, Bge0, Bgi0, Bgo0, Bgu0; \ - UINT32 Bga1, Bge1, Bgi1, Bgo1, Bgu1; \ - UINT32 Bka0, Bke0, Bki0, Bko0, Bku0; \ - UINT32 Bka1, Bke1, Bki1, Bko1, Bku1; \ - UINT32 Bma0, Bme0, Bmi0, Bmo0, Bmu0; \ - UINT32 Bma1, Bme1, Bmi1, Bmo1, Bmu1; \ - UINT32 Bsa0, Bse0, Bsi0, Bso0, Bsu0; \ - UINT32 Bsa1, Bse1, Bsi1, Bso1, Bsu1; \ - UINT32 Ca0, Ce0, Ci0, Co0, Cu0; \ - UINT32 Ca1, Ce1, Ci1, Co1, Cu1; \ - UINT32 Da0, De0, Di0, Do0, Du0; \ - UINT32 Da1, De1, Di1, Do1, Du1; \ - UINT32 Eba0, Ebe0, Ebi0, Ebo0, Ebu0; \ - UINT32 Eba1, Ebe1, Ebi1, Ebo1, Ebu1; \ - UINT32 Ega0, Ege0, Egi0, Ego0, Egu0; \ - UINT32 Ega1, Ege1, Egi1, Ego1, Egu1; \ - UINT32 Eka0, Eke0, Eki0, Eko0, Eku0; \ - UINT32 Eka1, Eke1, Eki1, Eko1, Eku1; \ - UINT32 Ema0, Eme0, Emi0, Emo0, Emu0; \ - UINT32 Ema1, Eme1, Emi1, Emo1, Emu1; \ - UINT32 Esa0, Ese0, Esi0, Eso0, Esu0; \ - UINT32 Esa1, Ese1, Esi1, Eso1, Esu1; \ - -#define prepareTheta \ - Ca0 = Aba0^Aga0^Aka0^Ama0^Asa0; \ - Ca1 = Aba1^Aga1^Aka1^Ama1^Asa1; \ - Ce0 = Abe0^Age0^Ake0^Ame0^Ase0; \ - Ce1 = Abe1^Age1^Ake1^Ame1^Ase1; \ - Ci0 = Abi0^Agi0^Aki0^Ami0^Asi0; \ - Ci1 = Abi1^Agi1^Aki1^Ami1^Asi1; \ - Co0 = Abo0^Ago0^Ako0^Amo0^Aso0; \ - Co1 = Abo1^Ago1^Ako1^Amo1^Aso1; \ - Cu0 = Abu0^Agu0^Aku0^Amu0^Asu0; \ - Cu1 = Abu1^Agu1^Aku1^Amu1^Asu1; \ - -#ifdef UseBebigokimisa -/* --- Code for round, with prepare-theta (lane complementing pattern 'bebigokimisa') */ -/* --- using factor 2 interleaving, 64-bit lanes mapped to 32-bit words */ -#define thetaRhoPiChiIotaPrepareTheta(i, A, E) \ - Da0 = Cu0^ROL32(Ce1, 1); \ - Da1 = Cu1^Ce0; \ - De0 = Ca0^ROL32(Ci1, 1); \ - De1 = Ca1^Ci0; \ - Di0 = Ce0^ROL32(Co1, 1); \ - Di1 = Ce1^Co0; \ - Do0 = Ci0^ROL32(Cu1, 1); \ - Do1 = Ci1^Cu0; \ - Du0 = Co0^ROL32(Ca1, 1); \ - Du1 = Co1^Ca0; \ -\ - A##ba0 ^= Da0; \ - Bba0 = A##ba0; \ - A##ge0 ^= De0; \ - Bbe0 = ROL32(A##ge0, 22); \ - A##ki1 ^= Di1; \ - Bbi0 = ROL32(A##ki1, 22); \ - A##mo1 ^= Do1; \ - Bbo0 = ROL32(A##mo1, 11); \ - A##su0 ^= Du0; \ - Bbu0 = ROL32(A##su0, 7); \ - E##ba0 = Bba0 ^( Bbe0 | Bbi0 ); \ - E##ba0 ^= KeccakF1600RoundConstants_int2_0[i]; \ - Ca0 = E##ba0; \ - E##be0 = Bbe0 ^((~Bbi0)| Bbo0 ); \ - Ce0 = E##be0; \ - E##bi0 = Bbi0 ^( Bbo0 & Bbu0 ); \ - Ci0 = E##bi0; \ - E##bo0 = Bbo0 ^( Bbu0 | Bba0 ); \ - Co0 = E##bo0; \ - E##bu0 = Bbu0 ^( Bba0 & Bbe0 ); \ - Cu0 = E##bu0; \ -\ - A##ba1 ^= Da1; \ - Bba1 = A##ba1; \ - A##ge1 ^= De1; \ - Bbe1 = ROL32(A##ge1, 22); \ - A##ki0 ^= Di0; \ - Bbi1 = ROL32(A##ki0, 21); \ - A##mo0 ^= Do0; \ - Bbo1 = ROL32(A##mo0, 10); \ - A##su1 ^= Du1; \ - Bbu1 = ROL32(A##su1, 7); \ - E##ba1 = Bba1 ^( Bbe1 | Bbi1 ); \ - E##ba1 ^= KeccakF1600RoundConstants_int2_1[i]; \ - Ca1 = E##ba1; \ - E##be1 = Bbe1 ^((~Bbi1)| Bbo1 ); \ - Ce1 = E##be1; \ - E##bi1 = Bbi1 ^( Bbo1 & Bbu1 ); \ - Ci1 = E##bi1; \ - E##bo1 = Bbo1 ^( Bbu1 | Bba1 ); \ - Co1 = E##bo1; \ - E##bu1 = Bbu1 ^( Bba1 & Bbe1 ); \ - Cu1 = E##bu1; \ -\ - A##bo0 ^= Do0; \ - Bga0 = ROL32(A##bo0, 14); \ - A##gu0 ^= Du0; \ - Bge0 = ROL32(A##gu0, 10); \ - A##ka1 ^= Da1; \ - Bgi0 = ROL32(A##ka1, 2); \ - A##me1 ^= De1; \ - Bgo0 = ROL32(A##me1, 23); \ - A##si1 ^= Di1; \ - Bgu0 = ROL32(A##si1, 31); \ - E##ga0 = Bga0 ^( Bge0 | Bgi0 ); \ - Ca0 ^= E##ga0; \ - E##ge0 = Bge0 ^( Bgi0 & Bgo0 ); \ - Ce0 ^= E##ge0; \ - E##gi0 = Bgi0 ^( Bgo0 |(~Bgu0)); \ - Ci0 ^= E##gi0; \ - E##go0 = Bgo0 ^( Bgu0 | Bga0 ); \ - Co0 ^= E##go0; \ - E##gu0 = Bgu0 ^( Bga0 & Bge0 ); \ - Cu0 ^= E##gu0; \ -\ - A##bo1 ^= Do1; \ - Bga1 = ROL32(A##bo1, 14); \ - A##gu1 ^= Du1; \ - Bge1 = ROL32(A##gu1, 10); \ - A##ka0 ^= Da0; \ - Bgi1 = ROL32(A##ka0, 1); \ - A##me0 ^= De0; \ - Bgo1 = ROL32(A##me0, 22); \ - A##si0 ^= Di0; \ - Bgu1 = ROL32(A##si0, 30); \ - E##ga1 = Bga1 ^( Bge1 | Bgi1 ); \ - Ca1 ^= E##ga1; \ - E##ge1 = Bge1 ^( Bgi1 & Bgo1 ); \ - Ce1 ^= E##ge1; \ - E##gi1 = Bgi1 ^( Bgo1 |(~Bgu1)); \ - Ci1 ^= E##gi1; \ - E##go1 = Bgo1 ^( Bgu1 | Bga1 ); \ - Co1 ^= E##go1; \ - E##gu1 = Bgu1 ^( Bga1 & Bge1 ); \ - Cu1 ^= E##gu1; \ -\ - A##be1 ^= De1; \ - Bka0 = ROL32(A##be1, 1); \ - A##gi0 ^= Di0; \ - Bke0 = ROL32(A##gi0, 3); \ - A##ko1 ^= Do1; \ - Bki0 = ROL32(A##ko1, 13); \ - A##mu0 ^= Du0; \ - Bko0 = ROL32(A##mu0, 4); \ - A##sa0 ^= Da0; \ - Bku0 = ROL32(A##sa0, 9); \ - E##ka0 = Bka0 ^( Bke0 | Bki0 ); \ - Ca0 ^= E##ka0; \ - E##ke0 = Bke0 ^( Bki0 & Bko0 ); \ - Ce0 ^= E##ke0; \ - E##ki0 = Bki0 ^((~Bko0)& Bku0 ); \ - Ci0 ^= E##ki0; \ - E##ko0 = (~Bko0)^( Bku0 | Bka0 ); \ - Co0 ^= E##ko0; \ - E##ku0 = Bku0 ^( Bka0 & Bke0 ); \ - Cu0 ^= E##ku0; \ -\ - A##be0 ^= De0; \ - Bka1 = A##be0; \ - A##gi1 ^= Di1; \ - Bke1 = ROL32(A##gi1, 3); \ - A##ko0 ^= Do0; \ - Bki1 = ROL32(A##ko0, 12); \ - A##mu1 ^= Du1; \ - Bko1 = ROL32(A##mu1, 4); \ - A##sa1 ^= Da1; \ - Bku1 = ROL32(A##sa1, 9); \ - E##ka1 = Bka1 ^( Bke1 | Bki1 ); \ - Ca1 ^= E##ka1; \ - E##ke1 = Bke1 ^( Bki1 & Bko1 ); \ - Ce1 ^= E##ke1; \ - E##ki1 = Bki1 ^((~Bko1)& Bku1 ); \ - Ci1 ^= E##ki1; \ - E##ko1 = (~Bko1)^( Bku1 | Bka1 ); \ - Co1 ^= E##ko1; \ - E##ku1 = Bku1 ^( Bka1 & Bke1 ); \ - Cu1 ^= E##ku1; \ -\ - A##bu1 ^= Du1; \ - Bma0 = ROL32(A##bu1, 14); \ - A##ga0 ^= Da0; \ - Bme0 = ROL32(A##ga0, 18); \ - A##ke0 ^= De0; \ - Bmi0 = ROL32(A##ke0, 5); \ - A##mi1 ^= Di1; \ - Bmo0 = ROL32(A##mi1, 8); \ - A##so0 ^= Do0; \ - Bmu0 = ROL32(A##so0, 28); \ - E##ma0 = Bma0 ^( Bme0 & Bmi0 ); \ - Ca0 ^= E##ma0; \ - E##me0 = Bme0 ^( Bmi0 | Bmo0 ); \ - Ce0 ^= E##me0; \ - E##mi0 = Bmi0 ^((~Bmo0)| Bmu0 ); \ - Ci0 ^= E##mi0; \ - E##mo0 = (~Bmo0)^( Bmu0 & Bma0 ); \ - Co0 ^= E##mo0; \ - E##mu0 = Bmu0 ^( Bma0 | Bme0 ); \ - Cu0 ^= E##mu0; \ -\ - A##bu0 ^= Du0; \ - Bma1 = ROL32(A##bu0, 13); \ - A##ga1 ^= Da1; \ - Bme1 = ROL32(A##ga1, 18); \ - A##ke1 ^= De1; \ - Bmi1 = ROL32(A##ke1, 5); \ - A##mi0 ^= Di0; \ - Bmo1 = ROL32(A##mi0, 7); \ - A##so1 ^= Do1; \ - Bmu1 = ROL32(A##so1, 28); \ - E##ma1 = Bma1 ^( Bme1 & Bmi1 ); \ - Ca1 ^= E##ma1; \ - E##me1 = Bme1 ^( Bmi1 | Bmo1 ); \ - Ce1 ^= E##me1; \ - E##mi1 = Bmi1 ^((~Bmo1)| Bmu1 ); \ - Ci1 ^= E##mi1; \ - E##mo1 = (~Bmo1)^( Bmu1 & Bma1 ); \ - Co1 ^= E##mo1; \ - E##mu1 = Bmu1 ^( Bma1 | Bme1 ); \ - Cu1 ^= E##mu1; \ -\ - A##bi0 ^= Di0; \ - Bsa0 = ROL32(A##bi0, 31); \ - A##go1 ^= Do1; \ - Bse0 = ROL32(A##go1, 28); \ - A##ku1 ^= Du1; \ - Bsi0 = ROL32(A##ku1, 20); \ - A##ma1 ^= Da1; \ - Bso0 = ROL32(A##ma1, 21); \ - A##se0 ^= De0; \ - Bsu0 = ROL32(A##se0, 1); \ - E##sa0 = Bsa0 ^((~Bse0)& Bsi0 ); \ - Ca0 ^= E##sa0; \ - E##se0 = (~Bse0)^( Bsi0 | Bso0 ); \ - Ce0 ^= E##se0; \ - E##si0 = Bsi0 ^( Bso0 & Bsu0 ); \ - Ci0 ^= E##si0; \ - E##so0 = Bso0 ^( Bsu0 | Bsa0 ); \ - Co0 ^= E##so0; \ - E##su0 = Bsu0 ^( Bsa0 & Bse0 ); \ - Cu0 ^= E##su0; \ -\ - A##bi1 ^= Di1; \ - Bsa1 = ROL32(A##bi1, 31); \ - A##go0 ^= Do0; \ - Bse1 = ROL32(A##go0, 27); \ - A##ku0 ^= Du0; \ - Bsi1 = ROL32(A##ku0, 19); \ - A##ma0 ^= Da0; \ - Bso1 = ROL32(A##ma0, 20); \ - A##se1 ^= De1; \ - Bsu1 = ROL32(A##se1, 1); \ - E##sa1 = Bsa1 ^((~Bse1)& Bsi1 ); \ - Ca1 ^= E##sa1; \ - E##se1 = (~Bse1)^( Bsi1 | Bso1 ); \ - Ce1 ^= E##se1; \ - E##si1 = Bsi1 ^( Bso1 & Bsu1 ); \ - Ci1 ^= E##si1; \ - E##so1 = Bso1 ^( Bsu1 | Bsa1 ); \ - Co1 ^= E##so1; \ - E##su1 = Bsu1 ^( Bsa1 & Bse1 ); \ - Cu1 ^= E##su1; \ -\ - -/* --- Code for round (lane complementing pattern 'bebigokimisa') */ -/* --- using factor 2 interleaving, 64-bit lanes mapped to 32-bit words */ -#define thetaRhoPiChiIota(i, A, E) \ - Da0 = Cu0^ROL32(Ce1, 1); \ - Da1 = Cu1^Ce0; \ - De0 = Ca0^ROL32(Ci1, 1); \ - De1 = Ca1^Ci0; \ - Di0 = Ce0^ROL32(Co1, 1); \ - Di1 = Ce1^Co0; \ - Do0 = Ci0^ROL32(Cu1, 1); \ - Do1 = Ci1^Cu0; \ - Du0 = Co0^ROL32(Ca1, 1); \ - Du1 = Co1^Ca0; \ -\ - A##ba0 ^= Da0; \ - Bba0 = A##ba0; \ - A##ge0 ^= De0; \ - Bbe0 = ROL32(A##ge0, 22); \ - A##ki1 ^= Di1; \ - Bbi0 = ROL32(A##ki1, 22); \ - A##mo1 ^= Do1; \ - Bbo0 = ROL32(A##mo1, 11); \ - A##su0 ^= Du0; \ - Bbu0 = ROL32(A##su0, 7); \ - E##ba0 = Bba0 ^( Bbe0 | Bbi0 ); \ - E##ba0 ^= KeccakF1600RoundConstants_int2_0[i]; \ - E##be0 = Bbe0 ^((~Bbi0)| Bbo0 ); \ - E##bi0 = Bbi0 ^( Bbo0 & Bbu0 ); \ - E##bo0 = Bbo0 ^( Bbu0 | Bba0 ); \ - E##bu0 = Bbu0 ^( Bba0 & Bbe0 ); \ -\ - A##ba1 ^= Da1; \ - Bba1 = A##ba1; \ - A##ge1 ^= De1; \ - Bbe1 = ROL32(A##ge1, 22); \ - A##ki0 ^= Di0; \ - Bbi1 = ROL32(A##ki0, 21); \ - A##mo0 ^= Do0; \ - Bbo1 = ROL32(A##mo0, 10); \ - A##su1 ^= Du1; \ - Bbu1 = ROL32(A##su1, 7); \ - E##ba1 = Bba1 ^( Bbe1 | Bbi1 ); \ - E##ba1 ^= KeccakF1600RoundConstants_int2_1[i]; \ - E##be1 = Bbe1 ^((~Bbi1)| Bbo1 ); \ - E##bi1 = Bbi1 ^( Bbo1 & Bbu1 ); \ - E##bo1 = Bbo1 ^( Bbu1 | Bba1 ); \ - E##bu1 = Bbu1 ^( Bba1 & Bbe1 ); \ -\ - A##bo0 ^= Do0; \ - Bga0 = ROL32(A##bo0, 14); \ - A##gu0 ^= Du0; \ - Bge0 = ROL32(A##gu0, 10); \ - A##ka1 ^= Da1; \ - Bgi0 = ROL32(A##ka1, 2); \ - A##me1 ^= De1; \ - Bgo0 = ROL32(A##me1, 23); \ - A##si1 ^= Di1; \ - Bgu0 = ROL32(A##si1, 31); \ - E##ga0 = Bga0 ^( Bge0 | Bgi0 ); \ - E##ge0 = Bge0 ^( Bgi0 & Bgo0 ); \ - E##gi0 = Bgi0 ^( Bgo0 |(~Bgu0)); \ - E##go0 = Bgo0 ^( Bgu0 | Bga0 ); \ - E##gu0 = Bgu0 ^( Bga0 & Bge0 ); \ -\ - A##bo1 ^= Do1; \ - Bga1 = ROL32(A##bo1, 14); \ - A##gu1 ^= Du1; \ - Bge1 = ROL32(A##gu1, 10); \ - A##ka0 ^= Da0; \ - Bgi1 = ROL32(A##ka0, 1); \ - A##me0 ^= De0; \ - Bgo1 = ROL32(A##me0, 22); \ - A##si0 ^= Di0; \ - Bgu1 = ROL32(A##si0, 30); \ - E##ga1 = Bga1 ^( Bge1 | Bgi1 ); \ - E##ge1 = Bge1 ^( Bgi1 & Bgo1 ); \ - E##gi1 = Bgi1 ^( Bgo1 |(~Bgu1)); \ - E##go1 = Bgo1 ^( Bgu1 | Bga1 ); \ - E##gu1 = Bgu1 ^( Bga1 & Bge1 ); \ -\ - A##be1 ^= De1; \ - Bka0 = ROL32(A##be1, 1); \ - A##gi0 ^= Di0; \ - Bke0 = ROL32(A##gi0, 3); \ - A##ko1 ^= Do1; \ - Bki0 = ROL32(A##ko1, 13); \ - A##mu0 ^= Du0; \ - Bko0 = ROL32(A##mu0, 4); \ - A##sa0 ^= Da0; \ - Bku0 = ROL32(A##sa0, 9); \ - E##ka0 = Bka0 ^( Bke0 | Bki0 ); \ - E##ke0 = Bke0 ^( Bki0 & Bko0 ); \ - E##ki0 = Bki0 ^((~Bko0)& Bku0 ); \ - E##ko0 = (~Bko0)^( Bku0 | Bka0 ); \ - E##ku0 = Bku0 ^( Bka0 & Bke0 ); \ -\ - A##be0 ^= De0; \ - Bka1 = A##be0; \ - A##gi1 ^= Di1; \ - Bke1 = ROL32(A##gi1, 3); \ - A##ko0 ^= Do0; \ - Bki1 = ROL32(A##ko0, 12); \ - A##mu1 ^= Du1; \ - Bko1 = ROL32(A##mu1, 4); \ - A##sa1 ^= Da1; \ - Bku1 = ROL32(A##sa1, 9); \ - E##ka1 = Bka1 ^( Bke1 | Bki1 ); \ - E##ke1 = Bke1 ^( Bki1 & Bko1 ); \ - E##ki1 = Bki1 ^((~Bko1)& Bku1 ); \ - E##ko1 = (~Bko1)^( Bku1 | Bka1 ); \ - E##ku1 = Bku1 ^( Bka1 & Bke1 ); \ -\ - A##bu1 ^= Du1; \ - Bma0 = ROL32(A##bu1, 14); \ - A##ga0 ^= Da0; \ - Bme0 = ROL32(A##ga0, 18); \ - A##ke0 ^= De0; \ - Bmi0 = ROL32(A##ke0, 5); \ - A##mi1 ^= Di1; \ - Bmo0 = ROL32(A##mi1, 8); \ - A##so0 ^= Do0; \ - Bmu0 = ROL32(A##so0, 28); \ - E##ma0 = Bma0 ^( Bme0 & Bmi0 ); \ - E##me0 = Bme0 ^( Bmi0 | Bmo0 ); \ - E##mi0 = Bmi0 ^((~Bmo0)| Bmu0 ); \ - E##mo0 = (~Bmo0)^( Bmu0 & Bma0 ); \ - E##mu0 = Bmu0 ^( Bma0 | Bme0 ); \ -\ - A##bu0 ^= Du0; \ - Bma1 = ROL32(A##bu0, 13); \ - A##ga1 ^= Da1; \ - Bme1 = ROL32(A##ga1, 18); \ - A##ke1 ^= De1; \ - Bmi1 = ROL32(A##ke1, 5); \ - A##mi0 ^= Di0; \ - Bmo1 = ROL32(A##mi0, 7); \ - A##so1 ^= Do1; \ - Bmu1 = ROL32(A##so1, 28); \ - E##ma1 = Bma1 ^( Bme1 & Bmi1 ); \ - E##me1 = Bme1 ^( Bmi1 | Bmo1 ); \ - E##mi1 = Bmi1 ^((~Bmo1)| Bmu1 ); \ - E##mo1 = (~Bmo1)^( Bmu1 & Bma1 ); \ - E##mu1 = Bmu1 ^( Bma1 | Bme1 ); \ -\ - A##bi0 ^= Di0; \ - Bsa0 = ROL32(A##bi0, 31); \ - A##go1 ^= Do1; \ - Bse0 = ROL32(A##go1, 28); \ - A##ku1 ^= Du1; \ - Bsi0 = ROL32(A##ku1, 20); \ - A##ma1 ^= Da1; \ - Bso0 = ROL32(A##ma1, 21); \ - A##se0 ^= De0; \ - Bsu0 = ROL32(A##se0, 1); \ - E##sa0 = Bsa0 ^((~Bse0)& Bsi0 ); \ - E##se0 = (~Bse0)^( Bsi0 | Bso0 ); \ - E##si0 = Bsi0 ^( Bso0 & Bsu0 ); \ - E##so0 = Bso0 ^( Bsu0 | Bsa0 ); \ - E##su0 = Bsu0 ^( Bsa0 & Bse0 ); \ -\ - A##bi1 ^= Di1; \ - Bsa1 = ROL32(A##bi1, 31); \ - A##go0 ^= Do0; \ - Bse1 = ROL32(A##go0, 27); \ - A##ku0 ^= Du0; \ - Bsi1 = ROL32(A##ku0, 19); \ - A##ma0 ^= Da0; \ - Bso1 = ROL32(A##ma0, 20); \ - A##se1 ^= De1; \ - Bsu1 = ROL32(A##se1, 1); \ - E##sa1 = Bsa1 ^((~Bse1)& Bsi1 ); \ - E##se1 = (~Bse1)^( Bsi1 | Bso1 ); \ - E##si1 = Bsi1 ^( Bso1 & Bsu1 ); \ - E##so1 = Bso1 ^( Bsu1 | Bsa1 ); \ - E##su1 = Bsu1 ^( Bsa1 & Bse1 ); \ -\ - -#else /* UseBebigokimisa */ -/* --- Code for round, with prepare-theta */ -/* --- using factor 2 interleaving, 64-bit lanes mapped to 32-bit words */ -#define thetaRhoPiChiIotaPrepareTheta(i, A, E) \ - Da0 = Cu0^ROL32(Ce1, 1); \ - Da1 = Cu1^Ce0; \ - De0 = Ca0^ROL32(Ci1, 1); \ - De1 = Ca1^Ci0; \ - Di0 = Ce0^ROL32(Co1, 1); \ - Di1 = Ce1^Co0; \ - Do0 = Ci0^ROL32(Cu1, 1); \ - Do1 = Ci1^Cu0; \ - Du0 = Co0^ROL32(Ca1, 1); \ - Du1 = Co1^Ca0; \ -\ - A##ba0 ^= Da0; \ - Bba0 = A##ba0; \ - A##ge0 ^= De0; \ - Bbe0 = ROL32(A##ge0, 22); \ - A##ki1 ^= Di1; \ - Bbi0 = ROL32(A##ki1, 22); \ - A##mo1 ^= Do1; \ - Bbo0 = ROL32(A##mo1, 11); \ - A##su0 ^= Du0; \ - Bbu0 = ROL32(A##su0, 7); \ - E##ba0 = Bba0 ^((~Bbe0)& Bbi0 ); \ - E##ba0 ^= KeccakF1600RoundConstants_int2_0[i]; \ - Ca0 = E##ba0; \ - E##be0 = Bbe0 ^((~Bbi0)& Bbo0 ); \ - Ce0 = E##be0; \ - E##bi0 = Bbi0 ^((~Bbo0)& Bbu0 ); \ - Ci0 = E##bi0; \ - E##bo0 = Bbo0 ^((~Bbu0)& Bba0 ); \ - Co0 = E##bo0; \ - E##bu0 = Bbu0 ^((~Bba0)& Bbe0 ); \ - Cu0 = E##bu0; \ -\ - A##ba1 ^= Da1; \ - Bba1 = A##ba1; \ - A##ge1 ^= De1; \ - Bbe1 = ROL32(A##ge1, 22); \ - A##ki0 ^= Di0; \ - Bbi1 = ROL32(A##ki0, 21); \ - A##mo0 ^= Do0; \ - Bbo1 = ROL32(A##mo0, 10); \ - A##su1 ^= Du1; \ - Bbu1 = ROL32(A##su1, 7); \ - E##ba1 = Bba1 ^((~Bbe1)& Bbi1 ); \ - E##ba1 ^= KeccakF1600RoundConstants_int2_1[i]; \ - Ca1 = E##ba1; \ - E##be1 = Bbe1 ^((~Bbi1)& Bbo1 ); \ - Ce1 = E##be1; \ - E##bi1 = Bbi1 ^((~Bbo1)& Bbu1 ); \ - Ci1 = E##bi1; \ - E##bo1 = Bbo1 ^((~Bbu1)& Bba1 ); \ - Co1 = E##bo1; \ - E##bu1 = Bbu1 ^((~Bba1)& Bbe1 ); \ - Cu1 = E##bu1; \ -\ - A##bo0 ^= Do0; \ - Bga0 = ROL32(A##bo0, 14); \ - A##gu0 ^= Du0; \ - Bge0 = ROL32(A##gu0, 10); \ - A##ka1 ^= Da1; \ - Bgi0 = ROL32(A##ka1, 2); \ - A##me1 ^= De1; \ - Bgo0 = ROL32(A##me1, 23); \ - A##si1 ^= Di1; \ - Bgu0 = ROL32(A##si1, 31); \ - E##ga0 = Bga0 ^((~Bge0)& Bgi0 ); \ - Ca0 ^= E##ga0; \ - E##ge0 = Bge0 ^((~Bgi0)& Bgo0 ); \ - Ce0 ^= E##ge0; \ - E##gi0 = Bgi0 ^((~Bgo0)& Bgu0 ); \ - Ci0 ^= E##gi0; \ - E##go0 = Bgo0 ^((~Bgu0)& Bga0 ); \ - Co0 ^= E##go0; \ - E##gu0 = Bgu0 ^((~Bga0)& Bge0 ); \ - Cu0 ^= E##gu0; \ -\ - A##bo1 ^= Do1; \ - Bga1 = ROL32(A##bo1, 14); \ - A##gu1 ^= Du1; \ - Bge1 = ROL32(A##gu1, 10); \ - A##ka0 ^= Da0; \ - Bgi1 = ROL32(A##ka0, 1); \ - A##me0 ^= De0; \ - Bgo1 = ROL32(A##me0, 22); \ - A##si0 ^= Di0; \ - Bgu1 = ROL32(A##si0, 30); \ - E##ga1 = Bga1 ^((~Bge1)& Bgi1 ); \ - Ca1 ^= E##ga1; \ - E##ge1 = Bge1 ^((~Bgi1)& Bgo1 ); \ - Ce1 ^= E##ge1; \ - E##gi1 = Bgi1 ^((~Bgo1)& Bgu1 ); \ - Ci1 ^= E##gi1; \ - E##go1 = Bgo1 ^((~Bgu1)& Bga1 ); \ - Co1 ^= E##go1; \ - E##gu1 = Bgu1 ^((~Bga1)& Bge1 ); \ - Cu1 ^= E##gu1; \ -\ - A##be1 ^= De1; \ - Bka0 = ROL32(A##be1, 1); \ - A##gi0 ^= Di0; \ - Bke0 = ROL32(A##gi0, 3); \ - A##ko1 ^= Do1; \ - Bki0 = ROL32(A##ko1, 13); \ - A##mu0 ^= Du0; \ - Bko0 = ROL32(A##mu0, 4); \ - A##sa0 ^= Da0; \ - Bku0 = ROL32(A##sa0, 9); \ - E##ka0 = Bka0 ^((~Bke0)& Bki0 ); \ - Ca0 ^= E##ka0; \ - E##ke0 = Bke0 ^((~Bki0)& Bko0 ); \ - Ce0 ^= E##ke0; \ - E##ki0 = Bki0 ^((~Bko0)& Bku0 ); \ - Ci0 ^= E##ki0; \ - E##ko0 = Bko0 ^((~Bku0)& Bka0 ); \ - Co0 ^= E##ko0; \ - E##ku0 = Bku0 ^((~Bka0)& Bke0 ); \ - Cu0 ^= E##ku0; \ -\ - A##be0 ^= De0; \ - Bka1 = A##be0; \ - A##gi1 ^= Di1; \ - Bke1 = ROL32(A##gi1, 3); \ - A##ko0 ^= Do0; \ - Bki1 = ROL32(A##ko0, 12); \ - A##mu1 ^= Du1; \ - Bko1 = ROL32(A##mu1, 4); \ - A##sa1 ^= Da1; \ - Bku1 = ROL32(A##sa1, 9); \ - E##ka1 = Bka1 ^((~Bke1)& Bki1 ); \ - Ca1 ^= E##ka1; \ - E##ke1 = Bke1 ^((~Bki1)& Bko1 ); \ - Ce1 ^= E##ke1; \ - E##ki1 = Bki1 ^((~Bko1)& Bku1 ); \ - Ci1 ^= E##ki1; \ - E##ko1 = Bko1 ^((~Bku1)& Bka1 ); \ - Co1 ^= E##ko1; \ - E##ku1 = Bku1 ^((~Bka1)& Bke1 ); \ - Cu1 ^= E##ku1; \ -\ - A##bu1 ^= Du1; \ - Bma0 = ROL32(A##bu1, 14); \ - A##ga0 ^= Da0; \ - Bme0 = ROL32(A##ga0, 18); \ - A##ke0 ^= De0; \ - Bmi0 = ROL32(A##ke0, 5); \ - A##mi1 ^= Di1; \ - Bmo0 = ROL32(A##mi1, 8); \ - A##so0 ^= Do0; \ - Bmu0 = ROL32(A##so0, 28); \ - E##ma0 = Bma0 ^((~Bme0)& Bmi0 ); \ - Ca0 ^= E##ma0; \ - E##me0 = Bme0 ^((~Bmi0)& Bmo0 ); \ - Ce0 ^= E##me0; \ - E##mi0 = Bmi0 ^((~Bmo0)& Bmu0 ); \ - Ci0 ^= E##mi0; \ - E##mo0 = Bmo0 ^((~Bmu0)& Bma0 ); \ - Co0 ^= E##mo0; \ - E##mu0 = Bmu0 ^((~Bma0)& Bme0 ); \ - Cu0 ^= E##mu0; \ -\ - A##bu0 ^= Du0; \ - Bma1 = ROL32(A##bu0, 13); \ - A##ga1 ^= Da1; \ - Bme1 = ROL32(A##ga1, 18); \ - A##ke1 ^= De1; \ - Bmi1 = ROL32(A##ke1, 5); \ - A##mi0 ^= Di0; \ - Bmo1 = ROL32(A##mi0, 7); \ - A##so1 ^= Do1; \ - Bmu1 = ROL32(A##so1, 28); \ - E##ma1 = Bma1 ^((~Bme1)& Bmi1 ); \ - Ca1 ^= E##ma1; \ - E##me1 = Bme1 ^((~Bmi1)& Bmo1 ); \ - Ce1 ^= E##me1; \ - E##mi1 = Bmi1 ^((~Bmo1)& Bmu1 ); \ - Ci1 ^= E##mi1; \ - E##mo1 = Bmo1 ^((~Bmu1)& Bma1 ); \ - Co1 ^= E##mo1; \ - E##mu1 = Bmu1 ^((~Bma1)& Bme1 ); \ - Cu1 ^= E##mu1; \ -\ - A##bi0 ^= Di0; \ - Bsa0 = ROL32(A##bi0, 31); \ - A##go1 ^= Do1; \ - Bse0 = ROL32(A##go1, 28); \ - A##ku1 ^= Du1; \ - Bsi0 = ROL32(A##ku1, 20); \ - A##ma1 ^= Da1; \ - Bso0 = ROL32(A##ma1, 21); \ - A##se0 ^= De0; \ - Bsu0 = ROL32(A##se0, 1); \ - E##sa0 = Bsa0 ^((~Bse0)& Bsi0 ); \ - Ca0 ^= E##sa0; \ - E##se0 = Bse0 ^((~Bsi0)& Bso0 ); \ - Ce0 ^= E##se0; \ - E##si0 = Bsi0 ^((~Bso0)& Bsu0 ); \ - Ci0 ^= E##si0; \ - E##so0 = Bso0 ^((~Bsu0)& Bsa0 ); \ - Co0 ^= E##so0; \ - E##su0 = Bsu0 ^((~Bsa0)& Bse0 ); \ - Cu0 ^= E##su0; \ -\ - A##bi1 ^= Di1; \ - Bsa1 = ROL32(A##bi1, 31); \ - A##go0 ^= Do0; \ - Bse1 = ROL32(A##go0, 27); \ - A##ku0 ^= Du0; \ - Bsi1 = ROL32(A##ku0, 19); \ - A##ma0 ^= Da0; \ - Bso1 = ROL32(A##ma0, 20); \ - A##se1 ^= De1; \ - Bsu1 = ROL32(A##se1, 1); \ - E##sa1 = Bsa1 ^((~Bse1)& Bsi1 ); \ - Ca1 ^= E##sa1; \ - E##se1 = Bse1 ^((~Bsi1)& Bso1 ); \ - Ce1 ^= E##se1; \ - E##si1 = Bsi1 ^((~Bso1)& Bsu1 ); \ - Ci1 ^= E##si1; \ - E##so1 = Bso1 ^((~Bsu1)& Bsa1 ); \ - Co1 ^= E##so1; \ - E##su1 = Bsu1 ^((~Bsa1)& Bse1 ); \ - Cu1 ^= E##su1; \ -\ - -/* --- Code for round */ -/* --- using factor 2 interleaving, 64-bit lanes mapped to 32-bit words */ -#define thetaRhoPiChiIota(i, A, E) \ - Da0 = Cu0^ROL32(Ce1, 1); \ - Da1 = Cu1^Ce0; \ - De0 = Ca0^ROL32(Ci1, 1); \ - De1 = Ca1^Ci0; \ - Di0 = Ce0^ROL32(Co1, 1); \ - Di1 = Ce1^Co0; \ - Do0 = Ci0^ROL32(Cu1, 1); \ - Do1 = Ci1^Cu0; \ - Du0 = Co0^ROL32(Ca1, 1); \ - Du1 = Co1^Ca0; \ -\ - A##ba0 ^= Da0; \ - Bba0 = A##ba0; \ - A##ge0 ^= De0; \ - Bbe0 = ROL32(A##ge0, 22); \ - A##ki1 ^= Di1; \ - Bbi0 = ROL32(A##ki1, 22); \ - A##mo1 ^= Do1; \ - Bbo0 = ROL32(A##mo1, 11); \ - A##su0 ^= Du0; \ - Bbu0 = ROL32(A##su0, 7); \ - E##ba0 = Bba0 ^((~Bbe0)& Bbi0 ); \ - E##ba0 ^= KeccakF1600RoundConstants_int2_0[i]; \ - E##be0 = Bbe0 ^((~Bbi0)& Bbo0 ); \ - E##bi0 = Bbi0 ^((~Bbo0)& Bbu0 ); \ - E##bo0 = Bbo0 ^((~Bbu0)& Bba0 ); \ - E##bu0 = Bbu0 ^((~Bba0)& Bbe0 ); \ -\ - A##ba1 ^= Da1; \ - Bba1 = A##ba1; \ - A##ge1 ^= De1; \ - Bbe1 = ROL32(A##ge1, 22); \ - A##ki0 ^= Di0; \ - Bbi1 = ROL32(A##ki0, 21); \ - A##mo0 ^= Do0; \ - Bbo1 = ROL32(A##mo0, 10); \ - A##su1 ^= Du1; \ - Bbu1 = ROL32(A##su1, 7); \ - E##ba1 = Bba1 ^((~Bbe1)& Bbi1 ); \ - E##ba1 ^= KeccakF1600RoundConstants_int2_1[i]; \ - E##be1 = Bbe1 ^((~Bbi1)& Bbo1 ); \ - E##bi1 = Bbi1 ^((~Bbo1)& Bbu1 ); \ - E##bo1 = Bbo1 ^((~Bbu1)& Bba1 ); \ - E##bu1 = Bbu1 ^((~Bba1)& Bbe1 ); \ -\ - A##bo0 ^= Do0; \ - Bga0 = ROL32(A##bo0, 14); \ - A##gu0 ^= Du0; \ - Bge0 = ROL32(A##gu0, 10); \ - A##ka1 ^= Da1; \ - Bgi0 = ROL32(A##ka1, 2); \ - A##me1 ^= De1; \ - Bgo0 = ROL32(A##me1, 23); \ - A##si1 ^= Di1; \ - Bgu0 = ROL32(A##si1, 31); \ - E##ga0 = Bga0 ^((~Bge0)& Bgi0 ); \ - E##ge0 = Bge0 ^((~Bgi0)& Bgo0 ); \ - E##gi0 = Bgi0 ^((~Bgo0)& Bgu0 ); \ - E##go0 = Bgo0 ^((~Bgu0)& Bga0 ); \ - E##gu0 = Bgu0 ^((~Bga0)& Bge0 ); \ -\ - A##bo1 ^= Do1; \ - Bga1 = ROL32(A##bo1, 14); \ - A##gu1 ^= Du1; \ - Bge1 = ROL32(A##gu1, 10); \ - A##ka0 ^= Da0; \ - Bgi1 = ROL32(A##ka0, 1); \ - A##me0 ^= De0; \ - Bgo1 = ROL32(A##me0, 22); \ - A##si0 ^= Di0; \ - Bgu1 = ROL32(A##si0, 30); \ - E##ga1 = Bga1 ^((~Bge1)& Bgi1 ); \ - E##ge1 = Bge1 ^((~Bgi1)& Bgo1 ); \ - E##gi1 = Bgi1 ^((~Bgo1)& Bgu1 ); \ - E##go1 = Bgo1 ^((~Bgu1)& Bga1 ); \ - E##gu1 = Bgu1 ^((~Bga1)& Bge1 ); \ -\ - A##be1 ^= De1; \ - Bka0 = ROL32(A##be1, 1); \ - A##gi0 ^= Di0; \ - Bke0 = ROL32(A##gi0, 3); \ - A##ko1 ^= Do1; \ - Bki0 = ROL32(A##ko1, 13); \ - A##mu0 ^= Du0; \ - Bko0 = ROL32(A##mu0, 4); \ - A##sa0 ^= Da0; \ - Bku0 = ROL32(A##sa0, 9); \ - E##ka0 = Bka0 ^((~Bke0)& Bki0 ); \ - E##ke0 = Bke0 ^((~Bki0)& Bko0 ); \ - E##ki0 = Bki0 ^((~Bko0)& Bku0 ); \ - E##ko0 = Bko0 ^((~Bku0)& Bka0 ); \ - E##ku0 = Bku0 ^((~Bka0)& Bke0 ); \ -\ - A##be0 ^= De0; \ - Bka1 = A##be0; \ - A##gi1 ^= Di1; \ - Bke1 = ROL32(A##gi1, 3); \ - A##ko0 ^= Do0; \ - Bki1 = ROL32(A##ko0, 12); \ - A##mu1 ^= Du1; \ - Bko1 = ROL32(A##mu1, 4); \ - A##sa1 ^= Da1; \ - Bku1 = ROL32(A##sa1, 9); \ - E##ka1 = Bka1 ^((~Bke1)& Bki1 ); \ - E##ke1 = Bke1 ^((~Bki1)& Bko1 ); \ - E##ki1 = Bki1 ^((~Bko1)& Bku1 ); \ - E##ko1 = Bko1 ^((~Bku1)& Bka1 ); \ - E##ku1 = Bku1 ^((~Bka1)& Bke1 ); \ -\ - A##bu1 ^= Du1; \ - Bma0 = ROL32(A##bu1, 14); \ - A##ga0 ^= Da0; \ - Bme0 = ROL32(A##ga0, 18); \ - A##ke0 ^= De0; \ - Bmi0 = ROL32(A##ke0, 5); \ - A##mi1 ^= Di1; \ - Bmo0 = ROL32(A##mi1, 8); \ - A##so0 ^= Do0; \ - Bmu0 = ROL32(A##so0, 28); \ - E##ma0 = Bma0 ^((~Bme0)& Bmi0 ); \ - E##me0 = Bme0 ^((~Bmi0)& Bmo0 ); \ - E##mi0 = Bmi0 ^((~Bmo0)& Bmu0 ); \ - E##mo0 = Bmo0 ^((~Bmu0)& Bma0 ); \ - E##mu0 = Bmu0 ^((~Bma0)& Bme0 ); \ -\ - A##bu0 ^= Du0; \ - Bma1 = ROL32(A##bu0, 13); \ - A##ga1 ^= Da1; \ - Bme1 = ROL32(A##ga1, 18); \ - A##ke1 ^= De1; \ - Bmi1 = ROL32(A##ke1, 5); \ - A##mi0 ^= Di0; \ - Bmo1 = ROL32(A##mi0, 7); \ - A##so1 ^= Do1; \ - Bmu1 = ROL32(A##so1, 28); \ - E##ma1 = Bma1 ^((~Bme1)& Bmi1 ); \ - E##me1 = Bme1 ^((~Bmi1)& Bmo1 ); \ - E##mi1 = Bmi1 ^((~Bmo1)& Bmu1 ); \ - E##mo1 = Bmo1 ^((~Bmu1)& Bma1 ); \ - E##mu1 = Bmu1 ^((~Bma1)& Bme1 ); \ -\ - A##bi0 ^= Di0; \ - Bsa0 = ROL32(A##bi0, 31); \ - A##go1 ^= Do1; \ - Bse0 = ROL32(A##go1, 28); \ - A##ku1 ^= Du1; \ - Bsi0 = ROL32(A##ku1, 20); \ - A##ma1 ^= Da1; \ - Bso0 = ROL32(A##ma1, 21); \ - A##se0 ^= De0; \ - Bsu0 = ROL32(A##se0, 1); \ - E##sa0 = Bsa0 ^((~Bse0)& Bsi0 ); \ - E##se0 = Bse0 ^((~Bsi0)& Bso0 ); \ - E##si0 = Bsi0 ^((~Bso0)& Bsu0 ); \ - E##so0 = Bso0 ^((~Bsu0)& Bsa0 ); \ - E##su0 = Bsu0 ^((~Bsa0)& Bse0 ); \ -\ - A##bi1 ^= Di1; \ - Bsa1 = ROL32(A##bi1, 31); \ - A##go0 ^= Do0; \ - Bse1 = ROL32(A##go0, 27); \ - A##ku0 ^= Du0; \ - Bsi1 = ROL32(A##ku0, 19); \ - A##ma0 ^= Da0; \ - Bso1 = ROL32(A##ma0, 20); \ - A##se1 ^= De1; \ - Bsu1 = ROL32(A##se1, 1); \ - E##sa1 = Bsa1 ^((~Bse1)& Bsi1 ); \ - E##se1 = Bse1 ^((~Bsi1)& Bso1 ); \ - E##si1 = Bsi1 ^((~Bso1)& Bsu1 ); \ - E##so1 = Bso1 ^((~Bsu1)& Bsa1 ); \ - E##su1 = Bsu1 ^((~Bsa1)& Bse1 ); \ -\ - -#endif /* UseBebigokimisa */ - -const UINT32 KeccakF1600RoundConstants_int2_0[24] = { - 0x00000001UL, - 0x00000000UL, - 0x00000000UL, - 0x00000000UL, - 0x00000001UL, - 0x00000001UL, - 0x00000001UL, - 0x00000001UL, - 0x00000000UL, - 0x00000000UL, - 0x00000001UL, - 0x00000000UL, - 0x00000001UL, - 0x00000001UL, - 0x00000001UL, - 0x00000001UL, - 0x00000000UL, - 0x00000000UL, - 0x00000000UL, - 0x00000000UL, - 0x00000001UL, - 0x00000000UL, - 0x00000001UL, - 0x00000000UL }; - -const UINT32 KeccakF1600RoundConstants_int2_1[24] = { - 0x00000000UL, - 0x00000089UL, - 0x8000008bUL, - 0x80008080UL, - 0x0000008bUL, - 0x00008000UL, - 0x80008088UL, - 0x80000082UL, - 0x0000000bUL, - 0x0000000aUL, - 0x00008082UL, - 0x00008003UL, - 0x0000808bUL, - 0x8000000bUL, - 0x8000008aUL, - 0x80000081UL, - 0x80000081UL, - 0x80000008UL, - 0x00000083UL, - 0x80008003UL, - 0x80008088UL, - 0x80000088UL, - 0x00008000UL, - 0x80008082UL }; - -#define copyFromStateAndXor1024bits(X, state, input) \ - X##ba0 = state[ 0]^input[ 0]; \ - X##ba1 = state[ 1]^input[ 1]; \ - X##be0 = state[ 2]^input[ 2]; \ - X##be1 = state[ 3]^input[ 3]; \ - X##bi0 = state[ 4]^input[ 4]; \ - X##bi1 = state[ 5]^input[ 5]; \ - X##bo0 = state[ 6]^input[ 6]; \ - X##bo1 = state[ 7]^input[ 7]; \ - X##bu0 = state[ 8]^input[ 8]; \ - X##bu1 = state[ 9]^input[ 9]; \ - X##ga0 = state[10]^input[10]; \ - X##ga1 = state[11]^input[11]; \ - X##ge0 = state[12]^input[12]; \ - X##ge1 = state[13]^input[13]; \ - X##gi0 = state[14]^input[14]; \ - X##gi1 = state[15]^input[15]; \ - X##go0 = state[16]^input[16]; \ - X##go1 = state[17]^input[17]; \ - X##gu0 = state[18]^input[18]; \ - X##gu1 = state[19]^input[19]; \ - X##ka0 = state[20]^input[20]; \ - X##ka1 = state[21]^input[21]; \ - X##ke0 = state[22]^input[22]; \ - X##ke1 = state[23]^input[23]; \ - X##ki0 = state[24]^input[24]; \ - X##ki1 = state[25]^input[25]; \ - X##ko0 = state[26]^input[26]; \ - X##ko1 = state[27]^input[27]; \ - X##ku0 = state[28]^input[28]; \ - X##ku1 = state[29]^input[29]; \ - X##ma0 = state[30]^input[30]; \ - X##ma1 = state[31]^input[31]; \ - X##me0 = state[32]; \ - X##me1 = state[33]; \ - X##mi0 = state[34]; \ - X##mi1 = state[35]; \ - X##mo0 = state[36]; \ - X##mo1 = state[37]; \ - X##mu0 = state[38]; \ - X##mu1 = state[39]; \ - X##sa0 = state[40]; \ - X##sa1 = state[41]; \ - X##se0 = state[42]; \ - X##se1 = state[43]; \ - X##si0 = state[44]; \ - X##si1 = state[45]; \ - X##so0 = state[46]; \ - X##so1 = state[47]; \ - X##su0 = state[48]; \ - X##su1 = state[49]; \ - -#define copyFromStateAndXor1088bits(X, state, input) \ - X##ba0 = state[ 0]^input[ 0]; \ - X##ba1 = state[ 1]^input[ 1]; \ - X##be0 = state[ 2]^input[ 2]; \ - X##be1 = state[ 3]^input[ 3]; \ - X##bi0 = state[ 4]^input[ 4]; \ - X##bi1 = state[ 5]^input[ 5]; \ - X##bo0 = state[ 6]^input[ 6]; \ - X##bo1 = state[ 7]^input[ 7]; \ - X##bu0 = state[ 8]^input[ 8]; \ - X##bu1 = state[ 9]^input[ 9]; \ - X##ga0 = state[10]^input[10]; \ - X##ga1 = state[11]^input[11]; \ - X##ge0 = state[12]^input[12]; \ - X##ge1 = state[13]^input[13]; \ - X##gi0 = state[14]^input[14]; \ - X##gi1 = state[15]^input[15]; \ - X##go0 = state[16]^input[16]; \ - X##go1 = state[17]^input[17]; \ - X##gu0 = state[18]^input[18]; \ - X##gu1 = state[19]^input[19]; \ - X##ka0 = state[20]^input[20]; \ - X##ka1 = state[21]^input[21]; \ - X##ke0 = state[22]^input[22]; \ - X##ke1 = state[23]^input[23]; \ - X##ki0 = state[24]^input[24]; \ - X##ki1 = state[25]^input[25]; \ - X##ko0 = state[26]^input[26]; \ - X##ko1 = state[27]^input[27]; \ - X##ku0 = state[28]^input[28]; \ - X##ku1 = state[29]^input[29]; \ - X##ma0 = state[30]^input[30]; \ - X##ma1 = state[31]^input[31]; \ - X##me0 = state[32]^input[32]; \ - X##me1 = state[33]^input[33]; \ - X##mi0 = state[34]; \ - X##mi1 = state[35]; \ - X##mo0 = state[36]; \ - X##mo1 = state[37]; \ - X##mu0 = state[38]; \ - X##mu1 = state[39]; \ - X##sa0 = state[40]; \ - X##sa1 = state[41]; \ - X##se0 = state[42]; \ - X##se1 = state[43]; \ - X##si0 = state[44]; \ - X##si1 = state[45]; \ - X##so0 = state[46]; \ - X##so1 = state[47]; \ - X##su0 = state[48]; \ - X##su1 = state[49]; \ - -#define copyFromState(X, state) \ - X##ba0 = state[ 0]; \ - X##ba1 = state[ 1]; \ - X##be0 = state[ 2]; \ - X##be1 = state[ 3]; \ - X##bi0 = state[ 4]; \ - X##bi1 = state[ 5]; \ - X##bo0 = state[ 6]; \ - X##bo1 = state[ 7]; \ - X##bu0 = state[ 8]; \ - X##bu1 = state[ 9]; \ - X##ga0 = state[10]; \ - X##ga1 = state[11]; \ - X##ge0 = state[12]; \ - X##ge1 = state[13]; \ - X##gi0 = state[14]; \ - X##gi1 = state[15]; \ - X##go0 = state[16]; \ - X##go1 = state[17]; \ - X##gu0 = state[18]; \ - X##gu1 = state[19]; \ - X##ka0 = state[20]; \ - X##ka1 = state[21]; \ - X##ke0 = state[22]; \ - X##ke1 = state[23]; \ - X##ki0 = state[24]; \ - X##ki1 = state[25]; \ - X##ko0 = state[26]; \ - X##ko1 = state[27]; \ - X##ku0 = state[28]; \ - X##ku1 = state[29]; \ - X##ma0 = state[30]; \ - X##ma1 = state[31]; \ - X##me0 = state[32]; \ - X##me1 = state[33]; \ - X##mi0 = state[34]; \ - X##mi1 = state[35]; \ - X##mo0 = state[36]; \ - X##mo1 = state[37]; \ - X##mu0 = state[38]; \ - X##mu1 = state[39]; \ - X##sa0 = state[40]; \ - X##sa1 = state[41]; \ - X##se0 = state[42]; \ - X##se1 = state[43]; \ - X##si0 = state[44]; \ - X##si1 = state[45]; \ - X##so0 = state[46]; \ - X##so1 = state[47]; \ - X##su0 = state[48]; \ - X##su1 = state[49]; \ - -#define copyToState(state, X) \ - state[ 0] = X##ba0; \ - state[ 1] = X##ba1; \ - state[ 2] = X##be0; \ - state[ 3] = X##be1; \ - state[ 4] = X##bi0; \ - state[ 5] = X##bi1; \ - state[ 6] = X##bo0; \ - state[ 7] = X##bo1; \ - state[ 8] = X##bu0; \ - state[ 9] = X##bu1; \ - state[10] = X##ga0; \ - state[11] = X##ga1; \ - state[12] = X##ge0; \ - state[13] = X##ge1; \ - state[14] = X##gi0; \ - state[15] = X##gi1; \ - state[16] = X##go0; \ - state[17] = X##go1; \ - state[18] = X##gu0; \ - state[19] = X##gu1; \ - state[20] = X##ka0; \ - state[21] = X##ka1; \ - state[22] = X##ke0; \ - state[23] = X##ke1; \ - state[24] = X##ki0; \ - state[25] = X##ki1; \ - state[26] = X##ko0; \ - state[27] = X##ko1; \ - state[28] = X##ku0; \ - state[29] = X##ku1; \ - state[30] = X##ma0; \ - state[31] = X##ma1; \ - state[32] = X##me0; \ - state[33] = X##me1; \ - state[34] = X##mi0; \ - state[35] = X##mi1; \ - state[36] = X##mo0; \ - state[37] = X##mo1; \ - state[38] = X##mu0; \ - state[39] = X##mu1; \ - state[40] = X##sa0; \ - state[41] = X##sa1; \ - state[42] = X##se0; \ - state[43] = X##se1; \ - state[44] = X##si0; \ - state[45] = X##si1; \ - state[46] = X##so0; \ - state[47] = X##so1; \ - state[48] = X##su0; \ - state[49] = X##su1; \ - -#define copyStateVariables(X, Y) \ - X##ba0 = Y##ba0; \ - X##ba1 = Y##ba1; \ - X##be0 = Y##be0; \ - X##be1 = Y##be1; \ - X##bi0 = Y##bi0; \ - X##bi1 = Y##bi1; \ - X##bo0 = Y##bo0; \ - X##bo1 = Y##bo1; \ - X##bu0 = Y##bu0; \ - X##bu1 = Y##bu1; \ - X##ga0 = Y##ga0; \ - X##ga1 = Y##ga1; \ - X##ge0 = Y##ge0; \ - X##ge1 = Y##ge1; \ - X##gi0 = Y##gi0; \ - X##gi1 = Y##gi1; \ - X##go0 = Y##go0; \ - X##go1 = Y##go1; \ - X##gu0 = Y##gu0; \ - X##gu1 = Y##gu1; \ - X##ka0 = Y##ka0; \ - X##ka1 = Y##ka1; \ - X##ke0 = Y##ke0; \ - X##ke1 = Y##ke1; \ - X##ki0 = Y##ki0; \ - X##ki1 = Y##ki1; \ - X##ko0 = Y##ko0; \ - X##ko1 = Y##ko1; \ - X##ku0 = Y##ku0; \ - X##ku1 = Y##ku1; \ - X##ma0 = Y##ma0; \ - X##ma1 = Y##ma1; \ - X##me0 = Y##me0; \ - X##me1 = Y##me1; \ - X##mi0 = Y##mi0; \ - X##mi1 = Y##mi1; \ - X##mo0 = Y##mo0; \ - X##mo1 = Y##mo1; \ - X##mu0 = Y##mu0; \ - X##mu1 = Y##mu1; \ - X##sa0 = Y##sa0; \ - X##sa1 = Y##sa1; \ - X##se0 = Y##se0; \ - X##se1 = Y##se1; \ - X##si0 = Y##si0; \ - X##si1 = Y##si1; \ - X##so0 = Y##so0; \ - X##so1 = Y##so1; \ - X##su0 = Y##su0; \ - X##su1 = Y##su1; \ - diff --git a/Modules/_sha3/keccak/KeccakF-1600-32-s2.macros b/Modules/_sha3/keccak/KeccakF-1600-32-s2.macros deleted file mode 100644 index fa1176219a4b..000000000000 --- a/Modules/_sha3/keccak/KeccakF-1600-32-s2.macros +++ /dev/null @@ -1,1187 +0,0 @@ -/* -Code automatically generated by KeccakTools! - -The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, -Michaël Peeters and Gilles Van Assche. For more information, feedback or -questions, please refer to our website: http://keccak.noekeon.org/ - -Implementation by the designers, -hereby denoted as "the implementer". - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#define declareABCDE \ - UINT32 Aba0, Abe0, Abi0, Abo0, Abu0; \ - UINT32 Aba1, Abe1, Abi1, Abo1, Abu1; \ - UINT32 Aga0, Age0, Agi0, Ago0, Agu0; \ - UINT32 Aga1, Age1, Agi1, Ago1, Agu1; \ - UINT32 Aka0, Ake0, Aki0, Ako0, Aku0; \ - UINT32 Aka1, Ake1, Aki1, Ako1, Aku1; \ - UINT32 Ama0, Ame0, Ami0, Amo0, Amu0; \ - UINT32 Ama1, Ame1, Ami1, Amo1, Amu1; \ - UINT32 Asa0, Ase0, Asi0, Aso0, Asu0; \ - UINT32 Asa1, Ase1, Asi1, Aso1, Asu1; \ - UINT32 Bba0, Bbe0, Bbi0, Bbo0, Bbu0; \ - UINT32 Bba1, Bbe1, Bbi1, Bbo1, Bbu1; \ - UINT32 Bga0, Bge0, Bgi0, Bgo0, Bgu0; \ - UINT32 Bga1, Bge1, Bgi1, Bgo1, Bgu1; \ - UINT32 Bka0, Bke0, Bki0, Bko0, Bku0; \ - UINT32 Bka1, Bke1, Bki1, Bko1, Bku1; \ - UINT32 Bma0, Bme0, Bmi0, Bmo0, Bmu0; \ - UINT32 Bma1, Bme1, Bmi1, Bmo1, Bmu1; \ - UINT32 Bsa0, Bse0, Bsi0, Bso0, Bsu0; \ - UINT32 Bsa1, Bse1, Bsi1, Bso1, Bsu1; \ - UINT32 Ca0, Ce0, Ci0, Co0, Cu0; \ - UINT32 Ca1, Ce1, Ci1, Co1, Cu1; \ - UINT32 Da0, De0, Di0, Do0, Du0; \ - UINT32 Da1, De1, Di1, Do1, Du1; \ - UINT32 Eba0, Ebe0, Ebi0, Ebo0, Ebu0; \ - UINT32 Eba1, Ebe1, Ebi1, Ebo1, Ebu1; \ - UINT32 Ega0, Ege0, Egi0, Ego0, Egu0; \ - UINT32 Ega1, Ege1, Egi1, Ego1, Egu1; \ - UINT32 Eka0, Eke0, Eki0, Eko0, Eku0; \ - UINT32 Eka1, Eke1, Eki1, Eko1, Eku1; \ - UINT32 Ema0, Eme0, Emi0, Emo0, Emu0; \ - UINT32 Ema1, Eme1, Emi1, Emo1, Emu1; \ - UINT32 Esa0, Ese0, Esi0, Eso0, Esu0; \ - UINT32 Esa1, Ese1, Esi1, Eso1, Esu1; \ - -#define prepareTheta \ - Ca0 = Aba0^Aga0^Aka0^Ama0^Asa0; \ - Ca1 = Aba1^Aga1^Aka1^Ama1^Asa1; \ - Ce0 = Abe0^Age0^Ake0^Ame0^Ase0; \ - Ce1 = Abe1^Age1^Ake1^Ame1^Ase1; \ - Ci0 = Abi0^Agi0^Aki0^Ami0^Asi0; \ - Ci1 = Abi1^Agi1^Aki1^Ami1^Asi1; \ - Co0 = Abo0^Ago0^Ako0^Amo0^Aso0; \ - Co1 = Abo1^Ago1^Ako1^Amo1^Aso1; \ - Cu0 = Abu0^Agu0^Aku0^Amu0^Asu0; \ - Cu1 = Abu1^Agu1^Aku1^Amu1^Asu1; \ - -#ifdef UseBebigokimisa -/* --- Code for round, with prepare-theta (lane complementing pattern 'bebigokimisa') */ -/* --- using factor 2 interleaving, 64-bit lanes mapped to 32-bit words */ -#define thetaRhoPiChiIotaPrepareTheta(i, A, E) \ - Da0 = Cu0^ROL32(Ce1, 1); \ - Da1 = Cu1^Ce0; \ - De0 = Ca0^ROL32(Ci1, 1); \ - De1 = Ca1^Ci0; \ - Di0 = Ce0^ROL32(Co1, 1); \ - Di1 = Ce1^Co0; \ - Do0 = Ci0^ROL32(Cu1, 1); \ - Do1 = Ci1^Cu0; \ - Du0 = Co0^ROL32(Ca1, 1); \ - Du1 = Co1^Ca0; \ -\ - A##ba0 ^= Da0; \ - Bba0 = A##ba0; \ - A##ge0 ^= De0; \ - Bbe0 = ROL32(A##ge0, 22); \ - A##ki1 ^= Di1; \ - Bbi0 = ROL32(A##ki1, 22); \ - E##ba0 = Bba0 ^( Bbe0 | Bbi0 ); \ - E##ba0 ^= KeccakF1600RoundConstants_int2_0[i]; \ - Ca0 = E##ba0; \ - A##mo1 ^= Do1; \ - Bbo0 = ROL32(A##mo1, 11); \ - E##be0 = Bbe0 ^((~Bbi0)| Bbo0 ); \ - Ce0 = E##be0; \ - A##su0 ^= Du0; \ - Bbu0 = ROL32(A##su0, 7); \ - E##bi0 = Bbi0 ^( Bbo0 & Bbu0 ); \ - Ci0 = E##bi0; \ - E##bo0 = Bbo0 ^( Bbu0 | Bba0 ); \ - Co0 = E##bo0; \ - E##bu0 = Bbu0 ^( Bba0 & Bbe0 ); \ - Cu0 = E##bu0; \ -\ - A##ba1 ^= Da1; \ - Bba1 = A##ba1; \ - A##ge1 ^= De1; \ - Bbe1 = ROL32(A##ge1, 22); \ - A##ki0 ^= Di0; \ - Bbi1 = ROL32(A##ki0, 21); \ - E##ba1 = Bba1 ^( Bbe1 | Bbi1 ); \ - E##ba1 ^= KeccakF1600RoundConstants_int2_1[i]; \ - Ca1 = E##ba1; \ - A##mo0 ^= Do0; \ - Bbo1 = ROL32(A##mo0, 10); \ - E##be1 = Bbe1 ^((~Bbi1)| Bbo1 ); \ - Ce1 = E##be1; \ - A##su1 ^= Du1; \ - Bbu1 = ROL32(A##su1, 7); \ - E##bi1 = Bbi1 ^( Bbo1 & Bbu1 ); \ - Ci1 = E##bi1; \ - E##bo1 = Bbo1 ^( Bbu1 | Bba1 ); \ - Co1 = E##bo1; \ - E##bu1 = Bbu1 ^( Bba1 & Bbe1 ); \ - Cu1 = E##bu1; \ -\ - A##bo0 ^= Do0; \ - Bga0 = ROL32(A##bo0, 14); \ - A##gu0 ^= Du0; \ - Bge0 = ROL32(A##gu0, 10); \ - A##ka1 ^= Da1; \ - Bgi0 = ROL32(A##ka1, 2); \ - E##ga0 = Bga0 ^( Bge0 | Bgi0 ); \ - Ca0 ^= E##ga0; \ - A##me1 ^= De1; \ - Bgo0 = ROL32(A##me1, 23); \ - E##ge0 = Bge0 ^( Bgi0 & Bgo0 ); \ - Ce0 ^= E##ge0; \ - A##si1 ^= Di1; \ - Bgu0 = ROL32(A##si1, 31); \ - E##gi0 = Bgi0 ^( Bgo0 |(~Bgu0)); \ - Ci0 ^= E##gi0; \ - E##go0 = Bgo0 ^( Bgu0 | Bga0 ); \ - Co0 ^= E##go0; \ - E##gu0 = Bgu0 ^( Bga0 & Bge0 ); \ - Cu0 ^= E##gu0; \ -\ - A##bo1 ^= Do1; \ - Bga1 = ROL32(A##bo1, 14); \ - A##gu1 ^= Du1; \ - Bge1 = ROL32(A##gu1, 10); \ - A##ka0 ^= Da0; \ - Bgi1 = ROL32(A##ka0, 1); \ - E##ga1 = Bga1 ^( Bge1 | Bgi1 ); \ - Ca1 ^= E##ga1; \ - A##me0 ^= De0; \ - Bgo1 = ROL32(A##me0, 22); \ - E##ge1 = Bge1 ^( Bgi1 & Bgo1 ); \ - Ce1 ^= E##ge1; \ - A##si0 ^= Di0; \ - Bgu1 = ROL32(A##si0, 30); \ - E##gi1 = Bgi1 ^( Bgo1 |(~Bgu1)); \ - Ci1 ^= E##gi1; \ - E##go1 = Bgo1 ^( Bgu1 | Bga1 ); \ - Co1 ^= E##go1; \ - E##gu1 = Bgu1 ^( Bga1 & Bge1 ); \ - Cu1 ^= E##gu1; \ -\ - A##be1 ^= De1; \ - Bka0 = ROL32(A##be1, 1); \ - A##gi0 ^= Di0; \ - Bke0 = ROL32(A##gi0, 3); \ - A##ko1 ^= Do1; \ - Bki0 = ROL32(A##ko1, 13); \ - E##ka0 = Bka0 ^( Bke0 | Bki0 ); \ - Ca0 ^= E##ka0; \ - A##mu0 ^= Du0; \ - Bko0 = ROL32(A##mu0, 4); \ - E##ke0 = Bke0 ^( Bki0 & Bko0 ); \ - Ce0 ^= E##ke0; \ - A##sa0 ^= Da0; \ - Bku0 = ROL32(A##sa0, 9); \ - E##ki0 = Bki0 ^((~Bko0)& Bku0 ); \ - Ci0 ^= E##ki0; \ - E##ko0 = (~Bko0)^( Bku0 | Bka0 ); \ - Co0 ^= E##ko0; \ - E##ku0 = Bku0 ^( Bka0 & Bke0 ); \ - Cu0 ^= E##ku0; \ -\ - A##be0 ^= De0; \ - Bka1 = A##be0; \ - A##gi1 ^= Di1; \ - Bke1 = ROL32(A##gi1, 3); \ - A##ko0 ^= Do0; \ - Bki1 = ROL32(A##ko0, 12); \ - E##ka1 = Bka1 ^( Bke1 | Bki1 ); \ - Ca1 ^= E##ka1; \ - A##mu1 ^= Du1; \ - Bko1 = ROL32(A##mu1, 4); \ - E##ke1 = Bke1 ^( Bki1 & Bko1 ); \ - Ce1 ^= E##ke1; \ - A##sa1 ^= Da1; \ - Bku1 = ROL32(A##sa1, 9); \ - E##ki1 = Bki1 ^((~Bko1)& Bku1 ); \ - Ci1 ^= E##ki1; \ - E##ko1 = (~Bko1)^( Bku1 | Bka1 ); \ - Co1 ^= E##ko1; \ - E##ku1 = Bku1 ^( Bka1 & Bke1 ); \ - Cu1 ^= E##ku1; \ -\ - A##bu1 ^= Du1; \ - Bma0 = ROL32(A##bu1, 14); \ - A##ga0 ^= Da0; \ - Bme0 = ROL32(A##ga0, 18); \ - A##ke0 ^= De0; \ - Bmi0 = ROL32(A##ke0, 5); \ - E##ma0 = Bma0 ^( Bme0 & Bmi0 ); \ - Ca0 ^= E##ma0; \ - A##mi1 ^= Di1; \ - Bmo0 = ROL32(A##mi1, 8); \ - E##me0 = Bme0 ^( Bmi0 | Bmo0 ); \ - Ce0 ^= E##me0; \ - A##so0 ^= Do0; \ - Bmu0 = ROL32(A##so0, 28); \ - E##mi0 = Bmi0 ^((~Bmo0)| Bmu0 ); \ - Ci0 ^= E##mi0; \ - E##mo0 = (~Bmo0)^( Bmu0 & Bma0 ); \ - Co0 ^= E##mo0; \ - E##mu0 = Bmu0 ^( Bma0 | Bme0 ); \ - Cu0 ^= E##mu0; \ -\ - A##bu0 ^= Du0; \ - Bma1 = ROL32(A##bu0, 13); \ - A##ga1 ^= Da1; \ - Bme1 = ROL32(A##ga1, 18); \ - A##ke1 ^= De1; \ - Bmi1 = ROL32(A##ke1, 5); \ - E##ma1 = Bma1 ^( Bme1 & Bmi1 ); \ - Ca1 ^= E##ma1; \ - A##mi0 ^= Di0; \ - Bmo1 = ROL32(A##mi0, 7); \ - E##me1 = Bme1 ^( Bmi1 | Bmo1 ); \ - Ce1 ^= E##me1; \ - A##so1 ^= Do1; \ - Bmu1 = ROL32(A##so1, 28); \ - E##mi1 = Bmi1 ^((~Bmo1)| Bmu1 ); \ - Ci1 ^= E##mi1; \ - E##mo1 = (~Bmo1)^( Bmu1 & Bma1 ); \ - Co1 ^= E##mo1; \ - E##mu1 = Bmu1 ^( Bma1 | Bme1 ); \ - Cu1 ^= E##mu1; \ -\ - A##bi0 ^= Di0; \ - Bsa0 = ROL32(A##bi0, 31); \ - A##go1 ^= Do1; \ - Bse0 = ROL32(A##go1, 28); \ - A##ku1 ^= Du1; \ - Bsi0 = ROL32(A##ku1, 20); \ - E##sa0 = Bsa0 ^((~Bse0)& Bsi0 ); \ - Ca0 ^= E##sa0; \ - A##ma1 ^= Da1; \ - Bso0 = ROL32(A##ma1, 21); \ - E##se0 = (~Bse0)^( Bsi0 | Bso0 ); \ - Ce0 ^= E##se0; \ - A##se0 ^= De0; \ - Bsu0 = ROL32(A##se0, 1); \ - E##si0 = Bsi0 ^( Bso0 & Bsu0 ); \ - Ci0 ^= E##si0; \ - E##so0 = Bso0 ^( Bsu0 | Bsa0 ); \ - Co0 ^= E##so0; \ - E##su0 = Bsu0 ^( Bsa0 & Bse0 ); \ - Cu0 ^= E##su0; \ -\ - A##bi1 ^= Di1; \ - Bsa1 = ROL32(A##bi1, 31); \ - A##go0 ^= Do0; \ - Bse1 = ROL32(A##go0, 27); \ - A##ku0 ^= Du0; \ - Bsi1 = ROL32(A##ku0, 19); \ - E##sa1 = Bsa1 ^((~Bse1)& Bsi1 ); \ - Ca1 ^= E##sa1; \ - A##ma0 ^= Da0; \ - Bso1 = ROL32(A##ma0, 20); \ - E##se1 = (~Bse1)^( Bsi1 | Bso1 ); \ - Ce1 ^= E##se1; \ - A##se1 ^= De1; \ - Bsu1 = ROL32(A##se1, 1); \ - E##si1 = Bsi1 ^( Bso1 & Bsu1 ); \ - Ci1 ^= E##si1; \ - E##so1 = Bso1 ^( Bsu1 | Bsa1 ); \ - Co1 ^= E##so1; \ - E##su1 = Bsu1 ^( Bsa1 & Bse1 ); \ - Cu1 ^= E##su1; \ -\ - -/* --- Code for round (lane complementing pattern 'bebigokimisa') */ -/* --- using factor 2 interleaving, 64-bit lanes mapped to 32-bit words */ -#define thetaRhoPiChiIota(i, A, E) \ - Da0 = Cu0^ROL32(Ce1, 1); \ - Da1 = Cu1^Ce0; \ - De0 = Ca0^ROL32(Ci1, 1); \ - De1 = Ca1^Ci0; \ - Di0 = Ce0^ROL32(Co1, 1); \ - Di1 = Ce1^Co0; \ - Do0 = Ci0^ROL32(Cu1, 1); \ - Do1 = Ci1^Cu0; \ - Du0 = Co0^ROL32(Ca1, 1); \ - Du1 = Co1^Ca0; \ -\ - A##ba0 ^= Da0; \ - Bba0 = A##ba0; \ - A##ge0 ^= De0; \ - Bbe0 = ROL32(A##ge0, 22); \ - A##ki1 ^= Di1; \ - Bbi0 = ROL32(A##ki1, 22); \ - E##ba0 = Bba0 ^( Bbe0 | Bbi0 ); \ - E##ba0 ^= KeccakF1600RoundConstants_int2_0[i]; \ - A##mo1 ^= Do1; \ - Bbo0 = ROL32(A##mo1, 11); \ - E##be0 = Bbe0 ^((~Bbi0)| Bbo0 ); \ - A##su0 ^= Du0; \ - Bbu0 = ROL32(A##su0, 7); \ - E##bi0 = Bbi0 ^( Bbo0 & Bbu0 ); \ - E##bo0 = Bbo0 ^( Bbu0 | Bba0 ); \ - E##bu0 = Bbu0 ^( Bba0 & Bbe0 ); \ -\ - A##ba1 ^= Da1; \ - Bba1 = A##ba1; \ - A##ge1 ^= De1; \ - Bbe1 = ROL32(A##ge1, 22); \ - A##ki0 ^= Di0; \ - Bbi1 = ROL32(A##ki0, 21); \ - E##ba1 = Bba1 ^( Bbe1 | Bbi1 ); \ - E##ba1 ^= KeccakF1600RoundConstants_int2_1[i]; \ - A##mo0 ^= Do0; \ - Bbo1 = ROL32(A##mo0, 10); \ - E##be1 = Bbe1 ^((~Bbi1)| Bbo1 ); \ - A##su1 ^= Du1; \ - Bbu1 = ROL32(A##su1, 7); \ - E##bi1 = Bbi1 ^( Bbo1 & Bbu1 ); \ - E##bo1 = Bbo1 ^( Bbu1 | Bba1 ); \ - E##bu1 = Bbu1 ^( Bba1 & Bbe1 ); \ -\ - A##bo0 ^= Do0; \ - Bga0 = ROL32(A##bo0, 14); \ - A##gu0 ^= Du0; \ - Bge0 = ROL32(A##gu0, 10); \ - A##ka1 ^= Da1; \ - Bgi0 = ROL32(A##ka1, 2); \ - E##ga0 = Bga0 ^( Bge0 | Bgi0 ); \ - A##me1 ^= De1; \ - Bgo0 = ROL32(A##me1, 23); \ - E##ge0 = Bge0 ^( Bgi0 & Bgo0 ); \ - A##si1 ^= Di1; \ - Bgu0 = ROL32(A##si1, 31); \ - E##gi0 = Bgi0 ^( Bgo0 |(~Bgu0)); \ - E##go0 = Bgo0 ^( Bgu0 | Bga0 ); \ - E##gu0 = Bgu0 ^( Bga0 & Bge0 ); \ -\ - A##bo1 ^= Do1; \ - Bga1 = ROL32(A##bo1, 14); \ - A##gu1 ^= Du1; \ - Bge1 = ROL32(A##gu1, 10); \ - A##ka0 ^= Da0; \ - Bgi1 = ROL32(A##ka0, 1); \ - E##ga1 = Bga1 ^( Bge1 | Bgi1 ); \ - A##me0 ^= De0; \ - Bgo1 = ROL32(A##me0, 22); \ - E##ge1 = Bge1 ^( Bgi1 & Bgo1 ); \ - A##si0 ^= Di0; \ - Bgu1 = ROL32(A##si0, 30); \ - E##gi1 = Bgi1 ^( Bgo1 |(~Bgu1)); \ - E##go1 = Bgo1 ^( Bgu1 | Bga1 ); \ - E##gu1 = Bgu1 ^( Bga1 & Bge1 ); \ -\ - A##be1 ^= De1; \ - Bka0 = ROL32(A##be1, 1); \ - A##gi0 ^= Di0; \ - Bke0 = ROL32(A##gi0, 3); \ - A##ko1 ^= Do1; \ - Bki0 = ROL32(A##ko1, 13); \ - E##ka0 = Bka0 ^( Bke0 | Bki0 ); \ - A##mu0 ^= Du0; \ - Bko0 = ROL32(A##mu0, 4); \ - E##ke0 = Bke0 ^( Bki0 & Bko0 ); \ - A##sa0 ^= Da0; \ - Bku0 = ROL32(A##sa0, 9); \ - E##ki0 = Bki0 ^((~Bko0)& Bku0 ); \ - E##ko0 = (~Bko0)^( Bku0 | Bka0 ); \ - E##ku0 = Bku0 ^( Bka0 & Bke0 ); \ -\ - A##be0 ^= De0; \ - Bka1 = A##be0; \ - A##gi1 ^= Di1; \ - Bke1 = ROL32(A##gi1, 3); \ - A##ko0 ^= Do0; \ - Bki1 = ROL32(A##ko0, 12); \ - E##ka1 = Bka1 ^( Bke1 | Bki1 ); \ - A##mu1 ^= Du1; \ - Bko1 = ROL32(A##mu1, 4); \ - E##ke1 = Bke1 ^( Bki1 & Bko1 ); \ - A##sa1 ^= Da1; \ - Bku1 = ROL32(A##sa1, 9); \ - E##ki1 = Bki1 ^((~Bko1)& Bku1 ); \ - E##ko1 = (~Bko1)^( Bku1 | Bka1 ); \ - E##ku1 = Bku1 ^( Bka1 & Bke1 ); \ -\ - A##bu1 ^= Du1; \ - Bma0 = ROL32(A##bu1, 14); \ - A##ga0 ^= Da0; \ - Bme0 = ROL32(A##ga0, 18); \ - A##ke0 ^= De0; \ - Bmi0 = ROL32(A##ke0, 5); \ - E##ma0 = Bma0 ^( Bme0 & Bmi0 ); \ - A##mi1 ^= Di1; \ - Bmo0 = ROL32(A##mi1, 8); \ - E##me0 = Bme0 ^( Bmi0 | Bmo0 ); \ - A##so0 ^= Do0; \ - Bmu0 = ROL32(A##so0, 28); \ - E##mi0 = Bmi0 ^((~Bmo0)| Bmu0 ); \ - E##mo0 = (~Bmo0)^( Bmu0 & Bma0 ); \ - E##mu0 = Bmu0 ^( Bma0 | Bme0 ); \ -\ - A##bu0 ^= Du0; \ - Bma1 = ROL32(A##bu0, 13); \ - A##ga1 ^= Da1; \ - Bme1 = ROL32(A##ga1, 18); \ - A##ke1 ^= De1; \ - Bmi1 = ROL32(A##ke1, 5); \ - E##ma1 = Bma1 ^( Bme1 & Bmi1 ); \ - A##mi0 ^= Di0; \ - Bmo1 = ROL32(A##mi0, 7); \ - E##me1 = Bme1 ^( Bmi1 | Bmo1 ); \ - A##so1 ^= Do1; \ - Bmu1 = ROL32(A##so1, 28); \ - E##mi1 = Bmi1 ^((~Bmo1)| Bmu1 ); \ - E##mo1 = (~Bmo1)^( Bmu1 & Bma1 ); \ - E##mu1 = Bmu1 ^( Bma1 | Bme1 ); \ -\ - A##bi0 ^= Di0; \ - Bsa0 = ROL32(A##bi0, 31); \ - A##go1 ^= Do1; \ - Bse0 = ROL32(A##go1, 28); \ - A##ku1 ^= Du1; \ - Bsi0 = ROL32(A##ku1, 20); \ - E##sa0 = Bsa0 ^((~Bse0)& Bsi0 ); \ - A##ma1 ^= Da1; \ - Bso0 = ROL32(A##ma1, 21); \ - E##se0 = (~Bse0)^( Bsi0 | Bso0 ); \ - A##se0 ^= De0; \ - Bsu0 = ROL32(A##se0, 1); \ - E##si0 = Bsi0 ^( Bso0 & Bsu0 ); \ - E##so0 = Bso0 ^( Bsu0 | Bsa0 ); \ - E##su0 = Bsu0 ^( Bsa0 & Bse0 ); \ -\ - A##bi1 ^= Di1; \ - Bsa1 = ROL32(A##bi1, 31); \ - A##go0 ^= Do0; \ - Bse1 = ROL32(A##go0, 27); \ - A##ku0 ^= Du0; \ - Bsi1 = ROL32(A##ku0, 19); \ - E##sa1 = Bsa1 ^((~Bse1)& Bsi1 ); \ - A##ma0 ^= Da0; \ - Bso1 = ROL32(A##ma0, 20); \ - E##se1 = (~Bse1)^( Bsi1 | Bso1 ); \ - A##se1 ^= De1; \ - Bsu1 = ROL32(A##se1, 1); \ - E##si1 = Bsi1 ^( Bso1 & Bsu1 ); \ - E##so1 = Bso1 ^( Bsu1 | Bsa1 ); \ - E##su1 = Bsu1 ^( Bsa1 & Bse1 ); \ -\ - -#else /* UseBebigokimisa */ -/* --- Code for round, with prepare-theta */ -/* --- using factor 2 interleaving, 64-bit lanes mapped to 32-bit words */ -#define thetaRhoPiChiIotaPrepareTheta(i, A, E) \ - Da0 = Cu0^ROL32(Ce1, 1); \ - Da1 = Cu1^Ce0; \ - De0 = Ca0^ROL32(Ci1, 1); \ - De1 = Ca1^Ci0; \ - Di0 = Ce0^ROL32(Co1, 1); \ - Di1 = Ce1^Co0; \ - Do0 = Ci0^ROL32(Cu1, 1); \ - Do1 = Ci1^Cu0; \ - Du0 = Co0^ROL32(Ca1, 1); \ - Du1 = Co1^Ca0; \ -\ - A##ba0 ^= Da0; \ - Bba0 = A##ba0; \ - A##ge0 ^= De0; \ - Bbe0 = ROL32(A##ge0, 22); \ - A##ki1 ^= Di1; \ - Bbi0 = ROL32(A##ki1, 22); \ - E##ba0 = Bba0 ^((~Bbe0)& Bbi0 ); \ - E##ba0 ^= KeccakF1600RoundConstants_int2_0[i]; \ - Ca0 = E##ba0; \ - A##mo1 ^= Do1; \ - Bbo0 = ROL32(A##mo1, 11); \ - E##be0 = Bbe0 ^((~Bbi0)& Bbo0 ); \ - Ce0 = E##be0; \ - A##su0 ^= Du0; \ - Bbu0 = ROL32(A##su0, 7); \ - E##bi0 = Bbi0 ^((~Bbo0)& Bbu0 ); \ - Ci0 = E##bi0; \ - E##bo0 = Bbo0 ^((~Bbu0)& Bba0 ); \ - Co0 = E##bo0; \ - E##bu0 = Bbu0 ^((~Bba0)& Bbe0 ); \ - Cu0 = E##bu0; \ -\ - A##ba1 ^= Da1; \ - Bba1 = A##ba1; \ - A##ge1 ^= De1; \ - Bbe1 = ROL32(A##ge1, 22); \ - A##ki0 ^= Di0; \ - Bbi1 = ROL32(A##ki0, 21); \ - E##ba1 = Bba1 ^((~Bbe1)& Bbi1 ); \ - E##ba1 ^= KeccakF1600RoundConstants_int2_1[i]; \ - Ca1 = E##ba1; \ - A##mo0 ^= Do0; \ - Bbo1 = ROL32(A##mo0, 10); \ - E##be1 = Bbe1 ^((~Bbi1)& Bbo1 ); \ - Ce1 = E##be1; \ - A##su1 ^= Du1; \ - Bbu1 = ROL32(A##su1, 7); \ - E##bi1 = Bbi1 ^((~Bbo1)& Bbu1 ); \ - Ci1 = E##bi1; \ - E##bo1 = Bbo1 ^((~Bbu1)& Bba1 ); \ - Co1 = E##bo1; \ - E##bu1 = Bbu1 ^((~Bba1)& Bbe1 ); \ - Cu1 = E##bu1; \ -\ - A##bo0 ^= Do0; \ - Bga0 = ROL32(A##bo0, 14); \ - A##gu0 ^= Du0; \ - Bge0 = ROL32(A##gu0, 10); \ - A##ka1 ^= Da1; \ - Bgi0 = ROL32(A##ka1, 2); \ - E##ga0 = Bga0 ^((~Bge0)& Bgi0 ); \ - Ca0 ^= E##ga0; \ - A##me1 ^= De1; \ - Bgo0 = ROL32(A##me1, 23); \ - E##ge0 = Bge0 ^((~Bgi0)& Bgo0 ); \ - Ce0 ^= E##ge0; \ - A##si1 ^= Di1; \ - Bgu0 = ROL32(A##si1, 31); \ - E##gi0 = Bgi0 ^((~Bgo0)& Bgu0 ); \ - Ci0 ^= E##gi0; \ - E##go0 = Bgo0 ^((~Bgu0)& Bga0 ); \ - Co0 ^= E##go0; \ - E##gu0 = Bgu0 ^((~Bga0)& Bge0 ); \ - Cu0 ^= E##gu0; \ -\ - A##bo1 ^= Do1; \ - Bga1 = ROL32(A##bo1, 14); \ - A##gu1 ^= Du1; \ - Bge1 = ROL32(A##gu1, 10); \ - A##ka0 ^= Da0; \ - Bgi1 = ROL32(A##ka0, 1); \ - E##ga1 = Bga1 ^((~Bge1)& Bgi1 ); \ - Ca1 ^= E##ga1; \ - A##me0 ^= De0; \ - Bgo1 = ROL32(A##me0, 22); \ - E##ge1 = Bge1 ^((~Bgi1)& Bgo1 ); \ - Ce1 ^= E##ge1; \ - A##si0 ^= Di0; \ - Bgu1 = ROL32(A##si0, 30); \ - E##gi1 = Bgi1 ^((~Bgo1)& Bgu1 ); \ - Ci1 ^= E##gi1; \ - E##go1 = Bgo1 ^((~Bgu1)& Bga1 ); \ - Co1 ^= E##go1; \ - E##gu1 = Bgu1 ^((~Bga1)& Bge1 ); \ - Cu1 ^= E##gu1; \ -\ - A##be1 ^= De1; \ - Bka0 = ROL32(A##be1, 1); \ - A##gi0 ^= Di0; \ - Bke0 = ROL32(A##gi0, 3); \ - A##ko1 ^= Do1; \ - Bki0 = ROL32(A##ko1, 13); \ - E##ka0 = Bka0 ^((~Bke0)& Bki0 ); \ - Ca0 ^= E##ka0; \ - A##mu0 ^= Du0; \ - Bko0 = ROL32(A##mu0, 4); \ - E##ke0 = Bke0 ^((~Bki0)& Bko0 ); \ - Ce0 ^= E##ke0; \ - A##sa0 ^= Da0; \ - Bku0 = ROL32(A##sa0, 9); \ - E##ki0 = Bki0 ^((~Bko0)& Bku0 ); \ - Ci0 ^= E##ki0; \ - E##ko0 = Bko0 ^((~Bku0)& Bka0 ); \ - Co0 ^= E##ko0; \ - E##ku0 = Bku0 ^((~Bka0)& Bke0 ); \ - Cu0 ^= E##ku0; \ -\ - A##be0 ^= De0; \ - Bka1 = A##be0; \ - A##gi1 ^= Di1; \ - Bke1 = ROL32(A##gi1, 3); \ - A##ko0 ^= Do0; \ - Bki1 = ROL32(A##ko0, 12); \ - E##ka1 = Bka1 ^((~Bke1)& Bki1 ); \ - Ca1 ^= E##ka1; \ - A##mu1 ^= Du1; \ - Bko1 = ROL32(A##mu1, 4); \ - E##ke1 = Bke1 ^((~Bki1)& Bko1 ); \ - Ce1 ^= E##ke1; \ - A##sa1 ^= Da1; \ - Bku1 = ROL32(A##sa1, 9); \ - E##ki1 = Bki1 ^((~Bko1)& Bku1 ); \ - Ci1 ^= E##ki1; \ - E##ko1 = Bko1 ^((~Bku1)& Bka1 ); \ - Co1 ^= E##ko1; \ - E##ku1 = Bku1 ^((~Bka1)& Bke1 ); \ - Cu1 ^= E##ku1; \ -\ - A##bu1 ^= Du1; \ - Bma0 = ROL32(A##bu1, 14); \ - A##ga0 ^= Da0; \ - Bme0 = ROL32(A##ga0, 18); \ - A##ke0 ^= De0; \ - Bmi0 = ROL32(A##ke0, 5); \ - E##ma0 = Bma0 ^((~Bme0)& Bmi0 ); \ - Ca0 ^= E##ma0; \ - A##mi1 ^= Di1; \ - Bmo0 = ROL32(A##mi1, 8); \ - E##me0 = Bme0 ^((~Bmi0)& Bmo0 ); \ - Ce0 ^= E##me0; \ - A##so0 ^= Do0; \ - Bmu0 = ROL32(A##so0, 28); \ - E##mi0 = Bmi0 ^((~Bmo0)& Bmu0 ); \ - Ci0 ^= E##mi0; \ - E##mo0 = Bmo0 ^((~Bmu0)& Bma0 ); \ - Co0 ^= E##mo0; \ - E##mu0 = Bmu0 ^((~Bma0)& Bme0 ); \ - Cu0 ^= E##mu0; \ -\ - A##bu0 ^= Du0; \ - Bma1 = ROL32(A##bu0, 13); \ - A##ga1 ^= Da1; \ - Bme1 = ROL32(A##ga1, 18); \ - A##ke1 ^= De1; \ - Bmi1 = ROL32(A##ke1, 5); \ - E##ma1 = Bma1 ^((~Bme1)& Bmi1 ); \ - Ca1 ^= E##ma1; \ - A##mi0 ^= Di0; \ - Bmo1 = ROL32(A##mi0, 7); \ - E##me1 = Bme1 ^((~Bmi1)& Bmo1 ); \ - Ce1 ^= E##me1; \ - A##so1 ^= Do1; \ - Bmu1 = ROL32(A##so1, 28); \ - E##mi1 = Bmi1 ^((~Bmo1)& Bmu1 ); \ - Ci1 ^= E##mi1; \ - E##mo1 = Bmo1 ^((~Bmu1)& Bma1 ); \ - Co1 ^= E##mo1; \ - E##mu1 = Bmu1 ^((~Bma1)& Bme1 ); \ - Cu1 ^= E##mu1; \ -\ - A##bi0 ^= Di0; \ - Bsa0 = ROL32(A##bi0, 31); \ - A##go1 ^= Do1; \ - Bse0 = ROL32(A##go1, 28); \ - A##ku1 ^= Du1; \ - Bsi0 = ROL32(A##ku1, 20); \ - E##sa0 = Bsa0 ^((~Bse0)& Bsi0 ); \ - Ca0 ^= E##sa0; \ - A##ma1 ^= Da1; \ - Bso0 = ROL32(A##ma1, 21); \ - E##se0 = Bse0 ^((~Bsi0)& Bso0 ); \ - Ce0 ^= E##se0; \ - A##se0 ^= De0; \ - Bsu0 = ROL32(A##se0, 1); \ - E##si0 = Bsi0 ^((~Bso0)& Bsu0 ); \ - Ci0 ^= E##si0; \ - E##so0 = Bso0 ^((~Bsu0)& Bsa0 ); \ - Co0 ^= E##so0; \ - E##su0 = Bsu0 ^((~Bsa0)& Bse0 ); \ - Cu0 ^= E##su0; \ -\ - A##bi1 ^= Di1; \ - Bsa1 = ROL32(A##bi1, 31); \ - A##go0 ^= Do0; \ - Bse1 = ROL32(A##go0, 27); \ - A##ku0 ^= Du0; \ - Bsi1 = ROL32(A##ku0, 19); \ - E##sa1 = Bsa1 ^((~Bse1)& Bsi1 ); \ - Ca1 ^= E##sa1; \ - A##ma0 ^= Da0; \ - Bso1 = ROL32(A##ma0, 20); \ - E##se1 = Bse1 ^((~Bsi1)& Bso1 ); \ - Ce1 ^= E##se1; \ - A##se1 ^= De1; \ - Bsu1 = ROL32(A##se1, 1); \ - E##si1 = Bsi1 ^((~Bso1)& Bsu1 ); \ - Ci1 ^= E##si1; \ - E##so1 = Bso1 ^((~Bsu1)& Bsa1 ); \ - Co1 ^= E##so1; \ - E##su1 = Bsu1 ^((~Bsa1)& Bse1 ); \ - Cu1 ^= E##su1; \ -\ - -/* --- Code for round */ -/* --- using factor 2 interleaving, 64-bit lanes mapped to 32-bit words */ -#define thetaRhoPiChiIota(i, A, E) \ - Da0 = Cu0^ROL32(Ce1, 1); \ - Da1 = Cu1^Ce0; \ - De0 = Ca0^ROL32(Ci1, 1); \ - De1 = Ca1^Ci0; \ - Di0 = Ce0^ROL32(Co1, 1); \ - Di1 = Ce1^Co0; \ - Do0 = Ci0^ROL32(Cu1, 1); \ - Do1 = Ci1^Cu0; \ - Du0 = Co0^ROL32(Ca1, 1); \ - Du1 = Co1^Ca0; \ -\ - A##ba0 ^= Da0; \ - Bba0 = A##ba0; \ - A##ge0 ^= De0; \ - Bbe0 = ROL32(A##ge0, 22); \ - A##ki1 ^= Di1; \ - Bbi0 = ROL32(A##ki1, 22); \ - E##ba0 = Bba0 ^((~Bbe0)& Bbi0 ); \ - E##ba0 ^= KeccakF1600RoundConstants_int2_0[i]; \ - A##mo1 ^= Do1; \ - Bbo0 = ROL32(A##mo1, 11); \ - E##be0 = Bbe0 ^((~Bbi0)& Bbo0 ); \ - A##su0 ^= Du0; \ - Bbu0 = ROL32(A##su0, 7); \ - E##bi0 = Bbi0 ^((~Bbo0)& Bbu0 ); \ - E##bo0 = Bbo0 ^((~Bbu0)& Bba0 ); \ - E##bu0 = Bbu0 ^((~Bba0)& Bbe0 ); \ -\ - A##ba1 ^= Da1; \ - Bba1 = A##ba1; \ - A##ge1 ^= De1; \ - Bbe1 = ROL32(A##ge1, 22); \ - A##ki0 ^= Di0; \ - Bbi1 = ROL32(A##ki0, 21); \ - E##ba1 = Bba1 ^((~Bbe1)& Bbi1 ); \ - E##ba1 ^= KeccakF1600RoundConstants_int2_1[i]; \ - A##mo0 ^= Do0; \ - Bbo1 = ROL32(A##mo0, 10); \ - E##be1 = Bbe1 ^((~Bbi1)& Bbo1 ); \ - A##su1 ^= Du1; \ - Bbu1 = ROL32(A##su1, 7); \ - E##bi1 = Bbi1 ^((~Bbo1)& Bbu1 ); \ - E##bo1 = Bbo1 ^((~Bbu1)& Bba1 ); \ - E##bu1 = Bbu1 ^((~Bba1)& Bbe1 ); \ -\ - A##bo0 ^= Do0; \ - Bga0 = ROL32(A##bo0, 14); \ - A##gu0 ^= Du0; \ - Bge0 = ROL32(A##gu0, 10); \ - A##ka1 ^= Da1; \ - Bgi0 = ROL32(A##ka1, 2); \ - E##ga0 = Bga0 ^((~Bge0)& Bgi0 ); \ - A##me1 ^= De1; \ - Bgo0 = ROL32(A##me1, 23); \ - E##ge0 = Bge0 ^((~Bgi0)& Bgo0 ); \ - A##si1 ^= Di1; \ - Bgu0 = ROL32(A##si1, 31); \ - E##gi0 = Bgi0 ^((~Bgo0)& Bgu0 ); \ - E##go0 = Bgo0 ^((~Bgu0)& Bga0 ); \ - E##gu0 = Bgu0 ^((~Bga0)& Bge0 ); \ -\ - A##bo1 ^= Do1; \ - Bga1 = ROL32(A##bo1, 14); \ - A##gu1 ^= Du1; \ - Bge1 = ROL32(A##gu1, 10); \ - A##ka0 ^= Da0; \ - Bgi1 = ROL32(A##ka0, 1); \ - E##ga1 = Bga1 ^((~Bge1)& Bgi1 ); \ - A##me0 ^= De0; \ - Bgo1 = ROL32(A##me0, 22); \ - E##ge1 = Bge1 ^((~Bgi1)& Bgo1 ); \ - A##si0 ^= Di0; \ - Bgu1 = ROL32(A##si0, 30); \ - E##gi1 = Bgi1 ^((~Bgo1)& Bgu1 ); \ - E##go1 = Bgo1 ^((~Bgu1)& Bga1 ); \ - E##gu1 = Bgu1 ^((~Bga1)& Bge1 ); \ -\ - A##be1 ^= De1; \ - Bka0 = ROL32(A##be1, 1); \ - A##gi0 ^= Di0; \ - Bke0 = ROL32(A##gi0, 3); \ - A##ko1 ^= Do1; \ - Bki0 = ROL32(A##ko1, 13); \ - E##ka0 = Bka0 ^((~Bke0)& Bki0 ); \ - A##mu0 ^= Du0; \ - Bko0 = ROL32(A##mu0, 4); \ - E##ke0 = Bke0 ^((~Bki0)& Bko0 ); \ - A##sa0 ^= Da0; \ - Bku0 = ROL32(A##sa0, 9); \ - E##ki0 = Bki0 ^((~Bko0)& Bku0 ); \ - E##ko0 = Bko0 ^((~Bku0)& Bka0 ); \ - E##ku0 = Bku0 ^((~Bka0)& Bke0 ); \ -\ - A##be0 ^= De0; \ - Bka1 = A##be0; \ - A##gi1 ^= Di1; \ - Bke1 = ROL32(A##gi1, 3); \ - A##ko0 ^= Do0; \ - Bki1 = ROL32(A##ko0, 12); \ - E##ka1 = Bka1 ^((~Bke1)& Bki1 ); \ - A##mu1 ^= Du1; \ - Bko1 = ROL32(A##mu1, 4); \ - E##ke1 = Bke1 ^((~Bki1)& Bko1 ); \ - A##sa1 ^= Da1; \ - Bku1 = ROL32(A##sa1, 9); \ - E##ki1 = Bki1 ^((~Bko1)& Bku1 ); \ - E##ko1 = Bko1 ^((~Bku1)& Bka1 ); \ - E##ku1 = Bku1 ^((~Bka1)& Bke1 ); \ -\ - A##bu1 ^= Du1; \ - Bma0 = ROL32(A##bu1, 14); \ - A##ga0 ^= Da0; \ - Bme0 = ROL32(A##ga0, 18); \ - A##ke0 ^= De0; \ - Bmi0 = ROL32(A##ke0, 5); \ - E##ma0 = Bma0 ^((~Bme0)& Bmi0 ); \ - A##mi1 ^= Di1; \ - Bmo0 = ROL32(A##mi1, 8); \ - E##me0 = Bme0 ^((~Bmi0)& Bmo0 ); \ - A##so0 ^= Do0; \ - Bmu0 = ROL32(A##so0, 28); \ - E##mi0 = Bmi0 ^((~Bmo0)& Bmu0 ); \ - E##mo0 = Bmo0 ^((~Bmu0)& Bma0 ); \ - E##mu0 = Bmu0 ^((~Bma0)& Bme0 ); \ -\ - A##bu0 ^= Du0; \ - Bma1 = ROL32(A##bu0, 13); \ - A##ga1 ^= Da1; \ - Bme1 = ROL32(A##ga1, 18); \ - A##ke1 ^= De1; \ - Bmi1 = ROL32(A##ke1, 5); \ - E##ma1 = Bma1 ^((~Bme1)& Bmi1 ); \ - A##mi0 ^= Di0; \ - Bmo1 = ROL32(A##mi0, 7); \ - E##me1 = Bme1 ^((~Bmi1)& Bmo1 ); \ - A##so1 ^= Do1; \ - Bmu1 = ROL32(A##so1, 28); \ - E##mi1 = Bmi1 ^((~Bmo1)& Bmu1 ); \ - E##mo1 = Bmo1 ^((~Bmu1)& Bma1 ); \ - E##mu1 = Bmu1 ^((~Bma1)& Bme1 ); \ -\ - A##bi0 ^= Di0; \ - Bsa0 = ROL32(A##bi0, 31); \ - A##go1 ^= Do1; \ - Bse0 = ROL32(A##go1, 28); \ - A##ku1 ^= Du1; \ - Bsi0 = ROL32(A##ku1, 20); \ - E##sa0 = Bsa0 ^((~Bse0)& Bsi0 ); \ - A##ma1 ^= Da1; \ - Bso0 = ROL32(A##ma1, 21); \ - E##se0 = Bse0 ^((~Bsi0)& Bso0 ); \ - A##se0 ^= De0; \ - Bsu0 = ROL32(A##se0, 1); \ - E##si0 = Bsi0 ^((~Bso0)& Bsu0 ); \ - E##so0 = Bso0 ^((~Bsu0)& Bsa0 ); \ - E##su0 = Bsu0 ^((~Bsa0)& Bse0 ); \ -\ - A##bi1 ^= Di1; \ - Bsa1 = ROL32(A##bi1, 31); \ - A##go0 ^= Do0; \ - Bse1 = ROL32(A##go0, 27); \ - A##ku0 ^= Du0; \ - Bsi1 = ROL32(A##ku0, 19); \ - E##sa1 = Bsa1 ^((~Bse1)& Bsi1 ); \ - A##ma0 ^= Da0; \ - Bso1 = ROL32(A##ma0, 20); \ - E##se1 = Bse1 ^((~Bsi1)& Bso1 ); \ - A##se1 ^= De1; \ - Bsu1 = ROL32(A##se1, 1); \ - E##si1 = Bsi1 ^((~Bso1)& Bsu1 ); \ - E##so1 = Bso1 ^((~Bsu1)& Bsa1 ); \ - E##su1 = Bsu1 ^((~Bsa1)& Bse1 ); \ -\ - -#endif /* UseBebigokimisa */ - -const UINT32 KeccakF1600RoundConstants_int2_0[24] = { - 0x00000001UL, - 0x00000000UL, - 0x00000000UL, - 0x00000000UL, - 0x00000001UL, - 0x00000001UL, - 0x00000001UL, - 0x00000001UL, - 0x00000000UL, - 0x00000000UL, - 0x00000001UL, - 0x00000000UL, - 0x00000001UL, - 0x00000001UL, - 0x00000001UL, - 0x00000001UL, - 0x00000000UL, - 0x00000000UL, - 0x00000000UL, - 0x00000000UL, - 0x00000001UL, - 0x00000000UL, - 0x00000001UL, - 0x00000000UL }; - -const UINT32 KeccakF1600RoundConstants_int2_1[24] = { - 0x00000000UL, - 0x00000089UL, - 0x8000008bUL, - 0x80008080UL, - 0x0000008bUL, - 0x00008000UL, - 0x80008088UL, - 0x80000082UL, - 0x0000000bUL, - 0x0000000aUL, - 0x00008082UL, - 0x00008003UL, - 0x0000808bUL, - 0x8000000bUL, - 0x8000008aUL, - 0x80000081UL, - 0x80000081UL, - 0x80000008UL, - 0x00000083UL, - 0x80008003UL, - 0x80008088UL, - 0x80000088UL, - 0x00008000UL, - 0x80008082UL }; - -#define copyFromStateAndXor1024bits(X, state, input) \ - X##ba0 = state[ 0]^input[ 0]; \ - X##ba1 = state[ 1]^input[ 1]; \ - X##be0 = state[ 2]^input[ 2]; \ - X##be1 = state[ 3]^input[ 3]; \ - X##bi0 = state[ 4]^input[ 4]; \ - X##bi1 = state[ 5]^input[ 5]; \ - X##bo0 = state[ 6]^input[ 6]; \ - X##bo1 = state[ 7]^input[ 7]; \ - X##bu0 = state[ 8]^input[ 8]; \ - X##bu1 = state[ 9]^input[ 9]; \ - X##ga0 = state[10]^input[10]; \ - X##ga1 = state[11]^input[11]; \ - X##ge0 = state[12]^input[12]; \ - X##ge1 = state[13]^input[13]; \ - X##gi0 = state[14]^input[14]; \ - X##gi1 = state[15]^input[15]; \ - X##go0 = state[16]^input[16]; \ - X##go1 = state[17]^input[17]; \ - X##gu0 = state[18]^input[18]; \ - X##gu1 = state[19]^input[19]; \ - X##ka0 = state[20]^input[20]; \ - X##ka1 = state[21]^input[21]; \ - X##ke0 = state[22]^input[22]; \ - X##ke1 = state[23]^input[23]; \ - X##ki0 = state[24]^input[24]; \ - X##ki1 = state[25]^input[25]; \ - X##ko0 = state[26]^input[26]; \ - X##ko1 = state[27]^input[27]; \ - X##ku0 = state[28]^input[28]; \ - X##ku1 = state[29]^input[29]; \ - X##ma0 = state[30]^input[30]; \ - X##ma1 = state[31]^input[31]; \ - X##me0 = state[32]; \ - X##me1 = state[33]; \ - X##mi0 = state[34]; \ - X##mi1 = state[35]; \ - X##mo0 = state[36]; \ - X##mo1 = state[37]; \ - X##mu0 = state[38]; \ - X##mu1 = state[39]; \ - X##sa0 = state[40]; \ - X##sa1 = state[41]; \ - X##se0 = state[42]; \ - X##se1 = state[43]; \ - X##si0 = state[44]; \ - X##si1 = state[45]; \ - X##so0 = state[46]; \ - X##so1 = state[47]; \ - X##su0 = state[48]; \ - X##su1 = state[49]; \ - -#define copyFromStateAndXor1088bits(X, state, input) \ - X##ba0 = state[ 0]^input[ 0]; \ - X##ba1 = state[ 1]^input[ 1]; \ - X##be0 = state[ 2]^input[ 2]; \ - X##be1 = state[ 3]^input[ 3]; \ - X##bi0 = state[ 4]^input[ 4]; \ - X##bi1 = state[ 5]^input[ 5]; \ - X##bo0 = state[ 6]^input[ 6]; \ - X##bo1 = state[ 7]^input[ 7]; \ - X##bu0 = state[ 8]^input[ 8]; \ - X##bu1 = state[ 9]^input[ 9]; \ - X##ga0 = state[10]^input[10]; \ - X##ga1 = state[11]^input[11]; \ - X##ge0 = state[12]^input[12]; \ - X##ge1 = state[13]^input[13]; \ - X##gi0 = state[14]^input[14]; \ - X##gi1 = state[15]^input[15]; \ - X##go0 = state[16]^input[16]; \ - X##go1 = state[17]^input[17]; \ - X##gu0 = state[18]^input[18]; \ - X##gu1 = state[19]^input[19]; \ - X##ka0 = state[20]^input[20]; \ - X##ka1 = state[21]^input[21]; \ - X##ke0 = state[22]^input[22]; \ - X##ke1 = state[23]^input[23]; \ - X##ki0 = state[24]^input[24]; \ - X##ki1 = state[25]^input[25]; \ - X##ko0 = state[26]^input[26]; \ - X##ko1 = state[27]^input[27]; \ - X##ku0 = state[28]^input[28]; \ - X##ku1 = state[29]^input[29]; \ - X##ma0 = state[30]^input[30]; \ - X##ma1 = state[31]^input[31]; \ - X##me0 = state[32]^input[32]; \ - X##me1 = state[33]^input[33]; \ - X##mi0 = state[34]; \ - X##mi1 = state[35]; \ - X##mo0 = state[36]; \ - X##mo1 = state[37]; \ - X##mu0 = state[38]; \ - X##mu1 = state[39]; \ - X##sa0 = state[40]; \ - X##sa1 = state[41]; \ - X##se0 = state[42]; \ - X##se1 = state[43]; \ - X##si0 = state[44]; \ - X##si1 = state[45]; \ - X##so0 = state[46]; \ - X##so1 = state[47]; \ - X##su0 = state[48]; \ - X##su1 = state[49]; \ - -#define copyFromState(X, state) \ - X##ba0 = state[ 0]; \ - X##ba1 = state[ 1]; \ - X##be0 = state[ 2]; \ - X##be1 = state[ 3]; \ - X##bi0 = state[ 4]; \ - X##bi1 = state[ 5]; \ - X##bo0 = state[ 6]; \ - X##bo1 = state[ 7]; \ - X##bu0 = state[ 8]; \ - X##bu1 = state[ 9]; \ - X##ga0 = state[10]; \ - X##ga1 = state[11]; \ - X##ge0 = state[12]; \ - X##ge1 = state[13]; \ - X##gi0 = state[14]; \ - X##gi1 = state[15]; \ - X##go0 = state[16]; \ - X##go1 = state[17]; \ - X##gu0 = state[18]; \ - X##gu1 = state[19]; \ - X##ka0 = state[20]; \ - X##ka1 = state[21]; \ - X##ke0 = state[22]; \ - X##ke1 = state[23]; \ - X##ki0 = state[24]; \ - X##ki1 = state[25]; \ - X##ko0 = state[26]; \ - X##ko1 = state[27]; \ - X##ku0 = state[28]; \ - X##ku1 = state[29]; \ - X##ma0 = state[30]; \ - X##ma1 = state[31]; \ - X##me0 = state[32]; \ - X##me1 = state[33]; \ - X##mi0 = state[34]; \ - X##mi1 = state[35]; \ - X##mo0 = state[36]; \ - X##mo1 = state[37]; \ - X##mu0 = state[38]; \ - X##mu1 = state[39]; \ - X##sa0 = state[40]; \ - X##sa1 = state[41]; \ - X##se0 = state[42]; \ - X##se1 = state[43]; \ - X##si0 = state[44]; \ - X##si1 = state[45]; \ - X##so0 = state[46]; \ - X##so1 = state[47]; \ - X##su0 = state[48]; \ - X##su1 = state[49]; \ - -#define copyToState(state, X) \ - state[ 0] = X##ba0; \ - state[ 1] = X##ba1; \ - state[ 2] = X##be0; \ - state[ 3] = X##be1; \ - state[ 4] = X##bi0; \ - state[ 5] = X##bi1; \ - state[ 6] = X##bo0; \ - state[ 7] = X##bo1; \ - state[ 8] = X##bu0; \ - state[ 9] = X##bu1; \ - state[10] = X##ga0; \ - state[11] = X##ga1; \ - state[12] = X##ge0; \ - state[13] = X##ge1; \ - state[14] = X##gi0; \ - state[15] = X##gi1; \ - state[16] = X##go0; \ - state[17] = X##go1; \ - state[18] = X##gu0; \ - state[19] = X##gu1; \ - state[20] = X##ka0; \ - state[21] = X##ka1; \ - state[22] = X##ke0; \ - state[23] = X##ke1; \ - state[24] = X##ki0; \ - state[25] = X##ki1; \ - state[26] = X##ko0; \ - state[27] = X##ko1; \ - state[28] = X##ku0; \ - state[29] = X##ku1; \ - state[30] = X##ma0; \ - state[31] = X##ma1; \ - state[32] = X##me0; \ - state[33] = X##me1; \ - state[34] = X##mi0; \ - state[35] = X##mi1; \ - state[36] = X##mo0; \ - state[37] = X##mo1; \ - state[38] = X##mu0; \ - state[39] = X##mu1; \ - state[40] = X##sa0; \ - state[41] = X##sa1; \ - state[42] = X##se0; \ - state[43] = X##se1; \ - state[44] = X##si0; \ - state[45] = X##si1; \ - state[46] = X##so0; \ - state[47] = X##so1; \ - state[48] = X##su0; \ - state[49] = X##su1; \ - -#define copyStateVariables(X, Y) \ - X##ba0 = Y##ba0; \ - X##ba1 = Y##ba1; \ - X##be0 = Y##be0; \ - X##be1 = Y##be1; \ - X##bi0 = Y##bi0; \ - X##bi1 = Y##bi1; \ - X##bo0 = Y##bo0; \ - X##bo1 = Y##bo1; \ - X##bu0 = Y##bu0; \ - X##bu1 = Y##bu1; \ - X##ga0 = Y##ga0; \ - X##ga1 = Y##ga1; \ - X##ge0 = Y##ge0; \ - X##ge1 = Y##ge1; \ - X##gi0 = Y##gi0; \ - X##gi1 = Y##gi1; \ - X##go0 = Y##go0; \ - X##go1 = Y##go1; \ - X##gu0 = Y##gu0; \ - X##gu1 = Y##gu1; \ - X##ka0 = Y##ka0; \ - X##ka1 = Y##ka1; \ - X##ke0 = Y##ke0; \ - X##ke1 = Y##ke1; \ - X##ki0 = Y##ki0; \ - X##ki1 = Y##ki1; \ - X##ko0 = Y##ko0; \ - X##ko1 = Y##ko1; \ - X##ku0 = Y##ku0; \ - X##ku1 = Y##ku1; \ - X##ma0 = Y##ma0; \ - X##ma1 = Y##ma1; \ - X##me0 = Y##me0; \ - X##me1 = Y##me1; \ - X##mi0 = Y##mi0; \ - X##mi1 = Y##mi1; \ - X##mo0 = Y##mo0; \ - X##mo1 = Y##mo1; \ - X##mu0 = Y##mu0; \ - X##mu1 = Y##mu1; \ - X##sa0 = Y##sa0; \ - X##sa1 = Y##sa1; \ - X##se0 = Y##se0; \ - X##se1 = Y##se1; \ - X##si0 = Y##si0; \ - X##si1 = Y##si1; \ - X##so0 = Y##so0; \ - X##so1 = Y##so1; \ - X##su0 = Y##su0; \ - X##su1 = Y##su1; \ - diff --git a/Modules/_sha3/keccak/KeccakF-1600-32.macros b/Modules/_sha3/keccak/KeccakF-1600-32.macros deleted file mode 100644 index 9ade6000678f..000000000000 --- a/Modules/_sha3/keccak/KeccakF-1600-32.macros +++ /dev/null @@ -1,26 +0,0 @@ -/* -The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, -Michaël Peeters and Gilles Van Assche. For more information, feedback or -questions, please refer to our website: http://keccak.noekeon.org/ - -Implementation by the designers, -hereby denoted as "the implementer". - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#ifdef UseSchedule - #if (UseSchedule == 1) - #include "KeccakF-1600-32-s1.macros" - #elif (UseSchedule == 2) - #include "KeccakF-1600-32-s2.macros" - #elif (UseSchedule == 3) - #include "KeccakF-1600-32-rvk.macros" - #else - #error "This schedule is not supported." - #endif -#else - #include "KeccakF-1600-32-s1.macros" -#endif diff --git a/Modules/_sha3/keccak/KeccakF-1600-64.macros b/Modules/_sha3/keccak/KeccakF-1600-64.macros deleted file mode 100644 index dc0f78924d4b..000000000000 --- a/Modules/_sha3/keccak/KeccakF-1600-64.macros +++ /dev/null @@ -1,728 +0,0 @@ -/* -Code automatically generated by KeccakTools! - -The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, -Michaël Peeters and Gilles Van Assche. For more information, feedback or -questions, please refer to our website: http://keccak.noekeon.org/ - -Implementation by the designers, -hereby denoted as "the implementer". - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#define declareABCDE \ - UINT64 Aba, Abe, Abi, Abo, Abu; \ - UINT64 Aga, Age, Agi, Ago, Agu; \ - UINT64 Aka, Ake, Aki, Ako, Aku; \ - UINT64 Ama, Ame, Ami, Amo, Amu; \ - UINT64 Asa, Ase, Asi, Aso, Asu; \ - UINT64 Bba, Bbe, Bbi, Bbo, Bbu; \ - UINT64 Bga, Bge, Bgi, Bgo, Bgu; \ - UINT64 Bka, Bke, Bki, Bko, Bku; \ - UINT64 Bma, Bme, Bmi, Bmo, Bmu; \ - UINT64 Bsa, Bse, Bsi, Bso, Bsu; \ - UINT64 Ca, Ce, Ci, Co, Cu; \ - UINT64 Da, De, Di, Do, Du; \ - UINT64 Eba, Ebe, Ebi, Ebo, Ebu; \ - UINT64 Ega, Ege, Egi, Ego, Egu; \ - UINT64 Eka, Eke, Eki, Eko, Eku; \ - UINT64 Ema, Eme, Emi, Emo, Emu; \ - UINT64 Esa, Ese, Esi, Eso, Esu; \ - -#define prepareTheta \ - Ca = Aba^Aga^Aka^Ama^Asa; \ - Ce = Abe^Age^Ake^Ame^Ase; \ - Ci = Abi^Agi^Aki^Ami^Asi; \ - Co = Abo^Ago^Ako^Amo^Aso; \ - Cu = Abu^Agu^Aku^Amu^Asu; \ - -#ifdef UseBebigokimisa -/* --- Code for round, with prepare-theta (lane complementing pattern 'bebigokimisa') */ -/* --- 64-bit lanes mapped to 64-bit words */ -#define thetaRhoPiChiIotaPrepareTheta(i, A, E) \ - Da = Cu^ROL64(Ce, 1); \ - De = Ca^ROL64(Ci, 1); \ - Di = Ce^ROL64(Co, 1); \ - Do = Ci^ROL64(Cu, 1); \ - Du = Co^ROL64(Ca, 1); \ -\ - A##ba ^= Da; \ - Bba = A##ba; \ - A##ge ^= De; \ - Bbe = ROL64(A##ge, 44); \ - A##ki ^= Di; \ - Bbi = ROL64(A##ki, 43); \ - A##mo ^= Do; \ - Bbo = ROL64(A##mo, 21); \ - A##su ^= Du; \ - Bbu = ROL64(A##su, 14); \ - E##ba = Bba ^( Bbe | Bbi ); \ - E##ba ^= KeccakF1600RoundConstants[i]; \ - Ca = E##ba; \ - E##be = Bbe ^((~Bbi)| Bbo ); \ - Ce = E##be; \ - E##bi = Bbi ^( Bbo & Bbu ); \ - Ci = E##bi; \ - E##bo = Bbo ^( Bbu | Bba ); \ - Co = E##bo; \ - E##bu = Bbu ^( Bba & Bbe ); \ - Cu = E##bu; \ -\ - A##bo ^= Do; \ - Bga = ROL64(A##bo, 28); \ - A##gu ^= Du; \ - Bge = ROL64(A##gu, 20); \ - A##ka ^= Da; \ - Bgi = ROL64(A##ka, 3); \ - A##me ^= De; \ - Bgo = ROL64(A##me, 45); \ - A##si ^= Di; \ - Bgu = ROL64(A##si, 61); \ - E##ga = Bga ^( Bge | Bgi ); \ - Ca ^= E##ga; \ - E##ge = Bge ^( Bgi & Bgo ); \ - Ce ^= E##ge; \ - E##gi = Bgi ^( Bgo |(~Bgu)); \ - Ci ^= E##gi; \ - E##go = Bgo ^( Bgu | Bga ); \ - Co ^= E##go; \ - E##gu = Bgu ^( Bga & Bge ); \ - Cu ^= E##gu; \ -\ - A##be ^= De; \ - Bka = ROL64(A##be, 1); \ - A##gi ^= Di; \ - Bke = ROL64(A##gi, 6); \ - A##ko ^= Do; \ - Bki = ROL64(A##ko, 25); \ - A##mu ^= Du; \ - Bko = ROL64(A##mu, 8); \ - A##sa ^= Da; \ - Bku = ROL64(A##sa, 18); \ - E##ka = Bka ^( Bke | Bki ); \ - Ca ^= E##ka; \ - E##ke = Bke ^( Bki & Bko ); \ - Ce ^= E##ke; \ - E##ki = Bki ^((~Bko)& Bku ); \ - Ci ^= E##ki; \ - E##ko = (~Bko)^( Bku | Bka ); \ - Co ^= E##ko; \ - E##ku = Bku ^( Bka & Bke ); \ - Cu ^= E##ku; \ -\ - A##bu ^= Du; \ - Bma = ROL64(A##bu, 27); \ - A##ga ^= Da; \ - Bme = ROL64(A##ga, 36); \ - A##ke ^= De; \ - Bmi = ROL64(A##ke, 10); \ - A##mi ^= Di; \ - Bmo = ROL64(A##mi, 15); \ - A##so ^= Do; \ - Bmu = ROL64(A##so, 56); \ - E##ma = Bma ^( Bme & Bmi ); \ - Ca ^= E##ma; \ - E##me = Bme ^( Bmi | Bmo ); \ - Ce ^= E##me; \ - E##mi = Bmi ^((~Bmo)| Bmu ); \ - Ci ^= E##mi; \ - E##mo = (~Bmo)^( Bmu & Bma ); \ - Co ^= E##mo; \ - E##mu = Bmu ^( Bma | Bme ); \ - Cu ^= E##mu; \ -\ - A##bi ^= Di; \ - Bsa = ROL64(A##bi, 62); \ - A##go ^= Do; \ - Bse = ROL64(A##go, 55); \ - A##ku ^= Du; \ - Bsi = ROL64(A##ku, 39); \ - A##ma ^= Da; \ - Bso = ROL64(A##ma, 41); \ - A##se ^= De; \ - Bsu = ROL64(A##se, 2); \ - E##sa = Bsa ^((~Bse)& Bsi ); \ - Ca ^= E##sa; \ - E##se = (~Bse)^( Bsi | Bso ); \ - Ce ^= E##se; \ - E##si = Bsi ^( Bso & Bsu ); \ - Ci ^= E##si; \ - E##so = Bso ^( Bsu | Bsa ); \ - Co ^= E##so; \ - E##su = Bsu ^( Bsa & Bse ); \ - Cu ^= E##su; \ -\ - -/* --- Code for round (lane complementing pattern 'bebigokimisa') */ -/* --- 64-bit lanes mapped to 64-bit words */ -#define thetaRhoPiChiIota(i, A, E) \ - Da = Cu^ROL64(Ce, 1); \ - De = Ca^ROL64(Ci, 1); \ - Di = Ce^ROL64(Co, 1); \ - Do = Ci^ROL64(Cu, 1); \ - Du = Co^ROL64(Ca, 1); \ -\ - A##ba ^= Da; \ - Bba = A##ba; \ - A##ge ^= De; \ - Bbe = ROL64(A##ge, 44); \ - A##ki ^= Di; \ - Bbi = ROL64(A##ki, 43); \ - A##mo ^= Do; \ - Bbo = ROL64(A##mo, 21); \ - A##su ^= Du; \ - Bbu = ROL64(A##su, 14); \ - E##ba = Bba ^( Bbe | Bbi ); \ - E##ba ^= KeccakF1600RoundConstants[i]; \ - E##be = Bbe ^((~Bbi)| Bbo ); \ - E##bi = Bbi ^( Bbo & Bbu ); \ - E##bo = Bbo ^( Bbu | Bba ); \ - E##bu = Bbu ^( Bba & Bbe ); \ -\ - A##bo ^= Do; \ - Bga = ROL64(A##bo, 28); \ - A##gu ^= Du; \ - Bge = ROL64(A##gu, 20); \ - A##ka ^= Da; \ - Bgi = ROL64(A##ka, 3); \ - A##me ^= De; \ - Bgo = ROL64(A##me, 45); \ - A##si ^= Di; \ - Bgu = ROL64(A##si, 61); \ - E##ga = Bga ^( Bge | Bgi ); \ - E##ge = Bge ^( Bgi & Bgo ); \ - E##gi = Bgi ^( Bgo |(~Bgu)); \ - E##go = Bgo ^( Bgu | Bga ); \ - E##gu = Bgu ^( Bga & Bge ); \ -\ - A##be ^= De; \ - Bka = ROL64(A##be, 1); \ - A##gi ^= Di; \ - Bke = ROL64(A##gi, 6); \ - A##ko ^= Do; \ - Bki = ROL64(A##ko, 25); \ - A##mu ^= Du; \ - Bko = ROL64(A##mu, 8); \ - A##sa ^= Da; \ - Bku = ROL64(A##sa, 18); \ - E##ka = Bka ^( Bke | Bki ); \ - E##ke = Bke ^( Bki & Bko ); \ - E##ki = Bki ^((~Bko)& Bku ); \ - E##ko = (~Bko)^( Bku | Bka ); \ - E##ku = Bku ^( Bka & Bke ); \ -\ - A##bu ^= Du; \ - Bma = ROL64(A##bu, 27); \ - A##ga ^= Da; \ - Bme = ROL64(A##ga, 36); \ - A##ke ^= De; \ - Bmi = ROL64(A##ke, 10); \ - A##mi ^= Di; \ - Bmo = ROL64(A##mi, 15); \ - A##so ^= Do; \ - Bmu = ROL64(A##so, 56); \ - E##ma = Bma ^( Bme & Bmi ); \ - E##me = Bme ^( Bmi | Bmo ); \ - E##mi = Bmi ^((~Bmo)| Bmu ); \ - E##mo = (~Bmo)^( Bmu & Bma ); \ - E##mu = Bmu ^( Bma | Bme ); \ -\ - A##bi ^= Di; \ - Bsa = ROL64(A##bi, 62); \ - A##go ^= Do; \ - Bse = ROL64(A##go, 55); \ - A##ku ^= Du; \ - Bsi = ROL64(A##ku, 39); \ - A##ma ^= Da; \ - Bso = ROL64(A##ma, 41); \ - A##se ^= De; \ - Bsu = ROL64(A##se, 2); \ - E##sa = Bsa ^((~Bse)& Bsi ); \ - E##se = (~Bse)^( Bsi | Bso ); \ - E##si = Bsi ^( Bso & Bsu ); \ - E##so = Bso ^( Bsu | Bsa ); \ - E##su = Bsu ^( Bsa & Bse ); \ -\ - -#else /* UseBebigokimisa */ -/* --- Code for round, with prepare-theta */ -/* --- 64-bit lanes mapped to 64-bit words */ -#define thetaRhoPiChiIotaPrepareTheta(i, A, E) \ - Da = Cu^ROL64(Ce, 1); \ - De = Ca^ROL64(Ci, 1); \ - Di = Ce^ROL64(Co, 1); \ - Do = Ci^ROL64(Cu, 1); \ - Du = Co^ROL64(Ca, 1); \ -\ - A##ba ^= Da; \ - Bba = A##ba; \ - A##ge ^= De; \ - Bbe = ROL64(A##ge, 44); \ - A##ki ^= Di; \ - Bbi = ROL64(A##ki, 43); \ - A##mo ^= Do; \ - Bbo = ROL64(A##mo, 21); \ - A##su ^= Du; \ - Bbu = ROL64(A##su, 14); \ - E##ba = Bba ^((~Bbe)& Bbi ); \ - E##ba ^= KeccakF1600RoundConstants[i]; \ - Ca = E##ba; \ - E##be = Bbe ^((~Bbi)& Bbo ); \ - Ce = E##be; \ - E##bi = Bbi ^((~Bbo)& Bbu ); \ - Ci = E##bi; \ - E##bo = Bbo ^((~Bbu)& Bba ); \ - Co = E##bo; \ - E##bu = Bbu ^((~Bba)& Bbe ); \ - Cu = E##bu; \ -\ - A##bo ^= Do; \ - Bga = ROL64(A##bo, 28); \ - A##gu ^= Du; \ - Bge = ROL64(A##gu, 20); \ - A##ka ^= Da; \ - Bgi = ROL64(A##ka, 3); \ - A##me ^= De; \ - Bgo = ROL64(A##me, 45); \ - A##si ^= Di; \ - Bgu = ROL64(A##si, 61); \ - E##ga = Bga ^((~Bge)& Bgi ); \ - Ca ^= E##ga; \ - E##ge = Bge ^((~Bgi)& Bgo ); \ - Ce ^= E##ge; \ - E##gi = Bgi ^((~Bgo)& Bgu ); \ - Ci ^= E##gi; \ - E##go = Bgo ^((~Bgu)& Bga ); \ - Co ^= E##go; \ - E##gu = Bgu ^((~Bga)& Bge ); \ - Cu ^= E##gu; \ -\ - A##be ^= De; \ - Bka = ROL64(A##be, 1); \ - A##gi ^= Di; \ - Bke = ROL64(A##gi, 6); \ - A##ko ^= Do; \ - Bki = ROL64(A##ko, 25); \ - A##mu ^= Du; \ - Bko = ROL64(A##mu, 8); \ - A##sa ^= Da; \ - Bku = ROL64(A##sa, 18); \ - E##ka = Bka ^((~Bke)& Bki ); \ - Ca ^= E##ka; \ - E##ke = Bke ^((~Bki)& Bko ); \ - Ce ^= E##ke; \ - E##ki = Bki ^((~Bko)& Bku ); \ - Ci ^= E##ki; \ - E##ko = Bko ^((~Bku)& Bka ); \ - Co ^= E##ko; \ - E##ku = Bku ^((~Bka)& Bke ); \ - Cu ^= E##ku; \ -\ - A##bu ^= Du; \ - Bma = ROL64(A##bu, 27); \ - A##ga ^= Da; \ - Bme = ROL64(A##ga, 36); \ - A##ke ^= De; \ - Bmi = ROL64(A##ke, 10); \ - A##mi ^= Di; \ - Bmo = ROL64(A##mi, 15); \ - A##so ^= Do; \ - Bmu = ROL64(A##so, 56); \ - E##ma = Bma ^((~Bme)& Bmi ); \ - Ca ^= E##ma; \ - E##me = Bme ^((~Bmi)& Bmo ); \ - Ce ^= E##me; \ - E##mi = Bmi ^((~Bmo)& Bmu ); \ - Ci ^= E##mi; \ - E##mo = Bmo ^((~Bmu)& Bma ); \ - Co ^= E##mo; \ - E##mu = Bmu ^((~Bma)& Bme ); \ - Cu ^= E##mu; \ -\ - A##bi ^= Di; \ - Bsa = ROL64(A##bi, 62); \ - A##go ^= Do; \ - Bse = ROL64(A##go, 55); \ - A##ku ^= Du; \ - Bsi = ROL64(A##ku, 39); \ - A##ma ^= Da; \ - Bso = ROL64(A##ma, 41); \ - A##se ^= De; \ - Bsu = ROL64(A##se, 2); \ - E##sa = Bsa ^((~Bse)& Bsi ); \ - Ca ^= E##sa; \ - E##se = Bse ^((~Bsi)& Bso ); \ - Ce ^= E##se; \ - E##si = Bsi ^((~Bso)& Bsu ); \ - Ci ^= E##si; \ - E##so = Bso ^((~Bsu)& Bsa ); \ - Co ^= E##so; \ - E##su = Bsu ^((~Bsa)& Bse ); \ - Cu ^= E##su; \ -\ - -/* --- Code for round */ -/* --- 64-bit lanes mapped to 64-bit words */ -#define thetaRhoPiChiIota(i, A, E) \ - Da = Cu^ROL64(Ce, 1); \ - De = Ca^ROL64(Ci, 1); \ - Di = Ce^ROL64(Co, 1); \ - Do = Ci^ROL64(Cu, 1); \ - Du = Co^ROL64(Ca, 1); \ -\ - A##ba ^= Da; \ - Bba = A##ba; \ - A##ge ^= De; \ - Bbe = ROL64(A##ge, 44); \ - A##ki ^= Di; \ - Bbi = ROL64(A##ki, 43); \ - A##mo ^= Do; \ - Bbo = ROL64(A##mo, 21); \ - A##su ^= Du; \ - Bbu = ROL64(A##su, 14); \ - E##ba = Bba ^((~Bbe)& Bbi ); \ - E##ba ^= KeccakF1600RoundConstants[i]; \ - E##be = Bbe ^((~Bbi)& Bbo ); \ - E##bi = Bbi ^((~Bbo)& Bbu ); \ - E##bo = Bbo ^((~Bbu)& Bba ); \ - E##bu = Bbu ^((~Bba)& Bbe ); \ -\ - A##bo ^= Do; \ - Bga = ROL64(A##bo, 28); \ - A##gu ^= Du; \ - Bge = ROL64(A##gu, 20); \ - A##ka ^= Da; \ - Bgi = ROL64(A##ka, 3); \ - A##me ^= De; \ - Bgo = ROL64(A##me, 45); \ - A##si ^= Di; \ - Bgu = ROL64(A##si, 61); \ - E##ga = Bga ^((~Bge)& Bgi ); \ - E##ge = Bge ^((~Bgi)& Bgo ); \ - E##gi = Bgi ^((~Bgo)& Bgu ); \ - E##go = Bgo ^((~Bgu)& Bga ); \ - E##gu = Bgu ^((~Bga)& Bge ); \ -\ - A##be ^= De; \ - Bka = ROL64(A##be, 1); \ - A##gi ^= Di; \ - Bke = ROL64(A##gi, 6); \ - A##ko ^= Do; \ - Bki = ROL64(A##ko, 25); \ - A##mu ^= Du; \ - Bko = ROL64(A##mu, 8); \ - A##sa ^= Da; \ - Bku = ROL64(A##sa, 18); \ - E##ka = Bka ^((~Bke)& Bki ); \ - E##ke = Bke ^((~Bki)& Bko ); \ - E##ki = Bki ^((~Bko)& Bku ); \ - E##ko = Bko ^((~Bku)& Bka ); \ - E##ku = Bku ^((~Bka)& Bke ); \ -\ - A##bu ^= Du; \ - Bma = ROL64(A##bu, 27); \ - A##ga ^= Da; \ - Bme = ROL64(A##ga, 36); \ - A##ke ^= De; \ - Bmi = ROL64(A##ke, 10); \ - A##mi ^= Di; \ - Bmo = ROL64(A##mi, 15); \ - A##so ^= Do; \ - Bmu = ROL64(A##so, 56); \ - E##ma = Bma ^((~Bme)& Bmi ); \ - E##me = Bme ^((~Bmi)& Bmo ); \ - E##mi = Bmi ^((~Bmo)& Bmu ); \ - E##mo = Bmo ^((~Bmu)& Bma ); \ - E##mu = Bmu ^((~Bma)& Bme ); \ -\ - A##bi ^= Di; \ - Bsa = ROL64(A##bi, 62); \ - A##go ^= Do; \ - Bse = ROL64(A##go, 55); \ - A##ku ^= Du; \ - Bsi = ROL64(A##ku, 39); \ - A##ma ^= Da; \ - Bso = ROL64(A##ma, 41); \ - A##se ^= De; \ - Bsu = ROL64(A##se, 2); \ - E##sa = Bsa ^((~Bse)& Bsi ); \ - E##se = Bse ^((~Bsi)& Bso ); \ - E##si = Bsi ^((~Bso)& Bsu ); \ - E##so = Bso ^((~Bsu)& Bsa ); \ - E##su = Bsu ^((~Bsa)& Bse ); \ -\ - -#endif /* UseBebigokimisa */ - -static const UINT64 KeccakF1600RoundConstants[24] = { - 0x0000000000000001ULL, - 0x0000000000008082ULL, - 0x800000000000808aULL, - 0x8000000080008000ULL, - 0x000000000000808bULL, - 0x0000000080000001ULL, - 0x8000000080008081ULL, - 0x8000000000008009ULL, - 0x000000000000008aULL, - 0x0000000000000088ULL, - 0x0000000080008009ULL, - 0x000000008000000aULL, - 0x000000008000808bULL, - 0x800000000000008bULL, - 0x8000000000008089ULL, - 0x8000000000008003ULL, - 0x8000000000008002ULL, - 0x8000000000000080ULL, - 0x000000000000800aULL, - 0x800000008000000aULL, - 0x8000000080008081ULL, - 0x8000000000008080ULL, - 0x0000000080000001ULL, - 0x8000000080008008ULL }; - -#define copyFromStateAndXor576bits(X, state, input) \ - X##ba = state[ 0]^input[ 0]; \ - X##be = state[ 1]^input[ 1]; \ - X##bi = state[ 2]^input[ 2]; \ - X##bo = state[ 3]^input[ 3]; \ - X##bu = state[ 4]^input[ 4]; \ - X##ga = state[ 5]^input[ 5]; \ - X##ge = state[ 6]^input[ 6]; \ - X##gi = state[ 7]^input[ 7]; \ - X##go = state[ 8]^input[ 8]; \ - X##gu = state[ 9]; \ - X##ka = state[10]; \ - X##ke = state[11]; \ - X##ki = state[12]; \ - X##ko = state[13]; \ - X##ku = state[14]; \ - X##ma = state[15]; \ - X##me = state[16]; \ - X##mi = state[17]; \ - X##mo = state[18]; \ - X##mu = state[19]; \ - X##sa = state[20]; \ - X##se = state[21]; \ - X##si = state[22]; \ - X##so = state[23]; \ - X##su = state[24]; \ - -#define copyFromStateAndXor832bits(X, state, input) \ - X##ba = state[ 0]^input[ 0]; \ - X##be = state[ 1]^input[ 1]; \ - X##bi = state[ 2]^input[ 2]; \ - X##bo = state[ 3]^input[ 3]; \ - X##bu = state[ 4]^input[ 4]; \ - X##ga = state[ 5]^input[ 5]; \ - X##ge = state[ 6]^input[ 6]; \ - X##gi = state[ 7]^input[ 7]; \ - X##go = state[ 8]^input[ 8]; \ - X##gu = state[ 9]^input[ 9]; \ - X##ka = state[10]^input[10]; \ - X##ke = state[11]^input[11]; \ - X##ki = state[12]^input[12]; \ - X##ko = state[13]; \ - X##ku = state[14]; \ - X##ma = state[15]; \ - X##me = state[16]; \ - X##mi = state[17]; \ - X##mo = state[18]; \ - X##mu = state[19]; \ - X##sa = state[20]; \ - X##se = state[21]; \ - X##si = state[22]; \ - X##so = state[23]; \ - X##su = state[24]; \ - -#define copyFromStateAndXor1024bits(X, state, input) \ - X##ba = state[ 0]^input[ 0]; \ - X##be = state[ 1]^input[ 1]; \ - X##bi = state[ 2]^input[ 2]; \ - X##bo = state[ 3]^input[ 3]; \ - X##bu = state[ 4]^input[ 4]; \ - X##ga = state[ 5]^input[ 5]; \ - X##ge = state[ 6]^input[ 6]; \ - X##gi = state[ 7]^input[ 7]; \ - X##go = state[ 8]^input[ 8]; \ - X##gu = state[ 9]^input[ 9]; \ - X##ka = state[10]^input[10]; \ - X##ke = state[11]^input[11]; \ - X##ki = state[12]^input[12]; \ - X##ko = state[13]^input[13]; \ - X##ku = state[14]^input[14]; \ - X##ma = state[15]^input[15]; \ - X##me = state[16]; \ - X##mi = state[17]; \ - X##mo = state[18]; \ - X##mu = state[19]; \ - X##sa = state[20]; \ - X##se = state[21]; \ - X##si = state[22]; \ - X##so = state[23]; \ - X##su = state[24]; \ - -#define copyFromStateAndXor1088bits(X, state, input) \ - X##ba = state[ 0]^input[ 0]; \ - X##be = state[ 1]^input[ 1]; \ - X##bi = state[ 2]^input[ 2]; \ - X##bo = state[ 3]^input[ 3]; \ - X##bu = state[ 4]^input[ 4]; \ - X##ga = state[ 5]^input[ 5]; \ - X##ge = state[ 6]^input[ 6]; \ - X##gi = state[ 7]^input[ 7]; \ - X##go = state[ 8]^input[ 8]; \ - X##gu = state[ 9]^input[ 9]; \ - X##ka = state[10]^input[10]; \ - X##ke = state[11]^input[11]; \ - X##ki = state[12]^input[12]; \ - X##ko = state[13]^input[13]; \ - X##ku = state[14]^input[14]; \ - X##ma = state[15]^input[15]; \ - X##me = state[16]^input[16]; \ - X##mi = state[17]; \ - X##mo = state[18]; \ - X##mu = state[19]; \ - X##sa = state[20]; \ - X##se = state[21]; \ - X##si = state[22]; \ - X##so = state[23]; \ - X##su = state[24]; \ - -#define copyFromStateAndXor1152bits(X, state, input) \ - X##ba = state[ 0]^input[ 0]; \ - X##be = state[ 1]^input[ 1]; \ - X##bi = state[ 2]^input[ 2]; \ - X##bo = state[ 3]^input[ 3]; \ - X##bu = state[ 4]^input[ 4]; \ - X##ga = state[ 5]^input[ 5]; \ - X##ge = state[ 6]^input[ 6]; \ - X##gi = state[ 7]^input[ 7]; \ - X##go = state[ 8]^input[ 8]; \ - X##gu = state[ 9]^input[ 9]; \ - X##ka = state[10]^input[10]; \ - X##ke = state[11]^input[11]; \ - X##ki = state[12]^input[12]; \ - X##ko = state[13]^input[13]; \ - X##ku = state[14]^input[14]; \ - X##ma = state[15]^input[15]; \ - X##me = state[16]^input[16]; \ - X##mi = state[17]^input[17]; \ - X##mo = state[18]; \ - X##mu = state[19]; \ - X##sa = state[20]; \ - X##se = state[21]; \ - X##si = state[22]; \ - X##so = state[23]; \ - X##su = state[24]; \ - -#define copyFromStateAndXor1344bits(X, state, input) \ - X##ba = state[ 0]^input[ 0]; \ - X##be = state[ 1]^input[ 1]; \ - X##bi = state[ 2]^input[ 2]; \ - X##bo = state[ 3]^input[ 3]; \ - X##bu = state[ 4]^input[ 4]; \ - X##ga = state[ 5]^input[ 5]; \ - X##ge = state[ 6]^input[ 6]; \ - X##gi = state[ 7]^input[ 7]; \ - X##go = state[ 8]^input[ 8]; \ - X##gu = state[ 9]^input[ 9]; \ - X##ka = state[10]^input[10]; \ - X##ke = state[11]^input[11]; \ - X##ki = state[12]^input[12]; \ - X##ko = state[13]^input[13]; \ - X##ku = state[14]^input[14]; \ - X##ma = state[15]^input[15]; \ - X##me = state[16]^input[16]; \ - X##mi = state[17]^input[17]; \ - X##mo = state[18]^input[18]; \ - X##mu = state[19]^input[19]; \ - X##sa = state[20]^input[20]; \ - X##se = state[21]; \ - X##si = state[22]; \ - X##so = state[23]; \ - X##su = state[24]; \ - -#define copyFromState(X, state) \ - X##ba = state[ 0]; \ - X##be = state[ 1]; \ - X##bi = state[ 2]; \ - X##bo = state[ 3]; \ - X##bu = state[ 4]; \ - X##ga = state[ 5]; \ - X##ge = state[ 6]; \ - X##gi = state[ 7]; \ - X##go = state[ 8]; \ - X##gu = state[ 9]; \ - X##ka = state[10]; \ - X##ke = state[11]; \ - X##ki = state[12]; \ - X##ko = state[13]; \ - X##ku = state[14]; \ - X##ma = state[15]; \ - X##me = state[16]; \ - X##mi = state[17]; \ - X##mo = state[18]; \ - X##mu = state[19]; \ - X##sa = state[20]; \ - X##se = state[21]; \ - X##si = state[22]; \ - X##so = state[23]; \ - X##su = state[24]; \ - -#define copyToState(state, X) \ - state[ 0] = X##ba; \ - state[ 1] = X##be; \ - state[ 2] = X##bi; \ - state[ 3] = X##bo; \ - state[ 4] = X##bu; \ - state[ 5] = X##ga; \ - state[ 6] = X##ge; \ - state[ 7] = X##gi; \ - state[ 8] = X##go; \ - state[ 9] = X##gu; \ - state[10] = X##ka; \ - state[11] = X##ke; \ - state[12] = X##ki; \ - state[13] = X##ko; \ - state[14] = X##ku; \ - state[15] = X##ma; \ - state[16] = X##me; \ - state[17] = X##mi; \ - state[18] = X##mo; \ - state[19] = X##mu; \ - state[20] = X##sa; \ - state[21] = X##se; \ - state[22] = X##si; \ - state[23] = X##so; \ - state[24] = X##su; \ - -#define copyStateVariables(X, Y) \ - X##ba = Y##ba; \ - X##be = Y##be; \ - X##bi = Y##bi; \ - X##bo = Y##bo; \ - X##bu = Y##bu; \ - X##ga = Y##ga; \ - X##ge = Y##ge; \ - X##gi = Y##gi; \ - X##go = Y##go; \ - X##gu = Y##gu; \ - X##ka = Y##ka; \ - X##ke = Y##ke; \ - X##ki = Y##ki; \ - X##ko = Y##ko; \ - X##ku = Y##ku; \ - X##ma = Y##ma; \ - X##me = Y##me; \ - X##mi = Y##mi; \ - X##mo = Y##mo; \ - X##mu = Y##mu; \ - X##sa = Y##sa; \ - X##se = Y##se; \ - X##si = Y##si; \ - X##so = Y##so; \ - X##su = Y##su; \ - diff --git a/Modules/_sha3/keccak/KeccakF-1600-int-set.h b/Modules/_sha3/keccak/KeccakF-1600-int-set.h deleted file mode 100644 index 0ed1d802e3e3..000000000000 --- a/Modules/_sha3/keccak/KeccakF-1600-int-set.h +++ /dev/null @@ -1,6 +0,0 @@ -#define ProvideFast576 -#define ProvideFast832 -#define ProvideFast1024 -#define ProvideFast1088 -#define ProvideFast1152 -#define ProvideFast1344 diff --git a/Modules/_sha3/keccak/KeccakF-1600-interface.h b/Modules/_sha3/keccak/KeccakF-1600-interface.h deleted file mode 100644 index ce2710eeb22d..000000000000 --- a/Modules/_sha3/keccak/KeccakF-1600-interface.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, -Michaël Peeters and Gilles Van Assche. For more information, feedback or -questions, please refer to our website: http://keccak.noekeon.org/ - -Implementation by the designers, -hereby denoted as "the implementer". - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#ifndef _KeccakPermutationInterface_h_ -#define _KeccakPermutationInterface_h_ - -#include "KeccakF-1600-int-set.h" - -static void KeccakInitialize( void ); -static void KeccakInitializeState(unsigned char *state); -static void KeccakPermutation(unsigned char *state); -#ifdef ProvideFast576 -static void KeccakAbsorb576bits(unsigned char *state, const unsigned char *data); -#endif -#ifdef ProvideFast832 -static void KeccakAbsorb832bits(unsigned char *state, const unsigned char *data); -#endif -#ifdef ProvideFast1024 -static void KeccakAbsorb1024bits(unsigned char *state, const unsigned char *data); -#endif -#ifdef ProvideFast1088 -static void KeccakAbsorb1088bits(unsigned char *state, const unsigned char *data); -#endif -#ifdef ProvideFast1152 -static void KeccakAbsorb1152bits(unsigned char *state, const unsigned char *data); -#endif -#ifdef ProvideFast1344 -static void KeccakAbsorb1344bits(unsigned char *state, const unsigned char *data); -#endif -static void KeccakAbsorb(unsigned char *state, const unsigned char *data, unsigned int laneCount); -#ifdef ProvideFast1024 -static void KeccakExtract1024bits(const unsigned char *state, unsigned char *data); -#endif -static void KeccakExtract(const unsigned char *state, unsigned char *data, unsigned int laneCount); - -#endif diff --git a/Modules/_sha3/keccak/KeccakF-1600-opt32-settings.h b/Modules/_sha3/keccak/KeccakF-1600-opt32-settings.h deleted file mode 100644 index 615c78217e3c..000000000000 --- a/Modules/_sha3/keccak/KeccakF-1600-opt32-settings.h +++ /dev/null @@ -1,6 +0,0 @@ -/* -#define Unrolling 2 -#define UseBebigokimisa -#define UseInterleaveTables -#define UseSchedule 3 -*/ diff --git a/Modules/_sha3/keccak/KeccakF-1600-opt32.c b/Modules/_sha3/keccak/KeccakF-1600-opt32.c deleted file mode 100644 index c52bfb7fd7c0..000000000000 --- a/Modules/_sha3/keccak/KeccakF-1600-opt32.c +++ /dev/null @@ -1,524 +0,0 @@ -/* -The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, -Michaël Peeters and Gilles Van Assche. For more information, feedback or -questions, please refer to our website: http://keccak.noekeon.org/ - -Implementation by the designers, -hereby denoted as "the implementer". - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#include -/* #include "brg_endian.h" */ -#include "KeccakF-1600-opt32-settings.h" -#include "KeccakF-1600-interface.h" - -typedef unsigned char UINT8; -typedef unsigned short UINT16; -typedef unsigned int UINT32; -/* typedef unsigned long long int UINT64; */ - -#ifdef UseInterleaveTables -static int interleaveTablesBuilt = 0; -static UINT16 interleaveTable[65536]; -static UINT16 deinterleaveTable[65536]; - -static void buildInterleaveTables() -{ - UINT32 i, j; - UINT16 x; - - if (!interleaveTablesBuilt) { - for(i=0; i<65536; i++) { - x = 0; - for(j=0; j<16; j++) { - if (i & (1 << j)) - x |= (1 << (j/2 + 8*(j%2))); - } - interleaveTable[i] = x; - deinterleaveTable[x] = (UINT16)i; - } - interleaveTablesBuilt = 1; - } -} - -#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) - -#define xor2bytesIntoInterleavedWords(even, odd, source, j) \ - i##j = interleaveTable[((const UINT16*)source)[j]]; \ - ((UINT8*)even)[j] ^= i##j & 0xFF; \ - ((UINT8*)odd)[j] ^= i##j >> 8; - -#define setInterleavedWordsInto2bytes(dest, even, odd, j) \ - d##j = deinterleaveTable[((even >> (j*8)) & 0xFF) ^ (((odd >> (j*8)) & 0xFF) << 8)]; \ - ((UINT16*)dest)[j] = d##j; - -#else /* (PLATFORM_BYTE_ORDER == IS_BIG_ENDIAN) */ - -#define xor2bytesIntoInterleavedWords(even, odd, source, j) \ - i##j = interleaveTable[source[2*j] ^ ((UINT16)source[2*j+1] << 8)]; \ - *even ^= (i##j & 0xFF) << (j*8); \ - *odd ^= ((i##j >> 8) & 0xFF) << (j*8); - -#define setInterleavedWordsInto2bytes(dest, even, odd, j) \ - d##j = deinterleaveTable[((even >> (j*8)) & 0xFF) ^ (((odd >> (j*8)) & 0xFF) << 8)]; \ - dest[2*j] = d##j & 0xFF; \ - dest[2*j+1] = d##j >> 8; - -#endif /* Endianness */ - -static void xor8bytesIntoInterleavedWords(UINT32 *even, UINT32 *odd, const UINT8* source) -{ - UINT16 i0, i1, i2, i3; - - xor2bytesIntoInterleavedWords(even, odd, source, 0) - xor2bytesIntoInterleavedWords(even, odd, source, 1) - xor2bytesIntoInterleavedWords(even, odd, source, 2) - xor2bytesIntoInterleavedWords(even, odd, source, 3) -} - -#define xorLanesIntoState(laneCount, state, input) \ - { \ - int i; \ - for(i=0; i<(laneCount); i++) \ - xor8bytesIntoInterleavedWords(state+i*2, state+i*2+1, input+i*8); \ - } - -static void setInterleavedWordsInto8bytes(UINT8* dest, UINT32 even, UINT32 odd) -{ - UINT16 d0, d1, d2, d3; - - setInterleavedWordsInto2bytes(dest, even, odd, 0) - setInterleavedWordsInto2bytes(dest, even, odd, 1) - setInterleavedWordsInto2bytes(dest, even, odd, 2) - setInterleavedWordsInto2bytes(dest, even, odd, 3) -} - -#define extractLanes(laneCount, state, data) \ - { \ - int i; \ - for(i=0; i<(laneCount); i++) \ - setInterleavedWordsInto8bytes(data+i*8, ((UINT32*)state)[i*2], ((UINT32*)state)[i*2+1]); \ - } - -#else /* No interleaving tables */ - -#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) - -/* Credit: Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 */ -#define xorInterleavedLE(rateInLanes, state, input) \ - { \ - const UINT32 * pI = (const UINT32 *)input; \ - UINT32 * pS = state; \ - UINT32 t, x0, x1; \ - int i; \ - for (i = (rateInLanes)-1; i >= 0; --i) \ - { \ - x0 = *(pI++); \ - t = (x0 ^ (x0 >> 1)) & 0x22222222UL; x0 = x0 ^ t ^ (t << 1); \ - t = (x0 ^ (x0 >> 2)) & 0x0C0C0C0CUL; x0 = x0 ^ t ^ (t << 2); \ - t = (x0 ^ (x0 >> 4)) & 0x00F000F0UL; x0 = x0 ^ t ^ (t << 4); \ - t = (x0 ^ (x0 >> 8)) & 0x0000FF00UL; x0 = x0 ^ t ^ (t << 8); \ - x1 = *(pI++); \ - t = (x1 ^ (x1 >> 1)) & 0x22222222UL; x1 = x1 ^ t ^ (t << 1); \ - t = (x1 ^ (x1 >> 2)) & 0x0C0C0C0CUL; x1 = x1 ^ t ^ (t << 2); \ - t = (x1 ^ (x1 >> 4)) & 0x00F000F0UL; x1 = x1 ^ t ^ (t << 4); \ - t = (x1 ^ (x1 >> 8)) & 0x0000FF00UL; x1 = x1 ^ t ^ (t << 8); \ - *(pS++) ^= (UINT16)x0 | (x1 << 16); \ - *(pS++) ^= (x0 >> 16) | (x1 & 0xFFFF0000); \ - } \ - } - -#define xorLanesIntoState(laneCount, state, input) \ - xorInterleavedLE(laneCount, state, input) - -#else /* (PLATFORM_BYTE_ORDER == IS_BIG_ENDIAN) */ - -/* Credit: Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 */ -UINT64 toInterleaving(UINT64 x) -{ - UINT64 t; - - t = (x ^ (x >> 1)) & 0x2222222222222222ULL; x = x ^ t ^ (t << 1); - t = (x ^ (x >> 2)) & 0x0C0C0C0C0C0C0C0CULL; x = x ^ t ^ (t << 2); - t = (x ^ (x >> 4)) & 0x00F000F000F000F0ULL; x = x ^ t ^ (t << 4); - t = (x ^ (x >> 8)) & 0x0000FF000000FF00ULL; x = x ^ t ^ (t << 8); - t = (x ^ (x >> 16)) & 0x00000000FFFF0000ULL; x = x ^ t ^ (t << 16); - - return x; -} - -static void xor8bytesIntoInterleavedWords(UINT32* evenAndOdd, const UINT8* source) -{ - /* This can be optimized */ - UINT64 sourceWord = - (UINT64)source[0] - ^ (((UINT64)source[1]) << 8) - ^ (((UINT64)source[2]) << 16) - ^ (((UINT64)source[3]) << 24) - ^ (((UINT64)source[4]) << 32) - ^ (((UINT64)source[5]) << 40) - ^ (((UINT64)source[6]) << 48) - ^ (((UINT64)source[7]) << 56); - UINT64 evenAndOddWord = toInterleaving(sourceWord); - evenAndOdd[0] ^= (UINT32)evenAndOddWord; - evenAndOdd[1] ^= (UINT32)(evenAndOddWord >> 32); -} - -#define xorLanesIntoState(laneCount, state, input) \ - { \ - int i; \ - for(i=0; i<(laneCount); i++) \ - xor8bytesIntoInterleavedWords(state+i*2, input+i*8); \ - } - -#endif /* Endianness */ - -/* Credit: Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 */ -UINT64 fromInterleaving(UINT64 x) -{ - UINT64 t; - - t = (x ^ (x >> 16)) & 0x00000000FFFF0000ULL; x = x ^ t ^ (t << 16); - t = (x ^ (x >> 8)) & 0x0000FF000000FF00ULL; x = x ^ t ^ (t << 8); - t = (x ^ (x >> 4)) & 0x00F000F000F000F0ULL; x = x ^ t ^ (t << 4); - t = (x ^ (x >> 2)) & 0x0C0C0C0C0C0C0C0CULL; x = x ^ t ^ (t << 2); - t = (x ^ (x >> 1)) & 0x2222222222222222ULL; x = x ^ t ^ (t << 1); - - return x; -} - -static void setInterleavedWordsInto8bytes(UINT8* dest, UINT32* evenAndOdd) -{ -#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) - ((UINT64*)dest)[0] = fromInterleaving(*(UINT64*)evenAndOdd); -#else /* (PLATFORM_BYTE_ORDER == IS_BIG_ENDIAN) */ - /* This can be optimized */ - UINT64 evenAndOddWord = (UINT64)evenAndOdd[0] ^ ((UINT64)evenAndOdd[1] << 32); - UINT64 destWord = fromInterleaving(evenAndOddWord); - dest[0] = destWord & 0xFF; - dest[1] = (destWord >> 8) & 0xFF; - dest[2] = (destWord >> 16) & 0xFF; - dest[3] = (destWord >> 24) & 0xFF; - dest[4] = (destWord >> 32) & 0xFF; - dest[5] = (destWord >> 40) & 0xFF; - dest[6] = (destWord >> 48) & 0xFF; - dest[7] = (destWord >> 56) & 0xFF; -#endif /* Endianness */ -} - -#define extractLanes(laneCount, state, data) \ - { \ - unsigned int i; \ - for(i=0; i<(laneCount); i++) \ - setInterleavedWordsInto8bytes(data+i*8, (UINT32*)state+i*2); \ - } - -#endif /* With or without interleaving tables */ - -#if defined(_MSC_VER) -#define ROL32(a, offset) _rotl(a, offset) -#elif (defined (__arm__) && defined(__ARMCC_VERSION)) -#define ROL32(a, offset) __ror(a, 32-(offset)) -#else -#define ROL32(a, offset) ((((UINT32)a) << (offset)) ^ (((UINT32)a) >> (32-(offset)))) -#endif - -#include "KeccakF-1600-unrolling.macros" -#include "KeccakF-1600-32.macros" - -#if (UseSchedule == 3) - -#ifdef UseBebigokimisa -#error "No lane complementing with schedule 3." -#endif - -#if (Unrolling != 2) -#error "Only unrolling 2 is supported by schedule 3." -#endif - -static void KeccakPermutationOnWords(UINT32 *state) -{ - rounds -} - -static void KeccakPermutationOnWordsAfterXoring(UINT32 *state, const UINT8 *input, unsigned int laneCount) -{ - xorLanesIntoState(laneCount, state, input) - rounds -} - -#ifdef ProvideFast576 -static void KeccakPermutationOnWordsAfterXoring576bits(UINT32 *state, const UINT8 *input) -{ - xorLanesIntoState(9, state, input) - rounds -} -#endif - -#ifdef ProvideFast832 -static void KeccakPermutationOnWordsAfterXoring832bits(UINT32 *state, const UINT8 *input) -{ - xorLanesIntoState(13, state, input) - rounds -} -#endif - -#ifdef ProvideFast1024 -static void KeccakPermutationOnWordsAfterXoring1024bits(UINT32 *state, const UINT8 *input) -{ - xorLanesIntoState(16, state, input) - rounds -} -#endif - -#ifdef ProvideFast1088 -static void KeccakPermutationOnWordsAfterXoring1088bits(UINT32 *state, const UINT8 *input) -{ - xorLanesIntoState(17, state, input) - rounds -} -#endif - -#ifdef ProvideFast1152 -static void KeccakPermutationOnWordsAfterXoring1152bits(UINT32 *state, const UINT8 *input) -{ - xorLanesIntoState(18, state, input) - rounds -} -#endif - -#ifdef ProvideFast1344 -static void KeccakPermutationOnWordsAfterXoring1344bits(UINT32 *state, const UINT8 *input) -{ - xorLanesIntoState(21, state, input) - rounds -} -#endif - -#else /* (Schedule != 3) */ - -static void KeccakPermutationOnWords(UINT32 *state) -{ - declareABCDE -#if (Unrolling != 24) - unsigned int i; -#endif - - copyFromState(A, state) - rounds -} - -static void KeccakPermutationOnWordsAfterXoring(UINT32 *state, const UINT8 *input, unsigned int laneCount) -{ - declareABCDE - unsigned int i; - - xorLanesIntoState(laneCount, state, input) - copyFromState(A, state) - rounds -} - -#ifdef ProvideFast576 -static void KeccakPermutationOnWordsAfterXoring576bits(UINT32 *state, const UINT8 *input) -{ - declareABCDE - unsigned int i; - - xorLanesIntoState(9, state, input) - copyFromState(A, state) - rounds -} -#endif - -#ifdef ProvideFast832 -static void KeccakPermutationOnWordsAfterXoring832bits(UINT32 *state, const UINT8 *input) -{ - declareABCDE - unsigned int i; - - xorLanesIntoState(13, state, input) - copyFromState(A, state) - rounds -} -#endif - -#ifdef ProvideFast1024 -static void KeccakPermutationOnWordsAfterXoring1024bits(UINT32 *state, const UINT8 *input) -{ - declareABCDE - unsigned int i; - - xorLanesIntoState(16, state, input) - copyFromState(A, state) - rounds -} -#endif - -#ifdef ProvideFast1088 -static void KeccakPermutationOnWordsAfterXoring1088bits(UINT32 *state, const UINT8 *input) -{ - declareABCDE - unsigned int i; - - xorLanesIntoState(17, state, input) - copyFromState(A, state) - rounds -} -#endif - -#ifdef ProvideFast1152 -static void KeccakPermutationOnWordsAfterXoring1152bits(UINT32 *state, const UINT8 *input) -{ - declareABCDE - unsigned int i; - - xorLanesIntoState(18, state, input) - copyFromState(A, state) - rounds -} -#endif - -#ifdef ProvideFast1344 -static void KeccakPermutationOnWordsAfterXoring1344bits(UINT32 *state, const UINT8 *input) -{ - declareABCDE - unsigned int i; - - xorLanesIntoState(21, state, input) - copyFromState(A, state) - rounds -} -#endif - -#endif - -static void KeccakInitialize() -{ -#ifdef UseInterleaveTables - buildInterleaveTables(); -#endif -} - -static void KeccakInitializeState(unsigned char *state) -{ - memset(state, 0, 200); -#ifdef UseBebigokimisa - ((UINT32*)state)[ 2] = ~(UINT32)0; - ((UINT32*)state)[ 3] = ~(UINT32)0; - ((UINT32*)state)[ 4] = ~(UINT32)0; - ((UINT32*)state)[ 5] = ~(UINT32)0; - ((UINT32*)state)[16] = ~(UINT32)0; - ((UINT32*)state)[17] = ~(UINT32)0; - ((UINT32*)state)[24] = ~(UINT32)0; - ((UINT32*)state)[25] = ~(UINT32)0; - ((UINT32*)state)[34] = ~(UINT32)0; - ((UINT32*)state)[35] = ~(UINT32)0; - ((UINT32*)state)[40] = ~(UINT32)0; - ((UINT32*)state)[41] = ~(UINT32)0; -#endif -} - -static void KeccakPermutation(unsigned char *state) -{ - /* We assume the state is always stored as interleaved 32-bit words */ - KeccakPermutationOnWords((UINT32*)state); -} - -#ifdef ProvideFast576 -static void KeccakAbsorb576bits(unsigned char *state, const unsigned char *data) -{ - KeccakPermutationOnWordsAfterXoring576bits((UINT32*)state, data); -} -#endif - -#ifdef ProvideFast832 -static void KeccakAbsorb832bits(unsigned char *state, const unsigned char *data) -{ - KeccakPermutationOnWordsAfterXoring832bits((UINT32*)state, data); -} -#endif - -#ifdef ProvideFast1024 -static void KeccakAbsorb1024bits(unsigned char *state, const unsigned char *data) -{ - KeccakPermutationOnWordsAfterXoring1024bits((UINT32*)state, data); -} -#endif - -#ifdef ProvideFast1088 -static void KeccakAbsorb1088bits(unsigned char *state, const unsigned char *data) -{ - KeccakPermutationOnWordsAfterXoring1088bits((UINT32*)state, data); -} -#endif - -#ifdef ProvideFast1152 -static void KeccakAbsorb1152bits(unsigned char *state, const unsigned char *data) -{ - KeccakPermutationOnWordsAfterXoring1152bits((UINT32*)state, data); -} -#endif - -#ifdef ProvideFast1344 -static void KeccakAbsorb1344bits(unsigned char *state, const unsigned char *data) -{ - KeccakPermutationOnWordsAfterXoring1344bits((UINT32*)state, data); -} -#endif - -static void KeccakAbsorb(unsigned char *state, const unsigned char *data, unsigned int laneCount) -{ - KeccakPermutationOnWordsAfterXoring((UINT32*)state, data, laneCount); -} - -#ifdef ProvideFast1024 -static void KeccakExtract1024bits(const unsigned char *state, unsigned char *data) -{ - extractLanes(16, state, data) -#ifdef UseBebigokimisa - ((UINT32*)data)[ 2] = ~((UINT32*)data)[ 2]; - ((UINT32*)data)[ 3] = ~((UINT32*)data)[ 3]; - ((UINT32*)data)[ 4] = ~((UINT32*)data)[ 4]; - ((UINT32*)data)[ 5] = ~((UINT32*)data)[ 5]; - ((UINT32*)data)[16] = ~((UINT32*)data)[16]; - ((UINT32*)data)[17] = ~((UINT32*)data)[17]; - ((UINT32*)data)[24] = ~((UINT32*)data)[24]; - ((UINT32*)data)[25] = ~((UINT32*)data)[25]; -#endif -} -#endif - -static void KeccakExtract(const unsigned char *state, unsigned char *data, unsigned int laneCount) -{ - extractLanes(laneCount, state, data) -#ifdef UseBebigokimisa - if (laneCount > 1) { - ((UINT32*)data)[ 2] = ~((UINT32*)data)[ 2]; - ((UINT32*)data)[ 3] = ~((UINT32*)data)[ 3]; - if (laneCount > 2) { - ((UINT32*)data)[ 4] = ~((UINT32*)data)[ 4]; - ((UINT32*)data)[ 5] = ~((UINT32*)data)[ 5]; - if (laneCount > 8) { - ((UINT32*)data)[16] = ~((UINT32*)data)[16]; - ((UINT32*)data)[17] = ~((UINT32*)data)[17]; - if (laneCount > 12) { - ((UINT32*)data)[24] = ~((UINT32*)data)[24]; - ((UINT32*)data)[25] = ~((UINT32*)data)[25]; - if (laneCount > 17) { - ((UINT32*)data)[34] = ~((UINT32*)data)[34]; - ((UINT32*)data)[35] = ~((UINT32*)data)[35]; - if (laneCount > 20) { - ((UINT32*)data)[40] = ~((UINT32*)data)[40]; - ((UINT32*)data)[41] = ~((UINT32*)data)[41]; - } - } - } - } - } - } -#endif -} diff --git a/Modules/_sha3/keccak/KeccakF-1600-opt64-settings.h b/Modules/_sha3/keccak/KeccakF-1600-opt64-settings.h deleted file mode 100644 index df83e6331fcc..000000000000 --- a/Modules/_sha3/keccak/KeccakF-1600-opt64-settings.h +++ /dev/null @@ -1,9 +0,0 @@ -/* -#define Unrolling 24 -#define UseBebigokimisa -#define UseSSE -#define UseOnlySIMD64 -#define UseMMX -#define UseSHLD -#define UseXOP -*/ diff --git a/Modules/_sha3/keccak/KeccakF-1600-opt64.c b/Modules/_sha3/keccak/KeccakF-1600-opt64.c deleted file mode 100644 index f19b18b36ac4..000000000000 --- a/Modules/_sha3/keccak/KeccakF-1600-opt64.c +++ /dev/null @@ -1,510 +0,0 @@ -/* -The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, -Michaël Peeters and Gilles Van Assche. For more information, feedback or -questions, please refer to our website: http://keccak.noekeon.org/ - -Implementation by the designers, -hereby denoted as "the implementer". - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#include -/* #include "brg_endian.h" */ -#include "KeccakF-1600-opt64-settings.h" -#include "KeccakF-1600-interface.h" - -typedef unsigned char UINT8; -/* typedef unsigned long long int UINT64; */ - -#if defined(__GNUC__) -#define ALIGN __attribute__ ((aligned(32))) -#elif defined(_MSC_VER) -#define ALIGN __declspec(align(32)) -#else -#define ALIGN -#endif - -#if defined(UseSSE) - #include - typedef __m128i V64; - typedef __m128i V128; - typedef union { - V128 v128; - UINT64 v64[2]; - } V6464; - - #define ANDnu64(a, b) _mm_andnot_si128(a, b) - #define LOAD64(a) _mm_loadl_epi64((const V64 *)&(a)) - #define CONST64(a) _mm_loadl_epi64((const V64 *)&(a)) - #define ROL64(a, o) _mm_or_si128(_mm_slli_epi64(a, o), _mm_srli_epi64(a, 64-(o))) - #define STORE64(a, b) _mm_storel_epi64((V64 *)&(a), b) - #define XOR64(a, b) _mm_xor_si128(a, b) - #define XOReq64(a, b) a = _mm_xor_si128(a, b) - #define SHUFFLEBYTES128(a, b) _mm_shuffle_epi8(a, b) - - #define ANDnu128(a, b) _mm_andnot_si128(a, b) - #define LOAD6464(a, b) _mm_set_epi64((__m64)(a), (__m64)(b)) - #define CONST128(a) _mm_load_si128((const V128 *)&(a)) - #define LOAD128(a) _mm_load_si128((const V128 *)&(a)) - #define LOAD128u(a) _mm_loadu_si128((const V128 *)&(a)) - #define ROL64in128(a, o) _mm_or_si128(_mm_slli_epi64(a, o), _mm_srli_epi64(a, 64-(o))) - #define STORE128(a, b) _mm_store_si128((V128 *)&(a), b) - #define XOR128(a, b) _mm_xor_si128(a, b) - #define XOReq128(a, b) a = _mm_xor_si128(a, b) - #define GET64LOLO(a, b) _mm_unpacklo_epi64(a, b) - #define GET64HIHI(a, b) _mm_unpackhi_epi64(a, b) - #define COPY64HI2LO(a) _mm_shuffle_epi32(a, 0xEE) - #define COPY64LO2HI(a) _mm_shuffle_epi32(a, 0x44) - #define ZERO128() _mm_setzero_si128() - - #ifdef UseOnlySIMD64 - #include "KeccakF-1600-simd64.macros" - #else -ALIGN const UINT64 rho8_56[2] = {0x0605040302010007, 0x080F0E0D0C0B0A09}; - #include "KeccakF-1600-simd128.macros" - #endif - - #ifdef UseBebigokimisa - #error "UseBebigokimisa cannot be used in combination with UseSSE" - #endif -#elif defined(UseXOP) - #include - typedef __m128i V64; - typedef __m128i V128; - - #define LOAD64(a) _mm_loadl_epi64((const V64 *)&(a)) - #define CONST64(a) _mm_loadl_epi64((const V64 *)&(a)) - #define STORE64(a, b) _mm_storel_epi64((V64 *)&(a), b) - #define XOR64(a, b) _mm_xor_si128(a, b) - #define XOReq64(a, b) a = _mm_xor_si128(a, b) - - #define ANDnu128(a, b) _mm_andnot_si128(a, b) - #define LOAD6464(a, b) _mm_set_epi64((__m64)(a), (__m64)(b)) - #define CONST128(a) _mm_load_si128((const V128 *)&(a)) - #define LOAD128(a) _mm_load_si128((const V128 *)&(a)) - #define LOAD128u(a) _mm_loadu_si128((const V128 *)&(a)) - #define STORE128(a, b) _mm_store_si128((V128 *)&(a), b) - #define XOR128(a, b) _mm_xor_si128(a, b) - #define XOReq128(a, b) a = _mm_xor_si128(a, b) - #define ZERO128() _mm_setzero_si128() - - #define SWAP64(a) _mm_shuffle_epi32(a, 0x4E) - #define GET64LOLO(a, b) _mm_unpacklo_epi64(a, b) - #define GET64HIHI(a, b) _mm_unpackhi_epi64(a, b) - #define GET64LOHI(a, b) ((__m128i)_mm_blend_pd((__m128d)a, (__m128d)b, 2)) - #define GET64HILO(a, b) SWAP64(GET64LOHI(b, a)) - #define COPY64HI2LO(a) _mm_shuffle_epi32(a, 0xEE) - #define COPY64LO2HI(a) _mm_shuffle_epi32(a, 0x44) - - #define ROL6464same(a, o) _mm_roti_epi64(a, o) - #define ROL6464(a, r1, r2) _mm_rot_epi64(a, CONST128( rot_##r1##_##r2 )) -ALIGN const UINT64 rot_0_20[2] = { 0, 20}; -ALIGN const UINT64 rot_44_3[2] = {44, 3}; -ALIGN const UINT64 rot_43_45[2] = {43, 45}; -ALIGN const UINT64 rot_21_61[2] = {21, 61}; -ALIGN const UINT64 rot_14_28[2] = {14, 28}; -ALIGN const UINT64 rot_1_36[2] = { 1, 36}; -ALIGN const UINT64 rot_6_10[2] = { 6, 10}; -ALIGN const UINT64 rot_25_15[2] = {25, 15}; -ALIGN const UINT64 rot_8_56[2] = { 8, 56}; -ALIGN const UINT64 rot_18_27[2] = {18, 27}; -ALIGN const UINT64 rot_62_55[2] = {62, 55}; -ALIGN const UINT64 rot_39_41[2] = {39, 41}; - -#if defined(UseSimulatedXOP) - /* For debugging purposes, when XOP is not available */ - #undef ROL6464 - #undef ROL6464same - #define ROL6464same(a, o) _mm_or_si128(_mm_slli_epi64(a, o), _mm_srli_epi64(a, 64-(o))) - V128 ROL6464(V128 a, int r0, int r1) - { - V128 a0 = ROL64(a, r0); - V128 a1 = COPY64HI2LO(ROL64(a, r1)); - return GET64LOLO(a0, a1); - } -#endif - - #include "KeccakF-1600-xop.macros" - - #ifdef UseBebigokimisa - #error "UseBebigokimisa cannot be used in combination with UseXOP" - #endif -#elif defined(UseMMX) - #include - typedef __m64 V64; - #define ANDnu64(a, b) _mm_andnot_si64(a, b) - - #if (defined(_MSC_VER) || defined (__INTEL_COMPILER)) - #define LOAD64(a) *(V64*)&(a) - #define CONST64(a) *(V64*)&(a) - #define STORE64(a, b) *(V64*)&(a) = b - #else - #define LOAD64(a) (V64)a - #define CONST64(a) (V64)a - #define STORE64(a, b) a = (UINT64)b - #endif - #define ROL64(a, o) _mm_or_si64(_mm_slli_si64(a, o), _mm_srli_si64(a, 64-(o))) - #define XOR64(a, b) _mm_xor_si64(a, b) - #define XOReq64(a, b) a = _mm_xor_si64(a, b) - - #include "KeccakF-1600-simd64.macros" - - #ifdef UseBebigokimisa - #error "UseBebigokimisa cannot be used in combination with UseMMX" - #endif -#else - #if defined(_MSC_VER) - #define ROL64(a, offset) _rotl64(a, offset) - #elif defined(UseSHLD) - #define ROL64(x,N) ({ \ - register UINT64 __out; \ - register UINT64 __in = x; \ - __asm__ ("shld %2,%0,%0" : "=r"(__out) : "0"(__in), "i"(N)); \ - __out; \ - }) - #else - #define ROL64(a, offset) ((((UINT64)a) << offset) ^ (((UINT64)a) >> (64-offset))) - #endif - - #include "KeccakF-1600-64.macros" -#endif - -#include "KeccakF-1600-unrolling.macros" - -static void KeccakPermutationOnWords(UINT64 *state) -{ - declareABCDE -#if (Unrolling != 24) - unsigned int i; -#endif - - copyFromState(A, state) - rounds -#if defined(UseMMX) - _mm_empty(); -#endif -} - -static void KeccakPermutationOnWordsAfterXoring(UINT64 *state, const UINT64 *input, unsigned int laneCount) -{ - declareABCDE -#if (Unrolling != 24) - unsigned int i; -#endif - unsigned int j; - - for(j=0; j> (8*i)) & 0xFF; -} -#endif - - -#ifdef ProvideFast1024 -static void KeccakExtract1024bits(const unsigned char *state, unsigned char *data) -{ -#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) - memcpy(data, state, 128); -#else - unsigned int i; - - for(i=0; i<16; i++) - fromWordToBytes(data+(i*8), ((const UINT64*)state)[i]); -#endif -#ifdef UseBebigokimisa - ((UINT64*)data)[ 1] = ~((UINT64*)data)[ 1]; - ((UINT64*)data)[ 2] = ~((UINT64*)data)[ 2]; - ((UINT64*)data)[ 8] = ~((UINT64*)data)[ 8]; - ((UINT64*)data)[12] = ~((UINT64*)data)[12]; -#endif -} -#endif - -static void KeccakExtract(const unsigned char *state, unsigned char *data, unsigned int laneCount) -{ -#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) - memcpy(data, state, laneCount*8); -#else - unsigned int i; - - for(i=0; i 1) { - ((UINT64*)data)[ 1] = ~((UINT64*)data)[ 1]; - if (laneCount > 2) { - ((UINT64*)data)[ 2] = ~((UINT64*)data)[ 2]; - if (laneCount > 8) { - ((UINT64*)data)[ 8] = ~((UINT64*)data)[ 8]; - if (laneCount > 12) { - ((UINT64*)data)[12] = ~((UINT64*)data)[12]; - if (laneCount > 17) { - ((UINT64*)data)[17] = ~((UINT64*)data)[17]; - if (laneCount > 20) { - ((UINT64*)data)[20] = ~((UINT64*)data)[20]; - } - } - } - } - } - } -#endif -} diff --git a/Modules/_sha3/keccak/KeccakF-1600-simd128.macros b/Modules/_sha3/keccak/KeccakF-1600-simd128.macros deleted file mode 100644 index 98e47f5a59a5..000000000000 --- a/Modules/_sha3/keccak/KeccakF-1600-simd128.macros +++ /dev/null @@ -1,651 +0,0 @@ -/* -The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, -Michaël Peeters and Gilles Van Assche. For more information, feedback or -questions, please refer to our website: http://keccak.noekeon.org/ - -Implementation by the designers, -hereby denoted as "the implementer". - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#define declareABCDE \ - V6464 Abage, Abegi, Abigo, Abogu, Abuga; \ - V6464 Akame, Akemi, Akimo, Akomu, Akuma; \ - V6464 Abae, Abio, Agae, Agio, Akae, Akio, Amae, Amio, Asae, Asio; \ - V64 Aba, Abe, Abi, Abo, Abu; \ - V64 Aga, Age, Agi, Ago, Agu; \ - V64 Aka, Ake, Aki, Ako, Aku; \ - V64 Ama, Ame, Ami, Amo, Amu; \ - V64 Asa, Ase, Asi, Aso, Asu; \ - V128 Bbage, Bbegi, Bbigo, Bbogu, Bbuga; \ - V128 Bkame, Bkemi, Bkimo, Bkomu, Bkuma; \ - V64 Bba, Bbe, Bbi, Bbo, Bbu; \ - V64 Bga, Bge, Bgi, Bgo, Bgu; \ - V64 Bka, Bke, Bki, Bko, Bku; \ - V64 Bma, Bme, Bmi, Bmo, Bmu; \ - V64 Bsa, Bse, Bsi, Bso, Bsu; \ - V128 Cae, Cei, Cio, Cou, Cua, Dei, Dou; \ - V64 Ca, Ce, Ci, Co, Cu; \ - V64 Da, De, Di, Do, Du; \ - V6464 Ebage, Ebegi, Ebigo, Ebogu, Ebuga; \ - V6464 Ekame, Ekemi, Ekimo, Ekomu, Ekuma; \ - V64 Eba, Ebe, Ebi, Ebo, Ebu; \ - V64 Ega, Ege, Egi, Ego, Egu; \ - V64 Eka, Eke, Eki, Eko, Eku; \ - V64 Ema, Eme, Emi, Emo, Emu; \ - V64 Esa, Ese, Esi, Eso, Esu; \ - V128 Zero; - -#define prepareTheta - -#define computeD \ - Cua = GET64LOLO(Cu, Cae); \ - Dei = XOR128(Cae, ROL64in128(Cio, 1)); \ - Dou = XOR128(Cio, ROL64in128(Cua, 1)); \ - Da = XOR64(Cu, ROL64in128(COPY64HI2LO(Cae), 1)); \ - De = Dei; \ - Di = COPY64HI2LO(Dei); \ - Do = Dou; \ - Du = COPY64HI2LO(Dou); - -/* --- Theta Rho Pi Chi Iota Prepare-theta */ -/* --- 64-bit lanes mapped to 64-bit and 128-bit words */ -#define thetaRhoPiChiIotaPrepareTheta(i, A, E) \ - computeD \ - \ - A##ba = LOAD64(A##bage.v64[0]); \ - XOReq64(A##ba, Da); \ - Bba = A##ba; \ - XOReq64(A##gu, Du); \ - Bge = ROL64(A##gu, 20); \ - Bbage = GET64LOLO(Bba, Bge); \ - A##ge = LOAD64(A##bage.v64[1]); \ - XOReq64(A##ge, De); \ - Bbe = ROL64(A##ge, 44); \ - A##ka = LOAD64(A##kame.v64[0]); \ - XOReq64(A##ka, Da); \ - Bgi = ROL64(A##ka, 3); \ - Bbegi = GET64LOLO(Bbe, Bgi); \ - XOReq64(A##ki, Di); \ - Bbi = ROL64(A##ki, 43); \ - A##me = LOAD64(A##kame.v64[1]); \ - XOReq64(A##me, De); \ - Bgo = ROL64(A##me, 45); \ - Bbigo = GET64LOLO(Bbi, Bgo); \ - E##bage.v128 = XOR128(Bbage, ANDnu128(Bbegi, Bbigo)); \ - XOReq128(E##bage.v128, CONST64(KeccakF1600RoundConstants[i])); \ - Cae = E##bage.v128; \ - XOReq64(A##mo, Do); \ - Bbo = ROL64(A##mo, 21); \ - XOReq64(A##si, Di); \ - Bgu = ROL64(A##si, 61); \ - Bbogu = GET64LOLO(Bbo, Bgu); \ - E##begi.v128 = XOR128(Bbegi, ANDnu128(Bbigo, Bbogu)); \ - Cei = E##begi.v128; \ - XOReq64(A##su, Du); \ - Bbu = ROL64(A##su, 14); \ - XOReq64(A##bo, Do); \ - Bga = ROL64(A##bo, 28); \ - Bbuga = GET64LOLO(Bbu, Bga); \ - E##bigo.v128 = XOR128(Bbigo, ANDnu128(Bbogu, Bbuga)); \ - E##bi = E##bigo.v128; \ - E##go = GET64HIHI(E##bigo.v128, E##bigo.v128); \ - Cio = E##bigo.v128; \ - E##bogu.v128 = XOR128(Bbogu, ANDnu128(Bbuga, Bbage)); \ - E##bo = E##bogu.v128; \ - E##gu = GET64HIHI(E##bogu.v128, E##bogu.v128); \ - Cou = E##bogu.v128; \ - E##buga.v128 = XOR128(Bbuga, ANDnu128(Bbage, Bbegi)); \ - E##bu = E##buga.v128; \ - E##ga = GET64HIHI(E##buga.v128, E##buga.v128); \ - Cua = E##buga.v128; \ -\ - A##be = LOAD64(A##begi.v64[0]); \ - XOReq64(A##be, De); \ - Bka = ROL64(A##be, 1); \ - XOReq64(A##ga, Da); \ - Bme = ROL64(A##ga, 36); \ - Bkame = GET64LOLO(Bka, Bme); \ - A##gi = LOAD64(A##begi.v64[1]); \ - XOReq64(A##gi, Di); \ - Bke = ROL64(A##gi, 6); \ - A##ke = LOAD64(A##kemi.v64[0]); \ - XOReq64(A##ke, De); \ - Bmi = ROL64(A##ke, 10); \ - Bkemi = GET64LOLO(Bke, Bmi); \ - XOReq64(A##ko, Do); \ - Bki = ROL64(A##ko, 25); \ - A##mi = LOAD64(A##kemi.v64[1]); \ - XOReq64(A##mi, Di); \ - Bmo = ROL64(A##mi, 15); \ - Bkimo = GET64LOLO(Bki, Bmo); \ - E##kame.v128 = XOR128(Bkame, ANDnu128(Bkemi, Bkimo)); \ - XOReq128(Cae, E##kame.v128); \ - Bkomu = GET64LOLO(XOR64(A##mu, Du), XOR64(A##so, Do)); \ - Bkomu = SHUFFLEBYTES128(Bkomu, CONST128(rho8_56)); \ - E##kemi.v128 = XOR128(Bkemi, ANDnu128(Bkimo, Bkomu)); \ - XOReq128(Cei, E##kemi.v128); \ - XOReq64(A##sa, Da); \ - Bku = ROL64(A##sa, 18); \ - XOReq64(A##bu, Du); \ - Bma = ROL64(A##bu, 27); \ - Bkuma = GET64LOLO(Bku, Bma); \ - E##kimo.v128 = XOR128(Bkimo, ANDnu128(Bkomu, Bkuma)); \ - E##ki = E##kimo.v128; \ - E##mo = GET64HIHI(E##kimo.v128, E##kimo.v128); \ - XOReq128(Cio, E##kimo.v128); \ - E##komu.v128 = XOR128(Bkomu, ANDnu128(Bkuma, Bkame)); \ - E##ko = E##komu.v128; \ - E##mu = GET64HIHI(E##komu.v128, E##komu.v128); \ - XOReq128(Cou, E##komu.v128); \ - E##kuma.v128 = XOR128(Bkuma, ANDnu128(Bkame, Bkemi)); \ - E##ku = E##kuma.v128; \ - E##ma = GET64HIHI(E##kuma.v128, E##kuma.v128); \ - XOReq128(Cua, E##kuma.v128); \ -\ - XOReq64(A##bi, Di); \ - Bsa = ROL64(A##bi, 62); \ - XOReq64(A##go, Do); \ - Bse = ROL64(A##go, 55); \ - XOReq64(A##ku, Du); \ - Bsi = ROL64(A##ku, 39); \ - E##sa = XOR64(Bsa, ANDnu64(Bse, Bsi)); \ - Ca = E##sa; \ - XOReq64(A##ma, Da); \ - Bso = ROL64(A##ma, 41); \ - E##se = XOR64(Bse, ANDnu64(Bsi, Bso)); \ - Ce = E##se; \ - XOReq128(Cae, GET64LOLO(Ca, Ce)); \ - XOReq64(A##se, De); \ - Bsu = ROL64(A##se, 2); \ - E##si = XOR64(Bsi, ANDnu64(Bso, Bsu)); \ - Ci = E##si; \ - E##so = XOR64(Bso, ANDnu64(Bsu, Bsa)); \ - Co = E##so; \ - XOReq128(Cio, GET64LOLO(Ci, Co)); \ - E##su = XOR64(Bsu, ANDnu64(Bsa, Bse)); \ - Cu = E##su; \ -\ - Zero = ZERO128(); \ - XOReq128(Cae, GET64HIHI(Cua, Zero)); \ - XOReq128(Cae, GET64LOLO(Zero, Cei)); \ - XOReq128(Cio, GET64HIHI(Cei, Zero)); \ - XOReq128(Cio, GET64LOLO(Zero, Cou)); \ - XOReq128(Cua, GET64HIHI(Cou, Zero)); \ - XOReq64(Cu, Cua); \ - -/* --- Theta Rho Pi Chi Iota */ -/* --- 64-bit lanes mapped to 64-bit and 128-bit words */ -#define thetaRhoPiChiIota(i, A, E) thetaRhoPiChiIotaPrepareTheta(i, A, E) - -static const UINT64 KeccakF1600RoundConstants[24] = { - 0x0000000000000001ULL, - 0x0000000000008082ULL, - 0x800000000000808aULL, - 0x8000000080008000ULL, - 0x000000000000808bULL, - 0x0000000080000001ULL, - 0x8000000080008081ULL, - 0x8000000000008009ULL, - 0x000000000000008aULL, - 0x0000000000000088ULL, - 0x0000000080008009ULL, - 0x000000008000000aULL, - 0x000000008000808bULL, - 0x800000000000008bULL, - 0x8000000000008089ULL, - 0x8000000000008003ULL, - 0x8000000000008002ULL, - 0x8000000000000080ULL, - 0x000000000000800aULL, - 0x800000008000000aULL, - 0x8000000080008081ULL, - 0x8000000000008080ULL, - 0x0000000080000001ULL, - 0x8000000080008008ULL }; - -#define copyFromStateAndXor576bits(X, state, input) \ - X##bae.v128 = XOR128(LOAD128(state[ 0]), LOAD128u(input[ 0])); \ - X##ba = X##bae.v128; \ - X##be = GET64HIHI(X##bae.v128, X##bae.v128); \ - Cae = X##bae.v128; \ - X##bio.v128 = XOR128(LOAD128(state[ 2]), LOAD128u(input[ 2])); \ - X##bi = X##bio.v128; \ - X##bo = GET64HIHI(X##bio.v128, X##bio.v128); \ - Cio = X##bio.v128; \ - X##bu = XOR64(LOAD64(state[ 4]), LOAD64(input[ 4])); \ - Cu = X##bu; \ - X##gae.v128 = XOR128(LOAD128u(state[ 5]), LOAD128u(input[ 5])); \ - X##ga = X##gae.v128; \ - X##ge = GET64HIHI(X##gae.v128, X##gae.v128); \ - X##bage.v128 = GET64LOLO(X##ba, X##ge); \ - XOReq128(Cae, X##gae.v128); \ - X##gio.v128 = XOR128(LOAD128u(state[ 7]), LOAD128u(input[ 7])); \ - X##gi = X##gio.v128; \ - X##begi.v128 = GET64LOLO(X##be, X##gi); \ - X##go = GET64HIHI(X##gio.v128, X##gio.v128); \ - XOReq128(Cio, X##gio.v128); \ - X##gu = LOAD64(state[ 9]); \ - XOReq64(Cu, X##gu); \ - X##kae.v128 = LOAD128(state[10]); \ - X##ka = X##kae.v128; \ - X##ke = GET64HIHI(X##kae.v128, X##kae.v128); \ - XOReq128(Cae, X##kae.v128); \ - X##kio.v128 = LOAD128(state[12]); \ - X##ki = X##kio.v128; \ - X##ko = GET64HIHI(X##kio.v128, X##kio.v128); \ - XOReq128(Cio, X##kio.v128); \ - X##ku = LOAD64(state[14]); \ - XOReq64(Cu, X##ku); \ - X##mae.v128 = LOAD128u(state[15]); \ - X##ma = X##mae.v128; \ - X##me = GET64HIHI(X##mae.v128, X##mae.v128); \ - X##kame.v128 = GET64LOLO(X##ka, X##me); \ - XOReq128(Cae, X##mae.v128); \ - X##mio.v128 = LOAD128u(state[17]); \ - X##mi = X##mio.v128; \ - X##kemi.v128 = GET64LOLO(X##ke, X##mi); \ - X##mo = GET64HIHI(X##mio.v128, X##mio.v128); \ - XOReq128(Cio, X##mio.v128); \ - X##mu = LOAD64(state[19]); \ - XOReq64(Cu, X##mu); \ - X##sae.v128 = LOAD128(state[20]); \ - X##sa = X##sae.v128; \ - X##se = GET64HIHI(X##sae.v128, X##sae.v128); \ - XOReq128(Cae, X##sae.v128); \ - X##sio.v128 = LOAD128(state[22]); \ - X##si = X##sio.v128; \ - X##so = GET64HIHI(X##sio.v128, X##sio.v128); \ - XOReq128(Cio, X##sio.v128); \ - X##su = LOAD64(state[24]); \ - XOReq64(Cu, X##su); \ - -#define copyFromStateAndXor832bits(X, state, input) \ - X##bae.v128 = XOR128(LOAD128(state[ 0]), LOAD128u(input[ 0])); \ - X##ba = X##bae.v128; \ - X##be = GET64HIHI(X##bae.v128, X##bae.v128); \ - Cae = X##bae.v128; \ - X##bio.v128 = XOR128(LOAD128(state[ 2]), LOAD128u(input[ 2])); \ - X##bi = X##bio.v128; \ - X##bo = GET64HIHI(X##bio.v128, X##bio.v128); \ - Cio = X##bio.v128; \ - X##bu = XOR64(LOAD64(state[ 4]), LOAD64(input[ 4])); \ - Cu = X##bu; \ - X##gae.v128 = XOR128(LOAD128u(state[ 5]), LOAD128u(input[ 5])); \ - X##ga = X##gae.v128; \ - X##ge = GET64HIHI(X##gae.v128, X##gae.v128); \ - X##bage.v128 = GET64LOLO(X##ba, X##ge); \ - XOReq128(Cae, X##gae.v128); \ - X##gio.v128 = XOR128(LOAD128u(state[ 7]), LOAD128u(input[ 7])); \ - X##gi = X##gio.v128; \ - X##begi.v128 = GET64LOLO(X##be, X##gi); \ - X##go = GET64HIHI(X##gio.v128, X##gio.v128); \ - XOReq128(Cio, X##gio.v128); \ - X##gu = XOR64(LOAD64(state[ 9]), LOAD64(input[ 9])); \ - XOReq64(Cu, X##gu); \ - X##kae.v128 = XOR128(LOAD128(state[10]), LOAD128u(input[10])); \ - X##ka = X##kae.v128; \ - X##ke = GET64HIHI(X##kae.v128, X##kae.v128); \ - XOReq128(Cae, X##kae.v128); \ - X##kio.v128 = XOR128(LOAD128(state[12]), LOAD64(input[12])); \ - X##ki = X##kio.v128; \ - X##ko = GET64HIHI(X##kio.v128, X##kio.v128); \ - XOReq128(Cio, X##kio.v128); \ - X##ku = LOAD64(state[14]); \ - XOReq64(Cu, X##ku); \ - X##mae.v128 = LOAD128u(state[15]); \ - X##ma = X##mae.v128; \ - X##me = GET64HIHI(X##mae.v128, X##mae.v128); \ - X##kame.v128 = GET64LOLO(X##ka, X##me); \ - XOReq128(Cae, X##mae.v128); \ - X##mio.v128 = LOAD128u(state[17]); \ - X##mi = X##mio.v128; \ - X##kemi.v128 = GET64LOLO(X##ke, X##mi); \ - X##mo = GET64HIHI(X##mio.v128, X##mio.v128); \ - XOReq128(Cio, X##mio.v128); \ - X##mu = LOAD64(state[19]); \ - XOReq64(Cu, X##mu); \ - X##sae.v128 = LOAD128(state[20]); \ - X##sa = X##sae.v128; \ - X##se = GET64HIHI(X##sae.v128, X##sae.v128); \ - XOReq128(Cae, X##sae.v128); \ - X##sio.v128 = LOAD128(state[22]); \ - X##si = X##sio.v128; \ - X##so = GET64HIHI(X##sio.v128, X##sio.v128); \ - XOReq128(Cio, X##sio.v128); \ - X##su = LOAD64(state[24]); \ - XOReq64(Cu, X##su); \ - -#define copyFromStateAndXor1024bits(X, state, input) \ - X##bae.v128 = XOR128(LOAD128(state[ 0]), LOAD128u(input[ 0])); \ - X##ba = X##bae.v128; \ - X##be = GET64HIHI(X##bae.v128, X##bae.v128); \ - Cae = X##bae.v128; \ - X##bio.v128 = XOR128(LOAD128(state[ 2]), LOAD128u(input[ 2])); \ - X##bi = X##bio.v128; \ - X##bo = GET64HIHI(X##bio.v128, X##bio.v128); \ - Cio = X##bio.v128; \ - X##bu = XOR64(LOAD64(state[ 4]), LOAD64(input[ 4])); \ - Cu = X##bu; \ - X##gae.v128 = XOR128(LOAD128u(state[ 5]), LOAD128u(input[ 5])); \ - X##ga = X##gae.v128; \ - X##ge = GET64HIHI(X##gae.v128, X##gae.v128); \ - X##bage.v128 = GET64LOLO(X##ba, X##ge); \ - XOReq128(Cae, X##gae.v128); \ - X##gio.v128 = XOR128(LOAD128u(state[ 7]), LOAD128u(input[ 7])); \ - X##gi = X##gio.v128; \ - X##begi.v128 = GET64LOLO(X##be, X##gi); \ - X##go = GET64HIHI(X##gio.v128, X##gio.v128); \ - XOReq128(Cio, X##gio.v128); \ - X##gu = XOR64(LOAD64(state[ 9]), LOAD64(input[ 9])); \ - XOReq64(Cu, X##gu); \ - X##kae.v128 = XOR128(LOAD128(state[10]), LOAD128u(input[10])); \ - X##ka = X##kae.v128; \ - X##ke = GET64HIHI(X##kae.v128, X##kae.v128); \ - XOReq128(Cae, X##kae.v128); \ - X##kio.v128 = XOR128(LOAD128(state[12]), LOAD128u(input[12])); \ - X##ki = X##kio.v128; \ - X##ko = GET64HIHI(X##kio.v128, X##kio.v128); \ - XOReq128(Cio, X##kio.v128); \ - X##ku = XOR64(LOAD64(state[14]), LOAD64(input[14])); \ - XOReq64(Cu, X##ku); \ - X##mae.v128 = XOR128(LOAD128u(state[15]), LOAD64(input[15])); \ - X##ma = X##mae.v128; \ - X##me = GET64HIHI(X##mae.v128, X##mae.v128); \ - X##kame.v128 = GET64LOLO(X##ka, X##me); \ - XOReq128(Cae, X##mae.v128); \ - X##mio.v128 = LOAD128u(state[17]); \ - X##mi = X##mio.v128; \ - X##kemi.v128 = GET64LOLO(X##ke, X##mi); \ - X##mo = GET64HIHI(X##mio.v128, X##mio.v128); \ - XOReq128(Cio, X##mio.v128); \ - X##mu = LOAD64(state[19]); \ - XOReq64(Cu, X##mu); \ - X##sae.v128 = LOAD128(state[20]); \ - X##sa = X##sae.v128; \ - X##se = GET64HIHI(X##sae.v128, X##sae.v128); \ - XOReq128(Cae, X##sae.v128); \ - X##sio.v128 = LOAD128(state[22]); \ - X##si = X##sio.v128; \ - X##so = GET64HIHI(X##sio.v128, X##sio.v128); \ - XOReq128(Cio, X##sio.v128); \ - X##su = LOAD64(state[24]); \ - XOReq64(Cu, X##su); \ - -#define copyFromStateAndXor1088bits(X, state, input) \ - X##bae.v128 = XOR128(LOAD128(state[ 0]), LOAD128u(input[ 0])); \ - X##ba = X##bae.v128; \ - X##be = GET64HIHI(X##bae.v128, X##bae.v128); \ - Cae = X##bae.v128; \ - X##bio.v128 = XOR128(LOAD128(state[ 2]), LOAD128u(input[ 2])); \ - X##bi = X##bio.v128; \ - X##bo = GET64HIHI(X##bio.v128, X##bio.v128); \ - Cio = X##bio.v128; \ - X##bu = XOR64(LOAD64(state[ 4]), LOAD64(input[ 4])); \ - Cu = X##bu; \ - X##gae.v128 = XOR128(LOAD128u(state[ 5]), LOAD128u(input[ 5])); \ - X##ga = X##gae.v128; \ - X##ge = GET64HIHI(X##gae.v128, X##gae.v128); \ - X##bage.v128 = GET64LOLO(X##ba, X##ge); \ - XOReq128(Cae, X##gae.v128); \ - X##gio.v128 = XOR128(LOAD128u(state[ 7]), LOAD128u(input[ 7])); \ - X##gi = X##gio.v128; \ - X##begi.v128 = GET64LOLO(X##be, X##gi); \ - X##go = GET64HIHI(X##gio.v128, X##gio.v128); \ - XOReq128(Cio, X##gio.v128); \ - X##gu = XOR64(LOAD64(state[ 9]), LOAD64(input[ 9])); \ - XOReq64(Cu, X##gu); \ - X##kae.v128 = XOR128(LOAD128(state[10]), LOAD128u(input[10])); \ - X##ka = X##kae.v128; \ - X##ke = GET64HIHI(X##kae.v128, X##kae.v128); \ - XOReq128(Cae, X##kae.v128); \ - X##kio.v128 = XOR128(LOAD128(state[12]), LOAD128u(input[12])); \ - X##ki = X##kio.v128; \ - X##ko = GET64HIHI(X##kio.v128, X##kio.v128); \ - XOReq128(Cio, X##kio.v128); \ - X##ku = XOR64(LOAD64(state[14]), LOAD64(input[14])); \ - XOReq64(Cu, X##ku); \ - X##mae.v128 = XOR128(LOAD128u(state[15]), LOAD128u(input[15])); \ - X##ma = X##mae.v128; \ - X##me = GET64HIHI(X##mae.v128, X##mae.v128); \ - X##kame.v128 = GET64LOLO(X##ka, X##me); \ - XOReq128(Cae, X##mae.v128); \ - X##mio.v128 = LOAD128u(state[17]); \ - X##mi = X##mio.v128; \ - X##kemi.v128 = GET64LOLO(X##ke, X##mi); \ - X##mo = GET64HIHI(X##mio.v128, X##mio.v128); \ - XOReq128(Cio, X##mio.v128); \ - X##mu = LOAD64(state[19]); \ - XOReq64(Cu, X##mu); \ - X##sae.v128 = LOAD128(state[20]); \ - X##sa = X##sae.v128; \ - X##se = GET64HIHI(X##sae.v128, X##sae.v128); \ - XOReq128(Cae, X##sae.v128); \ - X##sio.v128 = LOAD128(state[22]); \ - X##si = X##sio.v128; \ - X##so = GET64HIHI(X##sio.v128, X##sio.v128); \ - XOReq128(Cio, X##sio.v128); \ - X##su = LOAD64(state[24]); \ - XOReq64(Cu, X##su); \ - -#define copyFromStateAndXor1152bits(X, state, input) \ - X##bae.v128 = XOR128(LOAD128(state[ 0]), LOAD128u(input[ 0])); \ - X##ba = X##bae.v128; \ - X##be = GET64HIHI(X##bae.v128, X##bae.v128); \ - Cae = X##bae.v128; \ - X##bio.v128 = XOR128(LOAD128(state[ 2]), LOAD128u(input[ 2])); \ - X##bi = X##bio.v128; \ - X##bo = GET64HIHI(X##bio.v128, X##bio.v128); \ - Cio = X##bio.v128; \ - X##bu = XOR64(LOAD64(state[ 4]), LOAD64(input[ 4])); \ - Cu = X##bu; \ - X##gae.v128 = XOR128(LOAD128u(state[ 5]), LOAD128u(input[ 5])); \ - X##ga = X##gae.v128; \ - X##ge = GET64HIHI(X##gae.v128, X##gae.v128); \ - X##bage.v128 = GET64LOLO(X##ba, X##ge); \ - XOReq128(Cae, X##gae.v128); \ - X##gio.v128 = XOR128(LOAD128u(state[ 7]), LOAD128u(input[ 7])); \ - X##gi = X##gio.v128; \ - X##begi.v128 = GET64LOLO(X##be, X##gi); \ - X##go = GET64HIHI(X##gio.v128, X##gio.v128); \ - XOReq128(Cio, X##gio.v128); \ - X##gu = XOR64(LOAD64(state[ 9]), LOAD64(input[ 9])); \ - XOReq64(Cu, X##gu); \ - X##kae.v128 = XOR128(LOAD128(state[10]), LOAD128u(input[10])); \ - X##ka = X##kae.v128; \ - X##ke = GET64HIHI(X##kae.v128, X##kae.v128); \ - XOReq128(Cae, X##kae.v128); \ - X##kio.v128 = XOR128(LOAD128(state[12]), LOAD128u(input[12])); \ - X##ki = X##kio.v128; \ - X##ko = GET64HIHI(X##kio.v128, X##kio.v128); \ - XOReq128(Cio, X##kio.v128); \ - X##ku = XOR64(LOAD64(state[14]), LOAD64(input[14])); \ - XOReq64(Cu, X##ku); \ - X##mae.v128 = XOR128(LOAD128u(state[15]), LOAD128u(input[15])); \ - X##ma = X##mae.v128; \ - X##me = GET64HIHI(X##mae.v128, X##mae.v128); \ - X##kame.v128 = GET64LOLO(X##ka, X##me); \ - XOReq128(Cae, X##mae.v128); \ - X##mio.v128 = XOR128(LOAD128u(state[17]), LOAD64(input[17])); \ - X##mi = X##mio.v128; \ - X##kemi.v128 = GET64LOLO(X##ke, X##mi); \ - X##mo = GET64HIHI(X##mio.v128, X##mio.v128); \ - XOReq128(Cio, X##mio.v128); \ - X##mu = LOAD64(state[19]); \ - XOReq64(Cu, X##mu); \ - X##sae.v128 = LOAD128(state[20]); \ - X##sa = X##sae.v128; \ - X##se = GET64HIHI(X##sae.v128, X##sae.v128); \ - XOReq128(Cae, X##sae.v128); \ - X##sio.v128 = LOAD128(state[22]); \ - X##si = X##sio.v128; \ - X##so = GET64HIHI(X##sio.v128, X##sio.v128); \ - XOReq128(Cio, X##sio.v128); \ - X##su = LOAD64(state[24]); \ - XOReq64(Cu, X##su); \ - -#define copyFromStateAndXor1344bits(X, state, input) \ - X##bae.v128 = XOR128(LOAD128(state[ 0]), LOAD128u(input[ 0])); \ - X##ba = X##bae.v128; \ - X##be = GET64HIHI(X##bae.v128, X##bae.v128); \ - Cae = X##bae.v128; \ - X##bio.v128 = XOR128(LOAD128(state[ 2]), LOAD128u(input[ 2])); \ - X##bi = X##bio.v128; \ - X##bo = GET64HIHI(X##bio.v128, X##bio.v128); \ - Cio = X##bio.v128; \ - X##bu = XOR64(LOAD64(state[ 4]), LOAD64(input[ 4])); \ - Cu = X##bu; \ - X##gae.v128 = XOR128(LOAD128u(state[ 5]), LOAD128u(input[ 5])); \ - X##ga = X##gae.v128; \ - X##ge = GET64HIHI(X##gae.v128, X##gae.v128); \ - X##bage.v128 = GET64LOLO(X##ba, X##ge); \ - XOReq128(Cae, X##gae.v128); \ - X##gio.v128 = XOR128(LOAD128u(state[ 7]), LOAD128u(input[ 7])); \ - X##gi = X##gio.v128; \ - X##begi.v128 = GET64LOLO(X##be, X##gi); \ - X##go = GET64HIHI(X##gio.v128, X##gio.v128); \ - XOReq128(Cio, X##gio.v128); \ - X##gu = XOR64(LOAD64(state[ 9]), LOAD64(input[ 9])); \ - XOReq64(Cu, X##gu); \ - X##kae.v128 = XOR128(LOAD128(state[10]), LOAD128u(input[10])); \ - X##ka = X##kae.v128; \ - X##ke = GET64HIHI(X##kae.v128, X##kae.v128); \ - XOReq128(Cae, X##kae.v128); \ - X##kio.v128 = XOR128(LOAD128(state[12]), LOAD128u(input[12])); \ - X##ki = X##kio.v128; \ - X##ko = GET64HIHI(X##kio.v128, X##kio.v128); \ - XOReq128(Cio, X##kio.v128); \ - X##ku = XOR64(LOAD64(state[14]), LOAD64(input[14])); \ - XOReq64(Cu, X##ku); \ - X##mae.v128 = XOR128(LOAD128u(state[15]), LOAD128u(input[15])); \ - X##ma = X##mae.v128; \ - X##me = GET64HIHI(X##mae.v128, X##mae.v128); \ - X##kame.v128 = GET64LOLO(X##ka, X##me); \ - XOReq128(Cae, X##mae.v128); \ - X##mio.v128 = XOR128(LOAD128u(state[17]), LOAD128u(input[17])); \ - X##mi = X##mio.v128; \ - X##kemi.v128 = GET64LOLO(X##ke, X##mi); \ - X##mo = GET64HIHI(X##mio.v128, X##mio.v128); \ - XOReq128(Cio, X##mio.v128); \ - X##mu = XOR64(LOAD64(state[19]), LOAD64(input[19])); \ - XOReq64(Cu, X##mu); \ - X##sae.v128 = XOR128(LOAD128(state[20]), LOAD64(input[20])); \ - X##sa = X##sae.v128; \ - X##se = GET64HIHI(X##sae.v128, X##sae.v128); \ - XOReq128(Cae, X##sae.v128); \ - X##sio.v128 = LOAD128(state[22]); \ - X##si = X##sio.v128; \ - X##so = GET64HIHI(X##sio.v128, X##sio.v128); \ - XOReq128(Cio, X##sio.v128); \ - X##su = LOAD64(state[24]); \ - XOReq64(Cu, X##su); \ - -#define copyFromState(X, state) \ - X##bae.v128 = LOAD128(state[ 0]); \ - X##ba = X##bae.v128; \ - X##be = GET64HIHI(X##bae.v128, X##bae.v128); \ - Cae = X##bae.v128; \ - X##bio.v128 = LOAD128(state[ 2]); \ - X##bi = X##bio.v128; \ - X##bo = GET64HIHI(X##bio.v128, X##bio.v128); \ - Cio = X##bio.v128; \ - X##bu = LOAD64(state[ 4]); \ - Cu = X##bu; \ - X##gae.v128 = LOAD128u(state[ 5]); \ - X##ga = X##gae.v128; \ - X##ge = GET64HIHI(X##gae.v128, X##gae.v128); \ - X##bage.v128 = GET64LOLO(X##ba, X##ge); \ - XOReq128(Cae, X##gae.v128); \ - X##gio.v128 = LOAD128u(state[ 7]); \ - X##gi = X##gio.v128; \ - X##begi.v128 = GET64LOLO(X##be, X##gi); \ - X##go = GET64HIHI(X##gio.v128, X##gio.v128); \ - XOReq128(Cio, X##gio.v128); \ - X##gu = LOAD64(state[ 9]); \ - XOReq64(Cu, X##gu); \ - X##kae.v128 = LOAD128(state[10]); \ - X##ka = X##kae.v128; \ - X##ke = GET64HIHI(X##kae.v128, X##kae.v128); \ - XOReq128(Cae, X##kae.v128); \ - X##kio.v128 = LOAD128(state[12]); \ - X##ki = X##kio.v128; \ - X##ko = GET64HIHI(X##kio.v128, X##kio.v128); \ - XOReq128(Cio, X##kio.v128); \ - X##ku = LOAD64(state[14]); \ - XOReq64(Cu, X##ku); \ - X##mae.v128 = LOAD128u(state[15]); \ - X##ma = X##mae.v128; \ - X##me = GET64HIHI(X##mae.v128, X##mae.v128); \ - X##kame.v128 = GET64LOLO(X##ka, X##me); \ - XOReq128(Cae, X##mae.v128); \ - X##mio.v128 = LOAD128u(state[17]); \ - X##mi = X##mio.v128; \ - X##kemi.v128 = GET64LOLO(X##ke, X##mi); \ - X##mo = GET64HIHI(X##mio.v128, X##mio.v128); \ - XOReq128(Cio, X##mio.v128); \ - X##mu = LOAD64(state[19]); \ - XOReq64(Cu, X##mu); \ - X##sae.v128 = LOAD128(state[20]); \ - X##sa = X##sae.v128; \ - X##se = GET64HIHI(X##sae.v128, X##sae.v128); \ - XOReq128(Cae, X##sae.v128); \ - X##sio.v128 = LOAD128(state[22]); \ - X##si = X##sio.v128; \ - X##so = GET64HIHI(X##sio.v128, X##sio.v128); \ - XOReq128(Cio, X##sio.v128); \ - X##su = LOAD64(state[24]); \ - XOReq64(Cu, X##su); \ - -#define copyToState(state, X) \ - state[ 0] = A##bage.v64[0]; \ - state[ 1] = A##begi.v64[0]; \ - STORE64(state[ 2], X##bi); \ - STORE64(state[ 3], X##bo); \ - STORE64(state[ 4], X##bu); \ - STORE64(state[ 5], X##ga); \ - state[ 6] = A##bage.v64[1]; \ - state[ 7] = A##begi.v64[1]; \ - STORE64(state[ 8], X##go); \ - STORE64(state[ 9], X##gu); \ - state[10] = X##kame.v64[0]; \ - state[11] = X##kemi.v64[0]; \ - STORE64(state[12], X##ki); \ - STORE64(state[13], X##ko); \ - STORE64(state[14], X##ku); \ - STORE64(state[15], X##ma); \ - state[16] = X##kame.v64[1]; \ - state[17] = X##kemi.v64[1]; \ - STORE64(state[18], X##mo); \ - STORE64(state[19], X##mu); \ - STORE64(state[20], X##sa); \ - STORE64(state[21], X##se); \ - STORE64(state[22], X##si); \ - STORE64(state[23], X##so); \ - STORE64(state[24], X##su); \ - -#define copyStateVariables(X, Y) \ - X##bage = Y##bage; \ - X##begi = Y##begi; \ - X##bi = Y##bi; \ - X##bo = Y##bo; \ - X##bu = Y##bu; \ - X##ga = Y##ga; \ - X##go = Y##go; \ - X##gu = Y##gu; \ - X##kame = Y##kame; \ - X##kemi = Y##kemi; \ - X##ki = Y##ki; \ - X##ko = Y##ko; \ - X##ku = Y##ku; \ - X##ma = Y##ma; \ - X##mo = Y##mo; \ - X##mu = Y##mu; \ - X##sa = Y##sa; \ - X##se = Y##se; \ - X##si = Y##si; \ - X##so = Y##so; \ - X##su = Y##su; \ - diff --git a/Modules/_sha3/keccak/KeccakF-1600-simd64.macros b/Modules/_sha3/keccak/KeccakF-1600-simd64.macros deleted file mode 100644 index 06a30e2ae060..000000000000 --- a/Modules/_sha3/keccak/KeccakF-1600-simd64.macros +++ /dev/null @@ -1,517 +0,0 @@ -/* -Code automatically generated by KeccakTools! - -The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, -Michaël Peeters and Gilles Van Assche. For more information, feedback or -questions, please refer to our website: http://keccak.noekeon.org/ - -Implementation by the designers, -hereby denoted as "the implementer". - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#define declareABCDE \ - V64 Aba, Abe, Abi, Abo, Abu; \ - V64 Aga, Age, Agi, Ago, Agu; \ - V64 Aka, Ake, Aki, Ako, Aku; \ - V64 Ama, Ame, Ami, Amo, Amu; \ - V64 Asa, Ase, Asi, Aso, Asu; \ - V64 Bba, Bbe, Bbi, Bbo, Bbu; \ - V64 Bga, Bge, Bgi, Bgo, Bgu; \ - V64 Bka, Bke, Bki, Bko, Bku; \ - V64 Bma, Bme, Bmi, Bmo, Bmu; \ - V64 Bsa, Bse, Bsi, Bso, Bsu; \ - V64 Ca, Ce, Ci, Co, Cu; \ - V64 Da, De, Di, Do, Du; \ - V64 Eba, Ebe, Ebi, Ebo, Ebu; \ - V64 Ega, Ege, Egi, Ego, Egu; \ - V64 Eka, Eke, Eki, Eko, Eku; \ - V64 Ema, Eme, Emi, Emo, Emu; \ - V64 Esa, Ese, Esi, Eso, Esu; \ - -#define prepareTheta \ - Ca = XOR64(Aba, XOR64(Aga, XOR64(Aka, XOR64(Ama, Asa)))); \ - Ce = XOR64(Abe, XOR64(Age, XOR64(Ake, XOR64(Ame, Ase)))); \ - Ci = XOR64(Abi, XOR64(Agi, XOR64(Aki, XOR64(Ami, Asi)))); \ - Co = XOR64(Abo, XOR64(Ago, XOR64(Ako, XOR64(Amo, Aso)))); \ - Cu = XOR64(Abu, XOR64(Agu, XOR64(Aku, XOR64(Amu, Asu)))); \ - -/* --- Code for round, with prepare-theta */ -/* --- 64-bit lanes mapped to 64-bit words */ -#define thetaRhoPiChiIotaPrepareTheta(i, A, E) \ - Da = XOR64(Cu, ROL64(Ce, 1)); \ - De = XOR64(Ca, ROL64(Ci, 1)); \ - Di = XOR64(Ce, ROL64(Co, 1)); \ - Do = XOR64(Ci, ROL64(Cu, 1)); \ - Du = XOR64(Co, ROL64(Ca, 1)); \ -\ - XOReq64(A##ba, Da); \ - Bba = A##ba; \ - XOReq64(A##ge, De); \ - Bbe = ROL64(A##ge, 44); \ - XOReq64(A##ki, Di); \ - Bbi = ROL64(A##ki, 43); \ - E##ba = XOR64(Bba, ANDnu64(Bbe, Bbi)); \ - XOReq64(E##ba, CONST64(KeccakF1600RoundConstants[i])); \ - Ca = E##ba; \ - XOReq64(A##mo, Do); \ - Bbo = ROL64(A##mo, 21); \ - E##be = XOR64(Bbe, ANDnu64(Bbi, Bbo)); \ - Ce = E##be; \ - XOReq64(A##su, Du); \ - Bbu = ROL64(A##su, 14); \ - E##bi = XOR64(Bbi, ANDnu64(Bbo, Bbu)); \ - Ci = E##bi; \ - E##bo = XOR64(Bbo, ANDnu64(Bbu, Bba)); \ - Co = E##bo; \ - E##bu = XOR64(Bbu, ANDnu64(Bba, Bbe)); \ - Cu = E##bu; \ -\ - XOReq64(A##bo, Do); \ - Bga = ROL64(A##bo, 28); \ - XOReq64(A##gu, Du); \ - Bge = ROL64(A##gu, 20); \ - XOReq64(A##ka, Da); \ - Bgi = ROL64(A##ka, 3); \ - E##ga = XOR64(Bga, ANDnu64(Bge, Bgi)); \ - XOReq64(Ca, E##ga); \ - XOReq64(A##me, De); \ - Bgo = ROL64(A##me, 45); \ - E##ge = XOR64(Bge, ANDnu64(Bgi, Bgo)); \ - XOReq64(Ce, E##ge); \ - XOReq64(A##si, Di); \ - Bgu = ROL64(A##si, 61); \ - E##gi = XOR64(Bgi, ANDnu64(Bgo, Bgu)); \ - XOReq64(Ci, E##gi); \ - E##go = XOR64(Bgo, ANDnu64(Bgu, Bga)); \ - XOReq64(Co, E##go); \ - E##gu = XOR64(Bgu, ANDnu64(Bga, Bge)); \ - XOReq64(Cu, E##gu); \ -\ - XOReq64(A##be, De); \ - Bka = ROL64(A##be, 1); \ - XOReq64(A##gi, Di); \ - Bke = ROL64(A##gi, 6); \ - XOReq64(A##ko, Do); \ - Bki = ROL64(A##ko, 25); \ - E##ka = XOR64(Bka, ANDnu64(Bke, Bki)); \ - XOReq64(Ca, E##ka); \ - XOReq64(A##mu, Du); \ - Bko = ROL64(A##mu, 8); \ - E##ke = XOR64(Bke, ANDnu64(Bki, Bko)); \ - XOReq64(Ce, E##ke); \ - XOReq64(A##sa, Da); \ - Bku = ROL64(A##sa, 18); \ - E##ki = XOR64(Bki, ANDnu64(Bko, Bku)); \ - XOReq64(Ci, E##ki); \ - E##ko = XOR64(Bko, ANDnu64(Bku, Bka)); \ - XOReq64(Co, E##ko); \ - E##ku = XOR64(Bku, ANDnu64(Bka, Bke)); \ - XOReq64(Cu, E##ku); \ -\ - XOReq64(A##bu, Du); \ - Bma = ROL64(A##bu, 27); \ - XOReq64(A##ga, Da); \ - Bme = ROL64(A##ga, 36); \ - XOReq64(A##ke, De); \ - Bmi = ROL64(A##ke, 10); \ - E##ma = XOR64(Bma, ANDnu64(Bme, Bmi)); \ - XOReq64(Ca, E##ma); \ - XOReq64(A##mi, Di); \ - Bmo = ROL64(A##mi, 15); \ - E##me = XOR64(Bme, ANDnu64(Bmi, Bmo)); \ - XOReq64(Ce, E##me); \ - XOReq64(A##so, Do); \ - Bmu = ROL64(A##so, 56); \ - E##mi = XOR64(Bmi, ANDnu64(Bmo, Bmu)); \ - XOReq64(Ci, E##mi); \ - E##mo = XOR64(Bmo, ANDnu64(Bmu, Bma)); \ - XOReq64(Co, E##mo); \ - E##mu = XOR64(Bmu, ANDnu64(Bma, Bme)); \ - XOReq64(Cu, E##mu); \ -\ - XOReq64(A##bi, Di); \ - Bsa = ROL64(A##bi, 62); \ - XOReq64(A##go, Do); \ - Bse = ROL64(A##go, 55); \ - XOReq64(A##ku, Du); \ - Bsi = ROL64(A##ku, 39); \ - E##sa = XOR64(Bsa, ANDnu64(Bse, Bsi)); \ - XOReq64(Ca, E##sa); \ - XOReq64(A##ma, Da); \ - Bso = ROL64(A##ma, 41); \ - E##se = XOR64(Bse, ANDnu64(Bsi, Bso)); \ - XOReq64(Ce, E##se); \ - XOReq64(A##se, De); \ - Bsu = ROL64(A##se, 2); \ - E##si = XOR64(Bsi, ANDnu64(Bso, Bsu)); \ - XOReq64(Ci, E##si); \ - E##so = XOR64(Bso, ANDnu64(Bsu, Bsa)); \ - XOReq64(Co, E##so); \ - E##su = XOR64(Bsu, ANDnu64(Bsa, Bse)); \ - XOReq64(Cu, E##su); \ -\ - -/* --- Code for round */ -/* --- 64-bit lanes mapped to 64-bit words */ -#define thetaRhoPiChiIota(i, A, E) \ - Da = XOR64(Cu, ROL64(Ce, 1)); \ - De = XOR64(Ca, ROL64(Ci, 1)); \ - Di = XOR64(Ce, ROL64(Co, 1)); \ - Do = XOR64(Ci, ROL64(Cu, 1)); \ - Du = XOR64(Co, ROL64(Ca, 1)); \ -\ - XOReq64(A##ba, Da); \ - Bba = A##ba; \ - XOReq64(A##ge, De); \ - Bbe = ROL64(A##ge, 44); \ - XOReq64(A##ki, Di); \ - Bbi = ROL64(A##ki, 43); \ - E##ba = XOR64(Bba, ANDnu64(Bbe, Bbi)); \ - XOReq64(E##ba, CONST64(KeccakF1600RoundConstants[i])); \ - XOReq64(A##mo, Do); \ - Bbo = ROL64(A##mo, 21); \ - E##be = XOR64(Bbe, ANDnu64(Bbi, Bbo)); \ - XOReq64(A##su, Du); \ - Bbu = ROL64(A##su, 14); \ - E##bi = XOR64(Bbi, ANDnu64(Bbo, Bbu)); \ - E##bo = XOR64(Bbo, ANDnu64(Bbu, Bba)); \ - E##bu = XOR64(Bbu, ANDnu64(Bba, Bbe)); \ -\ - XOReq64(A##bo, Do); \ - Bga = ROL64(A##bo, 28); \ - XOReq64(A##gu, Du); \ - Bge = ROL64(A##gu, 20); \ - XOReq64(A##ka, Da); \ - Bgi = ROL64(A##ka, 3); \ - E##ga = XOR64(Bga, ANDnu64(Bge, Bgi)); \ - XOReq64(A##me, De); \ - Bgo = ROL64(A##me, 45); \ - E##ge = XOR64(Bge, ANDnu64(Bgi, Bgo)); \ - XOReq64(A##si, Di); \ - Bgu = ROL64(A##si, 61); \ - E##gi = XOR64(Bgi, ANDnu64(Bgo, Bgu)); \ - E##go = XOR64(Bgo, ANDnu64(Bgu, Bga)); \ - E##gu = XOR64(Bgu, ANDnu64(Bga, Bge)); \ -\ - XOReq64(A##be, De); \ - Bka = ROL64(A##be, 1); \ - XOReq64(A##gi, Di); \ - Bke = ROL64(A##gi, 6); \ - XOReq64(A##ko, Do); \ - Bki = ROL64(A##ko, 25); \ - E##ka = XOR64(Bka, ANDnu64(Bke, Bki)); \ - XOReq64(A##mu, Du); \ - Bko = ROL64(A##mu, 8); \ - E##ke = XOR64(Bke, ANDnu64(Bki, Bko)); \ - XOReq64(A##sa, Da); \ - Bku = ROL64(A##sa, 18); \ - E##ki = XOR64(Bki, ANDnu64(Bko, Bku)); \ - E##ko = XOR64(Bko, ANDnu64(Bku, Bka)); \ - E##ku = XOR64(Bku, ANDnu64(Bka, Bke)); \ -\ - XOReq64(A##bu, Du); \ - Bma = ROL64(A##bu, 27); \ - XOReq64(A##ga, Da); \ - Bme = ROL64(A##ga, 36); \ - XOReq64(A##ke, De); \ - Bmi = ROL64(A##ke, 10); \ - E##ma = XOR64(Bma, ANDnu64(Bme, Bmi)); \ - XOReq64(A##mi, Di); \ - Bmo = ROL64(A##mi, 15); \ - E##me = XOR64(Bme, ANDnu64(Bmi, Bmo)); \ - XOReq64(A##so, Do); \ - Bmu = ROL64(A##so, 56); \ - E##mi = XOR64(Bmi, ANDnu64(Bmo, Bmu)); \ - E##mo = XOR64(Bmo, ANDnu64(Bmu, Bma)); \ - E##mu = XOR64(Bmu, ANDnu64(Bma, Bme)); \ -\ - XOReq64(A##bi, Di); \ - Bsa = ROL64(A##bi, 62); \ - XOReq64(A##go, Do); \ - Bse = ROL64(A##go, 55); \ - XOReq64(A##ku, Du); \ - Bsi = ROL64(A##ku, 39); \ - E##sa = XOR64(Bsa, ANDnu64(Bse, Bsi)); \ - XOReq64(A##ma, Da); \ - Bso = ROL64(A##ma, 41); \ - E##se = XOR64(Bse, ANDnu64(Bsi, Bso)); \ - XOReq64(A##se, De); \ - Bsu = ROL64(A##se, 2); \ - E##si = XOR64(Bsi, ANDnu64(Bso, Bsu)); \ - E##so = XOR64(Bso, ANDnu64(Bsu, Bsa)); \ - E##su = XOR64(Bsu, ANDnu64(Bsa, Bse)); \ -\ - -static const UINT64 KeccakF1600RoundConstants[24] = { - 0x0000000000000001ULL, - 0x0000000000008082ULL, - 0x800000000000808aULL, - 0x8000000080008000ULL, - 0x000000000000808bULL, - 0x0000000080000001ULL, - 0x8000000080008081ULL, - 0x8000000000008009ULL, - 0x000000000000008aULL, - 0x0000000000000088ULL, - 0x0000000080008009ULL, - 0x000000008000000aULL, - 0x000000008000808bULL, - 0x800000000000008bULL, - 0x8000000000008089ULL, - 0x8000000000008003ULL, - 0x8000000000008002ULL, - 0x8000000000000080ULL, - 0x000000000000800aULL, - 0x800000008000000aULL, - 0x8000000080008081ULL, - 0x8000000000008080ULL, - 0x0000000080000001ULL, - 0x8000000080008008ULL }; - -#define copyFromStateAndXor576bits(X, state, input) \ - X##ba = XOR64(LOAD64(state[ 0]), LOAD64(input[ 0])); \ - X##be = XOR64(LOAD64(state[ 1]), LOAD64(input[ 1])); \ - X##bi = XOR64(LOAD64(state[ 2]), LOAD64(input[ 2])); \ - X##bo = XOR64(LOAD64(state[ 3]), LOAD64(input[ 3])); \ - X##bu = XOR64(LOAD64(state[ 4]), LOAD64(input[ 4])); \ - X##ga = XOR64(LOAD64(state[ 5]), LOAD64(input[ 5])); \ - X##ge = XOR64(LOAD64(state[ 6]), LOAD64(input[ 6])); \ - X##gi = XOR64(LOAD64(state[ 7]), LOAD64(input[ 7])); \ - X##go = XOR64(LOAD64(state[ 8]), LOAD64(input[ 8])); \ - X##gu = LOAD64(state[ 9]); \ - X##ka = LOAD64(state[10]); \ - X##ke = LOAD64(state[11]); \ - X##ki = LOAD64(state[12]); \ - X##ko = LOAD64(state[13]); \ - X##ku = LOAD64(state[14]); \ - X##ma = LOAD64(state[15]); \ - X##me = LOAD64(state[16]); \ - X##mi = LOAD64(state[17]); \ - X##mo = LOAD64(state[18]); \ - X##mu = LOAD64(state[19]); \ - X##sa = LOAD64(state[20]); \ - X##se = LOAD64(state[21]); \ - X##si = LOAD64(state[22]); \ - X##so = LOAD64(state[23]); \ - X##su = LOAD64(state[24]); \ - -#define copyFromStateAndXor832bits(X, state, input) \ - X##ba = XOR64(LOAD64(state[ 0]), LOAD64(input[ 0])); \ - X##be = XOR64(LOAD64(state[ 1]), LOAD64(input[ 1])); \ - X##bi = XOR64(LOAD64(state[ 2]), LOAD64(input[ 2])); \ - X##bo = XOR64(LOAD64(state[ 3]), LOAD64(input[ 3])); \ - X##bu = XOR64(LOAD64(state[ 4]), LOAD64(input[ 4])); \ - X##ga = XOR64(LOAD64(state[ 5]), LOAD64(input[ 5])); \ - X##ge = XOR64(LOAD64(state[ 6]), LOAD64(input[ 6])); \ - X##gi = XOR64(LOAD64(state[ 7]), LOAD64(input[ 7])); \ - X##go = XOR64(LOAD64(state[ 8]), LOAD64(input[ 8])); \ - X##gu = XOR64(LOAD64(state[ 9]), LOAD64(input[ 9])); \ - X##ka = XOR64(LOAD64(state[10]), LOAD64(input[10])); \ - X##ke = XOR64(LOAD64(state[11]), LOAD64(input[11])); \ - X##ki = XOR64(LOAD64(state[12]), LOAD64(input[12])); \ - X##ko = LOAD64(state[13]); \ - X##ku = LOAD64(state[14]); \ - X##ma = LOAD64(state[15]); \ - X##me = LOAD64(state[16]); \ - X##mi = LOAD64(state[17]); \ - X##mo = LOAD64(state[18]); \ - X##mu = LOAD64(state[19]); \ - X##sa = LOAD64(state[20]); \ - X##se = LOAD64(state[21]); \ - X##si = LOAD64(state[22]); \ - X##so = LOAD64(state[23]); \ - X##su = LOAD64(state[24]); \ - -#define copyFromStateAndXor1024bits(X, state, input) \ - X##ba = XOR64(LOAD64(state[ 0]), LOAD64(input[ 0])); \ - X##be = XOR64(LOAD64(state[ 1]), LOAD64(input[ 1])); \ - X##bi = XOR64(LOAD64(state[ 2]), LOAD64(input[ 2])); \ - X##bo = XOR64(LOAD64(state[ 3]), LOAD64(input[ 3])); \ - X##bu = XOR64(LOAD64(state[ 4]), LOAD64(input[ 4])); \ - X##ga = XOR64(LOAD64(state[ 5]), LOAD64(input[ 5])); \ - X##ge = XOR64(LOAD64(state[ 6]), LOAD64(input[ 6])); \ - X##gi = XOR64(LOAD64(state[ 7]), LOAD64(input[ 7])); \ - X##go = XOR64(LOAD64(state[ 8]), LOAD64(input[ 8])); \ - X##gu = XOR64(LOAD64(state[ 9]), LOAD64(input[ 9])); \ - X##ka = XOR64(LOAD64(state[10]), LOAD64(input[10])); \ - X##ke = XOR64(LOAD64(state[11]), LOAD64(input[11])); \ - X##ki = XOR64(LOAD64(state[12]), LOAD64(input[12])); \ - X##ko = XOR64(LOAD64(state[13]), LOAD64(input[13])); \ - X##ku = XOR64(LOAD64(state[14]), LOAD64(input[14])); \ - X##ma = XOR64(LOAD64(state[15]), LOAD64(input[15])); \ - X##me = LOAD64(state[16]); \ - X##mi = LOAD64(state[17]); \ - X##mo = LOAD64(state[18]); \ - X##mu = LOAD64(state[19]); \ - X##sa = LOAD64(state[20]); \ - X##se = LOAD64(state[21]); \ - X##si = LOAD64(state[22]); \ - X##so = LOAD64(state[23]); \ - X##su = LOAD64(state[24]); \ - -#define copyFromStateAndXor1088bits(X, state, input) \ - X##ba = XOR64(LOAD64(state[ 0]), LOAD64(input[ 0])); \ - X##be = XOR64(LOAD64(state[ 1]), LOAD64(input[ 1])); \ - X##bi = XOR64(LOAD64(state[ 2]), LOAD64(input[ 2])); \ - X##bo = XOR64(LOAD64(state[ 3]), LOAD64(input[ 3])); \ - X##bu = XOR64(LOAD64(state[ 4]), LOAD64(input[ 4])); \ - X##ga = XOR64(LOAD64(state[ 5]), LOAD64(input[ 5])); \ - X##ge = XOR64(LOAD64(state[ 6]), LOAD64(input[ 6])); \ - X##gi = XOR64(LOAD64(state[ 7]), LOAD64(input[ 7])); \ - X##go = XOR64(LOAD64(state[ 8]), LOAD64(input[ 8])); \ - X##gu = XOR64(LOAD64(state[ 9]), LOAD64(input[ 9])); \ - X##ka = XOR64(LOAD64(state[10]), LOAD64(input[10])); \ - X##ke = XOR64(LOAD64(state[11]), LOAD64(input[11])); \ - X##ki = XOR64(LOAD64(state[12]), LOAD64(input[12])); \ - X##ko = XOR64(LOAD64(state[13]), LOAD64(input[13])); \ - X##ku = XOR64(LOAD64(state[14]), LOAD64(input[14])); \ - X##ma = XOR64(LOAD64(state[15]), LOAD64(input[15])); \ - X##me = XOR64(LOAD64(state[16]), LOAD64(input[16])); \ - X##mi = LOAD64(state[17]); \ - X##mo = LOAD64(state[18]); \ - X##mu = LOAD64(state[19]); \ - X##sa = LOAD64(state[20]); \ - X##se = LOAD64(state[21]); \ - X##si = LOAD64(state[22]); \ - X##so = LOAD64(state[23]); \ - X##su = LOAD64(state[24]); \ - -#define copyFromStateAndXor1152bits(X, state, input) \ - X##ba = XOR64(LOAD64(state[ 0]), LOAD64(input[ 0])); \ - X##be = XOR64(LOAD64(state[ 1]), LOAD64(input[ 1])); \ - X##bi = XOR64(LOAD64(state[ 2]), LOAD64(input[ 2])); \ - X##bo = XOR64(LOAD64(state[ 3]), LOAD64(input[ 3])); \ - X##bu = XOR64(LOAD64(state[ 4]), LOAD64(input[ 4])); \ - X##ga = XOR64(LOAD64(state[ 5]), LOAD64(input[ 5])); \ - X##ge = XOR64(LOAD64(state[ 6]), LOAD64(input[ 6])); \ - X##gi = XOR64(LOAD64(state[ 7]), LOAD64(input[ 7])); \ - X##go = XOR64(LOAD64(state[ 8]), LOAD64(input[ 8])); \ - X##gu = XOR64(LOAD64(state[ 9]), LOAD64(input[ 9])); \ - X##ka = XOR64(LOAD64(state[10]), LOAD64(input[10])); \ - X##ke = XOR64(LOAD64(state[11]), LOAD64(input[11])); \ - X##ki = XOR64(LOAD64(state[12]), LOAD64(input[12])); \ - X##ko = XOR64(LOAD64(state[13]), LOAD64(input[13])); \ - X##ku = XOR64(LOAD64(state[14]), LOAD64(input[14])); \ - X##ma = XOR64(LOAD64(state[15]), LOAD64(input[15])); \ - X##me = XOR64(LOAD64(state[16]), LOAD64(input[16])); \ - X##mi = XOR64(LOAD64(state[17]), LOAD64(input[17])); \ - X##mo = LOAD64(state[18]); \ - X##mu = LOAD64(state[19]); \ - X##sa = LOAD64(state[20]); \ - X##se = LOAD64(state[21]); \ - X##si = LOAD64(state[22]); \ - X##so = LOAD64(state[23]); \ - X##su = LOAD64(state[24]); \ - -#define copyFromStateAndXor1344bits(X, state, input) \ - X##ba = XOR64(LOAD64(state[ 0]), LOAD64(input[ 0])); \ - X##be = XOR64(LOAD64(state[ 1]), LOAD64(input[ 1])); \ - X##bi = XOR64(LOAD64(state[ 2]), LOAD64(input[ 2])); \ - X##bo = XOR64(LOAD64(state[ 3]), LOAD64(input[ 3])); \ - X##bu = XOR64(LOAD64(state[ 4]), LOAD64(input[ 4])); \ - X##ga = XOR64(LOAD64(state[ 5]), LOAD64(input[ 5])); \ - X##ge = XOR64(LOAD64(state[ 6]), LOAD64(input[ 6])); \ - X##gi = XOR64(LOAD64(state[ 7]), LOAD64(input[ 7])); \ - X##go = XOR64(LOAD64(state[ 8]), LOAD64(input[ 8])); \ - X##gu = XOR64(LOAD64(state[ 9]), LOAD64(input[ 9])); \ - X##ka = XOR64(LOAD64(state[10]), LOAD64(input[10])); \ - X##ke = XOR64(LOAD64(state[11]), LOAD64(input[11])); \ - X##ki = XOR64(LOAD64(state[12]), LOAD64(input[12])); \ - X##ko = XOR64(LOAD64(state[13]), LOAD64(input[13])); \ - X##ku = XOR64(LOAD64(state[14]), LOAD64(input[14])); \ - X##ma = XOR64(LOAD64(state[15]), LOAD64(input[15])); \ - X##me = XOR64(LOAD64(state[16]), LOAD64(input[16])); \ - X##mi = XOR64(LOAD64(state[17]), LOAD64(input[17])); \ - X##mo = XOR64(LOAD64(state[18]), LOAD64(input[18])); \ - X##mu = XOR64(LOAD64(state[19]), LOAD64(input[19])); \ - X##sa = XOR64(LOAD64(state[20]), LOAD64(input[20])); \ - X##se = LOAD64(state[21]); \ - X##si = LOAD64(state[22]); \ - X##so = LOAD64(state[23]); \ - X##su = LOAD64(state[24]); \ - -#define copyFromState(X, state) \ - X##ba = LOAD64(state[ 0]); \ - X##be = LOAD64(state[ 1]); \ - X##bi = LOAD64(state[ 2]); \ - X##bo = LOAD64(state[ 3]); \ - X##bu = LOAD64(state[ 4]); \ - X##ga = LOAD64(state[ 5]); \ - X##ge = LOAD64(state[ 6]); \ - X##gi = LOAD64(state[ 7]); \ - X##go = LOAD64(state[ 8]); \ - X##gu = LOAD64(state[ 9]); \ - X##ka = LOAD64(state[10]); \ - X##ke = LOAD64(state[11]); \ - X##ki = LOAD64(state[12]); \ - X##ko = LOAD64(state[13]); \ - X##ku = LOAD64(state[14]); \ - X##ma = LOAD64(state[15]); \ - X##me = LOAD64(state[16]); \ - X##mi = LOAD64(state[17]); \ - X##mo = LOAD64(state[18]); \ - X##mu = LOAD64(state[19]); \ - X##sa = LOAD64(state[20]); \ - X##se = LOAD64(state[21]); \ - X##si = LOAD64(state[22]); \ - X##so = LOAD64(state[23]); \ - X##su = LOAD64(state[24]); \ - -#define copyToState(state, X) \ - STORE64(state[ 0], X##ba); \ - STORE64(state[ 1], X##be); \ - STORE64(state[ 2], X##bi); \ - STORE64(state[ 3], X##bo); \ - STORE64(state[ 4], X##bu); \ - STORE64(state[ 5], X##ga); \ - STORE64(state[ 6], X##ge); \ - STORE64(state[ 7], X##gi); \ - STORE64(state[ 8], X##go); \ - STORE64(state[ 9], X##gu); \ - STORE64(state[10], X##ka); \ - STORE64(state[11], X##ke); \ - STORE64(state[12], X##ki); \ - STORE64(state[13], X##ko); \ - STORE64(state[14], X##ku); \ - STORE64(state[15], X##ma); \ - STORE64(state[16], X##me); \ - STORE64(state[17], X##mi); \ - STORE64(state[18], X##mo); \ - STORE64(state[19], X##mu); \ - STORE64(state[20], X##sa); \ - STORE64(state[21], X##se); \ - STORE64(state[22], X##si); \ - STORE64(state[23], X##so); \ - STORE64(state[24], X##su); \ - -#define copyStateVariables(X, Y) \ - X##ba = Y##ba; \ - X##be = Y##be; \ - X##bi = Y##bi; \ - X##bo = Y##bo; \ - X##bu = Y##bu; \ - X##ga = Y##ga; \ - X##ge = Y##ge; \ - X##gi = Y##gi; \ - X##go = Y##go; \ - X##gu = Y##gu; \ - X##ka = Y##ka; \ - X##ke = Y##ke; \ - X##ki = Y##ki; \ - X##ko = Y##ko; \ - X##ku = Y##ku; \ - X##ma = Y##ma; \ - X##me = Y##me; \ - X##mi = Y##mi; \ - X##mo = Y##mo; \ - X##mu = Y##mu; \ - X##sa = Y##sa; \ - X##se = Y##se; \ - X##si = Y##si; \ - X##so = Y##so; \ - X##su = Y##su; \ - diff --git a/Modules/_sha3/keccak/KeccakF-1600-unrolling.macros b/Modules/_sha3/keccak/KeccakF-1600-unrolling.macros deleted file mode 100644 index 83c694ca4893..000000000000 --- a/Modules/_sha3/keccak/KeccakF-1600-unrolling.macros +++ /dev/null @@ -1,124 +0,0 @@ -/* -The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, -Michaël Peeters and Gilles Van Assche. For more information, feedback or -questions, please refer to our website: http://keccak.noekeon.org/ - -Implementation by the designers, -hereby denoted as "the implementer". - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#if (Unrolling == 24) -#define rounds \ - prepareTheta \ - thetaRhoPiChiIotaPrepareTheta( 0, A, E) \ - thetaRhoPiChiIotaPrepareTheta( 1, E, A) \ - thetaRhoPiChiIotaPrepareTheta( 2, A, E) \ - thetaRhoPiChiIotaPrepareTheta( 3, E, A) \ - thetaRhoPiChiIotaPrepareTheta( 4, A, E) \ - thetaRhoPiChiIotaPrepareTheta( 5, E, A) \ - thetaRhoPiChiIotaPrepareTheta( 6, A, E) \ - thetaRhoPiChiIotaPrepareTheta( 7, E, A) \ - thetaRhoPiChiIotaPrepareTheta( 8, A, E) \ - thetaRhoPiChiIotaPrepareTheta( 9, E, A) \ - thetaRhoPiChiIotaPrepareTheta(10, A, E) \ - thetaRhoPiChiIotaPrepareTheta(11, E, A) \ - thetaRhoPiChiIotaPrepareTheta(12, A, E) \ - thetaRhoPiChiIotaPrepareTheta(13, E, A) \ - thetaRhoPiChiIotaPrepareTheta(14, A, E) \ - thetaRhoPiChiIotaPrepareTheta(15, E, A) \ - thetaRhoPiChiIotaPrepareTheta(16, A, E) \ - thetaRhoPiChiIotaPrepareTheta(17, E, A) \ - thetaRhoPiChiIotaPrepareTheta(18, A, E) \ - thetaRhoPiChiIotaPrepareTheta(19, E, A) \ - thetaRhoPiChiIotaPrepareTheta(20, A, E) \ - thetaRhoPiChiIotaPrepareTheta(21, E, A) \ - thetaRhoPiChiIotaPrepareTheta(22, A, E) \ - thetaRhoPiChiIota(23, E, A) \ - copyToState(state, A) -#elif (Unrolling == 12) -#define rounds \ - prepareTheta \ - for(i=0; i<24; i+=12) { \ - thetaRhoPiChiIotaPrepareTheta(i , A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+ 1, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+ 2, A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+ 3, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+ 4, A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+ 5, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+ 6, A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+ 7, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+ 8, A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+ 9, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+10, A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+11, E, A) \ - } \ - copyToState(state, A) -#elif (Unrolling == 8) -#define rounds \ - prepareTheta \ - for(i=0; i<24; i+=8) { \ - thetaRhoPiChiIotaPrepareTheta(i , A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+3, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+4, A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+5, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+6, A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+7, E, A) \ - } \ - copyToState(state, A) -#elif (Unrolling == 6) -#define rounds \ - prepareTheta \ - for(i=0; i<24; i+=6) { \ - thetaRhoPiChiIotaPrepareTheta(i , A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+3, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+4, A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+5, E, A) \ - } \ - copyToState(state, A) -#elif (Unrolling == 4) -#define rounds \ - prepareTheta \ - for(i=0; i<24; i+=4) { \ - thetaRhoPiChiIotaPrepareTheta(i , A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+3, E, A) \ - } \ - copyToState(state, A) -#elif (Unrolling == 3) -#define rounds \ - prepareTheta \ - for(i=0; i<24; i+=3) { \ - thetaRhoPiChiIotaPrepareTheta(i , A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ - thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \ - copyStateVariables(A, E) \ - } \ - copyToState(state, A) -#elif (Unrolling == 2) -#define rounds \ - prepareTheta \ - for(i=0; i<24; i+=2) { \ - thetaRhoPiChiIotaPrepareTheta(i , A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ - } \ - copyToState(state, A) -#elif (Unrolling == 1) -#define rounds \ - prepareTheta \ - for(i=0; i<24; i++) { \ - thetaRhoPiChiIotaPrepareTheta(i , A, E) \ - copyStateVariables(A, E) \ - } \ - copyToState(state, A) -#else -#error "Unrolling is not correctly specified!" -#endif diff --git a/Modules/_sha3/keccak/KeccakF-1600-xop.macros b/Modules/_sha3/keccak/KeccakF-1600-xop.macros deleted file mode 100644 index 823c946fff4e..000000000000 --- a/Modules/_sha3/keccak/KeccakF-1600-xop.macros +++ /dev/null @@ -1,573 +0,0 @@ -/* -The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, -Michaël Peeters and Gilles Van Assche. For more information, feedback or -questions, please refer to our website: http://keccak.noekeon.org/ - -Implementation by the designers, -hereby denoted as "the implementer". - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#define declareABCDE \ - V128 Abage, Abegi, Abigo, Abogu, Abuga; \ - V128 Akame, Akemi, Akimo, Akomu, Akuma; \ - V128 Abae, Abio, Agae, Agio, Akae, Akio, Amae, Amio; \ - V64 Aba, Abe, Abi, Abo, Abu; \ - V64 Aga, Age, Agi, Ago, Agu; \ - V64 Aka, Ake, Aki, Ako, Aku; \ - V64 Ama, Ame, Ami, Amo, Amu; \ - V128 Asase, Asiso; \ - V64 Asu; \ - V128 Bbage, Bbegi, Bbigo, Bbogu, Bbuga; \ - V128 Bkame, Bkemi, Bkimo, Bkomu, Bkuma; \ - V128 Bsase, Bsesi, Bsiso, Bsosu, Bsusa; \ - V128 Cae, Cei, Cio, Cou, Cua; \ - V128 Dau, Dea, Die, Doi, Duo; \ - V128 Dua, Dae, Dei, Dio, Dou; \ - V128 Ebage, Ebegi, Ebigo, Ebogu, Ebuga; \ - V128 Ekame, Ekemi, Ekimo, Ekomu, Ekuma; \ - V128 Esase, Esiso; \ - V64 Esu; \ - V128 Zero; - -#define prepareTheta - -#define computeD \ - Cua = GET64LOLO(Cua, Cae); \ - Dei = XOR128(Cae, ROL6464same(Cio, 1)); \ - Dou = XOR128(Cio, ROL6464same(Cua, 1)); \ - Cei = GET64HILO(Cae, Cio); \ - Dae = XOR128(Cua, ROL6464same(Cei, 1)); \ - Dau = GET64LOHI(Dae, Dou); \ - Dea = SWAP64(Dae); \ - Die = SWAP64(Dei); \ - Doi = GET64LOLO(Dou, Die); \ - Duo = SWAP64(Dou); - -/* --- Theta Rho Pi Chi Iota Prepare-theta */ -/* --- 64-bit lanes mapped to 64-bit and 128-bit words */ -#define thetaRhoPiChiIotaPrepareTheta(i, A, E) \ - computeD \ - \ - Bbage = XOR128(GET64LOHI(A##bage, A##bogu), Dau); \ - Bbage = ROL6464(Bbage, 0, 20); \ - Bbegi = XOR128(GET64HILO(A##bage, A##kame), Dea); \ - Bbegi = ROL6464(Bbegi, 44, 3); \ - Bbigo = XOR128(GET64LOHI(A##kimo, A##kame), Die); \ - Bbigo = ROL6464(Bbigo, 43, 45); \ - E##bage = XOR128(Bbage, ANDnu128(Bbegi, Bbigo)); \ - XOReq128(E##bage, CONST64(KeccakF1600RoundConstants[i])); \ - Cae = E##bage; \ - Bbogu = XOR128(GET64HILO(A##kimo, A##siso), Doi); \ - Bbogu = ROL6464(Bbogu, 21, 61); \ - E##begi = XOR128(Bbegi, ANDnu128(Bbigo, Bbogu)); \ - Cei = E##begi; \ - Bbuga = XOR128(GET64LOLO(A##su, A##bogu), Duo); \ - Bbuga = ROL6464(Bbuga, 14, 28); \ - E##bigo = XOR128(Bbigo, ANDnu128(Bbogu, Bbuga)); \ - Cio = E##bigo; \ - E##bogu = XOR128(Bbogu, ANDnu128(Bbuga, Bbage)); \ - Cou = E##bogu; \ - E##buga = XOR128(Bbuga, ANDnu128(Bbage, Bbegi)); \ - Cua = E##buga; \ -\ - Bkame = XOR128(GET64LOHI(A##begi, A##buga), Dea); \ - Bkame = ROL6464(Bkame, 1, 36); \ - Bkemi = XOR128(GET64HILO(A##begi, A##kemi), Die); \ - Bkemi = ROL6464(Bkemi, 6, 10); \ - Bkimo = XOR128(GET64LOHI(A##komu, A##kemi), Doi); \ - Bkimo = ROL6464(Bkimo, 25, 15); \ - E##kame = XOR128(Bkame, ANDnu128(Bkemi, Bkimo)); \ - XOReq128(Cae, E##kame); \ - Bkomu = XOR128(GET64HIHI(A##komu, A##siso), Duo); \ - Bkomu = ROL6464(Bkomu, 8, 56); \ - E##kemi = XOR128(Bkemi, ANDnu128(Bkimo, Bkomu)); \ - XOReq128(Cei, E##kemi); \ - Bkuma = XOR128(GET64LOLO(A##sase, A##buga), Dau); \ - Bkuma = ROL6464(Bkuma, 18, 27); \ - E##kimo = XOR128(Bkimo, ANDnu128(Bkomu, Bkuma)); \ - XOReq128(Cio, E##kimo); \ - E##komu = XOR128(Bkomu, ANDnu128(Bkuma, Bkame)); \ - XOReq128(Cou, E##komu); \ - E##kuma = XOR128(Bkuma, ANDnu128(Bkame, Bkemi)); \ - XOReq128(Cua, E##kuma); \ -\ - Bsase = XOR128(A##bigo, SWAP64(Doi)); \ - Bsase = ROL6464(Bsase, 62, 55); \ - Bsiso = XOR128(A##kuma, SWAP64(Dau)); \ - Bsiso = ROL6464(Bsiso, 39, 41); \ - Bsusa = XOR64(COPY64HI2LO(A##sase), Dei); \ - Bsusa = ROL6464same(Bsusa, 2); \ - Bsusa = GET64LOLO(Bsusa, Bsase); \ - Bsesi = GET64HILO(Bsase, Bsiso); \ - Bsosu = GET64HILO(Bsiso, Bsusa); \ - E##sase = XOR128(Bsase, ANDnu128(Bsesi, Bsiso)); \ - XOReq128(Cae, E##sase); \ - E##siso = XOR128(Bsiso, ANDnu128(Bsosu, Bsusa)); \ - XOReq128(Cio, E##siso); \ - E##su = GET64LOLO(XOR128(Bsusa, ANDnu128(Bsase, Bsesi)), Zero); \ - XOReq128(Cua, E##su); \ -\ - Zero = ZERO128(); \ - XOReq128(Cae, GET64HIHI(Cua, Zero)); \ - XOReq128(Cae, GET64LOLO(Zero, Cei)); \ - XOReq128(Cio, GET64HIHI(Cei, Zero)); \ - XOReq128(Cio, GET64LOLO(Zero, Cou)); \ - XOReq128(Cua, GET64HIHI(Cou, Zero)); \ - -/* --- Theta Rho Pi Chi Iota */ -/* --- 64-bit lanes mapped to 64-bit and 128-bit words */ -#define thetaRhoPiChiIota(i, A, E) thetaRhoPiChiIotaPrepareTheta(i, A, E) - -static const UINT64 KeccakF1600RoundConstants[24] = { - 0x0000000000000001ULL, - 0x0000000000008082ULL, - 0x800000000000808aULL, - 0x8000000080008000ULL, - 0x000000000000808bULL, - 0x0000000080000001ULL, - 0x8000000080008081ULL, - 0x8000000000008009ULL, - 0x000000000000008aULL, - 0x0000000000000088ULL, - 0x0000000080008009ULL, - 0x000000008000000aULL, - 0x000000008000808bULL, - 0x800000000000008bULL, - 0x8000000000008089ULL, - 0x8000000000008003ULL, - 0x8000000000008002ULL, - 0x8000000000000080ULL, - 0x000000000000800aULL, - 0x800000008000000aULL, - 0x8000000080008081ULL, - 0x8000000000008080ULL, - 0x0000000080000001ULL, - 0x8000000080008008ULL }; - -#define copyFromStateAndXor576bits(X, state, input) \ - X##bae = XOR128(LOAD128(state[ 0]), LOAD128u(input[ 0])); \ - X##ba = X##bae; \ - X##be = GET64HIHI(X##bae, X##bae); \ - Cae = X##bae; \ - X##bio = XOR128(LOAD128(state[ 2]), LOAD128u(input[ 2])); \ - X##bi = X##bio; \ - X##bo = GET64HIHI(X##bio, X##bio); \ - Cio = X##bio; \ - X##bu = XOR64(LOAD64(state[ 4]), LOAD64(input[ 4])); \ - Cua = X##bu; \ - X##gae = XOR128(LOAD128u(state[ 5]), LOAD128u(input[ 5])); \ - X##ga = X##gae; \ - X##buga = GET64LOLO(X##bu, X##ga); \ - X##ge = GET64HIHI(X##gae, X##gae); \ - X##bage = GET64LOLO(X##ba, X##ge); \ - XOReq128(Cae, X##gae); \ - X##gio = XOR128(LOAD128u(state[ 7]), LOAD128u(input[ 7])); \ - X##gi = X##gio; \ - X##begi = GET64LOLO(X##be, X##gi); \ - X##go = GET64HIHI(X##gio, X##gio); \ - X##bigo = GET64LOLO(X##bi, X##go); \ - XOReq128(Cio, X##gio); \ - X##gu = LOAD64(state[ 9]); \ - X##bogu = GET64LOLO(X##bo, X##gu); \ - XOReq64(Cua, X##gu); \ - X##kae = LOAD128(state[10]); \ - X##ka = X##kae; \ - X##ke = GET64HIHI(X##kae, X##kae); \ - XOReq128(Cae, X##kae); \ - X##kio = LOAD128(state[12]); \ - X##ki = X##kio; \ - X##ko = GET64HIHI(X##kio, X##kio); \ - XOReq128(Cio, X##kio); \ - X##kuma = LOAD128(state[14]); \ - XOReq64(Cua, X##kuma); \ - X##me = LOAD64(state[16]); \ - X##kame = GET64LOLO(X##ka, X##me); \ - XOReq128(Cae, GET64HIHI(X##kuma, X##kame)); \ - X##mio = LOAD128u(state[17]); \ - X##mi = X##mio; \ - X##kemi = GET64LOLO(X##ke, X##mi); \ - X##mo = GET64HIHI(X##mio, X##mio); \ - X##kimo = GET64LOLO(X##ki, X##mo); \ - XOReq128(Cio, X##mio); \ - X##mu = LOAD64(state[19]); \ - X##komu = GET64LOLO(X##ko, X##mu); \ - XOReq64(Cua, X##mu); \ - X##sase = LOAD128(state[20]); \ - XOReq128(Cae, X##sase); \ - X##siso = LOAD128(state[22]); \ - XOReq128(Cio, X##siso); \ - X##su = LOAD64(state[24]); \ - XOReq64(Cua, X##su); \ - -#define copyFromStateAndXor832bits(X, state, input) \ - X##bae = XOR128(LOAD128(state[ 0]), LOAD128u(input[ 0])); \ - X##ba = X##bae; \ - X##be = GET64HIHI(X##bae, X##bae); \ - Cae = X##bae; \ - X##bio = XOR128(LOAD128(state[ 2]), LOAD128u(input[ 2])); \ - X##bi = X##bio; \ - X##bo = GET64HIHI(X##bio, X##bio); \ - Cio = X##bio; \ - X##bu = XOR64(LOAD64(state[ 4]), LOAD64(input[ 4])); \ - Cua = X##bu; \ - X##gae = XOR128(LOAD128u(state[ 5]), LOAD128u(input[ 5])); \ - X##ga = X##gae; \ - X##buga = GET64LOLO(X##bu, X##ga); \ - X##ge = GET64HIHI(X##gae, X##gae); \ - X##bage = GET64LOLO(X##ba, X##ge); \ - XOReq128(Cae, X##gae); \ - X##gio = XOR128(LOAD128u(state[ 7]), LOAD128u(input[ 7])); \ - X##gi = X##gio; \ - X##begi = GET64LOLO(X##be, X##gi); \ - X##go = GET64HIHI(X##gio, X##gio); \ - X##bigo = GET64LOLO(X##bi, X##go); \ - XOReq128(Cio, X##gio); \ - X##gu = XOR64(LOAD64(state[ 9]), LOAD64(input[ 9])); \ - X##bogu = GET64LOLO(X##bo, X##gu); \ - XOReq64(Cua, X##gu); \ - X##kae = XOR128(LOAD128(state[10]), LOAD128u(input[10])); \ - X##ka = X##kae; \ - X##ke = GET64HIHI(X##kae, X##kae); \ - XOReq128(Cae, X##kae); \ - X##kio = XOR128(LOAD128(state[12]), LOAD64(input[12])); \ - X##ki = X##kio; \ - X##ko = GET64HIHI(X##kio, X##kio); \ - XOReq128(Cio, X##kio); \ - X##kuma = LOAD128(state[14]); \ - XOReq64(Cua, X##kuma); \ - X##me = LOAD64(state[16]); \ - X##kame = GET64LOLO(X##ka, X##me); \ - XOReq128(Cae, GET64HIHI(X##kuma, X##kame)); \ - X##mio = LOAD128u(state[17]); \ - X##mi = X##mio; \ - X##kemi = GET64LOLO(X##ke, X##mi); \ - X##mo = GET64HIHI(X##mio, X##mio); \ - X##kimo = GET64LOLO(X##ki, X##mo); \ - XOReq128(Cio, X##mio); \ - X##mu = LOAD64(state[19]); \ - X##komu = GET64LOLO(X##ko, X##mu); \ - XOReq64(Cua, X##mu); \ - X##sase = LOAD128(state[20]); \ - XOReq128(Cae, X##sase); \ - X##siso = LOAD128(state[22]); \ - XOReq128(Cio, X##siso); \ - X##su = LOAD64(state[24]); \ - XOReq64(Cua, X##su); \ - -#define copyFromStateAndXor1024bits(X, state, input) \ - X##bae = XOR128(LOAD128(state[ 0]), LOAD128u(input[ 0])); \ - X##ba = X##bae; \ - X##be = GET64HIHI(X##bae, X##bae); \ - Cae = X##bae; \ - X##bio = XOR128(LOAD128(state[ 2]), LOAD128u(input[ 2])); \ - X##bi = X##bio; \ - X##bo = GET64HIHI(X##bio, X##bio); \ - Cio = X##bio; \ - X##bu = XOR64(LOAD64(state[ 4]), LOAD64(input[ 4])); \ - Cua = X##bu; \ - X##gae = XOR128(LOAD128u(state[ 5]), LOAD128u(input[ 5])); \ - X##ga = X##gae; \ - X##buga = GET64LOLO(X##bu, X##ga); \ - X##ge = GET64HIHI(X##gae, X##gae); \ - X##bage = GET64LOLO(X##ba, X##ge); \ - XOReq128(Cae, X##gae); \ - X##gio = XOR128(LOAD128u(state[ 7]), LOAD128u(input[ 7])); \ - X##gi = X##gio; \ - X##begi = GET64LOLO(X##be, X##gi); \ - X##go = GET64HIHI(X##gio, X##gio); \ - X##bigo = GET64LOLO(X##bi, X##go); \ - XOReq128(Cio, X##gio); \ - X##gu = XOR64(LOAD64(state[ 9]), LOAD64(input[ 9])); \ - X##bogu = GET64LOLO(X##bo, X##gu); \ - XOReq64(Cua, X##gu); \ - X##kae = XOR128(LOAD128(state[10]), LOAD128u(input[10])); \ - X##ka = X##kae; \ - X##ke = GET64HIHI(X##kae, X##kae); \ - XOReq128(Cae, X##kae); \ - X##kio = XOR128(LOAD128(state[12]), LOAD128u(input[12])); \ - X##ki = X##kio; \ - X##ko = GET64HIHI(X##kio, X##kio); \ - XOReq128(Cio, X##kio); \ - X##kuma = XOR128(LOAD128(state[14]), LOAD128(input[14])); \ - XOReq64(Cua, X##kuma); \ - X##me = LOAD64(state[16]); \ - X##kame = GET64LOLO(X##ka, X##me); \ - XOReq128(Cae, GET64HIHI(X##kuma, X##kame)); \ - X##mio = LOAD128u(state[17]); \ - X##mi = X##mio; \ - X##kemi = GET64LOLO(X##ke, X##mi); \ - X##mo = GET64HIHI(X##mio, X##mio); \ - X##kimo = GET64LOLO(X##ki, X##mo); \ - XOReq128(Cio, X##mio); \ - X##mu = LOAD64(state[19]); \ - X##komu = GET64LOLO(X##ko, X##mu); \ - XOReq64(Cua, X##mu); \ - X##sase = LOAD128(state[20]); \ - XOReq128(Cae, X##sase); \ - X##siso = LOAD128(state[22]); \ - XOReq128(Cio, X##siso); \ - X##su = LOAD64(state[24]); \ - XOReq64(Cua, X##su); \ - -#define copyFromStateAndXor1088bits(X, state, input) \ - X##bae = XOR128(LOAD128(state[ 0]), LOAD128u(input[ 0])); \ - X##ba = X##bae; \ - X##be = GET64HIHI(X##bae, X##bae); \ - Cae = X##bae; \ - X##bio = XOR128(LOAD128(state[ 2]), LOAD128u(input[ 2])); \ - X##bi = X##bio; \ - X##bo = GET64HIHI(X##bio, X##bio); \ - Cio = X##bio; \ - X##bu = XOR64(LOAD64(state[ 4]), LOAD64(input[ 4])); \ - Cua = X##bu; \ - X##gae = XOR128(LOAD128u(state[ 5]), LOAD128u(input[ 5])); \ - X##ga = X##gae; \ - X##buga = GET64LOLO(X##bu, X##ga); \ - X##ge = GET64HIHI(X##gae, X##gae); \ - X##bage = GET64LOLO(X##ba, X##ge); \ - XOReq128(Cae, X##gae); \ - X##gio = XOR128(LOAD128u(state[ 7]), LOAD128u(input[ 7])); \ - X##gi = X##gio; \ - X##begi = GET64LOLO(X##be, X##gi); \ - X##go = GET64HIHI(X##gio, X##gio); \ - X##bigo = GET64LOLO(X##bi, X##go); \ - XOReq128(Cio, X##gio); \ - X##gu = XOR64(LOAD64(state[ 9]), LOAD64(input[ 9])); \ - X##bogu = GET64LOLO(X##bo, X##gu); \ - XOReq64(Cua, X##gu); \ - X##kae = XOR128(LOAD128(state[10]), LOAD128u(input[10])); \ - X##ka = X##kae; \ - X##ke = GET64HIHI(X##kae, X##kae); \ - XOReq128(Cae, X##kae); \ - X##kio = XOR128(LOAD128(state[12]), LOAD128u(input[12])); \ - X##ki = X##kio; \ - X##ko = GET64HIHI(X##kio, X##kio); \ - XOReq128(Cio, X##kio); \ - X##kuma = XOR128(LOAD128(state[14]), LOAD128(input[14])); \ - XOReq64(Cua, X##kuma); \ - X##me = XOR64(LOAD64(state[16]), LOAD64(input[16])); \ - X##kame = GET64LOLO(X##ka, X##me); \ - XOReq128(Cae, GET64HIHI(X##kuma, X##kame)); \ - X##mio = LOAD128u(state[17]); \ - X##mi = X##mio; \ - X##kemi = GET64LOLO(X##ke, X##mi); \ - X##mo = GET64HIHI(X##mio, X##mio); \ - X##kimo = GET64LOLO(X##ki, X##mo); \ - XOReq128(Cio, X##mio); \ - X##mu = LOAD64(state[19]); \ - X##komu = GET64LOLO(X##ko, X##mu); \ - XOReq64(Cua, X##mu); \ - X##sase = LOAD128(state[20]); \ - XOReq128(Cae, X##sase); \ - X##siso = LOAD128(state[22]); \ - XOReq128(Cio, X##siso); \ - X##su = LOAD64(state[24]); \ - XOReq64(Cua, X##su); \ - -#define copyFromStateAndXor1152bits(X, state, input) \ - X##bae = XOR128(LOAD128(state[ 0]), LOAD128u(input[ 0])); \ - X##ba = X##bae; \ - X##be = GET64HIHI(X##bae, X##bae); \ - Cae = X##bae; \ - X##bio = XOR128(LOAD128(state[ 2]), LOAD128u(input[ 2])); \ - X##bi = X##bio; \ - X##bo = GET64HIHI(X##bio, X##bio); \ - Cio = X##bio; \ - X##bu = XOR64(LOAD64(state[ 4]), LOAD64(input[ 4])); \ - Cua = X##bu; \ - X##gae = XOR128(LOAD128u(state[ 5]), LOAD128u(input[ 5])); \ - X##ga = X##gae; \ - X##buga = GET64LOLO(X##bu, X##ga); \ - X##ge = GET64HIHI(X##gae, X##gae); \ - X##bage = GET64LOLO(X##ba, X##ge); \ - XOReq128(Cae, X##gae); \ - X##gio = XOR128(LOAD128u(state[ 7]), LOAD128u(input[ 7])); \ - X##gi = X##gio; \ - X##begi = GET64LOLO(X##be, X##gi); \ - X##go = GET64HIHI(X##gio, X##gio); \ - X##bigo = GET64LOLO(X##bi, X##go); \ - XOReq128(Cio, X##gio); \ - X##gu = XOR64(LOAD64(state[ 9]), LOAD64(input[ 9])); \ - X##bogu = GET64LOLO(X##bo, X##gu); \ - XOReq64(Cua, X##gu); \ - X##kae = XOR128(LOAD128(state[10]), LOAD128u(input[10])); \ - X##ka = X##kae; \ - X##ke = GET64HIHI(X##kae, X##kae); \ - XOReq128(Cae, X##kae); \ - X##kio = XOR128(LOAD128(state[12]), LOAD128u(input[12])); \ - X##ki = X##kio; \ - X##ko = GET64HIHI(X##kio, X##kio); \ - XOReq128(Cio, X##kio); \ - X##kuma = XOR128(LOAD128(state[14]), LOAD128(input[14])); \ - XOReq64(Cua, X##kuma); \ - X##me = XOR64(LOAD64(state[16]), LOAD64(input[16])); \ - X##kame = GET64LOLO(X##ka, X##me); \ - XOReq128(Cae, GET64HIHI(X##kuma, X##kame)); \ - X##mio = XOR128(LOAD128u(state[17]), LOAD64(input[17])); \ - X##mi = X##mio; \ - X##kemi = GET64LOLO(X##ke, X##mi); \ - X##mo = GET64HIHI(X##mio, X##mio); \ - X##kimo = GET64LOLO(X##ki, X##mo); \ - XOReq128(Cio, X##mio); \ - X##mu = LOAD64(state[19]); \ - X##komu = GET64LOLO(X##ko, X##mu); \ - XOReq64(Cua, X##mu); \ - X##sase = LOAD128(state[20]); \ - XOReq128(Cae, X##sase); \ - X##siso = LOAD128(state[22]); \ - XOReq128(Cio, X##siso); \ - X##su = LOAD64(state[24]); \ - XOReq64(Cua, X##su); \ - -#define copyFromStateAndXor1344bits(X, state, input) \ - X##bae = XOR128(LOAD128(state[ 0]), LOAD128u(input[ 0])); \ - X##ba = X##bae; \ - X##be = GET64HIHI(X##bae, X##bae); \ - Cae = X##bae; \ - X##bio = XOR128(LOAD128(state[ 2]), LOAD128u(input[ 2])); \ - X##bi = X##bio; \ - X##bo = GET64HIHI(X##bio, X##bio); \ - Cio = X##bio; \ - X##bu = XOR64(LOAD64(state[ 4]), LOAD64(input[ 4])); \ - Cua = X##bu; \ - X##gae = XOR128(LOAD128u(state[ 5]), LOAD128u(input[ 5])); \ - X##ga = X##gae; \ - X##buga = GET64LOLO(X##bu, X##ga); \ - X##ge = GET64HIHI(X##gae, X##gae); \ - X##bage = GET64LOLO(X##ba, X##ge); \ - XOReq128(Cae, X##gae); \ - X##gio = XOR128(LOAD128u(state[ 7]), LOAD128u(input[ 7])); \ - X##gi = X##gio; \ - X##begi = GET64LOLO(X##be, X##gi); \ - X##go = GET64HIHI(X##gio, X##gio); \ - X##bigo = GET64LOLO(X##bi, X##go); \ - XOReq128(Cio, X##gio); \ - X##gu = XOR64(LOAD64(state[ 9]), LOAD64(input[ 9])); \ - X##bogu = GET64LOLO(X##bo, X##gu); \ - XOReq64(Cua, X##gu); \ - X##kae = XOR128(LOAD128(state[10]), LOAD128u(input[10])); \ - X##ka = X##kae; \ - X##ke = GET64HIHI(X##kae, X##kae); \ - XOReq128(Cae, X##kae); \ - X##kio = XOR128(LOAD128(state[12]), LOAD128u(input[12])); \ - X##ki = X##kio; \ - X##ko = GET64HIHI(X##kio, X##kio); \ - XOReq128(Cio, X##kio); \ - X##kuma = XOR128(LOAD128(state[14]), LOAD128(input[14])); \ - XOReq64(Cua, X##kuma); \ - X##me = XOR64(LOAD64(state[16]), LOAD64(input[16])); \ - X##kame = GET64LOLO(X##ka, X##me); \ - XOReq128(Cae, GET64HIHI(X##kuma, X##kame)); \ - X##mio = XOR128(LOAD128u(state[17]), LOAD128u(input[17])); \ - X##mi = X##mio; \ - X##kemi = GET64LOLO(X##ke, X##mi); \ - X##mo = GET64HIHI(X##mio, X##mio); \ - X##kimo = GET64LOLO(X##ki, X##mo); \ - XOReq128(Cio, X##mio); \ - X##mu = XOR64(LOAD64(state[19]), LOAD64(input[19])); \ - X##komu = GET64LOLO(X##ko, X##mu); \ - XOReq64(Cua, X##mu); \ - X##sase = XOR128(LOAD128(state[20]), LOAD64(input[20])); \ - XOReq128(Cae, X##sase); \ - X##siso = LOAD128(state[22]); \ - XOReq128(Cio, X##siso); \ - X##su = LOAD64(state[24]); \ - XOReq64(Cua, X##su); \ - -#define copyFromState(X, state) \ - X##bae = LOAD128(state[ 0]); \ - X##ba = X##bae; \ - X##be = GET64HIHI(X##bae, X##bae); \ - Cae = X##bae; \ - X##bio = LOAD128(state[ 2]); \ - X##bi = X##bio; \ - X##bo = GET64HIHI(X##bio, X##bio); \ - Cio = X##bio; \ - X##bu = LOAD64(state[ 4]); \ - Cua = X##bu; \ - X##gae = LOAD128u(state[ 5]); \ - X##ga = X##gae; \ - X##buga = GET64LOLO(X##bu, X##ga); \ - X##ge = GET64HIHI(X##gae, X##gae); \ - X##bage = GET64LOLO(X##ba, X##ge); \ - XOReq128(Cae, X##gae); \ - X##gio = LOAD128u(state[ 7]); \ - X##gi = X##gio; \ - X##begi = GET64LOLO(X##be, X##gi); \ - X##go = GET64HIHI(X##gio, X##gio); \ - X##bigo = GET64LOLO(X##bi, X##go); \ - XOReq128(Cio, X##gio); \ - X##gu = LOAD64(state[ 9]); \ - X##bogu = GET64LOLO(X##bo, X##gu); \ - XOReq64(Cua, X##gu); \ - X##kae = LOAD128(state[10]); \ - X##ka = X##kae; \ - X##ke = GET64HIHI(X##kae, X##kae); \ - XOReq128(Cae, X##kae); \ - X##kio = LOAD128(state[12]); \ - X##ki = X##kio; \ - X##ko = GET64HIHI(X##kio, X##kio); \ - XOReq128(Cio, X##kio); \ - X##kuma = LOAD128(state[14]); \ - XOReq64(Cua, X##kuma); \ - X##me = LOAD64(state[16]); \ - X##kame = GET64LOLO(X##ka, X##me); \ - XOReq128(Cae, GET64HIHI(X##kuma, X##kame)); \ - X##mio = LOAD128u(state[17]); \ - X##mi = X##mio; \ - X##kemi = GET64LOLO(X##ke, X##mi); \ - X##mo = GET64HIHI(X##mio, X##mio); \ - X##kimo = GET64LOLO(X##ki, X##mo); \ - XOReq128(Cio, X##mio); \ - X##mu = LOAD64(state[19]); \ - X##komu = GET64LOLO(X##ko, X##mu); \ - XOReq64(Cua, X##mu); \ - X##sase = LOAD128(state[20]); \ - XOReq128(Cae, X##sase); \ - X##siso = LOAD128(state[22]); \ - XOReq128(Cio, X##siso); \ - X##su = LOAD64(state[24]); \ - XOReq64(Cua, X##su); \ - -#define copyToState(state, X) \ - STORE64(state[ 0], X##bage); \ - STORE64(state[ 1], X##begi); \ - STORE64(state[ 2], X##bigo); \ - STORE64(state[ 3], X##bogu); \ - STORE128(state[ 4], X##buga); \ - STORE64(state[ 6], COPY64HI2LO(X##bage)); \ - STORE64(state[ 7], COPY64HI2LO(X##begi)); \ - STORE64(state[ 8], COPY64HI2LO(X##bigo)); \ - STORE64(state[ 9], COPY64HI2LO(X##bogu)); \ - STORE64(state[10], X##kame); \ - STORE64(state[11], X##kemi); \ - STORE64(state[12], X##kimo); \ - STORE64(state[13], X##komu); \ - STORE128(state[14], X##kuma); \ - STORE64(state[16], COPY64HI2LO(X##kame)); \ - STORE64(state[17], COPY64HI2LO(X##kemi)); \ - STORE64(state[18], COPY64HI2LO(X##kimo)); \ - STORE64(state[19], COPY64HI2LO(X##komu)); \ - STORE128(state[20], X##sase); \ - STORE128(state[22], X##siso); \ - STORE64(state[24], X##su); \ - -#define copyStateVariables(X, Y) \ - X##bage = Y##bage; \ - X##begi = Y##begi; \ - X##bigo = Y##bigo; \ - X##bogu = Y##bogu; \ - X##buga = Y##buga; \ - X##kame = Y##kame; \ - X##kemi = Y##kemi; \ - X##kimo = Y##kimo; \ - X##komu = Y##komu; \ - X##kuma = Y##kuma; \ - X##sase = Y##sase; \ - X##siso = Y##siso; \ - X##su = Y##su; \ - diff --git a/Modules/_sha3/keccak/KeccakNISTInterface.c b/Modules/_sha3/keccak/KeccakNISTInterface.c deleted file mode 100644 index e94082bc24de..000000000000 --- a/Modules/_sha3/keccak/KeccakNISTInterface.c +++ /dev/null @@ -1,83 +0,0 @@ -/* -The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, -Michaël Peeters and Gilles Van Assche. For more information, feedback or -questions, please refer to our website: http://keccak.noekeon.org/ - -Implementation by the designers, -hereby denoted as "the implementer". - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#include -#include "KeccakNISTInterface.h" -#include "KeccakF-1600-interface.h" - -static HashReturn Init(hashState *state, int hashbitlen) -{ - switch(hashbitlen) { - case 0: /* Default parameters, arbitrary length output */ - InitSponge((spongeState*)state, 1024, 576); - break; - case 224: - InitSponge((spongeState*)state, 1152, 448); - break; - case 256: - InitSponge((spongeState*)state, 1088, 512); - break; - case 384: - InitSponge((spongeState*)state, 832, 768); - break; - case 512: - InitSponge((spongeState*)state, 576, 1024); - break; - default: - return BAD_HASHLEN; - } - state->fixedOutputLength = hashbitlen; - return SUCCESS; -} - -static HashReturn Update(hashState *state, const BitSequence *data, DataLength databitlen) -{ - if ((databitlen % 8) == 0) - return Absorb((spongeState*)state, data, databitlen); - else { - HashReturn ret = Absorb((spongeState*)state, data, databitlen - (databitlen % 8)); - if (ret == SUCCESS) { - unsigned char lastByte; - /* Align the last partial byte to the least significant bits */ - lastByte = data[databitlen/8] >> (8 - (databitlen % 8)); - return Absorb((spongeState*)state, &lastByte, databitlen % 8); - } - else - return ret; - } -} - -static HashReturn Final(hashState *state, BitSequence *hashval) -{ - return Squeeze(state, hashval, state->fixedOutputLength); -} - -/* -static HashReturn Hash(int hashbitlen, const BitSequence *data, DataLength databitlen, BitSequence *hashval) -{ - hashState state; - HashReturn result; - - if ((hashbitlen != 224) && (hashbitlen != 256) && (hashbitlen != 384) && (hashbitlen != 512)) - return BAD_HASHLEN; * Only the four fixed output lengths available through this API * - result = Init(&state, hashbitlen); - if (result != SUCCESS) - return result; - result = Update(&state, data, databitlen); - if (result != SUCCESS) - return result; - result = Final(&state, hashval); - return result; -} -*/ - diff --git a/Modules/_sha3/keccak/KeccakNISTInterface.h b/Modules/_sha3/keccak/KeccakNISTInterface.h deleted file mode 100644 index 244431b1eb84..000000000000 --- a/Modules/_sha3/keccak/KeccakNISTInterface.h +++ /dev/null @@ -1,72 +0,0 @@ -/* -The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, -Michaël Peeters and Gilles Van Assche. For more information, feedback or -questions, please refer to our website: http://keccak.noekeon.org/ - -Implementation by the designers, -hereby denoted as "the implementer". - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#ifndef _KeccakNISTInterface_h_ -#define _KeccakNISTInterface_h_ - -#include "KeccakSponge.h" - -typedef unsigned char BitSequence; -typedef unsigned long long DataLength; -typedef enum { SUCCESS = 0, FAIL = 1, BAD_HASHLEN = 2 } HashReturn; - -typedef spongeState hashState; - -/** - * Function to initialize the state of the Keccak[r, c] sponge function. - * The rate r and capacity c values are determined from @a hashbitlen. - * @param state Pointer to the state of the sponge function to be initialized. - * @param hashbitlen The desired number of output bits, - * or 0 for Keccak[] with default parameters - * and arbitrarily-long output. - * @pre The value of hashbitlen must be one of 0, 224, 256, 384 and 512. - * @return SUCCESS if successful, BAD_HASHLEN if the value of hashbitlen is incorrect. - */ -static HashReturn Init(hashState *state, int hashbitlen); -/** - * Function to give input data for the sponge function to absorb. - * @param state Pointer to the state of the sponge function initialized by Init(). - * @param data Pointer to the input data. - * When @a databitLen is not a multiple of 8, the last bits of data must be - * in the most significant bits of the last byte. - * @param databitLen The number of input bits provided in the input data. - * @pre In the previous call to Absorb(), databitLen was a multiple of 8. - * @return SUCCESS if successful, FAIL otherwise. - */ -static HashReturn Update(hashState *state, const BitSequence *data, DataLength databitlen); -/** - * Function to squeeze output data from the sponge function. - * If @a hashbitlen was not 0 in the call to Init(), the number of output bits is equal to @a hashbitlen. - * If @a hashbitlen was 0 in the call to Init(), the output bits must be extracted using the Squeeze() function. - * @param state Pointer to the state of the sponge function initialized by Init(). - * @param hashval Pointer to the buffer where to store the output data. - * @return SUCCESS if successful, FAIL otherwise. - */ -static HashReturn Final(hashState *state, BitSequence *hashval); -/** - * Function to compute a hash using the Keccak[r, c] sponge function. - * The rate r and capacity c values are determined from @a hashbitlen. - * @param hashbitlen The desired number of output bits. - * @param data Pointer to the input data. - * When @a databitLen is not a multiple of 8, the last bits of data must be - * in the most significant bits of the last byte. - * @param databitLen The number of input bits provided in the input data. - * @param hashval Pointer to the buffer where to store the output data. - * @pre The value of hashbitlen must be one of 224, 256, 384 and 512. - * @return SUCCESS if successful, BAD_HASHLEN if the value of hashbitlen is incorrect. - */ -/* -static HashReturn Hash(int hashbitlen, const BitSequence *data, DataLength databitlen, BitSequence *hashval); -*/ - -#endif diff --git a/Modules/_sha3/keccak/KeccakSponge.c b/Modules/_sha3/keccak/KeccakSponge.c deleted file mode 100644 index 1ca6bf00100e..000000000000 --- a/Modules/_sha3/keccak/KeccakSponge.c +++ /dev/null @@ -1,266 +0,0 @@ -/* -The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, -Michaël Peeters and Gilles Van Assche. For more information, feedback or -questions, please refer to our website: http://keccak.noekeon.org/ - -Implementation by the designers, -hereby denoted as "the implementer". - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#include -#include "KeccakSponge.h" -#include "KeccakF-1600-interface.h" -#ifdef KeccakReference -#include "displayIntermediateValues.h" -#endif - -static int InitSponge(spongeState *state, unsigned int rate, unsigned int capacity) -{ - if (rate+capacity != 1600) - return 1; - if ((rate <= 0) || (rate >= 1600) || ((rate % 64) != 0)) - return 1; - KeccakInitialize(); - state->rate = rate; - state->capacity = capacity; - state->fixedOutputLength = 0; - KeccakInitializeState(state->state); - memset(state->dataQueue, 0, KeccakMaximumRateInBytes); - state->bitsInQueue = 0; - state->squeezing = 0; - state->bitsAvailableForSqueezing = 0; - - return 0; -} - -static void AbsorbQueue(spongeState *state) -{ - /* state->bitsInQueue is assumed to be equal to state->rate */ - #ifdef KeccakReference - displayBytes(1, "Block to be absorbed", state->dataQueue, state->rate/8); - #endif -#ifdef ProvideFast576 - if (state->rate == 576) - KeccakAbsorb576bits(state->state, state->dataQueue); - else -#endif -#ifdef ProvideFast832 - if (state->rate == 832) - KeccakAbsorb832bits(state->state, state->dataQueue); - else -#endif -#ifdef ProvideFast1024 - if (state->rate == 1024) - KeccakAbsorb1024bits(state->state, state->dataQueue); - else -#endif -#ifdef ProvideFast1088 - if (state->rate == 1088) - KeccakAbsorb1088bits(state->state, state->dataQueue); - else -#endif -#ifdef ProvideFast1152 - if (state->rate == 1152) - KeccakAbsorb1152bits(state->state, state->dataQueue); - else -#endif -#ifdef ProvideFast1344 - if (state->rate == 1344) - KeccakAbsorb1344bits(state->state, state->dataQueue); - else -#endif - KeccakAbsorb(state->state, state->dataQueue, state->rate/64); - state->bitsInQueue = 0; -} - -static int Absorb(spongeState *state, const unsigned char *data, unsigned long long databitlen) -{ - unsigned long long i, j, wholeBlocks; - unsigned int partialBlock, partialByte; - const unsigned char *curData; - - if ((state->bitsInQueue % 8) != 0) - return 1; /* Only the last call may contain a partial byte */ - if (state->squeezing) - return 1; /* Too late for additional input */ - - i = 0; - while(i < databitlen) { - if ((state->bitsInQueue == 0) && (databitlen >= state->rate) && (i <= (databitlen-state->rate))) { - wholeBlocks = (databitlen-i)/state->rate; - curData = data+i/8; -#ifdef ProvideFast576 - if (state->rate == 576) { - for(j=0; jrate/8); - #endif - KeccakAbsorb576bits(state->state, curData); - } - } - else -#endif -#ifdef ProvideFast832 - if (state->rate == 832) { - for(j=0; jrate/8); - #endif - KeccakAbsorb832bits(state->state, curData); - } - } - else -#endif -#ifdef ProvideFast1024 - if (state->rate == 1024) { - for(j=0; jrate/8); - #endif - KeccakAbsorb1024bits(state->state, curData); - } - } - else -#endif -#ifdef ProvideFast1088 - if (state->rate == 1088) { - for(j=0; jrate/8); - #endif - KeccakAbsorb1088bits(state->state, curData); - } - } - else -#endif -#ifdef ProvideFast1152 - if (state->rate == 1152) { - for(j=0; jrate/8); - #endif - KeccakAbsorb1152bits(state->state, curData); - } - } - else -#endif -#ifdef ProvideFast1344 - if (state->rate == 1344) { - for(j=0; jrate/8); - #endif - KeccakAbsorb1344bits(state->state, curData); - } - } - else -#endif - { - for(j=0; jrate/8) { - #ifdef KeccakReference - displayBytes(1, "Block to be absorbed", curData, state->rate/8); - #endif - KeccakAbsorb(state->state, curData, state->rate/64); - } - } - i += wholeBlocks*state->rate; - } - else { - partialBlock = (unsigned int)(databitlen - i); - if (partialBlock+state->bitsInQueue > state->rate) - partialBlock = state->rate-state->bitsInQueue; - partialByte = partialBlock % 8; - partialBlock -= partialByte; - memcpy(state->dataQueue+state->bitsInQueue/8, data+i/8, partialBlock/8); - state->bitsInQueue += partialBlock; - i += partialBlock; - if (state->bitsInQueue == state->rate) - AbsorbQueue(state); - if (partialByte > 0) { - unsigned char mask = (1 << partialByte)-1; - state->dataQueue[state->bitsInQueue/8] = data[i/8] & mask; - state->bitsInQueue += partialByte; - i += partialByte; - } - } - } - return 0; -} - -static void PadAndSwitchToSqueezingPhase(spongeState *state) -{ - /* Note: the bits are numbered from 0=LSB to 7=MSB */ - if (state->bitsInQueue + 1 == state->rate) { - state->dataQueue[state->bitsInQueue/8 ] |= 1 << (state->bitsInQueue % 8); - AbsorbQueue(state); - memset(state->dataQueue, 0, state->rate/8); - } - else { - memset(state->dataQueue + (state->bitsInQueue+7)/8, 0, state->rate/8 - (state->bitsInQueue+7)/8); - state->dataQueue[state->bitsInQueue/8 ] |= 1 << (state->bitsInQueue % 8); - } - state->dataQueue[(state->rate-1)/8] |= 1 << ((state->rate-1) % 8); - AbsorbQueue(state); - - #ifdef KeccakReference - displayText(1, "--- Switching to squeezing phase ---"); - #endif -#ifdef ProvideFast1024 - if (state->rate == 1024) { - KeccakExtract1024bits(state->state, state->dataQueue); - state->bitsAvailableForSqueezing = 1024; - } - else -#endif - { - KeccakExtract(state->state, state->dataQueue, state->rate/64); - state->bitsAvailableForSqueezing = state->rate; - } - #ifdef KeccakReference - displayBytes(1, "Block available for squeezing", state->dataQueue, state->bitsAvailableForSqueezing/8); - #endif - state->squeezing = 1; -} - -static int Squeeze(spongeState *state, unsigned char *output, unsigned long long outputLength) -{ - unsigned long long i; - unsigned int partialBlock; - - if (!state->squeezing) - PadAndSwitchToSqueezingPhase(state); - if ((outputLength % 8) != 0) - return 1; /* Only multiple of 8 bits are allowed, truncation can be done at user level */ - - i = 0; - while(i < outputLength) { - if (state->bitsAvailableForSqueezing == 0) { - KeccakPermutation(state->state); -#ifdef ProvideFast1024 - if (state->rate == 1024) { - KeccakExtract1024bits(state->state, state->dataQueue); - state->bitsAvailableForSqueezing = 1024; - } - else -#endif - { - KeccakExtract(state->state, state->dataQueue, state->rate/64); - state->bitsAvailableForSqueezing = state->rate; - } - #ifdef KeccakReference - displayBytes(1, "Block available for squeezing", state->dataQueue, state->bitsAvailableForSqueezing/8); - #endif - } - partialBlock = state->bitsAvailableForSqueezing; - if ((unsigned long long)partialBlock > outputLength - i) - partialBlock = (unsigned int)(outputLength - i); - memcpy(output+i/8, state->dataQueue+(state->rate-state->bitsAvailableForSqueezing)/8, partialBlock/8); - state->bitsAvailableForSqueezing -= partialBlock; - i += partialBlock; - } - return 0; -} diff --git a/Modules/_sha3/keccak/KeccakSponge.h b/Modules/_sha3/keccak/KeccakSponge.h deleted file mode 100644 index a545cacb3035..000000000000 --- a/Modules/_sha3/keccak/KeccakSponge.h +++ /dev/null @@ -1,76 +0,0 @@ -/* -The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, -Michaël Peeters and Gilles Van Assche. For more information, feedback or -questions, please refer to our website: http://keccak.noekeon.org/ - -Implementation by the designers, -hereby denoted as "the implementer". - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -#ifndef _KeccakSponge_h_ -#define _KeccakSponge_h_ - -#define KeccakPermutationSize 1600 -#define KeccakPermutationSizeInBytes (KeccakPermutationSize/8) -#define KeccakMaximumRate 1536 -#define KeccakMaximumRateInBytes (KeccakMaximumRate/8) - -#if defined(__GNUC__) -#define ALIGN __attribute__ ((aligned(32))) -#elif defined(_MSC_VER) -#define ALIGN __declspec(align(32)) -#else -#define ALIGN -#endif - -ALIGN typedef struct spongeStateStruct { - ALIGN unsigned char state[KeccakPermutationSizeInBytes]; - ALIGN unsigned char dataQueue[KeccakMaximumRateInBytes]; - unsigned int rate; - unsigned int capacity; - unsigned int bitsInQueue; - unsigned int fixedOutputLength; - int squeezing; - unsigned int bitsAvailableForSqueezing; -} spongeState; - -/** - * Function to initialize the state of the Keccak[r, c] sponge function. - * The sponge function is set to the absorbing phase. - * @param state Pointer to the state of the sponge function to be initialized. - * @param rate The value of the rate r. - * @param capacity The value of the capacity c. - * @pre One must have r+c=1600 and the rate a multiple of 64 bits in this implementation. - * @return Zero if successful, 1 otherwise. - */ -static int InitSponge(spongeState *state, unsigned int rate, unsigned int capacity); -/** - * Function to give input data for the sponge function to absorb. - * @param state Pointer to the state of the sponge function initialized by InitSponge(). - * @param data Pointer to the input data. - * When @a databitLen is not a multiple of 8, the last bits of data must be - * in the least significant bits of the last byte. - * @param databitLen The number of input bits provided in the input data. - * @pre In the previous call to Absorb(), databitLen was a multiple of 8. - * @pre The sponge function must be in the absorbing phase, - * i.e., Squeeze() must not have been called before. - * @return Zero if successful, 1 otherwise. - */ -static int Absorb(spongeState *state, const unsigned char *data, unsigned long long databitlen); -/** - * Function to squeeze output data from the sponge function. - * If the sponge function was in the absorbing phase, this function - * switches it to the squeezing phase. - * @param state Pointer to the state of the sponge function initialized by InitSponge(). - * @param output Pointer to the buffer where to store the output data. - * @param outputLength The number of output bits desired. - * It must be a multiple of 8. - * @return Zero if successful, 1 otherwise. - */ -static int Squeeze(spongeState *state, unsigned char *output, unsigned long long outputLength); - -#endif diff --git a/Modules/_sha3/keccak/brg_endian.h b/Modules/_sha3/keccak/brg_endian.h deleted file mode 100755 index 7226eb3bec51..000000000000 --- a/Modules/_sha3/keccak/brg_endian.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - --------------------------------------------------------------------------- - Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved. - - LICENSE TERMS - - The redistribution and use of this software (with or without changes) - is allowed without the payment of fees or royalties provided that: - - 1. source code distributions include the above copyright notice, this - list of conditions and the following disclaimer; - - 2. binary distributions include the above copyright notice, this list - of conditions and the following disclaimer in their documentation; - - 3. the name of the copyright holder is not used to endorse products - built using this software without specific written permission. - - DISCLAIMER - - This software is provided 'as is' with no explicit or implied warranties - in respect of its properties, including, but not limited to, correctness - and/or fitness for purpose. - --------------------------------------------------------------------------- - Issue Date: 20/12/2007 - Changes for ARM 9/9/2010 -*/ - -#ifndef _BRG_ENDIAN_H -#define _BRG_ENDIAN_H - -#define IS_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */ -#define IS_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */ - -#if 0 -/* Include files where endian defines and byteswap functions may reside */ -#if defined( __sun ) -# include -#elif defined( __FreeBSD__ ) || defined( __OpenBSD__ ) || defined( __NetBSD__ ) -# include -#elif defined( BSD ) && ( BSD >= 199103 ) || defined( __APPLE__ ) || \ - defined( __CYGWIN32__ ) || defined( __DJGPP__ ) || defined( __osf__ ) -# include -#elif defined( __linux__ ) || defined( __GNUC__ ) || defined( __GNU_LIBRARY__ ) -# if !defined( __MINGW32__ ) && !defined( _AIX ) -# include -# if !defined( __BEOS__ ) -# include -# endif -# endif -#endif -#endif - -/* Now attempt to set the define for platform byte order using any */ -/* of the four forms SYMBOL, _SYMBOL, __SYMBOL & __SYMBOL__, which */ -/* seem to encompass most endian symbol definitions */ - -#if defined( BIG_ENDIAN ) && defined( LITTLE_ENDIAN ) -# if defined( BYTE_ORDER ) && BYTE_ORDER == BIG_ENDIAN -# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN -# elif defined( BYTE_ORDER ) && BYTE_ORDER == LITTLE_ENDIAN -# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN -# endif -#elif defined( BIG_ENDIAN ) -# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN -#elif defined( LITTLE_ENDIAN ) -# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN -#endif - -#if defined( _BIG_ENDIAN ) && defined( _LITTLE_ENDIAN ) -# if defined( _BYTE_ORDER ) && _BYTE_ORDER == _BIG_ENDIAN -# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN -# elif defined( _BYTE_ORDER ) && _BYTE_ORDER == _LITTLE_ENDIAN -# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN -# endif -#elif defined( _BIG_ENDIAN ) -# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN -#elif defined( _LITTLE_ENDIAN ) -# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN -#endif - -#if defined( __BIG_ENDIAN ) && defined( __LITTLE_ENDIAN ) -# if defined( __BYTE_ORDER ) && __BYTE_ORDER == __BIG_ENDIAN -# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN -# elif defined( __BYTE_ORDER ) && __BYTE_ORDER == __LITTLE_ENDIAN -# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN -# endif -#elif defined( __BIG_ENDIAN ) -# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN -#elif defined( __LITTLE_ENDIAN ) -# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN -#endif - -#if defined( __BIG_ENDIAN__ ) && defined( __LITTLE_ENDIAN__ ) -# if defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __BIG_ENDIAN__ -# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN -# elif defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __LITTLE_ENDIAN__ -# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN -# endif -#elif defined( __BIG_ENDIAN__ ) -# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN -#elif defined( __LITTLE_ENDIAN__ ) -# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN -#endif - -/* if the platform byte order could not be determined, then try to */ -/* set this define using common machine defines */ -#if !defined(PLATFORM_BYTE_ORDER) - -#if defined( __alpha__ ) || defined( __alpha ) || defined( i386 ) || \ - defined( __i386__ ) || defined( _M_I86 ) || defined( _M_IX86 ) || \ - defined( __OS2__ ) || defined( sun386 ) || defined( __TURBOC__ ) || \ - defined( vax ) || defined( vms ) || defined( VMS ) || \ - defined( __VMS ) || defined( _M_X64 ) -# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN - -#elif defined( AMIGA ) || defined( applec ) || defined( __AS400__ ) || \ - defined( _CRAY ) || defined( __hppa ) || defined( __hp9000 ) || \ - defined( ibm370 ) || defined( mc68000 ) || defined( m68k ) || \ - defined( __MRC__ ) || defined( __MVS__ ) || defined( __MWERKS__ ) || \ - defined( sparc ) || defined( __sparc) || defined( SYMANTEC_C ) || \ - defined( __VOS__ ) || defined( __TIGCC__ ) || defined( __TANDEM ) || \ - defined( THINK_C ) || defined( __VMCMS__ ) || defined( _AIX ) -# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN - -#elif defined(__arm__) -# ifdef __BIG_ENDIAN -# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN -# else -# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN -# endif -#elif 1 /* **** EDIT HERE IF NECESSARY **** */ -# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN -#elif 0 /* **** EDIT HERE IF NECESSARY **** */ -# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN -#else -# error Please edit lines 132 or 134 in brg_endian.h to set the platform byte order -#endif - -#endif - -#endif diff --git a/Modules/_sha3/keccak/crypto_hash.h b/Modules/_sha3/keccak/crypto_hash.h deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/Modules/_sha3/sha3module.c b/Modules/_sha3/sha3module.c deleted file mode 100644 index 71127d0b76c5..000000000000 --- a/Modules/_sha3/sha3module.c +++ /dev/null @@ -1,593 +0,0 @@ -/* SHA3 module - * - * This module provides an interface to the SHA3 algorithm - * - * See below for information about the original code this module was - * based upon. Additional work performed by: - * - * Andrew Kuchling (amk@amk.ca) - * Greg Stein (gstein@lyra.org) - * Trevor Perrin (trevp@trevp.net) - * Gregory P. Smith (greg@krypto.org) - * - * Copyright (C) 2012 Christian Heimes (christian@python.org) - * Licensed to PSF under a Contributor Agreement. - * - */ - -#include "Python.h" -#include "../hashlib.h" - -/* ************************************************************************** - * SHA-3 (Keccak) - * - * The code is based on KeccakReferenceAndOptimized-3.2.zip from 29 May 2012. - * - * The reference implementation is altered in this points: - * - C++ comments are converted to ANSI C comments. - * - All functions and globals are declared static. - * - The typedef for UINT64 is commented out. - * - KeccakF-1600-opt[32|64]-settings.h are commented out - * - Some unused functions are commented out to silence compiler warnings. - * - * In order to avoid name clashes with other software I have to declare all - * Keccak functions and global data as static. The C code is directly - * included into this file in order to access the static functions. - * - * Keccak can be tuned with several paramenters. I try to explain all options - * as far as I understand them. The reference implementation also contains - * assembler code for ARM platforms (NEON instructions). - * - * Common - * ====== - * - * Options: - * UseBebigokimisa, Unrolling - * - * - Unrolling: loop unrolling (24, 12, 8, 6, 4, 3, 2, 1) - * - UseBebigokimisa: lane complementing - * - * 64bit platforms - * =============== - * - * Additional options: - * UseSSE, UseOnlySIMD64, UseMMX, UseXOP, UseSHLD - * - * Optimized instructions (disabled by default): - * - UseSSE: use Stream SIMD extensions - * o UseOnlySIMD64: limit to 64bit instructions, otherwise 128bit - * o w/o UseOnlySIMD64: requires compiler agument -mssse3 or -mtune - * - UseMMX: use 64bit MMX instructions - * - UseXOP: use AMD's eXtended Operations (128bit SSE extension) - * - * Other: - * - Unrolling: default 24 - * - UseBebigokimisa: default 1 - * - * When neither UseSSE, UseMMX nor UseXOP is configured, ROL64 (rotate left - * 64) is implemented as: - * - Windows: _rotl64() - * - UseSHLD: use shld (shift left) asm optimization - * - otherwise: shift and xor - * - * UseBebigokimisa can't be used in combination with UseSSE, UseMMX or - * UseXOP. UseOnlySIMD64 has no effect unless UseSSE is specified. - * - * Tests have shown that UseSSE + UseOnlySIMD64 is about three to four - * times SLOWER than UseBebigokimisa. UseSSE and UseMMX are about two times - * slower. (tested by CH and AP) - * - * 32bit platforms - * =============== - * - * Additional options: - * UseInterleaveTables, UseSchedule - * - * - Unrolling: default 2 - * - UseBebigokimisa: default n/a - * - UseSchedule: ???, (1, 2, 3; default 3) - * - UseInterleaveTables: use two 64k lookup tables for (de)interleaving - * default: n/a - * - * schedules: - * - 3: no UseBebigokimisa, Unrolling must be 2 - * - 2 + 1: ??? - * - * *************************************************************************/ - -#ifdef __sparc - /* opt64 uses un-aligned memory access that causes a BUS error with msg - * 'invalid address alignment' on SPARC. */ - #define KeccakOpt 32 -#elif SIZEOF_VOID_P == 8 && defined(PY_UINT64_T) - /* opt64 works only for 64bit platforms with unsigned int64 */ - #define KeccakOpt 64 -#else - /* opt32 is used for the remaining 32 and 64bit platforms */ - #define KeccakOpt 32 -#endif - -#if KeccakOpt == 64 && defined(PY_UINT64_T) - /* 64bit platforms with unsigned int64 */ - #define Unrolling 24 - #define UseBebigokimisa - typedef PY_UINT64_T UINT64; -#elif KeccakOpt == 32 && defined(PY_UINT64_T) - /* 32bit platforms with unsigned int64 */ - #define Unrolling 2 - #define UseSchedule 3 - typedef PY_UINT64_T UINT64; -#else - /* 32 or 64bit platforms without unsigned int64 */ - #define Unrolling 2 - #define UseSchedule 3 - #define UseInterleaveTables -#endif - -/* replacement for brg_endian.h */ -#define IS_BIG_ENDIAN 4321 -#define IS_LITTLE_ENDIAN 1234 -#if PY_BIG_ENDIAN -# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN -#else -# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN -#endif - -/* inline all Keccak dependencies */ -#include "keccak/KeccakNISTInterface.h" -#include "keccak/KeccakNISTInterface.c" -#include "keccak/KeccakSponge.c" -#if KeccakOpt == 64 - #include "keccak/KeccakF-1600-opt64.c" -#elif KeccakOpt == 32 - #include "keccak/KeccakF-1600-opt32.c" -#endif - -/* #define SHA3_BLOCKSIZE 200 // 1600 bits */ -#define SHA3_MAX_DIGESTSIZE 64 /* 512 bits */ -#define SHA3_state hashState -#define SHA3_init Init -#define SHA3_process Update -#define SHA3_done Final -#define SHA3_copystate(dest, src) memcpy(&(dest), &(src), sizeof(SHA3_state)) -#define SHA3_clearstate(state) memset(&(state), 0, sizeof(SHA3_state)) - -/* The structure for storing SHA3 info */ - -typedef struct { - PyObject_HEAD - int hashbitlen; - SHA3_state hash_state; -#ifdef WITH_THREAD - PyThread_type_lock lock; -#endif - -} SHA3object; - -static PyTypeObject SHA3type; - - -static SHA3object * -newSHA3object(int hashbitlen) -{ - SHA3object *newobj; - - /* check hashbitlen */ - switch(hashbitlen) { - /* supported hash length */ - case 224: - break; - case 256: - break; - case 384: - break; - case 512: - break; - case 0: - /* arbitrarily-long output isn't supported by this module */ - default: - /* everything else is an error */ - PyErr_SetString(PyExc_ValueError, - "hashbitlen must be one of 224, 256, 384 or 512."); - return NULL; - } - newobj = (SHA3object *)PyObject_New(SHA3object, &SHA3type); - if (newobj == NULL) { - return NULL; - } - newobj->hashbitlen = hashbitlen; -#ifdef WITH_THREAD - newobj->lock = NULL; -#endif - return newobj; -} - - -/* Internal methods for a hash object */ - -static void -SHA3_dealloc(SHA3object *self) -{ - SHA3_clearstate(self->hash_state); -#ifdef WITH_THREAD - if (self->lock) { - PyThread_free_lock(self->lock); - } -#endif - PyObject_Del(self); -} - - -/* External methods for a hash object */ - -PyDoc_STRVAR(SHA3_copy__doc__, "Return a copy of the hash object."); - -static PyObject * -SHA3_copy(SHA3object *self, PyObject *unused) -{ - SHA3object *newobj; - - if ((newobj = newSHA3object(self->hashbitlen)) == NULL) { - return NULL; - } - ENTER_HASHLIB(self); - SHA3_copystate(newobj->hash_state, self->hash_state); - LEAVE_HASHLIB(self); - return (PyObject *)newobj; -} - - -PyDoc_STRVAR(SHA3_digest__doc__, -"Return the digest value as a string of binary data."); - -static PyObject * -SHA3_digest(SHA3object *self, PyObject *unused) -{ - unsigned char digest[SHA3_MAX_DIGESTSIZE]; - SHA3_state temp; - HashReturn res; - - ENTER_HASHLIB(self); - SHA3_copystate(temp, self->hash_state); - LEAVE_HASHLIB(self); - res = SHA3_done(&temp, digest); - SHA3_clearstate(temp); - if (res != SUCCESS) { - PyErr_SetString(PyExc_RuntimeError, "internal error in SHA3 Final()"); - return NULL; - } - return PyBytes_FromStringAndSize((const char *)digest, - self->hashbitlen / 8); -} - - -PyDoc_STRVAR(SHA3_hexdigest__doc__, -"Return the digest value as a string of hexadecimal digits."); - -static PyObject * -SHA3_hexdigest(SHA3object *self, PyObject *unused) -{ - unsigned char digest[SHA3_MAX_DIGESTSIZE]; - SHA3_state temp; - HashReturn res; - PyObject *retval; - Py_UCS1 *hex_digest; - int digestlen, i, j; - - /* Get the raw (binary) digest value */ - ENTER_HASHLIB(self); - SHA3_copystate(temp, self->hash_state); - LEAVE_HASHLIB(self); - res = SHA3_done(&temp, digest); - SHA3_clearstate(temp); - if (res != SUCCESS) { - PyErr_SetString(PyExc_RuntimeError, "internal error in SHA3 Final()"); - return NULL; - } - - /* Create a new string */ - digestlen = self->hashbitlen / 8; - retval = PyUnicode_New(digestlen * 2, 127); - if (!retval) - return NULL; - hex_digest = PyUnicode_1BYTE_DATA(retval); - - /* Make hex version of the digest */ - for(i=j=0; i < digestlen; i++) { - unsigned char c; - c = (digest[i] >> 4) & 0xf; - hex_digest[j++] = Py_hexdigits[c]; - c = (digest[i] & 0xf); - hex_digest[j++] = Py_hexdigits[c]; - } -#ifdef Py_DEBUG - assert(_PyUnicode_CheckConsistency(retval, 1)); -#endif - return retval; -} - -PyDoc_STRVAR(SHA3_update__doc__, -"Update this hash object's state with the provided string."); - -static PyObject * -SHA3_update(SHA3object *self, PyObject *args) -{ - PyObject *obj; - Py_buffer buf; - HashReturn res; - - if (!PyArg_ParseTuple(args, "O:update", &obj)) - return NULL; - - GET_BUFFER_VIEW_OR_ERROUT(obj, &buf); - - /* add new data, the function takes the length in bits not bytes */ -#ifdef WITH_THREAD - if (self->lock == NULL && buf.len >= HASHLIB_GIL_MINSIZE) { - self->lock = PyThread_allocate_lock(); - } - /* Once a lock exists all code paths must be synchronized. We have to - * release the GIL even for small buffers as acquiring the lock may take - * an unlimited amount of time when another thread updates this object - * with lots of data. */ - if (self->lock) { - Py_BEGIN_ALLOW_THREADS - PyThread_acquire_lock(self->lock, 1); - res = SHA3_process(&self->hash_state, buf.buf, buf.len * 8); - PyThread_release_lock(self->lock); - Py_END_ALLOW_THREADS - } - else { - res = SHA3_process(&self->hash_state, buf.buf, buf.len * 8); - } -#else - res = SHA3_process(&self->hash_state, buf.buf, buf.len * 8); -#endif - LEAVE_HASHLIB(self); - - if (res != SUCCESS) { - PyBuffer_Release(&buf); - PyErr_SetString(PyExc_RuntimeError, - "internal error in SHA3 Update()"); - return NULL; - } - - PyBuffer_Release(&buf); - Py_INCREF(Py_None); - return Py_None; -} - -static PyMethodDef SHA3_methods[] = { - {"copy", (PyCFunction)SHA3_copy, METH_NOARGS, - SHA3_copy__doc__}, - {"digest", (PyCFunction)SHA3_digest, METH_NOARGS, - SHA3_digest__doc__}, - {"hexdigest", (PyCFunction)SHA3_hexdigest, METH_NOARGS, - SHA3_hexdigest__doc__}, - {"update", (PyCFunction)SHA3_update, METH_VARARGS, - SHA3_update__doc__}, - {NULL, NULL} /* sentinel */ -}; - -static PyObject * -SHA3_get_block_size(SHA3object *self, void *closure) -{ - /* HMAC-SHA3 hasn't been specified yet and no official test vectors are - * available. Thus block_size returns NotImplemented to prevent people - * from using SHA3 with the hmac module. - */ - Py_RETURN_NOTIMPLEMENTED; -} - -static PyObject * -SHA3_get_name(SHA3object *self, void *closure) -{ - return PyUnicode_FromFormat("sha3_%i", self->hashbitlen); -} - -static PyObject * -SHA3_get_digest_size(SHA3object *self, void *closure) -{ - return PyLong_FromLong(self->hashbitlen / 8); -} - - -static PyGetSetDef SHA3_getseters[] = { - {"block_size", (getter)SHA3_get_block_size, NULL, NULL, NULL}, - {"name", (getter)SHA3_get_name, NULL, NULL, NULL}, - {"digest_size", (getter)SHA3_get_digest_size, NULL, NULL, NULL}, - {NULL} /* Sentinel */ -}; - -static PyTypeObject SHA3type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_sha3.SHA3", /* tp_name */ - sizeof(SHA3object), /* tp_size */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)SHA3_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - SHA3_methods, /* tp_methods */ - NULL, /* tp_members */ - SHA3_getseters, /* tp_getset */ -}; - - -/* constructor helper */ -static PyObject * -SHA3_factory(PyObject *args, PyObject *kwdict, const char *fmt, - int hashbitlen) -{ - SHA3object *newobj = NULL; - static char *kwlist[] = {"string", NULL}; - PyObject *data_obj = NULL; - Py_buffer buf; - HashReturn res; - - if (!PyArg_ParseTupleAndKeywords(args, kwdict, fmt, kwlist, - &data_obj)) { - return NULL; - } - - if (data_obj) - GET_BUFFER_VIEW_OR_ERROUT(data_obj, &buf); - - if ((newobj = newSHA3object(hashbitlen)) == NULL) { - goto error; - } - - if (SHA3_init(&newobj->hash_state, hashbitlen) != SUCCESS) { - PyErr_SetString(PyExc_RuntimeError, - "internal error in SHA3 Update()"); - goto error; - } - - if (data_obj) { -#ifdef WITH_THREAD - if (buf.len >= HASHLIB_GIL_MINSIZE) { - /* invariant: New objects can't be accessed by other code yet, - * thus it's safe to release the GIL without locking the object. - */ - Py_BEGIN_ALLOW_THREADS - res = SHA3_process(&newobj->hash_state, buf.buf, buf.len * 8); - Py_END_ALLOW_THREADS - } - else { - res = SHA3_process(&newobj->hash_state, buf.buf, buf.len * 8); - } -#else - res = SHA3_process(&newobj->hash_state, buf.buf, buf.len * 8); -#endif - if (res != SUCCESS) { - PyErr_SetString(PyExc_RuntimeError, - "internal error in SHA3 Update()"); - goto error; - } - PyBuffer_Release(&buf); - } - - return (PyObject *)newobj; - - error: - if (newobj) { - SHA3_dealloc(newobj); - } - if (data_obj) { - PyBuffer_Release(&buf); - } - return NULL; - -} - -PyDoc_STRVAR(sha3_224__doc__, -"sha3_224([string]) -> SHA3 object\n\ -\n\ -Return a new SHA3 hash object with a hashbit length of 28 bytes."); - -static PyObject * -sha3_224(PyObject *self, PyObject *args, PyObject *kwdict) -{ - return SHA3_factory(args, kwdict, "|O:sha3_224", 224); -} - - -PyDoc_STRVAR(sha3_256__doc__, -"sha3_256([string]) -> SHA3 object\n\ -\n\ -Return a new SHA3 hash object with a hashbit length of 32 bytes."); - -static PyObject * -sha3_256(PyObject *self, PyObject *args, PyObject *kwdict) -{ - return SHA3_factory(args, kwdict, "|O:sha3_256", 256); -} - -PyDoc_STRVAR(sha3_384__doc__, -"sha3_384([string]) -> SHA3 object\n\ -\n\ -Return a new SHA3 hash object with a hashbit length of 48 bytes."); - -static PyObject * -sha3_384(PyObject *self, PyObject *args, PyObject *kwdict) -{ - return SHA3_factory(args, kwdict, "|O:sha3_384", 384); -} - -PyDoc_STRVAR(sha3_512__doc__, -"sha3_512([string]) -> SHA3 object\n\ -\n\ -Return a new SHA3 hash object with a hashbit length of 64 bytes."); - -static PyObject * -sha3_512(PyObject *self, PyObject *args, PyObject *kwdict) -{ - return SHA3_factory(args, kwdict, "|O:sha3_512", 512); -} - - -/* List of functions exported by this module */ -static struct PyMethodDef SHA3_functions[] = { - {"sha3_224", (PyCFunction)sha3_224, METH_VARARGS|METH_KEYWORDS, - sha3_224__doc__}, - {"sha3_256", (PyCFunction)sha3_256, METH_VARARGS|METH_KEYWORDS, - sha3_256__doc__}, - {"sha3_384", (PyCFunction)sha3_384, METH_VARARGS|METH_KEYWORDS, - sha3_384__doc__}, - {"sha3_512", (PyCFunction)sha3_512, METH_VARARGS|METH_KEYWORDS, - sha3_512__doc__}, - {NULL, NULL} /* Sentinel */ -}; - - -/* Initialize this module. */ -static struct PyModuleDef _SHA3module = { - PyModuleDef_HEAD_INIT, - "_sha3", - NULL, - -1, - SHA3_functions, - NULL, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC -PyInit__sha3(void) -{ - PyObject *m; - - Py_TYPE(&SHA3type) = &PyType_Type; - if (PyType_Ready(&SHA3type) < 0) { - return NULL; - } - - m = PyModule_Create(&_SHA3module); - if (m == NULL) - return NULL; - - Py_INCREF((PyObject *)&SHA3type); - PyModule_AddObject(m, "SHA3Type", (PyObject *)&SHA3type); - return m; -} diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 50c6f0a8d597..2e8cab5554be 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -128,7 +128,10 @@ int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject Py_INCREF(isolation_level); } self->isolation_level = NULL; - pysqlite_connection_set_isolation_level(self, isolation_level); + if (pysqlite_connection_set_isolation_level(self, isolation_level) < 0) { + Py_DECREF(isolation_level); + return -1; + } Py_DECREF(isolation_level); self->statement_cache = (pysqlite_Cache*)PyObject_CallFunction((PyObject*)&pysqlite_CacheType, "Oi", self, cached_statements); @@ -519,19 +522,20 @@ _pysqlite_set_result(sqlite3_context* context, PyObject* py_val) return -1; sqlite3_result_text(context, str, -1, SQLITE_TRANSIENT); } else if (PyObject_CheckBuffer(py_val)) { - const char* buffer; - Py_ssize_t buflen; - if (PyObject_AsCharBuffer(py_val, &buffer, &buflen) != 0) { + Py_buffer view; + if (PyObject_GetBuffer(py_val, &view, PyBUF_SIMPLE) != 0) { PyErr_SetString(PyExc_ValueError, "could not convert BLOB to buffer"); return -1; } - if (buflen > INT_MAX) { + if (view.len > INT_MAX) { PyErr_SetString(PyExc_OverflowError, "BLOB longer than INT_MAX bytes"); + PyBuffer_Release(&view); return -1; } - sqlite3_result_blob(context, buffer, (int)buflen, SQLITE_TRANSIENT); + sqlite3_result_blob(context, view.buf, (int)view.len, SQLITE_TRANSIENT); + PyBuffer_Release(&view); } else { return -1; } @@ -1258,7 +1262,8 @@ PyObject* pysqlite_connection_call(pysqlite_Connection* self, PyObject* args, Py if (rc == PYSQLITE_TOO_MUCH_SQL) { PyErr_SetString(pysqlite_Warning, "You can only execute one statement at a time."); } else if (rc == PYSQLITE_SQL_WRONG_TYPE) { - PyErr_SetString(pysqlite_Warning, "SQL is of wrong type. Must be string or unicode."); + if (PyErr_ExceptionMatches(PyExc_TypeError)) + PyErr_SetString(pysqlite_Warning, "SQL is of wrong type. Must be string."); } else { (void)pysqlite_statement_reset(statement); _pysqlite_seterror(self->db, NULL); diff --git a/Modules/_sqlite/connection.h b/Modules/_sqlite/connection.h index 0c9734caf710..fbd906377952 100644 --- a/Modules/_sqlite/connection.h +++ b/Modules/_sqlite/connection.h @@ -52,7 +52,7 @@ typedef struct * first get called with count=0? */ double timeout_started; - /* None for autocommit, otherwise a PyString with the isolation level */ + /* None for autocommit, otherwise a PyUnicode with the isolation level */ PyObject* isolation_level; /* NULL for autocommit, otherwise a string with the BEGIN statement; will be diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index 8d10890eb022..7fe00e32d2fa 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -46,7 +46,7 @@ static pysqlite_StatementKind detect_statement_type(const char* statement) dst = buf; *dst = 0; - while (Py_ISALPHA(*src) && dst - buf < sizeof(buf) - 2) { + while (Py_ISALPHA(*src) && (dst - buf) < ((Py_ssize_t)sizeof(buf) - 2)) { *dst++ = Py_TOLOWER(*src++); } @@ -229,8 +229,7 @@ int pysqlite_build_row_cast_map(pysqlite_Cursor* self) if (converter != Py_None) { Py_DECREF(converter); } - Py_XDECREF(self->row_cast_map); - self->row_cast_map = NULL; + Py_CLEAR(self->row_cast_map); return -1; } @@ -290,9 +289,8 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self) Py_END_ALLOW_THREADS row = PyTuple_New(numcols); - if (!row) { + if (!row) return NULL; - } for (i = 0; i < numcols; i++) { if (self->connection->detect_types) { @@ -312,14 +310,12 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self) converted = Py_None; } else { item = PyBytes_FromStringAndSize(val_str, nbytes); - if (!item) { - return NULL; - } + if (!item) + goto error; converted = PyObject_CallFunction(converter, "O", item); Py_DECREF(item); - if (!converted) { + if (!converted) break; - } } } else { Py_BEGIN_ALLOW_THREADS @@ -375,9 +371,8 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self) nbytes = sqlite3_column_bytes(self->statement->st, i); buffer = PyBytes_FromStringAndSize( sqlite3_column_blob(self->statement->st, i), nbytes); - if (!buffer) { + if (!buffer) break; - } converted = buffer; } } @@ -390,12 +385,14 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self) } } - if (PyErr_Occurred()) { - Py_DECREF(row); - row = NULL; - } + if (PyErr_Occurred()) + goto error; return row; + +error: + Py_DECREF(row); + return NULL; } /* @@ -447,8 +444,7 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* self->locked = 1; self->reset = 0; - Py_XDECREF(self->next_row); - self->next_row = NULL; + Py_CLEAR(self->next_row); if (multiple) { /* executemany() */ @@ -614,6 +610,10 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* while (1) { /* Actually execute the SQL statement. */ rc = pysqlite_step(self->statement->st, self->connection); + if (PyErr_Occurred()) { + (void)pysqlite_statement_reset(self->statement); + goto error; + } if (rc == SQLITE_DONE || rc == SQLITE_ROW) { /* If it worked, let's get out of the loop */ break; @@ -687,6 +687,8 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* } self->next_row = _pysqlite_fetch_one_row(self); + if (self->next_row == NULL) + goto error; } else if (rc == SQLITE_DONE && !multiple) { pysqlite_statement_reset(self->statement); Py_CLEAR(self->statement); @@ -809,7 +811,10 @@ PyObject* pysqlite_cursor_executescript(pysqlite_Cursor* self, PyObject* args) rc = SQLITE_ROW; while (rc == SQLITE_ROW) { rc = pysqlite_step(statement, self->connection); - /* TODO: we probably need more error handling here */ + if (PyErr_Occurred()) { + (void)sqlite3_finalize(statement); + goto error; + } } if (rc != SQLITE_DONE) { @@ -864,8 +869,7 @@ PyObject* pysqlite_cursor_iternext(pysqlite_Cursor *self) if (!self->next_row) { if (self->statement) { (void)pysqlite_statement_reset(self->statement); - Py_DECREF(self->statement); - self->statement = NULL; + Py_CLEAR(self->statement); } return NULL; } @@ -887,6 +891,11 @@ PyObject* pysqlite_cursor_iternext(pysqlite_Cursor *self) if (self->statement) { rc = pysqlite_step(self->statement->st, self->connection); + if (PyErr_Occurred()) { + (void)pysqlite_statement_reset(self->statement); + Py_DECREF(next_row); + return NULL; + } if (rc != SQLITE_DONE && rc != SQLITE_ROW) { (void)pysqlite_statement_reset(self->statement); Py_DECREF(next_row); @@ -898,8 +907,6 @@ PyObject* pysqlite_cursor_iternext(pysqlite_Cursor *self) self->next_row = _pysqlite_fetch_one_row(self); if (self->next_row == NULL) { (void)pysqlite_statement_reset(self->statement); - Py_DECREF(next_row); - _pysqlite_seterror(self->connection->db, NULL); return NULL; } } diff --git a/Modules/_sqlite/row.c b/Modules/_sqlite/row.c index 4a87a048fd2b..ed8ad47ffc72 100644 --- a/Modules/_sqlite/row.c +++ b/Modules/_sqlite/row.c @@ -32,40 +32,53 @@ void pysqlite_row_dealloc(pysqlite_Row* self) Py_TYPE(self)->tp_free((PyObject*)self); } -int pysqlite_row_init(pysqlite_Row* self, PyObject* args, PyObject* kwargs) +static PyObject * +pysqlite_row_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { + pysqlite_Row *self; PyObject* data; pysqlite_Cursor* cursor; - self->data = 0; - self->description = 0; + assert(type != NULL && type->tp_alloc != NULL); - if (!PyArg_ParseTuple(args, "OO", &cursor, &data)) { - return -1; - } + if (!_PyArg_NoKeywords("Row()", kwargs)) + return NULL; + if (!PyArg_ParseTuple(args, "OO", &cursor, &data)) + return NULL; if (!PyObject_IsInstance((PyObject*)cursor, (PyObject*)&pysqlite_CursorType)) { PyErr_SetString(PyExc_TypeError, "instance of cursor required for first argument"); - return -1; + return NULL; } if (!PyTuple_Check(data)) { PyErr_SetString(PyExc_TypeError, "tuple required for second argument"); - return -1; + return NULL; } + self = (pysqlite_Row *) type->tp_alloc(type, 0); + if (self == NULL) + return NULL; + Py_INCREF(data); self->data = data; Py_INCREF(cursor->description); self->description = cursor->description; - return 0; + return (PyObject *) self; +} + +PyObject* pysqlite_row_item(pysqlite_Row* self, Py_ssize_t idx) +{ + PyObject* item = PyTuple_GetItem(self->data, idx); + Py_XINCREF(item); + return item; } PyObject* pysqlite_row_subscript(pysqlite_Row* self, PyObject* idx) { - long _idx; + Py_ssize_t _idx; char* key; Py_ssize_t nitems, i; char* compare_key; @@ -76,7 +89,11 @@ PyObject* pysqlite_row_subscript(pysqlite_Row* self, PyObject* idx) PyObject* item; if (PyLong_Check(idx)) { - _idx = PyLong_AsLong(idx); + _idx = PyNumber_AsSsize_t(idx, PyExc_IndexError); + if (_idx == -1 && PyErr_Occurred()) + return NULL; + if (_idx < 0) + _idx += PyTuple_GET_SIZE(self->data); item = PyTuple_GetItem(self->data, _idx); Py_XINCREF(item); return item; @@ -142,7 +159,7 @@ Py_ssize_t pysqlite_row_length(pysqlite_Row* self, PyObject* args, PyObject* kwa PyObject* pysqlite_row_keys(pysqlite_Row* self, PyObject* args, PyObject* kwargs) { PyObject* list; - int nitems, i; + Py_ssize_t nitems, i; list = PyList_New(0); if (!list) { @@ -198,6 +215,14 @@ PyMappingMethods pysqlite_row_as_mapping = { /* mp_ass_subscript */ (objobjargproc)0, }; +static PySequenceMethods pysqlite_row_as_sequence = { + /* sq_length */ (lenfunc)pysqlite_row_length, + /* sq_concat */ 0, + /* sq_repeat */ 0, + /* sq_item */ (ssizeargfunc)pysqlite_row_item, +}; + + static PyMethodDef pysqlite_row_methods[] = { {"keys", (PyCFunction)pysqlite_row_keys, METH_NOARGS, PyDoc_STR("Returns the keys of the row.")}, @@ -241,7 +266,7 @@ PyTypeObject pysqlite_RowType = { 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ - (initproc)pysqlite_row_init, /* tp_init */ + 0, /* tp_init */ 0, /* tp_alloc */ 0, /* tp_new */ 0 /* tp_free */ @@ -249,7 +274,8 @@ PyTypeObject pysqlite_RowType = { extern int pysqlite_row_setup_types(void) { - pysqlite_RowType.tp_new = PyType_GenericNew; + pysqlite_RowType.tp_new = pysqlite_row_new; pysqlite_RowType.tp_as_mapping = &pysqlite_row_as_mapping; + pysqlite_RowType.tp_as_sequence = &pysqlite_row_as_sequence; return PyType_Ready(&pysqlite_RowType); } diff --git a/Modules/_sqlite/statement.c b/Modules/_sqlite/statement.c index 66b4a5256524..e87063341db6 100644 --- a/Modules/_sqlite/statement.c +++ b/Modules/_sqlite/statement.c @@ -63,6 +63,10 @@ int pysqlite_statement_create(pysqlite_Statement* self, pysqlite_Connection* con rc = PYSQLITE_SQL_WRONG_TYPE; return rc; } + if (strlen(sql_cstr) != (size_t)sql_cstr_len) { + PyErr_SetString(PyExc_ValueError, "the query contains a null character"); + return PYSQLITE_SQL_WRONG_TYPE; + } self->in_weakreflist = NULL; Py_INCREF(sql); @@ -90,7 +94,6 @@ int pysqlite_statement_create(pysqlite_Statement* self, pysqlite_Connection* con int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObject* parameter) { int rc = SQLITE_OK; - const char* buffer; char* string; Py_ssize_t buflen; parameter_type paramtype; @@ -141,18 +144,22 @@ int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObjec } rc = sqlite3_bind_text(self->st, pos, string, (int)buflen, SQLITE_TRANSIENT); break; - case TYPE_BUFFER: - if (PyObject_AsCharBuffer(parameter, &buffer, &buflen) != 0) { + case TYPE_BUFFER: { + Py_buffer view; + if (PyObject_GetBuffer(parameter, &view, PyBUF_SIMPLE) != 0) { PyErr_SetString(PyExc_ValueError, "could not convert BLOB to buffer"); return -1; } - if (buflen > INT_MAX) { + if (view.len > INT_MAX) { PyErr_SetString(PyExc_OverflowError, "BLOB longer than INT_MAX bytes"); + PyBuffer_Release(&view); return -1; } - rc = sqlite3_bind_blob(self->st, pos, buffer, buflen, SQLITE_TRANSIENT); + rc = sqlite3_bind_blob(self->st, pos, view.buf, (int)view.len, SQLITE_TRANSIENT); + PyBuffer_Release(&view); break; + } case TYPE_UNKNOWN: rc = -1; } diff --git a/Modules/_sre.c b/Modules/_sre.c index 55a86c290181..9550d97c1bd3 100644 --- a/Modules/_sre.c +++ b/Modules/_sre.c @@ -97,48 +97,25 @@ static char copyright[] = /* -------------------------------------------------------------------- */ /* search engine state */ -/* default character predicates (run sre_chars.py to regenerate tables) */ - -#define SRE_DIGIT_MASK 1 -#define SRE_SPACE_MASK 2 -#define SRE_LINEBREAK_MASK 4 -#define SRE_ALNUM_MASK 8 -#define SRE_WORD_MASK 16 - -/* FIXME: this assumes ASCII. create tables in init_sre() instead */ - -static char sre_char_info[128] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6, 2, -2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25, 25, 25, 25, 25, 25, -25, 25, 0, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, -0, 0, 16, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, 0 }; - -static char sre_char_lower[128] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, -27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, -44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, -61, 62, 63, 64, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, -108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, -122, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, -106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, -120, 121, 122, 123, 124, 125, 126, 127 }; - #define SRE_IS_DIGIT(ch)\ - ((ch) < 128 ? (sre_char_info[(ch)] & SRE_DIGIT_MASK) : 0) + ((ch) < 128 && Py_ISDIGIT(ch)) #define SRE_IS_SPACE(ch)\ - ((ch) < 128 ? (sre_char_info[(ch)] & SRE_SPACE_MASK) : 0) + ((ch) < 128 && Py_ISSPACE(ch)) #define SRE_IS_LINEBREAK(ch)\ - ((ch) < 128 ? (sre_char_info[(ch)] & SRE_LINEBREAK_MASK) : 0) + ((ch) == '\n') #define SRE_IS_ALNUM(ch)\ - ((ch) < 128 ? (sre_char_info[(ch)] & SRE_ALNUM_MASK) : 0) + ((ch) < 128 && Py_ISALNUM(ch)) #define SRE_IS_WORD(ch)\ - ((ch) < 128 ? (sre_char_info[(ch)] & SRE_WORD_MASK) : 0) + ((ch) < 128 && (Py_ISALNUM(ch) || (ch) == '_')) static unsigned int sre_lower(unsigned int ch) { - return ((ch) < 128 ? (unsigned int)sre_char_lower[ch] : ch); + return ((ch) < 128 ? Py_TOLOWER(ch) : ch); +} + +static unsigned int sre_upper(unsigned int ch) +{ + return ((ch) < 128 ? Py_TOUPPER(ch) : ch); } /* locale-specific character predicates */ @@ -152,6 +129,11 @@ static unsigned int sre_lower_locale(unsigned int ch) return ((ch) < 256 ? (unsigned int)tolower((ch)) : ch); } +static unsigned int sre_upper_locale(unsigned int ch) +{ + return ((ch) < 256 ? (unsigned int)toupper((ch)) : ch); +} + /* unicode-specific character predicates */ #define SRE_UNI_IS_DIGIT(ch) Py_UNICODE_ISDECIMAL(ch) @@ -165,6 +147,11 @@ static unsigned int sre_lower_unicode(unsigned int ch) return (unsigned int) Py_UNICODE_TOLOWER(ch); } +static unsigned int sre_upper_unicode(unsigned int ch) +{ + return (unsigned int) Py_UNICODE_TOUPPER(ch); +} + LOCAL(int) sre_category(SRE_CODE category, unsigned int ch) { @@ -357,6 +344,11 @@ state_init(SRE_STATE* state, PatternObject* pattern, PyObject* string, memset(state, 0, sizeof(SRE_STATE)); + state->mark = PyMem_New(void *, pattern->groups * 2); + if (!state->mark) { + PyErr_NoMemory(); + goto err; + } state->lastmark = -1; state->lastindex = -1; @@ -400,15 +392,23 @@ state_init(SRE_STATE* state, PatternObject* pattern, PyObject* string, state->pos = start; state->endpos = end; - if (pattern->flags & SRE_FLAG_LOCALE) + if (pattern->flags & SRE_FLAG_LOCALE) { state->lower = sre_lower_locale; - else if (pattern->flags & SRE_FLAG_UNICODE) + state->upper = sre_upper_locale; + } + else if (pattern->flags & SRE_FLAG_UNICODE) { state->lower = sre_lower_unicode; - else + state->upper = sre_upper_unicode; + } + else { state->lower = sre_lower; + state->upper = sre_upper; + } return string; err: + PyMem_Del(state->mark); + state->mark = NULL; if (state->buffer.buf) PyBuffer_Release(&state->buffer); return NULL; @@ -421,6 +421,8 @@ state_fini(SRE_STATE* state) PyBuffer_Release(&state->buffer); Py_XDECREF(state->string); data_stack_dealloc(state); + PyMem_Del(state->mark); + state->mark = NULL; } /* calculate offset from start of string */ @@ -505,14 +507,14 @@ pattern_dealloc(PatternObject* self) } LOCAL(Py_ssize_t) -sre_match(SRE_STATE* state, SRE_CODE* pattern) +sre_match(SRE_STATE* state, SRE_CODE* pattern, int match_all) { if (state->charsize == 1) - return sre_ucs1_match(state, pattern); + return sre_ucs1_match(state, pattern, match_all); if (state->charsize == 2) - return sre_ucs2_match(state, pattern); + return sre_ucs2_match(state, pattern, match_all); assert(state->charsize == 4); - return sre_ucs4_match(state, pattern); + return sre_ucs4_match(state, pattern, match_all); } LOCAL(Py_ssize_t) @@ -526,21 +528,50 @@ sre_search(SRE_STATE* state, SRE_CODE* pattern) return sre_ucs4_search(state, pattern); } -static PyObject* -pattern_match(PatternObject* self, PyObject* args, PyObject* kw) +static PyObject * +fix_string_param(PyObject *string, PyObject *string2, const char *oldname) { + if (string2 != NULL) { + if (string != NULL) { + PyErr_Format(PyExc_TypeError, + "Argument given by name ('%s') and position (1)", + oldname); + return NULL; + } + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "The '%s' keyword parameter name is deprecated. " + "Use 'string' instead.", oldname) < 0) + return NULL; + return string2; + } + if (string == NULL) { + PyErr_SetString(PyExc_TypeError, + "Required argument 'string' (pos 1) not found"); + return NULL; + } + return string; +} + +static PyObject * +pattern_match(PatternObject *self, PyObject *args, PyObject *kwargs) +{ + static char *_keywords[] = {"string", "pos", "endpos", "pattern", NULL}; + PyObject *string = NULL; + Py_ssize_t pos = 0; + Py_ssize_t endpos = PY_SSIZE_T_MAX; + PyObject *pattern = NULL; SRE_STATE state; Py_ssize_t status; + PyObject *match; - PyObject* string; - Py_ssize_t start = 0; - Py_ssize_t end = PY_SSIZE_T_MAX; - static char* kwlist[] = { "pattern", "pos", "endpos", NULL }; - if (!PyArg_ParseTupleAndKeywords(args, kw, "O|nn:match", kwlist, - &string, &start, &end)) + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "|Onn$O:match", _keywords, + &string, &pos, &endpos, &pattern)) return NULL; - - string = state_init(&state, self, string, start, end); + string = fix_string_param(string, pattern, "pattern"); + if (!string) + return NULL; + string = state_init(&state, (PatternObject *)self, string, pos, endpos); if (!string) return NULL; @@ -548,15 +579,17 @@ pattern_match(PatternObject* self, PyObject* args, PyObject* kw) TRACE(("|%p|%p|MATCH\n", PatternObject_GetCode(self), state.ptr)); - status = sre_match(&state, PatternObject_GetCode(self)); + status = sre_match(&state, PatternObject_GetCode(self), 0); TRACE(("|%p|%p|END\n", PatternObject_GetCode(self), state.ptr)); - if (PyErr_Occurred()) + if (PyErr_Occurred()) { + state_fini(&state); return NULL; + } + match = pattern_new_match(self, &state, status); state_fini(&state); - - return pattern_new_match(self, &state, status); + return match; } static PyObject* @@ -564,33 +597,39 @@ pattern_fullmatch(PatternObject* self, PyObject* args, PyObject* kw) { SRE_STATE state; Py_ssize_t status; + PyObject *match; - PyObject* string; + PyObject *string = NULL, *string2 = NULL; Py_ssize_t start = 0; Py_ssize_t end = PY_SSIZE_T_MAX; - static char* kwlist[] = { "pattern", "pos", "endpos", NULL }; - if (!PyArg_ParseTupleAndKeywords(args, kw, "O|nn:fullmatch", kwlist, - &string, &start, &end)) + static char* kwlist[] = { "string", "pos", "endpos", "pattern", NULL }; + if (!PyArg_ParseTupleAndKeywords(args, kw, "|Onn$O:fullmatch", kwlist, + &string, &start, &end, &string2)) + return NULL; + + string = fix_string_param(string, string2, "pattern"); + if (!string) return NULL; string = state_init(&state, self, string, start, end); if (!string) return NULL; - state.match_all = 1; state.ptr = state.start; TRACE(("|%p|%p|FULLMATCH\n", PatternObject_GetCode(self), state.ptr)); - status = sre_match(&state, PatternObject_GetCode(self)); + status = sre_match(&state, PatternObject_GetCode(self), 1); TRACE(("|%p|%p|END\n", PatternObject_GetCode(self), state.ptr)); - if (PyErr_Occurred()) + if (PyErr_Occurred()) { + state_fini(&state); return NULL; + } + match = pattern_new_match(self, &state, status); state_fini(&state); - - return pattern_new_match(self, &state, status); + return match; } static PyObject* @@ -598,13 +637,18 @@ pattern_search(PatternObject* self, PyObject* args, PyObject* kw) { SRE_STATE state; Py_ssize_t status; + PyObject *match; - PyObject* string; + PyObject *string = NULL, *string2 = NULL; Py_ssize_t start = 0; Py_ssize_t end = PY_SSIZE_T_MAX; - static char* kwlist[] = { "pattern", "pos", "endpos", NULL }; - if (!PyArg_ParseTupleAndKeywords(args, kw, "O|nn:search", kwlist, - &string, &start, &end)) + static char* kwlist[] = { "string", "pos", "endpos", "pattern", NULL }; + if (!PyArg_ParseTupleAndKeywords(args, kw, "|Onn$O:search", kwlist, + &string, &start, &end, &string2)) + return NULL; + + string = fix_string_param(string, string2, "pattern"); + if (!string) return NULL; string = state_init(&state, self, string, start, end); @@ -617,12 +661,14 @@ pattern_search(PatternObject* self, PyObject* args, PyObject* kw) TRACE(("|%p|%p|END\n", PatternObject_GetCode(self), state.ptr)); - state_fini(&state); - - if (PyErr_Occurred()) + if (PyErr_Occurred()) { + state_fini(&state); return NULL; + } - return pattern_new_match(self, &state, status); + match = pattern_new_match(self, &state, status); + state_fini(&state); + return match; } static PyObject* @@ -680,12 +726,16 @@ pattern_findall(PatternObject* self, PyObject* args, PyObject* kw) Py_ssize_t status; Py_ssize_t i, b, e; - PyObject* string; + PyObject *string = NULL, *string2 = NULL; Py_ssize_t start = 0; Py_ssize_t end = PY_SSIZE_T_MAX; - static char* kwlist[] = { "source", "pos", "endpos", NULL }; - if (!PyArg_ParseTupleAndKeywords(args, kw, "O|nn:findall", kwlist, - &string, &start, &end)) + static char* kwlist[] = { "string", "pos", "endpos", "source", NULL }; + if (!PyArg_ParseTupleAndKeywords(args, kw, "|Onn$O:findall", kwlist, + &string, &start, &end, &string2)) + return NULL; + + string = fix_string_param(string, string2, "source"); + if (!string) return NULL; string = state_init(&state, self, string, start, end); @@ -802,13 +852,30 @@ pattern_split(PatternObject* self, PyObject* args, PyObject* kw) Py_ssize_t i; void* last; - PyObject* string; + PyObject *string = NULL, *string2 = NULL; Py_ssize_t maxsplit = 0; - static char* kwlist[] = { "source", "maxsplit", NULL }; - if (!PyArg_ParseTupleAndKeywords(args, kw, "O|n:split", kwlist, - &string, &maxsplit)) + static char* kwlist[] = { "string", "maxsplit", "source", NULL }; + if (!PyArg_ParseTupleAndKeywords(args, kw, "|On$O:split", kwlist, + &string, &maxsplit, &string2)) return NULL; + string = fix_string_param(string, string2, "source"); + if (!string) + return NULL; + + assert(self->codesize != 0); + if (self->code[0] != SRE_OP_INFO || self->code[3] == 0) { + if (self->code[0] == SRE_OP_INFO && self->code[4] == 0) { + PyErr_SetString(PyExc_ValueError, + "split() requires a non-empty pattern match."); + return NULL; + } + if (PyErr_WarnEx(PyExc_FutureWarning, + "split() requires a non-empty pattern match.", + 1) < 0) + return NULL; + } + string = state_init(&state, self, string, 0, PY_SSIZE_T_MAX); if (!string) return NULL; @@ -1193,7 +1260,7 @@ pattern_repr(PatternObject *obj) }; PyObject *result = NULL; PyObject *flag_items; - int i; + size_t i; int flags = obj->flags; /* Omit re.UNICODE for valid string patterns. */ @@ -1374,7 +1441,7 @@ _compile(PyObject* self_, PyObject* args) PyObject* groupindex = NULL; PyObject* indexgroup = NULL; - if (!PyArg_ParseTuple(args, "OiO!|nOO", &pattern, &flags, + if (!PyArg_ParseTuple(args, "OiO!nOO", &pattern, &flags, &PyList_Type, &code, &groups, &groupindex, &indexgroup)) return NULL; @@ -1534,6 +1601,7 @@ _validate_charset(SRE_CODE *code, SRE_CODE *end) break; case SRE_OP_RANGE: + case SRE_OP_RANGE_IGNORE: GET_ARG; GET_ARG; break; @@ -1890,10 +1958,9 @@ _validate_inner(SRE_CODE *code, SRE_CODE *end, Py_ssize_t groups) static int _validate_outer(SRE_CODE *code, SRE_CODE *end, Py_ssize_t groups) { - if (groups < 0 || groups > 100 || code >= end || end[-1] != SRE_OP_SUCCESS) + if (groups < 0 || (size_t)groups > SRE_MAXGROUPS || + code >= end || end[-1] != SRE_OP_SUCCESS) FAIL; - if (groups == 0) /* fix for simplejson */ - groups = 100; /* 100 groups should always be safe */ return _validate_inner(code, end-1, groups); } @@ -2528,7 +2595,7 @@ scanner_match(ScannerObject* self, PyObject *unused) state->ptr = state->start; - status = sre_match(state, PatternObject_GetCode(self->pattern)); + status = sre_match(state, PatternObject_GetCode(self->pattern), 0); if (PyErr_Occurred()) return NULL; @@ -2621,12 +2688,16 @@ pattern_scanner(PatternObject* pattern, PyObject* args, PyObject* kw) ScannerObject* self; - PyObject* string; + PyObject *string = NULL, *string2 = NULL; Py_ssize_t start = 0; Py_ssize_t end = PY_SSIZE_T_MAX; - static char* kwlist[] = { "source", "pos", "endpos", NULL }; - if (!PyArg_ParseTupleAndKeywords(args, kw, "O|nn:scanner", kwlist, - &string, &start, &end)) + static char* kwlist[] = { "string", "pos", "endpos", "source", NULL }; + if (!PyArg_ParseTupleAndKeywords(args, kw, "|Onn$O:scanner", kwlist, + &string, &start, &end, &string2)) + return NULL; + + string = fix_string_param(string, string2, "source"); + if (!string) return NULL; /* create scanner object */ @@ -2700,6 +2771,12 @@ PyMODINIT_FUNC PyInit__sre(void) Py_DECREF(x); } + x = PyLong_FromUnsignedLong(SRE_MAXGROUPS); + if (x) { + PyDict_SetItemString(d, "MAXGROUPS", x); + Py_DECREF(x); + } + x = PyUnicode_FromString(copyright); if (x) { PyDict_SetItemString(d, "copyright", x); diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 6b0d67a3a644..0e6abda97536 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -14,6 +14,8 @@ http://bugs.python.org/issue8108#msg102867 ? */ +#define PY_SSIZE_T_CLEAN + #include "Python.h" #ifdef WITH_THREAD @@ -62,6 +64,7 @@ static PySocketModule_APIObject PySocketModule; #include "openssl/ssl.h" #include "openssl/err.h" #include "openssl/rand.h" +#include "openssl/bio.h" /* SSL error object */ static PyObject *PySSLErrorObject; @@ -106,6 +109,11 @@ struct py_ssl_library_code { # define HAVE_SNI 0 #endif +/* ALPN added in OpenSSL 1.0.2 */ +#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined(OPENSSL_NO_TLSEXT) +# define HAVE_ALPN +#endif + enum py_ssl_error { /* these mirror ssl.h */ PY_SSL_ERROR_NONE, @@ -134,9 +142,7 @@ enum py_ssl_cert_requirements { }; enum py_ssl_version { -#ifndef OPENSSL_NO_SSL2 PY_SSL_VERSION_SSL2, -#endif PY_SSL_VERSION_SSL3=1, PY_SSL_VERSION_SSL23, #if HAVE_TLSv1_2 @@ -161,13 +167,6 @@ static unsigned int _ssl_locks_count = 0; #define X509_NAME_MAXLEN 256 -/* RAND_* APIs got added to OpenSSL in 0.9.5 */ -#if OPENSSL_VERSION_NUMBER >= 0x0090500fL -# define HAVE_OPENSSL_RAND 1 -#else -# undef HAVE_OPENSSL_RAND -#endif - /* SSL_CTX_clear_options() and SSL_clear_options() were first added in * OpenSSL 0.9.8m but do not appear in some 0.9.9-dev versions such the * 0.9.9 from "May 2008" that NetBSD 5.0 uses. */ @@ -181,36 +180,18 @@ static unsigned int _ssl_locks_count = 0; * older SSL, but let's be safe */ #define PySSL_CB_MAXLEN 128 -/* SSL_get_finished got added to OpenSSL in 0.9.5 */ -#if OPENSSL_VERSION_NUMBER >= 0x0090500fL -# define HAVE_OPENSSL_FINISHED 1 -#else -# define HAVE_OPENSSL_FINISHED 0 -#endif - -/* ECDH support got added to OpenSSL in 0.9.8 */ -#if OPENSSL_VERSION_NUMBER < 0x0090800fL && !defined(OPENSSL_NO_ECDH) -# define OPENSSL_NO_ECDH -#endif - -/* compression support got added to OpenSSL in 0.9.8 */ -#if OPENSSL_VERSION_NUMBER < 0x0090800fL && !defined(OPENSSL_NO_COMP) -# define OPENSSL_NO_COMP -#endif - -/* X509_VERIFY_PARAM got added to OpenSSL in 0.9.8 */ -#if OPENSSL_VERSION_NUMBER >= 0x0090800fL -# define HAVE_OPENSSL_VERIFY_PARAM -#endif - typedef struct { PyObject_HEAD SSL_CTX *ctx; #ifdef OPENSSL_NPN_NEGOTIATED - char *npn_protocols; + unsigned char *npn_protocols; int npn_protocols_len; #endif +#ifdef HAVE_ALPN + unsigned char *alpn_protocols; + int alpn_protocols_len; +#endif #ifndef OPENSSL_NO_TLSEXT PyObject *set_hostname; #endif @@ -226,10 +207,19 @@ typedef struct { char shutdown_seen_zero; char handshake_done; enum py_ssl_server_or_client socket_type; + PyObject *owner; /* Python level "owner" passed to servername callback */ + PyObject *server_hostname; } PySSLSocket; +typedef struct { + PyObject_HEAD + BIO *bio; + int eof_written; +} PySSLMemoryBIO; + static PyTypeObject PySSLContext_Type; static PyTypeObject PySSLSocket_Type; +static PyTypeObject PySSLMemoryBIO_Type; static PyObject *PySSL_SSLwrite(PySSLSocket *self, PyObject *args); static PyObject *PySSL_SSLread(PySSLSocket *self, PyObject *args); @@ -240,6 +230,7 @@ static PyObject *PySSL_cipher(PySSLSocket *self); #define PySSLContext_Check(v) (Py_TYPE(v) == &PySSLContext_Type) #define PySSLSocket_Check(v) (Py_TYPE(v) == &PySSLSocket_Type) +#define PySSLMemoryBIO_Check(v) (Py_TYPE(v) == &PySSLMemoryBIO_Type) typedef enum { SOCKET_IS_NONBLOCKING, @@ -251,11 +242,12 @@ typedef enum { } timeout_state; /* Wrap error strings with filename and line # */ -#define STRINGIFY1(x) #x -#define STRINGIFY2(x) STRINGIFY1(x) #define ERRSTR1(x,y,z) (x ":" y ": " z) -#define ERRSTR(x) ERRSTR1("_ssl.c", STRINGIFY2(__LINE__), x) +#define ERRSTR(x) ERRSTR1("_ssl.c", Py_STRINGIFY(__LINE__), x) +/* Get the socket from a PySSLSocket, if it has one */ +#define GET_SOCKET(obj) ((obj)->Socket ? \ + (PySocketSockObject *) PyWeakref_GetObject((obj)->Socket) : NULL) /* * SSL errors. @@ -419,13 +411,12 @@ PySSL_SetError(PySSLSocket *obj, int ret, char *filename, int lineno) case SSL_ERROR_SYSCALL: { if (e == 0) { - PySocketSockObject *s - = (PySocketSockObject *) PyWeakref_GetObject(obj->Socket); + PySocketSockObject *s = GET_SOCKET(obj); if (ret == 0 || (((PyObject *)s) == Py_None)) { p = PY_SSL_ERROR_EOF; type = PySSLEOFErrorObject; errstr = "EOF occurred in violation of protocol"; - } else if (ret == -1) { + } else if (s && ret == -1) { /* underlying BIO reported an I/O error */ Py_INCREF(s); ERR_clear_error(); @@ -479,10 +470,12 @@ _setSSLError (char *errstr, int errcode, char *filename, int lineno) { static PySSLSocket * newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock, enum py_ssl_server_or_client socket_type, - char *server_hostname) + char *server_hostname, + PySSLMemoryBIO *inbio, PySSLMemoryBIO *outbio) { PySSLSocket *self; SSL_CTX *ctx = sslctx->ctx; + PyObject *hostname; long mode; self = PyObject_New(PySSLSocket, &PySSLSocket_Type); @@ -495,6 +488,18 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock, self->ctx = sslctx; self->shutdown_seen_zero = 0; self->handshake_done = 0; + self->owner = NULL; + if (server_hostname != NULL) { + hostname = PyUnicode_Decode(server_hostname, strlen(server_hostname), + "idna", "strict"); + if (hostname == NULL) { + Py_DECREF(self); + return NULL; + } + self->server_hostname = hostname; + } else + self->server_hostname = NULL; + Py_INCREF(sslctx); /* Make sure the SSL error state is initialized */ @@ -504,8 +509,17 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock, PySSL_BEGIN_ALLOW_THREADS self->ssl = SSL_new(ctx); PySSL_END_ALLOW_THREADS - SSL_set_app_data(self->ssl,self); - SSL_set_fd(self->ssl, Py_SAFE_DOWNCAST(sock->sock_fd, SOCKET_T, int)); + SSL_set_app_data(self->ssl, self); + if (sock) { + SSL_set_fd(self->ssl, Py_SAFE_DOWNCAST(sock->sock_fd, SOCKET_T, int)); + } else { + /* BIOs are reference counted and SSL_set_bio borrows our reference. + * To prevent a double free in memory_bio_dealloc() we need to take an + * extra reference here. */ + CRYPTO_add(&inbio->bio->references, 1, CRYPTO_LOCK_BIO); + CRYPTO_add(&outbio->bio->references, 1, CRYPTO_LOCK_BIO); + SSL_set_bio(self->ssl, inbio->bio, outbio->bio); + } mode = SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER; #ifdef SSL_MODE_AUTO_RETRY mode |= SSL_MODE_AUTO_RETRY; @@ -520,7 +534,7 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock, /* If the socket is in non-blocking mode or timeout mode, set the BIO * to non-blocking mode (blocking is the default) */ - if (sock->sock_timeout >= 0.0) { + if (sock && sock->sock_timeout >= 0.0) { BIO_set_nbio(SSL_get_rbio(self->ssl), 1); BIO_set_nbio(SSL_get_wbio(self->ssl), 1); } @@ -533,10 +547,13 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock, PySSL_END_ALLOW_THREADS self->socket_type = socket_type; - self->Socket = PyWeakref_NewRef((PyObject *) sock, NULL); - if (self->Socket == NULL) { - Py_DECREF(self); - return NULL; + if (sock != NULL) { + self->Socket = PyWeakref_NewRef((PyObject *) sock, NULL); + if (self->Socket == NULL) { + Py_DECREF(self); + Py_XDECREF(self->server_hostname); + return NULL; + } } return self; } @@ -548,20 +565,21 @@ static PyObject *PySSL_SSLdo_handshake(PySSLSocket *self) int ret; int err; int sockstate, nonblocking; - PySocketSockObject *sock - = (PySocketSockObject *) PyWeakref_GetObject(self->Socket); + PySocketSockObject *sock = GET_SOCKET(self); - if (((PyObject*)sock) == Py_None) { - _setSSLError("Underlying socket connection gone", - PY_SSL_ERROR_NO_SOCKET, __FILE__, __LINE__); - return NULL; - } - Py_INCREF(sock); + if (sock) { + if (((PyObject*)sock) == Py_None) { + _setSSLError("Underlying socket connection gone", + PY_SSL_ERROR_NO_SOCKET, __FILE__, __LINE__); + return NULL; + } + Py_INCREF(sock); - /* just in case the blocking state of the socket has been changed */ - nonblocking = (sock->sock_timeout >= 0.0); - BIO_set_nbio(SSL_get_rbio(self->ssl), nonblocking); - BIO_set_nbio(SSL_get_wbio(self->ssl), nonblocking); + /* just in case the blocking state of the socket has been changed */ + nonblocking = (sock->sock_timeout >= 0.0); + BIO_set_nbio(SSL_get_rbio(self->ssl), nonblocking); + BIO_set_nbio(SSL_get_wbio(self->ssl), nonblocking); + } /* Actually negotiate SSL connection */ /* XXX If SSL_do_handshake() returns 0, it's also a failure. */ @@ -595,7 +613,7 @@ static PyObject *PySSL_SSLdo_handshake(PySSLSocket *self) break; } } while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE); - Py_DECREF(sock); + Py_XDECREF(sock); if (ret < 1) return PySSL_SetError(self, ret, __FILE__, __LINE__); @@ -610,7 +628,7 @@ static PyObject *PySSL_SSLdo_handshake(PySSLSocket *self) return Py_None; error: - Py_DECREF(sock); + Py_XDECREF(sock); return NULL; } @@ -779,12 +797,7 @@ _get_peer_alt_names (X509 *certificate) { char buf[2048]; char *vptr; int len; - /* Issue #2973: ASN1_item_d2i() API changed in OpenSSL 0.9.6m */ -#if OPENSSL_VERSION_NUMBER >= 0x009060dfL const unsigned char *p; -#else - unsigned char *p; -#endif if (certificate == NULL) return peer_alt_names; @@ -1356,54 +1369,96 @@ If the optional argument is True, returns a DER-encoded copy of the\n\ peer certificate, or None if no certificate was provided. This will\n\ return the certificate even if it wasn't validated."); -static PyObject *PySSL_cipher (PySSLSocket *self) { - - PyObject *retval, *v; - const SSL_CIPHER *current; - char *cipher_name; - char *cipher_protocol; - - if (self->ssl == NULL) - Py_RETURN_NONE; - current = SSL_get_current_cipher(self->ssl); - if (current == NULL) - Py_RETURN_NONE; - - retval = PyTuple_New(3); +static PyObject * +cipher_to_tuple(const SSL_CIPHER *cipher) +{ + const char *cipher_name, *cipher_protocol; + PyObject *v, *retval = PyTuple_New(3); if (retval == NULL) return NULL; - cipher_name = (char *) SSL_CIPHER_get_name(current); + cipher_name = SSL_CIPHER_get_name(cipher); if (cipher_name == NULL) { Py_INCREF(Py_None); PyTuple_SET_ITEM(retval, 0, Py_None); } else { v = PyUnicode_FromString(cipher_name); if (v == NULL) - goto fail0; + goto fail; PyTuple_SET_ITEM(retval, 0, v); } - cipher_protocol = SSL_CIPHER_get_version(current); + + cipher_protocol = SSL_CIPHER_get_version(cipher); if (cipher_protocol == NULL) { Py_INCREF(Py_None); PyTuple_SET_ITEM(retval, 1, Py_None); } else { v = PyUnicode_FromString(cipher_protocol); if (v == NULL) - goto fail0; + goto fail; PyTuple_SET_ITEM(retval, 1, v); } - v = PyLong_FromLong(SSL_CIPHER_get_bits(current, NULL)); + + v = PyLong_FromLong(SSL_CIPHER_get_bits(cipher, NULL)); if (v == NULL) - goto fail0; + goto fail; PyTuple_SET_ITEM(retval, 2, v); + return retval; - fail0: + fail: Py_DECREF(retval); return NULL; } +static PyObject *PySSL_shared_ciphers(PySSLSocket *self) +{ + SSL_SESSION *sess = SSL_get_session(self->ssl); + STACK_OF(SSL_CIPHER) *ciphers; + int i; + PyObject *res; + + if (!sess || !sess->ciphers) + Py_RETURN_NONE; + ciphers = sess->ciphers; + res = PyList_New(sk_SSL_CIPHER_num(ciphers)); + if (!res) + return NULL; + for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) { + PyObject *tup = cipher_to_tuple(sk_SSL_CIPHER_value(ciphers, i)); + if (!tup) { + Py_DECREF(res); + return NULL; + } + PyList_SET_ITEM(res, i, tup); + } + return res; +} + +static PyObject *PySSL_cipher (PySSLSocket *self) +{ + const SSL_CIPHER *current; + + if (self->ssl == NULL) + Py_RETURN_NONE; + current = SSL_get_current_cipher(self->ssl); + if (current == NULL) + Py_RETURN_NONE; + return cipher_to_tuple(current); +} + +static PyObject *PySSL_version(PySSLSocket *self) +{ + const char *version; + + if (self->ssl == NULL) + Py_RETURN_NONE; + version = SSL_get_version(self->ssl); + if (!strcmp(version, "unknown")) + Py_RETURN_NONE; + return PyUnicode_FromString(version); +} + #ifdef OPENSSL_NPN_NEGOTIATED static PyObject *PySSL_selected_npn_protocol(PySSLSocket *self) { const unsigned char *out; @@ -1414,7 +1469,20 @@ static PyObject *PySSL_selected_npn_protocol(PySSLSocket *self) { if (out == NULL) Py_RETURN_NONE; - return PyUnicode_FromStringAndSize((char *) out, outlen); + return PyUnicode_FromStringAndSize((char *)out, outlen); +} +#endif + +#ifdef HAVE_ALPN +static PyObject *PySSL_selected_alpn_protocol(PySSLSocket *self) { + const unsigned char *out; + unsigned int outlen; + + SSL_get0_alpn_selected(self->ssl, &out, &outlen); + + if (out == NULL) + Py_RETURN_NONE; + return PyUnicode_FromStringAndSize((char *)out, outlen); } #endif @@ -1473,6 +1541,54 @@ on the SSLContext to change the certificate information associated with the\n\ SSLSocket before the cryptographic exchange handshake messages\n"); +static PyObject * +PySSL_get_server_side(PySSLSocket *self, void *c) +{ + return PyBool_FromLong(self->socket_type == PY_SSL_SERVER); +} + +PyDoc_STRVAR(PySSL_get_server_side_doc, +"Whether this is a server-side socket."); + +static PyObject * +PySSL_get_server_hostname(PySSLSocket *self, void *c) +{ + if (self->server_hostname == NULL) + Py_RETURN_NONE; + Py_INCREF(self->server_hostname); + return self->server_hostname; +} + +PyDoc_STRVAR(PySSL_get_server_hostname_doc, +"The currently set server hostname (for SNI)."); + +static PyObject * +PySSL_get_owner(PySSLSocket *self, void *c) +{ + PyObject *owner; + + if (self->owner == NULL) + Py_RETURN_NONE; + + owner = PyWeakref_GetObject(self->owner); + Py_INCREF(owner); + return owner; +} + +static int +PySSL_set_owner(PySSLSocket *self, PyObject *value, void *c) +{ + Py_XDECREF(self->owner); + self->owner = PyWeakref_NewRef(value, NULL); + if (self->owner == NULL) + return -1; + return 0; +} + +PyDoc_STRVAR(PySSL_get_owner_doc, +"The Python-level owner of this object.\ +Passed as \"self\" in servername callback."); + static void PySSL_dealloc(PySSLSocket *self) { @@ -1482,6 +1598,8 @@ static void PySSL_dealloc(PySSLSocket *self) SSL_free(self->ssl); Py_XDECREF(self->Socket); Py_XDECREF(self->ctx); + Py_XDECREF(self->server_hostname); + Py_XDECREF(self->owner); PyObject_Del(self); } @@ -1498,10 +1616,10 @@ check_socket_and_wait_for_timeout(PySocketSockObject *s, int writing) int rc; /* Nothing to do unless we're in timeout mode (not non-blocking) */ - if (s->sock_timeout < 0.0) - return SOCKET_IS_BLOCKING; - else if (s->sock_timeout == 0.0) + if ((s == NULL) || (s->sock_timeout == 0.0)) return SOCKET_IS_NONBLOCKING; + else if (s->sock_timeout < 0.0) + return SOCKET_IS_BLOCKING; /* Guard against closed socket */ if (s->sock_fd < 0) @@ -1562,18 +1680,19 @@ static PyObject *PySSL_SSLwrite(PySSLSocket *self, PyObject *args) int sockstate; int err; int nonblocking; - PySocketSockObject *sock - = (PySocketSockObject *) PyWeakref_GetObject(self->Socket); + PySocketSockObject *sock = GET_SOCKET(self); - if (((PyObject*)sock) == Py_None) { - _setSSLError("Underlying socket connection gone", - PY_SSL_ERROR_NO_SOCKET, __FILE__, __LINE__); - return NULL; + if (sock != NULL) { + if (((PyObject*)sock) == Py_None) { + _setSSLError("Underlying socket connection gone", + PY_SSL_ERROR_NO_SOCKET, __FILE__, __LINE__); + return NULL; + } + Py_INCREF(sock); } - Py_INCREF(sock); if (!PyArg_ParseTuple(args, "y*:write", &buf)) { - Py_DECREF(sock); + Py_XDECREF(sock); return NULL; } @@ -1583,10 +1702,12 @@ static PyObject *PySSL_SSLwrite(PySSLSocket *self, PyObject *args) goto error; } - /* just in case the blocking state of the socket has been changed */ - nonblocking = (sock->sock_timeout >= 0.0); - BIO_set_nbio(SSL_get_rbio(self->ssl), nonblocking); - BIO_set_nbio(SSL_get_wbio(self->ssl), nonblocking); + if (sock != NULL) { + /* just in case the blocking state of the socket has been changed */ + nonblocking = (sock->sock_timeout >= 0.0); + BIO_set_nbio(SSL_get_rbio(self->ssl), nonblocking); + BIO_set_nbio(SSL_get_wbio(self->ssl), nonblocking); + } sockstate = check_socket_and_wait_for_timeout(sock, 1); if (sockstate == SOCKET_HAS_TIMED_OUT) { @@ -1630,7 +1751,7 @@ static PyObject *PySSL_SSLwrite(PySSLSocket *self, PyObject *args) } } while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE); - Py_DECREF(sock); + Py_XDECREF(sock); PyBuffer_Release(&buf); if (len > 0) return PyLong_FromLong(len); @@ -1638,7 +1759,7 @@ static PyObject *PySSL_SSLwrite(PySSLSocket *self, PyObject *args) return PySSL_SetError(self, len, __FILE__, __LINE__); error: - Py_DECREF(sock); + Py_XDECREF(sock); PyBuffer_Release(&buf); return NULL; } @@ -1678,15 +1799,16 @@ static PyObject *PySSL_SSLread(PySSLSocket *self, PyObject *args) int sockstate; int err; int nonblocking; - PySocketSockObject *sock - = (PySocketSockObject *) PyWeakref_GetObject(self->Socket); + PySocketSockObject *sock = GET_SOCKET(self); - if (((PyObject*)sock) == Py_None) { - _setSSLError("Underlying socket connection gone", - PY_SSL_ERROR_NO_SOCKET, __FILE__, __LINE__); - return NULL; + if (sock != NULL) { + if (((PyObject*)sock) == Py_None) { + _setSSLError("Underlying socket connection gone", + PY_SSL_ERROR_NO_SOCKET, __FILE__, __LINE__); + return NULL; + } + Py_INCREF(sock); } - Py_INCREF(sock); buf.obj = NULL; buf.buf = NULL; @@ -1712,10 +1834,12 @@ static PyObject *PySSL_SSLread(PySSLSocket *self, PyObject *args) } } - /* just in case the blocking state of the socket has been changed */ - nonblocking = (sock->sock_timeout >= 0.0); - BIO_set_nbio(SSL_get_rbio(self->ssl), nonblocking); - BIO_set_nbio(SSL_get_wbio(self->ssl), nonblocking); + if (sock != NULL) { + /* just in case the blocking state of the socket has been changed */ + nonblocking = (sock->sock_timeout >= 0.0); + BIO_set_nbio(SSL_get_rbio(self->ssl), nonblocking); + BIO_set_nbio(SSL_get_wbio(self->ssl), nonblocking); + } /* first check if there are bytes ready to be read */ PySSL_BEGIN_ALLOW_THREADS @@ -1771,7 +1895,7 @@ static PyObject *PySSL_SSLread(PySSLSocket *self, PyObject *args) } done: - Py_DECREF(sock); + Py_XDECREF(sock); if (!buf_passed) { _PyBytes_Resize(&dest, count); return dest; @@ -1782,7 +1906,7 @@ static PyObject *PySSL_SSLread(PySSLSocket *self, PyObject *args) } error: - Py_DECREF(sock); + Py_XDECREF(sock); if (!buf_passed) Py_XDECREF(dest); else @@ -1799,21 +1923,22 @@ static PyObject *PySSL_SSLshutdown(PySSLSocket *self) { int err, ssl_err, sockstate, nonblocking; int zeros = 0; - PySocketSockObject *sock - = (PySocketSockObject *) PyWeakref_GetObject(self->Socket); + PySocketSockObject *sock = GET_SOCKET(self); - /* Guard against closed socket */ - if ((((PyObject*)sock) == Py_None) || (sock->sock_fd < 0)) { - _setSSLError("Underlying socket connection gone", - PY_SSL_ERROR_NO_SOCKET, __FILE__, __LINE__); - return NULL; - } - Py_INCREF(sock); + if (sock != NULL) { + /* Guard against closed socket */ + if ((((PyObject*)sock) == Py_None) || (sock->sock_fd < 0)) { + _setSSLError("Underlying socket connection gone", + PY_SSL_ERROR_NO_SOCKET, __FILE__, __LINE__); + return NULL; + } + Py_INCREF(sock); - /* Just in case the blocking state of the socket has been changed */ - nonblocking = (sock->sock_timeout >= 0.0); - BIO_set_nbio(SSL_get_rbio(self->ssl), nonblocking); - BIO_set_nbio(SSL_get_wbio(self->ssl), nonblocking); + /* Just in case the blocking state of the socket has been changed */ + nonblocking = (sock->sock_timeout >= 0.0); + BIO_set_nbio(SSL_get_rbio(self->ssl), nonblocking); + BIO_set_nbio(SSL_get_wbio(self->ssl), nonblocking); + } while (1) { PySSL_BEGIN_ALLOW_THREADS @@ -1871,15 +1996,17 @@ static PyObject *PySSL_SSLshutdown(PySSLSocket *self) } if (err < 0) { - Py_DECREF(sock); + Py_XDECREF(sock); return PySSL_SetError(self, err, __FILE__, __LINE__); } - else + if (sock) /* It's already INCREF'ed */ return (PyObject *) sock; + else + Py_RETURN_NONE; error: - Py_DECREF(sock); + Py_XDECREF(sock); return NULL; } @@ -1889,7 +2016,6 @@ PyDoc_STRVAR(PySSL_SSLshutdown_doc, Does the SSL shutdown handshake with the remote end, and returns\n\ the underlying socket object."); -#if HAVE_OPENSSL_FINISHED static PyObject * PySSL_tls_unique_cb(PySSLSocket *self) { @@ -1922,11 +2048,15 @@ Returns the 'tls-unique' channel binding data, as defined by RFC 5929.\n\ \n\ If the TLS handshake is not yet complete, None is returned"); -#endif /* HAVE_OPENSSL_FINISHED */ - static PyGetSetDef ssl_getsetlist[] = { {"context", (getter) PySSL_get_context, (setter) PySSL_set_context, PySSL_set_context_doc}, + {"server_side", (getter) PySSL_get_server_side, NULL, + PySSL_get_server_side_doc}, + {"server_hostname", (getter) PySSL_get_server_hostname, NULL, + PySSL_get_server_hostname_doc}, + {"owner", (getter) PySSL_get_owner, (setter) PySSL_set_owner, + PySSL_get_owner_doc}, {NULL}, /* sentinel */ }; @@ -1941,16 +2071,19 @@ static PyMethodDef PySSLMethods[] = { {"peer_certificate", (PyCFunction)PySSL_peercert, METH_VARARGS, PySSL_peercert_doc}, {"cipher", (PyCFunction)PySSL_cipher, METH_NOARGS}, + {"shared_ciphers", (PyCFunction)PySSL_shared_ciphers, METH_NOARGS}, + {"version", (PyCFunction)PySSL_version, METH_NOARGS}, #ifdef OPENSSL_NPN_NEGOTIATED {"selected_npn_protocol", (PyCFunction)PySSL_selected_npn_protocol, METH_NOARGS}, +#endif +#ifdef HAVE_ALPN + {"selected_alpn_protocol", (PyCFunction)PySSL_selected_alpn_protocol, METH_NOARGS}, #endif {"compression", (PyCFunction)PySSL_compression, METH_NOARGS}, {"shutdown", (PyCFunction)PySSL_SSLshutdown, METH_NOARGS, PySSL_SSLshutdown_doc}, -#if HAVE_OPENSSL_FINISHED {"tls_unique_cb", (PyCFunction)PySSL_tls_unique_cb, METH_NOARGS, PySSL_tls_unique_cb_doc}, -#endif {NULL, NULL} }; @@ -1999,6 +2132,7 @@ context_new(PyTypeObject *type, PyObject *args, PyObject *kwds) char *kwlist[] = {"protocol", NULL}; PySSLContext *self; int proto_version = PY_SSL_VERSION_SSL23; + long options; SSL_CTX *ctx = NULL; if (!PyArg_ParseTupleAndKeywords( @@ -2015,8 +2149,10 @@ context_new(PyTypeObject *type, PyObject *args, PyObject *kwds) else if (proto_version == PY_SSL_VERSION_TLS1_2) ctx = SSL_CTX_new(TLSv1_2_method()); #endif +#ifndef OPENSSL_NO_SSL3 else if (proto_version == PY_SSL_VERSION_SSL3) ctx = SSL_CTX_new(SSLv3_method()); +#endif #ifndef OPENSSL_NO_SSL2 else if (proto_version == PY_SSL_VERSION_SSL2) ctx = SSL_CTX_new(SSLv2_method()); @@ -2048,6 +2184,9 @@ context_new(PyTypeObject *type, PyObject *args, PyObject *kwds) #ifdef OPENSSL_NPN_NEGOTIATED self->npn_protocols = NULL; #endif +#ifdef HAVE_ALPN + self->alpn_protocols = NULL; +#endif #ifndef OPENSSL_NO_TLSEXT self->set_hostname = NULL; #endif @@ -2055,8 +2194,25 @@ context_new(PyTypeObject *type, PyObject *args, PyObject *kwds) self->check_hostname = 0; /* Defaults */ SSL_CTX_set_verify(self->ctx, SSL_VERIFY_NONE, NULL); - SSL_CTX_set_options(self->ctx, - SSL_OP_ALL & ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS); + options = SSL_OP_ALL & ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; + if (proto_version != PY_SSL_VERSION_SSL2) + options |= SSL_OP_NO_SSLv2; + SSL_CTX_set_options(self->ctx, options); + +#ifndef OPENSSL_NO_ECDH + /* Allow automatic ECDH curve selection (on OpenSSL 1.0.2+), or use + prime256v1 by default. This is Apache mod_ssl's initialization + policy, so we should be safe. */ +#if defined(SSL_CTX_set_ecdh_auto) + SSL_CTX_set_ecdh_auto(self->ctx, 1); +#else + { + EC_KEY *key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); + SSL_CTX_set_tmp_ecdh(self->ctx, key); + EC_KEY_free(key); + } +#endif +#endif #define SID_CTX "Python" SSL_CTX_set_session_id_context(self->ctx, (const unsigned char *) SID_CTX, @@ -2090,7 +2246,10 @@ context_dealloc(PySSLContext *self) context_clear(self); SSL_CTX_free(self->ctx); #ifdef OPENSSL_NPN_NEGOTIATED - PyMem_Free(self->npn_protocols); + PyMem_FREE(self->npn_protocols); +#endif +#ifdef HAVE_ALPN + PyMem_FREE(self->alpn_protocols); #endif Py_TYPE(self)->tp_free(self); } @@ -2117,6 +2276,30 @@ set_ciphers(PySSLContext *self, PyObject *args) } #ifdef OPENSSL_NPN_NEGOTIATED +static int +do_protocol_selection(int alpn, unsigned char **out, unsigned char *outlen, + const unsigned char *server_protocols, unsigned int server_protocols_len, + const unsigned char *client_protocols, unsigned int client_protocols_len) +{ + int ret; + if (client_protocols == NULL) { + client_protocols = (unsigned char *)""; + client_protocols_len = 0; + } + if (server_protocols == NULL) { + server_protocols = (unsigned char *)""; + server_protocols_len = 0; + } + + ret = SSL_select_next_proto(out, outlen, + server_protocols, server_protocols_len, + client_protocols, client_protocols_len); + if (alpn && ret != OPENSSL_NPN_NEGOTIATED) + return SSL_TLSEXT_ERR_NOACK; + + return SSL_TLSEXT_ERR_OK; +} + /* this callback gets passed to SSL_CTX_set_next_protos_advertise_cb */ static int _advertiseNPN_cb(SSL *s, @@ -2126,10 +2309,10 @@ _advertiseNPN_cb(SSL *s, PySSLContext *ssl_ctx = (PySSLContext *) args; if (ssl_ctx->npn_protocols == NULL) { - *data = (unsigned char *) ""; + *data = (unsigned char *)""; *len = 0; } else { - *data = (unsigned char *) ssl_ctx->npn_protocols; + *data = ssl_ctx->npn_protocols; *len = ssl_ctx->npn_protocols_len; } @@ -2142,23 +2325,9 @@ _selectNPN_cb(SSL *s, const unsigned char *server, unsigned int server_len, void *args) { - PySSLContext *ssl_ctx = (PySSLContext *) args; - - unsigned char *client = (unsigned char *) ssl_ctx->npn_protocols; - int client_len; - - if (client == NULL) { - client = (unsigned char *) ""; - client_len = 0; - } else { - client_len = ssl_ctx->npn_protocols_len; - } - - SSL_select_next_proto(out, outlen, - server, server_len, - client, client_len); - - return SSL_TLSEXT_ERR_OK; + PySSLContext *ctx = (PySSLContext *)args; + return do_protocol_selection(0, out, outlen, server, server_len, + ctx->npn_protocols, ctx->npn_protocols_len); } #endif @@ -2201,6 +2370,50 @@ _set_npn_protocols(PySSLContext *self, PyObject *args) #endif } +#ifdef HAVE_ALPN +static int +_selectALPN_cb(SSL *s, + const unsigned char **out, unsigned char *outlen, + const unsigned char *client_protocols, unsigned int client_protocols_len, + void *args) +{ + PySSLContext *ctx = (PySSLContext *)args; + return do_protocol_selection(1, (unsigned char **)out, outlen, + ctx->alpn_protocols, ctx->alpn_protocols_len, + client_protocols, client_protocols_len); +} +#endif + +static PyObject * +_set_alpn_protocols(PySSLContext *self, PyObject *args) +{ +#ifdef HAVE_ALPN + Py_buffer protos; + + if (!PyArg_ParseTuple(args, "y*:set_npn_protocols", &protos)) + return NULL; + + PyMem_FREE(self->alpn_protocols); + self->alpn_protocols = PyMem_Malloc(protos.len); + if (!self->alpn_protocols) + return PyErr_NoMemory(); + memcpy(self->alpn_protocols, protos.buf, protos.len); + self->alpn_protocols_len = protos.len; + PyBuffer_Release(&protos); + + if (SSL_CTX_set_alpn_protos(self->ctx, self->alpn_protocols, self->alpn_protocols_len)) + return PyErr_NoMemory(); + SSL_CTX_set_alpn_select_cb(self->ctx, _selectALPN_cb, self); + + PyBuffer_Release(&protos); + Py_RETURN_NONE; +#else + PyErr_SetString(PyExc_NotImplementedError, + "The ALPN extension requires OpenSSL 1.0.2 or later."); + return NULL; +#endif +} + static PyObject * get_verify_mode(PySSLContext *self, void *c) { @@ -2244,7 +2457,6 @@ set_verify_mode(PySSLContext *self, PyObject *arg, void *c) return 0; } -#ifdef HAVE_OPENSSL_VERIFY_PARAM static PyObject * get_verify_flags(PySSLContext *self, void *c) { @@ -2282,7 +2494,6 @@ set_verify_flags(PySSLContext *self, PyObject *arg, void *c) } return 0; } -#endif static PyObject * get_options(PySSLContext *self, void *c) @@ -2788,21 +2999,44 @@ context_wrap_socket(PySSLContext *self, PyObject *args, PyObject *kwds) &sock, &server_side, "idna", &hostname)) return NULL; -#if !HAVE_SNI - PyMem_Free(hostname); - PyErr_SetString(PyExc_ValueError, "server_hostname is not supported " - "by your OpenSSL library"); - return NULL; -#endif } - res = (PyObject *) newPySSLSocket(self, sock, server_side, - hostname); + res = (PyObject *) newPySSLSocket(self, sock, server_side, hostname, + NULL, NULL); if (hostname != NULL) PyMem_Free(hostname); return res; } +static PyObject * +context_wrap_bio(PySSLContext *self, PyObject *args, PyObject *kwds) +{ + char *kwlist[] = {"incoming", "outgoing", "server_side", + "server_hostname", NULL}; + int server_side; + char *hostname = NULL; + PyObject *hostname_obj = Py_None, *res; + PySSLMemoryBIO *incoming, *outgoing; + + /* server_hostname is either None (or absent), or to be encoded + using the idna encoding. */ + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!O!i|O:_wrap_bio", kwlist, + &PySSLMemoryBIO_Type, &incoming, + &PySSLMemoryBIO_Type, &outgoing, + &server_side, &hostname_obj)) + return NULL; + if (hostname_obj != Py_None) { + if (!PyArg_Parse(hostname_obj, "et", "idna", &hostname)) + return NULL; + } + + res = (PyObject *) newPySSLSocket(self, NULL, server_side, hostname, + incoming, outgoing); + + PyMem_Free(hostname); + return res; +} + static PyObject * session_stats(PySSLContext *self, PyObject *unused) { @@ -2909,11 +3143,25 @@ _servername_callback(SSL *s, int *al, void *args) ssl = SSL_get_app_data(s); assert(PySSLSocket_Check(ssl)); - ssl_socket = PyWeakref_GetObject(ssl->Socket); + + /* The servername callback expects a argument that represents the current + * SSL connection and that has a .context attribute that can be changed to + * identify the requested hostname. Since the official API is the Python + * level API we want to pass the callback a Python level object rather than + * a _ssl.SSLSocket instance. If there's an "owner" (typically an + * SSLObject) that will be passed. Otherwise if there's a socket then that + * will be passed. If both do not exist only then the C-level object is + * passed. */ + if (ssl->owner) + ssl_socket = PyWeakref_GetObject(ssl->owner); + else if (ssl->Socket) + ssl_socket = PyWeakref_GetObject(ssl->Socket); + else + ssl_socket = (PyObject *) ssl; + Py_INCREF(ssl_socket); - if (ssl_socket == Py_None) { + if (ssl_socket == Py_None) goto error; - } if (servername == NULL) { result = PyObject_CallFunctionObjArgs(ssl_ctx->set_hostname, ssl_socket, @@ -3130,10 +3378,8 @@ static PyGetSetDef context_getsetlist[] = { (setter) set_check_hostname, NULL}, {"options", (getter) get_options, (setter) set_options, NULL}, -#ifdef HAVE_OPENSSL_VERIFY_PARAM {"verify_flags", (getter) get_verify_flags, (setter) set_verify_flags, NULL}, -#endif {"verify_mode", (getter) get_verify_mode, (setter) set_verify_mode, NULL}, {NULL}, /* sentinel */ @@ -3142,8 +3388,12 @@ static PyGetSetDef context_getsetlist[] = { static struct PyMethodDef context_methods[] = { {"_wrap_socket", (PyCFunction) context_wrap_socket, METH_VARARGS | METH_KEYWORDS, NULL}, + {"_wrap_bio", (PyCFunction) context_wrap_bio, + METH_VARARGS | METH_KEYWORDS, NULL}, {"set_ciphers", (PyCFunction) set_ciphers, METH_VARARGS, NULL}, + {"_set_alpn_protocols", (PyCFunction) _set_alpn_protocols, + METH_VARARGS, NULL}, {"_set_npn_protocols", (PyCFunction) _set_npn_protocols, METH_VARARGS, NULL}, {"load_cert_chain", (PyCFunction) load_cert_chain, @@ -3211,20 +3461,242 @@ static PyTypeObject PySSLContext_Type = { }; +/* + * MemoryBIO objects + */ + +static PyObject * +memory_bio_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + char *kwlist[] = {NULL}; + BIO *bio; + PySSLMemoryBIO *self; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, ":MemoryBIO", kwlist)) + return NULL; + + bio = BIO_new(BIO_s_mem()); + if (bio == NULL) { + PyErr_SetString(PySSLErrorObject, + "failed to allocate BIO"); + return NULL; + } + /* Since our BIO is non-blocking an empty read() does not indicate EOF, + * just that no data is currently available. The SSL routines should retry + * the read, which we can achieve by calling BIO_set_retry_read(). */ + BIO_set_retry_read(bio); + BIO_set_mem_eof_return(bio, -1); + + assert(type != NULL && type->tp_alloc != NULL); + self = (PySSLMemoryBIO *) type->tp_alloc(type, 0); + if (self == NULL) { + BIO_free(bio); + return NULL; + } + self->bio = bio; + self->eof_written = 0; + + return (PyObject *) self; +} + +static void +memory_bio_dealloc(PySSLMemoryBIO *self) +{ + BIO_free(self->bio); + Py_TYPE(self)->tp_free(self); +} + +static PyObject * +memory_bio_get_pending(PySSLMemoryBIO *self, void *c) +{ + return PyLong_FromLong(BIO_ctrl_pending(self->bio)); +} + +PyDoc_STRVAR(PySSL_memory_bio_pending_doc, +"The number of bytes pending in the memory BIO."); + +static PyObject * +memory_bio_get_eof(PySSLMemoryBIO *self, void *c) +{ + return PyBool_FromLong((BIO_ctrl_pending(self->bio) == 0) + && self->eof_written); +} + +PyDoc_STRVAR(PySSL_memory_bio_eof_doc, +"Whether the memory BIO is at EOF."); + +static PyObject * +memory_bio_read(PySSLMemoryBIO *self, PyObject *args) +{ + int len = -1, avail, nbytes; + PyObject *result; + + if (!PyArg_ParseTuple(args, "|i:read", &len)) + return NULL; + + avail = BIO_ctrl_pending(self->bio); + if ((len < 0) || (len > avail)) + len = avail; + + result = PyBytes_FromStringAndSize(NULL, len); + if ((result == NULL) || (len == 0)) + return result; + + nbytes = BIO_read(self->bio, PyBytes_AS_STRING(result), len); + /* There should never be any short reads but check anyway. */ + if ((nbytes < len) && (_PyBytes_Resize(&result, len) < 0)) { + Py_DECREF(result); + return NULL; + } + + return result; +} + +PyDoc_STRVAR(PySSL_memory_bio_read_doc, +"read([len]) -> bytes\n\ +\n\ +Read up to len bytes from the memory BIO.\n\ +\n\ +If len is not specified, read the entire buffer.\n\ +If the return value is an empty bytes instance, this means either\n\ +EOF or that no data is available. Use the \"eof\" property to\n\ +distinguish between the two."); + +static PyObject * +memory_bio_write(PySSLMemoryBIO *self, PyObject *args) +{ + Py_buffer buf; + int nbytes; + + if (!PyArg_ParseTuple(args, "y*:write", &buf)) + return NULL; + + if (buf.len > INT_MAX) { + PyErr_Format(PyExc_OverflowError, + "string longer than %d bytes", INT_MAX); + goto error; + } + + if (self->eof_written) { + PyErr_SetString(PySSLErrorObject, + "cannot write() after write_eof()"); + goto error; + } + + nbytes = BIO_write(self->bio, buf.buf, buf.len); + if (nbytes < 0) { + _setSSLError(NULL, 0, __FILE__, __LINE__); + goto error; + } + + PyBuffer_Release(&buf); + return PyLong_FromLong(nbytes); + +error: + PyBuffer_Release(&buf); + return NULL; +} + +PyDoc_STRVAR(PySSL_memory_bio_write_doc, +"write(b) -> len\n\ +\n\ +Writes the bytes b into the memory BIO. Returns the number\n\ +of bytes written."); + +static PyObject * +memory_bio_write_eof(PySSLMemoryBIO *self, PyObject *args) +{ + self->eof_written = 1; + /* After an EOF is written, a zero return from read() should be a real EOF + * i.e. it should not be retried. Clear the SHOULD_RETRY flag. */ + BIO_clear_retry_flags(self->bio); + BIO_set_mem_eof_return(self->bio, 0); + + Py_RETURN_NONE; +} + +PyDoc_STRVAR(PySSL_memory_bio_write_eof_doc, +"write_eof()\n\ +\n\ +Write an EOF marker to the memory BIO.\n\ +When all data has been read, the \"eof\" property will be True."); + +static PyGetSetDef memory_bio_getsetlist[] = { + {"pending", (getter) memory_bio_get_pending, NULL, + PySSL_memory_bio_pending_doc}, + {"eof", (getter) memory_bio_get_eof, NULL, + PySSL_memory_bio_eof_doc}, + {NULL}, /* sentinel */ +}; + +static struct PyMethodDef memory_bio_methods[] = { + {"read", (PyCFunction) memory_bio_read, + METH_VARARGS, PySSL_memory_bio_read_doc}, + {"write", (PyCFunction) memory_bio_write, + METH_VARARGS, PySSL_memory_bio_write_doc}, + {"write_eof", (PyCFunction) memory_bio_write_eof, + METH_NOARGS, PySSL_memory_bio_write_eof_doc}, + {NULL, NULL} /* sentinel */ +}; + +static PyTypeObject PySSLMemoryBIO_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_ssl.MemoryBIO", /*tp_name*/ + sizeof(PySSLMemoryBIO), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)memory_bio_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_reserved*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + memory_bio_methods, /*tp_methods*/ + 0, /*tp_members*/ + memory_bio_getsetlist, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + 0, /*tp_init*/ + 0, /*tp_alloc*/ + memory_bio_new, /*tp_new*/ +}; -#ifdef HAVE_OPENSSL_RAND /* helper routines for seeding the SSL PRNG */ static PyObject * PySSL_RAND_add(PyObject *self, PyObject *args) { char *buf; - int len; + Py_ssize_t len, written; double entropy; if (!PyArg_ParseTuple(args, "s#d:RAND_add", &buf, &len, &entropy)) return NULL; - RAND_add(buf, len, entropy); + do { + written = Py_MIN(len, INT_MAX); + RAND_add(buf, (int)written, entropy); + buf += written; + len -= written; + } while (len); Py_INCREF(Py_None); return Py_None; } @@ -3244,6 +3716,11 @@ PySSL_RAND(int len, int pseudo) const char *errstr; PyObject *v; + if (len < 0) { + PyErr_SetString(PyExc_ValueError, "num must be positive"); + return NULL; + } + bytes = PyBytes_FromStringAndSize(NULL, len); if (bytes == NULL) return NULL; @@ -3311,6 +3788,7 @@ Returns 1 if the OpenSSL PRNG has been seeded with enough data and 0 if not.\n\ It is necessary to seed the PRNG with RAND_add() on some platforms before\n\ using the ssl() function."); +#ifdef HAVE_RAND_EGD static PyObject * PySSL_RAND_egd(PyObject *self, PyObject *args) { @@ -3338,8 +3816,7 @@ PyDoc_STRVAR(PySSL_RAND_egd_doc, Queries the entropy gather daemon (EGD) on the socket named by 'path'.\n\ Returns number of bytes read. Raises SSLError if connection to EGD\n\ fails or if it does not provide enough data to seed PRNG."); - -#endif /* HAVE_OPENSSL_RAND */ +#endif /* HAVE_RAND_EGD */ PyDoc_STRVAR(PySSL_get_default_verify_paths_doc, @@ -3388,7 +3865,7 @@ asn1obj2py(ASN1_OBJECT *obj) int nid; const char *ln, *sn; char buf[100]; - int buflen; + Py_ssize_t buflen; nid = OBJ_obj2nid(obj); if (nid == NID_undef) { @@ -3726,18 +4203,18 @@ PySSL_enum_crls(PyObject *self, PyObject *args, PyObject *kwds) static PyMethodDef PySSL_methods[] = { {"_test_decode_cert", PySSL_test_decode_certificate, METH_VARARGS}, -#ifdef HAVE_OPENSSL_RAND {"RAND_add", PySSL_RAND_add, METH_VARARGS, PySSL_RAND_add_doc}, {"RAND_bytes", PySSL_RAND_bytes, METH_VARARGS, PySSL_RAND_bytes_doc}, {"RAND_pseudo_bytes", PySSL_RAND_pseudo_bytes, METH_VARARGS, PySSL_RAND_pseudo_bytes_doc}, +#ifdef HAVE_RAND_EGD {"RAND_egd", PySSL_RAND_egd, METH_VARARGS, PySSL_RAND_egd_doc}, +#endif {"RAND_status", (PyCFunction)PySSL_RAND_status, METH_NOARGS, PySSL_RAND_status_doc}, -#endif {"get_default_verify_paths", (PyCFunction)PySSL_get_default_verify_paths, METH_NOARGS, PySSL_get_default_verify_paths_doc}, #ifdef _MSC_VER @@ -3810,10 +4287,11 @@ static int _setup_ssl_threads(void) { if (_ssl_locks == NULL) { _ssl_locks_count = CRYPTO_num_locks(); - _ssl_locks = (PyThread_type_lock *) - PyMem_Malloc(sizeof(PyThread_type_lock) * _ssl_locks_count); - if (_ssl_locks == NULL) + _ssl_locks = PyMem_New(PyThread_type_lock, _ssl_locks_count); + if (_ssl_locks == NULL) { + PyErr_NoMemory(); return 0; + } memset(_ssl_locks, 0, sizeof(PyThread_type_lock) * _ssl_locks_count); for (i = 0; i < _ssl_locks_count; i++) { @@ -3888,6 +4366,8 @@ PyInit__ssl(void) return NULL; if (PyType_Ready(&PySSLSocket_Type) < 0) return NULL; + if (PyType_Ready(&PySSLMemoryBIO_Type) < 0) + return NULL; m = PyModule_Create(&_sslmodule); if (m == NULL) @@ -3951,6 +4431,9 @@ PyInit__ssl(void) if (PyDict_SetItemString(d, "_SSLSocket", (PyObject *)&PySSLSocket_Type) != 0) return NULL; + if (PyDict_SetItemString(d, "MemoryBIO", + (PyObject *)&PySSLMemoryBIO_Type) != 0) + return NULL; PyModule_AddIntConstant(m, "SSL_ERROR_ZERO_RETURN", PY_SSL_ERROR_ZERO_RETURN); PyModule_AddIntConstant(m, "SSL_ERROR_WANT_READ", @@ -4043,8 +4526,10 @@ PyInit__ssl(void) PyModule_AddIntConstant(m, "PROTOCOL_SSLv2", PY_SSL_VERSION_SSL2); #endif +#ifndef OPENSSL_NO_SSL3 PyModule_AddIntConstant(m, "PROTOCOL_SSLv3", PY_SSL_VERSION_SSL3); +#endif PyModule_AddIntConstant(m, "PROTOCOL_SSLv23", PY_SSL_VERSION_SSL23); PyModule_AddIntConstant(m, "PROTOCOL_TLSv1", @@ -4085,11 +4570,7 @@ PyInit__ssl(void) Py_INCREF(r); PyModule_AddObject(m, "HAS_SNI", r); -#if HAVE_OPENSSL_FINISHED r = Py_True; -#else - r = Py_False; -#endif Py_INCREF(r); PyModule_AddObject(m, "HAS_TLS_UNIQUE", r); @@ -4109,6 +4590,14 @@ PyInit__ssl(void) Py_INCREF(r); PyModule_AddObject(m, "HAS_NPN", r); +#ifdef HAVE_ALPN + r = Py_True; +#else + r = Py_False; +#endif + Py_INCREF(r); + PyModule_AddObject(m, "HAS_ALPN", r); + /* Mappings for error codes */ err_codes_to_names = PyDict_New(); err_names_to_codes = PyDict_New(); diff --git a/Modules/_ssl_data.h b/Modules/_ssl_data.h index 81a8d7ba169e..85165b90bc38 100644 --- a/Modules/_ssl_data.h +++ b/Modules/_ssl_data.h @@ -1,5 +1,5 @@ /* File generated by Tools/ssl/make_ssl_data.py */ -/* Generated on 2012-05-16T23:56:40.981382 */ +/* Generated on 2015-01-17T20:33:43.377453 */ static struct py_ssl_library_code library_codes[] = { {"PEM", ERR_LIB_PEM}, @@ -179,6 +179,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"BAD_CHECKSUM", ERR_LIB_SSL, 104}, #endif + #ifdef SSL_R_BAD_DATA + {"BAD_DATA", ERR_LIB_SSL, SSL_R_BAD_DATA}, + #else + {"BAD_DATA", ERR_LIB_SSL, 390}, + #endif #ifdef SSL_R_BAD_DATA_RETURNED_BY_CALLBACK {"BAD_DATA_RETURNED_BY_CALLBACK", ERR_LIB_SSL, SSL_R_BAD_DATA_RETURNED_BY_CALLBACK}, #else @@ -309,6 +314,46 @@ static struct py_ssl_error_code error_codes[] = { #else {"BAD_SIGNATURE", ERR_LIB_SSL, 123}, #endif + #ifdef SSL_R_BAD_SRP_A_LENGTH + {"BAD_SRP_A_LENGTH", ERR_LIB_SSL, SSL_R_BAD_SRP_A_LENGTH}, + #else + {"BAD_SRP_A_LENGTH", ERR_LIB_SSL, 347}, + #endif + #ifdef SSL_R_BAD_SRP_B_LENGTH + {"BAD_SRP_B_LENGTH", ERR_LIB_SSL, SSL_R_BAD_SRP_B_LENGTH}, + #else + {"BAD_SRP_B_LENGTH", ERR_LIB_SSL, 348}, + #endif + #ifdef SSL_R_BAD_SRP_G_LENGTH + {"BAD_SRP_G_LENGTH", ERR_LIB_SSL, SSL_R_BAD_SRP_G_LENGTH}, + #else + {"BAD_SRP_G_LENGTH", ERR_LIB_SSL, 349}, + #endif + #ifdef SSL_R_BAD_SRP_N_LENGTH + {"BAD_SRP_N_LENGTH", ERR_LIB_SSL, SSL_R_BAD_SRP_N_LENGTH}, + #else + {"BAD_SRP_N_LENGTH", ERR_LIB_SSL, 350}, + #endif + #ifdef SSL_R_BAD_SRP_PARAMETERS + {"BAD_SRP_PARAMETERS", ERR_LIB_SSL, SSL_R_BAD_SRP_PARAMETERS}, + #else + {"BAD_SRP_PARAMETERS", ERR_LIB_SSL, 371}, + #endif + #ifdef SSL_R_BAD_SRP_S_LENGTH + {"BAD_SRP_S_LENGTH", ERR_LIB_SSL, SSL_R_BAD_SRP_S_LENGTH}, + #else + {"BAD_SRP_S_LENGTH", ERR_LIB_SSL, 351}, + #endif + #ifdef SSL_R_BAD_SRTP_MKI_VALUE + {"BAD_SRTP_MKI_VALUE", ERR_LIB_SSL, SSL_R_BAD_SRTP_MKI_VALUE}, + #else + {"BAD_SRTP_MKI_VALUE", ERR_LIB_SSL, 352}, + #endif + #ifdef SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST + {"BAD_SRTP_PROTECTION_PROFILE_LIST", ERR_LIB_SSL, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST}, + #else + {"BAD_SRTP_PROTECTION_PROFILE_LIST", ERR_LIB_SSL, 353}, + #endif #ifdef SSL_R_BAD_SSL_FILETYPE {"BAD_SSL_FILETYPE", ERR_LIB_SSL, SSL_R_BAD_SSL_FILETYPE}, #else @@ -324,6 +369,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"BAD_STATE", ERR_LIB_SSL, 126}, #endif + #ifdef SSL_R_BAD_VALUE + {"BAD_VALUE", ERR_LIB_SSL, SSL_R_BAD_VALUE}, + #else + {"BAD_VALUE", ERR_LIB_SSL, 384}, + #endif #ifdef SSL_R_BAD_WRITE_RETRY {"BAD_WRITE_RETRY", ERR_LIB_SSL, SSL_R_BAD_WRITE_RETRY}, #else @@ -354,6 +404,16 @@ static struct py_ssl_error_code error_codes[] = { #else {"CA_DN_TOO_LONG", ERR_LIB_SSL, 132}, #endif + #ifdef SSL_R_CA_KEY_TOO_SMALL + {"CA_KEY_TOO_SMALL", ERR_LIB_SSL, SSL_R_CA_KEY_TOO_SMALL}, + #else + {"CA_KEY_TOO_SMALL", ERR_LIB_SSL, 397}, + #endif + #ifdef SSL_R_CA_MD_TOO_WEAK + {"CA_MD_TOO_WEAK", ERR_LIB_SSL, SSL_R_CA_MD_TOO_WEAK}, + #else + {"CA_MD_TOO_WEAK", ERR_LIB_SSL, 398}, + #endif #ifdef SSL_R_CCS_RECEIVED_EARLY {"CCS_RECEIVED_EARLY", ERR_LIB_SSL, SSL_R_CCS_RECEIVED_EARLY}, #else @@ -364,6 +424,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"CERTIFICATE_VERIFY_FAILED", ERR_LIB_SSL, 134}, #endif + #ifdef SSL_R_CERT_CB_ERROR + {"CERT_CB_ERROR", ERR_LIB_SSL, SSL_R_CERT_CB_ERROR}, + #else + {"CERT_CB_ERROR", ERR_LIB_SSL, 377}, + #endif #ifdef SSL_R_CERT_LENGTH_MISMATCH {"CERT_LENGTH_MISMATCH", ERR_LIB_SSL, SSL_R_CERT_LENGTH_MISMATCH}, #else @@ -454,6 +519,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"DECRYPTION_FAILED_OR_BAD_RECORD_MAC", ERR_LIB_SSL, 281}, #endif + #ifdef SSL_R_DH_KEY_TOO_SMALL + {"DH_KEY_TOO_SMALL", ERR_LIB_SSL, SSL_R_DH_KEY_TOO_SMALL}, + #else + {"DH_KEY_TOO_SMALL", ERR_LIB_SSL, 394}, + #endif #ifdef SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG {"DH_PUBLIC_VALUE_LENGTH_IS_WRONG", ERR_LIB_SSL, SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG}, #else @@ -494,11 +564,26 @@ static struct py_ssl_error_code error_codes[] = { #else {"ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE", ERR_LIB_SSL, 323}, #endif + #ifdef SSL_R_ECDH_REQUIRED_FOR_SUITEB_MODE + {"ECDH_REQUIRED_FOR_SUITEB_MODE", ERR_LIB_SSL, SSL_R_ECDH_REQUIRED_FOR_SUITEB_MODE}, + #else + {"ECDH_REQUIRED_FOR_SUITEB_MODE", ERR_LIB_SSL, 374}, + #endif #ifdef SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER {"ECGROUP_TOO_LARGE_FOR_CIPHER", ERR_LIB_SSL, SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER}, #else {"ECGROUP_TOO_LARGE_FOR_CIPHER", ERR_LIB_SSL, 310}, #endif + #ifdef SSL_R_EE_KEY_TOO_SMALL + {"EE_KEY_TOO_SMALL", ERR_LIB_SSL, SSL_R_EE_KEY_TOO_SMALL}, + #else + {"EE_KEY_TOO_SMALL", ERR_LIB_SSL, 399}, + #endif + #ifdef SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST + {"EMPTY_SRTP_PROTECTION_PROFILE_LIST", ERR_LIB_SSL, SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST}, + #else + {"EMPTY_SRTP_PROTECTION_PROFILE_LIST", ERR_LIB_SSL, 354}, + #endif #ifdef SSL_R_ENCRYPTED_LENGTH_TOO_LONG {"ENCRYPTED_LENGTH_TOO_LONG", ERR_LIB_SSL, SSL_R_ENCRYPTED_LENGTH_TOO_LONG}, #else @@ -529,6 +614,16 @@ static struct py_ssl_error_code error_codes[] = { #else {"GOT_A_FIN_BEFORE_A_CCS", ERR_LIB_SSL, 154}, #endif + #ifdef SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS + {"GOT_NEXT_PROTO_BEFORE_A_CCS", ERR_LIB_SSL, SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS}, + #else + {"GOT_NEXT_PROTO_BEFORE_A_CCS", ERR_LIB_SSL, 355}, + #endif + #ifdef SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION + {"GOT_NEXT_PROTO_WITHOUT_EXTENSION", ERR_LIB_SSL, SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION}, + #else + {"GOT_NEXT_PROTO_WITHOUT_EXTENSION", ERR_LIB_SSL, 356}, + #endif #ifdef SSL_R_HTTPS_PROXY_REQUEST {"HTTPS_PROXY_REQUEST", ERR_LIB_SSL, SSL_R_HTTPS_PROXY_REQUEST}, #else @@ -544,6 +639,16 @@ static struct py_ssl_error_code error_codes[] = { #else {"ILLEGAL_PADDING", ERR_LIB_SSL, 283}, #endif + #ifdef SSL_R_ILLEGAL_SUITEB_DIGEST + {"ILLEGAL_SUITEB_DIGEST", ERR_LIB_SSL, SSL_R_ILLEGAL_SUITEB_DIGEST}, + #else + {"ILLEGAL_SUITEB_DIGEST", ERR_LIB_SSL, 380}, + #endif + #ifdef SSL_R_INAPPROPRIATE_FALLBACK + {"INAPPROPRIATE_FALLBACK", ERR_LIB_SSL, SSL_R_INAPPROPRIATE_FALLBACK}, + #else + {"INAPPROPRIATE_FALLBACK", ERR_LIB_SSL, 373}, + #endif #ifdef SSL_R_INCONSISTENT_COMPRESSION {"INCONSISTENT_COMPRESSION", ERR_LIB_SSL, SSL_R_INCONSISTENT_COMPRESSION}, #else @@ -564,11 +669,26 @@ static struct py_ssl_error_code error_codes[] = { #else {"INVALID_COMPRESSION_ALGORITHM", ERR_LIB_SSL, 341}, #endif + #ifdef SSL_R_INVALID_NULL_CMD_NAME + {"INVALID_NULL_CMD_NAME", ERR_LIB_SSL, SSL_R_INVALID_NULL_CMD_NAME}, + #else + {"INVALID_NULL_CMD_NAME", ERR_LIB_SSL, 385}, + #endif #ifdef SSL_R_INVALID_PURPOSE {"INVALID_PURPOSE", ERR_LIB_SSL, SSL_R_INVALID_PURPOSE}, #else {"INVALID_PURPOSE", ERR_LIB_SSL, 278}, #endif + #ifdef SSL_R_INVALID_SERVERINFO_DATA + {"INVALID_SERVERINFO_DATA", ERR_LIB_SSL, SSL_R_INVALID_SERVERINFO_DATA}, + #else + {"INVALID_SERVERINFO_DATA", ERR_LIB_SSL, 388}, + #endif + #ifdef SSL_R_INVALID_SRP_USERNAME + {"INVALID_SRP_USERNAME", ERR_LIB_SSL, SSL_R_INVALID_SRP_USERNAME}, + #else + {"INVALID_SRP_USERNAME", ERR_LIB_SSL, 357}, + #endif #ifdef SSL_R_INVALID_STATUS_RESPONSE {"INVALID_STATUS_RESPONSE", ERR_LIB_SSL, SSL_R_INVALID_STATUS_RESPONSE}, #else @@ -689,6 +809,16 @@ static struct py_ssl_error_code error_codes[] = { #else {"MISSING_DSA_SIGNING_CERT", ERR_LIB_SSL, 165}, #endif + #ifdef SSL_R_MISSING_ECDH_CERT + {"MISSING_ECDH_CERT", ERR_LIB_SSL, SSL_R_MISSING_ECDH_CERT}, + #else + {"MISSING_ECDH_CERT", ERR_LIB_SSL, 382}, + #endif + #ifdef SSL_R_MISSING_ECDSA_SIGNING_CERT + {"MISSING_ECDSA_SIGNING_CERT", ERR_LIB_SSL, SSL_R_MISSING_ECDSA_SIGNING_CERT}, + #else + {"MISSING_ECDSA_SIGNING_CERT", ERR_LIB_SSL, 381}, + #endif #ifdef SSL_R_MISSING_EXPORT_TMP_DH_KEY {"MISSING_EXPORT_TMP_DH_KEY", ERR_LIB_SSL, SSL_R_MISSING_EXPORT_TMP_DH_KEY}, #else @@ -714,6 +844,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"MISSING_RSA_SIGNING_CERT", ERR_LIB_SSL, 170}, #endif + #ifdef SSL_R_MISSING_SRP_PARAM + {"MISSING_SRP_PARAM", ERR_LIB_SSL, SSL_R_MISSING_SRP_PARAM}, + #else + {"MISSING_SRP_PARAM", ERR_LIB_SSL, 358}, + #endif #ifdef SSL_R_MISSING_TMP_DH_KEY {"MISSING_TMP_DH_KEY", ERR_LIB_SSL, SSL_R_MISSING_TMP_DH_KEY}, #else @@ -739,6 +874,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"MISSING_VERIFY_MESSAGE", ERR_LIB_SSL, 174}, #endif + #ifdef SSL_R_MULTIPLE_SGC_RESTARTS + {"MULTIPLE_SGC_RESTARTS", ERR_LIB_SSL, SSL_R_MULTIPLE_SGC_RESTARTS}, + #else + {"MULTIPLE_SGC_RESTARTS", ERR_LIB_SSL, 346}, + #endif #ifdef SSL_R_NON_SSLV2_INITIAL_PACKET {"NON_SSLV2_INITIAL_PACKET", ERR_LIB_SSL, SSL_R_NON_SSLV2_INITIAL_PACKET}, #else @@ -819,6 +959,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"NO_METHOD_SPECIFIED", ERR_LIB_SSL, 188}, #endif + #ifdef SSL_R_NO_PEM_EXTENSIONS + {"NO_PEM_EXTENSIONS", ERR_LIB_SSL, SSL_R_NO_PEM_EXTENSIONS}, + #else + {"NO_PEM_EXTENSIONS", ERR_LIB_SSL, 389}, + #endif #ifdef SSL_R_NO_PRIVATEKEY {"NO_PRIVATEKEY", ERR_LIB_SSL, SSL_R_NO_PRIVATEKEY}, #else @@ -854,6 +999,16 @@ static struct py_ssl_error_code error_codes[] = { #else {"NO_SHARED_CIPHER", ERR_LIB_SSL, 193}, #endif + #ifdef SSL_R_NO_SHARED_SIGATURE_ALGORITHMS + {"NO_SHARED_SIGATURE_ALGORITHMS", ERR_LIB_SSL, SSL_R_NO_SHARED_SIGATURE_ALGORITHMS}, + #else + {"NO_SHARED_SIGATURE_ALGORITHMS", ERR_LIB_SSL, 376}, + #endif + #ifdef SSL_R_NO_SRTP_PROFILES + {"NO_SRTP_PROFILES", ERR_LIB_SSL, SSL_R_NO_SRTP_PROFILES}, + #else + {"NO_SRTP_PROFILES", ERR_LIB_SSL, 359}, + #endif #ifdef SSL_R_NO_VERIFY_CALLBACK {"NO_VERIFY_CALLBACK", ERR_LIB_SSL, SSL_R_NO_VERIFY_CALLBACK}, #else @@ -879,6 +1034,16 @@ static struct py_ssl_error_code error_codes[] = { #else {"OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED", ERR_LIB_SSL, 344}, #endif + #ifdef SSL_R_ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE + {"ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE", ERR_LIB_SSL, SSL_R_ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE}, + #else + {"ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE", ERR_LIB_SSL, 387}, + #endif + #ifdef SSL_R_ONLY_TLS_1_2_ALLOWED_IN_SUITEB_MODE + {"ONLY_TLS_1_2_ALLOWED_IN_SUITEB_MODE", ERR_LIB_SSL, SSL_R_ONLY_TLS_1_2_ALLOWED_IN_SUITEB_MODE}, + #else + {"ONLY_TLS_1_2_ALLOWED_IN_SUITEB_MODE", ERR_LIB_SSL, 379}, + #endif #ifdef SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE {"ONLY_TLS_ALLOWED_IN_FIPS_MODE", ERR_LIB_SSL, SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE}, #else @@ -934,6 +1099,16 @@ static struct py_ssl_error_code error_codes[] = { #else {"PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE", ERR_LIB_SSL, 204}, #endif + #ifdef SSL_R_PEM_NAME_BAD_PREFIX + {"PEM_NAME_BAD_PREFIX", ERR_LIB_SSL, SSL_R_PEM_NAME_BAD_PREFIX}, + #else + {"PEM_NAME_BAD_PREFIX", ERR_LIB_SSL, 391}, + #endif + #ifdef SSL_R_PEM_NAME_TOO_SHORT + {"PEM_NAME_TOO_SHORT", ERR_LIB_SSL, SSL_R_PEM_NAME_TOO_SHORT}, + #else + {"PEM_NAME_TOO_SHORT", ERR_LIB_SSL, 392}, + #endif #ifdef SSL_R_PRE_MAC_LENGTH_TOO_LONG {"PRE_MAC_LENGTH_TOO_LONG", ERR_LIB_SSL, SSL_R_PRE_MAC_LENGTH_TOO_LONG}, #else @@ -1069,11 +1244,36 @@ static struct py_ssl_error_code error_codes[] = { #else {"SHORT_READ", ERR_LIB_SSL, 219}, #endif + #ifdef SSL_R_SIGNATURE_ALGORITHMS_ERROR + {"SIGNATURE_ALGORITHMS_ERROR", ERR_LIB_SSL, SSL_R_SIGNATURE_ALGORITHMS_ERROR}, + #else + {"SIGNATURE_ALGORITHMS_ERROR", ERR_LIB_SSL, 360}, + #endif #ifdef SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE {"SIGNATURE_FOR_NON_SIGNING_CERTIFICATE", ERR_LIB_SSL, SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE}, #else {"SIGNATURE_FOR_NON_SIGNING_CERTIFICATE", ERR_LIB_SSL, 220}, #endif + #ifdef SSL_R_SRP_A_CALC + {"SRP_A_CALC", ERR_LIB_SSL, SSL_R_SRP_A_CALC}, + #else + {"SRP_A_CALC", ERR_LIB_SSL, 361}, + #endif + #ifdef SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES + {"SRTP_COULD_NOT_ALLOCATE_PROFILES", ERR_LIB_SSL, SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES}, + #else + {"SRTP_COULD_NOT_ALLOCATE_PROFILES", ERR_LIB_SSL, 362}, + #endif + #ifdef SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG + {"SRTP_PROTECTION_PROFILE_LIST_TOO_LONG", ERR_LIB_SSL, SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG}, + #else + {"SRTP_PROTECTION_PROFILE_LIST_TOO_LONG", ERR_LIB_SSL, 363}, + #endif + #ifdef SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE + {"SRTP_UNKNOWN_PROTECTION_PROFILE", ERR_LIB_SSL, SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE}, + #else + {"SRTP_UNKNOWN_PROTECTION_PROFILE", ERR_LIB_SSL, 364}, + #endif #ifdef SSL_R_SSL23_DOING_SESSION_ID_REUSE {"SSL23_DOING_SESSION_ID_REUSE", ERR_LIB_SSL, SSL_R_SSL23_DOING_SESSION_ID_REUSE}, #else @@ -1179,6 +1379,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"SSL_LIBRARY_HAS_NO_CIPHERS", ERR_LIB_SSL, 230}, #endif + #ifdef SSL_R_SSL_NEGATIVE_LENGTH + {"SSL_NEGATIVE_LENGTH", ERR_LIB_SSL, SSL_R_SSL_NEGATIVE_LENGTH}, + #else + {"SSL_NEGATIVE_LENGTH", ERR_LIB_SSL, 372}, + #endif #ifdef SSL_R_SSL_SESSION_ID_CALLBACK_FAILED {"SSL_SESSION_ID_CALLBACK_FAILED", ERR_LIB_SSL, SSL_R_SSL_SESSION_ID_CALLBACK_FAILED}, #else @@ -1229,6 +1434,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"TLSV1_ALERT_EXPORT_RESTRICTION", ERR_LIB_SSL, 1060}, #endif + #ifdef SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK + {"TLSV1_ALERT_INAPPROPRIATE_FALLBACK", ERR_LIB_SSL, SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK}, + #else + {"TLSV1_ALERT_INAPPROPRIATE_FALLBACK", ERR_LIB_SSL, 1086}, + #endif #ifdef SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY {"TLSV1_ALERT_INSUFFICIENT_SECURITY", ERR_LIB_SSL, SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY}, #else @@ -1294,6 +1504,21 @@ static struct py_ssl_error_code error_codes[] = { #else {"TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER", ERR_LIB_SSL, 232}, #endif + #ifdef SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT + {"TLS_HEARTBEAT_PEER_DOESNT_ACCEPT", ERR_LIB_SSL, SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT}, + #else + {"TLS_HEARTBEAT_PEER_DOESNT_ACCEPT", ERR_LIB_SSL, 365}, + #endif + #ifdef SSL_R_TLS_HEARTBEAT_PENDING + {"TLS_HEARTBEAT_PENDING", ERR_LIB_SSL, SSL_R_TLS_HEARTBEAT_PENDING}, + #else + {"TLS_HEARTBEAT_PENDING", ERR_LIB_SSL, 366}, + #endif + #ifdef SSL_R_TLS_ILLEGAL_EXPORTER_LABEL + {"TLS_ILLEGAL_EXPORTER_LABEL", ERR_LIB_SSL, SSL_R_TLS_ILLEGAL_EXPORTER_LABEL}, + #else + {"TLS_ILLEGAL_EXPORTER_LABEL", ERR_LIB_SSL, 367}, + #endif #ifdef SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST {"TLS_INVALID_ECPOINTFORMAT_LIST", ERR_LIB_SSL, SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST}, #else @@ -1399,6 +1624,16 @@ static struct py_ssl_error_code error_codes[] = { #else {"UNKNOWN_CIPHER_TYPE", ERR_LIB_SSL, 249}, #endif + #ifdef SSL_R_UNKNOWN_CMD_NAME + {"UNKNOWN_CMD_NAME", ERR_LIB_SSL, SSL_R_UNKNOWN_CMD_NAME}, + #else + {"UNKNOWN_CMD_NAME", ERR_LIB_SSL, 386}, + #endif + #ifdef SSL_R_UNKNOWN_DIGEST + {"UNKNOWN_DIGEST", ERR_LIB_SSL, SSL_R_UNKNOWN_DIGEST}, + #else + {"UNKNOWN_DIGEST", ERR_LIB_SSL, 368}, + #endif #ifdef SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE {"UNKNOWN_KEY_EXCHANGE_TYPE", ERR_LIB_SSL, SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE}, #else @@ -1469,16 +1704,36 @@ static struct py_ssl_error_code error_codes[] = { #else {"UNSUPPORTED_STATUS_TYPE", ERR_LIB_SSL, 329}, #endif + #ifdef SSL_R_USE_SRTP_NOT_NEGOTIATED + {"USE_SRTP_NOT_NEGOTIATED", ERR_LIB_SSL, SSL_R_USE_SRTP_NOT_NEGOTIATED}, + #else + {"USE_SRTP_NOT_NEGOTIATED", ERR_LIB_SSL, 369}, + #endif + #ifdef SSL_R_VERSION_TOO_LOW + {"VERSION_TOO_LOW", ERR_LIB_SSL, SSL_R_VERSION_TOO_LOW}, + #else + {"VERSION_TOO_LOW", ERR_LIB_SSL, 396}, + #endif #ifdef SSL_R_WRITE_BIO_NOT_SET {"WRITE_BIO_NOT_SET", ERR_LIB_SSL, SSL_R_WRITE_BIO_NOT_SET}, #else {"WRITE_BIO_NOT_SET", ERR_LIB_SSL, 260}, #endif + #ifdef SSL_R_WRONG_CERTIFICATE_TYPE + {"WRONG_CERTIFICATE_TYPE", ERR_LIB_SSL, SSL_R_WRONG_CERTIFICATE_TYPE}, + #else + {"WRONG_CERTIFICATE_TYPE", ERR_LIB_SSL, 383}, + #endif #ifdef SSL_R_WRONG_CIPHER_RETURNED {"WRONG_CIPHER_RETURNED", ERR_LIB_SSL, SSL_R_WRONG_CIPHER_RETURNED}, #else {"WRONG_CIPHER_RETURNED", ERR_LIB_SSL, 261}, #endif + #ifdef SSL_R_WRONG_CURVE + {"WRONG_CURVE", ERR_LIB_SSL, SSL_R_WRONG_CURVE}, + #else + {"WRONG_CURVE", ERR_LIB_SSL, 378}, + #endif #ifdef SSL_R_WRONG_MESSAGE_TYPE {"WRONG_MESSAGE_TYPE", ERR_LIB_SSL, SSL_R_WRONG_MESSAGE_TYPE}, #else @@ -1499,6 +1754,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"WRONG_SIGNATURE_SIZE", ERR_LIB_SSL, 265}, #endif + #ifdef SSL_R_WRONG_SIGNATURE_TYPE + {"WRONG_SIGNATURE_TYPE", ERR_LIB_SSL, SSL_R_WRONG_SIGNATURE_TYPE}, + #else + {"WRONG_SIGNATURE_TYPE", ERR_LIB_SSL, 370}, + #endif #ifdef SSL_R_WRONG_SSL_VERSION {"WRONG_SSL_VERSION", ERR_LIB_SSL, SSL_R_WRONG_SSL_VERSION}, #else @@ -1519,6 +1779,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"X509_VERIFICATION_SETUP_PROBLEMS", ERR_LIB_SSL, 269}, #endif + #ifdef X509_R_AKID_MISMATCH + {"AKID_MISMATCH", ERR_LIB_X509, X509_R_AKID_MISMATCH}, + #else + {"AKID_MISMATCH", ERR_LIB_X509, 110}, + #endif #ifdef X509_R_BAD_X509_FILETYPE {"BAD_X509_FILETYPE", ERR_LIB_X509, X509_R_BAD_X509_FILETYPE}, #else @@ -1539,11 +1804,26 @@ static struct py_ssl_error_code error_codes[] = { #else {"CERT_ALREADY_IN_HASH_TABLE", ERR_LIB_X509, 101}, #endif + #ifdef X509_R_CRL_ALREADY_DELTA + {"CRL_ALREADY_DELTA", ERR_LIB_X509, X509_R_CRL_ALREADY_DELTA}, + #else + {"CRL_ALREADY_DELTA", ERR_LIB_X509, 127}, + #endif + #ifdef X509_R_CRL_VERIFY_FAILURE + {"CRL_VERIFY_FAILURE", ERR_LIB_X509, X509_R_CRL_VERIFY_FAILURE}, + #else + {"CRL_VERIFY_FAILURE", ERR_LIB_X509, 131}, + #endif #ifdef X509_R_ERR_ASN1_LIB {"ERR_ASN1_LIB", ERR_LIB_X509, X509_R_ERR_ASN1_LIB}, #else {"ERR_ASN1_LIB", ERR_LIB_X509, 102}, #endif + #ifdef X509_R_IDP_MISMATCH + {"IDP_MISMATCH", ERR_LIB_X509, X509_R_IDP_MISMATCH}, + #else + {"IDP_MISMATCH", ERR_LIB_X509, 128}, + #endif #ifdef X509_R_INVALID_DIRECTORY {"INVALID_DIRECTORY", ERR_LIB_X509, X509_R_INVALID_DIRECTORY}, #else @@ -1559,6 +1839,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"INVALID_TRUST", ERR_LIB_X509, 123}, #endif + #ifdef X509_R_ISSUER_MISMATCH + {"ISSUER_MISMATCH", ERR_LIB_X509, X509_R_ISSUER_MISMATCH}, + #else + {"ISSUER_MISMATCH", ERR_LIB_X509, 129}, + #endif #ifdef X509_R_KEY_TYPE_MISMATCH {"KEY_TYPE_MISMATCH", ERR_LIB_X509, X509_R_KEY_TYPE_MISMATCH}, #else @@ -1584,11 +1869,21 @@ static struct py_ssl_error_code error_codes[] = { #else {"METHOD_NOT_SUPPORTED", ERR_LIB_X509, 124}, #endif + #ifdef X509_R_NEWER_CRL_NOT_NEWER + {"NEWER_CRL_NOT_NEWER", ERR_LIB_X509, X509_R_NEWER_CRL_NOT_NEWER}, + #else + {"NEWER_CRL_NOT_NEWER", ERR_LIB_X509, 132}, + #endif #ifdef X509_R_NO_CERT_SET_FOR_US_TO_VERIFY {"NO_CERT_SET_FOR_US_TO_VERIFY", ERR_LIB_X509, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY}, #else {"NO_CERT_SET_FOR_US_TO_VERIFY", ERR_LIB_X509, 105}, #endif + #ifdef X509_R_NO_CRL_NUMBER + {"NO_CRL_NUMBER", ERR_LIB_X509, X509_R_NO_CRL_NUMBER}, + #else + {"NO_CRL_NUMBER", ERR_LIB_X509, 130}, + #endif #ifdef X509_R_PUBLIC_KEY_DECODE_ERROR {"PUBLIC_KEY_DECODE_ERROR", ERR_LIB_X509, X509_R_PUBLIC_KEY_DECODE_ERROR}, #else diff --git a/Modules/_stat.c b/Modules/_stat.c index a301fa8840c5..f6cb303500cd 100644 --- a/Modules/_stat.c +++ b/Modules/_stat.c @@ -27,9 +27,21 @@ extern "C" { #endif /* HAVE_SYS_STAT_H */ #ifdef MS_WINDOWS +#include typedef unsigned short mode_t; + +/* FILE_ATTRIBUTE_INTEGRITY_STREAM and FILE_ATTRIBUTE_NO_SCRUB_DATA + are not present in VC2010, so define them manually */ +#ifndef FILE_ATTRIBUTE_INTEGRITY_STREAM +# define FILE_ATTRIBUTE_INTEGRITY_STREAM 0x8000 +#endif + +#ifndef FILE_ATTRIBUTE_NO_SCRUB_DATA +# define FILE_ATTRIBUTE_NO_SCRUB_DATA 0x20000 #endif +#endif /* MS_WINDOWS */ + /* From Python's stat.py */ #ifndef S_IMODE # define S_IMODE 07777 @@ -473,6 +485,10 @@ ST_SIZE\n\ ST_ATIME\n\ ST_MTIME\n\ ST_CTIME\n\ +\n" + +"FILE_ATTRIBUTE_*: Windows file attribute constants\n\ + (only present on Windows)\n\ "); @@ -555,6 +571,26 @@ PyInit__stat(void) if (PyModule_AddIntConstant(m, "ST_MTIME", 8)) return NULL; if (PyModule_AddIntConstant(m, "ST_CTIME", 9)) return NULL; +#ifdef MS_WINDOWS + if (PyModule_AddIntMacro(m, FILE_ATTRIBUTE_ARCHIVE)) return NULL; + if (PyModule_AddIntMacro(m, FILE_ATTRIBUTE_COMPRESSED)) return NULL; + if (PyModule_AddIntMacro(m, FILE_ATTRIBUTE_DEVICE)) return NULL; + if (PyModule_AddIntMacro(m, FILE_ATTRIBUTE_DIRECTORY)) return NULL; + if (PyModule_AddIntMacro(m, FILE_ATTRIBUTE_ENCRYPTED)) return NULL; + if (PyModule_AddIntMacro(m, FILE_ATTRIBUTE_HIDDEN)) return NULL; + if (PyModule_AddIntMacro(m, FILE_ATTRIBUTE_INTEGRITY_STREAM)) return NULL; + if (PyModule_AddIntMacro(m, FILE_ATTRIBUTE_NORMAL)) return NULL; + if (PyModule_AddIntMacro(m, FILE_ATTRIBUTE_NOT_CONTENT_INDEXED)) return NULL; + if (PyModule_AddIntMacro(m, FILE_ATTRIBUTE_NO_SCRUB_DATA)) return NULL; + if (PyModule_AddIntMacro(m, FILE_ATTRIBUTE_OFFLINE)) return NULL; + if (PyModule_AddIntMacro(m, FILE_ATTRIBUTE_READONLY)) return NULL; + if (PyModule_AddIntMacro(m, FILE_ATTRIBUTE_REPARSE_POINT)) return NULL; + if (PyModule_AddIntMacro(m, FILE_ATTRIBUTE_SPARSE_FILE)) return NULL; + if (PyModule_AddIntMacro(m, FILE_ATTRIBUTE_SYSTEM)) return NULL; + if (PyModule_AddIntMacro(m, FILE_ATTRIBUTE_TEMPORARY)) return NULL; + if (PyModule_AddIntMacro(m, FILE_ATTRIBUTE_VIRTUAL)) return NULL; +#endif + return m; } diff --git a/Modules/_struct.c b/Modules/_struct.c index 1de94e406e18..068c5d1e1d83 100644 --- a/Modules/_struct.c +++ b/Modules/_struct.c @@ -85,8 +85,6 @@ typedef struct { char c; _Bool x; } s_bool; #define BOOL_ALIGN 0 #endif -#define STRINGIFY(x) #x - #ifdef __powerc #pragma options align=reset #endif @@ -546,8 +544,8 @@ np_short(char *p, PyObject *v, const formatdef *f) return -1; if (x < SHRT_MIN || x > SHRT_MAX){ PyErr_SetString(StructError, - "short format requires " STRINGIFY(SHRT_MIN) - " <= number <= " STRINGIFY(SHRT_MAX)); + "short format requires " Py_STRINGIFY(SHRT_MIN) + " <= number <= " Py_STRINGIFY(SHRT_MAX)); return -1; } y = (short)x; @@ -564,7 +562,8 @@ np_ushort(char *p, PyObject *v, const formatdef *f) return -1; if (x < 0 || x > USHRT_MAX){ PyErr_SetString(StructError, - "ushort format requires 0 <= number <= " STRINGIFY(USHRT_MAX)); + "ushort format requires 0 <= number <= " + Py_STRINGIFY(USHRT_MAX)); return -1; } y = (unsigned short)x; @@ -1264,7 +1263,8 @@ prepare_s(PyStructObject *self) const char *s; const char *fmt; char c; - Py_ssize_t size, len, ncodes, num, itemsize; + Py_ssize_t size, len, num, itemsize; + size_t ncodes; fmt = PyBytes_AS_STRING(self->s_format); @@ -1320,7 +1320,7 @@ prepare_s(PyStructObject *self) } /* check for overflow */ - if ((ncodes + 1) > (PY_SSIZE_T_MAX / sizeof(formatcode))) { + if ((ncodes + 1) > ((size_t)PY_SSIZE_T_MAX / sizeof(formatcode))) { PyErr_NoMemory(); return -1; } @@ -1842,8 +1842,8 @@ static PyObject * s_pack_into(PyObject *self, PyObject *args) { PyStructObject *soself; - char *buffer; - Py_ssize_t buffer_len, offset; + Py_buffer buffer; + Py_ssize_t offset; /* Validate arguments. +1 is for the first arg as buffer. */ soself = (PyStructObject *)self; @@ -1868,34 +1868,37 @@ s_pack_into(PyObject *self, PyObject *args) } /* Extract a writable memory buffer from the first argument */ - if ( PyObject_AsWriteBuffer(PyTuple_GET_ITEM(args, 0), - (void**)&buffer, &buffer_len) == -1 ) { + if (!PyArg_Parse(PyTuple_GET_ITEM(args, 0), "w*", &buffer)) return NULL; - } - assert( buffer_len >= 0 ); + assert(buffer.len >= 0); /* Extract the offset from the first argument */ offset = PyNumber_AsSsize_t(PyTuple_GET_ITEM(args, 1), PyExc_IndexError); - if (offset == -1 && PyErr_Occurred()) + if (offset == -1 && PyErr_Occurred()) { + PyBuffer_Release(&buffer); return NULL; + } /* Support negative offsets. */ if (offset < 0) - offset += buffer_len; + offset += buffer.len; /* Check boundaries */ - if (offset < 0 || (buffer_len - offset) < soself->s_size) { + if (offset < 0 || (buffer.len - offset) < soself->s_size) { PyErr_Format(StructError, "pack_into requires a buffer of at least %zd bytes", soself->s_size); + PyBuffer_Release(&buffer); return NULL; } /* Call the guts */ - if ( s_pack_internal(soself, args, 2, buffer + offset) != 0 ) { + if (s_pack_internal(soself, args, 2, (char*)buffer.buf + offset) != 0) { + PyBuffer_Release(&buffer); return NULL; } + PyBuffer_Release(&buffer); Py_RETURN_NONE; } diff --git a/Modules/_testbuffer.c b/Modules/_testbuffer.c index 0c6ef16f175f..de7b567c6973 100644 --- a/Modules/_testbuffer.c +++ b/Modules/_testbuffer.c @@ -850,7 +850,7 @@ seq_as_ssize_array(PyObject *seq, Py_ssize_t len, int is_shape) Py_ssize_t *dest; Py_ssize_t x, i; - dest = PyMem_Malloc(len * (sizeof *dest)); + dest = PyMem_New(Py_ssize_t, len); if (dest == NULL) { PyErr_NoMemory(); return NULL; @@ -1510,6 +1510,19 @@ ndarray_getbuf(NDArrayObject *self, Py_buffer *view, int flags) view->shape = NULL; } + /* Ascertain that the new buffer has the same contiguity as the exporter */ + if (ND_C_CONTIGUOUS(baseflags) != PyBuffer_IsContiguous(view, 'C') || + /* skip cast to 1-d */ + (view->format != NULL && view->shape != NULL && + ND_FORTRAN_CONTIGUOUS(baseflags) != PyBuffer_IsContiguous(view, 'F')) || + /* cast to 1-d */ + (view->format == NULL && view->shape == NULL && + !PyBuffer_IsContiguous(view, 'F'))) { + PyErr_SetString(PyExc_BufferError, + "ndarray: contiguity mismatch in getbuf()"); + return -1; + } + view->obj = (PyObject *)self; Py_INCREF(view->obj); self->head->exports++; @@ -2206,6 +2219,8 @@ ndarray_add_suboffsets(PyObject *self, PyObject *dummy) for (i = 0; i < base->ndim; i++) base->suboffsets[i] = -1; + nd->head->flags &= ~(ND_C|ND_FORTRAN); + Py_RETURN_NONE; } @@ -2469,13 +2484,12 @@ arraycmp(const Py_ssize_t *a1, const Py_ssize_t *a2, const Py_ssize_t *shape, { Py_ssize_t i; - if (ndim == 1 && shape && shape[0] == 1) { - /* This is for comparing strides: For example, the array - [175], shape=[1], strides=[-5] is considered contiguous. */ - return 1; - } for (i = 0; i < ndim; i++) { + if (shape && shape[i] <= 1) { + /* strides can differ if the dimension is less than 2 */ + continue; + } if (a1[i] != a2[i]) { return 0; } @@ -2555,30 +2569,35 @@ is_contiguous(PyObject *self, PyObject *args) PyObject *obj; PyObject *order; PyObject *ret = NULL; - Py_buffer view; + Py_buffer view, *base; char ord; if (!PyArg_ParseTuple(args, "OO", &obj, &order)) { return NULL; } - if (PyObject_GetBuffer(obj, &view, PyBUF_FULL_RO) < 0) { - PyErr_SetString(PyExc_TypeError, - "is_contiguous: object does not implement the buffer " - "protocol"); + ord = get_ascii_order(order); + if (ord == CHAR_MAX) { return NULL; } - ord = get_ascii_order(order); - if (ord == CHAR_MAX) { - goto release; + if (NDArray_Check(obj)) { + /* Skip the buffer protocol to check simple etc. buffers directly. */ + base = &((NDArrayObject *)obj)->head->base; + ret = PyBuffer_IsContiguous(base, ord) ? Py_True : Py_False; + } + else { + if (PyObject_GetBuffer(obj, &view, PyBUF_FULL_RO) < 0) { + PyErr_SetString(PyExc_TypeError, + "is_contiguous: object does not implement the buffer " + "protocol"); + return NULL; + } + ret = PyBuffer_IsContiguous(&view, ord) ? Py_True : Py_False; + PyBuffer_Release(&view); } - ret = PyBuffer_IsContiguous(&view, ord) ? Py_True : Py_False; Py_INCREF(ret); - -release: - PyBuffer_Release(&view); return ret; } diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 9662eb8f9e40..74159a7b525b 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -11,6 +11,8 @@ #include #include "structmember.h" #include "datetime.h" +#include "marshal.h" +#include #ifdef WITH_THREAD #include "pythread.h" @@ -1515,7 +1517,7 @@ unicode_aswidechar(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "Un", &unicode, &buflen)) return NULL; - buffer = PyMem_Malloc(buflen * sizeof(wchar_t)); + buffer = PyMem_New(wchar_t, buflen); if (buffer == NULL) return PyErr_NoMemory(); @@ -1718,7 +1720,7 @@ test_long_numbits(PyObject *self) {-0xffffL, 16, -1}, {0xfffffffL, 28, 1}, {-0xfffffffL, 28, -1}}; - int i; + size_t i; for (i = 0; i < Py_ARRAY_LENGTH(testcases); ++i) { size_t nbits; @@ -2467,6 +2469,108 @@ make_memoryview_from_NULL_pointer(PyObject *self) return NULL; return PyMemoryView_FromBuffer(&info); } + +static PyObject * +test_from_contiguous(PyObject* self, PyObject *noargs) +{ + int data[9] = {-1,-1,-1,-1,-1,-1,-1,-1,-1}; + int init[5] = {0, 1, 2, 3, 4}; + Py_ssize_t itemsize = sizeof(int); + Py_ssize_t shape = 5; + Py_ssize_t strides = 2 * itemsize; + Py_buffer view = { + data, + NULL, + 5 * itemsize, + itemsize, + 1, + 1, + NULL, + &shape, + &strides, + NULL, + NULL + }; + int *ptr; + int i; + + PyBuffer_FromContiguous(&view, init, view.len, 'C'); + ptr = view.buf; + for (i = 0; i < 5; i++) { + if (ptr[2*i] != i) { + PyErr_SetString(TestError, + "test_from_contiguous: incorrect result"); + return NULL; + } + } + + view.buf = &data[8]; + view.strides[0] = -2 * itemsize; + + PyBuffer_FromContiguous(&view, init, view.len, 'C'); + ptr = view.buf; + for (i = 0; i < 5; i++) { + if (*(ptr-2*i) != i) { + PyErr_SetString(TestError, + "test_from_contiguous: incorrect result"); + return NULL; + } + } + + Py_RETURN_NONE; +} + +#if (defined(__linux__) || defined(__FreeBSD__)) && defined(__GNUC__) +extern PyTypeObject _PyBytesIOBuffer_Type; + +static PyObject * +test_pep3118_obsolete_write_locks(PyObject* self, PyObject *noargs) +{ + PyTypeObject *type = &_PyBytesIOBuffer_Type; + PyObject *b; + char *dummy[1]; + int ret, match; + + /* PyBuffer_FillInfo() */ + ret = PyBuffer_FillInfo(NULL, NULL, dummy, 1, 0, PyBUF_SIMPLE); + match = PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_BufferError); + PyErr_Clear(); + if (ret != -1 || match == 0) + goto error; + + /* bytesiobuf_getbuffer() */ + b = type->tp_alloc(type, 0); + if (b == NULL) { + return NULL; + } + + ret = PyObject_GetBuffer(b, NULL, PyBUF_SIMPLE); + Py_DECREF(b); + match = PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_BufferError); + PyErr_Clear(); + if (ret != -1 || match == 0) + goto error; + + Py_RETURN_NONE; + +error: + PyErr_SetString(TestError, + "test_pep3118_obsolete_write_locks: failure"); + return NULL; +} +#endif + +/* This tests functions that historically supported write locks. It is + wrong to call getbuffer() with view==NULL and a compliant getbufferproc + is entitled to segfault in that case. */ +static PyObject * +getbuffer_with_null_view(PyObject* self, PyObject *obj) +{ + if (PyObject_GetBuffer(obj, NULL, PyBUF_SIMPLE) < 0) + return NULL; + + Py_RETURN_NONE; +} /* Test that the fatal error from not having a current thread doesn't cause an infinite loop. Run via Lib/test/test_capi.py */ @@ -2516,14 +2620,27 @@ run_in_subinterp(PyObject *self, PyObject *args) return PyLong_FromLong(r); } +static int +check_time_rounding(int round) +{ + if (round != _PyTime_ROUND_DOWN && round != _PyTime_ROUND_UP) { + PyErr_SetString(PyExc_ValueError, "invalid rounding"); + return -1; + } + return 0; +} + static PyObject * test_pytime_object_to_time_t(PyObject *self, PyObject *args) { PyObject *obj; time_t sec; - if (!PyArg_ParseTuple(args, "O:pytime_object_to_time_t", &obj)) + int round; + if (!PyArg_ParseTuple(args, "Oi:pytime_object_to_time_t", &obj, &round)) return NULL; - if (_PyTime_ObjectToTime_t(obj, &sec) == -1) + if (check_time_rounding(round) < 0) + return NULL; + if (_PyTime_ObjectToTime_t(obj, &sec, round) == -1) return NULL; return _PyLong_FromTime_t(sec); } @@ -2534,9 +2651,12 @@ test_pytime_object_to_timeval(PyObject *self, PyObject *args) PyObject *obj; time_t sec; long usec; - if (!PyArg_ParseTuple(args, "O:pytime_object_to_timeval", &obj)) + int round; + if (!PyArg_ParseTuple(args, "Oi:pytime_object_to_timeval", &obj, &round)) + return NULL; + if (check_time_rounding(round) < 0) return NULL; - if (_PyTime_ObjectToTimeval(obj, &sec, &usec) == -1) + if (_PyTime_ObjectToTimeval(obj, &sec, &usec, round) == -1) return NULL; return Py_BuildValue("Nl", _PyLong_FromTime_t(sec), usec); } @@ -2547,9 +2667,12 @@ test_pytime_object_to_timespec(PyObject *self, PyObject *args) PyObject *obj; time_t sec; long nsec; - if (!PyArg_ParseTuple(args, "O:pytime_object_to_timespec", &obj)) + int round; + if (!PyArg_ParseTuple(args, "Oi:pytime_object_to_timespec", &obj, &round)) + return NULL; + if (check_time_rounding(round) < 0) return NULL; - if (_PyTime_ObjectToTimespec(obj, &sec, &nsec) == -1) + if (_PyTime_ObjectToTimespec(obj, &sec, &nsec, round) == -1) return NULL; return Py_BuildValue("Nl", _PyLong_FromTime_t(sec), nsec); } @@ -2633,6 +2756,21 @@ with_tp_del(PyObject *self, PyObject *args) return obj; } +static PyMethodDef ml; + +static PyObject * +create_cfunction(PyObject *self, PyObject *args) +{ + return PyCFunction_NewEx(&ml, self, NULL); +} + +static PyMethodDef ml = { + "create_cfunction", + create_cfunction, + METH_NOARGS, + NULL +}; + static PyObject * _test_incref(PyObject *ob) { @@ -2680,7 +2818,7 @@ static PyObject * test_incref_decref_API(PyObject *ob) { PyObject *obj = PyLong_FromLong(0); - Py_IncRef(ob); + Py_IncRef(obj); Py_DecRef(obj); Py_DecRef(obj); Py_RETURN_NONE; @@ -2691,6 +2829,20 @@ test_pymem_alloc0(PyObject *self) { void *ptr; + ptr = PyMem_RawMalloc(0); + if (ptr == NULL) { + PyErr_SetString(PyExc_RuntimeError, "PyMem_RawMalloc(0) returns NULL"); + return NULL; + } + PyMem_RawFree(ptr); + + ptr = PyMem_RawCalloc(0, 0); + if (ptr == NULL) { + PyErr_SetString(PyExc_RuntimeError, "PyMem_RawCalloc(0, 0) returns NULL"); + return NULL; + } + PyMem_RawFree(ptr); + ptr = PyMem_Malloc(0); if (ptr == NULL) { PyErr_SetString(PyExc_RuntimeError, "PyMem_Malloc(0) returns NULL"); @@ -2698,6 +2850,13 @@ test_pymem_alloc0(PyObject *self) } PyMem_Free(ptr); + ptr = PyMem_Calloc(0, 0); + if (ptr == NULL) { + PyErr_SetString(PyExc_RuntimeError, "PyMem_Calloc(0, 0) returns NULL"); + return NULL; + } + PyMem_Free(ptr); + ptr = PyObject_Malloc(0); if (ptr == NULL) { PyErr_SetString(PyExc_RuntimeError, "PyObject_Malloc(0) returns NULL"); @@ -2705,13 +2864,22 @@ test_pymem_alloc0(PyObject *self) } PyObject_Free(ptr); + ptr = PyObject_Calloc(0, 0); + if (ptr == NULL) { + PyErr_SetString(PyExc_RuntimeError, "PyObject_Calloc(0, 0) returns NULL"); + return NULL; + } + PyObject_Free(ptr); + Py_RETURN_NONE; } typedef struct { - PyMemAllocator alloc; + PyMemAllocatorEx alloc; size_t malloc_size; + size_t calloc_nelem; + size_t calloc_elsize; void *realloc_ptr; size_t realloc_new_size; void *free_ptr; @@ -2724,6 +2892,14 @@ static void* hook_malloc (void* ctx, size_t size) return hook->alloc.malloc(hook->alloc.ctx, size); } +static void* hook_calloc (void* ctx, size_t nelem, size_t elsize) +{ + alloc_hook_t *hook = (alloc_hook_t *)ctx; + hook->calloc_nelem = nelem; + hook->calloc_elsize = elsize; + return hook->alloc.calloc(hook->alloc.ctx, nelem, elsize); +} + static void* hook_realloc (void* ctx, void* ptr, size_t new_size) { alloc_hook_t *hook = (alloc_hook_t *)ctx; @@ -2745,17 +2921,15 @@ test_setallocators(PyMemAllocatorDomain domain) PyObject *res = NULL; const char *error_msg; alloc_hook_t hook; - PyMemAllocator alloc; - size_t size, size2; + PyMemAllocatorEx alloc; + size_t size, size2, nelem, elsize; void *ptr, *ptr2; - hook.malloc_size = 0; - hook.realloc_ptr = NULL; - hook.realloc_new_size = 0; - hook.free_ptr = NULL; + memset(&hook, 0, sizeof(hook)); alloc.ctx = &hook; alloc.malloc = &hook_malloc; + alloc.calloc = &hook_calloc; alloc.realloc = &hook_realloc; alloc.free = &hook_free; PyMem_GetAllocator(domain, &hook.alloc); @@ -2812,6 +2986,33 @@ test_setallocators(PyMemAllocatorDomain domain) goto fail; } + nelem = 2; + elsize = 5; + switch(domain) + { + case PYMEM_DOMAIN_RAW: ptr = PyMem_RawCalloc(nelem, elsize); break; + case PYMEM_DOMAIN_MEM: ptr = PyMem_Calloc(nelem, elsize); break; + case PYMEM_DOMAIN_OBJ: ptr = PyObject_Calloc(nelem, elsize); break; + default: ptr = NULL; break; + } + + if (ptr == NULL) { + error_msg = "calloc failed"; + goto fail; + } + + if (hook.calloc_nelem != nelem || hook.calloc_elsize != elsize) { + error_msg = "calloc invalid nelem or elsize"; + goto fail; + } + + switch(domain) + { + case PYMEM_DOMAIN_RAW: PyMem_RawFree(ptr); break; + case PYMEM_DOMAIN_MEM: PyMem_Free(ptr); break; + case PYMEM_DOMAIN_OBJ: PyObject_Free(ptr); break; + } + Py_INCREF(Py_None); res = Py_None; goto finally; @@ -2851,24 +3052,308 @@ PyDoc_STRVAR(docstring_no_signature, ); PyDoc_STRVAR(docstring_with_invalid_signature, -"docstring_with_invalid_signature (boo)\n" +"docstring_with_invalid_signature($module, /, boo)\n" "\n" "This docstring has an invalid signature." ); +PyDoc_STRVAR(docstring_with_invalid_signature2, +"docstring_with_invalid_signature2($module, /, boo)\n" +"\n" +"--\n" +"\n" +"This docstring also has an invalid signature." +); + PyDoc_STRVAR(docstring_with_signature, -"docstring_with_signature(sig)\n" +"docstring_with_signature($module, /, sig)\n" +"--\n" +"\n" "This docstring has a valid signature." ); PyDoc_STRVAR(docstring_with_signature_and_extra_newlines, -"docstring_with_signature_and_extra_newlines(parameter)\n" -"\n" +"docstring_with_signature_and_extra_newlines($module, /, parameter)\n" +"--\n" "\n" "\n" "This docstring has a valid signature and some extra newlines." ); +PyDoc_STRVAR(docstring_with_signature_with_defaults, +"docstring_with_signature_with_defaults(module, s='avocado',\n" +" b=b'bytes', d=3.14, i=35, n=None, t=True, f=False,\n" +" local=the_number_three, sys=sys.maxsize,\n" +" exp=sys.maxsize - 1)\n" +"--\n" +"\n" +"\n" +"\n" +"This docstring has a valid signature with parameters,\n" +"and the parameters take defaults of varying types." +); + +#ifdef WITH_THREAD +typedef struct { + PyThread_type_lock start_event; + PyThread_type_lock exit_event; + PyObject *callback; +} test_c_thread_t; + +static void +temporary_c_thread(void *data) +{ + test_c_thread_t *test_c_thread = data; + PyGILState_STATE state; + PyObject *res; + + PyThread_release_lock(test_c_thread->start_event); + + /* Allocate a Python thread state for this thread */ + state = PyGILState_Ensure(); + + res = PyObject_CallFunction(test_c_thread->callback, "", NULL); + Py_CLEAR(test_c_thread->callback); + + if (res == NULL) { + PyErr_Print(); + } + else { + Py_DECREF(res); + } + + /* Destroy the Python thread state for this thread */ + PyGILState_Release(state); + + PyThread_release_lock(test_c_thread->exit_event); + + PyThread_exit_thread(); +} + +static PyObject * +call_in_temporary_c_thread(PyObject *self, PyObject *callback) +{ + PyObject *res = NULL; + test_c_thread_t test_c_thread; + long thread; + + PyEval_InitThreads(); + + test_c_thread.start_event = PyThread_allocate_lock(); + test_c_thread.exit_event = PyThread_allocate_lock(); + test_c_thread.callback = NULL; + if (!test_c_thread.start_event || !test_c_thread.exit_event) { + PyErr_SetString(PyExc_RuntimeError, "could not allocate lock"); + goto exit; + } + + Py_INCREF(callback); + test_c_thread.callback = callback; + + PyThread_acquire_lock(test_c_thread.start_event, 1); + PyThread_acquire_lock(test_c_thread.exit_event, 1); + + thread = PyThread_start_new_thread(temporary_c_thread, &test_c_thread); + if (thread == -1) { + PyErr_SetString(PyExc_RuntimeError, "unable to start the thread"); + PyThread_release_lock(test_c_thread.start_event); + PyThread_release_lock(test_c_thread.exit_event); + goto exit; + } + + PyThread_acquire_lock(test_c_thread.start_event, 1); + PyThread_release_lock(test_c_thread.start_event); + + Py_BEGIN_ALLOW_THREADS + PyThread_acquire_lock(test_c_thread.exit_event, 1); + PyThread_release_lock(test_c_thread.exit_event); + Py_END_ALLOW_THREADS + + Py_INCREF(Py_None); + res = Py_None; + +exit: + Py_CLEAR(test_c_thread.callback); + if (test_c_thread.start_event) + PyThread_free_lock(test_c_thread.start_event); + if (test_c_thread.exit_event) + PyThread_free_lock(test_c_thread.exit_event); + return res; +} +#endif /* WITH_THREAD */ + +static PyObject* +test_raise_signal(PyObject* self, PyObject *args) +{ + int signum, err; + + if (PyArg_ParseTuple(args, "i:raise_signal", &signum) < 0) + return NULL; + + err = raise(signum); + if (err) + return PyErr_SetFromErrno(PyExc_OSError); + + if (PyErr_CheckSignals() < 0) + return NULL; + + Py_RETURN_NONE; +} + +/* marshal */ + +static PyObject* +pymarshal_write_long_to_file(PyObject* self, PyObject *args) +{ + long value; + char *filename; + int version; + FILE *fp; + + if (!PyArg_ParseTuple(args, "lsi:pymarshal_write_long_to_file", + &value, &filename, &version)) + return NULL; + + fp = fopen(filename, "wb"); + if (fp == NULL) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + + PyMarshal_WriteLongToFile(value, fp, version); + + fclose(fp); + if (PyErr_Occurred()) + return NULL; + Py_RETURN_NONE; +} + +static PyObject* +pymarshal_write_object_to_file(PyObject* self, PyObject *args) +{ + PyObject *obj; + char *filename; + int version; + FILE *fp; + + if (!PyArg_ParseTuple(args, "Osi:pymarshal_write_object_to_file", + &obj, &filename, &version)) + return NULL; + + fp = fopen(filename, "wb"); + if (fp == NULL) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + + PyMarshal_WriteObjectToFile(obj, fp, version); + + fclose(fp); + if (PyErr_Occurred()) + return NULL; + Py_RETURN_NONE; +} + +static PyObject* +pymarshal_read_short_from_file(PyObject* self, PyObject *args) +{ + int value; + long pos; + char *filename; + FILE *fp; + + if (!PyArg_ParseTuple(args, "s:pymarshal_read_short_from_file", &filename)) + return NULL; + + fp = fopen(filename, "rb"); + if (fp == NULL) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + + value = PyMarshal_ReadShortFromFile(fp); + pos = ftell(fp); + + fclose(fp); + if (PyErr_Occurred()) + return NULL; + return Py_BuildValue("il", value, pos); +} + +static PyObject* +pymarshal_read_long_from_file(PyObject* self, PyObject *args) +{ + long value, pos; + char *filename; + FILE *fp; + + if (!PyArg_ParseTuple(args, "s:pymarshal_read_long_from_file", &filename)) + return NULL; + + fp = fopen(filename, "rb"); + if (fp == NULL) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + + value = PyMarshal_ReadLongFromFile(fp); + pos = ftell(fp); + + fclose(fp); + if (PyErr_Occurred()) + return NULL; + return Py_BuildValue("ll", value, pos); +} + +static PyObject* +pymarshal_read_last_object_from_file(PyObject* self, PyObject *args) +{ + PyObject *obj; + long pos; + char *filename; + FILE *fp; + + if (!PyArg_ParseTuple(args, "s:pymarshal_read_last_object_from_file", &filename)) + return NULL; + + fp = fopen(filename, "rb"); + if (fp == NULL) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + + obj = PyMarshal_ReadLastObjectFromFile(fp); + pos = ftell(fp); + + fclose(fp); + return Py_BuildValue("Nl", obj, pos); +} + +static PyObject* +pymarshal_read_object_from_file(PyObject* self, PyObject *args) +{ + PyObject *obj; + long pos; + char *filename; + FILE *fp; + + if (!PyArg_ParseTuple(args, "s:pymarshal_read_object_from_file", &filename)) + return NULL; + + fp = fopen(filename, "rb"); + if (fp == NULL) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + + obj = PyMarshal_ReadObjectFromFile(fp); + pos = ftell(fp); + + fclose(fp); + return Py_BuildValue("Nl", obj, pos); +} + + static PyMethodDef TestMethods[] = { {"raise_exception", raise_exception, METH_VARARGS}, {"raise_memoryerror", (PyCFunction)raise_memoryerror, METH_NOARGS}, @@ -2899,6 +3384,11 @@ static PyMethodDef TestMethods[] = { {"test_string_to_double", (PyCFunction)test_string_to_double, METH_NOARGS}, {"test_unicode_compare_with_ascii", (PyCFunction)test_unicode_compare_with_ascii, METH_NOARGS}, {"test_capsule", (PyCFunction)test_capsule, METH_NOARGS}, + {"test_from_contiguous", (PyCFunction)test_from_contiguous, METH_NOARGS}, +#if (defined(__linux__) || defined(__FreeBSD__)) && defined(__GNUC__) + {"test_pep3118_obsolete_write_locks", (PyCFunction)test_pep3118_obsolete_write_locks, METH_NOARGS}, +#endif + {"getbuffer_with_null_view", getbuffer_with_null_view, METH_O}, {"getargs_tuple", getargs_tuple, METH_VARARGS}, {"getargs_keywords", (PyCFunction)getargs_keywords, METH_VARARGS|METH_KEYWORDS}, @@ -2972,9 +3462,10 @@ static PyMethodDef TestMethods[] = { {"pytime_object_to_timeval", test_pytime_object_to_timeval, METH_VARARGS}, {"pytime_object_to_timespec", test_pytime_object_to_timespec, METH_VARARGS}, {"with_tp_del", with_tp_del, METH_VARARGS}, - {"test_pymem", - (PyCFunction)test_pymem_alloc0, METH_NOARGS}, + {"create_cfunction", create_cfunction, METH_NOARGS}, {"test_pymem_alloc0", + (PyCFunction)test_pymem_alloc0, METH_NOARGS}, + {"test_pymem_setrawallocators", (PyCFunction)test_pymem_setrawallocators, METH_NOARGS}, {"test_pymem_setallocators", (PyCFunction)test_pymem_setallocators, METH_NOARGS}, @@ -2991,12 +3482,36 @@ static PyMethodDef TestMethods[] = { {"docstring_with_invalid_signature", (PyCFunction)test_with_docstring, METH_NOARGS, docstring_with_invalid_signature}, + {"docstring_with_invalid_signature2", + (PyCFunction)test_with_docstring, METH_NOARGS, + docstring_with_invalid_signature2}, {"docstring_with_signature", (PyCFunction)test_with_docstring, METH_NOARGS, docstring_with_signature}, {"docstring_with_signature_and_extra_newlines", (PyCFunction)test_with_docstring, METH_NOARGS, docstring_with_signature_and_extra_newlines}, + {"docstring_with_signature_with_defaults", + (PyCFunction)test_with_docstring, METH_NOARGS, + docstring_with_signature_with_defaults}, + {"raise_signal", + (PyCFunction)test_raise_signal, METH_VARARGS}, +#ifdef WITH_THREAD + {"call_in_temporary_c_thread", call_in_temporary_c_thread, METH_O, + PyDoc_STR("set_error_class(error_class) -> None")}, +#endif + {"pymarshal_write_long_to_file", + pymarshal_write_long_to_file, METH_VARARGS}, + {"pymarshal_write_object_to_file", + pymarshal_write_object_to_file, METH_VARARGS}, + {"pymarshal_read_short_from_file", + pymarshal_read_short_from_file, METH_VARARGS}, + {"pymarshal_read_long_from_file", + pymarshal_read_long_from_file, METH_VARARGS}, + {"pymarshal_read_last_object_from_file", + pymarshal_read_last_object_from_file, METH_VARARGS}, + {"pymarshal_read_object_from_file", + pymarshal_read_object_from_file, METH_VARARGS}, {NULL, NULL} /* sentinel */ }; @@ -3156,6 +3671,109 @@ static PyTypeObject test_structmembersType = { }; +typedef struct { + PyObject_HEAD +} matmulObject; + +static PyObject * +matmulType_matmul(PyObject *self, PyObject *other) +{ + return Py_BuildValue("(sOO)", "matmul", self, other); +} + +static PyObject * +matmulType_imatmul(PyObject *self, PyObject *other) +{ + return Py_BuildValue("(sOO)", "imatmul", self, other); +} + +static void +matmulType_dealloc(PyObject *self) +{ + Py_TYPE(self)->tp_free(self); +} + +static PyNumberMethods matmulType_as_number = { + 0, /* nb_add */ + 0, /* nb_subtract */ + 0, /* nb_multiply */ + 0, /* nb_remainde r*/ + 0, /* nb_divmod */ + 0, /* nb_power */ + 0, /* nb_negative */ + 0, /* tp_positive */ + 0, /* tp_absolute */ + 0, /* tp_bool */ + 0, /* nb_invert */ + 0, /* nb_lshift */ + 0, /* nb_rshift */ + 0, /* nb_and */ + 0, /* nb_xor */ + 0, /* nb_or */ + 0, /* nb_int */ + 0, /* nb_reserved */ + 0, /* nb_float */ + 0, /* nb_inplace_add */ + 0, /* nb_inplace_subtract */ + 0, /* nb_inplace_multiply */ + 0, /* nb_inplace_remainder */ + 0, /* nb_inplace_power */ + 0, /* nb_inplace_lshift */ + 0, /* nb_inplace_rshift */ + 0, /* nb_inplace_and */ + 0, /* nb_inplace_xor */ + 0, /* nb_inplace_or */ + 0, /* nb_floor_divide */ + 0, /* nb_true_divide */ + 0, /* nb_inplace_floor_divide */ + 0, /* nb_inplace_true_divide */ + 0, /* nb_index */ + matmulType_matmul, /* nb_matrix_multiply */ + matmulType_imatmul /* nb_matrix_inplace_multiply */ +}; + +static PyTypeObject matmulType = { + PyVarObject_HEAD_INIT(NULL, 0) + "matmulType", + sizeof(matmulObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + matmulType_dealloc, /* destructor tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + &matmulType_as_number, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + PyObject_GenericSetAttr, /* tp_setattro */ + 0, /* tp_as_buffer */ + 0, /* tp_flags */ + "C level type with matrix operations defined", + 0, /* traverseproc tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + PyType_GenericNew, /* tp_new */ + PyObject_Del, /* tp_free */ +}; + static struct PyModuleDef _testcapimodule = { PyModuleDef_HEAD_INIT, @@ -3185,6 +3803,10 @@ PyInit__testcapi(void) /* don't use a name starting with "test", since we don't want test_capi to automatically call this */ PyModule_AddObject(m, "_test_structmembersType", (PyObject *)&test_structmembersType); + if (PyType_Ready(&matmulType) < 0) + return NULL; + Py_INCREF(&matmulType); + PyModule_AddObject(m, "matmulType", (PyObject *)&matmulType); PyModule_AddObject(m, "CHAR_MAX", PyLong_FromLong(CHAR_MAX)); PyModule_AddObject(m, "CHAR_MIN", PyLong_FromLong(CHAR_MIN)); @@ -3211,6 +3833,8 @@ PyInit__testcapi(void) Py_INCREF(&PyInstanceMethod_Type); PyModule_AddObject(m, "instancemethod", (PyObject *)&PyInstanceMethod_Type); + PyModule_AddIntConstant(m, "the_number_three", 3); + TestError = PyErr_NewException("_testcapi.error", NULL, NULL); Py_INCREF(TestError); PyModule_AddObject(m, "error", TestError); diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c index ab0fea44e419..8f59e036b9c8 100644 --- a/Modules/_threadmodule.c +++ b/Modules/_threadmodule.c @@ -57,7 +57,7 @@ acquire_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds) if (microseconds > 0) { - _PyTime_gettimeofday(&endtime); + _PyTime_monotonic(&endtime); endtime.tv_sec += microseconds / (1000 * 1000); endtime.tv_usec += microseconds % (1000 * 1000); } @@ -83,7 +83,7 @@ acquire_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds) /* If we're using a timeout, recompute the timeout after processing * signals, since those can take time. */ if (microseconds > 0) { - _PyTime_gettimeofday(&curtime); + _PyTime_monotonic(&curtime); microseconds = ((endtime.tv_sec - curtime.tv_sec) * 1000000 + (endtime.tv_usec - curtime.tv_usec)); @@ -192,6 +192,13 @@ PyDoc_STRVAR(locked_doc, \n\ Return whether the lock is in the locked state."); +static PyObject * +lock_repr(lockobject *self) +{ + return PyUnicode_FromFormat("<%s %s object at %p>", + self->locked ? "locked" : "unlocked", Py_TYPE(self)->tp_name, self); +} + static PyMethodDef lock_methods[] = { {"acquire_lock", (PyCFunction)lock_PyThread_acquire_lock, METH_VARARGS | METH_KEYWORDS, acquire_doc}, @@ -223,7 +230,7 @@ static PyTypeObject Locktype = { 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_reserved*/ - 0, /*tp_repr*/ + (reprfunc)lock_repr, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ @@ -379,13 +386,13 @@ current thread, release() needs to be called as many times for the lock\n\ to be available for other threads."); static PyObject * -rlock_acquire_restore(rlockobject *self, PyObject *arg) +rlock_acquire_restore(rlockobject *self, PyObject *args) { long owner; unsigned long count; int r = 1; - if (!PyArg_ParseTuple(arg, "kl:_acquire_restore", &count, &owner)) + if (!PyArg_ParseTuple(args, "(kl):_acquire_restore", &count, &owner)) return NULL; if (!PyThread_acquire_lock(self->rlock_lock, 0)) { @@ -475,8 +482,10 @@ rlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds) static PyObject * rlock_repr(rlockobject *self) { - return PyUnicode_FromFormat("<%s owner=%ld count=%lu>", - Py_TYPE(self)->tp_name, self->rlock_owner, self->rlock_count); + return PyUnicode_FromFormat("<%s %s object owner=%ld count=%lu at %p>", + self->rlock_count ? "locked" : "unlocked", + Py_TYPE(self)->tp_name, self->rlock_owner, + self->rlock_count, self); } @@ -488,7 +497,7 @@ static PyMethodDef rlock_methods[] = { {"_is_owned", (PyCFunction)rlock_is_owned, METH_NOARGS, rlock_is_owned_doc}, {"_acquire_restore", (PyCFunction)rlock_acquire_restore, - METH_O, rlock_acquire_restore_doc}, + METH_VARARGS, rlock_acquire_restore_doc}, {"_release_save", (PyCFunction)rlock_release_save, METH_NOARGS, rlock_release_save_doc}, {"__enter__", (PyCFunction)rlock_acquire, diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c index e022a7a7e156..b23ee8a66510 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -9,8 +9,8 @@ Copyright (C) 1994 Steen Lumholt. /* TCL/TK VERSION INFO: - Only Tcl/Tk 8.3.1 and later are supported. Older versions are not - supported. Use Python 2.6 or older if you cannot upgrade your + Only Tcl/Tk 8.4 and later are supported. Older versions are not + supported. Use Python 3.4 or older if you cannot upgrade your Tcl/Tk libraries. */ @@ -21,6 +21,7 @@ Copyright (C) 1994 Steen Lumholt. */ +#define PY_SSIZE_T_CLEAN #include "Python.h" #include @@ -33,29 +34,8 @@ Copyright (C) 1994 Steen Lumholt. #include #endif -/* Allow using this code in Python 2.[12] */ -#ifndef PyDoc_STRVAR -#define PyDoc_STRVAR(name,str) static char name[] = str -#endif - -#ifndef PyMODINIT_FUNC -#define PyMODINIT_FUNC void -#endif - -#ifndef PyBool_Check -#define PyBool_Check(o) 0 -#define PyBool_FromLong PyLong_FromLong -#endif - #define CHECK_SIZE(size, elemsize) \ - ((size_t)(size) <= Py_MAX((size_t)INT_MAX, UINT_MAX / (size_t)(elemsize))) - -/* Starting with Tcl 8.4, many APIs offer const-correctness. Unfortunately, - making _tkinter correct for this API means to break earlier - versions. USE_COMPAT_CONST allows to make _tkinter work with both 8.4 and - earlier versions. Once Tcl releases before 8.4 don't need to be supported - anymore, this should go. */ -#define USE_COMPAT_CONST + ((size_t)(size) <= Py_MIN((size_t)INT_MAX, UINT_MAX / (size_t)(elemsize))) /* If Tcl is compiled for threads, we must also define TCL_THREAD. We define it always; if Tcl is not threaded, the thread functions in @@ -72,15 +52,8 @@ Copyright (C) 1994 Steen Lumholt. #include "tkinter.h" -/* For Tcl 8.2 and 8.3, CONST* is not defined (except on Cygwin). */ -#ifndef CONST84_RETURN -#define CONST84_RETURN -#undef CONST -#define CONST -#endif - -#if TK_VERSION_HEX < 0x08030102 -#error "Tk older than 8.3.1 not supported" +#if TK_VERSION_HEX < 0x08040002 +#error "Tk older than 8.4 not supported" #endif #if !(defined(MS_WINDOWS) || defined(__CYGWIN__)) @@ -256,13 +229,13 @@ typedef struct { int dispatching; /* We cannot include tclInt.h, as this is internal. So we cache interesting types here. */ - Tcl_ObjType *BooleanType; - Tcl_ObjType *ByteArrayType; - Tcl_ObjType *DoubleType; - Tcl_ObjType *IntType; - Tcl_ObjType *ListType; - Tcl_ObjType *ProcBodyType; - Tcl_ObjType *StringType; + const Tcl_ObjType *BooleanType; + const Tcl_ObjType *ByteArrayType; + const Tcl_ObjType *DoubleType; + const Tcl_ObjType *IntType; + const Tcl_ObjType *ListType; + const Tcl_ObjType *ProcBodyType; + const Tcl_ObjType *StringType; } TkappObject; #define Tkapp_Interp(v) (((TkappObject *) (v))->interp) @@ -343,10 +316,57 @@ WaitForMainloop(TkappObject* self) static PyObject * -Split(char *list) +unicodeFromTclStringAndSize(const char *s, Py_ssize_t size) +{ + PyObject *r = PyUnicode_DecodeUTF8(s, size, NULL); + if (!r && PyErr_ExceptionMatches(PyExc_UnicodeDecodeError)) { + /* Tcl encodes null character as \xc0\x80 */ + if (memchr(s, '\xc0', size)) { + char *buf, *q; + const char *e = s + size; + PyErr_Clear(); + q = buf = (char *)PyMem_Malloc(size); + if (buf == NULL) { + PyErr_NoMemory(); + return NULL; + } + while (s != e) { + if (s + 1 != e && s[0] == '\xc0' && s[1] == '\x80') { + *q++ = '\0'; + s += 2; + } + else + *q++ = *s++; + } + s = buf; + size = q - s; + r = PyUnicode_DecodeUTF8(s, size, NULL); + PyMem_Free(buf); + } + } + return r; +} + +static PyObject * +unicodeFromTclString(const char *s) +{ + return unicodeFromTclStringAndSize(s, strlen(s)); +} + +static PyObject * +unicodeFromTclObj(Tcl_Obj *value) +{ + int len; + char *s = Tcl_GetStringFromObj(value, &len); + return unicodeFromTclStringAndSize(s, len); +} + + +static PyObject * +Split(const char *list) { int argc; - char **argv; + const char **argv; PyObject *v; if (list == NULL) { @@ -358,13 +378,13 @@ Split(char *list) * Could be a quoted string containing funnies, e.g. {"}. * Return the string itself. */ - return PyUnicode_FromString(list); + return unicodeFromTclString(list); } if (argc == 0) v = PyUnicode_FromString(""); else if (argc == 1) - v = PyUnicode_FromString(argv[0]); + v = unicodeFromTclString(argv[0]); else if ((v = PyTuple_New(argc)) != NULL) { int i; PyObject *w; @@ -390,7 +410,7 @@ static PyObject * SplitObj(PyObject *arg) { if (PyTuple_Check(arg)) { - int i, size; + Py_ssize_t i, size; PyObject *elem, *newelem, *result; size = PyTuple_Size(arg); @@ -406,7 +426,7 @@ SplitObj(PyObject *arg) return NULL; } if (!result) { - int k; + Py_ssize_t k; if (newelem == elem) { Py_DECREF(newelem); continue; @@ -426,9 +446,29 @@ SplitObj(PyObject *arg) return result; /* Fall through, returning arg. */ } + else if (PyList_Check(arg)) { + Py_ssize_t i, size; + PyObject *elem, *newelem, *result; + + size = PyList_GET_SIZE(arg); + result = PyTuple_New(size); + if (!result) + return NULL; + /* Recursively invoke SplitObj for all list items. */ + for(i = 0; i < size; i++) { + elem = PyList_GET_ITEM(arg, i); + newelem = SplitObj(elem); + if (!newelem) { + Py_XDECREF(result); + return NULL; + } + PyTuple_SetItem(result, i, newelem); + } + return result; + } else if (PyUnicode_Check(arg)) { int argc; - char **argv; + const char **argv; char *list = PyUnicode_AsUTF8(arg); if (list == NULL || @@ -443,7 +483,7 @@ SplitObj(PyObject *arg) } else if (PyBytes_Check(arg)) { int argc; - char **argv; + const char **argv; char *list = PyBytes_AsString(arg); if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) { @@ -510,8 +550,9 @@ static void EnableEventHook(void); /* Forward */ static void DisableEventHook(void); /* Forward */ static TkappObject * -Tkapp_New(char *screenName, char *className, - int interactive, int wantobjects, int wantTk, int sync, char *use) +Tkapp_New(const char *screenName, const char *className, + int interactive, int wantobjects, int wantTk, int sync, + const char *use) { TkappObject *v; char *argv0; @@ -565,7 +606,7 @@ Tkapp_New(char *screenName, char *className, Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY); /* This is used to get the application class for Tk 4.1 and up */ - argv0 = (char*)ckalloc(strlen(className) + 1); + argv0 = (char*)PyMem_Malloc(strlen(className) + 1); if (!argv0) { PyErr_NoMemory(); Py_DECREF(v); @@ -576,7 +617,7 @@ Tkapp_New(char *screenName, char *className, if (Py_ISUPPER(Py_CHARMASK(argv0[0]))) argv0[0] = Py_TOLOWER(Py_CHARMASK(argv0[0])); Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY); - ckfree(argv0); + PyMem_Free(argv0); if (! wantTk) { Tcl_SetVar(v->interp, @@ -592,14 +633,14 @@ Tkapp_New(char *screenName, char *className, /* some initial arguments need to be in argv */ if (sync || use) { char *args; - int len = 0; + Py_ssize_t len = 0; if (sync) len += sizeof "-sync"; if (use) - len += strlen(use) + sizeof "-use "; + len += strlen(use) + sizeof "-use "; /* never overflows */ - args = (char*)ckalloc(len); + args = (char*)PyMem_Malloc(len); if (!args) { PyErr_NoMemory(); Py_DECREF(v); @@ -617,7 +658,7 @@ Tkapp_New(char *screenName, char *className, } Tcl_SetVar(v->interp, "argv", args, TCL_GLOBAL_ONLY); - ckfree(args); + PyMem_Free(args); } if (Tcl_AppInit(v->interp) != TCL_OK) { @@ -708,11 +749,8 @@ PyDoc_STRVAR(PyTclObject_string__doc__, static PyObject * PyTclObject_string(PyTclObject *self, void *ignored) { - char *s; - int len; if (!self->string) { - s = Tcl_GetStringFromObj(self->value, &len); - self->string = PyUnicode_FromStringAndSize(s, len); + self->string = unicodeFromTclObj(self->value); if (!self->string) return NULL; } @@ -723,15 +761,12 @@ PyTclObject_string(PyTclObject *self, void *ignored) static PyObject * PyTclObject_str(PyTclObject *self, void *ignored) { - char *s; - int len; - if (self->string && PyUnicode_Check(self->string)) { + if (self->string) { Py_INCREF(self->string); return self->string; } /* XXX Could chache result if it is non-ASCII. */ - s = Tcl_GetStringFromObj(self->value, &len); - return PyUnicode_DecodeUTF8(s, len, "strict"); + return unicodeFromTclObj(self->value); } static PyObject * @@ -806,7 +841,7 @@ PyDoc_STRVAR(get_typename__doc__, "name of the Tcl type"); static PyObject* get_typename(PyTclObject* obj, void* ignored) { - return PyUnicode_FromString(obj->value->typePtr->name); + return unicodeFromTclString(obj->value->typePtr->name); } @@ -836,6 +871,16 @@ static PyType_Spec PyTclObject_Type_spec = { }; +#if PY_SIZE_MAX > INT_MAX +#define CHECK_STRING_LENGTH(s) do { \ + if (s != NULL && strlen(s) >= INT_MAX) { \ + PyErr_SetString(PyExc_OverflowError, "string is too long"); \ + return NULL; \ + } } while(0) +#else +#define CHECK_STRING_LENGTH(s) +#endif + static Tcl_Obj* AsObj(PyObject *value) { @@ -843,9 +888,14 @@ AsObj(PyObject *value) long longVal; int overflow; - if (PyBytes_Check(value)) - return Tcl_NewStringObj(PyBytes_AS_STRING(value), - PyBytes_GET_SIZE(value)); + if (PyBytes_Check(value)) { + if (PyBytes_GET_SIZE(value) >= INT_MAX) { + PyErr_SetString(PyExc_OverflowError, "bytes object is too long"); + return NULL; + } + return Tcl_NewByteArrayObj((unsigned char *)PyBytes_AS_STRING(value), + (int)PyBytes_GET_SIZE(value)); + } else if (PyBool_Check(value)) return Tcl_NewBooleanObj(PyObject_IsTrue(value)); else if (PyLong_CheckExact(value) && @@ -857,22 +907,28 @@ AsObj(PyObject *value) } else if (PyFloat_Check(value)) return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value)); - else if (PyTuple_Check(value)) { + else if (PyTuple_Check(value) || PyList_Check(value)) { Tcl_Obj **argv; Py_ssize_t size, i; - size = PyTuple_Size(value); + size = PySequence_Fast_GET_SIZE(value); + if (size == 0) + return Tcl_NewListObj(0, NULL); if (!CHECK_SIZE(size, sizeof(Tcl_Obj *))) { - PyErr_SetString(PyExc_OverflowError, "tuple is too long"); + PyErr_SetString(PyExc_OverflowError, + PyTuple_Check(value) ? "tuple is too long" : + "list is too long"); return NULL; } - argv = (Tcl_Obj **) ckalloc(((size_t)size) * sizeof(Tcl_Obj *)); - if(!argv) - return 0; + argv = (Tcl_Obj **) PyMem_Malloc(((size_t)size) * sizeof(Tcl_Obj *)); + if (!argv) { + PyErr_NoMemory(); + return NULL; + } for (i = 0; i < size; i++) - argv[i] = AsObj(PyTuple_GetItem(value,i)); - result = Tcl_NewListObj(PyTuple_Size(value), argv); - ckfree(FREECAST argv); + argv[i] = AsObj(PySequence_Fast_GET_ITEM(value,i)); + result = Tcl_NewListObj((int)size, argv); + PyMem_Free(argv); return result; } else if (PyUnicode_Check(value)) { @@ -888,13 +944,17 @@ AsObj(PyObject *value) inbuf = PyUnicode_DATA(value); size = PyUnicode_GET_LENGTH(value); + if (size == 0) + return Tcl_NewUnicodeObj((const void *)"", 0); if (!CHECK_SIZE(size, sizeof(Tcl_UniChar))) { PyErr_SetString(PyExc_OverflowError, "string is too long"); return NULL; } kind = PyUnicode_KIND(value); + if (kind == sizeof(Tcl_UniChar)) + return Tcl_NewUnicodeObj(inbuf, (int)size); allocsize = ((size_t)size) * sizeof(Tcl_UniChar); - outbuf = (Tcl_UniChar*)ckalloc(allocsize); + outbuf = (Tcl_UniChar*)PyMem_Malloc(allocsize); /* Else overflow occurred, and we take the next exit */ if (!outbuf) { PyErr_NoMemory(); @@ -911,14 +971,14 @@ AsObj(PyObject *value) "character U+%x is above the range " "(U+0000-U+FFFF) allowed by Tcl", ch); - ckfree(FREECAST outbuf); + PyMem_Free(outbuf); return NULL; } #endif outbuf[i] = ch; } - result = Tcl_NewUnicodeObj(outbuf, size); - ckfree(FREECAST outbuf); + result = Tcl_NewUnicodeObj(outbuf, (int)size); + PyMem_Free(outbuf); return result; } else if(PyTclObject_Check(value)) { @@ -943,8 +1003,7 @@ FromObj(PyObject* tkapp, Tcl_Obj *value) TkappObject *app = (TkappObject*)tkapp; if (value->typePtr == NULL) { - return PyUnicode_FromStringAndSize(value->bytes, - value->length); + return unicodeFromTclStringAndSize(value->bytes, value->length); } if (value->typePtr == app->BooleanType) { @@ -1001,15 +1060,9 @@ FromObj(PyObject* tkapp, Tcl_Obj *value) } if (value->typePtr == app->StringType) { -#if TCL_UTF_MAX==3 return PyUnicode_FromKindAndData( - PyUnicode_2BYTE_KIND, Tcl_GetUnicode(value), + sizeof(Tcl_UniChar), Tcl_GetUnicode(value), Tcl_GetCharLength(value)); -#else - return PyUnicode_FromKindAndData( - PyUnicode_4BYTE_KIND, Tcl_GetUnicode(value), - Tcl_GetCharLength(value)); -#endif } return newPyTclObject(value); @@ -1037,7 +1090,7 @@ Tkapp_CallDeallocArgs(Tcl_Obj** objv, Tcl_Obj** objStore, int objc) for (i = 0; i < objc; i++) Tcl_DecrRefCount(objv[i]); if (objv != objStore) - ckfree(FREECAST objv); + PyMem_Free(objv); } /* Convert Python objects to Tcl objects. This must happen in the @@ -1051,7 +1104,7 @@ Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc) if (args == NULL) /* do nothing */; - else if (!PyTuple_Check(args)) { + else if (!(PyTuple_Check(args) || PyList_Check(args))) { objv[0] = AsObj(args); if (objv[0] == 0) goto finally; @@ -1059,14 +1112,16 @@ Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc) Tcl_IncrRefCount(objv[0]); } else { - objc = PyTuple_Size(args); + objc = PySequence_Fast_GET_SIZE(args); if (objc > ARGSZ) { if (!CHECK_SIZE(objc, sizeof(Tcl_Obj *))) { - PyErr_SetString(PyExc_OverflowError, "tuple is too long"); + PyErr_SetString(PyExc_OverflowError, + PyTuple_Check(args) ? "tuple is too long" : + "list is too long"); return NULL; } - objv = (Tcl_Obj **)ckalloc(((size_t)objc) * sizeof(Tcl_Obj *)); + objv = (Tcl_Obj **)PyMem_Malloc(((size_t)objc) * sizeof(Tcl_Obj *)); if (objv == NULL) { PyErr_NoMemory(); objc = 0; @@ -1075,7 +1130,7 @@ Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc) } for (i = 0; i < objc; i++) { - PyObject *v = PyTuple_GetItem(args, i); + PyObject *v = PySequence_Fast_GET_ITEM(args, i); if (v == Py_None) { objc = i; break; @@ -1090,10 +1145,10 @@ Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc) Tcl_IncrRefCount(objv[i]); } } - *pobjc = objc; + *pobjc = (int)objc; return objv; finally: - Tkapp_CallDeallocArgs(objv, objStore, objc); + Tkapp_CallDeallocArgs(objv, objStore, (int)objc); return NULL; } @@ -1103,8 +1158,8 @@ static PyObject* Tkapp_CallResult(TkappObject *self) { PyObject *res = NULL; + Tcl_Obj *value = Tcl_GetObjResult(self->interp); if(self->wantobjects) { - Tcl_Obj *value = Tcl_GetObjResult(self->interp); /* Not sure whether the IncrRef is necessary, but something may overwrite the interpreter result while we are converting it. */ @@ -1112,7 +1167,7 @@ Tkapp_CallResult(TkappObject *self) res = FromObj((PyObject*)self, value); Tcl_DecrRefCount(value); } else { - res = PyUnicode_FromString(Tcl_GetStringResult(self->interp)); + res = unicodeFromTclObj(value); } return res; } @@ -1202,7 +1257,11 @@ Tkapp_Call(PyObject *selfptr, PyObject *args) PyObject *exc_type, *exc_value, *exc_tb; if (!WaitForMainloop(self)) return NULL; - ev = (Tkapp_CallEvent*)ckalloc(sizeof(Tkapp_CallEvent)); + ev = (Tkapp_CallEvent*)attemptckalloc(sizeof(Tkapp_CallEvent)); + if (ev == NULL) { + PyErr_NoMemory(); + return NULL; + } ev->ev.proc = (Tcl_EventProc*)Tkapp_CallProc; ev->self = self; ev->args = args; @@ -1259,6 +1318,7 @@ Tkapp_Eval(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "s:eval", &script)) return NULL; + CHECK_STRING_LENGTH(script); CHECK_TCL_APPARTMENT; ENTER_TCL @@ -1267,7 +1327,7 @@ Tkapp_Eval(PyObject *self, PyObject *args) if (err == TCL_ERROR) res = Tkinter_Error(self); else - res = PyUnicode_FromString(Tkapp_Result(self)); + res = unicodeFromTclString(Tkapp_Result(self)); LEAVE_OVERLAP_TCL return res; } @@ -1282,6 +1342,7 @@ Tkapp_EvalFile(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "s:evalfile", &fileName)) return NULL; + CHECK_STRING_LENGTH(fileName); CHECK_TCL_APPARTMENT; ENTER_TCL @@ -1289,9 +1350,8 @@ Tkapp_EvalFile(PyObject *self, PyObject *args) ENTER_OVERLAP if (err == TCL_ERROR) res = Tkinter_Error(self); - else - res = PyUnicode_FromString(Tkapp_Result(self)); + res = unicodeFromTclString(Tkapp_Result(self)); LEAVE_OVERLAP_TCL return res; } @@ -1303,9 +1363,10 @@ Tkapp_Record(PyObject *self, PyObject *args) PyObject *res = NULL; int err; - if (!PyArg_ParseTuple(args, "s", &script)) + if (!PyArg_ParseTuple(args, "s:record", &script)) return NULL; + CHECK_STRING_LENGTH(script); CHECK_TCL_APPARTMENT; ENTER_TCL @@ -1314,7 +1375,7 @@ Tkapp_Record(PyObject *self, PyObject *args) if (err == TCL_ERROR) res = Tkinter_Error(self); else - res = PyUnicode_FromString(Tkapp_Result(self)); + res = unicodeFromTclString(Tkapp_Result(self)); LEAVE_OVERLAP_TCL return res; } @@ -1326,6 +1387,7 @@ Tkapp_AddErrorInfo(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg)) return NULL; + CHECK_STRING_LENGTH(msg); CHECK_TCL_APPARTMENT; ENTER_TCL @@ -1360,20 +1422,45 @@ typedef struct VarEvent { static int varname_converter(PyObject *in, void *_out) { + char *s; char **out = (char**)_out; if (PyBytes_Check(in)) { - *out = PyBytes_AsString(in); + if (PyBytes_Size(in) > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, "bytes object is too long"); + return 0; + } + s = PyBytes_AsString(in); + if (strlen(s) != (size_t)PyBytes_Size(in)) { + PyErr_SetString(PyExc_ValueError, "embedded null byte"); + return 0; + } + *out = s; return 1; } if (PyUnicode_Check(in)) { - *out = _PyUnicode_AsString(in); + Py_ssize_t size; + s = PyUnicode_AsUTF8AndSize(in, &size); + if (s == NULL) { + return 0; + } + if (size > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, "string is too long"); + return 0; + } + if (strlen(s) != (size_t)size) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + return 0; + } + *out = s; return 1; } if (PyTclObject_Check(in)) { *out = PyTclObject_TclString(in); return 1; } - /* XXX: Should give diagnostics. */ + PyErr_Format(PyExc_TypeError, + "must be str, bytes or Tcl_Obj, not %.50s", + in->ob_type->tp_name); return 0; } @@ -1414,7 +1501,6 @@ var_invoke(EventFunc func, PyObject *selfptr, PyObject *args, int flags) #ifdef WITH_THREAD TkappObject *self = (TkappObject*)selfptr; if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) { - TkappObject *self = (TkappObject*)selfptr; VarEvent *ev; PyObject *res, *exc_type, *exc_val; Tcl_Condition cond = NULL; @@ -1425,8 +1511,11 @@ var_invoke(EventFunc func, PyObject *selfptr, PyObject *args, int flags) if (!WaitForMainloop(self)) return NULL; - ev = (VarEvent*)ckalloc(sizeof(VarEvent)); - + ev = (VarEvent*)attemptckalloc(sizeof(VarEvent)); + if (ev == NULL) { + PyErr_NoMemory(); + return NULL; + } ev->self = selfptr; ev->args = args; ev->flags = flags; @@ -1459,8 +1548,11 @@ SetVar(PyObject *self, PyObject *args, int flags) PyObject *res = NULL; Tcl_Obj *newval, *ok; - if (PyArg_ParseTuple(args, "O&O:setvar", - varname_converter, &name1, &newValue)) { + switch (PyTuple_GET_SIZE(args)) { + case 2: + if (!PyArg_ParseTuple(args, "O&O:setvar", + varname_converter, &name1, &newValue)) + return NULL; /* XXX Acquire tcl lock??? */ newval = AsObj(newValue); if (newval == NULL) @@ -1476,27 +1568,29 @@ SetVar(PyObject *self, PyObject *args, int flags) Py_INCREF(res); } LEAVE_OVERLAP_TCL - } - else { - PyErr_Clear(); - if (PyArg_ParseTuple(args, "ssO:setvar", - &name1, &name2, &newValue)) { - /* XXX must hold tcl lock already??? */ - newval = AsObj(newValue); - ENTER_TCL - ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, name2, newval, flags); - ENTER_OVERLAP - if (!ok) - Tkinter_Error(self); - else { - res = Py_None; - Py_INCREF(res); - } - LEAVE_OVERLAP_TCL - } - else { + break; + case 3: + if (!PyArg_ParseTuple(args, "ssO:setvar", + &name1, &name2, &newValue)) return NULL; + CHECK_STRING_LENGTH(name1); + CHECK_STRING_LENGTH(name2); + /* XXX must hold tcl lock already??? */ + newval = AsObj(newValue); + ENTER_TCL + ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, name2, newval, flags); + ENTER_OVERLAP + if (!ok) + Tkinter_Error(self); + else { + res = Py_None; + Py_INCREF(res); } + LEAVE_OVERLAP_TCL + break; + default: + PyErr_SetString(PyExc_TypeError, "setvar requires 2 to 3 arguments"); + return NULL; } return res; } @@ -1526,6 +1620,7 @@ GetVar(PyObject *self, PyObject *args, int flags) varname_converter, &name1, &name2)) return NULL; + CHECK_STRING_LENGTH(name2); ENTER_TCL tres = Tcl_GetVar2Ex(Tkapp_Interp(self), name1, name2, flags); ENTER_OVERLAP @@ -1537,7 +1632,7 @@ GetVar(PyObject *self, PyObject *args, int flags) res = FromObj(self, tres); } else { - res = PyUnicode_FromString(Tcl_GetString(tres)); + res = unicodeFromTclObj(tres); } } LEAVE_OVERLAP_TCL @@ -1568,6 +1663,8 @@ UnsetVar(PyObject *self, PyObject *args, int flags) if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2)) return NULL; + CHECK_STRING_LENGTH(name1); + CHECK_STRING_LENGTH(name2); ENTER_TCL code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags); ENTER_OVERLAP @@ -1613,6 +1710,7 @@ Tkapp_GetInt(PyObject *self, PyObject *args) } if (!PyArg_ParseTuple(args, "s:getint", &s)) return NULL; + CHECK_STRING_LENGTH(s); if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR) return Tkinter_Error(self); return Py_BuildValue("i", v); @@ -1633,6 +1731,7 @@ Tkapp_GetDouble(PyObject *self, PyObject *args) } if (!PyArg_ParseTuple(args, "s:getdouble", &s)) return NULL; + CHECK_STRING_LENGTH(s); if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR) return Tkinter_Error(self); return Py_BuildValue("d", v); @@ -1653,6 +1752,7 @@ Tkapp_GetBoolean(PyObject *self, PyObject *args) } if (!PyArg_ParseTuple(args, "s:getboolean", &s)) return NULL; + CHECK_STRING_LENGTH(s); if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR) return Tkinter_Error(self); return PyBool_FromLong(v); @@ -1668,6 +1768,7 @@ Tkapp_ExprString(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "s:exprstring", &s)) return NULL; + CHECK_STRING_LENGTH(s); CHECK_TCL_APPARTMENT; ENTER_TCL @@ -1676,7 +1777,7 @@ Tkapp_ExprString(PyObject *self, PyObject *args) if (retval == TCL_ERROR) res = Tkinter_Error(self); else - res = Py_BuildValue("s", Tkapp_Result(self)); + res = unicodeFromTclString(Tkapp_Result(self)); LEAVE_OVERLAP_TCL return res; } @@ -1692,6 +1793,7 @@ Tkapp_ExprLong(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "s:exprlong", &s)) return NULL; + CHECK_STRING_LENGTH(s); CHECK_TCL_APPARTMENT; ENTER_TCL @@ -1715,6 +1817,7 @@ Tkapp_ExprDouble(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "s:exprdouble", &s)) return NULL; + CHECK_STRING_LENGTH(s); CHECK_TCL_APPARTMENT; PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0) ENTER_TCL @@ -1739,6 +1842,7 @@ Tkapp_ExprBoolean(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "s:exprboolean", &s)) return NULL; + CHECK_STRING_LENGTH(s); CHECK_TCL_APPARTMENT; ENTER_TCL retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v); @@ -1758,7 +1862,7 @@ Tkapp_SplitList(PyObject *self, PyObject *args) { char *list; int argc; - char **argv; + const char **argv; PyObject *arg, *v; int i; @@ -1787,10 +1891,14 @@ Tkapp_SplitList(PyObject *self, PyObject *args) Py_INCREF(arg); return arg; } + if (PyList_Check(arg)) { + return PySequence_Tuple(arg); + } if (!PyArg_ParseTuple(args, "et:splitlist", "utf-8", &list)) return NULL; + CHECK_STRING_LENGTH(list); if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR) { PyMem_Free(list); @@ -1801,7 +1909,7 @@ Tkapp_SplitList(PyObject *self, PyObject *args) goto finally; for (i = 0; i < argc; i++) { - PyObject *s = PyUnicode_FromString(argv[i]); + PyObject *s = unicodeFromTclString(argv[i]); if (!s || PyTuple_SetItem(v, i, s)) { Py_DECREF(v); v = NULL; @@ -1847,11 +1955,12 @@ Tkapp_Split(PyObject *self, PyObject *args) } return v; } - if (PyTuple_Check(arg)) + if (PyTuple_Check(arg) || PyList_Check(arg)) return SplitObj(arg); if (!PyArg_ParseTuple(args, "et:split", "utf-8", &list)) return NULL; + CHECK_STRING_LENGTH(list); v = Split(list); PyMem_Free(list); return v; @@ -1880,7 +1989,7 @@ PythonCmd_Error(Tcl_Interp *interp) * function or method. */ static int -PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) +PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[]) { PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData; PyObject *func, *arg, *res; @@ -1899,20 +2008,8 @@ PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) return PythonCmd_Error(interp); for (i = 0; i < (argc - 1); i++) { - PyObject *s = PyUnicode_FromString(argv[i + 1]); - if (!s) { - /* Is Tk leaking 0xC080 in %A - a "modified" utf-8 null? */ - if (PyErr_ExceptionMatches(PyExc_UnicodeDecodeError) && - !strcmp(argv[i + 1], "\xC0\x80")) { - PyErr_Clear(); - /* Convert to "strict" utf-8 null */ - s = PyUnicode_FromString("\0"); - } else { - Py_DECREF(arg); - return PythonCmd_Error(interp); - } - } - if (PyTuple_SetItem(arg, i, s)) { + PyObject *s = unicodeFromTclString(argv[i + 1]); + if (!s || PyTuple_SetItem(arg, i, s)) { Py_DECREF(arg); return PythonCmd_Error(interp); } @@ -1995,6 +2092,7 @@ Tkapp_CreateCommand(PyObject *selfptr, PyObject *args) if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func)) return NULL; + CHECK_STRING_LENGTH(cmdName); if (!PyCallable_Check(func)) { PyErr_SetString(PyExc_TypeError, "command not callable"); return NULL; @@ -2016,7 +2114,12 @@ Tkapp_CreateCommand(PyObject *selfptr, PyObject *args) #ifdef WITH_THREAD if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) { Tcl_Condition cond = NULL; - CommandEvent *ev = (CommandEvent*)ckalloc(sizeof(CommandEvent)); + CommandEvent *ev = (CommandEvent*)attemptckalloc(sizeof(CommandEvent)); + if (ev == NULL) { + PyErr_NoMemory(); + PyMem_DEL(data); + return NULL; + } ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc; ev->interp = self->interp; ev->create = 1; @@ -2056,12 +2159,17 @@ Tkapp_DeleteCommand(PyObject *selfptr, PyObject *args) if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName)) return NULL; + CHECK_STRING_LENGTH(cmdName); #ifdef WITH_THREAD if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) { Tcl_Condition cond = NULL; CommandEvent *ev; - ev = (CommandEvent*)ckalloc(sizeof(CommandEvent)); + ev = (CommandEvent*)attemptckalloc(sizeof(CommandEvent)); + if (ev == NULL) { + PyErr_NoMemory(); + return NULL; + } ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc; ev->interp = self->interp; ev->create = 0; @@ -2618,20 +2726,20 @@ static PyType_Spec Tkapp_Type_spec = { typedef struct { PyObject* tuple; - int size; /* current size */ - int maxsize; /* allocated size */ + Py_ssize_t size; /* current size */ + Py_ssize_t maxsize; /* allocated size */ } FlattenContext; static int -_bump(FlattenContext* context, int size) +_bump(FlattenContext* context, Py_ssize_t size) { /* expand tuple to hold (at least) size new items. return true if successful, false if an exception was raised */ - int maxsize = context->maxsize * 2; + Py_ssize_t maxsize = context->maxsize * 2; /* never overflows */ if (maxsize < context->size + size) - maxsize = context->size + size; + maxsize = context->size + size; /* never overflows */ context->maxsize = maxsize; @@ -2643,41 +2751,21 @@ _flatten1(FlattenContext* context, PyObject* item, int depth) { /* add tuple or list to argument tuple (recursively) */ - int i, size; + Py_ssize_t i, size; if (depth > 1000) { PyErr_SetString(PyExc_ValueError, "nesting too deep in _flatten"); return 0; - } else if (PyList_Check(item)) { - size = PyList_GET_SIZE(item); + } else if (PyTuple_Check(item) || PyList_Check(item)) { + size = PySequence_Fast_GET_SIZE(item); /* preallocate (assume no nesting) */ if (context->size + size > context->maxsize && !_bump(context, size)) return 0; /* copy items to output tuple */ for (i = 0; i < size; i++) { - PyObject *o = PyList_GET_ITEM(item, i); - if (PyList_Check(o) || PyTuple_Check(o)) { - if (!_flatten1(context, o, depth + 1)) - return 0; - } else if (o != Py_None) { - if (context->size + 1 > context->maxsize && - !_bump(context, 1)) - return 0; - Py_INCREF(o); - PyTuple_SET_ITEM(context->tuple, - context->size++, o); - } - } - } else if (PyTuple_Check(item)) { - /* same, for tuples */ - size = PyTuple_GET_SIZE(item); - if (context->size + size > context->maxsize && - !_bump(context, size)) - return 0; - for (i = 0; i < size; i++) { - PyObject *o = PyTuple_GET_ITEM(item, i); + PyObject *o = PySequence_Fast_GET_ITEM(item, i); if (PyList_Check(o) || PyTuple_Check(o)) { if (!_flatten1(context, o, depth + 1)) return 0; @@ -2735,7 +2823,7 @@ Tkinter_Create(PyObject *self, PyObject *args) try getting rid of it. */ char *className = NULL; int interactive = 0; - int wantobjects = 0; + int wantobjects = 1; int wantTk = 1; /* If false, then Tk_Init() doesn't get called */ int sync = 0; /* pass -sync to wish */ char *use = NULL; /* pass -use to wish */ @@ -2747,6 +2835,10 @@ Tkinter_Create(PyObject *self, PyObject *args) &interactive, &wantobjects, &wantTk, &sync, &use)) return NULL; + CHECK_STRING_LENGTH(screenName); + CHECK_STRING_LENGTH(baseName); + CHECK_STRING_LENGTH(className); + CHECK_STRING_LENGTH(use); return (PyObject *) Tkapp_New(screenName, className, interactive, wantobjects, wantTk, diff --git a/Modules/_tracemalloc.c b/Modules/_tracemalloc.c index 7b88a7459482..12e32eb6a28e 100644 --- a/Modules/_tracemalloc.c +++ b/Modules/_tracemalloc.c @@ -16,14 +16,11 @@ static void raw_free(void *ptr); # define TRACE_DEBUG #endif -#define _STR(VAL) #VAL -#define STR(VAL) _STR(VAL) - /* Protected by the GIL */ static struct { - PyMemAllocator mem; - PyMemAllocator raw; - PyMemAllocator obj; + PyMemAllocatorEx mem; + PyMemAllocatorEx raw; + PyMemAllocatorEx obj; } allocators; static struct { @@ -61,10 +58,11 @@ static PyThread_type_lock tables_lock; architectures: 12 bytes instead of 16. This optimization might produce SIGBUS on architectures not supporting unaligned memory accesses (64-bit IPS CPU?): on such architecture, the structure must not be packed. */ -#pragma pack(4) typedef struct #ifdef __GNUC__ __attribute__((packed)) +#elif defined(_MSC_VER) +_declspec(align(4)) #endif { PyObject *filename; @@ -81,7 +79,7 @@ typedef struct { (sizeof(traceback_t) + sizeof(frame_t) * (NFRAME - 1)) #define MAX_NFRAME \ - ((INT_MAX - sizeof(traceback_t)) / sizeof(frame_t) + 1) + ((INT_MAX - (int)sizeof(traceback_t)) / (int)sizeof(frame_t) + 1) static PyObject *unknown_filename = NULL; static traceback_t tracemalloc_empty_traceback; @@ -103,7 +101,7 @@ static size_t tracemalloc_traced_memory = 0; Protected by TABLES_LOCK(). */ static size_t tracemalloc_peak_traced_memory = 0; -/* Hash table used as a set to to intern filenames: +/* Hash table used as a set to intern filenames: PyObject* => PyObject*. Protected by the GIL */ static _Py_hashtable_t *tracemalloc_filenames = NULL; @@ -168,14 +166,11 @@ set_reentrant(int reentrant) assert(reentrant == 0 || reentrant == 1); if (reentrant) { assert(PyThread_get_key_value(tracemalloc_reentrant_key) == NULL); - PyThread_set_key_value(tracemalloc_reentrant_key, - REENTRANT); + PyThread_set_key_value(tracemalloc_reentrant_key, REENTRANT); } else { - /* FIXME: PyThread_set_key_value() cannot be used to set the flag - to zero, because it does nothing if the variable has already - a value set. */ - PyThread_delete_key_value(tracemalloc_reentrant_key); + assert(PyThread_get_key_value(tracemalloc_reentrant_key) == REENTRANT); + PyThread_set_key_value(tracemalloc_reentrant_key, NULL); } } @@ -339,8 +334,7 @@ static Py_uhash_t traceback_hash(traceback_t *traceback) { /* code based on tuplehash() of Objects/tupleobject.c */ - Py_uhash_t x; /* Unsigned for defined overflow behavior. */ - Py_hash_t y; + Py_uhash_t x, y; /* Unsigned for defined overflow behavior. */ int len = traceback->nframe; Py_uhash_t mult = _PyHASH_MULTIPLIER; frame_t *frame; @@ -348,13 +342,13 @@ traceback_hash(traceback_t *traceback) x = 0x345678UL; frame = traceback->frames; while (--len >= 0) { - y = PyObject_Hash(frame->filename); - y ^= frame->lineno; + y = (Py_uhash_t)PyObject_Hash(frame->filename); + y ^= (Py_uhash_t)frame->lineno; frame++; x = (x ^ y) * mult; /* the cast might truncate len; that doesn't change hash stability */ - mult += (Py_hash_t)(82520UL + len + len); + mult += (Py_uhash_t)(82520UL + len + len); } x += 97531UL; return x; @@ -439,7 +433,7 @@ traceback_new(void) } static int -tracemalloc_log_alloc(void *ptr, size_t size) +tracemalloc_add_trace(void *ptr, size_t size) { traceback_t *traceback; trace_t trace; @@ -456,7 +450,6 @@ tracemalloc_log_alloc(void *ptr, size_t size) trace.size = size; trace.traceback = traceback; - TABLES_LOCK(); res = _Py_HASHTABLE_SET(tracemalloc_traces, ptr, trace); if (res == 0) { assert(tracemalloc_traced_memory <= PY_SIZE_MAX - size); @@ -464,144 +457,96 @@ tracemalloc_log_alloc(void *ptr, size_t size) if (tracemalloc_traced_memory > tracemalloc_peak_traced_memory) tracemalloc_peak_traced_memory = tracemalloc_traced_memory; } - TABLES_UNLOCK(); return res; } static void -tracemalloc_log_free(void *ptr) +tracemalloc_remove_trace(void *ptr) { trace_t trace; - TABLES_LOCK(); if (_Py_hashtable_pop(tracemalloc_traces, ptr, &trace, sizeof(trace))) { assert(tracemalloc_traced_memory >= trace.size); tracemalloc_traced_memory -= trace.size; } - TABLES_UNLOCK(); } static void* -tracemalloc_malloc(void *ctx, size_t size, int gil_held) +tracemalloc_alloc(int use_calloc, void *ctx, size_t nelem, size_t elsize) { - PyMemAllocator *alloc = (PyMemAllocator *)ctx; -#if defined(TRACE_RAW_MALLOC) && defined(WITH_THREAD) - PyGILState_STATE gil_state; -#endif + PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; void *ptr; - if (get_reentrant()) { - return alloc->malloc(alloc->ctx, size); - } + assert(elsize == 0 || nelem <= PY_SIZE_MAX / elsize); - /* Ignore reentrant call. PyObjet_Malloc() calls PyMem_Malloc() - for allocations larger than 512 bytes. PyGILState_Ensure() may call - PyMem_RawMalloc() indirectly which would call PyGILState_Ensure() if - reentrant are not disabled. */ - set_reentrant(1); -#ifdef WITH_THREAD -#ifdef TRACE_RAW_MALLOC - if (!gil_held) - gil_state = PyGILState_Ensure(); -#else - assert(gil_held); -#endif -#endif - ptr = alloc->malloc(alloc->ctx, size); + if (use_calloc) + ptr = alloc->calloc(alloc->ctx, nelem, elsize); + else + ptr = alloc->malloc(alloc->ctx, nelem * elsize); + if (ptr == NULL) + return NULL; - if (ptr != NULL) { - if (tracemalloc_log_alloc(ptr, size) < 0) { - /* Memory allocation failed */ - alloc->free(alloc->ctx, ptr); - ptr = NULL; - } + TABLES_LOCK(); + if (tracemalloc_add_trace(ptr, nelem * elsize) < 0) { + /* Failed to allocate a trace for the new memory block */ + TABLES_UNLOCK(); + alloc->free(alloc->ctx, ptr); + return NULL; } - set_reentrant(0); - -#if defined(TRACE_RAW_MALLOC) && defined(WITH_THREAD) - if (!gil_held) - PyGILState_Release(gil_state); -#endif - + TABLES_UNLOCK(); return ptr; } static void* -tracemalloc_realloc(void *ctx, void *ptr, size_t new_size, int gil_held) +tracemalloc_realloc(void *ctx, void *ptr, size_t new_size) { - PyMemAllocator *alloc = (PyMemAllocator *)ctx; -#if defined(TRACE_RAW_MALLOC) && defined(WITH_THREAD) - PyGILState_STATE gil_state; -#endif + PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; void *ptr2; - if (get_reentrant()) { - /* Reentrant call to PyMem_Realloc() and PyMem_RawRealloc(). - Example: PyMem_RawRealloc() is called internally by pymalloc - (_PyObject_Malloc() and _PyObject_Realloc()) to allocate a new - arena (new_arena()). */ - ptr2 = alloc->realloc(alloc->ctx, ptr, new_size); - - if (ptr2 != NULL && ptr != NULL) - tracemalloc_log_free(ptr); + ptr2 = alloc->realloc(alloc->ctx, ptr, new_size); + if (ptr2 == NULL) + return NULL; - return ptr2; - } + if (ptr != NULL) { + /* an existing memory block has been resized */ - /* Ignore reentrant call. PyObjet_Realloc() calls PyMem_Realloc() for - allocations larger than 512 bytes. PyGILState_Ensure() may call - PyMem_RawMalloc() indirectly which would call PyGILState_Ensure() if - reentrant are not disabled. */ - set_reentrant(1); -#ifdef WITH_THREAD -#ifdef TRACE_RAW_MALLOC - if (!gil_held) - gil_state = PyGILState_Ensure(); -#else - assert(gil_held); -#endif -#endif - ptr2 = alloc->realloc(alloc->ctx, ptr, new_size); + TABLES_LOCK(); + tracemalloc_remove_trace(ptr); - if (ptr2 != NULL) { - if (ptr != NULL) { - /* resize */ - tracemalloc_log_free(ptr); + if (tracemalloc_add_trace(ptr2, new_size) < 0) { + /* Memory allocation failed. The error cannot be reported to + the caller, because realloc() may already have shrinked the + memory block and so removed bytes. - if (tracemalloc_log_alloc(ptr2, new_size) < 0) { - /* Memory allocation failed. The error cannot be reported to - the caller, because realloc() may already have shrinked the - memory block and so removed bytes. + This case is very unlikely: an hash entry has just been + released, so the hash table should have at least one free entry. - This case is very unlikely since we just released an hash - entry, so we have enough free bytes to allocate the new - entry. */ - } - } - else { - /* new allocation */ - if (tracemalloc_log_alloc(ptr2, new_size) < 0) { - /* Memory allocation failed */ - alloc->free(alloc->ctx, ptr2); - ptr2 = NULL; - } + The GIL and the table lock ensures that only one thread is + allocating memory. */ + assert(0 && "should never happen"); } + TABLES_UNLOCK(); } - set_reentrant(0); - -#if defined(TRACE_RAW_MALLOC) && defined(WITH_THREAD) - if (!gil_held) - PyGILState_Release(gil_state); -#endif + else { + /* new allocation */ + TABLES_LOCK(); + if (tracemalloc_add_trace(ptr2, new_size) < 0) { + /* Failed to allocate a trace for the new memory block */ + TABLES_UNLOCK(); + alloc->free(alloc->ctx, ptr2); + return NULL; + } + TABLES_UNLOCK(); + } return ptr2; } static void tracemalloc_free(void *ctx, void *ptr) { - PyMemAllocator *alloc = (PyMemAllocator *)ctx; + PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; if (ptr == NULL) return; @@ -610,35 +555,166 @@ tracemalloc_free(void *ctx, void *ptr) a deadlock in PyThreadState_DeleteCurrent(). */ alloc->free(alloc->ctx, ptr); - tracemalloc_log_free(ptr); + + TABLES_LOCK(); + tracemalloc_remove_trace(ptr); + TABLES_UNLOCK(); +} + +static void* +tracemalloc_alloc_gil(int use_calloc, void *ctx, size_t nelem, size_t elsize) +{ + void *ptr; + + if (get_reentrant()) { + PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; + if (use_calloc) + return alloc->calloc(alloc->ctx, nelem, elsize); + else + return alloc->malloc(alloc->ctx, nelem * elsize); + } + + /* Ignore reentrant call. PyObjet_Malloc() calls PyMem_Malloc() for + allocations larger than 512 bytes, don't trace the same memory + allocation twice. */ + set_reentrant(1); + + ptr = tracemalloc_alloc(use_calloc, ctx, nelem, elsize); + + set_reentrant(0); + return ptr; } static void* tracemalloc_malloc_gil(void *ctx, size_t size) { - return tracemalloc_malloc(ctx, size, 1); + return tracemalloc_alloc_gil(0, ctx, 1, size); +} + +static void* +tracemalloc_calloc_gil(void *ctx, size_t nelem, size_t elsize) +{ + return tracemalloc_alloc_gil(1, ctx, nelem, elsize); } static void* tracemalloc_realloc_gil(void *ctx, void *ptr, size_t new_size) { - return tracemalloc_realloc(ctx, ptr, new_size, 1); + void *ptr2; + + if (get_reentrant()) { + /* Reentrant call to PyMem_Realloc() and PyMem_RawRealloc(). + Example: PyMem_RawRealloc() is called internally by pymalloc + (_PyObject_Malloc() and _PyObject_Realloc()) to allocate a new + arena (new_arena()). */ + PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; + + ptr2 = alloc->realloc(alloc->ctx, ptr, new_size); + if (ptr2 != NULL && ptr != NULL) { + TABLES_LOCK(); + tracemalloc_remove_trace(ptr); + TABLES_UNLOCK(); + } + return ptr2; + } + + /* Ignore reentrant call. PyObjet_Realloc() calls PyMem_Realloc() for + allocations larger than 512 bytes. Don't trace the same memory + allocation twice. */ + set_reentrant(1); + + ptr2 = tracemalloc_realloc(ctx, ptr, new_size); + + set_reentrant(0); + return ptr2; } #ifdef TRACE_RAW_MALLOC +static void* +tracemalloc_raw_alloc(int use_calloc, void *ctx, size_t nelem, size_t elsize) +{ +#ifdef WITH_THREAD + PyGILState_STATE gil_state; +#endif + void *ptr; + + if (get_reentrant()) { + PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; + if (use_calloc) + return alloc->calloc(alloc->ctx, nelem, elsize); + else + return alloc->malloc(alloc->ctx, nelem * elsize); + } + + /* Ignore reentrant call. PyGILState_Ensure() may call PyMem_RawMalloc() + indirectly which would call PyGILState_Ensure() if reentrant are not + disabled. */ + set_reentrant(1); + +#ifdef WITH_THREAD + gil_state = PyGILState_Ensure(); + ptr = tracemalloc_alloc(use_calloc, ctx, nelem, elsize); + PyGILState_Release(gil_state); +#else + ptr = tracemalloc_alloc(use_calloc, ctx, nelem, elsize); +#endif + + set_reentrant(0); + return ptr; +} + static void* tracemalloc_raw_malloc(void *ctx, size_t size) { - return tracemalloc_malloc(ctx, size, 0); + return tracemalloc_raw_alloc(0, ctx, 1, size); } static void* -tracemalloc_raw_realloc(void *ctx, void *ptr, size_t new_size) +tracemalloc_raw_calloc(void *ctx, size_t nelem, size_t elsize) { - return tracemalloc_realloc(ctx, ptr, new_size, 0); + return tracemalloc_raw_alloc(1, ctx, nelem, elsize); } + +static void* +tracemalloc_raw_realloc(void *ctx, void *ptr, size_t new_size) +{ +#ifdef WITH_THREAD + PyGILState_STATE gil_state; +#endif + void *ptr2; + + if (get_reentrant()) { + /* Reentrant call to PyMem_RawRealloc(). */ + PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; + + ptr2 = alloc->realloc(alloc->ctx, ptr, new_size); + + if (ptr2 != NULL && ptr != NULL) { + TABLES_LOCK(); + tracemalloc_remove_trace(ptr); + TABLES_UNLOCK(); + } + return ptr2; + } + + /* Ignore reentrant call. PyGILState_Ensure() may call PyMem_RawMalloc() + indirectly which would call PyGILState_Ensure() if reentrant calls are + not disabled. */ + set_reentrant(1); + +#ifdef WITH_THREAD + gil_state = PyGILState_Ensure(); + ptr2 = tracemalloc_realloc(ctx, ptr, new_size); + PyGILState_Release(gil_state); +#else + ptr2 = tracemalloc_realloc(ctx, ptr, new_size); #endif + set_reentrant(0); + return ptr2; +} +#endif /* TRACE_RAW_MALLOC */ + static int tracemalloc_clear_filename(_Py_hashtable_entry_t *entry, void *user_data) { @@ -787,7 +863,7 @@ tracemalloc_deinit(void) static int tracemalloc_start(int max_nframe) { - PyMemAllocator alloc; + PyMemAllocatorEx alloc; size_t size; if (tracemalloc_init() < 0) @@ -812,6 +888,7 @@ tracemalloc_start(int max_nframe) #ifdef TRACE_RAW_MALLOC alloc.malloc = tracemalloc_raw_malloc; + alloc.calloc = tracemalloc_raw_calloc; alloc.realloc = tracemalloc_raw_realloc; alloc.free = tracemalloc_free; @@ -821,6 +898,7 @@ tracemalloc_start(int max_nframe) #endif alloc.malloc = tracemalloc_malloc_gil; + alloc.calloc = tracemalloc_calloc_gil; alloc.realloc = tracemalloc_realloc_gil; alloc.free = tracemalloc_free; @@ -1008,7 +1086,7 @@ tracemalloc_get_traces_fill(_Py_hashtable_entry_t *entry, void *user_data) PyObject *tracemalloc_obj; int res; - trace = (trace_t *)_PY_HASHTABLE_ENTRY_DATA(entry); + trace = (trace_t *)_Py_HASHTABLE_ENTRY_DATA(entry); tracemalloc_obj = trace_to_pyobject(trace, get_traces->tracebacks); if (tracemalloc_obj == NULL) @@ -1151,7 +1229,7 @@ py_tracemalloc_start(PyObject *self, PyObject *args) if (nframe < 1 || nframe > MAX_NFRAME) { PyErr_Format(PyExc_ValueError, "the number of frames must be in range [1; %i]", - (int)MAX_NFRAME); + MAX_NFRAME); return NULL; } nframe_int = Py_SAFE_DOWNCAST(nframe, Py_ssize_t, int); @@ -1330,11 +1408,12 @@ _PyTraceMalloc_Init(void) char *endptr = p; long value; + errno = 0; value = strtol(p, &endptr, 10); if (*endptr != '\0' || value < 1 || value > MAX_NFRAME - || (errno == ERANGE && value == ULONG_MAX)) + || errno == ERANGE) { Py_FatalError("PYTHONTRACEMALLOC: invalid number of frames"); return -1; diff --git a/Modules/_weakref.c b/Modules/_weakref.c index 80de5da4d539..da589314ea5a 100644 --- a/Modules/_weakref.c +++ b/Modules/_weakref.c @@ -4,12 +4,12 @@ #define GET_WEAKREFS_LISTPTR(o) \ ((PyWeakReference **) PyObject_GET_WEAKREFS_LISTPTR(o)) -/*[clinic] +/*[clinic input] module _weakref -[clinic]*/ -/*[clinic checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=ffec73b85846596d]*/ -/*[clinic] +/*[clinic input] _weakref.getweakrefcount -> Py_ssize_t @@ -17,10 +17,12 @@ _weakref.getweakrefcount -> Py_ssize_t / Return the number of weak references to 'object'. -[clinic]*/ +[clinic start generated code]*/ PyDoc_STRVAR(_weakref_getweakrefcount__doc__, -"getweakrefcount(object)\n" +"getweakrefcount($module, object, /)\n" +"--\n" +"\n" "Return the number of weak references to \'object\'."); #define _WEAKREF_GETWEAKREFCOUNT_METHODDEF \ @@ -34,6 +36,7 @@ _weakref_getweakrefcount(PyModuleDef *module, PyObject *object) { PyObject *return_value = NULL; Py_ssize_t _return_value; + _return_value = _weakref_getweakrefcount_impl(module, object); if ((_return_value == -1) && PyErr_Occurred()) goto exit; @@ -45,13 +48,13 @@ _weakref_getweakrefcount(PyModuleDef *module, PyObject *object) static Py_ssize_t _weakref_getweakrefcount_impl(PyModuleDef *module, PyObject *object) -/*[clinic checksum: 436e8fbe0297434375f039d8c2d9fc3a9bbe773c]*/ +/*[clinic end generated code: output=032eedbfd7d69e10 input=cedb69711b6a2507]*/ { PyWeakReference **list; if (!PyType_SUPPORTS_WEAKREFS(Py_TYPE(object))) return 0; - + list = GET_WEAKREFS_LISTPTR(object); return _PyWeakref_GetWeakrefCount(*list); } diff --git a/Modules/_winapi.c b/Modules/_winapi.c index 724a4789f49f..51c4d5f45c4d 100644 --- a/Modules/_winapi.c +++ b/Modules/_winapi.c @@ -40,6 +40,7 @@ #define WINDOWS_LEAN_AND_MEAN #include "windows.h" #include +#include "winreparse.h" #if defined(MS_WIN32) && !defined(MS_WIN64) #define HANDLE_TO_PYNUM(handle) \ @@ -400,6 +401,140 @@ winapi_CreateFile(PyObject *self, PyObject *args) return Py_BuildValue(F_HANDLE, handle); } +static PyObject * +winapi_CreateJunction(PyObject *self, PyObject *args) +{ + /* Input arguments */ + LPWSTR src_path = NULL; + LPWSTR dst_path = NULL; + + /* Privilege adjustment */ + HANDLE token = NULL; + TOKEN_PRIVILEGES tp; + + /* Reparse data buffer */ + const USHORT prefix_len = 4; + USHORT print_len = 0; + USHORT rdb_size = 0; + PREPARSE_DATA_BUFFER rdb = NULL; + + /* Junction point creation */ + HANDLE junction = NULL; + DWORD ret = 0; + + if (!PyArg_ParseTuple(args, "uu", &src_path, &dst_path)) + return NULL; + + if (src_path == NULL || dst_path == NULL) + return PyErr_SetFromWindowsErr(ERROR_INVALID_PARAMETER); + + if (wcsncmp(src_path, L"\\??\\", prefix_len) == 0) + return PyErr_SetFromWindowsErr(ERROR_INVALID_PARAMETER); + + /* Adjust privileges to allow rewriting directory entry as a + junction point. */ + if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token)) + goto cleanup; + + if (!LookupPrivilegeValue(NULL, SE_RESTORE_NAME, &tp.Privileges[0].Luid)) + goto cleanup; + + tp.PrivilegeCount = 1; + tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + if (!AdjustTokenPrivileges(token, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), + NULL, NULL)) + goto cleanup; + + if (GetFileAttributesW(src_path) == INVALID_FILE_ATTRIBUTES) + goto cleanup; + + /* Store the absolute link target path length in print_len. */ + print_len = (USHORT)GetFullPathNameW(src_path, 0, NULL, NULL); + if (print_len == 0) + goto cleanup; + + /* NUL terminator should not be part of print_len. */ + --print_len; + + /* REPARSE_DATA_BUFFER usage is heavily under-documented, especially for + junction points. Here's what I've learned along the way: + - A junction point has two components: a print name and a substitute + name. They both describe the link target, but the substitute name is + the physical target and the print name is shown in directory listings. + - The print name must be a native name, prefixed with "\??\". + - Both names are stored after each other in the same buffer (the + PathBuffer) and both must be NUL-terminated. + - There are four members defining their respective offset and length + inside PathBuffer: SubstituteNameOffset, SubstituteNameLength, + PrintNameOffset and PrintNameLength. + - The total size we need to allocate for the REPARSE_DATA_BUFFER, thus, + is the sum of: + - the fixed header size (REPARSE_DATA_BUFFER_HEADER_SIZE) + - the size of the MountPointReparseBuffer member without the PathBuffer + - the size of the prefix ("\??\") in bytes + - the size of the print name in bytes + - the size of the substitute name in bytes + - the size of two NUL terminators in bytes */ + rdb_size = REPARSE_DATA_BUFFER_HEADER_SIZE + + sizeof(rdb->MountPointReparseBuffer) - + sizeof(rdb->MountPointReparseBuffer.PathBuffer) + + /* Two +1's for NUL terminators. */ + (prefix_len + print_len + 1 + print_len + 1) * sizeof(WCHAR); + rdb = (PREPARSE_DATA_BUFFER)PyMem_RawMalloc(rdb_size); + if (rdb == NULL) + goto cleanup; + + memset(rdb, 0, rdb_size); + rdb->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; + rdb->ReparseDataLength = rdb_size - REPARSE_DATA_BUFFER_HEADER_SIZE; + rdb->MountPointReparseBuffer.SubstituteNameOffset = 0; + rdb->MountPointReparseBuffer.SubstituteNameLength = + (prefix_len + print_len) * sizeof(WCHAR); + rdb->MountPointReparseBuffer.PrintNameOffset = + rdb->MountPointReparseBuffer.SubstituteNameLength + sizeof(WCHAR); + rdb->MountPointReparseBuffer.PrintNameLength = print_len * sizeof(WCHAR); + + /* Store the full native path of link target at the substitute name + offset (0). */ + wcscpy(rdb->MountPointReparseBuffer.PathBuffer, L"\\??\\"); + if (GetFullPathNameW(src_path, print_len + 1, + rdb->MountPointReparseBuffer.PathBuffer + prefix_len, + NULL) == 0) + goto cleanup; + + /* Copy everything but the native prefix to the print name offset. */ + wcscpy(rdb->MountPointReparseBuffer.PathBuffer + + prefix_len + print_len + 1, + rdb->MountPointReparseBuffer.PathBuffer + prefix_len); + + /* Create a directory for the junction point. */ + if (!CreateDirectoryW(dst_path, NULL)) + goto cleanup; + + junction = CreateFileW(dst_path, GENERIC_READ | GENERIC_WRITE, 0, NULL, + OPEN_EXISTING, + FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL); + if (junction == INVALID_HANDLE_VALUE) + goto cleanup; + + /* Make the directory entry a junction point. */ + if (!DeviceIoControl(junction, FSCTL_SET_REPARSE_POINT, rdb, rdb_size, + NULL, 0, &ret, NULL)) + goto cleanup; + +cleanup: + ret = GetLastError(); + + CloseHandle(token); + CloseHandle(junction); + PyMem_RawFree(rdb); + + if (ret != 0) + return PyErr_SetFromWindowsErr(ret); + + Py_RETURN_NONE; +} + static PyObject * winapi_CreateNamedPipe(PyObject *self, PyObject *args) { @@ -535,13 +670,23 @@ getenvironment(PyObject* environment) "environment can only contain strings"); goto error; } + if (totalsize > PY_SSIZE_T_MAX - PyUnicode_GET_LENGTH(key) - 1) { + PyErr_SetString(PyExc_OverflowError, "environment too long"); + goto error; + } totalsize += PyUnicode_GET_LENGTH(key) + 1; /* +1 for '=' */ + if (totalsize > PY_SSIZE_T_MAX - PyUnicode_GET_LENGTH(value) - 1) { + PyErr_SetString(PyExc_OverflowError, "environment too long"); + goto error; + } totalsize += PyUnicode_GET_LENGTH(value) + 1; /* +1 for '\0' */ } - buffer = PyMem_Malloc(totalsize * sizeof(Py_UCS4)); - if (! buffer) + buffer = PyMem_NEW(Py_UCS4, totalsize); + if (! buffer) { + PyErr_NoMemory(); goto error; + } p = buffer; end = buffer + totalsize; @@ -1225,6 +1370,8 @@ static PyMethodDef winapi_functions[] = { METH_VARARGS | METH_KEYWORDS, ""}, {"CreateFile", winapi_CreateFile, METH_VARARGS, ""}, + {"CreateJunction", winapi_CreateJunction, METH_VARARGS, + ""}, {"CreateNamedPipe", winapi_CreateNamedPipe, METH_VARARGS, ""}, {"CreatePipe", winapi_CreatePipe, METH_VARARGS, @@ -1343,6 +1490,7 @@ PyInit__winapi(void) WINAPI_CONSTANT(F_DWORD, STILL_ACTIVE); WINAPI_CONSTANT(F_DWORD, SW_HIDE); WINAPI_CONSTANT(F_DWORD, WAIT_OBJECT_0); + WINAPI_CONSTANT(F_DWORD, WAIT_ABANDONED_0); WINAPI_CONSTANT(F_DWORD, WAIT_TIMEOUT); WINAPI_CONSTANT("i", NULL); diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index 3b013acf6467..6e755f4fcfa2 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -15,6 +15,12 @@ #endif /* HAVE_SYS_TYPES_H */ #endif /* !STDC_HEADERS */ +/*[clinic input] +output preset file +module array +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=0909c1a148c69931]*/ + struct arrayobject; /* Forward */ /* All possible arraydescr values are defined in the vector "descriptors" @@ -42,6 +48,63 @@ typedef struct arrayobject { static PyTypeObject Arraytype; +typedef struct { + PyObject_HEAD + Py_ssize_t index; + arrayobject *ao; + PyObject* (*getitem)(struct arrayobject *, Py_ssize_t); +} arrayiterobject; + +static PyTypeObject PyArrayIter_Type; + +#define PyArrayIter_Check(op) PyObject_TypeCheck(op, &PyArrayIter_Type) + +enum machine_format_code { + UNKNOWN_FORMAT = -1, + /* UNKNOWN_FORMAT is used to indicate that the machine format for an + * array type code cannot be interpreted. When this occurs, a list of + * Python objects is used to represent the content of the array + * instead of using the memory content of the array directly. In that + * case, the array_reconstructor mechanism is bypassed completely, and + * the standard array constructor is used instead. + * + * This is will most likely occur when the machine doesn't use IEEE + * floating-point numbers. + */ + + UNSIGNED_INT8 = 0, + SIGNED_INT8 = 1, + UNSIGNED_INT16_LE = 2, + UNSIGNED_INT16_BE = 3, + SIGNED_INT16_LE = 4, + SIGNED_INT16_BE = 5, + UNSIGNED_INT32_LE = 6, + UNSIGNED_INT32_BE = 7, + SIGNED_INT32_LE = 8, + SIGNED_INT32_BE = 9, + UNSIGNED_INT64_LE = 10, + UNSIGNED_INT64_BE = 11, + SIGNED_INT64_LE = 12, + SIGNED_INT64_BE = 13, + IEEE_754_FLOAT_LE = 14, + IEEE_754_FLOAT_BE = 15, + IEEE_754_DOUBLE_LE = 16, + IEEE_754_DOUBLE_BE = 17, + UTF16_LE = 18, + UTF16_BE = 19, + UTF32_LE = 20, + UTF32_BE = 21 +}; +#define MACHINE_FORMAT_CODE_MIN 0 +#define MACHINE_FORMAT_CODE_MAX 21 + + +/* + * Must come after arrayobject, arrayiterobject, + * and enum machine_code_type definitions. + */ +#include "clinic/arraymodule.c.h" + #define array_Check(op) PyObject_TypeCheck(op, &Arraytype) #define array_CheckExact(op) (Py_TYPE(op) == &Arraytype) @@ -471,6 +534,10 @@ static struct arraydescr descriptors[] = { /**************************************************************************** Implementations of array object methods. ****************************************************************************/ +/*[clinic input] +class array.array "arrayobject *" "&Arraytype" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=ad43d37e942a8854]*/ static PyObject * newarrayobject(PyTypeObject *type, Py_ssize_t size, struct arraydescr *descr) @@ -684,16 +751,35 @@ array_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh) return (PyObject *)np; } + +/*[clinic input] +array.array.__copy__ + +Return a copy of the array. +[clinic start generated code]*/ + static PyObject * -array_copy(arrayobject *a, PyObject *unused) +array_array___copy___impl(arrayobject *self) +/*[clinic end generated code: output=dec7c3f925d9619e input=ad1ee5b086965f09]*/ { - return array_slice(a, 0, Py_SIZE(a)); + return array_slice(self, 0, Py_SIZE(self)); } -PyDoc_STRVAR(copy_doc, -"copy(array)\n\ -\n\ - Return a copy of the array."); +/*[clinic input] +array.array.__deepcopy__ + + unused: object + / + +Return a copy of the array. +[clinic start generated code]*/ + +static PyObject * +array_array___deepcopy__(arrayobject *self, PyObject *unused) +/*[clinic end generated code: output=1ec748d8e14a9faa input=2405ecb4933748c4]*/ +{ + return array_array___copy___impl(self); +} static PyObject * array_concat(arrayobject *a, PyObject *bb) @@ -961,8 +1047,18 @@ ins(arrayobject *self, Py_ssize_t where, PyObject *v) return Py_None; } +/*[clinic input] +array.array.count + + v: object + / + +Return number of occurrences of v in the array. +[clinic start generated code]*/ + static PyObject * -array_count(arrayobject *self, PyObject *v) +array_array_count(arrayobject *self, PyObject *v) +/*[clinic end generated code: output=3dd3624bf7135a3a input=d9bce9d65e39d1f5]*/ { Py_ssize_t count = 0; Py_ssize_t i; @@ -984,13 +1080,19 @@ array_count(arrayobject *self, PyObject *v) return PyLong_FromSsize_t(count); } -PyDoc_STRVAR(count_doc, -"count(x)\n\ -\n\ -Return number of occurrences of x in the array."); + +/*[clinic input] +array.array.index + + v: object + / + +Return index of first occurrence of v in the array. +[clinic start generated code]*/ static PyObject * -array_index(arrayobject *self, PyObject *v) +array_array_index(arrayobject *self, PyObject *v) +/*[clinic end generated code: output=d48498d325602167 input=cf619898c6649d08]*/ { Py_ssize_t i; @@ -1013,11 +1115,6 @@ array_index(arrayobject *self, PyObject *v) return NULL; } -PyDoc_STRVAR(index_doc, -"index(x)\n\ -\n\ -Return index of first occurrence of x in the array."); - static int array_contains(arrayobject *self, PyObject *v) { @@ -1034,8 +1131,18 @@ array_contains(arrayobject *self, PyObject *v) return cmp; } +/*[clinic input] +array.array.remove + + v: object + / + +Remove the first occurrence of v in the array. +[clinic start generated code]*/ + static PyObject * -array_remove(arrayobject *self, PyObject *v) +array_array_remove(arrayobject *self, PyObject *v) +/*[clinic end generated code: output=bef06be9fdf9dceb input=0b1e5aed25590027]*/ { int i; @@ -1062,18 +1169,23 @@ array_remove(arrayobject *self, PyObject *v) return NULL; } -PyDoc_STRVAR(remove_doc, -"remove(x)\n\ -\n\ -Remove the first occurrence of x in the array."); +/*[clinic input] +array.array.pop + + i: Py_ssize_t = -1 + / + +Return the i-th element and delete it from the array. + +i defaults to -1. +[clinic start generated code]*/ static PyObject * -array_pop(arrayobject *self, PyObject *args) +array_array_pop_impl(arrayobject *self, Py_ssize_t i) +/*[clinic end generated code: output=bc1f0c54fe5308e4 input=8e5feb4c1a11cd44]*/ { - Py_ssize_t i = -1; PyObject *v; - if (!PyArg_ParseTuple(args, "|n:pop", &i)) - return NULL; + if (Py_SIZE(self) == 0) { /* Special-case most common failure cause */ PyErr_SetString(PyExc_IndexError, "pop from empty array"); @@ -1095,13 +1207,18 @@ array_pop(arrayobject *self, PyObject *args) return v; } -PyDoc_STRVAR(pop_doc, -"pop([i])\n\ -\n\ -Return the i-th element and delete it from the array. i defaults to -1."); +/*[clinic input] +array.array.extend + + bb: object + / + +Append items to the end of the array. +[clinic start generated code]*/ static PyObject * -array_extend(arrayobject *self, PyObject *bb) +array_array_extend(arrayobject *self, PyObject *bb) +/*[clinic end generated code: output=bbddbc8e8bef871d input=43be86aba5c31e44]*/ { if (array_do_extend(self, bb) == -1) return NULL; @@ -1109,29 +1226,35 @@ array_extend(arrayobject *self, PyObject *bb) return Py_None; } -PyDoc_STRVAR(extend_doc, -"extend(array or iterable)\n\ -\n\ - Append items to the end of the array."); +/*[clinic input] +array.array.insert + + i: Py_ssize_t + v: object + / + +Insert a new item v into the array before position i. +[clinic start generated code]*/ static PyObject * -array_insert(arrayobject *self, PyObject *args) +array_array_insert_impl(arrayobject *self, Py_ssize_t i, PyObject *v) +/*[clinic end generated code: output=5a3648e278348564 input=5577d1b4383e9313]*/ { - Py_ssize_t i; - PyObject *v; - if (!PyArg_ParseTuple(args, "nO:insert", &i, &v)) - return NULL; return ins(self, i, v); } -PyDoc_STRVAR(insert_doc, -"insert(i,x)\n\ -\n\ -Insert a new item x into the array before position i."); +/*[clinic input] +array.array.buffer_info + +Return a tuple (address, length) giving the current memory address and the length in items of the buffer used to hold array's contents. +The length should be multiplied by the itemsize attribute to calculate +the buffer length in bytes. +[clinic start generated code]*/ static PyObject * -array_buffer_info(arrayobject *self, PyObject *unused) +array_array_buffer_info_impl(arrayobject *self) +/*[clinic end generated code: output=9b2a4ec3ae7e98e7 input=a58bae5c6e1ac6a6]*/ { PyObject *retval = NULL, *v; @@ -1156,29 +1279,34 @@ array_buffer_info(arrayobject *self, PyObject *unused) return retval; } -PyDoc_STRVAR(buffer_info_doc, -"buffer_info() -> (address, length)\n\ -\n\ -Return a tuple (address, length) giving the current memory address and\n\ -the length in items of the buffer used to hold array's contents\n\ -The length should be multiplied by the itemsize attribute to calculate\n\ -the buffer length in bytes."); +/*[clinic input] +array.array.append + v: object + / + +Append new value v to the end of the array. +[clinic start generated code]*/ static PyObject * -array_append(arrayobject *self, PyObject *v) +array_array_append(arrayobject *self, PyObject *v) +/*[clinic end generated code: output=745a0669bf8db0e2 input=0b98d9d78e78f0fa]*/ { return ins(self, Py_SIZE(self), v); } -PyDoc_STRVAR(append_doc, -"append(x)\n\ -\n\ -Append new value x to the end of the array."); +/*[clinic input] +array.array.byteswap + +Byteswap all items of the array. +If the items in the array are not 1, 2, 4, or 8 bytes in size, RuntimeError is +raised. +[clinic start generated code]*/ static PyObject * -array_byteswap(arrayobject *self, PyObject *unused) +array_array_byteswap_impl(arrayobject *self) +/*[clinic end generated code: output=5f8236cbdf0d90b5 input=6a85591b950a0186]*/ { char *p; Py_ssize_t i; @@ -1228,14 +1356,15 @@ array_byteswap(arrayobject *self, PyObject *unused) return Py_None; } -PyDoc_STRVAR(byteswap_doc, -"byteswap()\n\ -\n\ -Byteswap all items of the array. If the items in the array are not 1, 2,\n\ -4, or 8 bytes in size, RuntimeError is raised."); +/*[clinic input] +array.array.reverse + +Reverse the order of the items in the array. +[clinic start generated code]*/ static PyObject * -array_reverse(arrayobject *self, PyObject *unused) +array_array_reverse_impl(arrayobject *self) +/*[clinic end generated code: output=c04868b36f6f4089 input=cd904f01b27d966a]*/ { Py_ssize_t itemsize = self->ob_descr->itemsize; char *p, *q; @@ -1261,27 +1390,26 @@ array_reverse(arrayobject *self, PyObject *unused) return Py_None; } -PyDoc_STRVAR(reverse_doc, -"reverse()\n\ -\n\ -Reverse the order of the items in the array."); +/*[clinic input] +array.array.fromfile + f: object + n: Py_ssize_t + / -/* Forward */ -static PyObject *array_frombytes(arrayobject *self, PyObject *args); +Read n objects from the file object f and append them to the end of the array. +[clinic start generated code]*/ static PyObject * -array_fromfile(arrayobject *self, PyObject *args) +array_array_fromfile_impl(arrayobject *self, PyObject *f, Py_ssize_t n) +/*[clinic end generated code: output=ec9f600e10f53510 input=e188afe8e58adf40]*/ { - PyObject *f, *b, *res; + PyObject *args, *b, *res; Py_ssize_t itemsize = self->ob_descr->itemsize; - Py_ssize_t n, nbytes; + Py_ssize_t nbytes; _Py_IDENTIFIER(read); int not_enough_bytes; - if (!PyArg_ParseTuple(args, "On:fromfile", &f, &n)) - return NULL; - if (n < 0) { PyErr_SetString(PyExc_ValueError, "negative count"); return NULL; @@ -1310,7 +1438,7 @@ array_fromfile(arrayobject *self, PyObject *args) if (args == NULL) return NULL; - res = array_frombytes(self, args); + res = array_array_frombytes(self, args); Py_DECREF(args); if (res == NULL) return NULL; @@ -1325,15 +1453,18 @@ array_fromfile(arrayobject *self, PyObject *args) return res; } -PyDoc_STRVAR(fromfile_doc, -"fromfile(f, n)\n\ -\n\ -Read n objects from the file object f and append them to the end of the\n\ -array."); +/*[clinic input] +array.array.tofile + f: object + / + +Write all items (as machine values) to the file object f. +[clinic start generated code]*/ static PyObject * -array_tofile(arrayobject *self, PyObject *f) +array_array_tofile(arrayobject *self, PyObject *f) +/*[clinic end generated code: output=3a2cfa8128df0777 input=b0669a484aab0831]*/ { Py_ssize_t nbytes = Py_SIZE(self) * self->ob_descr->itemsize; /* Write 64K blocks at a time */ @@ -1368,14 +1499,18 @@ array_tofile(arrayobject *self, PyObject *f) return Py_None; } -PyDoc_STRVAR(tofile_doc, -"tofile(f)\n\ -\n\ -Write all items (as machine values) to the file object f."); +/*[clinic input] +array.array.fromlist + list: object + / + +Append items to array from list. +[clinic start generated code]*/ static PyObject * -array_fromlist(arrayobject *self, PyObject *list) +array_array_fromlist(arrayobject *self, PyObject *list) +/*[clinic end generated code: output=26411c2d228a3e3f input=be2605a96c49680f]*/ { Py_ssize_t n; @@ -1402,13 +1537,15 @@ array_fromlist(arrayobject *self, PyObject *list) return Py_None; } -PyDoc_STRVAR(fromlist_doc, -"fromlist(list)\n\ -\n\ -Append items to array from list."); +/*[clinic input] +array.array.tolist + +Convert array to an ordinary list with the same items. +[clinic start generated code]*/ static PyObject * -array_tolist(arrayobject *self, PyObject *unused) +array_array_tolist_impl(arrayobject *self) +/*[clinic end generated code: output=00b60cc9eab8ef89 input=a8d7784a94f86b53]*/ { PyObject *list = PyList_New(Py_SIZE(self)); Py_ssize_t i; @@ -1429,11 +1566,6 @@ array_tolist(arrayobject *self, PyObject *unused) return NULL; } -PyDoc_STRVAR(tolist_doc, -"tolist() -> list\n\ -\n\ -Convert array to an ordinary list with the same items."); - static PyObject * frombytes(arrayobject *self, Py_buffer *buffer) { @@ -1441,14 +1573,14 @@ frombytes(arrayobject *self, Py_buffer *buffer) Py_ssize_t n; if (buffer->itemsize != 1) { PyBuffer_Release(buffer); - PyErr_SetString(PyExc_TypeError, "string/buffer of bytes required."); + PyErr_SetString(PyExc_TypeError, "a bytes-like object is required"); return NULL; } n = buffer->len; if (n % itemsize != 0) { PyBuffer_Release(buffer); PyErr_SetString(PyExc_ValueError, - "string length not a multiple of item size"); + "bytes length not a multiple of item size"); return NULL; } n = n / itemsize; @@ -1471,47 +1603,52 @@ frombytes(arrayobject *self, Py_buffer *buffer) return Py_None; } +/*[clinic input] +array.array.fromstring + + buffer: Py_buffer(types='str bytes bytearray buffer') + / + +Appends items from the string, interpreting it as an array of machine values, as if it had been read from a file using the fromfile() method). + +This method is deprecated. Use frombytes instead. +[clinic start generated code]*/ + static PyObject * -array_fromstring(arrayobject *self, PyObject *args) +array_array_fromstring_impl(arrayobject *self, Py_buffer *buffer) +/*[clinic end generated code: output=31c4baa779df84ce input=1302d94c97696b84]*/ { - Py_buffer buffer; if (PyErr_WarnEx(PyExc_DeprecationWarning, "fromstring() is deprecated. Use frombytes() instead.", 2) != 0) return NULL; - if (!PyArg_ParseTuple(args, "s*:fromstring", &buffer)) - return NULL; - else - return frombytes(self, &buffer); + return frombytes(self, buffer); } -PyDoc_STRVAR(fromstring_doc, -"fromstring(string)\n\ -\n\ -Appends items from the string, interpreting it as an array of machine\n\ -values, as if it had been read from a file using the fromfile() method).\n\ -\n\ -This method is deprecated. Use frombytes instead."); +/*[clinic input] +array.array.frombytes + + buffer: Py_buffer + / +Appends items from the string, interpreting it as an array of machine values, as if it had been read from a file using the fromfile() method). +[clinic start generated code]*/ static PyObject * -array_frombytes(arrayobject *self, PyObject *args) +array_array_frombytes_impl(arrayobject *self, Py_buffer *buffer) +/*[clinic end generated code: output=d9842c8f7510a516 input=2bbf2b53ebfcc988]*/ { - Py_buffer buffer; - if (!PyArg_ParseTuple(args, "y*:frombytes", &buffer)) - return NULL; - else - return frombytes(self, &buffer); + return frombytes(self, buffer); } -PyDoc_STRVAR(frombytes_doc, -"frombytes(bytestring)\n\ -\n\ -Appends items from the string, interpreting it as an array of machine\n\ -values, as if it had been read from a file using the fromfile() method)."); +/*[clinic input] +array.array.tobytes +Convert the array to an array of machine values and return the bytes representation. +[clinic start generated code]*/ static PyObject * -array_tobytes(arrayobject *self, PyObject *unused) +array_array_tobytes_impl(arrayobject *self) +/*[clinic end generated code: output=87318e4edcdc2bb6 input=90ee495f96de34f5]*/ { if (Py_SIZE(self) <= PY_SSIZE_T_MAX / self->ob_descr->itemsize) { return PyBytes_FromStringAndSize(self->ob_item, @@ -1521,40 +1658,43 @@ array_tobytes(arrayobject *self, PyObject *unused) } } -PyDoc_STRVAR(tobytes_doc, -"tobytes() -> bytes\n\ -\n\ -Convert the array to an array of machine values and return the bytes\n\ -representation."); +/*[clinic input] +array.array.tostring + +Convert the array to an array of machine values and return the bytes representation. +This method is deprecated. Use tobytes instead. +[clinic start generated code]*/ static PyObject * -array_tostring(arrayobject *self, PyObject *unused) +array_array_tostring_impl(arrayobject *self) +/*[clinic end generated code: output=7d6bd92745a2c8f3 input=b6c0ddee7b30457e]*/ { if (PyErr_WarnEx(PyExc_DeprecationWarning, "tostring() is deprecated. Use tobytes() instead.", 2) != 0) return NULL; - return array_tobytes(self, unused); + return array_array_tobytes_impl(self); } -PyDoc_STRVAR(tostring_doc, -"tostring() -> bytes\n\ -\n\ -Convert the array to an array of machine values and return the bytes\n\ -representation.\n\ -\n\ -This method is deprecated. Use tobytes instead."); +/*[clinic input] +array.array.fromunicode + + ustr: Py_UNICODE(length=True) + / + +Extends this array with data from the unicode string ustr. +The array must be a unicode type array; otherwise a ValueError is raised. +Use array.frombytes(ustr.encode(...)) to append Unicode data to an array of +some other type. +[clinic start generated code]*/ static PyObject * -array_fromunicode(arrayobject *self, PyObject *args) +array_array_fromunicode_impl(arrayobject *self, Py_UNICODE *ustr, Py_ssize_clean_t ustr_length) +/*[clinic end generated code: output=3b3f4f133bac725e input=56bcedb5ef70139f]*/ { - Py_UNICODE *ustr; - Py_ssize_t n; char typecode; - if (!PyArg_ParseTuple(args, "u#:fromunicode", &ustr, &n)) - return NULL; typecode = self->ob_descr->typecode; if (typecode != 'u') { PyErr_SetString(PyExc_ValueError, @@ -1562,29 +1702,30 @@ array_fromunicode(arrayobject *self, PyObject *args) "unicode type arrays"); return NULL; } - if (n > 0) { + if (ustr_length > 0) { Py_ssize_t old_size = Py_SIZE(self); - if (array_resize(self, old_size + n) == -1) + if (array_resize(self, old_size + ustr_length) == -1) return NULL; memcpy(self->ob_item + old_size * sizeof(Py_UNICODE), - ustr, n * sizeof(Py_UNICODE)); + ustr, ustr_length * sizeof(Py_UNICODE)); } - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } -PyDoc_STRVAR(fromunicode_doc, -"fromunicode(ustr)\n\ -\n\ -Extends this array with data from the unicode string ustr.\n\ -The array must be a unicode type array; otherwise a ValueError\n\ -is raised. Use array.frombytes(ustr.encode(...)) to\n\ -append Unicode data to an array of some other type."); +/*[clinic input] +array.array.tounicode + +Extends this array with data from the unicode string ustr. +Convert the array to a unicode string. The array must be a unicode type array; +otherwise a ValueError is raised. Use array.tobytes().decode() to obtain a +unicode string from an array of some other type. +[clinic start generated code]*/ static PyObject * -array_tounicode(arrayobject *self, PyObject *unused) +array_array_tounicode_impl(arrayobject *self) +/*[clinic end generated code: output=08e442378336e1ef input=127242eebe70b66d]*/ { char typecode; typecode = self->ob_descr->typecode; @@ -1596,70 +1737,24 @@ array_tounicode(arrayobject *self, PyObject *unused) return PyUnicode_FromUnicode((Py_UNICODE *) self->ob_item, Py_SIZE(self)); } -PyDoc_STRVAR(tounicode_doc, -"tounicode() -> unicode\n\ -\n\ -Convert the array to a unicode string. The array must be\n\ -a unicode type array; otherwise a ValueError is raised. Use\n\ -array.tobytes().decode() to obtain a unicode string from\n\ -an array of some other type."); +/*[clinic input] +array.array.__sizeof__ +Size of the array in memory, in bytes. +[clinic start generated code]*/ static PyObject * -array_sizeof(arrayobject *self, PyObject *unused) +array_array___sizeof___impl(arrayobject *self) +/*[clinic end generated code: output=d8e1c61ebbe3eaed input=805586565bf2b3c6]*/ { Py_ssize_t res; res = sizeof(arrayobject) + self->allocated * self->ob_descr->itemsize; return PyLong_FromSsize_t(res); } -PyDoc_STRVAR(sizeof_doc, -"__sizeof__() -> int\n\ -\n\ -Size of the array in memory, in bytes."); - /*********************** Pickling support ************************/ -enum machine_format_code { - UNKNOWN_FORMAT = -1, - /* UNKNOWN_FORMAT is used to indicate that the machine format for an - * array type code cannot be interpreted. When this occurs, a list of - * Python objects is used to represent the content of the array - * instead of using the memory content of the array directly. In that - * case, the array_reconstructor mechanism is bypassed completely, and - * the standard array constructor is used instead. - * - * This is will most likely occur when the machine doesn't use IEEE - * floating-point numbers. - */ - - UNSIGNED_INT8 = 0, - SIGNED_INT8 = 1, - UNSIGNED_INT16_LE = 2, - UNSIGNED_INT16_BE = 3, - SIGNED_INT16_LE = 4, - SIGNED_INT16_BE = 5, - UNSIGNED_INT32_LE = 6, - UNSIGNED_INT32_BE = 7, - SIGNED_INT32_LE = 8, - SIGNED_INT32_BE = 9, - UNSIGNED_INT64_LE = 10, - UNSIGNED_INT64_BE = 11, - SIGNED_INT64_LE = 12, - SIGNED_INT64_BE = 13, - IEEE_754_FLOAT_LE = 14, - IEEE_754_FLOAT_BE = 15, - IEEE_754_DOUBLE_LE = 16, - IEEE_754_DOUBLE_BE = 17, - UTF16_LE = 18, - UTF16_BE = 19, - UTF32_LE = 20, - UTF32_BE = 21 -}; -#define MACHINE_FORMAT_CODE_MIN 0 -#define MACHINE_FORMAT_CODE_MAX 21 - static const struct mformatdescr { size_t size; int is_signed; @@ -1835,21 +1930,26 @@ make_array(PyTypeObject *arraytype, char typecode, PyObject *items) * This functions is a special constructor used when unpickling an array. It * provides a portable way to rebuild an array from its memory representation. */ +/*[clinic input] +array._array_reconstructor + + arraytype: object(type="PyTypeObject *") + typecode: int(types='str') + mformat_code: int(type="enum machine_format_code") + items: object + / + +Internal. Used for pickling support. +[clinic start generated code]*/ + static PyObject * -array_reconstructor(PyObject *self, PyObject *args) +array__array_reconstructor_impl(PyModuleDef *module, PyTypeObject *arraytype, int typecode, enum machine_format_code mformat_code, PyObject *items) +/*[clinic end generated code: output=c51081ec91caf7e9 input=f72492708c0a1d50]*/ { - PyTypeObject *arraytype; - PyObject *items; PyObject *converted_items; PyObject *result; - int typecode; - enum machine_format_code mformat_code; struct arraydescr *descr; - if (!PyArg_ParseTuple(args, "OCiO:array._array_reconstructor", - &arraytype, &typecode, &mformat_code, &items)) - return NULL; - if (!PyType_Check(arraytype)) { PyErr_Format(PyExc_TypeError, "first argument must a type object, not %.200s", @@ -2000,7 +2100,7 @@ array_reconstructor(PyObject *self, PyObject *args) */ for (descr = descriptors; descr->typecode != '\0'; descr++) { if (descr->is_integer_type && - descr->itemsize == mf_descr.size && + (size_t)descr->itemsize == mf_descr.size && descr->is_signed == mf_descr.is_signed) typecode = descr->typecode; } @@ -2038,13 +2138,23 @@ array_reconstructor(PyObject *self, PyObject *args) return result; } +/*[clinic input] +array.array.__reduce_ex__ + + value: object + / + +Return state information for pickling. +[clinic start generated code]*/ + static PyObject * -array_reduce_ex(arrayobject *array, PyObject *value) +array_array___reduce_ex__(arrayobject *self, PyObject *value) +/*[clinic end generated code: output=051e0a6175d0eddb input=c36c3f85de7df6cd]*/ { PyObject *dict; PyObject *result; PyObject *array_str; - int typecode = array->ob_descr->typecode; + int typecode = self->ob_descr->typecode; int mformat_code; static PyObject *array_reconstructor = NULL; long protocol; @@ -2072,7 +2182,7 @@ array_reduce_ex(arrayobject *array, PyObject *value) if (protocol == -1 && PyErr_Occurred()) return NULL; - dict = _PyObject_GetAttrId((PyObject *)array, &PyId___dict__); + dict = _PyObject_GetAttrId((PyObject *)self, &PyId___dict__); if (dict == NULL) { if (!PyErr_ExceptionMatches(PyExc_AttributeError)) return NULL; @@ -2095,32 +2205,30 @@ array_reduce_ex(arrayobject *array, PyObject *value) * coercing unicode objects to bytes in array_reconstructor. */ PyObject *list; - list = array_tolist(array, NULL); + list = array_array_tolist_impl(self); if (list == NULL) { Py_DECREF(dict); return NULL; } result = Py_BuildValue( - "O(CO)O", Py_TYPE(array), typecode, list, dict); + "O(CO)O", Py_TYPE(self), typecode, list, dict); Py_DECREF(list); Py_DECREF(dict); return result; } - array_str = array_tobytes(array, NULL); + array_str = array_array_tobytes_impl(self); if (array_str == NULL) { Py_DECREF(dict); return NULL; } result = Py_BuildValue( - "O(OCiN)O", array_reconstructor, Py_TYPE(array), typecode, + "O(OCiN)O", array_reconstructor, Py_TYPE(self), typecode, mformat_code, array_str, dict); Py_DECREF(dict); return result; } -PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); - static PyObject * array_get_typecode(arrayobject *a, void *closure) { @@ -2143,55 +2251,31 @@ static PyGetSetDef array_getsets [] = { }; static PyMethodDef array_methods[] = { - {"append", (PyCFunction)array_append, METH_O, - append_doc}, - {"buffer_info", (PyCFunction)array_buffer_info, METH_NOARGS, - buffer_info_doc}, - {"byteswap", (PyCFunction)array_byteswap, METH_NOARGS, - byteswap_doc}, - {"__copy__", (PyCFunction)array_copy, METH_NOARGS, - copy_doc}, - {"count", (PyCFunction)array_count, METH_O, - count_doc}, - {"__deepcopy__", (PyCFunction)array_copy, METH_O, - copy_doc}, - {"extend", (PyCFunction)array_extend, METH_O, - extend_doc}, - {"fromfile", (PyCFunction)array_fromfile, METH_VARARGS, - fromfile_doc}, - {"fromlist", (PyCFunction)array_fromlist, METH_O, - fromlist_doc}, - {"fromstring", (PyCFunction)array_fromstring, METH_VARARGS, - fromstring_doc}, - {"frombytes", (PyCFunction)array_frombytes, METH_VARARGS, - frombytes_doc}, - {"fromunicode", (PyCFunction)array_fromunicode, METH_VARARGS, - fromunicode_doc}, - {"index", (PyCFunction)array_index, METH_O, - index_doc}, - {"insert", (PyCFunction)array_insert, METH_VARARGS, - insert_doc}, - {"pop", (PyCFunction)array_pop, METH_VARARGS, - pop_doc}, - {"__reduce_ex__", (PyCFunction)array_reduce_ex, METH_O, - reduce_doc}, - {"remove", (PyCFunction)array_remove, METH_O, - remove_doc}, - {"reverse", (PyCFunction)array_reverse, METH_NOARGS, - reverse_doc}, - {"tofile", (PyCFunction)array_tofile, METH_O, - tofile_doc}, - {"tolist", (PyCFunction)array_tolist, METH_NOARGS, - tolist_doc}, - {"tostring", (PyCFunction)array_tostring, METH_NOARGS, - tostring_doc}, - {"tobytes", (PyCFunction)array_tobytes, METH_NOARGS, - tobytes_doc}, - {"tounicode", (PyCFunction)array_tounicode, METH_NOARGS, - tounicode_doc}, - {"__sizeof__", (PyCFunction)array_sizeof, METH_NOARGS, - sizeof_doc}, - {NULL, NULL} /* sentinel */ + ARRAY_ARRAY_APPEND_METHODDEF + ARRAY_ARRAY_BUFFER_INFO_METHODDEF + ARRAY_ARRAY_BYTESWAP_METHODDEF + ARRAY_ARRAY___COPY___METHODDEF + ARRAY_ARRAY_COUNT_METHODDEF + ARRAY_ARRAY___DEEPCOPY___METHODDEF + ARRAY_ARRAY_EXTEND_METHODDEF + ARRAY_ARRAY_FROMFILE_METHODDEF + ARRAY_ARRAY_FROMLIST_METHODDEF + ARRAY_ARRAY_FROMSTRING_METHODDEF + ARRAY_ARRAY_FROMBYTES_METHODDEF + ARRAY_ARRAY_FROMUNICODE_METHODDEF + ARRAY_ARRAY_INDEX_METHODDEF + ARRAY_ARRAY_INSERT_METHODDEF + ARRAY_ARRAY_POP_METHODDEF + ARRAY_ARRAY___REDUCE_EX___METHODDEF + ARRAY_ARRAY_REMOVE_METHODDEF + ARRAY_ARRAY_REVERSE_METHODDEF + ARRAY_ARRAY_TOFILE_METHODDEF + ARRAY_ARRAY_TOLIST_METHODDEF + ARRAY_ARRAY_TOSTRING_METHODDEF + ARRAY_ARRAY_TOBYTES_METHODDEF + ARRAY_ARRAY_TOUNICODE_METHODDEF + ARRAY_ARRAY___SIZEOF___METHODDEF + {NULL, NULL} /* sentinel */ }; static PyObject * @@ -2207,9 +2291,9 @@ array_repr(arrayobject *a) return PyUnicode_FromFormat("array('%c')", (int)typecode); } if (typecode == 'u') { - v = array_tounicode(a, NULL); + v = array_array_tounicode_impl(a); } else { - v = array_tolist(a, NULL); + v = array_array_tolist_impl(a); } if (v == NULL) return NULL; @@ -2446,7 +2530,11 @@ static const void *emptybuf = ""; static int array_buffer_getbuf(arrayobject *self, Py_buffer *view, int flags) { - if (view==NULL) goto finish; + if (view == NULL) { + PyErr_SetString(PyExc_BufferError, + "array_buffer_getbuf: view==NULL argument is obsolete"); + return -1; + } view->buf = (void *)self->ob_item; view->obj = (PyObject*)self; @@ -2476,7 +2564,6 @@ array_buffer_getbuf(arrayobject *self, Py_buffer *view, int flags) #endif } - finish: self->ob_exports++; return 0; } @@ -2592,8 +2679,8 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds) Py_DECREF(a); return NULL; } - v = array_frombytes((arrayobject *)a, - t_initial); + v = array_array_frombytes((arrayobject *)a, + t_initial); Py_DECREF(t_initial); if (v == NULL) { Py_DECREF(a); @@ -2628,7 +2715,7 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds) self->allocated = Py_SIZE(self); } } - else if (initial != NULL && array_Check(initial)) { + else if (initial != NULL && array_Check(initial) && len > 0) { arrayobject *self = (arrayobject *)a; arrayobject *other = (arrayobject *)initial; memcpy(self->ob_item, other->ob_item, len * other->ob_descr->itemsize); @@ -2766,16 +2853,10 @@ static PyTypeObject Arraytype = { /*********************** Array Iterator **************************/ -typedef struct { - PyObject_HEAD - Py_ssize_t index; - arrayobject *ao; - PyObject * (*getitem)(struct arrayobject *, Py_ssize_t); -} arrayiterobject; - -static PyTypeObject PyArrayIter_Type; - -#define PyArrayIter_Check(op) PyObject_TypeCheck(op, &PyArrayIter_Type) +/*[clinic input] +class array.arrayiterator "arrayiterobject *" "&PyArrayIter_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=5aefd2d74d8c8e30]*/ static PyObject * array_iter(arrayobject *ao) @@ -2823,31 +2904,47 @@ arrayiter_traverse(arrayiterobject *it, visitproc visit, void *arg) return 0; } +/*[clinic input] +array.arrayiterator.__reduce__ + +Return state information for pickling. +[clinic start generated code]*/ + static PyObject * -arrayiter_reduce(arrayiterobject *it) +array_arrayiterator___reduce___impl(arrayiterobject *self) +/*[clinic end generated code: output=7898a52e8e66e016 input=a062ea1e9951417a]*/ { return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"), - it->ao, it->index); + self->ao, self->index); } +/*[clinic input] +array.arrayiterator.__setstate__ + + state: object + / + +Set state information for unpickling. +[clinic start generated code]*/ + static PyObject * -arrayiter_setstate(arrayiterobject *it, PyObject *state) +array_arrayiterator___setstate__(arrayiterobject *self, PyObject *state) +/*[clinic end generated code: output=397da9904e443cbe input=f47d5ceda19e787b]*/ { Py_ssize_t index = PyLong_AsSsize_t(state); if (index == -1 && PyErr_Occurred()) return NULL; if (index < 0) index = 0; - it->index = index; + else if (index > Py_SIZE(self->ao)) + index = Py_SIZE(self->ao); /* iterator exhausted */ + self->index = index; Py_RETURN_NONE; } -PyDoc_STRVAR(setstate_doc, "Set state information for unpickling."); static PyMethodDef arrayiter_methods[] = { - {"__reduce__", (PyCFunction)arrayiter_reduce, METH_NOARGS, - reduce_doc}, - {"__setstate__", (PyCFunction)arrayiter_setstate, METH_O, - setstate_doc}, + ARRAY_ARRAYITERATOR___REDUCE___METHODDEF + ARRAY_ARRAYITERATOR___SETSTATE___METHODDEF {NULL, NULL} /* sentinel */ }; @@ -2888,8 +2985,7 @@ static PyTypeObject PyArrayIter_Type = { /* No functions in array module. */ static PyMethodDef a_methods[] = { - {"_array_reconstructor", array_reconstructor, METH_VARARGS, - PyDoc_STR("Internal. Used for pickling support.")}, + ARRAY__ARRAY_RECONSTRUCTOR_METHODDEF {NULL, NULL, 0, NULL} /* Sentinel */ }; diff --git a/Modules/atexitmodule.c b/Modules/atexitmodule.c index 98870141dda9..79e9962fc2a8 100644 --- a/Modules/atexitmodule.c +++ b/Modules/atexitmodule.c @@ -60,7 +60,7 @@ atexit_cleanup(atexitmodule_state *modstate) modstate->ncallbacks = 0; } -/* Installed into pythonrun.c's atexit mechanism */ +/* Installed into pylifecycle.c's atexit mechanism */ static void atexit_callfuncs(void) diff --git a/Modules/audioop.c b/Modules/audioop.c index ae3ff060b474..2d287f249b4a 100644 --- a/Modules/audioop.c +++ b/Modules/audioop.c @@ -390,128 +390,153 @@ audioop_check_parameters(Py_ssize_t len, int size) return 1; } +/*[clinic input] +output preset file +module audioop +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=5619f935f269199a]*/ + +/*[clinic input] +audioop.getsample + + fragment: Py_buffer + width: int + index: Py_ssize_t + / + +Return the value of sample index from the fragment. +[clinic start generated code]*/ + static PyObject * -audioop_getsample(PyObject *self, PyObject *args) +audioop_getsample_impl(PyModuleDef *module, Py_buffer *fragment, int width, Py_ssize_t index) +/*[clinic end generated code: output=f4482497e6f6e78f input=88edbe2871393549]*/ { - Py_buffer view; - Py_ssize_t i; - int size; int val; - if (!PyArg_ParseTuple(args, "y*in:getsample", &view, &size, &i)) + if (!audioop_check_parameters(fragment->len, width)) return NULL; - if (!audioop_check_parameters(view.len, size)) - goto error; - if (i < 0 || i >= view.len/size) { + if (index < 0 || index >= fragment->len/width) { PyErr_SetString(AudioopError, "Index out of range"); - goto error; + return NULL; } - val = GETRAWSAMPLE(size, view.buf, i*size); - PyBuffer_Release(&view); + val = GETRAWSAMPLE(width, fragment->buf, index*width); return PyLong_FromLong(val); - - error: - PyBuffer_Release(&view); - return NULL; } +/*[clinic input] +audioop.max + + fragment: Py_buffer + width: int + / + +Return the maximum of the absolute value of all samples in a fragment. +[clinic start generated code]*/ + static PyObject * -audioop_max(PyObject *self, PyObject *args) +audioop_max_impl(PyModuleDef *module, Py_buffer *fragment, int width) +/*[clinic end generated code: output=85047ee1001f2305 input=32bea5ea0ac8c223]*/ { - Py_buffer view; Py_ssize_t i; - int size; unsigned int absval, max = 0; - if (!PyArg_ParseTuple(args, "y*i:max", &view, &size)) - return NULL; - if (!audioop_check_parameters(view.len, size)) { - PyBuffer_Release(&view); + if (!audioop_check_parameters(fragment->len, width)) return NULL; - } - for (i = 0; i < view.len; i += size) { - int val = GETRAWSAMPLE(size, view.buf, i); + for (i = 0; i < fragment->len; i += width) { + int val = GETRAWSAMPLE(width, fragment->buf, i); if (val < 0) absval = (-val); else absval = val; if (absval > max) max = absval; } - PyBuffer_Release(&view); return PyLong_FromUnsignedLong(max); } +/*[clinic input] +audioop.minmax + + fragment: Py_buffer + width: int + / + +Return the minimum and maximum values of all samples in the sound fragment. +[clinic start generated code]*/ + static PyObject * -audioop_minmax(PyObject *self, PyObject *args) +audioop_minmax_impl(PyModuleDef *module, Py_buffer *fragment, int width) +/*[clinic end generated code: output=ae8f5513c64fd569 input=89848e9b927a0696]*/ { - Py_buffer view; Py_ssize_t i; - int size; /* -1 trick below is needed on Windows to support -0x80000000 without a warning */ int min = 0x7fffffff, max = -0x7FFFFFFF-1; - if (!PyArg_ParseTuple(args, "y*i:minmax", &view, &size)) - return NULL; - if (!audioop_check_parameters(view.len, size)) { - PyBuffer_Release(&view); + if (!audioop_check_parameters(fragment->len, width)) return NULL; - } - for (i = 0; i < view.len; i += size) { - int val = GETRAWSAMPLE(size, view.buf, i); + for (i = 0; i < fragment->len; i += width) { + int val = GETRAWSAMPLE(width, fragment->buf, i); if (val > max) max = val; if (val < min) min = val; } - PyBuffer_Release(&view); return Py_BuildValue("(ii)", min, max); } +/*[clinic input] +audioop.avg + + fragment: Py_buffer + width: int + / + +Return the average over all samples in the fragment. +[clinic start generated code]*/ + static PyObject * -audioop_avg(PyObject *self, PyObject *args) +audioop_avg_impl(PyModuleDef *module, Py_buffer *fragment, int width) +/*[clinic end generated code: output=7fccd645c95f4860 input=1114493c7611334d]*/ { - Py_buffer view; Py_ssize_t i; - int size, avg; + int avg; double sum = 0.0; - if (!PyArg_ParseTuple(args, "y*i:avg", &view, &size)) - return NULL; - if (!audioop_check_parameters(view.len, size)) { - PyBuffer_Release(&view); + if (!audioop_check_parameters(fragment->len, width)) return NULL; - } - for (i = 0; i < view.len; i += size) - sum += GETRAWSAMPLE(size, view.buf, i); - if (view.len == 0) + for (i = 0; i < fragment->len; i += width) + sum += GETRAWSAMPLE(width, fragment->buf, i); + if (fragment->len == 0) avg = 0; else - avg = (int)floor(sum / (double)(view.len/size)); - PyBuffer_Release(&view); + avg = (int)floor(sum / (double)(fragment->len/width)); return PyLong_FromLong(avg); } +/*[clinic input] +audioop.rms + + fragment: Py_buffer + width: int + / + +Return the root-mean-square of the fragment, i.e. sqrt(sum(S_i^2)/n). +[clinic start generated code]*/ + static PyObject * -audioop_rms(PyObject *self, PyObject *args) +audioop_rms_impl(PyModuleDef *module, Py_buffer *fragment, int width) +/*[clinic end generated code: output=7b398702c81b709d input=4cc57c6c94219d78]*/ { - Py_buffer view; Py_ssize_t i; - int size; unsigned int res; double sum_squares = 0.0; - if (!PyArg_ParseTuple(args, "y*i:rms", &view, &size)) - return NULL; - if (!audioop_check_parameters(view.len, size)) { - PyBuffer_Release(&view); + if (!audioop_check_parameters(fragment->len, width)) return NULL; - } - for (i = 0; i < view.len; i += size) { - double val = GETRAWSAMPLE(size, view.buf, i); + for (i = 0; i < fragment->len; i += width) { + double val = GETRAWSAMPLE(width, fragment->buf, i); sum_squares += val*val; } - if (view.len == 0) + if (fragment->len == 0) res = 0; else - res = (unsigned int)sqrt(sum_squares / (double)(view.len/size)); - PyBuffer_Release(&view); + res = (unsigned int)sqrt(sum_squares / (double)(fragment->len/width)); return PyLong_FromUnsignedLong(res); } @@ -558,31 +583,38 @@ static double _sum2(const short *a, const short *b, Py_ssize_t len) ** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri ** is completely recalculated each step. */ +/*[clinic input] +audioop.findfit + + fragment: Py_buffer + reference: Py_buffer + / + +Try to match reference as well as possible to a portion of fragment. +[clinic start generated code]*/ + static PyObject * -audioop_findfit(PyObject *self, PyObject *args) +audioop_findfit_impl(PyModuleDef *module, Py_buffer *fragment, Py_buffer *reference) +/*[clinic end generated code: output=505fd04d4244db31 input=62c305605e183c9a]*/ { - Py_buffer view1; - Py_buffer view2; const short *cp1, *cp2; Py_ssize_t len1, len2; Py_ssize_t j, best_j; double aj_m1, aj_lm1; double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor; - if (!PyArg_ParseTuple(args, "y*y*:findfit", &view1, &view2)) - return NULL; - if (view1.len & 1 || view2.len & 1) { + if (fragment->len & 1 || reference->len & 1) { PyErr_SetString(AudioopError, "Strings should be even-sized"); - goto error; + return NULL; } - cp1 = (const short *)view1.buf; - len1 = view1.len >> 1; - cp2 = (const short *)view2.buf; - len2 = view2.len >> 1; + cp1 = (const short *)fragment->buf; + len1 = fragment->len >> 1; + cp2 = (const short *)reference->buf; + len2 = reference->len >> 1; if (len1 < len2) { PyErr_SetString(AudioopError, "First sample should be longer"); - goto error; + return NULL; } sum_ri_2 = _sum2(cp2, cp2, len2); sum_aij_2 = _sum2(cp1, cp1, len2); @@ -612,93 +644,94 @@ audioop_findfit(PyObject *self, PyObject *args) factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2; - PyBuffer_Release(&view1); - PyBuffer_Release(&view2); return Py_BuildValue("(nf)", best_j, factor); - - error: - PyBuffer_Release(&view1); - PyBuffer_Release(&view2); - return NULL; } /* ** findfactor finds a factor f so that the energy in A-fB is minimal. ** See the comment for findfit for details. */ +/*[clinic input] +audioop.findfactor + + fragment: Py_buffer + reference: Py_buffer + / + +Return a factor F such that rms(add(fragment, mul(reference, -F))) is minimal. +[clinic start generated code]*/ + static PyObject * -audioop_findfactor(PyObject *self, PyObject *args) +audioop_findfactor_impl(PyModuleDef *module, Py_buffer *fragment, Py_buffer *reference) +/*[clinic end generated code: output=ddf35a1e57575ce4 input=816680301d012b21]*/ { - Py_buffer view1; - Py_buffer view2; const short *cp1, *cp2; Py_ssize_t len; double sum_ri_2, sum_aij_ri, result; - if (!PyArg_ParseTuple(args, "y*y*:findfactor", &view1, &view2)) - return NULL; - if (view1.len & 1 || view2.len & 1) { + if (fragment->len & 1 || reference->len & 1) { PyErr_SetString(AudioopError, "Strings should be even-sized"); - goto error; + return NULL; } - if (view1.len != view2.len) { + if (fragment->len != reference->len) { PyErr_SetString(AudioopError, "Samples should be same size"); - goto error; + return NULL; } - cp1 = (const short *)view1.buf; - cp2 = (const short *)view2.buf; - len = view1.len >> 1; + cp1 = (const short *)fragment->buf; + cp2 = (const short *)reference->buf; + len = fragment->len >> 1; sum_ri_2 = _sum2(cp2, cp2, len); sum_aij_ri = _sum2(cp1, cp2, len); result = sum_aij_ri / sum_ri_2; - PyBuffer_Release(&view1); - PyBuffer_Release(&view2); return PyFloat_FromDouble(result); - - error: - PyBuffer_Release(&view1); - PyBuffer_Release(&view2); - return NULL; } /* ** findmax returns the index of the n-sized segment of the input sample ** that contains the most energy. */ +/*[clinic input] +audioop.findmax + + fragment: Py_buffer + length: Py_ssize_t + / + +Search fragment for a slice of specified number of samples with maximum energy. +[clinic start generated code]*/ + static PyObject * -audioop_findmax(PyObject *self, PyObject *args) +audioop_findmax_impl(PyModuleDef *module, Py_buffer *fragment, Py_ssize_t length) +/*[clinic end generated code: output=21d0c2a1e5655134 input=2f304801ed42383c]*/ { - Py_buffer view; const short *cp1; - Py_ssize_t len1, len2; + Py_ssize_t len1; Py_ssize_t j, best_j; double aj_m1, aj_lm1; double result, best_result; - if (!PyArg_ParseTuple(args, "y*n:findmax", &view, &len2)) - return NULL; - if (view.len & 1) { + if (fragment->len & 1) { PyErr_SetString(AudioopError, "Strings should be even-sized"); - goto error; + return NULL; } - cp1 = (const short *)view.buf; - len1 = view.len >> 1; + cp1 = (const short *)fragment->buf; + len1 = fragment->len >> 1; - if (len2 < 0 || len1 < len2) { + if (length < 0 || len1 < length) { PyErr_SetString(AudioopError, "Input sample should be longer"); - goto error; + return NULL; } - result = _sum2(cp1, cp1, len2); + result = _sum2(cp1, cp1, length); best_result = result; best_j = 0; - for ( j=1; j<=len1-len2; j++) { + for ( j=1; j<=len1-length; j++) { aj_m1 = (double)cp1[j-1]; - aj_lm1 = (double)cp1[j+len2-1]; + aj_lm1 = (double)cp1[j+length-1]; result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1; @@ -709,39 +742,37 @@ audioop_findmax(PyObject *self, PyObject *args) } - PyBuffer_Release(&view); return PyLong_FromSsize_t(best_j); - - error: - PyBuffer_Release(&view); - return NULL; } +/*[clinic input] +audioop.avgpp + + fragment: Py_buffer + width: int + / + +Return the average peak-peak value over all samples in the fragment. +[clinic start generated code]*/ + static PyObject * -audioop_avgpp(PyObject *self, PyObject *args) +audioop_avgpp_impl(PyModuleDef *module, Py_buffer *fragment, int width) +/*[clinic end generated code: output=06c8380fd6e34207 input=0b3cceeae420a7d9]*/ { - Py_buffer view; Py_ssize_t i; - int size, prevval, prevextremevalid = 0, - prevextreme = 0; + int prevval, prevextremevalid = 0, prevextreme = 0; double sum = 0.0; unsigned int avg; int diff, prevdiff, nextreme = 0; - if (!PyArg_ParseTuple(args, "y*i:avgpp", &view, &size)) + if (!audioop_check_parameters(fragment->len, width)) return NULL; - if (!audioop_check_parameters(view.len, size)) { - PyBuffer_Release(&view); - return NULL; - } - if (view.len <= size) { - PyBuffer_Release(&view); + if (fragment->len <= width) return PyLong_FromLong(0); - } - prevval = GETRAWSAMPLE(size, view.buf, 0); + prevval = GETRAWSAMPLE(width, fragment->buf, 0); prevdiff = 17; /* Anything != 0, 1 */ - for (i = size; i < view.len; i += size) { - int val = GETRAWSAMPLE(size, view.buf, i); + for (i = width; i < fragment->len; i += width) { + int val = GETRAWSAMPLE(width, fragment->buf, i); if (val != prevval) { diff = val < prevval; if (prevdiff == !diff) { @@ -768,34 +799,36 @@ audioop_avgpp(PyObject *self, PyObject *args) avg = 0; else avg = (unsigned int)(sum / (double)nextreme); - PyBuffer_Release(&view); return PyLong_FromUnsignedLong(avg); } +/*[clinic input] +audioop.maxpp + + fragment: Py_buffer + width: int + / + +Return the maximum peak-peak value in the sound fragment. +[clinic start generated code]*/ + static PyObject * -audioop_maxpp(PyObject *self, PyObject *args) +audioop_maxpp_impl(PyModuleDef *module, Py_buffer *fragment, int width) +/*[clinic end generated code: output=c300c0bd7e8535c0 input=671a13e1518f80a1]*/ { - Py_buffer view; Py_ssize_t i; - int size, prevval, prevextremevalid = 0, - prevextreme = 0; + int prevval, prevextremevalid = 0, prevextreme = 0; unsigned int max = 0, extremediff; int diff, prevdiff; - if (!PyArg_ParseTuple(args, "y*i:maxpp", &view, &size)) - return NULL; - if (!audioop_check_parameters(view.len, size)) { - PyBuffer_Release(&view); + if (!audioop_check_parameters(fragment->len, width)) return NULL; - } - if (view.len <= size) { - PyBuffer_Release(&view); + if (fragment->len <= width) return PyLong_FromLong(0); - } - prevval = GETRAWSAMPLE(size, view.buf, 0); + prevval = GETRAWSAMPLE(width, fragment->buf, 0); prevdiff = 17; /* Anything != 0, 1 */ - for (i = size; i < view.len; i += size) { - int val = GETRAWSAMPLE(size, view.buf, i); + for (i = width; i < fragment->len; i += width) { + int val = GETRAWSAMPLE(width, fragment->buf, i); if (val != prevval) { diff = val < prevval; if (prevdiff == !diff) { @@ -819,187 +852,215 @@ audioop_maxpp(PyObject *self, PyObject *args) prevdiff = diff; } } - PyBuffer_Release(&view); return PyLong_FromUnsignedLong(max); } +/*[clinic input] +audioop.cross + + fragment: Py_buffer + width: int + / + +Return the number of zero crossings in the fragment passed as an argument. +[clinic start generated code]*/ + static PyObject * -audioop_cross(PyObject *self, PyObject *args) +audioop_cross_impl(PyModuleDef *module, Py_buffer *fragment, int width) +/*[clinic end generated code: output=99e6572d7d7cdbf1 input=b1b3f15b83f6b41a]*/ { - Py_buffer view; Py_ssize_t i; - int size; int prevval; Py_ssize_t ncross; - if (!PyArg_ParseTuple(args, "y*i:cross", &view, &size)) - return NULL; - if (!audioop_check_parameters(view.len, size)) { - PyBuffer_Release(&view); + if (!audioop_check_parameters(fragment->len, width)) return NULL; - } ncross = -1; prevval = 17; /* Anything <> 0,1 */ - for (i = 0; i < view.len; i += size) { - int val = GETRAWSAMPLE(size, view.buf, i) < 0; + for (i = 0; i < fragment->len; i += width) { + int val = GETRAWSAMPLE(width, fragment->buf, i) < 0; if (val != prevval) ncross++; prevval = val; } - PyBuffer_Release(&view); return PyLong_FromSsize_t(ncross); } +/*[clinic input] +audioop.mul + + fragment: Py_buffer + width: int + factor: double + / + +Return a fragment that has all samples in the original fragment multiplied by the floating-point value factor. +[clinic start generated code]*/ + static PyObject * -audioop_mul(PyObject *self, PyObject *args) +audioop_mul_impl(PyModuleDef *module, Py_buffer *fragment, int width, double factor) +/*[clinic end generated code: output=a697ebbd5852d38f input=c726667baa157d3c]*/ { - Py_buffer view; signed char *ncp; Py_ssize_t i; - int size; - double factor, maxval, minval; - PyObject *rv = NULL; + double maxval, minval; + PyObject *rv; - if (!PyArg_ParseTuple(args, "y*id:mul", &view, &size, &factor)) + if (!audioop_check_parameters(fragment->len, width)) return NULL; - if (!audioop_check_parameters(view.len, size)) - goto exit; - maxval = (double) maxvals[size]; - minval = (double) minvals[size]; + maxval = (double) maxvals[width]; + minval = (double) minvals[width]; - rv = PyBytes_FromStringAndSize(NULL, view.len); + rv = PyBytes_FromStringAndSize(NULL, fragment->len); if (rv == NULL) - goto exit; + return NULL; ncp = (signed char *)PyBytes_AsString(rv); - for (i = 0; i < view.len; i += size) { - double val = GETRAWSAMPLE(size, view.buf, i); + for (i = 0; i < fragment->len; i += width) { + double val = GETRAWSAMPLE(width, fragment->buf, i); val *= factor; val = floor(fbound(val, minval, maxval)); - SETRAWSAMPLE(size, ncp, i, (int)val); + SETRAWSAMPLE(width, ncp, i, (int)val); } - exit: - PyBuffer_Release(&view); return rv; } +/*[clinic input] +audioop.tomono + + fragment: Py_buffer + width: int + lfactor: double + rfactor: double + / + +Convert a stereo fragment to a mono fragment. +[clinic start generated code]*/ + static PyObject * -audioop_tomono(PyObject *self, PyObject *args) +audioop_tomono_impl(PyModuleDef *module, Py_buffer *fragment, int width, double lfactor, double rfactor) +/*[clinic end generated code: output=436e7710521661dd input=c4ec949b3f4dddfa]*/ { - Py_buffer pcp; signed char *cp, *ncp; Py_ssize_t len, i; - int size; - double fac1, fac2, maxval, minval; - PyObject *rv = NULL; + double maxval, minval; + PyObject *rv; - if (!PyArg_ParseTuple(args, "y*idd:tomono", - &pcp, &size, &fac1, &fac2)) + cp = fragment->buf; + len = fragment->len; + if (!audioop_check_parameters(len, width)) return NULL; - cp = pcp.buf; - len = pcp.len; - if (!audioop_check_parameters(len, size)) - goto exit; - if (((len / size) & 1) != 0) { + if (((len / width) & 1) != 0) { PyErr_SetString(AudioopError, "not a whole number of frames"); - goto exit; + return NULL; } - maxval = (double) maxvals[size]; - minval = (double) minvals[size]; + maxval = (double) maxvals[width]; + minval = (double) minvals[width]; rv = PyBytes_FromStringAndSize(NULL, len/2); if (rv == NULL) - goto exit; + return NULL; ncp = (signed char *)PyBytes_AsString(rv); - for (i = 0; i < len; i += size*2) { - double val1 = GETRAWSAMPLE(size, cp, i); - double val2 = GETRAWSAMPLE(size, cp, i + size); - double val = val1*fac1 + val2*fac2; + for (i = 0; i < len; i += width*2) { + double val1 = GETRAWSAMPLE(width, cp, i); + double val2 = GETRAWSAMPLE(width, cp, i + width); + double val = val1*lfactor + val2*rfactor; val = floor(fbound(val, minval, maxval)); - SETRAWSAMPLE(size, ncp, i/2, val); + SETRAWSAMPLE(width, ncp, i/2, val); } - exit: - PyBuffer_Release(&pcp); return rv; } +/*[clinic input] +audioop.tostereo + + fragment: Py_buffer + width: int + lfactor: double + rfactor: double + / + +Generate a stereo fragment from a mono fragment. +[clinic start generated code]*/ + static PyObject * -audioop_tostereo(PyObject *self, PyObject *args) +audioop_tostereo_impl(PyModuleDef *module, Py_buffer *fragment, int width, double lfactor, double rfactor) +/*[clinic end generated code: output=6ff50681c87f4c1c input=27b6395ebfdff37a]*/ { - Py_buffer view; signed char *ncp; Py_ssize_t i; - int size; - double fac1, fac2, maxval, minval; - PyObject *rv = NULL; + double maxval, minval; + PyObject *rv; - if (!PyArg_ParseTuple(args, "y*idd:tostereo", - &view, &size, &fac1, &fac2)) + if (!audioop_check_parameters(fragment->len, width)) return NULL; - if (!audioop_check_parameters(view.len, size)) - goto exit; - maxval = (double) maxvals[size]; - minval = (double) minvals[size]; + maxval = (double) maxvals[width]; + minval = (double) minvals[width]; - if (view.len > PY_SSIZE_T_MAX/2) { + if (fragment->len > PY_SSIZE_T_MAX/2) { PyErr_SetString(PyExc_MemoryError, "not enough memory for output buffer"); - goto exit; + return NULL; } - rv = PyBytes_FromStringAndSize(NULL, view.len*2); + rv = PyBytes_FromStringAndSize(NULL, fragment->len*2); if (rv == NULL) - goto exit; + return NULL; ncp = (signed char *)PyBytes_AsString(rv); - for (i = 0; i < view.len; i += size) { - double val = GETRAWSAMPLE(size, view.buf, i); - int val1 = (int)floor(fbound(val*fac1, minval, maxval)); - int val2 = (int)floor(fbound(val*fac2, minval, maxval)); - SETRAWSAMPLE(size, ncp, i*2, val1); - SETRAWSAMPLE(size, ncp, i*2 + size, val2); + for (i = 0; i < fragment->len; i += width) { + double val = GETRAWSAMPLE(width, fragment->buf, i); + int val1 = (int)floor(fbound(val*lfactor, minval, maxval)); + int val2 = (int)floor(fbound(val*rfactor, minval, maxval)); + SETRAWSAMPLE(width, ncp, i*2, val1); + SETRAWSAMPLE(width, ncp, i*2 + width, val2); } - exit: - PyBuffer_Release(&view); return rv; } +/*[clinic input] +audioop.add + + fragment1: Py_buffer + fragment2: Py_buffer + width: int + / + +Return a fragment which is the addition of the two samples passed as parameters. +[clinic start generated code]*/ + static PyObject * -audioop_add(PyObject *self, PyObject *args) +audioop_add_impl(PyModuleDef *module, Py_buffer *fragment1, Py_buffer *fragment2, int width) +/*[clinic end generated code: output=f9218bf9ea75c3f1 input=4a8d4bae4c1605c7]*/ { - Py_buffer view1; - Py_buffer view2; signed char *ncp; Py_ssize_t i; - int size, minval, maxval, newval; - PyObject *rv = NULL; + int minval, maxval, newval; + PyObject *rv; - if (!PyArg_ParseTuple(args, "y*y*i:add", - &view1, &view2, &size)) + if (!audioop_check_parameters(fragment1->len, width)) return NULL; - if (!audioop_check_parameters(view1.len, size)) - goto exit; - if (view1.len != view2.len) { + if (fragment1->len != fragment2->len) { PyErr_SetString(AudioopError, "Lengths should be the same"); - goto exit; + return NULL; } - maxval = maxvals[size]; - minval = minvals[size]; + maxval = maxvals[width]; + minval = minvals[width]; - rv = PyBytes_FromStringAndSize(NULL, view1.len); + rv = PyBytes_FromStringAndSize(NULL, fragment1->len); if (rv == NULL) - goto exit; + return NULL; ncp = (signed char *)PyBytes_AsString(rv); - for (i = 0; i < view1.len; i += size) { - int val1 = GETRAWSAMPLE(size, view1.buf, i); - int val2 = GETRAWSAMPLE(size, view2.buf, i); + for (i = 0; i < fragment1->len; i += width) { + int val1 = GETRAWSAMPLE(width, fragment1->buf, i); + int val2 = GETRAWSAMPLE(width, fragment2->buf, i); - if (size < 4) { + if (width < 4) { newval = val1 + val2; /* truncate in case of overflow */ if (newval > maxval) @@ -1013,165 +1074,176 @@ audioop_add(PyObject *self, PyObject *args) newval = (int)floor(fbound(fval, minval, maxval)); } - SETRAWSAMPLE(size, ncp, i, newval); + SETRAWSAMPLE(width, ncp, i, newval); } - exit: - PyBuffer_Release(&view1); - PyBuffer_Release(&view2); return rv; } +/*[clinic input] +audioop.bias + + fragment: Py_buffer + width: int + bias: int + / + +Return a fragment that is the original fragment with a bias added to each sample. +[clinic start generated code]*/ + static PyObject * -audioop_bias(PyObject *self, PyObject *args) +audioop_bias_impl(PyModuleDef *module, Py_buffer *fragment, int width, int bias) +/*[clinic end generated code: output=8ec80b3f5d510a51 input=2b5cce5c3bb4838c]*/ { - Py_buffer view; signed char *ncp; Py_ssize_t i; - int size, bias; unsigned int val = 0, mask; - PyObject *rv = NULL; + PyObject *rv; - if (!PyArg_ParseTuple(args, "y*ii:bias", - &view, &size, &bias)) + if (!audioop_check_parameters(fragment->len, width)) return NULL; - if (!audioop_check_parameters(view.len, size)) - goto exit; - - rv = PyBytes_FromStringAndSize(NULL, view.len); + rv = PyBytes_FromStringAndSize(NULL, fragment->len); if (rv == NULL) - goto exit; + return NULL; ncp = (signed char *)PyBytes_AsString(rv); - mask = masks[size]; + mask = masks[width]; - for (i = 0; i < view.len; i += size) { - if (size == 1) - val = GETINTX(unsigned char, view.buf, i); - else if (size == 2) - val = GETINTX(unsigned short, view.buf, i); - else if (size == 3) - val = ((unsigned int)GETINT24(view.buf, i)) & 0xffffffu; + for (i = 0; i < fragment->len; i += width) { + if (width == 1) + val = GETINTX(unsigned char, fragment->buf, i); + else if (width == 2) + val = GETINTX(unsigned short, fragment->buf, i); + else if (width == 3) + val = ((unsigned int)GETINT24(fragment->buf, i)) & 0xffffffu; else { - assert(size == 4); - val = GETINTX(PY_UINT32_T, view.buf, i); + assert(width == 4); + val = GETINTX(PY_UINT32_T, fragment->buf, i); } val += (unsigned int)bias; /* wrap around in case of overflow */ val &= mask; - if (size == 1) + if (width == 1) SETINTX(unsigned char, ncp, i, val); - else if (size == 2) + else if (width == 2) SETINTX(unsigned short, ncp, i, val); - else if (size == 3) + else if (width == 3) SETINT24(ncp, i, (int)val); else { - assert(size == 4); + assert(width == 4); SETINTX(PY_UINT32_T, ncp, i, val); } } - exit: - PyBuffer_Release(&view); return rv; } +/*[clinic input] +audioop.reverse + + fragment: Py_buffer + width: int + / + +Reverse the samples in a fragment and returns the modified fragment. +[clinic start generated code]*/ + static PyObject * -audioop_reverse(PyObject *self, PyObject *args) +audioop_reverse_impl(PyModuleDef *module, Py_buffer *fragment, int width) +/*[clinic end generated code: output=6ec3c91337f5925e input=668f890cf9f9d225]*/ { - Py_buffer view; unsigned char *ncp; Py_ssize_t i; - int size; - PyObject *rv = NULL; + PyObject *rv; - if (!PyArg_ParseTuple(args, "y*i:reverse", - &view, &size)) + if (!audioop_check_parameters(fragment->len, width)) return NULL; - if (!audioop_check_parameters(view.len, size)) - goto exit; - - rv = PyBytes_FromStringAndSize(NULL, view.len); + rv = PyBytes_FromStringAndSize(NULL, fragment->len); if (rv == NULL) - goto exit; + return NULL; ncp = (unsigned char *)PyBytes_AsString(rv); - for (i = 0; i < view.len; i += size) { - int val = GETRAWSAMPLE(size, view.buf, i); - SETRAWSAMPLE(size, ncp, view.len - i - size, val); + for (i = 0; i < fragment->len; i += width) { + int val = GETRAWSAMPLE(width, fragment->buf, i); + SETRAWSAMPLE(width, ncp, fragment->len - i - width, val); } - exit: - PyBuffer_Release(&view); return rv; } +/*[clinic input] +audioop.byteswap + + fragment: Py_buffer + width: int + / + +Convert big-endian samples to little-endian and vice versa. +[clinic start generated code]*/ + static PyObject * -audioop_byteswap(PyObject *self, PyObject *args) +audioop_byteswap_impl(PyModuleDef *module, Py_buffer *fragment, int width) +/*[clinic end generated code: output=bfe4aa584b7a3f5b input=fae7611ceffa5c82]*/ { - Py_buffer view; unsigned char *ncp; Py_ssize_t i; - int size; - PyObject *rv = NULL; + PyObject *rv; - if (!PyArg_ParseTuple(args, "y*i:swapbytes", - &view, &size)) + if (!audioop_check_parameters(fragment->len, width)) return NULL; - if (!audioop_check_parameters(view.len, size)) - goto exit; - - rv = PyBytes_FromStringAndSize(NULL, view.len); + rv = PyBytes_FromStringAndSize(NULL, fragment->len); if (rv == NULL) - goto exit; + return NULL; ncp = (unsigned char *)PyBytes_AsString(rv); - for (i = 0; i < view.len; i += size) { + for (i = 0; i < fragment->len; i += width) { int j; - for (j = 0; j < size; j++) - ncp[i + size - 1 - j] = ((unsigned char *)view.buf)[i + j]; + for (j = 0; j < width; j++) + ncp[i + width - 1 - j] = ((unsigned char *)fragment->buf)[i + j]; } - exit: - PyBuffer_Release(&view); return rv; } +/*[clinic input] +audioop.lin2lin + + fragment: Py_buffer + width: int + newwidth: int + / + +Convert samples between 1-, 2-, 3- and 4-byte formats. +[clinic start generated code]*/ + static PyObject * -audioop_lin2lin(PyObject *self, PyObject *args) +audioop_lin2lin_impl(PyModuleDef *module, Py_buffer *fragment, int width, int newwidth) +/*[clinic end generated code: output=3f9468a74472a93e input=5ce08c8aa2f24d96]*/ { - Py_buffer view; unsigned char *ncp; Py_ssize_t i, j; - int size, size2; - PyObject *rv = NULL; + PyObject *rv; - if (!PyArg_ParseTuple(args, "y*ii:lin2lin", - &view, &size, &size2)) + if (!audioop_check_parameters(fragment->len, width)) + return NULL; + if (!audioop_check_size(newwidth)) return NULL; - if (!audioop_check_parameters(view.len, size)) - goto exit; - if (!audioop_check_size(size2)) - goto exit; - - if (view.len/size > PY_SSIZE_T_MAX/size2) { + if (fragment->len/width > PY_SSIZE_T_MAX/newwidth) { PyErr_SetString(PyExc_MemoryError, "not enough memory for output buffer"); - goto exit; + return NULL; } - rv = PyBytes_FromStringAndSize(NULL, (view.len/size)*size2); + rv = PyBytes_FromStringAndSize(NULL, (fragment->len/width)*newwidth); if (rv == NULL) - goto exit; + return NULL; ncp = (unsigned char *)PyBytes_AsString(rv); - for (i = j = 0; i < view.len; i += size, j += size2) { - int val = GETSAMPLE32(size, view.buf, i); - SETSAMPLE32(size2, ncp, j, val); + for (i = j = 0; i < fragment->len; i += width, j += newwidth) { + int val = GETSAMPLE32(width, fragment->buf, i); + SETSAMPLE32(newwidth, ncp, j, val); } - exit: - PyBuffer_Release(&view); return rv; } @@ -1186,50 +1258,60 @@ gcd(int a, int b) return a; } +/*[clinic input] +audioop.ratecv + + fragment: Py_buffer + width: int + nchannels: int + inrate: int + outrate: int + state: object + weightA: int = 1 + weightB: int = 0 + / + +Convert the frame rate of the input fragment. +[clinic start generated code]*/ + static PyObject * -audioop_ratecv(PyObject *self, PyObject *args) +audioop_ratecv_impl(PyModuleDef *module, Py_buffer *fragment, int width, int nchannels, int inrate, int outrate, PyObject *state, int weightA, int weightB) +/*[clinic end generated code: output=5585dddc4b5ff236 input=aff3acdc94476191]*/ { - Py_buffer view; char *cp, *ncp; Py_ssize_t len; - int size, nchannels, inrate, outrate, weightA, weightB; int chan, d, *prev_i, *cur_i, cur_o; - PyObject *state, *samps, *str, *rv = NULL; + PyObject *samps, *str, *rv = NULL; int bytes_per_frame; - weightA = 1; - weightB = 0; - if (!PyArg_ParseTuple(args, "y*iiiiO|ii:ratecv", &view, &size, - &nchannels, &inrate, &outrate, &state, - &weightA, &weightB)) + if (!audioop_check_size(width)) return NULL; - if (!audioop_check_size(size)) - goto exit2; if (nchannels < 1) { PyErr_SetString(AudioopError, "# of channels should be >= 1"); - goto exit2; + return NULL; } - if (size > INT_MAX / nchannels) { + if (width > INT_MAX / nchannels) { /* This overflow test is rigorously correct because both multiplicands are >= 1. Use the argument names from the docs for the error msg. */ PyErr_SetString(PyExc_OverflowError, "width * nchannels too big for a C int"); - goto exit2; + return NULL; } - bytes_per_frame = size * nchannels; + bytes_per_frame = width * nchannels; if (weightA < 1 || weightB < 0) { PyErr_SetString(AudioopError, "weightA should be >= 1, weightB should be >= 0"); - goto exit2; + return NULL; } - if (view.len % bytes_per_frame != 0) { + assert(fragment->len >= 0); + if (fragment->len % bytes_per_frame != 0) { PyErr_SetString(AudioopError, "not a whole number of frames"); - goto exit2; + return NULL; } if (inrate <= 0 || outrate <= 0) { PyErr_SetString(AudioopError, "sampling rate not > 0"); - goto exit2; + return NULL; } /* divide inrate and outrate by their greatest common divisor */ d = gcd(inrate, outrate); @@ -1243,7 +1325,7 @@ audioop_ratecv(PyObject *self, PyObject *args) if ((size_t)nchannels > PY_SIZE_MAX/sizeof(int)) { PyErr_SetString(PyExc_MemoryError, "not enough memory for output buffer"); - goto exit2; + return NULL; } prev_i = (int *) PyMem_Malloc(nchannels * sizeof(int)); cur_i = (int *) PyMem_Malloc(nchannels * sizeof(int)); @@ -1252,7 +1334,7 @@ audioop_ratecv(PyObject *self, PyObject *args) goto exit; } - len = view.len / bytes_per_frame; /* # of frames */ + len = fragment->len / bytes_per_frame; /* # of frames */ if (state == Py_None) { d = -outrate; @@ -1289,7 +1371,7 @@ audioop_ratecv(PyObject *self, PyObject *args) case ceiling(len/inrate) * outrate. */ /* compute ceiling(len/inrate) without overflow */ - Py_ssize_t q = len > 0 ? 1 + (len - 1) / inrate : 0; + Py_ssize_t q = 1 + (len - 1) / inrate; if (outrate > PY_SSIZE_T_MAX / q / bytes_per_frame) str = NULL; else @@ -1302,7 +1384,7 @@ audioop_ratecv(PyObject *self, PyObject *args) goto exit; } ncp = PyBytes_AsString(str); - cp = view.buf; + cp = fragment->buf; for (;;) { while (d < 0) { @@ -1333,8 +1415,8 @@ audioop_ratecv(PyObject *self, PyObject *args) } for (chan = 0; chan < nchannels; chan++) { prev_i[chan] = cur_i[chan]; - cur_i[chan] = GETSAMPLE32(size, cp, 0); - cp += size; + cur_i[chan] = GETSAMPLE32(width, cp, 0); + cp += width; /* implements a simple digital filter */ cur_i[chan] = (int)( ((double)weightA * (double)cur_i[chan] + @@ -1349,8 +1431,8 @@ audioop_ratecv(PyObject *self, PyObject *args) cur_o = (int)(((double)prev_i[chan] * (double)d + (double)cur_i[chan] * (double)(outrate - d)) / (double)outrate); - SETSAMPLE32(size, ncp, 0, cur_o); - ncp += size; + SETSAMPLE32(width, ncp, 0, cur_o); + ncp += width; } d -= inrate; } @@ -1358,166 +1440,184 @@ audioop_ratecv(PyObject *self, PyObject *args) exit: PyMem_Free(prev_i); PyMem_Free(cur_i); - exit2: - PyBuffer_Release(&view); return rv; } +/*[clinic input] +audioop.lin2ulaw + + fragment: Py_buffer + width: int + / + +Convert samples in the audio fragment to u-LAW encoding. +[clinic start generated code]*/ + static PyObject * -audioop_lin2ulaw(PyObject *self, PyObject *args) +audioop_lin2ulaw_impl(PyModuleDef *module, Py_buffer *fragment, int width) +/*[clinic end generated code: output=26263cc877c5e1bc input=2450d1b870b6bac2]*/ { - Py_buffer view; unsigned char *ncp; Py_ssize_t i; - int size; - PyObject *rv = NULL; + PyObject *rv; - if (!PyArg_ParseTuple(args, "y*i:lin2ulaw", - &view, &size)) + if (!audioop_check_parameters(fragment->len, width)) return NULL; - if (!audioop_check_parameters(view.len, size)) - goto exit; - - rv = PyBytes_FromStringAndSize(NULL, view.len/size); + rv = PyBytes_FromStringAndSize(NULL, fragment->len/width); if (rv == NULL) - goto exit; + return NULL; ncp = (unsigned char *)PyBytes_AsString(rv); - for (i = 0; i < view.len; i += size) { - int val = GETSAMPLE32(size, view.buf, i); + for (i = 0; i < fragment->len; i += width) { + int val = GETSAMPLE32(width, fragment->buf, i); *ncp++ = st_14linear2ulaw(val >> 18); } - exit: - PyBuffer_Release(&view); return rv; } +/*[clinic input] +audioop.ulaw2lin + + fragment: Py_buffer + width: int + / + +Convert sound fragments in u-LAW encoding to linearly encoded sound fragments. +[clinic start generated code]*/ + static PyObject * -audioop_ulaw2lin(PyObject *self, PyObject *args) +audioop_ulaw2lin_impl(PyModuleDef *module, Py_buffer *fragment, int width) +/*[clinic end generated code: output=9864cb34e3a1d876 input=45d53ddce5be7d06]*/ { - Py_buffer view; unsigned char *cp; signed char *ncp; Py_ssize_t i; - int size; - PyObject *rv = NULL; + PyObject *rv; - if (!PyArg_ParseTuple(args, "y*i:ulaw2lin", - &view, &size)) + if (!audioop_check_size(width)) return NULL; - if (!audioop_check_size(size)) - goto exit; - - if (view.len > PY_SSIZE_T_MAX/size) { + if (fragment->len > PY_SSIZE_T_MAX/width) { PyErr_SetString(PyExc_MemoryError, "not enough memory for output buffer"); - goto exit; + return NULL; } - rv = PyBytes_FromStringAndSize(NULL, view.len*size); + rv = PyBytes_FromStringAndSize(NULL, fragment->len*width); if (rv == NULL) - goto exit; + return NULL; ncp = (signed char *)PyBytes_AsString(rv); - cp = view.buf; - for (i = 0; i < view.len*size; i += size) { + cp = fragment->buf; + for (i = 0; i < fragment->len*width; i += width) { int val = st_ulaw2linear16(*cp++) << 16; - SETSAMPLE32(size, ncp, i, val); + SETSAMPLE32(width, ncp, i, val); } - exit: - PyBuffer_Release(&view); return rv; } +/*[clinic input] +audioop.lin2alaw + + fragment: Py_buffer + width: int + / + +Convert samples in the audio fragment to a-LAW encoding. +[clinic start generated code]*/ + static PyObject * -audioop_lin2alaw(PyObject *self, PyObject *args) +audioop_lin2alaw_impl(PyModuleDef *module, Py_buffer *fragment, int width) +/*[clinic end generated code: output=d5bf14bd0fe6fdcd input=ffb1ef8bb39da945]*/ { - Py_buffer view; unsigned char *ncp; Py_ssize_t i; - int size; - PyObject *rv = NULL; + PyObject *rv; - if (!PyArg_ParseTuple(args, "y*i:lin2alaw", - &view, &size)) + if (!audioop_check_parameters(fragment->len, width)) return NULL; - if (!audioop_check_parameters(view.len, size)) - goto exit; - - rv = PyBytes_FromStringAndSize(NULL, view.len/size); + rv = PyBytes_FromStringAndSize(NULL, fragment->len/width); if (rv == NULL) - goto exit; + return NULL; ncp = (unsigned char *)PyBytes_AsString(rv); - for (i = 0; i < view.len; i += size) { - int val = GETSAMPLE32(size, view.buf, i); + for (i = 0; i < fragment->len; i += width) { + int val = GETSAMPLE32(width, fragment->buf, i); *ncp++ = st_linear2alaw(val >> 19); } - exit: - PyBuffer_Release(&view); return rv; } +/*[clinic input] +audioop.alaw2lin + + fragment: Py_buffer + width: int + / + +Convert sound fragments in a-LAW encoding to linearly encoded sound fragments. +[clinic start generated code]*/ + static PyObject * -audioop_alaw2lin(PyObject *self, PyObject *args) +audioop_alaw2lin_impl(PyModuleDef *module, Py_buffer *fragment, int width) +/*[clinic end generated code: output=d2b604ddd036e1cd input=4140626046cd1772]*/ { - Py_buffer view; unsigned char *cp; signed char *ncp; Py_ssize_t i; - int size, val; - PyObject *rv = NULL; + int val; + PyObject *rv; - if (!PyArg_ParseTuple(args, "y*i:alaw2lin", - &view, &size)) + if (!audioop_check_size(width)) return NULL; - if (!audioop_check_size(size)) - goto exit; - - if (view.len > PY_SSIZE_T_MAX/size) { + if (fragment->len > PY_SSIZE_T_MAX/width) { PyErr_SetString(PyExc_MemoryError, "not enough memory for output buffer"); - goto exit; + return NULL; } - rv = PyBytes_FromStringAndSize(NULL, view.len*size); + rv = PyBytes_FromStringAndSize(NULL, fragment->len*width); if (rv == NULL) - goto exit; + return NULL; ncp = (signed char *)PyBytes_AsString(rv); - cp = view.buf; + cp = fragment->buf; - for (i = 0; i < view.len*size; i += size) { + for (i = 0; i < fragment->len*width; i += width) { val = st_alaw2linear16(*cp++) << 16; - SETSAMPLE32(size, ncp, i, val); + SETSAMPLE32(width, ncp, i, val); } - exit: - PyBuffer_Release(&view); return rv; } +/*[clinic input] +audioop.lin2adpcm + + fragment: Py_buffer + width: int + state: object + / + +Convert samples to 4 bit Intel/DVI ADPCM encoding. +[clinic start generated code]*/ + static PyObject * -audioop_lin2adpcm(PyObject *self, PyObject *args) +audioop_lin2adpcm_impl(PyModuleDef *module, Py_buffer *fragment, int width, PyObject *state) +/*[clinic end generated code: output=4654c29d2731fafe input=12919d549b90c90a]*/ { - Py_buffer view; signed char *ncp; Py_ssize_t i; - int size, step, valpred, delta, + int step, valpred, delta, index, sign, vpdiff, diff; - PyObject *rv = NULL, *state, *str; + PyObject *rv = NULL, *str; int outputbuffer = 0, bufferstep; - if (!PyArg_ParseTuple(args, "y*iO:lin2adpcm", - &view, &size, &state)) + if (!audioop_check_parameters(fragment->len, width)) return NULL; - if (!audioop_check_parameters(view.len, size)) - goto exit; - - str = PyBytes_FromStringAndSize(NULL, view.len/(size*2)); + str = PyBytes_FromStringAndSize(NULL, fragment->len/(width*2)); if (str == NULL) - goto exit; + return NULL; ncp = (signed char *)PyBytes_AsString(str); /* Decode state, should have (value, step) */ @@ -1525,14 +1625,18 @@ audioop_lin2adpcm(PyObject *self, PyObject *args) /* First time, it seems. Set defaults */ valpred = 0; index = 0; - } else if (!PyArg_ParseTuple(state, "ii", &valpred, &index)) + } else if (!PyTuple_Check(state)) { + PyErr_SetString(PyExc_TypeError, "state must be a tuple or None"); + goto exit; + } else if (!PyArg_ParseTuple(state, "ii", &valpred, &index)) { goto exit; + } step = stepsizeTable[index]; bufferstep = 1; - for (i = 0; i < view.len; i += size) { - int val = GETSAMPLE32(size, view.buf, i) >> 16; + for (i = 0; i < fragment->len; i += width) { + int val = GETSAMPLE32(width, fragment->buf, i) >> 16; /* Step 1 - compute difference with previous value */ if (val < valpred) { @@ -1602,54 +1706,64 @@ audioop_lin2adpcm(PyObject *self, PyObject *args) bufferstep = !bufferstep; } rv = Py_BuildValue("(O(ii))", str, valpred, index); - Py_DECREF(str); + exit: - PyBuffer_Release(&view); + Py_DECREF(str); return rv; } +/*[clinic input] +audioop.adpcm2lin + + fragment: Py_buffer + width: int + state: object + / + +Decode an Intel/DVI ADPCM coded fragment to a linear fragment. +[clinic start generated code]*/ + static PyObject * -audioop_adpcm2lin(PyObject *self, PyObject *args) +audioop_adpcm2lin_impl(PyModuleDef *module, Py_buffer *fragment, int width, PyObject *state) +/*[clinic end generated code: output=371965cdcc0aa69b input=f5221144f5ca9ef0]*/ { - Py_buffer view; signed char *cp; signed char *ncp; Py_ssize_t i, outlen; - int size, valpred, step, delta, index, sign, vpdiff; - PyObject *rv = NULL, *str, *state; + int valpred, step, delta, index, sign, vpdiff; + PyObject *rv, *str; int inputbuffer = 0, bufferstep; - if (!PyArg_ParseTuple(args, "y*iO:adpcm2lin", - &view, &size, &state)) + if (!audioop_check_size(width)) return NULL; - if (!audioop_check_size(size)) - goto exit; - /* Decode state, should have (value, step) */ if ( state == Py_None ) { /* First time, it seems. Set defaults */ valpred = 0; index = 0; + } else if (!PyTuple_Check(state)) { + PyErr_SetString(PyExc_TypeError, "state must be a tuple or None"); + return NULL; } else if (!PyArg_ParseTuple(state, "ii", &valpred, &index)) - goto exit; + return NULL; - if (view.len > (PY_SSIZE_T_MAX/2)/size) { + if (fragment->len > (PY_SSIZE_T_MAX/2)/width) { PyErr_SetString(PyExc_MemoryError, "not enough memory for output buffer"); - goto exit; + return NULL; } - outlen = view.len*size*2; + outlen = fragment->len*width*2; str = PyBytes_FromStringAndSize(NULL, outlen); if (str == NULL) - goto exit; + return NULL; ncp = (signed char *)PyBytes_AsString(str); - cp = view.buf; + cp = fragment->buf; step = stepsizeTable[index]; bufferstep = 0; - for (i = 0; i < outlen; i += size) { + for (i = 0; i < outlen; i += width) { /* Step 1 - get the delta value and compute next index */ if ( bufferstep ) { delta = inputbuffer & 0xf; @@ -1694,43 +1808,43 @@ audioop_adpcm2lin(PyObject *self, PyObject *args) step = stepsizeTable[index]; /* Step 6 - Output value */ - SETSAMPLE32(size, ncp, i, valpred << 16); + SETSAMPLE32(width, ncp, i, valpred << 16); } rv = Py_BuildValue("(O(ii))", str, valpred, index); Py_DECREF(str); - exit: - PyBuffer_Release(&view); return rv; } +#include "clinic/audioop.c.h" + static PyMethodDef audioop_methods[] = { - { "max", audioop_max, METH_VARARGS }, - { "minmax", audioop_minmax, METH_VARARGS }, - { "avg", audioop_avg, METH_VARARGS }, - { "maxpp", audioop_maxpp, METH_VARARGS }, - { "avgpp", audioop_avgpp, METH_VARARGS }, - { "rms", audioop_rms, METH_VARARGS }, - { "findfit", audioop_findfit, METH_VARARGS }, - { "findmax", audioop_findmax, METH_VARARGS }, - { "findfactor", audioop_findfactor, METH_VARARGS }, - { "cross", audioop_cross, METH_VARARGS }, - { "mul", audioop_mul, METH_VARARGS }, - { "add", audioop_add, METH_VARARGS }, - { "bias", audioop_bias, METH_VARARGS }, - { "ulaw2lin", audioop_ulaw2lin, METH_VARARGS }, - { "lin2ulaw", audioop_lin2ulaw, METH_VARARGS }, - { "alaw2lin", audioop_alaw2lin, METH_VARARGS }, - { "lin2alaw", audioop_lin2alaw, METH_VARARGS }, - { "lin2lin", audioop_lin2lin, METH_VARARGS }, - { "adpcm2lin", audioop_adpcm2lin, METH_VARARGS }, - { "lin2adpcm", audioop_lin2adpcm, METH_VARARGS }, - { "tomono", audioop_tomono, METH_VARARGS }, - { "tostereo", audioop_tostereo, METH_VARARGS }, - { "getsample", audioop_getsample, METH_VARARGS }, - { "reverse", audioop_reverse, METH_VARARGS }, - { "byteswap", audioop_byteswap, METH_VARARGS }, - { "ratecv", audioop_ratecv, METH_VARARGS }, + AUDIOOP_MAX_METHODDEF + AUDIOOP_MINMAX_METHODDEF + AUDIOOP_AVG_METHODDEF + AUDIOOP_MAXPP_METHODDEF + AUDIOOP_AVGPP_METHODDEF + AUDIOOP_RMS_METHODDEF + AUDIOOP_FINDFIT_METHODDEF + AUDIOOP_FINDMAX_METHODDEF + AUDIOOP_FINDFACTOR_METHODDEF + AUDIOOP_CROSS_METHODDEF + AUDIOOP_MUL_METHODDEF + AUDIOOP_ADD_METHODDEF + AUDIOOP_BIAS_METHODDEF + AUDIOOP_ULAW2LIN_METHODDEF + AUDIOOP_LIN2ULAW_METHODDEF + AUDIOOP_ALAW2LIN_METHODDEF + AUDIOOP_LIN2ALAW_METHODDEF + AUDIOOP_LIN2LIN_METHODDEF + AUDIOOP_ADPCM2LIN_METHODDEF + AUDIOOP_LIN2ADPCM_METHODDEF + AUDIOOP_TOMONO_METHODDEF + AUDIOOP_TOSTEREO_METHODDEF + AUDIOOP_GETSAMPLE_METHODDEF + AUDIOOP_REVERSE_METHODDEF + AUDIOOP_BYTESWAP_METHODDEF + AUDIOOP_RATECV_METHODDEF { 0, 0 } }; diff --git a/Modules/binascii.c b/Modules/binascii.c index 0f4970141d3b..4e6953b8baa9 100644 --- a/Modules/binascii.c +++ b/Modules/binascii.c @@ -183,6 +183,27 @@ static unsigned short crctab_hqx[256] = { 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0, }; +/*[clinic input] +output preset file +module binascii +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=44c6f840ce708f0c]*/ + +/*[python input] + +class ascii_buffer_converter(CConverter): + type = 'Py_buffer' + converter = 'ascii_buffer_converter' + impl_by_reference = True + c_default = "{NULL, NULL}" + + def cleanup(self): + name = self.name + return "".join(["if (", name, ".obj)\n PyBuffer_Release(&", name, ");\n"]) + +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=3eb7b63610da92cd]*/ + static int ascii_buffer_converter(PyObject *arg, Py_buffer *buf) { @@ -207,26 +228,34 @@ ascii_buffer_converter(PyObject *arg, Py_buffer *buf) if (PyObject_GetBuffer(arg, buf, PyBUF_SIMPLE) != 0) { PyErr_Format(PyExc_TypeError, "argument should be bytes, buffer or ASCII string, " - "not %R", Py_TYPE(arg)); + "not '%.100s'", Py_TYPE(arg)->tp_name); return 0; } if (!PyBuffer_IsContiguous(buf, 'C')) { PyErr_Format(PyExc_TypeError, "argument should be a contiguous buffer, " - "not %R", Py_TYPE(arg)); + "not '%.100s'", Py_TYPE(arg)->tp_name); PyBuffer_Release(buf); return 0; } return Py_CLEANUP_SUPPORTED; } +#include "clinic/binascii.c.h" + +/*[clinic input] +binascii.a2b_uu -PyDoc_STRVAR(doc_a2b_uu, "(ascii) -> bin. Decode a line of uuencoded data"); + data: ascii_buffer + / + +Decode a line of uuencoded data. +[clinic start generated code]*/ static PyObject * -binascii_a2b_uu(PyObject *self, PyObject *args) +binascii_a2b_uu_impl(PyModuleDef *module, Py_buffer *data) +/*[clinic end generated code: output=5779f39b0b48459f input=7cafeaf73df63d1c]*/ { - Py_buffer pascii; unsigned char *ascii_data, *bin_data; int leftbits = 0; unsigned char this_ch; @@ -234,10 +263,8 @@ binascii_a2b_uu(PyObject *self, PyObject *args) PyObject *rv; Py_ssize_t ascii_len, bin_len; - if ( !PyArg_ParseTuple(args, "O&:a2b_uu", ascii_buffer_converter, &pascii) ) - return NULL; - ascii_data = pascii.buf; - ascii_len = pascii.len; + ascii_data = data->buf; + ascii_len = data->len; assert(ascii_len >= 0); @@ -246,10 +273,8 @@ binascii_a2b_uu(PyObject *self, PyObject *args) ascii_len--; /* Allocate the buffer */ - if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len)) == NULL ) { - PyBuffer_Release(&pascii); + if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len)) == NULL ) return NULL; - } bin_data = (unsigned char *)PyBytes_AS_STRING(rv); for( ; bin_len > 0 ; ascii_len--, ascii_data++ ) { @@ -269,7 +294,6 @@ binascii_a2b_uu(PyObject *self, PyObject *args) */ if ( this_ch < ' ' || this_ch > (' ' + 64)) { PyErr_SetString(Error, "Illegal char"); - PyBuffer_Release(&pascii); Py_DECREF(rv); return NULL; } @@ -298,21 +322,26 @@ binascii_a2b_uu(PyObject *self, PyObject *args) if ( this_ch != ' ' && this_ch != ' '+64 && this_ch != '\n' && this_ch != '\r' ) { PyErr_SetString(Error, "Trailing garbage"); - PyBuffer_Release(&pascii); Py_DECREF(rv); return NULL; } } - PyBuffer_Release(&pascii); return rv; } -PyDoc_STRVAR(doc_b2a_uu, "(bin) -> ascii. Uuencode line of data"); +/*[clinic input] +binascii.b2a_uu + + data: Py_buffer + / + +Uuencode line of data. +[clinic start generated code]*/ static PyObject * -binascii_b2a_uu(PyObject *self, PyObject *args) +binascii_b2a_uu_impl(PyModuleDef *module, Py_buffer *data) +/*[clinic end generated code: output=181021b69bb9a414 input=00fdf458ce8b465b]*/ { - Py_buffer pbin; unsigned char *ascii_data, *bin_data; int leftbits = 0; unsigned char this_ch; @@ -320,22 +349,17 @@ binascii_b2a_uu(PyObject *self, PyObject *args) PyObject *rv; Py_ssize_t bin_len; - if ( !PyArg_ParseTuple(args, "y*:b2a_uu", &pbin) ) - return NULL; - bin_data = pbin.buf; - bin_len = pbin.len; + bin_data = data->buf; + bin_len = data->len; if ( bin_len > 45 ) { /* The 45 is a limit that appears in all uuencode's */ PyErr_SetString(Error, "At most 45 bytes at once"); - PyBuffer_Release(&pbin); return NULL; } /* We're lazy and allocate to much (fixed up later) */ - if ( (rv=PyBytes_FromStringAndSize(NULL, 2 + (bin_len+2)/3*4)) == NULL ) { - PyBuffer_Release(&pbin); + if ( (rv=PyBytes_FromStringAndSize(NULL, 2 + (bin_len+2)/3*4)) == NULL ) return NULL; - } ascii_data = (unsigned char *)PyBytes_AS_STRING(rv); /* Store the length */ @@ -363,7 +387,6 @@ binascii_b2a_uu(PyObject *self, PyObject *args) (unsigned char *)PyBytes_AS_STRING(rv))) < 0) { Py_CLEAR(rv); } - PyBuffer_Release(&pbin); return rv; } @@ -393,12 +416,19 @@ binascii_find_valid(unsigned char *s, Py_ssize_t slen, int num) return ret; } -PyDoc_STRVAR(doc_a2b_base64, "(ascii) -> bin. Decode a line of base64 data"); +/*[clinic input] +binascii.a2b_base64 + + data: ascii_buffer + / + +Decode a line of base64 data. +[clinic start generated code]*/ static PyObject * -binascii_a2b_base64(PyObject *self, PyObject *args) +binascii_a2b_base64_impl(PyModuleDef *module, Py_buffer *data) +/*[clinic end generated code: output=3e351b702bed56d2 input=5872acf6e1cac243]*/ { - Py_buffer pascii; unsigned char *ascii_data, *bin_data; int leftbits = 0; unsigned char this_ch; @@ -407,25 +437,19 @@ binascii_a2b_base64(PyObject *self, PyObject *args) Py_ssize_t ascii_len, bin_len; int quad_pos = 0; - if ( !PyArg_ParseTuple(args, "O&:a2b_base64", ascii_buffer_converter, &pascii) ) - return NULL; - ascii_data = pascii.buf; - ascii_len = pascii.len; + ascii_data = data->buf; + ascii_len = data->len; assert(ascii_len >= 0); - if (ascii_len > PY_SSIZE_T_MAX - 3) { - PyBuffer_Release(&pascii); + if (ascii_len > PY_SSIZE_T_MAX - 3) return PyErr_NoMemory(); - } bin_len = ((ascii_len+3)/4)*3; /* Upper bound, corrected later */ /* Allocate the buffer */ - if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len)) == NULL ) { - PyBuffer_Release(&pascii); + if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len)) == NULL ) return NULL; - } bin_data = (unsigned char *)PyBytes_AS_STRING(rv); bin_len = 0; @@ -478,7 +502,6 @@ binascii_a2b_base64(PyObject *self, PyObject *args) } if (leftbits != 0) { - PyBuffer_Release(&pascii); PyErr_SetString(Error, "Incorrect padding"); Py_DECREF(rv); return NULL; @@ -497,16 +520,23 @@ binascii_a2b_base64(PyObject *self, PyObject *args) Py_DECREF(rv); rv = PyBytes_FromStringAndSize("", 0); } - PyBuffer_Release(&pascii); return rv; } -PyDoc_STRVAR(doc_b2a_base64, "(bin) -> ascii. Base64-code line of data"); + +/*[clinic input] +binascii.b2a_base64 + + data: Py_buffer + / + +Base64-code line of data. +[clinic start generated code]*/ static PyObject * -binascii_b2a_base64(PyObject *self, PyObject *args) +binascii_b2a_base64_impl(PyModuleDef *module, Py_buffer *data) +/*[clinic end generated code: output=3cd61fbee2913285 input=14ec4e47371174a9]*/ { - Py_buffer pbuf; unsigned char *ascii_data, *bin_data; int leftbits = 0; unsigned char this_ch; @@ -514,26 +544,21 @@ binascii_b2a_base64(PyObject *self, PyObject *args) PyObject *rv; Py_ssize_t bin_len; - if ( !PyArg_ParseTuple(args, "y*:b2a_base64", &pbuf) ) - return NULL; - bin_data = pbuf.buf; - bin_len = pbuf.len; + bin_data = data->buf; + bin_len = data->len; assert(bin_len >= 0); if ( bin_len > BASE64_MAXBIN ) { PyErr_SetString(Error, "Too much data for base64 line"); - PyBuffer_Release(&pbuf); return NULL; } /* We're lazy and allocate too much (fixed up later). "+3" leaves room for up to two pad characters and a trailing newline. Note that 'b' gets encoded as 'Yg==\n' (1 in, 5 out). */ - if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len*2 + 3)) == NULL ) { - PyBuffer_Release(&pbuf); + if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len*2 + 3)) == NULL ) return NULL; - } ascii_data = (unsigned char *)PyBytes_AS_STRING(rv); for( ; bin_len > 0 ; bin_len--, bin_data++ ) { @@ -563,16 +588,22 @@ binascii_b2a_base64(PyObject *self, PyObject *args) (unsigned char *)PyBytes_AS_STRING(rv))) < 0) { Py_CLEAR(rv); } - PyBuffer_Release(&pbuf); return rv; } -PyDoc_STRVAR(doc_a2b_hqx, "ascii -> bin, done. Decode .hqx coding"); +/*[clinic input] +binascii.a2b_hqx + + data: ascii_buffer + / + +Decode .hqx coding. +[clinic start generated code]*/ static PyObject * -binascii_a2b_hqx(PyObject *self, PyObject *args) +binascii_a2b_hqx_impl(PyModuleDef *module, Py_buffer *data) +/*[clinic end generated code: output=60bcdbbd28b105cd input=0d914c680e0eed55]*/ { - Py_buffer pascii; unsigned char *ascii_data, *bin_data; int leftbits = 0; unsigned char this_ch; @@ -581,25 +612,19 @@ binascii_a2b_hqx(PyObject *self, PyObject *args) Py_ssize_t len; int done = 0; - if ( !PyArg_ParseTuple(args, "O&:a2b_hqx", ascii_buffer_converter, &pascii) ) - return NULL; - ascii_data = pascii.buf; - len = pascii.len; + ascii_data = data->buf; + len = data->len; assert(len >= 0); - if (len > PY_SSIZE_T_MAX - 2) { - PyBuffer_Release(&pascii); + if (len > PY_SSIZE_T_MAX - 2) return PyErr_NoMemory(); - } /* Allocate a string that is too big (fixed later) Add two to the initial length to prevent interning which would preclude subsequent resizing. */ - if ( (rv=PyBytes_FromStringAndSize(NULL, len+2)) == NULL ) { - PyBuffer_Release(&pascii); + if ( (rv=PyBytes_FromStringAndSize(NULL, len+2)) == NULL ) return NULL; - } bin_data = (unsigned char *)PyBytes_AS_STRING(rv); for( ; len > 0 ; len--, ascii_data++ ) { @@ -609,7 +634,6 @@ binascii_a2b_hqx(PyObject *self, PyObject *args) continue; if ( this_ch == FAIL ) { PyErr_SetString(Error, "Illegal char"); - PyBuffer_Release(&pascii); Py_DECREF(rv); return NULL; } @@ -632,7 +656,6 @@ binascii_a2b_hqx(PyObject *self, PyObject *args) if ( leftbits && !done ) { PyErr_SetString(Incomplete, "String has incomplete number of bytes"); - PyBuffer_Release(&pascii); Py_DECREF(rv); return NULL; } @@ -643,43 +666,43 @@ binascii_a2b_hqx(PyObject *self, PyObject *args) } if (rv) { PyObject *rrv = Py_BuildValue("Oi", rv, done); - PyBuffer_Release(&pascii); Py_DECREF(rv); return rrv; } - PyBuffer_Release(&pascii); return NULL; } -PyDoc_STRVAR(doc_rlecode_hqx, "Binhex RLE-code binary data"); + +/*[clinic input] +binascii.rlecode_hqx + + data: Py_buffer + / + +Binhex RLE-code binary data. +[clinic start generated code]*/ static PyObject * -binascii_rlecode_hqx(PyObject *self, PyObject *args) +binascii_rlecode_hqx_impl(PyModuleDef *module, Py_buffer *data) +/*[clinic end generated code: output=0905da344dbf0648 input=e1f1712447a82b09]*/ { - Py_buffer pbuf; unsigned char *in_data, *out_data; PyObject *rv; unsigned char ch; Py_ssize_t in, inend, len; - if ( !PyArg_ParseTuple(args, "y*:rlecode_hqx", &pbuf) ) - return NULL; - in_data = pbuf.buf; - len = pbuf.len; + in_data = data->buf; + len = data->len; assert(len >= 0); - if (len > PY_SSIZE_T_MAX / 2 - 2) { - PyBuffer_Release(&pbuf); + if (len > PY_SSIZE_T_MAX / 2 - 2) return PyErr_NoMemory(); - } /* Worst case: output is twice as big as input (fixed later) */ - if ( (rv=PyBytes_FromStringAndSize(NULL, len*2+2)) == NULL ) { - PyBuffer_Release(&pbuf); + if ( (rv=PyBytes_FromStringAndSize(NULL, len*2+2)) == NULL ) return NULL; - } out_data = (unsigned char *)PyBytes_AS_STRING(rv); for( in=0; inbuf; + len = data->len; assert(len >= 0); - if (len > PY_SSIZE_T_MAX / 2 - 2) { - PyBuffer_Release(&pbin); + if (len > PY_SSIZE_T_MAX / 2 - 2) return PyErr_NoMemory(); - } /* Allocate a buffer that is at least large enough */ - if ( (rv=PyBytes_FromStringAndSize(NULL, len*2+2)) == NULL ) { - PyBuffer_Release(&pbin); + if ( (rv=PyBytes_FromStringAndSize(NULL, len*2+2)) == NULL ) return NULL; - } ascii_data = (unsigned char *)PyBytes_AS_STRING(rv); for( ; len > 0 ; len--, bin_data++ ) { @@ -767,44 +791,43 @@ binascii_b2a_hqx(PyObject *self, PyObject *args) (unsigned char *)PyBytes_AS_STRING(rv))) < 0) { Py_CLEAR(rv); } - PyBuffer_Release(&pbin); return rv; } -PyDoc_STRVAR(doc_rledecode_hqx, "Decode hexbin RLE-coded string"); + +/*[clinic input] +binascii.rledecode_hqx + + data: Py_buffer + / + +Decode hexbin RLE-coded string. +[clinic start generated code]*/ static PyObject * -binascii_rledecode_hqx(PyObject *self, PyObject *args) +binascii_rledecode_hqx_impl(PyModuleDef *module, Py_buffer *data) +/*[clinic end generated code: output=f7afd89b789946ab input=54cdd49fc014402c]*/ { - Py_buffer pin; unsigned char *in_data, *out_data; unsigned char in_byte, in_repeat; PyObject *rv; Py_ssize_t in_len, out_len, out_len_left; - if ( !PyArg_ParseTuple(args, "y*:rledecode_hqx", &pin) ) - return NULL; - in_data = pin.buf; - in_len = pin.len; + in_data = data->buf; + in_len = data->len; assert(in_len >= 0); /* Empty string is a special case */ - if ( in_len == 0 ) { - PyBuffer_Release(&pin); + if ( in_len == 0 ) return PyBytes_FromStringAndSize("", 0); - } - else if (in_len > PY_SSIZE_T_MAX / 2) { - PyBuffer_Release(&pin); + else if (in_len > PY_SSIZE_T_MAX / 2) return PyErr_NoMemory(); - } /* Allocate a buffer of reasonable size. Resized when needed */ out_len = in_len*2; - if ( (rv=PyBytes_FromStringAndSize(NULL, out_len)) == NULL ) { - PyBuffer_Release(&pin); + if ( (rv=PyBytes_FromStringAndSize(NULL, out_len)) == NULL ) return NULL; - } out_len_left = out_len; out_data = (unsigned char *)PyBytes_AS_STRING(rv); @@ -817,7 +840,6 @@ binascii_rledecode_hqx(PyObject *self, PyObject *args) if ( --in_len < 0 ) { \ PyErr_SetString(Incomplete, ""); \ Py_DECREF(rv); \ - PyBuffer_Release(&pin); \ return NULL; \ } \ b = *in_data++; \ @@ -828,7 +850,7 @@ binascii_rledecode_hqx(PyObject *self, PyObject *args) if ( --out_len_left < 0 ) { \ if ( out_len > PY_SSIZE_T_MAX / 2) return PyErr_NoMemory(); \ if (_PyBytes_Resize(&rv, 2*out_len) < 0) \ - { Py_XDECREF(rv); PyBuffer_Release(&pin); return NULL; } \ + { Py_XDECREF(rv); return NULL; } \ out_data = (unsigned char *)PyBytes_AS_STRING(rv) \ + out_len; \ out_len_left = out_len-1; \ @@ -850,7 +872,6 @@ binascii_rledecode_hqx(PyObject *self, PyObject *args) ** of the string only). This is a programmer error. */ PyErr_SetString(Error, "Orphaned RLE code at start"); - PyBuffer_Release(&pin); Py_DECREF(rv); return NULL; } @@ -883,57 +904,39 @@ binascii_rledecode_hqx(PyObject *self, PyObject *args) (unsigned char *)PyBytes_AS_STRING(rv))) < 0) { Py_CLEAR(rv); } - PyBuffer_Release(&pin); return rv; } -PyDoc_STRVAR(doc_crc_hqx, -"(data, oldcrc) -> newcrc. Compute hqx CRC incrementally"); -static PyObject * -binascii_crc_hqx(PyObject *self, PyObject *args) +/*[clinic input] +binascii.crc_hqx -> int + + data: Py_buffer + crc: int + / + +Compute hqx CRC incrementally. +[clinic start generated code]*/ + +static int +binascii_crc_hqx_impl(PyModuleDef *module, Py_buffer *data, int crc) +/*[clinic end generated code: output=634dac18dfa863d7 input=68060931b2f51c8a]*/ { - Py_buffer pin; unsigned char *bin_data; - unsigned int crc; + unsigned int ucrc = (unsigned int)crc; Py_ssize_t len; - if ( !PyArg_ParseTuple(args, "y*i:crc_hqx", &pin, &crc) ) - return NULL; - bin_data = pin.buf; - len = pin.len; + bin_data = data->buf; + len = data->len; while(len-- > 0) { - crc=((crc<<8)&0xff00)^crctab_hqx[((crc>>8)&0xff)^*bin_data++]; + ucrc=((ucrc<<8)&0xff00)^crctab_hqx[((ucrc>>8)&0xff)^*bin_data++]; } - PyBuffer_Release(&pin); - return Py_BuildValue("i", crc); + return (int)ucrc; } -PyDoc_STRVAR(doc_crc32, -"(data, oldcrc = 0) -> newcrc. Compute CRC-32 incrementally"); - -#ifdef USE_ZLIB_CRC32 -/* This was taken from zlibmodule.c PyZlib_crc32 (but is PY_SSIZE_T_CLEAN) */ -static PyObject * -binascii_crc32(PyObject *self, PyObject *args) -{ - unsigned int crc32val = 0; /* crc32(0L, Z_NULL, 0) */ - Py_buffer pbuf; - Byte *buf; - Py_ssize_t len; - int signed_val; - - if (!PyArg_ParseTuple(args, "y*|I:crc32", &pbuf, &crc32val)) - return NULL; - buf = (Byte*)pbuf.buf; - len = pbuf.len; - signed_val = crc32(crc32val, buf, len); - PyBuffer_Release(&pbuf); - return PyLong_FromUnsignedLong(signed_val & 0xffffffffU); -} -#else /* USE_ZLIB_CRC32 */ +#ifndef USE_ZLIB_CRC32 /* Crc - 32 BIT ANSI X3.66 CRC checksum files Also known as: ISO 3307 **********************************************************************| @@ -1051,20 +1054,42 @@ static unsigned int crc_32_tab[256] = { 0x5d681b02U, 0x2a6f2b94U, 0xb40bbe37U, 0xc30c8ea1U, 0x5a05df1bU, 0x2d02ef8dU }; +#endif /* USE_ZLIB_CRC32 */ -static PyObject * -binascii_crc32(PyObject *self, PyObject *args) +/*[clinic input] +binascii.crc32 -> unsigned_int + + data: Py_buffer + crc: unsigned_int(bitwise=True) = 0 + / + +Compute CRC-32 incrementally. +[clinic start generated code]*/ + +static unsigned int +binascii_crc32_impl(PyModuleDef *module, Py_buffer *data, unsigned int crc) +/*[clinic end generated code: output=620a961643393c4f input=bbe340bc99d25aa8]*/ + +#ifdef USE_ZLIB_CRC32 +/* This was taken from zlibmodule.c PyZlib_crc32 (but is PY_SSIZE_T_CLEAN) */ +{ + Byte *buf; + Py_ssize_t len; + int signed_val; + + buf = (Byte*)data->buf; + len = data->len; + signed_val = crc32(crc, buf, len); + return (unsigned int)signed_val & 0xffffffffU; +} +#else /* USE_ZLIB_CRC32 */ { /* By Jim Ahlstrom; All rights transferred to CNRI */ - Py_buffer pbin; unsigned char *bin_data; - unsigned int crc = 0; /* initial value of CRC */ Py_ssize_t len; unsigned int result; - if ( !PyArg_ParseTuple(args, "y*|I:crc32", &pbin, &crc) ) - return NULL; - bin_data = pbin.buf; - len = pbin.len; + bin_data = data->buf; + len = data->len; crc = ~ crc; while (len-- > 0) { @@ -1073,38 +1098,42 @@ binascii_crc32(PyObject *self, PyObject *args) } result = (crc ^ 0xFFFFFFFF); - PyBuffer_Release(&pbin); - return PyLong_FromUnsignedLong(result & 0xffffffff); + return result & 0xffffffff; } #endif /* USE_ZLIB_CRC32 */ +/*[clinic input] +binascii.b2a_hex + + data: Py_buffer + / + +Hexadecimal representation of binary data. + +The return value is a bytes object. This function is also +available as "hexlify()". +[clinic start generated code]*/ static PyObject * -binascii_hexlify(PyObject *self, PyObject *args) +binascii_b2a_hex_impl(PyModuleDef *module, Py_buffer *data) +/*[clinic end generated code: output=179318922c2f8fda input=96423cfa299ff3b1]*/ { - Py_buffer parg; char* argbuf; Py_ssize_t arglen; PyObject *retval; char* retbuf; Py_ssize_t i, j; - if (!PyArg_ParseTuple(args, "y*:b2a_hex", &parg)) - return NULL; - argbuf = parg.buf; - arglen = parg.len; + argbuf = data->buf; + arglen = data->len; assert(arglen >= 0); - if (arglen > PY_SSIZE_T_MAX / 2) { - PyBuffer_Release(&parg); + if (arglen > PY_SSIZE_T_MAX / 2) return PyErr_NoMemory(); - } retval = PyBytes_FromStringAndSize(NULL, arglen*2); - if (!retval) { - PyBuffer_Release(&parg); + if (!retval) return NULL; - } retbuf = PyBytes_AS_STRING(retval); /* make hex version of string, taken from shamodule.c */ @@ -1115,16 +1144,23 @@ binascii_hexlify(PyObject *self, PyObject *args) c = argbuf[i] & 0xf; retbuf[j++] = Py_hexdigits[c]; } - PyBuffer_Release(&parg); return retval; } -PyDoc_STRVAR(doc_hexlify, -"b2a_hex(data) -> s; Hexadecimal representation of binary data.\n\ -\n\ -The return value is a bytes object. This function is also\n\ -available as \"hexlify()\"."); +/*[clinic input] +binascii.hexlify = binascii.b2a_hex + +Hexadecimal representation of binary data. +The return value is a bytes object. +[clinic start generated code]*/ + +static PyObject * +binascii_hexlify_impl(PyModuleDef *module, Py_buffer *data) +/*[clinic end generated code: output=6098440091fb61dc input=2e3afae7f083f061]*/ +{ + return binascii_b2a_hex_impl(module, data); +} static int to_int(int c) @@ -1141,20 +1177,30 @@ to_int(int c) } +/*[clinic input] +binascii.a2b_hex + + hexstr: ascii_buffer + / + +Binary data of hexadecimal representation. + +hexstr must contain an even number of hex digits (upper or lower case). +This function is also available as "unhexlify()". +[clinic start generated code]*/ + static PyObject * -binascii_unhexlify(PyObject *self, PyObject *args) +binascii_a2b_hex_impl(PyModuleDef *module, Py_buffer *hexstr) +/*[clinic end generated code: output=d61da452b5c6d290 input=9e1e7f2f94db24fd]*/ { - Py_buffer parg; char* argbuf; Py_ssize_t arglen; PyObject *retval; char* retbuf; Py_ssize_t i, j; - if (!PyArg_ParseTuple(args, "O&:a2b_hex", ascii_buffer_converter, &parg)) - return NULL; - argbuf = parg.buf; - arglen = parg.len; + argbuf = hexstr->buf; + arglen = hexstr->len; assert(arglen >= 0); @@ -1163,16 +1209,13 @@ binascii_unhexlify(PyObject *self, PyObject *args) * raise an exception. */ if (arglen % 2) { - PyBuffer_Release(&parg); PyErr_SetString(Error, "Odd-length string"); return NULL; } retval = PyBytes_FromStringAndSize(NULL, (arglen/2)); - if (!retval) { - PyBuffer_Release(&parg); + if (!retval) return NULL; - } retbuf = PyBytes_AS_STRING(retval); for (i=j=0; i < arglen; i += 2) { @@ -1185,20 +1228,27 @@ binascii_unhexlify(PyObject *self, PyObject *args) } retbuf[j++] = (top << 4) + bot; } - PyBuffer_Release(&parg); return retval; finally: - PyBuffer_Release(&parg); Py_DECREF(retval); return NULL; } -PyDoc_STRVAR(doc_unhexlify, -"a2b_hex(hexstr) -> s; Binary data of hexadecimal representation.\n\ -\n\ -hexstr must contain an even number of hex digits (upper or lower case).\n\ -This function is also available as \"unhexlify()\""); +/*[clinic input] +binascii.unhexlify = binascii.a2b_hex + +Binary data of hexadecimal representation. + +hexstr must contain an even number of hex digits (upper or lower case). +[clinic start generated code]*/ + +static PyObject * +binascii_unhexlify_impl(PyModuleDef *module, Py_buffer *hexstr) +/*[clinic end generated code: output=17cec7544499803e input=dd8c012725f462da]*/ +{ + return binascii_a2b_hex_impl(module, hexstr); +} static int table_hex[128] = { -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, @@ -1215,25 +1265,28 @@ static int table_hex[128] = { #define MAXLINESIZE 76 -PyDoc_STRVAR(doc_a2b_qp, "Decode a string of qp-encoded data"); -static PyObject* -binascii_a2b_qp(PyObject *self, PyObject *args, PyObject *kwargs) +/*[clinic input] +binascii.a2b_qp + + data: ascii_buffer + header: int(c_default="0") = False + +Decode a string of qp-encoded data. +[clinic start generated code]*/ + +static PyObject * +binascii_a2b_qp_impl(PyModuleDef *module, Py_buffer *data, int header) +/*[clinic end generated code: output=a44ef88270352114 input=5187a0d3d8e54f3b]*/ { Py_ssize_t in, out; char ch; - Py_buffer pdata; - unsigned char *data, *odata; + unsigned char *ascii_data, *odata; Py_ssize_t datalen = 0; PyObject *rv; - static char *kwlist[] = {"data", "header", NULL}; - int header = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i:a2b_qp", kwlist, - ascii_buffer_converter, &pdata, &header)) - return NULL; - data = pdata.buf; - datalen = pdata.len; + ascii_data = data->buf; + datalen = data->len; /* We allocate the output same size as input, this is overkill. * The previous implementation used calloc() so we'll zero out the @@ -1241,7 +1294,6 @@ binascii_a2b_qp(PyObject *self, PyObject *args, PyObject *kwargs) */ odata = (unsigned char *) PyMem_Malloc(datalen); if (odata == NULL) { - PyBuffer_Release(&pdata); PyErr_NoMemory(); return NULL; } @@ -1249,31 +1301,31 @@ binascii_a2b_qp(PyObject *self, PyObject *args, PyObject *kwargs) in = out = 0; while (in < datalen) { - if (data[in] == '=') { + if (ascii_data[in] == '=') { in++; if (in >= datalen) break; /* Soft line breaks */ - if ((data[in] == '\n') || (data[in] == '\r')) { - if (data[in] != '\n') { - while (in < datalen && data[in] != '\n') in++; + if ((ascii_data[in] == '\n') || (ascii_data[in] == '\r')) { + if (ascii_data[in] != '\n') { + while (in < datalen && ascii_data[in] != '\n') in++; } if (in < datalen) in++; } - else if (data[in] == '=') { + else if (ascii_data[in] == '=') { /* broken case from broken python qp */ odata[out++] = '='; in++; } - else if (((data[in] >= 'A' && data[in] <= 'F') || - (data[in] >= 'a' && data[in] <= 'f') || - (data[in] >= '0' && data[in] <= '9')) && - ((data[in+1] >= 'A' && data[in+1] <= 'F') || - (data[in+1] >= 'a' && data[in+1] <= 'f') || - (data[in+1] >= '0' && data[in+1] <= '9'))) { + else if (((ascii_data[in] >= 'A' && ascii_data[in] <= 'F') || + (ascii_data[in] >= 'a' && ascii_data[in] <= 'f') || + (ascii_data[in] >= '0' && ascii_data[in] <= '9')) && + ((ascii_data[in+1] >= 'A' && ascii_data[in+1] <= 'F') || + (ascii_data[in+1] >= 'a' && ascii_data[in+1] <= 'f') || + (ascii_data[in+1] >= '0' && ascii_data[in+1] <= '9'))) { /* hexval */ - ch = hexval(data[in]) << 4; + ch = hexval(ascii_data[in]) << 4; in++; - ch |= hexval(data[in]); + ch |= hexval(ascii_data[in]); in++; odata[out++] = ch; } @@ -1281,22 +1333,20 @@ binascii_a2b_qp(PyObject *self, PyObject *args, PyObject *kwargs) odata[out++] = '='; } } - else if (header && data[in] == '_') { + else if (header && ascii_data[in] == '_') { odata[out++] = ' '; in++; } else { - odata[out] = data[in]; + odata[out] = ascii_data[in]; in++; out++; } } if ((rv = PyBytes_FromStringAndSize((char *)odata, out)) == NULL) { - PyBuffer_Release(&pdata); PyMem_Free(odata); return NULL; } - PyBuffer_Release(&pdata); PyMem_Free(odata); return rv; } @@ -1312,62 +1362,62 @@ to_hex (unsigned char ch, unsigned char *s) return 0; } -PyDoc_STRVAR(doc_b2a_qp, -"b2a_qp(data, quotetabs=0, istext=1, header=0) -> s; \n\ - Encode a string using quoted-printable encoding. \n\ -\n\ -On encoding, when istext is set, newlines are not encoded, and white \n\ -space at end of lines is. When istext is not set, \\r and \\n (CR/LF) are \n\ -both encoded. When quotetabs is set, space and tabs are encoded."); - /* XXX: This is ridiculously complicated to be backward compatible * (mostly) with the quopri module. It doesn't re-create the quopri * module bug where text ending in CRLF has the CR encoded */ -static PyObject* -binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs) + +/*[clinic input] +binascii.b2a_qp + + data: Py_buffer + quotetabs: int(c_default="0") = False + istext: int(c_default="1") = True + header: int(c_default="0") = False + +Encode a string using quoted-printable encoding. + +On encoding, when istext is set, newlines are not encoded, and white +space at end of lines is. When istext is not set, \r and \n (CR/LF) +are both encoded. When quotetabs is set, space and tabs are encoded. +[clinic start generated code]*/ + +static PyObject * +binascii_b2a_qp_impl(PyModuleDef *module, Py_buffer *data, int quotetabs, int istext, int header) +/*[clinic end generated code: output=ff2991ba640fff3e input=7f2a9aaa008e92b2]*/ { Py_ssize_t in, out; - Py_buffer pdata; - unsigned char *data, *odata; + unsigned char *databuf, *odata; Py_ssize_t datalen = 0, odatalen = 0; PyObject *rv; unsigned int linelen = 0; - static char *kwlist[] = {"data", "quotetabs", "istext", - "header", NULL}; - int istext = 1; - int quotetabs = 0; - int header = 0; unsigned char ch; int crlf = 0; unsigned char *p; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "y*|iii", kwlist, &pdata, - "etabs, &istext, &header)) - return NULL; - data = pdata.buf; - datalen = pdata.len; + databuf = data->buf; + datalen = data->len; /* See if this string is using CRLF line ends */ /* XXX: this function has the side effect of converting all of * the end of lines to be the same depending on this detection * here */ - p = (unsigned char *) memchr(data, '\n', datalen); - if ((p != NULL) && (p > data) && (*(p-1) == '\r')) + p = (unsigned char *) memchr(databuf, '\n', datalen); + if ((p != NULL) && (p > databuf) && (*(p-1) == '\r')) crlf = 1; /* First, scan to see how many characters need to be encoded */ in = 0; while (in < datalen) { - if ((data[in] > 126) || - (data[in] == '=') || - (header && data[in] == '_') || - ((data[in] == '.') && (linelen == 0) && - (data[in+1] == '\n' || data[in+1] == '\r' || data[in+1] == 0)) || - (!istext && ((data[in] == '\r') || (data[in] == '\n'))) || - ((data[in] == '\t' || data[in] == ' ') && (in + 1 == datalen)) || - ((data[in] < 33) && - (data[in] != '\r') && (data[in] != '\n') && - (quotetabs || ((data[in] != '\t') && (data[in] != ' '))))) + if ((databuf[in] > 126) || + (databuf[in] == '=') || + (header && databuf[in] == '_') || + ((databuf[in] == '.') && (linelen == 0) && + (databuf[in+1] == '\n' || databuf[in+1] == '\r' || databuf[in+1] == 0)) || + (!istext && ((databuf[in] == '\r') || (databuf[in] == '\n'))) || + ((databuf[in] == '\t' || databuf[in] == ' ') && (in + 1 == datalen)) || + ((databuf[in] < 33) && + (databuf[in] != '\r') && (databuf[in] != '\n') && + (quotetabs || ((databuf[in] != '\t') && (databuf[in] != ' '))))) { if ((linelen + 3) >= MAXLINESIZE) { linelen = 0; @@ -1382,26 +1432,26 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs) } else { if (istext && - ((data[in] == '\n') || - ((in+1 < datalen) && (data[in] == '\r') && - (data[in+1] == '\n')))) + ((databuf[in] == '\n') || + ((in+1 < datalen) && (databuf[in] == '\r') && + (databuf[in+1] == '\n')))) { linelen = 0; /* Protect against whitespace on end of line */ - if (in && ((data[in-1] == ' ') || (data[in-1] == '\t'))) + if (in && ((databuf[in-1] == ' ') || (databuf[in-1] == '\t'))) odatalen += 2; if (crlf) odatalen += 2; else odatalen += 1; - if (data[in] == '\r') + if (databuf[in] == '\r') in += 2; else in++; } else { if ((in + 1 != datalen) && - (data[in+1] != '\n') && + (databuf[in+1] != '\n') && (linelen + 1) >= MAXLINESIZE) { linelen = 0; if (crlf) @@ -1422,7 +1472,6 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs) */ odata = (unsigned char *) PyMem_Malloc(odatalen); if (odata == NULL) { - PyBuffer_Release(&pdata); PyErr_NoMemory(); return NULL; } @@ -1430,17 +1479,17 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs) in = out = linelen = 0; while (in < datalen) { - if ((data[in] > 126) || - (data[in] == '=') || - (header && data[in] == '_') || - ((data[in] == '.') && (linelen == 0) && - (data[in+1] == '\n' || data[in+1] == '\r' || data[in+1] == 0)) || - (!istext && ((data[in] == '\r') || (data[in] == '\n'))) || - ((data[in] == '\t' || data[in] == ' ') && (in + 1 == datalen)) || - ((data[in] < 33) && - (data[in] != '\r') && (data[in] != '\n') && + if ((databuf[in] > 126) || + (databuf[in] == '=') || + (header && databuf[in] == '_') || + ((databuf[in] == '.') && (linelen == 0) && + (databuf[in+1] == '\n' || databuf[in+1] == '\r' || databuf[in+1] == 0)) || + (!istext && ((databuf[in] == '\r') || (databuf[in] == '\n'))) || + ((databuf[in] == '\t' || databuf[in] == ' ') && (in + 1 == datalen)) || + ((databuf[in] < 33) && + (databuf[in] != '\r') && (databuf[in] != '\n') && (quotetabs || - (!quotetabs && ((data[in] != '\t') && (data[in] != ' ')))))) + (!quotetabs && ((databuf[in] != '\t') && (databuf[in] != ' ')))))) { if ((linelen + 3 )>= MAXLINESIZE) { odata[out++] = '='; @@ -1449,16 +1498,16 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs) linelen = 0; } odata[out++] = '='; - to_hex(data[in], &odata[out]); + to_hex(databuf[in], &odata[out]); out += 2; in++; linelen += 3; } else { if (istext && - ((data[in] == '\n') || - ((in+1 < datalen) && (data[in] == '\r') && - (data[in+1] == '\n')))) + ((databuf[in] == '\n') || + ((in+1 < datalen) && (databuf[in] == '\r') && + (databuf[in+1] == '\n')))) { linelen = 0; /* Protect against whitespace on end of line */ @@ -1471,14 +1520,14 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs) if (crlf) odata[out++] = '\r'; odata[out++] = '\n'; - if (data[in] == '\r') + if (databuf[in] == '\r') in += 2; else in++; } else { if ((in + 1 != datalen) && - (data[in+1] != '\n') && + (databuf[in+1] != '\n') && (linelen + 1) >= MAXLINESIZE) { odata[out++] = '='; if (crlf) odata[out++] = '\r'; @@ -1486,22 +1535,20 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs) linelen = 0; } linelen++; - if (header && data[in] == ' ') { + if (header && databuf[in] == ' ') { odata[out++] = '_'; in++; } else { - odata[out++] = data[in++]; + odata[out++] = databuf[in++]; } } } } if ((rv = PyBytes_FromStringAndSize((char *)odata, out)) == NULL) { - PyBuffer_Release(&pdata); PyMem_Free(odata); return NULL; } - PyBuffer_Release(&pdata); PyMem_Free(odata); return rv; } @@ -1509,25 +1556,22 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs) /* List of functions defined in the module */ static struct PyMethodDef binascii_module_methods[] = { - {"a2b_uu", binascii_a2b_uu, METH_VARARGS, doc_a2b_uu}, - {"b2a_uu", binascii_b2a_uu, METH_VARARGS, doc_b2a_uu}, - {"a2b_base64", binascii_a2b_base64, METH_VARARGS, doc_a2b_base64}, - {"b2a_base64", binascii_b2a_base64, METH_VARARGS, doc_b2a_base64}, - {"a2b_hqx", binascii_a2b_hqx, METH_VARARGS, doc_a2b_hqx}, - {"b2a_hqx", binascii_b2a_hqx, METH_VARARGS, doc_b2a_hqx}, - {"b2a_hex", binascii_hexlify, METH_VARARGS, doc_hexlify}, - {"a2b_hex", binascii_unhexlify, METH_VARARGS, doc_unhexlify}, - {"hexlify", binascii_hexlify, METH_VARARGS, doc_hexlify}, - {"unhexlify", binascii_unhexlify, METH_VARARGS, doc_unhexlify}, - {"rlecode_hqx", binascii_rlecode_hqx, METH_VARARGS, doc_rlecode_hqx}, - {"rledecode_hqx", binascii_rledecode_hqx, METH_VARARGS, - doc_rledecode_hqx}, - {"crc_hqx", binascii_crc_hqx, METH_VARARGS, doc_crc_hqx}, - {"crc32", binascii_crc32, METH_VARARGS, doc_crc32}, - {"a2b_qp", (PyCFunction)binascii_a2b_qp, METH_VARARGS | METH_KEYWORDS, - doc_a2b_qp}, - {"b2a_qp", (PyCFunction)binascii_b2a_qp, METH_VARARGS | METH_KEYWORDS, - doc_b2a_qp}, + BINASCII_A2B_UU_METHODDEF + BINASCII_B2A_UU_METHODDEF + BINASCII_A2B_BASE64_METHODDEF + BINASCII_B2A_BASE64_METHODDEF + BINASCII_A2B_HQX_METHODDEF + BINASCII_B2A_HQX_METHODDEF + BINASCII_A2B_HEX_METHODDEF + BINASCII_B2A_HEX_METHODDEF + BINASCII_HEXLIFY_METHODDEF + BINASCII_UNHEXLIFY_METHODDEF + BINASCII_RLECODE_HQX_METHODDEF + BINASCII_RLEDECODE_HQX_METHODDEF + BINASCII_CRC_HQX_METHODDEF + BINASCII_CRC32_METHODDEF + BINASCII_A2B_QP_METHODDEF + BINASCII_B2A_QP_METHODDEF {NULL, NULL} /* sentinel */ }; diff --git a/Modules/cjkcodecs/_codecs_cn.c b/Modules/cjkcodecs/_codecs_cn.c index 013c3fb6b77b..1a070f2f3932 100644 --- a/Modules/cjkcodecs/_codecs_cn.c +++ b/Modules/cjkcodecs/_codecs_cn.c @@ -15,7 +15,7 @@ #undef hz #endif -/* GBK and GB2312 map differently in few codepoints that are listed below: +/* GBK and GB2312 map differently in few code points that are listed below: * * gb2312 gbk * A1A4 U+30FB KATAKANA MIDDLE DOT U+00B7 MIDDLE DOT diff --git a/Modules/cjkcodecs/_codecs_hk.c b/Modules/cjkcodecs/_codecs_hk.c index b7a7ebd6e12d..4f21569a0ce7 100644 --- a/Modules/cjkcodecs/_codecs_hk.c +++ b/Modules/cjkcodecs/_codecs_hk.c @@ -171,7 +171,7 @@ DECODER(big5hkscs) default: return 1; } - NEXT_IN(2); /* all decoded codepoints are pairs, above. */ + NEXT_IN(2); /* all decoded code points are pairs, above. */ } return 0; diff --git a/Modules/cjkcodecs/_codecs_iso2022.c b/Modules/cjkcodecs/_codecs_iso2022.c index 5c401aaf8e93..1ce4218f3089 100644 --- a/Modules/cjkcodecs/_codecs_iso2022.c +++ b/Modules/cjkcodecs/_codecs_iso2022.c @@ -292,7 +292,7 @@ iso2022processesc(const void *config, MultibyteCodec_State *state, const unsigned char **inbuf, Py_ssize_t *inleft) { unsigned char charset, designation; - Py_ssize_t i, esclen; + Py_ssize_t i, esclen = 0; for (i = 1;i < MAX_ESCSEQLEN;i++) { if (i >= *inleft) @@ -307,10 +307,9 @@ iso2022processesc(const void *config, MultibyteCodec_State *state, } } - if (i >= MAX_ESCSEQLEN) - return 1; /* unterminated escape sequence */ - switch (esclen) { + case 0: + return 1; /* unterminated escape sequence */ case 3: if (INBYTE2 == '$') { charset = INBYTE3 | CHARSET_DBCS; diff --git a/Modules/cjkcodecs/_codecs_kr.c b/Modules/cjkcodecs/_codecs_kr.c index 1ad41a7851f1..6d6acb5c4be4 100644 --- a/Modules/cjkcodecs/_codecs_kr.c +++ b/Modules/cjkcodecs/_codecs_kr.c @@ -69,7 +69,7 @@ ENCODER(euc_kr) OUTBYTE1(EUCKR_JAMO_FIRSTBYTE); OUTBYTE2(EUCKR_JAMO_FILLER); - /* All codepoints in CP949 extension are in unicode + /* All code points in CP949 extension are in unicode * Hangul Syllable area. */ assert(0xac00 <= c && c <= 0xd7a3); c -= 0xac00; diff --git a/Modules/cjkcodecs/cjkcodecs.h b/Modules/cjkcodecs/cjkcodecs.h index 25bab41cf3f8..a45ed125fa80 100644 --- a/Modules/cjkcodecs/cjkcodecs.h +++ b/Modules/cjkcodecs/cjkcodecs.h @@ -12,10 +12,10 @@ #include "multibytecodec.h" -/* a unicode "undefined" codepoint */ +/* a unicode "undefined" code point */ #define UNIINV 0xFFFE -/* internal-use DBCS codepoints which aren't used by any charsets */ +/* internal-use DBCS code points which aren't used by any charsets */ #define NOCHAR 0xFFFF #define MULTIC 0xFFFE #define DBCINV 0xFFFD @@ -362,7 +362,7 @@ importmap(const char *modname, const char *symbol, if (mod == NULL) return -1; - o = PyObject_GetAttrString(mod, (char*)symbol); + o = PyObject_GetAttrString(mod, symbol); if (o == NULL) goto errorexit; else if (!PyCapsule_IsValid(o, PyMultibyteCodec_CAPSULE_NAME)) { diff --git a/Modules/cjkcodecs/clinic/multibytecodec.c.h b/Modules/cjkcodecs/clinic/multibytecodec.c.h new file mode 100644 index 000000000000..2f9cb6392764 --- /dev/null +++ b/Modules/cjkcodecs/clinic/multibytecodec.c.h @@ -0,0 +1,301 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_multibytecodec_MultibyteCodec_encode__doc__, +"encode($self, /, input, errors=None)\n" +"--\n" +"\n" +"Return an encoded string version of `input\'.\n" +"\n" +"\'errors\' may be given to set a different error handling scheme. Default is\n" +"\'strict\' meaning that encoding errors raise a UnicodeEncodeError. Other possible\n" +"values are \'ignore\', \'replace\' and \'xmlcharrefreplace\' as well as any other name\n" +"registered with codecs.register_error that can handle UnicodeEncodeErrors."); + +#define _MULTIBYTECODEC_MULTIBYTECODEC_ENCODE_METHODDEF \ + {"encode", (PyCFunction)_multibytecodec_MultibyteCodec_encode, METH_VARARGS|METH_KEYWORDS, _multibytecodec_MultibyteCodec_encode__doc__}, + +static PyObject * +_multibytecodec_MultibyteCodec_encode_impl(MultibyteCodecObject *self, PyObject *input, const char *errors); + +static PyObject * +_multibytecodec_MultibyteCodec_encode(MultibyteCodecObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"input", "errors", NULL}; + PyObject *input; + const char *errors = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O|z:encode", _keywords, + &input, &errors)) + goto exit; + return_value = _multibytecodec_MultibyteCodec_encode_impl(self, input, errors); + +exit: + return return_value; +} + +PyDoc_STRVAR(_multibytecodec_MultibyteCodec_decode__doc__, +"decode($self, /, input, errors=None)\n" +"--\n" +"\n" +"Decodes \'input\'.\n" +"\n" +"\'errors\' may be given to set a different error handling scheme. Default is\n" +"\'strict\' meaning that encoding errors raise a UnicodeDecodeError. Other possible\n" +"values are \'ignore\' and \'replace\' as well as any other name registered with\n" +"codecs.register_error that is able to handle UnicodeDecodeErrors.\""); + +#define _MULTIBYTECODEC_MULTIBYTECODEC_DECODE_METHODDEF \ + {"decode", (PyCFunction)_multibytecodec_MultibyteCodec_decode, METH_VARARGS|METH_KEYWORDS, _multibytecodec_MultibyteCodec_decode__doc__}, + +static PyObject * +_multibytecodec_MultibyteCodec_decode_impl(MultibyteCodecObject *self, Py_buffer *input, const char *errors); + +static PyObject * +_multibytecodec_MultibyteCodec_decode(MultibyteCodecObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"input", "errors", NULL}; + Py_buffer input = {NULL, NULL}; + const char *errors = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "y*|z:decode", _keywords, + &input, &errors)) + goto exit; + return_value = _multibytecodec_MultibyteCodec_decode_impl(self, &input, errors); + +exit: + /* Cleanup for input */ + if (input.obj) + PyBuffer_Release(&input); + + return return_value; +} + +PyDoc_STRVAR(_multibytecodec_MultibyteIncrementalEncoder_encode__doc__, +"encode($self, /, input, final=0)\n" +"--"); + +#define _MULTIBYTECODEC_MULTIBYTEINCREMENTALENCODER_ENCODE_METHODDEF \ + {"encode", (PyCFunction)_multibytecodec_MultibyteIncrementalEncoder_encode, METH_VARARGS|METH_KEYWORDS, _multibytecodec_MultibyteIncrementalEncoder_encode__doc__}, + +static PyObject * +_multibytecodec_MultibyteIncrementalEncoder_encode_impl(MultibyteIncrementalEncoderObject *self, PyObject *input, int final); + +static PyObject * +_multibytecodec_MultibyteIncrementalEncoder_encode(MultibyteIncrementalEncoderObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"input", "final", NULL}; + PyObject *input; + int final = 0; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O|i:encode", _keywords, + &input, &final)) + goto exit; + return_value = _multibytecodec_MultibyteIncrementalEncoder_encode_impl(self, input, final); + +exit: + return return_value; +} + +PyDoc_STRVAR(_multibytecodec_MultibyteIncrementalEncoder_reset__doc__, +"reset($self, /)\n" +"--"); + +#define _MULTIBYTECODEC_MULTIBYTEINCREMENTALENCODER_RESET_METHODDEF \ + {"reset", (PyCFunction)_multibytecodec_MultibyteIncrementalEncoder_reset, METH_NOARGS, _multibytecodec_MultibyteIncrementalEncoder_reset__doc__}, + +static PyObject * +_multibytecodec_MultibyteIncrementalEncoder_reset_impl(MultibyteIncrementalEncoderObject *self); + +static PyObject * +_multibytecodec_MultibyteIncrementalEncoder_reset(MultibyteIncrementalEncoderObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _multibytecodec_MultibyteIncrementalEncoder_reset_impl(self); +} + +PyDoc_STRVAR(_multibytecodec_MultibyteIncrementalDecoder_decode__doc__, +"decode($self, /, input, final=0)\n" +"--"); + +#define _MULTIBYTECODEC_MULTIBYTEINCREMENTALDECODER_DECODE_METHODDEF \ + {"decode", (PyCFunction)_multibytecodec_MultibyteIncrementalDecoder_decode, METH_VARARGS|METH_KEYWORDS, _multibytecodec_MultibyteIncrementalDecoder_decode__doc__}, + +static PyObject * +_multibytecodec_MultibyteIncrementalDecoder_decode_impl(MultibyteIncrementalDecoderObject *self, Py_buffer *input, int final); + +static PyObject * +_multibytecodec_MultibyteIncrementalDecoder_decode(MultibyteIncrementalDecoderObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"input", "final", NULL}; + Py_buffer input = {NULL, NULL}; + int final = 0; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "y*|i:decode", _keywords, + &input, &final)) + goto exit; + return_value = _multibytecodec_MultibyteIncrementalDecoder_decode_impl(self, &input, final); + +exit: + /* Cleanup for input */ + if (input.obj) + PyBuffer_Release(&input); + + return return_value; +} + +PyDoc_STRVAR(_multibytecodec_MultibyteIncrementalDecoder_reset__doc__, +"reset($self, /)\n" +"--"); + +#define _MULTIBYTECODEC_MULTIBYTEINCREMENTALDECODER_RESET_METHODDEF \ + {"reset", (PyCFunction)_multibytecodec_MultibyteIncrementalDecoder_reset, METH_NOARGS, _multibytecodec_MultibyteIncrementalDecoder_reset__doc__}, + +static PyObject * +_multibytecodec_MultibyteIncrementalDecoder_reset_impl(MultibyteIncrementalDecoderObject *self); + +static PyObject * +_multibytecodec_MultibyteIncrementalDecoder_reset(MultibyteIncrementalDecoderObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _multibytecodec_MultibyteIncrementalDecoder_reset_impl(self); +} + +PyDoc_STRVAR(_multibytecodec_MultibyteStreamReader_read__doc__, +"read($self, sizeobj=None, /)\n" +"--"); + +#define _MULTIBYTECODEC_MULTIBYTESTREAMREADER_READ_METHODDEF \ + {"read", (PyCFunction)_multibytecodec_MultibyteStreamReader_read, METH_VARARGS, _multibytecodec_MultibyteStreamReader_read__doc__}, + +static PyObject * +_multibytecodec_MultibyteStreamReader_read_impl(MultibyteStreamReaderObject *self, PyObject *sizeobj); + +static PyObject * +_multibytecodec_MultibyteStreamReader_read(MultibyteStreamReaderObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *sizeobj = Py_None; + + if (!PyArg_UnpackTuple(args, "read", + 0, 1, + &sizeobj)) + goto exit; + return_value = _multibytecodec_MultibyteStreamReader_read_impl(self, sizeobj); + +exit: + return return_value; +} + +PyDoc_STRVAR(_multibytecodec_MultibyteStreamReader_readline__doc__, +"readline($self, sizeobj=None, /)\n" +"--"); + +#define _MULTIBYTECODEC_MULTIBYTESTREAMREADER_READLINE_METHODDEF \ + {"readline", (PyCFunction)_multibytecodec_MultibyteStreamReader_readline, METH_VARARGS, _multibytecodec_MultibyteStreamReader_readline__doc__}, + +static PyObject * +_multibytecodec_MultibyteStreamReader_readline_impl(MultibyteStreamReaderObject *self, PyObject *sizeobj); + +static PyObject * +_multibytecodec_MultibyteStreamReader_readline(MultibyteStreamReaderObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *sizeobj = Py_None; + + if (!PyArg_UnpackTuple(args, "readline", + 0, 1, + &sizeobj)) + goto exit; + return_value = _multibytecodec_MultibyteStreamReader_readline_impl(self, sizeobj); + +exit: + return return_value; +} + +PyDoc_STRVAR(_multibytecodec_MultibyteStreamReader_readlines__doc__, +"readlines($self, sizehintobj=None, /)\n" +"--"); + +#define _MULTIBYTECODEC_MULTIBYTESTREAMREADER_READLINES_METHODDEF \ + {"readlines", (PyCFunction)_multibytecodec_MultibyteStreamReader_readlines, METH_VARARGS, _multibytecodec_MultibyteStreamReader_readlines__doc__}, + +static PyObject * +_multibytecodec_MultibyteStreamReader_readlines_impl(MultibyteStreamReaderObject *self, PyObject *sizehintobj); + +static PyObject * +_multibytecodec_MultibyteStreamReader_readlines(MultibyteStreamReaderObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *sizehintobj = Py_None; + + if (!PyArg_UnpackTuple(args, "readlines", + 0, 1, + &sizehintobj)) + goto exit; + return_value = _multibytecodec_MultibyteStreamReader_readlines_impl(self, sizehintobj); + +exit: + return return_value; +} + +PyDoc_STRVAR(_multibytecodec_MultibyteStreamReader_reset__doc__, +"reset($self, /)\n" +"--"); + +#define _MULTIBYTECODEC_MULTIBYTESTREAMREADER_RESET_METHODDEF \ + {"reset", (PyCFunction)_multibytecodec_MultibyteStreamReader_reset, METH_NOARGS, _multibytecodec_MultibyteStreamReader_reset__doc__}, + +static PyObject * +_multibytecodec_MultibyteStreamReader_reset_impl(MultibyteStreamReaderObject *self); + +static PyObject * +_multibytecodec_MultibyteStreamReader_reset(MultibyteStreamReaderObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _multibytecodec_MultibyteStreamReader_reset_impl(self); +} + +PyDoc_STRVAR(_multibytecodec_MultibyteStreamWriter_write__doc__, +"write($self, strobj, /)\n" +"--"); + +#define _MULTIBYTECODEC_MULTIBYTESTREAMWRITER_WRITE_METHODDEF \ + {"write", (PyCFunction)_multibytecodec_MultibyteStreamWriter_write, METH_O, _multibytecodec_MultibyteStreamWriter_write__doc__}, + +PyDoc_STRVAR(_multibytecodec_MultibyteStreamWriter_writelines__doc__, +"writelines($self, lines, /)\n" +"--"); + +#define _MULTIBYTECODEC_MULTIBYTESTREAMWRITER_WRITELINES_METHODDEF \ + {"writelines", (PyCFunction)_multibytecodec_MultibyteStreamWriter_writelines, METH_O, _multibytecodec_MultibyteStreamWriter_writelines__doc__}, + +PyDoc_STRVAR(_multibytecodec_MultibyteStreamWriter_reset__doc__, +"reset($self, /)\n" +"--"); + +#define _MULTIBYTECODEC_MULTIBYTESTREAMWRITER_RESET_METHODDEF \ + {"reset", (PyCFunction)_multibytecodec_MultibyteStreamWriter_reset, METH_NOARGS, _multibytecodec_MultibyteStreamWriter_reset__doc__}, + +static PyObject * +_multibytecodec_MultibyteStreamWriter_reset_impl(MultibyteStreamWriterObject *self); + +static PyObject * +_multibytecodec_MultibyteStreamWriter_reset(MultibyteStreamWriterObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _multibytecodec_MultibyteStreamWriter_reset_impl(self); +} + +PyDoc_STRVAR(_multibytecodec___create_codec__doc__, +"__create_codec($module, arg, /)\n" +"--"); + +#define _MULTIBYTECODEC___CREATE_CODEC_METHODDEF \ + {"__create_codec", (PyCFunction)_multibytecodec___create_codec, METH_O, _multibytecodec___create_codec__doc__}, +/*[clinic end generated code: output=dff1459dec464796 input=a9049054013a1b77]*/ diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c index 087ae9b1aff5..fe5b36256f42 100644 --- a/Modules/cjkcodecs/multibytecodec.c +++ b/Modules/cjkcodecs/multibytecodec.c @@ -8,6 +8,18 @@ #include "Python.h" #include "structmember.h" #include "multibytecodec.h" +#include "clinic/multibytecodec.c.h" + +/*[clinic input] +output preset file +module _multibytecodec +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=e0cf1b7f3c472d17]*/ + +/*[clinic input] +class _multibytecodec.MultibyteCodec "MultibyteCodecObject *" "&MultibyteCodec_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=d5b1fc1fec8eb003]*/ typedef struct { PyObject *inobj; @@ -22,27 +34,7 @@ typedef struct { _PyUnicodeWriter writer; } MultibyteDecodeBuffer; -PyDoc_STRVAR(MultibyteCodec_Encode__doc__, -"I.encode(unicode[, errors]) -> (string, length consumed)\n\ -\n\ -Return an encoded string version of `unicode'. errors may be given to\n\ -set a different error handling scheme. Default is 'strict' meaning that\n\ -encoding errors raise a UnicodeEncodeError. Other possible values are\n\ -'ignore', 'replace' and 'xmlcharrefreplace' as well as any other name\n\ -registered with codecs.register_error that can handle UnicodeEncodeErrors."); - -PyDoc_STRVAR(MultibyteCodec_Decode__doc__, -"I.decode(string[, errors]) -> (unicodeobject, length consumed)\n\ -\n\ -Decodes `string' using I, an MultibyteCodec instance. errors may be given\n\ -to set a different error handling scheme. Default is 'strict' meaning\n\ -that encoding errors raise a UnicodeDecodeError. Other possible values\n\ -are 'ignore' and 'replace' as well as any other name registered with\n\ -codecs.register_error that is able to handle UnicodeDecodeErrors."); - -static char *codeckwarglist[] = {"input", "errors", NULL}; static char *incnewkwarglist[] = {"errors", NULL}; -static char *incrementalkwarglist[] = {"input", "final", NULL}; static char *streamkwarglist[] = {"stream", "errors", NULL}; static PyObject *multibytecodec_encode(MultibyteCodec *, @@ -182,8 +174,10 @@ expand_encodebuffer(MultibyteEncodeBuffer *buf, Py_ssize_t esize) orgsize = PyBytes_GET_SIZE(buf->outobj); incsize = (esize < (orgsize >> 1) ? (orgsize >> 1) | 1 : esize); - if (orgsize > PY_SSIZE_T_MAX - incsize) + if (orgsize > PY_SSIZE_T_MAX - incsize) { + PyErr_NoMemory(); return -1; + } if (_PyBytes_Resize(&buf->outobj, orgsize + incsize) == -1) return -1; @@ -194,11 +188,11 @@ expand_encodebuffer(MultibyteEncodeBuffer *buf, Py_ssize_t esize) return 0; } -#define REQUIRE_ENCODEBUFFER(buf, s) { \ - if ((s) < 1 || (buf)->outbuf + (s) > (buf)->outbuf_end) \ +#define REQUIRE_ENCODEBUFFER(buf, s) do { \ + if ((s) < 0 || (s) > (buf)->outbuf_end - (buf)->outbuf) \ if (expand_encodebuffer(buf, s) == -1) \ goto errorexit; \ -} +} while(0) /** @@ -332,10 +326,11 @@ multibytecodec_encerror(MultibyteCodec *codec, assert(PyBytes_Check(retstr)); retstrsize = PyBytes_GET_SIZE(retstr); - REQUIRE_ENCODEBUFFER(buf, retstrsize); - - memcpy(buf->outbuf, PyBytes_AS_STRING(retstr), retstrsize); - buf->outbuf += retstrsize; + if (retstrsize > 0) { + REQUIRE_ENCODEBUFFER(buf, retstrsize); + memcpy(buf->outbuf, PyBytes_AS_STRING(retstr), retstrsize); + buf->outbuf += retstrsize; + } newpos = PyLong_AsSsize_t(PyTuple_GET_ITEM(retobj, 1)); if (newpos < 0 && !PyErr_Occurred()) @@ -550,26 +545,35 @@ multibytecodec_encode(MultibyteCodec *codec, return NULL; } +/*[clinic input] +_multibytecodec.MultibyteCodec.encode + + input: object + errors: str(nullable=True) = NULL + +Return an encoded string version of `input'. + +'errors' may be given to set a different error handling scheme. Default is +'strict' meaning that encoding errors raise a UnicodeEncodeError. Other possible +values are 'ignore', 'replace' and 'xmlcharrefreplace' as well as any other name +registered with codecs.register_error that can handle UnicodeEncodeErrors. +[clinic start generated code]*/ + static PyObject * -MultibyteCodec_Encode(MultibyteCodecObject *self, - PyObject *args, PyObject *kwargs) +_multibytecodec_MultibyteCodec_encode_impl(MultibyteCodecObject *self, PyObject *input, const char *errors) +/*[clinic end generated code: output=a36bfa08783a0d0b input=252e7ee695867b2d]*/ { MultibyteCodec_State state; - PyObject *errorcb, *r, *arg, *ucvt; - const char *errors = NULL; + PyObject *errorcb, *r, *ucvt; Py_ssize_t datalen; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|z:encode", - codeckwarglist, &arg, &errors)) - return NULL; - - if (PyUnicode_Check(arg)) + if (PyUnicode_Check(input)) ucvt = NULL; else { - arg = ucvt = PyObject_Str(arg); - if (arg == NULL) + input = ucvt = PyObject_Str(input); + if (input == NULL) return NULL; - else if (!PyUnicode_Check(arg)) { + else if (!PyUnicode_Check(input)) { PyErr_SetString(PyExc_TypeError, "couldn't convert the object to unicode."); Py_DECREF(ucvt); @@ -577,11 +581,11 @@ MultibyteCodec_Encode(MultibyteCodecObject *self, } } - if (PyUnicode_READY(arg) < 0) { + if (PyUnicode_READY(input) < 0) { Py_XDECREF(ucvt); return NULL; } - datalen = PyUnicode_GET_LENGTH(arg); + datalen = PyUnicode_GET_LENGTH(input); errorcb = internal_error_callback(errors); if (errorcb == NULL) { @@ -593,7 +597,7 @@ MultibyteCodec_Encode(MultibyteCodecObject *self, self->codec->encinit(&state, self->codec->config) != 0) goto errorexit; r = multibytecodec_encode(self->codec, &state, - arg, NULL, errorcb, + input, NULL, errorcb, MBENC_FLUSH | MBENC_RESET); if (r == NULL) goto errorexit; @@ -608,31 +612,39 @@ MultibyteCodec_Encode(MultibyteCodecObject *self, return NULL; } +/*[clinic input] +_multibytecodec.MultibyteCodec.decode + + input: Py_buffer + errors: str(nullable=True) = NULL + +Decodes 'input'. + +'errors' may be given to set a different error handling scheme. Default is +'strict' meaning that encoding errors raise a UnicodeDecodeError. Other possible +values are 'ignore' and 'replace' as well as any other name registered with +codecs.register_error that is able to handle UnicodeDecodeErrors." +[clinic start generated code]*/ + static PyObject * -MultibyteCodec_Decode(MultibyteCodecObject *self, - PyObject *args, PyObject *kwargs) +_multibytecodec_MultibyteCodec_decode_impl(MultibyteCodecObject *self, Py_buffer *input, const char *errors) +/*[clinic end generated code: output=4c8ee8b2931b014e input=37e1d9236e3ce8f3]*/ { MultibyteCodec_State state; MultibyteDecodeBuffer buf; PyObject *errorcb, *res; - Py_buffer pdata; - const char *data, *errors = NULL; + const char *data; Py_ssize_t datalen; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "y*|z:decode", - codeckwarglist, &pdata, &errors)) - return NULL; - data = pdata.buf; - datalen = pdata.len; + data = input->buf; + datalen = input->len; errorcb = internal_error_callback(errors); if (errorcb == NULL) { - PyBuffer_Release(&pdata); return NULL; } if (datalen == 0) { - PyBuffer_Release(&pdata); ERROR_DECREF(errorcb); return make_tuple(PyUnicode_New(0, 0), 0); } @@ -665,13 +677,11 @@ MultibyteCodec_Decode(MultibyteCodecObject *self, if (res == NULL) goto errorexit; - PyBuffer_Release(&pdata); Py_XDECREF(buf.excobj); ERROR_DECREF(errorcb); return make_tuple(res, datalen); errorexit: - PyBuffer_Release(&pdata); ERROR_DECREF(errorcb); Py_XDECREF(buf.excobj); _PyUnicodeWriter_Dealloc(&buf.writer); @@ -680,13 +690,9 @@ MultibyteCodec_Decode(MultibyteCodecObject *self, } static struct PyMethodDef multibytecodec_methods[] = { - {"encode", (PyCFunction)MultibyteCodec_Encode, - METH_VARARGS | METH_KEYWORDS, - MultibyteCodec_Encode__doc__}, - {"decode", (PyCFunction)MultibyteCodec_Decode, - METH_VARARGS | METH_KEYWORDS, - MultibyteCodec_Decode__doc__}, - {NULL, NULL}, + _MULTIBYTECODEC_MULTIBYTECODEC_ENCODE_METHODDEF + _MULTIBYTECODEC_MULTIBYTECODEC_DECODE_METHODDEF + {NULL, NULL}, }; static void @@ -870,26 +876,32 @@ decoder_feed_buffer(MultibyteStatefulDecoderContext *ctx, } -/** - * MultibyteIncrementalEncoder object - */ +/*[clinic input] + class _multibytecodec.MultibyteIncrementalEncoder "MultibyteIncrementalEncoderObject *" "&MultibyteIncrementalEncoder_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3be82909cd08924d]*/ -static PyObject * -mbiencoder_encode(MultibyteIncrementalEncoderObject *self, - PyObject *args, PyObject *kwargs) -{ - PyObject *data; - int final = 0; +/*[clinic input] +_multibytecodec.MultibyteIncrementalEncoder.encode - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|i:encode", - incrementalkwarglist, &data, &final)) - return NULL; + input: object + final: int = 0 +[clinic start generated code]*/ - return encoder_encode_stateful(STATEFUL_ECTX(self), data, final); +static PyObject * +_multibytecodec_MultibyteIncrementalEncoder_encode_impl(MultibyteIncrementalEncoderObject *self, PyObject *input, int final) +/*[clinic end generated code: output=3cd8780c8a719bbf input=456b76d73e464661]*/ +{ + return encoder_encode_stateful(STATEFUL_ECTX(self), input, final); } +/*[clinic input] +_multibytecodec.MultibyteIncrementalEncoder.reset +[clinic start generated code]*/ + static PyObject * -mbiencoder_reset(MultibyteIncrementalEncoderObject *self) +_multibytecodec_MultibyteIncrementalEncoder_reset_impl(MultibyteIncrementalEncoderObject *self) +/*[clinic end generated code: output=b4125d8f537a253f input=930f06760707b6ea]*/ { /* Longest output: 4 bytes (b'\x0F\x1F(B') with ISO 2022 */ unsigned char buffer[4], *outbuf; @@ -906,11 +918,9 @@ mbiencoder_reset(MultibyteIncrementalEncoderObject *self) } static struct PyMethodDef mbiencoder_methods[] = { - {"encode", (PyCFunction)mbiencoder_encode, - METH_VARARGS | METH_KEYWORDS, NULL}, - {"reset", (PyCFunction)mbiencoder_reset, - METH_NOARGS, NULL}, - {NULL, NULL}, + _MULTIBYTECODEC_MULTIBYTEINCREMENTALENCODER_ENCODE_METHODDEF + _MULTIBYTECODEC_MULTIBYTEINCREMENTALENCODER_RESET_METHODDEF + {NULL, NULL}, }; static PyObject * @@ -1021,26 +1031,29 @@ static PyTypeObject MultibyteIncrementalEncoder_Type = { }; -/** - * MultibyteIncrementalDecoder object - */ +/*[clinic input] + class _multibytecodec.MultibyteIncrementalDecoder "MultibyteIncrementalDecoderObject *" "&MultibyteIncrementalDecoder_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=f6003faaf2cea692]*/ + +/*[clinic input] +_multibytecodec.MultibyteIncrementalDecoder.decode + + input: Py_buffer + final: int = 0 +[clinic start generated code]*/ static PyObject * -mbidecoder_decode(MultibyteIncrementalDecoderObject *self, - PyObject *args, PyObject *kwargs) +_multibytecodec_MultibyteIncrementalDecoder_decode_impl(MultibyteIncrementalDecoderObject *self, Py_buffer *input, int final) +/*[clinic end generated code: output=a0f3f92aa7303cf7 input=eb18c2f6e83589e1]*/ { MultibyteDecodeBuffer buf; char *data, *wdata = NULL; - Py_buffer pdata; Py_ssize_t wsize, size, origpending; - int final = 0; PyObject *res; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "y*|i:decode", - incrementalkwarglist, &pdata, &final)) - return NULL; - data = pdata.buf; - size = pdata.len; + data = input->buf; + size = input->len; _PyUnicodeWriter_Init(&buf.writer); buf.excobj = NULL; @@ -1091,14 +1104,12 @@ mbidecoder_decode(MultibyteIncrementalDecoderObject *self, if (res == NULL) goto errorexit; - PyBuffer_Release(&pdata); if (wdata != data) PyMem_Del(wdata); Py_XDECREF(buf.excobj); return res; errorexit: - PyBuffer_Release(&pdata); if (wdata != NULL && wdata != data) PyMem_Del(wdata); Py_XDECREF(buf.excobj); @@ -1106,8 +1117,13 @@ mbidecoder_decode(MultibyteIncrementalDecoderObject *self, return NULL; } +/*[clinic input] +_multibytecodec.MultibyteIncrementalDecoder.reset +[clinic start generated code]*/ + static PyObject * -mbidecoder_reset(MultibyteIncrementalDecoderObject *self) +_multibytecodec_MultibyteIncrementalDecoder_reset_impl(MultibyteIncrementalDecoderObject *self) +/*[clinic end generated code: output=da423b1782c23ed1 input=3b63b3be85b2fb45]*/ { if (self->codec->decreset != NULL && self->codec->decreset(&self->state, self->codec->config) != 0) @@ -1118,11 +1134,9 @@ mbidecoder_reset(MultibyteIncrementalDecoderObject *self) } static struct PyMethodDef mbidecoder_methods[] = { - {"decode", (PyCFunction)mbidecoder_decode, - METH_VARARGS | METH_KEYWORDS, NULL}, - {"reset", (PyCFunction)mbidecoder_reset, - METH_NOARGS, NULL}, - {NULL, NULL}, + _MULTIBYTECODEC_MULTIBYTEINCREMENTALDECODER_DECODE_METHODDEF + _MULTIBYTECODEC_MULTIBYTEINCREMENTALDECODER_RESET_METHODDEF + {NULL, NULL}, }; static PyObject * @@ -1233,9 +1247,10 @@ static PyTypeObject MultibyteIncrementalDecoder_Type = { }; -/** - * MultibyteStreamReader object - */ +/*[clinic input] + class _multibytecodec.MultibyteStreamReader "MultibyteStreamReaderObject *" "MultibyteStreamReader_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=d323634b74976f09]*/ static PyObject * mbstreamreader_iread(MultibyteStreamReaderObject *self, @@ -1257,10 +1272,10 @@ mbstreamreader_iread(MultibyteStreamReaderObject *self, if (sizehint < 0) cres = PyObject_CallMethod(self->stream, - (char *)method, NULL); + method, NULL); else cres = PyObject_CallMethod(self->stream, - (char *)method, "i", sizehint); + method, "i", sizehint); if (cres == NULL) goto errorexit; @@ -1342,16 +1357,20 @@ mbstreamreader_iread(MultibyteStreamReaderObject *self, return NULL; } +/*[clinic input] + _multibytecodec.MultibyteStreamReader.read + + sizeobj: object = None + / +[clinic start generated code]*/ + static PyObject * -mbstreamreader_read(MultibyteStreamReaderObject *self, PyObject *args) +_multibytecodec_MultibyteStreamReader_read_impl(MultibyteStreamReaderObject *self, PyObject *sizeobj) +/*[clinic end generated code: output=f298ea6e1bd2083c input=015b0d3ff2fca485]*/ { - PyObject *sizeobj = NULL; Py_ssize_t size; - if (!PyArg_UnpackTuple(args, "read", 0, 1, &sizeobj)) - return NULL; - - if (sizeobj == Py_None || sizeobj == NULL) + if (sizeobj == Py_None) size = -1; else if (PyLong_Check(sizeobj)) size = PyLong_AsSsize_t(sizeobj); @@ -1366,16 +1385,20 @@ mbstreamreader_read(MultibyteStreamReaderObject *self, PyObject *args) return mbstreamreader_iread(self, "read", size); } +/*[clinic input] + _multibytecodec.MultibyteStreamReader.readline + + sizeobj: object = None + / +[clinic start generated code]*/ + static PyObject * -mbstreamreader_readline(MultibyteStreamReaderObject *self, PyObject *args) +_multibytecodec_MultibyteStreamReader_readline_impl(MultibyteStreamReaderObject *self, PyObject *sizeobj) +/*[clinic end generated code: output=e5ac302a6d0999de input=41ccc64f9bb0cec3]*/ { - PyObject *sizeobj = NULL; Py_ssize_t size; - if (!PyArg_UnpackTuple(args, "readline", 0, 1, &sizeobj)) - return NULL; - - if (sizeobj == Py_None || sizeobj == NULL) + if (sizeobj == Py_None) size = -1; else if (PyLong_Check(sizeobj)) size = PyLong_AsSsize_t(sizeobj); @@ -1390,16 +1413,21 @@ mbstreamreader_readline(MultibyteStreamReaderObject *self, PyObject *args) return mbstreamreader_iread(self, "readline", size); } +/*[clinic input] + _multibytecodec.MultibyteStreamReader.readlines + + sizehintobj: object = None + / +[clinic start generated code]*/ + static PyObject * -mbstreamreader_readlines(MultibyteStreamReaderObject *self, PyObject *args) +_multibytecodec_MultibyteStreamReader_readlines_impl(MultibyteStreamReaderObject *self, PyObject *sizehintobj) +/*[clinic end generated code: output=68f024178b77cb0f input=54932f5d4d88e880]*/ { - PyObject *sizehintobj = NULL, *r, *sr; + PyObject *r, *sr; Py_ssize_t sizehint; - if (!PyArg_UnpackTuple(args, "readlines", 0, 1, &sizehintobj)) - return NULL; - - if (sizehintobj == Py_None || sizehintobj == NULL) + if (sizehintobj == Py_None) sizehint = -1; else if (PyLong_Check(sizehintobj)) sizehint = PyLong_AsSsize_t(sizehintobj); @@ -1420,8 +1448,13 @@ mbstreamreader_readlines(MultibyteStreamReaderObject *self, PyObject *args) return sr; } +/*[clinic input] + _multibytecodec.MultibyteStreamReader.reset +[clinic start generated code]*/ + static PyObject * -mbstreamreader_reset(MultibyteStreamReaderObject *self) +_multibytecodec_MultibyteStreamReader_reset_impl(MultibyteStreamReaderObject *self) +/*[clinic end generated code: output=138490370a680abc input=5d4140db84b5e1e2]*/ { if (self->codec->decreset != NULL && self->codec->decreset(&self->state, self->codec->config) != 0) @@ -1432,14 +1465,10 @@ mbstreamreader_reset(MultibyteStreamReaderObject *self) } static struct PyMethodDef mbstreamreader_methods[] = { - {"read", (PyCFunction)mbstreamreader_read, - METH_VARARGS, NULL}, - {"readline", (PyCFunction)mbstreamreader_readline, - METH_VARARGS, NULL}, - {"readlines", (PyCFunction)mbstreamreader_readlines, - METH_VARARGS, NULL}, - {"reset", (PyCFunction)mbstreamreader_reset, - METH_NOARGS, NULL}, + _MULTIBYTECODEC_MULTIBYTESTREAMREADER_READ_METHODDEF + _MULTIBYTECODEC_MULTIBYTESTREAMREADER_READLINE_METHODDEF + _MULTIBYTECODEC_MULTIBYTESTREAMREADER_READLINES_METHODDEF + _MULTIBYTECODEC_MULTIBYTESTREAMREADER_RESET_METHODDEF {NULL, NULL}, }; @@ -1562,9 +1591,10 @@ static PyTypeObject MultibyteStreamReader_Type = { }; -/** - * MultibyteStreamWriter object - */ +/*[clinic input] + class _multibytecodec.MultibyteStreamWriter "MultibyteStreamWriterObject *" "&MultibyteStreamWriter_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=cde22780a215d6ac]*/ static int mbstreamwriter_iwrite(MultibyteStreamWriterObject *self, @@ -1585,8 +1615,16 @@ mbstreamwriter_iwrite(MultibyteStreamWriterObject *self, return 0; } +/*[clinic input] + _multibytecodec.MultibyteStreamWriter.write + + strobj: object + / +[clinic start generated code]*/ + static PyObject * -mbstreamwriter_write(MultibyteStreamWriterObject *self, PyObject *strobj) +_multibytecodec_MultibyteStreamWriter_write(MultibyteStreamWriterObject *self, PyObject *strobj) +/*[clinic end generated code: output=44e9eb0db0374cb1 input=551dc4c018c10a2b]*/ { if (mbstreamwriter_iwrite(self, strobj)) return NULL; @@ -1594,8 +1632,16 @@ mbstreamwriter_write(MultibyteStreamWriterObject *self, PyObject *strobj) Py_RETURN_NONE; } +/*[clinic input] + _multibytecodec.MultibyteStreamWriter.writelines + + lines: object + / +[clinic start generated code]*/ + static PyObject * -mbstreamwriter_writelines(MultibyteStreamWriterObject *self, PyObject *lines) +_multibytecodec_MultibyteStreamWriter_writelines(MultibyteStreamWriterObject *self, PyObject *lines) +/*[clinic end generated code: output=4facbb0638dde172 input=57797fe7008d4e96]*/ { PyObject *strobj; int i, r; @@ -1621,8 +1667,13 @@ mbstreamwriter_writelines(MultibyteStreamWriterObject *self, PyObject *lines) Py_RETURN_NONE; } +/*[clinic input] + _multibytecodec.MultibyteStreamWriter.reset +[clinic start generated code]*/ + static PyObject * -mbstreamwriter_reset(MultibyteStreamWriterObject *self) +_multibytecodec_MultibyteStreamWriter_reset_impl(MultibyteStreamWriterObject *self) +/*[clinic end generated code: output=8f54a4d9b03db5ff input=b56dbcbaf35cc10c]*/ { PyObject *pwrt; @@ -1721,13 +1772,10 @@ mbstreamwriter_dealloc(MultibyteStreamWriterObject *self) } static struct PyMethodDef mbstreamwriter_methods[] = { - {"write", (PyCFunction)mbstreamwriter_write, - METH_O, NULL}, - {"writelines", (PyCFunction)mbstreamwriter_writelines, - METH_O, NULL}, - {"reset", (PyCFunction)mbstreamwriter_reset, - METH_NOARGS, NULL}, - {NULL, NULL}, + _MULTIBYTECODEC_MULTIBYTESTREAMWRITER_WRITE_METHODDEF + _MULTIBYTECODEC_MULTIBYTESTREAMWRITER_WRITELINES_METHODDEF + _MULTIBYTECODEC_MULTIBYTESTREAMWRITER_RESET_METHODDEF + {NULL, NULL}, }; static PyMemberDef mbstreamwriter_members[] = { @@ -1781,12 +1829,16 @@ static PyTypeObject MultibyteStreamWriter_Type = { }; -/** - * Exposed factory function - */ +/*[clinic input] +_multibytecodec.__create_codec + + arg: object + / +[clinic start generated code]*/ static PyObject * -__create_codec(PyObject *ignore, PyObject *arg) +_multibytecodec___create_codec(PyModuleDef *module, PyObject *arg) +/*[clinic end generated code: output=fbe74f6510640163 input=6840b2a6b183fcfa]*/ { MultibyteCodecObject *self; MultibyteCodec *codec; @@ -1809,7 +1861,7 @@ __create_codec(PyObject *ignore, PyObject *arg) } static struct PyMethodDef __methods[] = { - {"__create_codec", (PyCFunction)__create_codec, METH_O}, + _MULTIBYTECODEC___CREATE_CODEC_METHODDEF {NULL, NULL}, }; diff --git a/Modules/clinic/_bz2module.c.h b/Modules/clinic/_bz2module.c.h new file mode 100644 index 000000000000..8a201a08de02 --- /dev/null +++ b/Modules/clinic/_bz2module.c.h @@ -0,0 +1,162 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_bz2_BZ2Compressor_compress__doc__, +"compress($self, data, /)\n" +"--\n" +"\n" +"Provide data to the compressor object.\n" +"\n" +"Returns a chunk of compressed data if possible, or b\'\' otherwise.\n" +"\n" +"When you have finished providing data to the compressor, call the\n" +"flush() method to finish the compression process."); + +#define _BZ2_BZ2COMPRESSOR_COMPRESS_METHODDEF \ + {"compress", (PyCFunction)_bz2_BZ2Compressor_compress, METH_VARARGS, _bz2_BZ2Compressor_compress__doc__}, + +static PyObject * +_bz2_BZ2Compressor_compress_impl(BZ2Compressor *self, Py_buffer *data); + +static PyObject * +_bz2_BZ2Compressor_compress(BZ2Compressor *self, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + + if (!PyArg_ParseTuple(args, + "y*:compress", + &data)) + goto exit; + return_value = _bz2_BZ2Compressor_compress_impl(self, &data); + +exit: + /* Cleanup for data */ + if (data.obj) + PyBuffer_Release(&data); + + return return_value; +} + +PyDoc_STRVAR(_bz2_BZ2Compressor_flush__doc__, +"flush($self, /)\n" +"--\n" +"\n" +"Finish the compression process.\n" +"\n" +"Returns the compressed data left in internal buffers.\n" +"\n" +"The compressor object may not be used after this method is called."); + +#define _BZ2_BZ2COMPRESSOR_FLUSH_METHODDEF \ + {"flush", (PyCFunction)_bz2_BZ2Compressor_flush, METH_NOARGS, _bz2_BZ2Compressor_flush__doc__}, + +static PyObject * +_bz2_BZ2Compressor_flush_impl(BZ2Compressor *self); + +static PyObject * +_bz2_BZ2Compressor_flush(BZ2Compressor *self, PyObject *Py_UNUSED(ignored)) +{ + return _bz2_BZ2Compressor_flush_impl(self); +} + +PyDoc_STRVAR(_bz2_BZ2Compressor___init____doc__, +"BZ2Compressor(compresslevel=9, /)\n" +"--\n" +"\n" +"Create a compressor object for compressing data incrementally.\n" +"\n" +" compresslevel\n" +" Compression level, as a number between 1 and 9.\n" +"\n" +"For one-shot compression, use the compress() function instead."); + +static int +_bz2_BZ2Compressor___init___impl(BZ2Compressor *self, int compresslevel); + +static int +_bz2_BZ2Compressor___init__(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + int compresslevel = 9; + + if ((Py_TYPE(self) == &BZ2Compressor_Type) && + !_PyArg_NoKeywords("BZ2Compressor", kwargs)) + goto exit; + if (!PyArg_ParseTuple(args, + "|i:BZ2Compressor", + &compresslevel)) + goto exit; + return_value = _bz2_BZ2Compressor___init___impl((BZ2Compressor *)self, compresslevel); + +exit: + return return_value; +} + +PyDoc_STRVAR(_bz2_BZ2Decompressor_decompress__doc__, +"decompress($self, data, /)\n" +"--\n" +"\n" +"Provide data to the decompressor object.\n" +"\n" +"Returns a chunk of decompressed data if possible, or b\'\' otherwise.\n" +"\n" +"Attempting to decompress data after the end of stream is reached\n" +"raises an EOFError. Any data found after the end of the stream\n" +"is ignored and saved in the unused_data attribute."); + +#define _BZ2_BZ2DECOMPRESSOR_DECOMPRESS_METHODDEF \ + {"decompress", (PyCFunction)_bz2_BZ2Decompressor_decompress, METH_VARARGS, _bz2_BZ2Decompressor_decompress__doc__}, + +static PyObject * +_bz2_BZ2Decompressor_decompress_impl(BZ2Decompressor *self, Py_buffer *data); + +static PyObject * +_bz2_BZ2Decompressor_decompress(BZ2Decompressor *self, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + + if (!PyArg_ParseTuple(args, + "y*:decompress", + &data)) + goto exit; + return_value = _bz2_BZ2Decompressor_decompress_impl(self, &data); + +exit: + /* Cleanup for data */ + if (data.obj) + PyBuffer_Release(&data); + + return return_value; +} + +PyDoc_STRVAR(_bz2_BZ2Decompressor___init____doc__, +"BZ2Decompressor()\n" +"--\n" +"\n" +"Create a decompressor object for decompressing data incrementally.\n" +"\n" +"For one-shot decompression, use the decompress() function instead."); + +static int +_bz2_BZ2Decompressor___init___impl(BZ2Decompressor *self); + +static int +_bz2_BZ2Decompressor___init__(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + + if ((Py_TYPE(self) == &BZ2Decompressor_Type) && + !_PyArg_NoPositional("BZ2Decompressor", args)) + goto exit; + if ((Py_TYPE(self) == &BZ2Decompressor_Type) && + !_PyArg_NoKeywords("BZ2Decompressor", kwargs)) + goto exit; + return_value = _bz2_BZ2Decompressor___init___impl((BZ2Decompressor *)self); + +exit: + return return_value; +} +/*[clinic end generated code: output=21ca4405519a0931 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_lzmamodule.c.h b/Modules/clinic/_lzmamodule.c.h new file mode 100644 index 000000000000..636427137fa3 --- /dev/null +++ b/Modules/clinic/_lzmamodule.c.h @@ -0,0 +1,254 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_lzma_LZMACompressor_compress__doc__, +"compress($self, data, /)\n" +"--\n" +"\n" +"Provide data to the compressor object.\n" +"\n" +"Returns a chunk of compressed data if possible, or b\'\' otherwise.\n" +"\n" +"When you have finished providing data to the compressor, call the\n" +"flush() method to finish the compression process."); + +#define _LZMA_LZMACOMPRESSOR_COMPRESS_METHODDEF \ + {"compress", (PyCFunction)_lzma_LZMACompressor_compress, METH_VARARGS, _lzma_LZMACompressor_compress__doc__}, + +static PyObject * +_lzma_LZMACompressor_compress_impl(Compressor *self, Py_buffer *data); + +static PyObject * +_lzma_LZMACompressor_compress(Compressor *self, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + + if (!PyArg_ParseTuple(args, + "y*:compress", + &data)) + goto exit; + return_value = _lzma_LZMACompressor_compress_impl(self, &data); + +exit: + /* Cleanup for data */ + if (data.obj) + PyBuffer_Release(&data); + + return return_value; +} + +PyDoc_STRVAR(_lzma_LZMACompressor_flush__doc__, +"flush($self, /)\n" +"--\n" +"\n" +"Finish the compression process.\n" +"\n" +"Returns the compressed data left in internal buffers.\n" +"\n" +"The compressor object may not be used after this method is called."); + +#define _LZMA_LZMACOMPRESSOR_FLUSH_METHODDEF \ + {"flush", (PyCFunction)_lzma_LZMACompressor_flush, METH_NOARGS, _lzma_LZMACompressor_flush__doc__}, + +static PyObject * +_lzma_LZMACompressor_flush_impl(Compressor *self); + +static PyObject * +_lzma_LZMACompressor_flush(Compressor *self, PyObject *Py_UNUSED(ignored)) +{ + return _lzma_LZMACompressor_flush_impl(self); +} + +PyDoc_STRVAR(_lzma_LZMADecompressor_decompress__doc__, +"decompress($self, /, data, max_length=-1)\n" +"--\n" +"\n" +"Decompress *data*, returning uncompressed data as bytes.\n" +"\n" +"If *max_length* is nonnegative, returns at most *max_length* bytes of\n" +"decompressed data. If this limit is reached and further output can be\n" +"produced, *self.needs_input* will be set to ``False``. In this case, the next\n" +"call to *decompress()* may provide *data* as b\'\' to obtain more of the output.\n" +"\n" +"If all of the input data was decompressed and returned (either because this\n" +"was less than *max_length* bytes, or because *max_length* was negative),\n" +"*self.needs_input* will be set to True.\n" +"\n" +"Attempting to decompress data after the end of stream is reached raises an\n" +"EOFError. Any data found after the end of the stream is ignored and saved in\n" +"the unused_data attribute."); + +#define _LZMA_LZMADECOMPRESSOR_DECOMPRESS_METHODDEF \ + {"decompress", (PyCFunction)_lzma_LZMADecompressor_decompress, METH_VARARGS|METH_KEYWORDS, _lzma_LZMADecompressor_decompress__doc__}, + +static PyObject * +_lzma_LZMADecompressor_decompress_impl(Decompressor *self, Py_buffer *data, Py_ssize_t max_length); + +static PyObject * +_lzma_LZMADecompressor_decompress(Decompressor *self, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"data", "max_length", NULL}; + Py_buffer data = {NULL, NULL}; + Py_ssize_t max_length = -1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "y*|n:decompress", _keywords, + &data, &max_length)) + goto exit; + return_value = _lzma_LZMADecompressor_decompress_impl(self, &data, max_length); + +exit: + /* Cleanup for data */ + if (data.obj) + PyBuffer_Release(&data); + + return return_value; +} + +PyDoc_STRVAR(_lzma_LZMADecompressor___init____doc__, +"LZMADecompressor(format=FORMAT_AUTO, memlimit=None, filters=None)\n" +"--\n" +"\n" +"Create a decompressor object for decompressing data incrementally.\n" +"\n" +" format\n" +" Specifies the container format of the input stream. If this is\n" +" FORMAT_AUTO (the default), the decompressor will automatically detect\n" +" whether the input is FORMAT_XZ or FORMAT_ALONE. Streams created with\n" +" FORMAT_RAW cannot be autodetected.\n" +" memlimit\n" +" Limit the amount of memory used by the decompressor. This will cause\n" +" decompression to fail if the input cannot be decompressed within the\n" +" given limit.\n" +" filters\n" +" A custom filter chain. This argument is required for FORMAT_RAW, and\n" +" not accepted with any other format. When provided, this should be a\n" +" sequence of dicts, each indicating the ID and options for a single\n" +" filter.\n" +"\n" +"For one-shot decompression, use the decompress() function instead."); + +static int +_lzma_LZMADecompressor___init___impl(Decompressor *self, int format, PyObject *memlimit, PyObject *filters); + +static int +_lzma_LZMADecompressor___init__(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + static char *_keywords[] = {"format", "memlimit", "filters", NULL}; + int format = FORMAT_AUTO; + PyObject *memlimit = Py_None; + PyObject *filters = Py_None; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "|iOO:LZMADecompressor", _keywords, + &format, &memlimit, &filters)) + goto exit; + return_value = _lzma_LZMADecompressor___init___impl((Decompressor *)self, format, memlimit, filters); + +exit: + return return_value; +} + +PyDoc_STRVAR(_lzma_is_check_supported__doc__, +"is_check_supported($module, check_id, /)\n" +"--\n" +"\n" +"Test whether the given integrity check is supported.\n" +"\n" +"Always returns True for CHECK_NONE and CHECK_CRC32."); + +#define _LZMA_IS_CHECK_SUPPORTED_METHODDEF \ + {"is_check_supported", (PyCFunction)_lzma_is_check_supported, METH_VARARGS, _lzma_is_check_supported__doc__}, + +static PyObject * +_lzma_is_check_supported_impl(PyModuleDef *module, int check_id); + +static PyObject * +_lzma_is_check_supported(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int check_id; + + if (!PyArg_ParseTuple(args, + "i:is_check_supported", + &check_id)) + goto exit; + return_value = _lzma_is_check_supported_impl(module, check_id); + +exit: + return return_value; +} + +PyDoc_STRVAR(_lzma__encode_filter_properties__doc__, +"_encode_filter_properties($module, filter, /)\n" +"--\n" +"\n" +"Return a bytes object encoding the options (properties) of the filter specified by *filter* (a dict).\n" +"\n" +"The result does not include the filter ID itself, only the options."); + +#define _LZMA__ENCODE_FILTER_PROPERTIES_METHODDEF \ + {"_encode_filter_properties", (PyCFunction)_lzma__encode_filter_properties, METH_VARARGS, _lzma__encode_filter_properties__doc__}, + +static PyObject * +_lzma__encode_filter_properties_impl(PyModuleDef *module, lzma_filter filter); + +static PyObject * +_lzma__encode_filter_properties(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + lzma_filter filter = {LZMA_VLI_UNKNOWN, NULL}; + + if (!PyArg_ParseTuple(args, + "O&:_encode_filter_properties", + lzma_filter_converter, &filter)) + goto exit; + return_value = _lzma__encode_filter_properties_impl(module, filter); + +exit: + /* Cleanup for filter */ + if (filter.id != LZMA_VLI_UNKNOWN) + PyMem_Free(filter.options); + + return return_value; +} + +PyDoc_STRVAR(_lzma__decode_filter_properties__doc__, +"_decode_filter_properties($module, filter_id, encoded_props, /)\n" +"--\n" +"\n" +"Return a bytes object encoding the options (properties) of the filter specified by *filter* (a dict).\n" +"\n" +"The result does not include the filter ID itself, only the options."); + +#define _LZMA__DECODE_FILTER_PROPERTIES_METHODDEF \ + {"_decode_filter_properties", (PyCFunction)_lzma__decode_filter_properties, METH_VARARGS, _lzma__decode_filter_properties__doc__}, + +static PyObject * +_lzma__decode_filter_properties_impl(PyModuleDef *module, lzma_vli filter_id, Py_buffer *encoded_props); + +static PyObject * +_lzma__decode_filter_properties(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + lzma_vli filter_id; + Py_buffer encoded_props = {NULL, NULL}; + + if (!PyArg_ParseTuple(args, + "O&y*:_decode_filter_properties", + lzma_vli_converter, &filter_id, &encoded_props)) + goto exit; + return_value = _lzma__decode_filter_properties_impl(module, filter_id, &encoded_props); + +exit: + /* Cleanup for encoded_props */ + if (encoded_props.obj) + PyBuffer_Release(&encoded_props); + + return return_value; +} +/*[clinic end generated code: output=dc42b73890609369 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_pickle.c.h b/Modules/clinic/_pickle.c.h new file mode 100644 index 000000000000..975298ce4717 --- /dev/null +++ b/Modules/clinic/_pickle.c.h @@ -0,0 +1,545 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_pickle_Pickler_clear_memo__doc__, +"clear_memo($self, /)\n" +"--\n" +"\n" +"Clears the pickler\'s \"memo\".\n" +"\n" +"The memo is the data structure that remembers which objects the\n" +"pickler has already seen, so that shared or recursive objects are\n" +"pickled by reference and not by value. This method is useful when\n" +"re-using picklers."); + +#define _PICKLE_PICKLER_CLEAR_MEMO_METHODDEF \ + {"clear_memo", (PyCFunction)_pickle_Pickler_clear_memo, METH_NOARGS, _pickle_Pickler_clear_memo__doc__}, + +static PyObject * +_pickle_Pickler_clear_memo_impl(PicklerObject *self); + +static PyObject * +_pickle_Pickler_clear_memo(PicklerObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _pickle_Pickler_clear_memo_impl(self); +} + +PyDoc_STRVAR(_pickle_Pickler_dump__doc__, +"dump($self, obj, /)\n" +"--\n" +"\n" +"Write a pickled representation of the given object to the open file."); + +#define _PICKLE_PICKLER_DUMP_METHODDEF \ + {"dump", (PyCFunction)_pickle_Pickler_dump, METH_O, _pickle_Pickler_dump__doc__}, + +PyDoc_STRVAR(_pickle_Pickler___sizeof____doc__, +"__sizeof__($self, /)\n" +"--\n" +"\n" +"Returns size in memory, in bytes."); + +#define _PICKLE_PICKLER___SIZEOF___METHODDEF \ + {"__sizeof__", (PyCFunction)_pickle_Pickler___sizeof__, METH_NOARGS, _pickle_Pickler___sizeof____doc__}, + +static Py_ssize_t +_pickle_Pickler___sizeof___impl(PicklerObject *self); + +static PyObject * +_pickle_Pickler___sizeof__(PicklerObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + Py_ssize_t _return_value; + + _return_value = _pickle_Pickler___sizeof___impl(self); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromSsize_t(_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_pickle_Pickler___init____doc__, +"Pickler(file, protocol=None, fix_imports=True)\n" +"--\n" +"\n" +"This takes a binary file for writing a pickle data stream.\n" +"\n" +"The optional *protocol* argument tells the pickler to use the given\n" +"protocol; supported protocols are 0, 1, 2, 3 and 4. The default\n" +"protocol is 3; a backward-incompatible protocol designed for Python 3.\n" +"\n" +"Specifying a negative protocol version selects the highest protocol\n" +"version supported. The higher the protocol used, the more recent the\n" +"version of Python needed to read the pickle produced.\n" +"\n" +"The *file* argument must have a write() method that accepts a single\n" +"bytes argument. It can thus be a file object opened for binary\n" +"writing, a io.BytesIO instance, or any other custom object that meets\n" +"this interface.\n" +"\n" +"If *fix_imports* is True and protocol is less than 3, pickle will try\n" +"to map the new Python 3 names to the old module names used in Python\n" +"2, so that the pickle data stream is readable with Python 2."); + +static int +_pickle_Pickler___init___impl(PicklerObject *self, PyObject *file, PyObject *protocol, int fix_imports); + +static int +_pickle_Pickler___init__(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + static char *_keywords[] = {"file", "protocol", "fix_imports", NULL}; + PyObject *file; + PyObject *protocol = NULL; + int fix_imports = 1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O|Op:Pickler", _keywords, + &file, &protocol, &fix_imports)) + goto exit; + return_value = _pickle_Pickler___init___impl((PicklerObject *)self, file, protocol, fix_imports); + +exit: + return return_value; +} + +PyDoc_STRVAR(_pickle_PicklerMemoProxy_clear__doc__, +"clear($self, /)\n" +"--\n" +"\n" +"Remove all items from memo."); + +#define _PICKLE_PICKLERMEMOPROXY_CLEAR_METHODDEF \ + {"clear", (PyCFunction)_pickle_PicklerMemoProxy_clear, METH_NOARGS, _pickle_PicklerMemoProxy_clear__doc__}, + +static PyObject * +_pickle_PicklerMemoProxy_clear_impl(PicklerMemoProxyObject *self); + +static PyObject * +_pickle_PicklerMemoProxy_clear(PicklerMemoProxyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _pickle_PicklerMemoProxy_clear_impl(self); +} + +PyDoc_STRVAR(_pickle_PicklerMemoProxy_copy__doc__, +"copy($self, /)\n" +"--\n" +"\n" +"Copy the memo to a new object."); + +#define _PICKLE_PICKLERMEMOPROXY_COPY_METHODDEF \ + {"copy", (PyCFunction)_pickle_PicklerMemoProxy_copy, METH_NOARGS, _pickle_PicklerMemoProxy_copy__doc__}, + +static PyObject * +_pickle_PicklerMemoProxy_copy_impl(PicklerMemoProxyObject *self); + +static PyObject * +_pickle_PicklerMemoProxy_copy(PicklerMemoProxyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _pickle_PicklerMemoProxy_copy_impl(self); +} + +PyDoc_STRVAR(_pickle_PicklerMemoProxy___reduce____doc__, +"__reduce__($self, /)\n" +"--\n" +"\n" +"Implement pickle support."); + +#define _PICKLE_PICKLERMEMOPROXY___REDUCE___METHODDEF \ + {"__reduce__", (PyCFunction)_pickle_PicklerMemoProxy___reduce__, METH_NOARGS, _pickle_PicklerMemoProxy___reduce____doc__}, + +static PyObject * +_pickle_PicklerMemoProxy___reduce___impl(PicklerMemoProxyObject *self); + +static PyObject * +_pickle_PicklerMemoProxy___reduce__(PicklerMemoProxyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _pickle_PicklerMemoProxy___reduce___impl(self); +} + +PyDoc_STRVAR(_pickle_Unpickler_load__doc__, +"load($self, /)\n" +"--\n" +"\n" +"Load a pickle.\n" +"\n" +"Read a pickled object representation from the open file object given\n" +"in the constructor, and return the reconstituted object hierarchy\n" +"specified therein."); + +#define _PICKLE_UNPICKLER_LOAD_METHODDEF \ + {"load", (PyCFunction)_pickle_Unpickler_load, METH_NOARGS, _pickle_Unpickler_load__doc__}, + +static PyObject * +_pickle_Unpickler_load_impl(UnpicklerObject *self); + +static PyObject * +_pickle_Unpickler_load(UnpicklerObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _pickle_Unpickler_load_impl(self); +} + +PyDoc_STRVAR(_pickle_Unpickler_find_class__doc__, +"find_class($self, module_name, global_name, /)\n" +"--\n" +"\n" +"Return an object from a specified module.\n" +"\n" +"If necessary, the module will be imported. Subclasses may override\n" +"this method (e.g. to restrict unpickling of arbitrary classes and\n" +"functions).\n" +"\n" +"This method is called whenever a class or a function object is\n" +"needed. Both arguments passed are str objects."); + +#define _PICKLE_UNPICKLER_FIND_CLASS_METHODDEF \ + {"find_class", (PyCFunction)_pickle_Unpickler_find_class, METH_VARARGS, _pickle_Unpickler_find_class__doc__}, + +static PyObject * +_pickle_Unpickler_find_class_impl(UnpicklerObject *self, PyObject *module_name, PyObject *global_name); + +static PyObject * +_pickle_Unpickler_find_class(UnpicklerObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *module_name; + PyObject *global_name; + + if (!PyArg_UnpackTuple(args, "find_class", + 2, 2, + &module_name, &global_name)) + goto exit; + return_value = _pickle_Unpickler_find_class_impl(self, module_name, global_name); + +exit: + return return_value; +} + +PyDoc_STRVAR(_pickle_Unpickler___sizeof____doc__, +"__sizeof__($self, /)\n" +"--\n" +"\n" +"Returns size in memory, in bytes."); + +#define _PICKLE_UNPICKLER___SIZEOF___METHODDEF \ + {"__sizeof__", (PyCFunction)_pickle_Unpickler___sizeof__, METH_NOARGS, _pickle_Unpickler___sizeof____doc__}, + +static Py_ssize_t +_pickle_Unpickler___sizeof___impl(UnpicklerObject *self); + +static PyObject * +_pickle_Unpickler___sizeof__(UnpicklerObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + Py_ssize_t _return_value; + + _return_value = _pickle_Unpickler___sizeof___impl(self); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromSsize_t(_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(_pickle_Unpickler___init____doc__, +"Unpickler(file, *, fix_imports=True, encoding=\'ASCII\', errors=\'strict\')\n" +"--\n" +"\n" +"This takes a binary file for reading a pickle data stream.\n" +"\n" +"The protocol version of the pickle is detected automatically, so no\n" +"protocol argument is needed. Bytes past the pickled object\'s\n" +"representation are ignored.\n" +"\n" +"The argument *file* must have two methods, a read() method that takes\n" +"an integer argument, and a readline() method that requires no\n" +"arguments. Both methods should return bytes. Thus *file* can be a\n" +"binary file object opened for reading, a io.BytesIO object, or any\n" +"other custom object that meets this interface.\n" +"\n" +"Optional keyword arguments are *fix_imports*, *encoding* and *errors*,\n" +"which are used to control compatiblity support for pickle stream\n" +"generated by Python 2. If *fix_imports* is True, pickle will try to\n" +"map the old Python 2 names to the new names used in Python 3. The\n" +"*encoding* and *errors* tell pickle how to decode 8-bit string\n" +"instances pickled by Python 2; these default to \'ASCII\' and \'strict\',\n" +"respectively. The *encoding* can be \'bytes\' to read these 8-bit\n" +"string instances as bytes objects."); + +static int +_pickle_Unpickler___init___impl(UnpicklerObject *self, PyObject *file, int fix_imports, const char *encoding, const char *errors); + +static int +_pickle_Unpickler___init__(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + static char *_keywords[] = {"file", "fix_imports", "encoding", "errors", NULL}; + PyObject *file; + int fix_imports = 1; + const char *encoding = "ASCII"; + const char *errors = "strict"; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O|$pss:Unpickler", _keywords, + &file, &fix_imports, &encoding, &errors)) + goto exit; + return_value = _pickle_Unpickler___init___impl((UnpicklerObject *)self, file, fix_imports, encoding, errors); + +exit: + return return_value; +} + +PyDoc_STRVAR(_pickle_UnpicklerMemoProxy_clear__doc__, +"clear($self, /)\n" +"--\n" +"\n" +"Remove all items from memo."); + +#define _PICKLE_UNPICKLERMEMOPROXY_CLEAR_METHODDEF \ + {"clear", (PyCFunction)_pickle_UnpicklerMemoProxy_clear, METH_NOARGS, _pickle_UnpicklerMemoProxy_clear__doc__}, + +static PyObject * +_pickle_UnpicklerMemoProxy_clear_impl(UnpicklerMemoProxyObject *self); + +static PyObject * +_pickle_UnpicklerMemoProxy_clear(UnpicklerMemoProxyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _pickle_UnpicklerMemoProxy_clear_impl(self); +} + +PyDoc_STRVAR(_pickle_UnpicklerMemoProxy_copy__doc__, +"copy($self, /)\n" +"--\n" +"\n" +"Copy the memo to a new object."); + +#define _PICKLE_UNPICKLERMEMOPROXY_COPY_METHODDEF \ + {"copy", (PyCFunction)_pickle_UnpicklerMemoProxy_copy, METH_NOARGS, _pickle_UnpicklerMemoProxy_copy__doc__}, + +static PyObject * +_pickle_UnpicklerMemoProxy_copy_impl(UnpicklerMemoProxyObject *self); + +static PyObject * +_pickle_UnpicklerMemoProxy_copy(UnpicklerMemoProxyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _pickle_UnpicklerMemoProxy_copy_impl(self); +} + +PyDoc_STRVAR(_pickle_UnpicklerMemoProxy___reduce____doc__, +"__reduce__($self, /)\n" +"--\n" +"\n" +"Implement pickling support."); + +#define _PICKLE_UNPICKLERMEMOPROXY___REDUCE___METHODDEF \ + {"__reduce__", (PyCFunction)_pickle_UnpicklerMemoProxy___reduce__, METH_NOARGS, _pickle_UnpicklerMemoProxy___reduce____doc__}, + +static PyObject * +_pickle_UnpicklerMemoProxy___reduce___impl(UnpicklerMemoProxyObject *self); + +static PyObject * +_pickle_UnpicklerMemoProxy___reduce__(UnpicklerMemoProxyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _pickle_UnpicklerMemoProxy___reduce___impl(self); +} + +PyDoc_STRVAR(_pickle_dump__doc__, +"dump($module, /, obj, file, protocol=None, *, fix_imports=True)\n" +"--\n" +"\n" +"Write a pickled representation of obj to the open file object file.\n" +"\n" +"This is equivalent to ``Pickler(file, protocol).dump(obj)``, but may\n" +"be more efficient.\n" +"\n" +"The optional *protocol* argument tells the pickler to use the given\n" +"protocol supported protocols are 0, 1, 2, 3 and 4. The default\n" +"protocol is 3; a backward-incompatible protocol designed for Python 3.\n" +"\n" +"Specifying a negative protocol version selects the highest protocol\n" +"version supported. The higher the protocol used, the more recent the\n" +"version of Python needed to read the pickle produced.\n" +"\n" +"The *file* argument must have a write() method that accepts a single\n" +"bytes argument. It can thus be a file object opened for binary\n" +"writing, a io.BytesIO instance, or any other custom object that meets\n" +"this interface.\n" +"\n" +"If *fix_imports* is True and protocol is less than 3, pickle will try\n" +"to map the new Python 3 names to the old module names used in Python\n" +"2, so that the pickle data stream is readable with Python 2."); + +#define _PICKLE_DUMP_METHODDEF \ + {"dump", (PyCFunction)_pickle_dump, METH_VARARGS|METH_KEYWORDS, _pickle_dump__doc__}, + +static PyObject * +_pickle_dump_impl(PyModuleDef *module, PyObject *obj, PyObject *file, PyObject *protocol, int fix_imports); + +static PyObject * +_pickle_dump(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"obj", "file", "protocol", "fix_imports", NULL}; + PyObject *obj; + PyObject *file; + PyObject *protocol = NULL; + int fix_imports = 1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "OO|O$p:dump", _keywords, + &obj, &file, &protocol, &fix_imports)) + goto exit; + return_value = _pickle_dump_impl(module, obj, file, protocol, fix_imports); + +exit: + return return_value; +} + +PyDoc_STRVAR(_pickle_dumps__doc__, +"dumps($module, /, obj, protocol=None, *, fix_imports=True)\n" +"--\n" +"\n" +"Return the pickled representation of the object as a bytes object.\n" +"\n" +"The optional *protocol* argument tells the pickler to use the given\n" +"protocol; supported protocols are 0, 1, 2, 3 and 4. The default\n" +"protocol is 3; a backward-incompatible protocol designed for Python 3.\n" +"\n" +"Specifying a negative protocol version selects the highest protocol\n" +"version supported. The higher the protocol used, the more recent the\n" +"version of Python needed to read the pickle produced.\n" +"\n" +"If *fix_imports* is True and *protocol* is less than 3, pickle will\n" +"try to map the new Python 3 names to the old module names used in\n" +"Python 2, so that the pickle data stream is readable with Python 2."); + +#define _PICKLE_DUMPS_METHODDEF \ + {"dumps", (PyCFunction)_pickle_dumps, METH_VARARGS|METH_KEYWORDS, _pickle_dumps__doc__}, + +static PyObject * +_pickle_dumps_impl(PyModuleDef *module, PyObject *obj, PyObject *protocol, int fix_imports); + +static PyObject * +_pickle_dumps(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"obj", "protocol", "fix_imports", NULL}; + PyObject *obj; + PyObject *protocol = NULL; + int fix_imports = 1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O|O$p:dumps", _keywords, + &obj, &protocol, &fix_imports)) + goto exit; + return_value = _pickle_dumps_impl(module, obj, protocol, fix_imports); + +exit: + return return_value; +} + +PyDoc_STRVAR(_pickle_load__doc__, +"load($module, /, file, *, fix_imports=True, encoding=\'ASCII\',\n" +" errors=\'strict\')\n" +"--\n" +"\n" +"Read and return an object from the pickle data stored in a file.\n" +"\n" +"This is equivalent to ``Unpickler(file).load()``, but may be more\n" +"efficient.\n" +"\n" +"The protocol version of the pickle is detected automatically, so no\n" +"protocol argument is needed. Bytes past the pickled object\'s\n" +"representation are ignored.\n" +"\n" +"The argument *file* must have two methods, a read() method that takes\n" +"an integer argument, and a readline() method that requires no\n" +"arguments. Both methods should return bytes. Thus *file* can be a\n" +"binary file object opened for reading, a io.BytesIO object, or any\n" +"other custom object that meets this interface.\n" +"\n" +"Optional keyword arguments are *fix_imports*, *encoding* and *errors*,\n" +"which are used to control compatiblity support for pickle stream\n" +"generated by Python 2. If *fix_imports* is True, pickle will try to\n" +"map the old Python 2 names to the new names used in Python 3. The\n" +"*encoding* and *errors* tell pickle how to decode 8-bit string\n" +"instances pickled by Python 2; these default to \'ASCII\' and \'strict\',\n" +"respectively. The *encoding* can be \'bytes\' to read these 8-bit\n" +"string instances as bytes objects."); + +#define _PICKLE_LOAD_METHODDEF \ + {"load", (PyCFunction)_pickle_load, METH_VARARGS|METH_KEYWORDS, _pickle_load__doc__}, + +static PyObject * +_pickle_load_impl(PyModuleDef *module, PyObject *file, int fix_imports, const char *encoding, const char *errors); + +static PyObject * +_pickle_load(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"file", "fix_imports", "encoding", "errors", NULL}; + PyObject *file; + int fix_imports = 1; + const char *encoding = "ASCII"; + const char *errors = "strict"; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O|$pss:load", _keywords, + &file, &fix_imports, &encoding, &errors)) + goto exit; + return_value = _pickle_load_impl(module, file, fix_imports, encoding, errors); + +exit: + return return_value; +} + +PyDoc_STRVAR(_pickle_loads__doc__, +"loads($module, /, data, *, fix_imports=True, encoding=\'ASCII\',\n" +" errors=\'strict\')\n" +"--\n" +"\n" +"Read and return an object from the given pickle data.\n" +"\n" +"The protocol version of the pickle is detected automatically, so no\n" +"protocol argument is needed. Bytes past the pickled object\'s\n" +"representation are ignored.\n" +"\n" +"Optional keyword arguments are *fix_imports*, *encoding* and *errors*,\n" +"which are used to control compatiblity support for pickle stream\n" +"generated by Python 2. If *fix_imports* is True, pickle will try to\n" +"map the old Python 2 names to the new names used in Python 3. The\n" +"*encoding* and *errors* tell pickle how to decode 8-bit string\n" +"instances pickled by Python 2; these default to \'ASCII\' and \'strict\',\n" +"respectively. The *encoding* can be \'bytes\' to read these 8-bit\n" +"string instances as bytes objects."); + +#define _PICKLE_LOADS_METHODDEF \ + {"loads", (PyCFunction)_pickle_loads, METH_VARARGS|METH_KEYWORDS, _pickle_loads__doc__}, + +static PyObject * +_pickle_loads_impl(PyModuleDef *module, PyObject *data, int fix_imports, const char *encoding, const char *errors); + +static PyObject * +_pickle_loads(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"data", "fix_imports", "encoding", "errors", NULL}; + PyObject *data; + int fix_imports = 1; + const char *encoding = "ASCII"; + const char *errors = "strict"; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O|$pss:loads", _keywords, + &data, &fix_imports, &encoding, &errors)) + goto exit; + return_value = _pickle_loads_impl(module, data, fix_imports, encoding, errors); + +exit: + return return_value; +} +/*[clinic end generated code: output=3aba79576e240c62 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/arraymodule.c.h b/Modules/clinic/arraymodule.c.h new file mode 100644 index 000000000000..57d769026d62 --- /dev/null +++ b/Modules/clinic/arraymodule.c.h @@ -0,0 +1,505 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(array_array___copy____doc__, +"__copy__($self, /)\n" +"--\n" +"\n" +"Return a copy of the array."); + +#define ARRAY_ARRAY___COPY___METHODDEF \ + {"__copy__", (PyCFunction)array_array___copy__, METH_NOARGS, array_array___copy____doc__}, + +static PyObject * +array_array___copy___impl(arrayobject *self); + +static PyObject * +array_array___copy__(arrayobject *self, PyObject *Py_UNUSED(ignored)) +{ + return array_array___copy___impl(self); +} + +PyDoc_STRVAR(array_array___deepcopy____doc__, +"__deepcopy__($self, unused, /)\n" +"--\n" +"\n" +"Return a copy of the array."); + +#define ARRAY_ARRAY___DEEPCOPY___METHODDEF \ + {"__deepcopy__", (PyCFunction)array_array___deepcopy__, METH_O, array_array___deepcopy____doc__}, + +PyDoc_STRVAR(array_array_count__doc__, +"count($self, v, /)\n" +"--\n" +"\n" +"Return number of occurrences of v in the array."); + +#define ARRAY_ARRAY_COUNT_METHODDEF \ + {"count", (PyCFunction)array_array_count, METH_O, array_array_count__doc__}, + +PyDoc_STRVAR(array_array_index__doc__, +"index($self, v, /)\n" +"--\n" +"\n" +"Return index of first occurrence of v in the array."); + +#define ARRAY_ARRAY_INDEX_METHODDEF \ + {"index", (PyCFunction)array_array_index, METH_O, array_array_index__doc__}, + +PyDoc_STRVAR(array_array_remove__doc__, +"remove($self, v, /)\n" +"--\n" +"\n" +"Remove the first occurrence of v in the array."); + +#define ARRAY_ARRAY_REMOVE_METHODDEF \ + {"remove", (PyCFunction)array_array_remove, METH_O, array_array_remove__doc__}, + +PyDoc_STRVAR(array_array_pop__doc__, +"pop($self, i=-1, /)\n" +"--\n" +"\n" +"Return the i-th element and delete it from the array.\n" +"\n" +"i defaults to -1."); + +#define ARRAY_ARRAY_POP_METHODDEF \ + {"pop", (PyCFunction)array_array_pop, METH_VARARGS, array_array_pop__doc__}, + +static PyObject * +array_array_pop_impl(arrayobject *self, Py_ssize_t i); + +static PyObject * +array_array_pop(arrayobject *self, PyObject *args) +{ + PyObject *return_value = NULL; + Py_ssize_t i = -1; + + if (!PyArg_ParseTuple(args, + "|n:pop", + &i)) + goto exit; + return_value = array_array_pop_impl(self, i); + +exit: + return return_value; +} + +PyDoc_STRVAR(array_array_extend__doc__, +"extend($self, bb, /)\n" +"--\n" +"\n" +"Append items to the end of the array."); + +#define ARRAY_ARRAY_EXTEND_METHODDEF \ + {"extend", (PyCFunction)array_array_extend, METH_O, array_array_extend__doc__}, + +PyDoc_STRVAR(array_array_insert__doc__, +"insert($self, i, v, /)\n" +"--\n" +"\n" +"Insert a new item v into the array before position i."); + +#define ARRAY_ARRAY_INSERT_METHODDEF \ + {"insert", (PyCFunction)array_array_insert, METH_VARARGS, array_array_insert__doc__}, + +static PyObject * +array_array_insert_impl(arrayobject *self, Py_ssize_t i, PyObject *v); + +static PyObject * +array_array_insert(arrayobject *self, PyObject *args) +{ + PyObject *return_value = NULL; + Py_ssize_t i; + PyObject *v; + + if (!PyArg_ParseTuple(args, + "nO:insert", + &i, &v)) + goto exit; + return_value = array_array_insert_impl(self, i, v); + +exit: + return return_value; +} + +PyDoc_STRVAR(array_array_buffer_info__doc__, +"buffer_info($self, /)\n" +"--\n" +"\n" +"Return a tuple (address, length) giving the current memory address and the length in items of the buffer used to hold array\'s contents.\n" +"\n" +"The length should be multiplied by the itemsize attribute to calculate\n" +"the buffer length in bytes."); + +#define ARRAY_ARRAY_BUFFER_INFO_METHODDEF \ + {"buffer_info", (PyCFunction)array_array_buffer_info, METH_NOARGS, array_array_buffer_info__doc__}, + +static PyObject * +array_array_buffer_info_impl(arrayobject *self); + +static PyObject * +array_array_buffer_info(arrayobject *self, PyObject *Py_UNUSED(ignored)) +{ + return array_array_buffer_info_impl(self); +} + +PyDoc_STRVAR(array_array_append__doc__, +"append($self, v, /)\n" +"--\n" +"\n" +"Append new value v to the end of the array."); + +#define ARRAY_ARRAY_APPEND_METHODDEF \ + {"append", (PyCFunction)array_array_append, METH_O, array_array_append__doc__}, + +PyDoc_STRVAR(array_array_byteswap__doc__, +"byteswap($self, /)\n" +"--\n" +"\n" +"Byteswap all items of the array.\n" +"\n" +"If the items in the array are not 1, 2, 4, or 8 bytes in size, RuntimeError is\n" +"raised."); + +#define ARRAY_ARRAY_BYTESWAP_METHODDEF \ + {"byteswap", (PyCFunction)array_array_byteswap, METH_NOARGS, array_array_byteswap__doc__}, + +static PyObject * +array_array_byteswap_impl(arrayobject *self); + +static PyObject * +array_array_byteswap(arrayobject *self, PyObject *Py_UNUSED(ignored)) +{ + return array_array_byteswap_impl(self); +} + +PyDoc_STRVAR(array_array_reverse__doc__, +"reverse($self, /)\n" +"--\n" +"\n" +"Reverse the order of the items in the array."); + +#define ARRAY_ARRAY_REVERSE_METHODDEF \ + {"reverse", (PyCFunction)array_array_reverse, METH_NOARGS, array_array_reverse__doc__}, + +static PyObject * +array_array_reverse_impl(arrayobject *self); + +static PyObject * +array_array_reverse(arrayobject *self, PyObject *Py_UNUSED(ignored)) +{ + return array_array_reverse_impl(self); +} + +PyDoc_STRVAR(array_array_fromfile__doc__, +"fromfile($self, f, n, /)\n" +"--\n" +"\n" +"Read n objects from the file object f and append them to the end of the array."); + +#define ARRAY_ARRAY_FROMFILE_METHODDEF \ + {"fromfile", (PyCFunction)array_array_fromfile, METH_VARARGS, array_array_fromfile__doc__}, + +static PyObject * +array_array_fromfile_impl(arrayobject *self, PyObject *f, Py_ssize_t n); + +static PyObject * +array_array_fromfile(arrayobject *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *f; + Py_ssize_t n; + + if (!PyArg_ParseTuple(args, + "On:fromfile", + &f, &n)) + goto exit; + return_value = array_array_fromfile_impl(self, f, n); + +exit: + return return_value; +} + +PyDoc_STRVAR(array_array_tofile__doc__, +"tofile($self, f, /)\n" +"--\n" +"\n" +"Write all items (as machine values) to the file object f."); + +#define ARRAY_ARRAY_TOFILE_METHODDEF \ + {"tofile", (PyCFunction)array_array_tofile, METH_O, array_array_tofile__doc__}, + +PyDoc_STRVAR(array_array_fromlist__doc__, +"fromlist($self, list, /)\n" +"--\n" +"\n" +"Append items to array from list."); + +#define ARRAY_ARRAY_FROMLIST_METHODDEF \ + {"fromlist", (PyCFunction)array_array_fromlist, METH_O, array_array_fromlist__doc__}, + +PyDoc_STRVAR(array_array_tolist__doc__, +"tolist($self, /)\n" +"--\n" +"\n" +"Convert array to an ordinary list with the same items."); + +#define ARRAY_ARRAY_TOLIST_METHODDEF \ + {"tolist", (PyCFunction)array_array_tolist, METH_NOARGS, array_array_tolist__doc__}, + +static PyObject * +array_array_tolist_impl(arrayobject *self); + +static PyObject * +array_array_tolist(arrayobject *self, PyObject *Py_UNUSED(ignored)) +{ + return array_array_tolist_impl(self); +} + +PyDoc_STRVAR(array_array_fromstring__doc__, +"fromstring($self, buffer, /)\n" +"--\n" +"\n" +"Appends items from the string, interpreting it as an array of machine values, as if it had been read from a file using the fromfile() method).\n" +"\n" +"This method is deprecated. Use frombytes instead."); + +#define ARRAY_ARRAY_FROMSTRING_METHODDEF \ + {"fromstring", (PyCFunction)array_array_fromstring, METH_VARARGS, array_array_fromstring__doc__}, + +static PyObject * +array_array_fromstring_impl(arrayobject *self, Py_buffer *buffer); + +static PyObject * +array_array_fromstring(arrayobject *self, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer buffer = {NULL, NULL}; + + if (!PyArg_ParseTuple(args, + "s*:fromstring", + &buffer)) + goto exit; + return_value = array_array_fromstring_impl(self, &buffer); + +exit: + /* Cleanup for buffer */ + if (buffer.obj) + PyBuffer_Release(&buffer); + + return return_value; +} + +PyDoc_STRVAR(array_array_frombytes__doc__, +"frombytes($self, buffer, /)\n" +"--\n" +"\n" +"Appends items from the string, interpreting it as an array of machine values, as if it had been read from a file using the fromfile() method)."); + +#define ARRAY_ARRAY_FROMBYTES_METHODDEF \ + {"frombytes", (PyCFunction)array_array_frombytes, METH_VARARGS, array_array_frombytes__doc__}, + +static PyObject * +array_array_frombytes_impl(arrayobject *self, Py_buffer *buffer); + +static PyObject * +array_array_frombytes(arrayobject *self, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer buffer = {NULL, NULL}; + + if (!PyArg_ParseTuple(args, + "y*:frombytes", + &buffer)) + goto exit; + return_value = array_array_frombytes_impl(self, &buffer); + +exit: + /* Cleanup for buffer */ + if (buffer.obj) + PyBuffer_Release(&buffer); + + return return_value; +} + +PyDoc_STRVAR(array_array_tobytes__doc__, +"tobytes($self, /)\n" +"--\n" +"\n" +"Convert the array to an array of machine values and return the bytes representation."); + +#define ARRAY_ARRAY_TOBYTES_METHODDEF \ + {"tobytes", (PyCFunction)array_array_tobytes, METH_NOARGS, array_array_tobytes__doc__}, + +static PyObject * +array_array_tobytes_impl(arrayobject *self); + +static PyObject * +array_array_tobytes(arrayobject *self, PyObject *Py_UNUSED(ignored)) +{ + return array_array_tobytes_impl(self); +} + +PyDoc_STRVAR(array_array_tostring__doc__, +"tostring($self, /)\n" +"--\n" +"\n" +"Convert the array to an array of machine values and return the bytes representation.\n" +"\n" +"This method is deprecated. Use tobytes instead."); + +#define ARRAY_ARRAY_TOSTRING_METHODDEF \ + {"tostring", (PyCFunction)array_array_tostring, METH_NOARGS, array_array_tostring__doc__}, + +static PyObject * +array_array_tostring_impl(arrayobject *self); + +static PyObject * +array_array_tostring(arrayobject *self, PyObject *Py_UNUSED(ignored)) +{ + return array_array_tostring_impl(self); +} + +PyDoc_STRVAR(array_array_fromunicode__doc__, +"fromunicode($self, ustr, /)\n" +"--\n" +"\n" +"Extends this array with data from the unicode string ustr.\n" +"\n" +"The array must be a unicode type array; otherwise a ValueError is raised.\n" +"Use array.frombytes(ustr.encode(...)) to append Unicode data to an array of\n" +"some other type."); + +#define ARRAY_ARRAY_FROMUNICODE_METHODDEF \ + {"fromunicode", (PyCFunction)array_array_fromunicode, METH_VARARGS, array_array_fromunicode__doc__}, + +static PyObject * +array_array_fromunicode_impl(arrayobject *self, Py_UNICODE *ustr, Py_ssize_clean_t ustr_length); + +static PyObject * +array_array_fromunicode(arrayobject *self, PyObject *args) +{ + PyObject *return_value = NULL; + Py_UNICODE *ustr; + Py_ssize_clean_t ustr_length; + + if (!PyArg_ParseTuple(args, + "u#:fromunicode", + &ustr, &ustr_length)) + goto exit; + return_value = array_array_fromunicode_impl(self, ustr, ustr_length); + +exit: + return return_value; +} + +PyDoc_STRVAR(array_array_tounicode__doc__, +"tounicode($self, /)\n" +"--\n" +"\n" +"Extends this array with data from the unicode string ustr.\n" +"\n" +"Convert the array to a unicode string. The array must be a unicode type array;\n" +"otherwise a ValueError is raised. Use array.tobytes().decode() to obtain a\n" +"unicode string from an array of some other type."); + +#define ARRAY_ARRAY_TOUNICODE_METHODDEF \ + {"tounicode", (PyCFunction)array_array_tounicode, METH_NOARGS, array_array_tounicode__doc__}, + +static PyObject * +array_array_tounicode_impl(arrayobject *self); + +static PyObject * +array_array_tounicode(arrayobject *self, PyObject *Py_UNUSED(ignored)) +{ + return array_array_tounicode_impl(self); +} + +PyDoc_STRVAR(array_array___sizeof____doc__, +"__sizeof__($self, /)\n" +"--\n" +"\n" +"Size of the array in memory, in bytes."); + +#define ARRAY_ARRAY___SIZEOF___METHODDEF \ + {"__sizeof__", (PyCFunction)array_array___sizeof__, METH_NOARGS, array_array___sizeof____doc__}, + +static PyObject * +array_array___sizeof___impl(arrayobject *self); + +static PyObject * +array_array___sizeof__(arrayobject *self, PyObject *Py_UNUSED(ignored)) +{ + return array_array___sizeof___impl(self); +} + +PyDoc_STRVAR(array__array_reconstructor__doc__, +"_array_reconstructor($module, arraytype, typecode, mformat_code, items,\n" +" /)\n" +"--\n" +"\n" +"Internal. Used for pickling support."); + +#define ARRAY__ARRAY_RECONSTRUCTOR_METHODDEF \ + {"_array_reconstructor", (PyCFunction)array__array_reconstructor, METH_VARARGS, array__array_reconstructor__doc__}, + +static PyObject * +array__array_reconstructor_impl(PyModuleDef *module, PyTypeObject *arraytype, int typecode, enum machine_format_code mformat_code, PyObject *items); + +static PyObject * +array__array_reconstructor(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyTypeObject *arraytype; + int typecode; + enum machine_format_code mformat_code; + PyObject *items; + + if (!PyArg_ParseTuple(args, + "OCiO:_array_reconstructor", + &arraytype, &typecode, &mformat_code, &items)) + goto exit; + return_value = array__array_reconstructor_impl(module, arraytype, typecode, mformat_code, items); + +exit: + return return_value; +} + +PyDoc_STRVAR(array_array___reduce_ex____doc__, +"__reduce_ex__($self, value, /)\n" +"--\n" +"\n" +"Return state information for pickling."); + +#define ARRAY_ARRAY___REDUCE_EX___METHODDEF \ + {"__reduce_ex__", (PyCFunction)array_array___reduce_ex__, METH_O, array_array___reduce_ex____doc__}, + +PyDoc_STRVAR(array_arrayiterator___reduce____doc__, +"__reduce__($self, /)\n" +"--\n" +"\n" +"Return state information for pickling."); + +#define ARRAY_ARRAYITERATOR___REDUCE___METHODDEF \ + {"__reduce__", (PyCFunction)array_arrayiterator___reduce__, METH_NOARGS, array_arrayiterator___reduce____doc__}, + +static PyObject * +array_arrayiterator___reduce___impl(arrayiterobject *self); + +static PyObject * +array_arrayiterator___reduce__(arrayiterobject *self, PyObject *Py_UNUSED(ignored)) +{ + return array_arrayiterator___reduce___impl(self); +} + +PyDoc_STRVAR(array_arrayiterator___setstate____doc__, +"__setstate__($self, state, /)\n" +"--\n" +"\n" +"Set state information for unpickling."); + +#define ARRAY_ARRAYITERATOR___SETSTATE___METHODDEF \ + {"__setstate__", (PyCFunction)array_arrayiterator___setstate__, METH_O, array_arrayiterator___setstate____doc__}, +/*[clinic end generated code: output=e1deb61c6a3bc8c8 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/audioop.c.h b/Modules/clinic/audioop.c.h new file mode 100644 index 000000000000..40ef5e2dc4dc --- /dev/null +++ b/Modules/clinic/audioop.c.h @@ -0,0 +1,889 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(audioop_getsample__doc__, +"getsample($module, fragment, width, index, /)\n" +"--\n" +"\n" +"Return the value of sample index from the fragment."); + +#define AUDIOOP_GETSAMPLE_METHODDEF \ + {"getsample", (PyCFunction)audioop_getsample, METH_VARARGS, audioop_getsample__doc__}, + +static PyObject * +audioop_getsample_impl(PyModuleDef *module, Py_buffer *fragment, int width, Py_ssize_t index); + +static PyObject * +audioop_getsample(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + Py_ssize_t index; + + if (!PyArg_ParseTuple(args, + "y*in:getsample", + &fragment, &width, &index)) + goto exit; + return_value = audioop_getsample_impl(module, &fragment, width, index); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) + PyBuffer_Release(&fragment); + + return return_value; +} + +PyDoc_STRVAR(audioop_max__doc__, +"max($module, fragment, width, /)\n" +"--\n" +"\n" +"Return the maximum of the absolute value of all samples in a fragment."); + +#define AUDIOOP_MAX_METHODDEF \ + {"max", (PyCFunction)audioop_max, METH_VARARGS, audioop_max__doc__}, + +static PyObject * +audioop_max_impl(PyModuleDef *module, Py_buffer *fragment, int width); + +static PyObject * +audioop_max(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + + if (!PyArg_ParseTuple(args, + "y*i:max", + &fragment, &width)) + goto exit; + return_value = audioop_max_impl(module, &fragment, width); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) + PyBuffer_Release(&fragment); + + return return_value; +} + +PyDoc_STRVAR(audioop_minmax__doc__, +"minmax($module, fragment, width, /)\n" +"--\n" +"\n" +"Return the minimum and maximum values of all samples in the sound fragment."); + +#define AUDIOOP_MINMAX_METHODDEF \ + {"minmax", (PyCFunction)audioop_minmax, METH_VARARGS, audioop_minmax__doc__}, + +static PyObject * +audioop_minmax_impl(PyModuleDef *module, Py_buffer *fragment, int width); + +static PyObject * +audioop_minmax(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + + if (!PyArg_ParseTuple(args, + "y*i:minmax", + &fragment, &width)) + goto exit; + return_value = audioop_minmax_impl(module, &fragment, width); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) + PyBuffer_Release(&fragment); + + return return_value; +} + +PyDoc_STRVAR(audioop_avg__doc__, +"avg($module, fragment, width, /)\n" +"--\n" +"\n" +"Return the average over all samples in the fragment."); + +#define AUDIOOP_AVG_METHODDEF \ + {"avg", (PyCFunction)audioop_avg, METH_VARARGS, audioop_avg__doc__}, + +static PyObject * +audioop_avg_impl(PyModuleDef *module, Py_buffer *fragment, int width); + +static PyObject * +audioop_avg(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + + if (!PyArg_ParseTuple(args, + "y*i:avg", + &fragment, &width)) + goto exit; + return_value = audioop_avg_impl(module, &fragment, width); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) + PyBuffer_Release(&fragment); + + return return_value; +} + +PyDoc_STRVAR(audioop_rms__doc__, +"rms($module, fragment, width, /)\n" +"--\n" +"\n" +"Return the root-mean-square of the fragment, i.e. sqrt(sum(S_i^2)/n)."); + +#define AUDIOOP_RMS_METHODDEF \ + {"rms", (PyCFunction)audioop_rms, METH_VARARGS, audioop_rms__doc__}, + +static PyObject * +audioop_rms_impl(PyModuleDef *module, Py_buffer *fragment, int width); + +static PyObject * +audioop_rms(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + + if (!PyArg_ParseTuple(args, + "y*i:rms", + &fragment, &width)) + goto exit; + return_value = audioop_rms_impl(module, &fragment, width); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) + PyBuffer_Release(&fragment); + + return return_value; +} + +PyDoc_STRVAR(audioop_findfit__doc__, +"findfit($module, fragment, reference, /)\n" +"--\n" +"\n" +"Try to match reference as well as possible to a portion of fragment."); + +#define AUDIOOP_FINDFIT_METHODDEF \ + {"findfit", (PyCFunction)audioop_findfit, METH_VARARGS, audioop_findfit__doc__}, + +static PyObject * +audioop_findfit_impl(PyModuleDef *module, Py_buffer *fragment, Py_buffer *reference); + +static PyObject * +audioop_findfit(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + Py_buffer reference = {NULL, NULL}; + + if (!PyArg_ParseTuple(args, + "y*y*:findfit", + &fragment, &reference)) + goto exit; + return_value = audioop_findfit_impl(module, &fragment, &reference); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) + PyBuffer_Release(&fragment); + /* Cleanup for reference */ + if (reference.obj) + PyBuffer_Release(&reference); + + return return_value; +} + +PyDoc_STRVAR(audioop_findfactor__doc__, +"findfactor($module, fragment, reference, /)\n" +"--\n" +"\n" +"Return a factor F such that rms(add(fragment, mul(reference, -F))) is minimal."); + +#define AUDIOOP_FINDFACTOR_METHODDEF \ + {"findfactor", (PyCFunction)audioop_findfactor, METH_VARARGS, audioop_findfactor__doc__}, + +static PyObject * +audioop_findfactor_impl(PyModuleDef *module, Py_buffer *fragment, Py_buffer *reference); + +static PyObject * +audioop_findfactor(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + Py_buffer reference = {NULL, NULL}; + + if (!PyArg_ParseTuple(args, + "y*y*:findfactor", + &fragment, &reference)) + goto exit; + return_value = audioop_findfactor_impl(module, &fragment, &reference); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) + PyBuffer_Release(&fragment); + /* Cleanup for reference */ + if (reference.obj) + PyBuffer_Release(&reference); + + return return_value; +} + +PyDoc_STRVAR(audioop_findmax__doc__, +"findmax($module, fragment, length, /)\n" +"--\n" +"\n" +"Search fragment for a slice of specified number of samples with maximum energy."); + +#define AUDIOOP_FINDMAX_METHODDEF \ + {"findmax", (PyCFunction)audioop_findmax, METH_VARARGS, audioop_findmax__doc__}, + +static PyObject * +audioop_findmax_impl(PyModuleDef *module, Py_buffer *fragment, Py_ssize_t length); + +static PyObject * +audioop_findmax(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + Py_ssize_t length; + + if (!PyArg_ParseTuple(args, + "y*n:findmax", + &fragment, &length)) + goto exit; + return_value = audioop_findmax_impl(module, &fragment, length); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) + PyBuffer_Release(&fragment); + + return return_value; +} + +PyDoc_STRVAR(audioop_avgpp__doc__, +"avgpp($module, fragment, width, /)\n" +"--\n" +"\n" +"Return the average peak-peak value over all samples in the fragment."); + +#define AUDIOOP_AVGPP_METHODDEF \ + {"avgpp", (PyCFunction)audioop_avgpp, METH_VARARGS, audioop_avgpp__doc__}, + +static PyObject * +audioop_avgpp_impl(PyModuleDef *module, Py_buffer *fragment, int width); + +static PyObject * +audioop_avgpp(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + + if (!PyArg_ParseTuple(args, + "y*i:avgpp", + &fragment, &width)) + goto exit; + return_value = audioop_avgpp_impl(module, &fragment, width); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) + PyBuffer_Release(&fragment); + + return return_value; +} + +PyDoc_STRVAR(audioop_maxpp__doc__, +"maxpp($module, fragment, width, /)\n" +"--\n" +"\n" +"Return the maximum peak-peak value in the sound fragment."); + +#define AUDIOOP_MAXPP_METHODDEF \ + {"maxpp", (PyCFunction)audioop_maxpp, METH_VARARGS, audioop_maxpp__doc__}, + +static PyObject * +audioop_maxpp_impl(PyModuleDef *module, Py_buffer *fragment, int width); + +static PyObject * +audioop_maxpp(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + + if (!PyArg_ParseTuple(args, + "y*i:maxpp", + &fragment, &width)) + goto exit; + return_value = audioop_maxpp_impl(module, &fragment, width); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) + PyBuffer_Release(&fragment); + + return return_value; +} + +PyDoc_STRVAR(audioop_cross__doc__, +"cross($module, fragment, width, /)\n" +"--\n" +"\n" +"Return the number of zero crossings in the fragment passed as an argument."); + +#define AUDIOOP_CROSS_METHODDEF \ + {"cross", (PyCFunction)audioop_cross, METH_VARARGS, audioop_cross__doc__}, + +static PyObject * +audioop_cross_impl(PyModuleDef *module, Py_buffer *fragment, int width); + +static PyObject * +audioop_cross(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + + if (!PyArg_ParseTuple(args, + "y*i:cross", + &fragment, &width)) + goto exit; + return_value = audioop_cross_impl(module, &fragment, width); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) + PyBuffer_Release(&fragment); + + return return_value; +} + +PyDoc_STRVAR(audioop_mul__doc__, +"mul($module, fragment, width, factor, /)\n" +"--\n" +"\n" +"Return a fragment that has all samples in the original fragment multiplied by the floating-point value factor."); + +#define AUDIOOP_MUL_METHODDEF \ + {"mul", (PyCFunction)audioop_mul, METH_VARARGS, audioop_mul__doc__}, + +static PyObject * +audioop_mul_impl(PyModuleDef *module, Py_buffer *fragment, int width, double factor); + +static PyObject * +audioop_mul(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + double factor; + + if (!PyArg_ParseTuple(args, + "y*id:mul", + &fragment, &width, &factor)) + goto exit; + return_value = audioop_mul_impl(module, &fragment, width, factor); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) + PyBuffer_Release(&fragment); + + return return_value; +} + +PyDoc_STRVAR(audioop_tomono__doc__, +"tomono($module, fragment, width, lfactor, rfactor, /)\n" +"--\n" +"\n" +"Convert a stereo fragment to a mono fragment."); + +#define AUDIOOP_TOMONO_METHODDEF \ + {"tomono", (PyCFunction)audioop_tomono, METH_VARARGS, audioop_tomono__doc__}, + +static PyObject * +audioop_tomono_impl(PyModuleDef *module, Py_buffer *fragment, int width, double lfactor, double rfactor); + +static PyObject * +audioop_tomono(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + double lfactor; + double rfactor; + + if (!PyArg_ParseTuple(args, + "y*idd:tomono", + &fragment, &width, &lfactor, &rfactor)) + goto exit; + return_value = audioop_tomono_impl(module, &fragment, width, lfactor, rfactor); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) + PyBuffer_Release(&fragment); + + return return_value; +} + +PyDoc_STRVAR(audioop_tostereo__doc__, +"tostereo($module, fragment, width, lfactor, rfactor, /)\n" +"--\n" +"\n" +"Generate a stereo fragment from a mono fragment."); + +#define AUDIOOP_TOSTEREO_METHODDEF \ + {"tostereo", (PyCFunction)audioop_tostereo, METH_VARARGS, audioop_tostereo__doc__}, + +static PyObject * +audioop_tostereo_impl(PyModuleDef *module, Py_buffer *fragment, int width, double lfactor, double rfactor); + +static PyObject * +audioop_tostereo(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + double lfactor; + double rfactor; + + if (!PyArg_ParseTuple(args, + "y*idd:tostereo", + &fragment, &width, &lfactor, &rfactor)) + goto exit; + return_value = audioop_tostereo_impl(module, &fragment, width, lfactor, rfactor); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) + PyBuffer_Release(&fragment); + + return return_value; +} + +PyDoc_STRVAR(audioop_add__doc__, +"add($module, fragment1, fragment2, width, /)\n" +"--\n" +"\n" +"Return a fragment which is the addition of the two samples passed as parameters."); + +#define AUDIOOP_ADD_METHODDEF \ + {"add", (PyCFunction)audioop_add, METH_VARARGS, audioop_add__doc__}, + +static PyObject * +audioop_add_impl(PyModuleDef *module, Py_buffer *fragment1, Py_buffer *fragment2, int width); + +static PyObject * +audioop_add(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment1 = {NULL, NULL}; + Py_buffer fragment2 = {NULL, NULL}; + int width; + + if (!PyArg_ParseTuple(args, + "y*y*i:add", + &fragment1, &fragment2, &width)) + goto exit; + return_value = audioop_add_impl(module, &fragment1, &fragment2, width); + +exit: + /* Cleanup for fragment1 */ + if (fragment1.obj) + PyBuffer_Release(&fragment1); + /* Cleanup for fragment2 */ + if (fragment2.obj) + PyBuffer_Release(&fragment2); + + return return_value; +} + +PyDoc_STRVAR(audioop_bias__doc__, +"bias($module, fragment, width, bias, /)\n" +"--\n" +"\n" +"Return a fragment that is the original fragment with a bias added to each sample."); + +#define AUDIOOP_BIAS_METHODDEF \ + {"bias", (PyCFunction)audioop_bias, METH_VARARGS, audioop_bias__doc__}, + +static PyObject * +audioop_bias_impl(PyModuleDef *module, Py_buffer *fragment, int width, int bias); + +static PyObject * +audioop_bias(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + int bias; + + if (!PyArg_ParseTuple(args, + "y*ii:bias", + &fragment, &width, &bias)) + goto exit; + return_value = audioop_bias_impl(module, &fragment, width, bias); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) + PyBuffer_Release(&fragment); + + return return_value; +} + +PyDoc_STRVAR(audioop_reverse__doc__, +"reverse($module, fragment, width, /)\n" +"--\n" +"\n" +"Reverse the samples in a fragment and returns the modified fragment."); + +#define AUDIOOP_REVERSE_METHODDEF \ + {"reverse", (PyCFunction)audioop_reverse, METH_VARARGS, audioop_reverse__doc__}, + +static PyObject * +audioop_reverse_impl(PyModuleDef *module, Py_buffer *fragment, int width); + +static PyObject * +audioop_reverse(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + + if (!PyArg_ParseTuple(args, + "y*i:reverse", + &fragment, &width)) + goto exit; + return_value = audioop_reverse_impl(module, &fragment, width); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) + PyBuffer_Release(&fragment); + + return return_value; +} + +PyDoc_STRVAR(audioop_byteswap__doc__, +"byteswap($module, fragment, width, /)\n" +"--\n" +"\n" +"Convert big-endian samples to little-endian and vice versa."); + +#define AUDIOOP_BYTESWAP_METHODDEF \ + {"byteswap", (PyCFunction)audioop_byteswap, METH_VARARGS, audioop_byteswap__doc__}, + +static PyObject * +audioop_byteswap_impl(PyModuleDef *module, Py_buffer *fragment, int width); + +static PyObject * +audioop_byteswap(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + + if (!PyArg_ParseTuple(args, + "y*i:byteswap", + &fragment, &width)) + goto exit; + return_value = audioop_byteswap_impl(module, &fragment, width); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) + PyBuffer_Release(&fragment); + + return return_value; +} + +PyDoc_STRVAR(audioop_lin2lin__doc__, +"lin2lin($module, fragment, width, newwidth, /)\n" +"--\n" +"\n" +"Convert samples between 1-, 2-, 3- and 4-byte formats."); + +#define AUDIOOP_LIN2LIN_METHODDEF \ + {"lin2lin", (PyCFunction)audioop_lin2lin, METH_VARARGS, audioop_lin2lin__doc__}, + +static PyObject * +audioop_lin2lin_impl(PyModuleDef *module, Py_buffer *fragment, int width, int newwidth); + +static PyObject * +audioop_lin2lin(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + int newwidth; + + if (!PyArg_ParseTuple(args, + "y*ii:lin2lin", + &fragment, &width, &newwidth)) + goto exit; + return_value = audioop_lin2lin_impl(module, &fragment, width, newwidth); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) + PyBuffer_Release(&fragment); + + return return_value; +} + +PyDoc_STRVAR(audioop_ratecv__doc__, +"ratecv($module, fragment, width, nchannels, inrate, outrate, state,\n" +" weightA=1, weightB=0, /)\n" +"--\n" +"\n" +"Convert the frame rate of the input fragment."); + +#define AUDIOOP_RATECV_METHODDEF \ + {"ratecv", (PyCFunction)audioop_ratecv, METH_VARARGS, audioop_ratecv__doc__}, + +static PyObject * +audioop_ratecv_impl(PyModuleDef *module, Py_buffer *fragment, int width, int nchannels, int inrate, int outrate, PyObject *state, int weightA, int weightB); + +static PyObject * +audioop_ratecv(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + int nchannels; + int inrate; + int outrate; + PyObject *state; + int weightA = 1; + int weightB = 0; + + if (!PyArg_ParseTuple(args, + "y*iiiiO|ii:ratecv", + &fragment, &width, &nchannels, &inrate, &outrate, &state, &weightA, &weightB)) + goto exit; + return_value = audioop_ratecv_impl(module, &fragment, width, nchannels, inrate, outrate, state, weightA, weightB); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) + PyBuffer_Release(&fragment); + + return return_value; +} + +PyDoc_STRVAR(audioop_lin2ulaw__doc__, +"lin2ulaw($module, fragment, width, /)\n" +"--\n" +"\n" +"Convert samples in the audio fragment to u-LAW encoding."); + +#define AUDIOOP_LIN2ULAW_METHODDEF \ + {"lin2ulaw", (PyCFunction)audioop_lin2ulaw, METH_VARARGS, audioop_lin2ulaw__doc__}, + +static PyObject * +audioop_lin2ulaw_impl(PyModuleDef *module, Py_buffer *fragment, int width); + +static PyObject * +audioop_lin2ulaw(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + + if (!PyArg_ParseTuple(args, + "y*i:lin2ulaw", + &fragment, &width)) + goto exit; + return_value = audioop_lin2ulaw_impl(module, &fragment, width); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) + PyBuffer_Release(&fragment); + + return return_value; +} + +PyDoc_STRVAR(audioop_ulaw2lin__doc__, +"ulaw2lin($module, fragment, width, /)\n" +"--\n" +"\n" +"Convert sound fragments in u-LAW encoding to linearly encoded sound fragments."); + +#define AUDIOOP_ULAW2LIN_METHODDEF \ + {"ulaw2lin", (PyCFunction)audioop_ulaw2lin, METH_VARARGS, audioop_ulaw2lin__doc__}, + +static PyObject * +audioop_ulaw2lin_impl(PyModuleDef *module, Py_buffer *fragment, int width); + +static PyObject * +audioop_ulaw2lin(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + + if (!PyArg_ParseTuple(args, + "y*i:ulaw2lin", + &fragment, &width)) + goto exit; + return_value = audioop_ulaw2lin_impl(module, &fragment, width); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) + PyBuffer_Release(&fragment); + + return return_value; +} + +PyDoc_STRVAR(audioop_lin2alaw__doc__, +"lin2alaw($module, fragment, width, /)\n" +"--\n" +"\n" +"Convert samples in the audio fragment to a-LAW encoding."); + +#define AUDIOOP_LIN2ALAW_METHODDEF \ + {"lin2alaw", (PyCFunction)audioop_lin2alaw, METH_VARARGS, audioop_lin2alaw__doc__}, + +static PyObject * +audioop_lin2alaw_impl(PyModuleDef *module, Py_buffer *fragment, int width); + +static PyObject * +audioop_lin2alaw(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + + if (!PyArg_ParseTuple(args, + "y*i:lin2alaw", + &fragment, &width)) + goto exit; + return_value = audioop_lin2alaw_impl(module, &fragment, width); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) + PyBuffer_Release(&fragment); + + return return_value; +} + +PyDoc_STRVAR(audioop_alaw2lin__doc__, +"alaw2lin($module, fragment, width, /)\n" +"--\n" +"\n" +"Convert sound fragments in a-LAW encoding to linearly encoded sound fragments."); + +#define AUDIOOP_ALAW2LIN_METHODDEF \ + {"alaw2lin", (PyCFunction)audioop_alaw2lin, METH_VARARGS, audioop_alaw2lin__doc__}, + +static PyObject * +audioop_alaw2lin_impl(PyModuleDef *module, Py_buffer *fragment, int width); + +static PyObject * +audioop_alaw2lin(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + + if (!PyArg_ParseTuple(args, + "y*i:alaw2lin", + &fragment, &width)) + goto exit; + return_value = audioop_alaw2lin_impl(module, &fragment, width); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) + PyBuffer_Release(&fragment); + + return return_value; +} + +PyDoc_STRVAR(audioop_lin2adpcm__doc__, +"lin2adpcm($module, fragment, width, state, /)\n" +"--\n" +"\n" +"Convert samples to 4 bit Intel/DVI ADPCM encoding."); + +#define AUDIOOP_LIN2ADPCM_METHODDEF \ + {"lin2adpcm", (PyCFunction)audioop_lin2adpcm, METH_VARARGS, audioop_lin2adpcm__doc__}, + +static PyObject * +audioop_lin2adpcm_impl(PyModuleDef *module, Py_buffer *fragment, int width, PyObject *state); + +static PyObject * +audioop_lin2adpcm(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + PyObject *state; + + if (!PyArg_ParseTuple(args, + "y*iO:lin2adpcm", + &fragment, &width, &state)) + goto exit; + return_value = audioop_lin2adpcm_impl(module, &fragment, width, state); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) + PyBuffer_Release(&fragment); + + return return_value; +} + +PyDoc_STRVAR(audioop_adpcm2lin__doc__, +"adpcm2lin($module, fragment, width, state, /)\n" +"--\n" +"\n" +"Decode an Intel/DVI ADPCM coded fragment to a linear fragment."); + +#define AUDIOOP_ADPCM2LIN_METHODDEF \ + {"adpcm2lin", (PyCFunction)audioop_adpcm2lin, METH_VARARGS, audioop_adpcm2lin__doc__}, + +static PyObject * +audioop_adpcm2lin_impl(PyModuleDef *module, Py_buffer *fragment, int width, PyObject *state); + +static PyObject * +audioop_adpcm2lin(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + PyObject *state; + + if (!PyArg_ParseTuple(args, + "y*iO:adpcm2lin", + &fragment, &width, &state)) + goto exit; + return_value = audioop_adpcm2lin_impl(module, &fragment, width, state); + +exit: + /* Cleanup for fragment */ + if (fragment.obj) + PyBuffer_Release(&fragment); + + return return_value; +} +/*[clinic end generated code: output=be840bba5d40c2ce input=a9049054013a1b77]*/ diff --git a/Modules/clinic/binascii.c.h b/Modules/clinic/binascii.c.h new file mode 100644 index 000000000000..b2b6e6b4faf2 --- /dev/null +++ b/Modules/clinic/binascii.c.h @@ -0,0 +1,546 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(binascii_a2b_uu__doc__, +"a2b_uu($module, data, /)\n" +"--\n" +"\n" +"Decode a line of uuencoded data."); + +#define BINASCII_A2B_UU_METHODDEF \ + {"a2b_uu", (PyCFunction)binascii_a2b_uu, METH_VARARGS, binascii_a2b_uu__doc__}, + +static PyObject * +binascii_a2b_uu_impl(PyModuleDef *module, Py_buffer *data); + +static PyObject * +binascii_a2b_uu(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + + if (!PyArg_ParseTuple(args, + "O&:a2b_uu", + ascii_buffer_converter, &data)) + goto exit; + return_value = binascii_a2b_uu_impl(module, &data); + +exit: + /* Cleanup for data */ + if (data.obj) + PyBuffer_Release(&data); + + return return_value; +} + +PyDoc_STRVAR(binascii_b2a_uu__doc__, +"b2a_uu($module, data, /)\n" +"--\n" +"\n" +"Uuencode line of data."); + +#define BINASCII_B2A_UU_METHODDEF \ + {"b2a_uu", (PyCFunction)binascii_b2a_uu, METH_VARARGS, binascii_b2a_uu__doc__}, + +static PyObject * +binascii_b2a_uu_impl(PyModuleDef *module, Py_buffer *data); + +static PyObject * +binascii_b2a_uu(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + + if (!PyArg_ParseTuple(args, + "y*:b2a_uu", + &data)) + goto exit; + return_value = binascii_b2a_uu_impl(module, &data); + +exit: + /* Cleanup for data */ + if (data.obj) + PyBuffer_Release(&data); + + return return_value; +} + +PyDoc_STRVAR(binascii_a2b_base64__doc__, +"a2b_base64($module, data, /)\n" +"--\n" +"\n" +"Decode a line of base64 data."); + +#define BINASCII_A2B_BASE64_METHODDEF \ + {"a2b_base64", (PyCFunction)binascii_a2b_base64, METH_VARARGS, binascii_a2b_base64__doc__}, + +static PyObject * +binascii_a2b_base64_impl(PyModuleDef *module, Py_buffer *data); + +static PyObject * +binascii_a2b_base64(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + + if (!PyArg_ParseTuple(args, + "O&:a2b_base64", + ascii_buffer_converter, &data)) + goto exit; + return_value = binascii_a2b_base64_impl(module, &data); + +exit: + /* Cleanup for data */ + if (data.obj) + PyBuffer_Release(&data); + + return return_value; +} + +PyDoc_STRVAR(binascii_b2a_base64__doc__, +"b2a_base64($module, data, /)\n" +"--\n" +"\n" +"Base64-code line of data."); + +#define BINASCII_B2A_BASE64_METHODDEF \ + {"b2a_base64", (PyCFunction)binascii_b2a_base64, METH_VARARGS, binascii_b2a_base64__doc__}, + +static PyObject * +binascii_b2a_base64_impl(PyModuleDef *module, Py_buffer *data); + +static PyObject * +binascii_b2a_base64(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + + if (!PyArg_ParseTuple(args, + "y*:b2a_base64", + &data)) + goto exit; + return_value = binascii_b2a_base64_impl(module, &data); + +exit: + /* Cleanup for data */ + if (data.obj) + PyBuffer_Release(&data); + + return return_value; +} + +PyDoc_STRVAR(binascii_a2b_hqx__doc__, +"a2b_hqx($module, data, /)\n" +"--\n" +"\n" +"Decode .hqx coding."); + +#define BINASCII_A2B_HQX_METHODDEF \ + {"a2b_hqx", (PyCFunction)binascii_a2b_hqx, METH_VARARGS, binascii_a2b_hqx__doc__}, + +static PyObject * +binascii_a2b_hqx_impl(PyModuleDef *module, Py_buffer *data); + +static PyObject * +binascii_a2b_hqx(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + + if (!PyArg_ParseTuple(args, + "O&:a2b_hqx", + ascii_buffer_converter, &data)) + goto exit; + return_value = binascii_a2b_hqx_impl(module, &data); + +exit: + /* Cleanup for data */ + if (data.obj) + PyBuffer_Release(&data); + + return return_value; +} + +PyDoc_STRVAR(binascii_rlecode_hqx__doc__, +"rlecode_hqx($module, data, /)\n" +"--\n" +"\n" +"Binhex RLE-code binary data."); + +#define BINASCII_RLECODE_HQX_METHODDEF \ + {"rlecode_hqx", (PyCFunction)binascii_rlecode_hqx, METH_VARARGS, binascii_rlecode_hqx__doc__}, + +static PyObject * +binascii_rlecode_hqx_impl(PyModuleDef *module, Py_buffer *data); + +static PyObject * +binascii_rlecode_hqx(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + + if (!PyArg_ParseTuple(args, + "y*:rlecode_hqx", + &data)) + goto exit; + return_value = binascii_rlecode_hqx_impl(module, &data); + +exit: + /* Cleanup for data */ + if (data.obj) + PyBuffer_Release(&data); + + return return_value; +} + +PyDoc_STRVAR(binascii_b2a_hqx__doc__, +"b2a_hqx($module, data, /)\n" +"--\n" +"\n" +"Encode .hqx data."); + +#define BINASCII_B2A_HQX_METHODDEF \ + {"b2a_hqx", (PyCFunction)binascii_b2a_hqx, METH_VARARGS, binascii_b2a_hqx__doc__}, + +static PyObject * +binascii_b2a_hqx_impl(PyModuleDef *module, Py_buffer *data); + +static PyObject * +binascii_b2a_hqx(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + + if (!PyArg_ParseTuple(args, + "y*:b2a_hqx", + &data)) + goto exit; + return_value = binascii_b2a_hqx_impl(module, &data); + +exit: + /* Cleanup for data */ + if (data.obj) + PyBuffer_Release(&data); + + return return_value; +} + +PyDoc_STRVAR(binascii_rledecode_hqx__doc__, +"rledecode_hqx($module, data, /)\n" +"--\n" +"\n" +"Decode hexbin RLE-coded string."); + +#define BINASCII_RLEDECODE_HQX_METHODDEF \ + {"rledecode_hqx", (PyCFunction)binascii_rledecode_hqx, METH_VARARGS, binascii_rledecode_hqx__doc__}, + +static PyObject * +binascii_rledecode_hqx_impl(PyModuleDef *module, Py_buffer *data); + +static PyObject * +binascii_rledecode_hqx(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + + if (!PyArg_ParseTuple(args, + "y*:rledecode_hqx", + &data)) + goto exit; + return_value = binascii_rledecode_hqx_impl(module, &data); + +exit: + /* Cleanup for data */ + if (data.obj) + PyBuffer_Release(&data); + + return return_value; +} + +PyDoc_STRVAR(binascii_crc_hqx__doc__, +"crc_hqx($module, data, crc, /)\n" +"--\n" +"\n" +"Compute hqx CRC incrementally."); + +#define BINASCII_CRC_HQX_METHODDEF \ + {"crc_hqx", (PyCFunction)binascii_crc_hqx, METH_VARARGS, binascii_crc_hqx__doc__}, + +static int +binascii_crc_hqx_impl(PyModuleDef *module, Py_buffer *data, int crc); + +static PyObject * +binascii_crc_hqx(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + int crc; + int _return_value; + + if (!PyArg_ParseTuple(args, + "y*i:crc_hqx", + &data, &crc)) + goto exit; + _return_value = binascii_crc_hqx_impl(module, &data, crc); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromLong((long)_return_value); + +exit: + /* Cleanup for data */ + if (data.obj) + PyBuffer_Release(&data); + + return return_value; +} + +PyDoc_STRVAR(binascii_crc32__doc__, +"crc32($module, data, crc=0, /)\n" +"--\n" +"\n" +"Compute CRC-32 incrementally."); + +#define BINASCII_CRC32_METHODDEF \ + {"crc32", (PyCFunction)binascii_crc32, METH_VARARGS, binascii_crc32__doc__}, + +static unsigned int +binascii_crc32_impl(PyModuleDef *module, Py_buffer *data, unsigned int crc); + +static PyObject * +binascii_crc32(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + unsigned int crc = 0; + unsigned int _return_value; + + if (!PyArg_ParseTuple(args, + "y*|I:crc32", + &data, &crc)) + goto exit; + _return_value = binascii_crc32_impl(module, &data, crc); + if ((_return_value == (unsigned int)-1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromUnsignedLong((unsigned long)_return_value); + +exit: + /* Cleanup for data */ + if (data.obj) + PyBuffer_Release(&data); + + return return_value; +} + +PyDoc_STRVAR(binascii_b2a_hex__doc__, +"b2a_hex($module, data, /)\n" +"--\n" +"\n" +"Hexadecimal representation of binary data.\n" +"\n" +"The return value is a bytes object. This function is also\n" +"available as \"hexlify()\"."); + +#define BINASCII_B2A_HEX_METHODDEF \ + {"b2a_hex", (PyCFunction)binascii_b2a_hex, METH_VARARGS, binascii_b2a_hex__doc__}, + +static PyObject * +binascii_b2a_hex_impl(PyModuleDef *module, Py_buffer *data); + +static PyObject * +binascii_b2a_hex(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + + if (!PyArg_ParseTuple(args, + "y*:b2a_hex", + &data)) + goto exit; + return_value = binascii_b2a_hex_impl(module, &data); + +exit: + /* Cleanup for data */ + if (data.obj) + PyBuffer_Release(&data); + + return return_value; +} + +PyDoc_STRVAR(binascii_hexlify__doc__, +"hexlify($module, data, /)\n" +"--\n" +"\n" +"Hexadecimal representation of binary data.\n" +"\n" +"The return value is a bytes object."); + +#define BINASCII_HEXLIFY_METHODDEF \ + {"hexlify", (PyCFunction)binascii_hexlify, METH_VARARGS, binascii_hexlify__doc__}, + +static PyObject * +binascii_hexlify_impl(PyModuleDef *module, Py_buffer *data); + +static PyObject * +binascii_hexlify(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + + if (!PyArg_ParseTuple(args, + "y*:hexlify", + &data)) + goto exit; + return_value = binascii_hexlify_impl(module, &data); + +exit: + /* Cleanup for data */ + if (data.obj) + PyBuffer_Release(&data); + + return return_value; +} + +PyDoc_STRVAR(binascii_a2b_hex__doc__, +"a2b_hex($module, hexstr, /)\n" +"--\n" +"\n" +"Binary data of hexadecimal representation.\n" +"\n" +"hexstr must contain an even number of hex digits (upper or lower case).\n" +"This function is also available as \"unhexlify()\"."); + +#define BINASCII_A2B_HEX_METHODDEF \ + {"a2b_hex", (PyCFunction)binascii_a2b_hex, METH_VARARGS, binascii_a2b_hex__doc__}, + +static PyObject * +binascii_a2b_hex_impl(PyModuleDef *module, Py_buffer *hexstr); + +static PyObject * +binascii_a2b_hex(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer hexstr = {NULL, NULL}; + + if (!PyArg_ParseTuple(args, + "O&:a2b_hex", + ascii_buffer_converter, &hexstr)) + goto exit; + return_value = binascii_a2b_hex_impl(module, &hexstr); + +exit: + /* Cleanup for hexstr */ + if (hexstr.obj) + PyBuffer_Release(&hexstr); + + return return_value; +} + +PyDoc_STRVAR(binascii_unhexlify__doc__, +"unhexlify($module, hexstr, /)\n" +"--\n" +"\n" +"Binary data of hexadecimal representation.\n" +"\n" +"hexstr must contain an even number of hex digits (upper or lower case)."); + +#define BINASCII_UNHEXLIFY_METHODDEF \ + {"unhexlify", (PyCFunction)binascii_unhexlify, METH_VARARGS, binascii_unhexlify__doc__}, + +static PyObject * +binascii_unhexlify_impl(PyModuleDef *module, Py_buffer *hexstr); + +static PyObject * +binascii_unhexlify(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer hexstr = {NULL, NULL}; + + if (!PyArg_ParseTuple(args, + "O&:unhexlify", + ascii_buffer_converter, &hexstr)) + goto exit; + return_value = binascii_unhexlify_impl(module, &hexstr); + +exit: + /* Cleanup for hexstr */ + if (hexstr.obj) + PyBuffer_Release(&hexstr); + + return return_value; +} + +PyDoc_STRVAR(binascii_a2b_qp__doc__, +"a2b_qp($module, /, data, header=False)\n" +"--\n" +"\n" +"Decode a string of qp-encoded data."); + +#define BINASCII_A2B_QP_METHODDEF \ + {"a2b_qp", (PyCFunction)binascii_a2b_qp, METH_VARARGS|METH_KEYWORDS, binascii_a2b_qp__doc__}, + +static PyObject * +binascii_a2b_qp_impl(PyModuleDef *module, Py_buffer *data, int header); + +static PyObject * +binascii_a2b_qp(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"data", "header", NULL}; + Py_buffer data = {NULL, NULL}; + int header = 0; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&|i:a2b_qp", _keywords, + ascii_buffer_converter, &data, &header)) + goto exit; + return_value = binascii_a2b_qp_impl(module, &data, header); + +exit: + /* Cleanup for data */ + if (data.obj) + PyBuffer_Release(&data); + + return return_value; +} + +PyDoc_STRVAR(binascii_b2a_qp__doc__, +"b2a_qp($module, /, data, quotetabs=False, istext=True, header=False)\n" +"--\n" +"\n" +"Encode a string using quoted-printable encoding.\n" +"\n" +"On encoding, when istext is set, newlines are not encoded, and white\n" +"space at end of lines is. When istext is not set, \\r and \\n (CR/LF)\n" +"are both encoded. When quotetabs is set, space and tabs are encoded."); + +#define BINASCII_B2A_QP_METHODDEF \ + {"b2a_qp", (PyCFunction)binascii_b2a_qp, METH_VARARGS|METH_KEYWORDS, binascii_b2a_qp__doc__}, + +static PyObject * +binascii_b2a_qp_impl(PyModuleDef *module, Py_buffer *data, int quotetabs, int istext, int header); + +static PyObject * +binascii_b2a_qp(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"data", "quotetabs", "istext", "header", NULL}; + Py_buffer data = {NULL, NULL}; + int quotetabs = 0; + int istext = 1; + int header = 0; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "y*|iii:b2a_qp", _keywords, + &data, "etabs, &istext, &header)) + goto exit; + return_value = binascii_b2a_qp_impl(module, &data, quotetabs, istext, header); + +exit: + /* Cleanup for data */ + if (data.obj) + PyBuffer_Release(&data); + + return return_value; +} +/*[clinic end generated code: output=771126f8f53e84e7 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/cmathmodule.c.h b/Modules/clinic/cmathmodule.c.h new file mode 100644 index 000000000000..d0c48d334eeb --- /dev/null +++ b/Modules/clinic/cmathmodule.c.h @@ -0,0 +1,851 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(cmath_acos__doc__, +"acos($module, z, /)\n" +"--\n" +"\n" +"Return the arc cosine of z."); + +#define CMATH_ACOS_METHODDEF \ + {"acos", (PyCFunction)cmath_acos, METH_VARARGS, cmath_acos__doc__}, + +static Py_complex +cmath_acos_impl(PyModuleDef *module, Py_complex z); + +static PyObject * +cmath_acos(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_complex z; + Py_complex _return_value; + + if (!PyArg_ParseTuple(args, + "D:acos", + &z)) + goto exit; + /* modifications for z */ + errno = 0; PyFPE_START_PROTECT("complex function", goto exit); + _return_value = cmath_acos_impl(module, z); + PyFPE_END_PROTECT(_return_value); + if (errno == EDOM) { + PyErr_SetString(PyExc_ValueError, "math domain error"); + goto exit; + } + else if (errno == ERANGE) { + PyErr_SetString(PyExc_OverflowError, "math range error"); + goto exit; + } + else { + return_value = PyComplex_FromCComplex(_return_value); + } + +exit: + return return_value; +} + +PyDoc_STRVAR(cmath_acosh__doc__, +"acosh($module, z, /)\n" +"--\n" +"\n" +"Return the inverse hyperbolic cosine of z."); + +#define CMATH_ACOSH_METHODDEF \ + {"acosh", (PyCFunction)cmath_acosh, METH_VARARGS, cmath_acosh__doc__}, + +static Py_complex +cmath_acosh_impl(PyModuleDef *module, Py_complex z); + +static PyObject * +cmath_acosh(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_complex z; + Py_complex _return_value; + + if (!PyArg_ParseTuple(args, + "D:acosh", + &z)) + goto exit; + /* modifications for z */ + errno = 0; PyFPE_START_PROTECT("complex function", goto exit); + _return_value = cmath_acosh_impl(module, z); + PyFPE_END_PROTECT(_return_value); + if (errno == EDOM) { + PyErr_SetString(PyExc_ValueError, "math domain error"); + goto exit; + } + else if (errno == ERANGE) { + PyErr_SetString(PyExc_OverflowError, "math range error"); + goto exit; + } + else { + return_value = PyComplex_FromCComplex(_return_value); + } + +exit: + return return_value; +} + +PyDoc_STRVAR(cmath_asin__doc__, +"asin($module, z, /)\n" +"--\n" +"\n" +"Return the arc sine of z."); + +#define CMATH_ASIN_METHODDEF \ + {"asin", (PyCFunction)cmath_asin, METH_VARARGS, cmath_asin__doc__}, + +static Py_complex +cmath_asin_impl(PyModuleDef *module, Py_complex z); + +static PyObject * +cmath_asin(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_complex z; + Py_complex _return_value; + + if (!PyArg_ParseTuple(args, + "D:asin", + &z)) + goto exit; + /* modifications for z */ + errno = 0; PyFPE_START_PROTECT("complex function", goto exit); + _return_value = cmath_asin_impl(module, z); + PyFPE_END_PROTECT(_return_value); + if (errno == EDOM) { + PyErr_SetString(PyExc_ValueError, "math domain error"); + goto exit; + } + else if (errno == ERANGE) { + PyErr_SetString(PyExc_OverflowError, "math range error"); + goto exit; + } + else { + return_value = PyComplex_FromCComplex(_return_value); + } + +exit: + return return_value; +} + +PyDoc_STRVAR(cmath_asinh__doc__, +"asinh($module, z, /)\n" +"--\n" +"\n" +"Return the inverse hyperbolic sine of z."); + +#define CMATH_ASINH_METHODDEF \ + {"asinh", (PyCFunction)cmath_asinh, METH_VARARGS, cmath_asinh__doc__}, + +static Py_complex +cmath_asinh_impl(PyModuleDef *module, Py_complex z); + +static PyObject * +cmath_asinh(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_complex z; + Py_complex _return_value; + + if (!PyArg_ParseTuple(args, + "D:asinh", + &z)) + goto exit; + /* modifications for z */ + errno = 0; PyFPE_START_PROTECT("complex function", goto exit); + _return_value = cmath_asinh_impl(module, z); + PyFPE_END_PROTECT(_return_value); + if (errno == EDOM) { + PyErr_SetString(PyExc_ValueError, "math domain error"); + goto exit; + } + else if (errno == ERANGE) { + PyErr_SetString(PyExc_OverflowError, "math range error"); + goto exit; + } + else { + return_value = PyComplex_FromCComplex(_return_value); + } + +exit: + return return_value; +} + +PyDoc_STRVAR(cmath_atan__doc__, +"atan($module, z, /)\n" +"--\n" +"\n" +"Return the arc tangent of z."); + +#define CMATH_ATAN_METHODDEF \ + {"atan", (PyCFunction)cmath_atan, METH_VARARGS, cmath_atan__doc__}, + +static Py_complex +cmath_atan_impl(PyModuleDef *module, Py_complex z); + +static PyObject * +cmath_atan(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_complex z; + Py_complex _return_value; + + if (!PyArg_ParseTuple(args, + "D:atan", + &z)) + goto exit; + /* modifications for z */ + errno = 0; PyFPE_START_PROTECT("complex function", goto exit); + _return_value = cmath_atan_impl(module, z); + PyFPE_END_PROTECT(_return_value); + if (errno == EDOM) { + PyErr_SetString(PyExc_ValueError, "math domain error"); + goto exit; + } + else if (errno == ERANGE) { + PyErr_SetString(PyExc_OverflowError, "math range error"); + goto exit; + } + else { + return_value = PyComplex_FromCComplex(_return_value); + } + +exit: + return return_value; +} + +PyDoc_STRVAR(cmath_atanh__doc__, +"atanh($module, z, /)\n" +"--\n" +"\n" +"Return the inverse hyperbolic tangent of z."); + +#define CMATH_ATANH_METHODDEF \ + {"atanh", (PyCFunction)cmath_atanh, METH_VARARGS, cmath_atanh__doc__}, + +static Py_complex +cmath_atanh_impl(PyModuleDef *module, Py_complex z); + +static PyObject * +cmath_atanh(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_complex z; + Py_complex _return_value; + + if (!PyArg_ParseTuple(args, + "D:atanh", + &z)) + goto exit; + /* modifications for z */ + errno = 0; PyFPE_START_PROTECT("complex function", goto exit); + _return_value = cmath_atanh_impl(module, z); + PyFPE_END_PROTECT(_return_value); + if (errno == EDOM) { + PyErr_SetString(PyExc_ValueError, "math domain error"); + goto exit; + } + else if (errno == ERANGE) { + PyErr_SetString(PyExc_OverflowError, "math range error"); + goto exit; + } + else { + return_value = PyComplex_FromCComplex(_return_value); + } + +exit: + return return_value; +} + +PyDoc_STRVAR(cmath_cos__doc__, +"cos($module, z, /)\n" +"--\n" +"\n" +"Return the cosine of z."); + +#define CMATH_COS_METHODDEF \ + {"cos", (PyCFunction)cmath_cos, METH_VARARGS, cmath_cos__doc__}, + +static Py_complex +cmath_cos_impl(PyModuleDef *module, Py_complex z); + +static PyObject * +cmath_cos(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_complex z; + Py_complex _return_value; + + if (!PyArg_ParseTuple(args, + "D:cos", + &z)) + goto exit; + /* modifications for z */ + errno = 0; PyFPE_START_PROTECT("complex function", goto exit); + _return_value = cmath_cos_impl(module, z); + PyFPE_END_PROTECT(_return_value); + if (errno == EDOM) { + PyErr_SetString(PyExc_ValueError, "math domain error"); + goto exit; + } + else if (errno == ERANGE) { + PyErr_SetString(PyExc_OverflowError, "math range error"); + goto exit; + } + else { + return_value = PyComplex_FromCComplex(_return_value); + } + +exit: + return return_value; +} + +PyDoc_STRVAR(cmath_cosh__doc__, +"cosh($module, z, /)\n" +"--\n" +"\n" +"Return the hyperbolic cosine of z."); + +#define CMATH_COSH_METHODDEF \ + {"cosh", (PyCFunction)cmath_cosh, METH_VARARGS, cmath_cosh__doc__}, + +static Py_complex +cmath_cosh_impl(PyModuleDef *module, Py_complex z); + +static PyObject * +cmath_cosh(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_complex z; + Py_complex _return_value; + + if (!PyArg_ParseTuple(args, + "D:cosh", + &z)) + goto exit; + /* modifications for z */ + errno = 0; PyFPE_START_PROTECT("complex function", goto exit); + _return_value = cmath_cosh_impl(module, z); + PyFPE_END_PROTECT(_return_value); + if (errno == EDOM) { + PyErr_SetString(PyExc_ValueError, "math domain error"); + goto exit; + } + else if (errno == ERANGE) { + PyErr_SetString(PyExc_OverflowError, "math range error"); + goto exit; + } + else { + return_value = PyComplex_FromCComplex(_return_value); + } + +exit: + return return_value; +} + +PyDoc_STRVAR(cmath_exp__doc__, +"exp($module, z, /)\n" +"--\n" +"\n" +"Return the exponential value e**z."); + +#define CMATH_EXP_METHODDEF \ + {"exp", (PyCFunction)cmath_exp, METH_VARARGS, cmath_exp__doc__}, + +static Py_complex +cmath_exp_impl(PyModuleDef *module, Py_complex z); + +static PyObject * +cmath_exp(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_complex z; + Py_complex _return_value; + + if (!PyArg_ParseTuple(args, + "D:exp", + &z)) + goto exit; + /* modifications for z */ + errno = 0; PyFPE_START_PROTECT("complex function", goto exit); + _return_value = cmath_exp_impl(module, z); + PyFPE_END_PROTECT(_return_value); + if (errno == EDOM) { + PyErr_SetString(PyExc_ValueError, "math domain error"); + goto exit; + } + else if (errno == ERANGE) { + PyErr_SetString(PyExc_OverflowError, "math range error"); + goto exit; + } + else { + return_value = PyComplex_FromCComplex(_return_value); + } + +exit: + return return_value; +} + +PyDoc_STRVAR(cmath_log10__doc__, +"log10($module, z, /)\n" +"--\n" +"\n" +"Return the base-10 logarithm of z."); + +#define CMATH_LOG10_METHODDEF \ + {"log10", (PyCFunction)cmath_log10, METH_VARARGS, cmath_log10__doc__}, + +static Py_complex +cmath_log10_impl(PyModuleDef *module, Py_complex z); + +static PyObject * +cmath_log10(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_complex z; + Py_complex _return_value; + + if (!PyArg_ParseTuple(args, + "D:log10", + &z)) + goto exit; + /* modifications for z */ + errno = 0; PyFPE_START_PROTECT("complex function", goto exit); + _return_value = cmath_log10_impl(module, z); + PyFPE_END_PROTECT(_return_value); + if (errno == EDOM) { + PyErr_SetString(PyExc_ValueError, "math domain error"); + goto exit; + } + else if (errno == ERANGE) { + PyErr_SetString(PyExc_OverflowError, "math range error"); + goto exit; + } + else { + return_value = PyComplex_FromCComplex(_return_value); + } + +exit: + return return_value; +} + +PyDoc_STRVAR(cmath_sin__doc__, +"sin($module, z, /)\n" +"--\n" +"\n" +"Return the sine of z."); + +#define CMATH_SIN_METHODDEF \ + {"sin", (PyCFunction)cmath_sin, METH_VARARGS, cmath_sin__doc__}, + +static Py_complex +cmath_sin_impl(PyModuleDef *module, Py_complex z); + +static PyObject * +cmath_sin(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_complex z; + Py_complex _return_value; + + if (!PyArg_ParseTuple(args, + "D:sin", + &z)) + goto exit; + /* modifications for z */ + errno = 0; PyFPE_START_PROTECT("complex function", goto exit); + _return_value = cmath_sin_impl(module, z); + PyFPE_END_PROTECT(_return_value); + if (errno == EDOM) { + PyErr_SetString(PyExc_ValueError, "math domain error"); + goto exit; + } + else if (errno == ERANGE) { + PyErr_SetString(PyExc_OverflowError, "math range error"); + goto exit; + } + else { + return_value = PyComplex_FromCComplex(_return_value); + } + +exit: + return return_value; +} + +PyDoc_STRVAR(cmath_sinh__doc__, +"sinh($module, z, /)\n" +"--\n" +"\n" +"Return the hyperbolic sine of z."); + +#define CMATH_SINH_METHODDEF \ + {"sinh", (PyCFunction)cmath_sinh, METH_VARARGS, cmath_sinh__doc__}, + +static Py_complex +cmath_sinh_impl(PyModuleDef *module, Py_complex z); + +static PyObject * +cmath_sinh(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_complex z; + Py_complex _return_value; + + if (!PyArg_ParseTuple(args, + "D:sinh", + &z)) + goto exit; + /* modifications for z */ + errno = 0; PyFPE_START_PROTECT("complex function", goto exit); + _return_value = cmath_sinh_impl(module, z); + PyFPE_END_PROTECT(_return_value); + if (errno == EDOM) { + PyErr_SetString(PyExc_ValueError, "math domain error"); + goto exit; + } + else if (errno == ERANGE) { + PyErr_SetString(PyExc_OverflowError, "math range error"); + goto exit; + } + else { + return_value = PyComplex_FromCComplex(_return_value); + } + +exit: + return return_value; +} + +PyDoc_STRVAR(cmath_sqrt__doc__, +"sqrt($module, z, /)\n" +"--\n" +"\n" +"Return the square root of z."); + +#define CMATH_SQRT_METHODDEF \ + {"sqrt", (PyCFunction)cmath_sqrt, METH_VARARGS, cmath_sqrt__doc__}, + +static Py_complex +cmath_sqrt_impl(PyModuleDef *module, Py_complex z); + +static PyObject * +cmath_sqrt(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_complex z; + Py_complex _return_value; + + if (!PyArg_ParseTuple(args, + "D:sqrt", + &z)) + goto exit; + /* modifications for z */ + errno = 0; PyFPE_START_PROTECT("complex function", goto exit); + _return_value = cmath_sqrt_impl(module, z); + PyFPE_END_PROTECT(_return_value); + if (errno == EDOM) { + PyErr_SetString(PyExc_ValueError, "math domain error"); + goto exit; + } + else if (errno == ERANGE) { + PyErr_SetString(PyExc_OverflowError, "math range error"); + goto exit; + } + else { + return_value = PyComplex_FromCComplex(_return_value); + } + +exit: + return return_value; +} + +PyDoc_STRVAR(cmath_tan__doc__, +"tan($module, z, /)\n" +"--\n" +"\n" +"Return the tangent of z."); + +#define CMATH_TAN_METHODDEF \ + {"tan", (PyCFunction)cmath_tan, METH_VARARGS, cmath_tan__doc__}, + +static Py_complex +cmath_tan_impl(PyModuleDef *module, Py_complex z); + +static PyObject * +cmath_tan(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_complex z; + Py_complex _return_value; + + if (!PyArg_ParseTuple(args, + "D:tan", + &z)) + goto exit; + /* modifications for z */ + errno = 0; PyFPE_START_PROTECT("complex function", goto exit); + _return_value = cmath_tan_impl(module, z); + PyFPE_END_PROTECT(_return_value); + if (errno == EDOM) { + PyErr_SetString(PyExc_ValueError, "math domain error"); + goto exit; + } + else if (errno == ERANGE) { + PyErr_SetString(PyExc_OverflowError, "math range error"); + goto exit; + } + else { + return_value = PyComplex_FromCComplex(_return_value); + } + +exit: + return return_value; +} + +PyDoc_STRVAR(cmath_tanh__doc__, +"tanh($module, z, /)\n" +"--\n" +"\n" +"Return the hyperbolic tangent of z."); + +#define CMATH_TANH_METHODDEF \ + {"tanh", (PyCFunction)cmath_tanh, METH_VARARGS, cmath_tanh__doc__}, + +static Py_complex +cmath_tanh_impl(PyModuleDef *module, Py_complex z); + +static PyObject * +cmath_tanh(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_complex z; + Py_complex _return_value; + + if (!PyArg_ParseTuple(args, + "D:tanh", + &z)) + goto exit; + /* modifications for z */ + errno = 0; PyFPE_START_PROTECT("complex function", goto exit); + _return_value = cmath_tanh_impl(module, z); + PyFPE_END_PROTECT(_return_value); + if (errno == EDOM) { + PyErr_SetString(PyExc_ValueError, "math domain error"); + goto exit; + } + else if (errno == ERANGE) { + PyErr_SetString(PyExc_OverflowError, "math range error"); + goto exit; + } + else { + return_value = PyComplex_FromCComplex(_return_value); + } + +exit: + return return_value; +} + +PyDoc_STRVAR(cmath_log__doc__, +"log($module, x, y_obj=None, /)\n" +"--\n" +"\n" +"The logarithm of z to the given base.\n" +"\n" +"If the base not specified, returns the natural logarithm (base e) of z."); + +#define CMATH_LOG_METHODDEF \ + {"log", (PyCFunction)cmath_log, METH_VARARGS, cmath_log__doc__}, + +static PyObject * +cmath_log_impl(PyModuleDef *module, Py_complex x, PyObject *y_obj); + +static PyObject * +cmath_log(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_complex x; + PyObject *y_obj = NULL; + + if (!PyArg_ParseTuple(args, + "D|O:log", + &x, &y_obj)) + goto exit; + return_value = cmath_log_impl(module, x, y_obj); + +exit: + return return_value; +} + +PyDoc_STRVAR(cmath_phase__doc__, +"phase($module, z, /)\n" +"--\n" +"\n" +"Return argument, also known as the phase angle, of a complex."); + +#define CMATH_PHASE_METHODDEF \ + {"phase", (PyCFunction)cmath_phase, METH_VARARGS, cmath_phase__doc__}, + +static PyObject * +cmath_phase_impl(PyModuleDef *module, Py_complex z); + +static PyObject * +cmath_phase(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_complex z; + + if (!PyArg_ParseTuple(args, + "D:phase", + &z)) + goto exit; + return_value = cmath_phase_impl(module, z); + +exit: + return return_value; +} + +PyDoc_STRVAR(cmath_polar__doc__, +"polar($module, z, /)\n" +"--\n" +"\n" +"Convert a complex from rectangular coordinates to polar coordinates.\n" +"\n" +"r is the distance from 0 and phi the phase angle."); + +#define CMATH_POLAR_METHODDEF \ + {"polar", (PyCFunction)cmath_polar, METH_VARARGS, cmath_polar__doc__}, + +static PyObject * +cmath_polar_impl(PyModuleDef *module, Py_complex z); + +static PyObject * +cmath_polar(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_complex z; + + if (!PyArg_ParseTuple(args, + "D:polar", + &z)) + goto exit; + return_value = cmath_polar_impl(module, z); + +exit: + return return_value; +} + +PyDoc_STRVAR(cmath_rect__doc__, +"rect($module, r, phi, /)\n" +"--\n" +"\n" +"Convert from polar coordinates to rectangular coordinates."); + +#define CMATH_RECT_METHODDEF \ + {"rect", (PyCFunction)cmath_rect, METH_VARARGS, cmath_rect__doc__}, + +static PyObject * +cmath_rect_impl(PyModuleDef *module, double r, double phi); + +static PyObject * +cmath_rect(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + double r; + double phi; + + if (!PyArg_ParseTuple(args, + "dd:rect", + &r, &phi)) + goto exit; + return_value = cmath_rect_impl(module, r, phi); + +exit: + return return_value; +} + +PyDoc_STRVAR(cmath_isfinite__doc__, +"isfinite($module, z, /)\n" +"--\n" +"\n" +"Return True if both the real and imaginary parts of z are finite, else False."); + +#define CMATH_ISFINITE_METHODDEF \ + {"isfinite", (PyCFunction)cmath_isfinite, METH_VARARGS, cmath_isfinite__doc__}, + +static PyObject * +cmath_isfinite_impl(PyModuleDef *module, Py_complex z); + +static PyObject * +cmath_isfinite(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_complex z; + + if (!PyArg_ParseTuple(args, + "D:isfinite", + &z)) + goto exit; + return_value = cmath_isfinite_impl(module, z); + +exit: + return return_value; +} + +PyDoc_STRVAR(cmath_isnan__doc__, +"isnan($module, z, /)\n" +"--\n" +"\n" +"Checks if the real or imaginary part of z not a number (NaN)."); + +#define CMATH_ISNAN_METHODDEF \ + {"isnan", (PyCFunction)cmath_isnan, METH_VARARGS, cmath_isnan__doc__}, + +static PyObject * +cmath_isnan_impl(PyModuleDef *module, Py_complex z); + +static PyObject * +cmath_isnan(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_complex z; + + if (!PyArg_ParseTuple(args, + "D:isnan", + &z)) + goto exit; + return_value = cmath_isnan_impl(module, z); + +exit: + return return_value; +} + +PyDoc_STRVAR(cmath_isinf__doc__, +"isinf($module, z, /)\n" +"--\n" +"\n" +"Checks if the real or imaginary part of z is infinite."); + +#define CMATH_ISINF_METHODDEF \ + {"isinf", (PyCFunction)cmath_isinf, METH_VARARGS, cmath_isinf__doc__}, + +static PyObject * +cmath_isinf_impl(PyModuleDef *module, Py_complex z); + +static PyObject * +cmath_isinf(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_complex z; + + if (!PyArg_ParseTuple(args, + "D:isinf", + &z)) + goto exit; + return_value = cmath_isinf_impl(module, z); + +exit: + return return_value; +} +/*[clinic end generated code: output=9b6d81711e4e3c4b input=a9049054013a1b77]*/ diff --git a/Modules/clinic/fcntlmodule.c.h b/Modules/clinic/fcntlmodule.c.h new file mode 100644 index 000000000000..377e55d8c5cb --- /dev/null +++ b/Modules/clinic/fcntlmodule.c.h @@ -0,0 +1,188 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(fcntl_fcntl__doc__, +"fcntl($module, fd, code, arg=None, /)\n" +"--\n" +"\n" +"Perform the operation `code` on file descriptor fd.\n" +"\n" +"The values used for `code` are operating system dependent, and are available\n" +"as constants in the fcntl module, using the same names as used in\n" +"the relevant C header files. The argument arg is optional, and\n" +"defaults to 0; it may be an int or a string. If arg is given as a string,\n" +"the return value of fcntl is a string of that length, containing the\n" +"resulting value put in the arg buffer by the operating system. The length\n" +"of the arg string is not allowed to exceed 1024 bytes. If the arg given\n" +"is an integer or if none is specified, the result value is an integer\n" +"corresponding to the return value of the fcntl call in the C code."); + +#define FCNTL_FCNTL_METHODDEF \ + {"fcntl", (PyCFunction)fcntl_fcntl, METH_VARARGS, fcntl_fcntl__doc__}, + +static PyObject * +fcntl_fcntl_impl(PyModuleDef *module, int fd, int code, PyObject *arg); + +static PyObject * +fcntl_fcntl(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd; + int code; + PyObject *arg = NULL; + + if (!PyArg_ParseTuple(args, + "O&i|O:fcntl", + conv_descriptor, &fd, &code, &arg)) + goto exit; + return_value = fcntl_fcntl_impl(module, fd, code, arg); + +exit: + return return_value; +} + +PyDoc_STRVAR(fcntl_ioctl__doc__, +"ioctl($module, fd, op, arg=None, mutate_flag=True, /)\n" +"--\n" +"\n" +"Perform the operation op on file descriptor fd.\n" +"\n" +"The values used for op are operating system dependent, and are available as\n" +"constants in the fcntl or termios library modules, using the same names as\n" +"used in the relevant C header files.\n" +"\n" +"The argument `arg` is optional, and defaults to 0; it may be an int or a\n" +"buffer containing character data (most likely a string or an array).\n" +"\n" +"If the argument is a mutable buffer (such as an array) and if the\n" +"mutate_flag argument (which is only allowed in this case) is true then the\n" +"buffer is (in effect) passed to the operating system and changes made by\n" +"the OS will be reflected in the contents of the buffer after the call has\n" +"returned. The return value is the integer returned by the ioctl system\n" +"call.\n" +"\n" +"If the argument is a mutable buffer and the mutable_flag argument is not\n" +"passed or is false, the behavior is as if a string had been passed. This\n" +"behavior will change in future releases of Python.\n" +"\n" +"If the argument is an immutable buffer (most likely a string) then a copy\n" +"of the buffer is passed to the operating system and the return value is a\n" +"string of the same length containing whatever the operating system put in\n" +"the buffer. The length of the arg buffer in this case is not allowed to\n" +"exceed 1024 bytes.\n" +"\n" +"If the arg given is an integer or if none is specified, the result value is\n" +"an integer corresponding to the return value of the ioctl call in the C\n" +"code."); + +#define FCNTL_IOCTL_METHODDEF \ + {"ioctl", (PyCFunction)fcntl_ioctl, METH_VARARGS, fcntl_ioctl__doc__}, + +static PyObject * +fcntl_ioctl_impl(PyModuleDef *module, int fd, unsigned int code, PyObject *ob_arg, int mutate_arg); + +static PyObject * +fcntl_ioctl(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd; + unsigned int code; + PyObject *ob_arg = NULL; + int mutate_arg = 1; + + if (!PyArg_ParseTuple(args, + "O&I|Op:ioctl", + conv_descriptor, &fd, &code, &ob_arg, &mutate_arg)) + goto exit; + return_value = fcntl_ioctl_impl(module, fd, code, ob_arg, mutate_arg); + +exit: + return return_value; +} + +PyDoc_STRVAR(fcntl_flock__doc__, +"flock($module, fd, code, /)\n" +"--\n" +"\n" +"Perform the lock operation op on file descriptor fd.\n" +"\n" +"See the Unix manual page for flock(2) for details (On some systems, this\n" +"function is emulated using fcntl())."); + +#define FCNTL_FLOCK_METHODDEF \ + {"flock", (PyCFunction)fcntl_flock, METH_VARARGS, fcntl_flock__doc__}, + +static PyObject * +fcntl_flock_impl(PyModuleDef *module, int fd, int code); + +static PyObject * +fcntl_flock(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd; + int code; + + if (!PyArg_ParseTuple(args, + "O&i:flock", + conv_descriptor, &fd, &code)) + goto exit; + return_value = fcntl_flock_impl(module, fd, code); + +exit: + return return_value; +} + +PyDoc_STRVAR(fcntl_lockf__doc__, +"lockf($module, fd, code, lenobj=None, startobj=None, whence=0, /)\n" +"--\n" +"\n" +"A wrapper around the fcntl() locking calls.\n" +"\n" +"fd is the file descriptor of the file to lock or unlock, and operation is one\n" +"of the following values:\n" +"\n" +" LOCK_UN - unlock\n" +" LOCK_SH - acquire a shared lock\n" +" LOCK_EX - acquire an exclusive lock\n" +"\n" +"When operation is LOCK_SH or LOCK_EX, it can also be bitwise ORed with\n" +"LOCK_NB to avoid blocking on lock acquisition. If LOCK_NB is used and the\n" +"lock cannot be acquired, an IOError will be raised and the exception will\n" +"have an errno attribute set to EACCES or EAGAIN (depending on the operating\n" +"system -- for portability, check for either value).\n" +"\n" +"length is the number of bytes to lock, with the default meaning to lock to\n" +"EOF. start is the byte offset, relative to whence, to that the lock\n" +"starts. whence is as with fileobj.seek(), specifically:\n" +"\n" +" 0 - relative to the start of the file (SEEK_SET)\n" +" 1 - relative to the current buffer position (SEEK_CUR)\n" +" 2 - relative to the end of the file (SEEK_END)"); + +#define FCNTL_LOCKF_METHODDEF \ + {"lockf", (PyCFunction)fcntl_lockf, METH_VARARGS, fcntl_lockf__doc__}, + +static PyObject * +fcntl_lockf_impl(PyModuleDef *module, int fd, int code, PyObject *lenobj, PyObject *startobj, int whence); + +static PyObject * +fcntl_lockf(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd; + int code; + PyObject *lenobj = NULL; + PyObject *startobj = NULL; + int whence = 0; + + if (!PyArg_ParseTuple(args, + "O&i|OOi:lockf", + conv_descriptor, &fd, &code, &lenobj, &startobj, &whence)) + goto exit; + return_value = fcntl_lockf_impl(module, fd, code, lenobj, startobj, whence); + +exit: + return return_value; +} +/*[clinic end generated code: output=84bdde73a92f7c61 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/grpmodule.c.h b/Modules/clinic/grpmodule.c.h new file mode 100644 index 000000000000..681830954b1a --- /dev/null +++ b/Modules/clinic/grpmodule.c.h @@ -0,0 +1,87 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(grp_getgrgid__doc__, +"getgrgid($module, /, id)\n" +"--\n" +"\n" +"Return the group database entry for the given numeric group ID.\n" +"\n" +"If id is not valid, raise KeyError."); + +#define GRP_GETGRGID_METHODDEF \ + {"getgrgid", (PyCFunction)grp_getgrgid, METH_VARARGS|METH_KEYWORDS, grp_getgrgid__doc__}, + +static PyObject * +grp_getgrgid_impl(PyModuleDef *module, PyObject *id); + +static PyObject * +grp_getgrgid(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"id", NULL}; + PyObject *id; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O:getgrgid", _keywords, + &id)) + goto exit; + return_value = grp_getgrgid_impl(module, id); + +exit: + return return_value; +} + +PyDoc_STRVAR(grp_getgrnam__doc__, +"getgrnam($module, /, name)\n" +"--\n" +"\n" +"Return the group database entry for the given group name.\n" +"\n" +"If name is not valid, raise KeyError."); + +#define GRP_GETGRNAM_METHODDEF \ + {"getgrnam", (PyCFunction)grp_getgrnam, METH_VARARGS|METH_KEYWORDS, grp_getgrnam__doc__}, + +static PyObject * +grp_getgrnam_impl(PyModuleDef *module, PyObject *name); + +static PyObject * +grp_getgrnam(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"name", NULL}; + PyObject *name; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "U:getgrnam", _keywords, + &name)) + goto exit; + return_value = grp_getgrnam_impl(module, name); + +exit: + return return_value; +} + +PyDoc_STRVAR(grp_getgrall__doc__, +"getgrall($module, /)\n" +"--\n" +"\n" +"Return a list of all available group entries, in arbitrary order.\n" +"\n" +"An entry whose name starts with \'+\' or \'-\' represents an instruction\n" +"to use YP/NIS and may not be accessible via getgrnam or getgrgid."); + +#define GRP_GETGRALL_METHODDEF \ + {"getgrall", (PyCFunction)grp_getgrall, METH_NOARGS, grp_getgrall__doc__}, + +static PyObject * +grp_getgrall_impl(PyModuleDef *module); + +static PyObject * +grp_getgrall(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return grp_getgrall_impl(module); +} +/*[clinic end generated code: output=4709a6ba40bb8df9 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/pwdmodule.c.h b/Modules/clinic/pwdmodule.c.h new file mode 100644 index 000000000000..6a40042c5ecb --- /dev/null +++ b/Modules/clinic/pwdmodule.c.h @@ -0,0 +1,73 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(pwd_getpwuid__doc__, +"getpwuid($module, uidobj, /)\n" +"--\n" +"\n" +"Return the password database entry for the given numeric user ID.\n" +"\n" +"See `help(pwd)` for more on password database entries."); + +#define PWD_GETPWUID_METHODDEF \ + {"getpwuid", (PyCFunction)pwd_getpwuid, METH_O, pwd_getpwuid__doc__}, + +PyDoc_STRVAR(pwd_getpwnam__doc__, +"getpwnam($module, arg, /)\n" +"--\n" +"\n" +"Return the password database entry for the given user name.\n" +"\n" +"See `help(pwd)` for more on password database entries."); + +#define PWD_GETPWNAM_METHODDEF \ + {"getpwnam", (PyCFunction)pwd_getpwnam, METH_VARARGS, pwd_getpwnam__doc__}, + +static PyObject * +pwd_getpwnam_impl(PyModuleDef *module, PyObject *arg); + +static PyObject * +pwd_getpwnam(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *arg; + + if (!PyArg_ParseTuple(args, + "U:getpwnam", + &arg)) + goto exit; + return_value = pwd_getpwnam_impl(module, arg); + +exit: + return return_value; +} + +#if defined(HAVE_GETPWENT) + +PyDoc_STRVAR(pwd_getpwall__doc__, +"getpwall($module, /)\n" +"--\n" +"\n" +"Return a list of all available password database entries, in arbitrary order.\n" +"\n" +"See help(pwd) for more on password database entries."); + +#define PWD_GETPWALL_METHODDEF \ + {"getpwall", (PyCFunction)pwd_getpwall, METH_NOARGS, pwd_getpwall__doc__}, + +static PyObject * +pwd_getpwall_impl(PyModuleDef *module); + +static PyObject * +pwd_getpwall(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return pwd_getpwall_impl(module); +} + +#endif /* defined(HAVE_GETPWENT) */ + +#ifndef PWD_GETPWALL_METHODDEF + #define PWD_GETPWALL_METHODDEF +#endif /* !defined(PWD_GETPWALL_METHODDEF) */ +/*[clinic end generated code: output=2e23f920020a750a input=a9049054013a1b77]*/ diff --git a/Modules/clinic/spwdmodule.c.h b/Modules/clinic/spwdmodule.c.h new file mode 100644 index 000000000000..b091fc9ba72c --- /dev/null +++ b/Modules/clinic/spwdmodule.c.h @@ -0,0 +1,70 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if defined(HAVE_GETSPNAM) + +PyDoc_STRVAR(spwd_getspnam__doc__, +"getspnam($module, arg, /)\n" +"--\n" +"\n" +"Return the shadow password database entry for the given user name.\n" +"\n" +"See `help(spwd)` for more on shadow password database entries."); + +#define SPWD_GETSPNAM_METHODDEF \ + {"getspnam", (PyCFunction)spwd_getspnam, METH_VARARGS, spwd_getspnam__doc__}, + +static PyObject * +spwd_getspnam_impl(PyModuleDef *module, PyObject *arg); + +static PyObject * +spwd_getspnam(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *arg; + + if (!PyArg_ParseTuple(args, + "U:getspnam", + &arg)) + goto exit; + return_value = spwd_getspnam_impl(module, arg); + +exit: + return return_value; +} + +#endif /* defined(HAVE_GETSPNAM) */ + +#ifndef SPWD_GETSPNAM_METHODDEF + #define SPWD_GETSPNAM_METHODDEF +#endif /* !defined(SPWD_GETSPNAM_METHODDEF) */ + +#if defined(HAVE_GETSPENT) + +PyDoc_STRVAR(spwd_getspall__doc__, +"getspall($module, /)\n" +"--\n" +"\n" +"Return a list of all available shadow password database entries, in arbitrary order.\n" +"\n" +"See `help(spwd)` for more on shadow password database entries."); + +#define SPWD_GETSPALL_METHODDEF \ + {"getspall", (PyCFunction)spwd_getspall, METH_NOARGS, spwd_getspall__doc__}, + +static PyObject * +spwd_getspall_impl(PyModuleDef *module); + +static PyObject * +spwd_getspall(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return spwd_getspall_impl(module); +} + +#endif /* defined(HAVE_GETSPENT) */ + +#ifndef SPWD_GETSPALL_METHODDEF + #define SPWD_GETSPALL_METHODDEF +#endif /* !defined(SPWD_GETSPALL_METHODDEF) */ +/*[clinic end generated code: output=41fec4a15b0cd2a0 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/zlibmodule.c.h b/Modules/clinic/zlibmodule.c.h new file mode 100644 index 000000000000..f54a80537703 --- /dev/null +++ b/Modules/clinic/zlibmodule.c.h @@ -0,0 +1,453 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(zlib_compress__doc__, +"compress($module, bytes, level=Z_DEFAULT_COMPRESSION, /)\n" +"--\n" +"\n" +"Returns a bytes object containing compressed data.\n" +"\n" +" bytes\n" +" Binary data to be compressed.\n" +" level\n" +" Compression level, in 0-9."); + +#define ZLIB_COMPRESS_METHODDEF \ + {"compress", (PyCFunction)zlib_compress, METH_VARARGS, zlib_compress__doc__}, + +static PyObject * +zlib_compress_impl(PyModuleDef *module, Py_buffer *bytes, int level); + +static PyObject * +zlib_compress(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer bytes = {NULL, NULL}; + int level = Z_DEFAULT_COMPRESSION; + + if (!PyArg_ParseTuple(args, + "y*|i:compress", + &bytes, &level)) + goto exit; + return_value = zlib_compress_impl(module, &bytes, level); + +exit: + /* Cleanup for bytes */ + if (bytes.obj) + PyBuffer_Release(&bytes); + + return return_value; +} + +PyDoc_STRVAR(zlib_decompress__doc__, +"decompress($module, data, wbits=MAX_WBITS, bufsize=DEF_BUF_SIZE, /)\n" +"--\n" +"\n" +"Returns a bytes object containing the uncompressed data.\n" +"\n" +" data\n" +" Compressed data.\n" +" wbits\n" +" The window buffer size.\n" +" bufsize\n" +" The initial output buffer size."); + +#define ZLIB_DECOMPRESS_METHODDEF \ + {"decompress", (PyCFunction)zlib_decompress, METH_VARARGS, zlib_decompress__doc__}, + +static PyObject * +zlib_decompress_impl(PyModuleDef *module, Py_buffer *data, int wbits, unsigned int bufsize); + +static PyObject * +zlib_decompress(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + int wbits = MAX_WBITS; + unsigned int bufsize = DEF_BUF_SIZE; + + if (!PyArg_ParseTuple(args, + "y*|iO&:decompress", + &data, &wbits, uint_converter, &bufsize)) + goto exit; + return_value = zlib_decompress_impl(module, &data, wbits, bufsize); + +exit: + /* Cleanup for data */ + if (data.obj) + PyBuffer_Release(&data); + + return return_value; +} + +PyDoc_STRVAR(zlib_compressobj__doc__, +"compressobj($module, /, level=Z_DEFAULT_COMPRESSION, method=DEFLATED,\n" +" wbits=MAX_WBITS, memLevel=DEF_MEM_LEVEL,\n" +" strategy=Z_DEFAULT_STRATEGY, zdict=None)\n" +"--\n" +"\n" +"Return a compressor object.\n" +"\n" +" level\n" +" The compression level (an integer in the range 0-9; default is 6).\n" +" Higher compression levels are slower, but produce smaller results.\n" +" method\n" +" The compression algorithm. If given, this must be DEFLATED.\n" +" wbits\n" +" The base two logarithm of the window size (range: 8..15).\n" +" memLevel\n" +" Controls the amount of memory used for internal compression state.\n" +" Valid values range from 1 to 9. Higher values result in higher memory\n" +" usage, faster compression, and smaller output.\n" +" strategy\n" +" Used to tune the compression algorithm. Possible values are\n" +" Z_DEFAULT_STRATEGY, Z_FILTERED, and Z_HUFFMAN_ONLY.\n" +" zdict\n" +" The predefined compression dictionary - a sequence of bytes\n" +" containing subsequences that are likely to occur in the input data."); + +#define ZLIB_COMPRESSOBJ_METHODDEF \ + {"compressobj", (PyCFunction)zlib_compressobj, METH_VARARGS|METH_KEYWORDS, zlib_compressobj__doc__}, + +static PyObject * +zlib_compressobj_impl(PyModuleDef *module, int level, int method, int wbits, int memLevel, int strategy, Py_buffer *zdict); + +static PyObject * +zlib_compressobj(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"level", "method", "wbits", "memLevel", "strategy", "zdict", NULL}; + int level = Z_DEFAULT_COMPRESSION; + int method = DEFLATED; + int wbits = MAX_WBITS; + int memLevel = DEF_MEM_LEVEL; + int strategy = Z_DEFAULT_STRATEGY; + Py_buffer zdict = {NULL, NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "|iiiiiy*:compressobj", _keywords, + &level, &method, &wbits, &memLevel, &strategy, &zdict)) + goto exit; + return_value = zlib_compressobj_impl(module, level, method, wbits, memLevel, strategy, &zdict); + +exit: + /* Cleanup for zdict */ + if (zdict.obj) + PyBuffer_Release(&zdict); + + return return_value; +} + +PyDoc_STRVAR(zlib_decompressobj__doc__, +"decompressobj($module, /, wbits=MAX_WBITS, zdict=b\'\')\n" +"--\n" +"\n" +"Return a decompressor object.\n" +"\n" +" wbits\n" +" The window buffer size.\n" +" zdict\n" +" The predefined compression dictionary. This must be the same\n" +" dictionary as used by the compressor that produced the input data."); + +#define ZLIB_DECOMPRESSOBJ_METHODDEF \ + {"decompressobj", (PyCFunction)zlib_decompressobj, METH_VARARGS|METH_KEYWORDS, zlib_decompressobj__doc__}, + +static PyObject * +zlib_decompressobj_impl(PyModuleDef *module, int wbits, PyObject *zdict); + +static PyObject * +zlib_decompressobj(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"wbits", "zdict", NULL}; + int wbits = MAX_WBITS; + PyObject *zdict = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "|iO:decompressobj", _keywords, + &wbits, &zdict)) + goto exit; + return_value = zlib_decompressobj_impl(module, wbits, zdict); + +exit: + return return_value; +} + +PyDoc_STRVAR(zlib_Compress_compress__doc__, +"compress($self, data, /)\n" +"--\n" +"\n" +"Returns a bytes object containing compressed data.\n" +"\n" +" data\n" +" Binary data to be compressed.\n" +"\n" +"After calling this function, some of the input data may still\n" +"be stored in internal buffers for later processing.\n" +"Call the flush() method to clear these buffers."); + +#define ZLIB_COMPRESS_COMPRESS_METHODDEF \ + {"compress", (PyCFunction)zlib_Compress_compress, METH_VARARGS, zlib_Compress_compress__doc__}, + +static PyObject * +zlib_Compress_compress_impl(compobject *self, Py_buffer *data); + +static PyObject * +zlib_Compress_compress(compobject *self, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + + if (!PyArg_ParseTuple(args, + "y*:compress", + &data)) + goto exit; + return_value = zlib_Compress_compress_impl(self, &data); + +exit: + /* Cleanup for data */ + if (data.obj) + PyBuffer_Release(&data); + + return return_value; +} + +PyDoc_STRVAR(zlib_Decompress_decompress__doc__, +"decompress($self, data, max_length=0, /)\n" +"--\n" +"\n" +"Return a bytes object containing the decompressed version of the data.\n" +"\n" +" data\n" +" The binary data to decompress.\n" +" max_length\n" +" The maximum allowable length of the decompressed data.\n" +" Unconsumed input data will be stored in\n" +" the unconsumed_tail attribute.\n" +"\n" +"After calling this function, some of the input data may still be stored in\n" +"internal buffers for later processing.\n" +"Call the flush() method to clear these buffers."); + +#define ZLIB_DECOMPRESS_DECOMPRESS_METHODDEF \ + {"decompress", (PyCFunction)zlib_Decompress_decompress, METH_VARARGS, zlib_Decompress_decompress__doc__}, + +static PyObject * +zlib_Decompress_decompress_impl(compobject *self, Py_buffer *data, unsigned int max_length); + +static PyObject * +zlib_Decompress_decompress(compobject *self, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + unsigned int max_length = 0; + + if (!PyArg_ParseTuple(args, + "y*|O&:decompress", + &data, uint_converter, &max_length)) + goto exit; + return_value = zlib_Decompress_decompress_impl(self, &data, max_length); + +exit: + /* Cleanup for data */ + if (data.obj) + PyBuffer_Release(&data); + + return return_value; +} + +PyDoc_STRVAR(zlib_Compress_flush__doc__, +"flush($self, mode=zlib.Z_FINISH, /)\n" +"--\n" +"\n" +"Return a bytes object containing any remaining compressed data.\n" +"\n" +" mode\n" +" One of the constants Z_SYNC_FLUSH, Z_FULL_FLUSH, Z_FINISH.\n" +" If mode == Z_FINISH, the compressor object can no longer be\n" +" used after calling the flush() method. Otherwise, more data\n" +" can still be compressed."); + +#define ZLIB_COMPRESS_FLUSH_METHODDEF \ + {"flush", (PyCFunction)zlib_Compress_flush, METH_VARARGS, zlib_Compress_flush__doc__}, + +static PyObject * +zlib_Compress_flush_impl(compobject *self, int mode); + +static PyObject * +zlib_Compress_flush(compobject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int mode = Z_FINISH; + + if (!PyArg_ParseTuple(args, + "|i:flush", + &mode)) + goto exit; + return_value = zlib_Compress_flush_impl(self, mode); + +exit: + return return_value; +} + +#if defined(HAVE_ZLIB_COPY) + +PyDoc_STRVAR(zlib_Compress_copy__doc__, +"copy($self, /)\n" +"--\n" +"\n" +"Return a copy of the compression object."); + +#define ZLIB_COMPRESS_COPY_METHODDEF \ + {"copy", (PyCFunction)zlib_Compress_copy, METH_NOARGS, zlib_Compress_copy__doc__}, + +static PyObject * +zlib_Compress_copy_impl(compobject *self); + +static PyObject * +zlib_Compress_copy(compobject *self, PyObject *Py_UNUSED(ignored)) +{ + return zlib_Compress_copy_impl(self); +} + +#endif /* defined(HAVE_ZLIB_COPY) */ + +#ifndef ZLIB_COMPRESS_COPY_METHODDEF + #define ZLIB_COMPRESS_COPY_METHODDEF +#endif /* !defined(ZLIB_COMPRESS_COPY_METHODDEF) */ + +#if defined(HAVE_ZLIB_COPY) + +PyDoc_STRVAR(zlib_Decompress_copy__doc__, +"copy($self, /)\n" +"--\n" +"\n" +"Return a copy of the decompression object."); + +#define ZLIB_DECOMPRESS_COPY_METHODDEF \ + {"copy", (PyCFunction)zlib_Decompress_copy, METH_NOARGS, zlib_Decompress_copy__doc__}, + +static PyObject * +zlib_Decompress_copy_impl(compobject *self); + +static PyObject * +zlib_Decompress_copy(compobject *self, PyObject *Py_UNUSED(ignored)) +{ + return zlib_Decompress_copy_impl(self); +} + +#endif /* defined(HAVE_ZLIB_COPY) */ + +#ifndef ZLIB_DECOMPRESS_COPY_METHODDEF + #define ZLIB_DECOMPRESS_COPY_METHODDEF +#endif /* !defined(ZLIB_DECOMPRESS_COPY_METHODDEF) */ + +PyDoc_STRVAR(zlib_Decompress_flush__doc__, +"flush($self, length=zlib.DEF_BUF_SIZE, /)\n" +"--\n" +"\n" +"Return a bytes object containing any remaining decompressed data.\n" +"\n" +" length\n" +" the initial size of the output buffer."); + +#define ZLIB_DECOMPRESS_FLUSH_METHODDEF \ + {"flush", (PyCFunction)zlib_Decompress_flush, METH_VARARGS, zlib_Decompress_flush__doc__}, + +static PyObject * +zlib_Decompress_flush_impl(compobject *self, unsigned int length); + +static PyObject * +zlib_Decompress_flush(compobject *self, PyObject *args) +{ + PyObject *return_value = NULL; + unsigned int length = DEF_BUF_SIZE; + + if (!PyArg_ParseTuple(args, + "|O&:flush", + uint_converter, &length)) + goto exit; + return_value = zlib_Decompress_flush_impl(self, length); + +exit: + return return_value; +} + +PyDoc_STRVAR(zlib_adler32__doc__, +"adler32($module, data, value=1, /)\n" +"--\n" +"\n" +"Compute an Adler-32 checksum of data.\n" +"\n" +" value\n" +" Starting value of the checksum.\n" +"\n" +"The returned checksum is an integer."); + +#define ZLIB_ADLER32_METHODDEF \ + {"adler32", (PyCFunction)zlib_adler32, METH_VARARGS, zlib_adler32__doc__}, + +static PyObject * +zlib_adler32_impl(PyModuleDef *module, Py_buffer *data, unsigned int value); + +static PyObject * +zlib_adler32(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + unsigned int value = 1; + + if (!PyArg_ParseTuple(args, + "y*|I:adler32", + &data, &value)) + goto exit; + return_value = zlib_adler32_impl(module, &data, value); + +exit: + /* Cleanup for data */ + if (data.obj) + PyBuffer_Release(&data); + + return return_value; +} + +PyDoc_STRVAR(zlib_crc32__doc__, +"crc32($module, data, value=0, /)\n" +"--\n" +"\n" +"Compute a CRC-32 checksum of data.\n" +"\n" +" value\n" +" Starting value of the checksum.\n" +"\n" +"The returned checksum is an integer."); + +#define ZLIB_CRC32_METHODDEF \ + {"crc32", (PyCFunction)zlib_crc32, METH_VARARGS, zlib_crc32__doc__}, + +static PyObject * +zlib_crc32_impl(PyModuleDef *module, Py_buffer *data, unsigned int value); + +static PyObject * +zlib_crc32(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + unsigned int value = 0; + + if (!PyArg_ParseTuple(args, + "y*|I:crc32", + &data, &value)) + goto exit; + return_value = zlib_crc32_impl(module, &data, value); + +exit: + /* Cleanup for data */ + if (data.obj) + PyBuffer_Release(&data); + + return return_value; +} +/*[clinic end generated code: output=bc9473721ca7c962 input=a9049054013a1b77]*/ diff --git a/Modules/cmathmodule.c b/Modules/cmathmodule.c index 36bf4a1e3df8..67161adaf5f7 100644 --- a/Modules/cmathmodule.c +++ b/Modules/cmathmodule.c @@ -8,6 +8,41 @@ float.h. We assume that FLT_RADIX is either 2 or 16. */ #include +#include "clinic/cmathmodule.c.h" +/*[clinic input] +output preset file +module cmath +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=ef7e0fdd8a143c03]*/ + +/*[python input] +class Py_complex_protected_converter(Py_complex_converter): + def modify(self): + return 'errno = 0; PyFPE_START_PROTECT("complex function", goto exit);' + + +class Py_complex_protected_return_converter(CReturnConverter): + type = "Py_complex" + + def render(self, function, data): + self.declare(data) + data.return_conversion.append(""" +PyFPE_END_PROTECT(_return_value); +if (errno == EDOM) {{ + PyErr_SetString(PyExc_ValueError, "math domain error"); + goto exit; +}} +else if (errno == ERANGE) {{ + PyErr_SetString(PyExc_OverflowError, "math range error"); + goto exit; +}} +else {{ + return_value = PyComplex_FromCComplex(_return_value); +}} +""".strip()) +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=231019039a6fbb9a]*/ + #if (FLT_RADIX != 2 && FLT_RADIX != 16) #error "Modules/cmathmodule.c expects FLT_RADIX to be 2 or 16" #endif @@ -48,12 +83,12 @@ #define CM_SCALE_DOWN (-(CM_SCALE_UP+1)/2) /* forward declarations */ -static Py_complex c_asinh(Py_complex); -static Py_complex c_atanh(Py_complex); -static Py_complex c_cosh(Py_complex); -static Py_complex c_sinh(Py_complex); -static Py_complex c_sqrt(Py_complex); -static Py_complex c_tanh(Py_complex); +static Py_complex cmath_asinh_impl(PyModuleDef *, Py_complex); +static Py_complex cmath_atanh_impl(PyModuleDef *, Py_complex); +static Py_complex cmath_cosh_impl(PyModuleDef *, Py_complex); +static Py_complex cmath_sinh_impl(PyModuleDef *, Py_complex); +static Py_complex cmath_sqrt_impl(PyModuleDef *, Py_complex); +static Py_complex cmath_tanh_impl(PyModuleDef *, Py_complex); static PyObject * math_error(void); /* Code to deal with special values (infinities, NaNs, etc.). */ @@ -123,8 +158,18 @@ special_type(double d) static Py_complex acos_special_values[7][7]; +/*[clinic input] +cmath.acos -> Py_complex_protected + + z: Py_complex_protected + / + +Return the arc cosine of z. +[clinic start generated code]*/ + static Py_complex -c_acos(Py_complex z) +cmath_acos_impl(PyModuleDef *module, Py_complex z) +/*[clinic end generated code: output=7c1dd21ff818db6b input=bd6cbd78ae851927]*/ { Py_complex s1, s2, r; @@ -145,10 +190,10 @@ c_acos(Py_complex z) } else { s1.real = 1.-z.real; s1.imag = -z.imag; - s1 = c_sqrt(s1); + s1 = cmath_sqrt_impl(module, s1); s2.real = 1.+z.real; s2.imag = z.imag; - s2 = c_sqrt(s2); + s2 = cmath_sqrt_impl(module, s2); r.real = 2.*atan2(s1.real, s2.real); r.imag = m_asinh(s2.real*s1.imag - s2.imag*s1.real); } @@ -156,16 +201,18 @@ c_acos(Py_complex z) return r; } -PyDoc_STRVAR(c_acos_doc, -"acos(x)\n" -"\n" -"Return the arc cosine of x."); - static Py_complex acosh_special_values[7][7]; +/*[clinic input] +cmath.acosh = cmath.acos + +Return the inverse hyperbolic cosine of z. +[clinic start generated code]*/ + static Py_complex -c_acosh(Py_complex z) +cmath_acosh_impl(PyModuleDef *module, Py_complex z) +/*[clinic end generated code: output=c23c776429def981 input=3f61bee7d703e53c]*/ { Py_complex s1, s2, r; @@ -178,10 +225,10 @@ c_acosh(Py_complex z) } else { s1.real = z.real - 1.; s1.imag = z.imag; - s1 = c_sqrt(s1); + s1 = cmath_sqrt_impl(module, s1); s2.real = z.real + 1.; s2.imag = z.imag; - s2 = c_sqrt(s2); + s2 = cmath_sqrt_impl(module, s2); r.real = m_asinh(s1.real*s2.real + s1.imag*s2.imag); r.imag = 2.*atan2(s1.imag, s2.real); } @@ -189,35 +236,38 @@ c_acosh(Py_complex z) return r; } -PyDoc_STRVAR(c_acosh_doc, -"acosh(x)\n" -"\n" -"Return the hyperbolic arccosine of x."); +/*[clinic input] +cmath.asin = cmath.acos +Return the arc sine of z. +[clinic start generated code]*/ static Py_complex -c_asin(Py_complex z) +cmath_asin_impl(PyModuleDef *module, Py_complex z) +/*[clinic end generated code: output=42d2346d46690826 input=be0bf0cfdd5239c5]*/ { /* asin(z) = -i asinh(iz) */ Py_complex s, r; s.real = -z.imag; s.imag = z.real; - s = c_asinh(s); + s = cmath_asinh_impl(module, s); r.real = s.imag; r.imag = -s.real; return r; } -PyDoc_STRVAR(c_asin_doc, -"asin(x)\n" -"\n" -"Return the arc sine of x."); - static Py_complex asinh_special_values[7][7]; +/*[clinic input] +cmath.asinh = cmath.acos + +Return the inverse hyperbolic sine of z. +[clinic start generated code]*/ + static Py_complex -c_asinh(Py_complex z) +cmath_asinh_impl(PyModuleDef *module, Py_complex z) +/*[clinic end generated code: output=0c6664823c7b1b35 input=5c09448fcfc89a79]*/ { Py_complex s1, s2, r; @@ -235,10 +285,10 @@ c_asinh(Py_complex z) } else { s1.real = 1.+z.imag; s1.imag = -z.real; - s1 = c_sqrt(s1); + s1 = cmath_sqrt_impl(module, s1); s2.real = 1.-z.imag; s2.imag = z.real; - s2 = c_sqrt(s2); + s2 = cmath_sqrt_impl(module, s2); r.real = m_asinh(s1.real*s2.imag-s2.real*s1.imag); r.imag = atan2(z.imag, s1.real*s2.real-s1.imag*s2.imag); } @@ -246,20 +296,22 @@ c_asinh(Py_complex z) return r; } -PyDoc_STRVAR(c_asinh_doc, -"asinh(x)\n" -"\n" -"Return the hyperbolic arc sine of x."); +/*[clinic input] +cmath.atan = cmath.acos + +Return the arc tangent of z. +[clinic start generated code]*/ static Py_complex -c_atan(Py_complex z) +cmath_atan_impl(PyModuleDef *module, Py_complex z) +/*[clinic end generated code: output=b7d44f02c6a5c3b5 input=3b21ff7d5eac632a]*/ { /* atan(z) = -i atanh(iz) */ Py_complex s, r; s.real = -z.imag; s.imag = z.real; - s = c_atanh(s); + s = cmath_atanh_impl(module, s); r.real = s.imag; r.imag = -s.real; return r; @@ -295,16 +347,18 @@ c_atan2(Py_complex z) return atan2(z.imag, z.real); } -PyDoc_STRVAR(c_atan_doc, -"atan(x)\n" -"\n" -"Return the arc tangent of x."); - static Py_complex atanh_special_values[7][7]; +/*[clinic input] +cmath.atanh = cmath.acos + +Return the inverse hyperbolic tangent of z. +[clinic start generated code]*/ + static Py_complex -c_atanh(Py_complex z) +cmath_atanh_impl(PyModuleDef *module, Py_complex z) +/*[clinic end generated code: output=279e0b9fefc8da7c input=2b3fdb82fb34487b]*/ { Py_complex r; double ay, h; @@ -313,7 +367,7 @@ c_atanh(Py_complex z) /* Reduce to case where z.real >= 0., using atanh(z) = -atanh(-z). */ if (z.real < 0.) { - return c_neg(c_atanh(c_neg(z))); + return _Py_c_neg(cmath_atanh_impl(module, _Py_c_neg(z))); } ay = fabs(z.imag); @@ -350,34 +404,38 @@ c_atanh(Py_complex z) return r; } -PyDoc_STRVAR(c_atanh_doc, -"atanh(x)\n" -"\n" -"Return the hyperbolic arc tangent of x."); +/*[clinic input] +cmath.cos = cmath.acos + +Return the cosine of z. +[clinic start generated code]*/ static Py_complex -c_cos(Py_complex z) +cmath_cos_impl(PyModuleDef *module, Py_complex z) +/*[clinic end generated code: output=9d1cdc1b5e761667 input=6022e39b77127ac7]*/ { /* cos(z) = cosh(iz) */ Py_complex r; r.real = -z.imag; r.imag = z.real; - r = c_cosh(r); + r = cmath_cosh_impl(module, r); return r; } -PyDoc_STRVAR(c_cos_doc, -"cos(x)\n" -"\n" -"Return the cosine of x."); - /* cosh(infinity + i*y) needs to be dealt with specially */ static Py_complex cosh_special_values[7][7]; +/*[clinic input] +cmath.cosh = cmath.acos + +Return the hyperbolic cosine of z. +[clinic start generated code]*/ + static Py_complex -c_cosh(Py_complex z) +cmath_cosh_impl(PyModuleDef *module, Py_complex z) +/*[clinic end generated code: output=f3b5d3282b3024d3 input=d6b66339e9cc332b]*/ { Py_complex r; double x_minus_one; @@ -426,18 +484,20 @@ c_cosh(Py_complex z) return r; } -PyDoc_STRVAR(c_cosh_doc, -"cosh(x)\n" -"\n" -"Return the hyperbolic cosine of x."); - /* exp(infinity + i*y) and exp(-infinity + i*y) need special treatment for finite y */ static Py_complex exp_special_values[7][7]; +/*[clinic input] +cmath.exp = cmath.acos + +Return the exponential value e**z. +[clinic start generated code]*/ + static Py_complex -c_exp(Py_complex z) +cmath_exp_impl(PyModuleDef *module, Py_complex z) +/*[clinic end generated code: output=6f8825eb2bcad9ba input=8b9e6cf8a92174c3]*/ { Py_complex r; double l; @@ -486,12 +546,6 @@ c_exp(Py_complex z) return r; } -PyDoc_STRVAR(c_exp_doc, -"exp(x)\n" -"\n" -"Return the exponential value e**x."); - - static Py_complex log_special_values[7][7]; static Py_complex @@ -564,8 +618,15 @@ c_log(Py_complex z) } +/*[clinic input] +cmath.log10 = cmath.acos + +Return the base-10 logarithm of z. +[clinic start generated code]*/ + static Py_complex -c_log10(Py_complex z) +cmath_log10_impl(PyModuleDef *module, Py_complex z) +/*[clinic end generated code: output=c7c426ca0e782341 input=cff5644f73c1519c]*/ { Py_complex r; int errno_save; @@ -578,36 +639,40 @@ c_log10(Py_complex z) return r; } -PyDoc_STRVAR(c_log10_doc, -"log10(x)\n" -"\n" -"Return the base-10 logarithm of x."); +/*[clinic input] +cmath.sin = cmath.acos + +Return the sine of z. +[clinic start generated code]*/ static Py_complex -c_sin(Py_complex z) +cmath_sin_impl(PyModuleDef *module, Py_complex z) +/*[clinic end generated code: output=e7f5e2b253825ac7 input=2d3519842a8b4b85]*/ { /* sin(z) = -i sin(iz) */ Py_complex s, r; s.real = -z.imag; s.imag = z.real; - s = c_sinh(s); + s = cmath_sinh_impl(module, s); r.real = s.imag; r.imag = -s.real; return r; } -PyDoc_STRVAR(c_sin_doc, -"sin(x)\n" -"\n" -"Return the sine of x."); - /* sinh(infinity + i*y) needs to be dealt with specially */ static Py_complex sinh_special_values[7][7]; +/*[clinic input] +cmath.sinh = cmath.acos + +Return the hyperbolic sine of z. +[clinic start generated code]*/ + static Py_complex -c_sinh(Py_complex z) +cmath_sinh_impl(PyModuleDef *module, Py_complex z) +/*[clinic end generated code: output=d71fff8298043a95 input=d2d3fc8c1ddfd2dd]*/ { Py_complex r; double x_minus_one; @@ -655,16 +720,18 @@ c_sinh(Py_complex z) return r; } -PyDoc_STRVAR(c_sinh_doc, -"sinh(x)\n" -"\n" -"Return the hyperbolic sine of x."); - static Py_complex sqrt_special_values[7][7]; +/*[clinic input] +cmath.sqrt = cmath.acos + +Return the square root of z. +[clinic start generated code]*/ + static Py_complex -c_sqrt(Py_complex z) +cmath_sqrt_impl(PyModuleDef *module, Py_complex z) +/*[clinic end generated code: output=b6bda283d0c5a7b4 input=7088b166fc9a58c7]*/ { /* Method: use symmetries to reduce to the case when x = z.real and y @@ -730,36 +797,40 @@ c_sqrt(Py_complex z) return r; } -PyDoc_STRVAR(c_sqrt_doc, -"sqrt(x)\n" -"\n" -"Return the square root of x."); +/*[clinic input] +cmath.tan = cmath.acos + +Return the tangent of z. +[clinic start generated code]*/ static Py_complex -c_tan(Py_complex z) +cmath_tan_impl(PyModuleDef *module, Py_complex z) +/*[clinic end generated code: output=df374bacf36d99b4 input=fc167e528767888e]*/ { /* tan(z) = -i tanh(iz) */ Py_complex s, r; s.real = -z.imag; s.imag = z.real; - s = c_tanh(s); + s = cmath_tanh_impl(module, s); r.real = s.imag; r.imag = -s.real; return r; } -PyDoc_STRVAR(c_tan_doc, -"tan(x)\n" -"\n" -"Return the tangent of x."); - /* tanh(infinity + i*y) needs to be dealt with specially */ static Py_complex tanh_special_values[7][7]; +/*[clinic input] +cmath.tanh = cmath.acos + +Return the hyperbolic tangent of z. +[clinic start generated code]*/ + static Py_complex -c_tanh(Py_complex z) +cmath_tanh_impl(PyModuleDef *module, Py_complex z) +/*[clinic end generated code: output=f578773d27a18e96 input=22f67f9dc6d29685]*/ { /* Formula: @@ -822,27 +893,35 @@ c_tanh(Py_complex z) return r; } -PyDoc_STRVAR(c_tanh_doc, -"tanh(x)\n" -"\n" -"Return the hyperbolic tangent of x."); +/*[clinic input] +cmath.log + + x: Py_complex + y_obj: object = NULL + / + +The logarithm of z to the given base. + +If the base not specified, returns the natural logarithm (base e) of z. +[clinic start generated code]*/ static PyObject * -cmath_log(PyObject *self, PyObject *args) +cmath_log_impl(PyModuleDef *module, Py_complex x, PyObject *y_obj) +/*[clinic end generated code: output=35e2a1e5229b5a46 input=ee0e823a7c6e68ea]*/ { - Py_complex x; Py_complex y; - if (!PyArg_ParseTuple(args, "D|D", &x, &y)) - return NULL; - errno = 0; PyFPE_START_PROTECT("complex function", return 0) x = c_log(x); - if (PyTuple_GET_SIZE(args) == 2) { + if (y_obj != NULL) { + y = PyComplex_AsCComplex(y_obj); + if (PyErr_Occurred()) { + return NULL; + } y = c_log(y); - x = c_quot(x, y); + x = _Py_c_quot(x, y); } PyFPE_END_PROTECT(x) if (errno != 0) @@ -850,10 +929,6 @@ cmath_log(PyObject *self, PyObject *args) return PyComplex_FromCComplex(x); } -PyDoc_STRVAR(cmath_log_doc, -"log(x[, base]) -> the logarithm of x to the given base.\n\ -If the base not specified, returns the natural logarithm (base e) of x."); - /* And now the glue to make them available from Python: */ @@ -869,57 +944,22 @@ math_error(void) return NULL; } -static PyObject * -math_1(PyObject *args, Py_complex (*func)(Py_complex)) -{ - Py_complex x,r ; - if (!PyArg_ParseTuple(args, "D", &x)) - return NULL; - errno = 0; - PyFPE_START_PROTECT("complex function", return 0); - r = (*func)(x); - PyFPE_END_PROTECT(r); - if (errno == EDOM) { - PyErr_SetString(PyExc_ValueError, "math domain error"); - return NULL; - } - else if (errno == ERANGE) { - PyErr_SetString(PyExc_OverflowError, "math range error"); - return NULL; - } - else { - return PyComplex_FromCComplex(r); - } -} -#define FUNC1(stubname, func) \ - static PyObject * stubname(PyObject *self, PyObject *args) { \ - return math_1(args, func); \ - } +/*[clinic input] +cmath.phase + + z: Py_complex + / -FUNC1(cmath_acos, c_acos) -FUNC1(cmath_acosh, c_acosh) -FUNC1(cmath_asin, c_asin) -FUNC1(cmath_asinh, c_asinh) -FUNC1(cmath_atan, c_atan) -FUNC1(cmath_atanh, c_atanh) -FUNC1(cmath_cos, c_cos) -FUNC1(cmath_cosh, c_cosh) -FUNC1(cmath_exp, c_exp) -FUNC1(cmath_log10, c_log10) -FUNC1(cmath_sin, c_sin) -FUNC1(cmath_sinh, c_sinh) -FUNC1(cmath_sqrt, c_sqrt) -FUNC1(cmath_tan, c_tan) -FUNC1(cmath_tanh, c_tanh) +Return argument, also known as the phase angle, of a complex. +[clinic start generated code]*/ static PyObject * -cmath_phase(PyObject *self, PyObject *args) +cmath_phase_impl(PyModuleDef *module, Py_complex z) +/*[clinic end generated code: output=e09eaf373cb624c3 input=5cf75228ba94b69d]*/ { - Py_complex z; double phi; - if (!PyArg_ParseTuple(args, "D:phase", &z)) - return NULL; + errno = 0; PyFPE_START_PROTECT("arg function", return 0) phi = c_atan2(z); @@ -930,20 +970,26 @@ cmath_phase(PyObject *self, PyObject *args) return PyFloat_FromDouble(phi); } -PyDoc_STRVAR(cmath_phase_doc, -"phase(z) -> float\n\n\ -Return argument, also known as the phase angle, of a complex."); +/*[clinic input] +cmath.polar + + z: Py_complex + / + +Convert a complex from rectangular coordinates to polar coordinates. + +r is the distance from 0 and phi the phase angle. +[clinic start generated code]*/ static PyObject * -cmath_polar(PyObject *self, PyObject *args) +cmath_polar_impl(PyModuleDef *module, Py_complex z) +/*[clinic end generated code: output=07d41b16c877875a input=26c353574fd1a861]*/ { - Py_complex z; double r, phi; - if (!PyArg_ParseTuple(args, "D:polar", &z)) - return NULL; + PyFPE_START_PROTECT("polar function", return 0) phi = c_atan2(z); /* should not cause any exception */ - r = c_abs(z); /* sets errno to ERANGE on overflow; otherwise 0 */ + r = _Py_c_abs(z); /* sets errno to ERANGE on overflow; otherwise 0 */ PyFPE_END_PROTECT(r) if (errno != 0) return math_error(); @@ -951,11 +997,6 @@ cmath_polar(PyObject *self, PyObject *args) return Py_BuildValue("dd", r, phi); } -PyDoc_STRVAR(cmath_polar_doc, -"polar(z) -> r: float, phi: float\n\n\ -Convert a complex from rectangular coordinates to polar coordinates. r is\n\ -the distance from 0 and phi the phase angle."); - /* rect() isn't covered by the C99 standard, but it's not too hard to figure out 'spirit of C99' rules for special value handing: @@ -969,13 +1010,21 @@ the distance from 0 and phi the phase angle."); static Py_complex rect_special_values[7][7]; +/*[clinic input] +cmath.rect + + r: double + phi: double + / + +Convert from polar coordinates to rectangular coordinates. +[clinic start generated code]*/ + static PyObject * -cmath_rect(PyObject *self, PyObject *args) +cmath_rect_impl(PyModuleDef *module, double r, double phi) +/*[clinic end generated code: output=d97a8749bd63e9d5 input=24c5646d147efd69]*/ { Py_complex z; - double r, phi; - if (!PyArg_ParseTuple(args, "dd:rect", &r, &phi)) - return NULL; errno = 0; PyFPE_START_PROTECT("rect function", return 0) @@ -1026,79 +1075,75 @@ cmath_rect(PyObject *self, PyObject *args) return PyComplex_FromCComplex(z); } -PyDoc_STRVAR(cmath_rect_doc, -"rect(r, phi) -> z: complex\n\n\ -Convert from polar coordinates to rectangular coordinates."); +/*[clinic input] +cmath.isfinite = cmath.polar + +Return True if both the real and imaginary parts of z are finite, else False. +[clinic start generated code]*/ static PyObject * -cmath_isfinite(PyObject *self, PyObject *args) +cmath_isfinite_impl(PyModuleDef *module, Py_complex z) +/*[clinic end generated code: output=8f6682fa93de45d6 input=848e7ee701895815]*/ { - Py_complex z; - if (!PyArg_ParseTuple(args, "D:isfinite", &z)) - return NULL; return PyBool_FromLong(Py_IS_FINITE(z.real) && Py_IS_FINITE(z.imag)); } -PyDoc_STRVAR(cmath_isfinite_doc, -"isfinite(z) -> bool\n\ -Return True if both the real and imaginary parts of z are finite, else False."); +/*[clinic input] +cmath.isnan = cmath.polar + +Checks if the real or imaginary part of z not a number (NaN). +[clinic start generated code]*/ static PyObject * -cmath_isnan(PyObject *self, PyObject *args) +cmath_isnan_impl(PyModuleDef *module, Py_complex z) +/*[clinic end generated code: output=b85fe8c2047718ee input=71799f5d284c9baf]*/ { - Py_complex z; - if (!PyArg_ParseTuple(args, "D:isnan", &z)) - return NULL; return PyBool_FromLong(Py_IS_NAN(z.real) || Py_IS_NAN(z.imag)); } -PyDoc_STRVAR(cmath_isnan_doc, -"isnan(z) -> bool\n\ -Checks if the real or imaginary part of z not a number (NaN)"); +/*[clinic input] +cmath.isinf = cmath.polar + +Checks if the real or imaginary part of z is infinite. +[clinic start generated code]*/ static PyObject * -cmath_isinf(PyObject *self, PyObject *args) +cmath_isinf_impl(PyModuleDef *module, Py_complex z) +/*[clinic end generated code: output=8ca9c6109e468bf4 input=363df155c7181329]*/ { - Py_complex z; - if (!PyArg_ParseTuple(args, "D:isnan", &z)) - return NULL; return PyBool_FromLong(Py_IS_INFINITY(z.real) || Py_IS_INFINITY(z.imag)); } -PyDoc_STRVAR(cmath_isinf_doc, -"isinf(z) -> bool\n\ -Checks if the real or imaginary part of z is infinite."); - PyDoc_STRVAR(module_doc, "This module is always available. It provides access to mathematical\n" "functions for complex numbers."); static PyMethodDef cmath_methods[] = { - {"acos", cmath_acos, METH_VARARGS, c_acos_doc}, - {"acosh", cmath_acosh, METH_VARARGS, c_acosh_doc}, - {"asin", cmath_asin, METH_VARARGS, c_asin_doc}, - {"asinh", cmath_asinh, METH_VARARGS, c_asinh_doc}, - {"atan", cmath_atan, METH_VARARGS, c_atan_doc}, - {"atanh", cmath_atanh, METH_VARARGS, c_atanh_doc}, - {"cos", cmath_cos, METH_VARARGS, c_cos_doc}, - {"cosh", cmath_cosh, METH_VARARGS, c_cosh_doc}, - {"exp", cmath_exp, METH_VARARGS, c_exp_doc}, - {"isfinite", cmath_isfinite, METH_VARARGS, cmath_isfinite_doc}, - {"isinf", cmath_isinf, METH_VARARGS, cmath_isinf_doc}, - {"isnan", cmath_isnan, METH_VARARGS, cmath_isnan_doc}, - {"log", cmath_log, METH_VARARGS, cmath_log_doc}, - {"log10", cmath_log10, METH_VARARGS, c_log10_doc}, - {"phase", cmath_phase, METH_VARARGS, cmath_phase_doc}, - {"polar", cmath_polar, METH_VARARGS, cmath_polar_doc}, - {"rect", cmath_rect, METH_VARARGS, cmath_rect_doc}, - {"sin", cmath_sin, METH_VARARGS, c_sin_doc}, - {"sinh", cmath_sinh, METH_VARARGS, c_sinh_doc}, - {"sqrt", cmath_sqrt, METH_VARARGS, c_sqrt_doc}, - {"tan", cmath_tan, METH_VARARGS, c_tan_doc}, - {"tanh", cmath_tanh, METH_VARARGS, c_tanh_doc}, - {NULL, NULL} /* sentinel */ + CMATH_ACOS_METHODDEF + CMATH_ACOSH_METHODDEF + CMATH_ASIN_METHODDEF + CMATH_ASINH_METHODDEF + CMATH_ATAN_METHODDEF + CMATH_ATANH_METHODDEF + CMATH_COS_METHODDEF + CMATH_COSH_METHODDEF + CMATH_EXP_METHODDEF + CMATH_ISFINITE_METHODDEF + CMATH_ISINF_METHODDEF + CMATH_ISNAN_METHODDEF + CMATH_LOG_METHODDEF + CMATH_LOG10_METHODDEF + CMATH_PHASE_METHODDEF + CMATH_POLAR_METHODDEF + CMATH_RECT_METHODDEF + CMATH_SIN_METHODDEF + CMATH_SINH_METHODDEF + CMATH_SQRT_METHODDEF + CMATH_TAN_METHODDEF + CMATH_TANH_METHODDEF + {NULL, NULL} /* sentinel */ }; diff --git a/Modules/expat/expat_external.h b/Modules/expat/expat_external.h index 2c03284ea265..f337e1c5622a 100644 --- a/Modules/expat/expat_external.h +++ b/Modules/expat/expat_external.h @@ -7,6 +7,10 @@ /* External API definitions */ +/* Namespace external symbols to allow multiple libexpat version to + co-exist. */ +#include "pyexpatns.h" + #if defined(_MSC_EXTENSIONS) && !defined(__BEOS__) && !defined(__CYGWIN__) #define XML_USE_MSC_EXTENSIONS 1 #endif diff --git a/Modules/expat/xmlparse.c b/Modules/expat/xmlparse.c index f35aa36ba8a7..0ac0317b8e14 100644 --- a/Modules/expat/xmlparse.c +++ b/Modules/expat/xmlparse.c @@ -2,12 +2,6 @@ See the file COPYING for copying permission. */ -#include -#include /* memset(), memcpy() */ -#include -#include /* UINT_MAX */ -#include /* time() */ - #define XML_BUILDING_EXPAT 1 #ifdef COMPILED_FROM_DSP @@ -22,6 +16,12 @@ #include #endif /* ndef COMPILED_FROM_DSP */ +#include +#include /* memset(), memcpy() */ +#include +#include /* UINT_MAX */ +#include /* time() */ + #include "ascii.h" #include "expat.h" diff --git a/Modules/expat/xmlrole.c b/Modules/expat/xmlrole.c index 44772e21dd33..9a8f85dd2535 100644 --- a/Modules/expat/xmlrole.c +++ b/Modules/expat/xmlrole.c @@ -2,8 +2,6 @@ See the file COPYING for copying permission. */ -#include - #ifdef COMPILED_FROM_DSP #include "winconfig.h" #elif defined(MACOS_CLASSIC) @@ -18,6 +16,8 @@ #endif #endif /* ndef COMPILED_FROM_DSP */ +#include + #include "expat_external.h" #include "internal.h" #include "xmlrole.h" diff --git a/Modules/expat/xmltok.c b/Modules/expat/xmltok.c index b9cd7a451300..fd6bf7a3d18d 100644 --- a/Modules/expat/xmltok.c +++ b/Modules/expat/xmltok.c @@ -2,8 +2,6 @@ See the file COPYING for copying permission. */ -#include - #ifdef COMPILED_FROM_DSP #include "winconfig.h" #elif defined(MACOS_CLASSIC) @@ -18,6 +16,8 @@ #endif #endif /* ndef COMPILED_FROM_DSP */ +#include + #include "expat_external.h" #include "internal.h" #include "xmltok.h" diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c index 27b1d54c60cc..4643c0ede53c 100644 --- a/Modules/faulthandler.c +++ b/Modules/faulthandler.c @@ -5,7 +5,13 @@ #include #include #if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK) -#include +# include +#endif +#ifdef MS_WINDOWS +# include +#endif +#ifdef HAVE_SYS_RESOURCE_H +# include #endif /* Allocate at maximum 100 MB of the stack to raise the stack overflow */ @@ -144,6 +150,10 @@ faulthandler_get_fileno(PyObject *file, int *p_fd) PyErr_SetString(PyExc_RuntimeError, "unable to get sys.stderr"); return NULL; } + if (file == Py_None) { + PyErr_SetString(PyExc_RuntimeError, "sys.stderr is None"); + return NULL; + } } result = _PyObject_CallMethodId(file, &PyId_fileno, ""); @@ -303,7 +313,7 @@ faulthandler_fatal_error(int signum) return; } #endif - /* call the previous signal handler: it is called immediatly if we use + /* call the previous signal handler: it is called immediately if we use sigaction() thanks to SA_NODEFER flag, otherwise it is deferred */ raise(signum); } @@ -448,7 +458,7 @@ faulthandler_thread(void *unused) assert(st == PY_LOCK_FAILURE); /* get the thread holding the GIL, NULL if no thread hold the GIL */ - current = _Py_atomic_load_relaxed(&_PyThreadState_Current); + current = (PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current); write(thread.fd, thread.header, (int)thread.header_len); @@ -800,29 +810,51 @@ faulthandler_unregister_py(PyObject *self, PyObject *args) #endif /* FAULTHANDLER_USER */ +static void +faulthandler_suppress_crash_report(void) +{ +#ifdef MS_WINDOWS + UINT mode; + + /* Configure Windows to not display the Windows Error Reporting dialog */ + mode = SetErrorMode(SEM_NOGPFAULTERRORBOX); + SetErrorMode(mode | SEM_NOGPFAULTERRORBOX); +#endif + +#ifdef HAVE_SYS_RESOURCE_H + struct rlimit rl; + + /* Disable creation of core dump */ + if (getrlimit(RLIMIT_CORE, &rl) != 0) { + rl.rlim_cur = 0; + setrlimit(RLIMIT_CORE, &rl); + } +#endif + +#ifdef _MSC_VER + /* Visual Studio: configure abort() to not display an error message nor + open a popup asking to report the fault. */ + _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); +#endif +} + static PyObject * faulthandler_read_null(PyObject *self, PyObject *args) { volatile int *x; volatile int y; - int release_gil = 0; - if (!PyArg_ParseTuple(args, "|i:_read_null", &release_gil)) - return NULL; + faulthandler_suppress_crash_report(); x = NULL; - if (release_gil) { - Py_BEGIN_ALLOW_THREADS - y = *x; - Py_END_ALLOW_THREADS - } else - y = *x; + y = *x; return PyLong_FromLong(y); } -static PyObject * -faulthandler_sigsegv(PyObject *self, PyObject *args) +static void +faulthandler_raise_sigsegv(void) { + faulthandler_suppress_crash_report(); #if defined(MS_WINDOWS) /* For SIGSEGV, faulthandler_fatal_error() restores the previous signal handler and then gives back the execution flow to the program (without @@ -840,6 +872,22 @@ faulthandler_sigsegv(PyObject *self, PyObject *args) #else raise(SIGSEGV); #endif +} + +static PyObject * +faulthandler_sigsegv(PyObject *self, PyObject *args) +{ + int release_gil = 0; + if (!PyArg_ParseTuple(args, "|i:_read_null", &release_gil)) + return NULL; + + if (release_gil) { + Py_BEGIN_ALLOW_THREADS + faulthandler_raise_sigsegv(); + Py_END_ALLOW_THREADS + } else { + faulthandler_raise_sigsegv(); + } Py_RETURN_NONE; } @@ -849,6 +897,7 @@ faulthandler_sigfpe(PyObject *self, PyObject *args) /* Do an integer division by zero: raise a SIGFPE on Intel CPU, but not on PowerPC. Use volatile to disable compile-time optimizations. */ volatile int x = 1, y = 0, z; + faulthandler_suppress_crash_report(); z = x / y; /* If the division by zero didn't raise a SIGFPE (e.g. on PowerPC), raise it manually. */ @@ -861,50 +910,29 @@ faulthandler_sigfpe(PyObject *self, PyObject *args) static PyObject * faulthandler_sigabrt(PyObject *self, PyObject *args) { -#ifdef _MSC_VER - /* Visual Studio: configure abort() to not display an error message nor - open a popup asking to report the fault. */ - _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); -#endif + faulthandler_suppress_crash_report(); abort(); Py_RETURN_NONE; } -#ifdef SIGBUS -static PyObject * -faulthandler_sigbus(PyObject *self, PyObject *args) -{ - raise(SIGBUS); - Py_RETURN_NONE; -} -#endif - -#ifdef SIGILL -static PyObject * -faulthandler_sigill(PyObject *self, PyObject *args) -{ - raise(SIGILL); - Py_RETURN_NONE; -} -#endif - static PyObject * faulthandler_fatal_error_py(PyObject *self, PyObject *args) { char *message; if (!PyArg_ParseTuple(args, "y:fatal_error", &message)) return NULL; + faulthandler_suppress_crash_report(); Py_FatalError(message); Py_RETURN_NONE; } #if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION) -static void* -stack_overflow(void *min_sp, void *max_sp, size_t *depth) +static Py_uintptr_t +stack_overflow(Py_uintptr_t min_sp, Py_uintptr_t max_sp, size_t *depth) { /* allocate 4096 bytes on the stack at each call */ unsigned char buffer[4096]; - void *sp = &buffer; + Py_uintptr_t sp = (Py_uintptr_t)&buffer; *depth += 1; if (sp < min_sp || max_sp < sp) return sp; @@ -917,8 +945,10 @@ static PyObject * faulthandler_stack_overflow(PyObject *self) { size_t depth, size; - char *sp = (char *)&depth, *stop; + Py_uintptr_t sp = (Py_uintptr_t)&depth; + Py_uintptr_t stop; + faulthandler_suppress_crash_report(); depth = 0; stop = stack_overflow(sp - STACK_OVERFLOW_MAX_SIZE, sp + STACK_OVERFLOW_MAX_SIZE, @@ -999,23 +1029,15 @@ static PyMethodDef module_methods[] = { "'signum' registered by register()")}, #endif - {"_read_null", faulthandler_read_null, METH_VARARGS, - PyDoc_STR("_read_null(release_gil=False): read from NULL, raise " + {"_read_null", faulthandler_read_null, METH_NOARGS, + PyDoc_STR("_read_null(): read from NULL, raise " "a SIGSEGV or SIGBUS signal depending on the platform")}, {"_sigsegv", faulthandler_sigsegv, METH_VARARGS, - PyDoc_STR("_sigsegv(): raise a SIGSEGV signal")}, - {"_sigabrt", faulthandler_sigabrt, METH_VARARGS, + PyDoc_STR("_sigsegv(release_gil=False): raise a SIGSEGV signal")}, + {"_sigabrt", faulthandler_sigabrt, METH_NOARGS, PyDoc_STR("_sigabrt(): raise a SIGABRT signal")}, {"_sigfpe", (PyCFunction)faulthandler_sigfpe, METH_NOARGS, PyDoc_STR("_sigfpe(): raise a SIGFPE signal")}, -#ifdef SIGBUS - {"_sigbus", (PyCFunction)faulthandler_sigbus, METH_NOARGS, - PyDoc_STR("_sigbus(): raise a SIGBUS signal")}, -#endif -#ifdef SIGILL - {"_sigill", (PyCFunction)faulthandler_sigill, METH_NOARGS, - PyDoc_STR("_sigill(): raise a SIGILL signal")}, -#endif {"_fatal_error", faulthandler_fatal_error_py, METH_VARARGS, PyDoc_STR("_fatal_error(message): call Py_FatalError(message)")}, #if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION) diff --git a/Modules/fcntlmodule.c b/Modules/fcntlmodule.c index 79d292f1ae44..780e2222c565 100644 --- a/Modules/fcntlmodule.c +++ b/Modules/fcntlmodule.c @@ -15,6 +15,12 @@ #include #endif +/*[clinic input] +output preset file +module fcntl +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=c7356fdb126a904a]*/ + static int conv_descriptor(PyObject *object, int *target) { @@ -26,48 +32,72 @@ conv_descriptor(PyObject *object, int *target) return 1; } +/* Must come after conv_descriptor definition. */ +#include "clinic/fcntlmodule.c.h" + +/*[clinic input] +fcntl.fcntl + + fd: object(type='int', converter='conv_descriptor') + code: int + arg: object = NULL + / -/* fcntl(fd, op, [arg]) */ +Perform the operation `code` on file descriptor fd. + +The values used for `code` are operating system dependent, and are available +as constants in the fcntl module, using the same names as used in +the relevant C header files. The argument arg is optional, and +defaults to 0; it may be an int or a string. If arg is given as a string, +the return value of fcntl is a string of that length, containing the +resulting value put in the arg buffer by the operating system. The length +of the arg string is not allowed to exceed 1024 bytes. If the arg given +is an integer or if none is specified, the result value is an integer +corresponding to the return value of the fcntl call in the C code. +[clinic start generated code]*/ static PyObject * -fcntl_fcntl(PyObject *self, PyObject *args) +fcntl_fcntl_impl(PyModuleDef *module, int fd, int code, PyObject *arg) +/*[clinic end generated code: output=afc5bfa74a03ef0d input=4850c13a41e86930]*/ { - int fd; - int code; - long arg; + unsigned int int_arg = 0; int ret; char *str; Py_ssize_t len; char buf[1024]; - if (PyArg_ParseTuple(args, "O&is#:fcntl", - conv_descriptor, &fd, &code, &str, &len)) { - if (len > sizeof buf) { - PyErr_SetString(PyExc_ValueError, - "fcntl string arg too long"); - return NULL; + if (arg != NULL) { + int parse_result; + + if (PyArg_Parse(arg, "s#", &str, &len)) { + if ((size_t)len > sizeof buf) { + PyErr_SetString(PyExc_ValueError, + "fcntl string arg too long"); + return NULL; + } + memcpy(buf, str, len); + Py_BEGIN_ALLOW_THREADS + ret = fcntl(fd, code, buf); + Py_END_ALLOW_THREADS + if (ret < 0) { + PyErr_SetFromErrno(PyExc_IOError); + return NULL; + } + return PyBytes_FromStringAndSize(buf, len); } - memcpy(buf, str, len); - Py_BEGIN_ALLOW_THREADS - ret = fcntl(fd, code, buf); - Py_END_ALLOW_THREADS - if (ret < 0) { - PyErr_SetFromErrno(PyExc_IOError); - return NULL; + + PyErr_Clear(); + parse_result = PyArg_Parse(arg, + "I;fcntl requires a file or file descriptor," + " an integer and optionally a third integer or a string", + &int_arg); + if (!parse_result) { + return NULL; } - return PyBytes_FromStringAndSize(buf, len); } - PyErr_Clear(); - arg = 0; - if (!PyArg_ParseTuple(args, - "O&i|l;fcntl requires a file or file descriptor," - " an integer and optionally a third integer or a string", - conv_descriptor, &fd, &code, &arg)) { - return NULL; - } Py_BEGIN_ALLOW_THREADS - ret = fcntl(fd, code, arg); + ret = fcntl(fd, code, (int)int_arg); Py_END_ALLOW_THREADS if (ret < 0) { PyErr_SetFromErrno(PyExc_IOError); @@ -76,33 +106,54 @@ fcntl_fcntl(PyObject *self, PyObject *args) return PyLong_FromLong((long)ret); } -PyDoc_STRVAR(fcntl_doc, -"fcntl(fd, op, [arg])\n\ -\n\ -Perform the operation op on file descriptor fd. The values used\n\ -for op are operating system dependent, and are available\n\ -as constants in the fcntl module, using the same names as used in\n\ -the relevant C header files. The argument arg is optional, and\n\ -defaults to 0; it may be an int or a string. If arg is given as a string,\n\ -the return value of fcntl is a string of that length, containing the\n\ -resulting value put in the arg buffer by the operating system. The length\n\ -of the arg string is not allowed to exceed 1024 bytes. If the arg given\n\ -is an integer or if none is specified, the result value is an integer\n\ -corresponding to the return value of the fcntl call in the C code."); +/*[clinic input] +fcntl.ioctl + + fd: object(type='int', converter='conv_descriptor') + op as code: unsigned_int(bitwise=True) + arg as ob_arg: object = NULL + mutate_flag as mutate_arg: bool = True + / + +Perform the operation op on file descriptor fd. -/* ioctl(fd, op, [arg]) */ +The values used for op are operating system dependent, and are available as +constants in the fcntl or termios library modules, using the same names as +used in the relevant C header files. + +The argument `arg` is optional, and defaults to 0; it may be an int or a +buffer containing character data (most likely a string or an array). + +If the argument is a mutable buffer (such as an array) and if the +mutate_flag argument (which is only allowed in this case) is true then the +buffer is (in effect) passed to the operating system and changes made by +the OS will be reflected in the contents of the buffer after the call has +returned. The return value is the integer returned by the ioctl system +call. + +If the argument is a mutable buffer and the mutable_flag argument is not +passed or is false, the behavior is as if a string had been passed. This +behavior will change in future releases of Python. + +If the argument is an immutable buffer (most likely a string) then a copy +of the buffer is passed to the operating system and the return value is a +string of the same length containing whatever the operating system put in +the buffer. The length of the arg buffer in this case is not allowed to +exceed 1024 bytes. + +If the arg given is an integer or if none is specified, the result value is +an integer corresponding to the return value of the ioctl call in the C +code. +[clinic start generated code]*/ static PyObject * -fcntl_ioctl(PyObject *self, PyObject *args) +fcntl_ioctl_impl(PyModuleDef *module, int fd, unsigned int code, PyObject *ob_arg, int mutate_arg) +/*[clinic end generated code: output=ad47738c118622bf input=a55a6ee8e494c449]*/ { #define IOCTL_BUFSZ 1024 - int fd; - /* In PyArg_ParseTuple below, we use the unsigned non-checked 'I' - format for the 'code' parameter because Python turns 0x8000000 - into either a large positive number (PyLong or PyInt on 64-bit - platforms) or a negative number on others (32-bit PyInt) - whereas the system expects it to be a 32bit bit field value + /* We use the unsigned non-checked 'I' format for the 'code' parameter + because the system expects it to be a 32bit bit field value regardless of it being passed as an int or unsigned long on various platforms. See the termios.TIOCSWINSZ constant across platforms for an example of this. @@ -111,108 +162,101 @@ fcntl_ioctl(PyObject *self, PyObject *args) in their unsigned long ioctl codes this will break and need special casing based on the platform being built on. */ - unsigned int code; - int arg; + int arg = 0; int ret; Py_buffer pstr; char *str; Py_ssize_t len; - int mutate_arg = 1; char buf[IOCTL_BUFSZ+1]; /* argument plus NUL byte */ - if (PyArg_ParseTuple(args, "O&Iw*|i:ioctl", - conv_descriptor, &fd, &code, - &pstr, &mutate_arg)) { - char *arg; - str = pstr.buf; - len = pstr.len; - - if (mutate_arg) { - if (len <= IOCTL_BUFSZ) { - memcpy(buf, str, len); - buf[len] = '\0'; - arg = buf; + if (ob_arg != NULL) { + if (PyArg_Parse(ob_arg, "w*:ioctl", &pstr)) { + char *arg; + str = pstr.buf; + len = pstr.len; + + if (mutate_arg) { + if (len <= IOCTL_BUFSZ) { + memcpy(buf, str, len); + buf[len] = '\0'; + arg = buf; + } + else { + arg = str; + } + } + else { + if (len > IOCTL_BUFSZ) { + PyBuffer_Release(&pstr); + PyErr_SetString(PyExc_ValueError, + "ioctl string arg too long"); + return NULL; + } + else { + memcpy(buf, str, len); + buf[len] = '\0'; + arg = buf; + } + } + if (buf == arg) { + Py_BEGIN_ALLOW_THREADS /* think array.resize() */ + ret = ioctl(fd, code, arg); + Py_END_ALLOW_THREADS + } + else { + ret = ioctl(fd, code, arg); + } + if (mutate_arg && (len <= IOCTL_BUFSZ)) { + memcpy(str, buf, len); + } + PyBuffer_Release(&pstr); /* No further access to str below this point */ + if (ret < 0) { + PyErr_SetFromErrno(PyExc_IOError); + return NULL; + } + if (mutate_arg) { + return PyLong_FromLong(ret); } else { - arg = str; + return PyBytes_FromStringAndSize(buf, len); } } - else { + + PyErr_Clear(); + if (PyArg_Parse(ob_arg, "s*:ioctl", &pstr)) { + str = pstr.buf; + len = pstr.len; if (len > IOCTL_BUFSZ) { PyBuffer_Release(&pstr); PyErr_SetString(PyExc_ValueError, - "ioctl string arg too long"); + "ioctl string arg too long"); return NULL; } - else { - memcpy(buf, str, len); - buf[len] = '\0'; - arg = buf; - } - } - if (buf == arg) { - Py_BEGIN_ALLOW_THREADS /* think array.resize() */ - ret = ioctl(fd, code, arg); + memcpy(buf, str, len); + buf[len] = '\0'; + Py_BEGIN_ALLOW_THREADS + ret = ioctl(fd, code, buf); Py_END_ALLOW_THREADS - } - else { - ret = ioctl(fd, code, arg); - } - if (mutate_arg && (len <= IOCTL_BUFSZ)) { - memcpy(str, buf, len); - } - PyBuffer_Release(&pstr); /* No further access to str below this point */ - if (ret < 0) { - PyErr_SetFromErrno(PyExc_IOError); - return NULL; - } - if (mutate_arg) { - return PyLong_FromLong(ret); - } - else { + if (ret < 0) { + PyBuffer_Release(&pstr); + PyErr_SetFromErrno(PyExc_IOError); + return NULL; + } + PyBuffer_Release(&pstr); return PyBytes_FromStringAndSize(buf, len); } - } - PyErr_Clear(); - if (PyArg_ParseTuple(args, "O&Is*:ioctl", - conv_descriptor, &fd, &code, &pstr)) { - str = pstr.buf; - len = pstr.len; - if (len > IOCTL_BUFSZ) { - PyBuffer_Release(&pstr); - PyErr_SetString(PyExc_ValueError, - "ioctl string arg too long"); - return NULL; - } - memcpy(buf, str, len); - buf[len] = '\0'; - Py_BEGIN_ALLOW_THREADS - ret = ioctl(fd, code, buf); - Py_END_ALLOW_THREADS - if (ret < 0) { - PyBuffer_Release(&pstr); - PyErr_SetFromErrno(PyExc_IOError); - return NULL; + PyErr_Clear(); + if (!PyArg_Parse(ob_arg, + "i;ioctl requires a file or file descriptor," + " an integer and optionally an integer or buffer argument", + &arg)) { + return NULL; } - PyBuffer_Release(&pstr); - return PyBytes_FromStringAndSize(buf, len); - } - - PyErr_Clear(); - arg = 0; - if (!PyArg_ParseTuple(args, - "O&I|i;ioctl requires a file or file descriptor," - " an integer and optionally an integer or buffer argument", - conv_descriptor, &fd, &code, &arg)) { - return NULL; + // Fall-through to outside the 'if' statement. } Py_BEGIN_ALLOW_THREADS -#ifdef __VMS - ret = ioctl(fd, code, (void *)arg); -#else ret = ioctl(fd, code, arg); -#endif Py_END_ALLOW_THREADS if (ret < 0) { PyErr_SetFromErrno(PyExc_IOError); @@ -222,52 +266,25 @@ fcntl_ioctl(PyObject *self, PyObject *args) #undef IOCTL_BUFSZ } -PyDoc_STRVAR(ioctl_doc, -"ioctl(fd, op[, arg[, mutate_flag]])\n\ -\n\ -Perform the operation op on file descriptor fd. The values used for op\n\ -are operating system dependent, and are available as constants in the\n\ -fcntl or termios library modules, using the same names as used in the\n\ -relevant C header files.\n\ -\n\ -The argument arg is optional, and defaults to 0; it may be an int or a\n\ -buffer containing character data (most likely a string or an array). \n\ -\n\ -If the argument is a mutable buffer (such as an array) and if the\n\ -mutate_flag argument (which is only allowed in this case) is true then the\n\ -buffer is (in effect) passed to the operating system and changes made by\n\ -the OS will be reflected in the contents of the buffer after the call has\n\ -returned. The return value is the integer returned by the ioctl system\n\ -call.\n\ -\n\ -If the argument is a mutable buffer and the mutable_flag argument is not\n\ -passed or is false, the behavior is as if a string had been passed. This\n\ -behavior will change in future releases of Python.\n\ -\n\ -If the argument is an immutable buffer (most likely a string) then a copy\n\ -of the buffer is passed to the operating system and the return value is a\n\ -string of the same length containing whatever the operating system put in\n\ -the buffer. The length of the arg buffer in this case is not allowed to\n\ -exceed 1024 bytes.\n\ -\n\ -If the arg given is an integer or if none is specified, the result value is\n\ -an integer corresponding to the return value of the ioctl call in the C\n\ -code."); - - -/* flock(fd, operation) */ +/*[clinic input] +fcntl.flock + + fd: object(type='int', converter='conv_descriptor') + code: int + / + +Perform the lock operation op on file descriptor fd. + +See the Unix manual page for flock(2) for details (On some systems, this +function is emulated using fcntl()). +[clinic start generated code]*/ static PyObject * -fcntl_flock(PyObject *self, PyObject *args) +fcntl_flock_impl(PyModuleDef *module, int fd, int code) +/*[clinic end generated code: output=c9035133a7dbfc96 input=b762aa9448d05e43]*/ { - int fd; - int code; int ret; - if (!PyArg_ParseTuple(args, "O&i:flock", - conv_descriptor, &fd, &code)) - return NULL; - #ifdef HAVE_FLOCK Py_BEGIN_ALLOW_THREADS ret = flock(fd, code); @@ -303,29 +320,49 @@ fcntl_flock(PyObject *self, PyObject *args) PyErr_SetFromErrno(PyExc_IOError); return NULL; } - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } -PyDoc_STRVAR(flock_doc, -"flock(fd, operation)\n\ -\n\ -Perform the lock operation op on file descriptor fd. See the Unix \n\ -manual page for flock(2) for details. (On some systems, this function is\n\ -emulated using fcntl().)"); +/*[clinic input] +fcntl.lockf + + fd: object(type='int', converter='conv_descriptor') + code: int + lenobj: object = NULL + startobj: object = NULL + whence: int = 0 + / + +A wrapper around the fcntl() locking calls. + +fd is the file descriptor of the file to lock or unlock, and operation is one +of the following values: + + LOCK_UN - unlock + LOCK_SH - acquire a shared lock + LOCK_EX - acquire an exclusive lock + +When operation is LOCK_SH or LOCK_EX, it can also be bitwise ORed with +LOCK_NB to avoid blocking on lock acquisition. If LOCK_NB is used and the +lock cannot be acquired, an IOError will be raised and the exception will +have an errno attribute set to EACCES or EAGAIN (depending on the operating +system -- for portability, check for either value). + +length is the number of bytes to lock, with the default meaning to lock to +EOF. start is the byte offset, relative to whence, to that the lock +starts. whence is as with fileobj.seek(), specifically: + + 0 - relative to the start of the file (SEEK_SET) + 1 - relative to the current buffer position (SEEK_CUR) + 2 - relative to the end of the file (SEEK_END) +[clinic start generated code]*/ -/* lockf(fd, operation) */ static PyObject * -fcntl_lockf(PyObject *self, PyObject *args) +fcntl_lockf_impl(PyModuleDef *module, int fd, int code, PyObject *lenobj, PyObject *startobj, int whence) +/*[clinic end generated code: output=5536df2892bf3ce9 input=44856fa06db36184]*/ { - int fd, code, ret, whence = 0; - PyObject *lenobj = NULL, *startobj = NULL; - - if (!PyArg_ParseTuple(args, "O&i|OOi:lockf", - conv_descriptor, &fd, &code, - &lenobj, &startobj, &whence)) - return NULL; + int ret; #ifndef LOCK_SH #define LOCK_SH 1 /* shared lock */ @@ -378,43 +415,17 @@ fcntl_lockf(PyObject *self, PyObject *args) PyErr_SetFromErrno(PyExc_IOError); return NULL; } - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } -PyDoc_STRVAR(lockf_doc, -"lockf (fd, operation, length=0, start=0, whence=0)\n\ -\n\ -This is essentially a wrapper around the fcntl() locking calls. fd is the\n\ -file descriptor of the file to lock or unlock, and operation is one of the\n\ -following values:\n\ -\n\ - LOCK_UN - unlock\n\ - LOCK_SH - acquire a shared lock\n\ - LOCK_EX - acquire an exclusive lock\n\ -\n\ -When operation is LOCK_SH or LOCK_EX, it can also be bitwise ORed with\n\ -LOCK_NB to avoid blocking on lock acquisition. If LOCK_NB is used and the\n\ -lock cannot be acquired, an IOError will be raised and the exception will\n\ -have an errno attribute set to EACCES or EAGAIN (depending on the operating\n\ -system -- for portability, check for either value).\n\ -\n\ -length is the number of bytes to lock, with the default meaning to lock to\n\ -EOF. start is the byte offset, relative to whence, to that the lock\n\ -starts. whence is as with fileobj.seek(), specifically:\n\ -\n\ - 0 - relative to the start of the file (SEEK_SET)\n\ - 1 - relative to the current buffer position (SEEK_CUR)\n\ - 2 - relative to the end of the file (SEEK_END)"); - /* List of functions */ static PyMethodDef fcntl_methods[] = { - {"fcntl", fcntl_fcntl, METH_VARARGS, fcntl_doc}, - {"ioctl", fcntl_ioctl, METH_VARARGS, ioctl_doc}, - {"flock", fcntl_flock, METH_VARARGS, flock_doc}, - {"lockf", fcntl_lockf, METH_VARARGS, lockf_doc}, - {NULL, NULL} /* sentinel */ + FCNTL_FCNTL_METHODDEF + FCNTL_IOCTL_METHODDEF + FCNTL_FLOCK_METHODDEF + FCNTL_LOCKF_METHODDEF + {NULL, NULL} /* sentinel */ }; diff --git a/Modules/fpectlmodule.c b/Modules/fpectlmodule.c index 6af2f82f7073..052b83480daa 100644 --- a/Modules/fpectlmodule.c +++ b/Modules/fpectlmodule.c @@ -70,10 +70,6 @@ extern "C" { #if defined(__FreeBSD__) # include -#elif defined(__VMS) -#define __NEW_STARLET -#include -#include #endif #ifndef WANT_SIGFPE_HANDLER @@ -182,23 +178,6 @@ static void fpe_reset(Sigfunc *handler) ieee_set_fp_control(fp_control); PyOS_setsig(SIGFPE, handler); -/*-- DEC ALPHA VMS --------------------------------------------------------*/ -#elif defined(__ALPHA) && defined(__VMS) - IEEE clrmsk; - IEEE setmsk; - clrmsk.ieee$q_flags = - IEEE$M_TRAP_ENABLE_UNF | IEEE$M_TRAP_ENABLE_INE | - IEEE$M_MAP_UMZ; - setmsk.ieee$q_flags = - IEEE$M_TRAP_ENABLE_INV | IEEE$M_TRAP_ENABLE_DZE | - IEEE$M_TRAP_ENABLE_OVF; - sys$ieee_set_fp_control(&clrmsk, &setmsk, 0); - PyOS_setsig(SIGFPE, handler); - -/*-- HP IA64 VMS --------------------------------------------------------*/ -#elif defined(__ia64) && defined(__VMS) - PyOS_setsig(SIGFPE, handler); - /*-- Cray Unicos ----------------------------------------------------------*/ #elif defined(cray) /* UNICOS delivers SIGFPE by default, but no matherr */ @@ -251,14 +230,6 @@ static PyObject *turnoff_sigfpe(PyObject *self,PyObject *args) #ifdef __FreeBSD__ fpresetsticky(fpgetsticky()); fpsetmask(0); -#elif defined(__VMS) - IEEE clrmsk; - clrmsk.ieee$q_flags = - IEEE$M_TRAP_ENABLE_UNF | IEEE$M_TRAP_ENABLE_INE | - IEEE$M_MAP_UMZ | IEEE$M_TRAP_ENABLE_INV | - IEEE$M_TRAP_ENABLE_DZE | IEEE$M_TRAP_ENABLE_OVF | - IEEE$M_INHERIT; - sys$ieee_set_fp_control(&clrmsk, 0, 0); #else fputs("Operation not implemented\n", stderr); #endif diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index a84d752ffa6c..142687bb7fc4 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -25,6 +25,7 @@ #include "Python.h" #include "frameobject.h" /* for PyFrame_ClearFreeList */ +#include "pytime.h" /* for _PyTime_monotonic, _PyTime_INTERVAL */ /* Get an object's GC head */ #define AS_GC(o) ((PyGC_Head *)(o)-1) @@ -166,7 +167,6 @@ static Py_ssize_t long_lived_pending = 0; DEBUG_UNCOLLECTABLE | \ DEBUG_SAVEALL static int debug; -static PyObject *tmod = NULL; /* Running stats per generation */ struct gc_generation_stats { @@ -776,28 +776,40 @@ handle_legacy_finalizers(PyGC_Head *finalizers, PyGC_Head *old) return 0; } +/* Run first-time finalizers (if any) on all the objects in collectable. + * Note that this may remove some (or even all) of the objects from the + * list, due to refcounts falling to 0. + */ static void -finalize_garbage(PyGC_Head *collectable, PyGC_Head *old) +finalize_garbage(PyGC_Head *collectable) { destructor finalize; - PyGC_Head *gc = collectable->gc.gc_next; + PyGC_Head seen; + + /* While we're going through the loop, `finalize(op)` may cause op, or + * other objects, to be reclaimed via refcounts falling to zero. So + * there's little we can rely on about the structure of the input + * `collectable` list across iterations. For safety, we always take the + * first object in that list and move it to a temporary `seen` list. + * If objects vanish from the `collectable` and `seen` lists we don't + * care. + */ + gc_list_init(&seen); - for (; gc != collectable; gc = gc->gc.gc_next) { + while (!gc_list_is_empty(collectable)) { + PyGC_Head *gc = collectable->gc.gc_next; PyObject *op = FROM_GC(gc); - + gc_list_move(gc, &seen); if (!_PyGCHead_FINALIZED(gc) && - PyType_HasFeature(Py_TYPE(op), Py_TPFLAGS_HAVE_FINALIZE) && - (finalize = Py_TYPE(op)->tp_finalize) != NULL) { + PyType_HasFeature(Py_TYPE(op), Py_TPFLAGS_HAVE_FINALIZE) && + (finalize = Py_TYPE(op)->tp_finalize) != NULL) { _PyGCHead_SET_FINALIZED(gc, 1); Py_INCREF(op); finalize(op); - if (Py_REFCNT(op) == 1) { - /* op will be destroyed */ - gc = gc->gc.gc_prev; - } Py_DECREF(op); } } + gc_list_merge(&seen, collectable); } /* Walk the collectable list and check that they are really unreachable @@ -882,26 +894,6 @@ clear_freelists(void) (void)PySet_ClearFreeList(); } -static double -get_time(void) -{ - double result = 0; - if (tmod != NULL) { - _Py_IDENTIFIER(time); - - PyObject *f = _PyObject_CallMethodId(tmod, &PyId_time, NULL); - if (f == NULL) { - PyErr_Clear(); - } - else { - if (PyFloat_Check(f)) - result = PyFloat_AsDouble(f); - Py_DECREF(f); - } - } - return result; -} - /* This is the main function. Read this to understand how the * collection process works. */ static Py_ssize_t @@ -916,7 +908,8 @@ collect(int generation, Py_ssize_t *n_collected, Py_ssize_t *n_uncollectable, PyGC_Head unreachable; /* non-problematic unreachable trash */ PyGC_Head finalizers; /* objects with, & reachable from, __del__ */ PyGC_Head *gc; - double t1 = 0.0; + _PyTime_timeval t1; + struct gc_generation_stats *stats = &generation_stats[generation]; if (debug & DEBUG_STATS) { @@ -924,9 +917,10 @@ collect(int generation, Py_ssize_t *n_collected, Py_ssize_t *n_uncollectable, generation); PySys_WriteStderr("gc: objects in each generation:"); for (i = 0; i < NUM_GENERATIONS; i++) - PySys_WriteStderr(" %" PY_FORMAT_SIZE_T "d", + PySys_FormatStderr(" %zd", gc_list_size(GEN_HEAD(i))); - t1 = get_time(); + _PyTime_monotonic(&t1); + PySys_WriteStderr("\n"); } @@ -1006,7 +1000,7 @@ collect(int generation, Py_ssize_t *n_collected, Py_ssize_t *n_uncollectable, m += handle_weakrefs(&unreachable, old); /* Call tp_finalize on objects which have one. */ - finalize_garbage(&unreachable, old); + finalize_garbage(&unreachable); if (check_garbage(&unreachable)) { revive_garbage(&unreachable); @@ -1030,19 +1024,16 @@ collect(int generation, Py_ssize_t *n_collected, Py_ssize_t *n_uncollectable, debug_cycle("uncollectable", FROM_GC(gc)); } if (debug & DEBUG_STATS) { - double t2 = get_time(); + _PyTime_timeval t2; + _PyTime_monotonic(&t2); + if (m == 0 && n == 0) PySys_WriteStderr("gc: done"); else - PySys_WriteStderr( - "gc: done, " - "%" PY_FORMAT_SIZE_T "d unreachable, " - "%" PY_FORMAT_SIZE_T "d uncollectable", + PySys_FormatStderr( + "gc: done, %zd unreachable, %zd uncollectable", n+m, n); - if (t1 && t2) { - PySys_WriteStderr(", %.4fs elapsed", t2-t1); - } - PySys_WriteStderr(".\n"); + PySys_WriteStderr(", %.4fs elapsed\n", _PyTime_INTERVAL(t1, t2)); } /* Append instances in the uncollectable set to a Python @@ -1498,6 +1489,7 @@ PyDoc_STRVAR(gc__doc__, "isenabled() -- Returns true if automatic collection is enabled.\n" "collect() -- Do a full collection right now.\n" "get_count() -- Return the current collection counts.\n" +"get_stats() -- Return list of dictionaries containing per-generation stats.\n" "set_debug() -- Set debugging flags.\n" "get_debug() -- Get debugging flags.\n" "set_threshold() -- Set the collection thresholds.\n" @@ -1568,18 +1560,6 @@ PyInit_gc(void) if (PyModule_AddObject(m, "callbacks", callbacks) < 0) return NULL; - /* Importing can't be done in collect() because collect() - * can be called via PyGC_Collect() in Py_Finalize(). - * This wouldn't be a problem, except that is - * reset to 0 before calling collect which trips up - * the import and triggers an assertion. - */ - if (tmod == NULL) { - tmod = PyImport_ImportModuleNoBlock("time"); - if (tmod == NULL) - PyErr_Clear(); - } - #define ADD_INT(NAME) if (PyModule_AddIntConstant(m, #NAME, NAME) < 0) return NULL ADD_INT(DEBUG_STATS); ADD_INT(DEBUG_COLLECTABLE); @@ -1668,7 +1648,6 @@ void _PyGC_Fini(void) { Py_CLEAR(callbacks); - Py_CLEAR(tmod); } /* for debugging */ @@ -1692,13 +1671,6 @@ PyObject_GC_Track(void *op) _PyObject_GC_TRACK(op); } -/* for binary compatibility with 2.2 */ -void -_PyObject_GC_Track(PyObject *op) -{ - PyObject_GC_Track(op); -} - void PyObject_GC_UnTrack(void *op) { @@ -1709,22 +1681,19 @@ PyObject_GC_UnTrack(void *op) _PyObject_GC_UNTRACK(op); } -/* for binary compatibility with 2.2 */ -void -_PyObject_GC_UnTrack(PyObject *op) -{ - PyObject_GC_UnTrack(op); -} - -PyObject * -_PyObject_GC_Malloc(size_t basicsize) +static PyObject * +_PyObject_GC_Alloc(int use_calloc, size_t basicsize) { PyObject *op; PyGC_Head *g; + size_t size; if (basicsize > PY_SSIZE_T_MAX - sizeof(PyGC_Head)) return PyErr_NoMemory(); - g = (PyGC_Head *)PyObject_MALLOC( - sizeof(PyGC_Head) + basicsize); + size = sizeof(PyGC_Head) + basicsize; + if (use_calloc) + g = (PyGC_Head *)PyObject_Calloc(1, size); + else + g = (PyGC_Head *)PyObject_Malloc(size); if (g == NULL) return PyErr_NoMemory(); g->gc.gc_refs = 0; @@ -1743,6 +1712,18 @@ _PyObject_GC_Malloc(size_t basicsize) return op; } +PyObject * +_PyObject_GC_Malloc(size_t basicsize) +{ + return _PyObject_GC_Alloc(0, basicsize); +} + +PyObject * +_PyObject_GC_Calloc(size_t basicsize) +{ + return _PyObject_GC_Alloc(1, basicsize); +} + PyObject * _PyObject_GC_New(PyTypeObject *tp) { diff --git a/Modules/getpath.c b/Modules/getpath.c index 9e79c26b9e4a..3564d72afb80 100644 --- a/Modules/getpath.c +++ b/Modules/getpath.c @@ -110,11 +110,7 @@ #endif #ifndef PREFIX -# ifdef __VMS -# define PREFIX "" -# else -# define PREFIX "/usr/local" -# endif +# define PREFIX "/usr/local" #endif #ifndef EXEC_PREFIX @@ -340,7 +336,7 @@ search_for_prefix(wchar_t *argv0_path, wchar_t *home, wchar_t *_prefix, joinpath(prefix, L"Modules/Setup"); if (isfile(prefix)) { /* Check VPATH to see if argv0_path is in the build directory. */ - vpath = _Py_char2wchar(VPATH, NULL); + vpath = Py_DecodeLocale(VPATH, NULL); if (vpath != NULL) { wcsncpy(prefix, argv0_path, MAXPATHLEN); prefix[MAXPATHLEN] = L'\0'; @@ -495,10 +491,10 @@ calculate_path(void) wchar_t *_pythonpath, *_prefix, *_exec_prefix; wchar_t *lib_python; - _pythonpath = _Py_char2wchar(PYTHONPATH, NULL); - _prefix = _Py_char2wchar(PREFIX, NULL); - _exec_prefix = _Py_char2wchar(EXEC_PREFIX, NULL); - lib_python = _Py_char2wchar("lib/python" VERSION, NULL); + _pythonpath = Py_DecodeLocale(PYTHONPATH, NULL); + _prefix = Py_DecodeLocale(PREFIX, NULL); + _exec_prefix = Py_DecodeLocale(EXEC_PREFIX, NULL); + lib_python = Py_DecodeLocale("lib/python" VERSION, NULL); if (!_pythonpath || !_prefix || !_exec_prefix || !lib_python) { Py_FatalError( @@ -507,7 +503,7 @@ calculate_path(void) } if (_path) { - path_buffer = _Py_char2wchar(_path, NULL); + path_buffer = Py_DecodeLocale(_path, NULL); path = path_buffer; } @@ -588,7 +584,7 @@ calculate_path(void) ** be running the interpreter in the build directory, so we use the ** build-directory-specific logic to find Lib and such. */ - wchar_t* wbuf = _Py_char2wchar(modPath, NULL); + wchar_t* wbuf = Py_DecodeLocale(modPath, NULL); if (wbuf == NULL) { Py_FatalError("Cannot decode framework location"); } @@ -713,7 +709,7 @@ calculate_path(void) if (_rtpypath && _rtpypath[0] != '\0') { size_t rtpypath_len; - rtpypath = _Py_char2wchar(_rtpypath, &rtpypath_len); + rtpypath = Py_DecodeLocale(_rtpypath, &rtpypath_len); if (rtpypath != NULL) bufsz += rtpypath_len + 1; } @@ -739,7 +735,7 @@ calculate_path(void) bufsz += wcslen(zip_path) + 1; bufsz += wcslen(exec_prefix) + 1; - buf = (wchar_t *)PyMem_Malloc(bufsz * sizeof(wchar_t)); + buf = PyMem_New(wchar_t, bufsz); if (buf == NULL) { Py_FatalError( "Not enough memory for dynamic PYTHONPATH"); diff --git a/Modules/grpmodule.c b/Modules/grpmodule.c index a85a2715e91f..f7979be334a5 100644 --- a/Modules/grpmodule.c +++ b/Modules/grpmodule.c @@ -6,6 +6,13 @@ #include +#include "clinic/grpmodule.c.h" +/*[clinic input] +output preset file +module grp +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=68180a9a9efb8506]*/ + static PyStructSequence_Field struct_group_type_fields[] = { {"gr_name", "group name"}, {"gr_passwd", "password"}, @@ -58,17 +65,12 @@ mkgrent(struct group *p) #define SET(i,val) PyStructSequence_SET_ITEM(v, i, val) SET(setIndex++, PyUnicode_DecodeFSDefault(p->gr_name)); -#ifdef __VMS - SET(setIndex++, Py_None); - Py_INCREF(Py_None); -#else if (p->gr_passwd) SET(setIndex++, PyUnicode_DecodeFSDefault(p->gr_passwd)); else { SET(setIndex++, Py_None); Py_INCREF(Py_None); } -#endif SET(setIndex++, _PyLong_FromGid(p->gr_gid)); SET(setIndex++, w); #undef SET @@ -81,14 +83,25 @@ mkgrent(struct group *p) return v; } +/*[clinic input] +grp.getgrgid + + id: object + +Return the group database entry for the given numeric group ID. + +If id is not valid, raise KeyError. +[clinic start generated code]*/ + static PyObject * -grp_getgrgid(PyObject *self, PyObject *pyo_id) +grp_getgrgid_impl(PyModuleDef *module, PyObject *id) +/*[clinic end generated code: output=8a11f5fdeb8c78a0 input=15fa0e2ccf5cda25]*/ { PyObject *py_int_id; gid_t gid; struct group *p; - py_int_id = PyNumber_Long(pyo_id); + py_int_id = PyNumber_Long(id); if (!py_int_id) return NULL; if (!_Py_Gid_Converter(py_int_id, &gid)) { @@ -108,22 +121,31 @@ grp_getgrgid(PyObject *self, PyObject *pyo_id) return mkgrent(p); } +/*[clinic input] +grp.getgrnam + + name: unicode + +Return the group database entry for the given group name. + +If name is not valid, raise KeyError. +[clinic start generated code]*/ + static PyObject * -grp_getgrnam(PyObject *self, PyObject *args) +grp_getgrnam_impl(PyModuleDef *module, PyObject *name) +/*[clinic end generated code: output=cd47511f4854da8e input=08ded29affa3c863]*/ { - char *name; + char *name_chars; struct group *p; - PyObject *arg, *bytes, *retval = NULL; + PyObject *bytes, *retval = NULL; - if (!PyArg_ParseTuple(args, "U:getgrnam", &arg)) - return NULL; - if ((bytes = PyUnicode_EncodeFSDefault(arg)) == NULL) + if ((bytes = PyUnicode_EncodeFSDefault(name)) == NULL) return NULL; - if (PyBytes_AsStringAndSize(bytes, &name, NULL) == -1) + if (PyBytes_AsStringAndSize(bytes, &name_chars, NULL) == -1) goto out; - if ((p = getgrnam(name)) == NULL) { - PyErr_Format(PyExc_KeyError, "getgrnam(): name not found: %s", name); + if ((p = getgrnam(name_chars)) == NULL) { + PyErr_Format(PyExc_KeyError, "getgrnam(): name not found: %s", name_chars); goto out; } retval = mkgrent(p); @@ -132,8 +154,18 @@ grp_getgrnam(PyObject *self, PyObject *args) return retval; } +/*[clinic input] +grp.getgrall + +Return a list of all available group entries, in arbitrary order. + +An entry whose name starts with '+' or '-' represents an instruction +to use YP/NIS and may not be accessible via getgrnam or getgrgid. +[clinic start generated code]*/ + static PyObject * -grp_getgrall(PyObject *self, PyObject *ignore) +grp_getgrall_impl(PyModuleDef *module) +/*[clinic end generated code: output=add9037a20c202de input=d7df76c825c367df]*/ { PyObject *d; struct group *p; @@ -156,20 +188,10 @@ grp_getgrall(PyObject *self, PyObject *ignore) } static PyMethodDef grp_methods[] = { - {"getgrgid", grp_getgrgid, METH_O, - "getgrgid(id) -> tuple\n\ -Return the group database entry for the given numeric group ID. If\n\ -id is not valid, raise KeyError."}, - {"getgrnam", grp_getgrnam, METH_VARARGS, - "getgrnam(name) -> tuple\n\ -Return the group database entry for the given group name. If\n\ -name is not valid, raise KeyError."}, - {"getgrall", grp_getgrall, METH_NOARGS, - "getgrall() -> list of tuples\n\ -Return a list of all available group entries, in arbitrary order.\n\ -An entry whose name starts with '+' or '-' represents an instruction\n\ -to use YP/NIS and may not be accessible via getgrnam or getgrgid."}, - {NULL, NULL} /* sentinel */ + GRP_GETGRGID_METHODDEF + GRP_GETGRNAM_METHODDEF + GRP_GETGRALL_METHODDEF + {NULL, NULL} }; PyDoc_STRVAR(grp__doc__, @@ -178,10 +200,10 @@ PyDoc_STRVAR(grp__doc__, Group entries are reported as 4-tuples containing the following fields\n\ from the group database, in order:\n\ \n\ - name - name of the group\n\ - passwd - group password (encrypted); often empty\n\ - gid - numeric ID of the group\n\ - mem - list of members\n\ + gr_name - name of the group\n\ + gr_passwd - group password (encrypted); often empty\n\ + gr_gid - numeric ID of the group\n\ + gr_mem - list of members\n\ \n\ The gid is an integer, name and password are strings. (Note that most\n\ users are not explicitly listed as members of the groups they are in\n\ diff --git a/Modules/hashtable.c b/Modules/hashtable.c index 221ed53b9f60..133f3133ef37 100644 --- a/Modules/hashtable.c +++ b/Modules/hashtable.c @@ -233,11 +233,12 @@ _Py_hashtable_print_stats(_Py_hashtable_t *ht) nchains++; } } - printf("hash table %p: entries=%zu/%zu (%.0f%%), ", + printf("hash table %p: entries=%" + PY_FORMAT_SIZE_T "u/%" PY_FORMAT_SIZE_T "u (%.0f%%), ", ht, ht->entries, ht->num_buckets, load * 100.0); if (nchains) printf("avg_chain_len=%.1f, ", (double)total_chain_len / nchains); - printf("max_chain_len=%zu, %zu kB\n", + printf("max_chain_len=%" PY_FORMAT_SIZE_T "u, %" PY_FORMAT_SIZE_T "u kB\n", max_chain_len, size / 1024); } #endif @@ -326,7 +327,7 @@ _Py_hashtable_set(_Py_hashtable_t *ht, const void *key, entry->key_hash = key_hash; assert(data_size == ht->data_size); - memcpy(_PY_HASHTABLE_ENTRY_DATA(entry), data, data_size); + memcpy(_Py_HASHTABLE_ENTRY_DATA(entry), data, data_size); _Py_slist_prepend(&ht->buckets[index], (_Py_slist_item_t*)entry); ht->entries++; @@ -504,7 +505,7 @@ _Py_hashtable_copy(_Py_hashtable_t *src) err = 1; } else { - data = _PY_HASHTABLE_ENTRY_DATA(entry); + data = _Py_HASHTABLE_ENTRY_DATA(entry); err = _Py_hashtable_set(dst, entry->key, data, src->data_size); } if (err) { diff --git a/Modules/hashtable.h b/Modules/hashtable.h index 539e490c3197..a9f9993bfd7b 100644 --- a/Modules/hashtable.h +++ b/Modules/hashtable.h @@ -26,16 +26,16 @@ typedef struct { /* data follows */ } _Py_hashtable_entry_t; -#define _PY_HASHTABLE_ENTRY_DATA(ENTRY) \ +#define _Py_HASHTABLE_ENTRY_DATA(ENTRY) \ ((char *)(ENTRY) + sizeof(_Py_hashtable_entry_t)) #define _Py_HASHTABLE_ENTRY_DATA_AS_VOID_P(ENTRY) \ - (*(void **)_PY_HASHTABLE_ENTRY_DATA(ENTRY)) + (*(void **)_Py_HASHTABLE_ENTRY_DATA(ENTRY)) #define _Py_HASHTABLE_ENTRY_READ_DATA(TABLE, DATA, DATA_SIZE, ENTRY) \ do { \ assert((DATA_SIZE) == (TABLE)->data_size); \ - memcpy(DATA, _PY_HASHTABLE_ENTRY_DATA(ENTRY), DATA_SIZE); \ + memcpy(DATA, _Py_HASHTABLE_ENTRY_DATA(ENTRY), DATA_SIZE); \ } while (0) typedef Py_uhash_t (*_Py_hashtable_hash_func) (const void *key); diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index 8be62ce94c04..afff7e4aa871 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -1492,19 +1492,22 @@ islice_next(isliceobject *lz) Py_ssize_t oldnext; PyObject *(*iternext)(PyObject *); + if (it == NULL) + return NULL; + iternext = *Py_TYPE(it)->tp_iternext; while (lz->cnt < lz->next) { item = iternext(it); if (item == NULL) - return NULL; + goto empty; Py_DECREF(item); lz->cnt++; } if (stop != -1 && lz->cnt >= stop) - return NULL; + goto empty; item = iternext(it); if (item == NULL) - return NULL; + goto empty; lz->cnt++; oldnext = lz->next; /* The (size_t) cast below avoids the danger of undefined @@ -1513,6 +1516,10 @@ islice_next(isliceobject *lz) if (lz->next < oldnext || (stop != -1 && lz->next > stop)) lz->next = stop; return item; + +empty: + Py_CLEAR(lz->it); + return NULL; } static PyObject * @@ -1522,6 +1529,18 @@ islice_reduce(isliceobject *lz) * then 'setstate' with the next and count */ PyObject *stop; + if (lz->it == NULL) { + PyObject *empty_list; + PyObject *empty_it; + empty_list = PyList_New(0); + if (empty_list == NULL) + return NULL; + empty_it = PyObject_GetIter(empty_list); + Py_DECREF(empty_list); + if (empty_it == NULL) + return NULL; + return Py_BuildValue("O(Nn)n", Py_TYPE(lz), empty_it, 0, 0); + } if (lz->stop == -1) { stop = Py_None; Py_INCREF(stop); @@ -1998,11 +2017,19 @@ product_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } } - assert(PyTuple_Check(args)); - nargs = (repeat == 0) ? 0 : PyTuple_GET_SIZE(args); + assert(PyTuple_CheckExact(args)); + if (repeat == 0) { + nargs = 0; + } else { + nargs = PyTuple_GET_SIZE(args); + if ((size_t)nargs > PY_SSIZE_T_MAX/sizeof(Py_ssize_t)/repeat) { + PyErr_SetString(PyExc_OverflowError, "repeat argument too large"); + return NULL; + } + } npools = nargs * repeat; - indices = PyMem_Malloc(npools * sizeof(Py_ssize_t)); + indices = PyMem_New(Py_ssize_t, npools); if (indices == NULL) { PyErr_NoMemory(); goto error; @@ -2057,6 +2084,18 @@ product_dealloc(productobject *lz) Py_TYPE(lz)->tp_free(lz); } +static PyObject * +product_sizeof(productobject *lz, void *unused) +{ + Py_ssize_t res; + + res = sizeof(productobject); + res += PyTuple_GET_SIZE(lz->pools) * sizeof(Py_ssize_t); + return PyLong_FromSsize_t(res); +} + +PyDoc_STRVAR(sizeof_doc, "Returns size in memory, in bytes."); + static int product_traverse(productobject *lz, visitproc visit, void *arg) { @@ -2226,6 +2265,8 @@ static PyMethodDef product_methods[] = { reduce_doc}, {"__setstate__", (PyCFunction)product_setstate, METH_O, setstate_doc}, + {"__sizeof__", (PyCFunction)product_sizeof, METH_NOARGS, + sizeof_doc}, {NULL, NULL} /* sentinel */ }; @@ -2326,7 +2367,7 @@ combinations_new(PyTypeObject *type, PyObject *args, PyObject *kwds) goto error; } - indices = PyMem_Malloc(r * sizeof(Py_ssize_t)); + indices = PyMem_New(Py_ssize_t, r); if (indices == NULL) { PyErr_NoMemory(); goto error; @@ -2366,6 +2407,16 @@ combinations_dealloc(combinationsobject *co) Py_TYPE(co)->tp_free(co); } +static PyObject * +combinations_sizeof(combinationsobject *co, void *unused) +{ + Py_ssize_t res; + + res = sizeof(combinationsobject); + res += co->r * sizeof(Py_ssize_t); + return PyLong_FromSsize_t(res); +} + static int combinations_traverse(combinationsobject *co, visitproc visit, void *arg) { @@ -2537,6 +2588,8 @@ static PyMethodDef combinations_methods[] = { reduce_doc}, {"__setstate__", (PyCFunction)combinations_setstate, METH_O, setstate_doc}, + {"__sizeof__", (PyCFunction)combinations_sizeof, METH_NOARGS, + sizeof_doc}, {NULL, NULL} /* sentinel */ }; @@ -2655,7 +2708,7 @@ cwr_new(PyTypeObject *type, PyObject *args, PyObject *kwds) goto error; } - indices = PyMem_Malloc(r * sizeof(Py_ssize_t)); + indices = PyMem_New(Py_ssize_t, r); if (indices == NULL) { PyErr_NoMemory(); goto error; @@ -2695,6 +2748,16 @@ cwr_dealloc(cwrobject *co) Py_TYPE(co)->tp_free(co); } +static PyObject * +cwr_sizeof(cwrobject *co, void *unused) +{ + Py_ssize_t res; + + res = sizeof(cwrobject); + res += co->r * sizeof(Py_ssize_t); + return PyLong_FromSsize_t(res); +} + static int cwr_traverse(cwrobject *co, visitproc visit, void *arg) { @@ -2854,6 +2917,8 @@ static PyMethodDef cwr_methods[] = { reduce_doc}, {"__setstate__", (PyCFunction)cwr_setstate, METH_O, setstate_doc}, + {"__sizeof__", (PyCFunction)cwr_sizeof, METH_NOARGS, + sizeof_doc}, {NULL, NULL} /* sentinel */ }; @@ -2984,8 +3049,8 @@ permutations_new(PyTypeObject *type, PyObject *args, PyObject *kwds) goto error; } - indices = PyMem_Malloc(n * sizeof(Py_ssize_t)); - cycles = PyMem_Malloc(r * sizeof(Py_ssize_t)); + indices = PyMem_New(Py_ssize_t, n); + cycles = PyMem_New(Py_ssize_t, r); if (indices == NULL || cycles == NULL) { PyErr_NoMemory(); goto error; @@ -3030,6 +3095,17 @@ permutations_dealloc(permutationsobject *po) Py_TYPE(po)->tp_free(po); } +static PyObject * +permutations_sizeof(permutationsobject *po, void *unused) +{ + Py_ssize_t res; + + res = sizeof(permutationsobject); + res += PyTuple_GET_SIZE(po->pool) * sizeof(Py_ssize_t); + res += po->r * sizeof(Py_ssize_t); + return PyLong_FromSsize_t(res); +} + static int permutations_traverse(permutationsobject *po, visitproc visit, void *arg) { @@ -3235,6 +3311,8 @@ static PyMethodDef permuations_methods[] = { reduce_doc}, {"__setstate__", (PyCFunction)permutations_setstate, METH_O, setstate_doc}, + {"__sizeof__", (PyCFunction)permutations_sizeof, METH_NOARGS, + sizeof_doc}, {NULL, NULL} /* sentinel */ }; @@ -3796,7 +3874,7 @@ typedef struct { fast_mode: when cnt an integer < PY_SSIZE_T_MAX and no step is specified. - assert(cnt != PY_SSIZE_T_MAX && long_cnt == NULL && long_step==PyInt(1)); + assert(cnt != PY_SSIZE_T_MAX && long_cnt == NULL && long_step==PyLong(1)); Advances with: cnt += 1 When count hits Y_SSIZE_T_MAX, switch to slow_mode. @@ -4039,14 +4117,17 @@ repeat_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { repeatobject *ro; PyObject *element; - Py_ssize_t cnt = -1; + Py_ssize_t cnt = -1, n_kwds = 0; static char *kwargs[] = {"object", "times", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:repeat", kwargs, &element, &cnt)) return NULL; - if (PyTuple_Size(args) == 2 && cnt < 0) + if (kwds != NULL) + n_kwds = PyDict_Size(kwds); + /* Does user supply times argument? */ + if ((PyTuple_Size(args) + n_kwds == 2) && cnt < 0) cnt = 0; ro = (repeatobject *)type->tp_alloc(type, 0); diff --git a/Modules/main.c b/Modules/main.c index 9171070ab5dd..83538c42e036 100644 --- a/Modules/main.c +++ b/Modules/main.c @@ -5,16 +5,10 @@ #include -#ifdef __VMS -#error "PEP 11: VMS is now unsupported, code will be removed in Python 3.4" -#include -#endif - #if defined(MS_WINDOWS) || defined(__CYGWIN__) #include #ifdef HAVE_FCNTL_H #include -#define PATH_MAX MAXPATHLEN #endif #endif @@ -124,19 +118,7 @@ usage(int exitcode, wchar_t* program) fprintf(f, usage_5, DELIM, PYTHONHOMEHELP); fputs(usage_6, f); } -#if defined(__VMS) - if (exitcode == 0) { - /* suppress 'error' message */ - return 1; - } - else { - /* STS$M_INHIB_MSG + SS$_ABORT */ - return 0x1000002c; - } -#else return exitcode; -#endif - /*NOTREACHED*/ } static void RunStartupFile(PyCompilerFlags *cf) @@ -360,6 +342,8 @@ Py_Main(int argc, wchar_t **argv) int version = 0; int saw_unbuffered_flag = 0; PyCompilerFlags cf; + PyObject *warning_option = NULL; + PyObject *warning_options = NULL; cf.cf_flags = 0; @@ -482,7 +466,15 @@ Py_Main(int argc, wchar_t **argv) break; case 'W': - PySys_AddWarnOption(_PyOS_optarg); + if (warning_options == NULL) + warning_options = PyList_New(0); + if (warning_options == NULL) + Py_FatalError("failure in handling of -W argument"); + warning_option = PyUnicode_FromWideChar(_PyOS_optarg, -1); + if (warning_option == NULL) + Py_FatalError("failure in handling of -W argument"); + PyList_Append(warning_options, warning_option); + Py_DECREF(warning_option); break; case 'X': @@ -576,18 +568,17 @@ Py_Main(int argc, wchar_t **argv) PyMem_RawFree(buf); } #endif + if (warning_options != NULL) { + Py_ssize_t i; + for (i = 0; i < PyList_GET_SIZE(warning_options); i++) { + PySys_AddWarnOptionUnicode(PyList_GET_ITEM(warning_options, i)); + } + } if (command == NULL && module == NULL && _PyOS_optind < argc && wcscmp(argv[_PyOS_optind], L"-") != 0) { -#ifdef __VMS - filename = decc$translate_vms(argv[_PyOS_optind]); - if (filename == (char *)0 || filename == (char *)-1) - filename = argv[_PyOS_optind]; - -#else filename = argv[_PyOS_optind]; -#endif } stdin_is_interactive = Py_FdIsInteractive(stdin, (char *)0); @@ -623,11 +614,6 @@ Py_Main(int argc, wchar_t **argv) #endif /* !MS_WINDOWS */ /* Leave stderr alone - it should be unbuffered anyway. */ } -#ifdef __VMS - else { - setvbuf (stdout, (char *)NULL, _IOLBF, BUFSIZ); - } -#endif /* __VMS */ #ifdef __APPLE__ /* On MacOS X, when the Python interpreter is embedded in an @@ -660,7 +646,7 @@ Py_Main(int argc, wchar_t **argv) /* Used by Mac/Tools/pythonw.c to forward * the argv0 of the stub executable */ - wchar_t* wbuf = _Py_char2wchar(pyvenv_launcher, NULL); + wchar_t* wbuf = Py_DecodeLocale(pyvenv_launcher, NULL); if (wbuf == NULL) { Py_FatalError("Cannot decode __PYVENV_LAUNCHER__"); @@ -681,6 +667,7 @@ Py_Main(int argc, wchar_t **argv) Py_SetProgramName(argv[0]); #endif Py_Initialize(); + Py_XDECREF(warning_options); if (!Py_QuietFlag && (Py_VerboseFlag || (command == NULL && filename == NULL && @@ -742,7 +729,7 @@ Py_Main(int argc, wchar_t **argv) char *cfilename_buffer; const char *cfilename; int err = errno; - cfilename_buffer = _Py_wchar2char(filename, NULL); + cfilename_buffer = Py_EncodeLocale(filename, NULL); if (cfilename_buffer != NULL) cfilename = cfilename_buffer; else @@ -765,9 +752,8 @@ Py_Main(int argc, wchar_t **argv) } } { - /* XXX: does this work on Win/Win64? (see posix_fstat) */ - struct stat sb; - if (fstat(fileno(fp), &sb) == 0 && + struct _Py_stat_struct sb; + if (_Py_fstat(fileno(fp), &sb) == 0 && S_ISDIR(sb.st_mode)) { fprintf(stderr, "%ls: '%ls' is a directory, cannot continue\n", argv[0], filename); fclose(fp); diff --git a/Modules/makesetup b/Modules/makesetup index 40dfa9db488a..8b5cc28bba1d 100755 --- a/Modules/makesetup +++ b/Modules/makesetup @@ -217,7 +217,7 @@ sed -e 's/[ ]*#.*//' -e '/^[ ]*$/d' | *) src='$(srcdir)/'"$srcdir/$src";; esac case $doconfig in - no) cc="$cc \$(CCSHARED) \$(CFLAGS) \$(CPPFLAGS)";; + no) cc="$cc \$(CCSHARED) \$(PY_CFLAGS) \$(PY_CPPFLAGS)";; *) cc="$cc \$(PY_CORE_CFLAGS)";; esac @@ -229,11 +229,7 @@ sed -e 's/[ ]*#.*//' -e '/^[ ]*$/d' | esac for mod in $mods do - case $objs in - *$mod.o*) base=$mod;; - *) base=${mod}module;; - esac - file="$srcdir/$base\$(SO)" + file="$srcdir/$mod\$(EXT_SUFFIX)" case $doconfig in no) SHAREDMODS="$SHAREDMODS $file";; esac diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 4b3e642ff60a..9c97a2a6b73a 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -223,6 +223,35 @@ lanczos_sum(double x) return num/den; } +/* Constant for +infinity, generated in the same way as float('inf'). */ + +static double +m_inf(void) +{ +#ifndef PY_NO_SHORT_FLOAT_REPR + return _Py_dg_infinity(0); +#else + return Py_HUGE_VAL; +#endif +} + +/* Constant nan value, generated in the same way as float('nan'). */ +/* We don't currently assume that Py_NAN is defined everywhere. */ + +#if !defined(PY_NO_SHORT_FLOAT_REPR) || defined(Py_NAN) + +static double +m_nan(void) +{ +#ifndef PY_NO_SHORT_FLOAT_REPR + return _Py_dg_stdnan(0); +#else + return Py_NAN; +#endif +} + +#endif + static double m_tgamma(double x) { @@ -873,18 +902,18 @@ math_2(PyObject *args, double (*func) (double, double), char *funcname) FUNC1(acos, acos, 0, "acos(x)\n\nReturn the arc cosine (measured in radians) of x.") FUNC1(acosh, m_acosh, 0, - "acosh(x)\n\nReturn the hyperbolic arc cosine (measured in radians) of x.") + "acosh(x)\n\nReturn the inverse hyperbolic cosine of x.") FUNC1(asin, asin, 0, "asin(x)\n\nReturn the arc sine (measured in radians) of x.") FUNC1(asinh, m_asinh, 0, - "asinh(x)\n\nReturn the hyperbolic arc sine (measured in radians) of x.") + "asinh(x)\n\nReturn the inverse hyperbolic sine of x.") FUNC1(atan, atan, 0, "atan(x)\n\nReturn the arc tangent (measured in radians) of x.") FUNC2(atan2, m_atan2, "atan2(y, x)\n\nReturn the arc tangent (measured in radians) of y/x.\n" "Unlike atan(y/x), the signs of both x and y are considered.") FUNC1(atanh, m_atanh, 0, - "atanh(x)\n\nReturn the hyperbolic arc tangent (measured in radians) of x.") + "atanh(x)\n\nReturn the inverse hyperbolic tangent of x.") static PyObject * math_ceil(PyObject *self, PyObject *number) { _Py_IDENTIFIER(__ceil__); @@ -906,7 +935,9 @@ PyDoc_STRVAR(math_ceil_doc, "This is the smallest integral value >= x."); FUNC2(copysign, copysign, - "copysign(x, y)\n\nReturn x with the sign of y.") + "copysign(x, y)\n\nReturn a float with the magnitude (absolute value) " + "of x but the sign \nof y. On platforms that support signed zeros, " + "copysign(1.0, -0.0) \nreturns -1.0.\n") FUNC1(cos, cos, 0, "cos(x)\n\nReturn the cosine of x (measured in radians).") FUNC1(cosh, cosh, 1, @@ -1008,7 +1039,7 @@ _fsum_realloc(double **p_ptr, Py_ssize_t n, Py_ssize_t m = *m_ptr; m += m; /* double */ - if (n < m && m < (PY_SSIZE_T_MAX / sizeof(double))) { + if (n < m && (size_t)m < ((size_t)PY_SSIZE_T_MAX / sizeof(double))) { double *p = *p_ptr; if (p == ps) { v = PyMem_Malloc(sizeof(double) * m); @@ -1406,6 +1437,7 @@ static PyObject * math_factorial(PyObject *self, PyObject *arg) { long x; + int overflow; PyObject *result, *odd_part, *two_valuation; if (PyFloat_Check(arg)) { @@ -1419,15 +1451,22 @@ math_factorial(PyObject *self, PyObject *arg) lx = PyLong_FromDouble(dx); if (lx == NULL) return NULL; - x = PyLong_AsLong(lx); + x = PyLong_AsLongAndOverflow(lx, &overflow); Py_DECREF(lx); } else - x = PyLong_AsLong(arg); + x = PyLong_AsLongAndOverflow(arg, &overflow); - if (x == -1 && PyErr_Occurred()) + if (x == -1 && PyErr_Occurred()) { + return NULL; + } + else if (overflow == 1) { + PyErr_Format(PyExc_OverflowError, + "factorial() argument should not exceed %ld", + LONG_MAX); return NULL; - if (x < 0) { + } + else if (overflow == -1 || x < 0) { PyErr_SetString(PyExc_ValueError, "factorial() not defined for negative values"); return NULL; @@ -1999,7 +2038,11 @@ PyInit_math(void) PyModule_AddObject(m, "pi", PyFloat_FromDouble(Py_MATH_PI)); PyModule_AddObject(m, "e", PyFloat_FromDouble(Py_MATH_E)); + PyModule_AddObject(m, "inf", PyFloat_FromDouble(m_inf())); +#if !defined(PY_NO_SHORT_FLOAT_REPR) || defined(Py_NAN) + PyModule_AddObject(m, "nan", PyFloat_FromDouble(m_nan())); +#endif - finally: + finally: return m; } diff --git a/Modules/md5module.c b/Modules/md5module.c index 5cb3d36c9b09..65f5c35a6203 100644 --- a/Modules/md5module.c +++ b/Modules/md5module.c @@ -19,6 +19,11 @@ #include "Python.h" #include "hashlib.h" +/*[clinic input] +module _md5 +class MD5Type "MD5object *" "&PyType_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=6e5261719957a912]*/ /* Some useful types */ @@ -332,10 +337,33 @@ MD5_dealloc(PyObject *ptr) /* External methods for a hash object */ -PyDoc_STRVAR(MD5_copy__doc__, "Return a copy of the hash object."); +/*[clinic input] +MD5Type.copy + +Return a copy of the hash object. +[clinic start generated code]*/ + +PyDoc_STRVAR(MD5Type_copy__doc__, +"copy($self, /)\n" +"--\n" +"\n" +"Return a copy of the hash object."); + +#define MD5TYPE_COPY_METHODDEF \ + {"copy", (PyCFunction)MD5Type_copy, METH_NOARGS, MD5Type_copy__doc__}, + +static PyObject * +MD5Type_copy_impl(MD5object *self); + +static PyObject * +MD5Type_copy(MD5object *self, PyObject *Py_UNUSED(ignored)) +{ + return MD5Type_copy_impl(self); +} static PyObject * -MD5_copy(MD5object *self, PyObject *unused) +MD5Type_copy_impl(MD5object *self) +/*[clinic end generated code: output=3b3a88920b3dc7f4 input=2c09e6d2493f3079]*/ { MD5object *newobj; @@ -351,11 +379,33 @@ MD5_copy(MD5object *self, PyObject *unused) return (PyObject *)newobj; } -PyDoc_STRVAR(MD5_digest__doc__, +/*[clinic input] +MD5Type.digest + +Return the digest value as a string of binary data. +[clinic start generated code]*/ + +PyDoc_STRVAR(MD5Type_digest__doc__, +"digest($self, /)\n" +"--\n" +"\n" "Return the digest value as a string of binary data."); +#define MD5TYPE_DIGEST_METHODDEF \ + {"digest", (PyCFunction)MD5Type_digest, METH_NOARGS, MD5Type_digest__doc__}, + static PyObject * -MD5_digest(MD5object *self, PyObject *unused) +MD5Type_digest_impl(MD5object *self); + +static PyObject * +MD5Type_digest(MD5object *self, PyObject *Py_UNUSED(ignored)) +{ + return MD5Type_digest_impl(self); +} + +static PyObject * +MD5Type_digest_impl(MD5object *self) +/*[clinic end generated code: output=7a796b28fa89485f input=7b96e65389412a34]*/ { unsigned char digest[MD5_DIGESTSIZE]; struct md5_state temp; @@ -365,11 +415,33 @@ MD5_digest(MD5object *self, PyObject *unused) return PyBytes_FromStringAndSize((const char *)digest, MD5_DIGESTSIZE); } -PyDoc_STRVAR(MD5_hexdigest__doc__, +/*[clinic input] +MD5Type.hexdigest + +Return the digest value as a string of hexadecimal digits. +[clinic start generated code]*/ + +PyDoc_STRVAR(MD5Type_hexdigest__doc__, +"hexdigest($self, /)\n" +"--\n" +"\n" "Return the digest value as a string of hexadecimal digits."); +#define MD5TYPE_HEXDIGEST_METHODDEF \ + {"hexdigest", (PyCFunction)MD5Type_hexdigest, METH_NOARGS, MD5Type_hexdigest__doc__}, + +static PyObject * +MD5Type_hexdigest_impl(MD5object *self); + static PyObject * -MD5_hexdigest(MD5object *self, PyObject *unused) +MD5Type_hexdigest(MD5object *self, PyObject *Py_UNUSED(ignored)) +{ + return MD5Type_hexdigest_impl(self); +} + +static PyObject * +MD5Type_hexdigest_impl(MD5object *self) +/*[clinic end generated code: output=daa73609f94f92e1 input=b60b19de644798dd]*/ { unsigned char digest[MD5_DIGESTSIZE]; struct md5_state temp; @@ -401,18 +473,30 @@ MD5_hexdigest(MD5object *self, PyObject *unused) return retval; } -PyDoc_STRVAR(MD5_update__doc__, -"Update this hash object's state with the provided string."); +/*[clinic input] +MD5Type.update + + obj: object + / + +Update this hash object's state with the provided string. +[clinic start generated code]*/ + +PyDoc_STRVAR(MD5Type_update__doc__, +"update($self, obj, /)\n" +"--\n" +"\n" +"Update this hash object\'s state with the provided string."); + +#define MD5TYPE_UPDATE_METHODDEF \ + {"update", (PyCFunction)MD5Type_update, METH_O, MD5Type_update__doc__}, static PyObject * -MD5_update(MD5object *self, PyObject *args) +MD5Type_update(MD5object *self, PyObject *obj) +/*[clinic end generated code: output=9d09b6c6cdc6cac3 input=6e1efcd9ecf17032]*/ { - PyObject *obj; Py_buffer buf; - if (!PyArg_ParseTuple(args, "O:update", &obj)) - return NULL; - GET_BUFFER_VIEW_OR_ERROUT(obj, &buf); md5_process(&self->hash_state, buf.buf, buf.len); @@ -423,10 +507,10 @@ MD5_update(MD5object *self, PyObject *args) } static PyMethodDef MD5_methods[] = { - {"copy", (PyCFunction)MD5_copy, METH_NOARGS, MD5_copy__doc__}, - {"digest", (PyCFunction)MD5_digest, METH_NOARGS, MD5_digest__doc__}, - {"hexdigest", (PyCFunction)MD5_hexdigest, METH_NOARGS, MD5_hexdigest__doc__}, - {"update", (PyCFunction)MD5_update, METH_VARARGS, MD5_update__doc__}, + MD5TYPE_COPY_METHODDEF + MD5TYPE_DIGEST_METHODDEF + MD5TYPE_HEXDIGEST_METHODDEF + MD5TYPE_UPDATE_METHODDEF {NULL, NULL} /* sentinel */ }; @@ -502,27 +586,55 @@ static PyTypeObject MD5type = { /* The single module-level function: new() */ -PyDoc_STRVAR(MD5_new__doc__, +/*[clinic input] +_md5.md5 + + string: object(c_default="NULL") = b'' + +Return a new MD5 hash object; optionally initialized with a string. +[clinic start generated code]*/ + +PyDoc_STRVAR(_md5_md5__doc__, +"md5($module, /, string=b\'\')\n" +"--\n" +"\n" "Return a new MD5 hash object; optionally initialized with a string."); +#define _MD5_MD5_METHODDEF \ + {"md5", (PyCFunction)_md5_md5, METH_VARARGS|METH_KEYWORDS, _md5_md5__doc__}, + +static PyObject * +_md5_md5_impl(PyModuleDef *module, PyObject *string); + static PyObject * -MD5_new(PyObject *self, PyObject *args, PyObject *kwdict) +_md5_md5(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"string", NULL}; + PyObject *string = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "|O:md5", _keywords, + &string)) + goto exit; + return_value = _md5_md5_impl(module, string); + +exit: + return return_value; +} + +static PyObject * +_md5_md5_impl(PyModuleDef *module, PyObject *string) +/*[clinic end generated code: output=1039e912d919880e input=d12ef8f72d684f7b]*/ { - static char *kwlist[] = {"string", NULL}; MD5object *new; - PyObject *data_obj = NULL; Py_buffer buf; - if (!PyArg_ParseTupleAndKeywords(args, kwdict, "|O:new", kwlist, - &data_obj)) { - return NULL; - } - - if (data_obj) - GET_BUFFER_VIEW_OR_ERROUT(data_obj, &buf); + if (string) + GET_BUFFER_VIEW_OR_ERROUT(string, &buf); if ((new = newMD5object()) == NULL) { - if (data_obj) + if (string) PyBuffer_Release(&buf); return NULL; } @@ -531,11 +643,11 @@ MD5_new(PyObject *self, PyObject *args, PyObject *kwdict) if (PyErr_Occurred()) { Py_DECREF(new); - if (data_obj) + if (string) PyBuffer_Release(&buf); return NULL; } - if (data_obj) { + if (string) { md5_process(&new->hash_state, buf.buf, buf.len); PyBuffer_Release(&buf); } @@ -547,7 +659,7 @@ MD5_new(PyObject *self, PyObject *args, PyObject *kwdict) /* List of functions exported by this module */ static struct PyMethodDef MD5_functions[] = { - {"md5", (PyCFunction)MD5_new, METH_VARARGS|METH_KEYWORDS, MD5_new__doc__}, + _MD5_MD5_METHODDEF {NULL, NULL} /* Sentinel */ }; diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c index 366dac15e675..ac134b837d69 100644 --- a/Modules/mmapmodule.c +++ b/Modules/mmapmodule.c @@ -459,8 +459,8 @@ mmap_size_method(mmap_object *self, #ifdef UNIX { - struct stat buf; - if (-1 == fstat(self->fd, &buf)) { + struct _Py_stat_struct buf; + if (-1 == _Py_fstat(self->fd, &buf)) { PyErr_SetFromErrno(PyExc_OSError); return NULL; } @@ -709,6 +709,19 @@ mmap__exit__method(PyObject *self, PyObject *args) return _PyObject_CallMethodId(self, &PyId_close, NULL); } +#ifdef MS_WINDOWS +static PyObject * +mmap__sizeof__method(mmap_object *self, void *unused) +{ + Py_ssize_t res; + + res = sizeof(mmap_object); + if (self->tagname) + res += strlen(self->tagname) + 1; + return PyLong_FromSsize_t(res); +} +#endif + static struct PyMethodDef mmap_object_methods[] = { {"close", (PyCFunction) mmap_close_method, METH_NOARGS}, {"find", (PyCFunction) mmap_find_method, METH_VARARGS}, @@ -726,6 +739,9 @@ static struct PyMethodDef mmap_object_methods[] = { {"write_byte", (PyCFunction) mmap_write_byte_method, METH_VARARGS}, {"__enter__", (PyCFunction) mmap__enter__method, METH_NOARGS}, {"__exit__", (PyCFunction) mmap__exit__method, METH_VARARGS}, +#ifdef MS_WINDOWS + {"__sizeof__", (PyCFunction) mmap__sizeof__method, METH_NOARGS}, +#endif {NULL, NULL} /* sentinel */ }; @@ -1091,7 +1107,7 @@ static PyObject * new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict) { #ifdef HAVE_FSTAT - struct stat st; + struct _Py_stat_struct st; #endif mmap_object *m_obj; PyObject *map_size_obj = NULL; @@ -1158,13 +1174,7 @@ new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict) (void)fcntl(fd, F_FULLFSYNC); #endif #ifdef HAVE_FSTAT -# ifdef __VMS - /* on OpenVMS we must ensure that all bytes are written to the file */ - if (fd != -1) { - fsync(fd); - } -# endif - if (fd != -1 && fstat(fd, &st) == 0 && S_ISREG(st.st_mode)) { + if (fd != -1 && _Py_fstat(fd, &st) == 0 && S_ISREG(st.st_mode)) { if (map_size == 0) { if (st.st_size == 0) { PyErr_SetString(PyExc_ValueError, diff --git a/Modules/ossaudiodev.c b/Modules/ossaudiodev.c index b0a16dbf0d76..2d0dd098d8e6 100644 --- a/Modules/ossaudiodev.c +++ b/Modules/ossaudiodev.c @@ -564,7 +564,6 @@ oss_setparameters(oss_audio_t *self, PyObject *args) { int wanted_fmt, wanted_channels, wanted_rate, strict=0; int fmt, channels, rate; - PyObject * rv; /* return tuple (fmt, channels, rate) */ if (!_is_fd_valid(self->fd)) return NULL; @@ -609,13 +608,7 @@ oss_setparameters(oss_audio_t *self, PyObject *args) /* Construct the return value: a (fmt, channels, rate) tuple that tells what the audio hardware was actually set to. */ - rv = PyTuple_New(3); - if (rv == NULL) - return NULL; - PyTuple_SET_ITEM(rv, 0, PyLong_FromLong(fmt)); - PyTuple_SET_ITEM(rv, 1, PyLong_FromLong(channels)); - PyTuple_SET_ITEM(rv, 2, PyLong_FromLong(rate)); - return rv; + return Py_BuildValue("(iii)", fmt, channels, rate); } static int @@ -901,7 +894,7 @@ static PyMethodDef oss_methods[] = { /* Aliases for backwards compatibility */ { "flush", (PyCFunction)oss_sync, METH_VARARGS }, - /* Support for the context manager protocol */ + /* Support for the context management protocol */ { "__enter__", oss_self, METH_NOARGS }, { "__exit__", oss_exit, METH_VARARGS }, @@ -913,7 +906,7 @@ static PyMethodDef oss_mixer_methods[] = { { "close", (PyCFunction)oss_mixer_close, METH_NOARGS }, { "fileno", (PyCFunction)oss_mixer_fileno, METH_NOARGS }, - /* Support for the context manager protocol */ + /* Support for the context management protocol */ { "__enter__", oss_self, METH_NOARGS }, { "__exit__", oss_exit, METH_VARARGS }, diff --git a/Modules/overlapped.c b/Modules/overlapped.c index 625c76eff4e6..ef77c8875aa3 100644 --- a/Modules/overlapped.c +++ b/Modules/overlapped.c @@ -45,19 +45,13 @@ typedef struct { /* Type of operation */ DWORD type; union { - /* Buffer used for reading (optional) */ + /* Buffer used for reading: TYPE_READ and TYPE_ACCEPT */ PyObject *read_buffer; - /* Buffer used for writing (optional) */ + /* Buffer used for writing: TYPE_WRITE */ Py_buffer write_buffer; }; } OverlappedObject; -typedef struct { - OVERLAPPED *Overlapped; - HANDLE IocpHandle; - char Address[1]; -} WaitNamedPipeAndConnectContext; - /* * Map Windows error codes to subclasses of OSError */ @@ -309,6 +303,29 @@ overlapped_UnregisterWait(PyObject *self, PyObject *args) Py_RETURN_NONE; } +PyDoc_STRVAR( + UnregisterWaitEx_doc, + "UnregisterWaitEx(WaitHandle, Event) -> None\n\n" + "Unregister wait handle.\n"); + +static PyObject * +overlapped_UnregisterWaitEx(PyObject *self, PyObject *args) +{ + HANDLE WaitHandle, Event; + BOOL ret; + + if (!PyArg_ParseTuple(args, F_HANDLE F_HANDLE, &WaitHandle, &Event)) + return NULL; + + Py_BEGIN_ALLOW_THREADS + ret = UnregisterWaitEx(WaitHandle, Event); + Py_END_ALLOW_THREADS + + if (!ret) + return SetFromWindowsErr(0); + Py_RETURN_NONE; +} + /* * Event functions -- currently only used by tests */ @@ -568,13 +585,15 @@ Overlapped_dealloc(OverlappedObject *self) if (self->overlapped.hEvent != NULL) CloseHandle(self->overlapped.hEvent); - if (self->write_buffer.obj) - PyBuffer_Release(&self->write_buffer); - switch (self->type) { - case TYPE_READ: - case TYPE_ACCEPT: - Py_CLEAR(self->read_buffer); + case TYPE_READ: + case TYPE_ACCEPT: + Py_CLEAR(self->read_buffer); + break; + case TYPE_WRITE: + if (self->write_buffer.obj) + PyBuffer_Release(&self->write_buffer); + break; } PyObject_Del(self); SetLastError(olderr); @@ -648,7 +667,7 @@ Overlapped_getresult(OverlappedObject *self, PyObject *args) case ERROR_MORE_DATA: break; case ERROR_BROKEN_PIPE: - if (self->read_buffer != NULL) + if ((self->type == TYPE_READ || self->type == TYPE_ACCEPT) && self->read_buffer != NULL) break; /* fall through */ default: @@ -711,7 +730,7 @@ Overlapped_ReadFile(OverlappedObject *self, PyObject *args) switch (err) { case ERROR_BROKEN_PIPE: mark_as_completed(&self->overlapped); - Py_RETURN_NONE; + return SetFromWindowsErr(err); case ERROR_SUCCESS: case ERROR_MORE_DATA: case ERROR_IO_PENDING: @@ -770,7 +789,7 @@ Overlapped_WSARecv(OverlappedObject *self, PyObject *args) switch (err) { case ERROR_BROKEN_PIPE: mark_as_completed(&self->overlapped); - Py_RETURN_NONE; + return SetFromWindowsErr(err); case ERROR_SUCCESS: case ERROR_MORE_DATA: case ERROR_IO_PENDING: @@ -1098,109 +1117,46 @@ Overlapped_ConnectNamedPipe(OverlappedObject *self, PyObject *args) switch (err) { case ERROR_PIPE_CONNECTED: mark_as_completed(&self->overlapped); - Py_RETURN_NONE; + Py_RETURN_TRUE; case ERROR_SUCCESS: case ERROR_IO_PENDING: - Py_RETURN_NONE; + Py_RETURN_FALSE; default: self->type = TYPE_NOT_STARTED; return SetFromWindowsErr(err); } } -/* Unfortunately there is no way to do an overlapped connect to a - pipe. We instead use WaitNamedPipe() and CreateFile() in a thread - pool thread. If a connection succeeds within a time limit (10 - seconds) then PostQueuedCompletionStatus() is used to return the - pipe handle to the completion port. */ - -static DWORD WINAPI -WaitNamedPipeAndConnectInThread(WaitNamedPipeAndConnectContext *ctx) -{ - HANDLE PipeHandle = INVALID_HANDLE_VALUE; - DWORD Start = GetTickCount(); - DWORD Deadline = Start + 10*1000; - DWORD Error = 0; - DWORD Timeout; - BOOL Success; - - for ( ; ; ) { - Timeout = Deadline - GetTickCount(); - if ((int)Timeout < 0) - break; - Success = WaitNamedPipe(ctx->Address, Timeout); - Error = Success ? ERROR_SUCCESS : GetLastError(); - switch (Error) { - case ERROR_SUCCESS: - PipeHandle = CreateFile(ctx->Address, - GENERIC_READ | GENERIC_WRITE, - 0, NULL, OPEN_EXISTING, - FILE_FLAG_OVERLAPPED, NULL); - if (PipeHandle == INVALID_HANDLE_VALUE) - continue; - break; - case ERROR_SEM_TIMEOUT: - continue; - } - break; - } - if (!PostQueuedCompletionStatus(ctx->IocpHandle, Error, - (ULONG_PTR)PipeHandle, ctx->Overlapped)) - CloseHandle(PipeHandle); - free(ctx); - return 0; -} - PyDoc_STRVAR( - Overlapped_WaitNamedPipeAndConnect_doc, - "WaitNamedPipeAndConnect(addr, iocp_handle) -> Overlapped[pipe_handle]\n\n" - "Start overlapped connection to address, notifying iocp_handle when\n" - "finished"); + ConnectPipe_doc, + "ConnectPipe(addr) -> pipe_handle\n\n" + "Connect to the pipe for asynchronous I/O (overlapped)."); static PyObject * -Overlapped_WaitNamedPipeAndConnect(OverlappedObject *self, PyObject *args) +ConnectPipe(OverlappedObject *self, PyObject *args) { - char *Address; - Py_ssize_t AddressLength; - HANDLE IocpHandle; - OVERLAPPED Overlapped; - BOOL ret; - DWORD err; - WaitNamedPipeAndConnectContext *ctx; - Py_ssize_t ContextLength; + PyObject *AddressObj; + wchar_t *Address; + HANDLE PipeHandle; - if (!PyArg_ParseTuple(args, "s#" F_HANDLE F_POINTER, - &Address, &AddressLength, &IocpHandle, &Overlapped)) + if (!PyArg_ParseTuple(args, "U", &AddressObj)) return NULL; - if (self->type != TYPE_NONE) { - PyErr_SetString(PyExc_ValueError, "operation already attempted"); + Address = PyUnicode_AsWideCharString(AddressObj, NULL); + if (Address == NULL) return NULL; - } - - ContextLength = (AddressLength + - offsetof(WaitNamedPipeAndConnectContext, Address)); - ctx = calloc(1, ContextLength + 1); - if (ctx == NULL) - return PyErr_NoMemory(); - memcpy(ctx->Address, Address, AddressLength + 1); - ctx->Overlapped = &self->overlapped; - ctx->IocpHandle = IocpHandle; - - self->type = TYPE_WAIT_NAMED_PIPE_AND_CONNECT; - self->handle = NULL; Py_BEGIN_ALLOW_THREADS - ret = QueueUserWorkItem(WaitNamedPipeAndConnectInThread, ctx, - WT_EXECUTELONGFUNCTION); + PipeHandle = CreateFileW(Address, + GENERIC_READ | GENERIC_WRITE, + 0, NULL, OPEN_EXISTING, + FILE_FLAG_OVERLAPPED, NULL); Py_END_ALLOW_THREADS - mark_as_completed(&self->overlapped); - - self->error = err = ret ? ERROR_SUCCESS : GetLastError(); - if (!ret) - return SetFromWindowsErr(err); - Py_RETURN_NONE; + PyMem_Free(Address); + if (PipeHandle == INVALID_HANDLE_VALUE) + return SetFromWindowsErr(0); + return Py_BuildValue(F_HANDLE, PipeHandle); } static PyObject* @@ -1237,9 +1193,6 @@ static PyMethodDef Overlapped_methods[] = { METH_VARARGS, Overlapped_DisconnectEx_doc}, {"ConnectNamedPipe", (PyCFunction) Overlapped_ConnectNamedPipe, METH_VARARGS, Overlapped_ConnectNamedPipe_doc}, - {"WaitNamedPipeAndConnect", - (PyCFunction) Overlapped_WaitNamedPipeAndConnect, - METH_VARARGS, Overlapped_WaitNamedPipeAndConnect_doc}, {NULL} }; @@ -1317,12 +1270,17 @@ static PyMethodDef overlapped_functions[] = { METH_VARARGS, RegisterWaitWithQueue_doc}, {"UnregisterWait", overlapped_UnregisterWait, METH_VARARGS, UnregisterWait_doc}, + {"UnregisterWaitEx", overlapped_UnregisterWaitEx, + METH_VARARGS, UnregisterWaitEx_doc}, {"CreateEvent", overlapped_CreateEvent, METH_VARARGS, CreateEvent_doc}, {"SetEvent", overlapped_SetEvent, METH_VARARGS, SetEvent_doc}, {"ResetEvent", overlapped_ResetEvent, METH_VARARGS, ResetEvent_doc}, + {"ConnectPipe", + (PyCFunction) ConnectPipe, + METH_VARARGS, ConnectPipe_doc}, {NULL} }; @@ -1367,6 +1325,7 @@ PyInit__overlapped(void) WINAPI_CONSTANT(F_DWORD, ERROR_IO_PENDING); WINAPI_CONSTANT(F_DWORD, ERROR_NETNAME_DELETED); WINAPI_CONSTANT(F_DWORD, ERROR_SEM_TIMEOUT); + WINAPI_CONSTANT(F_DWORD, ERROR_PIPE_BUSY); WINAPI_CONSTANT(F_DWORD, INFINITE); WINAPI_CONSTANT(F_HANDLE, INVALID_HANDLE_VALUE); WINAPI_CONSTANT(F_HANDLE, NULL); diff --git a/Modules/parsermodule.c b/Modules/parsermodule.c index 537a2e9e6d2c..36e9893da843 100644 --- a/Modules/parsermodule.c +++ b/Modules/parsermodule.c @@ -785,7 +785,7 @@ build_node_children(PyObject *tuple, node *root, int *line_num) } } if (!ok) { - PyObject *err = Py_BuildValue("os", elem, + PyObject *err = Py_BuildValue("Os", elem, "Illegal node construct."); PyErr_SetObject(parser_error, err); Py_XDECREF(err); diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 2f21ceb6f7ca..0d3fe5790b6d 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -6,7 +6,7 @@ functions are either unimplemented or implemented differently. The source assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent of the compiler used. Different compilers define their own feature - test macro, e.g. '__BORLANDC__' or '_MSC_VER'. */ + test macro, e.g. '_MSC_VER'. */ @@ -27,13 +27,10 @@ #include "Python.h" #ifndef MS_WINDOWS #include "posixmodule.h" +#else +#include "winreparse.h" #endif -#if defined(__VMS) -# error "PEP 11: VMS is now unsupported, code will be removed in Python 3.4" -# include -#endif /* defined(__VMS) */ - #ifdef __cplusplus extern "C" { #endif @@ -97,7 +94,7 @@ corresponding Unix manual entries for more information on calls."); #undef HAVE_SCHED_SETAFFINITY #endif -#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) +#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__) #define USE_XATTRS #endif @@ -146,13 +143,6 @@ corresponding Unix manual entries for more information on calls."); #define HAVE_SYSTEM 1 #include #else -#ifdef __BORLANDC__ /* Borland compiler */ -#define HAVE_EXECV 1 -#define HAVE_OPENDIR 1 -#define HAVE_PIPE 1 -#define HAVE_SYSTEM 1 -#define HAVE_WAIT 1 -#else #ifdef _MSC_VER /* Microsoft compiler */ #define HAVE_GETPPID 1 #define HAVE_GETLOGIN 1 @@ -164,9 +154,6 @@ corresponding Unix manual entries for more information on calls."); #define HAVE_FSYNC 1 #define fsync _commit #else -#if defined(__VMS) -/* Everything needed is defined in vms/pyconfig.h */ -#else /* all other compilers */ /* Unix functions that the configure script doesn't check for */ #define HAVE_EXECV 1 #define HAVE_FORK 1 @@ -184,16 +171,15 @@ corresponding Unix manual entries for more information on calls."); #define HAVE_SYSTEM 1 #define HAVE_WAIT 1 #define HAVE_TTYNAME 1 -#endif /* __VMS */ #endif /* _MSC_VER */ -#endif /* __BORLANDC__ */ #endif /* ! __WATCOMC__ || __QNX__ */ -/*[clinic] +/*[clinic input] +# one of the few times we lie about this name! module os -[clinic]*/ -/*[clinic checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=94a0f0f978acae17]*/ #ifndef _MSC_VER @@ -220,11 +206,7 @@ extern int rmdir(char *); extern int chdir(const char *); extern int rmdir(const char *); #endif -#ifdef __BORLANDC__ -extern int chmod(const char *, int); -#else extern int chmod(const char *, mode_t); -#endif /*#ifdef HAVE_FCHMOD extern int fchmod(int, mode_t); #endif*/ @@ -310,6 +292,9 @@ extern int lstat(const char *, struct stat *); #ifndef IO_REPARSE_TAG_SYMLINK #define IO_REPARSE_TAG_SYMLINK (0xA000000CL) #endif +#ifndef IO_REPARSE_TAG_MOUNT_POINT +#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L) +#endif #include "osdefs.h" #include #include @@ -365,8 +350,8 @@ static int win32_can_symlink = 0; #ifdef MS_WINDOWS # define STAT win32_stat # define LSTAT win32_lstat -# define FSTAT win32_fstat -# define STRUCT_STAT struct win32_stat +# define FSTAT _Py_fstat +# define STRUCT_STAT struct _Py_stat_struct #else # define STAT stat # define LSTAT lstat @@ -632,6 +617,29 @@ _Py_Gid_Converter(PyObject *obj, void *p) #endif /* MS_WINDOWS */ +#ifdef HAVE_LONG_LONG +# define _PyLong_FromDev PyLong_FromLongLong +#else +# define _PyLong_FromDev PyLong_FromLong +#endif + + +#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) +static int +_Py_Dev_Converter(PyObject *obj, void *p) +{ +#ifdef HAVE_LONG_LONG + *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj); +#else + *((dev_t *)p) = PyLong_AsUnsignedLong(obj); +#endif + if (PyErr_Occurred()) + return 0; + return 1; +} +#endif /* HAVE_MKNOD && HAVE_MAKEDEV */ + + #ifdef AT_FDCWD /* * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965); @@ -687,7 +695,6 @@ dir_fd_converter(PyObject *o, void *p) } - /* * A PyArg_ParseTuple "converter" function * that handles filesystem paths in the manner @@ -783,14 +790,13 @@ typedef struct { PyObject *cleanup; } path_t; -#define PATH_T_INITIALIZE(function_name, nullable, allow_fd) \ - {function_name, NULL, nullable, allow_fd, NULL, NULL, 0, 0, NULL, NULL} +#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \ + {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL} static void path_cleanup(path_t *path) { if (path->cleanup) { - Py_DECREF(path->cleanup); - path->cleanup = NULL; + Py_CLEAR(path->cleanup); } } @@ -907,8 +913,8 @@ path_converter(PyObject *o, void *p) { #endif narrow = PyBytes_AS_STRING(bytes); - if (length != strlen(narrow)) { - FORMAT_EXCEPTION(PyExc_ValueError, "embedded NUL character in %s"); + if ((size_t)length != strlen(narrow)) { + FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s"); Py_DECREF(bytes); return 0; } @@ -1009,21 +1015,35 @@ dir_fd_and_follow_symlinks_invalid(char *function_name, int dir_fd, return 0; } -/* A helper used by a number of POSIX-only functions */ -#ifndef MS_WINDOWS +#ifdef MS_WINDOWS + typedef PY_LONG_LONG Py_off_t; +#else + typedef off_t Py_off_t; +#endif + static int -_parse_off_t(PyObject* arg, void* addr) +Py_off_t_converter(PyObject *arg, void *addr) { -#if !defined(HAVE_LARGEFILE_SUPPORT) - *((off_t*)addr) = PyLong_AsLong(arg); +#ifdef HAVE_LARGEFILE_SUPPORT + *((Py_off_t *)addr) = PyLong_AsLongLong(arg); #else - *((off_t*)addr) = PyLong_AsLongLong(arg); + *((Py_off_t *)addr) = PyLong_AsLong(arg); #endif if (PyErr_Occurred()) return 0; return 1; } + +static PyObject * +PyLong_FromPy_off_t(Py_off_t offset) +{ +#ifdef HAVE_LARGEFILE_SUPPORT + return PyLong_FromLongLong(offset); +#else + return PyLong_FromLong(offset); #endif +} + #if defined _MSC_VER && _MSC_VER >= 1400 /* Microsoft CRT in VS2005 and higher will verify that a filehandle is @@ -1049,15 +1069,33 @@ _parse_off_t(PyObject* arg, void* addr) /* The actual size of the structure is determined at runtime. * Only the first items must be present. */ + +#if _MSC_VER >= 1900 + +typedef struct { + CRITICAL_SECTION lock; + intptr_t osfhnd; + __int64 startpos; + char osfile; +} my_ioinfo; + +#define IOINFO_L2E 6 +#define IOINFO_ARRAYS 128 + +#else + typedef struct { intptr_t osfhnd; char osfile; } my_ioinfo; -extern __declspec(dllimport) char * __pioinfo[]; #define IOINFO_L2E 5 -#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E) #define IOINFO_ARRAYS 64 + +#endif + +extern __declspec(dllimport) char * __pioinfo[]; +#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E) #define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS) #define FOPEN 0x01 #define _NO_CONSOLE_FILENO (intptr_t)-2 @@ -1119,41 +1157,6 @@ _PyVerify_fd_dup2(int fd1, int fd2) #endif #ifdef MS_WINDOWS -/* The following structure was copied from - http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required - include doesn't seem to be present in the Windows SDK (at least as included - with Visual Studio Express). */ -typedef struct _REPARSE_DATA_BUFFER { - ULONG ReparseTag; - USHORT ReparseDataLength; - USHORT Reserved; - union { - struct { - USHORT SubstituteNameOffset; - USHORT SubstituteNameLength; - USHORT PrintNameOffset; - USHORT PrintNameLength; - ULONG Flags; - WCHAR PathBuffer[1]; - } SymbolicLinkReparseBuffer; - - struct { - USHORT SubstituteNameOffset; - USHORT SubstituteNameLength; - USHORT PrintNameOffset; - USHORT PrintNameLength; - WCHAR PathBuffer[1]; - } MountPointReparseBuffer; - - struct { - UCHAR DataBuffer[1]; - } GenericReparseBuffer; - }; -} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; - -#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\ - GenericReparseBuffer) -#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 ) static int win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag) @@ -1323,49 +1326,51 @@ path_error(path_t *path) } +static PyObject * +path_error2(path_t *path, path_t *path2) +{ +#ifdef MS_WINDOWS + return PyErr_SetExcFromWindowsErrWithFilenameObjects(PyExc_OSError, + 0, path->object, path2->object); +#else + return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, + path->object, path2->object); +#endif +} + + /* POSIX generic methods */ -static PyObject * -posix_fildes(PyObject *fdobj, int (*func)(int)) +static int +fildes_converter(PyObject *o, void *p) { int fd; - int res; - fd = PyObject_AsFileDescriptor(fdobj); + int *pointer = (int *)p; + fd = PyObject_AsFileDescriptor(o); if (fd < 0) - return NULL; - if (!_PyVerify_fd(fd)) - return posix_error(); - Py_BEGIN_ALLOW_THREADS - res = (*func)(fd); - Py_END_ALLOW_THREADS - if (res < 0) - return posix_error(); - Py_INCREF(Py_None); - return Py_None; + return 0; + if (!_PyVerify_fd(fd)) { + posix_error(); + return 0; + } + *pointer = fd; + return 1; } static PyObject * -posix_1str(const char *func_name, PyObject *args, char *format, - int (*func)(const char*)) +posix_fildes_fd(int fd, int (*func)(int)) { - path_t path; int res; - memset(&path, 0, sizeof(path)); - path.function_name = func_name; - if (!PyArg_ParseTuple(args, format, - path_converter, &path)) - return NULL; - Py_BEGIN_ALLOW_THREADS - res = (*func)(path.narrow); - Py_END_ALLOW_THREADS - if (res < 0) { - path_error(&path); - path_cleanup(&path); - return NULL; - } - path_cleanup(&path); - Py_INCREF(Py_None); - return Py_None; + int async_err = 0; + + do { + Py_BEGIN_ALLOW_THREADS + res = (*func)(fd); + Py_END_ALLOW_THREADS + } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + if (res != 0) + return (!async_err) ? posix_error() : NULL; + Py_RETURN_NONE; } @@ -1444,89 +1449,7 @@ win32_wchdir(LPCWSTR path) Therefore, we implement our own stat, based on the Win32 API directly. */ #define HAVE_STAT_NSEC 1 - -struct win32_stat{ - unsigned long st_dev; - __int64 st_ino; - unsigned short st_mode; - int st_nlink; - int st_uid; - int st_gid; - unsigned long st_rdev; - __int64 st_size; - time_t st_atime; - int st_atime_nsec; - time_t st_mtime; - int st_mtime_nsec; - time_t st_ctime; - int st_ctime_nsec; -}; - -static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */ - -static void -FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out) -{ - /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */ - /* Cannot simply cast and dereference in_ptr, - since it might not be aligned properly */ - __int64 in; - memcpy(&in, in_ptr, sizeof(in)); - *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */ - *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t); -} - -static void -time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr) -{ - /* XXX endianness */ - __int64 out; - out = time_in + secs_between_epochs; - out = out * 10000000 + nsec_in / 100; - memcpy(out_ptr, &out, sizeof(out)); -} - -/* Below, we *know* that ugo+r is 0444 */ -#if _S_IREAD != 0400 -#error Unsupported C library -#endif -static int -attributes_to_mode(DWORD attr) -{ - int m = 0; - if (attr & FILE_ATTRIBUTE_DIRECTORY) - m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */ - else - m |= _S_IFREG; - if (attr & FILE_ATTRIBUTE_READONLY) - m |= 0444; - else - m |= 0666; - return m; -} - -static int -attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct win32_stat *result) -{ - memset(result, 0, sizeof(*result)); - result->st_mode = attributes_to_mode(info->dwFileAttributes); - result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow; - result->st_dev = info->dwVolumeSerialNumber; - result->st_rdev = result->st_dev; - FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec); - FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec); - FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec); - result->st_nlink = info->nNumberOfLinks; - result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow; - if (reparse_tag == IO_REPARSE_TAG_SYMLINK) { - /* first clear the S_IFMT bits */ - result->st_mode ^= (result->st_mode & S_IFMT); - /* now set the bits that make this a symlink */ - result->st_mode |= S_IFLNK; - } - - return 0; -} +#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1 static BOOL attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag) @@ -1612,7 +1535,7 @@ get_target_path(HANDLE hdl, wchar_t **target_path) if(!buf_size) return FALSE; - buf = (wchar_t *)PyMem_Malloc((buf_size+1)*sizeof(wchar_t)); + buf = PyMem_New(wchar_t, buf_size+1); if (!buf) { SetLastError(ERROR_OUTOFMEMORY); return FALSE; @@ -1637,11 +1560,15 @@ get_target_path(HANDLE hdl, wchar_t **target_path) return TRUE; } +/* defined in fileutils.c */ +void +_Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct _Py_stat_struct *result); + static int -win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result, +win32_xstat_impl_w(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse); static int -win32_xstat_impl(const char *path, struct win32_stat *result, +win32_xstat_impl(const char *path, struct _Py_stat_struct *result, BOOL traverse) { int code; @@ -1666,7 +1593,7 @@ win32_xstat_impl(const char *path, struct win32_stat *result, /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */ /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink. Because of this, calls like GetFinalPathNameByHandle will return - the symlink path agin and not the actual final path. */ + the symlink path again and not the actual final path. */ FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS| FILE_FLAG_OPEN_REPARSE_POINT, NULL); @@ -1724,7 +1651,7 @@ win32_xstat_impl(const char *path, struct win32_stat *result, } else CloseHandle(hFile); } - attribute_data_to_stat(&info, reparse_tag, result); + _Py_attribute_data_to_stat(&info, reparse_tag, result); /* Set S_IEXEC if it is an .exe, .bat, ... */ dot = strrchr(path, '.'); @@ -1737,7 +1664,7 @@ win32_xstat_impl(const char *path, struct win32_stat *result, } static int -win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result, +win32_xstat_impl_w(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse) { int code; @@ -1762,7 +1689,7 @@ win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result, /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */ /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink. Because of this, calls like GetFinalPathNameByHandle will return - the symlink path agin and not the actual final path. */ + the symlink path again and not the actual final path. */ FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS| FILE_FLAG_OPEN_REPARSE_POINT, NULL); @@ -1820,7 +1747,7 @@ win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result, } else CloseHandle(hFile); } - attribute_data_to_stat(&info, reparse_tag, result); + _Py_attribute_data_to_stat(&info, reparse_tag, result); /* Set S_IEXEC if it is an .exe, .bat, ... */ dot = wcsrchr(path, '.'); @@ -1833,7 +1760,7 @@ win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result, } static int -win32_xstat(const char *path, struct win32_stat *result, BOOL traverse) +win32_xstat(const char *path, struct _Py_stat_struct *result, BOOL traverse) { /* Protocol violation: we explicitly clear errno, instead of setting it to a POSIX error. Callers should use GetLastError. */ @@ -1843,7 +1770,7 @@ win32_xstat(const char *path, struct win32_stat *result, BOOL traverse) } static int -win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse) +win32_xstat_w(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse) { /* Protocol violation: we explicitly clear errno, instead of setting it to a POSIX error. Callers should use GetLastError. */ @@ -1865,80 +1792,29 @@ win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse) The _w represent Unicode equivalents of the aforementioned ANSI functions. */ static int -win32_lstat(const char* path, struct win32_stat *result) +win32_lstat(const char* path, struct _Py_stat_struct *result) { return win32_xstat(path, result, FALSE); } static int -win32_lstat_w(const wchar_t* path, struct win32_stat *result) +win32_lstat_w(const wchar_t* path, struct _Py_stat_struct *result) { return win32_xstat_w(path, result, FALSE); } static int -win32_stat(const char* path, struct win32_stat *result) +win32_stat(const char* path, struct _Py_stat_struct *result) { return win32_xstat(path, result, TRUE); } static int -win32_stat_w(const wchar_t* path, struct win32_stat *result) +win32_stat_w(const wchar_t* path, struct _Py_stat_struct *result) { return win32_xstat_w(path, result, TRUE); } -static int -win32_fstat(int file_number, struct win32_stat *result) -{ - BY_HANDLE_FILE_INFORMATION info; - HANDLE h; - int type; - - if (!_PyVerify_fd(file_number)) - h = INVALID_HANDLE_VALUE; - else - h = (HANDLE)_get_osfhandle(file_number); - - /* Protocol violation: we explicitly clear errno, instead of - setting it to a POSIX error. Callers should use GetLastError. */ - errno = 0; - - if (h == INVALID_HANDLE_VALUE) { - /* This is really a C library error (invalid file handle). - We set the Win32 error to the closes one matching. */ - SetLastError(ERROR_INVALID_HANDLE); - return -1; - } - memset(result, 0, sizeof(*result)); - - type = GetFileType(h); - if (type == FILE_TYPE_UNKNOWN) { - DWORD error = GetLastError(); - if (error != 0) { - return -1; - } - /* else: valid but unknown file */ - } - - if (type != FILE_TYPE_DISK) { - if (type == FILE_TYPE_CHAR) - result->st_mode = _S_IFCHR; - else if (type == FILE_TYPE_PIPE) - result->st_mode = _S_IFIFO; - return 0; - } - - if (!GetFileInformationByHandle(h, &info)) { - return -1; - } - - attribute_data_to_stat(&info, 0, result); - /* specific to fstat() */ - result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow; - return 0; -} - #endif /* MS_WINDOWS */ PyDoc_STRVAR(stat_result__doc__, @@ -1987,6 +1863,9 @@ static PyStructSequence_Field stat_result_fields[] = { #endif #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME {"st_birthtime", "time of creation"}, +#endif +#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES + {"st_file_attributes", "Windows file attribute bits"}, #endif {0} }; @@ -2027,6 +1906,12 @@ static PyStructSequence_Field stat_result_fields[] = { #define ST_BIRTHTIME_IDX ST_GEN_IDX #endif +#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES +#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1) +#else +#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX +#endif + static PyStructSequence_Desc stat_result_desc = { "stat_result", /* name */ stat_result__doc__, /* doc */ @@ -2128,10 +2013,12 @@ static int _stat_float_times = 1; PyDoc_STRVAR(stat_float_times__doc__, "stat_float_times([newval]) -> oldval\n\n\ Determine whether os.[lf]stat represents time stamps as float objects.\n\ -If newval is True, future calls to stat() return floats, if it is False,\n\ -future calls return ints. \n\ -If newval is omitted, return the current setting.\n"); +\n\ +If value is True, future calls to stat() return floats; if it is False,\n\ +future calls return ints.\n\ +If value is omitted, return the current setting.\n"); +/* AC 3.5: the public default value should be None, not ready for that yet */ static PyObject* stat_float_times(PyObject* self, PyObject *args) { @@ -2215,11 +2102,8 @@ _pystat_fromstructstat(STRUCT_STAT *st) #endif #ifdef MS_WINDOWS PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev)); -#elif defined(HAVE_LONG_LONG) - PyStructSequence_SET_ITEM(v, 2, - PyLong_FromLongLong((PY_LONG_LONG)st->st_dev)); #else - PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev)); + PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev)); #endif PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink)); #if defined(MS_WINDOWS) @@ -2294,6 +2178,10 @@ _pystat_fromstructstat(STRUCT_STAT *st) PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX, PyLong_FromLong((long)st->st_flags)); #endif +#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES + PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX, + PyLong_FromUnsignedLong(st->st_file_attributes)); +#endif if (PyErr_Occurred()) { Py_DECREF(v); @@ -2357,14 +2245,179 @@ posix_do_stat(char *function_name, path_t *path, return _pystat_fromstructstat(&st); } +/*[python input] + +for s in """ + +FACCESSAT +FCHMODAT +FCHOWNAT +FSTATAT +LINKAT +MKDIRAT +MKFIFOAT +MKNODAT +OPENAT +READLINKAT +SYMLINKAT +UNLINKAT + +""".strip().split(): + s = s.strip() + print(""" +#ifdef HAVE_{s} + #define {s}_DIR_FD_CONVERTER dir_fd_converter +#else + #define {s}_DIR_FD_CONVERTER dir_fd_unavailable +#endif +""".rstrip().format(s=s)) + +for s in """ + +FCHDIR +FCHMOD +FCHOWN +FDOPENDIR +FEXECVE +FPATHCONF +FSTATVFS +FTRUNCATE + +""".strip().split(): + s = s.strip() + print(""" +#ifdef HAVE_{s} + #define PATH_HAVE_{s} 1 +#else + #define PATH_HAVE_{s} 0 +#endif + +""".rstrip().format(s=s)) +[python start generated code]*/ + +#ifdef HAVE_FACCESSAT + #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable +#endif + +#ifdef HAVE_FCHMODAT + #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable +#endif + +#ifdef HAVE_FCHOWNAT + #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable +#endif + #ifdef HAVE_FSTATAT - #define OS_STAT_DIR_FD_CONVERTER dir_fd_converter + #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable +#endif + +#ifdef HAVE_LINKAT + #define LINKAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable +#endif + +#ifdef HAVE_MKDIRAT + #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable +#endif + +#ifdef HAVE_MKFIFOAT + #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable +#endif + +#ifdef HAVE_MKNODAT + #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable +#endif + +#ifdef HAVE_OPENAT + #define OPENAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable +#endif + +#ifdef HAVE_READLINKAT + #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable +#endif + +#ifdef HAVE_SYMLINKAT + #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable +#endif + +#ifdef HAVE_UNLINKAT + #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable +#endif + +#ifdef HAVE_FCHDIR + #define PATH_HAVE_FCHDIR 1 +#else + #define PATH_HAVE_FCHDIR 0 +#endif + +#ifdef HAVE_FCHMOD + #define PATH_HAVE_FCHMOD 1 +#else + #define PATH_HAVE_FCHMOD 0 +#endif + +#ifdef HAVE_FCHOWN + #define PATH_HAVE_FCHOWN 1 +#else + #define PATH_HAVE_FCHOWN 0 +#endif + +#ifdef HAVE_FDOPENDIR + #define PATH_HAVE_FDOPENDIR 1 +#else + #define PATH_HAVE_FDOPENDIR 0 +#endif + +#ifdef HAVE_FEXECVE + #define PATH_HAVE_FEXECVE 1 +#else + #define PATH_HAVE_FEXECVE 0 +#endif + +#ifdef HAVE_FPATHCONF + #define PATH_HAVE_FPATHCONF 1 +#else + #define PATH_HAVE_FPATHCONF 0 +#endif + +#ifdef HAVE_FSTATVFS + #define PATH_HAVE_FSTATVFS 1 +#else + #define PATH_HAVE_FSTATVFS 0 +#endif + +#ifdef HAVE_FTRUNCATE + #define PATH_HAVE_FTRUNCATE 1 #else - #define OS_STAT_DIR_FD_CONVERTER dir_fd_unavailable + #define PATH_HAVE_FTRUNCATE 0 #endif +/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/ -/*[python] +/*[python input] class path_t_converter(CConverter): @@ -2375,21 +2428,29 @@ class path_t_converter(CConverter): converter = 'path_converter' def converter_init(self, *, allow_fd=False, nullable=False): - def strify(value): - return str(int(bool(value))) - # right now path_t doesn't support default values. # to support a default value, you'll need to override initialize(). + if self.default not in (unspecified, None): + fail("Can't specify a default to the path_t converter!") - assert self.default is unspecified + if self.c_default not in (None, 'Py_None'): + raise RuntimeError("Can't specify a c_default to the path_t converter!") self.nullable = nullable self.allow_fd = allow_fd - self.c_default = 'PATH_T_INITIALIZE("{}", {}, {})'.format( + def pre_render(self): + def strify(value): + if isinstance(value, str): + return value + return str(int(bool(value))) + + # add self.py_name here when merging with posixmodule conversion + self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format( self.function.name, - strify(nullable), - strify(allow_fd), + self.name, + strify(self.nullable), + strify(self.allow_fd), ) def cleanup(self): @@ -2398,29 +2459,101 @@ class path_t_converter(CConverter): class dir_fd_converter(CConverter): type = 'int' - converter = 'OS_STAT_DIR_FD_CONVERTER' - def converter_init(self): + def converter_init(self, requires=None): if self.default in (unspecified, None): self.c_default = 'DEFAULT_DIR_FD' + if isinstance(requires, str): + self.converter = requires.upper() + '_DIR_FD_CONVERTER' + else: + self.converter = 'dir_fd_converter' +class fildes_converter(CConverter): + type = 'int' + converter = 'fildes_converter' -[python]*/ -/*[python checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ +class uid_t_converter(CConverter): + type = "uid_t" + converter = '_Py_Uid_Converter' -/*[clinic] +class gid_t_converter(CConverter): + type = "gid_t" + converter = '_Py_Gid_Converter' -os.stat -> object(doc_default='stat_result') +class dev_t_converter(CConverter): + type = 'dev_t' + converter = '_Py_Dev_Converter' - path : path_t(allow_fd=True) - Path to be examined; can be string, bytes, or open-file-descriptor int. +class dev_t_return_converter(unsigned_long_return_converter): + type = 'dev_t' + conversion_fn = '_PyLong_FromDev' + unsigned_cast = '(dev_t)' - * +class FSConverter_converter(CConverter): + type = 'PyObject *' + converter = 'PyUnicode_FSConverter' + def converter_init(self): + if self.default is not unspecified: + fail("FSConverter_converter does not support default values") + self.c_default = 'NULL' - dir_fd : dir_fd = None - If not None, it should be a file descriptor open to a directory, - and path should be a relative string; path will then be relative to - that directory. + def cleanup(self): + return "Py_XDECREF(" + self.name + ");\n" + +class pid_t_converter(CConverter): + type = 'pid_t' + format_unit = '" _Py_PARSE_PID "' + +class idtype_t_converter(int_converter): + type = 'idtype_t' + +class id_t_converter(CConverter): + type = 'id_t' + format_unit = '" _Py_PARSE_PID "' + +class Py_intptr_t_converter(CConverter): + type = 'Py_intptr_t' + format_unit = '" _Py_PARSE_INTPTR "' + +class Py_off_t_converter(CConverter): + type = 'Py_off_t' + converter = 'Py_off_t_converter' + +class Py_off_t_return_converter(long_return_converter): + type = 'Py_off_t' + conversion_fn = 'PyLong_FromPy_off_t' + +class path_confname_converter(CConverter): + type="int" + converter="conv_path_confname" + +class confstr_confname_converter(path_confname_converter): + converter='conv_confstr_confname' + +class sysconf_confname_converter(path_confname_converter): + converter="conv_sysconf_confname" + +class sched_param_converter(CConverter): + type = 'struct sched_param' + converter = 'convert_sched_param' + impl_by_reference = True; + +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=affe68316f160401]*/ + +/*[clinic input] + +os.stat + + path : path_t(allow_fd=True) + Path to be examined; can be string, bytes, or open-file-descriptor int. + + * + + dir_fd : dir_fd(requires='fstatat') = None + If not None, it should be a file descriptor open to a directory, + and path should be a relative string; path will then be relative to + that directory. follow_symlinks: bool = True If False, and the last element of the path is a symbolic link, @@ -2436,10 +2569,12 @@ dir_fd and follow_symlinks may not be implemented It's an error to use dir_fd or follow_symlinks when specifying path as an open file descriptor. -[clinic]*/ +[clinic start generated code]*/ PyDoc_STRVAR(os_stat__doc__, -"stat(path, *, dir_fd=None, follow_symlinks=True)\n" +"stat($module, /, path, *, dir_fd=None, follow_symlinks=True)\n" +"--\n" +"\n" "Perform a stat system call on the given path.\n" "\n" " path\n" @@ -2471,13 +2606,13 @@ os_stat(PyModuleDef *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; static char *_keywords[] = {"path", "dir_fd", "follow_symlinks", NULL}; - path_t path = PATH_T_INITIALIZE("stat", 0, 1); + path_t path = PATH_T_INITIALIZE("stat", "path", 0, 1); int dir_fd = DEFAULT_DIR_FD; int follow_symlinks = 1; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&p:stat", _keywords, - path_converter, &path, OS_STAT_DIR_FD_CONVERTER, &dir_fd, &follow_symlinks)) + path_converter, &path, FSTATAT_DIR_FD_CONVERTER, &dir_fd, &follow_symlinks)) goto exit; return_value = os_stat_impl(module, &path, dir_fd, follow_symlinks); @@ -2490,49 +2625,74 @@ os_stat(PyModuleDef *module, PyObject *args, PyObject *kwargs) static PyObject * os_stat_impl(PyModuleDef *module, path_t *path, int dir_fd, int follow_symlinks) -/*[clinic checksum: 85a71ad602e89f8e280118da976f70cd2f9abdf1]*/ +/*[clinic end generated code: output=0e9f9508fa0c0607 input=099d356c306fa24a]*/ { return posix_do_stat("stat", path, dir_fd, follow_symlinks); } -PyDoc_STRVAR(posix_lstat__doc__, -"lstat(path, *, dir_fd=None) -> stat result\n\n\ -Like stat(), but do not follow symbolic links.\n\ -Equivalent to stat(path, follow_symlinks=False)."); + +/*[clinic input] +os.lstat + + path : path_t + + * + + dir_fd : dir_fd(requires='fstatat') = None + +Perform a stat system call on the given path, without following symbolic links. + +Like stat(), but do not follow symbolic links. +Equivalent to stat(path, follow_symlinks=False). +[clinic start generated code]*/ + +PyDoc_STRVAR(os_lstat__doc__, +"lstat($module, /, path, *, dir_fd=None)\n" +"--\n" +"\n" +"Perform a stat system call on the given path, without following symbolic links.\n" +"\n" +"Like stat(), but do not follow symbolic links.\n" +"Equivalent to stat(path, follow_symlinks=False)."); + +#define OS_LSTAT_METHODDEF \ + {"lstat", (PyCFunction)os_lstat, METH_VARARGS|METH_KEYWORDS, os_lstat__doc__}, + +static PyObject * +os_lstat_impl(PyModuleDef *module, path_t *path, int dir_fd); static PyObject * -posix_lstat(PyObject *self, PyObject *args, PyObject *kwargs) +os_lstat(PyModuleDef *module, PyObject *args, PyObject *kwargs) { - static char *keywords[] = {"path", "dir_fd", NULL}; - path_t path; + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "dir_fd", NULL}; + path_t path = PATH_T_INITIALIZE("lstat", "path", 0, 0); int dir_fd = DEFAULT_DIR_FD; - int follow_symlinks = 0; - PyObject *return_value; - memset(&path, 0, sizeof(path)); - path.function_name = "lstat"; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:lstat", keywords, - path_converter, &path, -#ifdef HAVE_FSTATAT - dir_fd_converter, &dir_fd -#else - dir_fd_unavailable, &dir_fd -#endif - )) - return NULL; - return_value = posix_do_stat("lstat", &path, dir_fd, follow_symlinks); + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&|$O&:lstat", _keywords, + path_converter, &path, FSTATAT_DIR_FD_CONVERTER, &dir_fd)) + goto exit; + return_value = os_lstat_impl(module, &path, dir_fd); + +exit: + /* Cleanup for path */ path_cleanup(&path); + return return_value; } +static PyObject * +os_lstat_impl(PyModuleDef *module, path_t *path, int dir_fd) +/*[clinic end generated code: output=85702247224a2b1c input=0b7474765927b925]*/ +{ + int follow_symlinks = 0; + return posix_do_stat("lstat", path, dir_fd, follow_symlinks); +} + -#ifdef HAVE_FACCESSAT - #define OS_ACCESS_DIR_FD_CONVERTER dir_fd_converter -#else - #define OS_ACCESS_DIR_FD_CONVERTER dir_fd_unavailable -#endif -/*[clinic] -os.access -> object(doc_default='True if granted, False otherwise') +/*[clinic input] +os.access -> bool path: path_t(allow_fd=True) Path to be tested; can be string, bytes, or open-file-descriptor int. @@ -2543,7 +2703,7 @@ os.access -> object(doc_default='True if granted, False otherwise') * - dir_fd : dir_fd = None + dir_fd : dir_fd(requires='faccessat') = None If not None, it should be a file descriptor open to a directory, and path should be relative; path will then be relative to that directory. @@ -2568,10 +2728,13 @@ Note that most operations will use the effective uid/gid, therefore this routine can be used in a suid/sgid environment to test if the invoking user has the specified access to the path. -[clinic]*/ +[clinic start generated code]*/ PyDoc_STRVAR(os_access__doc__, -"access(path, mode, *, dir_fd=None, effective_ids=False, follow_symlinks=True)\n" +"access($module, /, path, mode, *, dir_fd=None, effective_ids=False,\n" +" follow_symlinks=True)\n" +"--\n" +"\n" "Use the real uid/gid to test for access to a path.\n" "\n" " path\n" @@ -2602,7 +2765,7 @@ PyDoc_STRVAR(os_access__doc__, #define OS_ACCESS_METHODDEF \ {"access", (PyCFunction)os_access, METH_VARARGS|METH_KEYWORDS, os_access__doc__}, -static PyObject * +static int os_access_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd, int effective_ids, int follow_symlinks); static PyObject * @@ -2610,17 +2773,21 @@ os_access(PyModuleDef *module, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; static char *_keywords[] = {"path", "mode", "dir_fd", "effective_ids", "follow_symlinks", NULL}; - path_t path = PATH_T_INITIALIZE("access", 0, 1); + path_t path = PATH_T_INITIALIZE("access", "path", 0, 1); int mode; int dir_fd = DEFAULT_DIR_FD; int effective_ids = 0; int follow_symlinks = 1; + int _return_value; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&pp:access", _keywords, - path_converter, &path, &mode, OS_STAT_DIR_FD_CONVERTER, &dir_fd, &effective_ids, &follow_symlinks)) + path_converter, &path, &mode, FACCESSAT_DIR_FD_CONVERTER, &dir_fd, &effective_ids, &follow_symlinks)) + goto exit; + _return_value = os_access_impl(module, &path, mode, dir_fd, effective_ids, follow_symlinks); + if ((_return_value == -1) && PyErr_Occurred()) goto exit; - return_value = os_access_impl(module, &path, mode, dir_fd, effective_ids, follow_symlinks); + return_value = PyBool_FromLong((long)_return_value); exit: /* Cleanup for path */ @@ -2629,11 +2796,11 @@ os_access(PyModuleDef *module, PyObject *args, PyObject *kwargs) return return_value; } -static PyObject * +static int os_access_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd, int effective_ids, int follow_symlinks) -/*[clinic checksum: 636e835c36562a2fc11acab75314634127fdf769]*/ +/*[clinic end generated code: output=dfd404666906f012 input=b75a756797af45ec]*/ { - PyObject *return_value = NULL; + int return_value; #ifdef MS_WINDOWS DWORD attr; @@ -2643,11 +2810,11 @@ os_access_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd, int effe #ifndef HAVE_FACCESSAT if (follow_symlinks_specified("access", follow_symlinks)) - goto exit; + return -1; if (effective_ids) { argument_unavailable_error("access", "effective_ids"); - goto exit; + return -1; } #endif @@ -2667,11 +2834,10 @@ os_access_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd, int effe * * or it's a directory. * (Directories cannot be read-only on Windows.) */ - return_value = PyBool_FromLong( - (attr != INVALID_FILE_ATTRIBUTES) && + return_value = (attr != INVALID_FILE_ATTRIBUTES) && (!(mode & 2) || !(attr & FILE_ATTRIBUTE_READONLY) || - (attr & FILE_ATTRIBUTE_DIRECTORY))); + (attr & FILE_ATTRIBUTE_DIRECTORY)); #else Py_BEGIN_ALLOW_THREADS @@ -2690,12 +2856,9 @@ os_access_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd, int effe #endif result = access(path->narrow, mode); Py_END_ALLOW_THREADS - return_value = PyBool_FromLong(!result); + return_value = !result; #endif -#ifndef HAVE_FACCESSAT -exit: -#endif return return_value; } @@ -2714,8 +2877,7 @@ os_access_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd, int effe #ifdef HAVE_TTYNAME - -/*[clinic] +/*[clinic input] os.ttyname -> DecodeFSDefault fd: int @@ -2724,10 +2886,12 @@ os.ttyname -> DecodeFSDefault / Return the name of the terminal device connected to 'fd'. -[clinic]*/ +[clinic start generated code]*/ PyDoc_STRVAR(os_ttyname__doc__, -"ttyname(fd)\n" +"ttyname($module, fd, /)\n" +"--\n" +"\n" "Return the name of the terminal device connected to \'fd\'.\n" "\n" " fd\n" @@ -2761,36 +2925,45 @@ os_ttyname(PyModuleDef *module, PyObject *args) static char * os_ttyname_impl(PyModuleDef *module, int fd) -/*[clinic checksum: 0f368134dc0a7f21f25185e2e6bacf7675fb473a]*/ +/*[clinic end generated code: output=cee7bc4cffec01a2 input=5f72ca83e76b3b45]*/ { char *ret; -#if defined(__VMS) - /* file descriptor 0 only, the default input device (stdin) */ - if (fd == 0) { - ret = ttyname(); - } - else { - ret = NULL; - } -#else ret = ttyname(fd); -#endif if (ret == NULL) posix_error(); return ret; } -#else -#define OS_TTYNAME_METHODDEF #endif #ifdef HAVE_CTERMID -PyDoc_STRVAR(posix_ctermid__doc__, -"ctermid() -> string\n\n\ -Return the name of the controlling terminal for this process."); +/*[clinic input] +os.ctermid + +Return the name of the controlling terminal for this process. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_ctermid__doc__, +"ctermid($module, /)\n" +"--\n" +"\n" +"Return the name of the controlling terminal for this process."); + +#define OS_CTERMID_METHODDEF \ + {"ctermid", (PyCFunction)os_ctermid, METH_NOARGS, os_ctermid__doc__}, + +static PyObject * +os_ctermid_impl(PyModuleDef *module); static PyObject * -posix_ctermid(PyObject *self, PyObject *noargs) +os_ctermid(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_ctermid_impl(module); +} + +static PyObject * +os_ctermid_impl(PyModuleDef *module) +/*[clinic end generated code: output=277bf7964ec2d782 input=3b87fdd52556382d]*/ { char *ret; char buffer[L_ctermid]; @@ -2804,106 +2977,234 @@ posix_ctermid(PyObject *self, PyObject *noargs) return posix_error(); return PyUnicode_DecodeFSDefault(buffer); } -#endif +#endif /* HAVE_CTERMID */ -PyDoc_STRVAR(posix_chdir__doc__, -"chdir(path)\n\n\ -Change the current working directory to the specified path.\n\ -\n\ -path may always be specified as a string.\n\ -On some platforms, path may also be specified as an open file descriptor.\n\ - If this functionality is unavailable, using it raises an exception."); + +/*[clinic input] +os.chdir + + path: path_t(allow_fd='PATH_HAVE_FCHDIR') + +Change the current working directory to the specified path. + +path may always be specified as a string. +On some platforms, path may also be specified as an open file descriptor. + If this functionality is unavailable, using it raises an exception. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_chdir__doc__, +"chdir($module, /, path)\n" +"--\n" +"\n" +"Change the current working directory to the specified path.\n" +"\n" +"path may always be specified as a string.\n" +"On some platforms, path may also be specified as an open file descriptor.\n" +" If this functionality is unavailable, using it raises an exception."); + +#define OS_CHDIR_METHODDEF \ + {"chdir", (PyCFunction)os_chdir, METH_VARARGS|METH_KEYWORDS, os_chdir__doc__}, + +static PyObject * +os_chdir_impl(PyModuleDef *module, path_t *path); static PyObject * -posix_chdir(PyObject *self, PyObject *args, PyObject *kwargs) +os_chdir(PyModuleDef *module, PyObject *args, PyObject *kwargs) { - path_t path; - int result; PyObject *return_value = NULL; - static char *keywords[] = {"path", NULL}; + static char *_keywords[] = {"path", NULL}; + path_t path = PATH_T_INITIALIZE("chdir", "path", 0, PATH_HAVE_FCHDIR); - memset(&path, 0, sizeof(path)); - path.function_name = "chdir"; -#ifdef HAVE_FCHDIR - path.allow_fd = 1; -#endif - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:chdir", keywords, - path_converter, &path - )) - return NULL; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&:chdir", _keywords, + path_converter, &path)) + goto exit; + return_value = os_chdir_impl(module, &path); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +static PyObject * +os_chdir_impl(PyModuleDef *module, path_t *path) +/*[clinic end generated code: output=cc07592dd23ca9e0 input=1a4a15b4d12cb15d]*/ +{ + int result; Py_BEGIN_ALLOW_THREADS #ifdef MS_WINDOWS - if (path.wide) - result = win32_wchdir(path.wide); + if (path->wide) + result = win32_wchdir(path->wide); else - result = win32_chdir(path.narrow); + result = win32_chdir(path->narrow); result = !result; /* on unix, success = 0, on windows, success = !0 */ #else #ifdef HAVE_FCHDIR - if (path.fd != -1) - result = fchdir(path.fd); + if (path->fd != -1) + result = fchdir(path->fd); else #endif - result = chdir(path.narrow); + result = chdir(path->narrow); #endif Py_END_ALLOW_THREADS if (result) { - return_value = path_error(&path); - goto exit; + return path_error(path); } - return_value = Py_None; - Py_INCREF(Py_None); + Py_RETURN_NONE; +} + + +#ifdef HAVE_FCHDIR +/*[clinic input] +os.fchdir + + fd: fildes + +Change to the directory of the given file descriptor. + +fd must be opened on a directory, not a file. +Equivalent to os.chdir(fd). + +[clinic start generated code]*/ + +PyDoc_STRVAR(os_fchdir__doc__, +"fchdir($module, /, fd)\n" +"--\n" +"\n" +"Change to the directory of the given file descriptor.\n" +"\n" +"fd must be opened on a directory, not a file.\n" +"Equivalent to os.chdir(fd)."); + +#define OS_FCHDIR_METHODDEF \ + {"fchdir", (PyCFunction)os_fchdir, METH_VARARGS|METH_KEYWORDS, os_fchdir__doc__}, + +static PyObject * +os_fchdir_impl(PyModuleDef *module, int fd); + +static PyObject * +os_fchdir(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"fd", NULL}; + int fd; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&:fchdir", _keywords, + fildes_converter, &fd)) + goto exit; + return_value = os_fchdir_impl(module, fd); exit: - path_cleanup(&path); return return_value; } -#ifdef HAVE_FCHDIR -PyDoc_STRVAR(posix_fchdir__doc__, -"fchdir(fd)\n\n\ -Change to the directory of the given file descriptor. fd must be\n\ -opened on a directory, not a file. Equivalent to os.chdir(fd)."); - static PyObject * -posix_fchdir(PyObject *self, PyObject *fdobj) +os_fchdir_impl(PyModuleDef *module, int fd) +/*[clinic end generated code: output=9f6dbc89b2778834 input=18e816479a2fa985]*/ { - return posix_fildes(fdobj, fchdir); + return posix_fildes_fd(fd, fchdir); } #endif /* HAVE_FCHDIR */ -PyDoc_STRVAR(posix_chmod__doc__, -"chmod(path, mode, *, dir_fd=None, follow_symlinks=True)\n\n\ -Change the access permissions of a file.\n\ -\n\ -path may always be specified as a string.\n\ -On some platforms, path may also be specified as an open file descriptor.\n\ - If this functionality is unavailable, using it raises an exception.\n\ -If dir_fd is not None, it should be a file descriptor open to a directory,\n\ - and path should be relative; path will then be relative to that directory.\n\ -If follow_symlinks is False, and the last element of the path is a symbolic\n\ - link, chmod will modify the symbolic link itself instead of the file the\n\ - link points to.\n\ -It is an error to use dir_fd or follow_symlinks when specifying path as\n\ - an open file descriptor.\n\ -dir_fd and follow_symlinks may not be implemented on your platform.\n\ - If they are unavailable, using them will raise a NotImplementedError."); +/*[clinic input] +os.chmod + + path: path_t(allow_fd='PATH_HAVE_FCHMOD') + Path to be modified. May always be specified as a str or bytes. + On some platforms, path may also be specified as an open file descriptor. + If this functionality is unavailable, using it raises an exception. + + mode: int + Operating-system mode bitfield. + + * + + dir_fd : dir_fd(requires='fchmodat') = None + If not None, it should be a file descriptor open to a directory, + and path should be relative; path will then be relative to that + directory. + + follow_symlinks: bool = True + If False, and the last element of the path is a symbolic link, + chmod will modify the symbolic link itself instead of the file + the link points to. + +Change the access permissions of a file. + +It is an error to use dir_fd or follow_symlinks when specifying path as + an open file descriptor. +dir_fd and follow_symlinks may not be implemented on your platform. + If they are unavailable, using them will raise a NotImplementedError. + +[clinic start generated code]*/ + +PyDoc_STRVAR(os_chmod__doc__, +"chmod($module, /, path, mode, *, dir_fd=None, follow_symlinks=True)\n" +"--\n" +"\n" +"Change the access permissions of a file.\n" +"\n" +" path\n" +" Path to be modified. May always be specified as a str or bytes.\n" +" On some platforms, path may also be specified as an open file descriptor.\n" +" If this functionality is unavailable, using it raises an exception.\n" +" mode\n" +" Operating-system mode bitfield.\n" +" dir_fd\n" +" If not None, it should be a file descriptor open to a directory,\n" +" and path should be relative; path will then be relative to that\n" +" directory.\n" +" follow_symlinks\n" +" If False, and the last element of the path is a symbolic link,\n" +" chmod will modify the symbolic link itself instead of the file\n" +" the link points to.\n" +"\n" +"It is an error to use dir_fd or follow_symlinks when specifying path as\n" +" an open file descriptor.\n" +"dir_fd and follow_symlinks may not be implemented on your platform.\n" +" If they are unavailable, using them will raise a NotImplementedError."); + +#define OS_CHMOD_METHODDEF \ + {"chmod", (PyCFunction)os_chmod, METH_VARARGS|METH_KEYWORDS, os_chmod__doc__}, + +static PyObject * +os_chmod_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd, int follow_symlinks); static PyObject * -posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs) +os_chmod(PyModuleDef *module, PyObject *args, PyObject *kwargs) { - path_t path; + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "mode", "dir_fd", "follow_symlinks", NULL}; + path_t path = PATH_T_INITIALIZE("chmod", "path", 0, PATH_HAVE_FCHMOD); int mode; int dir_fd = DEFAULT_DIR_FD; int follow_symlinks = 1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&i|$O&p:chmod", _keywords, + path_converter, &path, &mode, FCHMODAT_DIR_FD_CONVERTER, &dir_fd, &follow_symlinks)) + goto exit; + return_value = os_chmod_impl(module, &path, mode, dir_fd, follow_symlinks); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +static PyObject * +os_chmod_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd, int follow_symlinks) +/*[clinic end generated code: output=1e9db031aea46422 input=7f1618e5e15cc196]*/ +{ int result; - PyObject *return_value = NULL; - static char *keywords[] = {"path", "mode", "dir_fd", - "follow_symlinks", NULL}; #ifdef MS_WINDOWS DWORD attr; @@ -2913,33 +3214,17 @@ posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs) int fchmodat_nofollow_unsupported = 0; #endif - memset(&path, 0, sizeof(path)); - path.function_name = "chmod"; -#ifdef HAVE_FCHMOD - path.allow_fd = 1; -#endif - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&p:chmod", keywords, - path_converter, &path, - &mode, -#ifdef HAVE_FCHMODAT - dir_fd_converter, &dir_fd, -#else - dir_fd_unavailable, &dir_fd, -#endif - &follow_symlinks)) - return NULL; - #if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD)) if (follow_symlinks_specified("chmod", follow_symlinks)) - goto exit; + return NULL; #endif #ifdef MS_WINDOWS Py_BEGIN_ALLOW_THREADS - if (path.wide) - attr = GetFileAttributesW(path.wide); + if (path->wide) + attr = GetFileAttributesW(path->wide); else - attr = GetFileAttributesA(path.narrow); + attr = GetFileAttributesA(path->narrow); if (attr == INVALID_FILE_ATTRIBUTES) result = 0; else { @@ -2947,27 +3232,26 @@ posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs) attr &= ~FILE_ATTRIBUTE_READONLY; else attr |= FILE_ATTRIBUTE_READONLY; - if (path.wide) - result = SetFileAttributesW(path.wide, attr); + if (path->wide) + result = SetFileAttributesW(path->wide, attr); else - result = SetFileAttributesA(path.narrow, attr); + result = SetFileAttributesA(path->narrow, attr); } Py_END_ALLOW_THREADS if (!result) { - return_value = path_error(&path); - goto exit; + return path_error(path); } #else /* MS_WINDOWS */ Py_BEGIN_ALLOW_THREADS #ifdef HAVE_FCHMOD - if (path.fd != -1) - result = fchmod(path.fd, mode); + if (path->fd != -1) + result = fchmod(path->fd, mode); else #endif #ifdef HAVE_LCHMOD if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD)) - result = lchmod(path.narrow, mode); + result = lchmod(path->narrow, mode); else #endif #ifdef HAVE_FCHMODAT @@ -2982,7 +3266,7 @@ posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs) * support dir_fd and follow_symlinks=False. (Hopefully.) * Until then, we need to be careful what exception we raise. */ - result = fchmodat(dir_fd, path.narrow, mode, + result = fchmodat(dir_fd, path->narrow, mode, follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW); /* * But wait! We can't throw the exception without allowing threads, @@ -2995,7 +3279,7 @@ posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs) } else #endif - result = chmod(path.narrow, mode); + result = chmod(path->narrow, mode); Py_END_ALLOW_THREADS if (result) { @@ -3009,272 +3293,599 @@ posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs) } else #endif - return_value = path_error(&path); - goto exit; + return path_error(path); } #endif - Py_INCREF(Py_None); - return_value = Py_None; -exit: - path_cleanup(&path); - return return_value; + Py_RETURN_NONE; } #ifdef HAVE_FCHMOD -PyDoc_STRVAR(posix_fchmod__doc__, -"fchmod(fd, mode)\n\n\ -Change the access permissions of the file given by file\n\ -descriptor fd. Equivalent to os.chmod(fd, mode)."); +/*[clinic input] +os.fchmod -static PyObject * -posix_fchmod(PyObject *self, PyObject *args) -{ - int fd, mode, res; - if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode)) - return NULL; - Py_BEGIN_ALLOW_THREADS - res = fchmod(fd, mode); - Py_END_ALLOW_THREADS - if (res < 0) - return posix_error(); - Py_RETURN_NONE; -} -#endif /* HAVE_FCHMOD */ + fd: int + mode: int -#ifdef HAVE_LCHMOD -PyDoc_STRVAR(posix_lchmod__doc__, -"lchmod(path, mode)\n\n\ -Change the access permissions of a file. If path is a symlink, this\n\ -affects the link itself rather than the target.\n\ -Equivalent to chmod(path, mode, follow_symlinks=False)."); +Change the access permissions of the file given by file descriptor fd. + +Equivalent to os.chmod(fd, mode). +[clinic start generated code]*/ + +PyDoc_STRVAR(os_fchmod__doc__, +"fchmod($module, /, fd, mode)\n" +"--\n" +"\n" +"Change the access permissions of the file given by file descriptor fd.\n" +"\n" +"Equivalent to os.chmod(fd, mode)."); + +#define OS_FCHMOD_METHODDEF \ + {"fchmod", (PyCFunction)os_fchmod, METH_VARARGS|METH_KEYWORDS, os_fchmod__doc__}, + +static PyObject * +os_fchmod_impl(PyModuleDef *module, int fd, int mode); static PyObject * -posix_lchmod(PyObject *self, PyObject *args) +os_fchmod(PyModuleDef *module, PyObject *args, PyObject *kwargs) { - path_t path; - int i; - int res; - memset(&path, 0, sizeof(path)); - path.function_name = "lchmod"; - if (!PyArg_ParseTuple(args, "O&i:lchmod", - path_converter, &path, &i)) - return NULL; + PyObject *return_value = NULL; + static char *_keywords[] = {"fd", "mode", NULL}; + int fd; + int mode; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "ii:fchmod", _keywords, + &fd, &mode)) + goto exit; + return_value = os_fchmod_impl(module, fd, mode); + +exit: + return return_value; +} + +static PyObject * +os_fchmod_impl(PyModuleDef *module, int fd, int mode) +/*[clinic end generated code: output=3c19fbfd724a8e0f input=8ab11975ca01ee5b]*/ +{ + int res; + int async_err = 0; + + do { + Py_BEGIN_ALLOW_THREADS + res = fchmod(fd, mode); + Py_END_ALLOW_THREADS + } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + if (res != 0) + return (!async_err) ? posix_error() : NULL; + + Py_RETURN_NONE; +} +#endif /* HAVE_FCHMOD */ + + +#ifdef HAVE_LCHMOD +/*[clinic input] +os.lchmod + + path: path_t + mode: int + +Change the access permissions of a file, without following symbolic links. + +If path is a symlink, this affects the link itself rather than the target. +Equivalent to chmod(path, mode, follow_symlinks=False)." +[clinic start generated code]*/ + +PyDoc_STRVAR(os_lchmod__doc__, +"lchmod($module, /, path, mode)\n" +"--\n" +"\n" +"Change the access permissions of a file, without following symbolic links.\n" +"\n" +"If path is a symlink, this affects the link itself rather than the target.\n" +"Equivalent to chmod(path, mode, follow_symlinks=False).\""); + +#define OS_LCHMOD_METHODDEF \ + {"lchmod", (PyCFunction)os_lchmod, METH_VARARGS|METH_KEYWORDS, os_lchmod__doc__}, + +static PyObject * +os_lchmod_impl(PyModuleDef *module, path_t *path, int mode); + +static PyObject * +os_lchmod(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "mode", NULL}; + path_t path = PATH_T_INITIALIZE("lchmod", "path", 0, 0); + int mode; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&i:lchmod", _keywords, + path_converter, &path, &mode)) + goto exit; + return_value = os_lchmod_impl(module, &path, mode); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +static PyObject * +os_lchmod_impl(PyModuleDef *module, path_t *path, int mode) +/*[clinic end generated code: output=2849977d65f8c68c input=90c5663c7465d24f]*/ +{ + int res; Py_BEGIN_ALLOW_THREADS - res = lchmod(path.narrow, i); + res = lchmod(path->narrow, mode); Py_END_ALLOW_THREADS if (res < 0) { - path_error(&path); - path_cleanup(&path); + path_error(path); return NULL; } - path_cleanup(&path); Py_RETURN_NONE; } #endif /* HAVE_LCHMOD */ #ifdef HAVE_CHFLAGS -PyDoc_STRVAR(posix_chflags__doc__, -"chflags(path, flags, *, follow_symlinks=True)\n\n\ -Set file flags.\n\ -\n\ -If follow_symlinks is False, and the last element of the path is a symbolic\n\ - link, chflags will change flags on the symbolic link itself instead of the\n\ - file the link points to.\n\ -follow_symlinks may not be implemented on your platform. If it is\n\ -unavailable, using it will raise a NotImplementedError."); +/*[clinic input] +os.chflags + + path: path_t + flags: unsigned_long(bitwise=True) + follow_symlinks: bool=True + +Set file flags. + +If follow_symlinks is False, and the last element of the path is a symbolic + link, chflags will change flags on the symbolic link itself instead of the + file the link points to. +follow_symlinks may not be implemented on your platform. If it is +unavailable, using it will raise a NotImplementedError. + +[clinic start generated code]*/ + +PyDoc_STRVAR(os_chflags__doc__, +"chflags($module, /, path, flags, follow_symlinks=True)\n" +"--\n" +"\n" +"Set file flags.\n" +"\n" +"If follow_symlinks is False, and the last element of the path is a symbolic\n" +" link, chflags will change flags on the symbolic link itself instead of the\n" +" file the link points to.\n" +"follow_symlinks may not be implemented on your platform. If it is\n" +"unavailable, using it will raise a NotImplementedError."); + +#define OS_CHFLAGS_METHODDEF \ + {"chflags", (PyCFunction)os_chflags, METH_VARARGS|METH_KEYWORDS, os_chflags__doc__}, + +static PyObject * +os_chflags_impl(PyModuleDef *module, path_t *path, unsigned long flags, int follow_symlinks); static PyObject * -posix_chflags(PyObject *self, PyObject *args, PyObject *kwargs) +os_chflags(PyModuleDef *module, PyObject *args, PyObject *kwargs) { - path_t path; + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "flags", "follow_symlinks", NULL}; + path_t path = PATH_T_INITIALIZE("chflags", "path", 0, 0); unsigned long flags; int follow_symlinks = 1; - int result; - PyObject *return_value = NULL; - static char *keywords[] = {"path", "flags", "follow_symlinks", NULL}; - memset(&path, 0, sizeof(path)); - path.function_name = "chflags"; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&k|$i:chflags", keywords, - path_converter, &path, - &flags, &follow_symlinks)) - return NULL; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&k|p:chflags", _keywords, + path_converter, &path, &flags, &follow_symlinks)) + goto exit; + return_value = os_chflags_impl(module, &path, flags, follow_symlinks); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +static PyObject * +os_chflags_impl(PyModuleDef *module, path_t *path, unsigned long flags, int follow_symlinks) +/*[clinic end generated code: output=2767927bf071e3cf input=0327e29feb876236]*/ +{ + int result; #ifndef HAVE_LCHFLAGS if (follow_symlinks_specified("chflags", follow_symlinks)) - goto exit; + return NULL; #endif Py_BEGIN_ALLOW_THREADS #ifdef HAVE_LCHFLAGS if (!follow_symlinks) - result = lchflags(path.narrow, flags); + result = lchflags(path->narrow, flags); else #endif - result = chflags(path.narrow, flags); + result = chflags(path->narrow, flags); Py_END_ALLOW_THREADS - if (result) { - return_value = path_error(&path); - goto exit; - } - - return_value = Py_None; - Py_INCREF(Py_None); + if (result) + return path_error(path); -exit: - path_cleanup(&path); - return return_value; + Py_RETURN_NONE; } #endif /* HAVE_CHFLAGS */ + #ifdef HAVE_LCHFLAGS -PyDoc_STRVAR(posix_lchflags__doc__, -"lchflags(path, flags)\n\n\ -Set file flags.\n\ -This function will not follow symbolic links.\n\ -Equivalent to chflags(path, flags, follow_symlinks=False)."); +/*[clinic input] +os.lchflags + + path: path_t + flags: unsigned_long(bitwise=True) + +Set file flags. + +This function will not follow symbolic links. +Equivalent to chflags(path, flags, follow_symlinks=False). +[clinic start generated code]*/ + +PyDoc_STRVAR(os_lchflags__doc__, +"lchflags($module, /, path, flags)\n" +"--\n" +"\n" +"Set file flags.\n" +"\n" +"This function will not follow symbolic links.\n" +"Equivalent to chflags(path, flags, follow_symlinks=False)."); + +#define OS_LCHFLAGS_METHODDEF \ + {"lchflags", (PyCFunction)os_lchflags, METH_VARARGS|METH_KEYWORDS, os_lchflags__doc__}, + +static PyObject * +os_lchflags_impl(PyModuleDef *module, path_t *path, unsigned long flags); static PyObject * -posix_lchflags(PyObject *self, PyObject *args) +os_lchflags(PyModuleDef *module, PyObject *args, PyObject *kwargs) { - path_t path; + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "flags", NULL}; + path_t path = PATH_T_INITIALIZE("lchflags", "path", 0, 0); unsigned long flags; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&k:lchflags", _keywords, + path_converter, &path, &flags)) + goto exit; + return_value = os_lchflags_impl(module, &path, flags); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +static PyObject * +os_lchflags_impl(PyModuleDef *module, path_t *path, unsigned long flags) +/*[clinic end generated code: output=bb93b6b8a5e45aa7 input=f9f82ea8b585ca9d]*/ +{ int res; - memset(&path, 0, sizeof(path)); - path.function_name = "lchflags"; - if (!PyArg_ParseTuple(args, "O&k:lchflags", - path_converter, &path, &flags)) - return NULL; Py_BEGIN_ALLOW_THREADS - res = lchflags(path.narrow, flags); + res = lchflags(path->narrow, flags); Py_END_ALLOW_THREADS if (res < 0) { - path_error(&path); - path_cleanup(&path); - return NULL; + return path_error(path); } - path_cleanup(&path); Py_RETURN_NONE; } #endif /* HAVE_LCHFLAGS */ + #ifdef HAVE_CHROOT -PyDoc_STRVAR(posix_chroot__doc__, -"chroot(path)\n\n\ -Change root directory to path."); +/*[clinic input] +os.chroot + path: path_t + +Change root directory to path. + +[clinic start generated code]*/ + +PyDoc_STRVAR(os_chroot__doc__, +"chroot($module, /, path)\n" +"--\n" +"\n" +"Change root directory to path."); + +#define OS_CHROOT_METHODDEF \ + {"chroot", (PyCFunction)os_chroot, METH_VARARGS|METH_KEYWORDS, os_chroot__doc__}, + +static PyObject * +os_chroot_impl(PyModuleDef *module, path_t *path); + +static PyObject * +os_chroot(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", NULL}; + path_t path = PATH_T_INITIALIZE("chroot", "path", 0, 0); + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&:chroot", _keywords, + path_converter, &path)) + goto exit; + return_value = os_chroot_impl(module, &path); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} static PyObject * -posix_chroot(PyObject *self, PyObject *args) +os_chroot_impl(PyModuleDef *module, path_t *path) +/*[clinic end generated code: output=15b1256cbe4f24a1 input=14822965652c3dc3]*/ { - return posix_1str("chroot", args, "O&:chroot", chroot); + int res; + Py_BEGIN_ALLOW_THREADS + res = chroot(path->narrow); + Py_END_ALLOW_THREADS + if (res < 0) + return path_error(path); + Py_RETURN_NONE; } -#endif +#endif /* HAVE_CHROOT */ + #ifdef HAVE_FSYNC -PyDoc_STRVAR(posix_fsync__doc__, -"fsync(fildes)\n\n\ -force write of file with filedescriptor to disk."); +/*[clinic input] +os.fsync + + fd: fildes + +Force write of fd to disk. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_fsync__doc__, +"fsync($module, /, fd)\n" +"--\n" +"\n" +"Force write of fd to disk."); + +#define OS_FSYNC_METHODDEF \ + {"fsync", (PyCFunction)os_fsync, METH_VARARGS|METH_KEYWORDS, os_fsync__doc__}, + +static PyObject * +os_fsync_impl(PyModuleDef *module, int fd); + +static PyObject * +os_fsync(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"fd", NULL}; + int fd; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&:fsync", _keywords, + fildes_converter, &fd)) + goto exit; + return_value = os_fsync_impl(module, fd); + +exit: + return return_value; +} static PyObject * -posix_fsync(PyObject *self, PyObject *fdobj) +os_fsync_impl(PyModuleDef *module, int fd) +/*[clinic end generated code: output=59f32d3a0b360133 input=21c3645c056967f2]*/ { - return posix_fildes(fdobj, fsync); + return posix_fildes_fd(fd, fsync); } #endif /* HAVE_FSYNC */ + #ifdef HAVE_SYNC -PyDoc_STRVAR(posix_sync__doc__, -"sync()\n\n\ -Force write of everything to disk."); +/*[clinic input] +os.sync + +Force write of everything to disk. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_sync__doc__, +"sync($module, /)\n" +"--\n" +"\n" +"Force write of everything to disk."); + +#define OS_SYNC_METHODDEF \ + {"sync", (PyCFunction)os_sync, METH_NOARGS, os_sync__doc__}, + +static PyObject * +os_sync_impl(PyModuleDef *module); + +static PyObject * +os_sync(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_sync_impl(module); +} static PyObject * -posix_sync(PyObject *self, PyObject *noargs) +os_sync_impl(PyModuleDef *module) +/*[clinic end generated code: output=526c495683d0bb38 input=84749fe5e9b404ff]*/ { Py_BEGIN_ALLOW_THREADS sync(); Py_END_ALLOW_THREADS Py_RETURN_NONE; } -#endif +#endif /* HAVE_SYNC */ -#ifdef HAVE_FDATASYNC +#ifdef HAVE_FDATASYNC #ifdef __hpux extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */ #endif -PyDoc_STRVAR(posix_fdatasync__doc__, -"fdatasync(fildes)\n\n\ -force write of file with filedescriptor to disk.\n\ - does not force update of metadata."); +/*[clinic input] +os.fdatasync + + fd: fildes + +Force write of fd to disk without forcing update of metadata. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_fdatasync__doc__, +"fdatasync($module, /, fd)\n" +"--\n" +"\n" +"Force write of fd to disk without forcing update of metadata."); + +#define OS_FDATASYNC_METHODDEF \ + {"fdatasync", (PyCFunction)os_fdatasync, METH_VARARGS|METH_KEYWORDS, os_fdatasync__doc__}, + +static PyObject * +os_fdatasync_impl(PyModuleDef *module, int fd); + +static PyObject * +os_fdatasync(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"fd", NULL}; + int fd; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&:fdatasync", _keywords, + fildes_converter, &fd)) + goto exit; + return_value = os_fdatasync_impl(module, fd); + +exit: + return return_value; +} static PyObject * -posix_fdatasync(PyObject *self, PyObject *fdobj) +os_fdatasync_impl(PyModuleDef *module, int fd) +/*[clinic end generated code: output=2335fdfd37c92180 input=bc74791ee54dd291]*/ { - return posix_fildes(fdobj, fdatasync); + return posix_fildes_fd(fd, fdatasync); } #endif /* HAVE_FDATASYNC */ #ifdef HAVE_CHOWN -PyDoc_STRVAR(posix_chown__doc__, -"chown(path, uid, gid, *, dir_fd=None, follow_symlinks=True)\n\n\ -Change the owner and group id of path to the numeric uid and gid.\n\ -\n\ -path may always be specified as a string.\n\ -On some platforms, path may also be specified as an open file descriptor.\n\ - If this functionality is unavailable, using it raises an exception.\n\ -If dir_fd is not None, it should be a file descriptor open to a directory,\n\ - and path should be relative; path will then be relative to that directory.\n\ -If follow_symlinks is False, and the last element of the path is a symbolic\n\ - link, chown will modify the symbolic link itself instead of the file the\n\ - link points to.\n\ -It is an error to use dir_fd or follow_symlinks when specifying path as\n\ - an open file descriptor.\n\ -dir_fd and follow_symlinks may not be implemented on your platform.\n\ - If they are unavailable, using them will raise a NotImplementedError."); +/*[clinic input] +os.chown + + path : path_t(allow_fd='PATH_HAVE_FCHOWN') + Path to be examined; can be string, bytes, or open-file-descriptor int. + + uid: uid_t + + gid: gid_t + + * + + dir_fd : dir_fd(requires='fchownat') = None + If not None, it should be a file descriptor open to a directory, + and path should be relative; path will then be relative to that + directory. + + follow_symlinks: bool = True + If False, and the last element of the path is a symbolic link, + stat will examine the symbolic link itself instead of the file + the link points to. + +Change the owner and group id of path to the numeric uid and gid.\ + +path may always be specified as a string. +On some platforms, path may also be specified as an open file descriptor. + If this functionality is unavailable, using it raises an exception. +If dir_fd is not None, it should be a file descriptor open to a directory, + and path should be relative; path will then be relative to that directory. +If follow_symlinks is False, and the last element of the path is a symbolic + link, chown will modify the symbolic link itself instead of the file the + link points to. +It is an error to use dir_fd or follow_symlinks when specifying path as + an open file descriptor. +dir_fd and follow_symlinks may not be implemented on your platform. + If they are unavailable, using them will raise a NotImplementedError. + +[clinic start generated code]*/ + +PyDoc_STRVAR(os_chown__doc__, +"chown($module, /, path, uid, gid, *, dir_fd=None, follow_symlinks=True)\n" +"--\n" +"\n" +"Change the owner and group id of path to the numeric uid and gid.\\\n" +"\n" +" path\n" +" Path to be examined; can be string, bytes, or 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 relative; path will then be relative to that\n" +" directory.\n" +" follow_symlinks\n" +" If False, and the last element of the path is a symbolic link,\n" +" stat will examine the symbolic link itself instead of the file\n" +" the link points to.\n" +"\n" +"path may always be specified as a string.\n" +"On some platforms, path may also be specified as an open file descriptor.\n" +" If this functionality is unavailable, using it raises an exception.\n" +"If dir_fd is not None, it should be a file descriptor open to a directory,\n" +" and path should be relative; path will then be relative to that directory.\n" +"If follow_symlinks is False, and the last element of the path is a symbolic\n" +" link, chown will modify the symbolic link itself instead of the file the\n" +" link points to.\n" +"It is an error to use dir_fd or follow_symlinks when specifying path as\n" +" an open file descriptor.\n" +"dir_fd and follow_symlinks may not be implemented on your platform.\n" +" If they are unavailable, using them will raise a NotImplementedError."); + +#define OS_CHOWN_METHODDEF \ + {"chown", (PyCFunction)os_chown, METH_VARARGS|METH_KEYWORDS, os_chown__doc__}, static PyObject * -posix_chown(PyObject *self, PyObject *args, PyObject *kwargs) +os_chown_impl(PyModuleDef *module, path_t *path, uid_t uid, gid_t gid, int dir_fd, int follow_symlinks); + +static PyObject * +os_chown(PyModuleDef *module, PyObject *args, PyObject *kwargs) { - path_t path; + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "uid", "gid", "dir_fd", "follow_symlinks", NULL}; + path_t path = PATH_T_INITIALIZE("chown", "path", 0, PATH_HAVE_FCHOWN); uid_t uid; gid_t gid; int dir_fd = DEFAULT_DIR_FD; int follow_symlinks = 1; - int result; - PyObject *return_value = NULL; - static char *keywords[] = {"path", "uid", "gid", "dir_fd", - "follow_symlinks", NULL}; - memset(&path, 0, sizeof(path)); - path.function_name = "chown"; -#ifdef HAVE_FCHOWN - path.allow_fd = 1; -#endif - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&O&|$O&p:chown", keywords, - path_converter, &path, - _Py_Uid_Converter, &uid, - _Py_Gid_Converter, &gid, -#ifdef HAVE_FCHOWNAT - dir_fd_converter, &dir_fd, -#else - dir_fd_unavailable, &dir_fd, -#endif - &follow_symlinks)) - return NULL; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&O&O&|$O&p:chown", _keywords, + path_converter, &path, _Py_Uid_Converter, &uid, _Py_Gid_Converter, &gid, FCHOWNAT_DIR_FD_CONVERTER, &dir_fd, &follow_symlinks)) + goto exit; + return_value = os_chown_impl(module, &path, uid, gid, dir_fd, follow_symlinks); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +static PyObject * +os_chown_impl(PyModuleDef *module, path_t *path, uid_t uid, gid_t gid, int dir_fd, int follow_symlinks) +/*[clinic end generated code: output=22f011e3b4f9ff49 input=a61cc35574814d5d]*/ +{ + int result; #if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT)) if (follow_symlinks_specified("chown", follow_symlinks)) - goto exit; + return NULL; #endif - if (dir_fd_and_fd_invalid("chown", dir_fd, path.fd) || - fd_and_follow_symlinks_invalid("chown", path.fd, follow_symlinks)) - goto exit; + if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) || + fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks)) + return NULL; #ifdef __APPLE__ /* @@ -3285,102 +3896,168 @@ posix_chown(PyObject *self, PyObject *args, PyObject *kwargs) */ if ((!follow_symlinks) && (lchown == NULL)) { follow_symlinks_specified("chown", follow_symlinks); - goto exit; + return NULL; } #endif Py_BEGIN_ALLOW_THREADS #ifdef HAVE_FCHOWN - if (path.fd != -1) - result = fchown(path.fd, uid, gid); + if (path->fd != -1) + result = fchown(path->fd, uid, gid); else #endif #ifdef HAVE_LCHOWN if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD)) - result = lchown(path.narrow, uid, gid); + result = lchown(path->narrow, uid, gid); else #endif #ifdef HAVE_FCHOWNAT if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks)) - result = fchownat(dir_fd, path.narrow, uid, gid, + result = fchownat(dir_fd, path->narrow, uid, gid, follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW); else #endif - result = chown(path.narrow, uid, gid); + result = chown(path->narrow, uid, gid); Py_END_ALLOW_THREADS - if (result) { - return_value = path_error(&path); - goto exit; - } - - return_value = Py_None; - Py_INCREF(Py_None); + if (result) + return path_error(path); -exit: - path_cleanup(&path); - return return_value; + Py_RETURN_NONE; } #endif /* HAVE_CHOWN */ + #ifdef HAVE_FCHOWN -PyDoc_STRVAR(posix_fchown__doc__, -"fchown(fd, uid, gid)\n\n\ -Change the owner and group id of the file given by file descriptor\n\ -fd to the numeric uid and gid. Equivalent to os.chown(fd, uid, gid)."); +/*[clinic input] +os.fchown + + fd: int + uid: uid_t + gid: gid_t + +Change the owner and group id of the file specified by file descriptor. + +Equivalent to os.chown(fd, uid, gid). + +[clinic start generated code]*/ + +PyDoc_STRVAR(os_fchown__doc__, +"fchown($module, /, fd, uid, gid)\n" +"--\n" +"\n" +"Change the owner and group id of the file specified by file descriptor.\n" +"\n" +"Equivalent to os.chown(fd, uid, gid)."); + +#define OS_FCHOWN_METHODDEF \ + {"fchown", (PyCFunction)os_fchown, METH_VARARGS|METH_KEYWORDS, os_fchown__doc__}, + +static PyObject * +os_fchown_impl(PyModuleDef *module, int fd, uid_t uid, gid_t gid); static PyObject * -posix_fchown(PyObject *self, PyObject *args) +os_fchown(PyModuleDef *module, PyObject *args, PyObject *kwargs) { + PyObject *return_value = NULL; + static char *_keywords[] = {"fd", "uid", "gid", NULL}; int fd; uid_t uid; gid_t gid; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "iO&O&:fchown", _keywords, + &fd, _Py_Uid_Converter, &uid, _Py_Gid_Converter, &gid)) + goto exit; + return_value = os_fchown_impl(module, fd, uid, gid); + +exit: + return return_value; +} + +static PyObject * +os_fchown_impl(PyModuleDef *module, int fd, uid_t uid, gid_t gid) +/*[clinic end generated code: output=687781cb7d8974d6 input=3af544ba1b13a0d7]*/ +{ int res; - if (!PyArg_ParseTuple(args, "iO&O&:fchown", &fd, - _Py_Uid_Converter, &uid, - _Py_Gid_Converter, &gid)) - return NULL; - Py_BEGIN_ALLOW_THREADS - res = fchown(fd, uid, gid); - Py_END_ALLOW_THREADS - if (res < 0) - return posix_error(); + int async_err = 0; + + do { + Py_BEGIN_ALLOW_THREADS + res = fchown(fd, uid, gid); + Py_END_ALLOW_THREADS + } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + if (res != 0) + return (!async_err) ? posix_error() : NULL; + Py_RETURN_NONE; } #endif /* HAVE_FCHOWN */ + #ifdef HAVE_LCHOWN -PyDoc_STRVAR(posix_lchown__doc__, -"lchown(path, uid, gid)\n\n\ -Change the owner and group id of path to the numeric uid and gid.\n\ -This function will not follow symbolic links.\n\ -Equivalent to os.chown(path, uid, gid, follow_symlinks=False)."); +/*[clinic input] +os.lchown + + path : path_t + uid: uid_t + gid: gid_t + +Change the owner and group id of path to the numeric uid and gid. + +This function will not follow symbolic links. +Equivalent to os.chown(path, uid, gid, follow_symlinks=False). +[clinic start generated code]*/ + +PyDoc_STRVAR(os_lchown__doc__, +"lchown($module, /, path, uid, gid)\n" +"--\n" +"\n" +"Change the owner and group id of path to the numeric uid and gid.\n" +"\n" +"This function will not follow symbolic links.\n" +"Equivalent to os.chown(path, uid, gid, follow_symlinks=False)."); + +#define OS_LCHOWN_METHODDEF \ + {"lchown", (PyCFunction)os_lchown, METH_VARARGS|METH_KEYWORDS, os_lchown__doc__}, static PyObject * -posix_lchown(PyObject *self, PyObject *args) +os_lchown_impl(PyModuleDef *module, path_t *path, uid_t uid, gid_t gid); + +static PyObject * +os_lchown(PyModuleDef *module, PyObject *args, PyObject *kwargs) { - path_t path; + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "uid", "gid", NULL}; + path_t path = PATH_T_INITIALIZE("lchown", "path", 0, 0); uid_t uid; gid_t gid; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&O&O&:lchown", _keywords, + path_converter, &path, _Py_Uid_Converter, &uid, _Py_Gid_Converter, &gid)) + goto exit; + return_value = os_lchown_impl(module, &path, uid, gid); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +static PyObject * +os_lchown_impl(PyModuleDef *module, path_t *path, uid_t uid, gid_t gid) +/*[clinic end generated code: output=bf25fdb0d25130e2 input=b1c6014d563a7161]*/ +{ int res; - memset(&path, 0, sizeof(path)); - path.function_name = "lchown"; - if (!PyArg_ParseTuple(args, "O&O&O&:lchown", - path_converter, &path, - _Py_Uid_Converter, &uid, - _Py_Gid_Converter, &gid)) - return NULL; Py_BEGIN_ALLOW_THREADS - res = lchown(path.narrow, uid, gid); + res = lchown(path->narrow, uid, gid); Py_END_ALLOW_THREADS if (res < 0) { - path_error(&path); - path_cleanup(&path); - return NULL; + return path_error(path); } - path_cleanup(&path); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } #endif /* HAVE_LCHOWN */ @@ -3437,148 +4114,209 @@ posix_getcwd(int use_bytes) return PyUnicode_DecodeFSDefault(buf); } -PyDoc_STRVAR(posix_getcwd__doc__, -"getcwd() -> path\n\n\ -Return a unicode string representing the current working directory."); + +/*[clinic input] +os.getcwd + +Return a unicode string representing the current working directory. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_getcwd__doc__, +"getcwd($module, /)\n" +"--\n" +"\n" +"Return a unicode string representing the current working directory."); + +#define OS_GETCWD_METHODDEF \ + {"getcwd", (PyCFunction)os_getcwd, METH_NOARGS, os_getcwd__doc__}, static PyObject * -posix_getcwd_unicode(PyObject *self) +os_getcwd_impl(PyModuleDef *module); + +static PyObject * +os_getcwd(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_getcwd_impl(module); +} + +static PyObject * +os_getcwd_impl(PyModuleDef *module) +/*[clinic end generated code: output=d70b281db5c78ff7 input=f069211bb70e3d39]*/ { return posix_getcwd(0); } -PyDoc_STRVAR(posix_getcwdb__doc__, -"getcwdb() -> path\n\n\ -Return a bytes string representing the current working directory."); + +/*[clinic input] +os.getcwdb + +Return a bytes string representing the current working directory. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_getcwdb__doc__, +"getcwdb($module, /)\n" +"--\n" +"\n" +"Return a bytes string representing the current working directory."); + +#define OS_GETCWDB_METHODDEF \ + {"getcwdb", (PyCFunction)os_getcwdb, METH_NOARGS, os_getcwdb__doc__}, + +static PyObject * +os_getcwdb_impl(PyModuleDef *module); + +static PyObject * +os_getcwdb(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_getcwdb_impl(module); +} static PyObject * -posix_getcwd_bytes(PyObject *self) +os_getcwdb_impl(PyModuleDef *module) +/*[clinic end generated code: output=75da47f2d75f9166 input=f6f6a378dad3d9cb]*/ { return posix_getcwd(1); } + #if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS)) #define HAVE_LINK 1 #endif #ifdef HAVE_LINK -PyDoc_STRVAR(posix_link__doc__, -"link(src, dst, *, src_dir_fd=None, dst_dir_fd=None, follow_symlinks=True)\n\n\ -Create a hard link to a file.\n\ -\n\ -If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\ - descriptor open to a directory, and the respective path string (src or dst)\n\ - should be relative; the path will then be relative to that directory.\n\ -If follow_symlinks is False, and the last element of src is a symbolic\n\ - link, link will create a link to the symbolic link itself instead of the\n\ - file the link points to.\n\ -src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your\n\ - platform. If they are unavailable, using them will raise a\n\ - NotImplementedError."); +/*[clinic input] + +os.link + + src : path_t + dst : path_t + * + src_dir_fd : dir_fd = None + dst_dir_fd : dir_fd = None + follow_symlinks: bool = True + +Create a hard link to a file. + +If either src_dir_fd or dst_dir_fd is not None, it should be a file + descriptor open to a directory, and the respective path string (src or dst) + should be relative; the path will then be relative to that directory. +If follow_symlinks is False, and the last element of src is a symbolic + link, link will create a link to the symbolic link itself instead of the + file the link points to. +src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your + platform. If they are unavailable, using them will raise a + NotImplementedError. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_link__doc__, +"link($module, /, src, dst, *, src_dir_fd=None, dst_dir_fd=None,\n" +" follow_symlinks=True)\n" +"--\n" +"\n" +"Create a hard link to a file.\n" +"\n" +"If either src_dir_fd or dst_dir_fd is not None, it should be a file\n" +" descriptor open to a directory, and the respective path string (src or dst)\n" +" should be relative; the path will then be relative to that directory.\n" +"If follow_symlinks is False, and the last element of src is a symbolic\n" +" link, link will create a link to the symbolic link itself instead of the\n" +" file the link points to.\n" +"src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your\n" +" platform. If they are unavailable, using them will raise a\n" +" NotImplementedError."); + +#define OS_LINK_METHODDEF \ + {"link", (PyCFunction)os_link, METH_VARARGS|METH_KEYWORDS, os_link__doc__}, + +static PyObject * +os_link_impl(PyModuleDef *module, path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd, int follow_symlinks); static PyObject * -posix_link(PyObject *self, PyObject *args, PyObject *kwargs) +os_link(PyModuleDef *module, PyObject *args, PyObject *kwargs) { - path_t src, dst; + PyObject *return_value = NULL; + static char *_keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", "follow_symlinks", NULL}; + path_t src = PATH_T_INITIALIZE("link", "src", 0, 0); + path_t dst = PATH_T_INITIALIZE("link", "dst", 0, 0); int src_dir_fd = DEFAULT_DIR_FD; int dst_dir_fd = DEFAULT_DIR_FD; int follow_symlinks = 1; - PyObject *return_value = NULL; - static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", - "follow_symlinks", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&O&|$O&O&p:link", _keywords, + path_converter, &src, path_converter, &dst, dir_fd_converter, &src_dir_fd, dir_fd_converter, &dst_dir_fd, &follow_symlinks)) + goto exit; + return_value = os_link_impl(module, &src, &dst, src_dir_fd, dst_dir_fd, follow_symlinks); + +exit: + /* Cleanup for src */ + path_cleanup(&src); + /* Cleanup for dst */ + path_cleanup(&dst); + + return return_value; +} + +static PyObject * +os_link_impl(PyModuleDef *module, path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd, int follow_symlinks) +/*[clinic end generated code: output=53477662fe02e183 input=b0095ebbcbaa7e04]*/ +{ #ifdef MS_WINDOWS BOOL result; #else int result; #endif - memset(&src, 0, sizeof(src)); - memset(&dst, 0, sizeof(dst)); - src.function_name = "link"; - dst.function_name = "link"; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|O&O&p:link", keywords, - path_converter, &src, - path_converter, &dst, - dir_fd_converter, &src_dir_fd, - dir_fd_converter, &dst_dir_fd, - &follow_symlinks)) - return NULL; - #ifndef HAVE_LINKAT if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) { argument_unavailable_error("link", "src_dir_fd and dst_dir_fd"); - goto exit; + return NULL; } #endif - if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) { + if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) { PyErr_SetString(PyExc_NotImplementedError, "link: src and dst must be the same type"); - goto exit; + return NULL; } #ifdef MS_WINDOWS Py_BEGIN_ALLOW_THREADS - if (src.wide) - result = CreateHardLinkW(dst.wide, src.wide, NULL); + if (src->wide) + result = CreateHardLinkW(dst->wide, src->wide, NULL); else - result = CreateHardLinkA(dst.narrow, src.narrow, NULL); + result = CreateHardLinkA(dst->narrow, src->narrow, NULL); Py_END_ALLOW_THREADS - if (!result) { - return_value = path_error(&src); - goto exit; - } + if (!result) + return path_error2(src, dst); #else Py_BEGIN_ALLOW_THREADS #ifdef HAVE_LINKAT if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks)) - result = linkat(src_dir_fd, src.narrow, - dst_dir_fd, dst.narrow, + result = linkat(src_dir_fd, src->narrow, + dst_dir_fd, dst->narrow, follow_symlinks ? AT_SYMLINK_FOLLOW : 0); else #endif - result = link(src.narrow, dst.narrow); + result = link(src->narrow, dst->narrow); Py_END_ALLOW_THREADS - if (result) { - return_value = path_error(&src); - goto exit; - } + if (result) + return path_error2(src, dst); #endif - return_value = Py_None; - Py_INCREF(Py_None); - -exit: - path_cleanup(&src); - path_cleanup(&dst); - return return_value; + Py_RETURN_NONE; } #endif - -PyDoc_STRVAR(posix_listdir__doc__, -"listdir(path='.') -> list_of_filenames\n\n\ -Return a list containing the names of the files in the directory.\n\ -The list is in arbitrary order. It does not include the special\n\ -entries '.' and '..' even if they are present in the directory.\n\ -\n\ -path can be specified as either str or bytes. If path is bytes,\n\ - the filenames returned will also be bytes; in all other circumstances\n\ - the filenames returned will be str.\n\ -On some platforms, path may also be specified as an open file descriptor;\n\ - the file descriptor must refer to a directory.\n\ - If this functionality is unavailable, using it raises NotImplementedError."); - #if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR) static PyObject * _listdir_windows_no_opendir(path_t *path, PyObject *list) { - static char *keywords[] = {"path", NULL}; PyObject *v; HANDLE hFindFile = INVALID_HANDLE_VALUE; BOOL result; @@ -3602,7 +4340,7 @@ _listdir_windows_no_opendir(path_t *path, PyObject *list) len = wcslen(path->wide); } /* The +5 is so we can append "\\*.*\0" */ - wnamebuf = PyMem_Malloc((len + 5) * sizeof(wchar_t)); + wnamebuf = PyMem_New(wchar_t, len + 5); if (!wnamebuf) { PyErr_NoMemory(); goto exit; @@ -3746,10 +4484,8 @@ _posix_listdir(path_t *path, PyObject *list) if (path->fd != -1) { /* closedir() closes the FD, so we duplicate it */ fd = _Py_dup(path->fd); - if (fd == -1) { - list = posix_error(); - goto exit; - } + if (fd == -1) + return NULL; return_str = 1; @@ -3839,38 +4575,85 @@ _posix_listdir(path_t *path, PyObject *list) } /* end of _posix_listdir */ #endif /* which OS */ + +/*[clinic input] +os.listdir + + path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None + +Return a list containing the names of the files in the directory. + +path can be specified as either str or bytes. If path is bytes, + the filenames returned will also be bytes; in all other circumstances + the filenames returned will be str. +If path is None, uses the path='.'. +On some platforms, path may also be specified as an open file descriptor;\ + the file descriptor must refer to a directory. + If this functionality is unavailable, using it raises NotImplementedError. + +The list is in arbitrary order. It does not include the special +entries '.' and '..' even if they are present in the directory. + + +[clinic start generated code]*/ + +PyDoc_STRVAR(os_listdir__doc__, +"listdir($module, /, path=None)\n" +"--\n" +"\n" +"Return a list containing the names of the files in the directory.\n" +"\n" +"path can be specified as either str or bytes. If path is bytes,\n" +" the filenames returned will also be bytes; in all other circumstances\n" +" the filenames returned will be str.\n" +"If path is None, uses the path=\'.\'.\n" +"On some platforms, path may also be specified as an open file descriptor;\\\n" +" the file descriptor must refer to a directory.\n" +" If this functionality is unavailable, using it raises NotImplementedError.\n" +"\n" +"The list is in arbitrary order. It does not include the special\n" +"entries \'.\' and \'..\' even if they are present in the directory."); + +#define OS_LISTDIR_METHODDEF \ + {"listdir", (PyCFunction)os_listdir, METH_VARARGS|METH_KEYWORDS, os_listdir__doc__}, + +static PyObject * +os_listdir_impl(PyModuleDef *module, path_t *path); + static PyObject * -posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs) +os_listdir(PyModuleDef *module, PyObject *args, PyObject *kwargs) { - path_t path; - PyObject *list = NULL; - static char *keywords[] = {"path", NULL}; - PyObject *return_value; + PyObject *return_value = NULL; + static char *_keywords[] = {"path", NULL}; + path_t path = PATH_T_INITIALIZE("listdir", "path", 1, PATH_HAVE_FDOPENDIR); - memset(&path, 0, sizeof(path)); - path.function_name = "listdir"; - path.nullable = 1; -#ifdef HAVE_FDOPENDIR - path.allow_fd = 1; - path.fd = -1; -#endif + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "|O&:listdir", _keywords, + path_converter, &path)) + goto exit; + return_value = os_listdir_impl(module, &path); - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:listdir", keywords, - path_converter, &path)) { - return NULL; - } +exit: + /* Cleanup for path */ + path_cleanup(&path); + return return_value; +} + +static PyObject * +os_listdir_impl(PyModuleDef *module, path_t *path) +/*[clinic end generated code: output=e159bd9be6909018 input=09e300416e3cd729]*/ +{ #if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR) - return_value = _listdir_windows_no_opendir(&path, list); + return _listdir_windows_no_opendir(path, NULL); #else - return_value = _posix_listdir(&path, list); + return _posix_listdir(path, NULL); #endif - path_cleanup(&path); - return return_value; } #ifdef MS_WINDOWS /* A helper function for abspath on win32 */ +/* AC 3.5: probably just convert to using path converter */ static PyObject * posix__getfullpathname(PyObject *self, PyObject *args) { @@ -3894,7 +4677,7 @@ posix__getfullpathname(PyObject *self, PyObject *args) Py_ARRAY_LENGTH(woutbuf), woutbuf, &wtemp); if (result > Py_ARRAY_LENGTH(woutbuf)) { - woutbufp = PyMem_Malloc(result * sizeof(wchar_t)); + woutbufp = PyMem_New(wchar_t, result); if (!woutbufp) return PyErr_NoMemory(); result = GetFullPathNameW(wpath, result, woutbufp, &wtemp); @@ -3926,25 +4709,59 @@ posix__getfullpathname(PyObject *self, PyObject *args) Py_FileSystemDefaultEncoding, NULL); } return PyBytes_FromString(outbuf); -} /* end of posix__getfullpathname */ +} + + +/*[clinic input] +os._getfinalpathname + + path: unicode + / +A helper function for samepath on windows. +[clinic start generated code]*/ +PyDoc_STRVAR(os__getfinalpathname__doc__, +"_getfinalpathname($module, path, /)\n" +"--\n" +"\n" +"A helper function for samepath on windows."); + +#define OS__GETFINALPATHNAME_METHODDEF \ + {"_getfinalpathname", (PyCFunction)os__getfinalpathname, METH_VARARGS, os__getfinalpathname__doc__}, + +static PyObject * +os__getfinalpathname_impl(PyModuleDef *module, PyObject *path); + +static PyObject * +os__getfinalpathname(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *path; + + if (!PyArg_ParseTuple(args, + "U:_getfinalpathname", + &path)) + goto exit; + return_value = os__getfinalpathname_impl(module, path); + +exit: + return return_value; +} -/* A helper function for samepath on windows */ static PyObject * -posix__getfinalpathname(PyObject *self, PyObject *args) +os__getfinalpathname_impl(PyModuleDef *module, PyObject *path) +/*[clinic end generated code: output=4563c6eacf1b0881 input=71d5e89334891bf4]*/ { HANDLE hFile; int buf_size; wchar_t *target_path; int result_length; - PyObject *po, *result; - wchar_t *path; + PyObject *result; + wchar_t *path_wchar; - if (!PyArg_ParseTuple(args, "U|:_getfinalpathname", &po)) - return NULL; - path = PyUnicode_AsUnicode(po); - if (path == NULL) + path_wchar = PyUnicode_AsUnicode(path); + if (path_wchar == NULL) return NULL; if(!check_GetFinalPathNameByHandle()) { @@ -3955,7 +4772,7 @@ posix__getfinalpathname(PyObject *self, PyObject *args) } hFile = CreateFileW( - path, + path_wchar, 0, /* desired access */ 0, /* share mode */ NULL, /* security attributes */ @@ -3965,37 +4782,37 @@ posix__getfinalpathname(PyObject *self, PyObject *args) NULL); if(hFile == INVALID_HANDLE_VALUE) - return win32_error_object("CreateFileW", po); + return win32_error_object("CreateFileW", path); /* We have a good handle to the target, use it to determine the target path name. */ buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT); if(!buf_size) - return win32_error_object("GetFinalPathNameByHandle", po); + return win32_error_object("GetFinalPathNameByHandle", path); - target_path = (wchar_t *)PyMem_Malloc((buf_size+1)*sizeof(wchar_t)); + target_path = PyMem_New(wchar_t, buf_size+1); if(!target_path) return PyErr_NoMemory(); result_length = Py_GetFinalPathNameByHandleW(hFile, target_path, buf_size, VOLUME_NAME_DOS); if(!result_length) - return win32_error_object("GetFinalPathNamyByHandle", po); + return win32_error_object("GetFinalPathNamyByHandle", path); if(!CloseHandle(hFile)) - return win32_error_object("CloseHandle", po); + return win32_error_object("CloseHandle", path); target_path[result_length] = 0; result = PyUnicode_FromWideChar(target_path, result_length); PyMem_Free(target_path); return result; - -} /* end of posix__getfinalpathname */ +} PyDoc_STRVAR(posix__isdir__doc__, "Return true if the pathname refers to an existing directory."); +/* AC 3.5: convert using path converter */ static PyObject * posix__isdir(PyObject *self, PyObject *args) { @@ -4032,22 +4849,55 @@ posix__isdir(PyObject *self, PyObject *args) Py_RETURN_FALSE; } -PyDoc_STRVAR(posix__getvolumepathname__doc__, -"Return volume mount point of the specified path."); -/* A helper function for ismount on windows */ +/*[clinic input] +os._getvolumepathname + + path: unicode + +A helper function for ismount on Win32. +[clinic start generated code]*/ + +PyDoc_STRVAR(os__getvolumepathname__doc__, +"_getvolumepathname($module, /, path)\n" +"--\n" +"\n" +"A helper function for ismount on Win32."); + +#define OS__GETVOLUMEPATHNAME_METHODDEF \ + {"_getvolumepathname", (PyCFunction)os__getvolumepathname, METH_VARARGS|METH_KEYWORDS, os__getvolumepathname__doc__}, + +static PyObject * +os__getvolumepathname_impl(PyModuleDef *module, PyObject *path); + static PyObject * -posix__getvolumepathname(PyObject *self, PyObject *args) +os__getvolumepathname(PyModuleDef *module, PyObject *args, PyObject *kwargs) { - PyObject *po, *result; - wchar_t *path, *mountpath=NULL; + PyObject *return_value = NULL; + static char *_keywords[] = {"path", NULL}; + PyObject *path; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "U:_getvolumepathname", _keywords, + &path)) + goto exit; + return_value = os__getvolumepathname_impl(module, path); + +exit: + return return_value; +} + +static PyObject * +os__getvolumepathname_impl(PyModuleDef *module, PyObject *path) +/*[clinic end generated code: output=ac0833b6d6da7657 input=7eacadc40acbda6b]*/ +{ + PyObject *result; + wchar_t *path_wchar, *mountpath=NULL; size_t buflen; BOOL ret; - if (!PyArg_ParseTuple(args, "U|:_getvolumepathname", &po)) - return NULL; - path = PyUnicode_AsUnicodeAndSize(po, &buflen); - if (path == NULL) + path_wchar = PyUnicode_AsUnicodeAndSize(path, &buflen); + if (path_wchar == NULL) return NULL; buflen += 1; @@ -4059,17 +4909,17 @@ posix__getvolumepathname(PyObject *self, PyObject *args) return NULL; } - mountpath = (wchar_t *)PyMem_Malloc(buflen * sizeof(wchar_t)); + mountpath = PyMem_New(wchar_t, buflen); if (mountpath == NULL) return PyErr_NoMemory(); Py_BEGIN_ALLOW_THREADS - ret = GetVolumePathNameW(path, mountpath, + ret = GetVolumePathNameW(path_wchar, mountpath, Py_SAFE_DOWNCAST(buflen, size_t, DWORD)); Py_END_ALLOW_THREADS if (!ret) { - result = win32_error_object("_getvolumepathname", po); + result = win32_error_object("_getvolumepathname", path); goto exit; } result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath)); @@ -4078,78 +4928,107 @@ posix__getvolumepathname(PyObject *self, PyObject *args) PyMem_Free(mountpath); return result; } -/* end of posix__getvolumepathname */ #endif /* MS_WINDOWS */ -PyDoc_STRVAR(posix_mkdir__doc__, -"mkdir(path, mode=0o777, *, dir_fd=None)\n\n\ -Create a directory.\n\ -\n\ -If dir_fd is not None, it should be a file descriptor open to a directory,\n\ - and path should be relative; path will then be relative to that directory.\n\ -dir_fd may not be implemented on your platform.\n\ - If it is unavailable, using it will raise a NotImplementedError.\n\ -\n\ -The mode argument is ignored on Windows."); + +/*[clinic input] +os.mkdir + + path : path_t + + mode: int = 0o777 + + * + + dir_fd : dir_fd(requires='mkdirat') = None + +# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\ + +Create a directory. + +If dir_fd is not None, it should be a file descriptor open to a directory, + and path should be relative; path will then be relative to that directory. +dir_fd may not be implemented on your platform. + If it is unavailable, using it will raise a NotImplementedError. + +The mode argument is ignored on Windows. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_mkdir__doc__, +"mkdir($module, /, path, mode=511, *, dir_fd=None)\n" +"--\n" +"\n" +"Create a directory.\n" +"\n" +"If dir_fd is not None, it should be a file descriptor open to a directory,\n" +" and path should be relative; path will then be relative to that directory.\n" +"dir_fd may not be implemented on your platform.\n" +" If it is unavailable, using it will raise a NotImplementedError.\n" +"\n" +"The mode argument is ignored on Windows."); + +#define OS_MKDIR_METHODDEF \ + {"mkdir", (PyCFunction)os_mkdir, METH_VARARGS|METH_KEYWORDS, os_mkdir__doc__}, + +static PyObject * +os_mkdir_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd); static PyObject * -posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs) +os_mkdir(PyModuleDef *module, PyObject *args, PyObject *kwargs) { - path_t path; - int mode = 0777; - int dir_fd = DEFAULT_DIR_FD; - static char *keywords[] = {"path", "mode", "dir_fd", NULL}; PyObject *return_value = NULL; - int result; + static char *_keywords[] = {"path", "mode", "dir_fd", NULL}; + path_t path = PATH_T_INITIALIZE("mkdir", "path", 0, 0); + int mode = 511; + int dir_fd = DEFAULT_DIR_FD; - memset(&path, 0, sizeof(path)); - path.function_name = "mkdir"; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkdir", keywords, - path_converter, &path, &mode, -#ifdef HAVE_MKDIRAT - dir_fd_converter, &dir_fd -#else - dir_fd_unavailable, &dir_fd -#endif - )) - return NULL; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&|i$O&:mkdir", _keywords, + path_converter, &path, &mode, MKDIRAT_DIR_FD_CONVERTER, &dir_fd)) + goto exit; + return_value = os_mkdir_impl(module, &path, mode, dir_fd); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +static PyObject * +os_mkdir_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd) +/*[clinic end generated code: output=55c6ef2bc1b207e6 input=e965f68377e9b1ce]*/ +{ + int result; #ifdef MS_WINDOWS Py_BEGIN_ALLOW_THREADS - if (path.wide) - result = CreateDirectoryW(path.wide, NULL); + if (path->wide) + result = CreateDirectoryW(path->wide, NULL); else - result = CreateDirectoryA(path.narrow, NULL); + result = CreateDirectoryA(path->narrow, NULL); Py_END_ALLOW_THREADS - if (!result) { - return_value = path_error(&path); - goto exit; - } + if (!result) + return path_error(path); #else Py_BEGIN_ALLOW_THREADS #if HAVE_MKDIRAT if (dir_fd != DEFAULT_DIR_FD) - result = mkdirat(dir_fd, path.narrow, mode); + result = mkdirat(dir_fd, path->narrow, mode); else #endif #if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__) - result = mkdir(path.narrow); + result = mkdir(path->narrow); #else - result = mkdir(path.narrow, mode); + result = mkdir(path->narrow, mode); #endif Py_END_ALLOW_THREADS - if (result < 0) { - return_value = path_error(&path); - goto exit; - } + if (result < 0) + return path_error(path); #endif - return_value = Py_None; - Py_INCREF(Py_None); -exit: - path_cleanup(&path); - return return_value; + Py_RETURN_NONE; } @@ -4160,17 +5039,48 @@ posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs) #ifdef HAVE_NICE -PyDoc_STRVAR(posix_nice__doc__, -"nice(inc) -> new_priority\n\n\ -Decrease the priority of process by inc and return the new priority."); +/*[clinic input] +os.nice + + increment: int + / + +Add increment to the priority of process and return the new priority. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_nice__doc__, +"nice($module, increment, /)\n" +"--\n" +"\n" +"Add increment to the priority of process and return the new priority."); + +#define OS_NICE_METHODDEF \ + {"nice", (PyCFunction)os_nice, METH_VARARGS, os_nice__doc__}, + +static PyObject * +os_nice_impl(PyModuleDef *module, int increment); static PyObject * -posix_nice(PyObject *self, PyObject *args) +os_nice(PyModuleDef *module, PyObject *args) { - int increment, value; + PyObject *return_value = NULL; + int increment; - if (!PyArg_ParseTuple(args, "i:nice", &increment)) - return NULL; + if (!PyArg_ParseTuple(args, + "i:nice", + &increment)) + goto exit; + return_value = os_nice_impl(module, increment); + +exit: + return return_value; +} + +static PyObject * +os_nice_impl(PyModuleDef *module, int increment) +/*[clinic end generated code: output=c360dc2a3bd8e3d0 input=864be2d402a21da2]*/ +{ + int value; /* There are two flavours of 'nice': one that returns the new priority (as required by almost all standards out there) and the @@ -4197,17 +5107,51 @@ posix_nice(PyObject *self, PyObject *args) #ifdef HAVE_GETPRIORITY -PyDoc_STRVAR(posix_getpriority__doc__, -"getpriority(which, who) -> current_priority\n\n\ -Get program scheduling priority."); +/*[clinic input] +os.getpriority + + which: int + who: int + +Return program scheduling priority. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_getpriority__doc__, +"getpriority($module, /, which, who)\n" +"--\n" +"\n" +"Return program scheduling priority."); + +#define OS_GETPRIORITY_METHODDEF \ + {"getpriority", (PyCFunction)os_getpriority, METH_VARARGS|METH_KEYWORDS, os_getpriority__doc__}, static PyObject * -posix_getpriority(PyObject *self, PyObject *args) +os_getpriority_impl(PyModuleDef *module, int which, int who); + +static PyObject * +os_getpriority(PyModuleDef *module, PyObject *args, PyObject *kwargs) { - int which, who, retval; + PyObject *return_value = NULL; + static char *_keywords[] = {"which", "who", NULL}; + int which; + int who; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "ii:getpriority", _keywords, + &which, &who)) + goto exit; + return_value = os_getpriority_impl(module, which, who); + +exit: + return return_value; +} + +static PyObject * +os_getpriority_impl(PyModuleDef *module, int which, int who) +/*[clinic end generated code: output=81639cf765f05dae input=9be615d40e2544ef]*/ +{ + int retval; - if (!PyArg_ParseTuple(args, "ii", &which, &who)) - return NULL; errno = 0; retval = getpriority(which, who); if (errno != 0) @@ -4218,18 +5162,54 @@ posix_getpriority(PyObject *self, PyObject *args) #ifdef HAVE_SETPRIORITY -PyDoc_STRVAR(posix_setpriority__doc__, -"setpriority(which, who, prio) -> None\n\n\ -Set program scheduling priority."); +/*[clinic input] +os.setpriority + + which: int + who: int + priority: int + +Set program scheduling priority. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_setpriority__doc__, +"setpriority($module, /, which, who, priority)\n" +"--\n" +"\n" +"Set program scheduling priority."); + +#define OS_SETPRIORITY_METHODDEF \ + {"setpriority", (PyCFunction)os_setpriority, METH_VARARGS|METH_KEYWORDS, os_setpriority__doc__}, + +static PyObject * +os_setpriority_impl(PyModuleDef *module, int which, int who, int priority); static PyObject * -posix_setpriority(PyObject *self, PyObject *args) +os_setpriority(PyModuleDef *module, PyObject *args, PyObject *kwargs) { - int which, who, prio, retval; + PyObject *return_value = NULL; + static char *_keywords[] = {"which", "who", "priority", NULL}; + int which; + int who; + int priority; - if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio)) - return NULL; - retval = setpriority(which, who, prio); + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "iii:setpriority", _keywords, + &which, &who, &priority)) + goto exit; + return_value = os_setpriority_impl(module, which, who, priority); + +exit: + return return_value; +} + +static PyObject * +os_setpriority_impl(PyModuleDef *module, int which, int who, int priority) +/*[clinic end generated code: output=ddad62651fb2120c input=710ccbf65b9dc513]*/ +{ + int retval; + + retval = setpriority(which, who, priority); if (retval == -1) return posix_error(); Py_RETURN_NONE; @@ -4238,17 +5218,10 @@ posix_setpriority(PyObject *self, PyObject *args) static PyObject * -internal_rename(PyObject *args, PyObject *kwargs, int is_replace) +internal_rename(path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd, int is_replace) { char *function_name = is_replace ? "replace" : "rename"; - path_t src; - path_t dst; - int src_dir_fd = DEFAULT_DIR_FD; - int dst_dir_fd = DEFAULT_DIR_FD; int dir_fd_specified; - PyObject *return_value = NULL; - char format[24]; - static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL}; #ifdef MS_WINDOWS BOOL result; @@ -4257,210 +5230,419 @@ internal_rename(PyObject *args, PyObject *kwargs, int is_replace) int result; #endif - memset(&src, 0, sizeof(src)); - memset(&dst, 0, sizeof(dst)); - src.function_name = function_name; - dst.function_name = function_name; - strcpy(format, "O&O&|$O&O&:"); - strcat(format, function_name); - if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, keywords, - path_converter, &src, - path_converter, &dst, - dir_fd_converter, &src_dir_fd, - dir_fd_converter, &dst_dir_fd)) - return NULL; - dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD); #ifndef HAVE_RENAMEAT if (dir_fd_specified) { argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd"); - goto exit; + return NULL; } #endif - if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) { + if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) { PyErr_Format(PyExc_ValueError, "%s: src and dst must be the same type", function_name); - goto exit; + return NULL; } #ifdef MS_WINDOWS Py_BEGIN_ALLOW_THREADS - if (src.wide) - result = MoveFileExW(src.wide, dst.wide, flags); + if (src->wide) + result = MoveFileExW(src->wide, dst->wide, flags); else - result = MoveFileExA(src.narrow, dst.narrow, flags); + result = MoveFileExA(src->narrow, dst->narrow, flags); Py_END_ALLOW_THREADS - if (!result) { - return_value = path_error(&src); - goto exit; - } + if (!result) + return path_error2(src, dst); #else Py_BEGIN_ALLOW_THREADS #ifdef HAVE_RENAMEAT if (dir_fd_specified) - result = renameat(src_dir_fd, src.narrow, dst_dir_fd, dst.narrow); + result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow); else #endif - result = rename(src.narrow, dst.narrow); + result = rename(src->narrow, dst->narrow); Py_END_ALLOW_THREADS - if (result) { - return_value = path_error(&src); - goto exit; - } + if (result) + return path_error2(src, dst); #endif + Py_RETURN_NONE; +} + + +/*[clinic input] +os.rename + + src : path_t + dst : path_t + * + src_dir_fd : dir_fd = None + dst_dir_fd : dir_fd = None + +Rename a file or directory. + +If either src_dir_fd or dst_dir_fd is not None, it should be a file + descriptor open to a directory, and the respective path string (src or dst) + should be relative; the path will then be relative to that directory. +src_dir_fd and dst_dir_fd, may not be implemented on your platform. + If they are unavailable, using them will raise a NotImplementedError. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_rename__doc__, +"rename($module, /, src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n" +"--\n" +"\n" +"Rename a file or directory.\n" +"\n" +"If either src_dir_fd or dst_dir_fd is not None, it should be a file\n" +" descriptor open to a directory, and the respective path string (src or dst)\n" +" should be relative; the path will then be relative to that directory.\n" +"src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n" +" If they are unavailable, using them will raise a NotImplementedError."); + +#define OS_RENAME_METHODDEF \ + {"rename", (PyCFunction)os_rename, METH_VARARGS|METH_KEYWORDS, os_rename__doc__}, + +static PyObject * +os_rename_impl(PyModuleDef *module, path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd); + +static PyObject * +os_rename(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL}; + path_t src = PATH_T_INITIALIZE("rename", "src", 0, 0); + path_t dst = PATH_T_INITIALIZE("rename", "dst", 0, 0); + int src_dir_fd = DEFAULT_DIR_FD; + int dst_dir_fd = DEFAULT_DIR_FD; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&O&|$O&O&:rename", _keywords, + path_converter, &src, path_converter, &dst, dir_fd_converter, &src_dir_fd, dir_fd_converter, &dst_dir_fd)) + goto exit; + return_value = os_rename_impl(module, &src, &dst, src_dir_fd, dst_dir_fd); - Py_INCREF(Py_None); - return_value = Py_None; exit: + /* Cleanup for src */ path_cleanup(&src); + /* Cleanup for dst */ path_cleanup(&dst); + return return_value; } -PyDoc_STRVAR(posix_rename__doc__, -"rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\ -Rename a file or directory.\n\ -\n\ -If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\ - descriptor open to a directory, and the respective path string (src or dst)\n\ - should be relative; the path will then be relative to that directory.\n\ -src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\ - If they are unavailable, using them will raise a NotImplementedError."); - static PyObject * -posix_rename(PyObject *self, PyObject *args, PyObject *kwargs) +os_rename_impl(PyModuleDef *module, path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd) +/*[clinic end generated code: output=c936bdc81f460a1e input=faa61c847912c850]*/ { - return internal_rename(args, kwargs, 0); + return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0); } -PyDoc_STRVAR(posix_replace__doc__, -"replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\ -Rename a file or directory, overwriting the destination.\n\ -\n\ -If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\ - descriptor open to a directory, and the respective path string (src or dst)\n\ - should be relative; the path will then be relative to that directory.\n\ -src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\ - If they are unavailable, using them will raise a NotImplementedError."); + +/*[clinic input] +os.replace = os.rename + +Rename a file or directory, overwriting the destination. + +If either src_dir_fd or dst_dir_fd is not None, it should be a file + descriptor open to a directory, and the respective path string (src or dst) + should be relative; the path will then be relative to that directory. +src_dir_fd and dst_dir_fd, may not be implemented on your platform. + If they are unavailable, using them will raise a NotImplementedError." +[clinic start generated code]*/ + +PyDoc_STRVAR(os_replace__doc__, +"replace($module, /, src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n" +"--\n" +"\n" +"Rename a file or directory, overwriting the destination.\n" +"\n" +"If either src_dir_fd or dst_dir_fd is not None, it should be a file\n" +" descriptor open to a directory, and the respective path string (src or dst)\n" +" should be relative; the path will then be relative to that directory.\n" +"src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n" +" If they are unavailable, using them will raise a NotImplementedError.\""); + +#define OS_REPLACE_METHODDEF \ + {"replace", (PyCFunction)os_replace, METH_VARARGS|METH_KEYWORDS, os_replace__doc__}, + +static PyObject * +os_replace_impl(PyModuleDef *module, path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd); + +static PyObject * +os_replace(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL}; + path_t src = PATH_T_INITIALIZE("replace", "src", 0, 0); + path_t dst = PATH_T_INITIALIZE("replace", "dst", 0, 0); + int src_dir_fd = DEFAULT_DIR_FD; + int dst_dir_fd = DEFAULT_DIR_FD; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&O&|$O&O&:replace", _keywords, + path_converter, &src, path_converter, &dst, dir_fd_converter, &src_dir_fd, dir_fd_converter, &dst_dir_fd)) + goto exit; + return_value = os_replace_impl(module, &src, &dst, src_dir_fd, dst_dir_fd); + +exit: + /* Cleanup for src */ + path_cleanup(&src); + /* Cleanup for dst */ + path_cleanup(&dst); + + return return_value; +} static PyObject * -posix_replace(PyObject *self, PyObject *args, PyObject *kwargs) +os_replace_impl(PyModuleDef *module, path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd) +/*[clinic end generated code: output=224e4710d290d171 input=25515dfb107c8421]*/ { - return internal_rename(args, kwargs, 1); + return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1); } -PyDoc_STRVAR(posix_rmdir__doc__, -"rmdir(path, *, dir_fd=None)\n\n\ -Remove a directory.\n\ -\n\ -If dir_fd is not None, it should be a file descriptor open to a directory,\n\ - and path should be relative; path will then be relative to that directory.\n\ -dir_fd may not be implemented on your platform.\n\ - If it is unavailable, using it will raise a NotImplementedError."); + +/*[clinic input] +os.rmdir + + path: path_t + * + dir_fd: dir_fd(requires='unlinkat') = None + +Remove a directory. + +If dir_fd is not None, it should be a file descriptor open to a directory, + and path should be relative; path will then be relative to that directory. +dir_fd may not be implemented on your platform. + If it is unavailable, using it will raise a NotImplementedError. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_rmdir__doc__, +"rmdir($module, /, path, *, dir_fd=None)\n" +"--\n" +"\n" +"Remove a directory.\n" +"\n" +"If dir_fd is not None, it should be a file descriptor open to a directory,\n" +" and path should be relative; path will then be relative to that directory.\n" +"dir_fd may not be implemented on your platform.\n" +" If it is unavailable, using it will raise a NotImplementedError."); + +#define OS_RMDIR_METHODDEF \ + {"rmdir", (PyCFunction)os_rmdir, METH_VARARGS|METH_KEYWORDS, os_rmdir__doc__}, + +static PyObject * +os_rmdir_impl(PyModuleDef *module, path_t *path, int dir_fd); static PyObject * -posix_rmdir(PyObject *self, PyObject *args, PyObject *kwargs) +os_rmdir(PyModuleDef *module, PyObject *args, PyObject *kwargs) { - path_t path; - int dir_fd = DEFAULT_DIR_FD; - static char *keywords[] = {"path", "dir_fd", NULL}; - int result; PyObject *return_value = NULL; + static char *_keywords[] = {"path", "dir_fd", NULL}; + path_t path = PATH_T_INITIALIZE("rmdir", "path", 0, 0); + int dir_fd = DEFAULT_DIR_FD; - memset(&path, 0, sizeof(path)); - path.function_name = "rmdir"; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:rmdir", keywords, - path_converter, &path, -#ifdef HAVE_UNLINKAT - dir_fd_converter, &dir_fd -#else - dir_fd_unavailable, &dir_fd -#endif - )) - return NULL; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&|$O&:rmdir", _keywords, + path_converter, &path, UNLINKAT_DIR_FD_CONVERTER, &dir_fd)) + goto exit; + return_value = os_rmdir_impl(module, &path, dir_fd); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +static PyObject * +os_rmdir_impl(PyModuleDef *module, path_t *path, int dir_fd) +/*[clinic end generated code: output=70b9fdbe3bee0591 input=38c8b375ca34a7e2]*/ +{ + int result; Py_BEGIN_ALLOW_THREADS #ifdef MS_WINDOWS - if (path.wide) - result = RemoveDirectoryW(path.wide); + if (path->wide) + result = RemoveDirectoryW(path->wide); else - result = RemoveDirectoryA(path.narrow); + result = RemoveDirectoryA(path->narrow); result = !result; /* Windows, success=1, UNIX, success=0 */ #else #ifdef HAVE_UNLINKAT if (dir_fd != DEFAULT_DIR_FD) - result = unlinkat(dir_fd, path.narrow, AT_REMOVEDIR); + result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR); else #endif - result = rmdir(path.narrow); + result = rmdir(path->narrow); #endif Py_END_ALLOW_THREADS - if (result) { - return_value = path_error(&path); - goto exit; - } - - return_value = Py_None; - Py_INCREF(Py_None); + if (result) + return path_error(path); -exit: - path_cleanup(&path); - return return_value; + Py_RETURN_NONE; } #ifdef HAVE_SYSTEM -PyDoc_STRVAR(posix_system__doc__, -"system(command) -> exit_status\n\n\ -Execute the command (a string) in a subshell."); +#ifdef MS_WINDOWS +/*[clinic input] +os.system -> long -static PyObject * -posix_system(PyObject *self, PyObject *args) + command: Py_UNICODE + +Execute the command in a subshell. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_system__doc__, +"system($module, /, command)\n" +"--\n" +"\n" +"Execute the command in a subshell."); + +#define OS_SYSTEM_METHODDEF \ + {"system", (PyCFunction)os_system, METH_VARARGS|METH_KEYWORDS, os_system__doc__}, + +static long +os_system_impl(PyModuleDef *module, Py_UNICODE *command); + +static PyObject * +os_system(PyModuleDef *module, PyObject *args, PyObject *kwargs) { - long sts; -#ifdef MS_WINDOWS - wchar_t *command; - if (!PyArg_ParseTuple(args, "u:system", &command)) - return NULL; + PyObject *return_value = NULL; + static char *_keywords[] = {"command", NULL}; + Py_UNICODE *command; + long _return_value; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "u:system", _keywords, + &command)) + goto exit; + _return_value = os_system_impl(module, command); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromLong(_return_value); + +exit: + return return_value; +} +static long +os_system_impl(PyModuleDef *module, Py_UNICODE *command) +/*[clinic end generated code: output=29fe699c0b2e9d38 input=303f5ce97df606b0]*/ +{ + long result; Py_BEGIN_ALLOW_THREADS - sts = _wsystem(command); + result = _wsystem(command); Py_END_ALLOW_THREADS -#else - PyObject *command_obj; - char *command; - if (!PyArg_ParseTuple(args, "O&:system", - PyUnicode_FSConverter, &command_obj)) - return NULL; + return result; +} +#else /* MS_WINDOWS */ +/*[clinic input] +os.system -> long + + command: FSConverter + +Execute the command in a subshell. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_system__doc__, +"system($module, /, command)\n" +"--\n" +"\n" +"Execute the command in a subshell."); + +#define OS_SYSTEM_METHODDEF \ + {"system", (PyCFunction)os_system, METH_VARARGS|METH_KEYWORDS, os_system__doc__}, + +static long +os_system_impl(PyModuleDef *module, PyObject *command); + +static PyObject * +os_system(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"command", NULL}; + PyObject *command = NULL; + long _return_value; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&:system", _keywords, + PyUnicode_FSConverter, &command)) + goto exit; + _return_value = os_system_impl(module, command); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromLong(_return_value); + +exit: + /* Cleanup for command */ + Py_XDECREF(command); + + return return_value; +} - command = PyBytes_AsString(command_obj); +static long +os_system_impl(PyModuleDef *module, PyObject *command) +/*[clinic end generated code: output=5be9f3c40ead3bad input=86a58554ba6094af]*/ +{ + long result; + char *bytes = PyBytes_AsString(command); Py_BEGIN_ALLOW_THREADS - sts = system(command); + result = system(bytes); Py_END_ALLOW_THREADS - Py_DECREF(command_obj); -#endif - return PyLong_FromLong(sts); + return result; } #endif +#endif /* HAVE_SYSTEM */ -PyDoc_STRVAR(posix_umask__doc__, -"umask(new_mask) -> old_mask\n\n\ -Set the current numeric umask and return the previous umask."); +/*[clinic input] +os.umask + + mask: int + / + +Set the current numeric umask and return the previous umask. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_umask__doc__, +"umask($module, mask, /)\n" +"--\n" +"\n" +"Set the current numeric umask and return the previous umask."); + +#define OS_UMASK_METHODDEF \ + {"umask", (PyCFunction)os_umask, METH_VARARGS, os_umask__doc__}, + +static PyObject * +os_umask_impl(PyModuleDef *module, int mask); static PyObject * -posix_umask(PyObject *self, PyObject *args) +os_umask(PyModuleDef *module, PyObject *args) { - int i; - if (!PyArg_ParseTuple(args, "i:umask", &i)) - return NULL; - i = (int)umask(i); + PyObject *return_value = NULL; + int mask; + + if (!PyArg_ParseTuple(args, + "i:umask", + &mask)) + goto exit; + return_value = os_umask_impl(module, mask); + +exit: + return return_value; +} + +static PyObject * +os_umask_impl(PyModuleDef *module, int mask) +/*[clinic end generated code: output=90048b39d2d4a961 input=ab6bfd9b24d8a7e8]*/ +{ + int i = (int)umask(mask); if (i < 0) return posix_error(); return PyLong_FromLong((long)i); @@ -4489,7 +5671,10 @@ BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName) find_data_handle = FindFirstFileW(lpFileName, &find_data); if(find_data_handle != INVALID_HANDLE_VALUE) { - is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK; + /* IO_REPARSE_TAG_SYMLINK if it is a symlink and + IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */ + is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK || + find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT; FindClose(find_data_handle); } } @@ -4502,81 +5687,147 @@ BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName) } #endif /* MS_WINDOWS */ -PyDoc_STRVAR(posix_unlink__doc__, -"unlink(path, *, dir_fd=None)\n\n\ -Remove a file (same as remove()).\n\ -\n\ -If dir_fd is not None, it should be a file descriptor open to a directory,\n\ - and path should be relative; path will then be relative to that directory.\n\ -dir_fd may not be implemented on your platform.\n\ - If it is unavailable, using it will raise a NotImplementedError."); -PyDoc_STRVAR(posix_remove__doc__, -"remove(path, *, dir_fd=None)\n\n\ -Remove a file (same as unlink()).\n\ -\n\ -If dir_fd is not None, it should be a file descriptor open to a directory,\n\ - and path should be relative; path will then be relative to that directory.\n\ -dir_fd may not be implemented on your platform.\n\ - If it is unavailable, using it will raise a NotImplementedError."); +/*[clinic input] +os.unlink + + path: path_t + * + dir_fd: dir_fd(requires='unlinkat')=None + +Remove a file (same as remove()). + +If dir_fd is not None, it should be a file descriptor open to a directory, + and path should be relative; path will then be relative to that directory. +dir_fd may not be implemented on your platform. + If it is unavailable, using it will raise a NotImplementedError. + +[clinic start generated code]*/ + +PyDoc_STRVAR(os_unlink__doc__, +"unlink($module, /, path, *, dir_fd=None)\n" +"--\n" +"\n" +"Remove a file (same as remove()).\n" +"\n" +"If dir_fd is not None, it should be a file descriptor open to a directory,\n" +" and path should be relative; path will then be relative to that directory.\n" +"dir_fd may not be implemented on your platform.\n" +" If it is unavailable, using it will raise a NotImplementedError."); + +#define OS_UNLINK_METHODDEF \ + {"unlink", (PyCFunction)os_unlink, METH_VARARGS|METH_KEYWORDS, os_unlink__doc__}, static PyObject * -posix_unlink(PyObject *self, PyObject *args, PyObject *kwargs) +os_unlink_impl(PyModuleDef *module, path_t *path, int dir_fd); + +static PyObject * +os_unlink(PyModuleDef *module, PyObject *args, PyObject *kwargs) { - path_t path; - int dir_fd = DEFAULT_DIR_FD; - static char *keywords[] = {"path", "dir_fd", NULL}; - int result; PyObject *return_value = NULL; + static char *_keywords[] = {"path", "dir_fd", NULL}; + path_t path = PATH_T_INITIALIZE("unlink", "path", 0, 0); + int dir_fd = DEFAULT_DIR_FD; - memset(&path, 0, sizeof(path)); - path.function_name = "unlink"; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:unlink", keywords, - path_converter, &path, -#ifdef HAVE_UNLINKAT - dir_fd_converter, &dir_fd -#else - dir_fd_unavailable, &dir_fd -#endif - )) - return NULL; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&|$O&:unlink", _keywords, + path_converter, &path, UNLINKAT_DIR_FD_CONVERTER, &dir_fd)) + goto exit; + return_value = os_unlink_impl(module, &path, dir_fd); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +static PyObject * +os_unlink_impl(PyModuleDef *module, path_t *path, int dir_fd) +/*[clinic end generated code: output=59a6e66d67ff2e75 input=d7bcde2b1b2a2552]*/ +{ + int result; Py_BEGIN_ALLOW_THREADS #ifdef MS_WINDOWS - if (path.wide) - result = Py_DeleteFileW(path.wide); + if (path->wide) + result = Py_DeleteFileW(path->wide); else - result = DeleteFileA(path.narrow); + result = DeleteFileA(path->narrow); result = !result; /* Windows, success=1, UNIX, success=0 */ #else #ifdef HAVE_UNLINKAT if (dir_fd != DEFAULT_DIR_FD) - result = unlinkat(dir_fd, path.narrow, 0); + result = unlinkat(dir_fd, path->narrow, 0); else #endif /* HAVE_UNLINKAT */ - result = unlink(path.narrow); + result = unlink(path->narrow); #endif Py_END_ALLOW_THREADS - if (result) { - return_value = path_error(&path); - goto exit; - } + if (result) + return path_error(path); - return_value = Py_None; - Py_INCREF(Py_None); + Py_RETURN_NONE; +} + + +/*[clinic input] +os.remove = os.unlink + +Remove a file (same as unlink()). + +If dir_fd is not None, it should be a file descriptor open to a directory, + and path should be relative; path will then be relative to that directory. +dir_fd may not be implemented on your platform. + If it is unavailable, using it will raise a NotImplementedError. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_remove__doc__, +"remove($module, /, path, *, dir_fd=None)\n" +"--\n" +"\n" +"Remove a file (same as unlink()).\n" +"\n" +"If dir_fd is not None, it should be a file descriptor open to a directory,\n" +" and path should be relative; path will then be relative to that directory.\n" +"dir_fd may not be implemented on your platform.\n" +" If it is unavailable, using it will raise a NotImplementedError."); + +#define OS_REMOVE_METHODDEF \ + {"remove", (PyCFunction)os_remove, METH_VARARGS|METH_KEYWORDS, os_remove__doc__}, + +static PyObject * +os_remove_impl(PyModuleDef *module, path_t *path, int dir_fd); + +static PyObject * +os_remove(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "dir_fd", NULL}; + path_t path = PATH_T_INITIALIZE("remove", "path", 0, 0); + int dir_fd = DEFAULT_DIR_FD; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&|$O&:remove", _keywords, + path_converter, &path, UNLINKAT_DIR_FD_CONVERTER, &dir_fd)) + goto exit; + return_value = os_remove_impl(module, &path, dir_fd); exit: + /* Cleanup for path */ path_cleanup(&path); + return return_value; } +static PyObject * +os_remove_impl(PyModuleDef *module, path_t *path, int dir_fd) +/*[clinic end generated code: output=cb170cf1e195b8ed input=e05c5ab55cd30983]*/ +{ + return os_unlink_impl(module, path, dir_fd); +} -PyDoc_STRVAR(posix_uname__doc__, -"uname() -> uname_result\n\n\ -Return an object identifying the current operating system.\n\ -The object behaves like a named tuple with the following fields:\n\ - (sysname, nodename, release, version, machine)"); static PyStructSequence_Field uname_result_fields[] = { {"sysname", "operating system name"}, @@ -4606,8 +5857,40 @@ static PyTypeObject UnameResultType; #ifdef HAVE_UNAME +/*[clinic input] +os.uname + +Return an object identifying the current operating system. + +The object behaves like a named tuple with the following fields: + (sysname, nodename, release, version, machine) + +[clinic start generated code]*/ + +PyDoc_STRVAR(os_uname__doc__, +"uname($module, /)\n" +"--\n" +"\n" +"Return an object identifying the current operating system.\n" +"\n" +"The object behaves like a named tuple with the following fields:\n" +" (sysname, nodename, release, version, machine)"); + +#define OS_UNAME_METHODDEF \ + {"uname", (PyCFunction)os_uname, METH_NOARGS, os_uname__doc__}, + +static PyObject * +os_uname_impl(PyModuleDef *module); + +static PyObject * +os_uname(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_uname_impl(module); +} + static PyObject * -posix_uname(PyObject *self, PyObject *noargs) +os_uname_impl(PyModuleDef *module) +/*[clinic end generated code: output=459a86521ff5041c input=e68bd246db3043ed]*/ { struct utsname u; int res; @@ -4646,31 +5929,6 @@ posix_uname(PyObject *self, PyObject *noargs) #endif /* HAVE_UNAME */ -PyDoc_STRVAR(posix_utime__doc__, -"utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\n\ -Set the access and modified time of path.\n\ -\n\ -path may always be specified as a string.\n\ -On some platforms, path may also be specified as an open file descriptor.\n\ - If this functionality is unavailable, using it raises an exception.\n\ -\n\ -If times is not None, it must be a tuple (atime, mtime);\n\ - atime and mtime should be expressed as float seconds since the epoch.\n\ -If ns is not None, it must be a tuple (atime_ns, mtime_ns);\n\ - atime_ns and mtime_ns should be expressed as integer nanoseconds\n\ - since the epoch.\n\ -If both times and ns are None, utime uses the current time.\n\ -Specifying tuples for both times and ns is an error.\n\ -\n\ -If dir_fd is not None, it should be a file descriptor open to a directory,\n\ - and path should be relative; path will then be relative to that directory.\n\ -If follow_symlinks is False, and the last element of the path is a symbolic\n\ - link, utime will modify the symbolic link itself instead of the file the\n\ - link points to.\n\ -It is an error to use dir_fd or follow_symlinks when specifying path\n\ - as an open file descriptor.\n\ -dir_fd and follow_symlinks may not be available on your platform.\n\ - If they are unavailable, using them will raise a NotImplementedError."); typedef struct { int now; @@ -4681,55 +5939,55 @@ typedef struct { } utime_t; /* - * these macros assume that "utime" is a pointer to a utime_t + * these macros assume that "ut" is a pointer to a utime_t * they also intentionally leak the declaration of a pointer named "time" */ #define UTIME_TO_TIMESPEC \ struct timespec ts[2]; \ struct timespec *time; \ - if (utime->now) \ + if (ut->now) \ time = NULL; \ else { \ - ts[0].tv_sec = utime->atime_s; \ - ts[0].tv_nsec = utime->atime_ns; \ - ts[1].tv_sec = utime->mtime_s; \ - ts[1].tv_nsec = utime->mtime_ns; \ + ts[0].tv_sec = ut->atime_s; \ + ts[0].tv_nsec = ut->atime_ns; \ + ts[1].tv_sec = ut->mtime_s; \ + ts[1].tv_nsec = ut->mtime_ns; \ time = ts; \ } \ #define UTIME_TO_TIMEVAL \ struct timeval tv[2]; \ struct timeval *time; \ - if (utime->now) \ + if (ut->now) \ time = NULL; \ else { \ - tv[0].tv_sec = utime->atime_s; \ - tv[0].tv_usec = utime->atime_ns / 1000; \ - tv[1].tv_sec = utime->mtime_s; \ - tv[1].tv_usec = utime->mtime_ns / 1000; \ + tv[0].tv_sec = ut->atime_s; \ + tv[0].tv_usec = ut->atime_ns / 1000; \ + tv[1].tv_sec = ut->mtime_s; \ + tv[1].tv_usec = ut->mtime_ns / 1000; \ time = tv; \ } \ #define UTIME_TO_UTIMBUF \ - struct utimbuf u[2]; \ + struct utimbuf u; \ struct utimbuf *time; \ - if (utime->now) \ + if (ut->now) \ time = NULL; \ else { \ - u.actime = utime->atime_s; \ - u.modtime = utime->mtime_s; \ - time = u; \ + u.actime = ut->atime_s; \ + u.modtime = ut->mtime_s; \ + time = &u; \ } #define UTIME_TO_TIME_T \ time_t timet[2]; \ - struct timet time; \ - if (utime->now) \ + time_t *time; \ + if (ut->now) \ time = NULL; \ else { \ - timet[0] = utime->atime_s; \ - timet[1] = utime->mtime_s; \ - time = &timet; \ + timet[0] = ut->atime_s; \ + timet[1] = ut->mtime_s; \ + time = timet; \ } \ @@ -4738,7 +5996,7 @@ typedef struct { #if UTIME_HAVE_DIR_FD static int -utime_dir_fd(utime_t *utime, int dir_fd, char *path, int follow_symlinks) +utime_dir_fd(utime_t *ut, int dir_fd, char *path, int follow_symlinks) { #ifdef HAVE_UTIMENSAT int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW; @@ -4756,6 +6014,9 @@ utime_dir_fd(utime_t *utime, int dir_fd, char *path, int follow_symlinks) #endif } + #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable #endif #define UTIME_HAVE_FD (defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)) @@ -4763,7 +6024,7 @@ utime_dir_fd(utime_t *utime, int dir_fd, char *path, int follow_symlinks) #if UTIME_HAVE_FD static int -utime_fd(utime_t *utime, int fd) +utime_fd(utime_t *ut, int fd) { #ifdef HAVE_FUTIMENS UTIME_TO_TIMESPEC; @@ -4774,6 +6035,9 @@ utime_fd(utime_t *utime, int fd) #endif } + #define PATH_UTIME_HAVE_FD 1 +#else + #define PATH_UTIME_HAVE_FD 0 #endif @@ -4783,7 +6047,7 @@ utime_fd(utime_t *utime, int fd) #if UTIME_HAVE_NOFOLLOW_SYMLINKS static int -utime_nofollow_symlinks(utime_t *utime, char *path) +utime_nofollow_symlinks(utime_t *ut, char *path) { #ifdef HAVE_UTIMENSAT UTIME_TO_TIMESPEC; @@ -4799,7 +6063,7 @@ utime_nofollow_symlinks(utime_t *utime, char *path) #ifndef MS_WINDOWS static int -utime_default(utime_t *utime, char *path) +utime_default(utime_t *ut, char *path) { #ifdef HAVE_UTIMENSAT UTIME_TO_TIMESPEC; @@ -4839,19 +6103,113 @@ split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns) return result; } + +/*[clinic input] +os.utime + + path: path_t(allow_fd='PATH_UTIME_HAVE_FD') + times: object = NULL + * + ns: object = NULL + dir_fd: dir_fd(requires='futimensat') = None + follow_symlinks: bool=True + +# "utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\n\ + +Set the access and modified time of path. + +path may always be specified as a string. +On some platforms, path may also be specified as an open file descriptor. + If this functionality is unavailable, using it raises an exception. + +If times is not None, it must be a tuple (atime, mtime); + atime and mtime should be expressed as float seconds since the epoch. +If ns is not None, it must be a tuple (atime_ns, mtime_ns); + atime_ns and mtime_ns should be expressed as integer nanoseconds + since the epoch. +If both times and ns are None, utime uses the current time. +Specifying tuples for both times and ns is an error. + +If dir_fd is not None, it should be a file descriptor open to a directory, + and path should be relative; path will then be relative to that directory. +If follow_symlinks is False, and the last element of the path is a symbolic + link, utime will modify the symbolic link itself instead of the file the + link points to. +It is an error to use dir_fd or follow_symlinks when specifying path + as an open file descriptor. +dir_fd and follow_symlinks may not be available on your platform. + If they are unavailable, using them will raise a NotImplementedError. + +[clinic start generated code]*/ + +PyDoc_STRVAR(os_utime__doc__, +"utime($module, /, path, times=None, *, ns=None, dir_fd=None,\n" +" follow_symlinks=True)\n" +"--\n" +"\n" +"Set the access and modified time of path.\n" +"\n" +"path may always be specified as a string.\n" +"On some platforms, path may also be specified as an open file descriptor.\n" +" If this functionality is unavailable, using it raises an exception.\n" +"\n" +"If times is not None, it must be a tuple (atime, mtime);\n" +" atime and mtime should be expressed as float seconds since the epoch.\n" +"If ns is not None, it must be a tuple (atime_ns, mtime_ns);\n" +" atime_ns and mtime_ns should be expressed as integer nanoseconds\n" +" since the epoch.\n" +"If both times and ns are None, utime uses the current time.\n" +"Specifying tuples for both times and ns is an error.\n" +"\n" +"If dir_fd is not None, it should be a file descriptor open to a directory,\n" +" and path should be relative; path will then be relative to that directory.\n" +"If follow_symlinks is False, and the last element of the path is a symbolic\n" +" link, utime will modify the symbolic link itself instead of the file the\n" +" link points to.\n" +"It is an error to use dir_fd or follow_symlinks when specifying path\n" +" as an open file descriptor.\n" +"dir_fd and follow_symlinks may not be available on your platform.\n" +" If they are unavailable, using them will raise a NotImplementedError."); + +#define OS_UTIME_METHODDEF \ + {"utime", (PyCFunction)os_utime, METH_VARARGS|METH_KEYWORDS, os_utime__doc__}, + +static PyObject * +os_utime_impl(PyModuleDef *module, path_t *path, PyObject *times, PyObject *ns, int dir_fd, int follow_symlinks); + static PyObject * -posix_utime(PyObject *self, PyObject *args, PyObject *kwargs) +os_utime(PyModuleDef *module, PyObject *args, PyObject *kwargs) { - path_t path; + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "times", "ns", "dir_fd", "follow_symlinks", NULL}; + path_t path = PATH_T_INITIALIZE("utime", "path", 0, PATH_UTIME_HAVE_FD); PyObject *times = NULL; PyObject *ns = NULL; int dir_fd = DEFAULT_DIR_FD; int follow_symlinks = 1; - char *keywords[] = {"path", "times", "ns", "dir_fd", - "follow_symlinks", NULL}; - utime_t utime; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&|O$OO&p:utime", _keywords, + path_converter, &path, ×, &ns, FUTIMENSAT_DIR_FD_CONVERTER, &dir_fd, &follow_symlinks)) + goto exit; + return_value = os_utime_impl(module, &path, times, ns, dir_fd, follow_symlinks); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} +#ifdef MS_WINDOWS +void +_Py_time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr); +#endif + +static PyObject * +os_utime_impl(PyModuleDef *module, path_t *path, PyObject *times, PyObject *ns, int dir_fd, int follow_symlinks) +/*[clinic end generated code: output=891489c35cc68c5d input=1f18c17d5941aa82]*/ +{ #ifdef MS_WINDOWS HANDLE hFile; FILETIME atime, mtime; @@ -4860,25 +6218,9 @@ posix_utime(PyObject *self, PyObject *args, PyObject *kwargs) #endif PyObject *return_value = NULL; + utime_t utime; - memset(&path, 0, sizeof(path)); - path.function_name = "utime"; memset(&utime, 0, sizeof(utime_t)); -#if UTIME_HAVE_FD - path.allow_fd = 1; -#endif - if (!PyArg_ParseTupleAndKeywords(args, kwargs, - "O&|O$OO&p:utime", keywords, - path_converter, &path, - ×, &ns, -#if UTIME_HAVE_DIR_FD - dir_fd_converter, &dir_fd, -#else - dir_fd_unavailable, &dir_fd, -#endif - &follow_symlinks - )) - return NULL; if (times && (times != Py_None) && ns) { PyErr_SetString(PyExc_ValueError, @@ -4898,9 +6240,9 @@ posix_utime(PyObject *self, PyObject *args, PyObject *kwargs) } utime.now = 0; if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0), - &a_sec, &a_nsec) == -1 || + &a_sec, &a_nsec, _PyTime_ROUND_DOWN) == -1 || _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1), - &m_sec, &m_nsec) == -1) { + &m_sec, &m_nsec, _PyTime_ROUND_DOWN) == -1) { goto exit; } utime.atime_s = a_sec; @@ -4932,9 +6274,9 @@ posix_utime(PyObject *self, PyObject *args, PyObject *kwargs) goto exit; #endif - if (path_and_dir_fd_invalid("utime", &path, dir_fd) || - dir_fd_and_fd_invalid("utime", dir_fd, path.fd) || - fd_and_follow_symlinks_invalid("utime", path.fd, follow_symlinks)) + if (path_and_dir_fd_invalid("utime", path, dir_fd) || + dir_fd_and_fd_invalid("utime", dir_fd, path->fd) || + fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks)) goto exit; #if !defined(HAVE_UTIMENSAT) @@ -4948,17 +6290,17 @@ posix_utime(PyObject *self, PyObject *args, PyObject *kwargs) #ifdef MS_WINDOWS Py_BEGIN_ALLOW_THREADS - if (path.wide) - hFile = CreateFileW(path.wide, FILE_WRITE_ATTRIBUTES, 0, + if (path->wide) + hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); else - hFile = CreateFileA(path.narrow, FILE_WRITE_ATTRIBUTES, 0, + hFile = CreateFileA(path->narrow, FILE_WRITE_ATTRIBUTES, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); Py_END_ALLOW_THREADS if (hFile == INVALID_HANDLE_VALUE) { - path_error(&path); + path_error(path); goto exit; } @@ -4967,8 +6309,8 @@ posix_utime(PyObject *self, PyObject *args, PyObject *kwargs) atime = mtime; } else { - time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime); - time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime); + _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime); + _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime); } if (!SetFileTime(hFile, NULL, &atime, &mtime)) { /* Avoid putting the file name into the error here, @@ -4983,23 +6325,23 @@ posix_utime(PyObject *self, PyObject *args, PyObject *kwargs) #if UTIME_HAVE_NOFOLLOW_SYMLINKS if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD)) - result = utime_nofollow_symlinks(&utime, path.narrow); + result = utime_nofollow_symlinks(&utime, path->narrow); else #endif #if UTIME_HAVE_DIR_FD if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks)) - result = utime_dir_fd(&utime, dir_fd, path.narrow, follow_symlinks); + result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks); else #endif #if UTIME_HAVE_FD - if (path.fd != -1) - result = utime_fd(&utime, path.fd); + if (path->fd != -1) + result = utime_fd(&utime, path->fd); else #endif - result = utime_default(&utime, path.narrow); + result = utime_default(&utime, path->narrow); Py_END_ALLOW_THREADS @@ -5015,7 +6357,6 @@ posix_utime(PyObject *self, PyObject *args, PyObject *kwargs) return_value = Py_None; exit: - path_cleanup(&path); #ifdef MS_WINDOWS if (hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile); @@ -5025,17 +6366,49 @@ posix_utime(PyObject *self, PyObject *args, PyObject *kwargs) /* Process operations */ -PyDoc_STRVAR(posix__exit__doc__, -"_exit(status)\n\n\ -Exit to the system with specified status, without normal exit processing."); + +/*[clinic input] +os._exit + + status: int + +Exit to the system with specified status, without normal exit processing. +[clinic start generated code]*/ + +PyDoc_STRVAR(os__exit__doc__, +"_exit($module, /, status)\n" +"--\n" +"\n" +"Exit to the system with specified status, without normal exit processing."); + +#define OS__EXIT_METHODDEF \ + {"_exit", (PyCFunction)os__exit, METH_VARARGS|METH_KEYWORDS, os__exit__doc__}, + +static PyObject * +os__exit_impl(PyModuleDef *module, int status); static PyObject * -posix__exit(PyObject *self, PyObject *args) +os__exit(PyModuleDef *module, PyObject *args, PyObject *kwargs) { - int sts; - if (!PyArg_ParseTuple(args, "i:_exit", &sts)) - return NULL; - _exit(sts); + PyObject *return_value = NULL; + static char *_keywords[] = {"status", NULL}; + int status; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "i:_exit", _keywords, + &status)) + goto exit; + return_value = os__exit_impl(module, status); + +exit: + return return_value; +} + +static PyObject * +os__exit_impl(PyModuleDef *module, int status) +/*[clinic end generated code: output=4f9858c4cc2dcb89 input=5e6d57556b0c4a62]*/ +{ + _exit(status); return NULL; /* Make gcc -Wall happy */ } @@ -5173,96 +6546,160 @@ parse_arglist(PyObject* argv, Py_ssize_t *argc) } #endif + #ifdef HAVE_EXECV -PyDoc_STRVAR(posix_execv__doc__, -"execv(path, args)\n\n\ -Execute an executable path with arguments, replacing current process.\n\ -\n\ - path: path of executable file\n\ - args: tuple or list of strings"); +/*[clinic input] +os.execv + + path: FSConverter + Path of executable file. + argv: object + Tuple or list of strings. + / + +Execute an executable path with arguments, replacing current process. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_execv__doc__, +"execv($module, path, argv, /)\n" +"--\n" +"\n" +"Execute an executable path with arguments, replacing current process.\n" +"\n" +" path\n" +" Path of executable file.\n" +" argv\n" +" Tuple or list of strings."); + +#define OS_EXECV_METHODDEF \ + {"execv", (PyCFunction)os_execv, METH_VARARGS, os_execv__doc__}, + +static PyObject * +os_execv_impl(PyModuleDef *module, PyObject *path, PyObject *argv); static PyObject * -posix_execv(PyObject *self, PyObject *args) +os_execv(PyModuleDef *module, PyObject *args) { - PyObject *opath; - char *path; + PyObject *return_value = NULL; + PyObject *path = NULL; PyObject *argv; + + if (!PyArg_ParseTuple(args, + "O&O:execv", + PyUnicode_FSConverter, &path, &argv)) + goto exit; + return_value = os_execv_impl(module, path, argv); + +exit: + /* Cleanup for path */ + Py_XDECREF(path); + + return return_value; +} + +static PyObject * +os_execv_impl(PyModuleDef *module, PyObject *path, PyObject *argv) +/*[clinic end generated code: output=b0f5f2caa6097edc input=96041559925e5229]*/ +{ + char *path_char; char **argvlist; Py_ssize_t argc; /* execv has two arguments: (path, argv), where argv is a list or tuple of strings. */ - if (!PyArg_ParseTuple(args, "O&O:execv", - PyUnicode_FSConverter, - &opath, &argv)) - return NULL; - path = PyBytes_AsString(opath); + path_char = PyBytes_AsString(path); if (!PyList_Check(argv) && !PyTuple_Check(argv)) { PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list"); - Py_DECREF(opath); return NULL; } argc = PySequence_Size(argv); if (argc < 1) { PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty"); - Py_DECREF(opath); return NULL; } argvlist = parse_arglist(argv, &argc); if (argvlist == NULL) { - Py_DECREF(opath); return NULL; } - execv(path, argvlist); + execv(path_char, argvlist); /* If we get here it's definitely an error */ free_string_array(argvlist, argc); - Py_DECREF(opath); return posix_error(); } -PyDoc_STRVAR(posix_execve__doc__, -"execve(path, args, env)\n\n\ -Execute a path with arguments and environment, replacing current process.\n\ -\n\ - path: path of executable file\n\ - args: tuple or list of arguments\n\ - env: dictionary of strings mapping to strings\n\ -\n\ -On some platforms, you may specify an open file descriptor for path;\n\ - execve will execute the program the file descriptor is open to.\n\ - If this functionality is unavailable, using it raises NotImplementedError."); -static PyObject * -posix_execve(PyObject *self, PyObject *args, PyObject *kwargs) -{ - path_t path; - PyObject *argv, *env; - char **argvlist = NULL; +/*[clinic input] +os.execve + + path: path_t(allow_fd='PATH_HAVE_FEXECVE') + Path of executable file. + argv: object + Tuple or list of strings. + env: object + Dictionary of strings mapping to strings. + +Execute an executable path with arguments, replacing current process. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_execve__doc__, +"execve($module, /, path, argv, env)\n" +"--\n" +"\n" +"Execute an executable path with arguments, replacing current process.\n" +"\n" +" path\n" +" Path of executable file.\n" +" argv\n" +" Tuple or list of strings.\n" +" env\n" +" Dictionary of strings mapping to strings."); + +#define OS_EXECVE_METHODDEF \ + {"execve", (PyCFunction)os_execve, METH_VARARGS|METH_KEYWORDS, os_execve__doc__}, + +static PyObject * +os_execve_impl(PyModuleDef *module, path_t *path, PyObject *argv, PyObject *env); + +static PyObject * +os_execve(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "argv", "env", NULL}; + path_t path = PATH_T_INITIALIZE("execve", "path", 0, PATH_HAVE_FEXECVE); + PyObject *argv; + PyObject *env; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&OO:execve", _keywords, + path_converter, &path, &argv, &env)) + goto exit; + return_value = os_execve_impl(module, &path, argv, env); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +static PyObject * +os_execve_impl(PyModuleDef *module, path_t *path, PyObject *argv, PyObject *env) +/*[clinic end generated code: output=fb283760f5d15ab7 input=626804fa092606d9]*/ +{ + char **argvlist = NULL; char **envlist; Py_ssize_t argc, envc; - static char *keywords[] = {"path", "argv", "environment", NULL}; /* execve has three arguments: (path, argv, env), where argv is a list or tuple of strings and env is a dictionary like posix.environ. */ - memset(&path, 0, sizeof(path)); - path.function_name = "execve"; -#ifdef HAVE_FEXECVE - path.allow_fd = 1; -#endif - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&OO:execve", keywords, - path_converter, &path, - &argv, &env - )) - return NULL; - if (!PyList_Check(argv) && !PyTuple_Check(argv)) { PyErr_SetString(PyExc_TypeError, "execve: argv must be a tuple or list"); @@ -5285,15 +6722,15 @@ posix_execve(PyObject *self, PyObject *args, PyObject *kwargs) goto fail; #ifdef HAVE_FEXECVE - if (path.fd > -1) - fexecve(path.fd, argvlist, envlist); + if (path->fd > -1) + fexecve(path->fd, argvlist, envlist); else #endif - execve(path.narrow, argvlist, envlist); + execve(path->narrow, argvlist, envlist); /* If we get here it's definitely an error */ - path_error(&path); + path_error(path); while (--envc >= 0) PyMem_DEL(envlist[envc]); @@ -5301,29 +6738,73 @@ posix_execve(PyObject *self, PyObject *args, PyObject *kwargs) fail: if (argvlist) free_string_array(argvlist, argc); - path_cleanup(&path); return NULL; } #endif /* HAVE_EXECV */ #ifdef HAVE_SPAWNV -PyDoc_STRVAR(posix_spawnv__doc__, -"spawnv(mode, path, args)\n\n\ -Execute the program 'path' in a new process.\n\ -\n\ - mode: mode of process creation\n\ - path: path of executable file\n\ - args: tuple or list of strings"); +/*[clinic input] +os.spawnv + + mode: int + Mode of process creation. + path: FSConverter + Path of executable file. + argv: object + Tuple or list of strings. + / + +Execute the program specified by path in a new process. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_spawnv__doc__, +"spawnv($module, mode, path, argv, /)\n" +"--\n" +"\n" +"Execute the program specified by path in a new process.\n" +"\n" +" mode\n" +" Mode of process creation.\n" +" path\n" +" Path of executable file.\n" +" argv\n" +" Tuple or list of strings."); + +#define OS_SPAWNV_METHODDEF \ + {"spawnv", (PyCFunction)os_spawnv, METH_VARARGS, os_spawnv__doc__}, + +static PyObject * +os_spawnv_impl(PyModuleDef *module, int mode, PyObject *path, PyObject *argv); static PyObject * -posix_spawnv(PyObject *self, PyObject *args) +os_spawnv(PyModuleDef *module, PyObject *args) { - PyObject *opath; - char *path; + PyObject *return_value = NULL; + int mode; + PyObject *path = NULL; PyObject *argv; + + if (!PyArg_ParseTuple(args, + "iO&O:spawnv", + &mode, PyUnicode_FSConverter, &path, &argv)) + goto exit; + return_value = os_spawnv_impl(module, mode, path, argv); + +exit: + /* Cleanup for path */ + Py_XDECREF(path); + + return return_value; +} + +static PyObject * +os_spawnv_impl(PyModuleDef *module, int mode, PyObject *path, PyObject *argv) +/*[clinic end generated code: output=dfee6be062e780e3 input=042c91dfc1e6debc]*/ +{ + char *path_char; char **argvlist; - int mode, i; + int i; Py_ssize_t argc; Py_intptr_t spawnval; PyObject *(*getitem)(PyObject *, Py_ssize_t); @@ -5331,11 +6812,7 @@ posix_spawnv(PyObject *self, PyObject *args) /* spawnv has three arguments: (mode, path, argv), where argv is a list or tuple of strings. */ - if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode, - PyUnicode_FSConverter, - &opath, &argv)) - return NULL; - path = PyBytes_AsString(opath); + path_char = PyBytes_AsString(path); if (PyList_Check(argv)) { argc = PyList_Size(argv); getitem = PyList_GetItem; @@ -5347,13 +6824,11 @@ posix_spawnv(PyObject *self, PyObject *args) else { PyErr_SetString(PyExc_TypeError, "spawnv() arg 2 must be a tuple or list"); - Py_DECREF(opath); return NULL; } argvlist = PyMem_NEW(char *, argc+1); if (argvlist == NULL) { - Py_DECREF(opath); return PyErr_NoMemory(); } for (i = 0; i < argc; i++) { @@ -5363,7 +6838,6 @@ posix_spawnv(PyObject *self, PyObject *args) PyErr_SetString( PyExc_TypeError, "spawnv() arg 2 must contain only strings"); - Py_DECREF(opath); return NULL; } } @@ -5373,11 +6847,10 @@ posix_spawnv(PyObject *self, PyObject *args) mode = _P_OVERLAY; Py_BEGIN_ALLOW_THREADS - spawnval = _spawnv(mode, path, argvlist); + spawnval = _spawnv(mode, path_char, argvlist); Py_END_ALLOW_THREADS free_string_array(argvlist, argc); - Py_DECREF(opath); if (spawnval == -1) return posix_error(); @@ -5386,25 +6859,73 @@ posix_spawnv(PyObject *self, PyObject *args) } -PyDoc_STRVAR(posix_spawnve__doc__, -"spawnve(mode, path, args, env)\n\n\ -Execute the program 'path' in a new process.\n\ -\n\ - mode: mode of process creation\n\ - path: path of executable file\n\ - args: tuple or list of arguments\n\ - env: dictionary of strings mapping to strings"); +/*[clinic input] +os.spawnve + + mode: int + Mode of process creation. + path: FSConverter + Path of executable file. + argv: object + Tuple or list of strings. + env: object + Dictionary of strings mapping to strings. + / + +Execute the program specified by path in a new process. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_spawnve__doc__, +"spawnve($module, mode, path, argv, env, /)\n" +"--\n" +"\n" +"Execute the program specified by path in a new process.\n" +"\n" +" mode\n" +" Mode of process creation.\n" +" path\n" +" Path of executable file.\n" +" argv\n" +" Tuple or list of strings.\n" +" env\n" +" Dictionary of strings mapping to strings."); + +#define OS_SPAWNVE_METHODDEF \ + {"spawnve", (PyCFunction)os_spawnve, METH_VARARGS, os_spawnve__doc__}, + +static PyObject * +os_spawnve_impl(PyModuleDef *module, int mode, PyObject *path, PyObject *argv, PyObject *env); + +static PyObject * +os_spawnve(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int mode; + PyObject *path = NULL; + PyObject *argv; + PyObject *env; + + if (!PyArg_ParseTuple(args, + "iO&OO:spawnve", + &mode, PyUnicode_FSConverter, &path, &argv, &env)) + goto exit; + return_value = os_spawnve_impl(module, mode, path, argv, env); + +exit: + /* Cleanup for path */ + Py_XDECREF(path); + + return return_value; +} static PyObject * -posix_spawnve(PyObject *self, PyObject *args) +os_spawnve_impl(PyModuleDef *module, int mode, PyObject *path, PyObject *argv, PyObject *env) +/*[clinic end generated code: output=6f7df38473f63c7c input=02362fd937963f8f]*/ { - PyObject *opath; - char *path; - PyObject *argv, *env; + char *path_char; char **argvlist; char **envlist; PyObject *res = NULL; - int mode; Py_ssize_t argc, i, envc; Py_intptr_t spawnval; PyObject *(*getitem)(PyObject *, Py_ssize_t); @@ -5414,11 +6935,7 @@ posix_spawnve(PyObject *self, PyObject *args) argv is a list or tuple of strings and env is a dictionary like posix.environ. */ - if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode, - PyUnicode_FSConverter, - &opath, &argv, &env)) - return NULL; - path = PyBytes_AsString(opath); + path_char = PyBytes_AsString(path); if (PyList_Check(argv)) { argc = PyList_Size(argv); getitem = PyList_GetItem; @@ -5462,7 +6979,7 @@ posix_spawnve(PyObject *self, PyObject *args) mode = _P_OVERLAY; Py_BEGIN_ALLOW_THREADS - spawnval = _spawnve(mode, path, argvlist, envlist); + spawnval = _spawnve(mode, path_char, argvlist, envlist); Py_END_ALLOW_THREADS if (spawnval == -1) @@ -5476,7 +6993,6 @@ posix_spawnve(PyObject *self, PyObject *args) fail_1: free_string_array(argvlist, lastarg); fail_0: - Py_DECREF(opath); return res; } @@ -5484,14 +7000,37 @@ posix_spawnve(PyObject *self, PyObject *args) #ifdef HAVE_FORK1 -PyDoc_STRVAR(posix_fork1__doc__, -"fork1() -> pid\n\n\ -Fork a child process with a single multiplexed (i.e., not bound) thread.\n\ -\n\ -Return 0 to child process and PID of child to parent process."); +/*[clinic input] +os.fork1 + +Fork a child process with a single multiplexed (i.e., not bound) thread. + +Return 0 to child process and PID of child to parent process. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_fork1__doc__, +"fork1($module, /)\n" +"--\n" +"\n" +"Fork a child process with a single multiplexed (i.e., not bound) thread.\n" +"\n" +"Return 0 to child process and PID of child to parent process."); + +#define OS_FORK1_METHODDEF \ + {"fork1", (PyCFunction)os_fork1, METH_NOARGS, os_fork1__doc__}, + +static PyObject * +os_fork1_impl(PyModuleDef *module); static PyObject * -posix_fork1(PyObject *self, PyObject *noargs) +os_fork1(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_fork1_impl(module); +} + +static PyObject * +os_fork1_impl(PyModuleDef *module) +/*[clinic end generated code: output=fa04088d6bc02efa input=12db02167893926e]*/ { pid_t pid; int result = 0; @@ -5514,17 +7053,41 @@ posix_fork1(PyObject *self, PyObject *noargs) } return PyLong_FromPid(pid); } -#endif +#endif /* HAVE_FORK1 */ #ifdef HAVE_FORK -PyDoc_STRVAR(posix_fork__doc__, -"fork() -> pid\n\n\ -Fork a child process.\n\ -Return 0 to child process and PID of child to parent process."); +/*[clinic input] +os.fork + +Fork a child process. + +Return 0 to child process and PID of child to parent process. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_fork__doc__, +"fork($module, /)\n" +"--\n" +"\n" +"Fork a child process.\n" +"\n" +"Return 0 to child process and PID of child to parent process."); + +#define OS_FORK_METHODDEF \ + {"fork", (PyCFunction)os_fork, METH_NOARGS, os_fork__doc__}, + +static PyObject * +os_fork_impl(PyModuleDef *module); + +static PyObject * +os_fork(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_fork_impl(module); +} static PyObject * -posix_fork(PyObject *self, PyObject *noargs) +os_fork_impl(PyModuleDef *module) +/*[clinic end generated code: output=b3c8e6bdc11eedc6 input=13c956413110eeaa]*/ { pid_t pid; int result = 0; @@ -5547,92 +7110,221 @@ posix_fork(PyObject *self, PyObject *noargs) } return PyLong_FromPid(pid); } -#endif +#endif /* HAVE_FORK */ -#ifdef HAVE_SCHED_H +#ifdef HAVE_SCHED_H #ifdef HAVE_SCHED_GET_PRIORITY_MAX +/*[clinic input] +os.sched_get_priority_max + + policy: int + +Get the maximum scheduling priority for policy. +[clinic start generated code]*/ -PyDoc_STRVAR(posix_sched_get_priority_max__doc__, -"sched_get_priority_max(policy)\n\n\ -Get the maximum scheduling priority for *policy*."); +PyDoc_STRVAR(os_sched_get_priority_max__doc__, +"sched_get_priority_max($module, /, policy)\n" +"--\n" +"\n" +"Get the maximum scheduling priority for policy."); + +#define OS_SCHED_GET_PRIORITY_MAX_METHODDEF \ + {"sched_get_priority_max", (PyCFunction)os_sched_get_priority_max, METH_VARARGS|METH_KEYWORDS, os_sched_get_priority_max__doc__}, + +static PyObject * +os_sched_get_priority_max_impl(PyModuleDef *module, int policy); static PyObject * -posix_sched_get_priority_max(PyObject *self, PyObject *args) +os_sched_get_priority_max(PyModuleDef *module, PyObject *args, PyObject *kwargs) { - int policy, max; + PyObject *return_value = NULL; + static char *_keywords[] = {"policy", NULL}; + int policy; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "i:sched_get_priority_max", _keywords, + &policy)) + goto exit; + return_value = os_sched_get_priority_max_impl(module, policy); + +exit: + return return_value; +} + +static PyObject * +os_sched_get_priority_max_impl(PyModuleDef *module, int policy) +/*[clinic end generated code: output=a580a52f25238c1f input=2097b7998eca6874]*/ +{ + int max; - if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy)) - return NULL; max = sched_get_priority_max(policy); if (max < 0) return posix_error(); return PyLong_FromLong(max); } -PyDoc_STRVAR(posix_sched_get_priority_min__doc__, -"sched_get_priority_min(policy)\n\n\ -Get the minimum scheduling priority for *policy*."); + +/*[clinic input] +os.sched_get_priority_min + + policy: int + +Get the minimum scheduling priority for policy. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_sched_get_priority_min__doc__, +"sched_get_priority_min($module, /, policy)\n" +"--\n" +"\n" +"Get the minimum scheduling priority for policy."); + +#define OS_SCHED_GET_PRIORITY_MIN_METHODDEF \ + {"sched_get_priority_min", (PyCFunction)os_sched_get_priority_min, METH_VARARGS|METH_KEYWORDS, os_sched_get_priority_min__doc__}, + +static PyObject * +os_sched_get_priority_min_impl(PyModuleDef *module, int policy); static PyObject * -posix_sched_get_priority_min(PyObject *self, PyObject *args) +os_sched_get_priority_min(PyModuleDef *module, PyObject *args, PyObject *kwargs) { - int policy, min; + PyObject *return_value = NULL; + static char *_keywords[] = {"policy", NULL}; + int policy; - if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy)) - return NULL; - min = sched_get_priority_min(policy); + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "i:sched_get_priority_min", _keywords, + &policy)) + goto exit; + return_value = os_sched_get_priority_min_impl(module, policy); + +exit: + return return_value; +} + +static PyObject * +os_sched_get_priority_min_impl(PyModuleDef *module, int policy) +/*[clinic end generated code: output=bad8ba10e7d0e977 input=21bc8fa0d70983bf]*/ +{ + int min = sched_get_priority_min(policy); if (min < 0) return posix_error(); return PyLong_FromLong(min); } - #endif /* HAVE_SCHED_GET_PRIORITY_MAX */ + #ifdef HAVE_SCHED_SETSCHEDULER +/*[clinic input] +os.sched_getscheduler + pid: pid_t + / -PyDoc_STRVAR(posix_sched_getscheduler__doc__, -"sched_getscheduler(pid)\n\n\ -Get the scheduling policy for the process with a PID of *pid*.\n\ -Passing a PID of 0 returns the scheduling policy for the calling process."); +Get the scheduling policy for the process identifiedy by pid. + +Passing 0 for pid returns the scheduling policy for the calling process. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_sched_getscheduler__doc__, +"sched_getscheduler($module, pid, /)\n" +"--\n" +"\n" +"Get the scheduling policy for the process identifiedy by pid.\n" +"\n" +"Passing 0 for pid returns the scheduling policy for the calling process."); + +#define OS_SCHED_GETSCHEDULER_METHODDEF \ + {"sched_getscheduler", (PyCFunction)os_sched_getscheduler, METH_VARARGS, os_sched_getscheduler__doc__}, + +static PyObject * +os_sched_getscheduler_impl(PyModuleDef *module, pid_t pid); static PyObject * -posix_sched_getscheduler(PyObject *self, PyObject *args) +os_sched_getscheduler(PyModuleDef *module, PyObject *args) { + PyObject *return_value = NULL; pid_t pid; + + if (!PyArg_ParseTuple(args, + "" _Py_PARSE_PID ":sched_getscheduler", + &pid)) + goto exit; + return_value = os_sched_getscheduler_impl(module, pid); + +exit: + return return_value; +} + +static PyObject * +os_sched_getscheduler_impl(PyModuleDef *module, pid_t pid) +/*[clinic end generated code: output=e0d6244207b1d828 input=5f14cfd1f189e1a0]*/ +{ int policy; - if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid)) - return NULL; policy = sched_getscheduler(pid); if (policy < 0) return posix_error(); return PyLong_FromLong(policy); } +#endif /* HAVE_SCHED_SETSCHEDULER */ -#endif #if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) +/*[clinic input] +class os.sched_param "PyObject *" "&SchedParamType" + +@classmethod +os.sched_param.__new__ + + sched_priority: object + A scheduling parameter. + +Current has only one field: sched_priority"); +[clinic start generated code]*/ + +PyDoc_STRVAR(os_sched_param__doc__, +"sched_param(sched_priority)\n" +"--\n" +"\n" +"Current has only one field: sched_priority\");\n" +"\n" +" sched_priority\n" +" A scheduling parameter."); + +static PyObject * +os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority); static PyObject * -sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +os_sched_param(PyTypeObject *type, PyObject *args, PyObject *kwargs) { - PyObject *res, *priority; - static char *kwlist[] = {"sched_priority", NULL}; + PyObject *return_value = NULL; + static char *_keywords[] = {"sched_priority", NULL}; + PyObject *sched_priority; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O:sched_param", _keywords, + &sched_priority)) + goto exit; + return_value = os_sched_param_impl(type, sched_priority); + +exit: + return return_value; +} + +static PyObject * +os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority) +/*[clinic end generated code: output=d3791e345f7fe573 input=73a4c22f7071fc62]*/ +{ + PyObject *res; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority)) - return NULL; res = PyStructSequence_New(type); if (!res) return NULL; - Py_INCREF(priority); - PyStructSequence_SET_ITEM(res, 0, priority); + Py_INCREF(sched_priority); + PyStructSequence_SET_ITEM(res, 0, sched_priority); return res; } -PyDoc_STRVAR(sched_param__doc__, -"sched_param(sched_priority): A scheduling parameter.\n\n\ -Current has only one field: sched_priority"); static PyStructSequence_Field sched_param_fields[] = { {"sched_priority", "the scheduling priority"}, @@ -5641,7 +7333,7 @@ static PyStructSequence_Field sched_param_fields[] = { static PyStructSequence_Desc sched_param_desc = { "sched_param", /* name */ - sched_param__doc__, /* doc */ + os_sched_param__doc__, /* doc */ sched_param_fields, 1 }; @@ -5665,118 +7357,280 @@ convert_sched_param(PyObject *param, struct sched_param *res) res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int); return 1; } +#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */ -#endif #ifdef HAVE_SCHED_SETSCHEDULER +/*[clinic input] +os.sched_setscheduler + + pid: pid_t + policy: int + param: sched_param + / + +Set the scheduling policy for the process identified by pid. + +If pid is 0, the calling process is changed. +param is an instance of sched_param. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_sched_setscheduler__doc__, +"sched_setscheduler($module, pid, policy, param, /)\n" +"--\n" +"\n" +"Set the scheduling policy for the process identified by pid.\n" +"\n" +"If pid is 0, the calling process is changed.\n" +"param is an instance of sched_param."); -PyDoc_STRVAR(posix_sched_setscheduler__doc__, -"sched_setscheduler(pid, policy, param)\n\n\ -Set the scheduling policy, *policy*, for *pid*.\n\ -If *pid* is 0, the calling process is changed.\n\ -*param* is an instance of sched_param."); +#define OS_SCHED_SETSCHEDULER_METHODDEF \ + {"sched_setscheduler", (PyCFunction)os_sched_setscheduler, METH_VARARGS, os_sched_setscheduler__doc__}, + +static PyObject * +os_sched_setscheduler_impl(PyModuleDef *module, pid_t pid, int policy, struct sched_param *param); static PyObject * -posix_sched_setscheduler(PyObject *self, PyObject *args) +os_sched_setscheduler(PyModuleDef *module, PyObject *args) { + PyObject *return_value = NULL; pid_t pid; int policy; struct sched_param param; - if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler", - &pid, &policy, &convert_sched_param, ¶m)) - return NULL; + if (!PyArg_ParseTuple(args, + "" _Py_PARSE_PID "iO&:sched_setscheduler", + &pid, &policy, convert_sched_param, ¶m)) + goto exit; + return_value = os_sched_setscheduler_impl(module, pid, policy, ¶m); +exit: + return return_value; +} + +static PyObject * +os_sched_setscheduler_impl(PyModuleDef *module, pid_t pid, int policy, struct sched_param *param) +/*[clinic end generated code: output=36abdb73f81c224f input=c581f9469a5327dd]*/ +{ /* ** sched_setscheduler() returns 0 in Linux, but the previous ** scheduling policy under Solaris/Illumos, and others. ** On error, -1 is returned in all Operating Systems. */ - if (sched_setscheduler(pid, policy, ¶m) == -1) + if (sched_setscheduler(pid, policy, param) == -1) return posix_error(); Py_RETURN_NONE; } +#endif /* HAVE_SCHED_SETSCHEDULER*/ -#endif #ifdef HAVE_SCHED_SETPARAM +/*[clinic input] +os.sched_getparam + pid: pid_t + / -PyDoc_STRVAR(posix_sched_getparam__doc__, -"sched_getparam(pid) -> sched_param\n\n\ -Returns scheduling parameters for the process with *pid* as an instance of the\n\ -sched_param class. A PID of 0 means the calling process."); +Returns scheduling parameters for the process identified by pid. + +If pid is 0, returns parameters for the calling process. +Return value is an instance of sched_param. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_sched_getparam__doc__, +"sched_getparam($module, pid, /)\n" +"--\n" +"\n" +"Returns scheduling parameters for the process identified by pid.\n" +"\n" +"If pid is 0, returns parameters for the calling process.\n" +"Return value is an instance of sched_param."); + +#define OS_SCHED_GETPARAM_METHODDEF \ + {"sched_getparam", (PyCFunction)os_sched_getparam, METH_VARARGS, os_sched_getparam__doc__}, + +static PyObject * +os_sched_getparam_impl(PyModuleDef *module, pid_t pid); static PyObject * -posix_sched_getparam(PyObject *self, PyObject *args) +os_sched_getparam(PyModuleDef *module, PyObject *args) { + PyObject *return_value = NULL; pid_t pid; + + if (!PyArg_ParseTuple(args, + "" _Py_PARSE_PID ":sched_getparam", + &pid)) + goto exit; + return_value = os_sched_getparam_impl(module, pid); + +exit: + return return_value; +} + +static PyObject * +os_sched_getparam_impl(PyModuleDef *module, pid_t pid) +/*[clinic end generated code: output=b33acc8db004a8c9 input=18a1ef9c2efae296]*/ +{ struct sched_param param; - PyObject *res, *priority; + PyObject *result; + PyObject *priority; - if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid)) - return NULL; if (sched_getparam(pid, ¶m)) return posix_error(); - res = PyStructSequence_New(&SchedParamType); - if (!res) + result = PyStructSequence_New(&SchedParamType); + if (!result) return NULL; priority = PyLong_FromLong(param.sched_priority); if (!priority) { - Py_DECREF(res); + Py_DECREF(result); return NULL; } - PyStructSequence_SET_ITEM(res, 0, priority); - return res; + PyStructSequence_SET_ITEM(result, 0, priority); + return result; } -PyDoc_STRVAR(posix_sched_setparam__doc__, -"sched_setparam(pid, param)\n\n\ -Set scheduling parameters for a process with PID *pid*.\n\ -A PID of 0 means the calling process."); + +/*[clinic input] +os.sched_setparam + pid: pid_t + param: sched_param + / + +Set scheduling parameters for the process identified by pid. + +If pid is 0, sets parameters for the calling process. +param should be an instance of sched_param. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_sched_setparam__doc__, +"sched_setparam($module, pid, param, /)\n" +"--\n" +"\n" +"Set scheduling parameters for the process identified by pid.\n" +"\n" +"If pid is 0, sets parameters for the calling process.\n" +"param should be an instance of sched_param."); + +#define OS_SCHED_SETPARAM_METHODDEF \ + {"sched_setparam", (PyCFunction)os_sched_setparam, METH_VARARGS, os_sched_setparam__doc__}, + +static PyObject * +os_sched_setparam_impl(PyModuleDef *module, pid_t pid, struct sched_param *param); static PyObject * -posix_sched_setparam(PyObject *self, PyObject *args) +os_sched_setparam(PyModuleDef *module, PyObject *args) { + PyObject *return_value = NULL; pid_t pid; struct sched_param param; - if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam", - &pid, &convert_sched_param, ¶m)) - return NULL; - if (sched_setparam(pid, ¶m)) + if (!PyArg_ParseTuple(args, + "" _Py_PARSE_PID "O&:sched_setparam", + &pid, convert_sched_param, ¶m)) + goto exit; + return_value = os_sched_setparam_impl(module, pid, ¶m); + +exit: + return return_value; +} + +static PyObject * +os_sched_setparam_impl(PyModuleDef *module, pid_t pid, struct sched_param *param) +/*[clinic end generated code: output=488bdf5bcbe0d4e8 input=6b8d6dfcecdc21bd]*/ +{ + if (sched_setparam(pid, param)) return posix_error(); Py_RETURN_NONE; } +#endif /* HAVE_SCHED_SETPARAM */ -#endif #ifdef HAVE_SCHED_RR_GET_INTERVAL +/*[clinic input] +os.sched_rr_get_interval -> double + pid: pid_t + / -PyDoc_STRVAR(posix_sched_rr_get_interval__doc__, -"sched_rr_get_interval(pid) -> float\n\n\ -Return the round-robin quantum for the process with PID *pid* in seconds."); +Return the round-robin quantum for the process identified by pid, in seconds. + +Value returned is a float. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_sched_rr_get_interval__doc__, +"sched_rr_get_interval($module, pid, /)\n" +"--\n" +"\n" +"Return the round-robin quantum for the process identified by pid, in seconds.\n" +"\n" +"Value returned is a float."); + +#define OS_SCHED_RR_GET_INTERVAL_METHODDEF \ + {"sched_rr_get_interval", (PyCFunction)os_sched_rr_get_interval, METH_VARARGS, os_sched_rr_get_interval__doc__}, + +static double +os_sched_rr_get_interval_impl(PyModuleDef *module, pid_t pid); static PyObject * -posix_sched_rr_get_interval(PyObject *self, PyObject *args) +os_sched_rr_get_interval(PyModuleDef *module, PyObject *args) { + PyObject *return_value = NULL; pid_t pid; - struct timespec interval; + double _return_value; - if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid)) - return NULL; - if (sched_rr_get_interval(pid, &interval)) - return posix_error(); - return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec); + if (!PyArg_ParseTuple(args, + "" _Py_PARSE_PID ":sched_rr_get_interval", + &pid)) + goto exit; + _return_value = os_sched_rr_get_interval_impl(module, pid); + if ((_return_value == -1.0) && PyErr_Occurred()) + goto exit; + return_value = PyFloat_FromDouble(_return_value); + +exit: + return return_value; } -#endif +static double +os_sched_rr_get_interval_impl(PyModuleDef *module, pid_t pid) +/*[clinic end generated code: output=5b3b8d1f27fb2c0a input=2a973da15cca6fae]*/ +{ + struct timespec interval; + if (sched_rr_get_interval(pid, &interval)) { + posix_error(); + return -1.0; + } + return (double)interval.tv_sec + 1e-9*interval.tv_nsec; +} +#endif /* HAVE_SCHED_RR_GET_INTERVAL */ + + +/*[clinic input] +os.sched_yield -PyDoc_STRVAR(posix_sched_yield__doc__, -"sched_yield()\n\n\ -Voluntarily relinquish the CPU."); +Voluntarily relinquish the CPU. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_sched_yield__doc__, +"sched_yield($module, /)\n" +"--\n" +"\n" +"Voluntarily relinquish the CPU."); + +#define OS_SCHED_YIELD_METHODDEF \ + {"sched_yield", (PyCFunction)os_sched_yield, METH_NOARGS, os_sched_yield__doc__}, + +static PyObject * +os_sched_yield_impl(PyModuleDef *module); + +static PyObject * +os_sched_yield(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_sched_yield_impl(module); +} static PyObject * -posix_sched_yield(PyObject *self, PyObject *noargs) +os_sched_yield_impl(PyModuleDef *module) +/*[clinic end generated code: output=9d2e5f29f1370324 input=e54d6f98189391d4]*/ { if (sched_yield()) return posix_error(); @@ -5784,39 +7638,72 @@ posix_sched_yield(PyObject *self, PyObject *noargs) } #ifdef HAVE_SCHED_SETAFFINITY - /* The minimum number of CPUs allocated in a cpu_set_t */ static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT; -PyDoc_STRVAR(posix_sched_setaffinity__doc__, -"sched_setaffinity(pid, cpu_set)\n\n\ -Set the affinity of the process with PID *pid* to *cpu_set*."); +/*[clinic input] +os.sched_setaffinity + pid: pid_t + mask : object + / + +Set the CPU affinity of the process identified by pid to mask. + +mask should be an iterable of integers identifying CPUs. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_sched_setaffinity__doc__, +"sched_setaffinity($module, pid, mask, /)\n" +"--\n" +"\n" +"Set the CPU affinity of the process identified by pid to mask.\n" +"\n" +"mask should be an iterable of integers identifying CPUs."); + +#define OS_SCHED_SETAFFINITY_METHODDEF \ + {"sched_setaffinity", (PyCFunction)os_sched_setaffinity, METH_VARARGS, os_sched_setaffinity__doc__}, + +static PyObject * +os_sched_setaffinity_impl(PyModuleDef *module, pid_t pid, PyObject *mask); static PyObject * -posix_sched_setaffinity(PyObject *self, PyObject *args) +os_sched_setaffinity(PyModuleDef *module, PyObject *args) { + PyObject *return_value = NULL; pid_t pid; + PyObject *mask; + + if (!PyArg_ParseTuple(args, + "" _Py_PARSE_PID "O:sched_setaffinity", + &pid, &mask)) + goto exit; + return_value = os_sched_setaffinity_impl(module, pid, mask); + +exit: + return return_value; +} + +static PyObject * +os_sched_setaffinity_impl(PyModuleDef *module, pid_t pid, PyObject *mask) +/*[clinic end generated code: output=5199929738130196 input=a0791a597c7085ba]*/ +{ int ncpus; size_t setsize; - cpu_set_t *mask = NULL; - PyObject *iterable, *iterator = NULL, *item; - - if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O:sched_setaffinity", - &pid, &iterable)) - return NULL; + cpu_set_t *cpu_set = NULL; + PyObject *iterator = NULL, *item; - iterator = PyObject_GetIter(iterable); + iterator = PyObject_GetIter(mask); if (iterator == NULL) return NULL; ncpus = NCPUS_START; setsize = CPU_ALLOC_SIZE(ncpus); - mask = CPU_ALLOC(ncpus); - if (mask == NULL) { + cpu_set = CPU_ALLOC(ncpus); + if (cpu_set == NULL) { PyErr_NoMemory(); goto error; } - CPU_ZERO_S(setsize, mask); + CPU_ZERO_S(setsize, cpu_set); while ((item = PyIter_Next(iterator))) { long cpu; @@ -5857,48 +7744,80 @@ posix_sched_setaffinity(PyObject *self, PyObject *args) } newsetsize = CPU_ALLOC_SIZE(newncpus); CPU_ZERO_S(newsetsize, newmask); - memcpy(newmask, mask, setsize); - CPU_FREE(mask); + memcpy(newmask, cpu_set, setsize); + CPU_FREE(cpu_set); setsize = newsetsize; - mask = newmask; + cpu_set = newmask; ncpus = newncpus; } - CPU_SET_S(cpu, setsize, mask); + CPU_SET_S(cpu, setsize, cpu_set); } Py_CLEAR(iterator); - if (sched_setaffinity(pid, setsize, mask)) { + if (sched_setaffinity(pid, setsize, cpu_set)) { posix_error(); goto error; } - CPU_FREE(mask); + CPU_FREE(cpu_set); Py_RETURN_NONE; error: - if (mask) - CPU_FREE(mask); + if (cpu_set) + CPU_FREE(cpu_set); Py_XDECREF(iterator); return NULL; } -PyDoc_STRVAR(posix_sched_getaffinity__doc__, -"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\ -Return the affinity of the process with PID *pid*.\n\ -The returned cpu_set will be of size *ncpus*."); + +/*[clinic input] +os.sched_getaffinity + pid: pid_t + / + +Return the affinity of the process identified by pid. + +The affinity is returned as a set of CPU identifiers. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_sched_getaffinity__doc__, +"sched_getaffinity($module, pid, /)\n" +"--\n" +"\n" +"Return the affinity of the process identified by pid.\n" +"\n" +"The affinity is returned as a set of CPU identifiers."); + +#define OS_SCHED_GETAFFINITY_METHODDEF \ + {"sched_getaffinity", (PyCFunction)os_sched_getaffinity, METH_VARARGS, os_sched_getaffinity__doc__}, static PyObject * -posix_sched_getaffinity(PyObject *self, PyObject *args) +os_sched_getaffinity_impl(PyModuleDef *module, pid_t pid); + +static PyObject * +os_sched_getaffinity(PyModuleDef *module, PyObject *args) { + PyObject *return_value = NULL; pid_t pid; + + if (!PyArg_ParseTuple(args, + "" _Py_PARSE_PID ":sched_getaffinity", + &pid)) + goto exit; + return_value = os_sched_getaffinity_impl(module, pid); + +exit: + return return_value; +} + +static PyObject * +os_sched_getaffinity_impl(PyModuleDef *module, pid_t pid) +/*[clinic end generated code: output=7b273b0fca9830f0 input=eaf161936874b8a1]*/ +{ int cpu, ncpus, count; size_t setsize; cpu_set_t *mask = NULL; PyObject *res = NULL; - if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getaffinity", - &pid)) - return NULL; - ncpus = NCPUS_START; while (1) { setsize = CPU_ALLOC_SIZE(ncpus); @@ -5948,6 +7867,47 @@ posix_sched_getaffinity(PyObject *self, PyObject *args) #endif /* HAVE_SCHED_H */ +#ifndef OS_SCHED_GET_PRIORITY_MAX_METHODDEF +#define OS_SCHED_GET_PRIORITY_MAX_METHODDEF +#endif /* OS_SCHED_GET_PRIORITY_MAX_METHODDEF */ + +#ifndef OS_SCHED_GET_PRIORITY_MIN_METHODDEF +#define OS_SCHED_GET_PRIORITY_MIN_METHODDEF +#endif /* OS_SCHED_GET_PRIORITY_MIN_METHODDEF */ + +#ifndef OS_SCHED_GETSCHEDULER_METHODDEF +#define OS_SCHED_GETSCHEDULER_METHODDEF +#endif /* OS_SCHED_GETSCHEDULER_METHODDEF */ + +#ifndef OS_SCHED_SETSCHEDULER_METHODDEF +#define OS_SCHED_SETSCHEDULER_METHODDEF +#endif /* OS_SCHED_SETSCHEDULER_METHODDEF */ + +#ifndef OS_SCHED_GETPARAM_METHODDEF +#define OS_SCHED_GETPARAM_METHODDEF +#endif /* OS_SCHED_GETPARAM_METHODDEF */ + +#ifndef OS_SCHED_SETPARAM_METHODDEF +#define OS_SCHED_SETPARAM_METHODDEF +#endif /* OS_SCHED_SETPARAM_METHODDEF */ + +#ifndef OS_SCHED_RR_GET_INTERVAL_METHODDEF +#define OS_SCHED_RR_GET_INTERVAL_METHODDEF +#endif /* OS_SCHED_RR_GET_INTERVAL_METHODDEF */ + +#ifndef OS_SCHED_YIELD_METHODDEF +#define OS_SCHED_YIELD_METHODDEF +#endif /* OS_SCHED_YIELD_METHODDEF */ + +#ifndef OS_SCHED_SETAFFINITY_METHODDEF +#define OS_SCHED_SETAFFINITY_METHODDEF +#endif /* OS_SCHED_SETAFFINITY_METHODDEF */ + +#ifndef OS_SCHED_GETAFFINITY_METHODDEF +#define OS_SCHED_GETAFFINITY_METHODDEF +#endif /* OS_SCHED_GETAFFINITY_METHODDEF */ + + /* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */ /* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */ #if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX) @@ -5974,13 +7934,41 @@ posix_sched_getaffinity(PyObject *self, PyObject *args) #endif #endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */ + #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) -PyDoc_STRVAR(posix_openpty__doc__, -"openpty() -> (master_fd, slave_fd)\n\n\ -Open a pseudo-terminal, returning open fd's for both master and slave end.\n"); +/*[clinic input] +os.openpty + +Open a pseudo-terminal. + +Return a tuple of (master_fd, slave_fd) containing open file descriptors +for both the master and slave ends. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_openpty__doc__, +"openpty($module, /)\n" +"--\n" +"\n" +"Open a pseudo-terminal.\n" +"\n" +"Return a tuple of (master_fd, slave_fd) containing open file descriptors\n" +"for both the master and slave ends."); + +#define OS_OPENPTY_METHODDEF \ + {"openpty", (PyCFunction)os_openpty, METH_NOARGS, os_openpty__doc__}, + +static PyObject * +os_openpty_impl(PyModuleDef *module); + +static PyObject * +os_openpty(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_openpty_impl(module); +} static PyObject * -posix_openpty(PyObject *self, PyObject *noargs) +os_openpty_impl(PyModuleDef *module) +/*[clinic end generated code: output=b12d3c1735468464 input=f3d99fd99e762907]*/ { int master_fd = -1, slave_fd = -1; #ifndef HAVE_OPENPTY @@ -6069,15 +8057,45 @@ posix_openpty(PyObject *self, PyObject *noargs) } #endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */ + #ifdef HAVE_FORKPTY -PyDoc_STRVAR(posix_forkpty__doc__, -"forkpty() -> (pid, master_fd)\n\n\ -Fork a new process with a new pseudo-terminal as controlling tty.\n\n\ -Like fork(), return 0 as pid to child process, and PID of child to parent.\n\ -To both, return fd of newly opened pseudo-terminal.\n"); +/*[clinic input] +os.forkpty + +Fork a new process with a new pseudo-terminal as controlling tty. + +Returns a tuple of (pid, master_fd). +Like fork(), return pid of 0 to the child process, +and pid of child to the parent process. +To both, return fd of newly opened pseudo-terminal. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_forkpty__doc__, +"forkpty($module, /)\n" +"--\n" +"\n" +"Fork a new process with a new pseudo-terminal as controlling tty.\n" +"\n" +"Returns a tuple of (pid, master_fd).\n" +"Like fork(), return pid of 0 to the child process,\n" +"and pid of child to the parent process.\n" +"To both, return fd of newly opened pseudo-terminal."); + +#define OS_FORKPTY_METHODDEF \ + {"forkpty", (PyCFunction)os_forkpty, METH_NOARGS, os_forkpty__doc__}, + +static PyObject * +os_forkpty_impl(PyModuleDef *module); + +static PyObject * +os_forkpty(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_forkpty_impl(module); +} static PyObject * -posix_forkpty(PyObject *self, PyObject *noargs) +os_forkpty_impl(PyModuleDef *module) +/*[clinic end generated code: output=d4f82958d2ed5cad input=f1f7f4bae3966010]*/ { int master_fd = -1, result = 0; pid_t pid; @@ -6101,59 +8119,145 @@ posix_forkpty(PyObject *self, PyObject *noargs) } return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd); } -#endif +#endif /* HAVE_FORKPTY */ #ifdef HAVE_GETEGID -PyDoc_STRVAR(posix_getegid__doc__, -"getegid() -> egid\n\n\ -Return the current process's effective group id."); +/*[clinic input] +os.getegid + +Return the current process's effective group id. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_getegid__doc__, +"getegid($module, /)\n" +"--\n" +"\n" +"Return the current process\'s effective group id."); + +#define OS_GETEGID_METHODDEF \ + {"getegid", (PyCFunction)os_getegid, METH_NOARGS, os_getegid__doc__}, + +static PyObject * +os_getegid_impl(PyModuleDef *module); static PyObject * -posix_getegid(PyObject *self, PyObject *noargs) +os_getegid(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_getegid_impl(module); +} + +static PyObject * +os_getegid_impl(PyModuleDef *module) +/*[clinic end generated code: output=fd12c346fa41cccb input=1596f79ad1107d5d]*/ { return _PyLong_FromGid(getegid()); } -#endif +#endif /* HAVE_GETEGID */ #ifdef HAVE_GETEUID -PyDoc_STRVAR(posix_geteuid__doc__, -"geteuid() -> euid\n\n\ -Return the current process's effective user id."); +/*[clinic input] +os.geteuid + +Return the current process's effective user id. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_geteuid__doc__, +"geteuid($module, /)\n" +"--\n" +"\n" +"Return the current process\'s effective user id."); + +#define OS_GETEUID_METHODDEF \ + {"geteuid", (PyCFunction)os_geteuid, METH_NOARGS, os_geteuid__doc__}, + +static PyObject * +os_geteuid_impl(PyModuleDef *module); + +static PyObject * +os_geteuid(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_geteuid_impl(module); +} static PyObject * -posix_geteuid(PyObject *self, PyObject *noargs) +os_geteuid_impl(PyModuleDef *module) +/*[clinic end generated code: output=03d98e07f4bc03d4 input=4644c662d3bd9f19]*/ { return _PyLong_FromUid(geteuid()); } -#endif +#endif /* HAVE_GETEUID */ #ifdef HAVE_GETGID -PyDoc_STRVAR(posix_getgid__doc__, -"getgid() -> gid\n\n\ -Return the current process's group id."); +/*[clinic input] +os.getgid + +Return the current process's group id. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_getgid__doc__, +"getgid($module, /)\n" +"--\n" +"\n" +"Return the current process\'s group id."); + +#define OS_GETGID_METHODDEF \ + {"getgid", (PyCFunction)os_getgid, METH_NOARGS, os_getgid__doc__}, + +static PyObject * +os_getgid_impl(PyModuleDef *module); static PyObject * -posix_getgid(PyObject *self, PyObject *noargs) +os_getgid(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_getgid_impl(module); +} + +static PyObject * +os_getgid_impl(PyModuleDef *module) +/*[clinic end generated code: output=07b0356121b8098d input=58796344cd87c0f6]*/ { return _PyLong_FromGid(getgid()); } -#endif +#endif /* HAVE_GETGID */ + + +/*[clinic input] +os.getpid +Return the current process id. +[clinic start generated code]*/ -PyDoc_STRVAR(posix_getpid__doc__, -"getpid() -> pid\n\n\ -Return the current process id"); +PyDoc_STRVAR(os_getpid__doc__, +"getpid($module, /)\n" +"--\n" +"\n" +"Return the current process id."); + +#define OS_GETPID_METHODDEF \ + {"getpid", (PyCFunction)os_getpid, METH_NOARGS, os_getpid__doc__}, + +static PyObject * +os_getpid_impl(PyModuleDef *module); + +static PyObject * +os_getpid(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_getpid_impl(module); +} static PyObject * -posix_getpid(PyObject *self, PyObject *noargs) +os_getpid_impl(PyModuleDef *module) +/*[clinic end generated code: output=d63a01a3cebc573d input=5a9a00f0ab68aa00]*/ { return PyLong_FromPid(getpid()); } #ifdef HAVE_GETGROUPLIST + +/* AC 3.5: funny apple logic below */ PyDoc_STRVAR(posix_getgrouplist__doc__, "getgrouplist(user, group) -> list of groups to which a user belongs\n\n\ Returns a list of groups to which a user belongs.\n\n\ @@ -6190,9 +8294,9 @@ posix_getgrouplist(PyObject *self, PyObject *args) #endif #ifdef __APPLE__ - groups = PyMem_Malloc(ngroups * sizeof(int)); + groups = PyMem_New(int, ngroups); #else - groups = PyMem_Malloc(ngroups * sizeof(gid_t)); + groups = PyMem_New(gid_t, ngroups); #endif if (groups == NULL) return PyErr_NoMemory(); @@ -6226,15 +8330,37 @@ posix_getgrouplist(PyObject *self, PyObject *args) return list; } -#endif +#endif /* HAVE_GETGROUPLIST */ + #ifdef HAVE_GETGROUPS -PyDoc_STRVAR(posix_getgroups__doc__, -"getgroups() -> list of group IDs\n\n\ -Return list of supplemental group IDs for the process."); +/*[clinic input] +os.getgroups + +Return list of supplemental group IDs for the process. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_getgroups__doc__, +"getgroups($module, /)\n" +"--\n" +"\n" +"Return list of supplemental group IDs for the process."); + +#define OS_GETGROUPS_METHODDEF \ + {"getgroups", (PyCFunction)os_getgroups, METH_NOARGS, os_getgroups__doc__}, + +static PyObject * +os_getgroups_impl(PyModuleDef *module); + +static PyObject * +os_getgroups(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_getgroups_impl(module); +} static PyObject * -posix_getgroups(PyObject *self, PyObject *noargs) +os_getgroups_impl(PyModuleDef *module) +/*[clinic end generated code: output=d9a3559b2e6f4ab8 input=d3f109412e6a155c]*/ { PyObject *result = NULL; @@ -6270,7 +8396,7 @@ posix_getgroups(PyObject *self, PyObject *noargs) /* groups will fit in existing array */ alt_grouplist = grouplist; } else { - alt_grouplist = PyMem_Malloc(n * sizeof(gid_t)); + alt_grouplist = PyMem_New(gid_t, n); if (alt_grouplist == NULL) { errno = EINVAL; return posix_error(); @@ -6296,7 +8422,7 @@ posix_getgroups(PyObject *self, PyObject *noargs) /* Avoid malloc(0) */ alt_grouplist = grouplist; } else { - alt_grouplist = PyMem_Malloc(n * sizeof(gid_t)); + alt_grouplist = PyMem_New(gid_t, n); if (alt_grouplist == NULL) { errno = EINVAL; return posix_error(); @@ -6333,7 +8459,7 @@ posix_getgroups(PyObject *self, PyObject *noargs) return result; } -#endif +#endif /* HAVE_GETGROUPS */ #ifdef HAVE_INITGROUPS PyDoc_STRVAR(posix_initgroups__doc__, @@ -6342,6 +8468,7 @@ Call the system initgroups() to initialize the group access list with all of\n\ the groups of which the specified username is a member, plus the specified\n\ group id."); +/* AC 3.5: funny apple logic */ static PyObject * posix_initgroups(PyObject *self, PyObject *args) { @@ -6374,20 +8501,52 @@ posix_initgroups(PyObject *self, PyObject *args) Py_INCREF(Py_None); return Py_None; } -#endif +#endif /* HAVE_INITGROUPS */ + #ifdef HAVE_GETPGID -PyDoc_STRVAR(posix_getpgid__doc__, -"getpgid(pid) -> pgid\n\n\ -Call the system call getpgid()."); +/*[clinic input] +os.getpgid + + pid: pid_t + +Call the system call getpgid(), and return the result. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_getpgid__doc__, +"getpgid($module, /, pid)\n" +"--\n" +"\n" +"Call the system call getpgid(), and return the result."); + +#define OS_GETPGID_METHODDEF \ + {"getpgid", (PyCFunction)os_getpgid, METH_VARARGS|METH_KEYWORDS, os_getpgid__doc__}, + +static PyObject * +os_getpgid_impl(PyModuleDef *module, pid_t pid); static PyObject * -posix_getpgid(PyObject *self, PyObject *args) +os_getpgid(PyModuleDef *module, PyObject *args, PyObject *kwargs) { - pid_t pid, pgid; - if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid)) - return NULL; - pgid = getpgid(pid); + PyObject *return_value = NULL; + static char *_keywords[] = {"pid", NULL}; + pid_t pid; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "" _Py_PARSE_PID ":getpgid", _keywords, + &pid)) + goto exit; + return_value = os_getpgid_impl(module, pid); + +exit: + return return_value; +} + +static PyObject * +os_getpgid_impl(PyModuleDef *module, pid_t pid) +/*[clinic end generated code: output=3db4ed686179160d input=39d710ae3baaf1c7]*/ +{ + pid_t pgid = getpgid(pid); if (pgid < 0) return posix_error(); return PyLong_FromPid(pgid); @@ -6396,12 +8555,33 @@ posix_getpgid(PyObject *self, PyObject *args) #ifdef HAVE_GETPGRP -PyDoc_STRVAR(posix_getpgrp__doc__, -"getpgrp() -> pgrp\n\n\ -Return the current process group id."); +/*[clinic input] +os.getpgrp + +Return the current process group id. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_getpgrp__doc__, +"getpgrp($module, /)\n" +"--\n" +"\n" +"Return the current process group id."); + +#define OS_GETPGRP_METHODDEF \ + {"getpgrp", (PyCFunction)os_getpgrp, METH_NOARGS, os_getpgrp__doc__}, + +static PyObject * +os_getpgrp_impl(PyModuleDef *module); + +static PyObject * +os_getpgrp(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_getpgrp_impl(module); +} static PyObject * -posix_getpgrp(PyObject *self, PyObject *noargs) +os_getpgrp_impl(PyModuleDef *module) +/*[clinic end generated code: output=3b0d3663ea054277 input=6846fb2bb9a3705e]*/ { #ifdef GETPGRP_HAVE_ARG return PyLong_FromPid(getpgrp(0)); @@ -6413,12 +8593,33 @@ posix_getpgrp(PyObject *self, PyObject *noargs) #ifdef HAVE_SETPGRP -PyDoc_STRVAR(posix_setpgrp__doc__, -"setpgrp()\n\n\ -Make this process the process group leader."); +/*[clinic input] +os.setpgrp + +Make the current process the leader of its process group. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_setpgrp__doc__, +"setpgrp($module, /)\n" +"--\n" +"\n" +"Make the current process the leader of its process group."); + +#define OS_SETPGRP_METHODDEF \ + {"setpgrp", (PyCFunction)os_setpgrp, METH_NOARGS, os_setpgrp__doc__}, + +static PyObject * +os_setpgrp_impl(PyModuleDef *module); + +static PyObject * +os_setpgrp(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_setpgrp_impl(module); +} static PyObject * -posix_setpgrp(PyObject *self, PyObject *noargs) +os_setpgrp_impl(PyModuleDef *module) +/*[clinic end generated code: output=8fbb0ee29ef6fb2d input=1f0619fcb5731e7e]*/ { #ifdef SETPGRP_HAVE_ARG if (setpgrp(0, 0) < 0) @@ -6429,7 +8630,6 @@ posix_setpgrp(PyObject *self, PyObject *noargs) Py_INCREF(Py_None); return Py_None; } - #endif /* HAVE_SETPGRP */ #ifdef HAVE_GETPPID @@ -6476,31 +8676,78 @@ win32_getppid() } #endif /*MS_WINDOWS*/ -PyDoc_STRVAR(posix_getppid__doc__, -"getppid() -> ppid\n\n\ -Return the parent's process id. If the parent process has already exited,\n\ -Windows machines will still return its id; others systems will return the id\n\ -of the 'init' process (1)."); -static PyObject * -posix_getppid(PyObject *self, PyObject *noargs) -{ -#ifdef MS_WINDOWS - return win32_getppid(); -#else - return PyLong_FromPid(getppid()); +/*[clinic input] +os.getppid + +Return the parent's process id. + +If the parent process has already exited, Windows machines will still +return its id; others systems will return the id of the 'init' process (1). +[clinic start generated code]*/ + +PyDoc_STRVAR(os_getppid__doc__, +"getppid($module, /)\n" +"--\n" +"\n" +"Return the parent\'s process id.\n" +"\n" +"If the parent process has already exited, Windows machines will still\n" +"return its id; others systems will return the id of the \'init\' process (1)."); + +#define OS_GETPPID_METHODDEF \ + {"getppid", (PyCFunction)os_getppid, METH_NOARGS, os_getppid__doc__}, + +static PyObject * +os_getppid_impl(PyModuleDef *module); + +static PyObject * +os_getppid(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_getppid_impl(module); +} + +static PyObject * +os_getppid_impl(PyModuleDef *module) +/*[clinic end generated code: output=9ff3b387781edf3a input=e637cb87539c030e]*/ +{ +#ifdef MS_WINDOWS + return win32_getppid(); +#else + return PyLong_FromPid(getppid()); #endif } #endif /* HAVE_GETPPID */ #ifdef HAVE_GETLOGIN -PyDoc_STRVAR(posix_getlogin__doc__, -"getlogin() -> string\n\n\ -Return the actual login name."); +/*[clinic input] +os.getlogin + +Return the actual login name. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_getlogin__doc__, +"getlogin($module, /)\n" +"--\n" +"\n" +"Return the actual login name."); + +#define OS_GETLOGIN_METHODDEF \ + {"getlogin", (PyCFunction)os_getlogin, METH_NOARGS, os_getlogin__doc__}, + +static PyObject * +os_getlogin_impl(PyModuleDef *module); + +static PyObject * +os_getlogin(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_getlogin_impl(module); +} static PyObject * -posix_getlogin(PyObject *self, PyObject *noargs) +os_getlogin_impl(PyModuleDef *module) +/*[clinic end generated code: output=ab6211dab104cbb2 input=2a21ab1e917163df]*/ { PyObject *result = NULL; #ifdef MS_WINDOWS @@ -6533,77 +8780,101 @@ posix_getlogin(PyObject *self, PyObject *noargs) } #endif /* HAVE_GETLOGIN */ + #ifdef HAVE_GETUID -PyDoc_STRVAR(posix_getuid__doc__, -"getuid() -> uid\n\n\ -Return the current process's user id."); +/*[clinic input] +os.getuid + +Return the current process's user id. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_getuid__doc__, +"getuid($module, /)\n" +"--\n" +"\n" +"Return the current process\'s user id."); + +#define OS_GETUID_METHODDEF \ + {"getuid", (PyCFunction)os_getuid, METH_NOARGS, os_getuid__doc__}, + +static PyObject * +os_getuid_impl(PyModuleDef *module); + +static PyObject * +os_getuid(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_getuid_impl(module); +} static PyObject * -posix_getuid(PyObject *self, PyObject *noargs) +os_getuid_impl(PyModuleDef *module) +/*[clinic end generated code: output=77e0dcf2e37d1e89 input=b53c8b35f110a516]*/ { return _PyLong_FromUid(getuid()); } -#endif +#endif /* HAVE_GETUID */ +#ifdef MS_WINDOWS +#define HAVE_KILL +#endif /* MS_WINDOWS */ + #ifdef HAVE_KILL -PyDoc_STRVAR(posix_kill__doc__, -"kill(pid, sig)\n\n\ -Kill a process with a signal."); +/*[clinic input] +os.kill + + pid: pid_t + signal: Py_ssize_t + / + +Kill a process with a signal. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_kill__doc__, +"kill($module, pid, signal, /)\n" +"--\n" +"\n" +"Kill a process with a signal."); + +#define OS_KILL_METHODDEF \ + {"kill", (PyCFunction)os_kill, METH_VARARGS, os_kill__doc__}, + +static PyObject * +os_kill_impl(PyModuleDef *module, pid_t pid, Py_ssize_t signal); static PyObject * -posix_kill(PyObject *self, PyObject *args) +os_kill(PyModuleDef *module, PyObject *args) { + PyObject *return_value = NULL; pid_t pid; - int sig; - if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig)) - return NULL; - if (kill(pid, sig) == -1) - return posix_error(); - Py_INCREF(Py_None); - return Py_None; -} -#endif + Py_ssize_t signal; -#ifdef HAVE_KILLPG -PyDoc_STRVAR(posix_killpg__doc__, -"killpg(pgid, sig)\n\n\ -Kill a process group with a signal."); + if (!PyArg_ParseTuple(args, + "" _Py_PARSE_PID "n:kill", + &pid, &signal)) + goto exit; + return_value = os_kill_impl(module, pid, signal); + +exit: + return return_value; +} static PyObject * -posix_killpg(PyObject *self, PyObject *args) +os_kill_impl(PyModuleDef *module, pid_t pid, Py_ssize_t signal) +/*[clinic end generated code: output=2f5c77920ed575e6 input=61a36b86ca275ab9]*/ +#ifndef MS_WINDOWS { - int sig; - pid_t pgid; - /* XXX some man pages make the `pgid` parameter an int, others - a pid_t. Since getpgrp() returns a pid_t, we assume killpg should - take the same type. Moreover, pid_t is always at least as wide as - int (else compilation of this module fails), which is safe. */ - if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig)) - return NULL; - if (killpg(pgid, sig) == -1) + if (kill(pid, (int)signal) == -1) return posix_error(); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } -#endif - -#ifdef MS_WINDOWS -PyDoc_STRVAR(win32_kill__doc__, -"kill(pid, sig)\n\n\ -Kill a process with a signal."); - -static PyObject * -win32_kill(PyObject *self, PyObject *args) +#else /* !MS_WINDOWS */ { PyObject *result; - pid_t pid; - DWORD sig, err; + DWORD sig = (DWORD)signal; + DWORD err; HANDLE handle; - if (!PyArg_ParseTuple(args, _Py_PARSE_PID "k:kill", &pid, &sig)) - return NULL; - /* Console processes which share a common console can be sent CTRL+C or CTRL+BREAK events, provided they handle said events. */ if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) { @@ -6634,103 +8905,308 @@ win32_kill(PyObject *self, PyObject *args) CloseHandle(handle); return result; } -#endif /* MS_WINDOWS */ +#endif /* !MS_WINDOWS */ +#endif /* HAVE_KILL */ -#ifdef HAVE_PLOCK +#ifdef HAVE_KILLPG +/*[clinic input] +os.killpg + + pgid: pid_t + signal: int + / + +Kill a process group with a signal. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_killpg__doc__, +"killpg($module, pgid, signal, /)\n" +"--\n" +"\n" +"Kill a process group with a signal."); + +#define OS_KILLPG_METHODDEF \ + {"killpg", (PyCFunction)os_killpg, METH_VARARGS, os_killpg__doc__}, + +static PyObject * +os_killpg_impl(PyModuleDef *module, pid_t pgid, int signal); + +static PyObject * +os_killpg(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + pid_t pgid; + int signal; + + if (!PyArg_ParseTuple(args, + "" _Py_PARSE_PID "i:killpg", + &pgid, &signal)) + goto exit; + return_value = os_killpg_impl(module, pgid, signal); + +exit: + return return_value; +} + +static PyObject * +os_killpg_impl(PyModuleDef *module, pid_t pgid, int signal) +/*[clinic end generated code: output=0e05215d1c007e01 input=38b5449eb8faec19]*/ +{ + /* XXX some man pages make the `pgid` parameter an int, others + a pid_t. Since getpgrp() returns a pid_t, we assume killpg should + take the same type. Moreover, pid_t is always at least as wide as + int (else compilation of this module fails), which is safe. */ + if (killpg(pgid, signal) == -1) + return posix_error(); + Py_RETURN_NONE; +} +#endif /* HAVE_KILLPG */ + + +#ifdef HAVE_PLOCK #ifdef HAVE_SYS_LOCK_H #include #endif -PyDoc_STRVAR(posix_plock__doc__, -"plock(op)\n\n\ +/*[clinic input] +os.plock + op: int + / + Lock program segments into memory."); +[clinic start generated code]*/ + +PyDoc_STRVAR(os_plock__doc__, +"plock($module, op, /)\n" +"--\n" +"\n" +"Lock program segments into memory.\");"); + +#define OS_PLOCK_METHODDEF \ + {"plock", (PyCFunction)os_plock, METH_VARARGS, os_plock__doc__}, + +static PyObject * +os_plock_impl(PyModuleDef *module, int op); static PyObject * -posix_plock(PyObject *self, PyObject *args) +os_plock(PyModuleDef *module, PyObject *args) { + PyObject *return_value = NULL; int op; - if (!PyArg_ParseTuple(args, "i:plock", &op)) - return NULL; + + if (!PyArg_ParseTuple(args, + "i:plock", + &op)) + goto exit; + return_value = os_plock_impl(module, op); + +exit: + return return_value; +} + +static PyObject * +os_plock_impl(PyModuleDef *module, int op) +/*[clinic end generated code: output=2744fe4b6e5f4dbc input=e6e5e348e1525f60]*/ +{ if (plock(op) == -1) return posix_error(); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } -#endif +#endif /* HAVE_PLOCK */ + #ifdef HAVE_SETUID -PyDoc_STRVAR(posix_setuid__doc__, -"setuid(uid)\n\n\ -Set the current process's user id."); +/*[clinic input] +os.setuid + + uid: uid_t + / + +Set the current process's user id. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_setuid__doc__, +"setuid($module, uid, /)\n" +"--\n" +"\n" +"Set the current process\'s user id."); + +#define OS_SETUID_METHODDEF \ + {"setuid", (PyCFunction)os_setuid, METH_VARARGS, os_setuid__doc__}, + +static PyObject * +os_setuid_impl(PyModuleDef *module, uid_t uid); static PyObject * -posix_setuid(PyObject *self, PyObject *args) +os_setuid(PyModuleDef *module, PyObject *args) { + PyObject *return_value = NULL; uid_t uid; - if (!PyArg_ParseTuple(args, "O&:setuid", _Py_Uid_Converter, &uid)) - return NULL; + + if (!PyArg_ParseTuple(args, + "O&:setuid", + _Py_Uid_Converter, &uid)) + goto exit; + return_value = os_setuid_impl(module, uid); + +exit: + return return_value; +} + +static PyObject * +os_setuid_impl(PyModuleDef *module, uid_t uid) +/*[clinic end generated code: output=aea344bc22ccf400 input=c921a3285aa22256]*/ +{ if (setuid(uid) < 0) return posix_error(); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } #endif /* HAVE_SETUID */ #ifdef HAVE_SETEUID -PyDoc_STRVAR(posix_seteuid__doc__, -"seteuid(uid)\n\n\ -Set the current process's effective user id."); +/*[clinic input] +os.seteuid + + euid: uid_t + / + +Set the current process's effective user id. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_seteuid__doc__, +"seteuid($module, euid, /)\n" +"--\n" +"\n" +"Set the current process\'s effective user id."); + +#define OS_SETEUID_METHODDEF \ + {"seteuid", (PyCFunction)os_seteuid, METH_VARARGS, os_seteuid__doc__}, + +static PyObject * +os_seteuid_impl(PyModuleDef *module, uid_t euid); static PyObject * -posix_seteuid (PyObject *self, PyObject *args) +os_seteuid(PyModuleDef *module, PyObject *args) { + PyObject *return_value = NULL; uid_t euid; - if (!PyArg_ParseTuple(args, "O&:seteuid", _Py_Uid_Converter, &euid)) - return NULL; - if (seteuid(euid) < 0) { + + if (!PyArg_ParseTuple(args, + "O&:seteuid", + _Py_Uid_Converter, &euid)) + goto exit; + return_value = os_seteuid_impl(module, euid); + +exit: + return return_value; +} + +static PyObject * +os_seteuid_impl(PyModuleDef *module, uid_t euid) +/*[clinic end generated code: output=6e824cce4f3b8a5d input=ba93d927e4781aa9]*/ +{ + if (seteuid(euid) < 0) return posix_error(); - } else { - Py_INCREF(Py_None); - return Py_None; - } + Py_RETURN_NONE; } #endif /* HAVE_SETEUID */ + #ifdef HAVE_SETEGID -PyDoc_STRVAR(posix_setegid__doc__, -"setegid(gid)\n\n\ -Set the current process's effective group id."); +/*[clinic input] +os.setegid + + egid: gid_t + / + +Set the current process's effective group id. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_setegid__doc__, +"setegid($module, egid, /)\n" +"--\n" +"\n" +"Set the current process\'s effective group id."); + +#define OS_SETEGID_METHODDEF \ + {"setegid", (PyCFunction)os_setegid, METH_VARARGS, os_setegid__doc__}, static PyObject * -posix_setegid (PyObject *self, PyObject *args) +os_setegid_impl(PyModuleDef *module, gid_t egid); + +static PyObject * +os_setegid(PyModuleDef *module, PyObject *args) { + PyObject *return_value = NULL; gid_t egid; - if (!PyArg_ParseTuple(args, "O&:setegid", _Py_Gid_Converter, &egid)) - return NULL; - if (setegid(egid) < 0) { + + if (!PyArg_ParseTuple(args, + "O&:setegid", + _Py_Gid_Converter, &egid)) + goto exit; + return_value = os_setegid_impl(module, egid); + +exit: + return return_value; +} + +static PyObject * +os_setegid_impl(PyModuleDef *module, gid_t egid) +/*[clinic end generated code: output=80a32263a4d56a9c input=4080526d0ccd6ce3]*/ +{ + if (setegid(egid) < 0) return posix_error(); - } else { - Py_INCREF(Py_None); - return Py_None; - } + Py_RETURN_NONE; } #endif /* HAVE_SETEGID */ + #ifdef HAVE_SETREUID -PyDoc_STRVAR(posix_setreuid__doc__, -"setreuid(ruid, euid)\n\n\ -Set the current process's real and effective user ids."); +/*[clinic input] +os.setreuid + + ruid: uid_t + euid: uid_t + / + +Set the current process's real and effective user ids. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_setreuid__doc__, +"setreuid($module, ruid, euid, /)\n" +"--\n" +"\n" +"Set the current process\'s real and effective user ids."); + +#define OS_SETREUID_METHODDEF \ + {"setreuid", (PyCFunction)os_setreuid, METH_VARARGS, os_setreuid__doc__}, + +static PyObject * +os_setreuid_impl(PyModuleDef *module, uid_t ruid, uid_t euid); static PyObject * -posix_setreuid (PyObject *self, PyObject *args) +os_setreuid(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + uid_t ruid; + uid_t euid; + + if (!PyArg_ParseTuple(args, + "O&O&:setreuid", + _Py_Uid_Converter, &ruid, _Py_Uid_Converter, &euid)) + goto exit; + return_value = os_setreuid_impl(module, ruid, euid); + +exit: + return return_value; +} + +static PyObject * +os_setreuid_impl(PyModuleDef *module, uid_t ruid, uid_t euid) +/*[clinic end generated code: output=d7f226f943dad739 input=0ca8978de663880c]*/ { - uid_t ruid, euid; - if (!PyArg_ParseTuple(args, "O&O&:setreuid", - _Py_Uid_Converter, &ruid, - _Py_Uid_Converter, &euid)) - return NULL; if (setreuid(ruid, euid) < 0) { return posix_error(); } else { @@ -6740,53 +9216,128 @@ posix_setreuid (PyObject *self, PyObject *args) } #endif /* HAVE_SETREUID */ + #ifdef HAVE_SETREGID -PyDoc_STRVAR(posix_setregid__doc__, -"setregid(rgid, egid)\n\n\ -Set the current process's real and effective group ids."); +/*[clinic input] +os.setregid + + rgid: gid_t + egid: gid_t + / + +Set the current process's real and effective group ids. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_setregid__doc__, +"setregid($module, rgid, egid, /)\n" +"--\n" +"\n" +"Set the current process\'s real and effective group ids."); + +#define OS_SETREGID_METHODDEF \ + {"setregid", (PyCFunction)os_setregid, METH_VARARGS, os_setregid__doc__}, static PyObject * -posix_setregid (PyObject *self, PyObject *args) +os_setregid_impl(PyModuleDef *module, gid_t rgid, gid_t egid); + +static PyObject * +os_setregid(PyModuleDef *module, PyObject *args) { - gid_t rgid, egid; - if (!PyArg_ParseTuple(args, "O&O&:setregid", - _Py_Gid_Converter, &rgid, - _Py_Gid_Converter, &egid)) - return NULL; - if (setregid(rgid, egid) < 0) { - return posix_error(); - } else { - Py_INCREF(Py_None); - return Py_None; - } + PyObject *return_value = NULL; + gid_t rgid; + gid_t egid; + + if (!PyArg_ParseTuple(args, + "O&O&:setregid", + _Py_Gid_Converter, &rgid, _Py_Gid_Converter, &egid)) + goto exit; + return_value = os_setregid_impl(module, rgid, egid); + +exit: + return return_value; +} + +static PyObject * +os_setregid_impl(PyModuleDef *module, gid_t rgid, gid_t egid) +/*[clinic end generated code: output=a82d9ab70f8e6562 input=c59499f72846db78]*/ +{ + if (setregid(rgid, egid) < 0) + return posix_error(); + Py_RETURN_NONE; } #endif /* HAVE_SETREGID */ + #ifdef HAVE_SETGID -PyDoc_STRVAR(posix_setgid__doc__, -"setgid(gid)\n\n\ -Set the current process's group id."); +/*[clinic input] +os.setgid + gid: gid_t + / + +Set the current process's group id. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_setgid__doc__, +"setgid($module, gid, /)\n" +"--\n" +"\n" +"Set the current process\'s group id."); + +#define OS_SETGID_METHODDEF \ + {"setgid", (PyCFunction)os_setgid, METH_VARARGS, os_setgid__doc__}, static PyObject * -posix_setgid(PyObject *self, PyObject *args) +os_setgid_impl(PyModuleDef *module, gid_t gid); + +static PyObject * +os_setgid(PyModuleDef *module, PyObject *args) { + PyObject *return_value = NULL; gid_t gid; - if (!PyArg_ParseTuple(args, "O&:setgid", _Py_Gid_Converter, &gid)) - return NULL; + + if (!PyArg_ParseTuple(args, + "O&:setgid", + _Py_Gid_Converter, &gid)) + goto exit; + return_value = os_setgid_impl(module, gid); + +exit: + return return_value; +} + +static PyObject * +os_setgid_impl(PyModuleDef *module, gid_t gid) +/*[clinic end generated code: output=08287886db435f23 input=27d30c4059045dc6]*/ +{ if (setgid(gid) < 0) return posix_error(); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } #endif /* HAVE_SETGID */ + #ifdef HAVE_SETGROUPS -PyDoc_STRVAR(posix_setgroups__doc__, -"setgroups(list)\n\n\ -Set the groups of the current process to list."); +/*[clinic input] +os.setgroups + + groups: object + / + +Set the groups of the current process to list. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_setgroups__doc__, +"setgroups($module, groups, /)\n" +"--\n" +"\n" +"Set the groups of the current process to list."); + +#define OS_SETGROUPS_METHODDEF \ + {"setgroups", (PyCFunction)os_setgroups, METH_O, os_setgroups__doc__}, static PyObject * -posix_setgroups(PyObject *self, PyObject *groups) +os_setgroups(PyModuleDef *module, PyObject *groups) +/*[clinic end generated code: output=0b8de65d5b3cda94 input=fa742ca3daf85a7e]*/ { int i, len; gid_t grouplist[MAX_GROUPS]; @@ -6887,83 +9438,220 @@ wait_helper(pid_t pid, int status, struct rusage *ru) } #endif /* HAVE_WAIT3 || HAVE_WAIT4 */ + #ifdef HAVE_WAIT3 -PyDoc_STRVAR(posix_wait3__doc__, -"wait3(options) -> (pid, status, rusage)\n\n\ -Wait for completion of a child process."); +/*[clinic input] +os.wait3 + + options: int +Wait for completion of a child process. + +Returns a tuple of information about the child process: + (pid, status, rusage) +[clinic start generated code]*/ + +PyDoc_STRVAR(os_wait3__doc__, +"wait3($module, /, options)\n" +"--\n" +"\n" +"Wait for completion of a child process.\n" +"\n" +"Returns a tuple of information about the child process:\n" +" (pid, status, rusage)"); + +#define OS_WAIT3_METHODDEF \ + {"wait3", (PyCFunction)os_wait3, METH_VARARGS|METH_KEYWORDS, os_wait3__doc__}, + +static PyObject * +os_wait3_impl(PyModuleDef *module, int options); static PyObject * -posix_wait3(PyObject *self, PyObject *args) +os_wait3(PyModuleDef *module, PyObject *args, PyObject *kwargs) { - pid_t pid; + PyObject *return_value = NULL; + static char *_keywords[] = {"options", NULL}; int options; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "i:wait3", _keywords, + &options)) + goto exit; + return_value = os_wait3_impl(module, options); + +exit: + return return_value; +} + +static PyObject * +os_wait3_impl(PyModuleDef *module, int options) +/*[clinic end generated code: output=1f2a63b6a93cbb57 input=8ac4c56956b61710]*/ +{ + pid_t pid; struct rusage ru; + int async_err = 0; WAIT_TYPE status; WAIT_STATUS_INT(status) = 0; - if (!PyArg_ParseTuple(args, "i:wait3", &options)) - return NULL; - - Py_BEGIN_ALLOW_THREADS - pid = wait3(&status, options, &ru); - Py_END_ALLOW_THREADS + do { + Py_BEGIN_ALLOW_THREADS + pid = wait3(&status, options, &ru); + Py_END_ALLOW_THREADS + } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + if (pid < 0) + return (!async_err) ? posix_error() : NULL; return wait_helper(pid, WAIT_STATUS_INT(status), &ru); } #endif /* HAVE_WAIT3 */ + #ifdef HAVE_WAIT4 -PyDoc_STRVAR(posix_wait4__doc__, -"wait4(pid, options) -> (pid, status, rusage)\n\n\ -Wait for completion of a given child process."); +/*[clinic input] + +os.wait4 + + pid: pid_t + options: int + +Wait for completion of a specific child process. + +Returns a tuple of information about the child process: + (pid, status, rusage) +[clinic start generated code]*/ + +PyDoc_STRVAR(os_wait4__doc__, +"wait4($module, /, pid, options)\n" +"--\n" +"\n" +"Wait for completion of a specific child process.\n" +"\n" +"Returns a tuple of information about the child process:\n" +" (pid, status, rusage)"); + +#define OS_WAIT4_METHODDEF \ + {"wait4", (PyCFunction)os_wait4, METH_VARARGS|METH_KEYWORDS, os_wait4__doc__}, + +static PyObject * +os_wait4_impl(PyModuleDef *module, pid_t pid, int options); static PyObject * -posix_wait4(PyObject *self, PyObject *args) +os_wait4(PyModuleDef *module, PyObject *args, PyObject *kwargs) { + PyObject *return_value = NULL; + static char *_keywords[] = {"pid", "options", NULL}; pid_t pid; int options; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "" _Py_PARSE_PID "i:wait4", _keywords, + &pid, &options)) + goto exit; + return_value = os_wait4_impl(module, pid, options); + +exit: + return return_value; +} + +static PyObject * +os_wait4_impl(PyModuleDef *module, pid_t pid, int options) +/*[clinic end generated code: output=20dfb05289d37dc6 input=d11deed0750600ba]*/ +{ + pid_t res; struct rusage ru; + int async_err = 0; WAIT_TYPE status; WAIT_STATUS_INT(status) = 0; - if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options)) - return NULL; - - Py_BEGIN_ALLOW_THREADS - pid = wait4(pid, &status, options, &ru); - Py_END_ALLOW_THREADS + do { + Py_BEGIN_ALLOW_THREADS + res = wait4(pid, &status, options, &ru); + Py_END_ALLOW_THREADS + } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + if (res < 0) + return (!async_err) ? posix_error() : NULL; - return wait_helper(pid, WAIT_STATUS_INT(status), &ru); + return wait_helper(res, WAIT_STATUS_INT(status), &ru); } #endif /* HAVE_WAIT4 */ + #if defined(HAVE_WAITID) && !defined(__APPLE__) -PyDoc_STRVAR(posix_waitid__doc__, -"waitid(idtype, id, options) -> waitid_result\n\n\ -Wait for the completion of one or more child processes.\n\n\ -idtype can be P_PID, P_PGID or P_ALL.\n\ -id specifies the pid to wait on.\n\ -options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\ -or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\ -Returns either waitid_result or None if WNOHANG is specified and there are\n\ -no children in a waitable state."); +/*[clinic input] +os.waitid + + idtype: idtype_t + Must be one of be P_PID, P_PGID or P_ALL. + id: id_t + The id to wait on. + options: int + Constructed from the ORing of one or more of WEXITED, WSTOPPED + or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT. + / + +Returns the result of waiting for a process or processes. + +Returns either waitid_result or None if WNOHANG is specified and there are +no children in a waitable state. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_waitid__doc__, +"waitid($module, idtype, id, options, /)\n" +"--\n" +"\n" +"Returns the result of waiting for a process or processes.\n" +"\n" +" idtype\n" +" Must be one of be P_PID, P_PGID or P_ALL.\n" +" id\n" +" The id to wait on.\n" +" options\n" +" Constructed from the ORing of one or more of WEXITED, WSTOPPED\n" +" or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n" +"\n" +"Returns either waitid_result or None if WNOHANG is specified and there are\n" +"no children in a waitable state."); + +#define OS_WAITID_METHODDEF \ + {"waitid", (PyCFunction)os_waitid, METH_VARARGS, os_waitid__doc__}, + +static PyObject * +os_waitid_impl(PyModuleDef *module, idtype_t idtype, id_t id, int options); static PyObject * -posix_waitid(PyObject *self, PyObject *args) +os_waitid(PyModuleDef *module, PyObject *args) { - PyObject *result; + PyObject *return_value = NULL; idtype_t idtype; id_t id; - int options, res; + int options; + + if (!PyArg_ParseTuple(args, + "i" _Py_PARSE_PID "i:waitid", + &idtype, &id, &options)) + goto exit; + return_value = os_waitid_impl(module, idtype, id, options); + +exit: + return return_value; +} + +static PyObject * +os_waitid_impl(PyModuleDef *module, idtype_t idtype, id_t id, int options) +/*[clinic end generated code: output=fb44bf97f01021b2 input=d8e7f76e052b7920]*/ +{ + PyObject *result; + int res; + int async_err = 0; siginfo_t si; si.si_pid = 0; - if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options)) - return NULL; - Py_BEGIN_ALLOW_THREADS - res = waitid(idtype, id, &si, options); - Py_END_ALLOW_THREADS - if (res == -1) - return posix_error(); + + do { + Py_BEGIN_ALLOW_THREADS + res = waitid(idtype, id, &si, options); + Py_END_ALLOW_THREADS + } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + if (res < 0) + return (!async_err) ? posix_error() : NULL; if (si.si_pid == 0) Py_RETURN_NONE; @@ -6984,79 +9672,200 @@ posix_waitid(PyObject *self, PyObject *args) return result; } -#endif +#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */ + + +#if defined(HAVE_WAITPID) +/*[clinic input] +os.waitpid + pid: pid_t + options: int + / + +Wait for completion of a given child process. + +Returns a tuple of information regarding the child process: + (pid, status) + +The options argument is ignored on Windows. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_waitpid__doc__, +"waitpid($module, pid, options, /)\n" +"--\n" +"\n" +"Wait for completion of a given child process.\n" +"\n" +"Returns a tuple of information regarding the child process:\n" +" (pid, status)\n" +"\n" +"The options argument is ignored on Windows."); + +#define OS_WAITPID_METHODDEF \ + {"waitpid", (PyCFunction)os_waitpid, METH_VARARGS, os_waitpid__doc__}, -#ifdef HAVE_WAITPID -PyDoc_STRVAR(posix_waitpid__doc__, -"waitpid(pid, options) -> (pid, status)\n\n\ -Wait for completion of a given child process."); +static PyObject * +os_waitpid_impl(PyModuleDef *module, pid_t pid, int options); static PyObject * -posix_waitpid(PyObject *self, PyObject *args) +os_waitpid(PyModuleDef *module, PyObject *args) { + PyObject *return_value = NULL; pid_t pid; int options; + + if (!PyArg_ParseTuple(args, + "" _Py_PARSE_PID "i:waitpid", + &pid, &options)) + goto exit; + return_value = os_waitpid_impl(module, pid, options); + +exit: + return return_value; +} + +static PyObject * +os_waitpid_impl(PyModuleDef *module, pid_t pid, int options) +/*[clinic end generated code: output=095a6b00af70b7ac input=0bf1666b8758fda3]*/ +{ + pid_t res; + int async_err = 0; WAIT_TYPE status; WAIT_STATUS_INT(status) = 0; - if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options)) - return NULL; - Py_BEGIN_ALLOW_THREADS - pid = waitpid(pid, &status, options); - Py_END_ALLOW_THREADS - if (pid == -1) - return posix_error(); + do { + Py_BEGIN_ALLOW_THREADS + res = waitpid(pid, &status, options); + Py_END_ALLOW_THREADS + } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + if (res < 0) + return (!async_err) ? posix_error() : NULL; - return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status)); + return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status)); } - #elif defined(HAVE_CWAIT) - /* MS C has a variant of waitpid() that's usable for most purposes. */ -PyDoc_STRVAR(posix_waitpid__doc__, -"waitpid(pid, options) -> (pid, status << 8)\n\n" -"Wait for completion of a given process. options is ignored on Windows."); +/*[clinic input] +os.waitpid + pid: Py_intptr_t + options: int + / + +Wait for completion of a given process. + +Returns a tuple of information regarding the process: + (pid, status << 8) + +The options argument is ignored on Windows. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_waitpid__doc__, +"waitpid($module, pid, options, /)\n" +"--\n" +"\n" +"Wait for completion of a given process.\n" +"\n" +"Returns a tuple of information regarding the process:\n" +" (pid, status << 8)\n" +"\n" +"The options argument is ignored on Windows."); + +#define OS_WAITPID_METHODDEF \ + {"waitpid", (PyCFunction)os_waitpid, METH_VARARGS, os_waitpid__doc__}, + +static PyObject * +os_waitpid_impl(PyModuleDef *module, Py_intptr_t pid, int options); static PyObject * -posix_waitpid(PyObject *self, PyObject *args) +os_waitpid(PyModuleDef *module, PyObject *args) { + PyObject *return_value = NULL; Py_intptr_t pid; - int status, options; + int options; - if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR "i:waitpid", &pid, &options)) - return NULL; - Py_BEGIN_ALLOW_THREADS - pid = _cwait(&status, pid, options); - Py_END_ALLOW_THREADS - if (pid == -1) - return posix_error(); + if (!PyArg_ParseTuple(args, + "" _Py_PARSE_INTPTR "i:waitpid", + &pid, &options)) + goto exit; + return_value = os_waitpid_impl(module, pid, options); + +exit: + return return_value; +} + +static PyObject * +os_waitpid_impl(PyModuleDef *module, Py_intptr_t pid, int options) +/*[clinic end generated code: output=c20b95b15ad44a3a input=444c8f51cca5b862]*/ +{ + int status; + Py_intptr_t res; + int async_err = 0; + + do { + Py_BEGIN_ALLOW_THREADS + res = _cwait(&status, pid, options); + Py_END_ALLOW_THREADS + } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + if (res != 0) + return (!async_err) ? posix_error() : NULL; /* shift the status left a byte so this is more like the POSIX waitpid */ - return Py_BuildValue(_Py_PARSE_INTPTR "i", pid, status << 8); + return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8); } -#endif /* HAVE_WAITPID || HAVE_CWAIT */ +#endif + #ifdef HAVE_WAIT -PyDoc_STRVAR(posix_wait__doc__, -"wait() -> (pid, status)\n\n\ -Wait for completion of a child process."); +/*[clinic input] +os.wait + +Wait for completion of a child process. + +Returns a tuple of information about the child process: + (pid, status) +[clinic start generated code]*/ + +PyDoc_STRVAR(os_wait__doc__, +"wait($module, /)\n" +"--\n" +"\n" +"Wait for completion of a child process.\n" +"\n" +"Returns a tuple of information about the child process:\n" +" (pid, status)"); + +#define OS_WAIT_METHODDEF \ + {"wait", (PyCFunction)os_wait, METH_NOARGS, os_wait__doc__}, + +static PyObject * +os_wait_impl(PyModuleDef *module); + +static PyObject * +os_wait(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_wait_impl(module); +} static PyObject * -posix_wait(PyObject *self, PyObject *noargs) +os_wait_impl(PyModuleDef *module) +/*[clinic end generated code: output=2a83a9d164e7e6a8 input=03b0182d4a4700ce]*/ { pid_t pid; + int async_err = 0; WAIT_TYPE status; WAIT_STATUS_INT(status) = 0; - Py_BEGIN_ALLOW_THREADS - pid = wait(&status); - Py_END_ALLOW_THREADS - if (pid == -1) - return posix_error(); + do { + Py_BEGIN_ALLOW_THREADS + pid = wait(&status); + Py_END_ALLOW_THREADS + } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + if (pid < 0) + return (!async_err) ? posix_error() : NULL; return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status)); } -#endif +#endif /* HAVE_WAIT */ #if defined(HAVE_READLINK) || defined(MS_WINDOWS) @@ -7072,6 +9881,7 @@ dir_fd may not be implemented on your platform.\n\ #ifdef HAVE_READLINK +/* AC 3.5: merge win32 and not together */ static PyObject * posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs) { @@ -7086,12 +9896,7 @@ posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs) path.function_name = "readlink"; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords, path_converter, &path, -#ifdef HAVE_READLINKAT - dir_fd_converter, &dir_fd -#else - dir_fd_unavailable, &dir_fd -#endif - )) + READLINKAT_DIR_FD_CONVERTER, &dir_fd)) return NULL; Py_BEGIN_ALLOW_THREADS @@ -7117,31 +9922,94 @@ posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs) return return_value; } - #endif /* HAVE_READLINK */ +#if !defined(HAVE_READLINK) && defined(MS_WINDOWS) -#ifdef HAVE_SYMLINK -PyDoc_STRVAR(posix_symlink__doc__, -"symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\ -Create a symbolic link pointing to src named dst.\n\n\ -target_is_directory is required on Windows if the target is to be\n\ - interpreted as a directory. (On Windows, symlink requires\n\ - Windows 6.0 or greater, and raises a NotImplementedError otherwise.)\n\ - target_is_directory is ignored on non-Windows platforms.\n\ -\n\ -If dir_fd is not None, it should be a file descriptor open to a directory,\n\ - and path should be relative; path will then be relative to that directory.\n\ -dir_fd may not be implemented on your platform.\n\ - If it is unavailable, using it will raise a NotImplementedError."); - -#if defined(MS_WINDOWS) - -/* Grab CreateSymbolicLinkW dynamically from kernel32 */ -static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL; -static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL; - -static int +static PyObject * +win_readlink(PyObject *self, PyObject *args, PyObject *kwargs) +{ + wchar_t *path; + DWORD n_bytes_returned; + DWORD io_result; + PyObject *po, *result; + int dir_fd; + HANDLE reparse_point_handle; + + char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; + REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer; + wchar_t *print_name; + + static char *keywords[] = {"path", "dir_fd", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords, + &po, + dir_fd_unavailable, &dir_fd + )) + return NULL; + + path = PyUnicode_AsUnicode(po); + if (path == NULL) + return NULL; + + /* First get a handle to the reparse point */ + Py_BEGIN_ALLOW_THREADS + reparse_point_handle = CreateFileW( + path, + 0, + 0, + 0, + OPEN_EXISTING, + FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, + 0); + Py_END_ALLOW_THREADS + + if (reparse_point_handle==INVALID_HANDLE_VALUE) + return win32_error_object("readlink", po); + + Py_BEGIN_ALLOW_THREADS + /* New call DeviceIoControl to read the reparse point */ + io_result = DeviceIoControl( + reparse_point_handle, + FSCTL_GET_REPARSE_POINT, + 0, 0, /* in buffer */ + target_buffer, sizeof(target_buffer), + &n_bytes_returned, + 0 /* we're not using OVERLAPPED_IO */ + ); + CloseHandle(reparse_point_handle); + Py_END_ALLOW_THREADS + + if (io_result==0) + return win32_error_object("readlink", po); + + if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK) + { + PyErr_SetString(PyExc_ValueError, + "not a symbolic link"); + return NULL; + } + print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer + + rdb->SymbolicLinkReparseBuffer.PrintNameOffset; + + result = PyUnicode_FromWideChar(print_name, + rdb->SymbolicLinkReparseBuffer.PrintNameLength/2); + return result; +} + +#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */ + + + +#ifdef HAVE_SYMLINK + +#if defined(MS_WINDOWS) + +/* Grab CreateSymbolicLinkW dynamically from kernel32 */ +static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL; +static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL; + +static int check_CreateSymbolicLink(void) { HINSTANCE hKernel32; @@ -7279,189 +10147,148 @@ _check_dirA(char *src, char *dest) && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ); } - #endif + +/*[clinic input] +os.symlink + src: path_t + dst: path_t + target_is_directory: bool = False + * + dir_fd: dir_fd(requires='symlinkat')=None + +# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\ + +Create a symbolic link pointing to src named dst. + +target_is_directory is required on Windows if the target is to be + interpreted as a directory. (On Windows, symlink requires + Windows 6.0 or greater, and raises a NotImplementedError otherwise.) + target_is_directory is ignored on non-Windows platforms. + +If dir_fd is not None, it should be a file descriptor open to a directory, + and path should be relative; path will then be relative to that directory. +dir_fd may not be implemented on your platform. + If it is unavailable, using it will raise a NotImplementedError. + +[clinic start generated code]*/ + +PyDoc_STRVAR(os_symlink__doc__, +"symlink($module, /, src, dst, target_is_directory=False, *, dir_fd=None)\n" +"--\n" +"\n" +"Create a symbolic link pointing to src named dst.\n" +"\n" +"target_is_directory is required on Windows if the target is to be\n" +" interpreted as a directory. (On Windows, symlink requires\n" +" Windows 6.0 or greater, and raises a NotImplementedError otherwise.)\n" +" target_is_directory is ignored on non-Windows platforms.\n" +"\n" +"If dir_fd is not None, it should be a file descriptor open to a directory,\n" +" and path should be relative; path will then be relative to that directory.\n" +"dir_fd may not be implemented on your platform.\n" +" If it is unavailable, using it will raise a NotImplementedError."); + +#define OS_SYMLINK_METHODDEF \ + {"symlink", (PyCFunction)os_symlink, METH_VARARGS|METH_KEYWORDS, os_symlink__doc__}, + +static PyObject * +os_symlink_impl(PyModuleDef *module, path_t *src, path_t *dst, int target_is_directory, int dir_fd); + static PyObject * -posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs) +os_symlink(PyModuleDef *module, PyObject *args, PyObject *kwargs) { - path_t src; - path_t dst; - int dir_fd = DEFAULT_DIR_FD; + PyObject *return_value = NULL; + static char *_keywords[] = {"src", "dst", "target_is_directory", "dir_fd", NULL}; + path_t src = PATH_T_INITIALIZE("symlink", "src", 0, 0); + path_t dst = PATH_T_INITIALIZE("symlink", "dst", 0, 0); int target_is_directory = 0; - static char *keywords[] = {"src", "dst", "target_is_directory", - "dir_fd", NULL}; - PyObject *return_value; + int dir_fd = DEFAULT_DIR_FD; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&O&|p$O&:symlink", _keywords, + path_converter, &src, path_converter, &dst, &target_is_directory, SYMLINKAT_DIR_FD_CONVERTER, &dir_fd)) + goto exit; + return_value = os_symlink_impl(module, &src, &dst, target_is_directory, dir_fd); + +exit: + /* Cleanup for src */ + path_cleanup(&src); + /* Cleanup for dst */ + path_cleanup(&dst); + + return return_value; +} + +static PyObject * +os_symlink_impl(PyModuleDef *module, path_t *src, path_t *dst, int target_is_directory, int dir_fd) +/*[clinic end generated code: output=1a31e6d88aafe9b6 input=e820ec4472547bc3]*/ +{ #ifdef MS_WINDOWS DWORD result; #else int result; #endif - memset(&src, 0, sizeof(src)); - src.function_name = "symlink"; - src.argument_name = "src"; - memset(&dst, 0, sizeof(dst)); - dst.function_name = "symlink"; - dst.argument_name = "dst"; - #ifdef MS_WINDOWS if (!check_CreateSymbolicLink()) { PyErr_SetString(PyExc_NotImplementedError, "CreateSymbolicLink functions not found"); - return NULL; + return NULL; } if (!win32_can_symlink) { PyErr_SetString(PyExc_OSError, "symbolic link privilege not held"); - return NULL; + return NULL; } #endif - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|i$O&:symlink", - keywords, - path_converter, &src, - path_converter, &dst, - &target_is_directory, -#ifdef HAVE_SYMLINKAT - dir_fd_converter, &dir_fd -#else - dir_fd_unavailable, &dir_fd -#endif - )) - return NULL; - - if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) { + if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) { PyErr_SetString(PyExc_ValueError, "symlink: src and dst must be the same type"); - return_value = NULL; - goto exit; + return NULL; } #ifdef MS_WINDOWS Py_BEGIN_ALLOW_THREADS - if (dst.wide) { + if (dst->wide) { /* if src is a directory, ensure target_is_directory==1 */ - target_is_directory |= _check_dirW(src.wide, dst.wide); - result = Py_CreateSymbolicLinkW(dst.wide, src.wide, + target_is_directory |= _check_dirW(src->wide, dst->wide); + result = Py_CreateSymbolicLinkW(dst->wide, src->wide, target_is_directory); } else { /* if src is a directory, ensure target_is_directory==1 */ - target_is_directory |= _check_dirA(src.narrow, dst.narrow); - result = Py_CreateSymbolicLinkA(dst.narrow, src.narrow, + target_is_directory |= _check_dirA(src->narrow, dst->narrow); + result = Py_CreateSymbolicLinkA(dst->narrow, src->narrow, target_is_directory); } Py_END_ALLOW_THREADS - if (!result) { - return_value = path_error(&src); - goto exit; - } + if (!result) + return path_error2(src, dst); #else Py_BEGIN_ALLOW_THREADS #if HAVE_SYMLINKAT if (dir_fd != DEFAULT_DIR_FD) - result = symlinkat(src.narrow, dir_fd, dst.narrow); + result = symlinkat(src->narrow, dir_fd, dst->narrow); else #endif - result = symlink(src.narrow, dst.narrow); + result = symlink(src->narrow, dst->narrow); Py_END_ALLOW_THREADS - if (result) { - return_value = path_error(&src); - goto exit; - } + if (result) + return path_error2(src, dst); #endif - return_value = Py_None; - Py_INCREF(Py_None); - goto exit; /* silence "unused label" warning */ -exit: - path_cleanup(&src); - path_cleanup(&dst); - return return_value; + Py_RETURN_NONE; } - #endif /* HAVE_SYMLINK */ -#if !defined(HAVE_READLINK) && defined(MS_WINDOWS) - -static PyObject * -win_readlink(PyObject *self, PyObject *args, PyObject *kwargs) -{ - wchar_t *path; - DWORD n_bytes_returned; - DWORD io_result; - PyObject *po, *result; - int dir_fd; - HANDLE reparse_point_handle; - - char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; - REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer; - wchar_t *print_name; - - static char *keywords[] = {"path", "dir_fd", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords, - &po, - dir_fd_unavailable, &dir_fd - )) - return NULL; - - path = PyUnicode_AsUnicode(po); - if (path == NULL) - return NULL; - - /* First get a handle to the reparse point */ - Py_BEGIN_ALLOW_THREADS - reparse_point_handle = CreateFileW( - path, - 0, - 0, - 0, - OPEN_EXISTING, - FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, - 0); - Py_END_ALLOW_THREADS - - if (reparse_point_handle==INVALID_HANDLE_VALUE) - return win32_error_object("readlink", po); - - Py_BEGIN_ALLOW_THREADS - /* New call DeviceIoControl to read the reparse point */ - io_result = DeviceIoControl( - reparse_point_handle, - FSCTL_GET_REPARSE_POINT, - 0, 0, /* in buffer */ - target_buffer, sizeof(target_buffer), - &n_bytes_returned, - 0 /* we're not using OVERLAPPED_IO */ - ); - CloseHandle(reparse_point_handle); - Py_END_ALLOW_THREADS - - if (io_result==0) - return win32_error_object("readlink", po); - - if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK) - { - PyErr_SetString(PyExc_ValueError, - "not a symbolic link"); - return NULL; - } - print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer + - rdb->SymbolicLinkReparseBuffer.PrintNameOffset; - - result = PyUnicode_FromWideChar(print_name, - rdb->SymbolicLinkReparseBuffer.PrintNameLength/2); - return result; -} - -#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */ static PyStructSequence_Field times_result_fields[] = { @@ -7527,15 +10354,48 @@ build_times_result(double user, double system, return value; } -PyDoc_STRVAR(posix_times__doc__, -"times() -> times_result\n\n\ -Return an object containing floating point numbers indicating process\n\ -times. The object behaves like a named tuple with these fields:\n\ - (utime, stime, cutime, cstime, elapsed_time)"); -#if defined(MS_WINDOWS) +#ifndef MS_WINDOWS +#define NEED_TICKS_PER_SECOND +static long ticks_per_second = -1; +#endif /* MS_WINDOWS */ + +/*[clinic input] +os.times + +Return a collection containing process timing information. + +The object returned behaves like a named tuple with these fields: + (utime, stime, cutime, cstime, elapsed_time) +All fields are floating point numbers. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_times__doc__, +"times($module, /)\n" +"--\n" +"\n" +"Return a collection containing process timing information.\n" +"\n" +"The object returned behaves like a named tuple with these fields:\n" +" (utime, stime, cutime, cstime, elapsed_time)\n" +"All fields are floating point numbers."); + +#define OS_TIMES_METHODDEF \ + {"times", (PyCFunction)os_times, METH_NOARGS, os_times__doc__}, + +static PyObject * +os_times_impl(PyModuleDef *module); + static PyObject * -posix_times(PyObject *self, PyObject *noargs) +os_times(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_times_impl(module); +} + +static PyObject * +os_times_impl(PyModuleDef *module) +/*[clinic end generated code: output=b86896d031a9b768 input=2bf9df3d6ab2e48b]*/ +#ifdef MS_WINDOWS { FILETIME create, exit, kernel, user; HANDLE hProc; @@ -7555,12 +10415,10 @@ posix_times(PyObject *self, PyObject *noargs) (double)0, (double)0); } -#else /* Not Windows */ -#define NEED_TICKS_PER_SECOND -static long ticks_per_second = -1; -static PyObject * -posix_times(PyObject *self, PyObject *noargs) +#else /* MS_WINDOWS */ { + + struct tms t; clock_t c; errno = 0; @@ -7574,23 +10432,53 @@ posix_times(PyObject *self, PyObject *noargs) (double)t.tms_cstime / ticks_per_second, (double)c / ticks_per_second); } -#endif - +#endif /* MS_WINDOWS */ #endif /* HAVE_TIMES */ #ifdef HAVE_GETSID -PyDoc_STRVAR(posix_getsid__doc__, -"getsid(pid) -> sid\n\n\ -Call the system call getsid()."); +/*[clinic input] +os.getsid + + pid: pid_t + / + +Call the system call getsid(pid) and return the result. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_getsid__doc__, +"getsid($module, pid, /)\n" +"--\n" +"\n" +"Call the system call getsid(pid) and return the result."); + +#define OS_GETSID_METHODDEF \ + {"getsid", (PyCFunction)os_getsid, METH_VARARGS, os_getsid__doc__}, static PyObject * -posix_getsid(PyObject *self, PyObject *args) +os_getsid_impl(PyModuleDef *module, pid_t pid); + +static PyObject * +os_getsid(PyModuleDef *module, PyObject *args) { + PyObject *return_value = NULL; pid_t pid; - int sid; - if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid)) - return NULL; + + if (!PyArg_ParseTuple(args, + "" _Py_PARSE_PID ":getsid", + &pid)) + goto exit; + return_value = os_getsid_impl(module, pid); + +exit: + return return_value; +} + +static PyObject * +os_getsid_impl(PyModuleDef *module, pid_t pid) +/*[clinic end generated code: output=ea8390f395f4e0e1 input=eeb2b923a30ce04e]*/ +{ + int sid; sid = getsid(pid); if (sid < 0) return posix_error(); @@ -7600,53 +10488,135 @@ posix_getsid(PyObject *self, PyObject *args) #ifdef HAVE_SETSID -PyDoc_STRVAR(posix_setsid__doc__, -"setsid()\n\n\ -Call the system call setsid()."); +/*[clinic input] +os.setsid + +Call the system call setsid(). +[clinic start generated code]*/ + +PyDoc_STRVAR(os_setsid__doc__, +"setsid($module, /)\n" +"--\n" +"\n" +"Call the system call setsid()."); + +#define OS_SETSID_METHODDEF \ + {"setsid", (PyCFunction)os_setsid, METH_NOARGS, os_setsid__doc__}, static PyObject * -posix_setsid(PyObject *self, PyObject *noargs) +os_setsid_impl(PyModuleDef *module); + +static PyObject * +os_setsid(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_setsid_impl(module); +} + +static PyObject * +os_setsid_impl(PyModuleDef *module) +/*[clinic end generated code: output=2a9a1435d8d764d5 input=5fff45858e2f0776]*/ { if (setsid() < 0) return posix_error(); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } #endif /* HAVE_SETSID */ + #ifdef HAVE_SETPGID -PyDoc_STRVAR(posix_setpgid__doc__, -"setpgid(pid, pgrp)\n\n\ -Call the system call setpgid()."); +/*[clinic input] +os.setpgid + + pid: pid_t + pgrp: pid_t + / + +Call the system call setpgid(pid, pgrp). +[clinic start generated code]*/ + +PyDoc_STRVAR(os_setpgid__doc__, +"setpgid($module, pid, pgrp, /)\n" +"--\n" +"\n" +"Call the system call setpgid(pid, pgrp)."); + +#define OS_SETPGID_METHODDEF \ + {"setpgid", (PyCFunction)os_setpgid, METH_VARARGS, os_setpgid__doc__}, static PyObject * -posix_setpgid(PyObject *self, PyObject *args) +os_setpgid_impl(PyModuleDef *module, pid_t pid, pid_t pgrp); + +static PyObject * +os_setpgid(PyModuleDef *module, PyObject *args) { + PyObject *return_value = NULL; pid_t pid; - int pgrp; - if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp)) - return NULL; + pid_t pgrp; + + if (!PyArg_ParseTuple(args, + "" _Py_PARSE_PID "" _Py_PARSE_PID ":setpgid", + &pid, &pgrp)) + goto exit; + return_value = os_setpgid_impl(module, pid, pgrp); + +exit: + return return_value; +} + +static PyObject * +os_setpgid_impl(PyModuleDef *module, pid_t pid, pid_t pgrp) +/*[clinic end generated code: output=7ad79b725f890e1f input=fceb395eca572e1a]*/ +{ if (setpgid(pid, pgrp) < 0) return posix_error(); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } #endif /* HAVE_SETPGID */ #ifdef HAVE_TCGETPGRP -PyDoc_STRVAR(posix_tcgetpgrp__doc__, -"tcgetpgrp(fd) -> pgid\n\n\ -Return the process group associated with the terminal given by a fd."); +/*[clinic input] +os.tcgetpgrp + + fd: int + / + +Return the process group associated with the terminal specified by fd. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_tcgetpgrp__doc__, +"tcgetpgrp($module, fd, /)\n" +"--\n" +"\n" +"Return the process group associated with the terminal specified by fd."); + +#define OS_TCGETPGRP_METHODDEF \ + {"tcgetpgrp", (PyCFunction)os_tcgetpgrp, METH_VARARGS, os_tcgetpgrp__doc__}, static PyObject * -posix_tcgetpgrp(PyObject *self, PyObject *args) +os_tcgetpgrp_impl(PyModuleDef *module, int fd); + +static PyObject * +os_tcgetpgrp(PyModuleDef *module, PyObject *args) { + PyObject *return_value = NULL; int fd; - pid_t pgid; - if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd)) - return NULL; - pgid = tcgetpgrp(fd); + + if (!PyArg_ParseTuple(args, + "i:tcgetpgrp", + &fd)) + goto exit; + return_value = os_tcgetpgrp_impl(module, fd); + +exit: + return return_value; +} + +static PyObject * +os_tcgetpgrp_impl(PyModuleDef *module, int fd) +/*[clinic end generated code: output=abcf52ed4c8d22cb input=7f6c18eac10ada86]*/ +{ + pid_t pgid = tcgetpgrp(fd); if (pgid < 0) return posix_error(); return PyLong_FromPid(pgid); @@ -7655,21 +10625,52 @@ posix_tcgetpgrp(PyObject *self, PyObject *args) #ifdef HAVE_TCSETPGRP -PyDoc_STRVAR(posix_tcsetpgrp__doc__, -"tcsetpgrp(fd, pgid)\n\n\ -Set the process group associated with the terminal given by a fd."); +/*[clinic input] +os.tcsetpgrp + + fd: int + pgid: pid_t + / + +Set the process group associated with the terminal specified by fd. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_tcsetpgrp__doc__, +"tcsetpgrp($module, fd, pgid, /)\n" +"--\n" +"\n" +"Set the process group associated with the terminal specified by fd."); + +#define OS_TCSETPGRP_METHODDEF \ + {"tcsetpgrp", (PyCFunction)os_tcsetpgrp, METH_VARARGS, os_tcsetpgrp__doc__}, + +static PyObject * +os_tcsetpgrp_impl(PyModuleDef *module, int fd, pid_t pgid); static PyObject * -posix_tcsetpgrp(PyObject *self, PyObject *args) +os_tcsetpgrp(PyModuleDef *module, PyObject *args) { + PyObject *return_value = NULL; int fd; pid_t pgid; - if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid)) - return NULL; + + if (!PyArg_ParseTuple(args, + "i" _Py_PARSE_PID ":tcsetpgrp", + &fd, &pgid)) + goto exit; + return_value = os_tcsetpgrp_impl(module, fd, pgid); + +exit: + return return_value; +} + +static PyObject * +os_tcsetpgrp_impl(PyModuleDef *module, int fd, pid_t pgid) +/*[clinic end generated code: output=76f9bb8fd00f20f5 input=5bdc997c6a619020]*/ +{ if (tcsetpgrp(fd, pgid) < 0) return posix_error(); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } #endif /* HAVE_TCSETPGRP */ @@ -7679,117 +10680,224 @@ posix_tcsetpgrp(PyObject *self, PyObject *args) extern int _Py_open_cloexec_works; #endif -PyDoc_STRVAR(posix_open__doc__, -"open(path, flags, mode=0o777, *, dir_fd=None)\n\n\ -Open a file for low level IO. Returns a file handle (integer).\n\ -\n\ -If dir_fd is not None, it should be a file descriptor open to a directory,\n\ - and path should be relative; path will then be relative to that directory.\n\ -dir_fd may not be implemented on your platform.\n\ - If it is unavailable, using it will raise a NotImplementedError."); + +/*[clinic input] +os.open -> int + path: path_t + flags: int + mode: int = 0o777 + * + dir_fd: dir_fd(requires='openat') = None + +# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\ + +Open a file for low level IO. Returns a file descriptor (integer). + +If dir_fd is not None, it should be a file descriptor open to a directory, + and path should be relative; path will then be relative to that directory. +dir_fd may not be implemented on your platform. + If it is unavailable, using it will raise a NotImplementedError. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_open__doc__, +"open($module, /, path, flags, mode=511, *, dir_fd=None)\n" +"--\n" +"\n" +"Open a file for low level IO. Returns a file descriptor (integer).\n" +"\n" +"If dir_fd is not None, it should be a file descriptor open to a directory,\n" +" and path should be relative; path will then be relative to that directory.\n" +"dir_fd may not be implemented on your platform.\n" +" If it is unavailable, using it will raise a NotImplementedError."); + +#define OS_OPEN_METHODDEF \ + {"open", (PyCFunction)os_open, METH_VARARGS|METH_KEYWORDS, os_open__doc__}, + +static int +os_open_impl(PyModuleDef *module, path_t *path, int flags, int mode, int dir_fd); static PyObject * -posix_open(PyObject *self, PyObject *args, PyObject *kwargs) +os_open(PyModuleDef *module, PyObject *args, PyObject *kwargs) { - path_t path; + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "flags", "mode", "dir_fd", NULL}; + path_t path = PATH_T_INITIALIZE("open", "path", 0, 0); int flags; - int mode = 0777; + int mode = 511; int dir_fd = DEFAULT_DIR_FD; + int _return_value; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&i|i$O&:open", _keywords, + path_converter, &path, &flags, &mode, OPENAT_DIR_FD_CONVERTER, &dir_fd)) + goto exit; + _return_value = os_open_impl(module, &path, flags, mode, dir_fd); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromLong((long)_return_value); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +static int +os_open_impl(PyModuleDef *module, path_t *path, int flags, int mode, int dir_fd) +/*[clinic end generated code: output=05b68fc4ed5e29c9 input=ad8623b29acd2934]*/ +{ int fd; - PyObject *return_value = NULL; - static char *keywords[] = {"path", "flags", "mode", "dir_fd", NULL}; + int async_err = 0; + #ifdef O_CLOEXEC int *atomic_flag_works = &_Py_open_cloexec_works; #elif !defined(MS_WINDOWS) int *atomic_flag_works = NULL; #endif - memset(&path, 0, sizeof(path)); - path.function_name = "open"; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|i$O&:open", keywords, - path_converter, &path, - &flags, &mode, -#ifdef HAVE_OPENAT - dir_fd_converter, &dir_fd -#else - dir_fd_unavailable, &dir_fd -#endif - )) - return NULL; - #ifdef MS_WINDOWS flags |= O_NOINHERIT; #elif defined(O_CLOEXEC) flags |= O_CLOEXEC; #endif - Py_BEGIN_ALLOW_THREADS + do { + Py_BEGIN_ALLOW_THREADS #ifdef MS_WINDOWS - if (path.wide) - fd = _wopen(path.wide, flags, mode); - else + if (path->wide) + fd = _wopen(path->wide, flags, mode); + else #endif #ifdef HAVE_OPENAT - if (dir_fd != DEFAULT_DIR_FD) - fd = openat(dir_fd, path.narrow, flags, mode); - else + if (dir_fd != DEFAULT_DIR_FD) + fd = openat(dir_fd, path->narrow, flags, mode); + else #endif - fd = open(path.narrow, flags, mode); - Py_END_ALLOW_THREADS + fd = open(path->narrow, flags, mode); + Py_END_ALLOW_THREADS + } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); if (fd == -1) { - PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path.object); - goto exit; + if (!async_err) + PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object); + return -1; } #ifndef MS_WINDOWS if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) { close(fd); - goto exit; + return -1; } #endif - return_value = PyLong_FromLong((long)fd); + return fd; +} + + +/*[clinic input] +os.close + + fd: int + +Close a file descriptor. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_close__doc__, +"close($module, /, fd)\n" +"--\n" +"\n" +"Close a file descriptor."); + +#define OS_CLOSE_METHODDEF \ + {"close", (PyCFunction)os_close, METH_VARARGS|METH_KEYWORDS, os_close__doc__}, + +static PyObject * +os_close_impl(PyModuleDef *module, int fd); + +static PyObject * +os_close(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"fd", NULL}; + int fd; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "i:close", _keywords, + &fd)) + goto exit; + return_value = os_close_impl(module, fd); exit: - path_cleanup(&path); return return_value; } -PyDoc_STRVAR(posix_close__doc__, -"close(fd)\n\n\ -Close a file descriptor (for low level IO)."); - static PyObject * -posix_close(PyObject *self, PyObject *args) +os_close_impl(PyModuleDef *module, int fd) +/*[clinic end generated code: output=927004e29ad55808 input=2bc42451ca5c3223]*/ { - int fd, res; - if (!PyArg_ParseTuple(args, "i:close", &fd)) - return NULL; + int res; if (!_PyVerify_fd(fd)) return posix_error(); + /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/ + * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html + * for more details. + */ Py_BEGIN_ALLOW_THREADS res = close(fd); Py_END_ALLOW_THREADS if (res < 0) return posix_error(); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } -PyDoc_STRVAR(posix_closerange__doc__, -"closerange(fd_low, fd_high)\n\n\ -Closes all file descriptors in [fd_low, fd_high), ignoring errors."); +/*[clinic input] +os.closerange + + fd_low: int + fd_high: int + / + +Closes all file descriptors in [fd_low, fd_high), ignoring errors. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_closerange__doc__, +"closerange($module, fd_low, fd_high, /)\n" +"--\n" +"\n" +"Closes all file descriptors in [fd_low, fd_high), ignoring errors."); + +#define OS_CLOSERANGE_METHODDEF \ + {"closerange", (PyCFunction)os_closerange, METH_VARARGS, os_closerange__doc__}, + +static PyObject * +os_closerange_impl(PyModuleDef *module, int fd_low, int fd_high); static PyObject * -posix_closerange(PyObject *self, PyObject *args) +os_closerange(PyModuleDef *module, PyObject *args) { - int fd_from, fd_to, i; - if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to)) - return NULL; + PyObject *return_value = NULL; + int fd_low; + int fd_high; + + if (!PyArg_ParseTuple(args, + "ii:closerange", + &fd_low, &fd_high)) + goto exit; + return_value = os_closerange_impl(module, fd_low, fd_high); + +exit: + return return_value; +} + +static PyObject * +os_closerange_impl(PyModuleDef *module, int fd_low, int fd_high) +/*[clinic end generated code: output=0a929ece386811c3 input=5855a3d053ebd4ec]*/ +{ + int i; Py_BEGIN_ALLOW_THREADS - for (i = fd_from; i < fd_to; i++) + for (i = fd_low; i < fd_high; i++) if (_PyVerify_fd(i)) close(i); Py_END_ALLOW_THREADS @@ -7797,36 +10905,99 @@ posix_closerange(PyObject *self, PyObject *args) } -PyDoc_STRVAR(posix_dup__doc__, -"dup(fd) -> fd2\n\n\ -Return a duplicate of a file descriptor."); +/*[clinic input] +os.dup -> int + + fd: int + / + +Return a duplicate of a file descriptor. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_dup__doc__, +"dup($module, fd, /)\n" +"--\n" +"\n" +"Return a duplicate of a file descriptor."); + +#define OS_DUP_METHODDEF \ + {"dup", (PyCFunction)os_dup, METH_VARARGS, os_dup__doc__}, + +static int +os_dup_impl(PyModuleDef *module, int fd); static PyObject * -posix_dup(PyObject *self, PyObject *args) +os_dup(PyModuleDef *module, PyObject *args) { + PyObject *return_value = NULL; int fd; + int _return_value; - if (!PyArg_ParseTuple(args, "i:dup", &fd)) - return NULL; + if (!PyArg_ParseTuple(args, + "i:dup", + &fd)) + goto exit; + _return_value = os_dup_impl(module, fd); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromLong((long)_return_value); - fd = _Py_dup(fd); - if (fd == -1) - return NULL; +exit: + return return_value; +} - return PyLong_FromLong((long)fd); +static int +os_dup_impl(PyModuleDef *module, int fd) +/*[clinic end generated code: output=75943e057b25e1bd input=6f10f7ea97f7852a]*/ +{ + return _Py_dup(fd); } -PyDoc_STRVAR(posix_dup2__doc__, -"dup2(old_fd, new_fd)\n\n\ -Duplicate file descriptor."); +/*[clinic input] +os.dup2 + fd: int + fd2: int + inheritable: bool=True + +Duplicate file descriptor. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_dup2__doc__, +"dup2($module, /, fd, fd2, inheritable=True)\n" +"--\n" +"\n" +"Duplicate file descriptor."); + +#define OS_DUP2_METHODDEF \ + {"dup2", (PyCFunction)os_dup2, METH_VARARGS|METH_KEYWORDS, os_dup2__doc__}, + +static PyObject * +os_dup2_impl(PyModuleDef *module, int fd, int fd2, int inheritable); static PyObject * -posix_dup2(PyObject *self, PyObject *args, PyObject *kwargs) +os_dup2(PyModuleDef *module, PyObject *args, PyObject *kwargs) { - static char *keywords[] = {"fd", "fd2", "inheritable", NULL}; - int fd, fd2; + PyObject *return_value = NULL; + static char *_keywords[] = {"fd", "fd2", "inheritable", NULL}; + int fd; + int fd2; int inheritable = 1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "ii|p:dup2", _keywords, + &fd, &fd2, &inheritable)) + goto exit; + return_value = os_dup2_impl(module, fd, fd2, inheritable); + +exit: + return return_value; +} + +static PyObject * +os_dup2_impl(PyModuleDef *module, int fd, int fd2, int inheritable) +/*[clinic end generated code: output=531e482dd11a99a0 input=76e96f511be0352f]*/ +{ int res; #if defined(HAVE_DUP3) && \ !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)) @@ -7834,13 +11005,13 @@ posix_dup2(PyObject *self, PyObject *args, PyObject *kwargs) int dup3_works = -1; #endif - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii|i:dup2", keywords, - &fd, &fd2, &inheritable)) - return NULL; - if (!_PyVerify_fd_dup2(fd, fd2)) return posix_error(); + /* dup2() can fail with EINTR if the target FD is already open, because it + * then has to be closed. See os_close_impl() for why we don't handle EINTR + * upon close(), and therefore below. + */ #ifdef MS_WINDOWS Py_BEGIN_ALLOW_THREADS res = dup2(fd, fd2); @@ -7898,126 +11069,251 @@ posix_dup2(PyObject *self, PyObject *args, PyObject *kwargs) #endif - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } + #ifdef HAVE_LOCKF -PyDoc_STRVAR(posix_lockf__doc__, -"lockf(fd, cmd, len)\n\n\ -Apply, test or remove a POSIX lock on an open file descriptor.\n\n\ -fd is an open file descriptor.\n\ -cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\ -F_TEST.\n\ -len specifies the section of the file to lock."); +/*[clinic input] +os.lockf -static PyObject * -posix_lockf(PyObject *self, PyObject *args) -{ - int fd, cmd, res; - off_t len; - if (!PyArg_ParseTuple(args, "iiO&:lockf", - &fd, &cmd, _parse_off_t, &len)) - return NULL; + fd: int + An open file descriptor. + command: int + One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST. + length: Py_off_t + The number of bytes to lock, starting at the current position. + / - Py_BEGIN_ALLOW_THREADS - res = lockf(fd, cmd, len); - Py_END_ALLOW_THREADS +Apply, test or remove a POSIX lock on an open file descriptor. - if (res < 0) - return posix_error(); +[clinic start generated code]*/ + +PyDoc_STRVAR(os_lockf__doc__, +"lockf($module, fd, command, length, /)\n" +"--\n" +"\n" +"Apply, test or remove a POSIX lock on an open file descriptor.\n" +"\n" +" fd\n" +" An open file descriptor.\n" +" command\n" +" One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.\n" +" length\n" +" The number of bytes to lock, starting at the current position."); + +#define OS_LOCKF_METHODDEF \ + {"lockf", (PyCFunction)os_lockf, METH_VARARGS, os_lockf__doc__}, + +static PyObject * +os_lockf_impl(PyModuleDef *module, int fd, int command, Py_off_t length); + +static PyObject * +os_lockf(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd; + int command; + Py_off_t length; + + if (!PyArg_ParseTuple(args, + "iiO&:lockf", + &fd, &command, Py_off_t_converter, &length)) + goto exit; + return_value = os_lockf_impl(module, fd, command, length); + +exit: + return return_value; +} + +static PyObject * +os_lockf_impl(PyModuleDef *module, int fd, int command, Py_off_t length) +/*[clinic end generated code: output=1b28346ac7335c0f input=65da41d2106e9b79]*/ +{ + int res; + + Py_BEGIN_ALLOW_THREADS + res = lockf(fd, command, length); + Py_END_ALLOW_THREADS + + if (res < 0) + return posix_error(); Py_RETURN_NONE; } -#endif +#endif /* HAVE_LOCKF */ + + +/*[clinic input] +os.lseek -> Py_off_t + fd: int + position: Py_off_t + how: int + / + +Set the position of a file descriptor. Return the new position. + +Return the new cursor position in number of bytes +relative to the beginning of the file. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_lseek__doc__, +"lseek($module, fd, position, how, /)\n" +"--\n" +"\n" +"Set the position of a file descriptor. Return the new position.\n" +"\n" +"Return the new cursor position in number of bytes\n" +"relative to the beginning of the file."); + +#define OS_LSEEK_METHODDEF \ + {"lseek", (PyCFunction)os_lseek, METH_VARARGS, os_lseek__doc__}, -PyDoc_STRVAR(posix_lseek__doc__, -"lseek(fd, pos, how) -> newpos\n\n\ -Set the current position of a file descriptor.\n\ -Return the new cursor position in bytes, starting from the beginning."); +static Py_off_t +os_lseek_impl(PyModuleDef *module, int fd, Py_off_t position, int how); static PyObject * -posix_lseek(PyObject *self, PyObject *args) +os_lseek(PyModuleDef *module, PyObject *args) { - int fd, how; -#ifdef MS_WINDOWS - PY_LONG_LONG pos, res; -#else - off_t pos, res; -#endif - PyObject *posobj; - if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how)) - return NULL; + PyObject *return_value = NULL; + int fd; + Py_off_t position; + int how; + Py_off_t _return_value; + + if (!PyArg_ParseTuple(args, + "iO&i:lseek", + &fd, Py_off_t_converter, &position, &how)) + goto exit; + _return_value = os_lseek_impl(module, fd, position, how); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromPy_off_t(_return_value); + +exit: + return return_value; +} + +static Py_off_t +os_lseek_impl(PyModuleDef *module, int fd, Py_off_t position, int how) +/*[clinic end generated code: output=88cfc146f55667af input=902654ad3f96a6d3]*/ +{ + Py_off_t result; + + if (!_PyVerify_fd(fd)) { + posix_error(); + return -1; + } #ifdef SEEK_SET /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */ switch (how) { - case 0: how = SEEK_SET; break; - case 1: how = SEEK_CUR; break; - case 2: how = SEEK_END; break; + case 0: how = SEEK_SET; break; + case 1: how = SEEK_CUR; break; + case 2: how = SEEK_END; break; } #endif /* SEEK_END */ -#if !defined(HAVE_LARGEFILE_SUPPORT) - pos = PyLong_AsLong(posobj); -#else - pos = PyLong_AsLongLong(posobj); -#endif if (PyErr_Occurred()) - return NULL; + return -1; - if (!_PyVerify_fd(fd)) - return posix_error(); + if (!_PyVerify_fd(fd)) { + posix_error(); + return -1; + } Py_BEGIN_ALLOW_THREADS #ifdef MS_WINDOWS - res = _lseeki64(fd, pos, how); + result = _lseeki64(fd, position, how); #else - res = lseek(fd, pos, how); + result = lseek(fd, position, how); #endif Py_END_ALLOW_THREADS - if (res < 0) - return posix_error(); + if (result < 0) + posix_error(); -#if !defined(HAVE_LARGEFILE_SUPPORT) - return PyLong_FromLong(res); -#else - return PyLong_FromLongLong(res); -#endif + return result; } -PyDoc_STRVAR(posix_read__doc__, -"read(fd, buffersize) -> bytes\n\n\ -Read a file descriptor."); +/*[clinic input] +os.read + fd: int + length: Py_ssize_t + / + +Read from a file descriptor. Returns a bytes object. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_read__doc__, +"read($module, fd, length, /)\n" +"--\n" +"\n" +"Read from a file descriptor. Returns a bytes object."); + +#define OS_READ_METHODDEF \ + {"read", (PyCFunction)os_read, METH_VARARGS, os_read__doc__}, + +static PyObject * +os_read_impl(PyModuleDef *module, int fd, Py_ssize_t length); + +static PyObject * +os_read(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd; + Py_ssize_t length; + + if (!PyArg_ParseTuple(args, + "in:read", + &fd, &length)) + goto exit; + return_value = os_read_impl(module, fd, length); + +exit: + return return_value; +} static PyObject * -posix_read(PyObject *self, PyObject *args) +os_read_impl(PyModuleDef *module, int fd, Py_ssize_t length) +/*[clinic end generated code: output=1f3bc27260a24968 input=1df2eaa27c0bf1d3]*/ { - int fd, size; Py_ssize_t n; + int async_err = 0; PyObject *buffer; - if (!PyArg_ParseTuple(args, "ii:read", &fd, &size)) - return NULL; - if (size < 0) { + + if (length < 0) { errno = EINVAL; return posix_error(); } - buffer = PyBytes_FromStringAndSize((char *)NULL, size); + if (!_PyVerify_fd(fd)) + return posix_error(); + +#ifdef MS_WINDOWS + #define READ_CAST (int) + if (length > INT_MAX) + length = INT_MAX; +#else + #define READ_CAST +#endif + + buffer = PyBytes_FromStringAndSize((char *)NULL, length); if (buffer == NULL) return NULL; - if (!_PyVerify_fd(fd)) { - Py_DECREF(buffer); - return posix_error(); - } - Py_BEGIN_ALLOW_THREADS - n = read(fd, PyBytes_AS_STRING(buffer), size); - Py_END_ALLOW_THREADS + + do { + Py_BEGIN_ALLOW_THREADS + n = read(fd, PyBytes_AS_STRING(buffer), READ_CAST length); + Py_END_ALLOW_THREADS + } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + if (n < 0) { Py_DECREF(buffer); - return posix_error(); + return (!async_err) ? posix_error() : NULL; } - if (n != size) + + if (n != length) _PyBytes_Resize(&buffer, n); + return buffer; } @@ -8032,14 +11328,14 @@ iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type) *iov = PyMem_New(struct iovec, cnt); if (*iov == NULL) { PyErr_NoMemory(); - return total; + return -1; } *buf = PyMem_New(Py_buffer, cnt); if (*buf == NULL) { PyMem_Del(*iov); PyErr_NoMemory(); - return total; + return -1; } for (i = 0; i < cnt; i++) { @@ -8064,7 +11360,7 @@ iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type) PyBuffer_Release(&(*buf)[j]); } PyMem_Del(*buf); - return 0; + return -1; } static void @@ -8079,114 +11375,270 @@ iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt) } #endif + #ifdef HAVE_READV -PyDoc_STRVAR(posix_readv__doc__, -"readv(fd, buffers) -> bytesread\n\n\ -Read from a file descriptor into a number of writable buffers. buffers\n\ -is an arbitrary sequence of writable buffers.\n\ -Returns the total number of bytes read."); +/*[clinic input] +os.readv -> Py_ssize_t + + fd: int + buffers: object + / + +Read from a file descriptor fd into an iterable of buffers. + +The buffers should be mutable buffers accepting bytes. +readv will transfer data into each buffer until it is full +and then move on to the next buffer in the sequence to hold +the rest of the data. + +readv returns the total number of bytes read, +which may be less than the total capacity of all the buffers. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_readv__doc__, +"readv($module, fd, buffers, /)\n" +"--\n" +"\n" +"Read from a file descriptor fd into an iterable of buffers.\n" +"\n" +"The buffers should be mutable buffers accepting bytes.\n" +"readv will transfer data into each buffer until it is full\n" +"and then move on to the next buffer in the sequence to hold\n" +"the rest of the data.\n" +"\n" +"readv returns the total number of bytes read,\n" +"which may be less than the total capacity of all the buffers."); + +#define OS_READV_METHODDEF \ + {"readv", (PyCFunction)os_readv, METH_VARARGS, os_readv__doc__}, + +static Py_ssize_t +os_readv_impl(PyModuleDef *module, int fd, PyObject *buffers); static PyObject * -posix_readv(PyObject *self, PyObject *args) +os_readv(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd; + PyObject *buffers; + Py_ssize_t _return_value; + + if (!PyArg_ParseTuple(args, + "iO:readv", + &fd, &buffers)) + goto exit; + _return_value = os_readv_impl(module, fd, buffers); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromSsize_t(_return_value); + +exit: + return return_value; +} + +static Py_ssize_t +os_readv_impl(PyModuleDef *module, int fd, PyObject *buffers) +/*[clinic end generated code: output=72748b1c32a6e2a1 input=e679eb5dbfa0357d]*/ { - int fd, cnt; + int cnt; Py_ssize_t n; - PyObject *seq; + int async_err = 0; struct iovec *iov; Py_buffer *buf; - if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq)) - return NULL; - if (!PySequence_Check(seq)) { + if (!PySequence_Check(buffers)) { PyErr_SetString(PyExc_TypeError, "readv() arg 2 must be a sequence"); - return NULL; + return -1; } - cnt = PySequence_Size(seq); - if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE)) - return NULL; + cnt = PySequence_Size(buffers); - Py_BEGIN_ALLOW_THREADS - n = readv(fd, iov, cnt); - Py_END_ALLOW_THREADS + if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) + return -1; + + do { + Py_BEGIN_ALLOW_THREADS + n = readv(fd, iov, cnt); + Py_END_ALLOW_THREADS + } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); iov_cleanup(iov, buf, cnt); - return PyLong_FromSsize_t(n); + if (n < 0) { + if (!async_err) + posix_error(); + return -1; + } + + return n; } -#endif +#endif /* HAVE_READV */ + #ifdef HAVE_PREAD -PyDoc_STRVAR(posix_pread__doc__, -"pread(fd, buffersize, offset) -> string\n\n\ -Read from a file descriptor, fd, at a position of offset. It will read up\n\ -to buffersize number of bytes. The file offset remains unchanged."); +/*[clinic input] +# TODO length should be size_t! but Python doesn't support parsing size_t yet. +os.pread + + fd: int + length: int + offset: Py_off_t + / + +Read a number of bytes from a file descriptor starting at a particular offset. + +Read length bytes from file descriptor fd, starting at offset bytes from +the beginning of the file. The file offset remains unchanged. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_pread__doc__, +"pread($module, fd, length, offset, /)\n" +"--\n" +"\n" +"Read a number of bytes from a file descriptor starting at a particular offset.\n" +"\n" +"Read length bytes from file descriptor fd, starting at offset bytes from\n" +"the beginning of the file. The file offset remains unchanged."); + +#define OS_PREAD_METHODDEF \ + {"pread", (PyCFunction)os_pread, METH_VARARGS, os_pread__doc__}, + +static PyObject * +os_pread_impl(PyModuleDef *module, int fd, int length, Py_off_t offset); static PyObject * -posix_pread(PyObject *self, PyObject *args) +os_pread(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd; + int length; + Py_off_t offset; + + if (!PyArg_ParseTuple(args, + "iiO&:pread", + &fd, &length, Py_off_t_converter, &offset)) + goto exit; + return_value = os_pread_impl(module, fd, length, offset); + +exit: + return return_value; +} + +static PyObject * +os_pread_impl(PyModuleDef *module, int fd, int length, Py_off_t offset) +/*[clinic end generated code: output=7b62bf6c06e20ae8 input=084948dcbaa35d4c]*/ { - int fd, size; - off_t offset; Py_ssize_t n; + int async_err = 0; PyObject *buffer; - if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset)) - return NULL; - if (size < 0) { + if (length < 0) { errno = EINVAL; return posix_error(); } - buffer = PyBytes_FromStringAndSize((char *)NULL, size); + buffer = PyBytes_FromStringAndSize((char *)NULL, length); if (buffer == NULL) return NULL; if (!_PyVerify_fd(fd)) { Py_DECREF(buffer); return posix_error(); } - Py_BEGIN_ALLOW_THREADS - n = pread(fd, PyBytes_AS_STRING(buffer), size, offset); - Py_END_ALLOW_THREADS + + do { + Py_BEGIN_ALLOW_THREADS + n = pread(fd, PyBytes_AS_STRING(buffer), length, offset); + Py_END_ALLOW_THREADS + } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + if (n < 0) { Py_DECREF(buffer); - return posix_error(); + return (!async_err) ? posix_error() : NULL; } - if (n != size) + if (n != length) _PyBytes_Resize(&buffer, n); return buffer; } -#endif +#endif /* HAVE_PREAD */ + + +/*[clinic input] +os.write -> Py_ssize_t + + fd: int + data: Py_buffer + / + +Write a bytes object to a file descriptor. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_write__doc__, +"write($module, fd, data, /)\n" +"--\n" +"\n" +"Write a bytes object to a file descriptor."); + +#define OS_WRITE_METHODDEF \ + {"write", (PyCFunction)os_write, METH_VARARGS, os_write__doc__}, -PyDoc_STRVAR(posix_write__doc__, -"write(fd, data) -> byteswritten\n\n\ -Write bytes to a file descriptor."); +static Py_ssize_t +os_write_impl(PyModuleDef *module, int fd, Py_buffer *data); static PyObject * -posix_write(PyObject *self, PyObject *args) +os_write(PyModuleDef *module, PyObject *args) { - Py_buffer pbuf; + PyObject *return_value = NULL; int fd; - Py_ssize_t size, len; + Py_buffer data = {NULL, NULL}; + Py_ssize_t _return_value; + + if (!PyArg_ParseTuple(args, + "iy*:write", + &fd, &data)) + goto exit; + _return_value = os_write_impl(module, fd, &data); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromSsize_t(_return_value); + +exit: + /* Cleanup for data */ + if (data.obj) + PyBuffer_Release(&data); + + return return_value; +} + +static Py_ssize_t +os_write_impl(PyModuleDef *module, int fd, Py_buffer *data) +/*[clinic end generated code: output=aeb96acfdd4d5112 input=3207e28963234f3c]*/ +{ + Py_ssize_t size; + int async_err = 0; + Py_ssize_t len = data->len; - if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf)) - return NULL; if (!_PyVerify_fd(fd)) { - PyBuffer_Release(&pbuf); - return posix_error(); + posix_error(); + return -1; } - len = pbuf.len; - Py_BEGIN_ALLOW_THREADS + + do { + Py_BEGIN_ALLOW_THREADS #ifdef MS_WINDOWS - if (len > INT_MAX) - len = INT_MAX; - size = write(fd, pbuf.buf, (int)len); + if (len > INT_MAX) + len = INT_MAX; + size = write(fd, data->buf, (int)len); #else - size = write(fd, pbuf.buf, len); + size = write(fd, data->buf, len); #endif - Py_END_ALLOW_THREADS - PyBuffer_Release(&pbuf); - if (size < 0) - return posix_error(); - return PyLong_FromSsize_t(size); + Py_END_ALLOW_THREADS + } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + + if (size < 0) { + if (!async_err) + posix_error(); + return -1; + } + return size; } #ifdef HAVE_SENDFILE @@ -8196,11 +11648,13 @@ sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\ -> byteswritten\n\ Copy nbytes bytes from file descriptor in to file descriptor out."); +/* AC 3.5: don't bother converting, has optional group*/ static PyObject * posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict) { int in, out; Py_ssize_t ret; + int async_err = 0; off_t offset; #if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__) @@ -8221,10 +11675,10 @@ posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict) #ifdef __APPLE__ if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile", - keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes, + keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes, #else if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile", - keywords, &out, &in, _parse_off_t, &offset, &len, + keywords, &out, &in, Py_off_t_converter, &offset, &len, #endif &headers, &trailers, &flags)) return NULL; @@ -8237,8 +11691,8 @@ posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict) Py_ssize_t i = 0; /* Avoid uninitialized warning */ sf.hdr_cnt = PySequence_Size(headers); if (sf.hdr_cnt > 0 && - !(i = iov_setup(&(sf.headers), &hbuf, - headers, sf.hdr_cnt, PyBUF_SIMPLE))) + (i = iov_setup(&(sf.headers), &hbuf, + headers, sf.hdr_cnt, PyBUF_SIMPLE)) < 0) return NULL; #ifdef __APPLE__ sbytes += i; @@ -8254,8 +11708,8 @@ posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict) Py_ssize_t i = 0; /* Avoid uninitialized warning */ sf.trl_cnt = PySequence_Size(trailers); if (sf.trl_cnt > 0 && - !(i = iov_setup(&(sf.trailers), &tbuf, - trailers, sf.trl_cnt, PyBUF_SIMPLE))) + (i = iov_setup(&(sf.trailers), &tbuf, + trailers, sf.trl_cnt, PyBUF_SIMPLE)) < 0) return NULL; #ifdef __APPLE__ sbytes += i; @@ -8263,13 +11717,15 @@ posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict) } } - Py_BEGIN_ALLOW_THREADS + do { + Py_BEGIN_ALLOW_THREADS #ifdef __APPLE__ - ret = sendfile(in, out, offset, &sbytes, &sf, flags); + ret = sendfile(in, out, offset, &sbytes, &sf, flags); #else - ret = sendfile(in, out, offset, len, &sf, &sbytes, flags); + ret = sendfile(in, out, offset, len, &sf, &sbytes, flags); #endif - Py_END_ALLOW_THREADS + Py_END_ALLOW_THREADS + } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); if (sf.headers != NULL) iov_cleanup(sf.headers, hbuf, sf.hdr_cnt); @@ -8288,7 +11744,7 @@ posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict) return posix_error(); } } - return posix_error(); + return (!async_err) ? posix_error() : NULL; } goto done; @@ -8309,80 +11765,190 @@ posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict) return NULL; #ifdef linux if (offobj == Py_None) { - Py_BEGIN_ALLOW_THREADS - ret = sendfile(out, in, NULL, count); - Py_END_ALLOW_THREADS + do { + Py_BEGIN_ALLOW_THREADS + ret = sendfile(out, in, NULL, count); + Py_END_ALLOW_THREADS + } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); if (ret < 0) - return posix_error(); + return (!async_err) ? posix_error() : NULL; return Py_BuildValue("n", ret); } #endif - if (!_parse_off_t(offobj, &offset)) + if (!Py_off_t_converter(offobj, &offset)) return NULL; - Py_BEGIN_ALLOW_THREADS - ret = sendfile(out, in, &offset, count); - Py_END_ALLOW_THREADS + + do { + Py_BEGIN_ALLOW_THREADS + ret = sendfile(out, in, &offset, count); + Py_END_ALLOW_THREADS + } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); if (ret < 0) - return posix_error(); + return (!async_err) ? posix_error() : NULL; return Py_BuildValue("n", ret); #endif } -#endif +#endif /* HAVE_SENDFILE */ + + +/*[clinic input] +os.fstat -PyDoc_STRVAR(posix_fstat__doc__, -"fstat(fd) -> stat result\n\n\ -Like stat(), but for an open file descriptor.\n\ -Equivalent to stat(fd=fd)."); + fd : int + +Perform a stat system call on the given file descriptor. + +Like stat(), but for an open file descriptor. +Equivalent to os.stat(fd). +[clinic start generated code]*/ + +PyDoc_STRVAR(os_fstat__doc__, +"fstat($module, /, fd)\n" +"--\n" +"\n" +"Perform a stat system call on the given file descriptor.\n" +"\n" +"Like stat(), but for an open file descriptor.\n" +"Equivalent to os.stat(fd)."); + +#define OS_FSTAT_METHODDEF \ + {"fstat", (PyCFunction)os_fstat, METH_VARARGS|METH_KEYWORDS, os_fstat__doc__}, + +static PyObject * +os_fstat_impl(PyModuleDef *module, int fd); static PyObject * -posix_fstat(PyObject *self, PyObject *args) +os_fstat(PyModuleDef *module, PyObject *args, PyObject *kwargs) { + PyObject *return_value = NULL; + static char *_keywords[] = {"fd", NULL}; int fd; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "i:fstat", _keywords, + &fd)) + goto exit; + return_value = os_fstat_impl(module, fd); + +exit: + return return_value; +} + +static PyObject * +os_fstat_impl(PyModuleDef *module, int fd) +/*[clinic end generated code: output=dae4a9678c7bd881 input=27e0e0ebbe5600c9]*/ +{ STRUCT_STAT st; int res; - if (!PyArg_ParseTuple(args, "i:fstat", &fd)) - return NULL; -#ifdef __VMS - /* on OpenVMS we must ensure that all bytes are written to the file */ - fsync(fd); -#endif - Py_BEGIN_ALLOW_THREADS - res = FSTAT(fd, &st); - Py_END_ALLOW_THREADS + int async_err = 0; + + do { + Py_BEGIN_ALLOW_THREADS + res = FSTAT(fd, &st); + Py_END_ALLOW_THREADS + } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); if (res != 0) { #ifdef MS_WINDOWS return PyErr_SetFromWindowsErr(0); #else - return posix_error(); + return (!async_err) ? posix_error() : NULL; #endif } return _pystat_fromstructstat(&st); } -PyDoc_STRVAR(posix_isatty__doc__, -"isatty(fd) -> bool\n\n\ -Return True if the file descriptor 'fd' is an open file descriptor\n\ -connected to the slave end of a terminal."); + +/*[clinic input] +os.isatty -> bool + fd: int + / + +Return True if the fd is connected to a terminal. + +Return True if the file descriptor is an open file descriptor +connected to the slave end of a terminal. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_isatty__doc__, +"isatty($module, fd, /)\n" +"--\n" +"\n" +"Return True if the fd is connected to a terminal.\n" +"\n" +"Return True if the file descriptor is an open file descriptor\n" +"connected to the slave end of a terminal."); + +#define OS_ISATTY_METHODDEF \ + {"isatty", (PyCFunction)os_isatty, METH_VARARGS, os_isatty__doc__}, + +static int +os_isatty_impl(PyModuleDef *module, int fd); static PyObject * -posix_isatty(PyObject *self, PyObject *args) +os_isatty(PyModuleDef *module, PyObject *args) { + PyObject *return_value = NULL; int fd; - if (!PyArg_ParseTuple(args, "i:isatty", &fd)) - return NULL; + int _return_value; + + if (!PyArg_ParseTuple(args, + "i:isatty", + &fd)) + goto exit; + _return_value = os_isatty_impl(module, fd); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyBool_FromLong((long)_return_value); + +exit: + return return_value; +} + +static int +os_isatty_impl(PyModuleDef *module, int fd) +/*[clinic end generated code: output=4bfadbfe22715097 input=08ce94aa1eaf7b5e]*/ +{ if (!_PyVerify_fd(fd)) - return PyBool_FromLong(0); - return PyBool_FromLong(isatty(fd)); + return 0; + return isatty(fd); } + #ifdef HAVE_PIPE -PyDoc_STRVAR(posix_pipe__doc__, -"pipe() -> (read_end, write_end)\n\n\ -Create a pipe."); +/*[clinic input] +os.pipe + +Create a pipe. + +Returns a tuple of two file descriptors: + (read_fd, write_fd) +[clinic start generated code]*/ + +PyDoc_STRVAR(os_pipe__doc__, +"pipe($module, /)\n" +"--\n" +"\n" +"Create a pipe.\n" +"\n" +"Returns a tuple of two file descriptors:\n" +" (read_fd, write_fd)"); + +#define OS_PIPE_METHODDEF \ + {"pipe", (PyCFunction)os_pipe, METH_NOARGS, os_pipe__doc__}, + +static PyObject * +os_pipe_impl(PyModuleDef *module); static PyObject * -posix_pipe(PyObject *self, PyObject *noargs) +os_pipe(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_pipe_impl(module); +} + +static PyObject * +os_pipe_impl(PyModuleDef *module) +/*[clinic end generated code: output=0da2479f2266e774 input=02535e8c8fa6c4d4]*/ { int fds[2]; #ifdef MS_WINDOWS @@ -8450,25 +12016,64 @@ posix_pipe(PyObject *self, PyObject *noargs) } #endif /* HAVE_PIPE */ + #ifdef HAVE_PIPE2 -PyDoc_STRVAR(posix_pipe2__doc__, -"pipe2(flags) -> (read_end, write_end)\n\n\ -Create a pipe with flags set atomically.\n\ -flags can be constructed by ORing together one or more of these values:\n\ -O_NONBLOCK, O_CLOEXEC.\n\ -"); +/*[clinic input] +os.pipe2 + + flags: int + / + +Create a pipe with flags set atomically. + +Returns a tuple of two file descriptors: + (read_fd, write_fd) + +flags can be constructed by ORing together one or more of these values: +O_NONBLOCK, O_CLOEXEC. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_pipe2__doc__, +"pipe2($module, flags, /)\n" +"--\n" +"\n" +"Create a pipe with flags set atomically.\n" +"\n" +"Returns a tuple of two file descriptors:\n" +" (read_fd, write_fd)\n" +"\n" +"flags can be constructed by ORing together one or more of these values:\n" +"O_NONBLOCK, O_CLOEXEC."); + +#define OS_PIPE2_METHODDEF \ + {"pipe2", (PyCFunction)os_pipe2, METH_VARARGS, os_pipe2__doc__}, + +static PyObject * +os_pipe2_impl(PyModuleDef *module, int flags); static PyObject * -posix_pipe2(PyObject *self, PyObject *arg) +os_pipe2(PyModuleDef *module, PyObject *args) { + PyObject *return_value = NULL; int flags; + + if (!PyArg_ParseTuple(args, + "i:pipe2", + &flags)) + goto exit; + return_value = os_pipe2_impl(module, flags); + +exit: + return return_value; +} + +static PyObject * +os_pipe2_impl(PyModuleDef *module, int flags) +/*[clinic end generated code: output=9e27c799ce19220b input=f261b6e7e63c6817]*/ +{ int fds[2]; int res; - flags = _PyLong_AsInt(arg); - if (flags == -1 && PyErr_Occurred()) - return NULL; - res = pipe2(fds, flags); if (res != 0) return posix_error(); @@ -8476,2666 +12081,4822 @@ posix_pipe2(PyObject *self, PyObject *arg) } #endif /* HAVE_PIPE2 */ + #ifdef HAVE_WRITEV -PyDoc_STRVAR(posix_writev__doc__, -"writev(fd, buffers) -> byteswritten\n\n\ -Write the contents of buffers to a file descriptor, where buffers is an\n\ -arbitrary sequence of buffers.\n\ -Returns the total bytes written."); +/*[clinic input] +os.writev -> Py_ssize_t + fd: int + buffers: object + / + +Iterate over buffers, and write the contents of each to a file descriptor. + +Returns the total number of bytes written. +buffers must be a sequence of bytes-like objects. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_writev__doc__, +"writev($module, fd, buffers, /)\n" +"--\n" +"\n" +"Iterate over buffers, and write the contents of each to a file descriptor.\n" +"\n" +"Returns the total number of bytes written.\n" +"buffers must be a sequence of bytes-like objects."); + +#define OS_WRITEV_METHODDEF \ + {"writev", (PyCFunction)os_writev, METH_VARARGS, os_writev__doc__}, + +static Py_ssize_t +os_writev_impl(PyModuleDef *module, int fd, PyObject *buffers); static PyObject * -posix_writev(PyObject *self, PyObject *args) +os_writev(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd; + PyObject *buffers; + Py_ssize_t _return_value; + + if (!PyArg_ParseTuple(args, + "iO:writev", + &fd, &buffers)) + goto exit; + _return_value = os_writev_impl(module, fd, buffers); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromSsize_t(_return_value); + +exit: + return return_value; +} + +static Py_ssize_t +os_writev_impl(PyModuleDef *module, int fd, PyObject *buffers) +/*[clinic end generated code: output=591c662dccbe4951 input=5b8d17fe4189d2fe]*/ { - int fd, cnt; - Py_ssize_t res; - PyObject *seq; + int cnt; + Py_ssize_t result; + int async_err = 0; struct iovec *iov; Py_buffer *buf; - if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq)) - return NULL; - if (!PySequence_Check(seq)) { + + if (!PySequence_Check(buffers)) { PyErr_SetString(PyExc_TypeError, "writev() arg 2 must be a sequence"); - return NULL; + return -1; } - cnt = PySequence_Size(seq); + cnt = PySequence_Size(buffers); - if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE)) { - return NULL; + if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) { + return -1; } - Py_BEGIN_ALLOW_THREADS - res = writev(fd, iov, cnt); - Py_END_ALLOW_THREADS + do { + Py_BEGIN_ALLOW_THREADS + result = writev(fd, iov, cnt); + Py_END_ALLOW_THREADS + } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); iov_cleanup(iov, buf, cnt); - return PyLong_FromSsize_t(res); + if (result < 0 && !async_err) + posix_error(); + + return result; } -#endif +#endif /* HAVE_WRITEV */ + #ifdef HAVE_PWRITE -PyDoc_STRVAR(posix_pwrite__doc__, -"pwrite(fd, string, offset) -> byteswritten\n\n\ -Write string to a file descriptor, fd, from offset, leaving the file\n\ -offset unchanged."); +/*[clinic input] +os.pwrite -> Py_ssize_t + + fd: int + buffer: Py_buffer + offset: Py_off_t + / + +Write bytes to a file descriptor starting at a particular offset. + +Write buffer to fd, starting at offset bytes from the beginning of +the file. Returns the number of bytes writte. Does not change the +current file offset. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_pwrite__doc__, +"pwrite($module, fd, buffer, offset, /)\n" +"--\n" +"\n" +"Write bytes to a file descriptor starting at a particular offset.\n" +"\n" +"Write buffer to fd, starting at offset bytes from the beginning of\n" +"the file. Returns the number of bytes writte. Does not change the\n" +"current file offset."); + +#define OS_PWRITE_METHODDEF \ + {"pwrite", (PyCFunction)os_pwrite, METH_VARARGS, os_pwrite__doc__}, + +static Py_ssize_t +os_pwrite_impl(PyModuleDef *module, int fd, Py_buffer *buffer, Py_off_t offset); static PyObject * -posix_pwrite(PyObject *self, PyObject *args) +os_pwrite(PyModuleDef *module, PyObject *args) { - Py_buffer pbuf; + PyObject *return_value = NULL; int fd; - off_t offset; - Py_ssize_t size; + Py_buffer buffer = {NULL, NULL}; + Py_off_t offset; + Py_ssize_t _return_value; - if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset)) - return NULL; + if (!PyArg_ParseTuple(args, + "iy*O&:pwrite", + &fd, &buffer, Py_off_t_converter, &offset)) + goto exit; + _return_value = os_pwrite_impl(module, fd, &buffer, offset); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromSsize_t(_return_value); + +exit: + /* Cleanup for buffer */ + if (buffer.obj) + PyBuffer_Release(&buffer); + + return return_value; +} + +static Py_ssize_t +os_pwrite_impl(PyModuleDef *module, int fd, Py_buffer *buffer, Py_off_t offset) +/*[clinic end generated code: output=ec9cc5b2238e96a7 input=19903f1b3dd26377]*/ +{ + Py_ssize_t size; + int async_err = 0; if (!_PyVerify_fd(fd)) { - PyBuffer_Release(&pbuf); - return posix_error(); + posix_error(); + return -1; } - Py_BEGIN_ALLOW_THREADS - size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset); - Py_END_ALLOW_THREADS - PyBuffer_Release(&pbuf); - if (size < 0) - return posix_error(); - return PyLong_FromSsize_t(size); + + do { + Py_BEGIN_ALLOW_THREADS + size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset); + Py_END_ALLOW_THREADS + } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + + if (size < 0 && !async_err) + posix_error(); + return size; } -#endif +#endif /* HAVE_PWRITE */ + #ifdef HAVE_MKFIFO -PyDoc_STRVAR(posix_mkfifo__doc__, -"mkfifo(path, mode=0o666, *, dir_fd=None)\n\n\ -Create a FIFO (a POSIX named pipe).\n\ -\n\ -If dir_fd is not None, it should be a file descriptor open to a directory,\n\ - and path should be relative; path will then be relative to that directory.\n\ -dir_fd may not be implemented on your platform.\n\ - If it is unavailable, using it will raise a NotImplementedError."); +/*[clinic input] +os.mkfifo + + path: path_t + mode: int=0o666 + * + dir_fd: dir_fd(requires='mkfifoat')=None + +Create a "fifo" (a POSIX named pipe). + +If dir_fd is not None, it should be a file descriptor open to a directory, + and path should be relative; path will then be relative to that directory. +dir_fd may not be implemented on your platform. + If it is unavailable, using it will raise a NotImplementedError. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_mkfifo__doc__, +"mkfifo($module, /, path, mode=438, *, dir_fd=None)\n" +"--\n" +"\n" +"Create a \"fifo\" (a POSIX named pipe).\n" +"\n" +"If dir_fd is not None, it should be a file descriptor open to a directory,\n" +" and path should be relative; path will then be relative to that directory.\n" +"dir_fd may not be implemented on your platform.\n" +" If it is unavailable, using it will raise a NotImplementedError."); + +#define OS_MKFIFO_METHODDEF \ + {"mkfifo", (PyCFunction)os_mkfifo, METH_VARARGS|METH_KEYWORDS, os_mkfifo__doc__}, + +static PyObject * +os_mkfifo_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd); static PyObject * -posix_mkfifo(PyObject *self, PyObject *args, PyObject *kwargs) +os_mkfifo(PyModuleDef *module, PyObject *args, PyObject *kwargs) { - path_t path; - int mode = 0666; - int dir_fd = DEFAULT_DIR_FD; - int result; PyObject *return_value = NULL; - static char *keywords[] = {"path", "mode", "dir_fd", NULL}; - - memset(&path, 0, sizeof(path)); - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkfifo", keywords, - path_converter, &path, - &mode, -#ifdef HAVE_MKFIFOAT - dir_fd_converter, &dir_fd -#else - dir_fd_unavailable, &dir_fd -#endif - )) - return NULL; - - Py_BEGIN_ALLOW_THREADS -#ifdef HAVE_MKFIFOAT - if (dir_fd != DEFAULT_DIR_FD) - result = mkfifoat(dir_fd, path.narrow, mode); - else -#endif - result = mkfifo(path.narrow, mode); - Py_END_ALLOW_THREADS + static char *_keywords[] = {"path", "mode", "dir_fd", NULL}; + path_t path = PATH_T_INITIALIZE("mkfifo", "path", 0, 0); + int mode = 438; + int dir_fd = DEFAULT_DIR_FD; - if (result < 0) { - return_value = posix_error(); + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&|i$O&:mkfifo", _keywords, + path_converter, &path, &mode, MKFIFOAT_DIR_FD_CONVERTER, &dir_fd)) goto exit; - } - - return_value = Py_None; - Py_INCREF(Py_None); + return_value = os_mkfifo_impl(module, &path, mode, dir_fd); exit: + /* Cleanup for path */ path_cleanup(&path); + return return_value; } -#endif - -#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) -PyDoc_STRVAR(posix_mknod__doc__, -"mknod(filename, mode=0o600, device=0, *, dir_fd=None)\n\n\ -Create a filesystem node (file, device special file or named pipe)\n\ -named filename. mode specifies both the permissions to use and the\n\ -type of node to be created, being combined (bitwise OR) with one of\n\ -S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\ -device defines the newly created device special file (probably using\n\ -os.makedev()), otherwise it is ignored.\n\ -\n\ -If dir_fd is not None, it should be a file descriptor open to a directory,\n\ - and path should be relative; path will then be relative to that directory.\n\ -dir_fd may not be implemented on your platform.\n\ - If it is unavailable, using it will raise a NotImplementedError."); - static PyObject * -posix_mknod(PyObject *self, PyObject *args, PyObject *kwargs) +os_mkfifo_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd) +/*[clinic end generated code: output=b3321927546893d0 input=73032e98a36e0e19]*/ { - path_t path; - int mode = 0666; - int device = 0; - int dir_fd = DEFAULT_DIR_FD; int result; - PyObject *return_value = NULL; - static char *keywords[] = {"path", "mode", "device", "dir_fd", NULL}; + int async_err = 0; - memset(&path, 0, sizeof(path)); - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|ii$O&:mknod", keywords, - path_converter, &path, - &mode, &device, -#ifdef HAVE_MKNODAT - dir_fd_converter, &dir_fd -#else - dir_fd_unavailable, &dir_fd + do { + Py_BEGIN_ALLOW_THREADS +#ifdef HAVE_MKFIFOAT + if (dir_fd != DEFAULT_DIR_FD) + result = mkfifoat(dir_fd, path->narrow, mode); + else #endif - )) - return NULL; + result = mkfifo(path->narrow, mode); + Py_END_ALLOW_THREADS + } while (result != 0 && errno == EINTR && + !(async_err = PyErr_CheckSignals())); + if (result != 0) + return (!async_err) ? posix_error() : NULL; - Py_BEGIN_ALLOW_THREADS -#ifdef HAVE_MKNODAT - if (dir_fd != DEFAULT_DIR_FD) - result = mknodat(dir_fd, path.narrow, mode, device); - else -#endif - result = mknod(path.narrow, mode, device); - Py_END_ALLOW_THREADS + Py_RETURN_NONE; +} +#endif /* HAVE_MKFIFO */ - if (result < 0) { - return_value = posix_error(); - goto exit; - } - return_value = Py_None; - Py_INCREF(Py_None); +#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) +/*[clinic input] +os.mknod -exit: - path_cleanup(&path); - return return_value; -} -#endif + path: path_t + mode: int=0o600 + device: dev_t=0 + * + dir_fd: dir_fd(requires='mknodat')=None + +Create a node in the file system. + +Create a node in the file system (file, device special file or named pipe) +at path. mode specifies both the permissions to use and the +type of node to be created, being combined (bitwise OR) with one of +S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode, +device defines the newly created device special file (probably using +os.makedev()). Otherwise device is ignored. + +If dir_fd is not None, it should be a file descriptor open to a directory, + and path should be relative; path will then be relative to that directory. +dir_fd may not be implemented on your platform. + If it is unavailable, using it will raise a NotImplementedError. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_mknod__doc__, +"mknod($module, /, path, mode=384, device=0, *, dir_fd=None)\n" +"--\n" +"\n" +"Create a node in the file system.\n" +"\n" +"Create a node in the file system (file, device special file or named pipe)\n" +"at path. mode specifies both the permissions to use and the\n" +"type of node to be created, being combined (bitwise OR) with one of\n" +"S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,\n" +"device defines the newly created device special file (probably using\n" +"os.makedev()). Otherwise device is ignored.\n" +"\n" +"If dir_fd is not None, it should be a file descriptor open to a directory,\n" +" and path should be relative; path will then be relative to that directory.\n" +"dir_fd may not be implemented on your platform.\n" +" If it is unavailable, using it will raise a NotImplementedError."); -#ifdef HAVE_DEVICE_MACROS -PyDoc_STRVAR(posix_major__doc__, -"major(device) -> major number\n\ -Extracts a device major number from a raw device number."); +#define OS_MKNOD_METHODDEF \ + {"mknod", (PyCFunction)os_mknod, METH_VARARGS|METH_KEYWORDS, os_mknod__doc__}, static PyObject * -posix_major(PyObject *self, PyObject *args) -{ - int device; - if (!PyArg_ParseTuple(args, "i:major", &device)) - return NULL; - return PyLong_FromLong((long)major(device)); -} - -PyDoc_STRVAR(posix_minor__doc__, -"minor(device) -> minor number\n\ -Extracts a device minor number from a raw device number."); +os_mknod_impl(PyModuleDef *module, path_t *path, int mode, dev_t device, int dir_fd); static PyObject * -posix_minor(PyObject *self, PyObject *args) +os_mknod(PyModuleDef *module, PyObject *args, PyObject *kwargs) { - int device; - if (!PyArg_ParseTuple(args, "i:minor", &device)) - return NULL; - return PyLong_FromLong((long)minor(device)); -} - -PyDoc_STRVAR(posix_makedev__doc__, -"makedev(major, minor) -> device number\n\ -Composes a raw device number from the major and minor device numbers."); + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "mode", "device", "dir_fd", NULL}; + path_t path = PATH_T_INITIALIZE("mknod", "path", 0, 0); + int mode = 384; + dev_t device = 0; + int dir_fd = DEFAULT_DIR_FD; -static PyObject * -posix_makedev(PyObject *self, PyObject *args) -{ - int major, minor; - if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor)) - return NULL; - return PyLong_FromLong((long)makedev(major, minor)); -} -#endif /* device macros */ + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&|iO&$O&:mknod", _keywords, + path_converter, &path, &mode, _Py_Dev_Converter, &device, MKNODAT_DIR_FD_CONVERTER, &dir_fd)) + goto exit; + return_value = os_mknod_impl(module, &path, mode, device, dir_fd); +exit: + /* Cleanup for path */ + path_cleanup(&path); -#ifdef HAVE_FTRUNCATE -PyDoc_STRVAR(posix_ftruncate__doc__, -"ftruncate(fd, length)\n\n\ -Truncate a file to a specified length."); + return return_value; +} static PyObject * -posix_ftruncate(PyObject *self, PyObject *args) +os_mknod_impl(PyModuleDef *module, path_t *path, int mode, dev_t device, int dir_fd) +/*[clinic end generated code: output=f71d54eaf9bb6f1a input=ee44531551a4d83b]*/ { - int fd; - off_t length; - int res; + int result; + int async_err = 0; - if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length)) - return NULL; + do { + Py_BEGIN_ALLOW_THREADS +#ifdef HAVE_MKNODAT + if (dir_fd != DEFAULT_DIR_FD) + result = mknodat(dir_fd, path->narrow, mode, device); + else +#endif + result = mknod(path->narrow, mode, device); + Py_END_ALLOW_THREADS + } while (result != 0 && errno == EINTR && + !(async_err = PyErr_CheckSignals())); + if (result != 0) + return (!async_err) ? posix_error() : NULL; - Py_BEGIN_ALLOW_THREADS - res = ftruncate(fd, length); - Py_END_ALLOW_THREADS - if (res < 0) - return posix_error(); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } -#endif +#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */ -#ifdef HAVE_TRUNCATE -PyDoc_STRVAR(posix_truncate__doc__, -"truncate(path, length)\n\n\ -Truncate the file given by path to length bytes.\n\ -On some platforms, path may also be specified as an open file descriptor.\n\ - If this functionality is unavailable, using it raises an exception."); -static PyObject * -posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs) -{ - path_t path; - off_t length; - int res; - PyObject *result = NULL; - static char *keywords[] = {"path", "length", NULL}; +#ifdef HAVE_DEVICE_MACROS +/*[clinic input] +os.major -> unsigned_int - memset(&path, 0, sizeof(path)); - path.function_name = "truncate"; -#ifdef HAVE_FTRUNCATE - path.allow_fd = 1; -#endif - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:truncate", keywords, - path_converter, &path, - _parse_off_t, &length)) - return NULL; + device: dev_t + / - Py_BEGIN_ALLOW_THREADS -#ifdef HAVE_FTRUNCATE - if (path.fd != -1) - res = ftruncate(path.fd, length); - else -#endif - res = truncate(path.narrow, length); - Py_END_ALLOW_THREADS - if (res < 0) - result = path_error(&path); - else { - Py_INCREF(Py_None); - result = Py_None; - } - path_cleanup(&path); - return result; -} -#endif +Extracts a device major number from a raw device number. +[clinic start generated code]*/ -#ifdef HAVE_POSIX_FALLOCATE -PyDoc_STRVAR(posix_posix_fallocate__doc__, -"posix_fallocate(fd, offset, len)\n\n\ -Ensures that enough disk space is allocated for the file specified by fd\n\ -starting from offset and continuing for len bytes."); +PyDoc_STRVAR(os_major__doc__, +"major($module, device, /)\n" +"--\n" +"\n" +"Extracts a device major number from a raw device number."); + +#define OS_MAJOR_METHODDEF \ + {"major", (PyCFunction)os_major, METH_VARARGS, os_major__doc__}, + +static unsigned int +os_major_impl(PyModuleDef *module, dev_t device); static PyObject * -posix_posix_fallocate(PyObject *self, PyObject *args) +os_major(PyModuleDef *module, PyObject *args) { - off_t len, offset; - int res, fd; + PyObject *return_value = NULL; + dev_t device; + unsigned int _return_value; - if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate", - &fd, _parse_off_t, &offset, _parse_off_t, &len)) - return NULL; + if (!PyArg_ParseTuple(args, + "O&:major", + _Py_Dev_Converter, &device)) + goto exit; + _return_value = os_major_impl(module, device); + if ((_return_value == (unsigned int)-1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromUnsignedLong((unsigned long)_return_value); - Py_BEGIN_ALLOW_THREADS - res = posix_fallocate(fd, offset, len); - Py_END_ALLOW_THREADS - if (res != 0) { - errno = res; - return posix_error(); - } - Py_RETURN_NONE; +exit: + return return_value; } -#endif - -#ifdef HAVE_POSIX_FADVISE -PyDoc_STRVAR(posix_posix_fadvise__doc__, -"posix_fadvise(fd, offset, len, advice)\n\n\ -Announces an intention to access data in a specific pattern thus allowing\n\ -the kernel to make optimizations.\n\ -The advice applies to the region of the file specified by fd starting at\n\ -offset and continuing for len bytes.\n\ -advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\ -POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\ -POSIX_FADV_DONTNEED."); -static PyObject * -posix_posix_fadvise(PyObject *self, PyObject *args) +static unsigned int +os_major_impl(PyModuleDef *module, dev_t device) +/*[clinic end generated code: output=a2d06e908ebf95b5 input=1e16a4d30c4d4462]*/ { - off_t len, offset; - int res, fd, advice; + return major(device); +} - if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise", - &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice)) - return NULL; - Py_BEGIN_ALLOW_THREADS - res = posix_fadvise(fd, offset, len, advice); - Py_END_ALLOW_THREADS - if (res != 0) { - errno = res; - return posix_error(); - } - Py_RETURN_NONE; -} -#endif +/*[clinic input] +os.minor -> unsigned_int -#ifdef HAVE_PUTENV -PyDoc_STRVAR(posix_putenv__doc__, -"putenv(key, value)\n\n\ -Change or add an environment variable."); + device: dev_t + / -/* Save putenv() parameters as values here, so we can collect them when they - * get re-set with another call for the same key. */ -static PyObject *posix_putenv_garbage; +Extracts a device minor number from a raw device number. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_minor__doc__, +"minor($module, device, /)\n" +"--\n" +"\n" +"Extracts a device minor number from a raw device number."); + +#define OS_MINOR_METHODDEF \ + {"minor", (PyCFunction)os_minor, METH_VARARGS, os_minor__doc__}, + +static unsigned int +os_minor_impl(PyModuleDef *module, dev_t device); static PyObject * -posix_putenv(PyObject *self, PyObject *args) +os_minor(PyModuleDef *module, PyObject *args) { - PyObject *newstr = NULL; -#ifdef MS_WINDOWS - PyObject *os1, *os2; - wchar_t *newenv; + PyObject *return_value = NULL; + dev_t device; + unsigned int _return_value; if (!PyArg_ParseTuple(args, - "UU:putenv", - &os1, &os2)) - return NULL; + "O&:minor", + _Py_Dev_Converter, &device)) + goto exit; + _return_value = os_minor_impl(module, device); + if ((_return_value == (unsigned int)-1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromUnsignedLong((unsigned long)_return_value); - newstr = PyUnicode_FromFormat("%U=%U", os1, os2); - if (newstr == NULL) { - PyErr_NoMemory(); - goto error; - } - if (_MAX_ENV < PyUnicode_GET_LENGTH(newstr)) { - PyErr_Format(PyExc_ValueError, - "the environment variable is longer than %u characters", - _MAX_ENV); - goto error; - } +exit: + return return_value; +} - newenv = PyUnicode_AsUnicode(newstr); - if (newenv == NULL) - goto error; - if (_wputenv(newenv)) { - posix_error(); - goto error; - } -#else - PyObject *os1, *os2; - char *s1, *s2; - char *newenv; +static unsigned int +os_minor_impl(PyModuleDef *module, dev_t device) +/*[clinic end generated code: output=6332287ee3f006e2 input=0842c6d23f24c65e]*/ +{ + return minor(device); +} - if (!PyArg_ParseTuple(args, - "O&O&:putenv", - PyUnicode_FSConverter, &os1, - PyUnicode_FSConverter, &os2)) - return NULL; - s1 = PyBytes_AsString(os1); - s2 = PyBytes_AsString(os2); - newstr = PyBytes_FromFormat("%s=%s", s1, s2); - if (newstr == NULL) { - PyErr_NoMemory(); - goto error; - } +/*[clinic input] +os.makedev -> dev_t - newenv = PyBytes_AS_STRING(newstr); - if (putenv(newenv)) { - posix_error(); - goto error; - } -#endif + major: int + minor: int + / - /* Install the first arg and newstr in posix_putenv_garbage; - * this will cause previous value to be collected. This has to - * happen after the real putenv() call because the old value - * was still accessible until then. */ - if (PyDict_SetItem(posix_putenv_garbage, os1, newstr)) { - /* really not much we can do; just leak */ - PyErr_Clear(); - } - else { - Py_DECREF(newstr); - } +Composes a raw device number from the major and minor device numbers. +[clinic start generated code]*/ -#ifndef MS_WINDOWS - Py_DECREF(os1); - Py_DECREF(os2); -#endif - Py_RETURN_NONE; +PyDoc_STRVAR(os_makedev__doc__, +"makedev($module, major, minor, /)\n" +"--\n" +"\n" +"Composes a raw device number from the major and minor device numbers."); -error: -#ifndef MS_WINDOWS - Py_DECREF(os1); - Py_DECREF(os2); -#endif - Py_XDECREF(newstr); - return NULL; -} -#endif /* putenv */ +#define OS_MAKEDEV_METHODDEF \ + {"makedev", (PyCFunction)os_makedev, METH_VARARGS, os_makedev__doc__}, -#ifdef HAVE_UNSETENV -PyDoc_STRVAR(posix_unsetenv__doc__, -"unsetenv(key)\n\n\ -Delete an environment variable."); +static dev_t +os_makedev_impl(PyModuleDef *module, int major, int minor); static PyObject * -posix_unsetenv(PyObject *self, PyObject *args) +os_makedev(PyModuleDef *module, PyObject *args) { - PyObject *name; -#ifndef HAVE_BROKEN_UNSETENV - int err; -#endif - - if (!PyArg_ParseTuple(args, "O&:unsetenv", - - PyUnicode_FSConverter, &name)) - return NULL; + PyObject *return_value = NULL; + int major; + int minor; + dev_t _return_value; -#ifdef HAVE_BROKEN_UNSETENV - unsetenv(PyBytes_AS_STRING(name)); -#else - err = unsetenv(PyBytes_AS_STRING(name)); - if (err) { - Py_DECREF(name); - return posix_error(); - } -#endif + if (!PyArg_ParseTuple(args, + "ii:makedev", + &major, &minor)) + goto exit; + _return_value = os_makedev_impl(module, major, minor); + if ((_return_value == (dev_t)-1) && PyErr_Occurred()) + goto exit; + return_value = _PyLong_FromDev(_return_value); - /* Remove the key from posix_putenv_garbage; - * this will cause it to be collected. This has to - * happen after the real unsetenv() call because the - * old value was still accessible until then. - */ - if (PyDict_DelItem(posix_putenv_garbage, name)) { - /* really not much we can do; just leak */ - PyErr_Clear(); - } - Py_DECREF(name); - Py_RETURN_NONE; +exit: + return return_value; } -#endif /* unsetenv */ -PyDoc_STRVAR(posix_strerror__doc__, -"strerror(code) -> string\n\n\ -Translate an error code to a message string."); - -static PyObject * -posix_strerror(PyObject *self, PyObject *args) +static dev_t +os_makedev_impl(PyModuleDef *module, int major, int minor) +/*[clinic end generated code: output=38e9a9774c96511a input=4b9fd8fc73cbe48f]*/ { - int code; - char *message; - if (!PyArg_ParseTuple(args, "i:strerror", &code)) - return NULL; - message = strerror(code); - if (message == NULL) { - PyErr_SetString(PyExc_ValueError, - "strerror() argument out of range"); - return NULL; - } - return PyUnicode_DecodeLocale(message, "surrogateescape"); + return makedev(major, minor); } +#endif /* HAVE_DEVICE_MACROS */ -#ifdef HAVE_SYS_WAIT_H +#ifdef HAVE_FTRUNCATE +/*[clinic input] +os.ftruncate -#ifdef WCOREDUMP -PyDoc_STRVAR(posix_WCOREDUMP__doc__, -"WCOREDUMP(status) -> bool\n\n\ -Return True if the process returning 'status' was dumped to a core file."); + fd: int + length: Py_off_t + / -static PyObject * -posix_WCOREDUMP(PyObject *self, PyObject *args) -{ - WAIT_TYPE status; - WAIT_STATUS_INT(status) = 0; +Truncate a file, specified by file descriptor, to a specific length. +[clinic start generated code]*/ - if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status))) - return NULL; +PyDoc_STRVAR(os_ftruncate__doc__, +"ftruncate($module, fd, length, /)\n" +"--\n" +"\n" +"Truncate a file, specified by file descriptor, to a specific length."); - return PyBool_FromLong(WCOREDUMP(status)); -} -#endif /* WCOREDUMP */ +#define OS_FTRUNCATE_METHODDEF \ + {"ftruncate", (PyCFunction)os_ftruncate, METH_VARARGS, os_ftruncate__doc__}, -#ifdef WIFCONTINUED -PyDoc_STRVAR(posix_WIFCONTINUED__doc__, -"WIFCONTINUED(status) -> bool\n\n\ -Return True if the process returning 'status' was continued from a\n\ -job control stop."); +static PyObject * +os_ftruncate_impl(PyModuleDef *module, int fd, Py_off_t length); static PyObject * -posix_WIFCONTINUED(PyObject *self, PyObject *args) +os_ftruncate(PyModuleDef *module, PyObject *args) { - WAIT_TYPE status; - WAIT_STATUS_INT(status) = 0; + PyObject *return_value = NULL; + int fd; + Py_off_t length; - if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status))) - return NULL; + if (!PyArg_ParseTuple(args, + "iO&:ftruncate", + &fd, Py_off_t_converter, &length)) + goto exit; + return_value = os_ftruncate_impl(module, fd, length); - return PyBool_FromLong(WIFCONTINUED(status)); +exit: + return return_value; } -#endif /* WIFCONTINUED */ - -#ifdef WIFSTOPPED -PyDoc_STRVAR(posix_WIFSTOPPED__doc__, -"WIFSTOPPED(status) -> bool\n\n\ -Return True if the process returning 'status' was stopped."); static PyObject * -posix_WIFSTOPPED(PyObject *self, PyObject *args) +os_ftruncate_impl(PyModuleDef *module, int fd, Py_off_t length) +/*[clinic end generated code: output=62326766cb9b76bf input=63b43641e52818f2]*/ { - WAIT_TYPE status; - WAIT_STATUS_INT(status) = 0; - - if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status))) - return NULL; + int result; + int async_err = 0; - return PyBool_FromLong(WIFSTOPPED(status)); + do { + Py_BEGIN_ALLOW_THREADS + result = ftruncate(fd, length); + Py_END_ALLOW_THREADS + } while (result != 0 && errno == EINTR && + !(async_err = PyErr_CheckSignals())); + if (result != 0) + return (!async_err) ? posix_error() : NULL; + Py_RETURN_NONE; } -#endif /* WIFSTOPPED */ +#endif /* HAVE_FTRUNCATE */ -#ifdef WIFSIGNALED -PyDoc_STRVAR(posix_WIFSIGNALED__doc__, -"WIFSIGNALED(status) -> bool\n\n\ -Return True if the process returning 'status' was terminated by a signal."); + +#ifdef HAVE_TRUNCATE +/*[clinic input] +os.truncate + path: path_t(allow_fd='PATH_HAVE_FTRUNCATE') + length: Py_off_t + +Truncate a file, specified by path, to a specific length. + +On some platforms, path may also be specified as an open file descriptor. + If this functionality is unavailable, using it raises an exception. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_truncate__doc__, +"truncate($module, /, path, length)\n" +"--\n" +"\n" +"Truncate a file, specified by path, to a specific length.\n" +"\n" +"On some platforms, path may also be specified as an open file descriptor.\n" +" If this functionality is unavailable, using it raises an exception."); + +#define OS_TRUNCATE_METHODDEF \ + {"truncate", (PyCFunction)os_truncate, METH_VARARGS|METH_KEYWORDS, os_truncate__doc__}, static PyObject * -posix_WIFSIGNALED(PyObject *self, PyObject *args) +os_truncate_impl(PyModuleDef *module, path_t *path, Py_off_t length); + +static PyObject * +os_truncate(PyModuleDef *module, PyObject *args, PyObject *kwargs) { - WAIT_TYPE status; - WAIT_STATUS_INT(status) = 0; + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "length", NULL}; + path_t path = PATH_T_INITIALIZE("truncate", "path", 0, PATH_HAVE_FTRUNCATE); + Py_off_t length; - if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status))) - return NULL; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&O&:truncate", _keywords, + path_converter, &path, Py_off_t_converter, &length)) + goto exit; + return_value = os_truncate_impl(module, &path, length); - return PyBool_FromLong(WIFSIGNALED(status)); -} -#endif /* WIFSIGNALED */ +exit: + /* Cleanup for path */ + path_cleanup(&path); -#ifdef WIFEXITED -PyDoc_STRVAR(posix_WIFEXITED__doc__, -"WIFEXITED(status) -> bool\n\n\ -Return true if the process returning 'status' exited using the exit()\n\ -system call."); + return return_value; +} static PyObject * -posix_WIFEXITED(PyObject *self, PyObject *args) +os_truncate_impl(PyModuleDef *module, path_t *path, Py_off_t length) +/*[clinic end generated code: output=6bd76262d2e027c6 input=77229cf0b50a9b77]*/ { - WAIT_TYPE status; - WAIT_STATUS_INT(status) = 0; + int result; - if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status))) - return NULL; + Py_BEGIN_ALLOW_THREADS +#ifdef HAVE_FTRUNCATE + if (path->fd != -1) + result = ftruncate(path->fd, length); + else +#endif + result = truncate(path->narrow, length); + Py_END_ALLOW_THREADS + if (result < 0) + return path_error(path); - return PyBool_FromLong(WIFEXITED(status)); + Py_RETURN_NONE; } -#endif /* WIFEXITED */ +#endif /* HAVE_TRUNCATE */ -#ifdef WEXITSTATUS -PyDoc_STRVAR(posix_WEXITSTATUS__doc__, -"WEXITSTATUS(status) -> integer\n\n\ -Return the process return code from 'status'."); + +/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise() + and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is + defined, which is the case in Python on AIX. AIX bug report: + http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */ +#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__) +# define POSIX_FADVISE_AIX_BUG +#endif + + +#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG) +/*[clinic input] +os.posix_fallocate + + fd: int + offset: Py_off_t + length: Py_off_t + / + +Ensure a file has allocated at least a particular number of bytes on disk. + +Ensure that the file specified by fd encompasses a range of bytes +starting at offset bytes from the beginning and continuing for length bytes. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_posix_fallocate__doc__, +"posix_fallocate($module, fd, offset, length, /)\n" +"--\n" +"\n" +"Ensure a file has allocated at least a particular number of bytes on disk.\n" +"\n" +"Ensure that the file specified by fd encompasses a range of bytes\n" +"starting at offset bytes from the beginning and continuing for length bytes."); + +#define OS_POSIX_FALLOCATE_METHODDEF \ + {"posix_fallocate", (PyCFunction)os_posix_fallocate, METH_VARARGS, os_posix_fallocate__doc__}, + +static PyObject * +os_posix_fallocate_impl(PyModuleDef *module, int fd, Py_off_t offset, Py_off_t length); static PyObject * -posix_WEXITSTATUS(PyObject *self, PyObject *args) +os_posix_fallocate(PyModuleDef *module, PyObject *args) { - WAIT_TYPE status; - WAIT_STATUS_INT(status) = 0; + PyObject *return_value = NULL; + int fd; + Py_off_t offset; + Py_off_t length; - if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status))) - return NULL; + if (!PyArg_ParseTuple(args, + "iO&O&:posix_fallocate", + &fd, Py_off_t_converter, &offset, Py_off_t_converter, &length)) + goto exit; + return_value = os_posix_fallocate_impl(module, fd, offset, length); - return Py_BuildValue("i", WEXITSTATUS(status)); +exit: + return return_value; } -#endif /* WEXITSTATUS */ -#ifdef WTERMSIG -PyDoc_STRVAR(posix_WTERMSIG__doc__, -"WTERMSIG(status) -> integer\n\n\ -Return the signal that terminated the process that provided the 'status'\n\ -value."); +static PyObject * +os_posix_fallocate_impl(PyModuleDef *module, int fd, Py_off_t offset, Py_off_t length) +/*[clinic end generated code: output=0cd702d2065c79db input=d7a2ef0ab2ca52fb]*/ +{ + int result; + int async_err = 0; + + do { + Py_BEGIN_ALLOW_THREADS + result = posix_fallocate(fd, offset, length); + Py_END_ALLOW_THREADS + } while (result != 0 && errno == EINTR && + !(async_err = PyErr_CheckSignals())); + if (result != 0) + return (!async_err) ? posix_error() : NULL; + Py_RETURN_NONE; +} +#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */ + + +#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG) +/*[clinic input] +os.posix_fadvise + + fd: int + offset: Py_off_t + length: Py_off_t + advice: int + / + +Announce an intention to access data in a specific pattern. + +Announce an intention to access data in a specific pattern, thus allowing +the kernel to make optimizations. +The advice applies to the region of the file specified by fd starting at +offset and continuing for length bytes. +advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL, +POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or +POSIX_FADV_DONTNEED. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_posix_fadvise__doc__, +"posix_fadvise($module, fd, offset, length, advice, /)\n" +"--\n" +"\n" +"Announce an intention to access data in a specific pattern.\n" +"\n" +"Announce an intention to access data in a specific pattern, thus allowing\n" +"the kernel to make optimizations.\n" +"The advice applies to the region of the file specified by fd starting at\n" +"offset and continuing for length bytes.\n" +"advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n" +"POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or\n" +"POSIX_FADV_DONTNEED."); + +#define OS_POSIX_FADVISE_METHODDEF \ + {"posix_fadvise", (PyCFunction)os_posix_fadvise, METH_VARARGS, os_posix_fadvise__doc__}, static PyObject * -posix_WTERMSIG(PyObject *self, PyObject *args) +os_posix_fadvise_impl(PyModuleDef *module, int fd, Py_off_t offset, Py_off_t length, int advice); + +static PyObject * +os_posix_fadvise(PyModuleDef *module, PyObject *args) { - WAIT_TYPE status; - WAIT_STATUS_INT(status) = 0; + PyObject *return_value = NULL; + int fd; + Py_off_t offset; + Py_off_t length; + int advice; - if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status))) - return NULL; + if (!PyArg_ParseTuple(args, + "iO&O&i:posix_fadvise", + &fd, Py_off_t_converter, &offset, Py_off_t_converter, &length, &advice)) + goto exit; + return_value = os_posix_fadvise_impl(module, fd, offset, length, advice); - return Py_BuildValue("i", WTERMSIG(status)); +exit: + return return_value; } -#endif /* WTERMSIG */ - -#ifdef WSTOPSIG -PyDoc_STRVAR(posix_WSTOPSIG__doc__, -"WSTOPSIG(status) -> integer\n\n\ -Return the signal that stopped the process that provided\n\ -the 'status' value."); static PyObject * -posix_WSTOPSIG(PyObject *self, PyObject *args) +os_posix_fadvise_impl(PyModuleDef *module, int fd, Py_off_t offset, Py_off_t length, int advice) +/*[clinic end generated code: output=dad93f32c04dd4f7 input=0fbe554edc2f04b5]*/ { - WAIT_TYPE status; - WAIT_STATUS_INT(status) = 0; + int result; + int async_err = 0; - if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status))) - return NULL; + do { + Py_BEGIN_ALLOW_THREADS + result = posix_fadvise(fd, offset, length, advice); + Py_END_ALLOW_THREADS + } while (result != 0 && errno == EINTR && + !(async_err = PyErr_CheckSignals())); + if (result != 0) + return (!async_err) ? posix_error() : NULL; + Py_RETURN_NONE; +} +#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */ + +#ifdef HAVE_PUTENV + +/* Save putenv() parameters as values here, so we can collect them when they + * get re-set with another call for the same key. */ +static PyObject *posix_putenv_garbage; - return Py_BuildValue("i", WSTOPSIG(status)); +static void +posix_putenv_garbage_setitem(PyObject *name, PyObject *value) +{ + /* Install the first arg and newstr in posix_putenv_garbage; + * this will cause previous value to be collected. This has to + * happen after the real putenv() call because the old value + * was still accessible until then. */ + if (PyDict_SetItem(posix_putenv_garbage, name, value)) + /* really not much we can do; just leak */ + PyErr_Clear(); + else + Py_DECREF(value); } -#endif /* WSTOPSIG */ -#endif /* HAVE_SYS_WAIT_H */ +#ifdef MS_WINDOWS +/*[clinic input] +os.putenv -#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) -#ifdef _SCO_DS -/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the - needed definitions in sys/statvfs.h */ -#define _SVID3 -#endif -#include + name: unicode + value: unicode + / -static PyObject* -_pystatvfs_fromstructstatvfs(struct statvfs st) { - PyObject *v = PyStructSequence_New(&StatVFSResultType); - if (v == NULL) - return NULL; +Change or add an environment variable. +[clinic start generated code]*/ -#if !defined(HAVE_LARGEFILE_SUPPORT) - PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize)); - PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize)); - PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks)); - PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree)); - PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail)); - PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files)); - PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree)); - PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail)); - PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag)); - PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax)); -#else - PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize)); - PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize)); - PyStructSequence_SET_ITEM(v, 2, - PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks)); - PyStructSequence_SET_ITEM(v, 3, - PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree)); - PyStructSequence_SET_ITEM(v, 4, - PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail)); - PyStructSequence_SET_ITEM(v, 5, - PyLong_FromLongLong((PY_LONG_LONG) st.f_files)); - PyStructSequence_SET_ITEM(v, 6, - PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree)); - PyStructSequence_SET_ITEM(v, 7, - PyLong_FromLongLong((PY_LONG_LONG) st.f_favail)); - PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag)); - PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax)); -#endif - if (PyErr_Occurred()) { - Py_DECREF(v); - return NULL; - } +PyDoc_STRVAR(os_putenv__doc__, +"putenv($module, name, value, /)\n" +"--\n" +"\n" +"Change or add an environment variable."); - return v; -} +#define OS_PUTENV_METHODDEF \ + {"putenv", (PyCFunction)os_putenv, METH_VARARGS, os_putenv__doc__}, -PyDoc_STRVAR(posix_fstatvfs__doc__, -"fstatvfs(fd) -> statvfs result\n\n\ -Perform an fstatvfs system call on the given fd.\n\ -Equivalent to statvfs(fd)."); +static PyObject * +os_putenv_impl(PyModuleDef *module, PyObject *name, PyObject *value); static PyObject * -posix_fstatvfs(PyObject *self, PyObject *args) +os_putenv(PyModuleDef *module, PyObject *args) { - int fd, res; - struct statvfs st; + PyObject *return_value = NULL; + PyObject *name; + PyObject *value; + + if (!PyArg_ParseTuple(args, + "UU:putenv", + &name, &value)) + goto exit; + return_value = os_putenv_impl(module, name, value); + +exit: + return return_value; +} + +static PyObject * +os_putenv_impl(PyModuleDef *module, PyObject *name, PyObject *value) +/*[clinic end generated code: output=5ce9ef9b15606e7e input=ba586581c2e6105f]*/ +{ + wchar_t *env; - if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd)) + PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value); + if (unicode == NULL) { + PyErr_NoMemory(); return NULL; - Py_BEGIN_ALLOW_THREADS - res = fstatvfs(fd, &st); - Py_END_ALLOW_THREADS - if (res != 0) - return posix_error(); + } + if (_MAX_ENV < PyUnicode_GET_LENGTH(unicode)) { + PyErr_Format(PyExc_ValueError, + "the environment variable is longer than %u characters", + _MAX_ENV); + goto error; + } - return _pystatvfs_fromstructstatvfs(st); + env = PyUnicode_AsUnicode(unicode); + if (env == NULL) + goto error; + if (_wputenv(env)) { + posix_error(); + goto error; + } + + posix_putenv_garbage_setitem(name, unicode); + Py_RETURN_NONE; + +error: + Py_DECREF(unicode); + return NULL; } -#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */ +#else /* MS_WINDOWS */ +/*[clinic input] +os.putenv + name: FSConverter + value: FSConverter + / -#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) -#include +Change or add an environment variable. +[clinic start generated code]*/ -PyDoc_STRVAR(posix_statvfs__doc__, -"statvfs(path)\n\n\ -Perform a statvfs system call on the given path.\n\ -\n\ -path may always be specified as a string.\n\ -On some platforms, path may also be specified as an open file descriptor.\n\ - If this functionality is unavailable, using it raises an exception."); +PyDoc_STRVAR(os_putenv__doc__, +"putenv($module, name, value, /)\n" +"--\n" +"\n" +"Change or add an environment variable."); + +#define OS_PUTENV_METHODDEF \ + {"putenv", (PyCFunction)os_putenv, METH_VARARGS, os_putenv__doc__}, + +static PyObject * +os_putenv_impl(PyModuleDef *module, PyObject *name, PyObject *value); static PyObject * -posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs) +os_putenv(PyModuleDef *module, PyObject *args) { - static char *keywords[] = {"path", NULL}; - path_t path; - int result; PyObject *return_value = NULL; - struct statvfs st; - - memset(&path, 0, sizeof(path)); - path.function_name = "statvfs"; -#ifdef HAVE_FSTATVFS - path.allow_fd = 1; -#endif - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:statvfs", keywords, - path_converter, &path - )) - return NULL; - - Py_BEGIN_ALLOW_THREADS -#ifdef HAVE_FSTATVFS - if (path.fd != -1) { -#ifdef __APPLE__ - /* handle weak-linking on Mac OS X 10.3 */ - if (fstatvfs == NULL) { - fd_specified("statvfs", path.fd); - goto exit; - } -#endif - result = fstatvfs(path.fd, &st); - } - else -#endif - result = statvfs(path.narrow, &st); - Py_END_ALLOW_THREADS + PyObject *name = NULL; + PyObject *value = NULL; - if (result) { - return_value = path_error(&path); + if (!PyArg_ParseTuple(args, + "O&O&:putenv", + PyUnicode_FSConverter, &name, PyUnicode_FSConverter, &value)) goto exit; - } - - return_value = _pystatvfs_fromstructstatvfs(st); + return_value = os_putenv_impl(module, name, value); exit: - path_cleanup(&path); + /* Cleanup for name */ + Py_XDECREF(name); + /* Cleanup for value */ + Py_XDECREF(value); + return return_value; } -#endif /* HAVE_STATVFS */ - -#ifdef MS_WINDOWS -PyDoc_STRVAR(win32__getdiskusage__doc__, -"_getdiskusage(path) -> (total, free)\n\n\ -Return disk usage statistics about the given path as (total, free) tuple."); static PyObject * -win32__getdiskusage(PyObject *self, PyObject *args) +os_putenv_impl(PyModuleDef *module, PyObject *name, PyObject *value) +/*[clinic end generated code: output=85ab223393dc7afd input=a97bc6152f688d31]*/ { - BOOL retval; - ULARGE_INTEGER _, total, free; - const wchar_t *path; + PyObject *bytes = NULL; + char *env; + char *name_string = PyBytes_AsString(name); + char *value_string = PyBytes_AsString(value); - if (! PyArg_ParseTuple(args, "u", &path)) + bytes = PyBytes_FromFormat("%s=%s", name_string, value_string); + if (bytes == NULL) { + PyErr_NoMemory(); return NULL; + } - Py_BEGIN_ALLOW_THREADS - retval = GetDiskFreeSpaceExW(path, &_, &total, &free); - Py_END_ALLOW_THREADS - if (retval == 0) - return PyErr_SetFromWindowsErr(0); + env = PyBytes_AS_STRING(bytes); + if (putenv(env)) { + Py_DECREF(bytes); + return posix_error(); + } - return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart); + posix_putenv_garbage_setitem(name, bytes); + Py_RETURN_NONE; } -#endif +#endif /* MS_WINDOWS */ +#endif /* HAVE_PUTENV */ -/* This is used for fpathconf(), pathconf(), confstr() and sysconf(). - * It maps strings representing configuration variable names to - * integer values, allowing those functions to be called with the - * magic names instead of polluting the module's namespace with tons of - * rarely-used constants. There are three separate tables that use - * these definitions. - * - * This code is always included, even if none of the interfaces that - * need it are included. The #if hackery needed to avoid it would be - * sufficiently pervasive that it's not worth the loss of readability. - */ -struct constdef { - char *name; - long value; -}; +#ifdef HAVE_UNSETENV +/*[clinic input] +os.unsetenv + name: FSConverter + / -static int -conv_confname(PyObject *arg, int *valuep, struct constdef *table, - size_t tablesize) -{ - if (PyLong_Check(arg)) { - *valuep = PyLong_AS_LONG(arg); - return 1; - } - else { - /* look up the value in the table using a binary search */ - size_t lo = 0; - size_t mid; - size_t hi = tablesize; - int cmp; - const char *confname; - if (!PyUnicode_Check(arg)) { - PyErr_SetString(PyExc_TypeError, - "configuration names must be strings or integers"); - return 0; - } - confname = _PyUnicode_AsString(arg); - if (confname == NULL) - return 0; - while (lo < hi) { - mid = (lo + hi) / 2; - cmp = strcmp(confname, table[mid].name); - if (cmp < 0) - hi = mid; - else if (cmp > 0) - lo = mid + 1; - else { - *valuep = table[mid].value; - return 1; - } - } - PyErr_SetString(PyExc_ValueError, "unrecognized configuration name"); - return 0; - } -} +Delete an environment variable. +[clinic start generated code]*/ +PyDoc_STRVAR(os_unsetenv__doc__, +"unsetenv($module, name, /)\n" +"--\n" +"\n" +"Delete an environment variable."); -#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF) -static struct constdef posix_constants_pathconf[] = { -#ifdef _PC_ABI_AIO_XFER_MAX - {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX}, -#endif -#ifdef _PC_ABI_ASYNC_IO - {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO}, -#endif -#ifdef _PC_ASYNC_IO - {"PC_ASYNC_IO", _PC_ASYNC_IO}, -#endif -#ifdef _PC_CHOWN_RESTRICTED - {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED}, -#endif -#ifdef _PC_FILESIZEBITS - {"PC_FILESIZEBITS", _PC_FILESIZEBITS}, -#endif -#ifdef _PC_LAST - {"PC_LAST", _PC_LAST}, -#endif -#ifdef _PC_LINK_MAX - {"PC_LINK_MAX", _PC_LINK_MAX}, -#endif -#ifdef _PC_MAX_CANON - {"PC_MAX_CANON", _PC_MAX_CANON}, -#endif -#ifdef _PC_MAX_INPUT - {"PC_MAX_INPUT", _PC_MAX_INPUT}, -#endif -#ifdef _PC_NAME_MAX - {"PC_NAME_MAX", _PC_NAME_MAX}, -#endif -#ifdef _PC_NO_TRUNC - {"PC_NO_TRUNC", _PC_NO_TRUNC}, -#endif -#ifdef _PC_PATH_MAX - {"PC_PATH_MAX", _PC_PATH_MAX}, -#endif -#ifdef _PC_PIPE_BUF - {"PC_PIPE_BUF", _PC_PIPE_BUF}, -#endif -#ifdef _PC_PRIO_IO - {"PC_PRIO_IO", _PC_PRIO_IO}, -#endif -#ifdef _PC_SOCK_MAXBUF - {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF}, -#endif -#ifdef _PC_SYNC_IO - {"PC_SYNC_IO", _PC_SYNC_IO}, -#endif -#ifdef _PC_VDISABLE - {"PC_VDISABLE", _PC_VDISABLE}, -#endif -#ifdef _PC_ACL_ENABLED - {"PC_ACL_ENABLED", _PC_ACL_ENABLED}, -#endif -#ifdef _PC_MIN_HOLE_SIZE - {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE}, -#endif -#ifdef _PC_ALLOC_SIZE_MIN - {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN}, -#endif -#ifdef _PC_REC_INCR_XFER_SIZE - {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE}, -#endif -#ifdef _PC_REC_MAX_XFER_SIZE - {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE}, -#endif -#ifdef _PC_REC_MIN_XFER_SIZE - {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE}, -#endif -#ifdef _PC_REC_XFER_ALIGN - {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN}, -#endif -#ifdef _PC_SYMLINK_MAX - {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX}, -#endif -#ifdef _PC_XATTR_ENABLED - {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED}, -#endif -#ifdef _PC_XATTR_EXISTS - {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS}, -#endif -#ifdef _PC_TIMESTAMP_RESOLUTION - {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION}, -#endif -}; +#define OS_UNSETENV_METHODDEF \ + {"unsetenv", (PyCFunction)os_unsetenv, METH_VARARGS, os_unsetenv__doc__}, -static int -conv_path_confname(PyObject *arg, int *valuep) +static PyObject * +os_unsetenv_impl(PyModuleDef *module, PyObject *name); + +static PyObject * +os_unsetenv(PyModuleDef *module, PyObject *args) { - return conv_confname(arg, valuep, posix_constants_pathconf, - sizeof(posix_constants_pathconf) - / sizeof(struct constdef)); -} -#endif + PyObject *return_value = NULL; + PyObject *name = NULL; -#ifdef HAVE_FPATHCONF -PyDoc_STRVAR(posix_fpathconf__doc__, -"fpathconf(fd, name) -> integer\n\n\ -Return the configuration limit name for the file descriptor fd.\n\ -If there is no limit, return -1."); + if (!PyArg_ParseTuple(args, + "O&:unsetenv", + PyUnicode_FSConverter, &name)) + goto exit; + return_value = os_unsetenv_impl(module, name); + +exit: + /* Cleanup for name */ + Py_XDECREF(name); + + return return_value; +} static PyObject * -posix_fpathconf(PyObject *self, PyObject *args) +os_unsetenv_impl(PyModuleDef *module, PyObject *name) +/*[clinic end generated code: output=91318c995f9a0767 input=2bb5288a599c7107]*/ { - PyObject *result = NULL; - int name, fd; +#ifndef HAVE_BROKEN_UNSETENV + int err; +#endif - if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd, - conv_path_confname, &name)) { - long limit; +#ifdef HAVE_BROKEN_UNSETENV + unsetenv(PyBytes_AS_STRING(name)); +#else + err = unsetenv(PyBytes_AS_STRING(name)); + if (err) + return posix_error(); +#endif - errno = 0; - limit = fpathconf(fd, name); - if (limit == -1 && errno != 0) - posix_error(); - else - result = PyLong_FromLong(limit); + /* Remove the key from posix_putenv_garbage; + * this will cause it to be collected. This has to + * happen after the real unsetenv() call because the + * old value was still accessible until then. + */ + if (PyDict_DelItem(posix_putenv_garbage, name)) { + /* really not much we can do; just leak */ + PyErr_Clear(); } - return result; + Py_RETURN_NONE; } -#endif +#endif /* HAVE_UNSETENV */ -#ifdef HAVE_PATHCONF -PyDoc_STRVAR(posix_pathconf__doc__, -"pathconf(path, name) -> integer\n\n\ -Return the configuration limit name for the file or directory path.\n\ -If there is no limit, return -1.\n\ -On some platforms, path may also be specified as an open file descriptor.\n\ - If this functionality is unavailable, using it raises an exception."); +/*[clinic input] +os.strerror + + code: int + / + +Translate an error code to a message string. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_strerror__doc__, +"strerror($module, code, /)\n" +"--\n" +"\n" +"Translate an error code to a message string."); + +#define OS_STRERROR_METHODDEF \ + {"strerror", (PyCFunction)os_strerror, METH_VARARGS, os_strerror__doc__}, static PyObject * -posix_pathconf(PyObject *self, PyObject *args, PyObject *kwargs) +os_strerror_impl(PyModuleDef *module, int code); + +static PyObject * +os_strerror(PyModuleDef *module, PyObject *args) { - path_t path; - PyObject *result = NULL; - int name; - static char *keywords[] = {"path", "name", NULL}; + PyObject *return_value = NULL; + int code; - memset(&path, 0, sizeof(path)); - path.function_name = "pathconf"; -#ifdef HAVE_FPATHCONF - path.allow_fd = 1; -#endif - if (PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:pathconf", keywords, - path_converter, &path, - conv_path_confname, &name)) { - long limit; + if (!PyArg_ParseTuple(args, + "i:strerror", + &code)) + goto exit; + return_value = os_strerror_impl(module, code); - errno = 0; -#ifdef HAVE_FPATHCONF - if (path.fd != -1) - limit = fpathconf(path.fd, name); - else -#endif - limit = pathconf(path.narrow, name); - if (limit == -1 && errno != 0) { - if (errno == EINVAL) - /* could be a path or name problem */ - posix_error(); - else - result = path_error(&path); - } - else - result = PyLong_FromLong(limit); +exit: + return return_value; +} + +static PyObject * +os_strerror_impl(PyModuleDef *module, int code) +/*[clinic end generated code: output=8665c70bb2ca4720 input=75a8673d97915a91]*/ +{ + char *message = strerror(code); + if (message == NULL) { + PyErr_SetString(PyExc_ValueError, + "strerror() argument out of range"); + return NULL; } - path_cleanup(&path); - return result; + return PyUnicode_DecodeLocale(message, "surrogateescape"); } -#endif -#ifdef HAVE_CONFSTR -static struct constdef posix_constants_confstr[] = { -#ifdef _CS_ARCHITECTURE - {"CS_ARCHITECTURE", _CS_ARCHITECTURE}, -#endif -#ifdef _CS_GNU_LIBC_VERSION - {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION}, -#endif -#ifdef _CS_GNU_LIBPTHREAD_VERSION - {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION}, -#endif -#ifdef _CS_HOSTNAME - {"CS_HOSTNAME", _CS_HOSTNAME}, -#endif -#ifdef _CS_HW_PROVIDER - {"CS_HW_PROVIDER", _CS_HW_PROVIDER}, -#endif -#ifdef _CS_HW_SERIAL - {"CS_HW_SERIAL", _CS_HW_SERIAL}, -#endif -#ifdef _CS_INITTAB_NAME - {"CS_INITTAB_NAME", _CS_INITTAB_NAME}, -#endif -#ifdef _CS_LFS64_CFLAGS - {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS}, -#endif -#ifdef _CS_LFS64_LDFLAGS - {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS}, -#endif -#ifdef _CS_LFS64_LIBS - {"CS_LFS64_LIBS", _CS_LFS64_LIBS}, -#endif -#ifdef _CS_LFS64_LINTFLAGS - {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS}, -#endif -#ifdef _CS_LFS_CFLAGS - {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS}, -#endif -#ifdef _CS_LFS_LDFLAGS - {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS}, -#endif -#ifdef _CS_LFS_LIBS - {"CS_LFS_LIBS", _CS_LFS_LIBS}, -#endif -#ifdef _CS_LFS_LINTFLAGS - {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS}, -#endif -#ifdef _CS_MACHINE - {"CS_MACHINE", _CS_MACHINE}, -#endif -#ifdef _CS_PATH - {"CS_PATH", _CS_PATH}, -#endif -#ifdef _CS_RELEASE - {"CS_RELEASE", _CS_RELEASE}, -#endif -#ifdef _CS_SRPC_DOMAIN - {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN}, -#endif -#ifdef _CS_SYSNAME - {"CS_SYSNAME", _CS_SYSNAME}, -#endif -#ifdef _CS_VERSION - {"CS_VERSION", _CS_VERSION}, -#endif -#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS - {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS}, -#endif -#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS - {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS}, -#endif -#ifdef _CS_XBS5_ILP32_OFF32_LIBS - {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS}, -#endif -#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS - {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS}, -#endif -#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS - {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS}, -#endif -#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS - {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS}, -#endif -#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS - {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS}, -#endif -#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS - {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS}, -#endif -#ifdef _CS_XBS5_LP64_OFF64_CFLAGS - {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS}, -#endif -#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS - {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS}, -#endif -#ifdef _CS_XBS5_LP64_OFF64_LIBS - {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS}, -#endif -#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS - {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS}, -#endif -#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS - {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS}, -#endif -#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS - {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS}, -#endif -#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS - {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS}, -#endif -#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS - {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS}, -#endif -#ifdef _MIPS_CS_AVAIL_PROCESSORS - {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS}, -#endif -#ifdef _MIPS_CS_BASE - {"MIPS_CS_BASE", _MIPS_CS_BASE}, -#endif -#ifdef _MIPS_CS_HOSTID - {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID}, -#endif -#ifdef _MIPS_CS_HW_NAME - {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME}, -#endif -#ifdef _MIPS_CS_NUM_PROCESSORS - {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS}, -#endif -#ifdef _MIPS_CS_OSREL_MAJ - {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ}, -#endif -#ifdef _MIPS_CS_OSREL_MIN - {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN}, -#endif -#ifdef _MIPS_CS_OSREL_PATCH - {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH}, -#endif -#ifdef _MIPS_CS_OS_NAME - {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME}, -#endif -#ifdef _MIPS_CS_OS_PROVIDER - {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER}, -#endif -#ifdef _MIPS_CS_PROCESSORS - {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS}, -#endif -#ifdef _MIPS_CS_SERIAL - {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL}, -#endif -#ifdef _MIPS_CS_VENDOR - {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR}, -#endif -}; + +#ifdef HAVE_SYS_WAIT_H +#ifdef WCOREDUMP +/*[clinic input] +os.WCOREDUMP -> bool + + status: int + / + +Return True if the process returning status was dumped to a core file. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_WCOREDUMP__doc__, +"WCOREDUMP($module, status, /)\n" +"--\n" +"\n" +"Return True if the process returning status was dumped to a core file."); + +#define OS_WCOREDUMP_METHODDEF \ + {"WCOREDUMP", (PyCFunction)os_WCOREDUMP, METH_VARARGS, os_WCOREDUMP__doc__}, static int -conv_confstr_confname(PyObject *arg, int *valuep) +os_WCOREDUMP_impl(PyModuleDef *module, int status); + +static PyObject * +os_WCOREDUMP(PyModuleDef *module, PyObject *args) { - return conv_confname(arg, valuep, posix_constants_confstr, - sizeof(posix_constants_confstr) - / sizeof(struct constdef)); + PyObject *return_value = NULL; + int status; + int _return_value; + + if (!PyArg_ParseTuple(args, + "i:WCOREDUMP", + &status)) + goto exit; + _return_value = os_WCOREDUMP_impl(module, status); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyBool_FromLong((long)_return_value); + +exit: + return return_value; +} + +static int +os_WCOREDUMP_impl(PyModuleDef *module, int status) +/*[clinic end generated code: output=e04d55c09c299828 input=8b05e7ab38528d04]*/ +{ + WAIT_TYPE wait_status; + WAIT_STATUS_INT(wait_status) = status; + return WCOREDUMP(wait_status); } +#endif /* WCOREDUMP */ + + +#ifdef WIFCONTINUED +/*[clinic input] +os.WIFCONTINUED -> bool + + status: int + +Return True if a particular process was continued from a job control stop. + +Return True if the process returning status was continued from a +job control stop. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_WIFCONTINUED__doc__, +"WIFCONTINUED($module, /, status)\n" +"--\n" +"\n" +"Return True if a particular process was continued from a job control stop.\n" +"\n" +"Return True if the process returning status was continued from a\n" +"job control stop."); -PyDoc_STRVAR(posix_confstr__doc__, -"confstr(name) -> string\n\n\ -Return a string-valued system configuration variable."); +#define OS_WIFCONTINUED_METHODDEF \ + {"WIFCONTINUED", (PyCFunction)os_WIFCONTINUED, METH_VARARGS|METH_KEYWORDS, os_WIFCONTINUED__doc__}, + +static int +os_WIFCONTINUED_impl(PyModuleDef *module, int status); static PyObject * -posix_confstr(PyObject *self, PyObject *args) +os_WIFCONTINUED(PyModuleDef *module, PyObject *args, PyObject *kwargs) { - PyObject *result = NULL; - int name; - char buffer[255]; - size_t len; + PyObject *return_value = NULL; + static char *_keywords[] = {"status", NULL}; + int status; + int _return_value; - if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) - return NULL; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "i:WIFCONTINUED", _keywords, + &status)) + goto exit; + _return_value = os_WIFCONTINUED_impl(module, status); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyBool_FromLong((long)_return_value); - errno = 0; - len = confstr(name, buffer, sizeof(buffer)); - if (len == 0) { - if (errno) { - posix_error(); - return NULL; - } - else { - Py_RETURN_NONE; - } - } +exit: + return return_value; +} - if (len >= sizeof(buffer)) { - char *buf = PyMem_Malloc(len); - if (buf == NULL) - return PyErr_NoMemory(); - confstr(name, buf, len); - result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1); - PyMem_Free(buf); - } - else - result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1); - return result; +static int +os_WIFCONTINUED_impl(PyModuleDef *module, int status) +/*[clinic end generated code: output=9c4e6105a4520ab5 input=e777e7d38eb25bd9]*/ +{ + WAIT_TYPE wait_status; + WAIT_STATUS_INT(wait_status) = status; + return WIFCONTINUED(wait_status); } -#endif +#endif /* WIFCONTINUED */ -#ifdef HAVE_SYSCONF -static struct constdef posix_constants_sysconf[] = { -#ifdef _SC_2_CHAR_TERM - {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM}, -#endif -#ifdef _SC_2_C_BIND - {"SC_2_C_BIND", _SC_2_C_BIND}, -#endif -#ifdef _SC_2_C_DEV - {"SC_2_C_DEV", _SC_2_C_DEV}, -#endif -#ifdef _SC_2_C_VERSION - {"SC_2_C_VERSION", _SC_2_C_VERSION}, -#endif -#ifdef _SC_2_FORT_DEV - {"SC_2_FORT_DEV", _SC_2_FORT_DEV}, -#endif -#ifdef _SC_2_FORT_RUN - {"SC_2_FORT_RUN", _SC_2_FORT_RUN}, -#endif -#ifdef _SC_2_LOCALEDEF - {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF}, -#endif -#ifdef _SC_2_SW_DEV - {"SC_2_SW_DEV", _SC_2_SW_DEV}, -#endif -#ifdef _SC_2_UPE - {"SC_2_UPE", _SC_2_UPE}, -#endif -#ifdef _SC_2_VERSION - {"SC_2_VERSION", _SC_2_VERSION}, -#endif -#ifdef _SC_ABI_ASYNCHRONOUS_IO - {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO}, -#endif -#ifdef _SC_ACL - {"SC_ACL", _SC_ACL}, -#endif -#ifdef _SC_AIO_LISTIO_MAX - {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX}, -#endif -#ifdef _SC_AIO_MAX - {"SC_AIO_MAX", _SC_AIO_MAX}, -#endif -#ifdef _SC_AIO_PRIO_DELTA_MAX - {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX}, -#endif -#ifdef _SC_ARG_MAX - {"SC_ARG_MAX", _SC_ARG_MAX}, -#endif -#ifdef _SC_ASYNCHRONOUS_IO - {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO}, -#endif -#ifdef _SC_ATEXIT_MAX - {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX}, -#endif -#ifdef _SC_AUDIT - {"SC_AUDIT", _SC_AUDIT}, -#endif -#ifdef _SC_AVPHYS_PAGES - {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES}, -#endif -#ifdef _SC_BC_BASE_MAX - {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX}, -#endif -#ifdef _SC_BC_DIM_MAX - {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX}, -#endif -#ifdef _SC_BC_SCALE_MAX - {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX}, -#endif -#ifdef _SC_BC_STRING_MAX - {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX}, -#endif -#ifdef _SC_CAP - {"SC_CAP", _SC_CAP}, -#endif -#ifdef _SC_CHARCLASS_NAME_MAX - {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX}, -#endif -#ifdef _SC_CHAR_BIT - {"SC_CHAR_BIT", _SC_CHAR_BIT}, +#ifdef WIFSTOPPED +/*[clinic input] +os.WIFSTOPPED -> bool + + status: int + +Return True if the process returning status was stopped. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_WIFSTOPPED__doc__, +"WIFSTOPPED($module, /, status)\n" +"--\n" +"\n" +"Return True if the process returning status was stopped."); + +#define OS_WIFSTOPPED_METHODDEF \ + {"WIFSTOPPED", (PyCFunction)os_WIFSTOPPED, METH_VARARGS|METH_KEYWORDS, os_WIFSTOPPED__doc__}, + +static int +os_WIFSTOPPED_impl(PyModuleDef *module, int status); + +static PyObject * +os_WIFSTOPPED(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"status", NULL}; + int status; + int _return_value; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "i:WIFSTOPPED", _keywords, + &status)) + goto exit; + _return_value = os_WIFSTOPPED_impl(module, status); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyBool_FromLong((long)_return_value); + +exit: + return return_value; +} + +static int +os_WIFSTOPPED_impl(PyModuleDef *module, int status) +/*[clinic end generated code: output=e0de2da8ec9593ff input=043cb7f1289ef904]*/ +{ + WAIT_TYPE wait_status; + WAIT_STATUS_INT(wait_status) = status; + return WIFSTOPPED(wait_status); +} +#endif /* WIFSTOPPED */ + + +#ifdef WIFSIGNALED +/*[clinic input] +os.WIFSIGNALED -> bool + + status: int + +Return True if the process returning status was terminated by a signal. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_WIFSIGNALED__doc__, +"WIFSIGNALED($module, /, status)\n" +"--\n" +"\n" +"Return True if the process returning status was terminated by a signal."); + +#define OS_WIFSIGNALED_METHODDEF \ + {"WIFSIGNALED", (PyCFunction)os_WIFSIGNALED, METH_VARARGS|METH_KEYWORDS, os_WIFSIGNALED__doc__}, + +static int +os_WIFSIGNALED_impl(PyModuleDef *module, int status); + +static PyObject * +os_WIFSIGNALED(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"status", NULL}; + int status; + int _return_value; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "i:WIFSIGNALED", _keywords, + &status)) + goto exit; + _return_value = os_WIFSIGNALED_impl(module, status); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyBool_FromLong((long)_return_value); + +exit: + return return_value; +} + +static int +os_WIFSIGNALED_impl(PyModuleDef *module, int status) +/*[clinic end generated code: output=f14d106558f406be input=d55ba7cc9ce5dc43]*/ +{ + WAIT_TYPE wait_status; + WAIT_STATUS_INT(wait_status) = status; + return WIFSIGNALED(wait_status); +} +#endif /* WIFSIGNALED */ + + +#ifdef WIFEXITED +/*[clinic input] +os.WIFEXITED -> bool + + status: int + +Return True if the process returning status exited via the exit() system call. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_WIFEXITED__doc__, +"WIFEXITED($module, /, status)\n" +"--\n" +"\n" +"Return True if the process returning status exited via the exit() system call."); + +#define OS_WIFEXITED_METHODDEF \ + {"WIFEXITED", (PyCFunction)os_WIFEXITED, METH_VARARGS|METH_KEYWORDS, os_WIFEXITED__doc__}, + +static int +os_WIFEXITED_impl(PyModuleDef *module, int status); + +static PyObject * +os_WIFEXITED(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"status", NULL}; + int status; + int _return_value; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "i:WIFEXITED", _keywords, + &status)) + goto exit; + _return_value = os_WIFEXITED_impl(module, status); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyBool_FromLong((long)_return_value); + +exit: + return return_value; +} + +static int +os_WIFEXITED_impl(PyModuleDef *module, int status) +/*[clinic end generated code: output=2f76087d53721255 input=d63775a6791586c0]*/ +{ + WAIT_TYPE wait_status; + WAIT_STATUS_INT(wait_status) = status; + return WIFEXITED(wait_status); +} +#endif /* WIFEXITED */ + + +#ifdef WEXITSTATUS +/*[clinic input] +os.WEXITSTATUS -> int + + status: int + +Return the process return code from status. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_WEXITSTATUS__doc__, +"WEXITSTATUS($module, /, status)\n" +"--\n" +"\n" +"Return the process return code from status."); + +#define OS_WEXITSTATUS_METHODDEF \ + {"WEXITSTATUS", (PyCFunction)os_WEXITSTATUS, METH_VARARGS|METH_KEYWORDS, os_WEXITSTATUS__doc__}, + +static int +os_WEXITSTATUS_impl(PyModuleDef *module, int status); + +static PyObject * +os_WEXITSTATUS(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"status", NULL}; + int status; + int _return_value; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "i:WEXITSTATUS", _keywords, + &status)) + goto exit; + _return_value = os_WEXITSTATUS_impl(module, status); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromLong((long)_return_value); + +exit: + return return_value; +} + +static int +os_WEXITSTATUS_impl(PyModuleDef *module, int status) +/*[clinic end generated code: output=13b6c270e2a326b1 input=e1fb4944e377585b]*/ +{ + WAIT_TYPE wait_status; + WAIT_STATUS_INT(wait_status) = status; + return WEXITSTATUS(wait_status); +} +#endif /* WEXITSTATUS */ + + +#ifdef WTERMSIG +/*[clinic input] +os.WTERMSIG -> int + + status: int + +Return the signal that terminated the process that provided the status value. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_WTERMSIG__doc__, +"WTERMSIG($module, /, status)\n" +"--\n" +"\n" +"Return the signal that terminated the process that provided the status value."); + +#define OS_WTERMSIG_METHODDEF \ + {"WTERMSIG", (PyCFunction)os_WTERMSIG, METH_VARARGS|METH_KEYWORDS, os_WTERMSIG__doc__}, + +static int +os_WTERMSIG_impl(PyModuleDef *module, int status); + +static PyObject * +os_WTERMSIG(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"status", NULL}; + int status; + int _return_value; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "i:WTERMSIG", _keywords, + &status)) + goto exit; + _return_value = os_WTERMSIG_impl(module, status); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromLong((long)_return_value); + +exit: + return return_value; +} + +static int +os_WTERMSIG_impl(PyModuleDef *module, int status) +/*[clinic end generated code: output=bf1fd4b002d0a9ed input=727fd7f84ec3f243]*/ +{ + WAIT_TYPE wait_status; + WAIT_STATUS_INT(wait_status) = status; + return WTERMSIG(wait_status); +} +#endif /* WTERMSIG */ + + +#ifdef WSTOPSIG +/*[clinic input] +os.WSTOPSIG -> int + + status: int + +Return the signal that stopped the process that provided the status value. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_WSTOPSIG__doc__, +"WSTOPSIG($module, /, status)\n" +"--\n" +"\n" +"Return the signal that stopped the process that provided the status value."); + +#define OS_WSTOPSIG_METHODDEF \ + {"WSTOPSIG", (PyCFunction)os_WSTOPSIG, METH_VARARGS|METH_KEYWORDS, os_WSTOPSIG__doc__}, + +static int +os_WSTOPSIG_impl(PyModuleDef *module, int status); + +static PyObject * +os_WSTOPSIG(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"status", NULL}; + int status; + int _return_value; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "i:WSTOPSIG", _keywords, + &status)) + goto exit; + _return_value = os_WSTOPSIG_impl(module, status); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromLong((long)_return_value); + +exit: + return return_value; +} + +static int +os_WSTOPSIG_impl(PyModuleDef *module, int status) +/*[clinic end generated code: output=92e1647d29ee0549 input=46ebf1d1b293c5c1]*/ +{ + WAIT_TYPE wait_status; + WAIT_STATUS_INT(wait_status) = status; + return WSTOPSIG(wait_status); +} +#endif /* WSTOPSIG */ +#endif /* HAVE_SYS_WAIT_H */ + + +#ifndef OS_WCOREDUMP_METHODDEF +#define OS_WCOREDUMP_METHODDEF +#endif /* OS_WCOREDUMP_METHODDEF */ + +#ifndef OS_WIFCONTINUED_METHODDEF +#define OS_WIFCONTINUED_METHODDEF +#endif /* OS_WIFCONTINUED_METHODDEF */ + +#ifndef OS_WIFSTOPPED_METHODDEF +#define OS_WIFSTOPPED_METHODDEF +#endif /* OS_WIFSTOPPED_METHODDEF */ + +#ifndef OS_WIFSIGNALED_METHODDEF +#define OS_WIFSIGNALED_METHODDEF +#endif /* OS_WIFSIGNALED_METHODDEF */ + +#ifndef OS_WIFEXITED_METHODDEF +#define OS_WIFEXITED_METHODDEF +#endif /* OS_WIFEXITED_METHODDEF */ + +#ifndef OS_WEXITSTATUS_METHODDEF +#define OS_WEXITSTATUS_METHODDEF +#endif /* OS_WEXITSTATUS_METHODDEF */ + +#ifndef OS_WTERMSIG_METHODDEF +#define OS_WTERMSIG_METHODDEF +#endif /* OS_WTERMSIG_METHODDEF */ + +#ifndef OS_WSTOPSIG_METHODDEF +#define OS_WSTOPSIG_METHODDEF +#endif /* OS_WSTOPSIG_METHODDEF */ + + +#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) +#ifdef _SCO_DS +/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the + needed definitions in sys/statvfs.h */ +#define _SVID3 #endif -#ifdef _SC_CHAR_MAX - {"SC_CHAR_MAX", _SC_CHAR_MAX}, +#include + +static PyObject* +_pystatvfs_fromstructstatvfs(struct statvfs st) { + PyObject *v = PyStructSequence_New(&StatVFSResultType); + if (v == NULL) + return NULL; + +#if !defined(HAVE_LARGEFILE_SUPPORT) + PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize)); + PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize)); + PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks)); + PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree)); + PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail)); + PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files)); + PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree)); + PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail)); + PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag)); + PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax)); +#else + PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize)); + PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize)); + PyStructSequence_SET_ITEM(v, 2, + PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks)); + PyStructSequence_SET_ITEM(v, 3, + PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree)); + PyStructSequence_SET_ITEM(v, 4, + PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail)); + PyStructSequence_SET_ITEM(v, 5, + PyLong_FromLongLong((PY_LONG_LONG) st.f_files)); + PyStructSequence_SET_ITEM(v, 6, + PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree)); + PyStructSequence_SET_ITEM(v, 7, + PyLong_FromLongLong((PY_LONG_LONG) st.f_favail)); + PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag)); + PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax)); #endif -#ifdef _SC_CHAR_MIN - {"SC_CHAR_MIN", _SC_CHAR_MIN}, + if (PyErr_Occurred()) { + Py_DECREF(v); + return NULL; + } + + return v; +} + + +/*[clinic input] +os.fstatvfs + fd: int + / + +Perform an fstatvfs system call on the given fd. + +Equivalent to statvfs(fd). +[clinic start generated code]*/ + +PyDoc_STRVAR(os_fstatvfs__doc__, +"fstatvfs($module, fd, /)\n" +"--\n" +"\n" +"Perform an fstatvfs system call on the given fd.\n" +"\n" +"Equivalent to statvfs(fd)."); + +#define OS_FSTATVFS_METHODDEF \ + {"fstatvfs", (PyCFunction)os_fstatvfs, METH_VARARGS, os_fstatvfs__doc__}, + +static PyObject * +os_fstatvfs_impl(PyModuleDef *module, int fd); + +static PyObject * +os_fstatvfs(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd; + + if (!PyArg_ParseTuple(args, + "i:fstatvfs", + &fd)) + goto exit; + return_value = os_fstatvfs_impl(module, fd); + +exit: + return return_value; +} + +static PyObject * +os_fstatvfs_impl(PyModuleDef *module, int fd) +/*[clinic end generated code: output=0e32bf07f946ec0d input=d8122243ac50975e]*/ +{ + int result; + int async_err = 0; + struct statvfs st; + + do { + Py_BEGIN_ALLOW_THREADS + result = fstatvfs(fd, &st); + Py_END_ALLOW_THREADS + } while (result != 0 && errno == EINTR && + !(async_err = PyErr_CheckSignals())); + if (result != 0) + return (!async_err) ? posix_error() : NULL; + + return _pystatvfs_fromstructstatvfs(st); +} +#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */ + + +#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) +#include +/*[clinic input] +os.statvfs + + path: path_t(allow_fd='PATH_HAVE_FSTATVFS') + +Perform a statvfs system call on the given path. + +path may always be specified as a string. +On some platforms, path may also be specified as an open file descriptor. + If this functionality is unavailable, using it raises an exception. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_statvfs__doc__, +"statvfs($module, /, path)\n" +"--\n" +"\n" +"Perform a statvfs system call on the given path.\n" +"\n" +"path may always be specified as a string.\n" +"On some platforms, path may also be specified as an open file descriptor.\n" +" If this functionality is unavailable, using it raises an exception."); + +#define OS_STATVFS_METHODDEF \ + {"statvfs", (PyCFunction)os_statvfs, METH_VARARGS|METH_KEYWORDS, os_statvfs__doc__}, + +static PyObject * +os_statvfs_impl(PyModuleDef *module, path_t *path); + +static PyObject * +os_statvfs(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", NULL}; + path_t path = PATH_T_INITIALIZE("statvfs", "path", 0, PATH_HAVE_FSTATVFS); + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&:statvfs", _keywords, + path_converter, &path)) + goto exit; + return_value = os_statvfs_impl(module, &path); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +static PyObject * +os_statvfs_impl(PyModuleDef *module, path_t *path) +/*[clinic end generated code: output=00ff54983360b446 input=3f5c35791c669bd9]*/ +{ + int result; + struct statvfs st; + + Py_BEGIN_ALLOW_THREADS +#ifdef HAVE_FSTATVFS + if (path->fd != -1) { +#ifdef __APPLE__ + /* handle weak-linking on Mac OS X 10.3 */ + if (fstatvfs == NULL) { + fd_specified("statvfs", path->fd); + return NULL; + } #endif -#ifdef _SC_CHILD_MAX - {"SC_CHILD_MAX", _SC_CHILD_MAX}, + result = fstatvfs(path->fd, &st); + } + else #endif -#ifdef _SC_CLK_TCK - {"SC_CLK_TCK", _SC_CLK_TCK}, + result = statvfs(path->narrow, &st); + Py_END_ALLOW_THREADS + + if (result) { + return path_error(path); + } + + return _pystatvfs_fromstructstatvfs(st); +} +#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */ + + +#ifdef MS_WINDOWS +/*[clinic input] +os._getdiskusage + + path: Py_UNICODE + +Return disk usage statistics about the given path as a (total, free) tuple. +[clinic start generated code]*/ + +PyDoc_STRVAR(os__getdiskusage__doc__, +"_getdiskusage($module, /, path)\n" +"--\n" +"\n" +"Return disk usage statistics about the given path as a (total, free) tuple."); + +#define OS__GETDISKUSAGE_METHODDEF \ + {"_getdiskusage", (PyCFunction)os__getdiskusage, METH_VARARGS|METH_KEYWORDS, os__getdiskusage__doc__}, + +static PyObject * +os__getdiskusage_impl(PyModuleDef *module, Py_UNICODE *path); + +static PyObject * +os__getdiskusage(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", NULL}; + Py_UNICODE *path; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "u:_getdiskusage", _keywords, + &path)) + goto exit; + return_value = os__getdiskusage_impl(module, path); + +exit: + return return_value; +} + +static PyObject * +os__getdiskusage_impl(PyModuleDef *module, Py_UNICODE *path) +/*[clinic end generated code: output=054c972179b13708 input=6458133aed893c78]*/ +{ + BOOL retval; + ULARGE_INTEGER _, total, free; + + Py_BEGIN_ALLOW_THREADS + retval = GetDiskFreeSpaceExW(path, &_, &total, &free); + Py_END_ALLOW_THREADS + if (retval == 0) + return PyErr_SetFromWindowsErr(0); + + return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart); +} +#endif /* MS_WINDOWS */ + + +/* This is used for fpathconf(), pathconf(), confstr() and sysconf(). + * It maps strings representing configuration variable names to + * integer values, allowing those functions to be called with the + * magic names instead of polluting the module's namespace with tons of + * rarely-used constants. There are three separate tables that use + * these definitions. + * + * This code is always included, even if none of the interfaces that + * need it are included. The #if hackery needed to avoid it would be + * sufficiently pervasive that it's not worth the loss of readability. + */ +struct constdef { + char *name; + long value; +}; + +static int +conv_confname(PyObject *arg, int *valuep, struct constdef *table, + size_t tablesize) +{ + if (PyLong_Check(arg)) { + *valuep = PyLong_AS_LONG(arg); + return 1; + } + else { + /* look up the value in the table using a binary search */ + size_t lo = 0; + size_t mid; + size_t hi = tablesize; + int cmp; + const char *confname; + if (!PyUnicode_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "configuration names must be strings or integers"); + return 0; + } + confname = _PyUnicode_AsString(arg); + if (confname == NULL) + return 0; + while (lo < hi) { + mid = (lo + hi) / 2; + cmp = strcmp(confname, table[mid].name); + if (cmp < 0) + hi = mid; + else if (cmp > 0) + lo = mid + 1; + else { + *valuep = table[mid].value; + return 1; + } + } + PyErr_SetString(PyExc_ValueError, "unrecognized configuration name"); + return 0; + } +} + + +#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF) +static struct constdef posix_constants_pathconf[] = { +#ifdef _PC_ABI_AIO_XFER_MAX + {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX}, #endif -#ifdef _SC_COHER_BLKSZ - {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ}, +#ifdef _PC_ABI_ASYNC_IO + {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO}, #endif -#ifdef _SC_COLL_WEIGHTS_MAX - {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX}, +#ifdef _PC_ASYNC_IO + {"PC_ASYNC_IO", _PC_ASYNC_IO}, #endif -#ifdef _SC_DCACHE_ASSOC - {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC}, +#ifdef _PC_CHOWN_RESTRICTED + {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED}, #endif -#ifdef _SC_DCACHE_BLKSZ - {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ}, +#ifdef _PC_FILESIZEBITS + {"PC_FILESIZEBITS", _PC_FILESIZEBITS}, #endif -#ifdef _SC_DCACHE_LINESZ - {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ}, +#ifdef _PC_LAST + {"PC_LAST", _PC_LAST}, #endif -#ifdef _SC_DCACHE_SZ - {"SC_DCACHE_SZ", _SC_DCACHE_SZ}, +#ifdef _PC_LINK_MAX + {"PC_LINK_MAX", _PC_LINK_MAX}, #endif -#ifdef _SC_DCACHE_TBLKSZ - {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ}, +#ifdef _PC_MAX_CANON + {"PC_MAX_CANON", _PC_MAX_CANON}, #endif -#ifdef _SC_DELAYTIMER_MAX - {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX}, +#ifdef _PC_MAX_INPUT + {"PC_MAX_INPUT", _PC_MAX_INPUT}, #endif -#ifdef _SC_EQUIV_CLASS_MAX - {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX}, +#ifdef _PC_NAME_MAX + {"PC_NAME_MAX", _PC_NAME_MAX}, #endif -#ifdef _SC_EXPR_NEST_MAX - {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX}, +#ifdef _PC_NO_TRUNC + {"PC_NO_TRUNC", _PC_NO_TRUNC}, #endif -#ifdef _SC_FSYNC - {"SC_FSYNC", _SC_FSYNC}, +#ifdef _PC_PATH_MAX + {"PC_PATH_MAX", _PC_PATH_MAX}, #endif -#ifdef _SC_GETGR_R_SIZE_MAX - {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX}, +#ifdef _PC_PIPE_BUF + {"PC_PIPE_BUF", _PC_PIPE_BUF}, #endif -#ifdef _SC_GETPW_R_SIZE_MAX - {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX}, +#ifdef _PC_PRIO_IO + {"PC_PRIO_IO", _PC_PRIO_IO}, #endif -#ifdef _SC_ICACHE_ASSOC - {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC}, +#ifdef _PC_SOCK_MAXBUF + {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF}, #endif -#ifdef _SC_ICACHE_BLKSZ - {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ}, -#endif -#ifdef _SC_ICACHE_LINESZ - {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ}, +#ifdef _PC_SYNC_IO + {"PC_SYNC_IO", _PC_SYNC_IO}, #endif -#ifdef _SC_ICACHE_SZ - {"SC_ICACHE_SZ", _SC_ICACHE_SZ}, +#ifdef _PC_VDISABLE + {"PC_VDISABLE", _PC_VDISABLE}, #endif -#ifdef _SC_INF - {"SC_INF", _SC_INF}, +#ifdef _PC_ACL_ENABLED + {"PC_ACL_ENABLED", _PC_ACL_ENABLED}, #endif -#ifdef _SC_INT_MAX - {"SC_INT_MAX", _SC_INT_MAX}, +#ifdef _PC_MIN_HOLE_SIZE + {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE}, #endif -#ifdef _SC_INT_MIN - {"SC_INT_MIN", _SC_INT_MIN}, +#ifdef _PC_ALLOC_SIZE_MIN + {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN}, #endif -#ifdef _SC_IOV_MAX - {"SC_IOV_MAX", _SC_IOV_MAX}, +#ifdef _PC_REC_INCR_XFER_SIZE + {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE}, #endif -#ifdef _SC_IP_SECOPTS - {"SC_IP_SECOPTS", _SC_IP_SECOPTS}, +#ifdef _PC_REC_MAX_XFER_SIZE + {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE}, #endif -#ifdef _SC_JOB_CONTROL - {"SC_JOB_CONTROL", _SC_JOB_CONTROL}, +#ifdef _PC_REC_MIN_XFER_SIZE + {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE}, #endif -#ifdef _SC_KERN_POINTERS - {"SC_KERN_POINTERS", _SC_KERN_POINTERS}, +#ifdef _PC_REC_XFER_ALIGN + {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN}, #endif -#ifdef _SC_KERN_SIM - {"SC_KERN_SIM", _SC_KERN_SIM}, +#ifdef _PC_SYMLINK_MAX + {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX}, #endif -#ifdef _SC_LINE_MAX - {"SC_LINE_MAX", _SC_LINE_MAX}, +#ifdef _PC_XATTR_ENABLED + {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED}, #endif -#ifdef _SC_LOGIN_NAME_MAX - {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX}, +#ifdef _PC_XATTR_EXISTS + {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS}, #endif -#ifdef _SC_LOGNAME_MAX - {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX}, +#ifdef _PC_TIMESTAMP_RESOLUTION + {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION}, #endif -#ifdef _SC_LONG_BIT - {"SC_LONG_BIT", _SC_LONG_BIT}, +}; + +static int +conv_path_confname(PyObject *arg, int *valuep) +{ + return conv_confname(arg, valuep, posix_constants_pathconf, + sizeof(posix_constants_pathconf) + / sizeof(struct constdef)); +} #endif -#ifdef _SC_MAC - {"SC_MAC", _SC_MAC}, + + +#ifdef HAVE_FPATHCONF +/*[clinic input] +os.fpathconf -> long + + fd: int + name: path_confname + / + +Return the configuration limit name for the file descriptor fd. + +If there is no limit, return -1. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_fpathconf__doc__, +"fpathconf($module, fd, name, /)\n" +"--\n" +"\n" +"Return the configuration limit name for the file descriptor fd.\n" +"\n" +"If there is no limit, return -1."); + +#define OS_FPATHCONF_METHODDEF \ + {"fpathconf", (PyCFunction)os_fpathconf, METH_VARARGS, os_fpathconf__doc__}, + +static long +os_fpathconf_impl(PyModuleDef *module, int fd, int name); + +static PyObject * +os_fpathconf(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd; + int name; + long _return_value; + + if (!PyArg_ParseTuple(args, + "iO&:fpathconf", + &fd, conv_path_confname, &name)) + goto exit; + _return_value = os_fpathconf_impl(module, fd, name); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromLong(_return_value); + +exit: + return return_value; +} + +static long +os_fpathconf_impl(PyModuleDef *module, int fd, int name) +/*[clinic end generated code: output=3bf04b40e0523a8c input=5942a024d3777810]*/ +{ + long limit; + + errno = 0; + limit = fpathconf(fd, name); + if (limit == -1 && errno != 0) + posix_error(); + + return limit; +} +#endif /* HAVE_FPATHCONF */ + + +#ifdef HAVE_PATHCONF +/*[clinic input] +os.pathconf -> long + path: path_t(allow_fd='PATH_HAVE_FPATHCONF') + name: path_confname + +Return the configuration limit name for the file or directory path. + +If there is no limit, return -1. +On some platforms, path may also be specified as an open file descriptor. + If this functionality is unavailable, using it raises an exception. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_pathconf__doc__, +"pathconf($module, /, path, name)\n" +"--\n" +"\n" +"Return the configuration limit name for the file or directory path.\n" +"\n" +"If there is no limit, return -1.\n" +"On some platforms, path may also be specified as an open file descriptor.\n" +" If this functionality is unavailable, using it raises an exception."); + +#define OS_PATHCONF_METHODDEF \ + {"pathconf", (PyCFunction)os_pathconf, METH_VARARGS|METH_KEYWORDS, os_pathconf__doc__}, + +static long +os_pathconf_impl(PyModuleDef *module, path_t *path, int name); + +static PyObject * +os_pathconf(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "name", NULL}; + path_t path = PATH_T_INITIALIZE("pathconf", "path", 0, PATH_HAVE_FPATHCONF); + int name; + long _return_value; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&O&:pathconf", _keywords, + path_converter, &path, conv_path_confname, &name)) + goto exit; + _return_value = os_pathconf_impl(module, &path, name); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromLong(_return_value); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +static long +os_pathconf_impl(PyModuleDef *module, path_t *path, int name) +/*[clinic end generated code: output=1a53e125b6cf63e4 input=bc3e2a985af27e5e]*/ +{ + long limit; + + errno = 0; +#ifdef HAVE_FPATHCONF + if (path->fd != -1) + limit = fpathconf(path->fd, name); + else #endif -#ifdef _SC_MAPPED_FILES - {"SC_MAPPED_FILES", _SC_MAPPED_FILES}, + limit = pathconf(path->narrow, name); + if (limit == -1 && errno != 0) { + if (errno == EINVAL) + /* could be a path or name problem */ + posix_error(); + else + path_error(path); + } + + return limit; +} +#endif /* HAVE_PATHCONF */ + +#ifdef HAVE_CONFSTR +static struct constdef posix_constants_confstr[] = { +#ifdef _CS_ARCHITECTURE + {"CS_ARCHITECTURE", _CS_ARCHITECTURE}, #endif -#ifdef _SC_MAXPID - {"SC_MAXPID", _SC_MAXPID}, +#ifdef _CS_GNU_LIBC_VERSION + {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION}, #endif -#ifdef _SC_MB_LEN_MAX - {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX}, +#ifdef _CS_GNU_LIBPTHREAD_VERSION + {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION}, #endif -#ifdef _SC_MEMLOCK - {"SC_MEMLOCK", _SC_MEMLOCK}, +#ifdef _CS_HOSTNAME + {"CS_HOSTNAME", _CS_HOSTNAME}, #endif -#ifdef _SC_MEMLOCK_RANGE - {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE}, +#ifdef _CS_HW_PROVIDER + {"CS_HW_PROVIDER", _CS_HW_PROVIDER}, #endif -#ifdef _SC_MEMORY_PROTECTION - {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION}, +#ifdef _CS_HW_SERIAL + {"CS_HW_SERIAL", _CS_HW_SERIAL}, #endif -#ifdef _SC_MESSAGE_PASSING - {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING}, +#ifdef _CS_INITTAB_NAME + {"CS_INITTAB_NAME", _CS_INITTAB_NAME}, #endif -#ifdef _SC_MMAP_FIXED_ALIGNMENT - {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT}, +#ifdef _CS_LFS64_CFLAGS + {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS}, #endif -#ifdef _SC_MQ_OPEN_MAX - {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX}, +#ifdef _CS_LFS64_LDFLAGS + {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS}, #endif -#ifdef _SC_MQ_PRIO_MAX - {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX}, +#ifdef _CS_LFS64_LIBS + {"CS_LFS64_LIBS", _CS_LFS64_LIBS}, #endif -#ifdef _SC_NACLS_MAX - {"SC_NACLS_MAX", _SC_NACLS_MAX}, +#ifdef _CS_LFS64_LINTFLAGS + {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS}, #endif -#ifdef _SC_NGROUPS_MAX - {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX}, +#ifdef _CS_LFS_CFLAGS + {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS}, #endif -#ifdef _SC_NL_ARGMAX - {"SC_NL_ARGMAX", _SC_NL_ARGMAX}, +#ifdef _CS_LFS_LDFLAGS + {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS}, #endif -#ifdef _SC_NL_LANGMAX - {"SC_NL_LANGMAX", _SC_NL_LANGMAX}, +#ifdef _CS_LFS_LIBS + {"CS_LFS_LIBS", _CS_LFS_LIBS}, #endif -#ifdef _SC_NL_MSGMAX - {"SC_NL_MSGMAX", _SC_NL_MSGMAX}, +#ifdef _CS_LFS_LINTFLAGS + {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS}, #endif -#ifdef _SC_NL_NMAX - {"SC_NL_NMAX", _SC_NL_NMAX}, +#ifdef _CS_MACHINE + {"CS_MACHINE", _CS_MACHINE}, #endif -#ifdef _SC_NL_SETMAX - {"SC_NL_SETMAX", _SC_NL_SETMAX}, +#ifdef _CS_PATH + {"CS_PATH", _CS_PATH}, #endif -#ifdef _SC_NL_TEXTMAX - {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX}, +#ifdef _CS_RELEASE + {"CS_RELEASE", _CS_RELEASE}, #endif -#ifdef _SC_NPROCESSORS_CONF - {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF}, +#ifdef _CS_SRPC_DOMAIN + {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN}, #endif -#ifdef _SC_NPROCESSORS_ONLN - {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN}, +#ifdef _CS_SYSNAME + {"CS_SYSNAME", _CS_SYSNAME}, #endif -#ifdef _SC_NPROC_CONF - {"SC_NPROC_CONF", _SC_NPROC_CONF}, +#ifdef _CS_VERSION + {"CS_VERSION", _CS_VERSION}, #endif -#ifdef _SC_NPROC_ONLN - {"SC_NPROC_ONLN", _SC_NPROC_ONLN}, +#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS + {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS}, #endif -#ifdef _SC_NZERO - {"SC_NZERO", _SC_NZERO}, +#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS + {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS}, #endif -#ifdef _SC_OPEN_MAX - {"SC_OPEN_MAX", _SC_OPEN_MAX}, +#ifdef _CS_XBS5_ILP32_OFF32_LIBS + {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS}, #endif -#ifdef _SC_PAGESIZE - {"SC_PAGESIZE", _SC_PAGESIZE}, +#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS + {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS}, #endif -#ifdef _SC_PAGE_SIZE - {"SC_PAGE_SIZE", _SC_PAGE_SIZE}, +#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS + {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS}, #endif -#ifdef _SC_PASS_MAX - {"SC_PASS_MAX", _SC_PASS_MAX}, +#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS + {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS}, #endif -#ifdef _SC_PHYS_PAGES - {"SC_PHYS_PAGES", _SC_PHYS_PAGES}, -#endif -#ifdef _SC_PII - {"SC_PII", _SC_PII}, +#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS + {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS}, #endif -#ifdef _SC_PII_INTERNET - {"SC_PII_INTERNET", _SC_PII_INTERNET}, +#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS + {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS}, #endif -#ifdef _SC_PII_INTERNET_DGRAM - {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM}, +#ifdef _CS_XBS5_LP64_OFF64_CFLAGS + {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS}, #endif -#ifdef _SC_PII_INTERNET_STREAM - {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM}, +#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS + {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS}, #endif -#ifdef _SC_PII_OSI - {"SC_PII_OSI", _SC_PII_OSI}, +#ifdef _CS_XBS5_LP64_OFF64_LIBS + {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS}, #endif -#ifdef _SC_PII_OSI_CLTS - {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS}, +#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS + {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS}, #endif -#ifdef _SC_PII_OSI_COTS - {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS}, +#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS + {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS}, #endif -#ifdef _SC_PII_OSI_M - {"SC_PII_OSI_M", _SC_PII_OSI_M}, +#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS + {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS}, #endif -#ifdef _SC_PII_SOCKET - {"SC_PII_SOCKET", _SC_PII_SOCKET}, +#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS + {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS}, #endif -#ifdef _SC_PII_XTI - {"SC_PII_XTI", _SC_PII_XTI}, +#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS + {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS}, #endif -#ifdef _SC_POLL - {"SC_POLL", _SC_POLL}, +#ifdef _MIPS_CS_AVAIL_PROCESSORS + {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS}, #endif -#ifdef _SC_PRIORITIZED_IO - {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO}, +#ifdef _MIPS_CS_BASE + {"MIPS_CS_BASE", _MIPS_CS_BASE}, #endif -#ifdef _SC_PRIORITY_SCHEDULING - {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING}, +#ifdef _MIPS_CS_HOSTID + {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID}, #endif -#ifdef _SC_REALTIME_SIGNALS - {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS}, +#ifdef _MIPS_CS_HW_NAME + {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME}, #endif -#ifdef _SC_RE_DUP_MAX - {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX}, +#ifdef _MIPS_CS_NUM_PROCESSORS + {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS}, #endif -#ifdef _SC_RTSIG_MAX - {"SC_RTSIG_MAX", _SC_RTSIG_MAX}, +#ifdef _MIPS_CS_OSREL_MAJ + {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ}, #endif -#ifdef _SC_SAVED_IDS - {"SC_SAVED_IDS", _SC_SAVED_IDS}, +#ifdef _MIPS_CS_OSREL_MIN + {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN}, #endif -#ifdef _SC_SCHAR_MAX - {"SC_SCHAR_MAX", _SC_SCHAR_MAX}, +#ifdef _MIPS_CS_OSREL_PATCH + {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH}, #endif -#ifdef _SC_SCHAR_MIN - {"SC_SCHAR_MIN", _SC_SCHAR_MIN}, +#ifdef _MIPS_CS_OS_NAME + {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME}, #endif -#ifdef _SC_SELECT - {"SC_SELECT", _SC_SELECT}, +#ifdef _MIPS_CS_OS_PROVIDER + {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER}, #endif -#ifdef _SC_SEMAPHORES - {"SC_SEMAPHORES", _SC_SEMAPHORES}, +#ifdef _MIPS_CS_PROCESSORS + {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS}, #endif -#ifdef _SC_SEM_NSEMS_MAX - {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX}, +#ifdef _MIPS_CS_SERIAL + {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL}, #endif -#ifdef _SC_SEM_VALUE_MAX - {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX}, +#ifdef _MIPS_CS_VENDOR + {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR}, #endif -#ifdef _SC_SHARED_MEMORY_OBJECTS - {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS}, +}; + +static int +conv_confstr_confname(PyObject *arg, int *valuep) +{ + return conv_confname(arg, valuep, posix_constants_confstr, + sizeof(posix_constants_confstr) + / sizeof(struct constdef)); +} + + +/*[clinic input] +os.confstr + + name: confstr_confname + / + +Return a string-valued system configuration variable. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_confstr__doc__, +"confstr($module, name, /)\n" +"--\n" +"\n" +"Return a string-valued system configuration variable."); + +#define OS_CONFSTR_METHODDEF \ + {"confstr", (PyCFunction)os_confstr, METH_VARARGS, os_confstr__doc__}, + +static PyObject * +os_confstr_impl(PyModuleDef *module, int name); + +static PyObject * +os_confstr(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int name; + + if (!PyArg_ParseTuple(args, + "O&:confstr", + conv_confstr_confname, &name)) + goto exit; + return_value = os_confstr_impl(module, name); + +exit: + return return_value; +} + +static PyObject * +os_confstr_impl(PyModuleDef *module, int name) +/*[clinic end generated code: output=3f5e8aba9f8e3174 input=18fb4d0567242e65]*/ +{ + PyObject *result = NULL; + char buffer[255]; + size_t len; + + errno = 0; + len = confstr(name, buffer, sizeof(buffer)); + if (len == 0) { + if (errno) { + posix_error(); + return NULL; + } + else { + Py_RETURN_NONE; + } + } + + if (len >= sizeof(buffer)) { + size_t len2; + char *buf = PyMem_Malloc(len); + if (buf == NULL) + return PyErr_NoMemory(); + len2 = confstr(name, buf, len); + assert(len == len2); + result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1); + PyMem_Free(buf); + } + else + result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1); + return result; +} +#endif /* HAVE_CONFSTR */ + + +#ifdef HAVE_SYSCONF +static struct constdef posix_constants_sysconf[] = { +#ifdef _SC_2_CHAR_TERM + {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM}, #endif -#ifdef _SC_SHRT_MAX - {"SC_SHRT_MAX", _SC_SHRT_MAX}, +#ifdef _SC_2_C_BIND + {"SC_2_C_BIND", _SC_2_C_BIND}, #endif -#ifdef _SC_SHRT_MIN - {"SC_SHRT_MIN", _SC_SHRT_MIN}, +#ifdef _SC_2_C_DEV + {"SC_2_C_DEV", _SC_2_C_DEV}, #endif -#ifdef _SC_SIGQUEUE_MAX - {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX}, +#ifdef _SC_2_C_VERSION + {"SC_2_C_VERSION", _SC_2_C_VERSION}, #endif -#ifdef _SC_SIGRT_MAX - {"SC_SIGRT_MAX", _SC_SIGRT_MAX}, +#ifdef _SC_2_FORT_DEV + {"SC_2_FORT_DEV", _SC_2_FORT_DEV}, #endif -#ifdef _SC_SIGRT_MIN - {"SC_SIGRT_MIN", _SC_SIGRT_MIN}, +#ifdef _SC_2_FORT_RUN + {"SC_2_FORT_RUN", _SC_2_FORT_RUN}, #endif -#ifdef _SC_SOFTPOWER - {"SC_SOFTPOWER", _SC_SOFTPOWER}, +#ifdef _SC_2_LOCALEDEF + {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF}, #endif -#ifdef _SC_SPLIT_CACHE - {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE}, +#ifdef _SC_2_SW_DEV + {"SC_2_SW_DEV", _SC_2_SW_DEV}, #endif -#ifdef _SC_SSIZE_MAX - {"SC_SSIZE_MAX", _SC_SSIZE_MAX}, +#ifdef _SC_2_UPE + {"SC_2_UPE", _SC_2_UPE}, #endif -#ifdef _SC_STACK_PROT - {"SC_STACK_PROT", _SC_STACK_PROT}, +#ifdef _SC_2_VERSION + {"SC_2_VERSION", _SC_2_VERSION}, #endif -#ifdef _SC_STREAM_MAX - {"SC_STREAM_MAX", _SC_STREAM_MAX}, +#ifdef _SC_ABI_ASYNCHRONOUS_IO + {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO}, #endif -#ifdef _SC_SYNCHRONIZED_IO - {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO}, +#ifdef _SC_ACL + {"SC_ACL", _SC_ACL}, #endif -#ifdef _SC_THREADS - {"SC_THREADS", _SC_THREADS}, +#ifdef _SC_AIO_LISTIO_MAX + {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX}, #endif -#ifdef _SC_THREAD_ATTR_STACKADDR - {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR}, +#ifdef _SC_AIO_MAX + {"SC_AIO_MAX", _SC_AIO_MAX}, #endif -#ifdef _SC_THREAD_ATTR_STACKSIZE - {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE}, +#ifdef _SC_AIO_PRIO_DELTA_MAX + {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX}, #endif -#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS - {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS}, +#ifdef _SC_ARG_MAX + {"SC_ARG_MAX", _SC_ARG_MAX}, #endif -#ifdef _SC_THREAD_KEYS_MAX - {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX}, +#ifdef _SC_ASYNCHRONOUS_IO + {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO}, #endif -#ifdef _SC_THREAD_PRIORITY_SCHEDULING - {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING}, +#ifdef _SC_ATEXIT_MAX + {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX}, #endif -#ifdef _SC_THREAD_PRIO_INHERIT - {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT}, +#ifdef _SC_AUDIT + {"SC_AUDIT", _SC_AUDIT}, #endif -#ifdef _SC_THREAD_PRIO_PROTECT - {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT}, +#ifdef _SC_AVPHYS_PAGES + {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES}, #endif -#ifdef _SC_THREAD_PROCESS_SHARED - {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED}, +#ifdef _SC_BC_BASE_MAX + {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX}, #endif -#ifdef _SC_THREAD_SAFE_FUNCTIONS - {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS}, +#ifdef _SC_BC_DIM_MAX + {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX}, #endif -#ifdef _SC_THREAD_STACK_MIN - {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN}, +#ifdef _SC_BC_SCALE_MAX + {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX}, #endif -#ifdef _SC_THREAD_THREADS_MAX - {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX}, +#ifdef _SC_BC_STRING_MAX + {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX}, #endif -#ifdef _SC_TIMERS - {"SC_TIMERS", _SC_TIMERS}, +#ifdef _SC_CAP + {"SC_CAP", _SC_CAP}, #endif -#ifdef _SC_TIMER_MAX - {"SC_TIMER_MAX", _SC_TIMER_MAX}, +#ifdef _SC_CHARCLASS_NAME_MAX + {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX}, #endif -#ifdef _SC_TTY_NAME_MAX - {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX}, +#ifdef _SC_CHAR_BIT + {"SC_CHAR_BIT", _SC_CHAR_BIT}, #endif -#ifdef _SC_TZNAME_MAX - {"SC_TZNAME_MAX", _SC_TZNAME_MAX}, +#ifdef _SC_CHAR_MAX + {"SC_CHAR_MAX", _SC_CHAR_MAX}, #endif -#ifdef _SC_T_IOV_MAX - {"SC_T_IOV_MAX", _SC_T_IOV_MAX}, +#ifdef _SC_CHAR_MIN + {"SC_CHAR_MIN", _SC_CHAR_MIN}, #endif -#ifdef _SC_UCHAR_MAX - {"SC_UCHAR_MAX", _SC_UCHAR_MAX}, +#ifdef _SC_CHILD_MAX + {"SC_CHILD_MAX", _SC_CHILD_MAX}, #endif -#ifdef _SC_UINT_MAX - {"SC_UINT_MAX", _SC_UINT_MAX}, +#ifdef _SC_CLK_TCK + {"SC_CLK_TCK", _SC_CLK_TCK}, #endif -#ifdef _SC_UIO_MAXIOV - {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV}, +#ifdef _SC_COHER_BLKSZ + {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ}, #endif -#ifdef _SC_ULONG_MAX - {"SC_ULONG_MAX", _SC_ULONG_MAX}, +#ifdef _SC_COLL_WEIGHTS_MAX + {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX}, #endif -#ifdef _SC_USHRT_MAX - {"SC_USHRT_MAX", _SC_USHRT_MAX}, +#ifdef _SC_DCACHE_ASSOC + {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC}, #endif -#ifdef _SC_VERSION - {"SC_VERSION", _SC_VERSION}, +#ifdef _SC_DCACHE_BLKSZ + {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ}, #endif -#ifdef _SC_WORD_BIT - {"SC_WORD_BIT", _SC_WORD_BIT}, +#ifdef _SC_DCACHE_LINESZ + {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ}, #endif -#ifdef _SC_XBS5_ILP32_OFF32 - {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32}, +#ifdef _SC_DCACHE_SZ + {"SC_DCACHE_SZ", _SC_DCACHE_SZ}, #endif -#ifdef _SC_XBS5_ILP32_OFFBIG - {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG}, +#ifdef _SC_DCACHE_TBLKSZ + {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ}, #endif -#ifdef _SC_XBS5_LP64_OFF64 - {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64}, +#ifdef _SC_DELAYTIMER_MAX + {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX}, #endif -#ifdef _SC_XBS5_LPBIG_OFFBIG - {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG}, +#ifdef _SC_EQUIV_CLASS_MAX + {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX}, #endif -#ifdef _SC_XOPEN_CRYPT - {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT}, +#ifdef _SC_EXPR_NEST_MAX + {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX}, #endif -#ifdef _SC_XOPEN_ENH_I18N - {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N}, +#ifdef _SC_FSYNC + {"SC_FSYNC", _SC_FSYNC}, #endif -#ifdef _SC_XOPEN_LEGACY - {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY}, +#ifdef _SC_GETGR_R_SIZE_MAX + {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX}, #endif -#ifdef _SC_XOPEN_REALTIME - {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME}, +#ifdef _SC_GETPW_R_SIZE_MAX + {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX}, #endif -#ifdef _SC_XOPEN_REALTIME_THREADS - {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS}, +#ifdef _SC_ICACHE_ASSOC + {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC}, #endif -#ifdef _SC_XOPEN_SHM - {"SC_XOPEN_SHM", _SC_XOPEN_SHM}, +#ifdef _SC_ICACHE_BLKSZ + {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ}, #endif -#ifdef _SC_XOPEN_UNIX - {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX}, +#ifdef _SC_ICACHE_LINESZ + {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ}, #endif -#ifdef _SC_XOPEN_VERSION - {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION}, +#ifdef _SC_ICACHE_SZ + {"SC_ICACHE_SZ", _SC_ICACHE_SZ}, #endif -#ifdef _SC_XOPEN_XCU_VERSION - {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION}, +#ifdef _SC_INF + {"SC_INF", _SC_INF}, #endif -#ifdef _SC_XOPEN_XPG2 - {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2}, +#ifdef _SC_INT_MAX + {"SC_INT_MAX", _SC_INT_MAX}, #endif -#ifdef _SC_XOPEN_XPG3 - {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3}, +#ifdef _SC_INT_MIN + {"SC_INT_MIN", _SC_INT_MIN}, #endif -#ifdef _SC_XOPEN_XPG4 - {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4}, +#ifdef _SC_IOV_MAX + {"SC_IOV_MAX", _SC_IOV_MAX}, +#endif +#ifdef _SC_IP_SECOPTS + {"SC_IP_SECOPTS", _SC_IP_SECOPTS}, +#endif +#ifdef _SC_JOB_CONTROL + {"SC_JOB_CONTROL", _SC_JOB_CONTROL}, +#endif +#ifdef _SC_KERN_POINTERS + {"SC_KERN_POINTERS", _SC_KERN_POINTERS}, +#endif +#ifdef _SC_KERN_SIM + {"SC_KERN_SIM", _SC_KERN_SIM}, +#endif +#ifdef _SC_LINE_MAX + {"SC_LINE_MAX", _SC_LINE_MAX}, +#endif +#ifdef _SC_LOGIN_NAME_MAX + {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX}, +#endif +#ifdef _SC_LOGNAME_MAX + {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX}, +#endif +#ifdef _SC_LONG_BIT + {"SC_LONG_BIT", _SC_LONG_BIT}, +#endif +#ifdef _SC_MAC + {"SC_MAC", _SC_MAC}, +#endif +#ifdef _SC_MAPPED_FILES + {"SC_MAPPED_FILES", _SC_MAPPED_FILES}, +#endif +#ifdef _SC_MAXPID + {"SC_MAXPID", _SC_MAXPID}, +#endif +#ifdef _SC_MB_LEN_MAX + {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX}, +#endif +#ifdef _SC_MEMLOCK + {"SC_MEMLOCK", _SC_MEMLOCK}, +#endif +#ifdef _SC_MEMLOCK_RANGE + {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE}, +#endif +#ifdef _SC_MEMORY_PROTECTION + {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION}, +#endif +#ifdef _SC_MESSAGE_PASSING + {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING}, +#endif +#ifdef _SC_MMAP_FIXED_ALIGNMENT + {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT}, +#endif +#ifdef _SC_MQ_OPEN_MAX + {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX}, +#endif +#ifdef _SC_MQ_PRIO_MAX + {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX}, +#endif +#ifdef _SC_NACLS_MAX + {"SC_NACLS_MAX", _SC_NACLS_MAX}, +#endif +#ifdef _SC_NGROUPS_MAX + {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX}, +#endif +#ifdef _SC_NL_ARGMAX + {"SC_NL_ARGMAX", _SC_NL_ARGMAX}, +#endif +#ifdef _SC_NL_LANGMAX + {"SC_NL_LANGMAX", _SC_NL_LANGMAX}, +#endif +#ifdef _SC_NL_MSGMAX + {"SC_NL_MSGMAX", _SC_NL_MSGMAX}, +#endif +#ifdef _SC_NL_NMAX + {"SC_NL_NMAX", _SC_NL_NMAX}, +#endif +#ifdef _SC_NL_SETMAX + {"SC_NL_SETMAX", _SC_NL_SETMAX}, +#endif +#ifdef _SC_NL_TEXTMAX + {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX}, +#endif +#ifdef _SC_NPROCESSORS_CONF + {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF}, +#endif +#ifdef _SC_NPROCESSORS_ONLN + {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN}, +#endif +#ifdef _SC_NPROC_CONF + {"SC_NPROC_CONF", _SC_NPROC_CONF}, +#endif +#ifdef _SC_NPROC_ONLN + {"SC_NPROC_ONLN", _SC_NPROC_ONLN}, +#endif +#ifdef _SC_NZERO + {"SC_NZERO", _SC_NZERO}, +#endif +#ifdef _SC_OPEN_MAX + {"SC_OPEN_MAX", _SC_OPEN_MAX}, +#endif +#ifdef _SC_PAGESIZE + {"SC_PAGESIZE", _SC_PAGESIZE}, +#endif +#ifdef _SC_PAGE_SIZE + {"SC_PAGE_SIZE", _SC_PAGE_SIZE}, +#endif +#ifdef _SC_PASS_MAX + {"SC_PASS_MAX", _SC_PASS_MAX}, +#endif +#ifdef _SC_PHYS_PAGES + {"SC_PHYS_PAGES", _SC_PHYS_PAGES}, +#endif +#ifdef _SC_PII + {"SC_PII", _SC_PII}, +#endif +#ifdef _SC_PII_INTERNET + {"SC_PII_INTERNET", _SC_PII_INTERNET}, +#endif +#ifdef _SC_PII_INTERNET_DGRAM + {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM}, +#endif +#ifdef _SC_PII_INTERNET_STREAM + {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM}, +#endif +#ifdef _SC_PII_OSI + {"SC_PII_OSI", _SC_PII_OSI}, +#endif +#ifdef _SC_PII_OSI_CLTS + {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS}, +#endif +#ifdef _SC_PII_OSI_COTS + {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS}, +#endif +#ifdef _SC_PII_OSI_M + {"SC_PII_OSI_M", _SC_PII_OSI_M}, +#endif +#ifdef _SC_PII_SOCKET + {"SC_PII_SOCKET", _SC_PII_SOCKET}, +#endif +#ifdef _SC_PII_XTI + {"SC_PII_XTI", _SC_PII_XTI}, +#endif +#ifdef _SC_POLL + {"SC_POLL", _SC_POLL}, #endif +#ifdef _SC_PRIORITIZED_IO + {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO}, +#endif +#ifdef _SC_PRIORITY_SCHEDULING + {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING}, +#endif +#ifdef _SC_REALTIME_SIGNALS + {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS}, +#endif +#ifdef _SC_RE_DUP_MAX + {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX}, +#endif +#ifdef _SC_RTSIG_MAX + {"SC_RTSIG_MAX", _SC_RTSIG_MAX}, +#endif +#ifdef _SC_SAVED_IDS + {"SC_SAVED_IDS", _SC_SAVED_IDS}, +#endif +#ifdef _SC_SCHAR_MAX + {"SC_SCHAR_MAX", _SC_SCHAR_MAX}, +#endif +#ifdef _SC_SCHAR_MIN + {"SC_SCHAR_MIN", _SC_SCHAR_MIN}, +#endif +#ifdef _SC_SELECT + {"SC_SELECT", _SC_SELECT}, +#endif +#ifdef _SC_SEMAPHORES + {"SC_SEMAPHORES", _SC_SEMAPHORES}, +#endif +#ifdef _SC_SEM_NSEMS_MAX + {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX}, +#endif +#ifdef _SC_SEM_VALUE_MAX + {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX}, +#endif +#ifdef _SC_SHARED_MEMORY_OBJECTS + {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS}, +#endif +#ifdef _SC_SHRT_MAX + {"SC_SHRT_MAX", _SC_SHRT_MAX}, +#endif +#ifdef _SC_SHRT_MIN + {"SC_SHRT_MIN", _SC_SHRT_MIN}, +#endif +#ifdef _SC_SIGQUEUE_MAX + {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX}, +#endif +#ifdef _SC_SIGRT_MAX + {"SC_SIGRT_MAX", _SC_SIGRT_MAX}, +#endif +#ifdef _SC_SIGRT_MIN + {"SC_SIGRT_MIN", _SC_SIGRT_MIN}, +#endif +#ifdef _SC_SOFTPOWER + {"SC_SOFTPOWER", _SC_SOFTPOWER}, +#endif +#ifdef _SC_SPLIT_CACHE + {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE}, +#endif +#ifdef _SC_SSIZE_MAX + {"SC_SSIZE_MAX", _SC_SSIZE_MAX}, +#endif +#ifdef _SC_STACK_PROT + {"SC_STACK_PROT", _SC_STACK_PROT}, +#endif +#ifdef _SC_STREAM_MAX + {"SC_STREAM_MAX", _SC_STREAM_MAX}, +#endif +#ifdef _SC_SYNCHRONIZED_IO + {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO}, +#endif +#ifdef _SC_THREADS + {"SC_THREADS", _SC_THREADS}, +#endif +#ifdef _SC_THREAD_ATTR_STACKADDR + {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR}, +#endif +#ifdef _SC_THREAD_ATTR_STACKSIZE + {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE}, +#endif +#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS + {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS}, +#endif +#ifdef _SC_THREAD_KEYS_MAX + {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX}, +#endif +#ifdef _SC_THREAD_PRIORITY_SCHEDULING + {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING}, +#endif +#ifdef _SC_THREAD_PRIO_INHERIT + {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT}, +#endif +#ifdef _SC_THREAD_PRIO_PROTECT + {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT}, +#endif +#ifdef _SC_THREAD_PROCESS_SHARED + {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED}, +#endif +#ifdef _SC_THREAD_SAFE_FUNCTIONS + {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS}, +#endif +#ifdef _SC_THREAD_STACK_MIN + {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN}, +#endif +#ifdef _SC_THREAD_THREADS_MAX + {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX}, +#endif +#ifdef _SC_TIMERS + {"SC_TIMERS", _SC_TIMERS}, +#endif +#ifdef _SC_TIMER_MAX + {"SC_TIMER_MAX", _SC_TIMER_MAX}, +#endif +#ifdef _SC_TTY_NAME_MAX + {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX}, +#endif +#ifdef _SC_TZNAME_MAX + {"SC_TZNAME_MAX", _SC_TZNAME_MAX}, +#endif +#ifdef _SC_T_IOV_MAX + {"SC_T_IOV_MAX", _SC_T_IOV_MAX}, +#endif +#ifdef _SC_UCHAR_MAX + {"SC_UCHAR_MAX", _SC_UCHAR_MAX}, +#endif +#ifdef _SC_UINT_MAX + {"SC_UINT_MAX", _SC_UINT_MAX}, +#endif +#ifdef _SC_UIO_MAXIOV + {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV}, +#endif +#ifdef _SC_ULONG_MAX + {"SC_ULONG_MAX", _SC_ULONG_MAX}, +#endif +#ifdef _SC_USHRT_MAX + {"SC_USHRT_MAX", _SC_USHRT_MAX}, +#endif +#ifdef _SC_VERSION + {"SC_VERSION", _SC_VERSION}, +#endif +#ifdef _SC_WORD_BIT + {"SC_WORD_BIT", _SC_WORD_BIT}, +#endif +#ifdef _SC_XBS5_ILP32_OFF32 + {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32}, +#endif +#ifdef _SC_XBS5_ILP32_OFFBIG + {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG}, +#endif +#ifdef _SC_XBS5_LP64_OFF64 + {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64}, +#endif +#ifdef _SC_XBS5_LPBIG_OFFBIG + {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG}, +#endif +#ifdef _SC_XOPEN_CRYPT + {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT}, +#endif +#ifdef _SC_XOPEN_ENH_I18N + {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N}, +#endif +#ifdef _SC_XOPEN_LEGACY + {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY}, +#endif +#ifdef _SC_XOPEN_REALTIME + {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME}, +#endif +#ifdef _SC_XOPEN_REALTIME_THREADS + {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS}, +#endif +#ifdef _SC_XOPEN_SHM + {"SC_XOPEN_SHM", _SC_XOPEN_SHM}, +#endif +#ifdef _SC_XOPEN_UNIX + {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX}, +#endif +#ifdef _SC_XOPEN_VERSION + {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION}, +#endif +#ifdef _SC_XOPEN_XCU_VERSION + {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION}, +#endif +#ifdef _SC_XOPEN_XPG2 + {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2}, +#endif +#ifdef _SC_XOPEN_XPG3 + {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3}, +#endif +#ifdef _SC_XOPEN_XPG4 + {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4}, +#endif +}; + +static int +conv_sysconf_confname(PyObject *arg, int *valuep) +{ + return conv_confname(arg, valuep, posix_constants_sysconf, + sizeof(posix_constants_sysconf) + / sizeof(struct constdef)); +} + + +/*[clinic input] +os.sysconf -> long + name: sysconf_confname + / + +Return an integer-valued system configuration variable. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_sysconf__doc__, +"sysconf($module, name, /)\n" +"--\n" +"\n" +"Return an integer-valued system configuration variable."); + +#define OS_SYSCONF_METHODDEF \ + {"sysconf", (PyCFunction)os_sysconf, METH_VARARGS, os_sysconf__doc__}, + +static long +os_sysconf_impl(PyModuleDef *module, int name); + +static PyObject * +os_sysconf(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int name; + long _return_value; + + if (!PyArg_ParseTuple(args, + "O&:sysconf", + conv_sysconf_confname, &name)) + goto exit; + _return_value = os_sysconf_impl(module, name); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromLong(_return_value); + +exit: + return return_value; +} + +static long +os_sysconf_impl(PyModuleDef *module, int name) +/*[clinic end generated code: output=7b06dfdc472431e4 input=279e3430a33f29e4]*/ +{ + long value; + + errno = 0; + value = sysconf(name); + if (value == -1 && errno != 0) + posix_error(); + return value; +} +#endif /* HAVE_SYSCONF */ + + +/* This code is used to ensure that the tables of configuration value names + * are in sorted order as required by conv_confname(), and also to build + * the exported dictionaries that are used to publish information about the + * names available on the host platform. + * + * Sorting the table at runtime ensures that the table is properly ordered + * when used, even for platforms we're not able to test on. It also makes + * it easier to add additional entries to the tables. + */ + +static int +cmp_constdefs(const void *v1, const void *v2) +{ + const struct constdef *c1 = + (const struct constdef *) v1; + const struct constdef *c2 = + (const struct constdef *) v2; + + return strcmp(c1->name, c2->name); +} + +static int +setup_confname_table(struct constdef *table, size_t tablesize, + char *tablename, PyObject *module) +{ + PyObject *d = NULL; + size_t i; + + qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs); + d = PyDict_New(); + if (d == NULL) + return -1; + + for (i=0; i < tablesize; ++i) { + PyObject *o = PyLong_FromLong(table[i].value); + if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) { + Py_XDECREF(o); + Py_DECREF(d); + return -1; + } + Py_DECREF(o); + } + return PyModule_AddObject(module, tablename, d); +} + +/* Return -1 on failure, 0 on success. */ +static int +setup_confname_tables(PyObject *module) +{ +#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF) + if (setup_confname_table(posix_constants_pathconf, + sizeof(posix_constants_pathconf) + / sizeof(struct constdef), + "pathconf_names", module)) + return -1; +#endif +#ifdef HAVE_CONFSTR + if (setup_confname_table(posix_constants_confstr, + sizeof(posix_constants_confstr) + / sizeof(struct constdef), + "confstr_names", module)) + return -1; +#endif +#ifdef HAVE_SYSCONF + if (setup_confname_table(posix_constants_sysconf, + sizeof(posix_constants_sysconf) + / sizeof(struct constdef), + "sysconf_names", module)) + return -1; +#endif + return 0; +} + + +/*[clinic input] +os.abort + +Abort the interpreter immediately. + +This function 'dumps core' or otherwise fails in the hardest way possible +on the hosting operating system. This function never returns. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_abort__doc__, +"abort($module, /)\n" +"--\n" +"\n" +"Abort the interpreter immediately.\n" +"\n" +"This function \'dumps core\' or otherwise fails in the hardest way possible\n" +"on the hosting operating system. This function never returns."); + +#define OS_ABORT_METHODDEF \ + {"abort", (PyCFunction)os_abort, METH_NOARGS, os_abort__doc__}, + +static PyObject * +os_abort_impl(PyModuleDef *module); + +static PyObject * +os_abort(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_abort_impl(module); +} + +static PyObject * +os_abort_impl(PyModuleDef *module) +/*[clinic end generated code: output=cded2cc8c5453d3a input=cf2c7d98bc504047]*/ +{ + abort(); + /*NOTREACHED*/ + Py_FatalError("abort() called from Python code didn't abort!"); + return NULL; +} + +#ifdef MS_WINDOWS +/* AC 3.5: change to path_t? but that might change exceptions */ +PyDoc_STRVAR(win32_startfile__doc__, +"startfile(filepath [, operation])\n\ +\n\ +Start a file with its associated application.\n\ +\n\ +When \"operation\" is not specified or \"open\", this acts like\n\ +double-clicking the file in Explorer, or giving the file name as an\n\ +argument to the DOS \"start\" command: the file is opened with whatever\n\ +application (if any) its extension is associated.\n\ +When another \"operation\" is given, it specifies what should be done with\n\ +the file. A typical operation is \"print\".\n\ +\n\ +startfile returns as soon as the associated application is launched.\n\ +There is no option to wait for the application to close, and no way\n\ +to retrieve the application's exit status.\n\ +\n\ +The filepath is relative to the current directory. If you want to use\n\ +an absolute path, make sure the first character is not a slash (\"/\");\n\ +the underlying Win32 ShellExecute function doesn't work if it is."); + +/* Grab ShellExecute dynamically from shell32 */ +static int has_ShellExecute = -1; +static HINSTANCE (CALLBACK *Py_ShellExecuteA)(HWND, LPCSTR, LPCSTR, LPCSTR, + LPCSTR, INT); +static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR, + LPCWSTR, INT); +static int +check_ShellExecute() +{ + HINSTANCE hShell32; + + /* only recheck */ + if (-1 == has_ShellExecute) { + Py_BEGIN_ALLOW_THREADS + hShell32 = LoadLibraryW(L"SHELL32"); + Py_END_ALLOW_THREADS + if (hShell32) { + *(FARPROC*)&Py_ShellExecuteA = GetProcAddress(hShell32, + "ShellExecuteA"); + *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32, + "ShellExecuteW"); + has_ShellExecute = Py_ShellExecuteA && + Py_ShellExecuteW; + } else { + has_ShellExecute = 0; + } + } + return has_ShellExecute; +} + + +static PyObject * +win32_startfile(PyObject *self, PyObject *args) +{ + PyObject *ofilepath; + char *filepath; + char *operation = NULL; + wchar_t *wpath, *woperation; + HINSTANCE rc; + + PyObject *unipath, *uoperation = NULL; + + if(!check_ShellExecute()) { + /* If the OS doesn't have ShellExecute, return a + NotImplementedError. */ + return PyErr_Format(PyExc_NotImplementedError, + "startfile not available on this platform"); + } + + if (!PyArg_ParseTuple(args, "U|s:startfile", + &unipath, &operation)) { + PyErr_Clear(); + goto normal; + } + + if (operation) { + uoperation = PyUnicode_DecodeASCII(operation, + strlen(operation), NULL); + if (!uoperation) { + PyErr_Clear(); + operation = NULL; + goto normal; + } + } + + wpath = PyUnicode_AsUnicode(unipath); + if (wpath == NULL) + goto normal; + if (uoperation) { + woperation = PyUnicode_AsUnicode(uoperation); + if (woperation == NULL) + goto normal; + } + else + woperation = NULL; + + Py_BEGIN_ALLOW_THREADS + rc = Py_ShellExecuteW((HWND)0, woperation, wpath, + NULL, NULL, SW_SHOWNORMAL); + Py_END_ALLOW_THREADS + + Py_XDECREF(uoperation); + if (rc <= (HINSTANCE)32) { + win32_error_object("startfile", unipath); + return NULL; + } + Py_INCREF(Py_None); + return Py_None; + +normal: + if (!PyArg_ParseTuple(args, "O&|s:startfile", + PyUnicode_FSConverter, &ofilepath, + &operation)) + return NULL; + if (win32_warn_bytes_api()) { + Py_DECREF(ofilepath); + return NULL; + } + filepath = PyBytes_AsString(ofilepath); + Py_BEGIN_ALLOW_THREADS + rc = Py_ShellExecuteA((HWND)0, operation, filepath, + NULL, NULL, SW_SHOWNORMAL); + Py_END_ALLOW_THREADS + if (rc <= (HINSTANCE)32) { + PyObject *errval = win32_error("startfile", filepath); + Py_DECREF(ofilepath); + return errval; + } + Py_DECREF(ofilepath); + Py_INCREF(Py_None); + return Py_None; +} +#endif /* MS_WINDOWS */ + + +#ifdef HAVE_GETLOADAVG +/*[clinic input] +os.getloadavg + +Return average recent system load information. + +Return the number of processes in the system run queue averaged over +the last 1, 5, and 15 minutes as a tuple of three floats. +Raises OSError if the load average was unobtainable. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_getloadavg__doc__, +"getloadavg($module, /)\n" +"--\n" +"\n" +"Return average recent system load information.\n" +"\n" +"Return the number of processes in the system run queue averaged over\n" +"the last 1, 5, and 15 minutes as a tuple of three floats.\n" +"Raises OSError if the load average was unobtainable."); + +#define OS_GETLOADAVG_METHODDEF \ + {"getloadavg", (PyCFunction)os_getloadavg, METH_NOARGS, os_getloadavg__doc__}, + +static PyObject * +os_getloadavg_impl(PyModuleDef *module); + +static PyObject * +os_getloadavg(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_getloadavg_impl(module); +} + +static PyObject * +os_getloadavg_impl(PyModuleDef *module) +/*[clinic end generated code: output=67593a92457d55af input=3d6d826b76d8a34e]*/ +{ + double loadavg[3]; + if (getloadavg(loadavg, 3)!=3) { + PyErr_SetString(PyExc_OSError, "Load averages are unobtainable"); + return NULL; + } else + return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]); +} +#endif /* HAVE_GETLOADAVG */ + + +/*[clinic input] +os.device_encoding + fd: int + +Return a string describing the encoding of a terminal's file descriptor. + +The file descriptor must be attached to a terminal. +If the device is not a terminal, return None. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_device_encoding__doc__, +"device_encoding($module, /, fd)\n" +"--\n" +"\n" +"Return a string describing the encoding of a terminal\'s file descriptor.\n" +"\n" +"The file descriptor must be attached to a terminal.\n" +"If the device is not a terminal, return None."); + +#define OS_DEVICE_ENCODING_METHODDEF \ + {"device_encoding", (PyCFunction)os_device_encoding, METH_VARARGS|METH_KEYWORDS, os_device_encoding__doc__}, + +static PyObject * +os_device_encoding_impl(PyModuleDef *module, int fd); + +static PyObject * +os_device_encoding(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"fd", NULL}; + int fd; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "i:device_encoding", _keywords, + &fd)) + goto exit; + return_value = os_device_encoding_impl(module, fd); + +exit: + return return_value; +} + +static PyObject * +os_device_encoding_impl(PyModuleDef *module, int fd) +/*[clinic end generated code: output=e9f8274d42f5cce3 input=9e1d4a42b66df312]*/ +{ + return _Py_device_encoding(fd); +} + + +#ifdef HAVE_SETRESUID +/*[clinic input] +os.setresuid + + ruid: uid_t + euid: uid_t + suid: uid_t + / + +Set the current process's real, effective, and saved user ids. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_setresuid__doc__, +"setresuid($module, ruid, euid, suid, /)\n" +"--\n" +"\n" +"Set the current process\'s real, effective, and saved user ids."); + +#define OS_SETRESUID_METHODDEF \ + {"setresuid", (PyCFunction)os_setresuid, METH_VARARGS, os_setresuid__doc__}, + +static PyObject * +os_setresuid_impl(PyModuleDef *module, uid_t ruid, uid_t euid, uid_t suid); + +static PyObject * +os_setresuid(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + uid_t ruid; + uid_t euid; + uid_t suid; + + if (!PyArg_ParseTuple(args, + "O&O&O&:setresuid", + _Py_Uid_Converter, &ruid, _Py_Uid_Converter, &euid, _Py_Uid_Converter, &suid)) + goto exit; + return_value = os_setresuid_impl(module, ruid, euid, suid); + +exit: + return return_value; +} + +static PyObject * +os_setresuid_impl(PyModuleDef *module, uid_t ruid, uid_t euid, uid_t suid) +/*[clinic end generated code: output=2e3457cfe7cd1f94 input=9e33cb79a82792f3]*/ +{ + if (setresuid(ruid, euid, suid) < 0) + return posix_error(); + Py_RETURN_NONE; +} +#endif /* HAVE_SETRESUID */ + + +#ifdef HAVE_SETRESGID +/*[clinic input] +os.setresgid + + rgid: gid_t + egid: gid_t + sgid: gid_t + / + +Set the current process's real, effective, and saved group ids. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_setresgid__doc__, +"setresgid($module, rgid, egid, sgid, /)\n" +"--\n" +"\n" +"Set the current process\'s real, effective, and saved group ids."); + +#define OS_SETRESGID_METHODDEF \ + {"setresgid", (PyCFunction)os_setresgid, METH_VARARGS, os_setresgid__doc__}, + +static PyObject * +os_setresgid_impl(PyModuleDef *module, gid_t rgid, gid_t egid, gid_t sgid); + +static PyObject * +os_setresgid(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + gid_t rgid; + gid_t egid; + gid_t sgid; + + if (!PyArg_ParseTuple(args, + "O&O&O&:setresgid", + _Py_Gid_Converter, &rgid, _Py_Gid_Converter, &egid, _Py_Gid_Converter, &sgid)) + goto exit; + return_value = os_setresgid_impl(module, rgid, egid, sgid); + +exit: + return return_value; +} + +static PyObject * +os_setresgid_impl(PyModuleDef *module, gid_t rgid, gid_t egid, gid_t sgid) +/*[clinic end generated code: output=8a7ee6c1f2482362 input=33e9e0785ef426b1]*/ +{ + if (setresgid(rgid, egid, sgid) < 0) + return posix_error(); + Py_RETURN_NONE; +} +#endif /* HAVE_SETRESGID */ + + +#ifdef HAVE_GETRESUID +/*[clinic input] +os.getresuid + +Return a tuple of the current process's real, effective, and saved user ids. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_getresuid__doc__, +"getresuid($module, /)\n" +"--\n" +"\n" +"Return a tuple of the current process\'s real, effective, and saved user ids."); + +#define OS_GETRESUID_METHODDEF \ + {"getresuid", (PyCFunction)os_getresuid, METH_NOARGS, os_getresuid__doc__}, + +static PyObject * +os_getresuid_impl(PyModuleDef *module); + +static PyObject * +os_getresuid(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_getresuid_impl(module); +} + +static PyObject * +os_getresuid_impl(PyModuleDef *module) +/*[clinic end generated code: output=d0786686a6ef1320 input=41ccfa8e1f6517ad]*/ +{ + uid_t ruid, euid, suid; + if (getresuid(&ruid, &euid, &suid) < 0) + return posix_error(); + return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid), + _PyLong_FromUid(euid), + _PyLong_FromUid(suid)); +} +#endif /* HAVE_GETRESUID */ + + +#ifdef HAVE_GETRESGID +/*[clinic input] +os.getresgid + +Return a tuple of the current process's real, effective, and saved group ids. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_getresgid__doc__, +"getresgid($module, /)\n" +"--\n" +"\n" +"Return a tuple of the current process\'s real, effective, and saved group ids."); + +#define OS_GETRESGID_METHODDEF \ + {"getresgid", (PyCFunction)os_getresgid, METH_NOARGS, os_getresgid__doc__}, + +static PyObject * +os_getresgid_impl(PyModuleDef *module); + +static PyObject * +os_getresgid(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_getresgid_impl(module); +} + +static PyObject * +os_getresgid_impl(PyModuleDef *module) +/*[clinic end generated code: output=05249ac795fa759f input=517e68db9ca32df6]*/ +{ + gid_t rgid, egid, sgid; + if (getresgid(&rgid, &egid, &sgid) < 0) + return posix_error(); + return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid), + _PyLong_FromGid(egid), + _PyLong_FromGid(sgid)); +} +#endif /* HAVE_GETRESGID */ + + +#ifdef USE_XATTRS +/*[clinic input] +os.getxattr + + path: path_t(allow_fd=True) + attribute: path_t + * + follow_symlinks: bool = True + +Return the value of extended attribute attribute on path. + +path may be either a string or an open file descriptor. +If follow_symlinks is False, and the last element of the path is a symbolic + link, getxattr will examine the symbolic link itself instead of the file + the link points to. + +[clinic start generated code]*/ + +PyDoc_STRVAR(os_getxattr__doc__, +"getxattr($module, /, path, attribute, *, follow_symlinks=True)\n" +"--\n" +"\n" +"Return the value of extended attribute attribute on path.\n" +"\n" +"path may be either a string or an open file descriptor.\n" +"If follow_symlinks is False, and the last element of the path is a symbolic\n" +" link, getxattr will examine the symbolic link itself instead of the file\n" +" the link points to."); + +#define OS_GETXATTR_METHODDEF \ + {"getxattr", (PyCFunction)os_getxattr, METH_VARARGS|METH_KEYWORDS, os_getxattr__doc__}, + +static PyObject * +os_getxattr_impl(PyModuleDef *module, path_t *path, path_t *attribute, int follow_symlinks); + +static PyObject * +os_getxattr(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "attribute", "follow_symlinks", NULL}; + path_t path = PATH_T_INITIALIZE("getxattr", "path", 0, 1); + path_t attribute = PATH_T_INITIALIZE("getxattr", "attribute", 0, 0); + int follow_symlinks = 1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&O&|$p:getxattr", _keywords, + path_converter, &path, path_converter, &attribute, &follow_symlinks)) + goto exit; + return_value = os_getxattr_impl(module, &path, &attribute, follow_symlinks); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + /* Cleanup for attribute */ + path_cleanup(&attribute); + + return return_value; +} + +static PyObject * +os_getxattr_impl(PyModuleDef *module, path_t *path, path_t *attribute, int follow_symlinks) +/*[clinic end generated code: output=bbc9454fe2b9ea86 input=8c8ea3bab78d89c2]*/ +{ + Py_ssize_t i; + PyObject *buffer = NULL; + + if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks)) + return NULL; + + for (i = 0; ; i++) { + void *ptr; + ssize_t result; + static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0}; + Py_ssize_t buffer_size = buffer_sizes[i]; + if (!buffer_size) { + path_error(path); + return NULL; + } + buffer = PyBytes_FromStringAndSize(NULL, buffer_size); + if (!buffer) + return NULL; + ptr = PyBytes_AS_STRING(buffer); + + Py_BEGIN_ALLOW_THREADS; + if (path->fd >= 0) + result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size); + else if (follow_symlinks) + result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size); + else + result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size); + Py_END_ALLOW_THREADS; + + if (result < 0) { + Py_DECREF(buffer); + if (errno == ERANGE) + continue; + path_error(path); + return NULL; + } + + if (result != buffer_size) { + /* Can only shrink. */ + _PyBytes_Resize(&buffer, result); + } + break; + } + + return buffer; +} + + +/*[clinic input] +os.setxattr + + path: path_t(allow_fd=True) + attribute: path_t + value: Py_buffer + flags: int = 0 + * + follow_symlinks: bool = True + +Set extended attribute attribute on path to value. + +path may be either a string or an open file descriptor. +If follow_symlinks is False, and the last element of the path is a symbolic + link, setxattr will modify the symbolic link itself instead of the file + the link points to. + +[clinic start generated code]*/ + +PyDoc_STRVAR(os_setxattr__doc__, +"setxattr($module, /, path, attribute, value, flags=0, *,\n" +" follow_symlinks=True)\n" +"--\n" +"\n" +"Set extended attribute attribute on path to value.\n" +"\n" +"path may be either a string or an open file descriptor.\n" +"If follow_symlinks is False, and the last element of the path is a symbolic\n" +" link, setxattr will modify the symbolic link itself instead of the file\n" +" the link points to."); + +#define OS_SETXATTR_METHODDEF \ + {"setxattr", (PyCFunction)os_setxattr, METH_VARARGS|METH_KEYWORDS, os_setxattr__doc__}, + +static PyObject * +os_setxattr_impl(PyModuleDef *module, path_t *path, path_t *attribute, Py_buffer *value, int flags, int follow_symlinks); + +static PyObject * +os_setxattr(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "attribute", "value", "flags", "follow_symlinks", NULL}; + path_t path = PATH_T_INITIALIZE("setxattr", "path", 0, 1); + path_t attribute = PATH_T_INITIALIZE("setxattr", "attribute", 0, 0); + Py_buffer value = {NULL, NULL}; + int flags = 0; + int follow_symlinks = 1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&O&y*|i$p:setxattr", _keywords, + path_converter, &path, path_converter, &attribute, &value, &flags, &follow_symlinks)) + goto exit; + return_value = os_setxattr_impl(module, &path, &attribute, &value, flags, follow_symlinks); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + /* Cleanup for attribute */ + path_cleanup(&attribute); + /* Cleanup for value */ + if (value.obj) + PyBuffer_Release(&value); + + return return_value; +} + +static PyObject * +os_setxattr_impl(PyModuleDef *module, path_t *path, path_t *attribute, Py_buffer *value, int flags, int follow_symlinks) +/*[clinic end generated code: output=2ff845d8e024b218 input=f0d26833992015c2]*/ +{ + ssize_t result; + + if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks)) + return NULL; + + Py_BEGIN_ALLOW_THREADS; + if (path->fd > -1) + result = fsetxattr(path->fd, attribute->narrow, + value->buf, value->len, flags); + else if (follow_symlinks) + result = setxattr(path->narrow, attribute->narrow, + value->buf, value->len, flags); + else + result = lsetxattr(path->narrow, attribute->narrow, + value->buf, value->len, flags); + Py_END_ALLOW_THREADS; + + if (result) { + path_error(path); + return NULL; + } + + Py_RETURN_NONE; +} + + +/*[clinic input] +os.removexattr + + path: path_t(allow_fd=True) + attribute: path_t + * + follow_symlinks: bool = True + +Remove extended attribute attribute on path. + +path may be either a string or an open file descriptor. +If follow_symlinks is False, and the last element of the path is a symbolic + link, removexattr will modify the symbolic link itself instead of the file + the link points to. + +[clinic start generated code]*/ + +PyDoc_STRVAR(os_removexattr__doc__, +"removexattr($module, /, path, attribute, *, follow_symlinks=True)\n" +"--\n" +"\n" +"Remove extended attribute attribute on path.\n" +"\n" +"path may be either a string or an open file descriptor.\n" +"If follow_symlinks is False, and the last element of the path is a symbolic\n" +" link, removexattr will modify the symbolic link itself instead of the file\n" +" the link points to."); + +#define OS_REMOVEXATTR_METHODDEF \ + {"removexattr", (PyCFunction)os_removexattr, METH_VARARGS|METH_KEYWORDS, os_removexattr__doc__}, + +static PyObject * +os_removexattr_impl(PyModuleDef *module, path_t *path, path_t *attribute, int follow_symlinks); + +static PyObject * +os_removexattr(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "attribute", "follow_symlinks", NULL}; + path_t path = PATH_T_INITIALIZE("removexattr", "path", 0, 1); + path_t attribute = PATH_T_INITIALIZE("removexattr", "attribute", 0, 0); + int follow_symlinks = 1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O&O&|$p:removexattr", _keywords, + path_converter, &path, path_converter, &attribute, &follow_symlinks)) + goto exit; + return_value = os_removexattr_impl(module, &path, &attribute, follow_symlinks); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + /* Cleanup for attribute */ + path_cleanup(&attribute); + + return return_value; +} + +static PyObject * +os_removexattr_impl(PyModuleDef *module, path_t *path, path_t *attribute, int follow_symlinks) +/*[clinic end generated code: output=8dfc715bf607c4cf input=cdb54834161e3329]*/ +{ + ssize_t result; + + if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks)) + return NULL; + + Py_BEGIN_ALLOW_THREADS; + if (path->fd > -1) + result = fremovexattr(path->fd, attribute->narrow); + else if (follow_symlinks) + result = removexattr(path->narrow, attribute->narrow); + else + result = lremovexattr(path->narrow, attribute->narrow); + Py_END_ALLOW_THREADS; + + if (result) { + return path_error(path); + } + + Py_RETURN_NONE; +} + + +/*[clinic input] +os.listxattr + + path: path_t(allow_fd=True, nullable=True) = None + * + follow_symlinks: bool = True + +Return a list of extended attributes on path. + +path may be either None, a string, or an open file descriptor. +if path is None, listxattr will examine the current directory. +If follow_symlinks is False, and the last element of the path is a symbolic + link, listxattr will examine the symbolic link itself instead of the file + the link points to. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_listxattr__doc__, +"listxattr($module, /, path=None, *, follow_symlinks=True)\n" +"--\n" +"\n" +"Return a list of extended attributes on path.\n" +"\n" +"path may be either None, a string, or an open file descriptor.\n" +"if path is None, listxattr will examine the current directory.\n" +"If follow_symlinks is False, and the last element of the path is a symbolic\n" +" link, listxattr will examine the symbolic link itself instead of the file\n" +" the link points to."); + +#define OS_LISTXATTR_METHODDEF \ + {"listxattr", (PyCFunction)os_listxattr, METH_VARARGS|METH_KEYWORDS, os_listxattr__doc__}, + +static PyObject * +os_listxattr_impl(PyModuleDef *module, path_t *path, int follow_symlinks); + +static PyObject * +os_listxattr(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "follow_symlinks", NULL}; + path_t path = PATH_T_INITIALIZE("listxattr", "path", 1, 1); + int follow_symlinks = 1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "|O&$p:listxattr", _keywords, + path_converter, &path, &follow_symlinks)) + goto exit; + return_value = os_listxattr_impl(module, &path, follow_symlinks); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +static PyObject * +os_listxattr_impl(PyModuleDef *module, path_t *path, int follow_symlinks) +/*[clinic end generated code: output=3104cafda1a3d887 input=08cca53ac0b07c13]*/ +{ + Py_ssize_t i; + PyObject *result = NULL; + const char *name; + char *buffer = NULL; + + if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks)) + goto exit; + + name = path->narrow ? path->narrow : "."; + + for (i = 0; ; i++) { + char *start, *trace, *end; + ssize_t length; + static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 }; + Py_ssize_t buffer_size = buffer_sizes[i]; + if (!buffer_size) { + /* ERANGE */ + path_error(path); + break; + } + buffer = PyMem_MALLOC(buffer_size); + if (!buffer) { + PyErr_NoMemory(); + break; + } + + Py_BEGIN_ALLOW_THREADS; + if (path->fd > -1) + length = flistxattr(path->fd, buffer, buffer_size); + else if (follow_symlinks) + length = listxattr(name, buffer, buffer_size); + else + length = llistxattr(name, buffer, buffer_size); + Py_END_ALLOW_THREADS; + + if (length < 0) { + if (errno == ERANGE) { + PyMem_FREE(buffer); + buffer = NULL; + continue; + } + path_error(path); + break; + } + + result = PyList_New(0); + if (!result) { + goto exit; + } + + end = buffer + length; + for (trace = start = buffer; trace != end; trace++) { + if (!*trace) { + int error; + PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start, + trace - start); + if (!attribute) { + Py_DECREF(result); + result = NULL; + goto exit; + } + error = PyList_Append(result, attribute); + Py_DECREF(attribute); + if (error) { + Py_DECREF(result); + result = NULL; + goto exit; + } + start = trace + 1; + } + } + break; + } +exit: + if (buffer) + PyMem_FREE(buffer); + return result; +} +#endif /* USE_XATTRS */ + + +/*[clinic input] +os.urandom + + size: Py_ssize_t + / + +Return a bytes object containing random bytes suitable for cryptographic use. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_urandom__doc__, +"urandom($module, size, /)\n" +"--\n" +"\n" +"Return a bytes object containing random bytes suitable for cryptographic use."); + +#define OS_URANDOM_METHODDEF \ + {"urandom", (PyCFunction)os_urandom, METH_VARARGS, os_urandom__doc__}, + +static PyObject * +os_urandom_impl(PyModuleDef *module, Py_ssize_t size); + +static PyObject * +os_urandom(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_ssize_t size; + + if (!PyArg_ParseTuple(args, + "n:urandom", + &size)) + goto exit; + return_value = os_urandom_impl(module, size); + +exit: + return return_value; +} + +static PyObject * +os_urandom_impl(PyModuleDef *module, Py_ssize_t size) +/*[clinic end generated code: output=5dbff582cab94cb9 input=4067cdb1b6776c29]*/ +{ + PyObject *bytes; + int result; + + if (size < 0) + return PyErr_Format(PyExc_ValueError, + "negative argument not allowed"); + bytes = PyBytes_FromStringAndSize(NULL, size); + if (bytes == NULL) + return NULL; + + result = _PyOS_URandom(PyBytes_AS_STRING(bytes), + PyBytes_GET_SIZE(bytes)); + if (result == -1) { + Py_DECREF(bytes); + return NULL; + } + return bytes; +} + +/* Terminal size querying */ + +static PyTypeObject TerminalSizeType; + +PyDoc_STRVAR(TerminalSize_docstring, + "A tuple of (columns, lines) for holding terminal window size"); + +static PyStructSequence_Field TerminalSize_fields[] = { + {"columns", "width of the terminal window in characters"}, + {"lines", "height of the terminal window in characters"}, + {NULL, NULL} +}; + +static PyStructSequence_Desc TerminalSize_desc = { + "os.terminal_size", + TerminalSize_docstring, + TerminalSize_fields, + 2, }; -static int -conv_sysconf_confname(PyObject *arg, int *valuep) +#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) +/* AC 3.5: fd should accept None */ +PyDoc_STRVAR(termsize__doc__, + "Return the size of the terminal window as (columns, lines).\n" \ + "\n" \ + "The optional argument fd (default standard output) specifies\n" \ + "which file descriptor should be queried.\n" \ + "\n" \ + "If the file descriptor is not connected to a terminal, an OSError\n" \ + "is thrown.\n" \ + "\n" \ + "This function will only be defined if an implementation is\n" \ + "available for this system.\n" \ + "\n" \ + "shutil.get_terminal_size is the high-level function which should \n" \ + "normally be used, os.get_terminal_size is the low-level implementation."); + +static PyObject* +get_terminal_size(PyObject *self, PyObject *args) { - return conv_confname(arg, valuep, posix_constants_sysconf, - sizeof(posix_constants_sysconf) - / sizeof(struct constdef)); -} + int columns, lines; + PyObject *termsize; -PyDoc_STRVAR(posix_sysconf__doc__, -"sysconf(name) -> integer\n\n\ -Return an integer-valued system configuration variable."); + int fd = fileno(stdout); + /* Under some conditions stdout may not be connected and + * fileno(stdout) may point to an invalid file descriptor. For example + * GUI apps don't have valid standard streams by default. + * + * If this happens, and the optional fd argument is not present, + * the ioctl below will fail returning EBADF. This is what we want. + */ -static PyObject * -posix_sysconf(PyObject *self, PyObject *args) -{ - PyObject *result = NULL; - int name; + if (!PyArg_ParseTuple(args, "|i", &fd)) + return NULL; - if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) { - long value; +#ifdef TERMSIZE_USE_IOCTL + { + struct winsize w; + if (ioctl(fd, TIOCGWINSZ, &w)) + return PyErr_SetFromErrno(PyExc_OSError); + columns = w.ws_col; + lines = w.ws_row; + } +#endif /* TERMSIZE_USE_IOCTL */ - errno = 0; - value = sysconf(name); - if (value == -1 && errno != 0) - posix_error(); - else - result = PyLong_FromLong(value); +#ifdef TERMSIZE_USE_CONIO + { + DWORD nhandle; + HANDLE handle; + CONSOLE_SCREEN_BUFFER_INFO csbi; + switch (fd) { + case 0: nhandle = STD_INPUT_HANDLE; + break; + case 1: nhandle = STD_OUTPUT_HANDLE; + break; + case 2: nhandle = STD_ERROR_HANDLE; + break; + default: + return PyErr_Format(PyExc_ValueError, "bad file descriptor"); + } + handle = GetStdHandle(nhandle); + if (handle == NULL) + return PyErr_Format(PyExc_OSError, "handle cannot be retrieved"); + if (handle == INVALID_HANDLE_VALUE) + return PyErr_SetFromWindowsErr(0); + + if (!GetConsoleScreenBufferInfo(handle, &csbi)) + return PyErr_SetFromWindowsErr(0); + + columns = csbi.srWindow.Right - csbi.srWindow.Left + 1; + lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1; } - return result; +#endif /* TERMSIZE_USE_CONIO */ + + termsize = PyStructSequence_New(&TerminalSizeType); + if (termsize == NULL) + return NULL; + PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns)); + PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines)); + if (PyErr_Occurred()) { + Py_DECREF(termsize); + return NULL; + } + return termsize; } -#endif +#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */ -/* This code is used to ensure that the tables of configuration value names - * are in sorted order as required by conv_confname(), and also to build the - * the exported dictionaries that are used to publish information about the - * names available on the host platform. - * - * Sorting the table at runtime ensures that the table is properly ordered - * when used, even for platforms we're not able to test on. It also makes - * it easier to add additional entries to the tables. - */ +/*[clinic input] +os.cpu_count -static int -cmp_constdefs(const void *v1, const void *v2) +Return the number of CPUs in the system; return None if indeterminable. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_cpu_count__doc__, +"cpu_count($module, /)\n" +"--\n" +"\n" +"Return the number of CPUs in the system; return None if indeterminable."); + +#define OS_CPU_COUNT_METHODDEF \ + {"cpu_count", (PyCFunction)os_cpu_count, METH_NOARGS, os_cpu_count__doc__}, + +static PyObject * +os_cpu_count_impl(PyModuleDef *module); + +static PyObject * +os_cpu_count(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) { - const struct constdef *c1 = - (const struct constdef *) v1; - const struct constdef *c2 = - (const struct constdef *) v2; + return os_cpu_count_impl(module); +} - return strcmp(c1->name, c2->name); +static PyObject * +os_cpu_count_impl(PyModuleDef *module) +/*[clinic end generated code: output=92e2a4a729eb7740 input=d55e2f8f3823a628]*/ +{ + int ncpu = 0; +#ifdef MS_WINDOWS + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + ncpu = sysinfo.dwNumberOfProcessors; +#elif defined(__hpux) + ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL); +#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN) + ncpu = sysconf(_SC_NPROCESSORS_ONLN); +#elif defined(__DragonFly__) || \ + defined(__OpenBSD__) || \ + defined(__FreeBSD__) || \ + defined(__NetBSD__) || \ + defined(__APPLE__) + int mib[2]; + size_t len = sizeof(ncpu); + mib[0] = CTL_HW; + mib[1] = HW_NCPU; + if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0) + ncpu = 0; +#endif + if (ncpu >= 1) + return PyLong_FromLong(ncpu); + else + Py_RETURN_NONE; } + +/*[clinic input] +os.get_inheritable -> bool + + fd: int + / + +Get the close-on-exe flag of the specified file descriptor. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_get_inheritable__doc__, +"get_inheritable($module, fd, /)\n" +"--\n" +"\n" +"Get the close-on-exe flag of the specified file descriptor."); + +#define OS_GET_INHERITABLE_METHODDEF \ + {"get_inheritable", (PyCFunction)os_get_inheritable, METH_VARARGS, os_get_inheritable__doc__}, + static int -setup_confname_table(struct constdef *table, size_t tablesize, - char *tablename, PyObject *module) +os_get_inheritable_impl(PyModuleDef *module, int fd); + +static PyObject * +os_get_inheritable(PyModuleDef *module, PyObject *args) { - PyObject *d = NULL; - size_t i; + PyObject *return_value = NULL; + int fd; + int _return_value; - qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs); - d = PyDict_New(); - if (d == NULL) - return -1; + if (!PyArg_ParseTuple(args, + "i:get_inheritable", + &fd)) + goto exit; + _return_value = os_get_inheritable_impl(module, fd); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyBool_FromLong((long)_return_value); - for (i=0; i < tablesize; ++i) { - PyObject *o = PyLong_FromLong(table[i].value); - if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) { - Py_XDECREF(o); - Py_DECREF(d); - return -1; - } - Py_DECREF(o); - } - return PyModule_AddObject(module, tablename, d); +exit: + return return_value; } -/* Return -1 on failure, 0 on success. */ static int -setup_confname_tables(PyObject *module) +os_get_inheritable_impl(PyModuleDef *module, int fd) +/*[clinic end generated code: output=261d1dd2b0dbdc35 input=89ac008dc9ab6b95]*/ { -#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF) - if (setup_confname_table(posix_constants_pathconf, - sizeof(posix_constants_pathconf) - / sizeof(struct constdef), - "pathconf_names", module)) - return -1; -#endif -#ifdef HAVE_CONFSTR - if (setup_confname_table(posix_constants_confstr, - sizeof(posix_constants_confstr) - / sizeof(struct constdef), - "confstr_names", module)) - return -1; -#endif -#ifdef HAVE_SYSCONF - if (setup_confname_table(posix_constants_sysconf, - sizeof(posix_constants_sysconf) - / sizeof(struct constdef), - "sysconf_names", module)) + if (!_PyVerify_fd(fd)){ + posix_error(); return -1; -#endif - return 0; + } + + return _Py_get_inheritable(fd); } -PyDoc_STRVAR(posix_abort__doc__, -"abort() -> does not return!\n\n\ -Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\ -in the hardest way possible on the hosting operating system."); +/*[clinic input] +os.set_inheritable + fd: int + inheritable: int + / + +Set the inheritable flag of the specified file descriptor. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_set_inheritable__doc__, +"set_inheritable($module, fd, inheritable, /)\n" +"--\n" +"\n" +"Set the inheritable flag of the specified file descriptor."); + +#define OS_SET_INHERITABLE_METHODDEF \ + {"set_inheritable", (PyCFunction)os_set_inheritable, METH_VARARGS, os_set_inheritable__doc__}, + +static PyObject * +os_set_inheritable_impl(PyModuleDef *module, int fd, int inheritable); static PyObject * -posix_abort(PyObject *self, PyObject *noargs) +os_set_inheritable(PyModuleDef *module, PyObject *args) { - abort(); - /*NOTREACHED*/ - Py_FatalError("abort() called from Python code didn't abort!"); - return NULL; + PyObject *return_value = NULL; + int fd; + int inheritable; + + if (!PyArg_ParseTuple(args, + "ii:set_inheritable", + &fd, &inheritable)) + goto exit; + return_value = os_set_inheritable_impl(module, fd, inheritable); + +exit: + return return_value; } -#ifdef MS_WINDOWS -PyDoc_STRVAR(win32_startfile__doc__, -"startfile(filepath [, operation]) - Start a file with its associated\n\ -application.\n\ -\n\ -When \"operation\" is not specified or \"open\", this acts like\n\ -double-clicking the file in Explorer, or giving the file name as an\n\ -argument to the DOS \"start\" command: the file is opened with whatever\n\ -application (if any) its extension is associated.\n\ -When another \"operation\" is given, it specifies what should be done with\n\ -the file. A typical operation is \"print\".\n\ -\n\ -startfile returns as soon as the associated application is launched.\n\ -There is no option to wait for the application to close, and no way\n\ -to retrieve the application's exit status.\n\ -\n\ -The filepath is relative to the current directory. If you want to use\n\ -an absolute path, make sure the first character is not a slash (\"/\");\n\ -the underlying Win32 ShellExecute function doesn't work if it is."); +static PyObject * +os_set_inheritable_impl(PyModuleDef *module, int fd, int inheritable) +/*[clinic end generated code: output=64dfe5e15c906539 input=9ceaead87a1e2402]*/ +{ + if (!_PyVerify_fd(fd)) + return posix_error(); + + if (_Py_set_inheritable(fd, inheritable, NULL) < 0) + return NULL; + Py_RETURN_NONE; +} + + +#ifdef MS_WINDOWS +/*[clinic input] +os.get_handle_inheritable -> bool + handle: Py_intptr_t + / + +Get the close-on-exe flag of the specified file descriptor. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_get_handle_inheritable__doc__, +"get_handle_inheritable($module, handle, /)\n" +"--\n" +"\n" +"Get the close-on-exe flag of the specified file descriptor."); + +#define OS_GET_HANDLE_INHERITABLE_METHODDEF \ + {"get_handle_inheritable", (PyCFunction)os_get_handle_inheritable, METH_VARARGS, os_get_handle_inheritable__doc__}, + +static int +os_get_handle_inheritable_impl(PyModuleDef *module, Py_intptr_t handle); static PyObject * -win32_startfile(PyObject *self, PyObject *args) +os_get_handle_inheritable(PyModuleDef *module, PyObject *args) { - PyObject *ofilepath; - char *filepath; - char *operation = NULL; - wchar_t *wpath, *woperation; - HINSTANCE rc; - - PyObject *unipath, *uoperation = NULL; - if (!PyArg_ParseTuple(args, "U|s:startfile", - &unipath, &operation)) { - PyErr_Clear(); - goto normal; - } + PyObject *return_value = NULL; + Py_intptr_t handle; + int _return_value; - if (operation) { - uoperation = PyUnicode_DecodeASCII(operation, - strlen(operation), NULL); - if (!uoperation) { - PyErr_Clear(); - operation = NULL; - goto normal; - } - } + if (!PyArg_ParseTuple(args, + "" _Py_PARSE_INTPTR ":get_handle_inheritable", + &handle)) + goto exit; + _return_value = os_get_handle_inheritable_impl(module, handle); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyBool_FromLong((long)_return_value); - wpath = PyUnicode_AsUnicode(unipath); - if (wpath == NULL) - goto normal; - if (uoperation) { - woperation = PyUnicode_AsUnicode(uoperation); - if (woperation == NULL) - goto normal; - } - else - woperation = NULL; +exit: + return return_value; +} - Py_BEGIN_ALLOW_THREADS - rc = ShellExecuteW((HWND)0, woperation, wpath, - NULL, NULL, SW_SHOWNORMAL); - Py_END_ALLOW_THREADS +static int +os_get_handle_inheritable_impl(PyModuleDef *module, Py_intptr_t handle) +/*[clinic end generated code: output=d5bf9d86900bf457 input=5f7759443aae3dc5]*/ +{ + DWORD flags; - Py_XDECREF(uoperation); - if (rc <= (HINSTANCE)32) { - win32_error_object("startfile", unipath); - return NULL; + if (!GetHandleInformation((HANDLE)handle, &flags)) { + PyErr_SetFromWindowsErr(0); + return -1; } - Py_INCREF(Py_None); - return Py_None; -normal: - if (!PyArg_ParseTuple(args, "O&|s:startfile", - PyUnicode_FSConverter, &ofilepath, - &operation)) - return NULL; - if (win32_warn_bytes_api()) { - Py_DECREF(ofilepath); - return NULL; - } - filepath = PyBytes_AsString(ofilepath); - Py_BEGIN_ALLOW_THREADS - rc = ShellExecute((HWND)0, operation, filepath, - NULL, NULL, SW_SHOWNORMAL); - Py_END_ALLOW_THREADS - if (rc <= (HINSTANCE)32) { - PyObject *errval = win32_error("startfile", filepath); - Py_DECREF(ofilepath); - return errval; - } - Py_DECREF(ofilepath); - Py_INCREF(Py_None); - return Py_None; + return flags & HANDLE_FLAG_INHERIT; } -#endif -#ifdef HAVE_GETLOADAVG -PyDoc_STRVAR(posix_getloadavg__doc__, -"getloadavg() -> (float, float, float)\n\n\ -Return the number of processes in the system run queue averaged over\n\ -the last 1, 5, and 15 minutes or raises OSError if the load average\n\ -was unobtainable"); -static PyObject * -posix_getloadavg(PyObject *self, PyObject *noargs) -{ - double loadavg[3]; - if (getloadavg(loadavg, 3)!=3) { - PyErr_SetString(PyExc_OSError, "Load averages are unobtainable"); - return NULL; - } else - return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]); -} -#endif +/*[clinic input] +os.set_handle_inheritable + handle: Py_intptr_t + inheritable: bool + / + +Set the inheritable flag of the specified handle. +[clinic start generated code]*/ + +PyDoc_STRVAR(os_set_handle_inheritable__doc__, +"set_handle_inheritable($module, handle, inheritable, /)\n" +"--\n" +"\n" +"Set the inheritable flag of the specified handle."); + +#define OS_SET_HANDLE_INHERITABLE_METHODDEF \ + {"set_handle_inheritable", (PyCFunction)os_set_handle_inheritable, METH_VARARGS, os_set_handle_inheritable__doc__}, -PyDoc_STRVAR(device_encoding__doc__, -"device_encoding(fd) -> str\n\n\ -Return a string describing the encoding of the device\n\ -if the output is a terminal; else return None."); +static PyObject * +os_set_handle_inheritable_impl(PyModuleDef *module, Py_intptr_t handle, int inheritable); static PyObject * -device_encoding(PyObject *self, PyObject *args) +os_set_handle_inheritable(PyModuleDef *module, PyObject *args) { - int fd; + PyObject *return_value = NULL; + Py_intptr_t handle; + int inheritable; - if (!PyArg_ParseTuple(args, "i:device_encoding", &fd)) - return NULL; + if (!PyArg_ParseTuple(args, + "" _Py_PARSE_INTPTR "p:set_handle_inheritable", + &handle, &inheritable)) + goto exit; + return_value = os_set_handle_inheritable_impl(module, handle, inheritable); - return _Py_device_encoding(fd); +exit: + return return_value; } -#ifdef HAVE_SETRESUID -PyDoc_STRVAR(posix_setresuid__doc__, -"setresuid(ruid, euid, suid)\n\n\ -Set the current process's real, effective, and saved user ids."); - -static PyObject* -posix_setresuid (PyObject *self, PyObject *args) +static PyObject * +os_set_handle_inheritable_impl(PyModuleDef *module, Py_intptr_t handle, int inheritable) +/*[clinic end generated code: output=ee5fcc6d9f0d4f8b input=e64b2b2730469def]*/ { - /* We assume uid_t is no larger than a long. */ - uid_t ruid, euid, suid; - if (!PyArg_ParseTuple(args, "O&O&O&:setresuid", - _Py_Uid_Converter, &ruid, - _Py_Uid_Converter, &euid, - _Py_Uid_Converter, &suid)) + DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0; + if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) { + PyErr_SetFromWindowsErr(0); return NULL; - if (setresuid(ruid, euid, suid) < 0) - return posix_error(); + } Py_RETURN_NONE; } -#endif +#endif /* MS_WINDOWS */ -#ifdef HAVE_SETRESGID -PyDoc_STRVAR(posix_setresgid__doc__, -"setresgid(rgid, egid, sgid)\n\n\ -Set the current process's real, effective, and saved group ids."); +#ifndef MS_WINDOWS +PyDoc_STRVAR(get_blocking__doc__, + "get_blocking(fd) -> bool\n" \ + "\n" \ + "Get the blocking mode of the file descriptor:\n" \ + "False if the O_NONBLOCK flag is set, True if the flag is cleared."); static PyObject* -posix_setresgid (PyObject *self, PyObject *args) +posix_get_blocking(PyObject *self, PyObject *args) { - gid_t rgid, egid, sgid; - if (!PyArg_ParseTuple(args, "O&O&O&:setresgid", - _Py_Gid_Converter, &rgid, - _Py_Gid_Converter, &egid, - _Py_Gid_Converter, &sgid)) + int fd; + int blocking; + + if (!PyArg_ParseTuple(args, "i:get_blocking", &fd)) return NULL; - if (setresgid(rgid, egid, sgid) < 0) + + if (!_PyVerify_fd(fd)) return posix_error(); - Py_RETURN_NONE; + + blocking = _Py_get_blocking(fd); + if (blocking < 0) + return NULL; + return PyBool_FromLong(blocking); } -#endif -#ifdef HAVE_GETRESUID -PyDoc_STRVAR(posix_getresuid__doc__, -"getresuid() -> (ruid, euid, suid)\n\n\ -Get tuple of the current process's real, effective, and saved user ids."); +PyDoc_STRVAR(set_blocking__doc__, + "set_blocking(fd, blocking)\n" \ + "\n" \ + "Set the blocking mode of the specified file descriptor.\n" \ + "Set the O_NONBLOCK flag if blocking is False,\n" \ + "clear the O_NONBLOCK flag otherwise."); static PyObject* -posix_getresuid (PyObject *self, PyObject *noargs) +posix_set_blocking(PyObject *self, PyObject *args) { - uid_t ruid, euid, suid; - if (getresuid(&ruid, &euid, &suid) < 0) - return posix_error(); - return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid), - _PyLong_FromUid(euid), - _PyLong_FromUid(suid)); -} -#endif + int fd, blocking; -#ifdef HAVE_GETRESGID -PyDoc_STRVAR(posix_getresgid__doc__, -"getresgid() -> (rgid, egid, sgid)\n\n\ -Get tuple of the current process's real, effective, and saved group ids."); + if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking)) + return NULL; -static PyObject* -posix_getresgid (PyObject *self, PyObject *noargs) -{ - uid_t rgid, egid, sgid; - if (getresgid(&rgid, &egid, &sgid) < 0) + if (!_PyVerify_fd(fd)) return posix_error(); - return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid), - _PyLong_FromGid(egid), - _PyLong_FromGid(sgid)); + + if (_Py_set_blocking(fd, blocking) < 0) + return NULL; + Py_RETURN_NONE; } -#endif +#endif /* !MS_WINDOWS */ -#ifdef USE_XATTRS -PyDoc_STRVAR(posix_getxattr__doc__, -"getxattr(path, attribute, *, follow_symlinks=True) -> value\n\n\ -Return the value of extended attribute attribute on path.\n\ -\n\ -path may be either a string or an open file descriptor.\n\ -If follow_symlinks is False, and the last element of the path is a symbolic\n\ - link, getxattr will examine the symbolic link itself instead of the file\n\ - the link points to."); +/*[clinic input] +dump buffer +[clinic start generated code]*/ -static PyObject * -posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs) -{ - path_t path; - path_t attribute; - int follow_symlinks = 1; - PyObject *buffer = NULL; - int i; - static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL}; +#ifndef OS_TTYNAME_METHODDEF + #define OS_TTYNAME_METHODDEF +#endif /* !defined(OS_TTYNAME_METHODDEF) */ - memset(&path, 0, sizeof(path)); - memset(&attribute, 0, sizeof(attribute)); - path.function_name = "getxattr"; - attribute.function_name = "getxattr"; - path.allow_fd = 1; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:getxattr", keywords, - path_converter, &path, - path_converter, &attribute, - &follow_symlinks)) - return NULL; +#ifndef OS_CTERMID_METHODDEF + #define OS_CTERMID_METHODDEF +#endif /* !defined(OS_CTERMID_METHODDEF) */ - if (fd_and_follow_symlinks_invalid("getxattr", path.fd, follow_symlinks)) - goto exit; +#ifndef OS_FCHDIR_METHODDEF + #define OS_FCHDIR_METHODDEF +#endif /* !defined(OS_FCHDIR_METHODDEF) */ - for (i = 0; ; i++) { - void *ptr; - ssize_t result; - static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0}; - Py_ssize_t buffer_size = buffer_sizes[i]; - if (!buffer_size) { - path_error(&path); - goto exit; - } - buffer = PyBytes_FromStringAndSize(NULL, buffer_size); - if (!buffer) - goto exit; - ptr = PyBytes_AS_STRING(buffer); +#ifndef OS_FCHMOD_METHODDEF + #define OS_FCHMOD_METHODDEF +#endif /* !defined(OS_FCHMOD_METHODDEF) */ - Py_BEGIN_ALLOW_THREADS; - if (path.fd >= 0) - result = fgetxattr(path.fd, attribute.narrow, ptr, buffer_size); - else if (follow_symlinks) - result = getxattr(path.narrow, attribute.narrow, ptr, buffer_size); - else - result = lgetxattr(path.narrow, attribute.narrow, ptr, buffer_size); - Py_END_ALLOW_THREADS; +#ifndef OS_LCHMOD_METHODDEF + #define OS_LCHMOD_METHODDEF +#endif /* !defined(OS_LCHMOD_METHODDEF) */ - if (result < 0) { - Py_DECREF(buffer); - buffer = NULL; - if (errno == ERANGE) - continue; - path_error(&path); - goto exit; - } +#ifndef OS_CHFLAGS_METHODDEF + #define OS_CHFLAGS_METHODDEF +#endif /* !defined(OS_CHFLAGS_METHODDEF) */ - if (result != buffer_size) { - /* Can only shrink. */ - _PyBytes_Resize(&buffer, result); - } - break; - } +#ifndef OS_LCHFLAGS_METHODDEF + #define OS_LCHFLAGS_METHODDEF +#endif /* !defined(OS_LCHFLAGS_METHODDEF) */ -exit: - path_cleanup(&path); - path_cleanup(&attribute); - return buffer; -} +#ifndef OS_CHROOT_METHODDEF + #define OS_CHROOT_METHODDEF +#endif /* !defined(OS_CHROOT_METHODDEF) */ -PyDoc_STRVAR(posix_setxattr__doc__, -"setxattr(path, attribute, value, flags=0, *, follow_symlinks=True)\n\n\ -Set extended attribute attribute on path to value.\n\ -path may be either a string or an open file descriptor.\n\ -If follow_symlinks is False, and the last element of the path is a symbolic\n\ - link, setxattr will modify the symbolic link itself instead of the file\n\ - the link points to."); +#ifndef OS_FSYNC_METHODDEF + #define OS_FSYNC_METHODDEF +#endif /* !defined(OS_FSYNC_METHODDEF) */ -static PyObject * -posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs) -{ - path_t path; - path_t attribute; - Py_buffer value; - int flags = 0; - int follow_symlinks = 1; - int result; - PyObject *return_value = NULL; - static char *keywords[] = {"path", "attribute", "value", - "flags", "follow_symlinks", NULL}; +#ifndef OS_SYNC_METHODDEF + #define OS_SYNC_METHODDEF +#endif /* !defined(OS_SYNC_METHODDEF) */ - memset(&path, 0, sizeof(path)); - path.function_name = "setxattr"; - path.allow_fd = 1; - memset(&attribute, 0, sizeof(attribute)); - memset(&value, 0, sizeof(value)); - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&y*|i$p:setxattr", - keywords, - path_converter, &path, - path_converter, &attribute, - &value, &flags, - &follow_symlinks)) - return NULL; +#ifndef OS_FDATASYNC_METHODDEF + #define OS_FDATASYNC_METHODDEF +#endif /* !defined(OS_FDATASYNC_METHODDEF) */ - if (fd_and_follow_symlinks_invalid("setxattr", path.fd, follow_symlinks)) - goto exit; +#ifndef OS_CHOWN_METHODDEF + #define OS_CHOWN_METHODDEF +#endif /* !defined(OS_CHOWN_METHODDEF) */ + +#ifndef OS_FCHOWN_METHODDEF + #define OS_FCHOWN_METHODDEF +#endif /* !defined(OS_FCHOWN_METHODDEF) */ + +#ifndef OS_LCHOWN_METHODDEF + #define OS_LCHOWN_METHODDEF +#endif /* !defined(OS_LCHOWN_METHODDEF) */ + +#ifndef OS_LINK_METHODDEF + #define OS_LINK_METHODDEF +#endif /* !defined(OS_LINK_METHODDEF) */ + +#ifndef OS__GETFINALPATHNAME_METHODDEF + #define OS__GETFINALPATHNAME_METHODDEF +#endif /* !defined(OS__GETFINALPATHNAME_METHODDEF) */ + +#ifndef OS__GETVOLUMEPATHNAME_METHODDEF + #define OS__GETVOLUMEPATHNAME_METHODDEF +#endif /* !defined(OS__GETVOLUMEPATHNAME_METHODDEF) */ + +#ifndef OS_NICE_METHODDEF + #define OS_NICE_METHODDEF +#endif /* !defined(OS_NICE_METHODDEF) */ + +#ifndef OS_GETPRIORITY_METHODDEF + #define OS_GETPRIORITY_METHODDEF +#endif /* !defined(OS_GETPRIORITY_METHODDEF) */ + +#ifndef OS_SETPRIORITY_METHODDEF + #define OS_SETPRIORITY_METHODDEF +#endif /* !defined(OS_SETPRIORITY_METHODDEF) */ + +#ifndef OS_SYSTEM_METHODDEF + #define OS_SYSTEM_METHODDEF +#endif /* !defined(OS_SYSTEM_METHODDEF) */ + +#ifndef OS_SYSTEM_METHODDEF + #define OS_SYSTEM_METHODDEF +#endif /* !defined(OS_SYSTEM_METHODDEF) */ + +#ifndef OS_UNAME_METHODDEF + #define OS_UNAME_METHODDEF +#endif /* !defined(OS_UNAME_METHODDEF) */ + +#ifndef OS_EXECV_METHODDEF + #define OS_EXECV_METHODDEF +#endif /* !defined(OS_EXECV_METHODDEF) */ + +#ifndef OS_EXECVE_METHODDEF + #define OS_EXECVE_METHODDEF +#endif /* !defined(OS_EXECVE_METHODDEF) */ + +#ifndef OS_SPAWNV_METHODDEF + #define OS_SPAWNV_METHODDEF +#endif /* !defined(OS_SPAWNV_METHODDEF) */ + +#ifndef OS_SPAWNVE_METHODDEF + #define OS_SPAWNVE_METHODDEF +#endif /* !defined(OS_SPAWNVE_METHODDEF) */ + +#ifndef OS_FORK1_METHODDEF + #define OS_FORK1_METHODDEF +#endif /* !defined(OS_FORK1_METHODDEF) */ + +#ifndef OS_FORK_METHODDEF + #define OS_FORK_METHODDEF +#endif /* !defined(OS_FORK_METHODDEF) */ + +#ifndef OS_SCHED_GET_PRIORITY_MAX_METHODDEF + #define OS_SCHED_GET_PRIORITY_MAX_METHODDEF +#endif /* !defined(OS_SCHED_GET_PRIORITY_MAX_METHODDEF) */ + +#ifndef OS_SCHED_GET_PRIORITY_MIN_METHODDEF + #define OS_SCHED_GET_PRIORITY_MIN_METHODDEF +#endif /* !defined(OS_SCHED_GET_PRIORITY_MIN_METHODDEF) */ + +#ifndef OS_SCHED_GETSCHEDULER_METHODDEF + #define OS_SCHED_GETSCHEDULER_METHODDEF +#endif /* !defined(OS_SCHED_GETSCHEDULER_METHODDEF) */ + +#ifndef OS_SCHED_SETSCHEDULER_METHODDEF + #define OS_SCHED_SETSCHEDULER_METHODDEF +#endif /* !defined(OS_SCHED_SETSCHEDULER_METHODDEF) */ + +#ifndef OS_SCHED_GETPARAM_METHODDEF + #define OS_SCHED_GETPARAM_METHODDEF +#endif /* !defined(OS_SCHED_GETPARAM_METHODDEF) */ + +#ifndef OS_SCHED_SETPARAM_METHODDEF + #define OS_SCHED_SETPARAM_METHODDEF +#endif /* !defined(OS_SCHED_SETPARAM_METHODDEF) */ + +#ifndef OS_SCHED_RR_GET_INTERVAL_METHODDEF + #define OS_SCHED_RR_GET_INTERVAL_METHODDEF +#endif /* !defined(OS_SCHED_RR_GET_INTERVAL_METHODDEF) */ + +#ifndef OS_SCHED_YIELD_METHODDEF + #define OS_SCHED_YIELD_METHODDEF +#endif /* !defined(OS_SCHED_YIELD_METHODDEF) */ + +#ifndef OS_SCHED_SETAFFINITY_METHODDEF + #define OS_SCHED_SETAFFINITY_METHODDEF +#endif /* !defined(OS_SCHED_SETAFFINITY_METHODDEF) */ + +#ifndef OS_SCHED_GETAFFINITY_METHODDEF + #define OS_SCHED_GETAFFINITY_METHODDEF +#endif /* !defined(OS_SCHED_GETAFFINITY_METHODDEF) */ + +#ifndef OS_OPENPTY_METHODDEF + #define OS_OPENPTY_METHODDEF +#endif /* !defined(OS_OPENPTY_METHODDEF) */ + +#ifndef OS_FORKPTY_METHODDEF + #define OS_FORKPTY_METHODDEF +#endif /* !defined(OS_FORKPTY_METHODDEF) */ + +#ifndef OS_GETEGID_METHODDEF + #define OS_GETEGID_METHODDEF +#endif /* !defined(OS_GETEGID_METHODDEF) */ + +#ifndef OS_GETEUID_METHODDEF + #define OS_GETEUID_METHODDEF +#endif /* !defined(OS_GETEUID_METHODDEF) */ + +#ifndef OS_GETGID_METHODDEF + #define OS_GETGID_METHODDEF +#endif /* !defined(OS_GETGID_METHODDEF) */ + +#ifndef OS_GETGROUPS_METHODDEF + #define OS_GETGROUPS_METHODDEF +#endif /* !defined(OS_GETGROUPS_METHODDEF) */ + +#ifndef OS_GETPGID_METHODDEF + #define OS_GETPGID_METHODDEF +#endif /* !defined(OS_GETPGID_METHODDEF) */ + +#ifndef OS_GETPGRP_METHODDEF + #define OS_GETPGRP_METHODDEF +#endif /* !defined(OS_GETPGRP_METHODDEF) */ + +#ifndef OS_SETPGRP_METHODDEF + #define OS_SETPGRP_METHODDEF +#endif /* !defined(OS_SETPGRP_METHODDEF) */ + +#ifndef OS_GETPPID_METHODDEF + #define OS_GETPPID_METHODDEF +#endif /* !defined(OS_GETPPID_METHODDEF) */ + +#ifndef OS_GETLOGIN_METHODDEF + #define OS_GETLOGIN_METHODDEF +#endif /* !defined(OS_GETLOGIN_METHODDEF) */ + +#ifndef OS_GETUID_METHODDEF + #define OS_GETUID_METHODDEF +#endif /* !defined(OS_GETUID_METHODDEF) */ + +#ifndef OS_KILL_METHODDEF + #define OS_KILL_METHODDEF +#endif /* !defined(OS_KILL_METHODDEF) */ + +#ifndef OS_KILLPG_METHODDEF + #define OS_KILLPG_METHODDEF +#endif /* !defined(OS_KILLPG_METHODDEF) */ - Py_BEGIN_ALLOW_THREADS; - if (path.fd > -1) - result = fsetxattr(path.fd, attribute.narrow, - value.buf, value.len, flags); - else if (follow_symlinks) - result = setxattr(path.narrow, attribute.narrow, - value.buf, value.len, flags); - else - result = lsetxattr(path.narrow, attribute.narrow, - value.buf, value.len, flags); - Py_END_ALLOW_THREADS; +#ifndef OS_PLOCK_METHODDEF + #define OS_PLOCK_METHODDEF +#endif /* !defined(OS_PLOCK_METHODDEF) */ - if (result) { - return_value = path_error(&path); - goto exit; - } +#ifndef OS_SETUID_METHODDEF + #define OS_SETUID_METHODDEF +#endif /* !defined(OS_SETUID_METHODDEF) */ - return_value = Py_None; - Py_INCREF(return_value); +#ifndef OS_SETEUID_METHODDEF + #define OS_SETEUID_METHODDEF +#endif /* !defined(OS_SETEUID_METHODDEF) */ -exit: - path_cleanup(&path); - path_cleanup(&attribute); - PyBuffer_Release(&value); +#ifndef OS_SETEGID_METHODDEF + #define OS_SETEGID_METHODDEF +#endif /* !defined(OS_SETEGID_METHODDEF) */ - return return_value; -} +#ifndef OS_SETREUID_METHODDEF + #define OS_SETREUID_METHODDEF +#endif /* !defined(OS_SETREUID_METHODDEF) */ -PyDoc_STRVAR(posix_removexattr__doc__, -"removexattr(path, attribute, *, follow_symlinks=True)\n\n\ -Remove extended attribute attribute on path.\n\ -path may be either a string or an open file descriptor.\n\ -If follow_symlinks is False, and the last element of the path is a symbolic\n\ - link, removexattr will modify the symbolic link itself instead of the file\n\ - the link points to."); +#ifndef OS_SETREGID_METHODDEF + #define OS_SETREGID_METHODDEF +#endif /* !defined(OS_SETREGID_METHODDEF) */ -static PyObject * -posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs) -{ - path_t path; - path_t attribute; - int follow_symlinks = 1; - int result; - PyObject *return_value = NULL; - static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL}; +#ifndef OS_SETGID_METHODDEF + #define OS_SETGID_METHODDEF +#endif /* !defined(OS_SETGID_METHODDEF) */ - memset(&path, 0, sizeof(path)); - path.function_name = "removexattr"; - memset(&attribute, 0, sizeof(attribute)); - attribute.function_name = "removexattr"; - path.allow_fd = 1; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:removexattr", - keywords, - path_converter, &path, - path_converter, &attribute, - &follow_symlinks)) - return NULL; +#ifndef OS_SETGROUPS_METHODDEF + #define OS_SETGROUPS_METHODDEF +#endif /* !defined(OS_SETGROUPS_METHODDEF) */ - if (fd_and_follow_symlinks_invalid("removexattr", path.fd, follow_symlinks)) - goto exit; +#ifndef OS_WAIT3_METHODDEF + #define OS_WAIT3_METHODDEF +#endif /* !defined(OS_WAIT3_METHODDEF) */ - Py_BEGIN_ALLOW_THREADS; - if (path.fd > -1) - result = fremovexattr(path.fd, attribute.narrow); - else if (follow_symlinks) - result = removexattr(path.narrow, attribute.narrow); - else - result = lremovexattr(path.narrow, attribute.narrow); - Py_END_ALLOW_THREADS; +#ifndef OS_WAIT4_METHODDEF + #define OS_WAIT4_METHODDEF +#endif /* !defined(OS_WAIT4_METHODDEF) */ - if (result) { - return_value = path_error(&path); - goto exit; - } +#ifndef OS_WAITID_METHODDEF + #define OS_WAITID_METHODDEF +#endif /* !defined(OS_WAITID_METHODDEF) */ - return_value = Py_None; - Py_INCREF(return_value); +#ifndef OS_WAITPID_METHODDEF + #define OS_WAITPID_METHODDEF +#endif /* !defined(OS_WAITPID_METHODDEF) */ -exit: - path_cleanup(&path); - path_cleanup(&attribute); +#ifndef OS_WAITPID_METHODDEF + #define OS_WAITPID_METHODDEF +#endif /* !defined(OS_WAITPID_METHODDEF) */ - return return_value; -} +#ifndef OS_WAIT_METHODDEF + #define OS_WAIT_METHODDEF +#endif /* !defined(OS_WAIT_METHODDEF) */ -PyDoc_STRVAR(posix_listxattr__doc__, -"listxattr(path='.', *, follow_symlinks=True)\n\n\ -Return a list of extended attributes on path.\n\ -\n\ -path may be either None, a string, or an open file descriptor.\n\ -if path is None, listxattr will examine the current directory.\n\ -If follow_symlinks is False, and the last element of the path is a symbolic\n\ - link, listxattr will examine the symbolic link itself instead of the file\n\ - the link points to."); +#ifndef OS_SYMLINK_METHODDEF + #define OS_SYMLINK_METHODDEF +#endif /* !defined(OS_SYMLINK_METHODDEF) */ -static PyObject * -posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs) -{ - path_t path; - int follow_symlinks = 1; - Py_ssize_t i; - PyObject *result = NULL; - char *buffer = NULL; - char *name; - static char *keywords[] = {"path", "follow_symlinks", NULL}; +#ifndef OS_TIMES_METHODDEF + #define OS_TIMES_METHODDEF +#endif /* !defined(OS_TIMES_METHODDEF) */ - memset(&path, 0, sizeof(path)); - path.function_name = "listxattr"; - path.allow_fd = 1; - path.fd = -1; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&$p:listxattr", keywords, - path_converter, &path, - &follow_symlinks)) - return NULL; +#ifndef OS_GETSID_METHODDEF + #define OS_GETSID_METHODDEF +#endif /* !defined(OS_GETSID_METHODDEF) */ - if (fd_and_follow_symlinks_invalid("listxattr", path.fd, follow_symlinks)) - goto exit; +#ifndef OS_SETSID_METHODDEF + #define OS_SETSID_METHODDEF +#endif /* !defined(OS_SETSID_METHODDEF) */ - name = path.narrow ? path.narrow : "."; - for (i = 0; ; i++) { - char *start, *trace, *end; - ssize_t length; - static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 }; - Py_ssize_t buffer_size = buffer_sizes[i]; - if (!buffer_size) { - /* ERANGE */ - path_error(&path); - break; - } - buffer = PyMem_MALLOC(buffer_size); - if (!buffer) { - PyErr_NoMemory(); - break; - } +#ifndef OS_SETPGID_METHODDEF + #define OS_SETPGID_METHODDEF +#endif /* !defined(OS_SETPGID_METHODDEF) */ - Py_BEGIN_ALLOW_THREADS; - if (path.fd > -1) - length = flistxattr(path.fd, buffer, buffer_size); - else if (follow_symlinks) - length = listxattr(name, buffer, buffer_size); - else - length = llistxattr(name, buffer, buffer_size); - Py_END_ALLOW_THREADS; +#ifndef OS_TCGETPGRP_METHODDEF + #define OS_TCGETPGRP_METHODDEF +#endif /* !defined(OS_TCGETPGRP_METHODDEF) */ - if (length < 0) { - if (errno == ERANGE) { - PyMem_FREE(buffer); - buffer = NULL; - continue; - } - path_error(&path); - break; - } +#ifndef OS_TCSETPGRP_METHODDEF + #define OS_TCSETPGRP_METHODDEF +#endif /* !defined(OS_TCSETPGRP_METHODDEF) */ - result = PyList_New(0); - if (!result) { - goto exit; - } +#ifndef OS_LOCKF_METHODDEF + #define OS_LOCKF_METHODDEF +#endif /* !defined(OS_LOCKF_METHODDEF) */ - end = buffer + length; - for (trace = start = buffer; trace != end; trace++) { - if (!*trace) { - int error; - PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start, - trace - start); - if (!attribute) { - Py_DECREF(result); - result = NULL; - goto exit; - } - error = PyList_Append(result, attribute); - Py_DECREF(attribute); - if (error) { - Py_DECREF(result); - result = NULL; - goto exit; - } - start = trace + 1; - } - } - break; - } -exit: - path_cleanup(&path); - if (buffer) - PyMem_FREE(buffer); - return result; -} +#ifndef OS_READV_METHODDEF + #define OS_READV_METHODDEF +#endif /* !defined(OS_READV_METHODDEF) */ -#endif /* USE_XATTRS */ +#ifndef OS_PREAD_METHODDEF + #define OS_PREAD_METHODDEF +#endif /* !defined(OS_PREAD_METHODDEF) */ +#ifndef OS_PIPE_METHODDEF + #define OS_PIPE_METHODDEF +#endif /* !defined(OS_PIPE_METHODDEF) */ -PyDoc_STRVAR(posix_urandom__doc__, -"urandom(n) -> str\n\n\ -Return n random bytes suitable for cryptographic use."); +#ifndef OS_PIPE2_METHODDEF + #define OS_PIPE2_METHODDEF +#endif /* !defined(OS_PIPE2_METHODDEF) */ -static PyObject * -posix_urandom(PyObject *self, PyObject *args) -{ - Py_ssize_t size; - PyObject *result; - int ret; +#ifndef OS_WRITEV_METHODDEF + #define OS_WRITEV_METHODDEF +#endif /* !defined(OS_WRITEV_METHODDEF) */ - /* Read arguments */ - if (!PyArg_ParseTuple(args, "n:urandom", &size)) - return NULL; - if (size < 0) - return PyErr_Format(PyExc_ValueError, - "negative argument not allowed"); - result = PyBytes_FromStringAndSize(NULL, size); - if (result == NULL) - return NULL; +#ifndef OS_PWRITE_METHODDEF + #define OS_PWRITE_METHODDEF +#endif /* !defined(OS_PWRITE_METHODDEF) */ - ret = _PyOS_URandom(PyBytes_AS_STRING(result), - PyBytes_GET_SIZE(result)); - if (ret == -1) { - Py_DECREF(result); - return NULL; - } - return result; -} +#ifndef OS_MKFIFO_METHODDEF + #define OS_MKFIFO_METHODDEF +#endif /* !defined(OS_MKFIFO_METHODDEF) */ -/* Terminal size querying */ +#ifndef OS_MKNOD_METHODDEF + #define OS_MKNOD_METHODDEF +#endif /* !defined(OS_MKNOD_METHODDEF) */ -static PyTypeObject TerminalSizeType; +#ifndef OS_MAJOR_METHODDEF + #define OS_MAJOR_METHODDEF +#endif /* !defined(OS_MAJOR_METHODDEF) */ -PyDoc_STRVAR(TerminalSize_docstring, - "A tuple of (columns, lines) for holding terminal window size"); +#ifndef OS_MINOR_METHODDEF + #define OS_MINOR_METHODDEF +#endif /* !defined(OS_MINOR_METHODDEF) */ -static PyStructSequence_Field TerminalSize_fields[] = { - {"columns", "width of the terminal window in characters"}, - {"lines", "height of the terminal window in characters"}, - {NULL, NULL} -}; +#ifndef OS_MAKEDEV_METHODDEF + #define OS_MAKEDEV_METHODDEF +#endif /* !defined(OS_MAKEDEV_METHODDEF) */ -static PyStructSequence_Desc TerminalSize_desc = { - "os.terminal_size", - TerminalSize_docstring, - TerminalSize_fields, - 2, -}; +#ifndef OS_FTRUNCATE_METHODDEF + #define OS_FTRUNCATE_METHODDEF +#endif /* !defined(OS_FTRUNCATE_METHODDEF) */ -#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) -PyDoc_STRVAR(termsize__doc__, - "Return the size of the terminal window as (columns, lines).\n" \ - "\n" \ - "The optional argument fd (default standard output) specifies\n" \ - "which file descriptor should be queried.\n" \ - "\n" \ - "If the file descriptor is not connected to a terminal, an OSError\n" \ - "is thrown.\n" \ - "\n" \ - "This function will only be defined if an implementation is\n" \ - "available for this system.\n" \ - "\n" \ - "shutil.get_terminal_size is the high-level function which should \n" \ - "normally be used, os.get_terminal_size is the low-level implementation."); +#ifndef OS_TRUNCATE_METHODDEF + #define OS_TRUNCATE_METHODDEF +#endif /* !defined(OS_TRUNCATE_METHODDEF) */ -static PyObject* -get_terminal_size(PyObject *self, PyObject *args) -{ - int columns, lines; - PyObject *termsize; +#ifndef OS_POSIX_FALLOCATE_METHODDEF + #define OS_POSIX_FALLOCATE_METHODDEF +#endif /* !defined(OS_POSIX_FALLOCATE_METHODDEF) */ - int fd = fileno(stdout); - /* Under some conditions stdout may not be connected and - * fileno(stdout) may point to an invalid file descriptor. For example - * GUI apps don't have valid standard streams by default. - * - * If this happens, and the optional fd argument is not present, - * the ioctl below will fail returning EBADF. This is what we want. - */ +#ifndef OS_POSIX_FADVISE_METHODDEF + #define OS_POSIX_FADVISE_METHODDEF +#endif /* !defined(OS_POSIX_FADVISE_METHODDEF) */ - if (!PyArg_ParseTuple(args, "|i", &fd)) - return NULL; +#ifndef OS_PUTENV_METHODDEF + #define OS_PUTENV_METHODDEF +#endif /* !defined(OS_PUTENV_METHODDEF) */ -#ifdef TERMSIZE_USE_IOCTL - { - struct winsize w; - if (ioctl(fd, TIOCGWINSZ, &w)) - return PyErr_SetFromErrno(PyExc_OSError); - columns = w.ws_col; - lines = w.ws_row; - } -#endif /* TERMSIZE_USE_IOCTL */ +#ifndef OS_PUTENV_METHODDEF + #define OS_PUTENV_METHODDEF +#endif /* !defined(OS_PUTENV_METHODDEF) */ -#ifdef TERMSIZE_USE_CONIO - { - DWORD nhandle; - HANDLE handle; - CONSOLE_SCREEN_BUFFER_INFO csbi; - switch (fd) { - case 0: nhandle = STD_INPUT_HANDLE; - break; - case 1: nhandle = STD_OUTPUT_HANDLE; - break; - case 2: nhandle = STD_ERROR_HANDLE; - break; - default: - return PyErr_Format(PyExc_ValueError, "bad file descriptor"); - } - handle = GetStdHandle(nhandle); - if (handle == NULL) - return PyErr_Format(PyExc_OSError, "handle cannot be retrieved"); - if (handle == INVALID_HANDLE_VALUE) - return PyErr_SetFromWindowsErr(0); +#ifndef OS_UNSETENV_METHODDEF + #define OS_UNSETENV_METHODDEF +#endif /* !defined(OS_UNSETENV_METHODDEF) */ - if (!GetConsoleScreenBufferInfo(handle, &csbi)) - return PyErr_SetFromWindowsErr(0); +#ifndef OS_WCOREDUMP_METHODDEF + #define OS_WCOREDUMP_METHODDEF +#endif /* !defined(OS_WCOREDUMP_METHODDEF) */ - columns = csbi.srWindow.Right - csbi.srWindow.Left + 1; - lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1; - } -#endif /* TERMSIZE_USE_CONIO */ +#ifndef OS_WIFCONTINUED_METHODDEF + #define OS_WIFCONTINUED_METHODDEF +#endif /* !defined(OS_WIFCONTINUED_METHODDEF) */ - termsize = PyStructSequence_New(&TerminalSizeType); - if (termsize == NULL) - return NULL; - PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns)); - PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines)); - if (PyErr_Occurred()) { - Py_DECREF(termsize); - return NULL; - } - return termsize; -} -#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */ +#ifndef OS_WIFSTOPPED_METHODDEF + #define OS_WIFSTOPPED_METHODDEF +#endif /* !defined(OS_WIFSTOPPED_METHODDEF) */ -PyDoc_STRVAR(posix_cpu_count__doc__, -"cpu_count() -> integer\n\n\ -Return the number of CPUs in the system, or None if this value cannot be\n\ -established."); +#ifndef OS_WIFSIGNALED_METHODDEF + #define OS_WIFSIGNALED_METHODDEF +#endif /* !defined(OS_WIFSIGNALED_METHODDEF) */ -static PyObject * -posix_cpu_count(PyObject *self) -{ - int ncpu = 0; -#ifdef MS_WINDOWS - SYSTEM_INFO sysinfo; - GetSystemInfo(&sysinfo); - ncpu = sysinfo.dwNumberOfProcessors; -#elif defined(__hpux) - ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL); -#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN) - ncpu = sysconf(_SC_NPROCESSORS_ONLN); -#elif defined(__DragonFly__) || \ - defined(__OpenBSD__) || \ - defined(__FreeBSD__) || \ - defined(__NetBSD__) || \ - defined(__APPLE__) - int mib[2]; - size_t len = sizeof(ncpu); - mib[0] = CTL_HW; - mib[1] = HW_NCPU; - if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0) - ncpu = 0; -#endif - if (ncpu >= 1) - return PyLong_FromLong(ncpu); - else - Py_RETURN_NONE; -} +#ifndef OS_WIFEXITED_METHODDEF + #define OS_WIFEXITED_METHODDEF +#endif /* !defined(OS_WIFEXITED_METHODDEF) */ -PyDoc_STRVAR(get_inheritable__doc__, - "get_inheritable(fd) -> bool\n" \ - "\n" \ - "Get the close-on-exe flag of the specified file descriptor."); +#ifndef OS_WEXITSTATUS_METHODDEF + #define OS_WEXITSTATUS_METHODDEF +#endif /* !defined(OS_WEXITSTATUS_METHODDEF) */ -static PyObject* -posix_get_inheritable(PyObject *self, PyObject *args) -{ - int fd; - int inheritable; +#ifndef OS_WTERMSIG_METHODDEF + #define OS_WTERMSIG_METHODDEF +#endif /* !defined(OS_WTERMSIG_METHODDEF) */ - if (!PyArg_ParseTuple(args, "i:get_inheritable", &fd)) - return NULL; +#ifndef OS_WSTOPSIG_METHODDEF + #define OS_WSTOPSIG_METHODDEF +#endif /* !defined(OS_WSTOPSIG_METHODDEF) */ - if (!_PyVerify_fd(fd)) - return posix_error(); +#ifndef OS_FSTATVFS_METHODDEF + #define OS_FSTATVFS_METHODDEF +#endif /* !defined(OS_FSTATVFS_METHODDEF) */ - inheritable = _Py_get_inheritable(fd); - if (inheritable < 0) - return NULL; - return PyBool_FromLong(inheritable); -} +#ifndef OS_STATVFS_METHODDEF + #define OS_STATVFS_METHODDEF +#endif /* !defined(OS_STATVFS_METHODDEF) */ -PyDoc_STRVAR(set_inheritable__doc__, - "set_inheritable(fd, inheritable)\n" \ - "\n" \ - "Set the inheritable flag of the specified file descriptor."); +#ifndef OS__GETDISKUSAGE_METHODDEF + #define OS__GETDISKUSAGE_METHODDEF +#endif /* !defined(OS__GETDISKUSAGE_METHODDEF) */ -static PyObject* -posix_set_inheritable(PyObject *self, PyObject *args) -{ - int fd, inheritable; +#ifndef OS_FPATHCONF_METHODDEF + #define OS_FPATHCONF_METHODDEF +#endif /* !defined(OS_FPATHCONF_METHODDEF) */ - if (!PyArg_ParseTuple(args, "ii:set_inheritable", &fd, &inheritable)) - return NULL; +#ifndef OS_PATHCONF_METHODDEF + #define OS_PATHCONF_METHODDEF +#endif /* !defined(OS_PATHCONF_METHODDEF) */ - if (!_PyVerify_fd(fd)) - return posix_error(); +#ifndef OS_CONFSTR_METHODDEF + #define OS_CONFSTR_METHODDEF +#endif /* !defined(OS_CONFSTR_METHODDEF) */ - if (_Py_set_inheritable(fd, inheritable, NULL) < 0) - return NULL; - Py_RETURN_NONE; -} +#ifndef OS_SYSCONF_METHODDEF + #define OS_SYSCONF_METHODDEF +#endif /* !defined(OS_SYSCONF_METHODDEF) */ +#ifndef OS_GETLOADAVG_METHODDEF + #define OS_GETLOADAVG_METHODDEF +#endif /* !defined(OS_GETLOADAVG_METHODDEF) */ -#ifdef MS_WINDOWS -PyDoc_STRVAR(get_handle_inheritable__doc__, - "get_handle_inheritable(fd) -> bool\n" \ - "\n" \ - "Get the close-on-exe flag of the specified file descriptor."); +#ifndef OS_SETRESUID_METHODDEF + #define OS_SETRESUID_METHODDEF +#endif /* !defined(OS_SETRESUID_METHODDEF) */ -static PyObject* -posix_get_handle_inheritable(PyObject *self, PyObject *args) -{ - Py_intptr_t handle; - DWORD flags; +#ifndef OS_SETRESGID_METHODDEF + #define OS_SETRESGID_METHODDEF +#endif /* !defined(OS_SETRESGID_METHODDEF) */ - if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR ":get_handle_inheritable", &handle)) - return NULL; +#ifndef OS_GETRESUID_METHODDEF + #define OS_GETRESUID_METHODDEF +#endif /* !defined(OS_GETRESUID_METHODDEF) */ - if (!GetHandleInformation((HANDLE)handle, &flags)) { - PyErr_SetFromWindowsErr(0); - return NULL; - } +#ifndef OS_GETRESGID_METHODDEF + #define OS_GETRESGID_METHODDEF +#endif /* !defined(OS_GETRESGID_METHODDEF) */ - return PyBool_FromLong(flags & HANDLE_FLAG_INHERIT); -} +#ifndef OS_GETXATTR_METHODDEF + #define OS_GETXATTR_METHODDEF +#endif /* !defined(OS_GETXATTR_METHODDEF) */ -PyDoc_STRVAR(set_handle_inheritable__doc__, - "set_handle_inheritable(fd, inheritable)\n" \ - "\n" \ - "Set the inheritable flag of the specified handle."); +#ifndef OS_SETXATTR_METHODDEF + #define OS_SETXATTR_METHODDEF +#endif /* !defined(OS_SETXATTR_METHODDEF) */ -static PyObject* -posix_set_handle_inheritable(PyObject *self, PyObject *args) -{ - int inheritable = 1; - Py_intptr_t handle; - DWORD flags; +#ifndef OS_REMOVEXATTR_METHODDEF + #define OS_REMOVEXATTR_METHODDEF +#endif /* !defined(OS_REMOVEXATTR_METHODDEF) */ - if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR "i:set_handle_inheritable", - &handle, &inheritable)) - return NULL; +#ifndef OS_LISTXATTR_METHODDEF + #define OS_LISTXATTR_METHODDEF +#endif /* !defined(OS_LISTXATTR_METHODDEF) */ - if (inheritable) - flags = HANDLE_FLAG_INHERIT; - else - flags = 0; - if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) { - PyErr_SetFromWindowsErr(0); - return NULL; - } - Py_RETURN_NONE; -} -#endif /* MS_WINDOWS */ +#ifndef OS_GET_HANDLE_INHERITABLE_METHODDEF + #define OS_GET_HANDLE_INHERITABLE_METHODDEF +#endif /* !defined(OS_GET_HANDLE_INHERITABLE_METHODDEF) */ +#ifndef OS_SET_HANDLE_INHERITABLE_METHODDEF + #define OS_SET_HANDLE_INHERITABLE_METHODDEF +#endif /* !defined(OS_SET_HANDLE_INHERITABLE_METHODDEF) */ +/*[clinic end generated code: output=52a6140b0b052ce6 input=524ce2e021e4eba6]*/ static PyMethodDef posix_methods[] = { @@ -11143,71 +16904,26 @@ static PyMethodDef posix_methods[] = { OS_STAT_METHODDEF OS_ACCESS_METHODDEF OS_TTYNAME_METHODDEF - - {"chdir", (PyCFunction)posix_chdir, - METH_VARARGS | METH_KEYWORDS, - posix_chdir__doc__}, -#ifdef HAVE_CHFLAGS - {"chflags", (PyCFunction)posix_chflags, - METH_VARARGS | METH_KEYWORDS, - posix_chflags__doc__}, -#endif /* HAVE_CHFLAGS */ - {"chmod", (PyCFunction)posix_chmod, - METH_VARARGS | METH_KEYWORDS, - posix_chmod__doc__}, -#ifdef HAVE_FCHMOD - {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__}, -#endif /* HAVE_FCHMOD */ -#ifdef HAVE_CHOWN - {"chown", (PyCFunction)posix_chown, - METH_VARARGS | METH_KEYWORDS, - posix_chown__doc__}, -#endif /* HAVE_CHOWN */ -#ifdef HAVE_LCHMOD - {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__}, -#endif /* HAVE_LCHMOD */ -#ifdef HAVE_FCHOWN - {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__}, -#endif /* HAVE_FCHOWN */ -#ifdef HAVE_LCHFLAGS - {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__}, -#endif /* HAVE_LCHFLAGS */ -#ifdef HAVE_LCHOWN - {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__}, -#endif /* HAVE_LCHOWN */ -#ifdef HAVE_CHROOT - {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__}, -#endif -#ifdef HAVE_CTERMID - {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__}, -#endif - {"getcwd", (PyCFunction)posix_getcwd_unicode, - METH_NOARGS, posix_getcwd__doc__}, - {"getcwdb", (PyCFunction)posix_getcwd_bytes, - METH_NOARGS, posix_getcwdb__doc__}, -#if defined(HAVE_LINK) || defined(MS_WINDOWS) - {"link", (PyCFunction)posix_link, - METH_VARARGS | METH_KEYWORDS, - posix_link__doc__}, -#endif /* HAVE_LINK */ - {"listdir", (PyCFunction)posix_listdir, - METH_VARARGS | METH_KEYWORDS, - posix_listdir__doc__}, - {"lstat", (PyCFunction)posix_lstat, - METH_VARARGS | METH_KEYWORDS, - posix_lstat__doc__}, - {"mkdir", (PyCFunction)posix_mkdir, - METH_VARARGS | METH_KEYWORDS, - posix_mkdir__doc__}, -#ifdef HAVE_NICE - {"nice", posix_nice, METH_VARARGS, posix_nice__doc__}, -#endif /* HAVE_NICE */ -#ifdef HAVE_GETPRIORITY - {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__}, -#endif /* HAVE_GETPRIORITY */ -#ifdef HAVE_SETPRIORITY - {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__}, -#endif /* HAVE_SETPRIORITY */ + OS_CHDIR_METHODDEF + OS_CHFLAGS_METHODDEF + OS_CHMOD_METHODDEF + OS_FCHMOD_METHODDEF + OS_LCHMOD_METHODDEF + OS_CHOWN_METHODDEF + OS_FCHOWN_METHODDEF + OS_LCHOWN_METHODDEF + OS_LCHFLAGS_METHODDEF + OS_CHROOT_METHODDEF + OS_CTERMID_METHODDEF + OS_GETCWD_METHODDEF + OS_GETCWDB_METHODDEF + OS_LINK_METHODDEF + OS_LISTDIR_METHODDEF + OS_LSTAT_METHODDEF + OS_MKDIR_METHODDEF + OS_NICE_METHODDEF + OS_GETPRIORITY_METHODDEF + OS_SETPRIORITY_METHODDEF #ifdef HAVE_READLINK {"readlink", (PyCFunction)posix_readlink, METH_VARARGS | METH_KEYWORDS, @@ -11218,375 +16934,160 @@ static PyMethodDef posix_methods[] = { METH_VARARGS | METH_KEYWORDS, readlink__doc__}, #endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */ - {"rename", (PyCFunction)posix_rename, - METH_VARARGS | METH_KEYWORDS, - posix_rename__doc__}, - {"replace", (PyCFunction)posix_replace, - METH_VARARGS | METH_KEYWORDS, - posix_replace__doc__}, - {"rmdir", (PyCFunction)posix_rmdir, - METH_VARARGS | METH_KEYWORDS, - posix_rmdir__doc__}, + OS_RENAME_METHODDEF + OS_REPLACE_METHODDEF + OS_RMDIR_METHODDEF {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__}, -#if defined(HAVE_SYMLINK) - {"symlink", (PyCFunction)posix_symlink, - METH_VARARGS | METH_KEYWORDS, - posix_symlink__doc__}, -#endif /* HAVE_SYMLINK */ -#ifdef HAVE_SYSTEM - {"system", posix_system, METH_VARARGS, posix_system__doc__}, -#endif - {"umask", posix_umask, METH_VARARGS, posix_umask__doc__}, -#ifdef HAVE_UNAME - {"uname", posix_uname, METH_NOARGS, posix_uname__doc__}, -#endif /* HAVE_UNAME */ - {"unlink", (PyCFunction)posix_unlink, - METH_VARARGS | METH_KEYWORDS, - posix_unlink__doc__}, - {"remove", (PyCFunction)posix_unlink, - METH_VARARGS | METH_KEYWORDS, - posix_remove__doc__}, - {"utime", (PyCFunction)posix_utime, - METH_VARARGS | METH_KEYWORDS, posix_utime__doc__}, -#ifdef HAVE_TIMES - {"times", posix_times, METH_NOARGS, posix_times__doc__}, -#endif /* HAVE_TIMES */ - {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__}, -#ifdef HAVE_EXECV - {"execv", posix_execv, METH_VARARGS, posix_execv__doc__}, - {"execve", (PyCFunction)posix_execve, - METH_VARARGS | METH_KEYWORDS, - posix_execve__doc__}, -#endif /* HAVE_EXECV */ -#ifdef HAVE_SPAWNV - {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__}, - {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__}, -#endif /* HAVE_SPAWNV */ -#ifdef HAVE_FORK1 - {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__}, -#endif /* HAVE_FORK1 */ -#ifdef HAVE_FORK - {"fork", posix_fork, METH_NOARGS, posix_fork__doc__}, -#endif /* HAVE_FORK */ -#ifdef HAVE_SCHED_H -#ifdef HAVE_SCHED_GET_PRIORITY_MAX - {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__}, - {"sched_get_priority_min", posix_sched_get_priority_min, METH_VARARGS, posix_sched_get_priority_min__doc__}, -#endif -#ifdef HAVE_SCHED_SETPARAM - {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__}, -#endif -#ifdef HAVE_SCHED_SETSCHEDULER - {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__}, -#endif -#ifdef HAVE_SCHED_RR_GET_INTERVAL - {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__}, -#endif -#ifdef HAVE_SCHED_SETPARAM - {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__}, -#endif -#ifdef HAVE_SCHED_SETSCHEDULER - {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__}, -#endif - {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__}, -#ifdef HAVE_SCHED_SETAFFINITY - {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__}, - {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__}, -#endif -#endif /* HAVE_SCHED_H */ -#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) - {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__}, -#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */ -#ifdef HAVE_FORKPTY - {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__}, -#endif /* HAVE_FORKPTY */ -#ifdef HAVE_GETEGID - {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__}, -#endif /* HAVE_GETEGID */ -#ifdef HAVE_GETEUID - {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__}, -#endif /* HAVE_GETEUID */ -#ifdef HAVE_GETGID - {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__}, -#endif /* HAVE_GETGID */ + OS_SYMLINK_METHODDEF + OS_SYSTEM_METHODDEF + OS_UMASK_METHODDEF + OS_UNAME_METHODDEF + OS_UNLINK_METHODDEF + OS_REMOVE_METHODDEF + OS_UTIME_METHODDEF + OS_TIMES_METHODDEF + OS__EXIT_METHODDEF + OS_EXECV_METHODDEF + OS_EXECVE_METHODDEF + OS_SPAWNV_METHODDEF + OS_SPAWNVE_METHODDEF + OS_FORK1_METHODDEF + OS_FORK_METHODDEF + OS_SCHED_GET_PRIORITY_MAX_METHODDEF + OS_SCHED_GET_PRIORITY_MIN_METHODDEF + OS_SCHED_GETPARAM_METHODDEF + OS_SCHED_GETSCHEDULER_METHODDEF + OS_SCHED_RR_GET_INTERVAL_METHODDEF + OS_SCHED_SETPARAM_METHODDEF + OS_SCHED_SETSCHEDULER_METHODDEF + OS_SCHED_YIELD_METHODDEF + OS_SCHED_SETAFFINITY_METHODDEF + OS_SCHED_GETAFFINITY_METHODDEF + OS_OPENPTY_METHODDEF + OS_FORKPTY_METHODDEF + OS_GETEGID_METHODDEF + OS_GETEUID_METHODDEF + OS_GETGID_METHODDEF #ifdef HAVE_GETGROUPLIST {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__}, #endif -#ifdef HAVE_GETGROUPS - {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__}, -#endif - {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__}, -#ifdef HAVE_GETPGRP - {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__}, -#endif /* HAVE_GETPGRP */ -#ifdef HAVE_GETPPID - {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__}, -#endif /* HAVE_GETPPID */ -#ifdef HAVE_GETUID - {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__}, -#endif /* HAVE_GETUID */ -#ifdef HAVE_GETLOGIN - {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__}, -#endif -#ifdef HAVE_KILL - {"kill", posix_kill, METH_VARARGS, posix_kill__doc__}, -#endif /* HAVE_KILL */ -#ifdef HAVE_KILLPG - {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__}, -#endif /* HAVE_KILLPG */ -#ifdef HAVE_PLOCK - {"plock", posix_plock, METH_VARARGS, posix_plock__doc__}, -#endif /* HAVE_PLOCK */ + OS_GETGROUPS_METHODDEF + OS_GETPID_METHODDEF + OS_GETPGRP_METHODDEF + OS_GETPPID_METHODDEF + OS_GETUID_METHODDEF + OS_GETLOGIN_METHODDEF + OS_KILL_METHODDEF + OS_KILLPG_METHODDEF + OS_PLOCK_METHODDEF #ifdef MS_WINDOWS {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__}, - {"kill", win32_kill, METH_VARARGS, win32_kill__doc__}, #endif -#ifdef HAVE_SETUID - {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__}, -#endif /* HAVE_SETUID */ -#ifdef HAVE_SETEUID - {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__}, -#endif /* HAVE_SETEUID */ -#ifdef HAVE_SETEGID - {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__}, -#endif /* HAVE_SETEGID */ -#ifdef HAVE_SETREUID - {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__}, -#endif /* HAVE_SETREUID */ -#ifdef HAVE_SETREGID - {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__}, -#endif /* HAVE_SETREGID */ -#ifdef HAVE_SETGID - {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__}, -#endif /* HAVE_SETGID */ -#ifdef HAVE_SETGROUPS - {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__}, -#endif /* HAVE_SETGROUPS */ + OS_SETUID_METHODDEF + OS_SETEUID_METHODDEF + OS_SETREUID_METHODDEF + OS_SETGID_METHODDEF + OS_SETEGID_METHODDEF + OS_SETREGID_METHODDEF + OS_SETGROUPS_METHODDEF #ifdef HAVE_INITGROUPS {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__}, #endif /* HAVE_INITGROUPS */ -#ifdef HAVE_GETPGID - {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__}, -#endif /* HAVE_GETPGID */ -#ifdef HAVE_SETPGRP - {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__}, -#endif /* HAVE_SETPGRP */ -#ifdef HAVE_WAIT - {"wait", posix_wait, METH_NOARGS, posix_wait__doc__}, -#endif /* HAVE_WAIT */ -#ifdef HAVE_WAIT3 - {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__}, -#endif /* HAVE_WAIT3 */ -#ifdef HAVE_WAIT4 - {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__}, -#endif /* HAVE_WAIT4 */ -#if defined(HAVE_WAITID) && !defined(__APPLE__) - {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__}, -#endif -#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT) - {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__}, -#endif /* HAVE_WAITPID */ -#ifdef HAVE_GETSID - {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__}, -#endif /* HAVE_GETSID */ -#ifdef HAVE_SETSID - {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__}, -#endif /* HAVE_SETSID */ -#ifdef HAVE_SETPGID - {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__}, -#endif /* HAVE_SETPGID */ -#ifdef HAVE_TCGETPGRP - {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__}, -#endif /* HAVE_TCGETPGRP */ -#ifdef HAVE_TCSETPGRP - {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__}, -#endif /* HAVE_TCSETPGRP */ - {"open", (PyCFunction)posix_open,\ - METH_VARARGS | METH_KEYWORDS, - posix_open__doc__}, - {"close", posix_close, METH_VARARGS, posix_close__doc__}, - {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__}, - {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__}, - {"dup", posix_dup, METH_VARARGS, posix_dup__doc__}, - {"dup2", (PyCFunction)posix_dup2, - METH_VARARGS | METH_KEYWORDS, posix_dup2__doc__}, -#ifdef HAVE_LOCKF - {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__}, -#endif - {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__}, - {"read", posix_read, METH_VARARGS, posix_read__doc__}, -#ifdef HAVE_READV - {"readv", posix_readv, METH_VARARGS, posix_readv__doc__}, -#endif -#ifdef HAVE_PREAD - {"pread", posix_pread, METH_VARARGS, posix_pread__doc__}, -#endif - {"write", posix_write, METH_VARARGS, posix_write__doc__}, -#ifdef HAVE_WRITEV - {"writev", posix_writev, METH_VARARGS, posix_writev__doc__}, -#endif -#ifdef HAVE_PWRITE - {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__}, -#endif + OS_GETPGID_METHODDEF + OS_SETPGRP_METHODDEF + OS_WAIT_METHODDEF + OS_WAIT3_METHODDEF + OS_WAIT4_METHODDEF + OS_WAITID_METHODDEF + OS_WAITPID_METHODDEF + OS_GETSID_METHODDEF + OS_SETSID_METHODDEF + OS_SETPGID_METHODDEF + OS_TCGETPGRP_METHODDEF + OS_TCSETPGRP_METHODDEF + OS_OPEN_METHODDEF + OS_CLOSE_METHODDEF + OS_CLOSERANGE_METHODDEF + OS_DEVICE_ENCODING_METHODDEF + OS_DUP_METHODDEF + OS_DUP2_METHODDEF + OS_LOCKF_METHODDEF + OS_LSEEK_METHODDEF + OS_READ_METHODDEF + OS_READV_METHODDEF + OS_PREAD_METHODDEF + OS_WRITE_METHODDEF + OS_WRITEV_METHODDEF + OS_PWRITE_METHODDEF #ifdef HAVE_SENDFILE {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS, posix_sendfile__doc__}, #endif - {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__}, - {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__}, -#ifdef HAVE_PIPE - {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__}, -#endif -#ifdef HAVE_PIPE2 - {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__}, -#endif -#ifdef HAVE_MKFIFO - {"mkfifo", (PyCFunction)posix_mkfifo, - METH_VARARGS | METH_KEYWORDS, - posix_mkfifo__doc__}, -#endif -#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) - {"mknod", (PyCFunction)posix_mknod, - METH_VARARGS | METH_KEYWORDS, - posix_mknod__doc__}, -#endif -#ifdef HAVE_DEVICE_MACROS - {"major", posix_major, METH_VARARGS, posix_major__doc__}, - {"minor", posix_minor, METH_VARARGS, posix_minor__doc__}, - {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__}, -#endif -#ifdef HAVE_FTRUNCATE - {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__}, -#endif -#ifdef HAVE_TRUNCATE - {"truncate", (PyCFunction)posix_truncate, - METH_VARARGS | METH_KEYWORDS, - posix_truncate__doc__}, -#endif -#ifdef HAVE_POSIX_FALLOCATE - {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__}, -#endif -#ifdef HAVE_POSIX_FADVISE - {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__}, -#endif -#ifdef HAVE_PUTENV - {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__}, -#endif -#ifdef HAVE_UNSETENV - {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__}, -#endif - {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__}, -#ifdef HAVE_FCHDIR - {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__}, -#endif -#ifdef HAVE_FSYNC - {"fsync", posix_fsync, METH_O, posix_fsync__doc__}, -#endif -#ifdef HAVE_SYNC - {"sync", posix_sync, METH_NOARGS, posix_sync__doc__}, -#endif -#ifdef HAVE_FDATASYNC - {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__}, -#endif -#ifdef HAVE_SYS_WAIT_H -#ifdef WCOREDUMP - {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__}, -#endif /* WCOREDUMP */ -#ifdef WIFCONTINUED - {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__}, -#endif /* WIFCONTINUED */ -#ifdef WIFSTOPPED - {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__}, -#endif /* WIFSTOPPED */ -#ifdef WIFSIGNALED - {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__}, -#endif /* WIFSIGNALED */ -#ifdef WIFEXITED - {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__}, -#endif /* WIFEXITED */ -#ifdef WEXITSTATUS - {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__}, -#endif /* WEXITSTATUS */ -#ifdef WTERMSIG - {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__}, -#endif /* WTERMSIG */ -#ifdef WSTOPSIG - {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__}, -#endif /* WSTOPSIG */ -#endif /* HAVE_SYS_WAIT_H */ -#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) - {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__}, -#endif -#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) - {"statvfs", (PyCFunction)posix_statvfs, - METH_VARARGS | METH_KEYWORDS, - posix_statvfs__doc__}, -#endif -#ifdef HAVE_CONFSTR - {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__}, -#endif -#ifdef HAVE_SYSCONF - {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__}, -#endif -#ifdef HAVE_FPATHCONF - {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__}, -#endif -#ifdef HAVE_PATHCONF - {"pathconf", (PyCFunction)posix_pathconf, - METH_VARARGS | METH_KEYWORDS, - posix_pathconf__doc__}, -#endif - {"abort", posix_abort, METH_NOARGS, posix_abort__doc__}, + OS_FSTAT_METHODDEF + OS_ISATTY_METHODDEF + OS_PIPE_METHODDEF + OS_PIPE2_METHODDEF + OS_MKFIFO_METHODDEF + OS_MKNOD_METHODDEF + OS_MAJOR_METHODDEF + OS_MINOR_METHODDEF + OS_MAKEDEV_METHODDEF + OS_FTRUNCATE_METHODDEF + OS_TRUNCATE_METHODDEF + OS_POSIX_FALLOCATE_METHODDEF + OS_POSIX_FADVISE_METHODDEF + OS_PUTENV_METHODDEF + OS_UNSETENV_METHODDEF + OS_STRERROR_METHODDEF + OS_FCHDIR_METHODDEF + OS_FSYNC_METHODDEF + OS_SYNC_METHODDEF + OS_FDATASYNC_METHODDEF + OS_WCOREDUMP_METHODDEF + OS_WIFCONTINUED_METHODDEF + OS_WIFSTOPPED_METHODDEF + OS_WIFSIGNALED_METHODDEF + OS_WIFEXITED_METHODDEF + OS_WEXITSTATUS_METHODDEF + OS_WTERMSIG_METHODDEF + OS_WSTOPSIG_METHODDEF + OS_FSTATVFS_METHODDEF + OS_STATVFS_METHODDEF + OS_CONFSTR_METHODDEF + OS_SYSCONF_METHODDEF + OS_FPATHCONF_METHODDEF + OS_PATHCONF_METHODDEF + OS_ABORT_METHODDEF #ifdef MS_WINDOWS {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL}, - {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL}, {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__}, - {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__}, - {"_getvolumepathname", posix__getvolumepathname, METH_VARARGS, posix__getvolumepathname__doc__}, -#endif -#ifdef HAVE_GETLOADAVG - {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__}, -#endif - {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__}, -#ifdef HAVE_SETRESUID - {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__}, -#endif -#ifdef HAVE_SETRESGID - {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__}, -#endif -#ifdef HAVE_GETRESUID - {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__}, -#endif -#ifdef HAVE_GETRESGID - {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__}, #endif + OS__GETDISKUSAGE_METHODDEF + OS__GETFINALPATHNAME_METHODDEF + OS__GETVOLUMEPATHNAME_METHODDEF + OS_GETLOADAVG_METHODDEF + OS_URANDOM_METHODDEF + OS_SETRESUID_METHODDEF + OS_SETRESGID_METHODDEF + OS_GETRESUID_METHODDEF + OS_GETRESGID_METHODDEF + + OS_GETXATTR_METHODDEF + OS_SETXATTR_METHODDEF + OS_REMOVEXATTR_METHODDEF + OS_LISTXATTR_METHODDEF -#ifdef USE_XATTRS - {"setxattr", (PyCFunction)posix_setxattr, - METH_VARARGS | METH_KEYWORDS, - posix_setxattr__doc__}, - {"getxattr", (PyCFunction)posix_getxattr, - METH_VARARGS | METH_KEYWORDS, - posix_getxattr__doc__}, - {"removexattr", (PyCFunction)posix_removexattr, - METH_VARARGS | METH_KEYWORDS, - posix_removexattr__doc__}, - {"listxattr", (PyCFunction)posix_listxattr, - METH_VARARGS | METH_KEYWORDS, - posix_listxattr__doc__}, -#endif #if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__}, #endif - {"cpu_count", (PyCFunction)posix_cpu_count, - METH_NOARGS, posix_cpu_count__doc__}, - {"get_inheritable", posix_get_inheritable, METH_VARARGS, get_inheritable__doc__}, - {"set_inheritable", posix_set_inheritable, METH_VARARGS, set_inheritable__doc__}, -#ifdef MS_WINDOWS - {"get_handle_inheritable", posix_get_handle_inheritable, - METH_VARARGS, get_handle_inheritable__doc__}, - {"set_handle_inheritable", posix_set_handle_inheritable, - METH_VARARGS, set_handle_inheritable__doc__}, + OS_CPU_COUNT_METHODDEF + OS_GET_INHERITABLE_METHODDEF + OS_SET_INHERITABLE_METHODDEF + OS_GET_HANDLE_INHERITABLE_METHODDEF + OS_SET_HANDLE_INHERITABLE_METHODDEF +#ifndef MS_WINDOWS + {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__}, + {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__}, #endif {NULL, NULL} /* Sentinel */ }; @@ -11858,6 +17359,35 @@ all_ins(PyObject *m) if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1; #endif /* ST_NOSUID */ + /* GNU extensions */ +#ifdef ST_NODEV + if (PyModule_AddIntMacro(m, ST_NODEV)) return -1; +#endif /* ST_NODEV */ +#ifdef ST_NOEXEC + if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1; +#endif /* ST_NOEXEC */ +#ifdef ST_SYNCHRONOUS + if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1; +#endif /* ST_SYNCHRONOUS */ +#ifdef ST_MANDLOCK + if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1; +#endif /* ST_MANDLOCK */ +#ifdef ST_WRITE + if (PyModule_AddIntMacro(m, ST_WRITE)) return -1; +#endif /* ST_WRITE */ +#ifdef ST_APPEND + if (PyModule_AddIntMacro(m, ST_APPEND)) return -1; +#endif /* ST_APPEND */ +#ifdef ST_NOATIME + if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1; +#endif /* ST_NOATIME */ +#ifdef ST_NODIRATIME + if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1; +#endif /* ST_NODIRATIME */ +#ifdef ST_RELATIME + if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1; +#endif /* ST_RELATIME */ + /* FreeBSD sendfile() constants */ #ifdef SF_NODISKIO if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1; @@ -12001,7 +17531,7 @@ all_ins(PyObject *m) } -#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__) +#ifdef MS_WINDOWS #define INITFUNC PyInit_nt #define MODNAME "nt" @@ -12223,7 +17753,7 @@ INITFUNC(void) sched_param_desc.name = MODNAME ".sched_param"; if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0) return NULL; - SchedParamType.tp_new = sched_param_new; + SchedParamType.tp_new = os_sched_param; #endif /* initialize TerminalSize_info */ diff --git a/Modules/pwdmodule.c b/Modules/pwdmodule.c index 99094004411f..b02753f9323e 100644 --- a/Modules/pwdmodule.c +++ b/Modules/pwdmodule.c @@ -6,6 +6,13 @@ #include +#include "clinic/pwdmodule.c.h" +/*[clinic input] +output preset file +module pwd +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=bbcf68b1f549f917]*/ + static PyStructSequence_Field struct_pwd_type_fields[] = { {"pw_name", "user name"}, {"pw_passwd", "password"}, @@ -69,18 +76,10 @@ mkpwent(struct passwd *p) #define SETS(i,val) sets(v, i, val) SETS(setIndex++, p->pw_name); -#ifdef __VMS - SETS(setIndex++, ""); -#else SETS(setIndex++, p->pw_passwd); -#endif PyStructSequence_SET_ITEM(v, setIndex++, _PyLong_FromUid(p->pw_uid)); PyStructSequence_SET_ITEM(v, setIndex++, _PyLong_FromGid(p->pw_gid)); -#ifdef __VMS - SETS(setIndex++, ""); -#else SETS(setIndex++, p->pw_gecos); -#endif SETS(setIndex++, p->pw_dir); SETS(setIndex++, p->pw_shell); @@ -95,18 +94,25 @@ mkpwent(struct passwd *p) return v; } -PyDoc_STRVAR(pwd_getpwuid__doc__, -"getpwuid(uid) -> (pw_name,pw_passwd,pw_uid,\n\ - pw_gid,pw_gecos,pw_dir,pw_shell)\n\ -Return the password database entry for the given numeric user ID.\n\ -See help(pwd) for more on password database entries."); +/*[clinic input] +pwd.getpwuid + + uidobj: object + / + +Return the password database entry for the given numeric user ID. + +See `help(pwd)` for more on password database entries. +[clinic start generated code]*/ static PyObject * -pwd_getpwuid(PyObject *self, PyObject *args) +pwd_getpwuid(PyModuleDef *module, PyObject *uidobj) +/*[clinic end generated code: output=cba29ae4c2bcb8e1 input=ae64d507a1c6d3e8]*/ { uid_t uid; struct passwd *p; - if (!PyArg_ParseTuple(args, "O&:getpwuid", _Py_Uid_Converter, &uid)) { + + if (!_Py_Uid_Converter(uidobj, &uid)) { if (PyErr_ExceptionMatches(PyExc_OverflowError)) PyErr_Format(PyExc_KeyError, "getpwuid(): uid not found"); @@ -124,21 +130,25 @@ pwd_getpwuid(PyObject *self, PyObject *args) return mkpwent(p); } -PyDoc_STRVAR(pwd_getpwnam__doc__, -"getpwnam(name) -> (pw_name,pw_passwd,pw_uid,\n\ - pw_gid,pw_gecos,pw_dir,pw_shell)\n\ -Return the password database entry for the given user name.\n\ -See help(pwd) for more on password database entries."); +/*[clinic input] +pwd.getpwnam + + arg: unicode + / + +Return the password database entry for the given user name. + +See `help(pwd)` for more on password database entries. +[clinic start generated code]*/ static PyObject * -pwd_getpwnam(PyObject *self, PyObject *args) +pwd_getpwnam_impl(PyModuleDef *module, PyObject *arg) +/*[clinic end generated code: output=66848d42d386fca3 input=d5f7e700919b02d3]*/ { char *name; struct passwd *p; - PyObject *arg, *bytes, *retval = NULL; + PyObject *bytes, *retval = NULL; - if (!PyArg_ParseTuple(args, "U:getpwnam", &arg)) - return NULL; if ((bytes = PyUnicode_EncodeFSDefault(arg)) == NULL) return NULL; if (PyBytes_AsStringAndSize(bytes, &name, NULL) == -1) @@ -155,14 +165,17 @@ pwd_getpwnam(PyObject *self, PyObject *args) } #ifdef HAVE_GETPWENT -PyDoc_STRVAR(pwd_getpwall__doc__, -"getpwall() -> list_of_entries\n\ -Return a list of all available password database entries, \ -in arbitrary order.\n\ -See help(pwd) for more on password database entries."); +/*[clinic input] +pwd.getpwall + +Return a list of all available password database entries, in arbitrary order. + +See help(pwd) for more on password database entries. +[clinic start generated code]*/ static PyObject * -pwd_getpwall(PyObject *self) +pwd_getpwall_impl(PyModuleDef *module) +/*[clinic end generated code: output=ab30e37bf26d431d input=d7ecebfd90219b85]*/ { PyObject *d; struct passwd *p; @@ -185,11 +198,10 @@ pwd_getpwall(PyObject *self) #endif static PyMethodDef pwd_methods[] = { - {"getpwuid", pwd_getpwuid, METH_VARARGS, pwd_getpwuid__doc__}, - {"getpwnam", pwd_getpwnam, METH_VARARGS, pwd_getpwnam__doc__}, + PWD_GETPWUID_METHODDEF + PWD_GETPWNAM_METHODDEF #ifdef HAVE_GETPWENT - {"getpwall", (PyCFunction)pwd_getpwall, - METH_NOARGS, pwd_getpwall__doc__}, + PWD_GETPWALL_METHODDEF #endif {NULL, NULL} /* sentinel */ }; diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c index 3f51c12cebce..21cb04a82607 100644 --- a/Modules/pyexpat.c +++ b/Modules/pyexpat.c @@ -6,9 +6,14 @@ #include "pyexpat.h" -#define XML_COMBINED_VERSION (10000*XML_MAJOR_VERSION+100*XML_MINOR_VERSION+XML_MICRO_VERSION) +/* Do not emit Clinic output to a file as that wreaks havoc with conditionally + included methods. */ +/*[clinic input] +module pyexpat +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=b168d503a4490c15]*/ -#define FIX_TRACE +#define XML_COMBINED_VERSION (10000*XML_MAJOR_VERSION+100*XML_MINOR_VERSION+XML_MICRO_VERSION) static XML_Memory_Handling_Suite ExpatMemoryHandler = { PyObject_Malloc, PyObject_Realloc, PyObject_Free}; @@ -210,122 +215,17 @@ flag_error(xmlparseobject *self) error_external_entity_ref_handler); } -static PyCodeObject* -getcode(enum HandlerTypes slot, char* func_name, int lineno) -{ - if (handler_info[slot].tb_code == NULL) { - handler_info[slot].tb_code = - PyCode_NewEmpty(__FILE__, func_name, lineno); - } - return handler_info[slot].tb_code; -} - -#ifdef FIX_TRACE -static int -trace_frame(PyThreadState *tstate, PyFrameObject *f, int code, PyObject *val) -{ - int result = 0; - if (!tstate->use_tracing || tstate->tracing) - return 0; - if (tstate->c_profilefunc != NULL) { - tstate->tracing++; - result = tstate->c_profilefunc(tstate->c_profileobj, - f, code , val); - tstate->use_tracing = ((tstate->c_tracefunc != NULL) - || (tstate->c_profilefunc != NULL)); - tstate->tracing--; - if (result) - return result; - } - if (tstate->c_tracefunc != NULL) { - tstate->tracing++; - result = tstate->c_tracefunc(tstate->c_traceobj, - f, code , val); - tstate->use_tracing = ((tstate->c_tracefunc != NULL) - || (tstate->c_profilefunc != NULL)); - tstate->tracing--; - } - return result; -} - -static int -trace_frame_exc(PyThreadState *tstate, PyFrameObject *f) -{ - PyObject *type, *value, *traceback, *arg; - int err; - - if (tstate->c_tracefunc == NULL) - return 0; - - PyErr_Fetch(&type, &value, &traceback); - if (value == NULL) { - value = Py_None; - Py_INCREF(value); - } - arg = PyTuple_Pack(3, type, value, traceback); - if (arg == NULL) { - PyErr_Restore(type, value, traceback); - return 0; - } - err = trace_frame(tstate, f, PyTrace_EXCEPTION, arg); - Py_DECREF(arg); - if (err == 0) - PyErr_Restore(type, value, traceback); - else { - Py_XDECREF(type); - Py_XDECREF(value); - Py_XDECREF(traceback); - } - return err; -} -#endif - static PyObject* -call_with_frame(PyCodeObject *c, PyObject* func, PyObject* args, +call_with_frame(char *funcname, int lineno, PyObject* func, PyObject* args, xmlparseobject *self) { - PyThreadState *tstate = PyThreadState_GET(); - PyFrameObject *f; - PyObject *res, *globals; - - if (c == NULL) - return NULL; + PyObject *res; - globals = PyEval_GetGlobals(); - if (globals == NULL) { - return NULL; - } - - f = PyFrame_New(tstate, c, globals, NULL); - if (f == NULL) - return NULL; - tstate->frame = f; -#ifdef FIX_TRACE - if (trace_frame(tstate, f, PyTrace_CALL, Py_None) < 0) { - return NULL; - } -#endif res = PyEval_CallObject(func, args); if (res == NULL) { - if (tstate->curexc_traceback == NULL) - PyTraceBack_Here(f); + _PyTraceback_Add(funcname, __FILE__, lineno); XML_StopParser(self->itself, XML_FALSE); -#ifdef FIX_TRACE - if (trace_frame_exc(tstate, f) < 0) { - return NULL; - } - } - else { - if (trace_frame(tstate, f, PyTrace_RETURN, res) < 0) { - Py_XDECREF(res); - res = NULL; - } - } -#else } -#endif - tstate->frame = f->f_back; - Py_DECREF(f); return res; } @@ -377,7 +277,7 @@ call_character_handler(xmlparseobject *self, const XML_Char *buffer, int len) PyTuple_SET_ITEM(args, 0, temp); /* temp is now a borrowed reference; consider it unused. */ self->in_callback = 1; - temp = call_with_frame(getcode(CharacterData, "CharacterData", __LINE__), + temp = call_with_frame("CharacterData", __LINE__, self->handlers[CharacterData], args, self); /* temp is an owned reference again, or NULL */ self->in_callback = 0; @@ -509,7 +409,7 @@ my_StartElementHandler(void *userData, } /* Container is now a borrowed reference; ignore it. */ self->in_callback = 1; - rv = call_with_frame(getcode(StartElement, "StartElement", __LINE__), + rv = call_with_frame("StartElement", __LINE__, self->handlers[StartElement], args, self); self->in_callback = 0; Py_DECREF(args); @@ -538,7 +438,7 @@ my_##NAME##Handler PARAMS {\ args = Py_BuildValue PARAM_FORMAT ;\ if (!args) { flag_error(self); return RETURN;} \ self->in_callback = 1; \ - rv = call_with_frame(getcode(NAME,#NAME,__LINE__), \ + rv = call_with_frame(#NAME,__LINE__, \ self->handlers[NAME], args, self); \ self->in_callback = 0; \ Py_DECREF(args); \ @@ -670,7 +570,7 @@ my_ElementDeclHandler(void *userData, goto finally; } self->in_callback = 1; - rv = call_with_frame(getcode(ElementDecl, "ElementDecl", __LINE__), + rv = call_with_frame("ElementDecl", __LINE__, self->handlers[ElementDecl], args, self); self->in_callback = 0; if (rv == NULL) { @@ -778,6 +678,11 @@ VOID_HANDLER(StartDoctypeDecl, VOID_HANDLER(EndDoctypeDecl, (void *userData), ("()")) /* ---------------------------------------------------------------- */ +/*[clinic input] +class pyexpat.xmlparser "xmlparseobject *" "&Xmlparsetype" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=2393162385232e1c]*/ + static PyObject * get_parse_result(xmlparseobject *self, int rv) @@ -794,25 +699,60 @@ get_parse_result(xmlparseobject *self, int rv) return PyLong_FromLong(rv); } -PyDoc_STRVAR(xmlparse_Parse__doc__, -"Parse(data[, isfinal])\n\ -Parse XML data. `isfinal' should be true at end of input."); - #define MAX_CHUNK_SIZE (1 << 20) +/*[clinic input] +pyexpat.xmlparser.Parse + + data: object + isFinal: int = 0 + / + +Parse XML data. + +`isfinal' should be true at end of input. +[clinic start generated code]*/ + +PyDoc_STRVAR(pyexpat_xmlparser_Parse__doc__, +"Parse($self, data, isFinal=0, /)\n" +"--\n" +"\n" +"Parse XML data.\n" +"\n" +"`isfinal\' should be true at end of input."); + +#define PYEXPAT_XMLPARSER_PARSE_METHODDEF \ + {"Parse", (PyCFunction)pyexpat_xmlparser_Parse, METH_VARARGS, pyexpat_xmlparser_Parse__doc__}, + +static PyObject * +pyexpat_xmlparser_Parse_impl(xmlparseobject *self, PyObject *data, int isFinal); + static PyObject * -xmlparse_Parse(xmlparseobject *self, PyObject *args) +pyexpat_xmlparser_Parse(xmlparseobject *self, PyObject *args) { + PyObject *return_value = NULL; PyObject *data; int isFinal = 0; + + if (!PyArg_ParseTuple(args, + "O|i:Parse", + &data, &isFinal)) + goto exit; + return_value = pyexpat_xmlparser_Parse_impl(self, data, isFinal); + +exit: + return return_value; +} + +static PyObject * +pyexpat_xmlparser_Parse_impl(xmlparseobject *self, PyObject *data, int isFinal) +/*[clinic end generated code: output=65b1652b01f20856 input=e37b81b8948ca7e0]*/ +{ const char *s; Py_ssize_t slen; Py_buffer view; int rc; - if (!PyArg_ParseTuple(args, "O|i:Parse", &data, &isFinal)) - return NULL; - if (PyUnicode_Check(data)) { view.buf = NULL; s = PyUnicode_AsUTF8AndSize(data, &slen); @@ -887,18 +827,33 @@ readinst(char *buf, int buf_size, PyObject *meth) return -1; } -PyDoc_STRVAR(xmlparse_ParseFile__doc__, -"ParseFile(file)\n\ -Parse XML data from file-like object."); +/*[clinic input] +pyexpat.xmlparser.ParseFile + + file: object + / + +Parse XML data from file-like object. +[clinic start generated code]*/ + +PyDoc_STRVAR(pyexpat_xmlparser_ParseFile__doc__, +"ParseFile($self, file, /)\n" +"--\n" +"\n" +"Parse XML data from file-like object."); + +#define PYEXPAT_XMLPARSER_PARSEFILE_METHODDEF \ + {"ParseFile", (PyCFunction)pyexpat_xmlparser_ParseFile, METH_O, pyexpat_xmlparser_ParseFile__doc__}, static PyObject * -xmlparse_ParseFile(xmlparseobject *self, PyObject *f) +pyexpat_xmlparser_ParseFile(xmlparseobject *self, PyObject *file) +/*[clinic end generated code: output=2e13803c3d8c22b2 input=fbb5a12b6038d735]*/ { int rv = 1; PyObject *readmethod = NULL; _Py_IDENTIFIER(read); - readmethod = _PyObject_GetAttrId(f, &PyId_read); + readmethod = _PyObject_GetAttrId(file, &PyId_read); if (readmethod == NULL) { PyErr_SetString(PyExc_TypeError, "argument must have 'read' attribute"); @@ -909,7 +864,7 @@ xmlparse_ParseFile(xmlparseobject *self, PyObject *f) void *buf = XML_GetBuffer(self->itself, BUF_SIZE); if (buf == NULL) { Py_XDECREF(readmethod); - return PyErr_NoMemory(); + return get_parse_result(self, 0); } bytes_read = readinst(buf, BUF_SIZE, readmethod); @@ -930,42 +885,117 @@ xmlparse_ParseFile(xmlparseobject *self, PyObject *f) return get_parse_result(self, rv); } -PyDoc_STRVAR(xmlparse_SetBase__doc__, -"SetBase(base_url)\n\ -Set the base URL for the parser."); +/*[clinic input] +pyexpat.xmlparser.SetBase + + base: str + / + +Set the base URL for the parser. +[clinic start generated code]*/ + +PyDoc_STRVAR(pyexpat_xmlparser_SetBase__doc__, +"SetBase($self, base, /)\n" +"--\n" +"\n" +"Set the base URL for the parser."); + +#define PYEXPAT_XMLPARSER_SETBASE_METHODDEF \ + {"SetBase", (PyCFunction)pyexpat_xmlparser_SetBase, METH_VARARGS, pyexpat_xmlparser_SetBase__doc__}, + +static PyObject * +pyexpat_xmlparser_SetBase_impl(xmlparseobject *self, const char *base); static PyObject * -xmlparse_SetBase(xmlparseobject *self, PyObject *args) +pyexpat_xmlparser_SetBase(xmlparseobject *self, PyObject *args) { - char *base; + PyObject *return_value = NULL; + const char *base; - if (!PyArg_ParseTuple(args, "s:SetBase", &base)) - return NULL; + if (!PyArg_ParseTuple(args, + "s:SetBase", + &base)) + goto exit; + return_value = pyexpat_xmlparser_SetBase_impl(self, base); + +exit: + return return_value; +} + +static PyObject * +pyexpat_xmlparser_SetBase_impl(xmlparseobject *self, const char *base) +/*[clinic end generated code: output=5bdb49f6689a5f93 input=c684e5de895ee1a8]*/ +{ if (!XML_SetBase(self->itself, base)) { return PyErr_NoMemory(); } - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } -PyDoc_STRVAR(xmlparse_GetBase__doc__, -"GetBase() -> url\n\ -Return base URL string for the parser."); +/*[clinic input] +pyexpat.xmlparser.GetBase + +Return base URL string for the parser. +[clinic start generated code]*/ + +PyDoc_STRVAR(pyexpat_xmlparser_GetBase__doc__, +"GetBase($self, /)\n" +"--\n" +"\n" +"Return base URL string for the parser."); + +#define PYEXPAT_XMLPARSER_GETBASE_METHODDEF \ + {"GetBase", (PyCFunction)pyexpat_xmlparser_GetBase, METH_NOARGS, pyexpat_xmlparser_GetBase__doc__}, + +static PyObject * +pyexpat_xmlparser_GetBase_impl(xmlparseobject *self); + +static PyObject * +pyexpat_xmlparser_GetBase(xmlparseobject *self, PyObject *Py_UNUSED(ignored)) +{ + return pyexpat_xmlparser_GetBase_impl(self); +} static PyObject * -xmlparse_GetBase(xmlparseobject *self, PyObject *unused) +pyexpat_xmlparser_GetBase_impl(xmlparseobject *self) +/*[clinic end generated code: output=ef6046ee28f2b8ee input=918d71c38009620e]*/ { return Py_BuildValue("z", XML_GetBase(self->itself)); } -PyDoc_STRVAR(xmlparse_GetInputContext__doc__, -"GetInputContext() -> string\n\ -Return the untranslated text of the input that caused the current event.\n\ -If the event was generated by a large amount of text (such as a start tag\n\ -for an element with many attributes), not all of the text may be available."); +/*[clinic input] +pyexpat.xmlparser.GetInputContext + +Return the untranslated text of the input that caused the current event. + +If the event was generated by a large amount of text (such as a start tag +for an element with many attributes), not all of the text may be available. +[clinic start generated code]*/ + +PyDoc_STRVAR(pyexpat_xmlparser_GetInputContext__doc__, +"GetInputContext($self, /)\n" +"--\n" +"\n" +"Return the untranslated text of the input that caused the current event.\n" +"\n" +"If the event was generated by a large amount of text (such as a start tag\n" +"for an element with many attributes), not all of the text may be available."); + +#define PYEXPAT_XMLPARSER_GETINPUTCONTEXT_METHODDEF \ + {"GetInputContext", (PyCFunction)pyexpat_xmlparser_GetInputContext, METH_NOARGS, pyexpat_xmlparser_GetInputContext__doc__}, static PyObject * -xmlparse_GetInputContext(xmlparseobject *self, PyObject *unused) +pyexpat_xmlparser_GetInputContext_impl(xmlparseobject *self); + +static PyObject * +pyexpat_xmlparser_GetInputContext(xmlparseobject *self, PyObject *Py_UNUSED(ignored)) +{ + return pyexpat_xmlparser_GetInputContext_impl(self); +} + +static PyObject * +pyexpat_xmlparser_GetInputContext_impl(xmlparseobject *self) +/*[clinic end generated code: output=62ff03390f074cd2 input=034df8712db68379]*/ { if (self->in_callback) { int offset, size; @@ -982,24 +1012,52 @@ xmlparse_GetInputContext(xmlparseobject *self, PyObject *unused) Py_RETURN_NONE; } -PyDoc_STRVAR(xmlparse_ExternalEntityParserCreate__doc__, -"ExternalEntityParserCreate(context[, encoding])\n\ -Create a parser for parsing an external entity based on the\n\ -information passed to the ExternalEntityRefHandler."); +/*[clinic input] +pyexpat.xmlparser.ExternalEntityParserCreate + + context: str(nullable=True) + encoding: str = NULL + / + +Create a parser for parsing an external entity based on the information passed to the ExternalEntityRefHandler. +[clinic start generated code]*/ + +PyDoc_STRVAR(pyexpat_xmlparser_ExternalEntityParserCreate__doc__, +"ExternalEntityParserCreate($self, context, encoding=None, /)\n" +"--\n" +"\n" +"Create a parser for parsing an external entity based on the information passed to the ExternalEntityRefHandler."); + +#define PYEXPAT_XMLPARSER_EXTERNALENTITYPARSERCREATE_METHODDEF \ + {"ExternalEntityParserCreate", (PyCFunction)pyexpat_xmlparser_ExternalEntityParserCreate, METH_VARARGS, pyexpat_xmlparser_ExternalEntityParserCreate__doc__}, static PyObject * -xmlparse_ExternalEntityParserCreate(xmlparseobject *self, PyObject *args) +pyexpat_xmlparser_ExternalEntityParserCreate_impl(xmlparseobject *self, const char *context, const char *encoding); + +static PyObject * +pyexpat_xmlparser_ExternalEntityParserCreate(xmlparseobject *self, PyObject *args) +{ + PyObject *return_value = NULL; + const char *context; + const char *encoding = NULL; + + if (!PyArg_ParseTuple(args, + "z|s:ExternalEntityParserCreate", + &context, &encoding)) + goto exit; + return_value = pyexpat_xmlparser_ExternalEntityParserCreate_impl(self, context, encoding); + +exit: + return return_value; +} + +static PyObject * +pyexpat_xmlparser_ExternalEntityParserCreate_impl(xmlparseobject *self, const char *context, const char *encoding) +/*[clinic end generated code: output=4948c35f3dd01133 input=283206575d960272]*/ { - char *context; - char *encoding = NULL; xmlparseobject *new_parser; int i; - if (!PyArg_ParseTuple(args, "z|s:ExternalEntityParserCreate", - &context, &encoding)) { - return NULL; - } - new_parser = PyObject_GC_New(xmlparseobject, &Xmlparsetype); if (new_parser == NULL) return NULL; @@ -1035,7 +1093,7 @@ xmlparse_ExternalEntityParserCreate(xmlparseobject *self, PyObject *args) for (i = 0; handler_info[i].name != NULL; i++) /* do nothing */; - new_parser->handlers = PyMem_Malloc(sizeof(PyObject *) * i); + new_parser->handlers = PyMem_New(PyObject *, i); if (!new_parser->handlers) { Py_DECREF(new_parser); return PyErr_NoMemory(); @@ -1055,41 +1113,114 @@ xmlparse_ExternalEntityParserCreate(xmlparseobject *self, PyObject *args) return (PyObject *)new_parser; } -PyDoc_STRVAR(xmlparse_SetParamEntityParsing__doc__, -"SetParamEntityParsing(flag) -> success\n\ -Controls parsing of parameter entities (including the external DTD\n\ -subset). Possible flag values are XML_PARAM_ENTITY_PARSING_NEVER,\n\ -XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE and\n\ -XML_PARAM_ENTITY_PARSING_ALWAYS. Returns true if setting the flag\n\ -was successful."); +/*[clinic input] +pyexpat.xmlparser.SetParamEntityParsing -static PyObject* -xmlparse_SetParamEntityParsing(xmlparseobject *p, PyObject* args) + flag: int + / + +Controls parsing of parameter entities (including the external DTD subset). + +Possible flag values are XML_PARAM_ENTITY_PARSING_NEVER, +XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE and +XML_PARAM_ENTITY_PARSING_ALWAYS. Returns true if setting the flag +was successful. +[clinic start generated code]*/ + +PyDoc_STRVAR(pyexpat_xmlparser_SetParamEntityParsing__doc__, +"SetParamEntityParsing($self, flag, /)\n" +"--\n" +"\n" +"Controls parsing of parameter entities (including the external DTD subset).\n" +"\n" +"Possible flag values are XML_PARAM_ENTITY_PARSING_NEVER,\n" +"XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE and\n" +"XML_PARAM_ENTITY_PARSING_ALWAYS. Returns true if setting the flag\n" +"was successful."); + +#define PYEXPAT_XMLPARSER_SETPARAMENTITYPARSING_METHODDEF \ + {"SetParamEntityParsing", (PyCFunction)pyexpat_xmlparser_SetParamEntityParsing, METH_VARARGS, pyexpat_xmlparser_SetParamEntityParsing__doc__}, + +static PyObject * +pyexpat_xmlparser_SetParamEntityParsing_impl(xmlparseobject *self, int flag); + +static PyObject * +pyexpat_xmlparser_SetParamEntityParsing(xmlparseobject *self, PyObject *args) { + PyObject *return_value = NULL; int flag; - if (!PyArg_ParseTuple(args, "i", &flag)) - return NULL; - flag = XML_SetParamEntityParsing(p->itself, flag); + + if (!PyArg_ParseTuple(args, + "i:SetParamEntityParsing", + &flag)) + goto exit; + return_value = pyexpat_xmlparser_SetParamEntityParsing_impl(self, flag); + +exit: + return return_value; +} + +static PyObject * +pyexpat_xmlparser_SetParamEntityParsing_impl(xmlparseobject *self, int flag) +/*[clinic end generated code: output=0f820882bc7768cc input=8aea19b4b15e9af1]*/ +{ + flag = XML_SetParamEntityParsing(self->itself, flag); return PyLong_FromLong(flag); } #if XML_COMBINED_VERSION >= 19505 -PyDoc_STRVAR(xmlparse_UseForeignDTD__doc__, -"UseForeignDTD([flag])\n\ -Allows the application to provide an artificial external subset if one is\n\ -not specified as part of the document instance. This readily allows the\n\ -use of a 'default' document type controlled by the application, while still\n\ -getting the advantage of providing document type information to the parser.\n\ -'flag' defaults to True if not provided."); +/*[clinic input] +pyexpat.xmlparser.UseForeignDTD + + flag: bool = True + / + +Allows the application to provide an artificial external subset if one is not specified as part of the document instance. + +This readily allows the use of a 'default' document type controlled by the +application, while still getting the advantage of providing document type +information to the parser. 'flag' defaults to True if not provided. +[clinic start generated code]*/ + +PyDoc_STRVAR(pyexpat_xmlparser_UseForeignDTD__doc__, +"UseForeignDTD($self, flag=True, /)\n" +"--\n" +"\n" +"Allows the application to provide an artificial external subset if one is not specified as part of the document instance.\n" +"\n" +"This readily allows the use of a \'default\' document type controlled by the\n" +"application, while still getting the advantage of providing document type\n" +"information to the parser. \'flag\' defaults to True if not provided."); + +#define PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF \ + {"UseForeignDTD", (PyCFunction)pyexpat_xmlparser_UseForeignDTD, METH_VARARGS, pyexpat_xmlparser_UseForeignDTD__doc__}, + +static PyObject * +pyexpat_xmlparser_UseForeignDTD_impl(xmlparseobject *self, int flag); static PyObject * -xmlparse_UseForeignDTD(xmlparseobject *self, PyObject *args) +pyexpat_xmlparser_UseForeignDTD(xmlparseobject *self, PyObject *args) { + PyObject *return_value = NULL; int flag = 1; + + if (!PyArg_ParseTuple(args, + "|p:UseForeignDTD", + &flag)) + goto exit; + return_value = pyexpat_xmlparser_UseForeignDTD_impl(self, flag); + +exit: + return return_value; +} + +static PyObject * +pyexpat_xmlparser_UseForeignDTD_impl(xmlparseobject *self, int flag) +/*[clinic end generated code: output=22e924ae6cad67d6 input=78144c519d116a6e]*/ +{ enum XML_Error rc; - if (!PyArg_ParseTuple(args, "|p:UseForeignDTD", &flag)) - return NULL; + rc = XML_UseForeignDTD(self->itself, flag ? XML_TRUE : XML_FALSE); if (rc != XML_ERROR_NONE) { return set_error(self, rc); @@ -1099,29 +1230,86 @@ xmlparse_UseForeignDTD(xmlparseobject *self, PyObject *args) } #endif -static PyObject *xmlparse_dir(PyObject *self, PyObject* noargs); +/*[clinic input] +pyexpat.xmlparser.__dir__ +[clinic start generated code]*/ + +PyDoc_STRVAR(pyexpat_xmlparser___dir____doc__, +"__dir__($self, /)\n" +"--"); + +#define PYEXPAT_XMLPARSER___DIR___METHODDEF \ + {"__dir__", (PyCFunction)pyexpat_xmlparser___dir__, METH_NOARGS, pyexpat_xmlparser___dir____doc__}, + +static PyObject * +pyexpat_xmlparser___dir___impl(xmlparseobject *self); + +static PyObject * +pyexpat_xmlparser___dir__(xmlparseobject *self, PyObject *Py_UNUSED(ignored)) +{ + return pyexpat_xmlparser___dir___impl(self); +} + +static PyObject * +pyexpat_xmlparser___dir___impl(xmlparseobject *self) +/*[clinic end generated code: output=1ed6efe83bc304cc input=76aa455f2a661384]*/ +{ +#define APPEND(list, str) \ + do { \ + PyObject *o = PyUnicode_FromString(str); \ + if (o != NULL) \ + PyList_Append(list, o); \ + Py_XDECREF(o); \ + } while (0) + + int i; + PyObject *rc = PyList_New(0); + if (!rc) + return NULL; + for (i = 0; handler_info[i].name != NULL; i++) { + PyObject *o = get_handler_name(&handler_info[i]); + if (o != NULL) + PyList_Append(rc, o); + Py_XDECREF(o); + } + APPEND(rc, "ErrorCode"); + APPEND(rc, "ErrorLineNumber"); + APPEND(rc, "ErrorColumnNumber"); + APPEND(rc, "ErrorByteIndex"); + APPEND(rc, "CurrentLineNumber"); + APPEND(rc, "CurrentColumnNumber"); + APPEND(rc, "CurrentByteIndex"); + APPEND(rc, "buffer_size"); + APPEND(rc, "buffer_text"); + APPEND(rc, "buffer_used"); + APPEND(rc, "namespace_prefixes"); + APPEND(rc, "ordered_attributes"); + APPEND(rc, "specified_attributes"); + APPEND(rc, "intern"); + +#undef APPEND + + if (PyErr_Occurred()) { + Py_DECREF(rc); + rc = NULL; + } + + return rc; +} static struct PyMethodDef xmlparse_methods[] = { - {"Parse", (PyCFunction)xmlparse_Parse, - METH_VARARGS, xmlparse_Parse__doc__}, - {"ParseFile", (PyCFunction)xmlparse_ParseFile, - METH_O, xmlparse_ParseFile__doc__}, - {"SetBase", (PyCFunction)xmlparse_SetBase, - METH_VARARGS, xmlparse_SetBase__doc__}, - {"GetBase", (PyCFunction)xmlparse_GetBase, - METH_NOARGS, xmlparse_GetBase__doc__}, - {"ExternalEntityParserCreate", (PyCFunction)xmlparse_ExternalEntityParserCreate, - METH_VARARGS, xmlparse_ExternalEntityParserCreate__doc__}, - {"SetParamEntityParsing", (PyCFunction)xmlparse_SetParamEntityParsing, - METH_VARARGS, xmlparse_SetParamEntityParsing__doc__}, - {"GetInputContext", (PyCFunction)xmlparse_GetInputContext, - METH_NOARGS, xmlparse_GetInputContext__doc__}, + PYEXPAT_XMLPARSER_PARSE_METHODDEF + PYEXPAT_XMLPARSER_PARSEFILE_METHODDEF + PYEXPAT_XMLPARSER_SETBASE_METHODDEF + PYEXPAT_XMLPARSER_GETBASE_METHODDEF + PYEXPAT_XMLPARSER_GETINPUTCONTEXT_METHODDEF + PYEXPAT_XMLPARSER_EXTERNALENTITYPARSERCREATE_METHODDEF + PYEXPAT_XMLPARSER_SETPARAMENTITYPARSING_METHODDEF #if XML_COMBINED_VERSION >= 19505 - {"UseForeignDTD", (PyCFunction)xmlparse_UseForeignDTD, - METH_VARARGS, xmlparse_UseForeignDTD__doc__}, + PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF #endif - {"__dir__", xmlparse_dir, METH_NOARGS}, - {NULL, NULL} /* sentinel */ + PYEXPAT_XMLPARSER___DIR___METHODDEF + {NULL, NULL} /* sentinel */ }; /* ---------- */ @@ -1184,7 +1372,7 @@ PyUnknownEncodingHandler(void *encodingHandlerData, static PyObject * -newxmlparseobject(char *encoding, char *namespace_separator, PyObject *intern) +newxmlparseobject(const char *encoding, const char *namespace_separator, PyObject *intern) { int i; xmlparseobject *self; @@ -1228,7 +1416,7 @@ newxmlparseobject(char *encoding, char *namespace_separator, PyObject *intern) for (i = 0; handler_info[i].name != NULL; i++) /* do nothing */; - self->handlers = PyMem_Malloc(sizeof(PyObject *) * i); + self->handlers = PyMem_New(PyObject *, i); if (!self->handlers) { Py_DECREF(self); return PyErr_NoMemory(); @@ -1362,52 +1550,6 @@ xmlparse_getattro(xmlparseobject *self, PyObject *nameobj) return PyObject_GenericGetAttr((PyObject*)self, nameobj); } -static PyObject * -xmlparse_dir(PyObject *self, PyObject* noargs) -{ -#define APPEND(list, str) \ - do { \ - PyObject *o = PyUnicode_FromString(str); \ - if (o != NULL) \ - PyList_Append(list, o); \ - Py_XDECREF(o); \ - } while (0) - - int i; - PyObject *rc = PyList_New(0); - if (!rc) - return NULL; - for (i = 0; handler_info[i].name != NULL; i++) { - PyObject *o = get_handler_name(&handler_info[i]); - if (o != NULL) - PyList_Append(rc, o); - Py_XDECREF(o); - } - APPEND(rc, "ErrorCode"); - APPEND(rc, "ErrorLineNumber"); - APPEND(rc, "ErrorColumnNumber"); - APPEND(rc, "ErrorByteIndex"); - APPEND(rc, "CurrentLineNumber"); - APPEND(rc, "CurrentColumnNumber"); - APPEND(rc, "CurrentByteIndex"); - APPEND(rc, "buffer_size"); - APPEND(rc, "buffer_text"); - APPEND(rc, "buffer_used"); - APPEND(rc, "namespace_prefixes"); - APPEND(rc, "ordered_attributes"); - APPEND(rc, "specified_attributes"); - APPEND(rc, "intern"); - -#undef APPEND - - if (PyErr_Occurred()) { - Py_DECREF(rc); - rc = NULL; - } - - return rc; -} - static int sethandler(xmlparseobject *self, PyObject *name, PyObject* v) { @@ -1613,24 +1755,55 @@ static PyTypeObject Xmlparsetype = { /* End of code for xmlparser objects */ /* -------------------------------------------------------- */ +/*[clinic input] +pyexpat.ParserCreate + + encoding: str(nullable=True) = NULL + namespace_separator: str(nullable=True) = NULL + intern: object = NULL + +Return a new XML parser object. +[clinic start generated code]*/ + PyDoc_STRVAR(pyexpat_ParserCreate__doc__, -"ParserCreate([encoding[, namespace_separator]]) -> parser\n\ -Return a new XML parser object."); +"ParserCreate($module, /, encoding=None, namespace_separator=None,\n" +" intern=None)\n" +"--\n" +"\n" +"Return a new XML parser object."); + +#define PYEXPAT_PARSERCREATE_METHODDEF \ + {"ParserCreate", (PyCFunction)pyexpat_ParserCreate, METH_VARARGS|METH_KEYWORDS, pyexpat_ParserCreate__doc__}, static PyObject * -pyexpat_ParserCreate(PyObject *notused, PyObject *args, PyObject *kw) +pyexpat_ParserCreate_impl(PyModuleDef *module, const char *encoding, const char *namespace_separator, PyObject *intern); + +static PyObject * +pyexpat_ParserCreate(PyModuleDef *module, PyObject *args, PyObject *kwargs) { - char *encoding = NULL; - char *namespace_separator = NULL; + PyObject *return_value = NULL; + static char *_keywords[] = {"encoding", "namespace_separator", "intern", NULL}; + const char *encoding = NULL; + const char *namespace_separator = NULL; PyObject *intern = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "|zzO:ParserCreate", _keywords, + &encoding, &namespace_separator, &intern)) + goto exit; + return_value = pyexpat_ParserCreate_impl(module, encoding, namespace_separator, intern); + +exit: + return return_value; +} + +static PyObject * +pyexpat_ParserCreate_impl(PyModuleDef *module, const char *encoding, const char *namespace_separator, PyObject *intern) +/*[clinic end generated code: output=4fc027dd33b7a2ac input=71b9f471aa6f8f86]*/ +{ PyObject *result; int intern_decref = 0; - static char *kwlist[] = {"encoding", "namespace_separator", - "intern", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kw, "|zzO:ParserCreate", kwlist, - &encoding, &namespace_separator, &intern)) - return NULL; if (namespace_separator != NULL && strlen(namespace_separator) > 1) { PyErr_SetString(PyExc_ValueError, @@ -1660,29 +1833,56 @@ pyexpat_ParserCreate(PyObject *notused, PyObject *args, PyObject *kw) return result; } +/*[clinic input] +pyexpat.ErrorString + + code: long + / + +Returns string error for given number. +[clinic start generated code]*/ + PyDoc_STRVAR(pyexpat_ErrorString__doc__, -"ErrorString(errno) -> string\n\ -Returns string error for given number."); +"ErrorString($module, code, /)\n" +"--\n" +"\n" +"Returns string error for given number."); + +#define PYEXPAT_ERRORSTRING_METHODDEF \ + {"ErrorString", (PyCFunction)pyexpat_ErrorString, METH_VARARGS, pyexpat_ErrorString__doc__}, + +static PyObject * +pyexpat_ErrorString_impl(PyModuleDef *module, long code); static PyObject * -pyexpat_ErrorString(PyObject *self, PyObject *args) +pyexpat_ErrorString(PyModuleDef *module, PyObject *args) { - long code = 0; + PyObject *return_value = NULL; + long code; - if (!PyArg_ParseTuple(args, "l:ErrorString", &code)) - return NULL; + if (!PyArg_ParseTuple(args, + "l:ErrorString", + &code)) + goto exit; + return_value = pyexpat_ErrorString_impl(module, code); + +exit: + return return_value; +} + +static PyObject * +pyexpat_ErrorString_impl(PyModuleDef *module, long code) +/*[clinic end generated code: output=c70f3cd82bfaf067 input=cc67de010d9e62b3]*/ +{ return Py_BuildValue("z", XML_ErrorString((int)code)); } /* List of methods defined in the module */ static struct PyMethodDef pyexpat_methods[] = { - {"ParserCreate", (PyCFunction)pyexpat_ParserCreate, - METH_VARARGS|METH_KEYWORDS, pyexpat_ParserCreate__doc__}, - {"ErrorString", (PyCFunction)pyexpat_ErrorString, - METH_VARARGS, pyexpat_ErrorString__doc__}, - - {NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */ + PYEXPAT_PARSERCREATE_METHODDEF + PYEXPAT_ERRORSTRING_METHODDEF + {NULL, NULL} /* sentinel */ }; /* Module docstring */ @@ -1767,7 +1967,7 @@ MODULE_INITFUNC(void) PyModule_AddObject(m, "XMLParserType", (PyObject *) &Xmlparsetype); PyModule_AddStringConstant(m, "EXPAT_VERSION", - (char *) XML_ExpatVersion()); + XML_ExpatVersion()); { XML_Expat_Version info = XML_ExpatVersionInfo(); PyModule_AddObject(m, "version_info", @@ -1847,7 +2047,7 @@ MODULE_INITFUNC(void) #define MYCONST(name) \ if (PyModule_AddStringConstant(errors_module, #name, \ - (char *)XML_ErrorString(name)) < 0) \ + XML_ErrorString(name)) < 0) \ return NULL; \ tmpnum = PyLong_FromLong(name); \ if (tmpnum == NULL) return NULL; \ @@ -2058,3 +2258,12 @@ static struct HandlerInfo handler_info[] = { {NULL, NULL, NULL} /* sentinel */ }; + +/*[clinic input] +dump buffer +[clinic start generated code]*/ + +#ifndef PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF + #define PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF +#endif /* !defined(PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF) */ +/*[clinic end generated code: output=a7880cb78bbd58ce input=524ce2e021e4eba6]*/ diff --git a/Modules/readline.c b/Modules/readline.c index f255a8747f9f..26dfffbfaa93 100644 --- a/Modules/readline.c +++ b/Modules/readline.c @@ -237,6 +237,43 @@ Save a readline history file.\n\ The default filename is ~/.history."); +#ifdef HAVE_RL_APPEND_HISTORY +/* Exported function to save part of a readline history file */ + +static PyObject * +append_history_file(PyObject *self, PyObject *args) +{ + int nelements; + PyObject *filename_obj = Py_None, *filename_bytes; + char *filename; + int err; + if (!PyArg_ParseTuple(args, "i|O:append_history_file", &nelements, &filename_obj)) + return NULL; + if (filename_obj != Py_None) { + if (!PyUnicode_FSConverter(filename_obj, &filename_bytes)) + return NULL; + filename = PyBytes_AsString(filename_bytes); + } else { + filename_bytes = NULL; + filename = NULL; + } + errno = err = append_history(nelements, filename); + if (!err && _history_length >= 0) + history_truncate_file(filename, _history_length); + Py_XDECREF(filename_bytes); + errno = err; + if (errno) + return PyErr_SetFromErrno(PyExc_IOError); + Py_RETURN_NONE; +} + +PyDoc_STRVAR(doc_append_history_file, +"append_history_file(nelements[, filename]) -> None\n\ +Append the last nelements of the history list to file.\n\ +The default filename is ~/.history."); +#endif + + /* Set history length */ static PyObject* @@ -281,8 +318,7 @@ set_hook(const char *funcname, PyObject **hook_var, PyObject *args) if (!PyArg_ParseTuple(args, buf, &function)) return NULL; if (function == Py_None) { - Py_XDECREF(*hook_var); - *hook_var = NULL; + Py_CLEAR(*hook_var); } else if (PyCallable_Check(function)) { PyObject *tmp = *hook_var; @@ -748,6 +784,10 @@ static struct PyMethodDef readline_methods[] = METH_VARARGS, doc_read_history_file}, {"write_history_file", write_history_file, METH_VARARGS, doc_write_history_file}, +#ifdef HAVE_RL_APPEND_HISTORY + {"append_history_file", append_history_file, + METH_VARARGS, doc_append_history_file}, +#endif {"get_history_item", get_history_item, METH_VARARGS, doc_get_history_item}, {"get_current_history_length", (PyCFunction)get_current_history_length, @@ -816,7 +856,11 @@ on_hook(PyObject *func) } static int +#if defined(_RL_FUNCTION_TYPEDEF) on_startup_hook(void) +#else +on_startup_hook() +#endif { int r; #ifdef WITH_THREAD @@ -831,7 +875,11 @@ on_startup_hook(void) #ifdef HAVE_RL_PRE_INPUT_HOOK static int +#if defined(_RL_FUNCTION_TYPEDEF) on_pre_input_hook(void) +#else +on_pre_input_hook() +#endif { int r; #ifdef WITH_THREAD @@ -877,7 +925,7 @@ on_completion_display_matches_hook(char **matches, (r != Py_None && PyLong_AsLong(r) == -1 && PyErr_Occurred())) { goto error; } - Py_XDECREF(r); r=NULL; + Py_CLEAR(r); if (0) { error: @@ -935,7 +983,7 @@ on_completion(const char *text, int state) * before calling the normal completer */ static char ** -flex_complete(char *text, int start, int end) +flex_complete(const char *text, int start, int end) { char **result; #ifdef WITH_THREAD @@ -998,12 +1046,12 @@ setup_readline(readlinestate *mod_state) rl_bind_key_in_map ('\t', rl_complete, emacs_meta_keymap); rl_bind_key_in_map ('\033', rl_complete, emacs_meta_keymap); /* Set our hook functions */ - rl_startup_hook = (Function *)on_startup_hook; + rl_startup_hook = on_startup_hook; #ifdef HAVE_RL_PRE_INPUT_HOOK - rl_pre_input_hook = (Function *)on_pre_input_hook; + rl_pre_input_hook = on_pre_input_hook; #endif /* Set our completion function */ - rl_attempted_completion_function = (CPPFunction *)flex_complete; + rl_attempted_completion_function = flex_complete; /* Set Python word break characters */ completer_word_break_characters = rl_completer_word_break_characters = @@ -1012,6 +1060,21 @@ setup_readline(readlinestate *mod_state) mod_state->begidx = PyLong_FromLong(0L); mod_state->endidx = PyLong_FromLong(0L); + +#ifndef __APPLE__ + if (!isatty(STDOUT_FILENO)) { + /* Issue #19884: stdout is no a terminal. Disable meta modifier + keys to not write the ANSI sequence "\033[1034h" into stdout. On + terminals supporting 8 bit characters like TERM=xterm-256color + (which is now the default Fedora since Fedora 18), the meta key is + used to enable support of 8 bit characters (ANSI sequence + "\033[1034h"). + + With libedit, this call makes readline() crash. */ + rl_variable_bind ("enable-meta-key", "off"); + } +#endif + /* Initialize (allows .inputrc to override) * * XXX: A bug in the readline-2.2 library causes a memory leak @@ -1118,7 +1181,7 @@ onintr(int sig) static char * -readline_until_enter_or_signal(char *prompt, int *signal) +readline_until_enter_or_signal(const char *prompt, int *signal) { PyOS_sighandler_t old_inthandler; char *p; @@ -1263,5 +1326,9 @@ PyInit_readline(void) mod_state = (readlinestate *) PyModule_GetState(m); PyOS_ReadlineFunctionPointer = call_readline; setup_readline(mod_state); + + PyModule_AddIntConstant(m, "_READLINE_VERSION", RL_READLINE_VERSION); + PyModule_AddIntConstant(m, "_READLINE_RUNTIME_VERSION", rl_readline_version); + return m; } diff --git a/Modules/resource.c b/Modules/resource.c index c12ce341fee2..3a1cf094c75e 100644 --- a/Modules/resource.c +++ b/Modules/resource.c @@ -424,6 +424,20 @@ PyInit_resource(void) PyModule_AddIntMacro(m, RUSAGE_THREAD); #endif +/* FreeBSD specific */ + +#ifdef RLIMIT_SWAP + PyModule_AddIntMacro(m, RLIMIT_SWAP); +#endif + +#ifdef RLIMIT_SBSIZE + PyModule_AddIntMacro(m, RLIMIT_SBSIZE); +#endif + +#ifdef RLIMIT_NPTS + PyModule_AddIntMacro(m, RLIMIT_NPTS); +#endif + #if defined(HAVE_LONG_LONG) if (sizeof(RLIM_INFINITY) > sizeof(long)) { v = PyLong_FromLongLong((PY_LONG_LONG) RLIM_INFINITY); diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index 6291a2daa929..ffaf865df2b7 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -52,9 +52,6 @@ extern void bzero(void *, int); # include #else # define SOCKET int -# if defined(__VMS) -# include -# endif #endif /* list of Python objects and their file descriptor */ @@ -69,8 +66,7 @@ reap_obj(pylist fd2obj[FD_SETSIZE + 1]) { int i; for (i = 0; i < FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) { - Py_XDECREF(fd2obj[i].obj); - fd2obj[i].obj = NULL; + Py_CLEAR(fd2obj[i].obj); } fd2obj[0].sentinel = -1; } @@ -216,10 +212,18 @@ select_select(PyObject *self, PyObject *args) return NULL; } else { -#ifdef MS_WINDOWS + /* On OpenBSD 5.4, timeval.tv_sec is a long. + * Example: long is 64-bit, whereas time_t is 32-bit. */ time_t sec; - if (_PyTime_ObjectToTimeval(tout, &sec, &tv.tv_usec) == -1) + /* On OS X 64-bit, timeval.tv_usec is an int (and thus still 4 + bytes as required), but no longer defined by a long. */ + long usec; + if (_PyTime_ObjectToTimeval(tout, &sec, &usec, + _PyTime_ROUND_UP) == -1) return NULL; +#ifdef MS_WINDOWS + /* On Windows, timeval.tv_sec is a long (32 bit), + * whereas time_t can be 64-bit. */ assert(sizeof(tv.tv_sec) == sizeof(long)); #if SIZEOF_TIME_T > SIZEOF_LONG if (sec > LONG_MAX) { @@ -230,13 +234,10 @@ select_select(PyObject *self, PyObject *args) #endif tv.tv_sec = (long)sec; #else - /* 64-bit OS X has struct timeval.tv_usec as an int (and thus still 4 - bytes as required), but no longer defined by a long. */ - long tv_usec; - if (_PyTime_ObjectToTimeval(tout, &tv.tv_sec, &tv_usec) == -1) - return NULL; - tv.tv_usec = tv_usec; + assert(sizeof(tv.tv_sec) >= sizeof(sec)); + tv.tv_sec = sec; #endif + tv.tv_usec = usec; if (tv.tv_sec < 0) { PyErr_SetString(PyExc_ValueError, "timeout must be non-negative"); return NULL; @@ -356,7 +357,7 @@ update_ufd_array(pollObject *self) assert(i < self->ufd_len); /* Never overflow */ self->ufds[i].fd = (int)PyLong_AsLong(key); - self->ufds[i].events = (short)PyLong_AsLong(value); + self->ufds[i].events = (short)(unsigned short)PyLong_AsLong(value); i++; } assert(i == self->ufd_len); @@ -364,6 +365,24 @@ update_ufd_array(pollObject *self) return 1; } +static int +ushort_converter(PyObject *obj, void *ptr) +{ + unsigned long uval; + + uval = PyLong_AsUnsignedLong(obj); + if (uval == (unsigned long)-1 && PyErr_Occurred()) + return 0; + if (uval > USHRT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "Python int too large for C unsigned short"); + return 0; + } + + *(unsigned short *)ptr = Py_SAFE_DOWNCAST(uval, unsigned long, unsigned short); + return 1; +} + PyDoc_STRVAR(poll_register_doc, "register(fd [, eventmask] ) -> None\n\n\ Register a file descriptor with the polling object.\n\ @@ -376,12 +395,11 @@ poll_register(pollObject *self, PyObject *args) { PyObject *o, *key, *value; int fd; - short events = POLLIN | POLLPRI | POLLOUT; + unsigned short events = POLLIN | POLLPRI | POLLOUT; int err; - if (!PyArg_ParseTuple(args, "O|h:register", &o, &events)) { + if (!PyArg_ParseTuple(args, "O|O&:register", &o, ushort_converter, &events)) return NULL; - } fd = PyObject_AsFileDescriptor(o); if (fd == -1) return NULL; @@ -419,12 +437,12 @@ static PyObject * poll_modify(pollObject *self, PyObject *args) { PyObject *o, *key, *value; - int fd, events; + int fd; + unsigned short events; int err; - if (!PyArg_ParseTuple(args, "Oi:modify", &o, &events)) { + if (!PyArg_ParseTuple(args, "OO&:modify", &o, ushort_converter, &events)) return NULL; - } fd = PyObject_AsFileDescriptor(o); if (fd == -1) return NULL; @@ -729,14 +747,14 @@ static PyObject * internal_devpoll_register(devpollObject *self, PyObject *args, int remove) { PyObject *o; - int fd, events = POLLIN | POLLPRI | POLLOUT; + int fd; + unsigned short events = POLLIN | POLLPRI | POLLOUT; if (self->fd_devpoll < 0) return devpoll_err_closed(); - if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) { + if (!PyArg_ParseTuple(args, "O|O&:register", &o, ushort_converter, &events)) return NULL; - } fd = PyObject_AsFileDescriptor(o); if (fd == -1) return NULL; @@ -752,7 +770,7 @@ internal_devpoll_register(devpollObject *self, PyObject *args, int remove) } self->fds[self->n_fds].fd = fd; - self->fds[self->n_fds].events = events; + self->fds[self->n_fds].events = (signed short)events; if (++self->n_fds == self->max_n_fds) { if (devpoll_flush(self)) @@ -1317,16 +1335,16 @@ pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events) return NULL; } - switch(op) { - case EPOLL_CTL_ADD: - case EPOLL_CTL_MOD: + switch (op) { + case EPOLL_CTL_ADD: + case EPOLL_CTL_MOD: ev.events = events; ev.data.fd = fd; Py_BEGIN_ALLOW_THREADS result = epoll_ctl(epfd, op, fd, &ev); Py_END_ALLOW_THREADS break; - case EPOLL_CTL_DEL: + case EPOLL_CTL_DEL: /* In kernel versions before 2.6.9, the EPOLL_CTL_DEL * operation required a non-NULL pointer in event, even * though this argument is ignored. */ @@ -1339,7 +1357,7 @@ pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events) } Py_END_ALLOW_THREADS break; - default: + default: result = -1; errno = EINVAL; } @@ -1444,7 +1462,9 @@ pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds) return NULL; } else { - timeout = (int)(dtimeout * 1000.0); + /* epoll_wait() has a resolution of 1 millisecond, round away from zero + to wait *at least* dtimeout seconds. */ + timeout = (int)ceil(dtimeout * 1000.0); } if (maxevents == -1) { @@ -1691,17 +1711,17 @@ static PyTypeObject kqueue_queue_Type; * kevent is not standard and its members vary across BSDs. */ #if !defined(__OpenBSD__) -# define IDENT_TYPE T_UINTPTRT -# define IDENT_CAST Py_intptr_t -# define DATA_TYPE T_INTPTRT +# define IDENT_TYPE T_UINTPTRT +# define IDENT_CAST Py_intptr_t +# define DATA_TYPE T_INTPTRT # define DATA_FMT_UNIT INTPTRT_FMT_UNIT -# define IDENT_AsType PyLong_AsUintptr_t +# define IDENT_AsType PyLong_AsUintptr_t #else -# define IDENT_TYPE T_UINT -# define IDENT_CAST int -# define DATA_TYPE T_INT +# define IDENT_TYPE T_UINT +# define IDENT_CAST int +# define DATA_TYPE T_INT # define DATA_FMT_UNIT "i" -# define IDENT_AsType PyLong_AsUnsignedLong +# define IDENT_AsType PyLong_AsUnsignedLong #endif /* Unfortunately, we can't store python objects in udata, because @@ -1753,7 +1773,7 @@ kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds) if (PyLong_Check(pfd) #if IDENT_TYPE == T_UINT - && PyLong_AsUnsignedLong(pfd) <= UINT_MAX + && PyLong_AsUnsignedLong(pfd) <= UINT_MAX #endif ) { self->e.ident = IDENT_AsType(pfd); @@ -1795,22 +1815,22 @@ kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o, } switch (op) { - case Py_EQ: + case Py_EQ: result = (result == 0); break; - case Py_NE: + case Py_NE: result = (result != 0); break; - case Py_LE: + case Py_LE: result = (result <= 0); break; - case Py_GE: + case Py_GE: result = (result >= 0); break; - case Py_LT: + case Py_LT: result = (result < 0); break; - case Py_GT: + case Py_GT: result = (result > 0); break; } @@ -2022,8 +2042,8 @@ kqueue_queue_control(kqueue_queue_Object *self, PyObject *args) ptimeoutspec = NULL; } else if (PyNumber_Check(otimeout)) { - if (_PyTime_ObjectToTimespec(otimeout, - &timeout.tv_sec, &timeout.tv_nsec) == -1) + if (_PyTime_ObjectToTimespec(otimeout, &timeout.tv_sec, + &timeout.tv_nsec, _PyTime_ROUND_UP) == -1) return NULL; if (timeout.tv_sec < 0) { @@ -2236,7 +2256,7 @@ arguments; each contains the subset of the corresponding file descriptors\n\ that are ready.\n\ \n\ *** IMPORTANT NOTICE ***\n\ -On Windows and OpenVMS, only sockets are supported; on Unix, all file\n\ +On Windows only sockets are supported; on Unix, all file\n\ descriptors can be used."); static PyMethodDef select_methods[] = { @@ -2254,7 +2274,7 @@ PyDoc_STRVAR(module_doc, "This module supports asynchronous I/O on multiple file descriptors.\n\ \n\ *** IMPORTANT NOTICE ***\n\ -On Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors."); +On Windows only sockets are supported; on Unix, all file descriptors."); static struct PyModuleDef selectmodule = { diff --git a/Modules/sha1module.c b/Modules/sha1module.c index b44fe189d267..8961de48d8fc 100644 --- a/Modules/sha1module.c +++ b/Modules/sha1module.c @@ -19,6 +19,11 @@ #include "Python.h" #include "hashlib.h" +/*[clinic input] +module _sha1 +class SHA1Type "SHA1object *" "&PyType_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3dc9a20d1becb759]*/ /* Some useful types */ @@ -309,10 +314,33 @@ SHA1_dealloc(PyObject *ptr) /* External methods for a hash object */ -PyDoc_STRVAR(SHA1_copy__doc__, "Return a copy of the hash object."); +/*[clinic input] +SHA1Type.copy + +Return a copy of the hash object. +[clinic start generated code]*/ + +PyDoc_STRVAR(SHA1Type_copy__doc__, +"copy($self, /)\n" +"--\n" +"\n" +"Return a copy of the hash object."); + +#define SHA1TYPE_COPY_METHODDEF \ + {"copy", (PyCFunction)SHA1Type_copy, METH_NOARGS, SHA1Type_copy__doc__}, + +static PyObject * +SHA1Type_copy_impl(SHA1object *self); + +static PyObject * +SHA1Type_copy(SHA1object *self, PyObject *Py_UNUSED(ignored)) +{ + return SHA1Type_copy_impl(self); +} static PyObject * -SHA1_copy(SHA1object *self, PyObject *unused) +SHA1Type_copy_impl(SHA1object *self) +/*[clinic end generated code: output=1a320e75a7444098 input=b7eae10df6f89b36]*/ { SHA1object *newobj; @@ -323,11 +351,33 @@ SHA1_copy(SHA1object *self, PyObject *unused) return (PyObject *)newobj; } -PyDoc_STRVAR(SHA1_digest__doc__, +/*[clinic input] +SHA1Type.digest + +Return the digest value as a string of binary data. +[clinic start generated code]*/ + +PyDoc_STRVAR(SHA1Type_digest__doc__, +"digest($self, /)\n" +"--\n" +"\n" "Return the digest value as a string of binary data."); +#define SHA1TYPE_DIGEST_METHODDEF \ + {"digest", (PyCFunction)SHA1Type_digest, METH_NOARGS, SHA1Type_digest__doc__}, + static PyObject * -SHA1_digest(SHA1object *self, PyObject *unused) +SHA1Type_digest_impl(SHA1object *self); + +static PyObject * +SHA1Type_digest(SHA1object *self, PyObject *Py_UNUSED(ignored)) +{ + return SHA1Type_digest_impl(self); +} + +static PyObject * +SHA1Type_digest_impl(SHA1object *self) +/*[clinic end generated code: output=c4920f75228bfbfd input=205d47e1927fd009]*/ { unsigned char digest[SHA1_DIGESTSIZE]; struct sha1_state temp; @@ -337,11 +387,33 @@ SHA1_digest(SHA1object *self, PyObject *unused) return PyBytes_FromStringAndSize((const char *)digest, SHA1_DIGESTSIZE); } -PyDoc_STRVAR(SHA1_hexdigest__doc__, +/*[clinic input] +SHA1Type.hexdigest + +Return the digest value as a string of hexadecimal digits. +[clinic start generated code]*/ + +PyDoc_STRVAR(SHA1Type_hexdigest__doc__, +"hexdigest($self, /)\n" +"--\n" +"\n" "Return the digest value as a string of hexadecimal digits."); +#define SHA1TYPE_HEXDIGEST_METHODDEF \ + {"hexdigest", (PyCFunction)SHA1Type_hexdigest, METH_NOARGS, SHA1Type_hexdigest__doc__}, + +static PyObject * +SHA1Type_hexdigest_impl(SHA1object *self); + static PyObject * -SHA1_hexdigest(SHA1object *self, PyObject *unused) +SHA1Type_hexdigest(SHA1object *self, PyObject *Py_UNUSED(ignored)) +{ + return SHA1Type_hexdigest_impl(self); +} + +static PyObject * +SHA1Type_hexdigest_impl(SHA1object *self) +/*[clinic end generated code: output=6e345aac201887b2 input=97691055c0c74ab0]*/ { unsigned char digest[SHA1_DIGESTSIZE]; struct sha1_state temp; @@ -373,18 +445,30 @@ SHA1_hexdigest(SHA1object *self, PyObject *unused) return retval; } -PyDoc_STRVAR(SHA1_update__doc__, -"Update this hash object's state with the provided string."); +/*[clinic input] +SHA1Type.update + + obj: object + / + +Update this hash object's state with the provided string. +[clinic start generated code]*/ + +PyDoc_STRVAR(SHA1Type_update__doc__, +"update($self, obj, /)\n" +"--\n" +"\n" +"Update this hash object\'s state with the provided string."); + +#define SHA1TYPE_UPDATE_METHODDEF \ + {"update", (PyCFunction)SHA1Type_update, METH_O, SHA1Type_update__doc__}, static PyObject * -SHA1_update(SHA1object *self, PyObject *args) +SHA1Type_update(SHA1object *self, PyObject *obj) +/*[clinic end generated code: output=ab20a86a25e7d255 input=aad8e07812edbba3]*/ { - PyObject *obj; Py_buffer buf; - if (!PyArg_ParseTuple(args, "O:update", &obj)) - return NULL; - GET_BUFFER_VIEW_OR_ERROUT(obj, &buf); sha1_process(&self->hash_state, buf.buf, buf.len); @@ -395,10 +479,10 @@ SHA1_update(SHA1object *self, PyObject *args) } static PyMethodDef SHA1_methods[] = { - {"copy", (PyCFunction)SHA1_copy, METH_NOARGS, SHA1_copy__doc__}, - {"digest", (PyCFunction)SHA1_digest, METH_NOARGS, SHA1_digest__doc__}, - {"hexdigest", (PyCFunction)SHA1_hexdigest, METH_NOARGS, SHA1_hexdigest__doc__}, - {"update", (PyCFunction)SHA1_update, METH_VARARGS, SHA1_update__doc__}, + SHA1TYPE_COPY_METHODDEF + SHA1TYPE_DIGEST_METHODDEF + SHA1TYPE_HEXDIGEST_METHODDEF + SHA1TYPE_UPDATE_METHODDEF {NULL, NULL} /* sentinel */ }; @@ -474,27 +558,55 @@ static PyTypeObject SHA1type = { /* The single module-level function: new() */ -PyDoc_STRVAR(SHA1_new__doc__, +/*[clinic input] +_sha1.sha1 + + string: object(c_default="NULL") = b'' + +Return a new SHA1 hash object; optionally initialized with a string. +[clinic start generated code]*/ + +PyDoc_STRVAR(_sha1_sha1__doc__, +"sha1($module, /, string=b\'\')\n" +"--\n" +"\n" "Return a new SHA1 hash object; optionally initialized with a string."); +#define _SHA1_SHA1_METHODDEF \ + {"sha1", (PyCFunction)_sha1_sha1, METH_VARARGS|METH_KEYWORDS, _sha1_sha1__doc__}, + +static PyObject * +_sha1_sha1_impl(PyModuleDef *module, PyObject *string); + static PyObject * -SHA1_new(PyObject *self, PyObject *args, PyObject *kwdict) +_sha1_sha1(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"string", NULL}; + PyObject *string = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "|O:sha1", _keywords, + &string)) + goto exit; + return_value = _sha1_sha1_impl(module, string); + +exit: + return return_value; +} + +static PyObject * +_sha1_sha1_impl(PyModuleDef *module, PyObject *string) +/*[clinic end generated code: output=c9068552f07b8954 input=27ea54281d995ec2]*/ { - static char *kwlist[] = {"string", NULL}; SHA1object *new; - PyObject *data_obj = NULL; Py_buffer buf; - if (!PyArg_ParseTupleAndKeywords(args, kwdict, "|O:new", kwlist, - &data_obj)) { - return NULL; - } - - if (data_obj) - GET_BUFFER_VIEW_OR_ERROUT(data_obj, &buf); + if (string) + GET_BUFFER_VIEW_OR_ERROUT(string, &buf); if ((new = newSHA1object()) == NULL) { - if (data_obj) + if (string) PyBuffer_Release(&buf); return NULL; } @@ -503,11 +615,11 @@ SHA1_new(PyObject *self, PyObject *args, PyObject *kwdict) if (PyErr_Occurred()) { Py_DECREF(new); - if (data_obj) + if (string) PyBuffer_Release(&buf); return NULL; } - if (data_obj) { + if (string) { sha1_process(&new->hash_state, buf.buf, buf.len); PyBuffer_Release(&buf); } @@ -519,7 +631,7 @@ SHA1_new(PyObject *self, PyObject *args, PyObject *kwdict) /* List of functions exported by this module */ static struct PyMethodDef SHA1_functions[] = { - {"sha1",(PyCFunction)SHA1_new, METH_VARARGS|METH_KEYWORDS,SHA1_new__doc__}, + _SHA1_SHA1_METHODDEF {NULL, NULL} /* Sentinel */ }; diff --git a/Modules/sha256module.c b/Modules/sha256module.c index b05bfc172f51..7b1488696f49 100644 --- a/Modules/sha256module.c +++ b/Modules/sha256module.c @@ -20,6 +20,11 @@ #include "structmember.h" #include "hashlib.h" +/*[clinic input] +module _sha256 +class SHA256Type "SHAobject *" "&PyType_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=71a39174d4f0a744]*/ /* Some useful types */ @@ -393,10 +398,33 @@ SHA_dealloc(PyObject *ptr) /* External methods for a hash object */ -PyDoc_STRVAR(SHA256_copy__doc__, "Return a copy of the hash object."); +/*[clinic input] +SHA256Type.copy + +Return a copy of the hash object. +[clinic start generated code]*/ + +PyDoc_STRVAR(SHA256Type_copy__doc__, +"copy($self, /)\n" +"--\n" +"\n" +"Return a copy of the hash object."); + +#define SHA256TYPE_COPY_METHODDEF \ + {"copy", (PyCFunction)SHA256Type_copy, METH_NOARGS, SHA256Type_copy__doc__}, + +static PyObject * +SHA256Type_copy_impl(SHAobject *self); static PyObject * -SHA256_copy(SHAobject *self, PyObject *unused) +SHA256Type_copy(SHAobject *self, PyObject *Py_UNUSED(ignored)) +{ + return SHA256Type_copy_impl(self); +} + +static PyObject * +SHA256Type_copy_impl(SHAobject *self) +/*[clinic end generated code: output=f716c39d3f81c27c input=f58840a618d4f2a7]*/ { SHAobject *newobj; @@ -412,11 +440,33 @@ SHA256_copy(SHAobject *self, PyObject *unused) return (PyObject *)newobj; } -PyDoc_STRVAR(SHA256_digest__doc__, +/*[clinic input] +SHA256Type.digest + +Return the digest value as a string of binary data. +[clinic start generated code]*/ + +PyDoc_STRVAR(SHA256Type_digest__doc__, +"digest($self, /)\n" +"--\n" +"\n" "Return the digest value as a string of binary data."); +#define SHA256TYPE_DIGEST_METHODDEF \ + {"digest", (PyCFunction)SHA256Type_digest, METH_NOARGS, SHA256Type_digest__doc__}, + +static PyObject * +SHA256Type_digest_impl(SHAobject *self); + +static PyObject * +SHA256Type_digest(SHAobject *self, PyObject *Py_UNUSED(ignored)) +{ + return SHA256Type_digest_impl(self); +} + static PyObject * -SHA256_digest(SHAobject *self, PyObject *unused) +SHA256Type_digest_impl(SHAobject *self) +/*[clinic end generated code: output=72d34723d7bb694c input=1fb752e58954157d]*/ { unsigned char digest[SHA_DIGESTSIZE]; SHAobject temp; @@ -426,11 +476,33 @@ SHA256_digest(SHAobject *self, PyObject *unused) return PyBytes_FromStringAndSize((const char *)digest, self->digestsize); } -PyDoc_STRVAR(SHA256_hexdigest__doc__, +/*[clinic input] +SHA256Type.hexdigest + +Return the digest value as a string of hexadecimal digits. +[clinic start generated code]*/ + +PyDoc_STRVAR(SHA256Type_hexdigest__doc__, +"hexdigest($self, /)\n" +"--\n" +"\n" "Return the digest value as a string of hexadecimal digits."); +#define SHA256TYPE_HEXDIGEST_METHODDEF \ + {"hexdigest", (PyCFunction)SHA256Type_hexdigest, METH_NOARGS, SHA256Type_hexdigest__doc__}, + +static PyObject * +SHA256Type_hexdigest_impl(SHAobject *self); + static PyObject * -SHA256_hexdigest(SHAobject *self, PyObject *unused) +SHA256Type_hexdigest(SHAobject *self, PyObject *Py_UNUSED(ignored)) +{ + return SHA256Type_hexdigest_impl(self); +} + +static PyObject * +SHA256Type_hexdigest_impl(SHAobject *self) +/*[clinic end generated code: output=3687aa6183c7d27f input=0cc4c714693010d1]*/ { unsigned char digest[SHA_DIGESTSIZE]; SHAobject temp; @@ -462,18 +534,30 @@ SHA256_hexdigest(SHAobject *self, PyObject *unused) return retval; } -PyDoc_STRVAR(SHA256_update__doc__, -"Update this hash object's state with the provided string."); +/*[clinic input] +SHA256Type.update + + obj: object + / + +Update this hash object's state with the provided string. +[clinic start generated code]*/ + +PyDoc_STRVAR(SHA256Type_update__doc__, +"update($self, obj, /)\n" +"--\n" +"\n" +"Update this hash object\'s state with the provided string."); + +#define SHA256TYPE_UPDATE_METHODDEF \ + {"update", (PyCFunction)SHA256Type_update, METH_O, SHA256Type_update__doc__}, static PyObject * -SHA256_update(SHAobject *self, PyObject *args) +SHA256Type_update(SHAobject *self, PyObject *obj) +/*[clinic end generated code: output=b47f53d7cbeabee4 input=b2d449d5b30f0f5a]*/ { - PyObject *obj; Py_buffer buf; - if (!PyArg_ParseTuple(args, "O:update", &obj)) - return NULL; - GET_BUFFER_VIEW_OR_ERROUT(obj, &buf); sha_update(self, buf.buf, buf.len); @@ -484,10 +568,10 @@ SHA256_update(SHAobject *self, PyObject *args) } static PyMethodDef SHA_methods[] = { - {"copy", (PyCFunction)SHA256_copy, METH_NOARGS, SHA256_copy__doc__}, - {"digest", (PyCFunction)SHA256_digest, METH_NOARGS, SHA256_digest__doc__}, - {"hexdigest", (PyCFunction)SHA256_hexdigest, METH_NOARGS, SHA256_hexdigest__doc__}, - {"update", (PyCFunction)SHA256_update, METH_VARARGS, SHA256_update__doc__}, + SHA256TYPE_COPY_METHODDEF + SHA256TYPE_DIGEST_METHODDEF + SHA256TYPE_HEXDIGEST_METHODDEF + SHA256TYPE_UPDATE_METHODDEF {NULL, NULL} /* sentinel */ }; @@ -594,27 +678,55 @@ static PyTypeObject SHA256type = { /* The single module-level function: new() */ -PyDoc_STRVAR(SHA256_new__doc__, +/*[clinic input] +_sha256.sha256 + + string: object(c_default="NULL") = b'' + +Return a new SHA-256 hash object; optionally initialized with a string. +[clinic start generated code]*/ + +PyDoc_STRVAR(_sha256_sha256__doc__, +"sha256($module, /, string=b\'\')\n" +"--\n" +"\n" "Return a new SHA-256 hash object; optionally initialized with a string."); +#define _SHA256_SHA256_METHODDEF \ + {"sha256", (PyCFunction)_sha256_sha256, METH_VARARGS|METH_KEYWORDS, _sha256_sha256__doc__}, + static PyObject * -SHA256_new(PyObject *self, PyObject *args, PyObject *kwdict) +_sha256_sha256_impl(PyModuleDef *module, PyObject *string); + +static PyObject * +_sha256_sha256(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"string", NULL}; + PyObject *string = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "|O:sha256", _keywords, + &string)) + goto exit; + return_value = _sha256_sha256_impl(module, string); + +exit: + return return_value; +} + +static PyObject * +_sha256_sha256_impl(PyModuleDef *module, PyObject *string) +/*[clinic end generated code: output=4b1263d1e2fcdb98 input=09cce3fb855056b2]*/ { - static char *kwlist[] = {"string", NULL}; SHAobject *new; - PyObject *data_obj = NULL; Py_buffer buf; - if (!PyArg_ParseTupleAndKeywords(args, kwdict, "|O:new", kwlist, - &data_obj)) { - return NULL; - } - - if (data_obj) - GET_BUFFER_VIEW_OR_ERROUT(data_obj, &buf); + if (string) + GET_BUFFER_VIEW_OR_ERROUT(string, &buf); if ((new = newSHA256object()) == NULL) { - if (data_obj) + if (string) PyBuffer_Release(&buf); return NULL; } @@ -623,11 +735,11 @@ SHA256_new(PyObject *self, PyObject *args, PyObject *kwdict) if (PyErr_Occurred()) { Py_DECREF(new); - if (data_obj) + if (string) PyBuffer_Release(&buf); return NULL; } - if (data_obj) { + if (string) { sha_update(new, buf.buf, buf.len); PyBuffer_Release(&buf); } @@ -635,27 +747,55 @@ SHA256_new(PyObject *self, PyObject *args, PyObject *kwdict) return (PyObject *)new; } -PyDoc_STRVAR(SHA224_new__doc__, +/*[clinic input] +_sha256.sha224 + + string: object(c_default="NULL") = b'' + +Return a new SHA-224 hash object; optionally initialized with a string. +[clinic start generated code]*/ + +PyDoc_STRVAR(_sha256_sha224__doc__, +"sha224($module, /, string=b\'\')\n" +"--\n" +"\n" "Return a new SHA-224 hash object; optionally initialized with a string."); +#define _SHA256_SHA224_METHODDEF \ + {"sha224", (PyCFunction)_sha256_sha224, METH_VARARGS|METH_KEYWORDS, _sha256_sha224__doc__}, + +static PyObject * +_sha256_sha224_impl(PyModuleDef *module, PyObject *string); + static PyObject * -SHA224_new(PyObject *self, PyObject *args, PyObject *kwdict) +_sha256_sha224(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"string", NULL}; + PyObject *string = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "|O:sha224", _keywords, + &string)) + goto exit; + return_value = _sha256_sha224_impl(module, string); + +exit: + return return_value; +} + +static PyObject * +_sha256_sha224_impl(PyModuleDef *module, PyObject *string) +/*[clinic end generated code: output=4dde0eb1cdaebc06 input=27a04ba24c353a73]*/ { - static char *kwlist[] = {"string", NULL}; SHAobject *new; - PyObject *data_obj = NULL; Py_buffer buf; - if (!PyArg_ParseTupleAndKeywords(args, kwdict, "|O:new", kwlist, - &data_obj)) { - return NULL; - } - - if (data_obj) - GET_BUFFER_VIEW_OR_ERROUT(data_obj, &buf); + if (string) + GET_BUFFER_VIEW_OR_ERROUT(string, &buf); if ((new = newSHA224object()) == NULL) { - if (data_obj) + if (string) PyBuffer_Release(&buf); return NULL; } @@ -664,11 +804,11 @@ SHA224_new(PyObject *self, PyObject *args, PyObject *kwdict) if (PyErr_Occurred()) { Py_DECREF(new); - if (data_obj) + if (string) PyBuffer_Release(&buf); return NULL; } - if (data_obj) { + if (string) { sha_update(new, buf.buf, buf.len); PyBuffer_Release(&buf); } @@ -680,8 +820,8 @@ SHA224_new(PyObject *self, PyObject *args, PyObject *kwdict) /* List of functions exported by this module */ static struct PyMethodDef SHA_functions[] = { - {"sha256", (PyCFunction)SHA256_new, METH_VARARGS|METH_KEYWORDS, SHA256_new__doc__}, - {"sha224", (PyCFunction)SHA224_new, METH_VARARGS|METH_KEYWORDS, SHA224_new__doc__}, + _SHA256_SHA256_METHODDEF + _SHA256_SHA224_METHODDEF {NULL, NULL} /* Sentinel */ }; diff --git a/Modules/sha512module.c b/Modules/sha512module.c index 47c57e5c428f..843f95d5c615 100644 --- a/Modules/sha512module.c +++ b/Modules/sha512module.c @@ -20,6 +20,12 @@ #include "structmember.h" #include "hashlib.h" +/*[clinic input] +module _sha512 +class SHA512Type "SHAobject *" "&PyType_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=81a3ccde92bcfe8d]*/ + #ifdef PY_LONG_LONG /* If no PY_LONG_LONG, don't compile anything! */ /* Some useful types */ @@ -459,10 +465,33 @@ SHA512_dealloc(PyObject *ptr) /* External methods for a hash object */ -PyDoc_STRVAR(SHA512_copy__doc__, "Return a copy of the hash object."); +/*[clinic input] +SHA512Type.copy + +Return a copy of the hash object. +[clinic start generated code]*/ + +PyDoc_STRVAR(SHA512Type_copy__doc__, +"copy($self, /)\n" +"--\n" +"\n" +"Return a copy of the hash object."); + +#define SHA512TYPE_COPY_METHODDEF \ + {"copy", (PyCFunction)SHA512Type_copy, METH_NOARGS, SHA512Type_copy__doc__}, static PyObject * -SHA512_copy(SHAobject *self, PyObject *unused) +SHA512Type_copy_impl(SHAobject *self); + +static PyObject * +SHA512Type_copy(SHAobject *self, PyObject *Py_UNUSED(ignored)) +{ + return SHA512Type_copy_impl(self); +} + +static PyObject * +SHA512Type_copy_impl(SHAobject *self) +/*[clinic end generated code: output=14f8e6ce9c61ece0 input=9f5f31e6c457776a]*/ { SHAobject *newobj; @@ -478,11 +507,33 @@ SHA512_copy(SHAobject *self, PyObject *unused) return (PyObject *)newobj; } -PyDoc_STRVAR(SHA512_digest__doc__, +/*[clinic input] +SHA512Type.digest + +Return the digest value as a string of binary data. +[clinic start generated code]*/ + +PyDoc_STRVAR(SHA512Type_digest__doc__, +"digest($self, /)\n" +"--\n" +"\n" "Return the digest value as a string of binary data."); +#define SHA512TYPE_DIGEST_METHODDEF \ + {"digest", (PyCFunction)SHA512Type_digest, METH_NOARGS, SHA512Type_digest__doc__}, + +static PyObject * +SHA512Type_digest_impl(SHAobject *self); + +static PyObject * +SHA512Type_digest(SHAobject *self, PyObject *Py_UNUSED(ignored)) +{ + return SHA512Type_digest_impl(self); +} + static PyObject * -SHA512_digest(SHAobject *self, PyObject *unused) +SHA512Type_digest_impl(SHAobject *self) +/*[clinic end generated code: output=be8de024b232977e input=60c2cede9e023018]*/ { unsigned char digest[SHA_DIGESTSIZE]; SHAobject temp; @@ -492,11 +543,33 @@ SHA512_digest(SHAobject *self, PyObject *unused) return PyBytes_FromStringAndSize((const char *)digest, self->digestsize); } -PyDoc_STRVAR(SHA512_hexdigest__doc__, +/*[clinic input] +SHA512Type.hexdigest + +Return the digest value as a string of hexadecimal digits. +[clinic start generated code]*/ + +PyDoc_STRVAR(SHA512Type_hexdigest__doc__, +"hexdigest($self, /)\n" +"--\n" +"\n" "Return the digest value as a string of hexadecimal digits."); +#define SHA512TYPE_HEXDIGEST_METHODDEF \ + {"hexdigest", (PyCFunction)SHA512Type_hexdigest, METH_NOARGS, SHA512Type_hexdigest__doc__}, + static PyObject * -SHA512_hexdigest(SHAobject *self, PyObject *unused) +SHA512Type_hexdigest_impl(SHAobject *self); + +static PyObject * +SHA512Type_hexdigest(SHAobject *self, PyObject *Py_UNUSED(ignored)) +{ + return SHA512Type_hexdigest_impl(self); +} + +static PyObject * +SHA512Type_hexdigest_impl(SHAobject *self) +/*[clinic end generated code: output=28a4ab2f9a1781b8 input=498b877b25cbe0a2]*/ { unsigned char digest[SHA_DIGESTSIZE]; SHAobject temp; @@ -528,18 +601,30 @@ SHA512_hexdigest(SHAobject *self, PyObject *unused) return retval; } -PyDoc_STRVAR(SHA512_update__doc__, -"Update this hash object's state with the provided string."); +/*[clinic input] +SHA512Type.update + + obj: object + / + +Update this hash object's state with the provided string. +[clinic start generated code]*/ + +PyDoc_STRVAR(SHA512Type_update__doc__, +"update($self, obj, /)\n" +"--\n" +"\n" +"Update this hash object\'s state with the provided string."); + +#define SHA512TYPE_UPDATE_METHODDEF \ + {"update", (PyCFunction)SHA512Type_update, METH_O, SHA512Type_update__doc__}, static PyObject * -SHA512_update(SHAobject *self, PyObject *args) +SHA512Type_update(SHAobject *self, PyObject *obj) +/*[clinic end generated code: output=6be574cdc3a9c52d input=ded2b46656566283]*/ { - PyObject *obj; Py_buffer buf; - if (!PyArg_ParseTuple(args, "O:update", &obj)) - return NULL; - GET_BUFFER_VIEW_OR_ERROUT(obj, &buf); sha512_update(self, buf.buf, buf.len); @@ -548,12 +633,32 @@ SHA512_update(SHAobject *self, PyObject *args) Py_INCREF(Py_None); return Py_None; } +/*[clinic input] +dump buffer +[clinic start generated code]*/ + +#ifndef SHA512TYPE_COPY_METHODDEF + #define SHA512TYPE_COPY_METHODDEF +#endif /* !defined(SHA512TYPE_COPY_METHODDEF) */ + +#ifndef SHA512TYPE_DIGEST_METHODDEF + #define SHA512TYPE_DIGEST_METHODDEF +#endif /* !defined(SHA512TYPE_DIGEST_METHODDEF) */ + +#ifndef SHA512TYPE_HEXDIGEST_METHODDEF + #define SHA512TYPE_HEXDIGEST_METHODDEF +#endif /* !defined(SHA512TYPE_HEXDIGEST_METHODDEF) */ + +#ifndef SHA512TYPE_UPDATE_METHODDEF + #define SHA512TYPE_UPDATE_METHODDEF +#endif /* !defined(SHA512TYPE_UPDATE_METHODDEF) */ +/*[clinic end generated code: output=de713947d31130e9 input=524ce2e021e4eba6]*/ static PyMethodDef SHA_methods[] = { - {"copy", (PyCFunction)SHA512_copy, METH_NOARGS, SHA512_copy__doc__}, - {"digest", (PyCFunction)SHA512_digest, METH_NOARGS, SHA512_digest__doc__}, - {"hexdigest", (PyCFunction)SHA512_hexdigest, METH_NOARGS, SHA512_hexdigest__doc__}, - {"update", (PyCFunction)SHA512_update, METH_VARARGS, SHA512_update__doc__}, + SHA512TYPE_COPY_METHODDEF + SHA512TYPE_DIGEST_METHODDEF + SHA512TYPE_HEXDIGEST_METHODDEF + SHA512TYPE_UPDATE_METHODDEF {NULL, NULL} /* sentinel */ }; @@ -660,27 +765,55 @@ static PyTypeObject SHA512type = { /* The single module-level function: new() */ -PyDoc_STRVAR(SHA512_new__doc__, +/*[clinic input] +_sha512.sha512 + + string: object(c_default="NULL") = b'' + +Return a new SHA-512 hash object; optionally initialized with a string. +[clinic start generated code]*/ + +PyDoc_STRVAR(_sha512_sha512__doc__, +"sha512($module, /, string=b\'\')\n" +"--\n" +"\n" "Return a new SHA-512 hash object; optionally initialized with a string."); +#define _SHA512_SHA512_METHODDEF \ + {"sha512", (PyCFunction)_sha512_sha512, METH_VARARGS|METH_KEYWORDS, _sha512_sha512__doc__}, + static PyObject * -SHA512_new(PyObject *self, PyObject *args, PyObject *kwdict) +_sha512_sha512_impl(PyModuleDef *module, PyObject *string); + +static PyObject * +_sha512_sha512(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"string", NULL}; + PyObject *string = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "|O:sha512", _keywords, + &string)) + goto exit; + return_value = _sha512_sha512_impl(module, string); + +exit: + return return_value; +} + +static PyObject * +_sha512_sha512_impl(PyModuleDef *module, PyObject *string) +/*[clinic end generated code: output=9e39b11115f36878 input=e69bad9ae9b6a308]*/ { - static char *kwlist[] = {"string", NULL}; SHAobject *new; - PyObject *data_obj = NULL; Py_buffer buf; - if (!PyArg_ParseTupleAndKeywords(args, kwdict, "|O:new", kwlist, - &data_obj)) { - return NULL; - } - - if (data_obj) - GET_BUFFER_VIEW_OR_ERROUT(data_obj, &buf); + if (string) + GET_BUFFER_VIEW_OR_ERROUT(string, &buf); if ((new = newSHA512object()) == NULL) { - if (data_obj) + if (string) PyBuffer_Release(&buf); return NULL; } @@ -689,11 +822,11 @@ SHA512_new(PyObject *self, PyObject *args, PyObject *kwdict) if (PyErr_Occurred()) { Py_DECREF(new); - if (data_obj) + if (string) PyBuffer_Release(&buf); return NULL; } - if (data_obj) { + if (string) { sha512_update(new, buf.buf, buf.len); PyBuffer_Release(&buf); } @@ -701,27 +834,55 @@ SHA512_new(PyObject *self, PyObject *args, PyObject *kwdict) return (PyObject *)new; } -PyDoc_STRVAR(SHA384_new__doc__, +/*[clinic input] +_sha512.sha384 + + string: object(c_default="NULL") = b'' + +Return a new SHA-384 hash object; optionally initialized with a string. +[clinic start generated code]*/ + +PyDoc_STRVAR(_sha512_sha384__doc__, +"sha384($module, /, string=b\'\')\n" +"--\n" +"\n" "Return a new SHA-384 hash object; optionally initialized with a string."); +#define _SHA512_SHA384_METHODDEF \ + {"sha384", (PyCFunction)_sha512_sha384, METH_VARARGS|METH_KEYWORDS, _sha512_sha384__doc__}, + +static PyObject * +_sha512_sha384_impl(PyModuleDef *module, PyObject *string); + +static PyObject * +_sha512_sha384(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"string", NULL}; + PyObject *string = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "|O:sha384", _keywords, + &string)) + goto exit; + return_value = _sha512_sha384_impl(module, string); + +exit: + return return_value; +} + static PyObject * -SHA384_new(PyObject *self, PyObject *args, PyObject *kwdict) +_sha512_sha384_impl(PyModuleDef *module, PyObject *string) +/*[clinic end generated code: output=397c6fba3525b93a input=c9327788d4ea4545]*/ { - static char *kwlist[] = {"string", NULL}; SHAobject *new; - PyObject *data_obj = NULL; Py_buffer buf; - if (!PyArg_ParseTupleAndKeywords(args, kwdict, "|O:new", kwlist, - &data_obj)) { - return NULL; - } - - if (data_obj) - GET_BUFFER_VIEW_OR_ERROUT(data_obj, &buf); + if (string) + GET_BUFFER_VIEW_OR_ERROUT(string, &buf); if ((new = newSHA384object()) == NULL) { - if (data_obj) + if (string) PyBuffer_Release(&buf); return NULL; } @@ -730,11 +891,11 @@ SHA384_new(PyObject *self, PyObject *args, PyObject *kwdict) if (PyErr_Occurred()) { Py_DECREF(new); - if (data_obj) + if (string) PyBuffer_Release(&buf); return NULL; } - if (data_obj) { + if (string) { sha512_update(new, buf.buf, buf.len); PyBuffer_Release(&buf); } @@ -743,11 +904,24 @@ SHA384_new(PyObject *self, PyObject *args, PyObject *kwdict) } +/*[clinic input] +dump buffer +[clinic start generated code]*/ + +#ifndef _SHA512_SHA512_METHODDEF + #define _SHA512_SHA512_METHODDEF +#endif /* !defined(_SHA512_SHA512_METHODDEF) */ + +#ifndef _SHA512_SHA384_METHODDEF + #define _SHA512_SHA384_METHODDEF +#endif /* !defined(_SHA512_SHA384_METHODDEF) */ +/*[clinic end generated code: output=69d84aa9445b01d8 input=524ce2e021e4eba6]*/ + /* List of functions exported by this module */ static struct PyMethodDef SHA_functions[] = { - {"sha512", (PyCFunction)SHA512_new, METH_VARARGS|METH_KEYWORDS, SHA512_new__doc__}, - {"sha384", (PyCFunction)SHA384_new, METH_VARARGS|METH_KEYWORDS, SHA384_new__doc__}, + _SHA512_SHA512_METHODDEF + _SHA512_SHA384_METHODDEF {NULL, NULL} /* Sentinel */ }; diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index 9a0e8e336516..598bc8a34290 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -7,6 +7,9 @@ #ifndef MS_WINDOWS #include "posixmodule.h" #endif +#ifdef MS_WINDOWS +#include "socketmodule.h" /* needed for SOCKET_T */ +#endif #ifdef MS_WINDOWS #include @@ -87,7 +90,20 @@ static volatile struct { PyObject *func; } Handlers[NSIG]; +#ifdef MS_WINDOWS +#define INVALID_FD ((SOCKET_T)-1) + +static volatile struct { + SOCKET_T fd; + int use_send; + int send_err_set; + int send_errno; + int send_win_error; +} wakeup = {INVALID_FD, 0, 0}; +#else +#define INVALID_FD (-1) static volatile sig_atomic_t wakeup_fd = -1; +#endif /* Speed up sigcheck() when none tripped */ static volatile sig_atomic_t is_tripped = 0; @@ -172,7 +188,7 @@ checksignals_witharg(void * unused) } static int -report_wakeup_error(void *data) +report_wakeup_write_error(void *data) { int save_errno = errno; errno = (int) (Py_intptr_t) data; @@ -184,25 +200,86 @@ report_wakeup_error(void *data) return 0; } +#ifdef MS_WINDOWS +static int +report_wakeup_send_error(void* Py_UNUSED(data)) +{ + PyObject *res; + + if (wakeup.send_win_error) { + /* PyErr_SetExcFromWindowsErr() invokes FormatMessage() which + recognizes the error codes used by both GetLastError() and + WSAGetLastError */ + res = PyErr_SetExcFromWindowsErr(PyExc_OSError, wakeup.send_win_error); + } + else { + errno = wakeup.send_errno; + res = PyErr_SetFromErrno(PyExc_OSError); + } + + assert(res == NULL); + wakeup.send_err_set = 0; + + PySys_WriteStderr("Exception ignored when trying to send to the " + "signal wakeup fd:\n"); + PyErr_WriteUnraisable(NULL); + + return 0; +} +#endif /* MS_WINDOWS */ + static void trip_signal(int sig_num) { unsigned char byte; - int rc = 0; + int fd; + Py_ssize_t rc; Handlers[sig_num].tripped = 1; - if (wakeup_fd != -1) { + +#ifdef MS_WINDOWS + fd = Py_SAFE_DOWNCAST(wakeup.fd, SOCKET_T, int); +#else + fd = wakeup_fd; +#endif + + if (fd != INVALID_FD) { byte = (unsigned char)sig_num; - while ((rc = write(wakeup_fd, &byte, 1)) == -1 && errno == EINTR); - if (rc == -1) - Py_AddPendingCall(report_wakeup_error, (void *) (Py_intptr_t) errno); +#ifdef MS_WINDOWS + if (wakeup.use_send) { + do { + rc = send(fd, &byte, 1, 0); + } while (rc < 0 && errno == EINTR); + + /* we only have a storage for one error in the wakeup structure */ + if (rc < 0 && !wakeup.send_err_set) { + wakeup.send_err_set = 1; + wakeup.send_errno = errno; + wakeup.send_win_error = GetLastError(); + Py_AddPendingCall(report_wakeup_send_error, NULL); + } + } + else +#endif + { + byte = (unsigned char)sig_num; + do { + rc = write(fd, &byte, 1); + } while (rc < 0 && errno == EINTR); + + if (rc < 0) { + Py_AddPendingCall(report_wakeup_write_error, + (void *)(Py_intptr_t)errno); + } + } + } + + if (!is_tripped) { + /* Set is_tripped after setting .tripped, as it gets + cleared in PyErr_CheckSignals() before .tripped. */ + is_tripped = 1; + Py_AddPendingCall(checksignals_witharg, NULL); } - if (is_tripped) - return; - /* Set is_tripped after setting .tripped, as it gets - cleared in PyErr_CheckSignals() before .tripped. */ - is_tripped = 1; - Py_AddPendingCall(checksignals_witharg, NULL); } static void @@ -227,7 +304,7 @@ signal_handler(int sig_num) if (sig_num != SIGCHLD) #endif /* If the handler was not set up with sigaction, reinstall it. See - * Python/pythonrun.c for the implementation of PyOS_setsig which + * Python/pylifecycle.c for the implementation of PyOS_setsig which * makes this true. See also issue8354. */ PyOS_setsig(sig_num, signal_handler); #endif @@ -426,10 +503,28 @@ signal_siginterrupt(PyObject *self, PyObject *args) static PyObject * signal_set_wakeup_fd(PyObject *self, PyObject *args) { - struct stat buf; + struct _Py_stat_struct st; +#ifdef MS_WINDOWS + PyObject *fdobj; + SOCKET_T sockfd, old_sockfd; + int res; + int res_size = sizeof res; + PyObject *mod; + int is_socket; + + if (!PyArg_ParseTuple(args, "O:set_wakeup_fd", &fdobj)) + return NULL; + + sockfd = PyLong_AsSocket_t(fdobj); + if (sockfd == (SOCKET_T)(-1) && PyErr_Occurred()) + return NULL; +#else int fd, old_fd; + if (!PyArg_ParseTuple(args, "i:set_wakeup_fd", &fd)) return NULL; +#endif + #ifdef WITH_THREAD if (PyThread_get_thread_ident() != main_thread) { PyErr_SetString(PyExc_ValueError, @@ -437,21 +532,94 @@ signal_set_wakeup_fd(PyObject *self, PyObject *args) return NULL; } #endif - if (fd != -1 && (!_PyVerify_fd(fd) || fstat(fd, &buf) != 0)) { - PyErr_SetString(PyExc_ValueError, "invalid fd"); - return NULL; + +#ifdef MS_WINDOWS + is_socket = 0; + if (sockfd != INVALID_FD) { + /* Import the _socket module to call WSAStartup() */ + mod = PyImport_ImportModuleNoBlock("_socket"); + if (mod == NULL) + return NULL; + Py_DECREF(mod); + + /* test the socket */ + if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, + (char *)&res, &res_size) != 0) { + int fd, err; + + err = WSAGetLastError(); + if (err != WSAENOTSOCK) { + PyErr_SetExcFromWindowsErr(PyExc_OSError, err); + return NULL; + } + + fd = (int)sockfd; + if ((SOCKET_T)fd != sockfd || !_PyVerify_fd(fd)) { + PyErr_SetString(PyExc_ValueError, "invalid fd"); + return NULL; + } + + if (_Py_fstat(fd, &st) != 0) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + + /* on Windows, a file cannot be set to non-blocking mode */ + } + else { + is_socket = 1; + + /* Windows does not provide a function to test if a socket + is in non-blocking mode */ + } + } + + old_sockfd = wakeup.fd; + wakeup.fd = sockfd; + wakeup.use_send = is_socket; + + if (old_sockfd != INVALID_FD) + return PyLong_FromSocket_t(old_sockfd); + else + return PyLong_FromLong(-1); +#else + if (fd != -1) { + int blocking; + + if (!_PyVerify_fd(fd)) { + PyErr_SetString(PyExc_ValueError, "invalid fd"); + return NULL; + } + + if (_Py_fstat(fd, &st) != 0) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + + blocking = _Py_get_blocking(fd); + if (blocking < 0) + return NULL; + if (blocking) { + PyErr_Format(PyExc_ValueError, + "the fd %i must be in non-blocking mode", + fd); + return NULL; + } } + old_fd = wakeup_fd; wakeup_fd = fd; + return PyLong_FromLong(old_fd); +#endif } PyDoc_STRVAR(set_wakeup_fd_doc, "set_wakeup_fd(fd) -> fd\n\ \n\ -Sets the fd to be written to (with '\\0') when a signal\n\ +Sets the fd to be written to (with the signal number) when a signal\n\ comes in. A library can use this to wakeup select or poll.\n\ -The previous fd is returned.\n\ +The previous fd or -1 is returned.\n\ \n\ The fd must be non-blocking."); @@ -459,10 +627,17 @@ The fd must be non-blocking."); int PySignal_SetWakeupFd(int fd) { - int old_fd = wakeup_fd; + int old_fd; if (fd < 0) fd = -1; + +#ifdef MS_WINDOWS + old_fd = Py_SAFE_DOWNCAST(wakeup.fd, SOCKET_T, int); + wakeup.fd = fd; +#else + old_fd = wakeup_fd; wakeup_fd = fd; +#endif return old_fd; } @@ -799,7 +974,8 @@ signal_sigtimedwait(PyObject *self, PyObject *args) &signals, &timeout)) return NULL; - if (_PyTime_ObjectToTimespec(timeout, &tv_sec, &tv_nsec) == -1) + if (_PyTime_ObjectToTimespec(timeout, &tv_sec, &tv_nsec, + _PyTime_ROUND_DOWN) == -1) return NULL; buf.tv_sec = tv_sec; buf.tv_nsec = tv_nsec; @@ -955,7 +1131,7 @@ the first is the signal number, the second is the interrupted stack frame."); static struct PyModuleDef signalmodule = { PyModuleDef_HEAD_INIT, - "signal", + "_signal", module_doc, -1, signal_methods, @@ -966,7 +1142,7 @@ static struct PyModuleDef signalmodule = { }; PyMODINIT_FUNC -PyInit_signal(void) +PyInit__signal(void) { PyObject *m, *d, *x; int i; @@ -1305,12 +1481,9 @@ finisignal(void) Py_XDECREF(func); } - Py_XDECREF(IntHandler); - IntHandler = NULL; - Py_XDECREF(DefaultHandler); - DefaultHandler = NULL; - Py_XDECREF(IgnoreHandler); - IgnoreHandler = NULL; + Py_CLEAR(IntHandler); + Py_CLEAR(DefaultHandler); + Py_CLEAR(IgnoreHandler); } @@ -1382,7 +1555,7 @@ PyErr_SetInterrupt(void) void PyOS_InitInterrupts(void) { - PyObject *m = PyImport_ImportModule("signal"); + PyObject *m = PyImport_ImportModule("_signal"); if (m) { Py_DECREF(m); } diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 9e0da132688c..7c7cb7de6fdc 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -33,8 +33,8 @@ Module interface: - socket.ntohl(32 bit value) --> new int object - socket.htons(16 bit value) --> new int object - socket.htonl(32 bit value) --> new int object -- socket.getaddrinfo(host, port [, family, socktype, proto, flags]) - --> List of (family, socktype, proto, canonname, sockaddr) +- socket.getaddrinfo(host, port [, family, type, proto, flags]) + --> List of (family, type, proto, canonname, sockaddr) - socket.getnameinfo(sockaddr, flags) --> (host, port) - socket.AF_INET, socket.SOCK_STREAM, etc.: constants from - socket.has_ipv6: boolean value indicating if IPv6 is supported @@ -121,7 +121,7 @@ getpeername() -- return remote address [*]\n\ getsockname() -- return local address\n\ getsockopt(level, optname[, buflen]) -- get socket options\n\ gettimeout() -- return timeout or None\n\ -listen(n) -- start listening for incoming connections\n\ +listen([n]) -- start listening for incoming connections\n\ recv(buflen[, flags]) -- receive data\n\ recv_into(buffer[, nbytes[, flags]]) -- receive data (into a buffer)\n\ recvfrom(buflen[, flags]) -- receive data and sender\'s address\n\ @@ -188,7 +188,7 @@ if_indextoname(index) -- return the corresponding interface name\n\ #if defined(WITH_THREAD) && (defined(__APPLE__) || \ (defined(__FreeBSD__) && __FreeBSD_version+0 < 503000) || \ defined(__OpenBSD__) || defined(__NetBSD__) || \ - defined(__VMS) || !defined(HAVE_GETADDRINFO)) + !defined(HAVE_GETADDRINFO)) #define USE_GETADDRINFO_LOCK #endif @@ -212,10 +212,6 @@ if_indextoname(index) -- return the corresponding interface name\n\ # include #endif -#if defined(__VMS) -# include -#endif - #ifdef __APPLE__ # include #endif @@ -288,14 +284,15 @@ if_indextoname(index) -- return the corresponding interface name\n\ # include # endif +#if defined(_MSC_VER) && _MSC_VER >= 1800 +/* Provides the IsWindows7SP1OrGreater() function */ +#include #endif -#include - -#ifndef offsetof -# define offsetof(type, member) ((size_t)(&((type *)0)->member)) #endif +#include + #ifndef O_NONBLOCK # define O_NONBLOCK O_NDELAY #endif @@ -403,11 +400,6 @@ const char *inet_ntop(int af, const void *src, char *dst, socklen_t size); #endif #endif -#ifdef __VMS -/* TCP/IP Services for VMS uses a maximum send/recv buffer length */ -#define SEGMENT_SIZE (32 * 1024 -1) -#endif - /* Convert "sock_addr_t *" to "struct sockaddr *". */ #define SAS2SA(x) (&((x)->sa)) @@ -556,37 +548,17 @@ set_gaierror(int error) return NULL; } -#ifdef __VMS -/* Function to send in segments */ -static int -sendsegmented(int sock_fd, char *buf, int len, int flags) -{ - int n = 0; - int remaining = len; - - while (remaining > 0) { - unsigned int segment; - - segment = (remaining >= SEGMENT_SIZE ? SEGMENT_SIZE : remaining); - n = send(sock_fd, buf, segment, flags); - if (n < 0) { - return n; - } - remaining -= segment; - buf += segment; - } /* end while */ - - return len; -} -#endif - /* Function to perform the setting of socket blocking mode internally. block = (1 | 0). */ static int internal_setblocking(PySocketSockObject *s, int block) { -#ifndef MS_WINDOWS - int delay_flag; +#ifdef MS_WINDOWS + u_long arg; +#endif +#if !defined(MS_WINDOWS) \ + && !((defined(HAVE_SYS_IOCTL_H) && defined(FIONBIO))) + int delay_flag, new_delay_flag; #endif #ifdef SOCK_NONBLOCK if (block) @@ -597,20 +569,21 @@ internal_setblocking(PySocketSockObject *s, int block) Py_BEGIN_ALLOW_THREADS #ifndef MS_WINDOWS -#if defined(__VMS) +#if (defined(HAVE_SYS_IOCTL_H) && defined(FIONBIO)) block = !block; ioctl(s->sock_fd, FIONBIO, (unsigned int *)&block); -#else /* !__VMS */ +#else delay_flag = fcntl(s->sock_fd, F_GETFL, 0); if (block) - delay_flag &= (~O_NONBLOCK); + new_delay_flag = delay_flag & (~O_NONBLOCK); else - delay_flag |= O_NONBLOCK; - fcntl(s->sock_fd, F_SETFL, delay_flag); -#endif /* !__VMS */ + new_delay_flag = delay_flag | O_NONBLOCK; + if (new_delay_flag != delay_flag) + fcntl(s->sock_fd, F_SETFL, new_delay_flag); +#endif #else /* MS_WINDOWS */ - block = !block; - ioctlsocket(s->sock_fd, FIONBIO, (u_long*)&block); + arg = !block; + ioctlsocket(s->sock_fd, FIONBIO, &arg); #endif /* MS_WINDOWS */ Py_END_ALLOW_THREADS @@ -712,7 +685,7 @@ internal_select(PySocketSockObject *s, int writing) double interval = s->sock_timeout; \ int has_timeout = s->sock_timeout > 0.0; \ if (has_timeout) { \ - _PyTime_gettimeofday(&now); \ + _PyTime_monotonic(&now); \ deadline = now; \ _PyTime_ADD_SECONDS(deadline, s->sock_timeout); \ } \ @@ -723,7 +696,7 @@ internal_select(PySocketSockObject *s, int writing) if (!has_timeout || \ (!CHECK_ERRNO(EWOULDBLOCK) && !CHECK_ERRNO(EAGAIN))) \ break; \ - _PyTime_gettimeofday(&now); \ + _PyTime_monotonic(&now); \ interval = _PyTime_INTERVAL(now, deadline); \ } \ } \ @@ -1245,6 +1218,71 @@ makesockaddr(SOCKET_T sockfd, struct sockaddr *addr, size_t addrlen, int proto) } } +/* Helper for getsockaddrarg: bypass IDNA for ASCII-only host names + (in particular, numeric IP addresses). */ +struct maybe_idna { + PyObject *obj; + char *buf; +}; + +static void +idna_cleanup(struct maybe_idna *data) +{ + Py_CLEAR(data->obj); +} + +static int +idna_converter(PyObject *obj, struct maybe_idna *data) +{ + size_t len; + PyObject *obj2, *obj3; + if (obj == NULL) { + idna_cleanup(data); + return 1; + } + data->obj = NULL; + len = -1; + if (PyBytes_Check(obj)) { + data->buf = PyBytes_AsString(obj); + len = PyBytes_Size(obj); + } + else if (PyByteArray_Check(obj)) { + data->buf = PyByteArray_AsString(obj); + len = PyByteArray_Size(obj); + } + else if (PyUnicode_Check(obj) && PyUnicode_READY(obj) == 0 && PyUnicode_IS_COMPACT_ASCII(obj)) { + data->buf = PyUnicode_DATA(obj); + len = PyUnicode_GET_LENGTH(obj); + } + else { + obj2 = PyUnicode_FromObject(obj); + if (!obj2) { + PyErr_Format(PyExc_TypeError, "string or unicode text buffer expected, not %s", + obj->ob_type->tp_name); + return 0; + } + obj3 = PyUnicode_AsEncodedString(obj2, "idna", NULL); + Py_DECREF(obj2); + if (!obj3) { + PyErr_SetString(PyExc_TypeError, "encoding of hostname failed"); + return 0; + } + if (!PyBytes_Check(obj3)) { + Py_DECREF(obj3); + PyErr_SetString(PyExc_TypeError, "encoding of hostname failed to return bytes"); + return 0; + } + data->obj = obj3; + data->buf = PyBytes_AS_STRING(obj3); + len = PyBytes_GET_SIZE(obj3); + } + if (strlen(data->buf) != len) { + Py_CLEAR(data->obj); + PyErr_SetString(PyExc_TypeError, "host name must not contain null character"); + return 0; + } + return Py_CLEANUP_SUPPORTED; +} /* Parse a socket address argument according to the socket object's address family. Return 1 if the address was in the proper format, @@ -1275,12 +1313,13 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, Py_INCREF(args); if (!PyArg_Parse(args, "y#", &path, &len)) goto unix_out; + assert(len >= 0); addr = (struct sockaddr_un*)addr_ret; #ifdef linux if (len > 0 && path[0] == 0) { /* Linux abstract namespace extension */ - if (len > sizeof addr->sun_path) { + if ((size_t)len > sizeof addr->sun_path) { PyErr_SetString(PyExc_OSError, "AF_UNIX path too long"); goto unix_out; @@ -1290,7 +1329,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, #endif /* linux */ { /* regular NULL-terminated string */ - if (len >= sizeof addr->sun_path) { + if ((size_t)len >= sizeof addr->sun_path) { PyErr_SetString(PyExc_OSError, "AF_UNIX path too long"); goto unix_out; @@ -1339,7 +1378,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, case AF_INET: { struct sockaddr_in* addr; - char *host; + struct maybe_idna host = {NULL, NULL}; int port, result; if (!PyTuple_Check(args)) { PyErr_Format( @@ -1349,13 +1388,13 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, Py_TYPE(args)->tp_name); return 0; } - if (!PyArg_ParseTuple(args, "eti:getsockaddrarg", - "idna", &host, &port)) + if (!PyArg_ParseTuple(args, "O&i:getsockaddrarg", + idna_converter, &host, &port)) return 0; addr=(struct sockaddr_in*)addr_ret; - result = setipaddr(host, (struct sockaddr *)addr, + result = setipaddr(host.buf, (struct sockaddr *)addr, sizeof(*addr), AF_INET); - PyMem_Free(host); + idna_cleanup(&host); if (result < 0) return 0; if (port < 0 || port > 0xffff) { @@ -1374,7 +1413,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, case AF_INET6: { struct sockaddr_in6* addr; - char *host; + struct maybe_idna host = {NULL, NULL}; int port, result; unsigned int flowinfo, scope_id; flowinfo = scope_id = 0; @@ -1386,15 +1425,15 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, Py_TYPE(args)->tp_name); return 0; } - if (!PyArg_ParseTuple(args, "eti|II", - "idna", &host, &port, &flowinfo, + if (!PyArg_ParseTuple(args, "O&i|II", + idna_converter, &host, &port, &flowinfo, &scope_id)) { return 0; } addr = (struct sockaddr_in6*)addr_ret; - result = setipaddr(host, (struct sockaddr *)addr, + result = setipaddr(host.buf, (struct sockaddr *)addr, sizeof(*addr), AF_INET6); - PyMem_Free(host); + idna_cleanup(&host); if (result < 0) return 0; if (port < 0 || port > 0xffff) { @@ -1620,7 +1659,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, } #endif -#ifdef AF_CAN +#if defined(AF_CAN) && defined(CAN_RAW) && defined(CAN_BCM) case AF_CAN: switch (s->sock_proto) { case CAN_RAW: @@ -1642,7 +1681,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, if (len == 0) { ifr.ifr_ifindex = 0; - } else if (len < sizeof(ifr.ifr_name)) { + } else if ((size_t)len < sizeof(ifr.ifr_name)) { strncpy(ifr.ifr_name, PyBytes_AS_STRING(interfaceName), sizeof(ifr.ifr_name)); ifr.ifr_name[(sizeof(ifr.ifr_name))-1] = '\0'; if (ioctl(s->sock_fd, SIOCGIFINDEX, &ifr) < 0) { @@ -1916,8 +1955,22 @@ cmsg_min_space(struct msghdr *msg, struct cmsghdr *cmsgh, size_t space) sizeof(cmsgh->cmsg_len)); /* Note that POSIX allows msg_controllen to be of signed type. */ - if (cmsgh == NULL || msg->msg_control == NULL || msg->msg_controllen < 0) + if (cmsgh == NULL || msg->msg_control == NULL) return 0; + /* Note that POSIX allows msg_controllen to be of a signed type. This is + annoying under OS X as it's unsigned there and so it triggers a + tautological comparison warning under Clang when compared against 0. + Since the check is valid on other platforms, silence the warning under + Clang. */ + #ifdef __clang__ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wtautological-compare" + #endif + if (msg->msg_controllen < 0) + return 0; + #ifdef __clang__ + #pragma clang diagnostic pop + #endif if (space < cmsg_len_end) space = cmsg_len_end; cmsg_offset = (char *)cmsgh - (char *)msg->msg_control; @@ -1984,6 +2037,7 @@ sock_accept(PySocketSockObject *s) PyObject *addr = NULL; PyObject *res = NULL; int timeout; + int async_err = 0; #if defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC) /* accept4() is available on Linux 2.6.28+ and glibc 2.10 */ static int accept4_works = -1; @@ -1997,27 +2051,27 @@ sock_accept(PySocketSockObject *s) return select_error(); BEGIN_SELECT_LOOP(s) - - Py_BEGIN_ALLOW_THREADS - timeout = internal_select_ex(s, 0, interval); - if (!timeout) { + do { + Py_BEGIN_ALLOW_THREADS + timeout = internal_select_ex(s, 0, interval); + if (!timeout) { #if defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC) - if (accept4_works != 0) { - newfd = accept4(s->sock_fd, SAS2SA(&addrbuf), &addrlen, - SOCK_CLOEXEC); - if (newfd == INVALID_SOCKET && accept4_works == -1) { - /* On Linux older than 2.6.28, accept4() fails with ENOSYS */ - accept4_works = (errno != ENOSYS); + if (accept4_works != 0) { + newfd = accept4(s->sock_fd, SAS2SA(&addrbuf), &addrlen, + SOCK_CLOEXEC); + if (newfd == INVALID_SOCKET && accept4_works == -1) { + /* On Linux older than 2.6.28, accept4() fails with ENOSYS */ + accept4_works = (errno != ENOSYS); + } } - } - if (accept4_works == 0) - newfd = accept(s->sock_fd, SAS2SA(&addrbuf), &addrlen); + if (accept4_works == 0) + newfd = accept(s->sock_fd, SAS2SA(&addrbuf), &addrlen); #else - newfd = accept(s->sock_fd, SAS2SA(&addrbuf), &addrlen); + newfd = accept(s->sock_fd, SAS2SA(&addrbuf), &addrlen); #endif - } - Py_END_ALLOW_THREADS - + } + Py_END_ALLOW_THREADS + } while (newfd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); if (timeout == 1) { PyErr_SetString(socket_timeout, "timed out"); return NULL; @@ -2025,7 +2079,7 @@ sock_accept(PySocketSockObject *s) END_SELECT_LOOP(s) if (newfd == INVALID_SOCKET) - return s->errorhandler(); + return (!async_err) ? s->errorhandler() : NULL; #ifdef MS_WINDOWS if (!SetHandleInformation((HANDLE)newfd, HANDLE_FLAG_INHERIT, 0)) { @@ -2225,13 +2279,7 @@ sock_getsockopt(PySocketSockObject *s, PyObject *args) return s->errorhandler(); return PyLong_FromLong(flag); } -#ifdef __VMS - /* socklen_t is unsigned so no negative test is needed, - test buflen == 0 is previously done */ - if (buflen > 1024) { -#else if (buflen <= 0 || buflen > 1024) { -#endif PyErr_SetString(PyExc_OSError, "getsockopt buflen out of range"); return NULL; @@ -2294,6 +2342,10 @@ sock_close(PySocketSockObject *s) { SOCKET_T fd; + /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/ + * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html + * for more details. + */ if ((fd = s->sock_fd) != -1) { s->sock_fd = -1; Py_BEGIN_ALLOW_THREADS @@ -2320,8 +2372,8 @@ sock_detach(PySocketSockObject *s) PyDoc_STRVAR(detach_doc, "detach()\n\ \n\ -Close the socket object without closing the underlying file descriptor.\ -The object cannot be used after this call, but the file descriptor\ +Close the socket object without closing the underlying file descriptor.\n\ +The object cannot be used after this call, but the file descriptor\n\ can be reused for other purposes. The file descriptor is returned."); static int @@ -2466,10 +2518,8 @@ sock_connect_ex(PySocketSockObject *s, PyObject *addro) /* Signals are not errors (though they may raise exceptions). Adapted from PyErr_SetFromErrnoWithFilenameObject(). */ -#ifdef EINTR if (res == EINTR && PyErr_CheckSignals()) return NULL; -#endif return PyLong_FromLong((long) res); } @@ -2557,14 +2607,16 @@ info is a pair (hostaddr, port)."); /* s.listen(n) method */ static PyObject * -sock_listen(PySocketSockObject *s, PyObject *arg) +sock_listen(PySocketSockObject *s, PyObject *args) { - int backlog; + /* We try to choose a default backlog high enough to avoid connection drops + * for common workloads, yet not too high to limit resource usage. */ + int backlog = Py_MIN(SOMAXCONN, 128); int res; - backlog = _PyLong_AsInt(arg); - if (backlog == -1 && PyErr_Occurred()) + if (!PyArg_ParseTuple(args, "|i:listen", &backlog)) return NULL; + Py_BEGIN_ALLOW_THREADS /* To avoid problems on systems that don't allow a negative backlog * (which doesn't make sense anyway) we force a minimum value of 0. */ @@ -2579,12 +2631,12 @@ sock_listen(PySocketSockObject *s, PyObject *arg) } PyDoc_STRVAR(listen_doc, -"listen(backlog)\n\ +"listen([backlog])\n\ \n\ -Enable a server to accept connections. The backlog argument must be at\n\ -least 0 (if it is lower, it is set to 0); it specifies the number of\n\ +Enable a server to accept connections. If backlog is specified, it must be\n\ +at least 0 (if it is lower, it is set to 0); it specifies the number of\n\ unaccepted connections that the system will allow before refusing new\n\ -connections."); +connections. If not specified, a default reasonable value is chosen."); /* @@ -2601,10 +2653,7 @@ sock_recv_guts(PySocketSockObject *s, char* cbuf, Py_ssize_t len, int flags) { Py_ssize_t outlen = -1; int timeout; -#ifdef __VMS - int remaining; - char *read_buf; -#endif + int async_err = 0; if (!IS_SELECTABLE(s)) { select_error(); @@ -2615,20 +2664,21 @@ sock_recv_guts(PySocketSockObject *s, char* cbuf, Py_ssize_t len, int flags) return 0; } -#ifndef __VMS BEGIN_SELECT_LOOP(s) - Py_BEGIN_ALLOW_THREADS - timeout = internal_select_ex(s, 0, interval); - if (!timeout) { + do { + Py_BEGIN_ALLOW_THREADS + timeout = internal_select_ex(s, 0, interval); + if (!timeout) { #ifdef MS_WINDOWS - if (len > INT_MAX) - len = INT_MAX; - outlen = recv(s->sock_fd, cbuf, (int)len, flags); + if (len > INT_MAX) + len = INT_MAX; + outlen = recv(s->sock_fd, cbuf, (int)len, flags); #else - outlen = recv(s->sock_fd, cbuf, len, flags); + outlen = recv(s->sock_fd, cbuf, len, flags); #endif - } - Py_END_ALLOW_THREADS + } + Py_END_ALLOW_THREADS + } while (outlen < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); if (timeout == 1) { PyErr_SetString(socket_timeout, "timed out"); @@ -2638,51 +2688,10 @@ sock_recv_guts(PySocketSockObject *s, char* cbuf, Py_ssize_t len, int flags) if (outlen < 0) { /* Note: the call to errorhandler() ALWAYS indirectly returned NULL, so ignore its return value */ - s->errorhandler(); - return -1; - } -#else - read_buf = cbuf; - remaining = len; - while (remaining != 0) { - unsigned int segment; - int nread = -1; - - segment = remaining /SEGMENT_SIZE; - if (segment != 0) { - segment = SEGMENT_SIZE; - } - else { - segment = remaining; - } - - BEGIN_SELECT_LOOP(s) - Py_BEGIN_ALLOW_THREADS - timeout = internal_select_ex(s, 0, interval); - if (!timeout) - nread = recv(s->sock_fd, read_buf, segment, flags); - Py_END_ALLOW_THREADS - if (timeout == 1) { - PyErr_SetString(socket_timeout, "timed out"); - return -1; - } - END_SELECT_LOOP(s) - - if (nread < 0) { + if (!async_err) s->errorhandler(); - return -1; - } - if (nread != remaining) { - read_buf += nread; - break; - } - - remaining -= segment; - read_buf += segment; + return -1; } - outlen = read_buf - cbuf; -#endif /* !__VMS */ - return outlen; } @@ -2817,6 +2826,7 @@ sock_recvfrom_guts(PySocketSockObject *s, char* cbuf, Py_ssize_t len, int flags, int timeout; Py_ssize_t n = -1; socklen_t addrlen; + int async_err = 0; *addr = NULL; @@ -2829,21 +2839,23 @@ sock_recvfrom_guts(PySocketSockObject *s, char* cbuf, Py_ssize_t len, int flags, } BEGIN_SELECT_LOOP(s) - Py_BEGIN_ALLOW_THREADS - memset(&addrbuf, 0, addrlen); - timeout = internal_select_ex(s, 0, interval); - if (!timeout) { + do { + Py_BEGIN_ALLOW_THREADS + memset(&addrbuf, 0, addrlen); + timeout = internal_select_ex(s, 0, interval); + if (!timeout) { #ifdef MS_WINDOWS - if (len > INT_MAX) - len = INT_MAX; - n = recvfrom(s->sock_fd, cbuf, (int)len, flags, - (void *) &addrbuf, &addrlen); + if (len > INT_MAX) + len = INT_MAX; + n = recvfrom(s->sock_fd, cbuf, (int)len, flags, + (void *) &addrbuf, &addrlen); #else - n = recvfrom(s->sock_fd, cbuf, len, flags, - SAS2SA(&addrbuf), &addrlen); + n = recvfrom(s->sock_fd, cbuf, len, flags, + SAS2SA(&addrbuf), &addrlen); #endif - } - Py_END_ALLOW_THREADS + } + Py_END_ALLOW_THREADS + } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); if (timeout == 1) { PyErr_SetString(socket_timeout, "timed out"); @@ -2851,7 +2863,8 @@ sock_recvfrom_guts(PySocketSockObject *s, char* cbuf, Py_ssize_t len, int flags, } END_SELECT_LOOP(s) if (n < 0) { - s->errorhandler(); + if (!async_err) + s->errorhandler(); return -1; } @@ -2934,7 +2947,6 @@ sock_recvfrom_into(PySocketSockObject *s, PyObject *args, PyObject* kwds) return NULL; buf = pbuf.buf; buflen = pbuf.len; - assert(buf != 0 && buflen > 0); if (recvlen < 0) { PyBuffer_Release(&pbuf); @@ -2945,6 +2957,11 @@ sock_recvfrom_into(PySocketSockObject *s, PyObject *args, PyObject* kwds) if (recvlen == 0) { /* If nbytes was not specified, use the buffer's length */ recvlen = buflen; + } else if (recvlen > buflen) { + PyBuffer_Release(&pbuf); + PyErr_SetString(PyExc_ValueError, + "nbytes is greater than the length of the buffer"); + return NULL; } readlen = sock_recvfrom_guts(s, buf, recvlen, flags, &addr); @@ -2987,6 +3004,7 @@ sock_recvmsg_guts(PySocketSockObject *s, struct iovec *iov, int iovlen, { ssize_t bytes_received = -1; int timeout; + int async_err = 0; sock_addr_t addrbuf; socklen_t addrbuflen; struct msghdr msg = {0}; @@ -3022,25 +3040,29 @@ sock_recvmsg_guts(PySocketSockObject *s, struct iovec *iov, int iovlen, } BEGIN_SELECT_LOOP(s) - Py_BEGIN_ALLOW_THREADS; - msg.msg_name = SAS2SA(&addrbuf); - msg.msg_namelen = addrbuflen; - msg.msg_iov = iov; - msg.msg_iovlen = iovlen; - msg.msg_control = controlbuf; - msg.msg_controllen = controllen; - timeout = internal_select_ex(s, 0, interval); - if (!timeout) - bytes_received = recvmsg(s->sock_fd, &msg, flags); - Py_END_ALLOW_THREADS; - if (timeout == 1) { - PyErr_SetString(socket_timeout, "timed out"); - goto finally; - } + do { + Py_BEGIN_ALLOW_THREADS; + msg.msg_name = SAS2SA(&addrbuf); + msg.msg_namelen = addrbuflen; + msg.msg_iov = iov; + msg.msg_iovlen = iovlen; + msg.msg_control = controlbuf; + msg.msg_controllen = controllen; + timeout = internal_select_ex(s, 0, interval); + if (!timeout) + bytes_received = recvmsg(s->sock_fd, &msg, flags); + Py_END_ALLOW_THREADS; + if (timeout == 1) { + PyErr_SetString(socket_timeout, "timed out"); + goto finally; + } + } while (bytes_received < 0 && errno == EINTR && + !(async_err = PyErr_CheckSignals())); END_SELECT_LOOP(s) if (bytes_received < 0) { - s->errorhandler(); + if (!async_err) + s->errorhandler(); goto finally; } @@ -3299,6 +3321,7 @@ sock_send(PySocketSockObject *s, PyObject *args) { char *buf; Py_ssize_t len, n = -1; + int async_err = 0; int flags = 0, timeout; Py_buffer pbuf; @@ -3313,20 +3336,20 @@ sock_send(PySocketSockObject *s, PyObject *args) len = pbuf.len; BEGIN_SELECT_LOOP(s) - Py_BEGIN_ALLOW_THREADS - timeout = internal_select_ex(s, 1, interval); - if (!timeout) { -#ifdef __VMS - n = sendsegmented(s->sock_fd, buf, len, flags); -#elif defined(MS_WINDOWS) - if (len > INT_MAX) - len = INT_MAX; - n = send(s->sock_fd, buf, (int)len, flags); + do { + Py_BEGIN_ALLOW_THREADS + timeout = internal_select_ex(s, 1, interval); + if (!timeout) { +#ifdef MS_WINDOWS + if (len > INT_MAX) + len = INT_MAX; + n = send(s->sock_fd, buf, (int)len, flags); #else - n = send(s->sock_fd, buf, len, flags); + n = send(s->sock_fd, buf, len, flags); #endif - } - Py_END_ALLOW_THREADS + } + Py_END_ALLOW_THREADS + } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); if (timeout == 1) { PyBuffer_Release(&pbuf); PyErr_SetString(socket_timeout, "timed out"); @@ -3336,7 +3359,7 @@ sock_send(PySocketSockObject *s, PyObject *args) PyBuffer_Release(&pbuf); if (n < 0) - return s->errorhandler(); + return (!async_err) ? s->errorhandler() : NULL; return PyLong_FromSsize_t(n); } @@ -3355,7 +3378,8 @@ sock_sendall(PySocketSockObject *s, PyObject *args) { char *buf; Py_ssize_t len, n = -1; - int flags = 0, timeout, saved_errno; + int async_err = 0; + int flags = 0, timeout; Py_buffer pbuf; if (!PyArg_ParseTuple(args, "y*|i:sendall", &pbuf, &flags)) @@ -3373,9 +3397,7 @@ sock_sendall(PySocketSockObject *s, PyObject *args) timeout = internal_select(s, 1); n = -1; if (!timeout) { -#ifdef __VMS - n = sendsegmented(s->sock_fd, buf, len, flags); -#elif defined(MS_WINDOWS) +#ifdef MS_WINDOWS if (len > INT_MAX) len = INT_MAX; n = send(s->sock_fd, buf, (int)len, flags); @@ -3389,29 +3411,16 @@ sock_sendall(PySocketSockObject *s, PyObject *args) PyErr_SetString(socket_timeout, "timed out"); return NULL; } - /* PyErr_CheckSignals() might change errno */ - saved_errno = errno; - /* We must run our signal handlers before looping again. - send() can return a successful partial write when it is - interrupted, so we can't restrict ourselves to EINTR. */ - if (PyErr_CheckSignals()) { - PyBuffer_Release(&pbuf); - return NULL; - } - if (n < 0) { - /* If interrupted, try again */ - if (saved_errno == EINTR) - continue; - else - break; + if (n >= 0) { + buf += n; + len -= n; } - buf += n; - len -= n; - } while (len > 0); + } while (len > 0 && (n >= 0 || errno == EINTR) && + !(async_err = PyErr_CheckSignals())); PyBuffer_Release(&pbuf); - if (n < 0) - return s->errorhandler(); + if (n < 0 || async_err) + return (!async_err) ? s->errorhandler() : NULL; Py_INCREF(Py_None); return Py_None; @@ -3437,6 +3446,7 @@ sock_sendto(PySocketSockObject *s, PyObject *args) Py_ssize_t len, arglen; sock_addr_t addrbuf; int addrlen, n = -1, flags, timeout; + int async_err = 0; flags = 0; arglen = PyTuple_Size(args); @@ -3471,20 +3481,22 @@ sock_sendto(PySocketSockObject *s, PyObject *args) } BEGIN_SELECT_LOOP(s) - Py_BEGIN_ALLOW_THREADS - timeout = internal_select_ex(s, 1, interval); - if (!timeout) { + do { + Py_BEGIN_ALLOW_THREADS + timeout = internal_select_ex(s, 1, interval); + if (!timeout) { #ifdef MS_WINDOWS - if (len > INT_MAX) - len = INT_MAX; - n = sendto(s->sock_fd, buf, (int)len, flags, - SAS2SA(&addrbuf), addrlen); + if (len > INT_MAX) + len = INT_MAX; + n = sendto(s->sock_fd, buf, (int)len, flags, + SAS2SA(&addrbuf), addrlen); #else - n = sendto(s->sock_fd, buf, len, flags, - SAS2SA(&addrbuf), addrlen); + n = sendto(s->sock_fd, buf, len, flags, + SAS2SA(&addrbuf), addrlen); #endif - } - Py_END_ALLOW_THREADS + } + Py_END_ALLOW_THREADS + } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); if (timeout == 1) { PyBuffer_Release(&pbuf); @@ -3494,7 +3506,7 @@ sock_sendto(PySocketSockObject *s, PyObject *args) END_SELECT_LOOP(s) PyBuffer_Release(&pbuf); if (n < 0) - return s->errorhandler(); + return (!async_err) ? s->errorhandler() : NULL; return PyLong_FromSsize_t(n); } @@ -3526,6 +3538,7 @@ sock_sendmsg(PySocketSockObject *s, PyObject *args) void *controlbuf = NULL; size_t controllen, controllen_last; ssize_t bytes_sent = -1; + int async_err = 0; int addrlen, timeout, flags = 0; PyObject *data_arg, *cmsg_arg = NULL, *addr_arg = NULL, *data_fast = NULL, *cmsg_fast = NULL, *retval = NULL; @@ -3563,7 +3576,7 @@ sock_sendmsg(PySocketSockObject *s, PyObject *args) for (; ndatabufs < ndataparts; ndatabufs++) { if (!PyArg_Parse(PySequence_Fast_GET_ITEM(data_fast, ndatabufs), "y*;sendmsg() argument 1 must be an iterable of " - "buffer-compatible objects", + "bytes-like objects", &databufs[ndatabufs])) goto finally; iovs[ndatabufs].iov_base = databufs[ndatabufs].buf; @@ -3683,19 +3696,23 @@ sock_sendmsg(PySocketSockObject *s, PyObject *args) } BEGIN_SELECT_LOOP(s) - Py_BEGIN_ALLOW_THREADS; - timeout = internal_select_ex(s, 1, interval); - if (!timeout) - bytes_sent = sendmsg(s->sock_fd, &msg, flags); - Py_END_ALLOW_THREADS; - if (timeout == 1) { - PyErr_SetString(socket_timeout, "timed out"); - goto finally; - } + do { + Py_BEGIN_ALLOW_THREADS; + timeout = internal_select_ex(s, 1, interval); + if (!timeout) + bytes_sent = sendmsg(s->sock_fd, &msg, flags); + Py_END_ALLOW_THREADS; + if (timeout == 1) { + PyErr_SetString(socket_timeout, "timed out"); + goto finally; + } + } while (bytes_sent < 0 && errno == EINTR && + !(async_err = PyErr_CheckSignals())); END_SELECT_LOOP(s) if (bytes_sent < 0) { - s->errorhandler(); + if (!async_err) + s->errorhandler(); goto finally; } retval = PyLong_FromSsize_t(bytes_sent); @@ -3720,12 +3737,12 @@ PyDoc_STRVAR(sendmsg_doc, Send normal and ancillary data to the socket, gathering the\n\ non-ancillary data from a series of buffers and concatenating it into\n\ a single message. The buffers argument specifies the non-ancillary\n\ -data as an iterable of buffer-compatible objects (e.g. bytes objects).\n\ +data as an iterable of bytes-like objects (e.g. bytes objects).\n\ The ancdata argument specifies the ancillary data (control messages)\n\ as an iterable of zero or more tuples (cmsg_level, cmsg_type,\n\ cmsg_data), where cmsg_level and cmsg_type are integers specifying the\n\ protocol level and protocol-specific type respectively, and cmsg_data\n\ -is a buffer-compatible object holding the associated data. The flags\n\ +is a bytes-like object holding the associated data. The flags\n\ argument defaults to 0 and has the same meaning as for send(). If\n\ address is supplied and not None, it sets a destination address for\n\ the message. The return value is the number of bytes of non-ancillary\n\ @@ -3865,7 +3882,7 @@ static PyMethodDef sock_methods[] = { {"share", (PyCFunction)sock_share, METH_VARARGS, sock_share_doc}, #endif - {"listen", (PyCFunction)sock_listen, METH_O, + {"listen", (PyCFunction)sock_listen, METH_VARARGS, listen_doc}, {"recv", (PyCFunction)sock_recv, METH_VARARGS, recv_doc}, @@ -3938,8 +3955,13 @@ sock_dealloc(PySocketSockObject *s) static PyObject * sock_repr(PySocketSockObject *s) { + long sock_fd; + /* On Windows, this test is needed because SOCKET_T is unsigned */ + if (s->sock_fd == INVALID_SOCKET) { + sock_fd = -1; + } #if SIZEOF_SOCKET_T > SIZEOF_LONG - if (s->sock_fd > LONG_MAX) { + else if (s->sock_fd > LONG_MAX) { /* this can occur on Win64, and actually there is a special ugly printf formatter for decimal pointer length integer printing, only bother if necessary*/ @@ -3949,9 +3971,11 @@ sock_repr(PySocketSockObject *s) return NULL; } #endif + else + sock_fd = (long)s->sock_fd; return PyUnicode_FromFormat( "", - (long)s->sock_fd, s->sock_family, + sock_fd, s->sock_family, s->sock_type, s->sock_proto); } @@ -4189,9 +4213,11 @@ socket_gethostname(PyObject *self, PyObject *unused) /* MSDN says ERROR_MORE_DATA may occur because DNS allows longer names */ - name = PyMem_Malloc(size * sizeof(wchar_t)); - if (!name) + name = PyMem_New(wchar_t, size); + if (!name) { + PyErr_NoMemory(); return NULL; + } if (!GetComputerNameExW(ComputerNamePhysicalDnsHostname, name, &size)) @@ -4287,7 +4313,7 @@ Return the IP address (a string of the form '255.255.255.255') for a host."); /* Convenience function common to gethostbyname_ex and gethostbyaddr */ static PyObject * -gethost_common(struct hostent *h, struct sockaddr *addr, int alen, int af) +gethost_common(struct hostent *h, struct sockaddr *addr, size_t alen, int af) { char **pch; PyObject *rtn_tuple = (PyObject *)NULL; @@ -5308,9 +5334,9 @@ socket_getaddrinfo(PyObject *self, PyObject *args, PyObject* kwargs) #if defined(__APPLE__) && defined(AI_NUMERICSERV) if ((flags & AI_NUMERICSERV) && (pptr == NULL || (pptr[0] == '0' && pptr[1] == 0))) { /* On OSX upto at least OSX 10.8 getaddrinfo crashes - * if AI_NUMERICSERV is set and the servname is NULL or "0". - * This workaround avoids a segfault in libsystem. - */ + * if AI_NUMERICSERV is set and the servname is NULL or "0". + * This workaround avoids a segfault in libsystem. + */ pptr = "00"; } #endif @@ -5362,8 +5388,8 @@ socket_getaddrinfo(PyObject *self, PyObject *args, PyObject* kwargs) } PyDoc_STRVAR(getaddrinfo_doc, -"getaddrinfo(host, port [, family, socktype, proto, flags])\n\ - -> list of (family, socktype, proto, canonname, sockaddr)\n\ +"getaddrinfo(host, port [, family, type, proto, flags])\n\ + -> list of (family, type, proto, canonname, sockaddr)\n\ \n\ Resolve host and port into addrinfo struct."); @@ -5841,11 +5867,15 @@ PyInit__socket(void) #ifdef MS_WINDOWS if (support_wsa_no_inherit == -1) { +#if defined(_MSC_VER) && _MSC_VER >= 1800 + support_wsa_no_inherit = IsWindows7SP1OrGreater(); +#else DWORD version = GetVersion(); DWORD major = (DWORD)LOBYTE(LOWORD(version)); DWORD minor = (DWORD)HIBYTE(LOWORD(version)); /* need Windows 7 SP1, 2008 R2 SP1 or later */ - support_wsa_no_inherit = (major >= 6 && minor >= 1); + support_wsa_no_inherit = major > 6 || (major == 6 && minor >= 1); +#endif } #endif @@ -6244,6 +6274,9 @@ PyInit__socket(void) #ifdef SO_PRIORITY PyModule_AddIntMacro(m, SO_PRIORITY); #endif +#ifdef SO_MARK + PyModule_AddIntMacro(m, SO_MARK); +#endif /* Maximum number of connections for "listen" */ #ifdef SOMAXCONN diff --git a/Modules/spwdmodule.c b/Modules/spwdmodule.c index 68ea1b5ea4af..013cb1156e08 100644 --- a/Modules/spwdmodule.c +++ b/Modules/spwdmodule.c @@ -10,6 +10,13 @@ #include #endif +#include "clinic/spwdmodule.c.h" + +/*[clinic input] +output preset file +module spwd +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=b3464a3667278fae]*/ PyDoc_STRVAR(spwd__doc__, "This module provides access to the Unix shadow password database.\n\ @@ -107,20 +114,25 @@ static PyObject *mkspent(struct spwd *p) #ifdef HAVE_GETSPNAM -PyDoc_STRVAR(spwd_getspnam__doc__, -"getspnam(name) -> (sp_namp, sp_pwdp, sp_lstchg, sp_min, sp_max,\n\ - sp_warn, sp_inact, sp_expire, sp_flag)\n\ -Return the shadow password database entry for the given user name.\n\ -See spwd.__doc__ for more on shadow password database entries."); +/*[clinic input] +spwd.getspnam + + arg: unicode + / + +Return the shadow password database entry for the given user name. + +See `help(spwd)` for more on shadow password database entries. +[clinic start generated code]*/ -static PyObject* spwd_getspnam(PyObject *self, PyObject *args) +static PyObject * +spwd_getspnam_impl(PyModuleDef *module, PyObject *arg) +/*[clinic end generated code: output=9f6bbe51a4eb3b21 input=dd89429e6167a00f]*/ { char *name; struct spwd *p; - PyObject *arg, *bytes, *retval = NULL; + PyObject *bytes, *retval = NULL; - if (!PyArg_ParseTuple(args, "U:getspnam", &arg)) - return NULL; if ((bytes = PyUnicode_EncodeFSDefault(arg)) == NULL) return NULL; if (PyBytes_AsStringAndSize(bytes, &name, NULL) == -1) @@ -139,14 +151,17 @@ static PyObject* spwd_getspnam(PyObject *self, PyObject *args) #ifdef HAVE_GETSPENT -PyDoc_STRVAR(spwd_getspall__doc__, -"getspall() -> list_of_entries\n\ -Return a list of all available shadow password database entries, \ -in arbitrary order.\n\ -See spwd.__doc__ for more on shadow password database entries."); +/*[clinic input] +spwd.getspall + +Return a list of all available shadow password database entries, in arbitrary order. + +See `help(spwd)` for more on shadow password database entries. +[clinic start generated code]*/ static PyObject * -spwd_getspall(PyObject *self, PyObject *args) +spwd_getspall_impl(PyModuleDef *module) +/*[clinic end generated code: output=b12d8ec7bdb29612 input=b2c84b7857d622bd]*/ { PyObject *d; struct spwd *p; @@ -171,10 +186,10 @@ spwd_getspall(PyObject *self, PyObject *args) static PyMethodDef spwd_methods[] = { #ifdef HAVE_GETSPNAM - {"getspnam", spwd_getspnam, METH_VARARGS, spwd_getspnam__doc__}, + SPWD_GETSPNAM_METHODDEF #endif #ifdef HAVE_GETSPENT - {"getspall", spwd_getspall, METH_NOARGS, spwd_getspall__doc__}, + SPWD_GETSPALL_METHODDEF #endif {NULL, NULL} /* sentinel */ }; diff --git a/Modules/sre.h b/Modules/sre.h index 621e2d88d53e..b632165a1f51 100644 --- a/Modules/sre.h +++ b/Modules/sre.h @@ -18,8 +18,10 @@ #define SRE_CODE Py_UCS4 #if SIZEOF_SIZE_T > 4 # define SRE_MAXREPEAT (~(SRE_CODE)0) +# define SRE_MAXGROUPS ((~(SRE_CODE)0) / 2) #else # define SRE_MAXREPEAT ((SRE_CODE)PY_SSIZE_T_MAX) +# define SRE_MAXGROUPS ((SRE_CODE)PY_SSIZE_T_MAX / SIZEOF_SIZE_T / 2) #endif typedef struct { @@ -52,9 +54,6 @@ typedef struct { typedef unsigned int (*SRE_TOLOWER_HOOK)(unsigned int ch); -/* FIXME: shouldn't be a constant, really... */ -#define SRE_MARK_SIZE 200 - typedef struct SRE_REPEAT_T { Py_ssize_t count; SRE_CODE* pattern; /* points to REPEAT operator arguments */ @@ -76,7 +75,7 @@ typedef struct { /* registers */ Py_ssize_t lastindex; Py_ssize_t lastmark; - void* mark[SRE_MARK_SIZE]; + void** mark; /* dynamically allocated stuff */ char* data_stack; size_t data_stack_size; @@ -85,8 +84,7 @@ typedef struct { /* current repeat context */ SRE_REPEAT *repeat; /* hooks */ - SRE_TOLOWER_HOOK lower; - int match_all; + SRE_TOLOWER_HOOK lower, upper; } SRE_STATE; typedef struct { diff --git a/Modules/sre_constants.h b/Modules/sre_constants.h index 5940d5a50f70..6632442efe56 100644 --- a/Modules/sre_constants.h +++ b/Modules/sre_constants.h @@ -11,7 +11,7 @@ * See the _sre.c file for information on usage and redistribution. */ -#define SRE_MAGIC 20031017 +#define SRE_MAGIC 20140917 #define SRE_OP_FAILURE 0 #define SRE_OP_SUCCESS 1 #define SRE_OP_ANY 2 @@ -44,6 +44,7 @@ #define SRE_OP_REPEAT_ONE 29 #define SRE_OP_SUBPATTERN 30 #define SRE_OP_MIN_REPEAT_ONE 31 +#define SRE_OP_RANGE_IGNORE 32 #define SRE_AT_BEGINNING 0 #define SRE_AT_BEGINNING_LINE 1 #define SRE_AT_BEGINNING_STRING 2 diff --git a/Modules/sre_lib.h b/Modules/sre_lib.h index df86697690ba..463a908b0064 100644 --- a/Modules/sre_lib.h +++ b/Modules/sre_lib.h @@ -101,7 +101,7 @@ SRE(at)(SRE_STATE* state, SRE_CHAR* ptr, SRE_CODE at) } LOCAL(int) -SRE(charset)(SRE_CODE* set, SRE_CODE ch) +SRE(charset)(SRE_STATE* state, SRE_CODE* set, SRE_CODE ch) { /* check if character is a member of the given set */ @@ -142,6 +142,20 @@ SRE(charset)(SRE_CODE* set, SRE_CODE ch) set += 2; break; + case SRE_OP_RANGE_IGNORE: + /* */ + { + SRE_CODE uch; + /* ch is already lower cased */ + if (set[0] <= ch && ch <= set[1]) + return ok; + uch = state->upper(ch); + if (set[0] <= uch && uch <= set[1]) + return ok; + set += 2; + break; + } + case SRE_OP_NEGATE: ok = !ok; break; @@ -173,7 +187,7 @@ SRE(charset)(SRE_CODE* set, SRE_CODE ch) } } -LOCAL(Py_ssize_t) SRE(match)(SRE_STATE* state, SRE_CODE* pattern); +LOCAL(Py_ssize_t) SRE(match)(SRE_STATE* state, SRE_CODE* pattern, int match_all); LOCAL(Py_ssize_t) SRE(count)(SRE_STATE* state, SRE_CODE* pattern, Py_ssize_t maxcount) @@ -193,7 +207,7 @@ SRE(count)(SRE_STATE* state, SRE_CODE* pattern, Py_ssize_t maxcount) case SRE_OP_IN: /* repeated set */ TRACE(("|%p|%p|COUNT IN\n", pattern, ptr)); - while (ptr < end && SRE(charset)(pattern + 2, *ptr)) + while (ptr < end && SRE(charset)(state, pattern + 2, *ptr)) ptr++; break; @@ -259,7 +273,7 @@ SRE(count)(SRE_STATE* state, SRE_CODE* pattern, Py_ssize_t maxcount) /* repeated single character pattern */ TRACE(("|%p|%p|COUNT SUBPATTERN\n", pattern, ptr)); while ((SRE_CHAR*) state->ptr < end) { - i = SRE(match)(state, pattern); + i = SRE(match)(state, pattern, 0); if (i < 0) return i; if (!i) @@ -490,7 +504,7 @@ typedef struct { /* check if string matches the given pattern. returns <0 for error, 0 for failure, and 1 for success */ LOCAL(Py_ssize_t) -SRE(match)(SRE_STATE* state, SRE_CODE* pattern) +SRE(match)(SRE_STATE* state, SRE_CODE* pattern, int match_all) { SRE_CHAR* end = (SRE_CHAR *)state->end; Py_ssize_t alloc_pos, ctx_pos = -1; @@ -507,7 +521,7 @@ SRE(match)(SRE_STATE* state, SRE_CODE* pattern) ctx->last_ctx_pos = -1; ctx->jump = JUMP_NONE; ctx->pattern = pattern; - ctx->match_all = state->match_all; + ctx->match_all = match_all; ctx_pos = alloc_pos; entrance: @@ -628,7 +642,8 @@ SRE(match)(SRE_STATE* state, SRE_CODE* pattern) /* match set member (or non_member) */ /* */ TRACE(("|%p|%p|IN\n", ctx->pattern, ctx->ptr)); - if (ctx->ptr >= end || !SRE(charset)(ctx->pattern + 1, *ctx->ptr)) + if (ctx->ptr >= end || + !SRE(charset)(state, ctx->pattern + 1, *ctx->ptr)) RETURN_FAILURE; ctx->pattern += ctx->pattern[0]; ctx->ptr++; @@ -657,7 +672,7 @@ SRE(match)(SRE_STATE* state, SRE_CODE* pattern) case SRE_OP_IN_IGNORE: TRACE(("|%p|%p|IN_IGNORE\n", ctx->pattern, ctx->ptr)); if (ctx->ptr >= end - || !SRE(charset)(ctx->pattern+1, + || !SRE(charset)(state, ctx->pattern+1, (SRE_CODE)state->lower(*ctx->ptr))) RETURN_FAILURE; ctx->pattern += ctx->pattern[0]; @@ -688,7 +703,8 @@ SRE(match)(SRE_STATE* state, SRE_CODE* pattern) continue; if (ctx->pattern[1] == SRE_OP_IN && (ctx->ptr >= end || - !SRE(charset)(ctx->pattern + 3, (SRE_CODE) *ctx->ptr))) + !SRE(charset)(state, ctx->pattern + 3, + (SRE_CODE) *ctx->ptr))) continue; state->ptr = ctx->ptr; DO_JUMP(JUMP_BRANCH, jump_branch, ctx->pattern+1); @@ -739,7 +755,7 @@ SRE(match)(SRE_STATE* state, SRE_CODE* pattern) RETURN_FAILURE; if (ctx->pattern[ctx->pattern[0]] == SRE_OP_SUCCESS && - (!ctx->match_all || ctx->ptr == state->end)) { + ctx->ptr == state->end) { /* tail is empty. we're finished */ state->ptr = ctx->ptr; RETURN_SUCCESS; @@ -824,7 +840,7 @@ SRE(match)(SRE_STATE* state, SRE_CODE* pattern) } if (ctx->pattern[ctx->pattern[0]] == SRE_OP_SUCCESS && - (!ctx->match_all || ctx->ptr == state->end)) { + (!match_all || ctx->ptr == state->end)) { /* tail is empty. we're finished */ state->ptr = ctx->ptr; RETURN_SUCCESS; @@ -1269,7 +1285,7 @@ SRE(search)(SRE_STATE* state, SRE_CODE* pattern) state->ptr = ptr - (prefix_len - prefix_skip - 1); if (flags & SRE_INFO_LITERAL) return 1; /* we got all of it */ - status = SRE(match)(state, pattern + 2*prefix_skip); + status = SRE(match)(state, pattern + 2*prefix_skip, 0); if (status != 0) return status; /* close but no cigar -- try again */ @@ -1302,7 +1318,7 @@ SRE(search)(SRE_STATE* state, SRE_CODE* pattern) state->ptr = ++ptr; if (flags & SRE_INFO_LITERAL) return 1; /* we got all of it */ - status = SRE(match)(state, pattern + 2); + status = SRE(match)(state, pattern + 2, 0); if (status != 0) break; } @@ -1310,14 +1326,14 @@ SRE(search)(SRE_STATE* state, SRE_CODE* pattern) /* pattern starts with a character from a known set */ end = (SRE_CHAR *)state->end; for (;;) { - while (ptr < end && !SRE(charset)(charset, *ptr)) + while (ptr < end && !SRE(charset)(state, charset, *ptr)) ptr++; if (ptr >= end) return 0; TRACE(("|%p|%p|SEARCH CHARSET\n", pattern, ptr)); state->start = ptr; state->ptr = ptr; - status = SRE(match)(state, pattern); + status = SRE(match)(state, pattern, 0); if (status != 0) break; ptr++; @@ -1327,7 +1343,7 @@ SRE(search)(SRE_STATE* state, SRE_CODE* pattern) while (ptr <= end) { TRACE(("|%p|%p|SEARCH\n", pattern, ptr)); state->start = state->ptr = ptr++; - status = SRE(match)(state, pattern); + status = SRE(match)(state, pattern, 0); if (status != 0) break; } diff --git a/Modules/syslogmodule.c b/Modules/syslogmodule.c index 9d79eec52a38..f2d44ff5e6b1 100644 --- a/Modules/syslogmodule.c +++ b/Modules/syslogmodule.c @@ -197,8 +197,7 @@ syslog_closelog(PyObject *self, PyObject *unused) { if (S_log_open) { closelog(); - Py_XDECREF(S_ident_o); - S_ident_o = NULL; + Py_CLEAR(S_ident_o); S_log_open = 0; } Py_INCREF(Py_None); diff --git a/Modules/timemodule.c b/Modules/timemodule.c index d3878b95d99f..7f5f3149afdb 100644 --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -27,28 +27,13 @@ #define WIN32_LEAN_AND_MEAN #include #include "pythread.h" - -#if defined(__BORLANDC__) -/* These overrides not needed for Win32 */ -#define timezone _timezone -#define tzname _tzname -#define daylight _daylight -#endif /* __BORLANDC__ */ #endif /* MS_WINDOWS */ #endif /* !__WATCOMC__ || __QNX__ */ -#if defined(__APPLE__) -#include -#endif - /* Forward declarations */ static int floatsleep(double); static PyObject* floattime(_Py_clock_info_t *info); -#ifdef MS_WINDOWS -static OSVERSIONINFOEX winver; -#endif - static PyObject * time_time(PyObject *self, PyObject *unused) { @@ -92,12 +77,12 @@ floatclock(_Py_clock_info_t *info) } #endif /* HAVE_CLOCK */ -#if defined(MS_WINDOWS) && !defined(__BORLANDC__) +#ifdef MS_WINDOWS #define WIN32_PERF_COUNTER /* Win32 has better clock replacement; we have our own version, due to Mark Hammond and Tim Peters */ -static int -win_perf_counter(_Py_clock_info_t *info, PyObject **result) +static PyObject* +win_perf_counter(_Py_clock_info_t *info) { static LONGLONG cpu_frequency = 0; static LONGLONG ctrStart; @@ -109,10 +94,8 @@ win_perf_counter(_Py_clock_info_t *info, PyObject **result) QueryPerformanceCounter(&now); ctrStart = now.QuadPart; if (!QueryPerformanceFrequency(&freq) || freq.QuadPart == 0) { - /* Unlikely to happen - this works on all intel - machines at least! Revert to clock() */ - *result = NULL; - return -1; + PyErr_SetFromWindowsErr(0); + return NULL; } cpu_frequency = freq.QuadPart; } @@ -124,10 +107,9 @@ win_perf_counter(_Py_clock_info_t *info, PyObject **result) info->monotonic = 1; info->adjustable = 0; } - *result = PyFloat_FromDouble(diff / (double)cpu_frequency); - return 0; + return PyFloat_FromDouble(diff / (double)cpu_frequency); } -#endif +#endif /* MS_WINDOWS */ #if defined(WIN32_PERF_COUNTER) || defined(HAVE_CLOCK) #define PYCLOCK @@ -135,11 +117,10 @@ static PyObject* pyclock(_Py_clock_info_t *info) { #ifdef WIN32_PERF_COUNTER - PyObject *res; - if (win_perf_counter(info, &res) == 0) - return res; -#endif + return win_perf_counter(info); +#else return floatclock(info); +#endif } static PyObject * @@ -169,7 +150,7 @@ time_clock_gettime(PyObject *self, PyObject *args) ret = clock_gettime((clockid_t)clk_id, &tp); if (ret != 0) { - PyErr_SetFromErrno(PyExc_IOError); + PyErr_SetFromErrno(PyExc_OSError); return NULL; } return PyFloat_FromDouble(tp.tv_sec + tp.tv_nsec * 1e-9); @@ -193,14 +174,14 @@ time_clock_settime(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "iO:clock_settime", &clk_id, &obj)) return NULL; - if (_PyTime_ObjectToTimespec(obj, &tv_sec, &tv_nsec) == -1) + if (_PyTime_ObjectToTimespec(obj, &tv_sec, &tv_nsec, _PyTime_ROUND_DOWN) == -1) return NULL; tp.tv_sec = tv_sec; tp.tv_nsec = tv_nsec; ret = clock_settime((clockid_t)clk_id, &tp); if (ret != 0) { - PyErr_SetFromErrno(PyExc_IOError); + PyErr_SetFromErrno(PyExc_OSError); return NULL; } Py_RETURN_NONE; @@ -223,7 +204,7 @@ time_clock_getres(PyObject *self, PyObject *args) ret = clock_getres((clockid_t)clk_id, &tp); if (ret != 0) { - PyErr_SetFromErrno(PyExc_IOError); + PyErr_SetFromErrno(PyExc_OSError); return NULL; } @@ -341,7 +322,7 @@ parse_time_t_args(PyObject *args, char *format, time_t *pwhen) whent = time(NULL); } else { - if (_PyTime_ObjectToTime_t(ot, &whent) == -1) + if (_PyTime_ObjectToTime_t(ot, &whent, _PyTime_ROUND_DOWN) == -1) return 0; } *pwhen = whent; @@ -823,7 +804,18 @@ time_mktime(PyObject *self, PyObject *tup) time_t tt; if (!gettmarg(tup, &buf)) return NULL; +#ifdef _AIX + /* year < 1902 or year > 2037 */ + if (buf.tm_year < 2 || buf.tm_year > 137) { + /* Issue #19748: On AIX, mktime() doesn't report overflow error for + * timestamp < -2^31 or timestamp > 2**31-1. */ + PyErr_SetString(PyExc_OverflowError, + "mktime argument out of range"); + return NULL; + } +#else buf.tm_wday = -1; /* sentinel; original value ignored */ +#endif tt = mktime(&buf); /* Return value of -1 does not necessarily mean an error, but tm_wday * cannot remain set to -1 if mktime succeeded. */ @@ -892,122 +884,15 @@ the local timezone used by methods such as localtime, but this behaviour\n\ should not be relied on."); #endif /* HAVE_WORKING_TZSET */ -#if defined(MS_WINDOWS) || defined(__APPLE__) \ - || (defined(HAVE_CLOCK_GETTIME) \ - && (defined(CLOCK_HIGHRES) || defined(CLOCK_MONOTONIC))) -#define PYMONOTONIC -#endif - -#ifdef PYMONOTONIC -static PyObject* +static PyObject * pymonotonic(_Py_clock_info_t *info) { -#if defined(MS_WINDOWS) - static ULONGLONG (*GetTickCount64) (void) = NULL; - static ULONGLONG (CALLBACK *Py_GetTickCount64)(void); - static int has_getickcount64 = -1; - double result; - - if (has_getickcount64 == -1) { - /* GetTickCount64() was added to Windows Vista */ - if (winver.dwMajorVersion >= 6) { - HINSTANCE hKernel32; - hKernel32 = GetModuleHandleW(L"KERNEL32"); - *(FARPROC*)&Py_GetTickCount64 = GetProcAddress(hKernel32, - "GetTickCount64"); - has_getickcount64 = (Py_GetTickCount64 != NULL); - } - else - has_getickcount64 = 0; - } - - if (has_getickcount64) { - ULONGLONG ticks; - ticks = Py_GetTickCount64(); - result = (double)ticks * 1e-3; - } - else { - static DWORD last_ticks = 0; - static DWORD n_overflow = 0; - DWORD ticks; - - ticks = GetTickCount(); - if (ticks < last_ticks) - n_overflow++; - last_ticks = ticks; - - result = ldexp(n_overflow, 32); - result += ticks; - result *= 1e-3; - } - - if (info) { - DWORD timeAdjustment, timeIncrement; - BOOL isTimeAdjustmentDisabled, ok; - if (has_getickcount64) - info->implementation = "GetTickCount64()"; - else - info->implementation = "GetTickCount()"; - info->monotonic = 1; - ok = GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement, - &isTimeAdjustmentDisabled); - if (!ok) { - PyErr_SetFromWindowsErr(0); - return NULL; - } - info->resolution = timeIncrement * 1e-7; - info->adjustable = 0; - } - return PyFloat_FromDouble(result); - -#elif defined(__APPLE__) - static mach_timebase_info_data_t timebase; - uint64_t time; - double secs; - - if (timebase.denom == 0) { - /* According to the Technical Q&A QA1398, mach_timebase_info() cannot - fail: https://developer.apple.com/library/mac/#qa/qa1398/ */ - (void)mach_timebase_info(&timebase); - } - - time = mach_absolute_time(); - secs = (double)time * timebase.numer / timebase.denom * 1e-9; - if (info) { - info->implementation = "mach_absolute_time()"; - info->resolution = (double)timebase.numer / timebase.denom * 1e-9; - info->monotonic = 1; - info->adjustable = 0; - } - return PyFloat_FromDouble(secs); - -#elif defined(HAVE_CLOCK_GETTIME) && (defined(CLOCK_HIGHRES) || defined(CLOCK_MONOTONIC)) - struct timespec tp; -#ifdef CLOCK_HIGHRES - const clockid_t clk_id = CLOCK_HIGHRES; - const char *function = "clock_gettime(CLOCK_HIGHRES)"; -#else - const clockid_t clk_id = CLOCK_MONOTONIC; - const char *function = "clock_gettime(CLOCK_MONOTONIC)"; -#endif - - if (clock_gettime(clk_id, &tp) != 0) { - PyErr_SetFromErrno(PyExc_OSError); + _PyTime_timeval tv; + if (_PyTime_monotonic_info(&tv, info) < 0) { + assert(info != NULL); return NULL; } - - if (info) { - struct timespec res; - info->monotonic = 1; - info->implementation = function; - info->adjustable = 0; - if (clock_getres(clk_id, &res) == 0) - info->resolution = res.tv_sec + res.tv_nsec * 1e-9; - else - info->resolution = 1e-9; - } - return PyFloat_FromDouble(tp.tv_sec + tp.tv_nsec * 1e-9); -#endif + return PyFloat_FromDouble((double)tv.tv_sec + tv.tv_usec * 1e-6); } static PyObject * @@ -1020,40 +905,15 @@ PyDoc_STRVAR(monotonic_doc, "monotonic() -> float\n\ \n\ Monotonic clock, cannot go backward."); -#endif /* PYMONOTONIC */ static PyObject* perf_counter(_Py_clock_info_t *info) { -#if defined(WIN32_PERF_COUNTER) || defined(PYMONOTONIC) - PyObject *res; -#endif -#if defined(WIN32_PERF_COUNTER) - static int use_perf_counter = 1; -#endif -#ifdef PYMONOTONIC - static int use_monotonic = 1; -#endif - #ifdef WIN32_PERF_COUNTER - if (use_perf_counter) { - if (win_perf_counter(info, &res) == 0) - return res; - use_perf_counter = 0; - } -#endif - -#ifdef PYMONOTONIC - if (use_monotonic) { - res = pymonotonic(info); - if (res != NULL) - return res; - use_monotonic = 0; - PyErr_Clear(); - } + return win_perf_counter(info); +#else + return pymonotonic(info); #endif - - return floattime(info); } static PyObject * @@ -1220,10 +1080,8 @@ time_get_clock_info(PyObject *self, PyObject *args) else if (strcmp(name, "clock") == 0) obj = pyclock(&info); #endif -#ifdef PYMONOTONIC else if (strcmp(name, "monotonic") == 0) obj = pymonotonic(&info); -#endif else if (strcmp(name, "perf_counter") == 0) obj = perf_counter(&info); else if (strcmp(name, "process_time") == 0) @@ -1415,9 +1273,7 @@ static PyMethodDef time_methods[] = { #ifdef HAVE_WORKING_TZSET {"tzset", time_tzset, METH_NOARGS, tzset_doc}, #endif -#ifdef PYMONOTONIC {"monotonic", time_monotonic, METH_NOARGS, monotonic_doc}, -#endif {"process_time", time_process_time, METH_NOARGS, process_time_doc}, {"perf_counter", time_perf_counter, METH_NOARGS, perf_counter_doc}, {"get_clock_info", time_get_clock_info, METH_VARARGS, get_clock_info_doc}, @@ -1499,15 +1355,6 @@ PyInit_time(void) if (PyStructSequence_InitType2(&StructTimeType, &struct_time_type_desc) < 0) return NULL; - -#ifdef MS_WINDOWS - winver.dwOSVersionInfoSize = sizeof(winver); - if (!GetVersionEx((OSVERSIONINFO*)&winver)) { - Py_DECREF(m); - PyErr_SetFromWindowsErr(0); - return NULL; - } -#endif } Py_INCREF(&StructTimeType); #ifdef HAVE_STRUCT_TM_TM_ZONE @@ -1524,29 +1371,10 @@ static PyObject* floattime(_Py_clock_info_t *info) { _PyTime_timeval t; -#ifdef HAVE_CLOCK_GETTIME - struct timespec tp; - int ret; - - /* _PyTime_gettimeofday() does not use clock_gettime() - because it would require to link Python to the rt (real-time) - library, at least on Linux */ - ret = clock_gettime(CLOCK_REALTIME, &tp); - if (ret == 0) { - if (info) { - struct timespec res; - info->implementation = "clock_gettime(CLOCK_REALTIME)"; - info->monotonic = 0; - info->adjustable = 1; - if (clock_getres(CLOCK_REALTIME, &res) == 0) - info->resolution = res.tv_sec + res.tv_nsec * 1e-9; - else - info->resolution = 1e-9; - } - return PyFloat_FromDouble(tp.tv_sec + tp.tv_nsec * 1e-9); + if (_PyTime_gettimeofday_info(&t, info) < 0) { + assert(info != NULL); + return NULL; } -#endif - _PyTime_gettimeofday_info(&t, info); return PyFloat_FromDouble((double)t.tv_sec + t.tv_usec * 1e-6); } @@ -1580,7 +1408,7 @@ floatsleep(double secs) else #endif { - PyErr_SetFromErrno(PyExc_IOError); + PyErr_SetFromErrno(PyExc_OSError); return -1; } } @@ -1614,7 +1442,7 @@ floatsleep(double secs) if (rc == WAIT_OBJECT_0) { Py_BLOCK_THREADS errno = EINTR; - PyErr_SetFromErrno(PyExc_IOError); + PyErr_SetFromErrno(PyExc_OSError); return -1; } } diff --git a/Modules/tkappinit.c b/Modules/tkappinit.c index 2ed85949cba0..7616d9d319d2 100644 --- a/Modules/tkappinit.c +++ b/Modules/tkappinit.c @@ -26,9 +26,6 @@ static int tk_load_failed; int Tcl_AppInit(Tcl_Interp *interp) { -#ifdef WITH_MOREBUTTONS - Tk_Window main_window; -#endif const char *_tkinter_skip_tk_init; #ifdef TKINTER_PROTECT_LOADTK const char *_tkinter_tk_failed; @@ -113,29 +110,13 @@ Tcl_AppInit(Tcl_Interp *interp) return TCL_ERROR; } -#ifdef WITH_MOREBUTTONS - main_window = Tk_MainWindow(interp); -#else Tk_MainWindow(interp); -#endif #ifdef TK_AQUA TkMacOSXInitAppleEvents(interp); TkMacOSXInitMenus(interp); #endif -#ifdef WITH_MOREBUTTONS - { - extern Tcl_CmdProc studButtonCmd; - extern Tcl_CmdProc triButtonCmd; - - Tcl_CreateCommand(interp, "studbutton", studButtonCmd, - (ClientData) main_window, NULL); - Tcl_CreateCommand(interp, "tributton", triButtonCmd, - (ClientData) main_window, NULL); - } -#endif - #ifdef WITH_PIL /* 0.2b5 and later -- not yet released as of May 14 */ { extern void TkImaging_Init(Tcl_Interp *); diff --git a/Modules/unicodedata.c b/Modules/unicodedata.c index eca0054b45ae..47d2937b8101 100644 --- a/Modules/unicodedata.c +++ b/Modules/unicodedata.c @@ -13,15 +13,17 @@ ------------------------------------------------------------------------ */ +#define PY_SSIZE_T_CLEAN + #include "Python.h" #include "ucnhash.h" #include "structmember.h" -/*[clinic] +/*[clinic input] module unicodedata -class unicodedata.UCD -[clinic]*/ -/*[clinic checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ +class unicodedata.UCD 'PreviousDBVersion *' '&UCD_Type' +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=6dac153082d150bc]*/ /* character properties */ @@ -113,11 +115,11 @@ static Py_UCS4 getuchar(PyUnicodeObject *obj) /* --- Module API --------------------------------------------------------- */ -/*[clinic] +/*[clinic input] unicodedata.UCD.decimal - unichr: object(type='str') + unichr: object(type='PyUnicodeObject *', subclass_of='&PyUnicode_Type') default: object=NULL / @@ -126,10 +128,12 @@ Converts a Unicode character into its equivalent decimal value. Returns the decimal value assigned to the Unicode character unichr as integer. If no such value is defined, default is returned, or, if not given, ValueError is raised. -[clinic]*/ +[clinic start generated code]*/ PyDoc_STRVAR(unicodedata_UCD_decimal__doc__, -"decimal(unichr, default=None)\n" +"decimal($self, unichr, default=None, /)\n" +"--\n" +"\n" "Converts a Unicode character into its equivalent decimal value.\n" "\n" "Returns the decimal value assigned to the Unicode character unichr\n" @@ -140,13 +144,13 @@ PyDoc_STRVAR(unicodedata_UCD_decimal__doc__, {"decimal", (PyCFunction)unicodedata_UCD_decimal, METH_VARARGS, unicodedata_UCD_decimal__doc__}, static PyObject * -unicodedata_UCD_decimal_impl(PyObject *self, PyObject *unichr, PyObject *default_value); +unicodedata_UCD_decimal_impl(PreviousDBVersion *self, PyUnicodeObject *unichr, PyObject *default_value); static PyObject * -unicodedata_UCD_decimal(PyObject *self, PyObject *args) +unicodedata_UCD_decimal(PreviousDBVersion *self, PyObject *args) { PyObject *return_value = NULL; - PyObject *unichr; + PyUnicodeObject *unichr; PyObject *default_value = NULL; if (!PyArg_ParseTuple(args, @@ -160,15 +164,14 @@ unicodedata_UCD_decimal(PyObject *self, PyObject *args) } static PyObject * -unicodedata_UCD_decimal_impl(PyObject *self, PyObject *unichr, PyObject *default_value) -/*[clinic checksum: 9576fa55f4ea0be82968af39dc9d0283e634beeb]*/ +unicodedata_UCD_decimal_impl(PreviousDBVersion *self, PyUnicodeObject *unichr, PyObject *default_value) +/*[clinic end generated code: output=8689669896d293df input=c25c9d2b4de076b1]*/ { - PyUnicodeObject *v = (PyUnicodeObject *)unichr; int have_old = 0; long rc; Py_UCS4 c; - c = getuchar(v); + c = getuchar(unichr); if (c == (Py_UCS4)-1) return NULL; @@ -553,7 +556,7 @@ nfd_nfkd(PyObject *self, PyObject *input, int k) /* Overallocate at most 10 characters. */ space = (isize > 10 ? 10 : isize) + isize; osize = space; - output = PyMem_Malloc(space * sizeof(Py_UCS4)); + output = PyMem_New(Py_UCS4, space); if (!output) { PyErr_NoMemory(); return NULL; @@ -700,7 +703,7 @@ nfc_nfkc(PyObject *self, PyObject *input, int k) /* We allocate a buffer for the output. If we find that we made no changes, we still return the NFD result. */ - output = PyMem_Malloc(len * sizeof(Py_UCS4)); + output = PyMem_New(Py_UCS4, len); if (!output) { PyErr_NoMemory(); Py_DECREF(result); @@ -973,7 +976,7 @@ is_unified_ideograph(Py_UCS4 code) (0x2B740 <= code && code <= 0x2B81D); /* CJK Ideograph Extension D */ } -/* macros used to determine if the given codepoint is in the PUA range that +/* macros used to determine if the given code point is in the PUA range that * we are using to store aliases and named sequences */ #define IS_ALIAS(cp) ((cp >= aliases_start) && (cp < aliases_end)) #define IS_NAMED_SEQ(cp) ((cp >= named_sequences_start) && \ @@ -983,7 +986,7 @@ static int _getucname(PyObject *self, Py_UCS4 code, char* buffer, int buflen, int with_alias_and_seq) { - /* Find the name associated with the given codepoint. + /* Find the name associated with the given code point. * If with_alias_and_seq is 1, check for names in the Private Use Area 15 * that we are using for aliases and named sequences. */ int offset; @@ -994,7 +997,7 @@ _getucname(PyObject *self, Py_UCS4 code, char* buffer, int buflen, if (code >= 0x110000) return 0; - /* XXX should we just skip all the codepoints in the PUAs here? */ + /* XXX should we just skip all the code points in the PUAs here? */ if (!with_alias_and_seq && (IS_ALIAS(code) || IS_NAMED_SEQ(code))) return 0; @@ -1122,8 +1125,8 @@ _check_alias_and_seq(unsigned int cp, Py_UCS4* code, int with_named_seq) /* check if named sequences are allowed */ if (!with_named_seq && IS_NAMED_SEQ(cp)) return 0; - /* if the codepoint is in the PUA range that we use for aliases, - * convert it to obtain the right codepoint */ + /* if the code point is in the PUA range that we use for aliases, + * convert it to obtain the right code point */ if (IS_ALIAS(cp)) *code = name_aliases[cp-aliases_start]; else @@ -1135,9 +1138,9 @@ static int _getcode(PyObject* self, const char* name, int namelen, Py_UCS4* code, int with_named_seq) { - /* Return the codepoint associated with the given name. + /* Return the code point associated with the given name. * Named aliases are resolved too (unless self != NULL (i.e. we are using - * 3.2.0)). If with_named_seq is 1, returns the PUA codepoint that we are + * 3.2.0)). If with_named_seq is 1, returns the PUA code point that we are * using for the named sequence, and the caller must then convert it. */ unsigned int h, v; unsigned int mask = code_size-1; @@ -1270,12 +1273,16 @@ unicodedata_lookup(PyObject* self, PyObject* args) Py_UCS4 code; char* name; - int namelen; + Py_ssize_t namelen; unsigned int index; if (!PyArg_ParseTuple(args, "s#:lookup", &name, &namelen)) return NULL; + if (namelen > INT_MAX) { + PyErr_SetString(PyExc_KeyError, "name too long"); + return NULL; + } - if (!_getcode(self, name, namelen, &code, 1)) { + if (!_getcode(self, name, (int)namelen, &code, 1)) { PyErr_Format(PyExc_KeyError, "undefined character name '%s'", name); return NULL; } diff --git a/Modules/unicodedata_db.h b/Modules/unicodedata_db.h index ec11fa1da497..a79132fd1e38 100644 --- a/Modules/unicodedata_db.h +++ b/Modules/unicodedata_db.h @@ -1,6 +1,6 @@ /* this file was generated by Tools/unicode/makeunicodedata.py 3.2 */ -#define UNIDATA_VERSION "6.3.0" +#define UNIDATA_VERSION "7.0.0" /* a list of unique database records */ const _PyUnicode_DatabaseRecord _PyUnicode_Database_Records[] = { {0, 0, 0, 0, 0, 0}, @@ -323,7 +323,9 @@ const _PyUnicode_DatabaseRecord _PyUnicode_Database_Records[] = { {27, 0, 19, 0, 1, 136}, {14, 0, 19, 0, 5, 0}, {8, 0, 19, 0, 5, 0}, + {9, 0, 9, 0, 5, 0}, {9, 0, 4, 0, 5, 0}, + {30, 0, 4, 0, 5, 0}, {9, 0, 12, 0, 5, 0}, {30, 0, 1, 0, 5, 170}, {5, 216, 1, 0, 5, 0}, @@ -335,8 +337,8 @@ const _PyUnicode_DatabaseRecord _PyUnicode_Database_Records[] = { }; /* Reindexing of NFC first characters. */ -#define TOTAL_FIRST 372 -#define TOTAL_LAST 56 +#define TOTAL_FIRST 376 +#define TOTAL_LAST 62 struct reindex{int start;short count,index;}; static struct reindex nfc_first[] = { { 60, 2, 0}, @@ -546,6 +548,9 @@ static struct reindex nfc_first[] = { { 69787, 0, 368}, { 69797, 0, 369}, { 69937, 1, 370}, + { 70471, 0, 372}, + { 70841, 0, 373}, + { 71096, 1, 374}, {0,0,0} }; @@ -583,6 +588,12 @@ static struct reindex nfc_last[] = { { 12441, 1, 52}, { 69818, 0, 54}, { 69927, 0, 55}, + { 70462, 0, 56}, + { 70487, 0, 57}, + { 70832, 0, 58}, + { 70842, 0, 59}, + { 70845, 0, 60}, + { 71087, 0, 61}, {0,0,0} }; @@ -714,36 +725,43 @@ static unsigned char index1[] = { 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 122, 122, 123, 124, - 125, 126, 127, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 84, - 138, 139, 140, 141, 142, 84, 84, 84, 84, 84, 84, 143, 84, 144, 145, 146, - 84, 147, 84, 148, 84, 84, 84, 149, 84, 84, 84, 150, 151, 152, 153, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 154, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 41, 41, 41, 41, 41, 41, 155, 84, 156, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 41, 41, 41, 41, 41, 41, 41, 41, 157, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 41, 41, 41, 41, 158, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 159, 160, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 161, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 78, 162, 163, 164, 165, 84, 166, 84, 167, 168, 169, 170, 171, 172, - 173, 174, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 175, 176, 84, 84, 177, 178, 179, - 180, 181, 84, 182, 183, 184, 185, 186, 187, 188, 189, 190, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 101, 101, 101, + 125, 126, 127, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, + 138, 139, 140, 141, 142, 143, 144, 138, 41, 41, 145, 138, 146, 147, 148, + 149, 150, 151, 152, 153, 154, 138, 138, 138, 155, 138, 138, 138, 156, + 157, 158, 159, 160, 161, 162, 138, 138, 163, 138, 164, 165, 166, 138, + 138, 138, 167, 138, 138, 138, 168, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 41, 41, 41, 41, 41, 41, 41, 169, 170, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 41, 41, 41, 41, 41, 41, 41, 41, 171, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 41, 41, 41, 41, 172, 173, 174, 175, 138, 138, 138, 138, + 138, 138, 176, 177, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 178, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 179, 180, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 78, + 181, 182, 183, 184, 138, 185, 138, 186, 187, 188, 189, 190, 191, 192, + 193, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 194, 195, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 196, 197, 138, 138, 198, 199, 200, 201, 202, 138, 203, + 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, @@ -767,359 +785,459 @@ static unsigned char index1[] = { 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 191, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 215, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 192, - 101, 193, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 122, 122, 122, 122, 194, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 195, 84, 196, 197, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 121, 121, 121, 121, 121, 121, 121, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 216, + 101, 217, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 122, 122, 122, 122, 218, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 219, 138, 220, 221, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, @@ -1155,8 +1273,8 @@ static unsigned char index1[] = { 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 222, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 198, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, @@ -1192,7 +1310,7 @@ static unsigned char index1[] = { 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 198, + 121, 121, 121, 121, 222, }; static unsigned short index2[] = { @@ -1244,7 +1362,7 @@ static unsigned short index2[] = { 69, 59, 69, 69, 70, 60, 62, 62, 62, 60, 60, 60, 62, 62, 71, 60, 60, 60, 62, 62, 62, 62, 60, 61, 62, 62, 60, 72, 73, 73, 72, 73, 73, 72, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 44, 47, 44, 47, 74, 54, 44, - 47, 0, 0, 51, 47, 47, 47, 75, 0, 0, 0, 0, 0, 58, 76, 38, 75, 38, 38, 38, + 47, 0, 0, 51, 47, 47, 47, 75, 44, 0, 0, 0, 0, 58, 76, 38, 75, 38, 38, 38, 0, 38, 0, 38, 38, 43, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 0, 39, 39, 39, 39, 39, 39, 39, 38, 38, 43, 43, 43, 43, 43, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, @@ -1267,153 +1385,154 @@ static unsigned short index2[] = { 38, 43, 38, 43, 38, 43, 44, 47, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 44, 47, 38, 43, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, - 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, + 44, 47, 44, 47, 44, 47, 0, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 0, 0, 53, 83, 83, 83, 83, 83, 83, 0, 47, 47, 47, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 0, 0, 53, 83, 83, 83, 83, 83, 83, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 35, - 0, 83, 84, 0, 0, 0, 0, 85, 0, 86, 81, 81, 81, 81, 86, 81, 81, 81, 87, 86, - 81, 81, 81, 81, 81, 81, 86, 86, 86, 86, 86, 86, 81, 81, 86, 81, 81, 87, - 88, 81, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 104, 81, 86, 104, 97, 0, 0, 0, 0, 0, 0, 0, 0, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, 0, - 0, 107, 107, 107, 104, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 108, - 108, 108, 108, 0, 78, 78, 109, 110, 110, 111, 112, 113, 26, 26, 81, 81, - 81, 81, 81, 81, 81, 81, 114, 115, 116, 113, 117, 0, 113, 113, 118, 118, - 119, 119, 119, 119, 119, 118, 118, 118, 118, 118, 118, 118, 118, 118, - 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, - 118, 118, 120, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 121, - 122, 123, 114, 115, 116, 124, 125, 126, 126, 127, 86, 81, 81, 81, 81, 81, - 86, 81, 81, 86, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 110, - 129, 129, 113, 118, 118, 130, 118, 118, 118, 118, 131, 131, 131, 131, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 35, 0, 83, 84, 0, 0, 26, 26, 85, 0, 86, 81, 81, 81, 81, 86, 81, + 81, 81, 87, 86, 81, 81, 81, 81, 81, 81, 86, 86, 86, 86, 86, 86, 81, 81, + 86, 81, 81, 87, 88, 81, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 98, 99, + 100, 101, 102, 103, 104, 105, 106, 104, 81, 86, 104, 97, 0, 0, 0, 0, 0, + 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, + 0, 0, 0, 0, 107, 107, 107, 104, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 108, 108, 108, 108, 108, 108, 78, 78, 109, 110, 110, 111, 112, 113, 26, + 26, 81, 81, 81, 81, 81, 81, 81, 81, 114, 115, 116, 113, 117, 0, 113, 113, + 118, 118, 119, 119, 119, 119, 119, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 120, 118, 118, 118, 118, 118, 118, 118, 118, 118, + 118, 121, 122, 123, 114, 115, 116, 124, 125, 126, 126, 127, 86, 81, 81, + 81, 81, 81, 86, 81, 81, 86, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 110, 129, 129, 113, 118, 118, 130, 118, 118, 118, 118, 131, 131, + 131, 131, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, - 118, 119, 118, 119, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, - 118, 118, 118, 118, 118, 118, 119, 113, 118, 81, 81, 81, 81, 81, 81, 81, - 108, 26, 81, 81, 81, 81, 86, 81, 120, 120, 81, 81, 26, 86, 81, 81, 86, - 118, 118, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 118, 118, - 118, 133, 133, 118, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 0, 117, 118, 134, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 119, 118, 119, 118, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 118, 119, 113, 118, 81, 81, 81, 81, + 81, 81, 81, 108, 26, 81, 81, 81, 81, 86, 81, 120, 120, 81, 81, 26, 86, + 81, 81, 86, 118, 118, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 118, 118, 118, 133, 133, 118, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 0, 117, 118, 134, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, - 118, 118, 118, 118, 118, 118, 118, 118, 118, 81, 86, 81, 81, 86, 81, 81, - 86, 86, 86, 81, 86, 86, 81, 86, 81, 81, 81, 86, 81, 86, 81, 86, 81, 86, - 81, 81, 0, 0, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 81, 86, 81, 81, + 86, 81, 81, 86, 86, 86, 81, 86, 86, 81, 86, 81, 81, 81, 86, 81, 86, 81, + 86, 81, 86, 81, 81, 0, 0, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, - 118, 118, 118, 118, 118, 118, 118, 135, 135, 135, 135, 135, 135, 135, - 135, 135, 135, 135, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 136, - 136, 136, 136, 136, 136, 136, 136, 136, 136, 107, 107, 107, 107, 107, + 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 81, - 81, 81, 81, 81, 81, 81, 86, 81, 137, 137, 26, 138, 138, 138, 137, 0, 0, - 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 81, 81, 81, 81, 137, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 137, 81, 81, 81, 137, 81, 81, 81, 81, 81, 0, - 0, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 86, 86, 86, - 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 118, 0, 118, - 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, - 81, 86, 81, 81, 86, 81, 81, 81, 86, 86, 86, 121, 122, 123, 81, 81, 81, - 86, 81, 81, 86, 86, 81, 81, 81, 81, 0, 135, 135, 135, 139, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 140, 48, - 48, 48, 48, 48, 48, 48, 140, 48, 48, 140, 48, 48, 48, 48, 48, 135, 139, - 141, 48, 139, 139, 139, 135, 135, 135, 135, 135, 135, 135, 135, 139, 139, - 139, 139, 142, 139, 139, 48, 81, 86, 81, 81, 135, 135, 135, 143, 143, - 143, 143, 143, 143, 143, 143, 48, 48, 135, 135, 83, 83, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 83, 53, 48, 48, 48, 48, 48, 48, 0, 48, - 48, 48, 48, 48, 48, 48, 0, 135, 139, 139, 0, 48, 48, 48, 48, 48, 48, 48, - 48, 0, 0, 48, 48, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 0, - 48, 0, 0, 0, 48, 48, 48, 48, 0, 0, 145, 48, 146, 139, 139, 135, 135, 135, - 135, 0, 0, 139, 139, 0, 0, 147, 147, 142, 48, 0, 0, 0, 0, 0, 0, 0, 0, - 146, 0, 0, 0, 0, 143, 143, 0, 143, 48, 48, 135, 135, 0, 0, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 48, 48, 85, 85, 148, 148, 148, 148, - 148, 148, 80, 85, 0, 0, 0, 0, 0, 135, 135, 139, 0, 48, 48, 48, 48, 48, - 48, 0, 0, 0, 0, 48, 48, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, - 48, 0, 48, 143, 0, 48, 143, 0, 48, 48, 0, 0, 145, 0, 139, 139, 139, 135, - 135, 0, 0, 0, 0, 135, 135, 0, 0, 135, 135, 142, 0, 0, 0, 135, 0, 0, 0, 0, - 0, 0, 0, 143, 143, 143, 48, 0, 143, 0, 0, 0, 0, 0, 0, 0, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 135, 135, 48, 48, 48, 135, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 135, 135, 139, 0, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 0, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, - 48, 0, 48, 48, 48, 48, 48, 0, 0, 145, 48, 139, 139, 139, 135, 135, 135, - 135, 135, 0, 135, 135, 139, 0, 139, 139, 142, 0, 0, 48, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 135, 135, 0, 0, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 83, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 135, 139, 139, 0, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 48, 48, - 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 0, 48, 48, - 48, 48, 48, 0, 0, 145, 48, 146, 135, 139, 135, 135, 135, 135, 0, 0, 139, - 147, 0, 0, 147, 147, 142, 0, 0, 0, 0, 0, 0, 0, 0, 149, 146, 0, 0, 0, 0, - 143, 143, 0, 48, 48, 48, 135, 135, 0, 0, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 80, 48, 148, 148, 148, 148, 148, 148, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 135, 48, 0, 48, 48, 48, 48, 48, 48, 0, 0, 0, 48, 48, 48, - 0, 48, 48, 140, 48, 0, 0, 0, 48, 48, 0, 48, 0, 48, 48, 0, 0, 0, 48, 48, - 0, 0, 0, 48, 48, 48, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 0, 0, 0, 0, 146, 139, 135, 139, 139, 0, 0, 0, 139, 139, 139, 0, 147, - 147, 147, 142, 0, 0, 48, 0, 0, 0, 0, 0, 0, 146, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 148, - 148, 148, 26, 26, 26, 26, 26, 26, 85, 26, 0, 0, 0, 0, 0, 0, 139, 139, - 139, 0, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 0, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 0, - 0, 0, 48, 135, 135, 135, 139, 139, 139, 139, 0, 135, 135, 150, 0, 135, - 135, 135, 142, 0, 0, 0, 0, 0, 0, 0, 151, 152, 0, 48, 48, 0, 0, 0, 0, 0, - 0, 48, 48, 135, 135, 0, 0, 144, 144, 144, 144, 144, 144, 144, 144, 144, - 144, 0, 0, 0, 0, 0, 0, 0, 0, 153, 153, 153, 153, 153, 153, 153, 80, 0, 0, - 139, 139, 0, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 0, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, - 48, 0, 0, 145, 48, 139, 154, 147, 139, 146, 139, 139, 0, 154, 147, 147, - 0, 147, 147, 135, 142, 0, 0, 0, 0, 0, 0, 0, 146, 146, 0, 0, 0, 0, 0, 0, - 0, 48, 0, 48, 48, 135, 135, 0, 0, 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 0, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 139, - 139, 0, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 0, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 0, 0, 48, 146, 139, 139, 135, 135, 135, 135, 0, 139, 139, 139, 0, - 147, 147, 147, 142, 48, 0, 0, 0, 0, 0, 0, 0, 0, 146, 0, 0, 0, 0, 0, 0, 0, - 0, 48, 48, 135, 135, 0, 0, 144, 144, 144, 144, 144, 144, 144, 144, 144, - 144, 148, 148, 148, 148, 148, 148, 0, 0, 0, 80, 48, 48, 48, 48, 48, 48, - 0, 0, 139, 139, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 81, 81, 81, 81, 81, 81, 81, 86, 81, 137, 137, 26, 138, 138, + 138, 137, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 81, 81, + 81, 81, 137, 81, 81, 81, 81, 81, 81, 81, 81, 81, 137, 81, 81, 81, 137, + 81, 81, 81, 81, 81, 0, 0, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 0, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 86, 86, 86, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 81, 86, 81, 81, 86, 81, 81, + 81, 86, 86, 86, 121, 122, 123, 81, 81, 81, 86, 81, 81, 86, 86, 81, 81, + 81, 81, 81, 135, 135, 135, 139, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 140, 48, 48, 48, 48, 48, 48, 48, 140, + 48, 48, 140, 48, 48, 48, 48, 48, 135, 139, 141, 48, 139, 139, 139, 135, + 135, 135, 135, 135, 135, 135, 135, 139, 139, 139, 139, 142, 139, 139, 48, + 81, 86, 81, 81, 135, 135, 135, 143, 143, 143, 143, 143, 143, 143, 143, + 48, 48, 135, 135, 83, 83, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 83, 53, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 135, 139, 139, 0, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 48, 48, 0, 0, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 0, 0, 0, 48, 48, 48, + 48, 0, 0, 145, 48, 146, 139, 139, 135, 135, 135, 135, 0, 0, 139, 139, 0, + 0, 147, 147, 142, 48, 0, 0, 0, 0, 0, 0, 0, 0, 146, 0, 0, 0, 0, 143, 143, + 0, 143, 48, 48, 135, 135, 0, 0, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 48, 48, 85, 85, 148, 148, 148, 148, 148, 148, 80, 85, 0, 0, 0, + 0, 0, 135, 135, 139, 0, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 48, 48, 0, 0, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 143, 0, 48, 143, 0, + 48, 48, 0, 0, 145, 0, 139, 139, 139, 135, 135, 0, 0, 0, 0, 135, 135, 0, + 0, 135, 135, 142, 0, 0, 0, 135, 0, 0, 0, 0, 0, 0, 0, 143, 143, 143, 48, + 0, 143, 0, 0, 0, 0, 0, 0, 0, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 135, 135, 48, 48, 48, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135, + 135, 139, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 0, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 0, 48, 48, 48, 48, + 48, 0, 0, 145, 48, 139, 139, 139, 135, 135, 135, 135, 135, 0, 135, 135, + 139, 0, 139, 139, 142, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 48, 48, 135, 135, 0, 0, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 83, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135, 139, + 139, 0, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 48, 48, 0, 0, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 0, 48, 48, 48, 48, 48, 0, + 0, 145, 48, 146, 135, 139, 135, 135, 135, 135, 0, 0, 139, 147, 0, 0, 147, + 147, 142, 0, 0, 0, 0, 0, 0, 0, 0, 149, 146, 0, 0, 0, 0, 143, 143, 0, 48, + 48, 48, 135, 135, 0, 0, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 80, 48, 148, 148, 148, 148, 148, 148, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135, + 48, 0, 48, 48, 48, 48, 48, 48, 0, 0, 0, 48, 48, 48, 0, 48, 48, 140, 48, + 0, 0, 0, 48, 48, 0, 48, 0, 48, 48, 0, 0, 0, 48, 48, 0, 0, 0, 48, 48, 48, + 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 146, + 139, 135, 139, 139, 0, 0, 0, 139, 139, 139, 0, 147, 147, 147, 142, 0, 0, + 48, 0, 0, 0, 0, 0, 0, 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 148, 148, 148, 26, 26, 26, + 26, 26, 26, 85, 26, 0, 0, 0, 0, 0, 135, 139, 139, 139, 0, 48, 48, 48, 48, + 48, 48, 48, 48, 0, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 0, 48, 0, 0, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, - 155, 0, 0, 0, 0, 146, 139, 139, 135, 135, 135, 0, 135, 0, 139, 139, 147, - 139, 147, 147, 147, 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 139, 139, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 135, 48, 156, 135, 135, 135, 135, 157, - 157, 142, 0, 0, 0, 0, 85, 48, 48, 48, 48, 48, 48, 53, 135, 158, 158, 158, - 158, 135, 135, 135, 83, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, - 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 0, 48, 0, 0, 48, 48, - 0, 48, 0, 0, 48, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, - 48, 48, 0, 48, 48, 48, 0, 48, 0, 48, 0, 0, 48, 48, 0, 48, 48, 48, 48, - 135, 48, 156, 135, 135, 135, 135, 159, 159, 0, 135, 135, 48, 0, 0, 48, - 48, 48, 48, 48, 0, 53, 0, 160, 160, 160, 160, 135, 135, 0, 0, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, 0, 0, 156, 156, 48, 48, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 48, 80, 80, 80, 83, 83, 83, 83, 83, 83, 83, 83, 161, 83, - 83, 83, 83, 83, 83, 80, 83, 80, 80, 80, 86, 86, 80, 80, 80, 80, 80, 80, - 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 148, 148, 148, 148, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 48, 135, 135, + 135, 139, 139, 139, 139, 0, 135, 135, 150, 0, 135, 135, 135, 142, 0, 0, + 0, 0, 0, 0, 0, 151, 152, 0, 48, 48, 0, 0, 0, 0, 0, 0, 48, 48, 135, 135, + 0, 0, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 0, 0, 0, 0, 0, 0, + 0, 0, 153, 153, 153, 153, 153, 153, 153, 80, 0, 135, 139, 139, 0, 48, 48, + 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 0, 0, 145, 48, + 139, 154, 147, 139, 146, 139, 139, 0, 154, 147, 147, 0, 147, 147, 135, + 142, 0, 0, 0, 0, 0, 0, 0, 146, 146, 0, 0, 0, 0, 0, 0, 0, 48, 0, 48, 48, + 135, 135, 0, 0, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 0, 48, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135, 139, 139, 0, 48, 48, + 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 48, + 146, 139, 139, 135, 135, 135, 135, 0, 139, 139, 139, 0, 147, 147, 147, + 142, 48, 0, 0, 0, 0, 0, 0, 0, 0, 146, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, + 135, 135, 0, 0, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 148, + 148, 148, 148, 148, 148, 0, 0, 0, 80, 48, 48, 48, 48, 48, 48, 0, 0, 139, + 139, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 0, 48, 0, 0, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 155, 0, 0, 0, + 0, 146, 139, 139, 135, 135, 135, 0, 135, 0, 139, 139, 147, 139, 147, 147, + 147, 146, 0, 0, 0, 0, 0, 0, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 0, 0, 139, 139, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 135, 48, 156, 135, 135, 135, 135, + 157, 157, 142, 0, 0, 0, 0, 85, 48, 48, 48, 48, 48, 48, 53, 135, 158, 158, + 158, 158, 135, 135, 135, 83, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 0, 48, 0, 0, + 48, 48, 0, 48, 0, 0, 48, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 0, 48, 48, 48, + 48, 48, 48, 48, 0, 48, 48, 48, 0, 48, 0, 48, 0, 0, 48, 48, 0, 48, 48, 48, + 48, 135, 48, 156, 135, 135, 135, 135, 159, 159, 0, 135, 135, 48, 0, 0, + 48, 48, 48, 48, 48, 0, 53, 0, 160, 160, 160, 160, 135, 135, 0, 0, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 0, 0, 156, 156, 48, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 48, 80, 80, 80, 83, 83, 83, 83, 83, 83, 83, 83, 161, + 83, 83, 83, 83, 83, 83, 80, 83, 80, 80, 80, 86, 86, 80, 80, 80, 80, 80, + 80, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 80, 86, 80, 86, 80, 162, 163, 164, 163, 164, 139, 139, 48, 48, 48, 143, 48, 48, 48, 48, 0, 48, 48, 48, 48, 143, 48, 48, 48, 48, 143, 48, 48, 48, 48, 143, 48, 48, 48, 48, 143, 48, 48, @@ -1513,10 +1632,10 @@ static unsigned short index2[] = { 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 83, 83, 83, 173, 173, 173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, - 48, 48, 48, 135, 135, 142, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 135, 135, + 48, 48, 48, 83, 83, 83, 173, 173, 173, 48, 48, 48, 48, 48, 48, 48, 48, 0, + 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, + 48, 48, 48, 48, 135, 135, 142, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 135, 135, 142, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 135, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, @@ -1544,7 +1663,7 @@ static unsigned short index2[] = { 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 0, 0, 0, 135, 135, 135, 139, 139, 139, 139, 135, 135, 139, 139, + 48, 48, 48, 48, 0, 135, 135, 135, 139, 139, 139, 139, 135, 135, 139, 139, 139, 0, 0, 0, 0, 139, 139, 135, 139, 139, 139, 139, 139, 139, 87, 81, 86, 0, 0, 0, 0, 26, 0, 0, 0, 138, 138, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, @@ -1567,295 +1686,297 @@ static unsigned short index2[] = { 81, 81, 81, 81, 81, 81, 0, 0, 86, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 0, 0, 0, 0, 0, 0, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 0, 0, 0, 0, 0, 0, 83, 83, 83, 83, 83, 83, 83, 53, 83, 83, 83, 83, - 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 83, 83, 0, 0, 81, 81, 81, 81, 81, 86, 86, 86, 86, 86, 86, 81, 81, 86, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135, 135, 135, 135, 139, 48, 140, 48, - 140, 48, 140, 48, 140, 48, 140, 48, 48, 48, 140, 48, 48, 48, 48, 48, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135, 135, 135, 135, + 139, 48, 140, 48, 140, 48, 140, 48, 140, 48, 140, 48, 48, 48, 140, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 145, 146, 135, + 135, 135, 135, 135, 147, 135, 147, 139, 139, 147, 147, 135, 147, 175, 48, + 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 83, 83, 83, 83, 83, 83, 83, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 81, 86, 81, 81, 81, 81, 81, 81, 81, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 0, 0, 0, 135, 135, 139, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 139, 135, 135, 135, 135, 139, 139, 135, 135, 175, 142, 135, + 135, 48, 48, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 145, 146, 135, 135, 135, 135, 135, - 147, 135, 147, 139, 139, 147, 147, 135, 147, 175, 48, 48, 48, 48, 48, 48, - 48, 0, 0, 0, 0, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 83, 83, - 83, 83, 83, 83, 83, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 81, 86, 81, - 81, 81, 81, 81, 81, 81, 80, 80, 80, 80, 80, 80, 80, 80, 80, 0, 0, 0, 135, - 135, 139, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 139, 135, 135, - 135, 135, 139, 139, 135, 135, 175, 142, 139, 139, 48, 48, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 145, - 139, 135, 135, 139, 139, 139, 135, 139, 135, 135, 135, 175, 175, 0, 0, 0, - 0, 0, 0, 0, 0, 83, 83, 83, 83, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 145, 139, 135, 135, 139, 139, 139, 135, 139, 135, + 135, 135, 175, 175, 0, 0, 0, 0, 0, 0, 0, 0, 83, 83, 83, 83, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 139, 139, 139, 139, 139, 139, 139, 139, - 135, 135, 135, 135, 135, 135, 135, 135, 139, 139, 135, 145, 0, 0, 0, 83, - 83, 83, 83, 83, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 0, 0, - 0, 48, 48, 48, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 139, 139, + 139, 139, 139, 139, 139, 139, 135, 135, 135, 135, 135, 135, 135, 135, + 139, 139, 135, 145, 0, 0, 0, 83, 83, 83, 83, 83, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 0, 0, 0, 48, 48, 48, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 53, 53, 53, 53, 53, 53, 83, 83, + 53, 53, 53, 53, 53, 53, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 83, 83, 83, 83, 83, - 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 81, 81, 81, 83, 176, 86, 86, 86, 86, 86, - 81, 81, 86, 86, 86, 86, 81, 139, 176, 176, 176, 176, 176, 176, 176, 48, - 48, 48, 48, 86, 48, 48, 48, 48, 139, 139, 81, 48, 48, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 0, 0, 83, 83, 83, 83, 83, 83, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 81, 81, 81, + 83, 176, 86, 86, 86, 86, 86, 81, 81, 86, 86, 86, 86, 81, 139, 176, 176, + 176, 176, 176, 176, 176, 48, 48, 48, 48, 86, 48, 48, 48, 48, 139, 139, + 81, 48, 48, 0, 81, 81, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 51, 51, 51, 53, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 53, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 53, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 51, 51, 51, 53, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 53, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 53, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 51, 47, 47, 47, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 51, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 51, 51, 51, 51, 51, + 47, 47, 47, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 81, 81, 86, 81, - 81, 81, 81, 81, 81, 81, 86, 81, 81, 177, 178, 86, 179, 81, 81, 81, 81, + 51, 51, 51, 51, 81, 81, 86, 81, 81, 81, 81, 81, 81, 81, 86, 81, 81, 177, + 178, 86, 179, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 86, - 81, 86, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, - 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, - 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, - 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, - 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, - 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, - 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, - 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, - 38, 43, 38, 43, 38, 43, 38, 43, 43, 43, 43, 43, 35, 181, 47, 47, 44, 47, - 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, - 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, - 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, - 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, - 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, - 44, 47, 44, 47, 44, 47, 43, 43, 43, 43, 43, 43, 43, 43, 38, 38, 38, 38, - 38, 38, 38, 38, 43, 43, 43, 43, 43, 43, 0, 0, 38, 38, 38, 38, 38, 38, 0, - 0, 43, 43, 43, 43, 43, 43, 43, 43, 38, 38, 38, 38, 38, 38, 38, 38, 43, + 81, 81, 81, 81, 0, 0, 0, 0, 0, 0, 180, 86, 81, 86, 38, 43, 38, 43, 38, + 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, + 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, + 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, + 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, + 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, + 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, + 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, + 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, + 43, 43, 43, 43, 43, 35, 181, 47, 47, 44, 47, 38, 43, 38, 43, 38, 43, 38, + 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, + 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, + 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, + 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, + 43, 38, 43, 38, 43, 38, 43, 38, 43, 38, 43, 44, 47, 44, 47, 44, 47, 43, 43, 43, 43, 43, 43, 43, 43, 38, 38, 38, 38, 38, 38, 38, 38, 43, 43, 43, 43, 43, 43, 0, 0, 38, 38, 38, 38, 38, 38, 0, 0, 43, 43, 43, 43, 43, 43, - 43, 43, 0, 38, 0, 38, 0, 38, 0, 38, 43, 43, 43, 43, 43, 43, 43, 43, 38, - 38, 38, 38, 38, 38, 38, 38, 43, 182, 43, 182, 43, 182, 43, 182, 43, 182, - 43, 182, 43, 182, 0, 0, 43, 43, 43, 43, 43, 43, 43, 43, 183, 183, 183, - 183, 183, 183, 183, 183, 43, 43, 43, 43, 43, 43, 43, 43, 183, 183, 183, - 183, 183, 183, 183, 183, 43, 43, 43, 43, 43, 43, 43, 43, 183, 183, 183, - 183, 183, 183, 183, 183, 43, 43, 43, 43, 43, 0, 43, 43, 38, 38, 38, 184, - 183, 58, 182, 58, 58, 76, 43, 43, 43, 0, 43, 43, 38, 184, 38, 184, 183, - 76, 76, 76, 43, 43, 43, 182, 0, 0, 43, 43, 38, 38, 38, 184, 0, 76, 76, - 76, 43, 43, 43, 182, 43, 43, 43, 43, 38, 38, 38, 184, 38, 76, 185, 185, - 0, 0, 43, 43, 43, 0, 43, 43, 38, 184, 38, 184, 183, 185, 58, 0, 186, 186, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 174, 174, 174, 188, 189, - 190, 191, 84, 190, 190, 190, 22, 192, 193, 194, 195, 196, 193, 194, 195, - 196, 22, 22, 22, 138, 197, 197, 197, 22, 198, 199, 200, 201, 202, 203, - 204, 21, 205, 110, 205, 206, 207, 22, 192, 192, 138, 28, 36, 22, 192, - 138, 197, 208, 208, 138, 138, 138, 209, 163, 164, 192, 192, 192, 138, - 138, 138, 138, 138, 138, 138, 138, 78, 138, 208, 138, 138, 192, 138, 138, - 138, 138, 138, 138, 138, 187, 174, 174, 174, 174, 174, 0, 210, 211, 212, - 213, 174, 174, 174, 174, 174, 174, 214, 51, 0, 0, 34, 214, 214, 214, 214, - 214, 215, 215, 216, 217, 218, 219, 214, 34, 34, 34, 34, 214, 214, 214, - 214, 214, 215, 215, 216, 217, 218, 0, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 0, 0, 0, 85, 85, 85, 85, 85, 85, 85, 85, 220, 221, 85, - 85, 23, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 81, 176, 176, - 81, 81, 81, 81, 176, 176, 176, 81, 81, 82, 82, 82, 82, 81, 82, 82, 82, - 176, 176, 81, 86, 81, 176, 176, 86, 86, 86, 86, 81, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 222, 222, 49, 223, 26, 223, 222, 49, 26, 223, 35, - 49, 49, 49, 35, 35, 49, 49, 49, 46, 26, 49, 223, 26, 78, 49, 49, 49, 49, - 49, 26, 26, 222, 223, 223, 26, 49, 26, 224, 26, 49, 26, 184, 224, 49, 49, - 225, 35, 49, 49, 44, 49, 35, 156, 156, 156, 156, 35, 26, 222, 35, 35, 49, - 49, 226, 78, 78, 78, 78, 49, 35, 35, 35, 35, 26, 78, 26, 26, 47, 80, 227, - 227, 227, 37, 37, 227, 227, 227, 227, 227, 227, 37, 37, 37, 37, 227, 228, - 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 229, 229, 229, - 229, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 229, 229, 229, - 229, 229, 229, 173, 173, 173, 44, 47, 173, 173, 173, 173, 37, 0, 0, 0, 0, - 0, 0, 40, 40, 40, 40, 40, 30, 30, 30, 30, 30, 230, 230, 26, 26, 26, 26, - 78, 26, 26, 78, 26, 26, 78, 26, 26, 26, 26, 26, 26, 26, 230, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 30, 30, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 231, 230, 230, 26, 26, 40, 26, 40, + 43, 43, 38, 38, 38, 38, 38, 38, 38, 38, 43, 43, 43, 43, 43, 43, 43, 43, + 38, 38, 38, 38, 38, 38, 38, 38, 43, 43, 43, 43, 43, 43, 0, 0, 38, 38, 38, + 38, 38, 38, 0, 0, 43, 43, 43, 43, 43, 43, 43, 43, 0, 38, 0, 38, 0, 38, 0, + 38, 43, 43, 43, 43, 43, 43, 43, 43, 38, 38, 38, 38, 38, 38, 38, 38, 43, + 182, 43, 182, 43, 182, 43, 182, 43, 182, 43, 182, 43, 182, 0, 0, 43, 43, + 43, 43, 43, 43, 43, 43, 183, 183, 183, 183, 183, 183, 183, 183, 43, 43, + 43, 43, 43, 43, 43, 43, 183, 183, 183, 183, 183, 183, 183, 183, 43, 43, + 43, 43, 43, 43, 43, 43, 183, 183, 183, 183, 183, 183, 183, 183, 43, 43, + 43, 43, 43, 0, 43, 43, 38, 38, 38, 184, 183, 58, 182, 58, 58, 76, 43, 43, + 43, 0, 43, 43, 38, 184, 38, 184, 183, 76, 76, 76, 43, 43, 43, 182, 0, 0, + 43, 43, 38, 38, 38, 184, 0, 76, 76, 76, 43, 43, 43, 182, 43, 43, 43, 43, + 38, 38, 38, 184, 38, 76, 185, 185, 0, 0, 43, 43, 43, 0, 43, 43, 38, 184, + 38, 184, 183, 185, 58, 0, 186, 186, 187, 187, 187, 187, 187, 187, 187, + 187, 187, 174, 174, 174, 188, 189, 190, 191, 84, 190, 190, 190, 22, 192, + 193, 194, 195, 196, 193, 194, 195, 196, 22, 22, 22, 138, 197, 197, 197, + 22, 198, 199, 200, 201, 202, 203, 204, 21, 205, 110, 205, 206, 207, 22, + 192, 192, 138, 28, 36, 22, 192, 138, 197, 208, 208, 138, 138, 138, 209, + 163, 164, 192, 192, 192, 138, 138, 138, 138, 138, 138, 138, 138, 78, 138, + 208, 138, 138, 192, 138, 138, 138, 138, 138, 138, 138, 187, 174, 174, + 174, 174, 174, 0, 210, 211, 212, 213, 174, 174, 174, 174, 174, 174, 214, + 51, 0, 0, 34, 214, 214, 214, 214, 214, 215, 215, 216, 217, 218, 219, 214, + 34, 34, 34, 34, 214, 214, 214, 214, 214, 215, 215, 216, 217, 218, 0, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 0, 0, 0, 85, 85, 85, 85, + 85, 85, 85, 85, 220, 221, 85, 85, 23, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 81, 81, 176, 176, 81, 81, 81, 81, 176, 176, 176, 81, 81, 82, + 82, 82, 82, 81, 82, 82, 82, 176, 176, 81, 86, 81, 176, 176, 86, 86, 86, + 86, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 222, 222, 49, 223, + 26, 223, 222, 49, 26, 223, 35, 49, 49, 49, 35, 35, 49, 49, 49, 46, 26, + 49, 223, 26, 78, 49, 49, 49, 49, 49, 26, 26, 222, 223, 223, 26, 49, 26, + 224, 26, 49, 26, 184, 224, 49, 49, 225, 35, 49, 49, 44, 49, 35, 156, 156, + 156, 156, 35, 26, 222, 35, 35, 49, 49, 226, 78, 78, 78, 78, 49, 35, 35, + 35, 35, 26, 78, 26, 26, 47, 80, 227, 227, 227, 37, 37, 227, 227, 227, + 227, 227, 227, 37, 37, 37, 37, 227, 228, 228, 228, 228, 228, 228, 228, + 228, 228, 228, 228, 228, 229, 229, 229, 229, 228, 228, 228, 228, 228, + 228, 228, 228, 228, 228, 229, 229, 229, 229, 229, 229, 173, 173, 173, 44, + 47, 173, 173, 173, 173, 37, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 30, 30, + 30, 30, 30, 230, 230, 26, 26, 26, 26, 78, 26, 26, 78, 26, 26, 78, 26, 26, + 26, 26, 26, 26, 26, 230, 26, 26, 26, 26, 26, 26, 26, 26, 26, 30, 30, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 30, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 40, 232, 233, 233, 234, 78, 78, 40, 233, 234, - 232, 233, 234, 232, 78, 40, 78, 233, 235, 236, 78, 233, 232, 78, 78, 78, - 233, 232, 232, 233, 40, 233, 233, 232, 232, 40, 234, 40, 234, 40, 40, 40, - 40, 233, 237, 226, 233, 226, 226, 232, 232, 232, 40, 40, 40, 40, 78, 232, - 78, 232, 233, 233, 232, 232, 232, 234, 232, 232, 234, 232, 232, 234, 233, - 234, 232, 232, 233, 78, 78, 78, 78, 78, 233, 232, 232, 232, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 232, 238, 40, 234, 78, 233, 233, 233, 233, 232, - 232, 233, 233, 78, 230, 238, 238, 234, 234, 232, 232, 234, 234, 232, 232, - 234, 234, 232, 232, 232, 232, 232, 232, 234, 234, 233, 233, 234, 234, - 233, 233, 234, 234, 232, 232, 232, 78, 78, 232, 232, 232, 232, 78, 78, - 40, 78, 78, 232, 40, 78, 78, 78, 78, 78, 78, 78, 78, 232, 232, 78, 40, - 232, 232, 232, 232, 232, 232, 234, 234, 234, 234, 232, 232, 232, 232, - 232, 232, 232, 232, 232, 78, 78, 78, 78, 78, 232, 233, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 232, 232, 232, 232, 232, 78, 78, 232, 232, 78, 78, - 78, 78, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 234, 234, 234, - 234, 232, 232, 232, 232, 232, 232, 234, 234, 234, 234, 78, 78, 232, 232, - 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 26, - 26, 26, 26, 26, 26, 26, 26, 163, 164, 163, 164, 26, 26, 26, 26, 26, 26, - 30, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 232, 232, 26, 26, - 26, 26, 26, 26, 26, 239, 240, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 231, 230, 230, 26, 26, 40, 26, 40, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 30, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 40, 232, + 233, 233, 234, 78, 78, 40, 233, 234, 232, 233, 234, 232, 78, 40, 78, 233, + 235, 236, 78, 233, 232, 78, 78, 78, 233, 232, 232, 233, 40, 233, 233, + 232, 232, 40, 234, 40, 234, 40, 40, 40, 40, 233, 237, 226, 233, 226, 226, + 232, 232, 232, 40, 40, 40, 40, 78, 232, 78, 232, 233, 233, 232, 232, 232, + 234, 232, 232, 234, 232, 232, 234, 233, 234, 232, 232, 233, 78, 78, 78, + 78, 78, 233, 232, 232, 232, 78, 78, 78, 78, 78, 78, 78, 78, 78, 232, 238, + 40, 234, 78, 233, 233, 233, 233, 232, 232, 233, 233, 78, 230, 238, 238, + 234, 234, 232, 232, 234, 234, 232, 232, 234, 234, 232, 232, 232, 232, + 232, 232, 234, 234, 233, 233, 234, 234, 233, 233, 234, 234, 232, 232, + 232, 78, 78, 232, 232, 232, 232, 78, 78, 40, 78, 78, 232, 40, 78, 78, 78, + 78, 78, 78, 78, 78, 232, 232, 78, 40, 232, 232, 232, 232, 232, 232, 234, + 234, 234, 234, 232, 232, 232, 232, 232, 232, 232, 232, 232, 78, 78, 78, + 78, 78, 232, 233, 78, 78, 78, 78, 78, 78, 78, 78, 78, 232, 232, 232, 232, + 232, 78, 78, 232, 232, 78, 78, 78, 78, 232, 232, 232, 232, 232, 232, 232, + 232, 232, 232, 234, 234, 234, 234, 232, 232, 232, 232, 232, 232, 234, + 234, 234, 234, 78, 78, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, + 232, 232, 232, 232, 232, 232, 26, 26, 26, 26, 26, 26, 26, 26, 163, 164, + 163, 164, 26, 26, 26, 26, 26, 26, 30, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 232, 232, 26, 26, 26, 26, 26, 26, 26, 239, 240, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 26, 78, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 80, 26, 26, 26, 26, 26, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 80, 80, 80, 80, 80, 80, 26, 78, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 80, 26, 26, 26, + 26, 26, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, + 78, 78, 78, 78, 78, 78, 78, 78, 78, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 78, 78, 78, 78, 78, 78, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 78, 78, 78, 78, 78, + 78, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 37, 37, 37, 37, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 227, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 227, 242, 242, 242, 242, 242, 242, 242, 242, 242, + 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 26, 26, 26, 26, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 26, 26, 26, 26, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 26, 26, 30, 30, 30, 30, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 30, 30, 26, 30, 30, 30, 30, 30, 30, 30, 26, 26, 26, 26, 26, 26, 26, 26, - 30, 30, 26, 26, 30, 40, 26, 26, 26, 26, 30, 30, 26, 26, 30, 40, 26, 26, - 26, 26, 30, 30, 30, 26, 26, 30, 26, 26, 30, 30, 30, 30, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 30, 30, 30, 30, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 30, 26, 26, 26, 26, 26, 26, 26, 26, 78, 78, - 78, 78, 78, 78, 78, 78, 26, 26, 26, 26, 26, 30, 30, 26, 26, 30, 26, 26, - 26, 26, 30, 30, 26, 26, 26, 26, 30, 30, 26, 26, 26, 26, 26, 26, 30, 26, - 30, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 30, 26, - 30, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 30, 30, 26, 30, 30, 30, - 26, 30, 30, 30, 30, 26, 30, 30, 26, 40, 26, 26, 26, 26, 26, 26, 26, 26, + 30, 30, 30, 30, 30, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 26, 26, 30, + 30, 30, 30, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 30, 30, 26, 30, 30, + 30, 30, 30, 30, 30, 26, 26, 26, 26, 26, 26, 26, 26, 30, 30, 26, 26, 30, + 40, 26, 26, 26, 26, 30, 30, 26, 26, 30, 40, 26, 26, 26, 26, 30, 30, 30, + 26, 26, 30, 26, 26, 30, 30, 30, 30, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 30, 30, 30, 30, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 30, 26, 26, 26, 26, 26, 26, 26, 26, 78, 78, 78, 78, 78, 78, 78, + 78, 26, 26, 26, 26, 26, 30, 30, 26, 26, 30, 26, 26, 26, 26, 30, 30, 26, + 26, 26, 26, 30, 30, 26, 26, 26, 26, 26, 26, 30, 26, 30, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 30, 26, 30, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 30, 30, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 80, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 30, 30, - 26, 26, 26, 26, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 26, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 26, 30, - 26, 26, 26, 26, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 0, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 30, 30, 26, 30, 30, 30, 26, 30, 30, 30, 30, + 26, 30, 30, 26, 40, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 30, 30, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 80, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 30, 30, 26, 26, 26, 26, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 26, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 26, 30, 26, 26, 26, 26, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 30, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 30, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 30, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 163, 164, 163, 164, 163, 164, 163, 164, 163, 164, - 163, 164, 163, 164, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, + 26, 26, 30, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 163, 164, 163, 164, 163, 164, 163, 164, 163, 164, 163, 164, 163, 164, + 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, - 153, 153, 153, 153, 153, 153, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 153, 153, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 232, 78, 78, - 232, 232, 163, 164, 78, 232, 232, 78, 232, 232, 232, 78, 78, 78, 78, 78, - 232, 232, 232, 232, 78, 78, 78, 78, 78, 232, 232, 232, 78, 78, 78, 232, - 232, 232, 232, 9, 10, 9, 10, 9, 10, 9, 10, 163, 164, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 80, 80, 80, 80, 80, 80, 80, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 232, 78, 78, 232, 232, 163, 164, + 78, 232, 232, 78, 232, 232, 232, 78, 78, 78, 78, 78, 232, 232, 232, 232, + 78, 78, 78, 78, 78, 232, 232, 232, 78, 78, 78, 232, 232, 232, 232, 9, 10, + 9, 10, 9, 10, 9, 10, 163, 164, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, + 78, 78, 78, 78, 78, 78, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 78, 78, 78, 78, 78, + 80, 80, 80, 80, 80, 80, 80, 80, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, - 163, 164, 9, 10, 163, 164, 163, 164, 163, 164, 163, 164, 163, 164, 163, - 164, 163, 164, 163, 164, 163, 164, 78, 78, 232, 232, 232, 232, 232, 232, + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 163, 164, 9, 10, 163, + 164, 163, 164, 163, 164, 163, 164, 163, 164, 163, 164, 163, 164, 163, + 164, 163, 164, 78, 78, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, + 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 78, 78, 78, 78, + 78, 78, 78, 78, 232, 78, 78, 78, 78, 78, 78, 78, 232, 232, 232, 232, 232, + 232, 78, 78, 78, 232, 78, 78, 78, 78, 232, 232, 232, 232, 232, 78, 232, + 232, 78, 78, 163, 164, 163, 164, 232, 78, 78, 78, 78, 232, 78, 232, 232, + 232, 78, 78, 232, 232, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 232, 232, + 232, 232, 232, 232, 78, 78, 163, 164, 78, 78, 78, 78, 78, 78, 78, 78, 78, + 78, 78, 78, 232, 232, 226, 232, 232, 232, 232, 232, 232, 232, 232, 232, + 232, 232, 232, 232, 232, 232, 232, 78, 232, 232, 232, 232, 78, 78, 232, + 78, 232, 78, 78, 232, 78, 232, 232, 232, 232, 78, 78, 78, 78, 78, 232, + 232, 78, 78, 78, 78, 78, 78, 232, 232, 232, 78, 78, 78, 78, 78, 78, 78, + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 232, + 232, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 232, 232, 78, 78, 78, + 78, 232, 232, 232, 232, 78, 232, 232, 78, 78, 232, 226, 216, 216, 78, 78, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, - 232, 78, 78, 78, 78, 78, 78, 78, 78, 232, 78, 78, 78, 78, 78, 78, 78, - 232, 232, 232, 232, 232, 232, 78, 78, 78, 232, 78, 78, 78, 78, 232, 232, - 232, 232, 232, 78, 232, 232, 78, 78, 163, 164, 163, 164, 232, 78, 78, 78, - 78, 232, 78, 232, 232, 232, 78, 78, 232, 232, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 232, 232, 232, 232, 232, 232, 78, 78, 163, 164, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, 78, 232, 232, 226, 232, 232, 232, 232, - 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 78, 232, 232, - 232, 232, 78, 78, 232, 78, 232, 78, 78, 232, 78, 232, 232, 232, 232, 78, - 78, 78, 78, 78, 232, 232, 78, 78, 78, 78, 78, 78, 232, 232, 232, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 232, 232, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, - 232, 232, 78, 78, 78, 78, 232, 232, 232, 232, 78, 232, 232, 78, 78, 232, - 226, 216, 216, 78, 78, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, - 232, 232, 232, 232, 232, 78, 78, 232, 232, 232, 232, 232, 232, 232, 232, - 78, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, + 232, 78, 78, 232, 232, 232, 232, 232, 232, 232, 232, 78, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, - 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 78, 78, 78, - 78, 78, 243, 78, 232, 78, 78, 78, 232, 232, 232, 232, 232, 78, 78, 78, - 78, 78, 232, 232, 232, 78, 78, 78, 78, 232, 78, 78, 78, 232, 232, 232, - 232, 232, 78, 232, 78, 78, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, + 232, 232, 232, 232, 232, 232, 232, 232, 232, 78, 78, 78, 78, 78, 243, 78, + 232, 78, 78, 78, 232, 232, 232, 232, 232, 78, 78, 78, 78, 78, 232, 232, + 232, 78, 78, 78, 78, 232, 78, 78, 78, 232, 232, 232, 232, 232, 78, 232, + 78, 78, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 78, 78, 78, 78, + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 26, + 26, 78, 78, 78, 78, 78, 78, 26, 26, 26, 26, 26, 26, 26, 26, 30, 30, 30, + 30, 30, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 26, 26, 78, 78, 78, 78, 78, 78, 0, 0, 0, 26, 26, 26, 26, - 26, 30, 30, 30, 30, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 26, 26, 26, 26, 26, 26, 26, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 0, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 0, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 44, 47, 44, 44, 44, 47, 47, 44, - 47, 44, 47, 44, 47, 44, 44, 44, 44, 47, 44, 47, 47, 44, 47, 47, 47, 47, - 47, 47, 51, 51, 44, 44, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, - 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, - 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, - 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, - 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, - 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 47, 26, - 26, 26, 26, 26, 26, 44, 47, 44, 47, 81, 81, 81, 44, 47, 0, 0, 0, 0, 0, - 138, 138, 138, 138, 153, 138, 138, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 44, 47, 44, + 44, 44, 47, 47, 44, 47, 44, 47, 44, 47, 44, 44, 44, 44, 47, 44, 47, 47, + 44, 47, 47, 47, 47, 47, 47, 51, 51, 44, 44, 44, 47, 44, 47, 44, 47, 44, + 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, + 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, + 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, + 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, + 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, + 47, 44, 47, 47, 26, 26, 26, 26, 26, 26, 44, 47, 44, 47, 81, 81, 81, 44, + 47, 0, 0, 0, 0, 0, 138, 138, 138, 138, 153, 138, 138, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 0, 0, 0, 0, 0, 47, 0, - 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 0, 0, + 0, 0, 0, 47, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 51, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 142, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, - 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, - 48, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, + 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 51, 83, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 142, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, - 48, 48, 48, 0, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, + 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, + 0, 48, 48, 48, 48, 48, 48, 48, 0, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, - 138, 138, 28, 36, 28, 36, 138, 138, 138, 28, 36, 138, 28, 36, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 84, 138, 138, 84, 138, 28, 36, 138, - 138, 28, 36, 163, 164, 163, 164, 163, 164, 163, 164, 138, 138, 138, 138, - 138, 52, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 84, 84, 0, 0, + 81, 81, 81, 81, 138, 138, 28, 36, 28, 36, 138, 138, 138, 28, 36, 138, 28, + 36, 138, 138, 138, 138, 138, 138, 138, 138, 138, 84, 138, 138, 84, 138, + 28, 36, 138, 138, 28, 36, 163, 164, 163, 164, 163, 164, 163, 164, 138, + 138, 138, 138, 138, 52, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 84, 84, 138, 138, 138, 138, 84, 138, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 244, 244, 244, 244, + 0, 0, 0, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, + 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 0, 244, + 244, 244, 244, 245, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, - 244, 244, 244, 244, 244, 244, 244, 244, 0, 244, 244, 244, 244, 245, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, - 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, - 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 245, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 245, 245, 245, 245, 245, 245, 245, 245, 245, + 244, 244, 244, 245, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, @@ -1870,63 +1991,64 @@ static unsigned short index2[] = { 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, - 245, 245, 245, 245, 245, 245, 245, 245, 245, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 244, 244, 244, 244, - 244, 244, 244, 244, 244, 244, 244, 244, 0, 0, 0, 0, 246, 247, 247, 247, - 244, 248, 170, 249, 250, 251, 250, 251, 250, 251, 250, 251, 250, 251, - 244, 244, 250, 251, 250, 251, 250, 251, 250, 251, 252, 253, 254, 254, - 244, 249, 249, 249, 249, 249, 249, 249, 249, 249, 255, 256, 257, 258, - 259, 259, 252, 248, 248, 248, 248, 248, 245, 244, 260, 260, 260, 248, - 170, 247, 244, 26, 0, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 261, 170, 261, 170, 261, 170, 261, 170, 261, 170, 261, 170, 261, - 170, 261, 170, 261, 170, 261, 170, 261, 170, 261, 170, 170, 261, 170, - 261, 170, 261, 170, 170, 170, 170, 170, 170, 261, 261, 170, 261, 261, - 170, 261, 261, 170, 261, 261, 170, 261, 261, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 261, 170, 170, 0, 0, 262, 262, 263, 263, 248, 264, 265, - 252, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 261, 170, + 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, + 245, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 0, + 0, 0, 0, 246, 247, 247, 247, 244, 248, 170, 249, 250, 251, 250, 251, 250, + 251, 250, 251, 250, 251, 244, 244, 250, 251, 250, 251, 250, 251, 250, + 251, 252, 253, 254, 254, 244, 249, 249, 249, 249, 249, 249, 249, 249, + 249, 255, 256, 257, 258, 259, 259, 252, 248, 248, 248, 248, 248, 245, + 244, 260, 260, 260, 248, 170, 247, 244, 26, 0, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 261, 170, 261, 170, 261, 170, 261, 170, 261, 170, 261, 170, 261, 170, 261, 170, 261, 170, 261, 170, 261, 170, - 261, 170, 261, 170, 261, 170, 261, 170, 170, 261, 170, 261, 170, 261, - 170, 170, 170, 170, 170, 170, 261, 261, 170, 261, 261, 170, 261, 261, - 170, 261, 261, 170, 261, 261, 170, 170, 170, 170, 170, 170, 170, 170, + 261, 170, 170, 261, 170, 261, 170, 261, 170, 170, 170, 170, 170, 170, + 261, 261, 170, 261, 261, 170, 261, 261, 170, 261, 261, 170, 261, 261, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, - 261, 170, 170, 261, 261, 261, 261, 247, 248, 248, 264, 265, 0, 0, 0, 0, - 0, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, 261, 170, 170, 0, 0, 262, 262, + 263, 263, 248, 264, 265, 252, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 261, 170, 261, 170, 261, 170, 261, 170, 261, 170, 261, + 170, 261, 170, 261, 170, 261, 170, 261, 170, 261, 170, 261, 170, 170, + 261, 170, 261, 170, 261, 170, 170, 170, 170, 170, 170, 261, 261, 170, + 261, 261, 170, 261, 261, 170, 261, 261, 170, 261, 261, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 0, 0, 0, + 170, 170, 170, 170, 170, 261, 170, 170, 261, 261, 261, 261, 247, 248, + 248, 264, 265, 0, 0, 0, 0, 0, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 0, 0, 0, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, - 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, 0, 266, 266, 267, 267, - 267, 267, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 170, 170, + 265, 265, 0, 266, 266, 267, 267, 267, 267, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 0, 0, 0, 0, 0, + 170, 170, 170, 0, 0, 0, 0, 0, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, - 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, - 244, 244, 244, 244, 244, 244, 244, 244, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 268, 245, 245, 0, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 245, 245, 0, 267, 267, 267, + 267, 267, 267, 267, 267, 267, 267, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 268, 269, 269, 269, 269, 269, 269, 269, 269, 245, 270, 270, - 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 269, 269, 269, 269, 269, + 269, 269, 269, 245, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, + 270, 270, 270, 270, 270, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 245, - 245, 245, 266, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 268, + 268, 268, 268, 268, 268, 245, 245, 245, 266, 267, 267, 267, 267, 267, + 267, 267, 267, 267, 267, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 270, 270, 270, 270, - 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 268, 268, 268, - 268, 268, 268, 268, 268, 268, 268, 268, 268, 245, 245, 245, 245, 268, + 268, 268, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, + 270, 270, 270, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 245, 245, 245, 245, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 0, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 268, 268, 0, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, @@ -1934,17 +2056,16 @@ static unsigned short index2[] = { 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 245, 245, 245, - 245, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 245, 245, 245, 245, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 245, 245, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 245, 245, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 268, 268, 268, 268, 268, 245, 170, 170, 170, 170, 170, 170, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 245, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, @@ -1957,21 +2078,21 @@ static unsigned short index2[] = { 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 170, 170, 170, 170, 170, 170, 170, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, 248, 170, 170, 170, 170, 170, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 248, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, @@ -1979,96 +2100,98 @@ static unsigned short index2[] = { 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 0, 0, 0, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, + 170, 170, 170, 170, 170, 170, 170, 170, 0, 0, 0, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, - 244, 244, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 244, 244, 244, 244, 244, 244, 244, 244, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 53, 53, 53, 53, 53, - 53, 83, 83, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 53, 138, 138, - 138, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 144, - 144, 144, 144, 144, 144, 144, 144, 144, 144, 48, 48, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 47, 44, 47, 44, 47, 44, 47, - 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, - 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, - 44, 47, 48, 81, 82, 82, 82, 138, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, - 138, 52, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, - 44, 47, 44, 47, 44, 47, 44, 47, 0, 0, 0, 0, 0, 0, 0, 81, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 53, 53, 53, 53, 53, 53, 83, 83, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 53, 138, 138, 138, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, + 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, + 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 48, 81, 82, 82, 82, 138, 81, + 81, 81, 81, 81, 81, 81, 81, 81, 81, 138, 52, 44, 47, 44, 47, 44, 47, 44, + 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, + 47, 44, 47, 51, 51, 0, 81, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 173, 173, 173, 173, 173, - 173, 173, 173, 173, 173, 81, 81, 83, 83, 83, 83, 83, 83, 0, 0, 0, 0, 0, - 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 52, 52, 52, 52, 52, 52, 52, 52, 52, 54, 54, - 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 47, 47, 44, 47, - 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, - 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, - 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, - 44, 47, 44, 47, 44, 47, 51, 47, 47, 47, 47, 47, 47, 47, 47, 44, 47, 44, - 47, 44, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 52, 271, 271, 44, 47, 44, - 47, 0, 44, 47, 44, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 47, 44, - 47, 44, 47, 44, 47, 44, 47, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 51, 47, 48, 48, 48, 48, - 48, 48, 48, 135, 48, 48, 48, 142, 48, 48, 48, 48, 135, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 139, 139, 135, 135, 139, 26, 26, 26, 26, 0, 0, 0, 0, 148, 148, 148, - 148, 148, 148, 80, 80, 85, 225, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 81, + 81, 83, 83, 83, 83, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 54, 54, 44, 47, 44, 47, 44, 47, 44, + 47, 44, 47, 44, 47, 44, 47, 47, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, + 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, + 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, + 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 51, + 47, 47, 47, 47, 47, 47, 47, 47, 44, 47, 44, 47, 44, 44, 47, 44, 47, 44, + 47, 44, 47, 44, 47, 52, 271, 271, 44, 47, 44, 47, 0, 44, 47, 44, 47, 47, + 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, 47, 44, + 47, 44, 47, 44, 44, 44, 44, 0, 0, 44, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 51, 51, 47, 48, 48, 48, 48, 48, 48, + 48, 135, 48, 48, 48, 142, 48, 48, 48, 48, 135, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 139, + 139, 135, 135, 139, 26, 26, 26, 26, 0, 0, 0, 0, 148, 148, 148, 148, 148, + 148, 80, 80, 85, 225, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 138, 138, 138, 138, 0, 0, 0, 0, - 0, 0, 0, 0, 139, 139, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 138, 138, 138, 138, 0, 0, 0, 0, 0, 0, 0, + 0, 139, 139, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 139, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, + 139, 142, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 83, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 0, 0, 0, 0, 0, 0, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 48, 48, 48, 48, 48, 48, 83, + 83, 83, 48, 0, 0, 0, 0, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 142, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 83, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 0, 0, 0, 0, 0, 0, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 48, 48, 48, 48, 48, 48, - 83, 83, 83, 48, 0, 0, 0, 0, 144, 144, 144, 144, 144, 144, 144, 144, 144, - 144, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 135, 135, 135, 135, 135, 86, - 86, 86, 83, 83, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 135, 135, 135, 135, 135, 135, 135, - 135, 135, 135, 135, 139, 175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 170, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 135, 135, 135, 135, 135, 86, 86, + 86, 83, 83, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 139, 175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 0, - 0, 0, 135, 135, 135, 139, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 0, 0, 0, + 135, 135, 135, 139, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 145, - 139, 139, 135, 135, 135, 135, 139, 139, 135, 139, 139, 139, 175, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 0, 53, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 0, 0, 0, 0, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 145, 139, + 139, 135, 135, 135, 135, 139, 139, 135, 139, 139, 139, 175, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 0, 53, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 0, 0, 0, 0, 83, 83, 48, 48, 48, 48, 48, 135, 53, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 135, 135, 135, + 135, 135, 135, 139, 139, 135, 135, 139, 139, 135, 135, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 48, 48, 48, 135, 48, 48, 48, 48, 48, 48, 48, 48, 135, 139, 0, 0, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 0, 0, 83, 83, 83, 83, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 53, 48, + 48, 48, 48, 48, 48, 80, 80, 80, 48, 139, 135, 139, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 135, 135, 135, 135, 135, 135, 139, 139, 135, 135, - 139, 139, 135, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 135, 48, 48, - 48, 48, 48, 48, 48, 48, 135, 139, 0, 0, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 0, 0, 83, 83, 83, 83, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 53, 48, 48, 48, 48, 48, 48, 80, 80, 80, - 48, 139, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 81, - 48, 81, 81, 86, 48, 48, 81, 81, 48, 48, 48, 48, 48, 81, 81, 48, 81, 48, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 48, 48, 53, 83, 83, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 139, 135, - 135, 139, 139, 83, 83, 48, 53, 53, 139, 142, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 48, 48, 48, 48, 48, 48, 0, 0, 48, 48, 48, 48, 48, 48, 0, 0, 48, 48, - 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 0, - 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 81, 48, 81, 81, 86, 48, 48, 81, 81, + 48, 48, 48, 48, 48, 81, 81, 48, 81, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 53, 83, 83, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 139, 135, 135, 139, 139, 83, 83, 48, 53, + 53, 139, 142, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 0, 0, + 48, 48, 48, 48, 48, 48, 0, 0, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 0, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 271, 51, 51, 51, 51, 0, 0, 0, 0, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 139, 139, 135, 139, 139, 135, 139, 139, 83, 139, - 142, 0, 0, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 0, 0, 0, 0, - 0, 0, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 139, 139, 135, 139, 139, + 135, 139, 139, 83, 139, 142, 0, 0, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 0, 0, 0, 0, 0, 0, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, @@ -2079,12 +2202,12 @@ static unsigned short index2[] = { 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, - 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, + 261, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, + 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 272, 272, 272, 272, 272, 272, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, @@ -2093,7 +2216,8 @@ static unsigned short index2[] = { 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 273, 273, 273, 273, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, @@ -2102,8 +2226,7 @@ static unsigned short index2[] = { 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, - 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 274, 274, - 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, + 273, 273, 273, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, @@ -2113,36 +2236,37 @@ static unsigned short index2[] = { 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, - 170, 170, 274, 170, 274, 170, 170, 274, 274, 274, 274, 274, 274, 274, - 274, 274, 274, 170, 274, 170, 274, 170, 170, 274, 274, 170, 170, 170, + 274, 274, 274, 274, 274, 170, 170, 274, 170, 274, 170, 170, 274, 274, + 274, 274, 274, 274, 274, 274, 274, 274, 170, 274, 170, 274, 170, 170, + 274, 274, 170, 170, 170, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, - 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 0, 0, 274, + 274, 274, 274, 0, 0, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, - 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, - 274, 274, 274, 274, 274, 274, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 35, 35, 35, 35, 35, 35, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, - 35, 35, 35, 35, 0, 0, 0, 0, 0, 275, 276, 275, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 215, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 0, 275, 275, 275, 275, 275, 0, 275, 0, 275, 275, 0, - 275, 275, 0, 275, 275, 275, 275, 275, 275, 275, 275, 275, 277, 131, 131, + 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 35, 35, 35, 35, 35, 35, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 35, 35, 35, 35, 35, 0, 0, 0, 0, 0, 275, 276, 275, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 215, 275, 275, 275, 275, + 275, 275, 275, 275, 275, 275, 275, 275, 275, 0, 275, 275, 275, 275, 275, + 0, 275, 0, 275, 275, 0, 275, 275, 0, 275, 275, 275, 275, 275, 275, 275, + 275, 275, 277, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 278, 278, - 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 131, 131, 131, 131, + 131, 131, 131, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, @@ -2158,27 +2282,28 @@ static unsigned short index2[] = { 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 279, 195, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 195, 279, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 0, 0, 131, 131, + 131, 0, 0, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 280, 26, 0, 0, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 281, 281, 281, 281, 281, 281, + 281, 282, 283, 281, 0, 0, 0, 0, 0, 0, 81, 81, 81, 81, 81, 81, 81, 86, 86, + 86, 86, 86, 86, 86, 0, 0, 281, 284, 284, 285, 285, 282, 283, 282, 283, + 282, 283, 282, 283, 282, 283, 282, 283, 282, 283, 282, 283, 247, 247, + 282, 283, 281, 281, 281, 281, 285, 285, 285, 286, 281, 286, 0, 281, 286, + 281, 281, 284, 287, 288, 287, 288, 287, 288, 289, 281, 281, 290, 291, + 292, 292, 293, 0, 281, 294, 289, 281, 0, 0, 0, 0, 131, 131, 131, 118, + 131, 0, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 280, 26, 0, 0, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 281, 281, 281, 281, 281, 281, 281, 282, 283, 281, 0, 0, - 0, 0, 0, 0, 81, 81, 81, 81, 81, 81, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 281, - 284, 284, 285, 285, 282, 283, 282, 283, 282, 283, 282, 283, 282, 283, - 282, 283, 282, 283, 282, 283, 247, 247, 282, 283, 281, 281, 281, 281, - 285, 285, 285, 286, 281, 286, 0, 281, 286, 281, 281, 284, 287, 288, 287, - 288, 287, 288, 289, 281, 281, 290, 291, 292, 292, 293, 0, 281, 294, 289, - 281, 0, 0, 0, 0, 131, 131, 131, 118, 131, 0, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, @@ -2186,379 +2311,517 @@ static unsigned short index2[] = { 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 0, 0, 174, 0, 295, 295, 296, 297, 296, 295, 295, 298, - 299, 295, 300, 301, 302, 301, 301, 303, 303, 303, 303, 303, 303, 303, - 303, 303, 303, 301, 295, 304, 305, 304, 295, 295, 306, 306, 306, 306, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 0, 0, 174, 0, 295, 295, + 296, 297, 296, 295, 295, 298, 299, 295, 300, 301, 302, 301, 301, 303, + 303, 303, 303, 303, 303, 303, 303, 303, 303, 301, 295, 304, 305, 304, + 295, 295, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, - 306, 306, 306, 306, 306, 306, 306, 306, 298, 295, 299, 307, 308, 307, + 298, 295, 299, 307, 308, 307, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, - 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 298, 305, - 299, 305, 298, 299, 310, 311, 312, 310, 310, 313, 313, 313, 313, 313, - 313, 313, 313, 313, 313, 314, 313, 313, 313, 313, 313, 313, 313, 313, + 309, 309, 309, 309, 298, 305, 299, 305, 298, 299, 310, 311, 312, 310, + 310, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 314, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, - 313, 313, 313, 313, 313, 313, 313, 313, 313, 314, 314, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, - 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 0, - 0, 0, 313, 313, 313, 313, 313, 313, 0, 0, 313, 313, 313, 313, 313, 313, - 0, 0, 313, 313, 313, 313, 313, 313, 0, 0, 313, 313, 313, 0, 0, 0, 297, - 297, 305, 307, 315, 297, 297, 0, 316, 317, 317, 317, 317, 316, 316, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 318, 318, 318, 26, 30, 0, 0, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, + 313, 314, 314, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, + 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, + 313, 313, 313, 313, 313, 313, 0, 0, 0, 313, 313, 313, 313, 313, 313, 0, + 0, 313, 313, 313, 313, 313, 313, 0, 0, 313, 313, 313, 313, 313, 313, 0, + 0, 313, 313, 313, 0, 0, 0, 297, 297, 305, 307, 315, 297, 297, 0, 316, + 317, 317, 317, 317, 316, 316, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 318, 318, + 318, 26, 30, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 0, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 0, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 0, 0, 0, 0, 0, 83, 138, 83, 0, 0, 0, 0, 148, 148, 148, 148, 148, 148, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 83, 138, 83, 0, 0, + 0, 0, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, - 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 0, 0, 0, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 319, 319, 319, 319, 319, 319, 319, 319, 319, + 148, 148, 148, 148, 0, 0, 0, 80, 80, 80, 80, 80, 80, 80, 80, 80, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - 319, 319, 153, 153, 153, 153, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 153, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 153, 153, 153, 153, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 153, 153, + 26, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, + 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 86, 0, 0, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 86, 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, + 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, 0, 0, 0, + 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 148, 148, + 148, 148, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 173, 48, 48, 48, 48, 48, 48, 48, + 48, 173, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 0, 148, 148, 148, 148, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 173, 48, - 48, 48, 48, 48, 48, 48, 48, 173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 81, 81, 81, 81, 81, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 0, 83, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 83, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, - 48, 83, 173, 173, 173, 173, 173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 48, 48, + 48, 48, 48, 48, 48, 48, 83, 173, 173, 173, 173, 173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 48, 48, 48, 48, 48, 48, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 0, 0, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 0, 0, 0, 0, 0, 0, + 48, 48, 48, 48, 0, 0, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 0, 0, 107, 0, 107, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 0, + 0, 107, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 0, 107, 107, 0, 0, 0, 107, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 0, 107, 107, 0, 0, 0, 107, 0, 0, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 0, 104, 321, 321, 321, 321, 321, 321, 321, 321, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 0, 104, 320, 320, 320, 320, 320, 320, 320, 320, 0, 0, 0, 0, 0, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 322, 322, 321, 321, 321, + 321, 321, 321, 321, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, 0, 0, 0, 0, 0, 321, 321, 321, + 321, 321, 321, 321, 321, 321, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 320, 320, 320, 320, 320, - 320, 0, 0, 0, 138, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 321, 321, 321, 321, 321, 321, 0, 0, 0, 138, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, - 0, 0, 0, 0, 0, 107, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, 0, 0, 0, 107, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 107, 135, 135, 135, 0, 135, 135, 0, 0, 0, 0, 0, 135, 86, 135, 81, 107, - 107, 107, 107, 0, 107, 107, 107, 0, 107, 107, 107, 107, 107, 107, 107, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 135, 135, 135, 0, + 135, 135, 0, 0, 0, 0, 0, 135, 86, 135, 81, 107, 107, 107, 107, 0, 107, + 107, 107, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 0, 0, 0, 0, 81, 176, 86, 0, 0, 0, 0, 142, 321, 321, 321, 321, 321, + 321, 321, 321, 0, 0, 0, 0, 0, 0, 0, 0, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 0, 0, 0, 0, 81, 176, 86, 0, 0, 0, 0, 142, - 320, 320, 320, 320, 320, 320, 320, 320, 0, 0, 0, 0, 0, 0, 0, 0, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 321, 321, 104, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 320, 320, - 104, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 321, 321, 321, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 322, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 81, 86, + 0, 0, 0, 0, 321, 321, 321, 321, 321, 104, 104, 104, 104, 104, 104, 104, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, - 138, 138, 138, 138, 138, 138, 138, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 0, 0, 320, 320, 320, 320, 320, 320, 320, 320, 107, 107, 107, 107, + 107, 107, 107, 0, 0, 0, 138, 138, 138, 138, 138, 138, 138, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 0, 0, 0, 0, 0, 320, 320, 320, 320, 320, 320, 320, 320, 107, 107, + 107, 107, 107, 107, 107, 0, 0, 321, 321, 321, 321, 321, 321, 321, 321, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 0, 0, 0, 0, 0, 321, 321, 321, 321, 321, 321, + 321, 321, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 0, 0, 0, 0, 0, 0, 0, 104, 104, 104, 104, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 321, 321, 321, 321, 321, 321, 321, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 107, 107, 107, 107, 107, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 0, 139, 135, 139, 48, 48, 48, 48, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 323, 323, 323, 323, + 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, + 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 323, 0, 139, + 135, 139, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 135, 135, 135, 135, 135, - 135, 135, 135, 135, 135, 135, 135, 135, 135, 142, 83, 83, 83, 83, 83, 83, - 83, 0, 0, 0, 0, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, - 153, 153, 153, 153, 153, 153, 153, 153, 153, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 135, 135, 139, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 140, 48, 140, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 140, 48, 48, 48, 48, 139, 139, 139, 135, - 135, 135, 135, 139, 139, 142, 141, 83, 83, 188, 83, 83, 83, 83, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, - 0, 0, 0, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 0, 0, 0, 0, 0, - 0, 81, 81, 81, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 142, 83, 83, 83, 83, 83, 83, 83, 0, 0, 0, 0, 153, 153, 153, 153, 153, + 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, + 153, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 142, 135, 135, 139, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 140, + 48, 140, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 140, 48, + 48, 48, 48, 139, 139, 139, 135, 135, 135, 135, 139, 139, 142, 141, 83, + 83, 188, 83, 83, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 149, 135, 135, 135, 135, 139, 135, 150, 150, 135, 135, - 135, 142, 142, 0, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 83, - 83, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135, 135, 139, 48, 48, + 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 0, 0, 0, 0, 0, 0, 81, 81, 81, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 149, 135, 135, + 135, 135, 139, 135, 150, 150, 135, 135, 135, 142, 142, 0, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 83, 83, 83, 83, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 145, 83, 83, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135, 135, 139, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 139, 139, 139, 135, 135, 135, - 135, 135, 135, 135, 135, 135, 139, 175, 48, 48, 48, 48, 83, 83, 83, 83, - 0, 0, 0, 0, 0, 0, 0, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 0, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 139, 139, 139, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 139, 175, 48, 48, 48, 48, 83, 83, 83, + 83, 0, 0, 0, 0, 83, 0, 0, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 48, 0, 0, 0, 0, 0, 0, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 139, 139, 139, 135, 135, + 135, 139, 139, 135, 175, 145, 135, 83, 83, 83, 83, 83, 83, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 135, - 139, 135, 139, 139, 135, 135, 135, 135, 135, 135, 175, 145, 0, 0, 0, 0, - 0, 0, 0, 0, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 135, 139, 139, 139, 135, 135, 135, 135, 135, 135, 145, 142, + 0, 0, 0, 0, 0, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 0, 0, 0, + 0, 0, 0, 0, 135, 139, 139, 0, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 48, + 48, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 0, 48, + 48, 48, 48, 48, 0, 0, 145, 48, 146, 139, 135, 139, 139, 139, 139, 0, 0, + 139, 139, 0, 0, 147, 147, 175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 146, 0, 0, 0, + 0, 0, 48, 48, 48, 48, 48, 139, 139, 0, 0, 81, 81, 81, 81, 81, 81, 81, 0, + 0, 0, 81, 81, 81, 81, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 146, 139, 139, 135, 135, 135, 135, + 135, 135, 139, 149, 147, 147, 146, 147, 135, 135, 139, 142, 145, 48, 48, + 83, 48, 0, 0, 0, 0, 0, 0, 0, 0, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 146, 139, 139, 135, 135, 135, 135, 0, 0, 139, + 139, 147, 147, 135, 135, 139, 142, 145, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 139, + 139, 139, 135, 135, 135, 135, 135, 135, 135, 135, 139, 139, 135, 139, + 142, 135, 83, 83, 83, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 135, 139, 135, 139, 139, 135, 135, 135, + 135, 135, 135, 175, 145, 0, 0, 0, 0, 0, 0, 0, 0, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 148, 148, 148, 148, 148, 148, 148, 148, 148, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 173, + 48, 48, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, - 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 83, 83, 83, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 0, 83, + 83, 83, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, + 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, + 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 0, 0, 0, 0, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 0, 0, 176, 176, 176, 176, 176, 83, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 81, + 81, 81, 81, 81, 81, 81, 83, 83, 83, 83, 83, 80, 80, 80, 80, 53, 53, 53, + 53, 83, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 0, 148, 148, 148, 148, 148, 148, 148, 0, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 139, 139, 139, 139, 139, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 48, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135, 135, 135, 135, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 139, 139, 139, 139, 139, 139, 139, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 135, 135, 135, 135, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 170, 170, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 170, 170, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, + 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 80, 135, + 176, 83, 174, 174, 174, 174, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 0, 0, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 322, 322, 322, 322, 322, 322, 322, 323, 323, 176, 176, 176, 80, 80, 80, - 324, 323, 323, 323, 323, 323, 174, 174, 174, 174, 174, 174, 174, 174, 86, - 86, 86, 86, 86, 86, 86, 86, 80, 80, 81, 81, 81, 81, 81, 86, 86, 80, 80, + 80, 80, 80, 80, 80, 80, 0, 0, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 81, 81, 81, 81, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 322, 322, 322, 322, 322, 322, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 80, 80, 80, 80, 80, 80, 324, 324, 324, 324, 324, 324, 324, 325, 325, 176, + 176, 176, 80, 80, 80, 326, 325, 325, 325, 325, 325, 174, 174, 174, 174, + 174, 174, 174, 174, 86, 86, 86, 86, 86, 86, 86, 86, 80, 80, 81, 81, 81, + 81, 81, 86, 86, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 81, 81, + 81, 81, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 324, 324, + 324, 324, 324, 324, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 81, 81, 81, 26, 0, 0, 0, 0, 0, 0, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 81, + 81, 81, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 148, 148, 148, 148, 148, 148, 148, 148, - 148, 148, 148, 148, 148, 148, 148, 148, 148, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 35, 35, 35, 35, 35, 35, 35, 0, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 49, 0, - 49, 49, 0, 0, 49, 0, 0, 49, 49, 0, 0, 49, 49, 49, 49, 0, 49, 49, 49, 49, - 49, 49, 49, 49, 35, 35, 35, 35, 0, 35, 0, 35, 35, 35, 35, 35, 35, 35, 0, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 49, 49, 0, 49, 49, 49, 49, 0, 0, 49, - 49, 49, 49, 49, 49, 49, 49, 0, 49, 49, 49, 49, 49, 49, 49, 0, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 49, 49, 0, 49, 49, 49, 49, 0, 49, 49, 49, 49, 49, 0, - 49, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 0, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 0, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 49, 0, 49, 49, 0, 0, 49, 0, 0, 49, 49, 0, 0, 49, + 49, 49, 49, 0, 49, 49, 49, 49, 49, 49, 49, 49, 35, 35, 35, 35, 0, 35, 0, + 35, 35, 35, 35, 35, 35, 35, 0, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 49, 0, 49, 49, 49, 49, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 0, 49, 49, + 49, 49, 49, 49, 49, 0, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 49, 49, 0, 49, + 49, 49, 49, 0, 49, 49, 49, 49, 49, 0, 49, 0, 0, 0, 49, 49, 49, 49, 49, + 49, 49, 0, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 325, + 35, 35, 35, 35, 35, 35, 35, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 327, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 226, + 35, 35, 35, 35, 35, 35, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 327, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 226, 35, 35, 35, 35, 35, 35, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 327, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 226, 35, 35, 35, 35, 35, 35, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 325, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 49, 49, 49, 327, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 226, 35, 35, 35, 35, 35, 35, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 325, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 49, 49, 49, 49, 49, 49, 49, 327, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 226, 35, 35, - 35, 35, 35, 35, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 325, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 226, 35, 35, 35, 35, 35, 35, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 325, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 226, 35, 35, 35, 35, 35, 35, 49, 35, 0, 0, 326, 326, - 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, - 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, - 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, - 326, 326, 326, 326, 326, 326, 131, 131, 131, 131, 0, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 0, 131, 131, 0, 131, 0, 0, - 131, 0, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 0, 131, 131, - 131, 131, 0, 131, 0, 131, 0, 0, 0, 0, 0, 0, 131, 0, 0, 0, 0, 131, 0, 131, - 0, 131, 0, 131, 131, 131, 0, 131, 131, 0, 131, 0, 0, 131, 0, 131, 0, 131, - 0, 131, 0, 131, 0, 131, 131, 0, 131, 0, 0, 131, 131, 131, 131, 0, 131, - 131, 131, 131, 131, 131, 131, 0, 131, 131, 131, 131, 0, 131, 131, 131, - 131, 0, 131, 0, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 0, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 0, 0, 0, 0, 0, 131, 131, 131, 0, 131, 131, 131, 131, 131, 0, + 35, 35, 35, 35, 49, 35, 0, 0, 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 0, 0, 321, 321, 321, 321, 321, 321, 321, 321, 321, 86, 86, 86, 86, + 86, 86, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 131, + 131, 131, 0, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 78, 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 131, 0, 131, 131, 0, 131, 0, 0, 131, 0, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 0, 131, 131, 131, 131, 0, 131, 0, 131, 0, 0, 0, 0, 0, + 0, 131, 0, 0, 0, 0, 131, 0, 131, 0, 131, 0, 131, 131, 131, 0, 131, 131, + 0, 131, 0, 0, 131, 0, 131, 0, 131, 0, 131, 0, 131, 0, 131, 131, 0, 131, + 0, 0, 131, 131, 131, 131, 0, 131, 131, 131, 131, 131, 131, 131, 0, 131, + 131, 131, 131, 0, 131, 131, 131, 131, 0, 131, 0, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 0, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 0, 0, 0, 0, 0, 131, 131, 131, 0, + 131, 131, 131, 131, 131, 0, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 78, 78, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 0, 0, 0, 0, 0, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 153, 153, 0, 0, + 0, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 327, 0, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 329, 0, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 328, 328, 328, - 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, - 328, 328, 328, 328, 328, 328, 328, 328, 328, 222, 222, 0, 0, 0, 0, 328, - 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, - 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, - 328, 328, 328, 241, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 0, + 241, 241, 241, 241, 241, 241, 241, 330, 330, 330, 330, 330, 330, 330, + 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, + 330, 330, 330, 330, 330, 222, 222, 0, 0, 0, 0, 330, 330, 330, 330, 330, + 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, + 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 241, + 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 268, 268, 268, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 268, 268, 268, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 268, 268, 0, 0, 0, 0, 0, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 0, 0, 0, 0, 0, 0, 0, 268, 268, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 0, 0, 0, 0, 0, 268, 268, 268, 268, 268, 268, 268, 268, 268, 0, 0, 0, + 0, 0, 0, 0, 268, 268, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, - 26, 26, 26, 26, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, - 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 0, 26, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, + 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, @@ -2567,76 +2830,103 @@ static unsigned short index2[] = { 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 0, 26, 26, 26, 26, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 0, 0, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 26, 26, 26, 26, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 0, 0, 0, 0, 0, 0, 0, 0, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, + 0, 0, 0, 0, 0, 0, 0, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, - 274, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 274, 274, 274, 274, 274, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 174, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 174, 174, 174, 174, 174, 174, 174, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 174, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, - 174, 174, 174, 174, 174, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, @@ -2649,8 +2939,8 @@ static unsigned short index2[] = { 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, @@ -2659,7 +2949,7 @@ static unsigned short index2[] = { 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, - 273, 273, 273, 273, 0, 0, + 273, 273, 273, 273, 273, 273, 273, 273, 273, 0, 0, }; /* decomposition data */ @@ -3146,359 +3436,355 @@ static unsigned int decomp_data[] = { 50, 49, 26085, 770, 50, 50, 26085, 770, 50, 51, 26085, 770, 50, 52, 26085, 770, 50, 53, 26085, 770, 50, 54, 26085, 770, 50, 55, 26085, 770, 50, 56, 26085, 770, 50, 57, 26085, 770, 51, 48, 26085, 770, 51, 49, - 26085, 778, 103, 97, 108, 259, 42863, 259, 294, 259, 339, 256, 35912, - 256, 26356, 256, 36554, 256, 36040, 256, 28369, 256, 20018, 256, 21477, - 256, 40860, 256, 40860, 256, 22865, 256, 37329, 256, 21895, 256, 22856, - 256, 25078, 256, 30313, 256, 32645, 256, 34367, 256, 34746, 256, 35064, - 256, 37007, 256, 27138, 256, 27931, 256, 28889, 256, 29662, 256, 33853, - 256, 37226, 256, 39409, 256, 20098, 256, 21365, 256, 27396, 256, 29211, - 256, 34349, 256, 40478, 256, 23888, 256, 28651, 256, 34253, 256, 35172, - 256, 25289, 256, 33240, 256, 34847, 256, 24266, 256, 26391, 256, 28010, - 256, 29436, 256, 37070, 256, 20358, 256, 20919, 256, 21214, 256, 25796, - 256, 27347, 256, 29200, 256, 30439, 256, 32769, 256, 34310, 256, 34396, - 256, 36335, 256, 38706, 256, 39791, 256, 40442, 256, 30860, 256, 31103, - 256, 32160, 256, 33737, 256, 37636, 256, 40575, 256, 35542, 256, 22751, - 256, 24324, 256, 31840, 256, 32894, 256, 29282, 256, 30922, 256, 36034, - 256, 38647, 256, 22744, 256, 23650, 256, 27155, 256, 28122, 256, 28431, - 256, 32047, 256, 32311, 256, 38475, 256, 21202, 256, 32907, 256, 20956, - 256, 20940, 256, 31260, 256, 32190, 256, 33777, 256, 38517, 256, 35712, - 256, 25295, 256, 27138, 256, 35582, 256, 20025, 256, 23527, 256, 24594, - 256, 29575, 256, 30064, 256, 21271, 256, 30971, 256, 20415, 256, 24489, - 256, 19981, 256, 27852, 256, 25976, 256, 32034, 256, 21443, 256, 22622, - 256, 30465, 256, 33865, 256, 35498, 256, 27578, 256, 36784, 256, 27784, - 256, 25342, 256, 33509, 256, 25504, 256, 30053, 256, 20142, 256, 20841, - 256, 20937, 256, 26753, 256, 31975, 256, 33391, 256, 35538, 256, 37327, - 256, 21237, 256, 21570, 256, 22899, 256, 24300, 256, 26053, 256, 28670, - 256, 31018, 256, 38317, 256, 39530, 256, 40599, 256, 40654, 256, 21147, - 256, 26310, 256, 27511, 256, 36706, 256, 24180, 256, 24976, 256, 25088, - 256, 25754, 256, 28451, 256, 29001, 256, 29833, 256, 31178, 256, 32244, - 256, 32879, 256, 36646, 256, 34030, 256, 36899, 256, 37706, 256, 21015, - 256, 21155, 256, 21693, 256, 28872, 256, 35010, 256, 35498, 256, 24265, - 256, 24565, 256, 25467, 256, 27566, 256, 31806, 256, 29557, 256, 20196, - 256, 22265, 256, 23527, 256, 23994, 256, 24604, 256, 29618, 256, 29801, - 256, 32666, 256, 32838, 256, 37428, 256, 38646, 256, 38728, 256, 38936, - 256, 20363, 256, 31150, 256, 37300, 256, 38584, 256, 24801, 256, 20102, - 256, 20698, 256, 23534, 256, 23615, 256, 26009, 256, 27138, 256, 29134, - 256, 30274, 256, 34044, 256, 36988, 256, 40845, 256, 26248, 256, 38446, - 256, 21129, 256, 26491, 256, 26611, 256, 27969, 256, 28316, 256, 29705, - 256, 30041, 256, 30827, 256, 32016, 256, 39006, 256, 20845, 256, 25134, - 256, 38520, 256, 20523, 256, 23833, 256, 28138, 256, 36650, 256, 24459, - 256, 24900, 256, 26647, 256, 29575, 256, 38534, 256, 21033, 256, 21519, - 256, 23653, 256, 26131, 256, 26446, 256, 26792, 256, 27877, 256, 29702, - 256, 30178, 256, 32633, 256, 35023, 256, 35041, 256, 37324, 256, 38626, - 256, 21311, 256, 28346, 256, 21533, 256, 29136, 256, 29848, 256, 34298, - 256, 38563, 256, 40023, 256, 40607, 256, 26519, 256, 28107, 256, 33256, - 256, 31435, 256, 31520, 256, 31890, 256, 29376, 256, 28825, 256, 35672, - 256, 20160, 256, 33590, 256, 21050, 256, 20999, 256, 24230, 256, 25299, - 256, 31958, 256, 23429, 256, 27934, 256, 26292, 256, 36667, 256, 34892, - 256, 38477, 256, 35211, 256, 24275, 256, 20800, 256, 21952, 256, 22618, - 256, 26228, 256, 20958, 256, 29482, 256, 30410, 256, 31036, 256, 31070, - 256, 31077, 256, 31119, 256, 38742, 256, 31934, 256, 32701, 256, 34322, - 256, 35576, 256, 36920, 256, 37117, 256, 39151, 256, 39164, 256, 39208, - 256, 40372, 256, 37086, 256, 38583, 256, 20398, 256, 20711, 256, 20813, - 256, 21193, 256, 21220, 256, 21329, 256, 21917, 256, 22022, 256, 22120, - 256, 22592, 256, 22696, 256, 23652, 256, 23662, 256, 24724, 256, 24936, - 256, 24974, 256, 25074, 256, 25935, 256, 26082, 256, 26257, 256, 26757, - 256, 28023, 256, 28186, 256, 28450, 256, 29038, 256, 29227, 256, 29730, - 256, 30865, 256, 31038, 256, 31049, 256, 31048, 256, 31056, 256, 31062, - 256, 31069, 256, 31117, 256, 31118, 256, 31296, 256, 31361, 256, 31680, - 256, 32244, 256, 32265, 256, 32321, 256, 32626, 256, 32773, 256, 33261, - 256, 33401, 256, 33401, 256, 33879, 256, 35088, 256, 35222, 256, 35585, - 256, 35641, 256, 36051, 256, 36104, 256, 36790, 256, 36920, 256, 38627, - 256, 38911, 256, 38971, 256, 24693, 256, 148206, 256, 33304, 256, 20006, - 256, 20917, 256, 20840, 256, 20352, 256, 20805, 256, 20864, 256, 21191, - 256, 21242, 256, 21917, 256, 21845, 256, 21913, 256, 21986, 256, 22618, - 256, 22707, 256, 22852, 256, 22868, 256, 23138, 256, 23336, 256, 24274, - 256, 24281, 256, 24425, 256, 24493, 256, 24792, 256, 24910, 256, 24840, - 256, 24974, 256, 24928, 256, 25074, 256, 25140, 256, 25540, 256, 25628, - 256, 25682, 256, 25942, 256, 26228, 256, 26391, 256, 26395, 256, 26454, - 256, 27513, 256, 27578, 256, 27969, 256, 28379, 256, 28363, 256, 28450, - 256, 28702, 256, 29038, 256, 30631, 256, 29237, 256, 29359, 256, 29482, - 256, 29809, 256, 29958, 256, 30011, 256, 30237, 256, 30239, 256, 30410, - 256, 30427, 256, 30452, 256, 30538, 256, 30528, 256, 30924, 256, 31409, - 256, 31680, 256, 31867, 256, 32091, 256, 32244, 256, 32574, 256, 32773, - 256, 33618, 256, 33775, 256, 34681, 256, 35137, 256, 35206, 256, 35222, - 256, 35519, 256, 35576, 256, 35531, 256, 35585, 256, 35582, 256, 35565, - 256, 35641, 256, 35722, 256, 36104, 256, 36664, 256, 36978, 256, 37273, - 256, 37494, 256, 38524, 256, 38627, 256, 38742, 256, 38875, 256, 38911, - 256, 38923, 256, 38971, 256, 39698, 256, 40860, 256, 141386, 256, 141380, - 256, 144341, 256, 15261, 256, 16408, 256, 16441, 256, 152137, 256, - 154832, 256, 163539, 256, 40771, 256, 40846, 514, 102, 102, 514, 102, - 105, 514, 102, 108, 770, 102, 102, 105, 770, 102, 102, 108, 514, 383, - 116, 514, 115, 116, 514, 1396, 1398, 514, 1396, 1381, 514, 1396, 1387, - 514, 1406, 1398, 514, 1396, 1389, 512, 1497, 1460, 512, 1522, 1463, 262, - 1506, 262, 1488, 262, 1491, 262, 1492, 262, 1499, 262, 1500, 262, 1501, - 262, 1512, 262, 1514, 262, 43, 512, 1513, 1473, 512, 1513, 1474, 512, - 64329, 1473, 512, 64329, 1474, 512, 1488, 1463, 512, 1488, 1464, 512, - 1488, 1468, 512, 1489, 1468, 512, 1490, 1468, 512, 1491, 1468, 512, 1492, - 1468, 512, 1493, 1468, 512, 1494, 1468, 512, 1496, 1468, 512, 1497, 1468, - 512, 1498, 1468, 512, 1499, 1468, 512, 1500, 1468, 512, 1502, 1468, 512, - 1504, 1468, 512, 1505, 1468, 512, 1507, 1468, 512, 1508, 1468, 512, 1510, - 1468, 512, 1511, 1468, 512, 1512, 1468, 512, 1513, 1468, 512, 1514, 1468, - 512, 1493, 1465, 512, 1489, 1471, 512, 1499, 1471, 512, 1508, 1471, 514, - 1488, 1500, 267, 1649, 268, 1649, 267, 1659, 268, 1659, 269, 1659, 270, - 1659, 267, 1662, 268, 1662, 269, 1662, 270, 1662, 267, 1664, 268, 1664, - 269, 1664, 270, 1664, 267, 1658, 268, 1658, 269, 1658, 270, 1658, 267, - 1663, 268, 1663, 269, 1663, 270, 1663, 267, 1657, 268, 1657, 269, 1657, - 270, 1657, 267, 1700, 268, 1700, 269, 1700, 270, 1700, 267, 1702, 268, - 1702, 269, 1702, 270, 1702, 267, 1668, 268, 1668, 269, 1668, 270, 1668, - 267, 1667, 268, 1667, 269, 1667, 270, 1667, 267, 1670, 268, 1670, 269, - 1670, 270, 1670, 267, 1671, 268, 1671, 269, 1671, 270, 1671, 267, 1677, - 268, 1677, 267, 1676, 268, 1676, 267, 1678, 268, 1678, 267, 1672, 268, - 1672, 267, 1688, 268, 1688, 267, 1681, 268, 1681, 267, 1705, 268, 1705, - 269, 1705, 270, 1705, 267, 1711, 268, 1711, 269, 1711, 270, 1711, 267, - 1715, 268, 1715, 269, 1715, 270, 1715, 267, 1713, 268, 1713, 269, 1713, - 270, 1713, 267, 1722, 268, 1722, 267, 1723, 268, 1723, 269, 1723, 270, - 1723, 267, 1728, 268, 1728, 267, 1729, 268, 1729, 269, 1729, 270, 1729, - 267, 1726, 268, 1726, 269, 1726, 270, 1726, 267, 1746, 268, 1746, 267, - 1747, 268, 1747, 267, 1709, 268, 1709, 269, 1709, 270, 1709, 267, 1735, - 268, 1735, 267, 1734, 268, 1734, 267, 1736, 268, 1736, 267, 1655, 267, - 1739, 268, 1739, 267, 1733, 268, 1733, 267, 1737, 268, 1737, 267, 1744, - 268, 1744, 269, 1744, 270, 1744, 269, 1609, 270, 1609, 523, 1574, 1575, - 524, 1574, 1575, 523, 1574, 1749, 524, 1574, 1749, 523, 1574, 1608, 524, - 1574, 1608, 523, 1574, 1735, 524, 1574, 1735, 523, 1574, 1734, 524, 1574, - 1734, 523, 1574, 1736, 524, 1574, 1736, 523, 1574, 1744, 524, 1574, 1744, - 525, 1574, 1744, 523, 1574, 1609, 524, 1574, 1609, 525, 1574, 1609, 267, - 1740, 268, 1740, 269, 1740, 270, 1740, 523, 1574, 1580, 523, 1574, 1581, - 523, 1574, 1605, 523, 1574, 1609, 523, 1574, 1610, 523, 1576, 1580, 523, - 1576, 1581, 523, 1576, 1582, 523, 1576, 1605, 523, 1576, 1609, 523, 1576, - 1610, 523, 1578, 1580, 523, 1578, 1581, 523, 1578, 1582, 523, 1578, 1605, - 523, 1578, 1609, 523, 1578, 1610, 523, 1579, 1580, 523, 1579, 1605, 523, - 1579, 1609, 523, 1579, 1610, 523, 1580, 1581, 523, 1580, 1605, 523, 1581, - 1580, 523, 1581, 1605, 523, 1582, 1580, 523, 1582, 1581, 523, 1582, 1605, - 523, 1587, 1580, 523, 1587, 1581, 523, 1587, 1582, 523, 1587, 1605, 523, - 1589, 1581, 523, 1589, 1605, 523, 1590, 1580, 523, 1590, 1581, 523, 1590, - 1582, 523, 1590, 1605, 523, 1591, 1581, 523, 1591, 1605, 523, 1592, 1605, - 523, 1593, 1580, 523, 1593, 1605, 523, 1594, 1580, 523, 1594, 1605, 523, - 1601, 1580, 523, 1601, 1581, 523, 1601, 1582, 523, 1601, 1605, 523, 1601, - 1609, 523, 1601, 1610, 523, 1602, 1581, 523, 1602, 1605, 523, 1602, 1609, - 523, 1602, 1610, 523, 1603, 1575, 523, 1603, 1580, 523, 1603, 1581, 523, - 1603, 1582, 523, 1603, 1604, 523, 1603, 1605, 523, 1603, 1609, 523, 1603, - 1610, 523, 1604, 1580, 523, 1604, 1581, 523, 1604, 1582, 523, 1604, 1605, - 523, 1604, 1609, 523, 1604, 1610, 523, 1605, 1580, 523, 1605, 1581, 523, - 1605, 1582, 523, 1605, 1605, 523, 1605, 1609, 523, 1605, 1610, 523, 1606, - 1580, 523, 1606, 1581, 523, 1606, 1582, 523, 1606, 1605, 523, 1606, 1609, - 523, 1606, 1610, 523, 1607, 1580, 523, 1607, 1605, 523, 1607, 1609, 523, - 1607, 1610, 523, 1610, 1580, 523, 1610, 1581, 523, 1610, 1582, 523, 1610, - 1605, 523, 1610, 1609, 523, 1610, 1610, 523, 1584, 1648, 523, 1585, 1648, - 523, 1609, 1648, 779, 32, 1612, 1617, 779, 32, 1613, 1617, 779, 32, 1614, - 1617, 779, 32, 1615, 1617, 779, 32, 1616, 1617, 779, 32, 1617, 1648, 524, - 1574, 1585, 524, 1574, 1586, 524, 1574, 1605, 524, 1574, 1606, 524, 1574, - 1609, 524, 1574, 1610, 524, 1576, 1585, 524, 1576, 1586, 524, 1576, 1605, - 524, 1576, 1606, 524, 1576, 1609, 524, 1576, 1610, 524, 1578, 1585, 524, - 1578, 1586, 524, 1578, 1605, 524, 1578, 1606, 524, 1578, 1609, 524, 1578, - 1610, 524, 1579, 1585, 524, 1579, 1586, 524, 1579, 1605, 524, 1579, 1606, - 524, 1579, 1609, 524, 1579, 1610, 524, 1601, 1609, 524, 1601, 1610, 524, - 1602, 1609, 524, 1602, 1610, 524, 1603, 1575, 524, 1603, 1604, 524, 1603, - 1605, 524, 1603, 1609, 524, 1603, 1610, 524, 1604, 1605, 524, 1604, 1609, - 524, 1604, 1610, 524, 1605, 1575, 524, 1605, 1605, 524, 1606, 1585, 524, - 1606, 1586, 524, 1606, 1605, 524, 1606, 1606, 524, 1606, 1609, 524, 1606, - 1610, 524, 1609, 1648, 524, 1610, 1585, 524, 1610, 1586, 524, 1610, 1605, - 524, 1610, 1606, 524, 1610, 1609, 524, 1610, 1610, 525, 1574, 1580, 525, - 1574, 1581, 525, 1574, 1582, 525, 1574, 1605, 525, 1574, 1607, 525, 1576, - 1580, 525, 1576, 1581, 525, 1576, 1582, 525, 1576, 1605, 525, 1576, 1607, - 525, 1578, 1580, 525, 1578, 1581, 525, 1578, 1582, 525, 1578, 1605, 525, - 1578, 1607, 525, 1579, 1605, 525, 1580, 1581, 525, 1580, 1605, 525, 1581, - 1580, 525, 1581, 1605, 525, 1582, 1580, 525, 1582, 1605, 525, 1587, 1580, - 525, 1587, 1581, 525, 1587, 1582, 525, 1587, 1605, 525, 1589, 1581, 525, - 1589, 1582, 525, 1589, 1605, 525, 1590, 1580, 525, 1590, 1581, 525, 1590, - 1582, 525, 1590, 1605, 525, 1591, 1581, 525, 1592, 1605, 525, 1593, 1580, - 525, 1593, 1605, 525, 1594, 1580, 525, 1594, 1605, 525, 1601, 1580, 525, - 1601, 1581, 525, 1601, 1582, 525, 1601, 1605, 525, 1602, 1581, 525, 1602, - 1605, 525, 1603, 1580, 525, 1603, 1581, 525, 1603, 1582, 525, 1603, 1604, - 525, 1603, 1605, 525, 1604, 1580, 525, 1604, 1581, 525, 1604, 1582, 525, - 1604, 1605, 525, 1604, 1607, 525, 1605, 1580, 525, 1605, 1581, 525, 1605, - 1582, 525, 1605, 1605, 525, 1606, 1580, 525, 1606, 1581, 525, 1606, 1582, - 525, 1606, 1605, 525, 1606, 1607, 525, 1607, 1580, 525, 1607, 1605, 525, - 1607, 1648, 525, 1610, 1580, 525, 1610, 1581, 525, 1610, 1582, 525, 1610, - 1605, 525, 1610, 1607, 526, 1574, 1605, 526, 1574, 1607, 526, 1576, 1605, - 526, 1576, 1607, 526, 1578, 1605, 526, 1578, 1607, 526, 1579, 1605, 526, - 1579, 1607, 526, 1587, 1605, 526, 1587, 1607, 526, 1588, 1605, 526, 1588, - 1607, 526, 1603, 1604, 526, 1603, 1605, 526, 1604, 1605, 526, 1606, 1605, - 526, 1606, 1607, 526, 1610, 1605, 526, 1610, 1607, 782, 1600, 1614, 1617, - 782, 1600, 1615, 1617, 782, 1600, 1616, 1617, 523, 1591, 1609, 523, 1591, - 1610, 523, 1593, 1609, 523, 1593, 1610, 523, 1594, 1609, 523, 1594, 1610, - 523, 1587, 1609, 523, 1587, 1610, 523, 1588, 1609, 523, 1588, 1610, 523, - 1581, 1609, 523, 1581, 1610, 523, 1580, 1609, 523, 1580, 1610, 523, 1582, - 1609, 523, 1582, 1610, 523, 1589, 1609, 523, 1589, 1610, 523, 1590, 1609, - 523, 1590, 1610, 523, 1588, 1580, 523, 1588, 1581, 523, 1588, 1582, 523, - 1588, 1605, 523, 1588, 1585, 523, 1587, 1585, 523, 1589, 1585, 523, 1590, - 1585, 524, 1591, 1609, 524, 1591, 1610, 524, 1593, 1609, 524, 1593, 1610, - 524, 1594, 1609, 524, 1594, 1610, 524, 1587, 1609, 524, 1587, 1610, 524, - 1588, 1609, 524, 1588, 1610, 524, 1581, 1609, 524, 1581, 1610, 524, 1580, - 1609, 524, 1580, 1610, 524, 1582, 1609, 524, 1582, 1610, 524, 1589, 1609, - 524, 1589, 1610, 524, 1590, 1609, 524, 1590, 1610, 524, 1588, 1580, 524, - 1588, 1581, 524, 1588, 1582, 524, 1588, 1605, 524, 1588, 1585, 524, 1587, - 1585, 524, 1589, 1585, 524, 1590, 1585, 525, 1588, 1580, 525, 1588, 1581, - 525, 1588, 1582, 525, 1588, 1605, 525, 1587, 1607, 525, 1588, 1607, 525, - 1591, 1605, 526, 1587, 1580, 526, 1587, 1581, 526, 1587, 1582, 526, 1588, - 1580, 526, 1588, 1581, 526, 1588, 1582, 526, 1591, 1605, 526, 1592, 1605, - 524, 1575, 1611, 523, 1575, 1611, 781, 1578, 1580, 1605, 780, 1578, 1581, - 1580, 781, 1578, 1581, 1580, 781, 1578, 1581, 1605, 781, 1578, 1582, - 1605, 781, 1578, 1605, 1580, 781, 1578, 1605, 1581, 781, 1578, 1605, - 1582, 780, 1580, 1605, 1581, 781, 1580, 1605, 1581, 780, 1581, 1605, - 1610, 780, 1581, 1605, 1609, 781, 1587, 1581, 1580, 781, 1587, 1580, - 1581, 780, 1587, 1580, 1609, 780, 1587, 1605, 1581, 781, 1587, 1605, - 1581, 781, 1587, 1605, 1580, 780, 1587, 1605, 1605, 781, 1587, 1605, - 1605, 780, 1589, 1581, 1581, 781, 1589, 1581, 1581, 780, 1589, 1605, - 1605, 780, 1588, 1581, 1605, 781, 1588, 1581, 1605, 780, 1588, 1580, - 1610, 780, 1588, 1605, 1582, 781, 1588, 1605, 1582, 780, 1588, 1605, - 1605, 781, 1588, 1605, 1605, 780, 1590, 1581, 1609, 780, 1590, 1582, - 1605, 781, 1590, 1582, 1605, 780, 1591, 1605, 1581, 781, 1591, 1605, - 1581, 781, 1591, 1605, 1605, 780, 1591, 1605, 1610, 780, 1593, 1580, - 1605, 780, 1593, 1605, 1605, 781, 1593, 1605, 1605, 780, 1593, 1605, - 1609, 780, 1594, 1605, 1605, 780, 1594, 1605, 1610, 780, 1594, 1605, - 1609, 780, 1601, 1582, 1605, 781, 1601, 1582, 1605, 780, 1602, 1605, - 1581, 780, 1602, 1605, 1605, 780, 1604, 1581, 1605, 780, 1604, 1581, - 1610, 780, 1604, 1581, 1609, 781, 1604, 1580, 1580, 780, 1604, 1580, - 1580, 780, 1604, 1582, 1605, 781, 1604, 1582, 1605, 780, 1604, 1605, - 1581, 781, 1604, 1605, 1581, 781, 1605, 1581, 1580, 781, 1605, 1581, - 1605, 780, 1605, 1581, 1610, 781, 1605, 1580, 1581, 781, 1605, 1580, - 1605, 781, 1605, 1582, 1580, 781, 1605, 1582, 1605, 781, 1605, 1580, - 1582, 781, 1607, 1605, 1580, 781, 1607, 1605, 1605, 781, 1606, 1581, - 1605, 780, 1606, 1581, 1609, 780, 1606, 1580, 1605, 781, 1606, 1580, - 1605, 780, 1606, 1580, 1609, 780, 1606, 1605, 1610, 780, 1606, 1605, - 1609, 780, 1610, 1605, 1605, 781, 1610, 1605, 1605, 780, 1576, 1582, - 1610, 780, 1578, 1580, 1610, 780, 1578, 1580, 1609, 780, 1578, 1582, - 1610, 780, 1578, 1582, 1609, 780, 1578, 1605, 1610, 780, 1578, 1605, - 1609, 780, 1580, 1605, 1610, 780, 1580, 1581, 1609, 780, 1580, 1605, - 1609, 780, 1587, 1582, 1609, 780, 1589, 1581, 1610, 780, 1588, 1581, - 1610, 780, 1590, 1581, 1610, 780, 1604, 1580, 1610, 780, 1604, 1605, - 1610, 780, 1610, 1581, 1610, 780, 1610, 1580, 1610, 780, 1610, 1605, - 1610, 780, 1605, 1605, 1610, 780, 1602, 1605, 1610, 780, 1606, 1581, - 1610, 781, 1602, 1605, 1581, 781, 1604, 1581, 1605, 780, 1593, 1605, - 1610, 780, 1603, 1605, 1610, 781, 1606, 1580, 1581, 780, 1605, 1582, - 1610, 781, 1604, 1580, 1605, 780, 1603, 1605, 1605, 780, 1604, 1580, - 1605, 780, 1606, 1580, 1581, 780, 1580, 1581, 1610, 780, 1581, 1580, - 1610, 780, 1605, 1580, 1610, 780, 1601, 1605, 1610, 780, 1576, 1581, - 1610, 781, 1603, 1605, 1605, 781, 1593, 1580, 1605, 781, 1589, 1605, - 1605, 780, 1587, 1582, 1610, 780, 1606, 1580, 1610, 779, 1589, 1604, - 1746, 779, 1602, 1604, 1746, 1035, 1575, 1604, 1604, 1607, 1035, 1575, - 1603, 1576, 1585, 1035, 1605, 1581, 1605, 1583, 1035, 1589, 1604, 1593, - 1605, 1035, 1585, 1587, 1608, 1604, 1035, 1593, 1604, 1610, 1607, 1035, - 1608, 1587, 1604, 1605, 779, 1589, 1604, 1609, 4619, 1589, 1604, 1609, - 32, 1575, 1604, 1604, 1607, 32, 1593, 1604, 1610, 1607, 32, 1608, 1587, - 1604, 1605, 2059, 1580, 1604, 32, 1580, 1604, 1575, 1604, 1607, 1035, - 1585, 1740, 1575, 1604, 265, 44, 265, 12289, 265, 12290, 265, 58, 265, - 59, 265, 33, 265, 63, 265, 12310, 265, 12311, 265, 8230, 265, 8229, 265, - 8212, 265, 8211, 265, 95, 265, 95, 265, 40, 265, 41, 265, 123, 265, 125, - 265, 12308, 265, 12309, 265, 12304, 265, 12305, 265, 12298, 265, 12299, - 265, 12296, 265, 12297, 265, 12300, 265, 12301, 265, 12302, 265, 12303, - 265, 91, 265, 93, 258, 8254, 258, 8254, 258, 8254, 258, 8254, 258, 95, - 258, 95, 258, 95, 271, 44, 271, 12289, 271, 46, 271, 59, 271, 58, 271, - 63, 271, 33, 271, 8212, 271, 40, 271, 41, 271, 123, 271, 125, 271, 12308, - 271, 12309, 271, 35, 271, 38, 271, 42, 271, 43, 271, 45, 271, 60, 271, - 62, 271, 61, 271, 92, 271, 36, 271, 37, 271, 64, 523, 32, 1611, 526, - 1600, 1611, 523, 32, 1612, 523, 32, 1613, 523, 32, 1614, 526, 1600, 1614, - 523, 32, 1615, 526, 1600, 1615, 523, 32, 1616, 526, 1600, 1616, 523, 32, - 1617, 526, 1600, 1617, 523, 32, 1618, 526, 1600, 1618, 267, 1569, 267, - 1570, 268, 1570, 267, 1571, 268, 1571, 267, 1572, 268, 1572, 267, 1573, - 268, 1573, 267, 1574, 268, 1574, 269, 1574, 270, 1574, 267, 1575, 268, - 1575, 267, 1576, 268, 1576, 269, 1576, 270, 1576, 267, 1577, 268, 1577, - 267, 1578, 268, 1578, 269, 1578, 270, 1578, 267, 1579, 268, 1579, 269, - 1579, 270, 1579, 267, 1580, 268, 1580, 269, 1580, 270, 1580, 267, 1581, - 268, 1581, 269, 1581, 270, 1581, 267, 1582, 268, 1582, 269, 1582, 270, - 1582, 267, 1583, 268, 1583, 267, 1584, 268, 1584, 267, 1585, 268, 1585, - 267, 1586, 268, 1586, 267, 1587, 268, 1587, 269, 1587, 270, 1587, 267, - 1588, 268, 1588, 269, 1588, 270, 1588, 267, 1589, 268, 1589, 269, 1589, - 270, 1589, 267, 1590, 268, 1590, 269, 1590, 270, 1590, 267, 1591, 268, - 1591, 269, 1591, 270, 1591, 267, 1592, 268, 1592, 269, 1592, 270, 1592, - 267, 1593, 268, 1593, 269, 1593, 270, 1593, 267, 1594, 268, 1594, 269, - 1594, 270, 1594, 267, 1601, 268, 1601, 269, 1601, 270, 1601, 267, 1602, - 268, 1602, 269, 1602, 270, 1602, 267, 1603, 268, 1603, 269, 1603, 270, - 1603, 267, 1604, 268, 1604, 269, 1604, 270, 1604, 267, 1605, 268, 1605, - 269, 1605, 270, 1605, 267, 1606, 268, 1606, 269, 1606, 270, 1606, 267, - 1607, 268, 1607, 269, 1607, 270, 1607, 267, 1608, 268, 1608, 267, 1609, - 268, 1609, 267, 1610, 268, 1610, 269, 1610, 270, 1610, 523, 1604, 1570, - 524, 1604, 1570, 523, 1604, 1571, 524, 1604, 1571, 523, 1604, 1573, 524, - 1604, 1573, 523, 1604, 1575, 524, 1604, 1575, 264, 33, 264, 34, 264, 35, - 264, 36, 264, 37, 264, 38, 264, 39, 264, 40, 264, 41, 264, 42, 264, 43, - 264, 44, 264, 45, 264, 46, 264, 47, 264, 48, 264, 49, 264, 50, 264, 51, - 264, 52, 264, 53, 264, 54, 264, 55, 264, 56, 264, 57, 264, 58, 264, 59, - 264, 60, 264, 61, 264, 62, 264, 63, 264, 64, 264, 65, 264, 66, 264, 67, - 264, 68, 264, 69, 264, 70, 264, 71, 264, 72, 264, 73, 264, 74, 264, 75, - 264, 76, 264, 77, 264, 78, 264, 79, 264, 80, 264, 81, 264, 82, 264, 83, - 264, 84, 264, 85, 264, 86, 264, 87, 264, 88, 264, 89, 264, 90, 264, 91, - 264, 92, 264, 93, 264, 94, 264, 95, 264, 96, 264, 97, 264, 98, 264, 99, - 264, 100, 264, 101, 264, 102, 264, 103, 264, 104, 264, 105, 264, 106, - 264, 107, 264, 108, 264, 109, 264, 110, 264, 111, 264, 112, 264, 113, - 264, 114, 264, 115, 264, 116, 264, 117, 264, 118, 264, 119, 264, 120, - 264, 121, 264, 122, 264, 123, 264, 124, 264, 125, 264, 126, 264, 10629, - 264, 10630, 272, 12290, 272, 12300, 272, 12301, 272, 12289, 272, 12539, - 272, 12530, 272, 12449, 272, 12451, 272, 12453, 272, 12455, 272, 12457, - 272, 12515, 272, 12517, 272, 12519, 272, 12483, 272, 12540, 272, 12450, - 272, 12452, 272, 12454, 272, 12456, 272, 12458, 272, 12459, 272, 12461, - 272, 12463, 272, 12465, 272, 12467, 272, 12469, 272, 12471, 272, 12473, - 272, 12475, 272, 12477, 272, 12479, 272, 12481, 272, 12484, 272, 12486, - 272, 12488, 272, 12490, 272, 12491, 272, 12492, 272, 12493, 272, 12494, - 272, 12495, 272, 12498, 272, 12501, 272, 12504, 272, 12507, 272, 12510, - 272, 12511, 272, 12512, 272, 12513, 272, 12514, 272, 12516, 272, 12518, - 272, 12520, 272, 12521, 272, 12522, 272, 12523, 272, 12524, 272, 12525, - 272, 12527, 272, 12531, 272, 12441, 272, 12442, 272, 12644, 272, 12593, - 272, 12594, 272, 12595, 272, 12596, 272, 12597, 272, 12598, 272, 12599, - 272, 12600, 272, 12601, 272, 12602, 272, 12603, 272, 12604, 272, 12605, - 272, 12606, 272, 12607, 272, 12608, 272, 12609, 272, 12610, 272, 12611, - 272, 12612, 272, 12613, 272, 12614, 272, 12615, 272, 12616, 272, 12617, - 272, 12618, 272, 12619, 272, 12620, 272, 12621, 272, 12622, 272, 12623, - 272, 12624, 272, 12625, 272, 12626, 272, 12627, 272, 12628, 272, 12629, - 272, 12630, 272, 12631, 272, 12632, 272, 12633, 272, 12634, 272, 12635, - 272, 12636, 272, 12637, 272, 12638, 272, 12639, 272, 12640, 272, 12641, - 272, 12642, 272, 12643, 264, 162, 264, 163, 264, 172, 264, 175, 264, 166, - 264, 165, 264, 8361, 272, 9474, 272, 8592, 272, 8593, 272, 8594, 272, - 8595, 272, 9632, 272, 9675, 512, 69785, 69818, 512, 69787, 69818, 512, - 69797, 69818, 512, 69937, 69927, 512, 69938, 69927, 512, 119127, 119141, - 512, 119128, 119141, 512, 119135, 119150, 512, 119135, 119151, 512, - 119135, 119152, 512, 119135, 119153, 512, 119135, 119154, 512, 119225, - 119141, 512, 119226, 119141, 512, 119227, 119150, 512, 119228, 119150, - 512, 119227, 119151, 512, 119228, 119151, 262, 65, 262, 66, 262, 67, 262, - 68, 262, 69, 262, 70, 262, 71, 262, 72, 262, 73, 262, 74, 262, 75, 262, - 76, 262, 77, 262, 78, 262, 79, 262, 80, 262, 81, 262, 82, 262, 83, 262, - 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 90, 262, 97, 262, - 98, 262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, 104, 262, 105, - 262, 106, 262, 107, 262, 108, 262, 109, 262, 110, 262, 111, 262, 112, - 262, 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, 262, 119, - 262, 120, 262, 121, 262, 122, 262, 65, 262, 66, 262, 67, 262, 68, 262, - 69, 262, 70, 262, 71, 262, 72, 262, 73, 262, 74, 262, 75, 262, 76, 262, - 77, 262, 78, 262, 79, 262, 80, 262, 81, 262, 82, 262, 83, 262, 84, 262, - 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 90, 262, 97, 262, 98, 262, - 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, 105, 262, 106, 262, 107, - 262, 108, 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, - 262, 115, 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, - 262, 122, 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, 71, - 262, 72, 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, - 262, 80, 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, - 262, 88, 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, - 262, 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, 262, 108, + 26085, 778, 103, 97, 108, 259, 1098, 259, 1100, 259, 42863, 259, 294, + 259, 339, 259, 42791, 259, 43831, 259, 619, 259, 43858, 256, 35912, 256, + 26356, 256, 36554, 256, 36040, 256, 28369, 256, 20018, 256, 21477, 256, + 40860, 256, 40860, 256, 22865, 256, 37329, 256, 21895, 256, 22856, 256, + 25078, 256, 30313, 256, 32645, 256, 34367, 256, 34746, 256, 35064, 256, + 37007, 256, 27138, 256, 27931, 256, 28889, 256, 29662, 256, 33853, 256, + 37226, 256, 39409, 256, 20098, 256, 21365, 256, 27396, 256, 29211, 256, + 34349, 256, 40478, 256, 23888, 256, 28651, 256, 34253, 256, 35172, 256, + 25289, 256, 33240, 256, 34847, 256, 24266, 256, 26391, 256, 28010, 256, + 29436, 256, 37070, 256, 20358, 256, 20919, 256, 21214, 256, 25796, 256, + 27347, 256, 29200, 256, 30439, 256, 32769, 256, 34310, 256, 34396, 256, + 36335, 256, 38706, 256, 39791, 256, 40442, 256, 30860, 256, 31103, 256, + 32160, 256, 33737, 256, 37636, 256, 40575, 256, 35542, 256, 22751, 256, + 24324, 256, 31840, 256, 32894, 256, 29282, 256, 30922, 256, 36034, 256, + 38647, 256, 22744, 256, 23650, 256, 27155, 256, 28122, 256, 28431, 256, + 32047, 256, 32311, 256, 38475, 256, 21202, 256, 32907, 256, 20956, 256, + 20940, 256, 31260, 256, 32190, 256, 33777, 256, 38517, 256, 35712, 256, + 25295, 256, 27138, 256, 35582, 256, 20025, 256, 23527, 256, 24594, 256, + 29575, 256, 30064, 256, 21271, 256, 30971, 256, 20415, 256, 24489, 256, + 19981, 256, 27852, 256, 25976, 256, 32034, 256, 21443, 256, 22622, 256, + 30465, 256, 33865, 256, 35498, 256, 27578, 256, 36784, 256, 27784, 256, + 25342, 256, 33509, 256, 25504, 256, 30053, 256, 20142, 256, 20841, 256, + 20937, 256, 26753, 256, 31975, 256, 33391, 256, 35538, 256, 37327, 256, + 21237, 256, 21570, 256, 22899, 256, 24300, 256, 26053, 256, 28670, 256, + 31018, 256, 38317, 256, 39530, 256, 40599, 256, 40654, 256, 21147, 256, + 26310, 256, 27511, 256, 36706, 256, 24180, 256, 24976, 256, 25088, 256, + 25754, 256, 28451, 256, 29001, 256, 29833, 256, 31178, 256, 32244, 256, + 32879, 256, 36646, 256, 34030, 256, 36899, 256, 37706, 256, 21015, 256, + 21155, 256, 21693, 256, 28872, 256, 35010, 256, 35498, 256, 24265, 256, + 24565, 256, 25467, 256, 27566, 256, 31806, 256, 29557, 256, 20196, 256, + 22265, 256, 23527, 256, 23994, 256, 24604, 256, 29618, 256, 29801, 256, + 32666, 256, 32838, 256, 37428, 256, 38646, 256, 38728, 256, 38936, 256, + 20363, 256, 31150, 256, 37300, 256, 38584, 256, 24801, 256, 20102, 256, + 20698, 256, 23534, 256, 23615, 256, 26009, 256, 27138, 256, 29134, 256, + 30274, 256, 34044, 256, 36988, 256, 40845, 256, 26248, 256, 38446, 256, + 21129, 256, 26491, 256, 26611, 256, 27969, 256, 28316, 256, 29705, 256, + 30041, 256, 30827, 256, 32016, 256, 39006, 256, 20845, 256, 25134, 256, + 38520, 256, 20523, 256, 23833, 256, 28138, 256, 36650, 256, 24459, 256, + 24900, 256, 26647, 256, 29575, 256, 38534, 256, 21033, 256, 21519, 256, + 23653, 256, 26131, 256, 26446, 256, 26792, 256, 27877, 256, 29702, 256, + 30178, 256, 32633, 256, 35023, 256, 35041, 256, 37324, 256, 38626, 256, + 21311, 256, 28346, 256, 21533, 256, 29136, 256, 29848, 256, 34298, 256, + 38563, 256, 40023, 256, 40607, 256, 26519, 256, 28107, 256, 33256, 256, + 31435, 256, 31520, 256, 31890, 256, 29376, 256, 28825, 256, 35672, 256, + 20160, 256, 33590, 256, 21050, 256, 20999, 256, 24230, 256, 25299, 256, + 31958, 256, 23429, 256, 27934, 256, 26292, 256, 36667, 256, 34892, 256, + 38477, 256, 35211, 256, 24275, 256, 20800, 256, 21952, 256, 22618, 256, + 26228, 256, 20958, 256, 29482, 256, 30410, 256, 31036, 256, 31070, 256, + 31077, 256, 31119, 256, 38742, 256, 31934, 256, 32701, 256, 34322, 256, + 35576, 256, 36920, 256, 37117, 256, 39151, 256, 39164, 256, 39208, 256, + 40372, 256, 37086, 256, 38583, 256, 20398, 256, 20711, 256, 20813, 256, + 21193, 256, 21220, 256, 21329, 256, 21917, 256, 22022, 256, 22120, 256, + 22592, 256, 22696, 256, 23652, 256, 23662, 256, 24724, 256, 24936, 256, + 24974, 256, 25074, 256, 25935, 256, 26082, 256, 26257, 256, 26757, 256, + 28023, 256, 28186, 256, 28450, 256, 29038, 256, 29227, 256, 29730, 256, + 30865, 256, 31038, 256, 31049, 256, 31048, 256, 31056, 256, 31062, 256, + 31069, 256, 31117, 256, 31118, 256, 31296, 256, 31361, 256, 31680, 256, + 32244, 256, 32265, 256, 32321, 256, 32626, 256, 32773, 256, 33261, 256, + 33401, 256, 33401, 256, 33879, 256, 35088, 256, 35222, 256, 35585, 256, + 35641, 256, 36051, 256, 36104, 256, 36790, 256, 36920, 256, 38627, 256, + 38911, 256, 38971, 256, 24693, 256, 148206, 256, 33304, 256, 20006, 256, + 20917, 256, 20840, 256, 20352, 256, 20805, 256, 20864, 256, 21191, 256, + 21242, 256, 21917, 256, 21845, 256, 21913, 256, 21986, 256, 22618, 256, + 22707, 256, 22852, 256, 22868, 256, 23138, 256, 23336, 256, 24274, 256, + 24281, 256, 24425, 256, 24493, 256, 24792, 256, 24910, 256, 24840, 256, + 24974, 256, 24928, 256, 25074, 256, 25140, 256, 25540, 256, 25628, 256, + 25682, 256, 25942, 256, 26228, 256, 26391, 256, 26395, 256, 26454, 256, + 27513, 256, 27578, 256, 27969, 256, 28379, 256, 28363, 256, 28450, 256, + 28702, 256, 29038, 256, 30631, 256, 29237, 256, 29359, 256, 29482, 256, + 29809, 256, 29958, 256, 30011, 256, 30237, 256, 30239, 256, 30410, 256, + 30427, 256, 30452, 256, 30538, 256, 30528, 256, 30924, 256, 31409, 256, + 31680, 256, 31867, 256, 32091, 256, 32244, 256, 32574, 256, 32773, 256, + 33618, 256, 33775, 256, 34681, 256, 35137, 256, 35206, 256, 35222, 256, + 35519, 256, 35576, 256, 35531, 256, 35585, 256, 35582, 256, 35565, 256, + 35641, 256, 35722, 256, 36104, 256, 36664, 256, 36978, 256, 37273, 256, + 37494, 256, 38524, 256, 38627, 256, 38742, 256, 38875, 256, 38911, 256, + 38923, 256, 38971, 256, 39698, 256, 40860, 256, 141386, 256, 141380, 256, + 144341, 256, 15261, 256, 16408, 256, 16441, 256, 152137, 256, 154832, + 256, 163539, 256, 40771, 256, 40846, 514, 102, 102, 514, 102, 105, 514, + 102, 108, 770, 102, 102, 105, 770, 102, 102, 108, 514, 383, 116, 514, + 115, 116, 514, 1396, 1398, 514, 1396, 1381, 514, 1396, 1387, 514, 1406, + 1398, 514, 1396, 1389, 512, 1497, 1460, 512, 1522, 1463, 262, 1506, 262, + 1488, 262, 1491, 262, 1492, 262, 1499, 262, 1500, 262, 1501, 262, 1512, + 262, 1514, 262, 43, 512, 1513, 1473, 512, 1513, 1474, 512, 64329, 1473, + 512, 64329, 1474, 512, 1488, 1463, 512, 1488, 1464, 512, 1488, 1468, 512, + 1489, 1468, 512, 1490, 1468, 512, 1491, 1468, 512, 1492, 1468, 512, 1493, + 1468, 512, 1494, 1468, 512, 1496, 1468, 512, 1497, 1468, 512, 1498, 1468, + 512, 1499, 1468, 512, 1500, 1468, 512, 1502, 1468, 512, 1504, 1468, 512, + 1505, 1468, 512, 1507, 1468, 512, 1508, 1468, 512, 1510, 1468, 512, 1511, + 1468, 512, 1512, 1468, 512, 1513, 1468, 512, 1514, 1468, 512, 1493, 1465, + 512, 1489, 1471, 512, 1499, 1471, 512, 1508, 1471, 514, 1488, 1500, 267, + 1649, 268, 1649, 267, 1659, 268, 1659, 269, 1659, 270, 1659, 267, 1662, + 268, 1662, 269, 1662, 270, 1662, 267, 1664, 268, 1664, 269, 1664, 270, + 1664, 267, 1658, 268, 1658, 269, 1658, 270, 1658, 267, 1663, 268, 1663, + 269, 1663, 270, 1663, 267, 1657, 268, 1657, 269, 1657, 270, 1657, 267, + 1700, 268, 1700, 269, 1700, 270, 1700, 267, 1702, 268, 1702, 269, 1702, + 270, 1702, 267, 1668, 268, 1668, 269, 1668, 270, 1668, 267, 1667, 268, + 1667, 269, 1667, 270, 1667, 267, 1670, 268, 1670, 269, 1670, 270, 1670, + 267, 1671, 268, 1671, 269, 1671, 270, 1671, 267, 1677, 268, 1677, 267, + 1676, 268, 1676, 267, 1678, 268, 1678, 267, 1672, 268, 1672, 267, 1688, + 268, 1688, 267, 1681, 268, 1681, 267, 1705, 268, 1705, 269, 1705, 270, + 1705, 267, 1711, 268, 1711, 269, 1711, 270, 1711, 267, 1715, 268, 1715, + 269, 1715, 270, 1715, 267, 1713, 268, 1713, 269, 1713, 270, 1713, 267, + 1722, 268, 1722, 267, 1723, 268, 1723, 269, 1723, 270, 1723, 267, 1728, + 268, 1728, 267, 1729, 268, 1729, 269, 1729, 270, 1729, 267, 1726, 268, + 1726, 269, 1726, 270, 1726, 267, 1746, 268, 1746, 267, 1747, 268, 1747, + 267, 1709, 268, 1709, 269, 1709, 270, 1709, 267, 1735, 268, 1735, 267, + 1734, 268, 1734, 267, 1736, 268, 1736, 267, 1655, 267, 1739, 268, 1739, + 267, 1733, 268, 1733, 267, 1737, 268, 1737, 267, 1744, 268, 1744, 269, + 1744, 270, 1744, 269, 1609, 270, 1609, 523, 1574, 1575, 524, 1574, 1575, + 523, 1574, 1749, 524, 1574, 1749, 523, 1574, 1608, 524, 1574, 1608, 523, + 1574, 1735, 524, 1574, 1735, 523, 1574, 1734, 524, 1574, 1734, 523, 1574, + 1736, 524, 1574, 1736, 523, 1574, 1744, 524, 1574, 1744, 525, 1574, 1744, + 523, 1574, 1609, 524, 1574, 1609, 525, 1574, 1609, 267, 1740, 268, 1740, + 269, 1740, 270, 1740, 523, 1574, 1580, 523, 1574, 1581, 523, 1574, 1605, + 523, 1574, 1609, 523, 1574, 1610, 523, 1576, 1580, 523, 1576, 1581, 523, + 1576, 1582, 523, 1576, 1605, 523, 1576, 1609, 523, 1576, 1610, 523, 1578, + 1580, 523, 1578, 1581, 523, 1578, 1582, 523, 1578, 1605, 523, 1578, 1609, + 523, 1578, 1610, 523, 1579, 1580, 523, 1579, 1605, 523, 1579, 1609, 523, + 1579, 1610, 523, 1580, 1581, 523, 1580, 1605, 523, 1581, 1580, 523, 1581, + 1605, 523, 1582, 1580, 523, 1582, 1581, 523, 1582, 1605, 523, 1587, 1580, + 523, 1587, 1581, 523, 1587, 1582, 523, 1587, 1605, 523, 1589, 1581, 523, + 1589, 1605, 523, 1590, 1580, 523, 1590, 1581, 523, 1590, 1582, 523, 1590, + 1605, 523, 1591, 1581, 523, 1591, 1605, 523, 1592, 1605, 523, 1593, 1580, + 523, 1593, 1605, 523, 1594, 1580, 523, 1594, 1605, 523, 1601, 1580, 523, + 1601, 1581, 523, 1601, 1582, 523, 1601, 1605, 523, 1601, 1609, 523, 1601, + 1610, 523, 1602, 1581, 523, 1602, 1605, 523, 1602, 1609, 523, 1602, 1610, + 523, 1603, 1575, 523, 1603, 1580, 523, 1603, 1581, 523, 1603, 1582, 523, + 1603, 1604, 523, 1603, 1605, 523, 1603, 1609, 523, 1603, 1610, 523, 1604, + 1580, 523, 1604, 1581, 523, 1604, 1582, 523, 1604, 1605, 523, 1604, 1609, + 523, 1604, 1610, 523, 1605, 1580, 523, 1605, 1581, 523, 1605, 1582, 523, + 1605, 1605, 523, 1605, 1609, 523, 1605, 1610, 523, 1606, 1580, 523, 1606, + 1581, 523, 1606, 1582, 523, 1606, 1605, 523, 1606, 1609, 523, 1606, 1610, + 523, 1607, 1580, 523, 1607, 1605, 523, 1607, 1609, 523, 1607, 1610, 523, + 1610, 1580, 523, 1610, 1581, 523, 1610, 1582, 523, 1610, 1605, 523, 1610, + 1609, 523, 1610, 1610, 523, 1584, 1648, 523, 1585, 1648, 523, 1609, 1648, + 779, 32, 1612, 1617, 779, 32, 1613, 1617, 779, 32, 1614, 1617, 779, 32, + 1615, 1617, 779, 32, 1616, 1617, 779, 32, 1617, 1648, 524, 1574, 1585, + 524, 1574, 1586, 524, 1574, 1605, 524, 1574, 1606, 524, 1574, 1609, 524, + 1574, 1610, 524, 1576, 1585, 524, 1576, 1586, 524, 1576, 1605, 524, 1576, + 1606, 524, 1576, 1609, 524, 1576, 1610, 524, 1578, 1585, 524, 1578, 1586, + 524, 1578, 1605, 524, 1578, 1606, 524, 1578, 1609, 524, 1578, 1610, 524, + 1579, 1585, 524, 1579, 1586, 524, 1579, 1605, 524, 1579, 1606, 524, 1579, + 1609, 524, 1579, 1610, 524, 1601, 1609, 524, 1601, 1610, 524, 1602, 1609, + 524, 1602, 1610, 524, 1603, 1575, 524, 1603, 1604, 524, 1603, 1605, 524, + 1603, 1609, 524, 1603, 1610, 524, 1604, 1605, 524, 1604, 1609, 524, 1604, + 1610, 524, 1605, 1575, 524, 1605, 1605, 524, 1606, 1585, 524, 1606, 1586, + 524, 1606, 1605, 524, 1606, 1606, 524, 1606, 1609, 524, 1606, 1610, 524, + 1609, 1648, 524, 1610, 1585, 524, 1610, 1586, 524, 1610, 1605, 524, 1610, + 1606, 524, 1610, 1609, 524, 1610, 1610, 525, 1574, 1580, 525, 1574, 1581, + 525, 1574, 1582, 525, 1574, 1605, 525, 1574, 1607, 525, 1576, 1580, 525, + 1576, 1581, 525, 1576, 1582, 525, 1576, 1605, 525, 1576, 1607, 525, 1578, + 1580, 525, 1578, 1581, 525, 1578, 1582, 525, 1578, 1605, 525, 1578, 1607, + 525, 1579, 1605, 525, 1580, 1581, 525, 1580, 1605, 525, 1581, 1580, 525, + 1581, 1605, 525, 1582, 1580, 525, 1582, 1605, 525, 1587, 1580, 525, 1587, + 1581, 525, 1587, 1582, 525, 1587, 1605, 525, 1589, 1581, 525, 1589, 1582, + 525, 1589, 1605, 525, 1590, 1580, 525, 1590, 1581, 525, 1590, 1582, 525, + 1590, 1605, 525, 1591, 1581, 525, 1592, 1605, 525, 1593, 1580, 525, 1593, + 1605, 525, 1594, 1580, 525, 1594, 1605, 525, 1601, 1580, 525, 1601, 1581, + 525, 1601, 1582, 525, 1601, 1605, 525, 1602, 1581, 525, 1602, 1605, 525, + 1603, 1580, 525, 1603, 1581, 525, 1603, 1582, 525, 1603, 1604, 525, 1603, + 1605, 525, 1604, 1580, 525, 1604, 1581, 525, 1604, 1582, 525, 1604, 1605, + 525, 1604, 1607, 525, 1605, 1580, 525, 1605, 1581, 525, 1605, 1582, 525, + 1605, 1605, 525, 1606, 1580, 525, 1606, 1581, 525, 1606, 1582, 525, 1606, + 1605, 525, 1606, 1607, 525, 1607, 1580, 525, 1607, 1605, 525, 1607, 1648, + 525, 1610, 1580, 525, 1610, 1581, 525, 1610, 1582, 525, 1610, 1605, 525, + 1610, 1607, 526, 1574, 1605, 526, 1574, 1607, 526, 1576, 1605, 526, 1576, + 1607, 526, 1578, 1605, 526, 1578, 1607, 526, 1579, 1605, 526, 1579, 1607, + 526, 1587, 1605, 526, 1587, 1607, 526, 1588, 1605, 526, 1588, 1607, 526, + 1603, 1604, 526, 1603, 1605, 526, 1604, 1605, 526, 1606, 1605, 526, 1606, + 1607, 526, 1610, 1605, 526, 1610, 1607, 782, 1600, 1614, 1617, 782, 1600, + 1615, 1617, 782, 1600, 1616, 1617, 523, 1591, 1609, 523, 1591, 1610, 523, + 1593, 1609, 523, 1593, 1610, 523, 1594, 1609, 523, 1594, 1610, 523, 1587, + 1609, 523, 1587, 1610, 523, 1588, 1609, 523, 1588, 1610, 523, 1581, 1609, + 523, 1581, 1610, 523, 1580, 1609, 523, 1580, 1610, 523, 1582, 1609, 523, + 1582, 1610, 523, 1589, 1609, 523, 1589, 1610, 523, 1590, 1609, 523, 1590, + 1610, 523, 1588, 1580, 523, 1588, 1581, 523, 1588, 1582, 523, 1588, 1605, + 523, 1588, 1585, 523, 1587, 1585, 523, 1589, 1585, 523, 1590, 1585, 524, + 1591, 1609, 524, 1591, 1610, 524, 1593, 1609, 524, 1593, 1610, 524, 1594, + 1609, 524, 1594, 1610, 524, 1587, 1609, 524, 1587, 1610, 524, 1588, 1609, + 524, 1588, 1610, 524, 1581, 1609, 524, 1581, 1610, 524, 1580, 1609, 524, + 1580, 1610, 524, 1582, 1609, 524, 1582, 1610, 524, 1589, 1609, 524, 1589, + 1610, 524, 1590, 1609, 524, 1590, 1610, 524, 1588, 1580, 524, 1588, 1581, + 524, 1588, 1582, 524, 1588, 1605, 524, 1588, 1585, 524, 1587, 1585, 524, + 1589, 1585, 524, 1590, 1585, 525, 1588, 1580, 525, 1588, 1581, 525, 1588, + 1582, 525, 1588, 1605, 525, 1587, 1607, 525, 1588, 1607, 525, 1591, 1605, + 526, 1587, 1580, 526, 1587, 1581, 526, 1587, 1582, 526, 1588, 1580, 526, + 1588, 1581, 526, 1588, 1582, 526, 1591, 1605, 526, 1592, 1605, 524, 1575, + 1611, 523, 1575, 1611, 781, 1578, 1580, 1605, 780, 1578, 1581, 1580, 781, + 1578, 1581, 1580, 781, 1578, 1581, 1605, 781, 1578, 1582, 1605, 781, + 1578, 1605, 1580, 781, 1578, 1605, 1581, 781, 1578, 1605, 1582, 780, + 1580, 1605, 1581, 781, 1580, 1605, 1581, 780, 1581, 1605, 1610, 780, + 1581, 1605, 1609, 781, 1587, 1581, 1580, 781, 1587, 1580, 1581, 780, + 1587, 1580, 1609, 780, 1587, 1605, 1581, 781, 1587, 1605, 1581, 781, + 1587, 1605, 1580, 780, 1587, 1605, 1605, 781, 1587, 1605, 1605, 780, + 1589, 1581, 1581, 781, 1589, 1581, 1581, 780, 1589, 1605, 1605, 780, + 1588, 1581, 1605, 781, 1588, 1581, 1605, 780, 1588, 1580, 1610, 780, + 1588, 1605, 1582, 781, 1588, 1605, 1582, 780, 1588, 1605, 1605, 781, + 1588, 1605, 1605, 780, 1590, 1581, 1609, 780, 1590, 1582, 1605, 781, + 1590, 1582, 1605, 780, 1591, 1605, 1581, 781, 1591, 1605, 1581, 781, + 1591, 1605, 1605, 780, 1591, 1605, 1610, 780, 1593, 1580, 1605, 780, + 1593, 1605, 1605, 781, 1593, 1605, 1605, 780, 1593, 1605, 1609, 780, + 1594, 1605, 1605, 780, 1594, 1605, 1610, 780, 1594, 1605, 1609, 780, + 1601, 1582, 1605, 781, 1601, 1582, 1605, 780, 1602, 1605, 1581, 780, + 1602, 1605, 1605, 780, 1604, 1581, 1605, 780, 1604, 1581, 1610, 780, + 1604, 1581, 1609, 781, 1604, 1580, 1580, 780, 1604, 1580, 1580, 780, + 1604, 1582, 1605, 781, 1604, 1582, 1605, 780, 1604, 1605, 1581, 781, + 1604, 1605, 1581, 781, 1605, 1581, 1580, 781, 1605, 1581, 1605, 780, + 1605, 1581, 1610, 781, 1605, 1580, 1581, 781, 1605, 1580, 1605, 781, + 1605, 1582, 1580, 781, 1605, 1582, 1605, 781, 1605, 1580, 1582, 781, + 1607, 1605, 1580, 781, 1607, 1605, 1605, 781, 1606, 1581, 1605, 780, + 1606, 1581, 1609, 780, 1606, 1580, 1605, 781, 1606, 1580, 1605, 780, + 1606, 1580, 1609, 780, 1606, 1605, 1610, 780, 1606, 1605, 1609, 780, + 1610, 1605, 1605, 781, 1610, 1605, 1605, 780, 1576, 1582, 1610, 780, + 1578, 1580, 1610, 780, 1578, 1580, 1609, 780, 1578, 1582, 1610, 780, + 1578, 1582, 1609, 780, 1578, 1605, 1610, 780, 1578, 1605, 1609, 780, + 1580, 1605, 1610, 780, 1580, 1581, 1609, 780, 1580, 1605, 1609, 780, + 1587, 1582, 1609, 780, 1589, 1581, 1610, 780, 1588, 1581, 1610, 780, + 1590, 1581, 1610, 780, 1604, 1580, 1610, 780, 1604, 1605, 1610, 780, + 1610, 1581, 1610, 780, 1610, 1580, 1610, 780, 1610, 1605, 1610, 780, + 1605, 1605, 1610, 780, 1602, 1605, 1610, 780, 1606, 1581, 1610, 781, + 1602, 1605, 1581, 781, 1604, 1581, 1605, 780, 1593, 1605, 1610, 780, + 1603, 1605, 1610, 781, 1606, 1580, 1581, 780, 1605, 1582, 1610, 781, + 1604, 1580, 1605, 780, 1603, 1605, 1605, 780, 1604, 1580, 1605, 780, + 1606, 1580, 1581, 780, 1580, 1581, 1610, 780, 1581, 1580, 1610, 780, + 1605, 1580, 1610, 780, 1601, 1605, 1610, 780, 1576, 1581, 1610, 781, + 1603, 1605, 1605, 781, 1593, 1580, 1605, 781, 1589, 1605, 1605, 780, + 1587, 1582, 1610, 780, 1606, 1580, 1610, 779, 1589, 1604, 1746, 779, + 1602, 1604, 1746, 1035, 1575, 1604, 1604, 1607, 1035, 1575, 1603, 1576, + 1585, 1035, 1605, 1581, 1605, 1583, 1035, 1589, 1604, 1593, 1605, 1035, + 1585, 1587, 1608, 1604, 1035, 1593, 1604, 1610, 1607, 1035, 1608, 1587, + 1604, 1605, 779, 1589, 1604, 1609, 4619, 1589, 1604, 1609, 32, 1575, + 1604, 1604, 1607, 32, 1593, 1604, 1610, 1607, 32, 1608, 1587, 1604, 1605, + 2059, 1580, 1604, 32, 1580, 1604, 1575, 1604, 1607, 1035, 1585, 1740, + 1575, 1604, 265, 44, 265, 12289, 265, 12290, 265, 58, 265, 59, 265, 33, + 265, 63, 265, 12310, 265, 12311, 265, 8230, 265, 8229, 265, 8212, 265, + 8211, 265, 95, 265, 95, 265, 40, 265, 41, 265, 123, 265, 125, 265, 12308, + 265, 12309, 265, 12304, 265, 12305, 265, 12298, 265, 12299, 265, 12296, + 265, 12297, 265, 12300, 265, 12301, 265, 12302, 265, 12303, 265, 91, 265, + 93, 258, 8254, 258, 8254, 258, 8254, 258, 8254, 258, 95, 258, 95, 258, + 95, 271, 44, 271, 12289, 271, 46, 271, 59, 271, 58, 271, 63, 271, 33, + 271, 8212, 271, 40, 271, 41, 271, 123, 271, 125, 271, 12308, 271, 12309, + 271, 35, 271, 38, 271, 42, 271, 43, 271, 45, 271, 60, 271, 62, 271, 61, + 271, 92, 271, 36, 271, 37, 271, 64, 523, 32, 1611, 526, 1600, 1611, 523, + 32, 1612, 523, 32, 1613, 523, 32, 1614, 526, 1600, 1614, 523, 32, 1615, + 526, 1600, 1615, 523, 32, 1616, 526, 1600, 1616, 523, 32, 1617, 526, + 1600, 1617, 523, 32, 1618, 526, 1600, 1618, 267, 1569, 267, 1570, 268, + 1570, 267, 1571, 268, 1571, 267, 1572, 268, 1572, 267, 1573, 268, 1573, + 267, 1574, 268, 1574, 269, 1574, 270, 1574, 267, 1575, 268, 1575, 267, + 1576, 268, 1576, 269, 1576, 270, 1576, 267, 1577, 268, 1577, 267, 1578, + 268, 1578, 269, 1578, 270, 1578, 267, 1579, 268, 1579, 269, 1579, 270, + 1579, 267, 1580, 268, 1580, 269, 1580, 270, 1580, 267, 1581, 268, 1581, + 269, 1581, 270, 1581, 267, 1582, 268, 1582, 269, 1582, 270, 1582, 267, + 1583, 268, 1583, 267, 1584, 268, 1584, 267, 1585, 268, 1585, 267, 1586, + 268, 1586, 267, 1587, 268, 1587, 269, 1587, 270, 1587, 267, 1588, 268, + 1588, 269, 1588, 270, 1588, 267, 1589, 268, 1589, 269, 1589, 270, 1589, + 267, 1590, 268, 1590, 269, 1590, 270, 1590, 267, 1591, 268, 1591, 269, + 1591, 270, 1591, 267, 1592, 268, 1592, 269, 1592, 270, 1592, 267, 1593, + 268, 1593, 269, 1593, 270, 1593, 267, 1594, 268, 1594, 269, 1594, 270, + 1594, 267, 1601, 268, 1601, 269, 1601, 270, 1601, 267, 1602, 268, 1602, + 269, 1602, 270, 1602, 267, 1603, 268, 1603, 269, 1603, 270, 1603, 267, + 1604, 268, 1604, 269, 1604, 270, 1604, 267, 1605, 268, 1605, 269, 1605, + 270, 1605, 267, 1606, 268, 1606, 269, 1606, 270, 1606, 267, 1607, 268, + 1607, 269, 1607, 270, 1607, 267, 1608, 268, 1608, 267, 1609, 268, 1609, + 267, 1610, 268, 1610, 269, 1610, 270, 1610, 523, 1604, 1570, 524, 1604, + 1570, 523, 1604, 1571, 524, 1604, 1571, 523, 1604, 1573, 524, 1604, 1573, + 523, 1604, 1575, 524, 1604, 1575, 264, 33, 264, 34, 264, 35, 264, 36, + 264, 37, 264, 38, 264, 39, 264, 40, 264, 41, 264, 42, 264, 43, 264, 44, + 264, 45, 264, 46, 264, 47, 264, 48, 264, 49, 264, 50, 264, 51, 264, 52, + 264, 53, 264, 54, 264, 55, 264, 56, 264, 57, 264, 58, 264, 59, 264, 60, + 264, 61, 264, 62, 264, 63, 264, 64, 264, 65, 264, 66, 264, 67, 264, 68, + 264, 69, 264, 70, 264, 71, 264, 72, 264, 73, 264, 74, 264, 75, 264, 76, + 264, 77, 264, 78, 264, 79, 264, 80, 264, 81, 264, 82, 264, 83, 264, 84, + 264, 85, 264, 86, 264, 87, 264, 88, 264, 89, 264, 90, 264, 91, 264, 92, + 264, 93, 264, 94, 264, 95, 264, 96, 264, 97, 264, 98, 264, 99, 264, 100, + 264, 101, 264, 102, 264, 103, 264, 104, 264, 105, 264, 106, 264, 107, + 264, 108, 264, 109, 264, 110, 264, 111, 264, 112, 264, 113, 264, 114, + 264, 115, 264, 116, 264, 117, 264, 118, 264, 119, 264, 120, 264, 121, + 264, 122, 264, 123, 264, 124, 264, 125, 264, 126, 264, 10629, 264, 10630, + 272, 12290, 272, 12300, 272, 12301, 272, 12289, 272, 12539, 272, 12530, + 272, 12449, 272, 12451, 272, 12453, 272, 12455, 272, 12457, 272, 12515, + 272, 12517, 272, 12519, 272, 12483, 272, 12540, 272, 12450, 272, 12452, + 272, 12454, 272, 12456, 272, 12458, 272, 12459, 272, 12461, 272, 12463, + 272, 12465, 272, 12467, 272, 12469, 272, 12471, 272, 12473, 272, 12475, + 272, 12477, 272, 12479, 272, 12481, 272, 12484, 272, 12486, 272, 12488, + 272, 12490, 272, 12491, 272, 12492, 272, 12493, 272, 12494, 272, 12495, + 272, 12498, 272, 12501, 272, 12504, 272, 12507, 272, 12510, 272, 12511, + 272, 12512, 272, 12513, 272, 12514, 272, 12516, 272, 12518, 272, 12520, + 272, 12521, 272, 12522, 272, 12523, 272, 12524, 272, 12525, 272, 12527, + 272, 12531, 272, 12441, 272, 12442, 272, 12644, 272, 12593, 272, 12594, + 272, 12595, 272, 12596, 272, 12597, 272, 12598, 272, 12599, 272, 12600, + 272, 12601, 272, 12602, 272, 12603, 272, 12604, 272, 12605, 272, 12606, + 272, 12607, 272, 12608, 272, 12609, 272, 12610, 272, 12611, 272, 12612, + 272, 12613, 272, 12614, 272, 12615, 272, 12616, 272, 12617, 272, 12618, + 272, 12619, 272, 12620, 272, 12621, 272, 12622, 272, 12623, 272, 12624, + 272, 12625, 272, 12626, 272, 12627, 272, 12628, 272, 12629, 272, 12630, + 272, 12631, 272, 12632, 272, 12633, 272, 12634, 272, 12635, 272, 12636, + 272, 12637, 272, 12638, 272, 12639, 272, 12640, 272, 12641, 272, 12642, + 272, 12643, 264, 162, 264, 163, 264, 172, 264, 175, 264, 166, 264, 165, + 264, 8361, 272, 9474, 272, 8592, 272, 8593, 272, 8594, 272, 8595, 272, + 9632, 272, 9675, 512, 69785, 69818, 512, 69787, 69818, 512, 69797, 69818, + 512, 69937, 69927, 512, 69938, 69927, 512, 70471, 70462, 512, 70471, + 70487, 512, 70841, 70842, 512, 70841, 70832, 512, 70841, 70845, 512, + 71096, 71087, 512, 71097, 71087, 512, 119127, 119141, 512, 119128, + 119141, 512, 119135, 119150, 512, 119135, 119151, 512, 119135, 119152, + 512, 119135, 119153, 512, 119135, 119154, 512, 119225, 119141, 512, + 119226, 119141, 512, 119227, 119150, 512, 119228, 119150, 512, 119227, + 119151, 512, 119228, 119151, 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, + 262, 70, 262, 71, 262, 72, 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, + 262, 78, 262, 79, 262, 80, 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, + 262, 86, 262, 87, 262, 88, 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, + 262, 100, 262, 101, 262, 102, 262, 103, 262, 104, 262, 105, 262, 106, + 262, 107, 262, 108, 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, + 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, + 262, 121, 262, 122, 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, + 262, 71, 262, 72, 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, + 262, 79, 262, 80, 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, + 262, 87, 262, 88, 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, + 262, 101, 262, 102, 262, 103, 262, 105, 262, 106, 262, 107, 262, 108, 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122, - 262, 65, 262, 67, 262, 68, 262, 71, 262, 74, 262, 75, 262, 78, 262, 79, - 262, 80, 262, 81, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, - 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 102, 262, - 104, 262, 105, 262, 106, 262, 107, 262, 108, 262, 109, 262, 110, 262, - 112, 262, 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, 262, - 119, 262, 120, 262, 121, 262, 122, 262, 65, 262, 66, 262, 67, 262, 68, - 262, 69, 262, 70, 262, 71, 262, 72, 262, 73, 262, 74, 262, 75, 262, 76, - 262, 77, 262, 78, 262, 79, 262, 80, 262, 81, 262, 82, 262, 83, 262, 84, - 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 90, 262, 97, 262, 98, - 262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, 104, 262, 105, 262, - 106, 262, 107, 262, 108, 262, 109, 262, 110, 262, 111, 262, 112, 262, - 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, 262, 119, 262, - 120, 262, 121, 262, 122, 262, 65, 262, 66, 262, 68, 262, 69, 262, 70, - 262, 71, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 262, 80, + 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, 71, 262, 72, + 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 262, 80, + 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, + 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262, + 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, 262, 108, 262, + 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, 262, + 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122, 262, 65, + 262, 67, 262, 68, 262, 71, 262, 74, 262, 75, 262, 78, 262, 79, 262, 80, 262, 81, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, - 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, - 104, 262, 105, 262, 106, 262, 107, 262, 108, 262, 109, 262, 110, 262, - 111, 262, 112, 262, 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, - 118, 262, 119, 262, 120, 262, 121, 262, 122, 262, 65, 262, 66, 262, 68, - 262, 69, 262, 70, 262, 71, 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, - 262, 79, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, - 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, - 104, 262, 105, 262, 106, 262, 107, 262, 108, 262, 109, 262, 110, 262, - 111, 262, 112, 262, 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, - 118, 262, 119, 262, 120, 262, 121, 262, 122, 262, 65, 262, 66, 262, 67, - 262, 68, 262, 69, 262, 70, 262, 71, 262, 72, 262, 73, 262, 74, 262, 75, - 262, 76, 262, 77, 262, 78, 262, 79, 262, 80, 262, 81, 262, 82, 262, 83, - 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 90, 262, 97, + 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 102, 262, 104, 262, + 105, 262, 106, 262, 107, 262, 108, 262, 109, 262, 110, 262, 112, 262, + 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, 262, 119, 262, + 120, 262, 121, 262, 122, 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, + 262, 70, 262, 71, 262, 72, 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, + 262, 78, 262, 79, 262, 80, 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, + 262, 86, 262, 87, 262, 88, 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, + 262, 100, 262, 101, 262, 102, 262, 103, 262, 104, 262, 105, 262, 106, + 262, 107, 262, 108, 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, + 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, + 262, 121, 262, 122, 262, 65, 262, 66, 262, 68, 262, 69, 262, 70, 262, 71, + 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 262, 80, 262, 81, + 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 97, + 262, 98, 262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, 104, 262, + 105, 262, 106, 262, 107, 262, 108, 262, 109, 262, 110, 262, 111, 262, + 112, 262, 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, 262, + 119, 262, 120, 262, 121, 262, 122, 262, 65, 262, 66, 262, 68, 262, 69, + 262, 70, 262, 71, 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 79, + 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, 262, 108, 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, 262, @@ -3536,33 +3822,15 @@ static unsigned int decomp_data[] = { 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, 262, 108, 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, 262, - 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122, 262, - 305, 262, 567, 262, 913, 262, 914, 262, 915, 262, 916, 262, 917, 262, - 918, 262, 919, 262, 920, 262, 921, 262, 922, 262, 923, 262, 924, 262, - 925, 262, 926, 262, 927, 262, 928, 262, 929, 262, 1012, 262, 931, 262, - 932, 262, 933, 262, 934, 262, 935, 262, 936, 262, 937, 262, 8711, 262, - 945, 262, 946, 262, 947, 262, 948, 262, 949, 262, 950, 262, 951, 262, - 952, 262, 953, 262, 954, 262, 955, 262, 956, 262, 957, 262, 958, 262, - 959, 262, 960, 262, 961, 262, 962, 262, 963, 262, 964, 262, 965, 262, - 966, 262, 967, 262, 968, 262, 969, 262, 8706, 262, 1013, 262, 977, 262, - 1008, 262, 981, 262, 1009, 262, 982, 262, 913, 262, 914, 262, 915, 262, - 916, 262, 917, 262, 918, 262, 919, 262, 920, 262, 921, 262, 922, 262, - 923, 262, 924, 262, 925, 262, 926, 262, 927, 262, 928, 262, 929, 262, - 1012, 262, 931, 262, 932, 262, 933, 262, 934, 262, 935, 262, 936, 262, - 937, 262, 8711, 262, 945, 262, 946, 262, 947, 262, 948, 262, 949, 262, - 950, 262, 951, 262, 952, 262, 953, 262, 954, 262, 955, 262, 956, 262, - 957, 262, 958, 262, 959, 262, 960, 262, 961, 262, 962, 262, 963, 262, - 964, 262, 965, 262, 966, 262, 967, 262, 968, 262, 969, 262, 8706, 262, - 1013, 262, 977, 262, 1008, 262, 981, 262, 1009, 262, 982, 262, 913, 262, - 914, 262, 915, 262, 916, 262, 917, 262, 918, 262, 919, 262, 920, 262, - 921, 262, 922, 262, 923, 262, 924, 262, 925, 262, 926, 262, 927, 262, - 928, 262, 929, 262, 1012, 262, 931, 262, 932, 262, 933, 262, 934, 262, - 935, 262, 936, 262, 937, 262, 8711, 262, 945, 262, 946, 262, 947, 262, - 948, 262, 949, 262, 950, 262, 951, 262, 952, 262, 953, 262, 954, 262, - 955, 262, 956, 262, 957, 262, 958, 262, 959, 262, 960, 262, 961, 262, - 962, 262, 963, 262, 964, 262, 965, 262, 966, 262, 967, 262, 968, 262, - 969, 262, 8706, 262, 1013, 262, 977, 262, 1008, 262, 981, 262, 1009, 262, - 982, 262, 913, 262, 914, 262, 915, 262, 916, 262, 917, 262, 918, 262, + 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122, 262, 65, + 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, 71, 262, 72, 262, 73, + 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 262, 80, 262, 81, + 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, + 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262, 102, 262, + 103, 262, 104, 262, 105, 262, 106, 262, 107, 262, 108, 262, 109, 262, + 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, 262, 116, 262, + 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122, 262, 305, 262, + 567, 262, 913, 262, 914, 262, 915, 262, 916, 262, 917, 262, 918, 262, 919, 262, 920, 262, 921, 262, 922, 262, 923, 262, 924, 262, 925, 262, 926, 262, 927, 262, 928, 262, 929, 262, 1012, 262, 931, 262, 932, 262, 933, 262, 934, 262, 935, 262, 936, 262, 937, 262, 8711, 262, 945, 262, @@ -3578,427 +3846,329 @@ static unsigned int decomp_data[] = { 951, 262, 952, 262, 953, 262, 954, 262, 955, 262, 956, 262, 957, 262, 958, 262, 959, 262, 960, 262, 961, 262, 962, 262, 963, 262, 964, 262, 965, 262, 966, 262, 967, 262, 968, 262, 969, 262, 8706, 262, 1013, 262, - 977, 262, 1008, 262, 981, 262, 1009, 262, 982, 262, 988, 262, 989, 262, - 48, 262, 49, 262, 50, 262, 51, 262, 52, 262, 53, 262, 54, 262, 55, 262, - 56, 262, 57, 262, 48, 262, 49, 262, 50, 262, 51, 262, 52, 262, 53, 262, - 54, 262, 55, 262, 56, 262, 57, 262, 48, 262, 49, 262, 50, 262, 51, 262, - 52, 262, 53, 262, 54, 262, 55, 262, 56, 262, 57, 262, 48, 262, 49, 262, - 50, 262, 51, 262, 52, 262, 53, 262, 54, 262, 55, 262, 56, 262, 57, 262, - 48, 262, 49, 262, 50, 262, 51, 262, 52, 262, 53, 262, 54, 262, 55, 262, - 56, 262, 57, 262, 1575, 262, 1576, 262, 1580, 262, 1583, 262, 1608, 262, - 1586, 262, 1581, 262, 1591, 262, 1610, 262, 1603, 262, 1604, 262, 1605, - 262, 1606, 262, 1587, 262, 1593, 262, 1601, 262, 1589, 262, 1602, 262, - 1585, 262, 1588, 262, 1578, 262, 1579, 262, 1582, 262, 1584, 262, 1590, - 262, 1592, 262, 1594, 262, 1646, 262, 1722, 262, 1697, 262, 1647, 262, - 1576, 262, 1580, 262, 1607, 262, 1581, 262, 1610, 262, 1603, 262, 1604, - 262, 1605, 262, 1606, 262, 1587, 262, 1593, 262, 1601, 262, 1589, 262, - 1602, 262, 1588, 262, 1578, 262, 1579, 262, 1582, 262, 1590, 262, 1594, - 262, 1580, 262, 1581, 262, 1610, 262, 1604, 262, 1606, 262, 1587, 262, - 1593, 262, 1589, 262, 1602, 262, 1588, 262, 1582, 262, 1590, 262, 1594, - 262, 1722, 262, 1647, 262, 1576, 262, 1580, 262, 1607, 262, 1581, 262, - 1591, 262, 1610, 262, 1603, 262, 1605, 262, 1606, 262, 1587, 262, 1593, - 262, 1601, 262, 1589, 262, 1602, 262, 1588, 262, 1578, 262, 1579, 262, - 1582, 262, 1590, 262, 1592, 262, 1594, 262, 1646, 262, 1697, 262, 1575, - 262, 1576, 262, 1580, 262, 1583, 262, 1607, 262, 1608, 262, 1586, 262, - 1581, 262, 1591, 262, 1610, 262, 1604, 262, 1605, 262, 1606, 262, 1587, - 262, 1593, 262, 1601, 262, 1589, 262, 1602, 262, 1585, 262, 1588, 262, - 1578, 262, 1579, 262, 1582, 262, 1584, 262, 1590, 262, 1592, 262, 1594, - 262, 1576, 262, 1580, 262, 1583, 262, 1608, 262, 1586, 262, 1581, 262, - 1591, 262, 1610, 262, 1604, 262, 1605, 262, 1606, 262, 1587, 262, 1593, - 262, 1601, 262, 1589, 262, 1602, 262, 1585, 262, 1588, 262, 1578, 262, - 1579, 262, 1582, 262, 1584, 262, 1590, 262, 1592, 262, 1594, 514, 48, 46, - 514, 48, 44, 514, 49, 44, 514, 50, 44, 514, 51, 44, 514, 52, 44, 514, 53, - 44, 514, 54, 44, 514, 55, 44, 514, 56, 44, 514, 57, 44, 770, 40, 65, 41, - 770, 40, 66, 41, 770, 40, 67, 41, 770, 40, 68, 41, 770, 40, 69, 41, 770, - 40, 70, 41, 770, 40, 71, 41, 770, 40, 72, 41, 770, 40, 73, 41, 770, 40, - 74, 41, 770, 40, 75, 41, 770, 40, 76, 41, 770, 40, 77, 41, 770, 40, 78, - 41, 770, 40, 79, 41, 770, 40, 80, 41, 770, 40, 81, 41, 770, 40, 82, 41, - 770, 40, 83, 41, 770, 40, 84, 41, 770, 40, 85, 41, 770, 40, 86, 41, 770, - 40, 87, 41, 770, 40, 88, 41, 770, 40, 89, 41, 770, 40, 90, 41, 770, - 12308, 83, 12309, 263, 67, 263, 82, 519, 67, 68, 519, 87, 90, 266, 65, - 266, 66, 266, 67, 266, 68, 266, 69, 266, 70, 266, 71, 266, 72, 266, 73, - 266, 74, 266, 75, 266, 76, 266, 77, 266, 78, 266, 79, 266, 80, 266, 81, - 266, 82, 266, 83, 266, 84, 266, 85, 266, 86, 266, 87, 266, 88, 266, 89, - 266, 90, 522, 72, 86, 522, 77, 86, 522, 83, 68, 522, 83, 83, 778, 80, 80, - 86, 522, 87, 67, 515, 77, 67, 515, 77, 68, 522, 68, 74, 522, 12411, - 12363, 522, 12467, 12467, 266, 12469, 266, 25163, 266, 23383, 266, 21452, - 266, 12487, 266, 20108, 266, 22810, 266, 35299, 266, 22825, 266, 20132, - 266, 26144, 266, 28961, 266, 26009, 266, 21069, 266, 24460, 266, 20877, - 266, 26032, 266, 21021, 266, 32066, 266, 29983, 266, 36009, 266, 22768, - 266, 21561, 266, 28436, 266, 25237, 266, 25429, 266, 19968, 266, 19977, - 266, 36938, 266, 24038, 266, 20013, 266, 21491, 266, 25351, 266, 36208, - 266, 25171, 266, 31105, 266, 31354, 266, 21512, 266, 28288, 266, 26377, - 266, 26376, 266, 30003, 266, 21106, 266, 21942, 770, 12308, 26412, 12309, - 770, 12308, 19977, 12309, 770, 12308, 20108, 12309, 770, 12308, 23433, - 12309, 770, 12308, 28857, 12309, 770, 12308, 25171, 12309, 770, 12308, - 30423, 12309, 770, 12308, 21213, 12309, 770, 12308, 25943, 12309, 263, - 24471, 263, 21487, 256, 20029, 256, 20024, 256, 20033, 256, 131362, 256, - 20320, 256, 20398, 256, 20411, 256, 20482, 256, 20602, 256, 20633, 256, - 20711, 256, 20687, 256, 13470, 256, 132666, 256, 20813, 256, 20820, 256, - 20836, 256, 20855, 256, 132380, 256, 13497, 256, 20839, 256, 20877, 256, - 132427, 256, 20887, 256, 20900, 256, 20172, 256, 20908, 256, 20917, 256, - 168415, 256, 20981, 256, 20995, 256, 13535, 256, 21051, 256, 21062, 256, - 21106, 256, 21111, 256, 13589, 256, 21191, 256, 21193, 256, 21220, 256, - 21242, 256, 21253, 256, 21254, 256, 21271, 256, 21321, 256, 21329, 256, - 21338, 256, 21363, 256, 21373, 256, 21375, 256, 21375, 256, 21375, 256, - 133676, 256, 28784, 256, 21450, 256, 21471, 256, 133987, 256, 21483, 256, - 21489, 256, 21510, 256, 21662, 256, 21560, 256, 21576, 256, 21608, 256, - 21666, 256, 21750, 256, 21776, 256, 21843, 256, 21859, 256, 21892, 256, - 21892, 256, 21913, 256, 21931, 256, 21939, 256, 21954, 256, 22294, 256, - 22022, 256, 22295, 256, 22097, 256, 22132, 256, 20999, 256, 22766, 256, - 22478, 256, 22516, 256, 22541, 256, 22411, 256, 22578, 256, 22577, 256, - 22700, 256, 136420, 256, 22770, 256, 22775, 256, 22790, 256, 22810, 256, - 22818, 256, 22882, 256, 136872, 256, 136938, 256, 23020, 256, 23067, 256, - 23079, 256, 23000, 256, 23142, 256, 14062, 256, 14076, 256, 23304, 256, - 23358, 256, 23358, 256, 137672, 256, 23491, 256, 23512, 256, 23527, 256, - 23539, 256, 138008, 256, 23551, 256, 23558, 256, 24403, 256, 23586, 256, - 14209, 256, 23648, 256, 23662, 256, 23744, 256, 23693, 256, 138724, 256, - 23875, 256, 138726, 256, 23918, 256, 23915, 256, 23932, 256, 24033, 256, - 24034, 256, 14383, 256, 24061, 256, 24104, 256, 24125, 256, 24169, 256, - 14434, 256, 139651, 256, 14460, 256, 24240, 256, 24243, 256, 24246, 256, - 24266, 256, 172946, 256, 24318, 256, 140081, 256, 140081, 256, 33281, - 256, 24354, 256, 24354, 256, 14535, 256, 144056, 256, 156122, 256, 24418, - 256, 24427, 256, 14563, 256, 24474, 256, 24525, 256, 24535, 256, 24569, - 256, 24705, 256, 14650, 256, 14620, 256, 24724, 256, 141012, 256, 24775, - 256, 24904, 256, 24908, 256, 24910, 256, 24908, 256, 24954, 256, 24974, - 256, 25010, 256, 24996, 256, 25007, 256, 25054, 256, 25074, 256, 25078, - 256, 25104, 256, 25115, 256, 25181, 256, 25265, 256, 25300, 256, 25424, - 256, 142092, 256, 25405, 256, 25340, 256, 25448, 256, 25475, 256, 25572, - 256, 142321, 256, 25634, 256, 25541, 256, 25513, 256, 14894, 256, 25705, - 256, 25726, 256, 25757, 256, 25719, 256, 14956, 256, 25935, 256, 25964, - 256, 143370, 256, 26083, 256, 26360, 256, 26185, 256, 15129, 256, 26257, - 256, 15112, 256, 15076, 256, 20882, 256, 20885, 256, 26368, 256, 26268, - 256, 32941, 256, 17369, 256, 26391, 256, 26395, 256, 26401, 256, 26462, - 256, 26451, 256, 144323, 256, 15177, 256, 26618, 256, 26501, 256, 26706, - 256, 26757, 256, 144493, 256, 26766, 256, 26655, 256, 26900, 256, 15261, - 256, 26946, 256, 27043, 256, 27114, 256, 27304, 256, 145059, 256, 27355, - 256, 15384, 256, 27425, 256, 145575, 256, 27476, 256, 15438, 256, 27506, - 256, 27551, 256, 27578, 256, 27579, 256, 146061, 256, 138507, 256, - 146170, 256, 27726, 256, 146620, 256, 27839, 256, 27853, 256, 27751, 256, - 27926, 256, 27966, 256, 28023, 256, 27969, 256, 28009, 256, 28024, 256, - 28037, 256, 146718, 256, 27956, 256, 28207, 256, 28270, 256, 15667, 256, - 28363, 256, 28359, 256, 147153, 256, 28153, 256, 28526, 256, 147294, 256, - 147342, 256, 28614, 256, 28729, 256, 28702, 256, 28699, 256, 15766, 256, - 28746, 256, 28797, 256, 28791, 256, 28845, 256, 132389, 256, 28997, 256, - 148067, 256, 29084, 256, 148395, 256, 29224, 256, 29237, 256, 29264, 256, - 149000, 256, 29312, 256, 29333, 256, 149301, 256, 149524, 256, 29562, - 256, 29579, 256, 16044, 256, 29605, 256, 16056, 256, 16056, 256, 29767, - 256, 29788, 256, 29809, 256, 29829, 256, 29898, 256, 16155, 256, 29988, - 256, 150582, 256, 30014, 256, 150674, 256, 30064, 256, 139679, 256, - 30224, 256, 151457, 256, 151480, 256, 151620, 256, 16380, 256, 16392, - 256, 30452, 256, 151795, 256, 151794, 256, 151833, 256, 151859, 256, - 30494, 256, 30495, 256, 30495, 256, 30538, 256, 16441, 256, 30603, 256, - 16454, 256, 16534, 256, 152605, 256, 30798, 256, 30860, 256, 30924, 256, - 16611, 256, 153126, 256, 31062, 256, 153242, 256, 153285, 256, 31119, - 256, 31211, 256, 16687, 256, 31296, 256, 31306, 256, 31311, 256, 153980, - 256, 154279, 256, 154279, 256, 31470, 256, 16898, 256, 154539, 256, - 31686, 256, 31689, 256, 16935, 256, 154752, 256, 31954, 256, 17056, 256, - 31976, 256, 31971, 256, 32000, 256, 155526, 256, 32099, 256, 17153, 256, - 32199, 256, 32258, 256, 32325, 256, 17204, 256, 156200, 256, 156231, 256, - 17241, 256, 156377, 256, 32634, 256, 156478, 256, 32661, 256, 32762, 256, - 32773, 256, 156890, 256, 156963, 256, 32864, 256, 157096, 256, 32880, - 256, 144223, 256, 17365, 256, 32946, 256, 33027, 256, 17419, 256, 33086, - 256, 23221, 256, 157607, 256, 157621, 256, 144275, 256, 144284, 256, - 33281, 256, 33284, 256, 36766, 256, 17515, 256, 33425, 256, 33419, 256, - 33437, 256, 21171, 256, 33457, 256, 33459, 256, 33469, 256, 33510, 256, - 158524, 256, 33509, 256, 33565, 256, 33635, 256, 33709, 256, 33571, 256, - 33725, 256, 33767, 256, 33879, 256, 33619, 256, 33738, 256, 33740, 256, - 33756, 256, 158774, 256, 159083, 256, 158933, 256, 17707, 256, 34033, - 256, 34035, 256, 34070, 256, 160714, 256, 34148, 256, 159532, 256, 17757, - 256, 17761, 256, 159665, 256, 159954, 256, 17771, 256, 34384, 256, 34396, - 256, 34407, 256, 34409, 256, 34473, 256, 34440, 256, 34574, 256, 34530, - 256, 34681, 256, 34600, 256, 34667, 256, 34694, 256, 17879, 256, 34785, - 256, 34817, 256, 17913, 256, 34912, 256, 34915, 256, 161383, 256, 35031, - 256, 35038, 256, 17973, 256, 35066, 256, 13499, 256, 161966, 256, 162150, - 256, 18110, 256, 18119, 256, 35488, 256, 35565, 256, 35722, 256, 35925, - 256, 162984, 256, 36011, 256, 36033, 256, 36123, 256, 36215, 256, 163631, - 256, 133124, 256, 36299, 256, 36284, 256, 36336, 256, 133342, 256, 36564, - 256, 36664, 256, 165330, 256, 165357, 256, 37012, 256, 37105, 256, 37137, - 256, 165678, 256, 37147, 256, 37432, 256, 37591, 256, 37592, 256, 37500, - 256, 37881, 256, 37909, 256, 166906, 256, 38283, 256, 18837, 256, 38327, - 256, 167287, 256, 18918, 256, 38595, 256, 23986, 256, 38691, 256, 168261, - 256, 168474, 256, 19054, 256, 19062, 256, 38880, 256, 168970, 256, 19122, - 256, 169110, 256, 38923, 256, 38923, 256, 38953, 256, 169398, 256, 39138, - 256, 19251, 256, 39209, 256, 39335, 256, 39362, 256, 39422, 256, 19406, - 256, 170800, 256, 39698, 256, 40000, 256, 40189, 256, 19662, 256, 19693, - 256, 40295, 256, 172238, 256, 19704, 256, 172293, 256, 172558, 256, - 172689, 256, 40635, 256, 19798, 256, 40697, 256, 40702, 256, 40709, 256, - 40719, 256, 40726, 256, 40763, 256, 173568, + 977, 262, 1008, 262, 981, 262, 1009, 262, 982, 262, 913, 262, 914, 262, + 915, 262, 916, 262, 917, 262, 918, 262, 919, 262, 920, 262, 921, 262, + 922, 262, 923, 262, 924, 262, 925, 262, 926, 262, 927, 262, 928, 262, + 929, 262, 1012, 262, 931, 262, 932, 262, 933, 262, 934, 262, 935, 262, + 936, 262, 937, 262, 8711, 262, 945, 262, 946, 262, 947, 262, 948, 262, + 949, 262, 950, 262, 951, 262, 952, 262, 953, 262, 954, 262, 955, 262, + 956, 262, 957, 262, 958, 262, 959, 262, 960, 262, 961, 262, 962, 262, + 963, 262, 964, 262, 965, 262, 966, 262, 967, 262, 968, 262, 969, 262, + 8706, 262, 1013, 262, 977, 262, 1008, 262, 981, 262, 1009, 262, 982, 262, + 913, 262, 914, 262, 915, 262, 916, 262, 917, 262, 918, 262, 919, 262, + 920, 262, 921, 262, 922, 262, 923, 262, 924, 262, 925, 262, 926, 262, + 927, 262, 928, 262, 929, 262, 1012, 262, 931, 262, 932, 262, 933, 262, + 934, 262, 935, 262, 936, 262, 937, 262, 8711, 262, 945, 262, 946, 262, + 947, 262, 948, 262, 949, 262, 950, 262, 951, 262, 952, 262, 953, 262, + 954, 262, 955, 262, 956, 262, 957, 262, 958, 262, 959, 262, 960, 262, + 961, 262, 962, 262, 963, 262, 964, 262, 965, 262, 966, 262, 967, 262, + 968, 262, 969, 262, 8706, 262, 1013, 262, 977, 262, 1008, 262, 981, 262, + 1009, 262, 982, 262, 913, 262, 914, 262, 915, 262, 916, 262, 917, 262, + 918, 262, 919, 262, 920, 262, 921, 262, 922, 262, 923, 262, 924, 262, + 925, 262, 926, 262, 927, 262, 928, 262, 929, 262, 1012, 262, 931, 262, + 932, 262, 933, 262, 934, 262, 935, 262, 936, 262, 937, 262, 8711, 262, + 945, 262, 946, 262, 947, 262, 948, 262, 949, 262, 950, 262, 951, 262, + 952, 262, 953, 262, 954, 262, 955, 262, 956, 262, 957, 262, 958, 262, + 959, 262, 960, 262, 961, 262, 962, 262, 963, 262, 964, 262, 965, 262, + 966, 262, 967, 262, 968, 262, 969, 262, 8706, 262, 1013, 262, 977, 262, + 1008, 262, 981, 262, 1009, 262, 982, 262, 988, 262, 989, 262, 48, 262, + 49, 262, 50, 262, 51, 262, 52, 262, 53, 262, 54, 262, 55, 262, 56, 262, + 57, 262, 48, 262, 49, 262, 50, 262, 51, 262, 52, 262, 53, 262, 54, 262, + 55, 262, 56, 262, 57, 262, 48, 262, 49, 262, 50, 262, 51, 262, 52, 262, + 53, 262, 54, 262, 55, 262, 56, 262, 57, 262, 48, 262, 49, 262, 50, 262, + 51, 262, 52, 262, 53, 262, 54, 262, 55, 262, 56, 262, 57, 262, 48, 262, + 49, 262, 50, 262, 51, 262, 52, 262, 53, 262, 54, 262, 55, 262, 56, 262, + 57, 262, 1575, 262, 1576, 262, 1580, 262, 1583, 262, 1608, 262, 1586, + 262, 1581, 262, 1591, 262, 1610, 262, 1603, 262, 1604, 262, 1605, 262, + 1606, 262, 1587, 262, 1593, 262, 1601, 262, 1589, 262, 1602, 262, 1585, + 262, 1588, 262, 1578, 262, 1579, 262, 1582, 262, 1584, 262, 1590, 262, + 1592, 262, 1594, 262, 1646, 262, 1722, 262, 1697, 262, 1647, 262, 1576, + 262, 1580, 262, 1607, 262, 1581, 262, 1610, 262, 1603, 262, 1604, 262, + 1605, 262, 1606, 262, 1587, 262, 1593, 262, 1601, 262, 1589, 262, 1602, + 262, 1588, 262, 1578, 262, 1579, 262, 1582, 262, 1590, 262, 1594, 262, + 1580, 262, 1581, 262, 1610, 262, 1604, 262, 1606, 262, 1587, 262, 1593, + 262, 1589, 262, 1602, 262, 1588, 262, 1582, 262, 1590, 262, 1594, 262, + 1722, 262, 1647, 262, 1576, 262, 1580, 262, 1607, 262, 1581, 262, 1591, + 262, 1610, 262, 1603, 262, 1605, 262, 1606, 262, 1587, 262, 1593, 262, + 1601, 262, 1589, 262, 1602, 262, 1588, 262, 1578, 262, 1579, 262, 1582, + 262, 1590, 262, 1592, 262, 1594, 262, 1646, 262, 1697, 262, 1575, 262, + 1576, 262, 1580, 262, 1583, 262, 1607, 262, 1608, 262, 1586, 262, 1581, + 262, 1591, 262, 1610, 262, 1604, 262, 1605, 262, 1606, 262, 1587, 262, + 1593, 262, 1601, 262, 1589, 262, 1602, 262, 1585, 262, 1588, 262, 1578, + 262, 1579, 262, 1582, 262, 1584, 262, 1590, 262, 1592, 262, 1594, 262, + 1576, 262, 1580, 262, 1583, 262, 1608, 262, 1586, 262, 1581, 262, 1591, + 262, 1610, 262, 1604, 262, 1605, 262, 1606, 262, 1587, 262, 1593, 262, + 1601, 262, 1589, 262, 1602, 262, 1585, 262, 1588, 262, 1578, 262, 1579, + 262, 1582, 262, 1584, 262, 1590, 262, 1592, 262, 1594, 514, 48, 46, 514, + 48, 44, 514, 49, 44, 514, 50, 44, 514, 51, 44, 514, 52, 44, 514, 53, 44, + 514, 54, 44, 514, 55, 44, 514, 56, 44, 514, 57, 44, 770, 40, 65, 41, 770, + 40, 66, 41, 770, 40, 67, 41, 770, 40, 68, 41, 770, 40, 69, 41, 770, 40, + 70, 41, 770, 40, 71, 41, 770, 40, 72, 41, 770, 40, 73, 41, 770, 40, 74, + 41, 770, 40, 75, 41, 770, 40, 76, 41, 770, 40, 77, 41, 770, 40, 78, 41, + 770, 40, 79, 41, 770, 40, 80, 41, 770, 40, 81, 41, 770, 40, 82, 41, 770, + 40, 83, 41, 770, 40, 84, 41, 770, 40, 85, 41, 770, 40, 86, 41, 770, 40, + 87, 41, 770, 40, 88, 41, 770, 40, 89, 41, 770, 40, 90, 41, 770, 12308, + 83, 12309, 263, 67, 263, 82, 519, 67, 68, 519, 87, 90, 266, 65, 266, 66, + 266, 67, 266, 68, 266, 69, 266, 70, 266, 71, 266, 72, 266, 73, 266, 74, + 266, 75, 266, 76, 266, 77, 266, 78, 266, 79, 266, 80, 266, 81, 266, 82, + 266, 83, 266, 84, 266, 85, 266, 86, 266, 87, 266, 88, 266, 89, 266, 90, + 522, 72, 86, 522, 77, 86, 522, 83, 68, 522, 83, 83, 778, 80, 80, 86, 522, + 87, 67, 515, 77, 67, 515, 77, 68, 522, 68, 74, 522, 12411, 12363, 522, + 12467, 12467, 266, 12469, 266, 25163, 266, 23383, 266, 21452, 266, 12487, + 266, 20108, 266, 22810, 266, 35299, 266, 22825, 266, 20132, 266, 26144, + 266, 28961, 266, 26009, 266, 21069, 266, 24460, 266, 20877, 266, 26032, + 266, 21021, 266, 32066, 266, 29983, 266, 36009, 266, 22768, 266, 21561, + 266, 28436, 266, 25237, 266, 25429, 266, 19968, 266, 19977, 266, 36938, + 266, 24038, 266, 20013, 266, 21491, 266, 25351, 266, 36208, 266, 25171, + 266, 31105, 266, 31354, 266, 21512, 266, 28288, 266, 26377, 266, 26376, + 266, 30003, 266, 21106, 266, 21942, 770, 12308, 26412, 12309, 770, 12308, + 19977, 12309, 770, 12308, 20108, 12309, 770, 12308, 23433, 12309, 770, + 12308, 28857, 12309, 770, 12308, 25171, 12309, 770, 12308, 30423, 12309, + 770, 12308, 21213, 12309, 770, 12308, 25943, 12309, 263, 24471, 263, + 21487, 256, 20029, 256, 20024, 256, 20033, 256, 131362, 256, 20320, 256, + 20398, 256, 20411, 256, 20482, 256, 20602, 256, 20633, 256, 20711, 256, + 20687, 256, 13470, 256, 132666, 256, 20813, 256, 20820, 256, 20836, 256, + 20855, 256, 132380, 256, 13497, 256, 20839, 256, 20877, 256, 132427, 256, + 20887, 256, 20900, 256, 20172, 256, 20908, 256, 20917, 256, 168415, 256, + 20981, 256, 20995, 256, 13535, 256, 21051, 256, 21062, 256, 21106, 256, + 21111, 256, 13589, 256, 21191, 256, 21193, 256, 21220, 256, 21242, 256, + 21253, 256, 21254, 256, 21271, 256, 21321, 256, 21329, 256, 21338, 256, + 21363, 256, 21373, 256, 21375, 256, 21375, 256, 21375, 256, 133676, 256, + 28784, 256, 21450, 256, 21471, 256, 133987, 256, 21483, 256, 21489, 256, + 21510, 256, 21662, 256, 21560, 256, 21576, 256, 21608, 256, 21666, 256, + 21750, 256, 21776, 256, 21843, 256, 21859, 256, 21892, 256, 21892, 256, + 21913, 256, 21931, 256, 21939, 256, 21954, 256, 22294, 256, 22022, 256, + 22295, 256, 22097, 256, 22132, 256, 20999, 256, 22766, 256, 22478, 256, + 22516, 256, 22541, 256, 22411, 256, 22578, 256, 22577, 256, 22700, 256, + 136420, 256, 22770, 256, 22775, 256, 22790, 256, 22810, 256, 22818, 256, + 22882, 256, 136872, 256, 136938, 256, 23020, 256, 23067, 256, 23079, 256, + 23000, 256, 23142, 256, 14062, 256, 14076, 256, 23304, 256, 23358, 256, + 23358, 256, 137672, 256, 23491, 256, 23512, 256, 23527, 256, 23539, 256, + 138008, 256, 23551, 256, 23558, 256, 24403, 256, 23586, 256, 14209, 256, + 23648, 256, 23662, 256, 23744, 256, 23693, 256, 138724, 256, 23875, 256, + 138726, 256, 23918, 256, 23915, 256, 23932, 256, 24033, 256, 24034, 256, + 14383, 256, 24061, 256, 24104, 256, 24125, 256, 24169, 256, 14434, 256, + 139651, 256, 14460, 256, 24240, 256, 24243, 256, 24246, 256, 24266, 256, + 172946, 256, 24318, 256, 140081, 256, 140081, 256, 33281, 256, 24354, + 256, 24354, 256, 14535, 256, 144056, 256, 156122, 256, 24418, 256, 24427, + 256, 14563, 256, 24474, 256, 24525, 256, 24535, 256, 24569, 256, 24705, + 256, 14650, 256, 14620, 256, 24724, 256, 141012, 256, 24775, 256, 24904, + 256, 24908, 256, 24910, 256, 24908, 256, 24954, 256, 24974, 256, 25010, + 256, 24996, 256, 25007, 256, 25054, 256, 25074, 256, 25078, 256, 25104, + 256, 25115, 256, 25181, 256, 25265, 256, 25300, 256, 25424, 256, 142092, + 256, 25405, 256, 25340, 256, 25448, 256, 25475, 256, 25572, 256, 142321, + 256, 25634, 256, 25541, 256, 25513, 256, 14894, 256, 25705, 256, 25726, + 256, 25757, 256, 25719, 256, 14956, 256, 25935, 256, 25964, 256, 143370, + 256, 26083, 256, 26360, 256, 26185, 256, 15129, 256, 26257, 256, 15112, + 256, 15076, 256, 20882, 256, 20885, 256, 26368, 256, 26268, 256, 32941, + 256, 17369, 256, 26391, 256, 26395, 256, 26401, 256, 26462, 256, 26451, + 256, 144323, 256, 15177, 256, 26618, 256, 26501, 256, 26706, 256, 26757, + 256, 144493, 256, 26766, 256, 26655, 256, 26900, 256, 15261, 256, 26946, + 256, 27043, 256, 27114, 256, 27304, 256, 145059, 256, 27355, 256, 15384, + 256, 27425, 256, 145575, 256, 27476, 256, 15438, 256, 27506, 256, 27551, + 256, 27578, 256, 27579, 256, 146061, 256, 138507, 256, 146170, 256, + 27726, 256, 146620, 256, 27839, 256, 27853, 256, 27751, 256, 27926, 256, + 27966, 256, 28023, 256, 27969, 256, 28009, 256, 28024, 256, 28037, 256, + 146718, 256, 27956, 256, 28207, 256, 28270, 256, 15667, 256, 28363, 256, + 28359, 256, 147153, 256, 28153, 256, 28526, 256, 147294, 256, 147342, + 256, 28614, 256, 28729, 256, 28702, 256, 28699, 256, 15766, 256, 28746, + 256, 28797, 256, 28791, 256, 28845, 256, 132389, 256, 28997, 256, 148067, + 256, 29084, 256, 148395, 256, 29224, 256, 29237, 256, 29264, 256, 149000, + 256, 29312, 256, 29333, 256, 149301, 256, 149524, 256, 29562, 256, 29579, + 256, 16044, 256, 29605, 256, 16056, 256, 16056, 256, 29767, 256, 29788, + 256, 29809, 256, 29829, 256, 29898, 256, 16155, 256, 29988, 256, 150582, + 256, 30014, 256, 150674, 256, 30064, 256, 139679, 256, 30224, 256, + 151457, 256, 151480, 256, 151620, 256, 16380, 256, 16392, 256, 30452, + 256, 151795, 256, 151794, 256, 151833, 256, 151859, 256, 30494, 256, + 30495, 256, 30495, 256, 30538, 256, 16441, 256, 30603, 256, 16454, 256, + 16534, 256, 152605, 256, 30798, 256, 30860, 256, 30924, 256, 16611, 256, + 153126, 256, 31062, 256, 153242, 256, 153285, 256, 31119, 256, 31211, + 256, 16687, 256, 31296, 256, 31306, 256, 31311, 256, 153980, 256, 154279, + 256, 154279, 256, 31470, 256, 16898, 256, 154539, 256, 31686, 256, 31689, + 256, 16935, 256, 154752, 256, 31954, 256, 17056, 256, 31976, 256, 31971, + 256, 32000, 256, 155526, 256, 32099, 256, 17153, 256, 32199, 256, 32258, + 256, 32325, 256, 17204, 256, 156200, 256, 156231, 256, 17241, 256, + 156377, 256, 32634, 256, 156478, 256, 32661, 256, 32762, 256, 32773, 256, + 156890, 256, 156963, 256, 32864, 256, 157096, 256, 32880, 256, 144223, + 256, 17365, 256, 32946, 256, 33027, 256, 17419, 256, 33086, 256, 23221, + 256, 157607, 256, 157621, 256, 144275, 256, 144284, 256, 33281, 256, + 33284, 256, 36766, 256, 17515, 256, 33425, 256, 33419, 256, 33437, 256, + 21171, 256, 33457, 256, 33459, 256, 33469, 256, 33510, 256, 158524, 256, + 33509, 256, 33565, 256, 33635, 256, 33709, 256, 33571, 256, 33725, 256, + 33767, 256, 33879, 256, 33619, 256, 33738, 256, 33740, 256, 33756, 256, + 158774, 256, 159083, 256, 158933, 256, 17707, 256, 34033, 256, 34035, + 256, 34070, 256, 160714, 256, 34148, 256, 159532, 256, 17757, 256, 17761, + 256, 159665, 256, 159954, 256, 17771, 256, 34384, 256, 34396, 256, 34407, + 256, 34409, 256, 34473, 256, 34440, 256, 34574, 256, 34530, 256, 34681, + 256, 34600, 256, 34667, 256, 34694, 256, 17879, 256, 34785, 256, 34817, + 256, 17913, 256, 34912, 256, 34915, 256, 161383, 256, 35031, 256, 35038, + 256, 17973, 256, 35066, 256, 13499, 256, 161966, 256, 162150, 256, 18110, + 256, 18119, 256, 35488, 256, 35565, 256, 35722, 256, 35925, 256, 162984, + 256, 36011, 256, 36033, 256, 36123, 256, 36215, 256, 163631, 256, 133124, + 256, 36299, 256, 36284, 256, 36336, 256, 133342, 256, 36564, 256, 36664, + 256, 165330, 256, 165357, 256, 37012, 256, 37105, 256, 37137, 256, + 165678, 256, 37147, 256, 37432, 256, 37591, 256, 37592, 256, 37500, 256, + 37881, 256, 37909, 256, 166906, 256, 38283, 256, 18837, 256, 38327, 256, + 167287, 256, 18918, 256, 38595, 256, 23986, 256, 38691, 256, 168261, 256, + 168474, 256, 19054, 256, 19062, 256, 38880, 256, 168970, 256, 19122, 256, + 169110, 256, 38923, 256, 38923, 256, 38953, 256, 169398, 256, 39138, 256, + 19251, 256, 39209, 256, 39335, 256, 39362, 256, 39422, 256, 19406, 256, + 170800, 256, 39698, 256, 40000, 256, 40189, 256, 19662, 256, 19693, 256, + 40295, 256, 172238, 256, 19704, 256, 172293, 256, 172558, 256, 172689, + 256, 40635, 256, 19798, 256, 40697, 256, 40702, 256, 40709, 256, 40719, + 256, 40726, 256, 40763, 256, 173568, }; /* index tables for the decomposition data */ -#define DECOMP_SHIFT 8 +#define DECOMP_SHIFT 7 static unsigned char decomp_index1[] = { - 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 9, 10, 11, 12, 13, 14, 15, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 16, 7, 17, 18, 19, 20, 21, 22, 23, 24, 7, 7, 7, 7, 7, 25, - 7, 26, 27, 28, 29, 30, 31, 32, 33, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 34, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 35, 36, 37, 38, 39, 40, - 41, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 42, 43, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 44, 7, 7, 45, - 46, 47, 48, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 49, 7, 7, 50, 51, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 52, 53, 54, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -}; - -static unsigned short decomp_index2[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 10, 11, 12, 0, 0, 0, 0, 13, 14, 15, 0, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 0, 42, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, + 45, 0, 0, 46, 0, 47, 0, 0, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 60, 61, 0, 0, 0, 0, 0, 0, 62, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, + 74, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 78, 0, 0, 0, 79, 0, 0, 80, 0, + 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 83, 0, 0, 0, 0, 84, 85, + 86, 87, 88, 89, 90, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 92, 93, 0, 0, 0, 0, 94, 95, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 98, 99, 100, 101, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, - 3, 0, 6, 0, 0, 0, 0, 8, 0, 0, 11, 13, 15, 18, 0, 0, 20, 23, 25, 0, 27, - 31, 35, 0, 39, 42, 45, 48, 51, 54, 0, 57, 60, 63, 66, 69, 72, 75, 78, 81, - 0, 84, 87, 90, 93, 96, 99, 0, 0, 102, 105, 108, 111, 114, 0, 0, 117, 120, - 123, 126, 129, 132, 0, 135, 138, 141, 144, 147, 150, 153, 156, 159, 0, - 162, 165, 168, 171, 174, 177, 0, 0, 180, 183, 186, 189, 192, 0, 195, 198, - 201, 204, 207, 210, 213, 216, 219, 222, 225, 228, 231, 234, 237, 240, - 243, 0, 0, 246, 249, 252, 255, 258, 261, 264, 267, 270, 273, 276, 279, - 282, 285, 288, 291, 294, 297, 300, 303, 0, 0, 306, 309, 312, 315, 318, - 321, 324, 327, 330, 0, 333, 336, 339, 342, 345, 348, 0, 351, 354, 357, - 360, 363, 366, 369, 372, 0, 0, 375, 378, 381, 384, 387, 390, 393, 0, 0, - 396, 399, 402, 405, 408, 411, 0, 0, 414, 417, 420, 423, 426, 429, 432, - 435, 438, 441, 444, 447, 450, 453, 456, 459, 462, 465, 0, 0, 468, 471, - 474, 477, 480, 483, 486, 489, 492, 495, 498, 501, 504, 507, 510, 513, - 516, 519, 522, 525, 528, 531, 534, 537, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 539, 542, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 545, 548, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 551, 554, 557, 560, 563, 566, 569, 572, - 575, 578, 581, 584, 587, 590, 593, 596, 599, 602, 605, 608, 611, 614, - 617, 620, 623, 0, 626, 629, 632, 635, 638, 641, 0, 0, 644, 647, 650, 653, - 656, 659, 662, 665, 668, 671, 674, 677, 680, 683, 686, 689, 0, 0, 692, - 695, 698, 701, 704, 707, 710, 713, 716, 719, 722, 725, 728, 731, 734, - 737, 740, 743, 746, 749, 752, 755, 758, 761, 764, 767, 770, 773, 776, - 779, 782, 785, 788, 791, 794, 797, 0, 0, 800, 803, 0, 0, 0, 0, 0, 0, 806, - 809, 812, 815, 818, 821, 824, 827, 830, 833, 836, 839, 842, 845, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 848, 850, 852, 854, 856, 858, 860, 862, 864, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 866, - 869, 872, 875, 878, 881, 0, 0, 884, 886, 888, 890, 892, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 894, 896, 0, 898, 900, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 903, 0, 0, 0, 0, - 0, 905, 0, 0, 0, 908, 0, 0, 0, 0, 0, 910, 913, 916, 919, 921, 924, 927, - 0, 930, 0, 933, 936, 939, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 942, 945, 948, 951, 954, 957, 960, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 963, 966, - 969, 972, 975, 0, 978, 980, 982, 984, 987, 990, 992, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 994, 996, 998, 0, - 1000, 1002, 0, 0, 0, 1004, 0, 0, 0, 0, 0, 0, 1006, 1009, 0, 1012, 0, 0, - 0, 1015, 0, 0, 0, 0, 1018, 1021, 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1027, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1030, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1033, 1036, 0, 1039, 0, 0, 0, 1042, 0, 0, 0, - 0, 1045, 1048, 1051, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1054, 1057, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1060, 1063, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1066, 1069, 1072, 1075, 0, 0, 1078, 1081, 0, 0, 1084, 1087, - 1090, 1093, 1096, 1099, 0, 0, 1102, 1105, 1108, 1111, 1114, 1117, 0, 0, - 1120, 1123, 1126, 1129, 1132, 1135, 1138, 1141, 1144, 1147, 1150, 1153, - 0, 0, 1156, 1159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1162, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1165, 1168, 1171, 1174, - 1177, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1180, 1183, 1186, 1189, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1192, 0, 1195, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -4012,21 +4182,13 @@ static unsigned short decomp_index2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1201, 0, 0, 0, - 0, 0, 0, 0, 1204, 0, 0, 1207, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1210, - 1213, 1216, 1219, 1222, 1225, 1228, 1231, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1234, 1237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1240, 1243, - 0, 1246, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1249, 0, 0, 1252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1255, 1258, 1261, 0, 0, 1264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -4036,181 +4198,42 @@ static unsigned short decomp_index2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1267, 0, 0, 1270, 1273, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1276, 1279, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1282, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1285, 1288, 1291, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1294, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1297, 0, 0, 0, 0, 0, 0, 1300, 1303, 0, - 1306, 1309, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1312, 1315, 1318, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1321, 0, 1324, 1327, 1330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1336, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1339, 1342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1345, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1347, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1350, 0, 0, 0, 0, 1353, 0, 0, 0, 0, - 1356, 0, 0, 0, 0, 1359, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1362, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1365, 0, 1368, 1371, 1374, 1377, 1380, 0, 0, 0, 0, - 0, 0, 0, 1383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1386, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1389, 0, 0, 0, 0, 1392, 0, 0, 0, 0, 1395, 0, - 0, 0, 0, 1398, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1401, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1404, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1407, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1409, 0, 1412, 0, - 1415, 0, 1418, 0, 1421, 0, 0, 0, 1424, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1427, 0, 1430, 0, 0, 1433, 1436, 0, 1439, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1442, 1444, 1446, 0, 1448, 1450, 1452, - 1454, 1456, 1458, 1460, 1462, 1464, 1466, 1468, 0, 1470, 1472, 1474, - 1476, 1478, 1480, 1482, 1484, 1486, 1488, 1490, 1492, 1494, 1496, 1498, - 1500, 1502, 1504, 0, 1506, 1508, 1510, 1512, 1514, 1516, 1518, 1520, - 1522, 1524, 1526, 1528, 1530, 1532, 1534, 1536, 1538, 1540, 1542, 1544, - 1546, 1548, 1550, 1552, 1554, 1556, 1558, 1560, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1562, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1564, 1566, 1568, - 1570, 1572, 1574, 1576, 1578, 1580, 1582, 1584, 1586, 1588, 1590, 1592, - 1594, 1596, 1598, 1600, 1602, 1604, 1606, 1608, 1610, 1612, 1614, 1616, - 1618, 1620, 1622, 1624, 1626, 1628, 1630, 1632, 1634, 1636, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1638, 1641, 1644, 1647, 1650, 1653, - 1656, 1659, 1662, 1665, 1668, 1671, 1674, 1677, 1680, 1683, 1686, 1689, - 1692, 1695, 1698, 1701, 1704, 1707, 1710, 1713, 1716, 1719, 1722, 1725, - 1728, 1731, 1734, 1737, 1740, 1743, 1746, 1749, 1752, 1755, 1758, 1761, - 1764, 1767, 1770, 1773, 1776, 1779, 1782, 1785, 1788, 1791, 1794, 1797, - 1800, 1803, 1806, 1809, 1812, 1815, 1818, 1821, 1824, 1827, 1830, 1833, - 1836, 1839, 1842, 1845, 1848, 1851, 1854, 1857, 1860, 1863, 1866, 1869, - 1872, 1875, 1878, 1881, 1884, 1887, 1890, 1893, 1896, 1899, 1902, 1905, - 1908, 1911, 1914, 1917, 1920, 1923, 1926, 1929, 1932, 1935, 1938, 1941, - 1944, 1947, 1950, 1953, 1956, 1959, 1962, 1965, 1968, 1971, 1974, 1977, - 1980, 1983, 1986, 1989, 1992, 1995, 1998, 2001, 2004, 2007, 2010, 2013, - 2016, 2019, 2022, 2025, 2028, 2031, 2034, 2037, 2040, 2043, 2046, 2049, - 2052, 2055, 2058, 2061, 2064, 2067, 2070, 2073, 2076, 2079, 2082, 2085, - 2088, 2091, 2094, 2097, 2100, 2103, 0, 0, 0, 0, 2106, 2109, 2112, 2115, - 2118, 2121, 2124, 2127, 2130, 2133, 2136, 2139, 2142, 2145, 2148, 2151, - 2154, 2157, 2160, 2163, 2166, 2169, 2172, 2175, 2178, 2181, 2184, 2187, - 2190, 2193, 2196, 2199, 2202, 2205, 2208, 2211, 2214, 2217, 2220, 2223, - 2226, 2229, 2232, 2235, 2238, 2241, 2244, 2247, 2250, 2253, 2256, 2259, - 2262, 2265, 2268, 2271, 2274, 2277, 2280, 2283, 2286, 2289, 2292, 2295, - 2298, 2301, 2304, 2307, 2310, 2313, 2316, 2319, 2322, 2325, 2328, 2331, - 2334, 2337, 2340, 2343, 2346, 2349, 2352, 2355, 2358, 2361, 2364, 2367, - 2370, 2373, 0, 0, 0, 0, 0, 0, 2376, 2379, 2382, 2385, 2388, 2391, 2394, - 2397, 2400, 2403, 2406, 2409, 2412, 2415, 2418, 2421, 2424, 2427, 2430, - 2433, 2436, 2439, 0, 0, 2442, 2445, 2448, 2451, 2454, 2457, 0, 0, 2460, - 2463, 2466, 2469, 2472, 2475, 2478, 2481, 2484, 2487, 2490, 2493, 2496, - 2499, 2502, 2505, 2508, 2511, 2514, 2517, 2520, 2523, 2526, 2529, 2532, - 2535, 2538, 2541, 2544, 2547, 2550, 2553, 2556, 2559, 2562, 2565, 2568, - 2571, 0, 0, 2574, 2577, 2580, 2583, 2586, 2589, 0, 0, 2592, 2595, 2598, - 2601, 2604, 2607, 2610, 2613, 0, 2616, 0, 2619, 0, 2622, 0, 2625, 2628, - 2631, 2634, 2637, 2640, 2643, 2646, 2649, 2652, 2655, 2658, 2661, 2664, - 2667, 2670, 2673, 2676, 2679, 2681, 2684, 2686, 2689, 2691, 2694, 2696, - 2699, 2701, 2704, 2706, 2709, 0, 0, 2711, 2714, 2717, 2720, 2723, 2726, - 2729, 2732, 2735, 2738, 2741, 2744, 2747, 2750, 2753, 2756, 2759, 2762, - 2765, 2768, 2771, 2774, 2777, 2780, 2783, 2786, 2789, 2792, 2795, 2798, - 2801, 2804, 2807, 2810, 2813, 2816, 2819, 2822, 2825, 2828, 2831, 2834, - 2837, 2840, 2843, 2846, 2849, 2852, 2855, 2858, 2861, 2864, 2867, 0, - 2870, 2873, 2876, 2879, 2882, 2885, 2887, 2890, 2893, 2895, 2898, 2901, - 2904, 2907, 2910, 0, 2913, 2916, 2919, 2922, 2924, 2927, 2929, 2932, - 2935, 2938, 2941, 2944, 2947, 2950, 0, 0, 2952, 2955, 2958, 2961, 2964, - 2967, 0, 2969, 2972, 2975, 2978, 2981, 2984, 2987, 2989, 2992, 2995, - 2998, 3001, 3004, 3007, 3010, 3012, 3015, 3018, 3020, 0, 0, 3022, 3025, - 3028, 0, 3031, 3034, 3037, 3040, 3042, 3045, 3047, 3050, 3052, 0, 3055, - 3057, 3059, 3061, 3063, 3065, 3067, 3069, 3071, 3073, 3075, 0, 0, 0, 0, - 0, 0, 3077, 0, 0, 0, 0, 0, 3079, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 3082, 3084, 3087, 0, 0, 0, 0, 0, 0, 0, 0, 3091, 0, 0, 0, 3093, 3096, 0, - 3100, 3103, 0, 0, 0, 0, 3107, 0, 3110, 0, 0, 0, 0, 0, 0, 0, 0, 3113, - 3116, 3119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3122, 0, 0, 0, 0, 0, - 0, 0, 3127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3129, 3131, - 0, 0, 3133, 3135, 3137, 3139, 3141, 3143, 3145, 3147, 3149, 3151, 3153, - 3155, 3157, 3159, 3161, 3163, 3165, 3167, 3169, 3171, 3173, 3175, 3177, - 3179, 3181, 3183, 3185, 0, 3187, 3189, 3191, 3193, 3195, 3197, 3199, - 3201, 3203, 3205, 3207, 3209, 3211, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 3213, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3216, 3220, 3224, - 3226, 0, 3229, 3233, 3237, 0, 3239, 3242, 3244, 3246, 3248, 3250, 3252, - 3254, 3256, 3258, 3260, 0, 3262, 3264, 0, 0, 3267, 3269, 3271, 3273, - 3275, 0, 0, 3277, 3280, 3284, 0, 3287, 0, 3289, 0, 3291, 0, 3293, 3295, - 3297, 3299, 0, 3301, 3303, 3305, 0, 3307, 3309, 3311, 3313, 3315, 3317, - 3319, 0, 3321, 3325, 3327, 3329, 3331, 3333, 0, 0, 0, 0, 3335, 3337, - 3339, 3341, 3343, 0, 0, 0, 0, 0, 0, 3345, 3349, 3353, 3358, 3362, 3366, - 3370, 3374, 3378, 3382, 3386, 3390, 3394, 3398, 3402, 3406, 3409, 3411, - 3414, 3418, 3421, 3423, 3426, 3430, 3435, 3438, 3440, 3443, 3447, 3449, - 3451, 3453, 3455, 3457, 3460, 3464, 3467, 3469, 3472, 3476, 3481, 3484, - 3486, 3489, 3493, 3495, 3497, 3499, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3501, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3505, 3508, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3511, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3514, - 3517, 3520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 3523, 0, 0, 0, 0, 3526, 0, 0, 3529, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3532, 0, 3535, - 0, 0, 0, 0, 0, 3538, 3541, 0, 3545, 3548, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3552, 0, 0, 3555, 0, 0, 3558, 0, 3561, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3564, 0, 3567, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 3570, 3573, 3576, 3579, 3582, 0, 0, 3585, 3588, - 0, 0, 3591, 3594, 0, 0, 0, 0, 0, 0, 3597, 3600, 0, 0, 3603, 3606, 0, 0, - 3609, 3612, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3615, 3618, 3621, 3624, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3627, - 3630, 3633, 3636, 0, 0, 0, 0, 0, 0, 3639, 3642, 3645, 3648, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 3651, 3653, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -4223,35 +4246,19 @@ static unsigned short decomp_index2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 3655, 3657, 3659, 3661, 3663, 3665, 3667, 3669, - 3671, 3673, 3676, 3679, 3682, 3685, 3688, 3691, 3694, 3697, 3700, 3703, - 3706, 3710, 3714, 3718, 3722, 3726, 3730, 3734, 3738, 3742, 3747, 3752, - 3757, 3762, 3767, 3772, 3777, 3782, 3787, 3792, 3797, 3800, 3803, 3806, - 3809, 3812, 3815, 3818, 3821, 3824, 3828, 3832, 3836, 3840, 3844, 3848, - 3852, 3856, 3860, 3864, 3868, 3872, 3876, 3880, 3884, 3888, 3892, 3896, - 3900, 3904, 3908, 3912, 3916, 3920, 3924, 3928, 3932, 3936, 3940, 3944, - 3948, 3952, 3956, 3960, 3964, 3968, 3972, 3974, 3976, 3978, 3980, 3982, - 3984, 3986, 3988, 3990, 3992, 3994, 3996, 3998, 4000, 4002, 4004, 4006, - 4008, 4010, 4012, 4014, 4016, 4018, 4020, 4022, 4024, 4026, 4028, 4030, - 4032, 4034, 4036, 4038, 4040, 4042, 4044, 4046, 4048, 4050, 4052, 4054, - 4056, 4058, 4060, 4062, 4064, 4066, 4068, 4070, 4072, 4074, 4076, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 4078, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4083, 4087, 4090, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 4094, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4097, 4099, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -4262,7 +4269,6 @@ static unsigned short decomp_index2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -4274,881 +4280,1339 @@ static unsigned short decomp_index2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 4105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4107, - 4109, 4111, 4113, 4115, 4117, 4119, 4121, 4123, 4125, 4127, 4129, 4131, - 4133, 4135, 4137, 4139, 4141, 4143, 4145, 4147, 4149, 4151, 4153, 4155, - 4157, 4159, 4161, 4163, 4165, 4167, 4169, 4171, 4173, 4175, 4177, 4179, - 4181, 4183, 4185, 4187, 4189, 4191, 4193, 4195, 4197, 4199, 4201, 4203, - 4205, 4207, 4209, 4211, 4213, 4215, 4217, 4219, 4221, 4223, 4225, 4227, - 4229, 4231, 4233, 4235, 4237, 4239, 4241, 4243, 4245, 4247, 4249, 4251, - 4253, 4255, 4257, 4259, 4261, 4263, 4265, 4267, 4269, 4271, 4273, 4275, - 4277, 4279, 4281, 4283, 4285, 4287, 4289, 4291, 4293, 4295, 4297, 4299, - 4301, 4303, 4305, 4307, 4309, 4311, 4313, 4315, 4317, 4319, 4321, 4323, - 4325, 4327, 4329, 4331, 4333, 4335, 4337, 4339, 4341, 4343, 4345, 4347, - 4349, 4351, 4353, 4355, 4357, 4359, 4361, 4363, 4365, 4367, 4369, 4371, - 4373, 4375, 4377, 4379, 4381, 4383, 4385, 4387, 4389, 4391, 4393, 4395, - 4397, 4399, 4401, 4403, 4405, 4407, 4409, 4411, 4413, 4415, 4417, 4419, - 4421, 4423, 4425, 4427, 4429, 4431, 4433, 4435, 4437, 4439, 4441, 4443, - 4445, 4447, 4449, 4451, 4453, 4455, 4457, 4459, 4461, 4463, 4465, 4467, - 4469, 4471, 4473, 4475, 4477, 4479, 4481, 4483, 4485, 4487, 4489, 4491, - 4493, 4495, 4497, 4499, 4501, 4503, 4505, 4507, 4509, 4511, 4513, 4515, - 4517, 4519, 4521, 4523, 4525, 4527, 4529, 4531, 4533, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4535, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4537, 0, 4539, - 4541, 4543, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4545, 0, - 4548, 0, 4551, 0, 4554, 0, 4557, 0, 4560, 0, 4563, 0, 4566, 0, 4569, 0, - 4572, 0, 4575, 0, 4578, 0, 0, 4581, 0, 4584, 0, 4587, 0, 0, 0, 0, 0, 0, - 4590, 4593, 0, 4596, 4599, 0, 4602, 4605, 0, 4608, 4611, 0, 4614, 4617, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4620, - 0, 0, 0, 0, 0, 0, 4623, 4626, 0, 4629, 4632, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 4635, 0, 4638, 0, 4641, 0, 4644, 0, 4647, 0, 4650, 0, 4653, 0, - 4656, 0, 4659, 0, 4662, 0, 4665, 0, 4668, 0, 0, 4671, 0, 4674, 0, 4677, - 0, 0, 0, 0, 0, 0, 4680, 4683, 0, 4686, 4689, 0, 4692, 4695, 0, 4698, - 4701, 0, 4704, 4707, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 4710, 0, 0, 4713, 4716, 4719, 4722, 0, 0, 0, 4725, 4728, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4731, 4733, 4735, 4737, 4739, 4741, 4743, 4745, 4747, 4749, 4751, - 4753, 4755, 4757, 4759, 4761, 4763, 4765, 4767, 4769, 4771, 4773, 4775, - 4777, 4779, 4781, 4783, 4785, 4787, 4789, 4791, 4793, 4795, 4797, 4799, - 4801, 4803, 4805, 4807, 4809, 4811, 4813, 4815, 4817, 4819, 4821, 4823, - 4825, 4827, 4829, 4831, 4833, 4835, 4837, 4839, 4841, 4843, 4845, 4847, - 4849, 4851, 4853, 4855, 4857, 4859, 4861, 4863, 4865, 4867, 4869, 4871, - 4873, 4875, 4877, 4879, 4881, 4883, 4885, 4887, 4889, 4891, 4893, 4895, - 4897, 4899, 4901, 4903, 4905, 4907, 4909, 4911, 4913, 4915, 4917, 0, 0, - 0, 4919, 4921, 4923, 4925, 4927, 4929, 4931, 4933, 4935, 4937, 4939, - 4941, 4943, 4945, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 4947, 4951, 4955, 4959, 4963, 4967, 4971, 4975, 4979, - 4983, 4987, 4991, 4995, 4999, 5003, 5008, 5013, 5018, 5023, 5028, 5033, - 5038, 5043, 5048, 5053, 5058, 5063, 5068, 5073, 5078, 5086, 0, 5093, - 5097, 5101, 5105, 5109, 5113, 5117, 5121, 5125, 5129, 5133, 5137, 5141, - 5145, 5149, 5153, 5157, 5161, 5165, 5169, 5173, 5177, 5181, 5185, 5189, - 5193, 5197, 5201, 5205, 5209, 5213, 5217, 5221, 5225, 5229, 5233, 5237, - 5239, 5241, 5243, 0, 0, 0, 0, 0, 0, 0, 0, 5245, 5249, 5252, 5255, 5258, - 5261, 5264, 5267, 5270, 5273, 5276, 5279, 5282, 5285, 5288, 5291, 5294, - 5296, 5298, 5300, 5302, 5304, 5306, 5308, 5310, 5312, 5314, 5316, 5318, - 5320, 5322, 5325, 5328, 5331, 5334, 5337, 5340, 5343, 5346, 5349, 5352, - 5355, 5358, 5361, 5364, 5370, 5375, 0, 5378, 5380, 5382, 5384, 5386, - 5388, 5390, 5392, 5394, 5396, 5398, 5400, 5402, 5404, 5406, 5408, 5410, - 5412, 5414, 5416, 5418, 5420, 5422, 5424, 5426, 5428, 5430, 5432, 5434, - 5436, 5438, 5440, 5442, 5444, 5446, 5448, 5450, 5452, 5454, 5456, 5458, - 5460, 5462, 5464, 5466, 5468, 5470, 5472, 5474, 5476, 5479, 5482, 5485, - 5488, 5491, 5494, 5497, 5500, 5503, 5506, 5509, 5512, 5515, 5518, 5521, - 5524, 5527, 5530, 5533, 5536, 5539, 5542, 5545, 5548, 5552, 5556, 5560, - 5563, 5567, 5570, 5574, 5576, 5578, 5580, 5582, 5584, 5586, 5588, 5590, - 5592, 5594, 5596, 5598, 5600, 5602, 5604, 5606, 5608, 5610, 5612, 5614, - 5616, 5618, 5620, 5622, 5624, 5626, 5628, 5630, 5632, 5634, 5636, 5638, - 5640, 5642, 5644, 5646, 5648, 5650, 5652, 5654, 5656, 5658, 5660, 5662, - 5664, 5666, 0, 5668, 5673, 5678, 5683, 5687, 5692, 5696, 5700, 5706, - 5711, 5715, 5719, 5723, 5728, 5733, 5737, 5741, 5744, 5748, 5753, 5758, - 5761, 5767, 5774, 5780, 5784, 5790, 5796, 5801, 5805, 5809, 5813, 5818, - 5824, 5829, 5833, 5837, 5841, 5844, 5847, 5850, 5853, 5857, 5861, 5867, - 5871, 5876, 5882, 5886, 5889, 5892, 5898, 5903, 5909, 5913, 5919, 5922, - 5926, 5930, 5934, 5938, 5942, 5947, 5951, 5954, 5958, 5962, 5966, 5971, - 5975, 5979, 5983, 5989, 5994, 5997, 6003, 6006, 6011, 6016, 6020, 6024, - 6028, 6033, 6036, 6040, 6045, 6048, 6054, 6058, 6061, 6064, 6067, 6070, - 6073, 6076, 6079, 6082, 6085, 6088, 6092, 6096, 6100, 6104, 6108, 6112, - 6116, 6120, 6124, 6128, 6132, 6136, 6140, 6144, 6148, 6152, 6155, 6158, - 6162, 6165, 6168, 6171, 6175, 6179, 6182, 6185, 6188, 6191, 6194, 6199, - 6202, 6205, 6208, 6211, 6214, 6217, 6220, 6223, 6227, 6232, 6235, 6238, - 6241, 6244, 6247, 6250, 6253, 6257, 6261, 6265, 6269, 6272, 6275, 6278, - 6281, 6284, 6287, 6290, 6293, 6296, 6299, 6303, 6307, 6310, 6314, 6318, - 6322, 6325, 6329, 6333, 6338, 6341, 6345, 6349, 6353, 6357, 6363, 6370, - 6373, 6376, 6379, 6382, 6385, 6388, 6391, 6394, 6397, 6400, 6403, 6406, - 6409, 6412, 6415, 6418, 6421, 6424, 6429, 6432, 6435, 6438, 6443, 6447, - 6450, 6453, 6456, 6459, 6462, 6465, 6468, 6471, 6474, 6477, 6481, 6484, - 6487, 6491, 6495, 6498, 6503, 6507, 6510, 6513, 6516, 6519, 6523, 6527, - 6530, 6533, 6536, 6539, 6542, 6545, 6548, 6551, 6554, 6558, 6562, 6566, - 6570, 6574, 6578, 6582, 6586, 6590, 6594, 6598, 6602, 6606, 6610, 6614, - 6618, 6622, 6626, 6630, 6634, 6638, 6642, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 6646, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 6648, 6650, 0, 0, 0, 0, 0, 0, 6652, 6654, 6656, 6658, 6660, 6662, 6664, - 6666, 6668, 6670, 6672, 6674, 6676, 6678, 6680, 6682, 6684, 6686, 6688, - 6690, 6692, 6694, 6696, 6698, 6700, 6702, 6704, 6706, 6708, 6710, 6712, - 6714, 6716, 6718, 6720, 6722, 6724, 6726, 6728, 6730, 6732, 6734, 6736, - 6738, 6740, 6742, 6744, 6746, 6748, 6750, 6752, 6754, 6756, 6758, 6760, - 6762, 6764, 6766, 6768, 6770, 6772, 6774, 6776, 6778, 6780, 6782, 6784, - 6786, 6788, 6790, 6792, 6794, 6796, 6798, 6800, 6802, 6804, 6806, 6808, - 6810, 6812, 6814, 6816, 6818, 6820, 6822, 6824, 6826, 6828, 6830, 6832, - 6834, 6836, 6838, 6840, 6842, 6844, 6846, 6848, 6850, 6852, 6854, 6856, - 6858, 6860, 6862, 6864, 6866, 6868, 6870, 6872, 6874, 6876, 6878, 6880, - 6882, 6884, 6886, 6888, 6890, 6892, 6894, 6896, 6898, 6900, 6902, 6904, - 6906, 6908, 6910, 6912, 6914, 6916, 6918, 6920, 6922, 6924, 6926, 6928, - 6930, 6932, 6934, 6936, 6938, 6940, 6942, 6944, 6946, 6948, 6950, 6952, - 6954, 6956, 6958, 6960, 6962, 6964, 6966, 6968, 6970, 6972, 6974, 6976, - 6978, 6980, 6982, 6984, 6986, 6988, 6990, 6992, 6994, 6996, 6998, 7000, - 7002, 7004, 7006, 7008, 7010, 7012, 7014, 7016, 7018, 7020, 7022, 7024, - 7026, 7028, 7030, 7032, 7034, 7036, 7038, 7040, 7042, 7044, 7046, 7048, - 7050, 7052, 7054, 7056, 7058, 7060, 7062, 7064, 7066, 7068, 7070, 7072, - 7074, 7076, 7078, 7080, 7082, 7084, 7086, 7088, 7090, 7092, 7094, 7096, - 7098, 7100, 7102, 7104, 7106, 7108, 7110, 7112, 7114, 7116, 7118, 7120, - 7122, 7124, 7126, 7128, 7130, 7132, 7134, 7136, 7138, 7140, 7142, 7144, - 7146, 7148, 7150, 7152, 7154, 7156, 7158, 7160, 7162, 7164, 7166, 7168, - 7170, 7172, 7174, 7176, 7178, 7180, 7182, 7184, 7186, 7188, 7190, 0, 0, - 7192, 0, 7194, 0, 0, 7196, 7198, 7200, 7202, 7204, 7206, 7208, 7210, - 7212, 7214, 0, 7216, 0, 7218, 0, 0, 7220, 7222, 0, 0, 0, 7224, 7226, - 7228, 7230, 7232, 7234, 7236, 7238, 7240, 7242, 7244, 7246, 7248, 7250, - 7252, 7254, 7256, 7258, 7260, 7262, 7264, 7266, 7268, 7270, 7272, 7274, - 7276, 7278, 7280, 7282, 7284, 7286, 7288, 7290, 7292, 7294, 7296, 7298, - 7300, 7302, 7304, 7306, 7308, 7310, 7312, 7314, 7316, 7318, 7320, 7322, - 7324, 7326, 7328, 7330, 7332, 7334, 7336, 7338, 7340, 7342, 7344, 7346, - 7348, 7350, 7352, 7354, 7356, 7358, 0, 0, 7360, 7362, 7364, 7366, 7368, - 7370, 7372, 7374, 7376, 7378, 7380, 7382, 7384, 7386, 7388, 7390, 7392, - 7394, 7396, 7398, 7400, 7402, 7404, 7406, 7408, 7410, 7412, 7414, 7416, - 7418, 7420, 7422, 7424, 7426, 7428, 7430, 7432, 7434, 7436, 7438, 7440, - 7442, 7444, 7446, 7448, 7450, 7452, 7454, 7456, 7458, 7460, 7462, 7464, - 7466, 7468, 7470, 7472, 7474, 7476, 7478, 7480, 7482, 7484, 7486, 7488, - 7490, 7492, 7494, 7496, 7498, 7500, 7502, 7504, 7506, 7508, 7510, 7512, - 7514, 7516, 7518, 7520, 7522, 7524, 7526, 7528, 7530, 7532, 7534, 7536, - 7538, 7540, 7542, 7544, 7546, 7548, 7550, 7552, 7554, 7556, 7558, 7560, - 7562, 7564, 7566, 7568, 7570, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 7572, 7575, 7578, 7581, 7585, 7589, 7592, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 7595, 7598, 7601, 7604, 7607, 0, 0, 0, 0, 0, 7610, 0, 7613, 7616, - 7618, 7620, 7622, 7624, 7626, 7628, 7630, 7632, 7634, 7636, 7639, 7642, - 7645, 7648, 7651, 7654, 7657, 7660, 7663, 7666, 7669, 7672, 0, 7675, - 7678, 7681, 7684, 7687, 0, 7690, 0, 7693, 7696, 0, 7699, 7702, 0, 7705, - 7708, 7711, 7714, 7717, 7720, 7723, 7726, 7729, 7732, 7735, 7737, 7739, - 7741, 7743, 7745, 7747, 7749, 7751, 7753, 7755, 7757, 7759, 7761, 7763, - 7765, 7767, 7769, 7771, 7773, 7775, 7777, 7779, 7781, 7783, 7785, 7787, - 7789, 7791, 7793, 7795, 7797, 7799, 7801, 7803, 7805, 7807, 7809, 7811, - 7813, 7815, 7817, 7819, 7821, 7823, 7825, 7827, 7829, 7831, 7833, 7835, - 7837, 7839, 7841, 7843, 7845, 7847, 7849, 7851, 7853, 7855, 7857, 7859, - 7861, 7863, 7865, 7867, 7869, 7871, 7873, 7875, 7877, 7879, 7881, 7883, - 7885, 7887, 7889, 7891, 7893, 7895, 7897, 7899, 7901, 7903, 7905, 7907, - 7909, 7911, 7913, 7915, 7917, 7919, 7921, 7923, 7925, 7927, 7929, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 7931, 7933, 7935, 7937, 7939, 7941, 7943, 7945, - 7947, 7949, 7951, 7953, 7955, 7957, 7959, 7961, 7963, 7965, 7967, 7969, - 7971, 7973, 7975, 7977, 7980, 7983, 7986, 7989, 7992, 7995, 7998, 8001, - 8004, 8007, 8010, 8013, 8016, 8019, 8022, 8025, 8028, 8031, 8033, 8035, - 8037, 8039, 8042, 8045, 8048, 8051, 8054, 8057, 8060, 8063, 8066, 8069, - 8072, 8075, 8078, 8081, 8084, 8087, 8090, 8093, 8096, 8099, 8102, 8105, - 8108, 8111, 8114, 8117, 8120, 8123, 8126, 8129, 8132, 8135, 8138, 8141, - 8144, 8147, 8150, 8153, 8156, 8159, 8162, 8165, 8168, 8171, 8174, 8177, - 8180, 8183, 8186, 8189, 8192, 8195, 8198, 8201, 8204, 8207, 8210, 8213, - 8216, 8219, 8222, 8225, 8228, 8231, 8234, 8237, 8240, 8243, 8246, 8249, - 8252, 8255, 8258, 8261, 8264, 8267, 8270, 8273, 8276, 8279, 8282, 8285, - 8288, 8291, 8294, 8297, 8300, 8303, 8306, 8309, 8312, 8315, 8318, 8321, - 8325, 8329, 8333, 8337, 8341, 8345, 8348, 8351, 8354, 8357, 8360, 8363, - 8366, 8369, 8372, 8375, 8378, 8381, 8384, 8387, 8390, 8393, 8396, 8399, - 8402, 8405, 8408, 8411, 8414, 8417, 8420, 8423, 8426, 8429, 8432, 8435, - 8438, 8441, 8444, 8447, 8450, 8453, 8456, 8459, 8462, 8465, 8468, 8471, - 8474, 8477, 8480, 8483, 8486, 8489, 8492, 8495, 8498, 8501, 8504, 8507, - 8510, 8513, 8516, 8519, 8522, 8525, 8528, 8531, 8534, 8537, 8540, 8543, - 8546, 8549, 8552, 8555, 8558, 8561, 8564, 8567, 8570, 8573, 8576, 8579, - 8582, 8585, 8588, 8591, 8594, 8597, 8600, 8603, 8606, 8609, 8612, 8615, - 8618, 8621, 8624, 8627, 8630, 8633, 8636, 8639, 8642, 8645, 8648, 8651, - 8654, 8657, 8660, 8663, 8666, 8669, 8672, 8675, 8678, 8681, 8684, 8687, - 8690, 8693, 8696, 8699, 8702, 8705, 8708, 8711, 8714, 8717, 8720, 8723, - 8726, 8729, 8732, 8735, 8738, 8741, 8744, 8747, 8750, 8753, 8756, 8759, - 8762, 8765, 8768, 8771, 8775, 8779, 8783, 8786, 8789, 8792, 8795, 8798, - 8801, 8804, 8807, 8810, 8813, 8816, 8819, 8822, 8825, 8828, 8831, 8834, - 8837, 8840, 8843, 8846, 8849, 8852, 8855, 8858, 8861, 8864, 8867, 8870, - 8873, 8876, 8879, 8882, 8885, 8888, 8891, 8894, 8897, 8900, 8903, 8906, - 8909, 8912, 8915, 8918, 8921, 8924, 8927, 8930, 8933, 8936, 8939, 8942, - 8945, 8948, 8951, 8954, 8957, 8960, 8963, 8966, 8969, 8972, 8975, 8978, - 8981, 8984, 8987, 8990, 8993, 8996, 8999, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 9002, 9006, 9010, 9014, 9018, 9022, 9026, 9030, - 9034, 9038, 9042, 9046, 9050, 9054, 9058, 9062, 9066, 9070, 9074, 9078, - 9082, 9086, 9090, 9094, 9098, 9102, 9106, 9110, 9114, 9118, 9122, 9126, - 9130, 9134, 9138, 9142, 9146, 9150, 9154, 9158, 9162, 9166, 9170, 9174, - 9178, 9182, 9186, 9190, 9194, 9198, 9202, 9206, 9210, 9214, 9218, 9222, - 9226, 9230, 9234, 9238, 9242, 9246, 9250, 9254, 0, 0, 9258, 9262, 9266, - 9270, 9274, 9278, 9282, 9286, 9290, 9294, 9298, 9302, 9306, 9310, 9314, - 9318, 9322, 9326, 9330, 9334, 9338, 9342, 9346, 9350, 9354, 9358, 9362, - 9366, 9370, 9374, 9378, 9382, 9386, 9390, 9394, 9398, 9402, 9406, 9410, - 9414, 9418, 9422, 9426, 9430, 9434, 9438, 9442, 9446, 9450, 9454, 9458, - 9462, 9466, 9470, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9474, - 9478, 9482, 9487, 9492, 9497, 9502, 9507, 9512, 9517, 9521, 9540, 9549, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9554, 9556, - 9558, 9560, 9562, 9564, 9566, 9568, 9570, 9572, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9574, 9576, 9578, 9580, 9582, - 9584, 9586, 9588, 9590, 9592, 9594, 9596, 9598, 9600, 9602, 9604, 9606, - 9608, 9610, 9612, 9614, 0, 0, 9616, 9618, 9620, 9622, 9624, 9626, 9628, - 9630, 9632, 9634, 9636, 9638, 0, 9640, 9642, 9644, 9646, 9648, 9650, - 9652, 9654, 9656, 9658, 9660, 9662, 9664, 9666, 9668, 9670, 9672, 9674, - 9676, 0, 9678, 9680, 9682, 9684, 0, 0, 0, 0, 9686, 9689, 9692, 0, 9695, - 0, 9698, 9701, 9704, 9707, 9710, 9713, 9716, 9719, 9722, 9725, 9728, - 9730, 9732, 9734, 9736, 9738, 9740, 9742, 9744, 9746, 9748, 9750, 9752, - 9754, 9756, 9758, 9760, 9762, 9764, 9766, 9768, 9770, 9772, 9774, 9776, - 9778, 9780, 9782, 9784, 9786, 9788, 9790, 9792, 9794, 9796, 9798, 9800, - 9802, 9804, 9806, 9808, 9810, 9812, 9814, 9816, 9818, 9820, 9822, 9824, - 9826, 9828, 9830, 9832, 9834, 9836, 9838, 9840, 9842, 9844, 9846, 9848, - 9850, 9852, 9854, 9856, 9858, 9860, 9862, 9864, 9866, 9868, 9870, 9872, - 9874, 9876, 9878, 9880, 9882, 9884, 9886, 9888, 9890, 9892, 9894, 9896, - 9898, 9900, 9902, 9904, 9906, 9908, 9910, 9912, 9914, 9916, 9918, 9920, - 9922, 9924, 9926, 9928, 9930, 9932, 9934, 9936, 9938, 9940, 9942, 9944, - 9946, 9948, 9950, 9952, 9954, 9956, 9958, 9960, 9962, 9965, 9968, 9971, - 9974, 9977, 9980, 9983, 0, 0, 0, 0, 9986, 9988, 9990, 9992, 9994, 9996, - 9998, 10000, 10002, 10004, 10006, 10008, 10010, 10012, 10014, 10016, - 10018, 10020, 10022, 10024, 10026, 10028, 10030, 10032, 10034, 10036, - 10038, 10040, 10042, 10044, 10046, 10048, 10050, 10052, 10054, 10056, - 10058, 10060, 10062, 10064, 10066, 10068, 10070, 10072, 10074, 10076, - 10078, 10080, 10082, 10084, 10086, 10088, 10090, 10092, 10094, 10096, - 10098, 10100, 10102, 10104, 10106, 10108, 10110, 10112, 10114, 10116, - 10118, 10120, 10122, 10124, 10126, 10128, 10130, 10132, 10134, 10136, - 10138, 10140, 10142, 10144, 10146, 10148, 10150, 10152, 10154, 10156, - 10158, 10160, 10162, 10164, 10166, 10168, 10170, 10172, 10174, 10176, - 10178, 10180, 10182, 10184, 10186, 10188, 10190, 10192, 10194, 10196, - 10198, 10200, 10202, 10204, 10206, 10208, 10210, 10212, 10214, 10216, - 10218, 10220, 10222, 10224, 10226, 10228, 10230, 10232, 10234, 10236, - 10238, 10240, 10242, 10244, 10246, 10248, 10250, 10252, 10254, 10256, - 10258, 10260, 10262, 10264, 10266, 10268, 10270, 10272, 10274, 10276, - 10278, 10280, 10282, 10284, 10286, 10288, 10290, 10292, 10294, 10296, - 10298, 10300, 10302, 10304, 10306, 10308, 10310, 10312, 10314, 10316, - 10318, 10320, 10322, 10324, 10326, 10328, 10330, 10332, 10334, 10336, - 10338, 10340, 10342, 10344, 10346, 10348, 10350, 10352, 10354, 10356, - 10358, 10360, 10362, 10364, 0, 0, 0, 10366, 10368, 10370, 10372, 10374, - 10376, 0, 0, 10378, 10380, 10382, 10384, 10386, 10388, 0, 0, 10390, - 10392, 10394, 10396, 10398, 10400, 0, 0, 10402, 10404, 10406, 0, 0, 0, - 10408, 10410, 10412, 10414, 10416, 10418, 10420, 0, 10422, 10424, 10426, - 10428, 10430, 10432, 10434, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10436, 0, 10439, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 10442, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10445, 10448, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10451, 10454, 10457, 10460, 10463, - 10466, 10469, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10472, 10475, - 10478, 10481, 10484, 10487, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 10490, 10492, 10494, 10496, 10498, 10500, 10502, 10504, 10506, 10508, - 10510, 10512, 10514, 10516, 10518, 10520, 10522, 10524, 10526, 10528, - 10530, 10532, 10534, 10536, 10538, 10540, 10542, 10544, 10546, 10548, - 10550, 10552, 10554, 10556, 10558, 10560, 10562, 10564, 10566, 10568, - 10570, 10572, 10574, 10576, 10578, 10580, 10582, 10584, 10586, 10588, - 10590, 10592, 10594, 10596, 10598, 10600, 10602, 10604, 10606, 10608, - 10610, 10612, 10614, 10616, 10618, 10620, 10622, 10624, 10626, 10628, - 10630, 10632, 10634, 10636, 10638, 10640, 10642, 10644, 10646, 10648, - 10650, 10652, 10654, 10656, 10658, 0, 10660, 10662, 10664, 10666, 10668, - 10670, 10672, 10674, 10676, 10678, 10680, 10682, 10684, 10686, 10688, - 10690, 10692, 10694, 10696, 10698, 10700, 10702, 10704, 10706, 10708, - 10710, 10712, 10714, 10716, 10718, 10720, 10722, 10724, 10726, 10728, - 10730, 10732, 10734, 10736, 10738, 10740, 10742, 10744, 10746, 10748, - 10750, 10752, 10754, 10756, 10758, 10760, 10762, 10764, 10766, 10768, - 10770, 10772, 10774, 10776, 10778, 10780, 10782, 10784, 10786, 10788, - 10790, 10792, 10794, 10796, 10798, 10800, 0, 10802, 10804, 0, 0, 10806, - 0, 0, 10808, 10810, 0, 0, 10812, 10814, 10816, 10818, 0, 10820, 10822, - 10824, 10826, 10828, 10830, 10832, 10834, 10836, 10838, 10840, 10842, 0, - 10844, 0, 10846, 10848, 10850, 10852, 10854, 10856, 10858, 0, 10860, - 10862, 10864, 10866, 10868, 10870, 10872, 10874, 10876, 10878, 10880, - 10882, 10884, 10886, 10888, 10890, 10892, 10894, 10896, 10898, 10900, - 10902, 10904, 10906, 10908, 10910, 10912, 10914, 10916, 10918, 10920, - 10922, 10924, 10926, 10928, 10930, 10932, 10934, 10936, 10938, 10940, - 10942, 10944, 10946, 10948, 10950, 10952, 10954, 10956, 10958, 10960, - 10962, 10964, 10966, 10968, 10970, 10972, 10974, 10976, 10978, 10980, - 10982, 10984, 10986, 10988, 0, 10990, 10992, 10994, 10996, 0, 0, 10998, - 11000, 11002, 11004, 11006, 11008, 11010, 11012, 0, 11014, 11016, 11018, - 11020, 11022, 11024, 11026, 0, 11028, 11030, 11032, 11034, 11036, 11038, - 11040, 11042, 11044, 11046, 11048, 11050, 11052, 11054, 11056, 11058, - 11060, 11062, 11064, 11066, 11068, 11070, 11072, 11074, 11076, 11078, - 11080, 11082, 0, 11084, 11086, 11088, 11090, 0, 11092, 11094, 11096, - 11098, 11100, 0, 11102, 0, 0, 0, 11104, 11106, 11108, 11110, 11112, - 11114, 11116, 0, 11118, 11120, 11122, 11124, 11126, 11128, 11130, 11132, - 11134, 11136, 11138, 11140, 11142, 11144, 11146, 11148, 11150, 11152, - 11154, 11156, 11158, 11160, 11162, 11164, 11166, 11168, 11170, 11172, - 11174, 11176, 11178, 11180, 11182, 11184, 11186, 11188, 11190, 11192, - 11194, 11196, 11198, 11200, 11202, 11204, 11206, 11208, 11210, 11212, - 11214, 11216, 11218, 11220, 11222, 11224, 11226, 11228, 11230, 11232, - 11234, 11236, 11238, 11240, 11242, 11244, 11246, 11248, 11250, 11252, - 11254, 11256, 11258, 11260, 11262, 11264, 11266, 11268, 11270, 11272, - 11274, 11276, 11278, 11280, 11282, 11284, 11286, 11288, 11290, 11292, - 11294, 11296, 11298, 11300, 11302, 11304, 11306, 11308, 11310, 11312, - 11314, 11316, 11318, 11320, 11322, 11324, 11326, 11328, 11330, 11332, - 11334, 11336, 11338, 11340, 11342, 11344, 11346, 11348, 11350, 11352, - 11354, 11356, 11358, 11360, 11362, 11364, 11366, 11368, 11370, 11372, - 11374, 11376, 11378, 11380, 11382, 11384, 11386, 11388, 11390, 11392, - 11394, 11396, 11398, 11400, 11402, 11404, 11406, 11408, 11410, 11412, - 11414, 11416, 11418, 11420, 11422, 11424, 11426, 11428, 11430, 11432, - 11434, 11436, 11438, 11440, 11442, 11444, 11446, 11448, 11450, 11452, - 11454, 11456, 11458, 11460, 11462, 11464, 11466, 11468, 11470, 11472, - 11474, 11476, 11478, 11480, 11482, 11484, 11486, 11488, 11490, 11492, - 11494, 11496, 11498, 11500, 11502, 11504, 11506, 11508, 11510, 11512, - 11514, 11516, 11518, 11520, 11522, 11524, 11526, 11528, 11530, 11532, - 11534, 11536, 11538, 11540, 11542, 11544, 11546, 11548, 11550, 11552, - 11554, 11556, 11558, 11560, 11562, 11564, 11566, 11568, 11570, 11572, - 11574, 11576, 11578, 11580, 11582, 11584, 11586, 11588, 11590, 11592, - 11594, 11596, 11598, 11600, 11602, 11604, 11606, 11608, 11610, 11612, - 11614, 11616, 11618, 11620, 11622, 11624, 11626, 11628, 11630, 11632, - 11634, 11636, 11638, 11640, 11642, 11644, 11646, 11648, 11650, 11652, - 11654, 11656, 11658, 11660, 11662, 11664, 11666, 11668, 11670, 11672, - 11674, 11676, 11678, 11680, 11682, 11684, 11686, 11688, 11690, 11692, - 11694, 11696, 11698, 11700, 11702, 11704, 11706, 11708, 11710, 11712, - 11714, 11716, 11718, 11720, 11722, 11724, 11726, 11728, 11730, 11732, - 11734, 11736, 11738, 11740, 11742, 11744, 11746, 11748, 11750, 11752, - 11754, 11756, 11758, 11760, 11762, 11764, 11766, 11768, 11770, 11772, - 11774, 11776, 11778, 11780, 11782, 11784, 11786, 11788, 11790, 11792, - 11794, 11796, 0, 0, 11798, 11800, 11802, 11804, 11806, 11808, 11810, - 11812, 11814, 11816, 11818, 11820, 11822, 11824, 11826, 11828, 11830, - 11832, 11834, 11836, 11838, 11840, 11842, 11844, 11846, 11848, 11850, - 11852, 11854, 11856, 11858, 11860, 11862, 11864, 11866, 11868, 11870, - 11872, 11874, 11876, 11878, 11880, 11882, 11884, 11886, 11888, 11890, - 11892, 11894, 11896, 11898, 11900, 11902, 11904, 11906, 11908, 11910, - 11912, 11914, 11916, 11918, 11920, 11922, 11924, 11926, 11928, 11930, - 11932, 11934, 11936, 11938, 11940, 11942, 11944, 11946, 11948, 11950, - 11952, 11954, 11956, 11958, 11960, 11962, 11964, 11966, 11968, 11970, - 11972, 11974, 11976, 11978, 11980, 11982, 11984, 11986, 11988, 11990, - 11992, 11994, 11996, 11998, 12000, 12002, 12004, 12006, 12008, 12010, - 12012, 12014, 12016, 12018, 12020, 12022, 12024, 12026, 12028, 12030, - 12032, 12034, 12036, 12038, 12040, 12042, 12044, 12046, 12048, 12050, - 12052, 12054, 12056, 12058, 12060, 12062, 12064, 12066, 12068, 12070, - 12072, 12074, 12076, 12078, 12080, 12082, 12084, 12086, 12088, 12090, - 12092, 12094, 12096, 12098, 12100, 12102, 12104, 12106, 12108, 12110, - 12112, 12114, 12116, 12118, 12120, 12122, 12124, 12126, 12128, 12130, - 12132, 12134, 12136, 12138, 12140, 12142, 12144, 12146, 12148, 12150, - 12152, 12154, 12156, 12158, 12160, 12162, 12164, 12166, 12168, 12170, - 12172, 12174, 12176, 12178, 12180, 12182, 12184, 12186, 12188, 12190, - 12192, 12194, 12196, 12198, 12200, 12202, 12204, 12206, 12208, 12210, - 12212, 12214, 12216, 12218, 12220, 12222, 12224, 12226, 12228, 12230, - 12232, 12234, 12236, 12238, 12240, 12242, 12244, 12246, 12248, 12250, - 12252, 12254, 12256, 12258, 12260, 12262, 12264, 12266, 12268, 12270, - 12272, 12274, 12276, 12278, 12280, 12282, 12284, 12286, 12288, 12290, - 12292, 12294, 12296, 12298, 12300, 12302, 12304, 12306, 12308, 12310, - 12312, 12314, 12316, 12318, 12320, 12322, 12324, 12326, 12328, 12330, - 12332, 12334, 12336, 12338, 12340, 12342, 12344, 12346, 12348, 12350, - 12352, 12354, 12356, 12358, 12360, 12362, 12364, 12366, 12368, 12370, - 12372, 12374, 12376, 12378, 12380, 0, 0, 12382, 12384, 12386, 12388, - 12390, 12392, 12394, 12396, 12398, 12400, 12402, 12404, 12406, 12408, - 12410, 12412, 12414, 12416, 12418, 12420, 12422, 12424, 12426, 12428, - 12430, 12432, 12434, 12436, 12438, 12440, 12442, 12444, 12446, 12448, - 12450, 12452, 12454, 12456, 12458, 12460, 12462, 12464, 12466, 12468, - 12470, 12472, 12474, 12476, 12478, 12480, 12482, 12484, 12486, 12488, 0, - 12490, 12492, 12494, 12496, 12498, 12500, 12502, 12504, 12506, 12508, - 12510, 12512, 12514, 12516, 12518, 12520, 12522, 12524, 12526, 12528, - 12530, 12532, 12534, 12536, 12538, 12540, 12542, 0, 12544, 12546, 0, - 12548, 0, 0, 12550, 0, 12552, 12554, 12556, 12558, 12560, 12562, 12564, - 12566, 12568, 12570, 0, 12572, 12574, 12576, 12578, 0, 12580, 0, 12582, - 0, 0, 0, 0, 0, 0, 12584, 0, 0, 0, 0, 12586, 0, 12588, 0, 12590, 0, 12592, - 12594, 12596, 0, 12598, 12600, 0, 12602, 0, 0, 12604, 0, 12606, 0, 12608, - 0, 12610, 0, 12612, 0, 12614, 12616, 0, 12618, 0, 0, 12620, 12622, 12624, - 12626, 0, 12628, 12630, 12632, 12634, 12636, 12638, 12640, 0, 12642, - 12644, 12646, 12648, 0, 12650, 12652, 12654, 12656, 0, 12658, 0, 12660, - 12662, 12664, 12666, 12668, 12670, 12672, 12674, 12676, 12678, 0, 12680, - 12682, 12684, 12686, 12688, 12690, 12692, 12694, 12696, 12698, 12700, - 12702, 12704, 12706, 12708, 12710, 12712, 0, 0, 0, 0, 0, 12714, 12716, - 12718, 0, 12720, 12722, 12724, 12726, 12728, 0, 12730, 12732, 12734, - 12736, 12738, 12740, 12742, 12744, 12746, 12748, 12750, 12752, 12754, - 12756, 12758, 12760, 12762, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 12764, 12767, 12770, 12773, 12776, 12779, 12782, 12785, - 12788, 12791, 12794, 0, 0, 0, 0, 0, 12797, 12801, 12805, 12809, 12813, - 12817, 12821, 12825, 12829, 12833, 12837, 12841, 12845, 12849, 12853, - 12857, 12861, 12865, 12869, 12873, 12877, 12881, 12885, 12889, 12893, - 12897, 12901, 12905, 12907, 12909, 12912, 0, 12915, 12917, 12919, 12921, - 12923, 12925, 12927, 12929, 12931, 12933, 12935, 12937, 12939, 12941, - 12943, 12945, 12947, 12949, 12951, 12953, 12955, 12957, 12959, 12961, - 12963, 12965, 12967, 12970, 12973, 12976, 12979, 12983, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12986, 12989, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12992, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 12995, 12998, 13001, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 13003, 13005, 13007, 13009, 13011, 13013, 13015, 13017, 13019, 13021, - 13023, 13025, 13027, 13029, 13031, 13033, 13035, 13037, 13039, 13041, - 13043, 13045, 13047, 13049, 13051, 13053, 13055, 13057, 13059, 13061, - 13063, 13065, 13067, 13069, 13071, 13073, 13075, 13077, 13079, 13081, - 13083, 13085, 13087, 0, 0, 0, 0, 0, 13089, 13093, 13097, 13101, 13105, - 13109, 13113, 13117, 13121, 0, 0, 0, 0, 0, 0, 0, 13125, 13127, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 13129, 13131, 13133, 13135, 13137, 13139, 13141, 13143, 13145, - 13147, 13149, 13151, 13153, 13155, 13157, 13159, 13161, 13163, 13165, - 13167, 13169, 13171, 13173, 13175, 13177, 13179, 13181, 13183, 13185, - 13187, 13189, 13191, 13193, 13195, 13197, 13199, 13201, 13203, 13205, - 13207, 13209, 13211, 13213, 13215, 13217, 13219, 13221, 13223, 13225, - 13227, 13229, 13231, 13233, 13235, 13237, 13239, 13241, 13243, 13245, - 13247, 13249, 13251, 13253, 13255, 13257, 13259, 13261, 13263, 13265, - 13267, 13269, 13271, 13273, 13275, 13277, 13279, 13281, 13283, 13285, - 13287, 13289, 13291, 13293, 13295, 13297, 13299, 13301, 13303, 13305, - 13307, 13309, 13311, 13313, 13315, 13317, 13319, 13321, 13323, 13325, - 13327, 13329, 13331, 13333, 13335, 13337, 13339, 13341, 13343, 13345, - 13347, 13349, 13351, 13353, 13355, 13357, 13359, 13361, 13363, 13365, - 13367, 13369, 13371, 13373, 13375, 13377, 13379, 13381, 13383, 13385, - 13387, 13389, 13391, 13393, 13395, 13397, 13399, 13401, 13403, 13405, - 13407, 13409, 13411, 13413, 13415, 13417, 13419, 13421, 13423, 13425, - 13427, 13429, 13431, 13433, 13435, 13437, 13439, 13441, 13443, 13445, - 13447, 13449, 13451, 13453, 13455, 13457, 13459, 13461, 13463, 13465, - 13467, 13469, 13471, 13473, 13475, 13477, 13479, 13481, 13483, 13485, - 13487, 13489, 13491, 13493, 13495, 13497, 13499, 13501, 13503, 13505, - 13507, 13509, 13511, 13513, 13515, 13517, 13519, 13521, 13523, 13525, - 13527, 13529, 13531, 13533, 13535, 13537, 13539, 13541, 13543, 13545, - 13547, 13549, 13551, 13553, 13555, 13557, 13559, 13561, 13563, 13565, - 13567, 13569, 13571, 13573, 13575, 13577, 13579, 13581, 13583, 13585, - 13587, 13589, 13591, 13593, 13595, 13597, 13599, 13601, 13603, 13605, - 13607, 13609, 13611, 13613, 13615, 13617, 13619, 13621, 13623, 13625, - 13627, 13629, 13631, 13633, 13635, 13637, 13639, 13641, 13643, 13645, - 13647, 13649, 13651, 13653, 13655, 13657, 13659, 13661, 13663, 13665, - 13667, 13669, 13671, 13673, 13675, 13677, 13679, 13681, 13683, 13685, - 13687, 13689, 13691, 13693, 13695, 13697, 13699, 13701, 13703, 13705, - 13707, 13709, 13711, 13713, 13715, 13717, 13719, 13721, 13723, 13725, - 13727, 13729, 13731, 13733, 13735, 13737, 13739, 13741, 13743, 13745, - 13747, 13749, 13751, 13753, 13755, 13757, 13759, 13761, 13763, 13765, - 13767, 13769, 13771, 13773, 13775, 13777, 13779, 13781, 13783, 13785, - 13787, 13789, 13791, 13793, 13795, 13797, 13799, 13801, 13803, 13805, - 13807, 13809, 13811, 13813, 13815, 13817, 13819, 13821, 13823, 13825, - 13827, 13829, 13831, 13833, 13835, 13837, 13839, 13841, 13843, 13845, - 13847, 13849, 13851, 13853, 13855, 13857, 13859, 13861, 13863, 13865, - 13867, 13869, 13871, 13873, 13875, 13877, 13879, 13881, 13883, 13885, - 13887, 13889, 13891, 13893, 13895, 13897, 13899, 13901, 13903, 13905, - 13907, 13909, 13911, 13913, 13915, 13917, 13919, 13921, 13923, 13925, - 13927, 13929, 13931, 13933, 13935, 13937, 13939, 13941, 13943, 13945, - 13947, 13949, 13951, 13953, 13955, 13957, 13959, 13961, 13963, 13965, - 13967, 13969, 13971, 13973, 13975, 13977, 13979, 13981, 13983, 13985, - 13987, 13989, 13991, 13993, 13995, 13997, 13999, 14001, 14003, 14005, - 14007, 14009, 14011, 14013, 14015, 14017, 14019, 14021, 14023, 14025, - 14027, 14029, 14031, 14033, 14035, 14037, 14039, 14041, 14043, 14045, - 14047, 14049, 14051, 14053, 14055, 14057, 14059, 14061, 14063, 14065, - 14067, 14069, 14071, 14073, 14075, 14077, 14079, 14081, 14083, 14085, - 14087, 14089, 14091, 14093, 14095, 14097, 14099, 14101, 14103, 14105, - 14107, 14109, 14111, 14113, 14115, 14117, 14119, 14121, 14123, 14125, - 14127, 14129, 14131, 14133, 14135, 14137, 14139, 14141, 14143, 14145, - 14147, 14149, 14151, 14153, 14155, 14157, 14159, 14161, 14163, 14165, - 14167, 14169, 14171, 14173, 14175, 14177, 14179, 14181, 14183, 14185, - 14187, 14189, 14191, 14193, 14195, 14197, 14199, 14201, 14203, 14205, - 14207, 14209, 14211, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +static unsigned short decomp_index2[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 6, 0, 0, 0, 0, 8, 0, 0, 11, 13, 15, 18, 0, 0, 20, 23, 25, 0, 27, + 31, 35, 0, 39, 42, 45, 48, 51, 54, 0, 57, 60, 63, 66, 69, 72, 75, 78, 81, + 0, 84, 87, 90, 93, 96, 99, 0, 0, 102, 105, 108, 111, 114, 0, 0, 117, 120, + 123, 126, 129, 132, 0, 135, 138, 141, 144, 147, 150, 153, 156, 159, 0, + 162, 165, 168, 171, 174, 177, 0, 0, 180, 183, 186, 189, 192, 0, 195, 198, + 201, 204, 207, 210, 213, 216, 219, 222, 225, 228, 231, 234, 237, 240, + 243, 0, 0, 246, 249, 252, 255, 258, 261, 264, 267, 270, 273, 276, 279, + 282, 285, 288, 291, 294, 297, 300, 303, 0, 0, 306, 309, 312, 315, 318, + 321, 324, 327, 330, 0, 333, 336, 339, 342, 345, 348, 0, 351, 354, 357, + 360, 363, 366, 369, 372, 0, 0, 375, 378, 381, 384, 387, 390, 393, 0, 0, + 396, 399, 402, 405, 408, 411, 0, 0, 414, 417, 420, 423, 426, 429, 432, + 435, 438, 441, 444, 447, 450, 453, 456, 459, 462, 465, 0, 0, 468, 471, + 474, 477, 480, 483, 486, 489, 492, 495, 498, 501, 504, 507, 510, 513, + 516, 519, 522, 525, 528, 531, 534, 537, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 539, 542, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 545, 548, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 551, 554, 557, 560, 563, 566, 569, 572, + 575, 578, 581, 584, 587, 590, 593, 596, 599, 602, 605, 608, 611, 614, + 617, 620, 623, 0, 626, 629, 632, 635, 638, 641, 0, 0, 644, 647, 650, 653, + 656, 659, 662, 665, 668, 671, 674, 677, 680, 683, 686, 689, 0, 0, 692, + 695, 698, 701, 704, 707, 710, 713, 716, 719, 722, 725, 728, 731, 734, + 737, 740, 743, 746, 749, 752, 755, 758, 761, 764, 767, 770, 773, 776, + 779, 782, 785, 788, 791, 794, 797, 0, 0, 800, 803, 0, 0, 0, 0, 0, 0, 806, + 809, 812, 815, 818, 821, 824, 827, 830, 833, 836, 839, 842, 845, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 848, 850, 852, 854, 856, 858, 860, 862, 864, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 866, + 869, 872, 875, 878, 881, 0, 0, 884, 886, 888, 890, 892, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 894, 896, 0, 898, 900, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 903, 0, 0, 0, 0, + 0, 905, 0, 0, 0, 908, 0, 0, 0, 0, 0, 910, 913, 916, 919, 921, 924, 927, + 0, 930, 0, 933, 936, 939, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 942, 945, 948, 951, 954, 957, 960, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 963, 966, + 969, 972, 975, 0, 978, 980, 982, 984, 987, 990, 992, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 994, 996, 998, 0, + 1000, 1002, 0, 0, 0, 1004, 0, 0, 0, 0, 0, 0, 1006, 1009, 0, 1012, 0, 0, + 0, 1015, 0, 0, 0, 0, 1018, 1021, 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1027, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1030, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1033, 1036, 0, 1039, 0, 0, 0, 1042, 0, 0, 0, + 0, 1045, 1048, 1051, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1054, 1057, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1060, 1063, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1066, 1069, 1072, 1075, 0, 0, 1078, 1081, 0, 0, 1084, 1087, + 1090, 1093, 1096, 1099, 0, 0, 1102, 1105, 1108, 1111, 1114, 1117, 0, 0, + 1120, 1123, 1126, 1129, 1132, 1135, 1138, 1141, 1144, 1147, 1150, 1153, + 0, 0, 1156, 1159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1162, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1165, 1168, 1171, 1174, 1177, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1180, 1183, 1186, 1189, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1192, 0, 1195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1201, 0, 0, 0, + 0, 0, 0, 0, 1204, 0, 0, 1207, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1210, + 1213, 1216, 1219, 1222, 1225, 1228, 1231, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1234, 1237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1240, 1243, + 0, 1246, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1249, 0, 0, 1252, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1255, 1258, 1261, 0, 0, 1264, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1267, 0, 0, 1270, 1273, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1276, 1279, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1282, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1285, 1288, 1291, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1294, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1297, 0, 0, 0, 0, 0, 0, 1300, 1303, 0, 1306, 1309, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1312, 1315, 1318, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1321, 0, 1324, 1327, 1330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1336, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1339, 1342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1345, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1347, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1350, 0, 0, 0, 0, 1353, 0, 0, 0, 0, 1356, 0, 0, 0, 0, 1359, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1362, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1365, 0, + 1368, 1371, 1374, 1377, 1380, 0, 0, 0, 0, 0, 0, 0, 1383, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1386, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1389, 0, 0, 0, 0, 1392, 0, 0, 0, 0, 1395, 0, 0, 0, 0, 1398, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1401, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1404, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1407, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1409, 0, 1412, 0, 1415, 0, 1418, 0, 1421, 0, 0, + 0, 1424, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1427, 0, 1430, + 0, 0, 1433, 1436, 0, 1439, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1442, 1444, 1446, 0, + 1448, 1450, 1452, 1454, 1456, 1458, 1460, 1462, 1464, 1466, 1468, 0, + 1470, 1472, 1474, 1476, 1478, 1480, 1482, 1484, 1486, 1488, 1490, 1492, + 1494, 1496, 1498, 1500, 1502, 1504, 0, 1506, 1508, 1510, 1512, 1514, + 1516, 1518, 1520, 1522, 1524, 1526, 1528, 1530, 1532, 1534, 1536, 1538, + 1540, 1542, 1544, 1546, 1548, 1550, 1552, 1554, 1556, 1558, 1560, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1562, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1564, 1566, 1568, 1570, 1572, 1574, 1576, 1578, 1580, 1582, 1584, 1586, + 1588, 1590, 1592, 1594, 1596, 1598, 1600, 1602, 1604, 1606, 1608, 1610, + 1612, 1614, 1616, 1618, 1620, 1622, 1624, 1626, 1628, 1630, 1632, 1634, + 1636, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1638, 1641, 1644, + 1647, 1650, 1653, 1656, 1659, 1662, 1665, 1668, 1671, 1674, 1677, 1680, + 1683, 1686, 1689, 1692, 1695, 1698, 1701, 1704, 1707, 1710, 1713, 1716, + 1719, 1722, 1725, 1728, 1731, 1734, 1737, 1740, 1743, 1746, 1749, 1752, + 1755, 1758, 1761, 1764, 1767, 1770, 1773, 1776, 1779, 1782, 1785, 1788, + 1791, 1794, 1797, 1800, 1803, 1806, 1809, 1812, 1815, 1818, 1821, 1824, + 1827, 1830, 1833, 1836, 1839, 1842, 1845, 1848, 1851, 1854, 1857, 1860, + 1863, 1866, 1869, 1872, 1875, 1878, 1881, 1884, 1887, 1890, 1893, 1896, + 1899, 1902, 1905, 1908, 1911, 1914, 1917, 1920, 1923, 1926, 1929, 1932, + 1935, 1938, 1941, 1944, 1947, 1950, 1953, 1956, 1959, 1962, 1965, 1968, + 1971, 1974, 1977, 1980, 1983, 1986, 1989, 1992, 1995, 1998, 2001, 2004, + 2007, 2010, 2013, 2016, 2019, 2022, 2025, 2028, 2031, 2034, 2037, 2040, + 2043, 2046, 2049, 2052, 2055, 2058, 2061, 2064, 2067, 2070, 2073, 2076, + 2079, 2082, 2085, 2088, 2091, 2094, 2097, 2100, 2103, 0, 0, 0, 0, 2106, + 2109, 2112, 2115, 2118, 2121, 2124, 2127, 2130, 2133, 2136, 2139, 2142, + 2145, 2148, 2151, 2154, 2157, 2160, 2163, 2166, 2169, 2172, 2175, 2178, + 2181, 2184, 2187, 2190, 2193, 2196, 2199, 2202, 2205, 2208, 2211, 2214, + 2217, 2220, 2223, 2226, 2229, 2232, 2235, 2238, 2241, 2244, 2247, 2250, + 2253, 2256, 2259, 2262, 2265, 2268, 2271, 2274, 2277, 2280, 2283, 2286, + 2289, 2292, 2295, 2298, 2301, 2304, 2307, 2310, 2313, 2316, 2319, 2322, + 2325, 2328, 2331, 2334, 2337, 2340, 2343, 2346, 2349, 2352, 2355, 2358, + 2361, 2364, 2367, 2370, 2373, 0, 0, 0, 0, 0, 0, 2376, 2379, 2382, 2385, + 2388, 2391, 2394, 2397, 2400, 2403, 2406, 2409, 2412, 2415, 2418, 2421, + 2424, 2427, 2430, 2433, 2436, 2439, 0, 0, 2442, 2445, 2448, 2451, 2454, + 2457, 0, 0, 2460, 2463, 2466, 2469, 2472, 2475, 2478, 2481, 2484, 2487, + 2490, 2493, 2496, 2499, 2502, 2505, 2508, 2511, 2514, 2517, 2520, 2523, + 2526, 2529, 2532, 2535, 2538, 2541, 2544, 2547, 2550, 2553, 2556, 2559, + 2562, 2565, 2568, 2571, 0, 0, 2574, 2577, 2580, 2583, 2586, 2589, 0, 0, + 2592, 2595, 2598, 2601, 2604, 2607, 2610, 2613, 0, 2616, 0, 2619, 0, + 2622, 0, 2625, 2628, 2631, 2634, 2637, 2640, 2643, 2646, 2649, 2652, + 2655, 2658, 2661, 2664, 2667, 2670, 2673, 2676, 2679, 2681, 2684, 2686, + 2689, 2691, 2694, 2696, 2699, 2701, 2704, 2706, 2709, 0, 0, 2711, 2714, + 2717, 2720, 2723, 2726, 2729, 2732, 2735, 2738, 2741, 2744, 2747, 2750, + 2753, 2756, 2759, 2762, 2765, 2768, 2771, 2774, 2777, 2780, 2783, 2786, + 2789, 2792, 2795, 2798, 2801, 2804, 2807, 2810, 2813, 2816, 2819, 2822, + 2825, 2828, 2831, 2834, 2837, 2840, 2843, 2846, 2849, 2852, 2855, 2858, + 2861, 2864, 2867, 0, 2870, 2873, 2876, 2879, 2882, 2885, 2887, 2890, + 2893, 2895, 2898, 2901, 2904, 2907, 2910, 0, 2913, 2916, 2919, 2922, + 2924, 2927, 2929, 2932, 2935, 2938, 2941, 2944, 2947, 2950, 0, 0, 2952, + 2955, 2958, 2961, 2964, 2967, 0, 2969, 2972, 2975, 2978, 2981, 2984, + 2987, 2989, 2992, 2995, 2998, 3001, 3004, 3007, 3010, 3012, 3015, 3018, + 3020, 0, 0, 3022, 3025, 3028, 0, 3031, 3034, 3037, 3040, 3042, 3045, + 3047, 3050, 3052, 0, 3055, 3057, 3059, 3061, 3063, 3065, 3067, 3069, + 3071, 3073, 3075, 0, 0, 0, 0, 0, 0, 3077, 0, 0, 0, 0, 0, 3079, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3082, 3084, 3087, 0, 0, 0, 0, 0, 0, 0, 0, + 3091, 0, 0, 0, 3093, 3096, 0, 3100, 3103, 0, 0, 0, 0, 3107, 0, 3110, 0, + 0, 0, 0, 0, 0, 0, 0, 3113, 3116, 3119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3122, 0, 0, 0, 0, 0, 0, 0, 3127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3129, 3131, 0, 0, 3133, 3135, 3137, 3139, 3141, 3143, + 3145, 3147, 3149, 3151, 3153, 3155, 3157, 3159, 3161, 3163, 3165, 3167, + 3169, 3171, 3173, 3175, 3177, 3179, 3181, 3183, 3185, 0, 3187, 3189, + 3191, 3193, 3195, 3197, 3199, 3201, 3203, 3205, 3207, 3209, 3211, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3213, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3216, 3220, 3224, 3226, 0, 3229, 3233, 3237, 0, 3239, 3242, 3244, + 3246, 3248, 3250, 3252, 3254, 3256, 3258, 3260, 0, 3262, 3264, 0, 0, + 3267, 3269, 3271, 3273, 3275, 0, 0, 3277, 3280, 3284, 0, 3287, 0, 3289, + 0, 3291, 0, 3293, 3295, 3297, 3299, 0, 3301, 3303, 3305, 0, 3307, 3309, + 3311, 3313, 3315, 3317, 3319, 0, 3321, 3325, 3327, 3329, 3331, 3333, 0, + 0, 0, 0, 3335, 3337, 3339, 3341, 3343, 0, 0, 0, 0, 0, 0, 3345, 3349, + 3353, 3358, 3362, 3366, 3370, 3374, 3378, 3382, 3386, 3390, 3394, 3398, + 3402, 3406, 3409, 3411, 3414, 3418, 3421, 3423, 3426, 3430, 3435, 3438, + 3440, 3443, 3447, 3449, 3451, 3453, 3455, 3457, 3460, 3464, 3467, 3469, + 3472, 3476, 3481, 3484, 3486, 3489, 3493, 3495, 3497, 3499, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3501, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3505, 3508, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3511, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 3514, 3517, 3520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3523, 0, 0, 0, 0, 3526, + 0, 0, 3529, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3532, 0, 3535, 0, 0, 0, 0, 0, 3538, 3541, 0, 3545, 3548, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3552, 0, 0, 3555, 0, 0, 3558, + 0, 3561, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3564, 0, 3567, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3570, 3573, 3576, 3579, + 3582, 0, 0, 3585, 3588, 0, 0, 3591, 3594, 0, 0, 0, 0, 0, 0, 3597, 3600, + 0, 0, 3603, 3606, 0, 0, 3609, 3612, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3615, + 3618, 3621, 3624, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 3627, 3630, 3633, 3636, 0, 0, 0, 0, 0, 0, 3639, 3642, + 3645, 3648, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3651, 3653, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3655, 3657, 3659, 3661, 3663, 3665, 3667, 3669, + 3671, 3673, 3676, 3679, 3682, 3685, 3688, 3691, 3694, 3697, 3700, 3703, + 3706, 3710, 3714, 3718, 3722, 3726, 3730, 3734, 3738, 3742, 3747, 3752, + 3757, 3762, 3767, 3772, 3777, 3782, 3787, 3792, 3797, 3800, 3803, 3806, + 3809, 3812, 3815, 3818, 3821, 3824, 3828, 3832, 3836, 3840, 3844, 3848, + 3852, 3856, 3860, 3864, 3868, 3872, 3876, 3880, 3884, 3888, 3892, 3896, + 3900, 3904, 3908, 3912, 3916, 3920, 3924, 3928, 3932, 3936, 3940, 3944, + 3948, 3952, 3956, 3960, 3964, 3968, 3972, 3974, 3976, 3978, 3980, 3982, + 3984, 3986, 3988, 3990, 3992, 3994, 3996, 3998, 4000, 4002, 4004, 4006, + 4008, 4010, 4012, 4014, 4016, 4018, 4020, 4022, 4024, 4026, 4028, 4030, + 4032, 4034, 4036, 4038, 4040, 4042, 4044, 4046, 4048, 4050, 4052, 4054, + 4056, 4058, 4060, 4062, 4064, 4066, 4068, 4070, 4072, 4074, 4076, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 4078, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4083, 4087, 4090, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 4094, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4097, 4099, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4101, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4103, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 4105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4107, + 4109, 4111, 4113, 4115, 4117, 4119, 4121, 4123, 4125, 4127, 4129, 4131, + 4133, 4135, 4137, 4139, 4141, 4143, 4145, 4147, 4149, 4151, 4153, 4155, + 4157, 4159, 4161, 4163, 4165, 4167, 4169, 4171, 4173, 4175, 4177, 4179, + 4181, 4183, 4185, 4187, 4189, 4191, 4193, 4195, 4197, 4199, 4201, 4203, + 4205, 4207, 4209, 4211, 4213, 4215, 4217, 4219, 4221, 4223, 4225, 4227, + 4229, 4231, 4233, 4235, 4237, 4239, 4241, 4243, 4245, 4247, 4249, 4251, + 4253, 4255, 4257, 4259, 4261, 4263, 4265, 4267, 4269, 4271, 4273, 4275, + 4277, 4279, 4281, 4283, 4285, 4287, 4289, 4291, 4293, 4295, 4297, 4299, + 4301, 4303, 4305, 4307, 4309, 4311, 4313, 4315, 4317, 4319, 4321, 4323, + 4325, 4327, 4329, 4331, 4333, 4335, 4337, 4339, 4341, 4343, 4345, 4347, + 4349, 4351, 4353, 4355, 4357, 4359, 4361, 4363, 4365, 4367, 4369, 4371, + 4373, 4375, 4377, 4379, 4381, 4383, 4385, 4387, 4389, 4391, 4393, 4395, + 4397, 4399, 4401, 4403, 4405, 4407, 4409, 4411, 4413, 4415, 4417, 4419, + 4421, 4423, 4425, 4427, 4429, 4431, 4433, 4435, 4437, 4439, 4441, 4443, + 4445, 4447, 4449, 4451, 4453, 4455, 4457, 4459, 4461, 4463, 4465, 4467, + 4469, 4471, 4473, 4475, 4477, 4479, 4481, 4483, 4485, 4487, 4489, 4491, + 4493, 4495, 4497, 4499, 4501, 4503, 4505, 4507, 4509, 4511, 4513, 4515, + 4517, 4519, 4521, 4523, 4525, 4527, 4529, 4531, 4533, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4535, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4537, 0, 4539, + 4541, 4543, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4545, 0, + 4548, 0, 4551, 0, 4554, 0, 4557, 0, 4560, 0, 4563, 0, 4566, 0, 4569, 0, + 4572, 0, 4575, 0, 4578, 0, 0, 4581, 0, 4584, 0, 4587, 0, 0, 0, 0, 0, 0, + 4590, 4593, 0, 4596, 4599, 0, 4602, 4605, 0, 4608, 4611, 0, 4614, 4617, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4620, + 0, 0, 0, 0, 0, 0, 4623, 4626, 0, 4629, 4632, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 4635, 0, 4638, 0, 4641, 0, 4644, 0, 4647, 0, 4650, 0, 4653, 0, + 4656, 0, 4659, 0, 4662, 0, 4665, 0, 4668, 0, 0, 4671, 0, 4674, 0, 4677, + 0, 0, 0, 0, 0, 0, 4680, 4683, 0, 4686, 4689, 0, 4692, 4695, 0, 4698, + 4701, 0, 4704, 4707, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 4710, 0, 0, 4713, 4716, 4719, 4722, 0, 0, 0, 4725, 4728, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 4731, 4733, 4735, 4737, 4739, 4741, 4743, 4745, 4747, 4749, 4751, + 4753, 4755, 4757, 4759, 4761, 4763, 4765, 4767, 4769, 4771, 4773, 4775, + 4777, 4779, 4781, 4783, 4785, 4787, 4789, 4791, 4793, 4795, 4797, 4799, + 4801, 4803, 4805, 4807, 4809, 4811, 4813, 4815, 4817, 4819, 4821, 4823, + 4825, 4827, 4829, 4831, 4833, 4835, 4837, 4839, 4841, 4843, 4845, 4847, + 4849, 4851, 4853, 4855, 4857, 4859, 4861, 4863, 4865, 4867, 4869, 4871, + 4873, 4875, 4877, 4879, 4881, 4883, 4885, 4887, 4889, 4891, 4893, 4895, + 4897, 4899, 4901, 4903, 4905, 4907, 4909, 4911, 4913, 4915, 4917, 0, 0, + 0, 4919, 4921, 4923, 4925, 4927, 4929, 4931, 4933, 4935, 4937, 4939, + 4941, 4943, 4945, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 4947, 4951, 4955, 4959, 4963, 4967, 4971, 4975, 4979, + 4983, 4987, 4991, 4995, 4999, 5003, 5008, 5013, 5018, 5023, 5028, 5033, + 5038, 5043, 5048, 5053, 5058, 5063, 5068, 5073, 5078, 5086, 0, 5093, + 5097, 5101, 5105, 5109, 5113, 5117, 5121, 5125, 5129, 5133, 5137, 5141, + 5145, 5149, 5153, 5157, 5161, 5165, 5169, 5173, 5177, 5181, 5185, 5189, + 5193, 5197, 5201, 5205, 5209, 5213, 5217, 5221, 5225, 5229, 5233, 5237, + 5239, 5241, 5243, 0, 0, 0, 0, 0, 0, 0, 0, 5245, 5249, 5252, 5255, 5258, + 5261, 5264, 5267, 5270, 5273, 5276, 5279, 5282, 5285, 5288, 5291, 5294, + 5296, 5298, 5300, 5302, 5304, 5306, 5308, 5310, 5312, 5314, 5316, 5318, + 5320, 5322, 5325, 5328, 5331, 5334, 5337, 5340, 5343, 5346, 5349, 5352, + 5355, 5358, 5361, 5364, 5370, 5375, 0, 5378, 5380, 5382, 5384, 5386, + 5388, 5390, 5392, 5394, 5396, 5398, 5400, 5402, 5404, 5406, 5408, 5410, + 5412, 5414, 5416, 5418, 5420, 5422, 5424, 5426, 5428, 5430, 5432, 5434, + 5436, 5438, 5440, 5442, 5444, 5446, 5448, 5450, 5452, 5454, 5456, 5458, + 5460, 5462, 5464, 5466, 5468, 5470, 5472, 5474, 5476, 5479, 5482, 5485, + 5488, 5491, 5494, 5497, 5500, 5503, 5506, 5509, 5512, 5515, 5518, 5521, + 5524, 5527, 5530, 5533, 5536, 5539, 5542, 5545, 5548, 5552, 5556, 5560, + 5563, 5567, 5570, 5574, 5576, 5578, 5580, 5582, 5584, 5586, 5588, 5590, + 5592, 5594, 5596, 5598, 5600, 5602, 5604, 5606, 5608, 5610, 5612, 5614, + 5616, 5618, 5620, 5622, 5624, 5626, 5628, 5630, 5632, 5634, 5636, 5638, + 5640, 5642, 5644, 5646, 5648, 5650, 5652, 5654, 5656, 5658, 5660, 5662, + 5664, 5666, 0, 5668, 5673, 5678, 5683, 5687, 5692, 5696, 5700, 5706, + 5711, 5715, 5719, 5723, 5728, 5733, 5737, 5741, 5744, 5748, 5753, 5758, + 5761, 5767, 5774, 5780, 5784, 5790, 5796, 5801, 5805, 5809, 5813, 5818, + 5824, 5829, 5833, 5837, 5841, 5844, 5847, 5850, 5853, 5857, 5861, 5867, + 5871, 5876, 5882, 5886, 5889, 5892, 5898, 5903, 5909, 5913, 5919, 5922, + 5926, 5930, 5934, 5938, 5942, 5947, 5951, 5954, 5958, 5962, 5966, 5971, + 5975, 5979, 5983, 5989, 5994, 5997, 6003, 6006, 6011, 6016, 6020, 6024, + 6028, 6033, 6036, 6040, 6045, 6048, 6054, 6058, 6061, 6064, 6067, 6070, + 6073, 6076, 6079, 6082, 6085, 6088, 6092, 6096, 6100, 6104, 6108, 6112, + 6116, 6120, 6124, 6128, 6132, 6136, 6140, 6144, 6148, 6152, 6155, 6158, + 6162, 6165, 6168, 6171, 6175, 6179, 6182, 6185, 6188, 6191, 6194, 6199, + 6202, 6205, 6208, 6211, 6214, 6217, 6220, 6223, 6227, 6232, 6235, 6238, + 6241, 6244, 6247, 6250, 6253, 6257, 6261, 6265, 6269, 6272, 6275, 6278, + 6281, 6284, 6287, 6290, 6293, 6296, 6299, 6303, 6307, 6310, 6314, 6318, + 6322, 6325, 6329, 6333, 6338, 6341, 6345, 6349, 6353, 6357, 6363, 6370, + 6373, 6376, 6379, 6382, 6385, 6388, 6391, 6394, 6397, 6400, 6403, 6406, + 6409, 6412, 6415, 6418, 6421, 6424, 6429, 6432, 6435, 6438, 6443, 6447, + 6450, 6453, 6456, 6459, 6462, 6465, 6468, 6471, 6474, 6477, 6481, 6484, + 6487, 6491, 6495, 6498, 6503, 6507, 6510, 6513, 6516, 6519, 6523, 6527, + 6530, 6533, 6536, 6539, 6542, 6545, 6548, 6551, 6554, 6558, 6562, 6566, + 6570, 6574, 6578, 6582, 6586, 6590, 6594, 6598, 6602, 6606, 6610, 6614, + 6618, 6622, 6626, 6630, 6634, 6638, 6642, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6646, 6648, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6650, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 6652, 6654, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6656, 6658, 6660, 6662, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 6664, 6666, 6668, 6670, 6672, 6674, 6676, 6678, + 6680, 6682, 6684, 6686, 6688, 6690, 6692, 6694, 6696, 6698, 6700, 6702, + 6704, 6706, 6708, 6710, 6712, 6714, 6716, 6718, 6720, 6722, 6724, 6726, + 6728, 6730, 6732, 6734, 6736, 6738, 6740, 6742, 6744, 6746, 6748, 6750, + 6752, 6754, 6756, 6758, 6760, 6762, 6764, 6766, 6768, 6770, 6772, 6774, + 6776, 6778, 6780, 6782, 6784, 6786, 6788, 6790, 6792, 6794, 6796, 6798, + 6800, 6802, 6804, 6806, 6808, 6810, 6812, 6814, 6816, 6818, 6820, 6822, + 6824, 6826, 6828, 6830, 6832, 6834, 6836, 6838, 6840, 6842, 6844, 6846, + 6848, 6850, 6852, 6854, 6856, 6858, 6860, 6862, 6864, 6866, 6868, 6870, + 6872, 6874, 6876, 6878, 6880, 6882, 6884, 6886, 6888, 6890, 6892, 6894, + 6896, 6898, 6900, 6902, 6904, 6906, 6908, 6910, 6912, 6914, 6916, 6918, + 6920, 6922, 6924, 6926, 6928, 6930, 6932, 6934, 6936, 6938, 6940, 6942, + 6944, 6946, 6948, 6950, 6952, 6954, 6956, 6958, 6960, 6962, 6964, 6966, + 6968, 6970, 6972, 6974, 6976, 6978, 6980, 6982, 6984, 6986, 6988, 6990, + 6992, 6994, 6996, 6998, 7000, 7002, 7004, 7006, 7008, 7010, 7012, 7014, + 7016, 7018, 7020, 7022, 7024, 7026, 7028, 7030, 7032, 7034, 7036, 7038, + 7040, 7042, 7044, 7046, 7048, 7050, 7052, 7054, 7056, 7058, 7060, 7062, + 7064, 7066, 7068, 7070, 7072, 7074, 7076, 7078, 7080, 7082, 7084, 7086, + 7088, 7090, 7092, 7094, 7096, 7098, 7100, 7102, 7104, 7106, 7108, 7110, + 7112, 7114, 7116, 7118, 7120, 7122, 7124, 7126, 7128, 7130, 7132, 7134, + 7136, 7138, 7140, 7142, 7144, 7146, 7148, 7150, 7152, 7154, 7156, 7158, + 7160, 7162, 7164, 7166, 7168, 7170, 7172, 7174, 7176, 7178, 7180, 7182, + 7184, 7186, 7188, 7190, 7192, 7194, 7196, 7198, 7200, 7202, 0, 0, 7204, + 0, 7206, 0, 0, 7208, 7210, 7212, 7214, 7216, 7218, 7220, 7222, 7224, + 7226, 0, 7228, 0, 7230, 0, 0, 7232, 7234, 0, 0, 0, 7236, 7238, 7240, + 7242, 7244, 7246, 7248, 7250, 7252, 7254, 7256, 7258, 7260, 7262, 7264, + 7266, 7268, 7270, 7272, 7274, 7276, 7278, 7280, 7282, 7284, 7286, 7288, + 7290, 7292, 7294, 7296, 7298, 7300, 7302, 7304, 7306, 7308, 7310, 7312, + 7314, 7316, 7318, 7320, 7322, 7324, 7326, 7328, 7330, 7332, 7334, 7336, + 7338, 7340, 7342, 7344, 7346, 7348, 7350, 7352, 7354, 7356, 7358, 7360, + 7362, 7364, 7366, 7368, 7370, 0, 0, 7372, 7374, 7376, 7378, 7380, 7382, + 7384, 7386, 7388, 7390, 7392, 7394, 7396, 7398, 7400, 7402, 7404, 7406, + 7408, 7410, 7412, 7414, 7416, 7418, 7420, 7422, 7424, 7426, 7428, 7430, + 7432, 7434, 7436, 7438, 7440, 7442, 7444, 7446, 7448, 7450, 7452, 7454, + 7456, 7458, 7460, 7462, 7464, 7466, 7468, 7470, 7472, 7474, 7476, 7478, + 7480, 7482, 7484, 7486, 7488, 7490, 7492, 7494, 7496, 7498, 7500, 7502, + 7504, 7506, 7508, 7510, 7512, 7514, 7516, 7518, 7520, 7522, 7524, 7526, + 7528, 7530, 7532, 7534, 7536, 7538, 7540, 7542, 7544, 7546, 7548, 7550, + 7552, 7554, 7556, 7558, 7560, 7562, 7564, 7566, 7568, 7570, 7572, 7574, + 7576, 7578, 7580, 7582, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7584, + 7587, 7590, 7593, 7597, 7601, 7604, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 7607, 7610, 7613, 7616, 7619, 0, 0, 0, 0, 0, 7622, 0, 7625, 7628, 7630, + 7632, 7634, 7636, 7638, 7640, 7642, 7644, 7646, 7648, 7651, 7654, 7657, + 7660, 7663, 7666, 7669, 7672, 7675, 7678, 7681, 7684, 0, 7687, 7690, + 7693, 7696, 7699, 0, 7702, 0, 7705, 7708, 0, 7711, 7714, 0, 7717, 7720, + 7723, 7726, 7729, 7732, 7735, 7738, 7741, 7744, 7747, 7749, 7751, 7753, + 7755, 7757, 7759, 7761, 7763, 7765, 7767, 7769, 7771, 7773, 7775, 7777, + 7779, 7781, 7783, 7785, 7787, 7789, 7791, 7793, 7795, 7797, 7799, 7801, + 7803, 7805, 7807, 7809, 7811, 7813, 7815, 7817, 7819, 7821, 7823, 7825, + 7827, 7829, 7831, 7833, 7835, 7837, 7839, 7841, 7843, 7845, 7847, 7849, + 7851, 7853, 7855, 7857, 7859, 7861, 7863, 7865, 7867, 7869, 7871, 7873, + 7875, 7877, 7879, 7881, 7883, 7885, 7887, 7889, 7891, 7893, 7895, 7897, + 7899, 7901, 7903, 7905, 7907, 7909, 7911, 7913, 7915, 7917, 7919, 7921, + 7923, 7925, 7927, 7929, 7931, 7933, 7935, 7937, 7939, 7941, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 7943, 7945, 7947, 7949, 7951, 7953, 7955, 7957, 7959, + 7961, 7963, 7965, 7967, 7969, 7971, 7973, 7975, 7977, 7979, 7981, 7983, + 7985, 7987, 7989, 7992, 7995, 7998, 8001, 8004, 8007, 8010, 8013, 8016, + 8019, 8022, 8025, 8028, 8031, 8034, 8037, 8040, 8043, 8045, 8047, 8049, + 8051, 8054, 8057, 8060, 8063, 8066, 8069, 8072, 8075, 8078, 8081, 8084, + 8087, 8090, 8093, 8096, 8099, 8102, 8105, 8108, 8111, 8114, 8117, 8120, + 8123, 8126, 8129, 8132, 8135, 8138, 8141, 8144, 8147, 8150, 8153, 8156, + 8159, 8162, 8165, 8168, 8171, 8174, 8177, 8180, 8183, 8186, 8189, 8192, + 8195, 8198, 8201, 8204, 8207, 8210, 8213, 8216, 8219, 8222, 8225, 8228, + 8231, 8234, 8237, 8240, 8243, 8246, 8249, 8252, 8255, 8258, 8261, 8264, + 8267, 8270, 8273, 8276, 8279, 8282, 8285, 8288, 8291, 8294, 8297, 8300, + 8303, 8306, 8309, 8312, 8315, 8318, 8321, 8324, 8327, 8330, 8333, 8337, + 8341, 8345, 8349, 8353, 8357, 8360, 8363, 8366, 8369, 8372, 8375, 8378, + 8381, 8384, 8387, 8390, 8393, 8396, 8399, 8402, 8405, 8408, 8411, 8414, + 8417, 8420, 8423, 8426, 8429, 8432, 8435, 8438, 8441, 8444, 8447, 8450, + 8453, 8456, 8459, 8462, 8465, 8468, 8471, 8474, 8477, 8480, 8483, 8486, + 8489, 8492, 8495, 8498, 8501, 8504, 8507, 8510, 8513, 8516, 8519, 8522, + 8525, 8528, 8531, 8534, 8537, 8540, 8543, 8546, 8549, 8552, 8555, 8558, + 8561, 8564, 8567, 8570, 8573, 8576, 8579, 8582, 8585, 8588, 8591, 8594, + 8597, 8600, 8603, 8606, 8609, 8612, 8615, 8618, 8621, 8624, 8627, 8630, + 8633, 8636, 8639, 8642, 8645, 8648, 8651, 8654, 8657, 8660, 8663, 8666, + 8669, 8672, 8675, 8678, 8681, 8684, 8687, 8690, 8693, 8696, 8699, 8702, + 8705, 8708, 8711, 8714, 8717, 8720, 8723, 8726, 8729, 8732, 8735, 8738, + 8741, 8744, 8747, 8750, 8753, 8756, 8759, 8762, 8765, 8768, 8771, 8774, + 8777, 8780, 8783, 8787, 8791, 8795, 8798, 8801, 8804, 8807, 8810, 8813, + 8816, 8819, 8822, 8825, 8828, 8831, 8834, 8837, 8840, 8843, 8846, 8849, + 8852, 8855, 8858, 8861, 8864, 8867, 8870, 8873, 8876, 8879, 8882, 8885, + 8888, 8891, 8894, 8897, 8900, 8903, 8906, 8909, 8912, 8915, 8918, 8921, + 8924, 8927, 8930, 8933, 8936, 8939, 8942, 8945, 8948, 8951, 8954, 8957, + 8960, 8963, 8966, 8969, 8972, 8975, 8978, 8981, 8984, 8987, 8990, 8993, + 8996, 8999, 9002, 9005, 9008, 9011, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9014, 9018, 9022, 9026, 9030, 9034, 9038, 9042, 9046, + 9050, 9054, 9058, 9062, 9066, 9070, 9074, 9078, 9082, 9086, 9090, 9094, + 9098, 9102, 9106, 9110, 9114, 9118, 9122, 9126, 9130, 9134, 9138, 9142, + 9146, 9150, 9154, 9158, 9162, 9166, 9170, 9174, 9178, 9182, 9186, 9190, + 9194, 9198, 9202, 9206, 9210, 9214, 9218, 9222, 9226, 9230, 9234, 9238, + 9242, 9246, 9250, 9254, 9258, 9262, 9266, 0, 0, 9270, 9274, 9278, 9282, + 9286, 9290, 9294, 9298, 9302, 9306, 9310, 9314, 9318, 9322, 9326, 9330, + 9334, 9338, 9342, 9346, 9350, 9354, 9358, 9362, 9366, 9370, 9374, 9378, + 9382, 9386, 9390, 9394, 9398, 9402, 9406, 9410, 9414, 9418, 9422, 9426, + 9430, 9434, 9438, 9442, 9446, 9450, 9454, 9458, 9462, 9466, 9470, 9474, + 9478, 9482, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9486, 9490, + 9494, 9499, 9504, 9509, 9514, 9519, 9524, 9529, 9533, 9552, 9561, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9566, 9568, 9570, + 9572, 9574, 9576, 9578, 9580, 9582, 9584, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9586, 9588, 9590, 9592, 9594, 9596, + 9598, 9600, 9602, 9604, 9606, 9608, 9610, 9612, 9614, 9616, 9618, 9620, + 9622, 9624, 9626, 0, 0, 9628, 9630, 9632, 9634, 9636, 9638, 9640, 9642, + 9644, 9646, 9648, 9650, 0, 9652, 9654, 9656, 9658, 9660, 9662, 9664, + 9666, 9668, 9670, 9672, 9674, 9676, 9678, 9680, 9682, 9684, 9686, 9688, + 0, 9690, 9692, 9694, 9696, 0, 0, 0, 0, 9698, 9701, 9704, 0, 9707, 0, + 9710, 9713, 9716, 9719, 9722, 9725, 9728, 9731, 9734, 9737, 9740, 9742, + 9744, 9746, 9748, 9750, 9752, 9754, 9756, 9758, 9760, 9762, 9764, 9766, + 9768, 9770, 9772, 9774, 9776, 9778, 9780, 9782, 9784, 9786, 9788, 9790, + 9792, 9794, 9796, 9798, 9800, 9802, 9804, 9806, 9808, 9810, 9812, 9814, + 9816, 9818, 9820, 9822, 9824, 9826, 9828, 9830, 9832, 9834, 9836, 9838, + 9840, 9842, 9844, 9846, 9848, 9850, 9852, 9854, 9856, 9858, 9860, 9862, + 9864, 9866, 9868, 9870, 9872, 9874, 9876, 9878, 9880, 9882, 9884, 9886, + 9888, 9890, 9892, 9894, 9896, 9898, 9900, 9902, 9904, 9906, 9908, 9910, + 9912, 9914, 9916, 9918, 9920, 9922, 9924, 9926, 9928, 9930, 9932, 9934, + 9936, 9938, 9940, 9942, 9944, 9946, 9948, 9950, 9952, 9954, 9956, 9958, + 9960, 9962, 9964, 9966, 9968, 9970, 9972, 9974, 9977, 9980, 9983, 9986, + 9989, 9992, 9995, 0, 0, 0, 0, 9998, 10000, 10002, 10004, 10006, 10008, + 10010, 10012, 10014, 10016, 10018, 10020, 10022, 10024, 10026, 10028, + 10030, 10032, 10034, 10036, 10038, 10040, 10042, 10044, 10046, 10048, + 10050, 10052, 10054, 10056, 10058, 10060, 10062, 10064, 10066, 10068, + 10070, 10072, 10074, 10076, 10078, 10080, 10082, 10084, 10086, 10088, + 10090, 10092, 10094, 10096, 10098, 10100, 10102, 10104, 10106, 10108, + 10110, 10112, 10114, 10116, 10118, 10120, 10122, 10124, 10126, 10128, + 10130, 10132, 10134, 10136, 10138, 10140, 10142, 10144, 10146, 10148, + 10150, 10152, 10154, 10156, 10158, 10160, 10162, 10164, 10166, 10168, + 10170, 10172, 10174, 10176, 10178, 10180, 10182, 10184, 10186, 10188, + 10190, 10192, 10194, 10196, 10198, 10200, 10202, 10204, 10206, 10208, + 10210, 10212, 10214, 10216, 10218, 10220, 10222, 10224, 10226, 10228, + 10230, 10232, 10234, 10236, 10238, 10240, 10242, 10244, 10246, 10248, + 10250, 10252, 10254, 10256, 10258, 10260, 10262, 10264, 10266, 10268, + 10270, 10272, 10274, 10276, 10278, 10280, 10282, 10284, 10286, 10288, + 10290, 10292, 10294, 10296, 10298, 10300, 10302, 10304, 10306, 10308, + 10310, 10312, 10314, 10316, 10318, 10320, 10322, 10324, 10326, 10328, + 10330, 10332, 10334, 10336, 10338, 10340, 10342, 10344, 10346, 10348, + 10350, 10352, 10354, 10356, 10358, 10360, 10362, 10364, 10366, 10368, + 10370, 10372, 10374, 10376, 0, 0, 0, 10378, 10380, 10382, 10384, 10386, + 10388, 0, 0, 10390, 10392, 10394, 10396, 10398, 10400, 0, 0, 10402, + 10404, 10406, 10408, 10410, 10412, 0, 0, 10414, 10416, 10418, 0, 0, 0, + 10420, 10422, 10424, 10426, 10428, 10430, 10432, 0, 10434, 10436, 10438, + 10440, 10442, 10444, 10446, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 10448, 0, 10451, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 10454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10457, 10460, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 10463, 10466, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10469, + 10472, 0, 10475, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 10478, 10481, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 10484, 10487, 10490, 10493, 10496, 10499, 10502, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10505, 10508, 10511, 10514, 10517, + 10520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10523, 10525, 10527, + 10529, 10531, 10533, 10535, 10537, 10539, 10541, 10543, 10545, 10547, + 10549, 10551, 10553, 10555, 10557, 10559, 10561, 10563, 10565, 10567, + 10569, 10571, 10573, 10575, 10577, 10579, 10581, 10583, 10585, 10587, + 10589, 10591, 10593, 10595, 10597, 10599, 10601, 10603, 10605, 10607, + 10609, 10611, 10613, 10615, 10617, 10619, 10621, 10623, 10625, 10627, + 10629, 10631, 10633, 10635, 10637, 10639, 10641, 10643, 10645, 10647, + 10649, 10651, 10653, 10655, 10657, 10659, 10661, 10663, 10665, 10667, + 10669, 10671, 10673, 10675, 10677, 10679, 10681, 10683, 10685, 10687, + 10689, 10691, 0, 10693, 10695, 10697, 10699, 10701, 10703, 10705, 10707, + 10709, 10711, 10713, 10715, 10717, 10719, 10721, 10723, 10725, 10727, + 10729, 10731, 10733, 10735, 10737, 10739, 10741, 10743, 10745, 10747, + 10749, 10751, 10753, 10755, 10757, 10759, 10761, 10763, 10765, 10767, + 10769, 10771, 10773, 10775, 10777, 10779, 10781, 10783, 10785, 10787, + 10789, 10791, 10793, 10795, 10797, 10799, 10801, 10803, 10805, 10807, + 10809, 10811, 10813, 10815, 10817, 10819, 10821, 10823, 10825, 10827, + 10829, 10831, 10833, 0, 10835, 10837, 0, 0, 10839, 0, 0, 10841, 10843, 0, + 0, 10845, 10847, 10849, 10851, 0, 10853, 10855, 10857, 10859, 10861, + 10863, 10865, 10867, 10869, 10871, 10873, 10875, 0, 10877, 0, 10879, + 10881, 10883, 10885, 10887, 10889, 10891, 0, 10893, 10895, 10897, 10899, + 10901, 10903, 10905, 10907, 10909, 10911, 10913, 10915, 10917, 10919, + 10921, 10923, 10925, 10927, 10929, 10931, 10933, 10935, 10937, 10939, + 10941, 10943, 10945, 10947, 10949, 10951, 10953, 10955, 10957, 10959, + 10961, 10963, 10965, 10967, 10969, 10971, 10973, 10975, 10977, 10979, + 10981, 10983, 10985, 10987, 10989, 10991, 10993, 10995, 10997, 10999, + 11001, 11003, 11005, 11007, 11009, 11011, 11013, 11015, 11017, 11019, + 11021, 0, 11023, 11025, 11027, 11029, 0, 0, 11031, 11033, 11035, 11037, + 11039, 11041, 11043, 11045, 0, 11047, 11049, 11051, 11053, 11055, 11057, + 11059, 0, 11061, 11063, 11065, 11067, 11069, 11071, 11073, 11075, 11077, + 11079, 11081, 11083, 11085, 11087, 11089, 11091, 11093, 11095, 11097, + 11099, 11101, 11103, 11105, 11107, 11109, 11111, 11113, 11115, 0, 11117, + 11119, 11121, 11123, 0, 11125, 11127, 11129, 11131, 11133, 0, 11135, 0, + 0, 0, 11137, 11139, 11141, 11143, 11145, 11147, 11149, 0, 11151, 11153, + 11155, 11157, 11159, 11161, 11163, 11165, 11167, 11169, 11171, 11173, + 11175, 11177, 11179, 11181, 11183, 11185, 11187, 11189, 11191, 11193, + 11195, 11197, 11199, 11201, 11203, 11205, 11207, 11209, 11211, 11213, + 11215, 11217, 11219, 11221, 11223, 11225, 11227, 11229, 11231, 11233, + 11235, 11237, 11239, 11241, 11243, 11245, 11247, 11249, 11251, 11253, + 11255, 11257, 11259, 11261, 11263, 11265, 11267, 11269, 11271, 11273, + 11275, 11277, 11279, 11281, 11283, 11285, 11287, 11289, 11291, 11293, + 11295, 11297, 11299, 11301, 11303, 11305, 11307, 11309, 11311, 11313, + 11315, 11317, 11319, 11321, 11323, 11325, 11327, 11329, 11331, 11333, + 11335, 11337, 11339, 11341, 11343, 11345, 11347, 11349, 11351, 11353, + 11355, 11357, 11359, 11361, 11363, 11365, 11367, 11369, 11371, 11373, + 11375, 11377, 11379, 11381, 11383, 11385, 11387, 11389, 11391, 11393, + 11395, 11397, 11399, 11401, 11403, 11405, 11407, 11409, 11411, 11413, + 11415, 11417, 11419, 11421, 11423, 11425, 11427, 11429, 11431, 11433, + 11435, 11437, 11439, 11441, 11443, 11445, 11447, 11449, 11451, 11453, + 11455, 11457, 11459, 11461, 11463, 11465, 11467, 11469, 11471, 11473, + 11475, 11477, 11479, 11481, 11483, 11485, 11487, 11489, 11491, 11493, + 11495, 11497, 11499, 11501, 11503, 11505, 11507, 11509, 11511, 11513, + 11515, 11517, 11519, 11521, 11523, 11525, 11527, 11529, 11531, 11533, + 11535, 11537, 11539, 11541, 11543, 11545, 11547, 11549, 11551, 11553, + 11555, 11557, 11559, 11561, 11563, 11565, 11567, 11569, 11571, 11573, + 11575, 11577, 11579, 11581, 11583, 11585, 11587, 11589, 11591, 11593, + 11595, 11597, 11599, 11601, 11603, 11605, 11607, 11609, 11611, 11613, + 11615, 11617, 11619, 11621, 11623, 11625, 11627, 11629, 11631, 11633, + 11635, 11637, 11639, 11641, 11643, 11645, 11647, 11649, 11651, 11653, + 11655, 11657, 11659, 11661, 11663, 11665, 11667, 11669, 11671, 11673, + 11675, 11677, 11679, 11681, 11683, 11685, 11687, 11689, 11691, 11693, + 11695, 11697, 11699, 11701, 11703, 11705, 11707, 11709, 11711, 11713, + 11715, 11717, 11719, 11721, 11723, 11725, 11727, 11729, 11731, 11733, + 11735, 11737, 11739, 11741, 11743, 11745, 11747, 11749, 11751, 11753, + 11755, 11757, 11759, 11761, 11763, 11765, 11767, 11769, 11771, 11773, + 11775, 11777, 11779, 11781, 11783, 11785, 11787, 11789, 11791, 11793, + 11795, 11797, 11799, 11801, 11803, 11805, 11807, 11809, 11811, 11813, + 11815, 11817, 11819, 11821, 11823, 11825, 11827, 11829, 0, 0, 11831, + 11833, 11835, 11837, 11839, 11841, 11843, 11845, 11847, 11849, 11851, + 11853, 11855, 11857, 11859, 11861, 11863, 11865, 11867, 11869, 11871, + 11873, 11875, 11877, 11879, 11881, 11883, 11885, 11887, 11889, 11891, + 11893, 11895, 11897, 11899, 11901, 11903, 11905, 11907, 11909, 11911, + 11913, 11915, 11917, 11919, 11921, 11923, 11925, 11927, 11929, 11931, + 11933, 11935, 11937, 11939, 11941, 11943, 11945, 11947, 11949, 11951, + 11953, 11955, 11957, 11959, 11961, 11963, 11965, 11967, 11969, 11971, + 11973, 11975, 11977, 11979, 11981, 11983, 11985, 11987, 11989, 11991, + 11993, 11995, 11997, 11999, 12001, 12003, 12005, 12007, 12009, 12011, + 12013, 12015, 12017, 12019, 12021, 12023, 12025, 12027, 12029, 12031, + 12033, 12035, 12037, 12039, 12041, 12043, 12045, 12047, 12049, 12051, + 12053, 12055, 12057, 12059, 12061, 12063, 12065, 12067, 12069, 12071, + 12073, 12075, 12077, 12079, 12081, 12083, 12085, 12087, 12089, 12091, + 12093, 12095, 12097, 12099, 12101, 12103, 12105, 12107, 12109, 12111, + 12113, 12115, 12117, 12119, 12121, 12123, 12125, 12127, 12129, 12131, + 12133, 12135, 12137, 12139, 12141, 12143, 12145, 12147, 12149, 12151, + 12153, 12155, 12157, 12159, 12161, 12163, 12165, 12167, 12169, 12171, + 12173, 12175, 12177, 12179, 12181, 12183, 12185, 12187, 12189, 12191, + 12193, 12195, 12197, 12199, 12201, 12203, 12205, 12207, 12209, 12211, + 12213, 12215, 12217, 12219, 12221, 12223, 12225, 12227, 12229, 12231, + 12233, 12235, 12237, 12239, 12241, 12243, 12245, 12247, 12249, 12251, + 12253, 12255, 12257, 12259, 12261, 12263, 12265, 12267, 12269, 12271, + 12273, 12275, 12277, 12279, 12281, 12283, 12285, 12287, 12289, 12291, + 12293, 12295, 12297, 12299, 12301, 12303, 12305, 12307, 12309, 12311, + 12313, 12315, 12317, 12319, 12321, 12323, 12325, 12327, 12329, 12331, + 12333, 12335, 12337, 12339, 12341, 12343, 12345, 12347, 12349, 12351, + 12353, 12355, 12357, 12359, 12361, 12363, 12365, 12367, 12369, 12371, + 12373, 12375, 12377, 12379, 12381, 12383, 12385, 12387, 12389, 12391, + 12393, 12395, 12397, 12399, 12401, 12403, 12405, 12407, 12409, 12411, + 12413, 0, 0, 12415, 12417, 12419, 12421, 12423, 12425, 12427, 12429, + 12431, 12433, 12435, 12437, 12439, 12441, 12443, 12445, 12447, 12449, + 12451, 12453, 12455, 12457, 12459, 12461, 12463, 12465, 12467, 12469, + 12471, 12473, 12475, 12477, 12479, 12481, 12483, 12485, 12487, 12489, + 12491, 12493, 12495, 12497, 12499, 12501, 12503, 12505, 12507, 12509, + 12511, 12513, 12515, 12517, 12519, 12521, 0, 12523, 12525, 12527, 12529, + 12531, 12533, 12535, 12537, 12539, 12541, 12543, 12545, 12547, 12549, + 12551, 12553, 12555, 12557, 12559, 12561, 12563, 12565, 12567, 12569, + 12571, 12573, 12575, 0, 12577, 12579, 0, 12581, 0, 0, 12583, 0, 12585, + 12587, 12589, 12591, 12593, 12595, 12597, 12599, 12601, 12603, 0, 12605, + 12607, 12609, 12611, 0, 12613, 0, 12615, 0, 0, 0, 0, 0, 0, 12617, 0, 0, + 0, 0, 12619, 0, 12621, 0, 12623, 0, 12625, 12627, 12629, 0, 12631, 12633, + 0, 12635, 0, 0, 12637, 0, 12639, 0, 12641, 0, 12643, 0, 12645, 0, 12647, + 12649, 0, 12651, 0, 0, 12653, 12655, 12657, 12659, 0, 12661, 12663, + 12665, 12667, 12669, 12671, 12673, 0, 12675, 12677, 12679, 12681, 0, + 12683, 12685, 12687, 12689, 0, 12691, 0, 12693, 12695, 12697, 12699, + 12701, 12703, 12705, 12707, 12709, 12711, 0, 12713, 12715, 12717, 12719, + 12721, 12723, 12725, 12727, 12729, 12731, 12733, 12735, 12737, 12739, + 12741, 12743, 12745, 0, 0, 0, 0, 0, 12747, 12749, 12751, 0, 12753, 12755, + 12757, 12759, 12761, 0, 12763, 12765, 12767, 12769, 12771, 12773, 12775, + 12777, 12779, 12781, 12783, 12785, 12787, 12789, 12791, 12793, 12795, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12797, 12800, + 12803, 12806, 12809, 12812, 12815, 12818, 12821, 12824, 12827, 0, 0, 0, + 0, 0, 12830, 12834, 12838, 12842, 12846, 12850, 12854, 12858, 12862, + 12866, 12870, 12874, 12878, 12882, 12886, 12890, 12894, 12898, 12902, + 12906, 12910, 12914, 12918, 12922, 12926, 12930, 12934, 12938, 12940, + 12942, 12945, 0, 12948, 12950, 12952, 12954, 12956, 12958, 12960, 12962, + 12964, 12966, 12968, 12970, 12972, 12974, 12976, 12978, 12980, 12982, + 12984, 12986, 12988, 12990, 12992, 12994, 12996, 12998, 13000, 13003, + 13006, 13009, 13012, 13016, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13019, 13022, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 13025, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13028, 13031, + 13034, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13036, 13038, 13040, 13042, + 13044, 13046, 13048, 13050, 13052, 13054, 13056, 13058, 13060, 13062, + 13064, 13066, 13068, 13070, 13072, 13074, 13076, 13078, 13080, 13082, + 13084, 13086, 13088, 13090, 13092, 13094, 13096, 13098, 13100, 13102, + 13104, 13106, 13108, 13110, 13112, 13114, 13116, 13118, 13120, 0, 0, 0, + 0, 0, 13122, 13126, 13130, 13134, 13138, 13142, 13146, 13150, 13154, 0, + 0, 0, 0, 0, 0, 0, 13158, 13160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 13162, 13164, 13166, 13168, 13170, 13172, 13174, + 13176, 13178, 13180, 13182, 13184, 13186, 13188, 13190, 13192, 13194, + 13196, 13198, 13200, 13202, 13204, 13206, 13208, 13210, 13212, 13214, + 13216, 13218, 13220, 13222, 13224, 13226, 13228, 13230, 13232, 13234, + 13236, 13238, 13240, 13242, 13244, 13246, 13248, 13250, 13252, 13254, + 13256, 13258, 13260, 13262, 13264, 13266, 13268, 13270, 13272, 13274, + 13276, 13278, 13280, 13282, 13284, 13286, 13288, 13290, 13292, 13294, + 13296, 13298, 13300, 13302, 13304, 13306, 13308, 13310, 13312, 13314, + 13316, 13318, 13320, 13322, 13324, 13326, 13328, 13330, 13332, 13334, + 13336, 13338, 13340, 13342, 13344, 13346, 13348, 13350, 13352, 13354, + 13356, 13358, 13360, 13362, 13364, 13366, 13368, 13370, 13372, 13374, + 13376, 13378, 13380, 13382, 13384, 13386, 13388, 13390, 13392, 13394, + 13396, 13398, 13400, 13402, 13404, 13406, 13408, 13410, 13412, 13414, + 13416, 13418, 13420, 13422, 13424, 13426, 13428, 13430, 13432, 13434, + 13436, 13438, 13440, 13442, 13444, 13446, 13448, 13450, 13452, 13454, + 13456, 13458, 13460, 13462, 13464, 13466, 13468, 13470, 13472, 13474, + 13476, 13478, 13480, 13482, 13484, 13486, 13488, 13490, 13492, 13494, + 13496, 13498, 13500, 13502, 13504, 13506, 13508, 13510, 13512, 13514, + 13516, 13518, 13520, 13522, 13524, 13526, 13528, 13530, 13532, 13534, + 13536, 13538, 13540, 13542, 13544, 13546, 13548, 13550, 13552, 13554, + 13556, 13558, 13560, 13562, 13564, 13566, 13568, 13570, 13572, 13574, + 13576, 13578, 13580, 13582, 13584, 13586, 13588, 13590, 13592, 13594, + 13596, 13598, 13600, 13602, 13604, 13606, 13608, 13610, 13612, 13614, + 13616, 13618, 13620, 13622, 13624, 13626, 13628, 13630, 13632, 13634, + 13636, 13638, 13640, 13642, 13644, 13646, 13648, 13650, 13652, 13654, + 13656, 13658, 13660, 13662, 13664, 13666, 13668, 13670, 13672, 13674, + 13676, 13678, 13680, 13682, 13684, 13686, 13688, 13690, 13692, 13694, + 13696, 13698, 13700, 13702, 13704, 13706, 13708, 13710, 13712, 13714, + 13716, 13718, 13720, 13722, 13724, 13726, 13728, 13730, 13732, 13734, + 13736, 13738, 13740, 13742, 13744, 13746, 13748, 13750, 13752, 13754, + 13756, 13758, 13760, 13762, 13764, 13766, 13768, 13770, 13772, 13774, + 13776, 13778, 13780, 13782, 13784, 13786, 13788, 13790, 13792, 13794, + 13796, 13798, 13800, 13802, 13804, 13806, 13808, 13810, 13812, 13814, + 13816, 13818, 13820, 13822, 13824, 13826, 13828, 13830, 13832, 13834, + 13836, 13838, 13840, 13842, 13844, 13846, 13848, 13850, 13852, 13854, + 13856, 13858, 13860, 13862, 13864, 13866, 13868, 13870, 13872, 13874, + 13876, 13878, 13880, 13882, 13884, 13886, 13888, 13890, 13892, 13894, + 13896, 13898, 13900, 13902, 13904, 13906, 13908, 13910, 13912, 13914, + 13916, 13918, 13920, 13922, 13924, 13926, 13928, 13930, 13932, 13934, + 13936, 13938, 13940, 13942, 13944, 13946, 13948, 13950, 13952, 13954, + 13956, 13958, 13960, 13962, 13964, 13966, 13968, 13970, 13972, 13974, + 13976, 13978, 13980, 13982, 13984, 13986, 13988, 13990, 13992, 13994, + 13996, 13998, 14000, 14002, 14004, 14006, 14008, 14010, 14012, 14014, + 14016, 14018, 14020, 14022, 14024, 14026, 14028, 14030, 14032, 14034, + 14036, 14038, 14040, 14042, 14044, 14046, 14048, 14050, 14052, 14054, + 14056, 14058, 14060, 14062, 14064, 14066, 14068, 14070, 14072, 14074, + 14076, 14078, 14080, 14082, 14084, 14086, 14088, 14090, 14092, 14094, + 14096, 14098, 14100, 14102, 14104, 14106, 14108, 14110, 14112, 14114, + 14116, 14118, 14120, 14122, 14124, 14126, 14128, 14130, 14132, 14134, + 14136, 14138, 14140, 14142, 14144, 14146, 14148, 14150, 14152, 14154, + 14156, 14158, 14160, 14162, 14164, 14166, 14168, 14170, 14172, 14174, + 14176, 14178, 14180, 14182, 14184, 14186, 14188, 14190, 14192, 14194, + 14196, 14198, 14200, 14202, 14204, 14206, 14208, 14210, 14212, 14214, + 14216, 14218, 14220, 14222, 14224, 14226, 14228, 14230, 14232, 14234, + 14236, 14238, 14240, 14242, 14244, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; /* NFC pairs */ #define COMP_SHIFT 2 static unsigned short comp_index[] = { - 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 5, 6, 7, 8, 9, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 0, 12, 0, 0, 0, 0, 0, 0, 0, 13, - 14, 15, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 18, 0, 19, 20, 21, 0, 0, - 0, 0, 0, 0, 0, 22, 23, 24, 25, 26, 27, 28, 0, 0, 0, 0, 0, 0, 0, 0, 29, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 31, 32, 0, 0, 33, 0, 0, 0, 0, 0, 0, - 0, 0, 34, 35, 36, 0, 37, 38, 39, 0, 0, 0, 0, 0, 0, 0, 40, 41, 42, 43, 44, - 45, 46, 0, 0, 0, 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 48, 0, 49, 0, 50, 51, 52, 0, 0, 0, 0, 0, 0, 0, 53, 0, 54, 0, 55, 56, 57, - 0, 0, 0, 0, 0, 0, 0, 58, 59, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 62, - 63, 0, 64, 65, 66, 0, 0, 0, 0, 0, 0, 0, 67, 68, 69, 70, 71, 72, 0, 0, 0, - 0, 0, 0, 0, 0, 73, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 75, 76, 77, - 78, 79, 80, 81, 0, 0, 0, 0, 0, 0, 0, 82, 83, 84, 0, 85, 86, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 87, 88, 0, 89, 90, 91, 0, 0, 0, 0, 0, 0, 0, 92, 93, 94, - 95, 96, 97, 98, 0, 0, 0, 0, 0, 0, 0, 99, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 101, 102, 0, 0, 103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 104, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 105, 106, 107, 0, 108, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 109, 110, 111, 0, 112, 0, 113, 0, 0, 0, 0, 0, 0, 0, 114, 115, 116, - 117, 118, 119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 0, 0, 121, 0, 122, 0, 0, - 0, 0, 0, 0, 0, 123, 124, 125, 0, 0, 126, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, - 128, 0, 129, 130, 131, 0, 0, 0, 0, 0, 0, 0, 132, 133, 134, 135, 136, 137, - 138, 0, 0, 0, 0, 0, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 140, 141, 142, 0, 0, 143, 0, 0, 0, 0, 0, 0, 0, 0, 144, 145, 146, 0, 147, - 148, 149, 0, 0, 0, 0, 0, 0, 0, 150, 151, 152, 153, 154, 155, 156, 0, 0, - 0, 0, 0, 0, 0, 157, 0, 158, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 159, 0, 160, - 0, 161, 162, 163, 0, 0, 0, 0, 0, 0, 0, 164, 0, 165, 0, 166, 167, 168, 0, - 0, 0, 0, 0, 0, 0, 169, 170, 0, 0, 171, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, - 173, 174, 0, 175, 176, 177, 0, 0, 0, 0, 0, 0, 0, 178, 179, 180, 181, 182, - 183, 0, 0, 0, 0, 0, 0, 0, 0, 184, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 186, 187, 188, 189, 190, 191, 192, 0, 0, 0, 0, 0, 0, 0, 193, 194, 195, - 0, 196, 197, 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, 199, 0, 200, 201, 202, 0, 0, - 0, 0, 0, 0, 0, 203, 204, 205, 206, 207, 208, 209, 0, 0, 0, 0, 0, 0, 0, - 210, 0, 0, 0, 211, 0, 0, 0, 0, 0, 0, 0, 0, 0, 212, 213, 214, 0, 215, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 217, - 218, 219, 0, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 221, 222, 223, 0, 224, 0, - 225, 0, 0, 0, 0, 0, 0, 0, 226, 0, 0, 0, 0, 0, 0, 227, 0, 0, 0, 0, 0, 0, - 228, 0, 229, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 231, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 232, 233, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 234, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 235, 0, 236, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 238, 0, 239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 240, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 242, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 243, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 244, 245, - 246, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 247, 0, 248, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 249, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 251, 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 253, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 0, 255, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 257, 0, - 258, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 259, 260, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 262, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 263, 264, 265, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 266, 0, 267, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 268, 0, 269, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 270, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 271, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 272, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 273, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 276, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 277, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 278, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 279, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 281, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 282, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 283, 0, 284, 0, 285, 0, 0, 0, 0, 0, 0, 0, 0, 0, 286, 0, 287, 0, - 288, 0, 0, 0, 0, 0, 0, 0, 0, 0, 289, 0, 290, 0, 291, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 292, 0, 293, 0, 294, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 295, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 296, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 297, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 298, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 299, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 300, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 301, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 302, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 303, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 304, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 305, 306, 0, 307, - 0, 0, 0, 308, 0, 0, 0, 0, 0, 0, 309, 0, 0, 310, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 311, 0, 0, 312, 0, 0, 0, 313, 0, 0, 0, 0, 0, 0, 314, 315, 0, 316, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 317, 0, 0, 318, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 319, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 320, 321, 0, 322, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 323, 0, 0, 324, 0, 0, 0, 325, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 327, 0, 0, - 0, 0, 0, 0, 328, 329, 0, 330, 0, 0, 0, 331, 0, 0, 0, 0, 0, 0, 332, 0, 0, - 333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 334, 0, 0, 335, 0, 0, 0, 336, 0, 0, 0, - 0, 0, 0, 337, 338, 0, 339, 0, 0, 0, 340, 0, 0, 0, 0, 0, 0, 341, 0, 0, - 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 343, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 344, 345, 0, 346, 0, 0, 0, 347, 0, 0, 0, 0, 0, 0, 348, 0, 0, 349, - 0, 0, 0, 350, 0, 0, 0, 0, 0, 0, 351, 0, 0, 0, 0, 0, 0, 352, 0, 0, 0, 0, - 0, 0, 353, 0, 0, 0, 0, 0, 0, 354, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 355, 0, 0, 0, 0, 0, 0, 356, 357, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 358, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 359, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 361, 362, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 363, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 364, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 365, 366, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 367, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 368, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 369, 370, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 371, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 372, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 373, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 374, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 375, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 376, 377, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 378, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 379, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 380, - 381, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 382, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 384, 385, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 386, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 387, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 388, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 389, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 390, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 391, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 392, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 393, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 395, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 396, 397, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 398, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 399, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 400, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 401, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 402, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 403, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 404, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 405, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 406, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 407, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 408, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 409, 410, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 412, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 413, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, 415, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 416, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 417, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 419, 420, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 421, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 422, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 423, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 424, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 425, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 426, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 429, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 430, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 431, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 432, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 433, 0, - 0, 434, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 436, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 437, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 438, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 439, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 440, 441, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 442, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 444, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 445, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 446, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 447, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 448, 0, 0, 0, 0, 0, 0, 449, 0, 0, 0, 0, 0, 0, 450, - 0, 0, 0, 0, 0, 0, 451, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 452, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 453, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 455, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 456, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 457, 0, 0, - 0, 0, 0, 0, 458, 0, 0, 0, 0, 0, 0, 459, 0, 0, 0, 0, 0, 0, 460, 0, 0, 0, - 0, 0, 0, 461, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 462, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 463, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 464, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 465, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 466, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 467, 0, 0, 0, 0, 0, - 0, 468, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 469, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 470, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 471, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 472, 0, 0, 0, 0, 0, 0, 473, 0, 0, 0, 0, - 0, 0, 474, 0, 0, 0, 0, 0, 0, 475, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 476, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 477, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 478, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 479, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 480, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 481, 0, 0, 0, 0, 0, 0, 482, 0, 0, 0, 0, 0, 0, 483, 0, 0, 0, 0, 0, 0, 484, - 0, 0, 0, 0, 0, 0, 485, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 486, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 487, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 488, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 489, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 490, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 491, 0, 0, - 0, 0, 0, 0, 492, 0, 0, 0, 0, 0, 0, 493, 0, 0, 0, 0, 0, 0, 494, 0, 0, 0, - 0, 0, 0, 495, 0, 0, 0, 0, 0, 0, 496, 0, 0, 0, 0, 0, 0, 497, 0, 0, 0, 0, - 0, 0, 498, 0, 0, 0, 0, 0, 0, 499, 0, 0, 0, 0, 0, 0, 500, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 501, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 502, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 503, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 504, 0, 0, 0, 0, 0, 0, 505, 0, 0, 0, 0, 0, 0, 506, 0, 0, 0, 0, - 0, 0, 507, 0, 0, 0, 0, 0, 0, 508, 0, 0, 0, 0, 0, 0, 509, 0, 0, 0, 0, 0, - 0, 510, 0, 0, 0, 0, 0, 0, 511, 0, 0, 0, 0, 0, 0, 512, 0, 0, 0, 0, 0, 0, - 513, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 514, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 515, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 517, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 518, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 519, 0, 0, 0, 0, 0, 0, 520, - 0, 0, 0, 0, 0, 0, 521, 0, 0, 0, 0, 0, 0, 522, 0, 0, 0, 0, 0, 0, 523, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 524, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 525, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 526, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 527, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 528, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 529, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 530, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 531, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 533, 0, - 0, 0, 0, 0, 0, 534, 0, 0, 0, 0, 0, 0, 535, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 536, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 537, 0, 0, 0, 0, 0, - 0, 538, 0, 0, 0, 0, 0, 0, 539, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 540, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 541, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 542, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 543, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 544, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 545, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 546, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 547, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 548, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 549, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 550, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 551, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 552, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 553, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 554, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 555, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 556, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 557, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 558, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 559, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 560, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 561, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 562, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 563, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 564, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 565, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 566, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 567, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 568, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 569, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 570, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 571, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 572, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 573, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 574, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 575, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 576, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 577, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 578, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 579, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 580, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 581, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 582, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 583, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 584, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 585, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 586, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 587, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 588, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 589, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 590, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 591, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 592, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 593, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 594, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 595, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 596, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 597, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 598, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 599, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 600, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 601, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 602, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 603, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 604, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 605, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 606, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 607, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 609, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 610, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 611, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 612, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 613, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 614, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 615, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 616, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 617, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 618, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 619, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 620, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 621, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 622, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 623, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 624, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 625, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 626, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 627, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 628, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 629, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 630, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 631, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 632, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 633, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, + 6, 7, 8, 9, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 12, 0, 13, 0, 0, + 0, 0, 0, 0, 0, 0, 14, 15, 16, 17, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 19, 20, 0, 21, 22, 23, 0, 0, 0, 0, 0, 0, 0, 0, 24, 25, 26, 27, 28, 29, + 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 32, 33, 34, 35, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 38, 39, 0, + 40, 41, 42, 0, 0, 0, 0, 0, 0, 0, 0, 43, 44, 45, 46, 47, 0, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, + 51, 52, 53, 0, 54, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 56, 0, 57, 58, 59, 0, + 0, 0, 0, 0, 0, 0, 0, 60, 0, 61, 0, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 63, 64, 65, 0, 66, 67, 68, 0, 0, 0, 0, 0, 0, 0, 0, 69, 70, 71, 72, 73, 0, + 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 77, 0, 78, 79, 80, 81, 0, 82, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 85, + 0, 86, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88, 89, 90, 91, 92, 93, 0, 0, + 0, 0, 0, 0, 0, 0, 94, 95, 96, 97, 98, 99, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 101, 0, 0, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 103, 104, 0, 0, 105, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 106, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 107, 108, 109, 0, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 111, 112, 113, + 114, 115, 0, 0, 116, 0, 0, 0, 0, 0, 0, 0, 0, 117, 118, 119, 120, 121, + 122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 123, 0, 124, 0, 0, 125, 0, 0, 0, 0, + 0, 0, 0, 0, 126, 127, 128, 0, 0, 129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 130, 131, 132, 133, 134, 135, 0, 0, 0, 0, 0, 0, 0, 0, 136, 137, 138, 139, + 140, 141, 142, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 143, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 144, 145, 146, 0, 0, 147, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 148, 149, 150, 151, 152, 153, 154, 0, 0, 0, 0, 0, 0, 0, 0, 155, 156, 157, + 158, 159, 160, 161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 162, 0, 163, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 164, 0, 165, 0, 166, 167, 168, 0, 0, 0, 0, 0, 0, + 0, 0, 169, 0, 0, 170, 171, 172, 173, 174, 0, 0, 0, 0, 0, 0, 0, 0, 175, + 176, 0, 0, 177, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 178, 179, 180, 181, 182, + 183, 184, 185, 0, 0, 0, 0, 0, 0, 0, 0, 186, 187, 188, 189, 190, 191, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 192, 0, 193, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 194, 195, 196, 197, 198, 199, 200, 0, 0, 0, 0, 0, 0, 0, 0, 201, 202, + 203, 204, 205, 206, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 207, 208, 0, 209, + 210, 211, 0, 0, 0, 0, 0, 0, 0, 0, 212, 213, 214, 215, 216, 217, 218, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 219, 0, 0, 0, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 221, 222, 223, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 225, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 226, 227, 228, 0, 229, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 230, 231, 232, 0, 233, 0, 234, 0, 0, 0, 0, 0, 0, 0, 0, 235, + 0, 0, 0, 0, 0, 0, 236, 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, 238, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 241, 242, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 243, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 244, 245, 246, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 247, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 248, 249, 250, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 251, 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 253, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 255, 256, 0, 257, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 258, 0, + 259, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 260, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 262, + 263, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 264, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 265, 266, 267, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 268, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 269, 270, 271, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 272, 273, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 275, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 276, 277, 0, 278, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 279, 0, 280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 281, 282, + 283, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 284, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 285, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 286, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 287, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 288, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 289, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 290, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 291, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 292, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 293, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 294, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 295, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 296, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 297, 298, 299, 0, 300, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 301, 0, 302, 0, 303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 304, 305, 306, 0, 307, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 308, 0, 309, 0, 310, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 311, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 312, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 313, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 314, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 315, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 316, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 317, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 318, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 319, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 320, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 321, 322, 0, 0, + 323, 0, 0, 324, 0, 0, 0, 0, 0, 0, 0, 0, 325, 0, 0, 326, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 327, 0, 0, 0, 328, 0, 0, 329, 0, 0, 0, 0, 0, 0, 0, 0, 330, + 331, 0, 332, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 333, 0, 0, 0, 334, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 335, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 336, 337, 338, 0, 339, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 340, 0, 0, 341, + 0, 0, 0, 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 343, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 344, 0, 0, 0, 0, 0, 0, 0, 345, 346, 0, + 0, 347, 0, 0, 348, 0, 0, 0, 0, 0, 0, 0, 0, 349, 0, 0, 350, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 351, 0, 0, 0, 352, 0, 0, 353, 0, 0, 0, 0, 0, 0, 0, 0, + 354, 355, 0, 356, 0, 0, 0, 357, 0, 0, 0, 0, 0, 0, 0, 358, 0, 0, 0, 359, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 360, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 361, 362, 363, 0, 364, 0, 0, 365, 0, 0, 0, 0, 0, 0, 0, 0, 366, 0, + 0, 367, 0, 0, 0, 368, 0, 0, 0, 0, 0, 0, 0, 369, 0, 0, 0, 0, 0, 0, 370, 0, + 0, 0, 0, 0, 0, 0, 0, 371, 0, 0, 0, 0, 0, 0, 372, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 373, 0, 0, 0, 0, 0, 0, 0, 0, 374, 375, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 376, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 377, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 378, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 379, 380, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 381, 382, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 383, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 384, 385, 386, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 387, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 388, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 389, 390, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 391, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 392, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 393, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 395, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 396, 397, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 398, 399, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 400, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 401, 402, 403, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 404, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 405, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 406, 407, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 408, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 409, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 410, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 411, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 412, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 413, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 414, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 415, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 416, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 417, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 418, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 419, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 420, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 421, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 422, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 423, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 424, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 425, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 426, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 428, + 429, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 430, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 431, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 432, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 433, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 434, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 435, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 436, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 437, 438, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 439, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 440, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 441, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 442, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 444, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 445, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 446, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 447, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 448, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 449, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 450, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 451, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 452, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 453, 0, 0, 0, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 455, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 456, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 457, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 458, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 459, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 460, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 461, 462, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 463, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 464, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 465, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 466, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 467, 0, 0, 0, 0, 0, 0, 468, 0, 0, 0, + 0, 0, 0, 0, 0, 469, 0, 0, 0, 0, 0, 0, 470, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 471, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 472, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 473, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 474, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 475, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 476, 0, 0, 0, 0, 0, 0, 0, 477, 0, 0, + 0, 0, 0, 0, 478, 0, 0, 0, 0, 0, 0, 0, 0, 479, 0, 0, 0, 0, 0, 0, 480, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 481, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 482, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 483, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 484, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 485, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 486, 0, 0, + 0, 0, 0, 0, 0, 487, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 488, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 489, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 490, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 491, 0, 0, + 0, 0, 0, 0, 492, 0, 0, 0, 0, 0, 0, 0, 0, 493, 0, 0, 0, 0, 0, 0, 494, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 495, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 496, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 497, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 498, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 499, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 500, 0, 0, + 0, 0, 0, 0, 0, 501, 0, 0, 0, 0, 0, 0, 502, 0, 0, 0, 0, 0, 0, 0, 0, 503, + 0, 0, 0, 0, 0, 0, 504, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 505, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 506, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 507, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 508, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 509, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 510, 0, 0, 0, 0, 0, 0, 0, 511, 0, 0, 0, 0, 0, 0, 512, 0, + 0, 0, 0, 0, 0, 0, 0, 513, 0, 0, 0, 0, 0, 0, 514, 0, 0, 0, 0, 0, 0, 0, + 515, 0, 0, 0, 0, 0, 0, 516, 0, 0, 0, 0, 0, 0, 0, 0, 517, 0, 0, 0, 0, 0, + 0, 518, 0, 0, 0, 0, 0, 0, 0, 519, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 521, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 522, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 523, 0, 0, 0, 0, 0, 0, 524, 0, 0, 0, 0, 0, 0, 0, 0, 525, 0, 0, 0, 0, + 0, 0, 526, 0, 0, 0, 0, 0, 0, 0, 527, 0, 0, 0, 0, 0, 0, 528, 0, 0, 0, 0, + 0, 0, 0, 0, 529, 0, 0, 0, 0, 0, 0, 530, 0, 0, 0, 0, 0, 0, 0, 531, 0, 0, + 0, 0, 0, 0, 532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 533, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 534, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 535, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 536, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 537, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 538, 0, 0, 0, 0, 0, 0, 0, 0, 539, 0, 0, 0, 0, 0, 0, 540, 0, 0, + 0, 0, 0, 0, 0, 541, 0, 0, 0, 0, 0, 0, 542, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 543, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 544, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 545, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 546, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 547, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 548, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 549, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 550, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 551, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 552, 0, 0, 0, 0, 0, 0, 0, 0, 553, 0, 0, 0, 0, 0, 0, 554, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 555, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 556, 0, 0, 0, 0, 0, 0, 0, 557, 0, 0, 0, 0, 0, 0, 558, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 559, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 560, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 561, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 562, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 563, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 564, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 565, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 566, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 567, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 568, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 569, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 570, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 571, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 572, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 573, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 574, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 575, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 576, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 577, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 578, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 579, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 580, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 581, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 582, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 583, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 584, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 585, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 586, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 587, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 588, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 589, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 590, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 591, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 592, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 593, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 594, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 595, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 596, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 597, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 598, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 599, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 600, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 601, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 602, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 603, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 604, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 605, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 606, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 607, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 609, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 610, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 611, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 612, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 613, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 614, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 615, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 616, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 617, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 618, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 619, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 620, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 621, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 622, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 623, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 624, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 625, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 626, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 627, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 628, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 629, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 630, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 631, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 632, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 633, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 634, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 635, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 636, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 637, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 638, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 639, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 640, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 641, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 642, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 643, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 644, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 645, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 646, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 647, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 648, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 649, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 650, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 651, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 652, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 653, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 654, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 655, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 656, }; static unsigned int comp_data[] = { - 0, 0, 0, 0, 0, 0, 0, 8814, 0, 0, 0, 8800, 0, 0, 0, 8815, 192, 193, 194, - 195, 256, 258, 550, 196, 7842, 197, 0, 461, 512, 514, 0, 0, 0, 7840, 0, - 7680, 0, 0, 260, 0, 0, 0, 7682, 0, 0, 7684, 0, 0, 0, 0, 7686, 0, 0, 262, - 264, 0, 0, 0, 266, 0, 0, 0, 0, 268, 0, 199, 0, 0, 0, 0, 7690, 0, 0, 0, 0, - 270, 0, 7692, 0, 0, 0, 7696, 0, 7698, 0, 0, 7694, 0, 200, 201, 202, 7868, - 274, 276, 278, 203, 7866, 0, 0, 282, 516, 518, 0, 0, 0, 7864, 0, 0, 0, - 552, 280, 7704, 0, 7706, 0, 0, 0, 0, 7710, 0, 0, 500, 284, 0, 7712, 286, - 288, 0, 0, 0, 0, 486, 0, 290, 0, 0, 0, 0, 292, 0, 0, 0, 7714, 7718, 0, 0, - 0, 542, 0, 7716, 0, 0, 0, 7720, 0, 0, 7722, 0, 0, 0, 204, 205, 206, 296, - 298, 300, 304, 207, 7880, 0, 0, 463, 520, 522, 0, 0, 0, 7882, 0, 0, 0, 0, - 302, 0, 0, 7724, 0, 0, 0, 0, 308, 0, 0, 7728, 0, 0, 0, 0, 0, 488, 0, - 7730, 0, 0, 0, 310, 0, 0, 0, 0, 7732, 0, 0, 313, 0, 0, 0, 0, 0, 317, 0, - 7734, 0, 0, 0, 315, 0, 7740, 0, 0, 7738, 0, 0, 7742, 0, 0, 0, 0, 7744, 0, - 0, 7746, 0, 0, 504, 323, 0, 209, 0, 0, 7748, 0, 0, 0, 0, 327, 0, 7750, 0, - 0, 0, 325, 0, 7754, 0, 0, 7752, 0, 210, 211, 212, 213, 332, 334, 558, - 214, 7886, 0, 336, 465, 524, 526, 0, 0, 416, 7884, 0, 0, 0, 0, 490, 0, 0, - 7764, 0, 0, 0, 0, 7766, 0, 0, 340, 0, 0, 0, 0, 7768, 0, 0, 0, 0, 344, - 528, 530, 0, 0, 0, 7770, 0, 0, 0, 342, 0, 0, 0, 0, 7774, 0, 0, 346, 348, - 0, 0, 0, 7776, 0, 0, 0, 0, 352, 0, 7778, 0, 0, 536, 350, 0, 0, 0, 0, - 7786, 0, 0, 0, 0, 356, 0, 7788, 0, 0, 538, 354, 0, 7792, 0, 0, 7790, 0, - 217, 218, 219, 360, 362, 364, 0, 220, 7910, 366, 368, 467, 532, 534, 0, - 0, 431, 7908, 7794, 0, 0, 0, 370, 7798, 0, 7796, 0, 0, 0, 0, 0, 7804, 0, - 7806, 0, 0, 7808, 7810, 372, 0, 0, 0, 7814, 7812, 0, 7816, 0, 0, 0, 0, - 7818, 7820, 7922, 221, 374, 7928, 562, 0, 7822, 376, 7926, 0, 0, 0, 0, - 7924, 0, 0, 0, 377, 7824, 0, 0, 0, 379, 0, 0, 0, 0, 381, 0, 7826, 0, 0, - 0, 0, 7828, 0, 224, 225, 226, 227, 257, 259, 551, 228, 7843, 229, 0, 462, - 513, 515, 0, 0, 0, 7841, 0, 7681, 0, 0, 261, 0, 0, 0, 7683, 0, 0, 7685, - 0, 0, 0, 0, 7687, 0, 0, 263, 265, 0, 0, 0, 267, 0, 0, 0, 0, 269, 0, 231, - 0, 0, 0, 0, 7691, 0, 0, 0, 0, 271, 0, 7693, 0, 0, 0, 7697, 0, 7699, 0, 0, - 7695, 0, 232, 233, 234, 7869, 275, 277, 279, 235, 7867, 0, 0, 283, 517, - 519, 0, 0, 0, 7865, 0, 0, 0, 553, 281, 7705, 0, 7707, 0, 0, 0, 0, 7711, - 0, 0, 501, 285, 0, 7713, 287, 289, 0, 0, 0, 0, 487, 0, 291, 0, 0, 0, 0, - 293, 0, 0, 0, 7715, 7719, 0, 0, 0, 543, 0, 7717, 0, 0, 0, 7721, 0, 0, - 7723, 0, 7830, 0, 236, 237, 238, 297, 299, 301, 0, 239, 7881, 0, 0, 464, - 521, 523, 0, 0, 0, 7883, 0, 0, 0, 0, 303, 0, 0, 7725, 0, 0, 0, 0, 309, 0, - 0, 0, 0, 496, 0, 7729, 0, 0, 0, 0, 0, 489, 0, 7731, 0, 0, 0, 311, 0, 0, - 0, 0, 7733, 0, 0, 314, 0, 0, 0, 0, 0, 318, 0, 7735, 0, 0, 0, 316, 0, - 7741, 0, 0, 7739, 0, 0, 7743, 0, 0, 0, 0, 7745, 0, 0, 7747, 0, 0, 505, - 324, 0, 241, 0, 0, 7749, 0, 0, 0, 0, 328, 0, 7751, 0, 0, 0, 326, 0, 7755, - 0, 0, 7753, 0, 242, 243, 244, 245, 333, 335, 559, 246, 7887, 0, 337, 466, - 525, 527, 0, 0, 417, 7885, 0, 0, 0, 0, 491, 0, 0, 7765, 0, 0, 0, 0, 7767, - 0, 0, 341, 0, 0, 0, 0, 7769, 0, 0, 0, 0, 345, 529, 531, 0, 0, 0, 7771, 0, - 0, 0, 343, 0, 0, 0, 0, 7775, 0, 0, 347, 349, 0, 0, 0, 7777, 0, 0, 0, 0, - 353, 0, 7779, 0, 0, 537, 351, 0, 0, 0, 0, 7787, 7831, 0, 0, 0, 357, 0, - 7789, 0, 0, 539, 355, 0, 7793, 0, 0, 7791, 0, 249, 250, 251, 361, 363, - 365, 0, 252, 7911, 367, 369, 468, 533, 535, 0, 0, 432, 7909, 7795, 0, 0, - 0, 371, 7799, 0, 7797, 0, 0, 0, 0, 0, 7805, 0, 7807, 0, 0, 7809, 7811, - 373, 0, 0, 0, 7815, 7813, 0, 7832, 0, 0, 0, 7817, 0, 0, 0, 0, 7819, 7821, - 7923, 253, 375, 7929, 563, 0, 7823, 255, 7927, 7833, 0, 0, 0, 7925, 0, 0, - 0, 378, 7825, 0, 0, 0, 380, 0, 0, 0, 0, 382, 0, 7827, 0, 0, 0, 0, 7829, - 0, 8173, 901, 0, 0, 8129, 0, 0, 0, 7846, 7844, 0, 7850, 7848, 0, 0, 0, - 478, 0, 0, 0, 0, 506, 0, 0, 0, 508, 0, 0, 482, 0, 0, 0, 0, 7688, 0, 0, - 7872, 7870, 0, 7876, 7874, 0, 0, 0, 0, 7726, 0, 0, 7890, 7888, 0, 7894, - 7892, 0, 0, 0, 0, 7756, 0, 0, 556, 0, 0, 7758, 554, 0, 0, 0, 0, 510, 0, - 0, 475, 471, 0, 0, 469, 0, 0, 0, 0, 0, 0, 473, 7847, 7845, 0, 7851, 7849, - 0, 0, 0, 479, 0, 0, 0, 0, 507, 0, 0, 0, 509, 0, 0, 483, 0, 0, 0, 0, 7689, - 0, 0, 7873, 7871, 0, 7877, 7875, 0, 0, 0, 0, 7727, 0, 0, 7891, 7889, 0, - 7895, 7893, 0, 0, 0, 0, 7757, 0, 0, 557, 0, 0, 7759, 555, 0, 0, 0, 0, - 511, 0, 0, 476, 472, 0, 0, 470, 0, 0, 0, 0, 0, 0, 474, 7856, 7854, 0, - 7860, 7858, 0, 0, 0, 7857, 7855, 0, 7861, 7859, 0, 0, 0, 7700, 7702, 0, - 0, 7701, 7703, 0, 0, 7760, 7762, 0, 0, 7761, 7763, 0, 0, 0, 0, 7780, 0, - 0, 0, 7781, 0, 0, 0, 7782, 0, 0, 0, 7783, 0, 0, 7800, 0, 0, 0, 7801, 0, - 0, 0, 0, 0, 7802, 0, 0, 0, 7803, 0, 0, 7835, 0, 7900, 7898, 0, 7904, - 7902, 0, 0, 0, 0, 7906, 0, 0, 7901, 7899, 0, 7905, 7903, 0, 0, 0, 0, - 7907, 0, 0, 7914, 7912, 0, 7918, 7916, 0, 0, 0, 0, 7920, 0, 0, 7915, - 7913, 0, 7919, 7917, 0, 0, 0, 0, 7921, 0, 0, 0, 0, 0, 494, 492, 0, 0, 0, - 493, 0, 0, 0, 480, 0, 0, 0, 481, 0, 0, 0, 0, 7708, 0, 0, 0, 7709, 0, 0, - 560, 0, 0, 0, 561, 0, 0, 0, 0, 0, 0, 495, 8122, 902, 0, 0, 8121, 8120, 0, - 0, 0, 0, 7944, 7945, 0, 8124, 0, 0, 8136, 904, 0, 0, 0, 0, 7960, 7961, - 8138, 905, 0, 0, 0, 0, 7976, 7977, 0, 8140, 0, 0, 8154, 906, 0, 0, 8153, - 8152, 0, 938, 0, 0, 7992, 7993, 8184, 908, 0, 0, 0, 0, 8008, 8009, 0, 0, - 0, 8172, 8170, 910, 0, 0, 8169, 8168, 0, 939, 0, 0, 0, 8025, 8186, 911, - 0, 0, 0, 0, 8040, 8041, 0, 8188, 0, 0, 0, 8116, 0, 0, 0, 8132, 0, 0, - 8048, 940, 0, 0, 8113, 8112, 0, 0, 0, 0, 7936, 7937, 8118, 8115, 0, 0, - 8050, 941, 0, 0, 0, 0, 7952, 7953, 8052, 942, 0, 0, 0, 0, 7968, 7969, - 8134, 8131, 0, 0, 8054, 943, 0, 0, 8145, 8144, 0, 970, 0, 0, 7984, 7985, - 8150, 0, 0, 0, 8056, 972, 0, 0, 0, 0, 8000, 8001, 0, 0, 8164, 8165, 8058, - 973, 0, 0, 8161, 8160, 0, 971, 0, 0, 8016, 8017, 8166, 0, 0, 0, 8060, - 974, 0, 0, 0, 0, 8032, 8033, 8182, 8179, 0, 0, 8146, 912, 0, 0, 8151, 0, - 0, 0, 8162, 944, 0, 0, 8167, 0, 0, 0, 0, 8180, 0, 0, 0, 979, 0, 0, 0, 0, - 0, 980, 0, 0, 0, 1031, 0, 1232, 0, 1234, 0, 1027, 0, 0, 1024, 0, 0, 0, 0, - 1238, 0, 1025, 0, 1217, 0, 1244, 0, 0, 0, 1246, 1037, 0, 0, 0, 1250, - 1049, 0, 1252, 0, 1036, 0, 0, 0, 0, 0, 1254, 1262, 1038, 0, 1264, 0, 0, - 1266, 0, 0, 0, 0, 1268, 0, 0, 0, 1272, 0, 0, 0, 1260, 0, 1233, 0, 1235, - 0, 1107, 0, 0, 1104, 0, 0, 0, 0, 1239, 0, 1105, 0, 1218, 0, 1245, 0, 0, - 0, 1247, 1117, 0, 0, 0, 1251, 1081, 0, 1253, 0, 1116, 0, 0, 0, 0, 0, - 1255, 1263, 1118, 0, 1265, 0, 0, 1267, 0, 0, 0, 0, 1269, 0, 0, 0, 1273, - 0, 0, 0, 1261, 0, 0, 0, 1111, 1142, 0, 0, 0, 1143, 0, 0, 0, 0, 0, 0, - 1242, 0, 0, 0, 1243, 0, 0, 0, 1258, 0, 0, 0, 1259, 0, 0, 1570, 1571, - 1573, 0, 0, 0, 0, 0, 0, 1572, 0, 0, 0, 1574, 0, 0, 0, 1730, 0, 0, 0, - 1747, 0, 0, 0, 1728, 0, 2345, 0, 0, 0, 2353, 0, 0, 0, 2356, 0, 0, 0, 0, - 2507, 2508, 2891, 2888, 2892, 0, 2964, 0, 0, 0, 0, 0, 0, 3018, 3020, 0, - 0, 0, 0, 0, 0, 3019, 0, 3144, 0, 0, 0, 0, 0, 3264, 0, 0, 3274, 3271, - 3272, 0, 0, 0, 0, 0, 0, 3275, 0, 3402, 3404, 0, 0, 3403, 0, 0, 0, 0, 0, - 3546, 3548, 3550, 0, 0, 0, 0, 0, 3549, 0, 0, 4134, 0, 0, 0, 0, 6918, 0, - 0, 0, 6920, 0, 0, 0, 6922, 0, 0, 0, 6924, 0, 0, 0, 6926, 0, 0, 0, 6930, - 0, 0, 0, 6971, 0, 0, 0, 6973, 0, 0, 0, 6976, 0, 0, 0, 6977, 0, 0, 0, - 6979, 7736, 0, 0, 0, 7737, 0, 0, 0, 7772, 0, 0, 0, 7773, 0, 0, 0, 0, 0, - 7784, 0, 0, 0, 7785, 0, 0, 0, 7852, 0, 0, 7862, 0, 0, 0, 0, 7853, 0, 0, - 7863, 0, 0, 0, 0, 7878, 0, 0, 0, 7879, 0, 0, 0, 7896, 0, 0, 0, 7897, 0, - 7938, 7940, 0, 0, 7942, 8064, 0, 0, 7939, 7941, 0, 0, 7943, 8065, 0, 0, - 0, 8066, 0, 0, 0, 8067, 0, 0, 0, 8068, 0, 0, 0, 8069, 0, 0, 0, 8070, 0, - 0, 0, 8071, 0, 0, 7946, 7948, 0, 0, 7950, 8072, 0, 0, 7947, 7949, 0, 0, - 7951, 8073, 0, 0, 0, 8074, 0, 0, 0, 8075, 0, 0, 0, 8076, 0, 0, 0, 8077, - 0, 0, 0, 8078, 0, 0, 0, 8079, 0, 0, 7954, 7956, 0, 0, 7955, 7957, 0, 0, - 7962, 7964, 0, 0, 7963, 7965, 0, 0, 7970, 7972, 0, 0, 7974, 8080, 0, 0, - 7971, 7973, 0, 0, 7975, 8081, 0, 0, 0, 8082, 0, 0, 0, 8083, 0, 0, 0, - 8084, 0, 0, 0, 8085, 0, 0, 0, 8086, 0, 0, 0, 8087, 0, 0, 7978, 7980, 0, - 0, 7982, 8088, 0, 0, 7979, 7981, 0, 0, 7983, 8089, 0, 0, 0, 8090, 0, 0, - 0, 8091, 0, 0, 0, 8092, 0, 0, 0, 8093, 0, 0, 0, 8094, 0, 0, 0, 8095, 0, - 0, 7986, 7988, 0, 0, 7990, 0, 0, 0, 7987, 7989, 0, 0, 7991, 0, 0, 0, - 7994, 7996, 0, 0, 7998, 0, 0, 0, 7995, 7997, 0, 0, 7999, 0, 0, 0, 8002, - 8004, 0, 0, 8003, 8005, 0, 0, 8010, 8012, 0, 0, 8011, 8013, 0, 0, 8018, - 8020, 0, 0, 8022, 0, 0, 0, 8019, 8021, 0, 0, 8023, 0, 0, 0, 8027, 8029, - 0, 0, 8031, 0, 0, 0, 8034, 8036, 0, 0, 8038, 8096, 0, 0, 8035, 8037, 0, - 0, 8039, 8097, 0, 0, 0, 8098, 0, 0, 0, 8099, 0, 0, 0, 8100, 0, 0, 0, - 8101, 0, 0, 0, 8102, 0, 0, 0, 8103, 0, 0, 8042, 8044, 0, 0, 8046, 8104, - 0, 0, 8043, 8045, 0, 0, 8047, 8105, 0, 0, 0, 8106, 0, 0, 0, 8107, 0, 0, - 0, 8108, 0, 0, 0, 8109, 0, 0, 0, 8110, 0, 0, 0, 8111, 0, 0, 0, 8114, 0, - 0, 0, 8130, 0, 0, 0, 8178, 0, 0, 0, 8119, 0, 0, 8141, 8142, 0, 0, 8143, - 0, 0, 0, 0, 8135, 0, 0, 0, 8183, 0, 0, 8157, 8158, 0, 0, 8159, 0, 0, 0, - 0, 0, 0, 8602, 0, 0, 0, 8603, 0, 0, 0, 8622, 0, 0, 0, 8653, 0, 0, 0, - 8655, 0, 0, 0, 8654, 0, 0, 0, 8708, 0, 0, 0, 8713, 0, 0, 0, 8716, 0, 0, - 0, 8740, 0, 0, 0, 8742, 0, 0, 0, 8769, 0, 0, 0, 8772, 0, 0, 0, 8775, 0, - 0, 0, 8777, 0, 0, 0, 8813, 0, 0, 0, 8802, 0, 0, 0, 8816, 0, 0, 0, 8817, - 0, 0, 0, 8820, 0, 0, 0, 8821, 0, 0, 0, 8824, 0, 0, 0, 8825, 0, 0, 0, - 8832, 0, 0, 0, 8833, 0, 0, 0, 8928, 0, 0, 0, 8929, 0, 0, 0, 8836, 0, 0, - 0, 8837, 0, 0, 0, 8840, 0, 0, 0, 8841, 0, 0, 0, 8930, 0, 0, 0, 8931, 0, - 0, 0, 8876, 0, 0, 0, 8877, 0, 0, 0, 8878, 0, 0, 0, 8879, 0, 0, 0, 8938, - 0, 0, 0, 8939, 0, 0, 0, 8940, 0, 0, 0, 8941, 12436, 0, 0, 0, 12364, 0, 0, - 0, 12366, 0, 0, 0, 12368, 0, 0, 0, 12370, 0, 0, 0, 12372, 0, 0, 0, 12374, - 0, 0, 0, 12376, 0, 0, 0, 12378, 0, 0, 0, 12380, 0, 0, 0, 12382, 0, 0, 0, - 12384, 0, 0, 0, 12386, 0, 0, 0, 12389, 0, 0, 0, 12391, 0, 0, 0, 12393, 0, - 0, 0, 12400, 12401, 0, 0, 12403, 12404, 0, 0, 12406, 12407, 0, 0, 12409, - 12410, 0, 0, 12412, 12413, 0, 0, 12446, 0, 0, 0, 12532, 0, 0, 0, 12460, - 0, 0, 0, 12462, 0, 0, 0, 12464, 0, 0, 0, 12466, 0, 0, 0, 12468, 0, 0, 0, - 12470, 0, 0, 0, 12472, 0, 0, 0, 12474, 0, 0, 0, 12476, 0, 0, 0, 12478, 0, - 0, 0, 12480, 0, 0, 0, 12482, 0, 0, 0, 12485, 0, 0, 0, 12487, 0, 0, 0, - 12489, 0, 0, 0, 12496, 12497, 0, 0, 12499, 12500, 0, 0, 12502, 12503, 0, - 0, 12505, 12506, 0, 0, 12508, 12509, 0, 0, 12535, 0, 0, 0, 12536, 0, 0, - 0, 12537, 0, 0, 0, 12538, 0, 0, 0, 12542, 0, 0, 0, 0, 0, 69786, 0, 0, 0, - 69788, 0, 0, 0, 69803, 0, 0, 0, 0, 69934, 0, 0, 0, 69935, + 0, 0, 0, 0, 0, 0, 0, 8814, 0, 8800, 0, 0, 0, 0, 0, 8815, 0, 0, 192, 193, + 194, 195, 256, 258, 550, 196, 7842, 197, 0, 461, 512, 514, 0, 0, 0, 7840, + 0, 7680, 0, 0, 260, 0, 0, 0, 0, 0, 7682, 0, 0, 7684, 0, 0, 0, 0, 7686, 0, + 0, 0, 0, 262, 264, 0, 0, 0, 266, 0, 0, 0, 0, 268, 0, 0, 0, 0, 0, 199, 0, + 0, 7690, 0, 0, 0, 0, 270, 0, 7692, 0, 0, 0, 7696, 0, 7698, 0, 0, 7694, 0, + 0, 0, 200, 201, 202, 7868, 274, 276, 278, 203, 7866, 0, 0, 282, 516, 518, + 0, 0, 0, 7864, 0, 0, 0, 552, 280, 7704, 0, 7706, 0, 0, 7710, 0, 0, 0, 0, + 500, 284, 0, 7712, 286, 288, 0, 0, 0, 0, 486, 0, 0, 0, 0, 0, 290, 0, 0, + 292, 0, 0, 0, 7714, 7718, 0, 0, 0, 542, 0, 7716, 0, 0, 0, 7720, 0, 0, + 7722, 0, 0, 0, 0, 0, 204, 205, 206, 296, 298, 300, 304, 207, 7880, 0, 0, + 463, 520, 522, 0, 0, 0, 7882, 302, 0, 0, 7724, 0, 0, 308, 0, 0, 0, 0, + 7728, 0, 488, 0, 0, 0, 0, 0, 7730, 0, 0, 0, 310, 7732, 0, 0, 0, 0, 313, + 0, 0, 0, 0, 0, 317, 0, 7734, 0, 0, 0, 315, 0, 7740, 0, 0, 7738, 0, 0, 0, + 0, 7742, 7744, 0, 0, 0, 0, 0, 0, 7746, 504, 323, 0, 209, 0, 0, 7748, 0, + 0, 0, 0, 327, 0, 7750, 0, 0, 0, 325, 0, 7754, 0, 0, 7752, 0, 0, 0, 210, + 211, 212, 213, 332, 334, 558, 214, 7886, 0, 336, 465, 524, 526, 0, 0, + 416, 7884, 490, 0, 0, 0, 0, 7764, 0, 0, 0, 0, 7766, 0, 0, 0, 0, 340, + 7768, 0, 0, 0, 0, 344, 528, 530, 0, 0, 0, 7770, 0, 0, 0, 342, 7774, 0, 0, + 0, 0, 346, 348, 0, 0, 0, 7776, 0, 0, 0, 0, 352, 0, 7778, 0, 0, 536, 350, + 0, 0, 7786, 0, 0, 0, 0, 356, 0, 0, 0, 0, 0, 7788, 0, 0, 538, 354, 0, + 7792, 0, 0, 7790, 0, 0, 0, 217, 218, 219, 360, 362, 364, 0, 220, 7910, + 366, 368, 467, 532, 534, 0, 0, 431, 7908, 7794, 0, 0, 0, 370, 7798, 0, + 7796, 0, 0, 0, 7804, 0, 0, 0, 0, 0, 7806, 7808, 7810, 372, 0, 0, 0, 7814, + 7812, 0, 7816, 0, 0, 7818, 7820, 0, 0, 7922, 221, 374, 7928, 562, 0, + 7822, 376, 7926, 0, 0, 0, 0, 7924, 0, 0, 0, 0, 0, 377, 7824, 0, 0, 0, + 379, 0, 0, 0, 0, 381, 0, 0, 0, 0, 0, 7826, 7828, 0, 0, 0, 224, 225, 226, + 227, 257, 259, 551, 228, 7843, 229, 0, 462, 513, 515, 0, 0, 0, 7841, 0, + 7681, 0, 0, 261, 0, 7683, 0, 0, 0, 0, 0, 0, 7685, 7687, 0, 0, 0, 0, 263, + 265, 0, 0, 0, 267, 0, 0, 0, 0, 269, 0, 231, 0, 0, 7691, 0, 0, 0, 0, 271, + 0, 0, 0, 0, 0, 7693, 0, 0, 0, 7697, 0, 7699, 0, 0, 7695, 0, 0, 0, 232, + 233, 234, 7869, 275, 277, 279, 235, 7867, 0, 0, 283, 517, 519, 0, 0, 0, + 7865, 0, 0, 0, 553, 281, 7705, 0, 7707, 0, 0, 7711, 0, 0, 0, 0, 501, 285, + 0, 7713, 287, 289, 0, 0, 0, 0, 487, 0, 291, 0, 0, 293, 0, 0, 0, 7715, + 7719, 0, 0, 0, 543, 0, 0, 0, 0, 0, 7717, 0, 0, 0, 7721, 0, 0, 7723, 0, + 7830, 0, 0, 0, 236, 237, 238, 297, 299, 301, 0, 239, 7881, 0, 0, 464, + 521, 523, 0, 0, 0, 7883, 0, 0, 0, 0, 303, 0, 0, 7725, 0, 0, 309, 0, 0, 0, + 0, 496, 0, 0, 0, 7729, 0, 0, 0, 0, 0, 489, 0, 7731, 0, 0, 0, 311, 0, 0, + 0, 0, 7733, 0, 0, 0, 0, 314, 0, 318, 0, 0, 0, 0, 0, 7735, 0, 0, 0, 316, + 0, 7741, 0, 0, 7739, 0, 0, 0, 0, 7743, 0, 0, 0, 0, 7745, 0, 0, 7747, 0, + 0, 0, 0, 505, 324, 0, 241, 0, 0, 7749, 0, 0, 0, 0, 328, 0, 0, 0, 0, 0, + 7751, 0, 0, 0, 326, 0, 7755, 0, 0, 7753, 0, 0, 0, 242, 243, 244, 245, + 333, 335, 559, 246, 7887, 0, 337, 466, 525, 527, 0, 0, 417, 7885, 0, 0, + 0, 0, 491, 0, 0, 0, 0, 7765, 7767, 0, 0, 0, 0, 341, 0, 0, 0, 0, 7769, 0, + 0, 0, 0, 345, 529, 531, 0, 0, 0, 7771, 0, 0, 0, 343, 0, 0, 0, 0, 7775, 0, + 0, 0, 0, 347, 349, 0, 0, 0, 7777, 0, 0, 0, 0, 353, 0, 0, 0, 0, 0, 7779, + 0, 0, 537, 351, 0, 0, 7787, 7831, 0, 0, 0, 357, 0, 7789, 0, 0, 539, 355, + 0, 7793, 0, 0, 7791, 0, 0, 0, 249, 250, 251, 361, 363, 365, 0, 252, 7911, + 367, 369, 468, 533, 535, 0, 0, 432, 7909, 7795, 0, 0, 0, 371, 7799, 0, + 7797, 0, 0, 0, 7805, 0, 7807, 0, 0, 0, 0, 7809, 7811, 373, 0, 0, 0, 7815, + 7813, 0, 7832, 0, 0, 0, 7817, 0, 0, 7819, 7821, 0, 0, 7923, 253, 375, + 7929, 563, 0, 7823, 255, 7927, 7833, 0, 0, 0, 7925, 0, 378, 7825, 0, 0, + 0, 380, 0, 0, 0, 0, 382, 0, 7827, 0, 0, 0, 0, 7829, 0, 0, 0, 8173, 901, + 0, 0, 8129, 0, 7846, 7844, 0, 7850, 7848, 0, 0, 0, 0, 0, 478, 0, 0, 506, + 0, 0, 0, 0, 0, 508, 0, 0, 482, 0, 0, 7688, 0, 0, 0, 0, 7872, 7870, 0, + 7876, 0, 0, 0, 0, 7874, 0, 0, 7726, 0, 0, 0, 0, 7890, 7888, 0, 7894, 0, + 0, 0, 0, 7892, 0, 0, 7756, 0, 0, 556, 0, 0, 7758, 0, 0, 554, 0, 0, 510, + 0, 0, 0, 0, 475, 471, 0, 0, 469, 0, 0, 473, 0, 0, 7847, 7845, 0, 7851, + 7849, 0, 0, 0, 0, 0, 479, 0, 0, 507, 0, 0, 0, 0, 0, 509, 0, 0, 483, 0, 0, + 7689, 0, 0, 0, 0, 7873, 7871, 0, 7877, 0, 0, 0, 0, 7875, 0, 0, 7727, 0, + 0, 0, 0, 7891, 7889, 0, 7895, 0, 0, 0, 0, 7893, 0, 0, 7757, 0, 0, 557, 0, + 0, 7759, 0, 0, 555, 0, 0, 511, 0, 0, 0, 0, 476, 472, 0, 0, 470, 0, 0, + 474, 0, 0, 7856, 7854, 0, 7860, 7858, 0, 0, 0, 0, 0, 7857, 7855, 0, 7861, + 0, 0, 0, 0, 7859, 0, 7700, 7702, 0, 0, 0, 0, 7701, 7703, 7760, 7762, 0, + 0, 0, 0, 7761, 7763, 0, 0, 7780, 0, 7781, 0, 0, 0, 0, 0, 7782, 0, 7783, + 0, 0, 0, 0, 7800, 0, 0, 0, 0, 0, 7801, 0, 0, 0, 7802, 0, 7803, 0, 0, 0, + 0, 7835, 0, 0, 0, 7900, 7898, 0, 7904, 0, 0, 0, 0, 7902, 0, 0, 0, 0, + 7906, 7901, 7899, 0, 7905, 7903, 0, 0, 0, 0, 7907, 0, 0, 0, 0, 7914, + 7912, 0, 7918, 0, 0, 0, 0, 7916, 0, 0, 0, 0, 7920, 7915, 7913, 0, 7919, + 7917, 0, 0, 0, 0, 7921, 0, 0, 0, 494, 0, 0, 492, 0, 0, 0, 0, 0, 493, 0, + 480, 0, 0, 0, 0, 0, 481, 0, 0, 7708, 0, 0, 0, 0, 0, 7709, 560, 0, 0, 0, + 0, 0, 561, 0, 0, 0, 0, 495, 0, 0, 8122, 902, 0, 0, 8121, 8120, 7944, + 7945, 0, 0, 0, 0, 0, 8124, 8136, 904, 0, 0, 0, 0, 7960, 7961, 0, 0, 8138, + 905, 7976, 7977, 0, 0, 0, 0, 0, 8140, 8154, 906, 0, 0, 8153, 8152, 0, + 938, 0, 0, 7992, 7993, 0, 0, 8184, 908, 8008, 8009, 0, 0, 0, 0, 0, 8172, + 0, 0, 8170, 910, 0, 0, 8169, 8168, 0, 939, 0, 0, 0, 8025, 0, 0, 8186, + 911, 0, 0, 0, 0, 8040, 8041, 0, 8188, 0, 0, 0, 0, 0, 8116, 0, 8132, 0, 0, + 0, 0, 8048, 940, 0, 0, 8113, 8112, 7936, 7937, 0, 0, 0, 0, 8118, 8115, + 8050, 941, 0, 0, 0, 0, 7952, 7953, 0, 0, 8052, 942, 7968, 7969, 0, 0, 0, + 0, 8134, 8131, 8054, 943, 0, 0, 8145, 8144, 0, 970, 0, 0, 7984, 7985, + 8150, 0, 0, 0, 0, 0, 8056, 972, 8000, 8001, 0, 0, 0, 0, 8164, 8165, 0, 0, + 8058, 973, 0, 0, 8161, 8160, 0, 971, 0, 0, 8016, 8017, 0, 0, 0, 0, 8166, + 0, 8060, 974, 0, 0, 0, 0, 8032, 8033, 8182, 8179, 0, 0, 0, 0, 8146, 912, + 0, 0, 8151, 0, 8162, 944, 0, 0, 8167, 0, 0, 0, 0, 0, 0, 8180, 0, 979, 0, + 0, 0, 0, 0, 980, 0, 1031, 0, 0, 0, 1232, 0, 1234, 0, 0, 0, 1027, 1024, 0, + 0, 0, 0, 1238, 0, 1025, 0, 0, 0, 1217, 0, 1244, 0, 0, 0, 0, 0, 1246, 0, + 0, 1037, 0, 0, 0, 1250, 1049, 0, 1252, 0, 0, 0, 1036, 0, 0, 0, 1254, 0, + 0, 1262, 1038, 0, 1264, 0, 0, 1266, 0, 0, 1268, 0, 0, 0, 0, 0, 1272, 0, + 1260, 0, 0, 0, 1233, 0, 1235, 0, 0, 0, 1107, 1104, 0, 0, 0, 0, 1239, 0, + 1105, 0, 0, 0, 1218, 0, 1245, 0, 0, 0, 0, 0, 1247, 0, 0, 1117, 0, 0, 0, + 1251, 1081, 0, 1253, 0, 0, 0, 1116, 0, 0, 0, 1255, 0, 0, 1263, 1118, 0, + 1265, 0, 0, 1267, 0, 0, 1269, 0, 0, 0, 0, 0, 1273, 0, 1261, 0, 0, 0, 0, + 0, 1111, 0, 0, 1142, 0, 1143, 0, 0, 0, 0, 1242, 0, 0, 0, 0, 0, 1243, 0, + 1258, 0, 0, 0, 0, 0, 1259, 1570, 1571, 1573, 0, 0, 0, 0, 1572, 0, 1574, + 0, 0, 0, 0, 0, 1730, 0, 1747, 0, 0, 0, 0, 0, 1728, 0, 0, 0, 2345, 0, + 2353, 0, 0, 0, 0, 0, 2356, 0, 0, 2507, 2508, 0, 0, 2891, 2888, 2892, 0, + 0, 0, 2964, 0, 0, 0, 0, 3018, 3020, 0, 0, 0, 0, 3019, 0, 0, 0, 3144, 0, + 0, 0, 3264, 3274, 3271, 3272, 0, 0, 0, 0, 3275, 0, 0, 0, 3402, 3404, 0, + 0, 0, 0, 3403, 0, 0, 0, 3546, 3548, 3550, 0, 0, 0, 3549, 4134, 0, 0, 0, + 0, 0, 0, 6918, 0, 6920, 0, 0, 0, 0, 0, 6922, 0, 6924, 0, 0, 0, 0, 0, + 6926, 0, 6930, 0, 0, 0, 0, 0, 6971, 0, 6973, 0, 0, 0, 0, 0, 6976, 0, + 6977, 0, 0, 0, 0, 0, 6979, 0, 0, 7736, 0, 7737, 0, 0, 0, 0, 0, 7772, 0, + 7773, 0, 0, 0, 7784, 0, 0, 0, 0, 0, 7785, 0, 7852, 0, 0, 7862, 0, 0, + 7853, 0, 0, 7863, 0, 0, 7878, 0, 0, 0, 0, 0, 7879, 0, 7896, 0, 0, 0, 0, + 0, 7897, 0, 0, 0, 7938, 7940, 0, 0, 7942, 8064, 7939, 7941, 0, 0, 7943, + 8065, 0, 0, 0, 0, 0, 8066, 0, 8067, 0, 0, 0, 0, 0, 8068, 0, 8069, 0, 0, + 0, 0, 0, 8070, 0, 8071, 0, 0, 0, 0, 7946, 7948, 0, 0, 7950, 8072, 7947, + 7949, 0, 0, 7951, 8073, 0, 0, 0, 0, 0, 8074, 0, 8075, 0, 0, 0, 0, 0, + 8076, 0, 8077, 0, 0, 0, 0, 0, 8078, 0, 8079, 0, 0, 0, 0, 7954, 7956, + 7955, 7957, 0, 0, 0, 0, 7962, 7964, 7963, 7965, 0, 0, 0, 0, 7970, 7972, + 0, 0, 7974, 8080, 7971, 7973, 0, 0, 7975, 8081, 0, 0, 0, 0, 0, 8082, 0, + 8083, 0, 0, 0, 0, 0, 8084, 0, 8085, 0, 0, 0, 0, 0, 8086, 0, 8087, 0, 0, + 0, 0, 7978, 7980, 0, 0, 7982, 8088, 7979, 7981, 0, 0, 7983, 8089, 0, 0, + 0, 0, 0, 8090, 0, 8091, 0, 0, 0, 0, 0, 8092, 0, 8093, 0, 0, 0, 0, 0, + 8094, 0, 8095, 0, 0, 0, 0, 7986, 7988, 0, 0, 7990, 0, 7987, 7989, 0, 0, + 7991, 0, 0, 0, 0, 0, 7994, 7996, 0, 0, 7998, 0, 7995, 7997, 0, 0, 7999, + 0, 0, 0, 0, 0, 8002, 8004, 8003, 8005, 0, 0, 0, 0, 8010, 8012, 8011, + 8013, 0, 0, 0, 0, 8018, 8020, 0, 0, 8022, 0, 8019, 8021, 0, 0, 8023, 0, + 0, 0, 0, 0, 8027, 8029, 0, 0, 8031, 0, 8034, 8036, 0, 0, 8038, 8096, 0, + 0, 0, 0, 8035, 8037, 0, 0, 8039, 8097, 0, 8098, 0, 0, 0, 0, 0, 8099, 0, + 8100, 0, 0, 0, 0, 0, 8101, 0, 8102, 0, 0, 0, 0, 0, 8103, 8042, 8044, 0, + 0, 8046, 8104, 0, 0, 0, 0, 8043, 8045, 0, 0, 8047, 8105, 0, 8106, 0, 0, + 0, 0, 0, 8107, 0, 8108, 0, 0, 0, 0, 0, 8109, 0, 8110, 0, 0, 0, 0, 0, + 8111, 0, 8114, 0, 0, 0, 0, 0, 8130, 0, 8178, 0, 0, 0, 0, 0, 8119, 8141, + 8142, 0, 0, 8143, 0, 0, 0, 0, 0, 0, 8135, 0, 8183, 0, 0, 0, 0, 8157, + 8158, 0, 0, 8159, 0, 0, 0, 0, 8602, 0, 8603, 0, 0, 0, 0, 0, 8622, 0, + 8653, 0, 0, 0, 0, 0, 8655, 0, 8654, 0, 0, 0, 0, 0, 8708, 0, 8713, 0, 0, + 0, 0, 0, 8716, 0, 8740, 0, 0, 0, 0, 0, 8742, 0, 8769, 0, 0, 0, 0, 0, + 8772, 0, 8775, 0, 0, 0, 0, 0, 8777, 0, 8813, 0, 0, 0, 0, 0, 8802, 0, + 8816, 0, 0, 0, 0, 0, 8817, 0, 8820, 0, 0, 0, 0, 0, 8821, 0, 8824, 0, 0, + 0, 0, 0, 8825, 0, 8832, 0, 0, 0, 0, 0, 8833, 0, 8928, 0, 0, 0, 0, 0, + 8929, 0, 8836, 0, 0, 0, 0, 0, 8837, 0, 8840, 0, 0, 0, 0, 0, 8841, 0, + 8930, 0, 0, 0, 0, 0, 8931, 0, 8876, 0, 0, 0, 0, 0, 8877, 0, 8878, 0, 0, + 0, 0, 0, 8879, 0, 8938, 0, 0, 0, 0, 0, 8939, 0, 8940, 0, 0, 0, 0, 0, + 8941, 0, 0, 12436, 0, 12364, 0, 0, 0, 0, 0, 12366, 0, 12368, 0, 0, 0, 0, + 0, 12370, 0, 12372, 0, 0, 0, 0, 0, 12374, 0, 12376, 0, 0, 0, 0, 0, 12378, + 0, 12380, 0, 0, 0, 0, 0, 12382, 0, 12384, 0, 0, 0, 0, 0, 12386, 0, 12389, + 0, 0, 0, 0, 0, 12391, 0, 12393, 0, 0, 0, 0, 0, 12400, 12401, 12403, + 12404, 0, 0, 0, 0, 12406, 12407, 12409, 12410, 0, 0, 0, 0, 12412, 12413, + 12446, 0, 0, 0, 0, 0, 12532, 0, 12460, 0, 0, 0, 0, 0, 12462, 0, 12464, 0, + 0, 0, 0, 0, 12466, 0, 12468, 0, 0, 0, 0, 0, 12470, 0, 12472, 0, 0, 0, 0, + 0, 12474, 0, 12476, 0, 0, 0, 0, 0, 12478, 0, 12480, 0, 0, 0, 0, 0, 12482, + 0, 12485, 0, 0, 0, 0, 0, 12487, 0, 12489, 0, 0, 0, 0, 0, 12496, 12497, + 12499, 12500, 0, 0, 0, 0, 12502, 12503, 12505, 12506, 0, 0, 0, 0, 12508, + 12509, 12535, 0, 0, 0, 0, 0, 12536, 0, 12537, 0, 0, 0, 0, 0, 12538, 0, + 12542, 0, 0, 0, 69786, 0, 0, 0, 0, 0, 69788, 0, 69803, 0, 0, 0, 0, 0, 0, + 69934, 0, 69935, 0, 0, 70475, 70476, 0, 0, 70844, 70843, 70846, 0, 0, + 71098, 0, 0, 0, 0, 0, 71099, }; static const change_record change_records_3_2_0[] = { @@ -5210,73 +5674,74 @@ static const change_record change_records_3_2_0[] = { }; static unsigned char changes_3_2_0_index[] = { 0, 1, 2, 2, 3, 4, 5, 6, 2, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 23, 24, 2, 2, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 36, 2, 2, 2, 37, 38, 2, 39, 2, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 2, 51, 2, 2, 52, 53, 54, 55, 56, 2, 57, 58, 59, 60, 2, 2, 61, 62, 63, - 64, 65, 65, 2, 2, 2, 2, 66, 2, 67, 68, 69, 70, 71, 2, 2, 2, 72, 73, 74, - 75, 76, 77, 78, 79, 80, 81, 2, 2, 2, 2, 2, 2, 82, 2, 2, 2, 2, 2, 83, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 84, 2, 85, 2, 2, 2, 2, 2, 2, 2, 2, 86, - 87, 2, 2, 2, 2, 2, 2, 2, 88, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 89, 90, + 19, 20, 21, 22, 23, 24, 25, 2, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 2, 2, 2, 38, 39, 2, 40, 2, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 2, 52, 2, 2, 53, 54, 55, 56, 57, 2, 58, 59, 60, 61, 2, 2, 62, 63, + 64, 65, 66, 66, 2, 2, 2, 2, 67, 68, 69, 70, 71, 72, 73, 2, 2, 2, 74, 75, + 76, 77, 78, 79, 80, 81, 82, 83, 2, 2, 2, 2, 2, 2, 84, 2, 2, 2, 2, 2, 85, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 91, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 86, 2, 87, 2, 2, 2, 2, 2, 2, 2, 2, + 88, 89, 2, 2, 2, 2, 2, 2, 2, 90, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 91, + 92, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 93, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 92, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 93, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 94, 95, 2, 2, 2, 2, 2, 2, 2, 2, 96, 49, 49, - 97, 98, 49, 99, 100, 101, 102, 103, 104, 105, 106, 107, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 94, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 95, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 96, 97, 2, 2, 2, 2, 2, 2, 2, 2, 98, 50, 50, + 99, 100, 50, 101, 102, 103, 104, 105, 106, 107, 108, 109, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 108, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 110, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 109, 110, 111, 112, 113, 114, 2, 2, 2, 115, 116, 2, 117, 118, - 119, 120, 121, 122, 2, 123, 124, 125, 126, 127, 2, 2, 2, 2, 2, 2, 128, 2, - 129, 130, 131, 2, 132, 2, 133, 2, 2, 2, 134, 2, 2, 2, 135, 136, 137, 138, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 139, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 49, 49, 49, 49, 49, 49, 140, 2, 141, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 49, 49, 49, 49, 49, 49, 49, - 49, 142, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 111, 112, 113, 114, 115, 116, 2, 2, 117, 118, 119, 2, 120, + 121, 122, 123, 124, 125, 2, 126, 127, 128, 129, 130, 131, 2, 50, 50, 132, + 2, 133, 134, 135, 136, 137, 138, 139, 140, 141, 2, 2, 2, 142, 2, 2, 2, + 143, 144, 145, 146, 147, 148, 149, 2, 2, 150, 2, 151, 152, 153, 2, 2, 2, + 154, 2, 2, 2, 155, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 50, 50, 50, 50, 50, 50, + 50, 156, 157, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 50, 50, 50, 50, 50, 50, 50, 50, 158, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 49, 49, 49, 49, 143, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 144, 145, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 50, 50, + 50, 50, 159, 160, 161, 162, 2, 2, 2, 2, 2, 2, 163, 164, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 146, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 165, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 166, 167, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 168, 2, + 169, 2, 170, 2, 2, 171, 2, 2, 2, 172, 173, 174, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 147, 2, 148, 2, 149, 2, 2, 150, 2, 2, 2, 151, 152, - 153, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 154, 155, - 2, 2, 156, 157, 158, 159, 160, 2, 161, 162, 163, 164, 165, 166, 167, 148, - 168, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 169, 170, 93, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 82, 171, 2, 172, 173, 2, 2, 2, + 50, 175, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 176, 177, 2, 2, 178, 179, 180, + 181, 182, 2, 183, 184, 50, 185, 186, 187, 188, 189, 190, 191, 192, 193, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 194, 195, 95, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 84, 196, 2, 197, 198, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 174, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 175, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 176, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 199, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 200, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 201, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 202, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 177, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 178, 49, 179, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 203, 50, 204, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 199, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 174, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -5511,7 +5976,7 @@ static unsigned char changes_3_2_0_index[] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 49, 180, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 50, 205, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -5575,7 +6040,7 @@ static unsigned char changes_3_2_0_index[] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, }; static unsigned char changes_3_2_0_data[] = { @@ -5611,7 +6076,7 @@ static unsigned char changes_3_2_0_data[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 10, 0, 9, 9, 0, 0, 0, 9, 9, - 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -5623,16 +6088,16 @@ static unsigned char changes_3_2_0_data[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 0, 9, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -5660,16 +6125,16 @@ static unsigned char changes_3_2_0_data[] = { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -5696,18 +6161,18 @@ static unsigned char changes_3_2_0_data[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, - 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 20, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 9, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -5716,64 +6181,67 @@ static unsigned char changes_3_2_0_data[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, - 0, 0, 0, 0, 0, 9, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 0, 0, 0, 0, 9, - 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 9, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, - 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, - 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, - 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9, 9, 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 0, - 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, + 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 22, 23, 24, 25, 26, 27, 28, 29, 30, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -5781,66 +6249,68 @@ static unsigned char changes_3_2_0_data[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 0, 0, 0, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, + 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, + 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, + 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, + 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, - 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, @@ -5850,209 +6320,214 @@ static unsigned char changes_3_2_0_data[] = { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 0, 9, 9, 9, - 9, 0, 0, 0, 0, 0, 0, 35, 4, 0, 0, 36, 37, 38, 39, 40, 41, 1, 1, 0, 0, 0, - 4, 35, 8, 6, 7, 36, 37, 38, 39, 40, 41, 1, 1, 0, 0, 0, 0, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, + 0, 0, 0, 0, 9, 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 35, 4, 0, 0, 36, 37, 38, + 39, 40, 41, 1, 1, 0, 0, 0, 4, 35, 8, 6, 7, 36, 37, 38, 39, 40, 41, 1, 1, + 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, + 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 43, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 44, 44, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 44, 44, 44, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 45, 46, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 46, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 9, 0, 9, 0, 0, 0, 0, 9, 9, 9, 0, 9, 0, 0, 0, 0, 0, 0, - 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 9, 0, 0, 0, 0, 9, 9, 9, + 0, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, - 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 34, 34, 34, 34, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 9, 9, 9, 9, + 34, 34, 34, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 0, 0, 0, 0, 0, 9, 0, 0, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 0, 9, 0, 0, 0, 0, 0, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, + 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, - 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 0, + 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 9, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 19, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -6061,493 +6536,616 @@ static unsigned char changes_3_2_0_data[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, + 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, + 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, + 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, - 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, - 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, - 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, + 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, + 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 19, - 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 19, + 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 21, 21, 21, 21, 21, 21, 0, 0, 0, 1, 1, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 21, 21, 21, 21, 21, 21, 0, 0, 0, 1, 1, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 0, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 0, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 53, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 53, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, + 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 9, 0, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 0, 0, 9, 0, 0, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, + 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 9, - 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, - 0, 0, 0, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 9, 9, 0, 0, - 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, - 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 9, 9, 0, + 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, + 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, + 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, + 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 0, 0, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 9, 9, 9, + 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 0, 0, 9, 9, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, + 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, + 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, + 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, + 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0, 0, 0, - 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0, 0, + 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 9, 0, 0, 9, 0, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 0, 9, 0, 9, 0, 0, 0, 0, 0, - 0, 9, 0, 0, 0, 0, 9, 0, 9, 0, 9, 0, 9, 9, 9, 0, 9, 9, 0, 9, 0, 0, 9, 0, - 9, 0, 9, 0, 9, 0, 9, 0, 9, 9, 0, 9, 0, 0, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, - 9, 9, 0, 9, 9, 9, 9, 0, 9, 9, 9, 9, 0, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, - 9, 9, 9, 0, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, + 0, 9, 9, 0, 9, 0, 0, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, + 0, 9, 0, 9, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 9, 0, 9, 0, 9, 0, 9, 9, 9, + 0, 9, 9, 0, 9, 0, 0, 9, 0, 9, 0, 9, 0, 9, 0, 9, 0, 9, 9, 0, 9, 0, 0, 9, + 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 0, 9, 9, 9, 9, 0, 9, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 0, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 0, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, - 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, - 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const change_record* get_change_3_2_0(Py_UCS4 n) diff --git a/Modules/unicodename_db.h b/Modules/unicodename_db.h index 7ccb1261f5fc..dd05f852b541 100644 --- a/Modules/unicodename_db.h +++ b/Modules/unicodename_db.h @@ -4,76 +4,75 @@ /* lexicon */ static unsigned char lexicon[] = { - 76, 69, 84, 84, 69, 210, 87, 73, 84, 200, 83, 89, 76, 76, 65, 66, 76, - 197, 83, 77, 65, 76, 204, 83, 73, 71, 206, 67, 65, 80, 73, 84, 65, 204, - 76, 65, 84, 73, 206, 89, 201, 65, 82, 65, 66, 73, 195, 67, 74, 203, 77, + 76, 69, 84, 84, 69, 210, 87, 73, 84, 200, 83, 73, 71, 206, 83, 89, 76, + 76, 65, 66, 76, 197, 83, 77, 65, 76, 204, 67, 65, 80, 73, 84, 65, 204, + 76, 65, 84, 73, 206, 65, 82, 65, 66, 73, 195, 89, 201, 67, 74, 203, 77, 65, 84, 72, 69, 77, 65, 84, 73, 67, 65, 204, 69, 71, 89, 80, 84, 73, 65, - 206, 72, 73, 69, 82, 79, 71, 76, 89, 80, 200, 67, 79, 77, 80, 65, 84, 73, - 66, 73, 76, 73, 84, 217, 67, 85, 78, 69, 73, 70, 79, 82, 205, 83, 89, 77, - 66, 79, 204, 70, 79, 82, 77, 128, 67, 65, 78, 65, 68, 73, 65, 206, 83, - 89, 76, 76, 65, 66, 73, 67, 211, 66, 65, 77, 85, 205, 68, 73, 71, 73, - 212, 65, 78, 196, 66, 79, 76, 196, 72, 65, 78, 71, 85, 204, 86, 79, 87, - 69, 204, 71, 82, 69, 69, 203, 76, 73, 71, 65, 84, 85, 82, 197, 77, 85, - 83, 73, 67, 65, 204, 69, 84, 72, 73, 79, 80, 73, 195, 84, 73, 77, 69, - 211, 70, 79, 210, 73, 84, 65, 76, 73, 195, 67, 89, 82, 73, 76, 76, 73, - 195, 82, 65, 68, 73, 67, 65, 204, 83, 65, 78, 83, 45, 83, 69, 82, 73, - 198, 84, 65, 77, 73, 204, 67, 73, 82, 67, 76, 69, 196, 67, 79, 77, 66, - 73, 78, 73, 78, 199, 84, 65, 201, 70, 73, 78, 65, 204, 86, 65, 201, 83, - 81, 85, 65, 82, 197, 76, 69, 70, 212, 82, 73, 71, 72, 212, 86, 65, 82, - 73, 65, 84, 73, 79, 206, 66, 82, 65, 73, 76, 76, 197, 80, 65, 84, 84, 69, - 82, 206, 65, 66, 79, 86, 69, 128, 66, 89, 90, 65, 78, 84, 73, 78, 197, - 83, 73, 71, 78, 128, 66, 69, 76, 79, 87, 128, 68, 79, 85, 66, 76, 197, - 73, 83, 79, 76, 65, 84, 69, 196, 78, 85, 77, 66, 69, 210, 75, 65, 84, 65, - 75, 65, 78, 193, 194, 77, 79, 68, 73, 70, 73, 69, 210, 68, 79, 212, 75, - 65, 78, 71, 88, 201, 65, 128, 76, 73, 78, 69, 65, 210, 84, 73, 66, 69, - 84, 65, 206, 79, 198, 73, 78, 73, 84, 73, 65, 204, 77, 69, 69, 205, 86, - 69, 82, 84, 73, 67, 65, 204, 77, 89, 65, 78, 77, 65, 210, 85, 128, 75, - 72, 77, 69, 210, 87, 72, 73, 84, 197, 65, 66, 79, 86, 197, 67, 65, 82, - 82, 73, 69, 210, 73, 128, 65, 82, 82, 79, 87, 128, 89, 69, 200, 79, 128, - 77, 65, 82, 75, 128, 65, 82, 82, 79, 215, 67, 79, 80, 84, 73, 195, 80, - 72, 65, 83, 69, 45, 197, 77, 79, 78, 71, 79, 76, 73, 65, 206, 68, 69, 86, - 65, 78, 65, 71, 65, 82, 201, 66, 76, 65, 67, 203, 84, 73, 76, 197, 83, - 89, 77, 66, 79, 76, 128, 80, 65, 82, 69, 78, 84, 72, 69, 83, 73, 90, 69, - 196, 84, 72, 65, 205, 74, 79, 78, 71, 83, 69, 79, 78, 199, 83, 84, 82, - 79, 75, 69, 128, 83, 81, 85, 65, 82, 69, 196, 66, 79, 216, 72, 69, 66, - 82, 69, 215, 77, 73, 65, 207, 80, 76, 85, 211, 82, 73, 71, 72, 84, 87, - 65, 82, 68, 211, 71, 69, 79, 82, 71, 73, 65, 206, 68, 82, 65, 87, 73, 78, - 71, 211, 67, 72, 79, 83, 69, 79, 78, 199, 72, 65, 76, 70, 87, 73, 68, 84, - 200, 66, 65, 76, 73, 78, 69, 83, 197, 72, 79, 79, 75, 128, 213, 84, 87, - 79, 128, 73, 68, 69, 79, 71, 82, 65, 205, 80, 72, 65, 83, 69, 45, 196, - 65, 76, 67, 72, 69, 77, 73, 67, 65, 204, 65, 76, 69, 198, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 73, 195, 79, 78, 69, 128, 84, 79, 128, 84, 87, 207, - 72, 69, 65, 86, 217, 79, 86, 69, 210, 67, 79, 78, 83, 79, 78, 65, 78, - 212, 66, 82, 65, 72, 77, 201, 83, 67, 82, 73, 80, 212, 85, 208, 76, 79, - 215, 72, 65, 200, 79, 78, 197, 68, 79, 87, 206, 72, 73, 71, 200, 70, 85, - 76, 76, 87, 73, 68, 84, 200, 66, 82, 65, 67, 75, 69, 84, 128, 69, 81, 85, - 65, 204, 84, 65, 199, 66, 65, 82, 128, 68, 79, 77, 73, 78, 207, 78, 85, - 77, 69, 82, 73, 195, 70, 82, 65, 75, 84, 85, 210, 84, 72, 82, 69, 197, - 67, 72, 65, 82, 65, 67, 84, 69, 210, 77, 65, 76, 65, 89, 65, 76, 65, 205, - 80, 72, 65, 83, 69, 45, 195, 84, 79, 78, 197, 68, 79, 85, 66, 76, 69, 45, - 83, 84, 82, 85, 67, 203, 76, 69, 70, 84, 87, 65, 82, 68, 211, 72, 73, 82, - 65, 71, 65, 78, 193, 65, 67, 85, 84, 69, 128, 74, 85, 78, 71, 83, 69, 79, - 78, 199, 71, 76, 65, 71, 79, 76, 73, 84, 73, 195, 66, 69, 78, 71, 65, 76, - 201, 77, 69, 68, 73, 65, 204, 84, 69, 76, 85, 71, 213, 86, 79, 67, 65, - 76, 73, 195, 65, 82, 77, 69, 78, 73, 65, 206, 74, 69, 69, 205, 78, 69, - 71, 65, 84, 73, 86, 197, 73, 68, 69, 79, 71, 82, 65, 80, 200, 74, 65, 86, - 65, 78, 69, 83, 197, 79, 82, 73, 89, 193, 84, 72, 82, 69, 69, 128, 87, - 69, 83, 84, 45, 67, 82, 69, 197, 70, 79, 85, 82, 128, 72, 65, 128, 72, - 65, 76, 198, 77, 65, 82, 203, 75, 65, 78, 78, 65, 68, 193, 78, 69, 215, - 80, 72, 65, 83, 69, 45, 193, 84, 72, 65, 201, 67, 72, 69, 82, 79, 75, 69, - 197, 68, 79, 84, 211, 71, 85, 74, 65, 82, 65, 84, 201, 67, 72, 65, 205, - 76, 85, 197, 83, 72, 65, 82, 65, 68, 193, 83, 73, 78, 72, 65, 76, 193, - 75, 65, 128, 82, 85, 78, 73, 195, 83, 65, 85, 82, 65, 83, 72, 84, 82, - 193, 84, 69, 84, 82, 65, 71, 82, 65, 205, 68, 69, 83, 69, 82, 69, 212, - 72, 65, 77, 90, 193, 83, 89, 82, 73, 65, 195, 84, 73, 76, 68, 69, 128, - 71, 85, 82, 77, 85, 75, 72, 201, 77, 65, 128, 77, 65, 89, 69, 203, 77, - 69, 69, 84, 69, 201, 78, 79, 84, 65, 84, 73, 79, 206, 70, 73, 86, 69, - 128, 80, 65, 128, 89, 65, 128, 76, 73, 71, 72, 212, 83, 73, 88, 128, 69, - 73, 71, 72, 84, 128, 76, 69, 80, 67, 72, 193, 78, 65, 128, 83, 69, 86, - 69, 78, 128, 76, 79, 78, 199, 78, 73, 78, 69, 128, 84, 85, 82, 75, 73, - 195, 72, 79, 82, 73, 90, 79, 78, 84, 65, 204, 79, 80, 69, 206, 82, 65, - 128, 83, 65, 128, 83, 85, 78, 68, 65, 78, 69, 83, 197, 86, 73, 69, 212, - 76, 65, 207, 90, 90, 89, 88, 128, 90, 90, 89, 84, 128, 90, 90, 89, 82, + 206, 72, 73, 69, 82, 79, 71, 76, 89, 80, 200, 67, 85, 78, 69, 73, 70, 79, + 82, 205, 67, 79, 77, 80, 65, 84, 73, 66, 73, 76, 73, 84, 217, 83, 89, 77, + 66, 79, 204, 70, 79, 82, 77, 128, 68, 73, 71, 73, 212, 67, 65, 78, 65, + 68, 73, 65, 206, 83, 89, 76, 76, 65, 66, 73, 67, 211, 66, 65, 77, 85, + 205, 86, 79, 87, 69, 204, 65, 78, 196, 66, 79, 76, 196, 72, 65, 78, 71, + 85, 204, 76, 73, 78, 69, 65, 210, 71, 82, 69, 69, 203, 76, 73, 71, 65, + 84, 85, 82, 197, 84, 73, 77, 69, 211, 77, 85, 83, 73, 67, 65, 204, 69, + 84, 72, 73, 79, 80, 73, 195, 193, 70, 79, 210, 67, 89, 82, 73, 76, 76, + 73, 195, 73, 84, 65, 76, 73, 195, 67, 79, 77, 66, 73, 78, 73, 78, 199, + 82, 65, 68, 73, 67, 65, 204, 83, 65, 78, 83, 45, 83, 69, 82, 73, 198, 67, + 73, 82, 67, 76, 69, 196, 84, 65, 77, 73, 204, 84, 65, 201, 70, 73, 78, + 65, 204, 78, 85, 77, 66, 69, 210, 65, 82, 82, 79, 87, 128, 86, 65, 201, + 76, 69, 70, 212, 82, 73, 71, 72, 212, 83, 81, 85, 65, 82, 197, 68, 79, + 85, 66, 76, 197, 65, 82, 82, 79, 215, 65, 66, 79, 86, 69, 128, 83, 73, + 71, 78, 128, 86, 65, 82, 73, 65, 84, 73, 79, 206, 66, 69, 76, 79, 87, + 128, 66, 82, 65, 73, 76, 76, 197, 80, 65, 84, 84, 69, 82, 206, 66, 89, + 90, 65, 78, 84, 73, 78, 197, 87, 72, 73, 84, 197, 66, 76, 65, 67, 203, + 73, 83, 79, 76, 65, 84, 69, 196, 65, 128, 194, 75, 65, 84, 65, 75, 65, + 78, 193, 77, 79, 68, 73, 70, 73, 69, 210, 77, 89, 65, 78, 77, 65, 210, + 68, 79, 212, 75, 65, 78, 71, 88, 201, 75, 73, 75, 65, 75, 85, 201, 77, + 69, 78, 68, 197, 85, 128, 84, 73, 66, 69, 84, 65, 206, 79, 198, 73, 128, + 79, 128, 72, 69, 65, 86, 217, 73, 78, 73, 84, 73, 65, 204, 86, 69, 82, + 84, 73, 67, 65, 204, 77, 69, 69, 205, 67, 79, 80, 84, 73, 195, 75, 72, + 77, 69, 210, 77, 65, 82, 75, 128, 65, 66, 79, 86, 197, 67, 65, 82, 82, + 73, 69, 210, 82, 73, 71, 72, 84, 87, 65, 82, 68, 211, 89, 69, 200, 80, + 72, 65, 83, 69, 45, 197, 68, 69, 86, 65, 78, 65, 71, 65, 82, 201, 77, 79, + 78, 71, 79, 76, 73, 65, 206, 83, 84, 82, 79, 75, 69, 128, 76, 69, 70, 84, + 87, 65, 82, 68, 211, 83, 89, 77, 66, 79, 76, 128, 84, 73, 76, 197, 68, + 85, 80, 76, 79, 89, 65, 206, 66, 79, 216, 80, 65, 82, 69, 78, 84, 72, 69, + 83, 73, 90, 69, 196, 83, 81, 85, 65, 82, 69, 196, 84, 72, 65, 205, 74, + 79, 78, 71, 83, 69, 79, 78, 199, 80, 76, 85, 211, 79, 78, 69, 128, 72, + 69, 66, 82, 69, 215, 77, 73, 65, 207, 84, 87, 79, 128, 213, 67, 79, 78, + 83, 79, 78, 65, 78, 212, 71, 69, 79, 82, 71, 73, 65, 206, 72, 79, 79, 75, + 128, 68, 82, 65, 87, 73, 78, 71, 211, 72, 77, 79, 78, 199, 80, 65, 72, + 65, 87, 200, 67, 72, 79, 83, 69, 79, 78, 199, 76, 79, 215, 86, 79, 67, + 65, 76, 73, 195, 72, 65, 76, 70, 87, 73, 68, 84, 200, 66, 65, 76, 73, 78, + 69, 83, 197, 84, 87, 207, 79, 78, 197, 85, 208, 83, 67, 82, 73, 80, 212, + 73, 68, 69, 79, 71, 82, 65, 205, 80, 72, 65, 83, 69, 45, 196, 84, 79, + 128, 65, 76, 67, 72, 69, 77, 73, 67, 65, 204, 65, 76, 69, 198, 72, 73, + 71, 200, 73, 68, 69, 79, 71, 82, 65, 80, 72, 73, 195, 84, 72, 82, 69, + 197, 68, 79, 87, 206, 79, 86, 69, 210, 83, 73, 78, 72, 65, 76, 193, 78, + 85, 77, 69, 82, 73, 195, 66, 65, 82, 128, 84, 79, 78, 197, 66, 82, 65, + 72, 77, 201, 66, 65, 82, 194, 70, 79, 85, 82, 128, 72, 65, 200, 77, 65, + 82, 203, 84, 72, 82, 69, 69, 128, 78, 79, 82, 84, 200, 70, 85, 76, 76, + 87, 73, 68, 84, 200, 66, 82, 65, 67, 75, 69, 84, 128, 69, 81, 85, 65, + 204, 76, 73, 71, 72, 212, 84, 65, 199, 68, 79, 77, 73, 78, 207, 76, 79, + 78, 199, 65, 67, 85, 84, 69, 128, 70, 82, 65, 75, 84, 85, 210, 72, 65, + 128, 77, 65, 76, 65, 89, 65, 76, 65, 205, 67, 72, 65, 82, 65, 67, 84, 69, + 210, 80, 72, 65, 83, 69, 45, 195, 68, 79, 85, 66, 76, 69, 45, 83, 84, 82, + 85, 67, 203, 72, 65, 76, 198, 72, 73, 82, 65, 71, 65, 78, 193, 74, 85, + 78, 71, 83, 69, 79, 78, 199, 84, 69, 76, 85, 71, 213, 65, 82, 77, 69, 78, + 73, 65, 206, 66, 69, 78, 71, 65, 76, 201, 71, 76, 65, 71, 79, 76, 73, 84, + 73, 195, 85, 80, 87, 65, 82, 68, 211, 70, 73, 86, 69, 128, 77, 69, 68, + 73, 65, 204, 78, 69, 71, 65, 84, 73, 86, 197, 74, 69, 69, 205, 75, 65, + 128, 68, 79, 87, 78, 87, 65, 82, 68, 211, 73, 68, 69, 79, 71, 82, 65, 80, + 200, 74, 65, 86, 65, 78, 69, 83, 197, 68, 79, 84, 211, 79, 82, 73, 89, + 193, 80, 65, 128, 87, 69, 83, 84, 45, 67, 82, 69, 197, 82, 85, 78, 73, + 195, 83, 128, 75, 65, 78, 78, 65, 68, 193, 83, 73, 88, 128, 77, 65, 128, + 78, 69, 215, 80, 72, 65, 83, 69, 45, 193, 83, 79, 85, 84, 200, 84, 72, + 65, 201, 89, 65, 128, 67, 65, 82, 196, 67, 72, 69, 82, 79, 75, 69, 197, + 69, 73, 71, 72, 84, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 204, 83, 69, + 86, 69, 78, 128, 83, 72, 65, 82, 65, 68, 193, 67, 73, 84, 201, 71, 85, + 74, 65, 82, 65, 84, 201, 78, 65, 128, 78, 73, 78, 69, 128, 84, 85, 82, + 78, 69, 196, 87, 65, 82, 65, 78, 199, 67, 72, 65, 205, 71, 82, 65, 78, + 84, 72, 193, 90, 90, 89, 88, 128, 90, 90, 89, 84, 128, 90, 90, 89, 82, 88, 128, 90, 90, 89, 82, 128, 90, 90, 89, 80, 128, 90, 90, 89, 65, 128, 90, 90, 89, 128, 90, 90, 85, 88, 128, 90, 90, 85, 82, 88, 128, 90, 90, 85, 82, 128, 90, 90, 85, 80, 128, 90, 90, 85, 128, 90, 90, 83, 89, 65, @@ -84,181 +83,192 @@ static unsigned char lexicon[] = { 90, 69, 80, 128, 90, 90, 69, 69, 128, 90, 90, 69, 128, 90, 90, 65, 88, 128, 90, 90, 65, 84, 128, 90, 90, 65, 80, 128, 90, 90, 65, 65, 128, 90, 90, 65, 128, 90, 89, 71, 79, 83, 128, 90, 87, 83, 80, 128, 90, 87, 78, - 74, 128, 90, 87, 78, 66, 83, 80, 128, 90, 87, 74, 128, 90, 87, 65, 82, - 65, 75, 65, 89, 128, 90, 87, 65, 128, 90, 85, 84, 128, 90, 85, 79, 88, - 128, 90, 85, 79, 80, 128, 90, 85, 79, 128, 90, 85, 77, 128, 90, 85, 66, - 85, 82, 128, 90, 85, 53, 128, 90, 85, 181, 90, 83, 72, 65, 128, 90, 82, - 65, 128, 90, 81, 65, 80, 72, 193, 90, 79, 84, 128, 90, 79, 79, 128, 90, - 79, 65, 128, 90, 76, 65, 77, 193, 90, 76, 65, 128, 90, 76, 193, 90, 74, - 69, 128, 90, 73, 90, 50, 128, 90, 73, 81, 65, 65, 128, 90, 73, 78, 79, - 82, 128, 90, 73, 76, 68, 69, 128, 90, 73, 71, 90, 65, 199, 90, 73, 71, - 128, 90, 73, 68, 193, 90, 73, 66, 128, 90, 73, 194, 90, 73, 51, 128, 90, - 201, 90, 72, 89, 88, 128, 90, 72, 89, 84, 128, 90, 72, 89, 82, 88, 128, - 90, 72, 89, 82, 128, 90, 72, 89, 80, 128, 90, 72, 89, 128, 90, 72, 87, - 69, 128, 90, 72, 87, 65, 128, 90, 72, 85, 88, 128, 90, 72, 85, 84, 128, - 90, 72, 85, 82, 88, 128, 90, 72, 85, 82, 128, 90, 72, 85, 80, 128, 90, - 72, 85, 79, 88, 128, 90, 72, 85, 79, 80, 128, 90, 72, 85, 79, 128, 90, - 72, 85, 128, 90, 72, 79, 88, 128, 90, 72, 79, 84, 128, 90, 72, 79, 80, - 128, 90, 72, 79, 79, 128, 90, 72, 79, 128, 90, 72, 73, 86, 69, 84, 69, - 128, 90, 72, 73, 128, 90, 72, 69, 88, 128, 90, 72, 69, 84, 128, 90, 72, - 69, 80, 128, 90, 72, 69, 69, 128, 90, 72, 69, 128, 90, 72, 197, 90, 72, - 65, 88, 128, 90, 72, 65, 84, 128, 90, 72, 65, 82, 128, 90, 72, 65, 80, - 128, 90, 72, 65, 73, 78, 128, 90, 72, 65, 65, 128, 90, 72, 65, 128, 90, - 72, 128, 90, 69, 84, 65, 128, 90, 69, 82, 79, 128, 90, 69, 82, 207, 90, - 69, 78, 128, 90, 69, 77, 76, 89, 65, 128, 90, 69, 77, 76, 74, 65, 128, - 90, 69, 50, 128, 90, 197, 90, 65, 89, 78, 128, 90, 65, 89, 73, 78, 128, - 90, 65, 89, 73, 206, 90, 65, 86, 73, 89, 65, 78, 73, 128, 90, 65, 84, 65, - 128, 90, 65, 82, 81, 65, 128, 90, 65, 81, 69, 198, 90, 65, 77, 88, 128, - 90, 65, 204, 90, 65, 73, 78, 128, 90, 65, 73, 206, 90, 65, 73, 128, 90, - 65, 72, 128, 90, 65, 200, 90, 65, 71, 128, 90, 65, 69, 70, 128, 90, 48, - 49, 54, 72, 128, 90, 48, 49, 54, 71, 128, 90, 48, 49, 54, 70, 128, 90, - 48, 49, 54, 69, 128, 90, 48, 49, 54, 68, 128, 90, 48, 49, 54, 67, 128, - 90, 48, 49, 54, 66, 128, 90, 48, 49, 54, 65, 128, 90, 48, 49, 54, 128, - 90, 48, 49, 53, 73, 128, 90, 48, 49, 53, 72, 128, 90, 48, 49, 53, 71, - 128, 90, 48, 49, 53, 70, 128, 90, 48, 49, 53, 69, 128, 90, 48, 49, 53, - 68, 128, 90, 48, 49, 53, 67, 128, 90, 48, 49, 53, 66, 128, 90, 48, 49, - 53, 65, 128, 90, 48, 49, 53, 128, 90, 48, 49, 52, 128, 90, 48, 49, 51, - 128, 90, 48, 49, 50, 128, 90, 48, 49, 49, 128, 90, 48, 49, 48, 128, 90, - 48, 48, 57, 128, 90, 48, 48, 56, 128, 90, 48, 48, 55, 128, 90, 48, 48, - 54, 128, 90, 48, 48, 53, 65, 128, 90, 48, 48, 53, 128, 90, 48, 48, 52, - 65, 128, 90, 48, 48, 52, 128, 90, 48, 48, 51, 66, 128, 90, 48, 48, 51, - 65, 128, 90, 48, 48, 51, 128, 90, 48, 48, 50, 68, 128, 90, 48, 48, 50, - 67, 128, 90, 48, 48, 50, 66, 128, 90, 48, 48, 50, 65, 128, 90, 48, 48, - 50, 128, 90, 48, 48, 49, 128, 90, 128, 218, 89, 89, 88, 128, 89, 89, 84, - 128, 89, 89, 82, 88, 128, 89, 89, 82, 128, 89, 89, 80, 128, 89, 89, 69, - 128, 89, 89, 65, 65, 128, 89, 89, 65, 128, 89, 89, 128, 89, 87, 79, 79, - 128, 89, 87, 79, 128, 89, 87, 73, 73, 128, 89, 87, 73, 128, 89, 87, 69, - 128, 89, 87, 65, 65, 128, 89, 87, 65, 128, 89, 86, 128, 89, 85, 88, 128, - 89, 85, 87, 79, 81, 128, 89, 85, 85, 75, 65, 76, 69, 65, 80, 73, 78, 84, - 85, 128, 89, 85, 85, 128, 89, 85, 84, 128, 89, 85, 83, 128, 89, 85, 211, - 89, 85, 82, 88, 128, 89, 85, 82, 128, 89, 85, 81, 128, 89, 85, 209, 89, - 85, 80, 128, 89, 85, 79, 88, 128, 89, 85, 79, 84, 128, 89, 85, 79, 80, - 128, 89, 85, 79, 77, 128, 89, 85, 79, 128, 89, 85, 78, 128, 89, 85, 77, - 128, 89, 85, 69, 81, 128, 89, 85, 69, 128, 89, 85, 68, 72, 128, 89, 85, - 68, 200, 89, 85, 65, 78, 128, 89, 85, 65, 69, 78, 128, 89, 85, 45, 89, - 69, 79, 128, 89, 85, 45, 89, 69, 128, 89, 85, 45, 85, 128, 89, 85, 45, - 79, 128, 89, 85, 45, 73, 128, 89, 85, 45, 69, 79, 128, 89, 85, 45, 69, - 128, 89, 85, 45, 65, 69, 128, 89, 85, 45, 65, 128, 89, 85, 128, 89, 213, - 89, 80, 83, 73, 76, 73, 128, 89, 80, 79, 82, 82, 79, 73, 128, 89, 80, 79, - 75, 82, 73, 83, 73, 83, 128, 89, 80, 79, 75, 82, 73, 83, 73, 211, 89, 80, - 79, 71, 69, 71, 82, 65, 77, 77, 69, 78, 73, 128, 89, 79, 89, 128, 89, 79, - 88, 128, 89, 79, 85, 84, 72, 70, 85, 76, 78, 69, 83, 83, 128, 89, 79, 85, - 84, 72, 70, 85, 204, 89, 79, 84, 128, 89, 79, 82, 73, 128, 89, 79, 81, - 128, 89, 79, 209, 89, 79, 80, 128, 89, 79, 79, 128, 89, 79, 77, 79, 128, - 89, 79, 71, 72, 128, 89, 79, 68, 72, 128, 89, 79, 68, 128, 89, 79, 196, - 89, 79, 65, 128, 89, 79, 45, 89, 69, 79, 128, 89, 79, 45, 89, 65, 69, - 128, 89, 79, 45, 89, 65, 128, 89, 79, 45, 79, 128, 89, 79, 45, 73, 128, - 89, 79, 45, 69, 79, 128, 89, 79, 45, 65, 69, 128, 89, 79, 45, 65, 128, - 89, 79, 128, 89, 207, 89, 73, 90, 69, 84, 128, 89, 73, 88, 128, 89, 73, - 87, 78, 128, 89, 73, 84, 128, 89, 73, 80, 128, 89, 73, 78, 71, 128, 89, - 73, 73, 128, 89, 73, 199, 89, 73, 69, 88, 128, 89, 73, 69, 84, 128, 89, - 73, 69, 80, 128, 89, 73, 69, 69, 128, 89, 73, 69, 128, 89, 73, 68, 68, - 73, 83, 200, 89, 73, 45, 85, 128, 89, 73, 128, 89, 70, 69, 83, 73, 83, - 128, 89, 70, 69, 83, 73, 211, 89, 70, 69, 206, 89, 69, 89, 128, 89, 69, - 87, 128, 89, 69, 85, 88, 128, 89, 69, 85, 82, 65, 69, 128, 89, 69, 85, - 81, 128, 89, 69, 85, 77, 128, 89, 69, 85, 65, 69, 84, 128, 89, 69, 85, - 65, 69, 128, 89, 69, 84, 73, 86, 128, 89, 69, 83, 84, 85, 128, 89, 69, - 83, 73, 69, 85, 78, 71, 45, 83, 73, 79, 83, 128, 89, 69, 83, 73, 69, 85, - 78, 71, 45, 80, 65, 78, 83, 73, 79, 83, 128, 89, 69, 83, 73, 69, 85, 78, - 71, 45, 77, 73, 69, 85, 77, 128, 89, 69, 83, 73, 69, 85, 78, 71, 45, 72, - 73, 69, 85, 72, 128, 89, 69, 83, 73, 69, 85, 78, 71, 128, 89, 69, 82, 85, - 128, 89, 69, 82, 213, 89, 69, 82, 73, 128, 89, 69, 82, 65, 200, 89, 69, - 82, 128, 89, 69, 79, 82, 73, 78, 72, 73, 69, 85, 72, 128, 89, 69, 79, 45, - 89, 65, 128, 89, 69, 79, 45, 85, 128, 89, 69, 79, 45, 79, 128, 89, 69, - 78, 73, 83, 69, 201, 89, 69, 78, 65, 80, 128, 89, 69, 78, 128, 89, 69, - 206, 89, 69, 76, 76, 79, 87, 128, 89, 69, 76, 76, 79, 215, 89, 69, 72, - 128, 89, 69, 69, 128, 89, 69, 65, 210, 89, 69, 65, 128, 89, 65, 90, 90, - 128, 89, 65, 90, 72, 128, 89, 65, 90, 128, 89, 65, 89, 65, 78, 78, 65, - 128, 89, 65, 89, 128, 89, 65, 87, 128, 89, 65, 86, 128, 89, 65, 85, 128, - 89, 65, 84, 84, 128, 89, 65, 84, 73, 128, 89, 65, 84, 72, 128, 89, 65, - 84, 128, 89, 65, 83, 83, 128, 89, 65, 83, 72, 128, 89, 65, 83, 128, 89, - 65, 82, 82, 128, 89, 65, 82, 128, 89, 65, 210, 89, 65, 81, 128, 89, 65, - 80, 128, 89, 65, 78, 83, 65, 89, 65, 128, 89, 65, 78, 71, 128, 89, 65, - 78, 199, 89, 65, 78, 128, 89, 65, 77, 79, 75, 128, 89, 65, 77, 65, 75, - 75, 65, 78, 128, 89, 65, 77, 128, 89, 65, 76, 128, 89, 65, 75, 72, 72, - 128, 89, 65, 75, 72, 128, 89, 65, 75, 65, 83, 72, 128, 89, 65, 75, 128, - 89, 65, 74, 85, 82, 86, 69, 68, 73, 195, 89, 65, 74, 128, 89, 65, 73, - 128, 89, 65, 72, 72, 128, 89, 65, 72, 128, 89, 65, 71, 78, 128, 89, 65, - 71, 72, 72, 128, 89, 65, 71, 72, 128, 89, 65, 71, 128, 89, 65, 70, 213, - 89, 65, 70, 128, 89, 65, 69, 77, 77, 65, 69, 128, 89, 65, 68, 72, 128, - 89, 65, 68, 68, 72, 128, 89, 65, 68, 68, 128, 89, 65, 68, 128, 89, 65, - 67, 72, 128, 89, 65, 66, 72, 128, 89, 65, 66, 128, 89, 65, 65, 82, 85, - 128, 89, 65, 65, 73, 128, 89, 65, 65, 68, 79, 128, 89, 65, 45, 89, 79, - 128, 89, 65, 45, 85, 128, 89, 65, 45, 79, 128, 89, 48, 48, 56, 128, 89, - 48, 48, 55, 128, 89, 48, 48, 54, 128, 89, 48, 48, 53, 128, 89, 48, 48, - 52, 128, 89, 48, 48, 51, 128, 89, 48, 48, 50, 128, 89, 48, 48, 49, 65, - 128, 89, 48, 48, 49, 128, 89, 45, 67, 82, 69, 197, 88, 89, 88, 128, 88, - 89, 85, 128, 88, 89, 84, 128, 88, 89, 82, 88, 128, 88, 89, 82, 128, 88, - 89, 80, 128, 88, 89, 79, 128, 88, 89, 73, 128, 88, 89, 69, 69, 128, 88, - 89, 69, 128, 88, 89, 65, 65, 128, 88, 89, 65, 128, 88, 89, 128, 88, 87, - 73, 128, 88, 87, 69, 69, 128, 88, 87, 69, 128, 88, 87, 65, 65, 128, 88, - 87, 65, 128, 88, 86, 69, 128, 88, 86, 65, 128, 88, 85, 79, 88, 128, 88, - 85, 79, 128, 88, 85, 128, 88, 83, 72, 65, 65, 89, 65, 84, 72, 73, 89, 65, - 128, 88, 79, 88, 128, 88, 79, 84, 128, 88, 79, 82, 128, 88, 79, 80, 128, - 88, 79, 65, 128, 88, 79, 128, 88, 73, 88, 128, 88, 73, 84, 128, 88, 73, - 82, 79, 206, 88, 73, 80, 128, 88, 73, 69, 88, 128, 88, 73, 69, 84, 128, - 88, 73, 69, 80, 128, 88, 73, 69, 128, 88, 73, 128, 88, 71, 128, 88, 69, - 83, 84, 69, 211, 88, 69, 72, 128, 88, 69, 69, 128, 88, 69, 128, 88, 65, - 78, 128, 88, 65, 65, 128, 88, 65, 128, 88, 48, 48, 56, 65, 128, 88, 48, - 48, 56, 128, 88, 48, 48, 55, 128, 88, 48, 48, 54, 65, 128, 88, 48, 48, - 54, 128, 88, 48, 48, 53, 128, 88, 48, 48, 52, 66, 128, 88, 48, 48, 52, - 65, 128, 88, 48, 48, 52, 128, 88, 48, 48, 51, 128, 88, 48, 48, 50, 128, - 88, 48, 48, 49, 128, 87, 90, 128, 87, 89, 78, 78, 128, 87, 89, 78, 206, - 87, 86, 128, 87, 85, 80, 128, 87, 85, 79, 88, 128, 87, 85, 79, 80, 128, - 87, 85, 79, 128, 87, 85, 78, 74, 207, 87, 85, 78, 128, 87, 85, 76, 85, - 128, 87, 85, 76, 213, 87, 85, 69, 128, 87, 85, 65, 69, 84, 128, 87, 85, - 65, 69, 78, 128, 87, 85, 128, 87, 82, 217, 87, 82, 79, 78, 71, 128, 87, - 82, 73, 84, 73, 78, 199, 87, 82, 69, 78, 67, 72, 128, 87, 82, 69, 65, 84, - 200, 87, 82, 65, 80, 80, 69, 196, 87, 82, 65, 80, 128, 87, 79, 88, 128, - 87, 79, 82, 82, 73, 69, 196, 87, 79, 82, 75, 69, 82, 128, 87, 79, 82, 75, - 128, 87, 79, 82, 203, 87, 79, 82, 68, 83, 80, 65, 67, 69, 128, 87, 79, - 82, 196, 87, 79, 80, 128, 87, 79, 79, 78, 128, 87, 79, 79, 76, 128, 87, - 79, 79, 68, 83, 45, 67, 82, 69, 197, 87, 79, 79, 68, 128, 87, 79, 78, - 128, 87, 79, 206, 87, 79, 77, 69, 78, 211, 87, 79, 77, 69, 206, 87, 79, - 77, 65, 78, 211, 87, 79, 77, 65, 78, 128, 87, 79, 77, 65, 206, 87, 79, - 76, 79, 83, 79, 128, 87, 79, 76, 198, 87, 79, 69, 128, 87, 79, 65, 128, - 87, 73, 84, 72, 79, 85, 212, 87, 73, 84, 72, 73, 78, 128, 87, 73, 78, 84, - 69, 82, 128, 87, 73, 78, 75, 73, 78, 199, 87, 73, 78, 74, 65, 128, 87, - 73, 78, 71, 83, 128, 87, 73, 78, 69, 128, 87, 73, 78, 197, 87, 73, 78, - 68, 85, 128, 87, 73, 78, 68, 128, 87, 73, 78, 196, 87, 73, 78, 128, 87, + 74, 128, 90, 87, 78, 66, 83, 80, 128, 90, 87, 74, 128, 90, 87, 202, 90, + 87, 65, 82, 65, 75, 65, 89, 128, 90, 87, 65, 128, 90, 85, 84, 128, 90, + 85, 79, 88, 128, 90, 85, 79, 80, 128, 90, 85, 79, 128, 90, 85, 77, 128, + 90, 85, 66, 85, 82, 128, 90, 85, 53, 128, 90, 85, 181, 90, 83, 72, 65, + 128, 90, 82, 65, 128, 90, 81, 65, 80, 72, 193, 90, 79, 84, 128, 90, 79, + 79, 128, 90, 79, 65, 128, 90, 76, 65, 77, 193, 90, 76, 65, 128, 90, 76, + 193, 90, 74, 69, 128, 90, 73, 90, 50, 128, 90, 73, 81, 65, 65, 128, 90, + 73, 78, 79, 82, 128, 90, 73, 76, 68, 69, 128, 90, 73, 71, 90, 65, 199, + 90, 73, 71, 128, 90, 73, 68, 193, 90, 73, 66, 128, 90, 73, 194, 90, 73, + 51, 128, 90, 201, 90, 72, 89, 88, 128, 90, 72, 89, 84, 128, 90, 72, 89, + 82, 88, 128, 90, 72, 89, 82, 128, 90, 72, 89, 80, 128, 90, 72, 89, 128, + 90, 72, 87, 69, 128, 90, 72, 87, 65, 128, 90, 72, 85, 88, 128, 90, 72, + 85, 84, 128, 90, 72, 85, 82, 88, 128, 90, 72, 85, 82, 128, 90, 72, 85, + 80, 128, 90, 72, 85, 79, 88, 128, 90, 72, 85, 79, 80, 128, 90, 72, 85, + 79, 128, 90, 72, 85, 128, 90, 72, 79, 88, 128, 90, 72, 79, 84, 128, 90, + 72, 79, 80, 128, 90, 72, 79, 79, 128, 90, 72, 79, 73, 128, 90, 72, 79, + 128, 90, 72, 73, 86, 69, 84, 69, 128, 90, 72, 73, 76, 128, 90, 72, 73, + 128, 90, 72, 69, 88, 128, 90, 72, 69, 84, 128, 90, 72, 69, 80, 128, 90, + 72, 69, 69, 128, 90, 72, 69, 128, 90, 72, 197, 90, 72, 65, 89, 73, 78, + 128, 90, 72, 65, 88, 128, 90, 72, 65, 84, 128, 90, 72, 65, 82, 128, 90, + 72, 65, 80, 128, 90, 72, 65, 73, 78, 128, 90, 72, 65, 65, 128, 90, 72, + 65, 128, 90, 72, 128, 90, 69, 84, 65, 128, 90, 69, 82, 79, 128, 90, 69, + 82, 207, 90, 69, 78, 128, 90, 69, 77, 76, 89, 65, 128, 90, 69, 77, 76, + 74, 65, 128, 90, 69, 50, 128, 90, 197, 90, 65, 89, 78, 128, 90, 65, 89, + 73, 78, 128, 90, 65, 89, 73, 206, 90, 65, 86, 73, 89, 65, 78, 73, 128, + 90, 65, 84, 65, 128, 90, 65, 82, 81, 65, 128, 90, 65, 82, 76, 128, 90, + 65, 81, 69, 198, 90, 65, 77, 88, 128, 90, 65, 204, 90, 65, 73, 78, 128, + 90, 65, 73, 206, 90, 65, 73, 128, 90, 65, 72, 128, 90, 65, 200, 90, 65, + 71, 128, 90, 65, 69, 70, 128, 90, 193, 90, 48, 49, 54, 72, 128, 90, 48, + 49, 54, 71, 128, 90, 48, 49, 54, 70, 128, 90, 48, 49, 54, 69, 128, 90, + 48, 49, 54, 68, 128, 90, 48, 49, 54, 67, 128, 90, 48, 49, 54, 66, 128, + 90, 48, 49, 54, 65, 128, 90, 48, 49, 54, 128, 90, 48, 49, 53, 73, 128, + 90, 48, 49, 53, 72, 128, 90, 48, 49, 53, 71, 128, 90, 48, 49, 53, 70, + 128, 90, 48, 49, 53, 69, 128, 90, 48, 49, 53, 68, 128, 90, 48, 49, 53, + 67, 128, 90, 48, 49, 53, 66, 128, 90, 48, 49, 53, 65, 128, 90, 48, 49, + 53, 128, 90, 48, 49, 52, 128, 90, 48, 49, 51, 128, 90, 48, 49, 50, 128, + 90, 48, 49, 49, 128, 90, 48, 49, 48, 128, 90, 48, 48, 57, 128, 90, 48, + 48, 56, 128, 90, 48, 48, 55, 128, 90, 48, 48, 54, 128, 90, 48, 48, 53, + 65, 128, 90, 48, 48, 53, 128, 90, 48, 48, 52, 65, 128, 90, 48, 48, 52, + 128, 90, 48, 48, 51, 66, 128, 90, 48, 48, 51, 65, 128, 90, 48, 48, 51, + 128, 90, 48, 48, 50, 68, 128, 90, 48, 48, 50, 67, 128, 90, 48, 48, 50, + 66, 128, 90, 48, 48, 50, 65, 128, 90, 48, 48, 50, 128, 90, 48, 48, 49, + 128, 90, 128, 218, 89, 89, 88, 128, 89, 89, 84, 128, 89, 89, 82, 88, 128, + 89, 89, 82, 128, 89, 89, 80, 128, 89, 89, 69, 128, 89, 89, 65, 65, 128, + 89, 89, 65, 128, 89, 89, 128, 89, 87, 79, 79, 128, 89, 87, 79, 128, 89, + 87, 73, 73, 128, 89, 87, 73, 128, 89, 87, 69, 128, 89, 87, 65, 65, 128, + 89, 87, 65, 128, 89, 86, 128, 89, 85, 88, 128, 89, 85, 87, 79, 81, 128, + 89, 85, 85, 75, 65, 76, 69, 65, 80, 73, 78, 84, 85, 128, 89, 85, 85, 128, + 89, 85, 84, 128, 89, 85, 83, 128, 89, 85, 211, 89, 85, 82, 88, 128, 89, + 85, 82, 128, 89, 85, 81, 128, 89, 85, 209, 89, 85, 80, 128, 89, 85, 79, + 88, 128, 89, 85, 79, 84, 128, 89, 85, 79, 80, 128, 89, 85, 79, 77, 128, + 89, 85, 79, 128, 89, 85, 78, 128, 89, 85, 77, 128, 89, 85, 74, 128, 89, + 85, 69, 81, 128, 89, 85, 69, 128, 89, 85, 68, 72, 128, 89, 85, 68, 200, + 89, 85, 65, 78, 128, 89, 85, 65, 69, 78, 128, 89, 85, 45, 89, 69, 79, + 128, 89, 85, 45, 89, 69, 128, 89, 85, 45, 85, 128, 89, 85, 45, 79, 128, + 89, 85, 45, 73, 128, 89, 85, 45, 69, 79, 128, 89, 85, 45, 69, 128, 89, + 85, 45, 65, 69, 128, 89, 85, 45, 65, 128, 89, 85, 128, 89, 213, 89, 82, + 89, 128, 89, 80, 83, 73, 76, 73, 128, 89, 80, 79, 82, 82, 79, 73, 128, + 89, 80, 79, 75, 82, 73, 83, 73, 83, 128, 89, 80, 79, 75, 82, 73, 83, 73, + 211, 89, 80, 79, 71, 69, 71, 82, 65, 77, 77, 69, 78, 73, 128, 89, 79, 89, + 128, 89, 79, 88, 128, 89, 79, 87, 68, 128, 89, 79, 85, 84, 72, 70, 85, + 76, 78, 69, 83, 83, 128, 89, 79, 85, 84, 72, 70, 85, 204, 89, 79, 84, + 128, 89, 79, 82, 73, 128, 89, 79, 81, 128, 89, 79, 209, 89, 79, 80, 128, + 89, 79, 79, 128, 89, 79, 77, 79, 128, 89, 79, 71, 72, 128, 89, 79, 68, + 72, 128, 89, 79, 68, 128, 89, 79, 196, 89, 79, 65, 128, 89, 79, 45, 89, + 69, 79, 128, 89, 79, 45, 89, 65, 69, 128, 89, 79, 45, 89, 65, 128, 89, + 79, 45, 79, 128, 89, 79, 45, 73, 128, 89, 79, 45, 69, 79, 128, 89, 79, + 45, 65, 69, 128, 89, 79, 45, 65, 128, 89, 79, 128, 89, 207, 89, 73, 90, + 69, 84, 128, 89, 73, 88, 128, 89, 73, 87, 78, 128, 89, 73, 84, 128, 89, + 73, 80, 128, 89, 73, 78, 71, 128, 89, 73, 73, 128, 89, 73, 199, 89, 73, + 69, 88, 128, 89, 73, 69, 84, 128, 89, 73, 69, 80, 128, 89, 73, 69, 69, + 128, 89, 73, 69, 128, 89, 73, 68, 68, 73, 83, 200, 89, 73, 45, 85, 128, + 89, 73, 128, 89, 70, 69, 83, 73, 83, 128, 89, 70, 69, 83, 73, 211, 89, + 70, 69, 206, 89, 69, 89, 128, 89, 69, 87, 128, 89, 69, 85, 88, 128, 89, + 69, 85, 82, 65, 69, 128, 89, 69, 85, 81, 128, 89, 69, 85, 77, 128, 89, + 69, 85, 65, 69, 84, 128, 89, 69, 85, 65, 69, 128, 89, 69, 84, 73, 86, + 128, 89, 69, 83, 84, 85, 128, 89, 69, 83, 73, 69, 85, 78, 71, 45, 83, 73, + 79, 83, 128, 89, 69, 83, 73, 69, 85, 78, 71, 45, 80, 65, 78, 83, 73, 79, + 83, 128, 89, 69, 83, 73, 69, 85, 78, 71, 45, 77, 73, 69, 85, 77, 128, 89, + 69, 83, 73, 69, 85, 78, 71, 45, 72, 73, 69, 85, 72, 128, 89, 69, 83, 73, + 69, 85, 78, 71, 128, 89, 69, 82, 85, 128, 89, 69, 82, 213, 89, 69, 82, + 73, 128, 89, 69, 82, 65, 200, 89, 69, 82, 128, 89, 69, 79, 82, 73, 78, + 72, 73, 69, 85, 72, 128, 89, 69, 79, 45, 89, 65, 128, 89, 69, 79, 45, 85, + 128, 89, 69, 79, 45, 79, 128, 89, 69, 78, 73, 83, 69, 201, 89, 69, 78, + 65, 80, 128, 89, 69, 78, 128, 89, 69, 206, 89, 69, 76, 76, 79, 87, 128, + 89, 69, 76, 76, 79, 215, 89, 69, 73, 78, 128, 89, 69, 72, 128, 89, 69, + 69, 71, 128, 89, 69, 69, 128, 89, 69, 65, 210, 89, 69, 65, 128, 89, 65, + 90, 90, 128, 89, 65, 90, 72, 128, 89, 65, 90, 128, 89, 65, 89, 68, 128, + 89, 65, 89, 65, 78, 78, 65, 128, 89, 65, 89, 128, 89, 65, 87, 128, 89, + 65, 86, 128, 89, 65, 85, 128, 89, 65, 84, 84, 128, 89, 65, 84, 73, 128, + 89, 65, 84, 72, 128, 89, 65, 84, 128, 89, 65, 83, 83, 128, 89, 65, 83, + 72, 128, 89, 65, 83, 128, 89, 65, 82, 82, 128, 89, 65, 82, 128, 89, 65, + 210, 89, 65, 81, 128, 89, 65, 80, 128, 89, 65, 78, 83, 65, 89, 65, 128, + 89, 65, 78, 71, 128, 89, 65, 78, 199, 89, 65, 78, 128, 89, 65, 77, 79, + 75, 128, 89, 65, 77, 65, 75, 75, 65, 78, 128, 89, 65, 77, 128, 89, 65, + 76, 128, 89, 65, 75, 72, 72, 128, 89, 65, 75, 72, 128, 89, 65, 75, 65, + 83, 72, 128, 89, 65, 75, 128, 89, 65, 74, 85, 82, 86, 69, 68, 73, 195, + 89, 65, 74, 128, 89, 65, 73, 128, 89, 65, 72, 72, 128, 89, 65, 72, 128, + 89, 65, 71, 78, 128, 89, 65, 71, 72, 72, 128, 89, 65, 71, 72, 128, 89, + 65, 71, 128, 89, 65, 70, 213, 89, 65, 70, 128, 89, 65, 69, 77, 77, 65, + 69, 128, 89, 65, 68, 72, 128, 89, 65, 68, 68, 72, 128, 89, 65, 68, 68, + 128, 89, 65, 68, 128, 89, 65, 67, 72, 128, 89, 65, 66, 72, 128, 89, 65, + 66, 128, 89, 65, 65, 82, 85, 128, 89, 65, 65, 73, 128, 89, 65, 65, 68, + 79, 128, 89, 65, 45, 89, 79, 128, 89, 65, 45, 85, 128, 89, 65, 45, 79, + 128, 89, 48, 48, 56, 128, 89, 48, 48, 55, 128, 89, 48, 48, 54, 128, 89, + 48, 48, 53, 128, 89, 48, 48, 52, 128, 89, 48, 48, 51, 128, 89, 48, 48, + 50, 128, 89, 48, 48, 49, 65, 128, 89, 48, 48, 49, 128, 89, 45, 67, 82, + 69, 197, 88, 89, 88, 128, 88, 89, 85, 128, 88, 89, 84, 128, 88, 89, 82, + 88, 128, 88, 89, 82, 128, 88, 89, 80, 128, 88, 89, 79, 79, 74, 128, 88, + 89, 79, 79, 128, 88, 89, 79, 128, 88, 89, 73, 128, 88, 89, 69, 69, 205, + 88, 89, 69, 69, 128, 88, 89, 69, 128, 88, 89, 65, 65, 128, 88, 89, 65, + 128, 88, 89, 128, 88, 87, 73, 128, 88, 87, 69, 69, 128, 88, 87, 69, 128, + 88, 87, 65, 65, 128, 88, 87, 65, 128, 88, 87, 128, 88, 86, 69, 128, 88, + 86, 65, 128, 88, 85, 79, 88, 128, 88, 85, 79, 128, 88, 85, 128, 88, 83, + 72, 65, 65, 89, 65, 84, 72, 73, 89, 65, 128, 88, 79, 88, 128, 88, 79, 84, + 128, 88, 79, 82, 128, 88, 79, 80, 72, 128, 88, 79, 80, 128, 88, 79, 65, + 128, 88, 79, 128, 88, 73, 88, 128, 88, 73, 84, 128, 88, 73, 82, 79, 206, + 88, 73, 80, 128, 88, 73, 69, 88, 128, 88, 73, 69, 84, 128, 88, 73, 69, + 80, 128, 88, 73, 69, 128, 88, 73, 65, 66, 128, 88, 73, 128, 88, 71, 128, + 88, 69, 89, 78, 128, 88, 69, 83, 84, 69, 211, 88, 69, 72, 128, 88, 69, + 69, 128, 88, 69, 128, 88, 65, 85, 83, 128, 88, 65, 85, 128, 88, 65, 80, + 72, 128, 88, 65, 78, 128, 88, 65, 65, 128, 88, 65, 128, 88, 48, 48, 56, + 65, 128, 88, 48, 48, 56, 128, 88, 48, 48, 55, 128, 88, 48, 48, 54, 65, + 128, 88, 48, 48, 54, 128, 88, 48, 48, 53, 128, 88, 48, 48, 52, 66, 128, + 88, 48, 48, 52, 65, 128, 88, 48, 48, 52, 128, 88, 48, 48, 51, 128, 88, + 48, 48, 50, 128, 88, 48, 48, 49, 128, 88, 45, 216, 87, 90, 128, 87, 89, + 78, 78, 128, 87, 89, 78, 206, 87, 86, 73, 128, 87, 86, 69, 128, 87, 86, + 65, 128, 87, 86, 128, 87, 85, 80, 128, 87, 85, 79, 88, 128, 87, 85, 79, + 80, 128, 87, 85, 79, 128, 87, 85, 78, 74, 207, 87, 85, 78, 128, 87, 85, + 76, 85, 128, 87, 85, 76, 213, 87, 85, 73, 128, 87, 85, 69, 128, 87, 85, + 65, 69, 84, 128, 87, 85, 65, 69, 78, 128, 87, 85, 128, 87, 82, 217, 87, + 82, 79, 78, 71, 128, 87, 82, 73, 84, 73, 78, 199, 87, 82, 69, 78, 67, 72, + 128, 87, 82, 69, 65, 84, 200, 87, 82, 65, 80, 80, 69, 196, 87, 82, 65, + 80, 128, 87, 79, 88, 128, 87, 79, 87, 128, 87, 79, 82, 82, 73, 69, 196, + 87, 79, 82, 76, 196, 87, 79, 82, 75, 69, 82, 128, 87, 79, 82, 75, 128, + 87, 79, 82, 203, 87, 79, 82, 68, 83, 80, 65, 67, 69, 128, 87, 79, 82, + 196, 87, 79, 80, 128, 87, 79, 79, 78, 128, 87, 79, 79, 76, 128, 87, 79, + 79, 68, 83, 45, 67, 82, 69, 197, 87, 79, 79, 68, 128, 87, 79, 78, 128, + 87, 79, 206, 87, 79, 77, 69, 78, 211, 87, 79, 77, 69, 206, 87, 79, 77, + 65, 78, 211, 87, 79, 77, 65, 78, 128, 87, 79, 77, 65, 206, 87, 79, 76, + 79, 83, 79, 128, 87, 79, 76, 198, 87, 79, 69, 128, 87, 79, 65, 128, 87, + 73, 84, 72, 79, 85, 212, 87, 73, 84, 72, 73, 78, 128, 87, 73, 84, 72, 73, + 206, 87, 73, 82, 69, 196, 87, 73, 78, 84, 69, 82, 128, 87, 73, 78, 75, + 73, 78, 199, 87, 73, 78, 74, 65, 128, 87, 73, 78, 71, 83, 128, 87, 73, + 78, 69, 128, 87, 73, 78, 197, 87, 73, 78, 68, 85, 128, 87, 73, 78, 68, + 79, 87, 128, 87, 73, 78, 68, 128, 87, 73, 78, 196, 87, 73, 78, 128, 87, 73, 71, 78, 89, 65, 78, 128, 87, 73, 71, 71, 76, 217, 87, 73, 68, 69, 45, 72, 69, 65, 68, 69, 196, 87, 73, 68, 197, 87, 73, 65, 78, 71, 87, 65, 65, 75, 128, 87, 73, 65, 78, 71, 128, 87, 72, 79, 76, 197, 87, 72, 73, 84, 69, 45, 70, 69, 65, 84, 72, 69, 82, 69, 196, 87, 72, 73, 84, 69, 128, 87, 72, 69, 69, 76, 69, 196, 87, 72, 69, 69, 76, 67, 72, 65, 73, 210, 87, 72, 69, 69, 76, 128, 87, 72, 69, 69, 204, 87, 72, 69, 65, 84, 128, 87, 72, - 65, 76, 69, 128, 87, 71, 128, 87, 69, 88, 128, 87, 69, 85, 88, 128, 87, - 69, 83, 84, 69, 82, 206, 87, 69, 83, 84, 128, 87, 69, 83, 212, 87, 69, - 80, 128, 87, 69, 79, 128, 87, 69, 78, 128, 87, 69, 76, 76, 128, 87, 69, - 73, 71, 72, 212, 87, 69, 73, 69, 82, 83, 84, 82, 65, 83, 211, 87, 69, 69, - 78, 128, 87, 69, 68, 71, 69, 45, 84, 65, 73, 76, 69, 196, 87, 69, 68, 68, - 73, 78, 71, 128, 87, 69, 65, 82, 217, 87, 69, 65, 80, 79, 78, 128, 87, - 67, 128, 87, 66, 128, 87, 65, 89, 128, 87, 65, 217, 87, 65, 88, 73, 78, - 199, 87, 65, 88, 128, 87, 65, 87, 45, 65, 89, 73, 78, 45, 82, 69, 83, 72, - 128, 87, 65, 87, 128, 87, 65, 215, 87, 65, 86, 217, 87, 65, 86, 73, 78, - 199, 87, 65, 86, 69, 83, 128, 87, 65, 86, 69, 128, 87, 65, 86, 197, 87, - 65, 85, 128, 87, 65, 84, 84, 79, 128, 87, 65, 84, 69, 82, 77, 69, 76, 79, - 78, 128, 87, 65, 84, 69, 82, 128, 87, 65, 84, 69, 210, 87, 65, 84, 67, - 72, 128, 87, 65, 84, 128, 87, 65, 83, 84, 73, 78, 71, 128, 87, 65, 83, - 83, 65, 76, 76, 65, 77, 128, 87, 65, 83, 76, 65, 128, 87, 65, 83, 76, - 193, 87, 65, 83, 65, 76, 76, 65, 77, 128, 87, 65, 83, 65, 76, 76, 65, - 205, 87, 65, 82, 78, 73, 78, 199, 87, 65, 80, 128, 87, 65, 78, 73, 78, - 199, 87, 65, 78, 71, 75, 85, 79, 81, 128, 87, 65, 78, 68, 69, 82, 69, 82, - 128, 87, 65, 78, 128, 87, 65, 76, 76, 128, 87, 65, 76, 75, 128, 87, 65, - 76, 203, 87, 65, 73, 84, 73, 78, 71, 128, 87, 65, 73, 128, 87, 65, 69, - 78, 128, 87, 65, 69, 128, 87, 65, 65, 86, 85, 128, 87, 48, 50, 53, 128, - 87, 48, 50, 52, 65, 128, 87, 48, 50, 52, 128, 87, 48, 50, 51, 128, 87, - 48, 50, 50, 128, 87, 48, 50, 49, 128, 87, 48, 50, 48, 128, 87, 48, 49, - 57, 128, 87, 48, 49, 56, 65, 128, 87, 48, 49, 56, 128, 87, 48, 49, 55, - 65, 128, 87, 48, 49, 55, 128, 87, 48, 49, 54, 128, 87, 48, 49, 53, 128, - 87, 48, 49, 52, 65, 128, 87, 48, 49, 52, 128, 87, 48, 49, 51, 128, 87, - 48, 49, 50, 128, 87, 48, 49, 49, 128, 87, 48, 49, 48, 65, 128, 87, 48, - 49, 48, 128, 87, 48, 48, 57, 65, 128, 87, 48, 48, 57, 128, 87, 48, 48, - 56, 128, 87, 48, 48, 55, 128, 87, 48, 48, 54, 128, 87, 48, 48, 53, 128, - 87, 48, 48, 52, 128, 87, 48, 48, 51, 65, 128, 87, 48, 48, 51, 128, 87, - 48, 48, 50, 128, 87, 48, 48, 49, 128, 86, 90, 77, 69, 84, 128, 86, 89, - 88, 128, 86, 89, 84, 128, 86, 89, 82, 88, 128, 86, 89, 82, 128, 86, 89, - 80, 128, 86, 89, 128, 86, 87, 65, 128, 86, 85, 88, 128, 86, 85, 85, 128, + 65, 76, 69, 128, 87, 72, 128, 87, 71, 128, 87, 69, 88, 128, 87, 69, 85, + 88, 128, 87, 69, 83, 84, 69, 82, 206, 87, 69, 83, 84, 128, 87, 69, 83, + 212, 87, 69, 80, 128, 87, 69, 79, 128, 87, 69, 78, 128, 87, 69, 76, 76, + 128, 87, 69, 73, 71, 72, 212, 87, 69, 73, 69, 82, 83, 84, 82, 65, 83, + 211, 87, 69, 73, 128, 87, 69, 69, 78, 128, 87, 69, 68, 71, 69, 45, 84, + 65, 73, 76, 69, 196, 87, 69, 68, 68, 73, 78, 71, 128, 87, 69, 66, 128, + 87, 69, 65, 82, 217, 87, 69, 65, 80, 79, 78, 128, 87, 67, 128, 87, 66, + 128, 87, 65, 89, 128, 87, 65, 217, 87, 65, 88, 73, 78, 199, 87, 65, 88, + 128, 87, 65, 87, 45, 65, 89, 73, 78, 45, 82, 69, 83, 72, 128, 87, 65, 87, + 128, 87, 65, 215, 87, 65, 86, 217, 87, 65, 86, 73, 78, 199, 87, 65, 86, + 69, 83, 128, 87, 65, 86, 69, 128, 87, 65, 86, 197, 87, 65, 85, 128, 87, + 65, 84, 84, 79, 128, 87, 65, 84, 69, 82, 77, 69, 76, 79, 78, 128, 87, 65, + 84, 69, 82, 128, 87, 65, 84, 69, 210, 87, 65, 84, 67, 72, 128, 87, 65, + 84, 128, 87, 65, 83, 84, 73, 78, 71, 128, 87, 65, 83, 84, 69, 66, 65, 83, + 75, 69, 84, 128, 87, 65, 83, 83, 65, 76, 76, 65, 77, 128, 87, 65, 83, 76, + 65, 128, 87, 65, 83, 76, 193, 87, 65, 83, 65, 76, 76, 65, 77, 128, 87, + 65, 83, 65, 76, 76, 65, 205, 87, 65, 82, 78, 73, 78, 199, 87, 65, 80, + 128, 87, 65, 78, 73, 78, 199, 87, 65, 78, 71, 75, 85, 79, 81, 128, 87, + 65, 78, 68, 69, 82, 69, 82, 128, 87, 65, 78, 128, 87, 65, 76, 76, 128, + 87, 65, 76, 75, 128, 87, 65, 76, 203, 87, 65, 73, 84, 73, 78, 71, 128, + 87, 65, 73, 128, 87, 65, 69, 78, 128, 87, 65, 69, 128, 87, 65, 68, 68, + 65, 128, 87, 65, 65, 86, 85, 128, 87, 48, 50, 53, 128, 87, 48, 50, 52, + 65, 128, 87, 48, 50, 52, 128, 87, 48, 50, 51, 128, 87, 48, 50, 50, 128, + 87, 48, 50, 49, 128, 87, 48, 50, 48, 128, 87, 48, 49, 57, 128, 87, 48, + 49, 56, 65, 128, 87, 48, 49, 56, 128, 87, 48, 49, 55, 65, 128, 87, 48, + 49, 55, 128, 87, 48, 49, 54, 128, 87, 48, 49, 53, 128, 87, 48, 49, 52, + 65, 128, 87, 48, 49, 52, 128, 87, 48, 49, 51, 128, 87, 48, 49, 50, 128, + 87, 48, 49, 49, 128, 87, 48, 49, 48, 65, 128, 87, 48, 49, 48, 128, 87, + 48, 48, 57, 65, 128, 87, 48, 48, 57, 128, 87, 48, 48, 56, 128, 87, 48, + 48, 55, 128, 87, 48, 48, 54, 128, 87, 48, 48, 53, 128, 87, 48, 48, 52, + 128, 87, 48, 48, 51, 65, 128, 87, 48, 48, 51, 128, 87, 48, 48, 50, 128, + 87, 48, 48, 49, 128, 86, 90, 77, 69, 84, 128, 86, 89, 88, 128, 86, 89, + 84, 128, 86, 89, 82, 88, 128, 86, 89, 82, 128, 86, 89, 80, 128, 86, 89, + 128, 86, 87, 74, 128, 86, 87, 65, 128, 86, 85, 88, 128, 86, 85, 85, 128, 86, 85, 84, 128, 86, 85, 82, 88, 128, 86, 85, 82, 128, 86, 85, 80, 128, 86, 85, 76, 71, 65, 210, 86, 85, 69, 81, 128, 86, 84, 83, 128, 86, 84, 128, 86, 83, 57, 57, 128, 86, 83, 57, 56, 128, 86, 83, 57, 55, 128, 86, @@ -347,232 +357,250 @@ static unsigned char lexicon[] = { 48, 49, 128, 86, 83, 49, 48, 48, 128, 86, 83, 49, 48, 128, 86, 83, 49, 128, 86, 83, 128, 86, 82, 65, 67, 72, 89, 128, 86, 79, 88, 128, 86, 79, 87, 69, 76, 45, 67, 65, 82, 82, 73, 69, 210, 86, 79, 87, 128, 86, 79, 85, - 128, 86, 79, 84, 128, 86, 79, 80, 128, 86, 79, 79, 128, 86, 79, 77, 128, - 86, 79, 76, 85, 77, 197, 86, 79, 76, 84, 65, 71, 197, 86, 79, 76, 67, 65, - 78, 79, 128, 86, 79, 73, 196, 86, 79, 73, 67, 73, 78, 71, 128, 86, 79, - 73, 67, 69, 76, 69, 83, 211, 86, 79, 73, 67, 69, 196, 86, 79, 67, 65, 76, - 73, 90, 65, 84, 73, 79, 206, 86, 79, 67, 65, 204, 86, 79, 128, 86, 73, - 88, 128, 86, 73, 84, 82, 73, 79, 76, 45, 50, 128, 86, 73, 84, 82, 73, 79, - 76, 128, 86, 73, 84, 65, 69, 45, 50, 128, 86, 73, 84, 65, 69, 128, 86, - 73, 84, 128, 86, 73, 83, 73, 71, 79, 84, 72, 73, 195, 86, 73, 83, 65, 82, - 71, 65, 89, 65, 128, 86, 73, 83, 65, 82, 71, 65, 128, 86, 73, 83, 65, 82, - 71, 193, 86, 73, 82, 73, 65, 77, 128, 86, 73, 82, 71, 79, 128, 86, 73, - 82, 71, 65, 128, 86, 73, 82, 65, 77, 65, 128, 86, 73, 80, 128, 86, 73, - 79, 76, 73, 78, 128, 86, 73, 78, 69, 71, 65, 82, 45, 51, 128, 86, 73, 78, - 69, 71, 65, 82, 45, 50, 128, 86, 73, 78, 69, 71, 65, 82, 128, 86, 73, 78, - 69, 71, 65, 210, 86, 73, 78, 69, 128, 86, 73, 78, 128, 86, 73, 76, 76, - 65, 71, 69, 128, 86, 73, 73, 128, 86, 73, 69, 88, 128, 86, 73, 69, 87, - 73, 78, 199, 86, 73, 69, 87, 68, 65, 84, 193, 86, 73, 69, 84, 128, 86, - 73, 69, 80, 128, 86, 73, 69, 128, 86, 73, 68, 74, 45, 50, 128, 86, 73, - 68, 74, 128, 86, 73, 68, 69, 79, 67, 65, 83, 83, 69, 84, 84, 69, 128, 86, - 73, 68, 69, 207, 86, 73, 68, 65, 128, 86, 73, 67, 84, 79, 82, 217, 86, - 73, 66, 82, 65, 84, 73, 79, 206, 86, 73, 128, 86, 70, 65, 128, 86, 69, - 88, 128, 86, 69, 87, 128, 86, 69, 215, 86, 69, 85, 88, 128, 86, 69, 85, - 77, 128, 86, 69, 85, 65, 69, 80, 69, 78, 128, 86, 69, 85, 65, 69, 128, - 86, 69, 83, 84, 65, 128, 86, 69, 83, 83, 69, 204, 86, 69, 82, 217, 86, - 69, 82, 84, 73, 67, 65, 76, 76, 89, 128, 86, 69, 82, 84, 73, 67, 65, 76, - 76, 217, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 54, 45, 48, 54, 128, 86, - 69, 82, 84, 73, 67, 65, 76, 45, 48, 54, 45, 48, 53, 128, 86, 69, 82, 84, - 73, 67, 65, 76, 45, 48, 54, 45, 48, 52, 128, 86, 69, 82, 84, 73, 67, 65, - 76, 45, 48, 54, 45, 48, 51, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, - 54, 45, 48, 50, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 54, 45, 48, - 49, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 54, 45, 48, 48, 128, 86, - 69, 82, 84, 73, 67, 65, 76, 45, 48, 53, 45, 48, 54, 128, 86, 69, 82, 84, - 73, 67, 65, 76, 45, 48, 53, 45, 48, 53, 128, 86, 69, 82, 84, 73, 67, 65, - 76, 45, 48, 53, 45, 48, 52, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, - 53, 45, 48, 51, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 53, 45, 48, - 50, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 53, 45, 48, 49, 128, 86, - 69, 82, 84, 73, 67, 65, 76, 45, 48, 53, 45, 48, 48, 128, 86, 69, 82, 84, - 73, 67, 65, 76, 45, 48, 52, 45, 48, 54, 128, 86, 69, 82, 84, 73, 67, 65, - 76, 45, 48, 52, 45, 48, 53, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, - 52, 45, 48, 52, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 52, 45, 48, - 51, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 52, 45, 48, 50, 128, 86, - 69, 82, 84, 73, 67, 65, 76, 45, 48, 52, 45, 48, 49, 128, 86, 69, 82, 84, - 73, 67, 65, 76, 45, 48, 52, 45, 48, 48, 128, 86, 69, 82, 84, 73, 67, 65, - 76, 45, 48, 51, 45, 48, 54, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, - 51, 45, 48, 53, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 51, 45, 48, - 52, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 51, 45, 48, 51, 128, 86, - 69, 82, 84, 73, 67, 65, 76, 45, 48, 51, 45, 48, 50, 128, 86, 69, 82, 84, - 73, 67, 65, 76, 45, 48, 51, 45, 48, 49, 128, 86, 69, 82, 84, 73, 67, 65, - 76, 45, 48, 51, 45, 48, 48, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, - 50, 45, 48, 54, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 50, 45, 48, - 53, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 50, 45, 48, 52, 128, 86, - 69, 82, 84, 73, 67, 65, 76, 45, 48, 50, 45, 48, 51, 128, 86, 69, 82, 84, - 73, 67, 65, 76, 45, 48, 50, 45, 48, 50, 128, 86, 69, 82, 84, 73, 67, 65, - 76, 45, 48, 50, 45, 48, 49, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, - 50, 45, 48, 48, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 49, 45, 48, - 54, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 49, 45, 48, 53, 128, 86, - 69, 82, 84, 73, 67, 65, 76, 45, 48, 49, 45, 48, 52, 128, 86, 69, 82, 84, - 73, 67, 65, 76, 45, 48, 49, 45, 48, 51, 128, 86, 69, 82, 84, 73, 67, 65, - 76, 45, 48, 49, 45, 48, 50, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, - 49, 45, 48, 49, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 49, 45, 48, - 48, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 48, 45, 48, 54, 128, 86, - 69, 82, 84, 73, 67, 65, 76, 45, 48, 48, 45, 48, 53, 128, 86, 69, 82, 84, - 73, 67, 65, 76, 45, 48, 48, 45, 48, 52, 128, 86, 69, 82, 84, 73, 67, 65, - 76, 45, 48, 48, 45, 48, 51, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, - 48, 45, 48, 50, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 48, 45, 48, - 49, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 48, 45, 48, 48, 128, 86, - 69, 82, 84, 73, 67, 65, 76, 128, 86, 69, 82, 83, 73, 67, 76, 69, 128, 86, - 69, 82, 83, 197, 86, 69, 82, 71, 69, 128, 86, 69, 82, 68, 73, 71, 82, 73, - 83, 128, 86, 69, 80, 128, 86, 69, 78, 68, 128, 86, 69, 73, 76, 128, 86, + 128, 86, 79, 84, 128, 86, 79, 211, 86, 79, 80, 128, 86, 79, 79, 73, 128, + 86, 79, 79, 128, 86, 79, 77, 128, 86, 79, 76, 85, 77, 197, 86, 79, 76, + 84, 65, 71, 197, 86, 79, 76, 67, 65, 78, 79, 128, 86, 79, 76, 65, 80, 85, + 203, 86, 79, 73, 196, 86, 79, 73, 67, 73, 78, 71, 128, 86, 79, 73, 67, + 69, 76, 69, 83, 211, 86, 79, 73, 67, 69, 196, 86, 79, 67, 65, 76, 73, 90, + 65, 84, 73, 79, 206, 86, 79, 67, 65, 204, 86, 79, 128, 86, 73, 89, 79, + 128, 86, 73, 88, 128, 86, 73, 84, 82, 73, 79, 76, 45, 50, 128, 86, 73, + 84, 82, 73, 79, 76, 128, 86, 73, 84, 65, 69, 45, 50, 128, 86, 73, 84, 65, + 69, 128, 86, 73, 84, 128, 86, 73, 83, 73, 71, 79, 84, 72, 73, 195, 86, + 73, 83, 65, 82, 71, 65, 89, 65, 128, 86, 73, 83, 65, 82, 71, 65, 128, 86, + 73, 83, 65, 82, 71, 193, 86, 73, 82, 73, 65, 77, 128, 86, 73, 82, 71, 79, + 128, 86, 73, 82, 71, 65, 128, 86, 73, 82, 65, 77, 65, 128, 86, 73, 80, + 128, 86, 73, 79, 76, 73, 78, 128, 86, 73, 78, 69, 71, 65, 82, 45, 51, + 128, 86, 73, 78, 69, 71, 65, 82, 45, 50, 128, 86, 73, 78, 69, 71, 65, 82, + 128, 86, 73, 78, 69, 71, 65, 210, 86, 73, 78, 69, 128, 86, 73, 78, 197, + 86, 73, 78, 128, 86, 73, 76, 76, 65, 71, 69, 128, 86, 73, 73, 128, 86, + 73, 69, 88, 128, 86, 73, 69, 87, 73, 78, 199, 86, 73, 69, 87, 68, 65, 84, + 193, 86, 73, 69, 84, 128, 86, 73, 69, 212, 86, 73, 69, 80, 128, 86, 73, + 69, 128, 86, 73, 68, 74, 45, 50, 128, 86, 73, 68, 74, 128, 86, 73, 68, + 69, 79, 67, 65, 83, 83, 69, 84, 84, 69, 128, 86, 73, 68, 69, 207, 86, 73, + 68, 65, 128, 86, 73, 67, 84, 79, 82, 217, 86, 73, 66, 82, 65, 84, 73, 79, + 206, 86, 70, 65, 128, 86, 69, 89, 90, 128, 86, 69, 88, 128, 86, 69, 87, + 128, 86, 69, 215, 86, 69, 85, 88, 128, 86, 69, 85, 77, 128, 86, 69, 85, + 65, 69, 80, 69, 78, 128, 86, 69, 85, 65, 69, 128, 86, 69, 83, 84, 65, + 128, 86, 69, 83, 83, 69, 204, 86, 69, 82, 217, 86, 69, 82, 84, 73, 67, + 65, 76, 76, 89, 128, 86, 69, 82, 84, 73, 67, 65, 76, 76, 217, 86, 69, 82, + 84, 73, 67, 65, 76, 45, 48, 54, 45, 48, 54, 128, 86, 69, 82, 84, 73, 67, + 65, 76, 45, 48, 54, 45, 48, 53, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, + 48, 54, 45, 48, 52, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 54, 45, + 48, 51, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 54, 45, 48, 50, 128, + 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 54, 45, 48, 49, 128, 86, 69, 82, + 84, 73, 67, 65, 76, 45, 48, 54, 45, 48, 48, 128, 86, 69, 82, 84, 73, 67, + 65, 76, 45, 48, 53, 45, 48, 54, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, + 48, 53, 45, 48, 53, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 53, 45, + 48, 52, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 53, 45, 48, 51, 128, + 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 53, 45, 48, 50, 128, 86, 69, 82, + 84, 73, 67, 65, 76, 45, 48, 53, 45, 48, 49, 128, 86, 69, 82, 84, 73, 67, + 65, 76, 45, 48, 53, 45, 48, 48, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, + 48, 52, 45, 48, 54, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 52, 45, + 48, 53, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 52, 45, 48, 52, 128, + 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 52, 45, 48, 51, 128, 86, 69, 82, + 84, 73, 67, 65, 76, 45, 48, 52, 45, 48, 50, 128, 86, 69, 82, 84, 73, 67, + 65, 76, 45, 48, 52, 45, 48, 49, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, + 48, 52, 45, 48, 48, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 51, 45, + 48, 54, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 51, 45, 48, 53, 128, + 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 51, 45, 48, 52, 128, 86, 69, 82, + 84, 73, 67, 65, 76, 45, 48, 51, 45, 48, 51, 128, 86, 69, 82, 84, 73, 67, + 65, 76, 45, 48, 51, 45, 48, 50, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, + 48, 51, 45, 48, 49, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 51, 45, + 48, 48, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 50, 45, 48, 54, 128, + 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 50, 45, 48, 53, 128, 86, 69, 82, + 84, 73, 67, 65, 76, 45, 48, 50, 45, 48, 52, 128, 86, 69, 82, 84, 73, 67, + 65, 76, 45, 48, 50, 45, 48, 51, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, + 48, 50, 45, 48, 50, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 50, 45, + 48, 49, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 50, 45, 48, 48, 128, + 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 49, 45, 48, 54, 128, 86, 69, 82, + 84, 73, 67, 65, 76, 45, 48, 49, 45, 48, 53, 128, 86, 69, 82, 84, 73, 67, + 65, 76, 45, 48, 49, 45, 48, 52, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, + 48, 49, 45, 48, 51, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 49, 45, + 48, 50, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 49, 45, 48, 49, 128, + 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 49, 45, 48, 48, 128, 86, 69, 82, + 84, 73, 67, 65, 76, 45, 48, 48, 45, 48, 54, 128, 86, 69, 82, 84, 73, 67, + 65, 76, 45, 48, 48, 45, 48, 53, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, + 48, 48, 45, 48, 52, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 48, 45, + 48, 51, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 48, 45, 48, 50, 128, + 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 48, 45, 48, 49, 128, 86, 69, 82, + 84, 73, 67, 65, 76, 45, 48, 48, 45, 48, 48, 128, 86, 69, 82, 84, 73, 67, + 65, 76, 128, 86, 69, 82, 83, 73, 67, 76, 69, 128, 86, 69, 82, 83, 197, + 86, 69, 82, 71, 69, 128, 86, 69, 82, 68, 73, 71, 82, 73, 83, 128, 86, 69, + 82, 128, 86, 69, 80, 128, 86, 69, 78, 68, 128, 86, 69, 73, 76, 128, 86, 69, 72, 73, 67, 76, 69, 128, 86, 69, 72, 128, 86, 69, 200, 86, 69, 69, 128, 86, 69, 197, 86, 69, 68, 69, 128, 86, 69, 67, 84, 79, 210, 86, 65, 89, 65, 78, 78, 65, 128, 86, 65, 88, 128, 86, 65, 86, 128, 86, 65, 214, 86, 65, 85, 128, 86, 65, 84, 72, 89, 128, 86, 65, 84, 128, 86, 65, 83, 84, 78, 69, 83, 211, 86, 65, 83, 73, 83, 128, 86, 65, 82, 89, 211, 86, - 65, 82, 73, 75, 65, 128, 86, 65, 82, 73, 65, 78, 212, 86, 65, 82, 73, 65, - 128, 86, 65, 82, 73, 193, 86, 65, 82, 69, 73, 65, 201, 86, 65, 82, 69, - 73, 193, 86, 65, 80, 79, 85, 82, 83, 128, 86, 65, 80, 128, 86, 65, 78, - 69, 128, 86, 65, 77, 65, 71, 79, 77, 85, 75, 72, 65, 128, 86, 65, 77, 65, - 71, 79, 77, 85, 75, 72, 193, 86, 65, 76, 76, 69, 89, 128, 86, 65, 73, - 128, 86, 65, 72, 128, 86, 65, 65, 86, 85, 128, 86, 65, 65, 128, 86, 48, - 52, 48, 65, 128, 86, 48, 52, 48, 128, 86, 48, 51, 57, 128, 86, 48, 51, - 56, 128, 86, 48, 51, 55, 65, 128, 86, 48, 51, 55, 128, 86, 48, 51, 54, - 128, 86, 48, 51, 53, 128, 86, 48, 51, 52, 128, 86, 48, 51, 51, 65, 128, - 86, 48, 51, 51, 128, 86, 48, 51, 50, 128, 86, 48, 51, 49, 65, 128, 86, - 48, 51, 49, 128, 86, 48, 51, 48, 65, 128, 86, 48, 51, 48, 128, 86, 48, - 50, 57, 65, 128, 86, 48, 50, 57, 128, 86, 48, 50, 56, 65, 128, 86, 48, - 50, 56, 128, 86, 48, 50, 55, 128, 86, 48, 50, 54, 128, 86, 48, 50, 53, - 128, 86, 48, 50, 52, 128, 86, 48, 50, 51, 65, 128, 86, 48, 50, 51, 128, - 86, 48, 50, 50, 128, 86, 48, 50, 49, 128, 86, 48, 50, 48, 76, 128, 86, - 48, 50, 48, 75, 128, 86, 48, 50, 48, 74, 128, 86, 48, 50, 48, 73, 128, - 86, 48, 50, 48, 72, 128, 86, 48, 50, 48, 71, 128, 86, 48, 50, 48, 70, - 128, 86, 48, 50, 48, 69, 128, 86, 48, 50, 48, 68, 128, 86, 48, 50, 48, - 67, 128, 86, 48, 50, 48, 66, 128, 86, 48, 50, 48, 65, 128, 86, 48, 50, - 48, 128, 86, 48, 49, 57, 128, 86, 48, 49, 56, 128, 86, 48, 49, 55, 128, - 86, 48, 49, 54, 128, 86, 48, 49, 53, 128, 86, 48, 49, 52, 128, 86, 48, - 49, 51, 128, 86, 48, 49, 50, 66, 128, 86, 48, 49, 50, 65, 128, 86, 48, - 49, 50, 128, 86, 48, 49, 49, 67, 128, 86, 48, 49, 49, 66, 128, 86, 48, - 49, 49, 65, 128, 86, 48, 49, 49, 128, 86, 48, 49, 48, 128, 86, 48, 48, - 57, 128, 86, 48, 48, 56, 128, 86, 48, 48, 55, 66, 128, 86, 48, 48, 55, - 65, 128, 86, 48, 48, 55, 128, 86, 48, 48, 54, 128, 86, 48, 48, 53, 128, - 86, 48, 48, 52, 128, 86, 48, 48, 51, 128, 86, 48, 48, 50, 65, 128, 86, - 48, 48, 50, 128, 86, 48, 48, 49, 73, 128, 86, 48, 48, 49, 72, 128, 86, - 48, 48, 49, 71, 128, 86, 48, 48, 49, 70, 128, 86, 48, 48, 49, 69, 128, - 86, 48, 48, 49, 68, 128, 86, 48, 48, 49, 67, 128, 86, 48, 48, 49, 66, - 128, 86, 48, 48, 49, 65, 128, 86, 48, 48, 49, 128, 85, 90, 85, 128, 85, - 90, 51, 128, 85, 90, 179, 85, 89, 65, 78, 78, 65, 128, 85, 89, 128, 85, - 85, 89, 65, 78, 78, 65, 128, 85, 85, 85, 85, 128, 85, 85, 85, 51, 128, - 85, 85, 85, 50, 128, 85, 85, 69, 128, 85, 84, 85, 75, 73, 128, 85, 83, - 83, 85, 51, 128, 85, 83, 83, 85, 128, 85, 83, 72, 88, 128, 85, 83, 72, - 85, 77, 88, 128, 85, 83, 72, 69, 78, 78, 65, 128, 85, 83, 72, 50, 128, - 85, 83, 72, 128, 85, 83, 200, 85, 83, 69, 196, 85, 83, 69, 45, 50, 128, - 85, 83, 69, 45, 49, 128, 85, 83, 69, 128, 85, 83, 197, 85, 82, 85, 218, - 85, 82, 85, 83, 128, 85, 82, 85, 68, 65, 128, 85, 82, 85, 68, 193, 85, - 82, 85, 128, 85, 82, 213, 85, 82, 78, 128, 85, 82, 73, 78, 69, 128, 85, - 82, 73, 51, 128, 85, 82, 73, 128, 85, 82, 65, 78, 85, 83, 128, 85, 82, - 65, 128, 85, 82, 52, 128, 85, 82, 50, 128, 85, 82, 178, 85, 80, 87, 65, - 82, 68, 83, 128, 85, 80, 87, 65, 82, 68, 211, 85, 80, 87, 65, 82, 68, - 128, 85, 80, 87, 65, 82, 196, 85, 80, 84, 85, 82, 78, 128, 85, 80, 83, - 73, 76, 79, 78, 128, 85, 80, 83, 73, 76, 79, 206, 85, 80, 82, 73, 71, 72, - 212, 85, 80, 80, 69, 210, 85, 80, 65, 68, 72, 77, 65, 78, 73, 89, 65, - 128, 85, 80, 45, 80, 79, 73, 78, 84, 73, 78, 199, 85, 79, 78, 128, 85, - 78, 78, 128, 85, 78, 77, 65, 82, 82, 73, 69, 196, 85, 78, 75, 78, 79, 87, - 78, 128, 85, 78, 73, 86, 69, 82, 83, 65, 204, 85, 78, 73, 84, 89, 128, - 85, 78, 73, 84, 128, 85, 78, 73, 212, 85, 78, 73, 79, 78, 128, 85, 78, - 73, 79, 206, 85, 78, 73, 70, 73, 69, 196, 85, 78, 68, 207, 85, 78, 68, - 69, 82, 84, 73, 69, 128, 85, 78, 68, 69, 82, 76, 73, 78, 197, 85, 78, 68, - 69, 82, 68, 79, 84, 128, 85, 78, 68, 69, 82, 66, 65, 82, 128, 85, 78, 68, - 69, 210, 85, 78, 67, 73, 193, 85, 78, 65, 83, 80, 73, 82, 65, 84, 69, 68, - 128, 85, 78, 65, 80, 128, 85, 78, 65, 77, 85, 83, 69, 196, 85, 78, 65, - 128, 85, 206, 85, 77, 85, 77, 128, 85, 77, 85, 205, 85, 77, 66, 82, 69, - 76, 76, 65, 128, 85, 77, 66, 82, 69, 76, 76, 193, 85, 77, 66, 73, 78, - 128, 85, 75, 85, 128, 85, 75, 82, 65, 73, 78, 73, 65, 206, 85, 75, 65, - 82, 65, 128, 85, 75, 65, 82, 193, 85, 75, 128, 85, 73, 76, 76, 69, 65, - 78, 78, 128, 85, 73, 71, 72, 85, 210, 85, 71, 65, 82, 73, 84, 73, 195, - 85, 69, 89, 128, 85, 69, 73, 128, 85, 69, 69, 128, 85, 69, 65, 128, 85, - 68, 85, 71, 128, 85, 68, 65, 84, 84, 65, 128, 85, 68, 65, 84, 84, 193, - 85, 68, 65, 65, 84, 128, 85, 68, 128, 85, 196, 85, 67, 128, 85, 66, 85, - 70, 73, 76, 73, 128, 85, 66, 72, 65, 89, 65, 84, 207, 85, 66, 65, 68, 65, - 77, 65, 128, 85, 66, 128, 85, 65, 84, 72, 128, 85, 65, 78, 71, 128, 85, - 65, 128, 85, 178, 85, 48, 52, 50, 128, 85, 48, 52, 49, 128, 85, 48, 52, - 48, 128, 85, 48, 51, 57, 128, 85, 48, 51, 56, 128, 85, 48, 51, 55, 128, - 85, 48, 51, 54, 128, 85, 48, 51, 53, 128, 85, 48, 51, 52, 128, 85, 48, - 51, 51, 128, 85, 48, 51, 50, 65, 128, 85, 48, 51, 50, 128, 85, 48, 51, - 49, 128, 85, 48, 51, 48, 128, 85, 48, 50, 57, 65, 128, 85, 48, 50, 57, - 128, 85, 48, 50, 56, 128, 85, 48, 50, 55, 128, 85, 48, 50, 54, 128, 85, - 48, 50, 53, 128, 85, 48, 50, 52, 128, 85, 48, 50, 51, 65, 128, 85, 48, - 50, 51, 128, 85, 48, 50, 50, 128, 85, 48, 50, 49, 128, 85, 48, 50, 48, - 128, 85, 48, 49, 57, 128, 85, 48, 49, 56, 128, 85, 48, 49, 55, 128, 85, - 48, 49, 54, 128, 85, 48, 49, 53, 128, 85, 48, 49, 52, 128, 85, 48, 49, - 51, 128, 85, 48, 49, 50, 128, 85, 48, 49, 49, 128, 85, 48, 49, 48, 128, - 85, 48, 48, 57, 128, 85, 48, 48, 56, 128, 85, 48, 48, 55, 128, 85, 48, - 48, 54, 66, 128, 85, 48, 48, 54, 65, 128, 85, 48, 48, 54, 128, 85, 48, - 48, 53, 128, 85, 48, 48, 52, 128, 85, 48, 48, 51, 128, 85, 48, 48, 50, - 128, 85, 48, 48, 49, 128, 85, 45, 73, 45, 73, 128, 85, 45, 69, 79, 45, - 69, 85, 128, 85, 45, 66, 82, 74, 71, 85, 128, 84, 90, 85, 128, 84, 90, - 79, 65, 128, 84, 90, 79, 128, 84, 90, 73, 210, 84, 90, 73, 128, 84, 90, - 69, 69, 128, 84, 90, 69, 128, 84, 90, 65, 65, 128, 84, 90, 65, 128, 84, - 90, 128, 84, 89, 210, 84, 89, 80, 69, 45, 183, 84, 89, 80, 69, 45, 182, - 84, 89, 80, 69, 45, 181, 84, 89, 80, 69, 45, 180, 84, 89, 80, 69, 45, - 179, 84, 89, 80, 69, 45, 178, 84, 89, 80, 69, 45, 177, 84, 89, 80, 197, - 84, 89, 79, 128, 84, 89, 73, 128, 84, 89, 69, 128, 84, 89, 65, 128, 84, - 87, 79, 79, 128, 84, 87, 79, 45, 87, 65, 217, 84, 87, 79, 45, 84, 72, 73, - 82, 84, 89, 128, 84, 87, 79, 45, 76, 73, 78, 197, 84, 87, 79, 45, 72, 69, - 65, 68, 69, 196, 84, 87, 79, 45, 69, 205, 84, 87, 73, 83, 84, 69, 196, - 84, 87, 73, 73, 128, 84, 87, 73, 128, 84, 87, 69, 78, 84, 89, 45, 84, 87, - 79, 128, 84, 87, 69, 78, 84, 89, 45, 84, 72, 82, 69, 69, 128, 84, 87, 69, - 78, 84, 89, 45, 83, 73, 88, 128, 84, 87, 69, 78, 84, 89, 45, 83, 69, 86, - 69, 78, 128, 84, 87, 69, 78, 84, 89, 45, 79, 78, 69, 128, 84, 87, 69, 78, - 84, 89, 45, 78, 73, 78, 69, 128, 84, 87, 69, 78, 84, 89, 45, 70, 79, 85, - 82, 128, 84, 87, 69, 78, 84, 89, 45, 70, 73, 86, 69, 128, 84, 87, 69, 78, - 84, 89, 45, 69, 73, 71, 72, 84, 200, 84, 87, 69, 78, 84, 89, 45, 69, 73, - 71, 72, 84, 128, 84, 87, 69, 78, 84, 89, 128, 84, 87, 69, 78, 84, 217, - 84, 87, 69, 76, 86, 69, 45, 84, 72, 73, 82, 84, 89, 128, 84, 87, 69, 76, - 86, 69, 128, 84, 87, 69, 76, 86, 197, 84, 87, 69, 128, 84, 87, 65, 65, - 128, 84, 87, 65, 128, 84, 86, 82, 73, 68, 79, 128, 84, 86, 73, 77, 65, - 68, 85, 210, 84, 85, 88, 128, 84, 85, 85, 77, 85, 128, 84, 85, 85, 128, - 84, 85, 84, 84, 89, 128, 84, 85, 84, 69, 89, 65, 83, 65, 84, 128, 84, 85, - 84, 128, 84, 85, 82, 88, 128, 84, 85, 82, 85, 128, 84, 85, 82, 84, 76, - 69, 128, 84, 85, 82, 79, 50, 128, 84, 85, 82, 78, 83, 84, 73, 76, 69, - 128, 84, 85, 82, 78, 69, 196, 84, 85, 82, 206, 84, 85, 82, 75, 73, 83, - 200, 84, 85, 82, 66, 65, 78, 128, 84, 85, 82, 128, 84, 85, 80, 128, 84, - 85, 79, 88, 128, 84, 85, 79, 84, 128, 84, 85, 79, 80, 128, 84, 85, 79, - 128, 84, 85, 78, 78, 89, 128, 84, 85, 77, 69, 84, 69, 83, 128, 84, 85, - 77, 65, 69, 128, 84, 85, 77, 128, 84, 85, 76, 73, 80, 128, 84, 85, 75, - 87, 69, 78, 84, 73, 83, 128, 84, 85, 75, 128, 84, 85, 71, 82, 73, 203, - 84, 85, 71, 50, 128, 84, 85, 71, 178, 84, 85, 65, 82, 69, 199, 84, 85, - 65, 69, 80, 128, 84, 85, 65, 69, 128, 84, 213, 84, 84, 85, 85, 128, 84, - 84, 85, 68, 68, 65, 71, 128, 84, 84, 85, 68, 68, 65, 65, 71, 128, 84, 84, - 85, 128, 84, 84, 84, 72, 65, 128, 84, 84, 84, 65, 128, 84, 84, 83, 85, - 128, 84, 84, 83, 79, 128, 84, 84, 83, 73, 128, 84, 84, 83, 69, 69, 128, - 84, 84, 83, 69, 128, 84, 84, 83, 65, 128, 84, 84, 79, 79, 128, 84, 84, - 73, 73, 128, 84, 84, 73, 128, 84, 84, 72, 87, 69, 128, 84, 84, 72, 85, - 128, 84, 84, 72, 79, 79, 128, 84, 84, 72, 79, 128, 84, 84, 72, 73, 128, - 84, 84, 72, 69, 69, 128, 84, 84, 72, 69, 128, 84, 84, 72, 65, 65, 128, - 84, 84, 72, 128, 84, 84, 69, 72, 69, 72, 128, 84, 84, 69, 72, 69, 200, - 84, 84, 69, 72, 128, 84, 84, 69, 200, 84, 84, 69, 69, 128, 84, 84, 65, - 89, 65, 78, 78, 65, 128, 84, 84, 65, 85, 128, 84, 84, 65, 73, 128, 84, - 84, 65, 65, 128, 84, 84, 50, 128, 84, 83, 87, 69, 128, 84, 83, 87, 65, - 128, 84, 83, 86, 128, 84, 83, 83, 69, 128, 84, 83, 83, 65, 128, 84, 83, - 72, 85, 71, 83, 128, 84, 83, 72, 79, 79, 75, 128, 84, 83, 72, 79, 79, - 203, 84, 83, 72, 69, 83, 128, 84, 83, 72, 69, 71, 128, 84, 83, 72, 69, - 199, 84, 83, 72, 69, 128, 84, 83, 72, 65, 128, 84, 83, 69, 82, 69, 128, - 84, 83, 65, 68, 73, 128, 84, 83, 65, 68, 201, 84, 83, 65, 65, 68, 73, 89, - 128, 84, 83, 65, 65, 128, 84, 83, 193, 84, 82, 89, 66, 76, 73, 79, 206, - 84, 82, 85, 84, 72, 128, 84, 82, 85, 78, 75, 128, 84, 82, 85, 78, 67, 65, - 84, 69, 196, 84, 82, 85, 77, 80, 69, 84, 128, 84, 82, 85, 69, 128, 84, - 82, 85, 67, 75, 128, 84, 82, 79, 80, 73, 67, 65, 204, 84, 82, 79, 80, 72, - 89, 128, 84, 82, 79, 77, 73, 75, 79, 83, 89, 78, 65, 71, 77, 65, 128, 84, - 82, 79, 77, 73, 75, 79, 80, 83, 73, 70, 73, 83, 84, 79, 78, 128, 84, 82, - 79, 77, 73, 75, 79, 80, 65, 82, 65, 75, 65, 76, 69, 83, 77, 65, 128, 84, - 82, 79, 77, 73, 75, 79, 78, 128, 84, 82, 79, 77, 73, 75, 79, 206, 84, 82, - 79, 77, 73, 75, 79, 76, 89, 71, 73, 83, 77, 65, 128, 84, 82, 79, 76, 76, - 69, 89, 66, 85, 83, 128, 84, 82, 79, 75, 85, 84, 65, 83, 84, 201, 84, 82, - 79, 69, 90, 69, 78, 73, 65, 206, 84, 82, 73, 85, 77, 80, 72, 128, 84, 82, - 73, 84, 79, 211, 84, 82, 73, 84, 73, 77, 79, 82, 73, 79, 78, 128, 84, 82, - 73, 83, 73, 77, 79, 85, 128, 84, 82, 73, 83, 69, 77, 69, 128, 84, 82, 73, - 80, 79, 68, 128, 84, 82, 73, 80, 76, 73, 128, 84, 82, 73, 80, 76, 197, - 84, 82, 73, 79, 206, 84, 82, 73, 73, 83, 65, 80, 128, 84, 82, 73, 71, 82, - 65, 77, 77, 79, 211, 84, 82, 73, 71, 82, 65, 205, 84, 82, 73, 71, 79, 82, - 71, 79, 78, 128, 84, 82, 73, 70, 79, 78, 73, 65, 83, 128, 84, 82, 73, 70, - 79, 76, 73, 65, 84, 197, 84, 82, 73, 68, 69, 78, 84, 128, 84, 82, 73, 68, - 69, 78, 212, 84, 82, 73, 67, 79, 76, 79, 78, 128, 84, 82, 73, 65, 78, 71, - 85, 76, 65, 210, 84, 82, 73, 65, 78, 71, 76, 69, 45, 82, 79, 85, 78, 196, - 84, 82, 73, 65, 78, 71, 76, 69, 45, 72, 69, 65, 68, 69, 196, 84, 82, 73, - 65, 78, 71, 76, 69, 128, 84, 82, 73, 65, 78, 71, 76, 197, 84, 82, 73, 65, - 128, 84, 82, 73, 128, 84, 82, 69, 83, 73, 76, 76, 79, 128, 84, 82, 69, - 78, 68, 128, 84, 82, 69, 78, 196, 84, 82, 69, 77, 79, 76, 79, 45, 51, + 65, 82, 73, 75, 65, 128, 86, 65, 82, 73, 65, 78, 84, 128, 86, 65, 82, 73, + 65, 78, 212, 86, 65, 82, 73, 65, 128, 86, 65, 82, 73, 193, 86, 65, 82, + 69, 73, 65, 201, 86, 65, 82, 69, 73, 193, 86, 65, 80, 79, 85, 82, 83, + 128, 86, 65, 80, 128, 86, 65, 78, 69, 128, 86, 65, 77, 65, 71, 79, 77, + 85, 75, 72, 65, 128, 86, 65, 77, 65, 71, 79, 77, 85, 75, 72, 193, 86, 65, + 76, 76, 69, 89, 128, 86, 65, 74, 128, 86, 65, 73, 128, 86, 65, 72, 128, + 86, 65, 200, 86, 65, 65, 86, 85, 128, 86, 65, 65, 128, 86, 48, 52, 48, + 65, 128, 86, 48, 52, 48, 128, 86, 48, 51, 57, 128, 86, 48, 51, 56, 128, + 86, 48, 51, 55, 65, 128, 86, 48, 51, 55, 128, 86, 48, 51, 54, 128, 86, + 48, 51, 53, 128, 86, 48, 51, 52, 128, 86, 48, 51, 51, 65, 128, 86, 48, + 51, 51, 128, 86, 48, 51, 50, 128, 86, 48, 51, 49, 65, 128, 86, 48, 51, + 49, 128, 86, 48, 51, 48, 65, 128, 86, 48, 51, 48, 128, 86, 48, 50, 57, + 65, 128, 86, 48, 50, 57, 128, 86, 48, 50, 56, 65, 128, 86, 48, 50, 56, + 128, 86, 48, 50, 55, 128, 86, 48, 50, 54, 128, 86, 48, 50, 53, 128, 86, + 48, 50, 52, 128, 86, 48, 50, 51, 65, 128, 86, 48, 50, 51, 128, 86, 48, + 50, 50, 128, 86, 48, 50, 49, 128, 86, 48, 50, 48, 76, 128, 86, 48, 50, + 48, 75, 128, 86, 48, 50, 48, 74, 128, 86, 48, 50, 48, 73, 128, 86, 48, + 50, 48, 72, 128, 86, 48, 50, 48, 71, 128, 86, 48, 50, 48, 70, 128, 86, + 48, 50, 48, 69, 128, 86, 48, 50, 48, 68, 128, 86, 48, 50, 48, 67, 128, + 86, 48, 50, 48, 66, 128, 86, 48, 50, 48, 65, 128, 86, 48, 50, 48, 128, + 86, 48, 49, 57, 128, 86, 48, 49, 56, 128, 86, 48, 49, 55, 128, 86, 48, + 49, 54, 128, 86, 48, 49, 53, 128, 86, 48, 49, 52, 128, 86, 48, 49, 51, + 128, 86, 48, 49, 50, 66, 128, 86, 48, 49, 50, 65, 128, 86, 48, 49, 50, + 128, 86, 48, 49, 49, 67, 128, 86, 48, 49, 49, 66, 128, 86, 48, 49, 49, + 65, 128, 86, 48, 49, 49, 128, 86, 48, 49, 48, 128, 86, 48, 48, 57, 128, + 86, 48, 48, 56, 128, 86, 48, 48, 55, 66, 128, 86, 48, 48, 55, 65, 128, + 86, 48, 48, 55, 128, 86, 48, 48, 54, 128, 86, 48, 48, 53, 128, 86, 48, + 48, 52, 128, 86, 48, 48, 51, 128, 86, 48, 48, 50, 65, 128, 86, 48, 48, + 50, 128, 86, 48, 48, 49, 73, 128, 86, 48, 48, 49, 72, 128, 86, 48, 48, + 49, 71, 128, 86, 48, 48, 49, 70, 128, 86, 48, 48, 49, 69, 128, 86, 48, + 48, 49, 68, 128, 86, 48, 48, 49, 67, 128, 86, 48, 48, 49, 66, 128, 86, + 48, 48, 49, 65, 128, 86, 48, 48, 49, 128, 85, 90, 85, 128, 85, 90, 51, + 128, 85, 90, 179, 85, 89, 65, 78, 78, 65, 128, 85, 89, 128, 85, 87, 85, + 128, 85, 85, 89, 65, 78, 78, 65, 128, 85, 85, 85, 85, 128, 85, 85, 85, + 51, 128, 85, 85, 85, 50, 128, 85, 85, 69, 128, 85, 84, 85, 75, 73, 128, + 85, 83, 83, 85, 51, 128, 85, 83, 83, 85, 128, 85, 83, 72, 88, 128, 85, + 83, 72, 85, 77, 88, 128, 85, 83, 72, 69, 78, 78, 65, 128, 85, 83, 72, 50, + 128, 85, 83, 72, 128, 85, 83, 200, 85, 83, 69, 196, 85, 83, 69, 45, 50, + 128, 85, 83, 69, 45, 49, 128, 85, 83, 69, 128, 85, 83, 197, 85, 82, 85, + 218, 85, 82, 85, 83, 128, 85, 82, 85, 68, 65, 128, 85, 82, 85, 68, 193, + 85, 82, 85, 128, 85, 82, 213, 85, 82, 78, 128, 85, 82, 73, 78, 69, 128, + 85, 82, 73, 51, 128, 85, 82, 73, 128, 85, 82, 65, 78, 85, 83, 128, 85, + 82, 65, 128, 85, 82, 52, 128, 85, 82, 50, 128, 85, 82, 178, 85, 80, 87, + 65, 82, 68, 83, 128, 85, 80, 87, 65, 82, 68, 128, 85, 80, 87, 65, 82, + 196, 85, 80, 84, 85, 82, 78, 128, 85, 80, 83, 73, 76, 79, 78, 128, 85, + 80, 83, 73, 76, 79, 206, 85, 80, 82, 73, 71, 72, 212, 85, 80, 80, 69, + 210, 85, 80, 65, 68, 72, 77, 65, 78, 73, 89, 65, 128, 85, 80, 45, 80, 79, + 73, 78, 84, 73, 78, 199, 85, 79, 78, 128, 85, 78, 78, 128, 85, 78, 77, + 65, 82, 82, 73, 69, 196, 85, 78, 75, 78, 79, 87, 78, 128, 85, 78, 73, 86, + 69, 82, 83, 65, 204, 85, 78, 73, 84, 89, 128, 85, 78, 73, 84, 128, 85, + 78, 73, 212, 85, 78, 73, 79, 78, 128, 85, 78, 73, 79, 206, 85, 78, 73, + 70, 73, 69, 196, 85, 78, 68, 207, 85, 78, 68, 69, 82, 84, 73, 69, 128, + 85, 78, 68, 69, 82, 76, 73, 78, 197, 85, 78, 68, 69, 82, 68, 79, 84, 128, + 85, 78, 68, 69, 82, 66, 65, 82, 128, 85, 78, 68, 69, 210, 85, 78, 67, 73, + 193, 85, 78, 67, 69, 82, 84, 65, 73, 78, 84, 217, 85, 78, 65, 83, 80, 73, + 82, 65, 84, 69, 68, 128, 85, 78, 65, 80, 128, 85, 78, 65, 77, 85, 83, 69, + 196, 85, 78, 65, 128, 85, 206, 85, 77, 85, 77, 128, 85, 77, 85, 205, 85, + 77, 66, 82, 69, 76, 76, 65, 128, 85, 77, 66, 82, 69, 76, 76, 193, 85, 77, + 66, 73, 78, 128, 85, 75, 85, 128, 85, 75, 82, 65, 73, 78, 73, 65, 206, + 85, 75, 65, 82, 65, 128, 85, 75, 65, 82, 193, 85, 75, 128, 85, 73, 76, + 76, 69, 65, 78, 78, 128, 85, 73, 71, 72, 85, 210, 85, 71, 65, 82, 73, 84, + 73, 195, 85, 69, 89, 128, 85, 69, 73, 128, 85, 69, 69, 128, 85, 69, 65, + 128, 85, 68, 85, 71, 128, 85, 68, 65, 84, 84, 65, 128, 85, 68, 65, 84, + 84, 193, 85, 68, 65, 65, 84, 128, 85, 68, 128, 85, 196, 85, 67, 128, 85, + 66, 85, 70, 73, 76, 73, 128, 85, 66, 72, 65, 89, 65, 84, 207, 85, 66, 65, + 68, 65, 77, 65, 128, 85, 66, 128, 85, 65, 84, 72, 128, 85, 65, 78, 71, + 128, 85, 65, 128, 85, 178, 85, 48, 52, 50, 128, 85, 48, 52, 49, 128, 85, + 48, 52, 48, 128, 85, 48, 51, 57, 128, 85, 48, 51, 56, 128, 85, 48, 51, + 55, 128, 85, 48, 51, 54, 128, 85, 48, 51, 53, 128, 85, 48, 51, 52, 128, + 85, 48, 51, 51, 128, 85, 48, 51, 50, 65, 128, 85, 48, 51, 50, 128, 85, + 48, 51, 49, 128, 85, 48, 51, 48, 128, 85, 48, 50, 57, 65, 128, 85, 48, + 50, 57, 128, 85, 48, 50, 56, 128, 85, 48, 50, 55, 128, 85, 48, 50, 54, + 128, 85, 48, 50, 53, 128, 85, 48, 50, 52, 128, 85, 48, 50, 51, 65, 128, + 85, 48, 50, 51, 128, 85, 48, 50, 50, 128, 85, 48, 50, 49, 128, 85, 48, + 50, 48, 128, 85, 48, 49, 57, 128, 85, 48, 49, 56, 128, 85, 48, 49, 55, + 128, 85, 48, 49, 54, 128, 85, 48, 49, 53, 128, 85, 48, 49, 52, 128, 85, + 48, 49, 51, 128, 85, 48, 49, 50, 128, 85, 48, 49, 49, 128, 85, 48, 49, + 48, 128, 85, 48, 48, 57, 128, 85, 48, 48, 56, 128, 85, 48, 48, 55, 128, + 85, 48, 48, 54, 66, 128, 85, 48, 48, 54, 65, 128, 85, 48, 48, 54, 128, + 85, 48, 48, 53, 128, 85, 48, 48, 52, 128, 85, 48, 48, 51, 128, 85, 48, + 48, 50, 128, 85, 48, 48, 49, 128, 85, 45, 83, 72, 65, 80, 69, 196, 85, + 45, 73, 45, 73, 128, 85, 45, 69, 79, 45, 69, 85, 128, 85, 45, 66, 82, 74, + 71, 85, 128, 84, 90, 85, 128, 84, 90, 79, 65, 128, 84, 90, 79, 128, 84, + 90, 73, 210, 84, 90, 73, 128, 84, 90, 69, 69, 128, 84, 90, 69, 128, 84, + 90, 65, 65, 128, 84, 90, 65, 128, 84, 90, 128, 84, 89, 210, 84, 89, 80, + 69, 45, 183, 84, 89, 80, 69, 45, 182, 84, 89, 80, 69, 45, 181, 84, 89, + 80, 69, 45, 180, 84, 89, 80, 69, 45, 179, 84, 89, 80, 69, 45, 178, 84, + 89, 80, 69, 45, 177, 84, 89, 80, 197, 84, 89, 79, 128, 84, 89, 73, 128, + 84, 89, 69, 128, 84, 89, 65, 89, 128, 84, 89, 65, 128, 84, 88, 87, 86, + 128, 84, 88, 87, 214, 84, 88, 72, 69, 69, 202, 84, 87, 79, 79, 128, 84, + 87, 79, 45, 87, 65, 217, 84, 87, 79, 45, 84, 72, 73, 82, 84, 89, 128, 84, + 87, 79, 45, 76, 73, 78, 197, 84, 87, 79, 45, 72, 69, 65, 68, 69, 196, 84, + 87, 79, 45, 69, 205, 84, 87, 73, 83, 84, 69, 196, 84, 87, 73, 73, 128, + 84, 87, 73, 128, 84, 87, 69, 78, 84, 89, 45, 84, 87, 79, 128, 84, 87, 69, + 78, 84, 89, 45, 84, 72, 82, 69, 69, 128, 84, 87, 69, 78, 84, 89, 45, 83, + 73, 88, 128, 84, 87, 69, 78, 84, 89, 45, 83, 69, 86, 69, 78, 128, 84, 87, + 69, 78, 84, 89, 45, 79, 78, 69, 128, 84, 87, 69, 78, 84, 89, 45, 78, 73, + 78, 69, 128, 84, 87, 69, 78, 84, 89, 45, 70, 79, 85, 82, 128, 84, 87, 69, + 78, 84, 89, 45, 70, 73, 86, 69, 128, 84, 87, 69, 78, 84, 89, 45, 69, 73, + 71, 72, 84, 200, 84, 87, 69, 78, 84, 89, 45, 69, 73, 71, 72, 84, 128, 84, + 87, 69, 78, 84, 89, 128, 84, 87, 69, 78, 84, 217, 84, 87, 69, 76, 86, 69, + 45, 84, 72, 73, 82, 84, 89, 128, 84, 87, 69, 76, 86, 69, 128, 84, 87, 69, + 76, 86, 197, 84, 87, 69, 128, 84, 87, 65, 65, 128, 84, 87, 65, 128, 84, + 86, 82, 73, 68, 79, 128, 84, 86, 73, 77, 65, 68, 85, 210, 84, 85, 88, + 128, 84, 85, 85, 77, 85, 128, 84, 85, 85, 128, 84, 85, 84, 84, 89, 128, + 84, 85, 84, 69, 89, 65, 83, 65, 84, 128, 84, 85, 84, 128, 84, 85, 82, 88, + 128, 84, 85, 82, 85, 128, 84, 85, 82, 84, 76, 69, 128, 84, 85, 82, 79, + 50, 128, 84, 85, 82, 78, 83, 84, 73, 76, 69, 128, 84, 85, 82, 206, 84, + 85, 82, 75, 73, 83, 200, 84, 85, 82, 75, 73, 195, 84, 85, 82, 66, 65, 78, + 128, 84, 85, 82, 128, 84, 85, 80, 128, 84, 85, 79, 88, 128, 84, 85, 79, + 84, 128, 84, 85, 79, 80, 128, 84, 85, 79, 128, 84, 85, 78, 78, 89, 128, + 84, 85, 77, 69, 84, 69, 83, 128, 84, 85, 77, 65, 69, 128, 84, 85, 77, + 128, 84, 85, 76, 73, 80, 128, 84, 85, 75, 87, 69, 78, 84, 73, 83, 128, + 84, 85, 75, 128, 84, 85, 71, 82, 73, 203, 84, 85, 71, 50, 128, 84, 85, + 71, 178, 84, 85, 66, 128, 84, 85, 65, 82, 69, 199, 84, 85, 65, 69, 80, + 128, 84, 85, 65, 69, 128, 84, 213, 84, 84, 85, 85, 128, 84, 84, 85, 68, + 68, 65, 71, 128, 84, 84, 85, 68, 68, 65, 65, 71, 128, 84, 84, 85, 128, + 84, 84, 84, 72, 65, 128, 84, 84, 84, 65, 128, 84, 84, 83, 85, 128, 84, + 84, 83, 79, 128, 84, 84, 83, 73, 128, 84, 84, 83, 69, 69, 128, 84, 84, + 83, 69, 128, 84, 84, 83, 65, 128, 84, 84, 79, 79, 128, 84, 84, 73, 73, + 128, 84, 84, 73, 128, 84, 84, 72, 87, 69, 128, 84, 84, 72, 85, 128, 84, + 84, 72, 79, 79, 128, 84, 84, 72, 79, 128, 84, 84, 72, 73, 128, 84, 84, + 72, 69, 69, 128, 84, 84, 72, 69, 128, 84, 84, 72, 65, 65, 128, 84, 84, + 72, 128, 84, 84, 69, 72, 69, 72, 128, 84, 84, 69, 72, 69, 200, 84, 84, + 69, 72, 128, 84, 84, 69, 200, 84, 84, 69, 69, 128, 84, 84, 65, 89, 65, + 78, 78, 65, 128, 84, 84, 65, 85, 128, 84, 84, 65, 73, 128, 84, 84, 65, + 65, 128, 84, 84, 50, 128, 84, 83, 87, 69, 128, 84, 83, 87, 66, 128, 84, + 83, 87, 65, 128, 84, 83, 86, 128, 84, 83, 83, 69, 128, 84, 83, 83, 65, + 128, 84, 83, 79, 214, 84, 83, 73, 85, 128, 84, 83, 72, 85, 71, 83, 128, + 84, 83, 72, 79, 79, 75, 128, 84, 83, 72, 79, 79, 203, 84, 83, 72, 79, 79, + 74, 128, 84, 83, 72, 69, 83, 128, 84, 83, 72, 69, 71, 128, 84, 83, 72, + 69, 199, 84, 83, 72, 69, 69, 74, 128, 84, 83, 72, 69, 128, 84, 83, 72, + 65, 194, 84, 83, 72, 65, 128, 84, 83, 69, 82, 69, 128, 84, 83, 69, 69, + 66, 128, 84, 83, 65, 68, 73, 128, 84, 83, 65, 68, 201, 84, 83, 65, 66, + 128, 84, 83, 65, 65, 68, 73, 89, 128, 84, 83, 65, 65, 128, 84, 83, 193, + 84, 82, 89, 66, 76, 73, 79, 206, 84, 82, 85, 84, 72, 128, 84, 82, 85, 78, + 75, 128, 84, 82, 85, 78, 67, 65, 84, 69, 196, 84, 82, 85, 77, 80, 69, 84, + 128, 84, 82, 85, 77, 80, 45, 57, 128, 84, 82, 85, 77, 80, 45, 56, 128, + 84, 82, 85, 77, 80, 45, 55, 128, 84, 82, 85, 77, 80, 45, 54, 128, 84, 82, + 85, 77, 80, 45, 53, 128, 84, 82, 85, 77, 80, 45, 52, 128, 84, 82, 85, 77, + 80, 45, 51, 128, 84, 82, 85, 77, 80, 45, 50, 49, 128, 84, 82, 85, 77, 80, + 45, 50, 48, 128, 84, 82, 85, 77, 80, 45, 50, 128, 84, 82, 85, 77, 80, 45, + 49, 57, 128, 84, 82, 85, 77, 80, 45, 49, 56, 128, 84, 82, 85, 77, 80, 45, + 49, 55, 128, 84, 82, 85, 77, 80, 45, 49, 54, 128, 84, 82, 85, 77, 80, 45, + 49, 53, 128, 84, 82, 85, 77, 80, 45, 49, 52, 128, 84, 82, 85, 77, 80, 45, + 49, 51, 128, 84, 82, 85, 77, 80, 45, 49, 50, 128, 84, 82, 85, 77, 80, 45, + 49, 49, 128, 84, 82, 85, 77, 80, 45, 49, 48, 128, 84, 82, 85, 77, 80, 45, + 49, 128, 84, 82, 85, 69, 128, 84, 82, 85, 67, 75, 128, 84, 82, 79, 80, + 73, 67, 65, 204, 84, 82, 79, 80, 72, 89, 128, 84, 82, 79, 77, 73, 75, 79, + 83, 89, 78, 65, 71, 77, 65, 128, 84, 82, 79, 77, 73, 75, 79, 80, 83, 73, + 70, 73, 83, 84, 79, 78, 128, 84, 82, 79, 77, 73, 75, 79, 80, 65, 82, 65, + 75, 65, 76, 69, 83, 77, 65, 128, 84, 82, 79, 77, 73, 75, 79, 78, 128, 84, + 82, 79, 77, 73, 75, 79, 206, 84, 82, 79, 77, 73, 75, 79, 76, 89, 71, 73, + 83, 77, 65, 128, 84, 82, 79, 76, 76, 69, 89, 66, 85, 83, 128, 84, 82, 79, + 75, 85, 84, 65, 83, 84, 201, 84, 82, 79, 69, 90, 69, 78, 73, 65, 206, 84, + 82, 73, 85, 77, 80, 72, 128, 84, 82, 73, 84, 79, 211, 84, 82, 73, 84, 73, + 77, 79, 82, 73, 79, 78, 128, 84, 82, 73, 83, 73, 77, 79, 85, 128, 84, 82, + 73, 83, 69, 77, 69, 128, 84, 82, 73, 80, 79, 68, 128, 84, 82, 73, 80, 76, + 73, 128, 84, 82, 73, 80, 76, 197, 84, 82, 73, 79, 206, 84, 82, 73, 76, + 76, 73, 79, 78, 83, 128, 84, 82, 73, 73, 83, 65, 80, 128, 84, 82, 73, 71, + 82, 65, 77, 77, 79, 211, 84, 82, 73, 71, 82, 65, 205, 84, 82, 73, 71, 79, + 82, 71, 79, 78, 128, 84, 82, 73, 70, 79, 78, 73, 65, 83, 128, 84, 82, 73, + 70, 79, 76, 73, 65, 84, 197, 84, 82, 73, 68, 69, 78, 84, 128, 84, 82, 73, + 68, 69, 78, 212, 84, 82, 73, 67, 79, 76, 79, 78, 128, 84, 82, 73, 65, 78, + 71, 85, 76, 65, 210, 84, 82, 73, 65, 78, 71, 76, 69, 45, 82, 79, 85, 78, + 196, 84, 82, 73, 65, 78, 71, 76, 69, 45, 72, 69, 65, 68, 69, 196, 84, 82, + 73, 65, 78, 71, 76, 69, 128, 84, 82, 73, 65, 78, 71, 76, 197, 84, 82, 73, + 65, 128, 84, 82, 73, 128, 84, 82, 69, 83, 73, 76, 76, 79, 128, 84, 82, + 69, 78, 68, 128, 84, 82, 69, 78, 196, 84, 82, 69, 77, 79, 76, 79, 45, 51, 128, 84, 82, 69, 77, 79, 76, 79, 45, 50, 128, 84, 82, 69, 77, 79, 76, 79, 45, 49, 128, 84, 82, 69, 69, 128, 84, 82, 69, 197, 84, 82, 69, 65, 68, 73, 78, 71, 128, 84, 82, 65, 89, 128, 84, 82, 65, 80, 69, 90, 73, 85, 77, @@ -583,1414 +611,1483 @@ static unsigned char lexicon[] = { 84, 82, 65, 205, 84, 82, 65, 73, 78, 128, 84, 82, 65, 73, 206, 84, 82, 65, 73, 76, 73, 78, 199, 84, 82, 65, 70, 70, 73, 67, 128, 84, 82, 65, 70, 70, 73, 195, 84, 82, 65, 68, 197, 84, 82, 65, 67, 84, 79, 82, 128, 84, - 82, 65, 67, 75, 128, 84, 82, 128, 84, 79, 88, 128, 84, 79, 87, 69, 82, - 128, 84, 79, 85, 82, 78, 79, 73, 211, 84, 79, 84, 65, 204, 84, 79, 84, - 128, 84, 79, 82, 84, 79, 73, 83, 197, 84, 79, 82, 67, 85, 76, 85, 83, - 128, 84, 79, 82, 67, 85, 76, 85, 211, 84, 79, 82, 67, 72, 128, 84, 79, - 81, 128, 84, 79, 80, 66, 65, 82, 128, 84, 79, 80, 45, 76, 73, 71, 72, 84, - 69, 196, 84, 79, 80, 128, 84, 79, 208, 84, 79, 79, 84, 72, 128, 84, 79, - 79, 78, 128, 84, 79, 78, 79, 83, 128, 84, 79, 78, 71, 85, 69, 128, 84, - 79, 78, 71, 85, 197, 84, 79, 78, 71, 128, 84, 79, 78, 69, 45, 56, 128, - 84, 79, 78, 69, 45, 55, 128, 84, 79, 78, 69, 45, 54, 128, 84, 79, 78, 69, - 45, 53, 128, 84, 79, 78, 69, 45, 52, 128, 84, 79, 78, 69, 45, 51, 128, - 84, 79, 78, 69, 45, 50, 128, 84, 79, 78, 69, 45, 49, 128, 84, 79, 78, 69, - 128, 84, 79, 78, 65, 204, 84, 79, 77, 80, 73, 128, 84, 79, 77, 65, 84, - 79, 128, 84, 79, 76, 79, 78, 71, 128, 84, 79, 75, 89, 207, 84, 79, 73, - 76, 69, 84, 128, 84, 79, 71, 69, 84, 72, 69, 82, 128, 84, 79, 68, 207, - 84, 79, 65, 78, 68, 65, 75, 72, 73, 65, 84, 128, 84, 79, 65, 128, 84, 78, - 128, 84, 76, 86, 128, 84, 76, 85, 128, 84, 76, 79, 128, 84, 76, 73, 128, - 84, 76, 72, 89, 65, 128, 84, 76, 72, 87, 69, 128, 84, 76, 72, 85, 128, - 84, 76, 72, 79, 79, 128, 84, 76, 72, 79, 128, 84, 76, 72, 73, 128, 84, - 76, 72, 69, 69, 128, 84, 76, 72, 69, 128, 84, 76, 72, 65, 128, 84, 76, - 69, 69, 128, 84, 76, 65, 128, 84, 74, 69, 128, 84, 73, 88, 128, 84, 73, - 87, 78, 128, 84, 73, 87, 65, 218, 84, 73, 84, 85, 65, 69, 80, 128, 84, - 73, 84, 76, 79, 128, 84, 73, 84, 193, 84, 73, 84, 128, 84, 73, 82, 89, - 65, 75, 128, 84, 73, 82, 84, 193, 84, 73, 82, 79, 78, 73, 65, 206, 84, - 73, 82, 69, 196, 84, 73, 82, 128, 84, 73, 210, 84, 73, 80, 80, 73, 128, - 84, 73, 80, 69, 72, 65, 128, 84, 73, 80, 128, 84, 73, 208, 84, 73, 78, - 89, 128, 84, 73, 78, 217, 84, 73, 78, 78, 69, 128, 84, 73, 78, 67, 84, - 85, 82, 69, 128, 84, 73, 78, 65, 71, 77, 65, 128, 84, 73, 77, 69, 83, - 128, 84, 73, 77, 69, 210, 84, 73, 77, 69, 128, 84, 73, 76, 68, 197, 84, - 73, 76, 128, 84, 73, 204, 84, 73, 75, 69, 85, 84, 45, 84, 72, 73, 69, 85, - 84, 72, 128, 84, 73, 75, 69, 85, 84, 45, 83, 73, 79, 83, 45, 75, 73, 89, - 69, 79, 75, 128, 84, 73, 75, 69, 85, 84, 45, 83, 73, 79, 83, 128, 84, 73, - 75, 69, 85, 84, 45, 82, 73, 69, 85, 76, 128, 84, 73, 75, 69, 85, 84, 45, - 80, 73, 69, 85, 80, 128, 84, 73, 75, 69, 85, 84, 45, 77, 73, 69, 85, 77, - 128, 84, 73, 75, 69, 85, 84, 45, 75, 73, 89, 69, 79, 75, 128, 84, 73, 75, - 69, 85, 84, 45, 67, 73, 69, 85, 67, 128, 84, 73, 75, 69, 85, 84, 45, 67, - 72, 73, 69, 85, 67, 72, 128, 84, 73, 75, 69, 85, 84, 128, 84, 73, 75, 69, - 85, 212, 84, 73, 71, 72, 84, 76, 89, 45, 67, 76, 79, 83, 69, 196, 84, 73, - 71, 72, 212, 84, 73, 71, 69, 82, 128, 84, 73, 71, 69, 210, 84, 73, 70, - 73, 78, 65, 71, 200, 84, 73, 69, 88, 128, 84, 73, 69, 80, 128, 84, 73, - 197, 84, 73, 67, 75, 69, 84, 128, 84, 73, 67, 75, 128, 84, 73, 67, 203, - 84, 73, 65, 82, 65, 128, 84, 72, 90, 128, 84, 72, 89, 79, 79, 205, 84, - 72, 87, 79, 79, 128, 84, 72, 87, 79, 128, 84, 72, 87, 73, 73, 128, 84, - 72, 87, 73, 128, 84, 72, 87, 69, 69, 128, 84, 72, 87, 65, 65, 128, 84, - 72, 87, 65, 128, 84, 72, 85, 82, 211, 84, 72, 85, 82, 73, 83, 65, 218, - 84, 72, 85, 78, 71, 128, 84, 72, 85, 78, 68, 69, 82, 83, 84, 79, 82, 77, - 128, 84, 72, 85, 78, 68, 69, 82, 128, 84, 72, 85, 78, 68, 69, 210, 84, - 72, 85, 77, 66, 211, 84, 72, 82, 79, 87, 73, 78, 199, 84, 72, 82, 79, 85, - 71, 72, 128, 84, 72, 82, 79, 85, 71, 200, 84, 72, 82, 69, 69, 45, 84, 72, - 73, 82, 84, 89, 128, 84, 72, 82, 69, 69, 45, 80, 69, 82, 45, 69, 205, 84, - 72, 82, 69, 69, 45, 76, 73, 78, 197, 84, 72, 82, 69, 69, 45, 69, 205, 84, - 72, 82, 69, 69, 45, 196, 84, 72, 82, 69, 65, 68, 128, 84, 72, 79, 85, 83, - 65, 78, 68, 211, 84, 72, 79, 85, 83, 65, 78, 68, 128, 84, 72, 79, 85, 83, - 65, 78, 196, 84, 72, 79, 85, 71, 72, 212, 84, 72, 79, 85, 128, 84, 72, - 79, 82, 78, 128, 84, 72, 79, 82, 206, 84, 72, 79, 78, 71, 128, 84, 72, - 79, 65, 128, 84, 72, 207, 84, 72, 73, 85, 84, 72, 128, 84, 72, 73, 84, - 65, 128, 84, 72, 73, 82, 84, 89, 45, 83, 69, 67, 79, 78, 196, 84, 72, 73, - 82, 84, 89, 45, 79, 78, 69, 128, 84, 72, 73, 82, 84, 217, 84, 72, 73, 82, - 84, 69, 69, 78, 128, 84, 72, 73, 82, 84, 69, 69, 206, 84, 72, 73, 82, 68, - 83, 128, 84, 72, 73, 82, 68, 211, 84, 72, 73, 82, 68, 128, 84, 72, 73, - 82, 196, 84, 72, 73, 206, 84, 72, 73, 73, 128, 84, 72, 73, 71, 72, 128, - 84, 72, 73, 69, 85, 84, 200, 84, 72, 69, 89, 128, 84, 72, 69, 84, 72, 69, - 128, 84, 72, 69, 84, 72, 128, 84, 72, 69, 84, 65, 128, 84, 72, 69, 84, - 193, 84, 72, 69, 83, 80, 73, 65, 206, 84, 72, 69, 83, 69, 79, 83, 128, - 84, 72, 69, 83, 69, 79, 211, 84, 72, 69, 211, 84, 72, 69, 82, 77, 79, 68, - 89, 78, 65, 77, 73, 67, 128, 84, 72, 69, 82, 69, 70, 79, 82, 69, 128, 84, - 72, 69, 82, 197, 84, 72, 69, 206, 84, 72, 69, 77, 65, 84, 73, 83, 77, 79, - 211, 84, 72, 69, 77, 65, 128, 84, 72, 69, 77, 193, 84, 72, 69, 72, 128, - 84, 72, 69, 200, 84, 72, 197, 84, 72, 65, 87, 128, 84, 72, 65, 78, 84, - 72, 65, 75, 72, 65, 84, 128, 84, 72, 65, 78, 78, 65, 128, 84, 72, 65, 78, - 128, 84, 72, 65, 206, 84, 72, 65, 76, 128, 84, 72, 65, 204, 84, 72, 65, - 72, 65, 78, 128, 84, 72, 65, 65, 78, 193, 84, 72, 65, 65, 76, 85, 128, - 84, 72, 45, 67, 82, 69, 197, 84, 69, 88, 84, 128, 84, 69, 88, 128, 84, - 69, 86, 73, 82, 128, 84, 69, 85, 84, 69, 85, 88, 128, 84, 69, 85, 84, 69, - 85, 87, 69, 78, 128, 84, 69, 85, 84, 128, 84, 69, 85, 78, 128, 84, 69, - 85, 65, 69, 81, 128, 84, 69, 85, 65, 69, 78, 128, 84, 69, 85, 128, 84, - 69, 84, 82, 65, 83, 73, 77, 79, 85, 128, 84, 69, 84, 82, 65, 83, 69, 77, - 69, 128, 84, 69, 84, 82, 65, 80, 76, 73, 128, 84, 69, 84, 82, 65, 70, 79, - 78, 73, 65, 83, 128, 84, 69, 84, 72, 128, 84, 69, 84, 200, 84, 69, 84, - 65, 82, 84, 79, 211, 84, 69, 84, 65, 82, 84, 73, 77, 79, 82, 73, 79, 78, - 128, 84, 69, 84, 128, 84, 69, 212, 84, 69, 83, 83, 69, 82, 65, 128, 84, - 69, 83, 83, 69, 82, 193, 84, 69, 83, 83, 65, 82, 79, 206, 84, 69, 83, + 82, 65, 67, 75, 66, 65, 76, 76, 128, 84, 82, 65, 67, 75, 128, 84, 82, 65, + 128, 84, 82, 128, 84, 79, 88, 128, 84, 79, 87, 69, 82, 128, 84, 79, 86, + 128, 84, 79, 85, 82, 78, 79, 73, 211, 84, 79, 85, 67, 72, 84, 79, 78, + 197, 84, 79, 84, 65, 204, 84, 79, 84, 128, 84, 79, 83, 128, 84, 79, 82, + 84, 79, 73, 83, 197, 84, 79, 82, 78, 65, 68, 79, 128, 84, 79, 82, 67, 85, + 76, 85, 83, 128, 84, 79, 82, 67, 85, 76, 85, 211, 84, 79, 82, 67, 72, + 128, 84, 79, 81, 128, 84, 79, 80, 66, 65, 82, 128, 84, 79, 80, 45, 76, + 73, 71, 72, 84, 69, 196, 84, 79, 80, 128, 84, 79, 208, 84, 79, 79, 84, + 72, 128, 84, 79, 79, 78, 128, 84, 79, 78, 79, 83, 128, 84, 79, 78, 71, + 85, 69, 128, 84, 79, 78, 71, 85, 197, 84, 79, 78, 71, 128, 84, 79, 78, + 69, 45, 56, 128, 84, 79, 78, 69, 45, 55, 128, 84, 79, 78, 69, 45, 54, + 128, 84, 79, 78, 69, 45, 53, 128, 84, 79, 78, 69, 45, 52, 128, 84, 79, + 78, 69, 45, 51, 128, 84, 79, 78, 69, 45, 50, 128, 84, 79, 78, 69, 45, 49, + 128, 84, 79, 78, 69, 128, 84, 79, 78, 65, 204, 84, 79, 77, 80, 73, 128, + 84, 79, 77, 65, 84, 79, 128, 84, 79, 76, 79, 78, 71, 128, 84, 79, 75, 89, + 207, 84, 79, 73, 76, 69, 84, 128, 84, 79, 71, 69, 84, 72, 69, 82, 128, + 84, 79, 68, 207, 84, 79, 65, 78, 68, 65, 75, 72, 73, 65, 84, 128, 84, 79, + 65, 128, 84, 78, 128, 84, 76, 86, 128, 84, 76, 85, 128, 84, 76, 79, 128, + 84, 76, 73, 128, 84, 76, 72, 89, 65, 128, 84, 76, 72, 87, 69, 128, 84, + 76, 72, 85, 128, 84, 76, 72, 79, 79, 128, 84, 76, 72, 79, 128, 84, 76, + 72, 73, 128, 84, 76, 72, 69, 69, 128, 84, 76, 72, 69, 128, 84, 76, 72, + 65, 128, 84, 76, 69, 69, 128, 84, 76, 65, 128, 84, 74, 69, 128, 84, 73, + 88, 128, 84, 73, 87, 82, 128, 84, 73, 87, 78, 128, 84, 73, 87, 65, 218, + 84, 73, 84, 85, 65, 69, 80, 128, 84, 73, 84, 76, 79, 128, 84, 73, 84, + 193, 84, 73, 84, 128, 84, 73, 82, 89, 65, 75, 128, 84, 73, 82, 84, 193, + 84, 73, 82, 79, 78, 73, 65, 206, 84, 73, 82, 72, 85, 84, 193, 84, 73, 82, + 69, 196, 84, 73, 82, 128, 84, 73, 210, 84, 73, 80, 80, 73, 128, 84, 73, + 80, 69, 72, 65, 128, 84, 73, 80, 128, 84, 73, 208, 84, 73, 78, 89, 128, + 84, 73, 78, 217, 84, 73, 78, 78, 69, 128, 84, 73, 78, 67, 84, 85, 82, 69, + 128, 84, 73, 78, 65, 71, 77, 65, 128, 84, 73, 77, 69, 83, 128, 84, 73, + 77, 69, 210, 84, 73, 77, 69, 128, 84, 73, 76, 69, 83, 128, 84, 73, 76, + 68, 69, 128, 84, 73, 76, 68, 197, 84, 73, 76, 128, 84, 73, 204, 84, 73, + 75, 69, 85, 84, 45, 84, 72, 73, 69, 85, 84, 72, 128, 84, 73, 75, 69, 85, + 84, 45, 83, 73, 79, 83, 45, 75, 73, 89, 69, 79, 75, 128, 84, 73, 75, 69, + 85, 84, 45, 83, 73, 79, 83, 128, 84, 73, 75, 69, 85, 84, 45, 82, 73, 69, + 85, 76, 128, 84, 73, 75, 69, 85, 84, 45, 80, 73, 69, 85, 80, 128, 84, 73, + 75, 69, 85, 84, 45, 77, 73, 69, 85, 77, 128, 84, 73, 75, 69, 85, 84, 45, + 75, 73, 89, 69, 79, 75, 128, 84, 73, 75, 69, 85, 84, 45, 67, 73, 69, 85, + 67, 128, 84, 73, 75, 69, 85, 84, 45, 67, 72, 73, 69, 85, 67, 72, 128, 84, + 73, 75, 69, 85, 84, 128, 84, 73, 75, 69, 85, 212, 84, 73, 71, 72, 84, 76, + 89, 45, 67, 76, 79, 83, 69, 196, 84, 73, 71, 72, 212, 84, 73, 71, 69, 82, + 128, 84, 73, 71, 69, 210, 84, 73, 70, 73, 78, 65, 71, 200, 84, 73, 69, + 88, 128, 84, 73, 69, 80, 128, 84, 73, 197, 84, 73, 67, 75, 69, 84, 83, + 128, 84, 73, 67, 75, 69, 84, 128, 84, 73, 67, 75, 128, 84, 73, 67, 203, + 84, 73, 65, 82, 65, 128, 84, 73, 50, 128, 84, 72, 90, 128, 84, 72, 89, + 79, 79, 205, 84, 72, 87, 79, 79, 128, 84, 72, 87, 79, 128, 84, 72, 87, + 73, 73, 128, 84, 72, 87, 73, 128, 84, 72, 87, 69, 69, 128, 84, 72, 87, + 65, 65, 128, 84, 72, 87, 65, 128, 84, 72, 85, 82, 211, 84, 72, 85, 82, + 73, 83, 65, 218, 84, 72, 85, 78, 71, 128, 84, 72, 85, 78, 68, 69, 82, 83, + 84, 79, 82, 77, 128, 84, 72, 85, 78, 68, 69, 82, 128, 84, 72, 85, 78, 68, + 69, 210, 84, 72, 85, 77, 66, 211, 84, 72, 82, 79, 87, 73, 78, 199, 84, + 72, 82, 79, 85, 71, 72, 128, 84, 72, 82, 79, 85, 71, 200, 84, 72, 82, 69, + 69, 45, 84, 72, 73, 82, 84, 89, 128, 84, 72, 82, 69, 69, 45, 80, 69, 82, + 45, 69, 205, 84, 72, 82, 69, 69, 45, 76, 73, 78, 197, 84, 72, 82, 69, 69, + 45, 69, 205, 84, 72, 82, 69, 69, 45, 196, 84, 72, 82, 69, 65, 68, 128, + 84, 72, 79, 85, 83, 65, 78, 68, 83, 128, 84, 72, 79, 85, 83, 65, 78, 68, + 211, 84, 72, 79, 85, 83, 65, 78, 68, 128, 84, 72, 79, 85, 83, 65, 78, + 196, 84, 72, 79, 85, 71, 72, 212, 84, 72, 79, 85, 128, 84, 72, 79, 82, + 78, 128, 84, 72, 79, 82, 206, 84, 72, 79, 78, 71, 128, 84, 72, 79, 77, + 128, 84, 72, 79, 74, 128, 84, 72, 79, 65, 128, 84, 72, 207, 84, 72, 73, + 85, 84, 72, 128, 84, 72, 73, 84, 65, 128, 84, 72, 73, 82, 84, 89, 45, 83, + 69, 67, 79, 78, 196, 84, 72, 73, 82, 84, 89, 45, 79, 78, 69, 128, 84, 72, + 73, 82, 84, 217, 84, 72, 73, 82, 84, 69, 69, 78, 128, 84, 72, 73, 82, 84, + 69, 69, 206, 84, 72, 73, 82, 68, 83, 128, 84, 72, 73, 82, 68, 211, 84, + 72, 73, 82, 68, 45, 83, 84, 65, 71, 197, 84, 72, 73, 82, 68, 128, 84, 72, + 73, 82, 196, 84, 72, 73, 73, 128, 84, 72, 73, 71, 72, 128, 84, 72, 73, + 69, 85, 84, 200, 84, 72, 73, 67, 203, 84, 72, 73, 65, 66, 128, 84, 72, + 69, 89, 128, 84, 72, 69, 84, 72, 69, 128, 84, 72, 69, 84, 72, 128, 84, + 72, 69, 84, 65, 128, 84, 72, 69, 84, 193, 84, 72, 69, 83, 80, 73, 65, + 206, 84, 72, 69, 83, 69, 79, 83, 128, 84, 72, 69, 83, 69, 79, 211, 84, + 72, 69, 211, 84, 72, 69, 82, 77, 79, 77, 69, 84, 69, 82, 128, 84, 72, 69, + 82, 77, 79, 68, 89, 78, 65, 77, 73, 67, 128, 84, 72, 69, 82, 69, 70, 79, + 82, 69, 128, 84, 72, 69, 82, 197, 84, 72, 69, 206, 84, 72, 69, 77, 65, + 84, 73, 83, 77, 79, 211, 84, 72, 69, 77, 65, 128, 84, 72, 69, 77, 193, + 84, 72, 69, 72, 128, 84, 72, 69, 200, 84, 72, 69, 65, 128, 84, 72, 197, + 84, 72, 65, 87, 128, 84, 72, 65, 78, 84, 72, 65, 75, 72, 65, 84, 128, 84, + 72, 65, 78, 78, 65, 128, 84, 72, 65, 78, 128, 84, 72, 65, 206, 84, 72, + 65, 77, 69, 68, 72, 128, 84, 72, 65, 76, 128, 84, 72, 65, 204, 84, 72, + 65, 74, 128, 84, 72, 65, 72, 65, 78, 128, 84, 72, 65, 65, 78, 193, 84, + 72, 65, 65, 76, 85, 128, 84, 72, 45, 67, 82, 69, 197, 84, 69, 88, 84, + 128, 84, 69, 88, 212, 84, 69, 88, 128, 84, 69, 86, 73, 82, 128, 84, 69, + 85, 84, 69, 85, 88, 128, 84, 69, 85, 84, 69, 85, 87, 69, 78, 128, 84, 69, + 85, 84, 128, 84, 69, 85, 78, 128, 84, 69, 85, 65, 69, 81, 128, 84, 69, + 85, 65, 69, 78, 128, 84, 69, 85, 128, 84, 69, 84, 82, 65, 83, 73, 77, 79, + 85, 128, 84, 69, 84, 82, 65, 83, 69, 77, 69, 128, 84, 69, 84, 82, 65, 80, + 76, 73, 128, 84, 69, 84, 82, 65, 71, 82, 65, 205, 84, 69, 84, 82, 65, 70, + 79, 78, 73, 65, 83, 128, 84, 69, 84, 72, 128, 84, 69, 84, 200, 84, 69, + 84, 65, 82, 84, 79, 211, 84, 69, 84, 65, 82, 84, 73, 77, 79, 82, 73, 79, + 78, 128, 84, 69, 84, 128, 84, 69, 212, 84, 69, 83, 83, 69, 82, 65, 128, + 84, 69, 83, 83, 69, 82, 193, 84, 69, 83, 83, 65, 82, 79, 206, 84, 69, 83, 200, 84, 69, 82, 77, 73, 78, 65, 84, 79, 82, 128, 84, 69, 80, 128, 84, 69, 78, 85, 84, 79, 128, 84, 69, 78, 85, 128, 84, 69, 78, 213, 84, 69, - 78, 84, 72, 128, 84, 69, 78, 84, 128, 84, 69, 78, 211, 84, 69, 78, 78, - 73, 211, 84, 69, 78, 71, 197, 84, 69, 78, 45, 84, 72, 73, 82, 84, 89, - 128, 84, 69, 78, 128, 84, 69, 206, 84, 69, 77, 80, 85, 211, 84, 69, 76, - 85, 128, 84, 69, 76, 79, 85, 211, 84, 69, 76, 76, 69, 210, 84, 69, 76, - 73, 83, 72, 193, 84, 69, 76, 69, 86, 73, 83, 73, 79, 78, 128, 84, 69, 76, - 69, 83, 67, 79, 80, 69, 128, 84, 69, 76, 69, 80, 72, 79, 78, 69, 128, 84, - 69, 76, 69, 80, 72, 79, 78, 197, 84, 69, 76, 69, 73, 65, 128, 84, 69, 76, - 69, 71, 82, 65, 80, 200, 84, 69, 73, 87, 83, 128, 84, 69, 71, 69, 72, - 128, 84, 69, 69, 69, 69, 128, 84, 69, 197, 84, 69, 68, 85, 78, 71, 128, - 84, 69, 65, 82, 211, 84, 69, 65, 82, 68, 82, 79, 80, 45, 83, 80, 79, 75, - 69, 196, 84, 69, 65, 82, 68, 82, 79, 80, 45, 83, 72, 65, 78, 75, 69, 196, - 84, 69, 65, 82, 68, 82, 79, 80, 45, 66, 65, 82, 66, 69, 196, 84, 69, 65, - 82, 45, 79, 70, 198, 84, 69, 65, 67, 85, 208, 84, 69, 45, 85, 128, 84, - 69, 45, 50, 128, 84, 67, 72, 69, 72, 69, 72, 128, 84, 67, 72, 69, 72, 69, - 200, 84, 67, 72, 69, 72, 128, 84, 67, 72, 69, 200, 84, 67, 72, 69, 128, - 84, 195, 84, 65, 89, 128, 84, 65, 88, 73, 128, 84, 65, 88, 128, 84, 65, - 87, 69, 76, 76, 69, 77, 69, 212, 84, 65, 87, 65, 128, 84, 65, 87, 128, - 84, 65, 86, 73, 89, 65, 78, 73, 128, 84, 65, 86, 128, 84, 65, 214, 84, - 65, 85, 82, 85, 83, 128, 84, 65, 213, 84, 65, 84, 87, 69, 69, 76, 128, - 84, 65, 84, 87, 69, 69, 204, 84, 65, 84, 84, 79, 79, 69, 196, 84, 65, 84, - 128, 84, 65, 82, 85, 78, 71, 128, 84, 65, 82, 84, 65, 82, 45, 50, 128, - 84, 65, 82, 84, 65, 82, 128, 84, 65, 81, 128, 84, 65, 80, 69, 82, 128, - 84, 65, 80, 197, 84, 65, 80, 128, 84, 65, 79, 128, 84, 65, 78, 78, 69, - 196, 84, 65, 78, 71, 69, 82, 73, 78, 69, 128, 84, 65, 78, 199, 84, 65, - 78, 65, 66, 65, 84, 193, 84, 65, 78, 128, 84, 65, 77, 73, 78, 71, 128, - 84, 65, 77, 128, 84, 65, 76, 76, 128, 84, 65, 76, 204, 84, 65, 76, 73, - 78, 71, 128, 84, 65, 76, 73, 78, 199, 84, 65, 76, 69, 78, 84, 83, 128, - 84, 65, 76, 69, 78, 212, 84, 65, 75, 82, 201, 84, 65, 75, 72, 65, 76, 76, - 85, 83, 128, 84, 65, 75, 69, 128, 84, 65, 75, 52, 128, 84, 65, 75, 128, - 84, 65, 73, 83, 89, 79, 85, 128, 84, 65, 73, 76, 76, 69, 83, 211, 84, 65, - 73, 76, 128, 84, 65, 73, 204, 84, 65, 72, 128, 84, 65, 200, 84, 65, 71, - 66, 65, 78, 87, 193, 84, 65, 71, 65, 76, 79, 199, 84, 65, 71, 128, 84, - 65, 69, 206, 84, 65, 67, 75, 128, 84, 65, 67, 203, 84, 65, 66, 85, 76, - 65, 84, 73, 79, 78, 128, 84, 65, 66, 85, 76, 65, 84, 73, 79, 206, 84, 65, - 66, 83, 128, 84, 65, 66, 76, 69, 128, 84, 65, 66, 128, 84, 65, 194, 84, - 65, 65, 83, 72, 65, 69, 128, 84, 65, 65, 81, 128, 84, 65, 65, 77, 128, - 84, 65, 65, 76, 85, 74, 193, 84, 65, 65, 73, 128, 84, 65, 65, 70, 128, - 84, 65, 50, 128, 84, 65, 45, 82, 79, 76, 128, 84, 65, 45, 50, 128, 84, - 48, 51, 54, 128, 84, 48, 51, 53, 128, 84, 48, 51, 52, 128, 84, 48, 51, - 51, 65, 128, 84, 48, 51, 51, 128, 84, 48, 51, 50, 65, 128, 84, 48, 51, - 50, 128, 84, 48, 51, 49, 128, 84, 48, 51, 48, 128, 84, 48, 50, 57, 128, - 84, 48, 50, 56, 128, 84, 48, 50, 55, 128, 84, 48, 50, 54, 128, 84, 48, - 50, 53, 128, 84, 48, 50, 52, 128, 84, 48, 50, 51, 128, 84, 48, 50, 50, - 128, 84, 48, 50, 49, 128, 84, 48, 50, 48, 128, 84, 48, 49, 57, 128, 84, - 48, 49, 56, 128, 84, 48, 49, 55, 128, 84, 48, 49, 54, 65, 128, 84, 48, - 49, 54, 128, 84, 48, 49, 53, 128, 84, 48, 49, 52, 128, 84, 48, 49, 51, - 128, 84, 48, 49, 50, 128, 84, 48, 49, 49, 65, 128, 84, 48, 49, 49, 128, - 84, 48, 49, 48, 128, 84, 48, 48, 57, 65, 128, 84, 48, 48, 57, 128, 84, - 48, 48, 56, 65, 128, 84, 48, 48, 56, 128, 84, 48, 48, 55, 65, 128, 84, - 48, 48, 55, 128, 84, 48, 48, 54, 128, 84, 48, 48, 53, 128, 84, 48, 48, - 52, 128, 84, 48, 48, 51, 65, 128, 84, 48, 48, 51, 128, 84, 48, 48, 50, - 128, 84, 48, 48, 49, 128, 84, 45, 83, 72, 73, 82, 84, 128, 83, 90, 90, - 128, 83, 90, 87, 71, 128, 83, 90, 87, 65, 128, 83, 90, 85, 128, 83, 90, - 79, 128, 83, 90, 73, 128, 83, 90, 69, 69, 128, 83, 90, 69, 128, 83, 90, - 65, 65, 128, 83, 90, 65, 128, 83, 90, 128, 83, 89, 88, 128, 83, 89, 84, - 128, 83, 89, 83, 84, 69, 205, 83, 89, 82, 88, 128, 83, 89, 82, 77, 65, - 84, 73, 75, 73, 128, 83, 89, 82, 77, 65, 128, 83, 89, 82, 73, 78, 71, 69, - 128, 83, 89, 82, 128, 83, 89, 80, 128, 83, 89, 79, 85, 87, 65, 128, 83, - 89, 78, 69, 86, 77, 65, 128, 83, 89, 78, 68, 69, 83, 77, 79, 211, 83, 89, - 78, 67, 72, 82, 79, 78, 79, 85, 211, 83, 89, 78, 65, 71, 77, 193, 83, 89, - 78, 65, 70, 73, 128, 83, 89, 78, 128, 83, 89, 77, 77, 69, 84, 82, 89, - 128, 83, 89, 77, 77, 69, 84, 82, 73, 195, 83, 89, 77, 66, 79, 76, 83, - 128, 83, 89, 77, 66, 79, 76, 45, 57, 128, 83, 89, 77, 66, 79, 76, 45, 56, - 128, 83, 89, 77, 66, 79, 76, 45, 55, 128, 83, 89, 77, 66, 79, 76, 45, 54, - 128, 83, 89, 77, 66, 79, 76, 45, 53, 52, 128, 83, 89, 77, 66, 79, 76, 45, - 53, 51, 128, 83, 89, 77, 66, 79, 76, 45, 53, 50, 128, 83, 89, 77, 66, 79, - 76, 45, 53, 49, 128, 83, 89, 77, 66, 79, 76, 45, 53, 48, 128, 83, 89, 77, - 66, 79, 76, 45, 53, 128, 83, 89, 77, 66, 79, 76, 45, 52, 57, 128, 83, 89, - 77, 66, 79, 76, 45, 52, 56, 128, 83, 89, 77, 66, 79, 76, 45, 52, 55, 128, - 83, 89, 77, 66, 79, 76, 45, 52, 53, 128, 83, 89, 77, 66, 79, 76, 45, 52, - 51, 128, 83, 89, 77, 66, 79, 76, 45, 52, 50, 128, 83, 89, 77, 66, 79, 76, - 45, 52, 48, 128, 83, 89, 77, 66, 79, 76, 45, 52, 128, 83, 89, 77, 66, 79, - 76, 45, 51, 57, 128, 83, 89, 77, 66, 79, 76, 45, 51, 56, 128, 83, 89, 77, - 66, 79, 76, 45, 51, 55, 128, 83, 89, 77, 66, 79, 76, 45, 51, 54, 128, 83, - 89, 77, 66, 79, 76, 45, 51, 50, 128, 83, 89, 77, 66, 79, 76, 45, 51, 48, - 128, 83, 89, 77, 66, 79, 76, 45, 51, 128, 83, 89, 77, 66, 79, 76, 45, 50, - 57, 128, 83, 89, 77, 66, 79, 76, 45, 50, 55, 128, 83, 89, 77, 66, 79, 76, - 45, 50, 54, 128, 83, 89, 77, 66, 79, 76, 45, 50, 53, 128, 83, 89, 77, 66, - 79, 76, 45, 50, 52, 128, 83, 89, 77, 66, 79, 76, 45, 50, 51, 128, 83, 89, - 77, 66, 79, 76, 45, 50, 50, 128, 83, 89, 77, 66, 79, 76, 45, 50, 49, 128, - 83, 89, 77, 66, 79, 76, 45, 50, 48, 128, 83, 89, 77, 66, 79, 76, 45, 50, - 128, 83, 89, 77, 66, 79, 76, 45, 49, 57, 128, 83, 89, 77, 66, 79, 76, 45, - 49, 56, 128, 83, 89, 77, 66, 79, 76, 45, 49, 55, 128, 83, 89, 77, 66, 79, - 76, 45, 49, 54, 128, 83, 89, 77, 66, 79, 76, 45, 49, 53, 128, 83, 89, 77, - 66, 79, 76, 45, 49, 52, 128, 83, 89, 77, 66, 79, 76, 45, 49, 51, 128, 83, - 89, 77, 66, 79, 76, 45, 49, 50, 128, 83, 89, 77, 66, 79, 76, 45, 49, 49, - 128, 83, 89, 77, 66, 79, 76, 45, 49, 48, 128, 83, 89, 77, 66, 79, 76, 45, - 49, 128, 83, 89, 76, 79, 84, 201, 83, 89, 128, 83, 87, 90, 128, 83, 87, - 85, 78, 199, 83, 87, 79, 82, 68, 83, 128, 83, 87, 79, 82, 68, 128, 83, - 87, 79, 79, 128, 83, 87, 79, 128, 83, 87, 73, 82, 204, 83, 87, 73, 77, - 77, 73, 78, 71, 128, 83, 87, 73, 77, 77, 69, 82, 128, 83, 87, 73, 73, - 128, 83, 87, 73, 128, 83, 87, 71, 128, 83, 87, 69, 69, 84, 128, 83, 87, - 69, 69, 212, 83, 87, 69, 65, 84, 128, 83, 87, 69, 65, 212, 83, 87, 65, - 83, 200, 83, 87, 65, 80, 80, 73, 78, 71, 128, 83, 87, 65, 65, 128, 83, - 87, 128, 83, 86, 65, 83, 84, 201, 83, 86, 65, 82, 73, 84, 65, 128, 83, - 86, 65, 82, 73, 84, 193, 83, 85, 88, 128, 83, 85, 85, 128, 83, 85, 84, - 128, 83, 85, 83, 80, 69, 78, 83, 73, 79, 206, 83, 85, 83, 72, 73, 128, - 83, 85, 82, 89, 65, 128, 83, 85, 82, 88, 128, 83, 85, 82, 82, 79, 85, 78, - 68, 128, 83, 85, 82, 82, 79, 85, 78, 196, 83, 85, 82, 70, 69, 82, 128, - 83, 85, 82, 70, 65, 67, 197, 83, 85, 82, 69, 128, 83, 85, 82, 65, 78, 71, - 128, 83, 85, 82, 57, 128, 83, 85, 82, 128, 83, 85, 210, 83, 85, 80, 82, - 65, 76, 73, 78, 69, 65, 210, 83, 85, 80, 69, 82, 86, 73, 83, 69, 128, 83, - 85, 80, 69, 82, 83, 69, 84, 128, 83, 85, 80, 69, 82, 83, 69, 212, 83, 85, - 80, 69, 82, 83, 67, 82, 73, 80, 212, 83, 85, 80, 69, 82, 73, 77, 80, 79, - 83, 69, 196, 83, 85, 80, 69, 82, 70, 73, 88, 69, 196, 83, 85, 80, 69, - 210, 83, 85, 80, 128, 83, 85, 79, 88, 128, 83, 85, 79, 80, 128, 83, 85, - 79, 128, 83, 85, 78, 83, 69, 212, 83, 85, 78, 82, 73, 83, 69, 128, 83, - 85, 78, 82, 73, 83, 197, 83, 85, 78, 71, 76, 65, 83, 83, 69, 83, 128, 83, - 85, 78, 71, 128, 83, 85, 78, 70, 76, 79, 87, 69, 82, 128, 83, 85, 78, - 128, 83, 85, 206, 83, 85, 77, 77, 69, 82, 128, 83, 85, 77, 77, 65, 84, - 73, 79, 78, 128, 83, 85, 77, 77, 65, 84, 73, 79, 206, 83, 85, 77, 65, 83, - 72, 128, 83, 85, 77, 128, 83, 85, 76, 70, 85, 82, 128, 83, 85, 75, 85, - 78, 128, 83, 85, 75, 85, 206, 83, 85, 75, 85, 128, 83, 85, 75, 213, 83, - 85, 73, 84, 65, 66, 76, 69, 128, 83, 85, 73, 84, 128, 83, 85, 72, 85, 82, - 128, 83, 85, 69, 128, 83, 85, 68, 50, 128, 83, 85, 68, 128, 83, 85, 67, - 67, 69, 69, 68, 83, 128, 83, 85, 67, 67, 69, 69, 68, 211, 83, 85, 67, 67, - 69, 69, 68, 128, 83, 85, 67, 67, 69, 69, 196, 83, 85, 66, 85, 78, 73, 84, - 128, 83, 85, 66, 83, 84, 73, 84, 85, 84, 73, 79, 206, 83, 85, 66, 83, 84, - 73, 84, 85, 84, 69, 128, 83, 85, 66, 83, 84, 73, 84, 85, 84, 197, 83, 85, - 66, 83, 69, 84, 128, 83, 85, 66, 83, 69, 212, 83, 85, 66, 83, 67, 82, 73, - 80, 212, 83, 85, 66, 80, 85, 78, 67, 84, 73, 83, 128, 83, 85, 66, 76, 73, - 78, 69, 65, 210, 83, 85, 66, 76, 73, 77, 65, 84, 73, 79, 78, 128, 83, 85, - 66, 76, 73, 77, 65, 84, 69, 45, 51, 128, 83, 85, 66, 76, 73, 77, 65, 84, - 69, 45, 50, 128, 83, 85, 66, 76, 73, 77, 65, 84, 69, 128, 83, 85, 66, 76, - 73, 77, 65, 84, 197, 83, 85, 66, 74, 79, 73, 78, 69, 196, 83, 85, 66, 74, - 69, 67, 84, 128, 83, 85, 66, 73, 84, 79, 128, 83, 85, 66, 71, 82, 79, 85, - 80, 128, 83, 85, 66, 71, 82, 79, 85, 208, 83, 85, 66, 128, 83, 85, 65, - 69, 84, 128, 83, 85, 65, 69, 78, 128, 83, 85, 65, 69, 128, 83, 85, 65, - 128, 83, 213, 83, 84, 88, 128, 83, 84, 87, 65, 128, 83, 84, 85, 68, 89, - 128, 83, 84, 85, 67, 75, 45, 79, 85, 212, 83, 84, 83, 128, 83, 84, 82, - 79, 78, 199, 83, 84, 82, 79, 75, 69, 83, 128, 83, 84, 82, 79, 75, 69, - 211, 83, 84, 82, 79, 75, 69, 45, 57, 128, 83, 84, 82, 79, 75, 69, 45, 56, - 128, 83, 84, 82, 79, 75, 69, 45, 55, 128, 83, 84, 82, 79, 75, 69, 45, 54, - 128, 83, 84, 82, 79, 75, 69, 45, 53, 128, 83, 84, 82, 79, 75, 69, 45, 52, - 128, 83, 84, 82, 79, 75, 69, 45, 51, 128, 83, 84, 82, 79, 75, 69, 45, 50, - 128, 83, 84, 82, 79, 75, 69, 45, 49, 49, 128, 83, 84, 82, 79, 75, 69, 45, - 49, 48, 128, 83, 84, 82, 79, 75, 69, 45, 49, 128, 83, 84, 82, 79, 75, - 197, 83, 84, 82, 73, 80, 69, 128, 83, 84, 82, 73, 78, 71, 128, 83, 84, - 82, 73, 78, 199, 83, 84, 82, 73, 75, 69, 84, 72, 82, 79, 85, 71, 72, 128, - 83, 84, 82, 73, 68, 69, 128, 83, 84, 82, 73, 67, 84, 76, 217, 83, 84, 82, - 69, 84, 67, 72, 69, 196, 83, 84, 82, 69, 83, 211, 83, 84, 82, 69, 78, 71, - 84, 72, 128, 83, 84, 82, 69, 65, 77, 69, 82, 128, 83, 84, 82, 65, 87, 66, - 69, 82, 82, 89, 128, 83, 84, 82, 65, 84, 85, 77, 45, 50, 128, 83, 84, 82, - 65, 84, 85, 77, 128, 83, 84, 82, 65, 84, 85, 205, 83, 84, 82, 65, 84, 73, - 65, 206, 83, 84, 82, 65, 73, 78, 69, 82, 128, 83, 84, 82, 65, 73, 71, 72, - 84, 78, 69, 83, 83, 128, 83, 84, 82, 65, 73, 71, 72, 212, 83, 84, 82, 65, - 73, 70, 128, 83, 84, 82, 65, 71, 71, 73, 83, 77, 65, 84, 65, 128, 83, 84, - 79, 86, 69, 128, 83, 84, 79, 82, 69, 128, 83, 84, 79, 80, 87, 65, 84, 67, - 72, 128, 83, 84, 79, 80, 80, 73, 78, 71, 128, 83, 84, 79, 80, 80, 65, 71, - 69, 128, 83, 84, 79, 80, 128, 83, 84, 79, 208, 83, 84, 79, 78, 69, 128, - 83, 84, 79, 67, 75, 128, 83, 84, 73, 77, 77, 69, 128, 83, 84, 73, 76, - 204, 83, 84, 73, 76, 197, 83, 84, 73, 71, 77, 65, 128, 83, 84, 69, 80, - 128, 83, 84, 69, 77, 128, 83, 84, 69, 65, 77, 73, 78, 199, 83, 84, 69, - 65, 77, 128, 83, 84, 69, 65, 205, 83, 84, 65, 86, 82, 79, 85, 128, 83, - 84, 65, 86, 82, 79, 83, 128, 83, 84, 65, 86, 82, 79, 211, 83, 84, 65, 85, - 82, 79, 83, 128, 83, 84, 65, 84, 85, 197, 83, 84, 65, 84, 73, 79, 78, - 128, 83, 84, 65, 84, 69, 82, 83, 128, 83, 84, 65, 84, 69, 128, 83, 84, - 65, 82, 212, 83, 84, 65, 82, 83, 128, 83, 84, 65, 82, 82, 69, 196, 83, - 84, 65, 82, 75, 128, 83, 84, 65, 82, 128, 83, 84, 65, 210, 83, 84, 65, - 78, 68, 83, 84, 73, 76, 76, 128, 83, 84, 65, 78, 68, 65, 82, 196, 83, 84, - 65, 78, 68, 128, 83, 84, 65, 78, 128, 83, 84, 65, 76, 76, 73, 79, 78, - 128, 83, 84, 65, 70, 70, 128, 83, 84, 65, 70, 198, 83, 84, 65, 67, 67, - 65, 84, 79, 128, 83, 84, 65, 67, 67, 65, 84, 73, 83, 83, 73, 77, 79, 128, - 83, 84, 50, 128, 83, 83, 89, 88, 128, 83, 83, 89, 84, 128, 83, 83, 89, - 82, 88, 128, 83, 83, 89, 82, 128, 83, 83, 89, 80, 128, 83, 83, 89, 128, - 83, 83, 85, 88, 128, 83, 83, 85, 85, 128, 83, 83, 85, 84, 128, 83, 83, - 85, 80, 128, 83, 83, 79, 88, 128, 83, 83, 79, 84, 128, 83, 83, 79, 80, - 128, 83, 83, 79, 79, 128, 83, 83, 79, 128, 83, 83, 73, 88, 128, 83, 83, - 73, 84, 128, 83, 83, 73, 80, 128, 83, 83, 73, 73, 128, 83, 83, 73, 69, - 88, 128, 83, 83, 73, 69, 80, 128, 83, 83, 73, 69, 128, 83, 83, 73, 128, - 83, 83, 72, 69, 128, 83, 83, 69, 88, 128, 83, 83, 69, 80, 128, 83, 83, - 69, 69, 128, 83, 83, 65, 88, 128, 83, 83, 65, 85, 128, 83, 83, 65, 84, - 128, 83, 83, 65, 80, 128, 83, 83, 65, 78, 71, 89, 69, 79, 82, 73, 78, 72, - 73, 69, 85, 72, 128, 83, 83, 65, 78, 71, 84, 73, 75, 69, 85, 84, 45, 80, - 73, 69, 85, 80, 128, 83, 83, 65, 78, 71, 84, 73, 75, 69, 85, 84, 128, 83, - 83, 65, 78, 71, 84, 72, 73, 69, 85, 84, 72, 128, 83, 83, 65, 78, 71, 83, - 73, 79, 83, 45, 84, 73, 75, 69, 85, 84, 128, 83, 83, 65, 78, 71, 83, 73, - 79, 83, 45, 80, 73, 69, 85, 80, 128, 83, 83, 65, 78, 71, 83, 73, 79, 83, - 45, 75, 73, 89, 69, 79, 75, 128, 83, 83, 65, 78, 71, 83, 73, 79, 83, 128, - 83, 83, 65, 78, 71, 82, 73, 69, 85, 76, 45, 75, 72, 73, 69, 85, 75, 72, - 128, 83, 83, 65, 78, 71, 82, 73, 69, 85, 76, 128, 83, 83, 65, 78, 71, 80, - 73, 69, 85, 80, 128, 83, 83, 65, 78, 71, 78, 73, 69, 85, 78, 128, 83, 83, - 65, 78, 71, 77, 73, 69, 85, 77, 128, 83, 83, 65, 78, 71, 75, 73, 89, 69, - 79, 75, 128, 83, 83, 65, 78, 71, 73, 69, 85, 78, 71, 128, 83, 83, 65, 78, - 71, 72, 73, 69, 85, 72, 128, 83, 83, 65, 78, 71, 67, 73, 69, 85, 67, 45, - 72, 73, 69, 85, 72, 128, 83, 83, 65, 78, 71, 67, 73, 69, 85, 67, 128, 83, - 83, 65, 78, 71, 65, 82, 65, 69, 65, 128, 83, 83, 65, 73, 128, 83, 83, 65, - 65, 128, 83, 83, 51, 128, 83, 83, 50, 128, 83, 82, 128, 83, 81, 85, 73, - 83, 200, 83, 81, 85, 73, 82, 82, 69, 204, 83, 81, 85, 73, 71, 71, 76, + 78, 84, 72, 128, 84, 69, 78, 84, 128, 84, 69, 78, 83, 128, 84, 69, 78, + 211, 84, 69, 78, 78, 73, 211, 84, 69, 78, 71, 197, 84, 69, 78, 45, 84, + 72, 73, 82, 84, 89, 128, 84, 69, 78, 128, 84, 69, 206, 84, 69, 77, 80, + 85, 211, 84, 69, 76, 85, 128, 84, 69, 76, 79, 85, 211, 84, 69, 76, 76, + 69, 210, 84, 69, 76, 73, 83, 72, 193, 84, 69, 76, 69, 86, 73, 83, 73, 79, + 78, 128, 84, 69, 76, 69, 83, 67, 79, 80, 69, 128, 84, 69, 76, 69, 80, 72, + 79, 78, 69, 128, 84, 69, 76, 69, 80, 72, 79, 78, 197, 84, 69, 76, 69, 73, + 65, 128, 84, 69, 76, 69, 71, 82, 65, 80, 200, 84, 69, 75, 128, 84, 69, + 73, 87, 83, 128, 84, 69, 71, 69, 72, 128, 84, 69, 69, 78, 83, 128, 84, + 69, 69, 69, 69, 128, 84, 69, 197, 84, 69, 68, 85, 78, 71, 128, 84, 69, + 65, 82, 211, 84, 69, 65, 82, 68, 82, 79, 80, 45, 83, 80, 79, 75, 69, 196, + 84, 69, 65, 82, 68, 82, 79, 80, 45, 83, 72, 65, 78, 75, 69, 196, 84, 69, + 65, 82, 68, 82, 79, 80, 45, 66, 65, 82, 66, 69, 196, 84, 69, 65, 82, 45, + 79, 70, 198, 84, 69, 65, 67, 85, 208, 84, 69, 45, 85, 128, 84, 69, 45, + 50, 128, 84, 67, 72, 69, 72, 69, 72, 128, 84, 67, 72, 69, 72, 69, 200, + 84, 67, 72, 69, 72, 128, 84, 67, 72, 69, 200, 84, 67, 72, 69, 128, 84, + 195, 84, 65, 89, 128, 84, 65, 88, 73, 128, 84, 65, 88, 128, 84, 65, 87, + 69, 76, 76, 69, 77, 69, 212, 84, 65, 87, 65, 128, 84, 65, 87, 128, 84, + 65, 86, 73, 89, 65, 78, 73, 128, 84, 65, 86, 128, 84, 65, 214, 84, 65, + 85, 82, 85, 83, 128, 84, 65, 85, 77, 128, 84, 65, 213, 84, 65, 84, 87, + 69, 69, 76, 128, 84, 65, 84, 87, 69, 69, 204, 84, 65, 84, 84, 79, 79, 69, + 196, 84, 65, 84, 128, 84, 65, 83, 128, 84, 65, 82, 85, 78, 71, 128, 84, + 65, 82, 84, 65, 82, 45, 50, 128, 84, 65, 82, 84, 65, 82, 128, 84, 65, 82, + 71, 69, 84, 128, 84, 65, 81, 128, 84, 65, 80, 69, 82, 128, 84, 65, 80, + 197, 84, 65, 80, 128, 84, 65, 79, 128, 84, 65, 78, 78, 69, 196, 84, 65, + 78, 71, 69, 82, 73, 78, 69, 128, 84, 65, 78, 71, 69, 78, 84, 128, 84, 65, + 78, 71, 69, 78, 212, 84, 65, 78, 199, 84, 65, 78, 65, 66, 65, 84, 193, + 84, 65, 78, 128, 84, 65, 77, 73, 78, 71, 128, 84, 65, 77, 128, 84, 65, + 76, 76, 128, 84, 65, 76, 204, 84, 65, 76, 73, 78, 71, 128, 84, 65, 76, + 73, 78, 199, 84, 65, 76, 69, 78, 84, 83, 128, 84, 65, 76, 69, 78, 212, + 84, 65, 75, 82, 201, 84, 65, 75, 72, 65, 76, 76, 85, 83, 128, 84, 65, 75, + 69, 128, 84, 65, 75, 52, 128, 84, 65, 75, 128, 84, 65, 73, 83, 89, 79, + 85, 128, 84, 65, 73, 76, 76, 69, 83, 211, 84, 65, 73, 76, 128, 84, 65, + 73, 204, 84, 65, 72, 128, 84, 65, 200, 84, 65, 71, 66, 65, 78, 87, 193, + 84, 65, 71, 65, 76, 79, 199, 84, 65, 71, 128, 84, 65, 69, 206, 84, 65, + 67, 75, 128, 84, 65, 67, 203, 84, 65, 66, 85, 76, 65, 84, 73, 79, 78, + 128, 84, 65, 66, 85, 76, 65, 84, 73, 79, 206, 84, 65, 66, 83, 128, 84, + 65, 66, 76, 69, 128, 84, 65, 66, 128, 84, 65, 194, 84, 65, 65, 83, 72, + 65, 69, 128, 84, 65, 65, 81, 128, 84, 65, 65, 77, 128, 84, 65, 65, 76, + 85, 74, 193, 84, 65, 65, 73, 128, 84, 65, 65, 70, 128, 84, 65, 50, 128, + 84, 65, 45, 82, 79, 76, 128, 84, 65, 45, 50, 128, 84, 48, 51, 54, 128, + 84, 48, 51, 53, 128, 84, 48, 51, 52, 128, 84, 48, 51, 51, 65, 128, 84, + 48, 51, 51, 128, 84, 48, 51, 50, 65, 128, 84, 48, 51, 50, 128, 84, 48, + 51, 49, 128, 84, 48, 51, 48, 128, 84, 48, 50, 57, 128, 84, 48, 50, 56, + 128, 84, 48, 50, 55, 128, 84, 48, 50, 54, 128, 84, 48, 50, 53, 128, 84, + 48, 50, 52, 128, 84, 48, 50, 51, 128, 84, 48, 50, 50, 128, 84, 48, 50, + 49, 128, 84, 48, 50, 48, 128, 84, 48, 49, 57, 128, 84, 48, 49, 56, 128, + 84, 48, 49, 55, 128, 84, 48, 49, 54, 65, 128, 84, 48, 49, 54, 128, 84, + 48, 49, 53, 128, 84, 48, 49, 52, 128, 84, 48, 49, 51, 128, 84, 48, 49, + 50, 128, 84, 48, 49, 49, 65, 128, 84, 48, 49, 49, 128, 84, 48, 49, 48, + 128, 84, 48, 48, 57, 65, 128, 84, 48, 48, 57, 128, 84, 48, 48, 56, 65, + 128, 84, 48, 48, 56, 128, 84, 48, 48, 55, 65, 128, 84, 48, 48, 55, 128, + 84, 48, 48, 54, 128, 84, 48, 48, 53, 128, 84, 48, 48, 52, 128, 84, 48, + 48, 51, 65, 128, 84, 48, 48, 51, 128, 84, 48, 48, 50, 128, 84, 48, 48, + 49, 128, 84, 45, 83, 72, 73, 82, 84, 128, 83, 90, 90, 128, 83, 90, 87, + 71, 128, 83, 90, 87, 65, 128, 83, 90, 85, 128, 83, 90, 79, 128, 83, 90, + 73, 128, 83, 90, 69, 69, 128, 83, 90, 69, 128, 83, 90, 65, 65, 128, 83, + 90, 65, 128, 83, 90, 128, 83, 89, 88, 128, 83, 89, 84, 128, 83, 89, 83, + 84, 69, 205, 83, 89, 82, 88, 128, 83, 89, 82, 77, 65, 84, 73, 75, 73, + 128, 83, 89, 82, 77, 65, 128, 83, 89, 82, 73, 78, 71, 69, 128, 83, 89, + 82, 73, 65, 195, 83, 89, 82, 128, 83, 89, 80, 128, 83, 89, 79, 85, 87, + 65, 128, 83, 89, 78, 69, 86, 77, 65, 128, 83, 89, 78, 68, 69, 83, 77, 79, + 211, 83, 89, 78, 67, 72, 82, 79, 78, 79, 85, 211, 83, 89, 78, 65, 71, 77, + 193, 83, 89, 78, 65, 70, 73, 128, 83, 89, 78, 128, 83, 89, 77, 77, 69, + 84, 82, 89, 128, 83, 89, 77, 77, 69, 84, 82, 73, 195, 83, 89, 77, 66, 79, + 76, 83, 128, 83, 89, 77, 66, 79, 76, 45, 57, 128, 83, 89, 77, 66, 79, 76, + 45, 56, 128, 83, 89, 77, 66, 79, 76, 45, 55, 128, 83, 89, 77, 66, 79, 76, + 45, 54, 128, 83, 89, 77, 66, 79, 76, 45, 53, 52, 128, 83, 89, 77, 66, 79, + 76, 45, 53, 51, 128, 83, 89, 77, 66, 79, 76, 45, 53, 50, 128, 83, 89, 77, + 66, 79, 76, 45, 53, 49, 128, 83, 89, 77, 66, 79, 76, 45, 53, 48, 128, 83, + 89, 77, 66, 79, 76, 45, 53, 128, 83, 89, 77, 66, 79, 76, 45, 52, 57, 128, + 83, 89, 77, 66, 79, 76, 45, 52, 56, 128, 83, 89, 77, 66, 79, 76, 45, 52, + 55, 128, 83, 89, 77, 66, 79, 76, 45, 52, 53, 128, 83, 89, 77, 66, 79, 76, + 45, 52, 51, 128, 83, 89, 77, 66, 79, 76, 45, 52, 50, 128, 83, 89, 77, 66, + 79, 76, 45, 52, 48, 128, 83, 89, 77, 66, 79, 76, 45, 52, 128, 83, 89, 77, + 66, 79, 76, 45, 51, 57, 128, 83, 89, 77, 66, 79, 76, 45, 51, 56, 128, 83, + 89, 77, 66, 79, 76, 45, 51, 55, 128, 83, 89, 77, 66, 79, 76, 45, 51, 54, + 128, 83, 89, 77, 66, 79, 76, 45, 51, 50, 128, 83, 89, 77, 66, 79, 76, 45, + 51, 48, 128, 83, 89, 77, 66, 79, 76, 45, 51, 128, 83, 89, 77, 66, 79, 76, + 45, 50, 57, 128, 83, 89, 77, 66, 79, 76, 45, 50, 55, 128, 83, 89, 77, 66, + 79, 76, 45, 50, 54, 128, 83, 89, 77, 66, 79, 76, 45, 50, 53, 128, 83, 89, + 77, 66, 79, 76, 45, 50, 52, 128, 83, 89, 77, 66, 79, 76, 45, 50, 51, 128, + 83, 89, 77, 66, 79, 76, 45, 50, 50, 128, 83, 89, 77, 66, 79, 76, 45, 50, + 49, 128, 83, 89, 77, 66, 79, 76, 45, 50, 48, 128, 83, 89, 77, 66, 79, 76, + 45, 50, 128, 83, 89, 77, 66, 79, 76, 45, 49, 57, 128, 83, 89, 77, 66, 79, + 76, 45, 49, 56, 128, 83, 89, 77, 66, 79, 76, 45, 49, 55, 128, 83, 89, 77, + 66, 79, 76, 45, 49, 54, 128, 83, 89, 77, 66, 79, 76, 45, 49, 53, 128, 83, + 89, 77, 66, 79, 76, 45, 49, 52, 128, 83, 89, 77, 66, 79, 76, 45, 49, 51, + 128, 83, 89, 77, 66, 79, 76, 45, 49, 50, 128, 83, 89, 77, 66, 79, 76, 45, + 49, 49, 128, 83, 89, 77, 66, 79, 76, 45, 49, 48, 128, 83, 89, 77, 66, 79, + 76, 45, 49, 128, 83, 89, 76, 79, 84, 201, 83, 89, 128, 83, 87, 90, 128, + 83, 87, 85, 78, 199, 83, 87, 79, 82, 68, 83, 128, 83, 87, 79, 82, 68, + 128, 83, 87, 79, 79, 128, 83, 87, 79, 128, 83, 87, 73, 82, 204, 83, 87, + 73, 77, 77, 73, 78, 71, 128, 83, 87, 73, 77, 77, 69, 82, 128, 83, 87, 73, + 73, 128, 83, 87, 73, 128, 83, 87, 71, 128, 83, 87, 69, 69, 84, 128, 83, + 87, 69, 69, 212, 83, 87, 69, 65, 84, 128, 83, 87, 69, 65, 212, 83, 87, + 65, 83, 200, 83, 87, 65, 80, 80, 73, 78, 71, 128, 83, 87, 65, 65, 128, + 83, 87, 128, 83, 86, 65, 83, 84, 201, 83, 86, 65, 82, 73, 84, 65, 128, + 83, 86, 65, 82, 73, 84, 193, 83, 85, 88, 128, 83, 85, 85, 128, 83, 85, + 84, 82, 193, 83, 85, 84, 128, 83, 85, 83, 80, 69, 78, 83, 73, 79, 206, + 83, 85, 83, 72, 73, 128, 83, 85, 82, 89, 65, 128, 83, 85, 82, 88, 128, + 83, 85, 82, 82, 79, 85, 78, 68, 128, 83, 85, 82, 82, 79, 85, 78, 196, 83, + 85, 82, 70, 69, 82, 128, 83, 85, 82, 70, 65, 67, 197, 83, 85, 82, 69, + 128, 83, 85, 82, 65, 78, 71, 128, 83, 85, 82, 57, 128, 83, 85, 82, 128, + 83, 85, 210, 83, 85, 80, 82, 65, 76, 73, 78, 69, 65, 210, 83, 85, 80, 69, + 82, 86, 73, 83, 69, 128, 83, 85, 80, 69, 82, 83, 69, 84, 128, 83, 85, 80, + 69, 82, 83, 69, 212, 83, 85, 80, 69, 82, 83, 67, 82, 73, 80, 212, 83, 85, + 80, 69, 82, 73, 77, 80, 79, 83, 69, 196, 83, 85, 80, 69, 82, 70, 73, 88, + 69, 196, 83, 85, 80, 69, 210, 83, 85, 80, 128, 83, 85, 79, 88, 128, 83, + 85, 79, 80, 128, 83, 85, 79, 128, 83, 85, 78, 83, 69, 212, 83, 85, 78, + 82, 73, 83, 69, 128, 83, 85, 78, 82, 73, 83, 197, 83, 85, 78, 71, 76, 65, + 83, 83, 69, 83, 128, 83, 85, 78, 71, 128, 83, 85, 78, 70, 76, 79, 87, 69, + 82, 128, 83, 85, 78, 68, 65, 78, 69, 83, 197, 83, 85, 78, 128, 83, 85, + 206, 83, 85, 77, 77, 69, 82, 128, 83, 85, 77, 77, 65, 84, 73, 79, 78, + 128, 83, 85, 77, 77, 65, 84, 73, 79, 206, 83, 85, 77, 65, 83, 72, 128, + 83, 85, 77, 128, 83, 85, 76, 70, 85, 82, 128, 83, 85, 75, 85, 78, 128, + 83, 85, 75, 85, 206, 83, 85, 75, 85, 128, 83, 85, 75, 213, 83, 85, 73, + 84, 65, 66, 76, 69, 128, 83, 85, 73, 84, 128, 83, 85, 73, 212, 83, 85, + 72, 85, 82, 128, 83, 85, 69, 128, 83, 85, 68, 50, 128, 83, 85, 68, 128, + 83, 85, 67, 67, 69, 69, 68, 83, 128, 83, 85, 67, 67, 69, 69, 68, 211, 83, + 85, 67, 67, 69, 69, 68, 128, 83, 85, 67, 67, 69, 69, 196, 83, 85, 66, 85, + 78, 73, 84, 128, 83, 85, 66, 83, 84, 73, 84, 85, 84, 73, 79, 206, 83, 85, + 66, 83, 84, 73, 84, 85, 84, 69, 128, 83, 85, 66, 83, 84, 73, 84, 85, 84, + 197, 83, 85, 66, 83, 69, 84, 128, 83, 85, 66, 83, 69, 212, 83, 85, 66, + 83, 67, 82, 73, 80, 212, 83, 85, 66, 80, 85, 78, 67, 84, 73, 83, 128, 83, + 85, 66, 76, 73, 78, 69, 65, 210, 83, 85, 66, 76, 73, 77, 65, 84, 73, 79, + 78, 128, 83, 85, 66, 76, 73, 77, 65, 84, 69, 45, 51, 128, 83, 85, 66, 76, + 73, 77, 65, 84, 69, 45, 50, 128, 83, 85, 66, 76, 73, 77, 65, 84, 69, 128, + 83, 85, 66, 76, 73, 77, 65, 84, 197, 83, 85, 66, 74, 79, 73, 78, 69, 196, + 83, 85, 66, 74, 69, 67, 84, 128, 83, 85, 66, 73, 84, 79, 128, 83, 85, 66, + 71, 82, 79, 85, 80, 128, 83, 85, 66, 71, 82, 79, 85, 208, 83, 85, 66, + 128, 83, 85, 65, 77, 128, 83, 85, 65, 69, 84, 128, 83, 85, 65, 69, 78, + 128, 83, 85, 65, 69, 128, 83, 85, 65, 66, 128, 83, 85, 65, 128, 83, 213, + 83, 84, 88, 128, 83, 84, 87, 65, 128, 83, 84, 85, 68, 89, 128, 83, 84, + 85, 68, 73, 207, 83, 84, 85, 67, 75, 45, 79, 85, 212, 83, 84, 83, 128, + 83, 84, 82, 79, 78, 199, 83, 84, 82, 79, 75, 69, 83, 128, 83, 84, 82, 79, + 75, 69, 211, 83, 84, 82, 79, 75, 69, 45, 57, 128, 83, 84, 82, 79, 75, 69, + 45, 56, 128, 83, 84, 82, 79, 75, 69, 45, 55, 128, 83, 84, 82, 79, 75, 69, + 45, 54, 128, 83, 84, 82, 79, 75, 69, 45, 53, 128, 83, 84, 82, 79, 75, 69, + 45, 52, 128, 83, 84, 82, 79, 75, 69, 45, 51, 128, 83, 84, 82, 79, 75, 69, + 45, 50, 128, 83, 84, 82, 79, 75, 69, 45, 49, 49, 128, 83, 84, 82, 79, 75, + 69, 45, 49, 48, 128, 83, 84, 82, 79, 75, 69, 45, 49, 128, 83, 84, 82, 79, + 75, 197, 83, 84, 82, 73, 80, 69, 128, 83, 84, 82, 73, 78, 71, 128, 83, + 84, 82, 73, 78, 199, 83, 84, 82, 73, 75, 69, 84, 72, 82, 79, 85, 71, 72, + 128, 83, 84, 82, 73, 68, 69, 128, 83, 84, 82, 73, 67, 84, 76, 217, 83, + 84, 82, 69, 84, 67, 72, 69, 196, 83, 84, 82, 69, 83, 211, 83, 84, 82, 69, + 78, 71, 84, 72, 128, 83, 84, 82, 69, 65, 77, 69, 82, 128, 83, 84, 82, 65, + 87, 66, 69, 82, 82, 89, 128, 83, 84, 82, 65, 84, 85, 77, 45, 50, 128, 83, + 84, 82, 65, 84, 85, 77, 128, 83, 84, 82, 65, 84, 85, 205, 83, 84, 82, 65, + 84, 73, 65, 206, 83, 84, 82, 65, 73, 78, 69, 82, 128, 83, 84, 82, 65, 73, + 71, 72, 84, 78, 69, 83, 83, 128, 83, 84, 82, 65, 73, 71, 72, 212, 83, 84, + 82, 65, 73, 70, 128, 83, 84, 82, 65, 71, 71, 73, 83, 77, 65, 84, 65, 128, + 83, 84, 79, 86, 69, 128, 83, 84, 79, 82, 69, 128, 83, 84, 79, 80, 87, 65, + 84, 67, 72, 128, 83, 84, 79, 80, 80, 73, 78, 71, 128, 83, 84, 79, 80, 80, + 65, 71, 69, 128, 83, 84, 79, 80, 128, 83, 84, 79, 208, 83, 84, 79, 78, + 69, 128, 83, 84, 79, 67, 75, 128, 83, 84, 79, 67, 203, 83, 84, 73, 82, + 82, 85, 208, 83, 84, 73, 77, 77, 69, 128, 83, 84, 73, 76, 204, 83, 84, + 73, 76, 197, 83, 84, 73, 71, 77, 65, 128, 83, 84, 69, 82, 69, 79, 128, + 83, 84, 69, 80, 128, 83, 84, 69, 78, 79, 71, 82, 65, 80, 72, 73, 195, 83, + 84, 69, 77, 128, 83, 84, 69, 65, 77, 73, 78, 199, 83, 84, 69, 65, 77, + 128, 83, 84, 69, 65, 205, 83, 84, 65, 86, 82, 79, 85, 128, 83, 84, 65, + 86, 82, 79, 83, 128, 83, 84, 65, 86, 82, 79, 211, 83, 84, 65, 85, 82, 79, + 83, 128, 83, 84, 65, 84, 85, 197, 83, 84, 65, 84, 73, 79, 78, 128, 83, + 84, 65, 84, 69, 82, 83, 128, 83, 84, 65, 84, 69, 128, 83, 84, 65, 82, + 212, 83, 84, 65, 82, 83, 128, 83, 84, 65, 82, 82, 69, 196, 83, 84, 65, + 82, 75, 128, 83, 84, 65, 82, 128, 83, 84, 65, 210, 83, 84, 65, 78, 68, + 83, 84, 73, 76, 76, 128, 83, 84, 65, 78, 68, 65, 82, 196, 83, 84, 65, 78, + 68, 128, 83, 84, 65, 78, 128, 83, 84, 65, 77, 80, 69, 196, 83, 84, 65, + 76, 76, 73, 79, 78, 128, 83, 84, 65, 70, 70, 128, 83, 84, 65, 70, 198, + 83, 84, 65, 68, 73, 85, 77, 128, 83, 84, 65, 67, 67, 65, 84, 79, 128, 83, + 84, 65, 67, 67, 65, 84, 73, 83, 83, 73, 77, 79, 128, 83, 84, 50, 128, 83, + 83, 89, 88, 128, 83, 83, 89, 84, 128, 83, 83, 89, 82, 88, 128, 83, 83, + 89, 82, 128, 83, 83, 89, 80, 128, 83, 83, 89, 128, 83, 83, 85, 88, 128, + 83, 83, 85, 85, 128, 83, 83, 85, 84, 128, 83, 83, 85, 80, 128, 83, 83, + 79, 88, 128, 83, 83, 79, 84, 128, 83, 83, 79, 80, 128, 83, 83, 79, 79, + 128, 83, 83, 79, 128, 83, 83, 73, 88, 128, 83, 83, 73, 84, 128, 83, 83, + 73, 80, 128, 83, 83, 73, 73, 128, 83, 83, 73, 69, 88, 128, 83, 83, 73, + 69, 80, 128, 83, 83, 73, 69, 128, 83, 83, 73, 128, 83, 83, 72, 73, 78, + 128, 83, 83, 72, 69, 128, 83, 83, 69, 88, 128, 83, 83, 69, 80, 128, 83, + 83, 69, 69, 128, 83, 83, 65, 88, 128, 83, 83, 65, 85, 128, 83, 83, 65, + 84, 128, 83, 83, 65, 80, 128, 83, 83, 65, 78, 71, 89, 69, 79, 82, 73, 78, + 72, 73, 69, 85, 72, 128, 83, 83, 65, 78, 71, 84, 73, 75, 69, 85, 84, 45, + 80, 73, 69, 85, 80, 128, 83, 83, 65, 78, 71, 84, 73, 75, 69, 85, 84, 128, + 83, 83, 65, 78, 71, 84, 72, 73, 69, 85, 84, 72, 128, 83, 83, 65, 78, 71, + 83, 73, 79, 83, 45, 84, 73, 75, 69, 85, 84, 128, 83, 83, 65, 78, 71, 83, + 73, 79, 83, 45, 80, 73, 69, 85, 80, 128, 83, 83, 65, 78, 71, 83, 73, 79, + 83, 45, 75, 73, 89, 69, 79, 75, 128, 83, 83, 65, 78, 71, 83, 73, 79, 83, + 128, 83, 83, 65, 78, 71, 82, 73, 69, 85, 76, 45, 75, 72, 73, 69, 85, 75, + 72, 128, 83, 83, 65, 78, 71, 82, 73, 69, 85, 76, 128, 83, 83, 65, 78, 71, + 80, 73, 69, 85, 80, 128, 83, 83, 65, 78, 71, 78, 73, 69, 85, 78, 128, 83, + 83, 65, 78, 71, 77, 73, 69, 85, 77, 128, 83, 83, 65, 78, 71, 75, 73, 89, + 69, 79, 75, 128, 83, 83, 65, 78, 71, 73, 69, 85, 78, 71, 128, 83, 83, 65, + 78, 71, 72, 73, 69, 85, 72, 128, 83, 83, 65, 78, 71, 67, 73, 69, 85, 67, + 45, 72, 73, 69, 85, 72, 128, 83, 83, 65, 78, 71, 67, 73, 69, 85, 67, 128, + 83, 83, 65, 78, 71, 65, 82, 65, 69, 65, 128, 83, 83, 65, 73, 128, 83, 83, + 65, 65, 128, 83, 83, 51, 128, 83, 83, 50, 128, 83, 82, 128, 83, 81, 85, + 73, 83, 200, 83, 81, 85, 73, 82, 82, 69, 204, 83, 81, 85, 73, 71, 71, 76, 197, 83, 81, 85, 65, 212, 83, 81, 85, 65, 82, 69, 83, 128, 83, 81, 85, - 65, 82, 69, 68, 128, 83, 81, 85, 65, 82, 69, 128, 83, 80, 87, 65, 128, - 83, 80, 85, 78, 71, 211, 83, 80, 82, 79, 85, 84, 128, 83, 80, 82, 73, 78, - 71, 83, 128, 83, 80, 82, 73, 78, 71, 128, 83, 80, 82, 69, 67, 72, 71, 69, - 83, 65, 78, 199, 83, 80, 79, 85, 84, 73, 78, 199, 83, 80, 79, 84, 128, - 83, 80, 79, 79, 78, 128, 83, 80, 76, 73, 84, 84, 73, 78, 199, 83, 80, 76, - 65, 83, 72, 73, 78, 199, 83, 80, 73, 82, 73, 84, 85, 211, 83, 80, 73, 82, - 73, 84, 128, 83, 80, 73, 82, 73, 212, 83, 80, 73, 82, 65, 78, 84, 128, - 83, 80, 73, 82, 65, 76, 128, 83, 80, 73, 82, 65, 204, 83, 80, 73, 68, 69, - 82, 217, 83, 80, 73, 67, 69, 128, 83, 80, 72, 69, 82, 73, 67, 65, 204, - 83, 80, 69, 83, 77, 73, 76, 207, 83, 80, 69, 69, 68, 66, 79, 65, 84, 128, - 83, 80, 69, 69, 67, 72, 128, 83, 80, 69, 69, 67, 200, 83, 80, 69, 67, 73, - 65, 76, 128, 83, 80, 69, 65, 82, 128, 83, 80, 69, 65, 75, 69, 82, 128, - 83, 80, 69, 65, 75, 69, 210, 83, 80, 69, 65, 75, 45, 78, 79, 45, 69, 86, - 73, 204, 83, 80, 65, 84, 72, 73, 128, 83, 80, 65, 82, 75, 76, 73, 78, - 199, 83, 80, 65, 82, 75, 76, 69, 83, 128, 83, 80, 65, 82, 75, 76, 69, 82, - 128, 83, 80, 65, 82, 75, 76, 69, 128, 83, 80, 65, 71, 72, 69, 84, 84, 73, - 128, 83, 80, 65, 68, 69, 83, 128, 83, 80, 65, 68, 197, 83, 80, 65, 67, - 73, 78, 199, 83, 80, 65, 67, 197, 83, 80, 65, 128, 83, 79, 89, 128, 83, - 79, 87, 73, 76, 207, 83, 79, 87, 128, 83, 79, 85, 84, 72, 69, 82, 206, - 83, 79, 85, 84, 72, 45, 83, 76, 65, 86, 69, 217, 83, 79, 85, 84, 200, 83, + 65, 82, 69, 68, 128, 83, 81, 85, 65, 82, 69, 128, 83, 80, 89, 128, 83, + 80, 87, 65, 128, 83, 80, 85, 78, 71, 211, 83, 80, 82, 79, 85, 84, 128, + 83, 80, 82, 73, 78, 71, 83, 128, 83, 80, 82, 73, 78, 71, 128, 83, 80, 82, + 69, 67, 72, 71, 69, 83, 65, 78, 199, 83, 80, 79, 85, 84, 73, 78, 199, 83, + 80, 79, 84, 128, 83, 80, 79, 82, 84, 211, 83, 80, 79, 79, 78, 128, 83, + 80, 76, 73, 84, 84, 73, 78, 199, 83, 80, 76, 65, 89, 69, 68, 128, 83, 80, + 76, 65, 83, 72, 73, 78, 199, 83, 80, 73, 82, 73, 84, 85, 211, 83, 80, 73, + 82, 73, 84, 128, 83, 80, 73, 82, 73, 212, 83, 80, 73, 82, 65, 78, 84, + 128, 83, 80, 73, 82, 65, 76, 128, 83, 80, 73, 82, 65, 204, 83, 80, 73, + 68, 69, 82, 217, 83, 80, 73, 68, 69, 82, 128, 83, 80, 73, 68, 69, 210, + 83, 80, 73, 67, 69, 128, 83, 80, 72, 69, 82, 73, 67, 65, 204, 83, 80, 69, + 83, 77, 73, 76, 207, 83, 80, 69, 69, 68, 66, 79, 65, 84, 128, 83, 80, 69, + 69, 67, 72, 128, 83, 80, 69, 69, 67, 200, 83, 80, 69, 67, 73, 65, 76, + 128, 83, 80, 69, 65, 82, 128, 83, 80, 69, 65, 75, 73, 78, 199, 83, 80, + 69, 65, 75, 69, 82, 128, 83, 80, 69, 65, 75, 69, 210, 83, 80, 69, 65, 75, + 45, 78, 79, 45, 69, 86, 73, 204, 83, 80, 65, 84, 72, 73, 128, 83, 80, 65, + 82, 75, 76, 73, 78, 199, 83, 80, 65, 82, 75, 76, 69, 83, 128, 83, 80, 65, + 82, 75, 76, 69, 82, 128, 83, 80, 65, 82, 75, 76, 69, 128, 83, 80, 65, 71, + 72, 69, 84, 84, 73, 128, 83, 80, 65, 68, 69, 83, 128, 83, 80, 65, 68, + 197, 83, 80, 65, 67, 73, 78, 199, 83, 80, 65, 67, 197, 83, 80, 65, 128, + 83, 79, 89, 128, 83, 79, 87, 73, 76, 207, 83, 79, 87, 128, 83, 79, 85, + 84, 72, 69, 82, 206, 83, 79, 85, 84, 72, 45, 83, 76, 65, 86, 69, 217, 83, 79, 85, 82, 67, 69, 128, 83, 79, 85, 78, 68, 128, 83, 79, 85, 78, 196, 83, 79, 85, 78, 65, 80, 128, 83, 79, 85, 128, 83, 79, 83, 128, 83, 79, 82, 193, 83, 79, 81, 128, 83, 79, 79, 206, 83, 79, 78, 74, 65, 77, 128, 83, 79, 78, 71, 128, 83, 79, 78, 128, 83, 79, 77, 80, 69, 78, 199, 83, 79, 77, 128, 83, 79, 76, 73, 68, 85, 83, 128, 83, 79, 76, 73, 68, 85, - 211, 83, 79, 72, 128, 83, 79, 71, 68, 73, 65, 206, 83, 79, 70, 84, 87, - 65, 82, 69, 45, 70, 85, 78, 67, 84, 73, 79, 206, 83, 79, 70, 84, 78, 69, - 83, 83, 128, 83, 79, 70, 212, 83, 79, 198, 83, 79, 67, 73, 69, 84, 89, - 128, 83, 79, 67, 67, 69, 210, 83, 79, 65, 80, 128, 83, 79, 65, 128, 83, - 207, 83, 78, 79, 87, 77, 65, 78, 128, 83, 78, 79, 87, 77, 65, 206, 83, - 78, 79, 87, 70, 76, 65, 75, 69, 128, 83, 78, 79, 87, 66, 79, 65, 82, 68, - 69, 82, 128, 83, 78, 79, 87, 128, 83, 78, 79, 85, 84, 128, 83, 78, 79, - 85, 212, 83, 78, 65, 208, 83, 78, 65, 75, 69, 128, 83, 78, 65, 75, 197, - 83, 78, 65, 73, 76, 128, 83, 78, 193, 83, 77, 79, 75, 73, 78, 199, 83, - 77, 73, 82, 75, 73, 78, 199, 83, 77, 73, 76, 73, 78, 199, 83, 77, 73, 76, - 69, 128, 83, 77, 69, 65, 82, 128, 83, 77, 65, 83, 200, 83, 77, 65, 76, - 76, 69, 210, 83, 77, 65, 76, 76, 128, 83, 76, 85, 82, 128, 83, 76, 79, - 87, 76, 89, 128, 83, 76, 79, 215, 83, 76, 79, 86, 79, 128, 83, 76, 79, - 212, 83, 76, 79, 80, 73, 78, 199, 83, 76, 79, 80, 69, 128, 83, 76, 73, - 78, 71, 128, 83, 76, 73, 68, 73, 78, 71, 128, 83, 76, 73, 67, 69, 128, - 83, 76, 73, 67, 197, 83, 76, 69, 69, 80, 217, 83, 76, 69, 69, 80, 73, 78, - 199, 83, 76, 65, 86, 79, 78, 73, 195, 83, 76, 65, 86, 69, 128, 83, 76, - 65, 83, 72, 128, 83, 76, 65, 83, 200, 83, 76, 65, 78, 84, 69, 196, 83, - 75, 87, 65, 128, 83, 75, 87, 128, 83, 75, 85, 76, 76, 128, 83, 75, 85, - 76, 204, 83, 75, 76, 73, 82, 79, 206, 83, 75, 73, 78, 128, 83, 75, 73, - 69, 82, 128, 83, 75, 201, 83, 75, 69, 87, 69, 196, 83, 75, 65, 84, 69, - 128, 83, 75, 128, 83, 74, 69, 128, 83, 73, 88, 84, 89, 45, 70, 79, 85, - 82, 84, 200, 83, 73, 88, 84, 89, 128, 83, 73, 88, 84, 217, 83, 73, 88, - 84, 72, 83, 128, 83, 73, 88, 84, 72, 211, 83, 73, 88, 84, 72, 128, 83, - 73, 88, 84, 69, 69, 78, 84, 72, 83, 128, 83, 73, 88, 84, 69, 69, 78, 84, - 72, 128, 83, 73, 88, 84, 69, 69, 78, 84, 200, 83, 73, 88, 84, 69, 69, 78, - 128, 83, 73, 88, 84, 69, 69, 206, 83, 73, 88, 45, 84, 72, 73, 82, 84, 89, - 128, 83, 73, 88, 45, 83, 84, 82, 73, 78, 199, 83, 73, 88, 45, 80, 69, 82, - 45, 69, 205, 83, 73, 88, 45, 76, 73, 78, 197, 83, 73, 216, 83, 73, 84, - 69, 128, 83, 73, 83, 65, 128, 83, 73, 82, 73, 78, 71, 85, 128, 83, 73, - 79, 83, 45, 84, 72, 73, 69, 85, 84, 72, 128, 83, 73, 79, 83, 45, 83, 83, - 65, 78, 71, 83, 73, 79, 83, 128, 83, 73, 79, 83, 45, 82, 73, 69, 85, 76, - 128, 83, 73, 79, 83, 45, 80, 73, 69, 85, 80, 45, 75, 73, 89, 69, 79, 75, - 128, 83, 73, 79, 83, 45, 80, 72, 73, 69, 85, 80, 72, 128, 83, 73, 79, 83, - 45, 80, 65, 78, 83, 73, 79, 83, 128, 83, 73, 79, 83, 45, 78, 73, 69, 85, - 78, 128, 83, 73, 79, 83, 45, 77, 73, 69, 85, 77, 128, 83, 73, 79, 83, 45, - 75, 72, 73, 69, 85, 75, 72, 128, 83, 73, 79, 83, 45, 75, 65, 80, 89, 69, - 79, 85, 78, 80, 73, 69, 85, 80, 128, 83, 73, 79, 83, 45, 73, 69, 85, 78, - 71, 128, 83, 73, 79, 83, 45, 72, 73, 69, 85, 72, 128, 83, 73, 79, 83, 45, - 67, 73, 69, 85, 67, 128, 83, 73, 79, 83, 45, 67, 72, 73, 69, 85, 67, 72, - 128, 83, 73, 79, 211, 83, 73, 78, 75, 73, 78, 71, 128, 83, 73, 78, 71, - 76, 69, 45, 83, 72, 73, 70, 84, 45, 51, 128, 83, 73, 78, 71, 76, 69, 45, - 83, 72, 73, 70, 84, 45, 50, 128, 83, 73, 78, 71, 76, 69, 45, 76, 73, 78, - 197, 83, 73, 78, 71, 76, 69, 128, 83, 73, 78, 71, 76, 197, 83, 73, 78, - 71, 65, 65, 84, 128, 83, 73, 78, 197, 83, 73, 78, 68, 72, 201, 83, 73, - 206, 83, 73, 77, 80, 76, 73, 70, 73, 69, 196, 83, 73, 77, 73, 76, 65, 82, - 128, 83, 73, 77, 73, 76, 65, 210, 83, 73, 77, 65, 78, 83, 73, 211, 83, - 73, 77, 65, 76, 85, 78, 71, 85, 206, 83, 73, 77, 65, 128, 83, 73, 76, 86, - 69, 82, 128, 83, 73, 76, 75, 128, 83, 73, 76, 73, 81, 85, 193, 83, 73, - 76, 72, 79, 85, 69, 84, 84, 69, 128, 83, 73, 76, 72, 79, 85, 69, 84, 84, - 197, 83, 73, 76, 65, 51, 128, 83, 73, 75, 73, 128, 83, 73, 75, 50, 128, - 83, 73, 75, 178, 83, 73, 71, 78, 83, 128, 83, 73, 71, 77, 65, 128, 83, - 73, 71, 77, 193, 83, 73, 71, 69, 204, 83, 73, 71, 52, 128, 83, 73, 71, - 180, 83, 73, 71, 128, 83, 73, 69, 69, 128, 83, 73, 68, 69, 87, 65, 89, - 211, 83, 73, 67, 75, 78, 69, 83, 83, 128, 83, 73, 67, 75, 76, 69, 128, - 83, 73, 66, 197, 83, 201, 83, 72, 89, 88, 128, 83, 72, 89, 84, 128, 83, - 72, 89, 82, 88, 128, 83, 72, 89, 82, 128, 83, 72, 89, 80, 128, 83, 72, - 89, 69, 128, 83, 72, 89, 65, 128, 83, 72, 89, 128, 83, 72, 87, 79, 89, - 128, 83, 72, 87, 79, 79, 128, 83, 72, 87, 79, 128, 83, 72, 87, 73, 73, - 128, 83, 72, 87, 73, 128, 83, 72, 87, 69, 128, 83, 72, 87, 65, 65, 128, - 83, 72, 87, 65, 128, 83, 72, 85, 88, 128, 83, 72, 85, 85, 128, 83, 72, - 85, 84, 128, 83, 72, 85, 82, 88, 128, 83, 72, 85, 82, 128, 83, 72, 85, - 80, 128, 83, 72, 85, 79, 88, 128, 83, 72, 85, 79, 80, 128, 83, 72, 85, - 79, 128, 83, 72, 85, 77, 128, 83, 72, 85, 70, 70, 76, 197, 83, 72, 85, - 69, 81, 128, 83, 72, 85, 69, 78, 83, 72, 85, 69, 84, 128, 83, 72, 85, 66, - 85, 82, 128, 83, 72, 85, 50, 128, 83, 72, 85, 178, 83, 72, 85, 128, 83, - 72, 213, 83, 72, 84, 65, 80, 73, 67, 128, 83, 72, 84, 65, 128, 83, 72, - 82, 73, 78, 69, 128, 83, 72, 82, 73, 77, 80, 128, 83, 72, 82, 73, 73, - 128, 83, 72, 79, 89, 128, 83, 72, 79, 88, 128, 83, 72, 79, 87, 69, 82, - 128, 83, 72, 79, 85, 76, 68, 69, 82, 69, 196, 83, 72, 79, 84, 128, 83, - 72, 79, 82, 84, 83, 128, 83, 72, 79, 82, 84, 211, 83, 72, 79, 82, 84, 69, - 78, 69, 82, 128, 83, 72, 79, 82, 84, 67, 65, 75, 69, 128, 83, 72, 79, 82, - 84, 45, 84, 87, 73, 71, 45, 89, 82, 128, 83, 72, 79, 82, 84, 45, 84, 87, - 73, 71, 45, 84, 89, 210, 83, 72, 79, 82, 84, 45, 84, 87, 73, 71, 45, 83, - 79, 204, 83, 72, 79, 82, 84, 45, 84, 87, 73, 71, 45, 79, 83, 211, 83, 72, - 79, 82, 84, 45, 84, 87, 73, 71, 45, 78, 65, 85, 196, 83, 72, 79, 82, 84, - 45, 84, 87, 73, 71, 45, 77, 65, 68, 210, 83, 72, 79, 82, 84, 45, 84, 87, - 73, 71, 45, 72, 65, 71, 65, 76, 204, 83, 72, 79, 82, 84, 45, 84, 87, 73, - 71, 45, 66, 74, 65, 82, 75, 65, 206, 83, 72, 79, 82, 84, 45, 84, 87, 73, - 71, 45, 65, 210, 83, 72, 79, 82, 84, 128, 83, 72, 79, 82, 212, 83, 72, - 79, 81, 128, 83, 72, 79, 209, 83, 72, 79, 80, 128, 83, 72, 79, 79, 84, - 73, 78, 199, 83, 72, 79, 79, 84, 128, 83, 72, 79, 79, 128, 83, 72, 79, - 71, 201, 83, 72, 79, 199, 83, 72, 79, 69, 128, 83, 72, 79, 197, 83, 72, - 79, 65, 128, 83, 72, 79, 128, 83, 72, 73, 89, 89, 65, 65, 76, 65, 65, - 128, 83, 72, 73, 84, 65, 128, 83, 72, 73, 84, 193, 83, 72, 73, 82, 212, - 83, 72, 73, 82, 65, 69, 128, 83, 72, 73, 82, 128, 83, 72, 73, 210, 83, - 72, 73, 81, 128, 83, 72, 73, 80, 128, 83, 72, 73, 78, 84, 207, 83, 72, - 73, 78, 73, 71, 128, 83, 72, 73, 78, 68, 193, 83, 72, 73, 78, 128, 83, - 72, 73, 206, 83, 72, 73, 77, 65, 128, 83, 72, 73, 77, 193, 83, 72, 73, - 77, 128, 83, 72, 73, 205, 83, 72, 73, 73, 78, 128, 83, 72, 73, 73, 128, - 83, 72, 73, 70, 212, 83, 72, 73, 69, 76, 68, 128, 83, 72, 73, 68, 128, - 83, 72, 73, 196, 83, 72, 72, 65, 128, 83, 72, 72, 193, 83, 72, 69, 88, - 128, 83, 72, 69, 86, 65, 128, 83, 72, 69, 85, 88, 128, 83, 72, 69, 85, - 79, 81, 128, 83, 72, 69, 85, 65, 69, 81, 84, 85, 128, 83, 72, 69, 85, 65, - 69, 81, 128, 83, 72, 69, 85, 65, 69, 128, 83, 72, 69, 84, 128, 83, 72, - 69, 212, 83, 72, 69, 83, 72, 76, 65, 77, 128, 83, 72, 69, 83, 72, 73, 71, - 128, 83, 72, 69, 83, 72, 73, 199, 83, 72, 69, 83, 72, 50, 128, 83, 72, - 69, 83, 72, 128, 83, 72, 69, 81, 69, 204, 83, 72, 69, 80, 128, 83, 72, - 69, 78, 128, 83, 72, 69, 76, 76, 128, 83, 72, 69, 76, 204, 83, 72, 69, - 76, 70, 128, 83, 72, 69, 73, 128, 83, 72, 69, 71, 57, 128, 83, 72, 69, - 69, 80, 128, 83, 72, 69, 69, 78, 85, 128, 83, 72, 69, 69, 78, 128, 83, - 72, 69, 69, 206, 83, 72, 69, 69, 128, 83, 72, 69, 45, 71, 79, 65, 84, - 128, 83, 72, 197, 83, 72, 67, 72, 65, 128, 83, 72, 65, 89, 128, 83, 72, - 65, 88, 128, 83, 72, 65, 86, 73, 89, 65, 78, 73, 128, 83, 72, 65, 86, 73, - 65, 206, 83, 72, 65, 86, 69, 196, 83, 72, 65, 85, 128, 83, 72, 65, 84, - 128, 83, 72, 65, 82, 85, 128, 83, 72, 65, 82, 213, 83, 72, 65, 82, 80, - 128, 83, 72, 65, 82, 208, 83, 72, 65, 82, 65, 128, 83, 72, 65, 82, 50, - 128, 83, 72, 65, 82, 178, 83, 72, 65, 80, 73, 78, 71, 128, 83, 72, 65, - 80, 69, 83, 128, 83, 72, 65, 80, 197, 83, 72, 65, 80, 128, 83, 72, 65, - 78, 71, 128, 83, 72, 65, 78, 128, 83, 72, 65, 206, 83, 72, 65, 77, 82, - 79, 67, 75, 128, 83, 72, 65, 76, 83, 72, 69, 76, 69, 84, 128, 83, 72, 65, - 75, 84, 73, 128, 83, 72, 65, 73, 128, 83, 72, 65, 68, 79, 87, 69, 196, - 83, 72, 65, 68, 69, 128, 83, 72, 65, 68, 68, 65, 128, 83, 72, 65, 68, 68, - 193, 83, 72, 65, 68, 128, 83, 72, 65, 196, 83, 72, 65, 66, 54, 128, 83, - 72, 65, 65, 128, 83, 72, 65, 54, 128, 83, 72, 65, 51, 128, 83, 72, 65, - 179, 83, 71, 82, 193, 83, 71, 79, 210, 83, 71, 67, 128, 83, 71, 65, 215, - 83, 71, 65, 194, 83, 71, 128, 83, 69, 88, 84, 85, 76, 193, 83, 69, 88, - 84, 73, 76, 69, 128, 83, 69, 88, 84, 65, 78, 211, 83, 69, 86, 69, 82, 65, - 78, 67, 69, 128, 83, 69, 86, 69, 78, 84, 89, 128, 83, 69, 86, 69, 78, 84, - 217, 83, 69, 86, 69, 78, 84, 72, 128, 83, 69, 86, 69, 78, 84, 69, 69, 78, - 128, 83, 69, 86, 69, 78, 84, 69, 69, 206, 83, 69, 86, 69, 78, 45, 84, 72, - 73, 82, 84, 89, 128, 83, 69, 86, 69, 206, 83, 69, 85, 88, 128, 83, 69, - 85, 78, 89, 65, 77, 128, 83, 69, 85, 65, 69, 81, 128, 83, 69, 84, 70, 79, - 78, 128, 83, 69, 83, 84, 69, 82, 84, 73, 85, 211, 83, 69, 83, 81, 85, 73, - 81, 85, 65, 68, 82, 65, 84, 69, 128, 83, 69, 83, 65, 77, 197, 83, 69, 82, - 86, 73, 67, 197, 83, 69, 82, 73, 70, 83, 128, 83, 69, 82, 73, 70, 211, - 83, 69, 81, 85, 69, 78, 67, 197, 83, 69, 80, 84, 69, 77, 66, 69, 82, 128, - 83, 69, 80, 65, 82, 65, 84, 79, 82, 128, 83, 69, 80, 65, 82, 65, 84, 79, - 210, 83, 69, 78, 84, 79, 128, 83, 69, 78, 84, 73, 128, 83, 69, 77, 85, - 78, 67, 73, 193, 83, 69, 77, 75, 65, 84, 72, 128, 83, 69, 77, 75, 128, - 83, 69, 77, 73, 86, 79, 87, 69, 204, 83, 69, 77, 73, 83, 79, 70, 212, 83, - 69, 77, 73, 83, 69, 88, 84, 73, 76, 69, 128, 83, 69, 77, 73, 77, 73, 78, - 73, 77, 193, 83, 69, 77, 73, 68, 73, 82, 69, 67, 212, 83, 69, 77, 73, 67, - 79, 76, 79, 78, 128, 83, 69, 77, 73, 67, 79, 76, 79, 206, 83, 69, 77, 73, - 67, 73, 82, 67, 85, 76, 65, 210, 83, 69, 77, 73, 67, 73, 82, 67, 76, 197, - 83, 69, 77, 73, 66, 82, 69, 86, 73, 211, 83, 69, 77, 73, 45, 86, 79, 73, - 67, 69, 196, 83, 69, 76, 70, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 57, - 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 57, 56, 128, 83, 69, 76, 69, - 67, 84, 79, 82, 45, 57, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 57, - 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 57, 53, 128, 83, 69, 76, 69, - 67, 84, 79, 82, 45, 57, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 57, - 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 57, 50, 128, 83, 69, 76, 69, - 67, 84, 79, 82, 45, 57, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 57, - 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 57, 128, 83, 69, 76, 69, 67, - 84, 79, 82, 45, 56, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 56, 56, - 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 56, 55, 128, 83, 69, 76, 69, 67, - 84, 79, 82, 45, 56, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 56, 53, - 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 56, 52, 128, 83, 69, 76, 69, 67, - 84, 79, 82, 45, 56, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 56, 50, - 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 56, 49, 128, 83, 69, 76, 69, 67, - 84, 79, 82, 45, 56, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 56, 128, - 83, 69, 76, 69, 67, 84, 79, 82, 45, 55, 57, 128, 83, 69, 76, 69, 67, 84, - 79, 82, 45, 55, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 55, 55, 128, - 83, 69, 76, 69, 67, 84, 79, 82, 45, 55, 54, 128, 83, 69, 76, 69, 67, 84, - 79, 82, 45, 55, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 55, 52, 128, - 83, 69, 76, 69, 67, 84, 79, 82, 45, 55, 51, 128, 83, 69, 76, 69, 67, 84, - 79, 82, 45, 55, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 55, 49, 128, - 83, 69, 76, 69, 67, 84, 79, 82, 45, 55, 48, 128, 83, 69, 76, 69, 67, 84, - 79, 82, 45, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 54, 57, 128, 83, - 69, 76, 69, 67, 84, 79, 82, 45, 54, 56, 128, 83, 69, 76, 69, 67, 84, 79, - 82, 45, 54, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 54, 54, 128, 83, - 69, 76, 69, 67, 84, 79, 82, 45, 54, 53, 128, 83, 69, 76, 69, 67, 84, 79, - 82, 45, 54, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 54, 51, 128, 83, - 69, 76, 69, 67, 84, 79, 82, 45, 54, 50, 128, 83, 69, 76, 69, 67, 84, 79, - 82, 45, 54, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 54, 48, 128, 83, - 69, 76, 69, 67, 84, 79, 82, 45, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, - 45, 53, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 53, 56, 128, 83, 69, - 76, 69, 67, 84, 79, 82, 45, 53, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, - 45, 53, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 53, 53, 128, 83, 69, - 76, 69, 67, 84, 79, 82, 45, 53, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, - 45, 53, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 53, 50, 128, 83, 69, - 76, 69, 67, 84, 79, 82, 45, 53, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, - 45, 53, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 53, 128, 83, 69, 76, - 69, 67, 84, 79, 82, 45, 52, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, - 52, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 52, 55, 128, 83, 69, 76, - 69, 67, 84, 79, 82, 45, 52, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, - 52, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 52, 52, 128, 83, 69, 76, - 69, 67, 84, 79, 82, 45, 52, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, - 52, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 52, 49, 128, 83, 69, 76, - 69, 67, 84, 79, 82, 45, 52, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, - 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 51, 57, 128, 83, 69, 76, 69, - 67, 84, 79, 82, 45, 51, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 51, - 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 51, 54, 128, 83, 69, 76, 69, - 67, 84, 79, 82, 45, 51, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 51, - 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 51, 51, 128, 83, 69, 76, 69, - 67, 84, 79, 82, 45, 51, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 51, - 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 51, 48, 128, 83, 69, 76, 69, - 67, 84, 79, 82, 45, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 57, - 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 56, 128, 83, 69, 76, 69, 67, - 84, 79, 82, 45, 50, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 54, - 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 53, 54, 128, 83, 69, 76, 69, - 67, 84, 79, 82, 45, 50, 53, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, - 50, 53, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 53, 51, 128, 83, - 69, 76, 69, 67, 84, 79, 82, 45, 50, 53, 50, 128, 83, 69, 76, 69, 67, 84, - 79, 82, 45, 50, 53, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 53, - 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 53, 128, 83, 69, 76, 69, - 67, 84, 79, 82, 45, 50, 52, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, - 50, 52, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 52, 55, 128, 83, - 69, 76, 69, 67, 84, 79, 82, 45, 50, 52, 54, 128, 83, 69, 76, 69, 67, 84, - 79, 82, 45, 50, 52, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 52, - 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 52, 51, 128, 83, 69, 76, - 69, 67, 84, 79, 82, 45, 50, 52, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, - 45, 50, 52, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 52, 48, 128, - 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 52, 128, 83, 69, 76, 69, 67, 84, - 79, 82, 45, 50, 51, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 51, - 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 51, 55, 128, 83, 69, 76, - 69, 67, 84, 79, 82, 45, 50, 51, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, - 45, 50, 51, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 51, 52, 128, - 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 51, 51, 128, 83, 69, 76, 69, 67, - 84, 79, 82, 45, 50, 51, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, - 51, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 51, 48, 128, 83, 69, - 76, 69, 67, 84, 79, 82, 45, 50, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, - 45, 50, 50, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 50, 56, 128, - 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 50, 55, 128, 83, 69, 76, 69, 67, - 84, 79, 82, 45, 50, 50, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, - 50, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 50, 52, 128, 83, 69, - 76, 69, 67, 84, 79, 82, 45, 50, 50, 51, 128, 83, 69, 76, 69, 67, 84, 79, - 82, 45, 50, 50, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 50, 49, - 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 50, 48, 128, 83, 69, 76, 69, - 67, 84, 79, 82, 45, 50, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, - 49, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 49, 56, 128, 83, 69, - 76, 69, 67, 84, 79, 82, 45, 50, 49, 55, 128, 83, 69, 76, 69, 67, 84, 79, - 82, 45, 50, 49, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 49, 53, - 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 49, 52, 128, 83, 69, 76, 69, - 67, 84, 79, 82, 45, 50, 49, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, - 50, 49, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 49, 49, 128, 83, - 69, 76, 69, 67, 84, 79, 82, 45, 50, 49, 48, 128, 83, 69, 76, 69, 67, 84, - 79, 82, 45, 50, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 48, 57, - 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 48, 56, 128, 83, 69, 76, 69, - 67, 84, 79, 82, 45, 50, 48, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, - 50, 48, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 48, 53, 128, 83, - 69, 76, 69, 67, 84, 79, 82, 45, 50, 48, 52, 128, 83, 69, 76, 69, 67, 84, - 79, 82, 45, 50, 48, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 48, - 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 48, 49, 128, 83, 69, 76, - 69, 67, 84, 79, 82, 45, 50, 48, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, - 45, 50, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 128, 83, 69, 76, - 69, 67, 84, 79, 82, 45, 49, 57, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, - 45, 49, 57, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 57, 55, 128, - 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 57, 54, 128, 83, 69, 76, 69, 67, - 84, 79, 82, 45, 49, 57, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, - 57, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 57, 51, 128, 83, 69, - 76, 69, 67, 84, 79, 82, 45, 49, 57, 50, 128, 83, 69, 76, 69, 67, 84, 79, - 82, 45, 49, 57, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 57, 48, - 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 57, 128, 83, 69, 76, 69, 67, - 84, 79, 82, 45, 49, 56, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, - 56, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 56, 55, 128, 83, 69, - 76, 69, 67, 84, 79, 82, 45, 49, 56, 54, 128, 83, 69, 76, 69, 67, 84, 79, - 82, 45, 49, 56, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 56, 52, - 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 56, 51, 128, 83, 69, 76, 69, - 67, 84, 79, 82, 45, 49, 56, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, - 49, 56, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 56, 48, 128, 83, - 69, 76, 69, 67, 84, 79, 82, 45, 49, 56, 128, 83, 69, 76, 69, 67, 84, 79, - 82, 45, 49, 55, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 55, 56, - 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 55, 55, 128, 83, 69, 76, 69, - 67, 84, 79, 82, 45, 49, 55, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, - 49, 55, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 55, 52, 128, 83, - 69, 76, 69, 67, 84, 79, 82, 45, 49, 55, 51, 128, 83, 69, 76, 69, 67, 84, - 79, 82, 45, 49, 55, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 55, - 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 55, 48, 128, 83, 69, 76, - 69, 67, 84, 79, 82, 45, 49, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, - 49, 54, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 54, 56, 128, 83, - 69, 76, 69, 67, 84, 79, 82, 45, 49, 54, 55, 128, 83, 69, 76, 69, 67, 84, - 79, 82, 45, 49, 54, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 54, - 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 54, 52, 128, 83, 69, 76, - 69, 67, 84, 79, 82, 45, 49, 54, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, - 45, 49, 54, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 54, 49, 128, - 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 54, 48, 128, 83, 69, 76, 69, 67, - 84, 79, 82, 45, 49, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 53, - 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 53, 56, 128, 83, 69, 76, - 69, 67, 84, 79, 82, 45, 49, 53, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, - 45, 49, 53, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 53, 53, 128, - 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 53, 52, 128, 83, 69, 76, 69, 67, - 84, 79, 82, 45, 49, 53, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, - 53, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 53, 49, 128, 83, 69, - 76, 69, 67, 84, 79, 82, 45, 49, 53, 48, 128, 83, 69, 76, 69, 67, 84, 79, - 82, 45, 49, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 52, 57, 128, - 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 52, 56, 128, 83, 69, 76, 69, 67, - 84, 79, 82, 45, 49, 52, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, - 52, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 52, 53, 128, 83, 69, - 76, 69, 67, 84, 79, 82, 45, 49, 52, 52, 128, 83, 69, 76, 69, 67, 84, 79, - 82, 45, 49, 52, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 52, 50, - 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 52, 49, 128, 83, 69, 76, 69, - 67, 84, 79, 82, 45, 49, 52, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, - 49, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 51, 57, 128, 83, 69, - 76, 69, 67, 84, 79, 82, 45, 49, 51, 56, 128, 83, 69, 76, 69, 67, 84, 79, - 82, 45, 49, 51, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 51, 54, - 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 51, 53, 128, 83, 69, 76, 69, - 67, 84, 79, 82, 45, 49, 51, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, - 49, 51, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 51, 50, 128, 83, - 69, 76, 69, 67, 84, 79, 82, 45, 49, 51, 49, 128, 83, 69, 76, 69, 67, 84, - 79, 82, 45, 49, 51, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 51, - 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 50, 57, 128, 83, 69, 76, 69, - 67, 84, 79, 82, 45, 49, 50, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, - 49, 50, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 50, 54, 128, 83, - 69, 76, 69, 67, 84, 79, 82, 45, 49, 50, 53, 128, 83, 69, 76, 69, 67, 84, - 79, 82, 45, 49, 50, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 50, - 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 50, 50, 128, 83, 69, 76, - 69, 67, 84, 79, 82, 45, 49, 50, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, - 45, 49, 50, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 50, 128, 83, - 69, 76, 69, 67, 84, 79, 82, 45, 49, 49, 57, 128, 83, 69, 76, 69, 67, 84, - 79, 82, 45, 49, 49, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 49, - 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 49, 54, 128, 83, 69, 76, - 69, 67, 84, 79, 82, 45, 49, 49, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, - 45, 49, 49, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 49, 51, 128, - 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 49, 50, 128, 83, 69, 76, 69, 67, - 84, 79, 82, 45, 49, 49, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, - 49, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 49, 128, 83, 69, 76, - 69, 67, 84, 79, 82, 45, 49, 48, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, - 45, 49, 48, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 48, 55, 128, - 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 48, 54, 128, 83, 69, 76, 69, 67, - 84, 79, 82, 45, 49, 48, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, - 48, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 48, 51, 128, 83, 69, - 76, 69, 67, 84, 79, 82, 45, 49, 48, 50, 128, 83, 69, 76, 69, 67, 84, 79, - 82, 45, 49, 48, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 48, 48, - 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 48, 128, 83, 69, 76, 69, 67, - 84, 79, 82, 45, 49, 128, 83, 69, 76, 69, 67, 84, 79, 210, 83, 69, 76, 69, - 67, 84, 69, 196, 83, 69, 73, 83, 77, 65, 128, 83, 69, 73, 83, 77, 193, - 83, 69, 72, 128, 83, 69, 71, 79, 76, 128, 83, 69, 71, 78, 79, 128, 83, - 69, 71, 77, 69, 78, 84, 128, 83, 69, 69, 78, 85, 128, 83, 69, 69, 78, - 128, 83, 69, 69, 206, 83, 69, 69, 68, 76, 73, 78, 71, 128, 83, 69, 69, - 45, 78, 79, 45, 69, 86, 73, 204, 83, 69, 67, 84, 79, 82, 128, 83, 69, 67, - 84, 73, 79, 78, 128, 83, 69, 67, 84, 73, 79, 206, 83, 69, 67, 82, 69, 84, - 128, 83, 69, 67, 79, 78, 68, 128, 83, 69, 66, 65, 84, 66, 69, 73, 212, - 83, 69, 65, 84, 128, 83, 69, 65, 76, 128, 83, 69, 65, 71, 85, 76, 204, - 83, 68, 79, 78, 199, 83, 68, 128, 83, 67, 87, 65, 128, 83, 67, 82, 85, - 80, 76, 69, 128, 83, 67, 82, 79, 76, 76, 128, 83, 67, 82, 73, 80, 84, - 128, 83, 67, 82, 69, 69, 78, 128, 83, 67, 82, 69, 69, 206, 83, 67, 82, - 69, 65, 77, 73, 78, 199, 83, 67, 79, 82, 80, 73, 85, 83, 128, 83, 67, 79, - 82, 69, 128, 83, 67, 73, 83, 83, 79, 82, 83, 128, 83, 67, 73, 128, 83, - 67, 72, 87, 65, 128, 83, 67, 72, 87, 193, 83, 67, 72, 82, 79, 69, 68, 69, - 82, 128, 83, 67, 72, 79, 79, 76, 128, 83, 67, 72, 79, 79, 204, 83, 67, - 72, 79, 76, 65, 82, 128, 83, 67, 72, 69, 77, 193, 83, 67, 69, 80, 84, 69, - 210, 83, 67, 65, 78, 68, 73, 67, 85, 83, 128, 83, 67, 65, 78, 68, 73, 67, - 85, 211, 83, 67, 65, 206, 83, 67, 65, 76, 69, 83, 128, 83, 66, 85, 194, - 83, 66, 82, 85, 204, 83, 65, 89, 73, 83, 201, 83, 65, 89, 65, 78, 78, 65, - 128, 83, 65, 89, 128, 83, 65, 88, 79, 80, 72, 79, 78, 69, 128, 83, 65, - 88, 73, 77, 65, 84, 65, 128, 83, 65, 87, 65, 78, 128, 83, 65, 87, 128, - 83, 65, 86, 79, 85, 82, 73, 78, 199, 83, 65, 85, 73, 76, 128, 83, 65, 84, - 85, 82, 78, 128, 83, 65, 84, 75, 65, 65, 78, 75, 85, 85, 128, 83, 65, 84, - 75, 65, 65, 78, 128, 83, 65, 84, 69, 76, 76, 73, 84, 197, 83, 65, 84, 67, - 72, 69, 76, 128, 83, 65, 84, 65, 78, 71, 65, 128, 83, 65, 83, 72, 128, - 83, 65, 83, 65, 75, 128, 83, 65, 82, 73, 128, 83, 65, 82, 193, 83, 65, - 82, 128, 83, 65, 81, 128, 83, 65, 80, 65, 128, 83, 65, 78, 89, 79, 79, - 71, 193, 83, 65, 78, 89, 65, 75, 193, 83, 65, 78, 84, 73, 73, 77, 85, - 128, 83, 65, 78, 78, 89, 65, 128, 83, 65, 78, 71, 65, 50, 128, 83, 65, - 78, 68, 65, 76, 128, 83, 65, 78, 65, 72, 128, 83, 65, 78, 128, 83, 65, - 77, 89, 79, 203, 83, 65, 77, 86, 65, 84, 128, 83, 65, 77, 80, 73, 128, - 83, 65, 77, 80, 72, 65, 79, 128, 83, 65, 77, 75, 65, 128, 83, 65, 77, 69, - 75, 72, 128, 83, 65, 77, 69, 75, 200, 83, 65, 77, 66, 65, 128, 83, 65, - 77, 65, 82, 73, 84, 65, 206, 83, 65, 77, 128, 83, 65, 76, 84, 73, 82, 69, - 128, 83, 65, 76, 84, 73, 76, 76, 79, 128, 83, 65, 76, 84, 45, 50, 128, - 83, 65, 76, 84, 128, 83, 65, 76, 212, 83, 65, 76, 76, 65, 76, 76, 65, 72, - 79, 213, 83, 65, 76, 76, 193, 83, 65, 76, 65, 205, 83, 65, 76, 65, 128, - 83, 65, 76, 45, 65, 77, 77, 79, 78, 73, 65, 67, 128, 83, 65, 76, 128, 83, - 65, 75, 79, 84, 128, 83, 65, 75, 69, 85, 65, 69, 128, 83, 65, 75, 197, - 83, 65, 74, 68, 65, 72, 128, 83, 65, 73, 76, 66, 79, 65, 84, 128, 83, 65, - 73, 76, 128, 83, 65, 73, 75, 85, 82, 85, 128, 83, 65, 72, 128, 83, 65, - 71, 73, 84, 84, 65, 82, 73, 85, 83, 128, 83, 65, 71, 65, 128, 83, 65, 71, - 128, 83, 65, 199, 83, 65, 70, 72, 65, 128, 83, 65, 68, 72, 69, 128, 83, - 65, 68, 69, 128, 83, 65, 68, 128, 83, 65, 196, 83, 65, 67, 82, 73, 70, - 73, 67, 73, 65, 204, 83, 65, 65, 73, 128, 83, 65, 65, 68, 72, 85, 128, - 83, 65, 45, 73, 128, 83, 65, 45, 50, 128, 83, 48, 52, 54, 128, 83, 48, - 52, 53, 128, 83, 48, 52, 52, 128, 83, 48, 52, 51, 128, 83, 48, 52, 50, - 128, 83, 48, 52, 49, 128, 83, 48, 52, 48, 128, 83, 48, 51, 57, 128, 83, - 48, 51, 56, 128, 83, 48, 51, 55, 128, 83, 48, 51, 54, 128, 83, 48, 51, - 53, 65, 128, 83, 48, 51, 53, 128, 83, 48, 51, 52, 128, 83, 48, 51, 51, - 128, 83, 48, 51, 50, 128, 83, 48, 51, 49, 128, 83, 48, 51, 48, 128, 83, - 48, 50, 57, 128, 83, 48, 50, 56, 128, 83, 48, 50, 55, 128, 83, 48, 50, - 54, 66, 128, 83, 48, 50, 54, 65, 128, 83, 48, 50, 54, 128, 83, 48, 50, - 53, 128, 83, 48, 50, 52, 128, 83, 48, 50, 51, 128, 83, 48, 50, 50, 128, - 83, 48, 50, 49, 128, 83, 48, 50, 48, 128, 83, 48, 49, 57, 128, 83, 48, - 49, 56, 128, 83, 48, 49, 55, 65, 128, 83, 48, 49, 55, 128, 83, 48, 49, - 54, 128, 83, 48, 49, 53, 128, 83, 48, 49, 52, 66, 128, 83, 48, 49, 52, - 65, 128, 83, 48, 49, 52, 128, 83, 48, 49, 51, 128, 83, 48, 49, 50, 128, - 83, 48, 49, 49, 128, 83, 48, 49, 48, 128, 83, 48, 48, 57, 128, 83, 48, - 48, 56, 128, 83, 48, 48, 55, 128, 83, 48, 48, 54, 65, 128, 83, 48, 48, - 54, 128, 83, 48, 48, 53, 128, 83, 48, 48, 52, 128, 83, 48, 48, 51, 128, - 83, 48, 48, 50, 65, 128, 83, 48, 48, 50, 128, 83, 48, 48, 49, 128, 83, - 45, 87, 128, 83, 45, 83, 72, 65, 80, 69, 196, 82, 89, 89, 128, 82, 89, - 88, 128, 82, 89, 84, 128, 82, 89, 82, 88, 128, 82, 89, 82, 128, 82, 89, - 80, 128, 82, 87, 79, 79, 128, 82, 87, 79, 128, 82, 87, 73, 73, 128, 82, - 87, 73, 128, 82, 87, 69, 69, 128, 82, 87, 69, 128, 82, 87, 65, 72, 65, - 128, 82, 87, 65, 65, 128, 82, 87, 65, 128, 82, 85, 88, 128, 82, 85, 85, - 66, 85, 82, 85, 128, 82, 85, 85, 128, 82, 85, 84, 128, 82, 85, 83, 73, - 128, 82, 85, 82, 88, 128, 82, 85, 82, 128, 82, 85, 80, 73, 73, 128, 82, - 85, 80, 69, 197, 82, 85, 80, 128, 82, 85, 79, 88, 128, 82, 85, 79, 80, - 128, 82, 85, 79, 128, 82, 85, 78, 79, 85, 84, 128, 82, 85, 78, 78, 73, - 78, 199, 82, 85, 78, 78, 69, 82, 128, 82, 85, 78, 128, 82, 85, 77, 201, - 82, 85, 77, 65, 201, 82, 85, 77, 128, 82, 85, 205, 82, 85, 76, 69, 82, - 128, 82, 85, 76, 69, 45, 68, 69, 76, 65, 89, 69, 68, 128, 82, 85, 76, 69, - 128, 82, 85, 75, 75, 65, 75, 72, 65, 128, 82, 85, 73, 83, 128, 82, 85, - 71, 66, 217, 82, 85, 194, 82, 85, 65, 128, 82, 84, 72, 65, 78, 199, 82, - 84, 65, 71, 83, 128, 82, 84, 65, 71, 211, 82, 82, 89, 88, 128, 82, 82, - 89, 84, 128, 82, 82, 89, 82, 88, 128, 82, 82, 89, 82, 128, 82, 82, 89, - 80, 128, 82, 82, 85, 88, 128, 82, 82, 85, 85, 128, 82, 82, 85, 84, 128, - 82, 82, 85, 82, 88, 128, 82, 82, 85, 82, 128, 82, 82, 85, 80, 128, 82, - 82, 85, 79, 88, 128, 82, 82, 85, 79, 128, 82, 82, 85, 128, 82, 82, 79, - 88, 128, 82, 82, 79, 84, 128, 82, 82, 79, 80, 128, 82, 82, 79, 79, 128, - 82, 82, 79, 128, 82, 82, 73, 73, 128, 82, 82, 73, 128, 82, 82, 69, 88, - 128, 82, 82, 69, 84, 128, 82, 82, 69, 80, 128, 82, 82, 69, 72, 128, 82, - 82, 69, 200, 82, 82, 69, 69, 128, 82, 82, 69, 128, 82, 82, 65, 88, 128, - 82, 82, 65, 85, 128, 82, 82, 65, 73, 128, 82, 82, 65, 65, 128, 82, 82, - 65, 128, 82, 79, 87, 66, 79, 65, 84, 128, 82, 79, 85, 78, 68, 69, 196, - 82, 79, 85, 78, 68, 45, 84, 73, 80, 80, 69, 196, 82, 79, 84, 85, 78, 68, - 65, 128, 82, 79, 84, 65, 84, 69, 196, 82, 79, 83, 72, 128, 82, 79, 83, - 69, 84, 84, 69, 128, 82, 79, 83, 69, 128, 82, 79, 79, 84, 128, 82, 79, - 79, 83, 84, 69, 82, 128, 82, 79, 79, 75, 128, 82, 79, 79, 70, 128, 82, - 79, 77, 65, 206, 82, 79, 77, 128, 82, 79, 76, 76, 69, 210, 82, 79, 72, - 73, 78, 71, 89, 193, 82, 79, 196, 82, 79, 67, 75, 69, 84, 128, 82, 79, - 67, 203, 82, 79, 67, 128, 82, 79, 66, 65, 84, 128, 82, 79, 65, 83, 84, - 69, 196, 82, 79, 65, 82, 128, 82, 79, 65, 128, 82, 78, 89, 73, 78, 199, - 82, 78, 79, 79, 78, 128, 82, 78, 79, 79, 206, 82, 78, 65, 205, 82, 77, - 84, 128, 82, 76, 79, 128, 82, 76, 77, 128, 82, 76, 73, 128, 82, 76, 69, - 128, 82, 74, 69, 211, 82, 74, 69, 128, 82, 74, 197, 82, 73, 86, 69, 82, - 128, 82, 73, 84, 85, 65, 76, 128, 82, 73, 84, 84, 79, 82, 85, 128, 82, - 73, 84, 83, 73, 128, 82, 73, 83, 73, 78, 199, 82, 73, 83, 72, 128, 82, - 73, 82, 65, 128, 82, 73, 80, 128, 82, 73, 78, 71, 211, 82, 73, 78, 70, - 79, 82, 90, 65, 78, 68, 79, 128, 82, 73, 206, 82, 73, 77, 71, 66, 65, + 211, 83, 79, 76, 73, 196, 83, 79, 72, 128, 83, 79, 71, 68, 73, 65, 206, + 83, 79, 70, 84, 87, 65, 82, 69, 45, 70, 85, 78, 67, 84, 73, 79, 206, 83, + 79, 70, 84, 78, 69, 83, 83, 128, 83, 79, 70, 212, 83, 79, 198, 83, 79, + 67, 73, 69, 84, 89, 128, 83, 79, 67, 67, 69, 210, 83, 79, 65, 80, 128, + 83, 79, 65, 128, 83, 207, 83, 78, 79, 87, 77, 65, 78, 128, 83, 78, 79, + 87, 77, 65, 206, 83, 78, 79, 87, 70, 76, 65, 75, 69, 128, 83, 78, 79, 87, + 66, 79, 65, 82, 68, 69, 82, 128, 83, 78, 79, 87, 128, 83, 78, 79, 215, + 83, 78, 79, 85, 84, 128, 83, 78, 79, 85, 212, 83, 78, 65, 208, 83, 78, + 65, 75, 69, 128, 83, 78, 65, 75, 197, 83, 78, 65, 73, 76, 128, 83, 78, + 193, 83, 77, 79, 75, 73, 78, 199, 83, 77, 73, 82, 75, 73, 78, 199, 83, + 77, 73, 76, 73, 78, 199, 83, 77, 73, 76, 69, 128, 83, 77, 69, 65, 82, + 128, 83, 77, 65, 83, 200, 83, 77, 65, 76, 76, 69, 210, 83, 77, 65, 76, + 76, 128, 83, 76, 85, 82, 128, 83, 76, 79, 87, 76, 89, 128, 83, 76, 79, + 215, 83, 76, 79, 86, 79, 128, 83, 76, 79, 212, 83, 76, 79, 80, 73, 78, + 199, 83, 76, 79, 80, 69, 128, 83, 76, 79, 65, 206, 83, 76, 73, 78, 71, + 128, 83, 76, 73, 71, 72, 84, 76, 217, 83, 76, 73, 68, 73, 78, 71, 128, + 83, 76, 73, 68, 69, 82, 128, 83, 76, 73, 67, 69, 128, 83, 76, 73, 67, + 197, 83, 76, 69, 85, 84, 200, 83, 76, 69, 69, 80, 217, 83, 76, 69, 69, + 80, 73, 78, 199, 83, 76, 65, 86, 79, 78, 73, 195, 83, 76, 65, 86, 69, + 128, 83, 76, 65, 83, 72, 128, 83, 76, 65, 83, 200, 83, 76, 65, 78, 84, + 69, 196, 83, 75, 87, 65, 128, 83, 75, 87, 128, 83, 75, 85, 76, 76, 128, + 83, 75, 85, 76, 204, 83, 75, 76, 73, 82, 79, 206, 83, 75, 73, 78, 128, + 83, 75, 73, 69, 82, 128, 83, 75, 201, 83, 75, 69, 87, 69, 196, 83, 75, + 65, 84, 69, 128, 83, 75, 128, 83, 74, 69, 128, 83, 73, 90, 197, 83, 73, + 88, 84, 89, 45, 70, 79, 85, 82, 84, 200, 83, 73, 88, 84, 89, 128, 83, 73, + 88, 84, 217, 83, 73, 88, 84, 72, 83, 128, 83, 73, 88, 84, 72, 211, 83, + 73, 88, 84, 72, 128, 83, 73, 88, 84, 69, 69, 78, 84, 72, 83, 128, 83, 73, + 88, 84, 69, 69, 78, 84, 72, 128, 83, 73, 88, 84, 69, 69, 78, 84, 200, 83, + 73, 88, 84, 69, 69, 78, 128, 83, 73, 88, 84, 69, 69, 206, 83, 73, 88, 45, + 84, 72, 73, 82, 84, 89, 128, 83, 73, 88, 45, 83, 84, 82, 73, 78, 199, 83, + 73, 88, 45, 80, 69, 82, 45, 69, 205, 83, 73, 88, 45, 76, 73, 78, 197, 83, + 73, 216, 83, 73, 84, 69, 128, 83, 73, 83, 65, 128, 83, 73, 82, 73, 78, + 71, 85, 128, 83, 73, 79, 83, 45, 84, 72, 73, 69, 85, 84, 72, 128, 83, 73, + 79, 83, 45, 83, 83, 65, 78, 71, 83, 73, 79, 83, 128, 83, 73, 79, 83, 45, + 82, 73, 69, 85, 76, 128, 83, 73, 79, 83, 45, 80, 73, 69, 85, 80, 45, 75, + 73, 89, 69, 79, 75, 128, 83, 73, 79, 83, 45, 80, 72, 73, 69, 85, 80, 72, + 128, 83, 73, 79, 83, 45, 80, 65, 78, 83, 73, 79, 83, 128, 83, 73, 79, 83, + 45, 78, 73, 69, 85, 78, 128, 83, 73, 79, 83, 45, 77, 73, 69, 85, 77, 128, + 83, 73, 79, 83, 45, 75, 72, 73, 69, 85, 75, 72, 128, 83, 73, 79, 83, 45, + 75, 65, 80, 89, 69, 79, 85, 78, 80, 73, 69, 85, 80, 128, 83, 73, 79, 83, + 45, 73, 69, 85, 78, 71, 128, 83, 73, 79, 83, 45, 72, 73, 69, 85, 72, 128, + 83, 73, 79, 83, 45, 67, 73, 69, 85, 67, 128, 83, 73, 79, 83, 45, 67, 72, + 73, 69, 85, 67, 72, 128, 83, 73, 79, 211, 83, 73, 78, 85, 83, 79, 73, + 196, 83, 73, 78, 75, 73, 78, 71, 128, 83, 73, 78, 71, 76, 69, 45, 83, 72, + 73, 70, 84, 45, 51, 128, 83, 73, 78, 71, 76, 69, 45, 83, 72, 73, 70, 84, + 45, 50, 128, 83, 73, 78, 71, 76, 69, 45, 76, 73, 78, 197, 83, 73, 78, 71, + 76, 69, 128, 83, 73, 78, 71, 76, 197, 83, 73, 78, 71, 65, 65, 84, 128, + 83, 73, 78, 197, 83, 73, 78, 68, 72, 201, 83, 73, 206, 83, 73, 77, 80, + 76, 73, 70, 73, 69, 196, 83, 73, 77, 73, 76, 65, 82, 128, 83, 73, 77, 73, + 76, 65, 210, 83, 73, 77, 65, 78, 83, 73, 211, 83, 73, 77, 65, 76, 85, 78, + 71, 85, 206, 83, 73, 77, 65, 128, 83, 73, 76, 86, 69, 82, 128, 83, 73, + 76, 75, 128, 83, 73, 76, 73, 81, 85, 193, 83, 73, 76, 72, 79, 85, 69, 84, + 84, 69, 128, 83, 73, 76, 72, 79, 85, 69, 84, 84, 197, 83, 73, 76, 65, 51, + 128, 83, 73, 75, 73, 128, 83, 73, 75, 50, 128, 83, 73, 75, 178, 83, 73, + 71, 78, 83, 128, 83, 73, 71, 77, 65, 128, 83, 73, 71, 77, 193, 83, 73, + 71, 69, 204, 83, 73, 71, 52, 128, 83, 73, 71, 180, 83, 73, 71, 128, 83, + 73, 69, 69, 128, 83, 73, 68, 69, 87, 65, 89, 211, 83, 73, 68, 68, 72, 65, + 77, 128, 83, 73, 68, 68, 72, 65, 205, 83, 73, 67, 75, 78, 69, 83, 83, + 128, 83, 73, 67, 75, 76, 69, 128, 83, 73, 66, 197, 83, 73, 65, 128, 83, + 201, 83, 72, 89, 88, 128, 83, 72, 89, 84, 128, 83, 72, 89, 82, 88, 128, + 83, 72, 89, 82, 128, 83, 72, 89, 80, 128, 83, 72, 89, 69, 128, 83, 72, + 89, 65, 128, 83, 72, 89, 128, 83, 72, 87, 79, 89, 128, 83, 72, 87, 79, + 79, 128, 83, 72, 87, 79, 128, 83, 72, 87, 73, 73, 128, 83, 72, 87, 73, + 128, 83, 72, 87, 69, 128, 83, 72, 87, 197, 83, 72, 87, 65, 65, 128, 83, + 72, 87, 65, 128, 83, 72, 85, 88, 128, 83, 72, 85, 85, 128, 83, 72, 85, + 84, 128, 83, 72, 85, 82, 88, 128, 83, 72, 85, 82, 128, 83, 72, 85, 80, + 128, 83, 72, 85, 79, 88, 128, 83, 72, 85, 79, 80, 128, 83, 72, 85, 79, + 128, 83, 72, 85, 77, 128, 83, 72, 85, 76, 128, 83, 72, 85, 70, 70, 76, + 197, 83, 72, 85, 69, 81, 128, 83, 72, 85, 69, 78, 83, 72, 85, 69, 84, + 128, 83, 72, 85, 66, 85, 82, 128, 83, 72, 85, 50, 128, 83, 72, 85, 178, + 83, 72, 85, 128, 83, 72, 213, 83, 72, 84, 65, 80, 73, 67, 128, 83, 72, + 84, 65, 128, 83, 72, 82, 73, 78, 69, 128, 83, 72, 82, 73, 77, 80, 128, + 83, 72, 82, 73, 73, 128, 83, 72, 82, 73, 128, 83, 72, 79, 89, 128, 83, + 72, 79, 88, 128, 83, 72, 79, 87, 69, 82, 128, 83, 72, 79, 85, 76, 68, 69, + 82, 69, 196, 83, 72, 79, 84, 128, 83, 72, 79, 82, 84, 83, 128, 83, 72, + 79, 82, 84, 211, 83, 72, 79, 82, 84, 72, 65, 78, 196, 83, 72, 79, 82, 84, + 69, 78, 69, 82, 128, 83, 72, 79, 82, 84, 67, 65, 75, 69, 128, 83, 72, 79, + 82, 84, 45, 84, 87, 73, 71, 45, 89, 82, 128, 83, 72, 79, 82, 84, 45, 84, + 87, 73, 71, 45, 84, 89, 210, 83, 72, 79, 82, 84, 45, 84, 87, 73, 71, 45, + 83, 79, 204, 83, 72, 79, 82, 84, 45, 84, 87, 73, 71, 45, 79, 83, 211, 83, + 72, 79, 82, 84, 45, 84, 87, 73, 71, 45, 78, 65, 85, 196, 83, 72, 79, 82, + 84, 45, 84, 87, 73, 71, 45, 77, 65, 68, 210, 83, 72, 79, 82, 84, 45, 84, + 87, 73, 71, 45, 72, 65, 71, 65, 76, 204, 83, 72, 79, 82, 84, 45, 84, 87, + 73, 71, 45, 66, 74, 65, 82, 75, 65, 206, 83, 72, 79, 82, 84, 45, 84, 87, + 73, 71, 45, 65, 210, 83, 72, 79, 82, 84, 128, 83, 72, 79, 82, 212, 83, + 72, 79, 81, 128, 83, 72, 79, 209, 83, 72, 79, 80, 80, 73, 78, 199, 83, + 72, 79, 80, 128, 83, 72, 79, 79, 84, 73, 78, 199, 83, 72, 79, 79, 84, + 128, 83, 72, 79, 79, 73, 128, 83, 72, 79, 79, 128, 83, 72, 79, 71, 201, + 83, 72, 79, 199, 83, 72, 79, 69, 128, 83, 72, 79, 197, 83, 72, 79, 65, + 128, 83, 72, 79, 128, 83, 72, 73, 89, 89, 65, 65, 76, 65, 65, 128, 83, + 72, 73, 84, 65, 128, 83, 72, 73, 84, 193, 83, 72, 73, 82, 212, 83, 72, + 73, 82, 65, 69, 128, 83, 72, 73, 82, 128, 83, 72, 73, 210, 83, 72, 73, + 81, 128, 83, 72, 73, 80, 128, 83, 72, 73, 78, 84, 207, 83, 72, 73, 78, + 73, 71, 128, 83, 72, 73, 78, 68, 193, 83, 72, 73, 206, 83, 72, 73, 77, + 65, 128, 83, 72, 73, 77, 193, 83, 72, 73, 77, 128, 83, 72, 73, 205, 83, + 72, 73, 73, 78, 128, 83, 72, 73, 73, 128, 83, 72, 73, 70, 212, 83, 72, + 73, 69, 76, 68, 128, 83, 72, 73, 68, 128, 83, 72, 73, 196, 83, 72, 72, + 65, 128, 83, 72, 72, 193, 83, 72, 69, 88, 128, 83, 72, 69, 86, 65, 128, + 83, 72, 69, 85, 88, 128, 83, 72, 69, 85, 79, 81, 128, 83, 72, 69, 85, 65, + 69, 81, 84, 85, 128, 83, 72, 69, 85, 65, 69, 81, 128, 83, 72, 69, 85, 65, + 69, 128, 83, 72, 69, 84, 128, 83, 72, 69, 212, 83, 72, 69, 83, 72, 76, + 65, 77, 128, 83, 72, 69, 83, 72, 73, 71, 128, 83, 72, 69, 83, 72, 73, + 199, 83, 72, 69, 83, 72, 50, 128, 83, 72, 69, 83, 72, 128, 83, 72, 69, + 81, 69, 204, 83, 72, 69, 80, 128, 83, 72, 69, 78, 128, 83, 72, 69, 76, + 76, 128, 83, 72, 69, 76, 204, 83, 72, 69, 76, 70, 128, 83, 72, 69, 73, + 128, 83, 72, 69, 71, 57, 128, 83, 72, 69, 69, 80, 128, 83, 72, 69, 69, + 78, 85, 128, 83, 72, 69, 69, 78, 128, 83, 72, 69, 69, 206, 83, 72, 69, + 69, 128, 83, 72, 69, 45, 71, 79, 65, 84, 128, 83, 72, 197, 83, 72, 67, + 72, 79, 79, 73, 128, 83, 72, 67, 72, 65, 128, 83, 72, 65, 89, 128, 83, + 72, 65, 88, 128, 83, 72, 65, 86, 73, 89, 65, 78, 73, 128, 83, 72, 65, 86, + 73, 65, 206, 83, 72, 65, 86, 69, 196, 83, 72, 65, 85, 128, 83, 72, 65, + 84, 128, 83, 72, 65, 82, 85, 128, 83, 72, 65, 82, 213, 83, 72, 65, 82, + 80, 128, 83, 72, 65, 82, 208, 83, 72, 65, 82, 65, 128, 83, 72, 65, 82, + 50, 128, 83, 72, 65, 82, 178, 83, 72, 65, 80, 73, 78, 71, 128, 83, 72, + 65, 80, 69, 83, 128, 83, 72, 65, 80, 197, 83, 72, 65, 80, 128, 83, 72, + 65, 78, 71, 128, 83, 72, 65, 78, 128, 83, 72, 65, 206, 83, 72, 65, 77, + 82, 79, 67, 75, 128, 83, 72, 65, 76, 83, 72, 69, 76, 69, 84, 128, 83, 72, + 65, 75, 84, 73, 128, 83, 72, 65, 75, 128, 83, 72, 65, 73, 128, 83, 72, + 65, 70, 84, 128, 83, 72, 65, 70, 212, 83, 72, 65, 68, 79, 87, 69, 196, + 83, 72, 65, 68, 69, 196, 83, 72, 65, 68, 69, 128, 83, 72, 65, 68, 68, 65, + 128, 83, 72, 65, 68, 68, 193, 83, 72, 65, 68, 128, 83, 72, 65, 196, 83, + 72, 65, 66, 54, 128, 83, 72, 65, 65, 128, 83, 72, 65, 54, 128, 83, 72, + 65, 51, 128, 83, 72, 65, 179, 83, 71, 82, 193, 83, 71, 79, 210, 83, 71, + 67, 128, 83, 71, 65, 215, 83, 71, 65, 194, 83, 71, 128, 83, 69, 89, 75, + 128, 83, 69, 88, 84, 85, 76, 193, 83, 69, 88, 84, 73, 76, 69, 128, 83, + 69, 88, 84, 65, 78, 211, 83, 69, 86, 69, 82, 65, 78, 67, 69, 128, 83, 69, + 86, 69, 78, 84, 89, 128, 83, 69, 86, 69, 78, 84, 217, 83, 69, 86, 69, 78, + 84, 72, 128, 83, 69, 86, 69, 78, 84, 69, 69, 78, 128, 83, 69, 86, 69, 78, + 84, 69, 69, 206, 83, 69, 86, 69, 78, 45, 84, 72, 73, 82, 84, 89, 128, 83, + 69, 86, 69, 206, 83, 69, 85, 88, 128, 83, 69, 85, 78, 89, 65, 77, 128, + 83, 69, 85, 65, 69, 81, 128, 83, 69, 84, 70, 79, 78, 128, 83, 69, 83, 84, + 69, 82, 84, 73, 85, 211, 83, 69, 83, 81, 85, 73, 81, 85, 65, 68, 82, 65, + 84, 69, 128, 83, 69, 83, 65, 77, 197, 83, 69, 82, 86, 73, 67, 197, 83, + 69, 82, 73, 70, 83, 128, 83, 69, 82, 73, 70, 211, 83, 69, 82, 73, 70, + 128, 83, 69, 81, 85, 69, 78, 67, 197, 83, 69, 80, 84, 69, 77, 66, 69, 82, + 128, 83, 69, 80, 65, 82, 65, 84, 79, 82, 128, 83, 69, 80, 65, 82, 65, 84, + 79, 210, 83, 69, 78, 84, 79, 128, 83, 69, 78, 84, 73, 128, 83, 69, 77, + 85, 78, 67, 73, 193, 83, 69, 77, 75, 65, 84, 72, 128, 83, 69, 77, 75, + 128, 83, 69, 77, 73, 86, 79, 87, 69, 204, 83, 69, 77, 73, 83, 79, 70, + 212, 83, 69, 77, 73, 83, 69, 88, 84, 73, 76, 69, 128, 83, 69, 77, 73, 77, + 73, 78, 73, 77, 193, 83, 69, 77, 73, 68, 73, 82, 69, 67, 212, 83, 69, 77, + 73, 67, 79, 76, 79, 78, 128, 83, 69, 77, 73, 67, 79, 76, 79, 206, 83, 69, + 77, 73, 67, 73, 82, 67, 85, 76, 65, 210, 83, 69, 77, 73, 67, 73, 82, 67, + 76, 197, 83, 69, 77, 73, 66, 82, 69, 86, 73, 211, 83, 69, 77, 73, 45, 86, + 79, 73, 67, 69, 196, 83, 69, 76, 70, 128, 83, 69, 76, 69, 67, 84, 79, 82, + 45, 57, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 57, 56, 128, 83, 69, + 76, 69, 67, 84, 79, 82, 45, 57, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, + 45, 57, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 57, 53, 128, 83, 69, + 76, 69, 67, 84, 79, 82, 45, 57, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, + 45, 57, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 57, 50, 128, 83, 69, + 76, 69, 67, 84, 79, 82, 45, 57, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, + 45, 57, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 57, 128, 83, 69, 76, + 69, 67, 84, 79, 82, 45, 56, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, + 56, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 56, 55, 128, 83, 69, 76, + 69, 67, 84, 79, 82, 45, 56, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, + 56, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 56, 52, 128, 83, 69, 76, + 69, 67, 84, 79, 82, 45, 56, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, + 56, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 56, 49, 128, 83, 69, 76, + 69, 67, 84, 79, 82, 45, 56, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, + 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 55, 57, 128, 83, 69, 76, 69, + 67, 84, 79, 82, 45, 55, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 55, + 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 55, 54, 128, 83, 69, 76, 69, + 67, 84, 79, 82, 45, 55, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 55, + 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 55, 51, 128, 83, 69, 76, 69, + 67, 84, 79, 82, 45, 55, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 55, + 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 55, 48, 128, 83, 69, 76, 69, + 67, 84, 79, 82, 45, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 54, 57, + 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 54, 56, 128, 83, 69, 76, 69, 67, + 84, 79, 82, 45, 54, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 54, 54, + 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 54, 53, 128, 83, 69, 76, 69, 67, + 84, 79, 82, 45, 54, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 54, 51, + 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 54, 50, 128, 83, 69, 76, 69, 67, + 84, 79, 82, 45, 54, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 54, 48, + 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 54, 128, 83, 69, 76, 69, 67, 84, + 79, 82, 45, 53, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 53, 56, 128, + 83, 69, 76, 69, 67, 84, 79, 82, 45, 53, 55, 128, 83, 69, 76, 69, 67, 84, + 79, 82, 45, 53, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 53, 53, 128, + 83, 69, 76, 69, 67, 84, 79, 82, 45, 53, 52, 128, 83, 69, 76, 69, 67, 84, + 79, 82, 45, 53, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 53, 50, 128, + 83, 69, 76, 69, 67, 84, 79, 82, 45, 53, 49, 128, 83, 69, 76, 69, 67, 84, + 79, 82, 45, 53, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 53, 128, 83, + 69, 76, 69, 67, 84, 79, 82, 45, 52, 57, 128, 83, 69, 76, 69, 67, 84, 79, + 82, 45, 52, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 52, 55, 128, 83, + 69, 76, 69, 67, 84, 79, 82, 45, 52, 54, 128, 83, 69, 76, 69, 67, 84, 79, + 82, 45, 52, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 52, 52, 128, 83, + 69, 76, 69, 67, 84, 79, 82, 45, 52, 51, 128, 83, 69, 76, 69, 67, 84, 79, + 82, 45, 52, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 52, 49, 128, 83, + 69, 76, 69, 67, 84, 79, 82, 45, 52, 48, 128, 83, 69, 76, 69, 67, 84, 79, + 82, 45, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 51, 57, 128, 83, 69, + 76, 69, 67, 84, 79, 82, 45, 51, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, + 45, 51, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 51, 54, 128, 83, 69, + 76, 69, 67, 84, 79, 82, 45, 51, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, + 45, 51, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 51, 51, 128, 83, 69, + 76, 69, 67, 84, 79, 82, 45, 51, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, + 45, 51, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 51, 48, 128, 83, 69, + 76, 69, 67, 84, 79, 82, 45, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, + 50, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 56, 128, 83, 69, 76, + 69, 67, 84, 79, 82, 45, 50, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, + 50, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 53, 54, 128, 83, 69, + 76, 69, 67, 84, 79, 82, 45, 50, 53, 53, 128, 83, 69, 76, 69, 67, 84, 79, + 82, 45, 50, 53, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 53, 51, + 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 53, 50, 128, 83, 69, 76, 69, + 67, 84, 79, 82, 45, 50, 53, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, + 50, 53, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 53, 128, 83, 69, + 76, 69, 67, 84, 79, 82, 45, 50, 52, 57, 128, 83, 69, 76, 69, 67, 84, 79, + 82, 45, 50, 52, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 52, 55, + 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 52, 54, 128, 83, 69, 76, 69, + 67, 84, 79, 82, 45, 50, 52, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, + 50, 52, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 52, 51, 128, 83, + 69, 76, 69, 67, 84, 79, 82, 45, 50, 52, 50, 128, 83, 69, 76, 69, 67, 84, + 79, 82, 45, 50, 52, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 52, + 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 52, 128, 83, 69, 76, 69, + 67, 84, 79, 82, 45, 50, 51, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, + 50, 51, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 51, 55, 128, 83, + 69, 76, 69, 67, 84, 79, 82, 45, 50, 51, 54, 128, 83, 69, 76, 69, 67, 84, + 79, 82, 45, 50, 51, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 51, + 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 51, 51, 128, 83, 69, 76, + 69, 67, 84, 79, 82, 45, 50, 51, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, + 45, 50, 51, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 51, 48, 128, + 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 51, 128, 83, 69, 76, 69, 67, 84, + 79, 82, 45, 50, 50, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 50, + 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 50, 55, 128, 83, 69, 76, + 69, 67, 84, 79, 82, 45, 50, 50, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, + 45, 50, 50, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 50, 52, 128, + 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 50, 51, 128, 83, 69, 76, 69, 67, + 84, 79, 82, 45, 50, 50, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, + 50, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 50, 48, 128, 83, 69, + 76, 69, 67, 84, 79, 82, 45, 50, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, + 45, 50, 49, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 49, 56, 128, + 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 49, 55, 128, 83, 69, 76, 69, 67, + 84, 79, 82, 45, 50, 49, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, + 49, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 49, 52, 128, 83, 69, + 76, 69, 67, 84, 79, 82, 45, 50, 49, 51, 128, 83, 69, 76, 69, 67, 84, 79, + 82, 45, 50, 49, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 49, 49, + 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 49, 48, 128, 83, 69, 76, 69, + 67, 84, 79, 82, 45, 50, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, + 48, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 48, 56, 128, 83, 69, + 76, 69, 67, 84, 79, 82, 45, 50, 48, 55, 128, 83, 69, 76, 69, 67, 84, 79, + 82, 45, 50, 48, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 48, 53, + 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 48, 52, 128, 83, 69, 76, 69, + 67, 84, 79, 82, 45, 50, 48, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, + 50, 48, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 48, 49, 128, 83, + 69, 76, 69, 67, 84, 79, 82, 45, 50, 48, 48, 128, 83, 69, 76, 69, 67, 84, + 79, 82, 45, 50, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 50, 128, 83, + 69, 76, 69, 67, 84, 79, 82, 45, 49, 57, 57, 128, 83, 69, 76, 69, 67, 84, + 79, 82, 45, 49, 57, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 57, + 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 57, 54, 128, 83, 69, 76, + 69, 67, 84, 79, 82, 45, 49, 57, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, + 45, 49, 57, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 57, 51, 128, + 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 57, 50, 128, 83, 69, 76, 69, 67, + 84, 79, 82, 45, 49, 57, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, + 57, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 57, 128, 83, 69, 76, + 69, 67, 84, 79, 82, 45, 49, 56, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, + 45, 49, 56, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 56, 55, 128, + 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 56, 54, 128, 83, 69, 76, 69, 67, + 84, 79, 82, 45, 49, 56, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, + 56, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 56, 51, 128, 83, 69, + 76, 69, 67, 84, 79, 82, 45, 49, 56, 50, 128, 83, 69, 76, 69, 67, 84, 79, + 82, 45, 49, 56, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 56, 48, + 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 56, 128, 83, 69, 76, 69, 67, + 84, 79, 82, 45, 49, 55, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, + 55, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 55, 55, 128, 83, 69, + 76, 69, 67, 84, 79, 82, 45, 49, 55, 54, 128, 83, 69, 76, 69, 67, 84, 79, + 82, 45, 49, 55, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 55, 52, + 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 55, 51, 128, 83, 69, 76, 69, + 67, 84, 79, 82, 45, 49, 55, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, + 49, 55, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 55, 48, 128, 83, + 69, 76, 69, 67, 84, 79, 82, 45, 49, 55, 128, 83, 69, 76, 69, 67, 84, 79, + 82, 45, 49, 54, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 54, 56, + 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 54, 55, 128, 83, 69, 76, 69, + 67, 84, 79, 82, 45, 49, 54, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, + 49, 54, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 54, 52, 128, 83, + 69, 76, 69, 67, 84, 79, 82, 45, 49, 54, 51, 128, 83, 69, 76, 69, 67, 84, + 79, 82, 45, 49, 54, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 54, + 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 54, 48, 128, 83, 69, 76, + 69, 67, 84, 79, 82, 45, 49, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, + 49, 53, 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 53, 56, 128, 83, + 69, 76, 69, 67, 84, 79, 82, 45, 49, 53, 55, 128, 83, 69, 76, 69, 67, 84, + 79, 82, 45, 49, 53, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 53, + 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 53, 52, 128, 83, 69, 76, + 69, 67, 84, 79, 82, 45, 49, 53, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, + 45, 49, 53, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 53, 49, 128, + 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 53, 48, 128, 83, 69, 76, 69, 67, + 84, 79, 82, 45, 49, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 52, + 57, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 52, 56, 128, 83, 69, 76, + 69, 67, 84, 79, 82, 45, 49, 52, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, + 45, 49, 52, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 52, 53, 128, + 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 52, 52, 128, 83, 69, 76, 69, 67, + 84, 79, 82, 45, 49, 52, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, + 52, 50, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 52, 49, 128, 83, 69, + 76, 69, 67, 84, 79, 82, 45, 49, 52, 48, 128, 83, 69, 76, 69, 67, 84, 79, + 82, 45, 49, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 51, 57, 128, + 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 51, 56, 128, 83, 69, 76, 69, 67, + 84, 79, 82, 45, 49, 51, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, + 51, 54, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 51, 53, 128, 83, 69, + 76, 69, 67, 84, 79, 82, 45, 49, 51, 52, 128, 83, 69, 76, 69, 67, 84, 79, + 82, 45, 49, 51, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 51, 50, + 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 51, 49, 128, 83, 69, 76, 69, + 67, 84, 79, 82, 45, 49, 51, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, + 49, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 50, 57, 128, 83, 69, + 76, 69, 67, 84, 79, 82, 45, 49, 50, 56, 128, 83, 69, 76, 69, 67, 84, 79, + 82, 45, 49, 50, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 50, 54, + 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 50, 53, 128, 83, 69, 76, 69, + 67, 84, 79, 82, 45, 49, 50, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, + 49, 50, 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 50, 50, 128, 83, + 69, 76, 69, 67, 84, 79, 82, 45, 49, 50, 49, 128, 83, 69, 76, 69, 67, 84, + 79, 82, 45, 49, 50, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 50, + 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 49, 57, 128, 83, 69, 76, 69, + 67, 84, 79, 82, 45, 49, 49, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, + 49, 49, 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 49, 54, 128, 83, + 69, 76, 69, 67, 84, 79, 82, 45, 49, 49, 53, 128, 83, 69, 76, 69, 67, 84, + 79, 82, 45, 49, 49, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 49, + 51, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 49, 50, 128, 83, 69, 76, + 69, 67, 84, 79, 82, 45, 49, 49, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, + 45, 49, 49, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 49, 128, 83, + 69, 76, 69, 67, 84, 79, 82, 45, 49, 48, 57, 128, 83, 69, 76, 69, 67, 84, + 79, 82, 45, 49, 48, 56, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 48, + 55, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 48, 54, 128, 83, 69, 76, + 69, 67, 84, 79, 82, 45, 49, 48, 53, 128, 83, 69, 76, 69, 67, 84, 79, 82, + 45, 49, 48, 52, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 48, 51, 128, + 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 48, 50, 128, 83, 69, 76, 69, 67, + 84, 79, 82, 45, 49, 48, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, + 48, 48, 128, 83, 69, 76, 69, 67, 84, 79, 82, 45, 49, 48, 128, 83, 69, 76, + 69, 67, 84, 79, 82, 45, 49, 128, 83, 69, 76, 69, 67, 84, 79, 82, 128, 83, + 69, 76, 69, 67, 84, 79, 210, 83, 69, 76, 69, 67, 84, 69, 196, 83, 69, 73, + 83, 77, 65, 128, 83, 69, 73, 83, 77, 193, 83, 69, 72, 128, 83, 69, 71, + 79, 76, 128, 83, 69, 71, 78, 79, 128, 83, 69, 71, 77, 69, 78, 84, 128, + 83, 69, 69, 86, 128, 83, 69, 69, 78, 85, 128, 83, 69, 69, 78, 128, 83, + 69, 69, 206, 83, 69, 69, 68, 76, 73, 78, 71, 128, 83, 69, 69, 45, 78, 79, + 45, 69, 86, 73, 204, 83, 69, 67, 84, 79, 82, 128, 83, 69, 67, 84, 73, 79, + 78, 128, 83, 69, 67, 84, 73, 79, 206, 83, 69, 67, 82, 69, 84, 128, 83, + 69, 67, 79, 78, 68, 128, 83, 69, 67, 65, 78, 84, 128, 83, 69, 66, 65, 84, + 66, 69, 73, 212, 83, 69, 65, 84, 128, 83, 69, 65, 76, 128, 83, 69, 65, + 71, 85, 76, 204, 83, 68, 79, 78, 199, 83, 68, 128, 83, 67, 87, 65, 128, + 83, 67, 82, 85, 80, 76, 69, 128, 83, 67, 82, 79, 76, 76, 128, 83, 67, 82, + 73, 80, 84, 128, 83, 67, 82, 69, 69, 78, 128, 83, 67, 82, 69, 69, 206, + 83, 67, 82, 69, 65, 77, 73, 78, 199, 83, 67, 79, 82, 80, 73, 85, 83, 128, + 83, 67, 79, 82, 69, 128, 83, 67, 73, 83, 83, 79, 82, 83, 128, 83, 67, 73, + 128, 83, 67, 72, 87, 65, 128, 83, 67, 72, 87, 193, 83, 67, 72, 82, 79, + 69, 68, 69, 82, 128, 83, 67, 72, 79, 79, 76, 128, 83, 67, 72, 79, 79, + 204, 83, 67, 72, 79, 76, 65, 82, 128, 83, 67, 72, 69, 77, 193, 83, 67, + 69, 80, 84, 69, 210, 83, 67, 65, 78, 68, 73, 67, 85, 83, 128, 83, 67, 65, + 78, 68, 73, 67, 85, 211, 83, 67, 65, 206, 83, 67, 65, 76, 69, 83, 128, + 83, 66, 85, 194, 83, 66, 82, 85, 204, 83, 65, 89, 73, 83, 201, 83, 65, + 89, 65, 78, 78, 65, 128, 83, 65, 89, 128, 83, 65, 88, 79, 80, 72, 79, 78, + 69, 128, 83, 65, 88, 73, 77, 65, 84, 65, 128, 83, 65, 87, 65, 78, 128, + 83, 65, 87, 128, 83, 65, 86, 79, 85, 82, 73, 78, 199, 83, 65, 85, 82, 65, + 83, 72, 84, 82, 193, 83, 65, 85, 73, 76, 128, 83, 65, 84, 85, 82, 78, + 128, 83, 65, 84, 75, 65, 65, 78, 75, 85, 85, 128, 83, 65, 84, 75, 65, 65, + 78, 128, 83, 65, 84, 69, 76, 76, 73, 84, 69, 128, 83, 65, 84, 69, 76, 76, + 73, 84, 197, 83, 65, 84, 67, 72, 69, 76, 128, 83, 65, 84, 65, 78, 71, 65, + 128, 83, 65, 83, 72, 128, 83, 65, 83, 65, 75, 128, 83, 65, 82, 73, 128, + 83, 65, 82, 193, 83, 65, 82, 128, 83, 65, 81, 128, 83, 65, 80, 65, 128, + 83, 65, 78, 89, 79, 79, 71, 193, 83, 65, 78, 89, 65, 75, 193, 83, 65, 78, + 84, 73, 73, 77, 85, 128, 83, 65, 78, 78, 89, 65, 128, 83, 65, 78, 71, 65, + 50, 128, 83, 65, 78, 68, 72, 201, 83, 65, 78, 68, 65, 76, 128, 83, 65, + 78, 65, 72, 128, 83, 65, 78, 128, 83, 65, 77, 89, 79, 203, 83, 65, 77, + 86, 65, 84, 128, 83, 65, 77, 80, 73, 128, 83, 65, 77, 80, 72, 65, 79, + 128, 83, 65, 77, 75, 65, 128, 83, 65, 77, 69, 75, 72, 128, 83, 65, 77, + 69, 75, 200, 83, 65, 77, 66, 65, 128, 83, 65, 77, 65, 82, 73, 84, 65, + 206, 83, 65, 77, 128, 83, 65, 76, 84, 73, 82, 69, 128, 83, 65, 76, 84, + 73, 76, 76, 79, 128, 83, 65, 76, 84, 45, 50, 128, 83, 65, 76, 84, 128, + 83, 65, 76, 212, 83, 65, 76, 76, 65, 76, 76, 65, 72, 79, 213, 83, 65, 76, + 76, 193, 83, 65, 76, 65, 205, 83, 65, 76, 65, 128, 83, 65, 76, 45, 65, + 77, 77, 79, 78, 73, 65, 67, 128, 83, 65, 76, 128, 83, 65, 75, 79, 84, + 128, 83, 65, 75, 69, 85, 65, 69, 128, 83, 65, 75, 197, 83, 65, 74, 68, + 65, 72, 128, 83, 65, 73, 76, 66, 79, 65, 84, 128, 83, 65, 73, 76, 128, + 83, 65, 73, 75, 85, 82, 85, 128, 83, 65, 72, 128, 83, 65, 71, 73, 84, 84, + 65, 82, 73, 85, 83, 128, 83, 65, 71, 65, 128, 83, 65, 71, 128, 83, 65, + 199, 83, 65, 70, 72, 65, 128, 83, 65, 70, 69, 84, 217, 83, 65, 68, 72, + 69, 128, 83, 65, 68, 69, 128, 83, 65, 68, 128, 83, 65, 196, 83, 65, 67, + 82, 73, 70, 73, 67, 73, 65, 204, 83, 65, 65, 73, 128, 83, 65, 65, 68, 72, + 85, 128, 83, 65, 45, 73, 128, 83, 65, 45, 50, 128, 83, 48, 52, 54, 128, + 83, 48, 52, 53, 128, 83, 48, 52, 52, 128, 83, 48, 52, 51, 128, 83, 48, + 52, 50, 128, 83, 48, 52, 49, 128, 83, 48, 52, 48, 128, 83, 48, 51, 57, + 128, 83, 48, 51, 56, 128, 83, 48, 51, 55, 128, 83, 48, 51, 54, 128, 83, + 48, 51, 53, 65, 128, 83, 48, 51, 53, 128, 83, 48, 51, 52, 128, 83, 48, + 51, 51, 128, 83, 48, 51, 50, 128, 83, 48, 51, 49, 128, 83, 48, 51, 48, + 128, 83, 48, 50, 57, 128, 83, 48, 50, 56, 128, 83, 48, 50, 55, 128, 83, + 48, 50, 54, 66, 128, 83, 48, 50, 54, 65, 128, 83, 48, 50, 54, 128, 83, + 48, 50, 53, 128, 83, 48, 50, 52, 128, 83, 48, 50, 51, 128, 83, 48, 50, + 50, 128, 83, 48, 50, 49, 128, 83, 48, 50, 48, 128, 83, 48, 49, 57, 128, + 83, 48, 49, 56, 128, 83, 48, 49, 55, 65, 128, 83, 48, 49, 55, 128, 83, + 48, 49, 54, 128, 83, 48, 49, 53, 128, 83, 48, 49, 52, 66, 128, 83, 48, + 49, 52, 65, 128, 83, 48, 49, 52, 128, 83, 48, 49, 51, 128, 83, 48, 49, + 50, 128, 83, 48, 49, 49, 128, 83, 48, 49, 48, 128, 83, 48, 48, 57, 128, + 83, 48, 48, 56, 128, 83, 48, 48, 55, 128, 83, 48, 48, 54, 65, 128, 83, + 48, 48, 54, 128, 83, 48, 48, 53, 128, 83, 48, 48, 52, 128, 83, 48, 48, + 51, 128, 83, 48, 48, 50, 65, 128, 83, 48, 48, 50, 128, 83, 48, 48, 49, + 128, 83, 45, 87, 128, 83, 45, 83, 72, 65, 80, 69, 196, 82, 89, 89, 128, + 82, 89, 88, 128, 82, 89, 84, 128, 82, 89, 82, 88, 128, 82, 89, 82, 128, + 82, 89, 80, 128, 82, 87, 79, 79, 128, 82, 87, 79, 128, 82, 87, 73, 73, + 128, 82, 87, 73, 128, 82, 87, 69, 69, 128, 82, 87, 69, 128, 82, 87, 65, + 72, 65, 128, 82, 87, 65, 65, 128, 82, 87, 65, 128, 82, 85, 88, 128, 82, + 85, 85, 66, 85, 82, 85, 128, 82, 85, 85, 128, 82, 85, 84, 128, 82, 85, + 83, 73, 128, 82, 85, 82, 88, 128, 82, 85, 82, 128, 82, 85, 80, 73, 73, + 128, 82, 85, 80, 69, 197, 82, 85, 80, 128, 82, 85, 79, 88, 128, 82, 85, + 79, 80, 128, 82, 85, 79, 128, 82, 85, 78, 79, 85, 84, 128, 82, 85, 78, + 78, 73, 78, 199, 82, 85, 78, 78, 69, 82, 128, 82, 85, 78, 128, 82, 85, + 77, 201, 82, 85, 77, 65, 201, 82, 85, 77, 128, 82, 85, 205, 82, 85, 76, + 69, 82, 128, 82, 85, 76, 69, 45, 68, 69, 76, 65, 89, 69, 68, 128, 82, 85, + 76, 69, 128, 82, 85, 75, 75, 65, 75, 72, 65, 128, 82, 85, 73, 83, 128, + 82, 85, 71, 66, 217, 82, 85, 66, 76, 197, 82, 85, 194, 82, 85, 65, 128, + 82, 84, 72, 65, 78, 199, 82, 84, 65, 71, 83, 128, 82, 84, 65, 71, 211, + 82, 82, 89, 88, 128, 82, 82, 89, 84, 128, 82, 82, 89, 82, 88, 128, 82, + 82, 89, 82, 128, 82, 82, 89, 80, 128, 82, 82, 85, 88, 128, 82, 82, 85, + 85, 128, 82, 82, 85, 84, 128, 82, 82, 85, 82, 88, 128, 82, 82, 85, 82, + 128, 82, 82, 85, 80, 128, 82, 82, 85, 79, 88, 128, 82, 82, 85, 79, 128, + 82, 82, 85, 128, 82, 82, 79, 88, 128, 82, 82, 79, 84, 128, 82, 82, 79, + 80, 128, 82, 82, 79, 79, 128, 82, 82, 79, 128, 82, 82, 73, 73, 128, 82, + 82, 73, 128, 82, 82, 69, 88, 128, 82, 82, 69, 84, 128, 82, 82, 69, 80, + 128, 82, 82, 69, 72, 128, 82, 82, 69, 200, 82, 82, 69, 69, 128, 82, 82, + 69, 128, 82, 82, 65, 88, 128, 82, 82, 65, 85, 128, 82, 82, 65, 73, 128, + 82, 82, 65, 65, 128, 82, 82, 65, 128, 82, 79, 87, 66, 79, 65, 84, 128, + 82, 79, 85, 78, 68, 69, 196, 82, 79, 85, 78, 68, 45, 84, 73, 80, 80, 69, + 196, 82, 79, 84, 85, 78, 68, 65, 128, 82, 79, 84, 65, 84, 69, 196, 82, + 79, 83, 72, 128, 82, 79, 83, 69, 84, 84, 69, 128, 82, 79, 83, 69, 128, + 82, 79, 79, 84, 128, 82, 79, 79, 83, 84, 69, 82, 128, 82, 79, 79, 75, + 128, 82, 79, 79, 70, 128, 82, 79, 77, 65, 78, 73, 65, 206, 82, 79, 77, + 65, 206, 82, 79, 77, 128, 82, 79, 76, 76, 69, 210, 82, 79, 76, 76, 69, + 68, 45, 85, 208, 82, 79, 72, 73, 78, 71, 89, 193, 82, 79, 71, 128, 82, + 79, 196, 82, 79, 67, 75, 69, 84, 128, 82, 79, 67, 203, 82, 79, 67, 128, + 82, 79, 66, 65, 84, 128, 82, 79, 65, 83, 84, 69, 196, 82, 79, 65, 82, + 128, 82, 79, 65, 128, 82, 78, 89, 73, 78, 199, 82, 78, 79, 79, 78, 128, + 82, 78, 79, 79, 206, 82, 78, 65, 205, 82, 77, 84, 128, 82, 76, 79, 128, + 82, 76, 77, 128, 82, 76, 73, 128, 82, 76, 69, 128, 82, 74, 69, 211, 82, + 74, 69, 128, 82, 74, 197, 82, 73, 86, 69, 82, 128, 82, 73, 84, 85, 65, + 76, 128, 82, 73, 84, 84, 79, 82, 85, 128, 82, 73, 84, 83, 73, 128, 82, + 73, 83, 73, 78, 199, 82, 73, 83, 72, 128, 82, 73, 82, 65, 128, 82, 73, + 80, 128, 82, 73, 78, 71, 211, 82, 73, 78, 71, 73, 78, 199, 82, 73, 78, + 70, 79, 82, 90, 65, 78, 68, 79, 128, 82, 73, 206, 82, 73, 77, 71, 66, 65, 128, 82, 73, 75, 82, 73, 75, 128, 82, 73, 71, 86, 69, 68, 73, 195, 82, 73, 71, 72, 84, 87, 65, 82, 68, 83, 128, 82, 73, 71, 72, 84, 72, 65, 78, 196, 82, 73, 71, 72, 84, 45, 84, 79, 45, 76, 69, 70, 212, 82, 73, 71, 72, 84, 45, 83, 73, 68, 197, 82, 73, 71, 72, 84, 45, 83, 72, 65, 68, 79, 87, 69, 196, 82, 73, 71, 72, 84, 45, 83, 72, 65, 68, 69, 196, 82, 73, 71, 72, - 84, 45, 80, 79, 73, 78, 84, 73, 78, 199, 82, 73, 71, 72, 84, 45, 72, 65, - 78, 68, 69, 196, 82, 73, 71, 72, 84, 45, 72, 65, 78, 196, 82, 73, 71, 72, - 84, 45, 70, 65, 67, 73, 78, 199, 82, 73, 71, 72, 84, 128, 82, 73, 69, 85, - 76, 45, 89, 69, 83, 73, 69, 85, 78, 71, 128, 82, 73, 69, 85, 76, 45, 89, - 69, 79, 82, 73, 78, 72, 73, 69, 85, 72, 45, 72, 73, 69, 85, 72, 128, 82, - 73, 69, 85, 76, 45, 89, 69, 79, 82, 73, 78, 72, 73, 69, 85, 72, 128, 82, - 73, 69, 85, 76, 45, 84, 73, 75, 69, 85, 84, 45, 72, 73, 69, 85, 72, 128, - 82, 73, 69, 85, 76, 45, 84, 73, 75, 69, 85, 84, 128, 82, 73, 69, 85, 76, - 45, 84, 72, 73, 69, 85, 84, 72, 128, 82, 73, 69, 85, 76, 45, 83, 83, 65, - 78, 71, 84, 73, 75, 69, 85, 84, 128, 82, 73, 69, 85, 76, 45, 83, 83, 65, - 78, 71, 83, 73, 79, 83, 128, 82, 73, 69, 85, 76, 45, 83, 83, 65, 78, 71, - 80, 73, 69, 85, 80, 128, 82, 73, 69, 85, 76, 45, 83, 83, 65, 78, 71, 75, - 73, 89, 69, 79, 75, 128, 82, 73, 69, 85, 76, 45, 83, 73, 79, 83, 128, 82, - 73, 69, 85, 76, 45, 80, 73, 69, 85, 80, 45, 84, 73, 75, 69, 85, 84, 128, - 82, 73, 69, 85, 76, 45, 80, 73, 69, 85, 80, 45, 83, 73, 79, 83, 128, 82, - 73, 69, 85, 76, 45, 80, 73, 69, 85, 80, 45, 80, 72, 73, 69, 85, 80, 72, - 128, 82, 73, 69, 85, 76, 45, 80, 73, 69, 85, 80, 45, 72, 73, 69, 85, 72, - 128, 82, 73, 69, 85, 76, 45, 80, 73, 69, 85, 80, 128, 82, 73, 69, 85, 76, - 45, 80, 72, 73, 69, 85, 80, 72, 128, 82, 73, 69, 85, 76, 45, 80, 65, 78, - 83, 73, 79, 83, 128, 82, 73, 69, 85, 76, 45, 78, 73, 69, 85, 78, 128, 82, - 73, 69, 85, 76, 45, 77, 73, 69, 85, 77, 45, 83, 73, 79, 83, 128, 82, 73, - 69, 85, 76, 45, 77, 73, 69, 85, 77, 45, 75, 73, 89, 69, 79, 75, 128, 82, - 73, 69, 85, 76, 45, 77, 73, 69, 85, 77, 45, 72, 73, 69, 85, 72, 128, 82, - 73, 69, 85, 76, 45, 77, 73, 69, 85, 77, 128, 82, 73, 69, 85, 76, 45, 75, - 73, 89, 69, 79, 75, 45, 83, 73, 79, 83, 128, 82, 73, 69, 85, 76, 45, 75, - 73, 89, 69, 79, 75, 45, 72, 73, 69, 85, 72, 128, 82, 73, 69, 85, 76, 45, - 75, 73, 89, 69, 79, 75, 128, 82, 73, 69, 85, 76, 45, 75, 65, 80, 89, 69, - 79, 85, 78, 80, 73, 69, 85, 80, 128, 82, 73, 69, 85, 76, 45, 72, 73, 69, - 85, 72, 128, 82, 73, 69, 85, 76, 45, 67, 73, 69, 85, 67, 128, 82, 73, 69, - 85, 204, 82, 73, 69, 76, 128, 82, 73, 69, 69, 128, 82, 73, 67, 69, 77, - 128, 82, 73, 67, 69, 128, 82, 73, 67, 197, 82, 73, 66, 66, 79, 78, 128, - 82, 73, 65, 204, 82, 72, 79, 84, 73, 195, 82, 72, 79, 128, 82, 72, 207, - 82, 72, 65, 128, 82, 71, 89, 73, 78, 71, 83, 128, 82, 71, 89, 65, 78, - 128, 82, 71, 89, 193, 82, 69, 86, 79, 76, 86, 73, 78, 199, 82, 69, 86, - 79, 76, 85, 84, 73, 79, 78, 128, 82, 69, 86, 77, 65, 128, 82, 69, 86, 73, - 65, 128, 82, 69, 86, 69, 82, 83, 69, 68, 128, 82, 69, 86, 69, 82, 83, 69, - 196, 82, 69, 86, 69, 82, 83, 197, 82, 69, 85, 88, 128, 82, 69, 85, 128, - 82, 69, 84, 85, 82, 78, 128, 82, 69, 84, 85, 82, 206, 82, 69, 84, 82, 79, - 70, 76, 69, 216, 82, 69, 84, 82, 69, 65, 84, 128, 82, 69, 84, 79, 82, 84, - 128, 82, 69, 83, 85, 80, 73, 78, 85, 83, 128, 82, 69, 83, 84, 82, 79, 79, - 77, 128, 82, 69, 83, 84, 82, 73, 67, 84, 69, 196, 82, 69, 83, 84, 128, - 82, 69, 83, 80, 79, 78, 83, 69, 128, 82, 69, 83, 79, 85, 82, 67, 69, 128, - 82, 69, 83, 79, 76, 85, 84, 73, 79, 78, 128, 82, 69, 83, 73, 83, 84, 65, - 78, 67, 69, 128, 82, 69, 83, 73, 68, 69, 78, 67, 69, 128, 82, 69, 83, - 200, 82, 69, 82, 69, 78, 71, 71, 65, 78, 128, 82, 69, 82, 69, 75, 65, 78, - 128, 82, 69, 80, 82, 69, 83, 69, 78, 84, 128, 82, 69, 80, 76, 65, 67, 69, - 77, 69, 78, 212, 82, 69, 80, 72, 128, 82, 69, 80, 69, 84, 73, 84, 73, 79, - 206, 82, 69, 80, 69, 65, 84, 69, 196, 82, 69, 80, 69, 65, 84, 128, 82, - 69, 80, 69, 65, 212, 82, 69, 80, 65, 89, 65, 128, 82, 69, 80, 65, 128, - 82, 69, 80, 193, 82, 69, 78, 84, 79, 71, 69, 78, 128, 82, 69, 78, 128, - 82, 69, 206, 82, 69, 77, 85, 128, 82, 69, 77, 69, 68, 89, 128, 82, 69, - 76, 73, 71, 73, 79, 78, 128, 82, 69, 76, 73, 69, 86, 69, 196, 82, 69, 76, - 69, 65, 83, 69, 128, 82, 69, 76, 65, 84, 73, 79, 78, 65, 204, 82, 69, 76, - 65, 84, 73, 79, 78, 128, 82, 69, 76, 65, 65, 128, 82, 69, 74, 65, 78, - 199, 82, 69, 73, 196, 82, 69, 71, 85, 76, 85, 83, 45, 52, 128, 82, 69, - 71, 85, 76, 85, 83, 45, 51, 128, 82, 69, 71, 85, 76, 85, 83, 45, 50, 128, - 82, 69, 71, 85, 76, 85, 83, 128, 82, 69, 71, 85, 76, 85, 211, 82, 69, 71, - 73, 83, 84, 69, 82, 69, 196, 82, 69, 71, 73, 79, 78, 65, 204, 82, 69, 71, - 73, 65, 45, 50, 128, 82, 69, 71, 73, 65, 128, 82, 69, 70, 79, 82, 77, 69, - 196, 82, 69, 70, 69, 82, 69, 78, 67, 197, 82, 69, 68, 85, 80, 76, 73, 67, - 65, 84, 73, 79, 78, 128, 82, 69, 67, 89, 67, 76, 73, 78, 199, 82, 69, 67, - 89, 67, 76, 69, 196, 82, 69, 67, 84, 73, 76, 73, 78, 69, 65, 210, 82, 69, - 67, 84, 65, 78, 71, 85, 76, 65, 210, 82, 69, 67, 84, 65, 78, 71, 76, 69, - 128, 82, 69, 67, 84, 65, 78, 71, 76, 197, 82, 69, 67, 82, 69, 65, 84, 73, - 79, 78, 65, 204, 82, 69, 67, 79, 82, 68, 73, 78, 199, 82, 69, 67, 79, 82, - 68, 69, 82, 128, 82, 69, 67, 79, 82, 196, 82, 69, 67, 69, 80, 84, 73, 86, - 197, 82, 69, 67, 69, 73, 86, 69, 82, 128, 82, 69, 65, 76, 71, 65, 82, 45, - 50, 128, 82, 69, 65, 76, 71, 65, 82, 128, 82, 69, 65, 72, 77, 85, 75, - 128, 82, 69, 65, 67, 72, 128, 82, 68, 207, 82, 68, 69, 204, 82, 66, 65, - 83, 193, 82, 65, 89, 83, 128, 82, 65, 89, 65, 78, 78, 65, 128, 82, 65, - 84, 73, 79, 128, 82, 65, 84, 72, 65, 128, 82, 65, 84, 72, 193, 82, 65, - 84, 65, 128, 82, 65, 84, 128, 82, 65, 83, 87, 65, 68, 73, 128, 82, 65, - 83, 79, 85, 204, 82, 65, 83, 72, 65, 128, 82, 65, 81, 128, 82, 65, 80, - 73, 83, 77, 65, 128, 82, 65, 78, 71, 197, 82, 65, 78, 65, 128, 82, 65, - 78, 128, 82, 65, 77, 211, 82, 65, 77, 66, 65, 84, 128, 82, 65, 75, 72, - 65, 78, 71, 128, 82, 65, 75, 65, 65, 82, 65, 65, 78, 83, 65, 89, 65, 128, - 82, 65, 73, 83, 73, 78, 199, 82, 65, 73, 83, 69, 196, 82, 65, 73, 78, 66, - 79, 87, 128, 82, 65, 73, 76, 87, 65, 89, 128, 82, 65, 73, 76, 87, 65, - 217, 82, 65, 73, 76, 128, 82, 65, 73, 68, 207, 82, 65, 73, 68, 65, 128, - 82, 65, 72, 77, 65, 84, 85, 76, 76, 65, 200, 82, 65, 72, 128, 82, 65, 70, - 69, 128, 82, 65, 69, 77, 128, 82, 65, 68, 73, 79, 65, 67, 84, 73, 86, - 197, 82, 65, 68, 73, 79, 128, 82, 65, 68, 73, 207, 82, 65, 68, 201, 82, - 65, 68, 128, 82, 65, 196, 82, 65, 67, 81, 85, 69, 212, 82, 65, 67, 73, - 78, 71, 128, 82, 65, 66, 66, 73, 84, 128, 82, 65, 66, 66, 73, 212, 82, - 65, 66, 128, 82, 65, 65, 73, 128, 82, 65, 51, 128, 82, 65, 50, 128, 82, - 65, 45, 50, 128, 82, 48, 50, 57, 128, 82, 48, 50, 56, 128, 82, 48, 50, - 55, 128, 82, 48, 50, 54, 128, 82, 48, 50, 53, 128, 82, 48, 50, 52, 128, - 82, 48, 50, 51, 128, 82, 48, 50, 50, 128, 82, 48, 50, 49, 128, 82, 48, - 50, 48, 128, 82, 48, 49, 57, 128, 82, 48, 49, 56, 128, 82, 48, 49, 55, - 128, 82, 48, 49, 54, 65, 128, 82, 48, 49, 54, 128, 82, 48, 49, 53, 128, - 82, 48, 49, 52, 128, 82, 48, 49, 51, 128, 82, 48, 49, 50, 128, 82, 48, - 49, 49, 128, 82, 48, 49, 48, 65, 128, 82, 48, 49, 48, 128, 82, 48, 48, - 57, 128, 82, 48, 48, 56, 128, 82, 48, 48, 55, 128, 82, 48, 48, 54, 128, - 82, 48, 48, 53, 128, 82, 48, 48, 52, 128, 82, 48, 48, 51, 66, 128, 82, - 48, 48, 51, 65, 128, 82, 48, 48, 51, 128, 82, 48, 48, 50, 65, 128, 82, - 48, 48, 50, 128, 82, 48, 48, 49, 128, 82, 45, 67, 82, 69, 197, 81, 89, - 88, 128, 81, 89, 85, 128, 81, 89, 84, 128, 81, 89, 82, 88, 128, 81, 89, - 82, 128, 81, 89, 80, 128, 81, 89, 79, 128, 81, 89, 73, 128, 81, 89, 69, - 69, 128, 81, 89, 69, 128, 81, 89, 65, 65, 128, 81, 89, 65, 128, 81, 89, - 128, 81, 87, 73, 128, 81, 87, 69, 69, 128, 81, 87, 69, 128, 81, 87, 65, - 65, 128, 81, 87, 65, 128, 81, 85, 88, 128, 81, 85, 86, 128, 81, 85, 85, - 86, 128, 81, 85, 85, 128, 81, 85, 84, 128, 81, 85, 83, 72, 83, 72, 65, - 89, 65, 128, 81, 85, 82, 88, 128, 81, 85, 82, 128, 81, 85, 80, 128, 81, - 85, 79, 88, 128, 81, 85, 79, 84, 197, 81, 85, 79, 84, 65, 84, 73, 79, - 206, 81, 85, 79, 84, 128, 81, 85, 79, 80, 128, 81, 85, 79, 128, 81, 85, - 75, 128, 81, 85, 73, 78, 84, 69, 83, 83, 69, 78, 67, 69, 128, 81, 85, 73, - 78, 68, 73, 67, 69, 83, 73, 77, 193, 81, 85, 73, 78, 67, 85, 78, 88, 128, - 81, 85, 73, 78, 65, 82, 73, 85, 211, 81, 85, 73, 76, 76, 128, 81, 85, 73, - 67, 203, 81, 85, 73, 128, 81, 85, 70, 128, 81, 85, 69, 83, 84, 73, 79, - 78, 69, 196, 81, 85, 69, 83, 84, 73, 79, 78, 128, 81, 85, 69, 83, 84, 73, - 79, 206, 81, 85, 69, 69, 78, 128, 81, 85, 69, 69, 206, 81, 85, 69, 128, - 81, 85, 66, 85, 84, 83, 128, 81, 85, 65, 84, 69, 82, 78, 73, 79, 206, 81, - 85, 65, 82, 84, 69, 82, 83, 128, 81, 85, 65, 82, 84, 69, 82, 211, 81, 85, - 65, 82, 84, 69, 82, 128, 81, 85, 65, 82, 84, 69, 210, 81, 85, 65, 78, 84, - 73, 84, 217, 81, 85, 65, 68, 82, 85, 80, 76, 197, 81, 85, 65, 68, 82, 65, - 78, 84, 128, 81, 85, 65, 68, 82, 65, 78, 212, 81, 85, 65, 68, 128, 81, - 85, 65, 196, 81, 85, 65, 128, 81, 85, 128, 81, 208, 81, 79, 88, 128, 81, - 79, 84, 128, 81, 79, 80, 72, 128, 81, 79, 80, 65, 128, 81, 79, 80, 128, - 81, 79, 79, 128, 81, 79, 207, 81, 79, 70, 128, 81, 79, 198, 81, 79, 65, - 128, 81, 79, 128, 81, 78, 128, 81, 73, 88, 128, 81, 73, 84, 83, 65, 128, - 81, 73, 84, 128, 81, 73, 80, 128, 81, 73, 73, 128, 81, 73, 69, 88, 128, - 81, 73, 69, 84, 128, 81, 73, 69, 80, 128, 81, 73, 69, 128, 81, 73, 128, - 81, 72, 87, 73, 128, 81, 72, 87, 69, 69, 128, 81, 72, 87, 69, 128, 81, - 72, 87, 65, 65, 128, 81, 72, 87, 65, 128, 81, 72, 85, 128, 81, 72, 79, - 128, 81, 72, 73, 128, 81, 72, 69, 69, 128, 81, 72, 69, 128, 81, 72, 65, - 65, 128, 81, 72, 65, 128, 81, 71, 65, 128, 81, 69, 84, 65, 78, 65, 128, - 81, 69, 69, 128, 81, 69, 128, 81, 65, 85, 128, 81, 65, 84, 65, 78, 128, - 81, 65, 82, 78, 69, 217, 81, 65, 82, 128, 81, 65, 81, 128, 81, 65, 80, - 72, 128, 81, 65, 77, 65, 84, 83, 128, 81, 65, 77, 65, 84, 211, 81, 65, - 76, 193, 81, 65, 73, 82, 84, 72, 82, 65, 128, 81, 65, 73, 128, 81, 65, - 70, 128, 81, 65, 198, 81, 65, 68, 77, 65, 128, 81, 65, 65, 73, 128, 81, - 65, 65, 70, 85, 128, 81, 65, 65, 70, 128, 81, 48, 48, 55, 128, 81, 48, - 48, 54, 128, 81, 48, 48, 53, 128, 81, 48, 48, 52, 128, 81, 48, 48, 51, - 128, 81, 48, 48, 50, 128, 81, 48, 48, 49, 128, 80, 90, 128, 80, 89, 88, - 128, 80, 89, 84, 128, 80, 89, 82, 88, 128, 80, 89, 82, 128, 80, 89, 80, - 128, 80, 89, 128, 80, 87, 79, 89, 128, 80, 87, 79, 79, 128, 80, 87, 79, - 128, 80, 87, 207, 80, 87, 73, 73, 128, 80, 87, 73, 128, 80, 87, 69, 69, - 128, 80, 87, 69, 128, 80, 87, 65, 65, 128, 80, 87, 128, 80, 86, 128, 80, - 85, 88, 128, 80, 85, 85, 84, 128, 80, 85, 85, 128, 80, 85, 84, 82, 69, - 70, 65, 67, 84, 73, 79, 78, 128, 80, 85, 84, 128, 80, 85, 212, 80, 85, - 83, 72, 80, 73, 78, 128, 80, 85, 83, 72, 80, 73, 75, 65, 128, 80, 85, 83, - 72, 73, 78, 199, 80, 85, 82, 88, 128, 80, 85, 82, 83, 69, 128, 80, 85, - 82, 80, 76, 197, 80, 85, 82, 78, 65, 77, 65, 128, 80, 85, 82, 73, 84, 89, - 128, 80, 85, 82, 73, 70, 89, 128, 80, 85, 82, 128, 80, 85, 81, 128, 80, - 85, 80, 128, 80, 85, 79, 88, 128, 80, 85, 79, 80, 128, 80, 85, 79, 128, - 80, 85, 78, 71, 65, 65, 77, 128, 80, 85, 78, 71, 128, 80, 85, 78, 67, 84, - 85, 65, 84, 73, 79, 78, 128, 80, 85, 78, 67, 84, 85, 65, 84, 73, 79, 206, - 80, 85, 77, 80, 128, 80, 85, 77, 128, 80, 85, 69, 128, 80, 85, 66, 76, - 73, 195, 80, 85, 65, 81, 128, 80, 85, 65, 69, 128, 80, 85, 50, 128, 80, - 85, 49, 128, 80, 85, 128, 80, 84, 72, 65, 72, 193, 80, 84, 69, 128, 80, - 83, 73, 76, 201, 80, 83, 73, 70, 73, 83, 84, 79, 83, 89, 78, 65, 71, 77, - 65, 128, 80, 83, 73, 70, 73, 83, 84, 79, 80, 65, 82, 65, 75, 65, 76, 69, - 83, 77, 65, 128, 80, 83, 73, 70, 73, 83, 84, 79, 206, 80, 83, 73, 70, 73, - 83, 84, 79, 76, 89, 71, 73, 83, 77, 65, 128, 80, 83, 73, 128, 80, 83, - 128, 80, 82, 79, 86, 69, 128, 80, 82, 79, 84, 79, 86, 65, 82, 89, 211, - 80, 82, 79, 84, 79, 211, 80, 82, 79, 84, 69, 67, 84, 69, 196, 80, 82, 79, - 83, 71, 69, 71, 82, 65, 77, 77, 69, 78, 73, 128, 80, 82, 79, 80, 79, 82, - 84, 73, 79, 78, 65, 204, 80, 82, 79, 80, 79, 82, 84, 73, 79, 78, 128, 80, - 82, 79, 80, 69, 82, 84, 217, 80, 82, 79, 80, 69, 76, 76, 69, 210, 80, 82, - 79, 79, 70, 128, 80, 82, 79, 76, 79, 78, 71, 69, 196, 80, 82, 79, 76, 65, - 84, 73, 79, 78, 197, 80, 82, 79, 74, 69, 67, 84, 73, 86, 69, 128, 80, 82, - 79, 74, 69, 67, 84, 73, 79, 78, 128, 80, 82, 79, 71, 82, 69, 83, 83, 128, - 80, 82, 79, 71, 82, 65, 205, 80, 82, 79, 70, 79, 85, 78, 68, 128, 80, 82, - 79, 68, 85, 67, 84, 128, 80, 82, 79, 68, 85, 67, 212, 80, 82, 73, 86, 65, - 84, 69, 128, 80, 82, 73, 86, 65, 84, 197, 80, 82, 73, 86, 65, 67, 217, - 80, 82, 73, 83, 72, 84, 72, 65, 77, 65, 84, 82, 193, 80, 82, 73, 78, 84, - 83, 128, 80, 82, 73, 78, 84, 128, 80, 82, 73, 78, 212, 80, 82, 73, 78, - 67, 69, 83, 83, 128, 80, 82, 73, 77, 69, 128, 80, 82, 73, 77, 197, 80, - 82, 69, 86, 73, 79, 85, 211, 80, 82, 69, 83, 69, 84, 128, 80, 82, 69, 83, - 69, 78, 84, 65, 84, 73, 79, 206, 80, 82, 69, 83, 67, 82, 73, 80, 84, 73, - 79, 206, 80, 82, 69, 80, 79, 78, 68, 69, 82, 65, 78, 67, 69, 128, 80, 82, - 69, 78, 75, 72, 65, 128, 80, 82, 69, 70, 65, 67, 197, 80, 82, 69, 67, 73, - 80, 73, 84, 65, 84, 69, 128, 80, 82, 69, 67, 69, 68, 73, 78, 199, 80, 82, - 69, 67, 69, 68, 69, 83, 128, 80, 82, 69, 67, 69, 68, 69, 211, 80, 82, 69, - 67, 69, 68, 69, 196, 80, 82, 69, 67, 69, 68, 69, 128, 80, 82, 69, 67, 69, - 68, 197, 80, 82, 65, 77, 45, 80, 73, 73, 128, 80, 82, 65, 77, 45, 80, 73, - 201, 80, 82, 65, 77, 45, 77, 85, 79, 89, 128, 80, 82, 65, 77, 45, 77, 85, - 79, 217, 80, 82, 65, 77, 45, 66, 85, 79, 78, 128, 80, 82, 65, 77, 45, 66, - 85, 79, 206, 80, 82, 65, 77, 45, 66, 69, 73, 128, 80, 82, 65, 77, 45, 66, - 69, 201, 80, 82, 65, 77, 128, 80, 82, 65, 205, 80, 82, 128, 80, 80, 86, - 128, 80, 80, 77, 128, 80, 80, 65, 128, 80, 79, 89, 128, 80, 79, 88, 128, - 80, 79, 87, 69, 82, 211, 80, 79, 87, 69, 82, 128, 80, 79, 87, 68, 69, 82, - 69, 196, 80, 79, 87, 68, 69, 82, 128, 80, 79, 85, 78, 196, 80, 79, 85, - 76, 84, 82, 217, 80, 79, 85, 67, 72, 128, 80, 79, 84, 65, 84, 79, 128, - 80, 79, 84, 65, 66, 76, 197, 80, 79, 212, 80, 79, 83, 84, 80, 79, 83, 73, - 84, 73, 79, 206, 80, 79, 83, 84, 66, 79, 88, 128, 80, 79, 83, 84, 65, - 204, 80, 79, 83, 84, 128, 80, 79, 83, 212, 80, 79, 83, 83, 69, 83, 83, - 73, 79, 78, 128, 80, 79, 82, 82, 69, 67, 84, 85, 83, 128, 80, 79, 82, 82, - 69, 67, 84, 85, 211, 80, 79, 80, 80, 69, 82, 128, 80, 79, 80, 128, 80, - 79, 208, 80, 79, 79, 68, 76, 69, 128, 80, 79, 79, 128, 80, 79, 78, 68, - 79, 128, 80, 79, 206, 80, 79, 77, 77, 69, 69, 128, 80, 79, 77, 77, 69, - 197, 80, 79, 76, 73, 83, 72, 128, 80, 79, 76, 73, 67, 197, 80, 79, 76, - 201, 80, 79, 76, 69, 128, 80, 79, 76, 197, 80, 79, 75, 82, 89, 84, 73, - 69, 128, 80, 79, 75, 79, 74, 73, 128, 80, 79, 73, 78, 84, 211, 80, 79, - 73, 78, 84, 79, 128, 80, 79, 73, 78, 84, 69, 82, 128, 80, 79, 73, 78, 84, - 69, 196, 80, 79, 73, 78, 84, 128, 80, 79, 73, 78, 212, 80, 79, 69, 84, - 82, 217, 80, 79, 69, 84, 73, 195, 80, 79, 68, 65, 84, 85, 83, 128, 80, - 79, 65, 128, 80, 79, 128, 80, 207, 80, 78, 69, 85, 77, 65, 84, 65, 128, - 80, 76, 85, 84, 79, 128, 80, 76, 85, 83, 45, 77, 73, 78, 85, 211, 80, 76, - 85, 83, 128, 80, 76, 85, 82, 65, 76, 128, 80, 76, 85, 77, 69, 196, 80, - 76, 85, 77, 128, 80, 76, 85, 75, 128, 80, 76, 85, 71, 128, 80, 76, 85, - 128, 80, 76, 79, 87, 128, 80, 76, 79, 80, 72, 85, 128, 80, 76, 69, 84, - 72, 82, 79, 78, 128, 80, 76, 68, 128, 80, 76, 65, 89, 73, 78, 199, 80, - 76, 65, 83, 84, 73, 67, 83, 128, 80, 76, 65, 78, 69, 128, 80, 76, 65, 78, - 197, 80, 76, 65, 78, 67, 203, 80, 76, 65, 75, 128, 80, 76, 65, 71, 73, - 79, 211, 80, 76, 65, 67, 69, 72, 79, 76, 68, 69, 210, 80, 76, 65, 67, - 197, 80, 76, 65, 128, 80, 73, 90, 90, 73, 67, 65, 84, 79, 128, 80, 73, - 90, 90, 65, 128, 80, 73, 88, 128, 80, 73, 87, 82, 128, 80, 73, 84, 67, - 72, 70, 79, 82, 75, 128, 80, 73, 84, 67, 72, 70, 79, 82, 203, 80, 73, 84, - 128, 80, 73, 83, 84, 79, 76, 128, 80, 73, 83, 69, 76, 69, 72, 128, 80, - 73, 83, 67, 69, 83, 128, 80, 73, 82, 73, 71, 128, 80, 73, 82, 73, 199, - 80, 73, 82, 73, 69, 69, 78, 128, 80, 73, 80, 73, 78, 71, 128, 80, 73, 80, - 65, 69, 77, 71, 66, 73, 69, 69, 128, 80, 73, 80, 65, 69, 77, 66, 65, 128, - 80, 73, 80, 128, 80, 73, 78, 87, 72, 69, 69, 204, 80, 73, 78, 69, 65, 80, - 80, 76, 69, 128, 80, 73, 78, 197, 80, 73, 78, 65, 82, 66, 79, 82, 65, 83, - 128, 80, 73, 76, 76, 128, 80, 73, 76, 197, 80, 73, 76, 67, 82, 79, 215, - 80, 73, 75, 85, 82, 85, 128, 80, 73, 75, 79, 128, 80, 73, 71, 128, 80, - 73, 199, 80, 73, 69, 88, 128, 80, 73, 69, 85, 80, 45, 84, 72, 73, 69, 85, - 84, 72, 128, 80, 73, 69, 85, 80, 45, 83, 83, 65, 78, 71, 83, 73, 79, 83, - 128, 80, 73, 69, 85, 80, 45, 83, 73, 79, 83, 45, 84, 73, 75, 69, 85, 84, - 128, 80, 73, 69, 85, 80, 45, 83, 73, 79, 83, 45, 84, 72, 73, 69, 85, 84, - 72, 128, 80, 73, 69, 85, 80, 45, 83, 73, 79, 83, 45, 80, 73, 69, 85, 80, - 128, 80, 73, 69, 85, 80, 45, 83, 73, 79, 83, 45, 75, 73, 89, 69, 79, 75, - 128, 80, 73, 69, 85, 80, 45, 83, 73, 79, 83, 45, 67, 73, 69, 85, 67, 128, - 80, 73, 69, 85, 80, 45, 82, 73, 69, 85, 76, 45, 80, 72, 73, 69, 85, 80, - 72, 128, 80, 73, 69, 85, 80, 45, 82, 73, 69, 85, 76, 128, 80, 73, 69, 85, - 80, 45, 78, 73, 69, 85, 78, 128, 80, 73, 69, 85, 80, 45, 77, 73, 69, 85, - 77, 128, 80, 73, 69, 85, 80, 45, 75, 72, 73, 69, 85, 75, 72, 128, 80, 73, - 69, 85, 80, 45, 67, 73, 69, 85, 67, 128, 80, 73, 69, 85, 80, 45, 67, 72, - 73, 69, 85, 67, 72, 128, 80, 73, 69, 85, 208, 80, 73, 69, 84, 128, 80, - 73, 69, 80, 128, 80, 73, 69, 69, 84, 128, 80, 73, 69, 69, 81, 128, 80, - 73, 69, 67, 69, 128, 80, 73, 69, 128, 80, 73, 67, 75, 69, 84, 128, 80, - 73, 67, 75, 128, 80, 73, 65, 83, 85, 84, 79, 82, 85, 128, 80, 73, 65, 83, - 77, 193, 80, 73, 65, 78, 79, 128, 80, 201, 80, 72, 87, 65, 128, 80, 72, - 85, 84, 72, 65, 79, 128, 80, 72, 85, 210, 80, 72, 85, 78, 71, 128, 80, - 72, 82, 65, 83, 69, 128, 80, 72, 79, 78, 69, 83, 128, 80, 72, 79, 69, 78, - 73, 67, 73, 65, 206, 80, 72, 79, 65, 128, 80, 72, 79, 128, 80, 72, 207, - 80, 72, 78, 65, 69, 203, 80, 72, 73, 78, 84, 72, 85, 128, 80, 72, 73, 76, - 79, 83, 79, 80, 72, 69, 82, 211, 80, 72, 73, 76, 73, 80, 80, 73, 78, 197, - 80, 72, 73, 69, 85, 80, 72, 45, 84, 72, 73, 69, 85, 84, 72, 128, 80, 72, - 73, 69, 85, 80, 72, 45, 83, 73, 79, 83, 128, 80, 72, 73, 69, 85, 80, 72, - 45, 80, 73, 69, 85, 80, 128, 80, 72, 73, 69, 85, 80, 72, 45, 72, 73, 69, - 85, 72, 128, 80, 72, 73, 69, 85, 80, 200, 80, 72, 73, 128, 80, 72, 201, - 80, 72, 69, 69, 128, 80, 72, 69, 128, 80, 72, 65, 83, 69, 45, 198, 80, - 72, 65, 83, 69, 45, 194, 80, 72, 65, 82, 89, 78, 71, 69, 65, 204, 80, 72, - 65, 82, 128, 80, 72, 65, 78, 128, 80, 72, 65, 77, 128, 80, 72, 65, 73, - 83, 84, 79, 211, 80, 72, 65, 71, 83, 45, 80, 193, 80, 72, 65, 65, 82, 75, - 65, 65, 128, 80, 72, 65, 65, 128, 80, 72, 65, 128, 80, 71, 128, 80, 70, - 128, 80, 69, 85, 88, 128, 80, 69, 85, 84, 65, 69, 128, 80, 69, 85, 84, - 128, 80, 69, 84, 65, 83, 84, 79, 75, 79, 85, 70, 73, 83, 77, 65, 128, 80, - 69, 84, 65, 83, 84, 73, 128, 80, 69, 84, 65, 83, 77, 65, 128, 80, 69, 84, - 65, 76, 76, 69, 196, 80, 69, 83, 79, 128, 80, 69, 83, 207, 80, 69, 83, - 72, 50, 128, 80, 69, 83, 69, 84, 193, 80, 69, 211, 80, 69, 82, 84, 72, - 207, 80, 69, 82, 83, 80, 69, 67, 84, 73, 86, 69, 128, 80, 69, 82, 83, 79, - 78, 65, 204, 80, 69, 82, 83, 79, 78, 128, 80, 69, 82, 83, 79, 206, 80, - 69, 82, 83, 73, 65, 206, 80, 69, 82, 83, 69, 86, 69, 82, 73, 78, 199, 80, - 69, 82, 80, 69, 78, 68, 73, 67, 85, 76, 65, 82, 128, 80, 69, 82, 80, 69, - 78, 68, 73, 67, 85, 76, 65, 210, 80, 69, 82, 77, 73, 84, 84, 69, 196, 80, - 69, 82, 77, 65, 78, 69, 78, 212, 80, 69, 82, 73, 83, 80, 79, 77, 69, 78, - 73, 128, 80, 69, 82, 73, 83, 80, 79, 77, 69, 78, 201, 80, 69, 82, 70, 79, - 82, 77, 73, 78, 199, 80, 69, 82, 70, 69, 67, 84, 85, 205, 80, 69, 82, 70, - 69, 67, 84, 65, 128, 80, 69, 82, 70, 69, 67, 84, 193, 80, 69, 82, 67, 85, - 83, 83, 73, 86, 69, 128, 80, 69, 82, 67, 69, 78, 212, 80, 69, 80, 69, 84, - 128, 80, 69, 80, 69, 212, 80, 69, 79, 82, 84, 200, 80, 69, 79, 80, 76, - 69, 128, 80, 69, 78, 84, 65, 83, 69, 77, 69, 128, 80, 69, 78, 84, 65, 71, - 82, 65, 77, 128, 80, 69, 78, 84, 65, 71, 79, 78, 128, 80, 69, 78, 83, 85, - 128, 80, 69, 78, 83, 73, 86, 197, 80, 69, 78, 78, 217, 80, 69, 78, 73, - 72, 73, 128, 80, 69, 78, 71, 85, 73, 78, 128, 80, 69, 78, 71, 75, 65, 76, - 128, 80, 69, 78, 69, 84, 82, 65, 84, 73, 79, 78, 128, 80, 69, 78, 67, 73, - 76, 128, 80, 69, 76, 65, 83, 84, 79, 78, 128, 80, 69, 76, 65, 83, 84, 79, - 206, 80, 69, 73, 84, 72, 128, 80, 69, 72, 69, 72, 128, 80, 69, 72, 69, - 200, 80, 69, 72, 128, 80, 69, 200, 80, 69, 69, 90, 73, 128, 80, 69, 69, - 83, 72, 73, 128, 80, 69, 69, 80, 128, 80, 69, 69, 77, 128, 80, 69, 69, - 128, 80, 69, 68, 69, 83, 84, 82, 73, 65, 78, 83, 128, 80, 69, 68, 69, 83, - 84, 82, 73, 65, 78, 128, 80, 69, 68, 69, 83, 84, 65, 76, 128, 80, 69, 68, - 69, 83, 84, 65, 204, 80, 69, 68, 65, 204, 80, 69, 65, 67, 72, 128, 80, - 69, 65, 67, 69, 128, 80, 69, 65, 67, 197, 80, 68, 73, 128, 80, 68, 70, - 128, 80, 68, 128, 80, 67, 128, 80, 65, 90, 69, 82, 128, 80, 65, 89, 69, - 82, 79, 75, 128, 80, 65, 89, 65, 78, 78, 65, 128, 80, 65, 89, 128, 80, - 65, 88, 128, 80, 65, 87, 78, 128, 80, 65, 215, 80, 65, 86, 73, 89, 65, - 78, 73, 128, 80, 65, 85, 128, 80, 65, 84, 84, 69, 82, 78, 128, 80, 65, - 84, 72, 65, 77, 65, 83, 65, 84, 128, 80, 65, 84, 200, 80, 65, 84, 65, 75, - 128, 80, 65, 84, 65, 72, 128, 80, 65, 84, 128, 80, 65, 83, 85, 81, 128, - 80, 65, 83, 83, 80, 79, 82, 212, 80, 65, 83, 83, 73, 86, 69, 45, 80, 85, - 76, 76, 45, 85, 80, 45, 79, 85, 84, 80, 85, 212, 80, 65, 83, 83, 73, 86, - 69, 45, 80, 85, 76, 76, 45, 68, 79, 87, 78, 45, 79, 85, 84, 80, 85, 212, - 80, 65, 83, 72, 84, 65, 128, 80, 65, 83, 72, 65, 69, 128, 80, 65, 83, 69, - 81, 128, 80, 65, 83, 65, 78, 71, 65, 206, 80, 65, 82, 85, 77, 128, 80, - 65, 82, 84, 217, 80, 65, 82, 84, 78, 69, 82, 83, 72, 73, 208, 80, 65, 82, - 84, 73, 65, 76, 76, 89, 45, 82, 69, 67, 89, 67, 76, 69, 196, 80, 65, 82, - 84, 73, 65, 204, 80, 65, 82, 84, 72, 73, 65, 206, 80, 65, 82, 212, 80, - 65, 82, 73, 67, 72, 79, 78, 128, 80, 65, 82, 69, 83, 84, 73, 71, 77, 69, - 78, 79, 206, 80, 65, 82, 69, 82, 69, 78, 128, 80, 65, 82, 69, 78, 84, 72, - 69, 83, 73, 83, 128, 80, 65, 82, 69, 78, 84, 72, 69, 83, 73, 211, 80, 65, - 82, 65, 80, 72, 82, 65, 83, 197, 80, 65, 82, 65, 76, 76, 69, 76, 79, 71, - 82, 65, 77, 128, 80, 65, 82, 65, 76, 76, 69, 76, 128, 80, 65, 82, 65, 76, - 76, 69, 204, 80, 65, 82, 65, 75, 76, 73, 84, 73, 75, 73, 128, 80, 65, 82, - 65, 75, 76, 73, 84, 73, 75, 201, 80, 65, 82, 65, 75, 65, 76, 69, 83, 77, - 193, 80, 65, 82, 65, 71, 82, 65, 80, 72, 79, 83, 128, 80, 65, 82, 65, 71, - 82, 65, 80, 72, 128, 80, 65, 82, 65, 71, 82, 65, 80, 200, 80, 65, 82, 65, - 128, 80, 65, 82, 128, 80, 65, 80, 89, 82, 85, 83, 128, 80, 65, 80, 69, - 82, 67, 76, 73, 80, 128, 80, 65, 80, 69, 210, 80, 65, 80, 128, 80, 65, - 208, 80, 65, 207, 80, 65, 78, 89, 85, 75, 85, 128, 80, 65, 78, 89, 73, - 75, 85, 128, 80, 65, 78, 89, 69, 67, 69, 75, 128, 80, 65, 78, 89, 65, 78, - 71, 71, 65, 128, 80, 65, 78, 89, 65, 75, 82, 65, 128, 80, 65, 78, 84, 73, - 128, 80, 65, 78, 83, 73, 79, 83, 45, 80, 73, 69, 85, 80, 128, 80, 65, 78, - 83, 73, 79, 83, 45, 75, 65, 80, 89, 69, 79, 85, 78, 80, 73, 69, 85, 80, - 128, 80, 65, 78, 79, 78, 71, 79, 78, 65, 78, 128, 80, 65, 78, 79, 76, 79, - 78, 71, 128, 80, 65, 78, 71, 87, 73, 83, 65, 68, 128, 80, 65, 78, 71, 82, - 65, 78, 71, 75, 69, 80, 128, 80, 65, 78, 71, 79, 76, 65, 84, 128, 80, 65, - 78, 71, 76, 79, 78, 71, 128, 80, 65, 78, 71, 76, 65, 89, 65, 82, 128, 80, - 65, 78, 71, 75, 79, 78, 128, 80, 65, 78, 71, 75, 65, 84, 128, 80, 65, 78, - 71, 72, 85, 76, 85, 128, 80, 65, 78, 71, 128, 80, 65, 78, 69, 85, 76, 69, - 85, 78, 71, 128, 80, 65, 78, 68, 193, 80, 65, 78, 65, 69, 76, 65, 69, 78, - 71, 128, 80, 65, 78, 128, 80, 65, 77, 85, 78, 71, 75, 65, 72, 128, 80, - 65, 77, 85, 68, 80, 79, 68, 128, 80, 65, 77, 83, 72, 65, 69, 128, 80, 65, - 77, 80, 72, 89, 76, 73, 65, 206, 80, 65, 77, 73, 78, 71, 75, 65, 76, 128, - 80, 65, 77, 69, 80, 69, 84, 128, 80, 65, 77, 69, 78, 69, 78, 71, 128, 80, - 65, 77, 65, 68, 65, 128, 80, 65, 77, 65, 65, 69, 72, 128, 80, 65, 76, 85, - 84, 65, 128, 80, 65, 76, 79, 67, 72, 75, 65, 128, 80, 65, 76, 205, 80, - 65, 76, 76, 65, 87, 65, 128, 80, 65, 76, 76, 65, 83, 128, 80, 65, 76, 69, - 84, 84, 69, 128, 80, 65, 76, 65, 85, 78, 199, 80, 65, 76, 65, 84, 65, 76, - 73, 90, 69, 196, 80, 65, 76, 65, 84, 65, 76, 73, 90, 65, 84, 73, 79, 78, - 128, 80, 65, 76, 65, 84, 65, 204, 80, 65, 75, 80, 65, 203, 80, 65, 73, - 89, 65, 78, 78, 79, 73, 128, 80, 65, 73, 82, 84, 72, 82, 65, 128, 80, 65, - 73, 82, 69, 196, 80, 65, 73, 128, 80, 65, 72, 76, 65, 86, 201, 80, 65, - 72, 128, 80, 65, 71, 69, 82, 128, 80, 65, 71, 197, 80, 65, 68, 77, 193, - 80, 65, 68, 68, 73, 78, 199, 80, 65, 68, 193, 80, 65, 68, 128, 80, 65, - 67, 75, 73, 78, 71, 128, 80, 65, 67, 75, 65, 71, 69, 128, 80, 65, 65, 84, - 85, 128, 80, 65, 65, 83, 69, 78, 84, 79, 128, 80, 65, 65, 82, 65, 69, - 128, 80, 65, 65, 77, 128, 80, 65, 65, 73, 128, 80, 65, 65, 45, 80, 73, - 76, 76, 65, 128, 80, 65, 65, 128, 80, 50, 128, 80, 48, 49, 49, 128, 80, - 48, 49, 48, 128, 80, 48, 48, 57, 128, 80, 48, 48, 56, 128, 80, 48, 48, - 55, 128, 80, 48, 48, 54, 128, 80, 48, 48, 53, 128, 80, 48, 48, 52, 128, - 80, 48, 48, 51, 65, 128, 80, 48, 48, 51, 128, 80, 48, 48, 50, 128, 80, - 48, 48, 49, 65, 128, 80, 48, 48, 49, 128, 79, 89, 82, 65, 78, 73, 83, 77, - 193, 79, 89, 65, 78, 78, 65, 128, 79, 88, 73, 65, 128, 79, 88, 73, 193, - 79, 88, 69, 73, 65, 201, 79, 88, 69, 73, 193, 79, 86, 69, 82, 82, 73, 68, - 69, 128, 79, 86, 69, 82, 76, 79, 78, 199, 79, 86, 69, 82, 76, 73, 78, 69, + 84, 45, 80, 79, 73, 78, 84, 73, 78, 199, 82, 73, 71, 72, 84, 45, 76, 73, + 71, 72, 84, 69, 196, 82, 73, 71, 72, 84, 45, 72, 65, 78, 68, 69, 196, 82, + 73, 71, 72, 84, 45, 72, 65, 78, 196, 82, 73, 71, 72, 84, 45, 70, 65, 67, + 73, 78, 199, 82, 73, 71, 72, 84, 128, 82, 73, 69, 85, 76, 45, 89, 69, 83, + 73, 69, 85, 78, 71, 128, 82, 73, 69, 85, 76, 45, 89, 69, 79, 82, 73, 78, + 72, 73, 69, 85, 72, 45, 72, 73, 69, 85, 72, 128, 82, 73, 69, 85, 76, 45, + 89, 69, 79, 82, 73, 78, 72, 73, 69, 85, 72, 128, 82, 73, 69, 85, 76, 45, + 84, 73, 75, 69, 85, 84, 45, 72, 73, 69, 85, 72, 128, 82, 73, 69, 85, 76, + 45, 84, 73, 75, 69, 85, 84, 128, 82, 73, 69, 85, 76, 45, 84, 72, 73, 69, + 85, 84, 72, 128, 82, 73, 69, 85, 76, 45, 83, 83, 65, 78, 71, 84, 73, 75, + 69, 85, 84, 128, 82, 73, 69, 85, 76, 45, 83, 83, 65, 78, 71, 83, 73, 79, + 83, 128, 82, 73, 69, 85, 76, 45, 83, 83, 65, 78, 71, 80, 73, 69, 85, 80, + 128, 82, 73, 69, 85, 76, 45, 83, 83, 65, 78, 71, 75, 73, 89, 69, 79, 75, + 128, 82, 73, 69, 85, 76, 45, 83, 73, 79, 83, 128, 82, 73, 69, 85, 76, 45, + 80, 73, 69, 85, 80, 45, 84, 73, 75, 69, 85, 84, 128, 82, 73, 69, 85, 76, + 45, 80, 73, 69, 85, 80, 45, 83, 73, 79, 83, 128, 82, 73, 69, 85, 76, 45, + 80, 73, 69, 85, 80, 45, 80, 72, 73, 69, 85, 80, 72, 128, 82, 73, 69, 85, + 76, 45, 80, 73, 69, 85, 80, 45, 72, 73, 69, 85, 72, 128, 82, 73, 69, 85, + 76, 45, 80, 73, 69, 85, 80, 128, 82, 73, 69, 85, 76, 45, 80, 72, 73, 69, + 85, 80, 72, 128, 82, 73, 69, 85, 76, 45, 80, 65, 78, 83, 73, 79, 83, 128, + 82, 73, 69, 85, 76, 45, 78, 73, 69, 85, 78, 128, 82, 73, 69, 85, 76, 45, + 77, 73, 69, 85, 77, 45, 83, 73, 79, 83, 128, 82, 73, 69, 85, 76, 45, 77, + 73, 69, 85, 77, 45, 75, 73, 89, 69, 79, 75, 128, 82, 73, 69, 85, 76, 45, + 77, 73, 69, 85, 77, 45, 72, 73, 69, 85, 72, 128, 82, 73, 69, 85, 76, 45, + 77, 73, 69, 85, 77, 128, 82, 73, 69, 85, 76, 45, 75, 73, 89, 69, 79, 75, + 45, 83, 73, 79, 83, 128, 82, 73, 69, 85, 76, 45, 75, 73, 89, 69, 79, 75, + 45, 72, 73, 69, 85, 72, 128, 82, 73, 69, 85, 76, 45, 75, 73, 89, 69, 79, + 75, 128, 82, 73, 69, 85, 76, 45, 75, 65, 80, 89, 69, 79, 85, 78, 80, 73, + 69, 85, 80, 128, 82, 73, 69, 85, 76, 45, 72, 73, 69, 85, 72, 128, 82, 73, + 69, 85, 76, 45, 67, 73, 69, 85, 67, 128, 82, 73, 69, 85, 204, 82, 73, 69, + 76, 128, 82, 73, 69, 69, 128, 82, 73, 67, 69, 77, 128, 82, 73, 67, 69, + 128, 82, 73, 67, 197, 82, 73, 66, 66, 79, 78, 128, 82, 73, 66, 66, 79, + 206, 82, 73, 65, 204, 82, 72, 79, 84, 73, 195, 82, 72, 79, 128, 82, 72, + 207, 82, 72, 65, 128, 82, 72, 128, 82, 71, 89, 73, 78, 71, 83, 128, 82, + 71, 89, 65, 78, 128, 82, 71, 89, 193, 82, 69, 86, 79, 76, 86, 73, 78, + 199, 82, 69, 86, 79, 76, 85, 84, 73, 79, 78, 128, 82, 69, 86, 77, 65, + 128, 82, 69, 86, 73, 65, 128, 82, 69, 86, 69, 82, 83, 69, 68, 45, 83, 67, + 72, 87, 65, 128, 82, 69, 86, 69, 82, 83, 69, 68, 128, 82, 69, 86, 69, 82, + 83, 69, 196, 82, 69, 86, 69, 82, 83, 197, 82, 69, 85, 88, 128, 82, 69, + 85, 128, 82, 69, 84, 85, 82, 78, 128, 82, 69, 84, 85, 82, 206, 82, 69, + 84, 82, 79, 70, 76, 69, 216, 82, 69, 84, 82, 69, 65, 84, 128, 82, 69, 84, + 79, 82, 84, 128, 82, 69, 83, 85, 80, 73, 78, 85, 83, 128, 82, 69, 83, 84, + 82, 79, 79, 77, 128, 82, 69, 83, 84, 82, 73, 67, 84, 69, 196, 82, 69, 83, + 84, 128, 82, 69, 83, 80, 79, 78, 83, 69, 128, 82, 69, 83, 79, 85, 82, 67, + 69, 128, 82, 69, 83, 79, 76, 85, 84, 73, 79, 78, 128, 82, 69, 83, 73, 83, + 84, 65, 78, 67, 69, 128, 82, 69, 83, 73, 68, 69, 78, 67, 69, 128, 82, 69, + 83, 200, 82, 69, 82, 69, 78, 71, 71, 65, 78, 128, 82, 69, 82, 69, 75, 65, + 78, 128, 82, 69, 80, 82, 69, 83, 69, 78, 84, 128, 82, 69, 80, 76, 65, 67, + 69, 77, 69, 78, 212, 82, 69, 80, 72, 128, 82, 69, 80, 69, 84, 73, 84, 73, + 79, 206, 82, 69, 80, 69, 65, 84, 69, 196, 82, 69, 80, 69, 65, 84, 128, + 82, 69, 80, 69, 65, 212, 82, 69, 80, 65, 89, 65, 128, 82, 69, 80, 65, + 128, 82, 69, 80, 193, 82, 69, 78, 84, 79, 71, 69, 78, 128, 82, 69, 78, + 128, 82, 69, 206, 82, 69, 77, 85, 128, 82, 69, 77, 73, 78, 68, 69, 210, + 82, 69, 77, 69, 68, 89, 128, 82, 69, 76, 73, 71, 73, 79, 78, 128, 82, 69, + 76, 73, 69, 86, 69, 196, 82, 69, 76, 69, 65, 83, 69, 128, 82, 69, 76, 65, + 84, 73, 79, 78, 65, 204, 82, 69, 76, 65, 84, 73, 79, 78, 128, 82, 69, 76, + 65, 65, 128, 82, 69, 74, 65, 78, 199, 82, 69, 73, 196, 82, 69, 73, 128, + 82, 69, 71, 85, 76, 85, 83, 45, 52, 128, 82, 69, 71, 85, 76, 85, 83, 45, + 51, 128, 82, 69, 71, 85, 76, 85, 83, 45, 50, 128, 82, 69, 71, 85, 76, 85, + 83, 128, 82, 69, 71, 85, 76, 85, 211, 82, 69, 71, 73, 83, 84, 69, 82, 69, + 196, 82, 69, 71, 73, 79, 78, 65, 204, 82, 69, 71, 73, 65, 45, 50, 128, + 82, 69, 71, 73, 65, 128, 82, 69, 70, 79, 82, 77, 69, 196, 82, 69, 70, 69, + 82, 69, 78, 67, 197, 82, 69, 68, 85, 80, 76, 73, 67, 65, 84, 73, 79, 78, + 128, 82, 69, 67, 89, 67, 76, 73, 78, 199, 82, 69, 67, 89, 67, 76, 69, + 196, 82, 69, 67, 84, 73, 76, 73, 78, 69, 65, 210, 82, 69, 67, 84, 65, 78, + 71, 85, 76, 65, 210, 82, 69, 67, 84, 65, 78, 71, 76, 69, 128, 82, 69, 67, + 84, 65, 78, 71, 76, 197, 82, 69, 67, 82, 69, 65, 84, 73, 79, 78, 65, 204, + 82, 69, 67, 79, 82, 68, 73, 78, 199, 82, 69, 67, 79, 82, 68, 69, 82, 128, + 82, 69, 67, 79, 82, 68, 128, 82, 69, 67, 79, 82, 196, 82, 69, 67, 69, 80, + 84, 73, 86, 197, 82, 69, 67, 69, 73, 86, 69, 82, 128, 82, 69, 67, 69, 73, + 86, 69, 210, 82, 69, 65, 76, 71, 65, 82, 45, 50, 128, 82, 69, 65, 76, 71, + 65, 82, 128, 82, 69, 65, 72, 77, 85, 75, 128, 82, 69, 65, 67, 72, 128, + 82, 68, 207, 82, 68, 69, 204, 82, 66, 65, 83, 193, 82, 65, 89, 83, 128, + 82, 65, 89, 211, 82, 65, 89, 65, 78, 78, 65, 128, 82, 65, 84, 73, 79, + 128, 82, 65, 84, 72, 65, 128, 82, 65, 84, 72, 193, 82, 65, 84, 65, 128, + 82, 65, 84, 128, 82, 65, 83, 87, 65, 68, 73, 128, 82, 65, 83, 79, 85, + 204, 82, 65, 83, 72, 65, 128, 82, 65, 81, 128, 82, 65, 80, 73, 83, 77, + 65, 128, 82, 65, 78, 71, 197, 82, 65, 78, 65, 128, 82, 65, 78, 128, 82, + 65, 77, 211, 82, 65, 77, 66, 65, 84, 128, 82, 65, 75, 72, 65, 78, 71, + 128, 82, 65, 75, 65, 65, 82, 65, 65, 78, 83, 65, 89, 65, 128, 82, 65, 73, + 83, 73, 78, 199, 82, 65, 73, 83, 69, 196, 82, 65, 73, 78, 66, 79, 87, + 128, 82, 65, 73, 76, 87, 65, 89, 128, 82, 65, 73, 76, 87, 65, 217, 82, + 65, 73, 76, 128, 82, 65, 73, 68, 207, 82, 65, 73, 68, 65, 128, 82, 65, + 72, 77, 65, 84, 85, 76, 76, 65, 200, 82, 65, 72, 128, 82, 65, 70, 69, + 128, 82, 65, 69, 77, 128, 82, 65, 68, 73, 79, 65, 67, 84, 73, 86, 197, + 82, 65, 68, 73, 79, 128, 82, 65, 68, 73, 207, 82, 65, 68, 201, 82, 65, + 68, 128, 82, 65, 196, 82, 65, 67, 81, 85, 69, 212, 82, 65, 67, 73, 78, + 71, 128, 82, 65, 67, 73, 78, 199, 82, 65, 66, 66, 73, 84, 128, 82, 65, + 66, 66, 73, 212, 82, 65, 66, 128, 82, 65, 65, 73, 128, 82, 65, 51, 128, + 82, 65, 50, 128, 82, 65, 45, 50, 128, 82, 48, 50, 57, 128, 82, 48, 50, + 56, 128, 82, 48, 50, 55, 128, 82, 48, 50, 54, 128, 82, 48, 50, 53, 128, + 82, 48, 50, 52, 128, 82, 48, 50, 51, 128, 82, 48, 50, 50, 128, 82, 48, + 50, 49, 128, 82, 48, 50, 48, 128, 82, 48, 49, 57, 128, 82, 48, 49, 56, + 128, 82, 48, 49, 55, 128, 82, 48, 49, 54, 65, 128, 82, 48, 49, 54, 128, + 82, 48, 49, 53, 128, 82, 48, 49, 52, 128, 82, 48, 49, 51, 128, 82, 48, + 49, 50, 128, 82, 48, 49, 49, 128, 82, 48, 49, 48, 65, 128, 82, 48, 49, + 48, 128, 82, 48, 48, 57, 128, 82, 48, 48, 56, 128, 82, 48, 48, 55, 128, + 82, 48, 48, 54, 128, 82, 48, 48, 53, 128, 82, 48, 48, 52, 128, 82, 48, + 48, 51, 66, 128, 82, 48, 48, 51, 65, 128, 82, 48, 48, 51, 128, 82, 48, + 48, 50, 65, 128, 82, 48, 48, 50, 128, 82, 48, 48, 49, 128, 82, 45, 67, + 82, 69, 197, 81, 89, 88, 128, 81, 89, 85, 128, 81, 89, 84, 128, 81, 89, + 82, 88, 128, 81, 89, 82, 128, 81, 89, 80, 128, 81, 89, 79, 128, 81, 89, + 73, 128, 81, 89, 69, 69, 128, 81, 89, 69, 128, 81, 89, 65, 65, 128, 81, + 89, 65, 128, 81, 89, 128, 81, 87, 73, 128, 81, 87, 69, 69, 128, 81, 87, + 69, 128, 81, 87, 65, 65, 128, 81, 87, 65, 128, 81, 85, 88, 128, 81, 85, + 86, 128, 81, 85, 85, 86, 128, 81, 85, 85, 128, 81, 85, 84, 128, 81, 85, + 83, 72, 83, 72, 65, 89, 65, 128, 81, 85, 82, 88, 128, 81, 85, 82, 128, + 81, 85, 80, 128, 81, 85, 79, 88, 128, 81, 85, 79, 84, 197, 81, 85, 79, + 84, 65, 84, 73, 79, 206, 81, 85, 79, 84, 128, 81, 85, 79, 80, 128, 81, + 85, 79, 128, 81, 85, 75, 128, 81, 85, 73, 78, 84, 69, 83, 83, 69, 78, 67, + 69, 128, 81, 85, 73, 78, 68, 73, 67, 69, 83, 73, 77, 193, 81, 85, 73, 78, + 67, 85, 78, 88, 128, 81, 85, 73, 78, 65, 82, 73, 85, 211, 81, 85, 73, 76, + 212, 81, 85, 73, 76, 76, 128, 81, 85, 73, 67, 203, 81, 85, 73, 128, 81, + 85, 70, 128, 81, 85, 69, 83, 84, 73, 79, 78, 69, 196, 81, 85, 69, 83, 84, + 73, 79, 78, 128, 81, 85, 69, 83, 84, 73, 79, 206, 81, 85, 69, 69, 78, + 128, 81, 85, 69, 69, 206, 81, 85, 69, 128, 81, 85, 66, 85, 84, 83, 128, + 81, 85, 65, 84, 69, 82, 78, 73, 79, 206, 81, 85, 65, 82, 84, 69, 82, 83, + 128, 81, 85, 65, 82, 84, 69, 82, 211, 81, 85, 65, 82, 84, 69, 82, 128, + 81, 85, 65, 82, 84, 69, 210, 81, 85, 65, 78, 84, 73, 84, 217, 81, 85, 65, + 68, 82, 85, 80, 76, 197, 81, 85, 65, 68, 82, 65, 78, 84, 128, 81, 85, 65, + 68, 82, 65, 78, 212, 81, 85, 65, 68, 67, 79, 76, 79, 78, 128, 81, 85, 65, + 68, 128, 81, 85, 65, 196, 81, 85, 65, 128, 81, 85, 128, 81, 208, 81, 79, + 88, 128, 81, 79, 84, 128, 81, 79, 80, 72, 128, 81, 79, 80, 65, 128, 81, + 79, 80, 128, 81, 79, 79, 128, 81, 79, 207, 81, 79, 70, 128, 81, 79, 198, + 81, 79, 65, 128, 81, 79, 128, 81, 78, 128, 81, 73, 88, 128, 81, 73, 84, + 83, 65, 128, 81, 73, 84, 128, 81, 73, 80, 128, 81, 73, 73, 128, 81, 73, + 69, 88, 128, 81, 73, 69, 84, 128, 81, 73, 69, 80, 128, 81, 73, 69, 128, + 81, 73, 128, 81, 72, 87, 73, 128, 81, 72, 87, 69, 69, 128, 81, 72, 87, + 69, 128, 81, 72, 87, 65, 65, 128, 81, 72, 87, 65, 128, 81, 72, 85, 128, + 81, 72, 79, 80, 72, 128, 81, 72, 79, 128, 81, 72, 73, 128, 81, 72, 69, + 69, 128, 81, 72, 69, 128, 81, 72, 65, 85, 128, 81, 72, 65, 65, 128, 81, + 72, 65, 128, 81, 71, 65, 128, 81, 69, 84, 65, 78, 65, 128, 81, 69, 69, + 128, 81, 69, 128, 81, 65, 89, 128, 81, 65, 85, 128, 81, 65, 84, 65, 78, + 128, 81, 65, 82, 78, 69, 217, 81, 65, 82, 128, 81, 65, 81, 128, 81, 65, + 80, 72, 128, 81, 65, 77, 65, 84, 83, 128, 81, 65, 77, 65, 84, 211, 81, + 65, 76, 193, 81, 65, 73, 82, 84, 72, 82, 65, 128, 81, 65, 73, 128, 81, + 65, 70, 128, 81, 65, 198, 81, 65, 68, 77, 65, 128, 81, 65, 65, 73, 128, + 81, 65, 65, 70, 85, 128, 81, 65, 65, 70, 128, 81, 48, 48, 55, 128, 81, + 48, 48, 54, 128, 81, 48, 48, 53, 128, 81, 48, 48, 52, 128, 81, 48, 48, + 51, 128, 81, 48, 48, 50, 128, 81, 48, 48, 49, 128, 80, 90, 128, 80, 89, + 88, 128, 80, 89, 84, 128, 80, 89, 82, 88, 128, 80, 89, 82, 128, 80, 89, + 80, 128, 80, 87, 79, 89, 128, 80, 87, 79, 79, 128, 80, 87, 79, 128, 80, + 87, 207, 80, 87, 73, 73, 128, 80, 87, 73, 128, 80, 87, 69, 69, 128, 80, + 87, 69, 128, 80, 87, 65, 65, 128, 80, 87, 128, 80, 86, 128, 80, 85, 88, + 128, 80, 85, 85, 84, 128, 80, 85, 85, 128, 80, 85, 84, 82, 69, 70, 65, + 67, 84, 73, 79, 78, 128, 80, 85, 84, 128, 80, 85, 212, 80, 85, 83, 72, + 80, 73, 78, 128, 80, 85, 83, 72, 80, 73, 75, 65, 128, 80, 85, 83, 72, 73, + 78, 199, 80, 85, 82, 88, 128, 80, 85, 82, 83, 69, 128, 80, 85, 82, 80, + 76, 197, 80, 85, 82, 78, 65, 77, 65, 128, 80, 85, 82, 73, 84, 89, 128, + 80, 85, 82, 73, 70, 89, 128, 80, 85, 82, 128, 80, 85, 81, 128, 80, 85, + 80, 128, 80, 85, 79, 88, 128, 80, 85, 79, 80, 128, 80, 85, 79, 128, 80, + 85, 78, 71, 65, 65, 77, 128, 80, 85, 78, 71, 128, 80, 85, 78, 67, 84, 85, + 65, 84, 73, 79, 78, 128, 80, 85, 78, 67, 84, 85, 65, 84, 73, 79, 206, 80, + 85, 77, 80, 128, 80, 85, 77, 128, 80, 85, 69, 128, 80, 85, 66, 76, 73, + 195, 80, 85, 194, 80, 85, 65, 81, 128, 80, 85, 65, 69, 128, 80, 85, 50, + 128, 80, 85, 49, 128, 80, 85, 128, 80, 84, 72, 65, 72, 193, 80, 84, 69, + 128, 80, 83, 73, 76, 201, 80, 83, 73, 70, 73, 83, 84, 79, 83, 89, 78, 65, + 71, 77, 65, 128, 80, 83, 73, 70, 73, 83, 84, 79, 80, 65, 82, 65, 75, 65, + 76, 69, 83, 77, 65, 128, 80, 83, 73, 70, 73, 83, 84, 79, 206, 80, 83, 73, + 70, 73, 83, 84, 79, 76, 89, 71, 73, 83, 77, 65, 128, 80, 83, 73, 128, 80, + 83, 65, 76, 84, 69, 210, 80, 83, 128, 80, 82, 79, 86, 69, 128, 80, 82, + 79, 84, 79, 86, 65, 82, 89, 211, 80, 82, 79, 84, 79, 211, 80, 82, 79, 84, + 69, 67, 84, 69, 196, 80, 82, 79, 83, 71, 69, 71, 82, 65, 77, 77, 69, 78, + 73, 128, 80, 82, 79, 80, 79, 82, 84, 73, 79, 78, 65, 204, 80, 82, 79, 80, + 79, 82, 84, 73, 79, 78, 128, 80, 82, 79, 80, 69, 82, 84, 217, 80, 82, 79, + 80, 69, 76, 76, 69, 210, 80, 82, 79, 79, 70, 128, 80, 82, 79, 76, 79, 78, + 71, 69, 196, 80, 82, 79, 76, 65, 84, 73, 79, 78, 197, 80, 82, 79, 74, 69, + 67, 84, 79, 82, 128, 80, 82, 79, 74, 69, 67, 84, 73, 86, 69, 128, 80, 82, + 79, 74, 69, 67, 84, 73, 79, 78, 128, 80, 82, 79, 72, 73, 66, 73, 84, 69, + 196, 80, 82, 79, 71, 82, 69, 83, 83, 128, 80, 82, 79, 71, 82, 65, 205, + 80, 82, 79, 70, 79, 85, 78, 68, 128, 80, 82, 79, 68, 85, 67, 84, 128, 80, + 82, 79, 68, 85, 67, 212, 80, 82, 73, 86, 65, 84, 69, 128, 80, 82, 73, 86, + 65, 84, 197, 80, 82, 73, 86, 65, 67, 217, 80, 82, 73, 83, 72, 84, 72, 65, + 77, 65, 84, 82, 193, 80, 82, 73, 78, 84, 83, 128, 80, 82, 73, 78, 84, 69, + 82, 128, 80, 82, 73, 78, 84, 69, 210, 80, 82, 73, 78, 84, 128, 80, 82, + 73, 78, 212, 80, 82, 73, 78, 67, 69, 83, 83, 128, 80, 82, 73, 77, 69, + 128, 80, 82, 73, 77, 197, 80, 82, 69, 86, 73, 79, 85, 211, 80, 82, 69, + 83, 69, 84, 128, 80, 82, 69, 83, 69, 78, 84, 65, 84, 73, 79, 206, 80, 82, + 69, 83, 67, 82, 73, 80, 84, 73, 79, 206, 80, 82, 69, 80, 79, 78, 68, 69, + 82, 65, 78, 67, 69, 128, 80, 82, 69, 78, 75, 72, 65, 128, 80, 82, 69, 70, + 65, 67, 197, 80, 82, 69, 67, 73, 80, 73, 84, 65, 84, 69, 128, 80, 82, 69, + 67, 69, 68, 73, 78, 199, 80, 82, 69, 67, 69, 68, 69, 83, 128, 80, 82, 69, + 67, 69, 68, 69, 211, 80, 82, 69, 67, 69, 68, 69, 196, 80, 82, 69, 67, 69, + 68, 69, 128, 80, 82, 69, 67, 69, 68, 197, 80, 82, 65, 77, 45, 80, 73, 73, + 128, 80, 82, 65, 77, 45, 80, 73, 201, 80, 82, 65, 77, 45, 77, 85, 79, 89, + 128, 80, 82, 65, 77, 45, 77, 85, 79, 217, 80, 82, 65, 77, 45, 66, 85, 79, + 78, 128, 80, 82, 65, 77, 45, 66, 85, 79, 206, 80, 82, 65, 77, 45, 66, 69, + 73, 128, 80, 82, 65, 77, 45, 66, 69, 201, 80, 82, 65, 77, 128, 80, 82, + 65, 205, 80, 82, 128, 80, 80, 86, 128, 80, 80, 77, 128, 80, 80, 65, 128, + 80, 79, 89, 128, 80, 79, 88, 128, 80, 79, 87, 69, 82, 211, 80, 79, 87, + 69, 82, 128, 80, 79, 87, 68, 69, 82, 69, 196, 80, 79, 87, 68, 69, 82, + 128, 80, 79, 85, 78, 196, 80, 79, 85, 76, 84, 82, 217, 80, 79, 85, 67, + 72, 128, 80, 79, 84, 65, 84, 79, 128, 80, 79, 84, 65, 66, 76, 197, 80, + 79, 212, 80, 79, 83, 84, 80, 79, 83, 73, 84, 73, 79, 206, 80, 79, 83, 84, + 66, 79, 88, 128, 80, 79, 83, 84, 65, 204, 80, 79, 83, 84, 128, 80, 79, + 83, 212, 80, 79, 83, 83, 69, 83, 83, 73, 79, 78, 128, 80, 79, 82, 84, 65, + 66, 76, 197, 80, 79, 82, 82, 69, 67, 84, 85, 83, 128, 80, 79, 82, 82, 69, + 67, 84, 85, 211, 80, 79, 80, 80, 69, 82, 128, 80, 79, 80, 128, 80, 79, + 208, 80, 79, 79, 68, 76, 69, 128, 80, 79, 79, 128, 80, 79, 78, 68, 79, + 128, 80, 79, 206, 80, 79, 77, 77, 69, 69, 128, 80, 79, 77, 77, 69, 197, + 80, 79, 76, 73, 83, 72, 128, 80, 79, 76, 73, 67, 197, 80, 79, 76, 201, + 80, 79, 76, 69, 128, 80, 79, 76, 197, 80, 79, 75, 82, 89, 84, 73, 69, + 128, 80, 79, 75, 79, 74, 73, 128, 80, 79, 73, 78, 84, 211, 80, 79, 73, + 78, 84, 79, 128, 80, 79, 73, 78, 84, 69, 82, 128, 80, 79, 73, 78, 84, 69, + 196, 80, 79, 73, 78, 84, 128, 80, 79, 73, 78, 212, 80, 79, 69, 84, 82, + 217, 80, 79, 69, 84, 73, 195, 80, 79, 68, 65, 84, 85, 83, 128, 80, 79, + 67, 75, 69, 212, 80, 79, 65, 128, 80, 79, 128, 80, 207, 80, 78, 69, 85, + 77, 65, 84, 65, 128, 80, 76, 85, 84, 79, 128, 80, 76, 85, 84, 65, 128, + 80, 76, 85, 83, 45, 77, 73, 78, 85, 211, 80, 76, 85, 83, 128, 80, 76, 85, + 82, 65, 76, 128, 80, 76, 85, 77, 69, 196, 80, 76, 85, 77, 128, 80, 76, + 85, 75, 128, 80, 76, 85, 71, 128, 80, 76, 85, 128, 80, 76, 79, 87, 128, + 80, 76, 79, 80, 72, 85, 128, 80, 76, 72, 65, 85, 128, 80, 76, 69, 84, 72, + 82, 79, 78, 128, 80, 76, 68, 128, 80, 76, 65, 89, 73, 78, 199, 80, 76, + 65, 84, 69, 128, 80, 76, 65, 83, 84, 73, 67, 83, 128, 80, 76, 65, 78, 69, + 128, 80, 76, 65, 78, 197, 80, 76, 65, 78, 67, 203, 80, 76, 65, 75, 128, + 80, 76, 65, 71, 73, 79, 211, 80, 76, 65, 67, 69, 72, 79, 76, 68, 69, 210, + 80, 76, 65, 67, 197, 80, 76, 65, 128, 80, 73, 90, 90, 73, 67, 65, 84, 79, + 128, 80, 73, 90, 90, 65, 128, 80, 73, 88, 128, 80, 73, 87, 82, 128, 80, + 73, 84, 67, 72, 70, 79, 82, 75, 128, 80, 73, 84, 67, 72, 70, 79, 82, 203, + 80, 73, 84, 128, 80, 73, 83, 84, 79, 76, 128, 80, 73, 83, 69, 76, 69, 72, + 128, 80, 73, 83, 67, 69, 83, 128, 80, 73, 82, 73, 71, 128, 80, 73, 82, + 73, 199, 80, 73, 82, 73, 69, 69, 78, 128, 80, 73, 82, 65, 67, 89, 128, + 80, 73, 82, 50, 128, 80, 73, 80, 73, 78, 71, 128, 80, 73, 80, 65, 69, 77, + 71, 66, 73, 69, 69, 128, 80, 73, 80, 65, 69, 77, 66, 65, 128, 80, 73, 80, + 128, 80, 73, 78, 87, 72, 69, 69, 204, 80, 73, 78, 69, 65, 80, 80, 76, 69, + 128, 80, 73, 78, 197, 80, 73, 78, 65, 82, 66, 79, 82, 65, 83, 128, 80, + 73, 76, 76, 128, 80, 73, 76, 197, 80, 73, 76, 67, 82, 79, 215, 80, 73, + 75, 85, 82, 85, 128, 80, 73, 75, 79, 128, 80, 73, 71, 128, 80, 73, 199, + 80, 73, 69, 88, 128, 80, 73, 69, 85, 80, 45, 84, 72, 73, 69, 85, 84, 72, + 128, 80, 73, 69, 85, 80, 45, 83, 83, 65, 78, 71, 83, 73, 79, 83, 128, 80, + 73, 69, 85, 80, 45, 83, 73, 79, 83, 45, 84, 73, 75, 69, 85, 84, 128, 80, + 73, 69, 85, 80, 45, 83, 73, 79, 83, 45, 84, 72, 73, 69, 85, 84, 72, 128, + 80, 73, 69, 85, 80, 45, 83, 73, 79, 83, 45, 80, 73, 69, 85, 80, 128, 80, + 73, 69, 85, 80, 45, 83, 73, 79, 83, 45, 75, 73, 89, 69, 79, 75, 128, 80, + 73, 69, 85, 80, 45, 83, 73, 79, 83, 45, 67, 73, 69, 85, 67, 128, 80, 73, + 69, 85, 80, 45, 82, 73, 69, 85, 76, 45, 80, 72, 73, 69, 85, 80, 72, 128, + 80, 73, 69, 85, 80, 45, 82, 73, 69, 85, 76, 128, 80, 73, 69, 85, 80, 45, + 78, 73, 69, 85, 78, 128, 80, 73, 69, 85, 80, 45, 77, 73, 69, 85, 77, 128, + 80, 73, 69, 85, 80, 45, 75, 72, 73, 69, 85, 75, 72, 128, 80, 73, 69, 85, + 80, 45, 67, 73, 69, 85, 67, 128, 80, 73, 69, 85, 80, 45, 67, 72, 73, 69, + 85, 67, 72, 128, 80, 73, 69, 85, 208, 80, 73, 69, 84, 128, 80, 73, 69, + 80, 128, 80, 73, 69, 69, 84, 128, 80, 73, 69, 69, 81, 128, 80, 73, 69, + 67, 69, 128, 80, 73, 69, 128, 80, 73, 67, 84, 85, 82, 69, 128, 80, 73, + 67, 75, 69, 84, 128, 80, 73, 67, 75, 128, 80, 73, 65, 83, 85, 84, 79, 82, + 85, 128, 80, 73, 65, 83, 77, 193, 80, 73, 65, 78, 79, 128, 80, 201, 80, + 72, 87, 65, 128, 80, 72, 85, 84, 72, 65, 79, 128, 80, 72, 85, 210, 80, + 72, 85, 78, 71, 128, 80, 72, 82, 65, 83, 69, 128, 80, 72, 79, 78, 69, 83, + 128, 80, 72, 79, 69, 78, 73, 67, 73, 65, 206, 80, 72, 79, 65, 128, 80, + 72, 79, 128, 80, 72, 207, 80, 72, 78, 65, 69, 203, 80, 72, 73, 78, 84, + 72, 85, 128, 80, 72, 73, 76, 79, 83, 79, 80, 72, 69, 82, 211, 80, 72, 73, + 76, 73, 80, 80, 73, 78, 197, 80, 72, 73, 69, 85, 80, 72, 45, 84, 72, 73, + 69, 85, 84, 72, 128, 80, 72, 73, 69, 85, 80, 72, 45, 83, 73, 79, 83, 128, + 80, 72, 73, 69, 85, 80, 72, 45, 80, 73, 69, 85, 80, 128, 80, 72, 73, 69, + 85, 80, 72, 45, 72, 73, 69, 85, 72, 128, 80, 72, 73, 69, 85, 80, 200, 80, + 72, 73, 128, 80, 72, 201, 80, 72, 69, 69, 128, 80, 72, 69, 128, 80, 72, + 65, 83, 69, 45, 198, 80, 72, 65, 83, 69, 45, 194, 80, 72, 65, 82, 89, 78, + 71, 69, 65, 204, 80, 72, 65, 82, 128, 80, 72, 65, 78, 128, 80, 72, 65, + 77, 128, 80, 72, 65, 73, 83, 84, 79, 211, 80, 72, 65, 71, 83, 45, 80, + 193, 80, 72, 65, 66, 128, 80, 72, 65, 65, 82, 75, 65, 65, 128, 80, 72, + 65, 65, 128, 80, 72, 65, 128, 80, 71, 128, 80, 70, 128, 80, 69, 85, 88, + 128, 80, 69, 85, 84, 65, 69, 128, 80, 69, 85, 84, 128, 80, 69, 84, 65, + 83, 84, 79, 75, 79, 85, 70, 73, 83, 77, 65, 128, 80, 69, 84, 65, 83, 84, + 73, 128, 80, 69, 84, 65, 83, 77, 65, 128, 80, 69, 84, 65, 76, 76, 69, + 196, 80, 69, 83, 79, 128, 80, 69, 83, 207, 80, 69, 83, 72, 50, 128, 80, + 69, 83, 72, 178, 80, 69, 83, 69, 84, 193, 80, 69, 211, 80, 69, 82, 84, + 72, 207, 80, 69, 82, 83, 80, 69, 67, 84, 73, 86, 69, 128, 80, 69, 82, 83, + 79, 78, 65, 204, 80, 69, 82, 83, 79, 78, 128, 80, 69, 82, 83, 79, 206, + 80, 69, 82, 83, 73, 65, 206, 80, 69, 82, 83, 69, 86, 69, 82, 73, 78, 199, + 80, 69, 82, 80, 69, 78, 68, 73, 67, 85, 76, 65, 82, 128, 80, 69, 82, 80, + 69, 78, 68, 73, 67, 85, 76, 65, 210, 80, 69, 82, 78, 73, 206, 80, 69, 82, + 77, 73, 84, 84, 69, 196, 80, 69, 82, 77, 73, 195, 80, 69, 82, 77, 65, 78, + 69, 78, 212, 80, 69, 82, 73, 83, 80, 79, 77, 69, 78, 73, 128, 80, 69, 82, + 73, 83, 80, 79, 77, 69, 78, 201, 80, 69, 82, 70, 79, 82, 77, 73, 78, 199, + 80, 69, 82, 70, 69, 67, 84, 85, 205, 80, 69, 82, 70, 69, 67, 84, 65, 128, + 80, 69, 82, 70, 69, 67, 84, 193, 80, 69, 82, 67, 85, 83, 83, 73, 86, 69, + 128, 80, 69, 82, 67, 69, 78, 212, 80, 69, 80, 80, 69, 82, 128, 80, 69, + 80, 69, 84, 128, 80, 69, 80, 69, 212, 80, 69, 79, 82, 84, 200, 80, 69, + 79, 80, 76, 69, 128, 80, 69, 78, 84, 65, 83, 69, 77, 69, 128, 80, 69, 78, + 84, 65, 71, 82, 65, 77, 128, 80, 69, 78, 84, 65, 71, 79, 78, 128, 80, 69, + 78, 83, 85, 128, 80, 69, 78, 83, 73, 86, 197, 80, 69, 78, 78, 217, 80, + 69, 78, 78, 65, 78, 84, 128, 80, 69, 78, 73, 72, 73, 128, 80, 69, 78, 71, + 85, 73, 78, 128, 80, 69, 78, 71, 75, 65, 76, 128, 80, 69, 78, 69, 84, 82, + 65, 84, 73, 79, 78, 128, 80, 69, 78, 67, 73, 76, 128, 80, 69, 206, 80, + 69, 76, 65, 83, 84, 79, 78, 128, 80, 69, 76, 65, 83, 84, 79, 206, 80, 69, + 73, 84, 72, 128, 80, 69, 72, 69, 72, 128, 80, 69, 72, 69, 200, 80, 69, + 72, 128, 80, 69, 200, 80, 69, 69, 90, 73, 128, 80, 69, 69, 83, 72, 73, + 128, 80, 69, 69, 80, 128, 80, 69, 69, 77, 128, 80, 69, 69, 73, 128, 80, + 69, 69, 128, 80, 69, 68, 69, 83, 84, 82, 73, 65, 78, 83, 128, 80, 69, 68, + 69, 83, 84, 82, 73, 65, 78, 128, 80, 69, 68, 69, 83, 84, 65, 76, 128, 80, + 69, 68, 69, 83, 84, 65, 204, 80, 69, 68, 65, 204, 80, 69, 65, 67, 72, + 128, 80, 69, 65, 67, 69, 128, 80, 69, 65, 67, 197, 80, 68, 73, 128, 80, + 68, 70, 128, 80, 68, 128, 80, 67, 128, 80, 65, 90, 69, 82, 128, 80, 65, + 89, 69, 82, 79, 75, 128, 80, 65, 89, 65, 78, 78, 65, 128, 80, 65, 89, + 128, 80, 65, 88, 128, 80, 65, 87, 78, 128, 80, 65, 215, 80, 65, 86, 73, + 89, 65, 78, 73, 128, 80, 65, 85, 128, 80, 65, 213, 80, 65, 84, 84, 69, + 82, 78, 128, 80, 65, 84, 72, 65, 77, 65, 83, 65, 84, 128, 80, 65, 84, + 200, 80, 65, 84, 65, 75, 128, 80, 65, 84, 65, 72, 128, 80, 65, 84, 128, + 80, 65, 83, 85, 81, 128, 80, 65, 83, 83, 80, 79, 82, 212, 80, 65, 83, 83, + 73, 86, 69, 45, 80, 85, 76, 76, 45, 85, 80, 45, 79, 85, 84, 80, 85, 212, + 80, 65, 83, 83, 73, 86, 69, 45, 80, 85, 76, 76, 45, 68, 79, 87, 78, 45, + 79, 85, 84, 80, 85, 212, 80, 65, 83, 83, 69, 78, 71, 69, 210, 80, 65, 83, + 72, 84, 65, 128, 80, 65, 83, 72, 65, 69, 128, 80, 65, 83, 69, 81, 128, + 80, 65, 83, 65, 78, 71, 65, 206, 80, 65, 82, 85, 77, 128, 80, 65, 82, 84, + 217, 80, 65, 82, 84, 78, 69, 82, 83, 72, 73, 208, 80, 65, 82, 84, 73, 65, + 76, 76, 89, 45, 82, 69, 67, 89, 67, 76, 69, 196, 80, 65, 82, 84, 73, 65, + 204, 80, 65, 82, 84, 72, 73, 65, 206, 80, 65, 82, 212, 80, 65, 82, 75, + 128, 80, 65, 82, 73, 67, 72, 79, 78, 128, 80, 65, 82, 69, 83, 84, 73, 71, + 77, 69, 78, 79, 206, 80, 65, 82, 69, 82, 69, 78, 128, 80, 65, 82, 69, 78, + 84, 72, 69, 83, 73, 83, 128, 80, 65, 82, 69, 78, 84, 72, 69, 83, 73, 211, + 80, 65, 82, 69, 78, 84, 72, 69, 83, 69, 211, 80, 65, 82, 65, 80, 72, 82, + 65, 83, 197, 80, 65, 82, 65, 76, 76, 69, 76, 79, 71, 82, 65, 77, 128, 80, + 65, 82, 65, 76, 76, 69, 76, 128, 80, 65, 82, 65, 76, 76, 69, 204, 80, 65, + 82, 65, 75, 76, 73, 84, 73, 75, 73, 128, 80, 65, 82, 65, 75, 76, 73, 84, + 73, 75, 201, 80, 65, 82, 65, 75, 65, 76, 69, 83, 77, 193, 80, 65, 82, 65, + 71, 82, 65, 80, 72, 79, 83, 128, 80, 65, 82, 65, 71, 82, 65, 80, 72, 128, + 80, 65, 82, 65, 71, 82, 65, 80, 200, 80, 65, 82, 65, 128, 80, 65, 82, + 128, 80, 65, 80, 89, 82, 85, 83, 128, 80, 65, 80, 69, 82, 67, 76, 73, 80, + 83, 128, 80, 65, 80, 69, 82, 67, 76, 73, 80, 128, 80, 65, 80, 69, 210, + 80, 65, 80, 128, 80, 65, 208, 80, 65, 207, 80, 65, 78, 89, 85, 75, 85, + 128, 80, 65, 78, 89, 73, 75, 85, 128, 80, 65, 78, 89, 69, 67, 69, 75, + 128, 80, 65, 78, 89, 65, 78, 71, 71, 65, 128, 80, 65, 78, 89, 65, 75, 82, + 65, 128, 80, 65, 78, 84, 73, 128, 80, 65, 78, 83, 73, 79, 83, 45, 80, 73, + 69, 85, 80, 128, 80, 65, 78, 83, 73, 79, 83, 45, 75, 65, 80, 89, 69, 79, + 85, 78, 80, 73, 69, 85, 80, 128, 80, 65, 78, 79, 78, 71, 79, 78, 65, 78, + 128, 80, 65, 78, 79, 76, 79, 78, 71, 128, 80, 65, 78, 71, 87, 73, 83, 65, + 68, 128, 80, 65, 78, 71, 82, 65, 78, 71, 75, 69, 80, 128, 80, 65, 78, 71, + 79, 76, 65, 84, 128, 80, 65, 78, 71, 76, 79, 78, 71, 128, 80, 65, 78, 71, + 76, 65, 89, 65, 82, 128, 80, 65, 78, 71, 75, 79, 78, 128, 80, 65, 78, 71, + 75, 65, 84, 128, 80, 65, 78, 71, 72, 85, 76, 85, 128, 80, 65, 78, 71, + 128, 80, 65, 78, 69, 85, 76, 69, 85, 78, 71, 128, 80, 65, 78, 68, 193, + 80, 65, 78, 65, 69, 76, 65, 69, 78, 71, 128, 80, 65, 78, 128, 80, 65, 77, + 85, 78, 71, 75, 65, 72, 128, 80, 65, 77, 85, 68, 80, 79, 68, 128, 80, 65, + 77, 83, 72, 65, 69, 128, 80, 65, 77, 80, 72, 89, 76, 73, 65, 206, 80, 65, + 77, 73, 78, 71, 75, 65, 76, 128, 80, 65, 77, 69, 80, 69, 84, 128, 80, 65, + 77, 69, 78, 69, 78, 71, 128, 80, 65, 77, 65, 68, 65, 128, 80, 65, 77, 65, + 65, 69, 72, 128, 80, 65, 76, 85, 84, 65, 128, 80, 65, 76, 79, 67, 72, 75, + 65, 128, 80, 65, 76, 77, 89, 82, 69, 78, 197, 80, 65, 76, 205, 80, 65, + 76, 76, 65, 87, 65, 128, 80, 65, 76, 76, 65, 83, 128, 80, 65, 76, 69, 84, + 84, 69, 128, 80, 65, 76, 65, 85, 78, 199, 80, 65, 76, 65, 84, 65, 76, 73, + 90, 69, 196, 80, 65, 76, 65, 84, 65, 76, 73, 90, 65, 84, 73, 79, 78, 128, + 80, 65, 76, 65, 84, 65, 204, 80, 65, 75, 80, 65, 203, 80, 65, 73, 89, 65, + 78, 78, 79, 73, 128, 80, 65, 73, 82, 84, 72, 82, 65, 128, 80, 65, 73, 82, + 69, 196, 80, 65, 73, 78, 84, 66, 82, 85, 83, 72, 128, 80, 65, 73, 128, + 80, 65, 72, 76, 65, 86, 201, 80, 65, 72, 128, 80, 65, 71, 69, 83, 128, + 80, 65, 71, 69, 82, 128, 80, 65, 71, 197, 80, 65, 68, 77, 193, 80, 65, + 68, 68, 73, 78, 199, 80, 65, 68, 193, 80, 65, 68, 128, 80, 65, 67, 75, + 73, 78, 71, 128, 80, 65, 67, 75, 65, 71, 69, 128, 80, 65, 65, 84, 85, + 128, 80, 65, 65, 83, 69, 78, 84, 79, 128, 80, 65, 65, 82, 65, 69, 128, + 80, 65, 65, 77, 128, 80, 65, 65, 73, 128, 80, 65, 65, 45, 80, 73, 76, 76, + 65, 128, 80, 65, 65, 128, 80, 50, 128, 80, 48, 49, 49, 128, 80, 48, 49, + 48, 128, 80, 48, 48, 57, 128, 80, 48, 48, 56, 128, 80, 48, 48, 55, 128, + 80, 48, 48, 54, 128, 80, 48, 48, 53, 128, 80, 48, 48, 52, 128, 80, 48, + 48, 51, 65, 128, 80, 48, 48, 51, 128, 80, 48, 48, 50, 128, 80, 48, 48, + 49, 65, 128, 80, 48, 48, 49, 128, 79, 89, 82, 65, 78, 73, 83, 77, 193, + 79, 89, 65, 78, 78, 65, 128, 79, 88, 73, 65, 128, 79, 88, 73, 193, 79, + 88, 69, 73, 65, 201, 79, 88, 69, 73, 193, 79, 86, 69, 82, 82, 73, 68, 69, + 128, 79, 86, 69, 82, 76, 79, 78, 199, 79, 86, 69, 82, 76, 73, 78, 69, 128, 79, 86, 69, 82, 76, 65, 89, 128, 79, 86, 69, 82, 76, 65, 80, 80, 73, - 78, 199, 79, 86, 69, 82, 76, 65, 73, 68, 128, 79, 86, 69, 82, 66, 65, 82, - 128, 79, 86, 65, 204, 79, 86, 128, 79, 85, 84, 76, 73, 78, 69, 196, 79, - 85, 84, 76, 73, 78, 69, 128, 79, 85, 84, 69, 210, 79, 85, 84, 66, 79, - 216, 79, 85, 78, 75, 73, 193, 79, 85, 78, 67, 69, 128, 79, 85, 78, 67, - 197, 79, 84, 85, 128, 79, 84, 84, 65, 86, 193, 79, 84, 84, 128, 79, 84, - 72, 65, 76, 65, 206, 79, 84, 72, 65, 76, 128, 79, 83, 77, 65, 78, 89, - 193, 79, 83, 67, 128, 79, 82, 84, 72, 79, 71, 79, 78, 65, 204, 79, 82, - 84, 72, 79, 68, 79, 216, 79, 82, 78, 65, 84, 197, 79, 82, 78, 65, 77, 69, - 78, 84, 128, 79, 82, 78, 65, 77, 69, 78, 212, 79, 82, 75, 72, 79, 206, - 79, 82, 73, 71, 73, 78, 65, 204, 79, 82, 73, 71, 73, 78, 128, 79, 82, 69, - 45, 50, 128, 79, 82, 68, 73, 78, 65, 204, 79, 82, 68, 69, 210, 79, 82, - 67, 72, 73, 68, 128, 79, 82, 65, 78, 71, 197, 79, 80, 84, 73, 79, 206, - 79, 80, 84, 73, 67, 65, 204, 79, 80, 80, 82, 69, 83, 83, 73, 79, 78, 128, - 79, 80, 80, 79, 83, 73, 84, 73, 79, 78, 128, 79, 80, 80, 79, 83, 73, 78, - 199, 79, 80, 80, 79, 83, 69, 128, 79, 80, 72, 73, 85, 67, 72, 85, 83, - 128, 79, 80, 69, 82, 65, 84, 79, 82, 128, 79, 80, 69, 82, 65, 84, 79, - 210, 79, 80, 69, 82, 65, 84, 73, 78, 199, 79, 80, 69, 78, 73, 78, 199, - 79, 80, 69, 78, 45, 80, 128, 79, 80, 69, 78, 45, 79, 85, 84, 76, 73, 78, - 69, 196, 79, 80, 69, 78, 45, 72, 69, 65, 68, 69, 196, 79, 80, 69, 78, 45, - 67, 73, 82, 67, 85, 73, 84, 45, 79, 85, 84, 80, 85, 212, 79, 79, 90, 69, - 128, 79, 79, 89, 65, 78, 78, 65, 128, 79, 79, 85, 128, 79, 79, 77, 85, - 128, 79, 79, 69, 128, 79, 79, 66, 79, 79, 70, 73, 76, 73, 128, 79, 78, - 85, 128, 79, 78, 83, 85, 128, 79, 78, 78, 128, 79, 78, 75, 65, 82, 128, - 79, 78, 69, 83, 69, 76, 70, 128, 79, 78, 69, 45, 87, 65, 217, 79, 78, 69, - 45, 84, 72, 73, 82, 84, 89, 128, 79, 78, 69, 45, 76, 73, 78, 197, 79, 78, - 67, 79, 77, 73, 78, 199, 79, 78, 65, 80, 128, 79, 77, 73, 83, 83, 73, 79, - 206, 79, 77, 73, 67, 82, 79, 78, 128, 79, 77, 73, 67, 82, 79, 206, 79, - 77, 69, 71, 65, 128, 79, 77, 69, 71, 193, 79, 77, 65, 76, 79, 78, 128, - 79, 76, 73, 86, 69, 128, 79, 76, 73, 71, 79, 206, 79, 76, 68, 128, 79, - 75, 84, 207, 79, 75, 65, 82, 65, 128, 79, 75, 65, 82, 193, 79, 74, 73, - 66, 87, 65, 217, 79, 74, 69, 79, 78, 128, 79, 73, 76, 128, 79, 72, 77, - 128, 79, 72, 205, 79, 71, 82, 69, 128, 79, 71, 79, 78, 69, 75, 128, 79, - 71, 79, 78, 69, 203, 79, 71, 72, 65, 205, 79, 70, 70, 73, 67, 69, 82, - 128, 79, 70, 70, 73, 67, 69, 128, 79, 70, 70, 73, 67, 197, 79, 70, 70, - 128, 79, 69, 89, 128, 79, 69, 75, 128, 79, 68, 69, 78, 128, 79, 68, 196, - 79, 67, 84, 79, 80, 85, 83, 128, 79, 67, 84, 79, 66, 69, 82, 128, 79, 67, - 84, 69, 212, 79, 67, 210, 79, 67, 76, 79, 67, 75, 128, 79, 67, 67, 76, - 85, 83, 73, 79, 78, 128, 79, 66, 83, 84, 82, 85, 67, 84, 73, 79, 78, 128, - 79, 66, 79, 76, 211, 79, 66, 79, 204, 79, 66, 79, 70, 73, 76, 73, 128, - 79, 66, 76, 73, 81, 85, 197, 79, 66, 74, 69, 67, 212, 79, 66, 69, 76, 85, - 83, 128, 79, 66, 69, 76, 79, 83, 128, 79, 66, 128, 79, 65, 89, 128, 79, - 65, 75, 128, 79, 65, 66, 79, 65, 70, 73, 76, 73, 128, 79, 193, 79, 48, - 53, 49, 128, 79, 48, 53, 48, 66, 128, 79, 48, 53, 48, 65, 128, 79, 48, - 53, 48, 128, 79, 48, 52, 57, 128, 79, 48, 52, 56, 128, 79, 48, 52, 55, - 128, 79, 48, 52, 54, 128, 79, 48, 52, 53, 128, 79, 48, 52, 52, 128, 79, - 48, 52, 51, 128, 79, 48, 52, 50, 128, 79, 48, 52, 49, 128, 79, 48, 52, - 48, 128, 79, 48, 51, 57, 128, 79, 48, 51, 56, 128, 79, 48, 51, 55, 128, - 79, 48, 51, 54, 68, 128, 79, 48, 51, 54, 67, 128, 79, 48, 51, 54, 66, - 128, 79, 48, 51, 54, 65, 128, 79, 48, 51, 54, 128, 79, 48, 51, 53, 128, - 79, 48, 51, 52, 128, 79, 48, 51, 51, 65, 128, 79, 48, 51, 51, 128, 79, - 48, 51, 50, 128, 79, 48, 51, 49, 128, 79, 48, 51, 48, 65, 128, 79, 48, - 51, 48, 128, 79, 48, 50, 57, 65, 128, 79, 48, 50, 57, 128, 79, 48, 50, - 56, 128, 79, 48, 50, 55, 128, 79, 48, 50, 54, 128, 79, 48, 50, 53, 65, - 128, 79, 48, 50, 53, 128, 79, 48, 50, 52, 65, 128, 79, 48, 50, 52, 128, - 79, 48, 50, 51, 128, 79, 48, 50, 50, 128, 79, 48, 50, 49, 128, 79, 48, - 50, 48, 65, 128, 79, 48, 50, 48, 128, 79, 48, 49, 57, 65, 128, 79, 48, - 49, 57, 128, 79, 48, 49, 56, 128, 79, 48, 49, 55, 128, 79, 48, 49, 54, - 128, 79, 48, 49, 53, 128, 79, 48, 49, 52, 128, 79, 48, 49, 51, 128, 79, - 48, 49, 50, 128, 79, 48, 49, 49, 128, 79, 48, 49, 48, 67, 128, 79, 48, - 49, 48, 66, 128, 79, 48, 49, 48, 65, 128, 79, 48, 49, 48, 128, 79, 48, - 48, 57, 128, 79, 48, 48, 56, 128, 79, 48, 48, 55, 128, 79, 48, 48, 54, - 70, 128, 79, 48, 48, 54, 69, 128, 79, 48, 48, 54, 68, 128, 79, 48, 48, - 54, 67, 128, 79, 48, 48, 54, 66, 128, 79, 48, 48, 54, 65, 128, 79, 48, - 48, 54, 128, 79, 48, 48, 53, 65, 128, 79, 48, 48, 53, 128, 79, 48, 48, - 52, 128, 79, 48, 48, 51, 128, 79, 48, 48, 50, 128, 79, 48, 48, 49, 65, - 128, 79, 48, 48, 49, 128, 79, 45, 89, 69, 128, 79, 45, 79, 45, 73, 128, - 79, 45, 69, 128, 78, 90, 89, 88, 128, 78, 90, 89, 84, 128, 78, 90, 89, - 82, 88, 128, 78, 90, 89, 82, 128, 78, 90, 89, 80, 128, 78, 90, 89, 128, - 78, 90, 85, 88, 128, 78, 90, 85, 82, 88, 128, 78, 90, 85, 82, 128, 78, - 90, 85, 81, 128, 78, 90, 85, 80, 128, 78, 90, 85, 79, 88, 128, 78, 90, - 85, 79, 128, 78, 90, 85, 206, 78, 90, 85, 128, 78, 90, 79, 88, 128, 78, - 90, 79, 80, 128, 78, 90, 73, 88, 128, 78, 90, 73, 84, 128, 78, 90, 73, - 80, 128, 78, 90, 73, 69, 88, 128, 78, 90, 73, 69, 80, 128, 78, 90, 73, - 69, 128, 78, 90, 73, 128, 78, 90, 69, 88, 128, 78, 90, 69, 85, 77, 128, - 78, 90, 69, 128, 78, 90, 65, 88, 128, 78, 90, 65, 84, 128, 78, 90, 65, - 81, 128, 78, 90, 65, 80, 128, 78, 90, 65, 128, 78, 90, 193, 78, 89, 87, - 65, 128, 78, 89, 85, 88, 128, 78, 89, 85, 85, 128, 78, 89, 85, 84, 128, - 78, 89, 85, 80, 128, 78, 89, 85, 79, 88, 128, 78, 89, 85, 79, 80, 128, - 78, 89, 85, 79, 128, 78, 89, 85, 69, 128, 78, 89, 85, 128, 78, 89, 79, - 88, 128, 78, 89, 79, 84, 128, 78, 89, 79, 80, 128, 78, 89, 79, 79, 128, - 78, 89, 79, 65, 128, 78, 89, 79, 128, 78, 89, 74, 65, 128, 78, 89, 73, - 88, 128, 78, 89, 73, 84, 128, 78, 89, 73, 212, 78, 89, 73, 211, 78, 89, - 73, 210, 78, 89, 73, 80, 128, 78, 89, 73, 78, 45, 68, 79, 128, 78, 89, - 73, 73, 128, 78, 89, 73, 69, 88, 128, 78, 89, 73, 69, 84, 128, 78, 89, - 73, 69, 80, 128, 78, 89, 73, 69, 128, 78, 89, 73, 128, 78, 89, 201, 78, - 89, 72, 65, 128, 78, 89, 69, 84, 128, 78, 89, 69, 212, 78, 89, 69, 72, - 128, 78, 89, 69, 200, 78, 89, 69, 69, 128, 78, 89, 69, 128, 78, 89, 196, - 78, 89, 67, 65, 128, 78, 89, 65, 85, 128, 78, 89, 65, 73, 128, 78, 89, - 65, 72, 128, 78, 89, 65, 69, 77, 65, 69, 128, 78, 89, 65, 65, 128, 78, - 87, 79, 79, 128, 78, 87, 79, 128, 78, 87, 73, 73, 128, 78, 87, 73, 128, - 78, 87, 69, 128, 78, 87, 65, 65, 128, 78, 87, 65, 128, 78, 87, 128, 78, - 86, 128, 78, 85, 88, 128, 78, 85, 85, 78, 128, 78, 85, 85, 128, 78, 85, - 84, 73, 76, 76, 85, 128, 78, 85, 84, 128, 78, 85, 212, 78, 85, 82, 88, - 128, 78, 85, 82, 128, 78, 85, 80, 128, 78, 85, 79, 88, 128, 78, 85, 79, - 80, 128, 78, 85, 79, 128, 78, 85, 78, 85, 90, 128, 78, 85, 78, 85, 218, - 78, 85, 78, 71, 128, 78, 85, 78, 65, 86, 85, 212, 78, 85, 78, 65, 86, 73, - 203, 78, 85, 78, 128, 78, 85, 206, 78, 85, 77, 69, 82, 207, 78, 85, 77, - 69, 82, 65, 84, 79, 210, 78, 85, 77, 69, 82, 65, 204, 78, 85, 77, 66, 69, - 82, 83, 128, 78, 85, 77, 66, 69, 82, 128, 78, 85, 77, 128, 78, 85, 76, - 76, 128, 78, 85, 76, 204, 78, 85, 76, 128, 78, 85, 75, 84, 65, 128, 78, - 85, 69, 78, 71, 128, 78, 85, 69, 128, 78, 85, 66, 73, 65, 206, 78, 85, - 65, 69, 128, 78, 85, 49, 49, 128, 78, 85, 49, 177, 78, 85, 48, 50, 50, - 65, 128, 78, 85, 48, 50, 50, 128, 78, 85, 48, 50, 49, 128, 78, 85, 48, - 50, 48, 128, 78, 85, 48, 49, 57, 128, 78, 85, 48, 49, 56, 65, 128, 78, - 85, 48, 49, 56, 128, 78, 85, 48, 49, 55, 128, 78, 85, 48, 49, 54, 128, - 78, 85, 48, 49, 53, 128, 78, 85, 48, 49, 52, 128, 78, 85, 48, 49, 51, - 128, 78, 85, 48, 49, 50, 128, 78, 85, 48, 49, 49, 65, 128, 78, 85, 48, - 49, 49, 128, 78, 85, 48, 49, 48, 65, 128, 78, 85, 48, 49, 48, 128, 78, - 85, 48, 48, 57, 128, 78, 85, 48, 48, 56, 128, 78, 85, 48, 48, 55, 128, - 78, 85, 48, 48, 54, 128, 78, 85, 48, 48, 53, 128, 78, 85, 48, 48, 52, - 128, 78, 85, 48, 48, 51, 128, 78, 85, 48, 48, 50, 128, 78, 85, 48, 48, - 49, 128, 78, 84, 85, 85, 128, 78, 84, 85, 77, 128, 78, 84, 213, 78, 84, - 79, 81, 80, 69, 78, 128, 78, 84, 73, 69, 197, 78, 84, 69, 85, 78, 71, 66, - 65, 128, 78, 84, 69, 85, 77, 128, 78, 84, 69, 78, 128, 78, 84, 69, 69, - 128, 78, 84, 65, 80, 128, 78, 84, 65, 208, 78, 84, 65, 65, 128, 78, 83, - 85, 79, 212, 78, 83, 85, 78, 128, 78, 83, 85, 77, 128, 78, 83, 79, 77, - 128, 78, 83, 73, 69, 69, 84, 128, 78, 83, 73, 69, 69, 80, 128, 78, 83, - 73, 69, 69, 128, 78, 83, 72, 85, 84, 128, 78, 83, 72, 85, 212, 78, 83, - 72, 85, 79, 80, 128, 78, 83, 72, 85, 69, 128, 78, 83, 72, 73, 69, 69, - 128, 78, 83, 72, 69, 69, 128, 78, 83, 72, 65, 81, 128, 78, 83, 72, 65, - 128, 78, 83, 69, 85, 65, 69, 78, 128, 78, 83, 69, 78, 128, 78, 83, 65, - 128, 78, 82, 89, 88, 128, 78, 82, 89, 84, 128, 78, 82, 89, 82, 88, 128, - 78, 82, 89, 82, 128, 78, 82, 89, 80, 128, 78, 82, 89, 128, 78, 82, 85, - 88, 128, 78, 82, 85, 84, 128, 78, 82, 85, 82, 88, 128, 78, 82, 85, 82, - 128, 78, 82, 85, 80, 128, 78, 82, 85, 128, 78, 82, 79, 88, 128, 78, 82, - 79, 80, 128, 78, 82, 79, 128, 78, 82, 69, 88, 128, 78, 82, 69, 84, 128, - 78, 82, 69, 80, 128, 78, 82, 69, 128, 78, 82, 65, 88, 128, 78, 82, 65, - 84, 128, 78, 82, 65, 80, 128, 78, 82, 65, 128, 78, 79, 89, 128, 78, 79, - 88, 128, 78, 79, 86, 69, 77, 66, 69, 82, 128, 78, 79, 84, 84, 79, 128, - 78, 79, 84, 69, 83, 128, 78, 79, 84, 69, 72, 69, 65, 68, 128, 78, 79, 84, - 69, 72, 69, 65, 196, 78, 79, 84, 69, 66, 79, 79, 75, 128, 78, 79, 84, 69, - 66, 79, 79, 203, 78, 79, 84, 69, 128, 78, 79, 84, 197, 78, 79, 84, 67, - 72, 69, 196, 78, 79, 84, 67, 72, 128, 78, 79, 84, 128, 78, 79, 212, 78, - 79, 83, 69, 128, 78, 79, 82, 84, 72, 87, 69, 83, 212, 78, 79, 82, 84, 72, - 69, 82, 206, 78, 79, 82, 84, 200, 78, 79, 82, 77, 65, 204, 78, 79, 210, + 78, 199, 79, 86, 69, 82, 76, 65, 80, 128, 79, 86, 69, 82, 76, 65, 73, 68, + 128, 79, 86, 69, 82, 66, 65, 82, 128, 79, 86, 65, 204, 79, 85, 84, 76, + 73, 78, 69, 196, 79, 85, 84, 76, 73, 78, 69, 128, 79, 85, 84, 69, 210, + 79, 85, 84, 66, 79, 216, 79, 85, 78, 75, 73, 193, 79, 85, 78, 67, 69, + 128, 79, 85, 78, 67, 197, 79, 84, 85, 128, 79, 84, 84, 65, 86, 193, 79, + 84, 84, 128, 79, 84, 72, 65, 76, 65, 206, 79, 84, 72, 65, 76, 128, 79, + 83, 77, 65, 78, 89, 193, 79, 83, 67, 128, 79, 82, 84, 72, 79, 71, 79, 78, + 65, 204, 79, 82, 84, 72, 79, 68, 79, 216, 79, 82, 78, 65, 84, 197, 79, + 82, 78, 65, 77, 69, 78, 84, 128, 79, 82, 78, 65, 77, 69, 78, 212, 79, 82, + 75, 72, 79, 206, 79, 82, 73, 71, 73, 78, 65, 204, 79, 82, 73, 71, 73, 78, + 128, 79, 82, 69, 45, 50, 128, 79, 82, 68, 73, 78, 65, 204, 79, 82, 68, + 69, 210, 79, 82, 67, 72, 73, 68, 128, 79, 82, 65, 78, 71, 197, 79, 80, + 84, 73, 79, 206, 79, 80, 84, 73, 67, 65, 204, 79, 80, 80, 82, 69, 83, 83, + 73, 79, 78, 128, 79, 80, 80, 79, 83, 73, 84, 73, 79, 78, 128, 79, 80, 80, + 79, 83, 73, 78, 199, 79, 80, 80, 79, 83, 69, 128, 79, 80, 72, 73, 85, 67, + 72, 85, 83, 128, 79, 80, 69, 82, 65, 84, 79, 82, 128, 79, 80, 69, 82, 65, + 84, 79, 210, 79, 80, 69, 82, 65, 84, 73, 78, 199, 79, 80, 69, 78, 73, 78, + 199, 79, 80, 69, 78, 45, 80, 128, 79, 80, 69, 78, 45, 79, 85, 84, 76, 73, + 78, 69, 196, 79, 80, 69, 78, 45, 79, 128, 79, 80, 69, 78, 45, 207, 79, + 80, 69, 78, 45, 72, 69, 65, 68, 69, 196, 79, 80, 69, 78, 45, 67, 73, 82, + 67, 85, 73, 84, 45, 79, 85, 84, 80, 85, 212, 79, 80, 69, 206, 79, 79, 90, + 69, 128, 79, 79, 89, 65, 78, 78, 65, 128, 79, 79, 85, 128, 79, 79, 77, + 85, 128, 79, 79, 72, 128, 79, 79, 69, 128, 79, 79, 66, 79, 79, 70, 73, + 76, 73, 128, 79, 78, 85, 128, 79, 78, 83, 85, 128, 79, 78, 78, 128, 79, + 78, 75, 65, 82, 128, 79, 78, 69, 83, 69, 76, 70, 128, 79, 78, 69, 45, 87, + 65, 217, 79, 78, 69, 45, 84, 72, 73, 82, 84, 89, 128, 79, 78, 69, 45, 76, + 73, 78, 197, 79, 78, 67, 79, 77, 73, 78, 199, 79, 78, 65, 80, 128, 79, + 77, 73, 83, 83, 73, 79, 206, 79, 77, 73, 67, 82, 79, 78, 128, 79, 77, 73, + 67, 82, 79, 206, 79, 77, 69, 71, 65, 128, 79, 77, 69, 71, 193, 79, 77, + 65, 76, 79, 78, 128, 79, 76, 73, 86, 69, 128, 79, 76, 73, 71, 79, 206, + 79, 76, 68, 128, 79, 75, 84, 207, 79, 75, 65, 82, 65, 128, 79, 75, 65, + 82, 193, 79, 74, 73, 66, 87, 65, 217, 79, 74, 69, 79, 78, 128, 79, 73, + 76, 128, 79, 73, 204, 79, 72, 77, 128, 79, 72, 205, 79, 71, 82, 69, 128, + 79, 71, 79, 78, 69, 75, 128, 79, 71, 79, 78, 69, 203, 79, 71, 72, 65, + 205, 79, 70, 70, 73, 67, 69, 82, 128, 79, 70, 70, 73, 67, 69, 128, 79, + 70, 70, 73, 67, 197, 79, 70, 70, 128, 79, 69, 89, 128, 79, 69, 75, 128, + 79, 68, 69, 78, 128, 79, 68, 68, 128, 79, 68, 196, 79, 67, 84, 79, 80, + 85, 83, 128, 79, 67, 84, 79, 66, 69, 82, 128, 79, 67, 84, 69, 212, 79, + 67, 84, 65, 71, 79, 78, 128, 79, 67, 210, 79, 67, 76, 79, 67, 75, 128, + 79, 67, 67, 76, 85, 83, 73, 79, 78, 128, 79, 66, 83, 84, 82, 85, 67, 84, + 73, 79, 78, 128, 79, 66, 79, 76, 211, 79, 66, 79, 204, 79, 66, 79, 70, + 73, 76, 73, 128, 79, 66, 76, 73, 81, 85, 197, 79, 66, 74, 69, 67, 212, + 79, 66, 69, 76, 85, 83, 128, 79, 66, 69, 76, 79, 83, 128, 79, 66, 128, + 79, 65, 89, 128, 79, 65, 75, 128, 79, 65, 66, 79, 65, 70, 73, 76, 73, + 128, 79, 193, 79, 48, 53, 49, 128, 79, 48, 53, 48, 66, 128, 79, 48, 53, + 48, 65, 128, 79, 48, 53, 48, 128, 79, 48, 52, 57, 128, 79, 48, 52, 56, + 128, 79, 48, 52, 55, 128, 79, 48, 52, 54, 128, 79, 48, 52, 53, 128, 79, + 48, 52, 52, 128, 79, 48, 52, 51, 128, 79, 48, 52, 50, 128, 79, 48, 52, + 49, 128, 79, 48, 52, 48, 128, 79, 48, 51, 57, 128, 79, 48, 51, 56, 128, + 79, 48, 51, 55, 128, 79, 48, 51, 54, 68, 128, 79, 48, 51, 54, 67, 128, + 79, 48, 51, 54, 66, 128, 79, 48, 51, 54, 65, 128, 79, 48, 51, 54, 128, + 79, 48, 51, 53, 128, 79, 48, 51, 52, 128, 79, 48, 51, 51, 65, 128, 79, + 48, 51, 51, 128, 79, 48, 51, 50, 128, 79, 48, 51, 49, 128, 79, 48, 51, + 48, 65, 128, 79, 48, 51, 48, 128, 79, 48, 50, 57, 65, 128, 79, 48, 50, + 57, 128, 79, 48, 50, 56, 128, 79, 48, 50, 55, 128, 79, 48, 50, 54, 128, + 79, 48, 50, 53, 65, 128, 79, 48, 50, 53, 128, 79, 48, 50, 52, 65, 128, + 79, 48, 50, 52, 128, 79, 48, 50, 51, 128, 79, 48, 50, 50, 128, 79, 48, + 50, 49, 128, 79, 48, 50, 48, 65, 128, 79, 48, 50, 48, 128, 79, 48, 49, + 57, 65, 128, 79, 48, 49, 57, 128, 79, 48, 49, 56, 128, 79, 48, 49, 55, + 128, 79, 48, 49, 54, 128, 79, 48, 49, 53, 128, 79, 48, 49, 52, 128, 79, + 48, 49, 51, 128, 79, 48, 49, 50, 128, 79, 48, 49, 49, 128, 79, 48, 49, + 48, 67, 128, 79, 48, 49, 48, 66, 128, 79, 48, 49, 48, 65, 128, 79, 48, + 49, 48, 128, 79, 48, 48, 57, 128, 79, 48, 48, 56, 128, 79, 48, 48, 55, + 128, 79, 48, 48, 54, 70, 128, 79, 48, 48, 54, 69, 128, 79, 48, 48, 54, + 68, 128, 79, 48, 48, 54, 67, 128, 79, 48, 48, 54, 66, 128, 79, 48, 48, + 54, 65, 128, 79, 48, 48, 54, 128, 79, 48, 48, 53, 65, 128, 79, 48, 48, + 53, 128, 79, 48, 48, 52, 128, 79, 48, 48, 51, 128, 79, 48, 48, 50, 128, + 79, 48, 48, 49, 65, 128, 79, 48, 48, 49, 128, 79, 45, 89, 69, 128, 79, + 45, 79, 45, 73, 128, 79, 45, 69, 128, 78, 90, 89, 88, 128, 78, 90, 89, + 84, 128, 78, 90, 89, 82, 88, 128, 78, 90, 89, 82, 128, 78, 90, 89, 80, + 128, 78, 90, 89, 128, 78, 90, 85, 88, 128, 78, 90, 85, 82, 88, 128, 78, + 90, 85, 82, 128, 78, 90, 85, 81, 128, 78, 90, 85, 80, 128, 78, 90, 85, + 79, 88, 128, 78, 90, 85, 79, 128, 78, 90, 85, 206, 78, 90, 85, 128, 78, + 90, 79, 88, 128, 78, 90, 79, 80, 128, 78, 90, 73, 88, 128, 78, 90, 73, + 84, 128, 78, 90, 73, 80, 128, 78, 90, 73, 69, 88, 128, 78, 90, 73, 69, + 80, 128, 78, 90, 73, 69, 128, 78, 90, 73, 128, 78, 90, 69, 88, 128, 78, + 90, 69, 85, 77, 128, 78, 90, 69, 128, 78, 90, 65, 88, 128, 78, 90, 65, + 84, 128, 78, 90, 65, 81, 128, 78, 90, 65, 80, 128, 78, 90, 65, 128, 78, + 90, 193, 78, 89, 87, 65, 128, 78, 89, 85, 88, 128, 78, 89, 85, 85, 128, + 78, 89, 85, 84, 128, 78, 89, 85, 80, 128, 78, 89, 85, 79, 88, 128, 78, + 89, 85, 79, 80, 128, 78, 89, 85, 79, 128, 78, 89, 85, 78, 128, 78, 89, + 85, 69, 128, 78, 89, 85, 128, 78, 89, 79, 88, 128, 78, 89, 79, 84, 128, + 78, 89, 79, 80, 128, 78, 89, 79, 79, 128, 78, 89, 79, 78, 128, 78, 89, + 79, 65, 128, 78, 89, 79, 128, 78, 89, 74, 65, 128, 78, 89, 73, 88, 128, + 78, 89, 73, 84, 128, 78, 89, 73, 212, 78, 89, 73, 211, 78, 89, 73, 210, + 78, 89, 73, 80, 128, 78, 89, 73, 78, 45, 68, 79, 128, 78, 89, 73, 78, + 128, 78, 89, 73, 73, 128, 78, 89, 73, 69, 88, 128, 78, 89, 73, 69, 84, + 128, 78, 89, 73, 69, 80, 128, 78, 89, 73, 69, 128, 78, 89, 73, 128, 78, + 89, 201, 78, 89, 72, 65, 128, 78, 89, 69, 84, 128, 78, 89, 69, 212, 78, + 89, 69, 78, 128, 78, 89, 69, 72, 128, 78, 89, 69, 200, 78, 89, 69, 69, + 128, 78, 89, 69, 128, 78, 89, 196, 78, 89, 67, 65, 128, 78, 89, 65, 85, + 128, 78, 89, 65, 73, 128, 78, 89, 65, 72, 128, 78, 89, 65, 69, 77, 65, + 69, 128, 78, 89, 65, 65, 128, 78, 87, 79, 79, 128, 78, 87, 79, 128, 78, + 87, 73, 73, 128, 78, 87, 73, 128, 78, 87, 69, 128, 78, 87, 65, 65, 128, + 78, 87, 65, 128, 78, 87, 128, 78, 86, 128, 78, 85, 88, 128, 78, 85, 85, + 78, 128, 78, 85, 85, 128, 78, 85, 84, 73, 76, 76, 85, 128, 78, 85, 84, + 128, 78, 85, 212, 78, 85, 82, 88, 128, 78, 85, 82, 128, 78, 85, 80, 128, + 78, 85, 79, 88, 128, 78, 85, 79, 80, 128, 78, 85, 79, 128, 78, 85, 78, + 85, 90, 128, 78, 85, 78, 85, 218, 78, 85, 78, 71, 128, 78, 85, 78, 65, + 86, 85, 212, 78, 85, 78, 65, 86, 73, 203, 78, 85, 78, 128, 78, 85, 206, + 78, 85, 77, 69, 82, 207, 78, 85, 77, 69, 82, 65, 84, 79, 210, 78, 85, 77, + 69, 82, 65, 204, 78, 85, 77, 66, 69, 82, 83, 128, 78, 85, 77, 66, 69, 82, + 128, 78, 85, 77, 128, 78, 85, 76, 76, 128, 78, 85, 76, 204, 78, 85, 76, + 128, 78, 85, 75, 84, 65, 128, 78, 85, 69, 78, 71, 128, 78, 85, 69, 128, + 78, 85, 66, 73, 65, 206, 78, 85, 65, 69, 128, 78, 85, 49, 49, 128, 78, + 85, 49, 177, 78, 85, 48, 50, 50, 65, 128, 78, 85, 48, 50, 50, 128, 78, + 85, 48, 50, 49, 128, 78, 85, 48, 50, 48, 128, 78, 85, 48, 49, 57, 128, + 78, 85, 48, 49, 56, 65, 128, 78, 85, 48, 49, 56, 128, 78, 85, 48, 49, 55, + 128, 78, 85, 48, 49, 54, 128, 78, 85, 48, 49, 53, 128, 78, 85, 48, 49, + 52, 128, 78, 85, 48, 49, 51, 128, 78, 85, 48, 49, 50, 128, 78, 85, 48, + 49, 49, 65, 128, 78, 85, 48, 49, 49, 128, 78, 85, 48, 49, 48, 65, 128, + 78, 85, 48, 49, 48, 128, 78, 85, 48, 48, 57, 128, 78, 85, 48, 48, 56, + 128, 78, 85, 48, 48, 55, 128, 78, 85, 48, 48, 54, 128, 78, 85, 48, 48, + 53, 128, 78, 85, 48, 48, 52, 128, 78, 85, 48, 48, 51, 128, 78, 85, 48, + 48, 50, 128, 78, 85, 48, 48, 49, 128, 78, 84, 88, 73, 86, 128, 78, 84, + 85, 85, 128, 78, 84, 85, 77, 128, 78, 84, 85, 74, 128, 78, 84, 213, 78, + 84, 83, 65, 85, 128, 78, 84, 79, 81, 80, 69, 78, 128, 78, 84, 79, 71, + 128, 78, 84, 79, 199, 78, 84, 73, 69, 197, 78, 84, 72, 65, 85, 128, 78, + 84, 69, 85, 78, 71, 66, 65, 128, 78, 84, 69, 85, 77, 128, 78, 84, 69, 78, + 128, 78, 84, 69, 69, 128, 78, 84, 65, 80, 128, 78, 84, 65, 208, 78, 84, + 65, 65, 128, 78, 83, 85, 79, 212, 78, 83, 85, 78, 128, 78, 83, 85, 77, + 128, 78, 83, 79, 77, 128, 78, 83, 73, 69, 69, 84, 128, 78, 83, 73, 69, + 69, 80, 128, 78, 83, 73, 69, 69, 128, 78, 83, 72, 85, 84, 128, 78, 83, + 72, 85, 212, 78, 83, 72, 85, 79, 80, 128, 78, 83, 72, 85, 69, 128, 78, + 83, 72, 73, 69, 69, 128, 78, 83, 72, 69, 69, 128, 78, 83, 72, 65, 81, + 128, 78, 83, 72, 65, 128, 78, 83, 69, 85, 65, 69, 78, 128, 78, 83, 69, + 78, 128, 78, 83, 65, 128, 78, 82, 89, 88, 128, 78, 82, 89, 84, 128, 78, + 82, 89, 82, 88, 128, 78, 82, 89, 82, 128, 78, 82, 89, 80, 128, 78, 82, + 89, 128, 78, 82, 85, 88, 128, 78, 82, 85, 84, 128, 78, 82, 85, 82, 88, + 128, 78, 82, 85, 82, 128, 78, 82, 85, 80, 128, 78, 82, 85, 65, 128, 78, + 82, 85, 128, 78, 82, 79, 88, 128, 78, 82, 79, 80, 128, 78, 82, 79, 128, + 78, 82, 69, 88, 128, 78, 82, 69, 84, 128, 78, 82, 69, 211, 78, 82, 69, + 80, 128, 78, 82, 69, 128, 78, 82, 65, 88, 128, 78, 82, 65, 84, 128, 78, + 82, 65, 80, 128, 78, 82, 65, 128, 78, 81, 73, 71, 128, 78, 79, 89, 128, + 78, 79, 88, 128, 78, 79, 87, 67, 128, 78, 79, 86, 69, 77, 66, 69, 82, + 128, 78, 79, 84, 84, 79, 128, 78, 79, 84, 69, 83, 128, 78, 79, 84, 69, + 72, 69, 65, 68, 128, 78, 79, 84, 69, 72, 69, 65, 196, 78, 79, 84, 69, 66, + 79, 79, 75, 128, 78, 79, 84, 69, 66, 79, 79, 203, 78, 79, 84, 69, 128, + 78, 79, 84, 197, 78, 79, 84, 67, 72, 69, 196, 78, 79, 84, 67, 72, 128, + 78, 79, 84, 65, 84, 73, 79, 206, 78, 79, 84, 128, 78, 79, 212, 78, 79, + 83, 69, 128, 78, 79, 82, 84, 72, 87, 69, 83, 212, 78, 79, 82, 84, 72, 69, + 82, 206, 78, 79, 82, 84, 72, 69, 65, 83, 84, 45, 80, 79, 73, 78, 84, 73, + 78, 199, 78, 79, 82, 77, 65, 204, 78, 79, 82, 68, 73, 195, 78, 79, 210, 78, 79, 80, 128, 78, 79, 79, 78, 85, 128, 78, 79, 79, 128, 78, 79, 78, 70, 79, 82, 75, 73, 78, 71, 128, 78, 79, 78, 45, 80, 79, 84, 65, 66, 76, 197, 78, 79, 78, 45, 74, 79, 73, 78, 69, 82, 128, 78, 79, 78, 45, 66, 82, - 69, 65, 75, 73, 78, 199, 78, 79, 77, 73, 78, 65, 204, 78, 79, 75, 72, 85, - 75, 128, 78, 79, 68, 69, 128, 78, 79, 65, 128, 78, 79, 45, 66, 82, 69, - 65, 203, 78, 78, 85, 85, 128, 78, 78, 85, 128, 78, 78, 79, 79, 128, 78, - 78, 79, 128, 78, 78, 78, 85, 85, 128, 78, 78, 78, 85, 128, 78, 78, 78, - 79, 79, 128, 78, 78, 78, 79, 128, 78, 78, 78, 73, 73, 128, 78, 78, 78, - 73, 128, 78, 78, 78, 69, 69, 128, 78, 78, 78, 69, 128, 78, 78, 78, 65, - 85, 128, 78, 78, 78, 65, 73, 128, 78, 78, 78, 65, 65, 128, 78, 78, 78, - 65, 128, 78, 78, 78, 128, 78, 78, 72, 65, 128, 78, 78, 71, 79, 79, 128, - 78, 78, 71, 79, 128, 78, 78, 71, 73, 73, 128, 78, 78, 71, 73, 128, 78, - 78, 71, 65, 65, 128, 78, 78, 71, 65, 128, 78, 78, 71, 128, 78, 78, 66, - 83, 80, 128, 78, 77, 128, 78, 76, 48, 50, 48, 128, 78, 76, 48, 49, 57, - 128, 78, 76, 48, 49, 56, 128, 78, 76, 48, 49, 55, 65, 128, 78, 76, 48, - 49, 55, 128, 78, 76, 48, 49, 54, 128, 78, 76, 48, 49, 53, 128, 78, 76, - 48, 49, 52, 128, 78, 76, 48, 49, 51, 128, 78, 76, 48, 49, 50, 128, 78, - 76, 48, 49, 49, 128, 78, 76, 48, 49, 48, 128, 78, 76, 48, 48, 57, 128, - 78, 76, 48, 48, 56, 128, 78, 76, 48, 48, 55, 128, 78, 76, 48, 48, 54, - 128, 78, 76, 48, 48, 53, 65, 128, 78, 76, 48, 48, 53, 128, 78, 76, 48, - 48, 52, 128, 78, 76, 48, 48, 51, 128, 78, 76, 48, 48, 50, 128, 78, 76, - 48, 48, 49, 128, 78, 76, 128, 78, 75, 79, 77, 128, 78, 75, 207, 78, 75, - 73, 78, 68, 73, 128, 78, 75, 65, 65, 82, 65, 69, 128, 78, 74, 89, 88, - 128, 78, 74, 89, 84, 128, 78, 74, 89, 82, 88, 128, 78, 74, 89, 82, 128, - 78, 74, 89, 80, 128, 78, 74, 89, 128, 78, 74, 85, 88, 128, 78, 74, 85, - 82, 88, 128, 78, 74, 85, 82, 128, 78, 74, 85, 81, 65, 128, 78, 74, 85, - 80, 128, 78, 74, 85, 79, 88, 128, 78, 74, 85, 79, 128, 78, 74, 85, 69, - 81, 128, 78, 74, 85, 65, 69, 128, 78, 74, 85, 128, 78, 74, 79, 88, 128, - 78, 74, 79, 84, 128, 78, 74, 79, 80, 128, 78, 74, 79, 79, 128, 78, 74, - 79, 128, 78, 74, 73, 88, 128, 78, 74, 73, 84, 128, 78, 74, 73, 80, 128, - 78, 74, 73, 69, 88, 128, 78, 74, 73, 69, 84, 128, 78, 74, 73, 69, 80, - 128, 78, 74, 73, 69, 69, 128, 78, 74, 73, 69, 128, 78, 74, 73, 128, 78, - 74, 201, 78, 74, 69, 85, 88, 128, 78, 74, 69, 85, 84, 128, 78, 74, 69, - 85, 65, 69, 78, 65, 128, 78, 74, 69, 85, 65, 69, 77, 128, 78, 74, 69, 69, - 69, 69, 128, 78, 74, 69, 69, 128, 78, 74, 69, 197, 78, 74, 69, 128, 78, - 74, 65, 81, 128, 78, 74, 65, 80, 128, 78, 74, 65, 69, 77, 76, 73, 128, - 78, 74, 65, 69, 77, 128, 78, 74, 65, 65, 128, 78, 73, 88, 128, 78, 73, - 84, 82, 69, 128, 78, 73, 83, 65, 71, 128, 78, 73, 82, 85, 71, 85, 128, - 78, 73, 80, 128, 78, 73, 78, 84, 72, 128, 78, 73, 78, 69, 84, 89, 128, - 78, 73, 78, 69, 84, 217, 78, 73, 78, 69, 84, 69, 69, 78, 128, 78, 73, 78, - 69, 84, 69, 69, 206, 78, 73, 78, 69, 45, 84, 72, 73, 82, 84, 89, 128, 78, - 73, 78, 197, 78, 73, 78, 68, 65, 50, 128, 78, 73, 78, 68, 65, 178, 78, - 73, 77, 128, 78, 73, 205, 78, 73, 75, 72, 65, 72, 73, 84, 128, 78, 73, - 75, 65, 72, 73, 84, 128, 78, 73, 75, 65, 128, 78, 73, 72, 83, 72, 86, 65, - 83, 65, 128, 78, 73, 71, 73, 68, 65, 77, 73, 78, 128, 78, 73, 71, 73, 68, - 65, 69, 83, 72, 128, 78, 73, 71, 72, 84, 128, 78, 73, 71, 72, 212, 78, - 73, 71, 71, 65, 72, 73, 84, 65, 128, 78, 73, 69, 88, 128, 78, 73, 69, 85, - 78, 45, 84, 73, 75, 69, 85, 84, 128, 78, 73, 69, 85, 78, 45, 84, 72, 73, - 69, 85, 84, 72, 128, 78, 73, 69, 85, 78, 45, 83, 73, 79, 83, 128, 78, 73, - 69, 85, 78, 45, 82, 73, 69, 85, 76, 128, 78, 73, 69, 85, 78, 45, 80, 73, - 69, 85, 80, 128, 78, 73, 69, 85, 78, 45, 80, 65, 78, 83, 73, 79, 83, 128, - 78, 73, 69, 85, 78, 45, 75, 73, 89, 69, 79, 75, 128, 78, 73, 69, 85, 78, - 45, 72, 73, 69, 85, 72, 128, 78, 73, 69, 85, 78, 45, 67, 73, 69, 85, 67, - 128, 78, 73, 69, 85, 78, 45, 67, 72, 73, 69, 85, 67, 72, 128, 78, 73, 69, - 85, 206, 78, 73, 69, 80, 128, 78, 73, 69, 128, 78, 73, 66, 128, 78, 73, - 65, 128, 78, 73, 50, 128, 78, 72, 85, 69, 128, 78, 72, 74, 65, 128, 78, - 72, 128, 78, 71, 89, 69, 128, 78, 71, 86, 69, 128, 78, 71, 85, 85, 128, - 78, 71, 85, 79, 88, 128, 78, 71, 85, 79, 84, 128, 78, 71, 85, 79, 128, - 78, 71, 85, 65, 69, 84, 128, 78, 71, 85, 65, 69, 128, 78, 71, 79, 88, - 128, 78, 71, 79, 85, 128, 78, 71, 79, 213, 78, 71, 79, 84, 128, 78, 71, - 79, 81, 128, 78, 71, 79, 80, 128, 78, 71, 79, 78, 128, 78, 71, 79, 77, - 128, 78, 71, 79, 69, 72, 128, 78, 71, 79, 69, 200, 78, 71, 207, 78, 71, - 75, 89, 69, 69, 128, 78, 71, 75, 87, 65, 69, 78, 128, 78, 71, 75, 85, 80, - 128, 78, 71, 75, 85, 78, 128, 78, 71, 75, 85, 77, 128, 78, 71, 75, 85, - 69, 78, 90, 69, 85, 77, 128, 78, 71, 75, 85, 197, 78, 71, 75, 73, 78, 68, - 201, 78, 71, 75, 73, 69, 69, 128, 78, 71, 75, 69, 85, 88, 128, 78, 71, - 75, 69, 85, 82, 73, 128, 78, 71, 75, 69, 85, 65, 69, 81, 128, 78, 71, 75, - 69, 85, 65, 69, 77, 128, 78, 71, 75, 65, 81, 128, 78, 71, 75, 65, 80, - 128, 78, 71, 75, 65, 65, 77, 73, 128, 78, 71, 75, 65, 128, 78, 71, 73, - 69, 88, 128, 78, 71, 73, 69, 80, 128, 78, 71, 73, 69, 128, 78, 71, 72, - 65, 128, 78, 71, 71, 87, 65, 69, 78, 128, 78, 71, 71, 85, 82, 65, 69, - 128, 78, 71, 71, 85, 80, 128, 78, 71, 71, 85, 79, 81, 128, 78, 71, 71, - 85, 79, 209, 78, 71, 71, 85, 79, 78, 128, 78, 71, 71, 85, 79, 77, 128, - 78, 71, 71, 85, 77, 128, 78, 71, 71, 85, 69, 69, 84, 128, 78, 71, 71, 85, - 65, 69, 83, 72, 65, 197, 78, 71, 71, 85, 65, 69, 206, 78, 71, 71, 85, - 128, 78, 71, 71, 79, 79, 128, 78, 71, 71, 79, 128, 78, 71, 71, 73, 128, - 78, 71, 71, 69, 85, 88, 128, 78, 71, 71, 69, 85, 65, 69, 84, 128, 78, 71, - 71, 69, 85, 65, 69, 128, 78, 71, 71, 69, 213, 78, 71, 71, 69, 78, 128, - 78, 71, 71, 69, 69, 84, 128, 78, 71, 71, 69, 69, 69, 69, 128, 78, 71, 71, - 69, 69, 128, 78, 71, 71, 69, 128, 78, 71, 71, 65, 80, 128, 78, 71, 71, - 65, 65, 77, 65, 69, 128, 78, 71, 71, 65, 65, 77, 128, 78, 71, 71, 128, - 78, 71, 69, 88, 128, 78, 71, 69, 85, 82, 69, 85, 84, 128, 78, 71, 69, 80, - 128, 78, 71, 69, 78, 128, 78, 71, 69, 69, 128, 78, 71, 69, 65, 68, 65, - 76, 128, 78, 71, 65, 88, 128, 78, 71, 65, 85, 128, 78, 71, 65, 84, 128, - 78, 71, 65, 211, 78, 71, 65, 81, 128, 78, 71, 65, 80, 128, 78, 71, 65, - 78, 71, 85, 128, 78, 71, 65, 78, 128, 78, 71, 65, 73, 128, 78, 71, 65, - 72, 128, 78, 71, 65, 65, 73, 128, 78, 71, 193, 78, 70, 128, 78, 69, 88, - 212, 78, 69, 88, 128, 78, 69, 87, 83, 80, 65, 80, 69, 82, 128, 78, 69, - 87, 76, 73, 78, 69, 128, 78, 69, 87, 128, 78, 69, 85, 84, 82, 65, 204, - 78, 69, 85, 84, 69, 82, 128, 78, 69, 84, 128, 78, 69, 212, 78, 69, 83, - 84, 69, 196, 78, 69, 81, 85, 68, 65, 65, 128, 78, 69, 80, 84, 85, 78, 69, - 128, 78, 69, 80, 128, 78, 69, 79, 128, 78, 69, 207, 78, 69, 78, 65, 78, - 79, 128, 78, 69, 78, 128, 78, 69, 76, 128, 78, 69, 73, 84, 72, 69, 210, - 78, 69, 71, 65, 84, 73, 79, 206, 78, 69, 71, 65, 84, 69, 196, 78, 69, 67, - 75, 84, 73, 69, 128, 78, 69, 66, 69, 78, 83, 84, 73, 77, 77, 69, 128, 78, - 68, 85, 88, 128, 78, 68, 85, 84, 128, 78, 68, 85, 82, 88, 128, 78, 68, - 85, 82, 128, 78, 68, 85, 80, 128, 78, 68, 85, 78, 128, 78, 68, 213, 78, - 68, 79, 88, 128, 78, 68, 79, 84, 128, 78, 68, 79, 80, 128, 78, 68, 79, - 79, 128, 78, 68, 79, 78, 128, 78, 68, 79, 77, 66, 85, 128, 78, 68, 79, - 76, 197, 78, 68, 73, 88, 128, 78, 68, 73, 84, 128, 78, 68, 73, 81, 128, - 78, 68, 73, 80, 128, 78, 68, 73, 69, 88, 128, 78, 68, 73, 69, 128, 78, - 68, 73, 68, 65, 128, 78, 68, 73, 65, 81, 128, 78, 68, 69, 88, 128, 78, - 68, 69, 85, 88, 128, 78, 68, 69, 85, 84, 128, 78, 68, 69, 85, 65, 69, 82, - 69, 69, 128, 78, 68, 69, 80, 128, 78, 68, 69, 69, 128, 78, 68, 69, 128, - 78, 68, 65, 88, 128, 78, 68, 65, 84, 128, 78, 68, 65, 80, 128, 78, 68, - 65, 77, 128, 78, 68, 65, 65, 78, 71, 71, 69, 85, 65, 69, 84, 128, 78, 68, - 65, 65, 128, 78, 68, 65, 193, 78, 66, 89, 88, 128, 78, 66, 89, 84, 128, - 78, 66, 89, 82, 88, 128, 78, 66, 89, 82, 128, 78, 66, 89, 80, 128, 78, - 66, 89, 128, 78, 66, 85, 88, 128, 78, 66, 85, 84, 128, 78, 66, 85, 82, - 88, 128, 78, 66, 85, 82, 128, 78, 66, 85, 80, 128, 78, 66, 85, 128, 78, - 66, 79, 88, 128, 78, 66, 79, 84, 128, 78, 66, 79, 80, 128, 78, 66, 79, - 128, 78, 66, 73, 88, 128, 78, 66, 73, 84, 128, 78, 66, 73, 80, 128, 78, - 66, 73, 69, 88, 128, 78, 66, 73, 69, 80, 128, 78, 66, 73, 69, 128, 78, - 66, 73, 128, 78, 66, 72, 128, 78, 66, 65, 88, 128, 78, 66, 65, 84, 128, - 78, 66, 65, 80, 128, 78, 66, 65, 128, 78, 65, 89, 65, 78, 78, 65, 128, - 78, 65, 89, 128, 78, 65, 88, 73, 65, 206, 78, 65, 88, 128, 78, 65, 85, - 84, 72, 83, 128, 78, 65, 85, 68, 73, 218, 78, 65, 84, 85, 82, 65, 204, - 78, 65, 84, 73, 79, 78, 65, 204, 78, 65, 83, 75, 65, 80, 201, 78, 65, 83, - 72, 73, 128, 78, 65, 83, 65, 76, 73, 90, 65, 84, 73, 79, 78, 128, 78, 65, - 83, 65, 76, 73, 90, 65, 84, 73, 79, 206, 78, 65, 82, 82, 79, 215, 78, 65, - 82, 128, 78, 65, 81, 128, 78, 65, 79, 211, 78, 65, 78, 83, 65, 78, 65, - 81, 128, 78, 65, 78, 71, 77, 79, 78, 84, 72, 79, 128, 78, 65, 78, 68, - 128, 78, 65, 78, 65, 128, 78, 65, 77, 69, 128, 78, 65, 77, 197, 78, 65, - 77, 50, 128, 78, 65, 77, 128, 78, 65, 75, 128, 78, 65, 73, 82, 193, 78, - 65, 73, 204, 78, 65, 71, 82, 201, 78, 65, 71, 65, 82, 128, 78, 65, 71, - 65, 128, 78, 65, 71, 193, 78, 65, 71, 128, 78, 65, 199, 78, 65, 69, 128, - 78, 65, 66, 76, 65, 128, 78, 65, 65, 83, 73, 75, 89, 65, 89, 65, 128, 78, + 69, 65, 75, 73, 78, 199, 78, 79, 78, 128, 78, 79, 77, 73, 78, 65, 204, + 78, 79, 75, 72, 85, 75, 128, 78, 79, 68, 69, 128, 78, 79, 65, 128, 78, + 79, 45, 66, 82, 69, 65, 203, 78, 78, 85, 85, 128, 78, 78, 85, 128, 78, + 78, 79, 79, 128, 78, 78, 79, 128, 78, 78, 78, 85, 85, 128, 78, 78, 78, + 85, 128, 78, 78, 78, 79, 79, 128, 78, 78, 78, 79, 128, 78, 78, 78, 73, + 73, 128, 78, 78, 78, 73, 128, 78, 78, 78, 69, 69, 128, 78, 78, 78, 69, + 128, 78, 78, 78, 65, 85, 128, 78, 78, 78, 65, 73, 128, 78, 78, 78, 65, + 65, 128, 78, 78, 78, 65, 128, 78, 78, 78, 128, 78, 78, 72, 65, 128, 78, + 78, 71, 79, 79, 128, 78, 78, 71, 79, 128, 78, 78, 71, 73, 73, 128, 78, + 78, 71, 73, 128, 78, 78, 71, 65, 65, 128, 78, 78, 71, 65, 128, 78, 78, + 71, 128, 78, 78, 66, 83, 80, 128, 78, 77, 128, 78, 76, 65, 85, 128, 78, + 76, 48, 50, 48, 128, 78, 76, 48, 49, 57, 128, 78, 76, 48, 49, 56, 128, + 78, 76, 48, 49, 55, 65, 128, 78, 76, 48, 49, 55, 128, 78, 76, 48, 49, 54, + 128, 78, 76, 48, 49, 53, 128, 78, 76, 48, 49, 52, 128, 78, 76, 48, 49, + 51, 128, 78, 76, 48, 49, 50, 128, 78, 76, 48, 49, 49, 128, 78, 76, 48, + 49, 48, 128, 78, 76, 48, 48, 57, 128, 78, 76, 48, 48, 56, 128, 78, 76, + 48, 48, 55, 128, 78, 76, 48, 48, 54, 128, 78, 76, 48, 48, 53, 65, 128, + 78, 76, 48, 48, 53, 128, 78, 76, 48, 48, 52, 128, 78, 76, 48, 48, 51, + 128, 78, 76, 48, 48, 50, 128, 78, 76, 48, 48, 49, 128, 78, 76, 128, 78, + 75, 79, 77, 128, 78, 75, 207, 78, 75, 73, 78, 68, 73, 128, 78, 75, 65, + 85, 128, 78, 75, 65, 65, 82, 65, 69, 128, 78, 74, 89, 88, 128, 78, 74, + 89, 84, 128, 78, 74, 89, 82, 88, 128, 78, 74, 89, 82, 128, 78, 74, 89, + 80, 128, 78, 74, 89, 128, 78, 74, 85, 88, 128, 78, 74, 85, 82, 88, 128, + 78, 74, 85, 82, 128, 78, 74, 85, 81, 65, 128, 78, 74, 85, 80, 128, 78, + 74, 85, 79, 88, 128, 78, 74, 85, 79, 128, 78, 74, 85, 69, 81, 128, 78, + 74, 85, 65, 69, 128, 78, 74, 85, 128, 78, 74, 79, 88, 128, 78, 74, 79, + 84, 128, 78, 74, 79, 80, 128, 78, 74, 79, 79, 128, 78, 74, 79, 128, 78, + 74, 73, 88, 128, 78, 74, 73, 84, 128, 78, 74, 73, 80, 128, 78, 74, 73, + 69, 88, 128, 78, 74, 73, 69, 84, 128, 78, 74, 73, 69, 80, 128, 78, 74, + 73, 69, 69, 128, 78, 74, 73, 69, 128, 78, 74, 73, 128, 78, 74, 201, 78, + 74, 69, 85, 88, 128, 78, 74, 69, 85, 84, 128, 78, 74, 69, 85, 65, 69, 78, + 65, 128, 78, 74, 69, 85, 65, 69, 77, 128, 78, 74, 69, 69, 69, 69, 128, + 78, 74, 69, 69, 128, 78, 74, 69, 197, 78, 74, 69, 128, 78, 74, 65, 81, + 128, 78, 74, 65, 80, 128, 78, 74, 65, 69, 77, 76, 73, 128, 78, 74, 65, + 69, 77, 128, 78, 74, 65, 65, 128, 78, 73, 88, 128, 78, 73, 84, 82, 69, + 128, 78, 73, 83, 65, 71, 128, 78, 73, 82, 85, 71, 85, 128, 78, 73, 80, + 128, 78, 73, 78, 84, 72, 128, 78, 73, 78, 69, 84, 89, 128, 78, 73, 78, + 69, 84, 217, 78, 73, 78, 69, 84, 69, 69, 78, 128, 78, 73, 78, 69, 84, 69, + 69, 206, 78, 73, 78, 69, 45, 84, 72, 73, 82, 84, 89, 128, 78, 73, 78, + 197, 78, 73, 78, 68, 65, 50, 128, 78, 73, 78, 68, 65, 178, 78, 73, 78, + 57, 128, 78, 73, 78, 128, 78, 73, 77, 128, 78, 73, 205, 78, 73, 75, 72, + 65, 72, 73, 84, 128, 78, 73, 75, 65, 72, 73, 84, 128, 78, 73, 75, 65, + 128, 78, 73, 72, 83, 72, 86, 65, 83, 65, 128, 78, 73, 71, 73, 68, 65, 77, + 73, 78, 128, 78, 73, 71, 73, 68, 65, 69, 83, 72, 128, 78, 73, 71, 72, 84, + 128, 78, 73, 71, 72, 212, 78, 73, 71, 71, 65, 72, 73, 84, 65, 128, 78, + 73, 69, 88, 128, 78, 73, 69, 85, 78, 45, 84, 73, 75, 69, 85, 84, 128, 78, + 73, 69, 85, 78, 45, 84, 72, 73, 69, 85, 84, 72, 128, 78, 73, 69, 85, 78, + 45, 83, 73, 79, 83, 128, 78, 73, 69, 85, 78, 45, 82, 73, 69, 85, 76, 128, + 78, 73, 69, 85, 78, 45, 80, 73, 69, 85, 80, 128, 78, 73, 69, 85, 78, 45, + 80, 65, 78, 83, 73, 79, 83, 128, 78, 73, 69, 85, 78, 45, 75, 73, 89, 69, + 79, 75, 128, 78, 73, 69, 85, 78, 45, 72, 73, 69, 85, 72, 128, 78, 73, 69, + 85, 78, 45, 67, 73, 69, 85, 67, 128, 78, 73, 69, 85, 78, 45, 67, 72, 73, + 69, 85, 67, 72, 128, 78, 73, 69, 85, 206, 78, 73, 69, 80, 128, 78, 73, + 69, 128, 78, 73, 66, 128, 78, 73, 65, 128, 78, 73, 50, 128, 78, 72, 85, + 69, 128, 78, 72, 74, 65, 128, 78, 72, 128, 78, 71, 89, 69, 128, 78, 71, + 86, 69, 128, 78, 71, 85, 85, 128, 78, 71, 85, 79, 88, 128, 78, 71, 85, + 79, 84, 128, 78, 71, 85, 79, 128, 78, 71, 85, 65, 78, 128, 78, 71, 85, + 65, 69, 84, 128, 78, 71, 85, 65, 69, 128, 78, 71, 79, 88, 128, 78, 71, + 79, 85, 128, 78, 71, 79, 213, 78, 71, 79, 84, 128, 78, 71, 79, 81, 128, + 78, 71, 79, 80, 128, 78, 71, 79, 78, 128, 78, 71, 79, 77, 128, 78, 71, + 79, 69, 72, 128, 78, 71, 79, 69, 200, 78, 71, 207, 78, 71, 75, 89, 69, + 69, 128, 78, 71, 75, 87, 65, 69, 78, 128, 78, 71, 75, 85, 80, 128, 78, + 71, 75, 85, 78, 128, 78, 71, 75, 85, 77, 128, 78, 71, 75, 85, 69, 78, 90, + 69, 85, 77, 128, 78, 71, 75, 85, 197, 78, 71, 75, 73, 78, 68, 201, 78, + 71, 75, 73, 69, 69, 128, 78, 71, 75, 69, 85, 88, 128, 78, 71, 75, 69, 85, + 82, 73, 128, 78, 71, 75, 69, 85, 65, 69, 81, 128, 78, 71, 75, 69, 85, 65, + 69, 77, 128, 78, 71, 75, 65, 81, 128, 78, 71, 75, 65, 80, 128, 78, 71, + 75, 65, 65, 77, 73, 128, 78, 71, 75, 65, 128, 78, 71, 73, 69, 88, 128, + 78, 71, 73, 69, 80, 128, 78, 71, 73, 69, 128, 78, 71, 72, 65, 128, 78, + 71, 71, 87, 65, 69, 78, 128, 78, 71, 71, 85, 82, 65, 69, 128, 78, 71, 71, + 85, 80, 128, 78, 71, 71, 85, 79, 81, 128, 78, 71, 71, 85, 79, 209, 78, + 71, 71, 85, 79, 78, 128, 78, 71, 71, 85, 79, 77, 128, 78, 71, 71, 85, 77, + 128, 78, 71, 71, 85, 69, 69, 84, 128, 78, 71, 71, 85, 65, 69, 83, 72, 65, + 197, 78, 71, 71, 85, 65, 69, 206, 78, 71, 71, 85, 65, 128, 78, 71, 71, + 85, 128, 78, 71, 71, 79, 79, 128, 78, 71, 71, 79, 128, 78, 71, 71, 73, + 128, 78, 71, 71, 69, 85, 88, 128, 78, 71, 71, 69, 85, 65, 69, 84, 128, + 78, 71, 71, 69, 85, 65, 69, 128, 78, 71, 71, 69, 213, 78, 71, 71, 69, 78, + 128, 78, 71, 71, 69, 69, 84, 128, 78, 71, 71, 69, 69, 69, 69, 128, 78, + 71, 71, 69, 69, 128, 78, 71, 71, 69, 128, 78, 71, 71, 65, 80, 128, 78, + 71, 71, 65, 65, 77, 65, 69, 128, 78, 71, 71, 65, 65, 77, 128, 78, 71, 71, + 65, 65, 128, 78, 71, 71, 128, 78, 71, 69, 88, 128, 78, 71, 69, 85, 82, + 69, 85, 84, 128, 78, 71, 69, 80, 128, 78, 71, 69, 78, 128, 78, 71, 69, + 69, 128, 78, 71, 69, 65, 68, 65, 76, 128, 78, 71, 65, 88, 128, 78, 71, + 65, 85, 128, 78, 71, 65, 84, 128, 78, 71, 65, 211, 78, 71, 65, 81, 128, + 78, 71, 65, 80, 128, 78, 71, 65, 78, 71, 85, 128, 78, 71, 65, 78, 128, + 78, 71, 65, 73, 128, 78, 71, 65, 72, 128, 78, 71, 65, 65, 73, 128, 78, + 71, 193, 78, 70, 128, 78, 69, 88, 212, 78, 69, 88, 128, 78, 69, 87, 83, + 80, 65, 80, 69, 82, 128, 78, 69, 87, 76, 73, 78, 69, 128, 78, 69, 87, 76, + 73, 78, 197, 78, 69, 87, 128, 78, 69, 85, 84, 82, 65, 204, 78, 69, 85, + 84, 69, 82, 128, 78, 69, 84, 87, 79, 82, 75, 69, 196, 78, 69, 84, 128, + 78, 69, 212, 78, 69, 83, 84, 69, 196, 78, 69, 81, 85, 68, 65, 65, 128, + 78, 69, 80, 84, 85, 78, 69, 128, 78, 69, 80, 128, 78, 69, 79, 128, 78, + 69, 207, 78, 69, 78, 79, 69, 128, 78, 69, 78, 65, 78, 79, 128, 78, 69, + 78, 128, 78, 69, 76, 128, 78, 69, 73, 84, 72, 69, 210, 78, 69, 71, 65, + 84, 73, 79, 206, 78, 69, 71, 65, 84, 69, 196, 78, 69, 67, 75, 84, 73, 69, + 128, 78, 69, 66, 69, 78, 83, 84, 73, 77, 77, 69, 128, 78, 68, 85, 88, + 128, 78, 68, 85, 84, 128, 78, 68, 85, 82, 88, 128, 78, 68, 85, 82, 128, + 78, 68, 85, 80, 128, 78, 68, 85, 78, 128, 78, 68, 213, 78, 68, 79, 88, + 128, 78, 68, 79, 84, 128, 78, 68, 79, 80, 128, 78, 68, 79, 79, 128, 78, + 68, 79, 78, 128, 78, 68, 79, 77, 66, 85, 128, 78, 68, 79, 76, 197, 78, + 68, 73, 88, 128, 78, 68, 73, 84, 128, 78, 68, 73, 81, 128, 78, 68, 73, + 80, 128, 78, 68, 73, 69, 88, 128, 78, 68, 73, 69, 128, 78, 68, 73, 68, + 65, 128, 78, 68, 73, 65, 81, 128, 78, 68, 69, 88, 128, 78, 68, 69, 85, + 88, 128, 78, 68, 69, 85, 84, 128, 78, 68, 69, 85, 65, 69, 82, 69, 69, + 128, 78, 68, 69, 80, 128, 78, 68, 69, 69, 128, 78, 68, 69, 128, 78, 68, + 65, 88, 128, 78, 68, 65, 84, 128, 78, 68, 65, 80, 128, 78, 68, 65, 77, + 128, 78, 68, 65, 65, 78, 71, 71, 69, 85, 65, 69, 84, 128, 78, 68, 65, 65, + 128, 78, 68, 65, 193, 78, 67, 72, 65, 85, 128, 78, 66, 89, 88, 128, 78, + 66, 89, 84, 128, 78, 66, 89, 82, 88, 128, 78, 66, 89, 82, 128, 78, 66, + 89, 80, 128, 78, 66, 89, 128, 78, 66, 85, 88, 128, 78, 66, 85, 84, 128, + 78, 66, 85, 82, 88, 128, 78, 66, 85, 82, 128, 78, 66, 85, 80, 128, 78, + 66, 85, 128, 78, 66, 79, 88, 128, 78, 66, 79, 84, 128, 78, 66, 79, 80, + 128, 78, 66, 79, 128, 78, 66, 73, 88, 128, 78, 66, 73, 84, 128, 78, 66, + 73, 80, 128, 78, 66, 73, 69, 88, 128, 78, 66, 73, 69, 80, 128, 78, 66, + 73, 69, 128, 78, 66, 73, 128, 78, 66, 72, 128, 78, 66, 65, 88, 128, 78, + 66, 65, 84, 128, 78, 66, 65, 80, 128, 78, 66, 65, 128, 78, 65, 89, 65, + 78, 78, 65, 128, 78, 65, 89, 128, 78, 65, 88, 73, 65, 206, 78, 65, 88, + 128, 78, 65, 85, 84, 72, 83, 128, 78, 65, 85, 68, 73, 218, 78, 65, 84, + 85, 82, 65, 204, 78, 65, 84, 73, 79, 78, 65, 204, 78, 65, 83, 75, 65, 80, + 201, 78, 65, 83, 72, 73, 128, 78, 65, 83, 65, 76, 73, 90, 65, 84, 73, 79, + 78, 128, 78, 65, 83, 65, 76, 73, 90, 65, 84, 73, 79, 206, 78, 65, 83, 65, + 204, 78, 65, 82, 82, 79, 215, 78, 65, 82, 128, 78, 65, 81, 128, 78, 65, + 79, 211, 78, 65, 78, 83, 65, 78, 65, 81, 128, 78, 65, 78, 71, 77, 79, 78, + 84, 72, 79, 128, 78, 65, 78, 68, 128, 78, 65, 78, 65, 128, 78, 65, 77, + 69, 128, 78, 65, 77, 197, 78, 65, 77, 50, 128, 78, 65, 77, 128, 78, 65, + 75, 128, 78, 65, 73, 82, 193, 78, 65, 73, 204, 78, 65, 71, 82, 201, 78, + 65, 71, 65, 82, 128, 78, 65, 71, 65, 128, 78, 65, 71, 193, 78, 65, 71, + 128, 78, 65, 199, 78, 65, 69, 128, 78, 65, 66, 76, 65, 128, 78, 65, 66, + 65, 84, 65, 69, 65, 206, 78, 65, 65, 83, 73, 75, 89, 65, 89, 65, 128, 78, 65, 65, 75, 83, 73, 75, 89, 65, 89, 65, 128, 78, 65, 65, 73, 128, 78, 65, - 193, 78, 65, 50, 128, 78, 65, 45, 50, 128, 78, 48, 52, 50, 128, 78, 48, - 52, 49, 128, 78, 48, 52, 48, 128, 78, 48, 51, 57, 128, 78, 48, 51, 56, - 128, 78, 48, 51, 55, 65, 128, 78, 48, 51, 55, 128, 78, 48, 51, 54, 128, - 78, 48, 51, 53, 65, 128, 78, 48, 51, 53, 128, 78, 48, 51, 52, 65, 128, - 78, 48, 51, 52, 128, 78, 48, 51, 51, 65, 128, 78, 48, 51, 51, 128, 78, - 48, 51, 50, 128, 78, 48, 51, 49, 128, 78, 48, 51, 48, 128, 78, 48, 50, - 57, 128, 78, 48, 50, 56, 128, 78, 48, 50, 55, 128, 78, 48, 50, 54, 128, - 78, 48, 50, 53, 65, 128, 78, 48, 50, 53, 128, 78, 48, 50, 52, 128, 78, - 48, 50, 51, 128, 78, 48, 50, 50, 128, 78, 48, 50, 49, 128, 78, 48, 50, - 48, 128, 78, 48, 49, 57, 128, 78, 48, 49, 56, 66, 128, 78, 48, 49, 56, - 65, 128, 78, 48, 49, 56, 128, 78, 48, 49, 55, 128, 78, 48, 49, 54, 128, - 78, 48, 49, 53, 128, 78, 48, 49, 52, 128, 78, 48, 49, 51, 128, 78, 48, - 49, 50, 128, 78, 48, 49, 49, 128, 78, 48, 49, 48, 128, 78, 48, 48, 57, - 128, 78, 48, 48, 56, 128, 78, 48, 48, 55, 128, 78, 48, 48, 54, 128, 78, - 48, 48, 53, 128, 78, 48, 48, 52, 128, 78, 48, 48, 51, 128, 78, 48, 48, - 50, 128, 78, 48, 48, 49, 128, 78, 45, 67, 82, 69, 197, 78, 45, 65, 82, - 217, 77, 89, 88, 128, 77, 89, 84, 128, 77, 89, 83, 76, 73, 84, 69, 128, - 77, 89, 80, 128, 77, 89, 65, 128, 77, 89, 193, 77, 89, 128, 77, 217, 77, - 87, 79, 79, 128, 77, 87, 79, 128, 77, 87, 73, 73, 128, 77, 87, 73, 128, - 77, 87, 69, 69, 128, 77, 87, 69, 128, 77, 87, 65, 65, 128, 77, 87, 65, - 128, 77, 87, 128, 77, 215, 77, 86, 83, 128, 77, 86, 79, 80, 128, 77, 86, - 73, 128, 77, 86, 69, 85, 65, 69, 78, 71, 65, 77, 128, 77, 86, 128, 77, - 214, 77, 85, 88, 128, 77, 85, 85, 83, 73, 75, 65, 84, 79, 65, 78, 128, - 77, 85, 85, 82, 68, 72, 65, 74, 193, 77, 85, 85, 128, 77, 85, 84, 128, - 77, 85, 83, 73, 67, 128, 77, 85, 83, 73, 195, 77, 85, 83, 72, 82, 79, 79, - 77, 128, 77, 85, 83, 72, 51, 128, 77, 85, 83, 72, 179, 77, 85, 83, 72, - 128, 77, 85, 83, 200, 77, 85, 82, 88, 128, 77, 85, 82, 71, 85, 50, 128, - 77, 85, 82, 69, 128, 77, 85, 82, 68, 65, 128, 77, 85, 82, 68, 193, 77, - 85, 82, 128, 77, 85, 81, 68, 65, 77, 128, 77, 85, 80, 128, 77, 85, 79, - 88, 128, 77, 85, 79, 84, 128, 77, 85, 79, 80, 128, 77, 85, 79, 77, 65, - 69, 128, 77, 85, 79, 128, 77, 85, 78, 83, 85, 66, 128, 77, 85, 78, 65, - 72, 128, 77, 85, 76, 84, 73, 83, 69, 84, 128, 77, 85, 76, 84, 73, 83, 69, - 212, 77, 85, 76, 84, 73, 80, 76, 73, 67, 65, 84, 73, 79, 78, 128, 77, 85, - 76, 84, 73, 80, 76, 73, 67, 65, 84, 73, 79, 206, 77, 85, 76, 84, 73, 80, - 76, 197, 77, 85, 76, 84, 73, 79, 67, 85, 76, 65, 210, 77, 85, 76, 84, 73, - 77, 65, 80, 128, 77, 85, 76, 84, 201, 77, 85, 75, 80, 72, 82, 69, 78, 71, - 128, 77, 85, 73, 78, 128, 77, 85, 71, 83, 128, 77, 85, 71, 128, 77, 85, - 199, 77, 85, 69, 128, 77, 85, 67, 72, 128, 77, 85, 67, 200, 77, 85, 67, - 65, 65, 68, 128, 77, 85, 65, 78, 128, 77, 85, 65, 69, 128, 77, 85, 45, - 71, 65, 65, 72, 76, 65, 193, 77, 213, 77, 83, 128, 77, 80, 65, 128, 77, - 79, 89, 65, 73, 128, 77, 79, 88, 128, 77, 79, 86, 73, 197, 77, 79, 86, - 69, 196, 77, 79, 85, 84, 72, 128, 77, 79, 85, 84, 200, 77, 79, 85, 83, - 69, 128, 77, 79, 85, 83, 197, 77, 79, 85, 78, 84, 65, 73, 78, 83, 128, - 77, 79, 85, 78, 84, 65, 73, 78, 128, 77, 79, 85, 78, 84, 65, 73, 206, 77, - 79, 85, 78, 212, 77, 79, 85, 78, 68, 128, 77, 79, 85, 78, 196, 77, 79, - 84, 72, 69, 82, 128, 77, 79, 84, 128, 77, 79, 82, 84, 85, 85, 77, 128, - 77, 79, 82, 84, 65, 82, 128, 77, 79, 82, 80, 72, 79, 76, 79, 71, 73, 67, - 65, 204, 77, 79, 82, 78, 73, 78, 71, 128, 77, 79, 80, 128, 77, 79, 79, - 83, 69, 45, 67, 82, 69, 197, 77, 79, 79, 78, 128, 77, 79, 79, 206, 77, - 79, 79, 77, 80, 85, 81, 128, 77, 79, 79, 77, 69, 85, 84, 128, 77, 79, 79, - 128, 77, 79, 78, 84, 73, 69, 69, 78, 128, 77, 79, 78, 84, 72, 128, 77, - 79, 78, 84, 200, 77, 79, 78, 83, 84, 69, 82, 128, 77, 79, 78, 79, 83, 84, - 65, 66, 76, 197, 77, 79, 78, 79, 83, 80, 65, 67, 197, 77, 79, 78, 79, 82, - 65, 73, 76, 128, 77, 79, 78, 79, 71, 82, 65, 80, 200, 77, 79, 78, 79, 71, - 82, 65, 77, 77, 79, 211, 77, 79, 78, 79, 71, 82, 65, 205, 77, 79, 78, 79, - 70, 79, 78, 73, 65, 83, 128, 77, 79, 78, 79, 67, 85, 76, 65, 210, 77, 79, - 78, 75, 69, 89, 128, 77, 79, 78, 75, 69, 217, 77, 79, 78, 73, 128, 77, - 79, 78, 71, 75, 69, 85, 65, 69, 81, 128, 77, 79, 78, 69, 217, 77, 79, 78, - 128, 77, 79, 206, 77, 79, 76, 128, 77, 79, 72, 65, 77, 77, 65, 196, 77, - 79, 68, 85, 76, 207, 77, 79, 68, 69, 83, 84, 89, 128, 77, 79, 68, 69, 76, - 83, 128, 77, 79, 68, 69, 76, 128, 77, 79, 68, 69, 128, 77, 79, 66, 73, - 76, 197, 77, 79, 65, 128, 77, 207, 77, 78, 89, 65, 205, 77, 78, 65, 83, - 128, 77, 77, 83, 80, 128, 77, 77, 128, 77, 205, 77, 76, 65, 128, 77, 76, - 128, 77, 75, 80, 65, 82, 65, 209, 77, 73, 88, 128, 77, 73, 84, 128, 77, - 73, 83, 82, 65, 128, 77, 73, 82, 73, 66, 65, 65, 82, 85, 128, 77, 73, 82, - 73, 128, 77, 73, 82, 69, 68, 128, 77, 73, 80, 128, 77, 73, 78, 89, 128, - 77, 73, 78, 85, 83, 45, 79, 82, 45, 80, 76, 85, 211, 77, 73, 78, 85, 83, - 128, 77, 73, 78, 73, 83, 84, 69, 82, 128, 77, 73, 78, 73, 77, 65, 128, - 77, 73, 78, 73, 68, 73, 83, 67, 128, 77, 73, 78, 73, 66, 85, 83, 128, 77, - 73, 77, 69, 128, 77, 73, 77, 128, 77, 73, 76, 76, 73, 79, 78, 211, 77, - 73, 76, 76, 69, 84, 128, 77, 73, 76, 76, 197, 77, 73, 76, 204, 77, 73, - 76, 75, 217, 77, 73, 76, 128, 77, 73, 75, 85, 82, 79, 78, 128, 77, 73, - 75, 82, 79, 206, 77, 73, 75, 82, 73, 128, 77, 73, 73, 78, 128, 77, 73, - 73, 128, 77, 73, 199, 77, 73, 69, 88, 128, 77, 73, 69, 85, 77, 45, 84, - 73, 75, 69, 85, 84, 128, 77, 73, 69, 85, 77, 45, 83, 83, 65, 78, 71, 83, - 73, 79, 83, 128, 77, 73, 69, 85, 77, 45, 83, 83, 65, 78, 71, 78, 73, 69, - 85, 78, 128, 77, 73, 69, 85, 77, 45, 82, 73, 69, 85, 76, 128, 77, 73, 69, - 85, 77, 45, 80, 73, 69, 85, 80, 45, 83, 73, 79, 83, 128, 77, 73, 69, 85, - 77, 45, 80, 73, 69, 85, 80, 128, 77, 73, 69, 85, 77, 45, 80, 65, 78, 83, - 73, 79, 83, 128, 77, 73, 69, 85, 77, 45, 78, 73, 69, 85, 78, 128, 77, 73, - 69, 85, 77, 45, 67, 73, 69, 85, 67, 128, 77, 73, 69, 85, 77, 45, 67, 72, - 73, 69, 85, 67, 72, 128, 77, 73, 69, 85, 205, 77, 73, 69, 80, 128, 77, - 73, 69, 69, 128, 77, 73, 69, 128, 77, 73, 68, 76, 73, 78, 197, 77, 73, - 68, 68, 76, 69, 45, 87, 69, 76, 83, 200, 77, 73, 68, 68, 76, 197, 77, 73, + 193, 78, 65, 52, 128, 78, 65, 50, 128, 78, 65, 45, 50, 128, 78, 48, 52, + 50, 128, 78, 48, 52, 49, 128, 78, 48, 52, 48, 128, 78, 48, 51, 57, 128, + 78, 48, 51, 56, 128, 78, 48, 51, 55, 65, 128, 78, 48, 51, 55, 128, 78, + 48, 51, 54, 128, 78, 48, 51, 53, 65, 128, 78, 48, 51, 53, 128, 78, 48, + 51, 52, 65, 128, 78, 48, 51, 52, 128, 78, 48, 51, 51, 65, 128, 78, 48, + 51, 51, 128, 78, 48, 51, 50, 128, 78, 48, 51, 49, 128, 78, 48, 51, 48, + 128, 78, 48, 50, 57, 128, 78, 48, 50, 56, 128, 78, 48, 50, 55, 128, 78, + 48, 50, 54, 128, 78, 48, 50, 53, 65, 128, 78, 48, 50, 53, 128, 78, 48, + 50, 52, 128, 78, 48, 50, 51, 128, 78, 48, 50, 50, 128, 78, 48, 50, 49, + 128, 78, 48, 50, 48, 128, 78, 48, 49, 57, 128, 78, 48, 49, 56, 66, 128, + 78, 48, 49, 56, 65, 128, 78, 48, 49, 56, 128, 78, 48, 49, 55, 128, 78, + 48, 49, 54, 128, 78, 48, 49, 53, 128, 78, 48, 49, 52, 128, 78, 48, 49, + 51, 128, 78, 48, 49, 50, 128, 78, 48, 49, 49, 128, 78, 48, 49, 48, 128, + 78, 48, 48, 57, 128, 78, 48, 48, 56, 128, 78, 48, 48, 55, 128, 78, 48, + 48, 54, 128, 78, 48, 48, 53, 128, 78, 48, 48, 52, 128, 78, 48, 48, 51, + 128, 78, 48, 48, 50, 128, 78, 48, 48, 49, 128, 78, 45, 67, 82, 69, 197, + 78, 45, 65, 82, 217, 77, 89, 88, 128, 77, 89, 84, 128, 77, 89, 83, 76, + 73, 84, 69, 128, 77, 89, 80, 128, 77, 89, 65, 128, 77, 89, 193, 77, 89, + 128, 77, 217, 77, 87, 79, 79, 128, 77, 87, 79, 128, 77, 87, 73, 73, 128, + 77, 87, 73, 128, 77, 87, 69, 69, 128, 77, 87, 69, 128, 77, 87, 65, 65, + 128, 77, 87, 65, 128, 77, 87, 128, 77, 215, 77, 86, 83, 128, 77, 86, 79, + 80, 128, 77, 86, 73, 128, 77, 86, 69, 85, 65, 69, 78, 71, 65, 77, 128, + 77, 86, 128, 77, 214, 77, 85, 88, 128, 77, 85, 85, 83, 73, 75, 65, 84, + 79, 65, 78, 128, 77, 85, 85, 82, 68, 72, 65, 74, 193, 77, 85, 85, 128, + 77, 85, 84, 128, 77, 85, 83, 73, 67, 128, 77, 85, 83, 73, 195, 77, 85, + 83, 72, 82, 79, 79, 77, 128, 77, 85, 83, 72, 51, 128, 77, 85, 83, 72, + 179, 77, 85, 83, 72, 128, 77, 85, 83, 200, 77, 85, 83, 128, 77, 85, 82, + 88, 128, 77, 85, 82, 71, 85, 50, 128, 77, 85, 82, 69, 128, 77, 85, 82, + 68, 65, 128, 77, 85, 82, 68, 193, 77, 85, 82, 128, 77, 85, 81, 68, 65, + 77, 128, 77, 85, 80, 128, 77, 85, 79, 88, 128, 77, 85, 79, 84, 128, 77, + 85, 79, 80, 128, 77, 85, 79, 77, 65, 69, 128, 77, 85, 79, 128, 77, 85, + 78, 83, 85, 66, 128, 77, 85, 78, 65, 72, 128, 77, 85, 78, 128, 77, 85, + 76, 84, 73, 83, 69, 84, 128, 77, 85, 76, 84, 73, 83, 69, 212, 77, 85, 76, + 84, 73, 80, 76, 73, 67, 65, 84, 73, 79, 78, 128, 77, 85, 76, 84, 73, 80, + 76, 73, 67, 65, 84, 73, 79, 206, 77, 85, 76, 84, 73, 80, 76, 197, 77, 85, + 76, 84, 73, 79, 67, 85, 76, 65, 210, 77, 85, 76, 84, 73, 77, 65, 80, 128, + 77, 85, 76, 84, 201, 77, 85, 75, 80, 72, 82, 69, 78, 71, 128, 77, 85, 73, + 78, 128, 77, 85, 71, 83, 128, 77, 85, 71, 128, 77, 85, 199, 77, 85, 69, + 78, 128, 77, 85, 69, 128, 77, 85, 67, 72, 128, 77, 85, 67, 200, 77, 85, + 67, 65, 65, 68, 128, 77, 85, 65, 83, 128, 77, 85, 65, 78, 128, 77, 85, + 65, 69, 128, 77, 85, 45, 71, 65, 65, 72, 76, 65, 193, 77, 213, 77, 83, + 128, 77, 82, 207, 77, 80, 65, 128, 77, 79, 89, 65, 73, 128, 77, 79, 88, + 128, 77, 79, 86, 73, 197, 77, 79, 86, 69, 196, 77, 79, 85, 84, 72, 128, + 77, 79, 85, 84, 200, 77, 79, 85, 83, 69, 128, 77, 79, 85, 83, 197, 77, + 79, 85, 78, 84, 65, 73, 78, 83, 128, 77, 79, 85, 78, 84, 65, 73, 78, 128, + 77, 79, 85, 78, 84, 65, 73, 206, 77, 79, 85, 78, 212, 77, 79, 85, 78, 68, + 128, 77, 79, 85, 78, 196, 77, 79, 84, 79, 82, 87, 65, 89, 128, 77, 79, + 84, 79, 82, 67, 89, 67, 76, 69, 128, 77, 79, 84, 79, 210, 77, 79, 84, 72, + 69, 82, 128, 77, 79, 84, 128, 77, 79, 82, 84, 85, 85, 77, 128, 77, 79, + 82, 84, 65, 82, 128, 77, 79, 82, 80, 72, 79, 76, 79, 71, 73, 67, 65, 204, + 77, 79, 82, 78, 73, 78, 71, 128, 77, 79, 80, 128, 77, 79, 79, 83, 69, 45, + 67, 82, 69, 197, 77, 79, 79, 78, 128, 77, 79, 79, 206, 77, 79, 79, 77, + 80, 85, 81, 128, 77, 79, 79, 77, 69, 85, 84, 128, 77, 79, 79, 68, 128, + 77, 79, 79, 196, 77, 79, 79, 128, 77, 79, 78, 84, 73, 69, 69, 78, 128, + 77, 79, 78, 84, 72, 128, 77, 79, 78, 84, 200, 77, 79, 78, 83, 84, 69, 82, + 128, 77, 79, 78, 79, 83, 84, 65, 66, 76, 197, 77, 79, 78, 79, 83, 80, 65, + 67, 197, 77, 79, 78, 79, 82, 65, 73, 76, 128, 77, 79, 78, 79, 71, 82, 65, + 80, 200, 77, 79, 78, 79, 71, 82, 65, 77, 77, 79, 211, 77, 79, 78, 79, 71, + 82, 65, 205, 77, 79, 78, 79, 70, 79, 78, 73, 65, 83, 128, 77, 79, 78, 79, + 67, 85, 76, 65, 210, 77, 79, 78, 75, 69, 89, 128, 77, 79, 78, 75, 69, + 217, 77, 79, 78, 73, 128, 77, 79, 78, 71, 75, 69, 85, 65, 69, 81, 128, + 77, 79, 78, 69, 217, 77, 79, 78, 128, 77, 79, 206, 77, 79, 76, 128, 77, + 79, 72, 65, 77, 77, 65, 196, 77, 79, 68, 85, 76, 207, 77, 79, 68, 201, + 77, 79, 68, 69, 83, 84, 89, 128, 77, 79, 68, 69, 77, 128, 77, 79, 68, 69, + 76, 83, 128, 77, 79, 68, 69, 76, 128, 77, 79, 68, 69, 128, 77, 79, 66, + 73, 76, 197, 77, 79, 65, 128, 77, 207, 77, 78, 89, 65, 205, 77, 78, 65, + 83, 128, 77, 77, 83, 80, 128, 77, 77, 128, 77, 205, 77, 76, 65, 128, 77, + 76, 128, 77, 75, 80, 65, 82, 65, 209, 77, 73, 88, 128, 77, 73, 84, 128, + 77, 73, 83, 82, 65, 128, 77, 73, 82, 73, 66, 65, 65, 82, 85, 128, 77, 73, + 82, 73, 128, 77, 73, 82, 69, 68, 128, 77, 73, 80, 128, 77, 73, 78, 89, + 128, 77, 73, 78, 85, 83, 45, 79, 82, 45, 80, 76, 85, 211, 77, 73, 78, 85, + 83, 128, 77, 73, 78, 73, 83, 84, 69, 82, 128, 77, 73, 78, 73, 77, 73, 90, + 69, 128, 77, 73, 78, 73, 77, 65, 128, 77, 73, 78, 73, 68, 73, 83, 67, + 128, 77, 73, 78, 73, 66, 85, 83, 128, 77, 73, 77, 69, 128, 77, 73, 77, + 128, 77, 73, 76, 76, 73, 79, 78, 83, 128, 77, 73, 76, 76, 73, 79, 78, + 211, 77, 73, 76, 76, 69, 84, 128, 77, 73, 76, 76, 197, 77, 73, 76, 204, + 77, 73, 76, 75, 217, 77, 73, 76, 73, 84, 65, 82, 217, 77, 73, 76, 128, + 77, 73, 75, 85, 82, 79, 78, 128, 77, 73, 75, 82, 79, 206, 77, 73, 75, 82, + 73, 128, 77, 73, 73, 78, 128, 77, 73, 73, 128, 77, 73, 199, 77, 73, 69, + 88, 128, 77, 73, 69, 85, 77, 45, 84, 73, 75, 69, 85, 84, 128, 77, 73, 69, + 85, 77, 45, 83, 83, 65, 78, 71, 83, 73, 79, 83, 128, 77, 73, 69, 85, 77, + 45, 83, 83, 65, 78, 71, 78, 73, 69, 85, 78, 128, 77, 73, 69, 85, 77, 45, + 82, 73, 69, 85, 76, 128, 77, 73, 69, 85, 77, 45, 80, 73, 69, 85, 80, 45, + 83, 73, 79, 83, 128, 77, 73, 69, 85, 77, 45, 80, 73, 69, 85, 80, 128, 77, + 73, 69, 85, 77, 45, 80, 65, 78, 83, 73, 79, 83, 128, 77, 73, 69, 85, 77, + 45, 78, 73, 69, 85, 78, 128, 77, 73, 69, 85, 77, 45, 67, 73, 69, 85, 67, + 128, 77, 73, 69, 85, 77, 45, 67, 72, 73, 69, 85, 67, 72, 128, 77, 73, 69, + 85, 205, 77, 73, 69, 80, 128, 77, 73, 69, 69, 128, 77, 73, 69, 128, 77, + 73, 68, 76, 73, 78, 197, 77, 73, 68, 68, 76, 69, 45, 87, 69, 76, 83, 200, + 77, 73, 68, 68, 76, 197, 77, 73, 68, 45, 76, 69, 86, 69, 204, 77, 73, 196, 77, 73, 67, 82, 79, 83, 67, 79, 80, 69, 128, 77, 73, 67, 82, 79, 80, 72, 79, 78, 69, 128, 77, 73, 67, 82, 207, 77, 73, 67, 210, 77, 72, 90, 128, 77, 72, 65, 128, 77, 72, 128, 77, 71, 85, 88, 128, 77, 71, 85, 84, @@ -2018,161 +2115,219 @@ static unsigned char lexicon[] = { 77, 69, 82, 79, 73, 84, 73, 195, 77, 69, 82, 75, 72, 65, 128, 77, 69, 82, 75, 72, 193, 77, 69, 82, 73, 68, 73, 65, 78, 83, 128, 77, 69, 82, 73, 128, 77, 69, 82, 71, 69, 128, 77, 69, 82, 67, 85, 82, 89, 128, 77, 69, - 82, 67, 85, 82, 217, 77, 69, 78, 68, 85, 84, 128, 77, 69, 78, 128, 77, - 69, 77, 79, 128, 77, 69, 77, 66, 69, 82, 83, 72, 73, 80, 128, 77, 69, 77, - 66, 69, 82, 128, 77, 69, 77, 66, 69, 210, 77, 69, 77, 45, 81, 79, 80, 72, - 128, 77, 69, 77, 128, 77, 69, 205, 77, 69, 76, 79, 68, 73, 195, 77, 69, - 76, 73, 75, 128, 77, 69, 73, 90, 73, 128, 77, 69, 71, 65, 84, 79, 78, - 128, 77, 69, 71, 65, 80, 72, 79, 78, 69, 128, 77, 69, 71, 65, 76, 73, - 128, 77, 69, 69, 84, 79, 82, 85, 128, 77, 69, 69, 84, 128, 77, 69, 69, - 77, 85, 128, 77, 69, 69, 77, 128, 77, 69, 69, 69, 69, 128, 77, 69, 68, + 82, 67, 85, 82, 217, 77, 69, 78, 79, 69, 128, 77, 69, 78, 68, 85, 84, + 128, 77, 69, 78, 128, 77, 69, 77, 79, 128, 77, 69, 77, 66, 69, 82, 83, + 72, 73, 80, 128, 77, 69, 77, 66, 69, 82, 128, 77, 69, 77, 66, 69, 210, + 77, 69, 77, 45, 81, 79, 80, 72, 128, 77, 69, 77, 128, 77, 69, 205, 77, + 69, 76, 79, 68, 73, 195, 77, 69, 76, 73, 75, 128, 77, 69, 73, 90, 73, + 128, 77, 69, 71, 65, 84, 79, 78, 128, 77, 69, 71, 65, 80, 72, 79, 78, 69, + 128, 77, 69, 71, 65, 76, 73, 128, 77, 69, 69, 84, 79, 82, 85, 128, 77, + 69, 69, 84, 69, 201, 77, 69, 69, 84, 128, 77, 69, 69, 77, 85, 128, 77, + 69, 69, 77, 128, 77, 69, 69, 202, 77, 69, 69, 69, 69, 128, 77, 69, 68, 73, 85, 77, 128, 77, 69, 68, 73, 85, 205, 77, 69, 68, 73, 67, 73, 78, 69, - 128, 77, 69, 68, 73, 67, 65, 204, 77, 69, 65, 84, 128, 77, 69, 65, 212, - 77, 69, 65, 83, 85, 82, 69, 196, 77, 69, 65, 83, 85, 82, 69, 128, 77, 69, - 65, 83, 85, 82, 197, 77, 68, 85, 206, 77, 196, 77, 67, 72, 213, 77, 67, - 72, 65, 206, 77, 195, 77, 66, 85, 79, 81, 128, 77, 66, 85, 79, 128, 77, - 66, 85, 69, 128, 77, 66, 85, 65, 69, 77, 128, 77, 66, 85, 65, 69, 128, - 77, 66, 79, 79, 128, 77, 66, 79, 128, 77, 66, 73, 84, 128, 77, 66, 73, - 212, 77, 66, 73, 82, 73, 69, 69, 78, 128, 77, 66, 73, 128, 77, 66, 69, - 85, 88, 128, 77, 66, 69, 85, 82, 73, 128, 77, 66, 69, 85, 77, 128, 77, - 66, 69, 82, 65, 69, 128, 77, 66, 69, 78, 128, 77, 66, 69, 69, 75, 69, 69, - 84, 128, 77, 66, 69, 69, 128, 77, 66, 69, 128, 77, 66, 65, 81, 128, 77, - 66, 65, 78, 89, 73, 128, 77, 66, 65, 65, 82, 65, 69, 128, 77, 66, 65, 65, - 75, 69, 84, 128, 77, 66, 65, 65, 128, 77, 66, 65, 193, 77, 66, 193, 77, - 66, 52, 128, 77, 66, 51, 128, 77, 66, 50, 128, 77, 66, 128, 77, 194, 77, - 65, 89, 65, 78, 78, 65, 128, 77, 65, 89, 128, 77, 65, 88, 73, 77, 65, - 128, 77, 65, 88, 128, 77, 65, 85, 128, 77, 65, 84, 84, 79, 67, 75, 128, - 77, 65, 84, 82, 73, 88, 128, 77, 65, 84, 69, 82, 73, 65, 76, 83, 128, 77, - 65, 84, 128, 77, 65, 83, 213, 77, 65, 83, 83, 73, 78, 71, 128, 77, 65, - 83, 83, 65, 71, 69, 128, 77, 65, 83, 79, 82, 193, 77, 65, 83, 75, 128, - 77, 65, 83, 72, 70, 65, 65, 84, 128, 77, 65, 83, 72, 50, 128, 77, 65, 83, - 67, 85, 76, 73, 78, 197, 77, 65, 82, 89, 128, 77, 65, 82, 85, 75, 85, - 128, 77, 65, 82, 84, 89, 82, 73, 193, 77, 65, 82, 82, 89, 73, 78, 199, - 77, 65, 82, 82, 73, 65, 71, 197, 77, 65, 82, 75, 69, 82, 128, 77, 65, 82, - 75, 45, 52, 128, 77, 65, 82, 75, 45, 51, 128, 77, 65, 82, 75, 45, 50, - 128, 77, 65, 82, 75, 45, 49, 128, 77, 65, 82, 69, 128, 77, 65, 82, 67, - 72, 128, 77, 65, 82, 67, 65, 84, 79, 45, 83, 84, 65, 67, 67, 65, 84, 79, - 128, 77, 65, 82, 67, 65, 84, 79, 128, 77, 65, 82, 67, 65, 83, 73, 84, 69, - 128, 77, 65, 82, 66, 85, 84, 65, 128, 77, 65, 82, 66, 85, 84, 193, 77, - 65, 82, 128, 77, 65, 81, 65, 70, 128, 77, 65, 81, 128, 77, 65, 80, 76, - 197, 77, 65, 80, 73, 81, 128, 77, 65, 208, 77, 65, 79, 128, 77, 65, 78, - 83, 89, 79, 78, 128, 77, 65, 78, 83, 85, 65, 69, 128, 77, 65, 78, 78, 65, - 218, 77, 65, 78, 78, 65, 128, 77, 65, 78, 71, 65, 76, 65, 77, 128, 77, - 65, 78, 68, 65, 73, 76, 73, 78, 199, 77, 65, 78, 68, 65, 73, 195, 77, 65, - 78, 67, 72, 213, 77, 65, 78, 65, 67, 76, 69, 83, 128, 77, 65, 76, 84, 69, - 83, 197, 77, 65, 76, 69, 69, 82, 73, 128, 77, 65, 76, 69, 128, 77, 65, - 76, 197, 77, 65, 76, 65, 75, 79, 206, 77, 65, 75, 83, 85, 82, 65, 128, - 77, 65, 75, 83, 85, 82, 193, 77, 65, 73, 90, 69, 128, 77, 65, 73, 89, 65, - 77, 79, 75, 128, 77, 65, 73, 84, 65, 73, 75, 72, 85, 128, 77, 65, 73, 82, - 85, 128, 77, 65, 73, 77, 85, 65, 78, 128, 77, 65, 73, 77, 65, 76, 65, 73, + 128, 77, 69, 68, 73, 67, 65, 204, 77, 69, 68, 65, 76, 128, 77, 69, 65, + 84, 128, 77, 69, 65, 212, 77, 69, 65, 83, 85, 82, 69, 196, 77, 69, 65, + 83, 85, 82, 69, 128, 77, 69, 65, 83, 85, 82, 197, 77, 68, 85, 206, 77, + 196, 77, 67, 72, 213, 77, 67, 72, 65, 206, 77, 195, 77, 66, 85, 85, 128, + 77, 66, 85, 79, 81, 128, 77, 66, 85, 79, 128, 77, 66, 85, 69, 128, 77, + 66, 85, 65, 69, 77, 128, 77, 66, 85, 65, 69, 128, 77, 66, 79, 79, 128, + 77, 66, 79, 128, 77, 66, 73, 84, 128, 77, 66, 73, 212, 77, 66, 73, 82, + 73, 69, 69, 78, 128, 77, 66, 73, 128, 77, 66, 69, 85, 88, 128, 77, 66, + 69, 85, 82, 73, 128, 77, 66, 69, 85, 77, 128, 77, 66, 69, 82, 65, 69, + 128, 77, 66, 69, 78, 128, 77, 66, 69, 69, 75, 69, 69, 84, 128, 77, 66, + 69, 69, 128, 77, 66, 69, 128, 77, 66, 65, 81, 128, 77, 66, 65, 78, 89, + 73, 128, 77, 66, 65, 65, 82, 65, 69, 128, 77, 66, 65, 65, 75, 69, 84, + 128, 77, 66, 65, 65, 128, 77, 66, 65, 193, 77, 66, 193, 77, 66, 52, 128, + 77, 66, 51, 128, 77, 66, 50, 128, 77, 66, 128, 77, 194, 77, 65, 89, 69, + 203, 77, 65, 89, 65, 78, 78, 65, 128, 77, 65, 89, 128, 77, 65, 88, 73, + 77, 73, 90, 69, 128, 77, 65, 88, 73, 77, 65, 128, 77, 65, 88, 128, 77, + 65, 85, 128, 77, 65, 84, 84, 79, 67, 75, 128, 77, 65, 84, 82, 73, 88, + 128, 77, 65, 84, 69, 82, 73, 65, 76, 83, 128, 77, 65, 84, 128, 77, 65, + 83, 213, 77, 65, 83, 83, 73, 78, 71, 128, 77, 65, 83, 83, 65, 71, 69, + 128, 77, 65, 83, 79, 82, 193, 77, 65, 83, 75, 128, 77, 65, 83, 72, 70, + 65, 65, 84, 128, 77, 65, 83, 72, 50, 128, 77, 65, 83, 67, 85, 76, 73, 78, + 197, 77, 65, 82, 89, 128, 77, 65, 82, 87, 65, 82, 201, 77, 65, 82, 85, + 75, 85, 128, 77, 65, 82, 84, 89, 82, 73, 193, 77, 65, 82, 82, 89, 73, 78, + 199, 77, 65, 82, 82, 73, 65, 71, 197, 77, 65, 82, 75, 211, 77, 65, 82, + 75, 69, 82, 128, 77, 65, 82, 75, 45, 52, 128, 77, 65, 82, 75, 45, 51, + 128, 77, 65, 82, 75, 45, 50, 128, 77, 65, 82, 75, 45, 49, 128, 77, 65, + 82, 69, 128, 77, 65, 82, 67, 72, 128, 77, 65, 82, 67, 65, 84, 79, 45, 83, + 84, 65, 67, 67, 65, 84, 79, 128, 77, 65, 82, 67, 65, 84, 79, 128, 77, 65, + 82, 67, 65, 83, 73, 84, 69, 128, 77, 65, 82, 66, 85, 84, 65, 128, 77, 65, + 82, 66, 85, 84, 193, 77, 65, 82, 128, 77, 65, 81, 65, 70, 128, 77, 65, + 81, 128, 77, 65, 80, 76, 197, 77, 65, 80, 73, 81, 128, 77, 65, 208, 77, + 65, 79, 128, 77, 65, 78, 84, 69, 76, 80, 73, 69, 67, 197, 77, 65, 78, 83, + 89, 79, 78, 128, 77, 65, 78, 83, 85, 65, 69, 128, 77, 65, 78, 78, 65, + 218, 77, 65, 78, 78, 65, 128, 77, 65, 78, 73, 67, 72, 65, 69, 65, 206, + 77, 65, 78, 71, 65, 76, 65, 77, 128, 77, 65, 78, 68, 65, 73, 76, 73, 78, + 199, 77, 65, 78, 68, 65, 73, 195, 77, 65, 78, 67, 72, 213, 77, 65, 78, + 65, 212, 77, 65, 78, 65, 67, 76, 69, 83, 128, 77, 65, 76, 84, 69, 83, + 197, 77, 65, 76, 69, 69, 82, 73, 128, 77, 65, 76, 69, 128, 77, 65, 76, + 197, 77, 65, 76, 65, 75, 79, 206, 77, 65, 75, 83, 85, 82, 65, 128, 77, + 65, 75, 83, 85, 82, 193, 77, 65, 73, 90, 69, 128, 77, 65, 73, 89, 65, 77, + 79, 75, 128, 77, 65, 73, 84, 65, 73, 75, 72, 85, 128, 77, 65, 73, 82, 85, + 128, 77, 65, 73, 77, 85, 65, 78, 128, 77, 65, 73, 77, 65, 76, 65, 73, 128, 77, 65, 73, 76, 66, 79, 216, 77, 65, 73, 75, 85, 82, 79, 128, 77, 65, 73, 68, 69, 78, 128, 77, 65, 73, 128, 77, 65, 72, 74, 79, 78, 199, 77, 65, 72, 72, 65, 128, 77, 65, 72, 65, 80, 82, 65, 78, 65, 128, 77, 65, - 72, 65, 80, 65, 75, 72, 128, 77, 65, 72, 65, 65, 80, 82, 65, 65, 78, 193, - 77, 65, 72, 128, 77, 65, 71, 78, 73, 70, 89, 73, 78, 199, 77, 65, 69, 83, - 73, 128, 77, 65, 69, 78, 89, 73, 128, 77, 65, 69, 78, 74, 69, 84, 128, - 77, 65, 69, 77, 86, 69, 85, 88, 128, 77, 65, 69, 77, 75, 80, 69, 78, 128, - 77, 65, 69, 77, 71, 66, 73, 69, 69, 128, 77, 65, 69, 77, 66, 71, 66, 73, - 69, 69, 128, 77, 65, 69, 77, 66, 65, 128, 77, 65, 69, 77, 128, 77, 65, - 69, 76, 69, 69, 128, 77, 65, 69, 75, 69, 85, 80, 128, 77, 65, 68, 89, 65, - 128, 77, 65, 68, 85, 128, 77, 65, 68, 68, 65, 200, 77, 65, 68, 68, 65, - 128, 77, 65, 68, 68, 193, 77, 65, 67, 82, 79, 78, 45, 71, 82, 65, 86, 69, - 128, 77, 65, 67, 82, 79, 78, 45, 66, 82, 69, 86, 69, 128, 77, 65, 67, 82, - 79, 78, 45, 65, 67, 85, 84, 69, 128, 77, 65, 67, 82, 79, 78, 128, 77, 65, - 67, 82, 79, 206, 77, 65, 67, 72, 73, 78, 69, 128, 77, 65, 65, 89, 89, 65, - 65, 128, 77, 65, 65, 73, 128, 77, 65, 65, 128, 77, 65, 50, 128, 77, 48, - 52, 52, 128, 77, 48, 52, 51, 128, 77, 48, 52, 50, 128, 77, 48, 52, 49, - 128, 77, 48, 52, 48, 65, 128, 77, 48, 52, 48, 128, 77, 48, 51, 57, 128, - 77, 48, 51, 56, 128, 77, 48, 51, 55, 128, 77, 48, 51, 54, 128, 77, 48, - 51, 53, 128, 77, 48, 51, 52, 128, 77, 48, 51, 51, 66, 128, 77, 48, 51, - 51, 65, 128, 77, 48, 51, 51, 128, 77, 48, 51, 50, 128, 77, 48, 51, 49, - 65, 128, 77, 48, 51, 49, 128, 77, 48, 51, 48, 128, 77, 48, 50, 57, 128, - 77, 48, 50, 56, 65, 128, 77, 48, 50, 56, 128, 77, 48, 50, 55, 128, 77, - 48, 50, 54, 128, 77, 48, 50, 53, 128, 77, 48, 50, 52, 65, 128, 77, 48, - 50, 52, 128, 77, 48, 50, 51, 128, 77, 48, 50, 50, 65, 128, 77, 48, 50, - 50, 128, 77, 48, 50, 49, 128, 77, 48, 50, 48, 128, 77, 48, 49, 57, 128, - 77, 48, 49, 56, 128, 77, 48, 49, 55, 65, 128, 77, 48, 49, 55, 128, 77, - 48, 49, 54, 65, 128, 77, 48, 49, 54, 128, 77, 48, 49, 53, 65, 128, 77, - 48, 49, 53, 128, 77, 48, 49, 52, 128, 77, 48, 49, 51, 128, 77, 48, 49, + 72, 65, 80, 65, 75, 72, 128, 77, 65, 72, 65, 74, 65, 78, 201, 77, 65, 72, + 65, 65, 80, 82, 65, 65, 78, 193, 77, 65, 72, 128, 77, 65, 71, 78, 73, 70, + 89, 73, 78, 199, 77, 65, 69, 83, 73, 128, 77, 65, 69, 78, 89, 73, 128, + 77, 65, 69, 78, 74, 69, 84, 128, 77, 65, 69, 77, 86, 69, 85, 88, 128, 77, + 65, 69, 77, 75, 80, 69, 78, 128, 77, 65, 69, 77, 71, 66, 73, 69, 69, 128, + 77, 65, 69, 77, 66, 71, 66, 73, 69, 69, 128, 77, 65, 69, 77, 66, 65, 128, + 77, 65, 69, 77, 128, 77, 65, 69, 76, 69, 69, 128, 77, 65, 69, 75, 69, 85, + 80, 128, 77, 65, 68, 89, 65, 128, 77, 65, 68, 85, 128, 77, 65, 68, 68, + 65, 200, 77, 65, 68, 68, 65, 128, 77, 65, 68, 68, 193, 77, 65, 67, 82, + 79, 78, 45, 71, 82, 65, 86, 69, 128, 77, 65, 67, 82, 79, 78, 45, 66, 82, + 69, 86, 69, 128, 77, 65, 67, 82, 79, 78, 45, 65, 67, 85, 84, 69, 128, 77, + 65, 67, 82, 79, 78, 128, 77, 65, 67, 82, 79, 206, 77, 65, 67, 72, 73, 78, + 69, 128, 77, 65, 65, 89, 89, 65, 65, 128, 77, 65, 65, 73, 128, 77, 65, + 65, 128, 77, 65, 50, 128, 77, 49, 57, 183, 77, 49, 57, 182, 77, 49, 57, + 181, 77, 49, 57, 180, 77, 49, 57, 179, 77, 49, 57, 178, 77, 49, 57, 177, + 77, 49, 57, 176, 77, 49, 56, 185, 77, 49, 56, 184, 77, 49, 56, 183, 77, + 49, 56, 182, 77, 49, 56, 181, 77, 49, 56, 180, 77, 49, 56, 179, 77, 49, + 56, 178, 77, 49, 56, 177, 77, 49, 56, 176, 77, 49, 55, 185, 77, 49, 55, + 184, 77, 49, 55, 183, 77, 49, 55, 182, 77, 49, 55, 181, 77, 49, 55, 180, + 77, 49, 55, 179, 77, 49, 55, 178, 77, 49, 55, 177, 77, 49, 55, 176, 77, + 49, 54, 185, 77, 49, 54, 184, 77, 49, 54, 183, 77, 49, 54, 182, 77, 49, + 54, 181, 77, 49, 54, 180, 77, 49, 54, 179, 77, 49, 54, 178, 77, 49, 54, + 177, 77, 49, 54, 176, 77, 49, 53, 185, 77, 49, 53, 184, 77, 49, 53, 183, + 77, 49, 53, 182, 77, 49, 53, 181, 77, 49, 53, 180, 77, 49, 53, 179, 77, + 49, 53, 178, 77, 49, 53, 177, 77, 49, 53, 176, 77, 49, 52, 185, 77, 49, + 52, 184, 77, 49, 52, 183, 77, 49, 52, 182, 77, 49, 52, 181, 77, 49, 52, + 180, 77, 49, 52, 179, 77, 49, 52, 178, 77, 49, 52, 177, 77, 49, 52, 176, + 77, 49, 51, 185, 77, 49, 51, 184, 77, 49, 51, 183, 77, 49, 51, 182, 77, + 49, 51, 181, 77, 49, 51, 180, 77, 49, 51, 179, 77, 49, 51, 178, 77, 49, + 51, 177, 77, 49, 51, 176, 77, 49, 50, 185, 77, 49, 50, 184, 77, 49, 50, + 183, 77, 49, 50, 182, 77, 49, 50, 181, 77, 49, 50, 180, 77, 49, 50, 179, + 77, 49, 50, 178, 77, 49, 50, 177, 77, 49, 50, 176, 77, 49, 49, 185, 77, + 49, 49, 184, 77, 49, 49, 183, 77, 49, 49, 182, 77, 49, 49, 181, 77, 49, + 49, 180, 77, 49, 49, 179, 77, 49, 49, 178, 77, 49, 49, 177, 77, 49, 49, + 176, 77, 49, 48, 185, 77, 49, 48, 184, 77, 49, 48, 183, 77, 49, 48, 182, + 77, 49, 48, 181, 77, 49, 48, 180, 77, 49, 48, 179, 77, 49, 48, 178, 77, + 49, 48, 177, 77, 49, 48, 176, 77, 48, 57, 185, 77, 48, 57, 184, 77, 48, + 57, 183, 77, 48, 57, 182, 77, 48, 57, 181, 77, 48, 57, 180, 77, 48, 57, + 179, 77, 48, 57, 178, 77, 48, 57, 177, 77, 48, 57, 176, 77, 48, 56, 185, + 77, 48, 56, 184, 77, 48, 56, 183, 77, 48, 56, 182, 77, 48, 56, 181, 77, + 48, 56, 180, 77, 48, 56, 179, 77, 48, 56, 178, 77, 48, 56, 177, 77, 48, + 56, 176, 77, 48, 55, 185, 77, 48, 55, 184, 77, 48, 55, 183, 77, 48, 55, + 182, 77, 48, 55, 181, 77, 48, 55, 180, 77, 48, 55, 179, 77, 48, 55, 178, + 77, 48, 55, 177, 77, 48, 55, 176, 77, 48, 54, 185, 77, 48, 54, 184, 77, + 48, 54, 183, 77, 48, 54, 182, 77, 48, 54, 181, 77, 48, 54, 180, 77, 48, + 54, 179, 77, 48, 54, 178, 77, 48, 54, 177, 77, 48, 54, 176, 77, 48, 53, + 185, 77, 48, 53, 184, 77, 48, 53, 183, 77, 48, 53, 182, 77, 48, 53, 181, + 77, 48, 53, 180, 77, 48, 53, 179, 77, 48, 53, 178, 77, 48, 53, 177, 77, + 48, 53, 176, 77, 48, 52, 185, 77, 48, 52, 184, 77, 48, 52, 183, 77, 48, + 52, 182, 77, 48, 52, 181, 77, 48, 52, 52, 128, 77, 48, 52, 180, 77, 48, + 52, 51, 128, 77, 48, 52, 179, 77, 48, 52, 50, 128, 77, 48, 52, 178, 77, + 48, 52, 49, 128, 77, 48, 52, 177, 77, 48, 52, 48, 65, 128, 77, 48, 52, + 48, 128, 77, 48, 52, 176, 77, 48, 51, 57, 128, 77, 48, 51, 185, 77, 48, + 51, 56, 128, 77, 48, 51, 184, 77, 48, 51, 55, 128, 77, 48, 51, 183, 77, + 48, 51, 54, 128, 77, 48, 51, 182, 77, 48, 51, 53, 128, 77, 48, 51, 181, + 77, 48, 51, 52, 128, 77, 48, 51, 180, 77, 48, 51, 51, 66, 128, 77, 48, + 51, 51, 65, 128, 77, 48, 51, 51, 128, 77, 48, 51, 179, 77, 48, 51, 50, + 128, 77, 48, 51, 178, 77, 48, 51, 49, 65, 128, 77, 48, 51, 49, 128, 77, + 48, 51, 177, 77, 48, 51, 48, 128, 77, 48, 51, 176, 77, 48, 50, 57, 128, + 77, 48, 50, 185, 77, 48, 50, 56, 65, 128, 77, 48, 50, 56, 128, 77, 48, + 50, 184, 77, 48, 50, 55, 128, 77, 48, 50, 183, 77, 48, 50, 54, 128, 77, + 48, 50, 182, 77, 48, 50, 53, 128, 77, 48, 50, 181, 77, 48, 50, 52, 65, + 128, 77, 48, 50, 52, 128, 77, 48, 50, 180, 77, 48, 50, 51, 128, 77, 48, + 50, 179, 77, 48, 50, 50, 65, 128, 77, 48, 50, 50, 128, 77, 48, 50, 178, + 77, 48, 50, 49, 128, 77, 48, 50, 177, 77, 48, 50, 48, 128, 77, 48, 50, + 176, 77, 48, 49, 57, 128, 77, 48, 49, 185, 77, 48, 49, 56, 128, 77, 48, + 49, 184, 77, 48, 49, 55, 65, 128, 77, 48, 49, 55, 128, 77, 48, 49, 183, + 77, 48, 49, 54, 65, 128, 77, 48, 49, 54, 128, 77, 48, 49, 182, 77, 48, + 49, 53, 65, 128, 77, 48, 49, 53, 128, 77, 48, 49, 181, 77, 48, 49, 52, + 128, 77, 48, 49, 180, 77, 48, 49, 51, 128, 77, 48, 49, 179, 77, 48, 49, 50, 72, 128, 77, 48, 49, 50, 71, 128, 77, 48, 49, 50, 70, 128, 77, 48, 49, 50, 69, 128, 77, 48, 49, 50, 68, 128, 77, 48, 49, 50, 67, 128, 77, 48, 49, 50, 66, 128, 77, 48, 49, 50, 65, 128, 77, 48, 49, 50, 128, 77, - 48, 49, 49, 128, 77, 48, 49, 48, 65, 128, 77, 48, 49, 48, 128, 77, 48, - 48, 57, 128, 77, 48, 48, 56, 128, 77, 48, 48, 55, 128, 77, 48, 48, 54, - 128, 77, 48, 48, 53, 128, 77, 48, 48, 52, 128, 77, 48, 48, 51, 65, 128, - 77, 48, 48, 51, 128, 77, 48, 48, 50, 128, 77, 48, 48, 49, 66, 128, 77, - 48, 48, 49, 65, 128, 77, 48, 48, 49, 128, 76, 218, 76, 89, 89, 128, 76, - 89, 88, 128, 76, 89, 84, 128, 76, 89, 82, 88, 128, 76, 89, 82, 128, 76, - 89, 80, 128, 76, 89, 68, 73, 65, 206, 76, 89, 67, 73, 65, 206, 76, 88, - 128, 76, 87, 79, 79, 128, 76, 87, 79, 128, 76, 87, 73, 73, 128, 76, 87, - 73, 128, 76, 87, 69, 128, 76, 87, 65, 65, 128, 76, 87, 65, 128, 76, 85, - 88, 128, 76, 85, 85, 128, 76, 85, 84, 128, 76, 85, 82, 88, 128, 76, 85, - 80, 128, 76, 85, 79, 88, 128, 76, 85, 79, 84, 128, 76, 85, 79, 80, 128, - 76, 85, 79, 128, 76, 85, 78, 71, 83, 73, 128, 76, 85, 78, 65, 84, 197, - 76, 85, 205, 76, 85, 76, 128, 76, 85, 73, 83, 128, 76, 85, 72, 85, 82, - 128, 76, 85, 72, 128, 76, 85, 71, 71, 65, 71, 69, 128, 76, 85, 71, 65, - 76, 128, 76, 85, 71, 65, 204, 76, 85, 69, 128, 76, 85, 65, 69, 80, 128, - 76, 85, 51, 128, 76, 85, 50, 128, 76, 85, 178, 76, 82, 79, 128, 76, 82, - 77, 128, 76, 82, 73, 128, 76, 82, 69, 128, 76, 79, 90, 69, 78, 71, 69, - 128, 76, 79, 90, 69, 78, 71, 197, 76, 79, 88, 128, 76, 79, 87, 69, 82, - 69, 196, 76, 79, 87, 69, 210, 76, 79, 87, 45, 185, 76, 79, 86, 197, 76, - 79, 85, 82, 69, 128, 76, 79, 85, 68, 83, 80, 69, 65, 75, 69, 82, 128, 76, - 79, 85, 68, 76, 217, 76, 79, 84, 85, 83, 128, 76, 79, 84, 128, 76, 79, - 82, 82, 89, 128, 76, 79, 82, 82, 65, 73, 78, 69, 128, 76, 79, 81, 128, - 76, 79, 80, 128, 76, 79, 79, 84, 128, 76, 79, 79, 80, 69, 196, 76, 79, - 79, 80, 128, 76, 79, 79, 208, 76, 79, 79, 78, 128, 76, 79, 79, 203, 76, - 79, 79, 128, 76, 79, 78, 83, 85, 77, 128, 76, 79, 78, 71, 65, 128, 76, - 79, 78, 71, 193, 76, 79, 78, 71, 45, 66, 82, 65, 78, 67, 72, 45, 89, 82, - 128, 76, 79, 78, 71, 45, 66, 82, 65, 78, 67, 72, 45, 83, 79, 204, 76, 79, - 78, 71, 45, 66, 82, 65, 78, 67, 72, 45, 79, 83, 211, 76, 79, 78, 71, 45, - 66, 82, 65, 78, 67, 72, 45, 77, 65, 68, 210, 76, 79, 78, 71, 45, 66, 82, - 65, 78, 67, 72, 45, 72, 65, 71, 65, 76, 204, 76, 79, 78, 71, 45, 66, 82, - 65, 78, 67, 72, 45, 65, 210, 76, 79, 77, 77, 65, 69, 128, 76, 79, 77, - 128, 76, 79, 205, 76, 79, 76, 76, 73, 80, 79, 80, 128, 76, 79, 76, 76, - 128, 76, 79, 71, 210, 76, 79, 71, 79, 84, 89, 80, 197, 76, 79, 71, 79, - 71, 82, 65, 205, 76, 79, 71, 128, 76, 79, 68, 69, 83, 84, 79, 78, 69, - 128, 76, 79, 67, 79, 77, 79, 84, 73, 86, 69, 128, 76, 79, 67, 75, 73, 78, - 71, 45, 83, 72, 73, 70, 212, 76, 79, 67, 203, 76, 79, 67, 65, 84, 73, 86, - 69, 128, 76, 79, 67, 65, 84, 73, 79, 206, 76, 79, 65, 128, 76, 78, 128, - 76, 76, 85, 85, 128, 76, 76, 79, 79, 128, 76, 76, 76, 85, 85, 128, 76, - 76, 76, 85, 128, 76, 76, 76, 79, 79, 128, 76, 76, 76, 79, 128, 76, 76, - 76, 73, 73, 128, 76, 76, 76, 73, 128, 76, 76, 76, 69, 69, 128, 76, 76, - 76, 69, 128, 76, 76, 76, 65, 85, 128, 76, 76, 76, 65, 73, 128, 76, 76, - 76, 65, 65, 128, 76, 76, 76, 65, 128, 76, 76, 76, 128, 76, 74, 85, 68, - 73, 74, 69, 128, 76, 74, 69, 128, 76, 74, 128, 76, 73, 88, 128, 76, 73, - 87, 78, 128, 76, 73, 86, 82, 197, 76, 73, 84, 84, 76, 197, 76, 73, 84, - 84, 69, 210, 76, 73, 84, 82, 193, 76, 73, 84, 128, 76, 73, 83, 213, 76, - 73, 82, 193, 76, 73, 81, 85, 73, 196, 76, 73, 81, 128, 76, 73, 80, 83, - 84, 73, 67, 75, 128, 76, 73, 78, 75, 73, 78, 199, 76, 73, 78, 203, 76, - 73, 78, 71, 83, 65, 128, 76, 73, 78, 69, 83, 128, 76, 73, 78, 69, 211, - 76, 73, 78, 69, 45, 57, 128, 76, 73, 78, 69, 45, 55, 128, 76, 73, 78, 69, - 45, 51, 128, 76, 73, 78, 69, 45, 49, 128, 76, 73, 77, 77, 85, 52, 128, - 76, 73, 77, 77, 85, 50, 128, 76, 73, 77, 77, 85, 128, 76, 73, 77, 77, - 213, 76, 73, 77, 73, 84, 69, 196, 76, 73, 77, 73, 84, 65, 84, 73, 79, 78, - 128, 76, 73, 77, 73, 84, 128, 76, 73, 77, 69, 128, 76, 73, 77, 66, 213, - 76, 73, 76, 89, 128, 76, 73, 76, 73, 84, 72, 128, 76, 73, 76, 128, 76, - 73, 71, 72, 84, 78, 73, 78, 71, 128, 76, 73, 71, 72, 84, 72, 79, 85, 83, - 69, 128, 76, 73, 71, 72, 84, 128, 76, 73, 70, 69, 128, 76, 73, 69, 88, + 48, 49, 178, 77, 48, 49, 49, 128, 77, 48, 49, 177, 77, 48, 49, 48, 65, + 128, 77, 48, 49, 48, 128, 77, 48, 49, 176, 77, 48, 48, 57, 128, 77, 48, + 48, 185, 77, 48, 48, 56, 128, 77, 48, 48, 184, 77, 48, 48, 55, 128, 77, + 48, 48, 183, 77, 48, 48, 54, 128, 77, 48, 48, 182, 77, 48, 48, 53, 128, + 77, 48, 48, 181, 77, 48, 48, 52, 128, 77, 48, 48, 180, 77, 48, 48, 51, + 65, 128, 77, 48, 48, 51, 128, 77, 48, 48, 179, 77, 48, 48, 50, 128, 77, + 48, 48, 178, 77, 48, 48, 49, 66, 128, 77, 48, 48, 49, 65, 128, 77, 48, + 48, 49, 128, 77, 48, 48, 177, 76, 218, 76, 89, 89, 128, 76, 89, 88, 128, + 76, 89, 84, 128, 76, 89, 82, 88, 128, 76, 89, 82, 128, 76, 89, 80, 128, + 76, 89, 73, 84, 128, 76, 89, 68, 73, 65, 206, 76, 89, 67, 73, 65, 206, + 76, 88, 128, 76, 87, 79, 79, 128, 76, 87, 79, 128, 76, 87, 73, 73, 128, + 76, 87, 73, 128, 76, 87, 69, 128, 76, 87, 65, 65, 128, 76, 87, 65, 128, + 76, 85, 88, 128, 76, 85, 85, 128, 76, 85, 84, 128, 76, 85, 82, 88, 128, + 76, 85, 80, 128, 76, 85, 79, 88, 128, 76, 85, 79, 84, 128, 76, 85, 79, + 80, 128, 76, 85, 79, 128, 76, 85, 78, 71, 83, 73, 128, 76, 85, 78, 65, + 84, 197, 76, 85, 205, 76, 85, 76, 128, 76, 85, 73, 83, 128, 76, 85, 72, + 85, 82, 128, 76, 85, 72, 128, 76, 85, 71, 71, 65, 71, 69, 128, 76, 85, + 71, 65, 76, 128, 76, 85, 71, 65, 204, 76, 85, 69, 128, 76, 85, 197, 76, + 85, 66, 128, 76, 85, 65, 69, 80, 128, 76, 85, 51, 128, 76, 85, 50, 128, + 76, 85, 178, 76, 82, 79, 128, 76, 82, 77, 128, 76, 82, 73, 128, 76, 82, + 69, 128, 76, 79, 90, 69, 78, 71, 69, 128, 76, 79, 90, 69, 78, 71, 197, + 76, 79, 88, 128, 76, 79, 87, 69, 82, 69, 196, 76, 79, 87, 69, 210, 76, + 79, 87, 45, 82, 69, 86, 69, 82, 83, 69, 68, 45, 185, 76, 79, 87, 45, 77, + 73, 196, 76, 79, 87, 45, 70, 65, 76, 76, 73, 78, 199, 76, 79, 87, 45, + 185, 76, 79, 86, 197, 76, 79, 85, 82, 69, 128, 76, 79, 85, 68, 83, 80, + 69, 65, 75, 69, 82, 128, 76, 79, 85, 68, 76, 217, 76, 79, 84, 85, 83, + 128, 76, 79, 84, 128, 76, 79, 82, 82, 89, 128, 76, 79, 82, 82, 65, 73, + 78, 69, 128, 76, 79, 81, 128, 76, 79, 80, 128, 76, 79, 79, 84, 128, 76, + 79, 79, 80, 69, 196, 76, 79, 79, 80, 128, 76, 79, 79, 208, 76, 79, 79, + 78, 128, 76, 79, 79, 203, 76, 79, 79, 128, 76, 79, 78, 83, 85, 77, 128, + 76, 79, 78, 71, 65, 128, 76, 79, 78, 71, 193, 76, 79, 78, 71, 45, 66, 82, + 65, 78, 67, 72, 45, 89, 82, 128, 76, 79, 78, 71, 45, 66, 82, 65, 78, 67, + 72, 45, 83, 79, 204, 76, 79, 78, 71, 45, 66, 82, 65, 78, 67, 72, 45, 79, + 83, 211, 76, 79, 78, 71, 45, 66, 82, 65, 78, 67, 72, 45, 77, 65, 68, 210, + 76, 79, 78, 71, 45, 66, 82, 65, 78, 67, 72, 45, 72, 65, 71, 65, 76, 204, + 76, 79, 78, 71, 45, 66, 82, 65, 78, 67, 72, 45, 65, 210, 76, 79, 77, 77, + 65, 69, 128, 76, 79, 77, 128, 76, 79, 205, 76, 79, 76, 76, 73, 80, 79, + 80, 128, 76, 79, 76, 76, 128, 76, 79, 71, 210, 76, 79, 71, 79, 84, 89, + 80, 197, 76, 79, 71, 79, 71, 82, 65, 205, 76, 79, 71, 128, 76, 79, 68, + 69, 83, 84, 79, 78, 69, 128, 76, 79, 67, 79, 77, 79, 84, 73, 86, 69, 128, + 76, 79, 67, 75, 73, 78, 71, 45, 83, 72, 73, 70, 212, 76, 79, 67, 203, 76, + 79, 67, 65, 84, 73, 86, 69, 128, 76, 79, 67, 65, 84, 73, 79, 206, 76, 79, + 65, 128, 76, 78, 128, 76, 76, 85, 85, 128, 76, 76, 79, 79, 128, 76, 76, + 76, 85, 85, 128, 76, 76, 76, 85, 128, 76, 76, 76, 79, 79, 128, 76, 76, + 76, 79, 128, 76, 76, 76, 73, 73, 128, 76, 76, 76, 73, 128, 76, 76, 76, + 69, 69, 128, 76, 76, 76, 69, 128, 76, 76, 76, 65, 85, 128, 76, 76, 76, + 65, 73, 128, 76, 76, 76, 65, 65, 128, 76, 76, 76, 65, 128, 76, 76, 76, + 128, 76, 74, 85, 68, 73, 74, 69, 128, 76, 74, 69, 128, 76, 74, 128, 76, + 73, 88, 128, 76, 73, 87, 78, 128, 76, 73, 86, 82, 197, 76, 73, 84, 84, + 76, 197, 76, 73, 84, 84, 69, 210, 76, 73, 84, 82, 193, 76, 73, 84, 200, + 76, 73, 84, 128, 76, 73, 83, 213, 76, 73, 83, 128, 76, 73, 82, 193, 76, + 73, 81, 85, 73, 196, 76, 73, 81, 128, 76, 73, 80, 83, 84, 73, 67, 75, + 128, 76, 73, 78, 75, 73, 78, 199, 76, 73, 78, 75, 69, 196, 76, 73, 78, + 203, 76, 73, 78, 71, 83, 65, 128, 76, 73, 78, 69, 83, 128, 76, 73, 78, + 69, 211, 76, 73, 78, 69, 45, 57, 128, 76, 73, 78, 69, 45, 55, 128, 76, + 73, 78, 69, 45, 51, 128, 76, 73, 78, 69, 45, 49, 128, 76, 73, 77, 77, 85, + 52, 128, 76, 73, 77, 77, 85, 50, 128, 76, 73, 77, 77, 85, 128, 76, 73, + 77, 77, 213, 76, 73, 77, 73, 84, 69, 196, 76, 73, 77, 73, 84, 65, 84, 73, + 79, 78, 128, 76, 73, 77, 73, 84, 128, 76, 73, 77, 69, 128, 76, 73, 77, + 66, 213, 76, 73, 76, 89, 128, 76, 73, 76, 73, 84, 72, 128, 76, 73, 76, + 128, 76, 73, 71, 72, 84, 78, 73, 78, 71, 128, 76, 73, 71, 72, 84, 78, 73, + 78, 199, 76, 73, 71, 72, 84, 72, 79, 85, 83, 69, 128, 76, 73, 71, 72, 84, + 128, 76, 73, 70, 84, 69, 82, 128, 76, 73, 70, 69, 128, 76, 73, 69, 88, 128, 76, 73, 69, 84, 128, 76, 73, 69, 80, 128, 76, 73, 69, 69, 128, 76, 73, 69, 128, 76, 73, 68, 128, 76, 73, 66, 82, 65, 128, 76, 73, 66, 69, 82, 84, 89, 128, 76, 73, 65, 66, 73, 76, 73, 84, 217, 76, 72, 73, 73, 128, 76, 72, 65, 86, 73, 89, 65, 78, 73, 128, 76, 72, 65, 199, 76, 72, 65, 65, 128, 76, 72, 128, 76, 69, 90, 72, 128, 76, 69, 88, 128, 76, 69, - 86, 69, 204, 76, 69, 85, 77, 128, 76, 69, 85, 65, 69, 80, 128, 76, 69, - 85, 65, 69, 77, 128, 76, 69, 85, 128, 76, 69, 213, 76, 69, 84, 84, 69, - 82, 83, 128, 76, 69, 84, 84, 69, 82, 128, 76, 69, 212, 76, 69, 83, 83, - 69, 210, 76, 69, 83, 83, 45, 84, 72, 65, 78, 128, 76, 69, 83, 83, 45, 84, - 72, 65, 206, 76, 69, 80, 128, 76, 69, 79, 80, 65, 82, 68, 128, 76, 69, - 79, 128, 76, 69, 78, 84, 73, 67, 85, 76, 65, 210, 76, 69, 78, 73, 83, - 128, 76, 69, 78, 71, 84, 72, 69, 78, 69, 82, 128, 76, 69, 78, 71, 84, - 200, 76, 69, 78, 71, 65, 128, 76, 69, 78, 71, 193, 76, 69, 77, 79, 78, - 128, 76, 69, 77, 79, 73, 128, 76, 69, 76, 69, 84, 128, 76, 69, 76, 69, - 212, 76, 69, 203, 76, 69, 73, 77, 77, 65, 128, 76, 69, 73, 77, 77, 193, - 76, 69, 71, 83, 128, 76, 69, 71, 73, 79, 78, 128, 76, 69, 71, 69, 84, 79, - 211, 76, 69, 71, 128, 76, 69, 70, 84, 87, 65, 82, 68, 83, 128, 76, 69, - 70, 84, 45, 84, 79, 45, 82, 73, 71, 72, 212, 76, 69, 70, 84, 45, 83, 84, - 69, 205, 76, 69, 70, 84, 45, 83, 73, 68, 197, 76, 69, 70, 84, 45, 83, 72, - 65, 68, 69, 196, 76, 69, 70, 84, 45, 80, 79, 73, 78, 84, 73, 78, 199, 76, + 86, 73, 84, 65, 84, 73, 78, 71, 128, 76, 69, 85, 77, 128, 76, 69, 85, 65, + 69, 80, 128, 76, 69, 85, 65, 69, 77, 128, 76, 69, 85, 128, 76, 69, 213, + 76, 69, 84, 84, 69, 82, 83, 128, 76, 69, 84, 84, 69, 82, 128, 76, 69, + 212, 76, 69, 83, 83, 69, 210, 76, 69, 83, 83, 45, 84, 72, 65, 78, 128, + 76, 69, 83, 83, 45, 84, 72, 65, 206, 76, 69, 80, 67, 72, 193, 76, 69, 80, + 128, 76, 69, 79, 80, 65, 82, 68, 128, 76, 69, 79, 128, 76, 69, 78, 84, + 73, 67, 85, 76, 65, 210, 76, 69, 78, 73, 83, 128, 76, 69, 78, 73, 211, + 76, 69, 78, 71, 84, 72, 69, 78, 69, 82, 128, 76, 69, 78, 71, 84, 200, 76, + 69, 78, 71, 65, 128, 76, 69, 78, 71, 193, 76, 69, 77, 79, 78, 128, 76, + 69, 77, 79, 73, 128, 76, 69, 76, 69, 84, 128, 76, 69, 76, 69, 212, 76, + 69, 203, 76, 69, 73, 77, 77, 65, 128, 76, 69, 73, 77, 77, 193, 76, 69, + 73, 128, 76, 69, 71, 83, 128, 76, 69, 71, 73, 79, 78, 128, 76, 69, 71, + 69, 84, 79, 211, 76, 69, 71, 128, 76, 69, 199, 76, 69, 70, 84, 87, 65, + 82, 68, 83, 128, 76, 69, 70, 84, 45, 84, 79, 45, 82, 73, 71, 72, 212, 76, + 69, 70, 84, 45, 83, 84, 69, 205, 76, 69, 70, 84, 45, 83, 73, 68, 197, 76, + 69, 70, 84, 45, 83, 72, 65, 68, 69, 196, 76, 69, 70, 84, 45, 80, 79, 73, + 78, 84, 73, 78, 199, 76, 69, 70, 84, 45, 76, 73, 71, 72, 84, 69, 196, 76, 69, 70, 84, 45, 72, 65, 78, 68, 69, 196, 76, 69, 70, 84, 45, 72, 65, 78, 196, 76, 69, 70, 84, 45, 70, 65, 67, 73, 78, 199, 76, 69, 70, 84, 128, 76, 69, 69, 82, 65, 69, 87, 65, 128, 76, 69, 69, 75, 128, 76, 69, 69, 69, @@ -2181,137 +2336,151 @@ static unsigned char lexicon[] = { 69, 65, 68, 69, 82, 128, 76, 69, 65, 196, 76, 68, 65, 78, 128, 76, 68, 50, 128, 76, 67, 201, 76, 67, 197, 76, 65, 90, 217, 76, 65, 89, 65, 78, 78, 65, 128, 76, 65, 88, 128, 76, 65, 87, 128, 76, 65, 215, 76, 65, 85, - 76, 65, 128, 76, 65, 85, 75, 65, 218, 76, 65, 84, 73, 78, 65, 84, 197, - 76, 65, 84, 73, 75, 128, 76, 65, 84, 69, 82, 65, 204, 76, 65, 84, 197, - 76, 65, 83, 212, 76, 65, 82, 89, 78, 71, 69, 65, 204, 76, 65, 82, 71, 69, - 210, 76, 65, 82, 71, 69, 128, 76, 65, 82, 71, 197, 76, 65, 81, 128, 76, - 65, 80, 65, 81, 128, 76, 65, 80, 128, 76, 65, 78, 84, 69, 82, 78, 128, - 76, 65, 78, 71, 85, 65, 71, 197, 76, 65, 78, 69, 83, 128, 76, 65, 77, 69, - 68, 72, 128, 76, 65, 77, 69, 68, 128, 76, 65, 77, 69, 196, 76, 65, 77, - 69, 128, 76, 65, 77, 197, 76, 65, 77, 68, 65, 128, 76, 65, 77, 68, 128, - 76, 65, 77, 66, 68, 193, 76, 65, 77, 65, 68, 72, 128, 76, 65, 76, 128, - 76, 65, 204, 76, 65, 75, 75, 72, 65, 78, 71, 89, 65, 79, 128, 76, 65, 74, - 65, 78, 89, 65, 76, 65, 78, 128, 76, 65, 201, 76, 65, 72, 83, 72, 85, - 128, 76, 65, 72, 128, 76, 65, 71, 85, 83, 128, 76, 65, 71, 213, 76, 65, - 71, 65, 82, 128, 76, 65, 71, 65, 210, 76, 65, 71, 65, 66, 128, 76, 65, - 71, 65, 194, 76, 65, 69, 86, 128, 76, 65, 69, 128, 76, 65, 68, 217, 76, - 65, 67, 75, 128, 76, 65, 67, 65, 128, 76, 65, 66, 79, 85, 82, 73, 78, 71, - 128, 76, 65, 66, 79, 82, 128, 76, 65, 66, 73, 65, 76, 73, 90, 65, 84, 73, - 79, 206, 76, 65, 66, 73, 65, 204, 76, 65, 66, 65, 84, 128, 76, 65, 65, - 78, 65, 69, 128, 76, 65, 65, 78, 128, 76, 65, 65, 77, 85, 128, 76, 65, - 65, 77, 128, 76, 65, 65, 73, 128, 76, 48, 48, 54, 65, 128, 76, 48, 48, - 50, 65, 128, 76, 45, 84, 89, 80, 197, 76, 45, 83, 72, 65, 80, 69, 196, - 75, 89, 85, 82, 73, 73, 128, 75, 89, 85, 128, 75, 89, 79, 128, 75, 89, - 76, 73, 83, 77, 65, 128, 75, 89, 73, 128, 75, 89, 69, 128, 75, 89, 65, - 84, 72, 79, 211, 75, 89, 65, 65, 128, 75, 89, 65, 128, 75, 88, 87, 73, - 128, 75, 88, 87, 69, 69, 128, 75, 88, 87, 69, 128, 75, 88, 87, 65, 65, - 128, 75, 88, 87, 65, 128, 75, 88, 85, 128, 75, 88, 79, 128, 75, 88, 73, - 128, 75, 88, 69, 69, 128, 75, 88, 69, 128, 75, 88, 65, 65, 128, 75, 88, - 65, 128, 75, 87, 85, 51, 49, 56, 128, 75, 87, 79, 79, 128, 75, 87, 79, - 128, 75, 87, 73, 73, 128, 75, 87, 73, 128, 75, 87, 69, 69, 128, 75, 87, - 69, 128, 75, 87, 65, 89, 128, 75, 87, 65, 69, 84, 128, 75, 87, 65, 65, - 128, 75, 86, 65, 128, 75, 86, 128, 75, 85, 88, 128, 75, 85, 85, 72, 128, - 75, 85, 84, 128, 75, 85, 83, 77, 65, 128, 75, 85, 83, 72, 85, 50, 128, - 75, 85, 82, 88, 128, 75, 85, 82, 85, 90, 69, 73, 82, 79, 128, 75, 85, 82, - 84, 128, 75, 85, 82, 79, 79, 78, 69, 128, 75, 85, 82, 128, 75, 85, 210, - 75, 85, 81, 128, 75, 85, 79, 88, 128, 75, 85, 79, 80, 128, 75, 85, 79, - 208, 75, 85, 79, 77, 128, 75, 85, 79, 128, 75, 85, 78, 71, 128, 75, 85, - 78, 68, 68, 65, 76, 73, 89, 65, 128, 75, 85, 76, 128, 75, 85, 204, 75, - 85, 69, 84, 128, 75, 85, 55, 128, 75, 85, 52, 128, 75, 85, 180, 75, 85, - 51, 128, 75, 85, 179, 75, 84, 128, 75, 83, 83, 85, 85, 128, 75, 83, 83, - 85, 128, 75, 83, 83, 79, 79, 128, 75, 83, 83, 79, 128, 75, 83, 83, 73, - 73, 128, 75, 83, 83, 73, 128, 75, 83, 83, 69, 69, 128, 75, 83, 83, 69, - 128, 75, 83, 83, 65, 85, 128, 75, 83, 83, 65, 73, 128, 75, 83, 83, 65, - 65, 128, 75, 83, 83, 65, 128, 75, 83, 83, 128, 75, 83, 73, 128, 75, 82, - 69, 77, 65, 83, 84, 73, 128, 75, 82, 65, 84, 73, 77, 79, 89, 80, 79, 82, - 82, 79, 79, 78, 128, 75, 82, 65, 84, 73, 77, 79, 75, 79, 85, 70, 73, 83, - 77, 65, 128, 75, 82, 65, 84, 73, 77, 65, 84, 65, 128, 75, 82, 65, 84, 73, - 77, 193, 75, 80, 85, 128, 75, 80, 79, 81, 128, 75, 80, 79, 79, 128, 75, - 80, 79, 128, 75, 80, 73, 128, 75, 80, 69, 85, 88, 128, 75, 80, 69, 69, - 128, 75, 80, 69, 128, 75, 80, 65, 82, 65, 81, 128, 75, 80, 65, 78, 128, - 75, 80, 65, 128, 75, 79, 88, 128, 75, 79, 86, 85, 85, 128, 75, 79, 84, - 79, 128, 75, 79, 82, 85, 78, 65, 128, 75, 79, 82, 79, 78, 73, 83, 128, - 75, 79, 82, 69, 65, 206, 75, 79, 82, 65, 78, 73, 195, 75, 79, 81, 78, 68, - 79, 78, 128, 75, 79, 80, 80, 65, 128, 75, 79, 80, 128, 75, 79, 79, 80, - 79, 128, 75, 79, 79, 77, 85, 85, 84, 128, 75, 79, 79, 128, 75, 79, 78, - 84, 69, 86, 77, 65, 128, 75, 79, 78, 84, 69, 86, 77, 193, 75, 79, 77, - 201, 75, 79, 77, 66, 85, 86, 65, 128, 75, 79, 77, 66, 85, 86, 193, 75, - 79, 77, 66, 213, 75, 79, 75, 79, 128, 75, 79, 75, 128, 75, 79, 203, 75, + 76, 65, 128, 76, 65, 85, 75, 65, 218, 76, 65, 85, 74, 128, 76, 65, 84, + 73, 78, 65, 84, 197, 76, 65, 84, 73, 75, 128, 76, 65, 84, 69, 82, 65, + 204, 76, 65, 84, 197, 76, 65, 83, 212, 76, 65, 82, 89, 78, 71, 69, 65, + 204, 76, 65, 82, 71, 69, 210, 76, 65, 82, 71, 69, 128, 76, 65, 82, 71, + 197, 76, 65, 81, 128, 76, 65, 80, 65, 81, 128, 76, 65, 207, 76, 65, 78, + 84, 69, 82, 78, 128, 76, 65, 78, 71, 85, 65, 71, 197, 76, 65, 78, 69, 83, + 128, 76, 65, 78, 128, 76, 65, 77, 80, 128, 76, 65, 77, 69, 68, 72, 128, + 76, 65, 77, 69, 68, 128, 76, 65, 77, 69, 196, 76, 65, 77, 69, 128, 76, + 65, 77, 197, 76, 65, 77, 68, 65, 128, 76, 65, 77, 68, 128, 76, 65, 77, + 66, 68, 193, 76, 65, 77, 65, 68, 72, 128, 76, 65, 76, 128, 76, 65, 204, + 76, 65, 75, 75, 72, 65, 78, 71, 89, 65, 79, 128, 76, 65, 74, 65, 78, 89, + 65, 76, 65, 78, 128, 76, 65, 73, 78, 199, 76, 65, 201, 76, 65, 72, 83, + 72, 85, 128, 76, 65, 72, 128, 76, 65, 71, 85, 83, 128, 76, 65, 71, 213, + 76, 65, 71, 65, 82, 128, 76, 65, 71, 65, 210, 76, 65, 71, 65, 66, 128, + 76, 65, 71, 65, 194, 76, 65, 69, 86, 128, 76, 65, 69, 128, 76, 65, 68, + 217, 76, 65, 67, 75, 128, 76, 65, 67, 65, 128, 76, 65, 66, 79, 85, 82, + 73, 78, 71, 128, 76, 65, 66, 79, 82, 128, 76, 65, 66, 73, 65, 76, 73, 90, + 65, 84, 73, 79, 206, 76, 65, 66, 73, 65, 204, 76, 65, 66, 69, 76, 128, + 76, 65, 66, 65, 84, 128, 76, 65, 65, 78, 65, 69, 128, 76, 65, 65, 78, + 128, 76, 65, 65, 77, 85, 128, 76, 65, 65, 77, 128, 76, 65, 65, 73, 128, + 76, 54, 128, 76, 52, 128, 76, 51, 128, 76, 50, 128, 76, 48, 48, 54, 65, + 128, 76, 48, 48, 50, 65, 128, 76, 45, 84, 89, 80, 197, 76, 45, 83, 72, + 65, 80, 69, 196, 75, 89, 85, 82, 73, 73, 128, 75, 89, 85, 128, 75, 89, + 79, 128, 75, 89, 76, 73, 83, 77, 65, 128, 75, 89, 73, 128, 75, 89, 69, + 128, 75, 89, 65, 84, 72, 79, 211, 75, 89, 65, 65, 128, 75, 89, 65, 128, + 75, 88, 87, 73, 128, 75, 88, 87, 69, 69, 128, 75, 88, 87, 69, 128, 75, + 88, 87, 65, 65, 128, 75, 88, 87, 65, 128, 75, 88, 85, 128, 75, 88, 79, + 128, 75, 88, 73, 128, 75, 88, 69, 69, 128, 75, 88, 69, 128, 75, 88, 65, + 65, 128, 75, 88, 65, 128, 75, 87, 86, 128, 75, 87, 85, 51, 49, 56, 128, + 75, 87, 79, 79, 128, 75, 87, 79, 128, 75, 87, 77, 128, 75, 87, 73, 73, + 128, 75, 87, 73, 128, 75, 87, 69, 69, 128, 75, 87, 69, 128, 75, 87, 66, + 128, 75, 87, 65, 89, 128, 75, 87, 65, 69, 84, 128, 75, 87, 65, 65, 128, + 75, 86, 65, 128, 75, 86, 128, 75, 85, 88, 128, 75, 85, 86, 128, 75, 85, + 85, 72, 128, 75, 85, 84, 128, 75, 85, 83, 77, 65, 128, 75, 85, 83, 72, + 85, 50, 128, 75, 85, 82, 88, 128, 75, 85, 82, 85, 90, 69, 73, 82, 79, + 128, 75, 85, 82, 84, 128, 75, 85, 82, 79, 79, 78, 69, 128, 75, 85, 82, + 128, 75, 85, 210, 75, 85, 81, 128, 75, 85, 79, 88, 128, 75, 85, 79, 80, + 128, 75, 85, 79, 208, 75, 85, 79, 77, 128, 75, 85, 79, 128, 75, 85, 78, + 71, 128, 75, 85, 78, 68, 68, 65, 76, 73, 89, 65, 128, 75, 85, 76, 128, + 75, 85, 204, 75, 85, 71, 128, 75, 85, 69, 84, 128, 75, 85, 66, 128, 75, + 85, 65, 86, 128, 75, 85, 65, 66, 128, 75, 85, 65, 128, 75, 85, 55, 128, + 75, 85, 52, 128, 75, 85, 180, 75, 85, 51, 128, 75, 85, 179, 75, 84, 128, + 75, 83, 83, 85, 85, 128, 75, 83, 83, 85, 128, 75, 83, 83, 79, 79, 128, + 75, 83, 83, 79, 128, 75, 83, 83, 73, 73, 128, 75, 83, 83, 73, 128, 75, + 83, 83, 69, 69, 128, 75, 83, 83, 69, 128, 75, 83, 83, 65, 85, 128, 75, + 83, 83, 65, 73, 128, 75, 83, 83, 65, 65, 128, 75, 83, 83, 65, 128, 75, + 83, 83, 128, 75, 83, 73, 128, 75, 82, 69, 77, 65, 83, 84, 73, 128, 75, + 82, 65, 84, 73, 77, 79, 89, 80, 79, 82, 82, 79, 79, 78, 128, 75, 82, 65, + 84, 73, 77, 79, 75, 79, 85, 70, 73, 83, 77, 65, 128, 75, 82, 65, 84, 73, + 77, 65, 84, 65, 128, 75, 82, 65, 84, 73, 77, 193, 75, 80, 85, 128, 75, + 80, 79, 81, 128, 75, 80, 79, 79, 128, 75, 80, 79, 128, 75, 80, 73, 128, + 75, 80, 69, 85, 88, 128, 75, 80, 69, 69, 128, 75, 80, 69, 128, 75, 80, + 65, 82, 65, 81, 128, 75, 80, 65, 78, 128, 75, 80, 65, 72, 128, 75, 80, + 65, 128, 75, 79, 88, 128, 75, 79, 86, 85, 85, 128, 75, 79, 86, 128, 75, + 79, 84, 79, 128, 75, 79, 82, 85, 78, 65, 128, 75, 79, 82, 79, 78, 73, 83, + 128, 75, 79, 82, 69, 65, 206, 75, 79, 82, 65, 78, 73, 195, 75, 79, 81, + 78, 68, 79, 78, 128, 75, 79, 80, 80, 65, 128, 75, 79, 80, 128, 75, 79, + 79, 86, 128, 75, 79, 79, 80, 79, 128, 75, 79, 79, 77, 85, 85, 84, 128, + 75, 79, 79, 66, 128, 75, 79, 79, 128, 75, 79, 78, 84, 69, 86, 77, 65, + 128, 75, 79, 78, 84, 69, 86, 77, 193, 75, 79, 77, 201, 75, 79, 77, 66, + 85, 86, 65, 128, 75, 79, 77, 66, 85, 86, 193, 75, 79, 77, 66, 213, 75, + 79, 75, 79, 128, 75, 79, 75, 69, 128, 75, 79, 75, 128, 75, 79, 203, 75, 79, 73, 128, 75, 79, 201, 75, 79, 72, 128, 75, 79, 71, 72, 79, 77, 128, - 75, 79, 69, 84, 128, 75, 79, 65, 76, 65, 128, 75, 79, 65, 128, 75, 78, - 73, 71, 72, 84, 128, 75, 78, 73, 71, 72, 212, 75, 78, 73, 70, 69, 128, - 75, 78, 73, 70, 197, 75, 77, 128, 75, 205, 75, 76, 73, 84, 79, 78, 128, - 75, 76, 65, 83, 77, 65, 128, 75, 76, 65, 83, 77, 193, 75, 76, 65, 128, - 75, 76, 128, 75, 75, 85, 128, 75, 75, 79, 128, 75, 75, 73, 128, 75, 75, - 69, 69, 128, 75, 75, 69, 128, 75, 75, 65, 128, 75, 75, 128, 75, 74, 69, - 128, 75, 73, 89, 69, 79, 75, 45, 84, 73, 75, 69, 85, 84, 128, 75, 73, 89, - 69, 79, 75, 45, 83, 73, 79, 83, 45, 75, 73, 89, 69, 79, 75, 128, 75, 73, - 89, 69, 79, 75, 45, 82, 73, 69, 85, 76, 128, 75, 73, 89, 69, 79, 75, 45, - 80, 73, 69, 85, 80, 128, 75, 73, 89, 69, 79, 75, 45, 78, 73, 69, 85, 78, - 128, 75, 73, 89, 69, 79, 75, 45, 75, 72, 73, 69, 85, 75, 72, 128, 75, 73, - 89, 69, 79, 75, 45, 67, 72, 73, 69, 85, 67, 72, 128, 75, 73, 89, 69, 79, - 203, 75, 73, 88, 128, 75, 73, 84, 128, 75, 73, 83, 83, 73, 78, 199, 75, - 73, 83, 83, 128, 75, 73, 83, 211, 75, 73, 83, 73, 77, 53, 128, 75, 73, - 83, 73, 77, 181, 75, 73, 83, 72, 128, 75, 73, 83, 65, 76, 128, 75, 73, - 82, 79, 87, 65, 84, 84, 79, 128, 75, 73, 82, 79, 77, 69, 69, 84, 79, 82, - 85, 128, 75, 73, 82, 79, 71, 85, 82, 65, 77, 85, 128, 75, 73, 82, 79, - 128, 75, 73, 82, 71, 72, 73, 218, 75, 73, 81, 128, 75, 73, 80, 128, 75, - 73, 208, 75, 73, 78, 83, 72, 73, 80, 128, 75, 73, 78, 68, 69, 82, 71, 65, - 82, 84, 69, 78, 128, 75, 73, 77, 79, 78, 79, 128, 75, 73, 73, 128, 75, - 73, 72, 128, 75, 73, 69, 88, 128, 75, 73, 69, 80, 128, 75, 73, 69, 69, - 77, 128, 75, 73, 69, 128, 75, 73, 68, 128, 75, 73, 196, 75, 73, 67, 75, - 128, 75, 72, 90, 128, 75, 72, 87, 65, 73, 128, 75, 72, 85, 69, 78, 45, - 76, 85, 197, 75, 72, 85, 69, 206, 75, 72, 85, 68, 65, 77, 128, 75, 72, - 85, 65, 84, 128, 75, 72, 79, 85, 128, 75, 72, 79, 212, 75, 72, 79, 78, - 128, 75, 72, 79, 77, 85, 84, 128, 75, 72, 79, 128, 75, 72, 207, 75, 72, - 77, 213, 75, 72, 73, 84, 128, 75, 72, 73, 78, 89, 65, 128, 75, 72, 73, - 69, 85, 75, 200, 75, 72, 73, 128, 75, 72, 72, 79, 128, 75, 72, 72, 65, - 128, 75, 72, 69, 84, 72, 128, 75, 72, 69, 73, 128, 75, 72, 69, 69, 128, - 75, 72, 69, 128, 75, 72, 65, 82, 79, 83, 72, 84, 72, 201, 75, 72, 65, 82, - 128, 75, 72, 65, 80, 72, 128, 75, 72, 65, 78, 199, 75, 72, 65, 78, 68, - 193, 75, 72, 65, 78, 128, 75, 72, 65, 77, 84, 201, 75, 72, 65, 75, 65, - 83, 83, 73, 65, 206, 75, 72, 65, 73, 128, 75, 72, 65, 72, 128, 75, 72, - 65, 200, 75, 72, 65, 65, 128, 75, 71, 128, 75, 69, 89, 67, 65, 80, 128, - 75, 69, 89, 67, 65, 208, 75, 69, 89, 66, 79, 65, 82, 68, 128, 75, 69, 88, - 128, 75, 69, 85, 89, 69, 85, 88, 128, 75, 69, 85, 83, 72, 69, 85, 65, 69, - 80, 128, 75, 69, 85, 83, 69, 85, 88, 128, 75, 69, 85, 80, 85, 81, 128, - 75, 69, 85, 79, 212, 75, 69, 85, 77, 128, 75, 69, 85, 75, 69, 85, 84, 78, - 68, 65, 128, 75, 69, 85, 75, 65, 81, 128, 75, 69, 85, 65, 69, 84, 77, 69, - 85, 78, 128, 75, 69, 85, 65, 69, 82, 73, 128, 75, 69, 84, 84, 201, 75, - 69, 83, 72, 50, 128, 75, 69, 82, 69, 84, 128, 75, 69, 79, 87, 128, 75, - 69, 78, 84, 73, 77, 65, 84, 65, 128, 75, 69, 78, 84, 73, 77, 65, 84, 193, - 75, 69, 78, 84, 73, 77, 193, 75, 69, 78, 65, 84, 128, 75, 69, 78, 128, - 75, 69, 206, 75, 69, 77, 80, 85, 76, 128, 75, 69, 77, 80, 85, 204, 75, - 69, 77, 80, 76, 73, 128, 75, 69, 77, 80, 76, 201, 75, 69, 77, 80, 72, 82, - 69, 78, 71, 128, 75, 69, 77, 66, 65, 78, 71, 128, 75, 69, 76, 86, 73, - 206, 75, 69, 72, 69, 72, 128, 75, 69, 72, 69, 200, 75, 69, 72, 128, 75, - 69, 70, 85, 76, 65, 128, 75, 69, 69, 83, 85, 128, 75, 69, 69, 80, 73, 78, - 199, 75, 69, 69, 78, 71, 128, 75, 67, 65, 76, 128, 75, 66, 128, 75, 65, - 90, 65, 75, 200, 75, 65, 89, 65, 78, 78, 65, 128, 75, 65, 89, 65, 200, - 75, 65, 88, 128, 75, 65, 87, 73, 128, 75, 65, 86, 89, 75, 65, 128, 75, - 65, 85, 78, 65, 128, 75, 65, 85, 206, 75, 65, 85, 128, 75, 65, 84, 79, - 128, 75, 65, 84, 72, 73, 83, 84, 73, 128, 75, 65, 84, 72, 65, 75, 193, - 75, 65, 84, 65, 86, 65, 83, 77, 65, 128, 75, 65, 84, 65, 86, 193, 75, 65, - 84, 65, 75, 65, 78, 65, 45, 72, 73, 82, 65, 71, 65, 78, 193, 75, 65, 83, - 82, 65, 84, 65, 78, 128, 75, 65, 83, 82, 65, 84, 65, 206, 75, 65, 83, 82, - 65, 128, 75, 65, 83, 82, 193, 75, 65, 83, 75, 65, 76, 128, 75, 65, 83, - 75, 65, 204, 75, 65, 83, 72, 77, 73, 82, 201, 75, 65, 82, 83, 72, 65, 78, - 65, 128, 75, 65, 82, 79, 82, 73, 73, 128, 75, 65, 82, 207, 75, 65, 82, - 69, 206, 75, 65, 82, 65, 84, 84, 79, 128, 75, 65, 82, 65, 78, 128, 75, - 65, 80, 89, 69, 79, 85, 78, 83, 83, 65, 78, 71, 80, 73, 69, 85, 80, 128, - 75, 65, 80, 89, 69, 79, 85, 78, 82, 73, 69, 85, 76, 128, 75, 65, 80, 89, - 69, 79, 85, 78, 80, 72, 73, 69, 85, 80, 72, 128, 75, 65, 80, 89, 69, 79, - 85, 78, 77, 73, 69, 85, 77, 128, 75, 65, 80, 80, 65, 128, 75, 65, 80, 80, - 193, 75, 65, 80, 79, 128, 75, 65, 80, 72, 128, 75, 65, 80, 65, 76, 128, - 75, 65, 80, 65, 128, 75, 65, 78, 84, 65, 74, 193, 75, 65, 78, 71, 128, - 75, 65, 78, 199, 75, 65, 78, 65, 75, 79, 128, 75, 65, 77, 52, 128, 75, - 65, 77, 50, 128, 75, 65, 77, 128, 75, 65, 75, 79, 128, 75, 65, 75, 65, - 66, 65, 84, 128, 75, 65, 75, 128, 75, 65, 203, 75, 65, 73, 84, 72, 201, - 75, 65, 73, 82, 73, 128, 75, 65, 73, 128, 75, 65, 201, 75, 65, 70, 65, - 128, 75, 65, 70, 128, 75, 65, 198, 75, 65, 68, 53, 128, 75, 65, 68, 181, - 75, 65, 68, 52, 128, 75, 65, 68, 51, 128, 75, 65, 68, 179, 75, 65, 68, - 50, 128, 75, 65, 68, 128, 75, 65, 66, 193, 75, 65, 66, 128, 75, 65, 65, - 73, 128, 75, 65, 65, 70, 85, 128, 75, 65, 65, 70, 128, 75, 65, 50, 128, + 75, 79, 69, 84, 128, 75, 79, 66, 128, 75, 79, 65, 76, 65, 128, 75, 79, + 65, 128, 75, 78, 79, 66, 83, 128, 75, 78, 73, 71, 72, 84, 128, 75, 78, + 73, 71, 72, 212, 75, 78, 73, 70, 69, 128, 75, 78, 73, 70, 197, 75, 77, + 128, 75, 205, 75, 76, 73, 84, 79, 78, 128, 75, 76, 65, 83, 77, 65, 128, + 75, 76, 65, 83, 77, 193, 75, 76, 65, 128, 75, 76, 128, 75, 75, 85, 128, + 75, 75, 79, 128, 75, 75, 73, 128, 75, 75, 69, 69, 128, 75, 75, 69, 128, + 75, 75, 65, 128, 75, 75, 128, 75, 74, 69, 128, 75, 73, 89, 69, 79, 75, + 45, 84, 73, 75, 69, 85, 84, 128, 75, 73, 89, 69, 79, 75, 45, 83, 73, 79, + 83, 45, 75, 73, 89, 69, 79, 75, 128, 75, 73, 89, 69, 79, 75, 45, 82, 73, + 69, 85, 76, 128, 75, 73, 89, 69, 79, 75, 45, 80, 73, 69, 85, 80, 128, 75, + 73, 89, 69, 79, 75, 45, 78, 73, 69, 85, 78, 128, 75, 73, 89, 69, 79, 75, + 45, 75, 72, 73, 69, 85, 75, 72, 128, 75, 73, 89, 69, 79, 75, 45, 67, 72, + 73, 69, 85, 67, 72, 128, 75, 73, 89, 69, 79, 203, 75, 73, 88, 128, 75, + 73, 87, 128, 75, 73, 86, 128, 75, 73, 84, 128, 75, 73, 83, 83, 73, 78, + 199, 75, 73, 83, 83, 128, 75, 73, 83, 211, 75, 73, 83, 73, 77, 53, 128, + 75, 73, 83, 73, 77, 181, 75, 73, 83, 72, 128, 75, 73, 83, 65, 76, 128, + 75, 73, 82, 79, 87, 65, 84, 84, 79, 128, 75, 73, 82, 79, 77, 69, 69, 84, + 79, 82, 85, 128, 75, 73, 82, 79, 71, 85, 82, 65, 77, 85, 128, 75, 73, 82, + 79, 128, 75, 73, 82, 71, 72, 73, 218, 75, 73, 81, 128, 75, 73, 80, 128, + 75, 73, 208, 75, 73, 78, 83, 72, 73, 80, 128, 75, 73, 78, 68, 69, 82, 71, + 65, 82, 84, 69, 78, 128, 75, 73, 77, 79, 78, 79, 128, 75, 73, 73, 128, + 75, 73, 72, 128, 75, 73, 69, 88, 128, 75, 73, 69, 80, 128, 75, 73, 69, + 69, 77, 128, 75, 73, 69, 128, 75, 73, 68, 128, 75, 73, 196, 75, 73, 67, + 75, 128, 75, 73, 66, 128, 75, 73, 65, 86, 128, 75, 73, 65, 66, 128, 75, + 72, 90, 128, 75, 72, 87, 65, 73, 128, 75, 72, 85, 69, 78, 45, 76, 85, + 197, 75, 72, 85, 69, 206, 75, 72, 85, 68, 65, 87, 65, 68, 201, 75, 72, + 85, 68, 65, 77, 128, 75, 72, 85, 65, 84, 128, 75, 72, 79, 85, 128, 75, + 72, 79, 212, 75, 72, 79, 78, 128, 75, 72, 79, 77, 85, 84, 128, 75, 72, + 79, 74, 75, 201, 75, 72, 79, 128, 75, 72, 207, 75, 72, 77, 213, 75, 72, + 73, 84, 128, 75, 72, 73, 78, 89, 65, 128, 75, 72, 73, 69, 85, 75, 200, + 75, 72, 73, 128, 75, 72, 201, 75, 72, 72, 79, 128, 75, 72, 72, 65, 128, + 75, 72, 69, 84, 72, 128, 75, 72, 69, 73, 128, 75, 72, 69, 69, 128, 75, + 72, 69, 128, 75, 72, 65, 86, 128, 75, 72, 65, 82, 79, 83, 72, 84, 72, + 201, 75, 72, 65, 82, 128, 75, 72, 65, 80, 72, 128, 75, 72, 65, 78, 199, + 75, 72, 65, 78, 68, 193, 75, 72, 65, 78, 128, 75, 72, 65, 77, 84, 201, + 75, 72, 65, 75, 65, 83, 83, 73, 65, 206, 75, 72, 65, 73, 128, 75, 72, 65, + 72, 128, 75, 72, 65, 200, 75, 72, 65, 66, 128, 75, 72, 65, 65, 128, 75, + 71, 128, 75, 69, 89, 67, 65, 80, 128, 75, 69, 89, 67, 65, 208, 75, 69, + 89, 66, 79, 65, 82, 68, 128, 75, 69, 89, 66, 79, 65, 82, 196, 75, 69, 88, + 128, 75, 69, 86, 128, 75, 69, 85, 89, 69, 85, 88, 128, 75, 69, 85, 83, + 72, 69, 85, 65, 69, 80, 128, 75, 69, 85, 83, 69, 85, 88, 128, 75, 69, 85, + 80, 85, 81, 128, 75, 69, 85, 79, 212, 75, 69, 85, 77, 128, 75, 69, 85, + 75, 69, 85, 84, 78, 68, 65, 128, 75, 69, 85, 75, 65, 81, 128, 75, 69, 85, + 65, 69, 84, 77, 69, 85, 78, 128, 75, 69, 85, 65, 69, 82, 73, 128, 75, 69, + 84, 84, 201, 75, 69, 83, 72, 50, 128, 75, 69, 82, 69, 84, 128, 75, 69, + 79, 87, 128, 75, 69, 78, 84, 73, 77, 65, 84, 65, 128, 75, 69, 78, 84, 73, + 77, 65, 84, 193, 75, 69, 78, 84, 73, 77, 193, 75, 69, 78, 65, 84, 128, + 75, 69, 78, 128, 75, 69, 206, 75, 69, 77, 80, 85, 76, 128, 75, 69, 77, + 80, 85, 204, 75, 69, 77, 80, 76, 73, 128, 75, 69, 77, 80, 76, 201, 75, + 69, 77, 80, 72, 82, 69, 78, 71, 128, 75, 69, 77, 66, 65, 78, 71, 128, 75, + 69, 76, 86, 73, 206, 75, 69, 72, 69, 72, 128, 75, 69, 72, 69, 200, 75, + 69, 72, 128, 75, 69, 70, 85, 76, 65, 128, 75, 69, 69, 86, 128, 75, 69, + 69, 83, 85, 128, 75, 69, 69, 80, 73, 78, 199, 75, 69, 69, 78, 71, 128, + 75, 69, 69, 66, 128, 75, 69, 66, 128, 75, 69, 65, 65, 69, 128, 75, 67, + 65, 76, 128, 75, 66, 128, 75, 65, 90, 65, 75, 200, 75, 65, 89, 65, 78, + 78, 65, 128, 75, 65, 89, 65, 200, 75, 65, 88, 128, 75, 65, 87, 86, 128, + 75, 65, 87, 73, 128, 75, 65, 87, 66, 128, 75, 65, 86, 89, 75, 65, 128, + 75, 65, 86, 128, 75, 65, 85, 86, 128, 75, 65, 85, 78, 65, 128, 75, 65, + 85, 206, 75, 65, 85, 66, 128, 75, 65, 84, 79, 128, 75, 65, 84, 72, 73, + 83, 84, 73, 128, 75, 65, 84, 72, 65, 75, 193, 75, 65, 84, 65, 86, 65, 83, + 77, 65, 128, 75, 65, 84, 65, 86, 193, 75, 65, 84, 65, 75, 65, 78, 65, 45, + 72, 73, 82, 65, 71, 65, 78, 193, 75, 65, 83, 82, 65, 84, 65, 78, 128, 75, + 65, 83, 82, 65, 84, 65, 206, 75, 65, 83, 82, 65, 128, 75, 65, 83, 82, + 193, 75, 65, 83, 75, 65, 76, 128, 75, 65, 83, 75, 65, 204, 75, 65, 83, + 72, 77, 73, 82, 201, 75, 65, 82, 83, 72, 65, 78, 65, 128, 75, 65, 82, 79, + 82, 73, 73, 128, 75, 65, 82, 207, 75, 65, 82, 69, 206, 75, 65, 82, 65, + 84, 84, 79, 128, 75, 65, 82, 65, 78, 128, 75, 65, 80, 89, 69, 79, 85, 78, + 83, 83, 65, 78, 71, 80, 73, 69, 85, 80, 128, 75, 65, 80, 89, 69, 79, 85, + 78, 82, 73, 69, 85, 76, 128, 75, 65, 80, 89, 69, 79, 85, 78, 80, 72, 73, + 69, 85, 80, 72, 128, 75, 65, 80, 89, 69, 79, 85, 78, 77, 73, 69, 85, 77, + 128, 75, 65, 80, 80, 65, 128, 75, 65, 80, 80, 193, 75, 65, 80, 79, 128, + 75, 65, 80, 72, 128, 75, 65, 80, 65, 76, 128, 75, 65, 80, 65, 128, 75, + 65, 208, 75, 65, 78, 84, 65, 74, 193, 75, 65, 78, 71, 128, 75, 65, 78, + 199, 75, 65, 78, 65, 75, 79, 128, 75, 65, 77, 52, 128, 75, 65, 77, 50, + 128, 75, 65, 77, 128, 75, 65, 75, 79, 128, 75, 65, 75, 65, 66, 65, 84, + 128, 75, 65, 75, 128, 75, 65, 203, 75, 65, 73, 86, 128, 75, 65, 73, 84, + 72, 201, 75, 65, 73, 82, 73, 128, 75, 65, 73, 66, 128, 75, 65, 73, 128, + 75, 65, 201, 75, 65, 70, 65, 128, 75, 65, 70, 128, 75, 65, 198, 75, 65, + 68, 53, 128, 75, 65, 68, 181, 75, 65, 68, 52, 128, 75, 65, 68, 51, 128, + 75, 65, 68, 179, 75, 65, 68, 50, 128, 75, 65, 68, 128, 75, 65, 66, 193, + 75, 65, 66, 128, 75, 65, 65, 86, 128, 75, 65, 65, 73, 128, 75, 65, 65, + 70, 85, 128, 75, 65, 65, 70, 128, 75, 65, 65, 66, 128, 75, 65, 50, 128, 75, 65, 178, 75, 48, 48, 56, 128, 75, 48, 48, 55, 128, 75, 48, 48, 54, 128, 75, 48, 48, 53, 128, 75, 48, 48, 52, 128, 75, 48, 48, 51, 128, 75, 48, 48, 50, 128, 75, 48, 48, 49, 128, 74, 87, 65, 128, 74, 85, 85, 128, @@ -2319,1509 +2488,1538 @@ static unsigned char lexicon[] = { 74, 85, 80, 73, 84, 69, 82, 128, 74, 85, 79, 84, 128, 74, 85, 79, 80, 128, 74, 85, 78, 79, 128, 74, 85, 78, 69, 128, 74, 85, 76, 89, 128, 74, 85, 69, 85, 73, 128, 74, 85, 68, 85, 76, 128, 74, 85, 68, 71, 69, 128, - 74, 85, 68, 69, 79, 45, 83, 80, 65, 78, 73, 83, 200, 74, 79, 89, 79, 85, - 211, 74, 79, 89, 128, 74, 79, 86, 69, 128, 74, 79, 212, 74, 79, 78, 71, - 128, 74, 79, 78, 193, 74, 79, 75, 69, 82, 128, 74, 79, 73, 78, 69, 68, - 128, 74, 79, 73, 78, 128, 74, 79, 65, 128, 74, 74, 89, 88, 128, 74, 74, - 89, 84, 128, 74, 74, 89, 80, 128, 74, 74, 89, 128, 74, 74, 85, 88, 128, - 74, 74, 85, 84, 128, 74, 74, 85, 82, 88, 128, 74, 74, 85, 82, 128, 74, - 74, 85, 80, 128, 74, 74, 85, 79, 88, 128, 74, 74, 85, 79, 80, 128, 74, - 74, 85, 79, 128, 74, 74, 85, 128, 74, 74, 79, 88, 128, 74, 74, 79, 84, - 128, 74, 74, 79, 80, 128, 74, 74, 79, 128, 74, 74, 73, 88, 128, 74, 74, - 73, 84, 128, 74, 74, 73, 80, 128, 74, 74, 73, 69, 88, 128, 74, 74, 73, - 69, 84, 128, 74, 74, 73, 69, 80, 128, 74, 74, 73, 69, 128, 74, 74, 73, - 128, 74, 74, 69, 69, 128, 74, 74, 69, 128, 74, 74, 65, 128, 74, 73, 76, - 128, 74, 73, 73, 128, 74, 73, 72, 86, 65, 77, 85, 76, 73, 89, 65, 128, - 74, 73, 65, 128, 74, 72, 79, 128, 74, 72, 69, 72, 128, 74, 72, 65, 78, - 128, 74, 72, 65, 77, 128, 74, 72, 65, 65, 128, 74, 72, 65, 128, 74, 69, - 85, 128, 74, 69, 82, 85, 83, 65, 76, 69, 77, 128, 74, 69, 82, 65, 206, - 74, 69, 82, 65, 128, 74, 69, 82, 128, 74, 69, 72, 128, 74, 69, 200, 74, - 69, 71, 79, 71, 65, 78, 128, 74, 69, 69, 77, 128, 74, 69, 65, 78, 83, - 128, 74, 65, 89, 65, 78, 78, 65, 128, 74, 65, 86, 73, 89, 65, 78, 73, - 128, 74, 65, 85, 128, 74, 65, 82, 128, 74, 65, 80, 65, 78, 69, 83, 197, - 74, 65, 80, 65, 78, 128, 74, 65, 78, 85, 65, 82, 89, 128, 74, 65, 76, 76, - 65, 74, 65, 76, 65, 76, 79, 85, 72, 79, 85, 128, 74, 65, 73, 128, 74, 65, - 72, 128, 74, 65, 68, 69, 128, 74, 65, 67, 75, 45, 79, 45, 76, 65, 78, 84, - 69, 82, 78, 128, 74, 65, 67, 203, 74, 45, 83, 73, 77, 80, 76, 73, 70, 73, - 69, 196, 202, 73, 90, 72, 73, 84, 83, 65, 128, 73, 90, 72, 73, 84, 83, - 193, 73, 90, 72, 69, 128, 73, 90, 65, 75, 65, 89, 193, 73, 89, 69, 75, - 128, 73, 89, 65, 78, 78, 65, 128, 73, 85, 74, 65, 128, 73, 85, 128, 73, - 84, 211, 73, 84, 69, 82, 65, 84, 73, 79, 206, 73, 84, 69, 77, 128, 73, - 83, 83, 72, 65, 82, 128, 73, 83, 79, 78, 128, 73, 83, 79, 206, 73, 83, - 79, 76, 65, 84, 69, 128, 73, 83, 69, 78, 45, 73, 83, 69, 78, 128, 73, 83, - 65, 75, 73, 193, 73, 83, 45, 80, 73, 76, 76, 65, 128, 73, 82, 85, 89, 65, - 78, 78, 65, 128, 73, 82, 85, 85, 89, 65, 78, 78, 65, 128, 73, 82, 79, 78, - 45, 67, 79, 80, 80, 69, 210, 73, 82, 79, 78, 128, 73, 79, 84, 73, 70, 73, - 69, 196, 73, 79, 84, 65, 84, 69, 196, 73, 79, 84, 65, 128, 73, 79, 84, - 193, 73, 79, 82, 128, 73, 79, 68, 72, 65, 68, 72, 128, 73, 78, 86, 73, - 83, 73, 66, 76, 197, 73, 78, 86, 69, 82, 84, 69, 68, 128, 73, 78, 86, 69, - 82, 84, 69, 196, 73, 78, 86, 69, 82, 83, 197, 73, 78, 84, 82, 79, 68, 85, - 67, 69, 82, 128, 73, 78, 84, 73, 128, 73, 78, 84, 69, 82, 83, 89, 76, 76, - 65, 66, 73, 195, 73, 78, 84, 69, 82, 83, 69, 67, 84, 73, 79, 78, 128, 73, - 78, 84, 69, 82, 83, 69, 67, 84, 73, 79, 206, 73, 78, 84, 69, 82, 83, 69, - 67, 84, 73, 78, 199, 73, 78, 84, 69, 82, 82, 79, 66, 65, 78, 71, 128, 73, - 78, 84, 69, 82, 80, 79, 76, 65, 84, 73, 79, 206, 73, 78, 84, 69, 82, 76, - 79, 67, 75, 69, 196, 73, 78, 84, 69, 82, 76, 73, 78, 69, 65, 210, 73, 78, - 84, 69, 82, 76, 65, 67, 69, 196, 73, 78, 84, 69, 82, 73, 79, 210, 73, 78, - 84, 69, 82, 69, 83, 212, 73, 78, 84, 69, 82, 67, 65, 76, 65, 84, 69, 128, - 73, 78, 84, 69, 71, 82, 65, 84, 73, 79, 78, 128, 73, 78, 84, 69, 71, 82, - 65, 84, 73, 79, 206, 73, 78, 84, 69, 71, 82, 65, 76, 128, 73, 78, 84, 69, - 71, 82, 65, 204, 73, 78, 83, 85, 76, 65, 210, 73, 78, 83, 84, 82, 85, 77, - 69, 78, 84, 65, 204, 73, 78, 83, 73, 68, 69, 128, 73, 78, 83, 69, 82, 84, - 73, 79, 206, 73, 78, 83, 69, 67, 84, 128, 73, 78, 83, 67, 82, 73, 80, 84, - 73, 79, 78, 65, 204, 73, 78, 80, 85, 212, 73, 78, 78, 79, 67, 69, 78, 67, - 69, 128, 73, 78, 78, 78, 128, 73, 78, 78, 69, 82, 128, 73, 78, 78, 69, - 210, 73, 78, 78, 128, 73, 78, 73, 78, 71, 85, 128, 73, 78, 73, 128, 73, - 78, 72, 73, 66, 73, 212, 73, 78, 72, 69, 82, 69, 78, 212, 73, 78, 71, 87, - 65, 90, 128, 73, 78, 70, 79, 82, 77, 65, 84, 73, 79, 206, 73, 78, 70, 76, - 85, 69, 78, 67, 69, 128, 73, 78, 70, 73, 78, 73, 84, 89, 128, 73, 78, 70, - 73, 78, 73, 84, 217, 73, 78, 68, 85, 83, 84, 82, 73, 65, 204, 73, 78, 68, - 73, 82, 69, 67, 212, 73, 78, 68, 73, 67, 65, 84, 79, 82, 128, 73, 78, 68, - 73, 67, 65, 84, 79, 210, 73, 78, 68, 73, 195, 73, 78, 68, 73, 65, 206, - 73, 78, 68, 69, 88, 128, 73, 78, 68, 69, 80, 69, 78, 68, 69, 78, 212, 73, - 78, 67, 82, 69, 77, 69, 78, 84, 128, 73, 78, 67, 82, 69, 65, 83, 69, 211, - 73, 78, 67, 82, 69, 65, 83, 69, 128, 73, 78, 67, 79, 77, 80, 76, 69, 84, - 197, 73, 78, 67, 79, 77, 73, 78, 199, 73, 78, 67, 76, 85, 68, 73, 78, - 199, 73, 78, 67, 72, 128, 73, 78, 66, 79, 216, 73, 78, 65, 80, 128, 73, - 78, 45, 65, 76, 65, 70, 128, 73, 77, 80, 69, 82, 73, 65, 204, 73, 77, 80, - 69, 82, 70, 69, 67, 84, 85, 205, 73, 77, 80, 69, 82, 70, 69, 67, 84, 65, - 128, 73, 77, 80, 69, 82, 70, 69, 67, 84, 193, 73, 77, 78, 128, 73, 77, - 73, 83, 69, 79, 211, 73, 77, 73, 78, 51, 128, 73, 77, 73, 78, 128, 73, - 77, 73, 206, 73, 77, 73, 70, 84, 72, 79, 82, 79, 78, 128, 73, 77, 73, 70, - 84, 72, 79, 82, 65, 128, 73, 77, 73, 70, 79, 78, 79, 78, 128, 73, 77, 73, - 68, 73, 65, 82, 71, 79, 78, 128, 73, 77, 65, 71, 197, 73, 76, 85, 89, 65, - 78, 78, 65, 128, 73, 76, 85, 89, 128, 73, 76, 85, 85, 89, 65, 78, 78, 65, - 128, 73, 76, 85, 84, 128, 73, 76, 73, 77, 77, 85, 52, 128, 73, 76, 73, - 77, 77, 85, 51, 128, 73, 76, 73, 77, 77, 85, 128, 73, 76, 73, 77, 77, - 213, 73, 76, 50, 128, 73, 75, 65, 82, 65, 128, 73, 75, 65, 82, 193, 73, - 74, 128, 73, 73, 89, 65, 78, 78, 65, 128, 73, 71, 73, 128, 73, 71, 201, - 73, 71, 71, 87, 83, 128, 73, 70, 73, 78, 128, 73, 69, 85, 78, 71, 45, 84, - 73, 75, 69, 85, 84, 128, 73, 69, 85, 78, 71, 45, 84, 72, 73, 69, 85, 84, - 72, 128, 73, 69, 85, 78, 71, 45, 83, 83, 65, 78, 71, 75, 73, 89, 69, 79, - 75, 128, 73, 69, 85, 78, 71, 45, 82, 73, 69, 85, 76, 128, 73, 69, 85, 78, - 71, 45, 80, 73, 69, 85, 80, 128, 73, 69, 85, 78, 71, 45, 80, 72, 73, 69, - 85, 80, 72, 128, 73, 69, 85, 78, 71, 45, 75, 73, 89, 69, 79, 75, 128, 73, - 69, 85, 78, 71, 45, 75, 72, 73, 69, 85, 75, 72, 128, 73, 69, 85, 78, 71, - 45, 67, 73, 69, 85, 67, 128, 73, 69, 85, 78, 71, 45, 67, 72, 73, 69, 85, - 67, 72, 128, 73, 69, 85, 78, 199, 73, 68, 76, 69, 128, 73, 68, 73, 77, - 128, 73, 68, 73, 205, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, - 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, 56, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, 55, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 68, 54, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 68, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 68, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, - 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, 50, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, 49, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 68, 48, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 67, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 67, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, - 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 67, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 66, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 67, 65, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 67, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 67, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, - 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 54, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 53, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 67, 52, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 67, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 67, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, - 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 48, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 70, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 66, 69, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 66, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 66, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, - 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 65, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 57, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 66, 56, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 66, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 66, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, - 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 52, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 51, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 66, 50, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 66, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 66, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, - 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 69, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 68, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 65, 67, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 65, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 65, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, - 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 56, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 55, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 65, 54, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 65, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 65, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, - 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 50, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 49, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 65, 48, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 57, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 57, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, - 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 67, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 66, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 57, 65, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 57, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 57, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, - 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 54, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 53, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 57, 52, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 57, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 57, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, - 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 48, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 70, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 56, 69, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 56, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 56, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, - 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 65, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 57, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 56, 56, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 56, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 56, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, - 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 52, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 51, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 56, 50, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 56, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 56, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, - 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 69, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 68, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 55, 67, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 55, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 55, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, - 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 56, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 55, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 55, 54, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 55, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 55, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, - 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 50, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 49, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 55, 48, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 54, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 54, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, - 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 65, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 57, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 54, 56, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 54, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 54, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, - 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 52, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 51, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 54, 50, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 54, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 54, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, - 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 69, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 68, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 53, 67, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 53, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 53, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, - 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 56, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 55, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 53, 54, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 53, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 53, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, - 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 50, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 49, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 53, 48, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 52, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 52, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, - 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 67, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 66, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 52, 65, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 52, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 52, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, - 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 54, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 53, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 52, 52, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 52, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 52, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, - 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 48, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 70, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 51, 69, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 51, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 51, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, - 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 65, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 57, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 51, 56, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 51, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 51, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, - 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 52, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 51, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 51, 50, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 51, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 51, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, - 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 69, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 68, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 50, 67, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 50, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 50, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, - 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 56, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 55, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 50, 54, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 50, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 50, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, - 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 50, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 49, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 50, 48, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 49, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 49, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, - 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 67, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 66, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 49, 65, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 49, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 49, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, - 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 54, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 53, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 49, 52, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 49, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 49, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, - 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 48, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 70, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 48, 69, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 48, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 48, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, - 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 65, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 57, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 48, 56, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 48, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 48, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, - 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 52, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 51, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 48, 50, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 48, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 48, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, - 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 69, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 68, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 70, 67, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 70, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 70, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, - 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 56, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 55, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 70, 54, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 70, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 70, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, - 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 50, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 49, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 70, 48, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 69, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 69, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, - 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 67, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 66, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 69, 65, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 69, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 69, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, - 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 54, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 53, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 69, 52, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 69, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 69, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, - 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 48, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 70, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 68, 69, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 68, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 68, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, - 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 65, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 57, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 68, 56, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 68, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 68, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, - 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 52, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 51, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 68, 50, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 68, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 68, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, - 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 69, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 68, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 67, 67, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 67, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 67, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, - 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 56, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 55, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 67, 54, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 67, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 67, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, - 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 50, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 49, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 67, 48, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 66, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 66, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, - 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 67, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 66, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 66, 65, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 66, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 66, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, - 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 54, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 53, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 66, 52, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 66, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 66, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, - 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 48, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 70, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 65, 69, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 65, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 65, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, - 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 65, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 57, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 65, 56, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 65, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 65, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, - 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 52, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 51, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 65, 50, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 65, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 65, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, - 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 69, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 68, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 57, 67, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 57, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 57, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, - 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 56, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 55, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 57, 54, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 57, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 57, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, - 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 50, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 49, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 57, 48, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 56, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 56, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, - 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 67, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 66, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 56, 65, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 56, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 56, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, - 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 54, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 53, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 56, 52, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 56, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 56, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, - 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 48, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 70, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 55, 69, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 55, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 55, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, - 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 65, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 57, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 55, 56, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 55, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 55, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, - 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 52, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 51, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 55, 50, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 55, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 55, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, - 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 69, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 68, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 54, 67, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 54, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 54, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, - 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 56, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 55, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 54, 54, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 54, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 54, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, - 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 50, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 49, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 54, 48, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 53, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 53, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, - 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 67, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 66, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 53, 65, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 53, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 53, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, - 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 54, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 53, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 53, 52, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 53, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 53, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, - 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 48, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 70, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 52, 69, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 52, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 52, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, - 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 65, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 57, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 52, 56, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 52, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 52, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, - 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 52, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 51, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 52, 50, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 52, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 52, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, - 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 69, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 68, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 51, 67, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 51, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 51, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, - 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 56, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 55, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 51, 54, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 51, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 51, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, - 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 50, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 49, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 51, 48, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 50, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 50, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, - 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 67, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 66, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 50, 65, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 50, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 50, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, - 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 54, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 53, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 50, 52, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 50, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 50, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, - 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 48, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 70, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 49, 69, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 49, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 49, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, - 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 65, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 57, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 49, 56, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 49, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 49, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, - 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 52, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 51, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 49, 50, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 49, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 49, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, - 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 69, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 68, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 48, 67, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 48, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 48, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, - 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 56, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 55, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 48, 54, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 48, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 48, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, - 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 50, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 49, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 48, 48, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 57, 48, 52, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 56, 68, 55, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 56, 67, 65, - 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 56, 57, 69, 51, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 55, 68, 52, 50, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 55, 65, 55, 65, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 55, 57, 56, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 55, 54, 68, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 55, 53, 51, - 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 55, 53, 49, 70, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 55, 49, 50, 49, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 55, 48, 66, 57, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 54, 70, 49, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 54, 69, 56, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 55, 50, - 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 55, 48, 57, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 55, 48, 56, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 54, 54, 50, 48, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 54, 53, 66, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 54, 53, 57, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 53, 53, - 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 51, 53, 53, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 51, 48, 55, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 54, 50, 57, 53, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 54, 50, 53, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 54, 50, 52, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 70, 56, - 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 68, 69, 54, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 66, 56, 57, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 53, 66, 53, 55, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 53, 57, 50, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 53, 57, 49, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 56, 70, - 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 53, 66, 54, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 52, 51, 57, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 53, 52, 48, 56, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 53, 51, 70, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 53, 51, 67, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 50, 68, - 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 50, 55, 50, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 50, 52, 68, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 53, 50, 49, 68, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 53, 49, 56, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 52, 69, 65, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 52, 69, 56, - 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 52, 69, 50, 68, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 52, 69, 48, 57, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 52, 69, 48, 48, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 65, 49, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 65, 49, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 65, 49, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, - 49, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 57, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 56, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 55, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 54, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 65, 49, 53, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 65, 49, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 65, 49, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 65, 49, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, - 49, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 48, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 70, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 69, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 68, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 65, 48, 67, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 65, 48, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 65, 48, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 65, 48, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, - 48, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 55, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 54, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 53, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 52, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 65, 48, 51, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 65, 48, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 65, 48, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 65, 48, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 70, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 69, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 68, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 67, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 66, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 70, 65, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 70, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 70, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 70, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 70, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 53, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 52, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 51, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 50, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 70, 49, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 70, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 69, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 69, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 69, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 67, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 66, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 65, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 57, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 69, 56, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 69, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 69, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 69, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 69, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 51, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 50, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 49, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 48, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 68, 70, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 68, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 68, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 68, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 68, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 65, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 57, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 56, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 55, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 68, 54, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 68, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 68, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 68, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 68, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 49, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 48, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 70, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 69, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 67, 68, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 67, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 67, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 67, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 67, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 56, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 55, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 54, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 53, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 67, 52, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 67, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 67, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 67, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 67, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 70, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 69, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 68, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 67, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 66, 66, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 66, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 66, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 66, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 66, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 54, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 53, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 52, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 51, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 66, 50, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 66, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 66, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 65, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 65, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 68, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 67, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 66, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 65, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 65, 57, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 65, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 65, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 65, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 65, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 52, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 51, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 50, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 49, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 65, 48, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 57, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 57, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 57, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 57, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 66, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 65, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 57, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 56, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 57, 55, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 57, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 57, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 57, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 57, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 50, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 49, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 48, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 70, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 56, 69, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 56, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 56, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 56, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 56, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 57, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 56, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 55, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 54, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 56, 53, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 56, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 56, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 56, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 56, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 48, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 70, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 69, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 68, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 55, 67, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 55, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 55, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 55, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 55, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 55, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 54, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 53, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 52, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 55, 51, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 55, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 55, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 55, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 54, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 69, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 68, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 67, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 66, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 54, 65, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 54, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 54, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 54, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 54, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 53, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 52, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 51, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 50, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 54, 49, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 54, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 53, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 53, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 53, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 67, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 66, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 65, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 57, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 53, 56, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 53, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 53, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 53, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 53, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 51, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 50, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 49, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 48, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 52, 70, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 52, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 52, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 52, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 52, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 65, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 57, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 56, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 55, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 52, 54, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 52, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 52, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 52, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 52, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 49, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 48, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 70, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 69, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 51, 68, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 51, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 51, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 51, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 51, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 56, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 55, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 54, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 53, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 51, 52, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 51, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 51, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 51, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 51, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 70, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 69, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 68, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 67, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 50, 66, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 50, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 50, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 50, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 50, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 54, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 53, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 52, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 51, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 50, 50, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 50, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 50, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 49, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 49, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 68, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 67, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 66, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 65, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 49, 57, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 49, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 49, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 49, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 49, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 52, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 51, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 50, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 49, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 49, 48, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 48, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 48, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 48, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 48, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 66, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 65, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 57, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 56, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 57, 48, 55, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 57, 48, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 57, 48, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 57, 48, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, - 48, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 50, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 49, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 48, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 70, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 70, 69, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 70, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 70, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 70, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 70, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 57, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 56, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 55, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 54, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 70, 53, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 70, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 70, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 70, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 70, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 48, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 70, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 69, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 68, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 69, 67, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 69, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 69, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 69, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 69, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 55, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 54, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 53, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 52, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 69, 51, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 69, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 69, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 69, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 68, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 69, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 68, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 67, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 66, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 68, 65, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 68, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 68, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 68, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 68, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 53, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 52, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 51, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 50, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 68, 49, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 68, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 67, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 67, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 67, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 67, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 66, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 65, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 57, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 67, 56, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 67, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 67, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 67, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 67, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 51, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 50, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 49, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 48, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 66, 70, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 66, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 66, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 66, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 66, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 65, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 57, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 56, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 55, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 66, 54, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 66, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 66, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 66, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 66, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 49, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 48, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 70, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 69, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 65, 68, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 65, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 65, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 65, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 65, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 56, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 55, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 54, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 53, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 65, 52, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 65, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 65, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 65, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 65, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 70, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 69, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 68, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 67, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 57, 66, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 57, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 57, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 57, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 57, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 54, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 53, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 52, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 51, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 57, 50, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 57, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 57, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 56, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 56, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 68, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 67, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 66, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 65, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 56, 57, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 56, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 56, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 56, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 56, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 52, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 51, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 50, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 49, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 56, 48, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 55, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 55, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 55, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 55, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 66, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 65, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 57, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 56, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 55, 55, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 55, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 55, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 55, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 55, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 50, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 49, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 48, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 70, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 54, 69, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 54, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 54, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 54, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 54, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 57, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 56, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 55, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 54, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 54, 53, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 54, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 54, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 54, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 54, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 48, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 70, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 69, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 68, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 53, 67, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 53, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 53, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 53, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 53, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 55, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 54, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 53, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 52, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 53, 51, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 53, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 53, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 53, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 52, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 69, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 68, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 67, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 66, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 52, 65, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 52, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 52, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 52, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 52, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 53, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 52, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 51, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 50, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 52, 49, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 52, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 51, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 51, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 51, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 67, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 66, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 65, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 57, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 51, 56, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 51, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 51, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 51, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 51, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 51, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 50, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 49, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 48, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 50, 70, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 50, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 50, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 50, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 50, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 65, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 57, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 56, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 55, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 50, 54, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 50, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 50, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 50, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 50, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 49, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 48, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 70, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 69, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 49, 68, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 49, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 49, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 49, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 49, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 56, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 55, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 54, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 53, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 49, 52, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 49, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 49, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 49, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 49, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 70, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 69, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 68, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 67, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 48, 66, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 48, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 48, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, - 70, 56, 48, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, - 48, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 54, - 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 53, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 52, 128, 73, 68, 69, - 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 51, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 45, 50, 70, 56, 48, 50, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 50, 70, 56, 48, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, - 45, 50, 70, 56, 48, 48, 128, 73, 68, 69, 78, 84, 73, 70, 73, 67, 65, 84, - 73, 79, 78, 128, 73, 68, 69, 78, 84, 73, 67, 65, 204, 73, 67, 72, 79, 85, - 128, 73, 67, 72, 79, 83, 128, 73, 67, 72, 73, 77, 65, 84, 79, 83, 128, - 73, 67, 72, 65, 68, 73, 78, 128, 73, 67, 69, 76, 65, 78, 68, 73, 67, 45, - 89, 82, 128, 73, 66, 73, 70, 73, 76, 73, 128, 73, 65, 85, 68, 65, 128, - 73, 48, 49, 53, 128, 73, 48, 49, 52, 128, 73, 48, 49, 51, 128, 73, 48, - 49, 50, 128, 73, 48, 49, 49, 65, 128, 73, 48, 49, 49, 128, 73, 48, 49, - 48, 65, 128, 73, 48, 49, 48, 128, 73, 48, 48, 57, 65, 128, 73, 48, 48, - 57, 128, 73, 48, 48, 56, 128, 73, 48, 48, 55, 128, 73, 48, 48, 54, 128, - 73, 48, 48, 53, 65, 128, 73, 48, 48, 53, 128, 73, 48, 48, 52, 128, 73, - 48, 48, 51, 128, 73, 48, 48, 50, 128, 73, 48, 48, 49, 128, 73, 45, 89, - 85, 128, 73, 45, 89, 79, 128, 73, 45, 89, 69, 79, 128, 73, 45, 89, 69, - 128, 73, 45, 89, 65, 69, 128, 73, 45, 89, 65, 45, 79, 128, 73, 45, 89, - 65, 128, 73, 45, 79, 45, 73, 128, 73, 45, 79, 128, 73, 45, 69, 85, 128, - 73, 45, 66, 69, 65, 77, 128, 73, 45, 65, 82, 65, 69, 65, 128, 73, 45, 65, - 128, 72, 90, 90, 90, 71, 128, 72, 90, 90, 90, 128, 72, 90, 90, 80, 128, - 72, 90, 90, 128, 72, 90, 87, 71, 128, 72, 90, 87, 128, 72, 90, 84, 128, - 72, 90, 71, 128, 72, 89, 83, 84, 69, 82, 69, 83, 73, 211, 72, 89, 80, 79, - 68, 73, 65, 83, 84, 79, 76, 69, 128, 72, 89, 80, 72, 69, 78, 65, 84, 73, - 79, 206, 72, 89, 80, 72, 69, 78, 45, 77, 73, 78, 85, 83, 128, 72, 89, 80, - 72, 69, 78, 128, 72, 89, 80, 72, 69, 206, 72, 88, 87, 71, 128, 72, 88, - 85, 79, 88, 128, 72, 88, 85, 79, 84, 128, 72, 88, 85, 79, 80, 128, 72, - 88, 85, 79, 128, 72, 88, 79, 88, 128, 72, 88, 79, 84, 128, 72, 88, 79, - 80, 128, 72, 88, 79, 128, 72, 88, 73, 88, 128, 72, 88, 73, 84, 128, 72, - 88, 73, 80, 128, 72, 88, 73, 69, 88, 128, 72, 88, 73, 69, 84, 128, 72, - 88, 73, 69, 80, 128, 72, 88, 73, 69, 128, 72, 88, 73, 128, 72, 88, 69, - 88, 128, 72, 88, 69, 80, 128, 72, 88, 69, 128, 72, 88, 65, 88, 128, 72, - 88, 65, 84, 128, 72, 88, 65, 80, 128, 72, 88, 65, 128, 72, 87, 85, 128, - 72, 87, 65, 73, 82, 128, 72, 86, 128, 72, 85, 83, 72, 69, 196, 72, 85, - 82, 65, 78, 128, 72, 85, 79, 84, 128, 72, 85, 78, 68, 82, 69, 68, 128, - 72, 85, 78, 68, 82, 69, 196, 72, 85, 78, 128, 72, 85, 77, 65, 78, 128, - 72, 85, 77, 65, 206, 72, 85, 76, 50, 128, 72, 85, 73, 73, 84, 79, 128, - 72, 85, 66, 50, 128, 72, 85, 66, 178, 72, 85, 66, 128, 72, 85, 65, 82, - 65, 68, 68, 79, 128, 72, 84, 83, 128, 72, 84, 74, 128, 72, 82, 89, 86, - 78, 73, 193, 72, 80, 87, 71, 128, 72, 80, 65, 128, 72, 80, 128, 72, 79, - 85, 83, 197, 72, 79, 85, 82, 71, 76, 65, 83, 83, 128, 72, 79, 85, 82, 71, - 76, 65, 83, 211, 72, 79, 85, 82, 128, 72, 79, 85, 210, 72, 79, 84, 69, - 76, 128, 72, 79, 84, 65, 128, 72, 79, 83, 80, 73, 84, 65, 76, 128, 72, - 79, 82, 83, 69, 128, 72, 79, 82, 83, 197, 72, 79, 82, 78, 83, 128, 72, - 79, 82, 73, 90, 79, 78, 84, 65, 76, 76, 217, 72, 79, 82, 73, 90, 79, 78, - 84, 65, 76, 45, 48, 54, 45, 48, 54, 128, 72, 79, 82, 73, 90, 79, 78, 84, - 65, 76, 45, 48, 54, 45, 48, 53, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, - 76, 45, 48, 54, 45, 48, 52, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, - 45, 48, 54, 45, 48, 51, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, - 48, 54, 45, 48, 50, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, - 54, 45, 48, 49, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 54, - 45, 48, 48, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 53, 45, - 48, 54, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 53, 45, 48, - 53, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 53, 45, 48, 52, - 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 53, 45, 48, 51, 128, - 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 53, 45, 48, 50, 128, 72, - 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 53, 45, 48, 49, 128, 72, 79, - 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 53, 45, 48, 48, 128, 72, 79, 82, - 73, 90, 79, 78, 84, 65, 76, 45, 48, 52, 45, 48, 54, 128, 72, 79, 82, 73, - 90, 79, 78, 84, 65, 76, 45, 48, 52, 45, 48, 53, 128, 72, 79, 82, 73, 90, - 79, 78, 84, 65, 76, 45, 48, 52, 45, 48, 52, 128, 72, 79, 82, 73, 90, 79, - 78, 84, 65, 76, 45, 48, 52, 45, 48, 51, 128, 72, 79, 82, 73, 90, 79, 78, - 84, 65, 76, 45, 48, 52, 45, 48, 50, 128, 72, 79, 82, 73, 90, 79, 78, 84, - 65, 76, 45, 48, 52, 45, 48, 49, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, - 76, 45, 48, 52, 45, 48, 48, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, - 45, 48, 51, 45, 48, 54, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, - 48, 51, 45, 48, 53, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, - 51, 45, 48, 52, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 51, - 45, 48, 51, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 51, 45, - 48, 50, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 51, 45, 48, - 49, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 51, 45, 48, 48, - 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 50, 45, 48, 54, 128, - 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 50, 45, 48, 53, 128, 72, - 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 50, 45, 48, 52, 128, 72, 79, - 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 50, 45, 48, 51, 128, 72, 79, 82, - 73, 90, 79, 78, 84, 65, 76, 45, 48, 50, 45, 48, 50, 128, 72, 79, 82, 73, - 90, 79, 78, 84, 65, 76, 45, 48, 50, 45, 48, 49, 128, 72, 79, 82, 73, 90, - 79, 78, 84, 65, 76, 45, 48, 50, 45, 48, 48, 128, 72, 79, 82, 73, 90, 79, - 78, 84, 65, 76, 45, 48, 49, 45, 48, 54, 128, 72, 79, 82, 73, 90, 79, 78, - 84, 65, 76, 45, 48, 49, 45, 48, 53, 128, 72, 79, 82, 73, 90, 79, 78, 84, - 65, 76, 45, 48, 49, 45, 48, 52, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, - 76, 45, 48, 49, 45, 48, 51, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, - 45, 48, 49, 45, 48, 50, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, - 48, 49, 45, 48, 49, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, - 49, 45, 48, 48, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 48, - 45, 48, 54, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 48, 45, - 48, 53, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 48, 45, 48, - 52, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 48, 45, 48, 51, - 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 48, 45, 48, 50, 128, - 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 48, 45, 48, 49, 128, 72, - 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 48, 45, 48, 48, 128, 72, 79, - 82, 73, 90, 79, 78, 84, 65, 76, 128, 72, 79, 82, 73, 128, 72, 79, 82, - 193, 72, 79, 79, 82, 85, 128, 72, 79, 79, 80, 128, 72, 79, 79, 78, 128, - 72, 79, 79, 75, 69, 196, 72, 79, 78, 69, 89, 66, 69, 69, 128, 72, 79, 78, - 69, 217, 72, 79, 77, 79, 84, 72, 69, 84, 73, 67, 128, 72, 79, 77, 79, 84, - 72, 69, 84, 73, 195, 72, 79, 76, 69, 128, 72, 79, 76, 68, 73, 78, 199, + 74, 85, 68, 69, 79, 45, 83, 80, 65, 78, 73, 83, 200, 74, 79, 89, 83, 84, + 73, 67, 75, 128, 74, 79, 89, 79, 85, 211, 74, 79, 89, 128, 74, 79, 86, + 69, 128, 74, 79, 212, 74, 79, 78, 71, 128, 74, 79, 78, 193, 74, 79, 75, + 69, 82, 128, 74, 79, 73, 78, 69, 68, 128, 74, 79, 73, 78, 128, 74, 79, + 65, 128, 74, 74, 89, 88, 128, 74, 74, 89, 84, 128, 74, 74, 89, 80, 128, + 74, 74, 89, 128, 74, 74, 85, 88, 128, 74, 74, 85, 84, 128, 74, 74, 85, + 82, 88, 128, 74, 74, 85, 82, 128, 74, 74, 85, 80, 128, 74, 74, 85, 79, + 88, 128, 74, 74, 85, 79, 80, 128, 74, 74, 85, 79, 128, 74, 74, 85, 128, + 74, 74, 79, 88, 128, 74, 74, 79, 84, 128, 74, 74, 79, 80, 128, 74, 74, + 79, 128, 74, 74, 73, 88, 128, 74, 74, 73, 84, 128, 74, 74, 73, 80, 128, + 74, 74, 73, 69, 88, 128, 74, 74, 73, 69, 84, 128, 74, 74, 73, 69, 80, + 128, 74, 74, 73, 69, 128, 74, 74, 73, 128, 74, 74, 69, 69, 128, 74, 74, + 69, 128, 74, 74, 65, 128, 74, 73, 76, 128, 74, 73, 73, 128, 74, 73, 72, + 86, 65, 77, 85, 76, 73, 89, 65, 128, 74, 73, 65, 128, 74, 72, 79, 88, + 128, 74, 72, 79, 128, 74, 72, 69, 72, 128, 74, 72, 65, 89, 73, 78, 128, + 74, 72, 65, 78, 128, 74, 72, 65, 77, 128, 74, 72, 65, 65, 128, 74, 72, + 65, 128, 74, 69, 85, 128, 74, 69, 82, 85, 83, 65, 76, 69, 77, 128, 74, + 69, 82, 65, 206, 74, 69, 82, 65, 128, 74, 69, 82, 128, 74, 69, 72, 128, + 74, 69, 200, 74, 69, 71, 79, 71, 65, 78, 128, 74, 69, 69, 77, 128, 74, + 69, 65, 78, 83, 128, 74, 65, 89, 78, 128, 74, 65, 89, 73, 78, 128, 74, + 65, 89, 65, 78, 78, 65, 128, 74, 65, 86, 73, 89, 65, 78, 73, 128, 74, 65, + 85, 128, 74, 65, 82, 128, 74, 65, 80, 65, 78, 69, 83, 197, 74, 65, 80, + 65, 78, 128, 74, 65, 78, 85, 65, 82, 89, 128, 74, 65, 76, 76, 65, 74, 65, + 76, 65, 76, 79, 85, 72, 79, 85, 128, 74, 65, 73, 128, 74, 65, 72, 128, + 74, 65, 68, 69, 128, 74, 65, 67, 75, 83, 128, 74, 65, 67, 75, 45, 79, 45, + 76, 65, 78, 84, 69, 82, 78, 128, 74, 65, 67, 203, 74, 45, 83, 73, 77, 80, + 76, 73, 70, 73, 69, 196, 73, 90, 72, 73, 84, 83, 65, 128, 73, 90, 72, 73, + 84, 83, 193, 73, 90, 72, 69, 128, 73, 90, 65, 75, 65, 89, 193, 73, 89, + 69, 75, 128, 73, 89, 65, 78, 78, 65, 128, 73, 85, 74, 65, 128, 73, 84, + 211, 73, 84, 69, 82, 65, 84, 73, 79, 206, 73, 84, 69, 77, 128, 73, 83, + 83, 72, 65, 82, 128, 73, 83, 79, 83, 67, 69, 76, 69, 211, 73, 83, 79, 78, + 128, 73, 83, 79, 206, 73, 83, 79, 76, 65, 84, 69, 128, 73, 83, 76, 65, + 78, 68, 128, 73, 83, 69, 78, 45, 73, 83, 69, 78, 128, 73, 83, 65, 75, 73, + 193, 73, 83, 45, 80, 73, 76, 76, 65, 128, 73, 82, 85, 89, 65, 78, 78, 65, + 128, 73, 82, 85, 85, 89, 65, 78, 78, 65, 128, 73, 82, 79, 78, 45, 67, 79, + 80, 80, 69, 210, 73, 82, 79, 78, 128, 73, 82, 66, 128, 73, 79, 84, 73, + 70, 73, 69, 196, 73, 79, 84, 65, 84, 69, 196, 73, 79, 84, 65, 128, 73, + 79, 84, 193, 73, 79, 82, 128, 73, 79, 68, 72, 65, 68, 72, 128, 73, 78, + 86, 73, 83, 73, 66, 76, 197, 73, 78, 86, 69, 82, 84, 69, 68, 128, 73, 78, + 86, 69, 82, 84, 69, 196, 73, 78, 86, 69, 82, 83, 197, 73, 78, 84, 82, 79, + 68, 85, 67, 69, 82, 128, 73, 78, 84, 73, 128, 73, 78, 84, 69, 82, 83, 89, + 76, 76, 65, 66, 73, 195, 73, 78, 84, 69, 82, 83, 69, 67, 84, 73, 79, 78, + 128, 73, 78, 84, 69, 82, 83, 69, 67, 84, 73, 79, 206, 73, 78, 84, 69, 82, + 83, 69, 67, 84, 73, 78, 199, 73, 78, 84, 69, 82, 82, 79, 66, 65, 78, 71, + 128, 73, 78, 84, 69, 82, 82, 79, 66, 65, 78, 199, 73, 78, 84, 69, 82, 80, + 79, 76, 65, 84, 73, 79, 206, 73, 78, 84, 69, 82, 76, 79, 67, 75, 69, 196, + 73, 78, 84, 69, 82, 76, 73, 78, 69, 65, 210, 73, 78, 84, 69, 82, 76, 65, + 67, 69, 196, 73, 78, 84, 69, 82, 73, 79, 210, 73, 78, 84, 69, 82, 69, 83, + 212, 73, 78, 84, 69, 82, 67, 65, 76, 65, 84, 69, 128, 73, 78, 84, 69, 71, + 82, 65, 84, 73, 79, 78, 128, 73, 78, 84, 69, 71, 82, 65, 84, 73, 79, 206, + 73, 78, 84, 69, 71, 82, 65, 76, 128, 73, 78, 84, 69, 71, 82, 65, 204, 73, + 78, 83, 85, 76, 65, 210, 73, 78, 83, 84, 82, 85, 77, 69, 78, 84, 65, 204, + 73, 78, 83, 73, 68, 69, 128, 73, 78, 83, 73, 68, 197, 73, 78, 83, 69, 82, + 84, 73, 79, 206, 73, 78, 83, 69, 67, 84, 128, 73, 78, 83, 67, 82, 73, 80, + 84, 73, 79, 78, 65, 204, 73, 78, 80, 85, 212, 73, 78, 78, 79, 67, 69, 78, + 67, 69, 128, 73, 78, 78, 78, 128, 73, 78, 78, 69, 82, 128, 73, 78, 78, + 69, 210, 73, 78, 78, 128, 73, 78, 73, 78, 71, 85, 128, 73, 78, 73, 128, + 73, 78, 72, 73, 66, 73, 212, 73, 78, 72, 69, 82, 69, 78, 212, 73, 78, 71, + 87, 65, 90, 128, 73, 78, 70, 79, 82, 77, 65, 84, 73, 79, 206, 73, 78, 70, + 76, 85, 69, 78, 67, 69, 128, 73, 78, 70, 73, 78, 73, 84, 89, 128, 73, 78, + 70, 73, 78, 73, 84, 217, 73, 78, 68, 85, 83, 84, 82, 73, 65, 204, 73, 78, + 68, 73, 82, 69, 67, 212, 73, 78, 68, 73, 67, 65, 84, 79, 82, 128, 73, 78, + 68, 73, 67, 65, 84, 79, 210, 73, 78, 68, 73, 195, 73, 78, 68, 73, 65, + 206, 73, 78, 68, 69, 88, 128, 73, 78, 68, 69, 216, 73, 78, 68, 69, 80, + 69, 78, 68, 69, 78, 212, 73, 78, 67, 82, 69, 77, 69, 78, 84, 128, 73, 78, + 67, 82, 69, 65, 83, 69, 211, 73, 78, 67, 82, 69, 65, 83, 69, 128, 73, 78, + 67, 82, 69, 65, 83, 197, 73, 78, 67, 79, 77, 80, 76, 69, 84, 197, 73, 78, + 67, 79, 77, 73, 78, 199, 73, 78, 67, 76, 85, 68, 73, 78, 199, 73, 78, 67, + 72, 128, 73, 78, 66, 79, 216, 73, 78, 65, 80, 128, 73, 78, 45, 65, 76, + 65, 70, 128, 73, 77, 80, 69, 82, 73, 65, 204, 73, 77, 80, 69, 82, 70, 69, + 67, 84, 85, 205, 73, 77, 80, 69, 82, 70, 69, 67, 84, 65, 128, 73, 77, 80, + 69, 82, 70, 69, 67, 84, 193, 73, 77, 78, 128, 73, 77, 73, 83, 69, 79, + 211, 73, 77, 73, 78, 51, 128, 73, 77, 73, 78, 128, 73, 77, 73, 206, 73, + 77, 73, 70, 84, 72, 79, 82, 79, 78, 128, 73, 77, 73, 70, 84, 72, 79, 82, + 65, 128, 73, 77, 73, 70, 79, 78, 79, 78, 128, 73, 77, 73, 68, 73, 65, 82, + 71, 79, 78, 128, 73, 77, 65, 71, 197, 73, 76, 85, 89, 65, 78, 78, 65, + 128, 73, 76, 85, 89, 128, 73, 76, 85, 85, 89, 65, 78, 78, 65, 128, 73, + 76, 85, 84, 128, 73, 76, 73, 77, 77, 85, 52, 128, 73, 76, 73, 77, 77, 85, + 51, 128, 73, 76, 73, 77, 77, 85, 128, 73, 76, 73, 77, 77, 213, 73, 76, + 50, 128, 73, 75, 65, 82, 65, 128, 73, 75, 65, 82, 193, 73, 74, 128, 73, + 73, 89, 65, 78, 78, 65, 128, 73, 71, 73, 128, 73, 71, 201, 73, 71, 71, + 87, 83, 128, 73, 70, 73, 78, 128, 73, 69, 85, 78, 71, 45, 84, 73, 75, 69, + 85, 84, 128, 73, 69, 85, 78, 71, 45, 84, 72, 73, 69, 85, 84, 72, 128, 73, + 69, 85, 78, 71, 45, 83, 83, 65, 78, 71, 75, 73, 89, 69, 79, 75, 128, 73, + 69, 85, 78, 71, 45, 82, 73, 69, 85, 76, 128, 73, 69, 85, 78, 71, 45, 80, + 73, 69, 85, 80, 128, 73, 69, 85, 78, 71, 45, 80, 72, 73, 69, 85, 80, 72, + 128, 73, 69, 85, 78, 71, 45, 75, 73, 89, 69, 79, 75, 128, 73, 69, 85, 78, + 71, 45, 75, 72, 73, 69, 85, 75, 72, 128, 73, 69, 85, 78, 71, 45, 67, 73, + 69, 85, 67, 128, 73, 69, 85, 78, 71, 45, 67, 72, 73, 69, 85, 67, 72, 128, + 73, 69, 85, 78, 199, 73, 68, 76, 69, 128, 73, 68, 73, 77, 128, 73, 68, + 73, 205, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, 57, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, 56, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 68, 55, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 68, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 68, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, + 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, 51, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, 50, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 68, 49, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 68, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 67, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, + 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 68, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 67, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 67, 66, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 67, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 67, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, + 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 55, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 54, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 67, 53, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 67, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 67, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, + 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 49, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 48, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 66, 70, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 66, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 66, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, + 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 66, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 65, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 66, 57, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 66, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 66, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, + 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 53, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 52, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 66, 51, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 66, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 66, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, + 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 70, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 69, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 65, 68, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 65, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 65, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, + 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 57, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 56, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 65, 55, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 65, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 65, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, + 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 51, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 50, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 65, 49, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 65, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 57, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, + 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 68, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 67, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 57, 66, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 57, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 57, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, + 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 55, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 54, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 57, 53, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 57, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 57, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, + 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 49, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 48, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 56, 70, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 56, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 56, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, + 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 66, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 65, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 56, 57, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 56, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 56, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, + 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 53, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 52, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 56, 51, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 56, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 56, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, + 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 70, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 69, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 55, 68, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 55, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 55, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, + 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 57, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 56, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 55, 55, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 55, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 55, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, + 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 51, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 50, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 55, 49, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 55, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 54, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, + 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 66, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 65, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 54, 57, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 54, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 54, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, + 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 53, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 52, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 54, 51, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 54, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 54, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, + 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 70, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 69, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 53, 68, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 53, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 53, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, + 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 57, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 56, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 53, 55, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 53, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 53, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, + 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 51, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 50, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 53, 49, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 53, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 52, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, + 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 68, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 67, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 52, 66, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 52, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 52, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, + 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 55, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 54, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 52, 53, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 52, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 52, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, + 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 49, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 48, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 51, 70, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 51, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 51, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, + 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 66, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 65, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 51, 57, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 51, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 51, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, + 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 53, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 52, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 51, 51, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 51, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 51, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, + 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 70, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 69, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 50, 68, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 50, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 50, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, + 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 57, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 56, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 50, 55, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 50, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 50, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, + 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 51, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 50, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 50, 49, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 50, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 49, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, + 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 68, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 67, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 49, 66, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 49, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 49, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, + 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 55, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 54, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 49, 53, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 49, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 49, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, + 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 49, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 48, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 48, 70, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 48, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 48, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, + 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 66, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 65, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 48, 57, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 48, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 48, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, + 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 53, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 52, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 65, 48, 51, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 65, 48, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 65, 48, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, + 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 70, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 69, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 70, 68, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 70, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 70, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, + 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 57, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 56, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 70, 55, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 70, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 70, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, + 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 51, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 50, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 70, 49, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 70, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 69, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, + 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 68, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 67, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 69, 66, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 69, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 69, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, + 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 55, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 54, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 69, 53, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 69, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 69, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, + 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 49, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 48, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 68, 70, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 68, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 68, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, + 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 66, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 65, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 68, 57, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 68, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 68, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, + 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 53, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 52, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 68, 51, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 68, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 68, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, + 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 70, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 69, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 67, 68, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 67, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 67, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, + 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 57, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 56, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 67, 55, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 67, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 67, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, + 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 51, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 50, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 67, 49, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 67, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 66, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, + 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 68, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 67, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 66, 66, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 66, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 66, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, + 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 55, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 54, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 66, 53, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 66, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 66, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, + 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 49, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 48, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 65, 70, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 65, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 65, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, + 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 66, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 65, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 65, 57, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 65, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 65, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, + 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 53, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 52, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 65, 51, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 65, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 65, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, + 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 70, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 69, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 57, 68, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 57, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 57, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, + 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 57, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 56, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 57, 55, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 57, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 57, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, + 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 51, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 50, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 57, 49, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 57, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 56, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, + 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 68, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 67, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 56, 66, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 56, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 56, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, + 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 55, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 54, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 56, 53, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 56, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 56, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, + 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 49, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 48, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 55, 70, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 55, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 55, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, + 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 66, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 65, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 55, 57, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 55, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 55, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, + 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 53, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 52, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 55, 51, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 55, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 55, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, + 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 70, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 69, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 54, 68, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 54, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 54, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, + 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 57, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 56, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 54, 55, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 54, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 54, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, + 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 51, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 50, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 54, 49, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 54, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 53, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, + 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 68, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 67, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 53, 66, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 53, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 53, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, + 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 55, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 54, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 53, 53, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 53, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 53, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, + 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 49, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 48, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 52, 70, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 52, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 52, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, + 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 66, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 65, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 52, 57, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 52, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 52, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, + 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 53, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 52, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 52, 51, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 52, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 52, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, + 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 70, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 69, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 51, 68, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 51, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 51, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, + 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 57, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 56, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 51, 55, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 51, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 51, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, + 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 51, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 50, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 51, 49, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 51, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 50, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, + 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 68, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 67, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 50, 66, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 50, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 50, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, + 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 55, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 54, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 50, 53, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 50, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 50, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, + 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 49, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 48, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 49, 70, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 49, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 49, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, + 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 66, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 65, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 49, 57, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 49, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 49, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, + 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 53, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 52, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 49, 51, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 49, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 49, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, + 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 70, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 69, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 48, 68, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 48, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 48, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, + 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 57, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 56, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 48, 55, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 48, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 70, 57, 48, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, + 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 51, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 50, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 70, 57, 48, 49, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 70, 57, 48, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 57, 48, 52, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 56, 68, 55, + 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 56, 67, 65, 57, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 56, 57, 69, 51, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 55, 68, 52, 50, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 55, 65, 55, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 55, 57, 56, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 55, 54, 68, + 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 55, 53, 51, 51, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 55, 53, 49, 70, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 55, 49, 50, 49, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 55, 48, 66, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 54, 70, 49, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 69, 56, + 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 55, 50, 67, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 55, 48, 57, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 54, 55, 48, 56, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 54, 54, 50, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 54, 53, 66, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 53, 57, + 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 53, 53, 55, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 51, 53, 53, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 54, 51, 48, 55, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 54, 50, 57, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 54, 50, 53, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 50, 52, + 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 70, 56, 67, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 68, 69, 54, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 53, 66, 56, 57, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 53, 66, 53, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 53, 57, 50, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 57, 49, + 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 56, 70, 48, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 53, 66, 54, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 53, 52, 51, 57, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 53, 52, 48, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 53, 51, 70, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 51, 67, + 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 50, 68, 68, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 50, 55, 50, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 53, 50, 52, 68, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 53, 50, 49, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 53, 49, 56, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 52, 69, 65, + 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 52, 69, 56, 67, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 52, 69, 50, 68, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 52, 69, 48, 57, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 52, 69, 48, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 65, 49, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 65, 49, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, + 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 65, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 57, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 56, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 55, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 65, 49, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 65, 49, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 65, 49, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 65, 49, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, + 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 49, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 48, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 70, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 69, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 65, 48, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 65, 48, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 65, 48, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 65, 48, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, + 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 56, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 55, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 54, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 53, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 65, 48, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 65, 48, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 65, 48, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 65, 48, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, + 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 70, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 69, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 68, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 67, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 57, 70, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 57, 70, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 57, 70, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 57, 70, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, + 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 54, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 53, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 52, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 51, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 57, 70, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 57, 70, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 57, 70, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 57, 69, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, + 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 68, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 67, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 66, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 65, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 57, 69, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 57, 69, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 57, 69, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 57, 69, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, + 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 52, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 51, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 50, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 49, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 57, 69, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 57, 68, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 57, 68, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 57, 68, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, + 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 66, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 65, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 57, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 56, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 57, 68, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 57, 68, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 57, 68, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 57, 68, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, + 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 50, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 49, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 48, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 70, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 57, 67, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 57, 67, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 57, 67, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 57, 67, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, + 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 57, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 56, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 55, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 54, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 57, 67, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 57, 67, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 57, 67, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 57, 67, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, + 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 48, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 70, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 69, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 68, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 57, 66, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 57, 66, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 57, 66, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 57, 66, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, + 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 55, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 54, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 53, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 52, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 57, 66, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 57, 66, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 57, 66, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 57, 66, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, + 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 69, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 68, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 67, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 66, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 57, 65, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 57, 65, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 57, 65, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 57, 65, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, + 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 53, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 52, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 51, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 50, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 57, 65, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 57, 65, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 57, 57, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 57, 57, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, + 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 67, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 66, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 65, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 57, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 57, 57, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 57, 57, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 57, 57, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 57, 57, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, + 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 51, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 50, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 49, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 48, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 57, 56, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 57, 56, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 57, 56, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 57, 56, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, + 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 65, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 57, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 56, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 55, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 57, 56, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 57, 56, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 57, 56, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 57, 56, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, + 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 49, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 48, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 70, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 69, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 57, 55, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 57, 55, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 57, 55, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 57, 55, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, + 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 56, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 55, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 54, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 53, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 57, 55, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 57, 55, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 57, 55, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 57, 55, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, + 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 70, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 69, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 68, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 67, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 57, 54, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 57, 54, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 57, 54, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 57, 54, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, + 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 54, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 53, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 52, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 51, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 57, 54, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 57, 54, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 57, 54, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 57, 53, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, + 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 68, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 67, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 66, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 65, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 57, 53, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 57, 53, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 57, 53, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 57, 53, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, + 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 52, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 51, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 50, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 49, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 57, 53, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 57, 52, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 57, 52, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 57, 52, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, + 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 66, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 65, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 57, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 56, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 57, 52, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 57, 52, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 57, 52, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 57, 52, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, + 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 50, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 49, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 48, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 70, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 57, 51, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 57, 51, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 57, 51, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 57, 51, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, + 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 57, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 56, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 55, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 54, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 57, 51, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 57, 51, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 57, 51, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 57, 51, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, + 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 48, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 70, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 69, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 68, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 57, 50, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 57, 50, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 57, 50, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 57, 50, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, + 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 55, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 54, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 53, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 52, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 57, 50, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 57, 50, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 57, 50, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 57, 50, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, + 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 69, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 68, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 67, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 66, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 57, 49, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 57, 49, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 57, 49, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 57, 49, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, + 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 53, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 52, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 51, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 50, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 57, 49, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 57, 49, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 57, 48, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 57, 48, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, + 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 67, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 66, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 65, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 57, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 57, 48, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 57, 48, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 57, 48, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 57, 48, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, + 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 51, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 50, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 49, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 48, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 56, 70, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 56, 70, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 56, 70, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 56, 70, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, + 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 65, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 57, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 56, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 55, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 56, 70, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 56, 70, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 56, 70, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 56, 70, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, + 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 49, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 48, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 70, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 69, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 56, 69, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 56, 69, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 56, 69, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 56, 69, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, + 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 56, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 55, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 54, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 53, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 56, 69, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 56, 69, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 56, 69, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 56, 69, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, + 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 70, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 69, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 68, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 67, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 56, 68, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 56, 68, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 56, 68, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 56, 68, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, + 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 54, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 53, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 52, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 51, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 56, 68, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 56, 68, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 56, 68, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 56, 67, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, + 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 68, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 67, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 66, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 65, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 56, 67, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 56, 67, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 56, 67, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 56, 67, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, + 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 52, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 51, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 50, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 49, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 56, 67, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 56, 66, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 56, 66, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 56, 66, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, + 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 66, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 65, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 57, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 56, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 56, 66, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 56, 66, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 56, 66, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 56, 66, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, + 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 50, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 49, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 48, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 70, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 56, 65, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 56, 65, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 56, 65, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 56, 65, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, + 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 57, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 56, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 55, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 54, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 56, 65, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 56, 65, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 56, 65, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 56, 65, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, + 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 48, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 70, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 69, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 68, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 56, 57, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 56, 57, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 56, 57, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 56, 57, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, + 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 55, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 54, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 53, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 52, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 56, 57, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 56, 57, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 56, 57, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 56, 57, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, + 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 69, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 68, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 67, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 66, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 56, 56, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 56, 56, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 56, 56, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 56, 56, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, + 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 53, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 52, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 51, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 50, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 56, 56, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 56, 56, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 56, 55, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 56, 55, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, + 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 67, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 66, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 65, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 57, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 56, 55, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 56, 55, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 56, 55, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 56, 55, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, + 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 51, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 50, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 49, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 48, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 56, 54, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 56, 54, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 56, 54, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 56, 54, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, + 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 65, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 57, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 56, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 55, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 56, 54, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 56, 54, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 56, 54, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 56, 54, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, + 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 49, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 48, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 70, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 69, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 56, 53, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 56, 53, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 56, 53, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 56, 53, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, + 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 56, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 55, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 54, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 53, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 56, 53, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 56, 53, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 56, 53, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 56, 53, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, + 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 70, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 69, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 68, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 67, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 56, 52, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 56, 52, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 56, 52, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 56, 52, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, + 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 54, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 53, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 52, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 51, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 56, 52, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 56, 52, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 56, 52, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 56, 51, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, + 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 68, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 67, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 66, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 65, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 56, 51, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 56, 51, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 56, 51, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 56, 51, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, + 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 52, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 51, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 50, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 49, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 56, 51, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 56, 50, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 56, 50, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 56, 50, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, + 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 66, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 65, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 57, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 56, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 56, 50, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 56, 50, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 56, 50, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 56, 50, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, + 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 50, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 49, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 48, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 70, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 56, 49, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 56, 49, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 56, 49, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 56, 49, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, + 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 57, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 56, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 55, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 54, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 56, 49, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 56, 49, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 56, 49, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 56, 49, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, + 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 48, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 70, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 69, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 68, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 56, 48, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 56, 48, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 56, 48, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 56, 48, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, + 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 55, 128, + 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 54, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 53, 128, 73, 68, 69, 79, + 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 52, 128, 73, 68, 69, 79, 71, 82, + 65, 80, 72, 45, 50, 70, 56, 48, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 50, 70, 56, 48, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, + 50, 70, 56, 48, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, + 56, 48, 48, 128, 73, 68, 69, 78, 84, 73, 70, 73, 67, 65, 84, 73, 79, 78, + 128, 73, 68, 69, 78, 84, 73, 67, 65, 204, 73, 67, 79, 78, 128, 73, 67, + 72, 79, 85, 128, 73, 67, 72, 79, 83, 128, 73, 67, 72, 73, 77, 65, 84, 79, + 83, 128, 73, 67, 72, 65, 68, 73, 78, 128, 73, 67, 69, 76, 65, 78, 68, 73, + 67, 45, 89, 82, 128, 73, 66, 73, 70, 73, 76, 73, 128, 73, 65, 85, 68, 65, + 128, 73, 48, 49, 53, 128, 73, 48, 49, 52, 128, 73, 48, 49, 51, 128, 73, + 48, 49, 50, 128, 73, 48, 49, 49, 65, 128, 73, 48, 49, 49, 128, 73, 48, + 49, 48, 65, 128, 73, 48, 49, 48, 128, 73, 48, 48, 57, 65, 128, 73, 48, + 48, 57, 128, 73, 48, 48, 56, 128, 73, 48, 48, 55, 128, 73, 48, 48, 54, + 128, 73, 48, 48, 53, 65, 128, 73, 48, 48, 53, 128, 73, 48, 48, 52, 128, + 73, 48, 48, 51, 128, 73, 48, 48, 50, 128, 73, 48, 48, 49, 128, 73, 45, + 89, 85, 128, 73, 45, 89, 79, 128, 73, 45, 89, 69, 79, 128, 73, 45, 89, + 69, 128, 73, 45, 89, 65, 69, 128, 73, 45, 89, 65, 45, 79, 128, 73, 45, + 89, 65, 128, 73, 45, 79, 45, 73, 128, 73, 45, 79, 128, 73, 45, 69, 85, + 128, 73, 45, 66, 69, 65, 77, 128, 73, 45, 65, 82, 65, 69, 65, 128, 73, + 45, 65, 128, 72, 90, 90, 90, 71, 128, 72, 90, 90, 90, 128, 72, 90, 90, + 80, 128, 72, 90, 90, 128, 72, 90, 87, 71, 128, 72, 90, 87, 128, 72, 90, + 84, 128, 72, 90, 71, 128, 72, 89, 83, 84, 69, 82, 69, 83, 73, 211, 72, + 89, 80, 79, 68, 73, 65, 83, 84, 79, 76, 69, 128, 72, 89, 80, 72, 69, 78, + 65, 84, 73, 79, 206, 72, 89, 80, 72, 69, 78, 45, 77, 73, 78, 85, 83, 128, + 72, 89, 80, 72, 69, 78, 128, 72, 89, 80, 72, 69, 206, 72, 88, 87, 71, + 128, 72, 88, 85, 79, 88, 128, 72, 88, 85, 79, 84, 128, 72, 88, 85, 79, + 80, 128, 72, 88, 85, 79, 128, 72, 88, 79, 88, 128, 72, 88, 79, 84, 128, + 72, 88, 79, 80, 128, 72, 88, 79, 128, 72, 88, 73, 88, 128, 72, 88, 73, + 84, 128, 72, 88, 73, 80, 128, 72, 88, 73, 69, 88, 128, 72, 88, 73, 69, + 84, 128, 72, 88, 73, 69, 80, 128, 72, 88, 73, 69, 128, 72, 88, 73, 128, + 72, 88, 69, 88, 128, 72, 88, 69, 80, 128, 72, 88, 69, 128, 72, 88, 65, + 88, 128, 72, 88, 65, 84, 128, 72, 88, 65, 80, 128, 72, 88, 65, 128, 72, + 87, 85, 128, 72, 87, 65, 73, 82, 128, 72, 87, 65, 72, 128, 72, 86, 128, + 72, 85, 86, 65, 128, 72, 85, 83, 72, 69, 196, 72, 85, 83, 72, 128, 72, + 85, 82, 65, 78, 128, 72, 85, 79, 84, 128, 72, 85, 78, 68, 82, 69, 68, 83, + 128, 72, 85, 78, 68, 82, 69, 68, 128, 72, 85, 78, 68, 82, 69, 196, 72, + 85, 78, 128, 72, 85, 77, 65, 78, 128, 72, 85, 77, 65, 206, 72, 85, 76, + 50, 128, 72, 85, 73, 73, 84, 79, 128, 72, 85, 66, 50, 128, 72, 85, 66, + 178, 72, 85, 66, 128, 72, 85, 65, 82, 65, 68, 68, 79, 128, 72, 85, 65, + 78, 128, 72, 84, 83, 128, 72, 84, 74, 128, 72, 82, 89, 86, 78, 73, 193, + 72, 80, 87, 71, 128, 72, 80, 65, 128, 72, 80, 128, 72, 79, 85, 83, 197, + 72, 79, 85, 82, 71, 76, 65, 83, 83, 128, 72, 79, 85, 82, 71, 76, 65, 83, + 211, 72, 79, 85, 82, 128, 72, 79, 85, 210, 72, 79, 84, 69, 76, 128, 72, + 79, 84, 65, 128, 72, 79, 83, 80, 73, 84, 65, 76, 128, 72, 79, 82, 83, 69, + 128, 72, 79, 82, 83, 197, 72, 79, 82, 82, 128, 72, 79, 82, 78, 83, 128, + 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 76, 217, 72, 79, 82, 73, 90, 79, + 78, 84, 65, 76, 45, 48, 54, 45, 48, 54, 128, 72, 79, 82, 73, 90, 79, 78, + 84, 65, 76, 45, 48, 54, 45, 48, 53, 128, 72, 79, 82, 73, 90, 79, 78, 84, + 65, 76, 45, 48, 54, 45, 48, 52, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, + 76, 45, 48, 54, 45, 48, 51, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, + 45, 48, 54, 45, 48, 50, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, + 48, 54, 45, 48, 49, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, + 54, 45, 48, 48, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 53, + 45, 48, 54, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 53, 45, + 48, 53, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 53, 45, 48, + 52, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 53, 45, 48, 51, + 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 53, 45, 48, 50, 128, + 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 53, 45, 48, 49, 128, 72, + 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 53, 45, 48, 48, 128, 72, 79, + 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 52, 45, 48, 54, 128, 72, 79, 82, + 73, 90, 79, 78, 84, 65, 76, 45, 48, 52, 45, 48, 53, 128, 72, 79, 82, 73, + 90, 79, 78, 84, 65, 76, 45, 48, 52, 45, 48, 52, 128, 72, 79, 82, 73, 90, + 79, 78, 84, 65, 76, 45, 48, 52, 45, 48, 51, 128, 72, 79, 82, 73, 90, 79, + 78, 84, 65, 76, 45, 48, 52, 45, 48, 50, 128, 72, 79, 82, 73, 90, 79, 78, + 84, 65, 76, 45, 48, 52, 45, 48, 49, 128, 72, 79, 82, 73, 90, 79, 78, 84, + 65, 76, 45, 48, 52, 45, 48, 48, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, + 76, 45, 48, 51, 45, 48, 54, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, + 45, 48, 51, 45, 48, 53, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, + 48, 51, 45, 48, 52, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, + 51, 45, 48, 51, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 51, + 45, 48, 50, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 51, 45, + 48, 49, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 51, 45, 48, + 48, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 50, 45, 48, 54, + 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 50, 45, 48, 53, 128, + 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 50, 45, 48, 52, 128, 72, + 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 50, 45, 48, 51, 128, 72, 79, + 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 50, 45, 48, 50, 128, 72, 79, 82, + 73, 90, 79, 78, 84, 65, 76, 45, 48, 50, 45, 48, 49, 128, 72, 79, 82, 73, + 90, 79, 78, 84, 65, 76, 45, 48, 50, 45, 48, 48, 128, 72, 79, 82, 73, 90, + 79, 78, 84, 65, 76, 45, 48, 49, 45, 48, 54, 128, 72, 79, 82, 73, 90, 79, + 78, 84, 65, 76, 45, 48, 49, 45, 48, 53, 128, 72, 79, 82, 73, 90, 79, 78, + 84, 65, 76, 45, 48, 49, 45, 48, 52, 128, 72, 79, 82, 73, 90, 79, 78, 84, + 65, 76, 45, 48, 49, 45, 48, 51, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, + 76, 45, 48, 49, 45, 48, 50, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, + 45, 48, 49, 45, 48, 49, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, + 48, 49, 45, 48, 48, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, + 48, 45, 48, 54, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 48, + 45, 48, 53, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 48, 45, + 48, 52, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 48, 45, 48, + 51, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 48, 45, 48, 50, + 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 48, 45, 48, 49, 128, + 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 48, 45, 48, 48, 128, 72, + 79, 82, 73, 90, 79, 78, 84, 65, 76, 128, 72, 79, 82, 73, 128, 72, 79, 82, + 193, 72, 79, 79, 85, 128, 72, 79, 79, 82, 85, 128, 72, 79, 79, 80, 128, + 72, 79, 79, 78, 128, 72, 79, 79, 75, 69, 196, 72, 79, 78, 69, 89, 66, 69, + 69, 128, 72, 79, 78, 69, 217, 72, 79, 77, 79, 84, 72, 69, 84, 73, 67, + 128, 72, 79, 77, 79, 84, 72, 69, 84, 73, 195, 72, 79, 76, 79, 128, 72, + 79, 76, 76, 79, 215, 72, 79, 76, 69, 128, 72, 79, 76, 68, 73, 78, 199, 72, 79, 76, 65, 77, 128, 72, 79, 76, 65, 205, 72, 79, 75, 65, 128, 72, - 79, 73, 128, 72, 79, 67, 72, 79, 128, 72, 78, 85, 84, 128, 72, 78, 85, - 79, 88, 128, 72, 78, 85, 79, 128, 72, 78, 79, 88, 128, 72, 78, 79, 84, - 128, 72, 78, 79, 80, 128, 72, 78, 73, 88, 128, 72, 78, 73, 84, 128, 72, - 78, 73, 80, 128, 72, 78, 73, 69, 88, 128, 72, 78, 73, 69, 84, 128, 72, - 78, 73, 69, 80, 128, 72, 78, 73, 69, 128, 72, 78, 73, 128, 72, 78, 69, - 88, 128, 72, 78, 69, 80, 128, 72, 78, 69, 128, 72, 78, 65, 88, 128, 72, - 78, 65, 84, 128, 72, 78, 65, 80, 128, 72, 78, 65, 128, 72, 77, 89, 88, - 128, 72, 77, 89, 82, 88, 128, 72, 77, 89, 82, 128, 72, 77, 89, 80, 128, - 72, 77, 89, 128, 72, 77, 85, 88, 128, 72, 77, 85, 84, 128, 72, 77, 85, - 82, 88, 128, 72, 77, 85, 82, 128, 72, 77, 85, 80, 128, 72, 77, 85, 79, - 88, 128, 72, 77, 85, 79, 80, 128, 72, 77, 85, 79, 128, 72, 77, 85, 128, - 72, 77, 79, 88, 128, 72, 77, 79, 84, 128, 72, 77, 79, 80, 128, 72, 77, - 79, 128, 72, 77, 73, 88, 128, 72, 77, 73, 84, 128, 72, 77, 73, 80, 128, - 72, 77, 73, 69, 88, 128, 72, 77, 73, 69, 80, 128, 72, 77, 73, 69, 128, - 72, 77, 73, 128, 72, 77, 69, 128, 72, 77, 65, 88, 128, 72, 77, 65, 84, - 128, 72, 77, 65, 80, 128, 72, 77, 65, 128, 72, 76, 89, 88, 128, 72, 76, - 89, 84, 128, 72, 76, 89, 82, 88, 128, 72, 76, 89, 82, 128, 72, 76, 89, - 80, 128, 72, 76, 89, 128, 72, 76, 85, 88, 128, 72, 76, 85, 84, 128, 72, - 76, 85, 82, 88, 128, 72, 76, 85, 82, 128, 72, 76, 85, 80, 128, 72, 76, - 85, 79, 88, 128, 72, 76, 85, 79, 80, 128, 72, 76, 85, 79, 128, 72, 76, - 85, 128, 72, 76, 79, 88, 128, 72, 76, 79, 80, 128, 72, 76, 79, 128, 72, - 76, 73, 88, 128, 72, 76, 73, 84, 128, 72, 76, 73, 80, 128, 72, 76, 73, - 69, 88, 128, 72, 76, 73, 69, 80, 128, 72, 76, 73, 69, 128, 72, 76, 73, - 128, 72, 76, 69, 88, 128, 72, 76, 69, 80, 128, 72, 76, 69, 128, 72, 76, - 65, 88, 128, 72, 76, 65, 84, 128, 72, 76, 65, 80, 128, 72, 76, 65, 128, - 72, 75, 128, 72, 73, 90, 66, 128, 72, 73, 83, 84, 79, 82, 73, 195, 72, - 73, 82, 73, 81, 128, 72, 73, 71, 72, 45, 83, 80, 69, 69, 196, 72, 73, 71, - 72, 45, 82, 69, 86, 69, 82, 83, 69, 68, 45, 185, 72, 73, 71, 72, 45, 72, - 69, 69, 76, 69, 196, 72, 73, 69, 88, 128, 72, 73, 69, 85, 72, 45, 83, 73, - 79, 83, 128, 72, 73, 69, 85, 72, 45, 82, 73, 69, 85, 76, 128, 72, 73, 69, - 85, 72, 45, 80, 73, 69, 85, 80, 128, 72, 73, 69, 85, 72, 45, 78, 73, 69, - 85, 78, 128, 72, 73, 69, 85, 72, 45, 77, 73, 69, 85, 77, 128, 72, 73, 69, - 85, 200, 72, 73, 69, 82, 79, 71, 76, 89, 80, 72, 73, 195, 72, 73, 69, - 128, 72, 73, 68, 73, 78, 199, 72, 73, 68, 69, 84, 128, 72, 73, 68, 69, - 128, 72, 73, 66, 73, 83, 67, 85, 83, 128, 72, 72, 87, 65, 128, 72, 72, - 85, 128, 72, 72, 73, 128, 72, 72, 69, 69, 128, 72, 72, 69, 128, 72, 72, - 65, 65, 128, 72, 71, 128, 72, 69, 88, 73, 70, 79, 82, 205, 72, 69, 88, - 65, 71, 82, 65, 205, 72, 69, 88, 65, 71, 79, 78, 128, 72, 69, 82, 85, 84, - 85, 128, 72, 69, 82, 85, 128, 72, 69, 82, 77, 73, 84, 73, 65, 206, 72, - 69, 82, 77, 73, 79, 78, 73, 65, 206, 72, 69, 82, 77, 69, 83, 128, 72, 69, - 82, 69, 128, 72, 69, 82, 66, 128, 72, 69, 82, 65, 69, 85, 205, 72, 69, - 78, 71, 128, 72, 69, 78, 199, 72, 69, 77, 80, 128, 72, 69, 76, 77, 69, - 84, 128, 72, 69, 76, 77, 69, 212, 72, 69, 76, 205, 72, 69, 76, 73, 67, - 79, 80, 84, 69, 82, 128, 72, 69, 75, 85, 84, 65, 65, 82, 85, 128, 72, 69, - 73, 83, 69, 73, 128, 72, 69, 65, 86, 89, 128, 72, 69, 65, 86, 69, 78, 76, - 217, 72, 69, 65, 86, 69, 78, 128, 72, 69, 65, 86, 69, 206, 72, 69, 65, - 82, 84, 83, 128, 72, 69, 65, 82, 84, 45, 83, 72, 65, 80, 69, 196, 72, 69, - 65, 82, 84, 128, 72, 69, 65, 82, 212, 72, 69, 65, 82, 45, 78, 79, 45, 69, - 86, 73, 204, 72, 69, 65, 68, 83, 84, 82, 79, 75, 69, 128, 72, 69, 65, 68, - 83, 84, 79, 78, 197, 72, 69, 65, 68, 80, 72, 79, 78, 69, 128, 72, 69, 65, - 68, 73, 78, 71, 128, 72, 66, 65, 83, 65, 45, 69, 83, 65, 83, 193, 72, 66, - 65, 83, 193, 72, 65, 89, 65, 78, 78, 65, 128, 72, 65, 86, 69, 128, 72, - 65, 85, 80, 84, 83, 84, 73, 77, 77, 69, 128, 72, 65, 84, 72, 73, 128, 72, - 65, 84, 69, 128, 72, 65, 84, 67, 72, 73, 78, 199, 72, 65, 84, 65, 198, - 72, 65, 83, 69, 210, 72, 65, 83, 65, 78, 84, 65, 128, 72, 65, 82, 80, 79, - 79, 78, 128, 72, 65, 82, 80, 79, 79, 206, 72, 65, 82, 77, 79, 78, 73, 67, - 128, 72, 65, 82, 75, 76, 69, 65, 206, 72, 65, 82, 68, 78, 69, 83, 83, - 128, 72, 65, 82, 196, 72, 65, 80, 80, 217, 72, 65, 78, 85, 78, 79, 207, - 72, 65, 78, 71, 90, 72, 79, 213, 72, 65, 78, 68, 83, 128, 72, 65, 78, 68, - 211, 72, 65, 78, 68, 76, 69, 83, 128, 72, 65, 78, 68, 76, 69, 128, 72, - 65, 78, 68, 66, 65, 71, 128, 72, 65, 78, 68, 128, 72, 65, 78, 45, 65, 75, - 65, 84, 128, 72, 65, 77, 90, 65, 128, 72, 65, 77, 83, 84, 69, 210, 72, + 79, 67, 72, 79, 128, 72, 78, 85, 84, 128, 72, 78, 85, 79, 88, 128, 72, + 78, 85, 79, 128, 72, 78, 85, 66, 128, 72, 78, 79, 88, 128, 72, 78, 79, + 84, 128, 72, 78, 79, 80, 128, 72, 78, 73, 88, 128, 72, 78, 73, 84, 128, + 72, 78, 73, 80, 128, 72, 78, 73, 69, 88, 128, 72, 78, 73, 69, 84, 128, + 72, 78, 73, 69, 80, 128, 72, 78, 73, 69, 128, 72, 78, 73, 128, 72, 78, + 69, 88, 128, 72, 78, 69, 80, 128, 72, 78, 69, 128, 72, 78, 65, 88, 128, + 72, 78, 65, 85, 128, 72, 78, 65, 84, 128, 72, 78, 65, 80, 128, 72, 78, + 65, 128, 72, 77, 89, 88, 128, 72, 77, 89, 82, 88, 128, 72, 77, 89, 82, + 128, 72, 77, 89, 80, 128, 72, 77, 89, 128, 72, 77, 85, 88, 128, 72, 77, + 85, 84, 128, 72, 77, 85, 82, 88, 128, 72, 77, 85, 82, 128, 72, 77, 85, + 80, 128, 72, 77, 85, 79, 88, 128, 72, 77, 85, 79, 80, 128, 72, 77, 85, + 79, 128, 72, 77, 85, 128, 72, 77, 79, 88, 128, 72, 77, 79, 84, 128, 72, + 77, 79, 80, 128, 72, 77, 79, 128, 72, 77, 73, 88, 128, 72, 77, 73, 84, + 128, 72, 77, 73, 80, 128, 72, 77, 73, 69, 88, 128, 72, 77, 73, 69, 80, + 128, 72, 77, 73, 69, 128, 72, 77, 73, 128, 72, 77, 69, 128, 72, 77, 65, + 88, 128, 72, 77, 65, 84, 128, 72, 77, 65, 80, 128, 72, 77, 65, 128, 72, + 76, 89, 88, 128, 72, 76, 89, 84, 128, 72, 76, 89, 82, 88, 128, 72, 76, + 89, 82, 128, 72, 76, 89, 80, 128, 72, 76, 89, 128, 72, 76, 85, 88, 128, + 72, 76, 85, 84, 128, 72, 76, 85, 82, 88, 128, 72, 76, 85, 82, 128, 72, + 76, 85, 80, 128, 72, 76, 85, 79, 88, 128, 72, 76, 85, 79, 80, 128, 72, + 76, 85, 79, 128, 72, 76, 85, 128, 72, 76, 79, 88, 128, 72, 76, 79, 80, + 128, 72, 76, 79, 128, 72, 76, 73, 88, 128, 72, 76, 73, 84, 128, 72, 76, + 73, 80, 128, 72, 76, 73, 69, 88, 128, 72, 76, 73, 69, 80, 128, 72, 76, + 73, 69, 128, 72, 76, 73, 128, 72, 76, 69, 88, 128, 72, 76, 69, 80, 128, + 72, 76, 69, 128, 72, 76, 65, 88, 128, 72, 76, 65, 85, 128, 72, 76, 65, + 84, 128, 72, 76, 65, 80, 128, 72, 76, 65, 128, 72, 76, 128, 72, 75, 128, + 72, 73, 90, 66, 128, 72, 73, 89, 79, 128, 72, 73, 83, 84, 79, 82, 73, + 195, 72, 73, 82, 73, 81, 128, 72, 73, 71, 72, 45, 83, 80, 69, 69, 196, + 72, 73, 71, 72, 45, 82, 69, 86, 69, 82, 83, 69, 68, 45, 185, 72, 73, 71, + 72, 45, 76, 79, 215, 72, 73, 71, 72, 45, 72, 69, 69, 76, 69, 196, 72, 73, + 69, 88, 128, 72, 73, 69, 85, 72, 45, 83, 73, 79, 83, 128, 72, 73, 69, 85, + 72, 45, 82, 73, 69, 85, 76, 128, 72, 73, 69, 85, 72, 45, 80, 73, 69, 85, + 80, 128, 72, 73, 69, 85, 72, 45, 78, 73, 69, 85, 78, 128, 72, 73, 69, 85, + 72, 45, 77, 73, 69, 85, 77, 128, 72, 73, 69, 85, 200, 72, 73, 69, 82, 79, + 71, 76, 89, 80, 72, 73, 195, 72, 73, 69, 128, 72, 73, 68, 73, 78, 199, + 72, 73, 68, 69, 84, 128, 72, 73, 68, 69, 128, 72, 73, 66, 73, 83, 67, 85, + 83, 128, 72, 72, 87, 65, 128, 72, 72, 85, 128, 72, 72, 73, 128, 72, 72, + 69, 69, 128, 72, 72, 69, 128, 72, 72, 65, 65, 128, 72, 71, 128, 72, 69, + 89, 84, 128, 72, 69, 88, 73, 70, 79, 82, 205, 72, 69, 88, 65, 71, 82, 65, + 205, 72, 69, 88, 65, 71, 79, 78, 128, 72, 69, 82, 85, 84, 85, 128, 72, + 69, 82, 85, 128, 72, 69, 82, 77, 73, 84, 73, 65, 206, 72, 69, 82, 77, 73, + 79, 78, 73, 65, 206, 72, 69, 82, 77, 69, 83, 128, 72, 69, 82, 69, 128, + 72, 69, 82, 66, 128, 72, 69, 82, 65, 69, 85, 205, 72, 69, 78, 71, 128, + 72, 69, 78, 199, 72, 69, 77, 80, 128, 72, 69, 76, 77, 69, 84, 128, 72, + 69, 76, 77, 69, 212, 72, 69, 76, 205, 72, 69, 76, 73, 67, 79, 80, 84, 69, + 82, 128, 72, 69, 75, 85, 84, 65, 65, 82, 85, 128, 72, 69, 73, 83, 69, 73, + 128, 72, 69, 69, 73, 128, 72, 69, 65, 86, 89, 128, 72, 69, 65, 86, 69, + 78, 76, 217, 72, 69, 65, 86, 69, 78, 128, 72, 69, 65, 86, 69, 206, 72, + 69, 65, 82, 84, 83, 128, 72, 69, 65, 82, 84, 45, 83, 72, 65, 80, 69, 196, + 72, 69, 65, 82, 84, 128, 72, 69, 65, 82, 212, 72, 69, 65, 82, 45, 78, 79, + 45, 69, 86, 73, 204, 72, 69, 65, 68, 83, 84, 82, 79, 75, 69, 128, 72, 69, + 65, 68, 83, 84, 79, 78, 197, 72, 69, 65, 68, 80, 72, 79, 78, 69, 128, 72, + 69, 65, 68, 73, 78, 71, 128, 72, 66, 65, 83, 65, 45, 69, 83, 65, 83, 193, + 72, 66, 65, 83, 193, 72, 65, 89, 65, 78, 78, 65, 128, 72, 65, 87, 74, + 128, 72, 65, 86, 69, 128, 72, 65, 85, 80, 84, 83, 84, 73, 77, 77, 69, + 128, 72, 65, 213, 72, 65, 84, 72, 73, 128, 72, 65, 84, 69, 128, 72, 65, + 84, 67, 72, 73, 78, 199, 72, 65, 84, 65, 198, 72, 65, 83, 69, 210, 72, + 65, 83, 65, 78, 84, 65, 128, 72, 65, 82, 80, 79, 79, 78, 128, 72, 65, 82, + 80, 79, 79, 206, 72, 65, 82, 77, 79, 78, 73, 67, 128, 72, 65, 82, 75, 76, + 69, 65, 206, 72, 65, 82, 68, 78, 69, 83, 83, 128, 72, 65, 82, 196, 72, + 65, 80, 80, 217, 72, 65, 78, 85, 78, 79, 207, 72, 65, 78, 71, 90, 72, 79, + 213, 72, 65, 78, 68, 83, 128, 72, 65, 78, 68, 211, 72, 65, 78, 68, 76, + 69, 83, 128, 72, 65, 78, 68, 76, 69, 128, 72, 65, 78, 68, 66, 65, 71, + 128, 72, 65, 78, 68, 128, 72, 65, 78, 45, 65, 75, 65, 84, 128, 72, 65, + 77, 90, 65, 128, 72, 65, 77, 90, 193, 72, 65, 77, 83, 84, 69, 210, 72, 65, 77, 77, 69, 82, 128, 72, 65, 77, 77, 69, 210, 72, 65, 77, 66, 85, 82, 71, 69, 82, 128, 72, 65, 76, 81, 65, 128, 72, 65, 76, 79, 128, 72, 65, 76, 70, 45, 67, 73, 82, 67, 76, 197, 72, 65, 76, 70, 128, 72, 65, 76, 66, 69, 82, 68, 128, 72, 65, 76, 65, 78, 84, 65, 128, 72, 65, 73, 84, 85, - 128, 72, 65, 73, 82, 67, 85, 84, 128, 72, 65, 73, 82, 128, 72, 65, 71, - 76, 65, 218, 72, 65, 71, 76, 128, 72, 65, 70, 85, 75, 72, 65, 128, 72, - 65, 70, 85, 75, 72, 128, 72, 65, 69, 71, 204, 72, 65, 65, 82, 85, 128, - 72, 65, 65, 77, 128, 72, 65, 193, 72, 65, 45, 72, 65, 128, 72, 48, 48, - 56, 128, 72, 48, 48, 55, 128, 72, 48, 48, 54, 65, 128, 72, 48, 48, 54, - 128, 72, 48, 48, 53, 128, 72, 48, 48, 52, 128, 72, 48, 48, 51, 128, 72, - 48, 48, 50, 128, 72, 48, 48, 49, 128, 72, 45, 84, 89, 80, 197, 71, 89, - 85, 128, 71, 89, 79, 78, 128, 71, 89, 79, 128, 71, 89, 73, 128, 71, 89, - 70, 213, 71, 89, 69, 69, 128, 71, 89, 65, 83, 128, 71, 89, 65, 65, 128, - 71, 89, 65, 128, 71, 89, 128, 71, 87, 85, 128, 71, 87, 73, 128, 71, 87, - 69, 69, 128, 71, 87, 69, 128, 71, 87, 65, 65, 128, 71, 87, 65, 128, 71, - 86, 128, 71, 85, 82, 85, 83, 72, 128, 71, 85, 82, 85, 78, 128, 71, 85, - 82, 65, 77, 85, 84, 79, 78, 128, 71, 85, 82, 55, 128, 71, 85, 78, 85, + 128, 72, 65, 73, 211, 72, 65, 73, 82, 67, 85, 84, 128, 72, 65, 73, 82, + 128, 72, 65, 71, 76, 65, 218, 72, 65, 71, 76, 128, 72, 65, 70, 85, 75, + 72, 65, 128, 72, 65, 70, 85, 75, 72, 128, 72, 65, 69, 71, 204, 72, 65, + 65, 82, 85, 128, 72, 65, 65, 77, 128, 72, 65, 193, 72, 65, 45, 72, 65, + 128, 72, 48, 48, 56, 128, 72, 48, 48, 55, 128, 72, 48, 48, 54, 65, 128, + 72, 48, 48, 54, 128, 72, 48, 48, 53, 128, 72, 48, 48, 52, 128, 72, 48, + 48, 51, 128, 72, 48, 48, 50, 128, 72, 48, 48, 49, 128, 72, 45, 84, 89, + 80, 197, 71, 89, 85, 128, 71, 89, 79, 78, 128, 71, 89, 79, 128, 71, 89, + 73, 128, 71, 89, 70, 213, 71, 89, 69, 69, 128, 71, 89, 65, 83, 128, 71, + 89, 65, 65, 128, 71, 89, 65, 128, 71, 89, 128, 71, 87, 85, 128, 71, 87, + 73, 128, 71, 87, 69, 69, 128, 71, 87, 69, 128, 71, 87, 65, 65, 128, 71, + 87, 65, 128, 71, 86, 65, 78, 71, 128, 71, 86, 128, 71, 85, 82, 85, 83, + 72, 128, 71, 85, 82, 85, 78, 128, 71, 85, 82, 77, 85, 75, 72, 201, 71, + 85, 82, 65, 77, 85, 84, 79, 78, 128, 71, 85, 82, 55, 128, 71, 85, 78, 85, 128, 71, 85, 78, 213, 71, 85, 205, 71, 85, 76, 128, 71, 85, 73, 84, 65, - 82, 128, 71, 85, 199, 71, 85, 69, 72, 128, 71, 85, 69, 200, 71, 85, 68, - 128, 71, 85, 196, 71, 85, 65, 82, 68, 83, 77, 65, 78, 128, 71, 85, 65, - 82, 68, 69, 68, 78, 69, 83, 83, 128, 71, 85, 65, 82, 68, 69, 196, 71, 85, - 65, 82, 68, 128, 71, 85, 65, 82, 65, 78, 201, 71, 85, 193, 71, 85, 178, - 71, 84, 69, 210, 71, 83, 85, 77, 128, 71, 83, 85, 205, 71, 82, 213, 71, - 82, 79, 87, 73, 78, 199, 71, 82, 79, 85, 78, 68, 128, 71, 82, 79, 78, 84, - 72, 73, 83, 77, 65, 84, 65, 128, 71, 82, 73, 78, 78, 73, 78, 199, 71, 82, - 73, 77, 65, 67, 73, 78, 199, 71, 82, 69, 71, 79, 82, 73, 65, 206, 71, 82, - 69, 69, 206, 71, 82, 69, 65, 84, 78, 69, 83, 83, 128, 71, 82, 69, 65, 84, - 69, 82, 45, 84, 72, 65, 78, 128, 71, 82, 69, 65, 84, 69, 82, 45, 84, 72, - 65, 206, 71, 82, 69, 65, 84, 69, 210, 71, 82, 69, 65, 212, 71, 82, 65, - 86, 69, 89, 65, 82, 196, 71, 82, 65, 86, 69, 45, 77, 65, 67, 82, 79, 78, - 128, 71, 82, 65, 86, 69, 45, 65, 67, 85, 84, 69, 45, 71, 82, 65, 86, 69, - 128, 71, 82, 65, 86, 197, 71, 82, 65, 84, 69, 82, 128, 71, 82, 65, 83, - 83, 128, 71, 82, 65, 83, 211, 71, 82, 65, 80, 72, 69, 77, 197, 71, 82, - 65, 80, 69, 83, 128, 71, 82, 65, 77, 77, 193, 71, 82, 65, 73, 78, 128, - 71, 82, 65, 68, 85, 65, 84, 73, 79, 206, 71, 82, 65, 67, 69, 128, 71, 82, - 65, 67, 197, 71, 80, 65, 128, 71, 79, 82, 84, 72, 77, 73, 75, 79, 206, - 71, 79, 82, 84, 128, 71, 79, 82, 71, 79, 84, 69, 82, 73, 128, 71, 79, 82, - 71, 79, 83, 89, 78, 84, 72, 69, 84, 79, 78, 128, 71, 79, 82, 71, 79, 206, - 71, 79, 82, 71, 73, 128, 71, 79, 82, 65, 128, 71, 79, 79, 196, 71, 79, - 78, 71, 128, 71, 79, 76, 68, 128, 71, 79, 75, 128, 71, 79, 73, 78, 199, - 71, 79, 66, 76, 73, 78, 128, 71, 79, 65, 76, 128, 71, 79, 65, 204, 71, - 79, 65, 128, 71, 78, 89, 73, 83, 128, 71, 78, 65, 86, 73, 89, 65, 78, 73, - 128, 71, 76, 79, 87, 73, 78, 199, 71, 76, 79, 84, 84, 65, 204, 71, 76, - 79, 66, 197, 71, 76, 73, 83, 83, 65, 78, 68, 207, 71, 76, 69, 73, 67, - 200, 71, 76, 65, 71, 79, 76, 73, 128, 71, 76, 65, 128, 71, 74, 69, 128, - 71, 73, 88, 128, 71, 73, 84, 128, 71, 73, 83, 72, 128, 71, 73, 83, 200, - 71, 73, 83, 65, 76, 128, 71, 73, 82, 85, 68, 65, 65, 128, 71, 73, 82, 76, + 82, 128, 71, 85, 199, 71, 85, 69, 73, 128, 71, 85, 69, 72, 128, 71, 85, + 69, 200, 71, 85, 68, 128, 71, 85, 196, 71, 85, 65, 82, 68, 83, 77, 65, + 78, 128, 71, 85, 65, 82, 68, 69, 68, 78, 69, 83, 83, 128, 71, 85, 65, 82, + 68, 69, 196, 71, 85, 65, 82, 68, 128, 71, 85, 65, 82, 65, 78, 201, 71, + 85, 193, 71, 85, 178, 71, 84, 69, 210, 71, 83, 85, 77, 128, 71, 83, 85, + 205, 71, 82, 213, 71, 82, 79, 87, 73, 78, 199, 71, 82, 79, 85, 78, 68, + 128, 71, 82, 79, 78, 84, 72, 73, 83, 77, 65, 84, 65, 128, 71, 82, 73, 78, + 78, 73, 78, 199, 71, 82, 73, 77, 65, 67, 73, 78, 199, 71, 82, 69, 71, 79, + 82, 73, 65, 206, 71, 82, 69, 69, 206, 71, 82, 69, 65, 84, 78, 69, 83, 83, + 128, 71, 82, 69, 65, 84, 69, 82, 45, 84, 72, 65, 78, 128, 71, 82, 69, 65, + 84, 69, 82, 45, 84, 72, 65, 206, 71, 82, 69, 65, 84, 69, 210, 71, 82, 69, + 65, 212, 71, 82, 65, 86, 69, 89, 65, 82, 196, 71, 82, 65, 86, 69, 45, 77, + 65, 67, 82, 79, 78, 128, 71, 82, 65, 86, 69, 45, 65, 67, 85, 84, 69, 45, + 71, 82, 65, 86, 69, 128, 71, 82, 65, 86, 197, 71, 82, 65, 84, 69, 82, + 128, 71, 82, 65, 83, 83, 128, 71, 82, 65, 83, 211, 71, 82, 65, 80, 72, + 69, 77, 197, 71, 82, 65, 80, 69, 83, 128, 71, 82, 65, 77, 77, 193, 71, + 82, 65, 73, 78, 128, 71, 82, 65, 68, 85, 65, 84, 73, 79, 206, 71, 82, 65, + 67, 69, 128, 71, 82, 65, 67, 197, 71, 80, 65, 128, 71, 79, 82, 84, 72, + 77, 73, 75, 79, 206, 71, 79, 82, 84, 128, 71, 79, 82, 71, 79, 84, 69, 82, + 73, 128, 71, 79, 82, 71, 79, 83, 89, 78, 84, 72, 69, 84, 79, 78, 128, 71, + 79, 82, 71, 79, 206, 71, 79, 82, 71, 73, 128, 71, 79, 82, 65, 128, 71, + 79, 79, 196, 71, 79, 78, 71, 128, 71, 79, 76, 70, 69, 82, 128, 71, 79, + 76, 68, 128, 71, 79, 75, 128, 71, 79, 73, 78, 199, 71, 79, 66, 76, 73, + 78, 128, 71, 79, 65, 76, 128, 71, 79, 65, 204, 71, 79, 65, 128, 71, 78, + 89, 73, 83, 128, 71, 78, 65, 86, 73, 89, 65, 78, 73, 128, 71, 76, 79, 87, + 73, 78, 199, 71, 76, 79, 84, 84, 65, 204, 71, 76, 79, 66, 197, 71, 76, + 73, 83, 83, 65, 78, 68, 207, 71, 76, 69, 73, 67, 200, 71, 76, 65, 71, 79, + 76, 73, 128, 71, 76, 65, 128, 71, 74, 69, 128, 71, 73, 88, 128, 71, 73, + 84, 128, 71, 73, 83, 72, 128, 71, 73, 83, 200, 71, 73, 83, 65, 76, 128, + 71, 73, 82, 85, 68, 65, 65, 128, 71, 73, 82, 76, 211, 71, 73, 82, 76, 128, 71, 73, 82, 51, 128, 71, 73, 82, 179, 71, 73, 82, 50, 128, 71, 73, 82, 178, 71, 73, 80, 128, 71, 73, 78, 73, 73, 128, 71, 73, 77, 69, 76, 128, 71, 73, 77, 69, 204, 71, 73, 77, 128, 71, 73, 71, 65, 128, 71, 73, - 69, 84, 128, 71, 73, 68, 73, 77, 128, 71, 73, 66, 66, 79, 85, 211, 71, - 73, 66, 65, 128, 71, 73, 52, 128, 71, 73, 180, 71, 72, 90, 128, 71, 72, - 87, 65, 128, 71, 72, 85, 78, 78, 65, 128, 71, 72, 85, 78, 78, 193, 71, - 72, 85, 128, 71, 72, 79, 85, 128, 71, 72, 79, 83, 84, 128, 71, 72, 79, - 128, 71, 72, 73, 128, 71, 72, 72, 65, 128, 71, 72, 69, 85, 88, 128, 71, + 71, 128, 71, 73, 69, 84, 128, 71, 73, 68, 73, 77, 128, 71, 73, 66, 66, + 79, 85, 211, 71, 73, 66, 65, 128, 71, 73, 52, 128, 71, 73, 180, 71, 72, + 90, 128, 71, 72, 87, 65, 128, 71, 72, 85, 78, 78, 65, 128, 71, 72, 85, + 78, 78, 193, 71, 72, 85, 128, 71, 72, 79, 85, 128, 71, 72, 79, 83, 84, + 128, 71, 72, 79, 128, 71, 72, 73, 77, 69, 76, 128, 71, 72, 73, 128, 71, + 72, 72, 65, 128, 71, 72, 69, 89, 83, 128, 71, 72, 69, 85, 88, 128, 71, 72, 69, 85, 78, 128, 71, 72, 69, 85, 71, 72, 69, 85, 65, 69, 77, 128, 71, 72, 69, 85, 71, 72, 69, 78, 128, 71, 72, 69, 85, 65, 69, 82, 65, 69, 128, 71, 72, 69, 85, 65, 69, 71, 72, 69, 85, 65, 69, 128, 71, 72, 69, 84, 128, 71, 72, 69, 69, 128, 71, 72, 69, 128, 71, 72, 197, 71, 72, 65, 89, 78, 128, 71, 72, 65, 82, 65, 69, 128, 71, 72, 65, 80, 128, 71, 72, 65, 78, - 128, 71, 72, 65, 77, 65, 76, 128, 71, 72, 65, 73, 78, 85, 128, 71, 72, - 65, 73, 78, 128, 71, 72, 65, 73, 206, 71, 72, 65, 68, 128, 71, 72, 65, - 65, 77, 65, 69, 128, 71, 72, 65, 65, 128, 71, 71, 87, 73, 128, 71, 71, - 87, 69, 69, 128, 71, 71, 87, 69, 128, 71, 71, 87, 65, 65, 128, 71, 71, - 87, 65, 128, 71, 71, 85, 88, 128, 71, 71, 85, 84, 128, 71, 71, 85, 82, - 88, 128, 71, 71, 85, 82, 128, 71, 71, 85, 79, 88, 128, 71, 71, 85, 79, - 84, 128, 71, 71, 85, 79, 80, 128, 71, 71, 85, 79, 128, 71, 71, 79, 88, - 128, 71, 71, 79, 84, 128, 71, 71, 79, 80, 128, 71, 71, 73, 88, 128, 71, - 71, 73, 84, 128, 71, 71, 73, 69, 88, 128, 71, 71, 73, 69, 80, 128, 71, - 71, 73, 69, 128, 71, 71, 69, 88, 128, 71, 71, 69, 84, 128, 71, 71, 69, - 80, 128, 71, 71, 65, 88, 128, 71, 71, 65, 84, 128, 71, 71, 65, 65, 128, - 71, 69, 84, 193, 71, 69, 83, 84, 85, 82, 69, 128, 71, 69, 83, 72, 85, - 128, 71, 69, 83, 72, 84, 73, 78, 128, 71, 69, 83, 72, 84, 73, 206, 71, - 69, 83, 72, 50, 128, 71, 69, 82, 83, 72, 65, 89, 73, 77, 128, 71, 69, 82, - 77, 65, 206, 71, 69, 82, 69, 83, 72, 128, 71, 69, 82, 69, 83, 200, 71, - 69, 79, 77, 69, 84, 82, 73, 67, 65, 76, 76, 217, 71, 69, 79, 77, 69, 84, - 82, 73, 195, 71, 69, 78, 84, 76, 197, 71, 69, 78, 73, 84, 73, 86, 69, - 128, 71, 69, 78, 73, 75, 201, 71, 69, 78, 69, 82, 73, 195, 71, 69, 77, - 73, 78, 73, 128, 71, 69, 77, 73, 78, 65, 84, 73, 79, 206, 71, 69, 205, - 71, 69, 68, 79, 76, 65, 128, 71, 69, 68, 69, 128, 71, 69, 66, 207, 71, - 69, 66, 193, 71, 69, 65, 82, 128, 71, 69, 65, 210, 71, 68, 65, 78, 128, - 71, 67, 73, 71, 128, 71, 67, 65, 206, 71, 66, 79, 78, 128, 71, 66, 73, - 69, 197, 71, 66, 69, 85, 88, 128, 71, 66, 69, 84, 128, 71, 66, 65, 89, - 73, 128, 71, 66, 65, 75, 85, 82, 85, 78, 69, 78, 128, 71, 66, 128, 71, - 65, 89, 65, 78, 85, 75, 73, 84, 84, 65, 128, 71, 65, 89, 65, 78, 78, 65, - 128, 71, 65, 89, 128, 71, 65, 85, 78, 84, 76, 69, 84, 128, 71, 65, 84, - 72, 69, 82, 73, 78, 71, 128, 71, 65, 84, 72, 69, 82, 73, 78, 199, 71, 65, - 84, 69, 128, 71, 65, 83, 72, 65, 78, 128, 71, 65, 82, 83, 72, 85, 78, 73, - 128, 71, 65, 82, 79, 78, 128, 71, 65, 82, 77, 69, 78, 84, 128, 71, 65, - 82, 68, 69, 78, 128, 71, 65, 82, 51, 128, 71, 65, 80, 80, 69, 196, 71, - 65, 208, 71, 65, 78, 77, 65, 128, 71, 65, 78, 71, 73, 65, 128, 71, 65, - 78, 68, 193, 71, 65, 78, 50, 128, 71, 65, 78, 178, 71, 65, 77, 77, 65, - 128, 71, 65, 77, 76, 65, 128, 71, 65, 77, 76, 128, 71, 65, 77, 69, 128, - 71, 65, 77, 197, 71, 65, 77, 65, 78, 128, 71, 65, 77, 65, 76, 128, 71, - 65, 77, 65, 204, 71, 65, 71, 128, 71, 65, 70, 128, 71, 65, 198, 71, 65, - 69, 84, 84, 65, 45, 80, 73, 76, 76, 65, 128, 71, 65, 68, 79, 76, 128, 71, - 65, 68, 128, 71, 65, 196, 71, 65, 66, 65, 128, 71, 65, 66, 193, 71, 65, - 65, 70, 85, 128, 71, 65, 178, 71, 48, 53, 52, 128, 71, 48, 53, 51, 128, - 71, 48, 53, 50, 128, 71, 48, 53, 49, 128, 71, 48, 53, 48, 128, 71, 48, - 52, 57, 128, 71, 48, 52, 56, 128, 71, 48, 52, 55, 128, 71, 48, 52, 54, - 128, 71, 48, 52, 53, 65, 128, 71, 48, 52, 53, 128, 71, 48, 52, 52, 128, - 71, 48, 52, 51, 65, 128, 71, 48, 52, 51, 128, 71, 48, 52, 50, 128, 71, - 48, 52, 49, 128, 71, 48, 52, 48, 128, 71, 48, 51, 57, 128, 71, 48, 51, - 56, 128, 71, 48, 51, 55, 65, 128, 71, 48, 51, 55, 128, 71, 48, 51, 54, - 65, 128, 71, 48, 51, 54, 128, 71, 48, 51, 53, 128, 71, 48, 51, 52, 128, - 71, 48, 51, 51, 128, 71, 48, 51, 50, 128, 71, 48, 51, 49, 128, 71, 48, - 51, 48, 128, 71, 48, 50, 57, 128, 71, 48, 50, 56, 128, 71, 48, 50, 55, - 128, 71, 48, 50, 54, 65, 128, 71, 48, 50, 54, 128, 71, 48, 50, 53, 128, - 71, 48, 50, 52, 128, 71, 48, 50, 51, 128, 71, 48, 50, 50, 128, 71, 48, - 50, 49, 128, 71, 48, 50, 48, 65, 128, 71, 48, 50, 48, 128, 71, 48, 49, - 57, 128, 71, 48, 49, 56, 128, 71, 48, 49, 55, 128, 71, 48, 49, 54, 128, - 71, 48, 49, 53, 128, 71, 48, 49, 52, 128, 71, 48, 49, 51, 128, 71, 48, - 49, 50, 128, 71, 48, 49, 49, 65, 128, 71, 48, 49, 49, 128, 71, 48, 49, - 48, 128, 71, 48, 48, 57, 128, 71, 48, 48, 56, 128, 71, 48, 48, 55, 66, - 128, 71, 48, 48, 55, 65, 128, 71, 48, 48, 55, 128, 71, 48, 48, 54, 65, - 128, 71, 48, 48, 54, 128, 71, 48, 48, 53, 128, 71, 48, 48, 52, 128, 71, - 48, 48, 51, 128, 71, 48, 48, 50, 128, 71, 48, 48, 49, 128, 70, 89, 88, - 128, 70, 89, 84, 128, 70, 89, 80, 128, 70, 89, 65, 128, 70, 87, 73, 128, - 70, 87, 69, 69, 128, 70, 87, 69, 128, 70, 87, 65, 65, 128, 70, 87, 65, - 128, 70, 86, 83, 51, 128, 70, 86, 83, 50, 128, 70, 86, 83, 49, 128, 70, - 85, 88, 128, 70, 85, 84, 128, 70, 85, 83, 69, 128, 70, 85, 83, 193, 70, - 85, 82, 88, 128, 70, 85, 80, 128, 70, 85, 78, 69, 82, 65, 204, 70, 85, - 78, 67, 84, 73, 79, 78, 65, 204, 70, 85, 78, 67, 84, 73, 79, 78, 128, 70, - 85, 76, 76, 78, 69, 83, 83, 128, 70, 85, 76, 204, 70, 85, 74, 73, 128, - 70, 85, 69, 84, 128, 70, 85, 69, 204, 70, 85, 69, 128, 70, 84, 72, 79, - 82, 193, 70, 83, 73, 128, 70, 82, 79, 87, 78, 73, 78, 71, 128, 70, 82, - 79, 87, 78, 73, 78, 199, 70, 82, 79, 87, 78, 128, 70, 82, 79, 78, 84, 45, - 84, 73, 76, 84, 69, 196, 70, 82, 79, 78, 84, 45, 70, 65, 67, 73, 78, 199, - 70, 82, 79, 205, 70, 82, 79, 71, 128, 70, 82, 79, 199, 70, 82, 73, 84, - 85, 128, 70, 82, 73, 69, 83, 128, 70, 82, 73, 69, 196, 70, 82, 73, 67, - 65, 84, 73, 86, 69, 128, 70, 82, 69, 84, 66, 79, 65, 82, 68, 128, 70, 82, - 69, 78, 67, 200, 70, 82, 69, 69, 128, 70, 82, 69, 197, 70, 82, 65, 78, - 195, 70, 82, 65, 77, 69, 128, 70, 82, 65, 71, 82, 65, 78, 84, 128, 70, - 82, 65, 71, 77, 69, 78, 84, 128, 70, 82, 65, 67, 84, 73, 79, 206, 70, 79, - 88, 128, 70, 79, 85, 82, 84, 69, 69, 78, 128, 70, 79, 85, 82, 84, 69, 69, - 206, 70, 79, 85, 82, 45, 84, 72, 73, 82, 84, 89, 128, 70, 79, 85, 82, 45, - 83, 84, 82, 73, 78, 199, 70, 79, 85, 82, 45, 80, 69, 82, 45, 69, 205, 70, - 79, 85, 82, 45, 76, 73, 78, 197, 70, 79, 85, 210, 70, 79, 85, 78, 84, 65, - 73, 78, 128, 70, 79, 83, 84, 69, 82, 73, 78, 71, 128, 70, 79, 82, 87, 65, - 82, 68, 128, 70, 79, 82, 84, 89, 128, 70, 79, 82, 84, 217, 70, 79, 82, - 84, 69, 128, 70, 79, 82, 77, 211, 70, 79, 82, 77, 65, 84, 84, 73, 78, 71, - 128, 70, 79, 82, 75, 69, 196, 70, 79, 82, 67, 69, 83, 128, 70, 79, 82, - 67, 69, 128, 70, 79, 80, 128, 70, 79, 79, 84, 83, 84, 79, 79, 76, 128, - 70, 79, 79, 84, 80, 82, 73, 78, 84, 83, 128, 70, 79, 79, 84, 78, 79, 84, - 197, 70, 79, 79, 84, 66, 65, 76, 76, 128, 70, 79, 79, 84, 128, 70, 79, - 79, 68, 128, 70, 79, 79, 128, 70, 79, 78, 71, 77, 65, 78, 128, 70, 79, - 77, 128, 70, 79, 76, 76, 89, 128, 70, 79, 76, 76, 79, 87, 73, 78, 71, - 128, 70, 79, 76, 68, 69, 82, 128, 70, 79, 76, 68, 69, 196, 70, 79, 71, - 71, 89, 128, 70, 207, 70, 77, 128, 70, 76, 89, 128, 70, 76, 85, 84, 84, - 69, 82, 73, 78, 199, 70, 76, 85, 84, 69, 128, 70, 76, 85, 83, 72, 69, - 196, 70, 76, 79, 87, 73, 78, 199, 70, 76, 79, 87, 69, 210, 70, 76, 79, - 85, 82, 73, 83, 72, 128, 70, 76, 79, 82, 69, 84, 84, 69, 128, 70, 76, 79, - 82, 65, 204, 70, 76, 79, 80, 80, 217, 70, 76, 79, 79, 82, 128, 70, 76, - 73, 80, 128, 70, 76, 73, 71, 72, 84, 128, 70, 76, 69, 88, 85, 83, 128, - 70, 76, 69, 88, 69, 196, 70, 76, 69, 85, 82, 45, 68, 69, 45, 76, 73, 83, - 128, 70, 76, 65, 84, 84, 69, 78, 69, 196, 70, 76, 65, 84, 78, 69, 83, 83, - 128, 70, 76, 65, 84, 128, 70, 76, 65, 212, 70, 76, 65, 71, 83, 128, 70, - 76, 65, 71, 45, 53, 128, 70, 76, 65, 71, 45, 52, 128, 70, 76, 65, 71, 45, - 51, 128, 70, 76, 65, 71, 45, 50, 128, 70, 76, 65, 71, 45, 49, 128, 70, - 76, 65, 71, 128, 70, 76, 65, 199, 70, 76, 65, 128, 70, 76, 128, 70, 73, - 88, 69, 68, 45, 70, 79, 82, 205, 70, 73, 88, 128, 70, 73, 86, 69, 45, 84, - 72, 73, 82, 84, 89, 128, 70, 73, 86, 69, 45, 76, 73, 78, 197, 70, 73, 86, - 197, 70, 73, 84, 65, 128, 70, 73, 84, 128, 70, 73, 83, 84, 69, 196, 70, - 73, 83, 84, 128, 70, 73, 83, 72, 73, 78, 199, 70, 73, 83, 72, 72, 79, 79, - 75, 128, 70, 73, 83, 72, 72, 79, 79, 203, 70, 73, 83, 72, 69, 89, 69, + 128, 71, 72, 65, 77, 77, 65, 128, 71, 72, 65, 77, 65, 76, 128, 71, 72, + 65, 73, 78, 85, 128, 71, 72, 65, 73, 78, 128, 71, 72, 65, 73, 206, 71, + 72, 65, 68, 128, 71, 72, 65, 65, 77, 65, 69, 128, 71, 72, 65, 65, 128, + 71, 71, 87, 73, 128, 71, 71, 87, 69, 69, 128, 71, 71, 87, 69, 128, 71, + 71, 87, 65, 65, 128, 71, 71, 87, 65, 128, 71, 71, 85, 88, 128, 71, 71, + 85, 84, 128, 71, 71, 85, 82, 88, 128, 71, 71, 85, 82, 128, 71, 71, 85, + 79, 88, 128, 71, 71, 85, 79, 84, 128, 71, 71, 85, 79, 80, 128, 71, 71, + 85, 79, 128, 71, 71, 79, 88, 128, 71, 71, 79, 84, 128, 71, 71, 79, 80, + 128, 71, 71, 73, 88, 128, 71, 71, 73, 84, 128, 71, 71, 73, 69, 88, 128, + 71, 71, 73, 69, 80, 128, 71, 71, 73, 69, 128, 71, 71, 69, 88, 128, 71, + 71, 69, 84, 128, 71, 71, 69, 80, 128, 71, 71, 65, 88, 128, 71, 71, 65, + 84, 128, 71, 69, 84, 193, 71, 69, 83, 84, 85, 82, 69, 128, 71, 69, 83, + 72, 85, 128, 71, 69, 83, 72, 84, 73, 78, 128, 71, 69, 83, 72, 84, 73, + 206, 71, 69, 83, 72, 50, 128, 71, 69, 82, 83, 72, 65, 89, 73, 77, 128, + 71, 69, 82, 77, 65, 206, 71, 69, 82, 69, 83, 72, 128, 71, 69, 82, 69, 83, + 200, 71, 69, 79, 77, 69, 84, 82, 73, 67, 65, 76, 76, 217, 71, 69, 79, 77, + 69, 84, 82, 73, 195, 71, 69, 78, 84, 76, 197, 71, 69, 78, 73, 84, 73, 86, + 69, 128, 71, 69, 78, 73, 75, 201, 71, 69, 78, 69, 82, 73, 195, 71, 69, + 77, 73, 78, 73, 128, 71, 69, 77, 73, 78, 65, 84, 73, 79, 206, 71, 69, + 205, 71, 69, 69, 77, 128, 71, 69, 68, 79, 76, 65, 128, 71, 69, 68, 69, + 128, 71, 69, 66, 207, 71, 69, 66, 193, 71, 69, 65, 82, 128, 71, 69, 65, + 210, 71, 69, 50, 50, 128, 71, 68, 65, 78, 128, 71, 67, 73, 71, 128, 71, + 67, 65, 206, 71, 66, 79, 78, 128, 71, 66, 73, 69, 197, 71, 66, 69, 85, + 88, 128, 71, 66, 69, 84, 128, 71, 66, 65, 89, 73, 128, 71, 66, 65, 75, + 85, 82, 85, 78, 69, 78, 128, 71, 66, 128, 71, 65, 89, 65, 78, 85, 75, 73, + 84, 84, 65, 128, 71, 65, 89, 65, 78, 78, 65, 128, 71, 65, 89, 128, 71, + 65, 85, 78, 84, 76, 69, 84, 128, 71, 65, 84, 72, 69, 82, 73, 78, 71, 128, + 71, 65, 84, 72, 69, 82, 73, 78, 199, 71, 65, 84, 69, 128, 71, 65, 83, 72, + 65, 78, 128, 71, 65, 82, 83, 72, 85, 78, 73, 128, 71, 65, 82, 79, 78, + 128, 71, 65, 82, 77, 69, 78, 84, 128, 71, 65, 82, 68, 69, 78, 128, 71, + 65, 82, 51, 128, 71, 65, 80, 80, 69, 196, 71, 65, 208, 71, 65, 78, 77, + 65, 128, 71, 65, 78, 71, 73, 65, 128, 71, 65, 78, 68, 193, 71, 65, 78, + 50, 128, 71, 65, 78, 178, 71, 65, 77, 77, 65, 128, 71, 65, 77, 76, 65, + 128, 71, 65, 77, 76, 128, 71, 65, 77, 69, 128, 71, 65, 77, 197, 71, 65, + 77, 65, 78, 128, 71, 65, 77, 65, 76, 128, 71, 65, 77, 65, 204, 71, 65, + 71, 128, 71, 65, 70, 128, 71, 65, 198, 71, 65, 69, 84, 84, 65, 45, 80, + 73, 76, 76, 65, 128, 71, 65, 68, 79, 76, 128, 71, 65, 68, 128, 71, 65, + 196, 71, 65, 66, 65, 128, 71, 65, 66, 193, 71, 65, 65, 70, 85, 128, 71, + 65, 178, 71, 48, 53, 52, 128, 71, 48, 53, 51, 128, 71, 48, 53, 50, 128, + 71, 48, 53, 49, 128, 71, 48, 53, 48, 128, 71, 48, 52, 57, 128, 71, 48, + 52, 56, 128, 71, 48, 52, 55, 128, 71, 48, 52, 54, 128, 71, 48, 52, 53, + 65, 128, 71, 48, 52, 53, 128, 71, 48, 52, 52, 128, 71, 48, 52, 51, 65, + 128, 71, 48, 52, 51, 128, 71, 48, 52, 50, 128, 71, 48, 52, 49, 128, 71, + 48, 52, 48, 128, 71, 48, 51, 57, 128, 71, 48, 51, 56, 128, 71, 48, 51, + 55, 65, 128, 71, 48, 51, 55, 128, 71, 48, 51, 54, 65, 128, 71, 48, 51, + 54, 128, 71, 48, 51, 53, 128, 71, 48, 51, 52, 128, 71, 48, 51, 51, 128, + 71, 48, 51, 50, 128, 71, 48, 51, 49, 128, 71, 48, 51, 48, 128, 71, 48, + 50, 57, 128, 71, 48, 50, 56, 128, 71, 48, 50, 55, 128, 71, 48, 50, 54, + 65, 128, 71, 48, 50, 54, 128, 71, 48, 50, 53, 128, 71, 48, 50, 52, 128, + 71, 48, 50, 51, 128, 71, 48, 50, 50, 128, 71, 48, 50, 49, 128, 71, 48, + 50, 48, 65, 128, 71, 48, 50, 48, 128, 71, 48, 49, 57, 128, 71, 48, 49, + 56, 128, 71, 48, 49, 55, 128, 71, 48, 49, 54, 128, 71, 48, 49, 53, 128, + 71, 48, 49, 52, 128, 71, 48, 49, 51, 128, 71, 48, 49, 50, 128, 71, 48, + 49, 49, 65, 128, 71, 48, 49, 49, 128, 71, 48, 49, 48, 128, 71, 48, 48, + 57, 128, 71, 48, 48, 56, 128, 71, 48, 48, 55, 66, 128, 71, 48, 48, 55, + 65, 128, 71, 48, 48, 55, 128, 71, 48, 48, 54, 65, 128, 71, 48, 48, 54, + 128, 71, 48, 48, 53, 128, 71, 48, 48, 52, 128, 71, 48, 48, 51, 128, 71, + 48, 48, 50, 128, 71, 48, 48, 49, 128, 70, 89, 88, 128, 70, 89, 84, 128, + 70, 89, 80, 128, 70, 89, 65, 128, 70, 87, 73, 128, 70, 87, 69, 69, 128, + 70, 87, 69, 128, 70, 87, 65, 65, 128, 70, 87, 65, 128, 70, 86, 83, 51, + 128, 70, 86, 83, 50, 128, 70, 86, 83, 49, 128, 70, 85, 88, 128, 70, 85, + 84, 128, 70, 85, 83, 69, 128, 70, 85, 83, 193, 70, 85, 82, 88, 128, 70, + 85, 80, 128, 70, 85, 78, 69, 82, 65, 204, 70, 85, 78, 67, 84, 73, 79, 78, + 65, 204, 70, 85, 78, 67, 84, 73, 79, 78, 128, 70, 85, 76, 76, 78, 69, 83, + 83, 128, 70, 85, 76, 204, 70, 85, 74, 73, 128, 70, 85, 69, 84, 128, 70, + 85, 69, 204, 70, 85, 69, 128, 70, 85, 65, 128, 70, 84, 72, 79, 82, 193, + 70, 83, 73, 128, 70, 82, 79, 87, 78, 73, 78, 71, 128, 70, 82, 79, 87, 78, + 73, 78, 199, 70, 82, 79, 87, 78, 128, 70, 82, 79, 78, 84, 45, 84, 73, 76, + 84, 69, 196, 70, 82, 79, 78, 84, 45, 70, 65, 67, 73, 78, 199, 70, 82, 79, + 205, 70, 82, 79, 71, 128, 70, 82, 79, 199, 70, 82, 73, 84, 85, 128, 70, + 82, 73, 69, 83, 128, 70, 82, 73, 69, 196, 70, 82, 73, 67, 65, 84, 73, 86, + 69, 128, 70, 82, 69, 84, 66, 79, 65, 82, 68, 128, 70, 82, 69, 78, 67, + 200, 70, 82, 69, 69, 128, 70, 82, 69, 197, 70, 82, 65, 78, 75, 211, 70, + 82, 65, 78, 195, 70, 82, 65, 77, 69, 83, 128, 70, 82, 65, 77, 69, 128, + 70, 82, 65, 77, 197, 70, 82, 65, 71, 82, 65, 78, 84, 128, 70, 82, 65, 71, + 77, 69, 78, 84, 128, 70, 82, 65, 67, 84, 73, 79, 206, 70, 79, 88, 128, + 70, 79, 85, 82, 84, 69, 69, 78, 128, 70, 79, 85, 82, 84, 69, 69, 206, 70, + 79, 85, 82, 45, 84, 72, 73, 82, 84, 89, 128, 70, 79, 85, 82, 45, 83, 84, + 82, 73, 78, 199, 70, 79, 85, 82, 45, 80, 69, 82, 45, 69, 205, 70, 79, 85, + 82, 45, 76, 73, 78, 197, 70, 79, 85, 210, 70, 79, 85, 78, 84, 65, 73, 78, + 128, 70, 79, 85, 78, 84, 65, 73, 206, 70, 79, 83, 84, 69, 82, 73, 78, 71, + 128, 70, 79, 82, 87, 65, 82, 68, 128, 70, 79, 82, 84, 89, 128, 70, 79, + 82, 84, 217, 70, 79, 82, 84, 69, 128, 70, 79, 82, 77, 211, 70, 79, 82, + 77, 65, 84, 84, 73, 78, 71, 128, 70, 79, 82, 77, 65, 212, 70, 79, 82, 75, + 69, 196, 70, 79, 82, 67, 69, 83, 128, 70, 79, 82, 67, 69, 128, 70, 79, + 80, 128, 70, 79, 79, 84, 83, 84, 79, 79, 76, 128, 70, 79, 79, 84, 80, 82, + 73, 78, 84, 83, 128, 70, 79, 79, 84, 78, 79, 84, 197, 70, 79, 79, 84, 66, + 65, 76, 76, 128, 70, 79, 79, 84, 128, 70, 79, 79, 76, 128, 70, 79, 79, + 68, 128, 70, 79, 79, 128, 70, 79, 78, 212, 70, 79, 78, 71, 77, 65, 78, + 128, 70, 79, 77, 128, 70, 79, 76, 76, 89, 128, 70, 79, 76, 76, 79, 87, + 73, 78, 71, 128, 70, 79, 76, 68, 69, 82, 128, 70, 79, 76, 68, 69, 196, + 70, 79, 71, 71, 89, 128, 70, 79, 71, 128, 70, 207, 70, 77, 128, 70, 76, + 89, 73, 78, 199, 70, 76, 89, 128, 70, 76, 85, 84, 84, 69, 82, 73, 78, + 199, 70, 76, 85, 84, 69, 128, 70, 76, 85, 83, 72, 69, 196, 70, 76, 79, + 87, 73, 78, 199, 70, 76, 79, 87, 69, 82, 83, 128, 70, 76, 79, 87, 69, + 210, 70, 76, 79, 85, 82, 73, 83, 72, 128, 70, 76, 79, 82, 69, 84, 84, 69, + 128, 70, 76, 79, 82, 65, 204, 70, 76, 79, 80, 80, 217, 70, 76, 79, 79, + 82, 128, 70, 76, 73, 80, 128, 70, 76, 73, 71, 72, 84, 128, 70, 76, 69, + 88, 85, 83, 128, 70, 76, 69, 88, 69, 196, 70, 76, 69, 85, 82, 79, 78, + 128, 70, 76, 69, 85, 82, 45, 68, 69, 45, 76, 73, 83, 128, 70, 76, 65, 84, + 84, 69, 78, 69, 196, 70, 76, 65, 84, 78, 69, 83, 83, 128, 70, 76, 65, 84, + 128, 70, 76, 65, 212, 70, 76, 65, 83, 72, 128, 70, 76, 65, 71, 83, 128, + 70, 76, 65, 71, 45, 53, 128, 70, 76, 65, 71, 45, 52, 128, 70, 76, 65, 71, + 45, 51, 128, 70, 76, 65, 71, 45, 50, 128, 70, 76, 65, 71, 45, 49, 128, + 70, 76, 65, 71, 128, 70, 76, 65, 199, 70, 76, 65, 128, 70, 76, 128, 70, + 73, 88, 69, 68, 45, 70, 79, 82, 205, 70, 73, 88, 128, 70, 73, 86, 69, 45, + 84, 72, 73, 82, 84, 89, 128, 70, 73, 86, 69, 45, 76, 73, 78, 197, 70, 73, + 86, 197, 70, 73, 84, 65, 128, 70, 73, 84, 128, 70, 73, 83, 84, 69, 196, + 70, 73, 83, 84, 128, 70, 73, 83, 72, 73, 78, 199, 70, 73, 83, 72, 72, 79, + 79, 75, 128, 70, 73, 83, 72, 72, 79, 79, 203, 70, 73, 83, 72, 69, 89, 69, 128, 70, 73, 83, 72, 128, 70, 73, 83, 200, 70, 73, 82, 83, 212, 70, 73, 82, 73, 128, 70, 73, 82, 69, 87, 79, 82, 75, 83, 128, 70, 73, 82, 69, 87, 79, 82, 203, 70, 73, 82, 69, 128, 70, 73, 82, 197, 70, 73, 80, 128, 70, - 73, 78, 73, 84, 197, 70, 73, 78, 71, 69, 82, 78, 65, 73, 76, 83, 128, 70, - 73, 78, 71, 69, 82, 69, 196, 70, 73, 78, 65, 78, 67, 73, 65, 76, 128, 70, - 73, 76, 76, 69, 82, 128, 70, 73, 76, 76, 69, 196, 70, 73, 76, 76, 128, - 70, 73, 76, 204, 70, 73, 76, 197, 70, 73, 73, 128, 70, 73, 71, 85, 82, - 69, 45, 51, 128, 70, 73, 71, 85, 82, 69, 45, 50, 128, 70, 73, 71, 85, 82, - 69, 45, 49, 128, 70, 73, 71, 85, 82, 197, 70, 73, 71, 72, 84, 128, 70, - 73, 70, 84, 89, 128, 70, 73, 70, 84, 217, 70, 73, 70, 84, 72, 83, 128, - 70, 73, 70, 84, 72, 128, 70, 73, 70, 84, 69, 69, 78, 128, 70, 73, 70, 84, - 69, 69, 206, 70, 73, 69, 76, 68, 128, 70, 72, 84, 79, 82, 193, 70, 70, - 76, 128, 70, 70, 73, 128, 70, 69, 85, 88, 128, 70, 69, 85, 70, 69, 85, - 65, 69, 84, 128, 70, 69, 83, 84, 73, 86, 65, 76, 128, 70, 69, 82, 82, 89, - 128, 70, 69, 82, 82, 73, 211, 70, 69, 82, 77, 65, 84, 65, 128, 70, 69, - 82, 77, 65, 84, 193, 70, 69, 79, 200, 70, 69, 78, 199, 70, 69, 78, 67, - 69, 128, 70, 69, 77, 73, 78, 73, 78, 197, 70, 69, 77, 65, 76, 69, 128, - 70, 69, 77, 65, 76, 197, 70, 69, 76, 76, 79, 87, 83, 72, 73, 80, 128, 70, - 69, 73, 128, 70, 69, 72, 213, 70, 69, 72, 128, 70, 69, 200, 70, 69, 69, - 78, 71, 128, 70, 69, 69, 68, 128, 70, 69, 69, 196, 70, 69, 69, 128, 70, - 69, 66, 82, 85, 65, 82, 89, 128, 70, 69, 65, 84, 72, 69, 82, 128, 70, 69, - 65, 84, 72, 69, 210, 70, 69, 65, 82, 78, 128, 70, 69, 65, 82, 70, 85, - 204, 70, 69, 65, 82, 128, 70, 65, 89, 65, 78, 78, 65, 128, 70, 65, 89, - 128, 70, 65, 88, 128, 70, 65, 216, 70, 65, 84, 73, 71, 85, 69, 128, 70, - 65, 84, 72, 69, 82, 128, 70, 65, 84, 72, 69, 210, 70, 65, 84, 72, 65, 84, - 65, 78, 128, 70, 65, 84, 72, 65, 84, 65, 206, 70, 65, 84, 72, 65, 128, - 70, 65, 84, 72, 193, 70, 65, 84, 128, 70, 65, 82, 83, 201, 70, 65, 81, - 128, 70, 65, 80, 128, 70, 65, 78, 71, 128, 70, 65, 78, 69, 82, 79, 83, - 73, 211, 70, 65, 78, 128, 70, 65, 77, 73, 76, 89, 128, 70, 65, 76, 76, - 73, 78, 199, 70, 65, 76, 76, 69, 206, 70, 65, 73, 76, 85, 82, 69, 128, - 70, 65, 73, 72, 85, 128, 70, 65, 72, 82, 69, 78, 72, 69, 73, 84, 128, 70, - 65, 67, 84, 79, 82, 89, 128, 70, 65, 67, 84, 79, 210, 70, 65, 67, 83, 73, - 77, 73, 76, 197, 70, 65, 67, 69, 45, 54, 128, 70, 65, 67, 69, 45, 53, - 128, 70, 65, 67, 69, 45, 52, 128, 70, 65, 67, 69, 45, 51, 128, 70, 65, - 67, 69, 45, 50, 128, 70, 65, 67, 69, 45, 49, 128, 70, 65, 65, 77, 65, 69, - 128, 70, 65, 65, 73, 128, 70, 65, 65, 70, 85, 128, 70, 48, 53, 51, 128, - 70, 48, 53, 50, 128, 70, 48, 53, 49, 67, 128, 70, 48, 53, 49, 66, 128, - 70, 48, 53, 49, 65, 128, 70, 48, 53, 49, 128, 70, 48, 53, 48, 128, 70, - 48, 52, 57, 128, 70, 48, 52, 56, 128, 70, 48, 52, 55, 65, 128, 70, 48, - 52, 55, 128, 70, 48, 52, 54, 65, 128, 70, 48, 52, 54, 128, 70, 48, 52, - 53, 65, 128, 70, 48, 52, 53, 128, 70, 48, 52, 52, 128, 70, 48, 52, 51, - 128, 70, 48, 52, 50, 128, 70, 48, 52, 49, 128, 70, 48, 52, 48, 128, 70, - 48, 51, 57, 128, 70, 48, 51, 56, 65, 128, 70, 48, 51, 56, 128, 70, 48, - 51, 55, 65, 128, 70, 48, 51, 55, 128, 70, 48, 51, 54, 128, 70, 48, 51, - 53, 128, 70, 48, 51, 52, 128, 70, 48, 51, 51, 128, 70, 48, 51, 50, 128, - 70, 48, 51, 49, 65, 128, 70, 48, 51, 49, 128, 70, 48, 51, 48, 128, 70, - 48, 50, 57, 128, 70, 48, 50, 56, 128, 70, 48, 50, 55, 128, 70, 48, 50, - 54, 128, 70, 48, 50, 53, 128, 70, 48, 50, 52, 128, 70, 48, 50, 51, 128, - 70, 48, 50, 50, 128, 70, 48, 50, 49, 65, 128, 70, 48, 50, 49, 128, 70, - 48, 50, 48, 128, 70, 48, 49, 57, 128, 70, 48, 49, 56, 128, 70, 48, 49, - 55, 128, 70, 48, 49, 54, 128, 70, 48, 49, 53, 128, 70, 48, 49, 52, 128, - 70, 48, 49, 51, 65, 128, 70, 48, 49, 51, 128, 70, 48, 49, 50, 128, 70, - 48, 49, 49, 128, 70, 48, 49, 48, 128, 70, 48, 48, 57, 128, 70, 48, 48, - 56, 128, 70, 48, 48, 55, 128, 70, 48, 48, 54, 128, 70, 48, 48, 53, 128, - 70, 48, 48, 52, 128, 70, 48, 48, 51, 128, 70, 48, 48, 50, 128, 70, 48, - 48, 49, 65, 128, 70, 48, 48, 49, 128, 69, 90, 200, 69, 90, 69, 78, 128, - 69, 90, 69, 206, 69, 90, 128, 69, 89, 69, 83, 128, 69, 89, 69, 71, 76, - 65, 83, 83, 69, 83, 128, 69, 89, 66, 69, 89, 70, 73, 76, 73, 128, 69, 89, - 65, 78, 78, 65, 128, 69, 88, 84, 82, 65, 84, 69, 82, 82, 69, 83, 84, 82, - 73, 65, 204, 69, 88, 84, 82, 65, 45, 76, 79, 215, 69, 88, 84, 82, 65, 45, - 72, 73, 71, 200, 69, 88, 84, 69, 78, 83, 73, 79, 78, 128, 69, 88, 84, 69, - 78, 68, 69, 196, 69, 88, 80, 82, 69, 83, 83, 73, 79, 78, 76, 69, 83, 211, - 69, 88, 80, 79, 78, 69, 78, 212, 69, 88, 79, 128, 69, 88, 207, 69, 88, - 73, 83, 84, 83, 128, 69, 88, 73, 83, 84, 128, 69, 88, 72, 65, 85, 83, 84, - 73, 79, 78, 128, 69, 88, 67, 76, 65, 77, 65, 84, 73, 79, 78, 128, 69, 88, - 67, 76, 65, 77, 65, 84, 73, 79, 206, 69, 88, 67, 72, 65, 78, 71, 69, 128, - 69, 88, 67, 69, 83, 83, 128, 69, 88, 67, 69, 76, 76, 69, 78, 84, 128, 69, - 87, 69, 128, 69, 86, 69, 82, 71, 82, 69, 69, 206, 69, 86, 69, 78, 73, 78, - 71, 128, 69, 85, 82, 79, 80, 69, 65, 206, 69, 85, 82, 79, 80, 69, 45, 65, - 70, 82, 73, 67, 65, 128, 69, 85, 82, 79, 45, 67, 85, 82, 82, 69, 78, 67, - 217, 69, 85, 82, 207, 69, 85, 76, 69, 210, 69, 85, 45, 85, 128, 69, 85, - 45, 79, 128, 69, 85, 45, 69, 85, 128, 69, 85, 45, 69, 79, 128, 69, 85, - 45, 69, 128, 69, 85, 45, 65, 128, 69, 84, 88, 128, 69, 84, 78, 65, 72, - 84, 65, 128, 69, 84, 72, 69, 204, 69, 84, 69, 82, 79, 206, 69, 84, 69, - 82, 78, 73, 84, 89, 128, 69, 84, 66, 128, 69, 83, 85, 75, 85, 85, 68, 79, - 128, 69, 83, 84, 73, 77, 65, 84, 69, 83, 128, 69, 83, 84, 73, 77, 65, 84, - 69, 196, 69, 83, 72, 69, 51, 128, 69, 83, 72, 50, 49, 128, 69, 83, 72, - 178, 69, 83, 72, 49, 54, 128, 69, 83, 67, 65, 80, 69, 128, 69, 83, 67, - 128, 69, 83, 65, 128, 69, 83, 45, 84, 69, 128, 69, 82, 82, 79, 82, 45, - 66, 65, 82, 82, 69, 196, 69, 82, 82, 128, 69, 82, 73, 78, 50, 128, 69, - 82, 71, 128, 69, 82, 65, 83, 197, 69, 81, 85, 73, 86, 65, 76, 69, 78, - 212, 69, 81, 85, 73, 68, 128, 69, 81, 85, 73, 65, 78, 71, 85, 76, 65, - 210, 69, 81, 85, 65, 76, 83, 128, 69, 81, 85, 65, 76, 211, 69, 81, 85, - 65, 76, 128, 69, 80, 83, 73, 76, 79, 78, 128, 69, 80, 83, 73, 76, 79, + 73, 78, 73, 84, 197, 70, 73, 78, 71, 69, 82, 83, 128, 70, 73, 78, 71, 69, + 82, 211, 70, 73, 78, 71, 69, 82, 78, 65, 73, 76, 83, 128, 70, 73, 78, 71, + 69, 82, 69, 196, 70, 73, 78, 71, 69, 82, 45, 80, 79, 83, 212, 70, 73, 78, + 71, 69, 210, 70, 73, 78, 65, 78, 67, 73, 65, 76, 128, 70, 73, 78, 65, 76, + 128, 70, 73, 76, 205, 70, 73, 76, 76, 69, 82, 128, 70, 73, 76, 76, 69, + 196, 70, 73, 76, 76, 128, 70, 73, 76, 204, 70, 73, 76, 197, 70, 73, 73, + 128, 70, 73, 71, 85, 82, 69, 45, 51, 128, 70, 73, 71, 85, 82, 69, 45, 50, + 128, 70, 73, 71, 85, 82, 69, 45, 49, 128, 70, 73, 71, 85, 82, 197, 70, + 73, 71, 72, 84, 128, 70, 73, 70, 84, 89, 128, 70, 73, 70, 84, 217, 70, + 73, 70, 84, 72, 83, 128, 70, 73, 70, 84, 72, 128, 70, 73, 70, 84, 69, 69, + 78, 128, 70, 73, 70, 84, 69, 69, 206, 70, 73, 69, 76, 68, 128, 70, 72, + 84, 79, 82, 193, 70, 70, 76, 128, 70, 70, 73, 128, 70, 69, 85, 88, 128, + 70, 69, 85, 70, 69, 85, 65, 69, 84, 128, 70, 69, 83, 84, 73, 86, 65, 76, + 128, 70, 69, 82, 82, 89, 128, 70, 69, 82, 82, 73, 211, 70, 69, 82, 77, + 65, 84, 65, 128, 70, 69, 82, 77, 65, 84, 193, 70, 69, 79, 200, 70, 69, + 78, 199, 70, 69, 78, 67, 69, 128, 70, 69, 77, 73, 78, 73, 78, 197, 70, + 69, 77, 65, 76, 69, 128, 70, 69, 77, 65, 76, 197, 70, 69, 76, 76, 79, 87, + 83, 72, 73, 80, 128, 70, 69, 73, 128, 70, 69, 72, 213, 70, 69, 72, 128, + 70, 69, 200, 70, 69, 69, 78, 71, 128, 70, 69, 69, 77, 128, 70, 69, 69, + 68, 128, 70, 69, 69, 196, 70, 69, 69, 128, 70, 69, 66, 82, 85, 65, 82, + 89, 128, 70, 69, 65, 84, 72, 69, 82, 128, 70, 69, 65, 84, 72, 69, 210, + 70, 69, 65, 82, 78, 128, 70, 69, 65, 82, 70, 85, 204, 70, 69, 65, 82, + 128, 70, 65, 89, 65, 78, 78, 65, 128, 70, 65, 89, 128, 70, 65, 88, 128, + 70, 65, 216, 70, 65, 84, 73, 71, 85, 69, 128, 70, 65, 84, 72, 69, 82, + 128, 70, 65, 84, 72, 69, 210, 70, 65, 84, 72, 65, 84, 65, 78, 128, 70, + 65, 84, 72, 65, 84, 65, 206, 70, 65, 84, 72, 65, 128, 70, 65, 84, 72, + 193, 70, 65, 84, 128, 70, 65, 82, 83, 201, 70, 65, 81, 128, 70, 65, 80, + 128, 70, 65, 78, 71, 128, 70, 65, 78, 69, 82, 79, 83, 73, 211, 70, 65, + 78, 128, 70, 65, 77, 73, 76, 89, 128, 70, 65, 77, 128, 70, 65, 76, 76, + 69, 206, 70, 65, 74, 128, 70, 65, 73, 76, 85, 82, 69, 128, 70, 65, 73, + 72, 85, 128, 70, 65, 73, 66, 128, 70, 65, 72, 82, 69, 78, 72, 69, 73, 84, + 128, 70, 65, 67, 84, 79, 82, 89, 128, 70, 65, 67, 84, 79, 210, 70, 65, + 67, 83, 73, 77, 73, 76, 197, 70, 65, 67, 69, 45, 54, 128, 70, 65, 67, 69, + 45, 53, 128, 70, 65, 67, 69, 45, 52, 128, 70, 65, 67, 69, 45, 51, 128, + 70, 65, 67, 69, 45, 50, 128, 70, 65, 67, 69, 45, 49, 128, 70, 65, 65, 77, + 65, 69, 128, 70, 65, 65, 73, 128, 70, 65, 65, 70, 85, 128, 70, 48, 53, + 51, 128, 70, 48, 53, 50, 128, 70, 48, 53, 49, 67, 128, 70, 48, 53, 49, + 66, 128, 70, 48, 53, 49, 65, 128, 70, 48, 53, 49, 128, 70, 48, 53, 48, + 128, 70, 48, 52, 57, 128, 70, 48, 52, 56, 128, 70, 48, 52, 55, 65, 128, + 70, 48, 52, 55, 128, 70, 48, 52, 54, 65, 128, 70, 48, 52, 54, 128, 70, + 48, 52, 53, 65, 128, 70, 48, 52, 53, 128, 70, 48, 52, 52, 128, 70, 48, + 52, 51, 128, 70, 48, 52, 50, 128, 70, 48, 52, 49, 128, 70, 48, 52, 48, + 128, 70, 48, 51, 57, 128, 70, 48, 51, 56, 65, 128, 70, 48, 51, 56, 128, + 70, 48, 51, 55, 65, 128, 70, 48, 51, 55, 128, 70, 48, 51, 54, 128, 70, + 48, 51, 53, 128, 70, 48, 51, 52, 128, 70, 48, 51, 51, 128, 70, 48, 51, + 50, 128, 70, 48, 51, 49, 65, 128, 70, 48, 51, 49, 128, 70, 48, 51, 48, + 128, 70, 48, 50, 57, 128, 70, 48, 50, 56, 128, 70, 48, 50, 55, 128, 70, + 48, 50, 54, 128, 70, 48, 50, 53, 128, 70, 48, 50, 52, 128, 70, 48, 50, + 51, 128, 70, 48, 50, 50, 128, 70, 48, 50, 49, 65, 128, 70, 48, 50, 49, + 128, 70, 48, 50, 48, 128, 70, 48, 49, 57, 128, 70, 48, 49, 56, 128, 70, + 48, 49, 55, 128, 70, 48, 49, 54, 128, 70, 48, 49, 53, 128, 70, 48, 49, + 52, 128, 70, 48, 49, 51, 65, 128, 70, 48, 49, 51, 128, 70, 48, 49, 50, + 128, 70, 48, 49, 49, 128, 70, 48, 49, 48, 128, 70, 48, 48, 57, 128, 70, + 48, 48, 56, 128, 70, 48, 48, 55, 128, 70, 48, 48, 54, 128, 70, 48, 48, + 53, 128, 70, 48, 48, 52, 128, 70, 48, 48, 51, 128, 70, 48, 48, 50, 128, + 70, 48, 48, 49, 65, 128, 70, 48, 48, 49, 128, 69, 90, 200, 69, 90, 69, + 78, 128, 69, 90, 69, 206, 69, 90, 128, 69, 89, 89, 89, 128, 69, 89, 69, + 83, 128, 69, 89, 69, 71, 76, 65, 83, 83, 69, 83, 128, 69, 89, 66, 69, 89, + 70, 73, 76, 73, 128, 69, 89, 65, 78, 78, 65, 128, 69, 88, 84, 82, 69, 77, + 69, 76, 217, 69, 88, 84, 82, 65, 84, 69, 82, 82, 69, 83, 84, 82, 73, 65, + 204, 69, 88, 84, 82, 65, 45, 76, 79, 215, 69, 88, 84, 82, 65, 45, 72, 73, + 71, 200, 69, 88, 84, 69, 78, 83, 73, 79, 78, 128, 69, 88, 84, 69, 78, 68, + 69, 68, 128, 69, 88, 84, 69, 78, 68, 69, 196, 69, 88, 80, 82, 69, 83, 83, + 73, 79, 78, 76, 69, 83, 211, 69, 88, 80, 79, 78, 69, 78, 212, 69, 88, 79, + 128, 69, 88, 207, 69, 88, 73, 83, 84, 83, 128, 69, 88, 73, 83, 84, 128, + 69, 88, 72, 65, 85, 83, 84, 73, 79, 78, 128, 69, 88, 67, 76, 65, 77, 65, + 84, 73, 79, 78, 128, 69, 88, 67, 76, 65, 77, 65, 84, 73, 79, 206, 69, 88, + 67, 72, 65, 78, 71, 69, 128, 69, 88, 67, 69, 83, 83, 128, 69, 88, 67, 69, + 76, 76, 69, 78, 84, 128, 69, 87, 69, 128, 69, 86, 69, 82, 71, 82, 69, 69, + 206, 69, 86, 69, 78, 73, 78, 71, 128, 69, 85, 82, 79, 80, 69, 65, 206, + 69, 85, 82, 79, 80, 69, 45, 65, 70, 82, 73, 67, 65, 128, 69, 85, 82, 79, + 45, 67, 85, 82, 82, 69, 78, 67, 217, 69, 85, 82, 207, 69, 85, 76, 69, + 210, 69, 85, 45, 85, 128, 69, 85, 45, 79, 128, 69, 85, 45, 69, 85, 128, + 69, 85, 45, 69, 79, 128, 69, 85, 45, 69, 128, 69, 85, 45, 65, 128, 69, + 84, 88, 128, 69, 84, 78, 65, 72, 84, 65, 128, 69, 84, 72, 69, 204, 69, + 84, 69, 82, 79, 206, 69, 84, 69, 82, 78, 73, 84, 89, 128, 69, 84, 69, 82, + 78, 73, 84, 217, 69, 84, 66, 128, 69, 83, 85, 75, 85, 85, 68, 79, 128, + 69, 83, 84, 73, 77, 65, 84, 69, 83, 128, 69, 83, 84, 73, 77, 65, 84, 69, + 196, 69, 83, 72, 69, 51, 128, 69, 83, 72, 50, 49, 128, 69, 83, 72, 49, + 54, 128, 69, 83, 67, 65, 80, 69, 128, 69, 83, 67, 128, 69, 83, 65, 128, + 69, 83, 45, 84, 69, 128, 69, 83, 45, 51, 128, 69, 83, 45, 50, 128, 69, + 83, 45, 49, 128, 69, 82, 82, 79, 82, 45, 66, 65, 82, 82, 69, 196, 69, 82, + 82, 128, 69, 82, 73, 78, 50, 128, 69, 82, 71, 128, 69, 82, 65, 83, 197, + 69, 81, 85, 73, 86, 65, 76, 69, 78, 212, 69, 81, 85, 73, 76, 65, 84, 69, + 82, 65, 204, 69, 81, 85, 73, 68, 128, 69, 81, 85, 73, 65, 78, 71, 85, 76, + 65, 210, 69, 81, 85, 65, 76, 83, 128, 69, 81, 85, 65, 76, 211, 69, 81, + 85, 65, 76, 128, 69, 80, 83, 73, 76, 79, 78, 128, 69, 80, 83, 73, 76, 79, 206, 69, 80, 79, 67, 72, 128, 69, 80, 73, 71, 82, 65, 80, 72, 73, 195, 69, 80, 73, 68, 65, 85, 82, 69, 65, 206, 69, 80, 69, 78, 84, 72, 69, 84, - 73, 195, 69, 80, 69, 71, 69, 82, 77, 65, 128, 69, 79, 84, 128, 69, 79, - 77, 128, 69, 79, 76, 72, 88, 128, 69, 79, 76, 128, 69, 79, 72, 128, 69, - 78, 89, 128, 69, 78, 86, 69, 76, 79, 80, 69, 128, 69, 78, 86, 69, 76, 79, - 80, 197, 69, 78, 85, 77, 69, 82, 65, 84, 73, 79, 206, 69, 78, 84, 82, 89, - 45, 50, 128, 69, 78, 84, 82, 89, 45, 49, 128, 69, 78, 84, 82, 89, 128, - 69, 78, 84, 82, 217, 69, 78, 84, 72, 85, 83, 73, 65, 83, 77, 128, 69, 78, - 84, 69, 82, 80, 82, 73, 83, 69, 128, 69, 78, 84, 69, 82, 73, 78, 199, 69, - 78, 84, 69, 82, 128, 69, 78, 84, 69, 210, 69, 78, 81, 85, 73, 82, 89, - 128, 69, 78, 81, 128, 69, 78, 79, 211, 69, 78, 78, 128, 69, 78, 76, 65, - 82, 71, 69, 77, 69, 78, 84, 128, 69, 78, 71, 73, 78, 69, 128, 69, 78, 68, - 79, 70, 79, 78, 79, 78, 128, 69, 78, 68, 73, 78, 199, 69, 78, 68, 69, 80, - 128, 69, 78, 68, 69, 65, 86, 79, 85, 82, 128, 69, 78, 67, 79, 85, 78, 84, - 69, 82, 83, 128, 69, 78, 67, 76, 79, 83, 85, 82, 69, 128, 69, 78, 67, 76, - 79, 83, 73, 78, 199, 69, 78, 67, 128, 69, 78, 65, 82, 88, 73, 211, 69, - 78, 65, 82, 77, 79, 78, 73, 79, 211, 69, 77, 80, 84, 217, 69, 77, 80, 72, - 65, 84, 73, 195, 69, 77, 80, 72, 65, 83, 73, 211, 69, 77, 66, 82, 79, 73, - 68, 69, 82, 89, 128, 69, 77, 66, 76, 69, 77, 128, 69, 77, 66, 69, 76, 76, - 73, 83, 72, 77, 69, 78, 84, 128, 69, 77, 66, 69, 68, 68, 73, 78, 71, 128, - 69, 76, 84, 128, 69, 76, 76, 73, 80, 84, 73, 195, 69, 76, 76, 73, 80, 83, - 73, 83, 128, 69, 76, 76, 73, 80, 83, 69, 128, 69, 76, 73, 70, 73, 128, - 69, 76, 69, 86, 69, 78, 45, 84, 72, 73, 82, 84, 89, 128, 69, 76, 69, 86, - 69, 78, 128, 69, 76, 69, 86, 69, 206, 69, 76, 69, 80, 72, 65, 78, 84, - 128, 69, 76, 69, 77, 69, 78, 212, 69, 76, 69, 67, 84, 82, 73, 67, 65, - 204, 69, 76, 69, 67, 84, 82, 73, 195, 69, 76, 65, 70, 82, 79, 78, 128, - 69, 75, 83, 84, 82, 69, 80, 84, 79, 78, 128, 69, 75, 83, 128, 69, 75, 70, - 79, 78, 73, 84, 73, 75, 79, 78, 128, 69, 75, 65, 82, 65, 128, 69, 74, 69, - 67, 212, 69, 73, 83, 128, 69, 73, 71, 72, 84, 89, 128, 69, 73, 71, 72, - 84, 217, 69, 73, 71, 72, 84, 72, 83, 128, 69, 73, 71, 72, 84, 72, 211, - 69, 73, 71, 72, 84, 72, 128, 69, 73, 71, 72, 84, 69, 69, 78, 128, 69, 73, - 71, 72, 84, 69, 69, 206, 69, 73, 71, 72, 84, 45, 84, 72, 73, 82, 84, 89, - 128, 69, 73, 69, 128, 69, 72, 87, 65, 218, 69, 71, 89, 80, 84, 79, 76, - 79, 71, 73, 67, 65, 204, 69, 71, 73, 82, 128, 69, 71, 71, 128, 69, 69, - 89, 65, 78, 78, 65, 128, 69, 69, 75, 65, 65, 128, 69, 69, 72, 128, 69, - 69, 66, 69, 69, 70, 73, 76, 73, 128, 69, 68, 73, 84, 79, 82, 73, 65, 204, - 69, 68, 73, 78, 128, 69, 68, 68, 128, 69, 66, 69, 70, 73, 76, 73, 128, - 69, 65, 83, 84, 69, 82, 206, 69, 65, 83, 212, 69, 65, 82, 84, 72, 76, - 217, 69, 65, 82, 84, 72, 128, 69, 65, 82, 84, 200, 69, 65, 82, 83, 128, - 69, 65, 82, 76, 217, 69, 65, 77, 72, 65, 78, 67, 72, 79, 76, 76, 128, 69, - 65, 71, 76, 69, 128, 69, 65, 68, 72, 65, 68, 72, 128, 69, 65, 66, 72, 65, - 68, 72, 128, 69, 178, 69, 48, 51, 56, 128, 69, 48, 51, 55, 128, 69, 48, - 51, 54, 128, 69, 48, 51, 52, 65, 128, 69, 48, 51, 52, 128, 69, 48, 51, - 51, 128, 69, 48, 51, 50, 128, 69, 48, 51, 49, 128, 69, 48, 51, 48, 128, - 69, 48, 50, 57, 128, 69, 48, 50, 56, 65, 128, 69, 48, 50, 56, 128, 69, - 48, 50, 55, 128, 69, 48, 50, 54, 128, 69, 48, 50, 53, 128, 69, 48, 50, - 52, 128, 69, 48, 50, 51, 128, 69, 48, 50, 50, 128, 69, 48, 50, 49, 128, - 69, 48, 50, 48, 65, 128, 69, 48, 50, 48, 128, 69, 48, 49, 57, 128, 69, - 48, 49, 56, 128, 69, 48, 49, 55, 65, 128, 69, 48, 49, 55, 128, 69, 48, - 49, 54, 65, 128, 69, 48, 49, 54, 128, 69, 48, 49, 53, 128, 69, 48, 49, - 52, 128, 69, 48, 49, 51, 128, 69, 48, 49, 50, 128, 69, 48, 49, 49, 128, - 69, 48, 49, 48, 128, 69, 48, 48, 57, 65, 128, 69, 48, 48, 57, 128, 69, - 48, 48, 56, 65, 128, 69, 48, 48, 56, 128, 69, 48, 48, 55, 128, 69, 48, - 48, 54, 128, 69, 48, 48, 53, 128, 69, 48, 48, 52, 128, 69, 48, 48, 51, - 128, 69, 48, 48, 50, 128, 69, 48, 48, 49, 128, 69, 45, 77, 65, 73, 204, - 68, 90, 90, 69, 128, 68, 90, 90, 65, 128, 68, 90, 87, 69, 128, 68, 90, - 85, 128, 68, 90, 79, 128, 68, 90, 74, 69, 128, 68, 90, 73, 128, 68, 90, - 72, 69, 128, 68, 90, 72, 65, 128, 68, 90, 69, 76, 79, 128, 68, 90, 69, - 69, 128, 68, 90, 69, 128, 68, 90, 65, 65, 128, 68, 90, 65, 128, 68, 90, - 128, 68, 218, 68, 89, 79, 128, 68, 89, 207, 68, 89, 69, 72, 128, 68, 89, - 69, 200, 68, 87, 79, 128, 68, 87, 69, 128, 68, 87, 65, 128, 68, 86, 73, - 83, 86, 65, 82, 65, 128, 68, 86, 68, 128, 68, 86, 128, 68, 85, 84, 73, - 69, 83, 128, 68, 85, 83, 75, 128, 68, 85, 83, 72, 69, 78, 78, 65, 128, - 68, 85, 82, 65, 84, 73, 79, 78, 128, 68, 85, 82, 50, 128, 68, 85, 80, 79, - 78, 68, 73, 85, 211, 68, 85, 79, 88, 128, 68, 85, 79, 128, 68, 85, 78, - 52, 128, 68, 85, 78, 51, 128, 68, 85, 78, 179, 68, 85, 77, 128, 68, 85, - 204, 68, 85, 72, 128, 68, 85, 71, 85, 68, 128, 68, 85, 66, 50, 128, 68, - 85, 66, 128, 68, 85, 194, 68, 82, 89, 128, 68, 82, 217, 68, 82, 85, 77, - 128, 68, 82, 85, 205, 68, 82, 79, 80, 83, 128, 68, 82, 79, 80, 76, 69, - 84, 128, 68, 82, 79, 80, 45, 83, 72, 65, 68, 79, 87, 69, 196, 68, 82, 79, - 77, 69, 68, 65, 82, 217, 68, 82, 73, 86, 69, 128, 68, 82, 73, 86, 197, - 68, 82, 73, 78, 75, 128, 68, 82, 73, 204, 68, 82, 69, 83, 83, 128, 68, - 82, 65, 85, 71, 72, 84, 211, 68, 82, 65, 77, 128, 68, 82, 65, 205, 68, - 82, 65, 71, 79, 78, 128, 68, 82, 65, 71, 79, 206, 68, 82, 65, 70, 84, 73, - 78, 199, 68, 82, 65, 67, 72, 77, 65, 83, 128, 68, 82, 65, 67, 72, 77, 65, - 128, 68, 82, 65, 67, 72, 77, 193, 68, 79, 87, 78, 87, 65, 82, 68, 83, - 128, 68, 79, 87, 78, 87, 65, 82, 68, 211, 68, 79, 87, 78, 45, 80, 79, 73, - 78, 84, 73, 78, 199, 68, 79, 87, 78, 128, 68, 79, 86, 69, 128, 68, 79, - 85, 71, 72, 78, 85, 84, 128, 68, 79, 85, 66, 84, 128, 68, 79, 85, 66, 76, - 69, 196, 68, 79, 85, 66, 76, 69, 45, 76, 73, 78, 197, 68, 79, 85, 66, 76, - 69, 45, 69, 78, 68, 69, 196, 68, 79, 85, 66, 76, 69, 128, 68, 79, 84, 84, - 69, 68, 45, 80, 128, 68, 79, 84, 84, 69, 68, 45, 78, 128, 68, 79, 84, 84, - 69, 68, 45, 76, 128, 68, 79, 84, 84, 69, 68, 128, 68, 79, 84, 84, 69, - 196, 68, 79, 84, 83, 45, 56, 128, 68, 79, 84, 83, 45, 55, 56, 128, 68, - 79, 84, 83, 45, 55, 128, 68, 79, 84, 83, 45, 54, 56, 128, 68, 79, 84, 83, - 45, 54, 55, 56, 128, 68, 79, 84, 83, 45, 54, 55, 128, 68, 79, 84, 83, 45, - 54, 128, 68, 79, 84, 83, 45, 53, 56, 128, 68, 79, 84, 83, 45, 53, 55, 56, - 128, 68, 79, 84, 83, 45, 53, 55, 128, 68, 79, 84, 83, 45, 53, 54, 56, - 128, 68, 79, 84, 83, 45, 53, 54, 55, 56, 128, 68, 79, 84, 83, 45, 53, 54, - 55, 128, 68, 79, 84, 83, 45, 53, 54, 128, 68, 79, 84, 83, 45, 53, 128, - 68, 79, 84, 83, 45, 52, 56, 128, 68, 79, 84, 83, 45, 52, 55, 56, 128, 68, - 79, 84, 83, 45, 52, 55, 128, 68, 79, 84, 83, 45, 52, 54, 56, 128, 68, 79, - 84, 83, 45, 52, 54, 55, 56, 128, 68, 79, 84, 83, 45, 52, 54, 55, 128, 68, - 79, 84, 83, 45, 52, 54, 128, 68, 79, 84, 83, 45, 52, 53, 56, 128, 68, 79, - 84, 83, 45, 52, 53, 55, 56, 128, 68, 79, 84, 83, 45, 52, 53, 55, 128, 68, - 79, 84, 83, 45, 52, 53, 54, 56, 128, 68, 79, 84, 83, 45, 52, 53, 54, 55, - 56, 128, 68, 79, 84, 83, 45, 52, 53, 54, 55, 128, 68, 79, 84, 83, 45, 52, - 53, 54, 128, 68, 79, 84, 83, 45, 52, 53, 128, 68, 79, 84, 83, 45, 52, - 128, 68, 79, 84, 83, 45, 51, 56, 128, 68, 79, 84, 83, 45, 51, 55, 56, - 128, 68, 79, 84, 83, 45, 51, 55, 128, 68, 79, 84, 83, 45, 51, 54, 56, + 73, 195, 69, 80, 69, 71, 69, 82, 77, 65, 128, 69, 80, 65, 67, 212, 69, + 79, 84, 128, 69, 79, 77, 128, 69, 79, 76, 72, 88, 128, 69, 79, 76, 128, + 69, 79, 72, 128, 69, 78, 89, 128, 69, 78, 86, 69, 76, 79, 80, 69, 128, + 69, 78, 86, 69, 76, 79, 80, 197, 69, 78, 85, 77, 69, 82, 65, 84, 73, 79, + 206, 69, 78, 84, 82, 89, 45, 50, 128, 69, 78, 84, 82, 89, 45, 49, 128, + 69, 78, 84, 82, 89, 128, 69, 78, 84, 82, 217, 69, 78, 84, 72, 85, 83, 73, + 65, 83, 77, 128, 69, 78, 84, 69, 82, 80, 82, 73, 83, 69, 128, 69, 78, 84, + 69, 82, 73, 78, 199, 69, 78, 84, 69, 82, 128, 69, 78, 84, 69, 210, 69, + 78, 81, 85, 73, 82, 89, 128, 69, 78, 81, 128, 69, 78, 79, 211, 69, 78, + 78, 73, 128, 69, 78, 78, 128, 69, 78, 76, 65, 82, 71, 69, 77, 69, 78, 84, + 128, 69, 78, 71, 73, 78, 69, 128, 69, 78, 68, 79, 70, 79, 78, 79, 78, + 128, 69, 78, 68, 73, 78, 199, 69, 78, 68, 69, 80, 128, 69, 78, 68, 69, + 65, 86, 79, 85, 82, 128, 69, 78, 67, 79, 85, 78, 84, 69, 82, 83, 128, 69, + 78, 67, 76, 79, 83, 85, 82, 69, 128, 69, 78, 67, 76, 79, 83, 73, 78, 199, + 69, 78, 67, 128, 69, 78, 65, 82, 88, 73, 211, 69, 78, 65, 82, 77, 79, 78, + 73, 79, 211, 69, 77, 80, 84, 217, 69, 77, 80, 72, 65, 84, 73, 195, 69, + 77, 80, 72, 65, 83, 73, 211, 69, 77, 66, 82, 79, 73, 68, 69, 82, 89, 128, + 69, 77, 66, 76, 69, 77, 128, 69, 77, 66, 69, 76, 76, 73, 83, 72, 77, 69, + 78, 84, 128, 69, 77, 66, 69, 68, 68, 73, 78, 71, 128, 69, 76, 84, 128, + 69, 76, 76, 73, 80, 84, 73, 195, 69, 76, 76, 73, 80, 83, 73, 83, 128, 69, + 76, 76, 73, 80, 83, 69, 128, 69, 76, 73, 70, 73, 128, 69, 76, 69, 86, 69, + 78, 45, 84, 72, 73, 82, 84, 89, 128, 69, 76, 69, 86, 69, 78, 128, 69, 76, + 69, 86, 69, 206, 69, 76, 69, 80, 72, 65, 78, 84, 128, 69, 76, 69, 77, 69, + 78, 212, 69, 76, 69, 67, 84, 82, 73, 67, 65, 204, 69, 76, 69, 67, 84, 82, + 73, 195, 69, 76, 66, 65, 83, 65, 206, 69, 76, 65, 77, 73, 84, 69, 128, + 69, 76, 65, 77, 73, 84, 197, 69, 76, 65, 70, 82, 79, 78, 128, 69, 75, 83, + 84, 82, 69, 80, 84, 79, 78, 128, 69, 75, 83, 128, 69, 75, 70, 79, 78, 73, + 84, 73, 75, 79, 78, 128, 69, 75, 65, 82, 65, 128, 69, 75, 65, 77, 128, + 69, 74, 69, 67, 212, 69, 73, 83, 128, 69, 73, 71, 72, 84, 89, 128, 69, + 73, 71, 72, 84, 217, 69, 73, 71, 72, 84, 72, 83, 128, 69, 73, 71, 72, 84, + 72, 211, 69, 73, 71, 72, 84, 72, 128, 69, 73, 71, 72, 84, 69, 69, 78, + 128, 69, 73, 71, 72, 84, 69, 69, 206, 69, 73, 71, 72, 84, 45, 84, 72, 73, + 82, 84, 89, 128, 69, 73, 69, 128, 69, 72, 87, 65, 218, 69, 71, 89, 80, + 84, 79, 76, 79, 71, 73, 67, 65, 204, 69, 71, 73, 82, 128, 69, 71, 71, + 128, 69, 69, 89, 65, 78, 78, 65, 128, 69, 69, 75, 65, 65, 128, 69, 69, + 72, 128, 69, 69, 66, 69, 69, 70, 73, 76, 73, 128, 69, 68, 73, 84, 79, 82, + 73, 65, 204, 69, 68, 73, 78, 128, 69, 68, 68, 128, 69, 66, 69, 70, 73, + 76, 73, 128, 69, 65, 83, 84, 69, 82, 206, 69, 65, 83, 84, 128, 69, 65, + 83, 212, 69, 65, 82, 84, 72, 76, 217, 69, 65, 82, 84, 72, 128, 69, 65, + 82, 84, 200, 69, 65, 82, 83, 128, 69, 65, 82, 76, 217, 69, 65, 77, 72, + 65, 78, 67, 72, 79, 76, 76, 128, 69, 65, 71, 76, 69, 128, 69, 65, 68, 72, + 65, 68, 72, 128, 69, 65, 66, 72, 65, 68, 72, 128, 69, 178, 69, 48, 51, + 56, 128, 69, 48, 51, 55, 128, 69, 48, 51, 54, 128, 69, 48, 51, 52, 65, + 128, 69, 48, 51, 52, 128, 69, 48, 51, 51, 128, 69, 48, 51, 50, 128, 69, + 48, 51, 49, 128, 69, 48, 51, 48, 128, 69, 48, 50, 57, 128, 69, 48, 50, + 56, 65, 128, 69, 48, 50, 56, 128, 69, 48, 50, 55, 128, 69, 48, 50, 54, + 128, 69, 48, 50, 53, 128, 69, 48, 50, 52, 128, 69, 48, 50, 51, 128, 69, + 48, 50, 50, 128, 69, 48, 50, 49, 128, 69, 48, 50, 48, 65, 128, 69, 48, + 50, 48, 128, 69, 48, 49, 57, 128, 69, 48, 49, 56, 128, 69, 48, 49, 55, + 65, 128, 69, 48, 49, 55, 128, 69, 48, 49, 54, 65, 128, 69, 48, 49, 54, + 128, 69, 48, 49, 53, 128, 69, 48, 49, 52, 128, 69, 48, 49, 51, 128, 69, + 48, 49, 50, 128, 69, 48, 49, 49, 128, 69, 48, 49, 48, 128, 69, 48, 48, + 57, 65, 128, 69, 48, 48, 57, 128, 69, 48, 48, 56, 65, 128, 69, 48, 48, + 56, 128, 69, 48, 48, 55, 128, 69, 48, 48, 54, 128, 69, 48, 48, 53, 128, + 69, 48, 48, 52, 128, 69, 48, 48, 51, 128, 69, 48, 48, 50, 128, 69, 48, + 48, 49, 128, 69, 45, 77, 65, 73, 204, 68, 90, 90, 72, 69, 128, 68, 90, + 90, 69, 128, 68, 90, 90, 65, 128, 68, 90, 89, 65, 89, 128, 68, 90, 87, + 69, 128, 68, 90, 85, 128, 68, 90, 79, 128, 68, 90, 74, 69, 128, 68, 90, + 73, 84, 65, 128, 68, 90, 73, 128, 68, 90, 72, 79, 73, 128, 68, 90, 72, + 69, 128, 68, 90, 72, 65, 128, 68, 90, 69, 76, 79, 128, 68, 90, 69, 69, + 128, 68, 90, 69, 128, 68, 90, 65, 89, 128, 68, 90, 65, 65, 128, 68, 90, + 65, 128, 68, 90, 128, 68, 218, 68, 89, 79, 128, 68, 89, 207, 68, 89, 69, + 72, 128, 68, 89, 69, 200, 68, 89, 65, 78, 128, 68, 87, 79, 128, 68, 87, + 69, 128, 68, 87, 65, 128, 68, 86, 73, 83, 86, 65, 82, 65, 128, 68, 86, + 68, 128, 68, 86, 128, 68, 85, 84, 73, 69, 83, 128, 68, 85, 83, 75, 128, + 68, 85, 83, 72, 69, 78, 78, 65, 128, 68, 85, 82, 65, 84, 73, 79, 78, 128, + 68, 85, 82, 50, 128, 68, 85, 80, 79, 78, 68, 73, 85, 211, 68, 85, 79, 88, + 128, 68, 85, 79, 128, 68, 85, 78, 52, 128, 68, 85, 78, 51, 128, 68, 85, + 78, 179, 68, 85, 77, 128, 68, 85, 204, 68, 85, 72, 128, 68, 85, 71, 85, + 68, 128, 68, 85, 66, 50, 128, 68, 85, 66, 128, 68, 85, 194, 68, 82, 89, + 128, 68, 82, 217, 68, 82, 85, 77, 128, 68, 82, 85, 205, 68, 82, 79, 80, + 83, 128, 68, 82, 79, 80, 76, 69, 84, 128, 68, 82, 79, 80, 45, 83, 72, 65, + 68, 79, 87, 69, 196, 68, 82, 79, 77, 69, 68, 65, 82, 217, 68, 82, 73, 86, + 69, 128, 68, 82, 73, 86, 197, 68, 82, 73, 78, 75, 128, 68, 82, 73, 204, + 68, 82, 69, 83, 83, 128, 68, 82, 65, 85, 71, 72, 84, 211, 68, 82, 65, 77, + 128, 68, 82, 65, 205, 68, 82, 65, 71, 79, 78, 128, 68, 82, 65, 71, 79, + 206, 68, 82, 65, 70, 84, 73, 78, 199, 68, 82, 65, 67, 72, 77, 65, 83, + 128, 68, 82, 65, 67, 72, 77, 65, 128, 68, 82, 65, 67, 72, 77, 193, 68, + 79, 87, 78, 87, 65, 82, 68, 83, 128, 68, 79, 87, 78, 45, 80, 79, 73, 78, + 84, 73, 78, 199, 68, 79, 87, 78, 128, 68, 79, 86, 69, 128, 68, 79, 86, + 197, 68, 79, 85, 71, 72, 78, 85, 84, 128, 68, 79, 85, 66, 84, 128, 68, + 79, 85, 66, 76, 69, 196, 68, 79, 85, 66, 76, 69, 45, 76, 73, 78, 197, 68, + 79, 85, 66, 76, 69, 45, 69, 78, 68, 69, 196, 68, 79, 85, 66, 76, 69, 128, + 68, 79, 84, 84, 69, 68, 45, 80, 128, 68, 79, 84, 84, 69, 68, 45, 78, 128, + 68, 79, 84, 84, 69, 68, 45, 76, 128, 68, 79, 84, 84, 69, 68, 128, 68, 79, + 84, 84, 69, 196, 68, 79, 84, 83, 45, 56, 128, 68, 79, 84, 83, 45, 55, 56, + 128, 68, 79, 84, 83, 45, 55, 128, 68, 79, 84, 83, 45, 54, 56, 128, 68, + 79, 84, 83, 45, 54, 55, 56, 128, 68, 79, 84, 83, 45, 54, 55, 128, 68, 79, + 84, 83, 45, 54, 128, 68, 79, 84, 83, 45, 53, 56, 128, 68, 79, 84, 83, 45, + 53, 55, 56, 128, 68, 79, 84, 83, 45, 53, 55, 128, 68, 79, 84, 83, 45, 53, + 54, 56, 128, 68, 79, 84, 83, 45, 53, 54, 55, 56, 128, 68, 79, 84, 83, 45, + 53, 54, 55, 128, 68, 79, 84, 83, 45, 53, 54, 128, 68, 79, 84, 83, 45, 53, + 128, 68, 79, 84, 83, 45, 52, 56, 128, 68, 79, 84, 83, 45, 52, 55, 56, + 128, 68, 79, 84, 83, 45, 52, 55, 128, 68, 79, 84, 83, 45, 52, 54, 56, + 128, 68, 79, 84, 83, 45, 52, 54, 55, 56, 128, 68, 79, 84, 83, 45, 52, 54, + 55, 128, 68, 79, 84, 83, 45, 52, 54, 128, 68, 79, 84, 83, 45, 52, 53, 56, + 128, 68, 79, 84, 83, 45, 52, 53, 55, 56, 128, 68, 79, 84, 83, 45, 52, 53, + 55, 128, 68, 79, 84, 83, 45, 52, 53, 54, 56, 128, 68, 79, 84, 83, 45, 52, + 53, 54, 55, 56, 128, 68, 79, 84, 83, 45, 52, 53, 54, 55, 128, 68, 79, 84, + 83, 45, 52, 53, 54, 128, 68, 79, 84, 83, 45, 52, 53, 128, 68, 79, 84, 83, + 45, 52, 128, 68, 79, 84, 83, 45, 51, 56, 128, 68, 79, 84, 83, 45, 51, 55, + 56, 128, 68, 79, 84, 83, 45, 51, 55, 128, 68, 79, 84, 83, 45, 51, 54, 56, 128, 68, 79, 84, 83, 45, 51, 54, 55, 56, 128, 68, 79, 84, 83, 45, 51, 54, 55, 128, 68, 79, 84, 83, 45, 51, 54, 128, 68, 79, 84, 83, 45, 51, 53, 56, 128, 68, 79, 84, 83, 45, 51, 53, 55, 56, 128, 68, 79, 84, 83, 45, 51, 53, @@ -3952,99 +4150,106 @@ static unsigned char lexicon[] = { 71, 128, 68, 79, 78, 71, 128, 68, 79, 77, 65, 73, 206, 68, 79, 76, 80, 72, 73, 78, 128, 68, 79, 76, 76, 83, 128, 68, 79, 76, 76, 65, 210, 68, 79, 76, 73, 85, 77, 128, 68, 79, 75, 77, 65, 73, 128, 68, 79, 73, 84, - 128, 68, 79, 71, 128, 68, 79, 199, 68, 79, 69, 211, 68, 79, 68, 69, 75, - 65, 84, 65, 128, 68, 79, 66, 82, 79, 128, 68, 79, 65, 67, 72, 65, 83, 72, - 77, 69, 69, 128, 68, 79, 65, 67, 72, 65, 83, 72, 77, 69, 197, 68, 79, 65, - 128, 68, 79, 45, 79, 128, 68, 77, 128, 68, 205, 68, 76, 85, 128, 68, 76, - 79, 128, 68, 76, 73, 128, 68, 76, 72, 89, 65, 128, 68, 76, 72, 65, 128, - 68, 76, 69, 69, 128, 68, 76, 65, 128, 68, 76, 128, 68, 75, 65, 82, 128, - 68, 75, 65, 210, 68, 74, 69, 82, 86, 73, 128, 68, 74, 69, 82, 86, 128, - 68, 74, 69, 128, 68, 74, 65, 128, 68, 73, 90, 90, 217, 68, 73, 86, 79, - 82, 67, 197, 68, 73, 86, 73, 83, 73, 79, 78, 128, 68, 73, 86, 73, 83, 73, - 79, 206, 68, 73, 86, 73, 78, 65, 84, 73, 79, 78, 128, 68, 73, 86, 73, 68, - 69, 83, 128, 68, 73, 86, 73, 68, 69, 82, 128, 68, 73, 86, 73, 68, 69, - 196, 68, 73, 86, 73, 68, 69, 128, 68, 73, 86, 73, 68, 197, 68, 73, 86, - 69, 82, 71, 69, 78, 67, 69, 128, 68, 73, 84, 84, 207, 68, 73, 83, 84, 79, - 82, 84, 73, 79, 78, 128, 68, 73, 83, 84, 73, 78, 71, 85, 73, 83, 72, 128, - 68, 73, 83, 84, 73, 76, 76, 128, 68, 73, 83, 83, 79, 76, 86, 69, 45, 50, - 128, 68, 73, 83, 83, 79, 76, 86, 69, 128, 68, 73, 83, 80, 69, 82, 83, 73, - 79, 78, 128, 68, 73, 83, 75, 128, 68, 73, 83, 73, 77, 79, 85, 128, 68, - 73, 83, 72, 128, 68, 73, 83, 67, 79, 78, 84, 73, 78, 85, 79, 85, 211, 68, - 73, 83, 195, 68, 73, 83, 65, 80, 80, 79, 73, 78, 84, 69, 196, 68, 73, 83, - 65, 66, 76, 69, 196, 68, 73, 82, 71, 193, 68, 73, 82, 69, 67, 84, 76, - 217, 68, 73, 82, 69, 67, 84, 73, 79, 78, 65, 204, 68, 73, 80, 84, 69, - 128, 68, 73, 80, 80, 69, 82, 128, 68, 73, 80, 76, 79, 85, 78, 128, 68, - 73, 80, 76, 73, 128, 68, 73, 80, 76, 201, 68, 73, 78, 71, 66, 65, 212, - 68, 73, 206, 68, 73, 77, 77, 73, 78, 71, 128, 68, 73, 77, 73, 78, 85, 84, - 73, 79, 78, 45, 51, 128, 68, 73, 77, 73, 78, 85, 84, 73, 79, 78, 45, 50, - 128, 68, 73, 77, 73, 78, 85, 84, 73, 79, 78, 45, 49, 128, 68, 73, 77, 73, - 78, 73, 83, 72, 77, 69, 78, 84, 128, 68, 73, 77, 73, 68, 73, 193, 68, 73, - 77, 69, 78, 83, 73, 79, 78, 65, 204, 68, 73, 77, 69, 78, 83, 73, 79, 206, - 68, 73, 77, 50, 128, 68, 73, 76, 128, 68, 73, 71, 82, 65, 80, 72, 128, - 68, 73, 71, 82, 65, 80, 200, 68, 73, 71, 82, 65, 77, 77, 79, 211, 68, 73, - 71, 82, 65, 77, 77, 193, 68, 73, 71, 82, 65, 205, 68, 73, 71, 79, 82, 71, - 79, 78, 128, 68, 73, 71, 79, 82, 71, 79, 206, 68, 73, 71, 65, 77, 77, 65, - 128, 68, 73, 71, 193, 68, 73, 70, 84, 79, 71, 71, 79, 211, 68, 73, 70, - 79, 78, 73, 65, 83, 128, 68, 73, 70, 70, 73, 67, 85, 76, 84, 217, 68, 73, - 70, 70, 73, 67, 85, 76, 84, 73, 69, 83, 128, 68, 73, 70, 70, 69, 82, 69, - 78, 84, 73, 65, 76, 128, 68, 73, 70, 70, 69, 82, 69, 78, 67, 197, 68, 73, - 70, 65, 84, 128, 68, 73, 69, 83, 73, 83, 128, 68, 73, 69, 83, 73, 211, - 68, 73, 69, 80, 128, 68, 73, 197, 68, 73, 66, 128, 68, 73, 65, 84, 79, - 78, 79, 206, 68, 73, 65, 84, 79, 78, 73, 75, 201, 68, 73, 65, 83, 84, 79, - 76, 201, 68, 73, 65, 77, 79, 78, 68, 83, 128, 68, 73, 65, 77, 79, 78, 68, - 128, 68, 73, 65, 77, 79, 78, 196, 68, 73, 65, 77, 69, 84, 69, 210, 68, - 73, 65, 76, 89, 84, 73, 75, 65, 128, 68, 73, 65, 76, 89, 84, 73, 75, 193, - 68, 73, 65, 76, 69, 67, 84, 45, 208, 68, 73, 65, 71, 79, 78, 65, 76, 128, - 68, 73, 65, 71, 79, 78, 65, 204, 68, 73, 65, 69, 82, 69, 83, 73, 90, 69, - 196, 68, 73, 65, 69, 82, 69, 83, 73, 83, 128, 68, 73, 65, 69, 82, 69, 83, - 73, 211, 68, 72, 79, 85, 128, 68, 72, 79, 79, 128, 68, 72, 79, 128, 68, - 72, 73, 128, 68, 72, 72, 85, 128, 68, 72, 72, 79, 79, 128, 68, 72, 72, - 79, 128, 68, 72, 72, 73, 128, 68, 72, 72, 69, 69, 128, 68, 72, 72, 69, - 128, 68, 72, 72, 65, 128, 68, 72, 69, 69, 128, 68, 72, 65, 82, 77, 65, - 128, 68, 72, 65, 76, 69, 84, 72, 128, 68, 72, 65, 76, 65, 84, 72, 128, - 68, 72, 65, 76, 128, 68, 72, 65, 68, 72, 69, 128, 68, 72, 65, 65, 76, 85, - 128, 68, 72, 65, 65, 128, 68, 72, 65, 128, 68, 69, 90, 200, 68, 69, 89, - 84, 69, 82, 79, 213, 68, 69, 89, 84, 69, 82, 79, 211, 68, 69, 88, 73, 65, - 128, 68, 69, 86, 73, 67, 197, 68, 69, 86, 69, 76, 79, 80, 77, 69, 78, 84, - 128, 68, 69, 85, 78, 71, 128, 68, 69, 83, 203, 68, 69, 83, 73, 71, 78, - 128, 68, 69, 83, 73, 128, 68, 69, 83, 67, 82, 73, 80, 84, 73, 79, 206, - 68, 69, 83, 67, 69, 78, 68, 73, 78, 199, 68, 69, 83, 67, 69, 78, 68, 69, - 82, 128, 68, 69, 82, 69, 84, 45, 72, 73, 68, 69, 84, 128, 68, 69, 82, 69, - 84, 128, 68, 69, 80, 65, 82, 84, 85, 82, 69, 128, 68, 69, 80, 65, 82, 84, - 77, 69, 78, 212, 68, 69, 80, 65, 82, 84, 73, 78, 199, 68, 69, 78, 84, 73, - 83, 84, 82, 217, 68, 69, 78, 84, 65, 204, 68, 69, 78, 79, 77, 73, 78, 65, - 84, 79, 82, 128, 68, 69, 78, 79, 77, 73, 78, 65, 84, 79, 210, 68, 69, 78, - 78, 69, 78, 128, 68, 69, 78, 71, 128, 68, 69, 78, 197, 68, 69, 78, 65, - 82, 73, 85, 211, 68, 69, 76, 84, 65, 128, 68, 69, 76, 84, 193, 68, 69, - 76, 84, 128, 68, 69, 76, 80, 72, 73, 195, 68, 69, 76, 73, 86, 69, 82, - 217, 68, 69, 76, 73, 86, 69, 82, 65, 78, 67, 69, 128, 68, 69, 76, 73, 77, - 73, 84, 69, 82, 128, 68, 69, 76, 73, 77, 73, 84, 69, 210, 68, 69, 76, 73, - 67, 73, 79, 85, 211, 68, 69, 76, 69, 84, 69, 128, 68, 69, 76, 69, 84, - 197, 68, 69, 75, 65, 128, 68, 69, 75, 128, 68, 69, 73, 128, 68, 69, 72, - 73, 128, 68, 69, 71, 82, 69, 197, 68, 69, 70, 73, 78, 73, 84, 73, 79, 78, + 128, 68, 79, 73, 128, 68, 79, 71, 128, 68, 79, 199, 68, 79, 69, 211, 68, + 79, 68, 69, 75, 65, 84, 65, 128, 68, 79, 67, 85, 77, 69, 78, 84, 128, 68, + 79, 67, 85, 77, 69, 78, 212, 68, 79, 66, 82, 79, 128, 68, 79, 65, 67, 72, + 65, 83, 72, 77, 69, 69, 128, 68, 79, 65, 67, 72, 65, 83, 72, 77, 69, 197, + 68, 79, 65, 128, 68, 79, 45, 79, 128, 68, 77, 128, 68, 205, 68, 76, 85, + 128, 68, 76, 79, 128, 68, 76, 73, 128, 68, 76, 72, 89, 65, 128, 68, 76, + 72, 65, 128, 68, 76, 69, 69, 128, 68, 76, 65, 128, 68, 76, 128, 68, 75, + 65, 82, 128, 68, 75, 65, 210, 68, 74, 69, 82, 86, 73, 128, 68, 74, 69, + 82, 86, 128, 68, 74, 69, 128, 68, 74, 65, 128, 68, 73, 90, 90, 217, 68, + 73, 86, 79, 82, 67, 197, 68, 73, 86, 73, 83, 73, 79, 78, 128, 68, 73, 86, + 73, 83, 73, 79, 206, 68, 73, 86, 73, 78, 65, 84, 73, 79, 78, 128, 68, 73, + 86, 73, 68, 69, 83, 128, 68, 73, 86, 73, 68, 69, 82, 83, 128, 68, 73, 86, + 73, 68, 69, 82, 128, 68, 73, 86, 73, 68, 69, 196, 68, 73, 86, 73, 68, 69, + 128, 68, 73, 86, 73, 68, 197, 68, 73, 86, 69, 82, 71, 69, 78, 67, 69, + 128, 68, 73, 84, 84, 207, 68, 73, 83, 84, 79, 82, 84, 73, 79, 78, 128, + 68, 73, 83, 84, 73, 78, 71, 85, 73, 83, 72, 128, 68, 73, 83, 84, 73, 76, + 76, 128, 68, 73, 83, 83, 79, 76, 86, 69, 45, 50, 128, 68, 73, 83, 83, 79, + 76, 86, 69, 128, 68, 73, 83, 80, 69, 82, 83, 73, 79, 78, 128, 68, 73, 83, + 75, 128, 68, 73, 83, 73, 77, 79, 85, 128, 68, 73, 83, 72, 128, 68, 73, + 83, 67, 79, 78, 84, 73, 78, 85, 79, 85, 211, 68, 73, 83, 195, 68, 73, 83, + 65, 80, 80, 79, 73, 78, 84, 69, 196, 68, 73, 83, 65, 66, 76, 69, 196, 68, + 73, 82, 71, 193, 68, 73, 82, 69, 67, 84, 76, 217, 68, 73, 82, 69, 67, 84, + 73, 79, 78, 65, 204, 68, 73, 80, 84, 69, 128, 68, 73, 80, 80, 69, 82, + 128, 68, 73, 80, 76, 79, 85, 78, 128, 68, 73, 80, 76, 73, 128, 68, 73, + 80, 76, 201, 68, 73, 78, 71, 66, 65, 212, 68, 73, 206, 68, 73, 77, 77, + 73, 78, 71, 128, 68, 73, 77, 73, 78, 85, 84, 73, 79, 78, 45, 51, 128, 68, + 73, 77, 73, 78, 85, 84, 73, 79, 78, 45, 50, 128, 68, 73, 77, 73, 78, 85, + 84, 73, 79, 78, 45, 49, 128, 68, 73, 77, 73, 78, 73, 83, 72, 77, 69, 78, + 84, 128, 68, 73, 77, 73, 68, 73, 193, 68, 73, 77, 69, 78, 83, 73, 79, 78, + 65, 204, 68, 73, 77, 69, 78, 83, 73, 79, 206, 68, 73, 77, 50, 128, 68, + 73, 76, 128, 68, 73, 71, 82, 65, 80, 72, 128, 68, 73, 71, 82, 65, 80, + 200, 68, 73, 71, 82, 65, 77, 77, 79, 211, 68, 73, 71, 82, 65, 77, 77, + 193, 68, 73, 71, 82, 65, 205, 68, 73, 71, 79, 82, 71, 79, 78, 128, 68, + 73, 71, 79, 82, 71, 79, 206, 68, 73, 71, 65, 77, 77, 65, 128, 68, 73, 71, + 193, 68, 73, 70, 84, 79, 71, 71, 79, 211, 68, 73, 70, 79, 78, 73, 65, 83, + 128, 68, 73, 70, 70, 73, 67, 85, 76, 84, 217, 68, 73, 70, 70, 73, 67, 85, + 76, 84, 73, 69, 83, 128, 68, 73, 70, 70, 69, 82, 69, 78, 84, 73, 65, 76, + 128, 68, 73, 70, 70, 69, 82, 69, 78, 67, 197, 68, 73, 70, 65, 84, 128, + 68, 73, 69, 83, 73, 83, 128, 68, 73, 69, 83, 73, 211, 68, 73, 69, 83, 69, + 204, 68, 73, 69, 80, 128, 68, 73, 197, 68, 73, 66, 128, 68, 73, 65, 84, + 79, 78, 79, 206, 68, 73, 65, 84, 79, 78, 73, 75, 201, 68, 73, 65, 83, 84, + 79, 76, 201, 68, 73, 65, 77, 79, 78, 68, 83, 128, 68, 73, 65, 77, 79, 78, + 68, 128, 68, 73, 65, 77, 79, 78, 196, 68, 73, 65, 77, 69, 84, 69, 210, + 68, 73, 65, 76, 89, 84, 73, 75, 65, 128, 68, 73, 65, 76, 89, 84, 73, 75, + 193, 68, 73, 65, 76, 69, 67, 84, 45, 208, 68, 73, 65, 71, 79, 78, 65, 76, + 128, 68, 73, 65, 71, 79, 78, 65, 204, 68, 73, 65, 69, 82, 69, 83, 73, 90, + 69, 196, 68, 73, 65, 69, 82, 69, 83, 73, 83, 45, 82, 73, 78, 71, 128, 68, + 73, 65, 69, 82, 69, 83, 73, 83, 128, 68, 73, 65, 69, 82, 69, 83, 73, 211, + 68, 72, 79, 85, 128, 68, 72, 79, 79, 128, 68, 72, 79, 128, 68, 72, 73, + 73, 128, 68, 72, 73, 128, 68, 72, 72, 85, 128, 68, 72, 72, 79, 79, 128, + 68, 72, 72, 79, 128, 68, 72, 72, 73, 128, 68, 72, 72, 69, 69, 128, 68, + 72, 72, 69, 128, 68, 72, 72, 65, 128, 68, 72, 69, 69, 128, 68, 72, 65, + 82, 77, 65, 128, 68, 72, 65, 77, 69, 68, 72, 128, 68, 72, 65, 76, 69, 84, + 72, 128, 68, 72, 65, 76, 65, 84, 72, 128, 68, 72, 65, 76, 128, 68, 72, + 65, 68, 72, 69, 128, 68, 72, 65, 65, 76, 85, 128, 68, 72, 65, 65, 128, + 68, 72, 65, 128, 68, 69, 90, 200, 68, 69, 89, 84, 69, 82, 79, 213, 68, + 69, 89, 84, 69, 82, 79, 211, 68, 69, 88, 73, 65, 128, 68, 69, 86, 73, 67, + 197, 68, 69, 86, 69, 76, 79, 80, 77, 69, 78, 84, 128, 68, 69, 85, 78, 71, + 128, 68, 69, 83, 75, 84, 79, 208, 68, 69, 83, 203, 68, 69, 83, 73, 71, + 78, 128, 68, 69, 83, 73, 128, 68, 69, 83, 69, 82, 84, 128, 68, 69, 83, + 69, 82, 212, 68, 69, 83, 69, 82, 69, 212, 68, 69, 83, 67, 82, 73, 80, 84, + 73, 79, 206, 68, 69, 83, 67, 69, 78, 68, 73, 78, 199, 68, 69, 83, 67, 69, + 78, 68, 69, 82, 128, 68, 69, 82, 69, 84, 45, 72, 73, 68, 69, 84, 128, 68, + 69, 82, 69, 84, 128, 68, 69, 82, 69, 76, 73, 67, 212, 68, 69, 80, 65, 82, + 84, 85, 82, 69, 128, 68, 69, 80, 65, 82, 84, 77, 69, 78, 212, 68, 69, 80, + 65, 82, 84, 73, 78, 199, 68, 69, 78, 84, 73, 83, 84, 82, 217, 68, 69, 78, + 84, 65, 204, 68, 69, 78, 79, 77, 73, 78, 65, 84, 79, 82, 128, 68, 69, 78, + 79, 77, 73, 78, 65, 84, 79, 210, 68, 69, 78, 78, 69, 78, 128, 68, 69, 78, + 71, 128, 68, 69, 78, 197, 68, 69, 78, 65, 82, 73, 85, 211, 68, 69, 76, + 84, 65, 128, 68, 69, 76, 84, 193, 68, 69, 76, 84, 128, 68, 69, 76, 80, + 72, 73, 195, 68, 69, 76, 73, 86, 69, 82, 217, 68, 69, 76, 73, 86, 69, 82, + 65, 78, 67, 69, 128, 68, 69, 76, 73, 77, 73, 84, 69, 82, 128, 68, 69, 76, + 73, 77, 73, 84, 69, 210, 68, 69, 76, 73, 67, 73, 79, 85, 211, 68, 69, 76, + 69, 84, 69, 128, 68, 69, 76, 69, 84, 197, 68, 69, 75, 65, 128, 68, 69, + 75, 128, 68, 69, 73, 128, 68, 69, 72, 73, 128, 68, 69, 71, 82, 69, 69, + 83, 128, 68, 69, 71, 82, 69, 197, 68, 69, 70, 73, 78, 73, 84, 73, 79, 78, 128, 68, 69, 70, 69, 67, 84, 73, 86, 69, 78, 69, 83, 211, 68, 69, 69, 82, 128, 68, 69, 69, 80, 76, 89, 128, 68, 69, 69, 76, 128, 68, 69, 67, 82, 69, 83, 67, 69, 78, 68, 79, 128, 68, 69, 67, 82, 69, 65, 83, 69, 128, 68, - 69, 67, 79, 82, 65, 84, 73, 86, 197, 68, 69, 67, 79, 82, 65, 84, 73, 79, - 78, 128, 68, 69, 67, 73, 83, 73, 86, 69, 78, 69, 83, 83, 128, 68, 69, 67, - 73, 77, 65, 204, 68, 69, 67, 73, 68, 85, 79, 85, 211, 68, 69, 67, 69, 77, - 66, 69, 82, 128, 68, 69, 67, 65, 89, 69, 68, 128, 68, 69, 66, 73, 212, - 68, 69, 65, 84, 72, 128, 68, 69, 65, 68, 128, 68, 68, 87, 65, 128, 68, - 68, 85, 88, 128, 68, 68, 85, 84, 128, 68, 68, 85, 82, 88, 128, 68, 68, - 85, 82, 128, 68, 68, 85, 80, 128, 68, 68, 85, 79, 88, 128, 68, 68, 85, - 79, 80, 128, 68, 68, 85, 79, 128, 68, 68, 85, 128, 68, 68, 79, 88, 128, - 68, 68, 79, 84, 128, 68, 68, 79, 80, 128, 68, 68, 79, 65, 128, 68, 68, - 73, 88, 128, 68, 68, 73, 84, 128, 68, 68, 73, 80, 128, 68, 68, 73, 69, - 88, 128, 68, 68, 73, 69, 80, 128, 68, 68, 73, 69, 128, 68, 68, 73, 128, - 68, 68, 72, 85, 128, 68, 68, 72, 79, 128, 68, 68, 72, 73, 128, 68, 68, - 72, 69, 69, 128, 68, 68, 72, 69, 128, 68, 68, 72, 65, 65, 128, 68, 68, - 72, 65, 128, 68, 68, 69, 88, 128, 68, 68, 69, 80, 128, 68, 68, 69, 69, - 128, 68, 68, 69, 128, 68, 68, 68, 72, 65, 128, 68, 68, 68, 65, 128, 68, - 68, 65, 89, 65, 78, 78, 65, 128, 68, 68, 65, 88, 128, 68, 68, 65, 84, - 128, 68, 68, 65, 80, 128, 68, 68, 65, 76, 128, 68, 68, 65, 204, 68, 68, - 65, 72, 65, 76, 128, 68, 68, 65, 72, 65, 204, 68, 68, 65, 65, 128, 68, - 67, 83, 128, 68, 67, 52, 128, 68, 67, 51, 128, 68, 67, 50, 128, 68, 67, - 49, 128, 68, 194, 68, 65, 89, 45, 78, 73, 71, 72, 84, 128, 68, 65, 217, + 69, 67, 82, 69, 65, 83, 197, 68, 69, 67, 79, 82, 65, 84, 73, 86, 197, 68, + 69, 67, 79, 82, 65, 84, 73, 79, 78, 128, 68, 69, 67, 73, 83, 73, 86, 69, + 78, 69, 83, 83, 128, 68, 69, 67, 73, 77, 65, 204, 68, 69, 67, 73, 68, 85, + 79, 85, 211, 68, 69, 67, 69, 77, 66, 69, 82, 128, 68, 69, 67, 65, 89, 69, + 68, 128, 68, 69, 66, 73, 212, 68, 69, 65, 84, 72, 128, 68, 69, 65, 68, + 128, 68, 68, 87, 65, 128, 68, 68, 85, 88, 128, 68, 68, 85, 84, 128, 68, + 68, 85, 82, 88, 128, 68, 68, 85, 82, 128, 68, 68, 85, 80, 128, 68, 68, + 85, 79, 88, 128, 68, 68, 85, 79, 80, 128, 68, 68, 85, 79, 128, 68, 68, + 85, 128, 68, 68, 79, 88, 128, 68, 68, 79, 84, 128, 68, 68, 79, 80, 128, + 68, 68, 79, 65, 128, 68, 68, 73, 88, 128, 68, 68, 73, 84, 128, 68, 68, + 73, 80, 128, 68, 68, 73, 69, 88, 128, 68, 68, 73, 69, 80, 128, 68, 68, + 73, 69, 128, 68, 68, 73, 128, 68, 68, 72, 85, 128, 68, 68, 72, 79, 128, + 68, 68, 72, 73, 128, 68, 68, 72, 69, 69, 128, 68, 68, 72, 69, 128, 68, + 68, 72, 65, 65, 128, 68, 68, 72, 65, 128, 68, 68, 69, 88, 128, 68, 68, + 69, 80, 128, 68, 68, 69, 69, 128, 68, 68, 69, 128, 68, 68, 68, 72, 65, + 128, 68, 68, 68, 65, 128, 68, 68, 65, 89, 65, 78, 78, 65, 128, 68, 68, + 65, 88, 128, 68, 68, 65, 84, 128, 68, 68, 65, 80, 128, 68, 68, 65, 76, + 128, 68, 68, 65, 204, 68, 68, 65, 72, 65, 76, 128, 68, 68, 65, 72, 65, + 204, 68, 68, 65, 65, 128, 68, 67, 83, 128, 68, 67, 72, 69, 128, 68, 67, + 52, 128, 68, 67, 51, 128, 68, 67, 50, 128, 68, 67, 49, 128, 68, 194, 68, + 65, 89, 45, 78, 73, 71, 72, 84, 128, 68, 65, 217, 68, 65, 87, 66, 128, 68, 65, 86, 73, 89, 65, 78, 73, 128, 68, 65, 86, 73, 68, 128, 68, 65, 84, 197, 68, 65, 83, 73, 65, 128, 68, 65, 83, 73, 193, 68, 65, 83, 72, 69, 196, 68, 65, 83, 72, 128, 68, 65, 83, 200, 68, 65, 83, 69, 73, 65, 128, @@ -4061,285 +4266,310 @@ static unsigned char lexicon[] = { 69, 84, 72, 128, 68, 65, 76, 69, 84, 128, 68, 65, 76, 69, 212, 68, 65, 76, 68, 65, 128, 68, 65, 76, 65, 84, 72, 128, 68, 65, 76, 65, 84, 200, 68, 65, 76, 65, 84, 128, 68, 65, 73, 82, 128, 68, 65, 73, 78, 71, 128, - 68, 65, 72, 89, 65, 65, 85, 83, 72, 45, 50, 128, 68, 65, 72, 89, 65, 65, - 85, 83, 72, 128, 68, 65, 71, 83, 128, 68, 65, 71, 71, 69, 82, 128, 68, - 65, 71, 71, 69, 210, 68, 65, 71, 69, 83, 72, 128, 68, 65, 71, 69, 83, - 200, 68, 65, 71, 66, 65, 83, 73, 78, 78, 65, 128, 68, 65, 71, 65, 218, - 68, 65, 71, 65, 76, 71, 65, 128, 68, 65, 199, 68, 65, 69, 78, 71, 128, - 68, 65, 69, 199, 68, 65, 68, 128, 68, 65, 196, 68, 65, 65, 83, 85, 128, - 68, 65, 65, 68, 72, 85, 128, 68, 48, 54, 55, 72, 128, 68, 48, 54, 55, 71, - 128, 68, 48, 54, 55, 70, 128, 68, 48, 54, 55, 69, 128, 68, 48, 54, 55, - 68, 128, 68, 48, 54, 55, 67, 128, 68, 48, 54, 55, 66, 128, 68, 48, 54, - 55, 65, 128, 68, 48, 54, 55, 128, 68, 48, 54, 54, 128, 68, 48, 54, 53, - 128, 68, 48, 54, 52, 128, 68, 48, 54, 51, 128, 68, 48, 54, 50, 128, 68, - 48, 54, 49, 128, 68, 48, 54, 48, 128, 68, 48, 53, 57, 128, 68, 48, 53, - 56, 128, 68, 48, 53, 55, 128, 68, 48, 53, 54, 128, 68, 48, 53, 53, 128, - 68, 48, 53, 52, 65, 128, 68, 48, 53, 52, 128, 68, 48, 53, 51, 128, 68, - 48, 53, 50, 65, 128, 68, 48, 53, 50, 128, 68, 48, 53, 49, 128, 68, 48, - 53, 48, 73, 128, 68, 48, 53, 48, 72, 128, 68, 48, 53, 48, 71, 128, 68, - 48, 53, 48, 70, 128, 68, 48, 53, 48, 69, 128, 68, 48, 53, 48, 68, 128, - 68, 48, 53, 48, 67, 128, 68, 48, 53, 48, 66, 128, 68, 48, 53, 48, 65, - 128, 68, 48, 53, 48, 128, 68, 48, 52, 57, 128, 68, 48, 52, 56, 65, 128, - 68, 48, 52, 56, 128, 68, 48, 52, 55, 128, 68, 48, 52, 54, 65, 128, 68, - 48, 52, 54, 128, 68, 48, 52, 53, 128, 68, 48, 52, 52, 128, 68, 48, 52, - 51, 128, 68, 48, 52, 50, 128, 68, 48, 52, 49, 128, 68, 48, 52, 48, 128, - 68, 48, 51, 57, 128, 68, 48, 51, 56, 128, 68, 48, 51, 55, 128, 68, 48, - 51, 54, 128, 68, 48, 51, 53, 128, 68, 48, 51, 52, 65, 128, 68, 48, 51, - 52, 128, 68, 48, 51, 51, 128, 68, 48, 51, 50, 128, 68, 48, 51, 49, 65, - 128, 68, 48, 51, 49, 128, 68, 48, 51, 48, 128, 68, 48, 50, 57, 128, 68, - 48, 50, 56, 128, 68, 48, 50, 55, 65, 128, 68, 48, 50, 55, 128, 68, 48, - 50, 54, 128, 68, 48, 50, 53, 128, 68, 48, 50, 52, 128, 68, 48, 50, 51, - 128, 68, 48, 50, 50, 128, 68, 48, 50, 49, 128, 68, 48, 50, 48, 128, 68, - 48, 49, 57, 128, 68, 48, 49, 56, 128, 68, 48, 49, 55, 128, 68, 48, 49, - 54, 128, 68, 48, 49, 53, 128, 68, 48, 49, 52, 128, 68, 48, 49, 51, 128, - 68, 48, 49, 50, 128, 68, 48, 49, 49, 128, 68, 48, 49, 48, 128, 68, 48, - 48, 57, 128, 68, 48, 48, 56, 65, 128, 68, 48, 48, 56, 128, 68, 48, 48, - 55, 128, 68, 48, 48, 54, 128, 68, 48, 48, 53, 128, 68, 48, 48, 52, 128, - 68, 48, 48, 51, 128, 68, 48, 48, 50, 128, 68, 48, 48, 49, 128, 67, 89, - 88, 128, 67, 89, 84, 128, 67, 89, 82, 88, 128, 67, 89, 82, 69, 78, 65, - 73, 195, 67, 89, 82, 128, 67, 89, 80, 82, 73, 79, 212, 67, 89, 80, 69, - 82, 85, 83, 128, 67, 89, 80, 128, 67, 89, 76, 73, 78, 68, 82, 73, 67, 73, - 84, 89, 128, 67, 89, 67, 76, 79, 78, 69, 128, 67, 89, 65, 128, 67, 89, - 128, 67, 87, 79, 79, 128, 67, 87, 79, 128, 67, 87, 73, 73, 128, 67, 87, - 73, 128, 67, 87, 69, 79, 82, 84, 72, 128, 67, 87, 69, 128, 67, 87, 65, - 65, 128, 67, 85, 88, 128, 67, 85, 85, 128, 67, 85, 212, 67, 85, 83, 84, - 79, 77, 83, 128, 67, 85, 83, 84, 79, 77, 69, 210, 67, 85, 83, 84, 65, 82, - 68, 128, 67, 85, 82, 88, 128, 67, 85, 82, 86, 73, 78, 199, 67, 85, 82, - 86, 69, 196, 67, 85, 82, 86, 69, 128, 67, 85, 82, 86, 197, 67, 85, 82, - 83, 73, 86, 197, 67, 85, 82, 82, 217, 67, 85, 82, 82, 69, 78, 84, 128, - 67, 85, 82, 82, 69, 78, 212, 67, 85, 82, 76, 217, 67, 85, 82, 76, 128, - 67, 85, 82, 128, 67, 85, 80, 128, 67, 85, 79, 88, 128, 67, 85, 79, 80, - 128, 67, 85, 79, 128, 67, 85, 205, 67, 85, 66, 69, 68, 128, 67, 85, 66, - 197, 67, 85, 65, 84, 82, 73, 76, 76, 79, 128, 67, 85, 65, 84, 82, 73, 76, - 76, 207, 67, 85, 128, 67, 83, 73, 128, 67, 82, 89, 83, 84, 65, 204, 67, - 82, 89, 80, 84, 79, 71, 82, 65, 77, 77, 73, 195, 67, 82, 89, 73, 78, 199, - 67, 82, 85, 90, 69, 73, 82, 207, 67, 82, 85, 67, 73, 66, 76, 69, 45, 53, - 128, 67, 82, 85, 67, 73, 66, 76, 69, 45, 52, 128, 67, 82, 85, 67, 73, 66, - 76, 69, 45, 51, 128, 67, 82, 85, 67, 73, 66, 76, 69, 45, 50, 128, 67, 82, - 85, 67, 73, 66, 76, 69, 128, 67, 82, 79, 87, 78, 128, 67, 82, 79, 83, 83, - 73, 78, 71, 128, 67, 82, 79, 83, 83, 73, 78, 199, 67, 82, 79, 83, 83, 72, - 65, 84, 67, 200, 67, 82, 79, 83, 83, 69, 68, 45, 84, 65, 73, 76, 128, 67, - 82, 79, 83, 83, 69, 196, 67, 82, 79, 83, 83, 66, 79, 78, 69, 83, 128, 67, - 82, 79, 83, 83, 128, 67, 82, 79, 83, 211, 67, 82, 79, 80, 128, 67, 82, - 79, 73, 88, 128, 67, 82, 79, 67, 85, 211, 67, 82, 79, 67, 79, 68, 73, 76, - 69, 128, 67, 82, 69, 83, 67, 69, 78, 84, 128, 67, 82, 69, 83, 67, 69, 78, - 212, 67, 82, 69, 68, 73, 212, 67, 82, 69, 65, 84, 73, 86, 197, 67, 82, - 69, 65, 77, 128, 67, 82, 65, 67, 75, 69, 82, 128, 67, 82, 128, 67, 79, - 88, 128, 67, 79, 87, 128, 67, 79, 215, 67, 79, 86, 69, 82, 128, 67, 79, - 85, 80, 76, 197, 67, 79, 85, 78, 84, 73, 78, 199, 67, 79, 85, 78, 84, 69, - 82, 83, 73, 78, 75, 128, 67, 79, 85, 78, 84, 69, 82, 66, 79, 82, 69, 128, - 67, 79, 85, 78, 67, 73, 204, 67, 79, 84, 128, 67, 79, 82, 82, 69, 83, 80, - 79, 78, 68, 211, 67, 79, 82, 82, 69, 67, 84, 128, 67, 79, 82, 80, 83, 69, - 128, 67, 79, 82, 80, 79, 82, 65, 84, 73, 79, 78, 128, 67, 79, 82, 79, 78, - 73, 83, 128, 67, 79, 82, 78, 69, 82, 83, 128, 67, 79, 82, 78, 69, 82, - 128, 67, 79, 82, 78, 69, 210, 67, 79, 80, 89, 82, 73, 71, 72, 84, 128, - 67, 79, 80, 89, 82, 73, 71, 72, 212, 67, 79, 80, 89, 128, 67, 79, 80, 82, - 79, 68, 85, 67, 84, 128, 67, 79, 80, 80, 69, 82, 45, 50, 128, 67, 79, 80, - 80, 69, 82, 128, 67, 79, 80, 128, 67, 79, 79, 76, 128, 67, 79, 79, 75, - 73, 78, 71, 128, 67, 79, 79, 75, 73, 69, 128, 67, 79, 79, 75, 69, 196, - 67, 79, 79, 128, 67, 79, 78, 86, 69, 82, 71, 73, 78, 199, 67, 79, 78, 86, - 69, 78, 73, 69, 78, 67, 197, 67, 79, 78, 84, 82, 79, 76, 128, 67, 79, 78, - 84, 82, 79, 204, 67, 79, 78, 84, 82, 65, 82, 73, 69, 84, 89, 128, 67, 79, - 78, 84, 82, 65, 67, 84, 73, 79, 78, 128, 67, 79, 78, 84, 79, 85, 82, 69, - 196, 67, 79, 78, 84, 79, 85, 210, 67, 79, 78, 84, 69, 78, 84, 73, 79, 78, - 128, 67, 79, 78, 84, 69, 77, 80, 76, 65, 84, 73, 79, 78, 128, 67, 79, 78, - 84, 65, 73, 78, 211, 67, 79, 78, 84, 65, 73, 78, 73, 78, 199, 67, 79, 78, - 84, 65, 73, 206, 67, 79, 78, 84, 65, 67, 84, 128, 67, 79, 78, 83, 84, 82, - 85, 67, 84, 73, 79, 206, 67, 79, 78, 83, 84, 65, 78, 84, 128, 67, 79, 78, - 83, 84, 65, 78, 212, 67, 79, 78, 83, 84, 65, 78, 67, 89, 128, 67, 79, 78, - 83, 69, 67, 85, 84, 73, 86, 197, 67, 79, 78, 74, 85, 78, 67, 84, 73, 79, - 78, 128, 67, 79, 78, 74, 85, 71, 65, 84, 197, 67, 79, 78, 74, 79, 73, 78, - 73, 78, 199, 67, 79, 78, 73, 67, 65, 204, 67, 79, 78, 71, 82, 85, 69, 78, - 212, 67, 79, 78, 71, 82, 65, 84, 85, 76, 65, 84, 73, 79, 78, 128, 67, 79, - 78, 70, 85, 83, 69, 196, 67, 79, 78, 70, 79, 85, 78, 68, 69, 196, 67, 79, - 78, 70, 76, 73, 67, 84, 128, 67, 79, 78, 70, 69, 84, 84, 201, 67, 79, 78, - 67, 65, 86, 69, 45, 83, 73, 68, 69, 196, 67, 79, 78, 67, 65, 86, 69, 45, - 80, 79, 73, 78, 84, 69, 196, 67, 79, 78, 128, 67, 79, 77, 80, 85, 84, 69, - 82, 128, 67, 79, 77, 80, 79, 83, 73, 84, 73, 79, 78, 128, 67, 79, 77, 80, - 79, 83, 73, 84, 73, 79, 206, 67, 79, 77, 80, 76, 73, 65, 78, 67, 69, 128, - 67, 79, 77, 80, 76, 69, 84, 73, 79, 78, 128, 67, 79, 77, 80, 76, 69, 84, - 69, 68, 128, 67, 79, 77, 80, 76, 69, 77, 69, 78, 84, 128, 67, 79, 77, 80, - 65, 82, 69, 128, 67, 79, 77, 77, 79, 206, 67, 79, 77, 77, 69, 82, 67, 73, - 65, 204, 67, 79, 77, 77, 65, 78, 68, 128, 67, 79, 77, 77, 65, 128, 67, - 79, 77, 77, 193, 67, 79, 77, 69, 84, 128, 67, 79, 77, 66, 128, 67, 79, - 76, 85, 77, 78, 128, 67, 79, 76, 79, 82, 128, 67, 79, 76, 76, 73, 83, 73, - 79, 206, 67, 79, 76, 76, 128, 67, 79, 76, 196, 67, 79, 70, 70, 73, 78, - 128, 67, 79, 69, 78, 71, 128, 67, 79, 69, 78, 199, 67, 79, 68, 65, 128, - 67, 79, 67, 75, 84, 65, 73, 204, 67, 79, 65, 83, 84, 69, 82, 128, 67, 79, - 65, 128, 67, 79, 128, 67, 77, 128, 67, 205, 67, 76, 85, 83, 84, 69, 210, - 67, 76, 85, 66, 83, 128, 67, 76, 85, 66, 45, 83, 80, 79, 75, 69, 196, 67, - 76, 85, 66, 128, 67, 76, 85, 194, 67, 76, 79, 86, 69, 82, 128, 67, 76, - 79, 85, 68, 128, 67, 76, 79, 85, 196, 67, 76, 79, 84, 72, 69, 83, 128, - 67, 76, 79, 84, 72, 128, 67, 76, 79, 83, 69, 84, 128, 67, 76, 79, 83, 69, - 78, 69, 83, 83, 128, 67, 76, 79, 83, 69, 68, 128, 67, 76, 79, 83, 197, - 67, 76, 79, 67, 75, 87, 73, 83, 197, 67, 76, 79, 67, 203, 67, 76, 73, 86, - 73, 83, 128, 67, 76, 73, 80, 66, 79, 65, 82, 68, 128, 67, 76, 73, 78, 75, - 73, 78, 199, 67, 76, 73, 78, 71, 73, 78, 199, 67, 76, 73, 77, 65, 67, 85, - 83, 128, 67, 76, 73, 70, 70, 128, 67, 76, 73, 67, 75, 128, 67, 76, 69, - 70, 45, 50, 128, 67, 76, 69, 70, 45, 49, 128, 67, 76, 69, 70, 128, 67, - 76, 69, 198, 67, 76, 69, 65, 86, 69, 82, 128, 67, 76, 69, 65, 210, 67, - 76, 65, 87, 128, 67, 76, 65, 80, 80, 73, 78, 199, 67, 76, 65, 80, 80, 69, - 210, 67, 76, 65, 78, 128, 67, 76, 65, 73, 77, 128, 67, 76, 128, 67, 73, - 88, 128, 67, 73, 86, 73, 76, 73, 65, 78, 128, 67, 73, 84, 89, 83, 67, 65, - 80, 197, 67, 73, 84, 128, 67, 73, 82, 67, 85, 211, 67, 73, 82, 67, 85, - 77, 70, 76, 69, 88, 128, 67, 73, 82, 67, 85, 77, 70, 76, 69, 216, 67, 73, - 82, 67, 85, 76, 65, 84, 73, 79, 206, 67, 73, 82, 67, 76, 69, 83, 128, 67, - 73, 82, 67, 76, 69, 128, 67, 73, 80, 128, 67, 73, 78, 78, 65, 66, 65, 82, - 128, 67, 73, 78, 69, 77, 65, 128, 67, 73, 73, 128, 67, 73, 69, 88, 128, - 67, 73, 69, 85, 67, 45, 83, 83, 65, 78, 71, 80, 73, 69, 85, 80, 128, 67, - 73, 69, 85, 67, 45, 80, 73, 69, 85, 80, 128, 67, 73, 69, 85, 67, 45, 73, - 69, 85, 78, 71, 128, 67, 73, 69, 85, 195, 67, 73, 69, 84, 128, 67, 73, - 69, 80, 128, 67, 73, 69, 128, 67, 72, 89, 88, 128, 67, 72, 89, 84, 128, - 67, 72, 89, 82, 88, 128, 67, 72, 89, 82, 128, 67, 72, 89, 80, 128, 67, - 72, 85, 88, 128, 67, 72, 85, 82, 88, 128, 67, 72, 85, 82, 67, 72, 128, - 67, 72, 85, 82, 128, 67, 72, 85, 80, 128, 67, 72, 85, 79, 88, 128, 67, - 72, 85, 79, 84, 128, 67, 72, 85, 79, 80, 128, 67, 72, 85, 79, 128, 67, - 72, 85, 76, 65, 128, 67, 72, 85, 128, 67, 72, 82, 89, 83, 65, 78, 84, 72, - 69, 77, 85, 77, 128, 67, 72, 82, 79, 78, 79, 85, 128, 67, 72, 82, 79, 78, - 79, 78, 128, 67, 72, 82, 79, 77, 193, 67, 72, 82, 79, 193, 67, 72, 82, - 73, 86, 73, 128, 67, 72, 82, 73, 83, 84, 77, 65, 83, 128, 67, 72, 82, 73, - 83, 84, 77, 65, 211, 67, 72, 79, 88, 128, 67, 72, 79, 84, 128, 67, 72, - 79, 82, 69, 86, 77, 193, 67, 72, 79, 80, 128, 67, 72, 79, 75, 69, 128, - 67, 72, 79, 69, 128, 67, 72, 79, 67, 79, 76, 65, 84, 197, 67, 72, 79, 65, - 128, 67, 72, 207, 67, 72, 73, 84, 85, 69, 85, 77, 83, 83, 65, 78, 71, 83, - 73, 79, 83, 128, 67, 72, 73, 84, 85, 69, 85, 77, 83, 83, 65, 78, 71, 67, - 73, 69, 85, 67, 128, 67, 72, 73, 84, 85, 69, 85, 77, 83, 73, 79, 83, 128, - 67, 72, 73, 84, 85, 69, 85, 77, 67, 73, 69, 85, 67, 128, 67, 72, 73, 84, - 85, 69, 85, 77, 67, 72, 73, 69, 85, 67, 72, 128, 67, 72, 73, 82, 79, 78, - 128, 67, 72, 73, 82, 69, 84, 128, 67, 72, 73, 78, 71, 128, 67, 72, 73, - 78, 69, 83, 197, 67, 72, 73, 78, 128, 67, 72, 73, 77, 69, 128, 67, 72, - 73, 76, 76, 213, 67, 72, 73, 76, 68, 82, 69, 206, 67, 72, 73, 76, 68, - 128, 67, 72, 73, 76, 128, 67, 72, 73, 75, 201, 67, 72, 73, 69, 85, 67, - 72, 45, 75, 72, 73, 69, 85, 75, 72, 128, 67, 72, 73, 69, 85, 67, 72, 45, - 72, 73, 69, 85, 72, 128, 67, 72, 73, 69, 85, 67, 200, 67, 72, 73, 67, 75, - 69, 78, 128, 67, 72, 73, 67, 75, 128, 67, 72, 73, 128, 67, 72, 201, 67, - 72, 72, 65, 128, 67, 72, 69, 88, 128, 67, 72, 69, 86, 82, 79, 206, 67, - 72, 69, 84, 128, 67, 72, 69, 83, 84, 78, 85, 84, 128, 67, 72, 69, 83, - 211, 67, 72, 69, 82, 82, 217, 67, 72, 69, 82, 82, 73, 69, 83, 128, 67, + 68, 65, 73, 128, 68, 65, 72, 89, 65, 65, 85, 83, 72, 45, 50, 128, 68, 65, + 72, 89, 65, 65, 85, 83, 72, 128, 68, 65, 71, 83, 128, 68, 65, 71, 71, 69, + 82, 128, 68, 65, 71, 71, 69, 210, 68, 65, 71, 69, 83, 72, 128, 68, 65, + 71, 69, 83, 200, 68, 65, 71, 66, 65, 83, 73, 78, 78, 65, 128, 68, 65, 71, + 65, 218, 68, 65, 71, 65, 76, 71, 65, 128, 68, 65, 71, 51, 128, 68, 65, + 199, 68, 65, 69, 78, 71, 128, 68, 65, 69, 199, 68, 65, 68, 128, 68, 65, + 196, 68, 65, 65, 83, 85, 128, 68, 65, 65, 68, 72, 85, 128, 68, 48, 54, + 55, 72, 128, 68, 48, 54, 55, 71, 128, 68, 48, 54, 55, 70, 128, 68, 48, + 54, 55, 69, 128, 68, 48, 54, 55, 68, 128, 68, 48, 54, 55, 67, 128, 68, + 48, 54, 55, 66, 128, 68, 48, 54, 55, 65, 128, 68, 48, 54, 55, 128, 68, + 48, 54, 54, 128, 68, 48, 54, 53, 128, 68, 48, 54, 52, 128, 68, 48, 54, + 51, 128, 68, 48, 54, 50, 128, 68, 48, 54, 49, 128, 68, 48, 54, 48, 128, + 68, 48, 53, 57, 128, 68, 48, 53, 56, 128, 68, 48, 53, 55, 128, 68, 48, + 53, 54, 128, 68, 48, 53, 53, 128, 68, 48, 53, 52, 65, 128, 68, 48, 53, + 52, 128, 68, 48, 53, 51, 128, 68, 48, 53, 50, 65, 128, 68, 48, 53, 50, + 128, 68, 48, 53, 49, 128, 68, 48, 53, 48, 73, 128, 68, 48, 53, 48, 72, + 128, 68, 48, 53, 48, 71, 128, 68, 48, 53, 48, 70, 128, 68, 48, 53, 48, + 69, 128, 68, 48, 53, 48, 68, 128, 68, 48, 53, 48, 67, 128, 68, 48, 53, + 48, 66, 128, 68, 48, 53, 48, 65, 128, 68, 48, 53, 48, 128, 68, 48, 52, + 57, 128, 68, 48, 52, 56, 65, 128, 68, 48, 52, 56, 128, 68, 48, 52, 55, + 128, 68, 48, 52, 54, 65, 128, 68, 48, 52, 54, 128, 68, 48, 52, 53, 128, + 68, 48, 52, 52, 128, 68, 48, 52, 51, 128, 68, 48, 52, 50, 128, 68, 48, + 52, 49, 128, 68, 48, 52, 48, 128, 68, 48, 51, 57, 128, 68, 48, 51, 56, + 128, 68, 48, 51, 55, 128, 68, 48, 51, 54, 128, 68, 48, 51, 53, 128, 68, + 48, 51, 52, 65, 128, 68, 48, 51, 52, 128, 68, 48, 51, 51, 128, 68, 48, + 51, 50, 128, 68, 48, 51, 49, 65, 128, 68, 48, 51, 49, 128, 68, 48, 51, + 48, 128, 68, 48, 50, 57, 128, 68, 48, 50, 56, 128, 68, 48, 50, 55, 65, + 128, 68, 48, 50, 55, 128, 68, 48, 50, 54, 128, 68, 48, 50, 53, 128, 68, + 48, 50, 52, 128, 68, 48, 50, 51, 128, 68, 48, 50, 50, 128, 68, 48, 50, + 49, 128, 68, 48, 50, 48, 128, 68, 48, 49, 57, 128, 68, 48, 49, 56, 128, + 68, 48, 49, 55, 128, 68, 48, 49, 54, 128, 68, 48, 49, 53, 128, 68, 48, + 49, 52, 128, 68, 48, 49, 51, 128, 68, 48, 49, 50, 128, 68, 48, 49, 49, + 128, 68, 48, 49, 48, 128, 68, 48, 48, 57, 128, 68, 48, 48, 56, 65, 128, + 68, 48, 48, 56, 128, 68, 48, 48, 55, 128, 68, 48, 48, 54, 128, 68, 48, + 48, 53, 128, 68, 48, 48, 52, 128, 68, 48, 48, 51, 128, 68, 48, 48, 50, + 128, 68, 48, 48, 49, 128, 67, 89, 88, 128, 67, 89, 84, 128, 67, 89, 82, + 88, 128, 67, 89, 82, 69, 78, 65, 73, 195, 67, 89, 82, 128, 67, 89, 80, + 82, 73, 79, 212, 67, 89, 80, 69, 82, 85, 83, 128, 67, 89, 80, 128, 67, + 89, 76, 73, 78, 68, 82, 73, 67, 73, 84, 89, 128, 67, 89, 67, 76, 79, 78, + 69, 128, 67, 89, 65, 89, 128, 67, 89, 65, 87, 128, 67, 89, 65, 128, 67, + 87, 79, 79, 128, 67, 87, 79, 128, 67, 87, 73, 73, 128, 67, 87, 73, 128, + 67, 87, 69, 79, 82, 84, 72, 128, 67, 87, 69, 128, 67, 87, 65, 65, 128, + 67, 85, 88, 128, 67, 85, 85, 128, 67, 85, 212, 67, 85, 83, 84, 79, 77, + 83, 128, 67, 85, 83, 84, 79, 77, 69, 210, 67, 85, 83, 84, 65, 82, 68, + 128, 67, 85, 83, 80, 128, 67, 85, 82, 88, 128, 67, 85, 82, 86, 73, 78, + 199, 67, 85, 82, 86, 69, 196, 67, 85, 82, 86, 69, 128, 67, 85, 82, 86, + 197, 67, 85, 82, 83, 73, 86, 197, 67, 85, 82, 82, 217, 67, 85, 82, 82, + 69, 78, 84, 128, 67, 85, 82, 82, 69, 78, 212, 67, 85, 82, 76, 217, 67, + 85, 82, 76, 128, 67, 85, 82, 128, 67, 85, 80, 128, 67, 85, 79, 88, 128, + 67, 85, 79, 80, 128, 67, 85, 79, 128, 67, 85, 205, 67, 85, 66, 69, 68, + 128, 67, 85, 66, 197, 67, 85, 65, 84, 82, 73, 76, 76, 79, 128, 67, 85, + 65, 84, 82, 73, 76, 76, 207, 67, 85, 65, 205, 67, 85, 128, 67, 83, 73, + 128, 67, 82, 89, 83, 84, 65, 204, 67, 82, 89, 80, 84, 79, 71, 82, 65, 77, + 77, 73, 195, 67, 82, 89, 73, 78, 199, 67, 82, 85, 90, 69, 73, 82, 207, + 67, 82, 85, 67, 73, 70, 79, 82, 205, 67, 82, 85, 67, 73, 66, 76, 69, 45, + 53, 128, 67, 82, 85, 67, 73, 66, 76, 69, 45, 52, 128, 67, 82, 85, 67, 73, + 66, 76, 69, 45, 51, 128, 67, 82, 85, 67, 73, 66, 76, 69, 45, 50, 128, 67, + 82, 85, 67, 73, 66, 76, 69, 128, 67, 82, 79, 87, 78, 128, 67, 82, 79, 83, + 83, 73, 78, 71, 128, 67, 82, 79, 83, 83, 73, 78, 199, 67, 82, 79, 83, 83, + 72, 65, 84, 67, 200, 67, 82, 79, 83, 83, 69, 68, 45, 84, 65, 73, 76, 128, + 67, 82, 79, 83, 83, 69, 196, 67, 82, 79, 83, 83, 66, 79, 78, 69, 83, 128, + 67, 82, 79, 83, 83, 128, 67, 82, 79, 83, 211, 67, 82, 79, 80, 128, 67, + 82, 79, 73, 88, 128, 67, 82, 79, 67, 85, 211, 67, 82, 79, 67, 79, 68, 73, + 76, 69, 128, 67, 82, 69, 83, 67, 69, 78, 84, 128, 67, 82, 69, 83, 67, 69, + 78, 212, 67, 82, 69, 68, 73, 212, 67, 82, 69, 65, 84, 73, 86, 197, 67, + 82, 69, 65, 77, 128, 67, 82, 65, 89, 79, 78, 128, 67, 82, 65, 67, 75, 69, + 82, 128, 67, 82, 128, 67, 79, 88, 128, 67, 79, 87, 128, 67, 79, 215, 67, + 79, 86, 69, 82, 128, 67, 79, 85, 80, 76, 197, 67, 79, 85, 78, 84, 73, 78, + 199, 67, 79, 85, 78, 84, 69, 82, 83, 73, 78, 75, 128, 67, 79, 85, 78, 84, + 69, 82, 66, 79, 82, 69, 128, 67, 79, 85, 78, 67, 73, 204, 67, 79, 85, 67, + 200, 67, 79, 84, 128, 67, 79, 82, 82, 69, 83, 80, 79, 78, 68, 211, 67, + 79, 82, 82, 69, 67, 84, 128, 67, 79, 82, 80, 83, 69, 128, 67, 79, 82, 80, + 79, 82, 65, 84, 73, 79, 78, 128, 67, 79, 82, 79, 78, 73, 83, 128, 67, 79, + 82, 78, 69, 82, 83, 128, 67, 79, 82, 78, 69, 82, 128, 67, 79, 82, 78, 69, + 210, 67, 79, 80, 89, 82, 73, 71, 72, 84, 128, 67, 79, 80, 89, 82, 73, 71, + 72, 212, 67, 79, 80, 89, 128, 67, 79, 80, 82, 79, 68, 85, 67, 84, 128, + 67, 79, 80, 80, 69, 82, 45, 50, 128, 67, 79, 80, 80, 69, 82, 128, 67, 79, + 80, 128, 67, 79, 79, 76, 128, 67, 79, 79, 75, 73, 78, 71, 128, 67, 79, + 79, 75, 73, 69, 128, 67, 79, 79, 75, 69, 196, 67, 79, 79, 128, 67, 79, + 78, 86, 69, 82, 71, 73, 78, 199, 67, 79, 78, 86, 69, 78, 73, 69, 78, 67, + 197, 67, 79, 78, 84, 82, 79, 76, 128, 67, 79, 78, 84, 82, 79, 204, 67, + 79, 78, 84, 82, 65, 82, 73, 69, 84, 89, 128, 67, 79, 78, 84, 82, 65, 67, + 84, 73, 79, 78, 128, 67, 79, 78, 84, 79, 85, 82, 69, 196, 67, 79, 78, 84, + 79, 85, 210, 67, 79, 78, 84, 73, 78, 85, 73, 78, 199, 67, 79, 78, 84, 69, + 78, 84, 73, 79, 78, 128, 67, 79, 78, 84, 69, 77, 80, 76, 65, 84, 73, 79, + 78, 128, 67, 79, 78, 84, 65, 73, 78, 211, 67, 79, 78, 84, 65, 73, 78, 73, + 78, 199, 67, 79, 78, 84, 65, 73, 206, 67, 79, 78, 84, 65, 67, 84, 128, + 67, 79, 78, 83, 84, 82, 85, 67, 84, 73, 79, 78, 128, 67, 79, 78, 83, 84, + 82, 85, 67, 84, 73, 79, 206, 67, 79, 78, 83, 84, 65, 78, 84, 128, 67, 79, + 78, 83, 84, 65, 78, 212, 67, 79, 78, 83, 84, 65, 78, 67, 89, 128, 67, 79, + 78, 83, 69, 67, 85, 84, 73, 86, 197, 67, 79, 78, 74, 85, 78, 67, 84, 73, + 79, 78, 128, 67, 79, 78, 74, 85, 71, 65, 84, 197, 67, 79, 78, 74, 79, 73, + 78, 73, 78, 199, 67, 79, 78, 73, 67, 65, 204, 67, 79, 78, 71, 82, 85, 69, + 78, 212, 67, 79, 78, 71, 82, 65, 84, 85, 76, 65, 84, 73, 79, 78, 128, 67, + 79, 78, 70, 85, 83, 69, 196, 67, 79, 78, 70, 79, 85, 78, 68, 69, 196, 67, + 79, 78, 70, 76, 73, 67, 84, 128, 67, 79, 78, 70, 69, 84, 84, 201, 67, 79, + 78, 67, 65, 86, 69, 45, 83, 73, 68, 69, 196, 67, 79, 78, 67, 65, 86, 69, + 45, 80, 79, 73, 78, 84, 69, 196, 67, 79, 77, 80, 85, 84, 69, 82, 83, 128, + 67, 79, 77, 80, 85, 84, 69, 82, 128, 67, 79, 77, 80, 82, 69, 83, 83, 73, + 79, 78, 128, 67, 79, 77, 80, 82, 69, 83, 83, 69, 196, 67, 79, 77, 80, 79, + 83, 73, 84, 73, 79, 78, 128, 67, 79, 77, 80, 79, 83, 73, 84, 73, 79, 206, + 67, 79, 77, 80, 76, 73, 65, 78, 67, 69, 128, 67, 79, 77, 80, 76, 69, 84, + 73, 79, 78, 128, 67, 79, 77, 80, 76, 69, 84, 69, 68, 128, 67, 79, 77, 80, + 76, 69, 77, 69, 78, 84, 128, 67, 79, 77, 80, 65, 82, 69, 128, 67, 79, 77, + 77, 79, 206, 67, 79, 77, 77, 69, 82, 67, 73, 65, 204, 67, 79, 77, 77, 65, + 78, 68, 128, 67, 79, 77, 77, 65, 128, 67, 79, 77, 77, 193, 67, 79, 77, + 69, 84, 128, 67, 79, 77, 66, 128, 67, 79, 76, 85, 77, 78, 128, 67, 79, + 76, 79, 82, 128, 67, 79, 76, 76, 73, 83, 73, 79, 206, 67, 79, 76, 76, + 128, 67, 79, 76, 196, 67, 79, 70, 70, 73, 78, 128, 67, 79, 69, 78, 71, + 128, 67, 79, 69, 78, 199, 67, 79, 68, 65, 128, 67, 79, 67, 75, 84, 65, + 73, 204, 67, 79, 65, 83, 84, 69, 82, 128, 67, 79, 65, 128, 67, 79, 128, + 67, 77, 128, 67, 205, 67, 76, 85, 83, 84, 69, 210, 67, 76, 85, 66, 83, + 128, 67, 76, 85, 66, 45, 83, 80, 79, 75, 69, 196, 67, 76, 85, 66, 128, + 67, 76, 85, 194, 67, 76, 79, 86, 69, 82, 128, 67, 76, 79, 85, 68, 128, + 67, 76, 79, 85, 196, 67, 76, 79, 84, 72, 69, 83, 128, 67, 76, 79, 84, 72, + 128, 67, 76, 79, 83, 69, 84, 128, 67, 76, 79, 83, 69, 78, 69, 83, 83, + 128, 67, 76, 79, 83, 69, 68, 128, 67, 76, 79, 83, 197, 67, 76, 79, 67, + 75, 87, 73, 83, 197, 67, 76, 79, 67, 203, 67, 76, 73, 86, 73, 83, 128, + 67, 76, 73, 80, 66, 79, 65, 82, 68, 128, 67, 76, 73, 78, 75, 73, 78, 199, + 67, 76, 73, 78, 71, 73, 78, 199, 67, 76, 73, 77, 65, 67, 85, 83, 128, 67, + 76, 73, 70, 70, 128, 67, 76, 73, 67, 75, 128, 67, 76, 69, 70, 45, 50, + 128, 67, 76, 69, 70, 45, 49, 128, 67, 76, 69, 70, 128, 67, 76, 69, 198, + 67, 76, 69, 65, 86, 69, 82, 128, 67, 76, 69, 65, 210, 67, 76, 65, 87, + 128, 67, 76, 65, 83, 83, 73, 67, 65, 204, 67, 76, 65, 80, 80, 73, 78, + 199, 67, 76, 65, 80, 80, 69, 210, 67, 76, 65, 78, 128, 67, 76, 65, 206, + 67, 76, 65, 77, 83, 72, 69, 76, 204, 67, 76, 65, 73, 77, 128, 67, 76, + 128, 67, 73, 88, 128, 67, 73, 86, 73, 76, 73, 65, 78, 128, 67, 73, 84, + 89, 83, 67, 65, 80, 69, 128, 67, 73, 84, 89, 83, 67, 65, 80, 197, 67, 73, + 84, 65, 84, 73, 79, 206, 67, 73, 84, 128, 67, 73, 82, 67, 85, 211, 67, + 73, 82, 67, 85, 77, 70, 76, 69, 88, 128, 67, 73, 82, 67, 85, 77, 70, 76, + 69, 216, 67, 73, 82, 67, 85, 76, 65, 84, 73, 79, 206, 67, 73, 82, 67, 76, + 73, 78, 199, 67, 73, 82, 67, 76, 69, 83, 128, 67, 73, 82, 67, 76, 69, + 128, 67, 73, 80, 128, 67, 73, 78, 78, 65, 66, 65, 82, 128, 67, 73, 78, + 69, 77, 65, 128, 67, 73, 206, 67, 73, 205, 67, 73, 73, 128, 67, 73, 69, + 88, 128, 67, 73, 69, 85, 67, 45, 83, 83, 65, 78, 71, 80, 73, 69, 85, 80, + 128, 67, 73, 69, 85, 67, 45, 80, 73, 69, 85, 80, 128, 67, 73, 69, 85, 67, + 45, 73, 69, 85, 78, 71, 128, 67, 73, 69, 85, 195, 67, 73, 69, 84, 128, + 67, 73, 69, 80, 128, 67, 73, 69, 128, 67, 72, 89, 88, 128, 67, 72, 89, + 84, 128, 67, 72, 89, 82, 88, 128, 67, 72, 89, 82, 128, 67, 72, 89, 80, + 128, 67, 72, 87, 86, 128, 67, 72, 85, 88, 128, 67, 72, 85, 82, 88, 128, + 67, 72, 85, 82, 67, 72, 128, 67, 72, 85, 82, 128, 67, 72, 85, 80, 128, + 67, 72, 85, 79, 88, 128, 67, 72, 85, 79, 84, 128, 67, 72, 85, 79, 80, + 128, 67, 72, 85, 79, 128, 67, 72, 85, 76, 65, 128, 67, 72, 85, 128, 67, + 72, 82, 89, 83, 65, 78, 84, 72, 69, 77, 85, 77, 128, 67, 72, 82, 79, 78, + 79, 85, 128, 67, 72, 82, 79, 78, 79, 78, 128, 67, 72, 82, 79, 77, 193, + 67, 72, 82, 79, 193, 67, 72, 82, 73, 86, 73, 128, 67, 72, 82, 73, 83, 84, + 77, 65, 83, 128, 67, 72, 82, 73, 83, 84, 77, 65, 211, 67, 72, 79, 89, + 128, 67, 72, 79, 88, 128, 67, 72, 79, 84, 128, 67, 72, 79, 82, 69, 86, + 77, 193, 67, 72, 79, 80, 128, 67, 72, 79, 75, 69, 128, 67, 72, 79, 69, + 128, 67, 72, 79, 67, 79, 76, 65, 84, 197, 67, 72, 79, 65, 128, 67, 72, + 207, 67, 72, 73, 84, 85, 69, 85, 77, 83, 83, 65, 78, 71, 83, 73, 79, 83, + 128, 67, 72, 73, 84, 85, 69, 85, 77, 83, 83, 65, 78, 71, 67, 73, 69, 85, + 67, 128, 67, 72, 73, 84, 85, 69, 85, 77, 83, 73, 79, 83, 128, 67, 72, 73, + 84, 85, 69, 85, 77, 67, 73, 69, 85, 67, 128, 67, 72, 73, 84, 85, 69, 85, + 77, 67, 72, 73, 69, 85, 67, 72, 128, 67, 72, 73, 82, 79, 78, 128, 67, 72, + 73, 82, 69, 84, 128, 67, 72, 73, 80, 77, 85, 78, 75, 128, 67, 72, 73, 78, + 79, 79, 203, 67, 72, 73, 78, 71, 128, 67, 72, 73, 78, 69, 83, 197, 67, + 72, 73, 78, 128, 67, 72, 73, 77, 69, 128, 67, 72, 73, 76, 76, 213, 67, + 72, 73, 76, 68, 82, 69, 206, 67, 72, 73, 76, 68, 128, 67, 72, 73, 76, + 128, 67, 72, 73, 75, 201, 67, 72, 73, 69, 85, 67, 72, 45, 75, 72, 73, 69, + 85, 75, 72, 128, 67, 72, 73, 69, 85, 67, 72, 45, 72, 73, 69, 85, 72, 128, + 67, 72, 73, 69, 85, 67, 200, 67, 72, 73, 67, 75, 69, 78, 128, 67, 72, 73, + 67, 75, 128, 67, 72, 73, 128, 67, 72, 201, 67, 72, 72, 65, 128, 67, 72, + 69, 88, 128, 67, 72, 69, 86, 82, 79, 206, 67, 72, 69, 84, 128, 67, 72, + 69, 83, 84, 78, 85, 84, 128, 67, 72, 69, 83, 211, 67, 72, 69, 82, 89, + 128, 67, 72, 69, 82, 82, 217, 67, 72, 69, 82, 82, 73, 69, 83, 128, 67, 72, 69, 81, 85, 69, 82, 69, 196, 67, 72, 69, 80, 128, 67, 72, 69, 206, 67, 72, 69, 73, 78, 65, 80, 128, 67, 72, 69, 73, 75, 72, 69, 73, 128, 67, 72, 69, 73, 75, 72, 65, 78, 128, 67, 72, 69, 69, 82, 73, 78, 199, 67, 72, - 69, 69, 128, 67, 72, 69, 67, 75, 128, 67, 72, 69, 67, 203, 67, 72, 197, - 67, 72, 65, 88, 128, 67, 72, 65, 86, 73, 89, 65, 78, 73, 128, 67, 72, 65, - 84, 84, 65, 87, 65, 128, 67, 72, 65, 84, 128, 67, 72, 65, 82, 84, 128, - 67, 72, 65, 82, 212, 67, 72, 65, 82, 73, 79, 84, 128, 67, 72, 65, 82, 73, - 79, 212, 67, 72, 65, 82, 65, 67, 84, 69, 82, 83, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 128, 67, 72, 65, 82, 128, 67, 72, 65, 80, 128, 67, 72, - 65, 78, 71, 128, 67, 72, 65, 78, 128, 67, 72, 65, 77, 75, 79, 128, 67, - 72, 65, 77, 73, 76, 79, 78, 128, 67, 72, 65, 77, 73, 76, 73, 128, 67, 72, - 65, 75, 77, 193, 67, 72, 65, 73, 82, 128, 67, 72, 65, 73, 78, 83, 128, - 67, 72, 65, 68, 65, 128, 67, 72, 65, 196, 67, 72, 65, 65, 128, 67, 71, - 74, 128, 67, 69, 88, 128, 67, 69, 82, 69, 83, 128, 67, 69, 82, 69, 77, - 79, 78, 89, 128, 67, 69, 82, 69, 75, 128, 67, 69, 82, 45, 87, 65, 128, - 67, 69, 80, 128, 67, 69, 79, 78, 71, 67, 72, 73, 69, 85, 77, 83, 83, 65, - 78, 71, 83, 73, 79, 83, 128, 67, 69, 79, 78, 71, 67, 72, 73, 69, 85, 77, - 83, 83, 65, 78, 71, 67, 73, 69, 85, 67, 128, 67, 69, 79, 78, 71, 67, 72, - 73, 69, 85, 77, 83, 73, 79, 83, 128, 67, 69, 79, 78, 71, 67, 72, 73, 69, - 85, 77, 67, 73, 69, 85, 67, 128, 67, 69, 79, 78, 71, 67, 72, 73, 69, 85, - 77, 67, 72, 73, 69, 85, 67, 72, 128, 67, 69, 78, 84, 85, 82, 73, 65, 204, - 67, 69, 78, 84, 82, 69, 76, 73, 78, 197, 67, 69, 78, 84, 82, 69, 196, 67, - 69, 78, 84, 82, 69, 128, 67, 69, 78, 84, 82, 197, 67, 69, 78, 128, 67, - 69, 76, 83, 73, 85, 83, 128, 67, 69, 76, 69, 66, 82, 65, 84, 73, 79, 78, - 128, 67, 69, 73, 82, 84, 128, 67, 69, 73, 76, 73, 78, 71, 128, 67, 69, - 69, 128, 67, 69, 68, 73, 76, 76, 65, 128, 67, 69, 68, 73, 76, 76, 193, - 67, 69, 68, 201, 67, 69, 67, 69, 75, 128, 67, 69, 67, 65, 75, 128, 67, - 69, 67, 65, 203, 67, 69, 65, 76, 67, 128, 67, 67, 85, 128, 67, 67, 79, - 128, 67, 67, 73, 128, 67, 67, 72, 85, 128, 67, 67, 72, 79, 128, 67, 67, - 72, 73, 128, 67, 67, 72, 72, 85, 128, 67, 67, 72, 72, 79, 128, 67, 67, - 72, 72, 73, 128, 67, 67, 72, 72, 69, 69, 128, 67, 67, 72, 72, 69, 128, - 67, 67, 72, 72, 65, 65, 128, 67, 67, 72, 72, 65, 128, 67, 67, 72, 69, 69, - 128, 67, 67, 72, 69, 128, 67, 67, 72, 65, 65, 128, 67, 67, 72, 65, 128, - 67, 67, 72, 128, 67, 67, 69, 69, 128, 67, 67, 69, 128, 67, 67, 65, 65, - 128, 67, 67, 65, 128, 67, 65, 89, 78, 128, 67, 65, 89, 65, 78, 78, 65, - 128, 67, 65, 88, 128, 67, 65, 86, 69, 128, 67, 65, 85, 84, 73, 79, 206, - 67, 65, 85, 76, 68, 82, 79, 78, 128, 67, 65, 85, 68, 65, 128, 67, 65, 85, + 69, 69, 77, 128, 67, 72, 69, 69, 128, 67, 72, 69, 67, 75, 69, 210, 67, + 72, 69, 67, 75, 128, 67, 72, 69, 67, 203, 67, 72, 197, 67, 72, 65, 88, + 128, 67, 72, 65, 86, 73, 89, 65, 78, 73, 128, 67, 72, 65, 84, 84, 65, 87, + 65, 128, 67, 72, 65, 84, 128, 67, 72, 65, 82, 84, 128, 67, 72, 65, 82, + 212, 67, 72, 65, 82, 73, 79, 84, 128, 67, 72, 65, 82, 73, 79, 212, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 83, 128, 67, 72, 65, 82, 65, 67, 84, 69, + 82, 128, 67, 72, 65, 82, 128, 67, 72, 65, 80, 84, 69, 82, 128, 67, 72, + 65, 80, 128, 67, 72, 65, 78, 71, 128, 67, 72, 65, 78, 128, 67, 72, 65, + 77, 75, 79, 128, 67, 72, 65, 77, 73, 76, 79, 78, 128, 67, 72, 65, 77, 73, + 76, 73, 128, 67, 72, 65, 75, 77, 193, 67, 72, 65, 73, 82, 128, 67, 72, + 65, 73, 78, 83, 128, 67, 72, 65, 68, 65, 128, 67, 72, 65, 196, 67, 72, + 65, 65, 128, 67, 71, 74, 128, 67, 69, 88, 128, 67, 69, 82, 69, 83, 128, + 67, 69, 82, 69, 77, 79, 78, 89, 128, 67, 69, 82, 69, 75, 128, 67, 69, 82, + 45, 87, 65, 128, 67, 69, 80, 128, 67, 69, 79, 78, 71, 67, 72, 73, 69, 85, + 77, 83, 83, 65, 78, 71, 83, 73, 79, 83, 128, 67, 69, 79, 78, 71, 67, 72, + 73, 69, 85, 77, 83, 83, 65, 78, 71, 67, 73, 69, 85, 67, 128, 67, 69, 79, + 78, 71, 67, 72, 73, 69, 85, 77, 83, 73, 79, 83, 128, 67, 69, 79, 78, 71, + 67, 72, 73, 69, 85, 77, 67, 73, 69, 85, 67, 128, 67, 69, 79, 78, 71, 67, + 72, 73, 69, 85, 77, 67, 72, 73, 69, 85, 67, 72, 128, 67, 69, 78, 84, 85, + 82, 73, 65, 204, 67, 69, 78, 84, 82, 69, 76, 73, 78, 197, 67, 69, 78, 84, + 82, 69, 68, 128, 67, 69, 78, 84, 82, 69, 196, 67, 69, 78, 84, 82, 69, + 128, 67, 69, 78, 84, 82, 197, 67, 69, 78, 84, 82, 65, 76, 73, 90, 65, 84, + 73, 79, 206, 67, 69, 78, 128, 67, 69, 76, 84, 73, 195, 67, 69, 76, 83, + 73, 85, 83, 128, 67, 69, 76, 69, 66, 82, 65, 84, 73, 79, 78, 128, 67, 69, + 73, 82, 84, 128, 67, 69, 73, 76, 73, 78, 71, 128, 67, 69, 69, 86, 128, + 67, 69, 69, 66, 128, 67, 69, 69, 128, 67, 69, 68, 73, 76, 76, 65, 128, + 67, 69, 68, 73, 76, 76, 193, 67, 69, 68, 201, 67, 69, 67, 69, 75, 128, + 67, 69, 67, 65, 75, 128, 67, 69, 67, 65, 203, 67, 69, 65, 76, 67, 128, + 67, 67, 85, 128, 67, 67, 79, 128, 67, 67, 73, 128, 67, 67, 72, 85, 128, + 67, 67, 72, 79, 128, 67, 67, 72, 73, 128, 67, 67, 72, 72, 85, 128, 67, + 67, 72, 72, 79, 128, 67, 67, 72, 72, 73, 128, 67, 67, 72, 72, 69, 69, + 128, 67, 67, 72, 72, 69, 128, 67, 67, 72, 72, 65, 65, 128, 67, 67, 72, + 72, 65, 128, 67, 67, 72, 69, 69, 128, 67, 67, 72, 69, 128, 67, 67, 72, + 65, 65, 128, 67, 67, 72, 65, 128, 67, 67, 72, 128, 67, 67, 69, 69, 128, + 67, 67, 69, 128, 67, 67, 65, 65, 128, 67, 67, 65, 128, 67, 65, 89, 78, + 128, 67, 65, 89, 65, 78, 78, 65, 128, 67, 65, 88, 128, 67, 65, 86, 69, + 128, 67, 65, 85, 84, 73, 79, 206, 67, 65, 85, 76, 68, 82, 79, 78, 128, + 67, 65, 85, 68, 65, 128, 67, 65, 85, 67, 65, 83, 73, 65, 206, 67, 65, 85, 128, 67, 65, 84, 65, 87, 65, 128, 67, 65, 84, 128, 67, 65, 212, 67, 65, - 83, 84, 76, 69, 128, 67, 65, 82, 89, 83, 84, 73, 65, 206, 67, 65, 82, 84, - 128, 67, 65, 82, 211, 67, 65, 82, 82, 73, 65, 71, 197, 67, 65, 82, 80, - 69, 78, 84, 82, 217, 67, 65, 82, 208, 67, 65, 82, 79, 85, 83, 69, 204, - 67, 65, 82, 79, 78, 128, 67, 65, 82, 79, 206, 67, 65, 82, 73, 203, 67, - 65, 82, 73, 65, 206, 67, 65, 82, 69, 84, 128, 67, 65, 82, 69, 212, 67, - 65, 82, 197, 67, 65, 82, 68, 83, 128, 67, 65, 82, 68, 128, 67, 65, 82, - 196, 67, 65, 82, 128, 67, 65, 210, 67, 65, 80, 85, 212, 67, 65, 80, 84, - 73, 86, 69, 128, 67, 65, 80, 82, 73, 67, 79, 82, 78, 128, 67, 65, 80, 79, - 128, 67, 65, 80, 73, 84, 65, 76, 128, 67, 65, 78, 84, 73, 76, 76, 65, 84, - 73, 79, 206, 67, 65, 78, 199, 67, 65, 78, 68, 89, 128, 67, 65, 78, 68, - 82, 65, 66, 73, 78, 68, 85, 128, 67, 65, 78, 68, 82, 65, 66, 73, 78, 68, - 213, 67, 65, 78, 68, 82, 65, 128, 67, 65, 78, 68, 82, 193, 67, 65, 78, - 67, 69, 82, 128, 67, 65, 78, 67, 69, 76, 76, 65, 84, 73, 79, 206, 67, 65, - 78, 67, 69, 76, 128, 67, 65, 78, 67, 69, 204, 67, 65, 78, 128, 67, 65, - 77, 78, 85, 195, 67, 65, 77, 69, 82, 65, 128, 67, 65, 77, 69, 76, 128, - 67, 65, 76, 89, 65, 128, 67, 65, 76, 89, 193, 67, 65, 76, 88, 128, 67, - 65, 76, 76, 128, 67, 65, 76, 69, 78, 68, 65, 82, 128, 67, 65, 76, 67, - 128, 67, 65, 75, 82, 65, 128, 67, 65, 75, 197, 67, 65, 73, 128, 67, 65, - 72, 128, 67, 65, 69, 83, 85, 82, 65, 128, 67, 65, 68, 85, 67, 69, 85, 83, - 128, 67, 65, 68, 193, 67, 65, 67, 84, 85, 83, 128, 67, 65, 66, 76, 69, - 87, 65, 89, 128, 67, 65, 66, 66, 65, 71, 69, 45, 84, 82, 69, 69, 128, 67, - 65, 65, 78, 71, 128, 67, 65, 65, 73, 128, 67, 193, 67, 48, 50, 52, 128, - 67, 48, 50, 51, 128, 67, 48, 50, 50, 128, 67, 48, 50, 49, 128, 67, 48, - 50, 48, 128, 67, 48, 49, 57, 128, 67, 48, 49, 56, 128, 67, 48, 49, 55, - 128, 67, 48, 49, 54, 128, 67, 48, 49, 53, 128, 67, 48, 49, 52, 128, 67, - 48, 49, 51, 128, 67, 48, 49, 50, 128, 67, 48, 49, 49, 128, 67, 48, 49, - 48, 65, 128, 67, 48, 49, 48, 128, 67, 48, 48, 57, 128, 67, 48, 48, 56, - 128, 67, 48, 48, 55, 128, 67, 48, 48, 54, 128, 67, 48, 48, 53, 128, 67, - 48, 48, 52, 128, 67, 48, 48, 51, 128, 67, 48, 48, 50, 67, 128, 67, 48, - 48, 50, 66, 128, 67, 48, 48, 50, 65, 128, 67, 48, 48, 50, 128, 67, 48, - 48, 49, 128, 67, 45, 83, 73, 77, 80, 76, 73, 70, 73, 69, 196, 67, 45, 51, - 57, 128, 67, 45, 49, 56, 128, 66, 90, 85, 78, 199, 66, 90, 72, 201, 66, - 89, 84, 197, 66, 89, 69, 76, 79, 82, 85, 83, 83, 73, 65, 78, 45, 85, 75, - 82, 65, 73, 78, 73, 65, 206, 66, 88, 71, 128, 66, 87, 73, 128, 66, 87, - 69, 69, 128, 66, 87, 69, 128, 66, 87, 65, 128, 66, 85, 85, 77, 73, 83, - 72, 128, 66, 85, 84, 84, 79, 78, 128, 66, 85, 212, 66, 85, 83, 84, 211, - 66, 85, 83, 212, 66, 85, 83, 83, 89, 69, 82, 85, 128, 66, 85, 211, 66, + 83, 84, 76, 69, 128, 67, 65, 83, 75, 69, 212, 67, 65, 82, 89, 83, 84, 73, + 65, 206, 67, 65, 82, 84, 82, 73, 68, 71, 69, 128, 67, 65, 82, 84, 128, + 67, 65, 82, 211, 67, 65, 82, 82, 73, 65, 71, 197, 67, 65, 82, 80, 69, 78, + 84, 82, 217, 67, 65, 82, 208, 67, 65, 82, 79, 85, 83, 69, 204, 67, 65, + 82, 79, 78, 128, 67, 65, 82, 79, 206, 67, 65, 82, 73, 203, 67, 65, 82, + 73, 65, 206, 67, 65, 82, 69, 84, 128, 67, 65, 82, 69, 212, 67, 65, 82, + 197, 67, 65, 82, 68, 83, 128, 67, 65, 82, 68, 128, 67, 65, 82, 128, 67, + 65, 210, 67, 65, 80, 85, 212, 67, 65, 80, 84, 73, 86, 69, 128, 67, 65, + 80, 82, 73, 67, 79, 82, 78, 128, 67, 65, 80, 80, 69, 196, 67, 65, 80, 79, + 128, 67, 65, 80, 73, 84, 85, 76, 85, 77, 128, 67, 65, 80, 73, 84, 65, 76, + 128, 67, 65, 78, 84, 73, 76, 76, 65, 84, 73, 79, 206, 67, 65, 78, 199, + 67, 65, 78, 68, 89, 128, 67, 65, 78, 68, 82, 65, 66, 73, 78, 68, 85, 128, + 67, 65, 78, 68, 82, 65, 66, 73, 78, 68, 213, 67, 65, 78, 68, 82, 65, 128, + 67, 65, 78, 68, 82, 193, 67, 65, 78, 68, 76, 69, 128, 67, 65, 78, 67, 69, + 82, 128, 67, 65, 78, 67, 69, 76, 76, 65, 84, 73, 79, 206, 67, 65, 78, 67, + 69, 76, 128, 67, 65, 78, 67, 69, 204, 67, 65, 78, 128, 67, 65, 77, 80, + 73, 78, 71, 128, 67, 65, 77, 78, 85, 195, 67, 65, 77, 69, 82, 65, 128, + 67, 65, 77, 69, 82, 193, 67, 65, 77, 69, 76, 128, 67, 65, 76, 89, 65, + 128, 67, 65, 76, 89, 193, 67, 65, 76, 88, 128, 67, 65, 76, 76, 128, 67, + 65, 76, 69, 78, 68, 65, 82, 128, 67, 65, 76, 69, 78, 68, 65, 210, 67, 65, + 76, 67, 85, 76, 65, 84, 79, 82, 128, 67, 65, 76, 67, 128, 67, 65, 75, 82, + 65, 128, 67, 65, 75, 197, 67, 65, 73, 128, 67, 65, 72, 128, 67, 65, 69, + 83, 85, 82, 65, 128, 67, 65, 68, 85, 67, 69, 85, 83, 128, 67, 65, 68, + 193, 67, 65, 67, 84, 85, 83, 128, 67, 65, 66, 76, 69, 87, 65, 89, 128, + 67, 65, 66, 73, 78, 69, 84, 128, 67, 65, 66, 66, 65, 71, 69, 45, 84, 82, + 69, 69, 128, 67, 65, 65, 78, 71, 128, 67, 65, 65, 73, 128, 67, 193, 67, + 48, 50, 52, 128, 67, 48, 50, 51, 128, 67, 48, 50, 50, 128, 67, 48, 50, + 49, 128, 67, 48, 50, 48, 128, 67, 48, 49, 57, 128, 67, 48, 49, 56, 128, + 67, 48, 49, 55, 128, 67, 48, 49, 54, 128, 67, 48, 49, 53, 128, 67, 48, + 49, 52, 128, 67, 48, 49, 51, 128, 67, 48, 49, 50, 128, 67, 48, 49, 49, + 128, 67, 48, 49, 48, 65, 128, 67, 48, 49, 48, 128, 67, 48, 48, 57, 128, + 67, 48, 48, 56, 128, 67, 48, 48, 55, 128, 67, 48, 48, 54, 128, 67, 48, + 48, 53, 128, 67, 48, 48, 52, 128, 67, 48, 48, 51, 128, 67, 48, 48, 50, + 67, 128, 67, 48, 48, 50, 66, 128, 67, 48, 48, 50, 65, 128, 67, 48, 48, + 50, 128, 67, 48, 48, 49, 128, 67, 45, 83, 73, 77, 80, 76, 73, 70, 73, 69, + 196, 67, 45, 51, 57, 128, 67, 45, 49, 56, 128, 66, 90, 85, 78, 199, 66, + 90, 72, 201, 66, 89, 84, 197, 66, 89, 69, 76, 79, 82, 85, 83, 83, 73, 65, + 78, 45, 85, 75, 82, 65, 73, 78, 73, 65, 206, 66, 88, 71, 128, 66, 87, 73, + 128, 66, 87, 69, 69, 128, 66, 87, 69, 128, 66, 87, 65, 128, 66, 85, 85, + 77, 73, 83, 72, 128, 66, 85, 84, 84, 79, 78, 128, 66, 85, 84, 84, 79, + 206, 66, 85, 212, 66, 85, 83, 84, 211, 66, 85, 83, 212, 66, 85, 83, 83, + 89, 69, 82, 85, 128, 66, 85, 83, 73, 78, 69, 83, 211, 66, 85, 211, 66, 85, 82, 213, 66, 85, 82, 50, 128, 66, 85, 210, 66, 85, 79, 88, 128, 66, 85, 79, 80, 128, 66, 85, 78, 78, 217, 66, 85, 78, 71, 128, 66, 85, 77, 80, 217, 66, 85, 76, 85, 71, 128, 66, 85, 76, 85, 199, 66, 85, 76, 76, - 83, 69, 89, 69, 128, 66, 85, 76, 76, 211, 66, 85, 76, 76, 69, 84, 128, - 66, 85, 76, 76, 69, 212, 66, 85, 76, 76, 128, 66, 85, 76, 66, 128, 66, - 85, 75, 89, 128, 66, 85, 73, 76, 68, 73, 78, 71, 83, 128, 66, 85, 73, 76, - 68, 73, 78, 71, 128, 66, 85, 72, 73, 196, 66, 85, 71, 73, 78, 69, 83, - 197, 66, 85, 71, 128, 66, 85, 70, 70, 65, 76, 79, 128, 66, 85, 67, 75, - 76, 69, 128, 66, 83, 84, 65, 82, 128, 66, 83, 75, 85, 210, 66, 83, 75, - 65, 173, 66, 83, 68, 85, 211, 66, 82, 85, 83, 72, 128, 66, 82, 85, 83, - 200, 66, 82, 79, 78, 90, 69, 128, 66, 82, 79, 75, 69, 206, 66, 82, 79, - 65, 196, 66, 82, 73, 83, 84, 76, 69, 128, 66, 82, 73, 71, 72, 84, 78, 69, - 83, 211, 66, 82, 73, 69, 70, 67, 65, 83, 69, 128, 66, 82, 73, 68, 71, - 197, 66, 82, 73, 68, 197, 66, 82, 73, 67, 75, 128, 66, 82, 69, 86, 73, - 83, 128, 66, 82, 69, 86, 69, 45, 77, 65, 67, 82, 79, 78, 128, 66, 82, 69, - 86, 197, 66, 82, 69, 65, 84, 200, 66, 82, 69, 65, 75, 84, 72, 82, 79, 85, - 71, 72, 128, 66, 82, 69, 65, 68, 128, 66, 82, 68, 193, 66, 82, 65, 78, - 67, 72, 73, 78, 199, 66, 82, 65, 78, 67, 72, 128, 66, 82, 65, 78, 67, + 83, 69, 89, 69, 128, 66, 85, 76, 76, 211, 66, 85, 76, 76, 72, 79, 82, 78, + 128, 66, 85, 76, 76, 72, 79, 82, 206, 66, 85, 76, 76, 69, 84, 128, 66, + 85, 76, 76, 69, 212, 66, 85, 76, 76, 128, 66, 85, 76, 66, 128, 66, 85, + 75, 89, 128, 66, 85, 73, 76, 68, 73, 78, 71, 83, 128, 66, 85, 73, 76, 68, + 73, 78, 71, 128, 66, 85, 73, 76, 68, 73, 78, 199, 66, 85, 72, 73, 196, + 66, 85, 71, 73, 78, 69, 83, 197, 66, 85, 71, 128, 66, 85, 70, 70, 65, 76, + 79, 128, 66, 85, 68, 128, 66, 85, 67, 75, 76, 69, 128, 66, 85, 66, 66, + 76, 69, 83, 128, 66, 85, 66, 66, 76, 69, 128, 66, 83, 84, 65, 82, 128, + 66, 83, 75, 85, 210, 66, 83, 75, 65, 173, 66, 83, 68, 85, 211, 66, 82, + 85, 83, 200, 66, 82, 79, 78, 90, 69, 128, 66, 82, 79, 75, 69, 206, 66, + 82, 79, 65, 196, 66, 82, 73, 83, 84, 76, 69, 128, 66, 82, 73, 71, 72, 84, + 78, 69, 83, 211, 66, 82, 73, 69, 70, 67, 65, 83, 69, 128, 66, 82, 73, 68, + 71, 197, 66, 82, 73, 68, 197, 66, 82, 73, 67, 75, 128, 66, 82, 69, 86, + 73, 83, 128, 66, 82, 69, 86, 69, 45, 77, 65, 67, 82, 79, 78, 128, 66, 82, + 69, 86, 197, 66, 82, 69, 65, 84, 200, 66, 82, 69, 65, 75, 84, 72, 82, 79, + 85, 71, 72, 128, 66, 82, 69, 65, 68, 128, 66, 82, 68, 193, 66, 82, 65, + 78, 67, 72, 73, 78, 199, 66, 82, 65, 78, 67, 72, 128, 66, 82, 65, 78, 67, 200, 66, 82, 65, 75, 67, 69, 84, 128, 66, 82, 65, 67, 75, 69, 84, 69, 196, 66, 82, 65, 67, 75, 69, 212, 66, 82, 65, 67, 69, 128, 66, 81, 128, - 66, 80, 72, 128, 66, 79, 89, 128, 66, 79, 87, 84, 73, 69, 128, 66, 79, - 87, 84, 73, 197, 66, 79, 87, 76, 73, 78, 71, 128, 66, 79, 87, 76, 128, - 66, 79, 87, 73, 78, 199, 66, 79, 215, 66, 79, 85, 81, 85, 69, 84, 128, - 66, 79, 85, 78, 68, 65, 82, 217, 66, 79, 84, 84, 79, 77, 45, 76, 73, 71, - 72, 84, 69, 196, 66, 79, 84, 84, 79, 77, 128, 66, 79, 84, 84, 79, 205, - 66, 79, 84, 84, 76, 69, 128, 66, 79, 84, 84, 76, 197, 66, 79, 84, 200, - 66, 79, 82, 85, 84, 79, 128, 66, 79, 82, 65, 88, 45, 51, 128, 66, 79, 82, - 65, 88, 45, 50, 128, 66, 79, 82, 65, 88, 128, 66, 79, 80, 79, 77, 79, 70, - 207, 66, 79, 79, 84, 83, 128, 66, 79, 79, 84, 128, 66, 79, 79, 77, 69, - 82, 65, 78, 71, 128, 66, 79, 79, 75, 83, 128, 66, 79, 79, 75, 77, 65, 82, - 75, 128, 66, 79, 79, 75, 77, 65, 82, 203, 66, 79, 78, 69, 128, 66, 79, - 77, 66, 128, 66, 79, 77, 128, 66, 79, 76, 84, 128, 66, 79, 76, 212, 66, - 79, 72, 65, 73, 82, 73, 195, 66, 79, 68, 89, 128, 66, 79, 65, 82, 128, - 66, 79, 65, 128, 66, 76, 85, 69, 128, 66, 76, 85, 197, 66, 76, 79, 87, - 70, 73, 83, 72, 128, 66, 76, 79, 83, 83, 79, 77, 128, 66, 76, 79, 79, 68, - 128, 66, 76, 79, 78, 196, 66, 76, 79, 67, 75, 128, 66, 76, 69, 78, 68, - 69, 196, 66, 76, 65, 78, 75, 128, 66, 76, 65, 78, 203, 66, 76, 65, 68, - 197, 66, 76, 65, 67, 75, 70, 79, 79, 212, 66, 76, 65, 67, 75, 45, 76, 69, - 84, 84, 69, 210, 66, 76, 65, 67, 75, 45, 70, 69, 65, 84, 72, 69, 82, 69, - 196, 66, 76, 65, 67, 75, 128, 66, 75, 65, 173, 66, 73, 84, 84, 69, 82, - 128, 66, 73, 84, 73, 78, 199, 66, 73, 83, 77, 85, 84, 200, 66, 73, 83, - 77, 73, 76, 76, 65, 200, 66, 73, 83, 72, 79, 80, 128, 66, 73, 83, 69, 67, - 84, 73, 78, 199, 66, 73, 83, 65, 72, 128, 66, 73, 82, 85, 128, 66, 73, - 82, 84, 72, 68, 65, 217, 66, 73, 82, 71, 65, 128, 66, 73, 82, 68, 128, - 66, 73, 79, 72, 65, 90, 65, 82, 196, 66, 73, 78, 79, 67, 85, 76, 65, 210, - 66, 73, 78, 68, 73, 78, 199, 66, 73, 78, 68, 73, 128, 66, 73, 78, 65, 82, - 217, 66, 73, 76, 76, 73, 65, 82, 68, 83, 128, 66, 73, 76, 65, 66, 73, 65, - 204, 66, 73, 75, 73, 78, 73, 128, 66, 73, 71, 128, 66, 73, 199, 66, 73, - 69, 84, 128, 66, 73, 68, 69, 78, 84, 65, 204, 66, 73, 68, 65, 75, 85, 79, + 66, 80, 72, 128, 66, 79, 89, 211, 66, 79, 89, 128, 66, 79, 87, 84, 73, + 69, 128, 66, 79, 87, 84, 73, 197, 66, 79, 87, 76, 73, 78, 71, 128, 66, + 79, 87, 76, 128, 66, 79, 87, 73, 78, 199, 66, 79, 215, 66, 79, 85, 81, + 85, 69, 84, 128, 66, 79, 85, 81, 85, 69, 212, 66, 79, 85, 78, 68, 65, 82, + 217, 66, 79, 84, 84, 79, 77, 45, 83, 72, 65, 68, 69, 196, 66, 79, 84, 84, + 79, 77, 45, 76, 73, 71, 72, 84, 69, 196, 66, 79, 84, 84, 79, 77, 128, 66, + 79, 84, 84, 79, 205, 66, 79, 84, 84, 76, 69, 128, 66, 79, 84, 84, 76, + 197, 66, 79, 84, 200, 66, 79, 82, 85, 84, 79, 128, 66, 79, 82, 65, 88, + 45, 51, 128, 66, 79, 82, 65, 88, 45, 50, 128, 66, 79, 82, 65, 88, 128, + 66, 79, 80, 79, 77, 79, 70, 207, 66, 79, 79, 84, 83, 128, 66, 79, 79, 84, + 128, 66, 79, 79, 77, 69, 82, 65, 78, 71, 128, 66, 79, 79, 75, 83, 128, + 66, 79, 79, 75, 77, 65, 82, 75, 128, 66, 79, 79, 75, 77, 65, 82, 203, 66, + 79, 78, 69, 128, 66, 79, 77, 66, 128, 66, 79, 77, 128, 66, 79, 76, 84, + 128, 66, 79, 76, 212, 66, 79, 72, 65, 73, 82, 73, 195, 66, 79, 68, 89, + 128, 66, 79, 65, 82, 128, 66, 79, 65, 128, 66, 76, 85, 69, 128, 66, 76, + 85, 197, 66, 76, 79, 87, 73, 78, 199, 66, 76, 79, 87, 70, 73, 83, 72, + 128, 66, 76, 79, 83, 83, 79, 77, 128, 66, 76, 79, 79, 68, 128, 66, 76, + 79, 78, 196, 66, 76, 79, 67, 75, 128, 66, 76, 69, 78, 68, 69, 196, 66, + 76, 65, 78, 75, 128, 66, 76, 65, 78, 203, 66, 76, 65, 68, 197, 66, 76, + 65, 67, 75, 76, 69, 84, 84, 69, 210, 66, 76, 65, 67, 75, 70, 79, 79, 212, + 66, 76, 65, 67, 75, 45, 76, 69, 84, 84, 69, 210, 66, 76, 65, 67, 75, 45, + 70, 69, 65, 84, 72, 69, 82, 69, 196, 66, 76, 65, 67, 75, 128, 66, 75, 65, + 173, 66, 73, 84, 84, 69, 82, 128, 66, 73, 84, 73, 78, 199, 66, 73, 83, + 77, 85, 84, 200, 66, 73, 83, 77, 73, 76, 76, 65, 200, 66, 73, 83, 72, 79, + 80, 128, 66, 73, 83, 69, 67, 84, 73, 78, 199, 66, 73, 83, 65, 72, 128, + 66, 73, 82, 85, 128, 66, 73, 82, 84, 72, 68, 65, 217, 66, 73, 82, 71, 65, + 128, 66, 73, 82, 68, 128, 66, 73, 79, 72, 65, 90, 65, 82, 196, 66, 73, + 78, 79, 67, 85, 76, 65, 210, 66, 73, 78, 68, 73, 78, 199, 66, 73, 78, 68, + 73, 128, 66, 73, 78, 65, 82, 217, 66, 73, 76, 76, 73, 79, 78, 83, 128, + 66, 73, 76, 76, 73, 65, 82, 68, 83, 128, 66, 73, 76, 65, 66, 73, 65, 204, + 66, 73, 75, 73, 78, 73, 128, 66, 73, 71, 128, 66, 73, 199, 66, 73, 69, + 84, 128, 66, 73, 68, 69, 78, 84, 65, 204, 66, 73, 68, 65, 75, 85, 79, 206, 66, 73, 67, 89, 67, 76, 73, 83, 84, 128, 66, 73, 67, 89, 67, 76, 69, 83, 128, 66, 73, 67, 89, 67, 76, 69, 128, 66, 73, 67, 69, 80, 83, 128, 66, 73, 66, 76, 69, 45, 67, 82, 69, 197, 66, 73, 66, 128, 66, 201, 66, @@ -4351,15487 +4581,17201 @@ static unsigned char lexicon[] = { 84, 87, 69, 69, 206, 66, 69, 84, 72, 128, 66, 69, 84, 65, 128, 66, 69, 84, 193, 66, 69, 212, 66, 69, 83, 73, 68, 197, 66, 69, 82, 75, 65, 78, 65, 206, 66, 69, 82, 66, 69, 210, 66, 69, 80, 128, 66, 69, 79, 82, 195, - 66, 69, 78, 90, 69, 78, 197, 66, 69, 78, 84, 207, 66, 69, 78, 68, 69, - 128, 66, 69, 78, 68, 128, 66, 69, 206, 66, 69, 76, 84, 128, 66, 69, 76, - 212, 66, 69, 76, 79, 215, 66, 69, 76, 76, 128, 66, 69, 76, 204, 66, 69, - 76, 71, 84, 72, 79, 210, 66, 69, 76, 128, 66, 69, 73, 84, 72, 128, 66, - 69, 72, 73, 78, 196, 66, 69, 72, 69, 72, 128, 66, 69, 72, 69, 200, 66, - 69, 72, 128, 66, 69, 200, 66, 69, 71, 73, 78, 78, 73, 78, 71, 128, 66, - 69, 71, 73, 78, 78, 69, 82, 128, 66, 69, 71, 73, 206, 66, 69, 70, 79, 82, - 197, 66, 69, 69, 84, 76, 69, 128, 66, 69, 69, 84, 65, 128, 66, 69, 69, - 210, 66, 69, 69, 72, 73, 86, 69, 128, 66, 69, 69, 72, 128, 66, 69, 69, - 200, 66, 69, 67, 65, 85, 83, 69, 128, 66, 69, 65, 86, 69, 210, 66, 69, - 65, 84, 73, 78, 199, 66, 69, 65, 84, 128, 66, 69, 65, 210, 66, 69, 65, - 78, 128, 66, 69, 65, 77, 69, 196, 66, 67, 65, 68, 128, 66, 67, 65, 196, - 66, 66, 89, 88, 128, 66, 66, 89, 84, 128, 66, 66, 89, 80, 128, 66, 66, - 89, 128, 66, 66, 85, 88, 128, 66, 66, 85, 84, 128, 66, 66, 85, 82, 88, - 128, 66, 66, 85, 82, 128, 66, 66, 85, 80, 128, 66, 66, 85, 79, 88, 128, - 66, 66, 85, 79, 80, 128, 66, 66, 85, 79, 128, 66, 66, 85, 128, 66, 66, - 79, 88, 128, 66, 66, 79, 84, 128, 66, 66, 79, 80, 128, 66, 66, 79, 128, - 66, 66, 73, 88, 128, 66, 66, 73, 80, 128, 66, 66, 73, 69, 88, 128, 66, - 66, 73, 69, 84, 128, 66, 66, 73, 69, 80, 128, 66, 66, 73, 69, 128, 66, - 66, 73, 128, 66, 66, 69, 88, 128, 66, 66, 69, 80, 128, 66, 66, 69, 69, - 128, 66, 66, 69, 128, 66, 66, 65, 88, 128, 66, 66, 65, 84, 128, 66, 66, - 65, 80, 128, 66, 66, 65, 65, 128, 66, 66, 65, 128, 66, 65, 89, 65, 78, - 78, 65, 128, 66, 65, 85, 128, 66, 65, 84, 84, 69, 82, 89, 128, 66, 65, - 84, 72, 84, 85, 66, 128, 66, 65, 84, 72, 65, 77, 65, 83, 65, 84, 128, 66, - 65, 84, 72, 128, 66, 65, 84, 200, 66, 65, 84, 65, 203, 66, 65, 83, 83, - 65, 128, 66, 65, 83, 75, 69, 84, 66, 65, 76, 204, 66, 65, 83, 72, 75, 73, - 210, 66, 65, 83, 72, 128, 66, 65, 83, 69, 66, 65, 76, 76, 128, 66, 65, - 83, 69, 128, 66, 65, 83, 197, 66, 65, 82, 83, 128, 66, 65, 82, 82, 73, - 69, 82, 128, 66, 65, 82, 82, 69, 75, 72, 128, 66, 65, 82, 82, 69, 69, - 128, 66, 65, 82, 82, 69, 197, 66, 65, 82, 76, 73, 78, 69, 128, 66, 65, - 82, 76, 69, 89, 128, 66, 65, 82, 73, 89, 79, 79, 83, 65, 78, 128, 66, 65, - 82, 66, 69, 210, 66, 65, 82, 194, 66, 65, 82, 65, 50, 128, 66, 65, 210, - 66, 65, 78, 84, 79, 67, 128, 66, 65, 78, 75, 78, 79, 84, 197, 66, 65, 78, - 75, 128, 66, 65, 78, 203, 66, 65, 78, 68, 128, 66, 65, 78, 65, 78, 65, - 128, 66, 65, 78, 50, 128, 66, 65, 78, 178, 66, 65, 77, 66, 79, 79, 83, - 128, 66, 65, 77, 66, 79, 79, 128, 66, 65, 76, 85, 68, 65, 128, 66, 65, - 76, 76, 79, 212, 66, 65, 76, 76, 79, 79, 78, 45, 83, 80, 79, 75, 69, 196, - 66, 65, 76, 76, 79, 79, 78, 128, 66, 65, 76, 65, 71, 128, 66, 65, 76, - 128, 66, 65, 204, 66, 65, 73, 82, 75, 65, 78, 128, 66, 65, 73, 77, 65, - 73, 128, 66, 65, 72, 84, 128, 66, 65, 72, 73, 82, 71, 79, 77, 85, 75, 72, - 65, 128, 66, 65, 72, 65, 82, 50, 128, 66, 65, 72, 128, 66, 65, 71, 71, - 65, 71, 197, 66, 65, 71, 65, 128, 66, 65, 71, 51, 128, 66, 65, 199, 66, - 65, 68, 71, 69, 82, 128, 66, 65, 68, 71, 69, 128, 66, 65, 68, 128, 66, - 65, 67, 84, 82, 73, 65, 206, 66, 65, 67, 75, 87, 65, 82, 68, 128, 66, 65, - 67, 75, 83, 80, 65, 67, 69, 128, 66, 65, 67, 75, 83, 76, 65, 83, 72, 128, - 66, 65, 67, 75, 83, 76, 65, 83, 200, 66, 65, 67, 75, 72, 65, 78, 196, 66, - 65, 67, 75, 45, 84, 73, 76, 84, 69, 196, 66, 65, 67, 75, 128, 66, 65, 67, - 203, 66, 65, 66, 89, 128, 66, 65, 66, 217, 66, 65, 65, 82, 69, 82, 85, - 128, 66, 65, 45, 50, 128, 66, 51, 48, 53, 128, 66, 50, 53, 57, 128, 66, - 50, 53, 56, 128, 66, 50, 53, 55, 128, 66, 50, 53, 54, 128, 66, 50, 53, - 53, 128, 66, 50, 53, 180, 66, 50, 53, 51, 128, 66, 50, 53, 50, 128, 66, - 50, 53, 49, 128, 66, 50, 53, 48, 128, 66, 50, 52, 57, 128, 66, 50, 52, - 56, 128, 66, 50, 52, 183, 66, 50, 52, 54, 128, 66, 50, 52, 53, 128, 66, - 50, 52, 179, 66, 50, 52, 178, 66, 50, 52, 177, 66, 50, 52, 176, 66, 50, - 51, 54, 128, 66, 50, 51, 52, 128, 66, 50, 51, 179, 66, 50, 51, 50, 128, - 66, 50, 51, 177, 66, 50, 51, 176, 66, 50, 50, 57, 128, 66, 50, 50, 56, - 128, 66, 50, 50, 55, 128, 66, 50, 50, 54, 128, 66, 50, 50, 181, 66, 50, - 50, 50, 128, 66, 50, 50, 49, 128, 66, 50, 50, 176, 66, 50, 49, 57, 128, - 66, 50, 49, 56, 128, 66, 50, 49, 55, 128, 66, 50, 49, 54, 128, 66, 50, - 49, 53, 128, 66, 50, 49, 52, 128, 66, 50, 49, 51, 128, 66, 50, 49, 50, - 128, 66, 50, 49, 49, 128, 66, 50, 49, 48, 128, 66, 50, 48, 57, 128, 66, - 50, 48, 56, 128, 66, 50, 48, 55, 128, 66, 50, 48, 54, 128, 66, 50, 48, - 53, 128, 66, 50, 48, 52, 128, 66, 50, 48, 51, 128, 66, 50, 48, 50, 128, - 66, 50, 48, 49, 128, 66, 50, 48, 48, 128, 66, 49, 57, 177, 66, 49, 57, - 48, 128, 66, 49, 56, 57, 128, 66, 49, 56, 53, 128, 66, 49, 56, 52, 128, - 66, 49, 56, 51, 128, 66, 49, 56, 50, 128, 66, 49, 56, 49, 128, 66, 49, - 56, 48, 128, 66, 49, 55, 57, 128, 66, 49, 55, 56, 128, 66, 49, 55, 55, - 128, 66, 49, 55, 182, 66, 49, 55, 52, 128, 66, 49, 55, 179, 66, 49, 55, - 50, 128, 66, 49, 55, 49, 128, 66, 49, 55, 48, 128, 66, 49, 54, 57, 128, - 66, 49, 54, 56, 128, 66, 49, 54, 55, 128, 66, 49, 54, 54, 128, 66, 49, - 54, 53, 128, 66, 49, 54, 52, 128, 66, 49, 54, 179, 66, 49, 54, 178, 66, - 49, 54, 49, 128, 66, 49, 54, 48, 128, 66, 49, 53, 185, 66, 49, 53, 56, - 128, 66, 49, 53, 55, 128, 66, 49, 53, 182, 66, 49, 53, 53, 128, 66, 49, - 53, 52, 128, 66, 49, 53, 51, 128, 66, 49, 53, 50, 128, 66, 49, 53, 177, - 66, 49, 53, 48, 128, 66, 49, 52, 54, 128, 66, 49, 52, 181, 66, 49, 52, - 50, 128, 66, 49, 52, 177, 66, 49, 52, 176, 66, 49, 51, 181, 66, 49, 51, - 179, 66, 49, 51, 50, 128, 66, 49, 51, 177, 66, 49, 51, 176, 66, 49, 50, - 184, 66, 49, 50, 183, 66, 49, 50, 181, 66, 49, 50, 179, 66, 49, 50, 178, - 66, 49, 50, 177, 66, 49, 50, 176, 66, 49, 48, 57, 205, 66, 49, 48, 57, - 198, 66, 49, 48, 56, 205, 66, 49, 48, 56, 198, 66, 49, 48, 55, 205, 66, - 49, 48, 55, 198, 66, 49, 48, 54, 205, 66, 49, 48, 54, 198, 66, 49, 48, - 53, 205, 66, 49, 48, 53, 198, 66, 49, 48, 181, 66, 49, 48, 180, 66, 49, - 48, 178, 66, 49, 48, 176, 66, 48, 57, 177, 66, 48, 57, 176, 66, 48, 56, - 57, 128, 66, 48, 56, 183, 66, 48, 56, 54, 128, 66, 48, 56, 181, 66, 48, - 56, 51, 128, 66, 48, 56, 50, 128, 66, 48, 56, 177, 66, 48, 56, 176, 66, - 48, 55, 57, 128, 66, 48, 55, 184, 66, 48, 55, 183, 66, 48, 55, 182, 66, - 48, 55, 181, 66, 48, 55, 180, 66, 48, 55, 179, 66, 48, 55, 178, 66, 48, - 55, 177, 66, 48, 55, 176, 66, 48, 54, 185, 66, 48, 54, 184, 66, 48, 54, - 183, 66, 48, 54, 182, 66, 48, 54, 181, 66, 48, 54, 52, 128, 66, 48, 54, - 51, 128, 66, 48, 54, 178, 66, 48, 54, 177, 66, 48, 54, 176, 66, 48, 53, - 185, 66, 48, 53, 184, 66, 48, 53, 183, 66, 48, 53, 54, 128, 66, 48, 53, - 181, 66, 48, 53, 180, 66, 48, 53, 179, 66, 48, 53, 178, 66, 48, 53, 177, - 66, 48, 53, 176, 66, 48, 52, 57, 128, 66, 48, 52, 184, 66, 48, 52, 55, - 128, 66, 48, 52, 182, 66, 48, 52, 181, 66, 48, 52, 180, 66, 48, 52, 179, - 66, 48, 52, 178, 66, 48, 52, 177, 66, 48, 52, 176, 66, 48, 51, 185, 66, - 48, 51, 184, 66, 48, 51, 183, 66, 48, 51, 182, 66, 48, 51, 52, 128, 66, - 48, 51, 179, 66, 48, 51, 178, 66, 48, 51, 177, 66, 48, 51, 176, 66, 48, - 50, 185, 66, 48, 50, 184, 66, 48, 50, 183, 66, 48, 50, 182, 66, 48, 50, - 181, 66, 48, 50, 180, 66, 48, 50, 179, 66, 48, 50, 50, 128, 66, 48, 50, - 177, 66, 48, 50, 176, 66, 48, 49, 57, 128, 66, 48, 49, 56, 128, 66, 48, - 49, 183, 66, 48, 49, 182, 66, 48, 49, 181, 66, 48, 49, 180, 66, 48, 49, - 179, 66, 48, 49, 178, 66, 48, 49, 177, 66, 48, 49, 176, 66, 48, 48, 57, - 128, 66, 48, 48, 185, 66, 48, 48, 56, 128, 66, 48, 48, 184, 66, 48, 48, - 55, 128, 66, 48, 48, 183, 66, 48, 48, 54, 128, 66, 48, 48, 182, 66, 48, - 48, 53, 65, 128, 66, 48, 48, 53, 128, 66, 48, 48, 181, 66, 48, 48, 52, - 128, 66, 48, 48, 180, 66, 48, 48, 51, 128, 66, 48, 48, 179, 66, 48, 48, - 50, 128, 66, 48, 48, 178, 66, 48, 48, 49, 128, 66, 48, 48, 177, 65, 90, - 85, 128, 65, 89, 69, 210, 65, 89, 66, 128, 65, 89, 65, 72, 128, 65, 88, - 69, 128, 65, 87, 69, 128, 65, 86, 69, 83, 84, 65, 206, 65, 86, 69, 82, - 65, 71, 197, 65, 86, 65, 75, 82, 65, 72, 65, 83, 65, 78, 89, 65, 128, 65, - 86, 65, 71, 82, 65, 72, 65, 128, 65, 85, 89, 65, 78, 78, 65, 128, 65, 85, - 84, 85, 77, 78, 128, 65, 85, 84, 79, 77, 79, 66, 73, 76, 69, 128, 65, 85, - 84, 79, 77, 65, 84, 69, 196, 65, 85, 83, 84, 82, 65, 204, 65, 85, 82, 73, - 80, 73, 71, 77, 69, 78, 84, 128, 65, 85, 82, 65, 77, 65, 90, 68, 65, 65, - 72, 65, 128, 65, 85, 82, 65, 77, 65, 90, 68, 65, 65, 45, 50, 128, 65, 85, - 82, 65, 77, 65, 90, 68, 65, 65, 128, 65, 85, 78, 78, 128, 65, 85, 71, 85, - 83, 84, 128, 65, 85, 71, 77, 69, 78, 84, 65, 84, 73, 79, 206, 65, 85, 69, - 128, 65, 85, 66, 69, 82, 71, 73, 78, 69, 128, 65, 84, 84, 73, 195, 65, - 84, 84, 72, 65, 67, 65, 78, 128, 65, 84, 84, 69, 78, 84, 73, 79, 78, 128, - 65, 84, 84, 65, 203, 65, 84, 79, 205, 65, 84, 78, 65, 200, 65, 84, 77, - 65, 65, 85, 128, 65, 84, 73, 89, 65, 128, 65, 84, 72, 76, 69, 84, 73, - 195, 65, 84, 72, 65, 82, 86, 65, 86, 69, 68, 73, 195, 65, 84, 72, 65, 80, - 65, 83, 67, 65, 206, 65, 83, 90, 128, 65, 83, 89, 85, 82, 193, 65, 83, - 89, 77, 80, 84, 79, 84, 73, 67, 65, 76, 76, 217, 65, 83, 84, 82, 79, 78, - 79, 77, 73, 67, 65, 204, 65, 83, 84, 82, 79, 76, 79, 71, 73, 67, 65, 204, - 65, 83, 84, 79, 78, 73, 83, 72, 69, 196, 65, 83, 84, 69, 82, 73, 83, 77, - 128, 65, 83, 84, 69, 82, 73, 83, 75, 211, 65, 83, 84, 69, 82, 73, 83, 75, - 128, 65, 83, 84, 69, 82, 73, 83, 203, 65, 83, 84, 69, 82, 73, 83, 67, 85, - 83, 128, 65, 83, 83, 89, 82, 73, 65, 206, 65, 83, 83, 69, 82, 84, 73, 79, - 78, 128, 65, 83, 80, 73, 82, 65, 84, 73, 79, 78, 128, 65, 83, 80, 73, 82, - 65, 84, 69, 196, 65, 83, 80, 69, 82, 128, 65, 83, 73, 65, 45, 65, 85, 83, - 84, 82, 65, 76, 73, 65, 128, 65, 83, 72, 71, 65, 66, 128, 65, 83, 72, 69, - 83, 128, 65, 83, 72, 57, 128, 65, 83, 72, 178, 65, 83, 67, 69, 78, 84, + 66, 69, 78, 90, 69, 78, 197, 66, 69, 78, 84, 207, 66, 69, 78, 212, 66, + 69, 78, 68, 69, 128, 66, 69, 78, 68, 128, 66, 69, 206, 66, 69, 76, 84, + 128, 66, 69, 76, 212, 66, 69, 76, 79, 215, 66, 69, 76, 76, 72, 79, 208, + 66, 69, 76, 76, 128, 66, 69, 76, 204, 66, 69, 76, 71, 84, 72, 79, 210, + 66, 69, 73, 84, 72, 128, 66, 69, 72, 73, 78, 196, 66, 69, 72, 69, 72, + 128, 66, 69, 72, 69, 200, 66, 69, 72, 128, 66, 69, 200, 66, 69, 71, 73, + 78, 78, 73, 78, 71, 128, 66, 69, 71, 73, 78, 78, 69, 82, 128, 66, 69, 71, + 73, 206, 66, 69, 70, 79, 82, 197, 66, 69, 69, 84, 76, 69, 128, 66, 69, + 69, 84, 65, 128, 66, 69, 69, 210, 66, 69, 69, 72, 73, 86, 69, 128, 66, + 69, 69, 72, 128, 66, 69, 69, 200, 66, 69, 67, 65, 85, 83, 69, 128, 66, + 69, 65, 86, 69, 210, 66, 69, 65, 84, 73, 78, 199, 66, 69, 65, 84, 128, + 66, 69, 65, 210, 66, 69, 65, 78, 128, 66, 69, 65, 77, 69, 196, 66, 69, + 65, 67, 200, 66, 67, 65, 68, 128, 66, 67, 65, 196, 66, 66, 89, 88, 128, + 66, 66, 89, 84, 128, 66, 66, 89, 80, 128, 66, 66, 89, 128, 66, 66, 85, + 88, 128, 66, 66, 85, 84, 128, 66, 66, 85, 82, 88, 128, 66, 66, 85, 82, + 128, 66, 66, 85, 80, 128, 66, 66, 85, 79, 88, 128, 66, 66, 85, 79, 80, + 128, 66, 66, 85, 79, 128, 66, 66, 85, 128, 66, 66, 79, 88, 128, 66, 66, + 79, 84, 128, 66, 66, 79, 80, 128, 66, 66, 79, 128, 66, 66, 73, 88, 128, + 66, 66, 73, 80, 128, 66, 66, 73, 69, 88, 128, 66, 66, 73, 69, 84, 128, + 66, 66, 73, 69, 80, 128, 66, 66, 73, 69, 128, 66, 66, 73, 128, 66, 66, + 69, 88, 128, 66, 66, 69, 80, 128, 66, 66, 69, 69, 128, 66, 66, 69, 128, + 66, 66, 65, 88, 128, 66, 66, 65, 84, 128, 66, 66, 65, 80, 128, 66, 66, + 65, 65, 128, 66, 66, 65, 128, 66, 65, 89, 65, 78, 78, 65, 128, 66, 65, + 85, 128, 66, 65, 84, 84, 69, 82, 89, 128, 66, 65, 84, 72, 84, 85, 66, + 128, 66, 65, 84, 72, 65, 77, 65, 83, 65, 84, 128, 66, 65, 84, 72, 128, + 66, 65, 84, 200, 66, 65, 84, 65, 203, 66, 65, 83, 83, 65, 128, 66, 65, + 83, 83, 193, 66, 65, 83, 75, 69, 84, 66, 65, 76, 204, 66, 65, 83, 72, 75, + 73, 210, 66, 65, 83, 72, 128, 66, 65, 83, 69, 76, 73, 78, 197, 66, 65, + 83, 69, 66, 65, 76, 76, 128, 66, 65, 83, 69, 128, 66, 65, 83, 197, 66, + 65, 82, 83, 128, 66, 65, 82, 82, 73, 69, 82, 128, 66, 65, 82, 82, 69, 75, + 72, 128, 66, 65, 82, 82, 69, 69, 128, 66, 65, 82, 82, 69, 197, 66, 65, + 82, 76, 73, 78, 69, 128, 66, 65, 82, 76, 69, 89, 128, 66, 65, 82, 73, 89, + 79, 79, 83, 65, 78, 128, 66, 65, 82, 66, 69, 210, 66, 65, 82, 65, 50, + 128, 66, 65, 210, 66, 65, 78, 84, 79, 67, 128, 66, 65, 78, 75, 78, 79, + 84, 197, 66, 65, 78, 75, 128, 66, 65, 78, 203, 66, 65, 78, 68, 128, 66, + 65, 78, 65, 78, 65, 128, 66, 65, 78, 50, 128, 66, 65, 78, 178, 66, 65, + 77, 66, 79, 79, 83, 128, 66, 65, 77, 66, 79, 79, 128, 66, 65, 76, 85, 68, + 65, 128, 66, 65, 76, 76, 80, 79, 73, 78, 212, 66, 65, 76, 76, 79, 84, + 128, 66, 65, 76, 76, 79, 212, 66, 65, 76, 76, 79, 79, 78, 45, 83, 80, 79, + 75, 69, 196, 66, 65, 76, 76, 79, 79, 78, 128, 66, 65, 76, 65, 71, 128, + 66, 65, 76, 128, 66, 65, 204, 66, 65, 73, 82, 75, 65, 78, 128, 66, 65, + 73, 77, 65, 73, 128, 66, 65, 72, 84, 128, 66, 65, 72, 73, 82, 71, 79, 77, + 85, 75, 72, 65, 128, 66, 65, 72, 65, 82, 50, 128, 66, 65, 72, 128, 66, + 65, 71, 83, 128, 66, 65, 71, 71, 65, 71, 197, 66, 65, 71, 65, 128, 66, + 65, 71, 51, 128, 66, 65, 199, 66, 65, 68, 71, 69, 82, 128, 66, 65, 68, + 71, 69, 128, 66, 65, 68, 128, 66, 65, 67, 84, 82, 73, 65, 206, 66, 65, + 67, 75, 87, 65, 82, 68, 128, 66, 65, 67, 75, 83, 80, 65, 67, 69, 128, 66, + 65, 67, 75, 83, 76, 65, 83, 72, 128, 66, 65, 67, 75, 83, 76, 65, 83, 200, + 66, 65, 67, 75, 83, 76, 65, 78, 84, 69, 196, 66, 65, 67, 75, 72, 65, 78, + 196, 66, 65, 67, 75, 45, 84, 73, 76, 84, 69, 196, 66, 65, 67, 75, 128, + 66, 65, 67, 203, 66, 65, 66, 89, 128, 66, 65, 66, 217, 66, 65, 65, 82, + 69, 82, 85, 128, 66, 65, 45, 50, 128, 66, 51, 48, 53, 128, 66, 50, 53, + 57, 128, 66, 50, 53, 56, 128, 66, 50, 53, 55, 128, 66, 50, 53, 54, 128, + 66, 50, 53, 53, 128, 66, 50, 53, 180, 66, 50, 53, 51, 128, 66, 50, 53, + 50, 128, 66, 50, 53, 49, 128, 66, 50, 53, 48, 128, 66, 50, 52, 57, 128, + 66, 50, 52, 56, 128, 66, 50, 52, 183, 66, 50, 52, 54, 128, 66, 50, 52, + 53, 128, 66, 50, 52, 179, 66, 50, 52, 178, 66, 50, 52, 177, 66, 50, 52, + 176, 66, 50, 51, 54, 128, 66, 50, 51, 52, 128, 66, 50, 51, 179, 66, 50, + 51, 50, 128, 66, 50, 51, 177, 66, 50, 51, 176, 66, 50, 50, 57, 128, 66, + 50, 50, 56, 128, 66, 50, 50, 55, 128, 66, 50, 50, 54, 128, 66, 50, 50, + 181, 66, 50, 50, 50, 128, 66, 50, 50, 49, 128, 66, 50, 50, 176, 66, 50, + 49, 57, 128, 66, 50, 49, 56, 128, 66, 50, 49, 55, 128, 66, 50, 49, 54, + 128, 66, 50, 49, 53, 128, 66, 50, 49, 52, 128, 66, 50, 49, 51, 128, 66, + 50, 49, 50, 128, 66, 50, 49, 49, 128, 66, 50, 49, 48, 128, 66, 50, 48, + 57, 128, 66, 50, 48, 56, 128, 66, 50, 48, 55, 128, 66, 50, 48, 54, 128, + 66, 50, 48, 53, 128, 66, 50, 48, 52, 128, 66, 50, 48, 51, 128, 66, 50, + 48, 50, 128, 66, 50, 48, 49, 128, 66, 50, 48, 48, 128, 66, 49, 57, 177, + 66, 49, 57, 48, 128, 66, 49, 56, 57, 128, 66, 49, 56, 53, 128, 66, 49, + 56, 52, 128, 66, 49, 56, 51, 128, 66, 49, 56, 50, 128, 66, 49, 56, 49, + 128, 66, 49, 56, 48, 128, 66, 49, 55, 57, 128, 66, 49, 55, 56, 128, 66, + 49, 55, 55, 128, 66, 49, 55, 182, 66, 49, 55, 52, 128, 66, 49, 55, 179, + 66, 49, 55, 50, 128, 66, 49, 55, 49, 128, 66, 49, 55, 48, 128, 66, 49, + 54, 57, 128, 66, 49, 54, 56, 128, 66, 49, 54, 55, 128, 66, 49, 54, 54, + 128, 66, 49, 54, 53, 128, 66, 49, 54, 52, 128, 66, 49, 54, 179, 66, 49, + 54, 178, 66, 49, 54, 49, 128, 66, 49, 54, 48, 128, 66, 49, 53, 185, 66, + 49, 53, 56, 128, 66, 49, 53, 55, 128, 66, 49, 53, 182, 66, 49, 53, 53, + 128, 66, 49, 53, 52, 128, 66, 49, 53, 51, 128, 66, 49, 53, 50, 128, 66, + 49, 53, 177, 66, 49, 53, 48, 128, 66, 49, 52, 54, 128, 66, 49, 52, 181, + 66, 49, 52, 50, 128, 66, 49, 52, 177, 66, 49, 52, 176, 66, 49, 51, 181, + 66, 49, 51, 179, 66, 49, 51, 50, 128, 66, 49, 51, 177, 66, 49, 51, 176, + 66, 49, 50, 184, 66, 49, 50, 183, 66, 49, 50, 181, 66, 49, 50, 179, 66, + 49, 50, 178, 66, 49, 50, 177, 66, 49, 50, 176, 66, 49, 48, 57, 205, 66, + 49, 48, 57, 198, 66, 49, 48, 56, 205, 66, 49, 48, 56, 198, 66, 49, 48, + 55, 205, 66, 49, 48, 55, 198, 66, 49, 48, 54, 205, 66, 49, 48, 54, 198, + 66, 49, 48, 53, 205, 66, 49, 48, 53, 198, 66, 49, 48, 181, 66, 49, 48, + 180, 66, 49, 48, 178, 66, 49, 48, 176, 66, 48, 57, 177, 66, 48, 57, 176, + 66, 48, 56, 57, 128, 66, 48, 56, 183, 66, 48, 56, 54, 128, 66, 48, 56, + 181, 66, 48, 56, 51, 128, 66, 48, 56, 50, 128, 66, 48, 56, 177, 66, 48, + 56, 176, 66, 48, 55, 57, 128, 66, 48, 55, 184, 66, 48, 55, 183, 66, 48, + 55, 182, 66, 48, 55, 181, 66, 48, 55, 180, 66, 48, 55, 179, 66, 48, 55, + 178, 66, 48, 55, 177, 66, 48, 55, 176, 66, 48, 54, 185, 66, 48, 54, 184, + 66, 48, 54, 183, 66, 48, 54, 182, 66, 48, 54, 181, 66, 48, 54, 52, 128, + 66, 48, 54, 51, 128, 66, 48, 54, 178, 66, 48, 54, 177, 66, 48, 54, 176, + 66, 48, 53, 185, 66, 48, 53, 184, 66, 48, 53, 183, 66, 48, 53, 54, 128, + 66, 48, 53, 181, 66, 48, 53, 180, 66, 48, 53, 179, 66, 48, 53, 178, 66, + 48, 53, 177, 66, 48, 53, 176, 66, 48, 52, 57, 128, 66, 48, 52, 184, 66, + 48, 52, 55, 128, 66, 48, 52, 182, 66, 48, 52, 181, 66, 48, 52, 180, 66, + 48, 52, 179, 66, 48, 52, 178, 66, 48, 52, 177, 66, 48, 52, 176, 66, 48, + 51, 185, 66, 48, 51, 184, 66, 48, 51, 183, 66, 48, 51, 182, 66, 48, 51, + 52, 128, 66, 48, 51, 179, 66, 48, 51, 178, 66, 48, 51, 177, 66, 48, 51, + 176, 66, 48, 50, 185, 66, 48, 50, 184, 66, 48, 50, 183, 66, 48, 50, 182, + 66, 48, 50, 181, 66, 48, 50, 180, 66, 48, 50, 179, 66, 48, 50, 50, 128, + 66, 48, 50, 177, 66, 48, 50, 176, 66, 48, 49, 57, 128, 66, 48, 49, 56, + 128, 66, 48, 49, 183, 66, 48, 49, 182, 66, 48, 49, 181, 66, 48, 49, 180, + 66, 48, 49, 179, 66, 48, 49, 178, 66, 48, 49, 177, 66, 48, 49, 176, 66, + 48, 48, 57, 128, 66, 48, 48, 185, 66, 48, 48, 56, 128, 66, 48, 48, 184, + 66, 48, 48, 55, 128, 66, 48, 48, 183, 66, 48, 48, 54, 128, 66, 48, 48, + 182, 66, 48, 48, 53, 65, 128, 66, 48, 48, 53, 128, 66, 48, 48, 181, 66, + 48, 48, 52, 128, 66, 48, 48, 180, 66, 48, 48, 51, 128, 66, 48, 48, 179, + 66, 48, 48, 50, 128, 66, 48, 48, 178, 66, 48, 48, 49, 128, 66, 48, 48, + 177, 65, 90, 85, 128, 65, 89, 69, 210, 65, 89, 66, 128, 65, 89, 65, 72, + 128, 65, 88, 69, 128, 65, 87, 69, 128, 65, 86, 69, 83, 84, 65, 206, 65, + 86, 69, 82, 65, 71, 197, 65, 86, 65, 75, 82, 65, 72, 65, 83, 65, 78, 89, + 65, 128, 65, 86, 65, 71, 82, 65, 72, 65, 128, 65, 85, 89, 65, 78, 78, 65, + 128, 65, 85, 84, 85, 77, 78, 128, 65, 85, 84, 79, 77, 79, 66, 73, 76, 69, + 128, 65, 85, 84, 79, 77, 65, 84, 69, 196, 65, 85, 83, 84, 82, 65, 204, + 65, 85, 82, 73, 80, 73, 71, 77, 69, 78, 84, 128, 65, 85, 82, 65, 77, 65, + 90, 68, 65, 65, 72, 65, 128, 65, 85, 82, 65, 77, 65, 90, 68, 65, 65, 45, + 50, 128, 65, 85, 82, 65, 77, 65, 90, 68, 65, 65, 128, 65, 85, 78, 78, + 128, 65, 85, 71, 85, 83, 84, 128, 65, 85, 71, 77, 69, 78, 84, 65, 84, 73, + 79, 206, 65, 85, 69, 128, 65, 85, 66, 69, 82, 71, 73, 78, 69, 128, 65, + 84, 84, 73, 195, 65, 84, 84, 72, 65, 67, 65, 78, 128, 65, 84, 84, 69, 78, + 84, 73, 79, 78, 128, 65, 84, 84, 65, 203, 65, 84, 84, 65, 67, 72, 69, + 196, 65, 84, 79, 205, 65, 84, 78, 65, 200, 65, 84, 77, 65, 65, 85, 128, + 65, 84, 73, 89, 65, 128, 65, 84, 72, 76, 69, 84, 73, 195, 65, 84, 72, 65, + 82, 86, 65, 86, 69, 68, 73, 195, 65, 84, 72, 65, 80, 65, 83, 67, 65, 206, + 65, 83, 90, 128, 65, 83, 89, 85, 82, 193, 65, 83, 89, 77, 80, 84, 79, 84, + 73, 67, 65, 76, 76, 217, 65, 83, 84, 82, 79, 78, 79, 77, 73, 67, 65, 204, + 65, 83, 84, 82, 79, 76, 79, 71, 73, 67, 65, 204, 65, 83, 84, 79, 78, 73, + 83, 72, 69, 196, 65, 83, 84, 69, 82, 73, 83, 77, 128, 65, 83, 84, 69, 82, + 73, 83, 75, 211, 65, 83, 84, 69, 82, 73, 83, 75, 128, 65, 83, 84, 69, 82, + 73, 83, 203, 65, 83, 84, 69, 82, 73, 83, 67, 85, 83, 128, 65, 83, 83, 89, + 82, 73, 65, 206, 65, 83, 83, 69, 82, 84, 73, 79, 78, 128, 65, 83, 80, 73, + 82, 65, 84, 73, 79, 78, 128, 65, 83, 80, 73, 82, 65, 84, 69, 196, 65, 83, + 80, 69, 82, 128, 65, 83, 73, 65, 45, 65, 85, 83, 84, 82, 65, 76, 73, 65, + 128, 65, 83, 72, 71, 65, 66, 128, 65, 83, 72, 69, 83, 128, 65, 83, 72, + 57, 128, 65, 83, 72, 51, 128, 65, 83, 72, 178, 65, 83, 67, 69, 78, 84, 128, 65, 83, 67, 69, 78, 68, 73, 78, 199, 65, 83, 65, 76, 50, 128, 65, 82, 85, 72, 85, 65, 128, 65, 82, 84, 73, 83, 212, 65, 82, 84, 73, 67, 85, 76, 65, 84, 69, 196, 65, 82, 84, 65, 66, 197, 65, 82, 83, 69, 79, 83, 128, 65, 82, 83, 69, 79, 211, 65, 82, 83, 69, 78, 73, 67, 128, 65, 82, 82, 79, 87, 83, 128, 65, 82, 82, 79, 87, 211, 65, 82, 82, 79, 87, 72, 69, 65, 68, 128, 65, 82, 82, 79, 87, 72, 69, 65, 196, 65, 82, 82, 79, 87, 45, - 84, 65, 73, 76, 128, 65, 82, 82, 73, 86, 69, 128, 65, 82, 82, 65, 89, - 128, 65, 82, 80, 69, 71, 71, 73, 65, 84, 207, 65, 82, 79, 85, 83, 73, 78, - 199, 65, 82, 79, 85, 82, 193, 65, 82, 79, 85, 78, 68, 45, 80, 82, 79, 70, - 73, 76, 69, 128, 65, 82, 79, 85, 78, 196, 65, 82, 77, 89, 128, 65, 82, - 77, 79, 85, 82, 128, 65, 82, 205, 65, 82, 76, 65, 85, 199, 65, 82, 75, - 84, 73, 75, 207, 65, 82, 75, 65, 66, 128, 65, 82, 75, 65, 65, 78, 85, - 128, 65, 82, 73, 83, 84, 69, 82, 65, 128, 65, 82, 73, 83, 84, 69, 82, - 193, 65, 82, 73, 69, 83, 128, 65, 82, 71, 79, 84, 69, 82, 73, 128, 65, - 82, 71, 79, 83, 89, 78, 84, 72, 69, 84, 79, 78, 128, 65, 82, 71, 73, 128, - 65, 82, 69, 80, 65, 128, 65, 82, 69, 65, 128, 65, 82, 68, 72, 65, 86, 73, - 83, 65, 82, 71, 65, 128, 65, 82, 67, 72, 65, 73, 79, 78, 128, 65, 82, 67, - 72, 65, 73, 79, 206, 65, 82, 67, 72, 65, 73, 195, 65, 82, 67, 200, 65, - 82, 67, 128, 65, 82, 195, 65, 82, 65, 77, 65, 73, 195, 65, 82, 65, 69, - 65, 69, 128, 65, 82, 65, 69, 65, 45, 85, 128, 65, 82, 65, 69, 65, 45, 73, - 128, 65, 82, 65, 69, 65, 45, 69, 79, 128, 65, 82, 65, 69, 65, 45, 69, - 128, 65, 82, 65, 69, 65, 45, 65, 128, 65, 82, 65, 68, 128, 65, 82, 65, - 196, 65, 82, 65, 66, 73, 67, 45, 73, 78, 68, 73, 195, 65, 82, 65, 66, 73, - 65, 206, 65, 82, 45, 82, 65, 72, 77, 65, 206, 65, 82, 45, 82, 65, 72, 69, - 69, 77, 128, 65, 81, 85, 65, 82, 73, 85, 83, 128, 65, 81, 85, 65, 70, 79, - 82, 84, 73, 83, 128, 65, 81, 85, 193, 65, 80, 85, 206, 65, 80, 82, 73, - 76, 128, 65, 80, 80, 82, 79, 88, 73, 77, 65, 84, 69, 76, 217, 65, 80, 80, - 82, 79, 88, 73, 77, 65, 84, 69, 128, 65, 80, 80, 82, 79, 65, 67, 72, 69, - 211, 65, 80, 80, 82, 79, 65, 67, 72, 128, 65, 80, 80, 76, 73, 67, 65, 84, - 73, 79, 78, 128, 65, 80, 80, 76, 73, 67, 65, 84, 73, 79, 206, 65, 80, 79, - 84, 72, 69, 83, 128, 65, 80, 79, 84, 72, 69, 77, 65, 128, 65, 80, 79, 83, - 84, 82, 79, 80, 72, 69, 128, 65, 80, 79, 83, 84, 82, 79, 70, 79, 83, 128, - 65, 80, 79, 83, 84, 82, 79, 70, 79, 211, 65, 80, 79, 83, 84, 82, 79, 70, - 79, 201, 65, 80, 79, 68, 69, 88, 73, 65, 128, 65, 80, 79, 68, 69, 82, 77, - 193, 65, 80, 76, 79, 85, 78, 128, 65, 80, 76, 201, 65, 80, 204, 65, 80, - 73, 78, 128, 65, 80, 69, 83, 207, 65, 80, 67, 128, 65, 80, 65, 82, 84, - 128, 65, 80, 65, 65, 84, 79, 128, 65, 78, 85, 83, 86, 65, 82, 65, 89, 65, - 128, 65, 78, 85, 83, 86, 65, 82, 65, 128, 65, 78, 85, 83, 86, 65, 82, - 193, 65, 78, 85, 68, 65, 84, 84, 65, 128, 65, 78, 85, 68, 65, 84, 84, - 193, 65, 78, 84, 73, 82, 69, 83, 84, 82, 73, 67, 84, 73, 79, 78, 128, 65, - 78, 84, 73, 77, 79, 78, 89, 45, 50, 128, 65, 78, 84, 73, 77, 79, 78, 89, - 128, 65, 78, 84, 73, 77, 79, 78, 217, 65, 78, 84, 73, 77, 79, 78, 73, 65, - 84, 69, 128, 65, 78, 84, 73, 75, 69, 78, 79, 77, 65, 128, 65, 78, 84, 73, - 75, 69, 78, 79, 75, 89, 76, 73, 83, 77, 65, 128, 65, 78, 84, 73, 70, 79, - 78, 73, 65, 128, 65, 78, 84, 73, 67, 76, 79, 67, 75, 87, 73, 83, 69, 45, - 82, 79, 84, 65, 84, 69, 196, 65, 78, 84, 73, 67, 76, 79, 67, 75, 87, 73, - 83, 197, 65, 78, 84, 69, 78, 78, 65, 128, 65, 78, 84, 69, 78, 78, 193, - 65, 78, 84, 65, 82, 71, 79, 77, 85, 75, 72, 65, 128, 65, 78, 83, 85, 218, - 65, 78, 83, 72, 69, 128, 65, 78, 80, 69, 65, 128, 65, 78, 207, 65, 78, - 78, 85, 73, 84, 217, 65, 78, 78, 79, 84, 65, 84, 73, 79, 206, 65, 78, 78, - 65, 65, 85, 128, 65, 78, 75, 72, 128, 65, 78, 74, 73, 128, 65, 78, 72, - 85, 128, 65, 78, 71, 85, 76, 65, 82, 128, 65, 78, 71, 85, 73, 83, 72, 69, - 196, 65, 78, 71, 83, 84, 82, 79, 205, 65, 78, 71, 82, 217, 65, 78, 71, - 75, 72, 65, 78, 75, 72, 85, 128, 65, 78, 71, 69, 210, 65, 78, 71, 69, 76, - 128, 65, 78, 71, 69, 68, 128, 65, 78, 68, 65, 80, 128, 65, 78, 67, 79, - 82, 65, 128, 65, 78, 67, 72, 79, 82, 128, 65, 78, 65, 84, 82, 73, 67, 72, - 73, 83, 77, 65, 128, 65, 78, 65, 80, 128, 65, 77, 80, 83, 128, 65, 77, - 80, 69, 82, 83, 65, 78, 68, 128, 65, 77, 79, 85, 78, 212, 65, 77, 69, 82, - 73, 67, 65, 83, 128, 65, 77, 69, 82, 73, 67, 65, 206, 65, 77, 66, 85, 76, - 65, 78, 67, 69, 128, 65, 77, 66, 193, 65, 77, 65, 82, 128, 65, 77, 65, - 210, 65, 77, 65, 76, 71, 65, 77, 65, 84, 73, 79, 206, 65, 77, 65, 76, 71, - 65, 77, 128, 65, 76, 86, 69, 79, 76, 65, 210, 65, 76, 85, 77, 128, 65, - 76, 84, 69, 82, 78, 65, 84, 73, 86, 197, 65, 76, 84, 69, 82, 78, 65, 84, - 73, 79, 206, 65, 76, 84, 69, 82, 78, 65, 84, 197, 65, 76, 84, 65, 128, - 65, 76, 80, 72, 65, 128, 65, 76, 80, 72, 193, 65, 76, 80, 65, 80, 82, 65, - 78, 65, 128, 65, 76, 80, 65, 80, 82, 65, 65, 78, 193, 65, 76, 80, 65, - 128, 65, 76, 77, 79, 83, 212, 65, 76, 77, 128, 65, 76, 76, 79, 128, 65, - 76, 76, 73, 65, 78, 67, 69, 128, 65, 76, 76, 201, 65, 76, 76, 65, 200, - 65, 76, 75, 65, 76, 73, 45, 50, 128, 65, 76, 75, 65, 76, 73, 128, 65, 76, - 73, 71, 78, 69, 196, 65, 76, 73, 70, 85, 128, 65, 76, 73, 69, 78, 128, - 65, 76, 73, 69, 206, 65, 76, 71, 73, 218, 65, 76, 70, 65, 128, 65, 76, - 69, 85, 212, 65, 76, 69, 82, 84, 128, 65, 76, 69, 80, 72, 128, 65, 76, - 69, 77, 66, 73, 67, 128, 65, 76, 69, 70, 128, 65, 76, 65, 89, 72, 69, - 128, 65, 76, 65, 89, 72, 197, 65, 76, 65, 82, 205, 65, 76, 65, 80, 72, - 128, 65, 76, 45, 76, 65, 75, 85, 78, 65, 128, 65, 75, 84, 73, 69, 83, 69, - 76, 83, 75, 65, 66, 128, 65, 75, 83, 65, 128, 65, 75, 72, 77, 73, 77, 73, - 195, 65, 75, 66, 65, 210, 65, 75, 65, 82, 65, 128, 65, 75, 65, 82, 193, - 65, 73, 89, 65, 78, 78, 65, 128, 65, 73, 86, 73, 76, 73, 203, 65, 73, 84, - 79, 206, 65, 73, 82, 80, 76, 65, 78, 69, 128, 65, 73, 78, 213, 65, 73, - 78, 78, 128, 65, 73, 76, 77, 128, 65, 73, 75, 65, 82, 65, 128, 65, 73, - 72, 86, 85, 83, 128, 65, 72, 83, 68, 65, 128, 65, 72, 83, 65, 128, 65, - 72, 65, 78, 199, 65, 72, 65, 71, 71, 65, 210, 65, 72, 65, 68, 128, 65, - 71, 85, 78, 71, 128, 65, 71, 79, 71, 201, 65, 71, 71, 82, 65, 86, 65, 84, - 73, 79, 78, 128, 65, 71, 71, 82, 65, 86, 65, 84, 69, 196, 65, 71, 65, 73, - 78, 128, 65, 70, 84, 69, 210, 65, 70, 83, 65, 65, 81, 128, 65, 70, 82, - 73, 67, 65, 206, 65, 70, 79, 82, 69, 77, 69, 78, 84, 73, 79, 78, 69, 68, - 128, 65, 70, 71, 72, 65, 78, 201, 65, 70, 70, 82, 73, 67, 65, 84, 73, 79, - 206, 65, 69, 89, 65, 78, 78, 65, 128, 65, 69, 89, 128, 65, 69, 83, 67, + 84, 65, 73, 76, 128, 65, 82, 82, 73, 86, 73, 78, 71, 128, 65, 82, 82, 73, + 86, 69, 128, 65, 82, 82, 65, 89, 128, 65, 82, 80, 69, 71, 71, 73, 65, 84, + 207, 65, 82, 79, 85, 83, 73, 78, 199, 65, 82, 79, 85, 82, 193, 65, 82, + 79, 85, 78, 68, 45, 80, 82, 79, 70, 73, 76, 69, 128, 65, 82, 79, 85, 78, + 196, 65, 82, 77, 89, 128, 65, 82, 77, 79, 85, 82, 128, 65, 82, 205, 65, + 82, 76, 65, 85, 199, 65, 82, 75, 84, 73, 75, 207, 65, 82, 75, 65, 66, + 128, 65, 82, 75, 65, 65, 78, 85, 128, 65, 82, 73, 83, 84, 69, 82, 65, + 128, 65, 82, 73, 83, 84, 69, 82, 193, 65, 82, 73, 69, 83, 128, 65, 82, + 71, 79, 84, 69, 82, 73, 128, 65, 82, 71, 79, 83, 89, 78, 84, 72, 69, 84, + 79, 78, 128, 65, 82, 71, 73, 128, 65, 82, 69, 80, 65, 128, 65, 82, 69, + 65, 128, 65, 82, 68, 72, 65, 86, 73, 83, 65, 82, 71, 65, 128, 65, 82, 68, + 72, 65, 67, 65, 78, 68, 82, 65, 128, 65, 82, 67, 72, 65, 73, 79, 78, 128, + 65, 82, 67, 72, 65, 73, 79, 206, 65, 82, 67, 72, 65, 73, 195, 65, 82, 67, + 200, 65, 82, 67, 128, 65, 82, 195, 65, 82, 65, 77, 65, 73, 195, 65, 82, + 65, 69, 65, 69, 128, 65, 82, 65, 69, 65, 45, 85, 128, 65, 82, 65, 69, 65, + 45, 73, 128, 65, 82, 65, 69, 65, 45, 69, 79, 128, 65, 82, 65, 69, 65, 45, + 69, 128, 65, 82, 65, 69, 65, 45, 65, 128, 65, 82, 65, 68, 128, 65, 82, + 65, 196, 65, 82, 65, 66, 73, 67, 45, 73, 78, 68, 73, 195, 65, 82, 65, 66, + 73, 65, 206, 65, 82, 45, 82, 65, 72, 77, 65, 206, 65, 82, 45, 82, 65, 72, + 69, 69, 77, 128, 65, 81, 85, 65, 82, 73, 85, 83, 128, 65, 81, 85, 65, 70, + 79, 82, 84, 73, 83, 128, 65, 81, 85, 193, 65, 80, 85, 206, 65, 80, 82, + 73, 76, 128, 65, 80, 80, 82, 79, 88, 73, 77, 65, 84, 69, 76, 217, 65, 80, + 80, 82, 79, 88, 73, 77, 65, 84, 69, 128, 65, 80, 80, 82, 79, 65, 67, 72, + 69, 211, 65, 80, 80, 82, 79, 65, 67, 72, 128, 65, 80, 80, 76, 73, 67, 65, + 84, 73, 79, 78, 128, 65, 80, 80, 76, 73, 67, 65, 84, 73, 79, 206, 65, 80, + 79, 84, 72, 69, 83, 128, 65, 80, 79, 84, 72, 69, 77, 65, 128, 65, 80, 79, + 83, 84, 82, 79, 80, 72, 69, 128, 65, 80, 79, 83, 84, 82, 79, 70, 79, 83, + 128, 65, 80, 79, 83, 84, 82, 79, 70, 79, 211, 65, 80, 79, 83, 84, 82, 79, + 70, 79, 201, 65, 80, 79, 68, 69, 88, 73, 65, 128, 65, 80, 79, 68, 69, 82, + 77, 193, 65, 80, 76, 79, 85, 78, 128, 65, 80, 76, 201, 65, 80, 204, 65, + 80, 73, 78, 128, 65, 80, 69, 83, 207, 65, 80, 67, 128, 65, 80, 65, 82, + 84, 128, 65, 80, 65, 65, 84, 79, 128, 65, 79, 85, 128, 65, 79, 82, 128, + 65, 78, 85, 83, 86, 65, 82, 65, 89, 65, 128, 65, 78, 85, 83, 86, 65, 82, + 65, 128, 65, 78, 85, 83, 86, 65, 82, 193, 65, 78, 85, 68, 65, 84, 84, 65, + 128, 65, 78, 85, 68, 65, 84, 84, 193, 65, 78, 84, 73, 82, 69, 83, 84, 82, + 73, 67, 84, 73, 79, 78, 128, 65, 78, 84, 73, 77, 79, 78, 89, 45, 50, 128, + 65, 78, 84, 73, 77, 79, 78, 89, 128, 65, 78, 84, 73, 77, 79, 78, 217, 65, + 78, 84, 73, 77, 79, 78, 73, 65, 84, 69, 128, 65, 78, 84, 73, 75, 69, 78, + 79, 77, 65, 128, 65, 78, 84, 73, 75, 69, 78, 79, 75, 89, 76, 73, 83, 77, + 65, 128, 65, 78, 84, 73, 70, 79, 78, 73, 65, 128, 65, 78, 84, 73, 67, 76, + 79, 67, 75, 87, 73, 83, 69, 45, 82, 79, 84, 65, 84, 69, 196, 65, 78, 84, + 73, 67, 76, 79, 67, 75, 87, 73, 83, 69, 128, 65, 78, 84, 73, 67, 76, 79, + 67, 75, 87, 73, 83, 197, 65, 78, 84, 69, 78, 78, 65, 128, 65, 78, 84, 69, + 78, 78, 193, 65, 78, 84, 65, 82, 71, 79, 77, 85, 75, 72, 65, 128, 65, 78, + 83, 85, 218, 65, 78, 83, 72, 69, 128, 65, 78, 80, 69, 65, 128, 65, 78, + 207, 65, 78, 78, 85, 73, 84, 217, 65, 78, 78, 79, 84, 65, 84, 73, 79, + 206, 65, 78, 78, 65, 65, 85, 128, 65, 78, 75, 72, 128, 65, 78, 74, 73, + 128, 65, 78, 72, 85, 128, 65, 78, 71, 85, 76, 65, 82, 128, 65, 78, 71, + 85, 73, 83, 72, 69, 196, 65, 78, 71, 83, 84, 82, 79, 205, 65, 78, 71, 82, + 217, 65, 78, 71, 75, 72, 65, 78, 75, 72, 85, 128, 65, 78, 71, 69, 210, + 65, 78, 71, 69, 76, 128, 65, 78, 71, 69, 68, 128, 65, 78, 68, 65, 80, + 128, 65, 78, 67, 79, 82, 65, 128, 65, 78, 67, 72, 79, 82, 128, 65, 78, + 65, 84, 82, 73, 67, 72, 73, 83, 77, 65, 128, 65, 78, 65, 80, 128, 65, 77, + 80, 83, 128, 65, 77, 80, 69, 82, 83, 65, 78, 68, 128, 65, 77, 80, 69, 82, + 83, 65, 78, 196, 65, 77, 79, 85, 78, 212, 65, 77, 69, 82, 73, 67, 65, 83, + 128, 65, 77, 69, 82, 73, 67, 65, 206, 65, 77, 66, 85, 76, 65, 78, 67, 69, + 128, 65, 77, 66, 193, 65, 77, 65, 82, 128, 65, 77, 65, 210, 65, 77, 65, + 76, 71, 65, 77, 65, 84, 73, 79, 206, 65, 77, 65, 76, 71, 65, 77, 128, 65, + 76, 86, 69, 79, 76, 65, 210, 65, 76, 85, 77, 128, 65, 76, 84, 69, 82, 78, + 65, 84, 73, 86, 197, 65, 76, 84, 69, 82, 78, 65, 84, 73, 79, 206, 65, 76, + 84, 69, 82, 78, 65, 84, 197, 65, 76, 84, 65, 128, 65, 76, 80, 72, 65, + 128, 65, 76, 80, 72, 193, 65, 76, 80, 65, 80, 82, 65, 78, 65, 128, 65, + 76, 80, 65, 80, 82, 65, 65, 78, 193, 65, 76, 80, 65, 128, 65, 76, 77, 79, + 83, 212, 65, 76, 77, 128, 65, 76, 76, 79, 128, 65, 76, 76, 73, 65, 78, + 67, 69, 128, 65, 76, 76, 201, 65, 76, 76, 65, 200, 65, 76, 75, 65, 76, + 73, 45, 50, 128, 65, 76, 75, 65, 76, 73, 128, 65, 76, 73, 71, 78, 69, + 196, 65, 76, 73, 70, 85, 128, 65, 76, 73, 69, 78, 128, 65, 76, 73, 69, + 206, 65, 76, 71, 73, 218, 65, 76, 70, 65, 128, 65, 76, 69, 85, 212, 65, + 76, 69, 82, 84, 128, 65, 76, 69, 80, 72, 128, 65, 76, 69, 77, 66, 73, 67, + 128, 65, 76, 69, 70, 128, 65, 76, 66, 65, 78, 73, 65, 206, 65, 76, 65, + 89, 72, 69, 128, 65, 76, 65, 89, 72, 197, 65, 76, 65, 82, 205, 65, 76, + 65, 80, 72, 128, 65, 76, 45, 76, 65, 75, 85, 78, 65, 128, 65, 75, 84, 73, + 69, 83, 69, 76, 83, 75, 65, 66, 128, 65, 75, 83, 65, 128, 65, 75, 72, 77, + 73, 77, 73, 195, 65, 75, 66, 65, 210, 65, 75, 65, 82, 65, 128, 65, 75, + 65, 82, 193, 65, 73, 89, 65, 78, 78, 65, 128, 65, 73, 86, 73, 76, 73, + 203, 65, 73, 84, 79, 206, 65, 73, 82, 80, 76, 65, 78, 69, 128, 65, 73, + 82, 80, 76, 65, 78, 197, 65, 73, 78, 213, 65, 73, 78, 78, 128, 65, 73, + 76, 77, 128, 65, 73, 75, 65, 82, 65, 128, 65, 73, 72, 86, 85, 83, 128, + 65, 72, 83, 68, 65, 128, 65, 72, 83, 65, 128, 65, 72, 65, 78, 199, 65, + 72, 65, 71, 71, 65, 210, 65, 72, 65, 68, 128, 65, 71, 85, 78, 71, 128, + 65, 71, 79, 71, 201, 65, 71, 71, 82, 65, 86, 65, 84, 73, 79, 78, 128, 65, + 71, 71, 82, 65, 86, 65, 84, 69, 196, 65, 71, 65, 73, 78, 128, 65, 70, 84, + 69, 210, 65, 70, 83, 65, 65, 81, 128, 65, 70, 82, 73, 67, 65, 206, 65, + 70, 79, 82, 69, 77, 69, 78, 84, 73, 79, 78, 69, 68, 128, 65, 70, 71, 72, + 65, 78, 201, 65, 70, 70, 82, 73, 67, 65, 84, 73, 79, 206, 65, 70, 70, 73, + 216, 65, 69, 89, 65, 78, 78, 65, 128, 65, 69, 89, 128, 65, 69, 83, 67, 85, 76, 65, 80, 73, 85, 83, 128, 65, 69, 83, 67, 128, 65, 69, 83, 128, 65, 69, 82, 73, 65, 204, 65, 69, 82, 128, 65, 69, 76, 65, 45, 80, 73, 76, 76, 65, 128, 65, 69, 76, 128, 65, 69, 75, 128, 65, 69, 71, 69, 65, 206, 65, 69, 71, 128, 65, 69, 69, 89, 65, 78, 78, 65, 128, 65, 69, 69, 128, 65, 69, 68, 65, 45, 80, 73, 76, 76, 65, 128, 65, 69, 68, 128, 65, 69, 66, 128, 65, 68, 86, 65, 78, 84, 65, 71, 69, 128, 65, 68, 86, 65, 78, 67, 69, - 128, 65, 68, 69, 71, 128, 65, 68, 69, 199, 65, 68, 68, 82, 69, 83, 83, - 69, 196, 65, 68, 68, 82, 69, 83, 211, 65, 68, 68, 65, 75, 128, 65, 68, - 65, 203, 65, 67, 85, 84, 69, 45, 77, 65, 67, 82, 79, 78, 128, 65, 67, 85, - 84, 69, 45, 71, 82, 65, 86, 69, 45, 65, 67, 85, 84, 69, 128, 65, 67, 85, - 84, 197, 65, 67, 84, 85, 65, 76, 76, 217, 65, 67, 84, 73, 86, 65, 84, - 197, 65, 67, 82, 79, 80, 72, 79, 78, 73, 195, 65, 67, 75, 78, 79, 87, 76, - 69, 68, 71, 69, 128, 65, 67, 67, 85, 77, 85, 76, 65, 84, 73, 79, 78, 128, - 65, 67, 67, 79, 85, 78, 212, 65, 67, 67, 69, 80, 84, 128, 65, 67, 67, 69, - 78, 84, 45, 83, 84, 65, 67, 67, 65, 84, 79, 128, 65, 67, 67, 69, 78, 84, - 128, 65, 67, 67, 69, 78, 212, 65, 67, 65, 68, 69, 77, 217, 65, 66, 89, - 83, 77, 65, 204, 65, 66, 85, 78, 68, 65, 78, 67, 69, 128, 65, 66, 75, 72, - 65, 83, 73, 65, 206, 65, 66, 66, 82, 69, 86, 73, 65, 84, 73, 79, 206, 65, - 66, 65, 70, 73, 76, 73, 128, 65, 66, 178, 65, 65, 89, 65, 78, 78, 65, - 128, 65, 65, 89, 128, 65, 65, 87, 128, 65, 65, 79, 128, 65, 65, 74, 128, - 65, 65, 66, 65, 65, 70, 73, 76, 73, 128, 65, 65, 48, 51, 50, 128, 65, 65, - 48, 51, 49, 128, 65, 65, 48, 51, 48, 128, 65, 65, 48, 50, 57, 128, 65, - 65, 48, 50, 56, 128, 65, 65, 48, 50, 55, 128, 65, 65, 48, 50, 54, 128, - 65, 65, 48, 50, 53, 128, 65, 65, 48, 50, 52, 128, 65, 65, 48, 50, 51, - 128, 65, 65, 48, 50, 50, 128, 65, 65, 48, 50, 49, 128, 65, 65, 48, 50, - 48, 128, 65, 65, 48, 49, 57, 128, 65, 65, 48, 49, 56, 128, 65, 65, 48, - 49, 55, 128, 65, 65, 48, 49, 54, 128, 65, 65, 48, 49, 53, 128, 65, 65, - 48, 49, 52, 128, 65, 65, 48, 49, 51, 128, 65, 65, 48, 49, 50, 128, 65, - 65, 48, 49, 49, 128, 65, 65, 48, 49, 48, 128, 65, 65, 48, 48, 57, 128, - 65, 65, 48, 48, 56, 128, 65, 65, 48, 48, 55, 66, 128, 65, 65, 48, 48, 55, - 65, 128, 65, 65, 48, 48, 55, 128, 65, 65, 48, 48, 54, 128, 65, 65, 48, - 48, 53, 128, 65, 65, 48, 48, 52, 128, 65, 65, 48, 48, 51, 128, 65, 65, - 48, 48, 50, 128, 65, 65, 48, 48, 49, 128, 65, 48, 55, 48, 128, 65, 48, - 54, 57, 128, 65, 48, 54, 56, 128, 65, 48, 54, 55, 128, 65, 48, 54, 54, - 128, 65, 48, 54, 53, 128, 65, 48, 54, 52, 128, 65, 48, 54, 51, 128, 65, - 48, 54, 50, 128, 65, 48, 54, 49, 128, 65, 48, 54, 48, 128, 65, 48, 53, - 57, 128, 65, 48, 53, 56, 128, 65, 48, 53, 55, 128, 65, 48, 53, 54, 128, - 65, 48, 53, 53, 128, 65, 48, 53, 52, 128, 65, 48, 53, 51, 128, 65, 48, - 53, 50, 128, 65, 48, 53, 49, 128, 65, 48, 53, 48, 128, 65, 48, 52, 57, - 128, 65, 48, 52, 56, 128, 65, 48, 52, 55, 128, 65, 48, 52, 54, 128, 65, - 48, 52, 53, 65, 128, 65, 48, 52, 53, 128, 65, 48, 52, 52, 128, 65, 48, - 52, 51, 65, 128, 65, 48, 52, 51, 128, 65, 48, 52, 50, 65, 128, 65, 48, - 52, 50, 128, 65, 48, 52, 49, 128, 65, 48, 52, 48, 65, 128, 65, 48, 52, - 48, 128, 65, 48, 51, 57, 128, 65, 48, 51, 56, 128, 65, 48, 51, 55, 128, - 65, 48, 51, 54, 128, 65, 48, 51, 53, 128, 65, 48, 51, 52, 128, 65, 48, - 51, 51, 128, 65, 48, 51, 50, 65, 128, 65, 48, 49, 55, 65, 128, 65, 48, - 49, 52, 65, 128, 65, 48, 48, 54, 66, 128, 65, 48, 48, 54, 65, 128, 65, - 48, 48, 53, 65, 128, 65, 45, 69, 85, 128, 45, 85, 205, 45, 80, 72, 82, - 85, 128, 45, 75, 72, 89, 85, 196, 45, 75, 72, 89, 73, 76, 128, 45, 68, - 90, 85, 196, 45, 67, 72, 65, 210, 45, 67, 72, 65, 76, 128, + 128, 65, 68, 77, 73, 83, 83, 73, 79, 206, 65, 68, 69, 71, 128, 65, 68, + 69, 199, 65, 68, 68, 82, 69, 83, 83, 69, 196, 65, 68, 68, 82, 69, 83, + 211, 65, 68, 68, 65, 75, 128, 65, 68, 65, 203, 65, 67, 85, 84, 69, 45, + 77, 65, 67, 82, 79, 78, 128, 65, 67, 85, 84, 69, 45, 71, 82, 65, 86, 69, + 45, 65, 67, 85, 84, 69, 128, 65, 67, 85, 84, 197, 65, 67, 84, 85, 65, 76, + 76, 217, 65, 67, 84, 73, 86, 65, 84, 197, 65, 67, 82, 79, 80, 72, 79, 78, + 73, 195, 65, 67, 75, 78, 79, 87, 76, 69, 68, 71, 69, 128, 65, 67, 67, 85, + 77, 85, 76, 65, 84, 73, 79, 78, 128, 65, 67, 67, 79, 85, 78, 212, 65, 67, + 67, 79, 77, 77, 79, 68, 65, 84, 73, 79, 78, 128, 65, 67, 67, 69, 80, 84, + 128, 65, 67, 67, 69, 78, 84, 45, 83, 84, 65, 67, 67, 65, 84, 79, 128, 65, + 67, 67, 69, 78, 84, 128, 65, 67, 67, 69, 78, 212, 65, 67, 65, 68, 69, 77, + 217, 65, 66, 89, 83, 77, 65, 204, 65, 66, 85, 78, 68, 65, 78, 67, 69, + 128, 65, 66, 75, 72, 65, 83, 73, 65, 206, 65, 66, 66, 82, 69, 86, 73, 65, + 84, 73, 79, 206, 65, 66, 65, 70, 73, 76, 73, 128, 65, 66, 178, 65, 66, + 49, 57, 49, 128, 65, 66, 49, 56, 56, 128, 65, 66, 49, 56, 48, 128, 65, + 66, 49, 55, 49, 128, 65, 66, 49, 54, 52, 128, 65, 66, 49, 51, 49, 66, + 128, 65, 66, 49, 51, 49, 65, 128, 65, 66, 49, 50, 51, 128, 65, 66, 49, + 50, 50, 128, 65, 66, 49, 50, 48, 128, 65, 66, 49, 49, 56, 128, 65, 66, + 48, 56, 55, 128, 65, 66, 48, 56, 54, 128, 65, 66, 48, 56, 53, 128, 65, + 66, 48, 56, 50, 128, 65, 66, 48, 56, 49, 128, 65, 66, 48, 56, 48, 128, + 65, 66, 48, 55, 57, 128, 65, 66, 48, 55, 56, 128, 65, 66, 48, 55, 55, + 128, 65, 66, 48, 55, 54, 128, 65, 66, 48, 55, 52, 128, 65, 66, 48, 55, + 51, 128, 65, 66, 48, 55, 48, 128, 65, 66, 48, 54, 57, 128, 65, 66, 48, + 54, 55, 128, 65, 66, 48, 54, 54, 128, 65, 66, 48, 54, 53, 128, 65, 66, + 48, 54, 49, 128, 65, 66, 48, 54, 48, 128, 65, 66, 48, 53, 57, 128, 65, + 66, 48, 53, 56, 128, 65, 66, 48, 53, 55, 128, 65, 66, 48, 53, 54, 128, + 65, 66, 48, 53, 53, 128, 65, 66, 48, 53, 52, 128, 65, 66, 48, 53, 51, + 128, 65, 66, 48, 53, 49, 128, 65, 66, 48, 53, 48, 128, 65, 66, 48, 52, + 57, 128, 65, 66, 48, 52, 56, 128, 65, 66, 48, 52, 55, 128, 65, 66, 48, + 52, 54, 128, 65, 66, 48, 52, 53, 128, 65, 66, 48, 52, 52, 128, 65, 66, + 48, 52, 49, 128, 65, 66, 48, 52, 48, 128, 65, 66, 48, 51, 57, 128, 65, + 66, 48, 51, 56, 128, 65, 66, 48, 51, 55, 128, 65, 66, 48, 51, 52, 128, + 65, 66, 48, 51, 49, 128, 65, 66, 48, 51, 48, 128, 65, 66, 48, 50, 57, + 128, 65, 66, 48, 50, 56, 128, 65, 66, 48, 50, 55, 128, 65, 66, 48, 50, + 54, 128, 65, 66, 48, 50, 52, 128, 65, 66, 48, 50, 51, 77, 128, 65, 66, + 48, 50, 51, 128, 65, 66, 48, 50, 50, 77, 128, 65, 66, 48, 50, 50, 70, + 128, 65, 66, 48, 50, 50, 128, 65, 66, 48, 50, 49, 77, 128, 65, 66, 48, + 50, 49, 70, 128, 65, 66, 48, 50, 49, 128, 65, 66, 48, 50, 48, 128, 65, + 66, 48, 49, 55, 128, 65, 66, 48, 49, 54, 128, 65, 66, 48, 49, 51, 128, + 65, 66, 48, 49, 49, 128, 65, 66, 48, 49, 48, 128, 65, 66, 48, 48, 57, + 128, 65, 66, 48, 48, 56, 128, 65, 66, 48, 48, 55, 128, 65, 66, 48, 48, + 54, 128, 65, 66, 48, 48, 53, 128, 65, 66, 48, 48, 52, 128, 65, 66, 48, + 48, 51, 128, 65, 66, 48, 48, 50, 128, 65, 66, 48, 48, 49, 128, 65, 65, + 89, 73, 78, 128, 65, 65, 89, 65, 78, 78, 65, 128, 65, 65, 89, 128, 65, + 65, 87, 128, 65, 65, 79, 128, 65, 65, 74, 128, 65, 65, 66, 65, 65, 70, + 73, 76, 73, 128, 65, 65, 48, 51, 50, 128, 65, 65, 48, 51, 49, 128, 65, + 65, 48, 51, 48, 128, 65, 65, 48, 50, 57, 128, 65, 65, 48, 50, 56, 128, + 65, 65, 48, 50, 55, 128, 65, 65, 48, 50, 54, 128, 65, 65, 48, 50, 53, + 128, 65, 65, 48, 50, 52, 128, 65, 65, 48, 50, 51, 128, 65, 65, 48, 50, + 50, 128, 65, 65, 48, 50, 49, 128, 65, 65, 48, 50, 48, 128, 65, 65, 48, + 49, 57, 128, 65, 65, 48, 49, 56, 128, 65, 65, 48, 49, 55, 128, 65, 65, + 48, 49, 54, 128, 65, 65, 48, 49, 53, 128, 65, 65, 48, 49, 52, 128, 65, + 65, 48, 49, 51, 128, 65, 65, 48, 49, 50, 128, 65, 65, 48, 49, 49, 128, + 65, 65, 48, 49, 48, 128, 65, 65, 48, 48, 57, 128, 65, 65, 48, 48, 56, + 128, 65, 65, 48, 48, 55, 66, 128, 65, 65, 48, 48, 55, 65, 128, 65, 65, + 48, 48, 55, 128, 65, 65, 48, 48, 54, 128, 65, 65, 48, 48, 53, 128, 65, + 65, 48, 48, 52, 128, 65, 65, 48, 48, 51, 128, 65, 65, 48, 48, 50, 128, + 65, 65, 48, 48, 49, 128, 65, 56, 48, 55, 128, 65, 56, 48, 54, 128, 65, + 56, 48, 53, 128, 65, 56, 48, 52, 128, 65, 56, 48, 51, 128, 65, 56, 48, + 50, 128, 65, 56, 48, 49, 128, 65, 56, 48, 48, 128, 65, 55, 51, 178, 65, + 55, 50, 182, 65, 55, 49, 183, 65, 55, 49, 181, 65, 55, 49, 180, 65, 55, + 49, 179, 65, 55, 49, 178, 65, 55, 49, 177, 65, 55, 49, 176, 65, 55, 48, + 57, 45, 182, 65, 55, 48, 57, 45, 180, 65, 55, 48, 57, 45, 179, 65, 55, + 48, 57, 45, 178, 65, 55, 48, 185, 65, 55, 48, 184, 65, 55, 48, 183, 65, + 55, 48, 182, 65, 55, 48, 181, 65, 55, 48, 180, 65, 55, 48, 179, 65, 55, + 48, 178, 65, 55, 48, 177, 65, 54, 54, 52, 128, 65, 54, 54, 51, 128, 65, + 54, 54, 50, 128, 65, 54, 54, 49, 128, 65, 54, 54, 48, 128, 65, 54, 53, + 57, 128, 65, 54, 53, 56, 128, 65, 54, 53, 55, 128, 65, 54, 53, 54, 128, + 65, 54, 53, 53, 128, 65, 54, 53, 52, 128, 65, 54, 53, 51, 128, 65, 54, + 53, 50, 128, 65, 54, 53, 49, 128, 65, 54, 52, 57, 128, 65, 54, 52, 56, + 128, 65, 54, 52, 54, 128, 65, 54, 52, 53, 128, 65, 54, 52, 52, 128, 65, + 54, 52, 51, 128, 65, 54, 52, 50, 128, 65, 54, 52, 48, 128, 65, 54, 51, + 56, 128, 65, 54, 51, 55, 128, 65, 54, 51, 52, 128, 65, 54, 50, 57, 128, + 65, 54, 50, 56, 128, 65, 54, 50, 55, 128, 65, 54, 50, 54, 128, 65, 54, + 50, 52, 128, 65, 54, 50, 51, 128, 65, 54, 50, 50, 128, 65, 54, 50, 49, + 128, 65, 54, 50, 48, 128, 65, 54, 49, 57, 128, 65, 54, 49, 56, 128, 65, + 54, 49, 55, 128, 65, 54, 49, 54, 128, 65, 54, 49, 53, 128, 65, 54, 49, + 52, 128, 65, 54, 49, 51, 128, 65, 54, 49, 50, 128, 65, 54, 49, 49, 128, + 65, 54, 49, 48, 128, 65, 54, 48, 57, 128, 65, 54, 48, 56, 128, 65, 54, + 48, 54, 128, 65, 54, 48, 52, 128, 65, 54, 48, 51, 128, 65, 54, 48, 50, + 128, 65, 54, 48, 49, 128, 65, 54, 48, 48, 128, 65, 53, 57, 56, 128, 65, + 53, 57, 54, 128, 65, 53, 57, 53, 128, 65, 53, 57, 52, 128, 65, 53, 57, + 50, 128, 65, 53, 57, 49, 128, 65, 53, 56, 57, 128, 65, 53, 56, 56, 128, + 65, 53, 56, 55, 128, 65, 53, 56, 54, 128, 65, 53, 56, 53, 128, 65, 53, + 56, 52, 128, 65, 53, 56, 51, 128, 65, 53, 56, 50, 128, 65, 53, 56, 49, + 128, 65, 53, 56, 48, 128, 65, 53, 55, 57, 128, 65, 53, 55, 56, 128, 65, + 53, 55, 55, 128, 65, 53, 55, 54, 128, 65, 53, 55, 53, 128, 65, 53, 55, + 52, 128, 65, 53, 55, 51, 128, 65, 53, 55, 50, 128, 65, 53, 55, 49, 128, + 65, 53, 55, 48, 128, 65, 53, 54, 57, 128, 65, 53, 54, 56, 128, 65, 53, + 54, 54, 128, 65, 53, 54, 53, 128, 65, 53, 54, 52, 128, 65, 53, 54, 51, + 128, 65, 53, 53, 57, 128, 65, 53, 53, 55, 128, 65, 53, 53, 54, 128, 65, + 53, 53, 53, 128, 65, 53, 53, 52, 128, 65, 53, 53, 51, 128, 65, 53, 53, + 50, 128, 65, 53, 53, 49, 128, 65, 53, 53, 48, 128, 65, 53, 52, 57, 128, + 65, 53, 52, 56, 128, 65, 53, 52, 55, 128, 65, 53, 52, 53, 128, 65, 53, + 52, 50, 128, 65, 53, 52, 49, 128, 65, 53, 52, 48, 128, 65, 53, 51, 57, + 128, 65, 53, 51, 56, 128, 65, 53, 51, 55, 128, 65, 53, 51, 54, 128, 65, + 53, 51, 53, 128, 65, 53, 51, 52, 128, 65, 53, 51, 50, 128, 65, 53, 51, + 49, 128, 65, 53, 51, 48, 128, 65, 53, 50, 57, 128, 65, 53, 50, 56, 128, + 65, 53, 50, 55, 128, 65, 53, 50, 54, 128, 65, 53, 50, 53, 128, 65, 53, + 50, 52, 128, 65, 53, 50, 51, 128, 65, 53, 50, 49, 128, 65, 53, 50, 48, + 128, 65, 53, 49, 54, 128, 65, 53, 49, 53, 128, 65, 53, 49, 51, 128, 65, + 53, 49, 50, 128, 65, 53, 49, 49, 128, 65, 53, 49, 48, 128, 65, 53, 48, + 57, 128, 65, 53, 48, 56, 128, 65, 53, 48, 54, 128, 65, 53, 48, 53, 128, + 65, 53, 48, 52, 128, 65, 53, 48, 51, 128, 65, 53, 48, 50, 128, 65, 53, + 48, 49, 128, 65, 52, 49, 56, 45, 86, 65, 83, 128, 65, 52, 49, 55, 45, 86, + 65, 83, 128, 65, 52, 49, 54, 45, 86, 65, 83, 128, 65, 52, 49, 53, 45, 86, + 65, 83, 128, 65, 52, 49, 52, 45, 86, 65, 83, 128, 65, 52, 49, 51, 45, 86, + 65, 83, 128, 65, 52, 49, 50, 45, 86, 65, 83, 128, 65, 52, 49, 49, 45, 86, + 65, 83, 128, 65, 52, 49, 48, 45, 86, 65, 83, 128, 65, 52, 48, 57, 45, 86, + 65, 83, 128, 65, 52, 48, 56, 45, 86, 65, 83, 128, 65, 52, 48, 55, 45, 86, + 65, 83, 128, 65, 52, 48, 54, 45, 86, 65, 83, 128, 65, 52, 48, 53, 45, 86, + 65, 83, 128, 65, 52, 48, 52, 45, 86, 65, 83, 128, 65, 52, 48, 51, 45, 86, + 65, 83, 128, 65, 52, 48, 50, 45, 86, 65, 83, 128, 65, 52, 48, 49, 45, 86, + 65, 83, 128, 65, 52, 48, 48, 45, 86, 65, 83, 128, 65, 51, 55, 49, 128, + 65, 51, 55, 48, 128, 65, 51, 54, 57, 128, 65, 51, 54, 56, 128, 65, 51, + 54, 55, 128, 65, 51, 54, 54, 128, 65, 51, 54, 53, 128, 65, 51, 54, 52, + 128, 65, 51, 54, 51, 128, 65, 51, 54, 50, 128, 65, 51, 54, 49, 128, 65, + 51, 54, 48, 128, 65, 51, 53, 57, 128, 65, 51, 53, 56, 128, 65, 51, 53, + 55, 128, 65, 51, 53, 54, 128, 65, 51, 53, 53, 128, 65, 51, 53, 52, 128, + 65, 51, 53, 51, 128, 65, 51, 53, 50, 128, 65, 51, 53, 49, 128, 65, 51, + 53, 48, 128, 65, 51, 52, 57, 128, 65, 51, 52, 56, 128, 65, 51, 52, 55, + 128, 65, 51, 52, 54, 128, 65, 51, 52, 53, 128, 65, 51, 52, 52, 128, 65, + 51, 52, 51, 128, 65, 51, 52, 50, 128, 65, 51, 52, 49, 128, 65, 51, 52, + 48, 128, 65, 51, 51, 57, 128, 65, 51, 51, 56, 128, 65, 51, 51, 55, 128, + 65, 51, 51, 54, 128, 65, 51, 51, 53, 128, 65, 51, 51, 52, 128, 65, 51, + 51, 51, 128, 65, 51, 51, 50, 128, 65, 51, 51, 49, 128, 65, 51, 51, 48, + 128, 65, 51, 50, 57, 128, 65, 51, 50, 56, 128, 65, 51, 50, 55, 128, 65, + 51, 50, 54, 128, 65, 51, 50, 53, 128, 65, 51, 50, 52, 128, 65, 51, 50, + 51, 128, 65, 51, 50, 50, 128, 65, 51, 50, 49, 128, 65, 51, 50, 48, 128, + 65, 51, 49, 57, 128, 65, 51, 49, 56, 128, 65, 51, 49, 55, 128, 65, 51, + 49, 54, 128, 65, 51, 49, 53, 128, 65, 51, 49, 52, 128, 65, 51, 49, 51, + 67, 128, 65, 51, 49, 51, 66, 128, 65, 51, 49, 51, 65, 128, 65, 51, 49, + 50, 128, 65, 51, 49, 49, 128, 65, 51, 49, 48, 128, 65, 51, 48, 57, 67, + 128, 65, 51, 48, 57, 66, 128, 65, 51, 48, 57, 65, 128, 65, 51, 48, 56, + 128, 65, 51, 48, 55, 128, 65, 51, 48, 54, 128, 65, 51, 48, 53, 128, 65, + 51, 48, 52, 128, 65, 51, 48, 51, 128, 65, 51, 48, 50, 128, 65, 51, 48, + 49, 128, 65, 49, 51, 49, 67, 128, 65, 49, 50, 48, 66, 128, 65, 49, 48, + 48, 45, 49, 48, 50, 128, 65, 48, 55, 48, 128, 65, 48, 54, 57, 128, 65, + 48, 54, 56, 128, 65, 48, 54, 55, 128, 65, 48, 54, 54, 128, 65, 48, 54, + 53, 128, 65, 48, 54, 52, 128, 65, 48, 54, 51, 128, 65, 48, 54, 50, 128, + 65, 48, 54, 49, 128, 65, 48, 54, 48, 128, 65, 48, 53, 57, 128, 65, 48, + 53, 56, 128, 65, 48, 53, 55, 128, 65, 48, 53, 54, 128, 65, 48, 53, 53, + 128, 65, 48, 53, 52, 128, 65, 48, 53, 51, 128, 65, 48, 53, 50, 128, 65, + 48, 53, 49, 128, 65, 48, 53, 48, 128, 65, 48, 52, 57, 128, 65, 48, 52, + 56, 128, 65, 48, 52, 55, 128, 65, 48, 52, 54, 128, 65, 48, 52, 53, 65, + 128, 65, 48, 52, 53, 128, 65, 48, 52, 52, 128, 65, 48, 52, 51, 65, 128, + 65, 48, 52, 51, 128, 65, 48, 52, 50, 65, 128, 65, 48, 52, 50, 128, 65, + 48, 52, 49, 128, 65, 48, 52, 48, 65, 128, 65, 48, 52, 48, 128, 65, 48, + 51, 57, 128, 65, 48, 51, 56, 128, 65, 48, 51, 55, 128, 65, 48, 51, 54, + 128, 65, 48, 51, 53, 128, 65, 48, 51, 52, 128, 65, 48, 51, 51, 128, 65, + 48, 51, 50, 65, 128, 65, 48, 50, 56, 66, 128, 65, 48, 49, 55, 65, 128, + 65, 48, 49, 52, 65, 128, 65, 48, 48, 54, 66, 128, 65, 48, 48, 54, 65, + 128, 65, 48, 48, 53, 65, 128, 65, 45, 69, 85, 128, 45, 85, 205, 45, 80, + 72, 82, 85, 128, 45, 75, 72, 89, 85, 196, 45, 75, 72, 89, 73, 76, 128, + 45, 68, 90, 85, 196, 45, 67, 72, 65, 210, 45, 67, 72, 65, 76, 128, }; static unsigned int lexicon_offset[] = { - 0, 0, 6, 10, 18, 23, 27, 34, 39, 41, 47, 50, 62, 70, 80, 93, 102, 108, - 113, 121, 130, 135, 140, 143, 147, 153, 158, 163, 171, 178, 186, 191, - 194, 200, 208, 215, 225, 230, 237, 246, 249, 254, 257, 263, 267, 272, - 281, 288, 295, 301, 310, 315, 321, 327, 335, 144, 341, 349, 350, 358, - 361, 367, 369, 375, 382, 384, 391, 395, 403, 410, 412, 417, 422, 427, - 434, 436, 299, 442, 445, 447, 452, 457, 463, 470, 479, 489, 494, 498, - 505, 518, 522, 531, 538, 545, 548, 554, 558, 562, 572, 580, 588, 596, - 605, 613, 618, 619, 623, 631, 638, 648, 652, 663, 667, 670, 673, 678, - 348, 682, 691, 697, 703, 705, 708, 711, 714, 718, 722, 731, 739, 744, - 747, 751, 757, 764, 771, 776, 785, 794, 801, 805, 818, 827, 835, 841, - 557, 850, 860, 867, 873, 879, 886, 894, 898, 749, 906, 915, 503, 923, - 928, 934, 17, 943, 948, 951, 955, 959, 966, 969, 976, 980, 988, 992, - 1000, 1004, 1007, 1014, 1021, 192, 1024, 1029, 1039, 1048, 1055, 1060, - 1066, 1072, 1080, 1083, 1088, 1094, 1102, 1107, 1110, 1113, 111, 1118, - 1122, 1128, 1134, 1137, 1143, 1147, 1152, 1158, 1168, 1172, 1175, 1178, - 1187, 1191, 1194, 1199, 1204, 1210, 1215, 1220, 1225, 1229, 1234, 1240, - 1245, 1250, 1254, 1260, 1265, 1270, 1275, 1279, 1284, 1289, 1294, 1300, - 1306, 1312, 1317, 1321, 1326, 1331, 1336, 1340, 1345, 1350, 1355, 1360, - 1195, 1200, 1205, 1211, 1216, 1364, 1226, 1370, 1375, 1380, 1387, 1391, - 1400, 1230, 1404, 1235, 1241, 1246, 1408, 1413, 1418, 1422, 1426, 1432, - 1436, 1251, 1439, 1261, 1444, 1448, 1266, 1454, 1271, 1458, 1462, 1276, - 1466, 1471, 1475, 1478, 1482, 1280, 1285, 1487, 1290, 1493, 1499, 1505, - 1511, 1295, 1307, 1313, 1515, 1519, 1523, 1526, 1318, 1530, 1532, 1537, - 1542, 1548, 1553, 1558, 1562, 1567, 1572, 1577, 1582, 1588, 1593, 1598, - 1604, 1610, 1615, 1619, 1624, 1629, 1634, 1639, 1643, 1651, 1655, 1660, - 1665, 1670, 1675, 1679, 1682, 1687, 1692, 1697, 1702, 1708, 1713, 1717, - 1322, 1720, 1725, 1730, 1327, 1734, 1738, 1745, 1332, 1752, 1337, 1756, - 1758, 1763, 1769, 1341, 1774, 1783, 1346, 1788, 1794, 1351, 1799, 1804, - 1807, 1812, 1816, 1820, 1824, 1827, 1831, 1356, 1361, 1058, 1836, 1842, - 1848, 1854, 1860, 1866, 1872, 1878, 1884, 1889, 1895, 1901, 1907, 1913, - 1919, 1925, 1931, 1937, 1943, 1948, 1953, 1958, 1963, 1968, 1973, 1978, - 1983, 1988, 1993, 1999, 2004, 2010, 2015, 2021, 2027, 2032, 2038, 2044, - 2050, 2056, 2061, 2066, 2068, 2069, 2073, 2077, 2082, 2086, 2090, 2094, - 2099, 2103, 2106, 2111, 2115, 2120, 2124, 2128, 2133, 2137, 2140, 2144, - 2150, 2164, 2168, 2172, 2176, 2179, 2184, 2188, 2192, 2195, 2199, 2204, - 2209, 2214, 2219, 2223, 2227, 2231, 2236, 2240, 2245, 2249, 2254, 2260, - 2267, 2273, 2278, 2283, 2288, 2294, 2299, 2305, 2310, 2313, 1212, 2315, - 2322, 2330, 2340, 2349, 2363, 2367, 2371, 2384, 2392, 2396, 2401, 2405, - 2408, 2412, 2416, 2421, 2426, 2431, 2435, 2438, 2442, 2449, 2456, 2462, - 2467, 2472, 2478, 2484, 2489, 2492, 1760, 2494, 2500, 2504, 2509, 2513, - 2517, 1765, 1771, 2522, 2526, 2529, 2534, 2539, 2544, 2549, 2553, 2560, - 2565, 2568, 2575, 2581, 2585, 2589, 2593, 2598, 2605, 2610, 2615, 2622, - 2628, 2634, 2640, 2654, 2671, 2686, 2701, 2710, 2715, 2719, 2724, 2729, - 2733, 2745, 2752, 2758, 2263, 2764, 2771, 2777, 2781, 2784, 2791, 2797, - 2801, 2805, 2809, 2091, 2813, 2818, 2823, 2827, 2835, 2839, 2843, 2847, - 2851, 2856, 2861, 2866, 2870, 2875, 2880, 2884, 2889, 2893, 2896, 2900, - 2904, 2912, 2917, 2921, 2925, 2931, 2940, 2944, 2948, 2954, 2959, 2966, - 2970, 2980, 2984, 2988, 2993, 2997, 3002, 3008, 3013, 3017, 3021, 3025, - 2452, 3033, 3038, 3044, 3049, 3053, 3058, 3063, 3067, 3073, 3078, 2095, - 3084, 3090, 3095, 3100, 3105, 3110, 3115, 3120, 3125, 3130, 3135, 3141, - 3146, 1227, 92, 3152, 3156, 3160, 3164, 3169, 3173, 3177, 3181, 3185, - 3190, 3194, 3199, 3203, 3206, 3210, 3215, 3219, 3224, 3228, 3232, 3236, - 3241, 3245, 3248, 3261, 3265, 3269, 3273, 3277, 3281, 3284, 3288, 3292, - 3297, 3301, 3306, 3311, 3316, 3320, 3323, 3326, 3332, 3336, 3340, 3343, - 3347, 3351, 3354, 3360, 3365, 3370, 3376, 3381, 3386, 3392, 3398, 3403, - 3408, 3413, 1120, 547, 3418, 3421, 3426, 3430, 3433, 3437, 3442, 3447, - 3451, 3456, 3460, 3465, 3469, 3473, 3479, 3485, 3488, 3491, 3497, 3504, - 3511, 3517, 3524, 3529, 3533, 3540, 3547, 3552, 3556, 3566, 3570, 3574, - 3579, 3584, 3594, 2107, 3599, 3603, 3606, 3612, 3617, 3623, 3629, 3634, - 3641, 3645, 3649, 620, 671, 1388, 3653, 3660, 3667, 3674, 3681, 3687, - 3693, 3698, 3702, 3708, 3713, 3717, 2116, 3721, 3729, 600, 3735, 3746, - 3750, 3760, 2121, 3766, 3771, 3786, 3792, 3799, 3809, 3815, 3820, 3826, - 3832, 3835, 3839, 3844, 3851, 3856, 3860, 3864, 3868, 3872, 3877, 3883, - 3894, 3211, 3899, 3911, 3919, 3924, 1564, 3931, 3934, 3937, 3941, 3944, - 3950, 3954, 3968, 3972, 3975, 3979, 3985, 3991, 3996, 4000, 4004, 4010, - 4021, 4027, 4032, 4038, 4042, 4050, 4060, 4066, 4071, 4080, 4088, 4095, - 4099, 4105, 4114, 4123, 4127, 4132, 4137, 4141, 4149, 4153, 4158, 4162, - 2129, 1401, 4168, 4173, 4179, 4184, 4189, 4194, 4199, 4204, 4209, 4215, - 4220, 4226, 4231, 4236, 4241, 4247, 4252, 4257, 4262, 4267, 4273, 4278, - 4284, 4289, 4294, 4299, 4304, 4309, 4314, 4320, 4325, 4330, 319, 456, - 4335, 4341, 4345, 4349, 4354, 4358, 4362, 4365, 4369, 4373, 4377, 4381, - 4386, 4390, 4394, 4400, 4165, 4405, 4409, 4412, 4417, 4422, 4427, 4432, - 4437, 4442, 4447, 4452, 4457, 4462, 4466, 4471, 4476, 4481, 4486, 4491, - 4496, 4501, 4506, 4511, 4516, 4520, 4525, 4530, 4535, 4540, 4545, 4550, - 4555, 4560, 4565, 4570, 4574, 4579, 4584, 4589, 4594, 4599, 4604, 4609, - 4614, 4619, 4624, 4628, 4633, 4638, 4643, 4648, 4653, 4658, 4663, 4668, - 4673, 4678, 4682, 4687, 4692, 4697, 4702, 4707, 4712, 4717, 4722, 4727, - 4732, 4736, 4741, 4746, 4751, 4756, 4761, 4766, 4771, 4776, 4781, 4786, - 4790, 4795, 4800, 4805, 4810, 4816, 4822, 4828, 4834, 4840, 4846, 4852, - 4857, 4863, 4869, 4875, 4881, 4887, 4893, 4899, 4905, 4911, 4917, 4922, - 4928, 4934, 4940, 4946, 4952, 4958, 4964, 4970, 4976, 4982, 4987, 4993, - 4999, 5005, 5011, 5017, 5023, 5029, 5035, 5041, 5047, 5052, 5058, 5064, - 5070, 5076, 5082, 5088, 5094, 5100, 5106, 5112, 5117, 5123, 5129, 5135, - 5141, 5147, 5153, 5159, 5165, 5171, 5177, 5182, 5186, 5192, 5198, 5204, - 5210, 5216, 5222, 5228, 5234, 5240, 5246, 5251, 5257, 5263, 5269, 5275, - 5281, 5287, 5293, 5299, 5305, 5311, 5316, 5322, 5328, 5334, 5340, 5346, - 5352, 5358, 5364, 5370, 5376, 5381, 5387, 5393, 5399, 5405, 5411, 5417, - 5423, 5429, 5435, 5441, 5446, 5452, 5458, 5464, 5470, 5476, 5482, 5488, - 5494, 5500, 5506, 5511, 5517, 5523, 5529, 5535, 5541, 5547, 5553, 5559, - 5565, 5571, 5576, 5582, 5588, 5594, 5600, 5606, 5612, 5618, 5624, 5630, - 5636, 5641, 5647, 5653, 5659, 5665, 5671, 5677, 5683, 5689, 5695, 5701, - 5706, 5712, 5718, 5724, 5730, 5736, 5742, 5748, 5754, 5760, 5766, 5771, - 5777, 5783, 5789, 5795, 5801, 5807, 5813, 5819, 5825, 5831, 5836, 5840, - 5843, 5850, 5854, 5867, 5871, 5875, 5879, 5883, 5887, 5891, 5897, 5904, - 5912, 5916, 5924, 5933, 5939, 5951, 5956, 5959, 5963, 5973, 5981, 5989, - 5995, 5999, 6009, 6019, 6027, 6034, 6041, 6047, 6053, 6060, 6064, 6071, - 6081, 6091, 6099, 6106, 6111, 6115, 6123, 6127, 6132, 6139, 6147, 6152, - 6157, 6161, 6168, 6173, 6187, 6192, 6197, 6204, 6213, 6216, 6220, 6224, - 6228, 6231, 6236, 6241, 6250, 6256, 6262, 6268, 6272, 6283, 6293, 6308, - 6323, 6338, 6353, 6368, 6383, 6398, 6413, 6428, 6443, 6458, 6473, 6488, - 6503, 6518, 6533, 6548, 6563, 6578, 6593, 6608, 6623, 6638, 6653, 6668, - 6683, 6698, 6713, 6728, 6743, 6758, 6773, 6788, 6803, 6818, 6833, 6848, - 6863, 6878, 6893, 6908, 6923, 6938, 6953, 6968, 6983, 6998, 7013, 7028, - 7037, 7046, 7051, 7057, 7067, 7071, 7076, 7081, 7089, 7093, 7096, 7100, - 2975, 7103, 7108, 298, 425, 7114, 7122, 7126, 7130, 7133, 7137, 7143, - 7147, 7155, 7161, 7166, 7173, 7180, 7186, 7191, 7198, 7204, 7212, 7216, - 7221, 7233, 7244, 7251, 7255, 7259, 7265, 3233, 7269, 7275, 7280, 7285, - 7290, 7296, 7301, 7306, 7311, 7316, 7322, 7327, 7332, 7338, 7343, 7349, - 7354, 7360, 7365, 7371, 7376, 7381, 7386, 7391, 7396, 7402, 7407, 7412, - 7417, 7423, 7429, 7435, 7441, 7447, 7453, 7459, 7465, 7471, 7477, 7483, - 7489, 7494, 7499, 7504, 7509, 7514, 7519, 7524, 7529, 7535, 7541, 7546, - 7552, 7558, 7564, 7569, 7574, 7579, 7584, 7590, 7596, 7601, 7606, 7611, - 7616, 7621, 7627, 7632, 7638, 7644, 7650, 7656, 7662, 7668, 7674, 7680, - 7686, 2138, 7132, 7691, 7695, 7699, 7702, 7709, 7712, 7720, 7725, 7730, - 7721, 7735, 2165, 7739, 7745, 7751, 7756, 7761, 7768, 7776, 7781, 7785, - 7788, 7792, 7798, 7804, 7808, 2173, 560, 7811, 7815, 7820, 7826, 7831, - 7835, 7838, 7842, 7848, 7853, 7857, 7864, 7868, 7872, 7876, 945, 769, - 7879, 7887, 7894, 7901, 7907, 7914, 7922, 7929, 7936, 7941, 7953, 1247, - 1409, 1414, 7964, 1419, 7968, 7972, 7981, 7989, 7998, 8004, 8009, 8013, - 8019, 8024, 2706, 8031, 8035, 8044, 8053, 8062, 8071, 8076, 8081, 8093, - 8098, 8106, 2224, 8110, 8112, 8117, 8121, 8130, 8138, 1423, 133, 3461, - 3466, 8144, 8148, 8157, 8163, 8168, 8171, 8180, 2698, 8186, 8194, 8198, - 8202, 8206, 2237, 8210, 8215, 8222, 8228, 8234, 8237, 8239, 8242, 8250, - 8258, 8266, 8269, 8274, 2250, 8279, 7732, 8282, 8284, 8289, 8294, 8299, - 8304, 8309, 8314, 8319, 8324, 8329, 8334, 8340, 8345, 8350, 8355, 8361, - 8366, 8371, 8376, 8381, 8386, 8391, 8397, 8402, 8407, 8412, 8417, 8422, - 8427, 8432, 8437, 8442, 8447, 8452, 8457, 8462, 8467, 8472, 8477, 8482, - 8488, 8494, 8499, 8504, 8509, 8514, 8519, 2261, 2268, 2274, 8524, 8530, - 8538, 2300, 2306, 8546, 8550, 8555, 8559, 8563, 8567, 8572, 8576, 8581, - 8585, 8588, 8591, 8597, 8603, 8609, 8615, 8621, 8627, 8633, 8637, 8641, - 8645, 8649, 8653, 8658, 8665, 8676, 8684, 8694, 8700, 8707, 8712, 8716, - 8727, 8740, 8751, 8764, 8775, 8787, 8799, 8811, 8824, 8837, 8844, 8850, - 8864, 8871, 8877, 8881, 8886, 8890, 8897, 8905, 8909, 8915, 8919, 8925, - 8935, 8939, 8944, 8949, 8956, 8962, 8972, 7909, 8978, 8982, 8989, 8996, - 768, 9000, 9004, 9009, 9014, 9019, 9023, 9029, 9037, 9043, 9047, 9053, - 9063, 9067, 9073, 9078, 9082, 9088, 9094, 2161, 9099, 9101, 9106, 9114, - 9123, 9127, 9133, 9138, 9143, 9148, 9153, 9159, 9164, 9169, 4006, 9174, - 9179, 9183, 9189, 9194, 9200, 9205, 9210, 9216, 9221, 9128, 9227, 9231, - 9238, 9244, 9249, 9253, 6183, 9258, 9267, 9272, 9277, 8218, 8225, 9282, - 2853, 9286, 9291, 9296, 9139, 9300, 9305, 9144, 9149, 9310, 9317, 9324, - 9330, 9336, 9342, 9347, 9352, 9357, 9154, 9160, 9363, 9369, 9374, 9382, - 9165, 9387, 990, 9390, 9398, 9404, 9410, 9419, 9427, 9432, 9438, 9446, - 9453, 9468, 9485, 9504, 9513, 9521, 9536, 9547, 9557, 9567, 9575, 9581, - 9593, 9602, 9610, 9617, 9624, 9630, 9635, 9643, 9653, 9660, 9670, 9680, - 9690, 9698, 9705, 9714, 9724, 9738, 9753, 9762, 9770, 9775, 9779, 9788, - 9794, 9799, 9809, 9819, 9829, 9834, 9838, 9847, 9852, 9862, 9873, 9886, - 9894, 9907, 9919, 9927, 9932, 9936, 9942, 9947, 9955, 9963, 9970, 9975, - 9983, 9989, 9992, 9996, 10002, 10010, 10015, 10019, 10027, 10036, 10044, - 10050, 10054, 10061, 10072, 10076, 10079, 10085, 9170, 10090, 10096, - 10103, 10109, 10114, 10121, 10128, 10135, 10142, 10149, 10156, 10163, - 10170, 10175, 9481, 10180, 10186, 10193, 10200, 10205, 10212, 10221, - 10225, 10237, 8256, 10241, 10244, 10248, 10252, 10256, 10260, 10266, - 10272, 10277, 10283, 10288, 10293, 10299, 10304, 10309, 8952, 10314, - 10318, 10322, 10326, 10331, 10336, 10344, 10350, 10354, 10358, 10365, - 10370, 10378, 10383, 10387, 10390, 10396, 10403, 10407, 10410, 10415, - 10419, 4045, 10425, 10434, 36, 10442, 10448, 10453, 8967, 10458, 10463, - 10467, 10470, 10485, 10504, 10516, 10529, 10542, 10555, 10569, 10582, - 10597, 10604, 9175, 10610, 10624, 10629, 10635, 10640, 10648, 10653, - 8040, 10658, 10661, 10668, 10673, 10677, 2858, 998, 10683, 10687, 10693, - 10699, 10704, 10710, 10715, 9184, 10721, 10727, 10732, 10737, 10745, - 10751, 10764, 10772, 10779, 9190, 10785, 10793, 10801, 10808, 10821, - 10833, 10843, 10851, 10858, 10865, 10874, 10883, 10891, 10898, 10903, - 10909, 9195, 10914, 10920, 9201, 10925, 10928, 10935, 10941, 10954, 8669, - 10965, 10971, 10980, 10988, 10995, 11001, 11007, 11012, 11016, 11021, - 10477, 11027, 9206, 11034, 11039, 11046, 11052, 11058, 11063, 11071, - 11079, 11086, 11090, 11104, 11114, 11119, 11123, 11134, 11140, 11145, - 11150, 9211, 9217, 11154, 11157, 11162, 11174, 11181, 11186, 11190, - 11195, 11199, 11206, 11212, 9222, 9129, 11219, 2863, 8, 11226, 11231, - 11235, 11241, 11249, 11259, 11264, 11269, 11276, 11283, 11287, 11298, - 11308, 11317, 11329, 11334, 11338, 11346, 11360, 11364, 11367, 11375, - 11382, 11390, 11394, 11405, 11409, 11416, 11421, 11425, 11431, 11436, - 11440, 11446, 11451, 11462, 11466, 11469, 11475, 11480, 11486, 11492, - 11499, 11510, 11520, 11530, 11539, 11546, 11555, 9232, 9239, 9245, 9250, - 11561, 11567, 9254, 11573, 11576, 11583, 11588, 11603, 11619, 11634, - 11642, 11648, 11653, 838, 420, 11658, 11666, 11673, 11679, 11684, 11689, - 9259, 11691, 11695, 11700, 11704, 11714, 11719, 11723, 11732, 11736, - 11739, 9268, 11746, 11749, 11757, 11764, 11772, 11776, 11783, 11792, - 11795, 11799, 11803, 11809, 11813, 11817, 11821, 11827, 11837, 11841, - 11849, 11853, 11860, 11864, 11869, 11873, 11880, 11886, 11894, 11900, - 11905, 11915, 11920, 11925, 11929, 11937, 3905, 11945, 11950, 9273, - 11954, 11958, 11961, 11969, 11976, 11980, 5991, 11984, 11989, 11993, - 12004, 12014, 12019, 12025, 12029, 12032, 12040, 12045, 12050, 12057, - 12062, 9278, 12067, 12071, 12078, 1722, 6145, 12083, 12088, 12093, 12098, - 12104, 12109, 12115, 12120, 12125, 12130, 12135, 12140, 12145, 12150, - 12155, 12160, 12165, 12170, 12175, 12180, 12185, 12190, 12195, 12201, - 12206, 12211, 12216, 12221, 12226, 12232, 12237, 12242, 12248, 12253, - 12259, 12264, 12270, 12275, 12280, 12285, 12290, 12296, 12301, 12306, - 12311, 737, 139, 12319, 12323, 12328, 12333, 12337, 12341, 12345, 12350, - 12354, 12359, 12363, 12366, 12370, 12374, 12380, 12385, 12395, 12401, - 12409, 12413, 12417, 12424, 12432, 12441, 12452, 12459, 12466, 12470, - 12479, 12488, 12496, 12505, 12514, 12523, 12532, 12542, 12552, 12562, - 12572, 12582, 12591, 12601, 12611, 12621, 12631, 12641, 12651, 12661, - 12670, 12680, 12690, 12700, 12710, 12720, 12730, 12739, 12749, 12759, - 12769, 12779, 12789, 12799, 12809, 12819, 12829, 12838, 12848, 12858, - 12868, 12878, 12888, 12898, 12908, 12918, 12928, 12938, 12947, 1256, - 12953, 12956, 12960, 12965, 12972, 12978, 12983, 12987, 12992, 13001, - 13009, 13014, 13018, 13022, 13028, 13033, 13039, 9287, 13044, 13049, - 13058, 9292, 13063, 13066, 13072, 13080, 9297, 13087, 13091, 13095, - 13099, 13109, 13115, 13121, 13126, 13135, 13143, 13150, 13157, 13162, - 13169, 13174, 13178, 13181, 13192, 13202, 13211, 13219, 13230, 13242, - 13252, 13257, 13261, 13266, 13271, 13275, 13281, 13289, 13296, 13307, - 13312, 13322, 13326, 13329, 13336, 13346, 13355, 13362, 13366, 13373, - 13379, 13384, 13389, 13393, 13402, 13407, 13413, 13417, 13422, 13426, - 13435, 13443, 13451, 13458, 13466, 13478, 13489, 13499, 13506, 13512, - 13521, 13532, 13541, 13553, 13565, 13577, 13587, 13596, 13605, 13613, - 13620, 13629, 13637, 13641, 13647, 13653, 13658, 7753, 13662, 13664, - 13668, 13673, 13679, 13688, 13692, 13698, 13706, 13713, 13722, 13731, - 13740, 13749, 13758, 13767, 13776, 13785, 13795, 13805, 13814, 13820, - 13827, 13834, 13840, 13854, 13861, 13869, 13878, 13884, 13893, 13902, - 13913, 13923, 13931, 13938, 13946, 13955, 13968, 13976, 13983, 13996, - 14002, 14008, 14018, 14027, 14036, 14041, 14045, 14051, 14057, 14064, - 8966, 14069, 14074, 14081, 14086, 12376, 14091, 14099, 14105, 14110, - 14118, 14126, 14133, 14141, 14147, 14155, 14163, 14169, 14174, 14180, - 14187, 14193, 14198, 14202, 14213, 14221, 14227, 14232, 14241, 14247, - 14252, 14261, 14275, 3853, 14279, 14284, 14289, 14295, 14300, 14305, - 14309, 14314, 14319, 14324, 7752, 14329, 14334, 14339, 14344, 14349, - 14353, 14358, 14363, 14368, 14373, 14379, 14385, 14390, 14394, 14399, - 14404, 14409, 9301, 14414, 14419, 14424, 14429, 14434, 14451, 14469, - 14481, 14494, 14511, 14527, 14544, 14554, 14573, 14584, 14595, 14606, - 14617, 14629, 14640, 14651, 14668, 14679, 14690, 14695, 9306, 14700, - 14704, 2381, 14708, 14711, 14717, 14725, 14733, 14738, 14746, 14754, - 14761, 14766, 14772, 14779, 14787, 14794, 14806, 14814, 14819, 11597, - 14825, 14834, 14843, 14851, 14858, 14864, 14872, 14879, 14885, 14892, - 14898, 14907, 14915, 14925, 14932, 14938, 14946, 14952, 14960, 14967, - 14980, 14987, 14996, 15005, 15014, 15022, 15032, 15039, 15044, 3560, - 15051, 15056, 1372, 15060, 14330, 15064, 15070, 15074, 15082, 15094, - 15099, 15106, 15112, 15117, 15124, 14335, 15128, 15132, 15136, 14340, - 15140, 14345, 15144, 15151, 15156, 15160, 15167, 15171, 15179, 15186, - 15190, 15197, 15214, 15223, 15227, 15230, 15238, 15244, 15249, 3638, - 15253, 15255, 15263, 15270, 15280, 15292, 15297, 15303, 15308, 15312, - 15318, 15323, 15329, 15332, 15339, 15347, 15354, 15360, 15366, 15371, - 15378, 15384, 15389, 15396, 15400, 15406, 15410, 15417, 15423, 15429, - 15437, 15443, 15448, 15454, 15462, 15470, 15476, 15482, 15487, 15494, - 15499, 15503, 15509, 15514, 15521, 15526, 15532, 15535, 15541, 15547, - 15550, 15554, 15566, 15572, 15577, 15584, 15590, 15596, 15607, 15617, - 15626, 15634, 15641, 15652, 15662, 15672, 15680, 15683, 14359, 15688, - 15693, 14364, 14499, 15701, 15714, 15729, 15740, 14516, 15758, 15771, - 15784, 15795, 10492, 15806, 15819, 15838, 15849, 15860, 15871, 2649, - 15884, 15888, 15896, 15911, 15926, 15937, 15944, 15950, 15958, 15962, - 15968, 15971, 15981, 15989, 15996, 16004, 16014, 16019, 16026, 16031, - 16038, 16049, 16059, 16065, 16070, 16075, 14369, 16079, 16085, 16091, - 16096, 16101, 16106, 16110, 14374, 14380, 16114, 14386, 16119, 16127, - 16136, 16143, 9150, 16147, 16149, 16154, 16159, 16165, 16170, 16175, - 16180, 16185, 16189, 16195, 16201, 16206, 16212, 16217, 16222, 16228, - 16233, 16238, 16243, 16248, 16254, 16259, 16264, 16270, 16276, 16281, - 16286, 16293, 16299, 16310, 16317, 16322, 16326, 16330, 16333, 16341, - 16346, 16353, 16360, 16366, 16371, 16376, 16383, 16393, 16398, 16405, - 16411, 16421, 16431, 16445, 16459, 16473, 16487, 16502, 16517, 16534, - 16552, 16565, 16571, 16576, 16581, 16585, 16590, 16598, 16604, 16609, - 16614, 16618, 16623, 16627, 16632, 16636, 16647, 16653, 16658, 16663, - 16670, 16675, 16679, 16684, 16689, 16695, 16702, 16708, 16713, 16717, - 16723, 16728, 16733, 16737, 16743, 16748, 16753, 16760, 16765, 13111, - 16769, 16774, 16778, 16783, 16789, 16795, 16802, 16812, 16820, 16827, - 16832, 16836, 16845, 16853, 16860, 16867, 16873, 16879, 16884, 16889, - 16895, 16900, 16906, 16911, 16917, 16923, 16930, 16936, 16941, 16946, - 9348, 16955, 16958, 16964, 16969, 16974, 16984, 16991, 16997, 17002, - 17007, 17013, 17018, 17024, 17029, 17035, 17041, 17046, 17054, 17061, - 17066, 17071, 17077, 17082, 17086, 17095, 17106, 17113, 17118, 17126, - 17132, 17139, 17145, 17150, 17154, 17160, 17165, 17170, 17175, 1440, - 7777, 2877, 17179, 17183, 17187, 17191, 17195, 17199, 17202, 17209, - 17217, 14400, 17224, 17234, 17242, 17249, 17257, 17267, 17276, 17289, - 17294, 17299, 17307, 17314, 13207, 13216, 17321, 17331, 17346, 17352, - 17359, 17366, 17372, 17380, 17390, 17400, 14405, 17409, 17415, 17421, - 17429, 17437, 17442, 17451, 17459, 17471, 17481, 17491, 17501, 17510, - 17522, 17532, 17542, 17553, 17558, 17570, 17582, 17594, 17606, 17618, - 17630, 17642, 17654, 17666, 17678, 17689, 17701, 17713, 17725, 17737, - 17749, 17761, 17773, 17785, 17797, 17809, 17820, 17832, 17844, 17856, - 17868, 17880, 17892, 17904, 17916, 17928, 17940, 17951, 17963, 17975, - 17987, 17999, 18011, 18023, 18035, 18047, 18059, 18071, 18082, 18094, - 18106, 18118, 18130, 18142, 18154, 18166, 18178, 18190, 18202, 18213, - 18225, 18237, 18249, 18261, 18273, 18285, 18297, 18309, 18321, 18333, - 18344, 18356, 18368, 18380, 18392, 18404, 18416, 18428, 18440, 18452, - 18464, 18475, 18487, 18499, 18511, 18523, 18536, 18549, 18562, 18575, - 18588, 18601, 18614, 18626, 18639, 18652, 18665, 18678, 18691, 18704, - 18717, 18730, 18743, 18756, 18768, 18781, 18794, 18807, 18820, 18833, - 18846, 18859, 18872, 18885, 18898, 18910, 18923, 18936, 18949, 18962, - 18975, 18988, 19001, 19014, 19027, 19040, 19052, 19065, 19078, 19091, - 19104, 19117, 19130, 19143, 19156, 19169, 19182, 19194, 19207, 19220, - 19233, 19246, 19259, 19272, 19285, 19298, 19311, 19324, 19336, 19347, - 19360, 19373, 19386, 19399, 19412, 19425, 19438, 19451, 19464, 19477, - 19489, 19502, 19515, 19528, 19541, 19554, 19567, 19580, 19593, 19606, - 19619, 19631, 19644, 19657, 19670, 19683, 19696, 19709, 19722, 19735, - 19748, 19761, 19773, 19786, 19799, 19812, 19825, 19838, 19851, 19864, - 19877, 19890, 19903, 19915, 19928, 19941, 19954, 19967, 19980, 19993, - 20006, 20019, 20032, 20045, 20057, 20070, 20083, 20096, 20109, 20122, - 20135, 20148, 20161, 20174, 20187, 20199, 20212, 20225, 20238, 20251, - 20264, 20277, 20290, 20303, 20316, 20329, 20341, 20354, 20367, 20380, - 20393, 20406, 20419, 20432, 20445, 20458, 20471, 20483, 20496, 20509, - 20522, 20535, 20548, 20561, 20574, 20587, 20600, 20613, 20625, 20638, - 20651, 20664, 20677, 20690, 20703, 20716, 20729, 20742, 20755, 20767, - 20778, 20786, 20794, 20801, 20807, 20811, 20817, 20823, 20831, 20837, - 20842, 20846, 20855, 9155, 20866, 20873, 20881, 20888, 20895, 10948, - 20902, 20911, 20916, 20921, 7805, 20928, 20933, 20936, 20941, 20949, - 20956, 20963, 20970, 20976, 20985, 20994, 21000, 21009, 21013, 21019, - 21024, 21034, 21041, 21047, 21055, 21061, 21068, 21078, 21087, 21091, - 21098, 21102, 21107, 21113, 21121, 21125, 21135, 14415, 21144, 21150, - 21154, 21163, 14420, 21169, 21176, 21187, 21195, 21204, 21212, 8931, - 21220, 21225, 21231, 21236, 21240, 21244, 21248, 9639, 21253, 21261, - 21268, 21277, 21284, 21291, 10878, 21298, 21304, 21308, 21314, 21321, - 21327, 21335, 21341, 21348, 21354, 21360, 21369, 21373, 21381, 21390, - 21397, 21402, 21406, 21417, 21422, 21427, 21432, 21445, 7995, 21449, - 21455, 21463, 21467, 21474, 21483, 21488, 14691, 21496, 21500, 21512, - 21517, 21521, 21524, 21530, 21536, 21541, 21545, 21548, 21559, 21564, - 9383, 21571, 21576, 9388, 21581, 21586, 21591, 21596, 21601, 21606, - 21611, 21616, 21621, 21626, 21631, 21636, 21642, 21647, 21652, 21657, - 21662, 21667, 21672, 21677, 21682, 21687, 21693, 21699, 21704, 21709, - 21714, 21719, 21724, 21729, 21734, 21739, 21744, 21750, 21755, 21760, - 21765, 21771, 21777, 21782, 21787, 21792, 21797, 21802, 21807, 21812, - 21817, 21823, 21828, 21833, 21838, 21843, 21849, 21854, 21859, 21863, - 1368, 129, 21871, 21875, 21879, 21883, 21888, 21892, 13117, 12476, 21896, - 21901, 21905, 21910, 21914, 21919, 21923, 21929, 21934, 21938, 21942, - 21950, 21954, 21958, 21963, 21968, 21972, 21978, 21983, 21987, 21992, - 21997, 22001, 22008, 22015, 22022, 22026, 22030, 22035, 22039, 22042, - 22048, 22061, 22066, 22075, 22080, 9428, 22085, 22088, 2712, 2717, 22092, - 22098, 22104, 7209, 22109, 22114, 22119, 22125, 22130, 13909, 22135, - 22140, 22145, 22150, 22156, 22161, 22166, 22172, 22177, 22181, 22186, - 22191, 22196, 22201, 22205, 22210, 22214, 22219, 22224, 22229, 22234, - 22238, 22243, 22247, 22252, 22257, 22262, 22267, 2886, 22182, 22271, - 22279, 22286, 9733, 22298, 22306, 22187, 22313, 22318, 22326, 22192, - 22331, 22336, 22344, 22349, 22197, 22354, 22359, 22363, 22369, 22377, - 22380, 22387, 22391, 22395, 22401, 22408, 22413, 8958, 1727, 1732, 22417, - 22423, 22429, 22434, 22438, 22442, 22446, 22450, 22454, 22458, 22462, - 22466, 22469, 22475, 22482, 22490, 22496, 22502, 22507, 22512, 22516, - 13829, 13836, 22521, 22533, 22536, 22543, 16362, 22550, 22558, 22569, - 22578, 22591, 22601, 22615, 22627, 22641, 22653, 22663, 22675, 22681, - 22696, 22720, 22738, 22757, 22770, 22784, 22802, 22818, 22835, 22853, - 22864, 22883, 22900, 22920, 22938, 22950, 22964, 22978, 22990, 23007, - 23026, 23044, 23056, 23074, 23093, 14559, 23106, 23126, 23138, 10523, - 23150, 23155, 23160, 23165, 23171, 23176, 23180, 23187, 2398, 23191, - 23197, 23201, 23204, 23208, 23216, 23222, 22215, 23226, 23235, 23246, - 23252, 23258, 23267, 23275, 23282, 23287, 23291, 23298, 23304, 23313, - 23321, 23328, 23338, 23347, 23357, 23362, 23371, 23380, 23391, 23402, - 3963, 23412, 23416, 23426, 23434, 23444, 23455, 23460, 23470, 23478, - 23485, 23491, 23498, 23503, 22225, 23507, 23516, 23520, 23523, 23528, - 23535, 23544, 23552, 23560, 23570, 23579, 23585, 23591, 22230, 22235, - 23595, 23605, 23615, 23625, 23633, 23640, 23650, 23658, 23666, 23672, - 23680, 930, 23689, 14750, 542, 23703, 23712, 23720, 23731, 23742, 23752, - 23761, 23773, 23782, 23791, 23797, 23806, 23815, 23825, 23833, 23841, - 9360, 23847, 23850, 23854, 23859, 23864, 9848, 22248, 22253, 23872, - 23878, 23884, 23889, 23894, 23898, 23906, 23912, 23918, 23922, 3525, - 23930, 23935, 23940, 23944, 23948, 9928, 23955, 23963, 23977, 23984, - 23990, 9937, 9943, 23998, 24006, 24013, 24018, 24023, 22258, 24029, - 24040, 24044, 24049, 2601, 24054, 24065, 24071, 24076, 24080, 24084, - 24087, 24094, 24101, 24108, 24114, 24118, 22263, 24123, 24127, 24131, - 1037, 24136, 24141, 24146, 24151, 24156, 24161, 24166, 24171, 24176, - 24181, 24186, 24191, 24196, 24201, 24207, 24212, 24217, 24222, 24227, - 24232, 24237, 24243, 24248, 24253, 24258, 24263, 24268, 24273, 24278, - 24284, 24290, 24295, 24301, 24306, 24311, 5, 24317, 24321, 24325, 24329, - 24334, 24338, 24342, 24346, 24350, 24355, 24359, 24364, 24368, 24371, - 24375, 24380, 24384, 24389, 24393, 24397, 24401, 24406, 24410, 24414, - 24424, 24429, 24433, 24437, 24442, 24447, 24456, 24461, 24466, 24470, - 24474, 24487, 24499, 24508, 24517, 24523, 24528, 24532, 24536, 24546, - 24555, 24563, 24569, 24574, 24578, 24585, 24595, 24604, 24612, 24620, - 24627, 24635, 24644, 24653, 24661, 24666, 24670, 24674, 24677, 24679, - 24683, 24687, 24692, 24697, 24701, 24705, 24708, 24712, 24715, 24719, - 24722, 24725, 24729, 24735, 24739, 24743, 24747, 24752, 24757, 24762, - 24766, 24769, 24774, 24780, 24785, 24791, 24796, 24800, 24804, 24808, - 24813, 24817, 24822, 24826, 24830, 24837, 24841, 24844, 24848, 24854, - 24860, 24864, 24868, 24873, 24880, 24886, 24890, 24899, 24903, 24907, - 24910, 24916, 24921, 24927, 1489, 1791, 24932, 24937, 24942, 24947, - 24952, 24957, 24962, 2148, 2194, 24967, 24970, 24974, 24978, 24983, - 24987, 24991, 24994, 24999, 25004, 25008, 25011, 25016, 25020, 25025, - 25029, 14762, 25034, 25037, 25040, 25044, 25049, 25053, 25066, 25070, - 25073, 25081, 25090, 25097, 25102, 25108, 25114, 25122, 25129, 25136, - 25140, 25144, 25148, 25153, 25158, 25162, 25170, 25175, 25187, 25198, - 25203, 25207, 25211, 25217, 25222, 25227, 25231, 25235, 25238, 25244, - 7915, 2316, 25248, 25253, 25269, 9475, 25289, 25298, 25314, 25318, 25321, - 25327, 25337, 25343, 25352, 25367, 25379, 25390, 25398, 25407, 25413, - 25422, 25432, 25443, 25454, 25463, 25470, 25479, 25487, 25494, 25502, - 25509, 25516, 25529, 25536, 25542, 25547, 25556, 25562, 25567, 25575, - 25582, 23436, 25594, 25606, 25620, 25628, 25635, 25647, 25656, 25665, - 25673, 25681, 25689, 25696, 25705, 25713, 25723, 25732, 25742, 25751, - 25760, 25768, 25773, 25777, 25780, 25784, 25788, 25792, 25796, 25800, - 25806, 25812, 25820, 14807, 25827, 25832, 25839, 25845, 25852, 14815, - 25859, 25862, 25874, 25882, 25888, 25893, 25897, 9878, 25908, 25918, - 25927, 25934, 25938, 14820, 25941, 25948, 25952, 25958, 25961, 25968, - 25974, 25981, 25987, 25991, 25996, 26000, 26009, 26016, 26022, 7956, - 26029, 26037, 26044, 26050, 26055, 26061, 26067, 26075, 26079, 26082, - 26084, 25785, 26093, 26099, 26109, 26114, 26121, 26127, 26132, 26137, - 26142, 26146, 26151, 26158, 26167, 26171, 26178, 26187, 26193, 26198, - 26204, 26209, 26216, 26227, 26232, 26236, 26246, 26252, 26256, 26261, - 26271, 26280, 26284, 26291, 26299, 26306, 26312, 26317, 26325, 26332, - 26344, 26353, 26357, 13053, 26365, 26375, 26379, 25077, 26390, 26395, - 26399, 26406, 26413, 21974, 25710, 26418, 26422, 26425, 22870, 26430, - 26444, 26460, 26478, 26497, 26514, 26532, 22889, 26549, 26569, 22906, - 26581, 26593, 15745, 26605, 22926, 26619, 26631, 10536, 26645, 26650, - 26655, 26660, 26666, 26672, 26678, 26682, 26689, 26694, 26704, 26710, - 10183, 26716, 26718, 26723, 26731, 26735, 26154, 26741, 26748, 11524, - 11534, 26755, 26765, 26770, 26774, 26777, 26783, 26791, 26803, 26813, - 26829, 26842, 26856, 15763, 26870, 26877, 26881, 26884, 26889, 26893, - 26900, 26907, 26917, 26922, 26927, 26932, 26940, 26948, 26957, 26962, - 9572, 26966, 26969, 26972, 26977, 26984, 26989, 27005, 27013, 27021, - 9423, 27029, 27034, 27038, 27044, 27050, 27053, 27059, 27071, 27079, - 27086, 27092, 27099, 27110, 27124, 27137, 27146, 27155, 27167, 27178, - 27188, 27197, 27206, 27214, 27225, 7938, 27232, 27238, 27243, 27249, - 27256, 27266, 27276, 27285, 27291, 27298, 27303, 27310, 27318, 27326, - 27338, 6246, 27345, 27354, 27362, 27368, 27374, 27379, 27383, 27386, - 27392, 27399, 27404, 27409, 27413, 27425, 27436, 27445, 27453, 14947, - 27458, 27464, 27470, 11517, 8635, 27475, 27479, 27483, 27486, 27489, - 27495, 27503, 27511, 27515, 27519, 27524, 27527, 27536, 27540, 27548, - 27559, 27563, 27569, 27575, 27579, 27585, 27593, 27615, 27639, 27646, - 27653, 27659, 27667, 27673, 27678, 27689, 27707, 27714, 27722, 27726, - 27735, 27748, 27756, 27768, 27779, 27789, 27803, 27812, 27820, 27832, - 9492, 27843, 27854, 27866, 27876, 27885, 27890, 27894, 27902, 27912, - 27917, 27921, 27924, 27927, 27935, 27943, 27952, 27962, 27971, 27977, - 27991, 2663, 28013, 28024, 28033, 28043, 28055, 28064, 28073, 28083, - 28091, 28099, 28108, 28113, 28124, 28129, 28140, 28144, 28154, 28163, - 28171, 28181, 28191, 28199, 28208, 28215, 28223, 28230, 28239, 28243, - 28251, 28258, 28266, 28273, 28284, 28299, 28306, 28312, 28322, 28331, - 28337, 28341, 28348, 28352, 14031, 28358, 28362, 28367, 28374, 28378, - 28382, 28390, 28398, 28404, 28413, 28420, 28425, 28430, 28440, 23505, - 28444, 28447, 28452, 28457, 28462, 28467, 28472, 28477, 28482, 28487, - 28493, 28498, 28503, 28509, 1218, 704, 28514, 28523, 2364, 28530, 28535, - 28539, 28545, 1267, 546, 318, 28550, 28559, 28567, 28576, 28584, 28595, - 28604, 28612, 28616, 28619, 28627, 28635, 28640, 14775, 28646, 28652, - 28658, 5872, 28663, 28667, 28673, 28677, 28684, 1455, 28690, 28697, 9579, - 28701, 28711, 28719, 28725, 28734, 28742, 28748, 28756, 28763, 11110, - 28769, 28776, 28781, 28788, 1496, 2147, 28794, 28800, 28807, 28818, - 28829, 28837, 28844, 28854, 28863, 28871, 28880, 28887, 28894, 28907, - 28918, 1272, 28937, 28942, 28950, 3575, 28954, 28959, 28963, 1459, 24706, - 28973, 28977, 28982, 28986, 3493, 28992, 29000, 29007, 29018, 29026, - 29034, 3576, 279, 29039, 29047, 29055, 29062, 29068, 29073, 2216, 29080, - 29086, 25992, 26222, 29092, 106, 29096, 29100, 29106, 615, 9328, 29111, - 29118, 29124, 2327, 29128, 29132, 15187, 29135, 29140, 29147, 29153, - 29158, 29166, 29173, 29179, 22351, 29183, 29187, 3646, 16625, 29191, - 29196, 29199, 29207, 29215, 29220, 29223, 29230, 29240, 29252, 29257, - 29261, 29269, 29276, 29282, 29289, 29296, 29299, 29303, 29307, 1463, - 29317, 29319, 29324, 29330, 29336, 29341, 29346, 29351, 29356, 29361, - 29366, 29371, 29376, 29381, 29386, 29391, 29396, 29401, 29406, 29412, - 29418, 29424, 29430, 29435, 29440, 29445, 29451, 29456, 29461, 29466, - 29472, 29477, 29483, 29488, 29493, 29498, 29503, 29509, 29514, 29520, - 29525, 29530, 29535, 29540, 29546, 29551, 29557, 29562, 29567, 29572, - 29577, 29582, 29587, 29592, 29597, 29602, 29608, 29614, 29620, 29625, - 29630, 29635, 29640, 29646, 29652, 29658, 29664, 29670, 29676, 29681, - 29687, 29692, 29697, 29702, 29707, 29713, 2443, 29718, 2450, 2457, 2754, - 29723, 2463, 2473, 29729, 29733, 29738, 29743, 29749, 29754, 29759, - 29763, 29768, 29774, 29779, 29784, 29789, 29795, 29800, 29804, 29808, - 29813, 29818, 29823, 29828, 29833, 29839, 29845, 29850, 29854, 29859, - 29865, 29869, 29874, 29879, 29884, 29889, 29893, 29896, 29901, 29906, - 29911, 29916, 29921, 29927, 29933, 29938, 29943, 29947, 29952, 29957, - 29962, 29967, 29972, 29976, 29981, 29986, 29991, 29995, 29999, 30003, - 30008, 30016, 30021, 30027, 30033, 30039, 30044, 30048, 30051, 30056, - 30061, 30065, 30070, 30074, 30079, 30083, 30086, 30091, 17302, 30096, - 30101, 30106, 30114, 21280, 28694, 9026, 30119, 30124, 30128, 30133, - 30137, 30141, 30146, 30150, 30153, 30156, 30160, 30165, 30169, 30177, - 30181, 30184, 30189, 30193, 30197, 30202, 30207, 30211, 30217, 30222, - 30227, 30234, 30241, 30245, 30248, 30254, 30263, 30270, 30278, 30285, - 30289, 30294, 30298, 30302, 30308, 30314, 30318, 30324, 30329, 30334, - 30338, 30345, 30351, 30357, 30363, 30369, 30376, 30382, 30388, 30394, - 30400, 30406, 30412, 30418, 30425, 30431, 30438, 30444, 30450, 30456, - 30462, 30468, 30474, 30480, 30486, 30492, 11418, 30498, 30503, 30508, - 30511, 30519, 30524, 30533, 30539, 30544, 30549, 30554, 30558, 30563, - 30568, 30573, 30578, 30583, 30590, 30597, 30603, 30609, 30614, 16303, - 30621, 30627, 30634, 30640, 30646, 30651, 30659, 30664, 16082, 30668, - 30673, 30678, 30684, 30689, 30694, 30698, 30703, 30708, 30714, 30719, - 30724, 30728, 30733, 30738, 30742, 30747, 30752, 30757, 30761, 30766, - 30771, 30776, 30780, 30784, 15293, 30788, 30797, 30803, 30809, 30818, - 30826, 30835, 30843, 30848, 30852, 30859, 30865, 30869, 30872, 30877, - 30886, 30894, 30899, 1495, 30905, 30908, 30912, 22424, 22430, 30918, - 30922, 30933, 30944, 30955, 30967, 30974, 30981, 30986, 30990, 5909, 755, - 21279, 30998, 31003, 31007, 31012, 31016, 31022, 31027, 31033, 31038, - 31044, 31049, 31055, 31060, 31066, 31072, 31078, 31083, 31039, 31045, - 31087, 31092, 31098, 31103, 31109, 31114, 31120, 31125, 31050, 10421, - 31129, 31061, 31067, 31073, 2831, 3423, 31135, 31138, 31144, 31150, - 31156, 31163, 31169, 31175, 31181, 31187, 31193, 31199, 31205, 31211, - 31217, 31223, 31229, 31235, 31242, 31248, 31254, 31260, 31266, 31272, - 31275, 31280, 31283, 31290, 31298, 31303, 31308, 31314, 31319, 31324, - 31328, 31333, 31339, 31344, 31350, 31355, 31361, 31366, 31372, 31378, - 31382, 31387, 31392, 31397, 31402, 31406, 31411, 31416, 31421, 31427, - 31433, 31439, 31445, 31450, 31454, 31457, 31463, 31469, 31478, 31486, - 31493, 31498, 31502, 31506, 31511, 15146, 31516, 31524, 31530, 3683, - 1377, 31535, 31539, 8005, 31545, 31551, 31558, 8014, 31562, 31568, 31575, - 31581, 31590, 31598, 31610, 31614, 31621, 31627, 31631, 31634, 31643, - 31651, 31040, 31656, 31666, 31676, 31686, 31692, 31697, 31707, 31712, - 31725, 31739, 31750, 31762, 31774, 31788, 31801, 31813, 31825, 14600, - 31839, 31844, 31849, 31853, 31857, 31861, 1780, 27176, 31865, 31870, - 31088, 31875, 31878, 31883, 31888, 31893, 31899, 31905, 10098, 31910, - 31917, 15697, 31923, 31928, 31933, 31937, 31942, 31947, 31093, 31952, - 31957, 31962, 31968, 31099, 31973, 31976, 31983, 31991, 31997, 32003, - 32009, 32020, 32025, 32032, 32039, 32046, 32054, 32063, 32072, 32078, - 32084, 32092, 31104, 32097, 32103, 32109, 31110, 32114, 32119, 32127, - 32135, 32141, 32148, 32154, 32161, 32168, 32174, 32182, 32192, 32199, - 32204, 32210, 32215, 32220, 32227, 32236, 32244, 32249, 32255, 32262, - 32270, 32276, 32281, 32287, 32296, 27957, 32303, 32307, 32312, 32321, - 32326, 32331, 32336, 12405, 32344, 32349, 32354, 32359, 32363, 32368, - 32373, 32380, 32385, 32390, 32395, 31115, 21216, 32401, 2519, 244, 32404, - 32407, 32411, 32415, 32425, 32433, 32437, 32444, 32451, 32455, 32458, - 32464, 32472, 32480, 32484, 32488, 32491, 32498, 32502, 32506, 32513, - 32521, 31051, 32528, 32536, 10158, 664, 308, 32548, 32553, 32558, 32564, - 32569, 32574, 3704, 32579, 32582, 32587, 32592, 32597, 32602, 32607, - 32614, 22529, 32619, 32624, 32629, 32634, 32639, 32645, 32650, 32656, - 31286, 32662, 32667, 32673, 32679, 32689, 32694, 32699, 32703, 32708, - 32713, 32718, 32723, 32736, 32741, 22302, 16705, 3710, 32745, 32750, - 32755, 32761, 32766, 32771, 32775, 32780, 32785, 32791, 32796, 32801, - 1382, 32805, 32810, 32815, 32820, 32824, 32829, 32834, 32839, 32845, - 32851, 32856, 32860, 32864, 32869, 32874, 32879, 32883, 32891, 32895, - 32901, 32905, 32912, 16498, 31062, 32918, 32925, 32933, 32940, 32946, - 32959, 32971, 32977, 32981, 2773, 32985, 32989, 32493, 32998, 33009, - 33014, 33019, 33024, 33028, 33033, 22435, 33037, 33041, 33046, 31068, - 21300, 33050, 33055, 33061, 33066, 33070, 33074, 33077, 33081, 33087, - 33098, 33110, 31074, 33115, 33118, 33122, 347, 33127, 33132, 33137, - 33142, 33147, 33152, 33158, 33163, 33168, 33174, 33179, 33185, 33190, - 33196, 33201, 33206, 33211, 33216, 33221, 33226, 33231, 33236, 33242, - 33247, 33252, 33257, 33262, 33267, 33272, 33277, 33283, 33289, 33294, - 33299, 33304, 33309, 33314, 33319, 33324, 33329, 33334, 33339, 33344, - 33349, 33354, 33359, 33364, 33369, 33374, 33379, 33385, 313, 26, 33390, - 33394, 33398, 33406, 33410, 33414, 33417, 33420, 33422, 33427, 33431, - 33436, 33440, 33445, 33449, 33454, 33458, 33461, 33463, 33467, 33472, - 33476, 33487, 33490, 33492, 33496, 33508, 33517, 33521, 33525, 33531, - 33536, 33545, 33551, 33556, 33561, 33565, 33570, 33577, 33582, 33588, - 33593, 33597, 33604, 25718, 25728, 33608, 33613, 33618, 33623, 33630, - 33634, 33641, 8113, 33647, 33656, 33664, 33679, 33693, 33701, 33712, - 33721, 33726, 7227, 33736, 33741, 33746, 33750, 33753, 33757, 33762, - 33766, 33773, 33778, 33783, 8912, 33793, 33795, 33798, 33802, 33808, - 33812, 33817, 33822, 33828, 33833, 33839, 33844, 33854, 33863, 33871, - 33876, 33882, 33887, 33894, 33898, 33906, 33913, 33926, 33934, 33938, - 33948, 33953, 33957, 33965, 33973, 33977, 33986, 33992, 33997, 34005, - 34015, 34024, 34033, 34042, 34053, 34061, 34072, 34081, 34088, 34094, - 34099, 34110, 34115, 34119, 34122, 34126, 34134, 34140, 34148, 34155, - 34161, 34166, 34172, 2418, 34176, 34178, 34183, 34188, 34193, 34196, - 34198, 34202, 34205, 34212, 34216, 9891, 34220, 34226, 34236, 34241, - 34247, 34251, 34256, 34269, 26104, 34275, 34284, 17475, 34291, 34300, - 31672, 34308, 34313, 34317, 34325, 34332, 34337, 34341, 34346, 34350, - 34358, 34364, 34370, 34375, 34379, 34382, 34387, 34400, 34416, 22996, - 34433, 34445, 34462, 34474, 34488, 23013, 23032, 34500, 34512, 2680, - 34526, 34531, 34536, 34541, 34545, 34552, 34564, 34570, 34573, 34584, - 34595, 34600, 32089, 695, 34604, 34608, 34612, 34615, 34620, 34625, - 34631, 34636, 34641, 34647, 34653, 34658, 34662, 34667, 34672, 34677, - 34681, 34684, 34690, 34695, 34700, 34705, 34709, 34714, 34720, 34728, - 26337, 34733, 34738, 34745, 34751, 34757, 34762, 34770, 22538, 34777, - 34782, 34787, 34792, 34796, 34799, 34804, 34808, 34812, 34819, 34825, - 34831, 34837, 34844, 34849, 34855, 33968, 34859, 34863, 34868, 34881, - 34886, 34892, 34900, 34907, 34915, 34925, 34931, 34937, 34943, 34947, - 34956, 34964, 34971, 34976, 34981, 10444, 34986, 34994, 35001, 35007, - 35017, 35022, 35028, 35036, 3608, 35043, 35050, 3614, 35054, 35059, - 35070, 35077, 35083, 35092, 35096, 4015, 35099, 35106, 35112, 35118, - 35126, 35136, 29063, 35143, 35151, 35156, 35162, 35167, 25964, 35173, - 35180, 35186, 35195, 23677, 35202, 35207, 35211, 35219, 35227, 9607, - 5895, 35234, 35238, 35240, 35244, 35249, 35251, 35257, 35262, 35267, - 35274, 32610, 35280, 35285, 35289, 35294, 35298, 35307, 35311, 35317, - 35324, 35330, 35337, 35342, 35351, 35356, 35360, 35365, 35372, 35380, - 35388, 35393, 21356, 35397, 35400, 35404, 35408, 35412, 35415, 35417, - 35425, 35429, 35436, 35440, 35444, 35452, 35459, 35469, 35473, 35477, - 35485, 35493, 35499, 35504, 35513, 13357, 35519, 35528, 35533, 35540, - 35548, 35556, 35564, 35571, 35578, 35585, 35592, 35599, 35604, 35610, - 35627, 35635, 35645, 35653, 35660, 407, 35664, 35670, 35674, 35679, - 33717, 35685, 35688, 35692, 35700, 3619, 35708, 35714, 35720, 35729, - 35739, 35746, 35752, 3625, 3631, 35761, 35768, 35776, 35781, 35785, - 35792, 35800, 35807, 35813, 35822, 35832, 35838, 35846, 35855, 35862, - 35870, 35877, 22032, 35881, 35888, 35894, 35904, 35913, 35924, 35928, - 35938, 35944, 35951, 35959, 35968, 35977, 35987, 35998, 36005, 36010, - 36017, 3029, 36025, 36031, 36036, 36042, 36048, 36053, 36066, 36079, - 36092, 36099, 36105, 36113, 36121, 36126, 36130, 1469, 36134, 36139, - 36144, 36149, 36154, 36160, 36165, 36170, 36175, 36180, 36185, 36190, - 36195, 36201, 36207, 36212, 36217, 36223, 36228, 36233, 36238, 36244, - 36249, 36254, 36259, 36264, 36270, 36275, 36280, 36286, 36291, 36296, - 36301, 36306, 36311, 36317, 36322, 36328, 36333, 36339, 36344, 36349, - 36354, 36360, 36366, 36372, 36378, 36384, 36390, 36396, 36402, 36407, - 36412, 36418, 36423, 36428, 36433, 36438, 36443, 36448, 36453, 36459, - 36464, 36469, 36475, 36481, 101, 36486, 36488, 36492, 36496, 36500, - 36505, 36509, 9528, 36513, 36519, 1741, 6280, 36525, 36528, 36533, 36537, - 36542, 36546, 36550, 36555, 10245, 36559, 36563, 36567, 36571, 15385, - 36576, 36580, 36585, 36590, 36595, 36599, 36606, 26128, 36612, 36615, - 36619, 36624, 36630, 36634, 36642, 36648, 36653, 36657, 36663, 36667, - 36671, 3462, 3467, 29255, 36674, 36678, 36682, 36686, 36690, 36698, - 36705, 36709, 36716, 36721, 317, 36726, 36730, 36736, 36748, 36754, - 36760, 36764, 36770, 36779, 36783, 36787, 36792, 36798, 36803, 36807, - 36812, 36816, 36820, 36827, 36833, 36838, 36853, 36868, 36883, 36899, - 36917, 10195, 36931, 36938, 36942, 36945, 36954, 36959, 36963, 36971, - 33919, 36979, 36983, 36993, 37004, 29225, 37017, 37021, 37030, 37038, - 9785, 14913, 37042, 22447, 37045, 30173, 37050, 9784, 37055, 37061, - 37066, 37072, 37077, 37083, 37088, 37094, 37099, 37105, 37111, 37117, - 37122, 37078, 37084, 37089, 37095, 37100, 37106, 37112, 8126, 3874, - 37126, 37134, 37138, 37141, 37145, 37150, 37155, 37161, 37167, 37172, - 37176, 25976, 37180, 37184, 37190, 37194, 9049, 37203, 37210, 37214, - 11875, 37221, 37227, 37232, 37239, 37246, 37253, 28571, 8049, 37260, - 37267, 37274, 37280, 37285, 37292, 37303, 37309, 37314, 37319, 37324, - 37331, 37079, 37335, 37345, 37356, 37362, 37367, 37372, 37377, 37382, - 37387, 37391, 37395, 37401, 37409, 2319, 865, 10261, 10273, 10278, 10284, - 37418, 10289, 10294, 10300, 37423, 37433, 37437, 10305, 37442, 16903, - 37445, 37450, 37454, 37459, 37464, 37471, 37478, 37482, 37485, 37493, - 10208, 37500, 37503, 37509, 37519, 5929, 37528, 37532, 37540, 37544, - 37554, 37560, 37571, 37577, 37583, 37588, 37594, 37600, 37606, 37611, - 37614, 37621, 37627, 37632, 37639, 37646, 37650, 37660, 37673, 37682, - 37691, 37702, 37715, 37726, 37735, 37746, 37751, 37760, 37765, 10310, - 37771, 37778, 37786, 37791, 37795, 37802, 37809, 3829, 16, 37813, 37818, - 16757, 37822, 37825, 37828, 28077, 37832, 28580, 37840, 37844, 37848, - 37851, 37857, 37101, 37863, 37871, 37877, 37884, 28060, 37888, 28254, - 37892, 37901, 37907, 37913, 37918, 37922, 37928, 37932, 37940, 37948, - 26194, 37954, 37961, 37967, 37972, 37977, 37981, 37987, 37992, 37998, - 4056, 791, 38005, 38009, 38012, 15275, 38024, 35851, 38035, 38038, 38045, - 38049, 38055, 38059, 38065, 38070, 38076, 38081, 38086, 38090, 38094, - 38099, 38104, 38114, 38120, 38133, 38139, 38145, 38152, 38157, 38163, - 38168, 16643, 1472, 1019, 31218, 31224, 38173, 31230, 31243, 31249, - 31255, 38179, 31261, 31267, 38185, 38191, 22, 38199, 38206, 38210, 38214, - 38222, 31978, 38226, 38230, 38237, 38242, 38246, 38251, 38257, 38262, - 38268, 38273, 38277, 38281, 38285, 38290, 38294, 38299, 38303, 38310, - 38315, 38319, 38324, 38328, 38333, 38337, 38342, 38348, 15495, 15500, - 38353, 38357, 38360, 38364, 21183, 38369, 38373, 38379, 38386, 38391, - 38401, 38406, 38414, 38418, 38421, 31993, 38425, 4109, 38430, 38435, - 38439, 38444, 38448, 38453, 13375, 38464, 38468, 38471, 38476, 38480, - 38484, 38487, 38491, 8145, 13391, 38494, 38497, 38503, 38508, 38514, - 38519, 38525, 38530, 38536, 38541, 38547, 38553, 38559, 38564, 38568, - 38572, 38581, 38597, 38613, 38623, 27967, 38630, 38634, 38639, 38644, - 38648, 38652, 35972, 38658, 38663, 38667, 38674, 38679, 38683, 38687, - 26996, 38693, 21451, 38698, 38705, 38713, 38719, 38726, 38734, 38740, - 38744, 38750, 38758, 38762, 38771, 9509, 38779, 38783, 38791, 38798, - 38803, 38808, 38812, 38815, 38819, 38822, 38826, 38833, 38838, 38844, - 26415, 31281, 38848, 38855, 38861, 38867, 38872, 38875, 38877, 38884, - 38891, 38897, 38901, 38904, 38908, 38912, 38916, 38921, 38925, 38929, - 38932, 38936, 38950, 23062, 38969, 38982, 38995, 39008, 23080, 39023, - 10497, 39038, 39044, 39048, 39052, 39059, 39064, 39068, 39075, 39081, - 39086, 39092, 39102, 39114, 39125, 39130, 39137, 39141, 39145, 39148, - 15891, 3677, 39156, 15522, 39169, 39176, 39180, 39184, 39189, 39194, - 39200, 39204, 39208, 39211, 7742, 15533, 39216, 39220, 39226, 39235, - 39240, 39247, 35828, 39253, 39258, 39262, 39267, 39274, 39278, 39281, - 39285, 39290, 14565, 39297, 39304, 1077, 39308, 39313, 39318, 39324, - 39329, 39334, 39338, 39348, 39353, 39359, 39364, 39370, 39375, 39381, - 39391, 39396, 39401, 39405, 7229, 7241, 39410, 39413, 39420, 39426, - 34084, 34091, 39435, 39439, 32041, 39447, 39458, 39466, 36020, 39473, - 39478, 39483, 39494, 39501, 39512, 32065, 21457, 39520, 735, 39525, - 39531, 28051, 39537, 39542, 39552, 39561, 39568, 39574, 39578, 39581, - 39588, 39594, 39601, 39607, 39617, 39625, 39631, 39637, 39642, 39646, - 39653, 39659, 39666, 38917, 535, 13818, 39672, 39677, 39680, 39686, - 39694, 1396, 39699, 39703, 39708, 39715, 39721, 39725, 39729, 39734, - 39743, 39750, 39760, 39766, 28095, 39783, 39792, 39800, 39806, 39811, - 39818, 39824, 39832, 39841, 39849, 39853, 39858, 39866, 32074, 39872, - 39891, 15824, 39905, 39921, 39935, 39941, 39946, 39951, 39956, 39962, - 32080, 39967, 39974, 39979, 39983, 345, 2936, 39990, 39995, 40000, 27322, - 39821, 40004, 40009, 40017, 40021, 40024, 40030, 40036, 40040, 28150, - 40043, 40048, 40052, 40055, 40060, 40064, 40069, 40074, 40078, 40083, - 40087, 40091, 21179, 21190, 40095, 40100, 40106, 26953, 40111, 40115, - 21266, 16072, 40118, 40123, 40128, 40133, 40138, 40143, 40148, 40153, - 450, 49, 31299, 31304, 31309, 31315, 31320, 31325, 40158, 31329, 40162, - 40166, 40170, 31334, 31340, 40184, 31351, 31356, 40192, 40197, 31362, - 40202, 40207, 40212, 40217, 40223, 40229, 40235, 31379, 40248, 40254, - 31383, 40258, 31388, 40263, 31393, 31398, 40266, 40271, 40275, 30948, - 40281, 13599, 40288, 40293, 31403, 40297, 40302, 40307, 40312, 40316, - 40321, 40326, 40332, 40337, 40342, 40348, 40354, 40359, 40363, 40368, - 40373, 40378, 40382, 40387, 40392, 40397, 40403, 40409, 40415, 40420, - 40424, 40429, 40433, 31407, 31412, 31417, 40437, 40441, 40445, 31422, - 31428, 31434, 31446, 40457, 26013, 40461, 40465, 40470, 40475, 40480, - 40485, 40489, 40493, 40503, 40508, 40513, 40517, 40521, 40524, 40532, - 31494, 40537, 1479, 40543, 40551, 40560, 40564, 40568, 40576, 40582, - 40590, 40606, 40610, 40614, 40619, 40634, 31531, 1749, 12055, 40638, - 1378, 40650, 40651, 40659, 40666, 40671, 40678, 40683, 9379, 1119, 10332, - 40690, 40695, 40698, 40701, 40710, 1286, 40715, 39065, 40722, 40727, - 40731, 22503, 2557, 40739, 10741, 40749, 40755, 2337, 2347, 40764, 40773, - 40783, 40794, 3293, 34237, 10384, 3807, 16681, 1291, 40799, 40807, 40814, - 40819, 40823, 40827, 23875, 10411, 40835, 40844, 40853, 40861, 40868, - 40879, 40884, 40897, 40910, 40922, 40934, 40946, 40959, 40970, 40981, - 40991, 40999, 41007, 41019, 41031, 41042, 41051, 41059, 41066, 41078, - 41085, 41094, 41101, 41114, 41119, 41129, 41134, 41140, 41145, 37211, - 41149, 41156, 41160, 41167, 41175, 2518, 41182, 41193, 41203, 41212, - 41220, 41230, 41238, 41248, 41257, 41262, 41268, 41274, 3709, 41285, - 41295, 41304, 41313, 41323, 41331, 41340, 41345, 41350, 41355, 1705, 37, - 41363, 41371, 41382, 41393, 16356, 41403, 41407, 41414, 41420, 41425, - 41429, 41440, 41450, 41459, 41470, 16730, 16735, 41475, 41484, 41489, - 41499, 41504, 41512, 41520, 41527, 41533, 7078, 228, 41537, 41543, 41548, - 41551, 2117, 39181, 41559, 41563, 41566, 1512, 41572, 13980, 1296, 41577, - 41590, 41604, 2643, 41622, 41634, 41646, 2657, 2674, 41660, 41673, 2689, - 41687, 41699, 2704, 41713, 1302, 1308, 1314, 10659, 41718, 41723, 41728, - 41732, 41747, 41762, 41777, 41792, 41807, 41822, 41837, 41852, 41867, - 41882, 41897, 41912, 41927, 41942, 41957, 41972, 41987, 42002, 42017, - 42032, 42047, 42062, 42077, 42092, 42107, 42122, 42137, 42152, 42167, - 42182, 42197, 42212, 42227, 42242, 42257, 42272, 42287, 42302, 42317, - 42332, 42347, 42362, 42377, 42392, 42407, 42422, 42437, 42452, 42467, - 42482, 42497, 42512, 42527, 42542, 42557, 42572, 42587, 42602, 42617, - 42632, 42647, 42662, 42677, 42692, 42707, 42722, 42737, 42752, 42767, - 42782, 42797, 42812, 42827, 42842, 42857, 42872, 42887, 42902, 42917, - 42932, 42947, 42962, 42977, 42992, 43007, 43022, 43037, 43052, 43067, - 43082, 43097, 43112, 43127, 43142, 43157, 43172, 43187, 43202, 43217, - 43232, 43247, 43262, 43277, 43292, 43307, 43322, 43337, 43352, 43367, - 43382, 43397, 43412, 43427, 43442, 43457, 43472, 43487, 43502, 43517, - 43532, 43547, 43562, 43577, 43592, 43607, 43622, 43637, 43652, 43667, - 43682, 43697, 43712, 43727, 43742, 43757, 43772, 43787, 43802, 43817, - 43832, 43847, 43862, 43877, 43892, 43907, 43922, 43937, 43952, 43967, - 43982, 43997, 44012, 44027, 44042, 44057, 44072, 44087, 44102, 44117, - 44132, 44147, 44162, 44177, 44192, 44207, 44222, 44237, 44252, 44267, - 44282, 44297, 44312, 44327, 44342, 44357, 44372, 44387, 44402, 44417, - 44432, 44447, 44462, 44477, 44492, 44507, 44522, 44537, 44552, 44567, - 44582, 44597, 44612, 44627, 44642, 44657, 44672, 44687, 44702, 44717, - 44732, 44747, 44762, 44777, 44792, 44807, 44822, 44837, 44852, 44867, - 44882, 44897, 44912, 44927, 44942, 44957, 44972, 44987, 45002, 45017, - 45032, 45047, 45062, 45077, 45092, 45107, 45122, 45137, 45152, 45167, - 45182, 45197, 45212, 45227, 45242, 45257, 45272, 45287, 45302, 45317, - 45332, 45347, 45362, 45377, 45392, 45407, 45422, 45437, 45452, 45467, - 45482, 45497, 45512, 45527, 45542, 45557, 45572, 45587, 45602, 45617, - 45632, 45647, 45662, 45677, 45692, 45707, 45722, 45737, 45752, 45767, - 45782, 45797, 45812, 45827, 45842, 45857, 45872, 45887, 45902, 45917, - 45932, 45947, 45962, 45977, 45992, 46007, 46022, 46037, 46052, 46067, - 46082, 46097, 46112, 46127, 46142, 46157, 46172, 46187, 46202, 46217, - 46232, 46247, 46262, 46277, 46292, 46307, 46322, 46337, 46352, 46367, - 46382, 46397, 46412, 46427, 46442, 46457, 46472, 46487, 46502, 46517, - 46532, 46547, 46562, 46577, 46592, 46607, 46622, 46637, 46652, 46667, - 46682, 46697, 46712, 46727, 46742, 46757, 46772, 46787, 46802, 46817, - 46832, 46847, 46862, 46877, 46892, 46907, 46922, 46937, 46952, 46967, - 46982, 46997, 47012, 47027, 47042, 47057, 47072, 47087, 47102, 47117, - 47132, 47147, 47162, 47177, 47192, 47207, 47222, 47237, 47252, 47267, - 47282, 47297, 47312, 47327, 47342, 47357, 47372, 47387, 47402, 47417, - 47432, 47447, 47462, 47477, 47492, 47507, 47522, 47537, 47552, 47567, - 47582, 47597, 47612, 47627, 47642, 47657, 47672, 47687, 47702, 47717, - 47732, 47747, 47762, 47777, 47792, 47807, 47822, 47837, 47852, 47867, - 47882, 47897, 47912, 47927, 47942, 47957, 47972, 47987, 48002, 48017, - 48032, 48047, 48062, 48077, 48092, 48107, 48122, 48137, 48152, 48167, - 48182, 48197, 48212, 48227, 48242, 48257, 48272, 48287, 48302, 48317, - 48332, 48347, 48362, 48377, 48392, 48407, 48422, 48437, 48452, 48467, - 48482, 48497, 48512, 48527, 48542, 48557, 48572, 48587, 48602, 48617, - 48632, 48647, 48662, 48677, 48692, 48707, 48722, 48737, 48752, 48767, - 48782, 48797, 48812, 48827, 48842, 48857, 48872, 48887, 48902, 48917, - 48932, 48947, 48962, 48977, 48992, 49007, 49022, 49037, 49052, 49067, - 49082, 49097, 49112, 49127, 49142, 49157, 49172, 49187, 49202, 49217, - 49232, 49247, 49262, 49277, 49292, 49307, 49322, 49337, 49352, 49367, - 49382, 49397, 49412, 49427, 49442, 49457, 49472, 49487, 49502, 49517, - 49532, 49548, 49564, 49580, 49596, 49612, 49628, 49644, 49660, 49676, - 49692, 49708, 49724, 49740, 49756, 49772, 49788, 49804, 49820, 49836, - 49852, 49868, 49884, 49900, 49916, 49932, 49948, 49964, 49980, 49996, - 50012, 50028, 50044, 50060, 50076, 50092, 50108, 50124, 50140, 50156, - 50172, 50188, 50204, 50220, 50236, 50252, 50268, 50284, 50300, 50316, - 50332, 50348, 50364, 50380, 50396, 50412, 50428, 50444, 50460, 50476, - 50492, 50508, 50524, 50540, 50556, 50572, 50588, 50604, 50620, 50636, - 50652, 50668, 50684, 50700, 50716, 50732, 50748, 50764, 50780, 50796, - 50812, 50828, 50844, 50860, 50876, 50892, 50908, 50924, 50940, 50956, - 50972, 50988, 51004, 51020, 51036, 51052, 51068, 51084, 51100, 51116, - 51132, 51148, 51164, 51180, 51196, 51212, 51228, 51244, 51260, 51276, - 51292, 51308, 51324, 51340, 51356, 51372, 51388, 51404, 51420, 51436, - 51452, 51468, 51484, 51500, 51516, 51532, 51548, 51564, 51580, 51596, - 51612, 51628, 51644, 51660, 51676, 51692, 51708, 51724, 51740, 51756, - 51772, 51788, 51804, 51820, 51836, 51852, 51868, 51884, 51900, 51916, - 51932, 51948, 51964, 51980, 51996, 52012, 52028, 52044, 52060, 52076, - 52092, 52108, 52124, 52140, 52156, 52172, 52188, 52204, 52220, 52236, - 52252, 52268, 52284, 52300, 52316, 52332, 52348, 52364, 52380, 52396, - 52412, 52428, 52444, 52460, 52476, 52492, 52508, 52524, 52540, 52556, - 52572, 52588, 52604, 52620, 52636, 52652, 52668, 52684, 52700, 52716, - 52732, 52748, 52764, 52780, 52796, 52812, 52828, 52844, 52860, 52876, - 52892, 52908, 52924, 52940, 52956, 52972, 52988, 53004, 53020, 53036, - 53052, 53068, 53084, 53100, 53116, 53132, 53148, 53164, 53180, 53196, - 53212, 53228, 53244, 53260, 53276, 53292, 53308, 53324, 53340, 53356, - 53372, 53388, 53404, 53420, 53436, 53452, 53468, 53484, 53500, 53516, - 53532, 53548, 53564, 53580, 53596, 53612, 53628, 53644, 53660, 53676, - 53692, 53708, 53724, 53740, 53756, 53772, 53788, 53804, 53820, 53836, - 53852, 53868, 53884, 53900, 53916, 53932, 53948, 53964, 53980, 53996, - 54012, 54028, 54044, 54060, 54076, 54092, 54108, 54124, 54140, 54156, - 54172, 54188, 54204, 54220, 54236, 54252, 54268, 54284, 54300, 54316, - 54332, 54348, 54364, 54380, 54396, 54412, 54428, 54444, 54460, 54476, - 54492, 54508, 54524, 54540, 54556, 54572, 54588, 54604, 54620, 54636, - 54652, 54668, 54684, 54700, 54716, 54732, 54748, 54764, 54780, 54796, - 54812, 54828, 54844, 54860, 54876, 54892, 54908, 54924, 54940, 54956, - 54972, 54988, 55004, 55020, 55036, 55052, 55068, 55084, 55100, 55116, - 55132, 55148, 55164, 55180, 55196, 55212, 55228, 55244, 55260, 55276, - 55292, 55308, 55324, 55340, 55356, 55372, 55388, 55404, 55420, 55436, - 55452, 55468, 55484, 55500, 55516, 55532, 55548, 55564, 55580, 55596, - 55612, 55628, 55644, 55660, 55676, 55692, 55708, 55724, 55740, 55756, - 55772, 55788, 55804, 55820, 55836, 55852, 55868, 55884, 55900, 55916, - 55932, 55948, 55964, 55980, 55996, 56012, 56028, 56044, 56060, 56076, - 56092, 56108, 56124, 56140, 56156, 56172, 56188, 56204, 56220, 56236, - 56252, 56268, 56284, 56300, 56316, 56332, 56348, 56364, 56380, 56396, - 56412, 56428, 56444, 56460, 56476, 56492, 56508, 56524, 56540, 56556, - 56572, 56588, 56604, 56620, 56636, 56652, 56668, 56684, 56700, 56716, - 56732, 56748, 56764, 56780, 56796, 56812, 56828, 56844, 56860, 56876, - 56892, 56908, 56924, 56940, 56956, 56972, 56988, 57004, 57020, 57036, - 57052, 57068, 57084, 57100, 57116, 57132, 57148, 57164, 57180, 57196, - 57212, 57228, 57244, 57260, 57276, 57292, 57308, 57324, 57340, 57356, - 57372, 57388, 57404, 57420, 57436, 57452, 57468, 57484, 57500, 57516, - 57532, 57548, 57564, 57580, 57596, 57612, 57628, 57644, 57660, 57676, - 57692, 57708, 57724, 57740, 57756, 57772, 57788, 57804, 57820, 57836, - 57852, 57868, 57884, 57900, 57916, 57932, 57948, 57964, 57980, 57996, - 58012, 58028, 58044, 58060, 58076, 58092, 58108, 58124, 58140, 58156, - 58172, 58188, 58204, 58219, 16762, 58228, 58234, 58240, 58250, 58258, - 14894, 15445, 9960, 58271, 1520, 58279, 3761, 27432, 7183, 58285, 58290, - 58295, 58300, 58305, 58311, 58316, 58322, 58327, 58333, 58338, 58343, - 58348, 58353, 58359, 58364, 58369, 58374, 58379, 58384, 58389, 58394, - 58400, 58405, 58411, 58418, 2561, 58423, 58429, 8526, 58433, 58438, - 58445, 58453, 40, 58457, 58463, 58468, 58473, 58477, 58482, 58486, 58490, - 10684, 58494, 58504, 58517, 58528, 58541, 58548, 58554, 58559, 58565, - 58571, 58577, 58582, 58587, 58592, 58597, 58601, 58606, 58611, 58616, - 58622, 58628, 58634, 58639, 58643, 58648, 58653, 58657, 58662, 58667, - 58672, 58676, 10700, 10711, 10716, 1563, 58680, 1568, 58686, 16239, - 58689, 58695, 1599, 58701, 1605, 1611, 10746, 58706, 58714, 58721, 58725, - 58731, 58736, 30977, 58741, 58748, 58753, 58757, 58761, 1616, 16331, - 58770, 58774, 16342, 1125, 58778, 58785, 58790, 58794, 16367, 1620, - 37350, 58797, 58802, 58812, 58821, 58826, 58830, 58836, 1625, 39259, - 58841, 58850, 58856, 58861, 10904, 10910, 58867, 58879, 58896, 58913, - 58930, 58947, 58964, 58981, 58998, 59015, 59032, 59049, 59066, 59083, - 59100, 59117, 59134, 59151, 59168, 59185, 59202, 59219, 59236, 59253, - 59270, 59287, 59304, 59321, 59338, 59355, 59372, 59389, 59406, 59423, - 59440, 59457, 59474, 59491, 59508, 59525, 59542, 59559, 59576, 59593, - 59610, 59627, 59644, 59661, 59678, 59695, 59712, 59723, 59728, 1630, - 59732, 59738, 59743, 59748, 9326, 1635, 59754, 59763, 27731, 59768, - 59779, 59789, 59794, 59801, 59807, 59812, 59817, 16619, 59821, 10921, - 1640, 10926, 59827, 59832, 59838, 59843, 59848, 59853, 59858, 59863, - 59868, 59873, 59879, 59885, 59891, 59896, 59900, 59905, 59910, 59914, - 59919, 59924, 59929, 59933, 59938, 59944, 59949, 59954, 59958, 59963, - 59968, 59974, 59979, 59984, 59990, 59996, 60001, 60005, 60010, 60015, - 60020, 60024, 60029, 60034, 60039, 60045, 60051, 60056, 60060, 60064, - 60069, 60074, 60079, 29129, 60083, 60088, 60093, 60099, 60104, 60109, - 60113, 60118, 60123, 60129, 60134, 60139, 60145, 60151, 60156, 60160, - 60165, 60170, 60174, 60179, 60184, 60189, 60195, 60201, 60206, 60210, - 60215, 60220, 60224, 60229, 60234, 60239, 60243, 60246, 31639, 60251, - 60259, 16685, 3663, 11017, 60265, 60275, 60290, 11022, 60301, 60306, - 60317, 60329, 60341, 60353, 2695, 60365, 60370, 60382, 60386, 60392, - 60398, 60403, 1652, 1078, 60412, 60417, 39309, 60421, 60425, 60430, - 60434, 16770, 60439, 60442, 60450, 60458, 1656, 11047, 11053, 1661, - 60466, 60473, 60478, 60487, 60497, 60504, 60509, 60514, 1666, 60521, - 60526, 16885, 60530, 60535, 60542, 60548, 60552, 60563, 60573, 16907, - 9234, 9241, 1671, 60580, 60586, 60594, 60601, 60607, 60614, 60626, 60632, - 60637, 60649, 60660, 60669, 60679, 3740, 30813, 30822, 16947, 1676, 1680, - 60687, 60698, 60703, 1683, 60711, 60716, 16998, 60728, 60734, 60739, - 60747, 1688, 60752, 60757, 60765, 60773, 60780, 60789, 60797, 60806, - 1693, 60810, 1698, 60815, 60822, 17072, 60830, 60836, 60841, 60849, - 60856, 60864, 22574, 60869, 11182, 60878, 60884, 60891, 60898, 60904, - 60914, 60920, 60925, 60936, 60941, 60949, 11191, 11196, 60957, 60963, - 60971, 3805, 17114, 39397, 60976, 60982, 60987, 60995, 61002, 12036, - 61007, 61013, 1709, 61018, 61021, 1132, 61027, 61032, 61037, 61043, - 61048, 61053, 61058, 61063, 61068, 61073, 1718, 9, 61079, 61083, 61088, - 61092, 61096, 61100, 31879, 61105, 61110, 61115, 61119, 61122, 61126, - 61130, 61135, 61139, 61144, 61148, 34616, 34621, 34626, 61151, 61158, - 61164, 39118, 61174, 34632, 32137, 31894, 31900, 34648, 31906, 61179, - 61184, 32170, 61188, 61191, 61195, 61202, 61205, 61210, 61214, 61218, - 61221, 61231, 61243, 61250, 61256, 61263, 33573, 61266, 8543, 877, 61269, - 61273, 61278, 3690, 61282, 61285, 13632, 61292, 61299, 61312, 61320, - 61329, 61338, 61343, 61353, 61366, 61378, 61385, 61390, 61399, 61412, - 36060, 61430, 61435, 61442, 61448, 656, 61453, 61461, 61468, 27271, 627, - 61474, 61480, 61490, 61496, 61501, 31924, 6003, 31938, 61505, 61515, - 61520, 61530, 61545, 61551, 61557, 31948, 61562, 31094, 61566, 61571, - 61576, 61580, 61585, 16950, 61592, 61597, 61601, 6044, 31974, 61605, - 61611, 312, 61621, 61628, 61635, 61640, 61649, 58806, 61655, 61663, - 61667, 61671, 61675, 61679, 61684, 61688, 61694, 61702, 61707, 61712, - 61716, 61721, 61725, 61729, 61735, 61741, 61746, 61750, 32098, 61755, - 32104, 32110, 61760, 61766, 61773, 61778, 61782, 31111, 16612, 61785, - 61789, 61794, 61801, 61807, 61811, 61816, 38828, 61822, 61826, 61830, - 61835, 61841, 61847, 61859, 61868, 61878, 61884, 61891, 61896, 61901, - 61905, 61908, 61914, 61921, 61926, 61931, 61938, 61945, 61951, 61956, - 61961, 61969, 32115, 2423, 61974, 61979, 61985, 61990, 61996, 62001, - 62006, 62011, 62017, 32136, 62022, 62028, 62034, 62040, 32200, 62045, - 62050, 62055, 32211, 62060, 62065, 62070, 62076, 62082, 32216, 62087, - 62092, 62097, 32271, 32277, 62102, 62107, 32282, 62112, 27958, 32304, - 32308, 62117, 62093, 62121, 62129, 62135, 62143, 62150, 62156, 62166, - 62172, 62179, 10631, 32322, 62185, 62198, 62207, 62213, 62222, 62228, - 23512, 62235, 62242, 62252, 32272, 62255, 62262, 62267, 62271, 62275, - 62280, 6120, 62284, 62289, 62294, 34710, 34715, 62298, 34729, 62303, - 34734, 62308, 62314, 34746, 34752, 34758, 62319, 62325, 22539, 62336, - 62339, 62351, 62359, 32345, 62363, 62372, 62382, 62391, 32355, 62396, - 62403, 62412, 62418, 62426, 62433, 6095, 4397, 62438, 32283, 62444, - 62447, 62453, 62460, 62465, 62470, 23422, 62474, 62480, 62486, 62491, - 62496, 62500, 62506, 62512, 33483, 863, 35723, 36644, 36650, 32391, - 62517, 62521, 62525, 62528, 62541, 62547, 62551, 62554, 62559, 33786, - 62563, 31116, 21287, 62569, 6024, 6032, 9075, 62572, 62577, 62582, 62587, - 62592, 62597, 62602, 62607, 62612, 62617, 62623, 62628, 62633, 62639, - 62644, 62649, 62654, 62659, 62664, 62669, 62675, 62680, 62686, 62691, - 62696, 62701, 62706, 62711, 62716, 62721, 62726, 62731, 62736, 62742, - 62747, 62752, 62757, 62762, 62767, 62772, 62778, 62783, 62788, 62793, - 62798, 62803, 62808, 62813, 62818, 62823, 62829, 62834, 62839, 62844, - 62849, 62855, 62861, 62866, 62872, 62877, 62882, 62887, 62892, 62897, - 1513, 245, 62902, 62906, 62910, 62914, 25133, 62918, 62922, 62927, 62931, - 62936, 62940, 62945, 62950, 62955, 62959, 62963, 62968, 62972, 13369, - 62977, 62981, 62988, 62998, 15206, 63007, 63016, 63020, 63025, 63030, - 63034, 24924, 3019, 63038, 63044, 17363, 63048, 63057, 63065, 63071, - 63083, 63095, 63099, 63104, 63108, 63114, 63120, 63125, 63135, 63145, - 63151, 63156, 63160, 63165, 63171, 63180, 63189, 63197, 15560, 63201, - 63210, 63218, 63230, 63241, 63252, 63261, 63265, 63274, 63284, 63292, - 63298, 63303, 63309, 63314, 98, 30925, 63325, 26266, 26276, 63331, 63338, - 63344, 63348, 63358, 63369, 63377, 63386, 63391, 63396, 63400, 17317, - 63408, 63412, 63418, 63428, 63435, 63441, 34809, 63447, 63449, 63452, - 63456, 63466, 63472, 63479, 13315, 63486, 63492, 63501, 63510, 63516, - 63522, 63528, 63533, 63540, 63547, 63553, 63566, 63575, 63584, 63589, - 63593, 63599, 63606, 63613, 63620, 63627, 63634, 63639, 63643, 63647, - 63650, 63660, 63664, 63676, 63685, 63689, 63694, 63698, 63704, 63709, - 63716, 63725, 63733, 63741, 63746, 63750, 63755, 63760, 63770, 63778, - 63783, 63787, 63791, 63797, 63809, 63817, 63827, 63834, 63840, 63845, - 63849, 63853, 63857, 63866, 63875, 63884, 63890, 63896, 63902, 63907, - 63914, 63920, 63928, 63935, 12463, 63941, 63947, 63951, 14244, 63955, - 63960, 63970, 63979, 63985, 63991, 63999, 64006, 64010, 64014, 64020, - 64028, 64035, 64041, 64052, 64056, 64060, 64064, 64067, 64073, 64078, - 64082, 64086, 64095, 64103, 64110, 64116, 64123, 24046, 38870, 64128, - 64136, 64140, 64144, 64147, 64155, 64162, 64168, 64177, 64185, 64191, - 64196, 64200, 64205, 64209, 64213, 64218, 64227, 64231, 64238, 64245, - 64251, 64259, 64265, 64276, 64284, 64290, 22669, 64299, 64306, 64313, - 64320, 64327, 64334, 41907, 13153, 64341, 64348, 64353, 34845, 6217, - 64359, 64364, 64369, 64375, 64381, 64387, 64392, 64397, 64402, 64407, - 64413, 64418, 64424, 64429, 64435, 64440, 64445, 64450, 64455, 64460, - 64465, 64470, 64476, 64481, 64487, 64492, 64497, 64502, 64507, 64512, - 64517, 64523, 64528, 64533, 64538, 64543, 64548, 64553, 64558, 64563, - 64568, 64573, 64579, 64584, 64589, 64594, 64599, 64604, 64609, 64614, - 64619, 64625, 64630, 64635, 64640, 64645, 64650, 64655, 64660, 64665, - 64670, 64675, 64680, 64685, 64691, 1834, 224, 37446, 64696, 64699, 64704, - 64708, 64711, 64716, 63737, 64727, 64737, 64744, 64760, 64769, 64779, - 64789, 64797, 64811, 64819, 64823, 64826, 64833, 64839, 64850, 64862, - 64873, 64882, 64889, 1297, 23311, 64899, 2590, 64903, 64912, 1138, 17290, - 38083, 64920, 64928, 64942, 64955, 64959, 64964, 64969, 64974, 64980, - 64986, 64991, 8535, 64996, 65000, 65008, 11048, 65013, 65019, 65028, - 1721, 11060, 736, 65032, 65041, 65051, 27030, 65060, 65066, 16862, 65072, - 65076, 3964, 11391, 65082, 65089, 60693, 65093, 65097, 3988, 189, 14159, - 65103, 65115, 65119, 65125, 27751, 65129, 11379, 2730, 4, 65134, 65144, - 65150, 65161, 65168, 65174, 65180, 65188, 65195, 65201, 65211, 65221, - 65231, 23499, 1309, 65240, 65244, 65248, 65254, 65258, 2753, 2759, 8532, - 2264, 65262, 65266, 65275, 65283, 65294, 65302, 65310, 65316, 65321, - 65332, 65343, 65351, 65357, 9694, 65362, 65370, 65374, 65378, 65382, - 65394, 28136, 65401, 65411, 65417, 65423, 9796, 65433, 65444, 65454, - 65463, 65467, 65474, 1140, 1170, 65484, 65489, 65497, 65505, 65516, - 65523, 65537, 14088, 393, 65547, 65551, 65559, 65568, 65576, 65582, - 65596, 65603, 65609, 65618, 65625, 65635, 65643, 3812, 156, 65651, 65662, - 65666, 65678, 27949, 161, 65684, 65689, 65693, 65700, 65706, 65714, - 65721, 8818, 65728, 65737, 65745, 3878, 65758, 8199, 65762, 2798, 443, - 65767, 65780, 65785, 1833, 650, 65789, 3895, 65797, 65803, 65807, 931, - 65817, 65826, 65831, 14928, 14935, 45269, 65835, 3822, 13041, 65843, - 65850, 23555, 65854, 65861, 65867, 65872, 65877, 14948, 372, 65882, - 65894, 65900, 65908, 2810, 1753, 65916, 65918, 65923, 65928, 65933, - 65939, 65944, 65949, 65954, 65959, 65964, 65969, 65975, 65980, 65985, - 65990, 65995, 66000, 66005, 66010, 66015, 66021, 66026, 66031, 66036, - 66042, 66047, 66053, 66058, 66063, 66068, 66073, 66078, 66083, 66088, - 66094, 66099, 66105, 66110, 66115, 66120, 66125, 66130, 66135, 66140, - 66145, 66151, 66156, 66161, 66166, 66170, 66174, 66179, 66183, 66188, - 66193, 66199, 66204, 66208, 66213, 66217, 66220, 66222, 66226, 66229, - 66234, 66238, 66242, 66246, 66250, 66259, 66263, 32549, 66266, 32554, - 66273, 66278, 32559, 66287, 66296, 32565, 66301, 32570, 66310, 66315, - 11578, 66319, 66324, 66329, 32575, 66333, 40225, 66337, 66340, 66344, - 8211, 66350, 66355, 66359, 3705, 32580, 66362, 66366, 66369, 66374, - 66378, 66384, 66392, 66405, 66414, 66420, 66425, 66431, 66435, 66441, - 66449, 66454, 66458, 66465, 66471, 66479, 66488, 66496, 32583, 66503, - 66513, 66522, 66535, 66540, 66545, 66554, 66560, 66567, 66578, 66590, - 66597, 66606, 66615, 66624, 66631, 66637, 66644, 66652, 66659, 66667, - 66676, 66684, 66691, 66699, 66708, 66716, 66725, 66735, 66744, 66752, - 66759, 66767, 66776, 66784, 66793, 66803, 66812, 66820, 66829, 66839, - 66848, 66858, 66869, 66879, 66888, 66896, 66903, 66911, 66920, 66928, - 66937, 66947, 66956, 66964, 66973, 66983, 66992, 67002, 67013, 67023, - 67032, 67040, 67049, 67059, 67068, 67078, 67089, 67099, 67108, 67118, - 67129, 67139, 67150, 67162, 67173, 67183, 67192, 67200, 67207, 67215, - 67224, 67232, 67241, 67251, 67260, 67268, 67277, 67287, 67296, 67306, - 67317, 67327, 67336, 67344, 67353, 67363, 67372, 67382, 67393, 67403, - 67412, 67422, 67433, 67443, 67454, 67466, 67477, 67487, 67496, 67504, - 67513, 67523, 67532, 67542, 67553, 67563, 67572, 67582, 67593, 67603, - 67614, 67626, 67637, 67647, 67656, 67666, 67677, 67687, 67698, 67710, - 67721, 67731, 67742, 67754, 67765, 67777, 67790, 67802, 67813, 67823, - 67832, 67840, 67847, 67855, 67864, 67872, 67881, 67891, 67900, 67908, - 67917, 67927, 67936, 67946, 67957, 67967, 67976, 67984, 67993, 68003, - 68012, 68022, 68033, 68043, 68052, 68062, 68073, 68083, 68094, 68106, - 68117, 68127, 68136, 68144, 68153, 68163, 68172, 68182, 68193, 68203, - 68212, 68222, 68233, 68243, 68254, 68266, 68277, 68287, 68296, 68306, - 68317, 68327, 68338, 68350, 68361, 68371, 68382, 68394, 68405, 68417, - 68430, 68442, 68453, 68463, 68472, 68480, 68489, 68499, 68508, 68518, - 68529, 68539, 68548, 68558, 68569, 68579, 68590, 68602, 68613, 68623, - 68632, 68642, 68653, 68663, 68674, 68686, 68697, 68707, 68718, 68730, - 68741, 68753, 68766, 68778, 68789, 68799, 68808, 68818, 68829, 68839, - 68850, 68862, 68873, 68883, 68894, 68906, 68917, 68929, 68942, 68954, - 68965, 68975, 68986, 68998, 69009, 69021, 69034, 69046, 69057, 69069, - 69082, 69094, 69107, 69121, 69134, 69146, 69157, 69167, 69176, 69184, - 69191, 69196, 8058, 69203, 32593, 69208, 69213, 32598, 69219, 20929, - 32603, 69224, 69230, 69238, 69244, 69250, 69257, 69264, 69269, 69273, - 69276, 69280, 69289, 69295, 69307, 69318, 69322, 3081, 8033, 69327, - 69330, 69332, 69336, 69340, 69344, 69350, 69355, 25944, 69360, 69364, - 69367, 69372, 69376, 69383, 69389, 69393, 6170, 69397, 32620, 69402, - 69409, 69418, 69426, 69437, 69445, 69453, 69460, 69467, 69473, 69484, - 32625, 69489, 69500, 69512, 69520, 69531, 69540, 69551, 69556, 69564, - 2556, 69569, 34295, 69582, 69586, 69598, 69606, 69611, 69619, 17485, - 69630, 69636, 69643, 69651, 69657, 32635, 69662, 3914, 58254, 69669, - 69672, 69680, 69693, 69706, 69719, 69732, 69739, 69750, 69759, 41724, - 41729, 69764, 69768, 69776, 69783, 69792, 69800, 69806, 69815, 69823, - 69831, 69835, 69844, 69853, 69863, 69876, 69889, 69899, 32640, 69905, - 69912, 69918, 32646, 69923, 69926, 69930, 69938, 69947, 41462, 69955, - 69964, 69972, 69979, 69987, 69997, 70006, 70015, 70024, 70032, 70043, - 70053, 9366, 21567, 70062, 70067, 70072, 70076, 70080, 70085, 70091, - 70096, 70101, 70107, 70112, 70117, 21532, 70122, 70129, 70137, 70145, - 70150, 70157, 70164, 70169, 70173, 70177, 70185, 70193, 32663, 70199, - 70205, 70217, 70223, 70227, 70234, 70239, 70250, 70260, 70270, 70282, - 70288, 70298, 70308, 32690, 70317, 70326, 70332, 70344, 70355, 70362, - 70367, 70371, 70379, 70385, 70390, 70395, 70402, 70410, 70422, 70432, - 70441, 70450, 70457, 34157, 23851, 70463, 70468, 70472, 70476, 70481, - 70487, 70498, 70511, 70516, 70523, 32695, 70528, 70540, 70549, 70559, - 70570, 70583, 70590, 70599, 70608, 70616, 70621, 70627, 1069, 70632, - 70637, 70642, 70647, 70653, 70658, 70663, 70669, 70675, 70680, 70684, - 70689, 70694, 70699, 58766, 70704, 70709, 70714, 70719, 70725, 70731, - 70736, 70740, 70745, 70750, 70755, 70761, 70766, 70772, 70777, 70782, - 70787, 70792, 70796, 70802, 70807, 70816, 70821, 70826, 70831, 70836, - 70840, 70847, 70853, 17135, 17142, 70858, 70862, 70866, 70870, 70874, - 45524, 70878, 70808, 70880, 70890, 32704, 70893, 70902, 70908, 6143, - 32709, 70912, 70918, 70923, 70929, 70934, 70938, 70945, 70950, 70960, - 70969, 70973, 70979, 70985, 70991, 70995, 71003, 71010, 71018, 71026, - 32714, 71033, 71036, 71043, 71049, 71054, 71058, 71064, 71071, 71076, - 71080, 71089, 71097, 71103, 71108, 32719, 71115, 71122, 71128, 71133, - 71139, 71146, 71152, 21294, 27455, 71158, 71163, 71169, 71181, 70841, - 70848, 21470, 71191, 71196, 71203, 71209, 71216, 71222, 71233, 71238, - 9110, 71246, 71249, 71255, 71259, 71263, 71266, 71272, 32468, 6194, 964, - 13419, 71279, 71285, 71291, 71297, 71303, 71309, 71315, 71321, 71327, - 71332, 71337, 71342, 71347, 71352, 71357, 71362, 71367, 71372, 71377, - 71382, 71387, 71392, 71398, 71403, 71408, 71414, 71419, 71424, 71430, - 71436, 71442, 71448, 71454, 71460, 71466, 71472, 71478, 71483, 71488, - 71494, 71499, 71504, 71510, 71515, 71520, 71525, 71530, 71535, 71540, - 71545, 71550, 71555, 71560, 71565, 71570, 71576, 71581, 71586, 71591, - 71597, 71602, 71607, 71612, 71617, 71623, 71628, 71633, 71638, 71643, - 71648, 71653, 71658, 71663, 71668, 71673, 71678, 71683, 71688, 71693, - 71698, 71703, 71708, 71713, 71718, 71724, 71729, 71734, 71739, 71744, - 71749, 71754, 71759, 1864, 142, 71764, 71768, 71772, 71777, 71785, 71789, - 71796, 71804, 71808, 71821, 71829, 71833, 71836, 71841, 71845, 71850, - 71854, 71862, 71866, 20937, 71871, 71875, 60967, 71879, 71882, 71890, - 71898, 71906, 71911, 71918, 71924, 71930, 71935, 71942, 71947, 71955, - 64947, 71962, 71967, 71972, 71976, 11645, 71980, 71985, 71990, 71994, - 71997, 72003, 72007, 72017, 72026, 72029, 72033, 72040, 72053, 72059, - 72067, 72078, 72089, 72100, 72111, 72120, 72126, 72135, 72143, 72153, - 72166, 72173, 72184, 72190, 72195, 72200, 72206, 72212, 72222, 72231, - 70530, 72239, 72245, 72253, 72259, 72267, 72270, 72274, 72278, 72281, - 72287, 72293, 72301, 72313, 72325, 72332, 72336, 72347, 72355, 72362, - 72374, 72382, 72390, 72397, 72403, 72413, 72422, 72427, 72437, 72446, - 40788, 72453, 72457, 72462, 72470, 72477, 72483, 72487, 72497, 72508, - 72516, 72523, 72535, 72547, 72556, 69572, 72563, 72574, 72588, 72596, - 72606, 72613, 72621, 72633, 72642, 72650, 72660, 72671, 72683, 72692, - 72702, 72709, 72718, 72733, 72741, 72751, 72760, 72768, 72781, 72796, - 72800, 72809, 72821, 72832, 72843, 72854, 72864, 72875, 72883, 72889, - 72899, 72907, 72913, 29028, 72918, 72924, 72929, 72936, 9708, 17505, - 72942, 72951, 72956, 72960, 72967, 72973, 72978, 72983, 72991, 72999, - 73003, 73006, 73009, 73011, 73018, 73024, 73035, 73040, 73044, 73051, - 73057, 73062, 73070, 65446, 65456, 73076, 73083, 73093, 10618, 73100, - 73105, 29224, 73114, 73119, 73126, 73136, 73144, 73152, 73161, 73167, - 73173, 73180, 73187, 73192, 73196, 73204, 73209, 73214, 73222, 73229, - 73234, 73240, 73243, 73247, 73256, 71816, 73265, 73269, 73275, 73286, - 73296, 17514, 73307, 73315, 17526, 73322, 73326, 73335, 27341, 73342, - 73346, 73351, 73368, 73380, 10576, 73392, 73397, 73402, 73407, 21010, - 73411, 73416, 73421, 73427, 73432, 5846, 21014, 73437, 73442, 73448, - 73455, 73460, 73465, 73471, 73477, 73483, 73488, 73494, 73498, 73512, - 73520, 73528, 73534, 73539, 73546, 73556, 73565, 73570, 73575, 73583, - 73588, 73594, 73599, 73608, 59823, 73613, 73616, 73634, 73653, 73666, - 73680, 73696, 73703, 73710, 73716, 73723, 73728, 73734, 73740, 73748, - 73754, 73759, 73764, 73780, 10589, 73794, 73801, 73809, 73815, 73819, - 73822, 73827, 73832, 73839, 73844, 73853, 73858, 73864, 73873, 73882, - 73887, 73891, 73899, 73908, 11674, 73917, 73925, 73930, 73936, 11685, - 73941, 73944, 73949, 73959, 73968, 73973, 73979, 73984, 73992, 73999, - 74010, 74020, 74025, 64875, 74030, 74036, 74041, 74048, 74057, 74065, - 74071, 74077, 74084, 74090, 74094, 16960, 3055, 74099, 74103, 74107, - 74113, 74122, 74128, 74135, 74139, 74160, 74182, 74198, 74215, 74234, - 74243, 74253, 74260, 74267, 27228, 74273, 74277, 74285, 74297, 74303, - 74311, 74315, 74323, 74330, 74334, 74340, 74346, 74351, 3563, 41924, - 74357, 74361, 74365, 74369, 74374, 74379, 74384, 74390, 74396, 74402, - 74409, 74415, 74422, 74428, 74434, 74439, 74445, 74450, 74454, 74459, - 74463, 74468, 41939, 74472, 74477, 74485, 74489, 74494, 74501, 74510, - 74516, 74520, 74527, 74531, 74534, 74541, 74550, 74555, 74559, 74567, - 74576, 74580, 74588, 74594, 74599, 74604, 74610, 74616, 74621, 74625, - 74631, 74636, 74640, 74644, 74647, 74652, 74660, 74670, 74675, 39416, - 74683, 74695, 74699, 74705, 74717, 74728, 74735, 74741, 74748, 74760, - 74767, 74773, 21088, 74777, 74783, 74790, 74796, 74802, 74807, 74812, - 74817, 74826, 7033, 74831, 16426, 74837, 74841, 74845, 74849, 74857, - 74866, 74870, 74877, 74886, 74899, 74905, 74464, 30088, 74910, 74912, - 74917, 74922, 74927, 74932, 74937, 74942, 74947, 74952, 74957, 74962, - 74967, 74972, 74977, 74982, 74988, 74993, 74998, 75003, 75008, 75013, - 75018, 75023, 75028, 75034, 75040, 75046, 75051, 75056, 75068, 75073, - 1870, 46, 75078, 75083, 32746, 75087, 32751, 32756, 32762, 32767, 75091, - 32772, 22083, 75113, 75117, 75121, 75126, 75130, 32776, 75134, 75142, - 32781, 75149, 75152, 75157, 75161, 9543, 75170, 32786, 21945, 75173, - 75177, 1428, 75182, 32797, 75185, 75190, 25737, 25747, 35258, 75195, - 75200, 75205, 75210, 75216, 75221, 75230, 75235, 75242, 75248, 75253, - 75258, 75263, 75273, 75282, 75287, 75295, 75299, 75307, 32611, 37317, - 75314, 75320, 75325, 75330, 12016, 75335, 75341, 75346, 75353, 75359, - 75364, 75372, 75382, 75392, 75398, 75403, 75409, 17536, 75416, 36073, - 75429, 75434, 75440, 30993, 75453, 75459, 75463, 75472, 75479, 75485, - 75493, 75502, 75509, 75515, 75518, 75522, 25878, 75526, 75533, 75539, - 75547, 75552, 23994, 75558, 75561, 75569, 75577, 75591, 75598, 75604, - 75611, 75617, 32811, 75621, 75628, 75636, 75644, 75650, 32816, 75658, - 75664, 75669, 75679, 75685, 75694, 30830, 34716, 75702, 75707, 75712, - 75716, 75721, 75725, 75733, 14920, 39429, 75738, 75743, 32821, 62269, - 75747, 75752, 75756, 75765, 75773, 75779, 75784, 75790, 75797, 75803, - 75808, 75813, 75822, 75834, 75849, 33083, 75855, 16545, 32825, 75859, - 75866, 24104, 75872, 75879, 75888, 75895, 75904, 75910, 75915, 75923, - 75929, 32835, 75934, 75943, 74723, 75952, 75959, 75965, 75971, 75981, - 75989, 75996, 76000, 32840, 76003, 32846, 32852, 76008, 76016, 76024, - 76034, 76043, 76051, 76058, 76068, 32857, 76072, 76074, 76078, 76083, - 76087, 76091, 76097, 76102, 76106, 76117, 76122, 76127, 3060, 76131, - 76138, 76142, 76151, 76159, 76166, 76171, 76176, 62315, 76180, 76183, - 76189, 76197, 76203, 76207, 76212, 76219, 76224, 76230, 34747, 76235, - 76238, 76243, 76247, 76252, 76257, 76261, 76269, 76273, 25756, 25765, - 76279, 76285, 76291, 76296, 76300, 76303, 76313, 76322, 76327, 76333, - 76340, 76346, 76350, 76358, 76363, 34753, 76367, 76375, 76381, 76388, - 76393, 76397, 76402, 58440, 34759, 76408, 76413, 76417, 76422, 76427, - 76432, 76436, 76441, 76446, 76452, 76457, 76462, 76468, 76474, 76479, - 76483, 76488, 76493, 76498, 76502, 24103, 76507, 76512, 76518, 76524, - 76530, 76535, 76539, 76544, 76549, 76554, 76558, 76563, 76568, 76573, - 76578, 76582, 32865, 76590, 76594, 76602, 76610, 76621, 76626, 76630, - 22397, 76635, 76641, 76651, 76658, 76663, 76672, 76677, 76681, 76686, - 76694, 76702, 76709, 65109, 76715, 76723, 76730, 76741, 76747, 76751, - 76757, 32875, 76760, 76767, 76775, 76780, 39620, 76784, 76789, 76796, - 76801, 8992, 76805, 76813, 76820, 76827, 76833, 76847, 63381, 76855, - 76861, 76865, 76868, 76876, 76883, 76888, 76901, 76908, 76912, 76919, - 76924, 60860, 76929, 76932, 76939, 76945, 76949, 76957, 76966, 76976, - 76986, 76995, 77003, 77014, 77019, 77023, 77028, 77032, 35389, 77040, - 21357, 35398, 77045, 77050, 77055, 77060, 77065, 77070, 77075, 77079, - 77084, 77089, 77094, 77099, 77104, 77109, 77113, 77118, 77123, 77127, - 77131, 77135, 77139, 77144, 77149, 77153, 77158, 77162, 77166, 77171, - 77176, 77181, 77186, 77190, 77195, 77200, 77204, 77209, 77214, 77219, - 77224, 77229, 77234, 77239, 77244, 77249, 77254, 77259, 77264, 77269, - 77274, 77279, 77284, 77289, 77294, 77299, 77304, 77308, 77313, 77318, - 77323, 77328, 77333, 77338, 77343, 77348, 77353, 77358, 77363, 77367, - 77372, 77376, 77381, 77386, 77391, 77396, 77401, 77406, 77411, 77416, - 77421, 77425, 77429, 77434, 77439, 77443, 77448, 77453, 77457, 77462, - 77467, 77472, 77477, 77481, 77486, 77491, 77495, 77500, 77504, 77508, - 77512, 77516, 77521, 77525, 77529, 77533, 77537, 77541, 77545, 77549, - 77553, 77557, 77562, 77567, 77572, 77577, 77582, 77587, 77592, 77597, - 77602, 77607, 77611, 77615, 77619, 77623, 77627, 77631, 77636, 77640, - 77645, 77649, 77654, 77659, 77663, 77667, 77672, 77676, 77680, 77684, - 77688, 77692, 77696, 77700, 77704, 77708, 77712, 77716, 77720, 77724, - 77728, 77733, 77738, 77742, 77746, 77750, 77754, 77758, 77762, 77767, - 77771, 77775, 77779, 77783, 77787, 77791, 77796, 77800, 77805, 77809, - 77813, 77817, 77821, 77825, 77829, 77833, 77837, 77841, 77845, 77849, - 77854, 77858, 77862, 77866, 77870, 77874, 77878, 77882, 77886, 77890, - 77894, 77898, 77903, 77907, 77911, 77916, 77921, 77925, 77929, 77933, - 77937, 77941, 77945, 77949, 77953, 77958, 77962, 77967, 77971, 77976, - 77980, 77985, 77989, 77995, 78000, 78004, 78009, 78013, 78018, 78022, - 78027, 78031, 78036, 1521, 78040, 2824, 1759, 1764, 78044, 78048, 2828, - 78052, 1397, 78057, 1342, 78061, 2840, 78065, 78072, 78079, 78093, 2844, - 7131, 78102, 78110, 78117, 78128, 78137, 78144, 78156, 78169, 78182, - 78193, 78198, 78205, 78217, 78221, 2848, 11747, 78231, 78236, 78245, - 78255, 2852, 78260, 78264, 78269, 78276, 78282, 78290, 78302, 1347, - 13042, 78312, 78316, 78322, 78336, 78348, 78360, 78370, 78379, 78388, - 78397, 78405, 78416, 78424, 4051, 78434, 78445, 78454, 78460, 78475, - 78482, 78488, 35514, 78493, 2876, 13046, 78497, 78504, 8930, 78513, 2881, - 32361, 78519, 60609, 78526, 78532, 78543, 78549, 78556, 78562, 78570, - 78577, 78583, 78593, 78602, 78613, 78620, 78626, 78636, 78644, 78650, - 78665, 78671, 78676, 78683, 78686, 78692, 78699, 78705, 78713, 78722, - 78730, 78736, 78745, 41464, 78759, 78764, 78770, 14757, 78775, 78788, - 78797, 78805, 78812, 78816, 78820, 78823, 78830, 78837, 78845, 78853, - 78862, 78870, 14684, 78878, 78883, 78887, 78899, 78906, 78915, 748, - 78925, 78934, 78945, 2897, 78949, 78953, 78959, 78972, 78984, 78994, - 79003, 79015, 26369, 79026, 79034, 79043, 79054, 79065, 79075, 79085, - 79094, 79102, 11312, 79109, 79113, 79116, 79121, 79126, 79130, 79136, - 1352, 11818, 79143, 79154, 79163, 79171, 79180, 79188, 79204, 79215, - 79224, 79232, 79244, 79255, 79271, 79281, 79302, 79315, 79323, 79330, - 14868, 79343, 79348, 79354, 5908, 79360, 79363, 79370, 79380, 8176, - 79387, 79392, 79397, 79402, 79410, 79419, 79427, 9756, 9765, 79432, - 79443, 79448, 79454, 2913, 2918, 79460, 10879, 79466, 79473, 79480, - 79493, 2251, 68, 79498, 79503, 79513, 79519, 79528, 79536, 79546, 79550, - 79555, 79559, 79571, 2941, 79579, 79587, 79592, 79603, 79614, 79623, - 79628, 79634, 79639, 79649, 79659, 79664, 79670, 79674, 79679, 79688, - 21410, 79692, 4128, 20, 79697, 79706, 79713, 79720, 79726, 79732, 864, - 79737, 79742, 60937, 79747, 79752, 79758, 79764, 79772, 79777, 79784, - 79790, 79795, 38030, 41358, 79801, 2945, 32, 79811, 79824, 79829, 79837, - 79842, 79848, 2967, 28310, 79853, 79861, 79868, 79873, 58682, 61940, - 79882, 79886, 1704, 1813, 79891, 79896, 79903, 1817, 247, 79910, 79916, - 2989, 79921, 79926, 79933, 1821, 79938, 79944, 79949, 79961, 6119, 79971, - 1828, 79977, 79982, 79989, 79996, 80011, 80018, 80029, 80037, 2618, - 80041, 80053, 80058, 80062, 80068, 28135, 2256, 80072, 80083, 80087, - 80091, 80097, 80101, 80110, 80114, 80125, 80129, 2302, 32190, 80133, - 80143, 3080, 9371, 80151, 80156, 80160, 80169, 80176, 80182, 3050, 17152, - 80186, 80199, 80217, 80222, 80230, 80238, 80248, 9985, 13154, 80260, - 80273, 80280, 80287, 80303, 80310, 80316, 1064, 80323, 80330, 80340, - 80349, 80361, 42328, 80369, 3064, 12030, 80372, 80380, 80384, 78272, - 3068, 80388, 21191, 12046, 3756, 80392, 3074, 80396, 80406, 80412, 80418, - 80424, 80430, 80436, 80442, 80448, 80454, 80460, 80466, 80472, 80478, - 80484, 80490, 80496, 80502, 80508, 80514, 80520, 80526, 80532, 80538, - 80544, 80550, 80556, 80563, 80570, 80576, 80582, 80588, 80594, 80600, - 80606, 1357, 16062, 12068, 80612, 80617, 80622, 80627, 80632, 80637, - 80642, 80647, 80652, 80657, 80662, 80667, 80672, 80677, 80682, 80687, - 80692, 80697, 80702, 80707, 80712, 80717, 80722, 80727, 80732, 80737, - 80743, 80748, 80753, 80759, 80764, 80770, 80775, 80780, 80786, 80791, - 80796, 80801, 80806, 80811, 80816, 80821, 80826, 80407, 80413, 80419, - 80425, 80431, 80437, 80443, 80449, 80455, 80461, 80467, 80473, 80479, - 80485, 80491, 80832, 80497, 80503, 80509, 80838, 80515, 80521, 80527, - 80533, 80539, 80545, 80551, 80571, 80844, 80850, 80577, 80856, 80583, - 80589, 80595, 80601, 80607, 3091, 3096, 80862, 80867, 80870, 80876, - 80882, 80889, 80894, 80899, 2307, + 0, 0, 6, 10, 14, 22, 27, 34, 39, 45, 47, 50, 62, 70, 80, 89, 102, 108, + 113, 118, 126, 135, 140, 145, 148, 152, 158, 164, 169, 177, 182, 189, + 197, 198, 201, 209, 215, 224, 231, 241, 248, 253, 256, 261, 149, 267, + 273, 276, 280, 285, 291, 297, 302, 308, 313, 322, 328, 335, 342, 351, + 356, 361, 369, 371, 372, 380, 388, 395, 398, 404, 411, 416, 418, 425, + 427, 306, 429, 431, 436, 443, 451, 455, 461, 466, 471, 476, 483, 493, + 496, 503, 513, 522, 529, 538, 545, 549, 557, 560, 573, 580, 584, 593, + 597, 601, 607, 611, 615, 616, 625, 633, 638, 646, 651, 657, 665, 668, + 675, 684, 692, 695, 698, 700, 706, 714, 721, 724, 734, 738, 742, 753, + 758, 762, 766, 773, 780, 784, 788, 782, 794, 798, 803, 806, 810, 816, + 821, 830, 838, 843, 610, 543, 848, 851, 857, 861, 867, 874, 877, 886, + 895, 902, 915, 919, 927, 936, 942, 950, 957, 967, 974, 979, 985, 993, + 997, 1000, 21, 1009, 1018, 1026, 1030, 1035, 1038, 1047, 1052, 1054, + 1061, 1065, 1068, 1071, 1078, 1083, 1087, 1090, 1094, 1102, 1108, 1118, + 1124, 1131, 1135, 1143, 1146, 1151, 1157, 1163, 1167, 1174, 1179, 1184, + 1190, 1195, 1200, 1205, 1209, 1214, 1220, 1225, 1230, 1234, 1240, 1245, + 1250, 1255, 1259, 1264, 1269, 1274, 1280, 1286, 1292, 1297, 1301, 1306, + 1311, 1316, 1320, 1325, 1330, 1335, 1340, 1175, 1180, 1185, 1191, 1196, + 1344, 1206, 1350, 1355, 1360, 1367, 1371, 1374, 1383, 1210, 1387, 1215, + 1221, 1226, 1391, 1396, 1401, 1405, 1409, 1415, 1419, 1231, 1422, 1241, + 1427, 1431, 1246, 1437, 1251, 1441, 1445, 1256, 1449, 1454, 1458, 1461, + 1465, 1260, 1265, 1470, 1270, 1476, 1482, 1488, 1494, 1275, 1287, 1293, + 1498, 1502, 1506, 1509, 1298, 1513, 1515, 1520, 1525, 1531, 1536, 1541, + 1545, 1550, 1555, 1560, 1565, 1571, 1576, 1581, 1587, 1593, 1598, 1602, + 1607, 1612, 1617, 1622, 1627, 1631, 1639, 1644, 1648, 1653, 1658, 1663, + 1668, 1672, 1675, 1682, 1687, 1692, 1697, 1702, 1708, 1713, 1717, 1302, + 1720, 1725, 1730, 1307, 1734, 1738, 1745, 1312, 1752, 1317, 1756, 1758, + 1763, 1769, 1321, 1774, 1783, 1326, 1788, 1794, 1799, 1331, 1804, 1809, + 1812, 1817, 1821, 1825, 1829, 1832, 1836, 1336, 1341, 1841, 1843, 1849, + 1855, 1861, 1867, 1873, 1879, 1885, 1891, 1896, 1902, 1908, 1914, 1920, + 1926, 1932, 1938, 1944, 1950, 1955, 1960, 1965, 1970, 1975, 1980, 1985, + 1990, 1995, 2000, 2006, 2011, 2017, 2022, 2028, 2034, 2039, 2045, 2051, + 2057, 2063, 2068, 2073, 2075, 2076, 2080, 2084, 2089, 2093, 2097, 2101, + 2106, 2110, 2113, 2118, 2122, 2127, 2131, 2135, 2140, 2144, 2147, 2151, + 2157, 2171, 2175, 2179, 2183, 2186, 2191, 2195, 2199, 2202, 2206, 2211, + 2216, 2221, 2226, 2230, 2234, 2238, 2242, 2247, 2251, 2256, 2260, 2265, + 2271, 2278, 2284, 2289, 2294, 2299, 2305, 2310, 2316, 2321, 2324, 2326, + 1192, 2330, 2337, 2345, 2355, 2364, 2378, 2382, 2386, 2391, 2404, 2412, + 2416, 2421, 2425, 2428, 2432, 2436, 2441, 2446, 2451, 2455, 2458, 2462, + 2469, 2476, 2482, 2487, 2492, 2498, 2504, 2509, 2512, 1760, 2514, 2520, + 2524, 2529, 2533, 2537, 1678, 1771, 2542, 2546, 2549, 2554, 2559, 2564, + 2569, 2573, 2580, 2585, 2588, 2595, 2601, 2605, 2609, 2613, 2618, 2625, + 2630, 2635, 2642, 2648, 2654, 2660, 2674, 2691, 2706, 2721, 2730, 2735, + 2739, 2744, 2749, 2753, 2765, 2772, 2778, 2274, 2784, 2791, 2797, 2801, + 2804, 2811, 2817, 2822, 2826, 2831, 2835, 2839, 2098, 2843, 2848, 2853, + 2857, 2862, 2870, 2874, 2878, 2882, 2886, 2891, 2896, 2901, 2905, 2910, + 2915, 2919, 2924, 2928, 2931, 2935, 2939, 2947, 2952, 2956, 2960, 2966, + 2975, 2979, 2983, 2989, 2994, 3001, 3005, 3015, 3019, 3023, 3028, 3032, + 3037, 3043, 3048, 3052, 3056, 3060, 2472, 3068, 3073, 3079, 3084, 3088, + 3093, 3098, 3102, 3108, 3113, 2102, 3119, 3125, 3130, 3135, 3140, 3145, + 3150, 3155, 3160, 3165, 3170, 3176, 3181, 1207, 101, 3187, 3191, 3195, + 3199, 3204, 3208, 3212, 3218, 3223, 3227, 3231, 3236, 3241, 3245, 3250, + 3254, 3257, 3261, 3266, 3270, 3275, 3279, 3282, 3286, 3290, 3295, 3299, + 3302, 3315, 3319, 3323, 3327, 3332, 3336, 3340, 3343, 3347, 3351, 3356, + 3360, 3365, 3370, 3375, 3379, 3384, 3387, 3390, 3395, 3401, 3405, 3409, + 3412, 3417, 3421, 3426, 3430, 3434, 3437, 3443, 3448, 3453, 3459, 3464, + 3469, 3475, 3481, 3486, 3491, 3496, 3501, 1063, 559, 3504, 3507, 3512, + 3516, 3520, 3524, 3528, 3531, 3535, 3540, 3545, 3549, 3554, 3558, 3563, + 3567, 3571, 3575, 3581, 3587, 3590, 3593, 3599, 3606, 3613, 3619, 3626, + 3631, 3635, 3639, 3646, 3651, 3658, 3663, 3667, 3677, 3681, 3685, 3690, + 3695, 3705, 2114, 3710, 3714, 3717, 3723, 3728, 3734, 3740, 3745, 3752, + 3756, 3760, 612, 693, 1368, 3764, 3771, 3778, 3784, 3789, 3796, 3803, + 3809, 3815, 3820, 3824, 3830, 3837, 3842, 3846, 2123, 3850, 3858, 679, + 3864, 3875, 3879, 3889, 2128, 3895, 3900, 3915, 3921, 3928, 3938, 3944, + 3949, 3955, 3961, 3964, 3967, 3971, 3976, 3983, 3988, 3992, 3996, 4000, + 4004, 4009, 4015, 4026, 4030, 3262, 4035, 4047, 4055, 4059, 4064, 1547, + 4071, 4074, 4077, 4081, 4084, 4090, 4094, 4108, 4112, 4115, 4119, 4125, + 4131, 4136, 4140, 4144, 4150, 4161, 4167, 4172, 4178, 4182, 4190, 4202, + 4212, 4218, 4223, 4232, 4240, 4247, 4251, 4257, 4266, 4275, 4279, 4284, + 4289, 4293, 4301, 4305, 4310, 4314, 4320, 2136, 1384, 4326, 4331, 4337, + 4342, 4347, 4352, 4357, 4362, 4367, 4373, 4378, 4384, 4389, 4394, 4399, + 4405, 4410, 4415, 4420, 4425, 4431, 4436, 4442, 4447, 4452, 4457, 4462, + 4467, 4472, 4478, 4483, 4488, 271, 301, 4493, 4499, 4503, 4507, 4512, + 4516, 4520, 4523, 4527, 4531, 4535, 4539, 4543, 4548, 4552, 4556, 4562, + 4323, 4567, 4571, 4574, 4579, 4584, 4589, 4594, 4599, 4604, 4609, 4614, + 4619, 4624, 4628, 4633, 4638, 4643, 4648, 4653, 4658, 4663, 4668, 4673, + 4678, 4682, 4687, 4692, 4697, 4702, 4707, 4712, 4717, 4722, 4727, 4732, + 4736, 4741, 4746, 4751, 4756, 4761, 4766, 4771, 4776, 4781, 4786, 4790, + 4795, 4800, 4805, 4810, 4815, 4820, 4825, 4830, 4835, 4840, 4844, 4849, + 4854, 4859, 4864, 4869, 4874, 4879, 4884, 4889, 4894, 4898, 4903, 4908, + 4913, 4918, 4923, 4928, 4933, 4938, 4943, 4948, 4952, 4957, 4962, 4967, + 4972, 4978, 4984, 4990, 4996, 5002, 5008, 5014, 5019, 5025, 5031, 5037, + 5043, 5049, 5055, 5061, 5067, 5073, 5079, 5084, 5090, 5096, 5102, 5108, + 5114, 5120, 5126, 5132, 5138, 5144, 5149, 5155, 5161, 5167, 5173, 5179, + 5185, 5191, 5197, 5203, 5209, 5214, 5220, 5226, 5232, 5238, 5244, 5250, + 5256, 5262, 5268, 5274, 5279, 5285, 5291, 5297, 5303, 5309, 5315, 5321, + 5327, 5333, 5339, 5344, 5348, 5354, 5360, 5366, 5372, 5378, 5384, 5390, + 5396, 5402, 5408, 5413, 5419, 5425, 5431, 5437, 5443, 5449, 5455, 5461, + 5467, 5473, 5478, 5484, 5490, 5496, 5502, 5508, 5514, 5520, 5526, 5532, + 5538, 5543, 5549, 5555, 5561, 5567, 5573, 5579, 5585, 5591, 5597, 5603, + 5608, 5614, 5620, 5626, 5632, 5638, 5644, 5650, 5656, 5662, 5668, 5673, + 5679, 5685, 5691, 5697, 5703, 5709, 5715, 5721, 5727, 5733, 5738, 5744, + 5750, 5756, 5762, 5768, 5774, 5780, 5786, 5792, 5798, 5803, 5809, 5815, + 5821, 5827, 5833, 5839, 5845, 5851, 5857, 5863, 5868, 5874, 5880, 5886, + 5892, 5898, 5904, 5910, 5916, 5922, 5928, 5933, 5939, 5945, 5951, 5957, + 5963, 5969, 5975, 5981, 5987, 5993, 5998, 6002, 6005, 6012, 6016, 6029, + 6033, 6037, 6041, 6044, 6048, 6053, 6057, 6061, 6067, 6074, 6082, 6089, + 6093, 6101, 6110, 6116, 6128, 6133, 6136, 6141, 6145, 6155, 6163, 6171, + 6177, 6181, 6191, 6201, 6209, 6216, 6223, 6229, 6235, 6242, 6246, 6253, + 6263, 6273, 6281, 6288, 6293, 6297, 6301, 6309, 6313, 6318, 6325, 6333, + 6338, 6342, 6347, 6351, 6358, 6363, 6377, 6382, 6387, 6394, 3517, 6403, + 6407, 6412, 6416, 6420, 6423, 6428, 6433, 6442, 6448, 6454, 6460, 6464, + 6475, 6485, 6500, 6515, 6530, 6545, 6560, 6575, 6590, 6605, 6620, 6635, + 6650, 6665, 6680, 6695, 6710, 6725, 6740, 6755, 6770, 6785, 6800, 6815, + 6830, 6845, 6860, 6875, 6890, 6905, 6920, 6935, 6950, 6965, 6980, 6995, + 7010, 7025, 7040, 7055, 7070, 7085, 7100, 7115, 7130, 7145, 7160, 7175, + 7190, 7205, 7220, 7229, 7238, 7243, 7249, 7259, 7263, 7267, 7272, 7277, + 7285, 7289, 7292, 7296, 3010, 7299, 7304, 305, 474, 7310, 7318, 7322, + 7326, 7329, 7333, 7339, 7343, 7351, 7357, 7362, 7369, 7377, 7384, 7390, + 7395, 7402, 7408, 7416, 7420, 7425, 7437, 7448, 7455, 7459, 7463, 7467, + 7470, 7476, 3287, 7480, 7486, 7491, 7496, 7501, 7507, 7512, 7517, 7522, + 7527, 7533, 7538, 7543, 7549, 7554, 7560, 7565, 7571, 7576, 7582, 7587, + 7592, 7597, 7602, 7607, 7613, 7618, 7623, 7628, 7634, 7640, 7646, 7652, + 7658, 7664, 7670, 7676, 7682, 7688, 7694, 7700, 7705, 7710, 7715, 7720, + 7725, 7730, 7735, 7740, 7746, 7752, 7757, 7763, 7769, 7775, 7780, 7785, + 7790, 7795, 7801, 7807, 7812, 7817, 7822, 7827, 7832, 7838, 7843, 7849, + 7855, 7861, 7867, 7873, 7879, 7885, 7891, 7897, 2145, 7328, 7902, 7906, + 7910, 7913, 7920, 7923, 7927, 7935, 7940, 7945, 7936, 7950, 2172, 7954, + 7960, 7966, 7971, 7976, 7983, 7991, 7996, 8000, 8003, 8007, 8013, 8019, + 8023, 2180, 595, 8026, 8030, 8035, 8041, 8046, 8050, 8053, 8057, 8063, + 8068, 8072, 8079, 8083, 8087, 8091, 800, 872, 8094, 8102, 8109, 8115, + 8122, 8130, 8137, 8144, 8149, 8161, 1227, 1392, 1397, 8172, 1402, 8176, + 8180, 8189, 8197, 8206, 8212, 8217, 8221, 8227, 8232, 2726, 8239, 8243, + 8252, 8261, 8270, 8279, 8284, 8289, 8300, 8312, 8317, 8325, 2231, 8329, + 8331, 8336, 8340, 8349, 8357, 1406, 138, 3559, 3564, 8363, 8367, 8376, + 8382, 8387, 8390, 8399, 3568, 2718, 8405, 8413, 8417, 8421, 8425, 2248, + 8429, 8434, 8441, 8447, 8453, 8456, 8458, 8461, 8469, 8477, 8485, 8488, + 8493, 2261, 8498, 7947, 8501, 8503, 8508, 8513, 8518, 8523, 8528, 8533, + 8538, 8543, 8548, 8553, 8559, 8564, 8569, 8574, 8580, 8585, 8590, 8595, + 8600, 8605, 8610, 8616, 8621, 8626, 8631, 8636, 8641, 8646, 8651, 8656, + 8661, 8666, 8671, 8676, 8681, 8686, 8691, 8696, 8701, 8707, 8713, 8718, + 8723, 8728, 8733, 8738, 2272, 2279, 2285, 8743, 8751, 8757, 8765, 2311, + 2317, 8773, 8777, 8782, 8786, 8790, 8794, 8799, 8803, 8808, 8812, 8815, + 8818, 8824, 8830, 8836, 8842, 8848, 8854, 8860, 8864, 8868, 8872, 8876, + 8881, 8885, 8890, 8894, 8900, 8905, 8912, 8923, 8931, 8941, 8947, 8954, + 8959, 8963, 8974, 8987, 8998, 9011, 9022, 9034, 9046, 9058, 9071, 9084, + 9091, 9097, 9111, 9118, 9124, 9128, 9133, 9137, 9144, 9152, 9156, 9162, + 9166, 9172, 9182, 9186, 9191, 9196, 9203, 9209, 8117, 9219, 9223, 9230, + 9236, 9243, 871, 9247, 9251, 9256, 9261, 9266, 9270, 9276, 9284, 9290, + 9294, 9300, 9310, 9314, 9320, 9325, 9329, 9333, 9339, 9345, 2168, 9350, + 9352, 9357, 9365, 9374, 9378, 9384, 9389, 9394, 9399, 9404, 9410, 9415, + 9420, 4146, 9425, 9430, 9434, 9440, 9445, 9451, 9456, 9461, 9467, 9472, + 9379, 9478, 9482, 9489, 9495, 9500, 9504, 6373, 9509, 9518, 9523, 9528, + 8437, 8444, 9533, 2888, 9537, 9542, 9547, 9552, 9390, 9556, 9561, 9566, + 9395, 9570, 9400, 9575, 9582, 9589, 9595, 9602, 9608, 9614, 9619, 9626, + 9631, 9636, 9641, 9647, 9405, 9411, 9653, 9659, 9664, 9669, 9677, 9416, + 9682, 1028, 9685, 9693, 9699, 9705, 9714, 9722, 9730, 9738, 9746, 9754, + 9762, 9770, 9778, 9787, 9796, 9804, 9813, 9822, 9831, 9840, 9849, 9858, + 9867, 9876, 9885, 9894, 9902, 9907, 9913, 9921, 9928, 9943, 9960, 9979, + 9988, 9996, 10011, 10022, 10032, 10042, 10050, 10056, 10068, 10077, + 10085, 10092, 10099, 10105, 10110, 10120, 10128, 10138, 10145, 10155, + 10165, 10175, 10183, 10190, 10199, 10209, 10223, 10238, 10247, 10255, + 10260, 10264, 10273, 10279, 10284, 10294, 10304, 10314, 10319, 10323, + 10332, 10337, 10347, 10358, 10371, 10379, 10392, 10404, 10412, 10417, + 10421, 10427, 10432, 10440, 10448, 10455, 10460, 10468, 10478, 10484, + 10488, 10491, 10495, 10501, 10505, 10513, 10522, 10527, 10531, 10535, + 10543, 10551, 10560, 10568, 10574, 10578, 10585, 10596, 10600, 10603, + 10609, 9421, 10614, 10620, 10627, 10633, 10638, 10645, 10652, 10659, + 10666, 10673, 10680, 10687, 10694, 10699, 9956, 10704, 10710, 10717, + 10724, 10729, 10736, 10745, 10749, 10761, 8475, 10765, 10768, 10772, + 10776, 10780, 10784, 10790, 10796, 10801, 10807, 10812, 10817, 10823, + 10828, 10833, 9199, 10838, 10842, 10846, 10850, 10855, 10860, 10865, + 10873, 10879, 10883, 10887, 10894, 10899, 10907, 10914, 10919, 10923, + 10926, 10932, 10939, 10943, 10946, 10951, 10955, 4185, 10961, 10970, 36, + 10978, 10984, 10989, 10994, 9214, 11000, 11006, 11011, 11015, 11018, + 11033, 11052, 11064, 11077, 11090, 11103, 11117, 11130, 11145, 11152, + 9426, 11158, 11172, 11177, 11183, 11188, 11196, 11201, 8248, 11206, + 11209, 11217, 11224, 11229, 11233, 11239, 2893, 1133, 11243, 11247, + 11253, 11259, 11264, 11270, 11275, 9435, 11281, 11287, 11292, 11297, + 11305, 11311, 11324, 11332, 11339, 9441, 11345, 11353, 11361, 11368, + 11381, 11393, 11403, 11411, 11418, 11425, 11435, 11444, 11453, 11461, + 11468, 11473, 11479, 9446, 11484, 11490, 11495, 11500, 9452, 11505, + 11508, 11515, 11521, 11534, 8916, 11545, 11551, 11560, 11568, 11575, + 11581, 11592, 11598, 3780, 11603, 11608, 11025, 11614, 11621, 11626, + 9457, 11632, 11637, 11644, 11650, 11656, 11661, 11669, 11677, 11684, + 11688, 11700, 11714, 11724, 11729, 11733, 11744, 11750, 11755, 11760, + 9462, 11764, 9468, 11769, 11772, 11777, 11789, 11796, 11801, 11805, + 11813, 11818, 11822, 11827, 11834, 11840, 9473, 9380, 11847, 2898, 8, + 11854, 11859, 11863, 11867, 11873, 11881, 11891, 11896, 11901, 11908, + 11915, 11919, 11930, 11940, 11949, 11958, 11970, 11975, 11979, 11987, + 12001, 12005, 12008, 12016, 12023, 12031, 12035, 12046, 12050, 12057, + 12062, 12066, 12072, 12077, 12082, 12086, 12092, 12097, 12108, 12112, + 12115, 12121, 12126, 12132, 12138, 12145, 12156, 12166, 12176, 12185, + 12192, 12201, 12205, 9483, 9490, 9496, 9501, 12211, 12217, 12223, 9505, + 12229, 12232, 12239, 12244, 12259, 12275, 12290, 12298, 12304, 12309, + 864, 354, 12314, 12322, 12329, 12335, 12340, 12345, 9510, 12347, 12351, + 12356, 12360, 12370, 12375, 12379, 12388, 12392, 12395, 12402, 9519, + 12407, 12410, 12418, 12425, 12433, 12437, 12441, 12448, 12457, 12464, + 12460, 12471, 12475, 12481, 12485, 12489, 12493, 12499, 12509, 12517, + 12524, 12528, 12536, 12540, 12547, 12551, 12556, 12560, 12567, 12573, + 12581, 12587, 12592, 12602, 12607, 12612, 12616, 12624, 4041, 12632, + 12637, 9524, 12641, 12645, 12648, 12656, 12663, 12667, 6173, 12671, + 12676, 12680, 12691, 12701, 12706, 12712, 12716, 12719, 12727, 12732, + 12737, 12744, 12749, 9529, 12754, 12758, 12765, 1722, 6331, 12770, 12775, + 12780, 12785, 12791, 12796, 12802, 12807, 12812, 12817, 12822, 12827, + 12832, 12837, 12842, 12847, 12852, 12857, 12862, 12867, 12872, 12877, + 12882, 12888, 12893, 12898, 12903, 12908, 12913, 12919, 12924, 12929, + 12935, 12940, 12946, 12951, 12957, 12962, 12967, 12972, 12977, 12983, + 12988, 12993, 12998, 836, 117, 13006, 13010, 13015, 13020, 13024, 13028, + 13032, 13037, 13041, 13046, 13050, 13053, 13057, 13061, 13067, 13072, + 13082, 13088, 13096, 13102, 13106, 13110, 13117, 13125, 13134, 13145, + 13152, 13159, 13163, 13172, 13181, 13189, 13198, 13207, 13216, 13225, + 13235, 13245, 13255, 13265, 13275, 13284, 13294, 13304, 13314, 13324, + 13334, 13344, 13354, 13363, 13373, 13383, 13393, 13403, 13413, 13423, + 13432, 13442, 13452, 13462, 13472, 13482, 13492, 13502, 13512, 13522, + 13531, 13541, 13551, 13561, 13571, 13581, 13591, 13601, 13611, 13621, + 13631, 13640, 1236, 13646, 13649, 13653, 13658, 13665, 13671, 13676, + 13680, 13685, 13694, 13702, 13707, 13711, 13715, 13721, 13726, 13732, + 9538, 13737, 13742, 13751, 9548, 13756, 13759, 13765, 13773, 9553, 13780, + 13784, 13788, 13793, 13797, 13807, 13813, 13819, 13824, 13833, 13841, + 13848, 13855, 13860, 13867, 13872, 13876, 13879, 13890, 13900, 13909, + 13917, 13928, 13940, 13950, 13955, 13959, 13964, 13969, 13973, 13979, + 13987, 13994, 14005, 14010, 14020, 14029, 14033, 14036, 14043, 14053, + 14062, 14069, 14073, 14080, 14086, 14091, 14096, 14100, 14109, 14114, + 14118, 14124, 14128, 14133, 14137, 14146, 14154, 14162, 14169, 14177, + 14189, 14200, 14210, 14217, 14223, 14232, 14243, 14252, 14264, 14276, + 14288, 14298, 14307, 14316, 14324, 14331, 14340, 14348, 14352, 14357, + 14363, 14369, 14374, 14379, 7968, 14383, 14385, 14389, 14394, 14400, + 14406, 14415, 14419, 14425, 14433, 14440, 14449, 14458, 14467, 14476, + 14485, 14494, 14503, 14512, 14522, 14532, 14541, 14547, 14554, 14561, + 14567, 14581, 14588, 14596, 14605, 14611, 14620, 14629, 14640, 14650, + 14658, 14665, 14673, 14682, 14695, 14703, 14710, 14723, 14729, 14735, + 14745, 14754, 14763, 14768, 14772, 14778, 14784, 14789, 14796, 14803, + 9213, 14808, 14813, 14820, 14827, 14832, 14844, 13063, 14849, 14857, + 14863, 14868, 14876, 14884, 14891, 14899, 14905, 14913, 14921, 14927, + 14932, 14938, 14945, 14951, 14956, 14960, 14971, 14979, 14985, 14990, + 14997, 15006, 15012, 15017, 15025, 15034, 15048, 3985, 15052, 15057, + 15062, 15068, 15073, 15078, 15082, 15087, 15092, 15097, 7967, 15102, + 15107, 15112, 15117, 15122, 15126, 15131, 15136, 15141, 15146, 15152, + 15158, 15163, 15167, 15173, 15178, 15183, 15188, 9557, 15193, 15198, + 15203, 15208, 15213, 15230, 15248, 15260, 15273, 15290, 15306, 15323, + 15333, 15352, 15363, 15374, 15385, 15396, 15408, 15419, 15430, 15447, + 15458, 15469, 15474, 9562, 15479, 15483, 2401, 15487, 15490, 15496, + 15504, 15512, 15517, 15525, 15533, 15540, 15544, 15549, 15555, 15562, + 15570, 15577, 15589, 15597, 15602, 15608, 12253, 15614, 15623, 15631, + 15640, 15648, 15655, 15661, 15669, 15676, 15682, 15689, 15696, 15702, + 15708, 15717, 15725, 15735, 15742, 15748, 15756, 15762, 15770, 15778, + 15785, 15798, 15805, 15814, 15823, 15832, 15840, 15850, 15857, 15862, + 3671, 15869, 15874, 1352, 15878, 15103, 15882, 15888, 15892, 15900, + 15912, 15919, 15925, 15930, 15937, 15108, 15941, 15945, 15949, 15113, + 15953, 15118, 15957, 15964, 15969, 15973, 15980, 15984, 15992, 15999, + 16004, 16008, 16015, 16032, 16041, 16045, 16048, 16056, 16062, 16067, + 3749, 16071, 16073, 16081, 16088, 16098, 16110, 16115, 16119, 16125, + 16130, 16134, 16140, 16145, 16151, 16154, 16161, 16169, 16176, 16182, + 16188, 16193, 16200, 16206, 16211, 16218, 16222, 16228, 16232, 16239, + 16245, 16250, 16256, 16264, 16272, 16279, 16285, 16290, 16296, 16302, + 16310, 16318, 16324, 16330, 16335, 16342, 16347, 16351, 16357, 16362, + 16369, 16374, 16380, 16383, 16389, 16395, 16398, 16402, 16406, 16418, + 16424, 16429, 16436, 16442, 16448, 16459, 16469, 16478, 16486, 16493, + 16504, 16514, 16524, 16532, 16535, 15132, 16540, 16545, 15137, 15278, + 16553, 16566, 16581, 16592, 15295, 16610, 16623, 16636, 16647, 11040, + 16658, 16671, 16690, 16701, 16712, 16723, 2669, 16736, 16740, 16748, + 16756, 16771, 16786, 16797, 16804, 16810, 16818, 16822, 16828, 16831, + 16841, 16849, 16856, 16864, 16874, 16879, 16886, 16891, 16898, 16909, + 16919, 16925, 16930, 16935, 15142, 16939, 16945, 16951, 16956, 16961, + 16966, 16970, 15147, 15153, 16974, 15159, 16979, 16987, 16995, 17002, + 17011, 17018, 17022, 9401, 17026, 17028, 17033, 17038, 17044, 17049, + 17054, 17059, 17064, 17068, 17074, 17080, 17085, 17091, 17096, 17101, + 17105, 17111, 17116, 17121, 17126, 17131, 17137, 17142, 17147, 17153, + 17159, 17164, 17169, 17174, 17181, 17187, 17198, 17205, 17210, 17214, + 17218, 17221, 17229, 17234, 17241, 17248, 17254, 17259, 17264, 17269, + 17276, 17286, 17291, 17298, 17304, 17313, 17323, 17333, 17347, 17361, + 17375, 17389, 17404, 17419, 17436, 17454, 17467, 17473, 17478, 17483, + 17487, 17495, 17500, 17508, 17514, 17520, 17525, 17530, 17534, 17539, + 17543, 17548, 17552, 17563, 17569, 17574, 17579, 17586, 17591, 17595, + 17600, 17605, 17611, 17618, 15168, 17624, 17628, 17634, 17639, 17644, + 17648, 17654, 17659, 17664, 17671, 17676, 13809, 17680, 17685, 17689, + 17694, 17700, 17706, 17713, 17723, 17731, 17738, 17743, 17747, 17756, + 17764, 17771, 17778, 17784, 17790, 17795, 17800, 17806, 17811, 17817, + 17822, 17828, 17834, 17841, 17847, 17852, 17857, 9627, 17866, 17869, + 17877, 17883, 17888, 17893, 17903, 17910, 17916, 17921, 17926, 17932, + 17937, 17943, 17948, 17954, 17960, 17965, 17973, 17980, 17985, 17990, + 17996, 18001, 18005, 18014, 18025, 18032, 18037, 18042, 18048, 18053, + 18061, 18067, 18073, 18080, 18086, 18091, 18095, 18101, 18106, 18111, + 18116, 1423, 7992, 2912, 18120, 18124, 18128, 18132, 18136, 18140, 18143, + 18148, 18155, 18163, 15179, 18170, 18180, 18188, 18195, 18203, 18213, + 18222, 18235, 18240, 18245, 18253, 18260, 13905, 13914, 18267, 18277, + 18292, 18298, 18305, 18312, 18318, 18324, 18332, 18342, 18352, 15184, + 18361, 18367, 18373, 18381, 18389, 18394, 18403, 18411, 18423, 18433, + 18443, 18453, 18462, 18474, 18484, 18494, 18505, 18510, 18522, 18534, + 18546, 18558, 18570, 18582, 18594, 18606, 18618, 18630, 18641, 18653, + 18665, 18677, 18689, 18701, 18713, 18725, 18737, 18749, 18761, 18772, + 18784, 18796, 18808, 18820, 18832, 18844, 18856, 18868, 18880, 18892, + 18903, 18915, 18927, 18939, 18951, 18963, 18975, 18987, 18999, 19011, + 19023, 19034, 19046, 19058, 19070, 19082, 19094, 19106, 19118, 19130, + 19142, 19154, 19165, 19177, 19189, 19201, 19213, 19225, 19237, 19249, + 19261, 19273, 19285, 19296, 19308, 19320, 19332, 19344, 19356, 19368, + 19380, 19392, 19404, 19416, 19427, 19439, 19451, 19463, 19475, 19488, + 19501, 19514, 19527, 19540, 19553, 19566, 19578, 19591, 19604, 19617, + 19630, 19643, 19656, 19669, 19682, 19695, 19708, 19720, 19733, 19746, + 19759, 19772, 19785, 19798, 19811, 19824, 19837, 19850, 19862, 19875, + 19888, 19901, 19914, 19927, 19940, 19953, 19966, 19979, 19992, 20004, + 20017, 20030, 20043, 20056, 20069, 20082, 20095, 20108, 20121, 20134, + 20146, 20159, 20172, 20185, 20198, 20211, 20224, 20237, 20250, 20263, + 20276, 20288, 20299, 20312, 20325, 20338, 20351, 20364, 20377, 20390, + 20403, 20416, 20429, 20441, 20454, 20467, 20480, 20493, 20506, 20519, + 20532, 20545, 20558, 20571, 20583, 20596, 20609, 20622, 20635, 20648, + 20661, 20674, 20687, 20700, 20713, 20725, 20738, 20751, 20764, 20777, + 20790, 20803, 20816, 20829, 20842, 20855, 20867, 20880, 20893, 20906, + 20919, 20932, 20945, 20958, 20971, 20984, 20997, 21009, 21022, 21035, + 21048, 21061, 21074, 21087, 21100, 21113, 21126, 21139, 21151, 21164, + 21177, 21190, 21203, 21216, 21229, 21242, 21255, 21268, 21281, 21293, + 21306, 21319, 21332, 21345, 21358, 21371, 21384, 21397, 21410, 21423, + 21435, 21448, 21461, 21474, 21487, 21500, 21513, 21526, 21539, 21552, + 21565, 21577, 21590, 21603, 21616, 21629, 21642, 21655, 21668, 21681, + 21694, 21707, 21719, 21730, 21739, 21747, 21755, 21762, 21768, 21772, + 21778, 21784, 21792, 21797, 21803, 21808, 21812, 21821, 9406, 21832, + 21839, 21847, 21854, 21861, 11528, 21868, 21875, 21884, 21889, 21894, + 8020, 21901, 21906, 21909, 21914, 21922, 21929, 21936, 21943, 21949, + 21958, 21967, 21973, 21982, 21986, 21992, 21997, 22007, 22014, 22020, + 22028, 22034, 22041, 22051, 22060, 22064, 22071, 22075, 22080, 22086, + 22094, 22098, 22108, 15194, 22117, 22123, 22127, 22136, 22146, 15199, + 22152, 22159, 22170, 22178, 22188, 22197, 22205, 9178, 22213, 22218, + 22224, 22229, 22233, 22237, 22241, 10124, 22246, 22254, 22261, 22270, + 22277, 22284, 22290, 11448, 22297, 22303, 22307, 22313, 22320, 22326, + 22334, 22340, 22347, 22353, 22359, 22368, 22372, 22380, 22389, 22396, + 22401, 22405, 22416, 22421, 22426, 22431, 22444, 8203, 22448, 22454, + 22462, 22466, 22473, 22482, 22487, 15470, 22495, 22499, 22511, 22516, + 22520, 22523, 22529, 22535, 22541, 22546, 22550, 22553, 22564, 22569, + 9678, 22576, 22581, 1242, 9683, 22586, 22591, 22596, 22601, 22606, 22611, + 22616, 22621, 22626, 22631, 22636, 22641, 22647, 22652, 22657, 22662, + 22667, 22672, 22677, 22682, 22687, 22692, 22698, 22704, 22709, 22714, + 22719, 22724, 22729, 22734, 22739, 22744, 22749, 22755, 22760, 22765, + 22770, 22776, 22782, 22787, 22792, 22797, 22802, 22807, 22812, 22817, + 22822, 22828, 22833, 22838, 22843, 22848, 22854, 22859, 22864, 22868, + 134, 22876, 22880, 22884, 22888, 22893, 22897, 13815, 2327, 22901, 22906, + 22910, 22915, 22919, 22924, 22928, 22934, 22939, 22943, 22947, 22955, + 22959, 22963, 22968, 22973, 22977, 22983, 22988, 22992, 22997, 23002, + 23006, 23013, 23020, 23027, 23031, 23035, 23040, 23044, 23047, 23053, + 23066, 23071, 23080, 23085, 9903, 23090, 23095, 23098, 2732, 2737, 23102, + 23108, 23114, 7413, 23119, 23124, 23129, 23135, 23140, 14636, 23145, + 23150, 23155, 23160, 23166, 23171, 23176, 23182, 23187, 23191, 23196, + 23201, 23206, 23211, 23215, 23220, 23224, 23229, 23234, 23239, 23244, + 23248, 23253, 23257, 23262, 23267, 23272, 23277, 2921, 23192, 23281, + 23289, 23296, 10218, 23308, 23316, 23197, 23323, 23328, 23336, 23202, + 23341, 23346, 23354, 23359, 23207, 23364, 23372, 23377, 23381, 23387, + 23396, 23404, 23408, 23411, 23418, 23422, 23426, 23432, 23439, 23444, + 9205, 1727, 1732, 23448, 23454, 23460, 23465, 23469, 23473, 23477, 23481, + 23485, 23489, 23493, 23497, 23500, 23506, 23513, 23521, 23527, 23533, + 23538, 23543, 23547, 23552, 14556, 14563, 23559, 23571, 23574, 23581, + 17250, 23588, 23596, 23607, 23616, 23629, 23639, 23653, 23665, 23679, + 23692, 23704, 23714, 23726, 23732, 23747, 23771, 23789, 23808, 23821, + 23835, 23853, 23869, 23886, 23904, 23915, 23934, 23951, 23971, 23989, + 24001, 24015, 24029, 24041, 24058, 24077, 24095, 24107, 24125, 24144, + 15338, 24157, 24177, 24189, 11071, 24201, 24206, 24211, 24216, 24222, + 24227, 24231, 24238, 24244, 2418, 24248, 24254, 24258, 24261, 24265, + 24268, 24276, 24282, 23225, 24286, 24295, 24306, 24312, 24318, 24333, + 24342, 24350, 24357, 24362, 24366, 24373, 24379, 24388, 24396, 24403, + 24413, 24422, 24432, 24437, 24446, 24455, 24466, 24477, 4103, 24487, + 24491, 24501, 24509, 24519, 24530, 24535, 24545, 24553, 24560, 24566, + 24573, 24578, 23235, 24582, 24591, 24595, 24598, 24603, 24611, 24618, + 24627, 24635, 24643, 24653, 24662, 24668, 24674, 24678, 23240, 23245, + 24682, 24692, 24702, 24712, 24720, 24727, 24737, 24745, 24753, 24759, + 24767, 812, 24776, 15529, 577, 24790, 24799, 24807, 24818, 24829, 24839, + 24848, 24860, 24869, 24878, 24885, 24891, 24900, 24909, 24917, 24927, + 24935, 24943, 9644, 24949, 24952, 24956, 24961, 24966, 24970, 10333, + 23258, 23263, 24978, 24984, 24990, 24995, 25000, 25004, 25012, 25018, + 25024, 25028, 3627, 25036, 25041, 25046, 25050, 25054, 10413, 25061, + 25069, 25083, 25090, 25096, 10422, 10428, 25104, 25112, 25119, 25124, + 25129, 23268, 25135, 25146, 25150, 25155, 2621, 25160, 25171, 25177, + 25182, 25186, 25190, 25193, 25200, 25207, 25213, 25220, 25226, 25230, + 23273, 25235, 25239, 25243, 1428, 8385, 25248, 25253, 25258, 25263, + 25268, 25273, 25278, 25283, 25288, 25293, 25298, 25303, 25308, 25313, + 25319, 25324, 25329, 25334, 25339, 25344, 25349, 25355, 25360, 25365, + 25370, 25375, 25380, 25385, 25390, 25396, 25402, 25407, 25413, 25418, + 25423, 5, 25429, 25433, 25437, 25441, 25446, 25450, 25454, 25458, 25462, + 25467, 25471, 25476, 25480, 25483, 25487, 25492, 25496, 25501, 25505, + 25509, 25513, 25518, 25522, 25526, 25536, 25541, 25545, 25549, 25554, + 25559, 25568, 25573, 25578, 25582, 25586, 25599, 25611, 25620, 25629, + 25634, 25640, 25645, 25649, 25653, 25663, 25672, 25680, 25686, 25691, + 25695, 25702, 25712, 25721, 25729, 25737, 25744, 25752, 25761, 25770, + 25778, 25788, 25793, 25797, 25801, 25804, 25806, 25810, 25814, 25819, + 25824, 25828, 25832, 25835, 25839, 25842, 25846, 25849, 25852, 25856, + 25862, 25866, 25870, 25874, 25879, 25884, 25889, 25893, 25896, 25901, + 25907, 25912, 25918, 25923, 25927, 25933, 25937, 25941, 25946, 25950, + 25955, 25960, 25964, 25968, 25975, 25979, 25982, 25986, 25990, 25996, + 26002, 26006, 26010, 26015, 26022, 26028, 26032, 26041, 26045, 26049, + 26052, 26058, 26063, 26069, 1472, 1791, 26074, 26079, 26084, 26089, + 26094, 26099, 26104, 2155, 2201, 26109, 26112, 26116, 26120, 26125, + 26129, 15541, 26133, 26138, 26143, 26147, 26150, 26155, 26159, 26164, + 26168, 15545, 26173, 26176, 26179, 26183, 26188, 26192, 26205, 26209, + 26212, 26220, 26229, 26236, 26241, 26247, 26253, 26261, 26268, 26275, + 26279, 26283, 26287, 26292, 26297, 26301, 26309, 26314, 26326, 26337, + 26342, 26346, 26350, 26356, 26359, 26364, 26369, 26373, 26377, 26380, + 26386, 8123, 2331, 26390, 26395, 26411, 9950, 26431, 26440, 26456, 26460, + 26467, 26470, 26476, 26486, 26492, 26501, 26516, 26528, 26539, 26547, + 26556, 26562, 26571, 26581, 26591, 26602, 26613, 26623, 26632, 26639, + 26648, 26656, 26663, 26671, 26678, 26685, 26698, 26705, 26713, 26720, + 26726, 26731, 26740, 26746, 26751, 26759, 26766, 24511, 26778, 26790, + 26804, 26812, 26819, 26831, 26840, 26849, 26857, 26865, 26873, 26880, + 26889, 26897, 26907, 26916, 26926, 26935, 26944, 26952, 26957, 26961, + 26964, 26968, 26972, 26976, 26980, 26984, 26990, 26996, 27004, 15590, + 27011, 27016, 27023, 27029, 27036, 15598, 27043, 27046, 27058, 27066, + 27072, 27077, 27081, 10363, 27092, 27100, 27110, 27119, 27126, 27130, + 15609, 27133, 27140, 27144, 27150, 27153, 27160, 27166, 27173, 27179, + 27183, 27188, 27192, 27201, 27208, 27214, 8164, 27221, 27229, 27236, + 27242, 27247, 27253, 27259, 27267, 27273, 27277, 27280, 27282, 26969, + 27291, 27297, 27303, 27313, 27318, 27325, 27331, 27336, 27341, 27346, + 27350, 27355, 27362, 27368, 27377, 27381, 27388, 27394, 27403, 27409, + 27414, 27420, 27425, 27432, 27443, 27448, 27452, 27462, 27468, 27472, + 27477, 27487, 27496, 27500, 27507, 27515, 27522, 27528, 27533, 27541, + 27548, 27553, 27560, 27572, 27581, 27585, 13746, 27593, 27603, 27607, + 26216, 27618, 27623, 27627, 27634, 27641, 22979, 26894, 27646, 27650, + 27653, 23921, 27658, 27672, 27688, 27706, 27725, 27742, 27760, 23940, + 27777, 27797, 23957, 27809, 27821, 16597, 27833, 23977, 27847, 27859, + 11084, 27873, 27878, 27883, 27888, 27894, 27900, 27906, 27910, 27918, + 27925, 27930, 27940, 27946, 10707, 27952, 27954, 27959, 27967, 27971, + 27358, 27977, 27984, 12170, 12180, 27991, 28001, 28006, 28010, 28013, + 28019, 28027, 28039, 28049, 28065, 28078, 28092, 16615, 28106, 28113, + 28117, 28120, 28125, 28129, 28136, 28143, 28153, 28158, 28163, 28168, + 28176, 28184, 28189, 28198, 28203, 3329, 28207, 28210, 28213, 28218, + 28225, 28230, 28246, 28254, 28262, 9718, 28270, 28275, 28279, 28285, + 28290, 28296, 28299, 28305, 28317, 28325, 28332, 28338, 28345, 28356, + 28370, 28383, 28389, 28398, 28404, 28413, 28425, 28436, 28446, 28455, + 28464, 28472, 28483, 8146, 28490, 28497, 28503, 28508, 28514, 28521, + 28531, 28541, 28550, 28556, 28563, 28568, 28576, 28583, 28591, 28599, + 28611, 6438, 28618, 28621, 28630, 28638, 28644, 28650, 28655, 28659, + 28662, 28668, 28675, 28680, 28685, 28690, 28694, 28706, 28717, 28726, + 28734, 15757, 28739, 28745, 28751, 12163, 8862, 28756, 28760, 28764, + 28767, 28770, 28776, 28784, 28792, 28796, 28800, 28805, 28808, 28817, + 28821, 28824, 28832, 28843, 28847, 28853, 28859, 28863, 28869, 28877, + 28899, 28923, 28932, 28939, 28946, 28952, 28960, 28966, 28971, 28982, + 29000, 29007, 29015, 29019, 29024, 29033, 29046, 29054, 29066, 29077, + 29088, 29098, 29112, 29121, 29129, 29141, 9967, 29152, 29163, 29175, + 29185, 29194, 29199, 29203, 29211, 29222, 29232, 29237, 29241, 29244, + 29247, 29255, 29263, 29272, 29282, 29291, 29297, 29311, 2683, 29333, + 29344, 29353, 29363, 29375, 29384, 29393, 29403, 29411, 29419, 29428, + 29433, 29444, 29449, 29460, 29464, 29474, 29483, 29491, 29501, 29511, + 29519, 29528, 29535, 29543, 29550, 29559, 29568, 29572, 29580, 29587, + 29595, 29602, 29613, 29628, 29635, 29641, 29651, 29660, 29666, 29677, + 29681, 29688, 29692, 29698, 14758, 29704, 29708, 29713, 29720, 29724, + 29728, 29736, 29744, 29750, 29759, 29766, 29771, 29776, 29786, 24580, + 29790, 29793, 29798, 29803, 29808, 29813, 29818, 29823, 29828, 29833, + 29839, 29844, 29849, 29855, 1198, 699, 29860, 29869, 2379, 29876, 29881, + 29885, 29891, 1247, 558, 270, 29896, 29905, 29913, 29922, 29930, 29941, + 29949, 29958, 29966, 10502, 29970, 29978, 29986, 29991, 15558, 29997, + 30003, 30009, 6034, 30014, 30018, 30024, 30028, 30035, 1438, 30041, + 30048, 1347, 6042, 30052, 30062, 30070, 30076, 30085, 30093, 30099, + 30107, 30114, 11720, 30120, 30127, 30132, 30139, 1479, 199, 2154, 30145, + 30151, 30158, 30169, 30180, 30188, 30195, 30205, 30214, 30222, 30231, + 30238, 30245, 30258, 30265, 30271, 30282, 30301, 1252, 30305, 30310, + 30318, 3686, 30322, 30327, 30331, 30335, 1442, 25833, 30345, 30349, + 30354, 30358, 3595, 30364, 30372, 30379, 30390, 30398, 30406, 3687, 320, + 30411, 30419, 30427, 30434, 30440, 30445, 2223, 11251, 30452, 30458, + 27184, 27438, 30464, 542, 106, 30468, 30472, 30478, 635, 9593, 30483, + 30490, 30496, 30500, 1624, 30503, 30507, 16005, 30510, 30515, 30522, + 30528, 30533, 30541, 30548, 30554, 23361, 30558, 30562, 3757, 17541, + 30566, 30571, 30575, 30578, 30586, 30594, 30599, 30607, 30610, 30617, + 30627, 30639, 30644, 30648, 30656, 30663, 30669, 30676, 30683, 30686, + 30690, 30694, 1446, 30704, 30706, 30711, 30717, 30723, 30728, 30733, + 30738, 30743, 30748, 30753, 30758, 30763, 30768, 30773, 30778, 30783, + 30788, 30793, 30799, 30805, 30811, 30817, 30822, 30827, 30832, 30838, + 30843, 30848, 30853, 30859, 30864, 30870, 30875, 30880, 30885, 30890, + 30896, 30901, 30907, 30912, 30917, 30922, 30927, 30933, 30938, 30944, + 30949, 30954, 30959, 30964, 30969, 30974, 30979, 30984, 30989, 30995, + 31001, 31007, 31012, 31017, 31022, 31027, 31033, 31039, 31045, 31051, + 31057, 31063, 31068, 31074, 31079, 31084, 31089, 31094, 31100, 2463, + 31105, 2470, 2477, 2774, 31110, 2483, 2493, 31116, 31120, 31125, 31130, + 31136, 31141, 31146, 31150, 31155, 31161, 31166, 31171, 31176, 31182, + 31187, 31191, 31195, 31200, 31205, 31210, 31215, 31220, 31226, 31232, + 31237, 31241, 31246, 31252, 31256, 31261, 31266, 31271, 31276, 31280, + 31283, 31288, 31293, 31298, 31303, 31308, 31314, 31320, 31325, 31330, + 31335, 31339, 31344, 31349, 31354, 31359, 31364, 31369, 31373, 31378, + 31383, 31388, 31392, 31396, 31400, 31405, 31413, 31418, 31423, 31429, + 31435, 31441, 31446, 31450, 31453, 31458, 31463, 31467, 31472, 31477, + 31481, 31486, 31490, 31493, 31498, 3853, 18248, 31503, 31508, 31513, + 31521, 22273, 30045, 9273, 31526, 31531, 31535, 31540, 31544, 31548, + 31553, 31557, 31560, 31563, 31567, 31572, 31576, 31584, 31588, 31591, + 31596, 31600, 31604, 31609, 31614, 31618, 31624, 31629, 31634, 31641, + 31648, 31652, 31655, 31661, 31670, 31677, 31685, 31692, 31696, 31701, + 31705, 31709, 31715, 31721, 31725, 31731, 31736, 31741, 31745, 31752, + 31758, 31764, 31770, 31776, 31783, 31789, 31795, 31801, 31807, 31813, + 31819, 31825, 31832, 31838, 31845, 31851, 31857, 31863, 31869, 31875, + 31881, 31887, 31893, 31899, 12059, 31905, 31911, 31916, 31921, 31926, + 31929, 31935, 31943, 31948, 31952, 31957, 31963, 31972, 31978, 31983, + 31988, 31993, 31997, 32002, 32007, 32012, 32017, 32022, 32029, 32036, + 32042, 32048, 32053, 17191, 32060, 32066, 32073, 32079, 32085, 32090, + 32098, 32103, 10117, 32107, 32112, 32117, 32123, 32128, 32133, 32137, + 32142, 32147, 32153, 32158, 32163, 32168, 32172, 32177, 32182, 32186, + 32191, 32196, 32200, 32205, 32209, 32214, 32219, 32224, 32228, 32233, + 32237, 32241, 16111, 32246, 32255, 32261, 32267, 32276, 32284, 32293, + 32301, 32306, 32310, 32317, 32323, 32331, 32335, 32338, 32343, 32352, + 32360, 32378, 32384, 1478, 32390, 32393, 32397, 23455, 23461, 32403, + 32407, 32418, 32429, 32440, 32452, 32456, 32463, 32470, 32475, 32479, + 6079, 855, 22272, 32487, 32492, 32496, 32501, 32505, 32511, 32516, 32522, + 32527, 32533, 32538, 32544, 32549, 32555, 32561, 32567, 32572, 32528, + 32534, 32576, 32581, 32587, 32592, 32598, 32603, 32609, 32614, 32539, + 10957, 32618, 32550, 32556, 32562, 2866, 3509, 32624, 32627, 32632, + 32638, 32644, 32650, 32657, 32663, 32669, 32675, 32681, 32687, 32693, + 32699, 32705, 32711, 32717, 32723, 32729, 32736, 32742, 32748, 32754, + 32760, 32766, 32769, 32774, 32777, 32784, 32789, 32797, 32802, 32807, + 32813, 32818, 32823, 32827, 32832, 32838, 32843, 32849, 32854, 32860, + 32865, 32871, 32877, 32881, 32886, 32891, 32896, 32901, 32905, 32910, + 32915, 32920, 32926, 32932, 32938, 32944, 32949, 32953, 32956, 32962, + 32968, 32977, 32985, 32992, 32997, 33001, 33005, 33010, 15959, 33015, + 33023, 33029, 3805, 1357, 33034, 33038, 8213, 33044, 33050, 33057, 8222, + 33061, 33067, 33074, 33080, 33089, 33097, 33109, 33113, 33120, 33126, + 33131, 33135, 33139, 33142, 33151, 33159, 32529, 33164, 33174, 33184, + 33194, 33200, 33205, 33215, 33220, 33233, 33247, 33258, 33270, 33282, + 33296, 33309, 33321, 33333, 15379, 33347, 33352, 33357, 33361, 33365, + 33369, 1780, 28434, 33373, 33378, 32577, 33383, 33386, 33391, 33396, + 33401, 33407, 33413, 10622, 33418, 33424, 33431, 16549, 33437, 33442, + 33447, 33451, 33456, 33461, 32582, 33466, 33471, 33476, 33482, 32588, + 33487, 33490, 33497, 33505, 33511, 33517, 33523, 33534, 33539, 33546, + 33553, 33560, 33568, 33577, 33586, 33592, 33598, 33606, 32593, 33611, + 33617, 33623, 32599, 33628, 33633, 33641, 33649, 33655, 33662, 33668, + 33675, 33682, 33688, 33696, 33706, 33713, 33719, 33724, 33730, 33735, + 33740, 33747, 33756, 33764, 33769, 33775, 33782, 33790, 33796, 33801, + 33807, 33816, 33823, 29277, 33829, 33833, 33838, 33847, 33852, 33857, + 33862, 13092, 33870, 33875, 33880, 33885, 33889, 33894, 33899, 33906, + 33911, 33916, 33921, 32604, 22209, 33927, 2539, 222, 33930, 33933, 33937, + 33941, 33951, 33959, 33966, 33970, 33977, 33984, 33993, 33997, 34000, + 34006, 34014, 34022, 34026, 34030, 34033, 34039, 34046, 34050, 34054, + 34061, 34069, 32540, 34076, 34084, 10682, 598, 349, 34096, 34101, 34106, + 34112, 34117, 34122, 3826, 34127, 34130, 34135, 34140, 34145, 34150, + 34155, 34162, 23567, 34167, 34172, 34177, 34182, 34187, 34193, 34198, + 34204, 32780, 34210, 34215, 34221, 34227, 34237, 34242, 34247, 34251, + 34256, 34261, 34266, 34271, 34284, 34289, 23312, 17621, 3839, 34293, + 34299, 34304, 34309, 34315, 34320, 34325, 34329, 34334, 34339, 34345, + 34350, 34355, 1362, 34359, 34364, 34369, 34374, 34378, 34383, 34388, + 34393, 34399, 34405, 34410, 34414, 34418, 34423, 34428, 34433, 34437, + 34445, 34449, 34455, 34459, 34466, 17400, 32551, 34472, 34479, 34487, + 34494, 34500, 34513, 34525, 34530, 34536, 34540, 2793, 34544, 34548, + 34041, 34557, 34568, 34573, 29340, 34578, 34583, 34587, 34592, 23466, + 34596, 34600, 34605, 32557, 22299, 34609, 34614, 34620, 34625, 34629, + 34633, 34636, 34640, 34646, 34655, 34666, 34678, 32563, 34683, 34686, + 34690, 34694, 378, 34699, 34704, 34709, 34714, 34719, 34724, 34730, + 34735, 34740, 34746, 34751, 34757, 34762, 34768, 34773, 34778, 34783, + 34788, 34793, 34798, 34803, 34808, 34814, 34819, 34824, 34829, 34834, + 34839, 34844, 34849, 34855, 34861, 34866, 34871, 34876, 34881, 34886, + 34891, 34896, 34901, 34906, 34911, 34916, 34921, 34926, 34931, 34936, + 34941, 34946, 34951, 34957, 311, 13, 34962, 34966, 34970, 34978, 34982, + 34986, 34989, 34992, 34994, 34999, 35003, 35008, 35012, 35017, 35021, + 35026, 35030, 35033, 35035, 35039, 35044, 35048, 35059, 35062, 35064, + 35068, 35080, 35089, 35093, 35097, 35103, 35108, 35117, 35123, 35128, + 35133, 35137, 35141, 35146, 35153, 35158, 35164, 35169, 35173, 35180, + 26902, 26912, 35184, 35189, 35194, 35199, 35206, 35210, 35217, 35223, + 8332, 35227, 35236, 35244, 35259, 35273, 35281, 35292, 35301, 35306, + 7431, 35316, 35321, 35326, 35330, 35333, 35338, 35342, 35347, 35351, + 35358, 35363, 35368, 35373, 9159, 35383, 35385, 35388, 35391, 35395, + 35401, 35405, 35410, 35415, 35421, 35426, 35432, 35437, 35447, 35456, + 35464, 35469, 35475, 35480, 35489, 35500, 35505, 35512, 35516, 35524, + 35531, 35544, 35552, 35556, 35566, 35571, 35575, 35583, 35591, 35596, + 35600, 35604, 35613, 35619, 35624, 35632, 35642, 35651, 35660, 35669, + 35680, 35688, 35699, 35708, 35715, 35721, 35726, 35737, 35742, 35746, + 35749, 35753, 35761, 35767, 35771, 35779, 35785, 35792, 35798, 35803, + 35809, 2438, 35813, 35815, 35820, 35825, 35830, 35833, 35835, 35839, + 35842, 35849, 35853, 10376, 35857, 35863, 35873, 35878, 35884, 35888, + 35893, 35906, 27308, 35912, 35921, 35930, 18427, 35937, 35946, 33180, + 35954, 35959, 35963, 35972, 35980, 35987, 35992, 35996, 36001, 36009, + 36013, 36021, 36027, 36033, 36038, 36042, 36045, 36050, 36063, 36079, + 24047, 36096, 36108, 36125, 36137, 36151, 24064, 24083, 36163, 36175, + 2700, 36189, 36194, 36199, 36204, 36208, 36215, 36227, 36233, 36242, + 36245, 36256, 36267, 36272, 33603, 792, 36276, 36280, 36284, 36287, + 36292, 36297, 36303, 36308, 36313, 36319, 36325, 36330, 36334, 36339, + 36344, 36349, 36353, 36356, 36362, 36367, 36372, 36377, 36381, 36386, + 36392, 36400, 27565, 36405, 36410, 36417, 36423, 36429, 36434, 36442, + 23576, 36449, 36454, 36459, 36464, 36468, 36471, 36476, 36480, 36484, + 36491, 36497, 36503, 36509, 36516, 36521, 36527, 35586, 36531, 36535, + 36540, 36553, 36558, 36564, 36572, 36579, 36587, 36597, 36603, 36609, + 36615, 36619, 36628, 36636, 36643, 36648, 36653, 10980, 36658, 36666, + 36673, 36679, 36689, 36694, 36700, 36708, 3719, 36715, 36721, 36728, + 3725, 36732, 36737, 36748, 36755, 36761, 36770, 36774, 4155, 36777, + 36784, 36790, 36796, 36804, 36814, 30435, 36821, 36829, 36835, 36840, + 36846, 36851, 36855, 27156, 36861, 36868, 36874, 36883, 36890, 24764, + 36896, 36901, 36905, 36913, 36921, 10082, 6065, 36928, 36932, 36934, + 36938, 36943, 36945, 36950, 36956, 36961, 36966, 36973, 34158, 36979, + 36984, 36988, 36993, 36997, 37006, 37010, 37016, 37023, 37029, 37036, + 37041, 37050, 37055, 37059, 37064, 37071, 37079, 37087, 37092, 22355, + 37096, 37099, 37103, 37107, 37111, 37114, 37116, 37121, 37129, 37133, + 37142, 37149, 37153, 37157, 37165, 37172, 37182, 37186, 37190, 37198, + 37206, 37212, 37217, 37226, 14064, 37232, 37241, 37246, 37253, 37260, + 37268, 37276, 37284, 37289, 37296, 37303, 37310, 37317, 37324, 37329, + 37335, 37352, 37360, 37370, 37378, 37385, 392, 37389, 37395, 37399, + 37404, 35297, 37410, 37413, 37417, 37428, 37436, 3730, 37444, 37450, + 37456, 37466, 37475, 37485, 37492, 37498, 37503, 3736, 3742, 37512, + 37519, 37527, 37532, 37536, 37543, 37551, 37558, 37564, 37573, 37583, + 37589, 37597, 37606, 37613, 37621, 37628, 23037, 37632, 37639, 37645, + 37655, 37664, 37672, 37683, 37687, 37697, 37703, 37710, 37718, 37727, + 37736, 37746, 37757, 37764, 37769, 37776, 3064, 37784, 37790, 37795, + 37801, 37807, 37812, 37825, 37838, 37851, 37858, 37864, 37872, 37880, + 37885, 37889, 1452, 37893, 37897, 37901, 37905, 37909, 37913, 37917, + 37921, 37925, 37929, 37933, 37937, 37941, 37945, 37949, 37953, 37957, + 37961, 37965, 37969, 37973, 37977, 37981, 37985, 37989, 37993, 37997, + 38001, 38005, 38009, 38013, 38017, 38021, 38025, 38029, 38033, 38037, + 38041, 38045, 38049, 38053, 38057, 38061, 38065, 38069, 38073, 38077, + 38081, 38085, 38089, 38093, 38097, 38101, 38105, 38109, 38113, 38117, + 38121, 38125, 38129, 38133, 38137, 38141, 38145, 38149, 38153, 38157, + 38161, 38165, 38169, 38173, 38177, 38181, 38185, 38189, 38193, 38197, + 38201, 38205, 38209, 38213, 38217, 38221, 38225, 38229, 38233, 38237, + 38241, 38245, 38249, 38253, 38257, 38261, 38265, 38269, 38273, 38277, + 38281, 38285, 38289, 38293, 38297, 38301, 38305, 38309, 38313, 38317, + 38321, 38325, 38329, 38333, 38337, 38341, 38345, 38349, 38353, 38357, + 38361, 38365, 38369, 38373, 38377, 38381, 38385, 38389, 38393, 38397, + 38401, 38405, 38409, 38413, 38417, 38421, 38425, 38429, 38433, 38437, + 38441, 38445, 38449, 38453, 38457, 38461, 38465, 38469, 38473, 38477, + 38481, 38485, 38489, 38493, 38497, 38501, 38505, 38510, 38514, 38519, + 38523, 38528, 38532, 38537, 38541, 38547, 38552, 38556, 38561, 38565, + 38570, 38574, 38579, 38583, 38588, 38592, 38597, 38601, 38606, 38610, + 38616, 38622, 38627, 38631, 38636, 38640, 38646, 38651, 38655, 38660, + 38664, 38669, 38673, 38679, 38684, 38688, 38693, 38697, 38702, 38706, + 38711, 38715, 38721, 38726, 38730, 38735, 38739, 38745, 38750, 38754, + 38759, 38763, 38768, 38772, 38777, 38781, 38786, 38790, 38796, 38801, + 38805, 38811, 38816, 38820, 38826, 38831, 38835, 38840, 38844, 38849, + 38853, 38859, 38865, 38871, 38877, 38883, 38889, 38895, 38901, 38906, + 38910, 38915, 38919, 38925, 38930, 38934, 38939, 38943, 38948, 38952, + 38957, 38961, 38966, 38970, 38975, 38979, 38984, 38988, 38994, 38999, + 39003, 39008, 39012, 39018, 39024, 39029, 111, 88, 39033, 39035, 39039, + 39043, 39047, 39052, 39056, 39060, 10003, 39065, 39071, 1741, 6472, + 39077, 39080, 39085, 39089, 39094, 39098, 39102, 39107, 10769, 39111, + 39115, 39119, 594, 39123, 16207, 39128, 39132, 39137, 39142, 39147, + 39151, 39158, 27332, 39164, 39167, 39171, 39176, 39182, 39186, 39194, + 39200, 39205, 39209, 39212, 39216, 39222, 39226, 39230, 3560, 3565, + 30642, 39233, 39237, 39241, 39245, 39249, 39257, 39264, 39268, 39275, + 39280, 39294, 39301, 39312, 324, 39317, 39321, 39327, 39339, 39345, + 39351, 30679, 39355, 39361, 39370, 39374, 39378, 39383, 39389, 39394, + 39398, 39403, 39407, 39411, 39418, 39424, 39429, 39444, 39459, 39474, + 39490, 39508, 10719, 39522, 39529, 39533, 39536, 39545, 39550, 39554, + 39562, 35537, 39570, 39574, 39584, 39595, 30612, 39608, 39612, 39621, + 39629, 10270, 15723, 39633, 23478, 39636, 31580, 39641, 10269, 39646, + 39652, 39657, 39663, 39668, 39674, 39679, 39685, 39690, 39696, 39702, + 39708, 39713, 39669, 39675, 39680, 39686, 39691, 39697, 39703, 8345, + 4006, 39717, 39725, 39729, 39732, 39736, 39741, 39746, 39752, 39758, + 39763, 39767, 39771, 27168, 39775, 39779, 39783, 39789, 39793, 29217, + 9296, 39802, 39809, 39815, 39819, 12562, 39826, 39832, 39837, 39844, + 39851, 39858, 29917, 8257, 39865, 39872, 39879, 39885, 39890, 39897, + 39908, 39914, 39919, 39924, 39929, 39936, 39670, 39940, 39950, 39959, + 39970, 39976, 39983, 39988, 39993, 39998, 40003, 40008, 40012, 40016, + 40022, 40030, 2334, 955, 10785, 10797, 10802, 10808, 40039, 10813, 10818, + 10824, 40044, 40054, 40058, 10829, 40063, 17814, 40066, 40071, 40075, + 36237, 40086, 40091, 40098, 40105, 40109, 40112, 40120, 10732, 40127, + 40130, 40136, 40146, 6106, 40155, 40161, 40165, 40173, 40177, 40187, + 40193, 40198, 40209, 40215, 40221, 40226, 40232, 40238, 40244, 40249, + 40252, 40259, 40265, 40269, 40274, 40281, 40288, 40292, 40295, 40305, + 40318, 40327, 40336, 40347, 40360, 40372, 40383, 40392, 40403, 40408, + 40417, 40422, 10834, 40428, 40435, 40443, 40448, 40452, 40459, 40466, + 3958, 20, 40470, 40475, 17668, 40479, 40482, 40485, 29397, 40489, 29926, + 40497, 40501, 40505, 40508, 40514, 40520, 32628, 40525, 40533, 40539, + 40546, 29380, 40550, 29583, 40554, 40563, 40569, 40575, 40580, 40584, + 29945, 40590, 40593, 40601, 40609, 27410, 40615, 40619, 40624, 40631, + 40637, 40642, 40647, 40651, 40657, 40662, 40668, 4208, 883, 40675, 40679, + 40682, 16093, 40694, 40705, 37602, 40710, 40713, 40720, 40724, 40730, + 40734, 40740, 40745, 40751, 40756, 40761, 40765, 40769, 40774, 40779, + 40789, 40795, 40808, 40814, 40820, 40826, 40833, 40838, 40844, 40849, + 17559, 1455, 771, 40854, 40857, 40860, 40863, 32712, 32718, 40866, 32724, + 32737, 32743, 32749, 40872, 32755, 32761, 40878, 40884, 26, 40892, 40899, + 40903, 40907, 40915, 33492, 40919, 40923, 40930, 40935, 40939, 40944, + 40950, 40955, 40961, 40966, 40970, 40974, 40978, 40983, 40987, 40992, + 40996, 41000, 41007, 41012, 41016, 41020, 41025, 41029, 41034, 41038, + 41042, 41047, 41053, 16343, 16348, 41058, 41062, 41065, 41069, 41073, + 22166, 41078, 41082, 41088, 41095, 41100, 41110, 41115, 41123, 41127, + 41130, 33507, 41134, 4261, 41139, 41144, 41148, 41153, 41157, 41162, + 14082, 41173, 41177, 41180, 41184, 41189, 41193, 41198, 41203, 41207, + 41211, 41215, 41218, 41222, 8364, 14098, 41225, 41228, 41234, 41239, + 41245, 41250, 41256, 41261, 41267, 41272, 41278, 41284, 41290, 41295, + 41299, 41303, 41312, 41328, 41344, 41354, 29287, 41361, 41365, 41370, + 41375, 41379, 41383, 37731, 41389, 41394, 41398, 41405, 41410, 41415, + 41419, 41423, 41429, 28237, 41433, 22450, 41438, 41445, 41453, 41459, + 41466, 41474, 41480, 41484, 41489, 41495, 41503, 41508, 41512, 41521, + 9984, 41529, 41533, 41541, 41548, 41553, 41558, 41563, 41567, 41570, + 41574, 41577, 41581, 41588, 41593, 41597, 41603, 27643, 32775, 41607, + 41613, 41620, 41626, 41632, 41637, 41640, 41642, 41649, 41656, 41662, + 41666, 41669, 41673, 41677, 41681, 41686, 41690, 41694, 41697, 41701, + 41715, 24113, 41734, 41747, 41760, 41773, 24131, 41788, 11045, 41803, + 41809, 41813, 41817, 41821, 41825, 41832, 41837, 41841, 41848, 41854, + 41859, 41865, 41875, 41887, 41898, 41903, 41910, 41914, 41918, 41921, + 16751, 3799, 41929, 16370, 41942, 41949, 41953, 41957, 41962, 41967, + 41973, 41977, 41981, 41984, 41989, 41993, 41998, 7957, 16381, 42003, + 42007, 42013, 42022, 42027, 42036, 42043, 37579, 42049, 42054, 42058, + 42063, 42070, 42076, 42080, 42083, 42087, 42092, 15344, 42099, 42106, + 42110, 42113, 42118, 42123, 42129, 42134, 42139, 42143, 42148, 42158, + 42163, 42169, 42174, 42180, 42185, 42191, 42201, 42206, 42211, 42215, + 42220, 7433, 7445, 42225, 42228, 42235, 42241, 42250, 35711, 35718, + 42258, 42262, 42266, 33555, 42274, 42285, 42293, 37779, 42300, 42305, + 42310, 42321, 42328, 42339, 33579, 22456, 42347, 834, 42352, 14429, + 42358, 29371, 42364, 42369, 42379, 42388, 42395, 42401, 42405, 42408, + 42415, 42421, 42428, 42434, 42444, 42452, 42458, 42464, 42469, 42473, + 42480, 42485, 42491, 42498, 42504, 41682, 42509, 42513, 526, 14545, + 42519, 42524, 42527, 42533, 42541, 1379, 42546, 42550, 42555, 42560, + 42565, 42572, 42576, 42581, 42587, 42591, 32785, 42596, 42601, 42610, + 42617, 42627, 42633, 29415, 42650, 42659, 42667, 42673, 42678, 42685, + 42691, 42699, 42708, 42716, 42720, 42725, 42733, 30360, 33588, 42739, + 42758, 16676, 42772, 42788, 42802, 42808, 42813, 42818, 42823, 42829, + 33594, 42834, 42837, 42844, 42849, 42853, 376, 2971, 42860, 42865, 42870, + 28595, 42688, 42874, 42879, 42887, 42891, 42894, 42899, 42905, 42911, + 42916, 42920, 29470, 42923, 42928, 42932, 42935, 42940, 42944, 42949, + 42954, 42958, 42963, 42967, 42971, 42975, 22162, 22173, 42980, 42985, + 42991, 42996, 28194, 43001, 43005, 22259, 16932, 43008, 43013, 43018, + 43023, 43028, 43033, 43038, 43043, 469, 49, 32798, 32803, 32808, 32814, + 32819, 32824, 43048, 32828, 43052, 43056, 43060, 32833, 32839, 43074, + 32850, 32855, 43082, 43087, 32861, 43092, 43097, 43102, 43107, 43113, + 43119, 43125, 32878, 43138, 43147, 43153, 32882, 43157, 32887, 43162, + 32892, 32897, 43165, 43170, 43174, 32433, 43180, 14310, 43187, 43192, + 32902, 43196, 43201, 43206, 43211, 43215, 43220, 43225, 43231, 43236, + 43241, 43247, 43253, 43258, 43262, 43267, 43272, 43277, 43281, 43286, + 43291, 43296, 43302, 43308, 43314, 43319, 43323, 43328, 43332, 32906, + 32911, 32916, 43336, 43340, 43344, 32921, 32927, 32933, 32945, 43356, + 27205, 43360, 43365, 43369, 43374, 43381, 43386, 43391, 43396, 43400, + 43404, 43414, 43419, 43424, 43428, 43432, 43435, 43443, 32993, 43448, + 1462, 43454, 43459, 43465, 43473, 43482, 43486, 43490, 43498, 43504, + 43512, 43528, 43532, 43536, 43541, 43547, 43562, 33030, 1749, 12742, + 43566, 1358, 1373, 43578, 43586, 43593, 43598, 43605, 43610, 9674, 1062, + 2525, 10861, 43617, 9572, 43622, 43625, 43634, 1266, 43639, 41838, 43646, + 43655, 43660, 43664, 43672, 23534, 2577, 43679, 11301, 43689, 43695, + 2352, 2362, 43704, 43713, 43723, 43734, 3352, 35874, 43739, 10920, 3936, + 17597, 1271, 43743, 43751, 43758, 43763, 43767, 43771, 24981, 42094, + 10947, 43779, 43788, 43797, 43805, 43812, 43823, 43828, 43841, 43854, + 43866, 43878, 43890, 43901, 43914, 43925, 43936, 43946, 43954, 43962, + 43974, 43986, 43997, 44006, 44014, 44021, 44033, 44040, 44046, 44055, + 44062, 44075, 44080, 44090, 44095, 44101, 44106, 39816, 44110, 44117, + 44121, 44128, 44136, 2538, 44143, 44154, 44164, 44173, 44181, 44191, + 44199, 44209, 44218, 44223, 44229, 44235, 44240, 3838, 44251, 44261, + 44270, 44279, 44287, 44297, 44305, 44314, 44319, 44324, 44329, 1679, 37, + 44337, 44345, 44356, 44367, 17244, 44377, 44381, 44388, 44394, 44399, + 44403, 44414, 44424, 44433, 44444, 17641, 17646, 44449, 44458, 44463, + 44473, 44478, 44486, 44494, 44501, 44507, 1641, 251, 44511, 44517, 44522, + 44525, 2124, 41954, 44533, 44537, 44540, 1495, 44546, 14707, 1276, 44551, + 44564, 44578, 2663, 44596, 44608, 44620, 2677, 2694, 44634, 44647, 2709, + 44661, 44673, 2724, 44687, 1282, 1288, 1294, 11207, 44692, 44697, 44702, + 44706, 44721, 44736, 44751, 44766, 44781, 44796, 44811, 44826, 44841, + 44856, 44871, 44886, 44901, 44916, 44931, 44946, 44961, 44976, 44991, + 45006, 45021, 45036, 45051, 45066, 45081, 45096, 45111, 45126, 45141, + 45156, 45171, 45186, 45201, 45216, 45231, 45246, 45261, 45276, 45291, + 45306, 45321, 45336, 45351, 45366, 45381, 45396, 45411, 45426, 45441, + 45456, 45471, 45486, 45501, 45516, 45531, 45546, 45561, 45576, 45591, + 45606, 45621, 45636, 45651, 45666, 45681, 45696, 45711, 45726, 45741, + 45756, 45771, 45786, 45801, 45816, 45831, 45846, 45861, 45876, 45891, + 45906, 45921, 45936, 45951, 45966, 45981, 45996, 46011, 46026, 46041, + 46056, 46071, 46086, 46101, 46116, 46131, 46146, 46161, 46176, 46191, + 46206, 46221, 46236, 46251, 46266, 46281, 46296, 46311, 46326, 46341, + 46356, 46371, 46386, 46401, 46416, 46431, 46446, 46461, 46476, 46491, + 46506, 46521, 46536, 46551, 46566, 46581, 46596, 46611, 46626, 46641, + 46656, 46671, 46686, 46701, 46716, 46731, 46746, 46761, 46776, 46791, + 46806, 46821, 46836, 46851, 46866, 46881, 46896, 46911, 46926, 46941, + 46956, 46971, 46986, 47001, 47016, 47031, 47046, 47061, 47076, 47091, + 47106, 47121, 47136, 47151, 47166, 47181, 47196, 47211, 47226, 47241, + 47256, 47271, 47286, 47301, 47316, 47331, 47346, 47361, 47376, 47391, + 47406, 47421, 47436, 47451, 47466, 47481, 47496, 47511, 47526, 47541, + 47556, 47571, 47586, 47601, 47616, 47631, 47646, 47661, 47676, 47691, + 47706, 47721, 47736, 47751, 47766, 47781, 47796, 47811, 47826, 47841, + 47856, 47871, 47886, 47901, 47916, 47931, 47946, 47961, 47976, 47991, + 48006, 48021, 48036, 48051, 48066, 48081, 48096, 48111, 48126, 48141, + 48156, 48171, 48186, 48201, 48216, 48231, 48246, 48261, 48276, 48291, + 48306, 48321, 48336, 48351, 48366, 48381, 48396, 48411, 48426, 48441, + 48456, 48471, 48486, 48501, 48516, 48531, 48546, 48561, 48576, 48591, + 48606, 48621, 48636, 48651, 48666, 48681, 48696, 48711, 48726, 48741, + 48756, 48771, 48786, 48801, 48816, 48831, 48846, 48861, 48876, 48891, + 48906, 48921, 48936, 48951, 48966, 48981, 48996, 49011, 49026, 49041, + 49056, 49071, 49086, 49101, 49116, 49131, 49146, 49161, 49176, 49191, + 49206, 49221, 49236, 49251, 49266, 49281, 49296, 49311, 49326, 49341, + 49356, 49371, 49386, 49401, 49416, 49431, 49446, 49461, 49476, 49491, + 49506, 49521, 49536, 49551, 49566, 49581, 49596, 49611, 49626, 49641, + 49656, 49671, 49686, 49701, 49716, 49731, 49746, 49761, 49776, 49791, + 49806, 49821, 49836, 49851, 49866, 49881, 49896, 49911, 49926, 49941, + 49956, 49971, 49986, 50001, 50016, 50031, 50046, 50061, 50076, 50091, + 50106, 50121, 50136, 50151, 50166, 50181, 50196, 50211, 50226, 50241, + 50256, 50271, 50286, 50301, 50316, 50331, 50346, 50361, 50376, 50391, + 50406, 50421, 50436, 50451, 50466, 50481, 50496, 50511, 50526, 50541, + 50556, 50571, 50586, 50601, 50616, 50631, 50646, 50661, 50676, 50691, + 50706, 50721, 50736, 50751, 50766, 50781, 50796, 50811, 50826, 50841, + 50856, 50871, 50886, 50901, 50916, 50931, 50946, 50961, 50976, 50991, + 51006, 51021, 51036, 51051, 51066, 51081, 51096, 51111, 51126, 51141, + 51156, 51171, 51186, 51201, 51216, 51231, 51246, 51261, 51276, 51291, + 51306, 51321, 51336, 51351, 51366, 51381, 51396, 51411, 51426, 51441, + 51456, 51471, 51486, 51501, 51516, 51531, 51546, 51561, 51576, 51591, + 51606, 51621, 51636, 51651, 51666, 51681, 51696, 51711, 51726, 51741, + 51756, 51771, 51786, 51801, 51816, 51831, 51846, 51861, 51876, 51891, + 51906, 51921, 51936, 51951, 51966, 51981, 51996, 52011, 52026, 52041, + 52056, 52071, 52086, 52101, 52116, 52131, 52146, 52161, 52176, 52191, + 52206, 52221, 52236, 52251, 52266, 52281, 52296, 52311, 52326, 52341, + 52356, 52371, 52386, 52401, 52416, 52431, 52446, 52461, 52476, 52491, + 52506, 52522, 52538, 52554, 52570, 52586, 52602, 52618, 52634, 52650, + 52666, 52682, 52698, 52714, 52730, 52746, 52762, 52778, 52794, 52810, + 52826, 52842, 52858, 52874, 52890, 52906, 52922, 52938, 52954, 52970, + 52986, 53002, 53018, 53034, 53050, 53066, 53082, 53098, 53114, 53130, + 53146, 53162, 53178, 53194, 53210, 53226, 53242, 53258, 53274, 53290, + 53306, 53322, 53338, 53354, 53370, 53386, 53402, 53418, 53434, 53450, + 53466, 53482, 53498, 53514, 53530, 53546, 53562, 53578, 53594, 53610, + 53626, 53642, 53658, 53674, 53690, 53706, 53722, 53738, 53754, 53770, + 53786, 53802, 53818, 53834, 53850, 53866, 53882, 53898, 53914, 53930, + 53946, 53962, 53978, 53994, 54010, 54026, 54042, 54058, 54074, 54090, + 54106, 54122, 54138, 54154, 54170, 54186, 54202, 54218, 54234, 54250, + 54266, 54282, 54298, 54314, 54330, 54346, 54362, 54378, 54394, 54410, + 54426, 54442, 54458, 54474, 54490, 54506, 54522, 54538, 54554, 54570, + 54586, 54602, 54618, 54634, 54650, 54666, 54682, 54698, 54714, 54730, + 54746, 54762, 54778, 54794, 54810, 54826, 54842, 54858, 54874, 54890, + 54906, 54922, 54938, 54954, 54970, 54986, 55002, 55018, 55034, 55050, + 55066, 55082, 55098, 55114, 55130, 55146, 55162, 55178, 55194, 55210, + 55226, 55242, 55258, 55274, 55290, 55306, 55322, 55338, 55354, 55370, + 55386, 55402, 55418, 55434, 55450, 55466, 55482, 55498, 55514, 55530, + 55546, 55562, 55578, 55594, 55610, 55626, 55642, 55658, 55674, 55690, + 55706, 55722, 55738, 55754, 55770, 55786, 55802, 55818, 55834, 55850, + 55866, 55882, 55898, 55914, 55930, 55946, 55962, 55978, 55994, 56010, + 56026, 56042, 56058, 56074, 56090, 56106, 56122, 56138, 56154, 56170, + 56186, 56202, 56218, 56234, 56250, 56266, 56282, 56298, 56314, 56330, + 56346, 56362, 56378, 56394, 56410, 56426, 56442, 56458, 56474, 56490, + 56506, 56522, 56538, 56554, 56570, 56586, 56602, 56618, 56634, 56650, + 56666, 56682, 56698, 56714, 56730, 56746, 56762, 56778, 56794, 56810, + 56826, 56842, 56858, 56874, 56890, 56906, 56922, 56938, 56954, 56970, + 56986, 57002, 57018, 57034, 57050, 57066, 57082, 57098, 57114, 57130, + 57146, 57162, 57178, 57194, 57210, 57226, 57242, 57258, 57274, 57290, + 57306, 57322, 57338, 57354, 57370, 57386, 57402, 57418, 57434, 57450, + 57466, 57482, 57498, 57514, 57530, 57546, 57562, 57578, 57594, 57610, + 57626, 57642, 57658, 57674, 57690, 57706, 57722, 57738, 57754, 57770, + 57786, 57802, 57818, 57834, 57850, 57866, 57882, 57898, 57914, 57930, + 57946, 57962, 57978, 57994, 58010, 58026, 58042, 58058, 58074, 58090, + 58106, 58122, 58138, 58154, 58170, 58186, 58202, 58218, 58234, 58250, + 58266, 58282, 58298, 58314, 58330, 58346, 58362, 58378, 58394, 58410, + 58426, 58442, 58458, 58474, 58490, 58506, 58522, 58538, 58554, 58570, + 58586, 58602, 58618, 58634, 58650, 58666, 58682, 58698, 58714, 58730, + 58746, 58762, 58778, 58794, 58810, 58826, 58842, 58858, 58874, 58890, + 58906, 58922, 58938, 58954, 58970, 58986, 59002, 59018, 59034, 59050, + 59066, 59082, 59098, 59114, 59130, 59146, 59162, 59178, 59194, 59210, + 59226, 59242, 59258, 59274, 59290, 59306, 59322, 59338, 59354, 59370, + 59386, 59402, 59418, 59434, 59450, 59466, 59482, 59498, 59514, 59530, + 59546, 59562, 59578, 59594, 59610, 59626, 59642, 59658, 59674, 59690, + 59706, 59722, 59738, 59754, 59770, 59786, 59802, 59818, 59834, 59850, + 59866, 59882, 59898, 59914, 59930, 59946, 59962, 59978, 59994, 60010, + 60026, 60042, 60058, 60074, 60090, 60106, 60122, 60138, 60154, 60170, + 60186, 60202, 60218, 60234, 60250, 60266, 60282, 60298, 60314, 60330, + 60346, 60362, 60378, 60394, 60410, 60426, 60442, 60458, 60474, 60490, + 60506, 60522, 60538, 60554, 60570, 60586, 60602, 60618, 60634, 60650, + 60666, 60682, 60698, 60714, 60730, 60746, 60762, 60778, 60794, 60810, + 60826, 60842, 60858, 60874, 60890, 60906, 60922, 60938, 60954, 60970, + 60986, 61002, 61018, 61034, 61050, 61066, 61082, 61098, 61114, 61130, + 61146, 61162, 61178, 61193, 17673, 61202, 61207, 61213, 61219, 61229, + 61237, 15704, 16287, 10445, 61250, 1503, 1507, 61258, 3890, 28713, 7387, + 61264, 61269, 61274, 61279, 61284, 61290, 61295, 61301, 61306, 61312, + 61317, 61322, 61327, 61332, 61338, 61343, 61348, 61353, 61358, 61363, + 61368, 61373, 61379, 61384, 61390, 61397, 2581, 61402, 61408, 8753, + 61412, 61417, 61424, 61432, 46, 61436, 61442, 61447, 61452, 61456, 61461, + 61465, 61469, 11244, 61473, 61483, 61496, 61507, 61520, 61527, 61533, + 61538, 61544, 61550, 61556, 61561, 61566, 61571, 61576, 61580, 61585, + 61590, 61595, 61601, 61607, 61613, 61618, 61622, 61627, 61632, 61636, + 61641, 61646, 61651, 61655, 11260, 11271, 11276, 1546, 61659, 61665, + 1551, 61670, 61673, 17122, 61678, 61684, 61689, 1582, 61695, 1588, 1594, + 11306, 61700, 61709, 61717, 61724, 61728, 61734, 61739, 32466, 61744, + 61751, 61756, 61760, 61764, 61773, 1599, 17219, 61778, 61782, 17230, + 1105, 61786, 61793, 61798, 61802, 17260, 1603, 39964, 61805, 61810, + 61820, 61829, 61834, 61838, 61844, 1608, 42055, 61849, 61858, 61864, + 61869, 61874, 11474, 11480, 61880, 61892, 61909, 61926, 61943, 61960, + 61977, 61994, 62011, 62028, 62045, 62062, 62079, 62096, 62113, 62130, + 62147, 62164, 62181, 62198, 62215, 62232, 62249, 62266, 62283, 62300, + 62317, 62334, 62351, 62368, 62385, 62402, 62419, 62436, 62453, 62470, + 62487, 62504, 62521, 62538, 62555, 62572, 62589, 62606, 62623, 62640, + 62657, 62674, 62691, 62708, 62725, 62736, 62741, 1613, 62745, 62750, + 62756, 62761, 62766, 9591, 1618, 62772, 62781, 29029, 62786, 62797, + 11491, 62807, 62812, 62818, 62823, 62830, 62836, 62841, 1623, 17535, + 62846, 11501, 1628, 11506, 62852, 62857, 62863, 62868, 62873, 62878, + 62883, 62888, 62893, 62898, 62903, 62909, 62915, 62921, 62926, 62930, + 62935, 62940, 62944, 62949, 62954, 62959, 62964, 62968, 62973, 62979, + 62984, 62989, 62993, 62998, 63003, 63009, 63014, 63019, 63025, 63031, + 63036, 63040, 63045, 63050, 63055, 63059, 63064, 63069, 63074, 63080, + 63086, 63091, 63095, 63099, 63104, 63109, 63114, 30504, 63118, 63123, + 63128, 63134, 63139, 63144, 63148, 63153, 63158, 63164, 63169, 63174, + 63180, 63186, 63191, 63195, 63200, 63205, 63209, 63214, 63219, 63224, + 63230, 63236, 63241, 63245, 63250, 63255, 63259, 63264, 63269, 63274, + 63279, 63283, 63286, 63289, 63294, 33147, 63299, 63307, 17601, 3774, + 11604, 63313, 63323, 63338, 63346, 11609, 63357, 63362, 63373, 63385, + 63397, 63409, 2715, 63421, 63426, 63438, 63442, 63448, 63454, 63459, + 1645, 16826, 63468, 63473, 42114, 63477, 63481, 63486, 63490, 17681, + 63495, 63498, 63503, 63511, 63519, 1649, 11645, 11651, 1654, 63527, + 63534, 63539, 63548, 63558, 63565, 63570, 63575, 1659, 63582, 63587, + 17796, 63591, 63596, 63603, 63609, 63613, 63624, 63634, 17818, 9485, + 9492, 63641, 1664, 63646, 63652, 63660, 63667, 63673, 63680, 63692, + 63698, 63703, 63715, 63726, 63735, 63745, 3869, 32271, 32280, 17858, + 1669, 1673, 63753, 63764, 63769, 1683, 63777, 63782, 63787, 17917, 63799, + 63802, 63808, 63813, 63821, 1688, 63826, 63831, 63839, 63847, 63854, + 63863, 63871, 63880, 1693, 63884, 1698, 22330, 63889, 63896, 17991, + 63904, 63910, 63915, 63923, 63930, 63938, 17309, 63943, 11797, 63952, + 63958, 63963, 63970, 63977, 63983, 16991, 63993, 63999, 64004, 64015, + 64020, 64028, 11814, 11819, 64036, 64042, 64046, 64054, 3934, 18038, + 42207, 64059, 64065, 64070, 64078, 64085, 12723, 64090, 64096, 1709, + 64101, 64104, 1172, 64110, 64115, 64120, 64126, 64131, 64136, 64141, + 64146, 64151, 64156, 1718, 9, 64162, 64166, 64171, 64175, 64179, 64183, + 33387, 64188, 24277, 64193, 64198, 64202, 64205, 64209, 64213, 64218, + 64222, 64227, 64231, 64237, 36288, 36293, 36298, 64240, 64247, 64253, + 64261, 41891, 64271, 36304, 33651, 33402, 33408, 36320, 33414, 64276, + 64281, 33684, 64285, 64288, 64292, 64299, 64302, 64307, 64312, 64316, + 64320, 64323, 64333, 64345, 64352, 64358, 33419, 64365, 35149, 64368, + 8770, 940, 64371, 64375, 64380, 3812, 64384, 64387, 14343, 64394, 64401, + 64414, 64422, 64431, 64440, 64445, 64455, 64468, 64480, 64487, 64492, + 64501, 64514, 37819, 64532, 64537, 64544, 64550, 746, 64555, 64563, + 64570, 28536, 710, 64576, 64582, 64592, 64598, 64603, 33438, 6185, 33452, + 64607, 64617, 64622, 64632, 64647, 64653, 64659, 33462, 64664, 32583, + 64668, 64673, 64680, 64685, 64689, 64694, 17861, 64701, 64706, 64710, + 6226, 33488, 64714, 64720, 310, 64730, 64737, 64744, 64749, 64758, 61814, + 64764, 64772, 64776, 64780, 64784, 64788, 64793, 64797, 64803, 64811, + 64816, 64821, 64826, 64830, 64835, 64839, 64843, 64849, 64855, 64860, + 64864, 64869, 33612, 64873, 33618, 33624, 64878, 64884, 64891, 64896, + 64900, 32600, 17528, 64903, 64907, 64912, 64919, 64925, 64929, 64934, + 41583, 64940, 64944, 64951, 64955, 64960, 64966, 64972, 64978, 64990, + 64999, 65009, 65015, 65022, 65027, 65032, 65036, 65039, 65045, 65052, + 65057, 65062, 65069, 65076, 65083, 65089, 65094, 65099, 65107, 33629, + 2443, 65112, 65117, 65123, 65128, 65134, 65139, 65144, 65149, 65155, + 33650, 65160, 65166, 65172, 65178, 33720, 65183, 65188, 65193, 33731, + 65198, 65203, 65208, 65214, 65220, 33736, 65225, 65230, 65235, 33791, + 33797, 65240, 65245, 33802, 33824, 29278, 33830, 33834, 65250, 12467, + 65254, 65262, 65268, 65276, 65283, 65289, 65299, 65305, 65312, 11179, + 33848, 65318, 65331, 65340, 65346, 65355, 65361, 24587, 65368, 65375, + 65385, 65388, 33792, 65393, 65400, 65405, 65409, 65413, 65418, 65422, + 6306, 65427, 65432, 65437, 36382, 36387, 65441, 36401, 65446, 36406, + 65451, 65457, 36418, 36424, 36430, 65462, 65468, 23577, 65479, 65482, + 65494, 65502, 33871, 65506, 65515, 65525, 65534, 33881, 65539, 65546, + 65555, 65561, 65569, 65576, 6277, 4559, 65581, 33803, 65587, 65590, + 65596, 65603, 65608, 65613, 24497, 65617, 65623, 65629, 65634, 65639, + 65643, 65649, 65655, 35055, 953, 37469, 39196, 39202, 33912, 33917, + 65660, 65664, 65668, 65671, 65684, 65690, 65694, 65697, 65702, 35376, + 65706, 32605, 22280, 65712, 6206, 6214, 9322, 65715, 65720, 65725, 65730, + 65735, 65740, 65745, 65750, 65755, 65760, 65766, 65771, 65776, 65782, + 65787, 65792, 65797, 65802, 65807, 65812, 65818, 65823, 65829, 65834, + 65839, 65844, 65849, 65854, 65859, 65864, 65869, 65874, 65879, 65885, + 65890, 65895, 65900, 65905, 65910, 65915, 65921, 65926, 65931, 65936, + 65941, 65946, 65951, 65956, 65961, 65966, 65972, 65977, 65982, 65987, + 65992, 65998, 66004, 66009, 66015, 66020, 66025, 66030, 66035, 66040, + 1496, 223, 66045, 66049, 66053, 66057, 26272, 66061, 66065, 66070, 66074, + 66079, 66083, 66088, 66093, 66098, 66102, 66106, 66111, 66115, 14076, + 66120, 66124, 66131, 66141, 16024, 66150, 66159, 66163, 66168, 66173, + 66177, 66181, 26066, 3054, 66185, 66191, 18309, 66195, 66204, 66212, + 66218, 66230, 66242, 66246, 66251, 66255, 66261, 66267, 66272, 66282, + 66292, 66298, 66303, 66307, 66313, 66318, 66325, 66331, 66336, 66345, + 66354, 66362, 16412, 66366, 66375, 66383, 66395, 66406, 66417, 66426, + 66430, 66439, 66447, 66457, 66465, 66471, 66476, 66482, 66487, 66498, 85, + 32410, 66504, 27482, 27492, 66510, 66517, 66523, 66527, 66537, 66548, + 66556, 66565, 66570, 66575, 66580, 66584, 66588, 18263, 66596, 66600, + 66606, 66616, 66623, 66629, 66635, 36481, 66639, 66641, 66644, 66650, + 66654, 66664, 66670, 66677, 66684, 14013, 66692, 66698, 66707, 66716, + 66722, 66728, 66734, 66739, 66746, 66753, 66759, 66767, 66780, 66789, + 66798, 66803, 66807, 66813, 66819, 66826, 66833, 66840, 66847, 66854, + 66859, 66863, 66867, 66870, 66880, 66884, 66896, 66905, 66909, 66914, + 66918, 66924, 66929, 66936, 66945, 66953, 66961, 66966, 66970, 66975, + 66980, 66990, 66998, 67003, 67007, 67011, 67017, 67025, 67032, 67044, + 67052, 67063, 67069, 67079, 67085, 67089, 67096, 67102, 67107, 67111, + 67115, 67119, 67128, 67137, 67146, 67152, 67158, 67164, 67169, 67176, + 67182, 67190, 67197, 13156, 67203, 67209, 67213, 15009, 67217, 67222, + 67232, 67241, 67247, 67253, 67261, 67268, 67272, 67276, 67282, 67290, + 67297, 67303, 67314, 67318, 67322, 67326, 67329, 67335, 67340, 67345, + 67349, 67353, 67362, 67370, 67377, 67383, 67390, 25152, 41635, 67395, + 67403, 67407, 67411, 67414, 67422, 67429, 67435, 67444, 67452, 67458, + 67463, 67467, 67472, 67476, 67480, 67485, 67494, 67498, 67505, 39305, + 67509, 67515, 67519, 67527, 67533, 67538, 67549, 67557, 67563, 23720, + 67572, 67579, 67586, 67593, 67600, 67607, 44881, 13851, 67614, 67621, + 67626, 36517, 6404, 67632, 67637, 67642, 67648, 67654, 67660, 67665, + 67670, 67675, 67680, 67686, 67691, 67697, 67702, 67708, 67713, 67718, + 67723, 67728, 67733, 67738, 67743, 67749, 67754, 67760, 67765, 67770, + 67775, 67780, 67785, 67790, 67796, 67801, 67806, 67811, 67816, 67821, + 67826, 67831, 67836, 67841, 67846, 67852, 67857, 67862, 67867, 67872, + 67877, 67882, 67887, 67892, 67898, 67903, 67908, 67913, 67918, 67923, + 67928, 67933, 67938, 67943, 67948, 67953, 67958, 67964, 1839, 240, 40067, + 67969, 67972, 67977, 67981, 67984, 3391, 67989, 67994, 66957, 68005, + 68015, 68022, 68031, 68047, 68056, 68066, 68076, 68085, 68093, 68107, + 68115, 68119, 68122, 68129, 68135, 68146, 68158, 68169, 68178, 68185, + 1277, 24386, 68195, 2610, 68199, 68208, 1119, 18236, 21794, 68216, 68224, + 68238, 68251, 68255, 68260, 68265, 68270, 68276, 68282, 68287, 8762, + 68292, 68296, 68304, 11646, 68309, 68315, 68324, 68332, 1721, 11658, 835, + 6340, 68336, 68345, 68355, 2400, 28271, 68364, 68370, 17773, 28286, + 68376, 4104, 12032, 68382, 68389, 63759, 68393, 68397, 68403, 68408, + 68413, 4128, 180, 14917, 68418, 68430, 68434, 68440, 29049, 68444, 12020, + 2750, 4, 68449, 68459, 68470, 68476, 68487, 68494, 68500, 68506, 68514, + 68521, 68527, 68537, 68547, 68557, 68566, 24574, 1289, 68571, 68575, + 68579, 68585, 68589, 2773, 2779, 8759, 2275, 68593, 68597, 68606, 68614, + 68625, 68633, 68641, 68647, 68652, 68663, 68674, 68682, 68688, 10179, + 68693, 68701, 68705, 68709, 68714, 68718, 68730, 29456, 15977, 68737, + 68747, 68753, 68759, 10281, 68769, 68780, 68790, 68799, 68803, 68810, + 1121, 2603, 68820, 68825, 68833, 68841, 68852, 68859, 68873, 14846, 453, + 68883, 68887, 68895, 68904, 68912, 68918, 68932, 68939, 68945, 68954, + 68961, 68971, 68979, 68986, 68994, 69001, 3941, 143, 69009, 69020, 69024, + 69036, 69042, 12202, 167, 69047, 69052, 69056, 69063, 69069, 69077, + 69084, 9065, 69091, 69100, 69108, 4010, 69121, 4027, 69125, 2823, 494, + 69130, 69143, 69148, 1838, 736, 69152, 4031, 69160, 69166, 69170, 813, + 69180, 69189, 69194, 15738, 15745, 48243, 69198, 4056, 3951, 13734, + 69206, 69213, 69218, 24638, 69222, 69229, 69235, 69240, 69245, 15758, + 161, 69250, 69262, 69268, 69276, 2840, 1753, 69284, 69286, 69291, 69296, + 69301, 69307, 69312, 69317, 69322, 69327, 69332, 69337, 69343, 69348, + 69353, 69358, 69363, 69368, 69373, 69378, 69383, 69389, 69394, 69399, + 69404, 69410, 69415, 69421, 69426, 69431, 69436, 69441, 69446, 69451, + 69456, 69462, 69467, 69473, 69478, 69483, 69488, 69493, 69498, 69503, + 69508, 69513, 69519, 69525, 69530, 69535, 69541, 69546, 69550, 69554, + 69559, 69565, 69569, 69575, 69580, 69585, 69591, 69596, 69600, 69605, + 69610, 69614, 69617, 69619, 69623, 69626, 69631, 69635, 69640, 69644, + 69648, 69652, 69661, 69665, 34097, 69668, 34102, 69675, 69680, 34107, + 69689, 69698, 34113, 69703, 34118, 69712, 69717, 12234, 69721, 69726, + 69731, 34123, 69735, 43115, 69739, 69742, 69746, 8430, 69752, 69757, + 69761, 3827, 34128, 69764, 69768, 69771, 69776, 69780, 69786, 69794, + 69807, 69816, 69822, 69827, 69833, 69837, 69843, 69851, 69856, 69860, + 69867, 69873, 69881, 69890, 69898, 34131, 69905, 69915, 69928, 69933, + 69938, 69942, 69951, 69957, 69964, 69975, 69987, 69994, 70003, 70012, + 70021, 70028, 70034, 70041, 70049, 70056, 70064, 70073, 70081, 70088, + 70096, 70105, 70113, 70122, 70132, 70141, 70149, 70156, 70164, 70173, + 70181, 70190, 70200, 70209, 70217, 70226, 70236, 70245, 70255, 70266, + 70276, 70285, 70293, 70300, 70308, 70317, 70325, 70334, 70344, 70353, + 70361, 70370, 70380, 70389, 70399, 70410, 70420, 70429, 70437, 70446, + 70456, 70465, 70475, 70486, 70496, 70505, 70515, 70526, 70536, 70547, + 70559, 70570, 70580, 70589, 70597, 70604, 70612, 70621, 70629, 70638, + 70648, 70657, 70665, 70674, 70684, 70693, 70703, 70714, 70724, 70733, + 70741, 70750, 70760, 70769, 70779, 70790, 70800, 70809, 70819, 70830, + 70840, 70851, 70863, 70874, 70884, 70893, 70901, 70910, 70920, 70929, + 70939, 70950, 70960, 70969, 70979, 70990, 71000, 71011, 71023, 71034, + 71044, 71053, 71063, 71074, 71084, 71095, 71107, 71118, 71128, 71139, + 71151, 71162, 71174, 71187, 71199, 71210, 71220, 71229, 71237, 71244, + 71252, 71261, 71269, 71278, 71288, 71297, 71305, 71314, 71324, 71333, + 71343, 71354, 71364, 71373, 71381, 71390, 71400, 71409, 71419, 71430, + 71440, 71449, 71459, 71470, 71480, 71491, 71503, 71514, 71524, 71533, + 71541, 71550, 71560, 71569, 71579, 71590, 71600, 71609, 71619, 71630, + 71640, 71651, 71663, 71674, 71684, 71693, 71703, 71714, 71724, 71735, + 71747, 71758, 71768, 71779, 71791, 71802, 71814, 71827, 71839, 71850, + 71860, 71869, 71877, 71886, 71896, 71905, 71915, 71926, 71936, 71945, + 71955, 71966, 71976, 71987, 71999, 72010, 72020, 72029, 72039, 72050, + 72060, 72071, 72083, 72094, 72104, 72115, 72127, 72138, 72150, 72163, + 72175, 72186, 72196, 72205, 72215, 72226, 72236, 72247, 72259, 72270, + 72280, 72291, 72303, 72314, 72326, 72339, 72351, 72362, 72372, 72383, + 72395, 72406, 72418, 72431, 72443, 72454, 72466, 72479, 72491, 72504, + 72518, 72531, 72543, 72554, 72564, 72573, 72581, 72588, 72593, 8266, + 72600, 34141, 72605, 72610, 34146, 72616, 21902, 34151, 72621, 72627, + 72635, 72641, 72647, 72654, 72661, 72666, 72670, 72674, 72677, 72681, + 72690, 72699, 72707, 72713, 72725, 72736, 72740, 3116, 8241, 72745, + 72748, 72750, 72754, 72758, 72762, 72768, 72773, 27136, 72778, 72782, + 72785, 72790, 72794, 72801, 72807, 72811, 6360, 72815, 34168, 72820, + 72827, 72836, 72844, 72855, 72863, 72872, 72880, 72887, 72894, 72900, + 72911, 34173, 72916, 72927, 72939, 72947, 72958, 72967, 72978, 72983, + 72991, 2576, 72996, 35941, 73009, 73013, 73025, 73033, 73038, 73046, + 18437, 73057, 73063, 73070, 73078, 73084, 34183, 73089, 4050, 61233, + 73096, 73099, 73107, 73120, 73133, 73146, 73159, 73166, 73177, 73186, + 44698, 44703, 73191, 73195, 73203, 73210, 73219, 73227, 73233, 73242, + 73250, 73258, 73262, 73271, 73280, 73290, 73303, 73316, 73326, 34188, + 73332, 73339, 73345, 73351, 34194, 73356, 73359, 73363, 73371, 73380, + 44436, 73388, 73397, 73405, 73412, 73420, 73430, 73439, 73448, 73457, + 73465, 73476, 73491, 73501, 9656, 22572, 73510, 73515, 73520, 73524, + 73529, 73533, 73538, 73544, 73549, 73554, 73560, 73565, 73570, 22537, + 73575, 73582, 73590, 73598, 73606, 73611, 73618, 73625, 73630, 2253, + 73634, 73638, 73646, 73654, 34211, 73660, 73666, 73678, 73684, 73691, + 73695, 73702, 73707, 73714, 73720, 73727, 73738, 73748, 73758, 73770, + 73776, 73784, 73794, 73804, 34238, 73813, 73822, 73828, 73840, 73851, + 73858, 73863, 73867, 73875, 73881, 73886, 73891, 73898, 73906, 73918, + 73928, 73937, 73946, 73953, 35794, 24953, 73959, 73964, 73968, 73972, + 73977, 73985, 73991, 74002, 74015, 74020, 74027, 34243, 74032, 74044, + 74053, 74061, 74071, 74082, 74095, 74102, 74111, 74120, 74128, 74133, + 74139, 1485, 74144, 74149, 74154, 74159, 74165, 74170, 74175, 74181, + 74187, 74192, 74196, 74201, 74206, 74211, 61769, 74216, 74221, 74226, + 74231, 74237, 74243, 74248, 74252, 74257, 74262, 74267, 74273, 74278, + 74284, 74289, 74294, 74299, 74304, 74308, 74314, 74319, 74328, 74333, + 74338, 74343, 74348, 74352, 74359, 74365, 4316, 18083, 3081, 74370, + 74374, 74379, 74383, 74387, 74391, 48498, 74395, 74320, 74397, 74407, + 34252, 74410, 74415, 74424, 74430, 6329, 34257, 74434, 74440, 74445, + 74451, 74456, 74460, 74467, 74472, 74482, 74491, 74495, 74501, 74507, + 74513, 74517, 74525, 74532, 74540, 74548, 34262, 74555, 74558, 74565, + 74571, 74576, 74580, 74586, 74593, 74598, 74602, 74611, 74619, 74625, + 74630, 34267, 74637, 74644, 74650, 74655, 74661, 74668, 74674, 22293, + 28736, 74680, 74685, 74691, 74695, 74707, 74353, 74360, 22469, 74717, + 74722, 74729, 74735, 74742, 74748, 74759, 74764, 74772, 9361, 74777, + 74780, 74786, 74790, 74794, 74797, 74803, 34010, 4317, 1059, 14130, + 74810, 74816, 74822, 74828, 74834, 74840, 74846, 74852, 74858, 74863, + 74868, 74873, 74878, 74883, 74888, 74893, 74898, 74903, 74908, 74913, + 74918, 74923, 74929, 74934, 74939, 74945, 74950, 74955, 74961, 74967, + 74973, 74979, 74985, 74991, 74997, 75003, 75009, 75014, 75019, 75025, + 75030, 75035, 75041, 75046, 75051, 75056, 75061, 75066, 75071, 75076, + 75081, 75086, 75091, 75096, 75101, 75107, 75112, 75117, 75122, 75128, + 75133, 75138, 75143, 75148, 75154, 75159, 75164, 75169, 75174, 75179, + 75184, 75189, 75194, 75199, 75204, 75209, 75214, 75219, 75224, 75229, + 75234, 75239, 75244, 75249, 75255, 75260, 75265, 75270, 75275, 75280, + 75285, 75290, 1871, 147, 75295, 75299, 75303, 75308, 75316, 75320, 75327, + 75335, 75339, 75352, 75360, 75365, 75370, 27545, 75374, 75379, 75383, + 75388, 75392, 75400, 75404, 21910, 75409, 75413, 64050, 75417, 75420, + 75428, 75436, 75444, 75449, 75454, 75461, 75467, 75473, 75478, 75485, + 75490, 75498, 68243, 75505, 75510, 75515, 75519, 12301, 75523, 75528, + 75533, 75537, 75540, 75546, 75550, 75560, 75569, 75573, 75576, 75580, + 75587, 75600, 75606, 75614, 75623, 75634, 75645, 75656, 75667, 75676, + 75682, 75691, 75699, 75709, 75722, 75729, 75740, 75746, 75751, 75756, + 75762, 75768, 75778, 75787, 74034, 75795, 75801, 75809, 75815, 75822, + 75830, 75833, 75837, 75841, 75844, 75850, 75856, 75864, 75876, 75888, + 75895, 75900, 75904, 75915, 75923, 75930, 75942, 75950, 75958, 75965, + 75971, 75981, 75990, 75995, 76005, 76014, 43728, 76021, 76025, 76030, + 76038, 76045, 76051, 76055, 76065, 76076, 76084, 76091, 76103, 76115, + 76124, 72999, 76131, 76141, 76152, 76166, 76174, 76184, 76191, 76199, + 76212, 76224, 76233, 76241, 76251, 76262, 76274, 76283, 76293, 76300, + 76309, 76324, 76332, 76342, 76351, 76359, 76372, 61203, 76387, 76397, + 76406, 76418, 76428, 76440, 76451, 76462, 76473, 76483, 76494, 76502, + 76508, 76518, 76526, 76532, 30400, 76537, 76543, 76548, 76555, 10193, + 18457, 76561, 76570, 76575, 76579, 76586, 76592, 76597, 76602, 76610, + 76618, 76622, 76625, 76628, 76630, 76637, 76643, 76654, 76659, 76663, + 76670, 76676, 76681, 76689, 68782, 68792, 76695, 76702, 76712, 11166, + 76719, 76724, 30611, 76733, 76738, 76745, 76755, 76763, 76771, 76780, + 76786, 76792, 76799, 76806, 76811, 76815, 76823, 76828, 76833, 76842, + 76850, 76857, 76862, 76866, 76875, 76881, 76884, 76888, 76897, 76907, + 75347, 76916, 76924, 76928, 76934, 76945, 76955, 18466, 76966, 76974, + 76982, 18478, 76989, 76993, 77002, 77009, 77012, 28614, 77015, 77019, + 77024, 77041, 77053, 11124, 77065, 77070, 77075, 77080, 21983, 77084, + 77089, 77094, 77100, 77105, 6008, 77110, 21987, 77115, 77120, 77126, + 77133, 77138, 77143, 77149, 77155, 77161, 77166, 77172, 77176, 77190, + 77198, 77206, 77212, 77217, 77224, 77234, 77243, 77248, 77253, 77258, + 77266, 77271, 77277, 77282, 77291, 62848, 77296, 77299, 77317, 77336, + 77349, 77363, 77379, 77386, 77393, 77402, 77409, 77415, 77422, 77427, + 77433, 77439, 77447, 77453, 77458, 77463, 77479, 11137, 77493, 77500, + 77508, 77514, 77518, 77521, 77526, 77531, 77538, 77543, 77552, 77557, + 77563, 77569, 77578, 77587, 77592, 77596, 77604, 77613, 12330, 77622, + 77630, 77636, 77641, 77648, 77654, 12341, 77659, 77662, 77667, 34294, + 77677, 77686, 77691, 77697, 77702, 77710, 77717, 77728, 77738, 77743, + 77751, 68171, 77756, 77762, 77767, 77774, 77783, 77791, 77797, 77803, + 77810, 77816, 77820, 17879, 3090, 77825, 77829, 77833, 77839, 77848, + 77854, 77861, 77865, 77886, 77908, 77924, 77941, 77960, 77969, 77979, + 77987, 77994, 78001, 78007, 28486, 78021, 78025, 78031, 78039, 78051, + 78057, 78065, 78070, 78075, 78079, 78087, 78094, 78098, 78104, 78110, + 78115, 3674, 44898, 78121, 78125, 78129, 78133, 78138, 78143, 78148, + 78154, 78160, 78166, 78173, 78179, 78186, 78192, 78198, 78203, 78209, + 78214, 78218, 78223, 78227, 78232, 44913, 78236, 78241, 78249, 78253, + 78258, 78265, 78274, 78280, 78289, 78293, 78300, 78304, 78307, 78314, + 78320, 78329, 78339, 78344, 78348, 78356, 78365, 78369, 78377, 78383, + 78388, 78393, 78399, 78405, 78410, 78414, 78420, 78425, 78429, 78432, + 78437, 78445, 78455, 78461, 78466, 78476, 42231, 78484, 78496, 78500, + 78506, 78518, 78529, 78536, 78542, 78549, 78556, 78568, 78575, 78581, + 22061, 78585, 78593, 78599, 78606, 78612, 78618, 78624, 78629, 78634, + 78639, 78648, 78656, 78667, 7225, 78672, 17328, 78678, 78682, 78686, + 78690, 78698, 78707, 78711, 78718, 78727, 78735, 78748, 78754, 78228, + 31495, 78759, 78761, 78766, 78771, 78776, 78781, 78786, 78791, 78796, + 78801, 78806, 78811, 78816, 78821, 78826, 78831, 78837, 78842, 78847, + 78852, 78857, 78862, 78867, 78872, 78877, 78883, 78889, 78895, 78900, + 78905, 78917, 78922, 1877, 44, 78927, 78932, 34300, 78936, 34305, 34310, + 34316, 34321, 78940, 34326, 23088, 78962, 78966, 78970, 78975, 78979, + 34330, 78983, 78991, 78998, 34335, 79004, 79007, 79012, 79016, 79025, + 10018, 79033, 34340, 22950, 79036, 79040, 1411, 79045, 34351, 79048, + 79053, 26921, 26931, 36957, 79058, 79063, 79068, 79073, 79079, 79084, + 79093, 79098, 79107, 79115, 79122, 79128, 79133, 79138, 79143, 79153, + 79162, 79170, 79175, 79183, 79187, 79195, 79199, 79206, 79214, 34159, + 39922, 79221, 79227, 79232, 79237, 12703, 29671, 79242, 79247, 79254, + 79260, 79265, 79273, 79283, 79293, 79299, 79304, 79310, 18488, 79317, + 37832, 79330, 79335, 79341, 32482, 79354, 79360, 79364, 79373, 79380, + 79386, 79394, 79403, 79410, 79416, 79419, 79423, 79427, 27062, 79431, + 79438, 79444, 79452, 79457, 25100, 79463, 79466, 79474, 79481, 79489, + 79502, 79516, 79523, 79529, 79536, 79542, 34365, 79546, 79553, 79561, + 79569, 79575, 34370, 79583, 79589, 79594, 79604, 79610, 79619, 32288, + 36388, 79627, 79632, 79637, 79641, 79646, 79650, 79658, 15730, 42244, + 79663, 79668, 34375, 65407, 79672, 79677, 79681, 79688, 79697, 79705, + 79711, 79716, 79722, 79729, 79735, 79740, 79745, 79756, 79765, 79777, + 79792, 34642, 79798, 17447, 34379, 79802, 79809, 25216, 79815, 79822, + 79831, 79838, 79847, 79853, 79858, 79866, 79872, 34389, 79877, 79886, + 78524, 79895, 79902, 79908, 79914, 79923, 79933, 79941, 79948, 79952, + 34394, 79955, 34400, 34406, 79960, 79968, 79976, 79986, 79995, 80003, + 80010, 80020, 34411, 80024, 80026, 80030, 80035, 80039, 80043, 80049, + 80054, 80058, 80069, 80074, 80079, 3095, 80083, 80090, 80094, 80103, + 80111, 80118, 80123, 80128, 65458, 80132, 80135, 80141, 80149, 80155, + 80159, 80164, 80171, 80176, 80180, 80186, 36419, 80191, 80194, 80199, + 80203, 80208, 80215, 80220, 80224, 40816, 80232, 26940, 26949, 80238, + 80244, 80250, 80255, 80259, 80262, 80272, 80281, 80286, 80292, 80299, + 80305, 80309, 80317, 80322, 36425, 75542, 80326, 80334, 80340, 80347, + 80352, 80356, 80361, 61419, 80367, 36431, 80372, 80377, 80381, 80386, + 80391, 80396, 80400, 80405, 80410, 80416, 80421, 80426, 80432, 80438, + 80443, 80447, 80452, 80457, 80462, 80466, 25215, 80471, 80476, 80482, + 80488, 80494, 80499, 80503, 80508, 80513, 80518, 80522, 80527, 80532, + 80537, 80542, 45168, 80546, 34419, 80554, 80558, 80566, 80574, 80585, + 80590, 80594, 23428, 80599, 80605, 80610, 80620, 80627, 80632, 80640, + 80649, 80654, 80658, 80663, 80671, 80679, 80686, 68424, 80692, 80700, + 80707, 80718, 80724, 80730, 34429, 80733, 80740, 80748, 80753, 42447, + 80757, 80762, 80769, 80774, 9239, 80778, 80786, 80793, 80800, 80809, + 80816, 80822, 80836, 10473, 80844, 80850, 80854, 80857, 80865, 80872, + 80877, 80890, 80897, 80901, 80906, 80913, 80918, 63934, 80923, 80926, + 80933, 80939, 80943, 80951, 80960, 80970, 80980, 80989, 81000, 81008, + 81019, 81024, 81028, 81033, 81037, 37088, 81045, 22356, 37097, 81050, + 81055, 81060, 81065, 81070, 81075, 81080, 81084, 81089, 81094, 81099, + 81104, 81109, 81114, 81118, 81123, 81128, 81132, 81136, 81140, 81144, + 81149, 81154, 81158, 81163, 81167, 81171, 81176, 81181, 81186, 81191, + 81195, 81200, 81205, 81209, 81214, 81219, 81224, 81229, 81234, 81239, + 81244, 81249, 81254, 81259, 81264, 81269, 81274, 81279, 81284, 81289, + 81294, 81299, 81304, 81309, 81313, 81318, 81323, 81328, 81333, 81338, + 81343, 81348, 81353, 81358, 81363, 81368, 81372, 81377, 81381, 81386, + 81391, 81396, 81401, 81406, 81411, 81416, 81421, 81426, 81430, 81434, + 81439, 81444, 81448, 81453, 81458, 81462, 81467, 81472, 81477, 81482, + 81486, 81491, 81496, 81500, 81505, 81509, 81513, 81517, 81521, 81526, + 81530, 81534, 81538, 81542, 81546, 81550, 81554, 81558, 81562, 81567, + 81572, 81577, 81582, 81587, 81592, 81597, 81602, 81607, 81612, 81616, + 81620, 81624, 81628, 81632, 81636, 81641, 81645, 81650, 81654, 81659, + 81664, 81668, 81672, 81677, 81681, 81685, 81689, 81693, 81697, 81701, + 81705, 81709, 81713, 81717, 81721, 81725, 81729, 81733, 81738, 81743, + 81747, 81751, 81755, 81759, 81763, 81767, 81772, 81776, 81780, 81784, + 81788, 81792, 81796, 81801, 81805, 81810, 81814, 81818, 81822, 81826, + 81830, 81834, 81838, 81842, 81846, 81850, 81854, 81859, 81863, 81867, + 81871, 81875, 81879, 81883, 81887, 81891, 81895, 81899, 81903, 81908, + 81912, 81916, 81921, 81926, 81930, 81934, 81938, 81942, 81946, 81950, + 81954, 81958, 81963, 81967, 81972, 81976, 81981, 81985, 81990, 81994, + 82000, 82005, 82009, 82014, 82018, 82023, 82027, 82032, 82036, 82041, + 1504, 82045, 2854, 1759, 1677, 82049, 82053, 2863, 82057, 1380, 82062, + 1322, 82066, 2875, 82070, 82077, 82084, 82098, 2879, 7327, 82107, 82115, + 82122, 82133, 82142, 82149, 82161, 82174, 82187, 82198, 82203, 82210, + 82222, 82226, 2883, 12408, 82236, 82241, 82250, 82260, 82265, 2887, + 82273, 82277, 82282, 82289, 82295, 82303, 82315, 1327, 13735, 82325, + 82329, 82335, 82349, 82361, 82373, 82383, 82392, 82401, 82410, 82418, + 82429, 82437, 4203, 82447, 82458, 82467, 82473, 82488, 82495, 82501, + 82506, 37227, 82511, 2911, 13739, 82515, 82522, 9177, 82531, 2916, 33887, + 82537, 63675, 82544, 82550, 82561, 82567, 82574, 82580, 82588, 82595, + 82601, 82611, 82620, 82631, 82640, 82647, 82653, 82663, 82671, 82677, + 82692, 82698, 82703, 82710, 82713, 82719, 82726, 82732, 82740, 82749, + 82757, 82763, 82772, 44438, 82786, 82791, 82797, 15536, 82802, 82815, + 82827, 82836, 82844, 82851, 82855, 82859, 82862, 82869, 82876, 82884, + 82892, 82901, 82909, 15463, 82917, 82922, 82926, 82938, 82945, 82954, + 781, 82964, 82973, 82984, 2932, 82988, 82992, 82998, 83011, 83023, 83033, + 83042, 83054, 27597, 83065, 83073, 83082, 83093, 83104, 83114, 83124, + 83133, 83141, 11944, 83148, 83152, 83155, 83160, 83165, 83169, 83175, + 1332, 83182, 83186, 12490, 83190, 83201, 83210, 83218, 83227, 83235, + 83251, 83262, 83271, 83279, 83291, 83302, 83318, 83328, 83349, 83363, + 83376, 83384, 83391, 7373, 83404, 83409, 83415, 6078, 83421, 83424, + 83431, 83441, 8395, 83448, 83453, 83458, 83463, 83471, 83480, 83488, + 10241, 10250, 83493, 83504, 83509, 83515, 2948, 1160, 83521, 11449, + 83527, 83534, 83541, 83554, 2262, 68, 83559, 83564, 83574, 83583, 83589, + 83598, 83606, 83616, 83620, 83625, 83629, 83641, 2976, 83649, 83657, + 83662, 83673, 83684, 83693, 22397, 83698, 83704, 83709, 83719, 83729, + 83734, 83740, 83744, 83749, 83758, 22409, 83762, 4280, 24, 83767, 83776, + 83783, 83790, 83796, 83802, 954, 83807, 83812, 64016, 83817, 83822, + 83828, 83834, 83842, 83847, 83855, 83862, 83868, 83873, 40700, 44332, + 83879, 2980, 32, 83889, 83902, 83907, 83915, 83920, 83926, 3002, 29639, + 83931, 83939, 83946, 83951, 83960, 61661, 65078, 83968, 83972, 1704, + 1818, 83977, 83982, 83989, 1822, 254, 83996, 84002, 3024, 84007, 84012, + 84019, 1826, 84024, 84030, 84035, 84047, 6305, 84057, 1833, 84063, 84068, + 84075, 84082, 84097, 84104, 84115, 84120, 84128, 2638, 84132, 84144, + 84149, 84153, 84159, 29455, 2267, 84163, 84174, 84178, 84182, 84188, + 84192, 84201, 84205, 84216, 84220, 2313, 33704, 84224, 84234, 3115, + 84242, 9661, 84251, 84256, 84260, 84269, 84276, 84282, 3085, 18093, + 84286, 84299, 84317, 84322, 84330, 84338, 84348, 10480, 13852, 84360, + 84373, 84380, 84394, 84401, 84417, 84424, 84430, 22441, 13100, 84437, + 84444, 84454, 84463, 45167, 84475, 45302, 84483, 84486, 84492, 84498, + 84504, 84510, 84516, 84523, 84530, 84536, 84542, 84548, 84554, 84560, + 84566, 84572, 84578, 84584, 84590, 84596, 84602, 84608, 84614, 84620, + 84626, 84632, 84638, 84644, 84650, 84656, 84662, 84668, 84674, 84680, + 84686, 84692, 84698, 84704, 84710, 84716, 84722, 84728, 84734, 84740, + 84746, 84752, 84758, 84764, 84770, 84776, 84782, 84788, 84794, 84800, + 84806, 84812, 84818, 84824, 84830, 84836, 84843, 84849, 84856, 84863, + 84869, 84876, 84883, 84889, 84895, 84901, 84907, 84913, 84919, 84925, + 84931, 84937, 84943, 84949, 84955, 84961, 84967, 84973, 3099, 9634, + 84979, 84985, 84993, 84997, 82285, 3103, 85001, 22174, 12733, 3885, + 85005, 3109, 85009, 85019, 85025, 85031, 85037, 85043, 85049, 85055, + 85061, 85067, 85073, 85079, 85085, 85091, 85097, 85103, 85109, 85115, + 85121, 85127, 85133, 85139, 85145, 85151, 85157, 85163, 85169, 85176, + 85183, 85189, 85195, 85201, 85207, 85213, 85219, 1337, 85225, 85230, + 85235, 85240, 85245, 85250, 85255, 85260, 85265, 85269, 85273, 85277, + 85281, 85285, 85289, 85293, 85297, 85301, 85307, 85313, 85319, 85325, + 85329, 85333, 85337, 85341, 85345, 85349, 85353, 85357, 85361, 85366, + 85371, 85376, 85381, 85386, 85391, 85396, 85401, 85406, 85411, 85416, + 85421, 85426, 85431, 85436, 85441, 85446, 85451, 85456, 85461, 85466, + 85471, 85476, 85481, 85486, 85491, 85496, 85501, 85506, 85511, 85516, + 85521, 85526, 85531, 85536, 85541, 85546, 85551, 85556, 85561, 85566, + 85571, 85576, 85581, 85586, 85591, 85596, 85601, 85606, 85611, 85616, + 85621, 85626, 85631, 85636, 85641, 85646, 85651, 85656, 85661, 85666, + 85671, 85676, 85681, 85686, 85691, 85696, 85701, 85706, 85711, 85716, + 85721, 85726, 85731, 85736, 85741, 85746, 85751, 85756, 85761, 85766, + 85771, 85776, 85781, 85786, 85791, 85796, 85801, 85806, 85811, 85816, + 85821, 85826, 85831, 85836, 85841, 85846, 85851, 85856, 85861, 85866, + 85871, 85876, 85881, 85886, 85891, 85896, 85901, 85906, 85911, 85916, + 85921, 85926, 85931, 85936, 85941, 85946, 85951, 85956, 85961, 85966, + 85971, 85976, 85981, 85986, 85991, 85996, 86001, 86006, 86011, 86016, + 86021, 86030, 86039, 86048, 86057, 86066, 86075, 86084, 86093, 86102, + 86111, 86120, 86129, 86138, 86147, 86156, 86165, 86174, 86183, 86192, + 86197, 86202, 86207, 86212, 86217, 86222, 86227, 86232, 86237, 86242, + 86247, 86252, 86257, 86262, 86267, 86272, 86277, 86282, 86287, 86292, + 86297, 86302, 86307, 86312, 86317, 86322, 86327, 86332, 86337, 86342, + 86347, 86352, 86357, 86362, 86367, 86372, 86377, 86382, 86387, 86392, + 86397, 86402, 86407, 86412, 86417, 86422, 86427, 86432, 86437, 86442, + 86447, 86452, 86457, 86462, 86467, 86472, 86477, 86482, 86488, 86494, + 86500, 86505, 86510, 86515, 86521, 86527, 86533, 86538, 86543, 86548, + 86553, 86558, 86563, 86568, 16922, 12755, 86573, 86579, 86585, 86594, + 86599, 86604, 86609, 86614, 86619, 86624, 86629, 86634, 86639, 86644, + 86649, 86654, 86659, 86664, 86669, 86674, 86679, 86684, 86689, 86694, + 86699, 86704, 86709, 86714, 86719, 86725, 86730, 86735, 86741, 86746, + 86752, 86757, 86762, 86768, 86773, 86778, 86783, 86788, 86793, 86798, + 86803, 86808, 85020, 85026, 85032, 85038, 86814, 85044, 85050, 85056, + 85062, 85068, 85074, 85080, 85086, 85092, 85098, 85104, 86820, 85110, + 85116, 85122, 86826, 85128, 85134, 85140, 85146, 85152, 85158, 85164, + 85184, 86832, 86838, 85190, 86844, 85196, 85202, 85208, 85214, 85220, + 3126, 3131, 86850, 86855, 86858, 86864, 86870, 86877, 86882, 86887, 2318, }; /* code->name phrasebook */ -#define phrasebook_shift 7 -#define phrasebook_short 209 +#define phrasebook_shift 8 +#define phrasebook_short 204 static unsigned char phrasebook[] = { - 0, 219, 20, 245, 39, 79, 224, 1, 79, 54, 50, 247, 140, 50, 225, 185, 50, - 254, 134, 254, 65, 43, 226, 7, 44, 226, 7, 253, 224, 96, 50, 249, 227, - 240, 174, 243, 236, 218, 131, 219, 48, 21, 210, 86, 21, 111, 21, 105, 21, - 158, 21, 161, 21, 190, 21, 195, 21, 199, 21, 196, 21, 201, 249, 234, 220, - 152, 233, 21, 50, 245, 106, 50, 242, 137, 50, 224, 16, 79, 249, 225, 253, - 214, 7, 6, 1, 61, 7, 6, 1, 253, 166, 7, 6, 1, 251, 74, 7, 6, 1, 249, 68, - 7, 6, 1, 76, 7, 6, 1, 245, 14, 7, 6, 1, 243, 209, 7, 6, 1, 242, 67, 7, 6, - 1, 74, 7, 6, 1, 235, 150, 7, 6, 1, 235, 29, 7, 6, 1, 156, 7, 6, 1, 194, - 7, 6, 1, 230, 30, 7, 6, 1, 78, 7, 6, 1, 226, 109, 7, 6, 1, 224, 99, 7, 6, - 1, 153, 7, 6, 1, 222, 93, 7, 6, 1, 217, 153, 7, 6, 1, 69, 7, 6, 1, 214, - 105, 7, 6, 1, 212, 98, 7, 6, 1, 211, 178, 7, 6, 1, 211, 117, 7, 6, 1, - 210, 159, 43, 42, 127, 223, 53, 219, 48, 44, 42, 127, 250, 39, 255, 23, - 121, 232, 219, 242, 144, 255, 23, 7, 4, 1, 61, 7, 4, 1, 253, 166, 7, 4, - 1, 251, 74, 7, 4, 1, 249, 68, 7, 4, 1, 76, 7, 4, 1, 245, 14, 7, 4, 1, - 243, 209, 7, 4, 1, 242, 67, 7, 4, 1, 74, 7, 4, 1, 235, 150, 7, 4, 1, 235, - 29, 7, 4, 1, 156, 7, 4, 1, 194, 7, 4, 1, 230, 30, 7, 4, 1, 78, 7, 4, 1, - 226, 109, 7, 4, 1, 224, 99, 7, 4, 1, 153, 7, 4, 1, 222, 93, 7, 4, 1, 217, - 153, 7, 4, 1, 69, 7, 4, 1, 214, 105, 7, 4, 1, 212, 98, 7, 4, 1, 211, 178, - 7, 4, 1, 211, 117, 7, 4, 1, 210, 159, 43, 249, 107, 127, 67, 232, 219, - 44, 249, 107, 127, 184, 228, 78, 219, 20, 235, 200, 245, 39, 79, 250, - 184, 50, 224, 231, 50, 249, 106, 50, 211, 40, 50, 251, 143, 130, 221, - 175, 50, 248, 9, 249, 171, 50, 244, 144, 226, 158, 235, 245, 233, 48, 52, - 254, 118, 224, 1, 79, 228, 57, 50, 219, 54, 240, 175, 223, 105, 50, 231, - 237, 248, 79, 50, 225, 24, 50, 218, 24, 105, 218, 24, 158, 255, 12, 255, - 23, 230, 233, 50, 225, 71, 50, 230, 229, 247, 128, 250, 191, 218, 24, - 111, 231, 153, 226, 158, 235, 245, 222, 250, 52, 254, 118, 224, 1, 79, - 212, 114, 244, 10, 123, 224, 24, 212, 114, 244, 10, 123, 242, 34, 212, - 114, 244, 10, 134, 224, 22, 235, 200, 224, 16, 79, 7, 6, 1, 116, 2, 242, - 143, 7, 6, 1, 116, 2, 142, 7, 6, 1, 116, 2, 250, 38, 7, 6, 1, 116, 2, - 184, 7, 6, 1, 116, 2, 248, 9, 7, 6, 1, 116, 2, 222, 237, 48, 7, 6, 1, - 254, 252, 7, 6, 1, 251, 75, 2, 250, 191, 7, 6, 1, 160, 2, 242, 143, 7, 6, - 1, 160, 2, 142, 7, 6, 1, 160, 2, 250, 38, 7, 6, 1, 160, 2, 248, 9, 7, 6, - 1, 240, 161, 2, 242, 143, 7, 6, 1, 240, 161, 2, 142, 7, 6, 1, 240, 161, - 2, 250, 38, 7, 6, 1, 240, 161, 2, 248, 9, 7, 6, 1, 245, 67, 7, 6, 1, 230, - 31, 2, 184, 7, 6, 1, 144, 2, 242, 143, 7, 6, 1, 144, 2, 142, 7, 6, 1, - 144, 2, 250, 38, 7, 6, 1, 144, 2, 184, 7, 6, 1, 144, 2, 248, 9, 230, 89, - 50, 7, 6, 1, 144, 2, 91, 7, 6, 1, 104, 2, 242, 143, 7, 6, 1, 104, 2, 142, - 7, 6, 1, 104, 2, 250, 38, 7, 6, 1, 104, 2, 248, 9, 7, 6, 1, 211, 118, 2, - 142, 7, 6, 1, 216, 152, 7, 4, 1, 220, 78, 222, 93, 7, 4, 1, 116, 2, 242, - 143, 7, 4, 1, 116, 2, 142, 7, 4, 1, 116, 2, 250, 38, 7, 4, 1, 116, 2, - 184, 7, 4, 1, 116, 2, 248, 9, 7, 4, 1, 116, 2, 222, 237, 48, 7, 4, 1, - 254, 252, 7, 4, 1, 251, 75, 2, 250, 191, 7, 4, 1, 160, 2, 242, 143, 7, 4, - 1, 160, 2, 142, 7, 4, 1, 160, 2, 250, 38, 7, 4, 1, 160, 2, 248, 9, 7, 4, - 1, 240, 161, 2, 242, 143, 7, 4, 1, 240, 161, 2, 142, 7, 4, 1, 240, 161, - 2, 250, 38, 7, 4, 1, 240, 161, 2, 248, 9, 7, 4, 1, 245, 67, 7, 4, 1, 230, - 31, 2, 184, 7, 4, 1, 144, 2, 242, 143, 7, 4, 1, 144, 2, 142, 7, 4, 1, - 144, 2, 250, 38, 7, 4, 1, 144, 2, 184, 7, 4, 1, 144, 2, 248, 9, 247, 177, - 50, 7, 4, 1, 144, 2, 91, 7, 4, 1, 104, 2, 242, 143, 7, 4, 1, 104, 2, 142, - 7, 4, 1, 104, 2, 250, 38, 7, 4, 1, 104, 2, 248, 9, 7, 4, 1, 211, 118, 2, - 142, 7, 4, 1, 216, 152, 7, 4, 1, 211, 118, 2, 248, 9, 7, 6, 1, 116, 2, - 231, 237, 7, 4, 1, 116, 2, 231, 237, 7, 6, 1, 116, 2, 251, 154, 7, 4, 1, - 116, 2, 251, 154, 7, 6, 1, 116, 2, 226, 228, 7, 4, 1, 116, 2, 226, 228, - 7, 6, 1, 251, 75, 2, 142, 7, 4, 1, 251, 75, 2, 142, 7, 6, 1, 251, 75, 2, - 250, 38, 7, 4, 1, 251, 75, 2, 250, 38, 7, 6, 1, 251, 75, 2, 59, 48, 7, 4, - 1, 251, 75, 2, 59, 48, 7, 6, 1, 251, 75, 2, 250, 242, 7, 4, 1, 251, 75, - 2, 250, 242, 7, 6, 1, 249, 69, 2, 250, 242, 7, 4, 1, 249, 69, 2, 250, - 242, 7, 6, 1, 249, 69, 2, 91, 7, 4, 1, 249, 69, 2, 91, 7, 6, 1, 160, 2, - 231, 237, 7, 4, 1, 160, 2, 231, 237, 7, 6, 1, 160, 2, 251, 154, 7, 4, 1, - 160, 2, 251, 154, 7, 6, 1, 160, 2, 59, 48, 7, 4, 1, 160, 2, 59, 48, 7, 6, - 1, 160, 2, 226, 228, 7, 4, 1, 160, 2, 226, 228, 7, 6, 1, 160, 2, 250, - 242, 7, 4, 1, 160, 2, 250, 242, 7, 6, 1, 243, 210, 2, 250, 38, 7, 4, 1, - 243, 210, 2, 250, 38, 7, 6, 1, 243, 210, 2, 251, 154, 7, 4, 1, 243, 210, - 2, 251, 154, 7, 6, 1, 243, 210, 2, 59, 48, 7, 4, 1, 243, 210, 2, 59, 48, - 7, 6, 1, 243, 210, 2, 250, 191, 7, 4, 1, 243, 210, 2, 250, 191, 7, 6, 1, - 242, 68, 2, 250, 38, 7, 4, 1, 242, 68, 2, 250, 38, 7, 6, 1, 242, 68, 2, - 91, 7, 4, 1, 242, 68, 2, 91, 7, 6, 1, 240, 161, 2, 184, 7, 4, 1, 240, - 161, 2, 184, 7, 6, 1, 240, 161, 2, 231, 237, 7, 4, 1, 240, 161, 2, 231, - 237, 7, 6, 1, 240, 161, 2, 251, 154, 7, 4, 1, 240, 161, 2, 251, 154, 7, - 6, 1, 240, 161, 2, 226, 228, 7, 4, 1, 240, 161, 2, 226, 228, 7, 6, 1, - 240, 161, 2, 59, 48, 7, 4, 1, 247, 127, 74, 7, 6, 27, 236, 38, 7, 4, 27, - 236, 38, 7, 6, 1, 235, 151, 2, 250, 38, 7, 4, 1, 235, 151, 2, 250, 38, 7, - 6, 1, 235, 30, 2, 250, 191, 7, 4, 1, 235, 30, 2, 250, 191, 7, 4, 1, 233, - 245, 7, 6, 1, 233, 155, 2, 142, 7, 4, 1, 233, 155, 2, 142, 7, 6, 1, 233, - 155, 2, 250, 191, 7, 4, 1, 233, 155, 2, 250, 191, 7, 6, 1, 233, 155, 2, - 250, 242, 7, 4, 1, 233, 155, 2, 250, 242, 7, 6, 1, 233, 155, 2, 230, 229, - 247, 128, 7, 4, 1, 233, 155, 2, 230, 229, 247, 128, 7, 6, 1, 233, 155, 2, - 91, 7, 4, 1, 233, 155, 2, 91, 7, 6, 1, 230, 31, 2, 142, 7, 4, 1, 230, 31, - 2, 142, 7, 6, 1, 230, 31, 2, 250, 191, 7, 4, 1, 230, 31, 2, 250, 191, 7, - 6, 1, 230, 31, 2, 250, 242, 7, 4, 1, 230, 31, 2, 250, 242, 7, 4, 1, 230, - 31, 224, 207, 251, 86, 254, 65, 7, 6, 1, 245, 146, 7, 4, 1, 245, 146, 7, - 6, 1, 144, 2, 231, 237, 7, 4, 1, 144, 2, 231, 237, 7, 6, 1, 144, 2, 251, - 154, 7, 4, 1, 144, 2, 251, 154, 7, 6, 1, 144, 2, 52, 142, 7, 4, 1, 144, - 2, 52, 142, 7, 6, 27, 226, 238, 7, 4, 27, 226, 238, 7, 6, 1, 223, 227, 2, - 142, 7, 4, 1, 223, 227, 2, 142, 7, 6, 1, 223, 227, 2, 250, 191, 7, 4, 1, - 223, 227, 2, 250, 191, 7, 6, 1, 223, 227, 2, 250, 242, 7, 4, 1, 223, 227, - 2, 250, 242, 7, 6, 1, 222, 94, 2, 142, 7, 4, 1, 222, 94, 2, 142, 7, 6, 1, - 222, 94, 2, 250, 38, 7, 4, 1, 222, 94, 2, 250, 38, 7, 6, 1, 222, 94, 2, - 250, 191, 7, 4, 1, 222, 94, 2, 250, 191, 7, 6, 1, 222, 94, 2, 250, 242, - 7, 4, 1, 222, 94, 2, 250, 242, 7, 6, 1, 217, 154, 2, 250, 191, 7, 4, 1, - 217, 154, 2, 250, 191, 7, 6, 1, 217, 154, 2, 250, 242, 7, 4, 1, 217, 154, - 2, 250, 242, 7, 6, 1, 217, 154, 2, 91, 7, 4, 1, 217, 154, 2, 91, 7, 6, 1, - 104, 2, 184, 7, 4, 1, 104, 2, 184, 7, 6, 1, 104, 2, 231, 237, 7, 4, 1, - 104, 2, 231, 237, 7, 6, 1, 104, 2, 251, 154, 7, 4, 1, 104, 2, 251, 154, - 7, 6, 1, 104, 2, 222, 237, 48, 7, 4, 1, 104, 2, 222, 237, 48, 7, 6, 1, - 104, 2, 52, 142, 7, 4, 1, 104, 2, 52, 142, 7, 6, 1, 104, 2, 226, 228, 7, - 4, 1, 104, 2, 226, 228, 7, 6, 1, 212, 99, 2, 250, 38, 7, 4, 1, 212, 99, - 2, 250, 38, 7, 6, 1, 211, 118, 2, 250, 38, 7, 4, 1, 211, 118, 2, 250, 38, - 7, 6, 1, 211, 118, 2, 248, 9, 7, 6, 1, 210, 160, 2, 142, 7, 4, 1, 210, - 160, 2, 142, 7, 6, 1, 210, 160, 2, 59, 48, 7, 4, 1, 210, 160, 2, 59, 48, - 7, 6, 1, 210, 160, 2, 250, 242, 7, 4, 1, 210, 160, 2, 250, 242, 7, 4, 1, - 200, 222, 93, 7, 4, 1, 57, 2, 91, 7, 6, 1, 57, 2, 103, 7, 6, 1, 57, 2, - 216, 12, 7, 4, 1, 57, 2, 216, 12, 7, 6, 1, 138, 195, 7, 4, 1, 138, 195, - 7, 6, 1, 204, 78, 7, 6, 1, 251, 75, 2, 103, 7, 4, 1, 251, 75, 2, 103, 7, - 6, 1, 254, 228, 249, 68, 7, 6, 1, 249, 69, 2, 103, 7, 6, 1, 249, 69, 2, - 216, 12, 7, 4, 1, 249, 69, 2, 216, 12, 7, 4, 1, 215, 94, 248, 62, 7, 6, - 1, 223, 52, 76, 7, 6, 1, 221, 197, 7, 6, 1, 204, 76, 7, 6, 1, 245, 15, 2, - 103, 7, 4, 1, 245, 15, 2, 103, 7, 6, 1, 243, 210, 2, 103, 7, 6, 1, 243, - 114, 7, 4, 1, 240, 208, 7, 6, 1, 235, 192, 7, 6, 1, 240, 161, 2, 91, 7, - 6, 1, 235, 30, 2, 103, 7, 4, 1, 235, 30, 2, 103, 7, 4, 1, 233, 155, 2, - 130, 7, 4, 1, 233, 106, 2, 91, 7, 6, 1, 215, 94, 194, 7, 6, 1, 230, 31, - 2, 43, 103, 7, 4, 1, 230, 31, 2, 200, 44, 233, 42, 7, 6, 1, 144, 2, 230, - 229, 184, 7, 6, 1, 144, 2, 240, 255, 7, 4, 1, 144, 2, 240, 255, 7, 6, 1, - 226, 223, 7, 4, 1, 226, 223, 7, 6, 1, 226, 110, 2, 103, 7, 4, 1, 226, - 110, 2, 103, 7, 1, 210, 214, 7, 6, 1, 138, 105, 7, 4, 1, 138, 105, 7, 6, - 1, 245, 83, 7, 1, 223, 52, 245, 84, 232, 129, 7, 4, 1, 217, 154, 2, 226, - 70, 103, 7, 6, 1, 217, 154, 2, 103, 7, 4, 1, 217, 154, 2, 103, 7, 6, 1, - 217, 154, 2, 223, 58, 103, 7, 6, 1, 104, 2, 240, 255, 7, 4, 1, 104, 2, - 240, 255, 7, 6, 1, 214, 157, 7, 6, 1, 214, 106, 2, 103, 7, 6, 1, 211, - 118, 2, 103, 7, 4, 1, 211, 118, 2, 103, 7, 6, 1, 210, 160, 2, 91, 7, 4, - 1, 210, 160, 2, 91, 7, 6, 1, 245, 16, 7, 6, 1, 245, 17, 223, 51, 7, 4, 1, - 245, 17, 223, 51, 7, 4, 1, 245, 17, 2, 217, 78, 7, 1, 113, 2, 91, 7, 6, - 1, 138, 190, 7, 4, 1, 138, 190, 7, 1, 235, 200, 242, 187, 218, 132, 2, - 91, 7, 1, 211, 181, 7, 1, 248, 55, 250, 19, 7, 1, 233, 83, 250, 19, 7, 1, - 254, 145, 250, 19, 7, 1, 223, 58, 250, 19, 7, 6, 1, 246, 48, 2, 250, 242, - 7, 6, 1, 249, 69, 2, 4, 1, 210, 160, 2, 250, 242, 7, 4, 1, 246, 48, 2, - 250, 242, 7, 6, 1, 232, 194, 7, 6, 1, 233, 155, 2, 4, 1, 235, 150, 7, 4, - 1, 232, 194, 7, 6, 1, 228, 191, 7, 6, 1, 230, 31, 2, 4, 1, 235, 150, 7, - 4, 1, 228, 191, 7, 6, 1, 116, 2, 250, 242, 7, 4, 1, 116, 2, 250, 242, 7, - 6, 1, 240, 161, 2, 250, 242, 7, 4, 1, 240, 161, 2, 250, 242, 7, 6, 1, - 144, 2, 250, 242, 7, 4, 1, 144, 2, 250, 242, 7, 6, 1, 104, 2, 250, 242, - 7, 4, 1, 104, 2, 250, 242, 7, 6, 1, 104, 2, 248, 10, 22, 231, 237, 7, 4, - 1, 104, 2, 248, 10, 22, 231, 237, 7, 6, 1, 104, 2, 248, 10, 22, 142, 7, - 4, 1, 104, 2, 248, 10, 22, 142, 7, 6, 1, 104, 2, 248, 10, 22, 250, 242, - 7, 4, 1, 104, 2, 248, 10, 22, 250, 242, 7, 6, 1, 104, 2, 248, 10, 22, - 242, 143, 7, 4, 1, 104, 2, 248, 10, 22, 242, 143, 7, 4, 1, 215, 94, 76, - 7, 6, 1, 116, 2, 248, 10, 22, 231, 237, 7, 4, 1, 116, 2, 248, 10, 22, - 231, 237, 7, 6, 1, 116, 2, 59, 72, 22, 231, 237, 7, 4, 1, 116, 2, 59, 72, - 22, 231, 237, 7, 6, 1, 254, 253, 2, 231, 237, 7, 4, 1, 254, 253, 2, 231, - 237, 7, 6, 1, 243, 210, 2, 91, 7, 4, 1, 243, 210, 2, 91, 7, 6, 1, 243, - 210, 2, 250, 242, 7, 4, 1, 243, 210, 2, 250, 242, 7, 6, 1, 235, 30, 2, - 250, 242, 7, 4, 1, 235, 30, 2, 250, 242, 7, 6, 1, 144, 2, 226, 228, 7, 4, - 1, 144, 2, 226, 228, 7, 6, 1, 144, 2, 226, 229, 22, 231, 237, 7, 4, 1, - 144, 2, 226, 229, 22, 231, 237, 7, 6, 1, 245, 17, 2, 250, 242, 7, 4, 1, - 245, 17, 2, 250, 242, 7, 4, 1, 235, 151, 2, 250, 242, 7, 6, 1, 246, 47, - 7, 6, 1, 249, 69, 2, 4, 1, 210, 159, 7, 4, 1, 246, 47, 7, 6, 1, 243, 210, - 2, 142, 7, 4, 1, 243, 210, 2, 142, 7, 6, 1, 240, 206, 7, 6, 1, 211, 181, - 7, 6, 1, 230, 31, 2, 242, 143, 7, 4, 1, 230, 31, 2, 242, 143, 7, 6, 1, - 116, 2, 222, 237, 72, 22, 142, 7, 4, 1, 116, 2, 222, 237, 72, 22, 142, 7, - 6, 1, 254, 253, 2, 142, 7, 4, 1, 254, 253, 2, 142, 7, 6, 1, 144, 2, 218, - 105, 22, 142, 7, 4, 1, 144, 2, 218, 105, 22, 142, 7, 6, 1, 116, 2, 52, - 242, 143, 7, 4, 1, 116, 2, 52, 242, 143, 7, 6, 1, 116, 2, 235, 200, 251, - 154, 7, 4, 1, 116, 2, 235, 200, 251, 154, 7, 6, 1, 160, 2, 52, 242, 143, - 7, 4, 1, 160, 2, 52, 242, 143, 7, 6, 1, 160, 2, 235, 200, 251, 154, 7, 4, - 1, 160, 2, 235, 200, 251, 154, 7, 6, 1, 240, 161, 2, 52, 242, 143, 7, 4, - 1, 240, 161, 2, 52, 242, 143, 7, 6, 1, 240, 161, 2, 235, 200, 251, 154, - 7, 4, 1, 240, 161, 2, 235, 200, 251, 154, 7, 6, 1, 144, 2, 52, 242, 143, - 7, 4, 1, 144, 2, 52, 242, 143, 7, 6, 1, 144, 2, 235, 200, 251, 154, 7, 4, - 1, 144, 2, 235, 200, 251, 154, 7, 6, 1, 223, 227, 2, 52, 242, 143, 7, 4, - 1, 223, 227, 2, 52, 242, 143, 7, 6, 1, 223, 227, 2, 235, 200, 251, 154, - 7, 4, 1, 223, 227, 2, 235, 200, 251, 154, 7, 6, 1, 104, 2, 52, 242, 143, - 7, 4, 1, 104, 2, 52, 242, 143, 7, 6, 1, 104, 2, 235, 200, 251, 154, 7, 4, - 1, 104, 2, 235, 200, 251, 154, 7, 6, 1, 222, 94, 2, 249, 228, 51, 7, 4, - 1, 222, 94, 2, 249, 228, 51, 7, 6, 1, 217, 154, 2, 249, 228, 51, 7, 4, 1, - 217, 154, 2, 249, 228, 51, 7, 6, 1, 210, 231, 7, 4, 1, 210, 231, 7, 6, 1, - 242, 68, 2, 250, 242, 7, 4, 1, 242, 68, 2, 250, 242, 7, 6, 1, 230, 31, 2, - 200, 44, 233, 42, 7, 4, 1, 249, 69, 2, 249, 108, 7, 6, 1, 226, 138, 7, 4, - 1, 226, 138, 7, 6, 1, 210, 160, 2, 103, 7, 4, 1, 210, 160, 2, 103, 7, 6, - 1, 116, 2, 59, 48, 7, 4, 1, 116, 2, 59, 48, 7, 6, 1, 160, 2, 250, 191, 7, - 4, 1, 160, 2, 250, 191, 7, 6, 1, 144, 2, 248, 10, 22, 231, 237, 7, 4, 1, - 144, 2, 248, 10, 22, 231, 237, 7, 6, 1, 144, 2, 216, 90, 22, 231, 237, 7, - 4, 1, 144, 2, 216, 90, 22, 231, 237, 7, 6, 1, 144, 2, 59, 48, 7, 4, 1, - 144, 2, 59, 48, 7, 6, 1, 144, 2, 59, 72, 22, 231, 237, 7, 4, 1, 144, 2, - 59, 72, 22, 231, 237, 7, 6, 1, 211, 118, 2, 231, 237, 7, 4, 1, 211, 118, - 2, 231, 237, 7, 4, 1, 233, 155, 2, 249, 108, 7, 4, 1, 230, 31, 2, 249, - 108, 7, 4, 1, 217, 154, 2, 249, 108, 7, 4, 1, 247, 127, 235, 150, 7, 4, - 1, 248, 151, 247, 228, 7, 4, 1, 224, 34, 247, 228, 7, 6, 1, 116, 2, 91, - 7, 6, 1, 251, 75, 2, 91, 7, 4, 1, 251, 75, 2, 91, 7, 6, 1, 233, 155, 2, - 130, 7, 6, 1, 217, 154, 2, 248, 7, 91, 7, 4, 1, 222, 94, 2, 217, 251, - 217, 78, 7, 4, 1, 210, 160, 2, 217, 251, 217, 78, 7, 6, 1, 242, 187, 218, - 131, 7, 4, 1, 242, 187, 218, 131, 7, 6, 1, 57, 2, 91, 7, 6, 1, 104, 130, - 7, 6, 1, 215, 94, 214, 105, 7, 6, 1, 160, 2, 91, 7, 4, 1, 160, 2, 91, 7, - 6, 1, 235, 151, 2, 91, 7, 4, 1, 235, 151, 2, 91, 7, 6, 1, 4, 224, 100, 2, - 241, 59, 217, 78, 7, 4, 1, 224, 100, 2, 241, 59, 217, 78, 7, 6, 1, 223, - 227, 2, 91, 7, 4, 1, 223, 227, 2, 91, 7, 6, 1, 211, 118, 2, 91, 7, 4, 1, - 211, 118, 2, 91, 7, 4, 1, 215, 94, 61, 7, 4, 1, 254, 151, 7, 4, 1, 215, - 94, 254, 151, 7, 4, 1, 57, 2, 103, 7, 4, 1, 204, 78, 7, 4, 1, 251, 75, 2, - 249, 108, 7, 4, 1, 249, 69, 2, 217, 78, 7, 4, 1, 249, 69, 2, 103, 7, 4, - 1, 223, 52, 76, 7, 4, 1, 221, 197, 7, 4, 1, 221, 198, 2, 103, 7, 4, 1, - 204, 76, 7, 4, 1, 223, 52, 204, 76, 7, 4, 1, 223, 52, 204, 160, 2, 103, - 7, 4, 1, 250, 8, 223, 52, 204, 76, 7, 4, 1, 247, 127, 235, 151, 2, 91, 7, - 4, 1, 243, 210, 2, 103, 7, 4, 1, 119, 243, 209, 7, 1, 4, 6, 243, 209, 7, - 4, 1, 243, 114, 7, 4, 1, 223, 154, 240, 255, 7, 4, 1, 215, 94, 242, 67, - 7, 4, 1, 242, 68, 2, 103, 7, 4, 1, 241, 215, 2, 103, 7, 4, 1, 240, 161, - 2, 91, 7, 4, 1, 235, 192, 7, 1, 4, 6, 74, 7, 4, 1, 233, 155, 2, 230, 229, - 184, 7, 4, 1, 233, 155, 2, 252, 49, 7, 4, 1, 233, 155, 2, 223, 58, 103, - 7, 4, 1, 233, 7, 7, 4, 1, 215, 94, 194, 7, 4, 1, 215, 94, 232, 55, 2, - 200, 233, 42, 7, 4, 1, 232, 55, 2, 103, 7, 4, 1, 230, 31, 2, 43, 103, 7, - 4, 1, 230, 31, 2, 223, 58, 103, 7, 1, 4, 6, 230, 30, 7, 4, 1, 252, 142, - 78, 7, 1, 4, 6, 226, 238, 7, 4, 1, 250, 8, 226, 205, 7, 4, 1, 225, 136, - 7, 4, 1, 215, 94, 153, 7, 4, 1, 215, 94, 223, 227, 2, 200, 233, 42, 7, 4, - 1, 215, 94, 223, 227, 2, 103, 7, 4, 1, 223, 227, 2, 200, 233, 42, 7, 4, - 1, 223, 227, 2, 217, 78, 7, 4, 1, 223, 227, 2, 244, 95, 7, 4, 1, 223, 52, - 223, 227, 2, 244, 95, 7, 1, 4, 6, 153, 7, 1, 4, 6, 235, 200, 153, 7, 4, - 1, 222, 94, 2, 103, 7, 4, 1, 245, 83, 7, 4, 1, 247, 127, 235, 151, 2, - 218, 105, 22, 103, 7, 4, 1, 218, 233, 223, 52, 245, 83, 7, 4, 1, 245, 84, - 2, 249, 108, 7, 4, 1, 215, 94, 217, 153, 7, 4, 1, 217, 154, 2, 223, 58, - 103, 7, 4, 1, 104, 130, 7, 4, 1, 214, 157, 7, 4, 1, 214, 106, 2, 103, 7, - 4, 1, 215, 94, 214, 105, 7, 4, 1, 215, 94, 212, 98, 7, 4, 1, 215, 94, - 211, 117, 7, 1, 4, 6, 211, 117, 7, 4, 1, 210, 160, 2, 223, 58, 103, 7, 4, - 1, 210, 160, 2, 249, 108, 7, 4, 1, 245, 16, 7, 4, 1, 245, 17, 2, 249, - 108, 7, 1, 242, 187, 218, 131, 7, 1, 225, 142, 213, 135, 244, 1, 7, 1, - 235, 200, 242, 187, 218, 131, 7, 1, 218, 112, 251, 74, 7, 1, 251, 254, - 250, 19, 7, 1, 4, 6, 253, 166, 7, 4, 1, 250, 8, 204, 76, 7, 1, 4, 6, 243, - 210, 2, 103, 7, 1, 4, 6, 242, 67, 7, 4, 1, 235, 151, 2, 249, 135, 7, 4, - 1, 215, 94, 235, 29, 7, 1, 4, 6, 156, 7, 4, 1, 224, 100, 2, 103, 7, 1, - 242, 187, 218, 132, 2, 91, 7, 1, 223, 52, 242, 187, 218, 132, 2, 91, 7, - 4, 1, 246, 48, 247, 228, 7, 4, 1, 248, 34, 247, 228, 7, 4, 1, 246, 48, - 247, 229, 2, 249, 108, 7, 4, 1, 215, 186, 247, 228, 7, 4, 1, 216, 236, - 247, 228, 7, 4, 1, 217, 30, 247, 229, 2, 249, 108, 7, 4, 1, 244, 142, - 247, 228, 7, 4, 1, 232, 105, 247, 228, 7, 4, 1, 232, 56, 247, 228, 7, 1, - 251, 254, 225, 184, 7, 1, 252, 6, 225, 184, 7, 4, 1, 215, 94, 242, 68, 2, - 244, 95, 7, 4, 1, 215, 94, 242, 68, 2, 244, 96, 22, 217, 78, 58, 1, 4, - 242, 67, 58, 1, 4, 242, 68, 2, 103, 58, 1, 4, 235, 150, 58, 1, 4, 153, - 58, 1, 4, 215, 94, 153, 58, 1, 4, 215, 94, 223, 227, 2, 103, 58, 1, 4, 6, - 235, 200, 153, 58, 1, 4, 212, 98, 58, 1, 4, 211, 117, 58, 1, 224, 193, - 58, 1, 52, 224, 193, 58, 1, 215, 94, 249, 227, 58, 1, 254, 65, 58, 1, - 223, 52, 249, 227, 58, 1, 44, 163, 222, 236, 58, 1, 43, 163, 222, 236, - 58, 1, 242, 187, 218, 131, 58, 1, 223, 52, 242, 187, 218, 131, 58, 1, 43, - 254, 1, 58, 1, 44, 254, 1, 58, 1, 120, 254, 1, 58, 1, 124, 254, 1, 58, 1, - 250, 39, 255, 23, 250, 242, 58, 1, 67, 232, 219, 58, 1, 231, 237, 58, 1, - 255, 12, 255, 23, 58, 1, 242, 144, 255, 23, 58, 1, 121, 67, 232, 219, 58, - 1, 121, 231, 237, 58, 1, 121, 242, 144, 255, 23, 58, 1, 121, 255, 12, - 255, 23, 58, 1, 215, 223, 249, 234, 58, 1, 163, 215, 223, 249, 234, 58, - 1, 250, 181, 44, 163, 222, 236, 58, 1, 250, 181, 43, 163, 222, 236, 58, - 1, 120, 217, 88, 58, 1, 124, 217, 88, 58, 1, 96, 50, 58, 1, 230, 187, 50, - 251, 154, 59, 48, 222, 237, 48, 226, 228, 4, 184, 52, 255, 12, 255, 23, - 58, 1, 223, 39, 103, 58, 1, 249, 139, 255, 23, 58, 1, 4, 243, 114, 58, 1, - 4, 156, 58, 1, 4, 222, 93, 58, 1, 4, 211, 178, 58, 1, 4, 223, 52, 242, - 187, 218, 131, 58, 1, 245, 28, 138, 130, 58, 1, 125, 138, 130, 58, 1, - 230, 230, 138, 130, 58, 1, 121, 138, 130, 58, 1, 245, 27, 138, 130, 58, - 1, 210, 254, 248, 52, 138, 79, 58, 1, 211, 70, 248, 52, 138, 79, 58, 1, - 213, 133, 58, 1, 214, 186, 58, 1, 52, 254, 65, 58, 1, 121, 124, 254, 1, - 58, 1, 121, 120, 254, 1, 58, 1, 121, 43, 254, 1, 58, 1, 121, 44, 254, 1, - 58, 1, 121, 222, 236, 58, 1, 230, 229, 242, 144, 255, 23, 58, 1, 230, - 229, 52, 242, 144, 255, 23, 58, 1, 230, 229, 52, 255, 12, 255, 23, 58, 1, - 121, 184, 58, 1, 223, 160, 249, 234, 58, 1, 252, 66, 125, 216, 31, 58, 1, - 245, 151, 125, 216, 31, 58, 1, 252, 66, 121, 216, 31, 58, 1, 245, 151, - 121, 216, 31, 58, 1, 220, 56, 58, 1, 204, 220, 56, 58, 1, 121, 43, 75, - 38, 242, 144, 255, 23, 38, 255, 12, 255, 23, 38, 250, 39, 255, 23, 38, - 184, 38, 231, 237, 38, 226, 123, 38, 251, 154, 38, 59, 48, 38, 248, 9, - 38, 241, 59, 48, 38, 222, 237, 48, 38, 52, 255, 12, 255, 23, 38, 250, - 242, 38, 67, 232, 220, 48, 38, 52, 67, 232, 220, 48, 38, 52, 242, 144, - 255, 23, 38, 251, 7, 38, 235, 200, 251, 154, 38, 215, 94, 249, 228, 48, - 38, 249, 228, 48, 38, 223, 52, 249, 228, 48, 38, 249, 228, 72, 222, 254, - 38, 242, 144, 255, 24, 51, 38, 255, 12, 255, 24, 51, 38, 43, 217, 89, 51, - 38, 44, 217, 89, 51, 38, 43, 254, 118, 48, 38, 240, 255, 38, 43, 163, - 222, 237, 51, 38, 120, 217, 89, 51, 38, 124, 217, 89, 51, 38, 96, 5, 51, - 38, 230, 187, 5, 51, 38, 226, 68, 241, 59, 51, 38, 223, 58, 241, 59, 51, - 38, 59, 51, 38, 248, 10, 51, 38, 222, 237, 51, 38, 249, 228, 51, 38, 250, - 191, 38, 226, 228, 38, 67, 232, 220, 51, 38, 251, 148, 51, 38, 235, 200, - 52, 254, 32, 51, 38, 250, 243, 51, 38, 250, 39, 255, 24, 51, 38, 251, - 155, 51, 38, 235, 200, 251, 155, 51, 38, 216, 90, 51, 38, 231, 238, 51, - 38, 121, 232, 219, 38, 52, 121, 232, 219, 38, 216, 90, 226, 124, 38, 219, - 253, 218, 105, 226, 124, 38, 200, 218, 105, 226, 124, 38, 219, 253, 219, - 49, 226, 124, 38, 200, 219, 49, 226, 124, 38, 44, 163, 222, 237, 51, 38, - 235, 200, 251, 148, 51, 38, 42, 51, 38, 221, 182, 51, 38, 211, 179, 48, - 38, 67, 184, 38, 52, 226, 123, 38, 242, 144, 138, 79, 38, 255, 12, 138, - 79, 38, 26, 225, 178, 38, 26, 234, 8, 38, 26, 248, 4, 216, 19, 38, 26, - 210, 219, 38, 251, 148, 48, 38, 245, 106, 5, 51, 38, 52, 67, 232, 220, - 51, 38, 43, 254, 118, 51, 38, 228, 57, 216, 90, 48, 38, 241, 65, 48, 38, - 254, 156, 128, 216, 43, 48, 38, 43, 44, 80, 51, 38, 214, 153, 80, 51, 38, - 242, 149, 235, 69, 38, 44, 254, 2, 48, 38, 43, 163, 222, 237, 48, 38, - 244, 139, 38, 211, 179, 51, 38, 43, 254, 2, 51, 38, 44, 254, 2, 51, 38, - 44, 254, 2, 22, 120, 254, 2, 51, 38, 44, 163, 222, 237, 48, 38, 59, 72, - 222, 254, 38, 253, 225, 51, 38, 52, 222, 237, 51, 38, 210, 35, 48, 38, - 52, 251, 155, 51, 38, 52, 251, 154, 38, 52, 231, 237, 38, 52, 231, 238, - 51, 38, 52, 184, 38, 52, 235, 200, 251, 154, 38, 52, 97, 80, 51, 38, 7, - 4, 1, 61, 38, 7, 4, 1, 76, 38, 7, 4, 1, 74, 38, 7, 4, 1, 78, 38, 7, 4, 1, - 69, 38, 7, 4, 1, 251, 74, 38, 7, 4, 1, 249, 68, 38, 7, 4, 1, 242, 67, 38, - 7, 4, 1, 194, 38, 7, 4, 1, 153, 38, 7, 4, 1, 217, 153, 38, 7, 4, 1, 214, - 105, 38, 7, 4, 1, 211, 178, 26, 6, 1, 241, 203, 26, 4, 1, 241, 203, 26, - 6, 1, 254, 31, 221, 248, 26, 4, 1, 254, 31, 221, 248, 26, 227, 202, 50, - 26, 232, 114, 227, 202, 50, 26, 6, 1, 226, 55, 247, 235, 26, 4, 1, 226, - 55, 247, 235, 26, 210, 219, 26, 4, 223, 52, 232, 88, 219, 180, 87, 26, 4, - 246, 126, 232, 88, 219, 180, 87, 26, 4, 223, 52, 246, 126, 232, 88, 219, - 180, 87, 26, 224, 16, 79, 26, 216, 19, 26, 248, 4, 216, 19, 26, 6, 1, - 254, 152, 2, 216, 19, 26, 254, 105, 217, 3, 26, 6, 1, 245, 109, 2, 216, - 19, 26, 6, 1, 245, 72, 2, 216, 19, 26, 6, 1, 235, 193, 2, 216, 19, 26, 6, - 1, 226, 204, 2, 216, 19, 26, 6, 1, 214, 158, 2, 216, 19, 26, 6, 1, 226, - 206, 2, 216, 19, 26, 4, 1, 235, 193, 2, 248, 4, 22, 216, 19, 26, 6, 1, - 254, 151, 26, 6, 1, 252, 34, 26, 6, 1, 243, 114, 26, 6, 1, 248, 62, 26, - 6, 1, 245, 108, 26, 6, 1, 210, 85, 26, 6, 1, 245, 71, 26, 6, 1, 216, 180, - 26, 6, 1, 235, 192, 26, 6, 1, 234, 228, 26, 6, 1, 233, 104, 26, 6, 1, - 230, 107, 26, 6, 1, 227, 242, 26, 6, 1, 211, 157, 26, 6, 1, 226, 203, 26, - 6, 1, 225, 111, 26, 6, 1, 223, 40, 26, 6, 1, 219, 179, 26, 6, 1, 217, 42, - 26, 6, 1, 214, 157, 26, 6, 1, 225, 136, 26, 6, 1, 250, 118, 26, 6, 1, - 224, 164, 26, 6, 1, 226, 205, 26, 6, 1, 235, 193, 2, 248, 3, 26, 6, 1, - 214, 158, 2, 248, 3, 26, 4, 1, 254, 152, 2, 216, 19, 26, 4, 1, 245, 109, - 2, 216, 19, 26, 4, 1, 245, 72, 2, 216, 19, 26, 4, 1, 235, 193, 2, 216, - 19, 26, 4, 1, 214, 158, 2, 248, 4, 22, 216, 19, 26, 4, 1, 254, 151, 26, - 4, 1, 252, 34, 26, 4, 1, 243, 114, 26, 4, 1, 248, 62, 26, 4, 1, 245, 108, - 26, 4, 1, 210, 85, 26, 4, 1, 245, 71, 26, 4, 1, 216, 180, 26, 4, 1, 235, - 192, 26, 4, 1, 234, 228, 26, 4, 1, 233, 104, 26, 4, 1, 230, 107, 26, 4, - 1, 227, 242, 26, 4, 1, 211, 157, 26, 4, 1, 226, 203, 26, 4, 1, 225, 111, - 26, 4, 1, 223, 40, 26, 4, 1, 40, 219, 179, 26, 4, 1, 219, 179, 26, 4, 1, - 217, 42, 26, 4, 1, 214, 157, 26, 4, 1, 225, 136, 26, 4, 1, 250, 118, 26, - 4, 1, 224, 164, 26, 4, 1, 226, 205, 26, 4, 1, 235, 193, 2, 248, 3, 26, 4, - 1, 214, 158, 2, 248, 3, 26, 4, 1, 226, 204, 2, 216, 19, 26, 4, 1, 214, - 158, 2, 216, 19, 26, 4, 1, 226, 206, 2, 216, 19, 26, 6, 234, 253, 87, 26, - 252, 35, 87, 26, 216, 181, 87, 26, 214, 158, 2, 241, 59, 87, 26, 214, - 158, 2, 255, 12, 22, 241, 59, 87, 26, 214, 158, 2, 248, 10, 22, 241, 59, - 87, 26, 225, 137, 87, 26, 225, 112, 87, 26, 234, 253, 87, 26, 1, 254, 31, - 234, 12, 26, 4, 1, 254, 31, 234, 12, 26, 1, 218, 139, 26, 4, 1, 218, 139, - 26, 1, 247, 235, 26, 4, 1, 247, 235, 26, 1, 234, 12, 26, 4, 1, 234, 12, - 26, 1, 221, 248, 26, 4, 1, 221, 248, 81, 6, 1, 220, 57, 81, 4, 1, 220, - 57, 81, 6, 1, 244, 148, 81, 4, 1, 244, 148, 81, 6, 1, 234, 123, 81, 4, 1, - 234, 123, 81, 6, 1, 241, 52, 81, 4, 1, 241, 52, 81, 6, 1, 243, 109, 81, - 4, 1, 243, 109, 81, 6, 1, 220, 24, 81, 4, 1, 220, 24, 81, 6, 1, 248, 77, - 81, 4, 1, 248, 77, 26, 234, 229, 87, 26, 223, 41, 87, 26, 232, 88, 219, - 180, 87, 26, 1, 210, 224, 26, 6, 216, 181, 87, 26, 232, 88, 245, 109, 87, - 26, 223, 52, 232, 88, 245, 109, 87, 26, 6, 1, 220, 9, 26, 4, 1, 220, 9, - 26, 6, 232, 88, 219, 180, 87, 26, 6, 1, 221, 245, 26, 4, 1, 221, 245, 26, - 223, 41, 2, 218, 105, 87, 26, 6, 223, 52, 232, 88, 219, 180, 87, 26, 6, - 246, 126, 232, 88, 219, 180, 87, 26, 6, 223, 52, 246, 126, 232, 88, 219, - 180, 87, 33, 6, 1, 236, 68, 2, 242, 143, 33, 6, 1, 235, 196, 33, 6, 1, - 247, 170, 33, 6, 1, 242, 194, 33, 6, 1, 214, 202, 236, 67, 33, 6, 1, 246, - 44, 33, 6, 1, 251, 84, 74, 33, 6, 1, 211, 8, 33, 6, 1, 235, 132, 33, 6, - 1, 232, 193, 33, 6, 1, 228, 183, 33, 6, 1, 215, 175, 33, 6, 1, 234, 54, - 33, 6, 1, 240, 161, 2, 242, 143, 33, 6, 1, 219, 253, 69, 33, 6, 1, 246, - 40, 33, 6, 1, 61, 33, 6, 1, 252, 83, 33, 6, 1, 213, 255, 33, 6, 1, 242, - 243, 33, 6, 1, 248, 98, 33, 6, 1, 236, 67, 33, 6, 1, 210, 74, 33, 6, 1, - 210, 94, 33, 6, 1, 74, 33, 6, 1, 219, 253, 74, 33, 6, 1, 176, 33, 6, 1, - 245, 182, 33, 6, 1, 245, 167, 33, 6, 1, 245, 158, 33, 6, 1, 78, 33, 6, 1, - 225, 224, 33, 6, 1, 245, 100, 33, 6, 1, 245, 90, 33, 6, 1, 217, 23, 33, - 6, 1, 69, 33, 6, 1, 245, 210, 33, 6, 1, 162, 33, 6, 1, 215, 179, 33, 6, - 1, 250, 139, 33, 6, 1, 220, 104, 33, 6, 1, 220, 67, 33, 6, 1, 242, 10, - 50, 33, 6, 1, 211, 27, 33, 6, 1, 219, 54, 50, 33, 6, 1, 76, 33, 6, 1, - 210, 212, 33, 6, 1, 192, 33, 4, 1, 61, 33, 4, 1, 252, 83, 33, 4, 1, 213, - 255, 33, 4, 1, 242, 243, 33, 4, 1, 248, 98, 33, 4, 1, 236, 67, 33, 4, 1, - 210, 74, 33, 4, 1, 210, 94, 33, 4, 1, 74, 33, 4, 1, 219, 253, 74, 33, 4, - 1, 176, 33, 4, 1, 245, 182, 33, 4, 1, 245, 167, 33, 4, 1, 245, 158, 33, - 4, 1, 78, 33, 4, 1, 225, 224, 33, 4, 1, 245, 100, 33, 4, 1, 245, 90, 33, - 4, 1, 217, 23, 33, 4, 1, 69, 33, 4, 1, 245, 210, 33, 4, 1, 162, 33, 4, 1, - 215, 179, 33, 4, 1, 250, 139, 33, 4, 1, 220, 104, 33, 4, 1, 220, 67, 33, - 4, 1, 242, 10, 50, 33, 4, 1, 211, 27, 33, 4, 1, 219, 54, 50, 33, 4, 1, - 76, 33, 4, 1, 210, 212, 33, 4, 1, 192, 33, 4, 1, 236, 68, 2, 242, 143, - 33, 4, 1, 235, 196, 33, 4, 1, 247, 170, 33, 4, 1, 242, 194, 33, 4, 1, - 214, 202, 236, 67, 33, 4, 1, 246, 44, 33, 4, 1, 251, 84, 74, 33, 4, 1, - 211, 8, 33, 4, 1, 235, 132, 33, 4, 1, 232, 193, 33, 4, 1, 228, 183, 33, - 4, 1, 215, 175, 33, 4, 1, 234, 54, 33, 4, 1, 240, 161, 2, 242, 143, 33, - 4, 1, 219, 253, 69, 33, 4, 1, 246, 40, 33, 6, 1, 226, 205, 33, 4, 1, 226, - 205, 33, 6, 1, 211, 59, 33, 4, 1, 211, 59, 33, 6, 1, 235, 190, 76, 33, 4, - 1, 235, 190, 76, 33, 6, 1, 232, 198, 210, 183, 33, 4, 1, 232, 198, 210, - 183, 33, 6, 1, 235, 190, 232, 198, 210, 183, 33, 4, 1, 235, 190, 232, - 198, 210, 183, 33, 6, 1, 252, 1, 210, 183, 33, 4, 1, 252, 1, 210, 183, - 33, 6, 1, 235, 190, 252, 1, 210, 183, 33, 4, 1, 235, 190, 252, 1, 210, - 183, 33, 6, 1, 233, 239, 33, 4, 1, 233, 239, 33, 6, 1, 224, 164, 33, 4, - 1, 224, 164, 33, 6, 1, 244, 90, 33, 4, 1, 244, 90, 33, 6, 1, 235, 152, - 33, 4, 1, 235, 152, 33, 6, 1, 235, 153, 2, 52, 242, 144, 255, 23, 33, 4, - 1, 235, 153, 2, 52, 242, 144, 255, 23, 33, 6, 1, 214, 205, 33, 4, 1, 214, - 205, 33, 6, 1, 222, 187, 226, 205, 33, 4, 1, 222, 187, 226, 205, 33, 6, - 1, 226, 206, 2, 216, 66, 33, 4, 1, 226, 206, 2, 216, 66, 33, 6, 1, 226, - 144, 33, 4, 1, 226, 144, 33, 6, 1, 234, 12, 33, 4, 1, 234, 12, 33, 216, - 147, 50, 38, 33, 216, 66, 38, 33, 226, 69, 38, 33, 248, 162, 225, 21, 38, - 33, 224, 158, 225, 21, 38, 33, 225, 6, 38, 33, 240, 218, 216, 147, 50, - 38, 33, 230, 196, 50, 33, 6, 1, 219, 253, 240, 161, 2, 217, 78, 33, 4, 1, - 219, 253, 240, 161, 2, 217, 78, 33, 6, 1, 220, 148, 50, 33, 4, 1, 220, - 148, 50, 33, 6, 1, 245, 101, 2, 216, 115, 33, 4, 1, 245, 101, 2, 216, - 115, 33, 6, 1, 242, 244, 2, 214, 156, 33, 4, 1, 242, 244, 2, 214, 156, - 33, 6, 1, 242, 244, 2, 91, 33, 4, 1, 242, 244, 2, 91, 33, 6, 1, 242, 244, - 2, 230, 229, 103, 33, 4, 1, 242, 244, 2, 230, 229, 103, 33, 6, 1, 210, - 75, 2, 248, 47, 33, 4, 1, 210, 75, 2, 248, 47, 33, 6, 1, 210, 95, 2, 248, - 47, 33, 4, 1, 210, 95, 2, 248, 47, 33, 6, 1, 235, 19, 2, 248, 47, 33, 4, - 1, 235, 19, 2, 248, 47, 33, 6, 1, 235, 19, 2, 67, 91, 33, 4, 1, 235, 19, - 2, 67, 91, 33, 6, 1, 235, 19, 2, 91, 33, 4, 1, 235, 19, 2, 91, 33, 6, 1, - 252, 132, 176, 33, 4, 1, 252, 132, 176, 33, 6, 1, 245, 159, 2, 248, 47, - 33, 4, 1, 245, 159, 2, 248, 47, 33, 6, 27, 245, 159, 242, 243, 33, 4, 27, - 245, 159, 242, 243, 33, 6, 1, 225, 225, 2, 230, 229, 103, 33, 4, 1, 225, - 225, 2, 230, 229, 103, 33, 6, 1, 255, 29, 162, 33, 4, 1, 255, 29, 162, - 33, 6, 1, 245, 91, 2, 248, 47, 33, 4, 1, 245, 91, 2, 248, 47, 33, 6, 1, - 217, 24, 2, 248, 47, 33, 4, 1, 217, 24, 2, 248, 47, 33, 6, 1, 218, 123, - 69, 33, 4, 1, 218, 123, 69, 33, 6, 1, 218, 123, 104, 2, 91, 33, 4, 1, - 218, 123, 104, 2, 91, 33, 6, 1, 242, 56, 2, 248, 47, 33, 4, 1, 242, 56, - 2, 248, 47, 33, 6, 27, 217, 24, 215, 179, 33, 4, 27, 217, 24, 215, 179, - 33, 6, 1, 250, 140, 2, 248, 47, 33, 4, 1, 250, 140, 2, 248, 47, 33, 6, 1, - 250, 140, 2, 67, 91, 33, 4, 1, 250, 140, 2, 67, 91, 33, 6, 1, 220, 35, - 33, 4, 1, 220, 35, 33, 6, 1, 255, 29, 250, 139, 33, 4, 1, 255, 29, 250, - 139, 33, 6, 1, 255, 29, 250, 140, 2, 248, 47, 33, 4, 1, 255, 29, 250, - 140, 2, 248, 47, 33, 1, 226, 62, 33, 6, 1, 210, 75, 2, 251, 154, 33, 4, - 1, 210, 75, 2, 251, 154, 33, 6, 1, 235, 19, 2, 103, 33, 4, 1, 235, 19, 2, - 103, 33, 6, 1, 245, 183, 2, 217, 78, 33, 4, 1, 245, 183, 2, 217, 78, 33, - 6, 1, 245, 159, 2, 103, 33, 4, 1, 245, 159, 2, 103, 33, 6, 1, 245, 159, - 2, 217, 78, 33, 4, 1, 245, 159, 2, 217, 78, 33, 6, 1, 234, 133, 250, 139, - 33, 4, 1, 234, 133, 250, 139, 33, 6, 1, 245, 168, 2, 217, 78, 33, 4, 1, - 245, 168, 2, 217, 78, 33, 4, 1, 226, 62, 33, 6, 1, 116, 2, 251, 154, 33, - 4, 1, 116, 2, 251, 154, 33, 6, 1, 116, 2, 248, 9, 33, 4, 1, 116, 2, 248, - 9, 33, 6, 27, 116, 236, 67, 33, 4, 27, 116, 236, 67, 33, 6, 1, 236, 68, - 2, 251, 154, 33, 4, 1, 236, 68, 2, 251, 154, 33, 6, 1, 221, 197, 33, 4, - 1, 221, 197, 33, 6, 1, 221, 198, 2, 248, 9, 33, 4, 1, 221, 198, 2, 248, - 9, 33, 6, 1, 210, 75, 2, 248, 9, 33, 4, 1, 210, 75, 2, 248, 9, 33, 6, 1, - 210, 95, 2, 248, 9, 33, 4, 1, 210, 95, 2, 248, 9, 33, 6, 1, 255, 29, 246, - 44, 33, 4, 1, 255, 29, 246, 44, 33, 6, 1, 240, 161, 2, 231, 237, 33, 4, - 1, 240, 161, 2, 231, 237, 33, 6, 1, 240, 161, 2, 248, 9, 33, 4, 1, 240, - 161, 2, 248, 9, 33, 6, 1, 144, 2, 248, 9, 33, 4, 1, 144, 2, 248, 9, 33, - 6, 1, 252, 142, 78, 33, 4, 1, 252, 142, 78, 33, 6, 1, 252, 142, 144, 2, - 248, 9, 33, 4, 1, 252, 142, 144, 2, 248, 9, 33, 6, 1, 160, 2, 248, 9, 33, - 4, 1, 160, 2, 248, 9, 33, 6, 1, 104, 2, 231, 237, 33, 4, 1, 104, 2, 231, - 237, 33, 6, 1, 104, 2, 248, 9, 33, 4, 1, 104, 2, 248, 9, 33, 6, 1, 104, - 2, 52, 142, 33, 4, 1, 104, 2, 52, 142, 33, 6, 1, 250, 140, 2, 248, 9, 33, - 4, 1, 250, 140, 2, 248, 9, 33, 6, 1, 242, 244, 2, 248, 47, 33, 4, 1, 242, - 244, 2, 248, 47, 33, 6, 1, 211, 28, 2, 248, 9, 33, 4, 1, 211, 28, 2, 248, - 9, 33, 6, 1, 242, 244, 2, 218, 105, 22, 103, 33, 4, 1, 242, 244, 2, 218, - 105, 22, 103, 33, 6, 1, 242, 56, 2, 103, 33, 4, 1, 242, 56, 2, 103, 33, - 6, 1, 242, 56, 2, 91, 33, 4, 1, 242, 56, 2, 91, 33, 6, 1, 234, 20, 248, - 98, 33, 4, 1, 234, 20, 248, 98, 33, 6, 1, 234, 20, 247, 170, 33, 4, 1, - 234, 20, 247, 170, 33, 6, 1, 234, 20, 210, 27, 33, 4, 1, 234, 20, 210, - 27, 33, 6, 1, 234, 20, 246, 38, 33, 4, 1, 234, 20, 246, 38, 33, 6, 1, - 234, 20, 232, 193, 33, 4, 1, 234, 20, 232, 193, 33, 6, 1, 234, 20, 228, - 183, 33, 4, 1, 234, 20, 228, 183, 33, 6, 1, 234, 20, 219, 111, 33, 4, 1, - 234, 20, 219, 111, 33, 6, 1, 234, 20, 216, 61, 33, 4, 1, 234, 20, 216, - 61, 33, 6, 1, 223, 52, 210, 94, 33, 4, 1, 223, 52, 210, 94, 33, 6, 1, - 245, 183, 2, 103, 33, 4, 1, 245, 183, 2, 103, 33, 6, 1, 233, 4, 33, 4, 1, - 233, 4, 33, 6, 1, 223, 42, 33, 4, 1, 223, 42, 33, 6, 1, 211, 92, 33, 4, - 1, 211, 92, 33, 6, 1, 224, 91, 33, 4, 1, 224, 91, 33, 6, 1, 212, 22, 33, - 4, 1, 212, 22, 33, 6, 1, 254, 175, 176, 33, 4, 1, 254, 175, 176, 33, 6, - 1, 245, 183, 2, 230, 229, 103, 33, 4, 1, 245, 183, 2, 230, 229, 103, 33, - 6, 1, 245, 159, 2, 230, 229, 103, 33, 4, 1, 245, 159, 2, 230, 229, 103, - 33, 6, 1, 225, 225, 2, 248, 47, 33, 4, 1, 225, 225, 2, 248, 47, 33, 6, 1, - 220, 36, 2, 248, 47, 33, 4, 1, 220, 36, 2, 248, 47, 150, 6, 1, 253, 172, - 150, 6, 1, 252, 47, 150, 6, 1, 242, 210, 150, 6, 1, 248, 229, 150, 6, 1, - 245, 221, 150, 6, 1, 210, 116, 150, 6, 1, 245, 205, 150, 6, 1, 245, 73, - 150, 6, 1, 112, 150, 6, 1, 210, 74, 150, 6, 1, 235, 234, 150, 6, 1, 232, - 196, 150, 6, 1, 211, 160, 150, 6, 1, 251, 41, 150, 6, 1, 234, 171, 150, - 6, 1, 241, 75, 150, 6, 1, 235, 147, 150, 6, 1, 242, 253, 150, 6, 1, 250, - 134, 150, 6, 1, 231, 63, 150, 6, 1, 211, 8, 150, 6, 1, 228, 44, 150, 6, - 1, 220, 104, 150, 6, 1, 213, 138, 150, 6, 1, 250, 165, 150, 6, 1, 225, - 208, 150, 6, 1, 235, 116, 150, 6, 1, 205, 150, 6, 1, 221, 163, 150, 6, 1, - 213, 179, 150, 6, 1, 216, 63, 150, 6, 1, 223, 98, 150, 6, 1, 249, 246, - 150, 6, 1, 210, 249, 150, 6, 1, 225, 49, 150, 6, 1, 234, 182, 150, 6, 1, - 226, 226, 150, 6, 1, 244, 150, 150, 58, 1, 43, 163, 222, 236, 150, 254, - 65, 150, 245, 162, 79, 150, 245, 39, 79, 150, 249, 227, 150, 224, 16, 79, - 150, 255, 30, 79, 150, 4, 1, 253, 172, 150, 4, 1, 252, 47, 150, 4, 1, - 242, 210, 150, 4, 1, 248, 229, 150, 4, 1, 245, 221, 150, 4, 1, 210, 116, - 150, 4, 1, 245, 205, 150, 4, 1, 245, 73, 150, 4, 1, 112, 150, 4, 1, 210, - 74, 150, 4, 1, 235, 234, 150, 4, 1, 232, 196, 150, 4, 1, 211, 160, 150, - 4, 1, 251, 41, 150, 4, 1, 234, 171, 150, 4, 1, 241, 75, 150, 4, 1, 235, - 147, 150, 4, 1, 242, 253, 150, 4, 1, 250, 134, 150, 4, 1, 231, 63, 150, - 4, 1, 211, 8, 150, 4, 1, 228, 44, 150, 4, 1, 220, 104, 150, 4, 1, 213, - 138, 150, 4, 1, 250, 165, 150, 4, 1, 225, 208, 150, 4, 1, 235, 116, 150, - 4, 1, 205, 150, 4, 1, 221, 163, 150, 4, 1, 213, 179, 150, 4, 1, 216, 63, - 150, 4, 1, 223, 98, 150, 4, 1, 249, 246, 150, 4, 1, 210, 249, 150, 4, 1, - 225, 49, 150, 4, 1, 234, 182, 150, 4, 1, 226, 226, 150, 4, 1, 244, 150, - 150, 4, 27, 245, 222, 210, 249, 150, 243, 236, 218, 131, 150, 240, 175, - 150, 246, 103, 50, 94, 255, 24, 245, 65, 94, 255, 24, 221, 164, 94, 255, - 24, 220, 90, 94, 255, 24, 210, 104, 224, 74, 94, 255, 24, 210, 104, 243, - 132, 94, 255, 24, 216, 76, 94, 255, 24, 223, 50, 94, 255, 24, 210, 103, - 94, 255, 24, 225, 249, 94, 255, 24, 211, 20, 94, 255, 24, 216, 215, 94, - 255, 24, 243, 48, 94, 255, 24, 243, 49, 230, 74, 94, 255, 24, 243, 46, - 94, 255, 24, 224, 75, 226, 20, 94, 255, 24, 216, 254, 243, 63, 94, 255, - 24, 225, 230, 94, 255, 24, 253, 208, 242, 48, 94, 255, 24, 230, 84, 94, - 255, 24, 231, 213, 94, 255, 24, 231, 54, 94, 255, 24, 231, 55, 234, 183, - 94, 255, 24, 248, 171, 94, 255, 24, 224, 86, 94, 255, 24, 216, 254, 224, - 70, 94, 255, 24, 211, 30, 252, 48, 210, 230, 94, 255, 24, 226, 211, 94, - 255, 24, 236, 26, 94, 255, 24, 248, 78, 94, 255, 24, 210, 33, 94, 164, - 231, 148, 250, 43, 94, 225, 14, 220, 38, 94, 225, 14, 242, 1, 221, 164, - 94, 225, 14, 242, 1, 225, 243, 94, 225, 14, 242, 1, 224, 79, 94, 225, 14, - 241, 165, 94, 225, 14, 215, 177, 94, 225, 14, 221, 164, 94, 225, 14, 225, - 243, 94, 225, 14, 224, 79, 94, 225, 14, 241, 68, 94, 225, 14, 241, 69, - 242, 3, 31, 214, 3, 94, 225, 14, 224, 20, 94, 225, 14, 248, 216, 177, - 231, 176, 94, 225, 14, 231, 43, 94, 224, 144, 231, 173, 94, 225, 14, 223, - 172, 94, 224, 144, 225, 251, 94, 225, 14, 220, 23, 247, 128, 94, 225, 14, - 219, 161, 247, 128, 94, 224, 144, 219, 55, 225, 245, 94, 164, 214, 160, - 247, 128, 94, 164, 232, 114, 247, 128, 94, 224, 144, 227, 199, 242, 47, - 94, 225, 14, 224, 80, 224, 74, 94, 1, 254, 179, 94, 1, 252, 36, 94, 1, - 242, 208, 94, 1, 248, 197, 94, 1, 241, 245, 94, 1, 214, 3, 94, 1, 210, - 97, 94, 1, 241, 204, 94, 1, 216, 231, 94, 1, 210, 233, 94, 1, 40, 235, 0, - 94, 1, 235, 0, 94, 1, 233, 100, 94, 1, 40, 231, 70, 94, 1, 231, 70, 94, - 1, 40, 227, 198, 94, 1, 227, 198, 94, 1, 221, 251, 94, 1, 253, 170, 94, - 1, 40, 225, 224, 94, 1, 225, 224, 94, 1, 40, 215, 180, 94, 1, 215, 180, - 94, 1, 224, 42, 94, 1, 223, 70, 94, 1, 220, 22, 94, 1, 217, 39, 94, 27, - 211, 6, 52, 214, 3, 94, 27, 211, 6, 214, 4, 210, 233, 94, 27, 211, 6, 52, - 210, 233, 94, 224, 144, 243, 48, 94, 224, 144, 243, 46, 9, 54, 50, 9, 5, - 221, 244, 9, 244, 38, 231, 159, 9, 5, 222, 25, 9, 5, 221, 247, 254, 45, - 249, 117, 222, 195, 254, 45, 244, 12, 222, 195, 9, 223, 137, 254, 45, - 225, 186, 230, 198, 50, 254, 45, 225, 186, 216, 249, 216, 149, 50, 254, - 230, 50, 9, 249, 227, 9, 248, 158, 220, 139, 9, 225, 16, 213, 241, 50, 9, - 5, 230, 179, 9, 5, 222, 5, 254, 181, 212, 45, 9, 5, 254, 181, 253, 229, - 9, 5, 223, 170, 254, 180, 9, 5, 223, 178, 254, 161, 254, 112, 9, 5, 217, - 71, 9, 4, 125, 217, 81, 9, 4, 125, 27, 109, 2, 233, 109, 2, 211, 43, 9, - 4, 125, 210, 108, 9, 4, 244, 173, 9, 4, 248, 192, 9, 4, 234, 211, 9, 220, - 152, 9, 1, 79, 9, 215, 212, 59, 224, 144, 79, 9, 224, 16, 79, 9, 1, 234, - 215, 211, 43, 9, 1, 242, 26, 9, 1, 109, 2, 231, 233, 48, 9, 1, 109, 2, - 182, 48, 9, 1, 212, 31, 2, 182, 48, 9, 1, 109, 2, 182, 51, 9, 1, 77, 2, - 182, 48, 9, 1, 254, 179, 9, 1, 252, 62, 9, 1, 217, 9, 231, 169, 9, 1, - 217, 8, 9, 1, 216, 193, 9, 1, 235, 129, 9, 1, 242, 44, 9, 1, 234, 135, 9, - 1, 248, 203, 9, 1, 216, 203, 9, 1, 223, 98, 9, 1, 210, 108, 9, 1, 221, - 168, 9, 1, 220, 61, 9, 1, 222, 28, 9, 1, 248, 224, 9, 1, 217, 81, 9, 1, - 210, 111, 9, 1, 254, 205, 9, 1, 242, 251, 9, 1, 234, 181, 2, 113, 170, - 48, 9, 1, 234, 181, 2, 134, 170, 51, 9, 1, 244, 176, 77, 2, 235, 200, - 214, 105, 9, 1, 244, 176, 77, 2, 113, 170, 48, 9, 1, 244, 176, 77, 2, - 134, 170, 48, 9, 217, 44, 9, 1, 244, 150, 9, 1, 224, 84, 9, 1, 235, 0, 9, - 1, 233, 108, 9, 1, 231, 83, 9, 1, 228, 67, 9, 1, 241, 225, 9, 1, 212, 30, - 9, 1, 109, 231, 197, 9, 1, 211, 43, 9, 244, 171, 9, 248, 190, 9, 234, - 209, 9, 244, 173, 9, 248, 192, 9, 234, 211, 9, 220, 95, 9, 218, 46, 9, - 231, 231, 48, 9, 182, 48, 9, 182, 51, 9, 218, 66, 254, 179, 9, 235, 200, - 248, 192, 9, 164, 228, 68, 242, 225, 9, 209, 255, 9, 25, 5, 4, 214, 106, - 48, 9, 25, 5, 235, 200, 4, 214, 106, 48, 9, 25, 5, 59, 51, 9, 223, 52, - 248, 192, 9, 244, 174, 2, 113, 247, 126, 9, 212, 32, 182, 51, 254, 45, - 21, 210, 86, 254, 45, 21, 111, 254, 45, 21, 105, 254, 45, 21, 158, 254, - 45, 21, 161, 254, 45, 21, 190, 254, 45, 21, 195, 254, 45, 21, 199, 254, - 45, 21, 196, 254, 45, 21, 201, 9, 225, 185, 50, 9, 248, 91, 220, 139, 9, - 216, 147, 220, 139, 9, 244, 89, 225, 12, 218, 158, 9, 1, 247, 127, 252, - 62, 9, 1, 247, 127, 224, 84, 9, 1, 218, 24, 254, 179, 9, 1, 109, 212, 46, - 9, 1, 109, 2, 212, 32, 182, 48, 9, 1, 109, 2, 212, 32, 182, 51, 9, 1, - 125, 242, 26, 9, 1, 125, 182, 254, 179, 9, 1, 125, 182, 212, 30, 9, 1, - 104, 2, 182, 48, 9, 1, 125, 182, 211, 43, 9, 1, 215, 149, 9, 1, 215, 147, - 9, 1, 252, 72, 9, 1, 217, 9, 2, 222, 236, 9, 1, 217, 9, 2, 134, 170, 72, - 246, 111, 9, 1, 225, 208, 9, 1, 217, 6, 9, 1, 252, 60, 9, 1, 122, 2, 182, - 48, 9, 1, 122, 2, 113, 170, 67, 48, 9, 1, 227, 157, 9, 1, 246, 51, 9, 1, - 122, 2, 134, 170, 48, 9, 1, 217, 27, 9, 1, 217, 25, 9, 1, 248, 138, 9, 1, - 248, 204, 2, 222, 236, 9, 1, 248, 204, 2, 59, 51, 9, 1, 248, 204, 2, 59, - 252, 51, 22, 4, 217, 81, 9, 1, 248, 209, 9, 1, 248, 140, 9, 1, 246, 78, - 9, 1, 248, 204, 2, 134, 170, 72, 246, 111, 9, 1, 248, 204, 2, 244, 19, - 170, 48, 9, 1, 222, 173, 9, 1, 223, 99, 2, 4, 214, 105, 9, 1, 223, 99, 2, - 222, 236, 9, 1, 223, 99, 2, 59, 51, 9, 1, 223, 99, 2, 4, 214, 106, 51, 9, - 1, 223, 99, 2, 59, 252, 51, 22, 59, 48, 9, 1, 223, 99, 2, 113, 170, 48, - 9, 1, 235, 126, 9, 1, 223, 99, 2, 244, 19, 170, 48, 9, 1, 221, 169, 2, - 59, 252, 51, 22, 59, 48, 9, 1, 221, 169, 2, 134, 170, 51, 9, 1, 221, 169, - 2, 134, 170, 252, 51, 22, 134, 170, 48, 9, 1, 222, 29, 2, 113, 170, 51, - 9, 1, 222, 29, 2, 134, 170, 48, 9, 1, 217, 82, 2, 134, 170, 48, 9, 1, - 254, 206, 2, 134, 170, 48, 9, 1, 247, 127, 244, 150, 9, 1, 244, 151, 2, - 59, 230, 114, 51, 9, 1, 244, 151, 2, 59, 51, 9, 1, 213, 248, 9, 1, 244, - 151, 2, 134, 170, 51, 9, 1, 225, 206, 9, 1, 224, 85, 2, 59, 48, 9, 1, - 224, 85, 2, 134, 170, 48, 9, 1, 234, 180, 9, 1, 217, 251, 235, 0, 9, 1, - 235, 1, 2, 222, 236, 9, 1, 235, 1, 2, 59, 48, 9, 1, 229, 84, 9, 1, 235, - 1, 2, 134, 170, 51, 9, 1, 243, 129, 9, 1, 243, 130, 2, 222, 236, 9, 1, - 229, 7, 9, 1, 243, 130, 2, 113, 170, 51, 9, 1, 242, 108, 9, 1, 243, 130, - 2, 134, 170, 48, 9, 1, 233, 109, 2, 4, 214, 105, 9, 1, 233, 109, 2, 59, - 48, 9, 1, 233, 109, 2, 134, 170, 48, 9, 1, 233, 109, 2, 134, 170, 51, 9, - 1, 228, 68, 2, 59, 51, 9, 1, 228, 68, 242, 225, 9, 1, 222, 216, 9, 1, - 228, 68, 2, 222, 236, 9, 1, 228, 68, 2, 134, 170, 48, 9, 1, 241, 226, - 247, 149, 9, 1, 217, 28, 2, 59, 48, 9, 1, 241, 226, 2, 77, 48, 9, 1, 241, - 226, 242, 178, 9, 1, 241, 226, 242, 179, 2, 182, 48, 9, 1, 217, 9, 231, - 170, 242, 178, 9, 1, 212, 31, 2, 222, 236, 9, 1, 234, 79, 226, 238, 9, 1, - 226, 238, 9, 1, 69, 9, 1, 210, 212, 9, 1, 234, 79, 210, 212, 9, 1, 212, - 31, 2, 113, 170, 48, 9, 1, 213, 255, 9, 1, 244, 176, 211, 43, 9, 1, 77, - 2, 217, 78, 9, 1, 77, 2, 4, 214, 105, 9, 1, 212, 31, 2, 59, 48, 9, 1, 76, - 9, 1, 77, 2, 134, 170, 51, 9, 1, 77, 252, 140, 9, 1, 77, 252, 141, 2, - 182, 48, 9, 243, 236, 218, 131, 9, 1, 254, 252, 9, 4, 125, 27, 222, 29, - 2, 233, 109, 2, 109, 231, 197, 9, 4, 125, 27, 224, 85, 2, 233, 109, 2, - 109, 231, 197, 9, 4, 125, 66, 65, 17, 9, 4, 125, 233, 109, 254, 179, 9, - 4, 125, 235, 129, 9, 4, 125, 134, 247, 126, 9, 4, 125, 221, 168, 9, 245, - 151, 64, 253, 174, 9, 218, 154, 64, 222, 140, 245, 183, 241, 162, 9, 4, - 125, 222, 185, 210, 86, 9, 4, 125, 214, 159, 223, 118, 210, 86, 9, 4, - 125, 247, 127, 241, 243, 64, 234, 135, 9, 4, 125, 66, 53, 17, 9, 4, 121, - 221, 168, 9, 4, 125, 231, 232, 9, 4, 212, 30, 9, 4, 211, 43, 9, 4, 125, - 211, 43, 9, 4, 125, 228, 67, 9, 225, 44, 64, 222, 15, 9, 245, 160, 250, - 183, 121, 218, 131, 9, 245, 160, 250, 183, 125, 218, 131, 9, 222, 185, - 125, 218, 132, 2, 244, 112, 250, 182, 9, 4, 121, 231, 83, 9, 1, 248, 204, - 2, 235, 200, 214, 105, 9, 1, 223, 99, 2, 235, 200, 214, 105, 245, 30, - 254, 45, 21, 210, 86, 245, 30, 254, 45, 21, 111, 245, 30, 254, 45, 21, - 105, 245, 30, 254, 45, 21, 158, 245, 30, 254, 45, 21, 161, 245, 30, 254, - 45, 21, 190, 245, 30, 254, 45, 21, 195, 245, 30, 254, 45, 21, 199, 245, - 30, 254, 45, 21, 196, 245, 30, 254, 45, 21, 201, 9, 1, 220, 62, 2, 59, - 51, 9, 1, 248, 225, 2, 59, 51, 9, 1, 242, 252, 2, 59, 51, 9, 5, 219, 160, - 254, 134, 9, 5, 219, 160, 224, 238, 231, 63, 9, 1, 241, 226, 2, 235, 200, - 214, 105, 183, 245, 151, 64, 226, 18, 183, 218, 20, 243, 236, 218, 131, - 183, 218, 68, 243, 236, 218, 131, 183, 218, 20, 249, 234, 183, 218, 68, - 249, 234, 183, 203, 249, 234, 183, 249, 235, 219, 108, 233, 52, 183, 249, - 235, 219, 108, 222, 254, 183, 218, 20, 249, 235, 219, 108, 233, 52, 183, - 218, 68, 249, 235, 219, 108, 222, 254, 183, 249, 188, 183, 242, 8, 226, - 254, 183, 242, 8, 231, 41, 183, 242, 8, 253, 226, 183, 255, 30, 79, 183, - 1, 254, 183, 183, 1, 218, 24, 254, 183, 183, 1, 252, 33, 183, 1, 243, - 120, 183, 1, 243, 121, 243, 98, 183, 1, 248, 200, 183, 1, 247, 127, 248, - 201, 222, 232, 183, 1, 241, 245, 183, 1, 212, 30, 183, 1, 210, 108, 183, - 1, 241, 202, 183, 1, 216, 227, 183, 1, 216, 228, 243, 98, 183, 1, 210, - 199, 183, 1, 210, 200, 241, 245, 183, 1, 234, 231, 183, 1, 233, 107, 183, - 1, 230, 195, 183, 1, 227, 198, 183, 1, 220, 145, 183, 1, 40, 220, 145, - 183, 1, 76, 183, 1, 225, 224, 183, 1, 223, 52, 225, 224, 183, 1, 222, 26, - 183, 1, 224, 78, 183, 1, 222, 232, 183, 1, 220, 22, 183, 1, 217, 37, 183, - 1, 225, 172, 252, 20, 183, 1, 225, 172, 242, 249, 183, 1, 225, 172, 248, - 28, 183, 224, 154, 48, 183, 224, 154, 51, 183, 224, 154, 246, 125, 183, - 210, 17, 48, 183, 210, 17, 51, 183, 210, 17, 246, 125, 183, 223, 134, 48, - 183, 223, 134, 51, 183, 246, 126, 210, 24, 241, 51, 183, 246, 126, 210, - 24, 254, 113, 183, 241, 248, 48, 183, 241, 248, 51, 183, 241, 247, 246, - 125, 183, 245, 87, 48, 183, 245, 87, 51, 183, 222, 109, 183, 244, 144, - 247, 128, 183, 223, 251, 183, 222, 136, 183, 113, 67, 170, 48, 183, 113, - 67, 170, 51, 183, 134, 170, 48, 183, 134, 170, 51, 183, 226, 252, 232, - 220, 48, 183, 226, 252, 232, 220, 51, 183, 230, 61, 183, 252, 139, 183, - 1, 219, 51, 210, 80, 183, 1, 219, 51, 234, 128, 183, 1, 219, 51, 244, - 162, 9, 1, 252, 63, 2, 134, 170, 241, 1, 51, 9, 1, 252, 63, 2, 59, 252, - 51, 22, 134, 170, 48, 9, 1, 252, 63, 2, 134, 170, 225, 10, 214, 153, 51, - 9, 1, 252, 63, 2, 134, 170, 225, 10, 214, 153, 252, 51, 22, 113, 170, 48, - 9, 1, 252, 63, 2, 113, 170, 252, 51, 22, 59, 48, 9, 1, 252, 63, 2, 235, - 200, 4, 214, 106, 51, 9, 1, 252, 63, 2, 4, 214, 105, 9, 1, 122, 2, 113, - 170, 48, 9, 1, 122, 2, 134, 170, 225, 10, 214, 153, 51, 9, 1, 248, 204, - 2, 113, 170, 213, 189, 252, 51, 22, 4, 217, 81, 9, 1, 248, 204, 2, 235, - 200, 4, 214, 106, 51, 9, 1, 223, 99, 2, 91, 9, 1, 221, 169, 2, 244, 19, - 170, 48, 9, 1, 254, 206, 2, 113, 170, 48, 9, 1, 254, 206, 2, 134, 170, - 225, 10, 246, 112, 48, 9, 1, 254, 206, 2, 113, 170, 213, 189, 48, 9, 1, - 244, 151, 2, 113, 170, 51, 9, 1, 244, 151, 2, 134, 170, 225, 10, 214, - 153, 51, 9, 1, 234, 181, 2, 59, 48, 9, 1, 234, 181, 2, 134, 170, 48, 9, - 1, 234, 181, 2, 134, 170, 225, 10, 214, 153, 51, 9, 1, 66, 2, 59, 48, 9, - 1, 66, 2, 59, 51, 9, 1, 228, 68, 2, 113, 170, 51, 9, 1, 228, 68, 2, 4, - 217, 81, 9, 1, 228, 68, 2, 4, 214, 105, 9, 1, 233, 109, 2, 130, 9, 1, - 223, 99, 2, 113, 170, 213, 189, 48, 9, 1, 223, 99, 2, 182, 48, 9, 1, 221, - 169, 2, 113, 170, 213, 189, 48, 9, 1, 122, 2, 4, 9, 1, 217, 82, 51, 9, 1, - 122, 2, 4, 9, 1, 217, 82, 22, 113, 247, 126, 9, 1, 221, 169, 2, 4, 9, 1, - 217, 82, 22, 113, 247, 126, 9, 1, 223, 99, 2, 4, 9, 1, 217, 82, 22, 113, - 247, 126, 9, 1, 122, 2, 4, 9, 1, 217, 82, 48, 9, 1, 109, 2, 245, 30, 254, - 45, 21, 113, 48, 9, 1, 109, 2, 245, 30, 254, 45, 21, 134, 48, 9, 1, 244, - 176, 77, 2, 245, 30, 254, 45, 21, 113, 48, 9, 1, 244, 176, 77, 2, 245, - 30, 254, 45, 21, 134, 48, 9, 1, 244, 176, 77, 2, 245, 30, 254, 45, 21, - 244, 19, 51, 9, 1, 212, 31, 2, 245, 30, 254, 45, 21, 113, 48, 9, 1, 212, - 31, 2, 245, 30, 254, 45, 21, 134, 48, 9, 1, 77, 252, 141, 2, 245, 30, - 254, 45, 21, 113, 48, 9, 1, 77, 252, 141, 2, 245, 30, 254, 45, 21, 134, - 48, 9, 1, 122, 2, 245, 30, 254, 45, 21, 244, 19, 51, 9, 1, 221, 169, 2, - 245, 30, 254, 45, 21, 244, 19, 48, 9, 1, 221, 169, 2, 235, 200, 214, 105, - 9, 1, 235, 1, 2, 113, 170, 48, 216, 206, 1, 242, 53, 216, 206, 1, 220, - 70, 216, 206, 1, 228, 66, 216, 206, 1, 223, 187, 216, 206, 1, 252, 197, - 216, 206, 1, 233, 1, 216, 206, 1, 235, 14, 216, 206, 1, 254, 168, 216, - 206, 1, 214, 25, 216, 206, 1, 231, 82, 216, 206, 1, 244, 202, 216, 206, - 1, 248, 31, 216, 206, 1, 216, 208, 216, 206, 1, 233, 137, 216, 206, 1, - 243, 138, 216, 206, 1, 242, 184, 216, 206, 1, 221, 167, 216, 206, 1, 248, - 156, 216, 206, 1, 210, 100, 216, 206, 1, 217, 38, 216, 206, 1, 211, 103, - 216, 206, 1, 225, 237, 216, 206, 1, 235, 134, 216, 206, 1, 250, 142, 216, - 206, 1, 215, 156, 216, 206, 1, 241, 195, 216, 206, 1, 234, 137, 216, 206, - 1, 216, 207, 216, 206, 1, 210, 115, 216, 206, 1, 220, 60, 216, 206, 1, - 222, 32, 216, 206, 1, 248, 227, 216, 206, 1, 112, 216, 206, 1, 210, 23, - 216, 206, 1, 254, 202, 216, 206, 1, 242, 250, 216, 206, 1, 224, 88, 216, - 206, 1, 212, 63, 216, 206, 255, 31, 216, 206, 255, 47, 216, 206, 240, - 121, 216, 206, 245, 216, 216, 206, 214, 222, 216, 206, 226, 186, 216, - 206, 245, 224, 216, 206, 245, 24, 216, 206, 226, 251, 216, 206, 227, 3, - 216, 206, 218, 46, 216, 206, 1, 229, 230, 228, 142, 21, 210, 86, 228, - 142, 21, 111, 228, 142, 21, 105, 228, 142, 21, 158, 228, 142, 21, 161, - 228, 142, 21, 190, 228, 142, 21, 195, 228, 142, 21, 199, 228, 142, 21, - 196, 228, 142, 21, 201, 228, 142, 1, 61, 228, 142, 1, 245, 217, 228, 142, - 1, 74, 228, 142, 1, 76, 228, 142, 1, 69, 228, 142, 1, 226, 187, 228, 142, - 1, 78, 228, 142, 1, 248, 217, 228, 142, 1, 230, 30, 228, 142, 1, 252, - 199, 228, 142, 1, 191, 228, 142, 1, 217, 106, 228, 142, 1, 235, 147, 228, - 142, 1, 250, 165, 228, 142, 1, 248, 229, 228, 142, 1, 205, 228, 142, 1, - 222, 181, 228, 142, 1, 206, 228, 142, 1, 243, 86, 228, 142, 1, 244, 204, - 228, 142, 1, 176, 228, 142, 1, 233, 141, 228, 142, 1, 229, 234, 211, 223, - 228, 142, 1, 186, 228, 142, 1, 227, 169, 228, 142, 1, 198, 228, 142, 1, - 162, 228, 142, 1, 212, 65, 228, 142, 1, 192, 228, 142, 1, 227, 170, 211, - 223, 228, 142, 1, 235, 67, 235, 147, 228, 142, 1, 235, 67, 250, 165, 228, - 142, 1, 235, 67, 205, 228, 142, 38, 219, 253, 125, 216, 31, 228, 142, 38, - 219, 253, 121, 216, 31, 228, 142, 38, 219, 253, 222, 231, 216, 31, 228, - 142, 38, 200, 248, 46, 216, 31, 228, 142, 38, 200, 125, 216, 31, 228, - 142, 38, 200, 121, 216, 31, 228, 142, 38, 200, 222, 231, 216, 31, 228, - 142, 38, 229, 198, 79, 228, 142, 38, 52, 59, 48, 228, 142, 125, 138, 254, - 65, 228, 142, 121, 138, 254, 65, 228, 142, 16, 226, 188, 248, 58, 228, - 142, 16, 243, 85, 228, 142, 249, 227, 228, 142, 245, 39, 79, 228, 142, - 233, 114, 221, 254, 1, 254, 185, 221, 254, 1, 251, 236, 221, 254, 1, 243, - 119, 221, 254, 1, 248, 202, 221, 254, 1, 235, 158, 221, 254, 1, 252, 197, - 221, 254, 1, 210, 89, 221, 254, 1, 235, 166, 221, 254, 1, 216, 68, 221, - 254, 1, 210, 182, 221, 254, 1, 235, 15, 221, 254, 1, 233, 134, 221, 254, - 1, 230, 195, 221, 254, 1, 227, 198, 221, 254, 1, 219, 158, 221, 254, 1, - 236, 6, 221, 254, 1, 244, 129, 221, 254, 1, 215, 182, 221, 254, 1, 224, - 13, 221, 254, 1, 222, 232, 221, 254, 1, 220, 87, 221, 254, 1, 217, 101, - 221, 254, 164, 236, 6, 221, 254, 164, 236, 5, 221, 254, 164, 226, 247, - 221, 254, 164, 248, 215, 221, 254, 58, 1, 245, 113, 210, 182, 221, 254, - 164, 245, 113, 210, 182, 221, 254, 25, 5, 200, 76, 221, 254, 25, 5, 76, - 221, 254, 25, 5, 226, 122, 255, 82, 221, 254, 25, 5, 200, 255, 82, 221, - 254, 25, 5, 255, 82, 221, 254, 25, 5, 226, 122, 61, 221, 254, 25, 5, 200, - 61, 221, 254, 25, 5, 61, 221, 254, 58, 1, 219, 253, 61, 221, 254, 25, 5, - 219, 253, 61, 221, 254, 25, 5, 200, 69, 221, 254, 25, 5, 69, 221, 254, - 58, 1, 74, 221, 254, 25, 5, 200, 74, 221, 254, 25, 5, 74, 221, 254, 25, - 5, 78, 221, 254, 25, 5, 218, 46, 221, 254, 164, 229, 97, 221, 254, 224, - 144, 229, 97, 221, 254, 224, 144, 254, 227, 221, 254, 224, 144, 254, 122, - 221, 254, 224, 144, 252, 122, 221, 254, 224, 144, 253, 209, 221, 254, - 224, 144, 220, 10, 221, 254, 255, 30, 79, 221, 254, 224, 144, 231, 73, - 224, 48, 221, 254, 224, 144, 210, 31, 221, 254, 224, 144, 224, 48, 221, - 254, 224, 144, 210, 114, 221, 254, 224, 144, 215, 90, 221, 254, 224, 144, - 254, 17, 221, 254, 224, 144, 219, 55, 231, 150, 221, 254, 224, 144, 254, - 108, 231, 187, 1, 242, 31, 231, 187, 1, 255, 34, 231, 187, 1, 254, 225, - 231, 187, 1, 255, 8, 231, 187, 1, 254, 218, 231, 187, 1, 214, 124, 231, - 187, 1, 253, 168, 231, 187, 1, 235, 166, 231, 187, 1, 253, 206, 231, 187, - 1, 254, 190, 231, 187, 1, 254, 195, 231, 187, 1, 254, 187, 231, 187, 1, - 254, 144, 231, 187, 1, 254, 131, 231, 187, 1, 253, 245, 231, 187, 1, 236, - 6, 231, 187, 1, 254, 80, 231, 187, 1, 253, 216, 231, 187, 1, 254, 53, - 231, 187, 1, 254, 49, 231, 187, 1, 253, 239, 231, 187, 1, 253, 214, 231, - 187, 1, 246, 63, 231, 187, 1, 235, 8, 231, 187, 1, 254, 205, 231, 187, - 254, 231, 79, 231, 187, 213, 136, 79, 231, 187, 243, 60, 79, 231, 187, - 224, 143, 9, 1, 252, 63, 2, 4, 214, 106, 51, 9, 1, 151, 2, 113, 170, 48, - 9, 1, 217, 82, 2, 113, 170, 48, 9, 1, 244, 151, 2, 59, 252, 51, 22, 134, - 170, 48, 9, 1, 224, 85, 2, 59, 51, 9, 1, 233, 109, 2, 52, 130, 9, 1, 66, - 2, 134, 170, 48, 9, 1, 77, 2, 113, 170, 252, 51, 22, 182, 48, 9, 1, 77, - 2, 113, 170, 252, 51, 22, 59, 48, 9, 1, 223, 99, 2, 232, 129, 9, 1, 212, - 31, 2, 59, 211, 231, 9, 1, 222, 203, 211, 43, 9, 249, 107, 244, 173, 9, - 249, 107, 248, 192, 9, 249, 107, 234, 211, 9, 249, 107, 244, 171, 9, 249, - 107, 248, 190, 9, 249, 107, 234, 209, 9, 138, 123, 59, 48, 9, 138, 113, - 170, 48, 9, 138, 232, 130, 48, 9, 138, 123, 59, 51, 9, 138, 113, 170, 51, - 9, 138, 232, 130, 51, 9, 204, 244, 171, 9, 204, 248, 190, 9, 204, 234, - 209, 9, 4, 125, 212, 30, 9, 244, 174, 2, 222, 236, 9, 244, 174, 2, 59, - 48, 9, 234, 212, 2, 59, 51, 9, 43, 254, 2, 48, 9, 44, 254, 2, 48, 9, 43, - 254, 2, 51, 9, 44, 254, 2, 51, 9, 52, 44, 254, 2, 48, 9, 52, 44, 254, 2, - 72, 2, 247, 128, 9, 44, 254, 2, 72, 2, 247, 128, 9, 248, 193, 2, 247, - 128, 84, 5, 235, 200, 251, 7, 84, 5, 251, 7, 84, 5, 254, 83, 84, 5, 213, - 147, 84, 1, 219, 253, 61, 84, 1, 61, 84, 1, 255, 82, 84, 1, 74, 84, 1, - 236, 40, 84, 1, 69, 84, 1, 214, 118, 84, 1, 149, 153, 84, 1, 149, 156, - 84, 1, 251, 10, 76, 84, 1, 219, 253, 76, 84, 1, 76, 84, 1, 254, 210, 84, - 1, 251, 10, 78, 84, 1, 219, 253, 78, 84, 1, 78, 84, 1, 253, 200, 84, 1, - 176, 84, 1, 234, 138, 84, 1, 243, 142, 84, 1, 243, 0, 84, 1, 229, 82, 84, - 1, 251, 41, 84, 1, 250, 165, 84, 1, 235, 147, 84, 1, 235, 120, 84, 1, - 227, 169, 84, 1, 215, 157, 84, 1, 215, 145, 84, 1, 248, 143, 84, 1, 248, - 127, 84, 1, 228, 115, 84, 1, 217, 106, 84, 1, 216, 209, 84, 1, 248, 229, - 84, 1, 248, 33, 84, 1, 198, 84, 1, 228, 97, 84, 1, 191, 84, 1, 225, 150, - 84, 1, 252, 199, 84, 1, 252, 26, 84, 1, 186, 84, 1, 192, 84, 1, 205, 84, - 1, 222, 181, 84, 1, 233, 141, 84, 1, 232, 190, 84, 1, 232, 181, 84, 1, - 214, 27, 84, 1, 220, 104, 84, 1, 218, 225, 84, 1, 206, 84, 1, 162, 84, - 25, 5, 226, 238, 84, 25, 5, 226, 185, 84, 5, 227, 209, 84, 5, 253, 183, - 84, 25, 5, 255, 82, 84, 25, 5, 74, 84, 25, 5, 236, 40, 84, 25, 5, 69, 84, - 25, 5, 214, 118, 84, 25, 5, 149, 153, 84, 25, 5, 149, 222, 182, 84, 25, - 5, 251, 10, 76, 84, 25, 5, 219, 253, 76, 84, 25, 5, 76, 84, 25, 5, 254, - 210, 84, 25, 5, 251, 10, 78, 84, 25, 5, 219, 253, 78, 84, 25, 5, 78, 84, - 25, 5, 253, 200, 84, 5, 213, 152, 84, 25, 5, 224, 188, 76, 84, 25, 5, - 253, 179, 84, 226, 208, 84, 218, 113, 5, 214, 216, 84, 218, 113, 5, 254, - 85, 84, 242, 144, 255, 23, 84, 255, 12, 255, 23, 84, 25, 5, 251, 10, 200, - 76, 84, 25, 5, 214, 214, 84, 25, 5, 214, 117, 84, 1, 224, 91, 84, 1, 234, - 121, 84, 1, 242, 233, 84, 1, 210, 116, 84, 1, 248, 132, 84, 1, 223, 42, - 84, 1, 244, 204, 84, 1, 210, 168, 84, 1, 149, 222, 182, 84, 1, 149, 232, - 191, 84, 25, 5, 149, 156, 84, 25, 5, 149, 232, 191, 84, 248, 186, 84, 52, - 248, 186, 84, 21, 210, 86, 84, 21, 111, 84, 21, 105, 84, 21, 158, 84, 21, - 161, 84, 21, 190, 84, 21, 195, 84, 21, 199, 84, 21, 196, 84, 21, 201, 84, - 255, 30, 50, 84, 5, 125, 219, 19, 247, 128, 84, 1, 251, 10, 61, 84, 1, - 226, 238, 84, 1, 226, 185, 84, 1, 253, 179, 84, 1, 214, 214, 84, 1, 214, - 117, 84, 1, 210, 82, 84, 1, 114, 192, 84, 1, 243, 36, 84, 1, 235, 102, - 84, 1, 242, 187, 218, 131, 84, 1, 248, 133, 84, 1, 252, 119, 146, 5, 251, - 7, 146, 5, 254, 83, 146, 5, 213, 147, 146, 1, 61, 146, 1, 255, 82, 146, - 1, 74, 146, 1, 236, 40, 146, 1, 69, 146, 1, 214, 118, 146, 1, 149, 153, - 146, 1, 149, 156, 146, 1, 76, 146, 1, 254, 210, 146, 1, 78, 146, 1, 253, - 200, 146, 1, 176, 146, 1, 234, 138, 146, 1, 243, 142, 146, 1, 243, 0, - 146, 1, 229, 82, 146, 1, 251, 41, 146, 1, 250, 165, 146, 1, 235, 147, - 146, 1, 235, 120, 146, 1, 227, 169, 146, 1, 215, 157, 146, 1, 215, 145, - 146, 1, 248, 143, 146, 1, 248, 127, 146, 1, 228, 115, 146, 1, 217, 106, - 146, 1, 216, 209, 146, 1, 248, 229, 146, 1, 248, 33, 146, 1, 198, 146, 1, - 191, 146, 1, 225, 150, 146, 1, 252, 199, 146, 1, 252, 26, 146, 1, 186, - 146, 1, 192, 146, 1, 205, 146, 1, 233, 141, 146, 1, 220, 104, 146, 1, - 218, 225, 146, 1, 206, 146, 1, 162, 146, 5, 227, 209, 146, 5, 253, 183, - 146, 25, 5, 255, 82, 146, 25, 5, 74, 146, 25, 5, 236, 40, 146, 25, 5, 69, - 146, 25, 5, 214, 118, 146, 25, 5, 149, 153, 146, 25, 5, 149, 222, 182, - 146, 25, 5, 76, 146, 25, 5, 254, 210, 146, 25, 5, 78, 146, 25, 5, 253, - 200, 146, 5, 213, 152, 146, 1, 234, 130, 217, 106, 146, 253, 201, 233, - 29, 79, 146, 1, 222, 181, 146, 1, 223, 42, 146, 1, 210, 168, 146, 1, 149, - 222, 182, 146, 1, 149, 232, 191, 146, 25, 5, 149, 156, 146, 25, 5, 149, - 232, 191, 146, 21, 210, 86, 146, 21, 111, 146, 21, 105, 146, 21, 158, - 146, 21, 161, 146, 21, 190, 146, 21, 195, 146, 21, 199, 146, 21, 196, - 146, 21, 201, 146, 1, 223, 191, 2, 230, 229, 248, 6, 146, 1, 223, 191, 2, - 232, 114, 248, 6, 146, 222, 120, 79, 146, 222, 120, 50, 146, 249, 106, - 227, 201, 111, 146, 249, 106, 227, 201, 105, 146, 249, 106, 227, 201, - 158, 146, 249, 106, 227, 201, 161, 146, 249, 106, 227, 201, 123, 233, 22, - 216, 202, 216, 197, 248, 56, 146, 249, 106, 248, 57, 219, 121, 146, 235, - 167, 146, 243, 110, 79, 185, 5, 255, 7, 251, 251, 185, 5, 251, 251, 185, - 5, 213, 147, 185, 1, 61, 185, 1, 255, 82, 185, 1, 74, 185, 1, 236, 40, - 185, 1, 69, 185, 1, 214, 118, 185, 1, 245, 217, 185, 1, 254, 210, 185, 1, - 226, 187, 185, 1, 253, 200, 185, 1, 176, 185, 1, 234, 138, 185, 1, 243, - 142, 185, 1, 243, 0, 185, 1, 229, 82, 185, 1, 251, 41, 185, 1, 250, 165, - 185, 1, 235, 147, 185, 1, 235, 120, 185, 1, 227, 169, 185, 1, 215, 157, - 185, 1, 215, 145, 185, 1, 248, 143, 185, 1, 248, 127, 185, 1, 228, 115, - 185, 1, 217, 106, 185, 1, 216, 209, 185, 1, 248, 229, 185, 1, 248, 33, - 185, 1, 198, 185, 1, 191, 185, 1, 225, 150, 185, 1, 252, 199, 185, 1, - 252, 26, 185, 1, 186, 185, 1, 192, 185, 1, 205, 185, 1, 233, 141, 185, 1, - 232, 190, 185, 1, 214, 27, 185, 1, 220, 104, 185, 1, 206, 185, 1, 162, - 185, 5, 227, 209, 185, 25, 5, 255, 82, 185, 25, 5, 74, 185, 25, 5, 236, - 40, 185, 25, 5, 69, 185, 25, 5, 214, 118, 185, 25, 5, 245, 217, 185, 25, - 5, 254, 210, 185, 25, 5, 226, 187, 185, 25, 5, 253, 200, 185, 5, 213, - 152, 185, 5, 214, 218, 185, 1, 234, 121, 185, 1, 242, 233, 185, 1, 210, - 116, 185, 1, 222, 181, 185, 1, 244, 204, 185, 21, 210, 86, 185, 21, 111, - 185, 21, 105, 185, 21, 158, 185, 21, 161, 185, 21, 190, 185, 21, 195, - 185, 21, 199, 185, 21, 196, 185, 21, 201, 185, 216, 75, 185, 255, 6, 185, - 235, 185, 185, 214, 146, 185, 245, 189, 226, 192, 185, 5, 211, 78, 171, - 5, 251, 7, 171, 5, 254, 83, 171, 5, 213, 147, 171, 1, 61, 171, 1, 255, - 82, 171, 1, 74, 171, 1, 236, 40, 171, 1, 69, 171, 1, 214, 118, 171, 1, - 149, 153, 171, 1, 149, 156, 171, 25, 251, 10, 76, 171, 1, 76, 171, 1, - 254, 210, 171, 25, 251, 10, 78, 171, 1, 78, 171, 1, 253, 200, 171, 1, - 176, 171, 1, 234, 138, 171, 1, 243, 142, 171, 1, 243, 0, 171, 1, 229, 82, - 171, 1, 251, 41, 171, 1, 250, 165, 171, 1, 235, 147, 171, 1, 235, 120, - 171, 1, 227, 169, 171, 1, 215, 157, 171, 1, 215, 145, 171, 1, 248, 143, - 171, 1, 248, 127, 171, 1, 228, 115, 171, 1, 217, 106, 171, 1, 216, 209, - 171, 1, 248, 229, 171, 1, 248, 33, 171, 1, 198, 171, 1, 191, 171, 1, 225, - 150, 171, 1, 252, 199, 171, 1, 252, 26, 171, 1, 186, 171, 1, 192, 171, 1, - 205, 171, 1, 233, 141, 171, 1, 232, 190, 171, 1, 214, 27, 171, 1, 220, - 104, 171, 1, 218, 225, 171, 1, 206, 171, 1, 162, 171, 5, 227, 209, 171, - 5, 253, 183, 171, 25, 5, 255, 82, 171, 25, 5, 74, 171, 25, 5, 236, 40, - 171, 25, 5, 69, 171, 25, 5, 214, 118, 171, 25, 5, 149, 153, 171, 25, 5, - 149, 222, 182, 171, 25, 5, 251, 10, 76, 171, 25, 5, 76, 171, 25, 5, 254, - 210, 171, 25, 5, 251, 10, 78, 171, 25, 5, 78, 171, 25, 5, 253, 200, 171, - 5, 213, 152, 171, 226, 208, 171, 1, 149, 222, 182, 171, 1, 149, 232, 191, - 171, 25, 5, 149, 156, 171, 25, 5, 149, 232, 191, 171, 21, 210, 86, 171, - 21, 111, 171, 21, 105, 171, 21, 158, 171, 21, 161, 171, 21, 190, 171, 21, - 195, 171, 21, 199, 171, 21, 196, 171, 21, 201, 171, 255, 30, 50, 171, - 222, 120, 50, 157, 5, 251, 7, 157, 5, 254, 83, 157, 5, 213, 147, 157, 1, - 61, 157, 1, 255, 82, 157, 1, 74, 157, 1, 236, 40, 157, 1, 69, 157, 1, - 214, 118, 157, 1, 149, 153, 157, 1, 149, 156, 157, 1, 76, 157, 1, 254, - 210, 157, 1, 78, 157, 1, 253, 200, 157, 1, 176, 157, 1, 234, 138, 157, 1, - 243, 142, 157, 1, 243, 0, 157, 1, 229, 82, 157, 1, 251, 41, 157, 1, 250, - 165, 157, 1, 235, 147, 157, 1, 235, 120, 157, 1, 227, 169, 157, 1, 215, - 157, 157, 1, 215, 145, 157, 1, 248, 143, 157, 1, 248, 127, 157, 1, 228, - 115, 157, 1, 217, 106, 157, 1, 216, 209, 157, 1, 248, 229, 157, 1, 248, - 33, 157, 1, 198, 157, 1, 191, 157, 1, 225, 150, 157, 1, 252, 199, 157, 1, - 252, 26, 157, 1, 186, 157, 1, 192, 157, 1, 205, 157, 1, 233, 141, 157, 1, - 232, 190, 157, 1, 214, 27, 157, 1, 220, 104, 157, 1, 218, 225, 157, 1, - 206, 157, 1, 162, 157, 5, 227, 209, 157, 5, 253, 183, 157, 25, 5, 255, - 82, 157, 25, 5, 74, 157, 25, 5, 236, 40, 157, 25, 5, 69, 157, 25, 5, 214, - 118, 157, 25, 5, 149, 153, 157, 25, 5, 149, 222, 182, 157, 25, 5, 76, - 157, 25, 5, 254, 210, 157, 25, 5, 78, 157, 25, 5, 253, 200, 157, 5, 213, - 152, 157, 254, 211, 233, 29, 79, 157, 253, 201, 233, 29, 79, 157, 1, 222, - 181, 157, 1, 223, 42, 157, 1, 210, 168, 157, 1, 149, 222, 182, 157, 1, - 149, 232, 191, 157, 25, 5, 149, 156, 157, 25, 5, 149, 232, 191, 157, 21, - 210, 86, 157, 21, 111, 157, 21, 105, 157, 21, 158, 157, 21, 161, 157, 21, - 190, 157, 21, 195, 157, 21, 199, 157, 21, 196, 157, 21, 201, 157, 235, - 167, 157, 1, 212, 65, 157, 244, 10, 123, 224, 24, 157, 244, 10, 123, 242, - 34, 157, 244, 10, 134, 224, 22, 157, 244, 10, 123, 219, 119, 157, 244, - 10, 123, 245, 196, 157, 244, 10, 134, 219, 118, 36, 5, 254, 83, 36, 5, - 213, 147, 36, 1, 61, 36, 1, 255, 82, 36, 1, 74, 36, 1, 236, 40, 36, 1, - 69, 36, 1, 214, 118, 36, 1, 76, 36, 1, 245, 217, 36, 1, 254, 210, 36, 1, - 78, 36, 1, 226, 187, 36, 1, 253, 200, 36, 1, 176, 36, 1, 229, 82, 36, 1, - 251, 41, 36, 1, 235, 147, 36, 1, 227, 169, 36, 1, 215, 157, 36, 1, 228, - 115, 36, 1, 217, 106, 36, 1, 198, 36, 1, 228, 97, 36, 1, 191, 36, 1, 186, - 36, 1, 192, 36, 1, 205, 36, 1, 222, 181, 36, 1, 233, 141, 36, 1, 232, - 190, 36, 1, 232, 181, 36, 1, 214, 27, 36, 1, 220, 104, 36, 1, 218, 225, - 36, 1, 206, 36, 1, 162, 36, 25, 5, 255, 82, 36, 25, 5, 74, 36, 25, 5, - 236, 40, 36, 25, 5, 69, 36, 25, 5, 214, 118, 36, 25, 5, 76, 36, 25, 5, - 245, 217, 36, 25, 5, 254, 210, 36, 25, 5, 78, 36, 25, 5, 226, 187, 36, - 25, 5, 253, 200, 36, 5, 213, 152, 36, 226, 208, 36, 253, 201, 233, 29, - 79, 36, 21, 210, 86, 36, 21, 111, 36, 21, 105, 36, 21, 158, 36, 21, 161, - 36, 21, 190, 36, 21, 195, 36, 21, 199, 36, 21, 196, 36, 21, 201, 36, 54, - 216, 248, 36, 54, 123, 240, 217, 36, 54, 123, 216, 148, 36, 248, 154, 50, - 36, 230, 140, 50, 36, 211, 45, 50, 36, 248, 95, 50, 36, 249, 147, 50, 36, - 253, 246, 72, 50, 36, 222, 120, 50, 36, 54, 50, 148, 5, 251, 7, 148, 5, - 254, 83, 148, 5, 213, 147, 148, 1, 61, 148, 1, 255, 82, 148, 1, 74, 148, - 1, 236, 40, 148, 1, 69, 148, 1, 214, 118, 148, 1, 149, 153, 148, 1, 149, - 156, 148, 1, 76, 148, 1, 245, 217, 148, 1, 254, 210, 148, 1, 78, 148, 1, - 226, 187, 148, 1, 253, 200, 148, 1, 176, 148, 1, 234, 138, 148, 1, 243, - 142, 148, 1, 243, 0, 148, 1, 229, 82, 148, 1, 251, 41, 148, 1, 250, 165, - 148, 1, 235, 147, 148, 1, 235, 120, 148, 1, 227, 169, 148, 1, 215, 157, - 148, 1, 215, 145, 148, 1, 248, 143, 148, 1, 248, 127, 148, 1, 228, 115, - 148, 1, 217, 106, 148, 1, 216, 209, 148, 1, 248, 229, 148, 1, 248, 33, - 148, 1, 198, 148, 1, 191, 148, 1, 225, 150, 148, 1, 252, 199, 148, 1, - 252, 26, 148, 1, 186, 148, 1, 192, 148, 1, 205, 148, 1, 222, 181, 148, 1, - 233, 141, 148, 1, 232, 190, 148, 1, 214, 27, 148, 1, 220, 104, 148, 1, - 218, 225, 148, 1, 206, 148, 1, 162, 148, 5, 253, 183, 148, 25, 5, 255, - 82, 148, 25, 5, 74, 148, 25, 5, 236, 40, 148, 25, 5, 69, 148, 25, 5, 214, - 118, 148, 25, 5, 149, 153, 148, 25, 5, 149, 222, 182, 148, 25, 5, 76, - 148, 25, 5, 245, 217, 148, 25, 5, 254, 210, 148, 25, 5, 78, 148, 25, 5, - 226, 187, 148, 25, 5, 253, 200, 148, 5, 213, 152, 148, 233, 29, 79, 148, - 254, 211, 233, 29, 79, 148, 1, 215, 184, 148, 1, 246, 46, 148, 1, 149, - 222, 182, 148, 1, 149, 232, 191, 148, 25, 5, 149, 156, 148, 25, 5, 149, - 232, 191, 148, 21, 210, 86, 148, 21, 111, 148, 21, 105, 148, 21, 158, - 148, 21, 161, 148, 21, 190, 148, 21, 195, 148, 21, 199, 148, 21, 196, - 148, 21, 201, 148, 244, 10, 21, 210, 87, 31, 226, 241, 224, 226, 64, 161, - 148, 244, 10, 21, 123, 31, 226, 241, 224, 226, 64, 161, 148, 244, 10, 21, - 113, 31, 226, 241, 224, 226, 64, 161, 148, 244, 10, 21, 134, 31, 226, - 241, 224, 226, 64, 161, 148, 244, 10, 21, 123, 31, 245, 50, 224, 226, 64, - 161, 148, 244, 10, 21, 113, 31, 245, 50, 224, 226, 64, 161, 148, 244, 10, - 21, 134, 31, 245, 50, 224, 226, 64, 161, 148, 5, 215, 84, 165, 5, 254, - 83, 165, 5, 213, 147, 165, 1, 61, 165, 1, 255, 82, 165, 1, 74, 165, 1, - 236, 40, 165, 1, 69, 165, 1, 214, 118, 165, 1, 149, 153, 165, 1, 149, - 156, 165, 1, 76, 165, 1, 245, 217, 165, 1, 254, 210, 165, 1, 78, 165, 1, - 226, 187, 165, 1, 253, 200, 165, 1, 176, 165, 1, 234, 138, 165, 1, 243, - 142, 165, 1, 243, 0, 165, 1, 229, 82, 165, 1, 251, 41, 165, 1, 250, 165, - 165, 1, 235, 147, 165, 1, 235, 120, 165, 1, 227, 169, 165, 1, 215, 157, - 165, 1, 215, 145, 165, 1, 248, 143, 165, 1, 248, 127, 165, 1, 228, 115, - 165, 1, 217, 106, 165, 1, 216, 209, 165, 1, 248, 229, 165, 1, 248, 33, - 165, 1, 198, 165, 1, 191, 165, 1, 225, 150, 165, 1, 252, 199, 165, 1, - 252, 26, 165, 1, 186, 165, 1, 192, 165, 1, 205, 165, 1, 222, 181, 165, 1, - 233, 141, 165, 1, 232, 190, 165, 1, 214, 27, 165, 1, 220, 104, 165, 1, - 218, 225, 165, 1, 206, 165, 1, 162, 165, 5, 227, 209, 165, 5, 253, 183, - 165, 25, 5, 255, 82, 165, 25, 5, 74, 165, 25, 5, 236, 40, 165, 25, 5, 69, - 165, 25, 5, 214, 118, 165, 25, 5, 149, 153, 165, 25, 5, 149, 222, 182, - 165, 25, 5, 76, 165, 25, 5, 245, 217, 165, 25, 5, 254, 210, 165, 25, 5, - 78, 165, 25, 5, 226, 187, 165, 25, 5, 253, 200, 165, 5, 213, 152, 165, - 233, 29, 79, 165, 254, 211, 233, 29, 79, 165, 1, 244, 204, 165, 1, 149, - 222, 182, 165, 1, 149, 232, 191, 165, 25, 5, 149, 156, 165, 25, 5, 149, - 232, 191, 165, 21, 210, 86, 165, 21, 111, 165, 21, 105, 165, 21, 158, - 165, 21, 161, 165, 21, 190, 165, 21, 195, 165, 21, 199, 165, 21, 196, - 165, 21, 201, 165, 5, 235, 108, 165, 5, 214, 161, 136, 5, 254, 83, 136, - 5, 213, 147, 136, 1, 61, 136, 1, 255, 82, 136, 1, 74, 136, 1, 236, 40, - 136, 1, 69, 136, 1, 214, 118, 136, 1, 149, 153, 136, 1, 149, 156, 136, 1, - 76, 136, 1, 245, 217, 136, 1, 254, 210, 136, 1, 78, 136, 1, 226, 187, - 136, 1, 253, 200, 136, 1, 176, 136, 1, 234, 138, 136, 1, 243, 142, 136, - 1, 243, 0, 136, 1, 229, 82, 136, 1, 251, 41, 136, 1, 250, 165, 136, 1, - 235, 147, 136, 1, 235, 120, 136, 1, 227, 169, 136, 1, 215, 157, 136, 1, - 215, 145, 136, 1, 248, 143, 136, 1, 248, 127, 136, 1, 228, 115, 136, 1, - 217, 106, 136, 1, 216, 209, 136, 1, 248, 229, 136, 1, 248, 33, 136, 1, - 198, 136, 1, 228, 97, 136, 1, 191, 136, 1, 225, 150, 136, 1, 252, 199, - 136, 1, 252, 26, 136, 1, 186, 136, 1, 192, 136, 1, 205, 136, 1, 222, 181, - 136, 1, 233, 141, 136, 1, 232, 190, 136, 1, 232, 181, 136, 1, 214, 27, - 136, 1, 220, 104, 136, 1, 218, 225, 136, 1, 206, 136, 1, 162, 136, 1, - 215, 126, 136, 5, 253, 183, 136, 25, 5, 255, 82, 136, 25, 5, 74, 136, 25, - 5, 236, 40, 136, 25, 5, 69, 136, 25, 5, 214, 118, 136, 25, 5, 149, 153, - 136, 25, 5, 149, 222, 182, 136, 25, 5, 76, 136, 25, 5, 245, 217, 136, 25, - 5, 254, 210, 136, 25, 5, 78, 136, 25, 5, 226, 187, 136, 25, 5, 253, 200, - 136, 5, 213, 152, 136, 1, 59, 223, 76, 136, 253, 201, 233, 29, 79, 136, - 1, 149, 222, 182, 136, 1, 149, 232, 191, 136, 25, 5, 149, 156, 136, 25, - 5, 149, 232, 191, 136, 21, 210, 86, 136, 21, 111, 136, 21, 105, 136, 21, - 158, 136, 21, 161, 136, 21, 190, 136, 21, 195, 136, 21, 199, 136, 21, - 196, 136, 21, 201, 136, 54, 216, 248, 136, 54, 123, 240, 217, 136, 54, - 123, 216, 148, 136, 244, 10, 123, 224, 24, 136, 244, 10, 123, 242, 34, - 136, 244, 10, 134, 224, 22, 136, 248, 158, 79, 136, 1, 250, 107, 228, - 116, 136, 1, 250, 107, 230, 30, 136, 1, 250, 107, 222, 182, 136, 1, 250, - 107, 156, 136, 1, 250, 107, 232, 191, 136, 1, 250, 107, 235, 29, 175, 5, - 254, 82, 175, 5, 213, 146, 175, 1, 253, 173, 175, 1, 255, 36, 175, 1, - 254, 232, 175, 1, 254, 247, 175, 1, 235, 157, 175, 1, 236, 39, 175, 1, - 214, 110, 175, 1, 214, 112, 175, 1, 235, 180, 175, 1, 235, 181, 175, 1, - 236, 25, 175, 1, 236, 27, 175, 1, 245, 25, 175, 1, 245, 212, 175, 1, 254, - 197, 175, 1, 226, 112, 175, 1, 226, 181, 175, 1, 253, 186, 175, 1, 254, - 154, 234, 193, 175, 1, 231, 214, 234, 193, 175, 1, 254, 154, 243, 89, - 175, 1, 231, 214, 243, 89, 175, 1, 234, 235, 229, 227, 175, 1, 221, 238, - 243, 89, 175, 1, 254, 154, 250, 224, 175, 1, 231, 214, 250, 224, 175, 1, - 254, 154, 235, 133, 175, 1, 231, 214, 235, 133, 175, 1, 217, 99, 229, - 227, 175, 1, 217, 99, 221, 237, 229, 228, 175, 1, 221, 238, 235, 133, - 175, 1, 254, 154, 215, 153, 175, 1, 231, 214, 215, 153, 175, 1, 254, 154, - 248, 134, 175, 1, 231, 214, 248, 134, 175, 1, 230, 58, 229, 185, 175, 1, - 221, 238, 248, 134, 175, 1, 254, 154, 217, 31, 175, 1, 231, 214, 217, 31, - 175, 1, 254, 154, 248, 152, 175, 1, 231, 214, 248, 152, 175, 1, 248, 182, - 229, 185, 175, 1, 221, 238, 248, 152, 175, 1, 254, 154, 225, 232, 175, 1, - 231, 214, 225, 232, 175, 1, 254, 154, 252, 120, 175, 1, 231, 214, 252, - 120, 175, 1, 231, 136, 175, 1, 254, 139, 252, 120, 175, 1, 211, 51, 175, - 1, 223, 136, 175, 1, 248, 182, 233, 73, 175, 1, 214, 1, 175, 1, 217, 99, - 221, 212, 175, 1, 230, 58, 221, 212, 175, 1, 248, 182, 221, 212, 175, 1, - 241, 249, 175, 1, 230, 58, 233, 73, 175, 1, 244, 164, 175, 5, 254, 186, - 175, 25, 5, 254, 242, 175, 25, 5, 234, 161, 254, 249, 175, 25, 5, 247, - 236, 254, 249, 175, 25, 5, 234, 161, 235, 177, 175, 25, 5, 247, 236, 235, - 177, 175, 25, 5, 234, 161, 226, 92, 175, 25, 5, 247, 236, 226, 92, 175, - 25, 5, 243, 131, 175, 25, 5, 234, 21, 175, 25, 5, 247, 236, 234, 21, 175, - 25, 5, 234, 23, 248, 75, 175, 25, 5, 234, 22, 242, 54, 254, 242, 175, 25, - 5, 234, 22, 242, 54, 247, 236, 254, 242, 175, 25, 5, 234, 22, 242, 54, - 243, 88, 175, 25, 5, 243, 88, 175, 25, 5, 247, 236, 243, 131, 175, 25, 5, - 247, 236, 243, 88, 175, 224, 144, 233, 213, 168, 135, 234, 35, 234, 252, - 168, 135, 234, 112, 234, 134, 168, 135, 234, 112, 234, 105, 168, 135, - 234, 112, 234, 101, 168, 135, 234, 112, 234, 109, 168, 135, 234, 112, - 223, 157, 168, 135, 229, 10, 228, 253, 168, 135, 250, 95, 250, 155, 168, - 135, 250, 95, 250, 103, 168, 135, 250, 95, 250, 154, 168, 135, 219, 61, - 219, 60, 168, 135, 250, 95, 250, 91, 168, 135, 210, 245, 210, 252, 168, - 135, 247, 154, 250, 162, 168, 135, 216, 43, 225, 242, 168, 135, 216, 158, - 216, 201, 168, 135, 216, 158, 229, 206, 168, 135, 216, 158, 225, 114, - 168, 135, 228, 80, 229, 103, 168, 135, 247, 154, 248, 76, 168, 135, 216, - 43, 217, 56, 168, 135, 216, 158, 216, 132, 168, 135, 216, 158, 216, 205, - 168, 135, 216, 158, 216, 155, 168, 135, 228, 80, 227, 242, 168, 135, 251, - 214, 252, 172, 168, 135, 225, 20, 225, 45, 168, 135, 225, 125, 225, 116, - 168, 135, 244, 52, 244, 204, 168, 135, 225, 125, 225, 144, 168, 135, 244, - 52, 244, 181, 168, 135, 225, 125, 221, 249, 168, 135, 230, 167, 186, 168, - 135, 210, 245, 211, 79, 168, 135, 222, 214, 222, 141, 168, 135, 222, 142, - 168, 135, 232, 163, 232, 212, 168, 135, 232, 103, 168, 135, 211, 228, - 212, 61, 168, 135, 219, 61, 222, 8, 168, 135, 219, 61, 222, 116, 168, - 135, 219, 61, 218, 83, 168, 135, 241, 76, 241, 166, 168, 135, 232, 163, - 250, 76, 168, 135, 144, 254, 123, 168, 135, 241, 76, 228, 75, 168, 135, - 226, 72, 168, 135, 221, 232, 61, 168, 135, 231, 209, 242, 24, 168, 135, - 221, 232, 255, 82, 168, 135, 221, 232, 254, 144, 168, 135, 221, 232, 74, - 168, 135, 221, 232, 236, 40, 168, 135, 221, 232, 214, 214, 168, 135, 221, - 232, 214, 212, 168, 135, 221, 232, 69, 168, 135, 221, 232, 214, 118, 168, - 135, 225, 127, 168, 249, 106, 16, 252, 173, 168, 135, 221, 232, 76, 168, - 135, 221, 232, 254, 252, 168, 135, 221, 232, 78, 168, 135, 221, 232, 254, - 211, 231, 203, 168, 135, 221, 232, 254, 211, 231, 204, 168, 135, 233, - 112, 168, 135, 231, 200, 168, 135, 231, 201, 168, 135, 231, 209, 245, - 188, 168, 135, 231, 209, 216, 157, 168, 135, 231, 209, 215, 229, 168, - 135, 231, 209, 250, 143, 168, 135, 216, 199, 168, 135, 228, 210, 168, - 135, 211, 73, 168, 135, 244, 43, 168, 21, 210, 86, 168, 21, 111, 168, 21, - 105, 168, 21, 158, 168, 21, 161, 168, 21, 190, 168, 21, 195, 168, 21, - 199, 168, 21, 196, 168, 21, 201, 168, 135, 254, 119, 168, 135, 234, 110, - 209, 209, 1, 234, 34, 209, 209, 1, 234, 112, 218, 36, 209, 209, 1, 234, - 112, 217, 63, 209, 209, 1, 229, 9, 209, 209, 1, 249, 246, 209, 209, 1, - 219, 61, 217, 63, 209, 209, 1, 227, 138, 209, 209, 1, 247, 153, 209, 209, - 1, 112, 209, 209, 1, 216, 158, 218, 36, 209, 209, 1, 216, 158, 217, 63, - 209, 209, 1, 228, 79, 209, 209, 1, 251, 213, 209, 209, 1, 225, 19, 209, - 209, 1, 225, 125, 218, 36, 209, 209, 1, 244, 52, 217, 63, 209, 209, 1, - 225, 125, 217, 63, 209, 209, 1, 244, 52, 218, 36, 209, 209, 1, 230, 166, - 209, 209, 1, 210, 244, 209, 209, 1, 232, 163, 232, 212, 209, 209, 1, 232, - 163, 232, 127, 209, 209, 1, 211, 227, 209, 209, 1, 219, 61, 218, 36, 209, - 209, 1, 241, 76, 218, 36, 209, 209, 1, 78, 209, 209, 1, 241, 76, 217, 63, - 209, 209, 245, 171, 209, 209, 25, 5, 61, 209, 209, 25, 5, 231, 209, 234, - 240, 209, 209, 25, 5, 255, 82, 209, 209, 25, 5, 254, 144, 209, 209, 25, - 5, 74, 209, 209, 25, 5, 236, 40, 209, 209, 25, 5, 211, 117, 209, 209, 25, - 5, 210, 169, 209, 209, 25, 5, 69, 209, 209, 25, 5, 214, 118, 209, 209, - 25, 5, 231, 209, 234, 19, 209, 209, 220, 147, 5, 232, 162, 209, 209, 220, - 147, 5, 227, 138, 209, 209, 25, 5, 76, 209, 209, 25, 5, 245, 203, 209, - 209, 25, 5, 78, 209, 209, 25, 5, 253, 175, 209, 209, 25, 5, 254, 210, - 209, 209, 234, 35, 233, 141, 209, 209, 138, 231, 209, 245, 188, 209, 209, - 138, 231, 209, 216, 157, 209, 209, 138, 231, 209, 216, 118, 209, 209, - 138, 231, 209, 250, 231, 209, 209, 251, 12, 79, 209, 209, 228, 219, 209, - 209, 21, 210, 86, 209, 209, 21, 111, 209, 209, 21, 105, 209, 209, 21, - 158, 209, 209, 21, 161, 209, 209, 21, 190, 209, 209, 21, 195, 209, 209, - 21, 199, 209, 209, 21, 196, 209, 209, 21, 201, 209, 209, 241, 76, 228, - 79, 209, 209, 241, 76, 230, 166, 209, 209, 1, 234, 113, 242, 181, 209, - 209, 1, 234, 113, 227, 138, 63, 3, 226, 208, 63, 164, 242, 122, 211, 0, - 230, 253, 215, 190, 61, 63, 164, 242, 122, 211, 0, 230, 253, 255, 168, - 222, 218, 252, 85, 186, 63, 164, 242, 122, 211, 0, 230, 253, 255, 168, - 242, 122, 215, 174, 186, 63, 164, 65, 211, 0, 230, 253, 231, 98, 186, 63, - 164, 250, 4, 211, 0, 230, 253, 220, 111, 186, 63, 164, 250, 247, 211, 0, - 230, 253, 225, 115, 220, 98, 186, 63, 164, 211, 0, 230, 253, 215, 174, - 220, 98, 186, 63, 164, 221, 210, 220, 97, 63, 164, 251, 136, 211, 0, 230, - 252, 63, 164, 251, 231, 220, 5, 211, 0, 230, 252, 63, 164, 235, 204, 215, - 173, 63, 164, 248, 69, 215, 174, 251, 135, 63, 164, 220, 97, 63, 164, - 227, 143, 220, 97, 63, 164, 215, 174, 220, 97, 63, 164, 227, 143, 215, - 174, 220, 97, 63, 164, 222, 239, 250, 130, 218, 238, 220, 97, 63, 164, - 223, 45, 242, 153, 220, 97, 63, 164, 250, 247, 255, 172, 222, 146, 231, - 97, 200, 251, 15, 63, 164, 242, 122, 215, 173, 63, 232, 150, 5, 250, 163, - 222, 145, 63, 232, 150, 5, 233, 2, 222, 145, 63, 253, 220, 5, 220, 107, - 243, 72, 255, 173, 222, 145, 63, 253, 220, 5, 255, 170, 191, 63, 253, - 220, 5, 221, 184, 215, 169, 63, 5, 223, 133, 247, 167, 243, 71, 63, 5, - 223, 133, 247, 167, 242, 183, 63, 5, 223, 133, 247, 167, 242, 123, 63, 5, - 223, 133, 229, 224, 243, 71, 63, 5, 223, 133, 229, 224, 242, 183, 63, 5, - 223, 133, 247, 167, 223, 133, 229, 223, 63, 21, 210, 86, 63, 21, 111, 63, - 21, 105, 63, 21, 158, 63, 21, 161, 63, 21, 190, 63, 21, 195, 63, 21, 199, - 63, 21, 196, 63, 21, 201, 63, 21, 163, 111, 63, 21, 163, 105, 63, 21, - 163, 158, 63, 21, 163, 161, 63, 21, 163, 190, 63, 21, 163, 195, 63, 21, - 163, 199, 63, 21, 163, 196, 63, 21, 163, 201, 63, 21, 163, 210, 86, 63, - 164, 251, 138, 222, 145, 63, 164, 229, 73, 251, 76, 227, 153, 210, 25, - 63, 164, 250, 247, 255, 172, 222, 146, 251, 77, 230, 207, 251, 15, 63, - 164, 229, 73, 251, 76, 220, 108, 222, 145, 63, 164, 250, 140, 230, 252, - 63, 164, 215, 185, 255, 169, 63, 164, 242, 107, 222, 146, 242, 70, 63, - 164, 242, 107, 222, 146, 242, 76, 63, 164, 254, 124, 234, 129, 242, 70, - 63, 164, 254, 124, 234, 129, 242, 76, 63, 5, 211, 65, 215, 172, 63, 5, - 231, 172, 215, 172, 63, 1, 176, 63, 1, 234, 138, 63, 1, 243, 142, 63, 1, - 243, 0, 63, 1, 229, 82, 63, 1, 251, 41, 63, 1, 250, 165, 63, 1, 235, 147, - 63, 1, 227, 169, 63, 1, 215, 157, 63, 1, 215, 145, 63, 1, 248, 143, 63, - 1, 248, 127, 63, 1, 228, 115, 63, 1, 217, 106, 63, 1, 216, 209, 63, 1, - 248, 229, 63, 1, 248, 33, 63, 1, 198, 63, 1, 191, 63, 1, 225, 150, 63, 1, - 252, 199, 63, 1, 252, 26, 63, 1, 186, 63, 1, 215, 184, 63, 1, 215, 176, - 63, 1, 246, 46, 63, 1, 246, 41, 63, 1, 212, 65, 63, 1, 210, 82, 63, 1, - 210, 116, 63, 1, 255, 175, 63, 1, 192, 63, 1, 205, 63, 1, 233, 141, 63, - 1, 220, 104, 63, 1, 218, 225, 63, 1, 206, 63, 1, 162, 63, 1, 61, 63, 1, - 233, 237, 63, 1, 244, 85, 205, 63, 1, 234, 52, 63, 1, 222, 181, 63, 25, - 5, 255, 82, 63, 25, 5, 74, 63, 25, 5, 236, 40, 63, 25, 5, 69, 63, 25, 5, - 214, 118, 63, 25, 5, 149, 153, 63, 25, 5, 149, 222, 182, 63, 25, 5, 149, - 156, 63, 25, 5, 149, 232, 191, 63, 25, 5, 76, 63, 25, 5, 245, 217, 63, - 25, 5, 78, 63, 25, 5, 226, 187, 63, 5, 222, 224, 218, 85, 229, 83, 222, - 213, 63, 5, 222, 218, 252, 84, 63, 25, 5, 223, 52, 74, 63, 25, 5, 223, - 52, 236, 40, 63, 5, 227, 153, 210, 26, 229, 231, 248, 229, 63, 5, 219, - 73, 233, 66, 63, 164, 242, 36, 63, 164, 226, 61, 63, 5, 233, 69, 222, - 145, 63, 5, 211, 70, 222, 145, 63, 5, 233, 70, 215, 185, 251, 15, 63, 5, - 231, 100, 251, 15, 63, 5, 242, 126, 251, 16, 223, 43, 63, 5, 242, 126, - 231, 90, 223, 43, 63, 5, 235, 200, 231, 100, 251, 15, 63, 218, 74, 5, - 233, 70, 215, 185, 251, 15, 63, 218, 74, 5, 231, 100, 251, 15, 63, 218, - 74, 5, 235, 200, 231, 100, 251, 15, 63, 218, 74, 1, 176, 63, 218, 74, 1, - 234, 138, 63, 218, 74, 1, 243, 142, 63, 218, 74, 1, 243, 0, 63, 218, 74, - 1, 229, 82, 63, 218, 74, 1, 251, 41, 63, 218, 74, 1, 250, 165, 63, 218, - 74, 1, 235, 147, 63, 218, 74, 1, 227, 169, 63, 218, 74, 1, 215, 157, 63, - 218, 74, 1, 215, 145, 63, 218, 74, 1, 248, 143, 63, 218, 74, 1, 248, 127, - 63, 218, 74, 1, 228, 115, 63, 218, 74, 1, 217, 106, 63, 218, 74, 1, 216, - 209, 63, 218, 74, 1, 248, 229, 63, 218, 74, 1, 248, 33, 63, 218, 74, 1, - 198, 63, 218, 74, 1, 191, 63, 218, 74, 1, 225, 150, 63, 218, 74, 1, 252, - 199, 63, 218, 74, 1, 252, 26, 63, 218, 74, 1, 186, 63, 218, 74, 1, 215, - 184, 63, 218, 74, 1, 215, 176, 63, 218, 74, 1, 246, 46, 63, 218, 74, 1, - 246, 41, 63, 218, 74, 1, 212, 65, 63, 218, 74, 1, 210, 82, 63, 218, 74, - 1, 210, 116, 63, 218, 74, 1, 255, 175, 63, 218, 74, 1, 192, 63, 218, 74, - 1, 205, 63, 218, 74, 1, 233, 141, 63, 218, 74, 1, 220, 104, 63, 218, 74, - 1, 218, 225, 63, 218, 74, 1, 206, 63, 218, 74, 1, 162, 63, 218, 74, 1, - 61, 63, 218, 74, 1, 233, 237, 63, 218, 74, 1, 244, 85, 212, 65, 63, 218, - 74, 1, 244, 85, 192, 63, 218, 74, 1, 244, 85, 205, 63, 233, 224, 222, - 143, 234, 138, 63, 233, 224, 222, 143, 234, 139, 251, 77, 230, 207, 251, - 15, 63, 251, 4, 5, 114, 252, 78, 63, 251, 4, 5, 193, 252, 78, 63, 251, 4, - 5, 251, 5, 217, 21, 63, 251, 4, 5, 221, 209, 255, 174, 63, 16, 246, 99, - 251, 133, 63, 16, 223, 132, 222, 225, 63, 16, 226, 81, 243, 70, 63, 16, - 223, 132, 222, 226, 223, 45, 242, 152, 63, 16, 225, 115, 191, 63, 16, - 228, 64, 251, 133, 63, 16, 228, 64, 251, 134, 227, 143, 255, 171, 63, 16, - 228, 64, 251, 134, 242, 124, 255, 171, 63, 16, 228, 64, 251, 134, 251, - 77, 255, 171, 63, 5, 223, 133, 229, 224, 223, 133, 247, 166, 63, 5, 223, - 133, 229, 224, 242, 123, 63, 164, 251, 137, 220, 5, 242, 222, 230, 253, - 223, 44, 63, 164, 230, 168, 211, 0, 242, 222, 230, 253, 223, 44, 63, 164, - 227, 143, 215, 173, 63, 164, 65, 251, 160, 222, 215, 211, 0, 230, 253, - 231, 98, 186, 63, 164, 250, 4, 251, 160, 222, 215, 211, 0, 230, 253, 220, - 111, 186, 222, 253, 218, 0, 50, 233, 51, 218, 0, 50, 222, 253, 218, 0, 5, - 2, 247, 126, 233, 51, 218, 0, 5, 2, 247, 126, 63, 164, 233, 61, 231, 101, - 222, 145, 63, 164, 215, 251, 231, 101, 222, 145, 68, 1, 176, 68, 1, 234, - 138, 68, 1, 243, 142, 68, 1, 243, 0, 68, 1, 229, 82, 68, 1, 251, 41, 68, - 1, 250, 165, 68, 1, 235, 147, 68, 1, 235, 120, 68, 1, 227, 169, 68, 1, - 228, 81, 68, 1, 215, 157, 68, 1, 215, 145, 68, 1, 248, 143, 68, 1, 248, - 127, 68, 1, 228, 115, 68, 1, 217, 106, 68, 1, 216, 209, 68, 1, 248, 229, - 68, 1, 248, 33, 68, 1, 198, 68, 1, 191, 68, 1, 225, 150, 68, 1, 252, 199, - 68, 1, 252, 26, 68, 1, 186, 68, 1, 192, 68, 1, 205, 68, 1, 233, 141, 68, - 1, 212, 65, 68, 1, 206, 68, 1, 162, 68, 1, 232, 190, 68, 1, 61, 68, 1, - 220, 88, 61, 68, 1, 74, 68, 1, 236, 40, 68, 1, 69, 68, 1, 214, 118, 68, - 1, 76, 68, 1, 230, 156, 76, 68, 1, 78, 68, 1, 253, 200, 68, 25, 5, 217, - 65, 255, 82, 68, 25, 5, 255, 82, 68, 25, 5, 74, 68, 25, 5, 236, 40, 68, - 25, 5, 69, 68, 25, 5, 214, 118, 68, 25, 5, 76, 68, 25, 5, 254, 210, 68, - 25, 5, 230, 156, 236, 40, 68, 25, 5, 230, 156, 78, 68, 25, 5, 160, 48, - 68, 5, 254, 83, 68, 5, 59, 51, 68, 5, 213, 147, 68, 5, 213, 152, 68, 5, - 253, 243, 68, 117, 5, 147, 192, 68, 117, 5, 147, 205, 68, 117, 5, 147, - 212, 65, 68, 117, 5, 147, 162, 68, 1, 242, 139, 206, 68, 21, 210, 86, 68, - 21, 111, 68, 21, 105, 68, 21, 158, 68, 21, 161, 68, 21, 190, 68, 21, 195, - 68, 21, 199, 68, 21, 196, 68, 21, 201, 68, 5, 232, 198, 221, 174, 68, 5, - 221, 174, 68, 16, 232, 159, 68, 16, 249, 221, 68, 16, 254, 229, 68, 16, - 243, 55, 68, 1, 220, 104, 68, 1, 218, 225, 68, 1, 149, 153, 68, 1, 149, - 222, 182, 68, 1, 149, 156, 68, 1, 149, 232, 191, 68, 25, 5, 149, 153, 68, - 25, 5, 149, 222, 182, 68, 25, 5, 149, 156, 68, 25, 5, 149, 232, 191, 68, - 1, 230, 156, 229, 82, 68, 1, 230, 156, 235, 120, 68, 1, 230, 156, 252, - 119, 68, 1, 230, 156, 252, 114, 68, 117, 5, 230, 156, 147, 198, 68, 117, - 5, 230, 156, 147, 186, 68, 117, 5, 230, 156, 147, 233, 141, 68, 1, 220, - 110, 234, 219, 220, 104, 68, 25, 5, 220, 110, 234, 219, 245, 63, 68, 138, - 164, 220, 110, 234, 219, 241, 254, 68, 138, 164, 220, 110, 234, 219, 234, - 189, 225, 124, 68, 1, 212, 7, 224, 111, 234, 219, 216, 209, 68, 1, 212, - 7, 224, 111, 234, 219, 224, 117, 68, 25, 5, 212, 7, 224, 111, 234, 219, - 245, 63, 68, 25, 5, 212, 7, 224, 111, 234, 219, 214, 214, 68, 5, 212, 7, - 224, 111, 234, 219, 216, 30, 68, 5, 212, 7, 224, 111, 234, 219, 216, 29, - 68, 5, 212, 7, 224, 111, 234, 219, 216, 28, 68, 5, 212, 7, 224, 111, 234, - 219, 216, 27, 68, 5, 212, 7, 224, 111, 234, 219, 216, 26, 68, 1, 245, - 227, 224, 111, 234, 219, 228, 115, 68, 1, 245, 227, 224, 111, 234, 219, - 210, 176, 68, 1, 245, 227, 224, 111, 234, 219, 242, 224, 68, 25, 5, 243, - 66, 234, 219, 74, 68, 25, 5, 234, 194, 226, 238, 68, 25, 5, 234, 194, 69, - 68, 25, 5, 234, 194, 245, 217, 68, 1, 220, 88, 176, 68, 1, 220, 88, 234, - 138, 68, 1, 220, 88, 243, 142, 68, 1, 220, 88, 251, 41, 68, 1, 220, 88, - 210, 116, 68, 1, 220, 88, 227, 169, 68, 1, 220, 88, 248, 229, 68, 1, 220, - 88, 198, 68, 1, 220, 88, 225, 150, 68, 1, 220, 88, 244, 204, 68, 1, 220, - 88, 252, 199, 68, 1, 220, 88, 216, 209, 68, 1, 220, 88, 162, 68, 117, 5, - 220, 88, 147, 212, 65, 68, 25, 5, 220, 88, 255, 82, 68, 25, 5, 220, 88, - 76, 68, 25, 5, 220, 88, 160, 48, 68, 25, 5, 220, 88, 40, 211, 117, 68, 5, - 220, 88, 216, 29, 68, 5, 220, 88, 216, 28, 68, 5, 220, 88, 216, 26, 68, - 5, 220, 88, 216, 25, 68, 5, 220, 88, 249, 160, 216, 29, 68, 5, 220, 88, - 249, 160, 216, 28, 68, 5, 220, 88, 249, 160, 245, 161, 216, 31, 68, 1, - 222, 130, 226, 67, 244, 204, 68, 5, 222, 130, 226, 67, 216, 26, 68, 220, - 88, 21, 210, 86, 68, 220, 88, 21, 111, 68, 220, 88, 21, 105, 68, 220, 88, - 21, 158, 68, 220, 88, 21, 161, 68, 220, 88, 21, 190, 68, 220, 88, 21, - 195, 68, 220, 88, 21, 199, 68, 220, 88, 21, 196, 68, 220, 88, 21, 201, - 68, 5, 234, 132, 216, 30, 68, 5, 234, 132, 216, 28, 68, 25, 5, 254, 199, - 61, 68, 25, 5, 254, 199, 254, 210, 68, 16, 220, 88, 111, 68, 16, 220, 88, - 245, 38, 98, 6, 1, 254, 131, 98, 6, 1, 252, 160, 98, 6, 1, 243, 113, 98, - 6, 1, 247, 136, 98, 6, 1, 245, 158, 98, 6, 1, 213, 160, 98, 6, 1, 210, - 89, 98, 6, 1, 217, 61, 98, 6, 1, 236, 6, 98, 6, 1, 234, 240, 98, 6, 1, - 233, 87, 98, 6, 1, 231, 190, 98, 6, 1, 229, 200, 98, 6, 1, 226, 200, 98, - 6, 1, 226, 21, 98, 6, 1, 210, 78, 98, 6, 1, 223, 174, 98, 6, 1, 221, 245, - 98, 6, 1, 217, 51, 98, 6, 1, 214, 190, 98, 6, 1, 225, 143, 98, 6, 1, 234, - 127, 98, 6, 1, 242, 248, 98, 6, 1, 224, 76, 98, 6, 1, 220, 22, 98, 6, 1, - 250, 105, 98, 6, 1, 251, 15, 98, 6, 1, 235, 106, 98, 6, 1, 250, 48, 98, - 6, 1, 250, 151, 98, 6, 1, 211, 163, 98, 6, 1, 235, 117, 98, 6, 1, 242, - 50, 98, 6, 1, 241, 245, 98, 6, 1, 241, 182, 98, 6, 1, 212, 22, 98, 6, 1, - 242, 11, 98, 6, 1, 241, 72, 98, 6, 1, 210, 246, 98, 6, 1, 254, 241, 98, - 1, 254, 131, 98, 1, 252, 160, 98, 1, 243, 113, 98, 1, 247, 136, 98, 1, - 245, 158, 98, 1, 213, 160, 98, 1, 210, 89, 98, 1, 217, 61, 98, 1, 236, 6, - 98, 1, 234, 240, 98, 1, 233, 87, 98, 1, 231, 190, 98, 1, 229, 200, 98, 1, - 226, 200, 98, 1, 226, 21, 98, 1, 210, 78, 98, 1, 223, 174, 98, 1, 221, - 245, 98, 1, 217, 51, 98, 1, 214, 190, 98, 1, 225, 143, 98, 1, 234, 127, - 98, 1, 242, 248, 98, 1, 224, 76, 98, 1, 220, 22, 98, 1, 250, 105, 98, 1, - 251, 15, 98, 1, 235, 106, 98, 1, 250, 48, 98, 1, 250, 151, 98, 1, 211, - 163, 98, 1, 235, 117, 98, 1, 242, 50, 98, 1, 241, 245, 98, 1, 241, 182, - 98, 1, 212, 22, 98, 1, 242, 11, 98, 1, 241, 72, 98, 1, 244, 129, 98, 1, - 210, 246, 98, 1, 245, 173, 98, 1, 215, 94, 243, 113, 98, 1, 254, 205, 98, - 226, 19, 220, 139, 58, 1, 98, 229, 200, 98, 1, 254, 241, 98, 1, 242, 10, - 50, 98, 1, 233, 133, 50, 24, 100, 234, 64, 24, 100, 218, 217, 24, 100, - 228, 231, 24, 100, 216, 102, 24, 100, 218, 206, 24, 100, 223, 29, 24, - 100, 230, 222, 24, 100, 225, 98, 24, 100, 218, 214, 24, 100, 219, 150, - 24, 100, 218, 211, 24, 100, 236, 63, 24, 100, 250, 54, 24, 100, 218, 221, - 24, 100, 250, 114, 24, 100, 234, 116, 24, 100, 216, 174, 24, 100, 225, - 134, 24, 100, 241, 179, 24, 100, 228, 227, 24, 100, 218, 215, 24, 100, - 228, 221, 24, 100, 228, 225, 24, 100, 216, 99, 24, 100, 223, 17, 24, 100, - 218, 213, 24, 100, 223, 27, 24, 100, 234, 224, 24, 100, 230, 215, 24, - 100, 234, 227, 24, 100, 225, 93, 24, 100, 225, 91, 24, 100, 225, 79, 24, - 100, 225, 87, 24, 100, 225, 85, 24, 100, 225, 82, 24, 100, 225, 84, 24, - 100, 225, 81, 24, 100, 225, 86, 24, 100, 225, 96, 24, 100, 225, 97, 24, - 100, 225, 80, 24, 100, 225, 90, 24, 100, 234, 225, 24, 100, 234, 223, 24, - 100, 219, 143, 24, 100, 219, 141, 24, 100, 219, 133, 24, 100, 219, 136, - 24, 100, 219, 142, 24, 100, 219, 138, 24, 100, 219, 137, 24, 100, 219, - 135, 24, 100, 219, 146, 24, 100, 219, 148, 24, 100, 219, 149, 24, 100, - 219, 144, 24, 100, 219, 134, 24, 100, 219, 139, 24, 100, 219, 147, 24, - 100, 250, 98, 24, 100, 250, 96, 24, 100, 250, 176, 24, 100, 250, 174, 24, - 100, 226, 36, 24, 100, 236, 58, 24, 100, 236, 49, 24, 100, 236, 57, 24, - 100, 236, 54, 24, 100, 236, 52, 24, 100, 236, 56, 24, 100, 218, 218, 24, - 100, 236, 61, 24, 100, 236, 62, 24, 100, 236, 50, 24, 100, 236, 55, 24, - 100, 211, 26, 24, 100, 250, 53, 24, 100, 250, 99, 24, 100, 250, 97, 24, - 100, 250, 177, 24, 100, 250, 175, 24, 100, 250, 112, 24, 100, 250, 113, - 24, 100, 250, 100, 24, 100, 250, 178, 24, 100, 225, 132, 24, 100, 234, - 226, 24, 100, 218, 219, 24, 100, 211, 32, 24, 100, 234, 55, 24, 100, 228, - 223, 24, 100, 228, 229, 24, 100, 228, 228, 24, 100, 216, 96, 24, 100, - 244, 111, 24, 143, 244, 111, 24, 143, 61, 24, 143, 254, 252, 24, 143, - 192, 24, 143, 211, 92, 24, 143, 245, 125, 24, 143, 76, 24, 143, 211, 36, - 24, 143, 211, 47, 24, 143, 78, 24, 143, 212, 65, 24, 143, 212, 62, 24, - 143, 226, 238, 24, 143, 210, 244, 24, 143, 69, 24, 143, 212, 11, 24, 143, - 212, 22, 24, 143, 211, 250, 24, 143, 210, 212, 24, 143, 245, 63, 24, 143, - 211, 8, 24, 143, 74, 24, 143, 255, 166, 24, 143, 255, 165, 24, 143, 211, - 106, 24, 143, 211, 104, 24, 143, 245, 123, 24, 143, 245, 122, 24, 143, - 245, 124, 24, 143, 211, 35, 24, 143, 211, 34, 24, 143, 227, 88, 24, 143, - 227, 89, 24, 143, 227, 82, 24, 143, 227, 87, 24, 143, 227, 85, 24, 143, - 210, 238, 24, 143, 210, 237, 24, 143, 210, 236, 24, 143, 210, 239, 24, - 143, 210, 240, 24, 143, 215, 30, 24, 143, 215, 29, 24, 143, 215, 27, 24, - 143, 215, 24, 24, 143, 215, 25, 24, 143, 210, 211, 24, 143, 210, 208, 24, - 143, 210, 209, 24, 143, 210, 203, 24, 143, 210, 204, 24, 143, 210, 205, - 24, 143, 210, 207, 24, 143, 245, 57, 24, 143, 245, 59, 24, 143, 211, 7, - 24, 143, 240, 160, 24, 143, 240, 152, 24, 143, 240, 155, 24, 143, 240, - 153, 24, 143, 240, 157, 24, 143, 240, 159, 24, 143, 254, 42, 24, 143, - 254, 39, 24, 143, 254, 37, 24, 143, 254, 38, 24, 143, 218, 222, 24, 143, - 255, 167, 24, 143, 211, 105, 24, 143, 211, 33, 24, 143, 227, 84, 24, 143, - 227, 83, 24, 90, 234, 64, 24, 90, 218, 217, 24, 90, 234, 57, 24, 90, 228, - 231, 24, 90, 228, 229, 24, 90, 228, 228, 24, 90, 216, 102, 24, 90, 223, - 29, 24, 90, 223, 24, 24, 90, 223, 21, 24, 90, 223, 14, 24, 90, 223, 9, - 24, 90, 223, 4, 24, 90, 223, 15, 24, 90, 223, 27, 24, 90, 230, 222, 24, - 90, 225, 98, 24, 90, 225, 87, 24, 90, 219, 150, 24, 90, 218, 211, 24, 90, - 236, 63, 24, 90, 250, 54, 24, 90, 250, 114, 24, 90, 234, 116, 24, 90, - 216, 174, 24, 90, 225, 134, 24, 90, 241, 179, 24, 90, 234, 58, 24, 90, - 234, 56, 24, 90, 228, 227, 24, 90, 228, 221, 24, 90, 228, 223, 24, 90, - 228, 226, 24, 90, 228, 222, 24, 90, 216, 99, 24, 90, 216, 96, 24, 90, - 223, 22, 24, 90, 223, 17, 24, 90, 223, 3, 24, 90, 223, 2, 24, 90, 218, - 213, 24, 90, 223, 19, 24, 90, 223, 18, 24, 90, 223, 11, 24, 90, 223, 13, - 24, 90, 223, 26, 24, 90, 223, 6, 24, 90, 223, 16, 24, 90, 223, 25, 24, - 90, 223, 1, 24, 90, 230, 218, 24, 90, 230, 213, 24, 90, 230, 215, 24, 90, - 230, 212, 24, 90, 230, 210, 24, 90, 230, 216, 24, 90, 230, 221, 24, 90, - 230, 219, 24, 90, 234, 227, 24, 90, 225, 89, 24, 90, 225, 90, 24, 90, - 225, 95, 24, 90, 234, 225, 24, 90, 219, 143, 24, 90, 219, 133, 24, 90, - 219, 136, 24, 90, 219, 138, 24, 90, 226, 36, 24, 90, 236, 58, 24, 90, - 236, 51, 24, 90, 218, 218, 24, 90, 236, 59, 24, 90, 211, 26, 24, 90, 211, - 22, 24, 90, 211, 23, 24, 90, 225, 132, 24, 90, 234, 226, 24, 90, 241, - 177, 24, 90, 241, 175, 24, 90, 241, 178, 24, 90, 241, 176, 24, 90, 211, - 32, 24, 90, 234, 60, 24, 90, 234, 59, 24, 90, 234, 63, 24, 90, 234, 61, - 24, 90, 234, 62, 24, 90, 218, 215, 29, 3, 162, 29, 3, 240, 229, 29, 3, - 241, 187, 29, 3, 242, 53, 29, 3, 241, 227, 29, 3, 241, 245, 29, 3, 241, - 75, 29, 3, 241, 74, 29, 3, 233, 141, 29, 3, 232, 103, 29, 3, 232, 247, - 29, 3, 233, 140, 29, 3, 233, 56, 29, 3, 233, 64, 29, 3, 232, 162, 29, 3, - 232, 75, 29, 3, 241, 196, 29, 3, 241, 190, 29, 3, 241, 192, 29, 3, 241, - 195, 29, 3, 241, 193, 29, 3, 241, 194, 29, 3, 241, 191, 29, 3, 241, 189, - 29, 3, 186, 29, 3, 230, 107, 29, 3, 230, 235, 29, 3, 231, 242, 29, 3, - 231, 85, 29, 3, 231, 96, 29, 3, 230, 166, 29, 3, 230, 47, 29, 3, 217, - 164, 29, 3, 217, 158, 29, 3, 217, 160, 29, 3, 217, 163, 29, 3, 217, 161, - 29, 3, 217, 162, 29, 3, 217, 159, 29, 3, 217, 157, 29, 3, 205, 29, 3, - 222, 142, 29, 3, 223, 38, 29, 3, 223, 187, 29, 3, 223, 111, 29, 3, 223, - 131, 29, 3, 222, 213, 29, 3, 222, 111, 29, 3, 206, 29, 3, 218, 84, 29, 3, - 219, 193, 29, 3, 222, 33, 29, 3, 221, 172, 29, 3, 221, 183, 29, 3, 219, - 60, 29, 3, 217, 254, 29, 3, 220, 104, 29, 3, 219, 227, 29, 3, 220, 34, - 29, 3, 220, 100, 29, 3, 220, 63, 29, 3, 220, 65, 29, 3, 220, 9, 29, 3, - 219, 210, 29, 3, 224, 91, 29, 3, 224, 33, 29, 3, 224, 56, 29, 3, 224, 90, - 29, 3, 224, 71, 29, 3, 224, 72, 29, 3, 224, 45, 29, 3, 224, 44, 29, 3, - 223, 245, 29, 3, 223, 241, 29, 3, 223, 244, 29, 3, 223, 242, 29, 3, 223, - 243, 29, 3, 224, 68, 29, 3, 224, 62, 29, 3, 224, 64, 29, 3, 224, 67, 29, - 3, 224, 65, 29, 3, 224, 66, 29, 3, 224, 63, 29, 3, 224, 61, 29, 3, 224, - 57, 29, 3, 224, 60, 29, 3, 224, 58, 29, 3, 224, 59, 29, 3, 252, 199, 29, - 3, 251, 133, 29, 3, 252, 14, 29, 3, 252, 197, 29, 3, 252, 74, 29, 3, 252, - 83, 29, 3, 251, 213, 29, 3, 251, 91, 29, 3, 214, 27, 29, 3, 212, 116, 29, - 3, 213, 176, 29, 3, 214, 26, 29, 3, 213, 250, 29, 3, 213, 255, 29, 3, - 213, 138, 29, 3, 212, 107, 29, 3, 217, 106, 29, 3, 215, 119, 29, 3, 216, - 118, 29, 3, 217, 102, 29, 3, 217, 12, 29, 3, 217, 23, 29, 3, 112, 29, 3, - 215, 80, 29, 3, 251, 41, 29, 3, 249, 120, 29, 3, 250, 59, 29, 3, 251, 40, - 29, 3, 250, 190, 29, 3, 250, 198, 29, 3, 249, 246, 29, 3, 249, 89, 29, 3, - 211, 165, 29, 3, 211, 141, 29, 3, 211, 157, 29, 3, 211, 164, 29, 3, 211, - 161, 29, 3, 211, 162, 29, 3, 211, 148, 29, 3, 211, 147, 29, 3, 211, 136, - 29, 3, 211, 132, 29, 3, 211, 135, 29, 3, 211, 133, 29, 3, 211, 134, 29, - 3, 198, 29, 3, 227, 242, 29, 3, 228, 238, 29, 3, 229, 230, 29, 3, 229, - 108, 29, 3, 229, 112, 29, 3, 228, 79, 29, 3, 227, 178, 29, 3, 227, 169, - 29, 3, 227, 132, 29, 3, 227, 152, 29, 3, 227, 168, 29, 3, 227, 159, 29, - 3, 227, 160, 29, 3, 227, 138, 29, 3, 227, 123, 29, 3, 242, 187, 61, 29, - 3, 242, 187, 69, 29, 3, 242, 187, 74, 29, 3, 242, 187, 255, 82, 29, 3, - 242, 187, 245, 217, 29, 3, 242, 187, 76, 29, 3, 242, 187, 78, 29, 3, 242, - 187, 212, 65, 29, 3, 176, 29, 3, 233, 223, 29, 3, 234, 98, 29, 3, 235, - 16, 29, 3, 234, 187, 29, 3, 234, 188, 29, 3, 234, 34, 29, 3, 234, 33, 29, - 3, 233, 188, 29, 3, 233, 182, 29, 3, 233, 187, 29, 3, 233, 183, 29, 3, - 233, 184, 29, 3, 233, 177, 29, 3, 233, 171, 29, 3, 233, 173, 29, 3, 233, - 176, 29, 3, 233, 174, 29, 3, 233, 175, 29, 3, 233, 172, 29, 3, 233, 170, - 29, 3, 233, 166, 29, 3, 233, 169, 29, 3, 233, 167, 29, 3, 233, 168, 29, - 3, 212, 65, 29, 3, 211, 195, 29, 3, 211, 250, 29, 3, 212, 64, 29, 3, 212, - 17, 29, 3, 212, 22, 29, 3, 211, 227, 29, 3, 211, 226, 29, 3, 225, 142, - 61, 29, 3, 225, 142, 69, 29, 3, 225, 142, 74, 29, 3, 225, 142, 255, 82, - 29, 3, 225, 142, 245, 217, 29, 3, 225, 142, 76, 29, 3, 225, 142, 78, 29, - 3, 210, 116, 29, 3, 210, 13, 29, 3, 210, 44, 29, 3, 210, 115, 29, 3, 210, - 92, 29, 3, 210, 94, 29, 3, 210, 23, 29, 3, 210, 0, 29, 3, 210, 82, 29, 3, - 210, 62, 29, 3, 210, 69, 29, 3, 210, 81, 29, 3, 210, 73, 29, 3, 210, 74, - 29, 3, 210, 67, 29, 3, 210, 53, 29, 3, 192, 29, 3, 210, 212, 29, 3, 211, - 8, 29, 3, 211, 103, 29, 3, 211, 44, 29, 3, 211, 47, 29, 3, 210, 244, 29, - 3, 210, 235, 29, 3, 248, 229, 29, 3, 246, 86, 29, 3, 248, 11, 29, 3, 248, - 228, 29, 3, 248, 85, 29, 3, 248, 98, 29, 3, 247, 153, 29, 3, 246, 55, 29, - 3, 248, 143, 29, 3, 248, 108, 29, 3, 248, 120, 29, 3, 248, 142, 29, 3, - 248, 130, 29, 3, 248, 131, 29, 3, 248, 113, 29, 3, 248, 99, 29, 3, 235, - 147, 29, 3, 235, 57, 29, 3, 235, 114, 29, 3, 235, 146, 29, 3, 235, 130, - 29, 3, 235, 132, 29, 3, 235, 74, 29, 3, 235, 37, 29, 3, 243, 142, 29, 3, - 242, 120, 29, 3, 242, 221, 29, 3, 243, 139, 29, 3, 243, 62, 29, 3, 243, - 69, 29, 3, 242, 181, 29, 3, 242, 180, 29, 3, 242, 85, 29, 3, 242, 81, 29, - 3, 242, 84, 29, 3, 242, 82, 29, 3, 242, 83, 29, 3, 243, 36, 29, 3, 243, - 16, 29, 3, 243, 26, 29, 3, 243, 35, 29, 3, 243, 30, 29, 3, 243, 31, 29, - 3, 243, 20, 29, 3, 243, 5, 29, 3, 216, 209, 29, 3, 216, 137, 29, 3, 216, - 176, 29, 3, 216, 208, 29, 3, 216, 195, 29, 3, 216, 196, 29, 3, 216, 157, - 29, 3, 216, 129, 29, 3, 250, 165, 29, 3, 250, 77, 29, 3, 250, 118, 29, 3, - 250, 164, 29, 3, 250, 136, 29, 3, 250, 139, 29, 3, 250, 94, 29, 3, 250, - 66, 29, 3, 225, 150, 29, 3, 225, 117, 29, 3, 225, 136, 29, 3, 225, 149, - 29, 3, 225, 138, 29, 3, 225, 139, 29, 3, 225, 124, 29, 3, 225, 113, 29, - 3, 215, 184, 29, 3, 215, 164, 29, 3, 215, 168, 29, 3, 215, 183, 29, 3, - 215, 178, 29, 3, 215, 179, 29, 3, 215, 167, 29, 3, 215, 162, 29, 3, 215, - 39, 29, 3, 215, 31, 29, 3, 215, 35, 29, 3, 215, 38, 29, 3, 215, 36, 29, - 3, 215, 37, 29, 3, 215, 33, 29, 3, 215, 32, 29, 3, 244, 204, 29, 3, 243, - 241, 29, 3, 244, 129, 29, 3, 244, 203, 29, 3, 244, 155, 29, 3, 244, 162, - 29, 3, 244, 51, 29, 3, 243, 220, 29, 3, 191, 29, 3, 224, 153, 29, 3, 225, - 111, 29, 3, 226, 93, 29, 3, 225, 214, 29, 3, 225, 224, 29, 3, 225, 19, - 29, 3, 224, 117, 29, 3, 222, 101, 29, 3, 230, 36, 29, 3, 243, 214, 29, - 38, 243, 60, 22, 25, 233, 29, 79, 29, 38, 25, 233, 29, 79, 29, 38, 243, - 60, 79, 29, 221, 175, 79, 29, 211, 208, 29, 243, 236, 218, 131, 29, 249, - 227, 29, 220, 152, 29, 249, 234, 29, 224, 202, 249, 234, 29, 224, 16, 79, - 29, 226, 19, 220, 139, 29, 21, 111, 29, 21, 105, 29, 21, 158, 29, 21, - 161, 29, 21, 190, 29, 21, 195, 29, 21, 199, 29, 21, 196, 29, 21, 201, 29, - 54, 216, 248, 29, 54, 215, 73, 29, 54, 216, 163, 29, 54, 244, 23, 29, 54, - 244, 122, 29, 54, 219, 113, 29, 54, 220, 118, 29, 54, 245, 192, 29, 54, - 228, 200, 29, 54, 240, 217, 29, 54, 216, 249, 216, 148, 29, 3, 221, 179, - 230, 47, 29, 3, 230, 43, 29, 3, 230, 44, 29, 3, 230, 45, 29, 3, 221, 179, - 251, 91, 29, 3, 251, 88, 29, 3, 251, 89, 29, 3, 251, 90, 29, 3, 221, 179, - 243, 220, 29, 3, 243, 216, 29, 3, 243, 217, 29, 3, 243, 218, 29, 3, 221, - 179, 224, 117, 29, 3, 224, 113, 29, 3, 224, 114, 29, 3, 224, 115, 29, - 216, 32, 164, 210, 247, 29, 216, 32, 164, 248, 49, 29, 216, 32, 164, 222, - 241, 29, 216, 32, 164, 219, 253, 222, 241, 29, 216, 32, 164, 247, 243, - 29, 216, 32, 164, 234, 170, 29, 216, 32, 164, 250, 102, 29, 216, 32, 164, - 241, 184, 29, 216, 32, 164, 248, 48, 29, 216, 32, 164, 233, 200, 169, 1, - 61, 169, 1, 76, 169, 1, 74, 169, 1, 78, 169, 1, 69, 169, 1, 214, 105, - 169, 1, 243, 142, 169, 1, 176, 169, 1, 243, 69, 169, 1, 242, 221, 169, 1, - 242, 181, 169, 1, 242, 120, 169, 1, 242, 86, 169, 1, 162, 169, 1, 241, - 245, 169, 1, 241, 187, 169, 1, 241, 75, 169, 1, 240, 229, 169, 1, 240, - 208, 169, 1, 233, 141, 169, 1, 233, 64, 169, 1, 232, 247, 169, 1, 232, - 162, 169, 1, 232, 103, 169, 1, 232, 76, 169, 1, 186, 169, 1, 231, 96, - 169, 1, 230, 235, 169, 1, 230, 166, 169, 1, 230, 107, 169, 1, 198, 169, - 1, 241, 97, 169, 1, 229, 218, 169, 1, 229, 112, 169, 1, 228, 238, 169, 1, - 228, 79, 169, 1, 227, 242, 169, 1, 227, 180, 169, 1, 224, 32, 169, 1, - 224, 19, 169, 1, 224, 12, 169, 1, 224, 4, 169, 1, 223, 249, 169, 1, 223, - 247, 169, 1, 206, 169, 1, 222, 93, 169, 1, 221, 183, 169, 1, 219, 193, - 169, 1, 219, 60, 169, 1, 218, 84, 169, 1, 218, 3, 169, 1, 248, 229, 169, - 1, 217, 106, 169, 1, 248, 98, 169, 1, 217, 23, 169, 1, 248, 11, 169, 1, - 216, 118, 169, 1, 247, 153, 169, 1, 246, 86, 169, 1, 246, 58, 169, 1, - 247, 164, 169, 1, 216, 60, 169, 1, 216, 59, 169, 1, 216, 48, 169, 1, 216, - 47, 169, 1, 216, 46, 169, 1, 216, 45, 169, 1, 215, 184, 169, 1, 215, 179, - 169, 1, 215, 168, 169, 1, 215, 167, 169, 1, 215, 164, 169, 1, 215, 163, - 169, 1, 212, 65, 169, 1, 212, 22, 169, 1, 211, 250, 169, 1, 211, 227, - 169, 1, 211, 195, 169, 1, 211, 183, 169, 1, 192, 169, 1, 211, 47, 169, 1, - 211, 8, 169, 1, 210, 244, 169, 1, 210, 212, 169, 1, 210, 177, 18, 19, - 240, 175, 18, 19, 76, 18, 19, 255, 46, 18, 19, 74, 18, 19, 236, 40, 18, - 19, 78, 18, 19, 226, 187, 18, 19, 211, 116, 226, 187, 18, 19, 73, 245, - 217, 18, 19, 73, 74, 18, 19, 61, 18, 19, 255, 82, 18, 19, 212, 22, 18, - 19, 159, 212, 22, 18, 19, 211, 250, 18, 19, 159, 211, 250, 18, 19, 211, - 242, 18, 19, 159, 211, 242, 18, 19, 211, 227, 18, 19, 159, 211, 227, 18, - 19, 211, 215, 18, 19, 159, 211, 215, 18, 19, 229, 195, 211, 215, 18, 19, - 212, 65, 18, 19, 159, 212, 65, 18, 19, 212, 64, 18, 19, 159, 212, 64, 18, - 19, 229, 195, 212, 64, 18, 19, 254, 210, 18, 19, 211, 116, 212, 98, 18, - 19, 242, 187, 218, 131, 18, 19, 40, 142, 18, 19, 40, 242, 143, 18, 19, - 40, 251, 183, 163, 222, 236, 18, 19, 40, 216, 15, 163, 222, 236, 18, 19, - 40, 44, 163, 222, 236, 18, 19, 40, 222, 236, 18, 19, 40, 52, 142, 18, 19, - 40, 52, 219, 253, 67, 218, 92, 18, 19, 40, 230, 229, 247, 128, 18, 19, - 40, 219, 253, 203, 91, 18, 19, 40, 225, 25, 18, 19, 40, 124, 217, 88, 18, - 19, 245, 158, 18, 19, 236, 6, 18, 19, 226, 200, 18, 19, 254, 131, 18, 19, - 225, 224, 18, 19, 226, 91, 18, 19, 225, 111, 18, 19, 225, 74, 18, 19, - 225, 19, 18, 19, 224, 252, 18, 19, 211, 116, 224, 252, 18, 19, 73, 241, - 227, 18, 19, 73, 241, 187, 18, 19, 191, 18, 19, 226, 93, 18, 19, 224, - 115, 18, 19, 159, 224, 115, 18, 19, 224, 113, 18, 19, 159, 224, 113, 18, - 19, 224, 112, 18, 19, 159, 224, 112, 18, 19, 224, 110, 18, 19, 159, 224, - 110, 18, 19, 224, 109, 18, 19, 159, 224, 109, 18, 19, 224, 117, 18, 19, - 159, 224, 117, 18, 19, 224, 116, 18, 19, 159, 224, 116, 18, 19, 211, 116, - 224, 116, 18, 19, 226, 109, 18, 19, 159, 226, 109, 18, 19, 73, 242, 67, - 18, 19, 217, 23, 18, 19, 217, 100, 18, 19, 216, 118, 18, 19, 216, 104, - 18, 19, 112, 18, 19, 216, 18, 18, 19, 211, 116, 216, 18, 18, 19, 73, 248, - 85, 18, 19, 73, 248, 11, 18, 19, 217, 106, 18, 19, 217, 102, 18, 19, 215, - 78, 18, 19, 159, 215, 78, 18, 19, 215, 62, 18, 19, 159, 215, 62, 18, 19, - 215, 61, 18, 19, 159, 215, 61, 18, 19, 105, 18, 19, 159, 105, 18, 19, - 215, 54, 18, 19, 159, 215, 54, 18, 19, 215, 80, 18, 19, 159, 215, 80, 18, - 19, 215, 79, 18, 19, 159, 215, 79, 18, 19, 229, 195, 215, 79, 18, 19, - 217, 153, 18, 19, 215, 152, 18, 19, 215, 136, 18, 19, 215, 134, 18, 19, - 215, 157, 18, 19, 234, 188, 18, 19, 235, 13, 18, 19, 234, 98, 18, 19, - 234, 89, 18, 19, 234, 34, 18, 19, 234, 16, 18, 19, 211, 116, 234, 16, 18, - 19, 176, 18, 19, 235, 16, 18, 19, 233, 184, 18, 19, 159, 233, 184, 18, - 19, 233, 182, 18, 19, 159, 233, 182, 18, 19, 233, 181, 18, 19, 159, 233, - 181, 18, 19, 233, 180, 18, 19, 159, 233, 180, 18, 19, 233, 179, 18, 19, - 159, 233, 179, 18, 19, 233, 188, 18, 19, 159, 233, 188, 18, 19, 233, 187, - 18, 19, 159, 233, 187, 18, 19, 229, 195, 233, 187, 18, 19, 235, 29, 18, - 19, 233, 189, 18, 19, 219, 29, 234, 182, 18, 19, 219, 29, 234, 90, 18, - 19, 219, 29, 234, 29, 18, 19, 219, 29, 234, 254, 18, 19, 250, 198, 18, - 19, 251, 39, 18, 19, 250, 59, 18, 19, 250, 49, 18, 19, 249, 246, 18, 19, - 249, 182, 18, 19, 211, 116, 249, 182, 18, 19, 251, 41, 18, 19, 251, 40, - 18, 19, 249, 87, 18, 19, 159, 249, 87, 18, 19, 249, 85, 18, 19, 159, 249, - 85, 18, 19, 249, 84, 18, 19, 159, 249, 84, 18, 19, 249, 83, 18, 19, 159, - 249, 83, 18, 19, 249, 82, 18, 19, 159, 249, 82, 18, 19, 249, 89, 18, 19, - 159, 249, 89, 18, 19, 249, 88, 18, 19, 159, 249, 88, 18, 19, 229, 195, - 249, 88, 18, 19, 251, 74, 18, 19, 221, 211, 216, 211, 18, 19, 231, 96, - 18, 19, 231, 241, 18, 19, 230, 235, 18, 19, 230, 206, 18, 19, 230, 166, - 18, 19, 230, 137, 18, 19, 211, 116, 230, 137, 18, 19, 186, 18, 19, 231, - 242, 18, 19, 230, 45, 18, 19, 159, 230, 45, 18, 19, 230, 43, 18, 19, 159, - 230, 43, 18, 19, 230, 42, 18, 19, 159, 230, 42, 18, 19, 230, 41, 18, 19, - 159, 230, 41, 18, 19, 230, 40, 18, 19, 159, 230, 40, 18, 19, 230, 47, 18, - 19, 159, 230, 47, 18, 19, 230, 46, 18, 19, 159, 230, 46, 18, 19, 229, - 195, 230, 46, 18, 19, 194, 18, 19, 159, 194, 18, 19, 230, 239, 18, 19, - 253, 213, 194, 18, 19, 221, 211, 194, 18, 19, 229, 112, 18, 19, 229, 229, - 18, 19, 228, 238, 18, 19, 228, 213, 18, 19, 228, 79, 18, 19, 228, 69, 18, - 19, 211, 116, 228, 69, 18, 19, 198, 18, 19, 229, 230, 18, 19, 227, 176, - 18, 19, 159, 227, 176, 18, 19, 227, 178, 18, 19, 159, 227, 178, 18, 19, - 227, 177, 18, 19, 159, 227, 177, 18, 19, 229, 195, 227, 177, 18, 19, 230, - 30, 18, 19, 73, 229, 84, 18, 19, 228, 243, 18, 19, 233, 64, 18, 19, 233, - 139, 18, 19, 232, 247, 18, 19, 232, 233, 18, 19, 232, 162, 18, 19, 232, - 133, 18, 19, 211, 116, 232, 133, 18, 19, 233, 141, 18, 19, 233, 140, 18, - 19, 232, 73, 18, 19, 159, 232, 73, 18, 19, 232, 72, 18, 19, 159, 232, 72, - 18, 19, 232, 71, 18, 19, 159, 232, 71, 18, 19, 232, 70, 18, 19, 159, 232, - 70, 18, 19, 232, 69, 18, 19, 159, 232, 69, 18, 19, 232, 75, 18, 19, 159, - 232, 75, 18, 19, 232, 74, 18, 19, 159, 232, 74, 18, 19, 156, 18, 19, 159, - 156, 18, 19, 147, 156, 18, 19, 221, 183, 18, 19, 222, 31, 18, 19, 219, - 193, 18, 19, 219, 177, 18, 19, 219, 60, 18, 19, 219, 42, 18, 19, 211, - 116, 219, 42, 18, 19, 206, 18, 19, 222, 33, 18, 19, 217, 250, 18, 19, - 159, 217, 250, 18, 19, 217, 244, 18, 19, 159, 217, 244, 18, 19, 217, 243, - 18, 19, 159, 217, 243, 18, 19, 217, 239, 18, 19, 159, 217, 239, 18, 19, - 217, 238, 18, 19, 159, 217, 238, 18, 19, 217, 254, 18, 19, 159, 217, 254, - 18, 19, 217, 253, 18, 19, 159, 217, 253, 18, 19, 229, 195, 217, 253, 18, - 19, 222, 93, 18, 19, 253, 213, 222, 93, 18, 19, 217, 255, 18, 19, 251, - 226, 222, 93, 18, 19, 230, 132, 219, 110, 18, 19, 229, 195, 219, 101, 18, - 19, 229, 195, 222, 91, 18, 19, 229, 195, 218, 237, 18, 19, 229, 195, 218, - 87, 18, 19, 229, 195, 219, 100, 18, 19, 229, 195, 221, 186, 18, 19, 220, - 65, 18, 19, 220, 34, 18, 19, 220, 29, 18, 19, 220, 9, 18, 19, 220, 3, 18, - 19, 220, 104, 18, 19, 220, 100, 18, 19, 219, 208, 18, 19, 159, 219, 208, - 18, 19, 219, 207, 18, 19, 159, 219, 207, 18, 19, 219, 206, 18, 19, 159, - 219, 206, 18, 19, 219, 205, 18, 19, 159, 219, 205, 18, 19, 219, 204, 18, - 19, 159, 219, 204, 18, 19, 219, 210, 18, 19, 159, 219, 210, 18, 19, 219, - 209, 18, 19, 159, 219, 209, 18, 19, 220, 106, 18, 19, 211, 47, 18, 19, - 211, 101, 18, 19, 211, 8, 18, 19, 210, 255, 18, 19, 210, 244, 18, 19, - 210, 229, 18, 19, 211, 116, 210, 229, 18, 19, 192, 18, 19, 211, 103, 18, - 19, 210, 174, 18, 19, 159, 210, 174, 18, 19, 210, 173, 18, 19, 159, 210, - 173, 18, 19, 210, 172, 18, 19, 159, 210, 172, 18, 19, 210, 171, 18, 19, - 159, 210, 171, 18, 19, 210, 170, 18, 19, 159, 210, 170, 18, 19, 210, 176, - 18, 19, 159, 210, 176, 18, 19, 210, 175, 18, 19, 159, 210, 175, 18, 19, - 229, 195, 210, 175, 18, 19, 211, 117, 18, 19, 252, 12, 211, 117, 18, 19, - 159, 211, 117, 18, 19, 221, 211, 211, 8, 18, 19, 223, 131, 18, 19, 223, - 226, 223, 131, 18, 19, 159, 233, 64, 18, 19, 223, 186, 18, 19, 223, 38, - 18, 19, 222, 242, 18, 19, 222, 213, 18, 19, 222, 199, 18, 19, 159, 232, - 162, 18, 19, 205, 18, 19, 223, 187, 18, 19, 159, 233, 141, 18, 19, 222, - 110, 18, 19, 159, 222, 110, 18, 19, 153, 18, 19, 159, 153, 18, 19, 147, - 153, 18, 19, 244, 162, 18, 19, 244, 201, 18, 19, 244, 129, 18, 19, 244, - 116, 18, 19, 244, 51, 18, 19, 244, 42, 18, 19, 244, 204, 18, 19, 244, - 203, 18, 19, 243, 219, 18, 19, 159, 243, 219, 18, 19, 245, 14, 18, 19, - 216, 196, 18, 19, 230, 28, 216, 196, 18, 19, 216, 176, 18, 19, 230, 28, - 216, 176, 18, 19, 216, 172, 18, 19, 230, 28, 216, 172, 18, 19, 216, 157, - 18, 19, 216, 154, 18, 19, 216, 209, 18, 19, 216, 208, 18, 19, 216, 128, - 18, 19, 159, 216, 128, 18, 19, 216, 211, 18, 19, 215, 143, 18, 19, 215, - 141, 18, 19, 215, 140, 18, 19, 215, 145, 18, 19, 215, 146, 18, 19, 215, - 52, 18, 19, 215, 51, 18, 19, 215, 50, 18, 19, 215, 53, 18, 19, 227, 197, - 241, 245, 18, 19, 227, 197, 241, 187, 18, 19, 227, 197, 241, 168, 18, 19, - 227, 197, 241, 75, 18, 19, 227, 197, 241, 60, 18, 19, 227, 197, 162, 18, - 19, 227, 197, 242, 53, 18, 19, 227, 197, 242, 67, 18, 19, 227, 196, 242, - 67, 18, 19, 241, 161, 18, 19, 224, 87, 18, 19, 224, 56, 18, 19, 224, 51, - 18, 19, 224, 45, 18, 19, 224, 40, 18, 19, 224, 91, 18, 19, 224, 90, 18, - 19, 224, 99, 18, 19, 216, 56, 18, 19, 216, 54, 18, 19, 216, 53, 18, 19, - 216, 57, 18, 19, 159, 223, 131, 18, 19, 159, 223, 38, 18, 19, 159, 222, - 213, 18, 19, 159, 205, 18, 19, 229, 80, 18, 19, 229, 32, 18, 19, 229, 28, - 18, 19, 229, 9, 18, 19, 229, 4, 18, 19, 229, 82, 18, 19, 229, 81, 18, 19, - 229, 84, 18, 19, 228, 108, 18, 19, 221, 211, 220, 65, 18, 19, 221, 211, - 220, 34, 18, 19, 221, 211, 220, 9, 18, 19, 221, 211, 220, 104, 18, 19, - 211, 213, 216, 196, 18, 19, 211, 213, 216, 176, 18, 19, 211, 213, 216, - 157, 18, 19, 211, 213, 216, 209, 18, 19, 211, 213, 216, 211, 18, 19, 232, - 254, 18, 19, 232, 253, 18, 19, 232, 252, 18, 19, 232, 251, 18, 19, 233, - 4, 18, 19, 233, 3, 18, 19, 233, 5, 18, 19, 216, 210, 216, 196, 18, 19, - 216, 210, 216, 176, 18, 19, 216, 210, 216, 172, 18, 19, 216, 210, 216, - 157, 18, 19, 216, 210, 216, 154, 18, 19, 216, 210, 216, 209, 18, 19, 216, - 210, 216, 208, 18, 19, 216, 210, 216, 211, 18, 19, 254, 198, 253, 166, - 18, 19, 251, 226, 76, 18, 19, 251, 226, 74, 18, 19, 251, 226, 78, 18, 19, - 251, 226, 61, 18, 19, 251, 226, 212, 22, 18, 19, 251, 226, 211, 250, 18, - 19, 251, 226, 211, 227, 18, 19, 251, 226, 212, 65, 18, 19, 251, 226, 229, - 112, 18, 19, 251, 226, 228, 238, 18, 19, 251, 226, 228, 79, 18, 19, 251, - 226, 198, 18, 19, 251, 226, 234, 188, 18, 19, 251, 226, 234, 98, 18, 19, - 251, 226, 234, 34, 18, 19, 251, 226, 176, 18, 19, 221, 211, 241, 245, 18, - 19, 221, 211, 241, 187, 18, 19, 221, 211, 241, 75, 18, 19, 221, 211, 162, - 18, 19, 73, 242, 227, 18, 19, 73, 242, 231, 18, 19, 73, 242, 243, 18, 19, - 73, 242, 242, 18, 19, 73, 242, 232, 18, 19, 73, 243, 0, 18, 19, 73, 222, - 142, 18, 19, 73, 222, 213, 18, 19, 73, 223, 131, 18, 19, 73, 223, 111, - 18, 19, 73, 223, 38, 18, 19, 73, 205, 18, 19, 73, 211, 195, 18, 19, 73, - 211, 227, 18, 19, 73, 212, 22, 18, 19, 73, 212, 17, 18, 19, 73, 211, 250, - 18, 19, 73, 212, 65, 18, 19, 73, 240, 201, 18, 19, 73, 240, 202, 18, 19, - 73, 240, 205, 18, 19, 73, 240, 204, 18, 19, 73, 240, 203, 18, 19, 73, - 240, 207, 18, 19, 73, 216, 137, 18, 19, 73, 216, 157, 18, 19, 73, 216, - 196, 18, 19, 73, 216, 195, 18, 19, 73, 216, 176, 18, 19, 73, 216, 209, - 18, 19, 73, 215, 124, 18, 19, 73, 215, 134, 18, 19, 73, 215, 152, 18, 19, - 73, 215, 151, 18, 19, 73, 215, 136, 18, 19, 73, 215, 157, 18, 19, 73, - 224, 153, 18, 19, 73, 225, 19, 18, 19, 73, 225, 224, 18, 19, 73, 225, - 214, 18, 19, 73, 225, 111, 18, 19, 73, 191, 18, 19, 73, 226, 109, 18, 19, - 73, 242, 120, 18, 19, 73, 242, 181, 18, 19, 73, 243, 69, 18, 19, 73, 243, - 62, 18, 19, 73, 242, 221, 18, 19, 73, 243, 142, 18, 19, 73, 234, 106, 18, - 19, 73, 234, 111, 18, 19, 73, 234, 125, 18, 19, 73, 234, 124, 18, 19, 73, - 234, 118, 18, 19, 73, 234, 138, 18, 19, 73, 234, 47, 18, 19, 73, 234, 48, - 18, 19, 73, 234, 51, 18, 19, 73, 234, 50, 18, 19, 73, 234, 49, 18, 19, - 73, 234, 52, 18, 19, 73, 234, 53, 18, 19, 73, 227, 242, 18, 19, 73, 228, - 79, 18, 19, 73, 229, 112, 18, 19, 73, 229, 108, 18, 19, 73, 228, 238, 18, - 19, 73, 198, 18, 19, 73, 230, 107, 18, 19, 73, 230, 166, 18, 19, 73, 231, - 96, 18, 19, 73, 231, 85, 18, 19, 73, 230, 235, 18, 19, 73, 186, 18, 19, - 73, 210, 212, 18, 19, 73, 210, 244, 18, 19, 73, 211, 47, 18, 19, 73, 211, - 44, 18, 19, 73, 211, 8, 18, 19, 73, 192, 18, 19, 73, 235, 57, 18, 19, - 221, 211, 235, 57, 18, 19, 73, 235, 74, 18, 19, 73, 235, 132, 18, 19, 73, - 235, 130, 18, 19, 73, 235, 114, 18, 19, 221, 211, 235, 114, 18, 19, 73, - 235, 147, 18, 19, 73, 235, 87, 18, 19, 73, 235, 91, 18, 19, 73, 235, 101, - 18, 19, 73, 235, 100, 18, 19, 73, 235, 99, 18, 19, 73, 235, 102, 18, 19, - 73, 232, 103, 18, 19, 73, 232, 162, 18, 19, 73, 233, 64, 18, 19, 73, 233, - 56, 18, 19, 73, 232, 247, 18, 19, 73, 233, 141, 18, 19, 73, 247, 157, 18, - 19, 73, 247, 158, 18, 19, 73, 247, 163, 18, 19, 73, 247, 162, 18, 19, 73, - 247, 159, 18, 19, 73, 247, 164, 18, 19, 73, 232, 250, 18, 19, 73, 232, - 252, 18, 19, 73, 233, 0, 18, 19, 73, 232, 255, 18, 19, 73, 232, 254, 18, - 19, 73, 233, 4, 18, 19, 73, 216, 51, 18, 19, 73, 216, 53, 18, 19, 73, - 216, 56, 18, 19, 73, 216, 55, 18, 19, 73, 216, 54, 18, 19, 73, 216, 57, - 18, 19, 73, 216, 46, 18, 19, 73, 216, 47, 18, 19, 73, 216, 59, 18, 19, - 73, 216, 58, 18, 19, 73, 216, 48, 18, 19, 73, 216, 60, 18, 19, 73, 210, - 13, 18, 19, 73, 210, 23, 18, 19, 73, 210, 94, 18, 19, 73, 210, 92, 18, - 19, 73, 210, 44, 18, 19, 73, 210, 116, 18, 19, 73, 210, 159, 18, 19, 73, - 65, 210, 159, 18, 19, 73, 246, 36, 18, 19, 73, 246, 37, 18, 19, 73, 246, - 44, 18, 19, 73, 246, 43, 18, 19, 73, 246, 39, 18, 19, 73, 246, 46, 18, - 19, 73, 218, 84, 18, 19, 73, 219, 60, 18, 19, 73, 221, 183, 18, 19, 73, - 221, 172, 18, 19, 73, 219, 193, 18, 19, 73, 206, 18, 19, 73, 219, 227, - 18, 19, 73, 220, 9, 18, 19, 73, 220, 65, 18, 19, 73, 220, 63, 18, 19, 73, - 220, 34, 18, 19, 73, 220, 104, 18, 19, 73, 220, 106, 18, 19, 73, 215, - 164, 18, 19, 73, 215, 167, 18, 19, 73, 215, 179, 18, 19, 73, 215, 178, - 18, 19, 73, 215, 168, 18, 19, 73, 215, 184, 18, 19, 73, 250, 77, 18, 19, - 73, 250, 94, 18, 19, 73, 250, 139, 18, 19, 73, 250, 136, 18, 19, 73, 250, - 118, 18, 19, 73, 250, 165, 18, 19, 73, 215, 127, 18, 19, 73, 215, 128, - 18, 19, 73, 215, 131, 18, 19, 73, 215, 130, 18, 19, 73, 215, 129, 18, 19, - 73, 215, 132, 18, 19, 250, 119, 50, 18, 19, 243, 236, 218, 131, 18, 19, - 224, 83, 18, 19, 229, 78, 18, 19, 228, 105, 18, 19, 228, 104, 18, 19, - 228, 103, 18, 19, 228, 102, 18, 19, 228, 107, 18, 19, 228, 106, 18, 19, - 211, 213, 216, 126, 18, 19, 211, 213, 216, 125, 18, 19, 211, 213, 216, - 124, 18, 19, 211, 213, 216, 123, 18, 19, 211, 213, 216, 122, 18, 19, 211, - 213, 216, 129, 18, 19, 211, 213, 216, 128, 18, 19, 211, 213, 40, 216, - 211, 18, 19, 251, 226, 212, 98, 226, 230, 219, 21, 79, 226, 230, 1, 252, - 56, 226, 230, 1, 232, 92, 226, 230, 1, 244, 159, 226, 230, 1, 222, 17, - 226, 230, 1, 228, 198, 226, 230, 1, 214, 226, 226, 230, 1, 248, 205, 226, - 230, 1, 216, 81, 226, 230, 1, 249, 237, 226, 230, 1, 250, 188, 226, 230, - 1, 230, 96, 226, 230, 1, 242, 163, 226, 230, 1, 229, 68, 226, 230, 1, - 218, 124, 226, 230, 1, 222, 137, 226, 230, 1, 254, 207, 226, 230, 1, 226, - 191, 226, 230, 1, 214, 150, 226, 230, 1, 245, 239, 226, 230, 1, 235, 195, - 226, 230, 1, 245, 240, 226, 230, 1, 226, 162, 226, 230, 1, 214, 206, 226, - 230, 1, 236, 46, 226, 230, 1, 245, 237, 226, 230, 1, 225, 205, 226, 230, - 244, 158, 79, 226, 230, 223, 52, 244, 158, 79, 178, 1, 244, 149, 244, - 141, 244, 163, 245, 14, 178, 1, 214, 105, 178, 1, 214, 135, 214, 151, 69, - 178, 1, 210, 214, 178, 1, 211, 117, 178, 1, 212, 98, 178, 1, 216, 131, - 216, 130, 216, 152, 178, 1, 245, 67, 178, 1, 254, 101, 61, 178, 1, 226, - 147, 78, 178, 1, 255, 26, 61, 178, 1, 254, 236, 178, 1, 232, 139, 78, - 178, 1, 219, 246, 78, 178, 1, 78, 178, 1, 226, 238, 178, 1, 226, 200, - 178, 1, 223, 167, 223, 180, 223, 97, 153, 178, 1, 234, 199, 178, 1, 250, - 185, 178, 1, 234, 200, 235, 29, 178, 1, 243, 209, 178, 1, 245, 146, 178, - 1, 243, 65, 242, 73, 243, 209, 178, 1, 243, 103, 178, 1, 211, 188, 211, - 182, 212, 98, 178, 1, 242, 45, 242, 67, 178, 1, 242, 49, 242, 67, 178, 1, - 232, 141, 242, 67, 178, 1, 219, 249, 242, 67, 178, 1, 229, 190, 227, 161, - 229, 191, 230, 30, 178, 1, 219, 247, 230, 30, 178, 1, 246, 123, 178, 1, - 235, 175, 235, 179, 235, 168, 74, 178, 1, 76, 178, 1, 235, 123, 235, 150, - 178, 1, 243, 50, 178, 1, 232, 142, 254, 252, 178, 1, 219, 251, 61, 178, - 1, 235, 160, 245, 121, 178, 1, 225, 167, 225, 189, 226, 109, 178, 1, 254, - 172, 245, 119, 178, 1, 219, 26, 222, 93, 178, 1, 219, 181, 232, 138, 222, - 93, 178, 1, 219, 245, 222, 93, 178, 1, 251, 74, 178, 1, 210, 159, 178, 1, - 216, 64, 216, 74, 215, 41, 217, 153, 178, 1, 219, 244, 217, 153, 178, 1, - 249, 68, 178, 1, 252, 39, 252, 42, 251, 232, 253, 166, 178, 1, 219, 250, - 253, 166, 178, 1, 246, 122, 178, 1, 226, 175, 178, 1, 245, 204, 245, 206, - 76, 178, 1, 231, 183, 231, 191, 194, 178, 1, 232, 140, 194, 178, 1, 219, - 248, 194, 178, 1, 233, 79, 233, 120, 232, 149, 156, 178, 1, 246, 124, - 178, 1, 235, 237, 178, 1, 235, 238, 178, 1, 248, 218, 248, 223, 249, 68, - 178, 1, 226, 142, 245, 66, 78, 178, 1, 245, 235, 178, 1, 235, 194, 178, - 1, 249, 86, 178, 1, 251, 25, 178, 1, 250, 197, 178, 1, 218, 163, 178, 1, - 232, 137, 178, 1, 219, 243, 178, 1, 240, 117, 178, 1, 224, 99, 178, 1, - 211, 178, 178, 219, 157, 224, 143, 178, 230, 90, 224, 143, 178, 249, 139, - 224, 143, 178, 254, 14, 87, 178, 215, 82, 87, 178, 252, 54, 87, 217, 84, - 1, 61, 217, 84, 1, 74, 217, 84, 1, 69, 217, 84, 1, 176, 217, 84, 1, 243, - 142, 217, 84, 1, 229, 82, 217, 84, 1, 217, 106, 217, 84, 1, 248, 229, - 217, 84, 1, 198, 217, 84, 1, 191, 217, 84, 1, 252, 199, 217, 84, 1, 186, - 217, 84, 1, 192, 217, 84, 1, 233, 141, 217, 84, 1, 212, 65, 217, 84, 1, - 206, 217, 84, 1, 162, 217, 84, 25, 5, 74, 217, 84, 25, 5, 69, 217, 84, 5, - 213, 152, 242, 14, 1, 61, 242, 14, 1, 74, 242, 14, 1, 69, 242, 14, 1, - 176, 242, 14, 1, 243, 142, 242, 14, 1, 229, 82, 242, 14, 1, 217, 106, - 242, 14, 1, 248, 229, 242, 14, 1, 198, 242, 14, 1, 191, 242, 14, 1, 252, - 199, 242, 14, 1, 186, 242, 14, 1, 192, 242, 14, 1, 205, 242, 14, 1, 233, - 141, 242, 14, 1, 212, 65, 242, 14, 1, 206, 242, 14, 1, 162, 242, 14, 25, - 5, 74, 242, 14, 25, 5, 69, 242, 14, 5, 226, 53, 225, 129, 219, 157, 224, - 143, 225, 129, 52, 224, 143, 251, 128, 1, 61, 251, 128, 1, 74, 251, 128, - 1, 69, 251, 128, 1, 176, 251, 128, 1, 243, 142, 251, 128, 1, 229, 82, - 251, 128, 1, 217, 106, 251, 128, 1, 248, 229, 251, 128, 1, 198, 251, 128, - 1, 191, 251, 128, 1, 252, 199, 251, 128, 1, 186, 251, 128, 1, 192, 251, - 128, 1, 205, 251, 128, 1, 233, 141, 251, 128, 1, 212, 65, 251, 128, 1, - 206, 251, 128, 1, 162, 251, 128, 25, 5, 74, 251, 128, 25, 5, 69, 217, 83, - 1, 61, 217, 83, 1, 74, 217, 83, 1, 69, 217, 83, 1, 176, 217, 83, 1, 243, - 142, 217, 83, 1, 229, 82, 217, 83, 1, 217, 106, 217, 83, 1, 248, 229, - 217, 83, 1, 198, 217, 83, 1, 191, 217, 83, 1, 252, 199, 217, 83, 1, 186, - 217, 83, 1, 192, 217, 83, 1, 233, 141, 217, 83, 1, 212, 65, 217, 83, 1, - 206, 217, 83, 25, 5, 74, 217, 83, 25, 5, 69, 70, 1, 176, 70, 1, 234, 138, - 70, 1, 234, 34, 70, 1, 234, 111, 70, 1, 229, 9, 70, 1, 251, 41, 70, 1, - 250, 165, 70, 1, 249, 246, 70, 1, 250, 94, 70, 1, 227, 138, 70, 1, 248, - 229, 70, 1, 215, 145, 70, 1, 247, 153, 70, 1, 215, 140, 70, 1, 228, 85, - 70, 1, 217, 106, 70, 1, 216, 209, 70, 1, 112, 70, 1, 216, 157, 70, 1, - 228, 79, 70, 1, 252, 199, 70, 1, 225, 150, 70, 1, 225, 19, 70, 1, 225, - 124, 70, 1, 230, 166, 70, 1, 210, 244, 70, 1, 222, 213, 70, 1, 232, 162, - 70, 1, 213, 138, 70, 1, 220, 104, 70, 1, 218, 186, 70, 1, 206, 70, 1, - 162, 70, 1, 233, 141, 70, 1, 224, 91, 70, 235, 250, 25, 224, 77, 70, 235, - 250, 25, 224, 90, 70, 235, 250, 25, 224, 56, 70, 235, 250, 25, 224, 51, - 70, 235, 250, 25, 224, 33, 70, 235, 250, 25, 224, 5, 70, 235, 250, 25, - 223, 249, 70, 235, 250, 25, 223, 248, 70, 235, 250, 25, 222, 102, 70, - 235, 250, 25, 222, 95, 70, 235, 250, 25, 232, 67, 70, 235, 250, 25, 232, - 57, 70, 235, 250, 25, 224, 72, 70, 235, 250, 25, 224, 83, 70, 235, 250, - 25, 224, 41, 215, 49, 111, 70, 235, 250, 25, 224, 41, 215, 49, 105, 70, - 235, 250, 25, 224, 73, 70, 25, 235, 236, 254, 53, 70, 25, 235, 236, 255, - 82, 70, 25, 5, 255, 82, 70, 25, 5, 74, 70, 25, 5, 236, 40, 70, 25, 5, - 211, 117, 70, 25, 5, 210, 169, 70, 25, 5, 69, 70, 25, 5, 214, 118, 70, - 25, 5, 214, 229, 70, 25, 5, 226, 238, 70, 25, 5, 192, 70, 25, 5, 236, 67, - 70, 25, 5, 76, 70, 25, 5, 254, 252, 70, 25, 5, 254, 210, 70, 25, 5, 226, - 187, 70, 25, 5, 253, 200, 70, 5, 228, 211, 70, 5, 223, 129, 70, 5, 210, - 180, 70, 5, 230, 57, 70, 5, 215, 214, 70, 5, 252, 151, 70, 5, 222, 208, - 70, 5, 216, 41, 70, 5, 234, 247, 70, 5, 254, 212, 70, 5, 221, 246, 221, - 240, 70, 5, 213, 149, 70, 5, 249, 240, 70, 5, 252, 125, 70, 5, 234, 131, - 70, 5, 252, 145, 70, 5, 251, 17, 225, 75, 233, 193, 70, 5, 233, 36, 216, - 18, 70, 5, 252, 28, 70, 5, 225, 126, 230, 104, 70, 5, 234, 15, 70, 249, - 106, 16, 223, 31, 70, 5, 253, 182, 70, 5, 253, 203, 70, 21, 210, 86, 70, - 21, 111, 70, 21, 105, 70, 21, 158, 70, 21, 161, 70, 21, 190, 70, 21, 195, - 70, 21, 199, 70, 21, 196, 70, 21, 201, 70, 16, 233, 36, 253, 205, 219, - 45, 70, 16, 233, 36, 253, 205, 230, 76, 70, 16, 233, 36, 253, 205, 225, - 74, 70, 16, 233, 36, 253, 205, 252, 57, 70, 16, 233, 36, 253, 205, 251, - 111, 70, 16, 233, 36, 253, 205, 224, 218, 70, 16, 233, 36, 253, 205, 224, - 212, 70, 16, 233, 36, 253, 205, 224, 210, 70, 16, 233, 36, 253, 205, 224, - 216, 70, 16, 233, 36, 253, 205, 224, 214, 83, 251, 244, 83, 245, 171, 83, - 249, 227, 83, 243, 236, 218, 131, 83, 249, 234, 83, 244, 19, 247, 126, - 83, 216, 40, 219, 54, 240, 175, 83, 219, 192, 3, 251, 180, 231, 159, 83, - 231, 188, 249, 227, 83, 231, 188, 243, 236, 218, 131, 83, 228, 196, 83, - 244, 5, 45, 221, 159, 111, 83, 244, 5, 45, 221, 159, 105, 83, 244, 5, 45, - 221, 159, 158, 83, 25, 220, 139, 83, 21, 210, 86, 83, 21, 111, 83, 21, - 105, 83, 21, 158, 83, 21, 161, 83, 21, 190, 83, 21, 195, 83, 21, 199, 83, - 21, 196, 83, 21, 201, 83, 1, 61, 83, 1, 76, 83, 1, 74, 83, 1, 78, 83, 1, - 69, 83, 1, 226, 238, 83, 1, 214, 214, 83, 1, 245, 217, 83, 1, 198, 83, 1, - 254, 123, 83, 1, 252, 199, 83, 1, 191, 83, 1, 224, 91, 83, 1, 243, 142, - 83, 1, 186, 83, 1, 233, 141, 83, 1, 206, 83, 1, 220, 104, 83, 1, 217, - 106, 83, 1, 248, 229, 83, 1, 250, 165, 83, 1, 235, 147, 83, 1, 192, 83, - 1, 205, 83, 1, 212, 65, 83, 1, 244, 204, 83, 1, 176, 83, 1, 234, 138, 83, - 1, 215, 184, 83, 1, 210, 116, 83, 1, 242, 53, 83, 1, 210, 16, 83, 1, 233, - 4, 83, 1, 210, 69, 83, 1, 250, 118, 83, 1, 216, 40, 200, 25, 50, 83, 1, - 216, 40, 76, 83, 1, 216, 40, 74, 83, 1, 216, 40, 78, 83, 1, 216, 40, 69, - 83, 1, 216, 40, 226, 238, 83, 1, 216, 40, 214, 214, 83, 1, 216, 40, 254, - 123, 83, 1, 216, 40, 252, 199, 83, 1, 216, 40, 191, 83, 1, 216, 40, 224, - 91, 83, 1, 216, 40, 243, 142, 83, 1, 216, 40, 186, 83, 1, 216, 40, 217, - 106, 83, 1, 216, 40, 248, 229, 83, 1, 216, 40, 250, 165, 83, 1, 216, 40, - 235, 147, 83, 1, 216, 40, 215, 184, 83, 1, 216, 40, 192, 83, 1, 216, 40, - 212, 65, 83, 1, 216, 40, 176, 83, 1, 216, 40, 243, 139, 83, 1, 216, 40, - 242, 53, 83, 1, 216, 40, 235, 113, 83, 1, 216, 40, 228, 236, 83, 1, 216, - 40, 246, 46, 83, 1, 219, 192, 76, 83, 1, 219, 192, 74, 83, 1, 219, 192, - 235, 158, 83, 1, 219, 192, 214, 214, 83, 1, 219, 192, 69, 83, 1, 219, - 192, 254, 123, 83, 1, 219, 192, 176, 83, 1, 219, 192, 243, 142, 83, 1, - 219, 192, 162, 83, 1, 219, 192, 191, 83, 1, 219, 192, 220, 104, 83, 1, - 219, 192, 217, 106, 83, 1, 219, 192, 248, 229, 83, 1, 219, 192, 235, 147, - 83, 1, 219, 192, 244, 204, 83, 1, 219, 192, 243, 139, 83, 1, 219, 192, - 242, 53, 83, 1, 219, 192, 215, 184, 83, 1, 219, 192, 210, 116, 83, 1, - 219, 192, 223, 187, 83, 1, 219, 192, 250, 165, 83, 1, 219, 192, 210, 82, - 83, 1, 231, 188, 74, 83, 1, 231, 188, 176, 83, 1, 231, 188, 205, 83, 1, - 231, 188, 244, 204, 83, 1, 231, 188, 210, 82, 83, 1, 254, 171, 243, 123, - 254, 84, 111, 83, 1, 254, 171, 243, 123, 213, 148, 111, 83, 1, 254, 171, - 243, 123, 248, 194, 83, 1, 254, 171, 243, 123, 214, 224, 83, 1, 254, 171, - 243, 123, 235, 200, 214, 224, 83, 1, 254, 171, 243, 123, 252, 163, 83, 1, - 254, 171, 243, 123, 134, 252, 163, 83, 1, 254, 171, 243, 123, 61, 83, 1, - 254, 171, 243, 123, 74, 83, 1, 254, 171, 243, 123, 176, 83, 1, 254, 171, - 243, 123, 229, 82, 83, 1, 254, 171, 243, 123, 251, 41, 83, 1, 254, 171, - 243, 123, 215, 157, 83, 1, 254, 171, 243, 123, 215, 145, 83, 1, 254, 171, - 243, 123, 248, 143, 83, 1, 254, 171, 243, 123, 228, 115, 83, 1, 254, 171, - 243, 123, 217, 106, 83, 1, 254, 171, 243, 123, 248, 229, 83, 1, 254, 171, - 243, 123, 191, 83, 1, 254, 171, 243, 123, 225, 150, 83, 1, 254, 171, 243, - 123, 218, 225, 83, 1, 254, 171, 243, 123, 210, 82, 83, 1, 254, 171, 243, - 123, 210, 116, 83, 1, 254, 171, 243, 123, 254, 218, 83, 1, 216, 40, 254, - 171, 243, 123, 217, 106, 83, 1, 216, 40, 254, 171, 243, 123, 210, 82, 83, - 1, 231, 188, 254, 171, 243, 123, 243, 0, 83, 1, 231, 188, 254, 171, 243, - 123, 229, 82, 83, 1, 231, 188, 254, 171, 243, 123, 251, 41, 83, 1, 231, - 188, 254, 171, 243, 123, 235, 120, 83, 1, 231, 188, 254, 171, 243, 123, - 215, 157, 83, 1, 231, 188, 254, 171, 243, 123, 248, 127, 83, 1, 231, 188, - 254, 171, 243, 123, 217, 106, 83, 1, 231, 188, 254, 171, 243, 123, 248, - 33, 83, 1, 231, 188, 254, 171, 243, 123, 218, 225, 83, 1, 231, 188, 254, - 171, 243, 123, 249, 80, 83, 1, 231, 188, 254, 171, 243, 123, 210, 82, 83, - 1, 231, 188, 254, 171, 243, 123, 210, 116, 83, 1, 254, 171, 243, 123, - 163, 69, 83, 1, 254, 171, 243, 123, 163, 192, 83, 1, 231, 188, 254, 171, - 243, 123, 252, 26, 83, 1, 254, 171, 243, 123, 248, 219, 83, 1, 231, 188, - 254, 171, 243, 123, 233, 4, 18, 19, 226, 113, 18, 19, 253, 175, 18, 19, - 255, 37, 18, 19, 212, 25, 18, 19, 224, 224, 18, 19, 225, 233, 18, 19, - 224, 108, 18, 19, 217, 32, 18, 19, 234, 195, 18, 19, 233, 185, 18, 19, - 231, 137, 18, 19, 228, 42, 18, 19, 229, 186, 18, 19, 233, 74, 18, 19, - 219, 24, 18, 19, 221, 213, 18, 19, 219, 234, 18, 19, 220, 68, 18, 19, - 219, 203, 18, 19, 210, 220, 18, 19, 211, 52, 18, 19, 223, 137, 18, 19, - 227, 175, 18, 19, 226, 220, 227, 175, 18, 19, 227, 174, 18, 19, 226, 220, - 227, 174, 18, 19, 227, 173, 18, 19, 226, 220, 227, 173, 18, 19, 227, 172, - 18, 19, 226, 220, 227, 172, 18, 19, 222, 107, 18, 19, 222, 106, 18, 19, - 222, 105, 18, 19, 222, 104, 18, 19, 222, 103, 18, 19, 222, 111, 18, 19, - 226, 220, 226, 109, 18, 19, 226, 220, 217, 153, 18, 19, 226, 220, 235, - 29, 18, 19, 226, 220, 251, 74, 18, 19, 226, 220, 194, 18, 19, 226, 220, - 230, 30, 18, 19, 226, 220, 222, 93, 18, 19, 226, 220, 220, 106, 18, 19, - 245, 227, 212, 98, 18, 19, 212, 7, 212, 98, 18, 19, 40, 4, 222, 236, 18, - 19, 40, 223, 160, 247, 128, 18, 19, 223, 226, 222, 108, 18, 19, 159, 232, - 133, 18, 19, 159, 233, 140, 18, 19, 216, 127, 18, 19, 216, 129, 18, 19, - 215, 137, 18, 19, 215, 139, 18, 19, 215, 144, 18, 19, 216, 50, 18, 19, - 216, 52, 18, 19, 221, 211, 219, 208, 18, 19, 221, 211, 220, 3, 18, 19, - 221, 211, 241, 60, 18, 19, 73, 242, 80, 18, 19, 73, 248, 60, 243, 62, 18, - 19, 73, 243, 139, 18, 19, 73, 242, 85, 18, 19, 221, 211, 235, 39, 18, 19, - 73, 235, 37, 18, 19, 252, 76, 248, 60, 156, 18, 19, 252, 76, 248, 60, - 153, 18, 19, 73, 248, 55, 222, 93, 232, 229, 213, 122, 233, 16, 232, 229, - 1, 176, 232, 229, 1, 234, 138, 232, 229, 1, 243, 142, 232, 229, 1, 243, - 0, 232, 229, 1, 229, 82, 232, 229, 1, 251, 41, 232, 229, 1, 250, 165, - 232, 229, 1, 235, 147, 232, 229, 1, 235, 120, 232, 229, 1, 211, 71, 232, - 229, 1, 217, 106, 232, 229, 1, 216, 209, 232, 229, 1, 248, 229, 232, 229, - 1, 248, 33, 232, 229, 1, 198, 232, 229, 1, 191, 232, 229, 1, 225, 150, - 232, 229, 1, 252, 199, 232, 229, 1, 252, 26, 232, 229, 1, 186, 232, 229, - 1, 192, 232, 229, 1, 205, 232, 229, 1, 233, 141, 232, 229, 1, 212, 65, - 232, 229, 1, 220, 104, 232, 229, 1, 218, 225, 232, 229, 1, 206, 232, 229, - 1, 162, 232, 229, 25, 5, 61, 232, 229, 25, 5, 74, 232, 229, 25, 5, 69, - 232, 229, 25, 5, 245, 217, 232, 229, 25, 5, 254, 210, 232, 229, 25, 5, - 226, 187, 232, 229, 25, 5, 253, 200, 232, 229, 25, 5, 76, 232, 229, 25, - 5, 78, 232, 229, 218, 74, 1, 192, 232, 229, 218, 74, 1, 205, 232, 229, - 218, 74, 1, 212, 65, 232, 229, 4, 1, 176, 232, 229, 4, 1, 229, 82, 232, - 229, 4, 1, 254, 83, 232, 229, 4, 1, 217, 106, 232, 229, 4, 1, 198, 232, - 229, 4, 1, 191, 232, 229, 4, 1, 186, 232, 229, 4, 1, 205, 232, 229, 4, 1, - 233, 141, 232, 229, 5, 230, 94, 232, 229, 5, 234, 177, 232, 229, 5, 222, - 34, 232, 229, 5, 232, 133, 232, 229, 245, 39, 79, 232, 229, 224, 16, 79, - 232, 229, 21, 210, 86, 232, 229, 21, 111, 232, 229, 21, 105, 232, 229, - 21, 158, 232, 229, 21, 161, 232, 229, 21, 190, 232, 229, 21, 195, 232, - 229, 21, 199, 232, 229, 21, 196, 232, 229, 21, 201, 39, 233, 65, 1, 176, - 39, 233, 65, 1, 211, 165, 39, 233, 65, 1, 229, 82, 39, 233, 65, 1, 215, - 184, 39, 233, 65, 1, 206, 39, 233, 65, 1, 192, 39, 233, 65, 1, 217, 106, - 39, 233, 65, 1, 216, 209, 39, 233, 65, 1, 233, 141, 39, 233, 65, 1, 191, - 39, 233, 65, 1, 225, 150, 39, 233, 65, 1, 186, 39, 233, 65, 1, 244, 204, - 39, 233, 65, 1, 214, 27, 39, 233, 65, 1, 162, 39, 233, 65, 1, 224, 91, - 39, 233, 65, 1, 234, 138, 39, 233, 65, 1, 215, 176, 39, 233, 65, 1, 198, - 39, 233, 65, 1, 61, 39, 233, 65, 1, 74, 39, 233, 65, 1, 245, 217, 39, - 233, 65, 1, 245, 205, 39, 233, 65, 1, 69, 39, 233, 65, 1, 226, 187, 39, - 233, 65, 1, 78, 39, 233, 65, 1, 214, 214, 39, 233, 65, 1, 76, 39, 233, - 65, 1, 253, 198, 39, 233, 65, 1, 254, 210, 39, 233, 65, 1, 216, 29, 39, - 233, 65, 1, 216, 28, 39, 233, 65, 1, 216, 27, 39, 233, 65, 1, 216, 26, - 39, 233, 65, 1, 216, 25, 166, 39, 173, 1, 125, 224, 91, 166, 39, 173, 1, - 121, 224, 91, 166, 39, 173, 1, 125, 176, 166, 39, 173, 1, 125, 211, 165, - 166, 39, 173, 1, 125, 229, 82, 166, 39, 173, 1, 121, 176, 166, 39, 173, - 1, 121, 211, 165, 166, 39, 173, 1, 121, 229, 82, 166, 39, 173, 1, 125, - 215, 184, 166, 39, 173, 1, 125, 206, 166, 39, 173, 1, 125, 192, 166, 39, - 173, 1, 121, 215, 184, 166, 39, 173, 1, 121, 206, 166, 39, 173, 1, 121, - 192, 166, 39, 173, 1, 125, 217, 106, 166, 39, 173, 1, 125, 216, 209, 166, - 39, 173, 1, 125, 198, 166, 39, 173, 1, 121, 217, 106, 166, 39, 173, 1, - 121, 216, 209, 166, 39, 173, 1, 121, 198, 166, 39, 173, 1, 125, 191, 166, - 39, 173, 1, 125, 225, 150, 166, 39, 173, 1, 125, 186, 166, 39, 173, 1, - 121, 191, 166, 39, 173, 1, 121, 225, 150, 166, 39, 173, 1, 121, 186, 166, - 39, 173, 1, 125, 244, 204, 166, 39, 173, 1, 125, 214, 27, 166, 39, 173, - 1, 125, 233, 141, 166, 39, 173, 1, 121, 244, 204, 166, 39, 173, 1, 121, - 214, 27, 166, 39, 173, 1, 121, 233, 141, 166, 39, 173, 1, 125, 162, 166, - 39, 173, 1, 125, 248, 229, 166, 39, 173, 1, 125, 252, 199, 166, 39, 173, - 1, 121, 162, 166, 39, 173, 1, 121, 248, 229, 166, 39, 173, 1, 121, 252, - 199, 166, 39, 173, 1, 125, 233, 190, 166, 39, 173, 1, 125, 211, 138, 166, - 39, 173, 1, 121, 233, 190, 166, 39, 173, 1, 121, 211, 138, 166, 39, 173, - 1, 125, 218, 83, 166, 39, 173, 1, 121, 218, 83, 166, 39, 173, 25, 5, 25, - 219, 241, 166, 39, 173, 25, 5, 255, 82, 166, 39, 173, 25, 5, 236, 40, - 166, 39, 173, 25, 5, 69, 166, 39, 173, 25, 5, 214, 118, 166, 39, 173, 25, - 5, 76, 166, 39, 173, 25, 5, 254, 252, 166, 39, 173, 25, 5, 78, 166, 39, - 173, 25, 5, 227, 4, 166, 39, 173, 25, 5, 214, 214, 166, 39, 173, 25, 5, - 253, 175, 166, 39, 173, 25, 5, 255, 37, 166, 39, 173, 25, 5, 214, 111, - 166, 39, 173, 25, 5, 226, 113, 166, 39, 173, 25, 5, 227, 1, 166, 39, 173, - 25, 5, 214, 210, 166, 39, 173, 25, 5, 235, 158, 166, 39, 173, 1, 40, 214, - 105, 166, 39, 173, 1, 40, 229, 84, 166, 39, 173, 1, 40, 230, 30, 166, 39, - 173, 1, 40, 194, 166, 39, 173, 1, 40, 235, 29, 166, 39, 173, 1, 40, 249, - 68, 166, 39, 173, 1, 40, 253, 166, 166, 39, 173, 138, 231, 163, 166, 39, - 173, 138, 231, 162, 166, 39, 173, 21, 210, 86, 166, 39, 173, 21, 111, - 166, 39, 173, 21, 105, 166, 39, 173, 21, 158, 166, 39, 173, 21, 161, 166, - 39, 173, 21, 190, 166, 39, 173, 21, 195, 166, 39, 173, 21, 199, 166, 39, - 173, 21, 196, 166, 39, 173, 21, 201, 166, 39, 173, 89, 21, 111, 166, 39, - 173, 5, 233, 126, 166, 39, 173, 5, 233, 125, 70, 16, 225, 240, 70, 16, - 230, 77, 234, 31, 70, 16, 225, 75, 234, 31, 70, 16, 252, 58, 234, 31, 70, - 16, 251, 112, 234, 31, 70, 16, 224, 219, 234, 31, 70, 16, 224, 213, 234, - 31, 70, 16, 224, 211, 234, 31, 70, 16, 224, 217, 234, 31, 70, 16, 224, - 215, 234, 31, 70, 16, 248, 181, 234, 31, 70, 16, 248, 177, 234, 31, 70, - 16, 248, 176, 234, 31, 70, 16, 248, 179, 234, 31, 70, 16, 248, 178, 234, - 31, 70, 16, 248, 175, 234, 31, 70, 16, 215, 87, 70, 16, 230, 77, 222, - 207, 70, 16, 225, 75, 222, 207, 70, 16, 252, 58, 222, 207, 70, 16, 251, - 112, 222, 207, 70, 16, 224, 219, 222, 207, 70, 16, 224, 213, 222, 207, - 70, 16, 224, 211, 222, 207, 70, 16, 224, 217, 222, 207, 70, 16, 224, 215, - 222, 207, 70, 16, 248, 181, 222, 207, 70, 16, 248, 177, 222, 207, 70, 16, - 248, 176, 222, 207, 70, 16, 248, 179, 222, 207, 70, 16, 248, 178, 222, - 207, 70, 16, 248, 175, 222, 207, 251, 129, 1, 176, 251, 129, 1, 243, 142, - 251, 129, 1, 229, 82, 251, 129, 1, 229, 27, 251, 129, 1, 191, 251, 129, - 1, 252, 199, 251, 129, 1, 186, 251, 129, 1, 230, 110, 251, 129, 1, 217, - 106, 251, 129, 1, 248, 229, 251, 129, 1, 198, 251, 129, 1, 228, 41, 251, - 129, 1, 251, 41, 251, 129, 1, 235, 147, 251, 129, 1, 227, 169, 251, 129, - 1, 227, 162, 251, 129, 1, 192, 251, 129, 1, 205, 251, 129, 1, 233, 141, - 251, 129, 1, 214, 27, 251, 129, 1, 206, 251, 129, 1, 61, 251, 129, 1, - 162, 251, 129, 25, 5, 74, 251, 129, 25, 5, 69, 251, 129, 25, 5, 76, 251, - 129, 25, 5, 78, 251, 129, 25, 5, 254, 252, 251, 129, 226, 64, 251, 129, - 245, 151, 64, 221, 174, 39, 89, 1, 125, 176, 39, 89, 1, 125, 234, 138, - 39, 89, 1, 125, 233, 177, 39, 89, 1, 121, 176, 39, 89, 1, 121, 233, 177, - 39, 89, 1, 121, 234, 138, 39, 89, 1, 229, 82, 39, 89, 1, 125, 251, 41, - 39, 89, 1, 125, 250, 165, 39, 89, 1, 121, 251, 41, 39, 89, 1, 121, 206, - 39, 89, 1, 121, 250, 165, 39, 89, 1, 227, 169, 39, 89, 1, 223, 143, 39, - 89, 1, 125, 223, 141, 39, 89, 1, 248, 229, 39, 89, 1, 121, 223, 141, 39, - 89, 1, 223, 152, 39, 89, 1, 125, 217, 106, 39, 89, 1, 125, 216, 209, 39, - 89, 1, 121, 217, 106, 39, 89, 1, 121, 216, 209, 39, 89, 1, 198, 39, 89, - 1, 252, 199, 39, 89, 1, 125, 191, 39, 89, 1, 125, 225, 150, 39, 89, 1, - 125, 244, 204, 39, 89, 1, 121, 191, 39, 89, 1, 121, 244, 204, 39, 89, 1, - 121, 225, 150, 39, 89, 1, 186, 39, 89, 1, 121, 192, 39, 89, 1, 125, 192, - 39, 89, 1, 205, 39, 89, 1, 222, 139, 39, 89, 1, 233, 141, 39, 89, 1, 232, - 98, 39, 89, 1, 212, 65, 39, 89, 1, 125, 220, 104, 39, 89, 1, 125, 218, - 225, 39, 89, 1, 125, 206, 39, 89, 1, 125, 162, 39, 89, 1, 232, 190, 39, - 89, 1, 61, 39, 89, 1, 121, 162, 39, 89, 1, 74, 39, 89, 1, 236, 40, 39, - 89, 1, 69, 39, 89, 1, 214, 118, 39, 89, 1, 245, 217, 39, 89, 1, 226, 187, - 39, 89, 1, 233, 126, 39, 89, 1, 242, 139, 206, 39, 89, 117, 5, 147, 205, - 39, 89, 117, 5, 147, 233, 141, 39, 89, 117, 5, 233, 142, 217, 59, 233, - 115, 39, 89, 5, 231, 209, 234, 237, 233, 115, 39, 89, 117, 5, 40, 229, - 82, 39, 89, 117, 5, 121, 191, 39, 89, 117, 5, 125, 223, 142, 177, 121, - 191, 39, 89, 117, 5, 186, 39, 89, 117, 5, 252, 199, 39, 89, 117, 5, 206, - 39, 89, 5, 222, 12, 39, 89, 25, 5, 61, 39, 89, 25, 5, 231, 209, 221, 228, - 39, 89, 25, 5, 255, 82, 39, 89, 25, 5, 217, 65, 255, 82, 39, 89, 25, 5, - 74, 39, 89, 25, 5, 236, 40, 39, 89, 25, 5, 214, 214, 39, 89, 25, 5, 214, - 117, 39, 89, 25, 5, 69, 39, 89, 25, 5, 214, 118, 39, 89, 25, 5, 78, 39, - 89, 25, 5, 227, 5, 51, 39, 89, 25, 5, 226, 113, 39, 89, 25, 5, 76, 39, - 89, 25, 5, 254, 252, 39, 89, 25, 5, 226, 187, 39, 89, 25, 5, 254, 210, - 39, 89, 25, 5, 89, 254, 210, 39, 89, 25, 5, 227, 5, 48, 39, 89, 5, 231, - 209, 234, 236, 39, 89, 5, 216, 30, 39, 89, 5, 216, 29, 39, 89, 5, 234, - 103, 216, 28, 39, 89, 5, 234, 103, 216, 27, 39, 89, 5, 234, 103, 216, 26, - 39, 89, 5, 223, 191, 242, 52, 39, 89, 5, 231, 209, 221, 255, 39, 89, 5, - 234, 102, 234, 221, 39, 89, 38, 249, 123, 247, 128, 39, 89, 241, 53, 21, - 210, 86, 39, 89, 241, 53, 21, 111, 39, 89, 241, 53, 21, 105, 39, 89, 241, - 53, 21, 158, 39, 89, 241, 53, 21, 161, 39, 89, 241, 53, 21, 190, 39, 89, - 241, 53, 21, 195, 39, 89, 241, 53, 21, 199, 39, 89, 241, 53, 21, 196, 39, - 89, 241, 53, 21, 201, 39, 89, 89, 21, 210, 86, 39, 89, 89, 21, 111, 39, - 89, 89, 21, 105, 39, 89, 89, 21, 158, 39, 89, 89, 21, 161, 39, 89, 89, - 21, 190, 39, 89, 89, 21, 195, 39, 89, 89, 21, 199, 39, 89, 89, 21, 196, - 39, 89, 89, 21, 201, 39, 89, 5, 211, 249, 39, 89, 5, 211, 248, 39, 89, 5, - 221, 217, 39, 89, 5, 234, 166, 39, 89, 5, 240, 239, 39, 89, 5, 247, 142, - 39, 89, 5, 223, 52, 222, 189, 223, 152, 39, 89, 5, 231, 209, 211, 72, 39, - 89, 5, 235, 12, 39, 89, 5, 235, 11, 39, 89, 5, 221, 224, 39, 89, 5, 221, - 223, 39, 89, 5, 242, 16, 39, 89, 5, 251, 38, 102, 5, 214, 200, 223, 33, - 102, 5, 214, 200, 251, 9, 102, 5, 250, 194, 102, 5, 218, 16, 102, 5, 251, - 241, 102, 1, 254, 193, 102, 1, 254, 194, 217, 14, 102, 1, 236, 36, 102, - 1, 236, 37, 217, 14, 102, 1, 214, 203, 102, 1, 214, 204, 217, 14, 102, 1, - 223, 191, 223, 82, 102, 1, 223, 191, 223, 83, 217, 14, 102, 1, 233, 142, - 233, 30, 102, 1, 233, 142, 233, 31, 217, 14, 102, 1, 245, 187, 102, 1, - 254, 208, 102, 1, 226, 216, 102, 1, 226, 217, 217, 14, 102, 1, 176, 102, - 1, 235, 19, 231, 212, 102, 1, 243, 142, 102, 1, 243, 143, 242, 168, 102, - 1, 229, 82, 102, 1, 251, 41, 102, 1, 251, 42, 233, 129, 102, 1, 235, 147, - 102, 1, 235, 148, 235, 124, 102, 1, 227, 169, 102, 1, 217, 107, 233, 82, - 102, 1, 217, 107, 230, 72, 231, 212, 102, 1, 248, 230, 230, 72, 254, 153, - 102, 1, 248, 230, 230, 72, 231, 212, 102, 1, 229, 234, 223, 155, 102, 1, - 217, 106, 102, 1, 217, 107, 217, 36, 102, 1, 248, 229, 102, 1, 248, 230, - 231, 230, 102, 1, 198, 102, 1, 191, 102, 1, 226, 94, 234, 232, 102, 1, - 252, 199, 102, 1, 252, 200, 234, 178, 102, 1, 186, 102, 1, 192, 102, 1, - 205, 102, 1, 233, 141, 102, 1, 212, 65, 102, 1, 222, 36, 222, 22, 102, 1, - 222, 36, 221, 235, 102, 1, 206, 102, 1, 162, 102, 5, 223, 73, 102, 25, 5, - 217, 14, 102, 25, 5, 214, 199, 102, 25, 5, 214, 200, 221, 231, 102, 25, - 5, 218, 48, 102, 25, 5, 218, 49, 236, 28, 102, 25, 5, 223, 191, 223, 82, - 102, 25, 5, 223, 191, 223, 83, 217, 14, 102, 25, 5, 233, 142, 233, 30, - 102, 25, 5, 233, 142, 233, 31, 217, 14, 102, 25, 5, 217, 66, 102, 25, 5, - 217, 67, 223, 82, 102, 25, 5, 217, 67, 217, 14, 102, 25, 5, 217, 67, 223, - 83, 217, 14, 102, 25, 5, 225, 187, 102, 25, 5, 225, 188, 217, 14, 102, - 255, 3, 255, 2, 102, 1, 235, 1, 221, 230, 102, 1, 234, 108, 221, 230, - 102, 1, 215, 34, 221, 230, 102, 1, 245, 211, 221, 230, 102, 1, 214, 0, - 221, 230, 102, 1, 210, 107, 221, 230, 102, 1, 253, 217, 221, 230, 102, - 21, 210, 86, 102, 21, 111, 102, 21, 105, 102, 21, 158, 102, 21, 161, 102, - 21, 190, 102, 21, 195, 102, 21, 199, 102, 21, 196, 102, 21, 201, 102, - 226, 33, 102, 226, 59, 102, 211, 238, 102, 250, 244, 226, 52, 102, 250, - 244, 219, 174, 102, 250, 244, 226, 6, 102, 226, 58, 102, 28, 16, 247, - 134, 102, 28, 16, 248, 59, 102, 28, 16, 246, 72, 102, 28, 16, 248, 184, - 102, 28, 16, 248, 185, 218, 16, 102, 28, 16, 247, 213, 102, 28, 16, 248, - 222, 102, 28, 16, 248, 41, 102, 28, 16, 248, 206, 102, 28, 16, 248, 185, - 243, 64, 102, 28, 16, 38, 217, 10, 102, 28, 16, 38, 245, 149, 102, 28, - 16, 38, 234, 173, 102, 28, 16, 38, 234, 175, 102, 28, 16, 38, 235, 128, - 102, 28, 16, 38, 234, 174, 2, 235, 128, 102, 28, 16, 38, 234, 176, 2, - 235, 128, 102, 28, 16, 38, 252, 45, 102, 28, 16, 38, 242, 172, 102, 28, - 16, 222, 252, 204, 246, 82, 102, 28, 16, 222, 252, 204, 248, 220, 102, - 28, 16, 222, 252, 250, 8, 215, 112, 102, 28, 16, 222, 252, 250, 8, 217, - 74, 102, 28, 16, 233, 50, 204, 226, 47, 102, 28, 16, 233, 50, 204, 224, - 142, 102, 28, 16, 233, 50, 250, 8, 225, 41, 102, 28, 16, 233, 50, 250, 8, - 225, 29, 102, 28, 16, 233, 50, 204, 225, 64, 207, 5, 226, 30, 207, 5, - 226, 43, 207, 5, 226, 39, 207, 1, 61, 207, 1, 74, 207, 1, 69, 207, 1, - 254, 252, 207, 1, 78, 207, 1, 76, 207, 1, 245, 63, 207, 1, 176, 207, 1, - 224, 91, 207, 1, 243, 142, 207, 1, 229, 82, 207, 1, 251, 41, 207, 1, 235, - 147, 207, 1, 210, 116, 207, 1, 227, 169, 207, 1, 217, 106, 207, 1, 248, - 229, 207, 1, 198, 207, 1, 191, 207, 1, 244, 204, 207, 1, 214, 27, 207, 1, - 252, 199, 207, 1, 186, 207, 1, 192, 207, 1, 205, 207, 1, 233, 141, 207, - 1, 212, 65, 207, 1, 206, 207, 1, 211, 165, 207, 1, 162, 207, 117, 5, 226, - 56, 207, 117, 5, 226, 32, 207, 117, 5, 226, 29, 207, 25, 5, 226, 46, 207, - 25, 5, 226, 28, 207, 25, 5, 226, 50, 207, 25, 5, 226, 38, 207, 25, 5, - 226, 57, 207, 25, 5, 226, 48, 207, 5, 226, 60, 207, 5, 213, 152, 207, - 117, 5, 225, 252, 186, 207, 117, 5, 225, 252, 212, 65, 207, 1, 234, 138, - 207, 1, 217, 232, 207, 21, 210, 86, 207, 21, 111, 207, 21, 105, 207, 21, - 158, 207, 21, 161, 207, 21, 190, 207, 21, 195, 207, 21, 199, 207, 21, - 196, 207, 21, 201, 207, 253, 183, 207, 1, 223, 55, 207, 1, 233, 13, 207, - 1, 252, 26, 207, 1, 40, 235, 29, 207, 1, 40, 194, 252, 128, 1, 61, 252, - 128, 1, 219, 166, 61, 252, 128, 1, 162, 252, 128, 1, 219, 166, 162, 252, - 128, 1, 231, 186, 162, 252, 128, 1, 252, 199, 252, 128, 1, 234, 218, 252, - 199, 252, 128, 1, 191, 252, 128, 1, 219, 166, 191, 252, 128, 1, 198, 252, - 128, 1, 231, 186, 198, 252, 128, 1, 212, 65, 252, 128, 1, 219, 166, 212, - 65, 252, 128, 1, 226, 71, 212, 65, 252, 128, 1, 243, 142, 252, 128, 1, - 219, 166, 243, 142, 252, 128, 1, 235, 147, 252, 128, 1, 248, 229, 252, - 128, 1, 205, 252, 128, 1, 219, 166, 205, 252, 128, 1, 186, 252, 128, 1, - 219, 166, 186, 252, 128, 1, 219, 28, 217, 106, 252, 128, 1, 228, 60, 217, - 106, 252, 128, 1, 206, 252, 128, 1, 219, 166, 206, 252, 128, 1, 231, 186, - 206, 252, 128, 1, 192, 252, 128, 1, 219, 166, 192, 252, 128, 1, 229, 82, - 252, 128, 1, 233, 141, 252, 128, 1, 219, 166, 233, 141, 252, 128, 1, 227, - 169, 252, 128, 1, 251, 41, 252, 128, 1, 229, 153, 252, 128, 1, 231, 129, - 252, 128, 1, 74, 252, 128, 1, 69, 252, 128, 5, 216, 34, 252, 128, 25, 5, - 76, 252, 128, 25, 5, 226, 71, 76, 252, 128, 25, 5, 245, 217, 252, 128, - 25, 5, 74, 252, 128, 25, 5, 234, 218, 74, 252, 128, 25, 5, 78, 252, 128, - 25, 5, 234, 218, 78, 252, 128, 25, 5, 69, 252, 128, 25, 5, 104, 31, 219, - 166, 206, 252, 128, 117, 5, 229, 84, 252, 128, 117, 5, 242, 67, 252, 128, - 226, 41, 252, 128, 226, 37, 252, 128, 16, 251, 249, 229, 234, 231, 42, - 252, 128, 16, 251, 249, 225, 67, 252, 128, 16, 251, 249, 235, 54, 252, - 128, 16, 251, 249, 226, 41, 197, 1, 176, 197, 1, 234, 45, 197, 1, 234, - 138, 197, 1, 243, 142, 197, 1, 242, 193, 197, 1, 229, 82, 197, 1, 251, - 41, 197, 1, 250, 165, 197, 1, 235, 147, 197, 1, 227, 169, 197, 1, 217, - 106, 197, 1, 216, 209, 197, 1, 248, 229, 197, 1, 198, 197, 1, 191, 197, - 1, 225, 45, 197, 1, 225, 150, 197, 1, 244, 204, 197, 1, 244, 83, 197, 1, - 252, 199, 197, 1, 251, 230, 197, 1, 186, 197, 1, 230, 173, 197, 1, 215, - 184, 197, 1, 215, 176, 197, 1, 246, 46, 197, 1, 192, 197, 1, 205, 197, 1, - 233, 141, 197, 1, 162, 197, 1, 241, 160, 197, 1, 214, 27, 197, 1, 206, - 197, 1, 220, 104, 197, 1, 212, 65, 197, 1, 61, 197, 218, 74, 1, 192, 197, - 218, 74, 1, 205, 197, 25, 5, 255, 82, 197, 25, 5, 74, 197, 25, 5, 78, - 197, 25, 5, 226, 187, 197, 25, 5, 69, 197, 25, 5, 214, 118, 197, 25, 5, - 76, 197, 117, 5, 235, 29, 197, 117, 5, 194, 197, 117, 5, 156, 197, 117, - 5, 230, 30, 197, 117, 5, 226, 109, 197, 117, 5, 153, 197, 117, 5, 217, - 153, 197, 117, 5, 227, 146, 197, 117, 5, 234, 236, 197, 5, 223, 153, 197, - 5, 227, 209, 197, 224, 144, 217, 104, 197, 224, 144, 227, 156, 216, 121, - 217, 104, 197, 224, 144, 250, 172, 197, 224, 144, 215, 171, 250, 172, - 197, 224, 144, 215, 170, 197, 21, 210, 86, 197, 21, 111, 197, 21, 105, - 197, 21, 158, 197, 21, 161, 197, 21, 190, 197, 21, 195, 197, 21, 199, - 197, 21, 196, 197, 21, 201, 197, 1, 215, 157, 197, 1, 215, 145, 197, 1, - 248, 143, 226, 214, 250, 111, 21, 210, 86, 226, 214, 250, 111, 21, 111, - 226, 214, 250, 111, 21, 105, 226, 214, 250, 111, 21, 158, 226, 214, 250, - 111, 21, 161, 226, 214, 250, 111, 21, 190, 226, 214, 250, 111, 21, 195, - 226, 214, 250, 111, 21, 199, 226, 214, 250, 111, 21, 196, 226, 214, 250, - 111, 21, 201, 226, 214, 250, 111, 1, 233, 141, 226, 214, 250, 111, 1, - 253, 214, 226, 214, 250, 111, 1, 254, 225, 226, 214, 250, 111, 1, 254, - 123, 226, 214, 250, 111, 1, 254, 187, 226, 214, 250, 111, 1, 233, 140, - 226, 214, 250, 111, 1, 255, 44, 226, 214, 250, 111, 1, 255, 45, 226, 214, - 250, 111, 1, 255, 43, 226, 214, 250, 111, 1, 255, 38, 226, 214, 250, 111, - 1, 232, 247, 226, 214, 250, 111, 1, 235, 178, 226, 214, 250, 111, 1, 236, - 41, 226, 214, 250, 111, 1, 235, 197, 226, 214, 250, 111, 1, 235, 186, - 226, 214, 250, 111, 1, 232, 103, 226, 214, 250, 111, 1, 214, 221, 226, - 214, 250, 111, 1, 214, 219, 226, 214, 250, 111, 1, 214, 168, 226, 214, - 250, 111, 1, 214, 111, 226, 214, 250, 111, 1, 233, 64, 226, 214, 250, - 111, 1, 245, 116, 226, 214, 250, 111, 1, 245, 220, 226, 214, 250, 111, 1, - 245, 158, 226, 214, 250, 111, 1, 245, 94, 226, 214, 250, 111, 1, 232, - 162, 226, 214, 250, 111, 1, 226, 141, 226, 214, 250, 111, 1, 227, 0, 226, - 214, 250, 111, 1, 226, 129, 226, 214, 250, 111, 1, 226, 226, 226, 214, - 250, 111, 230, 108, 215, 122, 226, 214, 250, 111, 243, 137, 215, 123, - 226, 214, 250, 111, 230, 106, 215, 123, 226, 214, 250, 111, 223, 95, 226, - 214, 250, 111, 225, 148, 226, 214, 250, 111, 254, 217, 226, 214, 250, - 111, 224, 144, 230, 103, 226, 214, 250, 111, 224, 144, 52, 230, 103, 207, - 224, 144, 251, 249, 218, 9, 207, 224, 144, 251, 249, 226, 42, 207, 224, - 144, 251, 249, 224, 132, 207, 224, 144, 251, 249, 251, 27, 207, 224, 144, - 251, 249, 233, 14, 221, 227, 207, 224, 144, 251, 249, 235, 19, 221, 227, - 207, 224, 144, 251, 249, 248, 230, 221, 227, 207, 224, 144, 251, 249, - 252, 200, 221, 227, 213, 252, 138, 234, 216, 213, 252, 138, 220, 79, 213, - 252, 138, 224, 201, 213, 252, 5, 228, 214, 213, 252, 5, 211, 80, 230, - 227, 218, 1, 213, 252, 138, 211, 80, 254, 222, 235, 250, 218, 1, 213, - 252, 138, 211, 80, 235, 250, 218, 1, 213, 252, 138, 211, 80, 234, 204, - 235, 250, 218, 1, 213, 252, 138, 251, 10, 51, 213, 252, 138, 211, 80, - 234, 204, 235, 250, 218, 2, 221, 199, 213, 252, 138, 52, 218, 1, 213, - 252, 138, 215, 212, 218, 1, 213, 252, 138, 234, 204, 254, 85, 213, 252, - 138, 59, 51, 213, 252, 138, 113, 170, 51, 213, 252, 138, 134, 170, 51, - 213, 252, 138, 222, 243, 234, 215, 235, 250, 218, 1, 213, 252, 138, 253, - 212, 235, 250, 218, 1, 213, 252, 5, 213, 148, 218, 1, 213, 252, 5, 213, - 148, 214, 216, 213, 252, 5, 223, 52, 213, 148, 214, 216, 213, 252, 5, - 213, 148, 254, 85, 213, 252, 5, 223, 52, 213, 148, 254, 85, 213, 252, 5, - 213, 148, 214, 217, 2, 217, 78, 213, 252, 5, 213, 148, 254, 86, 2, 217, - 78, 213, 252, 5, 254, 84, 254, 99, 213, 252, 5, 254, 84, 252, 174, 213, - 252, 5, 254, 84, 214, 20, 213, 252, 5, 254, 84, 214, 21, 2, 217, 78, 213, - 252, 5, 216, 69, 213, 252, 5, 241, 198, 200, 254, 83, 213, 252, 5, 200, - 254, 83, 213, 252, 5, 222, 144, 200, 254, 83, 213, 252, 5, 254, 84, 214, - 223, 230, 95, 213, 252, 5, 254, 28, 213, 252, 5, 222, 189, 254, 28, 213, - 252, 138, 251, 10, 48, 213, 252, 5, 235, 108, 213, 252, 5, 214, 161, 7, - 1, 4, 6, 61, 7, 1, 4, 6, 254, 252, 7, 4, 1, 215, 94, 254, 252, 7, 1, 4, - 6, 252, 142, 253, 166, 7, 1, 4, 6, 251, 74, 7, 1, 4, 6, 249, 68, 7, 1, 4, - 6, 245, 67, 7, 1, 4, 6, 76, 7, 4, 1, 215, 94, 204, 76, 7, 4, 1, 215, 94, - 74, 7, 1, 4, 6, 235, 150, 7, 1, 4, 6, 235, 29, 7, 1, 4, 6, 233, 155, 2, - 91, 7, 1, 4, 6, 194, 7, 1, 4, 6, 223, 52, 230, 30, 7, 1, 4, 6, 78, 7, 1, - 4, 6, 204, 78, 7, 4, 1, 219, 189, 78, 7, 4, 1, 219, 189, 204, 78, 7, 4, - 1, 219, 189, 144, 2, 91, 7, 4, 1, 215, 94, 226, 238, 7, 1, 4, 6, 226, - 138, 7, 4, 1, 216, 15, 163, 78, 7, 4, 1, 251, 183, 163, 78, 7, 1, 4, 6, - 226, 109, 7, 1, 4, 6, 223, 52, 153, 7, 1, 4, 6, 215, 94, 153, 7, 1, 4, 6, - 217, 153, 7, 1, 4, 6, 69, 7, 4, 1, 219, 189, 69, 7, 4, 1, 219, 189, 248, - 8, 69, 7, 4, 1, 219, 189, 215, 94, 194, 7, 1, 4, 6, 214, 105, 7, 1, 4, 6, - 212, 98, 7, 1, 4, 6, 210, 159, 7, 1, 4, 6, 245, 16, 7, 1, 213, 135, 233, - 88, 218, 252, 7, 1, 254, 205, 26, 1, 4, 6, 243, 114, 26, 1, 4, 6, 233, - 104, 26, 1, 4, 6, 225, 111, 26, 1, 4, 6, 223, 40, 26, 1, 4, 6, 224, 164, - 33, 1, 4, 6, 245, 182, 58, 1, 6, 61, 58, 1, 6, 254, 252, 58, 1, 6, 253, - 166, 58, 1, 6, 252, 142, 253, 166, 58, 1, 6, 249, 68, 58, 1, 6, 76, 58, - 1, 6, 223, 52, 76, 58, 1, 6, 243, 209, 58, 1, 6, 242, 67, 58, 1, 6, 74, - 58, 1, 6, 235, 150, 58, 1, 6, 235, 29, 58, 1, 6, 156, 58, 1, 6, 194, 58, - 1, 6, 230, 30, 58, 1, 6, 223, 52, 230, 30, 58, 1, 6, 78, 58, 1, 6, 226, - 138, 58, 1, 6, 226, 109, 58, 1, 6, 153, 58, 1, 6, 217, 153, 58, 1, 6, 69, - 58, 1, 6, 212, 98, 58, 1, 4, 61, 58, 1, 4, 215, 94, 61, 58, 1, 4, 254, - 151, 58, 1, 4, 215, 94, 254, 252, 58, 1, 4, 253, 166, 58, 1, 4, 249, 68, - 58, 1, 4, 76, 58, 1, 4, 221, 197, 58, 1, 4, 204, 76, 58, 1, 4, 215, 94, - 204, 76, 58, 1, 4, 243, 209, 58, 1, 4, 215, 94, 74, 58, 1, 4, 235, 29, - 58, 1, 4, 194, 58, 1, 4, 245, 146, 58, 1, 4, 78, 58, 1, 4, 204, 78, 58, - 1, 4, 216, 15, 163, 78, 58, 1, 4, 251, 183, 163, 78, 58, 1, 4, 226, 109, - 58, 1, 4, 217, 153, 58, 1, 4, 69, 58, 1, 4, 219, 189, 69, 58, 1, 4, 215, - 94, 194, 58, 1, 4, 214, 105, 58, 1, 4, 254, 205, 58, 1, 4, 252, 34, 58, - 1, 4, 26, 243, 114, 58, 1, 4, 248, 62, 58, 1, 4, 26, 225, 136, 58, 1, 4, - 250, 118, 7, 218, 66, 4, 1, 74, 7, 218, 66, 4, 1, 153, 7, 218, 66, 4, 1, - 69, 7, 218, 66, 4, 1, 214, 105, 26, 218, 66, 4, 1, 252, 34, 26, 218, 66, - 4, 1, 243, 114, 26, 218, 66, 4, 1, 223, 40, 26, 218, 66, 4, 1, 225, 136, - 26, 218, 66, 4, 1, 250, 118, 7, 4, 1, 214, 214, 7, 4, 1, 57, 2, 230, 229, - 184, 7, 4, 1, 249, 69, 2, 230, 229, 184, 7, 4, 1, 245, 15, 2, 230, 229, - 184, 7, 4, 1, 232, 55, 2, 230, 229, 184, 7, 4, 1, 230, 31, 2, 230, 229, - 184, 7, 4, 1, 226, 110, 2, 230, 229, 184, 7, 4, 1, 223, 227, 2, 230, 229, - 184, 7, 4, 1, 223, 227, 2, 244, 96, 22, 230, 229, 184, 7, 4, 1, 222, 94, - 2, 230, 229, 184, 7, 4, 1, 217, 154, 2, 230, 229, 184, 7, 4, 1, 210, 160, - 2, 230, 229, 184, 7, 4, 1, 215, 94, 243, 209, 58, 1, 33, 245, 158, 7, 4, - 1, 235, 220, 243, 209, 7, 4, 1, 216, 212, 2, 218, 109, 7, 4, 6, 1, 240, - 161, 2, 91, 7, 4, 1, 235, 193, 2, 91, 7, 4, 1, 226, 110, 2, 91, 7, 4, 6, - 1, 104, 2, 91, 7, 4, 1, 214, 158, 2, 91, 7, 4, 1, 57, 2, 226, 70, 103, 7, - 4, 1, 249, 69, 2, 226, 70, 103, 7, 4, 1, 245, 15, 2, 226, 70, 103, 7, 4, - 1, 243, 210, 2, 226, 70, 103, 7, 4, 1, 235, 30, 2, 226, 70, 103, 7, 4, 1, - 233, 155, 2, 226, 70, 103, 7, 4, 1, 232, 55, 2, 226, 70, 103, 7, 4, 1, - 230, 31, 2, 226, 70, 103, 7, 4, 1, 226, 110, 2, 226, 70, 103, 7, 4, 1, - 223, 227, 2, 226, 70, 103, 7, 4, 1, 222, 94, 2, 226, 70, 103, 7, 4, 1, - 245, 84, 2, 226, 70, 103, 7, 4, 1, 214, 106, 2, 226, 70, 103, 7, 4, 1, - 211, 179, 2, 226, 70, 103, 7, 4, 1, 210, 160, 2, 226, 70, 103, 7, 4, 1, - 116, 2, 223, 58, 103, 7, 4, 1, 254, 152, 2, 223, 58, 103, 7, 4, 1, 249, - 69, 2, 241, 59, 22, 217, 78, 7, 4, 1, 160, 2, 223, 58, 103, 7, 4, 1, 204, - 160, 2, 223, 58, 103, 7, 4, 1, 223, 52, 204, 160, 2, 223, 58, 103, 7, 4, - 1, 221, 198, 2, 223, 58, 103, 7, 4, 1, 240, 161, 2, 223, 58, 103, 7, 4, - 1, 204, 144, 2, 223, 58, 103, 7, 4, 1, 245, 84, 2, 223, 58, 103, 7, 4, 1, - 104, 2, 223, 58, 103, 7, 4, 1, 245, 17, 2, 223, 58, 103, 58, 1, 4, 215, - 94, 254, 151, 58, 1, 4, 251, 74, 58, 1, 4, 251, 75, 2, 249, 108, 58, 1, - 4, 245, 67, 58, 1, 4, 223, 52, 204, 76, 58, 1, 4, 245, 14, 58, 1, 4, 247, - 127, 235, 151, 2, 91, 58, 1, 4, 119, 243, 209, 58, 1, 4, 215, 94, 242, - 67, 58, 1, 4, 240, 161, 2, 91, 58, 1, 4, 235, 192, 58, 1, 4, 6, 74, 58, - 1, 4, 6, 240, 161, 2, 91, 58, 1, 4, 235, 151, 2, 249, 135, 58, 1, 4, 233, - 155, 2, 223, 58, 103, 58, 1, 4, 233, 155, 2, 226, 70, 103, 58, 1, 4, 6, - 156, 58, 1, 4, 232, 55, 2, 103, 58, 1, 4, 215, 94, 232, 55, 2, 200, 233, - 42, 58, 1, 4, 230, 31, 2, 43, 103, 58, 1, 4, 230, 31, 2, 223, 58, 103, - 58, 1, 4, 6, 230, 30, 58, 1, 4, 252, 142, 78, 58, 1, 4, 225, 136, 58, 1, - 4, 222, 94, 2, 103, 58, 1, 4, 245, 83, 58, 1, 4, 217, 154, 2, 226, 70, - 103, 58, 1, 4, 104, 130, 58, 1, 4, 214, 157, 58, 1, 4, 6, 69, 58, 1, 4, - 214, 106, 2, 103, 58, 1, 4, 215, 94, 214, 105, 58, 1, 4, 210, 159, 58, 1, - 4, 210, 160, 2, 223, 58, 103, 58, 1, 4, 210, 160, 2, 249, 108, 58, 1, 4, - 245, 16, 58, 1, 4, 216, 180, 38, 246, 126, 242, 144, 255, 23, 38, 246, - 126, 255, 12, 255, 23, 38, 219, 71, 51, 38, 218, 7, 79, 38, 231, 236, 38, - 242, 141, 38, 231, 234, 38, 255, 10, 38, 242, 142, 38, 255, 11, 38, 7, 4, - 1, 223, 227, 51, 38, 251, 153, 38, 231, 235, 38, 52, 250, 39, 48, 38, - 226, 229, 48, 38, 210, 35, 51, 38, 235, 179, 51, 38, 214, 151, 48, 38, - 214, 134, 48, 38, 7, 4, 1, 244, 71, 204, 116, 48, 38, 7, 4, 1, 254, 252, - 38, 7, 4, 1, 254, 81, 38, 7, 4, 1, 253, 184, 38, 7, 4, 1, 251, 75, 250, - 191, 38, 7, 4, 1, 235, 220, 249, 68, 38, 7, 4, 1, 245, 67, 38, 7, 4, 1, - 243, 209, 38, 7, 1, 4, 6, 243, 209, 38, 7, 4, 1, 235, 29, 38, 7, 4, 1, - 156, 38, 7, 1, 4, 6, 156, 38, 7, 1, 4, 6, 194, 38, 7, 4, 1, 230, 30, 38, - 7, 1, 4, 6, 230, 30, 38, 7, 1, 4, 6, 153, 38, 7, 4, 1, 223, 227, 222, - 188, 38, 7, 4, 1, 222, 93, 38, 7, 4, 1, 200, 222, 93, 38, 7, 4, 1, 210, - 159, 38, 52, 235, 200, 251, 155, 51, 38, 254, 156, 128, 216, 43, 51, 38, - 43, 254, 2, 48, 38, 44, 254, 2, 22, 124, 254, 2, 51, 7, 6, 1, 116, 2, - 222, 237, 51, 7, 4, 1, 116, 2, 222, 237, 51, 7, 6, 1, 57, 2, 59, 48, 7, - 4, 1, 57, 2, 59, 48, 7, 6, 1, 57, 2, 59, 51, 7, 4, 1, 57, 2, 59, 51, 7, - 6, 1, 57, 2, 232, 220, 51, 7, 4, 1, 57, 2, 232, 220, 51, 7, 6, 1, 251, - 75, 2, 250, 192, 22, 142, 7, 4, 1, 251, 75, 2, 250, 192, 22, 142, 7, 6, - 1, 249, 69, 2, 59, 48, 7, 4, 1, 249, 69, 2, 59, 48, 7, 6, 1, 249, 69, 2, - 59, 51, 7, 4, 1, 249, 69, 2, 59, 51, 7, 6, 1, 249, 69, 2, 232, 220, 51, - 7, 4, 1, 249, 69, 2, 232, 220, 51, 7, 6, 1, 249, 69, 2, 250, 191, 7, 4, - 1, 249, 69, 2, 250, 191, 7, 6, 1, 249, 69, 2, 250, 39, 51, 7, 4, 1, 249, - 69, 2, 250, 39, 51, 7, 6, 1, 160, 2, 231, 238, 22, 242, 143, 7, 4, 1, - 160, 2, 231, 238, 22, 242, 143, 7, 6, 1, 160, 2, 231, 238, 22, 142, 7, 4, - 1, 160, 2, 231, 238, 22, 142, 7, 6, 1, 160, 2, 250, 39, 51, 7, 4, 1, 160, - 2, 250, 39, 51, 7, 6, 1, 160, 2, 216, 90, 51, 7, 4, 1, 160, 2, 216, 90, - 51, 7, 6, 1, 160, 2, 250, 192, 22, 251, 154, 7, 4, 1, 160, 2, 250, 192, - 22, 251, 154, 7, 6, 1, 245, 15, 2, 59, 48, 7, 4, 1, 245, 15, 2, 59, 48, - 7, 6, 1, 243, 210, 2, 231, 237, 7, 4, 1, 243, 210, 2, 231, 237, 7, 6, 1, - 242, 68, 2, 59, 48, 7, 4, 1, 242, 68, 2, 59, 48, 7, 6, 1, 242, 68, 2, 59, - 51, 7, 4, 1, 242, 68, 2, 59, 51, 7, 6, 1, 242, 68, 2, 248, 9, 7, 4, 1, - 242, 68, 2, 248, 9, 7, 6, 1, 242, 68, 2, 250, 191, 7, 4, 1, 242, 68, 2, - 250, 191, 7, 6, 1, 242, 68, 2, 251, 155, 51, 7, 4, 1, 242, 68, 2, 251, - 155, 51, 7, 6, 1, 240, 161, 2, 216, 90, 51, 7, 4, 1, 240, 161, 2, 216, - 90, 51, 7, 6, 1, 240, 161, 2, 248, 10, 22, 142, 7, 4, 1, 240, 161, 2, - 248, 10, 22, 142, 7, 6, 1, 235, 30, 2, 142, 7, 4, 1, 235, 30, 2, 142, 7, - 6, 1, 235, 30, 2, 59, 51, 7, 4, 1, 235, 30, 2, 59, 51, 7, 6, 1, 235, 30, - 2, 232, 220, 51, 7, 4, 1, 235, 30, 2, 232, 220, 51, 7, 6, 1, 233, 155, 2, - 59, 51, 7, 4, 1, 233, 155, 2, 59, 51, 7, 6, 1, 233, 155, 2, 59, 252, 51, - 22, 231, 237, 7, 4, 1, 233, 155, 2, 59, 252, 51, 22, 231, 237, 7, 6, 1, - 233, 155, 2, 232, 220, 51, 7, 4, 1, 233, 155, 2, 232, 220, 51, 7, 6, 1, - 233, 155, 2, 250, 39, 51, 7, 4, 1, 233, 155, 2, 250, 39, 51, 7, 6, 1, - 232, 55, 2, 142, 7, 4, 1, 232, 55, 2, 142, 7, 6, 1, 232, 55, 2, 59, 48, - 7, 4, 1, 232, 55, 2, 59, 48, 7, 6, 1, 232, 55, 2, 59, 51, 7, 4, 1, 232, - 55, 2, 59, 51, 7, 6, 1, 230, 31, 2, 59, 48, 7, 4, 1, 230, 31, 2, 59, 48, - 7, 6, 1, 230, 31, 2, 59, 51, 7, 4, 1, 230, 31, 2, 59, 51, 7, 6, 1, 230, - 31, 2, 232, 220, 51, 7, 4, 1, 230, 31, 2, 232, 220, 51, 7, 6, 1, 230, 31, - 2, 250, 39, 51, 7, 4, 1, 230, 31, 2, 250, 39, 51, 7, 6, 1, 144, 2, 216, - 90, 22, 142, 7, 4, 1, 144, 2, 216, 90, 22, 142, 7, 6, 1, 144, 2, 216, 90, - 22, 248, 9, 7, 4, 1, 144, 2, 216, 90, 22, 248, 9, 7, 6, 1, 144, 2, 231, - 238, 22, 242, 143, 7, 4, 1, 144, 2, 231, 238, 22, 242, 143, 7, 6, 1, 144, - 2, 231, 238, 22, 142, 7, 4, 1, 144, 2, 231, 238, 22, 142, 7, 6, 1, 226, - 110, 2, 142, 7, 4, 1, 226, 110, 2, 142, 7, 6, 1, 226, 110, 2, 59, 48, 7, - 4, 1, 226, 110, 2, 59, 48, 7, 6, 1, 223, 227, 2, 59, 48, 7, 4, 1, 223, - 227, 2, 59, 48, 7, 6, 1, 223, 227, 2, 59, 51, 7, 4, 1, 223, 227, 2, 59, - 51, 7, 6, 1, 223, 227, 2, 59, 252, 51, 22, 231, 237, 7, 4, 1, 223, 227, - 2, 59, 252, 51, 22, 231, 237, 7, 6, 1, 223, 227, 2, 232, 220, 51, 7, 4, - 1, 223, 227, 2, 232, 220, 51, 7, 6, 1, 222, 94, 2, 59, 48, 7, 4, 1, 222, - 94, 2, 59, 48, 7, 6, 1, 222, 94, 2, 59, 51, 7, 4, 1, 222, 94, 2, 59, 51, - 7, 6, 1, 222, 94, 2, 255, 12, 22, 59, 48, 7, 4, 1, 222, 94, 2, 255, 12, - 22, 59, 48, 7, 6, 1, 222, 94, 2, 250, 243, 22, 59, 48, 7, 4, 1, 222, 94, - 2, 250, 243, 22, 59, 48, 7, 6, 1, 222, 94, 2, 59, 252, 51, 22, 59, 48, 7, - 4, 1, 222, 94, 2, 59, 252, 51, 22, 59, 48, 7, 6, 1, 217, 154, 2, 59, 48, - 7, 4, 1, 217, 154, 2, 59, 48, 7, 6, 1, 217, 154, 2, 59, 51, 7, 4, 1, 217, - 154, 2, 59, 51, 7, 6, 1, 217, 154, 2, 232, 220, 51, 7, 4, 1, 217, 154, 2, - 232, 220, 51, 7, 6, 1, 217, 154, 2, 250, 39, 51, 7, 4, 1, 217, 154, 2, - 250, 39, 51, 7, 6, 1, 104, 2, 248, 10, 51, 7, 4, 1, 104, 2, 248, 10, 51, - 7, 6, 1, 104, 2, 216, 90, 51, 7, 4, 1, 104, 2, 216, 90, 51, 7, 6, 1, 104, - 2, 250, 39, 51, 7, 4, 1, 104, 2, 250, 39, 51, 7, 6, 1, 104, 2, 216, 90, - 22, 142, 7, 4, 1, 104, 2, 216, 90, 22, 142, 7, 6, 1, 104, 2, 231, 238, - 22, 248, 9, 7, 4, 1, 104, 2, 231, 238, 22, 248, 9, 7, 6, 1, 214, 106, 2, - 184, 7, 4, 1, 214, 106, 2, 184, 7, 6, 1, 214, 106, 2, 59, 51, 7, 4, 1, - 214, 106, 2, 59, 51, 7, 6, 1, 212, 99, 2, 242, 143, 7, 4, 1, 212, 99, 2, - 242, 143, 7, 6, 1, 212, 99, 2, 142, 7, 4, 1, 212, 99, 2, 142, 7, 6, 1, - 212, 99, 2, 248, 9, 7, 4, 1, 212, 99, 2, 248, 9, 7, 6, 1, 212, 99, 2, 59, - 48, 7, 4, 1, 212, 99, 2, 59, 48, 7, 6, 1, 212, 99, 2, 59, 51, 7, 4, 1, - 212, 99, 2, 59, 51, 7, 6, 1, 211, 179, 2, 59, 48, 7, 4, 1, 211, 179, 2, - 59, 48, 7, 6, 1, 211, 179, 2, 248, 9, 7, 4, 1, 211, 179, 2, 248, 9, 7, 6, - 1, 211, 118, 2, 59, 48, 7, 4, 1, 211, 118, 2, 59, 48, 7, 6, 1, 210, 160, - 2, 250, 38, 7, 4, 1, 210, 160, 2, 250, 38, 7, 6, 1, 210, 160, 2, 59, 51, - 7, 4, 1, 210, 160, 2, 59, 51, 7, 6, 1, 210, 160, 2, 232, 220, 51, 7, 4, - 1, 210, 160, 2, 232, 220, 51, 7, 4, 1, 242, 68, 2, 232, 220, 51, 7, 4, 1, - 217, 154, 2, 248, 9, 7, 4, 1, 212, 99, 2, 222, 237, 48, 7, 4, 1, 211, - 118, 2, 222, 237, 48, 7, 4, 1, 116, 2, 44, 163, 222, 236, 7, 4, 1, 200, - 222, 94, 2, 59, 48, 7, 4, 1, 200, 222, 94, 2, 248, 7, 91, 7, 4, 1, 200, - 222, 94, 2, 125, 91, 7, 6, 1, 220, 78, 222, 93, 7, 4, 1, 248, 62, 7, 6, - 1, 116, 2, 59, 51, 7, 4, 1, 116, 2, 59, 51, 7, 6, 1, 116, 2, 241, 59, 48, - 7, 4, 1, 116, 2, 241, 59, 48, 7, 6, 1, 116, 2, 250, 39, 22, 142, 7, 4, 1, - 116, 2, 250, 39, 22, 142, 7, 6, 1, 116, 2, 250, 39, 22, 242, 143, 7, 4, - 1, 116, 2, 250, 39, 22, 242, 143, 7, 6, 1, 116, 2, 250, 39, 22, 241, 59, - 48, 7, 4, 1, 116, 2, 250, 39, 22, 241, 59, 48, 7, 6, 1, 116, 2, 250, 39, - 22, 184, 7, 4, 1, 116, 2, 250, 39, 22, 184, 7, 6, 1, 116, 2, 250, 39, 22, - 59, 51, 7, 4, 1, 116, 2, 250, 39, 22, 59, 51, 7, 6, 1, 116, 2, 251, 155, - 22, 142, 7, 4, 1, 116, 2, 251, 155, 22, 142, 7, 6, 1, 116, 2, 251, 155, - 22, 242, 143, 7, 4, 1, 116, 2, 251, 155, 22, 242, 143, 7, 6, 1, 116, 2, - 251, 155, 22, 241, 59, 48, 7, 4, 1, 116, 2, 251, 155, 22, 241, 59, 48, 7, - 6, 1, 116, 2, 251, 155, 22, 184, 7, 4, 1, 116, 2, 251, 155, 22, 184, 7, - 6, 1, 116, 2, 251, 155, 22, 59, 51, 7, 4, 1, 116, 2, 251, 155, 22, 59, - 51, 7, 6, 1, 160, 2, 59, 51, 7, 4, 1, 160, 2, 59, 51, 7, 6, 1, 160, 2, - 241, 59, 48, 7, 4, 1, 160, 2, 241, 59, 48, 7, 6, 1, 160, 2, 184, 7, 4, 1, - 160, 2, 184, 7, 6, 1, 160, 2, 250, 39, 22, 142, 7, 4, 1, 160, 2, 250, 39, - 22, 142, 7, 6, 1, 160, 2, 250, 39, 22, 242, 143, 7, 4, 1, 160, 2, 250, - 39, 22, 242, 143, 7, 6, 1, 160, 2, 250, 39, 22, 241, 59, 48, 7, 4, 1, - 160, 2, 250, 39, 22, 241, 59, 48, 7, 6, 1, 160, 2, 250, 39, 22, 184, 7, - 4, 1, 160, 2, 250, 39, 22, 184, 7, 6, 1, 160, 2, 250, 39, 22, 59, 51, 7, - 4, 1, 160, 2, 250, 39, 22, 59, 51, 7, 6, 1, 240, 161, 2, 241, 59, 48, 7, - 4, 1, 240, 161, 2, 241, 59, 48, 7, 6, 1, 240, 161, 2, 59, 51, 7, 4, 1, - 240, 161, 2, 59, 51, 7, 6, 1, 144, 2, 59, 51, 7, 4, 1, 144, 2, 59, 51, 7, - 6, 1, 144, 2, 241, 59, 48, 7, 4, 1, 144, 2, 241, 59, 48, 7, 6, 1, 144, 2, - 250, 39, 22, 142, 7, 4, 1, 144, 2, 250, 39, 22, 142, 7, 6, 1, 144, 2, - 250, 39, 22, 242, 143, 7, 4, 1, 144, 2, 250, 39, 22, 242, 143, 7, 6, 1, - 144, 2, 250, 39, 22, 241, 59, 48, 7, 4, 1, 144, 2, 250, 39, 22, 241, 59, - 48, 7, 6, 1, 144, 2, 250, 39, 22, 184, 7, 4, 1, 144, 2, 250, 39, 22, 184, - 7, 6, 1, 144, 2, 250, 39, 22, 59, 51, 7, 4, 1, 144, 2, 250, 39, 22, 59, - 51, 7, 6, 1, 144, 2, 241, 0, 22, 142, 7, 4, 1, 144, 2, 241, 0, 22, 142, - 7, 6, 1, 144, 2, 241, 0, 22, 242, 143, 7, 4, 1, 144, 2, 241, 0, 22, 242, - 143, 7, 6, 1, 144, 2, 241, 0, 22, 241, 59, 48, 7, 4, 1, 144, 2, 241, 0, - 22, 241, 59, 48, 7, 6, 1, 144, 2, 241, 0, 22, 184, 7, 4, 1, 144, 2, 241, - 0, 22, 184, 7, 6, 1, 144, 2, 241, 0, 22, 59, 51, 7, 4, 1, 144, 2, 241, 0, - 22, 59, 51, 7, 6, 1, 104, 2, 59, 51, 7, 4, 1, 104, 2, 59, 51, 7, 6, 1, - 104, 2, 241, 59, 48, 7, 4, 1, 104, 2, 241, 59, 48, 7, 6, 1, 104, 2, 241, - 0, 22, 142, 7, 4, 1, 104, 2, 241, 0, 22, 142, 7, 6, 1, 104, 2, 241, 0, - 22, 242, 143, 7, 4, 1, 104, 2, 241, 0, 22, 242, 143, 7, 6, 1, 104, 2, - 241, 0, 22, 241, 59, 48, 7, 4, 1, 104, 2, 241, 0, 22, 241, 59, 48, 7, 6, - 1, 104, 2, 241, 0, 22, 184, 7, 4, 1, 104, 2, 241, 0, 22, 184, 7, 6, 1, - 104, 2, 241, 0, 22, 59, 51, 7, 4, 1, 104, 2, 241, 0, 22, 59, 51, 7, 6, 1, - 211, 118, 2, 242, 143, 7, 4, 1, 211, 118, 2, 242, 143, 7, 6, 1, 211, 118, - 2, 59, 51, 7, 4, 1, 211, 118, 2, 59, 51, 7, 6, 1, 211, 118, 2, 241, 59, - 48, 7, 4, 1, 211, 118, 2, 241, 59, 48, 7, 6, 1, 211, 118, 2, 184, 7, 4, - 1, 211, 118, 2, 184, 7, 6, 1, 230, 228, 232, 191, 7, 4, 1, 230, 228, 232, - 191, 7, 6, 1, 230, 228, 214, 105, 7, 4, 1, 230, 228, 214, 105, 7, 6, 1, - 211, 118, 2, 232, 129, 7, 4, 1, 211, 118, 2, 232, 129, 26, 4, 1, 254, - 152, 2, 224, 157, 26, 4, 1, 254, 152, 2, 248, 161, 26, 4, 1, 254, 152, 2, - 224, 158, 22, 214, 13, 26, 4, 1, 254, 152, 2, 248, 162, 22, 214, 13, 26, - 4, 1, 254, 152, 2, 224, 158, 22, 226, 114, 26, 4, 1, 254, 152, 2, 248, - 162, 22, 226, 114, 26, 4, 1, 254, 152, 2, 224, 158, 22, 225, 178, 26, 4, - 1, 254, 152, 2, 248, 162, 22, 225, 178, 26, 6, 1, 254, 152, 2, 224, 157, - 26, 6, 1, 254, 152, 2, 248, 161, 26, 6, 1, 254, 152, 2, 224, 158, 22, - 214, 13, 26, 6, 1, 254, 152, 2, 248, 162, 22, 214, 13, 26, 6, 1, 254, - 152, 2, 224, 158, 22, 226, 114, 26, 6, 1, 254, 152, 2, 248, 162, 22, 226, - 114, 26, 6, 1, 254, 152, 2, 224, 158, 22, 225, 178, 26, 6, 1, 254, 152, - 2, 248, 162, 22, 225, 178, 26, 4, 1, 245, 109, 2, 224, 157, 26, 4, 1, - 245, 109, 2, 248, 161, 26, 4, 1, 245, 109, 2, 224, 158, 22, 214, 13, 26, - 4, 1, 245, 109, 2, 248, 162, 22, 214, 13, 26, 4, 1, 245, 109, 2, 224, - 158, 22, 226, 114, 26, 4, 1, 245, 109, 2, 248, 162, 22, 226, 114, 26, 6, - 1, 245, 109, 2, 224, 157, 26, 6, 1, 245, 109, 2, 248, 161, 26, 6, 1, 245, - 109, 2, 224, 158, 22, 214, 13, 26, 6, 1, 245, 109, 2, 248, 162, 22, 214, - 13, 26, 6, 1, 245, 109, 2, 224, 158, 22, 226, 114, 26, 6, 1, 245, 109, 2, - 248, 162, 22, 226, 114, 26, 4, 1, 245, 72, 2, 224, 157, 26, 4, 1, 245, - 72, 2, 248, 161, 26, 4, 1, 245, 72, 2, 224, 158, 22, 214, 13, 26, 4, 1, - 245, 72, 2, 248, 162, 22, 214, 13, 26, 4, 1, 245, 72, 2, 224, 158, 22, - 226, 114, 26, 4, 1, 245, 72, 2, 248, 162, 22, 226, 114, 26, 4, 1, 245, - 72, 2, 224, 158, 22, 225, 178, 26, 4, 1, 245, 72, 2, 248, 162, 22, 225, - 178, 26, 6, 1, 245, 72, 2, 224, 157, 26, 6, 1, 245, 72, 2, 248, 161, 26, - 6, 1, 245, 72, 2, 224, 158, 22, 214, 13, 26, 6, 1, 245, 72, 2, 248, 162, - 22, 214, 13, 26, 6, 1, 245, 72, 2, 224, 158, 22, 226, 114, 26, 6, 1, 245, - 72, 2, 248, 162, 22, 226, 114, 26, 6, 1, 245, 72, 2, 224, 158, 22, 225, - 178, 26, 6, 1, 245, 72, 2, 248, 162, 22, 225, 178, 26, 4, 1, 235, 193, 2, - 224, 157, 26, 4, 1, 235, 193, 2, 248, 161, 26, 4, 1, 235, 193, 2, 224, - 158, 22, 214, 13, 26, 4, 1, 235, 193, 2, 248, 162, 22, 214, 13, 26, 4, 1, - 235, 193, 2, 224, 158, 22, 226, 114, 26, 4, 1, 235, 193, 2, 248, 162, 22, - 226, 114, 26, 4, 1, 235, 193, 2, 224, 158, 22, 225, 178, 26, 4, 1, 235, - 193, 2, 248, 162, 22, 225, 178, 26, 6, 1, 235, 193, 2, 224, 157, 26, 6, - 1, 235, 193, 2, 248, 161, 26, 6, 1, 235, 193, 2, 224, 158, 22, 214, 13, - 26, 6, 1, 235, 193, 2, 248, 162, 22, 214, 13, 26, 6, 1, 235, 193, 2, 224, - 158, 22, 226, 114, 26, 6, 1, 235, 193, 2, 248, 162, 22, 226, 114, 26, 6, - 1, 235, 193, 2, 224, 158, 22, 225, 178, 26, 6, 1, 235, 193, 2, 248, 162, - 22, 225, 178, 26, 4, 1, 226, 204, 2, 224, 157, 26, 4, 1, 226, 204, 2, - 248, 161, 26, 4, 1, 226, 204, 2, 224, 158, 22, 214, 13, 26, 4, 1, 226, - 204, 2, 248, 162, 22, 214, 13, 26, 4, 1, 226, 204, 2, 224, 158, 22, 226, - 114, 26, 4, 1, 226, 204, 2, 248, 162, 22, 226, 114, 26, 6, 1, 226, 204, - 2, 224, 157, 26, 6, 1, 226, 204, 2, 248, 161, 26, 6, 1, 226, 204, 2, 224, - 158, 22, 214, 13, 26, 6, 1, 226, 204, 2, 248, 162, 22, 214, 13, 26, 6, 1, - 226, 204, 2, 224, 158, 22, 226, 114, 26, 6, 1, 226, 204, 2, 248, 162, 22, - 226, 114, 26, 4, 1, 214, 158, 2, 224, 157, 26, 4, 1, 214, 158, 2, 248, - 161, 26, 4, 1, 214, 158, 2, 224, 158, 22, 214, 13, 26, 4, 1, 214, 158, 2, - 248, 162, 22, 214, 13, 26, 4, 1, 214, 158, 2, 224, 158, 22, 226, 114, 26, - 4, 1, 214, 158, 2, 248, 162, 22, 226, 114, 26, 4, 1, 214, 158, 2, 224, - 158, 22, 225, 178, 26, 4, 1, 214, 158, 2, 248, 162, 22, 225, 178, 26, 6, - 1, 214, 158, 2, 248, 161, 26, 6, 1, 214, 158, 2, 248, 162, 22, 214, 13, - 26, 6, 1, 214, 158, 2, 248, 162, 22, 226, 114, 26, 6, 1, 214, 158, 2, - 248, 162, 22, 225, 178, 26, 4, 1, 226, 206, 2, 224, 157, 26, 4, 1, 226, - 206, 2, 248, 161, 26, 4, 1, 226, 206, 2, 224, 158, 22, 214, 13, 26, 4, 1, - 226, 206, 2, 248, 162, 22, 214, 13, 26, 4, 1, 226, 206, 2, 224, 158, 22, - 226, 114, 26, 4, 1, 226, 206, 2, 248, 162, 22, 226, 114, 26, 4, 1, 226, - 206, 2, 224, 158, 22, 225, 178, 26, 4, 1, 226, 206, 2, 248, 162, 22, 225, - 178, 26, 6, 1, 226, 206, 2, 224, 157, 26, 6, 1, 226, 206, 2, 248, 161, - 26, 6, 1, 226, 206, 2, 224, 158, 22, 214, 13, 26, 6, 1, 226, 206, 2, 248, - 162, 22, 214, 13, 26, 6, 1, 226, 206, 2, 224, 158, 22, 226, 114, 26, 6, - 1, 226, 206, 2, 248, 162, 22, 226, 114, 26, 6, 1, 226, 206, 2, 224, 158, - 22, 225, 178, 26, 6, 1, 226, 206, 2, 248, 162, 22, 225, 178, 26, 4, 1, - 254, 152, 2, 214, 13, 26, 4, 1, 254, 152, 2, 226, 114, 26, 4, 1, 245, - 109, 2, 214, 13, 26, 4, 1, 245, 109, 2, 226, 114, 26, 4, 1, 245, 72, 2, - 214, 13, 26, 4, 1, 245, 72, 2, 226, 114, 26, 4, 1, 235, 193, 2, 214, 13, - 26, 4, 1, 235, 193, 2, 226, 114, 26, 4, 1, 226, 204, 2, 214, 13, 26, 4, - 1, 226, 204, 2, 226, 114, 26, 4, 1, 214, 158, 2, 214, 13, 26, 4, 1, 214, - 158, 2, 226, 114, 26, 4, 1, 226, 206, 2, 214, 13, 26, 4, 1, 226, 206, 2, - 226, 114, 26, 4, 1, 254, 152, 2, 224, 158, 22, 210, 219, 26, 4, 1, 254, - 152, 2, 248, 162, 22, 210, 219, 26, 4, 1, 254, 152, 2, 224, 158, 22, 214, - 14, 22, 210, 219, 26, 4, 1, 254, 152, 2, 248, 162, 22, 214, 14, 22, 210, - 219, 26, 4, 1, 254, 152, 2, 224, 158, 22, 226, 115, 22, 210, 219, 26, 4, - 1, 254, 152, 2, 248, 162, 22, 226, 115, 22, 210, 219, 26, 4, 1, 254, 152, - 2, 224, 158, 22, 225, 179, 22, 210, 219, 26, 4, 1, 254, 152, 2, 248, 162, - 22, 225, 179, 22, 210, 219, 26, 6, 1, 254, 152, 2, 224, 158, 22, 224, - 170, 26, 6, 1, 254, 152, 2, 248, 162, 22, 224, 170, 26, 6, 1, 254, 152, - 2, 224, 158, 22, 214, 14, 22, 224, 170, 26, 6, 1, 254, 152, 2, 248, 162, - 22, 214, 14, 22, 224, 170, 26, 6, 1, 254, 152, 2, 224, 158, 22, 226, 115, - 22, 224, 170, 26, 6, 1, 254, 152, 2, 248, 162, 22, 226, 115, 22, 224, - 170, 26, 6, 1, 254, 152, 2, 224, 158, 22, 225, 179, 22, 224, 170, 26, 6, - 1, 254, 152, 2, 248, 162, 22, 225, 179, 22, 224, 170, 26, 4, 1, 245, 72, - 2, 224, 158, 22, 210, 219, 26, 4, 1, 245, 72, 2, 248, 162, 22, 210, 219, - 26, 4, 1, 245, 72, 2, 224, 158, 22, 214, 14, 22, 210, 219, 26, 4, 1, 245, - 72, 2, 248, 162, 22, 214, 14, 22, 210, 219, 26, 4, 1, 245, 72, 2, 224, - 158, 22, 226, 115, 22, 210, 219, 26, 4, 1, 245, 72, 2, 248, 162, 22, 226, - 115, 22, 210, 219, 26, 4, 1, 245, 72, 2, 224, 158, 22, 225, 179, 22, 210, - 219, 26, 4, 1, 245, 72, 2, 248, 162, 22, 225, 179, 22, 210, 219, 26, 6, - 1, 245, 72, 2, 224, 158, 22, 224, 170, 26, 6, 1, 245, 72, 2, 248, 162, - 22, 224, 170, 26, 6, 1, 245, 72, 2, 224, 158, 22, 214, 14, 22, 224, 170, - 26, 6, 1, 245, 72, 2, 248, 162, 22, 214, 14, 22, 224, 170, 26, 6, 1, 245, - 72, 2, 224, 158, 22, 226, 115, 22, 224, 170, 26, 6, 1, 245, 72, 2, 248, - 162, 22, 226, 115, 22, 224, 170, 26, 6, 1, 245, 72, 2, 224, 158, 22, 225, - 179, 22, 224, 170, 26, 6, 1, 245, 72, 2, 248, 162, 22, 225, 179, 22, 224, - 170, 26, 4, 1, 226, 206, 2, 224, 158, 22, 210, 219, 26, 4, 1, 226, 206, - 2, 248, 162, 22, 210, 219, 26, 4, 1, 226, 206, 2, 224, 158, 22, 214, 14, - 22, 210, 219, 26, 4, 1, 226, 206, 2, 248, 162, 22, 214, 14, 22, 210, 219, - 26, 4, 1, 226, 206, 2, 224, 158, 22, 226, 115, 22, 210, 219, 26, 4, 1, - 226, 206, 2, 248, 162, 22, 226, 115, 22, 210, 219, 26, 4, 1, 226, 206, 2, - 224, 158, 22, 225, 179, 22, 210, 219, 26, 4, 1, 226, 206, 2, 248, 162, - 22, 225, 179, 22, 210, 219, 26, 6, 1, 226, 206, 2, 224, 158, 22, 224, - 170, 26, 6, 1, 226, 206, 2, 248, 162, 22, 224, 170, 26, 6, 1, 226, 206, - 2, 224, 158, 22, 214, 14, 22, 224, 170, 26, 6, 1, 226, 206, 2, 248, 162, - 22, 214, 14, 22, 224, 170, 26, 6, 1, 226, 206, 2, 224, 158, 22, 226, 115, - 22, 224, 170, 26, 6, 1, 226, 206, 2, 248, 162, 22, 226, 115, 22, 224, - 170, 26, 6, 1, 226, 206, 2, 224, 158, 22, 225, 179, 22, 224, 170, 26, 6, - 1, 226, 206, 2, 248, 162, 22, 225, 179, 22, 224, 170, 26, 4, 1, 254, 152, - 2, 213, 120, 26, 4, 1, 254, 152, 2, 231, 237, 26, 4, 1, 254, 152, 2, 214, - 14, 22, 210, 219, 26, 4, 1, 254, 152, 2, 210, 219, 26, 4, 1, 254, 152, 2, - 226, 115, 22, 210, 219, 26, 4, 1, 254, 152, 2, 225, 178, 26, 4, 1, 254, - 152, 2, 225, 179, 22, 210, 219, 26, 6, 1, 254, 152, 2, 213, 120, 26, 6, - 1, 254, 152, 2, 231, 237, 26, 6, 1, 254, 152, 2, 214, 13, 26, 6, 1, 254, - 152, 2, 226, 114, 26, 6, 1, 254, 152, 2, 224, 170, 26, 234, 8, 26, 224, - 170, 26, 224, 157, 26, 225, 178, 26, 248, 4, 22, 225, 178, 26, 4, 1, 245, - 72, 2, 214, 14, 22, 210, 219, 26, 4, 1, 245, 72, 2, 210, 219, 26, 4, 1, - 245, 72, 2, 226, 115, 22, 210, 219, 26, 4, 1, 245, 72, 2, 225, 178, 26, - 4, 1, 245, 72, 2, 225, 179, 22, 210, 219, 26, 6, 1, 245, 109, 2, 214, 13, - 26, 6, 1, 245, 109, 2, 226, 114, 26, 6, 1, 245, 72, 2, 214, 13, 26, 6, 1, - 245, 72, 2, 226, 114, 26, 6, 1, 245, 72, 2, 224, 170, 26, 224, 158, 22, - 214, 13, 26, 224, 158, 22, 226, 114, 26, 224, 158, 22, 225, 178, 26, 4, - 1, 235, 193, 2, 213, 120, 26, 4, 1, 235, 193, 2, 231, 237, 26, 4, 1, 235, - 193, 2, 248, 4, 22, 214, 13, 26, 4, 1, 235, 193, 2, 248, 4, 22, 226, 114, - 26, 4, 1, 235, 193, 2, 225, 178, 26, 4, 1, 235, 193, 2, 248, 4, 22, 225, - 178, 26, 6, 1, 235, 193, 2, 213, 120, 26, 6, 1, 235, 193, 2, 231, 237, - 26, 6, 1, 235, 193, 2, 214, 13, 26, 6, 1, 235, 193, 2, 226, 114, 26, 248, - 162, 22, 214, 13, 26, 248, 162, 22, 226, 114, 26, 248, 162, 22, 225, 178, - 26, 4, 1, 214, 158, 2, 213, 120, 26, 4, 1, 214, 158, 2, 231, 237, 26, 4, - 1, 214, 158, 2, 248, 4, 22, 214, 13, 26, 4, 1, 214, 158, 2, 248, 4, 22, - 226, 114, 26, 4, 1, 223, 41, 2, 224, 157, 26, 4, 1, 223, 41, 2, 248, 161, - 26, 4, 1, 214, 158, 2, 225, 178, 26, 4, 1, 214, 158, 2, 248, 4, 22, 225, - 178, 26, 6, 1, 214, 158, 2, 213, 120, 26, 6, 1, 214, 158, 2, 231, 237, - 26, 6, 1, 214, 158, 2, 214, 13, 26, 6, 1, 214, 158, 2, 226, 114, 26, 6, - 1, 223, 41, 2, 248, 161, 26, 248, 4, 22, 214, 13, 26, 248, 4, 22, 226, - 114, 26, 214, 13, 26, 4, 1, 226, 206, 2, 214, 14, 22, 210, 219, 26, 4, 1, - 226, 206, 2, 210, 219, 26, 4, 1, 226, 206, 2, 226, 115, 22, 210, 219, 26, - 4, 1, 226, 206, 2, 225, 178, 26, 4, 1, 226, 206, 2, 225, 179, 22, 210, - 219, 26, 6, 1, 226, 204, 2, 214, 13, 26, 6, 1, 226, 204, 2, 226, 114, 26, - 6, 1, 226, 206, 2, 214, 13, 26, 6, 1, 226, 206, 2, 226, 114, 26, 6, 1, - 226, 206, 2, 224, 170, 26, 226, 114, 26, 248, 161, 245, 159, 224, 30, - 245, 168, 224, 30, 245, 159, 219, 20, 245, 168, 219, 20, 216, 142, 219, - 20, 244, 17, 219, 20, 219, 125, 219, 20, 244, 120, 219, 20, 224, 144, - 219, 20, 216, 171, 219, 20, 242, 42, 219, 20, 210, 87, 211, 245, 219, 20, - 210, 87, 211, 245, 228, 72, 210, 87, 211, 245, 235, 69, 233, 44, 79, 222, - 246, 79, 240, 175, 228, 73, 240, 175, 244, 120, 248, 164, 245, 159, 248, - 164, 245, 168, 248, 164, 203, 130, 52, 67, 232, 219, 52, 121, 232, 219, - 43, 219, 157, 224, 1, 79, 44, 219, 157, 224, 1, 79, 219, 157, 232, 115, - 224, 1, 79, 219, 157, 241, 170, 224, 1, 79, 43, 52, 224, 1, 79, 44, 52, - 224, 1, 79, 52, 232, 115, 224, 1, 79, 52, 241, 170, 224, 1, 79, 248, 213, - 52, 248, 213, 251, 121, 215, 223, 251, 121, 123, 59, 233, 62, 113, 59, - 233, 62, 203, 245, 171, 240, 173, 225, 13, 232, 220, 220, 139, 226, 19, - 220, 139, 233, 44, 245, 166, 222, 246, 245, 166, 224, 249, 247, 204, 244, - 27, 233, 44, 226, 121, 222, 246, 226, 121, 229, 199, 228, 78, 219, 20, - 225, 186, 230, 198, 50, 225, 186, 216, 249, 216, 149, 50, 224, 193, 52, - 224, 193, 215, 212, 224, 193, 223, 52, 224, 193, 223, 52, 52, 224, 193, - 223, 52, 215, 212, 224, 193, 250, 246, 219, 157, 233, 48, 254, 118, 224, - 1, 79, 219, 157, 222, 250, 254, 118, 224, 1, 79, 223, 110, 79, 52, 245, - 39, 79, 235, 208, 226, 123, 214, 180, 135, 216, 112, 250, 247, 235, 223, - 225, 13, 253, 222, 240, 176, 251, 121, 244, 10, 219, 97, 43, 42, 251, - 166, 2, 224, 10, 44, 42, 251, 166, 2, 224, 10, 52, 224, 16, 79, 224, 16, - 245, 39, 79, 245, 39, 224, 16, 79, 216, 71, 5, 245, 73, 223, 52, 225, 71, - 50, 85, 140, 251, 121, 85, 97, 251, 121, 121, 253, 224, 223, 52, 220, - 152, 250, 9, 214, 163, 113, 253, 223, 254, 167, 213, 188, 249, 225, 230, - 187, 50, 217, 235, 248, 164, 235, 200, 214, 180, 244, 60, 224, 144, 79, - 134, 59, 224, 143, 224, 27, 224, 193, 244, 19, 59, 224, 143, 244, 89, 59, - 224, 143, 113, 59, 224, 143, 244, 19, 59, 79, 246, 126, 249, 138, 215, - 222, 67, 244, 19, 247, 126, 231, 87, 11, 219, 20, 211, 209, 235, 69, 243, - 234, 254, 60, 235, 198, 216, 86, 235, 198, 220, 139, 235, 198, 225, 25, - 233, 44, 235, 171, 222, 246, 235, 171, 244, 100, 218, 91, 235, 171, 224, - 249, 247, 204, 235, 171, 235, 235, 217, 183, 217, 252, 255, 14, 217, 183, - 217, 252, 235, 235, 9, 244, 28, 220, 82, 255, 14, 9, 244, 28, 220, 82, - 229, 194, 21, 220, 83, 228, 74, 21, 220, 83, 218, 24, 210, 86, 218, 24, - 7, 4, 1, 74, 218, 24, 161, 218, 24, 190, 218, 24, 195, 218, 24, 199, 218, - 24, 196, 218, 24, 201, 218, 24, 96, 50, 218, 24, 230, 186, 218, 24, 245, - 106, 50, 218, 24, 43, 226, 7, 218, 24, 44, 226, 7, 218, 24, 7, 4, 1, 230, - 30, 218, 66, 210, 86, 218, 66, 111, 218, 66, 105, 218, 66, 158, 218, 66, - 161, 218, 66, 190, 218, 66, 195, 218, 66, 199, 218, 66, 196, 218, 66, - 201, 218, 66, 96, 50, 218, 66, 230, 186, 218, 66, 245, 106, 50, 218, 66, - 43, 226, 7, 218, 66, 44, 226, 7, 7, 218, 66, 4, 1, 61, 7, 218, 66, 4, 1, - 76, 7, 218, 66, 4, 1, 78, 7, 218, 66, 4, 1, 211, 178, 7, 218, 66, 4, 1, - 221, 197, 7, 218, 66, 4, 1, 242, 67, 7, 218, 66, 4, 1, 235, 29, 7, 218, - 66, 4, 1, 156, 7, 218, 66, 4, 1, 194, 7, 218, 66, 4, 1, 230, 30, 7, 218, - 66, 4, 1, 226, 109, 7, 218, 66, 4, 1, 222, 93, 7, 218, 66, 4, 1, 217, - 153, 245, 54, 50, 249, 235, 50, 249, 125, 50, 244, 3, 244, 6, 50, 232, - 204, 50, 230, 199, 50, 229, 215, 50, 225, 165, 50, 222, 120, 50, 211, - 217, 50, 166, 220, 51, 50, 247, 135, 50, 245, 55, 50, 234, 82, 50, 215, - 113, 50, 246, 109, 50, 243, 47, 225, 196, 50, 225, 163, 50, 242, 116, 50, - 253, 190, 50, 240, 235, 50, 250, 193, 50, 232, 197, 216, 4, 50, 219, 2, - 50, 216, 246, 50, 235, 248, 222, 120, 50, 215, 97, 232, 204, 50, 38, 43, - 242, 6, 48, 38, 44, 242, 6, 48, 38, 200, 67, 232, 220, 226, 124, 38, 219, - 253, 67, 232, 220, 226, 124, 38, 254, 96, 80, 48, 38, 250, 10, 80, 48, - 38, 43, 80, 48, 38, 44, 80, 48, 38, 222, 237, 226, 124, 38, 250, 10, 222, - 237, 226, 124, 38, 254, 96, 222, 237, 226, 124, 38, 134, 170, 48, 38, - 244, 19, 170, 48, 38, 245, 154, 250, 43, 38, 245, 154, 218, 236, 38, 245, - 154, 248, 0, 38, 245, 154, 250, 44, 252, 188, 38, 43, 44, 80, 48, 38, - 245, 154, 221, 190, 38, 245, 154, 234, 141, 38, 245, 154, 214, 155, 225, - 10, 215, 226, 38, 223, 53, 219, 49, 226, 124, 38, 52, 67, 218, 105, 226, - 124, 38, 254, 106, 87, 38, 215, 212, 214, 182, 38, 211, 247, 251, 148, - 48, 38, 140, 80, 226, 124, 38, 200, 52, 219, 49, 226, 124, 38, 97, 242, - 6, 2, 252, 147, 246, 111, 38, 140, 242, 6, 2, 252, 147, 246, 111, 38, 43, - 80, 51, 38, 44, 80, 51, 38, 253, 225, 48, 255, 20, 226, 235, 255, 4, 216, - 43, 216, 197, 218, 75, 139, 6, 251, 74, 248, 79, 250, 186, 250, 183, 232, - 220, 87, 250, 248, 226, 235, 251, 34, 214, 189, 245, 56, 249, 199, 221, - 187, 248, 79, 244, 187, 119, 4, 243, 209, 119, 6, 242, 67, 251, 227, 6, - 242, 67, 139, 6, 242, 67, 225, 40, 249, 199, 225, 40, 249, 200, 115, 113, - 225, 111, 119, 6, 74, 251, 227, 6, 74, 119, 6, 156, 119, 4, 156, 233, - 155, 57, 252, 149, 87, 139, 6, 230, 30, 227, 200, 50, 219, 33, 223, 122, - 249, 170, 119, 6, 226, 109, 139, 6, 226, 109, 139, 6, 224, 99, 119, 6, - 153, 251, 227, 6, 153, 139, 6, 153, 224, 199, 217, 72, 223, 65, 220, 134, - 79, 217, 2, 50, 215, 254, 164, 50, 213, 240, 139, 6, 210, 159, 226, 137, - 50, 226, 225, 50, 235, 200, 226, 225, 50, 251, 227, 6, 210, 159, 215, 94, - 26, 4, 1, 235, 192, 234, 179, 50, 254, 115, 50, 119, 6, 253, 166, 251, - 227, 6, 251, 74, 245, 76, 87, 119, 4, 76, 119, 6, 76, 119, 6, 245, 14, - 215, 94, 6, 245, 14, 119, 6, 194, 119, 4, 78, 109, 87, 252, 37, 87, 242, - 209, 87, 248, 198, 87, 235, 239, 219, 31, 222, 189, 6, 224, 99, 244, 190, - 50, 139, 4, 225, 111, 139, 4, 243, 114, 139, 6, 243, 114, 139, 6, 225, - 111, 139, 230, 29, 218, 41, 215, 94, 35, 6, 243, 209, 215, 94, 35, 6, - 156, 223, 52, 35, 6, 156, 215, 94, 35, 6, 211, 117, 139, 32, 6, 249, 68, - 139, 32, 4, 249, 68, 139, 32, 4, 76, 139, 32, 4, 74, 139, 32, 4, 235, - 150, 224, 173, 232, 219, 215, 94, 254, 134, 225, 186, 50, 254, 189, 215, - 94, 4, 245, 14, 16, 31, 221, 254, 219, 31, 212, 114, 244, 10, 123, 220, - 120, 212, 114, 244, 10, 123, 228, 199, 212, 114, 244, 10, 123, 216, 242, - 212, 114, 244, 10, 123, 216, 169, 212, 114, 244, 10, 113, 216, 167, 212, - 114, 244, 10, 123, 244, 125, 212, 114, 244, 10, 113, 244, 124, 212, 114, - 244, 10, 134, 244, 124, 212, 114, 244, 10, 244, 19, 244, 124, 212, 114, - 244, 10, 123, 219, 117, 212, 114, 244, 10, 244, 89, 219, 115, 212, 114, - 244, 10, 123, 245, 196, 212, 114, 244, 10, 134, 245, 194, 212, 114, 244, - 10, 244, 89, 245, 194, 212, 114, 244, 10, 220, 124, 245, 194, 244, 10, - 227, 201, 111, 222, 200, 227, 202, 111, 222, 200, 227, 202, 105, 222, - 200, 227, 202, 158, 222, 200, 227, 202, 161, 222, 200, 227, 202, 190, - 222, 200, 227, 202, 195, 222, 200, 227, 202, 199, 222, 200, 227, 202, - 196, 222, 200, 227, 202, 201, 222, 200, 227, 202, 216, 248, 222, 200, - 227, 202, 245, 175, 222, 200, 227, 202, 215, 76, 222, 200, 227, 202, 244, - 122, 222, 200, 227, 202, 123, 240, 217, 222, 200, 227, 202, 244, 89, 240, - 217, 222, 200, 227, 202, 123, 216, 148, 4, 222, 200, 227, 202, 111, 4, - 222, 200, 227, 202, 105, 4, 222, 200, 227, 202, 158, 4, 222, 200, 227, - 202, 161, 4, 222, 200, 227, 202, 190, 4, 222, 200, 227, 202, 195, 4, 222, - 200, 227, 202, 199, 4, 222, 200, 227, 202, 196, 4, 222, 200, 227, 202, - 201, 4, 222, 200, 227, 202, 216, 248, 4, 222, 200, 227, 202, 245, 175, 4, - 222, 200, 227, 202, 215, 76, 4, 222, 200, 227, 202, 244, 122, 4, 222, - 200, 227, 202, 123, 240, 217, 4, 222, 200, 227, 202, 244, 89, 240, 217, - 4, 222, 200, 227, 202, 123, 216, 148, 222, 200, 227, 202, 123, 216, 149, - 251, 75, 249, 68, 222, 200, 227, 202, 244, 89, 216, 148, 222, 200, 227, - 202, 216, 249, 216, 148, 222, 200, 227, 202, 223, 52, 123, 240, 217, 7, - 4, 1, 223, 52, 251, 74, 222, 200, 227, 202, 219, 127, 233, 84, 17, 222, - 200, 227, 202, 244, 123, 245, 234, 17, 222, 200, 227, 202, 244, 123, 216, - 148, 222, 200, 227, 202, 123, 240, 218, 216, 148, 212, 114, 244, 10, 210, - 87, 216, 167, 140, 75, 214, 153, 75, 97, 75, 246, 112, 75, 43, 44, 75, - 120, 124, 75, 228, 61, 212, 9, 75, 228, 61, 245, 228, 75, 219, 30, 245, - 228, 75, 219, 30, 212, 9, 75, 140, 80, 2, 91, 97, 80, 2, 91, 140, 212, - 36, 75, 97, 212, 36, 75, 140, 113, 241, 241, 75, 214, 153, 113, 241, 241, - 75, 97, 113, 241, 241, 75, 246, 112, 113, 241, 241, 75, 140, 80, 2, 217, - 78, 97, 80, 2, 217, 78, 140, 80, 243, 251, 130, 214, 153, 80, 243, 251, - 130, 97, 80, 243, 251, 130, 246, 112, 80, 243, 251, 130, 120, 124, 80, 2, - 252, 135, 140, 80, 2, 103, 97, 80, 2, 103, 140, 80, 2, 232, 129, 97, 80, - 2, 232, 129, 43, 44, 212, 36, 75, 43, 44, 80, 2, 91, 246, 112, 210, 35, - 75, 214, 153, 80, 2, 216, 78, 233, 43, 214, 153, 80, 2, 216, 78, 222, - 244, 246, 112, 80, 2, 216, 78, 233, 43, 246, 112, 80, 2, 216, 78, 222, - 244, 97, 80, 2, 249, 169, 246, 111, 246, 112, 80, 2, 249, 169, 233, 43, - 254, 96, 216, 15, 220, 155, 75, 250, 10, 216, 15, 220, 155, 75, 228, 61, - 212, 9, 80, 216, 43, 200, 130, 140, 80, 216, 43, 252, 149, 115, 97, 80, - 216, 43, 130, 254, 96, 204, 250, 44, 75, 250, 10, 204, 250, 44, 75, 140, - 242, 6, 2, 252, 147, 214, 152, 140, 242, 6, 2, 252, 147, 246, 111, 214, - 153, 242, 6, 2, 252, 147, 222, 244, 214, 153, 242, 6, 2, 252, 147, 233, - 43, 97, 242, 6, 2, 252, 147, 214, 152, 97, 242, 6, 2, 252, 147, 246, 111, - 246, 112, 242, 6, 2, 252, 147, 222, 244, 246, 112, 242, 6, 2, 252, 147, - 233, 43, 97, 80, 115, 140, 75, 214, 153, 80, 140, 64, 246, 112, 75, 140, - 80, 115, 97, 75, 140, 226, 74, 253, 255, 214, 153, 226, 74, 253, 255, 97, - 226, 74, 253, 255, 246, 112, 226, 74, 253, 255, 140, 242, 6, 115, 97, - 242, 5, 97, 242, 6, 115, 140, 242, 5, 140, 52, 80, 2, 91, 43, 44, 52, 80, - 2, 91, 97, 52, 80, 2, 91, 140, 52, 75, 214, 153, 52, 75, 97, 52, 75, 246, - 112, 52, 75, 43, 44, 52, 75, 120, 124, 52, 75, 228, 61, 212, 9, 52, 75, - 228, 61, 245, 228, 52, 75, 219, 30, 245, 228, 52, 75, 219, 30, 212, 9, - 52, 75, 140, 215, 212, 75, 97, 215, 212, 75, 140, 218, 232, 75, 97, 218, - 232, 75, 214, 153, 80, 2, 52, 91, 246, 112, 80, 2, 52, 91, 140, 248, 163, - 75, 214, 153, 248, 163, 75, 97, 248, 163, 75, 246, 112, 248, 163, 75, - 140, 80, 216, 43, 130, 97, 80, 216, 43, 130, 140, 71, 75, 214, 153, 71, - 75, 97, 71, 75, 246, 112, 71, 75, 214, 153, 71, 80, 243, 251, 130, 214, - 153, 71, 80, 226, 201, 225, 217, 214, 153, 71, 80, 226, 201, 225, 218, 2, - 203, 130, 214, 153, 71, 80, 226, 201, 225, 218, 2, 67, 130, 214, 153, 71, - 52, 75, 214, 153, 71, 52, 80, 226, 201, 225, 217, 97, 71, 80, 243, 251, - 212, 56, 228, 61, 212, 9, 80, 216, 43, 249, 168, 219, 30, 245, 228, 80, - 216, 43, 249, 168, 120, 124, 71, 75, 44, 80, 2, 4, 250, 43, 246, 112, 80, - 140, 64, 214, 153, 75, 134, 97, 253, 255, 140, 80, 2, 67, 91, 97, 80, 2, - 67, 91, 43, 44, 80, 2, 67, 91, 140, 80, 2, 52, 67, 91, 97, 80, 2, 52, 67, - 91, 43, 44, 80, 2, 52, 67, 91, 140, 226, 177, 75, 97, 226, 177, 75, 43, - 44, 226, 177, 75, 31, 254, 163, 249, 222, 226, 1, 247, 241, 216, 188, - 245, 35, 216, 188, 247, 146, 228, 57, 245, 36, 245, 160, 220, 129, 235, - 252, 229, 226, 245, 178, 226, 235, 228, 57, 254, 132, 245, 178, 226, 235, - 4, 245, 178, 226, 235, 249, 194, 253, 246, 231, 67, 247, 146, 228, 57, - 249, 196, 253, 246, 231, 67, 4, 249, 194, 253, 246, 231, 67, 245, 151, - 64, 224, 175, 230, 29, 224, 183, 230, 29, 249, 173, 230, 29, 218, 41, - 230, 187, 50, 230, 185, 50, 59, 225, 25, 247, 177, 219, 97, 220, 130, - 230, 186, 253, 225, 226, 171, 222, 237, 226, 171, 251, 122, 226, 171, 42, - 222, 195, 249, 117, 222, 195, 244, 12, 222, 195, 224, 171, 112, 235, 241, - 44, 254, 117, 254, 117, 231, 93, 254, 117, 219, 1, 254, 117, 247, 179, - 247, 146, 228, 57, 247, 182, 226, 12, 112, 228, 57, 226, 12, 112, 232, - 152, 254, 126, 232, 152, 226, 162, 235, 205, 214, 175, 235, 218, 52, 235, - 218, 215, 212, 235, 218, 249, 190, 235, 218, 218, 14, 235, 218, 213, 129, - 235, 218, 250, 10, 235, 218, 250, 10, 249, 190, 235, 218, 254, 96, 249, - 190, 235, 218, 216, 187, 252, 75, 223, 140, 224, 172, 59, 230, 186, 245, - 41, 243, 53, 224, 172, 241, 64, 216, 90, 226, 171, 223, 52, 184, 235, - 200, 233, 71, 222, 93, 219, 159, 212, 35, 211, 200, 224, 183, 228, 57, - 184, 230, 187, 184, 253, 218, 128, 112, 228, 57, 253, 218, 128, 112, 254, - 56, 128, 112, 254, 56, 251, 96, 228, 57, 255, 13, 128, 112, 229, 105, - 254, 56, 228, 64, 255, 13, 128, 112, 254, 156, 128, 112, 228, 57, 254, - 156, 128, 112, 254, 156, 128, 177, 128, 112, 215, 212, 184, 254, 164, - 128, 112, 245, 102, 112, 243, 52, 245, 102, 112, 247, 242, 252, 31, 254, - 58, 216, 197, 232, 227, 243, 52, 128, 112, 254, 56, 128, 216, 43, 177, - 216, 197, 236, 22, 226, 235, 236, 22, 64, 177, 254, 56, 128, 112, 249, - 235, 245, 105, 245, 106, 249, 234, 222, 237, 236, 7, 128, 112, 222, 237, - 128, 112, 249, 162, 112, 245, 75, 245, 104, 112, 218, 159, 245, 105, 248, - 63, 128, 112, 128, 216, 43, 251, 86, 248, 80, 231, 93, 251, 85, 224, 14, - 128, 112, 228, 57, 128, 112, 240, 111, 112, 228, 57, 240, 111, 112, 218, - 111, 245, 102, 112, 233, 21, 177, 128, 112, 242, 137, 177, 128, 112, 233, - 21, 115, 128, 112, 242, 137, 115, 128, 112, 233, 21, 251, 96, 228, 57, - 128, 112, 242, 137, 251, 96, 228, 57, 128, 112, 230, 102, 233, 20, 230, - 102, 242, 136, 252, 31, 228, 57, 245, 102, 112, 228, 57, 233, 20, 228, - 57, 242, 136, 229, 105, 233, 21, 228, 64, 128, 112, 229, 105, 242, 137, - 228, 64, 128, 112, 233, 21, 177, 245, 102, 112, 242, 137, 177, 245, 102, - 112, 229, 105, 233, 21, 228, 64, 245, 102, 112, 229, 105, 242, 137, 228, - 64, 245, 102, 112, 233, 21, 177, 242, 136, 242, 137, 177, 233, 20, 229, - 105, 233, 21, 228, 64, 242, 136, 229, 105, 242, 137, 228, 64, 233, 20, - 224, 205, 218, 56, 224, 206, 177, 128, 112, 218, 57, 177, 128, 112, 224, - 206, 177, 245, 102, 112, 218, 57, 177, 245, 102, 112, 247, 146, 228, 57, - 224, 208, 247, 146, 228, 57, 218, 58, 218, 65, 226, 235, 218, 23, 226, - 235, 228, 57, 116, 218, 65, 226, 235, 228, 57, 116, 218, 23, 226, 235, - 218, 65, 64, 177, 128, 112, 218, 23, 64, 177, 128, 112, 229, 105, 116, - 218, 65, 64, 228, 64, 128, 112, 229, 105, 116, 218, 23, 64, 228, 64, 128, - 112, 218, 65, 64, 2, 228, 57, 128, 112, 218, 23, 64, 2, 228, 57, 128, - 112, 230, 86, 230, 87, 230, 88, 230, 87, 214, 175, 42, 236, 22, 226, 235, - 42, 226, 154, 226, 235, 42, 236, 22, 64, 177, 128, 112, 42, 226, 154, 64, - 177, 128, 112, 42, 251, 3, 42, 249, 110, 37, 225, 25, 37, 230, 186, 37, - 216, 86, 37, 247, 177, 219, 97, 37, 59, 226, 171, 37, 222, 237, 226, 171, - 37, 253, 225, 226, 171, 37, 245, 105, 37, 248, 164, 92, 225, 25, 92, 230, - 186, 92, 216, 86, 92, 59, 226, 171, 44, 217, 88, 43, 217, 88, 124, 217, - 88, 120, 217, 88, 253, 228, 230, 161, 215, 192, 244, 33, 215, 212, 67, - 252, 149, 44, 215, 93, 52, 67, 252, 149, 52, 44, 215, 93, 247, 146, 228, - 57, 224, 166, 228, 57, 215, 192, 247, 146, 228, 57, 244, 34, 229, 107, - 52, 67, 252, 149, 52, 44, 215, 93, 224, 206, 214, 184, 223, 94, 218, 57, - 214, 184, 223, 94, 228, 62, 218, 78, 226, 235, 249, 194, 253, 246, 228, - 62, 218, 77, 228, 62, 218, 78, 64, 177, 128, 112, 249, 194, 253, 246, - 228, 62, 218, 78, 177, 128, 112, 226, 154, 226, 235, 236, 22, 226, 235, - 230, 92, 241, 207, 249, 204, 231, 142, 235, 215, 211, 145, 229, 207, 228, - 63, 44, 254, 118, 2, 254, 33, 44, 215, 226, 230, 29, 232, 152, 254, 126, - 230, 29, 232, 152, 226, 162, 230, 29, 235, 205, 230, 29, 214, 175, 248, - 1, 226, 171, 59, 226, 171, 218, 159, 226, 171, 247, 177, 216, 86, 251, - 172, 43, 228, 62, 244, 189, 220, 151, 224, 183, 44, 228, 62, 244, 189, - 220, 151, 224, 183, 43, 220, 151, 224, 183, 44, 220, 151, 224, 183, 223, - 52, 216, 90, 245, 105, 249, 107, 232, 152, 226, 162, 249, 107, 232, 152, - 254, 126, 52, 218, 64, 52, 218, 22, 52, 235, 205, 52, 214, 175, 225, 50, - 128, 22, 226, 12, 112, 233, 21, 2, 247, 128, 242, 137, 2, 247, 128, 213, - 187, 230, 102, 233, 20, 213, 187, 230, 102, 242, 136, 233, 21, 128, 216, - 43, 177, 242, 136, 242, 137, 128, 216, 43, 177, 233, 20, 128, 216, 43, - 177, 233, 20, 128, 216, 43, 177, 242, 136, 128, 216, 43, 177, 224, 205, - 128, 216, 43, 177, 218, 56, 247, 146, 228, 57, 224, 209, 177, 245, 107, - 247, 146, 228, 57, 218, 59, 177, 245, 107, 228, 57, 42, 236, 22, 64, 177, - 128, 112, 228, 57, 42, 226, 154, 64, 177, 128, 112, 42, 236, 22, 64, 177, - 228, 57, 128, 112, 42, 226, 154, 64, 177, 228, 57, 128, 112, 233, 21, - 251, 96, 228, 57, 245, 102, 112, 242, 137, 251, 96, 228, 57, 245, 102, - 112, 224, 206, 251, 96, 228, 57, 245, 102, 112, 218, 57, 251, 96, 228, - 57, 245, 102, 112, 228, 57, 228, 62, 218, 78, 226, 235, 247, 146, 228, - 57, 249, 196, 253, 246, 228, 62, 218, 77, 228, 57, 228, 62, 218, 78, 64, - 177, 128, 112, 247, 146, 228, 57, 249, 196, 253, 246, 228, 62, 218, 78, - 177, 245, 107, 67, 245, 171, 230, 227, 203, 245, 171, 120, 44, 248, 7, - 245, 171, 124, 44, 248, 7, 245, 171, 245, 178, 64, 2, 200, 203, 91, 245, - 178, 64, 2, 67, 252, 149, 253, 215, 245, 151, 64, 203, 91, 4, 245, 178, - 64, 2, 67, 252, 149, 253, 215, 245, 151, 64, 203, 91, 245, 178, 64, 2, - 59, 48, 245, 178, 64, 2, 226, 127, 4, 245, 178, 64, 2, 226, 127, 245, - 178, 64, 2, 214, 183, 245, 178, 64, 2, 113, 203, 218, 92, 249, 194, 2, - 200, 203, 91, 249, 194, 2, 67, 252, 149, 253, 215, 245, 151, 64, 203, 91, - 4, 249, 194, 2, 67, 252, 149, 253, 215, 245, 151, 64, 203, 91, 249, 194, - 2, 226, 127, 4, 249, 194, 2, 226, 127, 210, 160, 189, 252, 181, 231, 66, - 248, 2, 50, 245, 180, 75, 240, 241, 120, 254, 1, 124, 254, 1, 224, 178, - 225, 168, 212, 32, 232, 219, 43, 250, 189, 44, 250, 189, 43, 244, 65, 44, - 244, 65, 251, 183, 44, 249, 140, 251, 183, 43, 249, 140, 216, 15, 44, - 249, 140, 216, 15, 43, 249, 140, 223, 52, 228, 57, 50, 42, 232, 110, 254, - 33, 221, 166, 221, 173, 217, 2, 223, 123, 224, 244, 235, 245, 213, 165, - 218, 236, 225, 44, 64, 235, 214, 50, 215, 94, 228, 57, 50, 212, 42, 240, - 243, 216, 15, 43, 249, 168, 216, 15, 44, 249, 168, 251, 183, 43, 249, - 168, 251, 183, 44, 249, 168, 216, 15, 163, 235, 218, 251, 183, 163, 235, - 218, 243, 248, 219, 77, 120, 254, 2, 252, 32, 113, 203, 252, 137, 226, - 164, 234, 144, 245, 98, 216, 43, 216, 197, 222, 254, 211, 179, 236, 7, - 116, 223, 120, 251, 171, 234, 143, 233, 48, 254, 118, 127, 222, 250, 254, - 118, 127, 245, 98, 216, 43, 216, 197, 233, 52, 252, 43, 222, 236, 249, - 78, 254, 164, 254, 9, 217, 182, 216, 5, 222, 125, 247, 223, 226, 155, - 249, 206, 217, 53, 219, 88, 249, 159, 249, 158, 254, 74, 243, 232, 16, - 240, 158, 254, 74, 243, 232, 16, 218, 230, 224, 30, 254, 74, 243, 232, - 16, 224, 31, 245, 107, 254, 74, 243, 232, 16, 224, 31, 247, 182, 254, 74, - 243, 232, 16, 224, 31, 248, 0, 254, 74, 243, 232, 16, 224, 31, 235, 62, - 254, 74, 243, 232, 16, 224, 31, 250, 43, 254, 74, 243, 232, 16, 250, 44, - 218, 137, 254, 74, 243, 232, 16, 250, 44, 235, 62, 254, 74, 243, 232, 16, - 219, 98, 130, 254, 74, 243, 232, 16, 252, 189, 130, 254, 74, 243, 232, - 16, 224, 31, 219, 97, 254, 74, 243, 232, 16, 224, 31, 252, 188, 254, 74, - 243, 232, 16, 224, 31, 233, 20, 254, 74, 243, 232, 16, 224, 31, 242, 136, - 254, 74, 243, 232, 16, 140, 214, 19, 254, 74, 243, 232, 16, 97, 214, 19, - 254, 74, 243, 232, 16, 224, 31, 140, 75, 254, 74, 243, 232, 16, 224, 31, - 97, 75, 254, 74, 243, 232, 16, 250, 44, 252, 188, 254, 74, 243, 232, 16, - 124, 217, 89, 214, 183, 254, 74, 243, 232, 16, 248, 63, 218, 137, 254, - 74, 243, 232, 16, 224, 31, 124, 250, 246, 254, 74, 243, 232, 16, 224, 31, - 248, 62, 254, 74, 243, 232, 16, 124, 217, 89, 235, 62, 254, 74, 243, 232, - 16, 214, 153, 214, 19, 254, 74, 243, 232, 16, 224, 31, 214, 153, 75, 254, - 74, 243, 232, 16, 120, 217, 89, 226, 127, 254, 74, 243, 232, 16, 248, 74, - 218, 137, 254, 74, 243, 232, 16, 224, 31, 120, 250, 246, 254, 74, 243, - 232, 16, 224, 31, 248, 73, 254, 74, 243, 232, 16, 120, 217, 89, 235, 62, - 254, 74, 243, 232, 16, 246, 112, 214, 19, 254, 74, 243, 232, 16, 224, 31, - 246, 112, 75, 254, 74, 243, 232, 16, 224, 0, 214, 183, 254, 74, 243, 232, - 16, 248, 63, 214, 183, 254, 74, 243, 232, 16, 248, 1, 214, 183, 254, 74, - 243, 232, 16, 235, 63, 214, 183, 254, 74, 243, 232, 16, 250, 44, 214, - 183, 254, 74, 243, 232, 16, 120, 220, 7, 235, 62, 254, 74, 243, 232, 16, - 224, 0, 224, 30, 254, 74, 243, 232, 16, 250, 44, 218, 158, 254, 74, 243, - 232, 16, 224, 31, 249, 234, 254, 74, 243, 232, 16, 120, 217, 89, 248, 9, - 254, 74, 243, 232, 16, 248, 74, 248, 9, 254, 74, 243, 232, 16, 218, 159, - 248, 9, 254, 74, 243, 232, 16, 235, 63, 248, 9, 254, 74, 243, 232, 16, - 250, 44, 248, 9, 254, 74, 243, 232, 16, 124, 220, 7, 218, 137, 254, 74, - 243, 232, 16, 43, 220, 7, 218, 137, 254, 74, 243, 232, 16, 216, 90, 248, - 9, 254, 74, 243, 232, 16, 242, 137, 248, 9, 254, 74, 243, 232, 16, 249, - 228, 130, 254, 74, 243, 232, 16, 248, 74, 184, 254, 74, 243, 232, 16, - 210, 34, 254, 74, 243, 232, 16, 218, 138, 184, 254, 74, 243, 232, 16, - 220, 153, 214, 183, 254, 74, 243, 232, 16, 224, 31, 228, 57, 245, 107, - 254, 74, 243, 232, 16, 224, 31, 224, 15, 254, 74, 243, 232, 16, 124, 250, - 247, 184, 254, 74, 243, 232, 16, 120, 250, 247, 184, 254, 74, 243, 232, - 16, 235, 192, 254, 74, 243, 232, 16, 223, 40, 254, 74, 243, 232, 16, 226, - 205, 254, 74, 243, 232, 16, 254, 152, 214, 183, 254, 74, 243, 232, 16, - 245, 109, 214, 183, 254, 74, 243, 232, 16, 235, 193, 214, 183, 254, 74, - 243, 232, 16, 226, 206, 214, 183, 254, 74, 243, 232, 16, 254, 151, 228, - 57, 250, 138, 79, 44, 254, 118, 2, 246, 112, 210, 35, 75, 219, 237, 204, - 251, 171, 252, 53, 87, 67, 232, 220, 2, 230, 229, 247, 128, 235, 223, 87, - 249, 191, 214, 181, 87, 247, 197, 214, 181, 87, 245, 162, 87, 249, 218, - 87, 71, 42, 2, 250, 183, 67, 232, 219, 245, 138, 87, 254, 147, 234, 145, - 87, 241, 220, 87, 37, 203, 252, 149, 2, 228, 55, 37, 215, 227, 246, 114, - 251, 143, 250, 44, 2, 228, 59, 75, 214, 179, 87, 230, 142, 87, 240, 171, - 87, 226, 178, 242, 66, 87, 226, 178, 233, 153, 87, 225, 248, 87, 225, - 247, 87, 247, 205, 249, 105, 16, 244, 28, 105, 219, 52, 87, 254, 74, 243, - 232, 16, 224, 30, 248, 91, 220, 140, 234, 145, 87, 224, 195, 226, 79, - 229, 87, 226, 79, 224, 191, 221, 191, 87, 250, 25, 221, 191, 87, 43, 226, - 8, 214, 160, 103, 43, 226, 8, 245, 29, 43, 226, 8, 232, 114, 103, 44, - 226, 8, 214, 160, 103, 44, 226, 8, 245, 29, 44, 226, 8, 232, 114, 103, - 43, 42, 251, 166, 214, 160, 249, 168, 43, 42, 251, 166, 245, 29, 43, 42, - 251, 166, 232, 114, 249, 168, 44, 42, 251, 166, 214, 160, 249, 168, 44, - 42, 251, 166, 245, 29, 44, 42, 251, 166, 232, 114, 249, 168, 43, 249, - 107, 251, 166, 214, 160, 103, 43, 249, 107, 251, 166, 230, 229, 225, 104, - 43, 249, 107, 251, 166, 232, 114, 103, 249, 107, 251, 166, 245, 29, 44, - 249, 107, 251, 166, 214, 160, 103, 44, 249, 107, 251, 166, 230, 229, 225, - 104, 44, 249, 107, 251, 166, 232, 114, 103, 235, 219, 245, 29, 203, 232, - 220, 245, 29, 214, 160, 43, 177, 232, 114, 44, 249, 107, 251, 166, 221, - 174, 214, 160, 44, 177, 232, 114, 43, 249, 107, 251, 166, 221, 174, 218, - 42, 216, 14, 218, 42, 251, 182, 216, 15, 42, 127, 251, 183, 42, 127, 251, - 183, 42, 251, 166, 115, 216, 15, 42, 127, 34, 16, 251, 182, 43, 67, 93, - 232, 219, 44, 67, 93, 232, 219, 203, 221, 207, 232, 218, 203, 221, 207, - 232, 217, 203, 221, 207, 232, 216, 203, 221, 207, 232, 215, 248, 54, 16, - 193, 67, 22, 216, 15, 222, 254, 248, 54, 16, 193, 67, 22, 251, 183, 222, - 254, 248, 54, 16, 193, 67, 2, 250, 43, 248, 54, 16, 193, 124, 22, 203, 2, - 250, 43, 248, 54, 16, 193, 120, 22, 203, 2, 250, 43, 248, 54, 16, 193, - 67, 2, 215, 226, 248, 54, 16, 193, 124, 22, 203, 2, 215, 226, 248, 54, - 16, 193, 120, 22, 203, 2, 215, 226, 248, 54, 16, 193, 67, 22, 212, 35, - 248, 54, 16, 193, 124, 22, 203, 2, 212, 35, 248, 54, 16, 193, 120, 22, - 203, 2, 212, 35, 248, 54, 16, 193, 124, 22, 241, 51, 248, 54, 16, 193, - 120, 22, 241, 51, 248, 54, 16, 193, 67, 22, 216, 15, 233, 52, 248, 54, - 16, 193, 67, 22, 251, 183, 233, 52, 42, 244, 40, 223, 57, 87, 245, 190, - 87, 67, 232, 220, 245, 29, 231, 38, 251, 154, 231, 38, 200, 115, 219, - 252, 231, 38, 219, 253, 115, 232, 143, 231, 38, 200, 115, 113, 219, 239, - 231, 38, 113, 219, 240, 115, 232, 143, 231, 38, 113, 219, 240, 235, 70, - 231, 38, 215, 209, 231, 38, 216, 224, 231, 38, 225, 191, 245, 232, 242, - 129, 243, 226, 216, 15, 226, 7, 251, 183, 226, 7, 216, 15, 249, 107, 127, - 251, 183, 249, 107, 127, 216, 15, 216, 7, 220, 55, 127, 251, 183, 216, 7, - 220, 55, 127, 71, 215, 240, 252, 43, 222, 237, 2, 250, 43, 218, 122, 244, - 72, 255, 26, 249, 104, 245, 179, 235, 205, 248, 91, 245, 32, 87, 85, 222, - 250, 52, 215, 226, 85, 233, 48, 52, 215, 226, 85, 214, 162, 52, 215, 226, - 85, 246, 113, 52, 215, 226, 85, 222, 250, 52, 215, 227, 2, 67, 130, 85, - 233, 48, 52, 215, 227, 2, 67, 130, 85, 222, 250, 215, 227, 2, 52, 67, - 130, 254, 182, 250, 11, 218, 128, 216, 87, 250, 11, 240, 244, 2, 244, 58, - 221, 243, 16, 31, 227, 206, 16, 31, 218, 154, 64, 241, 240, 16, 31, 218, - 154, 64, 216, 213, 16, 31, 245, 151, 64, 216, 213, 16, 31, 245, 151, 64, - 215, 244, 16, 31, 245, 140, 16, 31, 255, 16, 16, 31, 252, 52, 16, 31, - 252, 187, 16, 31, 203, 217, 90, 16, 31, 232, 220, 244, 153, 16, 31, 67, - 217, 90, 16, 31, 244, 28, 244, 153, 16, 31, 250, 238, 223, 56, 16, 31, - 220, 30, 226, 134, 16, 31, 220, 30, 236, 6, 16, 31, 248, 159, 232, 210, - 245, 85, 16, 31, 248, 39, 249, 186, 111, 16, 31, 248, 39, 249, 186, 105, - 16, 31, 248, 39, 249, 186, 158, 16, 31, 248, 39, 249, 186, 161, 16, 31, - 152, 255, 16, 16, 31, 217, 178, 236, 69, 16, 31, 245, 151, 64, 215, 245, - 251, 221, 16, 31, 251, 13, 16, 31, 245, 151, 64, 231, 86, 16, 31, 218, - 62, 16, 31, 245, 85, 16, 31, 244, 115, 220, 139, 16, 31, 242, 128, 220, - 139, 16, 31, 223, 124, 220, 139, 16, 31, 214, 174, 220, 139, 16, 31, 219, - 20, 16, 31, 248, 71, 251, 224, 87, 204, 251, 171, 16, 31, 229, 90, 16, - 31, 248, 72, 244, 28, 105, 16, 31, 218, 63, 244, 28, 105, 226, 245, 103, - 226, 245, 250, 160, 226, 245, 244, 31, 226, 245, 235, 200, 244, 31, 226, - 245, 252, 50, 251, 132, 226, 245, 251, 178, 216, 112, 226, 245, 251, 163, - 252, 154, 240, 110, 226, 245, 254, 135, 64, 250, 137, 226, 245, 248, 164, - 226, 245, 249, 95, 255, 20, 227, 204, 226, 245, 52, 252, 188, 37, 21, - 111, 37, 21, 105, 37, 21, 158, 37, 21, 161, 37, 21, 190, 37, 21, 195, 37, - 21, 199, 37, 21, 196, 37, 21, 201, 37, 54, 216, 248, 37, 54, 245, 175, - 37, 54, 215, 76, 37, 54, 216, 165, 37, 54, 244, 13, 37, 54, 244, 126, 37, - 54, 219, 121, 37, 54, 220, 121, 37, 54, 245, 198, 37, 54, 228, 202, 37, - 54, 215, 73, 88, 21, 111, 88, 21, 105, 88, 21, 158, 88, 21, 161, 88, 21, - 190, 88, 21, 195, 88, 21, 199, 88, 21, 196, 88, 21, 201, 88, 54, 216, - 248, 88, 54, 245, 175, 88, 54, 215, 76, 88, 54, 216, 165, 88, 54, 244, - 13, 88, 54, 244, 126, 88, 54, 219, 121, 88, 54, 220, 121, 88, 54, 245, - 198, 88, 54, 228, 202, 88, 54, 215, 73, 21, 123, 243, 236, 218, 131, 21, - 113, 243, 236, 218, 131, 21, 134, 243, 236, 218, 131, 21, 244, 19, 243, - 236, 218, 131, 21, 244, 89, 243, 236, 218, 131, 21, 219, 127, 243, 236, - 218, 131, 21, 220, 124, 243, 236, 218, 131, 21, 245, 201, 243, 236, 218, - 131, 21, 228, 205, 243, 236, 218, 131, 54, 216, 249, 243, 236, 218, 131, - 54, 245, 176, 243, 236, 218, 131, 54, 215, 77, 243, 236, 218, 131, 54, - 216, 166, 243, 236, 218, 131, 54, 244, 14, 243, 236, 218, 131, 54, 244, - 127, 243, 236, 218, 131, 54, 219, 122, 243, 236, 218, 131, 54, 220, 122, - 243, 236, 218, 131, 54, 245, 199, 243, 236, 218, 131, 54, 228, 203, 243, - 236, 218, 131, 54, 215, 74, 243, 236, 218, 131, 88, 7, 4, 1, 61, 88, 7, - 4, 1, 253, 166, 88, 7, 4, 1, 251, 74, 88, 7, 4, 1, 249, 68, 88, 7, 4, 1, - 76, 88, 7, 4, 1, 245, 14, 88, 7, 4, 1, 243, 209, 88, 7, 4, 1, 242, 67, - 88, 7, 4, 1, 74, 88, 7, 4, 1, 235, 150, 88, 7, 4, 1, 235, 29, 88, 7, 4, - 1, 156, 88, 7, 4, 1, 194, 88, 7, 4, 1, 230, 30, 88, 7, 4, 1, 78, 88, 7, - 4, 1, 226, 109, 88, 7, 4, 1, 224, 99, 88, 7, 4, 1, 153, 88, 7, 4, 1, 222, - 93, 88, 7, 4, 1, 217, 153, 88, 7, 4, 1, 69, 88, 7, 4, 1, 214, 105, 88, 7, - 4, 1, 212, 98, 88, 7, 4, 1, 211, 178, 88, 7, 4, 1, 211, 117, 88, 7, 4, 1, - 210, 159, 37, 7, 6, 1, 61, 37, 7, 6, 1, 253, 166, 37, 7, 6, 1, 251, 74, - 37, 7, 6, 1, 249, 68, 37, 7, 6, 1, 76, 37, 7, 6, 1, 245, 14, 37, 7, 6, 1, - 243, 209, 37, 7, 6, 1, 242, 67, 37, 7, 6, 1, 74, 37, 7, 6, 1, 235, 150, - 37, 7, 6, 1, 235, 29, 37, 7, 6, 1, 156, 37, 7, 6, 1, 194, 37, 7, 6, 1, - 230, 30, 37, 7, 6, 1, 78, 37, 7, 6, 1, 226, 109, 37, 7, 6, 1, 224, 99, - 37, 7, 6, 1, 153, 37, 7, 6, 1, 222, 93, 37, 7, 6, 1, 217, 153, 37, 7, 6, - 1, 69, 37, 7, 6, 1, 214, 105, 37, 7, 6, 1, 212, 98, 37, 7, 6, 1, 211, - 178, 37, 7, 6, 1, 211, 117, 37, 7, 6, 1, 210, 159, 37, 7, 4, 1, 61, 37, - 7, 4, 1, 253, 166, 37, 7, 4, 1, 251, 74, 37, 7, 4, 1, 249, 68, 37, 7, 4, - 1, 76, 37, 7, 4, 1, 245, 14, 37, 7, 4, 1, 243, 209, 37, 7, 4, 1, 242, 67, - 37, 7, 4, 1, 74, 37, 7, 4, 1, 235, 150, 37, 7, 4, 1, 235, 29, 37, 7, 4, - 1, 156, 37, 7, 4, 1, 194, 37, 7, 4, 1, 230, 30, 37, 7, 4, 1, 78, 37, 7, - 4, 1, 226, 109, 37, 7, 4, 1, 224, 99, 37, 7, 4, 1, 153, 37, 7, 4, 1, 222, - 93, 37, 7, 4, 1, 217, 153, 37, 7, 4, 1, 69, 37, 7, 4, 1, 214, 105, 37, 7, - 4, 1, 212, 98, 37, 7, 4, 1, 211, 178, 37, 7, 4, 1, 211, 117, 37, 7, 4, 1, - 210, 159, 37, 21, 210, 86, 152, 37, 54, 245, 175, 152, 37, 54, 215, 76, - 152, 37, 54, 216, 165, 152, 37, 54, 244, 13, 152, 37, 54, 244, 126, 152, - 37, 54, 219, 121, 152, 37, 54, 220, 121, 152, 37, 54, 245, 198, 152, 37, - 54, 228, 202, 152, 37, 54, 215, 73, 52, 37, 21, 111, 52, 37, 21, 105, 52, - 37, 21, 158, 52, 37, 21, 161, 52, 37, 21, 190, 52, 37, 21, 195, 52, 37, - 21, 199, 52, 37, 21, 196, 52, 37, 21, 201, 52, 37, 54, 216, 248, 152, 37, - 21, 210, 86, 93, 99, 193, 241, 51, 93, 99, 114, 241, 51, 93, 99, 193, - 213, 239, 93, 99, 114, 213, 239, 93, 99, 193, 215, 212, 248, 165, 241, - 51, 93, 99, 114, 215, 212, 248, 165, 241, 51, 93, 99, 193, 215, 212, 248, - 165, 213, 239, 93, 99, 114, 215, 212, 248, 165, 213, 239, 93, 99, 193, - 224, 27, 248, 165, 241, 51, 93, 99, 114, 224, 27, 248, 165, 241, 51, 93, - 99, 193, 224, 27, 248, 165, 213, 239, 93, 99, 114, 224, 27, 248, 165, - 213, 239, 93, 99, 193, 124, 22, 222, 254, 93, 99, 124, 193, 22, 44, 241, - 228, 93, 99, 124, 114, 22, 44, 232, 236, 93, 99, 114, 124, 22, 222, 254, - 93, 99, 193, 124, 22, 233, 52, 93, 99, 124, 193, 22, 43, 241, 228, 93, - 99, 124, 114, 22, 43, 232, 236, 93, 99, 114, 124, 22, 233, 52, 93, 99, - 193, 120, 22, 222, 254, 93, 99, 120, 193, 22, 44, 241, 228, 93, 99, 120, - 114, 22, 44, 232, 236, 93, 99, 114, 120, 22, 222, 254, 93, 99, 193, 120, - 22, 233, 52, 93, 99, 120, 193, 22, 43, 241, 228, 93, 99, 120, 114, 22, - 43, 232, 236, 93, 99, 114, 120, 22, 233, 52, 93, 99, 193, 67, 22, 222, - 254, 93, 99, 67, 193, 22, 44, 241, 228, 93, 99, 120, 114, 22, 44, 124, - 232, 236, 93, 99, 124, 114, 22, 44, 120, 232, 236, 93, 99, 67, 114, 22, - 44, 232, 236, 93, 99, 124, 193, 22, 44, 120, 241, 228, 93, 99, 120, 193, - 22, 44, 124, 241, 228, 93, 99, 114, 67, 22, 222, 254, 93, 99, 193, 67, - 22, 233, 52, 93, 99, 67, 193, 22, 43, 241, 228, 93, 99, 120, 114, 22, 43, - 124, 232, 236, 93, 99, 124, 114, 22, 43, 120, 232, 236, 93, 99, 67, 114, - 22, 43, 232, 236, 93, 99, 124, 193, 22, 43, 120, 241, 228, 93, 99, 120, - 193, 22, 43, 124, 241, 228, 93, 99, 114, 67, 22, 233, 52, 93, 99, 193, - 124, 22, 241, 51, 93, 99, 43, 114, 22, 44, 124, 232, 236, 93, 99, 44, - 114, 22, 43, 124, 232, 236, 93, 99, 124, 193, 22, 203, 241, 228, 93, 99, - 124, 114, 22, 203, 232, 236, 93, 99, 44, 193, 22, 43, 124, 241, 228, 93, - 99, 43, 193, 22, 44, 124, 241, 228, 93, 99, 114, 124, 22, 241, 51, 93, - 99, 193, 120, 22, 241, 51, 93, 99, 43, 114, 22, 44, 120, 232, 236, 93, - 99, 44, 114, 22, 43, 120, 232, 236, 93, 99, 120, 193, 22, 203, 241, 228, - 93, 99, 120, 114, 22, 203, 232, 236, 93, 99, 44, 193, 22, 43, 120, 241, - 228, 93, 99, 43, 193, 22, 44, 120, 241, 228, 93, 99, 114, 120, 22, 241, - 51, 93, 99, 193, 67, 22, 241, 51, 93, 99, 43, 114, 22, 44, 67, 232, 236, - 93, 99, 44, 114, 22, 43, 67, 232, 236, 93, 99, 67, 193, 22, 203, 241, - 228, 93, 99, 120, 114, 22, 124, 203, 232, 236, 93, 99, 124, 114, 22, 120, - 203, 232, 236, 93, 99, 67, 114, 22, 203, 232, 236, 93, 99, 43, 120, 114, - 22, 44, 124, 232, 236, 93, 99, 44, 120, 114, 22, 43, 124, 232, 236, 93, - 99, 43, 124, 114, 22, 44, 120, 232, 236, 93, 99, 44, 124, 114, 22, 43, - 120, 232, 236, 93, 99, 124, 193, 22, 120, 203, 241, 228, 93, 99, 120, - 193, 22, 124, 203, 241, 228, 93, 99, 44, 193, 22, 43, 67, 241, 228, 93, - 99, 43, 193, 22, 44, 67, 241, 228, 93, 99, 114, 67, 22, 241, 51, 93, 99, - 193, 52, 248, 165, 241, 51, 93, 99, 114, 52, 248, 165, 241, 51, 93, 99, - 193, 52, 248, 165, 213, 239, 93, 99, 114, 52, 248, 165, 213, 239, 93, 99, - 52, 241, 51, 93, 99, 52, 213, 239, 93, 99, 124, 219, 157, 22, 44, 246, - 121, 93, 99, 124, 52, 22, 44, 219, 156, 93, 99, 52, 124, 22, 222, 254, - 93, 99, 124, 219, 157, 22, 43, 246, 121, 93, 99, 124, 52, 22, 43, 219, - 156, 93, 99, 52, 124, 22, 233, 52, 93, 99, 120, 219, 157, 22, 44, 246, - 121, 93, 99, 120, 52, 22, 44, 219, 156, 93, 99, 52, 120, 22, 222, 254, - 93, 99, 120, 219, 157, 22, 43, 246, 121, 93, 99, 120, 52, 22, 43, 219, - 156, 93, 99, 52, 120, 22, 233, 52, 93, 99, 67, 219, 157, 22, 44, 246, - 121, 93, 99, 67, 52, 22, 44, 219, 156, 93, 99, 52, 67, 22, 222, 254, 93, - 99, 67, 219, 157, 22, 43, 246, 121, 93, 99, 67, 52, 22, 43, 219, 156, 93, - 99, 52, 67, 22, 233, 52, 93, 99, 124, 219, 157, 22, 203, 246, 121, 93, - 99, 124, 52, 22, 203, 219, 156, 93, 99, 52, 124, 22, 241, 51, 93, 99, - 120, 219, 157, 22, 203, 246, 121, 93, 99, 120, 52, 22, 203, 219, 156, 93, - 99, 52, 120, 22, 241, 51, 93, 99, 67, 219, 157, 22, 203, 246, 121, 93, - 99, 67, 52, 22, 203, 219, 156, 93, 99, 52, 67, 22, 241, 51, 93, 99, 193, - 254, 34, 124, 22, 222, 254, 93, 99, 193, 254, 34, 124, 22, 233, 52, 93, - 99, 193, 254, 34, 120, 22, 233, 52, 93, 99, 193, 254, 34, 120, 22, 222, - 254, 93, 99, 193, 248, 7, 214, 160, 44, 216, 43, 232, 114, 233, 52, 93, - 99, 193, 248, 7, 214, 160, 43, 216, 43, 232, 114, 222, 254, 93, 99, 193, - 248, 7, 249, 138, 93, 99, 193, 233, 52, 93, 99, 193, 214, 163, 93, 99, - 193, 222, 254, 93, 99, 193, 246, 114, 93, 99, 114, 233, 52, 93, 99, 114, - 214, 163, 93, 99, 114, 222, 254, 93, 99, 114, 246, 114, 93, 99, 193, 43, - 22, 114, 222, 254, 93, 99, 193, 120, 22, 114, 246, 114, 93, 99, 114, 43, - 22, 193, 222, 254, 93, 99, 114, 120, 22, 193, 246, 114, 214, 160, 163, - 251, 221, 232, 114, 123, 245, 197, 251, 221, 232, 114, 123, 224, 25, 251, - 221, 232, 114, 134, 245, 195, 251, 221, 232, 114, 163, 251, 221, 232, - 114, 244, 89, 245, 195, 251, 221, 232, 114, 134, 224, 23, 251, 221, 232, - 114, 220, 124, 245, 195, 251, 221, 243, 236, 251, 221, 43, 220, 124, 245, - 195, 251, 221, 43, 134, 224, 23, 251, 221, 43, 244, 89, 245, 195, 251, - 221, 43, 163, 251, 221, 43, 134, 245, 195, 251, 221, 43, 123, 224, 25, - 251, 221, 43, 123, 245, 197, 251, 221, 44, 163, 251, 221, 193, 220, 94, - 231, 87, 220, 94, 248, 170, 220, 94, 214, 160, 123, 245, 197, 251, 221, - 44, 123, 245, 197, 251, 221, 224, 29, 232, 114, 233, 52, 224, 29, 232, - 114, 222, 254, 224, 29, 214, 160, 233, 52, 224, 29, 214, 160, 43, 22, - 232, 114, 43, 22, 232, 114, 222, 254, 224, 29, 214, 160, 43, 22, 232, - 114, 222, 254, 224, 29, 214, 160, 43, 22, 214, 160, 44, 22, 232, 114, - 233, 52, 224, 29, 214, 160, 43, 22, 214, 160, 44, 22, 232, 114, 222, 254, - 224, 29, 214, 160, 222, 254, 224, 29, 214, 160, 44, 22, 232, 114, 233, - 52, 224, 29, 214, 160, 44, 22, 232, 114, 43, 22, 232, 114, 222, 254, 85, - 218, 236, 71, 218, 236, 71, 42, 2, 222, 185, 249, 167, 71, 42, 249, 195, - 85, 4, 218, 236, 42, 2, 203, 244, 113, 42, 2, 67, 244, 113, 42, 2, 226, - 148, 249, 134, 244, 113, 42, 2, 214, 160, 43, 216, 43, 232, 114, 44, 244, - 113, 42, 2, 214, 160, 44, 216, 43, 232, 114, 43, 244, 113, 42, 2, 248, 7, - 249, 134, 244, 113, 85, 4, 218, 236, 71, 4, 218, 236, 85, 223, 119, 71, - 223, 119, 85, 67, 223, 119, 71, 67, 223, 119, 85, 226, 10, 71, 226, 10, - 85, 214, 162, 215, 226, 71, 214, 162, 215, 226, 85, 214, 162, 4, 215, - 226, 71, 214, 162, 4, 215, 226, 85, 222, 250, 215, 226, 71, 222, 250, - 215, 226, 85, 222, 250, 4, 215, 226, 71, 222, 250, 4, 215, 226, 85, 222, - 250, 225, 11, 71, 222, 250, 225, 11, 85, 246, 113, 215, 226, 71, 246, - 113, 215, 226, 85, 246, 113, 4, 215, 226, 71, 246, 113, 4, 215, 226, 85, - 233, 48, 215, 226, 71, 233, 48, 215, 226, 85, 233, 48, 4, 215, 226, 71, - 233, 48, 4, 215, 226, 85, 233, 48, 225, 11, 71, 233, 48, 225, 11, 85, - 248, 0, 71, 248, 0, 71, 248, 1, 249, 195, 85, 4, 248, 0, 244, 97, 232, - 110, 71, 250, 43, 246, 126, 250, 43, 250, 44, 2, 67, 244, 113, 251, 119, - 85, 250, 43, 250, 44, 2, 43, 163, 251, 229, 250, 44, 2, 44, 163, 251, - 229, 250, 44, 2, 232, 114, 163, 251, 229, 250, 44, 2, 214, 160, 163, 251, - 229, 250, 44, 2, 214, 160, 44, 224, 29, 251, 229, 250, 44, 2, 254, 164, - 251, 96, 214, 160, 43, 224, 29, 251, 229, 43, 163, 85, 250, 43, 44, 163, - 85, 250, 43, 235, 201, 251, 121, 235, 201, 71, 250, 43, 214, 160, 163, - 235, 201, 71, 250, 43, 232, 114, 163, 235, 201, 71, 250, 43, 214, 160, - 43, 224, 29, 250, 41, 254, 33, 214, 160, 44, 224, 29, 250, 41, 254, 33, - 232, 114, 44, 224, 29, 250, 41, 254, 33, 232, 114, 43, 224, 29, 250, 41, - 254, 33, 214, 160, 163, 250, 43, 232, 114, 163, 250, 43, 85, 232, 114, - 44, 215, 226, 85, 232, 114, 43, 215, 226, 85, 214, 160, 43, 215, 226, 85, - 214, 160, 44, 215, 226, 71, 251, 121, 42, 2, 43, 163, 251, 229, 42, 2, - 44, 163, 251, 229, 42, 2, 214, 160, 43, 248, 7, 163, 251, 229, 42, 2, - 232, 114, 44, 248, 7, 163, 251, 229, 71, 42, 2, 67, 251, 240, 232, 219, - 71, 214, 162, 215, 227, 2, 247, 128, 214, 162, 215, 227, 2, 43, 163, 251, - 229, 214, 162, 215, 227, 2, 44, 163, 251, 229, 233, 91, 250, 43, 71, 42, - 2, 214, 160, 43, 224, 28, 71, 42, 2, 232, 114, 43, 224, 28, 71, 42, 2, - 232, 114, 44, 224, 28, 71, 42, 2, 214, 160, 44, 224, 28, 71, 250, 44, 2, - 214, 160, 43, 224, 28, 71, 250, 44, 2, 232, 114, 43, 224, 28, 71, 250, - 44, 2, 232, 114, 44, 224, 28, 71, 250, 44, 2, 214, 160, 44, 224, 28, 214, - 160, 43, 215, 226, 214, 160, 44, 215, 226, 232, 114, 43, 215, 226, 71, - 231, 87, 218, 236, 85, 231, 87, 218, 236, 71, 231, 87, 4, 218, 236, 85, - 231, 87, 4, 218, 236, 232, 114, 44, 215, 226, 85, 218, 39, 2, 223, 135, - 249, 255, 214, 194, 219, 62, 249, 230, 85, 218, 158, 71, 218, 158, 232, - 234, 216, 133, 218, 38, 253, 242, 228, 76, 248, 46, 228, 76, 249, 203, - 226, 167, 85, 217, 1, 71, 217, 1, 252, 164, 251, 171, 252, 164, 93, 2, - 250, 137, 252, 164, 93, 2, 211, 178, 222, 0, 214, 195, 2, 223, 163, 246, - 92, 240, 250, 252, 30, 71, 220, 4, 225, 104, 85, 220, 4, 225, 104, 220, - 89, 223, 52, 222, 189, 244, 63, 241, 235, 251, 121, 85, 43, 225, 10, 235, - 249, 85, 44, 225, 10, 235, 249, 71, 43, 225, 10, 235, 249, 71, 120, 225, - 10, 235, 249, 71, 44, 225, 10, 235, 249, 71, 124, 225, 10, 235, 249, 219, - 103, 22, 249, 137, 250, 227, 50, 223, 175, 50, 251, 247, 50, 251, 33, - 254, 110, 226, 149, 249, 138, 250, 119, 223, 40, 249, 139, 64, 232, 124, - 249, 139, 64, 235, 122, 218, 159, 22, 249, 144, 244, 176, 87, 255, 1, - 220, 91, 242, 29, 22, 219, 191, 225, 223, 87, 210, 254, 211, 69, 215, - 216, 31, 241, 230, 215, 216, 31, 233, 113, 215, 216, 31, 244, 104, 215, - 216, 31, 216, 134, 215, 216, 31, 211, 239, 215, 216, 31, 212, 40, 215, - 216, 31, 230, 120, 215, 216, 31, 245, 231, 212, 1, 64, 248, 26, 71, 243, - 247, 244, 198, 71, 219, 76, 244, 198, 85, 219, 76, 244, 198, 71, 218, 39, - 2, 223, 135, 244, 100, 224, 25, 230, 133, 233, 86, 224, 25, 230, 133, - 231, 59, 244, 146, 50, 245, 231, 231, 195, 50, 235, 44, 221, 222, 214, - 145, 229, 98, 225, 23, 254, 20, 217, 41, 243, 59, 251, 11, 233, 25, 213, - 150, 232, 244, 221, 193, 222, 21, 251, 0, 254, 50, 225, 55, 71, 250, 125, - 234, 84, 71, 250, 125, 224, 17, 71, 250, 125, 222, 197, 71, 250, 125, - 251, 239, 71, 250, 125, 234, 36, 71, 250, 125, 225, 235, 85, 250, 125, - 234, 84, 85, 250, 125, 224, 17, 85, 250, 125, 222, 197, 85, 250, 125, - 251, 239, 85, 250, 125, 234, 36, 85, 250, 125, 225, 235, 85, 219, 18, - 218, 51, 71, 241, 235, 218, 51, 71, 248, 1, 218, 51, 85, 249, 253, 218, - 51, 71, 219, 18, 218, 51, 85, 241, 235, 218, 51, 85, 248, 1, 218, 51, 71, - 249, 253, 218, 51, 240, 250, 218, 240, 224, 25, 228, 52, 245, 197, 228, - 52, 252, 81, 245, 197, 228, 47, 252, 81, 219, 120, 228, 47, 230, 62, 244, - 74, 50, 230, 62, 229, 193, 50, 230, 62, 220, 78, 50, 212, 9, 183, 249, - 138, 245, 228, 183, 249, 138, 214, 171, 223, 115, 87, 223, 115, 16, 31, - 215, 48, 225, 37, 223, 115, 16, 31, 215, 47, 225, 37, 223, 115, 16, 31, - 215, 46, 225, 37, 223, 115, 16, 31, 215, 45, 225, 37, 223, 115, 16, 31, - 215, 44, 225, 37, 223, 115, 16, 31, 215, 43, 225, 37, 223, 115, 16, 31, - 215, 42, 225, 37, 223, 115, 16, 31, 243, 57, 231, 143, 85, 214, 171, 223, - 115, 87, 223, 116, 226, 24, 87, 226, 0, 226, 24, 87, 225, 177, 226, 24, - 50, 211, 255, 87, 247, 249, 244, 197, 247, 249, 244, 196, 247, 249, 244, - 195, 247, 249, 244, 194, 247, 249, 244, 193, 247, 249, 244, 192, 71, 250, - 44, 2, 59, 222, 254, 71, 250, 44, 2, 113, 247, 126, 85, 250, 44, 2, 71, - 59, 222, 254, 85, 250, 44, 2, 113, 71, 247, 126, 230, 147, 31, 211, 69, - 230, 147, 31, 210, 253, 247, 232, 31, 242, 138, 211, 69, 247, 232, 31, - 233, 19, 210, 253, 247, 232, 31, 233, 19, 211, 69, 247, 232, 31, 242, - 138, 210, 253, 71, 244, 81, 85, 244, 81, 242, 29, 22, 225, 107, 254, 128, - 249, 136, 217, 236, 218, 166, 64, 254, 235, 221, 208, 254, 178, 244, 59, - 243, 67, 218, 166, 64, 241, 209, 253, 207, 87, 244, 70, 226, 130, 71, - 218, 158, 134, 232, 214, 249, 183, 222, 254, 134, 232, 214, 249, 183, - 233, 52, 212, 50, 50, 125, 213, 130, 50, 246, 118, 244, 146, 50, 246, - 118, 231, 195, 50, 235, 210, 244, 146, 22, 231, 195, 50, 231, 195, 22, - 244, 146, 50, 231, 195, 2, 218, 105, 50, 231, 195, 2, 218, 105, 22, 231, - 195, 22, 244, 146, 50, 67, 231, 195, 2, 218, 105, 50, 203, 231, 195, 2, - 218, 105, 50, 231, 87, 71, 250, 43, 231, 87, 85, 250, 43, 231, 87, 4, 71, - 250, 43, 231, 158, 87, 247, 175, 87, 214, 169, 225, 255, 87, 249, 239, - 243, 231, 214, 141, 229, 93, 250, 169, 226, 65, 235, 50, 213, 185, 250, - 101, 85, 230, 134, 232, 231, 220, 114, 220, 149, 224, 8, 220, 132, 219, - 57, 252, 167, 252, 134, 92, 234, 144, 71, 246, 101, 231, 190, 71, 246, - 101, 234, 84, 85, 246, 101, 231, 190, 85, 246, 101, 234, 84, 219, 63, - 211, 230, 219, 66, 218, 39, 252, 59, 249, 255, 223, 162, 85, 219, 62, - 216, 135, 250, 0, 22, 223, 162, 215, 94, 71, 220, 4, 225, 104, 215, 94, - 85, 220, 4, 225, 104, 71, 248, 1, 236, 7, 218, 236, 249, 133, 233, 97, - 247, 201, 250, 252, 226, 170, 225, 107, 250, 253, 219, 90, 241, 219, 2, - 71, 249, 138, 37, 249, 133, 233, 97, 250, 161, 228, 80, 245, 132, 254, - 149, 226, 195, 43, 212, 26, 215, 252, 85, 215, 55, 43, 212, 26, 215, 252, - 71, 215, 55, 43, 212, 26, 215, 252, 85, 43, 233, 98, 231, 58, 71, 43, - 233, 98, 231, 58, 246, 97, 219, 84, 50, 114, 71, 246, 113, 215, 226, 43, - 250, 8, 245, 132, 92, 222, 0, 244, 183, 248, 7, 236, 7, 71, 250, 44, 236, - 7, 85, 218, 236, 85, 215, 193, 223, 63, 43, 245, 131, 223, 63, 43, 245, - 130, 253, 219, 16, 31, 214, 145, 114, 250, 44, 2, 218, 105, 22, 113, 170, - 48, 225, 192, 222, 251, 235, 212, 225, 192, 233, 49, 235, 212, 225, 192, - 235, 200, 225, 192, 85, 249, 139, 226, 201, 220, 31, 220, 19, 219, 231, - 250, 69, 250, 234, 241, 164, 219, 128, 243, 68, 211, 230, 240, 227, 243, - 68, 2, 242, 19, 231, 178, 16, 31, 232, 235, 230, 120, 214, 195, 226, 201, - 242, 129, 244, 20, 244, 82, 236, 7, 241, 66, 244, 137, 222, 16, 42, 244, - 19, 249, 167, 219, 106, 240, 119, 219, 109, 225, 171, 2, 252, 167, 216, - 243, 235, 137, 252, 154, 87, 241, 238, 242, 140, 87, 243, 239, 224, 145, - 249, 111, 226, 201, 85, 218, 236, 71, 244, 82, 2, 203, 230, 229, 85, 218, - 106, 214, 160, 251, 225, 221, 195, 85, 221, 195, 232, 114, 251, 225, 221, - 195, 71, 221, 195, 71, 114, 250, 138, 79, 217, 2, 232, 160, 50, 217, 54, - 246, 96, 254, 200, 245, 127, 223, 160, 244, 93, 223, 160, 242, 22, 213, - 174, 242, 22, 211, 198, 242, 22, 232, 114, 44, 225, 201, 225, 201, 214, - 160, 44, 225, 201, 71, 228, 235, 85, 228, 235, 250, 138, 79, 114, 250, - 138, 79, 230, 89, 211, 178, 114, 230, 89, 211, 178, 252, 164, 211, 178, - 114, 252, 164, 211, 178, 226, 130, 26, 249, 138, 114, 26, 249, 138, 204, - 250, 183, 249, 138, 114, 204, 250, 183, 249, 138, 7, 249, 138, 220, 93, - 71, 7, 249, 138, 226, 130, 7, 249, 138, 231, 192, 249, 138, 218, 159, 64, - 248, 157, 244, 19, 217, 16, 253, 224, 244, 19, 252, 165, 253, 224, 114, - 244, 19, 252, 165, 253, 224, 244, 19, 249, 251, 253, 224, 85, 244, 19, - 225, 12, 218, 158, 71, 244, 19, 225, 12, 218, 158, 219, 13, 218, 113, - 226, 130, 71, 218, 158, 37, 71, 218, 158, 204, 250, 183, 85, 218, 158, - 85, 250, 183, 71, 218, 158, 226, 130, 85, 218, 158, 114, 226, 130, 85, - 218, 158, 225, 63, 218, 158, 220, 93, 71, 218, 158, 114, 253, 224, 204, - 250, 183, 253, 224, 245, 201, 218, 246, 253, 224, 245, 201, 225, 12, 85, - 218, 158, 245, 201, 225, 12, 225, 63, 218, 158, 219, 127, 225, 12, 85, - 218, 158, 245, 201, 225, 12, 223, 117, 85, 218, 158, 114, 245, 201, 225, - 12, 223, 117, 85, 218, 158, 215, 77, 225, 12, 85, 218, 158, 219, 122, - 225, 12, 253, 224, 217, 16, 253, 224, 204, 250, 183, 217, 16, 253, 224, - 114, 217, 16, 253, 224, 219, 127, 225, 160, 85, 22, 71, 244, 62, 85, 244, - 62, 71, 244, 62, 245, 201, 225, 160, 226, 130, 85, 244, 62, 37, 204, 250, - 183, 245, 201, 225, 12, 218, 158, 114, 217, 16, 225, 63, 253, 224, 219, - 64, 216, 106, 215, 219, 219, 64, 114, 250, 122, 219, 64, 219, 15, 114, - 219, 15, 252, 165, 253, 224, 245, 201, 217, 16, 224, 174, 253, 224, 114, - 245, 201, 217, 16, 224, 174, 253, 224, 249, 139, 79, 220, 93, 71, 250, - 43, 152, 92, 249, 139, 79, 232, 114, 44, 246, 94, 71, 218, 236, 214, 160, - 44, 246, 94, 71, 218, 236, 232, 114, 44, 220, 93, 71, 218, 236, 214, 160, - 44, 220, 93, 71, 218, 236, 85, 224, 16, 164, 226, 151, 71, 224, 16, 164, - 226, 151, 71, 245, 39, 164, 226, 151, 85, 248, 1, 230, 187, 71, 211, 178, - 114, 245, 39, 164, 87, 193, 67, 130, 231, 87, 67, 130, 114, 67, 130, 114, - 219, 157, 215, 94, 249, 228, 224, 1, 164, 226, 151, 114, 219, 157, 249, - 228, 224, 1, 164, 226, 151, 114, 52, 215, 94, 249, 228, 224, 1, 164, 226, - 151, 114, 52, 249, 228, 224, 1, 164, 226, 151, 114, 121, 219, 157, 249, - 228, 224, 1, 164, 226, 151, 114, 121, 52, 249, 228, 224, 1, 164, 226, - 151, 249, 99, 218, 142, 226, 19, 5, 226, 151, 114, 245, 39, 164, 226, - 151, 114, 241, 235, 245, 39, 164, 226, 151, 114, 85, 241, 234, 222, 189, - 114, 85, 241, 235, 251, 121, 244, 63, 241, 234, 222, 189, 244, 63, 241, - 235, 251, 121, 231, 87, 43, 226, 8, 226, 151, 231, 87, 44, 226, 8, 226, - 151, 231, 87, 244, 71, 43, 226, 8, 226, 151, 231, 87, 244, 71, 44, 226, - 8, 226, 151, 231, 87, 233, 48, 254, 118, 251, 166, 226, 151, 231, 87, - 222, 250, 254, 118, 251, 166, 226, 151, 114, 233, 48, 254, 118, 224, 1, - 164, 226, 151, 114, 222, 250, 254, 118, 224, 1, 164, 226, 151, 114, 233, - 48, 254, 118, 251, 166, 226, 151, 114, 222, 250, 254, 118, 251, 166, 226, - 151, 193, 43, 216, 7, 220, 55, 251, 166, 226, 151, 193, 44, 216, 7, 220, - 55, 251, 166, 226, 151, 231, 87, 43, 249, 107, 251, 166, 226, 151, 231, - 87, 44, 249, 107, 251, 166, 226, 151, 247, 212, 152, 37, 21, 111, 247, - 212, 152, 37, 21, 105, 247, 212, 152, 37, 21, 158, 247, 212, 152, 37, 21, - 161, 247, 212, 152, 37, 21, 190, 247, 212, 152, 37, 21, 195, 247, 212, - 152, 37, 21, 199, 247, 212, 152, 37, 21, 196, 247, 212, 152, 37, 21, 201, - 247, 212, 152, 37, 54, 216, 248, 247, 212, 37, 35, 21, 111, 247, 212, 37, - 35, 21, 105, 247, 212, 37, 35, 21, 158, 247, 212, 37, 35, 21, 161, 247, - 212, 37, 35, 21, 190, 247, 212, 37, 35, 21, 195, 247, 212, 37, 35, 21, - 199, 247, 212, 37, 35, 21, 196, 247, 212, 37, 35, 21, 201, 247, 212, 37, - 35, 54, 216, 248, 247, 212, 152, 37, 35, 21, 111, 247, 212, 152, 37, 35, - 21, 105, 247, 212, 152, 37, 35, 21, 158, 247, 212, 152, 37, 35, 21, 161, - 247, 212, 152, 37, 35, 21, 190, 247, 212, 152, 37, 35, 21, 195, 247, 212, - 152, 37, 35, 21, 199, 247, 212, 152, 37, 35, 21, 196, 247, 212, 152, 37, - 35, 21, 201, 247, 212, 152, 37, 35, 54, 216, 248, 114, 211, 246, 97, 75, - 114, 96, 50, 114, 230, 187, 50, 114, 247, 177, 50, 114, 219, 30, 245, - 228, 75, 114, 97, 75, 114, 228, 61, 245, 228, 75, 246, 106, 225, 14, 97, - 75, 114, 222, 186, 97, 75, 215, 225, 97, 75, 114, 215, 225, 97, 75, 248, - 163, 215, 225, 97, 75, 114, 248, 163, 215, 225, 97, 75, 85, 97, 75, 216, - 145, 216, 13, 97, 254, 1, 216, 145, 251, 181, 97, 254, 1, 85, 97, 254, 1, - 114, 85, 249, 99, 246, 112, 22, 97, 75, 114, 85, 249, 99, 214, 153, 22, - 97, 75, 218, 233, 85, 97, 75, 114, 249, 214, 85, 97, 75, 222, 249, 71, - 97, 75, 233, 47, 71, 97, 75, 252, 191, 220, 93, 71, 97, 75, 243, 249, - 220, 93, 71, 97, 75, 114, 232, 114, 222, 248, 71, 97, 75, 114, 214, 160, - 222, 248, 71, 97, 75, 228, 54, 232, 114, 222, 248, 71, 97, 75, 249, 107, - 232, 129, 228, 54, 214, 160, 222, 248, 71, 97, 75, 37, 114, 71, 97, 75, - 211, 252, 97, 75, 251, 228, 219, 30, 245, 228, 75, 251, 228, 97, 75, 251, - 228, 228, 61, 245, 228, 75, 114, 251, 228, 219, 30, 245, 228, 75, 114, - 251, 228, 97, 75, 114, 251, 228, 228, 61, 245, 228, 75, 217, 18, 97, 75, - 114, 217, 17, 97, 75, 212, 18, 97, 75, 114, 212, 18, 97, 75, 226, 176, - 97, 75, 52, 249, 107, 232, 129, 134, 247, 222, 254, 117, 71, 215, 227, - 249, 195, 4, 71, 215, 226, 225, 174, 204, 218, 64, 204, 218, 22, 43, 222, - 92, 252, 181, 248, 68, 44, 222, 92, 252, 181, 248, 68, 177, 2, 59, 235, - 222, 223, 53, 219, 49, 224, 204, 218, 64, 218, 23, 224, 204, 219, 48, 67, - 252, 149, 2, 203, 91, 11, 222, 231, 248, 6, 200, 247, 176, 11, 244, 183, - 248, 6, 92, 232, 152, 254, 126, 92, 232, 152, 226, 162, 71, 248, 1, 2, - 250, 181, 247, 128, 22, 2, 247, 128, 245, 178, 64, 226, 174, 214, 152, - 232, 114, 44, 249, 169, 2, 247, 128, 214, 160, 43, 249, 169, 2, 247, 128, - 43, 226, 132, 235, 72, 44, 226, 132, 235, 72, 243, 236, 226, 132, 235, - 72, 233, 91, 120, 217, 88, 233, 91, 124, 217, 88, 43, 22, 44, 52, 215, - 93, 43, 22, 44, 217, 88, 43, 230, 92, 200, 44, 217, 88, 200, 43, 217, 88, - 120, 217, 89, 2, 250, 44, 48, 232, 111, 247, 181, 251, 86, 203, 222, 135, - 71, 249, 213, 248, 0, 71, 249, 213, 248, 1, 2, 140, 216, 115, 71, 249, - 213, 248, 1, 2, 97, 216, 115, 71, 42, 2, 140, 216, 115, 71, 42, 2, 97, - 216, 115, 11, 43, 71, 42, 127, 11, 44, 71, 42, 127, 11, 43, 254, 118, - 127, 11, 44, 254, 118, 127, 11, 43, 52, 254, 118, 127, 11, 44, 52, 254, - 118, 127, 11, 43, 71, 216, 7, 220, 55, 127, 11, 44, 71, 216, 7, 220, 55, - 127, 11, 43, 244, 71, 226, 7, 11, 44, 244, 71, 226, 7, 214, 153, 224, 27, - 75, 246, 112, 224, 27, 75, 254, 96, 243, 105, 250, 44, 75, 250, 10, 243, - 105, 250, 44, 75, 44, 80, 2, 37, 225, 25, 200, 140, 75, 200, 97, 75, 200, - 43, 44, 75, 200, 140, 52, 75, 200, 97, 52, 75, 200, 43, 44, 52, 75, 200, - 140, 80, 243, 251, 130, 200, 97, 80, 243, 251, 130, 200, 140, 52, 80, - 243, 251, 130, 200, 97, 52, 80, 243, 251, 130, 200, 97, 218, 232, 75, 46, - 47, 251, 223, 46, 47, 247, 125, 46, 47, 246, 253, 46, 47, 247, 124, 46, - 47, 246, 189, 46, 47, 247, 60, 46, 47, 246, 252, 46, 47, 247, 123, 46, - 47, 246, 157, 46, 47, 247, 28, 46, 47, 246, 220, 46, 47, 247, 91, 46, 47, - 246, 188, 46, 47, 247, 59, 46, 47, 246, 251, 46, 47, 247, 122, 46, 47, - 246, 141, 46, 47, 247, 12, 46, 47, 246, 204, 46, 47, 247, 75, 46, 47, - 246, 172, 46, 47, 247, 43, 46, 47, 246, 235, 46, 47, 247, 106, 46, 47, - 246, 156, 46, 47, 247, 27, 46, 47, 246, 219, 46, 47, 247, 90, 46, 47, - 246, 187, 46, 47, 247, 58, 46, 47, 246, 250, 46, 47, 247, 121, 46, 47, - 246, 133, 46, 47, 247, 4, 46, 47, 246, 196, 46, 47, 247, 67, 46, 47, 246, - 164, 46, 47, 247, 35, 46, 47, 246, 227, 46, 47, 247, 98, 46, 47, 246, - 148, 46, 47, 247, 19, 46, 47, 246, 211, 46, 47, 247, 82, 46, 47, 246, - 179, 46, 47, 247, 50, 46, 47, 246, 242, 46, 47, 247, 113, 46, 47, 246, - 140, 46, 47, 247, 11, 46, 47, 246, 203, 46, 47, 247, 74, 46, 47, 246, - 171, 46, 47, 247, 42, 46, 47, 246, 234, 46, 47, 247, 105, 46, 47, 246, - 155, 46, 47, 247, 26, 46, 47, 246, 218, 46, 47, 247, 89, 46, 47, 246, - 186, 46, 47, 247, 57, 46, 47, 246, 249, 46, 47, 247, 120, 46, 47, 246, - 129, 46, 47, 247, 0, 46, 47, 246, 192, 46, 47, 247, 63, 46, 47, 246, 160, - 46, 47, 247, 31, 46, 47, 246, 223, 46, 47, 247, 94, 46, 47, 246, 144, 46, - 47, 247, 15, 46, 47, 246, 207, 46, 47, 247, 78, 46, 47, 246, 175, 46, 47, - 247, 46, 46, 47, 246, 238, 46, 47, 247, 109, 46, 47, 246, 136, 46, 47, - 247, 7, 46, 47, 246, 199, 46, 47, 247, 70, 46, 47, 246, 167, 46, 47, 247, - 38, 46, 47, 246, 230, 46, 47, 247, 101, 46, 47, 246, 151, 46, 47, 247, - 22, 46, 47, 246, 214, 46, 47, 247, 85, 46, 47, 246, 182, 46, 47, 247, 53, - 46, 47, 246, 245, 46, 47, 247, 116, 46, 47, 246, 132, 46, 47, 247, 3, 46, - 47, 246, 195, 46, 47, 247, 66, 46, 47, 246, 163, 46, 47, 247, 34, 46, 47, - 246, 226, 46, 47, 247, 97, 46, 47, 246, 147, 46, 47, 247, 18, 46, 47, - 246, 210, 46, 47, 247, 81, 46, 47, 246, 178, 46, 47, 247, 49, 46, 47, - 246, 241, 46, 47, 247, 112, 46, 47, 246, 139, 46, 47, 247, 10, 46, 47, - 246, 202, 46, 47, 247, 73, 46, 47, 246, 170, 46, 47, 247, 41, 46, 47, - 246, 233, 46, 47, 247, 104, 46, 47, 246, 154, 46, 47, 247, 25, 46, 47, - 246, 217, 46, 47, 247, 88, 46, 47, 246, 185, 46, 47, 247, 56, 46, 47, - 246, 248, 46, 47, 247, 119, 46, 47, 246, 127, 46, 47, 246, 254, 46, 47, - 246, 190, 46, 47, 247, 61, 46, 47, 246, 158, 46, 47, 247, 29, 46, 47, - 246, 221, 46, 47, 247, 92, 46, 47, 246, 142, 46, 47, 247, 13, 46, 47, - 246, 205, 46, 47, 247, 76, 46, 47, 246, 173, 46, 47, 247, 44, 46, 47, - 246, 236, 46, 47, 247, 107, 46, 47, 246, 134, 46, 47, 247, 5, 46, 47, - 246, 197, 46, 47, 247, 68, 46, 47, 246, 165, 46, 47, 247, 36, 46, 47, - 246, 228, 46, 47, 247, 99, 46, 47, 246, 149, 46, 47, 247, 20, 46, 47, - 246, 212, 46, 47, 247, 83, 46, 47, 246, 180, 46, 47, 247, 51, 46, 47, - 246, 243, 46, 47, 247, 114, 46, 47, 246, 130, 46, 47, 247, 1, 46, 47, - 246, 193, 46, 47, 247, 64, 46, 47, 246, 161, 46, 47, 247, 32, 46, 47, - 246, 224, 46, 47, 247, 95, 46, 47, 246, 145, 46, 47, 247, 16, 46, 47, - 246, 208, 46, 47, 247, 79, 46, 47, 246, 176, 46, 47, 247, 47, 46, 47, - 246, 239, 46, 47, 247, 110, 46, 47, 246, 137, 46, 47, 247, 8, 46, 47, - 246, 200, 46, 47, 247, 71, 46, 47, 246, 168, 46, 47, 247, 39, 46, 47, - 246, 231, 46, 47, 247, 102, 46, 47, 246, 152, 46, 47, 247, 23, 46, 47, - 246, 215, 46, 47, 247, 86, 46, 47, 246, 183, 46, 47, 247, 54, 46, 47, - 246, 246, 46, 47, 247, 117, 46, 47, 246, 128, 46, 47, 246, 255, 46, 47, - 246, 191, 46, 47, 247, 62, 46, 47, 246, 159, 46, 47, 247, 30, 46, 47, - 246, 222, 46, 47, 247, 93, 46, 47, 246, 143, 46, 47, 247, 14, 46, 47, - 246, 206, 46, 47, 247, 77, 46, 47, 246, 174, 46, 47, 247, 45, 46, 47, - 246, 237, 46, 47, 247, 108, 46, 47, 246, 135, 46, 47, 247, 6, 46, 47, - 246, 198, 46, 47, 247, 69, 46, 47, 246, 166, 46, 47, 247, 37, 46, 47, - 246, 229, 46, 47, 247, 100, 46, 47, 246, 150, 46, 47, 247, 21, 46, 47, - 246, 213, 46, 47, 247, 84, 46, 47, 246, 181, 46, 47, 247, 52, 46, 47, - 246, 244, 46, 47, 247, 115, 46, 47, 246, 131, 46, 47, 247, 2, 46, 47, - 246, 194, 46, 47, 247, 65, 46, 47, 246, 162, 46, 47, 247, 33, 46, 47, - 246, 225, 46, 47, 247, 96, 46, 47, 246, 146, 46, 47, 247, 17, 46, 47, - 246, 209, 46, 47, 247, 80, 46, 47, 246, 177, 46, 47, 247, 48, 46, 47, - 246, 240, 46, 47, 247, 111, 46, 47, 246, 138, 46, 47, 247, 9, 46, 47, - 246, 201, 46, 47, 247, 72, 46, 47, 246, 169, 46, 47, 247, 40, 46, 47, - 246, 232, 46, 47, 247, 103, 46, 47, 246, 153, 46, 47, 247, 24, 46, 47, - 246, 216, 46, 47, 247, 87, 46, 47, 246, 184, 46, 47, 247, 55, 46, 47, - 246, 247, 46, 47, 247, 118, 97, 215, 58, 80, 2, 67, 91, 97, 215, 58, 80, - 2, 52, 67, 91, 140, 52, 80, 2, 67, 91, 97, 52, 80, 2, 67, 91, 43, 44, 52, - 80, 2, 67, 91, 97, 215, 58, 80, 243, 251, 130, 140, 52, 80, 243, 251, - 130, 97, 52, 80, 243, 251, 130, 246, 112, 80, 2, 203, 91, 214, 153, 80, - 2, 203, 91, 214, 153, 215, 212, 75, 246, 112, 215, 212, 75, 140, 52, 248, - 165, 75, 97, 52, 248, 165, 75, 140, 215, 212, 248, 165, 75, 97, 215, 212, - 248, 165, 75, 97, 215, 58, 215, 212, 248, 165, 75, 97, 80, 2, 246, 126, - 218, 141, 214, 153, 80, 216, 43, 130, 246, 112, 80, 216, 43, 130, 97, 80, - 2, 217, 79, 2, 67, 91, 97, 80, 2, 217, 79, 2, 52, 67, 91, 97, 215, 58, - 80, 2, 217, 78, 97, 215, 58, 80, 2, 217, 79, 2, 67, 91, 97, 215, 58, 80, - 2, 217, 79, 2, 52, 67, 91, 140, 254, 3, 97, 254, 3, 140, 52, 254, 3, 97, - 52, 254, 3, 140, 80, 216, 43, 85, 248, 0, 97, 80, 216, 43, 85, 248, 0, - 140, 80, 243, 251, 252, 149, 216, 43, 85, 248, 0, 97, 80, 243, 251, 252, - 149, 216, 43, 85, 248, 0, 228, 61, 212, 9, 22, 219, 30, 245, 228, 75, - 228, 61, 245, 228, 22, 219, 30, 212, 9, 75, 228, 61, 212, 9, 80, 2, 103, - 228, 61, 245, 228, 80, 2, 103, 219, 30, 245, 228, 80, 2, 103, 219, 30, - 212, 9, 80, 2, 103, 228, 61, 212, 9, 80, 22, 228, 61, 245, 228, 75, 228, - 61, 245, 228, 80, 22, 219, 30, 245, 228, 75, 219, 30, 245, 228, 80, 22, - 219, 30, 212, 9, 75, 219, 30, 212, 9, 80, 22, 228, 61, 212, 9, 75, 222, - 231, 248, 7, 249, 133, 244, 183, 248, 6, 244, 183, 248, 7, 249, 133, 222, - 231, 248, 6, 219, 30, 245, 228, 80, 249, 133, 228, 61, 245, 228, 75, 228, - 61, 245, 228, 80, 249, 133, 219, 30, 245, 228, 75, 244, 183, 248, 7, 249, - 133, 228, 61, 245, 228, 75, 222, 231, 248, 7, 249, 133, 219, 30, 245, - 228, 75, 228, 61, 245, 228, 80, 249, 133, 228, 61, 212, 9, 75, 228, 61, - 212, 9, 80, 249, 133, 228, 61, 245, 228, 75, 212, 36, 80, 225, 10, 247, - 203, 222, 254, 80, 225, 10, 97, 216, 189, 249, 98, 214, 152, 80, 225, 10, - 97, 216, 189, 249, 98, 246, 111, 80, 225, 10, 246, 112, 216, 189, 249, - 98, 233, 43, 80, 225, 10, 246, 112, 216, 189, 249, 98, 222, 244, 222, - 247, 254, 34, 250, 10, 75, 233, 46, 254, 34, 254, 96, 75, 216, 15, 254, - 34, 254, 96, 75, 251, 183, 254, 34, 254, 96, 75, 216, 15, 254, 34, 250, - 10, 80, 2, 230, 186, 216, 15, 254, 34, 254, 96, 80, 2, 225, 25, 232, 114, - 44, 220, 154, 250, 10, 75, 232, 114, 43, 220, 154, 254, 96, 75, 254, 96, - 250, 8, 250, 44, 75, 250, 10, 250, 8, 250, 44, 75, 97, 80, 72, 219, 253, - 140, 75, 140, 80, 72, 219, 253, 97, 75, 219, 253, 97, 80, 72, 140, 75, - 97, 80, 2, 96, 51, 140, 80, 2, 96, 51, 97, 80, 216, 140, 211, 178, 43, - 44, 80, 216, 140, 4, 250, 43, 214, 153, 215, 58, 80, 243, 251, 4, 250, - 43, 43, 252, 147, 120, 44, 252, 147, 124, 242, 5, 43, 252, 147, 124, 44, - 252, 147, 120, 242, 5, 120, 252, 147, 44, 124, 252, 147, 43, 242, 5, 120, - 252, 147, 43, 124, 252, 147, 44, 242, 5, 43, 252, 147, 120, 44, 252, 147, - 120, 242, 5, 120, 252, 147, 44, 124, 252, 147, 44, 242, 5, 43, 252, 147, - 124, 44, 252, 147, 124, 242, 5, 120, 252, 147, 43, 124, 252, 147, 43, - 242, 5, 140, 242, 6, 2, 252, 147, 120, 216, 43, 130, 97, 242, 6, 2, 252, - 147, 120, 216, 43, 130, 214, 153, 242, 6, 2, 252, 147, 44, 216, 43, 130, - 246, 112, 242, 6, 2, 252, 147, 44, 216, 43, 130, 140, 242, 6, 2, 252, - 147, 124, 216, 43, 130, 97, 242, 6, 2, 252, 147, 124, 216, 43, 130, 214, - 153, 242, 6, 2, 252, 147, 43, 216, 43, 130, 246, 112, 242, 6, 2, 252, - 147, 43, 216, 43, 130, 140, 242, 6, 2, 252, 147, 120, 243, 251, 130, 97, - 242, 6, 2, 252, 147, 120, 243, 251, 130, 214, 153, 242, 6, 2, 252, 147, - 44, 243, 251, 130, 246, 112, 242, 6, 2, 252, 147, 44, 243, 251, 130, 140, - 242, 6, 2, 252, 147, 124, 243, 251, 130, 97, 242, 6, 2, 252, 147, 124, - 243, 251, 130, 214, 153, 242, 6, 2, 252, 147, 43, 243, 251, 130, 246, - 112, 242, 6, 2, 252, 147, 43, 243, 251, 130, 140, 242, 6, 2, 252, 147, - 120, 72, 140, 242, 6, 2, 252, 147, 246, 114, 214, 153, 242, 6, 2, 252, - 147, 43, 252, 38, 214, 153, 242, 6, 2, 252, 147, 222, 254, 97, 242, 6, 2, - 252, 147, 120, 72, 97, 242, 6, 2, 252, 147, 246, 114, 246, 112, 242, 6, - 2, 252, 147, 43, 252, 38, 246, 112, 242, 6, 2, 252, 147, 222, 254, 140, - 242, 6, 2, 252, 147, 120, 72, 97, 242, 6, 2, 252, 147, 214, 163, 140, - 242, 6, 2, 252, 147, 124, 72, 97, 242, 6, 2, 252, 147, 246, 114, 97, 242, - 6, 2, 252, 147, 120, 72, 140, 242, 6, 2, 252, 147, 214, 163, 97, 242, 6, - 2, 252, 147, 124, 72, 140, 242, 6, 2, 252, 147, 246, 114, 140, 242, 6, 2, - 252, 147, 120, 72, 200, 248, 164, 140, 242, 6, 2, 252, 147, 124, 252, 51, - 200, 248, 164, 97, 242, 6, 2, 252, 147, 120, 72, 200, 248, 164, 97, 242, - 6, 2, 252, 147, 124, 252, 51, 200, 248, 164, 214, 153, 242, 6, 2, 252, - 147, 43, 252, 38, 246, 112, 242, 6, 2, 252, 147, 222, 254, 246, 112, 242, - 6, 2, 252, 147, 43, 252, 38, 214, 153, 242, 6, 2, 252, 147, 222, 254, 44, - 52, 80, 2, 222, 185, 241, 242, 245, 106, 5, 72, 97, 75, 216, 90, 226, - 172, 72, 97, 75, 140, 80, 72, 216, 90, 226, 171, 97, 80, 72, 216, 90, - 226, 171, 97, 80, 72, 254, 156, 128, 112, 233, 21, 72, 140, 75, 140, 80, - 216, 140, 233, 20, 242, 137, 72, 97, 75, 218, 65, 72, 97, 75, 140, 80, - 216, 140, 218, 64, 218, 23, 72, 140, 75, 43, 244, 99, 217, 78, 44, 244, - 99, 217, 78, 120, 244, 99, 217, 78, 124, 244, 99, 217, 78, 215, 212, 67, - 252, 149, 248, 68, 210, 160, 189, 218, 244, 210, 160, 189, 215, 49, 249, - 234, 43, 71, 249, 107, 127, 44, 71, 249, 107, 127, 43, 71, 226, 7, 44, - 71, 226, 7, 210, 160, 189, 43, 236, 22, 127, 210, 160, 189, 44, 236, 22, - 127, 210, 160, 189, 43, 251, 250, 127, 210, 160, 189, 44, 251, 250, 127, - 43, 42, 251, 166, 2, 214, 183, 44, 42, 251, 166, 2, 214, 183, 43, 42, - 251, 166, 2, 216, 116, 236, 7, 216, 15, 249, 168, 44, 42, 251, 166, 2, - 216, 116, 236, 7, 251, 183, 249, 168, 43, 42, 251, 166, 2, 216, 116, 236, - 7, 251, 183, 249, 168, 44, 42, 251, 166, 2, 216, 116, 236, 7, 216, 15, - 249, 168, 43, 254, 118, 251, 166, 2, 247, 128, 44, 254, 118, 251, 166, 2, - 247, 128, 43, 254, 34, 233, 21, 127, 44, 254, 34, 242, 137, 127, 52, 43, - 254, 34, 242, 137, 127, 52, 44, 254, 34, 233, 21, 127, 43, 85, 216, 7, - 220, 55, 127, 44, 85, 216, 7, 220, 55, 127, 246, 126, 244, 143, 67, 210, - 35, 232, 219, 231, 93, 254, 118, 226, 174, 233, 52, 44, 254, 118, 214, - 12, 2, 218, 236, 231, 93, 44, 254, 118, 2, 247, 128, 254, 118, 2, 222, - 94, 235, 222, 255, 12, 254, 117, 219, 1, 254, 118, 226, 174, 233, 52, - 219, 1, 254, 118, 226, 174, 214, 163, 215, 94, 254, 117, 223, 52, 254, - 117, 254, 118, 2, 214, 183, 223, 52, 254, 118, 2, 214, 183, 226, 252, - 254, 118, 226, 174, 214, 163, 226, 252, 254, 118, 226, 174, 246, 114, - 231, 93, 254, 118, 2, 204, 254, 13, 245, 148, 236, 7, 80, 225, 10, 120, - 22, 222, 254, 231, 93, 254, 118, 2, 204, 254, 13, 245, 148, 236, 7, 80, - 225, 10, 120, 22, 233, 52, 231, 93, 254, 118, 2, 204, 254, 13, 245, 148, - 236, 7, 80, 225, 10, 124, 22, 222, 254, 231, 93, 254, 118, 2, 204, 254, - 13, 245, 148, 236, 7, 80, 225, 10, 124, 22, 233, 52, 231, 93, 254, 118, - 2, 204, 254, 13, 245, 148, 236, 7, 80, 225, 10, 44, 22, 214, 163, 231, - 93, 254, 118, 2, 204, 254, 13, 245, 148, 236, 7, 80, 225, 10, 43, 22, - 214, 163, 231, 93, 254, 118, 2, 204, 254, 13, 245, 148, 236, 7, 80, 225, - 10, 44, 22, 246, 114, 231, 93, 254, 118, 2, 204, 254, 13, 245, 148, 236, - 7, 80, 225, 10, 43, 22, 246, 114, 223, 52, 245, 160, 220, 129, 245, 160, - 220, 130, 2, 226, 127, 245, 160, 220, 130, 2, 4, 250, 44, 48, 245, 160, - 220, 130, 2, 44, 80, 48, 245, 160, 220, 130, 2, 43, 80, 48, 250, 44, 2, - 203, 130, 37, 67, 130, 37, 226, 11, 37, 223, 53, 219, 48, 37, 225, 174, - 250, 44, 247, 181, 251, 86, 203, 252, 149, 22, 216, 15, 163, 247, 181, - 251, 86, 67, 130, 250, 44, 2, 218, 25, 211, 178, 37, 254, 95, 247, 177, - 50, 120, 80, 216, 140, 250, 43, 37, 71, 251, 121, 37, 251, 121, 37, 233, - 20, 37, 242, 136, 250, 44, 2, 4, 250, 44, 216, 43, 216, 197, 222, 254, - 250, 44, 2, 113, 203, 218, 93, 216, 43, 216, 197, 222, 254, 92, 222, 231, - 248, 7, 219, 97, 92, 244, 183, 248, 7, 219, 97, 92, 253, 224, 92, 4, 250, - 43, 92, 218, 236, 113, 235, 71, 218, 234, 215, 227, 2, 59, 48, 215, 227, - 2, 214, 183, 222, 94, 236, 7, 215, 226, 215, 227, 2, 220, 136, 253, 215, - 251, 182, 44, 215, 227, 72, 43, 215, 226, 43, 215, 227, 252, 38, 67, 130, - 67, 252, 149, 252, 38, 44, 215, 226, 251, 173, 2, 43, 163, 251, 229, 251, - 173, 2, 44, 163, 251, 229, 85, 251, 172, 30, 2, 43, 163, 251, 229, 30, 2, - 44, 163, 251, 229, 71, 240, 243, 85, 240, 243, 43, 211, 244, 244, 143, - 44, 211, 244, 244, 143, 43, 52, 211, 244, 244, 143, 44, 52, 211, 244, - 244, 143, 235, 255, 235, 241, 216, 113, 115, 235, 241, 235, 242, 229, - 107, 2, 67, 130, 246, 120, 230, 92, 42, 2, 249, 189, 226, 131, 235, 253, - 253, 245, 219, 221, 224, 183, 245, 106, 5, 22, 219, 99, 226, 11, 245, - 106, 5, 22, 219, 99, 226, 12, 2, 216, 90, 48, 240, 111, 216, 43, 22, 219, - 99, 226, 11, 242, 190, 218, 157, 216, 186, 246, 113, 215, 227, 2, 43, - 163, 251, 229, 246, 113, 215, 227, 2, 44, 163, 251, 229, 85, 248, 1, 2, - 124, 75, 85, 232, 110, 71, 250, 44, 2, 124, 75, 85, 250, 44, 2, 124, 75, - 245, 93, 71, 218, 236, 245, 93, 85, 218, 236, 245, 93, 71, 248, 0, 245, - 93, 85, 248, 0, 245, 93, 71, 250, 43, 245, 93, 85, 250, 43, 222, 134, - 223, 53, 219, 49, 226, 171, 219, 49, 2, 226, 127, 223, 53, 219, 49, 2, - 203, 91, 252, 1, 219, 48, 252, 1, 223, 53, 219, 48, 52, 225, 25, 215, - 212, 225, 25, 233, 48, 249, 99, 254, 118, 127, 222, 250, 249, 99, 254, - 118, 127, 216, 79, 230, 184, 230, 29, 37, 59, 226, 171, 230, 29, 37, 96, - 226, 171, 230, 29, 37, 30, 226, 171, 230, 29, 214, 176, 226, 172, 2, 247, - 128, 230, 29, 214, 176, 226, 172, 2, 225, 25, 230, 29, 42, 235, 206, 226, - 171, 230, 29, 42, 214, 176, 226, 171, 113, 232, 152, 22, 226, 171, 113, - 232, 152, 177, 226, 171, 230, 29, 30, 226, 171, 230, 159, 113, 218, 44, - 218, 42, 2, 235, 218, 224, 27, 235, 219, 226, 171, 244, 107, 226, 3, 235, - 218, 235, 219, 2, 52, 91, 235, 219, 253, 181, 2, 219, 97, 250, 40, 243, - 233, 254, 96, 235, 216, 232, 220, 235, 217, 2, 223, 118, 225, 241, 254, - 10, 225, 4, 232, 220, 235, 217, 2, 220, 154, 225, 241, 254, 10, 225, 4, - 232, 220, 235, 217, 228, 57, 236, 1, 216, 197, 225, 4, 235, 219, 254, 10, - 116, 225, 14, 226, 171, 224, 21, 235, 219, 226, 171, 235, 219, 2, 140, - 80, 2, 103, 235, 219, 2, 30, 50, 235, 219, 2, 235, 205, 235, 219, 2, 214, - 175, 235, 219, 2, 226, 127, 235, 219, 2, 214, 183, 235, 72, 233, 91, 43, - 215, 227, 226, 171, 210, 160, 189, 221, 203, 249, 217, 210, 160, 189, - 221, 203, 225, 59, 210, 160, 189, 221, 203, 224, 179, 96, 5, 2, 4, 250, - 44, 48, 96, 5, 2, 250, 39, 255, 24, 48, 96, 5, 2, 216, 90, 48, 96, 5, 2, - 59, 51, 96, 5, 2, 216, 90, 51, 96, 5, 2, 218, 66, 105, 96, 5, 2, 85, 215, - 226, 230, 187, 5, 2, 249, 228, 48, 230, 187, 5, 2, 59, 51, 230, 187, 5, - 2, 244, 183, 247, 126, 230, 187, 5, 2, 222, 231, 247, 126, 96, 5, 236, 7, - 43, 163, 250, 43, 96, 5, 236, 7, 44, 163, 250, 43, 213, 254, 177, 249, - 139, 224, 183, 230, 89, 5, 2, 59, 48, 230, 89, 5, 2, 214, 183, 220, 151, - 224, 184, 2, 251, 183, 250, 7, 219, 79, 224, 183, 230, 89, 5, 236, 7, 43, - 163, 250, 43, 230, 89, 5, 236, 7, 44, 163, 250, 43, 37, 230, 89, 5, 2, - 250, 39, 255, 23, 230, 89, 5, 236, 7, 52, 250, 43, 37, 247, 177, 50, 96, - 5, 236, 7, 215, 226, 230, 187, 5, 236, 7, 215, 226, 230, 89, 5, 236, 7, - 215, 226, 235, 213, 224, 183, 222, 245, 235, 213, 224, 183, 210, 160, - 189, 223, 93, 249, 217, 254, 142, 177, 249, 173, 235, 206, 2, 247, 128, - 214, 176, 2, 230, 187, 50, 214, 176, 2, 226, 127, 235, 206, 2, 226, 127, - 235, 206, 2, 232, 152, 254, 126, 214, 176, 2, 232, 152, 226, 162, 214, - 176, 72, 235, 205, 235, 206, 72, 214, 175, 214, 176, 72, 252, 149, 72, - 235, 205, 235, 206, 72, 252, 149, 72, 214, 175, 214, 176, 252, 38, 22, - 235, 71, 2, 214, 175, 235, 206, 252, 38, 22, 235, 71, 2, 235, 205, 250, - 8, 214, 176, 2, 220, 135, 250, 8, 235, 206, 2, 220, 135, 52, 42, 235, - 205, 52, 42, 214, 175, 250, 8, 214, 176, 2, 220, 136, 22, 219, 79, 224, - 183, 232, 152, 22, 2, 59, 48, 232, 152, 177, 2, 59, 48, 52, 232, 152, - 254, 126, 52, 232, 152, 226, 162, 113, 235, 207, 232, 152, 254, 126, 113, - 235, 207, 232, 152, 226, 162, 219, 87, 233, 91, 226, 162, 219, 87, 233, - 91, 254, 126, 232, 152, 177, 226, 125, 232, 152, 254, 126, 232, 152, 22, - 2, 230, 229, 218, 141, 232, 152, 177, 2, 230, 229, 218, 141, 232, 152, - 22, 2, 203, 248, 164, 232, 152, 177, 2, 203, 248, 164, 232, 152, 22, 2, - 52, 226, 127, 232, 152, 22, 2, 214, 183, 232, 152, 22, 2, 52, 214, 183, - 4, 213, 251, 2, 214, 183, 232, 152, 177, 2, 52, 226, 127, 232, 152, 177, - 2, 52, 214, 183, 210, 160, 189, 247, 137, 254, 87, 210, 160, 189, 223, - 151, 254, 87, 245, 106, 5, 2, 59, 51, 240, 111, 2, 59, 48, 215, 212, 203, - 252, 149, 2, 52, 67, 91, 215, 212, 203, 252, 149, 2, 215, 212, 67, 91, - 216, 90, 226, 172, 2, 59, 48, 216, 90, 226, 172, 2, 222, 231, 247, 126, - 219, 164, 230, 187, 219, 163, 249, 207, 2, 59, 48, 245, 106, 2, 253, 224, - 254, 156, 128, 216, 43, 2, 250, 39, 255, 23, 254, 56, 128, 177, 128, 112, - 245, 106, 5, 72, 96, 50, 96, 5, 72, 245, 106, 50, 245, 106, 5, 72, 216, - 90, 226, 171, 52, 249, 235, 245, 107, 113, 249, 202, 245, 106, 219, 178, - 134, 249, 202, 245, 106, 219, 178, 245, 106, 5, 2, 113, 170, 72, 22, 113, - 170, 51, 245, 102, 2, 244, 19, 170, 48, 233, 21, 2, 250, 44, 235, 222, - 242, 137, 2, 250, 44, 235, 222, 233, 21, 2, 224, 16, 164, 48, 242, 137, - 2, 224, 16, 164, 48, 233, 21, 177, 219, 99, 128, 112, 242, 137, 177, 219, - 99, 128, 112, 233, 21, 177, 219, 99, 128, 216, 43, 2, 59, 235, 222, 242, - 137, 177, 219, 99, 128, 216, 43, 2, 59, 235, 222, 233, 21, 177, 219, 99, - 128, 216, 43, 2, 59, 48, 242, 137, 177, 219, 99, 128, 216, 43, 2, 59, 48, - 233, 21, 177, 219, 99, 128, 216, 43, 2, 59, 72, 222, 254, 242, 137, 177, - 219, 99, 128, 216, 43, 2, 59, 72, 233, 52, 233, 21, 177, 254, 57, 242, - 137, 177, 254, 57, 233, 21, 22, 219, 155, 228, 57, 128, 112, 242, 137, - 22, 219, 155, 228, 57, 128, 112, 233, 21, 22, 228, 57, 254, 57, 242, 137, - 22, 228, 57, 254, 57, 233, 21, 72, 246, 119, 128, 72, 242, 136, 242, 137, - 72, 246, 119, 128, 72, 233, 20, 233, 21, 72, 219, 164, 177, 245, 107, - 242, 137, 72, 219, 164, 177, 245, 107, 233, 21, 72, 219, 164, 72, 242, - 136, 242, 137, 72, 219, 164, 72, 233, 20, 233, 21, 72, 242, 137, 72, 246, - 119, 245, 107, 242, 137, 72, 233, 21, 72, 246, 119, 245, 107, 233, 21, - 72, 219, 99, 128, 72, 242, 137, 72, 219, 99, 245, 107, 242, 137, 72, 219, - 99, 128, 72, 233, 21, 72, 219, 99, 245, 107, 219, 99, 128, 216, 43, 177, - 233, 20, 219, 99, 128, 216, 43, 177, 242, 136, 219, 99, 128, 216, 43, - 177, 233, 21, 2, 59, 235, 222, 219, 99, 128, 216, 43, 177, 242, 137, 2, - 59, 235, 222, 246, 119, 128, 216, 43, 177, 233, 20, 246, 119, 128, 216, - 43, 177, 242, 136, 246, 119, 219, 99, 128, 216, 43, 177, 233, 20, 246, - 119, 219, 99, 128, 216, 43, 177, 242, 136, 219, 164, 177, 233, 20, 219, - 164, 177, 242, 136, 219, 164, 72, 233, 21, 72, 245, 106, 50, 219, 164, - 72, 242, 137, 72, 245, 106, 50, 52, 229, 96, 233, 20, 52, 229, 96, 242, - 136, 52, 229, 96, 233, 21, 2, 214, 183, 242, 137, 226, 125, 233, 20, 242, - 137, 252, 38, 233, 20, 233, 21, 250, 8, 251, 86, 249, 100, 242, 137, 250, - 8, 251, 86, 249, 100, 233, 21, 250, 8, 251, 86, 249, 101, 72, 219, 99, - 245, 107, 242, 137, 250, 8, 251, 86, 249, 101, 72, 219, 99, 245, 107, - 219, 80, 216, 201, 233, 89, 216, 201, 219, 80, 216, 202, 177, 128, 112, - 233, 89, 216, 202, 177, 128, 112, 245, 106, 5, 2, 251, 116, 48, 224, 206, - 72, 219, 155, 245, 106, 50, 218, 57, 72, 219, 155, 245, 106, 50, 224, - 206, 72, 219, 155, 228, 57, 128, 112, 218, 57, 72, 219, 155, 228, 57, - 128, 112, 224, 206, 72, 245, 106, 50, 218, 57, 72, 245, 106, 50, 224, - 206, 72, 228, 57, 128, 112, 218, 57, 72, 228, 57, 128, 112, 224, 206, 72, - 254, 156, 128, 112, 218, 57, 72, 254, 156, 128, 112, 224, 206, 72, 228, - 57, 254, 156, 128, 112, 218, 57, 72, 228, 57, 254, 156, 128, 112, 52, - 224, 205, 52, 218, 56, 218, 65, 2, 247, 128, 218, 23, 2, 247, 128, 218, - 65, 2, 96, 5, 51, 218, 23, 2, 96, 5, 51, 218, 65, 2, 230, 89, 5, 51, 218, - 23, 2, 230, 89, 5, 51, 218, 65, 64, 177, 128, 216, 43, 2, 59, 48, 218, - 23, 64, 177, 128, 216, 43, 2, 59, 48, 218, 65, 64, 72, 245, 106, 50, 218, - 23, 64, 72, 245, 106, 50, 218, 65, 64, 72, 216, 90, 226, 171, 218, 23, - 64, 72, 216, 90, 226, 171, 218, 65, 64, 72, 254, 156, 128, 112, 218, 23, - 64, 72, 254, 156, 128, 112, 218, 65, 64, 72, 228, 57, 128, 112, 218, 23, - 64, 72, 228, 57, 128, 112, 42, 43, 204, 93, 226, 171, 42, 44, 204, 93, - 226, 171, 250, 8, 218, 64, 250, 8, 218, 22, 250, 8, 218, 65, 177, 128, - 112, 250, 8, 218, 23, 177, 128, 112, 218, 65, 72, 218, 22, 218, 23, 72, - 218, 64, 218, 65, 72, 218, 64, 218, 23, 72, 218, 22, 218, 23, 252, 38, - 218, 64, 218, 23, 252, 38, 22, 235, 71, 251, 86, 248, 165, 2, 218, 64, - 245, 178, 64, 226, 174, 246, 111, 225, 51, 2, 217, 13, 216, 14, 215, 241, - 235, 205, 244, 29, 228, 70, 219, 253, 43, 217, 88, 219, 253, 124, 217, - 88, 219, 253, 120, 217, 88, 225, 175, 2, 222, 93, 67, 252, 149, 215, 212, - 44, 215, 93, 52, 67, 252, 149, 43, 215, 93, 67, 252, 149, 52, 43, 215, - 93, 52, 67, 252, 149, 52, 43, 215, 93, 200, 248, 165, 243, 251, 43, 231, - 68, 64, 52, 213, 239, 219, 253, 124, 217, 89, 2, 226, 127, 219, 253, 120, - 217, 89, 2, 214, 183, 219, 253, 120, 217, 89, 72, 219, 253, 124, 217, 88, - 52, 124, 217, 88, 52, 120, 217, 88, 52, 218, 105, 228, 57, 50, 223, 52, - 52, 218, 105, 228, 57, 50, 247, 146, 228, 57, 247, 183, 2, 223, 52, 229, - 106, 219, 97, 67, 232, 220, 2, 250, 44, 48, 67, 232, 220, 2, 250, 44, 51, - 124, 217, 89, 2, 250, 44, 51, 226, 12, 2, 203, 91, 226, 12, 2, 216, 90, - 226, 171, 215, 212, 67, 252, 149, 251, 252, 223, 94, 215, 212, 67, 252, - 149, 2, 203, 91, 215, 212, 249, 235, 226, 171, 215, 212, 229, 96, 233, - 20, 215, 212, 229, 96, 242, 136, 246, 119, 219, 99, 233, 21, 177, 128, - 112, 246, 119, 219, 99, 242, 137, 177, 128, 112, 215, 212, 219, 49, 251, - 252, 223, 94, 233, 91, 215, 212, 67, 252, 149, 226, 171, 52, 219, 49, - 226, 171, 71, 67, 130, 230, 29, 71, 67, 130, 228, 61, 245, 228, 71, 75, - 228, 61, 212, 9, 71, 75, 219, 30, 245, 228, 71, 75, 219, 30, 212, 9, 71, - 75, 43, 44, 71, 75, 140, 85, 75, 214, 153, 85, 75, 246, 112, 85, 75, 228, - 61, 245, 228, 85, 75, 228, 61, 212, 9, 85, 75, 219, 30, 245, 228, 85, 75, - 219, 30, 212, 9, 85, 75, 43, 44, 85, 75, 120, 124, 85, 75, 97, 80, 2, - 216, 78, 246, 111, 97, 80, 2, 216, 78, 214, 152, 140, 80, 2, 216, 78, - 246, 111, 140, 80, 2, 216, 78, 214, 152, 42, 2, 216, 15, 163, 251, 229, - 42, 2, 251, 183, 163, 251, 229, 42, 2, 214, 160, 44, 248, 7, 163, 251, - 229, 42, 2, 232, 114, 43, 248, 7, 163, 251, 229, 248, 1, 2, 43, 163, 251, - 229, 248, 1, 2, 44, 163, 251, 229, 248, 1, 2, 216, 15, 163, 251, 229, - 248, 1, 2, 251, 183, 163, 251, 229, 246, 126, 218, 236, 85, 233, 91, 218, - 236, 71, 233, 91, 218, 236, 85, 213, 187, 4, 218, 236, 71, 213, 187, 4, - 218, 236, 85, 225, 193, 71, 225, 193, 71, 241, 200, 85, 241, 200, 203, - 85, 241, 200, 85, 233, 91, 250, 43, 85, 231, 87, 248, 0, 71, 231, 87, - 248, 0, 85, 231, 87, 232, 110, 71, 231, 87, 232, 110, 85, 4, 248, 0, 85, - 4, 232, 110, 71, 4, 232, 110, 85, 203, 245, 172, 71, 203, 245, 172, 85, - 67, 245, 172, 71, 67, 245, 172, 43, 80, 2, 4, 250, 43, 134, 140, 253, - 255, 43, 80, 2, 37, 225, 25, 200, 140, 218, 232, 75, 140, 215, 58, 80, 2, - 67, 91, 140, 215, 58, 80, 2, 52, 67, 91, 140, 215, 58, 80, 243, 251, 130, - 140, 215, 58, 215, 212, 248, 165, 75, 140, 80, 2, 246, 126, 218, 141, - 140, 80, 2, 217, 79, 2, 67, 91, 140, 80, 2, 217, 79, 2, 52, 67, 91, 140, - 215, 58, 80, 2, 217, 78, 140, 215, 58, 80, 2, 217, 79, 2, 67, 91, 140, - 215, 58, 80, 2, 217, 79, 2, 52, 67, 91, 140, 80, 216, 140, 211, 178, 212, - 36, 80, 225, 10, 247, 203, 233, 52, 245, 106, 5, 72, 140, 75, 223, 53, - 216, 90, 226, 172, 72, 140, 75, 140, 80, 72, 223, 53, 254, 156, 128, 112, - 97, 80, 216, 140, 242, 136, 97, 80, 216, 140, 218, 22, 140, 224, 27, 75, - 97, 224, 27, 75, 223, 53, 216, 90, 226, 172, 72, 97, 75, 97, 80, 72, 223, - 53, 254, 156, 128, 112, 216, 90, 226, 172, 72, 140, 75, 140, 80, 72, 254, - 156, 128, 112, 140, 80, 72, 223, 53, 216, 90, 226, 171, 97, 80, 72, 223, - 53, 216, 90, 226, 171, 71, 231, 87, 218, 158, 85, 4, 218, 158, 71, 4, - 218, 158, 85, 222, 250, 225, 193, 71, 222, 250, 225, 193, 114, 233, 91, - 250, 43, 114, 226, 128, 2, 226, 128, 235, 222, 114, 250, 44, 2, 250, 44, - 235, 222, 114, 250, 43, 114, 37, 222, 0, 145, 6, 1, 253, 167, 145, 6, 1, - 251, 125, 145, 6, 1, 213, 253, 145, 6, 1, 242, 192, 145, 6, 1, 247, 148, - 145, 6, 1, 211, 21, 145, 6, 1, 210, 68, 145, 6, 1, 246, 42, 145, 6, 1, - 210, 91, 145, 6, 1, 235, 154, 145, 6, 1, 65, 235, 154, 145, 6, 1, 74, - 145, 6, 1, 247, 168, 145, 6, 1, 234, 246, 145, 6, 1, 232, 192, 145, 6, 1, - 230, 34, 145, 6, 1, 229, 196, 145, 6, 1, 226, 189, 145, 6, 1, 225, 7, - 145, 6, 1, 222, 230, 145, 6, 1, 219, 85, 145, 6, 1, 215, 81, 145, 6, 1, - 214, 201, 145, 6, 1, 243, 254, 145, 6, 1, 241, 206, 145, 6, 1, 226, 139, - 145, 6, 1, 225, 224, 145, 6, 1, 219, 230, 145, 6, 1, 215, 168, 145, 6, 1, - 250, 83, 145, 6, 1, 220, 104, 145, 6, 1, 211, 27, 145, 6, 1, 211, 29, - 145, 6, 1, 211, 57, 145, 6, 1, 218, 255, 162, 145, 6, 1, 210, 212, 145, - 6, 1, 4, 210, 183, 145, 6, 1, 4, 210, 184, 2, 217, 78, 145, 6, 1, 210, - 244, 145, 6, 1, 235, 191, 4, 210, 183, 145, 6, 1, 252, 1, 210, 183, 145, - 6, 1, 235, 191, 252, 1, 210, 183, 145, 6, 1, 244, 90, 145, 6, 1, 235, - 152, 145, 6, 1, 219, 229, 145, 6, 1, 215, 203, 61, 145, 6, 1, 233, 81, - 230, 34, 145, 4, 1, 253, 167, 145, 4, 1, 251, 125, 145, 4, 1, 213, 253, - 145, 4, 1, 242, 192, 145, 4, 1, 247, 148, 145, 4, 1, 211, 21, 145, 4, 1, - 210, 68, 145, 4, 1, 246, 42, 145, 4, 1, 210, 91, 145, 4, 1, 235, 154, - 145, 4, 1, 65, 235, 154, 145, 4, 1, 74, 145, 4, 1, 247, 168, 145, 4, 1, - 234, 246, 145, 4, 1, 232, 192, 145, 4, 1, 230, 34, 145, 4, 1, 229, 196, - 145, 4, 1, 226, 189, 145, 4, 1, 225, 7, 145, 4, 1, 222, 230, 145, 4, 1, - 219, 85, 145, 4, 1, 215, 81, 145, 4, 1, 214, 201, 145, 4, 1, 243, 254, - 145, 4, 1, 241, 206, 145, 4, 1, 226, 139, 145, 4, 1, 225, 224, 145, 4, 1, - 219, 230, 145, 4, 1, 215, 168, 145, 4, 1, 250, 83, 145, 4, 1, 220, 104, - 145, 4, 1, 211, 27, 145, 4, 1, 211, 29, 145, 4, 1, 211, 57, 145, 4, 1, - 218, 255, 162, 145, 4, 1, 210, 212, 145, 4, 1, 4, 210, 183, 145, 4, 1, 4, - 210, 184, 2, 217, 78, 145, 4, 1, 210, 244, 145, 4, 1, 235, 191, 4, 210, - 183, 145, 4, 1, 252, 1, 210, 183, 145, 4, 1, 235, 191, 252, 1, 210, 183, - 145, 4, 1, 244, 90, 145, 4, 1, 235, 152, 145, 4, 1, 219, 229, 145, 4, 1, - 215, 203, 61, 145, 4, 1, 233, 81, 230, 34, 7, 6, 1, 233, 155, 2, 52, 130, - 7, 4, 1, 233, 155, 2, 52, 130, 7, 6, 1, 233, 155, 2, 230, 229, 184, 7, 6, - 1, 226, 110, 2, 91, 7, 6, 1, 223, 227, 2, 217, 78, 7, 4, 1, 116, 2, 91, - 7, 4, 1, 217, 154, 2, 248, 7, 91, 7, 6, 1, 242, 68, 2, 248, 47, 7, 4, 1, - 242, 68, 2, 248, 47, 7, 6, 1, 235, 30, 2, 248, 47, 7, 4, 1, 235, 30, 2, - 248, 47, 7, 6, 1, 210, 160, 2, 248, 47, 7, 4, 1, 210, 160, 2, 248, 47, 7, - 6, 1, 254, 151, 7, 6, 1, 232, 55, 2, 103, 7, 6, 1, 215, 94, 61, 7, 6, 1, - 215, 94, 254, 151, 7, 4, 1, 214, 106, 2, 44, 103, 7, 6, 1, 212, 99, 2, - 103, 7, 4, 1, 212, 99, 2, 103, 7, 4, 1, 214, 106, 2, 249, 108, 7, 6, 1, - 163, 242, 67, 7, 4, 1, 163, 242, 67, 7, 4, 1, 217, 76, 225, 136, 7, 4, 1, - 160, 2, 228, 55, 7, 4, 1, 215, 94, 223, 227, 2, 217, 78, 7, 4, 1, 144, 2, - 121, 222, 237, 235, 222, 7, 1, 4, 6, 215, 94, 76, 7, 218, 66, 4, 1, 235, - 150, 58, 1, 6, 214, 105, 7, 6, 1, 222, 94, 2, 217, 251, 217, 78, 7, 6, 1, - 210, 160, 2, 217, 251, 217, 78, 81, 6, 1, 254, 173, 81, 4, 1, 254, 173, - 81, 6, 1, 213, 173, 81, 4, 1, 213, 173, 81, 6, 1, 243, 114, 81, 4, 1, - 243, 114, 81, 6, 1, 248, 199, 81, 4, 1, 248, 199, 81, 6, 1, 245, 202, 81, - 4, 1, 245, 202, 81, 6, 1, 219, 35, 81, 4, 1, 219, 35, 81, 6, 1, 210, 101, - 81, 4, 1, 210, 101, 81, 6, 1, 241, 255, 81, 4, 1, 241, 255, 81, 6, 1, - 216, 178, 81, 4, 1, 216, 178, 81, 6, 1, 240, 123, 81, 4, 1, 240, 123, 81, - 6, 1, 234, 233, 81, 4, 1, 234, 233, 81, 6, 1, 233, 78, 81, 4, 1, 233, 78, - 81, 6, 1, 230, 235, 81, 4, 1, 230, 235, 81, 6, 1, 228, 238, 81, 4, 1, - 228, 238, 81, 6, 1, 233, 239, 81, 4, 1, 233, 239, 81, 6, 1, 78, 81, 4, 1, - 78, 81, 6, 1, 225, 111, 81, 4, 1, 225, 111, 81, 6, 1, 222, 213, 81, 4, 1, - 222, 213, 81, 6, 1, 219, 167, 81, 4, 1, 219, 167, 81, 6, 1, 217, 42, 81, - 4, 1, 217, 42, 81, 6, 1, 214, 229, 81, 4, 1, 214, 229, 81, 6, 1, 244, - 129, 81, 4, 1, 244, 129, 81, 6, 1, 234, 118, 81, 4, 1, 234, 118, 81, 6, - 1, 224, 164, 81, 4, 1, 224, 164, 81, 6, 1, 226, 182, 81, 4, 1, 226, 182, - 81, 6, 1, 248, 5, 254, 179, 81, 4, 1, 248, 5, 254, 179, 81, 6, 1, 55, 81, - 254, 205, 81, 4, 1, 55, 81, 254, 205, 81, 6, 1, 249, 123, 245, 202, 81, - 4, 1, 249, 123, 245, 202, 81, 6, 1, 248, 5, 234, 233, 81, 4, 1, 248, 5, - 234, 233, 81, 6, 1, 248, 5, 228, 238, 81, 4, 1, 248, 5, 228, 238, 81, 6, - 1, 249, 123, 228, 238, 81, 4, 1, 249, 123, 228, 238, 81, 6, 1, 55, 81, - 226, 182, 81, 4, 1, 55, 81, 226, 182, 81, 6, 1, 221, 248, 81, 4, 1, 221, - 248, 81, 6, 1, 249, 136, 220, 57, 81, 4, 1, 249, 136, 220, 57, 81, 6, 1, - 55, 81, 220, 57, 81, 4, 1, 55, 81, 220, 57, 81, 6, 1, 55, 81, 245, 83, - 81, 4, 1, 55, 81, 245, 83, 81, 6, 1, 254, 191, 234, 123, 81, 4, 1, 254, - 191, 234, 123, 81, 6, 1, 248, 5, 241, 52, 81, 4, 1, 248, 5, 241, 52, 81, - 6, 1, 55, 81, 241, 52, 81, 4, 1, 55, 81, 241, 52, 81, 6, 1, 55, 81, 162, - 81, 4, 1, 55, 81, 162, 81, 6, 1, 233, 154, 162, 81, 4, 1, 233, 154, 162, - 81, 6, 1, 55, 81, 241, 224, 81, 4, 1, 55, 81, 241, 224, 81, 6, 1, 55, 81, - 242, 2, 81, 4, 1, 55, 81, 242, 2, 81, 6, 1, 55, 81, 243, 109, 81, 4, 1, - 55, 81, 243, 109, 81, 6, 1, 55, 81, 247, 171, 81, 4, 1, 55, 81, 247, 171, - 81, 6, 1, 55, 81, 220, 24, 81, 4, 1, 55, 81, 220, 24, 81, 6, 1, 55, 227, - 212, 220, 24, 81, 4, 1, 55, 227, 212, 220, 24, 81, 6, 1, 55, 227, 212, - 229, 32, 81, 4, 1, 55, 227, 212, 229, 32, 81, 6, 1, 55, 227, 212, 227, - 152, 81, 4, 1, 55, 227, 212, 227, 152, 81, 6, 1, 55, 227, 212, 212, 37, - 81, 4, 1, 55, 227, 212, 212, 37, 81, 16, 234, 252, 81, 16, 230, 236, 222, - 213, 81, 16, 225, 112, 222, 213, 81, 16, 218, 149, 81, 16, 217, 43, 222, - 213, 81, 16, 234, 119, 222, 213, 81, 16, 220, 25, 219, 167, 81, 6, 1, - 249, 123, 220, 57, 81, 4, 1, 249, 123, 220, 57, 81, 6, 1, 249, 123, 243, - 109, 81, 4, 1, 249, 123, 243, 109, 81, 38, 228, 239, 48, 81, 38, 218, - 249, 253, 232, 81, 38, 218, 249, 233, 27, 81, 6, 1, 251, 207, 234, 123, - 81, 4, 1, 251, 207, 234, 123, 81, 55, 227, 212, 243, 236, 218, 131, 81, - 55, 227, 212, 247, 205, 224, 16, 79, 81, 55, 227, 212, 235, 244, 224, 16, - 79, 81, 55, 227, 212, 213, 241, 247, 180, 81, 244, 10, 123, 242, 34, 81, - 243, 236, 218, 131, 81, 230, 129, 247, 180, 98, 4, 1, 254, 131, 98, 4, 1, - 252, 160, 98, 4, 1, 243, 113, 98, 4, 1, 247, 136, 98, 4, 1, 245, 158, 98, - 4, 1, 213, 160, 98, 4, 1, 210, 89, 98, 4, 1, 217, 61, 98, 4, 1, 236, 6, - 98, 4, 1, 234, 240, 98, 4, 1, 233, 87, 98, 4, 1, 231, 190, 98, 4, 1, 229, - 200, 98, 4, 1, 226, 200, 98, 4, 1, 226, 21, 98, 4, 1, 210, 78, 98, 4, 1, - 223, 174, 98, 4, 1, 221, 245, 98, 4, 1, 217, 51, 98, 4, 1, 214, 190, 98, - 4, 1, 225, 143, 98, 4, 1, 234, 127, 98, 4, 1, 242, 248, 98, 4, 1, 224, - 76, 98, 4, 1, 220, 22, 98, 4, 1, 250, 105, 98, 4, 1, 251, 15, 98, 4, 1, - 235, 106, 98, 4, 1, 250, 48, 98, 4, 1, 250, 151, 98, 4, 1, 211, 163, 98, - 4, 1, 235, 117, 98, 4, 1, 242, 50, 98, 4, 1, 241, 245, 98, 4, 1, 241, - 182, 98, 4, 1, 212, 22, 98, 4, 1, 242, 11, 98, 4, 1, 241, 72, 98, 4, 1, - 210, 246, 98, 4, 1, 254, 241, 216, 109, 1, 192, 216, 109, 1, 211, 99, - 216, 109, 1, 211, 98, 216, 109, 1, 211, 88, 216, 109, 1, 211, 86, 216, - 109, 1, 252, 40, 255, 25, 211, 81, 216, 109, 1, 211, 81, 216, 109, 1, - 211, 96, 216, 109, 1, 211, 93, 216, 109, 1, 211, 95, 216, 109, 1, 211, - 94, 216, 109, 1, 211, 12, 216, 109, 1, 211, 90, 216, 109, 1, 211, 79, - 216, 109, 1, 215, 116, 211, 79, 216, 109, 1, 211, 76, 216, 109, 1, 211, - 84, 216, 109, 1, 252, 40, 255, 25, 211, 84, 216, 109, 1, 215, 116, 211, - 84, 216, 109, 1, 211, 83, 216, 109, 1, 211, 103, 216, 109, 1, 211, 77, - 216, 109, 1, 215, 116, 211, 77, 216, 109, 1, 211, 66, 216, 109, 1, 215, - 116, 211, 66, 216, 109, 1, 211, 8, 216, 109, 1, 211, 49, 216, 109, 1, - 254, 216, 211, 49, 216, 109, 1, 215, 116, 211, 49, 216, 109, 1, 211, 75, - 216, 109, 1, 211, 74, 216, 109, 1, 211, 71, 216, 109, 1, 215, 116, 211, - 85, 216, 109, 1, 215, 116, 211, 69, 216, 109, 1, 211, 67, 216, 109, 1, - 210, 212, 216, 109, 1, 211, 64, 216, 109, 1, 211, 63, 216, 109, 1, 211, - 87, 216, 109, 1, 215, 116, 211, 87, 216, 109, 1, 253, 171, 211, 87, 216, - 109, 1, 211, 62, 216, 109, 1, 211, 60, 216, 109, 1, 211, 61, 216, 109, 1, - 211, 59, 216, 109, 1, 211, 58, 216, 109, 1, 211, 97, 216, 109, 1, 211, - 56, 216, 109, 1, 211, 54, 216, 109, 1, 211, 53, 216, 109, 1, 211, 52, - 216, 109, 1, 211, 50, 216, 109, 1, 217, 35, 211, 50, 216, 109, 1, 211, - 48, 216, 109, 1, 211, 47, 216, 109, 1, 210, 244, 216, 109, 58, 1, 233, - 132, 79, 216, 109, 220, 140, 79, 216, 109, 117, 235, 69, 29, 3, 232, 161, - 29, 3, 230, 165, 29, 3, 222, 211, 29, 3, 219, 59, 29, 3, 220, 8, 29, 3, - 251, 212, 29, 3, 216, 42, 29, 3, 249, 245, 29, 3, 228, 77, 29, 3, 227, - 137, 29, 3, 242, 187, 227, 4, 29, 3, 210, 22, 29, 3, 247, 151, 29, 3, - 248, 112, 29, 3, 235, 73, 29, 3, 216, 156, 29, 3, 250, 93, 29, 3, 225, - 123, 29, 3, 225, 18, 29, 3, 243, 6, 29, 3, 243, 2, 29, 3, 243, 3, 29, 3, - 243, 4, 29, 3, 218, 225, 29, 3, 218, 181, 29, 3, 218, 194, 29, 3, 218, - 224, 29, 3, 218, 198, 29, 3, 218, 199, 29, 3, 218, 186, 29, 3, 250, 221, - 29, 3, 250, 200, 29, 3, 250, 202, 29, 3, 250, 220, 29, 3, 250, 218, 29, - 3, 250, 219, 29, 3, 250, 201, 29, 3, 209, 243, 29, 3, 209, 221, 29, 3, - 209, 234, 29, 3, 209, 242, 29, 3, 209, 237, 29, 3, 209, 238, 29, 3, 209, - 226, 29, 3, 250, 216, 29, 3, 250, 203, 29, 3, 250, 205, 29, 3, 250, 215, - 29, 3, 250, 213, 29, 3, 250, 214, 29, 3, 250, 204, 29, 3, 223, 239, 29, - 3, 223, 229, 29, 3, 223, 235, 29, 3, 223, 238, 29, 3, 223, 236, 29, 3, - 223, 237, 29, 3, 223, 234, 29, 3, 233, 165, 29, 3, 233, 157, 29, 3, 233, - 160, 29, 3, 233, 164, 29, 3, 233, 161, 29, 3, 233, 162, 29, 3, 233, 158, - 29, 3, 211, 130, 29, 3, 211, 120, 29, 3, 211, 126, 29, 3, 211, 129, 29, - 3, 211, 127, 29, 3, 211, 128, 29, 3, 211, 125, 29, 3, 242, 78, 29, 3, - 242, 69, 29, 3, 242, 72, 29, 3, 242, 77, 29, 3, 242, 74, 29, 3, 242, 75, - 29, 3, 242, 71, 38, 33, 1, 252, 83, 38, 33, 1, 213, 255, 38, 33, 1, 242, - 243, 38, 33, 1, 248, 98, 38, 33, 1, 210, 74, 38, 33, 1, 210, 94, 38, 33, - 1, 176, 38, 33, 1, 245, 182, 38, 33, 1, 245, 167, 38, 33, 1, 245, 158, - 38, 33, 1, 78, 38, 33, 1, 225, 224, 38, 33, 1, 245, 100, 38, 33, 1, 245, - 90, 38, 33, 1, 217, 23, 38, 33, 1, 162, 38, 33, 1, 215, 179, 38, 33, 1, - 250, 139, 38, 33, 1, 220, 104, 38, 33, 1, 220, 67, 38, 33, 1, 244, 90, - 38, 33, 1, 245, 89, 38, 33, 1, 61, 38, 33, 1, 236, 67, 38, 33, 1, 247, - 169, 38, 33, 1, 230, 145, 214, 205, 38, 33, 1, 211, 59, 38, 33, 1, 210, - 212, 38, 33, 1, 235, 190, 61, 38, 33, 1, 232, 198, 210, 183, 38, 33, 1, - 252, 1, 210, 183, 38, 33, 1, 235, 190, 252, 1, 210, 183, 44, 254, 118, - 218, 61, 231, 159, 44, 254, 118, 246, 126, 218, 61, 231, 159, 43, 218, - 61, 127, 44, 218, 61, 127, 43, 246, 126, 218, 61, 127, 44, 246, 126, 218, - 61, 127, 223, 160, 235, 209, 231, 159, 223, 160, 246, 126, 235, 209, 231, - 159, 246, 126, 215, 242, 231, 159, 43, 215, 242, 127, 44, 215, 242, 127, - 223, 160, 218, 236, 43, 223, 160, 226, 202, 127, 44, 223, 160, 226, 202, - 127, 245, 218, 249, 166, 226, 17, 244, 30, 226, 17, 223, 52, 244, 30, - 226, 17, 240, 172, 246, 126, 226, 255, 246, 112, 254, 127, 214, 153, 254, - 127, 246, 126, 222, 250, 254, 117, 52, 226, 252, 240, 175, 235, 200, 235, - 208, 226, 63, 251, 162, 240, 176, 2, 248, 9, 216, 90, 2, 222, 237, 48, - 43, 121, 226, 9, 127, 44, 121, 226, 9, 127, 216, 90, 2, 59, 48, 216, 90, - 2, 59, 51, 43, 67, 252, 149, 2, 224, 10, 44, 67, 252, 149, 2, 224, 10, - 216, 15, 43, 163, 127, 216, 15, 44, 163, 127, 251, 183, 43, 163, 127, - 251, 183, 44, 163, 127, 43, 219, 189, 104, 127, 44, 219, 189, 104, 127, - 43, 52, 226, 7, 44, 52, 226, 7, 113, 170, 115, 123, 59, 224, 143, 123, - 59, 115, 113, 170, 224, 143, 92, 244, 19, 59, 224, 143, 244, 89, 59, 79, - 223, 52, 224, 16, 79, 67, 184, 222, 237, 225, 13, 211, 209, 220, 140, - 230, 229, 247, 128, 215, 94, 249, 227, 223, 160, 247, 128, 223, 160, 249, - 227, 215, 94, 220, 152, 248, 214, 2, 43, 242, 115, 248, 214, 2, 44, 242, - 115, 215, 94, 248, 213, 216, 15, 163, 221, 175, 50, 215, 59, 248, 164, - 216, 144, 248, 164, 10, 34, 223, 79, 10, 34, 250, 18, 10, 34, 221, 178, - 111, 10, 34, 221, 178, 105, 10, 34, 221, 178, 158, 10, 34, 225, 170, 10, - 34, 251, 171, 10, 34, 217, 93, 10, 34, 234, 39, 111, 10, 34, 234, 39, - 105, 10, 34, 247, 178, 10, 34, 221, 181, 10, 34, 4, 111, 10, 34, 4, 105, - 10, 34, 233, 103, 111, 10, 34, 233, 103, 105, 10, 34, 233, 103, 158, 10, - 34, 233, 103, 161, 10, 34, 219, 70, 10, 34, 216, 146, 10, 34, 219, 68, - 111, 10, 34, 219, 68, 105, 10, 34, 241, 235, 111, 10, 34, 241, 235, 105, - 10, 34, 242, 22, 10, 34, 223, 150, 10, 34, 250, 90, 10, 34, 218, 38, 10, - 34, 230, 133, 10, 34, 248, 96, 10, 34, 230, 125, 10, 34, 250, 33, 10, 34, - 212, 41, 111, 10, 34, 212, 41, 105, 10, 34, 244, 104, 10, 34, 225, 236, - 111, 10, 34, 225, 236, 105, 10, 34, 219, 162, 163, 215, 237, 215, 189, - 10, 34, 249, 153, 10, 34, 247, 144, 10, 34, 235, 143, 10, 34, 251, 206, - 64, 250, 2, 10, 34, 245, 23, 10, 34, 218, 251, 111, 10, 34, 218, 251, - 105, 10, 34, 252, 162, 10, 34, 219, 169, 10, 34, 251, 71, 219, 169, 10, - 34, 229, 95, 111, 10, 34, 229, 95, 105, 10, 34, 229, 95, 158, 10, 34, - 229, 95, 161, 10, 34, 231, 51, 10, 34, 220, 59, 10, 34, 223, 156, 10, 34, - 245, 45, 10, 34, 226, 213, 10, 34, 251, 141, 111, 10, 34, 251, 141, 105, - 10, 34, 231, 91, 10, 34, 230, 128, 10, 34, 242, 147, 111, 10, 34, 242, - 147, 105, 10, 34, 242, 147, 158, 10, 34, 216, 107, 10, 34, 250, 1, 10, - 34, 212, 9, 111, 10, 34, 212, 9, 105, 10, 34, 251, 71, 221, 172, 10, 34, - 219, 162, 240, 255, 10, 34, 240, 255, 10, 34, 251, 71, 219, 4, 10, 34, - 251, 71, 220, 54, 10, 34, 244, 40, 10, 34, 251, 71, 250, 236, 10, 34, - 219, 162, 212, 57, 10, 34, 212, 58, 111, 10, 34, 212, 58, 105, 10, 34, - 250, 35, 10, 34, 251, 71, 242, 173, 10, 34, 200, 111, 10, 34, 200, 105, - 10, 34, 251, 71, 232, 143, 10, 34, 251, 71, 243, 95, 10, 34, 230, 124, - 111, 10, 34, 230, 124, 105, 10, 34, 223, 162, 10, 34, 251, 215, 10, 34, - 251, 71, 217, 57, 233, 58, 10, 34, 251, 71, 233, 59, 10, 34, 251, 71, - 211, 239, 10, 34, 251, 71, 244, 54, 10, 34, 245, 226, 111, 10, 34, 245, - 226, 105, 10, 34, 245, 226, 158, 10, 34, 251, 71, 245, 225, 10, 34, 241, - 242, 10, 34, 251, 71, 240, 252, 10, 34, 251, 202, 10, 34, 242, 229, 10, - 34, 251, 71, 244, 98, 10, 34, 251, 71, 251, 245, 10, 34, 251, 71, 222, 3, - 10, 34, 219, 162, 212, 2, 10, 34, 219, 162, 211, 41, 10, 34, 251, 71, - 243, 252, 10, 34, 235, 149, 245, 49, 10, 34, 251, 71, 245, 49, 10, 34, - 235, 149, 216, 16, 10, 34, 251, 71, 216, 16, 10, 34, 235, 149, 246, 104, - 10, 34, 251, 71, 246, 104, 10, 34, 215, 91, 10, 34, 235, 149, 215, 91, - 10, 34, 251, 71, 215, 91, 60, 34, 111, 60, 34, 232, 219, 60, 34, 247, - 128, 60, 34, 219, 97, 60, 34, 221, 177, 60, 34, 103, 60, 34, 105, 60, 34, - 232, 243, 60, 34, 231, 190, 60, 34, 233, 39, 60, 34, 245, 137, 60, 34, - 196, 60, 34, 124, 251, 171, 60, 34, 249, 155, 60, 34, 240, 118, 60, 34, - 217, 93, 60, 34, 204, 251, 171, 60, 34, 234, 38, 60, 34, 224, 227, 60, - 34, 211, 202, 60, 34, 218, 245, 60, 34, 44, 204, 251, 171, 60, 34, 241, - 183, 245, 153, 60, 34, 216, 248, 60, 34, 247, 178, 60, 34, 221, 181, 60, - 34, 250, 18, 60, 34, 224, 185, 60, 34, 254, 224, 60, 34, 230, 115, 60, - 34, 245, 153, 60, 34, 245, 231, 60, 34, 221, 202, 60, 34, 242, 181, 60, - 34, 242, 182, 219, 83, 60, 34, 245, 48, 60, 34, 252, 0, 60, 34, 211, 221, - 60, 34, 250, 109, 60, 34, 222, 198, 60, 34, 236, 2, 60, 34, 219, 81, 60, - 34, 233, 102, 60, 34, 249, 164, 60, 34, 218, 239, 60, 34, 230, 120, 60, - 34, 222, 227, 60, 34, 211, 206, 60, 34, 226, 194, 60, 34, 215, 98, 60, - 34, 246, 88, 60, 34, 219, 253, 216, 146, 60, 34, 246, 126, 250, 18, 60, - 34, 200, 218, 110, 60, 34, 113, 242, 17, 60, 34, 220, 2, 60, 34, 251, - 177, 60, 34, 219, 67, 60, 34, 251, 145, 60, 34, 218, 140, 60, 34, 241, - 234, 60, 34, 242, 35, 60, 34, 247, 131, 60, 34, 242, 22, 60, 34, 251, - 162, 60, 34, 223, 150, 60, 34, 221, 189, 60, 34, 247, 207, 60, 34, 253, - 176, 60, 34, 218, 236, 60, 34, 228, 56, 60, 34, 218, 38, 60, 34, 221, - 213, 60, 34, 230, 133, 60, 34, 215, 236, 60, 34, 233, 128, 60, 34, 218, - 131, 60, 34, 248, 96, 60, 34, 212, 21, 60, 34, 247, 154, 228, 56, 60, 34, - 249, 223, 60, 34, 243, 229, 60, 34, 250, 29, 60, 34, 218, 144, 60, 34, - 212, 40, 60, 34, 244, 104, 60, 34, 250, 26, 60, 34, 244, 169, 60, 34, 52, - 211, 178, 60, 34, 163, 215, 237, 215, 189, 60, 34, 219, 91, 60, 34, 244, - 179, 60, 34, 249, 153, 60, 34, 247, 144, 60, 34, 224, 182, 60, 34, 235, - 143, 60, 34, 231, 72, 60, 34, 216, 89, 60, 34, 217, 246, 60, 34, 232, - 237, 60, 34, 214, 131, 60, 34, 244, 128, 60, 34, 251, 206, 64, 250, 2, - 60, 34, 219, 190, 60, 34, 246, 126, 216, 243, 60, 34, 211, 253, 60, 34, - 219, 105, 60, 34, 247, 195, 60, 34, 245, 23, 60, 34, 219, 7, 60, 34, 75, - 60, 34, 218, 133, 60, 34, 218, 250, 60, 34, 216, 0, 60, 34, 242, 154, 60, - 34, 250, 226, 60, 34, 218, 162, 60, 34, 252, 162, 60, 34, 223, 34, 60, - 34, 219, 169, 60, 34, 235, 136, 60, 34, 229, 94, 60, 34, 220, 59, 60, 34, - 244, 157, 60, 34, 226, 213, 60, 34, 254, 126, 60, 34, 225, 32, 60, 34, - 245, 235, 60, 34, 251, 140, 60, 34, 231, 91, 60, 34, 230, 188, 60, 34, - 220, 158, 60, 34, 254, 4, 60, 34, 230, 128, 60, 34, 216, 20, 60, 34, 226, - 169, 60, 34, 251, 209, 60, 34, 218, 129, 60, 34, 249, 233, 60, 34, 242, - 146, 60, 34, 216, 107, 60, 34, 235, 224, 60, 34, 251, 219, 60, 34, 212, - 58, 245, 153, 60, 34, 250, 1, 60, 34, 212, 8, 60, 34, 221, 172, 60, 34, - 240, 255, 60, 34, 219, 4, 60, 34, 214, 22, 60, 34, 252, 80, 60, 34, 225, - 76, 60, 34, 252, 182, 60, 34, 220, 54, 60, 34, 223, 113, 60, 34, 222, - 128, 60, 34, 244, 40, 60, 34, 251, 208, 60, 34, 250, 236, 60, 34, 251, - 234, 60, 34, 230, 130, 60, 34, 212, 57, 60, 34, 250, 35, 60, 34, 211, - 236, 60, 34, 247, 188, 60, 34, 213, 161, 60, 34, 242, 173, 60, 34, 232, - 143, 60, 34, 243, 95, 60, 34, 230, 123, 60, 34, 219, 96, 60, 34, 219, - 253, 217, 77, 251, 245, 60, 34, 223, 162, 60, 34, 251, 215, 60, 34, 211, - 197, 60, 34, 244, 198, 60, 34, 233, 58, 60, 34, 217, 57, 233, 58, 60, 34, - 233, 54, 60, 34, 219, 32, 60, 34, 233, 59, 60, 34, 211, 239, 60, 34, 244, - 54, 60, 34, 245, 225, 60, 34, 241, 242, 60, 34, 244, 8, 60, 34, 240, 252, - 60, 34, 251, 202, 60, 34, 217, 64, 60, 34, 242, 41, 60, 34, 244, 121, 60, - 34, 222, 30, 211, 236, 60, 34, 250, 228, 60, 34, 242, 229, 60, 34, 244, - 98, 60, 34, 251, 245, 60, 34, 222, 3, 60, 34, 248, 82, 60, 34, 212, 2, - 60, 34, 241, 217, 60, 34, 211, 41, 60, 34, 230, 197, 60, 34, 251, 229, - 60, 34, 245, 163, 60, 34, 243, 252, 60, 34, 215, 210, 60, 34, 246, 90, - 60, 34, 223, 144, 60, 34, 228, 58, 60, 34, 245, 49, 60, 34, 216, 16, 60, - 34, 246, 104, 60, 34, 215, 91, 60, 34, 244, 56, 110, 248, 45, 135, 43, - 216, 43, 222, 254, 110, 248, 45, 135, 72, 216, 43, 51, 110, 248, 45, 135, - 43, 216, 43, 230, 229, 22, 222, 254, 110, 248, 45, 135, 72, 216, 43, 230, - 229, 22, 51, 110, 248, 45, 135, 243, 236, 218, 11, 110, 248, 45, 135, - 218, 12, 243, 251, 48, 110, 248, 45, 135, 218, 12, 243, 251, 51, 110, - 248, 45, 135, 218, 12, 243, 251, 233, 52, 110, 248, 45, 135, 218, 12, - 243, 251, 214, 160, 233, 52, 110, 248, 45, 135, 218, 12, 243, 251, 214, - 160, 222, 254, 110, 248, 45, 135, 218, 12, 243, 251, 232, 114, 233, 52, - 110, 248, 45, 135, 226, 126, 110, 219, 20, 110, 249, 227, 110, 243, 236, - 218, 131, 247, 185, 79, 235, 137, 235, 243, 218, 161, 87, 110, 235, 164, - 79, 110, 250, 4, 79, 110, 54, 210, 86, 43, 254, 118, 127, 44, 254, 118, - 127, 43, 52, 254, 118, 127, 44, 52, 254, 118, 127, 43, 249, 169, 127, 44, - 249, 169, 127, 43, 71, 249, 169, 127, 44, 71, 249, 169, 127, 43, 85, 233, - 26, 127, 44, 85, 233, 26, 127, 224, 240, 79, 243, 39, 79, 43, 216, 7, - 220, 55, 127, 44, 216, 7, 220, 55, 127, 43, 71, 233, 26, 127, 44, 71, - 233, 26, 127, 43, 71, 216, 7, 220, 55, 127, 44, 71, 216, 7, 220, 55, 127, - 43, 71, 42, 127, 44, 71, 42, 127, 212, 36, 248, 164, 223, 52, 52, 224, - 194, 224, 1, 79, 52, 224, 194, 224, 1, 79, 121, 52, 224, 194, 224, 1, 79, - 224, 240, 164, 244, 198, 242, 15, 227, 202, 111, 242, 15, 227, 202, 105, - 242, 15, 227, 202, 158, 242, 15, 227, 202, 161, 242, 15, 227, 202, 190, - 242, 15, 227, 202, 195, 242, 15, 227, 202, 199, 242, 15, 227, 202, 196, - 242, 15, 227, 202, 201, 110, 233, 9, 138, 79, 110, 222, 231, 138, 79, - 110, 248, 52, 138, 79, 110, 245, 136, 138, 79, 24, 219, 157, 59, 138, 79, - 24, 52, 59, 138, 79, 212, 32, 248, 164, 67, 234, 239, 223, 80, 79, 67, - 234, 239, 223, 80, 2, 213, 135, 219, 33, 79, 67, 234, 239, 223, 80, 164, - 214, 160, 242, 34, 67, 234, 239, 223, 80, 2, 213, 135, 219, 33, 164, 214, - 160, 242, 34, 67, 234, 239, 223, 80, 164, 232, 114, 242, 34, 37, 224, - 240, 79, 110, 217, 4, 232, 220, 244, 154, 220, 140, 87, 242, 15, 227, - 202, 216, 248, 242, 15, 227, 202, 215, 73, 242, 15, 227, 202, 216, 163, - 67, 110, 235, 164, 79, 231, 145, 79, 226, 3, 254, 148, 79, 110, 45, 235, - 245, 110, 163, 244, 114, 219, 20, 141, 1, 4, 61, 141, 1, 61, 141, 1, 4, - 74, 141, 1, 74, 141, 1, 4, 69, 141, 1, 69, 141, 1, 4, 76, 141, 1, 76, - 141, 1, 4, 78, 141, 1, 78, 141, 1, 176, 141, 1, 243, 142, 141, 1, 234, - 98, 141, 1, 242, 221, 141, 1, 233, 223, 141, 1, 242, 120, 141, 1, 234, - 188, 141, 1, 243, 69, 141, 1, 234, 34, 141, 1, 242, 181, 141, 1, 206, - 141, 1, 210, 116, 141, 1, 219, 193, 141, 1, 210, 44, 141, 1, 218, 84, - 141, 1, 210, 13, 141, 1, 221, 183, 141, 1, 210, 94, 141, 1, 219, 60, 141, - 1, 210, 23, 141, 1, 217, 106, 141, 1, 248, 229, 141, 1, 216, 118, 141, 1, - 248, 11, 141, 1, 4, 215, 119, 141, 1, 215, 119, 141, 1, 246, 86, 141, 1, - 217, 23, 141, 1, 248, 98, 141, 1, 112, 141, 1, 247, 153, 141, 1, 198, - 141, 1, 228, 238, 141, 1, 227, 242, 141, 1, 229, 112, 141, 1, 228, 79, - 141, 1, 162, 141, 1, 252, 199, 141, 1, 191, 141, 1, 241, 187, 141, 1, - 252, 14, 141, 1, 225, 111, 141, 1, 240, 229, 141, 1, 251, 133, 141, 1, - 224, 153, 141, 1, 241, 245, 141, 1, 252, 83, 141, 1, 225, 224, 141, 1, - 241, 75, 141, 1, 251, 213, 141, 1, 225, 19, 141, 1, 186, 141, 1, 230, - 235, 141, 1, 230, 107, 141, 1, 231, 96, 141, 1, 230, 166, 141, 1, 4, 192, - 141, 1, 192, 141, 1, 4, 210, 212, 141, 1, 210, 212, 141, 1, 4, 210, 244, - 141, 1, 210, 244, 141, 1, 205, 141, 1, 223, 38, 141, 1, 222, 142, 141, 1, - 223, 131, 141, 1, 222, 213, 141, 1, 4, 212, 65, 141, 1, 212, 65, 141, 1, - 211, 250, 141, 1, 212, 22, 141, 1, 211, 227, 141, 1, 230, 30, 141, 1, - 212, 116, 141, 1, 4, 176, 141, 1, 4, 234, 188, 38, 234, 207, 213, 135, - 219, 33, 79, 38, 234, 207, 220, 157, 219, 33, 79, 234, 207, 213, 135, - 219, 33, 79, 234, 207, 220, 157, 219, 33, 79, 141, 235, 164, 79, 141, - 213, 135, 235, 164, 79, 141, 247, 229, 210, 225, 234, 207, 52, 240, 175, - 56, 1, 4, 61, 56, 1, 61, 56, 1, 4, 74, 56, 1, 74, 56, 1, 4, 69, 56, 1, - 69, 56, 1, 4, 76, 56, 1, 76, 56, 1, 4, 78, 56, 1, 78, 56, 1, 176, 56, 1, - 243, 142, 56, 1, 234, 98, 56, 1, 242, 221, 56, 1, 233, 223, 56, 1, 242, - 120, 56, 1, 234, 188, 56, 1, 243, 69, 56, 1, 234, 34, 56, 1, 242, 181, - 56, 1, 206, 56, 1, 210, 116, 56, 1, 219, 193, 56, 1, 210, 44, 56, 1, 218, - 84, 56, 1, 210, 13, 56, 1, 221, 183, 56, 1, 210, 94, 56, 1, 219, 60, 56, - 1, 210, 23, 56, 1, 217, 106, 56, 1, 248, 229, 56, 1, 216, 118, 56, 1, - 248, 11, 56, 1, 4, 215, 119, 56, 1, 215, 119, 56, 1, 246, 86, 56, 1, 217, - 23, 56, 1, 248, 98, 56, 1, 112, 56, 1, 247, 153, 56, 1, 198, 56, 1, 228, - 238, 56, 1, 227, 242, 56, 1, 229, 112, 56, 1, 228, 79, 56, 1, 162, 56, 1, - 252, 199, 56, 1, 191, 56, 1, 241, 187, 56, 1, 252, 14, 56, 1, 225, 111, - 56, 1, 240, 229, 56, 1, 251, 133, 56, 1, 224, 153, 56, 1, 241, 245, 56, - 1, 252, 83, 56, 1, 225, 224, 56, 1, 241, 75, 56, 1, 251, 213, 56, 1, 225, - 19, 56, 1, 186, 56, 1, 230, 235, 56, 1, 230, 107, 56, 1, 231, 96, 56, 1, - 230, 166, 56, 1, 4, 192, 56, 1, 192, 56, 1, 4, 210, 212, 56, 1, 210, 212, - 56, 1, 4, 210, 244, 56, 1, 210, 244, 56, 1, 205, 56, 1, 223, 38, 56, 1, - 222, 142, 56, 1, 223, 131, 56, 1, 222, 213, 56, 1, 4, 212, 65, 56, 1, - 212, 65, 56, 1, 211, 250, 56, 1, 212, 22, 56, 1, 211, 227, 56, 1, 230, - 30, 56, 1, 212, 116, 56, 1, 4, 176, 56, 1, 4, 234, 188, 56, 1, 214, 27, - 56, 1, 213, 176, 56, 1, 213, 255, 56, 1, 213, 138, 56, 230, 229, 247, - 128, 234, 207, 224, 176, 219, 33, 79, 56, 235, 164, 79, 56, 213, 135, - 235, 164, 79, 56, 247, 229, 234, 5, 251, 192, 1, 253, 166, 251, 192, 1, - 226, 109, 251, 192, 1, 194, 251, 192, 1, 245, 14, 251, 192, 1, 249, 68, - 251, 192, 1, 217, 153, 251, 192, 1, 230, 30, 251, 192, 1, 156, 251, 192, - 1, 243, 209, 251, 192, 1, 235, 29, 251, 192, 1, 242, 67, 251, 192, 1, - 235, 150, 251, 192, 1, 224, 99, 251, 192, 1, 211, 178, 251, 192, 1, 210, - 83, 251, 192, 1, 250, 166, 251, 192, 1, 220, 106, 251, 192, 1, 153, 251, - 192, 1, 210, 159, 251, 192, 1, 251, 74, 251, 192, 1, 222, 93, 251, 192, - 1, 61, 251, 192, 1, 78, 251, 192, 1, 76, 251, 192, 1, 245, 205, 251, 192, - 1, 254, 210, 251, 192, 1, 245, 203, 251, 192, 1, 253, 200, 251, 192, 1, - 226, 138, 251, 192, 1, 254, 131, 251, 192, 1, 245, 158, 251, 192, 1, 254, - 123, 251, 192, 1, 245, 146, 251, 192, 1, 245, 100, 251, 192, 1, 74, 251, - 192, 1, 69, 251, 192, 1, 235, 162, 251, 192, 1, 214, 105, 251, 192, 1, - 229, 84, 251, 192, 1, 242, 185, 251, 192, 1, 236, 41, 24, 1, 234, 64, 24, - 1, 218, 217, 24, 1, 234, 57, 24, 1, 228, 231, 24, 1, 228, 229, 24, 1, - 228, 228, 24, 1, 216, 102, 24, 1, 218, 206, 24, 1, 223, 29, 24, 1, 223, - 24, 24, 1, 223, 21, 24, 1, 223, 14, 24, 1, 223, 9, 24, 1, 223, 4, 24, 1, - 223, 15, 24, 1, 223, 27, 24, 1, 230, 222, 24, 1, 225, 98, 24, 1, 218, - 214, 24, 1, 225, 87, 24, 1, 219, 150, 24, 1, 218, 211, 24, 1, 236, 63, - 24, 1, 250, 54, 24, 1, 218, 221, 24, 1, 250, 114, 24, 1, 234, 116, 24, 1, - 216, 174, 24, 1, 225, 134, 24, 1, 241, 179, 24, 1, 61, 24, 1, 254, 252, - 24, 1, 192, 24, 1, 211, 92, 24, 1, 245, 125, 24, 1, 76, 24, 1, 211, 36, - 24, 1, 211, 47, 24, 1, 78, 24, 1, 212, 65, 24, 1, 212, 62, 24, 1, 226, - 238, 24, 1, 210, 244, 24, 1, 69, 24, 1, 212, 11, 24, 1, 212, 22, 24, 1, - 211, 250, 24, 1, 210, 212, 24, 1, 245, 63, 24, 1, 211, 8, 24, 1, 74, 24, - 244, 111, 24, 1, 218, 215, 24, 1, 228, 221, 24, 1, 228, 223, 24, 1, 228, - 226, 24, 1, 223, 22, 24, 1, 223, 3, 24, 1, 223, 11, 24, 1, 223, 16, 24, - 1, 223, 1, 24, 1, 230, 215, 24, 1, 230, 212, 24, 1, 230, 216, 24, 1, 234, - 227, 24, 1, 225, 93, 24, 1, 225, 79, 24, 1, 225, 85, 24, 1, 225, 82, 24, - 1, 225, 96, 24, 1, 225, 80, 24, 1, 234, 225, 24, 1, 234, 223, 24, 1, 219, - 143, 24, 1, 219, 141, 24, 1, 219, 133, 24, 1, 219, 138, 24, 1, 219, 148, - 24, 1, 226, 36, 24, 1, 218, 218, 24, 1, 211, 26, 24, 1, 211, 22, 24, 1, - 211, 23, 24, 1, 234, 226, 24, 1, 218, 219, 24, 1, 211, 32, 24, 1, 210, - 238, 24, 1, 210, 237, 24, 1, 210, 240, 24, 1, 210, 203, 24, 1, 210, 204, - 24, 1, 210, 207, 24, 1, 254, 42, 24, 1, 254, 36, 110, 254, 107, 232, 209, - 79, 110, 254, 107, 223, 53, 79, 110, 254, 107, 123, 79, 110, 254, 107, - 113, 79, 110, 254, 107, 134, 79, 110, 254, 107, 244, 19, 79, 110, 254, - 107, 216, 15, 79, 110, 254, 107, 230, 229, 79, 110, 254, 107, 251, 183, - 79, 110, 254, 107, 244, 100, 79, 110, 254, 107, 221, 178, 79, 110, 254, - 107, 216, 170, 79, 110, 254, 107, 244, 12, 79, 110, 254, 107, 241, 231, - 79, 110, 254, 107, 245, 232, 79, 110, 254, 107, 231, 191, 79, 251, 192, - 1, 251, 133, 251, 192, 1, 210, 44, 251, 192, 1, 235, 114, 251, 192, 1, - 242, 120, 251, 192, 1, 245, 217, 251, 192, 1, 245, 143, 251, 192, 1, 226, - 187, 251, 192, 1, 226, 191, 251, 192, 1, 235, 186, 251, 192, 1, 254, 109, - 251, 192, 1, 235, 231, 251, 192, 1, 214, 168, 251, 192, 1, 236, 23, 251, - 192, 1, 229, 62, 251, 192, 1, 254, 204, 251, 192, 1, 253, 195, 251, 192, - 1, 254, 144, 251, 192, 1, 226, 208, 251, 192, 1, 226, 193, 251, 192, 1, - 235, 228, 251, 192, 40, 1, 226, 109, 251, 192, 40, 1, 217, 153, 251, 192, - 40, 1, 235, 29, 251, 192, 40, 1, 242, 67, 251, 192, 1, 243, 1, 251, 192, - 1, 233, 5, 251, 192, 1, 209, 250, 10, 218, 105, 217, 153, 10, 218, 105, - 212, 4, 10, 218, 105, 211, 158, 10, 218, 105, 251, 87, 10, 218, 105, 217, - 255, 10, 218, 105, 240, 165, 10, 218, 105, 240, 169, 10, 218, 105, 240, - 238, 10, 218, 105, 240, 166, 10, 218, 105, 217, 156, 10, 218, 105, 240, - 168, 10, 218, 105, 240, 164, 10, 218, 105, 240, 236, 10, 218, 105, 240, - 167, 10, 218, 105, 240, 163, 10, 218, 105, 230, 30, 10, 218, 105, 242, - 67, 10, 218, 105, 222, 93, 10, 218, 105, 226, 109, 10, 218, 105, 219, 23, - 10, 218, 105, 249, 68, 10, 218, 105, 240, 170, 10, 218, 105, 241, 197, - 10, 218, 105, 217, 165, 10, 218, 105, 217, 234, 10, 218, 105, 218, 170, - 10, 218, 105, 220, 112, 10, 218, 105, 225, 228, 10, 218, 105, 224, 101, - 10, 218, 105, 216, 44, 10, 218, 105, 217, 155, 10, 218, 105, 217, 245, - 10, 218, 105, 240, 177, 10, 218, 105, 240, 162, 10, 218, 105, 225, 152, - 10, 218, 105, 224, 99, 56, 1, 4, 233, 223, 56, 1, 4, 219, 193, 56, 1, 4, - 218, 84, 56, 1, 4, 112, 56, 1, 4, 227, 242, 56, 1, 4, 162, 56, 1, 4, 241, - 187, 56, 1, 4, 240, 229, 56, 1, 4, 241, 245, 56, 1, 4, 241, 75, 56, 1, 4, - 230, 107, 56, 1, 4, 205, 56, 1, 4, 223, 38, 56, 1, 4, 222, 142, 56, 1, 4, - 223, 131, 56, 1, 4, 222, 213, 88, 24, 234, 64, 88, 24, 228, 231, 88, 24, - 216, 102, 88, 24, 223, 29, 88, 24, 230, 222, 88, 24, 225, 98, 88, 24, - 219, 150, 88, 24, 236, 63, 88, 24, 250, 54, 88, 24, 250, 114, 88, 24, - 234, 116, 88, 24, 216, 174, 88, 24, 225, 134, 88, 24, 241, 179, 88, 24, - 234, 65, 61, 88, 24, 228, 232, 61, 88, 24, 216, 103, 61, 88, 24, 223, 30, - 61, 88, 24, 230, 223, 61, 88, 24, 225, 99, 61, 88, 24, 219, 151, 61, 88, - 24, 236, 64, 61, 88, 24, 250, 55, 61, 88, 24, 250, 115, 61, 88, 24, 234, - 117, 61, 88, 24, 216, 175, 61, 88, 24, 225, 135, 61, 88, 24, 241, 180, - 61, 88, 24, 250, 55, 69, 88, 234, 9, 135, 226, 221, 88, 234, 9, 135, 144, - 240, 229, 88, 154, 111, 88, 154, 105, 88, 154, 158, 88, 154, 161, 88, - 154, 190, 88, 154, 195, 88, 154, 199, 88, 154, 196, 88, 154, 201, 88, - 154, 216, 248, 88, 154, 230, 133, 88, 154, 244, 104, 88, 154, 212, 40, - 88, 154, 211, 214, 88, 154, 231, 44, 88, 154, 245, 231, 88, 154, 218, 38, - 88, 154, 218, 134, 88, 154, 241, 251, 88, 154, 219, 56, 88, 154, 229, - 209, 88, 154, 219, 6, 88, 154, 244, 110, 88, 154, 249, 208, 88, 154, 233, - 131, 88, 154, 223, 74, 88, 154, 251, 23, 88, 154, 218, 88, 88, 154, 218, - 21, 88, 154, 245, 135, 88, 154, 223, 66, 88, 154, 254, 159, 88, 154, 244, - 136, 88, 154, 223, 64, 88, 154, 220, 158, 88, 154, 223, 130, 37, 154, - 224, 15, 37, 154, 234, 86, 37, 154, 221, 200, 37, 154, 234, 5, 37, 54, - 216, 249, 226, 201, 85, 218, 236, 37, 54, 215, 74, 226, 201, 85, 218, - 236, 37, 54, 216, 164, 226, 201, 85, 218, 236, 37, 54, 244, 24, 226, 201, - 85, 218, 236, 37, 54, 244, 123, 226, 201, 85, 218, 236, 37, 54, 219, 114, - 226, 201, 85, 218, 236, 37, 54, 220, 119, 226, 201, 85, 218, 236, 37, 54, - 245, 193, 226, 201, 85, 218, 236, 225, 255, 50, 37, 54, 215, 74, 111, 37, - 54, 215, 74, 105, 37, 54, 215, 74, 158, 37, 54, 215, 74, 161, 37, 54, - 215, 74, 190, 37, 54, 215, 74, 195, 37, 54, 215, 74, 199, 37, 54, 215, - 74, 196, 37, 54, 215, 74, 201, 37, 54, 216, 163, 37, 54, 216, 164, 111, - 37, 54, 216, 164, 105, 37, 54, 216, 164, 158, 37, 54, 216, 164, 161, 37, - 54, 216, 164, 190, 37, 24, 234, 64, 37, 24, 228, 231, 37, 24, 216, 102, - 37, 24, 223, 29, 37, 24, 230, 222, 37, 24, 225, 98, 37, 24, 219, 150, 37, - 24, 236, 63, 37, 24, 250, 54, 37, 24, 250, 114, 37, 24, 234, 116, 37, 24, - 216, 174, 37, 24, 225, 134, 37, 24, 241, 179, 37, 24, 234, 65, 61, 37, - 24, 228, 232, 61, 37, 24, 216, 103, 61, 37, 24, 223, 30, 61, 37, 24, 230, - 223, 61, 37, 24, 225, 99, 61, 37, 24, 219, 151, 61, 37, 24, 236, 64, 61, - 37, 24, 250, 55, 61, 37, 24, 250, 115, 61, 37, 24, 234, 117, 61, 37, 24, - 216, 175, 61, 37, 24, 225, 135, 61, 37, 24, 241, 180, 61, 37, 234, 9, - 135, 250, 156, 37, 234, 9, 135, 235, 53, 37, 24, 236, 64, 69, 234, 9, - 218, 161, 87, 37, 154, 111, 37, 154, 105, 37, 154, 158, 37, 154, 161, 37, - 154, 190, 37, 154, 195, 37, 154, 199, 37, 154, 196, 37, 154, 201, 37, - 154, 216, 248, 37, 154, 230, 133, 37, 154, 244, 104, 37, 154, 212, 40, - 37, 154, 211, 214, 37, 154, 231, 44, 37, 154, 245, 231, 37, 154, 218, 38, - 37, 154, 218, 134, 37, 154, 241, 251, 37, 154, 219, 56, 37, 154, 229, - 209, 37, 154, 219, 6, 37, 154, 244, 110, 37, 154, 249, 208, 37, 154, 233, - 131, 37, 154, 221, 176, 37, 154, 231, 194, 37, 154, 244, 145, 37, 154, - 218, 50, 37, 154, 245, 42, 37, 154, 224, 190, 37, 154, 253, 204, 37, 154, - 235, 165, 37, 154, 223, 64, 37, 154, 249, 172, 37, 154, 249, 163, 37, - 154, 241, 172, 37, 154, 250, 182, 37, 154, 232, 116, 37, 154, 233, 52, - 37, 154, 222, 254, 37, 154, 231, 88, 37, 154, 223, 90, 37, 154, 218, 88, - 37, 154, 218, 21, 37, 154, 245, 135, 37, 154, 223, 66, 37, 154, 254, 159, - 37, 154, 228, 217, 37, 54, 216, 164, 195, 37, 54, 216, 164, 199, 37, 54, - 216, 164, 196, 37, 54, 216, 164, 201, 37, 54, 244, 23, 37, 54, 244, 24, - 111, 37, 54, 244, 24, 105, 37, 54, 244, 24, 158, 37, 54, 244, 24, 161, - 37, 54, 244, 24, 190, 37, 54, 244, 24, 195, 37, 54, 244, 24, 199, 37, 54, - 244, 24, 196, 37, 54, 244, 24, 201, 37, 54, 244, 122, 110, 217, 4, 16, - 31, 235, 139, 110, 217, 4, 16, 31, 244, 156, 110, 217, 4, 16, 31, 231, - 165, 110, 217, 4, 16, 31, 254, 55, 110, 217, 4, 16, 31, 231, 137, 110, - 217, 4, 16, 31, 235, 51, 110, 217, 4, 16, 31, 235, 52, 110, 217, 4, 16, - 31, 253, 196, 110, 217, 4, 16, 31, 220, 138, 110, 217, 4, 16, 31, 226, - 243, 110, 217, 4, 16, 31, 228, 45, 110, 217, 4, 16, 31, 248, 93, 42, 241, - 197, 42, 245, 96, 42, 245, 51, 232, 225, 232, 246, 50, 37, 56, 61, 37, - 56, 74, 37, 56, 69, 37, 56, 76, 37, 56, 78, 37, 56, 176, 37, 56, 234, 98, - 37, 56, 233, 223, 37, 56, 234, 188, 37, 56, 234, 34, 37, 56, 206, 37, 56, - 219, 193, 37, 56, 218, 84, 37, 56, 221, 183, 37, 56, 219, 60, 37, 56, - 217, 106, 37, 56, 216, 118, 37, 56, 215, 119, 37, 56, 217, 23, 37, 56, - 112, 37, 56, 198, 37, 56, 228, 238, 37, 56, 227, 242, 37, 56, 229, 112, - 37, 56, 228, 79, 37, 56, 162, 37, 56, 241, 187, 37, 56, 240, 229, 37, 56, - 241, 245, 37, 56, 241, 75, 37, 56, 186, 37, 56, 230, 235, 37, 56, 230, - 107, 37, 56, 231, 96, 37, 56, 230, 166, 37, 56, 192, 37, 56, 210, 212, - 37, 56, 210, 244, 37, 56, 205, 37, 56, 223, 38, 37, 56, 222, 142, 37, 56, - 223, 131, 37, 56, 222, 213, 37, 56, 212, 65, 37, 56, 211, 250, 37, 56, - 212, 22, 37, 56, 211, 227, 42, 254, 79, 42, 253, 247, 42, 254, 103, 42, - 255, 40, 42, 235, 233, 42, 235, 203, 42, 214, 166, 42, 245, 74, 42, 245, - 214, 42, 226, 190, 42, 226, 184, 42, 234, 251, 42, 234, 220, 42, 234, - 217, 42, 243, 99, 42, 243, 108, 42, 242, 211, 42, 242, 207, 42, 233, 156, - 42, 242, 200, 42, 234, 78, 42, 234, 77, 42, 234, 76, 42, 234, 75, 42, - 242, 93, 42, 242, 92, 42, 233, 199, 42, 233, 201, 42, 234, 184, 42, 234, - 7, 42, 234, 14, 42, 222, 18, 42, 221, 239, 42, 219, 131, 42, 220, 143, - 42, 220, 142, 42, 248, 226, 42, 248, 44, 42, 247, 129, 42, 216, 33, 42, - 229, 205, 42, 228, 46, 42, 242, 39, 42, 226, 88, 42, 226, 87, 42, 252, - 196, 42, 225, 108, 42, 225, 72, 42, 225, 73, 42, 251, 242, 42, 240, 228, - 42, 240, 224, 42, 251, 99, 42, 240, 211, 42, 241, 222, 42, 225, 162, 42, - 225, 197, 42, 241, 205, 42, 225, 194, 42, 225, 210, 42, 252, 69, 42, 225, - 9, 42, 251, 188, 42, 241, 63, 42, 224, 253, 42, 241, 55, 42, 241, 57, 42, - 231, 206, 42, 231, 202, 42, 231, 211, 42, 231, 155, 42, 231, 180, 42, - 230, 202, 42, 230, 181, 42, 230, 180, 42, 231, 79, 42, 231, 76, 42, 231, - 80, 42, 211, 102, 42, 211, 100, 42, 210, 201, 42, 222, 229, 42, 222, 233, - 42, 222, 119, 42, 222, 113, 42, 223, 88, 42, 223, 85, 42, 212, 38, 110, - 217, 4, 16, 31, 240, 246, 210, 86, 110, 217, 4, 16, 31, 240, 246, 111, - 110, 217, 4, 16, 31, 240, 246, 105, 110, 217, 4, 16, 31, 240, 246, 158, - 110, 217, 4, 16, 31, 240, 246, 161, 110, 217, 4, 16, 31, 240, 246, 190, - 110, 217, 4, 16, 31, 240, 246, 195, 110, 217, 4, 16, 31, 240, 246, 199, - 110, 217, 4, 16, 31, 240, 246, 196, 110, 217, 4, 16, 31, 240, 246, 201, - 110, 217, 4, 16, 31, 240, 246, 216, 248, 110, 217, 4, 16, 31, 240, 246, - 245, 175, 110, 217, 4, 16, 31, 240, 246, 215, 76, 110, 217, 4, 16, 31, - 240, 246, 216, 165, 110, 217, 4, 16, 31, 240, 246, 244, 13, 110, 217, 4, - 16, 31, 240, 246, 244, 126, 110, 217, 4, 16, 31, 240, 246, 219, 121, 110, - 217, 4, 16, 31, 240, 246, 220, 121, 110, 217, 4, 16, 31, 240, 246, 245, - 198, 110, 217, 4, 16, 31, 240, 246, 228, 202, 110, 217, 4, 16, 31, 240, - 246, 215, 73, 110, 217, 4, 16, 31, 240, 246, 215, 67, 110, 217, 4, 16, - 31, 240, 246, 215, 63, 110, 217, 4, 16, 31, 240, 246, 215, 64, 110, 217, - 4, 16, 31, 240, 246, 215, 69, 42, 240, 237, 42, 248, 229, 42, 253, 200, - 42, 130, 42, 226, 129, 42, 225, 229, 42, 247, 155, 42, 247, 156, 218, - 235, 42, 247, 156, 249, 116, 42, 235, 162, 42, 245, 99, 229, 210, 241, - 223, 42, 245, 99, 229, 210, 217, 175, 42, 245, 99, 229, 210, 217, 75, 42, - 245, 99, 229, 210, 231, 75, 42, 249, 165, 42, 226, 94, 254, 133, 42, 198, - 42, 230, 108, 61, 42, 186, 42, 176, 42, 234, 191, 42, 231, 134, 42, 243, - 87, 42, 251, 26, 42, 234, 190, 42, 225, 153, 42, 229, 86, 42, 230, 108, - 245, 14, 42, 230, 108, 243, 209, 42, 231, 20, 42, 234, 140, 42, 240, 170, - 42, 234, 100, 42, 230, 237, 42, 242, 223, 42, 216, 120, 42, 230, 108, - 156, 42, 230, 174, 42, 247, 165, 42, 234, 46, 42, 244, 53, 42, 228, 117, - 42, 230, 108, 194, 42, 230, 171, 42, 249, 247, 42, 234, 40, 42, 230, 172, - 218, 235, 42, 249, 248, 218, 235, 42, 232, 55, 218, 235, 42, 234, 41, - 218, 235, 42, 230, 172, 249, 116, 42, 249, 248, 249, 116, 42, 232, 55, - 249, 116, 42, 234, 41, 249, 116, 42, 232, 55, 115, 222, 93, 42, 232, 55, - 115, 222, 94, 218, 235, 42, 191, 42, 234, 1, 42, 230, 110, 42, 242, 158, - 42, 223, 179, 42, 223, 180, 115, 222, 93, 42, 223, 180, 115, 222, 94, - 218, 235, 42, 224, 165, 42, 228, 18, 42, 230, 108, 222, 93, 42, 230, 109, - 42, 224, 119, 42, 227, 180, 42, 230, 108, 214, 105, 42, 230, 54, 42, 233, - 191, 42, 230, 55, 231, 79, 42, 224, 118, 42, 227, 179, 42, 230, 108, 212, - 98, 42, 230, 48, 42, 233, 189, 42, 230, 49, 231, 79, 42, 235, 30, 226, - 224, 42, 232, 55, 226, 224, 42, 254, 144, 42, 251, 168, 42, 250, 222, 42, - 250, 199, 42, 251, 75, 115, 234, 140, 42, 249, 246, 42, 248, 150, 42, - 242, 79, 42, 162, 42, 240, 238, 42, 236, 6, 42, 234, 53, 42, 234, 41, - 251, 2, 42, 233, 225, 42, 232, 165, 42, 232, 164, 42, 232, 153, 42, 232, - 68, 42, 231, 135, 219, 81, 42, 230, 201, 42, 230, 157, 42, 225, 151, 42, - 225, 22, 42, 224, 222, 42, 224, 220, 42, 218, 229, 42, 218, 3, 42, 212, - 24, 42, 214, 106, 115, 194, 42, 116, 115, 194, 110, 217, 4, 16, 31, 248, - 154, 111, 110, 217, 4, 16, 31, 248, 154, 105, 110, 217, 4, 16, 31, 248, - 154, 158, 110, 217, 4, 16, 31, 248, 154, 161, 110, 217, 4, 16, 31, 248, - 154, 190, 110, 217, 4, 16, 31, 248, 154, 195, 110, 217, 4, 16, 31, 248, - 154, 199, 110, 217, 4, 16, 31, 248, 154, 196, 110, 217, 4, 16, 31, 248, - 154, 201, 110, 217, 4, 16, 31, 248, 154, 216, 248, 110, 217, 4, 16, 31, - 248, 154, 245, 175, 110, 217, 4, 16, 31, 248, 154, 215, 76, 110, 217, 4, - 16, 31, 248, 154, 216, 165, 110, 217, 4, 16, 31, 248, 154, 244, 13, 110, - 217, 4, 16, 31, 248, 154, 244, 126, 110, 217, 4, 16, 31, 248, 154, 219, - 121, 110, 217, 4, 16, 31, 248, 154, 220, 121, 110, 217, 4, 16, 31, 248, - 154, 245, 198, 110, 217, 4, 16, 31, 248, 154, 228, 202, 110, 217, 4, 16, - 31, 248, 154, 215, 73, 110, 217, 4, 16, 31, 248, 154, 215, 67, 110, 217, - 4, 16, 31, 248, 154, 215, 63, 110, 217, 4, 16, 31, 248, 154, 215, 64, - 110, 217, 4, 16, 31, 248, 154, 215, 69, 110, 217, 4, 16, 31, 248, 154, - 215, 70, 110, 217, 4, 16, 31, 248, 154, 215, 65, 110, 217, 4, 16, 31, - 248, 154, 215, 66, 110, 217, 4, 16, 31, 248, 154, 215, 72, 110, 217, 4, - 16, 31, 248, 154, 215, 68, 110, 217, 4, 16, 31, 248, 154, 216, 163, 110, - 217, 4, 16, 31, 248, 154, 216, 162, 42, 243, 125, 241, 199, 31, 216, 197, - 249, 148, 241, 230, 241, 199, 31, 216, 197, 223, 125, 245, 231, 241, 199, - 31, 247, 239, 253, 215, 216, 197, 252, 64, 241, 199, 31, 210, 223, 244, - 46, 241, 199, 31, 212, 59, 241, 199, 31, 249, 211, 241, 199, 31, 216, - 197, 254, 11, 241, 199, 31, 241, 67, 216, 39, 241, 199, 31, 4, 217, 62, - 241, 199, 31, 215, 238, 241, 199, 31, 225, 222, 241, 199, 31, 218, 160, - 241, 199, 31, 244, 147, 241, 199, 31, 242, 139, 224, 243, 241, 199, 31, - 230, 160, 241, 199, 31, 245, 134, 241, 199, 31, 244, 47, 241, 199, 31, - 211, 207, 226, 201, 216, 197, 248, 94, 241, 199, 31, 254, 59, 241, 199, - 31, 249, 193, 241, 199, 31, 251, 235, 216, 139, 241, 199, 31, 242, 156, - 241, 199, 31, 218, 247, 254, 78, 241, 199, 31, 223, 56, 241, 199, 31, - 235, 227, 241, 199, 31, 242, 139, 217, 62, 241, 199, 31, 230, 116, 249, - 167, 241, 199, 31, 242, 139, 224, 200, 241, 199, 31, 216, 197, 255, 27, - 212, 40, 241, 199, 31, 216, 197, 250, 16, 244, 104, 241, 199, 31, 235, - 240, 241, 199, 31, 246, 65, 241, 199, 31, 223, 59, 241, 199, 31, 242, - 139, 224, 227, 241, 199, 31, 224, 180, 241, 199, 31, 248, 169, 64, 216, - 197, 232, 236, 241, 199, 31, 216, 197, 244, 182, 241, 199, 31, 226, 167, - 241, 199, 31, 226, 248, 241, 199, 31, 248, 67, 241, 199, 31, 248, 87, - 241, 199, 31, 235, 254, 241, 199, 31, 251, 157, 241, 199, 31, 249, 229, - 216, 43, 231, 81, 241, 199, 31, 243, 94, 216, 39, 241, 199, 31, 224, 128, - 214, 154, 241, 199, 31, 226, 166, 241, 199, 31, 216, 197, 212, 13, 241, - 199, 31, 223, 48, 241, 199, 31, 216, 197, 250, 228, 241, 199, 31, 216, - 197, 254, 7, 216, 134, 241, 199, 31, 216, 197, 234, 185, 218, 136, 230, - 120, 241, 199, 31, 248, 40, 241, 199, 31, 216, 197, 231, 157, 231, 207, - 241, 199, 31, 255, 28, 241, 199, 31, 216, 197, 212, 54, 241, 199, 31, - 216, 197, 243, 54, 211, 239, 241, 199, 31, 216, 197, 235, 58, 233, 113, - 241, 199, 31, 247, 192, 241, 199, 31, 232, 226, 241, 199, 31, 235, 230, - 215, 188, 241, 199, 31, 4, 224, 200, 241, 199, 31, 254, 226, 249, 220, - 241, 199, 31, 252, 67, 249, 220, 8, 3, 235, 166, 8, 3, 235, 159, 8, 3, - 74, 8, 3, 235, 189, 8, 3, 236, 65, 8, 3, 236, 48, 8, 3, 236, 67, 8, 3, - 236, 66, 8, 3, 253, 214, 8, 3, 253, 177, 8, 3, 61, 8, 3, 254, 80, 8, 3, - 214, 164, 8, 3, 214, 167, 8, 3, 214, 165, 8, 3, 226, 144, 8, 3, 226, 118, - 8, 3, 78, 8, 3, 226, 179, 8, 3, 245, 43, 8, 3, 76, 8, 3, 211, 195, 8, 3, - 251, 236, 8, 3, 251, 233, 8, 3, 252, 14, 8, 3, 251, 246, 8, 3, 252, 3, 8, - 3, 252, 2, 8, 3, 252, 5, 8, 3, 252, 4, 8, 3, 252, 129, 8, 3, 252, 121, 8, - 3, 252, 199, 8, 3, 252, 150, 8, 3, 251, 109, 8, 3, 251, 113, 8, 3, 251, - 110, 8, 3, 251, 187, 8, 3, 251, 171, 8, 3, 251, 213, 8, 3, 251, 193, 8, - 3, 252, 29, 8, 3, 252, 83, 8, 3, 252, 41, 8, 3, 251, 95, 8, 3, 251, 92, - 8, 3, 251, 133, 8, 3, 251, 108, 8, 3, 251, 102, 8, 3, 251, 106, 8, 3, - 251, 80, 8, 3, 251, 78, 8, 3, 251, 85, 8, 3, 251, 83, 8, 3, 251, 81, 8, - 3, 251, 82, 8, 3, 225, 52, 8, 3, 225, 48, 8, 3, 225, 111, 8, 3, 225, 62, - 8, 3, 225, 78, 8, 3, 225, 105, 8, 3, 225, 101, 8, 3, 225, 244, 8, 3, 225, - 234, 8, 3, 191, 8, 3, 226, 25, 8, 3, 224, 138, 8, 3, 224, 140, 8, 3, 224, - 139, 8, 3, 224, 236, 8, 3, 224, 225, 8, 3, 225, 19, 8, 3, 224, 248, 8, 3, - 224, 124, 8, 3, 224, 120, 8, 3, 224, 153, 8, 3, 224, 137, 8, 3, 224, 129, - 8, 3, 224, 135, 8, 3, 224, 103, 8, 3, 224, 102, 8, 3, 224, 107, 8, 3, - 224, 106, 8, 3, 224, 104, 8, 3, 224, 105, 8, 3, 252, 104, 8, 3, 252, 103, - 8, 3, 252, 110, 8, 3, 252, 105, 8, 3, 252, 107, 8, 3, 252, 106, 8, 3, - 252, 109, 8, 3, 252, 108, 8, 3, 252, 116, 8, 3, 252, 115, 8, 3, 252, 119, - 8, 3, 252, 117, 8, 3, 252, 95, 8, 3, 252, 97, 8, 3, 252, 96, 8, 3, 252, - 100, 8, 3, 252, 99, 8, 3, 252, 102, 8, 3, 252, 101, 8, 3, 252, 111, 8, 3, - 252, 114, 8, 3, 252, 112, 8, 3, 252, 91, 8, 3, 252, 90, 8, 3, 252, 98, 8, - 3, 252, 94, 8, 3, 252, 92, 8, 3, 252, 93, 8, 3, 252, 87, 8, 3, 252, 86, - 8, 3, 252, 89, 8, 3, 252, 88, 8, 3, 229, 174, 8, 3, 229, 173, 8, 3, 229, - 179, 8, 3, 229, 175, 8, 3, 229, 176, 8, 3, 229, 178, 8, 3, 229, 177, 8, - 3, 229, 182, 8, 3, 229, 181, 8, 3, 229, 184, 8, 3, 229, 183, 8, 3, 229, - 170, 8, 3, 229, 169, 8, 3, 229, 172, 8, 3, 229, 171, 8, 3, 229, 163, 8, - 3, 229, 162, 8, 3, 229, 167, 8, 3, 229, 166, 8, 3, 229, 164, 8, 3, 229, - 165, 8, 3, 229, 157, 8, 3, 229, 156, 8, 3, 229, 161, 8, 3, 229, 160, 8, - 3, 229, 158, 8, 3, 229, 159, 8, 3, 241, 117, 8, 3, 241, 116, 8, 3, 241, - 122, 8, 3, 241, 118, 8, 3, 241, 119, 8, 3, 241, 121, 8, 3, 241, 120, 8, - 3, 241, 125, 8, 3, 241, 124, 8, 3, 241, 127, 8, 3, 241, 126, 8, 3, 241, - 108, 8, 3, 241, 110, 8, 3, 241, 109, 8, 3, 241, 113, 8, 3, 241, 112, 8, - 3, 241, 115, 8, 3, 241, 114, 8, 3, 241, 104, 8, 3, 241, 103, 8, 3, 241, - 111, 8, 3, 241, 107, 8, 3, 241, 105, 8, 3, 241, 106, 8, 3, 241, 98, 8, 3, - 241, 102, 8, 3, 241, 101, 8, 3, 241, 99, 8, 3, 241, 100, 8, 3, 230, 177, - 8, 3, 230, 176, 8, 3, 230, 235, 8, 3, 230, 183, 8, 3, 230, 208, 8, 3, - 230, 226, 8, 3, 230, 224, 8, 3, 231, 144, 8, 3, 231, 139, 8, 3, 186, 8, - 3, 231, 177, 8, 3, 230, 79, 8, 3, 230, 78, 8, 3, 230, 82, 8, 3, 230, 80, - 8, 3, 230, 126, 8, 3, 230, 112, 8, 3, 230, 166, 8, 3, 230, 131, 8, 3, - 231, 31, 8, 3, 231, 96, 8, 3, 230, 60, 8, 3, 230, 56, 8, 3, 230, 107, 8, - 3, 230, 75, 8, 3, 230, 68, 8, 3, 230, 73, 8, 3, 230, 33, 8, 3, 230, 32, - 8, 3, 230, 38, 8, 3, 230, 35, 8, 3, 244, 91, 8, 3, 244, 86, 8, 3, 244, - 129, 8, 3, 244, 106, 8, 3, 244, 175, 8, 3, 244, 166, 8, 3, 244, 204, 8, - 3, 244, 178, 8, 3, 244, 11, 8, 3, 244, 51, 8, 3, 244, 35, 8, 3, 243, 225, - 8, 3, 243, 224, 8, 3, 243, 241, 8, 3, 243, 230, 8, 3, 243, 228, 8, 3, - 243, 229, 8, 3, 243, 212, 8, 3, 243, 211, 8, 3, 243, 215, 8, 3, 243, 213, - 8, 3, 213, 144, 8, 3, 213, 139, 8, 3, 213, 176, 8, 3, 213, 153, 8, 3, - 213, 166, 8, 3, 213, 163, 8, 3, 213, 168, 8, 3, 213, 167, 8, 3, 214, 7, - 8, 3, 214, 2, 8, 3, 214, 27, 8, 3, 214, 18, 8, 3, 213, 125, 8, 3, 213, - 121, 8, 3, 213, 138, 8, 3, 213, 126, 8, 3, 213, 178, 8, 3, 213, 244, 8, - 3, 212, 110, 8, 3, 212, 108, 8, 3, 212, 116, 8, 3, 212, 113, 8, 3, 212, - 111, 8, 3, 212, 112, 8, 3, 212, 102, 8, 3, 212, 101, 8, 3, 212, 106, 8, - 3, 212, 105, 8, 3, 212, 103, 8, 3, 212, 104, 8, 3, 247, 186, 8, 3, 247, - 174, 8, 3, 248, 11, 8, 3, 247, 211, 8, 3, 247, 244, 8, 3, 247, 248, 8, 3, - 247, 247, 8, 3, 248, 160, 8, 3, 248, 155, 8, 3, 248, 229, 8, 3, 248, 180, - 8, 3, 246, 70, 8, 3, 246, 71, 8, 3, 247, 128, 8, 3, 246, 110, 8, 3, 247, - 153, 8, 3, 247, 130, 8, 3, 248, 38, 8, 3, 248, 98, 8, 3, 248, 53, 8, 3, - 246, 61, 8, 3, 246, 59, 8, 3, 246, 86, 8, 3, 246, 69, 8, 3, 246, 64, 8, - 3, 246, 67, 8, 3, 216, 68, 8, 3, 216, 62, 8, 3, 216, 118, 8, 3, 216, 77, - 8, 3, 216, 110, 8, 3, 216, 112, 8, 3, 216, 111, 8, 3, 217, 47, 8, 3, 217, - 34, 8, 3, 217, 106, 8, 3, 217, 55, 8, 3, 215, 103, 8, 3, 215, 102, 8, 3, - 215, 105, 8, 3, 215, 104, 8, 3, 216, 6, 8, 3, 216, 2, 8, 3, 112, 8, 3, - 216, 14, 8, 3, 216, 214, 8, 3, 217, 23, 8, 3, 216, 238, 8, 3, 215, 88, 8, - 3, 215, 83, 8, 3, 215, 119, 8, 3, 215, 101, 8, 3, 215, 89, 8, 3, 215, 99, - 8, 3, 248, 115, 8, 3, 248, 114, 8, 3, 248, 120, 8, 3, 248, 116, 8, 3, - 248, 117, 8, 3, 248, 119, 8, 3, 248, 118, 8, 3, 248, 136, 8, 3, 248, 135, - 8, 3, 248, 143, 8, 3, 248, 137, 8, 3, 248, 105, 8, 3, 248, 107, 8, 3, - 248, 106, 8, 3, 248, 110, 8, 3, 248, 109, 8, 3, 248, 113, 8, 3, 248, 111, - 8, 3, 248, 128, 8, 3, 248, 131, 8, 3, 248, 129, 8, 3, 248, 101, 8, 3, - 248, 100, 8, 3, 248, 108, 8, 3, 248, 104, 8, 3, 248, 102, 8, 3, 248, 103, - 8, 3, 229, 131, 8, 3, 229, 130, 8, 3, 229, 138, 8, 3, 229, 133, 8, 3, - 229, 134, 8, 3, 229, 135, 8, 3, 229, 147, 8, 3, 229, 146, 8, 3, 229, 153, - 8, 3, 229, 148, 8, 3, 229, 123, 8, 3, 229, 122, 8, 3, 229, 129, 8, 3, - 229, 124, 8, 3, 229, 139, 8, 3, 229, 145, 8, 3, 229, 143, 8, 3, 229, 115, - 8, 3, 229, 114, 8, 3, 229, 120, 8, 3, 229, 118, 8, 3, 229, 116, 8, 3, - 229, 117, 8, 3, 241, 84, 8, 3, 241, 83, 8, 3, 241, 90, 8, 3, 241, 85, 8, - 3, 241, 87, 8, 3, 241, 86, 8, 3, 241, 89, 8, 3, 241, 88, 8, 3, 241, 95, - 8, 3, 241, 94, 8, 3, 241, 97, 8, 3, 241, 96, 8, 3, 241, 78, 8, 3, 241, - 79, 8, 3, 241, 81, 8, 3, 241, 80, 8, 3, 241, 82, 8, 3, 241, 91, 8, 3, - 241, 93, 8, 3, 241, 92, 8, 3, 241, 77, 8, 3, 228, 194, 8, 3, 228, 192, 8, - 3, 228, 238, 8, 3, 228, 197, 8, 3, 228, 220, 8, 3, 228, 234, 8, 3, 228, - 233, 8, 3, 229, 188, 8, 3, 198, 8, 3, 229, 202, 8, 3, 227, 190, 8, 3, - 227, 192, 8, 3, 227, 191, 8, 3, 228, 56, 8, 3, 228, 43, 8, 3, 228, 79, 8, - 3, 228, 65, 8, 3, 229, 88, 8, 3, 229, 112, 8, 3, 229, 99, 8, 3, 227, 185, - 8, 3, 227, 181, 8, 3, 227, 242, 8, 3, 227, 189, 8, 3, 227, 187, 8, 3, - 227, 188, 8, 3, 241, 148, 8, 3, 241, 147, 8, 3, 241, 153, 8, 3, 241, 149, - 8, 3, 241, 150, 8, 3, 241, 152, 8, 3, 241, 151, 8, 3, 241, 158, 8, 3, - 241, 157, 8, 3, 241, 160, 8, 3, 241, 159, 8, 3, 241, 140, 8, 3, 241, 142, - 8, 3, 241, 141, 8, 3, 241, 144, 8, 3, 241, 146, 8, 3, 241, 145, 8, 3, - 241, 154, 8, 3, 241, 156, 8, 3, 241, 155, 8, 3, 241, 136, 8, 3, 241, 135, - 8, 3, 241, 143, 8, 3, 241, 139, 8, 3, 241, 137, 8, 3, 241, 138, 8, 3, - 241, 130, 8, 3, 241, 129, 8, 3, 241, 134, 8, 3, 241, 133, 8, 3, 241, 131, - 8, 3, 241, 132, 8, 3, 232, 201, 8, 3, 232, 195, 8, 3, 232, 247, 8, 3, - 232, 208, 8, 3, 232, 239, 8, 3, 232, 238, 8, 3, 232, 242, 8, 3, 232, 240, - 8, 3, 233, 85, 8, 3, 233, 75, 8, 3, 233, 141, 8, 3, 233, 94, 8, 3, 232, - 84, 8, 3, 232, 83, 8, 3, 232, 86, 8, 3, 232, 85, 8, 3, 232, 122, 8, 3, - 232, 112, 8, 3, 232, 162, 8, 3, 232, 126, 8, 3, 233, 8, 8, 3, 233, 64, 8, - 3, 233, 23, 8, 3, 232, 79, 8, 3, 232, 77, 8, 3, 232, 103, 8, 3, 232, 82, - 8, 3, 232, 80, 8, 3, 232, 81, 8, 3, 232, 59, 8, 3, 232, 58, 8, 3, 232, - 67, 8, 3, 232, 62, 8, 3, 232, 60, 8, 3, 232, 61, 8, 3, 242, 196, 8, 3, - 242, 195, 8, 3, 242, 221, 8, 3, 242, 206, 8, 3, 242, 213, 8, 3, 242, 212, - 8, 3, 242, 215, 8, 3, 242, 214, 8, 3, 243, 96, 8, 3, 243, 91, 8, 3, 243, - 142, 8, 3, 243, 106, 8, 3, 242, 98, 8, 3, 242, 97, 8, 3, 242, 100, 8, 3, - 242, 99, 8, 3, 242, 161, 8, 3, 242, 159, 8, 3, 242, 181, 8, 3, 242, 169, - 8, 3, 243, 40, 8, 3, 243, 38, 8, 3, 243, 69, 8, 3, 243, 51, 8, 3, 242, - 88, 8, 3, 242, 87, 8, 3, 242, 120, 8, 3, 242, 96, 8, 3, 242, 89, 8, 3, - 242, 95, 8, 3, 234, 67, 8, 3, 234, 66, 8, 3, 234, 98, 8, 3, 234, 81, 8, - 3, 234, 91, 8, 3, 234, 94, 8, 3, 234, 92, 8, 3, 234, 208, 8, 3, 234, 196, - 8, 3, 176, 8, 3, 234, 234, 8, 3, 233, 206, 8, 3, 233, 211, 8, 3, 233, - 208, 8, 3, 234, 6, 8, 3, 234, 2, 8, 3, 234, 34, 8, 3, 234, 13, 8, 3, 234, - 162, 8, 3, 234, 146, 8, 3, 234, 188, 8, 3, 234, 165, 8, 3, 233, 195, 8, - 3, 233, 192, 8, 3, 233, 223, 8, 3, 233, 205, 8, 3, 233, 198, 8, 3, 233, - 202, 8, 3, 243, 22, 8, 3, 243, 21, 8, 3, 243, 26, 8, 3, 243, 23, 8, 3, - 243, 25, 8, 3, 243, 24, 8, 3, 243, 33, 8, 3, 243, 32, 8, 3, 243, 36, 8, - 3, 243, 34, 8, 3, 243, 13, 8, 3, 243, 12, 8, 3, 243, 15, 8, 3, 243, 14, - 8, 3, 243, 18, 8, 3, 243, 17, 8, 3, 243, 20, 8, 3, 243, 19, 8, 3, 243, - 28, 8, 3, 243, 27, 8, 3, 243, 31, 8, 3, 243, 29, 8, 3, 243, 8, 8, 3, 243, - 7, 8, 3, 243, 16, 8, 3, 243, 11, 8, 3, 243, 9, 8, 3, 243, 10, 8, 3, 230, - 254, 8, 3, 230, 255, 8, 3, 231, 17, 8, 3, 231, 16, 8, 3, 231, 19, 8, 3, - 231, 18, 8, 3, 230, 245, 8, 3, 230, 247, 8, 3, 230, 246, 8, 3, 230, 250, - 8, 3, 230, 249, 8, 3, 230, 252, 8, 3, 230, 251, 8, 3, 231, 0, 8, 3, 231, - 2, 8, 3, 231, 1, 8, 3, 230, 241, 8, 3, 230, 240, 8, 3, 230, 248, 8, 3, - 230, 244, 8, 3, 230, 242, 8, 3, 230, 243, 8, 3, 240, 187, 8, 3, 240, 186, - 8, 3, 240, 193, 8, 3, 240, 188, 8, 3, 240, 190, 8, 3, 240, 189, 8, 3, - 240, 192, 8, 3, 240, 191, 8, 3, 240, 198, 8, 3, 240, 197, 8, 3, 240, 200, - 8, 3, 240, 199, 8, 3, 240, 179, 8, 3, 240, 178, 8, 3, 240, 181, 8, 3, - 240, 180, 8, 3, 240, 183, 8, 3, 240, 182, 8, 3, 240, 185, 8, 3, 240, 184, - 8, 3, 240, 194, 8, 3, 240, 196, 8, 3, 240, 195, 8, 3, 229, 29, 8, 3, 229, - 31, 8, 3, 229, 30, 8, 3, 229, 72, 8, 3, 229, 70, 8, 3, 229, 82, 8, 3, - 229, 75, 8, 3, 228, 248, 8, 3, 228, 247, 8, 3, 228, 249, 8, 3, 229, 1, 8, - 3, 228, 254, 8, 3, 229, 9, 8, 3, 229, 3, 8, 3, 229, 63, 8, 3, 229, 69, 8, - 3, 229, 65, 8, 3, 241, 163, 8, 3, 241, 173, 8, 3, 241, 182, 8, 3, 242, 2, - 8, 3, 241, 250, 8, 3, 162, 8, 3, 242, 13, 8, 3, 240, 213, 8, 3, 240, 212, - 8, 3, 240, 215, 8, 3, 240, 214, 8, 3, 240, 249, 8, 3, 240, 240, 8, 3, - 241, 75, 8, 3, 241, 54, 8, 3, 241, 201, 8, 3, 241, 245, 8, 3, 241, 213, - 8, 3, 212, 43, 8, 3, 212, 28, 8, 3, 212, 65, 8, 3, 212, 51, 8, 3, 211, - 185, 8, 3, 211, 187, 8, 3, 211, 186, 8, 3, 211, 203, 8, 3, 211, 227, 8, - 3, 211, 210, 8, 3, 212, 5, 8, 3, 212, 22, 8, 3, 212, 10, 8, 3, 210, 30, - 8, 3, 210, 29, 8, 3, 210, 44, 8, 3, 210, 32, 8, 3, 210, 37, 8, 3, 210, - 39, 8, 3, 210, 38, 8, 3, 210, 102, 8, 3, 210, 99, 8, 3, 210, 116, 8, 3, - 210, 105, 8, 3, 210, 6, 8, 3, 210, 8, 8, 3, 210, 7, 8, 3, 210, 19, 8, 3, - 210, 18, 8, 3, 210, 23, 8, 3, 210, 20, 8, 3, 210, 84, 8, 3, 210, 94, 8, - 3, 210, 88, 8, 3, 210, 2, 8, 3, 210, 1, 8, 3, 210, 13, 8, 3, 210, 5, 8, - 3, 210, 3, 8, 3, 210, 4, 8, 3, 209, 245, 8, 3, 209, 244, 8, 3, 209, 250, - 8, 3, 209, 248, 8, 3, 209, 246, 8, 3, 209, 247, 8, 3, 250, 36, 8, 3, 250, - 32, 8, 3, 250, 59, 8, 3, 250, 45, 8, 3, 250, 56, 8, 3, 250, 50, 8, 3, - 250, 58, 8, 3, 250, 57, 8, 3, 250, 232, 8, 3, 250, 225, 8, 3, 251, 41, 8, - 3, 251, 3, 8, 3, 249, 112, 8, 3, 249, 114, 8, 3, 249, 113, 8, 3, 249, - 161, 8, 3, 249, 152, 8, 3, 249, 246, 8, 3, 249, 177, 8, 3, 250, 168, 8, - 3, 250, 198, 8, 3, 250, 173, 8, 3, 249, 92, 8, 3, 249, 90, 8, 3, 249, - 120, 8, 3, 249, 110, 8, 3, 249, 97, 8, 3, 249, 109, 8, 3, 249, 71, 8, 3, - 249, 70, 8, 3, 249, 81, 8, 3, 249, 77, 8, 3, 249, 72, 8, 3, 249, 74, 8, - 3, 209, 228, 8, 3, 209, 227, 8, 3, 209, 234, 8, 3, 209, 229, 8, 3, 209, - 231, 8, 3, 209, 230, 8, 3, 209, 233, 8, 3, 209, 232, 8, 3, 209, 240, 8, - 3, 209, 239, 8, 3, 209, 243, 8, 3, 209, 241, 8, 3, 209, 224, 8, 3, 209, - 226, 8, 3, 209, 225, 8, 3, 209, 235, 8, 3, 209, 238, 8, 3, 209, 236, 8, - 3, 209, 217, 8, 3, 209, 221, 8, 3, 209, 220, 8, 3, 209, 218, 8, 3, 209, - 219, 8, 3, 209, 211, 8, 3, 209, 210, 8, 3, 209, 216, 8, 3, 209, 214, 8, - 3, 209, 212, 8, 3, 209, 213, 8, 3, 227, 108, 8, 3, 227, 107, 8, 3, 227, - 113, 8, 3, 227, 109, 8, 3, 227, 110, 8, 3, 227, 112, 8, 3, 227, 111, 8, - 3, 227, 118, 8, 3, 227, 117, 8, 3, 227, 121, 8, 3, 227, 120, 8, 3, 227, - 101, 8, 3, 227, 102, 8, 3, 227, 105, 8, 3, 227, 106, 8, 3, 227, 114, 8, - 3, 227, 116, 8, 3, 227, 96, 8, 3, 227, 104, 8, 3, 227, 100, 8, 3, 227, - 97, 8, 3, 227, 98, 8, 3, 227, 91, 8, 3, 227, 90, 8, 3, 227, 95, 8, 3, - 227, 94, 8, 3, 227, 92, 8, 3, 227, 93, 8, 3, 219, 129, 8, 3, 195, 8, 3, - 219, 193, 8, 3, 219, 132, 8, 3, 219, 185, 8, 3, 219, 188, 8, 3, 219, 186, - 8, 3, 221, 228, 8, 3, 221, 216, 8, 3, 206, 8, 3, 221, 236, 8, 3, 218, 29, - 8, 3, 218, 31, 8, 3, 218, 30, 8, 3, 219, 36, 8, 3, 219, 25, 8, 3, 219, - 60, 8, 3, 219, 40, 8, 3, 220, 116, 8, 3, 221, 183, 8, 3, 220, 141, 8, 3, - 218, 6, 8, 3, 218, 4, 8, 3, 218, 84, 8, 3, 218, 28, 8, 3, 218, 10, 8, 3, - 218, 18, 8, 3, 217, 167, 8, 3, 217, 166, 8, 3, 217, 233, 8, 3, 217, 174, - 8, 3, 217, 169, 8, 3, 217, 173, 8, 3, 218, 188, 8, 3, 218, 187, 8, 3, - 218, 194, 8, 3, 218, 189, 8, 3, 218, 191, 8, 3, 218, 193, 8, 3, 218, 192, - 8, 3, 218, 202, 8, 3, 218, 200, 8, 3, 218, 225, 8, 3, 218, 203, 8, 3, - 218, 183, 8, 3, 218, 182, 8, 3, 218, 186, 8, 3, 218, 184, 8, 3, 218, 196, - 8, 3, 218, 199, 8, 3, 218, 197, 8, 3, 218, 179, 8, 3, 218, 177, 8, 3, - 218, 181, 8, 3, 218, 180, 8, 3, 218, 172, 8, 3, 218, 171, 8, 3, 218, 176, - 8, 3, 218, 175, 8, 3, 218, 173, 8, 3, 218, 174, 8, 3, 210, 77, 8, 3, 210, - 76, 8, 3, 210, 82, 8, 3, 210, 79, 8, 3, 210, 59, 8, 3, 210, 61, 8, 3, - 210, 60, 8, 3, 210, 64, 8, 3, 210, 63, 8, 3, 210, 67, 8, 3, 210, 65, 8, - 3, 210, 71, 8, 3, 210, 70, 8, 3, 210, 74, 8, 3, 210, 72, 8, 3, 210, 55, - 8, 3, 210, 54, 8, 3, 210, 62, 8, 3, 210, 58, 8, 3, 210, 56, 8, 3, 210, - 57, 8, 3, 210, 47, 8, 3, 210, 46, 8, 3, 210, 51, 8, 3, 210, 50, 8, 3, - 210, 48, 8, 3, 210, 49, 8, 3, 250, 144, 8, 3, 250, 141, 8, 3, 250, 165, - 8, 3, 250, 152, 8, 3, 250, 73, 8, 3, 250, 72, 8, 3, 250, 75, 8, 3, 250, - 74, 8, 3, 250, 87, 8, 3, 250, 86, 8, 3, 250, 94, 8, 3, 250, 89, 8, 3, - 250, 123, 8, 3, 250, 121, 8, 3, 250, 139, 8, 3, 250, 129, 8, 3, 250, 67, - 8, 3, 250, 77, 8, 3, 250, 71, 8, 3, 250, 68, 8, 3, 250, 70, 8, 3, 250, - 61, 8, 3, 250, 60, 8, 3, 250, 65, 8, 3, 250, 64, 8, 3, 250, 62, 8, 3, - 250, 63, 8, 3, 222, 177, 8, 3, 222, 181, 8, 3, 222, 160, 8, 3, 222, 161, - 8, 3, 222, 164, 8, 3, 222, 163, 8, 3, 222, 167, 8, 3, 222, 165, 8, 3, - 222, 171, 8, 3, 222, 170, 8, 3, 222, 176, 8, 3, 222, 172, 8, 3, 222, 156, - 8, 3, 222, 154, 8, 3, 222, 162, 8, 3, 222, 159, 8, 3, 222, 157, 8, 3, - 222, 158, 8, 3, 222, 149, 8, 3, 222, 148, 8, 3, 222, 153, 8, 3, 222, 152, - 8, 3, 222, 150, 8, 3, 222, 151, 8, 3, 228, 39, 8, 3, 228, 38, 8, 3, 228, - 41, 8, 3, 228, 40, 8, 3, 228, 31, 8, 3, 228, 33, 8, 3, 228, 32, 8, 3, - 228, 35, 8, 3, 228, 34, 8, 3, 228, 37, 8, 3, 228, 36, 8, 3, 228, 26, 8, - 3, 228, 25, 8, 3, 228, 30, 8, 3, 228, 29, 8, 3, 228, 27, 8, 3, 228, 28, - 8, 3, 228, 20, 8, 3, 228, 19, 8, 3, 228, 24, 8, 3, 228, 23, 8, 3, 228, - 21, 8, 3, 228, 22, 8, 3, 220, 74, 8, 3, 220, 69, 8, 3, 220, 104, 8, 3, - 220, 85, 8, 3, 219, 217, 8, 3, 219, 219, 8, 3, 219, 218, 8, 3, 219, 238, - 8, 3, 219, 235, 8, 3, 220, 9, 8, 3, 220, 0, 8, 3, 220, 44, 8, 3, 220, 37, - 8, 3, 220, 65, 8, 3, 220, 52, 8, 3, 219, 213, 8, 3, 219, 211, 8, 3, 219, - 227, 8, 3, 219, 216, 8, 3, 219, 214, 8, 3, 219, 215, 8, 3, 219, 196, 8, - 3, 219, 195, 8, 3, 219, 202, 8, 3, 219, 199, 8, 3, 219, 197, 8, 3, 219, - 198, 8, 3, 223, 144, 8, 3, 223, 138, 8, 3, 205, 8, 3, 223, 150, 8, 3, - 222, 122, 8, 3, 222, 124, 8, 3, 222, 123, 8, 3, 222, 190, 8, 3, 222, 183, - 8, 3, 222, 213, 8, 3, 222, 194, 8, 3, 223, 46, 8, 3, 223, 131, 8, 3, 223, - 84, 8, 3, 222, 115, 8, 3, 222, 112, 8, 3, 222, 142, 8, 3, 222, 121, 8, 3, - 222, 117, 8, 3, 222, 118, 8, 3, 222, 97, 8, 3, 222, 96, 8, 3, 222, 102, - 8, 3, 222, 100, 8, 3, 222, 98, 8, 3, 222, 99, 8, 3, 235, 104, 8, 3, 235, - 103, 8, 3, 235, 114, 8, 3, 235, 105, 8, 3, 235, 110, 8, 3, 235, 109, 8, - 3, 235, 112, 8, 3, 235, 111, 8, 3, 235, 47, 8, 3, 235, 46, 8, 3, 235, 49, - 8, 3, 235, 48, 8, 3, 235, 62, 8, 3, 235, 60, 8, 3, 235, 74, 8, 3, 235, - 64, 8, 3, 235, 40, 8, 3, 235, 38, 8, 3, 235, 57, 8, 3, 235, 45, 8, 3, - 235, 42, 8, 3, 235, 43, 8, 3, 235, 32, 8, 3, 235, 31, 8, 3, 235, 36, 8, - 3, 235, 35, 8, 3, 235, 33, 8, 3, 235, 34, 8, 3, 224, 49, 8, 3, 224, 47, - 8, 3, 224, 56, 8, 3, 224, 50, 8, 3, 224, 53, 8, 3, 224, 52, 8, 3, 224, - 55, 8, 3, 224, 54, 8, 3, 224, 2, 8, 3, 223, 255, 8, 3, 224, 4, 8, 3, 224, - 3, 8, 3, 224, 36, 8, 3, 224, 35, 8, 3, 224, 45, 8, 3, 224, 39, 8, 3, 223, - 250, 8, 3, 223, 246, 8, 3, 224, 33, 8, 3, 223, 254, 8, 3, 223, 252, 8, 3, - 223, 253, 8, 3, 223, 230, 8, 3, 223, 228, 8, 3, 223, 240, 8, 3, 223, 233, - 8, 3, 223, 231, 8, 3, 223, 232, 8, 3, 235, 93, 8, 3, 235, 92, 8, 3, 235, - 99, 8, 3, 235, 94, 8, 3, 235, 96, 8, 3, 235, 95, 8, 3, 235, 98, 8, 3, - 235, 97, 8, 3, 235, 84, 8, 3, 235, 86, 8, 3, 235, 85, 8, 3, 235, 89, 8, - 3, 235, 88, 8, 3, 235, 91, 8, 3, 235, 90, 8, 3, 235, 80, 8, 3, 235, 79, - 8, 3, 235, 87, 8, 3, 235, 83, 8, 3, 235, 81, 8, 3, 235, 82, 8, 3, 235, - 76, 8, 3, 235, 75, 8, 3, 235, 78, 8, 3, 235, 77, 8, 3, 228, 167, 8, 3, - 228, 166, 8, 3, 228, 174, 8, 3, 228, 168, 8, 3, 228, 170, 8, 3, 228, 169, - 8, 3, 228, 173, 8, 3, 228, 171, 8, 3, 228, 156, 8, 3, 228, 157, 8, 3, - 228, 162, 8, 3, 228, 161, 8, 3, 228, 165, 8, 3, 228, 163, 8, 3, 228, 151, - 8, 3, 228, 160, 8, 3, 228, 155, 8, 3, 228, 152, 8, 3, 228, 153, 8, 3, - 228, 146, 8, 3, 228, 145, 8, 3, 228, 150, 8, 3, 228, 149, 8, 3, 228, 147, - 8, 3, 228, 148, 8, 3, 227, 141, 8, 3, 227, 140, 8, 3, 227, 152, 8, 3, - 227, 145, 8, 3, 227, 149, 8, 3, 227, 148, 8, 3, 227, 151, 8, 3, 227, 150, - 8, 3, 227, 128, 8, 3, 227, 130, 8, 3, 227, 129, 8, 3, 227, 134, 8, 3, - 227, 133, 8, 3, 227, 138, 8, 3, 227, 135, 8, 3, 227, 126, 8, 3, 227, 124, - 8, 3, 227, 132, 8, 3, 227, 127, 8, 3, 211, 150, 8, 3, 211, 149, 8, 3, - 211, 157, 8, 3, 211, 152, 8, 3, 211, 154, 8, 3, 211, 153, 8, 3, 211, 156, - 8, 3, 211, 155, 8, 3, 211, 139, 8, 3, 211, 140, 8, 3, 211, 144, 8, 3, - 211, 143, 8, 3, 211, 148, 8, 3, 211, 146, 8, 3, 211, 121, 8, 3, 211, 119, - 8, 3, 211, 131, 8, 3, 211, 124, 8, 3, 211, 122, 8, 3, 211, 123, 8, 3, - 210, 250, 8, 3, 210, 248, 8, 3, 211, 8, 8, 3, 210, 251, 8, 3, 211, 2, 8, - 3, 211, 1, 8, 3, 211, 5, 8, 3, 211, 3, 8, 3, 210, 191, 8, 3, 210, 190, 8, - 3, 210, 194, 8, 3, 210, 192, 8, 3, 210, 224, 8, 3, 210, 221, 8, 3, 210, - 244, 8, 3, 210, 228, 8, 3, 210, 182, 8, 3, 210, 178, 8, 3, 210, 212, 8, - 3, 210, 189, 8, 3, 210, 185, 8, 3, 210, 186, 8, 3, 210, 162, 8, 3, 210, - 161, 8, 3, 210, 169, 8, 3, 210, 165, 8, 3, 210, 163, 8, 3, 210, 164, 8, - 34, 224, 36, 8, 34, 232, 247, 8, 34, 234, 67, 8, 34, 227, 145, 8, 34, - 249, 77, 8, 34, 218, 194, 8, 34, 243, 19, 8, 34, 243, 51, 8, 34, 230, - 235, 8, 34, 240, 187, 8, 34, 232, 61, 8, 34, 252, 91, 8, 34, 230, 131, 8, - 34, 210, 244, 8, 34, 224, 124, 8, 34, 240, 181, 8, 34, 217, 47, 8, 34, - 243, 142, 8, 34, 210, 5, 8, 34, 249, 71, 8, 34, 248, 103, 8, 34, 251, - 106, 8, 34, 243, 15, 8, 34, 227, 135, 8, 34, 215, 119, 8, 34, 226, 179, - 8, 34, 235, 80, 8, 34, 210, 19, 8, 34, 224, 103, 8, 34, 241, 115, 8, 34, - 210, 250, 8, 34, 212, 112, 8, 34, 219, 202, 8, 34, 213, 244, 8, 34, 210, - 116, 8, 34, 235, 74, 8, 34, 227, 100, 8, 34, 235, 78, 8, 34, 242, 161, 8, - 34, 235, 98, 8, 34, 211, 227, 8, 34, 246, 86, 8, 34, 219, 215, 8, 34, - 232, 242, 8, 34, 249, 81, 8, 34, 249, 113, 8, 34, 250, 45, 8, 34, 240, - 184, 8, 34, 220, 74, 8, 34, 210, 4, 8, 34, 220, 0, 8, 34, 250, 139, 8, - 34, 209, 231, 8, 34, 229, 178, 8, 34, 234, 188, 232, 202, 1, 252, 199, - 232, 202, 1, 191, 232, 202, 1, 225, 150, 232, 202, 1, 248, 229, 232, 202, - 1, 217, 106, 232, 202, 1, 216, 209, 232, 202, 1, 243, 142, 232, 202, 1, - 176, 232, 202, 1, 234, 138, 232, 202, 1, 235, 147, 232, 202, 1, 251, 41, - 232, 202, 1, 250, 165, 232, 202, 1, 246, 46, 232, 202, 1, 215, 184, 232, - 202, 1, 215, 176, 232, 202, 1, 186, 232, 202, 1, 198, 232, 202, 1, 233, - 141, 232, 202, 1, 206, 232, 202, 1, 210, 82, 232, 202, 1, 210, 116, 232, - 202, 1, 229, 82, 232, 202, 1, 162, 232, 202, 1, 211, 165, 232, 202, 1, - 241, 196, 232, 202, 1, 244, 204, 232, 202, 1, 212, 65, 232, 202, 1, 220, - 104, 232, 202, 1, 192, 232, 202, 1, 243, 0, 232, 202, 1, 61, 232, 202, 1, - 254, 252, 232, 202, 1, 76, 232, 202, 1, 245, 63, 232, 202, 1, 74, 232, - 202, 1, 78, 232, 202, 1, 69, 232, 202, 1, 214, 214, 232, 202, 1, 214, - 208, 232, 202, 1, 226, 238, 232, 202, 1, 138, 230, 37, 216, 118, 232, - 202, 1, 138, 229, 234, 225, 19, 232, 202, 1, 138, 230, 37, 249, 80, 232, - 202, 1, 138, 230, 37, 251, 213, 232, 202, 1, 138, 230, 37, 198, 232, 202, - 1, 138, 230, 37, 235, 121, 232, 202, 224, 144, 249, 227, 232, 202, 224, - 144, 243, 236, 218, 131, 41, 3, 245, 217, 41, 3, 245, 213, 41, 3, 241, - 227, 41, 3, 212, 17, 41, 3, 212, 16, 41, 3, 225, 214, 41, 3, 252, 21, 41, - 3, 252, 74, 41, 3, 231, 121, 41, 3, 233, 253, 41, 3, 231, 11, 41, 3, 243, - 82, 41, 3, 244, 155, 41, 3, 213, 250, 41, 3, 217, 12, 41, 3, 216, 195, - 41, 3, 248, 24, 41, 3, 248, 21, 41, 3, 233, 56, 41, 3, 223, 111, 41, 3, - 248, 85, 41, 3, 229, 144, 41, 3, 221, 172, 41, 3, 220, 63, 41, 3, 210, - 92, 41, 3, 210, 73, 41, 3, 250, 190, 41, 3, 235, 130, 41, 3, 228, 181, - 41, 3, 211, 44, 41, 3, 234, 187, 41, 3, 229, 56, 41, 3, 243, 62, 41, 3, - 231, 85, 41, 3, 229, 108, 41, 3, 227, 159, 41, 3, 74, 41, 3, 236, 6, 41, - 3, 241, 187, 41, 3, 241, 167, 41, 3, 211, 250, 41, 3, 211, 241, 41, 3, - 225, 111, 41, 3, 252, 19, 41, 3, 252, 14, 41, 3, 231, 114, 41, 3, 233, - 250, 41, 3, 231, 8, 41, 3, 243, 78, 41, 3, 244, 129, 41, 3, 213, 176, 41, - 3, 216, 118, 41, 3, 216, 176, 41, 3, 248, 16, 41, 3, 248, 20, 41, 3, 232, - 247, 41, 3, 223, 38, 41, 3, 248, 11, 41, 3, 229, 138, 41, 3, 219, 193, - 41, 3, 220, 34, 41, 3, 210, 44, 41, 3, 210, 69, 41, 3, 250, 59, 41, 3, - 235, 114, 41, 3, 228, 174, 41, 3, 211, 8, 41, 3, 234, 98, 41, 3, 229, 48, - 41, 3, 242, 221, 41, 3, 230, 235, 41, 3, 228, 238, 41, 3, 227, 152, 41, - 3, 61, 41, 3, 254, 131, 41, 3, 229, 77, 41, 3, 162, 41, 3, 242, 25, 41, - 3, 212, 65, 41, 3, 212, 55, 41, 3, 191, 41, 3, 252, 26, 41, 3, 252, 199, - 41, 3, 231, 129, 41, 3, 234, 1, 41, 3, 234, 0, 41, 3, 231, 15, 41, 3, - 243, 86, 41, 3, 244, 204, 41, 3, 214, 27, 41, 3, 217, 106, 41, 3, 216, - 209, 41, 3, 248, 33, 41, 3, 248, 23, 41, 3, 233, 141, 41, 3, 205, 41, 3, - 248, 229, 41, 3, 229, 153, 41, 3, 206, 41, 3, 220, 104, 41, 3, 210, 116, - 41, 3, 210, 82, 41, 3, 251, 41, 41, 3, 235, 147, 41, 3, 228, 190, 41, 3, - 192, 41, 3, 176, 41, 3, 234, 240, 41, 3, 229, 61, 41, 3, 243, 142, 41, 3, - 186, 41, 3, 198, 41, 3, 227, 169, 41, 3, 226, 187, 41, 3, 226, 183, 41, - 3, 241, 60, 41, 3, 211, 215, 41, 3, 211, 211, 41, 3, 224, 252, 41, 3, - 252, 17, 41, 3, 251, 201, 41, 3, 231, 109, 41, 3, 233, 248, 41, 3, 231, - 4, 41, 3, 243, 74, 41, 3, 244, 42, 41, 3, 213, 127, 41, 3, 216, 18, 41, - 3, 216, 154, 41, 3, 248, 14, 41, 3, 248, 18, 41, 3, 232, 133, 41, 3, 222, - 199, 41, 3, 247, 133, 41, 3, 229, 125, 41, 3, 219, 42, 41, 3, 220, 3, 41, - 3, 210, 21, 41, 3, 210, 66, 41, 3, 249, 182, 41, 3, 235, 65, 41, 3, 228, - 164, 41, 3, 210, 229, 41, 3, 234, 16, 41, 3, 229, 46, 41, 3, 242, 171, - 41, 3, 230, 137, 41, 3, 228, 69, 41, 3, 227, 136, 41, 3, 69, 41, 3, 214, - 190, 41, 3, 240, 229, 41, 3, 240, 219, 41, 3, 211, 195, 41, 3, 211, 189, - 41, 3, 224, 153, 41, 3, 252, 16, 41, 3, 251, 133, 41, 3, 231, 108, 41, 3, - 233, 246, 41, 3, 231, 3, 41, 3, 243, 73, 41, 3, 243, 241, 41, 3, 212, - 116, 41, 3, 215, 119, 41, 3, 216, 137, 41, 3, 248, 12, 41, 3, 248, 17, - 41, 3, 232, 103, 41, 3, 222, 142, 41, 3, 246, 86, 41, 3, 229, 120, 41, 3, - 218, 84, 41, 3, 219, 227, 41, 3, 210, 13, 41, 3, 210, 62, 41, 3, 249, - 120, 41, 3, 235, 57, 41, 3, 228, 160, 41, 3, 210, 212, 41, 3, 233, 223, - 41, 3, 229, 45, 41, 3, 242, 120, 41, 3, 230, 107, 41, 3, 227, 242, 41, 3, - 227, 132, 41, 3, 78, 41, 3, 226, 200, 41, 3, 229, 5, 41, 3, 241, 75, 41, - 3, 241, 63, 41, 3, 211, 227, 41, 3, 211, 216, 41, 3, 225, 19, 41, 3, 252, - 18, 41, 3, 251, 213, 41, 3, 231, 110, 41, 3, 233, 249, 41, 3, 231, 6, 41, - 3, 243, 76, 41, 3, 243, 75, 41, 3, 244, 51, 41, 3, 213, 138, 41, 3, 112, - 41, 3, 216, 157, 41, 3, 248, 15, 41, 3, 248, 19, 41, 3, 232, 162, 41, 3, - 222, 213, 41, 3, 247, 153, 41, 3, 229, 129, 41, 3, 219, 60, 41, 3, 220, - 9, 41, 3, 210, 23, 41, 3, 210, 67, 41, 3, 249, 246, 41, 3, 235, 74, 41, - 3, 228, 165, 41, 3, 210, 244, 41, 3, 234, 34, 41, 3, 229, 47, 41, 3, 242, - 181, 41, 3, 230, 166, 41, 3, 228, 79, 41, 3, 227, 138, 41, 3, 76, 41, 3, - 245, 158, 41, 3, 229, 66, 41, 3, 241, 245, 41, 3, 241, 216, 41, 3, 212, - 22, 41, 3, 212, 12, 41, 3, 225, 224, 41, 3, 252, 22, 41, 3, 252, 83, 41, - 3, 231, 122, 41, 3, 233, 254, 41, 3, 233, 252, 41, 3, 231, 12, 41, 3, - 243, 83, 41, 3, 243, 81, 41, 3, 244, 162, 41, 3, 213, 255, 41, 3, 217, - 23, 41, 3, 216, 196, 41, 3, 248, 25, 41, 3, 248, 22, 41, 3, 233, 64, 41, - 3, 223, 131, 41, 3, 248, 98, 41, 3, 229, 145, 41, 3, 221, 183, 41, 3, - 220, 65, 41, 3, 210, 94, 41, 3, 210, 74, 41, 3, 250, 198, 41, 3, 235, - 132, 41, 3, 228, 183, 41, 3, 211, 47, 41, 3, 234, 188, 41, 3, 229, 57, - 41, 3, 229, 53, 41, 3, 243, 69, 41, 3, 243, 58, 41, 3, 231, 96, 41, 3, - 229, 112, 41, 3, 227, 160, 41, 3, 229, 84, 41, 3, 233, 28, 41, 249, 227, - 41, 243, 236, 218, 131, 41, 224, 16, 79, 41, 3, 229, 128, 244, 204, 41, - 3, 229, 128, 176, 41, 3, 229, 128, 219, 42, 41, 16, 244, 152, 41, 16, - 234, 186, 41, 16, 216, 82, 41, 16, 228, 213, 41, 16, 252, 155, 41, 16, - 244, 203, 41, 16, 217, 102, 41, 16, 248, 184, 41, 16, 247, 132, 41, 16, - 233, 212, 41, 16, 216, 22, 41, 16, 247, 152, 41, 16, 235, 66, 41, 21, - 210, 86, 41, 21, 111, 41, 21, 105, 41, 21, 158, 41, 21, 161, 41, 21, 190, - 41, 21, 195, 41, 21, 199, 41, 21, 196, 41, 21, 201, 41, 3, 229, 128, 186, - 41, 3, 229, 128, 247, 153, 33, 6, 1, 210, 90, 33, 4, 1, 210, 90, 33, 6, - 1, 246, 42, 33, 4, 1, 246, 42, 33, 6, 1, 223, 52, 246, 44, 33, 4, 1, 223, - 52, 246, 44, 33, 6, 1, 235, 192, 33, 4, 1, 235, 192, 33, 6, 1, 247, 169, - 33, 4, 1, 247, 169, 33, 6, 1, 230, 145, 214, 205, 33, 4, 1, 230, 145, - 214, 205, 33, 6, 1, 251, 144, 226, 205, 33, 4, 1, 251, 144, 226, 205, 33, - 6, 1, 229, 92, 211, 31, 33, 4, 1, 229, 92, 211, 31, 33, 6, 1, 211, 28, 2, - 252, 193, 211, 31, 33, 4, 1, 211, 28, 2, 252, 193, 211, 31, 33, 6, 1, - 235, 190, 211, 59, 33, 4, 1, 235, 190, 211, 59, 33, 6, 1, 223, 52, 210, - 212, 33, 4, 1, 223, 52, 210, 212, 33, 6, 1, 235, 190, 61, 33, 4, 1, 235, - 190, 61, 33, 6, 1, 250, 8, 232, 198, 210, 183, 33, 4, 1, 250, 8, 232, - 198, 210, 183, 33, 6, 1, 251, 222, 210, 183, 33, 4, 1, 251, 222, 210, - 183, 33, 6, 1, 235, 190, 250, 8, 232, 198, 210, 183, 33, 4, 1, 235, 190, - 250, 8, 232, 198, 210, 183, 33, 6, 1, 210, 246, 33, 4, 1, 210, 246, 33, - 6, 1, 223, 52, 215, 179, 33, 4, 1, 223, 52, 215, 179, 33, 6, 1, 219, 54, - 248, 98, 33, 4, 1, 219, 54, 248, 98, 33, 6, 1, 219, 54, 245, 182, 33, 4, - 1, 219, 54, 245, 182, 33, 6, 1, 219, 54, 245, 167, 33, 4, 1, 219, 54, - 245, 167, 33, 6, 1, 230, 149, 78, 33, 4, 1, 230, 149, 78, 33, 6, 1, 251, - 248, 78, 33, 4, 1, 251, 248, 78, 33, 6, 1, 52, 230, 149, 78, 33, 4, 1, - 52, 230, 149, 78, 33, 1, 230, 91, 78, 38, 33, 212, 100, 38, 33, 216, 249, - 230, 196, 50, 38, 33, 240, 218, 230, 196, 50, 38, 33, 216, 149, 230, 196, - 50, 219, 95, 253, 224, 38, 33, 1, 214, 202, 236, 67, 38, 33, 1, 74, 38, - 33, 1, 211, 8, 38, 33, 1, 69, 38, 33, 1, 242, 10, 50, 38, 33, 1, 211, 27, - 38, 33, 1, 219, 54, 50, 38, 33, 1, 226, 205, 38, 33, 234, 198, 38, 33, - 225, 231, 33, 234, 198, 33, 225, 231, 33, 6, 1, 246, 54, 33, 4, 1, 246, - 54, 33, 6, 1, 246, 35, 33, 4, 1, 246, 35, 33, 6, 1, 210, 52, 33, 4, 1, - 210, 52, 33, 6, 1, 250, 214, 33, 4, 1, 250, 214, 33, 6, 1, 246, 33, 33, - 4, 1, 246, 33, 33, 6, 1, 217, 24, 2, 230, 229, 103, 33, 4, 1, 217, 24, 2, - 230, 229, 103, 33, 6, 1, 215, 78, 33, 4, 1, 215, 78, 33, 6, 1, 215, 161, - 33, 4, 1, 215, 161, 33, 6, 1, 215, 165, 33, 4, 1, 215, 165, 33, 6, 1, - 217, 29, 33, 4, 1, 217, 29, 33, 6, 1, 240, 205, 33, 4, 1, 240, 205, 33, - 6, 1, 219, 208, 33, 4, 1, 219, 208, 38, 33, 1, 235, 190, 76, 20, 1, 61, - 20, 1, 176, 20, 1, 69, 20, 1, 233, 223, 20, 1, 245, 217, 20, 1, 223, 111, - 20, 1, 217, 87, 20, 1, 78, 20, 1, 227, 152, 20, 1, 74, 20, 1, 233, 141, - 20, 1, 191, 20, 1, 222, 242, 20, 1, 223, 32, 20, 1, 233, 55, 20, 1, 231, - 84, 20, 1, 217, 102, 20, 1, 229, 151, 20, 1, 228, 188, 20, 1, 194, 20, 1, - 218, 5, 20, 1, 230, 107, 20, 1, 220, 29, 20, 1, 219, 193, 20, 1, 220, 39, - 20, 1, 220, 125, 20, 1, 233, 161, 20, 1, 234, 162, 20, 1, 227, 213, 20, - 1, 227, 242, 20, 1, 228, 159, 20, 1, 210, 226, 20, 1, 219, 227, 20, 1, - 210, 187, 20, 1, 192, 20, 1, 228, 14, 20, 1, 234, 148, 20, 1, 225, 154, - 20, 1, 228, 181, 20, 1, 227, 251, 20, 1, 224, 147, 20, 1, 211, 192, 20, - 1, 225, 214, 20, 1, 244, 155, 20, 1, 222, 142, 20, 1, 232, 103, 20, 1, - 230, 235, 20, 1, 228, 238, 20, 1, 223, 54, 20, 1, 223, 174, 20, 1, 234, - 171, 20, 1, 229, 12, 20, 1, 229, 61, 20, 1, 229, 82, 20, 1, 220, 9, 20, - 1, 224, 150, 20, 1, 243, 241, 20, 1, 244, 45, 20, 1, 212, 65, 20, 1, 198, - 20, 1, 232, 247, 20, 1, 225, 111, 20, 1, 232, 125, 20, 1, 234, 34, 20, 1, - 231, 119, 20, 1, 223, 86, 20, 1, 231, 63, 20, 1, 186, 20, 1, 216, 118, - 20, 1, 234, 98, 20, 1, 230, 166, 20, 1, 231, 127, 20, 1, 216, 231, 20, 1, - 234, 1, 20, 1, 216, 248, 20, 1, 227, 243, 20, 1, 221, 253, 20, 1, 244, - 200, 20, 1, 234, 3, 20, 1, 234, 30, 20, 38, 164, 234, 11, 20, 38, 164, - 215, 111, 20, 228, 187, 20, 243, 236, 218, 131, 20, 249, 234, 20, 249, - 227, 20, 220, 152, 20, 224, 16, 79, 58, 1, 250, 104, 138, 210, 254, 225, - 64, 58, 1, 250, 104, 138, 211, 70, 225, 64, 58, 1, 250, 104, 138, 210, - 254, 220, 86, 58, 1, 250, 104, 138, 211, 70, 220, 86, 58, 1, 250, 104, - 138, 210, 254, 224, 33, 58, 1, 250, 104, 138, 211, 70, 224, 33, 58, 1, - 250, 104, 138, 210, 254, 222, 142, 58, 1, 250, 104, 138, 211, 70, 222, - 142, 58, 1, 245, 28, 246, 126, 138, 130, 58, 1, 125, 246, 126, 138, 130, - 58, 1, 230, 230, 246, 126, 138, 130, 58, 1, 121, 246, 126, 138, 130, 58, - 1, 245, 27, 246, 126, 138, 130, 58, 1, 245, 28, 246, 126, 233, 45, 138, - 130, 58, 1, 125, 246, 126, 233, 45, 138, 130, 58, 1, 230, 230, 246, 126, - 233, 45, 138, 130, 58, 1, 121, 246, 126, 233, 45, 138, 130, 58, 1, 245, - 27, 246, 126, 233, 45, 138, 130, 58, 1, 245, 28, 233, 45, 138, 130, 58, - 1, 125, 233, 45, 138, 130, 58, 1, 230, 230, 233, 45, 138, 130, 58, 1, - 121, 233, 45, 138, 130, 58, 1, 245, 27, 233, 45, 138, 130, 58, 1, 59, 67, - 130, 58, 1, 59, 219, 97, 58, 1, 59, 203, 130, 58, 1, 232, 114, 44, 249, - 169, 254, 117, 58, 1, 223, 160, 120, 75, 58, 1, 223, 160, 124, 75, 58, 1, - 223, 160, 245, 39, 79, 58, 1, 223, 160, 235, 200, 245, 39, 79, 58, 1, - 121, 235, 200, 245, 39, 79, 58, 1, 218, 113, 22, 125, 216, 31, 58, 1, - 218, 113, 22, 121, 216, 31, 7, 6, 1, 245, 207, 254, 179, 7, 4, 1, 245, - 207, 254, 179, 7, 6, 1, 245, 207, 254, 205, 7, 4, 1, 245, 207, 254, 205, - 7, 6, 1, 241, 214, 7, 4, 1, 241, 214, 7, 6, 1, 215, 40, 7, 4, 1, 215, 40, - 7, 6, 1, 215, 230, 7, 4, 1, 215, 230, 7, 6, 1, 249, 118, 7, 4, 1, 249, - 118, 7, 6, 1, 249, 119, 2, 249, 227, 7, 4, 1, 249, 119, 2, 249, 227, 7, - 1, 4, 6, 245, 14, 7, 1, 4, 6, 222, 93, 7, 6, 1, 255, 82, 7, 4, 1, 255, - 82, 7, 6, 1, 254, 81, 7, 4, 1, 254, 81, 7, 6, 1, 253, 200, 7, 4, 1, 253, - 200, 7, 6, 1, 253, 184, 7, 4, 1, 253, 184, 7, 6, 1, 253, 185, 2, 203, - 130, 7, 4, 1, 253, 185, 2, 203, 130, 7, 6, 1, 253, 175, 7, 4, 1, 253, - 175, 7, 6, 1, 223, 52, 251, 75, 2, 247, 128, 7, 4, 1, 223, 52, 251, 75, - 2, 247, 128, 7, 6, 1, 235, 30, 2, 91, 7, 4, 1, 235, 30, 2, 91, 7, 6, 1, - 235, 30, 2, 248, 7, 91, 7, 4, 1, 235, 30, 2, 248, 7, 91, 7, 6, 1, 235, - 30, 2, 218, 105, 22, 248, 7, 91, 7, 4, 1, 235, 30, 2, 218, 105, 22, 248, - 7, 91, 7, 6, 1, 251, 143, 156, 7, 4, 1, 251, 143, 156, 7, 6, 1, 233, 155, - 2, 125, 91, 7, 4, 1, 233, 155, 2, 125, 91, 7, 6, 1, 144, 2, 200, 218, - 105, 226, 124, 7, 4, 1, 144, 2, 200, 218, 105, 226, 124, 7, 6, 1, 144, 2, - 232, 129, 7, 4, 1, 144, 2, 232, 129, 7, 6, 1, 226, 187, 7, 4, 1, 226, - 187, 7, 6, 1, 226, 110, 2, 218, 105, 216, 140, 248, 47, 7, 4, 1, 226, - 110, 2, 218, 105, 216, 140, 248, 47, 7, 6, 1, 226, 110, 2, 244, 61, 7, 4, - 1, 226, 110, 2, 244, 61, 7, 6, 1, 226, 110, 2, 218, 231, 217, 78, 7, 4, - 1, 226, 110, 2, 218, 231, 217, 78, 7, 6, 1, 224, 100, 2, 218, 105, 216, - 140, 248, 47, 7, 4, 1, 224, 100, 2, 218, 105, 216, 140, 248, 47, 7, 6, 1, - 224, 100, 2, 248, 7, 91, 7, 4, 1, 224, 100, 2, 248, 7, 91, 7, 6, 1, 223, - 227, 222, 188, 7, 4, 1, 223, 227, 222, 188, 7, 6, 1, 222, 132, 222, 188, - 7, 4, 1, 222, 132, 222, 188, 7, 6, 1, 214, 106, 2, 248, 7, 91, 7, 4, 1, - 214, 106, 2, 248, 7, 91, 7, 6, 1, 212, 106, 7, 4, 1, 212, 106, 7, 6, 1, - 213, 145, 210, 159, 7, 4, 1, 213, 145, 210, 159, 7, 6, 1, 216, 153, 2, - 91, 7, 4, 1, 216, 153, 2, 91, 7, 6, 1, 216, 153, 2, 218, 105, 216, 140, - 248, 47, 7, 4, 1, 216, 153, 2, 218, 105, 216, 140, 248, 47, 7, 6, 1, 213, - 245, 7, 4, 1, 213, 245, 7, 6, 1, 245, 73, 7, 4, 1, 245, 73, 7, 6, 1, 235, - 178, 7, 4, 1, 235, 178, 7, 6, 1, 249, 215, 7, 4, 1, 249, 215, 58, 1, 214, - 133, 7, 4, 1, 246, 77, 7, 4, 1, 232, 89, 7, 4, 1, 230, 85, 7, 4, 1, 227, - 205, 7, 4, 1, 222, 131, 7, 1, 4, 6, 222, 131, 7, 4, 1, 215, 109, 7, 4, 1, - 214, 197, 7, 6, 1, 235, 220, 249, 68, 7, 4, 1, 235, 220, 249, 68, 7, 6, - 1, 235, 220, 245, 14, 7, 4, 1, 235, 220, 245, 14, 7, 6, 1, 235, 220, 243, - 209, 7, 6, 1, 215, 94, 235, 220, 243, 209, 7, 4, 1, 215, 94, 235, 220, - 243, 209, 7, 6, 1, 215, 94, 156, 7, 4, 1, 215, 94, 156, 7, 6, 1, 235, - 220, 153, 7, 4, 1, 235, 220, 153, 7, 6, 1, 235, 220, 222, 93, 7, 4, 1, - 235, 220, 222, 93, 7, 6, 1, 235, 220, 217, 153, 7, 4, 1, 235, 220, 217, - 153, 58, 1, 121, 250, 39, 255, 23, 58, 1, 249, 234, 58, 1, 219, 253, 245, - 106, 50, 7, 6, 1, 222, 1, 7, 4, 1, 222, 1, 7, 6, 1, 215, 94, 242, 67, 7, - 4, 1, 233, 155, 2, 223, 58, 241, 59, 22, 252, 49, 7, 6, 1, 230, 31, 2, - 248, 47, 7, 4, 1, 230, 31, 2, 248, 47, 7, 6, 1, 251, 75, 2, 130, 7, 4, 1, - 251, 75, 2, 130, 7, 6, 1, 243, 210, 2, 226, 252, 91, 7, 4, 1, 243, 210, - 2, 226, 252, 91, 7, 6, 1, 235, 30, 2, 226, 252, 91, 7, 4, 1, 235, 30, 2, - 226, 252, 91, 7, 6, 1, 230, 31, 2, 226, 252, 91, 7, 4, 1, 230, 31, 2, - 226, 252, 91, 7, 6, 1, 223, 227, 2, 226, 252, 91, 7, 4, 1, 223, 227, 2, - 226, 252, 91, 7, 6, 1, 222, 94, 2, 226, 252, 91, 7, 4, 1, 222, 94, 2, - 226, 252, 91, 7, 6, 1, 242, 68, 2, 103, 58, 1, 6, 242, 68, 2, 91, 58, 1, - 4, 27, 226, 238, 7, 1, 4, 6, 215, 94, 194, 7, 245, 111, 1, 223, 52, 245, - 14, 7, 245, 111, 1, 223, 52, 226, 109, 7, 245, 111, 1, 235, 200, 194, 7, - 245, 111, 1, 240, 161, 232, 135, 7, 245, 111, 1, 254, 31, 194, 217, 231, - 229, 219, 1, 61, 217, 231, 229, 219, 1, 74, 217, 231, 229, 219, 5, 246, - 56, 217, 231, 229, 219, 1, 69, 217, 231, 229, 219, 1, 76, 217, 231, 229, - 219, 1, 78, 217, 231, 229, 219, 5, 242, 4, 217, 231, 229, 219, 1, 234, - 34, 217, 231, 229, 219, 1, 234, 111, 217, 231, 229, 219, 1, 242, 181, - 217, 231, 229, 219, 1, 242, 231, 217, 231, 229, 219, 5, 254, 83, 217, - 231, 229, 219, 1, 249, 246, 217, 231, 229, 219, 1, 250, 94, 217, 231, - 229, 219, 1, 235, 74, 217, 231, 229, 219, 1, 235, 115, 217, 231, 229, - 219, 1, 215, 134, 217, 231, 229, 219, 1, 215, 140, 217, 231, 229, 219, 1, - 248, 113, 217, 231, 229, 219, 1, 248, 122, 217, 231, 229, 219, 1, 112, - 217, 231, 229, 219, 1, 216, 157, 217, 231, 229, 219, 1, 247, 153, 217, - 231, 229, 219, 1, 248, 15, 217, 231, 229, 219, 1, 228, 79, 217, 231, 229, - 219, 1, 225, 19, 217, 231, 229, 219, 1, 225, 124, 217, 231, 229, 219, 1, - 251, 213, 217, 231, 229, 219, 1, 252, 18, 217, 231, 229, 219, 1, 230, - 166, 217, 231, 229, 219, 1, 222, 213, 217, 231, 229, 219, 1, 232, 162, - 217, 231, 229, 219, 1, 222, 167, 217, 231, 229, 219, 1, 219, 60, 217, - 231, 229, 219, 1, 241, 75, 217, 231, 229, 219, 25, 5, 61, 217, 231, 229, - 219, 25, 5, 74, 217, 231, 229, 219, 25, 5, 69, 217, 231, 229, 219, 25, 5, - 76, 217, 231, 229, 219, 25, 5, 226, 187, 217, 231, 229, 219, 225, 15, - 231, 163, 217, 231, 229, 219, 225, 15, 231, 162, 217, 231, 229, 219, 225, - 15, 231, 161, 217, 231, 229, 219, 225, 15, 231, 160, 228, 61, 235, 247, - 244, 10, 123, 224, 24, 228, 61, 235, 247, 244, 10, 123, 242, 34, 228, 61, - 235, 247, 244, 10, 134, 224, 22, 228, 61, 235, 247, 244, 10, 123, 219, - 119, 228, 61, 235, 247, 244, 10, 123, 245, 196, 228, 61, 235, 247, 244, - 10, 134, 219, 118, 228, 61, 235, 247, 224, 25, 79, 228, 61, 235, 247, - 225, 43, 79, 228, 61, 235, 247, 222, 120, 79, 228, 61, 235, 247, 224, 26, - 79, 225, 147, 1, 176, 225, 147, 1, 234, 138, 225, 147, 1, 243, 142, 225, - 147, 1, 229, 82, 225, 147, 1, 251, 41, 225, 147, 1, 250, 165, 225, 147, - 1, 235, 147, 225, 147, 1, 227, 169, 225, 147, 1, 217, 106, 225, 147, 1, - 216, 209, 225, 147, 1, 248, 229, 225, 147, 1, 198, 225, 147, 1, 191, 225, - 147, 1, 225, 150, 225, 147, 1, 252, 199, 225, 147, 1, 186, 225, 147, 1, - 215, 184, 225, 147, 1, 215, 176, 225, 147, 1, 246, 46, 225, 147, 1, 212, - 65, 225, 147, 1, 210, 82, 225, 147, 1, 210, 116, 225, 147, 1, 4, 61, 225, - 147, 1, 192, 225, 147, 1, 205, 225, 147, 1, 233, 141, 225, 147, 1, 220, - 104, 225, 147, 1, 206, 225, 147, 1, 162, 225, 147, 1, 61, 225, 147, 1, - 74, 225, 147, 1, 69, 225, 147, 1, 76, 225, 147, 1, 78, 225, 147, 1, 224, - 91, 225, 147, 1, 211, 165, 225, 147, 1, 244, 204, 225, 147, 1, 243, 36, - 225, 147, 1, 245, 217, 225, 147, 218, 74, 1, 212, 65, 225, 147, 218, 74, - 1, 192, 225, 147, 1, 215, 157, 225, 147, 1, 215, 145, 225, 147, 1, 248, - 143, 225, 147, 1, 228, 115, 225, 147, 1, 254, 149, 192, 225, 147, 1, 213, - 134, 220, 104, 225, 147, 1, 213, 135, 162, 225, 147, 1, 253, 231, 244, - 204, 225, 147, 218, 74, 1, 205, 225, 147, 218, 26, 1, 205, 225, 147, 1, - 251, 7, 225, 147, 219, 157, 241, 243, 79, 225, 147, 52, 241, 243, 79, - 225, 147, 164, 220, 97, 225, 147, 164, 52, 220, 97, 179, 5, 254, 83, 179, - 5, 213, 147, 179, 1, 61, 179, 1, 255, 82, 179, 1, 74, 179, 1, 236, 40, - 179, 1, 69, 179, 1, 214, 118, 179, 1, 149, 153, 179, 1, 149, 222, 182, - 179, 1, 149, 156, 179, 1, 149, 232, 191, 179, 1, 76, 179, 1, 245, 217, - 179, 1, 254, 210, 179, 1, 78, 179, 1, 226, 187, 179, 1, 253, 200, 179, 1, - 176, 179, 1, 234, 138, 179, 1, 243, 142, 179, 1, 243, 0, 179, 1, 229, 82, - 179, 1, 251, 41, 179, 1, 250, 165, 179, 1, 235, 147, 179, 1, 235, 120, - 179, 1, 227, 169, 179, 1, 215, 157, 179, 1, 215, 145, 179, 1, 248, 143, - 179, 1, 248, 127, 179, 1, 228, 115, 179, 1, 217, 106, 179, 1, 216, 209, - 179, 1, 248, 229, 179, 1, 248, 33, 179, 1, 198, 179, 1, 191, 179, 1, 225, - 150, 179, 1, 252, 199, 179, 1, 252, 26, 179, 1, 186, 179, 1, 192, 179, 1, - 205, 179, 1, 233, 141, 179, 1, 214, 27, 179, 1, 220, 104, 179, 1, 218, - 225, 179, 1, 206, 179, 1, 162, 179, 1, 232, 190, 179, 117, 5, 242, 51, - 179, 25, 5, 255, 82, 179, 25, 5, 74, 179, 25, 5, 236, 40, 179, 25, 5, 69, - 179, 25, 5, 214, 118, 179, 25, 5, 149, 153, 179, 25, 5, 149, 222, 182, - 179, 25, 5, 149, 156, 179, 25, 5, 149, 232, 191, 179, 25, 5, 76, 179, 25, - 5, 245, 217, 179, 25, 5, 254, 210, 179, 25, 5, 78, 179, 25, 5, 226, 187, - 179, 25, 5, 253, 200, 179, 5, 213, 152, 179, 248, 186, 179, 52, 248, 186, - 179, 21, 210, 86, 179, 21, 111, 179, 21, 105, 179, 21, 158, 179, 21, 161, - 179, 21, 190, 179, 21, 195, 179, 21, 199, 179, 21, 196, 179, 21, 201, 38, - 84, 21, 210, 86, 38, 84, 21, 111, 38, 84, 21, 105, 38, 84, 21, 158, 38, - 84, 21, 161, 38, 84, 21, 190, 38, 84, 21, 195, 38, 84, 21, 199, 38, 84, - 21, 196, 38, 84, 21, 201, 38, 84, 1, 61, 38, 84, 1, 69, 38, 84, 1, 176, - 38, 84, 1, 198, 38, 84, 1, 191, 38, 84, 1, 205, 38, 84, 1, 213, 176, 38, - 84, 5, 253, 183, 84, 5, 219, 19, 251, 7, 84, 5, 251, 8, 213, 152, 84, 5, - 52, 251, 8, 213, 152, 84, 5, 251, 8, 105, 84, 5, 251, 8, 158, 84, 5, 251, - 8, 253, 183, 84, 5, 224, 127, 84, 243, 107, 244, 111, 84, 250, 246, 84, - 241, 237, 234, 194, 232, 248, 21, 210, 86, 234, 194, 232, 248, 21, 111, - 234, 194, 232, 248, 21, 105, 234, 194, 232, 248, 21, 158, 234, 194, 232, - 248, 21, 161, 234, 194, 232, 248, 21, 190, 234, 194, 232, 248, 21, 195, - 234, 194, 232, 248, 21, 199, 234, 194, 232, 248, 21, 196, 234, 194, 232, - 248, 21, 201, 234, 194, 232, 248, 1, 176, 234, 194, 232, 248, 1, 234, - 138, 234, 194, 232, 248, 1, 243, 142, 234, 194, 232, 248, 1, 229, 82, - 234, 194, 232, 248, 1, 206, 234, 194, 232, 248, 1, 220, 104, 234, 194, - 232, 248, 1, 210, 116, 234, 194, 232, 248, 1, 227, 169, 234, 194, 232, - 248, 1, 217, 106, 234, 194, 232, 248, 1, 240, 233, 234, 194, 232, 248, 1, - 198, 234, 194, 232, 248, 1, 191, 234, 194, 232, 248, 1, 225, 150, 234, - 194, 232, 248, 1, 186, 234, 194, 232, 248, 1, 248, 229, 234, 194, 232, - 248, 1, 252, 199, 234, 194, 232, 248, 1, 205, 234, 194, 232, 248, 1, 192, - 234, 194, 232, 248, 1, 233, 141, 234, 194, 232, 248, 1, 212, 65, 234, - 194, 232, 248, 1, 216, 209, 234, 194, 232, 248, 1, 162, 234, 194, 232, - 248, 1, 214, 27, 234, 194, 232, 248, 1, 251, 41, 234, 194, 232, 248, 1, - 61, 234, 194, 232, 248, 1, 226, 238, 234, 194, 232, 248, 1, 74, 234, 194, - 232, 248, 1, 226, 187, 234, 194, 232, 248, 25, 214, 214, 234, 194, 232, - 248, 25, 76, 234, 194, 232, 248, 25, 69, 234, 194, 232, 248, 25, 245, - 217, 234, 194, 232, 248, 25, 78, 234, 194, 232, 248, 138, 225, 33, 234, - 194, 232, 248, 138, 251, 20, 234, 194, 232, 248, 138, 251, 21, 225, 33, - 234, 194, 232, 248, 5, 249, 85, 234, 194, 232, 248, 5, 219, 201, 223, 96, - 1, 176, 223, 96, 1, 243, 142, 223, 96, 1, 229, 82, 223, 96, 1, 217, 106, - 223, 96, 1, 248, 229, 223, 96, 1, 198, 223, 96, 1, 191, 223, 96, 1, 252, - 199, 223, 96, 1, 186, 223, 96, 1, 251, 41, 223, 96, 1, 235, 147, 223, 96, - 1, 227, 169, 223, 96, 1, 206, 223, 96, 1, 205, 223, 96, 1, 233, 141, 223, - 96, 1, 192, 223, 96, 1, 212, 65, 223, 96, 1, 162, 223, 96, 1, 231, 129, - 223, 96, 1, 229, 61, 223, 96, 1, 229, 153, 223, 96, 1, 227, 139, 223, 96, - 1, 61, 223, 96, 25, 5, 74, 223, 96, 25, 5, 69, 223, 96, 25, 5, 76, 223, - 96, 25, 5, 254, 210, 223, 96, 25, 5, 78, 223, 96, 25, 5, 253, 200, 223, - 96, 25, 5, 245, 63, 223, 96, 25, 5, 245, 241, 223, 96, 117, 5, 229, 84, - 223, 96, 117, 5, 230, 30, 223, 96, 117, 5, 153, 223, 96, 117, 5, 242, 67, - 223, 96, 213, 152, 223, 96, 221, 175, 79, 24, 100, 216, 98, 24, 100, 216, - 97, 24, 100, 216, 95, 24, 100, 216, 100, 24, 100, 223, 24, 24, 100, 223, - 8, 24, 100, 223, 3, 24, 100, 223, 5, 24, 100, 223, 21, 24, 100, 223, 14, - 24, 100, 223, 7, 24, 100, 223, 26, 24, 100, 223, 9, 24, 100, 223, 28, 24, - 100, 223, 25, 24, 100, 230, 218, 24, 100, 230, 209, 24, 100, 230, 212, - 24, 100, 225, 83, 24, 100, 225, 94, 24, 100, 225, 95, 24, 100, 218, 209, - 24, 100, 236, 53, 24, 100, 236, 60, 24, 100, 218, 220, 24, 100, 218, 207, - 24, 100, 225, 133, 24, 100, 241, 174, 24, 100, 218, 204, 155, 5, 226, 31, - 155, 5, 250, 195, 155, 5, 233, 72, 155, 5, 211, 243, 155, 1, 61, 155, 1, - 240, 161, 234, 197, 155, 1, 74, 155, 1, 236, 40, 155, 1, 69, 155, 1, 226, - 94, 250, 171, 155, 1, 229, 83, 233, 34, 155, 1, 229, 83, 233, 35, 223, - 145, 155, 1, 76, 155, 1, 254, 210, 155, 1, 78, 155, 1, 176, 155, 1, 235, - 19, 221, 230, 155, 1, 235, 19, 230, 71, 155, 1, 243, 142, 155, 1, 243, - 143, 230, 71, 155, 1, 229, 82, 155, 1, 251, 41, 155, 1, 251, 42, 230, 71, - 155, 1, 235, 147, 155, 1, 227, 170, 230, 71, 155, 1, 235, 148, 231, 212, - 155, 1, 227, 169, 155, 1, 215, 157, 155, 1, 215, 158, 231, 212, 155, 1, - 248, 143, 155, 1, 248, 144, 231, 212, 155, 1, 229, 234, 230, 71, 155, 1, - 217, 106, 155, 1, 217, 107, 230, 71, 155, 1, 248, 229, 155, 1, 248, 230, - 231, 212, 155, 1, 198, 155, 1, 191, 155, 1, 226, 94, 230, 71, 155, 1, - 252, 199, 155, 1, 252, 200, 230, 71, 155, 1, 186, 155, 1, 192, 155, 1, - 205, 155, 1, 223, 191, 254, 219, 155, 1, 233, 141, 155, 1, 212, 65, 155, - 1, 222, 36, 230, 71, 155, 1, 222, 36, 231, 212, 155, 1, 206, 155, 1, 162, - 155, 5, 250, 196, 216, 251, 155, 25, 5, 217, 48, 155, 25, 5, 216, 36, - 155, 25, 5, 211, 190, 155, 25, 5, 211, 191, 231, 74, 155, 25, 5, 218, 48, - 155, 25, 5, 218, 49, 231, 62, 155, 25, 5, 217, 66, 155, 25, 5, 247, 202, - 230, 70, 155, 25, 5, 225, 187, 155, 117, 5, 234, 164, 155, 117, 5, 225, - 199, 155, 117, 5, 251, 27, 155, 226, 44, 155, 43, 223, 72, 155, 44, 223, - 72, 155, 226, 83, 254, 125, 155, 226, 83, 231, 229, 155, 226, 83, 232, - 93, 155, 226, 83, 211, 238, 155, 226, 83, 226, 45, 155, 226, 83, 232, - 211, 155, 226, 83, 232, 87, 155, 226, 83, 255, 2, 155, 226, 83, 255, 3, - 255, 2, 155, 226, 83, 225, 54, 155, 215, 94, 226, 83, 225, 54, 155, 226, - 40, 155, 21, 210, 86, 155, 21, 111, 155, 21, 105, 155, 21, 158, 155, 21, - 161, 155, 21, 190, 155, 21, 195, 155, 21, 199, 155, 21, 196, 155, 21, - 201, 155, 226, 83, 216, 70, 215, 107, 155, 226, 83, 235, 174, 172, 1, 61, - 172, 1, 74, 172, 1, 69, 172, 1, 76, 172, 1, 254, 210, 172, 1, 78, 172, 1, - 176, 172, 1, 234, 138, 172, 1, 243, 142, 172, 1, 243, 0, 172, 1, 228, - 250, 172, 1, 229, 82, 172, 1, 250, 165, 172, 1, 250, 120, 172, 1, 235, - 147, 172, 1, 235, 120, 172, 1, 228, 240, 172, 1, 228, 242, 172, 1, 228, - 241, 172, 1, 217, 106, 172, 1, 216, 209, 172, 1, 248, 229, 172, 1, 248, - 33, 172, 1, 227, 211, 172, 1, 198, 172, 1, 248, 143, 172, 1, 191, 172, 1, - 224, 223, 172, 1, 225, 150, 172, 1, 252, 199, 172, 1, 252, 26, 172, 1, - 230, 100, 172, 1, 186, 172, 1, 252, 119, 172, 1, 192, 172, 1, 205, 172, - 1, 233, 141, 172, 1, 214, 27, 172, 1, 218, 225, 172, 1, 206, 172, 1, 162, - 172, 25, 5, 255, 82, 172, 25, 5, 74, 172, 25, 5, 236, 40, 172, 25, 5, - 245, 203, 172, 25, 5, 69, 172, 25, 5, 226, 238, 172, 25, 5, 78, 172, 25, - 5, 254, 210, 172, 25, 5, 253, 200, 172, 25, 5, 214, 214, 172, 117, 5, - 192, 172, 117, 5, 205, 172, 117, 5, 233, 141, 172, 117, 5, 212, 65, 172, - 1, 40, 235, 29, 172, 1, 40, 243, 209, 172, 1, 40, 229, 84, 172, 117, 5, - 40, 229, 84, 172, 1, 40, 250, 166, 172, 1, 40, 217, 153, 172, 1, 40, 230, - 30, 172, 1, 40, 226, 109, 172, 1, 40, 211, 117, 172, 1, 40, 153, 172, 1, - 40, 156, 172, 1, 40, 218, 228, 172, 117, 5, 40, 194, 172, 117, 5, 40, - 242, 67, 172, 21, 210, 86, 172, 21, 111, 172, 21, 105, 172, 21, 158, 172, - 21, 161, 172, 21, 190, 172, 21, 195, 172, 21, 199, 172, 21, 196, 172, 21, - 201, 172, 224, 144, 218, 253, 172, 224, 144, 248, 186, 172, 224, 144, 52, - 248, 186, 172, 224, 144, 215, 212, 248, 186, 68, 1, 234, 132, 243, 142, - 68, 1, 234, 132, 251, 41, 68, 1, 234, 132, 250, 165, 68, 1, 234, 132, - 235, 147, 68, 1, 234, 132, 235, 120, 68, 1, 234, 132, 227, 169, 68, 1, - 234, 132, 215, 157, 68, 1, 234, 132, 215, 145, 68, 1, 234, 132, 248, 143, - 68, 1, 234, 132, 248, 127, 68, 1, 234, 132, 248, 33, 68, 1, 234, 132, - 198, 68, 1, 234, 132, 206, 68, 1, 234, 132, 162, 68, 1, 234, 132, 241, - 196, 68, 1, 234, 132, 244, 204, 68, 58, 1, 234, 132, 223, 112, 68, 1, - 234, 132, 211, 165, 68, 1, 234, 132, 210, 116, 68, 1, 234, 132, 205, 68, - 232, 151, 234, 132, 227, 1, 68, 232, 151, 234, 132, 224, 46, 68, 232, - 151, 234, 132, 241, 128, 68, 16, 254, 199, 245, 38, 68, 16, 254, 199, - 111, 68, 16, 254, 199, 105, 68, 1, 254, 199, 205, 68, 5, 226, 27, 234, - 219, 216, 31, 39, 208, 1, 121, 234, 34, 39, 208, 1, 125, 234, 34, 39, - 208, 1, 121, 234, 111, 39, 208, 1, 125, 234, 111, 39, 208, 1, 121, 234, - 120, 39, 208, 1, 125, 234, 120, 39, 208, 1, 121, 242, 181, 39, 208, 1, - 125, 242, 181, 39, 208, 1, 121, 229, 9, 39, 208, 1, 125, 229, 9, 39, 208, - 1, 121, 249, 246, 39, 208, 1, 125, 249, 246, 39, 208, 1, 121, 250, 94, - 39, 208, 1, 125, 250, 94, 39, 208, 1, 121, 219, 60, 39, 208, 1, 125, 219, - 60, 39, 208, 1, 121, 227, 138, 39, 208, 1, 125, 227, 138, 39, 208, 1, - 121, 247, 153, 39, 208, 1, 125, 247, 153, 39, 208, 1, 121, 112, 39, 208, - 1, 125, 112, 39, 208, 1, 121, 216, 157, 39, 208, 1, 125, 216, 157, 39, - 208, 1, 121, 228, 79, 39, 208, 1, 125, 228, 79, 39, 208, 1, 121, 251, - 213, 39, 208, 1, 125, 251, 213, 39, 208, 1, 121, 225, 19, 39, 208, 1, - 125, 225, 19, 39, 208, 1, 121, 225, 124, 39, 208, 1, 125, 225, 124, 39, - 208, 1, 121, 244, 51, 39, 208, 1, 125, 244, 51, 39, 208, 1, 121, 230, - 166, 39, 208, 1, 125, 230, 166, 39, 208, 1, 121, 210, 244, 39, 208, 1, - 125, 210, 244, 39, 208, 1, 121, 222, 213, 39, 208, 1, 125, 222, 213, 39, - 208, 1, 121, 232, 162, 39, 208, 1, 125, 232, 162, 39, 208, 1, 121, 213, - 138, 39, 208, 1, 125, 213, 138, 39, 208, 1, 121, 241, 75, 39, 208, 1, - 125, 241, 75, 39, 208, 1, 121, 78, 39, 208, 1, 125, 78, 39, 208, 231, - 209, 234, 236, 39, 208, 25, 255, 82, 39, 208, 25, 74, 39, 208, 25, 214, - 214, 39, 208, 25, 69, 39, 208, 25, 76, 39, 208, 25, 78, 39, 208, 231, - 209, 234, 114, 39, 208, 25, 240, 126, 39, 208, 25, 214, 213, 39, 208, 25, - 214, 229, 39, 208, 25, 253, 198, 39, 208, 25, 253, 175, 39, 208, 25, 254, - 131, 39, 208, 25, 254, 144, 39, 208, 138, 231, 209, 245, 188, 39, 208, - 138, 231, 209, 227, 210, 39, 208, 138, 231, 209, 216, 157, 39, 208, 138, - 231, 209, 219, 44, 39, 208, 16, 234, 19, 39, 208, 16, 227, 210, 39, 208, - 16, 221, 255, 39, 208, 16, 241, 76, 241, 71, 39, 208, 16, 234, 28, 234, - 27, 188, 187, 1, 76, 188, 187, 1, 78, 188, 187, 1, 250, 165, 188, 187, 1, - 227, 169, 188, 187, 1, 215, 157, 188, 187, 1, 215, 145, 188, 187, 1, 248, - 143, 188, 187, 1, 248, 127, 188, 187, 1, 228, 115, 188, 187, 1, 220, 104, - 188, 187, 1, 218, 225, 188, 187, 25, 5, 236, 40, 188, 187, 25, 5, 214, - 118, 188, 187, 25, 5, 255, 46, 188, 187, 25, 5, 253, 200, 188, 187, 25, - 5, 255, 39, 188, 187, 250, 133, 188, 187, 254, 215, 234, 104, 188, 187, - 254, 111, 188, 187, 3, 223, 77, 79, 188, 187, 211, 209, 223, 77, 79, 188, - 187, 25, 5, 213, 147, 188, 187, 213, 152, 29, 3, 215, 138, 29, 3, 215, - 141, 29, 3, 215, 144, 29, 3, 215, 142, 29, 3, 215, 143, 29, 3, 215, 140, - 29, 3, 248, 121, 29, 3, 248, 123, 29, 3, 248, 126, 29, 3, 248, 124, 29, - 3, 248, 125, 29, 3, 248, 122, 29, 3, 246, 36, 29, 3, 246, 39, 29, 3, 246, - 45, 29, 3, 246, 43, 29, 3, 246, 44, 29, 3, 246, 37, 29, 3, 250, 212, 29, - 3, 250, 206, 29, 3, 250, 208, 29, 3, 250, 211, 29, 3, 250, 209, 29, 3, - 250, 210, 29, 3, 250, 207, 29, 3, 252, 119, 29, 3, 252, 98, 29, 3, 252, - 110, 29, 3, 252, 118, 29, 3, 252, 113, 29, 3, 252, 114, 29, 3, 252, 102, - 188, 187, 1, 234, 25, 188, 187, 1, 221, 255, 188, 187, 1, 233, 115, 188, - 187, 1, 230, 177, 188, 187, 1, 191, 188, 187, 1, 198, 188, 187, 1, 250, - 110, 188, 187, 1, 216, 91, 188, 187, 1, 234, 107, 188, 187, 1, 228, 255, - 188, 187, 1, 216, 151, 188, 187, 1, 212, 60, 188, 187, 1, 211, 69, 188, - 187, 1, 240, 223, 188, 187, 1, 214, 190, 188, 187, 1, 74, 188, 187, 1, - 225, 145, 188, 187, 1, 253, 210, 188, 187, 1, 242, 174, 188, 187, 1, 235, - 118, 188, 187, 1, 223, 169, 188, 187, 1, 252, 199, 188, 187, 1, 235, 106, - 188, 187, 1, 247, 227, 188, 187, 1, 242, 228, 188, 187, 1, 248, 13, 188, - 187, 1, 252, 24, 188, 187, 1, 234, 26, 232, 134, 188, 187, 1, 233, 116, - 232, 134, 188, 187, 1, 230, 178, 232, 134, 188, 187, 1, 226, 94, 232, - 134, 188, 187, 1, 229, 234, 232, 134, 188, 187, 1, 216, 92, 232, 134, - 188, 187, 1, 229, 0, 232, 134, 188, 187, 1, 240, 161, 232, 134, 188, 187, - 25, 5, 226, 199, 188, 187, 25, 5, 236, 4, 188, 187, 25, 5, 254, 130, 188, - 187, 25, 5, 211, 38, 188, 187, 25, 5, 219, 34, 188, 187, 25, 5, 214, 187, - 188, 187, 25, 5, 250, 131, 188, 187, 25, 5, 227, 195, 188, 187, 250, 132, - 188, 187, 232, 90, 235, 156, 188, 187, 254, 54, 235, 156, 188, 187, 21, - 210, 86, 188, 187, 21, 111, 188, 187, 21, 105, 188, 187, 21, 158, 188, - 187, 21, 161, 188, 187, 21, 190, 188, 187, 21, 195, 188, 187, 21, 199, - 188, 187, 21, 196, 188, 187, 21, 201, 24, 143, 227, 81, 24, 143, 227, 86, - 24, 143, 210, 243, 24, 143, 210, 242, 24, 143, 210, 241, 24, 143, 215, - 23, 24, 143, 215, 26, 24, 143, 210, 210, 24, 143, 210, 206, 24, 143, 245, - 62, 24, 143, 245, 60, 24, 143, 245, 61, 24, 143, 245, 58, 24, 143, 240, - 151, 24, 143, 240, 150, 24, 143, 240, 148, 24, 143, 240, 149, 24, 143, - 240, 154, 24, 143, 240, 147, 24, 143, 240, 146, 24, 143, 240, 156, 24, - 143, 254, 41, 24, 143, 254, 40, 24, 90, 228, 224, 24, 90, 228, 230, 24, - 90, 218, 206, 24, 90, 218, 205, 24, 90, 216, 97, 24, 90, 216, 95, 24, 90, - 216, 94, 24, 90, 216, 100, 24, 90, 216, 101, 24, 90, 216, 93, 24, 90, - 223, 8, 24, 90, 223, 23, 24, 90, 218, 212, 24, 90, 223, 20, 24, 90, 223, - 10, 24, 90, 223, 12, 24, 90, 222, 255, 24, 90, 223, 0, 24, 90, 234, 224, - 24, 90, 230, 217, 24, 90, 230, 211, 24, 90, 218, 216, 24, 90, 230, 214, - 24, 90, 230, 220, 24, 90, 225, 79, 24, 90, 225, 88, 24, 90, 225, 92, 24, - 90, 218, 214, 24, 90, 225, 82, 24, 90, 225, 96, 24, 90, 225, 97, 24, 90, - 219, 142, 24, 90, 219, 145, 24, 90, 218, 210, 24, 90, 218, 208, 24, 90, - 219, 140, 24, 90, 219, 148, 24, 90, 219, 149, 24, 90, 219, 134, 24, 90, - 219, 147, 24, 90, 226, 34, 24, 90, 226, 35, 24, 90, 211, 24, 24, 90, 211, - 25, 24, 90, 250, 52, 24, 90, 250, 51, 24, 90, 218, 221, 24, 90, 225, 131, - 24, 90, 225, 130, 10, 14, 238, 31, 10, 14, 238, 30, 10, 14, 238, 29, 10, - 14, 238, 28, 10, 14, 238, 27, 10, 14, 238, 26, 10, 14, 238, 25, 10, 14, - 238, 24, 10, 14, 238, 23, 10, 14, 238, 22, 10, 14, 238, 21, 10, 14, 238, - 20, 10, 14, 238, 19, 10, 14, 238, 18, 10, 14, 238, 17, 10, 14, 238, 16, - 10, 14, 238, 15, 10, 14, 238, 14, 10, 14, 238, 13, 10, 14, 238, 12, 10, - 14, 238, 11, 10, 14, 238, 10, 10, 14, 238, 9, 10, 14, 238, 8, 10, 14, - 238, 7, 10, 14, 238, 6, 10, 14, 238, 5, 10, 14, 238, 4, 10, 14, 238, 3, - 10, 14, 238, 2, 10, 14, 238, 1, 10, 14, 238, 0, 10, 14, 237, 255, 10, 14, - 237, 254, 10, 14, 237, 253, 10, 14, 237, 252, 10, 14, 237, 251, 10, 14, - 237, 250, 10, 14, 237, 249, 10, 14, 237, 248, 10, 14, 237, 247, 10, 14, - 237, 246, 10, 14, 237, 245, 10, 14, 237, 244, 10, 14, 237, 243, 10, 14, - 237, 242, 10, 14, 237, 241, 10, 14, 237, 240, 10, 14, 237, 239, 10, 14, - 237, 238, 10, 14, 237, 237, 10, 14, 237, 236, 10, 14, 237, 235, 10, 14, - 237, 234, 10, 14, 237, 233, 10, 14, 237, 232, 10, 14, 237, 231, 10, 14, - 237, 230, 10, 14, 237, 229, 10, 14, 237, 228, 10, 14, 237, 227, 10, 14, - 237, 226, 10, 14, 237, 225, 10, 14, 237, 224, 10, 14, 237, 223, 10, 14, - 237, 222, 10, 14, 237, 221, 10, 14, 237, 220, 10, 14, 237, 219, 10, 14, - 237, 218, 10, 14, 237, 217, 10, 14, 237, 216, 10, 14, 237, 215, 10, 14, - 237, 214, 10, 14, 237, 213, 10, 14, 237, 212, 10, 14, 237, 211, 10, 14, - 237, 210, 10, 14, 237, 209, 10, 14, 237, 208, 10, 14, 237, 207, 10, 14, - 237, 206, 10, 14, 237, 205, 10, 14, 237, 204, 10, 14, 237, 203, 10, 14, - 237, 202, 10, 14, 237, 201, 10, 14, 237, 200, 10, 14, 237, 199, 10, 14, - 237, 198, 10, 14, 237, 197, 10, 14, 237, 196, 10, 14, 237, 195, 10, 14, - 237, 194, 10, 14, 237, 193, 10, 14, 237, 192, 10, 14, 237, 191, 10, 14, - 237, 190, 10, 14, 237, 189, 10, 14, 237, 188, 10, 14, 237, 187, 10, 14, - 237, 186, 10, 14, 237, 185, 10, 14, 237, 184, 10, 14, 237, 183, 10, 14, - 237, 182, 10, 14, 237, 181, 10, 14, 237, 180, 10, 14, 237, 179, 10, 14, - 237, 178, 10, 14, 237, 177, 10, 14, 237, 176, 10, 14, 237, 175, 10, 14, - 237, 174, 10, 14, 237, 173, 10, 14, 237, 172, 10, 14, 237, 171, 10, 14, - 237, 170, 10, 14, 237, 169, 10, 14, 237, 168, 10, 14, 237, 167, 10, 14, - 237, 166, 10, 14, 237, 165, 10, 14, 237, 164, 10, 14, 237, 163, 10, 14, - 237, 162, 10, 14, 237, 161, 10, 14, 237, 160, 10, 14, 237, 159, 10, 14, - 237, 158, 10, 14, 237, 157, 10, 14, 237, 156, 10, 14, 237, 155, 10, 14, - 237, 154, 10, 14, 237, 153, 10, 14, 237, 152, 10, 14, 237, 151, 10, 14, - 237, 150, 10, 14, 237, 149, 10, 14, 237, 148, 10, 14, 237, 147, 10, 14, - 237, 146, 10, 14, 237, 145, 10, 14, 237, 144, 10, 14, 237, 143, 10, 14, - 237, 142, 10, 14, 237, 141, 10, 14, 237, 140, 10, 14, 237, 139, 10, 14, - 237, 138, 10, 14, 237, 137, 10, 14, 237, 136, 10, 14, 237, 135, 10, 14, - 237, 134, 10, 14, 237, 133, 10, 14, 237, 132, 10, 14, 237, 131, 10, 14, - 237, 130, 10, 14, 237, 129, 10, 14, 237, 128, 10, 14, 237, 127, 10, 14, - 237, 126, 10, 14, 237, 125, 10, 14, 237, 124, 10, 14, 237, 123, 10, 14, - 237, 122, 10, 14, 237, 121, 10, 14, 237, 120, 10, 14, 237, 119, 10, 14, - 237, 118, 10, 14, 237, 117, 10, 14, 237, 116, 10, 14, 237, 115, 10, 14, - 237, 114, 10, 14, 237, 113, 10, 14, 237, 112, 10, 14, 237, 111, 10, 14, - 237, 110, 10, 14, 237, 109, 10, 14, 237, 108, 10, 14, 237, 107, 10, 14, - 237, 106, 10, 14, 237, 105, 10, 14, 237, 104, 10, 14, 237, 103, 10, 14, - 237, 102, 10, 14, 237, 101, 10, 14, 237, 100, 10, 14, 237, 99, 10, 14, - 237, 98, 10, 14, 237, 97, 10, 14, 237, 96, 10, 14, 237, 95, 10, 14, 237, - 94, 10, 14, 237, 93, 10, 14, 237, 92, 10, 14, 237, 91, 10, 14, 237, 90, - 10, 14, 237, 89, 10, 14, 237, 88, 10, 14, 237, 87, 10, 14, 237, 86, 10, - 14, 237, 85, 10, 14, 237, 84, 10, 14, 237, 83, 10, 14, 237, 82, 10, 14, - 237, 81, 10, 14, 237, 80, 10, 14, 237, 79, 10, 14, 237, 78, 10, 14, 237, - 77, 10, 14, 237, 76, 10, 14, 237, 75, 10, 14, 237, 74, 10, 14, 237, 73, - 10, 14, 237, 72, 10, 14, 237, 71, 10, 14, 237, 70, 10, 14, 237, 69, 10, - 14, 237, 68, 10, 14, 237, 67, 10, 14, 237, 66, 10, 14, 237, 65, 10, 14, - 237, 64, 10, 14, 237, 63, 10, 14, 237, 62, 10, 14, 237, 61, 10, 14, 237, - 60, 10, 14, 237, 59, 10, 14, 237, 58, 10, 14, 237, 57, 10, 14, 237, 56, - 10, 14, 237, 55, 10, 14, 237, 54, 10, 14, 237, 53, 10, 14, 237, 52, 10, - 14, 237, 51, 10, 14, 237, 50, 10, 14, 237, 49, 10, 14, 237, 48, 10, 14, - 237, 47, 10, 14, 237, 46, 10, 14, 237, 45, 10, 14, 237, 44, 10, 14, 237, - 43, 10, 14, 237, 42, 10, 14, 237, 41, 10, 14, 237, 40, 10, 14, 237, 39, - 10, 14, 237, 38, 10, 14, 237, 37, 10, 14, 237, 36, 10, 14, 237, 35, 10, - 14, 237, 34, 10, 14, 237, 33, 10, 14, 237, 32, 10, 14, 237, 31, 10, 14, - 237, 30, 10, 14, 237, 29, 10, 14, 237, 28, 10, 14, 237, 27, 10, 14, 237, - 26, 10, 14, 237, 25, 10, 14, 237, 24, 10, 14, 237, 23, 10, 14, 237, 22, - 10, 14, 237, 21, 10, 14, 237, 20, 10, 14, 237, 19, 10, 14, 237, 18, 10, - 14, 237, 17, 10, 14, 237, 16, 10, 14, 237, 15, 10, 14, 237, 14, 10, 14, - 237, 13, 10, 14, 237, 12, 10, 14, 237, 11, 10, 14, 237, 10, 10, 14, 237, - 9, 10, 14, 237, 8, 10, 14, 237, 7, 10, 14, 237, 6, 10, 14, 237, 5, 10, - 14, 237, 4, 10, 14, 237, 3, 10, 14, 237, 2, 10, 14, 237, 1, 10, 14, 237, - 0, 10, 14, 236, 255, 10, 14, 236, 254, 10, 14, 236, 253, 10, 14, 236, - 252, 10, 14, 236, 251, 10, 14, 236, 250, 10, 14, 236, 249, 10, 14, 236, - 248, 10, 14, 236, 247, 10, 14, 236, 246, 10, 14, 236, 245, 10, 14, 236, - 244, 10, 14, 236, 243, 10, 14, 236, 242, 10, 14, 236, 241, 10, 14, 236, - 240, 10, 14, 236, 239, 10, 14, 236, 238, 10, 14, 236, 237, 10, 14, 236, - 236, 10, 14, 236, 235, 10, 14, 236, 234, 10, 14, 236, 233, 10, 14, 236, - 232, 10, 14, 236, 231, 10, 14, 236, 230, 10, 14, 236, 229, 10, 14, 236, - 228, 10, 14, 236, 227, 10, 14, 236, 226, 10, 14, 236, 225, 10, 14, 236, - 224, 10, 14, 236, 223, 10, 14, 236, 222, 10, 14, 236, 221, 10, 14, 236, - 220, 10, 14, 236, 219, 10, 14, 236, 218, 10, 14, 236, 217, 10, 14, 236, - 216, 10, 14, 236, 215, 10, 14, 236, 214, 10, 14, 236, 213, 10, 14, 236, - 212, 10, 14, 236, 211, 10, 14, 236, 210, 10, 14, 236, 209, 10, 14, 236, - 208, 10, 14, 236, 207, 10, 14, 236, 206, 10, 14, 236, 205, 10, 14, 236, - 204, 10, 14, 236, 203, 10, 14, 236, 202, 10, 14, 236, 201, 10, 14, 236, - 200, 10, 14, 236, 199, 10, 14, 236, 198, 10, 14, 236, 197, 10, 14, 236, - 196, 10, 14, 236, 195, 10, 14, 236, 194, 10, 14, 236, 193, 10, 14, 236, - 192, 10, 14, 236, 191, 10, 14, 236, 190, 10, 14, 236, 189, 10, 14, 236, - 188, 10, 14, 236, 187, 10, 14, 236, 186, 10, 14, 236, 185, 10, 14, 236, - 184, 10, 14, 236, 183, 10, 14, 236, 182, 10, 14, 236, 181, 10, 14, 236, - 180, 10, 14, 236, 179, 10, 14, 236, 178, 10, 14, 236, 177, 10, 14, 236, - 176, 10, 14, 236, 175, 10, 14, 236, 174, 10, 14, 236, 173, 10, 14, 236, - 172, 10, 14, 236, 171, 10, 14, 236, 170, 10, 14, 236, 169, 10, 14, 236, - 168, 10, 14, 236, 167, 10, 14, 236, 166, 10, 14, 236, 165, 10, 14, 236, - 164, 10, 14, 236, 163, 10, 14, 236, 162, 10, 14, 236, 161, 10, 14, 236, - 160, 10, 14, 236, 159, 10, 14, 236, 158, 10, 14, 236, 157, 10, 14, 236, - 156, 10, 14, 236, 155, 10, 14, 236, 154, 10, 14, 236, 153, 10, 14, 236, - 152, 10, 14, 236, 151, 10, 14, 236, 150, 10, 14, 236, 149, 10, 14, 236, - 148, 10, 14, 236, 147, 10, 14, 236, 146, 10, 14, 236, 145, 10, 14, 236, - 144, 10, 14, 236, 143, 10, 14, 236, 142, 10, 14, 236, 141, 10, 14, 236, - 140, 10, 14, 236, 139, 10, 14, 236, 138, 10, 14, 236, 137, 10, 14, 236, - 136, 10, 14, 236, 135, 10, 14, 236, 134, 10, 14, 236, 133, 10, 14, 236, - 132, 10, 14, 236, 131, 10, 14, 236, 130, 10, 14, 236, 129, 10, 14, 236, - 128, 10, 14, 236, 127, 10, 14, 236, 126, 10, 14, 236, 125, 10, 14, 236, - 124, 10, 14, 236, 123, 10, 14, 236, 122, 10, 14, 236, 121, 10, 14, 236, - 120, 10, 14, 236, 119, 10, 14, 236, 118, 10, 14, 236, 117, 10, 14, 236, - 116, 10, 14, 236, 115, 10, 14, 236, 114, 10, 14, 236, 113, 10, 14, 236, - 112, 10, 14, 236, 111, 10, 14, 236, 110, 10, 14, 236, 109, 10, 14, 236, - 108, 10, 14, 236, 107, 10, 14, 236, 106, 10, 14, 236, 105, 10, 14, 236, - 104, 10, 14, 236, 103, 10, 14, 236, 102, 10, 14, 236, 101, 10, 14, 236, - 100, 10, 14, 236, 99, 10, 14, 236, 98, 10, 14, 236, 97, 10, 14, 236, 96, - 10, 14, 236, 95, 10, 14, 236, 94, 10, 14, 236, 93, 10, 14, 236, 92, 10, - 14, 236, 91, 10, 14, 236, 90, 10, 14, 236, 89, 10, 14, 236, 88, 10, 14, - 236, 87, 10, 14, 236, 86, 10, 14, 236, 85, 10, 14, 236, 84, 10, 14, 236, - 83, 10, 14, 236, 82, 10, 14, 236, 81, 10, 14, 236, 80, 10, 14, 236, 79, - 10, 14, 236, 78, 10, 14, 236, 77, 10, 14, 236, 76, 10, 14, 236, 75, 10, - 14, 236, 74, 10, 14, 236, 73, 10, 14, 236, 72, 7, 4, 27, 244, 133, 7, 4, - 27, 244, 129, 7, 4, 27, 244, 84, 7, 4, 27, 244, 132, 7, 4, 27, 244, 131, - 7, 4, 27, 200, 222, 94, 217, 153, 7, 4, 27, 218, 170, 150, 4, 27, 231, - 64, 228, 44, 150, 4, 27, 231, 64, 245, 221, 150, 4, 27, 231, 64, 235, - 234, 150, 4, 27, 213, 180, 228, 44, 150, 4, 27, 231, 64, 211, 160, 94, 1, - 210, 234, 2, 241, 165, 94, 225, 14, 235, 56, 214, 11, 94, 27, 211, 6, - 210, 234, 210, 234, 225, 243, 94, 1, 254, 147, 253, 170, 94, 1, 211, 247, - 254, 179, 94, 1, 211, 247, 248, 197, 94, 1, 211, 247, 241, 245, 94, 1, - 211, 247, 235, 0, 94, 1, 211, 247, 233, 100, 94, 1, 211, 247, 40, 231, - 70, 94, 1, 211, 247, 223, 70, 94, 1, 211, 247, 217, 39, 94, 1, 254, 147, - 96, 50, 94, 1, 220, 23, 2, 220, 23, 247, 128, 94, 1, 220, 23, 2, 219, - 161, 247, 128, 94, 1, 220, 23, 2, 248, 216, 22, 220, 23, 247, 128, 94, 1, - 220, 23, 2, 248, 216, 22, 219, 161, 247, 128, 94, 1, 109, 2, 225, 243, - 94, 1, 109, 2, 224, 79, 94, 1, 109, 2, 231, 176, 94, 1, 252, 37, 2, 248, - 215, 94, 1, 242, 209, 2, 248, 215, 94, 1, 248, 198, 2, 248, 215, 94, 1, - 241, 246, 2, 231, 176, 94, 1, 214, 4, 2, 248, 215, 94, 1, 210, 98, 2, - 248, 215, 94, 1, 216, 232, 2, 248, 215, 94, 1, 210, 234, 2, 248, 215, 94, - 1, 40, 235, 1, 2, 248, 215, 94, 1, 235, 1, 2, 248, 215, 94, 1, 233, 101, - 2, 248, 215, 94, 1, 231, 71, 2, 248, 215, 94, 1, 227, 199, 2, 248, 215, - 94, 1, 221, 252, 2, 248, 215, 94, 1, 40, 225, 225, 2, 248, 215, 94, 1, - 225, 225, 2, 248, 215, 94, 1, 215, 181, 2, 248, 215, 94, 1, 224, 43, 2, - 248, 215, 94, 1, 223, 71, 2, 248, 215, 94, 1, 220, 23, 2, 248, 215, 94, - 1, 217, 40, 2, 248, 215, 94, 1, 214, 4, 2, 241, 68, 94, 1, 252, 37, 2, - 223, 172, 94, 1, 235, 1, 2, 223, 172, 94, 1, 225, 225, 2, 223, 172, 94, - 27, 109, 233, 100, 9, 1, 109, 212, 47, 53, 17, 9, 1, 109, 212, 47, 40, - 17, 9, 1, 252, 73, 53, 17, 9, 1, 252, 73, 40, 17, 9, 1, 252, 73, 65, 17, - 9, 1, 252, 73, 147, 17, 9, 1, 225, 209, 53, 17, 9, 1, 225, 209, 40, 17, - 9, 1, 225, 209, 65, 17, 9, 1, 225, 209, 147, 17, 9, 1, 252, 61, 53, 17, - 9, 1, 252, 61, 40, 17, 9, 1, 252, 61, 65, 17, 9, 1, 252, 61, 147, 17, 9, - 1, 215, 148, 53, 17, 9, 1, 215, 148, 40, 17, 9, 1, 215, 148, 65, 17, 9, - 1, 215, 148, 147, 17, 9, 1, 217, 7, 53, 17, 9, 1, 217, 7, 40, 17, 9, 1, - 217, 7, 65, 17, 9, 1, 217, 7, 147, 17, 9, 1, 215, 150, 53, 17, 9, 1, 215, - 150, 40, 17, 9, 1, 215, 150, 65, 17, 9, 1, 215, 150, 147, 17, 9, 1, 213, - 249, 53, 17, 9, 1, 213, 249, 40, 17, 9, 1, 213, 249, 65, 17, 9, 1, 213, - 249, 147, 17, 9, 1, 225, 207, 53, 17, 9, 1, 225, 207, 40, 17, 9, 1, 225, - 207, 65, 17, 9, 1, 225, 207, 147, 17, 9, 1, 246, 52, 53, 17, 9, 1, 246, - 52, 40, 17, 9, 1, 246, 52, 65, 17, 9, 1, 246, 52, 147, 17, 9, 1, 227, - 158, 53, 17, 9, 1, 227, 158, 40, 17, 9, 1, 227, 158, 65, 17, 9, 1, 227, - 158, 147, 17, 9, 1, 217, 28, 53, 17, 9, 1, 217, 28, 40, 17, 9, 1, 217, - 28, 65, 17, 9, 1, 217, 28, 147, 17, 9, 1, 217, 26, 53, 17, 9, 1, 217, 26, - 40, 17, 9, 1, 217, 26, 65, 17, 9, 1, 217, 26, 147, 17, 9, 1, 248, 141, - 53, 17, 9, 1, 248, 141, 40, 17, 9, 1, 248, 210, 53, 17, 9, 1, 248, 210, - 40, 17, 9, 1, 246, 79, 53, 17, 9, 1, 246, 79, 40, 17, 9, 1, 248, 139, 53, - 17, 9, 1, 248, 139, 40, 17, 9, 1, 235, 127, 53, 17, 9, 1, 235, 127, 40, - 17, 9, 1, 222, 174, 53, 17, 9, 1, 222, 174, 40, 17, 9, 1, 234, 181, 53, - 17, 9, 1, 234, 181, 40, 17, 9, 1, 234, 181, 65, 17, 9, 1, 234, 181, 147, - 17, 9, 1, 243, 130, 53, 17, 9, 1, 243, 130, 40, 17, 9, 1, 243, 130, 65, - 17, 9, 1, 243, 130, 147, 17, 9, 1, 242, 109, 53, 17, 9, 1, 242, 109, 40, - 17, 9, 1, 242, 109, 65, 17, 9, 1, 242, 109, 147, 17, 9, 1, 229, 8, 53, - 17, 9, 1, 229, 8, 40, 17, 9, 1, 229, 8, 65, 17, 9, 1, 229, 8, 147, 17, 9, - 1, 228, 68, 242, 226, 53, 17, 9, 1, 228, 68, 242, 226, 40, 17, 9, 1, 222, - 217, 53, 17, 9, 1, 222, 217, 40, 17, 9, 1, 222, 217, 65, 17, 9, 1, 222, - 217, 147, 17, 9, 1, 241, 226, 2, 77, 72, 53, 17, 9, 1, 241, 226, 2, 77, - 72, 40, 17, 9, 1, 241, 226, 242, 179, 53, 17, 9, 1, 241, 226, 242, 179, - 40, 17, 9, 1, 241, 226, 242, 179, 65, 17, 9, 1, 241, 226, 242, 179, 147, - 17, 9, 1, 241, 226, 247, 150, 53, 17, 9, 1, 241, 226, 247, 150, 40, 17, - 9, 1, 241, 226, 247, 150, 65, 17, 9, 1, 241, 226, 247, 150, 147, 17, 9, - 1, 77, 252, 141, 53, 17, 9, 1, 77, 252, 141, 40, 17, 9, 1, 77, 252, 141, - 2, 182, 72, 53, 17, 9, 1, 77, 252, 141, 2, 182, 72, 40, 17, 9, 16, 59, - 48, 9, 16, 59, 51, 9, 16, 113, 170, 48, 9, 16, 113, 170, 51, 9, 16, 134, - 170, 48, 9, 16, 134, 170, 51, 9, 16, 134, 170, 225, 10, 246, 112, 48, 9, - 16, 134, 170, 225, 10, 246, 112, 51, 9, 16, 244, 19, 170, 48, 9, 16, 244, - 19, 170, 51, 9, 16, 52, 67, 252, 149, 51, 9, 16, 113, 170, 213, 189, 48, - 9, 16, 113, 170, 213, 189, 51, 9, 16, 222, 236, 9, 16, 4, 217, 82, 48, 9, - 16, 4, 217, 82, 51, 9, 1, 229, 85, 53, 17, 9, 1, 229, 85, 40, 17, 9, 1, - 229, 85, 65, 17, 9, 1, 229, 85, 147, 17, 9, 1, 104, 53, 17, 9, 1, 104, - 40, 17, 9, 1, 226, 239, 53, 17, 9, 1, 226, 239, 40, 17, 9, 1, 210, 213, - 53, 17, 9, 1, 210, 213, 40, 17, 9, 1, 104, 2, 182, 72, 53, 17, 9, 1, 214, - 0, 53, 17, 9, 1, 214, 0, 40, 17, 9, 1, 234, 79, 226, 239, 53, 17, 9, 1, - 234, 79, 226, 239, 40, 17, 9, 1, 234, 79, 210, 213, 53, 17, 9, 1, 234, - 79, 210, 213, 40, 17, 9, 1, 160, 53, 17, 9, 1, 160, 40, 17, 9, 1, 160, - 65, 17, 9, 1, 160, 147, 17, 9, 1, 214, 207, 234, 192, 234, 79, 109, 231, - 198, 65, 17, 9, 1, 214, 207, 234, 192, 234, 79, 109, 231, 198, 147, 17, - 9, 27, 77, 2, 182, 72, 2, 109, 53, 17, 9, 27, 77, 2, 182, 72, 2, 109, 40, - 17, 9, 27, 77, 2, 182, 72, 2, 254, 253, 53, 17, 9, 27, 77, 2, 182, 72, 2, - 254, 253, 40, 17, 9, 27, 77, 2, 182, 72, 2, 212, 31, 53, 17, 9, 27, 77, - 2, 182, 72, 2, 212, 31, 40, 17, 9, 27, 77, 2, 182, 72, 2, 104, 53, 17, 9, - 27, 77, 2, 182, 72, 2, 104, 40, 17, 9, 27, 77, 2, 182, 72, 2, 226, 239, - 53, 17, 9, 27, 77, 2, 182, 72, 2, 226, 239, 40, 17, 9, 27, 77, 2, 182, - 72, 2, 210, 213, 53, 17, 9, 27, 77, 2, 182, 72, 2, 210, 213, 40, 17, 9, - 27, 77, 2, 182, 72, 2, 160, 53, 17, 9, 27, 77, 2, 182, 72, 2, 160, 40, - 17, 9, 27, 77, 2, 182, 72, 2, 160, 65, 17, 9, 27, 214, 207, 234, 79, 77, - 2, 182, 72, 2, 109, 231, 198, 53, 17, 9, 27, 214, 207, 234, 79, 77, 2, - 182, 72, 2, 109, 231, 198, 40, 17, 9, 27, 214, 207, 234, 79, 77, 2, 182, - 72, 2, 109, 231, 198, 65, 17, 9, 1, 244, 176, 77, 53, 17, 9, 1, 244, 176, - 77, 40, 17, 9, 1, 244, 176, 77, 65, 17, 9, 1, 244, 176, 77, 147, 17, 9, - 27, 77, 2, 182, 72, 2, 151, 53, 17, 9, 27, 77, 2, 182, 72, 2, 122, 53, - 17, 9, 27, 77, 2, 182, 72, 2, 66, 53, 17, 9, 27, 77, 2, 182, 72, 2, 109, - 231, 198, 53, 17, 9, 27, 77, 2, 182, 72, 2, 77, 53, 17, 9, 27, 252, 63, - 2, 151, 53, 17, 9, 27, 252, 63, 2, 122, 53, 17, 9, 27, 252, 63, 2, 234, - 136, 53, 17, 9, 27, 252, 63, 2, 66, 53, 17, 9, 27, 252, 63, 2, 109, 231, - 198, 53, 17, 9, 27, 252, 63, 2, 77, 53, 17, 9, 27, 217, 9, 2, 151, 53, - 17, 9, 27, 217, 9, 2, 122, 53, 17, 9, 27, 217, 9, 2, 234, 136, 53, 17, 9, - 27, 217, 9, 2, 66, 53, 17, 9, 27, 217, 9, 2, 109, 231, 198, 53, 17, 9, - 27, 217, 9, 2, 77, 53, 17, 9, 27, 216, 194, 2, 151, 53, 17, 9, 27, 216, - 194, 2, 66, 53, 17, 9, 27, 216, 194, 2, 109, 231, 198, 53, 17, 9, 27, - 216, 194, 2, 77, 53, 17, 9, 27, 151, 2, 122, 53, 17, 9, 27, 151, 2, 66, - 53, 17, 9, 27, 122, 2, 151, 53, 17, 9, 27, 122, 2, 66, 53, 17, 9, 27, - 234, 136, 2, 151, 53, 17, 9, 27, 234, 136, 2, 122, 53, 17, 9, 27, 234, - 136, 2, 66, 53, 17, 9, 27, 221, 169, 2, 151, 53, 17, 9, 27, 221, 169, 2, - 122, 53, 17, 9, 27, 221, 169, 2, 234, 136, 53, 17, 9, 27, 221, 169, 2, - 66, 53, 17, 9, 27, 222, 29, 2, 122, 53, 17, 9, 27, 222, 29, 2, 66, 53, - 17, 9, 27, 248, 225, 2, 151, 53, 17, 9, 27, 248, 225, 2, 122, 53, 17, 9, - 27, 248, 225, 2, 234, 136, 53, 17, 9, 27, 248, 225, 2, 66, 53, 17, 9, 27, - 217, 82, 2, 122, 53, 17, 9, 27, 217, 82, 2, 66, 53, 17, 9, 27, 210, 112, - 2, 66, 53, 17, 9, 27, 254, 206, 2, 151, 53, 17, 9, 27, 254, 206, 2, 66, - 53, 17, 9, 27, 242, 252, 2, 151, 53, 17, 9, 27, 242, 252, 2, 66, 53, 17, - 9, 27, 244, 151, 2, 151, 53, 17, 9, 27, 244, 151, 2, 122, 53, 17, 9, 27, - 244, 151, 2, 234, 136, 53, 17, 9, 27, 244, 151, 2, 66, 53, 17, 9, 27, - 244, 151, 2, 109, 231, 198, 53, 17, 9, 27, 244, 151, 2, 77, 53, 17, 9, - 27, 224, 85, 2, 122, 53, 17, 9, 27, 224, 85, 2, 66, 53, 17, 9, 27, 224, - 85, 2, 109, 231, 198, 53, 17, 9, 27, 224, 85, 2, 77, 53, 17, 9, 27, 235, - 1, 2, 109, 53, 17, 9, 27, 235, 1, 2, 151, 53, 17, 9, 27, 235, 1, 2, 122, - 53, 17, 9, 27, 235, 1, 2, 234, 136, 53, 17, 9, 27, 235, 1, 2, 233, 109, - 53, 17, 9, 27, 235, 1, 2, 66, 53, 17, 9, 27, 235, 1, 2, 109, 231, 198, - 53, 17, 9, 27, 235, 1, 2, 77, 53, 17, 9, 27, 233, 109, 2, 151, 53, 17, 9, - 27, 233, 109, 2, 122, 53, 17, 9, 27, 233, 109, 2, 234, 136, 53, 17, 9, - 27, 233, 109, 2, 66, 53, 17, 9, 27, 233, 109, 2, 109, 231, 198, 53, 17, - 9, 27, 233, 109, 2, 77, 53, 17, 9, 27, 66, 2, 151, 53, 17, 9, 27, 66, 2, - 122, 53, 17, 9, 27, 66, 2, 234, 136, 53, 17, 9, 27, 66, 2, 66, 53, 17, 9, - 27, 66, 2, 109, 231, 198, 53, 17, 9, 27, 66, 2, 77, 53, 17, 9, 27, 228, - 68, 2, 151, 53, 17, 9, 27, 228, 68, 2, 122, 53, 17, 9, 27, 228, 68, 2, - 234, 136, 53, 17, 9, 27, 228, 68, 2, 66, 53, 17, 9, 27, 228, 68, 2, 109, - 231, 198, 53, 17, 9, 27, 228, 68, 2, 77, 53, 17, 9, 27, 241, 226, 2, 151, - 53, 17, 9, 27, 241, 226, 2, 66, 53, 17, 9, 27, 241, 226, 2, 109, 231, - 198, 53, 17, 9, 27, 241, 226, 2, 77, 53, 17, 9, 27, 77, 2, 151, 53, 17, - 9, 27, 77, 2, 122, 53, 17, 9, 27, 77, 2, 234, 136, 53, 17, 9, 27, 77, 2, - 66, 53, 17, 9, 27, 77, 2, 109, 231, 198, 53, 17, 9, 27, 77, 2, 77, 53, - 17, 9, 27, 216, 204, 2, 218, 24, 109, 53, 17, 9, 27, 223, 99, 2, 218, 24, - 109, 53, 17, 9, 27, 109, 231, 198, 2, 218, 24, 109, 53, 17, 9, 27, 220, - 96, 2, 248, 191, 53, 17, 9, 27, 220, 96, 2, 234, 210, 53, 17, 9, 27, 220, - 96, 2, 244, 174, 53, 17, 9, 27, 220, 96, 2, 248, 193, 53, 17, 9, 27, 220, - 96, 2, 234, 212, 53, 17, 9, 27, 220, 96, 2, 218, 24, 109, 53, 17, 9, 27, - 77, 2, 182, 72, 2, 223, 99, 40, 17, 9, 27, 77, 2, 182, 72, 2, 210, 109, - 40, 17, 9, 27, 77, 2, 182, 72, 2, 66, 40, 17, 9, 27, 77, 2, 182, 72, 2, - 228, 68, 40, 17, 9, 27, 77, 2, 182, 72, 2, 109, 231, 198, 40, 17, 9, 27, - 77, 2, 182, 72, 2, 77, 40, 17, 9, 27, 252, 63, 2, 223, 99, 40, 17, 9, 27, - 252, 63, 2, 210, 109, 40, 17, 9, 27, 252, 63, 2, 66, 40, 17, 9, 27, 252, - 63, 2, 228, 68, 40, 17, 9, 27, 252, 63, 2, 109, 231, 198, 40, 17, 9, 27, - 252, 63, 2, 77, 40, 17, 9, 27, 217, 9, 2, 223, 99, 40, 17, 9, 27, 217, 9, - 2, 210, 109, 40, 17, 9, 27, 217, 9, 2, 66, 40, 17, 9, 27, 217, 9, 2, 228, - 68, 40, 17, 9, 27, 217, 9, 2, 109, 231, 198, 40, 17, 9, 27, 217, 9, 2, - 77, 40, 17, 9, 27, 216, 194, 2, 223, 99, 40, 17, 9, 27, 216, 194, 2, 210, - 109, 40, 17, 9, 27, 216, 194, 2, 66, 40, 17, 9, 27, 216, 194, 2, 228, 68, - 40, 17, 9, 27, 216, 194, 2, 109, 231, 198, 40, 17, 9, 27, 216, 194, 2, - 77, 40, 17, 9, 27, 244, 151, 2, 109, 231, 198, 40, 17, 9, 27, 244, 151, - 2, 77, 40, 17, 9, 27, 224, 85, 2, 109, 231, 198, 40, 17, 9, 27, 224, 85, - 2, 77, 40, 17, 9, 27, 235, 1, 2, 109, 40, 17, 9, 27, 235, 1, 2, 233, 109, - 40, 17, 9, 27, 235, 1, 2, 66, 40, 17, 9, 27, 235, 1, 2, 109, 231, 198, - 40, 17, 9, 27, 235, 1, 2, 77, 40, 17, 9, 27, 233, 109, 2, 66, 40, 17, 9, - 27, 233, 109, 2, 109, 231, 198, 40, 17, 9, 27, 233, 109, 2, 77, 40, 17, - 9, 27, 66, 2, 109, 40, 17, 9, 27, 66, 2, 66, 40, 17, 9, 27, 228, 68, 2, - 223, 99, 40, 17, 9, 27, 228, 68, 2, 210, 109, 40, 17, 9, 27, 228, 68, 2, - 66, 40, 17, 9, 27, 228, 68, 2, 228, 68, 40, 17, 9, 27, 228, 68, 2, 109, - 231, 198, 40, 17, 9, 27, 228, 68, 2, 77, 40, 17, 9, 27, 109, 231, 198, 2, - 218, 24, 109, 40, 17, 9, 27, 77, 2, 223, 99, 40, 17, 9, 27, 77, 2, 210, - 109, 40, 17, 9, 27, 77, 2, 66, 40, 17, 9, 27, 77, 2, 228, 68, 40, 17, 9, - 27, 77, 2, 109, 231, 198, 40, 17, 9, 27, 77, 2, 77, 40, 17, 9, 27, 77, 2, - 182, 72, 2, 151, 65, 17, 9, 27, 77, 2, 182, 72, 2, 122, 65, 17, 9, 27, - 77, 2, 182, 72, 2, 234, 136, 65, 17, 9, 27, 77, 2, 182, 72, 2, 66, 65, - 17, 9, 27, 77, 2, 182, 72, 2, 241, 226, 65, 17, 9, 27, 252, 63, 2, 151, - 65, 17, 9, 27, 252, 63, 2, 122, 65, 17, 9, 27, 252, 63, 2, 234, 136, 65, - 17, 9, 27, 252, 63, 2, 66, 65, 17, 9, 27, 252, 63, 2, 241, 226, 65, 17, - 9, 27, 217, 9, 2, 151, 65, 17, 9, 27, 217, 9, 2, 122, 65, 17, 9, 27, 217, - 9, 2, 234, 136, 65, 17, 9, 27, 217, 9, 2, 66, 65, 17, 9, 27, 217, 9, 2, - 241, 226, 65, 17, 9, 27, 216, 194, 2, 66, 65, 17, 9, 27, 151, 2, 122, 65, - 17, 9, 27, 151, 2, 66, 65, 17, 9, 27, 122, 2, 151, 65, 17, 9, 27, 122, 2, - 66, 65, 17, 9, 27, 234, 136, 2, 151, 65, 17, 9, 27, 234, 136, 2, 66, 65, - 17, 9, 27, 221, 169, 2, 151, 65, 17, 9, 27, 221, 169, 2, 122, 65, 17, 9, - 27, 221, 169, 2, 234, 136, 65, 17, 9, 27, 221, 169, 2, 66, 65, 17, 9, 27, - 222, 29, 2, 122, 65, 17, 9, 27, 222, 29, 2, 234, 136, 65, 17, 9, 27, 222, - 29, 2, 66, 65, 17, 9, 27, 248, 225, 2, 151, 65, 17, 9, 27, 248, 225, 2, - 122, 65, 17, 9, 27, 248, 225, 2, 234, 136, 65, 17, 9, 27, 248, 225, 2, - 66, 65, 17, 9, 27, 217, 82, 2, 122, 65, 17, 9, 27, 210, 112, 2, 66, 65, - 17, 9, 27, 254, 206, 2, 151, 65, 17, 9, 27, 254, 206, 2, 66, 65, 17, 9, - 27, 242, 252, 2, 151, 65, 17, 9, 27, 242, 252, 2, 66, 65, 17, 9, 27, 244, - 151, 2, 151, 65, 17, 9, 27, 244, 151, 2, 122, 65, 17, 9, 27, 244, 151, 2, - 234, 136, 65, 17, 9, 27, 244, 151, 2, 66, 65, 17, 9, 27, 224, 85, 2, 122, - 65, 17, 9, 27, 224, 85, 2, 66, 65, 17, 9, 27, 235, 1, 2, 151, 65, 17, 9, - 27, 235, 1, 2, 122, 65, 17, 9, 27, 235, 1, 2, 234, 136, 65, 17, 9, 27, - 235, 1, 2, 233, 109, 65, 17, 9, 27, 235, 1, 2, 66, 65, 17, 9, 27, 233, - 109, 2, 151, 65, 17, 9, 27, 233, 109, 2, 122, 65, 17, 9, 27, 233, 109, 2, - 234, 136, 65, 17, 9, 27, 233, 109, 2, 66, 65, 17, 9, 27, 233, 109, 2, - 241, 226, 65, 17, 9, 27, 66, 2, 151, 65, 17, 9, 27, 66, 2, 122, 65, 17, - 9, 27, 66, 2, 234, 136, 65, 17, 9, 27, 66, 2, 66, 65, 17, 9, 27, 228, 68, - 2, 151, 65, 17, 9, 27, 228, 68, 2, 122, 65, 17, 9, 27, 228, 68, 2, 234, - 136, 65, 17, 9, 27, 228, 68, 2, 66, 65, 17, 9, 27, 228, 68, 2, 241, 226, - 65, 17, 9, 27, 241, 226, 2, 151, 65, 17, 9, 27, 241, 226, 2, 66, 65, 17, - 9, 27, 241, 226, 2, 218, 24, 109, 65, 17, 9, 27, 77, 2, 151, 65, 17, 9, - 27, 77, 2, 122, 65, 17, 9, 27, 77, 2, 234, 136, 65, 17, 9, 27, 77, 2, 66, - 65, 17, 9, 27, 77, 2, 241, 226, 65, 17, 9, 27, 77, 2, 182, 72, 2, 66, - 147, 17, 9, 27, 77, 2, 182, 72, 2, 241, 226, 147, 17, 9, 27, 252, 63, 2, - 66, 147, 17, 9, 27, 252, 63, 2, 241, 226, 147, 17, 9, 27, 217, 9, 2, 66, - 147, 17, 9, 27, 217, 9, 2, 241, 226, 147, 17, 9, 27, 216, 194, 2, 66, - 147, 17, 9, 27, 216, 194, 2, 241, 226, 147, 17, 9, 27, 221, 169, 2, 66, - 147, 17, 9, 27, 221, 169, 2, 241, 226, 147, 17, 9, 27, 220, 62, 2, 66, - 147, 17, 9, 27, 220, 62, 2, 241, 226, 147, 17, 9, 27, 235, 1, 2, 233, - 109, 147, 17, 9, 27, 235, 1, 2, 66, 147, 17, 9, 27, 233, 109, 2, 66, 147, - 17, 9, 27, 228, 68, 2, 66, 147, 17, 9, 27, 228, 68, 2, 241, 226, 147, 17, - 9, 27, 77, 2, 66, 147, 17, 9, 27, 77, 2, 241, 226, 147, 17, 9, 27, 220, - 96, 2, 244, 174, 147, 17, 9, 27, 220, 96, 2, 248, 193, 147, 17, 9, 27, - 220, 96, 2, 234, 212, 147, 17, 9, 27, 217, 82, 2, 109, 231, 198, 53, 17, - 9, 27, 217, 82, 2, 77, 53, 17, 9, 27, 254, 206, 2, 109, 231, 198, 53, 17, - 9, 27, 254, 206, 2, 77, 53, 17, 9, 27, 242, 252, 2, 109, 231, 198, 53, - 17, 9, 27, 242, 252, 2, 77, 53, 17, 9, 27, 221, 169, 2, 109, 231, 198, - 53, 17, 9, 27, 221, 169, 2, 77, 53, 17, 9, 27, 220, 62, 2, 109, 231, 198, - 53, 17, 9, 27, 220, 62, 2, 77, 53, 17, 9, 27, 122, 2, 109, 231, 198, 53, - 17, 9, 27, 122, 2, 77, 53, 17, 9, 27, 151, 2, 109, 231, 198, 53, 17, 9, - 27, 151, 2, 77, 53, 17, 9, 27, 234, 136, 2, 109, 231, 198, 53, 17, 9, 27, - 234, 136, 2, 77, 53, 17, 9, 27, 222, 29, 2, 109, 231, 198, 53, 17, 9, 27, - 222, 29, 2, 77, 53, 17, 9, 27, 248, 225, 2, 109, 231, 198, 53, 17, 9, 27, - 248, 225, 2, 77, 53, 17, 9, 27, 220, 62, 2, 151, 53, 17, 9, 27, 220, 62, - 2, 122, 53, 17, 9, 27, 220, 62, 2, 234, 136, 53, 17, 9, 27, 220, 62, 2, - 66, 53, 17, 9, 27, 220, 62, 2, 223, 99, 53, 17, 9, 27, 221, 169, 2, 223, - 99, 53, 17, 9, 27, 222, 29, 2, 223, 99, 53, 17, 9, 27, 248, 225, 2, 223, - 99, 53, 17, 9, 27, 217, 82, 2, 109, 231, 198, 40, 17, 9, 27, 217, 82, 2, - 77, 40, 17, 9, 27, 254, 206, 2, 109, 231, 198, 40, 17, 9, 27, 254, 206, - 2, 77, 40, 17, 9, 27, 242, 252, 2, 109, 231, 198, 40, 17, 9, 27, 242, - 252, 2, 77, 40, 17, 9, 27, 221, 169, 2, 109, 231, 198, 40, 17, 9, 27, - 221, 169, 2, 77, 40, 17, 9, 27, 220, 62, 2, 109, 231, 198, 40, 17, 9, 27, - 220, 62, 2, 77, 40, 17, 9, 27, 122, 2, 109, 231, 198, 40, 17, 9, 27, 122, - 2, 77, 40, 17, 9, 27, 151, 2, 109, 231, 198, 40, 17, 9, 27, 151, 2, 77, - 40, 17, 9, 27, 234, 136, 2, 109, 231, 198, 40, 17, 9, 27, 234, 136, 2, - 77, 40, 17, 9, 27, 222, 29, 2, 109, 231, 198, 40, 17, 9, 27, 222, 29, 2, - 77, 40, 17, 9, 27, 248, 225, 2, 109, 231, 198, 40, 17, 9, 27, 248, 225, - 2, 77, 40, 17, 9, 27, 220, 62, 2, 151, 40, 17, 9, 27, 220, 62, 2, 122, - 40, 17, 9, 27, 220, 62, 2, 234, 136, 40, 17, 9, 27, 220, 62, 2, 66, 40, - 17, 9, 27, 220, 62, 2, 223, 99, 40, 17, 9, 27, 221, 169, 2, 223, 99, 40, - 17, 9, 27, 222, 29, 2, 223, 99, 40, 17, 9, 27, 248, 225, 2, 223, 99, 40, - 17, 9, 27, 220, 62, 2, 151, 65, 17, 9, 27, 220, 62, 2, 122, 65, 17, 9, - 27, 220, 62, 2, 234, 136, 65, 17, 9, 27, 220, 62, 2, 66, 65, 17, 9, 27, - 221, 169, 2, 241, 226, 65, 17, 9, 27, 220, 62, 2, 241, 226, 65, 17, 9, - 27, 217, 82, 2, 66, 65, 17, 9, 27, 221, 169, 2, 151, 147, 17, 9, 27, 221, - 169, 2, 122, 147, 17, 9, 27, 221, 169, 2, 234, 136, 147, 17, 9, 27, 220, - 62, 2, 151, 147, 17, 9, 27, 220, 62, 2, 122, 147, 17, 9, 27, 220, 62, 2, - 234, 136, 147, 17, 9, 27, 217, 82, 2, 66, 147, 17, 9, 27, 210, 112, 2, - 66, 147, 17, 9, 27, 109, 2, 244, 172, 40, 17, 9, 27, 109, 2, 244, 172, - 53, 17, 226, 150, 43, 226, 7, 226, 150, 44, 226, 7, 9, 27, 217, 9, 2, - 151, 2, 66, 65, 17, 9, 27, 217, 9, 2, 122, 2, 151, 40, 17, 9, 27, 217, 9, - 2, 122, 2, 151, 65, 17, 9, 27, 217, 9, 2, 122, 2, 66, 65, 17, 9, 27, 217, - 9, 2, 234, 136, 2, 66, 65, 17, 9, 27, 217, 9, 2, 66, 2, 151, 65, 17, 9, - 27, 217, 9, 2, 66, 2, 122, 65, 17, 9, 27, 217, 9, 2, 66, 2, 234, 136, 65, - 17, 9, 27, 151, 2, 66, 2, 122, 40, 17, 9, 27, 151, 2, 66, 2, 122, 65, 17, - 9, 27, 122, 2, 66, 2, 77, 40, 17, 9, 27, 122, 2, 66, 2, 109, 231, 198, - 40, 17, 9, 27, 221, 169, 2, 122, 2, 151, 65, 17, 9, 27, 221, 169, 2, 151, - 2, 122, 65, 17, 9, 27, 221, 169, 2, 151, 2, 109, 231, 198, 40, 17, 9, 27, - 221, 169, 2, 66, 2, 122, 40, 17, 9, 27, 221, 169, 2, 66, 2, 122, 65, 17, - 9, 27, 221, 169, 2, 66, 2, 151, 65, 17, 9, 27, 221, 169, 2, 66, 2, 66, - 40, 17, 9, 27, 221, 169, 2, 66, 2, 66, 65, 17, 9, 27, 222, 29, 2, 122, 2, - 122, 40, 17, 9, 27, 222, 29, 2, 122, 2, 122, 65, 17, 9, 27, 222, 29, 2, - 66, 2, 66, 40, 17, 9, 27, 220, 62, 2, 122, 2, 66, 40, 17, 9, 27, 220, 62, - 2, 122, 2, 66, 65, 17, 9, 27, 220, 62, 2, 151, 2, 77, 40, 17, 9, 27, 220, - 62, 2, 66, 2, 234, 136, 40, 17, 9, 27, 220, 62, 2, 66, 2, 234, 136, 65, - 17, 9, 27, 220, 62, 2, 66, 2, 66, 40, 17, 9, 27, 220, 62, 2, 66, 2, 66, - 65, 17, 9, 27, 248, 225, 2, 122, 2, 109, 231, 198, 40, 17, 9, 27, 248, - 225, 2, 234, 136, 2, 66, 40, 17, 9, 27, 248, 225, 2, 234, 136, 2, 66, 65, - 17, 9, 27, 217, 82, 2, 66, 2, 122, 40, 17, 9, 27, 217, 82, 2, 66, 2, 122, - 65, 17, 9, 27, 217, 82, 2, 66, 2, 66, 65, 17, 9, 27, 217, 82, 2, 66, 2, - 77, 40, 17, 9, 27, 254, 206, 2, 151, 2, 66, 40, 17, 9, 27, 254, 206, 2, - 66, 2, 66, 40, 17, 9, 27, 254, 206, 2, 66, 2, 66, 65, 17, 9, 27, 254, - 206, 2, 66, 2, 109, 231, 198, 40, 17, 9, 27, 242, 252, 2, 66, 2, 66, 40, - 17, 9, 27, 242, 252, 2, 66, 2, 77, 40, 17, 9, 27, 242, 252, 2, 66, 2, - 109, 231, 198, 40, 17, 9, 27, 244, 151, 2, 234, 136, 2, 66, 40, 17, 9, - 27, 244, 151, 2, 234, 136, 2, 66, 65, 17, 9, 27, 224, 85, 2, 66, 2, 122, - 40, 17, 9, 27, 224, 85, 2, 66, 2, 66, 40, 17, 9, 27, 233, 109, 2, 122, 2, - 66, 40, 17, 9, 27, 233, 109, 2, 122, 2, 77, 40, 17, 9, 27, 233, 109, 2, - 122, 2, 109, 231, 198, 40, 17, 9, 27, 233, 109, 2, 151, 2, 151, 65, 17, - 9, 27, 233, 109, 2, 151, 2, 151, 40, 17, 9, 27, 233, 109, 2, 234, 136, 2, - 66, 40, 17, 9, 27, 233, 109, 2, 234, 136, 2, 66, 65, 17, 9, 27, 233, 109, - 2, 66, 2, 122, 40, 17, 9, 27, 233, 109, 2, 66, 2, 122, 65, 17, 9, 27, 66, - 2, 122, 2, 151, 65, 17, 9, 27, 66, 2, 122, 2, 66, 65, 17, 9, 27, 66, 2, - 122, 2, 77, 40, 17, 9, 27, 66, 2, 151, 2, 122, 65, 17, 9, 27, 66, 2, 151, - 2, 66, 65, 17, 9, 27, 66, 2, 234, 136, 2, 151, 65, 17, 9, 27, 66, 2, 234, - 136, 2, 66, 65, 17, 9, 27, 66, 2, 151, 2, 234, 136, 65, 17, 9, 27, 241, - 226, 2, 66, 2, 151, 65, 17, 9, 27, 241, 226, 2, 66, 2, 66, 65, 17, 9, 27, - 228, 68, 2, 122, 2, 66, 65, 17, 9, 27, 228, 68, 2, 122, 2, 109, 231, 198, - 40, 17, 9, 27, 228, 68, 2, 151, 2, 66, 40, 17, 9, 27, 228, 68, 2, 151, 2, - 66, 65, 17, 9, 27, 228, 68, 2, 151, 2, 109, 231, 198, 40, 17, 9, 27, 228, - 68, 2, 66, 2, 77, 40, 17, 9, 27, 228, 68, 2, 66, 2, 109, 231, 198, 40, - 17, 9, 27, 77, 2, 66, 2, 66, 40, 17, 9, 27, 77, 2, 66, 2, 66, 65, 17, 9, - 27, 252, 63, 2, 234, 136, 2, 77, 40, 17, 9, 27, 217, 9, 2, 151, 2, 77, - 40, 17, 9, 27, 217, 9, 2, 151, 2, 109, 231, 198, 40, 17, 9, 27, 217, 9, - 2, 234, 136, 2, 77, 40, 17, 9, 27, 217, 9, 2, 234, 136, 2, 109, 231, 198, - 40, 17, 9, 27, 217, 9, 2, 66, 2, 77, 40, 17, 9, 27, 217, 9, 2, 66, 2, - 109, 231, 198, 40, 17, 9, 27, 151, 2, 66, 2, 77, 40, 17, 9, 27, 151, 2, - 122, 2, 109, 231, 198, 40, 17, 9, 27, 151, 2, 66, 2, 109, 231, 198, 40, - 17, 9, 27, 221, 169, 2, 234, 136, 2, 109, 231, 198, 40, 17, 9, 27, 222, - 29, 2, 122, 2, 77, 40, 17, 9, 27, 220, 62, 2, 122, 2, 77, 40, 17, 9, 27, - 248, 225, 2, 122, 2, 77, 40, 17, 9, 27, 233, 109, 2, 151, 2, 77, 40, 17, - 9, 27, 233, 109, 2, 66, 2, 77, 40, 17, 9, 27, 77, 2, 122, 2, 77, 40, 17, - 9, 27, 77, 2, 151, 2, 77, 40, 17, 9, 27, 77, 2, 66, 2, 77, 40, 17, 9, 27, - 66, 2, 66, 2, 77, 40, 17, 9, 27, 224, 85, 2, 66, 2, 77, 40, 17, 9, 27, - 228, 68, 2, 122, 2, 77, 40, 17, 9, 27, 224, 85, 2, 66, 2, 122, 65, 17, 9, - 27, 233, 109, 2, 122, 2, 66, 65, 17, 9, 27, 254, 206, 2, 66, 2, 77, 40, - 17, 9, 27, 235, 1, 2, 66, 2, 77, 40, 17, 9, 27, 228, 68, 2, 151, 2, 122, - 65, 17, 9, 27, 66, 2, 234, 136, 2, 77, 40, 17, 9, 27, 233, 109, 2, 151, - 2, 66, 65, 17, 9, 27, 235, 1, 2, 66, 2, 66, 40, 17, 9, 27, 233, 109, 2, - 151, 2, 66, 40, 17, 9, 27, 228, 68, 2, 151, 2, 122, 40, 17, 9, 27, 151, - 2, 122, 2, 77, 40, 17, 9, 27, 122, 2, 151, 2, 77, 40, 17, 9, 27, 66, 2, - 151, 2, 77, 40, 17, 9, 27, 244, 151, 2, 66, 2, 77, 40, 17, 9, 27, 252, - 63, 2, 122, 2, 77, 40, 17, 9, 27, 235, 1, 2, 66, 2, 66, 65, 17, 9, 27, - 254, 206, 2, 151, 2, 66, 65, 17, 9, 27, 222, 29, 2, 66, 2, 66, 65, 17, 9, - 27, 221, 169, 2, 234, 136, 2, 77, 40, 17, 9, 27, 228, 68, 2, 151, 2, 77, - 40, 17, 9, 27, 222, 6, 214, 128, 253, 246, 234, 10, 218, 132, 5, 53, 17, - 9, 27, 224, 81, 214, 128, 253, 246, 234, 10, 218, 132, 5, 53, 17, 9, 27, - 254, 162, 53, 17, 9, 27, 254, 192, 53, 17, 9, 27, 230, 158, 53, 17, 9, - 27, 222, 7, 53, 17, 9, 27, 223, 146, 53, 17, 9, 27, 254, 181, 53, 17, 9, - 27, 212, 49, 53, 17, 9, 27, 222, 6, 53, 17, 9, 27, 222, 5, 254, 181, 212, - 48, 9, 27, 235, 140, 223, 37, 50, 9, 27, 251, 238, 254, 47, 254, 48, 45, - 221, 158, 45, 221, 47, 45, 220, 235, 45, 220, 224, 45, 220, 213, 45, 220, - 202, 45, 220, 191, 45, 220, 180, 45, 220, 169, 45, 221, 157, 45, 221, - 146, 45, 221, 135, 45, 221, 124, 45, 221, 113, 45, 221, 102, 45, 221, 91, - 224, 197, 244, 28, 31, 67, 249, 227, 224, 197, 244, 28, 31, 67, 110, 249, - 227, 224, 197, 244, 28, 31, 67, 110, 243, 236, 218, 131, 224, 197, 244, - 28, 31, 67, 249, 234, 224, 197, 244, 28, 31, 67, 220, 152, 224, 197, 244, - 28, 31, 67, 245, 39, 79, 224, 197, 244, 28, 31, 67, 224, 16, 79, 224, - 197, 244, 28, 31, 67, 43, 71, 233, 26, 127, 224, 197, 244, 28, 31, 67, - 44, 71, 233, 26, 251, 164, 224, 197, 244, 28, 31, 67, 203, 245, 171, 38, - 27, 43, 242, 34, 38, 27, 44, 242, 34, 38, 52, 216, 90, 43, 242, 34, 38, - 52, 216, 90, 44, 242, 34, 38, 231, 238, 43, 242, 34, 38, 231, 238, 44, - 242, 34, 38, 249, 205, 231, 237, 224, 197, 244, 28, 31, 67, 113, 59, 233, - 62, 224, 197, 244, 28, 31, 67, 245, 168, 248, 164, 224, 197, 244, 28, 31, - 67, 245, 159, 248, 164, 224, 197, 244, 28, 31, 67, 121, 232, 219, 224, - 197, 244, 28, 31, 67, 212, 32, 121, 232, 219, 224, 197, 244, 28, 31, 67, - 43, 226, 7, 224, 197, 244, 28, 31, 67, 44, 226, 7, 224, 197, 244, 28, 31, - 67, 43, 249, 107, 127, 224, 197, 244, 28, 31, 67, 44, 249, 107, 127, 224, - 197, 244, 28, 31, 67, 43, 216, 7, 220, 55, 127, 224, 197, 244, 28, 31, - 67, 44, 216, 7, 220, 55, 127, 224, 197, 244, 28, 31, 67, 43, 85, 233, 26, - 127, 224, 197, 244, 28, 31, 67, 44, 85, 233, 26, 127, 224, 197, 244, 28, - 31, 67, 43, 52, 254, 118, 127, 224, 197, 244, 28, 31, 67, 44, 52, 254, - 118, 127, 224, 197, 244, 28, 31, 67, 43, 254, 118, 127, 224, 197, 244, - 28, 31, 67, 44, 254, 118, 127, 224, 197, 244, 28, 31, 67, 43, 249, 169, - 127, 224, 197, 244, 28, 31, 67, 44, 249, 169, 127, 224, 197, 244, 28, 31, - 67, 43, 71, 249, 169, 127, 224, 197, 244, 28, 31, 67, 44, 71, 249, 169, - 127, 220, 133, 247, 128, 71, 220, 133, 247, 128, 224, 197, 244, 28, 31, - 67, 43, 42, 127, 224, 197, 244, 28, 31, 67, 44, 42, 127, 248, 163, 226, - 123, 250, 180, 226, 123, 212, 32, 226, 123, 52, 212, 32, 226, 123, 248, - 163, 121, 232, 219, 250, 180, 121, 232, 219, 212, 32, 121, 232, 219, 4, - 249, 227, 4, 110, 249, 227, 4, 243, 236, 218, 131, 4, 220, 152, 4, 249, - 234, 4, 224, 16, 79, 4, 245, 39, 79, 4, 245, 168, 248, 164, 4, 43, 226, - 7, 4, 44, 226, 7, 4, 43, 249, 107, 127, 4, 44, 249, 107, 127, 4, 43, 216, - 7, 220, 55, 127, 4, 44, 216, 7, 220, 55, 127, 4, 54, 50, 4, 254, 134, 4, - 253, 224, 4, 96, 50, 4, 240, 174, 4, 233, 21, 50, 4, 242, 137, 50, 4, - 245, 106, 50, 4, 223, 53, 219, 48, 4, 247, 140, 50, 4, 225, 185, 50, 4, - 249, 225, 253, 214, 9, 244, 172, 53, 17, 9, 217, 45, 2, 244, 172, 48, 9, - 248, 191, 53, 17, 9, 217, 79, 244, 9, 9, 234, 210, 53, 17, 9, 244, 174, - 53, 17, 9, 244, 174, 147, 17, 9, 248, 193, 53, 17, 9, 248, 193, 147, 17, - 9, 234, 212, 53, 17, 9, 234, 212, 147, 17, 9, 220, 96, 53, 17, 9, 220, - 96, 147, 17, 9, 218, 47, 53, 17, 9, 218, 47, 147, 17, 9, 1, 182, 53, 17, - 9, 1, 109, 2, 231, 233, 72, 53, 17, 9, 1, 109, 2, 231, 233, 72, 40, 17, - 9, 1, 109, 2, 182, 72, 53, 17, 9, 1, 109, 2, 182, 72, 40, 17, 9, 1, 212, - 31, 2, 182, 72, 53, 17, 9, 1, 212, 31, 2, 182, 72, 40, 17, 9, 1, 109, 2, - 182, 252, 51, 53, 17, 9, 1, 109, 2, 182, 252, 51, 40, 17, 9, 1, 77, 2, - 182, 72, 53, 17, 9, 1, 77, 2, 182, 72, 40, 17, 9, 1, 77, 2, 182, 72, 65, - 17, 9, 1, 77, 2, 182, 72, 147, 17, 9, 1, 109, 53, 17, 9, 1, 109, 40, 17, - 9, 1, 252, 63, 53, 17, 9, 1, 252, 63, 40, 17, 9, 1, 252, 63, 65, 17, 9, - 1, 252, 63, 147, 17, 9, 1, 217, 9, 231, 170, 53, 17, 9, 1, 217, 9, 231, - 170, 40, 17, 9, 1, 217, 9, 53, 17, 9, 1, 217, 9, 40, 17, 9, 1, 217, 9, - 65, 17, 9, 1, 217, 9, 147, 17, 9, 1, 216, 194, 53, 17, 9, 1, 216, 194, - 40, 17, 9, 1, 216, 194, 65, 17, 9, 1, 216, 194, 147, 17, 9, 1, 151, 53, - 17, 9, 1, 151, 40, 17, 9, 1, 151, 65, 17, 9, 1, 151, 147, 17, 9, 1, 122, - 53, 17, 9, 1, 122, 40, 17, 9, 1, 122, 65, 17, 9, 1, 122, 147, 17, 9, 1, - 234, 136, 53, 17, 9, 1, 234, 136, 40, 17, 9, 1, 234, 136, 65, 17, 9, 1, - 234, 136, 147, 17, 9, 1, 248, 204, 53, 17, 9, 1, 248, 204, 40, 17, 9, 1, - 216, 204, 53, 17, 9, 1, 216, 204, 40, 17, 9, 1, 223, 99, 53, 17, 9, 1, - 223, 99, 40, 17, 9, 1, 210, 109, 53, 17, 9, 1, 210, 109, 40, 17, 9, 1, - 221, 169, 53, 17, 9, 1, 221, 169, 40, 17, 9, 1, 221, 169, 65, 17, 9, 1, - 221, 169, 147, 17, 9, 1, 220, 62, 53, 17, 9, 1, 220, 62, 40, 17, 9, 1, - 220, 62, 65, 17, 9, 1, 220, 62, 147, 17, 9, 1, 222, 29, 53, 17, 9, 1, - 222, 29, 40, 17, 9, 1, 222, 29, 65, 17, 9, 1, 222, 29, 147, 17, 9, 1, - 248, 225, 53, 17, 9, 1, 248, 225, 40, 17, 9, 1, 248, 225, 65, 17, 9, 1, - 248, 225, 147, 17, 9, 1, 217, 82, 53, 17, 9, 1, 217, 82, 40, 17, 9, 1, - 217, 82, 65, 17, 9, 1, 217, 82, 147, 17, 9, 1, 210, 112, 53, 17, 9, 1, - 210, 112, 40, 17, 9, 1, 210, 112, 65, 17, 9, 1, 210, 112, 147, 17, 9, 1, - 254, 206, 53, 17, 9, 1, 254, 206, 40, 17, 9, 1, 254, 206, 65, 17, 9, 1, - 254, 206, 147, 17, 9, 1, 242, 252, 53, 17, 9, 1, 242, 252, 40, 17, 9, 1, - 242, 252, 65, 17, 9, 1, 242, 252, 147, 17, 9, 1, 244, 151, 53, 17, 9, 1, - 244, 151, 40, 17, 9, 1, 244, 151, 65, 17, 9, 1, 244, 151, 147, 17, 9, 1, - 224, 85, 53, 17, 9, 1, 224, 85, 40, 17, 9, 1, 224, 85, 65, 17, 9, 1, 224, - 85, 147, 17, 9, 1, 235, 1, 53, 17, 9, 1, 235, 1, 40, 17, 9, 1, 235, 1, - 65, 17, 9, 1, 235, 1, 147, 17, 9, 1, 233, 109, 53, 17, 9, 1, 233, 109, - 40, 17, 9, 1, 233, 109, 65, 17, 9, 1, 233, 109, 147, 17, 9, 1, 66, 53, - 17, 9, 1, 66, 40, 17, 9, 1, 66, 65, 17, 9, 1, 66, 147, 17, 9, 1, 228, 68, - 53, 17, 9, 1, 228, 68, 40, 17, 9, 1, 228, 68, 65, 17, 9, 1, 228, 68, 147, - 17, 9, 1, 241, 226, 53, 17, 9, 1, 241, 226, 40, 17, 9, 1, 241, 226, 65, - 17, 9, 1, 241, 226, 147, 17, 9, 1, 212, 31, 53, 17, 9, 1, 212, 31, 40, - 17, 9, 1, 109, 231, 198, 53, 17, 9, 1, 109, 231, 198, 40, 17, 9, 1, 77, - 53, 17, 9, 1, 77, 40, 17, 9, 1, 77, 65, 17, 9, 1, 77, 147, 17, 9, 27, - 233, 109, 2, 109, 2, 231, 233, 72, 53, 17, 9, 27, 233, 109, 2, 109, 2, - 231, 233, 72, 40, 17, 9, 27, 233, 109, 2, 109, 2, 182, 72, 53, 17, 9, 27, - 233, 109, 2, 109, 2, 182, 72, 40, 17, 9, 27, 233, 109, 2, 109, 2, 182, - 252, 51, 53, 17, 9, 27, 233, 109, 2, 109, 2, 182, 252, 51, 40, 17, 9, 27, - 233, 109, 2, 109, 53, 17, 9, 27, 233, 109, 2, 109, 40, 17, 210, 87, 211, - 245, 228, 78, 219, 20, 126, 245, 39, 79, 126, 224, 1, 79, 126, 54, 50, - 126, 247, 140, 50, 126, 225, 185, 50, 126, 254, 134, 126, 254, 65, 126, - 43, 226, 7, 126, 44, 226, 7, 126, 253, 224, 126, 96, 50, 126, 249, 227, - 126, 240, 174, 126, 243, 236, 218, 131, 126, 219, 48, 126, 21, 210, 86, - 126, 21, 111, 126, 21, 105, 126, 21, 158, 126, 21, 161, 126, 21, 190, - 126, 21, 195, 126, 21, 199, 126, 21, 196, 126, 21, 201, 126, 249, 234, - 126, 220, 152, 126, 233, 21, 50, 126, 245, 106, 50, 126, 242, 137, 50, - 126, 224, 16, 79, 126, 249, 225, 253, 214, 126, 7, 6, 1, 61, 126, 7, 6, - 1, 253, 166, 126, 7, 6, 1, 251, 74, 126, 7, 6, 1, 249, 68, 126, 7, 6, 1, - 76, 126, 7, 6, 1, 245, 14, 126, 7, 6, 1, 243, 209, 126, 7, 6, 1, 242, 67, - 126, 7, 6, 1, 74, 126, 7, 6, 1, 235, 150, 126, 7, 6, 1, 235, 29, 126, 7, - 6, 1, 156, 126, 7, 6, 1, 194, 126, 7, 6, 1, 230, 30, 126, 7, 6, 1, 78, - 126, 7, 6, 1, 226, 109, 126, 7, 6, 1, 224, 99, 126, 7, 6, 1, 153, 126, 7, - 6, 1, 222, 93, 126, 7, 6, 1, 217, 153, 126, 7, 6, 1, 69, 126, 7, 6, 1, - 214, 105, 126, 7, 6, 1, 212, 98, 126, 7, 6, 1, 211, 178, 126, 7, 6, 1, - 211, 117, 126, 7, 6, 1, 210, 159, 126, 43, 42, 127, 126, 223, 53, 219, - 48, 126, 44, 42, 127, 126, 250, 39, 255, 23, 126, 121, 232, 219, 126, - 242, 144, 255, 23, 126, 7, 4, 1, 61, 126, 7, 4, 1, 253, 166, 126, 7, 4, - 1, 251, 74, 126, 7, 4, 1, 249, 68, 126, 7, 4, 1, 76, 126, 7, 4, 1, 245, - 14, 126, 7, 4, 1, 243, 209, 126, 7, 4, 1, 242, 67, 126, 7, 4, 1, 74, 126, - 7, 4, 1, 235, 150, 126, 7, 4, 1, 235, 29, 126, 7, 4, 1, 156, 126, 7, 4, - 1, 194, 126, 7, 4, 1, 230, 30, 126, 7, 4, 1, 78, 126, 7, 4, 1, 226, 109, - 126, 7, 4, 1, 224, 99, 126, 7, 4, 1, 153, 126, 7, 4, 1, 222, 93, 126, 7, - 4, 1, 217, 153, 126, 7, 4, 1, 69, 126, 7, 4, 1, 214, 105, 126, 7, 4, 1, - 212, 98, 126, 7, 4, 1, 211, 178, 126, 7, 4, 1, 211, 117, 126, 7, 4, 1, - 210, 159, 126, 43, 249, 107, 127, 126, 67, 232, 219, 126, 44, 249, 107, - 127, 126, 184, 126, 43, 71, 226, 7, 126, 44, 71, 226, 7, 101, 110, 243, - 236, 218, 131, 101, 43, 249, 169, 127, 101, 44, 249, 169, 127, 101, 110, - 249, 227, 101, 56, 230, 229, 247, 128, 101, 56, 1, 211, 227, 101, 56, 1, - 4, 61, 101, 56, 1, 4, 74, 101, 56, 1, 4, 69, 101, 56, 1, 4, 76, 101, 56, - 1, 4, 78, 101, 56, 1, 4, 192, 101, 56, 1, 4, 210, 212, 101, 56, 1, 4, - 210, 244, 101, 56, 1, 4, 215, 119, 101, 234, 207, 224, 176, 219, 33, 79, - 101, 56, 1, 61, 101, 56, 1, 74, 101, 56, 1, 69, 101, 56, 1, 76, 101, 56, - 1, 78, 101, 56, 1, 176, 101, 56, 1, 234, 98, 101, 56, 1, 233, 223, 101, - 56, 1, 234, 188, 101, 56, 1, 234, 34, 101, 56, 1, 206, 101, 56, 1, 219, - 193, 101, 56, 1, 218, 84, 101, 56, 1, 221, 183, 101, 56, 1, 219, 60, 101, - 56, 1, 217, 106, 101, 56, 1, 216, 118, 101, 56, 1, 215, 119, 101, 56, 1, - 217, 23, 101, 56, 1, 112, 101, 56, 1, 198, 101, 56, 1, 228, 238, 101, 56, - 1, 227, 242, 101, 56, 1, 229, 112, 101, 56, 1, 228, 79, 101, 56, 1, 162, - 101, 56, 1, 241, 187, 101, 56, 1, 240, 229, 101, 56, 1, 241, 245, 101, - 56, 1, 241, 75, 101, 56, 1, 186, 101, 56, 1, 230, 235, 101, 56, 1, 230, - 107, 101, 56, 1, 231, 96, 101, 56, 1, 230, 166, 101, 56, 1, 192, 101, 56, - 1, 210, 212, 101, 56, 1, 210, 244, 101, 56, 1, 205, 101, 56, 1, 223, 38, - 101, 56, 1, 222, 142, 101, 56, 1, 223, 131, 101, 56, 1, 222, 213, 101, - 56, 1, 212, 65, 101, 56, 1, 230, 30, 101, 56, 213, 135, 219, 33, 79, 101, - 56, 220, 157, 219, 33, 79, 101, 24, 244, 111, 101, 24, 1, 234, 64, 101, - 24, 1, 218, 217, 101, 24, 1, 234, 57, 101, 24, 1, 228, 231, 101, 24, 1, - 228, 229, 101, 24, 1, 228, 228, 101, 24, 1, 216, 102, 101, 24, 1, 218, - 206, 101, 24, 1, 223, 29, 101, 24, 1, 223, 24, 101, 24, 1, 223, 21, 101, - 24, 1, 223, 14, 101, 24, 1, 223, 9, 101, 24, 1, 223, 4, 101, 24, 1, 223, - 15, 101, 24, 1, 223, 27, 101, 24, 1, 230, 222, 101, 24, 1, 225, 98, 101, - 24, 1, 218, 214, 101, 24, 1, 225, 87, 101, 24, 1, 219, 150, 101, 24, 1, - 218, 211, 101, 24, 1, 236, 63, 101, 24, 1, 250, 54, 101, 24, 1, 218, 221, - 101, 24, 1, 250, 114, 101, 24, 1, 234, 116, 101, 24, 1, 216, 174, 101, - 24, 1, 225, 134, 101, 24, 1, 241, 179, 101, 24, 1, 61, 101, 24, 1, 254, - 252, 101, 24, 1, 192, 101, 24, 1, 211, 92, 101, 24, 1, 245, 125, 101, 24, - 1, 76, 101, 24, 1, 211, 36, 101, 24, 1, 211, 47, 101, 24, 1, 78, 101, 24, - 1, 212, 65, 101, 24, 1, 212, 62, 101, 24, 1, 226, 238, 101, 24, 1, 210, - 244, 101, 24, 1, 69, 101, 24, 1, 212, 11, 101, 24, 1, 212, 22, 101, 24, - 1, 211, 250, 101, 24, 1, 210, 212, 101, 24, 1, 245, 63, 101, 24, 1, 211, - 8, 101, 24, 1, 74, 126, 250, 184, 50, 126, 224, 231, 50, 126, 228, 57, - 50, 126, 231, 237, 126, 251, 143, 130, 126, 211, 40, 50, 126, 211, 217, - 50, 101, 244, 26, 193, 213, 239, 101, 140, 75, 101, 214, 153, 75, 101, - 97, 75, 101, 246, 112, 75, 101, 85, 218, 236, 101, 71, 250, 43, 235, 211, - 254, 107, 254, 128, 235, 211, 254, 107, 220, 139, 235, 211, 254, 107, - 216, 237, 226, 253, 223, 75, 250, 150, 223, 75, 250, 150, 62, 57, 3, 253, - 150, 61, 62, 57, 3, 253, 119, 76, 62, 57, 3, 253, 128, 74, 62, 57, 3, - 253, 96, 78, 62, 57, 3, 253, 146, 69, 62, 57, 3, 253, 165, 248, 229, 62, - 57, 3, 253, 112, 248, 98, 62, 57, 3, 253, 152, 248, 11, 62, 57, 3, 253, - 142, 247, 153, 62, 57, 3, 253, 106, 246, 86, 62, 57, 3, 253, 100, 235, - 147, 62, 57, 3, 253, 111, 235, 132, 62, 57, 3, 253, 121, 235, 74, 62, 57, - 3, 253, 92, 235, 57, 62, 57, 3, 253, 80, 176, 62, 57, 3, 253, 113, 234, - 188, 62, 57, 3, 253, 90, 234, 98, 62, 57, 3, 253, 87, 234, 34, 62, 57, 3, - 253, 76, 233, 223, 62, 57, 3, 253, 77, 186, 62, 57, 3, 253, 143, 231, 96, - 62, 57, 3, 253, 84, 230, 235, 62, 57, 3, 253, 141, 230, 166, 62, 57, 3, - 253, 133, 230, 107, 62, 57, 3, 253, 154, 198, 62, 57, 3, 253, 132, 229, - 112, 62, 57, 3, 253, 126, 228, 238, 62, 57, 3, 253, 105, 228, 79, 62, 57, - 3, 253, 102, 227, 242, 62, 57, 3, 253, 161, 191, 62, 57, 3, 253, 85, 225, - 224, 62, 57, 3, 253, 118, 225, 111, 62, 57, 3, 253, 145, 225, 19, 62, 57, - 3, 253, 107, 224, 153, 62, 57, 3, 253, 140, 224, 91, 62, 57, 3, 253, 79, - 224, 72, 62, 57, 3, 253, 135, 224, 56, 62, 57, 3, 253, 124, 224, 45, 62, - 57, 3, 253, 97, 205, 62, 57, 3, 253, 129, 223, 131, 62, 57, 3, 253, 104, - 223, 38, 62, 57, 3, 253, 163, 222, 213, 62, 57, 3, 253, 130, 222, 142, - 62, 57, 3, 253, 125, 206, 62, 57, 3, 253, 148, 221, 183, 62, 57, 3, 253, - 116, 219, 193, 62, 57, 3, 253, 144, 219, 60, 62, 57, 3, 253, 99, 218, 84, - 62, 57, 3, 253, 98, 217, 106, 62, 57, 3, 253, 159, 217, 23, 62, 57, 3, - 253, 120, 216, 118, 62, 57, 3, 253, 157, 112, 62, 57, 3, 253, 88, 215, - 119, 62, 57, 3, 253, 103, 212, 65, 62, 57, 3, 253, 82, 212, 22, 62, 57, - 3, 253, 117, 211, 250, 62, 57, 3, 253, 115, 211, 227, 62, 57, 3, 253, - 139, 210, 116, 62, 57, 3, 253, 83, 210, 94, 62, 57, 3, 253, 136, 210, 23, - 62, 57, 3, 253, 131, 255, 84, 62, 57, 3, 253, 114, 255, 83, 62, 57, 3, - 253, 73, 253, 200, 62, 57, 3, 253, 86, 246, 54, 62, 57, 3, 253, 69, 246, - 53, 62, 57, 3, 253, 109, 227, 178, 62, 57, 3, 253, 127, 224, 151, 62, 57, - 3, 253, 95, 224, 155, 62, 57, 3, 253, 81, 223, 189, 62, 57, 3, 253, 123, - 223, 188, 62, 57, 3, 253, 89, 222, 212, 62, 57, 3, 253, 91, 217, 103, 62, - 57, 3, 253, 71, 215, 78, 62, 57, 3, 253, 68, 105, 62, 57, 16, 253, 138, - 62, 57, 16, 253, 137, 62, 57, 16, 253, 134, 62, 57, 16, 253, 122, 62, 57, - 16, 253, 110, 62, 57, 16, 253, 108, 62, 57, 16, 253, 101, 62, 57, 16, - 253, 94, 62, 57, 16, 253, 93, 62, 57, 16, 253, 78, 62, 57, 16, 253, 75, - 62, 57, 16, 253, 74, 62, 57, 16, 253, 72, 62, 57, 16, 253, 70, 62, 57, - 106, 253, 67, 231, 190, 62, 57, 106, 253, 66, 211, 221, 62, 57, 106, 253, - 65, 248, 82, 62, 57, 106, 253, 64, 245, 103, 62, 57, 106, 253, 63, 231, - 164, 62, 57, 106, 253, 62, 218, 164, 62, 57, 106, 253, 61, 245, 45, 62, - 57, 106, 253, 60, 223, 156, 62, 57, 106, 253, 59, 220, 64, 62, 57, 106, - 253, 58, 241, 244, 62, 57, 106, 253, 57, 219, 27, 62, 57, 106, 253, 56, - 251, 211, 62, 57, 106, 253, 55, 249, 153, 62, 57, 106, 253, 54, 251, 123, - 62, 57, 106, 253, 53, 212, 2, 62, 57, 106, 253, 52, 252, 144, 62, 57, - 106, 253, 51, 226, 209, 62, 57, 106, 253, 50, 219, 0, 62, 57, 106, 253, - 49, 249, 76, 62, 57, 230, 147, 253, 48, 234, 230, 62, 57, 230, 147, 253, - 47, 234, 238, 62, 57, 106, 253, 46, 226, 222, 62, 57, 106, 253, 45, 211, - 236, 62, 57, 106, 253, 44, 62, 57, 230, 147, 253, 43, 254, 25, 62, 57, - 230, 147, 253, 42, 231, 57, 62, 57, 106, 253, 41, 251, 142, 62, 57, 106, - 253, 40, 242, 173, 62, 57, 106, 253, 39, 62, 57, 106, 253, 38, 211, 212, - 62, 57, 106, 253, 37, 62, 57, 106, 253, 36, 62, 57, 106, 253, 35, 240, - 255, 62, 57, 106, 253, 34, 62, 57, 106, 253, 33, 62, 57, 106, 253, 32, - 62, 57, 230, 147, 253, 30, 215, 92, 62, 57, 106, 253, 29, 62, 57, 106, - 253, 28, 62, 57, 106, 253, 27, 250, 2, 62, 57, 106, 253, 26, 62, 57, 106, - 253, 25, 62, 57, 106, 253, 24, 243, 100, 62, 57, 106, 253, 23, 254, 12, - 62, 57, 106, 253, 22, 62, 57, 106, 253, 21, 62, 57, 106, 253, 20, 62, 57, - 106, 253, 19, 62, 57, 106, 253, 18, 62, 57, 106, 253, 17, 62, 57, 106, - 253, 16, 62, 57, 106, 253, 15, 62, 57, 106, 253, 14, 62, 57, 106, 253, - 13, 230, 139, 62, 57, 106, 253, 12, 62, 57, 106, 253, 11, 215, 236, 62, - 57, 106, 253, 10, 62, 57, 106, 253, 9, 62, 57, 106, 253, 8, 62, 57, 106, - 253, 7, 62, 57, 106, 253, 6, 62, 57, 106, 253, 5, 62, 57, 106, 253, 4, - 62, 57, 106, 253, 3, 62, 57, 106, 253, 2, 62, 57, 106, 253, 1, 62, 57, - 106, 253, 0, 62, 57, 106, 252, 255, 241, 218, 62, 57, 106, 252, 234, 244, - 36, 62, 57, 106, 252, 231, 252, 124, 62, 57, 106, 252, 226, 219, 7, 62, - 57, 106, 252, 225, 75, 62, 57, 106, 252, 224, 62, 57, 106, 252, 223, 217, - 237, 62, 57, 106, 252, 222, 62, 57, 106, 252, 221, 62, 57, 106, 252, 220, - 211, 254, 250, 147, 62, 57, 106, 252, 219, 250, 147, 62, 57, 106, 252, - 218, 250, 148, 244, 7, 62, 57, 106, 252, 217, 212, 0, 62, 57, 106, 252, - 216, 62, 57, 106, 252, 215, 62, 57, 230, 147, 252, 214, 247, 206, 62, 57, - 106, 252, 213, 62, 57, 106, 252, 212, 62, 57, 106, 252, 210, 62, 57, 106, - 252, 209, 62, 57, 106, 252, 208, 62, 57, 106, 252, 207, 248, 167, 62, 57, - 106, 252, 206, 62, 57, 106, 252, 205, 62, 57, 106, 252, 204, 62, 57, 106, - 252, 203, 62, 57, 106, 252, 202, 62, 57, 106, 213, 186, 253, 31, 62, 57, - 106, 213, 186, 252, 254, 62, 57, 106, 213, 186, 252, 253, 62, 57, 106, - 213, 186, 252, 252, 62, 57, 106, 213, 186, 252, 251, 62, 57, 106, 213, - 186, 252, 250, 62, 57, 106, 213, 186, 252, 249, 62, 57, 106, 213, 186, - 252, 248, 62, 57, 106, 213, 186, 252, 247, 62, 57, 106, 213, 186, 252, - 246, 62, 57, 106, 213, 186, 252, 245, 62, 57, 106, 213, 186, 252, 244, - 62, 57, 106, 213, 186, 252, 243, 62, 57, 106, 213, 186, 252, 242, 62, 57, - 106, 213, 186, 252, 241, 62, 57, 106, 213, 186, 252, 240, 62, 57, 106, - 213, 186, 252, 239, 62, 57, 106, 213, 186, 252, 238, 62, 57, 106, 213, - 186, 252, 237, 62, 57, 106, 213, 186, 252, 236, 62, 57, 106, 213, 186, - 252, 235, 62, 57, 106, 213, 186, 252, 233, 62, 57, 106, 213, 186, 252, - 232, 62, 57, 106, 213, 186, 252, 230, 62, 57, 106, 213, 186, 252, 229, - 62, 57, 106, 213, 186, 252, 228, 62, 57, 106, 213, 186, 252, 227, 62, 57, - 106, 213, 186, 252, 211, 62, 57, 106, 213, 186, 252, 201, 254, 245, 211, - 209, 220, 140, 232, 219, 254, 245, 211, 209, 220, 140, 247, 128, 254, - 245, 250, 138, 79, 254, 245, 54, 111, 254, 245, 54, 105, 254, 245, 54, - 158, 254, 245, 54, 161, 254, 245, 54, 190, 254, 245, 54, 195, 254, 245, - 54, 199, 254, 245, 54, 196, 254, 245, 54, 201, 254, 245, 54, 216, 248, - 254, 245, 54, 215, 73, 254, 245, 54, 216, 163, 254, 245, 54, 244, 23, - 254, 245, 54, 244, 122, 254, 245, 54, 219, 113, 254, 245, 54, 220, 118, - 254, 245, 54, 245, 192, 254, 245, 54, 228, 200, 254, 245, 54, 123, 240, - 217, 254, 245, 54, 113, 240, 217, 254, 245, 54, 134, 240, 217, 254, 245, - 54, 244, 19, 240, 217, 254, 245, 54, 244, 89, 240, 217, 254, 245, 54, - 219, 127, 240, 217, 254, 245, 54, 220, 124, 240, 217, 254, 245, 54, 245, - 201, 240, 217, 254, 245, 54, 228, 205, 240, 217, 254, 245, 54, 123, 216, - 148, 254, 245, 54, 113, 216, 148, 254, 245, 54, 134, 216, 148, 254, 245, - 54, 244, 19, 216, 148, 254, 245, 54, 244, 89, 216, 148, 254, 245, 54, - 219, 127, 216, 148, 254, 245, 54, 220, 124, 216, 148, 254, 245, 54, 245, - 201, 216, 148, 254, 245, 54, 228, 205, 216, 148, 254, 245, 54, 216, 249, - 216, 148, 254, 245, 54, 215, 74, 216, 148, 254, 245, 54, 216, 164, 216, - 148, 254, 245, 54, 244, 24, 216, 148, 254, 245, 54, 244, 123, 216, 148, - 254, 245, 54, 219, 114, 216, 148, 254, 245, 54, 220, 119, 216, 148, 254, - 245, 54, 245, 193, 216, 148, 254, 245, 54, 228, 201, 216, 148, 254, 245, - 212, 14, 252, 136, 214, 173, 254, 245, 212, 14, 244, 100, 218, 60, 254, - 245, 212, 14, 221, 178, 218, 60, 254, 245, 212, 14, 216, 170, 218, 60, - 254, 245, 212, 14, 244, 12, 218, 60, 254, 245, 246, 89, 231, 95, 244, - 100, 218, 60, 254, 245, 232, 205, 231, 95, 244, 100, 218, 60, 254, 245, - 231, 95, 221, 178, 218, 60, 254, 245, 231, 95, 216, 170, 218, 60, 26, - 255, 15, 253, 202, 123, 224, 24, 26, 255, 15, 253, 202, 123, 242, 34, 26, - 255, 15, 253, 202, 123, 246, 108, 26, 255, 15, 253, 202, 190, 26, 255, - 15, 253, 202, 244, 122, 26, 255, 15, 253, 202, 244, 89, 240, 217, 26, - 255, 15, 253, 202, 244, 89, 216, 148, 26, 255, 15, 253, 202, 244, 123, - 216, 148, 26, 255, 15, 253, 202, 244, 89, 217, 68, 26, 255, 15, 253, 202, - 216, 249, 217, 68, 26, 255, 15, 253, 202, 244, 123, 217, 68, 26, 255, 15, - 253, 202, 123, 240, 218, 217, 68, 26, 255, 15, 253, 202, 244, 89, 240, - 218, 217, 68, 26, 255, 15, 253, 202, 123, 216, 149, 217, 68, 26, 255, 15, - 253, 202, 244, 89, 216, 149, 217, 68, 26, 255, 15, 253, 202, 244, 89, - 218, 152, 26, 255, 15, 253, 202, 216, 249, 218, 152, 26, 255, 15, 253, - 202, 244, 123, 218, 152, 26, 255, 15, 253, 202, 123, 240, 218, 218, 152, - 26, 255, 15, 253, 202, 244, 89, 240, 218, 218, 152, 26, 255, 15, 253, - 202, 123, 216, 149, 218, 152, 26, 255, 15, 253, 202, 216, 249, 216, 149, - 218, 152, 26, 255, 15, 253, 202, 244, 123, 216, 149, 218, 152, 26, 255, - 15, 253, 202, 216, 249, 230, 169, 26, 255, 15, 241, 212, 123, 225, 34, - 26, 255, 15, 216, 182, 111, 26, 255, 15, 241, 208, 111, 26, 255, 15, 245, - 112, 105, 26, 255, 15, 216, 182, 105, 26, 255, 15, 249, 73, 113, 246, - 107, 26, 255, 15, 245, 112, 113, 246, 107, 26, 255, 15, 215, 204, 190, - 26, 255, 15, 215, 204, 216, 248, 26, 255, 15, 215, 204, 216, 249, 254, - 149, 17, 26, 255, 15, 241, 208, 216, 248, 26, 255, 15, 231, 46, 216, 248, - 26, 255, 15, 216, 182, 216, 248, 26, 255, 15, 216, 182, 216, 163, 26, - 255, 15, 215, 204, 244, 122, 26, 255, 15, 215, 204, 244, 123, 254, 149, - 17, 26, 255, 15, 241, 208, 244, 122, 26, 255, 15, 216, 182, 244, 122, 26, - 255, 15, 216, 182, 123, 240, 217, 26, 255, 15, 216, 182, 134, 240, 217, - 26, 255, 15, 245, 112, 244, 89, 240, 217, 26, 255, 15, 215, 204, 244, 89, - 240, 217, 26, 255, 15, 216, 182, 244, 89, 240, 217, 26, 255, 15, 250, - 235, 244, 89, 240, 217, 26, 255, 15, 229, 187, 244, 89, 240, 217, 26, - 255, 15, 216, 182, 123, 216, 148, 26, 255, 15, 216, 182, 244, 89, 216, - 148, 26, 255, 15, 248, 65, 244, 89, 230, 169, 26, 255, 15, 218, 120, 244, - 123, 230, 169, 26, 123, 163, 50, 26, 123, 163, 5, 254, 149, 17, 26, 113, - 216, 168, 50, 26, 134, 224, 23, 50, 26, 211, 45, 50, 26, 217, 69, 50, 26, - 246, 109, 50, 26, 226, 250, 50, 26, 113, 226, 249, 50, 26, 134, 226, 249, - 50, 26, 244, 19, 226, 249, 50, 26, 244, 89, 226, 249, 50, 26, 231, 40, - 50, 26, 233, 163, 252, 136, 50, 26, 232, 200, 50, 26, 226, 135, 50, 26, - 211, 159, 50, 26, 253, 251, 50, 26, 254, 8, 50, 26, 242, 151, 50, 26, - 215, 187, 252, 136, 50, 26, 210, 87, 50, 222, 200, 220, 115, 50, 222, - 200, 214, 185, 50, 222, 200, 220, 144, 50, 222, 200, 220, 113, 50, 222, - 200, 247, 221, 220, 113, 50, 222, 200, 219, 170, 50, 222, 200, 248, 61, - 50, 222, 200, 224, 9, 50, 222, 200, 220, 131, 50, 222, 200, 246, 68, 50, - 222, 200, 253, 246, 50, 222, 200, 250, 179, 50, 225, 146, 247, 199, 5, - 225, 216, 225, 146, 247, 199, 5, 225, 27, 241, 242, 225, 146, 247, 199, - 5, 217, 46, 241, 242, 225, 146, 247, 199, 5, 250, 255, 225, 146, 247, - 199, 5, 250, 109, 225, 146, 247, 199, 5, 211, 221, 225, 146, 247, 199, 5, - 241, 218, 225, 146, 247, 199, 5, 243, 92, 225, 146, 247, 199, 5, 216, - 117, 225, 146, 247, 199, 5, 75, 225, 146, 247, 199, 5, 251, 177, 225, - 146, 247, 199, 5, 220, 31, 225, 146, 247, 199, 5, 249, 252, 225, 146, - 247, 199, 5, 231, 189, 225, 146, 247, 199, 5, 231, 141, 225, 146, 247, - 199, 5, 221, 218, 225, 146, 247, 199, 5, 232, 243, 225, 146, 247, 199, 5, - 251, 196, 225, 146, 247, 199, 5, 250, 239, 225, 38, 225, 146, 247, 199, - 5, 247, 141, 225, 146, 247, 199, 5, 249, 231, 225, 146, 247, 199, 5, 219, - 89, 225, 146, 247, 199, 5, 249, 232, 225, 146, 247, 199, 5, 252, 71, 225, - 146, 247, 199, 5, 220, 18, 225, 146, 247, 199, 5, 240, 255, 225, 146, - 247, 199, 5, 241, 185, 225, 146, 247, 199, 5, 251, 120, 233, 42, 225, - 146, 247, 199, 5, 250, 232, 225, 146, 247, 199, 5, 223, 156, 225, 146, - 247, 199, 5, 245, 238, 225, 146, 247, 199, 5, 246, 115, 225, 146, 247, - 199, 5, 215, 106, 225, 146, 247, 199, 5, 252, 74, 225, 146, 247, 199, 5, - 225, 39, 215, 236, 225, 146, 247, 199, 5, 213, 159, 225, 146, 247, 199, - 5, 226, 22, 225, 146, 247, 199, 5, 222, 192, 225, 146, 247, 199, 5, 232, - 230, 225, 146, 247, 199, 5, 226, 119, 252, 192, 225, 146, 247, 199, 5, - 244, 56, 225, 146, 247, 199, 5, 242, 145, 225, 146, 247, 199, 5, 218, - 121, 225, 146, 247, 199, 5, 4, 253, 176, 225, 146, 247, 199, 5, 212, 32, - 252, 156, 225, 146, 247, 199, 5, 38, 226, 252, 91, 232, 65, 1, 61, 232, - 65, 1, 76, 232, 65, 1, 253, 166, 232, 65, 1, 252, 27, 232, 65, 1, 243, - 209, 232, 65, 1, 249, 68, 232, 65, 1, 74, 232, 65, 1, 212, 98, 232, 65, - 1, 210, 159, 232, 65, 1, 216, 211, 232, 65, 1, 235, 150, 232, 65, 1, 235, - 29, 232, 65, 1, 224, 99, 232, 65, 1, 156, 232, 65, 1, 194, 232, 65, 1, - 230, 30, 232, 65, 1, 230, 171, 232, 65, 1, 228, 116, 232, 65, 1, 69, 232, - 65, 1, 226, 109, 232, 65, 1, 234, 53, 232, 65, 1, 153, 232, 65, 1, 222, - 93, 232, 65, 1, 217, 153, 232, 65, 1, 215, 160, 232, 65, 1, 254, 131, - 232, 65, 1, 245, 158, 232, 65, 1, 242, 67, 232, 65, 1, 211, 178, 250, - 245, 1, 61, 250, 245, 1, 226, 95, 250, 245, 1, 249, 68, 250, 245, 1, 156, - 250, 245, 1, 214, 116, 250, 245, 1, 153, 250, 245, 1, 233, 68, 250, 245, - 1, 255, 84, 250, 245, 1, 224, 99, 250, 245, 1, 253, 166, 250, 245, 1, - 194, 250, 245, 1, 78, 250, 245, 1, 248, 231, 250, 245, 1, 217, 153, 250, - 245, 1, 220, 106, 250, 245, 1, 220, 105, 250, 245, 1, 222, 93, 250, 245, - 1, 251, 73, 250, 245, 1, 69, 250, 245, 1, 228, 116, 250, 245, 1, 211, - 178, 250, 245, 1, 230, 30, 250, 245, 1, 215, 159, 250, 245, 1, 226, 109, - 250, 245, 1, 218, 228, 250, 245, 1, 74, 250, 245, 1, 76, 250, 245, 1, - 214, 113, 250, 245, 1, 235, 29, 250, 245, 1, 235, 20, 250, 245, 1, 229, - 155, 250, 245, 1, 214, 118, 250, 245, 1, 243, 209, 250, 245, 1, 243, 144, - 250, 245, 1, 218, 170, 250, 245, 1, 218, 169, 250, 245, 1, 229, 84, 250, - 245, 1, 236, 40, 250, 245, 1, 251, 72, 250, 245, 1, 215, 160, 250, 245, - 1, 214, 115, 250, 245, 1, 222, 182, 250, 245, 1, 231, 134, 250, 245, 1, - 231, 133, 250, 245, 1, 231, 132, 250, 245, 1, 231, 131, 250, 245, 1, 233, - 67, 250, 245, 1, 245, 242, 250, 245, 1, 214, 114, 55, 32, 1, 61, 55, 32, - 1, 252, 83, 55, 32, 1, 234, 188, 55, 32, 1, 248, 98, 55, 32, 1, 76, 55, - 32, 1, 213, 255, 55, 32, 1, 210, 94, 55, 32, 1, 241, 245, 55, 32, 1, 216, - 196, 55, 32, 1, 74, 55, 32, 1, 176, 55, 32, 1, 245, 182, 55, 32, 1, 245, - 167, 55, 32, 1, 245, 158, 55, 32, 1, 245, 83, 55, 32, 1, 78, 55, 32, 1, - 225, 224, 55, 32, 1, 220, 65, 55, 32, 1, 233, 223, 55, 32, 1, 245, 100, - 55, 32, 1, 245, 90, 55, 32, 1, 217, 23, 55, 32, 1, 69, 55, 32, 1, 245, - 185, 55, 32, 1, 225, 139, 55, 32, 1, 234, 125, 55, 32, 1, 245, 210, 55, - 32, 1, 245, 92, 55, 32, 1, 250, 139, 55, 32, 1, 236, 40, 55, 32, 1, 214, - 118, 55, 32, 227, 202, 111, 55, 32, 227, 202, 190, 55, 32, 227, 202, 216, - 248, 55, 32, 227, 202, 244, 122, 242, 160, 1, 254, 213, 242, 160, 1, 252, - 171, 242, 160, 1, 242, 218, 242, 160, 1, 248, 212, 242, 160, 1, 254, 209, - 242, 160, 1, 224, 82, 242, 160, 1, 235, 161, 242, 160, 1, 242, 46, 242, - 160, 1, 216, 159, 242, 160, 1, 245, 191, 242, 160, 1, 233, 196, 242, 160, - 1, 233, 119, 242, 160, 1, 231, 184, 242, 160, 1, 229, 189, 242, 160, 1, - 235, 125, 242, 160, 1, 214, 136, 242, 160, 1, 226, 73, 242, 160, 1, 228, - 200, 242, 160, 1, 223, 168, 242, 160, 1, 221, 220, 242, 160, 1, 217, 5, - 242, 160, 1, 211, 234, 242, 160, 1, 244, 186, 242, 160, 1, 236, 44, 242, - 160, 1, 240, 206, 242, 160, 1, 226, 143, 242, 160, 1, 228, 205, 240, 217, - 214, 209, 1, 254, 155, 214, 209, 1, 252, 34, 214, 209, 1, 243, 115, 214, - 209, 1, 234, 138, 214, 209, 1, 248, 62, 214, 209, 1, 241, 75, 214, 209, - 1, 211, 227, 214, 209, 1, 210, 85, 214, 209, 1, 240, 248, 214, 209, 1, - 216, 231, 214, 209, 1, 210, 233, 214, 209, 1, 235, 0, 214, 209, 1, 220, - 22, 214, 209, 1, 233, 104, 214, 209, 1, 231, 70, 214, 209, 1, 248, 29, - 214, 209, 1, 227, 198, 214, 209, 1, 210, 13, 214, 209, 1, 221, 250, 214, - 209, 1, 254, 205, 214, 209, 1, 224, 153, 214, 209, 1, 222, 27, 214, 209, - 1, 224, 38, 214, 209, 1, 223, 147, 214, 209, 1, 216, 200, 214, 209, 1, - 242, 251, 214, 209, 1, 112, 214, 209, 1, 74, 214, 209, 1, 69, 214, 209, - 1, 218, 181, 214, 209, 211, 209, 247, 180, 55, 225, 172, 5, 61, 55, 225, - 172, 5, 74, 55, 225, 172, 5, 69, 55, 225, 172, 5, 176, 55, 225, 172, 5, - 233, 223, 55, 225, 172, 5, 243, 142, 55, 225, 172, 5, 242, 120, 55, 225, - 172, 5, 211, 165, 55, 225, 172, 5, 251, 41, 55, 225, 172, 5, 235, 147, - 55, 225, 172, 5, 235, 114, 55, 225, 172, 5, 217, 106, 55, 225, 172, 5, - 215, 119, 55, 225, 172, 5, 248, 229, 55, 225, 172, 5, 248, 11, 55, 225, - 172, 5, 246, 86, 55, 225, 172, 5, 216, 209, 55, 225, 172, 5, 191, 55, - 225, 172, 5, 252, 199, 55, 225, 172, 5, 244, 204, 55, 225, 172, 5, 198, - 55, 225, 172, 5, 227, 242, 55, 225, 172, 5, 186, 55, 225, 172, 5, 230, - 235, 55, 225, 172, 5, 230, 107, 55, 225, 172, 5, 192, 55, 225, 172, 5, - 214, 27, 55, 225, 172, 5, 213, 176, 55, 225, 172, 5, 205, 55, 225, 172, - 5, 222, 142, 55, 225, 172, 5, 233, 141, 55, 225, 172, 5, 206, 55, 225, - 172, 5, 210, 116, 55, 225, 172, 5, 220, 104, 55, 225, 172, 5, 218, 225, - 55, 225, 172, 5, 162, 55, 225, 172, 5, 253, 194, 55, 225, 172, 5, 253, - 193, 55, 225, 172, 5, 253, 192, 55, 225, 172, 5, 211, 142, 55, 225, 172, - 5, 248, 208, 55, 225, 172, 5, 248, 207, 55, 225, 172, 5, 252, 178, 55, - 225, 172, 5, 251, 93, 55, 225, 172, 211, 209, 247, 180, 55, 225, 172, 54, - 111, 55, 225, 172, 54, 105, 55, 225, 172, 54, 216, 248, 55, 225, 172, 54, - 215, 73, 55, 225, 172, 54, 240, 217, 181, 6, 1, 200, 74, 181, 6, 1, 200, - 76, 181, 6, 1, 200, 61, 181, 6, 1, 200, 254, 218, 181, 6, 1, 200, 78, - 181, 6, 1, 200, 226, 187, 181, 6, 1, 219, 253, 74, 181, 6, 1, 219, 253, - 76, 181, 6, 1, 219, 253, 61, 181, 6, 1, 219, 253, 254, 218, 181, 6, 1, - 219, 253, 78, 181, 6, 1, 219, 253, 226, 187, 181, 6, 1, 253, 175, 181, 6, - 1, 226, 120, 181, 6, 1, 211, 195, 181, 6, 1, 211, 44, 181, 6, 1, 242, 67, - 181, 6, 1, 225, 214, 181, 6, 1, 252, 74, 181, 6, 1, 217, 12, 181, 6, 1, - 248, 85, 181, 6, 1, 250, 136, 181, 6, 1, 235, 130, 181, 6, 1, 234, 195, - 181, 6, 1, 243, 90, 181, 6, 1, 245, 210, 181, 6, 1, 213, 250, 181, 6, 1, - 245, 67, 181, 6, 1, 216, 195, 181, 6, 1, 245, 90, 181, 6, 1, 210, 92, - 181, 6, 1, 245, 83, 181, 6, 1, 210, 73, 181, 6, 1, 245, 100, 181, 6, 1, - 245, 182, 181, 6, 1, 245, 167, 181, 6, 1, 245, 158, 181, 6, 1, 245, 146, - 181, 6, 1, 226, 223, 181, 6, 1, 245, 46, 181, 4, 1, 200, 74, 181, 4, 1, - 200, 76, 181, 4, 1, 200, 61, 181, 4, 1, 200, 254, 218, 181, 4, 1, 200, - 78, 181, 4, 1, 200, 226, 187, 181, 4, 1, 219, 253, 74, 181, 4, 1, 219, - 253, 76, 181, 4, 1, 219, 253, 61, 181, 4, 1, 219, 253, 254, 218, 181, 4, - 1, 219, 253, 78, 181, 4, 1, 219, 253, 226, 187, 181, 4, 1, 253, 175, 181, - 4, 1, 226, 120, 181, 4, 1, 211, 195, 181, 4, 1, 211, 44, 181, 4, 1, 242, - 67, 181, 4, 1, 225, 214, 181, 4, 1, 252, 74, 181, 4, 1, 217, 12, 181, 4, - 1, 248, 85, 181, 4, 1, 250, 136, 181, 4, 1, 235, 130, 181, 4, 1, 234, - 195, 181, 4, 1, 243, 90, 181, 4, 1, 245, 210, 181, 4, 1, 213, 250, 181, - 4, 1, 245, 67, 181, 4, 1, 216, 195, 181, 4, 1, 245, 90, 181, 4, 1, 210, - 92, 181, 4, 1, 245, 83, 181, 4, 1, 210, 73, 181, 4, 1, 245, 100, 181, 4, - 1, 245, 182, 181, 4, 1, 245, 167, 181, 4, 1, 245, 158, 181, 4, 1, 245, - 146, 181, 4, 1, 226, 223, 181, 4, 1, 245, 46, 220, 71, 1, 225, 212, 220, - 71, 1, 216, 6, 220, 71, 1, 234, 97, 220, 71, 1, 244, 155, 220, 71, 1, - 216, 173, 220, 71, 1, 219, 60, 220, 71, 1, 218, 15, 220, 71, 1, 250, 69, - 220, 71, 1, 211, 46, 220, 71, 1, 240, 216, 220, 71, 1, 252, 13, 220, 71, - 1, 248, 97, 220, 71, 1, 243, 128, 220, 71, 1, 213, 123, 220, 71, 1, 216, - 177, 220, 71, 1, 210, 21, 220, 71, 1, 231, 94, 220, 71, 1, 235, 55, 220, - 71, 1, 211, 225, 220, 71, 1, 242, 55, 220, 71, 1, 232, 148, 220, 71, 1, - 230, 194, 220, 71, 1, 236, 47, 220, 71, 1, 245, 209, 220, 71, 1, 253, - 239, 220, 71, 1, 255, 0, 220, 71, 1, 226, 200, 220, 71, 1, 211, 212, 220, - 71, 1, 226, 134, 220, 71, 1, 254, 218, 220, 71, 1, 222, 210, 220, 71, 1, - 227, 198, 220, 71, 1, 245, 225, 220, 71, 1, 254, 223, 220, 71, 1, 240, - 118, 220, 71, 1, 214, 163, 220, 71, 1, 227, 2, 220, 71, 1, 226, 180, 220, - 71, 1, 226, 222, 220, 71, 1, 253, 178, 220, 71, 1, 254, 27, 220, 71, 1, - 226, 162, 220, 71, 1, 254, 201, 220, 71, 1, 245, 94, 220, 71, 1, 254, 5, - 220, 71, 1, 245, 235, 220, 71, 1, 240, 125, 220, 71, 1, 211, 13, 226, - 145, 1, 254, 179, 226, 145, 1, 252, 199, 226, 145, 1, 217, 106, 226, 145, - 1, 235, 147, 226, 145, 1, 211, 165, 226, 145, 1, 234, 138, 226, 145, 1, - 248, 84, 226, 145, 1, 205, 226, 145, 1, 206, 226, 145, 1, 220, 28, 226, - 145, 1, 248, 33, 226, 145, 1, 250, 223, 226, 145, 1, 243, 142, 226, 145, - 1, 244, 204, 226, 145, 1, 224, 89, 226, 145, 1, 235, 15, 226, 145, 1, - 233, 136, 226, 145, 1, 230, 205, 226, 145, 1, 227, 182, 226, 145, 1, 212, - 30, 226, 145, 1, 162, 226, 145, 1, 192, 226, 145, 1, 61, 226, 145, 1, 76, - 226, 145, 1, 74, 226, 145, 1, 78, 226, 145, 1, 69, 226, 145, 1, 255, 82, - 226, 145, 1, 245, 217, 226, 145, 1, 226, 187, 226, 145, 21, 210, 86, 226, - 145, 21, 111, 226, 145, 21, 105, 226, 145, 21, 158, 226, 145, 21, 161, - 226, 145, 21, 190, 226, 145, 21, 195, 226, 145, 21, 199, 226, 145, 21, - 196, 226, 145, 21, 201, 249, 75, 3, 61, 249, 75, 3, 76, 249, 75, 3, 74, - 249, 75, 3, 78, 249, 75, 3, 69, 249, 75, 3, 235, 147, 249, 75, 3, 235, - 74, 249, 75, 3, 176, 249, 75, 3, 234, 188, 249, 75, 3, 234, 98, 249, 75, - 3, 234, 34, 249, 75, 3, 233, 223, 249, 75, 3, 233, 141, 249, 75, 3, 233, - 64, 249, 75, 3, 232, 247, 249, 75, 3, 232, 162, 249, 75, 3, 232, 103, - 249, 75, 3, 186, 249, 75, 3, 231, 96, 249, 75, 3, 230, 235, 249, 75, 3, - 230, 166, 249, 75, 3, 230, 107, 249, 75, 3, 198, 249, 75, 3, 229, 112, - 249, 75, 3, 228, 238, 249, 75, 3, 228, 79, 249, 75, 3, 227, 242, 249, 75, - 3, 191, 249, 75, 3, 225, 224, 249, 75, 3, 225, 111, 249, 75, 3, 225, 19, - 249, 75, 3, 224, 153, 249, 75, 3, 205, 249, 75, 3, 223, 131, 249, 75, 3, - 223, 38, 249, 75, 3, 222, 213, 249, 75, 3, 222, 142, 249, 75, 3, 206, - 249, 75, 3, 221, 183, 249, 75, 3, 219, 193, 249, 75, 3, 219, 60, 249, 75, - 3, 218, 84, 249, 75, 3, 217, 106, 249, 75, 3, 217, 23, 249, 75, 3, 216, - 118, 249, 75, 3, 112, 249, 75, 3, 215, 119, 249, 75, 3, 212, 65, 249, 75, - 3, 212, 22, 249, 75, 3, 211, 250, 249, 75, 3, 211, 227, 249, 75, 3, 211, - 165, 249, 75, 3, 211, 162, 249, 75, 3, 210, 116, 249, 75, 3, 210, 23, - 236, 8, 254, 35, 1, 254, 177, 236, 8, 254, 35, 1, 252, 33, 236, 8, 254, - 35, 1, 242, 208, 236, 8, 254, 35, 1, 248, 196, 236, 8, 254, 35, 1, 241, - 245, 236, 8, 254, 35, 1, 212, 30, 236, 8, 254, 35, 1, 210, 97, 236, 8, - 254, 35, 1, 241, 202, 236, 8, 254, 35, 1, 216, 227, 236, 8, 254, 35, 1, - 210, 232, 236, 8, 254, 35, 1, 234, 231, 236, 8, 254, 35, 1, 233, 99, 236, - 8, 254, 35, 1, 231, 70, 236, 8, 254, 35, 1, 227, 198, 236, 8, 254, 35, 1, - 221, 251, 236, 8, 254, 35, 1, 253, 170, 236, 8, 254, 35, 1, 225, 224, - 236, 8, 254, 35, 1, 222, 26, 236, 8, 254, 35, 1, 224, 37, 236, 8, 254, - 35, 1, 223, 70, 236, 8, 254, 35, 1, 220, 22, 236, 8, 254, 35, 1, 217, 37, - 236, 8, 254, 35, 221, 175, 50, 236, 8, 254, 35, 54, 111, 236, 8, 254, 35, - 54, 105, 236, 8, 254, 35, 54, 158, 236, 8, 254, 35, 54, 216, 248, 236, 8, - 254, 35, 54, 215, 73, 236, 8, 254, 35, 54, 123, 240, 217, 236, 8, 254, - 35, 54, 123, 216, 148, 236, 8, 254, 35, 54, 216, 249, 216, 148, 225, 122, - 1, 254, 174, 225, 122, 1, 252, 36, 225, 122, 1, 243, 116, 225, 122, 1, - 248, 64, 225, 122, 1, 241, 245, 225, 122, 1, 212, 37, 225, 122, 1, 210, - 110, 225, 122, 1, 241, 204, 225, 122, 1, 216, 231, 225, 122, 1, 210, 233, - 225, 122, 1, 235, 0, 225, 122, 1, 233, 105, 225, 122, 1, 231, 70, 225, - 122, 1, 227, 198, 225, 122, 1, 220, 146, 225, 122, 1, 254, 205, 225, 122, - 1, 225, 224, 225, 122, 1, 222, 27, 225, 122, 1, 224, 42, 225, 122, 1, - 222, 191, 225, 122, 1, 220, 22, 225, 122, 1, 217, 42, 225, 122, 54, 111, - 225, 122, 54, 216, 248, 225, 122, 54, 215, 73, 225, 122, 54, 123, 240, - 217, 225, 122, 54, 105, 225, 122, 54, 158, 225, 122, 211, 209, 220, 139, - 232, 64, 1, 61, 232, 64, 1, 253, 166, 232, 64, 1, 243, 209, 232, 64, 1, - 249, 68, 232, 64, 1, 76, 232, 64, 1, 214, 105, 232, 64, 1, 74, 232, 64, - 1, 211, 117, 232, 64, 1, 235, 29, 232, 64, 1, 156, 232, 64, 1, 194, 232, - 64, 1, 230, 30, 232, 64, 1, 78, 232, 64, 1, 153, 232, 64, 1, 218, 228, - 232, 64, 1, 217, 153, 232, 64, 1, 69, 232, 64, 1, 245, 14, 232, 64, 1, - 224, 99, 232, 64, 1, 222, 93, 232, 64, 1, 215, 160, 232, 64, 1, 254, 131, - 232, 64, 1, 245, 158, 232, 64, 1, 232, 67, 232, 64, 1, 228, 116, 232, 64, - 1, 251, 74, 232, 64, 215, 223, 79, 231, 53, 241, 181, 1, 61, 231, 53, - 241, 181, 1, 76, 231, 53, 241, 181, 1, 74, 231, 53, 241, 181, 1, 78, 231, - 53, 241, 181, 1, 192, 231, 53, 241, 181, 1, 212, 65, 231, 53, 241, 181, - 1, 252, 199, 231, 53, 241, 181, 1, 252, 198, 231, 53, 241, 181, 1, 191, - 231, 53, 241, 181, 1, 186, 231, 53, 241, 181, 1, 198, 231, 53, 241, 181, - 1, 229, 233, 231, 53, 241, 181, 1, 229, 112, 231, 53, 241, 181, 1, 229, - 111, 231, 53, 241, 181, 1, 205, 231, 53, 241, 181, 1, 223, 190, 231, 53, - 241, 181, 1, 233, 141, 231, 53, 241, 181, 1, 234, 138, 231, 53, 241, 181, - 1, 241, 196, 231, 53, 241, 181, 1, 206, 231, 53, 241, 181, 1, 222, 35, - 231, 53, 241, 181, 1, 221, 183, 231, 53, 241, 181, 1, 176, 231, 53, 241, - 181, 1, 224, 91, 231, 53, 241, 181, 1, 217, 106, 231, 53, 241, 181, 1, - 217, 105, 231, 53, 241, 181, 1, 217, 23, 231, 53, 241, 181, 1, 217, 22, - 231, 53, 241, 181, 1, 112, 231, 53, 241, 181, 1, 248, 229, 231, 53, 241, - 181, 16, 213, 170, 231, 53, 241, 181, 16, 213, 169, 231, 53, 249, 102, 1, - 61, 231, 53, 249, 102, 1, 76, 231, 53, 249, 102, 1, 74, 231, 53, 249, - 102, 1, 78, 231, 53, 249, 102, 1, 192, 231, 53, 249, 102, 1, 212, 65, - 231, 53, 249, 102, 1, 252, 199, 231, 53, 249, 102, 1, 191, 231, 53, 249, - 102, 1, 186, 231, 53, 249, 102, 1, 198, 231, 53, 249, 102, 1, 229, 112, - 231, 53, 249, 102, 1, 205, 231, 53, 249, 102, 1, 233, 141, 231, 53, 249, - 102, 1, 234, 138, 231, 53, 249, 102, 1, 241, 196, 231, 53, 249, 102, 1, - 206, 231, 53, 249, 102, 1, 254, 31, 206, 231, 53, 249, 102, 1, 221, 183, - 231, 53, 249, 102, 1, 176, 231, 53, 249, 102, 1, 224, 91, 231, 53, 249, - 102, 1, 217, 106, 231, 53, 249, 102, 1, 217, 23, 231, 53, 249, 102, 1, - 112, 231, 53, 249, 102, 1, 248, 229, 231, 53, 249, 102, 232, 151, 222, - 219, 231, 53, 249, 102, 232, 151, 236, 13, 234, 126, 1, 61, 234, 126, 25, - 5, 74, 234, 126, 25, 5, 69, 234, 126, 25, 5, 149, 153, 234, 126, 25, 5, - 76, 234, 126, 25, 5, 78, 234, 126, 25, 233, 29, 79, 234, 126, 5, 52, 222, - 237, 51, 234, 126, 5, 254, 83, 234, 126, 5, 213, 147, 234, 126, 1, 176, - 234, 126, 1, 234, 138, 234, 126, 1, 243, 142, 234, 126, 1, 243, 0, 234, - 126, 1, 251, 41, 234, 126, 1, 250, 165, 234, 126, 1, 235, 147, 234, 126, - 1, 227, 169, 234, 126, 1, 215, 157, 234, 126, 1, 215, 145, 234, 126, 1, - 248, 143, 234, 126, 1, 248, 127, 234, 126, 1, 228, 115, 234, 126, 1, 217, - 106, 234, 126, 1, 216, 209, 234, 126, 1, 248, 229, 234, 126, 1, 248, 33, - 234, 126, 1, 198, 234, 126, 1, 191, 234, 126, 1, 225, 150, 234, 126, 1, - 252, 199, 234, 126, 1, 252, 26, 234, 126, 1, 186, 234, 126, 1, 192, 234, - 126, 1, 205, 234, 126, 1, 233, 141, 234, 126, 1, 214, 27, 234, 126, 1, - 220, 104, 234, 126, 1, 218, 225, 234, 126, 1, 206, 234, 126, 1, 210, 116, - 234, 126, 1, 162, 234, 126, 1, 234, 52, 234, 126, 1, 215, 125, 234, 126, - 5, 252, 149, 48, 234, 126, 5, 250, 229, 234, 126, 5, 59, 51, 234, 126, - 213, 152, 234, 126, 21, 111, 234, 126, 21, 105, 234, 126, 21, 158, 234, - 126, 21, 161, 234, 126, 54, 216, 248, 234, 126, 54, 215, 73, 234, 126, - 54, 123, 240, 217, 234, 126, 54, 123, 216, 148, 234, 126, 224, 144, 247, - 128, 234, 126, 224, 144, 4, 250, 43, 234, 126, 224, 144, 250, 43, 234, - 126, 224, 144, 249, 145, 130, 234, 126, 224, 144, 231, 185, 234, 126, - 224, 144, 232, 121, 234, 126, 224, 144, 248, 186, 234, 126, 224, 144, 52, - 248, 186, 234, 126, 224, 144, 232, 213, 55, 219, 30, 254, 46, 1, 241, - 245, 55, 219, 30, 254, 46, 1, 233, 99, 55, 219, 30, 254, 46, 1, 241, 202, - 55, 219, 30, 254, 46, 1, 231, 70, 55, 219, 30, 254, 46, 1, 224, 37, 55, - 219, 30, 254, 46, 1, 212, 30, 55, 219, 30, 254, 46, 1, 220, 22, 55, 219, - 30, 254, 46, 1, 223, 70, 55, 219, 30, 254, 46, 1, 252, 33, 55, 219, 30, - 254, 46, 1, 217, 37, 55, 219, 30, 254, 46, 1, 221, 228, 55, 219, 30, 254, - 46, 1, 234, 231, 55, 219, 30, 254, 46, 1, 227, 198, 55, 219, 30, 254, 46, - 1, 234, 122, 55, 219, 30, 254, 46, 1, 222, 26, 55, 219, 30, 254, 46, 1, - 221, 251, 55, 219, 30, 254, 46, 1, 244, 162, 55, 219, 30, 254, 46, 1, - 254, 179, 55, 219, 30, 254, 46, 1, 253, 169, 55, 219, 30, 254, 46, 1, - 248, 30, 55, 219, 30, 254, 46, 1, 242, 208, 55, 219, 30, 254, 46, 1, 248, - 196, 55, 219, 30, 254, 46, 1, 242, 245, 55, 219, 30, 254, 46, 1, 216, - 227, 55, 219, 30, 254, 46, 1, 210, 96, 55, 219, 30, 254, 46, 1, 248, 27, - 55, 219, 30, 254, 46, 1, 210, 232, 55, 219, 30, 254, 46, 1, 216, 198, 55, - 219, 30, 254, 46, 1, 216, 179, 55, 219, 30, 254, 46, 54, 111, 55, 219, - 30, 254, 46, 54, 244, 122, 55, 219, 30, 254, 46, 132, 235, 245, 253, 180, - 1, 61, 253, 180, 1, 255, 82, 253, 180, 1, 254, 81, 253, 180, 1, 255, 41, - 253, 180, 1, 254, 131, 253, 180, 1, 255, 42, 253, 180, 1, 254, 252, 253, - 180, 1, 254, 248, 253, 180, 1, 76, 253, 180, 1, 245, 217, 253, 180, 1, - 78, 253, 180, 1, 226, 187, 253, 180, 1, 74, 253, 180, 1, 236, 40, 253, - 180, 1, 69, 253, 180, 1, 214, 118, 253, 180, 1, 234, 188, 253, 180, 1, - 211, 162, 253, 180, 1, 211, 128, 253, 180, 1, 211, 137, 253, 180, 1, 243, - 69, 253, 180, 1, 243, 31, 253, 180, 1, 242, 243, 253, 180, 1, 250, 198, - 253, 180, 1, 235, 132, 253, 180, 1, 217, 23, 253, 180, 1, 216, 196, 253, - 180, 1, 248, 98, 253, 180, 1, 248, 25, 253, 180, 1, 215, 152, 253, 180, - 1, 225, 224, 253, 180, 1, 244, 162, 253, 180, 1, 252, 83, 253, 180, 1, - 252, 22, 253, 180, 1, 229, 69, 253, 180, 1, 228, 244, 253, 180, 1, 228, - 245, 253, 180, 1, 229, 112, 253, 180, 1, 227, 160, 253, 180, 1, 228, 110, - 253, 180, 1, 231, 96, 253, 180, 1, 241, 123, 253, 180, 1, 210, 166, 253, - 180, 1, 211, 47, 253, 180, 1, 213, 255, 253, 180, 1, 223, 131, 253, 180, - 1, 233, 64, 253, 180, 1, 221, 183, 253, 180, 1, 210, 94, 253, 180, 1, - 220, 65, 253, 180, 1, 210, 74, 253, 180, 1, 219, 200, 253, 180, 1, 218, - 195, 253, 180, 1, 241, 245, 253, 180, 255, 30, 79, 216, 80, 113, 170, - 115, 123, 59, 224, 143, 4, 113, 170, 115, 123, 59, 224, 143, 233, 91, - 113, 170, 115, 123, 59, 224, 143, 233, 91, 123, 59, 115, 113, 170, 224, - 143, 233, 91, 113, 222, 235, 115, 123, 222, 237, 224, 143, 233, 91, 123, - 222, 237, 115, 113, 222, 235, 224, 143, 235, 225, 226, 2, 1, 254, 177, - 235, 225, 226, 2, 1, 252, 33, 235, 225, 226, 2, 1, 242, 208, 235, 225, - 226, 2, 1, 248, 196, 235, 225, 226, 2, 1, 241, 245, 235, 225, 226, 2, 1, - 212, 30, 235, 225, 226, 2, 1, 210, 97, 235, 225, 226, 2, 1, 241, 202, - 235, 225, 226, 2, 1, 216, 227, 235, 225, 226, 2, 1, 210, 232, 235, 225, - 226, 2, 1, 234, 231, 235, 225, 226, 2, 1, 233, 99, 235, 225, 226, 2, 1, - 231, 70, 235, 225, 226, 2, 1, 227, 198, 235, 225, 226, 2, 1, 221, 251, - 235, 225, 226, 2, 1, 253, 170, 235, 225, 226, 2, 1, 225, 224, 235, 225, - 226, 2, 1, 222, 26, 235, 225, 226, 2, 1, 224, 37, 235, 225, 226, 2, 1, - 223, 70, 235, 225, 226, 2, 1, 220, 22, 235, 225, 226, 2, 1, 217, 37, 235, - 225, 226, 2, 54, 111, 235, 225, 226, 2, 54, 105, 235, 225, 226, 2, 54, - 158, 235, 225, 226, 2, 54, 161, 235, 225, 226, 2, 54, 216, 248, 235, 225, - 226, 2, 54, 215, 73, 235, 225, 226, 2, 54, 123, 240, 217, 235, 225, 226, - 2, 54, 123, 216, 148, 235, 225, 226, 76, 1, 254, 177, 235, 225, 226, 76, - 1, 252, 33, 235, 225, 226, 76, 1, 242, 208, 235, 225, 226, 76, 1, 248, - 196, 235, 225, 226, 76, 1, 241, 245, 235, 225, 226, 76, 1, 212, 29, 235, - 225, 226, 76, 1, 210, 97, 235, 225, 226, 76, 1, 241, 202, 235, 225, 226, - 76, 1, 216, 227, 235, 225, 226, 76, 1, 210, 232, 235, 225, 226, 76, 1, - 234, 231, 235, 225, 226, 76, 1, 233, 99, 235, 225, 226, 76, 1, 231, 69, - 235, 225, 226, 76, 1, 227, 198, 235, 225, 226, 76, 1, 221, 251, 235, 225, - 226, 76, 1, 225, 224, 235, 225, 226, 76, 1, 222, 26, 235, 225, 226, 76, - 1, 220, 22, 235, 225, 226, 76, 1, 217, 37, 235, 225, 226, 76, 54, 111, - 235, 225, 226, 76, 54, 105, 235, 225, 226, 76, 54, 158, 235, 225, 226, - 76, 54, 161, 235, 225, 226, 76, 54, 216, 248, 235, 225, 226, 76, 54, 215, - 73, 235, 225, 226, 76, 54, 123, 240, 217, 235, 225, 226, 76, 54, 123, - 216, 148, 55, 202, 1, 226, 153, 61, 55, 202, 1, 211, 37, 61, 55, 202, 1, - 211, 37, 254, 252, 55, 202, 1, 226, 153, 74, 55, 202, 1, 211, 37, 74, 55, - 202, 1, 211, 37, 76, 55, 202, 1, 226, 153, 78, 55, 202, 1, 226, 153, 226, - 238, 55, 202, 1, 211, 37, 226, 238, 55, 202, 1, 226, 153, 255, 34, 55, - 202, 1, 211, 37, 255, 34, 55, 202, 1, 226, 153, 254, 251, 55, 202, 1, - 211, 37, 254, 251, 55, 202, 1, 226, 153, 254, 225, 55, 202, 1, 211, 37, - 254, 225, 55, 202, 1, 226, 153, 254, 246, 55, 202, 1, 211, 37, 254, 246, - 55, 202, 1, 226, 153, 255, 8, 55, 202, 1, 211, 37, 255, 8, 55, 202, 1, - 226, 153, 254, 250, 55, 202, 1, 226, 153, 245, 20, 55, 202, 1, 211, 37, - 245, 20, 55, 202, 1, 226, 153, 253, 175, 55, 202, 1, 211, 37, 253, 175, - 55, 202, 1, 226, 153, 254, 233, 55, 202, 1, 211, 37, 254, 233, 55, 202, - 1, 226, 153, 254, 244, 55, 202, 1, 211, 37, 254, 244, 55, 202, 1, 226, - 153, 226, 237, 55, 202, 1, 211, 37, 226, 237, 55, 202, 1, 226, 153, 254, - 187, 55, 202, 1, 211, 37, 254, 187, 55, 202, 1, 226, 153, 254, 243, 55, - 202, 1, 226, 153, 245, 169, 55, 202, 1, 226, 153, 245, 167, 55, 202, 1, - 226, 153, 254, 131, 55, 202, 1, 226, 153, 254, 241, 55, 202, 1, 211, 37, - 254, 241, 55, 202, 1, 226, 153, 245, 139, 55, 202, 1, 211, 37, 245, 139, - 55, 202, 1, 226, 153, 245, 155, 55, 202, 1, 211, 37, 245, 155, 55, 202, - 1, 226, 153, 245, 126, 55, 202, 1, 211, 37, 245, 126, 55, 202, 1, 211, - 37, 254, 123, 55, 202, 1, 226, 153, 245, 146, 55, 202, 1, 211, 37, 254, - 240, 55, 202, 1, 226, 153, 245, 116, 55, 202, 1, 226, 153, 226, 179, 55, - 202, 1, 226, 153, 240, 120, 55, 202, 1, 226, 153, 245, 223, 55, 202, 1, - 211, 37, 245, 223, 55, 202, 1, 226, 153, 254, 53, 55, 202, 1, 211, 37, - 254, 53, 55, 202, 1, 226, 153, 235, 188, 55, 202, 1, 211, 37, 235, 188, - 55, 202, 1, 226, 153, 226, 163, 55, 202, 1, 211, 37, 226, 163, 55, 202, - 1, 226, 153, 254, 49, 55, 202, 1, 211, 37, 254, 49, 55, 202, 1, 226, 153, - 254, 239, 55, 202, 1, 226, 153, 253, 245, 55, 202, 1, 226, 153, 254, 237, - 55, 202, 1, 226, 153, 253, 239, 55, 202, 1, 211, 37, 253, 239, 55, 202, - 1, 226, 153, 245, 83, 55, 202, 1, 211, 37, 245, 83, 55, 202, 1, 226, 153, - 253, 214, 55, 202, 1, 211, 37, 253, 214, 55, 202, 1, 226, 153, 254, 234, - 55, 202, 1, 211, 37, 254, 234, 55, 202, 1, 226, 153, 226, 144, 55, 202, - 1, 226, 153, 252, 133, 222, 129, 21, 111, 222, 129, 21, 105, 222, 129, - 21, 158, 222, 129, 21, 161, 222, 129, 21, 190, 222, 129, 21, 195, 222, - 129, 21, 199, 222, 129, 21, 196, 222, 129, 21, 201, 222, 129, 54, 216, - 248, 222, 129, 54, 215, 73, 222, 129, 54, 216, 163, 222, 129, 54, 244, - 23, 222, 129, 54, 244, 122, 222, 129, 54, 219, 113, 222, 129, 54, 220, - 118, 222, 129, 54, 245, 192, 222, 129, 54, 228, 200, 222, 129, 54, 123, - 240, 217, 222, 129, 54, 113, 240, 217, 222, 129, 54, 134, 240, 217, 222, - 129, 54, 244, 19, 240, 217, 222, 129, 54, 244, 89, 240, 217, 222, 129, - 54, 219, 127, 240, 217, 222, 129, 54, 220, 124, 240, 217, 222, 129, 54, - 245, 201, 240, 217, 222, 129, 54, 228, 205, 240, 217, 222, 129, 244, 10, - 123, 242, 34, 222, 129, 244, 10, 123, 224, 24, 222, 129, 244, 10, 123, - 216, 169, 222, 129, 244, 10, 113, 216, 167, 118, 5, 251, 7, 118, 5, 254, - 83, 118, 5, 213, 147, 118, 5, 235, 108, 118, 5, 214, 161, 118, 1, 61, - 118, 1, 255, 82, 118, 1, 74, 118, 1, 236, 40, 118, 1, 69, 118, 1, 214, - 118, 118, 1, 149, 153, 118, 1, 149, 222, 182, 118, 1, 149, 156, 118, 1, - 149, 232, 191, 118, 1, 76, 118, 1, 254, 210, 118, 1, 78, 118, 1, 253, - 200, 118, 1, 176, 118, 1, 234, 138, 118, 1, 243, 142, 118, 1, 243, 0, - 118, 1, 229, 82, 118, 1, 251, 41, 118, 1, 250, 165, 118, 1, 235, 147, - 118, 1, 235, 120, 118, 1, 227, 169, 118, 1, 215, 157, 118, 1, 215, 145, - 118, 1, 248, 143, 118, 1, 248, 127, 118, 1, 228, 115, 118, 1, 217, 106, - 118, 1, 216, 209, 118, 1, 248, 229, 118, 1, 248, 33, 118, 1, 198, 118, 1, - 191, 118, 1, 225, 150, 118, 1, 252, 199, 118, 1, 252, 26, 118, 1, 186, - 118, 1, 192, 118, 1, 205, 118, 1, 233, 141, 118, 1, 214, 27, 118, 1, 220, - 104, 118, 1, 218, 225, 118, 1, 206, 118, 1, 162, 118, 1, 232, 190, 118, - 1, 55, 36, 232, 181, 118, 1, 55, 36, 222, 181, 118, 1, 55, 36, 228, 97, - 118, 25, 5, 255, 82, 118, 25, 5, 252, 23, 255, 82, 118, 25, 5, 74, 118, - 25, 5, 236, 40, 118, 25, 5, 69, 118, 25, 5, 214, 118, 118, 25, 5, 149, - 153, 118, 25, 5, 149, 222, 182, 118, 25, 5, 149, 156, 118, 25, 5, 149, - 232, 191, 118, 25, 5, 76, 118, 25, 5, 254, 210, 118, 25, 5, 78, 118, 25, - 5, 253, 200, 118, 213, 152, 118, 248, 186, 118, 52, 248, 186, 118, 224, - 144, 247, 128, 118, 224, 144, 52, 247, 128, 118, 224, 144, 232, 219, 118, - 224, 144, 249, 145, 130, 118, 224, 144, 232, 121, 118, 54, 111, 118, 54, - 105, 118, 54, 158, 118, 54, 161, 118, 54, 190, 118, 54, 195, 118, 54, - 199, 118, 54, 196, 118, 54, 201, 118, 54, 216, 248, 118, 54, 215, 73, - 118, 54, 216, 163, 118, 54, 244, 23, 118, 54, 244, 122, 118, 54, 219, - 113, 118, 54, 220, 118, 118, 54, 245, 192, 118, 54, 228, 200, 118, 54, - 123, 240, 217, 118, 54, 123, 216, 148, 118, 21, 210, 86, 118, 21, 111, - 118, 21, 105, 118, 21, 158, 118, 21, 161, 118, 21, 190, 118, 21, 195, - 118, 21, 199, 118, 21, 196, 118, 21, 201, 234, 250, 5, 251, 7, 234, 250, - 5, 254, 83, 234, 250, 5, 213, 147, 234, 250, 1, 61, 234, 250, 1, 255, 82, - 234, 250, 1, 74, 234, 250, 1, 236, 40, 234, 250, 1, 69, 234, 250, 1, 214, - 118, 234, 250, 1, 76, 234, 250, 1, 254, 210, 234, 250, 1, 78, 234, 250, - 1, 253, 200, 234, 250, 1, 176, 234, 250, 1, 234, 138, 234, 250, 1, 243, - 142, 234, 250, 1, 243, 0, 234, 250, 1, 229, 82, 234, 250, 1, 251, 41, - 234, 250, 1, 250, 165, 234, 250, 1, 235, 147, 234, 250, 1, 235, 120, 234, - 250, 1, 227, 169, 234, 250, 1, 215, 157, 234, 250, 1, 215, 145, 234, 250, - 1, 248, 143, 234, 250, 1, 248, 132, 234, 250, 1, 248, 127, 234, 250, 1, - 223, 42, 234, 250, 1, 228, 115, 234, 250, 1, 217, 106, 234, 250, 1, 216, - 209, 234, 250, 1, 248, 229, 234, 250, 1, 248, 33, 234, 250, 1, 198, 234, - 250, 1, 191, 234, 250, 1, 225, 150, 234, 250, 1, 252, 199, 234, 250, 1, - 252, 26, 234, 250, 1, 186, 234, 250, 1, 192, 234, 250, 1, 205, 234, 250, - 1, 233, 141, 234, 250, 1, 214, 27, 234, 250, 1, 220, 104, 234, 250, 1, - 218, 225, 234, 250, 1, 206, 234, 250, 1, 162, 234, 250, 25, 5, 255, 82, - 234, 250, 25, 5, 74, 234, 250, 25, 5, 236, 40, 234, 250, 25, 5, 69, 234, - 250, 25, 5, 214, 118, 234, 250, 25, 5, 76, 234, 250, 25, 5, 254, 210, - 234, 250, 25, 5, 78, 234, 250, 25, 5, 253, 200, 234, 250, 5, 213, 152, - 234, 250, 5, 227, 209, 234, 250, 255, 30, 50, 234, 250, 245, 129, 50, - 234, 250, 54, 50, 234, 250, 221, 175, 79, 234, 250, 52, 221, 175, 79, - 234, 250, 248, 186, 234, 250, 52, 248, 186, 219, 38, 219, 46, 1, 222, 20, - 219, 38, 219, 46, 1, 217, 81, 219, 38, 219, 46, 1, 252, 176, 219, 38, - 219, 46, 1, 251, 31, 219, 38, 219, 46, 1, 248, 211, 219, 38, 219, 46, 1, - 243, 127, 219, 38, 219, 46, 1, 231, 215, 219, 38, 219, 46, 1, 229, 79, - 219, 38, 219, 46, 1, 233, 118, 219, 38, 219, 46, 1, 229, 218, 219, 38, - 219, 46, 1, 214, 24, 219, 38, 219, 46, 1, 226, 77, 219, 38, 219, 46, 1, - 211, 84, 219, 38, 219, 46, 1, 223, 171, 219, 38, 219, 46, 1, 242, 44, - 219, 38, 219, 46, 1, 234, 254, 219, 38, 219, 46, 1, 235, 142, 219, 38, - 219, 46, 1, 227, 166, 219, 38, 219, 46, 1, 254, 218, 219, 38, 219, 46, 1, - 245, 215, 219, 38, 219, 46, 1, 236, 41, 219, 38, 219, 46, 1, 214, 208, - 219, 38, 219, 46, 1, 226, 226, 219, 38, 219, 46, 1, 245, 205, 219, 38, - 219, 46, 1, 231, 228, 219, 38, 219, 46, 21, 210, 86, 219, 38, 219, 46, - 21, 111, 219, 38, 219, 46, 21, 105, 219, 38, 219, 46, 21, 158, 219, 38, - 219, 46, 21, 161, 219, 38, 219, 46, 21, 190, 219, 38, 219, 46, 21, 195, - 219, 38, 219, 46, 21, 199, 219, 38, 219, 46, 21, 196, 219, 38, 219, 46, - 21, 201, 250, 159, 5, 251, 7, 250, 159, 5, 254, 83, 250, 159, 5, 213, - 147, 250, 159, 1, 255, 82, 250, 159, 1, 74, 250, 159, 1, 69, 250, 159, 1, - 76, 250, 159, 1, 235, 16, 250, 159, 1, 234, 137, 250, 159, 1, 243, 139, - 250, 159, 1, 242, 255, 250, 159, 1, 229, 81, 250, 159, 1, 251, 40, 250, - 159, 1, 250, 164, 250, 159, 1, 235, 146, 250, 159, 1, 235, 119, 250, 159, - 1, 227, 168, 250, 159, 1, 215, 156, 250, 159, 1, 215, 144, 250, 159, 1, - 248, 142, 250, 159, 1, 248, 126, 250, 159, 1, 228, 114, 250, 159, 1, 217, - 102, 250, 159, 1, 216, 208, 250, 159, 1, 248, 228, 250, 159, 1, 248, 32, - 250, 159, 1, 229, 230, 250, 159, 1, 226, 93, 250, 159, 1, 225, 149, 250, - 159, 1, 252, 197, 250, 159, 1, 252, 25, 250, 159, 1, 231, 242, 250, 159, - 1, 210, 167, 250, 159, 1, 211, 103, 250, 159, 1, 223, 187, 250, 159, 1, - 233, 140, 250, 159, 1, 212, 64, 250, 159, 1, 222, 33, 250, 159, 1, 242, - 53, 250, 159, 25, 5, 61, 250, 159, 25, 5, 74, 250, 159, 25, 5, 236, 40, - 250, 159, 25, 5, 69, 250, 159, 25, 5, 214, 118, 250, 159, 25, 5, 76, 250, - 159, 25, 5, 254, 210, 250, 159, 25, 5, 78, 250, 159, 25, 5, 253, 200, - 250, 159, 25, 5, 226, 223, 250, 159, 144, 79, 250, 159, 253, 201, 79, - 250, 159, 213, 152, 250, 159, 231, 240, 250, 159, 21, 210, 86, 250, 159, - 21, 111, 250, 159, 21, 105, 250, 159, 21, 158, 250, 159, 21, 161, 250, - 159, 21, 190, 250, 159, 21, 195, 250, 159, 21, 199, 250, 159, 21, 196, - 250, 159, 21, 201, 250, 159, 221, 175, 79, 250, 159, 248, 186, 250, 159, - 52, 248, 186, 250, 159, 224, 16, 79, 174, 5, 251, 7, 174, 5, 254, 83, - 174, 5, 213, 147, 174, 1, 61, 174, 1, 255, 82, 174, 1, 74, 174, 1, 236, - 40, 174, 1, 69, 174, 1, 214, 118, 174, 1, 149, 153, 174, 1, 149, 222, - 182, 174, 1, 149, 156, 174, 1, 149, 232, 191, 174, 1, 76, 174, 1, 254, - 210, 174, 1, 78, 174, 1, 253, 200, 174, 1, 176, 174, 1, 234, 138, 174, 1, - 243, 142, 174, 1, 243, 0, 174, 1, 229, 82, 174, 1, 251, 41, 174, 1, 250, - 165, 174, 1, 235, 147, 174, 1, 235, 120, 174, 1, 227, 169, 174, 1, 215, - 157, 174, 1, 215, 145, 174, 1, 248, 143, 174, 1, 248, 127, 174, 1, 228, - 115, 174, 1, 217, 106, 174, 1, 216, 209, 174, 1, 248, 229, 174, 1, 248, - 33, 174, 1, 198, 174, 1, 191, 174, 1, 225, 150, 174, 1, 252, 199, 174, 1, - 252, 26, 174, 1, 186, 174, 1, 192, 174, 1, 205, 174, 1, 233, 141, 174, 1, - 232, 190, 174, 1, 214, 27, 174, 1, 220, 104, 174, 1, 218, 225, 174, 1, - 206, 174, 1, 162, 174, 25, 5, 255, 82, 174, 25, 5, 74, 174, 25, 5, 236, - 40, 174, 25, 5, 69, 174, 25, 5, 214, 118, 174, 25, 5, 149, 153, 174, 25, - 5, 149, 222, 182, 174, 25, 5, 149, 156, 174, 25, 5, 149, 232, 191, 174, - 25, 5, 76, 174, 25, 5, 254, 210, 174, 25, 5, 78, 174, 25, 5, 253, 200, - 174, 5, 213, 152, 174, 5, 253, 183, 174, 5, 235, 108, 174, 5, 214, 161, - 174, 226, 208, 174, 248, 186, 174, 52, 248, 186, 174, 255, 30, 50, 174, - 220, 139, 174, 21, 210, 86, 174, 21, 111, 174, 21, 105, 174, 21, 158, - 174, 21, 161, 174, 21, 190, 174, 21, 195, 174, 21, 199, 174, 21, 196, - 174, 21, 201, 217, 70, 1, 61, 217, 70, 1, 255, 82, 217, 70, 1, 74, 217, - 70, 1, 236, 40, 217, 70, 1, 69, 217, 70, 1, 214, 118, 217, 70, 1, 76, - 217, 70, 1, 254, 210, 217, 70, 1, 78, 217, 70, 1, 253, 200, 217, 70, 1, - 176, 217, 70, 1, 234, 138, 217, 70, 1, 243, 142, 217, 70, 1, 243, 0, 217, - 70, 1, 229, 82, 217, 70, 1, 251, 41, 217, 70, 1, 250, 165, 217, 70, 1, - 235, 147, 217, 70, 1, 235, 120, 217, 70, 1, 227, 169, 217, 70, 1, 215, - 157, 217, 70, 1, 215, 145, 217, 70, 1, 248, 143, 217, 70, 1, 248, 127, - 217, 70, 1, 228, 115, 217, 70, 1, 217, 106, 217, 70, 1, 216, 209, 217, - 70, 1, 248, 229, 217, 70, 1, 248, 33, 217, 70, 1, 198, 217, 70, 1, 191, - 217, 70, 1, 225, 150, 217, 70, 1, 252, 199, 217, 70, 1, 252, 26, 217, 70, - 1, 186, 217, 70, 1, 192, 217, 70, 1, 205, 217, 70, 1, 233, 141, 217, 70, - 1, 214, 27, 217, 70, 1, 220, 104, 217, 70, 1, 206, 217, 70, 1, 162, 217, - 70, 1, 222, 181, 217, 70, 5, 254, 83, 217, 70, 5, 213, 147, 217, 70, 25, - 5, 255, 82, 217, 70, 25, 5, 74, 217, 70, 25, 5, 236, 40, 217, 70, 25, 5, - 69, 217, 70, 25, 5, 214, 118, 217, 70, 25, 5, 76, 217, 70, 25, 5, 254, - 210, 217, 70, 25, 5, 78, 217, 70, 25, 5, 253, 200, 217, 70, 5, 213, 152, - 217, 70, 5, 227, 209, 217, 70, 21, 210, 86, 217, 70, 21, 111, 217, 70, - 21, 105, 217, 70, 21, 158, 217, 70, 21, 161, 217, 70, 21, 190, 217, 70, - 21, 195, 217, 70, 21, 199, 217, 70, 21, 196, 217, 70, 21, 201, 15, 5, 61, - 15, 5, 116, 30, 61, 15, 5, 116, 30, 252, 184, 15, 5, 116, 30, 243, 112, - 216, 240, 15, 5, 116, 30, 162, 15, 5, 116, 30, 236, 42, 15, 5, 116, 30, - 233, 122, 242, 101, 15, 5, 116, 30, 230, 66, 15, 5, 116, 30, 222, 23, 15, - 5, 255, 84, 15, 5, 255, 34, 15, 5, 255, 35, 30, 253, 237, 15, 5, 255, 35, - 30, 246, 75, 242, 101, 15, 5, 255, 35, 30, 243, 125, 15, 5, 255, 35, 30, - 243, 112, 216, 240, 15, 5, 255, 35, 30, 162, 15, 5, 255, 35, 30, 236, 43, - 242, 101, 15, 5, 255, 35, 30, 236, 16, 15, 5, 255, 35, 30, 233, 123, 15, - 5, 255, 35, 30, 220, 50, 15, 5, 255, 35, 30, 104, 96, 104, 96, 69, 15, 5, - 255, 35, 242, 101, 15, 5, 255, 32, 15, 5, 255, 33, 30, 252, 168, 15, 5, - 255, 33, 30, 243, 112, 216, 240, 15, 5, 255, 33, 30, 231, 97, 96, 245, - 158, 15, 5, 255, 33, 30, 220, 102, 15, 5, 255, 33, 30, 217, 73, 15, 5, - 255, 8, 15, 5, 254, 195, 15, 5, 254, 196, 30, 245, 95, 15, 5, 254, 196, - 30, 220, 12, 96, 242, 197, 15, 5, 254, 187, 15, 5, 254, 188, 30, 254, - 187, 15, 5, 254, 188, 30, 247, 224, 15, 5, 254, 188, 30, 242, 197, 15, 5, - 254, 188, 30, 162, 15, 5, 254, 188, 30, 235, 5, 15, 5, 254, 188, 30, 234, - 98, 15, 5, 254, 188, 30, 220, 65, 15, 5, 254, 188, 30, 214, 126, 15, 5, - 254, 184, 15, 5, 254, 177, 15, 5, 254, 140, 15, 5, 254, 141, 30, 220, 65, - 15, 5, 254, 131, 15, 5, 254, 132, 115, 254, 131, 15, 5, 254, 132, 134, - 216, 86, 15, 5, 254, 132, 96, 229, 222, 226, 168, 254, 132, 96, 229, 221, - 15, 5, 254, 132, 96, 229, 222, 218, 235, 15, 5, 254, 102, 15, 5, 254, 75, - 15, 5, 254, 43, 15, 5, 254, 44, 30, 233, 202, 15, 5, 254, 16, 15, 5, 253, - 244, 15, 5, 253, 239, 15, 5, 253, 240, 210, 40, 216, 240, 15, 5, 253, - 240, 235, 9, 216, 240, 15, 5, 253, 240, 115, 253, 240, 215, 115, 115, - 215, 115, 215, 115, 115, 215, 115, 226, 25, 15, 5, 253, 240, 115, 253, - 240, 115, 253, 239, 15, 5, 253, 240, 115, 253, 240, 115, 253, 240, 249, - 133, 253, 240, 115, 253, 240, 115, 253, 239, 15, 5, 253, 237, 15, 5, 253, - 234, 15, 5, 252, 199, 15, 5, 252, 184, 15, 5, 252, 179, 15, 5, 252, 175, - 15, 5, 252, 169, 15, 5, 252, 170, 115, 252, 169, 15, 5, 252, 168, 15, 5, - 130, 15, 5, 252, 148, 15, 5, 252, 14, 15, 5, 252, 15, 30, 61, 15, 5, 252, - 15, 30, 243, 103, 15, 5, 252, 15, 30, 236, 43, 242, 101, 15, 5, 251, 133, - 15, 5, 251, 134, 115, 251, 134, 255, 34, 15, 5, 251, 134, 115, 251, 134, - 214, 190, 15, 5, 251, 134, 249, 133, 251, 133, 15, 5, 251, 117, 15, 5, - 251, 118, 115, 251, 117, 15, 5, 251, 106, 15, 5, 251, 105, 15, 5, 248, - 229, 15, 5, 248, 220, 15, 5, 248, 221, 234, 72, 30, 116, 96, 231, 152, - 15, 5, 248, 221, 234, 72, 30, 254, 140, 15, 5, 248, 221, 234, 72, 30, - 252, 168, 15, 5, 248, 221, 234, 72, 30, 252, 14, 15, 5, 248, 221, 234, - 72, 30, 243, 142, 15, 5, 248, 221, 234, 72, 30, 243, 143, 96, 231, 152, - 15, 5, 248, 221, 234, 72, 30, 242, 221, 15, 5, 248, 221, 234, 72, 30, - 242, 204, 15, 5, 248, 221, 234, 72, 30, 242, 110, 15, 5, 248, 221, 234, - 72, 30, 162, 15, 5, 248, 221, 234, 72, 30, 235, 186, 15, 5, 248, 221, - 234, 72, 30, 235, 187, 96, 232, 103, 15, 5, 248, 221, 234, 72, 30, 234, - 248, 15, 5, 248, 221, 234, 72, 30, 233, 141, 15, 5, 248, 221, 234, 72, - 30, 232, 103, 15, 5, 248, 221, 234, 72, 30, 232, 104, 96, 231, 151, 15, - 5, 248, 221, 234, 72, 30, 232, 89, 15, 5, 248, 221, 234, 72, 30, 229, - 112, 15, 5, 248, 221, 234, 72, 30, 226, 26, 96, 226, 25, 15, 5, 248, 221, - 234, 72, 30, 219, 193, 15, 5, 248, 221, 234, 72, 30, 217, 73, 15, 5, 248, - 221, 234, 72, 30, 214, 231, 96, 242, 204, 15, 5, 248, 221, 234, 72, 30, - 214, 126, 15, 5, 248, 195, 15, 5, 248, 174, 15, 5, 248, 173, 15, 5, 248, - 172, 15, 5, 248, 11, 15, 5, 247, 250, 15, 5, 247, 225, 15, 5, 247, 226, - 30, 220, 65, 15, 5, 247, 224, 15, 5, 247, 214, 15, 5, 247, 215, 234, 214, - 104, 242, 102, 247, 195, 15, 5, 247, 195, 15, 5, 246, 86, 15, 5, 246, 87, - 115, 246, 86, 15, 5, 246, 87, 242, 101, 15, 5, 246, 87, 220, 47, 15, 5, - 246, 84, 15, 5, 246, 85, 30, 245, 80, 15, 5, 246, 83, 15, 5, 246, 82, 15, - 5, 246, 81, 15, 5, 246, 80, 15, 5, 246, 76, 15, 5, 246, 74, 15, 5, 246, - 75, 242, 101, 15, 5, 246, 75, 242, 102, 242, 101, 15, 5, 246, 73, 15, 5, - 246, 66, 15, 5, 76, 15, 5, 160, 30, 226, 25, 15, 5, 160, 115, 160, 227, - 199, 115, 227, 198, 15, 5, 245, 242, 15, 5, 245, 243, 30, 116, 96, 242, - 56, 96, 248, 229, 15, 5, 245, 243, 30, 243, 103, 15, 5, 245, 243, 30, - 230, 235, 15, 5, 245, 243, 30, 222, 10, 15, 5, 245, 243, 30, 220, 65, 15, - 5, 245, 243, 30, 69, 15, 5, 245, 219, 15, 5, 245, 208, 15, 5, 245, 182, - 15, 5, 245, 158, 15, 5, 245, 159, 30, 243, 111, 15, 5, 245, 159, 30, 243, - 112, 216, 240, 15, 5, 245, 159, 30, 231, 96, 15, 5, 245, 159, 249, 133, - 245, 158, 15, 5, 245, 159, 226, 168, 245, 158, 15, 5, 245, 159, 218, 235, - 15, 5, 245, 97, 15, 5, 245, 95, 15, 5, 245, 80, 15, 5, 245, 18, 15, 5, - 245, 19, 30, 61, 15, 5, 245, 19, 30, 116, 96, 233, 110, 15, 5, 245, 19, - 30, 116, 96, 233, 111, 30, 233, 110, 15, 5, 245, 19, 30, 254, 131, 15, 5, - 245, 19, 30, 252, 184, 15, 5, 245, 19, 30, 246, 75, 242, 101, 15, 5, 245, - 19, 30, 246, 75, 242, 102, 242, 101, 15, 5, 245, 19, 30, 162, 15, 5, 245, - 19, 30, 242, 56, 242, 101, 15, 5, 245, 19, 30, 236, 43, 242, 101, 15, 5, - 245, 19, 30, 234, 213, 15, 5, 245, 19, 30, 234, 214, 218, 235, 15, 5, - 245, 19, 30, 233, 221, 15, 5, 245, 19, 30, 233, 141, 15, 5, 245, 19, 30, - 233, 111, 30, 233, 110, 15, 5, 245, 19, 30, 232, 247, 15, 5, 245, 19, 30, - 232, 103, 15, 5, 245, 19, 30, 214, 230, 15, 5, 245, 19, 30, 214, 219, 15, - 5, 243, 142, 15, 5, 243, 143, 242, 101, 15, 5, 243, 140, 15, 5, 243, 141, - 30, 116, 96, 248, 230, 96, 162, 15, 5, 243, 141, 30, 116, 96, 162, 15, 5, - 243, 141, 30, 116, 96, 236, 42, 15, 5, 243, 141, 30, 255, 33, 216, 241, - 96, 217, 94, 15, 5, 243, 141, 30, 254, 131, 15, 5, 243, 141, 30, 253, - 239, 15, 5, 243, 141, 30, 253, 238, 96, 243, 125, 15, 5, 243, 141, 30, - 252, 184, 15, 5, 243, 141, 30, 252, 149, 96, 205, 15, 5, 243, 141, 30, - 251, 106, 15, 5, 243, 141, 30, 251, 107, 96, 205, 15, 5, 243, 141, 30, - 248, 229, 15, 5, 243, 141, 30, 248, 11, 15, 5, 243, 141, 30, 247, 226, - 30, 220, 65, 15, 5, 243, 141, 30, 246, 84, 15, 5, 243, 141, 30, 245, 182, - 15, 5, 243, 141, 30, 245, 183, 96, 233, 141, 15, 5, 243, 141, 30, 245, - 158, 15, 5, 243, 141, 30, 245, 159, 30, 243, 112, 216, 240, 15, 5, 243, - 141, 30, 243, 112, 216, 240, 15, 5, 243, 141, 30, 243, 103, 15, 5, 243, - 141, 30, 242, 221, 15, 5, 243, 141, 30, 242, 219, 15, 5, 243, 141, 30, - 242, 220, 96, 61, 15, 5, 243, 141, 30, 242, 205, 96, 218, 84, 15, 5, 243, - 141, 30, 242, 56, 96, 232, 104, 96, 245, 80, 15, 5, 243, 141, 30, 242, - 37, 15, 5, 243, 141, 30, 242, 38, 96, 233, 141, 15, 5, 243, 141, 30, 241, - 188, 96, 232, 247, 15, 5, 243, 141, 30, 240, 225, 15, 5, 243, 141, 30, - 236, 43, 242, 101, 15, 5, 243, 141, 30, 235, 173, 96, 240, 230, 96, 253, - 239, 15, 5, 243, 141, 30, 234, 248, 15, 5, 243, 141, 30, 234, 213, 15, 5, - 243, 141, 30, 234, 95, 15, 5, 243, 141, 30, 234, 96, 96, 233, 110, 15, 5, - 243, 141, 30, 233, 222, 96, 254, 131, 15, 5, 243, 141, 30, 233, 141, 15, - 5, 243, 141, 30, 231, 97, 96, 245, 158, 15, 5, 243, 141, 30, 230, 235, - 15, 5, 243, 141, 30, 227, 198, 15, 5, 243, 141, 30, 227, 199, 115, 227, - 198, 15, 5, 243, 141, 30, 191, 15, 5, 243, 141, 30, 222, 10, 15, 5, 243, - 141, 30, 221, 233, 15, 5, 243, 141, 30, 220, 65, 15, 5, 243, 141, 30, - 220, 66, 96, 215, 99, 15, 5, 243, 141, 30, 220, 32, 15, 5, 243, 141, 30, - 218, 44, 15, 5, 243, 141, 30, 217, 73, 15, 5, 243, 141, 30, 69, 15, 5, - 243, 141, 30, 214, 219, 15, 5, 243, 141, 30, 214, 220, 96, 246, 86, 15, - 5, 243, 141, 115, 243, 140, 15, 5, 243, 135, 15, 5, 243, 136, 249, 133, - 243, 135, 15, 5, 243, 133, 15, 5, 243, 134, 115, 243, 134, 243, 104, 115, - 243, 103, 15, 5, 243, 125, 15, 5, 243, 126, 243, 134, 115, 243, 134, 243, - 104, 115, 243, 103, 15, 5, 243, 124, 15, 5, 243, 122, 15, 5, 243, 113, - 15, 5, 243, 111, 15, 5, 243, 112, 216, 240, 15, 5, 243, 112, 115, 243, - 111, 15, 5, 243, 112, 249, 133, 243, 111, 15, 5, 243, 103, 15, 5, 243, - 102, 15, 5, 243, 97, 15, 5, 243, 43, 15, 5, 243, 44, 30, 233, 202, 15, 5, - 242, 221, 15, 5, 242, 222, 30, 76, 15, 5, 242, 222, 30, 69, 15, 5, 242, - 222, 249, 133, 242, 221, 15, 5, 242, 219, 15, 5, 242, 220, 115, 242, 219, - 15, 5, 242, 220, 249, 133, 242, 219, 15, 5, 242, 216, 15, 5, 242, 204, - 15, 5, 242, 205, 242, 101, 15, 5, 242, 202, 15, 5, 242, 203, 30, 116, 96, - 236, 42, 15, 5, 242, 203, 30, 243, 112, 216, 240, 15, 5, 242, 203, 30, - 236, 42, 15, 5, 242, 203, 30, 232, 104, 96, 236, 42, 15, 5, 242, 203, 30, - 191, 15, 5, 242, 199, 15, 5, 242, 197, 15, 5, 242, 198, 249, 133, 242, - 197, 15, 5, 242, 198, 30, 252, 184, 15, 5, 242, 198, 30, 217, 73, 15, 5, - 242, 198, 216, 240, 15, 5, 242, 120, 15, 5, 242, 121, 249, 133, 242, 120, - 15, 5, 242, 118, 15, 5, 242, 119, 30, 234, 248, 15, 5, 242, 119, 30, 234, - 249, 30, 236, 43, 242, 101, 15, 5, 242, 119, 30, 227, 198, 15, 5, 242, - 119, 30, 222, 11, 96, 215, 114, 15, 5, 242, 119, 242, 101, 15, 5, 242, - 110, 15, 5, 242, 111, 30, 116, 96, 233, 202, 15, 5, 242, 111, 30, 233, - 202, 15, 5, 242, 111, 115, 242, 111, 232, 96, 15, 5, 242, 105, 15, 5, - 242, 103, 15, 5, 242, 104, 30, 220, 65, 15, 5, 242, 95, 15, 5, 242, 94, - 15, 5, 242, 91, 15, 5, 242, 90, 15, 5, 162, 15, 5, 242, 56, 216, 240, 15, - 5, 242, 56, 242, 101, 15, 5, 242, 37, 15, 5, 241, 187, 15, 5, 241, 188, - 30, 253, 239, 15, 5, 241, 188, 30, 253, 237, 15, 5, 241, 188, 30, 252, - 184, 15, 5, 241, 188, 30, 247, 195, 15, 5, 241, 188, 30, 243, 133, 15, 5, - 241, 188, 30, 234, 87, 15, 5, 241, 188, 30, 227, 198, 15, 5, 241, 188, - 30, 220, 65, 15, 5, 241, 188, 30, 69, 15, 5, 240, 229, 15, 5, 240, 225, - 15, 5, 240, 226, 30, 254, 131, 15, 5, 240, 226, 30, 242, 37, 15, 5, 240, - 226, 30, 234, 213, 15, 5, 240, 226, 30, 232, 203, 15, 5, 240, 226, 30, - 214, 219, 15, 5, 240, 222, 15, 5, 74, 15, 5, 240, 161, 61, 15, 5, 240, - 122, 15, 5, 236, 70, 15, 5, 236, 71, 115, 236, 71, 251, 106, 15, 5, 236, - 71, 115, 236, 71, 218, 235, 15, 5, 236, 45, 15, 5, 236, 42, 15, 5, 236, - 43, 247, 250, 15, 5, 236, 43, 223, 38, 15, 5, 236, 43, 115, 236, 43, 220, - 16, 115, 220, 16, 214, 220, 115, 214, 219, 15, 5, 236, 43, 242, 101, 15, - 5, 236, 34, 15, 5, 236, 35, 30, 243, 112, 216, 240, 15, 5, 236, 33, 15, - 5, 236, 23, 15, 5, 236, 24, 30, 217, 73, 15, 5, 236, 24, 249, 133, 236, - 23, 15, 5, 236, 24, 226, 168, 236, 23, 15, 5, 236, 24, 218, 235, 15, 5, - 236, 16, 15, 5, 236, 6, 15, 5, 235, 186, 15, 5, 235, 172, 15, 5, 176, 15, - 5, 235, 19, 30, 61, 15, 5, 235, 19, 30, 255, 8, 15, 5, 235, 19, 30, 255, - 9, 96, 233, 221, 15, 5, 235, 19, 30, 253, 237, 15, 5, 235, 19, 30, 252, - 184, 15, 5, 235, 19, 30, 252, 168, 15, 5, 235, 19, 30, 130, 15, 5, 235, - 19, 30, 252, 14, 15, 5, 235, 19, 30, 245, 95, 15, 5, 235, 19, 30, 245, - 80, 15, 5, 235, 19, 30, 243, 142, 15, 5, 235, 19, 30, 243, 125, 15, 5, - 235, 19, 30, 243, 112, 216, 240, 15, 5, 235, 19, 30, 243, 103, 15, 5, - 235, 19, 30, 243, 104, 96, 220, 103, 96, 61, 15, 5, 235, 19, 30, 242, - 221, 15, 5, 235, 19, 30, 242, 204, 15, 5, 235, 19, 30, 242, 198, 96, 221, - 233, 15, 5, 235, 19, 30, 242, 198, 249, 133, 242, 197, 15, 5, 235, 19, - 30, 242, 120, 15, 5, 235, 19, 30, 242, 94, 15, 5, 235, 19, 30, 236, 42, - 15, 5, 235, 19, 30, 236, 23, 15, 5, 235, 19, 30, 234, 248, 15, 5, 235, - 19, 30, 234, 98, 15, 5, 235, 19, 30, 234, 95, 15, 5, 235, 19, 30, 232, - 247, 15, 5, 235, 19, 30, 232, 103, 15, 5, 235, 19, 30, 231, 96, 15, 5, - 235, 19, 30, 231, 97, 96, 246, 86, 15, 5, 235, 19, 30, 231, 97, 96, 242, - 221, 15, 5, 235, 19, 30, 231, 97, 96, 217, 23, 15, 5, 235, 19, 30, 230, - 235, 15, 5, 235, 19, 30, 230, 236, 96, 227, 193, 15, 5, 235, 19, 30, 229, - 112, 15, 5, 235, 19, 30, 227, 198, 15, 5, 235, 19, 30, 225, 111, 15, 5, - 235, 19, 30, 222, 142, 15, 5, 235, 19, 30, 206, 15, 5, 235, 19, 30, 221, - 233, 15, 5, 235, 19, 30, 220, 104, 15, 5, 235, 19, 30, 220, 65, 15, 5, - 235, 19, 30, 220, 32, 15, 5, 235, 19, 30, 219, 227, 15, 5, 235, 19, 30, - 219, 184, 15, 5, 235, 19, 30, 218, 52, 15, 5, 235, 19, 30, 217, 51, 15, - 5, 235, 19, 30, 69, 15, 5, 235, 19, 30, 214, 230, 15, 5, 235, 19, 30, - 214, 219, 15, 5, 235, 19, 30, 214, 193, 30, 191, 15, 5, 235, 19, 30, 214, - 126, 15, 5, 235, 19, 30, 210, 44, 15, 5, 235, 17, 15, 5, 235, 18, 249, - 133, 235, 17, 15, 5, 235, 10, 15, 5, 235, 7, 15, 5, 235, 5, 15, 5, 235, - 4, 15, 5, 235, 2, 15, 5, 235, 3, 115, 235, 2, 15, 5, 234, 248, 15, 5, - 234, 249, 30, 236, 43, 242, 101, 15, 5, 234, 244, 15, 5, 234, 245, 30, - 252, 184, 15, 5, 234, 245, 249, 133, 234, 244, 15, 5, 234, 242, 15, 5, - 234, 241, 15, 5, 234, 213, 15, 5, 234, 214, 233, 124, 30, 104, 115, 233, - 124, 30, 69, 15, 5, 234, 214, 115, 234, 214, 233, 124, 30, 104, 115, 233, - 124, 30, 69, 15, 5, 234, 163, 15, 5, 234, 98, 15, 5, 234, 99, 30, 252, - 184, 15, 5, 234, 99, 30, 69, 15, 5, 234, 99, 30, 214, 219, 15, 5, 234, - 95, 15, 5, 234, 87, 15, 5, 234, 74, 15, 5, 234, 73, 15, 5, 234, 71, 15, - 5, 234, 72, 115, 234, 71, 15, 5, 233, 223, 15, 5, 233, 224, 115, 241, - 188, 30, 253, 238, 233, 224, 115, 241, 188, 30, 253, 237, 15, 5, 233, - 221, 15, 5, 233, 219, 15, 5, 233, 220, 214, 12, 17, 15, 5, 233, 218, 15, - 5, 233, 215, 15, 5, 233, 216, 242, 101, 15, 5, 233, 214, 15, 5, 233, 202, - 15, 5, 233, 203, 226, 168, 233, 202, 15, 5, 233, 197, 15, 5, 233, 178, - 15, 5, 233, 141, 15, 5, 233, 123, 15, 5, 233, 124, 30, 61, 15, 5, 233, - 124, 30, 116, 96, 248, 230, 96, 162, 15, 5, 233, 124, 30, 116, 96, 243, - 103, 15, 5, 233, 124, 30, 116, 96, 233, 110, 15, 5, 233, 124, 30, 254, - 187, 15, 5, 233, 124, 30, 254, 131, 15, 5, 233, 124, 30, 253, 240, 210, - 40, 216, 240, 15, 5, 233, 124, 30, 252, 184, 15, 5, 233, 124, 30, 252, - 14, 15, 5, 233, 124, 30, 248, 174, 15, 5, 233, 124, 30, 245, 158, 15, 5, - 233, 124, 30, 243, 142, 15, 5, 233, 124, 30, 243, 103, 15, 5, 233, 124, - 30, 242, 110, 15, 5, 233, 124, 30, 242, 111, 96, 242, 110, 15, 5, 233, - 124, 30, 162, 15, 5, 233, 124, 30, 242, 37, 15, 5, 233, 124, 30, 241, - 188, 30, 227, 198, 15, 5, 233, 124, 30, 236, 43, 242, 101, 15, 5, 233, - 124, 30, 236, 23, 15, 5, 233, 124, 30, 236, 24, 96, 162, 15, 5, 233, 124, - 30, 236, 24, 96, 232, 103, 15, 5, 233, 124, 30, 234, 98, 15, 5, 233, 124, - 30, 234, 87, 15, 5, 233, 124, 30, 233, 221, 15, 5, 233, 124, 30, 233, - 215, 15, 5, 233, 124, 30, 233, 216, 96, 241, 188, 96, 61, 15, 5, 233, - 124, 30, 233, 123, 15, 5, 233, 124, 30, 232, 203, 15, 5, 233, 124, 30, - 232, 103, 15, 5, 233, 124, 30, 232, 91, 15, 5, 233, 124, 30, 231, 96, 15, - 5, 233, 124, 30, 231, 97, 96, 245, 158, 15, 5, 233, 124, 30, 230, 66, 15, - 5, 233, 124, 30, 229, 112, 15, 5, 233, 124, 30, 220, 66, 96, 218, 44, 15, - 5, 233, 124, 30, 220, 12, 96, 242, 198, 96, 245, 95, 15, 5, 233, 124, 30, - 220, 12, 96, 242, 198, 216, 240, 15, 5, 233, 124, 30, 219, 225, 15, 5, - 233, 124, 30, 219, 226, 96, 219, 225, 15, 5, 233, 124, 30, 218, 44, 15, - 5, 233, 124, 30, 217, 85, 15, 5, 233, 124, 30, 217, 73, 15, 5, 233, 124, - 30, 217, 24, 96, 116, 96, 218, 85, 96, 198, 15, 5, 233, 124, 30, 69, 15, - 5, 233, 124, 30, 104, 96, 61, 15, 5, 233, 124, 30, 104, 96, 104, 96, 69, - 15, 5, 233, 124, 30, 214, 231, 96, 253, 239, 15, 5, 233, 124, 30, 214, - 219, 15, 5, 233, 124, 30, 214, 126, 15, 5, 233, 124, 218, 235, 15, 5, - 233, 121, 15, 5, 233, 122, 30, 220, 65, 15, 5, 233, 122, 30, 220, 66, 96, - 218, 44, 15, 5, 233, 122, 242, 101, 15, 5, 233, 122, 242, 102, 115, 233, - 122, 242, 102, 220, 65, 15, 5, 233, 117, 15, 5, 233, 110, 15, 5, 233, - 111, 30, 233, 110, 15, 5, 233, 108, 15, 5, 233, 109, 30, 233, 202, 15, 5, - 233, 109, 30, 233, 203, 96, 222, 142, 15, 5, 232, 247, 15, 5, 232, 232, - 15, 5, 232, 222, 15, 5, 232, 203, 15, 5, 232, 103, 15, 5, 232, 104, 30, - 252, 184, 15, 5, 232, 101, 15, 5, 232, 102, 30, 254, 187, 15, 5, 232, - 102, 30, 252, 184, 15, 5, 232, 102, 30, 245, 80, 15, 5, 232, 102, 30, - 245, 81, 216, 240, 15, 5, 232, 102, 30, 243, 112, 216, 240, 15, 5, 232, - 102, 30, 241, 188, 30, 252, 184, 15, 5, 232, 102, 30, 236, 23, 15, 5, - 232, 102, 30, 235, 7, 15, 5, 232, 102, 30, 235, 5, 15, 5, 232, 102, 30, - 235, 6, 96, 253, 239, 15, 5, 232, 102, 30, 234, 98, 15, 5, 232, 102, 30, - 233, 142, 96, 253, 239, 15, 5, 232, 102, 30, 233, 123, 15, 5, 232, 102, - 30, 231, 97, 96, 245, 158, 15, 5, 232, 102, 30, 229, 112, 15, 5, 232, - 102, 30, 227, 242, 15, 5, 232, 102, 30, 219, 194, 96, 253, 239, 15, 5, - 232, 102, 30, 219, 176, 96, 251, 133, 15, 5, 232, 102, 30, 215, 114, 15, - 5, 232, 102, 216, 240, 15, 5, 232, 102, 249, 133, 232, 101, 15, 5, 232, - 102, 226, 168, 232, 101, 15, 5, 232, 102, 218, 235, 15, 5, 232, 102, 220, - 47, 15, 5, 232, 100, 15, 5, 232, 96, 15, 5, 232, 97, 115, 232, 96, 15, 5, - 232, 97, 226, 168, 232, 96, 15, 5, 232, 97, 220, 47, 15, 5, 232, 94, 15, - 5, 232, 91, 15, 5, 232, 89, 15, 5, 232, 90, 115, 232, 89, 15, 5, 232, 90, - 115, 232, 90, 243, 104, 115, 243, 103, 15, 5, 186, 15, 5, 231, 244, 30, - 217, 73, 15, 5, 231, 244, 242, 101, 15, 5, 231, 243, 15, 5, 231, 215, 15, - 5, 231, 171, 15, 5, 231, 152, 15, 5, 231, 151, 15, 5, 231, 96, 15, 5, - 231, 52, 15, 5, 230, 235, 15, 5, 230, 193, 15, 5, 230, 107, 15, 5, 230, - 108, 115, 230, 107, 15, 5, 230, 98, 15, 5, 230, 99, 242, 101, 15, 5, 230, - 83, 15, 5, 230, 69, 15, 5, 230, 66, 15, 5, 230, 67, 30, 61, 15, 5, 230, - 67, 30, 233, 202, 15, 5, 230, 67, 30, 210, 116, 15, 5, 230, 67, 115, 230, - 66, 15, 5, 230, 67, 115, 230, 67, 30, 116, 96, 198, 15, 5, 230, 67, 249, - 133, 230, 66, 15, 5, 230, 64, 15, 5, 230, 65, 30, 61, 15, 5, 230, 65, 30, - 116, 96, 248, 11, 15, 5, 230, 65, 30, 248, 11, 15, 5, 230, 65, 242, 101, - 15, 5, 198, 15, 5, 229, 232, 15, 5, 229, 221, 15, 5, 229, 222, 235, 199, - 15, 5, 229, 222, 30, 219, 228, 216, 240, 15, 5, 229, 222, 226, 168, 229, - 221, 15, 5, 229, 220, 15, 5, 229, 213, 227, 184, 15, 5, 229, 212, 15, 5, - 229, 211, 15, 5, 229, 112, 15, 5, 229, 113, 30, 61, 15, 5, 229, 113, 30, - 214, 219, 15, 5, 229, 113, 220, 47, 15, 5, 228, 238, 15, 5, 228, 239, 30, - 76, 15, 5, 228, 237, 15, 5, 228, 208, 15, 5, 228, 209, 30, 243, 112, 216, - 240, 15, 5, 228, 209, 30, 243, 104, 96, 243, 112, 216, 240, 15, 5, 228, - 206, 15, 5, 228, 207, 30, 254, 131, 15, 5, 228, 207, 30, 253, 239, 15, 5, - 228, 207, 30, 253, 240, 96, 253, 239, 15, 5, 228, 207, 30, 242, 110, 15, - 5, 228, 207, 30, 231, 97, 96, 243, 112, 216, 240, 15, 5, 228, 207, 30, - 229, 112, 15, 5, 228, 207, 30, 227, 198, 15, 5, 228, 207, 30, 220, 65, - 15, 5, 228, 207, 30, 220, 66, 96, 116, 254, 131, 15, 5, 228, 207, 30, - 220, 66, 96, 253, 239, 15, 5, 228, 207, 30, 220, 66, 96, 253, 240, 96, - 253, 239, 15, 5, 228, 207, 30, 214, 231, 96, 253, 239, 15, 5, 228, 207, - 30, 214, 126, 15, 5, 228, 195, 15, 5, 227, 242, 15, 5, 227, 214, 15, 5, - 227, 198, 15, 5, 227, 199, 233, 122, 30, 243, 103, 15, 5, 227, 199, 233, - 122, 30, 231, 152, 15, 5, 227, 199, 233, 122, 30, 222, 10, 15, 5, 227, - 199, 233, 122, 30, 222, 11, 115, 227, 199, 233, 122, 30, 222, 10, 15, 5, - 227, 199, 233, 122, 30, 214, 126, 15, 5, 227, 199, 216, 240, 15, 5, 227, - 199, 115, 227, 198, 15, 5, 227, 199, 249, 133, 227, 198, 15, 5, 227, 199, - 249, 133, 227, 199, 233, 122, 115, 233, 121, 15, 5, 227, 193, 15, 5, 227, - 194, 255, 33, 30, 253, 234, 15, 5, 227, 194, 255, 33, 30, 252, 14, 15, 5, - 227, 194, 255, 33, 30, 246, 82, 15, 5, 227, 194, 255, 33, 30, 242, 110, - 15, 5, 227, 194, 255, 33, 30, 236, 43, 242, 101, 15, 5, 227, 194, 255, - 33, 30, 235, 5, 15, 5, 227, 194, 255, 33, 30, 233, 141, 15, 5, 227, 194, - 255, 33, 30, 229, 112, 15, 5, 227, 194, 255, 33, 30, 219, 173, 15, 5, - 227, 194, 255, 33, 30, 214, 230, 15, 5, 227, 194, 234, 72, 30, 252, 14, - 15, 5, 227, 194, 234, 72, 30, 252, 15, 69, 15, 5, 191, 15, 5, 226, 84, - 15, 5, 226, 51, 15, 5, 226, 25, 15, 5, 225, 164, 15, 5, 225, 111, 15, 5, - 225, 112, 30, 61, 15, 5, 225, 112, 30, 255, 34, 15, 5, 225, 112, 30, 252, - 14, 15, 5, 225, 112, 30, 251, 133, 15, 5, 225, 112, 30, 76, 15, 5, 225, - 112, 30, 74, 15, 5, 225, 112, 30, 240, 122, 15, 5, 225, 112, 30, 69, 15, - 5, 225, 112, 30, 214, 230, 15, 5, 225, 112, 249, 133, 225, 111, 15, 5, - 225, 56, 15, 5, 225, 57, 30, 234, 244, 15, 5, 225, 57, 30, 214, 219, 15, - 5, 225, 57, 30, 210, 116, 15, 5, 225, 57, 226, 168, 225, 56, 15, 5, 205, - 15, 5, 223, 185, 15, 5, 223, 38, 15, 5, 222, 142, 15, 5, 206, 15, 5, 222, - 24, 227, 184, 15, 5, 222, 23, 15, 5, 222, 24, 30, 61, 15, 5, 222, 24, 30, - 246, 86, 15, 5, 222, 24, 30, 246, 84, 15, 5, 222, 24, 30, 162, 15, 5, - 222, 24, 30, 234, 248, 15, 5, 222, 24, 30, 233, 202, 15, 5, 222, 24, 30, - 232, 89, 15, 5, 222, 24, 30, 230, 235, 15, 5, 222, 24, 30, 227, 198, 15, - 5, 222, 24, 30, 222, 10, 15, 5, 222, 24, 30, 220, 32, 15, 5, 222, 24, 30, - 217, 94, 15, 5, 222, 24, 30, 214, 230, 15, 5, 222, 24, 30, 214, 225, 15, - 5, 222, 24, 30, 214, 197, 15, 5, 222, 24, 30, 214, 150, 15, 5, 222, 24, - 30, 214, 126, 15, 5, 222, 24, 115, 222, 23, 15, 5, 222, 24, 242, 101, 15, - 5, 222, 10, 15, 5, 222, 11, 233, 124, 30, 253, 237, 15, 5, 221, 241, 15, - 5, 221, 233, 15, 5, 220, 104, 15, 5, 220, 102, 15, 5, 220, 103, 30, 61, - 15, 5, 220, 103, 30, 252, 184, 15, 5, 220, 103, 30, 242, 197, 15, 5, 220, - 103, 30, 229, 112, 15, 5, 220, 103, 30, 219, 225, 15, 5, 220, 103, 30, - 215, 99, 15, 5, 220, 103, 30, 69, 15, 5, 220, 103, 30, 104, 96, 61, 15, - 5, 220, 101, 15, 5, 220, 99, 15, 5, 220, 80, 15, 5, 220, 65, 15, 5, 220, - 66, 240, 229, 15, 5, 220, 66, 115, 220, 66, 243, 134, 115, 243, 134, 243, - 104, 115, 243, 103, 15, 5, 220, 66, 115, 220, 66, 217, 95, 115, 217, 95, - 243, 104, 115, 243, 103, 15, 5, 220, 58, 15, 5, 220, 53, 15, 5, 220, 50, - 15, 5, 220, 49, 15, 5, 220, 46, 15, 5, 220, 32, 15, 5, 220, 33, 30, 61, - 15, 5, 220, 33, 30, 236, 23, 15, 5, 220, 26, 15, 5, 220, 27, 30, 61, 15, - 5, 220, 27, 30, 252, 169, 15, 5, 220, 27, 30, 251, 117, 15, 5, 220, 27, - 30, 247, 214, 15, 5, 220, 27, 30, 243, 103, 15, 5, 220, 27, 30, 236, 42, - 15, 5, 220, 27, 30, 236, 43, 242, 101, 15, 5, 220, 27, 30, 233, 197, 15, - 5, 220, 27, 30, 232, 91, 15, 5, 220, 27, 30, 230, 98, 15, 5, 220, 27, 30, - 222, 10, 15, 5, 220, 20, 15, 5, 220, 15, 15, 5, 220, 16, 216, 240, 15, 5, - 220, 16, 115, 220, 16, 251, 107, 115, 251, 106, 15, 5, 220, 11, 15, 5, - 219, 227, 15, 5, 219, 228, 115, 235, 200, 219, 227, 15, 5, 219, 225, 15, - 5, 219, 224, 15, 5, 219, 193, 15, 5, 219, 194, 242, 101, 15, 5, 219, 184, - 15, 5, 219, 182, 15, 5, 219, 183, 115, 219, 183, 219, 225, 15, 5, 219, - 175, 15, 5, 219, 173, 15, 5, 218, 84, 15, 5, 218, 85, 115, 218, 84, 15, - 5, 218, 55, 15, 5, 218, 54, 15, 5, 218, 52, 15, 5, 218, 44, 15, 5, 218, - 43, 15, 5, 218, 18, 15, 5, 218, 17, 15, 5, 217, 106, 15, 5, 217, 107, - 253, 224, 15, 5, 217, 107, 30, 241, 187, 15, 5, 217, 107, 30, 230, 235, - 15, 5, 217, 107, 242, 101, 15, 5, 217, 94, 15, 5, 217, 95, 115, 217, 95, - 228, 239, 115, 228, 239, 247, 196, 115, 247, 195, 15, 5, 217, 95, 218, - 235, 15, 5, 217, 85, 15, 5, 129, 30, 252, 14, 15, 5, 129, 30, 242, 110, - 15, 5, 129, 30, 220, 65, 15, 5, 129, 30, 219, 227, 15, 5, 129, 30, 215, - 114, 15, 5, 129, 30, 214, 219, 15, 5, 217, 73, 15, 5, 217, 51, 15, 5, - 217, 23, 15, 5, 217, 24, 242, 101, 15, 5, 216, 118, 15, 5, 216, 119, 216, - 240, 15, 5, 216, 91, 15, 5, 216, 73, 15, 5, 216, 74, 30, 217, 73, 15, 5, - 216, 74, 115, 216, 73, 15, 5, 216, 74, 115, 216, 74, 243, 134, 115, 243, - 134, 243, 104, 115, 243, 103, 15, 5, 215, 119, 15, 5, 215, 114, 15, 5, - 215, 112, 15, 5, 215, 109, 15, 5, 215, 99, 15, 5, 215, 100, 115, 215, - 100, 210, 117, 115, 210, 116, 15, 5, 69, 15, 5, 104, 242, 110, 15, 5, - 104, 104, 69, 15, 5, 104, 115, 104, 226, 94, 115, 226, 94, 243, 104, 115, - 243, 103, 15, 5, 104, 115, 104, 218, 19, 115, 218, 18, 15, 5, 104, 115, - 104, 104, 223, 52, 115, 104, 223, 51, 15, 5, 214, 230, 15, 5, 214, 225, - 15, 5, 214, 219, 15, 5, 214, 220, 233, 197, 15, 5, 214, 220, 30, 252, - 184, 15, 5, 214, 220, 30, 230, 235, 15, 5, 214, 220, 30, 104, 96, 104, - 96, 69, 15, 5, 214, 220, 30, 104, 96, 104, 96, 104, 242, 101, 15, 5, 214, - 220, 242, 101, 15, 5, 214, 220, 220, 47, 15, 5, 214, 220, 220, 48, 30, - 252, 184, 15, 5, 214, 215, 15, 5, 214, 197, 15, 5, 214, 198, 30, 233, - 123, 15, 5, 214, 198, 30, 231, 97, 96, 248, 229, 15, 5, 214, 198, 30, - 220, 102, 15, 5, 214, 198, 30, 69, 15, 5, 214, 196, 15, 5, 214, 192, 15, - 5, 214, 193, 30, 234, 213, 15, 5, 214, 193, 30, 191, 15, 5, 214, 190, 15, - 5, 214, 191, 242, 101, 15, 5, 214, 150, 15, 5, 214, 151, 249, 133, 214, - 150, 15, 5, 214, 151, 220, 47, 15, 5, 214, 148, 15, 5, 214, 149, 30, 116, - 96, 162, 15, 5, 214, 149, 30, 116, 96, 198, 15, 5, 214, 149, 30, 254, - 187, 15, 5, 214, 149, 30, 162, 15, 5, 214, 149, 30, 227, 198, 15, 5, 214, - 149, 30, 214, 230, 15, 5, 214, 149, 30, 214, 231, 96, 253, 239, 15, 5, - 214, 149, 30, 214, 231, 96, 252, 14, 15, 5, 214, 147, 15, 5, 214, 144, - 15, 5, 214, 143, 15, 5, 214, 139, 15, 5, 214, 140, 30, 61, 15, 5, 214, - 140, 30, 253, 234, 15, 5, 214, 140, 30, 130, 15, 5, 214, 140, 30, 246, - 76, 15, 5, 214, 140, 30, 243, 142, 15, 5, 214, 140, 30, 243, 125, 15, 5, - 214, 140, 30, 243, 112, 216, 240, 15, 5, 214, 140, 30, 243, 103, 15, 5, - 214, 140, 30, 242, 120, 15, 5, 214, 140, 30, 162, 15, 5, 214, 140, 30, - 236, 42, 15, 5, 214, 140, 30, 236, 23, 15, 5, 214, 140, 30, 235, 172, 15, - 5, 214, 140, 30, 234, 98, 15, 5, 214, 140, 30, 232, 89, 15, 5, 214, 140, - 30, 230, 193, 15, 5, 214, 140, 30, 191, 15, 5, 214, 140, 30, 220, 65, 15, - 5, 214, 140, 30, 219, 182, 15, 5, 214, 140, 30, 215, 119, 15, 5, 214, - 140, 30, 104, 96, 242, 110, 15, 5, 214, 140, 30, 214, 219, 15, 5, 214, - 140, 30, 214, 137, 15, 5, 214, 137, 15, 5, 214, 138, 30, 69, 15, 5, 214, - 126, 15, 5, 214, 127, 30, 61, 15, 5, 214, 127, 30, 233, 223, 15, 5, 214, - 127, 30, 233, 202, 15, 5, 214, 127, 30, 217, 73, 15, 5, 214, 122, 15, 5, - 214, 125, 15, 5, 214, 123, 15, 5, 214, 119, 15, 5, 214, 108, 15, 5, 214, - 109, 30, 234, 213, 15, 5, 214, 107, 15, 5, 210, 116, 15, 5, 210, 117, - 216, 240, 15, 5, 210, 117, 92, 30, 233, 202, 15, 5, 210, 113, 15, 5, 210, - 106, 15, 5, 210, 93, 15, 5, 210, 44, 15, 5, 210, 45, 115, 210, 44, 15, 5, - 210, 43, 15, 5, 210, 41, 15, 5, 210, 42, 235, 9, 216, 240, 15, 5, 210, - 36, 15, 5, 210, 28, 15, 5, 210, 13, 15, 5, 210, 11, 15, 5, 210, 12, 30, - 61, 15, 5, 210, 10, 15, 5, 210, 9, 15, 132, 5, 113, 253, 239, 15, 132, 5, - 134, 253, 239, 15, 132, 5, 244, 19, 253, 239, 15, 132, 5, 244, 89, 253, - 239, 15, 132, 5, 219, 127, 253, 239, 15, 132, 5, 220, 124, 253, 239, 15, - 132, 5, 245, 201, 253, 239, 15, 132, 5, 228, 205, 253, 239, 15, 132, 5, - 134, 247, 195, 15, 132, 5, 244, 19, 247, 195, 15, 132, 5, 244, 89, 247, - 195, 15, 132, 5, 219, 127, 247, 195, 15, 132, 5, 220, 124, 247, 195, 15, - 132, 5, 245, 201, 247, 195, 15, 132, 5, 228, 205, 247, 195, 15, 132, 5, - 244, 19, 69, 15, 132, 5, 244, 89, 69, 15, 132, 5, 219, 127, 69, 15, 132, - 5, 220, 124, 69, 15, 132, 5, 245, 201, 69, 15, 132, 5, 228, 205, 69, 15, - 132, 5, 123, 243, 45, 15, 132, 5, 113, 243, 45, 15, 132, 5, 134, 243, 45, - 15, 132, 5, 244, 19, 243, 45, 15, 132, 5, 244, 89, 243, 45, 15, 132, 5, - 219, 127, 243, 45, 15, 132, 5, 220, 124, 243, 45, 15, 132, 5, 245, 201, - 243, 45, 15, 132, 5, 228, 205, 243, 45, 15, 132, 5, 123, 243, 42, 15, - 132, 5, 113, 243, 42, 15, 132, 5, 134, 243, 42, 15, 132, 5, 244, 19, 243, - 42, 15, 132, 5, 244, 89, 243, 42, 15, 132, 5, 113, 220, 80, 15, 132, 5, - 134, 220, 80, 15, 132, 5, 134, 220, 81, 214, 12, 17, 15, 132, 5, 244, 19, - 220, 80, 15, 132, 5, 244, 89, 220, 80, 15, 132, 5, 219, 127, 220, 80, 15, - 132, 5, 220, 124, 220, 80, 15, 132, 5, 245, 201, 220, 80, 15, 132, 5, - 228, 205, 220, 80, 15, 132, 5, 123, 220, 75, 15, 132, 5, 113, 220, 75, - 15, 132, 5, 134, 220, 75, 15, 132, 5, 134, 220, 76, 214, 12, 17, 15, 132, - 5, 244, 19, 220, 75, 15, 132, 5, 244, 89, 220, 75, 15, 132, 5, 220, 81, - 30, 243, 126, 96, 247, 195, 15, 132, 5, 220, 81, 30, 243, 126, 96, 230, - 193, 15, 132, 5, 123, 251, 103, 15, 132, 5, 113, 251, 103, 15, 132, 5, - 134, 251, 103, 15, 132, 5, 134, 251, 104, 214, 12, 17, 15, 132, 5, 244, - 19, 251, 103, 15, 132, 5, 244, 89, 251, 103, 15, 132, 5, 134, 214, 12, - 244, 28, 245, 82, 15, 132, 5, 134, 214, 12, 244, 28, 245, 79, 15, 132, 5, - 244, 19, 214, 12, 244, 28, 232, 223, 15, 132, 5, 244, 19, 214, 12, 244, - 28, 232, 221, 15, 132, 5, 244, 19, 214, 12, 244, 28, 232, 224, 61, 15, - 132, 5, 244, 19, 214, 12, 244, 28, 232, 224, 253, 166, 15, 132, 5, 219, - 127, 214, 12, 244, 28, 253, 236, 15, 132, 5, 220, 124, 214, 12, 244, 28, - 236, 15, 15, 132, 5, 220, 124, 214, 12, 244, 28, 236, 17, 61, 15, 132, 5, - 220, 124, 214, 12, 244, 28, 236, 17, 253, 166, 15, 132, 5, 245, 201, 214, - 12, 244, 28, 214, 121, 15, 132, 5, 245, 201, 214, 12, 244, 28, 214, 120, - 15, 132, 5, 228, 205, 214, 12, 244, 28, 236, 31, 15, 132, 5, 228, 205, - 214, 12, 244, 28, 236, 30, 15, 132, 5, 228, 205, 214, 12, 244, 28, 236, - 29, 15, 132, 5, 228, 205, 214, 12, 244, 28, 236, 32, 61, 15, 132, 5, 113, - 253, 240, 216, 240, 15, 132, 5, 134, 253, 240, 216, 240, 15, 132, 5, 244, - 19, 253, 240, 216, 240, 15, 132, 5, 244, 89, 253, 240, 216, 240, 15, 132, - 5, 219, 127, 253, 240, 216, 240, 15, 132, 5, 123, 252, 158, 15, 132, 5, - 113, 252, 158, 15, 132, 5, 134, 252, 158, 15, 132, 5, 244, 19, 252, 158, - 15, 132, 5, 244, 19, 252, 159, 214, 12, 17, 15, 132, 5, 244, 89, 252, - 158, 15, 132, 5, 244, 89, 252, 159, 214, 12, 17, 15, 132, 5, 228, 215, - 15, 132, 5, 228, 216, 15, 132, 5, 123, 245, 78, 15, 132, 5, 113, 245, 78, - 15, 132, 5, 123, 216, 170, 247, 195, 15, 132, 5, 113, 216, 168, 247, 195, - 15, 132, 5, 244, 89, 219, 116, 247, 195, 15, 132, 5, 123, 216, 170, 214, - 12, 244, 28, 61, 15, 132, 5, 113, 216, 168, 214, 12, 244, 28, 61, 15, - 132, 5, 123, 245, 197, 253, 239, 15, 132, 5, 123, 224, 25, 253, 239, 15, - 132, 5, 55, 253, 227, 123, 219, 117, 15, 132, 5, 55, 253, 227, 123, 224, - 24, 15, 224, 144, 5, 55, 253, 227, 211, 209, 247, 180, 15, 224, 144, 5, - 67, 249, 234, 15, 224, 144, 5, 248, 7, 249, 234, 15, 224, 144, 5, 248, 7, - 215, 222, 12, 13, 255, 164, 12, 13, 255, 163, 12, 13, 255, 162, 12, 13, - 255, 161, 12, 13, 255, 160, 12, 13, 255, 159, 12, 13, 255, 158, 12, 13, - 255, 157, 12, 13, 255, 156, 12, 13, 255, 155, 12, 13, 255, 154, 12, 13, - 255, 153, 12, 13, 255, 152, 12, 13, 255, 151, 12, 13, 255, 150, 12, 13, - 255, 149, 12, 13, 255, 148, 12, 13, 255, 147, 12, 13, 255, 146, 12, 13, - 255, 145, 12, 13, 255, 144, 12, 13, 255, 143, 12, 13, 255, 142, 12, 13, - 255, 141, 12, 13, 255, 140, 12, 13, 255, 139, 12, 13, 255, 138, 12, 13, - 255, 137, 12, 13, 255, 136, 12, 13, 255, 135, 12, 13, 255, 134, 12, 13, - 255, 133, 12, 13, 255, 132, 12, 13, 255, 131, 12, 13, 255, 130, 12, 13, - 255, 129, 12, 13, 255, 128, 12, 13, 255, 127, 12, 13, 255, 126, 12, 13, - 255, 125, 12, 13, 255, 124, 12, 13, 255, 123, 12, 13, 255, 122, 12, 13, - 255, 121, 12, 13, 255, 120, 12, 13, 255, 119, 12, 13, 255, 118, 12, 13, - 255, 117, 12, 13, 255, 116, 12, 13, 255, 115, 12, 13, 255, 114, 12, 13, - 255, 113, 12, 13, 255, 112, 12, 13, 255, 111, 12, 13, 255, 110, 12, 13, - 255, 109, 12, 13, 255, 108, 12, 13, 255, 107, 12, 13, 255, 106, 12, 13, - 255, 105, 12, 13, 255, 104, 12, 13, 255, 103, 12, 13, 255, 102, 12, 13, - 255, 101, 12, 13, 255, 100, 12, 13, 255, 99, 12, 13, 255, 98, 12, 13, - 255, 97, 12, 13, 255, 96, 12, 13, 255, 95, 12, 13, 255, 94, 12, 13, 255, - 93, 12, 13, 255, 92, 12, 13, 255, 91, 12, 13, 255, 90, 12, 13, 255, 89, - 12, 13, 255, 88, 12, 13, 255, 87, 12, 13, 255, 86, 12, 13, 255, 85, 12, - 13, 253, 164, 12, 13, 253, 162, 12, 13, 253, 160, 12, 13, 253, 158, 12, - 13, 253, 156, 12, 13, 253, 155, 12, 13, 253, 153, 12, 13, 253, 151, 12, - 13, 253, 149, 12, 13, 253, 147, 12, 13, 251, 70, 12, 13, 251, 69, 12, 13, - 251, 68, 12, 13, 251, 67, 12, 13, 251, 66, 12, 13, 251, 65, 12, 13, 251, - 64, 12, 13, 251, 63, 12, 13, 251, 62, 12, 13, 251, 61, 12, 13, 251, 60, - 12, 13, 251, 59, 12, 13, 251, 58, 12, 13, 251, 57, 12, 13, 251, 56, 12, - 13, 251, 55, 12, 13, 251, 54, 12, 13, 251, 53, 12, 13, 251, 52, 12, 13, - 251, 51, 12, 13, 251, 50, 12, 13, 251, 49, 12, 13, 251, 48, 12, 13, 251, - 47, 12, 13, 251, 46, 12, 13, 251, 45, 12, 13, 251, 44, 12, 13, 251, 43, - 12, 13, 249, 67, 12, 13, 249, 66, 12, 13, 249, 65, 12, 13, 249, 64, 12, - 13, 249, 63, 12, 13, 249, 62, 12, 13, 249, 61, 12, 13, 249, 60, 12, 13, - 249, 59, 12, 13, 249, 58, 12, 13, 249, 57, 12, 13, 249, 56, 12, 13, 249, - 55, 12, 13, 249, 54, 12, 13, 249, 53, 12, 13, 249, 52, 12, 13, 249, 51, - 12, 13, 249, 50, 12, 13, 249, 49, 12, 13, 249, 48, 12, 13, 249, 47, 12, - 13, 249, 46, 12, 13, 249, 45, 12, 13, 249, 44, 12, 13, 249, 43, 12, 13, - 249, 42, 12, 13, 249, 41, 12, 13, 249, 40, 12, 13, 249, 39, 12, 13, 249, - 38, 12, 13, 249, 37, 12, 13, 249, 36, 12, 13, 249, 35, 12, 13, 249, 34, - 12, 13, 249, 33, 12, 13, 249, 32, 12, 13, 249, 31, 12, 13, 249, 30, 12, - 13, 249, 29, 12, 13, 249, 28, 12, 13, 249, 27, 12, 13, 249, 26, 12, 13, - 249, 25, 12, 13, 249, 24, 12, 13, 249, 23, 12, 13, 249, 22, 12, 13, 249, - 21, 12, 13, 249, 20, 12, 13, 249, 19, 12, 13, 249, 18, 12, 13, 249, 17, - 12, 13, 249, 16, 12, 13, 249, 15, 12, 13, 249, 14, 12, 13, 249, 13, 12, - 13, 249, 12, 12, 13, 249, 11, 12, 13, 249, 10, 12, 13, 249, 9, 12, 13, - 249, 8, 12, 13, 249, 7, 12, 13, 249, 6, 12, 13, 249, 5, 12, 13, 249, 4, - 12, 13, 249, 3, 12, 13, 249, 2, 12, 13, 249, 1, 12, 13, 249, 0, 12, 13, - 248, 255, 12, 13, 248, 254, 12, 13, 248, 253, 12, 13, 248, 252, 12, 13, - 248, 251, 12, 13, 248, 250, 12, 13, 248, 249, 12, 13, 248, 248, 12, 13, - 248, 247, 12, 13, 248, 246, 12, 13, 248, 245, 12, 13, 248, 244, 12, 13, - 248, 243, 12, 13, 248, 242, 12, 13, 248, 241, 12, 13, 248, 240, 12, 13, - 248, 239, 12, 13, 248, 238, 12, 13, 248, 237, 12, 13, 248, 236, 12, 13, - 248, 235, 12, 13, 248, 234, 12, 13, 248, 233, 12, 13, 248, 232, 12, 13, - 246, 31, 12, 13, 246, 30, 12, 13, 246, 29, 12, 13, 246, 28, 12, 13, 246, - 27, 12, 13, 246, 26, 12, 13, 246, 25, 12, 13, 246, 24, 12, 13, 246, 23, - 12, 13, 246, 22, 12, 13, 246, 21, 12, 13, 246, 20, 12, 13, 246, 19, 12, - 13, 246, 18, 12, 13, 246, 17, 12, 13, 246, 16, 12, 13, 246, 15, 12, 13, - 246, 14, 12, 13, 246, 13, 12, 13, 246, 12, 12, 13, 246, 11, 12, 13, 246, - 10, 12, 13, 246, 9, 12, 13, 246, 8, 12, 13, 246, 7, 12, 13, 246, 6, 12, - 13, 246, 5, 12, 13, 246, 4, 12, 13, 246, 3, 12, 13, 246, 2, 12, 13, 246, - 1, 12, 13, 246, 0, 12, 13, 245, 255, 12, 13, 245, 254, 12, 13, 245, 253, - 12, 13, 245, 252, 12, 13, 245, 251, 12, 13, 245, 250, 12, 13, 245, 249, - 12, 13, 245, 248, 12, 13, 245, 247, 12, 13, 245, 246, 12, 13, 245, 245, - 12, 13, 245, 244, 12, 13, 245, 13, 12, 13, 245, 12, 12, 13, 245, 11, 12, - 13, 245, 10, 12, 13, 245, 9, 12, 13, 245, 8, 12, 13, 245, 7, 12, 13, 245, - 6, 12, 13, 245, 5, 12, 13, 245, 4, 12, 13, 245, 3, 12, 13, 245, 2, 12, - 13, 245, 1, 12, 13, 245, 0, 12, 13, 244, 255, 12, 13, 244, 254, 12, 13, - 244, 253, 12, 13, 244, 252, 12, 13, 244, 251, 12, 13, 244, 250, 12, 13, - 244, 249, 12, 13, 244, 248, 12, 13, 244, 247, 12, 13, 244, 246, 12, 13, - 244, 245, 12, 13, 244, 244, 12, 13, 244, 243, 12, 13, 244, 242, 12, 13, - 244, 241, 12, 13, 244, 240, 12, 13, 244, 239, 12, 13, 244, 238, 12, 13, - 244, 237, 12, 13, 244, 236, 12, 13, 244, 235, 12, 13, 244, 234, 12, 13, - 244, 233, 12, 13, 244, 232, 12, 13, 244, 231, 12, 13, 244, 230, 12, 13, - 244, 229, 12, 13, 244, 228, 12, 13, 244, 227, 12, 13, 244, 226, 12, 13, - 244, 225, 12, 13, 244, 224, 12, 13, 244, 223, 12, 13, 244, 222, 12, 13, - 244, 221, 12, 13, 244, 220, 12, 13, 244, 219, 12, 13, 244, 218, 12, 13, - 244, 217, 12, 13, 244, 216, 12, 13, 244, 215, 12, 13, 244, 214, 12, 13, - 244, 213, 12, 13, 244, 212, 12, 13, 244, 211, 12, 13, 244, 210, 12, 13, - 244, 209, 12, 13, 244, 208, 12, 13, 244, 207, 12, 13, 244, 206, 12, 13, - 244, 205, 12, 13, 243, 208, 12, 13, 243, 207, 12, 13, 243, 206, 12, 13, - 243, 205, 12, 13, 243, 204, 12, 13, 243, 203, 12, 13, 243, 202, 12, 13, - 243, 201, 12, 13, 243, 200, 12, 13, 243, 199, 12, 13, 243, 198, 12, 13, - 243, 197, 12, 13, 243, 196, 12, 13, 243, 195, 12, 13, 243, 194, 12, 13, - 243, 193, 12, 13, 243, 192, 12, 13, 243, 191, 12, 13, 243, 190, 12, 13, - 243, 189, 12, 13, 243, 188, 12, 13, 243, 187, 12, 13, 243, 186, 12, 13, - 243, 185, 12, 13, 243, 184, 12, 13, 243, 183, 12, 13, 243, 182, 12, 13, - 243, 181, 12, 13, 243, 180, 12, 13, 243, 179, 12, 13, 243, 178, 12, 13, - 243, 177, 12, 13, 243, 176, 12, 13, 243, 175, 12, 13, 243, 174, 12, 13, - 243, 173, 12, 13, 243, 172, 12, 13, 243, 171, 12, 13, 243, 170, 12, 13, - 243, 169, 12, 13, 243, 168, 12, 13, 243, 167, 12, 13, 243, 166, 12, 13, - 243, 165, 12, 13, 243, 164, 12, 13, 243, 163, 12, 13, 243, 162, 12, 13, - 243, 161, 12, 13, 243, 160, 12, 13, 243, 159, 12, 13, 243, 158, 12, 13, - 243, 157, 12, 13, 243, 156, 12, 13, 243, 155, 12, 13, 243, 154, 12, 13, - 243, 153, 12, 13, 243, 152, 12, 13, 243, 151, 12, 13, 243, 150, 12, 13, - 243, 149, 12, 13, 243, 148, 12, 13, 243, 147, 12, 13, 243, 146, 12, 13, - 243, 145, 12, 13, 242, 65, 12, 13, 242, 64, 12, 13, 242, 63, 12, 13, 242, - 62, 12, 13, 242, 61, 12, 13, 242, 60, 12, 13, 242, 59, 12, 13, 242, 58, - 12, 13, 242, 57, 12, 13, 240, 145, 12, 13, 240, 144, 12, 13, 240, 143, - 12, 13, 240, 142, 12, 13, 240, 141, 12, 13, 240, 140, 12, 13, 240, 139, - 12, 13, 240, 138, 12, 13, 240, 137, 12, 13, 240, 136, 12, 13, 240, 135, - 12, 13, 240, 134, 12, 13, 240, 133, 12, 13, 240, 132, 12, 13, 240, 131, - 12, 13, 240, 130, 12, 13, 240, 129, 12, 13, 240, 128, 12, 13, 240, 127, - 12, 13, 235, 28, 12, 13, 235, 27, 12, 13, 235, 26, 12, 13, 235, 25, 12, - 13, 235, 24, 12, 13, 235, 23, 12, 13, 235, 22, 12, 13, 235, 21, 12, 13, - 233, 152, 12, 13, 233, 151, 12, 13, 233, 150, 12, 13, 233, 149, 12, 13, - 233, 148, 12, 13, 233, 147, 12, 13, 233, 146, 12, 13, 233, 145, 12, 13, - 233, 144, 12, 13, 233, 143, 12, 13, 232, 54, 12, 13, 232, 53, 12, 13, - 232, 52, 12, 13, 232, 51, 12, 13, 232, 50, 12, 13, 232, 49, 12, 13, 232, - 48, 12, 13, 232, 47, 12, 13, 232, 46, 12, 13, 232, 45, 12, 13, 232, 44, - 12, 13, 232, 43, 12, 13, 232, 42, 12, 13, 232, 41, 12, 13, 232, 40, 12, - 13, 232, 39, 12, 13, 232, 38, 12, 13, 232, 37, 12, 13, 232, 36, 12, 13, - 232, 35, 12, 13, 232, 34, 12, 13, 232, 33, 12, 13, 232, 32, 12, 13, 232, - 31, 12, 13, 232, 30, 12, 13, 232, 29, 12, 13, 232, 28, 12, 13, 232, 27, - 12, 13, 232, 26, 12, 13, 232, 25, 12, 13, 232, 24, 12, 13, 232, 23, 12, - 13, 232, 22, 12, 13, 232, 21, 12, 13, 232, 20, 12, 13, 232, 19, 12, 13, - 232, 18, 12, 13, 232, 17, 12, 13, 232, 16, 12, 13, 232, 15, 12, 13, 232, - 14, 12, 13, 232, 13, 12, 13, 232, 12, 12, 13, 232, 11, 12, 13, 232, 10, - 12, 13, 232, 9, 12, 13, 232, 8, 12, 13, 232, 7, 12, 13, 232, 6, 12, 13, - 232, 5, 12, 13, 232, 4, 12, 13, 232, 3, 12, 13, 232, 2, 12, 13, 232, 1, - 12, 13, 232, 0, 12, 13, 231, 255, 12, 13, 231, 254, 12, 13, 231, 253, 12, - 13, 231, 252, 12, 13, 231, 251, 12, 13, 231, 250, 12, 13, 231, 249, 12, - 13, 231, 248, 12, 13, 231, 247, 12, 13, 231, 246, 12, 13, 231, 245, 12, - 13, 230, 27, 12, 13, 230, 26, 12, 13, 230, 25, 12, 13, 230, 24, 12, 13, - 230, 23, 12, 13, 230, 22, 12, 13, 230, 21, 12, 13, 230, 20, 12, 13, 230, - 19, 12, 13, 230, 18, 12, 13, 230, 17, 12, 13, 230, 16, 12, 13, 230, 15, - 12, 13, 230, 14, 12, 13, 230, 13, 12, 13, 230, 12, 12, 13, 230, 11, 12, - 13, 230, 10, 12, 13, 230, 9, 12, 13, 230, 8, 12, 13, 230, 7, 12, 13, 230, - 6, 12, 13, 230, 5, 12, 13, 230, 4, 12, 13, 230, 3, 12, 13, 230, 2, 12, - 13, 230, 1, 12, 13, 230, 0, 12, 13, 229, 255, 12, 13, 229, 254, 12, 13, - 229, 253, 12, 13, 229, 252, 12, 13, 229, 251, 12, 13, 229, 250, 12, 13, - 229, 249, 12, 13, 229, 248, 12, 13, 229, 247, 12, 13, 229, 246, 12, 13, - 229, 245, 12, 13, 229, 244, 12, 13, 229, 243, 12, 13, 229, 242, 12, 13, - 229, 241, 12, 13, 229, 240, 12, 13, 229, 239, 12, 13, 229, 238, 12, 13, - 229, 237, 12, 13, 229, 236, 12, 13, 229, 235, 12, 13, 228, 139, 12, 13, - 228, 138, 12, 13, 228, 137, 12, 13, 228, 136, 12, 13, 228, 135, 12, 13, - 228, 134, 12, 13, 228, 133, 12, 13, 228, 132, 12, 13, 228, 131, 12, 13, - 228, 130, 12, 13, 228, 129, 12, 13, 228, 128, 12, 13, 228, 127, 12, 13, - 228, 126, 12, 13, 228, 125, 12, 13, 228, 124, 12, 13, 228, 123, 12, 13, - 228, 122, 12, 13, 228, 121, 12, 13, 228, 120, 12, 13, 228, 119, 12, 13, - 228, 118, 12, 13, 227, 241, 12, 13, 227, 240, 12, 13, 227, 239, 12, 13, - 227, 238, 12, 13, 227, 237, 12, 13, 227, 236, 12, 13, 227, 235, 12, 13, - 227, 234, 12, 13, 227, 233, 12, 13, 227, 232, 12, 13, 227, 231, 12, 13, - 227, 230, 12, 13, 227, 229, 12, 13, 227, 228, 12, 13, 227, 227, 12, 13, - 227, 226, 12, 13, 227, 225, 12, 13, 227, 224, 12, 13, 227, 223, 12, 13, - 227, 222, 12, 13, 227, 221, 12, 13, 227, 220, 12, 13, 227, 219, 12, 13, - 227, 218, 12, 13, 227, 217, 12, 13, 227, 216, 12, 13, 227, 80, 12, 13, - 227, 79, 12, 13, 227, 78, 12, 13, 227, 77, 12, 13, 227, 76, 12, 13, 227, - 75, 12, 13, 227, 74, 12, 13, 227, 73, 12, 13, 227, 72, 12, 13, 227, 71, - 12, 13, 227, 70, 12, 13, 227, 69, 12, 13, 227, 68, 12, 13, 227, 67, 12, - 13, 227, 66, 12, 13, 227, 65, 12, 13, 227, 64, 12, 13, 227, 63, 12, 13, - 227, 62, 12, 13, 227, 61, 12, 13, 227, 60, 12, 13, 227, 59, 12, 13, 227, - 58, 12, 13, 227, 57, 12, 13, 227, 56, 12, 13, 227, 55, 12, 13, 227, 54, - 12, 13, 227, 53, 12, 13, 227, 52, 12, 13, 227, 51, 12, 13, 227, 50, 12, - 13, 227, 49, 12, 13, 227, 48, 12, 13, 227, 47, 12, 13, 227, 46, 12, 13, - 227, 45, 12, 13, 227, 44, 12, 13, 227, 43, 12, 13, 227, 42, 12, 13, 227, - 41, 12, 13, 227, 40, 12, 13, 227, 39, 12, 13, 227, 38, 12, 13, 227, 37, - 12, 13, 227, 36, 12, 13, 227, 35, 12, 13, 227, 34, 12, 13, 227, 33, 12, - 13, 227, 32, 12, 13, 227, 31, 12, 13, 227, 30, 12, 13, 227, 29, 12, 13, - 227, 28, 12, 13, 227, 27, 12, 13, 227, 26, 12, 13, 227, 25, 12, 13, 227, - 24, 12, 13, 227, 23, 12, 13, 227, 22, 12, 13, 227, 21, 12, 13, 227, 20, - 12, 13, 227, 19, 12, 13, 227, 18, 12, 13, 227, 17, 12, 13, 227, 16, 12, - 13, 227, 15, 12, 13, 227, 14, 12, 13, 227, 13, 12, 13, 227, 12, 12, 13, - 227, 11, 12, 13, 227, 10, 12, 13, 227, 9, 12, 13, 227, 8, 12, 13, 227, 7, - 12, 13, 227, 6, 12, 13, 226, 108, 12, 13, 226, 107, 12, 13, 226, 106, 12, - 13, 226, 105, 12, 13, 226, 104, 12, 13, 226, 103, 12, 13, 226, 102, 12, - 13, 226, 101, 12, 13, 226, 100, 12, 13, 226, 99, 12, 13, 226, 98, 12, 13, - 226, 97, 12, 13, 226, 96, 12, 13, 224, 98, 12, 13, 224, 97, 12, 13, 224, - 96, 12, 13, 224, 95, 12, 13, 224, 94, 12, 13, 224, 93, 12, 13, 224, 92, - 12, 13, 223, 225, 12, 13, 223, 224, 12, 13, 223, 223, 12, 13, 223, 222, - 12, 13, 223, 221, 12, 13, 223, 220, 12, 13, 223, 219, 12, 13, 223, 218, - 12, 13, 223, 217, 12, 13, 223, 216, 12, 13, 223, 215, 12, 13, 223, 214, - 12, 13, 223, 213, 12, 13, 223, 212, 12, 13, 223, 211, 12, 13, 223, 210, - 12, 13, 223, 209, 12, 13, 223, 208, 12, 13, 223, 207, 12, 13, 223, 206, - 12, 13, 223, 205, 12, 13, 223, 204, 12, 13, 223, 203, 12, 13, 223, 202, - 12, 13, 223, 201, 12, 13, 223, 200, 12, 13, 223, 199, 12, 13, 223, 198, - 12, 13, 223, 197, 12, 13, 223, 196, 12, 13, 223, 195, 12, 13, 223, 194, - 12, 13, 223, 193, 12, 13, 223, 192, 12, 13, 222, 90, 12, 13, 222, 89, 12, - 13, 222, 88, 12, 13, 222, 87, 12, 13, 222, 86, 12, 13, 222, 85, 12, 13, - 222, 84, 12, 13, 222, 83, 12, 13, 222, 82, 12, 13, 222, 81, 12, 13, 222, - 80, 12, 13, 222, 79, 12, 13, 222, 78, 12, 13, 222, 77, 12, 13, 222, 76, - 12, 13, 222, 75, 12, 13, 222, 74, 12, 13, 222, 73, 12, 13, 222, 72, 12, - 13, 222, 71, 12, 13, 222, 70, 12, 13, 222, 69, 12, 13, 222, 68, 12, 13, - 222, 67, 12, 13, 222, 66, 12, 13, 222, 65, 12, 13, 222, 64, 12, 13, 222, - 63, 12, 13, 222, 62, 12, 13, 222, 61, 12, 13, 222, 60, 12, 13, 222, 59, - 12, 13, 222, 58, 12, 13, 222, 57, 12, 13, 222, 56, 12, 13, 222, 55, 12, - 13, 222, 54, 12, 13, 222, 53, 12, 13, 222, 52, 12, 13, 222, 51, 12, 13, - 222, 50, 12, 13, 222, 49, 12, 13, 222, 48, 12, 13, 222, 47, 12, 13, 222, - 46, 12, 13, 222, 45, 12, 13, 222, 44, 12, 13, 222, 43, 12, 13, 222, 42, - 12, 13, 222, 41, 12, 13, 222, 40, 12, 13, 222, 39, 12, 13, 222, 38, 12, - 13, 222, 37, 12, 13, 217, 151, 12, 13, 217, 150, 12, 13, 217, 149, 12, - 13, 217, 148, 12, 13, 217, 147, 12, 13, 217, 146, 12, 13, 217, 145, 12, - 13, 217, 144, 12, 13, 217, 143, 12, 13, 217, 142, 12, 13, 217, 141, 12, - 13, 217, 140, 12, 13, 217, 139, 12, 13, 217, 138, 12, 13, 217, 137, 12, - 13, 217, 136, 12, 13, 217, 135, 12, 13, 217, 134, 12, 13, 217, 133, 12, - 13, 217, 132, 12, 13, 217, 131, 12, 13, 217, 130, 12, 13, 217, 129, 12, - 13, 217, 128, 12, 13, 217, 127, 12, 13, 217, 126, 12, 13, 217, 125, 12, - 13, 217, 124, 12, 13, 217, 123, 12, 13, 217, 122, 12, 13, 217, 121, 12, - 13, 217, 120, 12, 13, 217, 119, 12, 13, 217, 118, 12, 13, 217, 117, 12, - 13, 217, 116, 12, 13, 217, 115, 12, 13, 217, 114, 12, 13, 217, 113, 12, - 13, 217, 112, 12, 13, 217, 111, 12, 13, 217, 110, 12, 13, 217, 109, 12, - 13, 217, 108, 12, 13, 215, 22, 12, 13, 215, 21, 12, 13, 215, 20, 12, 13, - 215, 19, 12, 13, 215, 18, 12, 13, 215, 17, 12, 13, 215, 16, 12, 13, 215, - 15, 12, 13, 215, 14, 12, 13, 215, 13, 12, 13, 215, 12, 12, 13, 215, 11, - 12, 13, 215, 10, 12, 13, 215, 9, 12, 13, 215, 8, 12, 13, 215, 7, 12, 13, - 215, 6, 12, 13, 215, 5, 12, 13, 215, 4, 12, 13, 215, 3, 12, 13, 215, 2, - 12, 13, 215, 1, 12, 13, 215, 0, 12, 13, 214, 255, 12, 13, 214, 254, 12, - 13, 214, 253, 12, 13, 214, 252, 12, 13, 214, 251, 12, 13, 214, 250, 12, - 13, 214, 249, 12, 13, 214, 248, 12, 13, 214, 247, 12, 13, 214, 246, 12, - 13, 214, 245, 12, 13, 214, 244, 12, 13, 214, 243, 12, 13, 214, 242, 12, - 13, 214, 241, 12, 13, 214, 240, 12, 13, 214, 239, 12, 13, 214, 238, 12, - 13, 214, 237, 12, 13, 214, 236, 12, 13, 214, 235, 12, 13, 214, 234, 12, - 13, 214, 233, 12, 13, 214, 232, 12, 13, 214, 104, 12, 13, 214, 103, 12, - 13, 214, 102, 12, 13, 214, 101, 12, 13, 214, 100, 12, 13, 214, 99, 12, - 13, 214, 98, 12, 13, 214, 97, 12, 13, 214, 96, 12, 13, 214, 95, 12, 13, - 214, 94, 12, 13, 214, 93, 12, 13, 214, 92, 12, 13, 214, 91, 12, 13, 214, - 90, 12, 13, 214, 89, 12, 13, 214, 88, 12, 13, 214, 87, 12, 13, 214, 86, - 12, 13, 214, 85, 12, 13, 214, 84, 12, 13, 214, 83, 12, 13, 214, 82, 12, - 13, 214, 81, 12, 13, 214, 80, 12, 13, 214, 79, 12, 13, 214, 78, 12, 13, - 214, 77, 12, 13, 214, 76, 12, 13, 214, 75, 12, 13, 214, 74, 12, 13, 214, - 73, 12, 13, 214, 72, 12, 13, 214, 71, 12, 13, 214, 70, 12, 13, 214, 69, - 12, 13, 214, 68, 12, 13, 214, 67, 12, 13, 214, 66, 12, 13, 214, 65, 12, - 13, 214, 64, 12, 13, 214, 63, 12, 13, 214, 62, 12, 13, 214, 61, 12, 13, - 214, 60, 12, 13, 214, 59, 12, 13, 214, 58, 12, 13, 214, 57, 12, 13, 214, - 56, 12, 13, 214, 55, 12, 13, 214, 54, 12, 13, 214, 53, 12, 13, 214, 52, - 12, 13, 214, 51, 12, 13, 214, 50, 12, 13, 214, 49, 12, 13, 214, 48, 12, - 13, 214, 47, 12, 13, 214, 46, 12, 13, 214, 45, 12, 13, 214, 44, 12, 13, - 214, 43, 12, 13, 214, 42, 12, 13, 214, 41, 12, 13, 214, 40, 12, 13, 214, - 39, 12, 13, 214, 38, 12, 13, 214, 37, 12, 13, 214, 36, 12, 13, 214, 35, - 12, 13, 214, 34, 12, 13, 214, 33, 12, 13, 214, 32, 12, 13, 214, 31, 12, - 13, 214, 30, 12, 13, 214, 29, 12, 13, 214, 28, 12, 13, 212, 97, 12, 13, - 212, 96, 12, 13, 212, 95, 12, 13, 212, 94, 12, 13, 212, 93, 12, 13, 212, - 92, 12, 13, 212, 91, 12, 13, 212, 90, 12, 13, 212, 89, 12, 13, 212, 88, - 12, 13, 212, 87, 12, 13, 212, 86, 12, 13, 212, 85, 12, 13, 212, 84, 12, - 13, 212, 83, 12, 13, 212, 82, 12, 13, 212, 81, 12, 13, 212, 80, 12, 13, - 212, 79, 12, 13, 212, 78, 12, 13, 212, 77, 12, 13, 212, 76, 12, 13, 212, - 75, 12, 13, 212, 74, 12, 13, 212, 73, 12, 13, 212, 72, 12, 13, 212, 71, - 12, 13, 212, 70, 12, 13, 212, 69, 12, 13, 212, 68, 12, 13, 212, 67, 12, - 13, 212, 66, 12, 13, 211, 177, 12, 13, 211, 176, 12, 13, 211, 175, 12, - 13, 211, 174, 12, 13, 211, 173, 12, 13, 211, 172, 12, 13, 211, 171, 12, - 13, 211, 170, 12, 13, 211, 169, 12, 13, 211, 168, 12, 13, 211, 167, 12, - 13, 211, 166, 12, 13, 211, 115, 12, 13, 211, 114, 12, 13, 211, 113, 12, - 13, 211, 112, 12, 13, 211, 111, 12, 13, 211, 110, 12, 13, 211, 109, 12, - 13, 211, 108, 12, 13, 211, 107, 12, 13, 210, 158, 12, 13, 210, 157, 12, - 13, 210, 156, 12, 13, 210, 155, 12, 13, 210, 154, 12, 13, 210, 153, 12, - 13, 210, 152, 12, 13, 210, 151, 12, 13, 210, 150, 12, 13, 210, 149, 12, - 13, 210, 148, 12, 13, 210, 147, 12, 13, 210, 146, 12, 13, 210, 145, 12, - 13, 210, 144, 12, 13, 210, 143, 12, 13, 210, 142, 12, 13, 210, 141, 12, - 13, 210, 140, 12, 13, 210, 139, 12, 13, 210, 138, 12, 13, 210, 137, 12, - 13, 210, 136, 12, 13, 210, 135, 12, 13, 210, 134, 12, 13, 210, 133, 12, - 13, 210, 132, 12, 13, 210, 131, 12, 13, 210, 130, 12, 13, 210, 129, 12, - 13, 210, 128, 12, 13, 210, 127, 12, 13, 210, 126, 12, 13, 210, 125, 12, - 13, 210, 124, 12, 13, 210, 123, 12, 13, 210, 122, 12, 13, 210, 121, 12, - 13, 210, 120, 12, 13, 210, 119, 12, 13, 210, 118, 12, 13, 255, 81, 12, - 13, 255, 80, 12, 13, 255, 79, 12, 13, 255, 78, 12, 13, 255, 77, 12, 13, - 255, 76, 12, 13, 255, 75, 12, 13, 255, 74, 12, 13, 255, 73, 12, 13, 255, - 72, 12, 13, 255, 71, 12, 13, 255, 70, 12, 13, 255, 69, 12, 13, 255, 68, - 12, 13, 255, 67, 12, 13, 255, 66, 12, 13, 255, 65, 12, 13, 255, 64, 12, - 13, 255, 63, 12, 13, 255, 62, 12, 13, 255, 61, 12, 13, 255, 60, 12, 13, - 255, 59, 12, 13, 255, 58, 12, 13, 255, 57, 12, 13, 255, 56, 12, 13, 255, - 55, 12, 13, 255, 54, 12, 13, 255, 53, 12, 13, 255, 52, 12, 13, 255, 51, - 12, 13, 255, 50, 12, 13, 255, 49, 12, 13, 255, 48, 20, 1, 167, 229, 17, - 231, 21, 20, 1, 167, 243, 77, 244, 44, 20, 1, 167, 224, 254, 231, 22, - 225, 60, 20, 1, 167, 224, 254, 231, 22, 225, 61, 20, 1, 167, 229, 231, - 231, 21, 20, 1, 167, 219, 223, 20, 1, 167, 216, 67, 231, 21, 20, 1, 167, - 227, 122, 231, 21, 20, 1, 167, 220, 21, 226, 94, 228, 174, 20, 1, 167, - 224, 254, 226, 94, 228, 175, 225, 60, 20, 1, 167, 224, 254, 226, 94, 228, - 175, 225, 61, 20, 1, 167, 231, 223, 20, 1, 167, 215, 120, 231, 224, 20, - 1, 167, 229, 76, 20, 1, 167, 231, 220, 20, 1, 167, 231, 181, 20, 1, 167, - 230, 53, 20, 1, 167, 220, 126, 20, 1, 167, 227, 246, 20, 1, 167, 234, - 155, 20, 1, 167, 228, 143, 20, 1, 167, 218, 5, 20, 1, 167, 229, 16, 20, - 1, 167, 233, 93, 20, 1, 167, 233, 18, 233, 195, 20, 1, 167, 227, 253, - 231, 29, 20, 1, 167, 231, 227, 20, 1, 167, 225, 250, 20, 1, 167, 242, - 238, 20, 1, 167, 226, 54, 20, 1, 167, 230, 156, 229, 50, 20, 1, 167, 227, - 103, 231, 32, 20, 1, 167, 104, 210, 188, 229, 225, 20, 1, 167, 242, 239, - 20, 1, 167, 227, 253, 227, 254, 20, 1, 167, 219, 130, 20, 1, 167, 231, - 14, 20, 1, 167, 231, 35, 20, 1, 167, 230, 135, 20, 1, 167, 234, 255, 20, - 1, 167, 226, 94, 233, 53, 20, 1, 167, 229, 154, 233, 53, 20, 1, 167, 225, - 161, 20, 1, 167, 231, 221, 20, 1, 167, 228, 212, 20, 1, 167, 224, 137, - 20, 1, 167, 215, 117, 20, 1, 167, 232, 99, 20, 1, 167, 219, 43, 20, 1, - 167, 216, 217, 20, 1, 167, 231, 218, 20, 1, 167, 234, 162, 20, 1, 167, - 229, 150, 20, 1, 167, 233, 207, 20, 1, 167, 230, 136, 20, 1, 167, 219, - 220, 20, 1, 167, 232, 144, 20, 1, 167, 244, 101, 20, 1, 167, 222, 201, - 20, 1, 167, 233, 247, 20, 1, 167, 219, 39, 20, 1, 167, 231, 178, 225, - 102, 20, 1, 167, 220, 14, 20, 1, 167, 227, 252, 20, 1, 167, 219, 255, - 228, 7, 210, 196, 20, 1, 167, 227, 142, 230, 153, 20, 1, 167, 226, 89, - 20, 1, 167, 228, 144, 20, 1, 167, 214, 170, 20, 1, 167, 229, 53, 20, 1, - 167, 231, 217, 20, 1, 167, 228, 186, 20, 1, 167, 231, 124, 20, 1, 167, - 227, 155, 20, 1, 167, 216, 221, 20, 1, 167, 219, 36, 20, 1, 167, 226, 90, - 20, 1, 167, 228, 11, 20, 1, 167, 231, 225, 20, 1, 167, 227, 152, 20, 1, - 167, 234, 222, 20, 1, 167, 228, 14, 20, 1, 167, 213, 250, 20, 1, 167, - 232, 103, 20, 1, 167, 229, 103, 20, 1, 167, 229, 201, 20, 1, 167, 231, - 123, 20, 1, 225, 141, 228, 9, 20, 1, 225, 141, 215, 120, 231, 222, 20, 1, - 225, 141, 219, 187, 20, 1, 225, 141, 220, 130, 215, 119, 20, 1, 225, 141, - 232, 146, 227, 249, 20, 1, 225, 141, 231, 130, 231, 226, 20, 1, 225, 141, - 234, 93, 20, 1, 225, 141, 211, 15, 20, 1, 225, 141, 231, 125, 20, 1, 225, - 141, 234, 243, 20, 1, 225, 141, 225, 211, 20, 1, 225, 141, 211, 89, 233, - 53, 20, 1, 225, 141, 233, 109, 228, 7, 227, 164, 20, 1, 225, 141, 227, - 247, 220, 40, 20, 1, 225, 141, 229, 121, 228, 189, 20, 1, 225, 141, 242, - 236, 20, 1, 225, 141, 225, 52, 20, 1, 225, 141, 215, 120, 228, 5, 20, 1, - 225, 141, 220, 45, 228, 184, 20, 1, 225, 141, 220, 41, 20, 1, 225, 141, - 231, 22, 216, 220, 20, 1, 225, 141, 231, 112, 231, 126, 20, 1, 225, 141, - 227, 153, 227, 249, 20, 1, 225, 141, 234, 151, 20, 1, 225, 141, 242, 237, - 20, 1, 225, 141, 234, 147, 20, 1, 225, 141, 233, 135, 20, 1, 225, 141, - 225, 253, 20, 1, 225, 141, 213, 182, 20, 1, 225, 141, 229, 18, 230, 51, - 20, 1, 225, 141, 229, 52, 231, 108, 20, 1, 225, 141, 211, 193, 20, 1, - 225, 141, 222, 13, 20, 1, 225, 141, 217, 98, 20, 1, 225, 141, 231, 34, - 20, 1, 225, 141, 229, 37, 20, 1, 225, 141, 229, 38, 233, 90, 20, 1, 225, - 141, 231, 24, 20, 1, 225, 141, 218, 53, 20, 1, 225, 141, 231, 116, 20, 1, - 225, 141, 230, 138, 20, 1, 225, 141, 227, 167, 20, 1, 225, 141, 224, 141, - 20, 1, 225, 141, 231, 33, 229, 54, 20, 1, 225, 141, 244, 134, 20, 1, 225, - 141, 231, 103, 20, 1, 225, 141, 244, 155, 20, 1, 225, 141, 234, 159, 20, - 1, 225, 141, 231, 244, 228, 178, 20, 1, 225, 141, 231, 244, 228, 154, 20, - 1, 225, 141, 233, 17, 20, 1, 225, 141, 229, 60, 20, 1, 225, 141, 228, 16, - 20, 1, 225, 141, 186, 20, 1, 225, 141, 234, 80, 20, 1, 225, 141, 229, 6, - 20, 1, 137, 229, 17, 231, 224, 20, 1, 137, 227, 121, 20, 1, 137, 210, - 196, 20, 1, 137, 212, 53, 20, 1, 137, 229, 53, 20, 1, 137, 229, 142, 20, - 1, 137, 229, 24, 20, 1, 137, 242, 246, 20, 1, 137, 231, 120, 20, 1, 137, - 243, 84, 20, 1, 137, 227, 144, 230, 175, 231, 36, 20, 1, 137, 227, 245, - 231, 111, 20, 1, 137, 231, 117, 20, 1, 137, 225, 58, 20, 1, 137, 229, - 127, 20, 1, 137, 231, 128, 251, 37, 20, 1, 137, 234, 149, 20, 1, 137, - 242, 247, 20, 1, 137, 234, 156, 20, 1, 137, 210, 213, 230, 81, 20, 1, - 137, 227, 115, 20, 1, 137, 231, 105, 20, 1, 137, 228, 15, 20, 1, 137, - 231, 111, 20, 1, 137, 211, 16, 20, 1, 137, 233, 255, 20, 1, 137, 235, 16, - 20, 1, 137, 220, 125, 20, 1, 137, 229, 136, 20, 1, 137, 217, 96, 20, 1, - 137, 228, 158, 20, 1, 137, 216, 67, 210, 198, 20, 1, 137, 218, 80, 20, 1, - 137, 229, 44, 227, 164, 20, 1, 137, 213, 181, 20, 1, 137, 229, 204, 20, - 1, 137, 231, 244, 234, 158, 20, 1, 137, 227, 254, 20, 1, 137, 229, 39, - 20, 1, 137, 233, 94, 20, 1, 137, 231, 113, 20, 1, 137, 231, 13, 20, 1, - 137, 227, 248, 20, 1, 137, 216, 216, 20, 1, 137, 229, 41, 20, 1, 137, - 243, 240, 20, 1, 137, 229, 141, 20, 1, 137, 228, 17, 20, 1, 137, 228, 13, - 20, 1, 137, 251, 115, 20, 1, 137, 213, 183, 20, 1, 137, 231, 118, 20, 1, - 137, 222, 142, 20, 1, 137, 228, 188, 20, 1, 137, 233, 108, 20, 1, 137, - 216, 65, 20, 1, 137, 227, 255, 229, 6, 20, 1, 137, 228, 180, 20, 1, 137, - 234, 162, 20, 1, 137, 229, 45, 20, 1, 137, 231, 217, 20, 1, 137, 231, - 106, 20, 1, 137, 232, 103, 20, 1, 137, 233, 195, 20, 1, 137, 228, 186, - 20, 1, 137, 229, 6, 20, 1, 137, 211, 184, 20, 1, 137, 229, 42, 20, 1, - 137, 228, 2, 20, 1, 137, 227, 250, 20, 1, 137, 233, 209, 228, 144, 20, 1, - 137, 228, 0, 20, 1, 137, 229, 149, 20, 1, 137, 231, 244, 228, 5, 20, 1, - 137, 211, 103, 20, 1, 137, 229, 148, 20, 1, 137, 219, 222, 20, 1, 137, - 220, 128, 20, 1, 137, 231, 114, 20, 1, 137, 231, 224, 20, 1, 137, 231, - 124, 20, 1, 137, 234, 150, 20, 1, 137, 231, 115, 20, 1, 137, 234, 154, - 20, 1, 137, 231, 128, 225, 106, 20, 1, 137, 210, 179, 20, 1, 137, 228, - 176, 20, 1, 137, 230, 225, 20, 1, 137, 230, 105, 20, 1, 137, 220, 17, 20, - 1, 137, 234, 172, 233, 76, 20, 1, 137, 234, 172, 244, 168, 20, 1, 137, - 229, 74, 20, 1, 137, 229, 201, 20, 1, 137, 232, 206, 20, 1, 137, 225, 68, - 20, 1, 137, 225, 202, 20, 1, 137, 216, 231, 20, 1, 107, 231, 104, 20, 1, - 107, 212, 51, 20, 1, 107, 228, 174, 20, 1, 107, 231, 21, 20, 1, 107, 228, - 172, 20, 1, 107, 232, 241, 20, 1, 107, 228, 177, 20, 1, 107, 228, 12, 20, - 1, 107, 229, 59, 20, 1, 107, 227, 164, 20, 1, 107, 211, 194, 20, 1, 107, - 229, 14, 20, 1, 107, 220, 63, 20, 1, 107, 229, 25, 20, 1, 107, 234, 157, - 20, 1, 107, 216, 218, 20, 1, 107, 220, 43, 20, 1, 107, 228, 185, 20, 1, - 107, 218, 53, 20, 1, 107, 234, 162, 20, 1, 107, 211, 91, 20, 1, 107, 233, - 210, 20, 1, 107, 221, 236, 20, 1, 107, 231, 26, 20, 1, 107, 229, 140, 20, - 1, 107, 231, 193, 20, 1, 107, 231, 32, 20, 1, 107, 220, 127, 20, 1, 107, - 211, 39, 20, 1, 107, 228, 179, 20, 1, 107, 234, 153, 231, 107, 20, 1, - 107, 229, 21, 20, 1, 107, 215, 119, 20, 1, 107, 242, 255, 20, 1, 107, - 229, 11, 20, 1, 107, 244, 135, 20, 1, 107, 229, 144, 20, 1, 107, 231, 5, - 20, 1, 107, 233, 11, 20, 1, 107, 229, 126, 20, 1, 107, 230, 152, 20, 1, - 107, 231, 9, 20, 1, 107, 224, 121, 20, 1, 107, 231, 7, 20, 1, 107, 231, - 23, 20, 1, 107, 232, 89, 20, 1, 107, 228, 4, 20, 1, 107, 231, 127, 20, 1, - 107, 233, 186, 20, 1, 107, 227, 155, 20, 1, 107, 216, 221, 20, 1, 107, - 219, 36, 20, 1, 107, 210, 179, 20, 1, 107, 234, 154, 20, 1, 107, 223, - 173, 20, 1, 107, 217, 11, 20, 1, 107, 229, 22, 20, 1, 107, 231, 28, 20, - 1, 107, 228, 3, 20, 1, 107, 234, 152, 20, 1, 107, 225, 62, 20, 1, 107, - 225, 155, 20, 1, 107, 227, 131, 20, 1, 107, 233, 17, 20, 1, 107, 229, 60, - 20, 1, 107, 231, 25, 20, 1, 107, 229, 34, 20, 1, 107, 210, 193, 20, 1, - 107, 226, 25, 20, 1, 107, 210, 192, 20, 1, 107, 229, 149, 20, 1, 107, - 227, 249, 20, 1, 107, 218, 82, 20, 1, 107, 233, 214, 20, 1, 107, 229, 49, - 20, 1, 107, 229, 19, 20, 1, 107, 215, 103, 20, 1, 107, 231, 36, 20, 1, - 107, 233, 204, 20, 1, 107, 228, 1, 20, 1, 107, 216, 219, 20, 1, 107, 231, - 219, 20, 1, 107, 229, 58, 20, 1, 107, 233, 10, 20, 1, 107, 229, 40, 20, - 1, 107, 228, 6, 20, 1, 107, 228, 158, 20, 1, 107, 242, 240, 20, 1, 107, - 233, 223, 20, 1, 107, 223, 87, 226, 213, 20, 1, 107, 217, 87, 20, 1, 107, - 216, 11, 20, 1, 107, 227, 152, 20, 1, 107, 222, 242, 20, 1, 107, 233, 55, - 20, 1, 107, 231, 84, 20, 1, 107, 194, 20, 1, 107, 218, 5, 20, 1, 107, - 230, 107, 20, 1, 107, 220, 29, 20, 1, 107, 220, 39, 20, 1, 107, 233, 161, - 20, 1, 107, 227, 242, 20, 1, 107, 219, 227, 20, 1, 107, 227, 251, 20, 1, - 107, 225, 214, 20, 1, 107, 228, 238, 20, 1, 107, 219, 254, 20, 1, 107, - 224, 136, 20, 1, 107, 230, 51, 20, 1, 107, 232, 125, 20, 1, 107, 223, 87, - 230, 101, 20, 1, 107, 216, 118, 20, 1, 107, 227, 243, 20, 1, 107, 231, - 128, 199, 20, 1, 107, 221, 234, 20, 1, 107, 244, 203, 20, 1, 82, 229, - 148, 20, 1, 82, 216, 17, 20, 1, 82, 231, 117, 20, 1, 82, 233, 94, 20, 1, - 82, 213, 128, 20, 1, 82, 232, 131, 20, 1, 82, 226, 93, 20, 1, 82, 219, - 47, 20, 1, 82, 223, 148, 20, 1, 82, 228, 8, 20, 1, 82, 229, 119, 20, 1, - 82, 224, 150, 20, 1, 82, 217, 63, 20, 1, 82, 229, 27, 20, 1, 82, 233, - 251, 20, 1, 82, 211, 187, 20, 1, 82, 221, 172, 20, 1, 82, 229, 50, 20, 1, - 82, 226, 90, 20, 1, 82, 216, 18, 20, 1, 82, 233, 208, 20, 1, 82, 232, - 145, 20, 1, 82, 228, 11, 20, 1, 82, 229, 3, 20, 1, 82, 231, 225, 20, 1, - 82, 229, 20, 20, 1, 82, 229, 2, 20, 1, 82, 228, 10, 20, 1, 82, 222, 240, - 20, 1, 82, 228, 176, 20, 1, 82, 225, 213, 20, 1, 82, 222, 33, 20, 1, 82, - 229, 35, 20, 1, 82, 231, 15, 20, 1, 82, 242, 234, 20, 1, 82, 229, 23, 20, - 1, 82, 228, 187, 20, 1, 82, 231, 177, 20, 1, 82, 232, 127, 20, 1, 82, - 229, 55, 20, 1, 82, 229, 132, 20, 1, 82, 217, 86, 227, 249, 20, 1, 82, - 220, 129, 20, 1, 82, 224, 146, 20, 1, 82, 229, 152, 219, 53, 20, 1, 82, - 229, 43, 227, 164, 20, 1, 82, 211, 4, 20, 1, 82, 242, 235, 20, 1, 82, - 215, 118, 20, 1, 82, 211, 19, 20, 1, 82, 225, 19, 20, 1, 82, 215, 108, - 20, 1, 82, 234, 160, 20, 1, 82, 218, 81, 20, 1, 82, 216, 220, 20, 1, 82, - 213, 184, 20, 1, 82, 212, 6, 20, 1, 82, 233, 138, 20, 1, 82, 224, 153, - 20, 1, 82, 217, 97, 20, 1, 82, 242, 254, 20, 1, 82, 229, 64, 20, 1, 82, - 220, 42, 20, 1, 82, 231, 10, 20, 1, 82, 231, 121, 20, 1, 82, 227, 119, - 20, 1, 82, 228, 141, 20, 1, 82, 243, 80, 20, 1, 82, 215, 109, 20, 1, 82, - 233, 217, 20, 1, 82, 211, 67, 20, 1, 82, 227, 153, 250, 24, 20, 1, 82, - 210, 250, 20, 1, 82, 231, 27, 20, 1, 82, 229, 137, 20, 1, 82, 225, 103, - 20, 1, 82, 210, 197, 20, 1, 82, 233, 12, 20, 1, 82, 243, 240, 20, 1, 82, - 243, 79, 20, 1, 82, 229, 13, 20, 1, 82, 234, 162, 20, 1, 82, 231, 228, - 20, 1, 82, 229, 26, 20, 1, 82, 242, 241, 20, 1, 82, 244, 204, 20, 1, 82, - 227, 244, 20, 1, 82, 225, 156, 20, 1, 82, 211, 17, 20, 1, 82, 229, 51, - 20, 1, 82, 227, 153, 252, 31, 20, 1, 82, 227, 99, 20, 1, 82, 224, 250, - 20, 1, 82, 230, 225, 20, 1, 82, 243, 238, 20, 1, 82, 229, 225, 20, 1, 82, - 230, 105, 20, 1, 82, 242, 240, 20, 1, 82, 243, 242, 74, 20, 1, 82, 230, - 52, 20, 1, 82, 224, 149, 20, 1, 82, 229, 15, 20, 1, 82, 233, 195, 20, 1, - 82, 225, 100, 20, 1, 82, 227, 252, 20, 1, 82, 211, 18, 20, 1, 82, 229, - 36, 20, 1, 82, 226, 94, 225, 190, 20, 1, 82, 243, 242, 251, 23, 20, 1, - 82, 244, 45, 20, 1, 82, 228, 181, 20, 1, 82, 61, 20, 1, 82, 216, 11, 20, - 1, 82, 78, 20, 1, 82, 74, 20, 1, 82, 233, 92, 20, 1, 82, 226, 94, 225, - 26, 20, 1, 82, 217, 102, 20, 1, 82, 217, 52, 20, 1, 82, 229, 152, 230, - 39, 240, 241, 20, 1, 82, 220, 17, 20, 1, 82, 211, 14, 20, 1, 82, 228, - 252, 20, 1, 82, 210, 202, 20, 1, 82, 210, 227, 217, 241, 20, 1, 82, 210, - 227, 249, 155, 20, 1, 82, 210, 187, 20, 1, 82, 210, 195, 20, 1, 82, 234, - 148, 20, 1, 82, 225, 154, 20, 1, 82, 228, 182, 245, 110, 20, 1, 82, 224, - 147, 20, 1, 82, 211, 192, 20, 1, 82, 244, 155, 20, 1, 82, 213, 250, 20, - 1, 82, 232, 103, 20, 1, 82, 230, 235, 20, 1, 82, 223, 54, 20, 1, 82, 223, - 174, 20, 1, 82, 228, 251, 20, 1, 82, 229, 82, 20, 1, 82, 220, 9, 20, 1, - 82, 219, 254, 20, 1, 82, 243, 242, 223, 89, 20, 1, 82, 198, 20, 1, 82, - 225, 111, 20, 1, 82, 232, 125, 20, 1, 82, 234, 34, 20, 1, 82, 231, 63, - 20, 1, 82, 186, 20, 1, 82, 231, 174, 20, 1, 82, 216, 222, 20, 1, 82, 234, - 98, 20, 1, 82, 230, 155, 20, 1, 82, 216, 248, 20, 1, 82, 244, 177, 20, 1, - 82, 242, 230, 20, 1, 225, 140, 176, 20, 1, 225, 140, 69, 20, 1, 225, 140, - 233, 223, 20, 1, 225, 140, 245, 217, 20, 1, 225, 140, 223, 111, 20, 1, - 225, 140, 217, 87, 20, 1, 225, 140, 227, 152, 20, 1, 225, 140, 233, 141, - 20, 1, 225, 140, 222, 242, 20, 1, 225, 140, 223, 32, 20, 1, 225, 140, - 231, 84, 20, 1, 225, 140, 217, 102, 20, 1, 225, 140, 229, 151, 20, 1, - 225, 140, 228, 188, 20, 1, 225, 140, 194, 20, 1, 225, 140, 218, 5, 20, 1, - 225, 140, 220, 29, 20, 1, 225, 140, 219, 193, 20, 1, 225, 140, 220, 125, - 20, 1, 225, 140, 233, 161, 20, 1, 225, 140, 234, 162, 20, 1, 225, 140, - 227, 213, 20, 1, 225, 140, 227, 242, 20, 1, 225, 140, 228, 159, 20, 1, - 225, 140, 210, 226, 20, 1, 225, 140, 219, 227, 20, 1, 225, 140, 192, 20, - 1, 225, 140, 228, 14, 20, 1, 225, 140, 225, 154, 20, 1, 225, 140, 227, - 251, 20, 1, 225, 140, 211, 192, 20, 1, 225, 140, 225, 214, 20, 1, 225, - 140, 222, 142, 20, 1, 225, 140, 228, 238, 20, 1, 225, 140, 223, 54, 20, - 1, 225, 140, 234, 171, 20, 1, 225, 140, 229, 12, 20, 1, 225, 140, 229, - 61, 20, 1, 225, 140, 220, 9, 20, 1, 225, 140, 224, 150, 20, 1, 225, 140, - 244, 45, 20, 1, 225, 140, 212, 65, 20, 1, 225, 140, 232, 247, 20, 1, 225, - 140, 232, 125, 20, 1, 225, 140, 234, 34, 20, 1, 225, 140, 231, 119, 20, - 1, 225, 140, 223, 86, 20, 1, 225, 140, 186, 20, 1, 225, 140, 230, 166, - 20, 1, 225, 140, 231, 127, 20, 1, 225, 140, 216, 231, 20, 1, 225, 140, - 234, 1, 20, 1, 225, 140, 221, 253, 20, 1, 225, 140, 212, 115, 95, 1, 191, - 95, 1, 252, 199, 95, 1, 8, 191, 95, 1, 225, 45, 95, 1, 186, 95, 1, 230, - 238, 95, 1, 254, 31, 186, 95, 1, 244, 204, 95, 1, 214, 27, 95, 1, 213, - 177, 95, 1, 217, 106, 95, 1, 248, 229, 95, 1, 8, 215, 157, 95, 1, 8, 217, - 106, 95, 1, 215, 157, 95, 1, 248, 143, 95, 1, 198, 95, 1, 228, 242, 95, - 1, 8, 228, 115, 95, 1, 254, 31, 198, 95, 1, 228, 115, 95, 1, 228, 101, - 95, 1, 233, 141, 95, 1, 232, 66, 95, 1, 233, 4, 95, 1, 232, 249, 95, 1, - 216, 57, 95, 1, 247, 161, 95, 1, 216, 49, 95, 1, 247, 160, 95, 1, 176, - 95, 1, 243, 142, 95, 1, 8, 176, 95, 1, 224, 91, 95, 1, 224, 69, 95, 1, - 229, 82, 95, 1, 229, 33, 95, 1, 254, 31, 229, 82, 95, 1, 162, 95, 1, 211, - 165, 95, 1, 243, 0, 95, 1, 242, 233, 95, 1, 215, 166, 95, 1, 246, 34, 95, - 1, 227, 169, 95, 1, 227, 154, 95, 1, 215, 176, 95, 1, 246, 41, 95, 1, 8, - 215, 176, 95, 1, 8, 246, 41, 95, 1, 223, 109, 215, 176, 95, 1, 220, 104, - 95, 1, 218, 225, 95, 1, 210, 82, 95, 1, 210, 14, 95, 1, 215, 184, 95, 1, - 246, 46, 95, 1, 8, 215, 184, 95, 1, 206, 95, 1, 210, 116, 95, 1, 210, 15, - 95, 1, 209, 243, 95, 1, 209, 223, 95, 1, 254, 31, 209, 243, 95, 1, 209, - 215, 95, 1, 209, 222, 95, 1, 212, 65, 95, 1, 254, 218, 95, 1, 241, 196, - 95, 1, 229, 197, 95, 5, 253, 230, 95, 5, 223, 109, 213, 133, 95, 5, 223, - 109, 253, 230, 95, 25, 5, 61, 95, 25, 5, 255, 82, 95, 25, 5, 254, 214, - 95, 25, 5, 254, 131, 95, 25, 5, 254, 123, 95, 25, 5, 78, 95, 25, 5, 226, - 187, 95, 25, 5, 211, 227, 95, 25, 5, 212, 98, 95, 25, 5, 76, 95, 25, 5, - 245, 158, 95, 25, 5, 245, 146, 95, 25, 5, 226, 236, 95, 25, 5, 74, 95, - 25, 5, 240, 126, 95, 25, 5, 240, 125, 95, 25, 5, 240, 124, 95, 25, 5, - 235, 196, 95, 25, 5, 236, 67, 95, 25, 5, 236, 40, 95, 25, 5, 235, 162, - 95, 25, 5, 235, 238, 95, 25, 5, 69, 95, 25, 5, 214, 229, 95, 25, 5, 214, - 228, 95, 25, 5, 214, 227, 95, 25, 5, 214, 118, 95, 25, 5, 214, 211, 95, - 25, 5, 214, 178, 95, 25, 5, 211, 117, 95, 25, 5, 211, 8, 95, 25, 5, 254, - 252, 95, 25, 5, 254, 248, 95, 25, 5, 245, 94, 95, 25, 5, 222, 185, 245, - 94, 95, 25, 5, 245, 100, 95, 25, 5, 222, 185, 245, 100, 95, 25, 5, 254, - 210, 95, 25, 5, 245, 203, 95, 25, 5, 253, 200, 95, 25, 5, 226, 138, 95, - 25, 5, 230, 30, 95, 25, 5, 229, 84, 95, 138, 222, 254, 95, 138, 216, 15, - 222, 254, 95, 138, 48, 95, 138, 51, 95, 1, 216, 29, 95, 1, 216, 28, 95, - 1, 216, 27, 95, 1, 216, 26, 95, 1, 216, 25, 95, 1, 216, 24, 95, 1, 216, - 23, 95, 1, 223, 109, 216, 30, 95, 1, 223, 109, 216, 29, 95, 1, 223, 109, - 216, 27, 95, 1, 223, 109, 216, 26, 95, 1, 223, 109, 216, 25, 95, 1, 223, - 109, 216, 23, 56, 1, 254, 31, 76, 141, 1, 254, 31, 211, 47, 49, 28, 16, - 224, 157, 49, 28, 16, 248, 166, 49, 28, 16, 225, 178, 49, 28, 16, 226, - 117, 245, 186, 49, 28, 16, 226, 117, 247, 209, 49, 28, 16, 214, 16, 245, - 186, 49, 28, 16, 214, 16, 247, 209, 49, 28, 16, 234, 203, 49, 28, 16, - 217, 170, 49, 28, 16, 226, 13, 49, 28, 16, 210, 217, 49, 28, 16, 210, - 218, 247, 209, 49, 28, 16, 233, 240, 49, 28, 16, 254, 76, 245, 186, 49, - 28, 16, 245, 34, 245, 186, 49, 28, 16, 217, 3, 49, 28, 16, 234, 167, 49, - 28, 16, 254, 66, 49, 28, 16, 254, 67, 247, 209, 49, 28, 16, 217, 176, 49, - 28, 16, 216, 160, 49, 28, 16, 226, 210, 254, 29, 49, 28, 16, 242, 166, - 254, 29, 49, 28, 16, 224, 156, 49, 28, 16, 250, 157, 49, 28, 16, 214, 6, - 49, 28, 16, 235, 170, 254, 29, 49, 28, 16, 234, 169, 254, 29, 49, 28, 16, - 234, 168, 254, 29, 49, 28, 16, 221, 215, 49, 28, 16, 226, 4, 49, 28, 16, - 218, 148, 254, 69, 49, 28, 16, 226, 116, 254, 29, 49, 28, 16, 214, 15, - 254, 29, 49, 28, 16, 254, 70, 254, 29, 49, 28, 16, 254, 64, 49, 28, 16, - 234, 43, 49, 28, 16, 223, 49, 49, 28, 16, 225, 109, 254, 29, 49, 28, 16, - 216, 84, 49, 28, 16, 254, 129, 49, 28, 16, 221, 161, 49, 28, 16, 217, - 179, 254, 29, 49, 28, 16, 217, 179, 231, 45, 218, 146, 49, 28, 16, 226, - 111, 254, 29, 49, 28, 16, 216, 191, 49, 28, 16, 233, 33, 49, 28, 16, 246, - 49, 49, 28, 16, 215, 228, 49, 28, 16, 216, 233, 49, 28, 16, 233, 243, 49, - 28, 16, 254, 76, 245, 34, 229, 100, 49, 28, 16, 243, 243, 254, 29, 49, - 28, 16, 236, 19, 49, 28, 16, 215, 200, 254, 29, 49, 28, 16, 234, 206, - 215, 199, 49, 28, 16, 225, 203, 49, 28, 16, 224, 161, 49, 28, 16, 234, - 17, 49, 28, 16, 250, 88, 254, 29, 49, 28, 16, 223, 149, 49, 28, 16, 226, - 16, 254, 29, 49, 28, 16, 226, 14, 254, 29, 49, 28, 16, 240, 116, 49, 28, - 16, 229, 208, 49, 28, 16, 225, 159, 49, 28, 16, 234, 18, 254, 158, 49, - 28, 16, 215, 200, 254, 158, 49, 28, 16, 218, 125, 49, 28, 16, 242, 130, - 49, 28, 16, 235, 170, 229, 100, 49, 28, 16, 226, 210, 229, 100, 49, 28, - 16, 226, 117, 229, 100, 49, 28, 16, 225, 158, 49, 28, 16, 234, 4, 49, 28, - 16, 225, 157, 49, 28, 16, 233, 242, 49, 28, 16, 225, 204, 229, 100, 49, - 28, 16, 234, 168, 229, 101, 254, 104, 49, 28, 16, 234, 169, 229, 101, - 254, 104, 49, 28, 16, 210, 215, 49, 28, 16, 254, 67, 229, 100, 49, 28, - 16, 254, 68, 217, 177, 229, 100, 49, 28, 16, 210, 216, 49, 28, 16, 233, - 241, 49, 28, 16, 245, 181, 49, 28, 16, 250, 158, 49, 28, 16, 230, 203, - 235, 169, 49, 28, 16, 214, 16, 229, 100, 49, 28, 16, 225, 109, 229, 100, - 49, 28, 16, 224, 162, 229, 100, 49, 28, 16, 226, 207, 49, 28, 16, 254, - 92, 49, 28, 16, 232, 63, 49, 28, 16, 226, 14, 229, 100, 49, 28, 16, 226, - 16, 229, 100, 49, 28, 16, 245, 68, 226, 15, 49, 28, 16, 233, 159, 49, 28, - 16, 254, 93, 49, 28, 16, 215, 200, 229, 100, 49, 28, 16, 245, 184, 49, - 28, 16, 217, 179, 229, 100, 49, 28, 16, 217, 171, 49, 28, 16, 250, 88, - 229, 100, 49, 28, 16, 245, 114, 49, 28, 16, 221, 162, 229, 100, 49, 28, - 16, 211, 151, 234, 43, 49, 28, 16, 215, 197, 49, 28, 16, 224, 163, 49, - 28, 16, 215, 201, 49, 28, 16, 215, 198, 49, 28, 16, 224, 160, 49, 28, 16, - 215, 196, 49, 28, 16, 224, 159, 49, 28, 16, 242, 165, 49, 28, 16, 254, - 22, 49, 28, 16, 245, 68, 254, 22, 49, 28, 16, 226, 111, 229, 100, 49, 28, - 16, 216, 190, 245, 77, 49, 28, 16, 216, 190, 245, 33, 49, 28, 16, 216, - 192, 254, 71, 49, 28, 16, 216, 185, 234, 253, 254, 63, 49, 28, 16, 234, - 205, 49, 28, 16, 245, 147, 49, 28, 16, 211, 11, 234, 202, 49, 28, 16, - 211, 11, 254, 104, 49, 28, 16, 218, 147, 49, 28, 16, 234, 44, 254, 104, - 49, 28, 16, 247, 210, 254, 29, 49, 28, 16, 233, 244, 254, 29, 49, 28, 16, - 233, 244, 254, 158, 49, 28, 16, 233, 244, 229, 100, 49, 28, 16, 254, 70, - 229, 100, 49, 28, 16, 254, 72, 49, 28, 16, 247, 209, 49, 28, 16, 215, - 211, 49, 28, 16, 216, 225, 49, 28, 16, 234, 8, 49, 28, 16, 233, 38, 245, - 142, 250, 79, 49, 28, 16, 233, 38, 246, 50, 250, 80, 49, 28, 16, 233, 38, - 215, 213, 250, 80, 49, 28, 16, 233, 38, 216, 235, 250, 80, 49, 28, 16, - 233, 38, 236, 14, 250, 79, 49, 28, 16, 242, 166, 229, 101, 254, 104, 49, - 28, 16, 242, 166, 226, 5, 254, 18, 49, 28, 16, 242, 166, 226, 5, 248, 37, - 49, 28, 16, 247, 233, 49, 28, 16, 247, 234, 226, 5, 254, 19, 234, 202, - 49, 28, 16, 247, 234, 226, 5, 254, 19, 254, 104, 49, 28, 16, 247, 234, - 226, 5, 248, 37, 49, 28, 16, 215, 217, 49, 28, 16, 254, 23, 49, 28, 16, - 236, 21, 49, 28, 16, 247, 254, 49, 28, 16, 254, 220, 225, 3, 254, 24, 49, - 28, 16, 254, 220, 254, 21, 49, 28, 16, 254, 220, 254, 24, 49, 28, 16, - 254, 220, 231, 39, 49, 28, 16, 254, 220, 231, 50, 49, 28, 16, 254, 220, - 242, 167, 49, 28, 16, 254, 220, 242, 164, 49, 28, 16, 254, 220, 225, 3, - 242, 167, 49, 28, 16, 231, 156, 224, 168, 240, 114, 49, 28, 16, 231, 156, - 254, 160, 224, 168, 240, 114, 49, 28, 16, 231, 156, 248, 36, 240, 114, - 49, 28, 16, 231, 156, 254, 160, 248, 36, 240, 114, 49, 28, 16, 231, 156, - 215, 206, 240, 114, 49, 28, 16, 231, 156, 215, 218, 49, 28, 16, 231, 156, - 216, 229, 240, 114, 49, 28, 16, 231, 156, 216, 229, 233, 41, 240, 114, - 49, 28, 16, 231, 156, 233, 41, 240, 114, 49, 28, 16, 231, 156, 225, 42, - 240, 114, 49, 28, 16, 235, 176, 216, 252, 240, 115, 49, 28, 16, 254, 68, - 216, 252, 240, 115, 49, 28, 16, 244, 180, 216, 226, 49, 28, 16, 244, 180, - 230, 148, 49, 28, 16, 244, 180, 247, 238, 49, 28, 16, 231, 156, 214, 10, - 240, 114, 49, 28, 16, 231, 156, 224, 167, 240, 114, 49, 28, 16, 231, 156, - 225, 42, 216, 229, 240, 114, 49, 28, 16, 242, 162, 230, 31, 254, 71, 49, - 28, 16, 242, 162, 230, 31, 247, 208, 49, 28, 16, 245, 156, 234, 253, 243, - 243, 213, 124, 49, 28, 16, 236, 20, 49, 28, 16, 236, 18, 49, 28, 16, 243, - 243, 254, 30, 248, 35, 240, 113, 49, 28, 16, 243, 243, 247, 252, 191, 49, - 28, 16, 243, 243, 247, 252, 229, 208, 49, 28, 16, 243, 243, 229, 203, - 240, 114, 49, 28, 16, 243, 243, 247, 252, 248, 11, 49, 28, 16, 243, 243, - 219, 104, 247, 251, 248, 11, 49, 28, 16, 243, 243, 247, 252, 234, 188, - 49, 28, 16, 243, 243, 247, 252, 210, 23, 49, 28, 16, 243, 243, 247, 252, - 228, 239, 234, 202, 49, 28, 16, 243, 243, 247, 252, 228, 239, 254, 104, - 49, 28, 16, 243, 243, 231, 196, 250, 81, 247, 238, 49, 28, 16, 243, 243, - 231, 196, 250, 81, 230, 148, 49, 28, 16, 244, 130, 219, 104, 250, 81, - 214, 9, 49, 28, 16, 243, 243, 219, 104, 250, 81, 217, 180, 49, 28, 16, - 243, 243, 229, 102, 49, 28, 16, 250, 82, 209, 249, 49, 28, 16, 250, 82, - 234, 42, 49, 28, 16, 250, 82, 219, 11, 49, 28, 16, 243, 243, 240, 161, - 211, 10, 216, 230, 49, 28, 16, 243, 243, 245, 157, 254, 94, 49, 28, 16, - 211, 10, 215, 207, 49, 28, 16, 247, 246, 215, 207, 49, 28, 16, 247, 246, - 216, 230, 49, 28, 16, 247, 246, 254, 73, 246, 50, 247, 147, 49, 28, 16, - 247, 246, 230, 146, 216, 234, 247, 147, 49, 28, 16, 247, 246, 247, 230, - 245, 44, 247, 147, 49, 28, 16, 247, 246, 215, 215, 226, 215, 247, 147, - 49, 28, 16, 211, 10, 254, 73, 246, 50, 247, 147, 49, 28, 16, 211, 10, - 230, 146, 216, 234, 247, 147, 49, 28, 16, 211, 10, 247, 230, 245, 44, - 247, 147, 49, 28, 16, 211, 10, 215, 215, 226, 215, 247, 147, 49, 28, 16, - 243, 56, 247, 245, 49, 28, 16, 243, 56, 211, 9, 49, 28, 16, 247, 253, - 254, 73, 230, 204, 49, 28, 16, 247, 253, 254, 73, 231, 78, 49, 28, 16, - 247, 253, 247, 209, 49, 28, 16, 247, 253, 216, 183, 49, 28, 16, 219, 165, - 216, 183, 49, 28, 16, 219, 165, 216, 184, 247, 194, 49, 28, 16, 219, 165, - 216, 184, 215, 208, 49, 28, 16, 219, 165, 216, 184, 216, 223, 49, 28, 16, - 219, 165, 253, 252, 49, 28, 16, 219, 165, 253, 253, 247, 194, 49, 28, 16, - 219, 165, 253, 253, 215, 208, 49, 28, 16, 219, 165, 253, 253, 216, 223, - 49, 28, 16, 247, 231, 243, 37, 49, 28, 16, 247, 237, 226, 138, 49, 28, - 16, 218, 139, 49, 28, 16, 254, 15, 191, 49, 28, 16, 254, 15, 213, 124, - 49, 28, 16, 254, 15, 243, 142, 49, 28, 16, 254, 15, 248, 11, 49, 28, 16, - 254, 15, 234, 188, 49, 28, 16, 254, 15, 210, 23, 49, 28, 16, 254, 15, - 228, 238, 49, 28, 16, 234, 168, 229, 101, 231, 49, 49, 28, 16, 234, 169, - 229, 101, 231, 49, 49, 28, 16, 234, 168, 229, 101, 234, 202, 49, 28, 16, - 234, 169, 229, 101, 234, 202, 49, 28, 16, 234, 44, 234, 202, 49, 28, 16, - 242, 166, 229, 101, 234, 202, 28, 16, 219, 157, 252, 143, 28, 16, 52, - 252, 143, 28, 16, 40, 252, 143, 28, 16, 223, 53, 40, 252, 143, 28, 16, - 248, 163, 252, 143, 28, 16, 219, 253, 252, 143, 28, 16, 43, 223, 80, 50, - 28, 16, 44, 223, 80, 50, 28, 16, 223, 80, 247, 126, 28, 16, 248, 204, - 221, 165, 28, 16, 248, 230, 251, 1, 28, 16, 221, 165, 28, 16, 249, 242, - 28, 16, 223, 78, 244, 119, 28, 16, 223, 78, 244, 118, 28, 16, 223, 78, - 244, 117, 28, 16, 244, 139, 28, 16, 244, 140, 51, 28, 16, 251, 156, 79, - 28, 16, 251, 32, 28, 16, 251, 167, 28, 16, 127, 28, 16, 226, 197, 218, - 165, 28, 16, 215, 57, 218, 165, 28, 16, 216, 143, 218, 165, 28, 16, 244, - 18, 218, 165, 28, 16, 244, 88, 218, 165, 28, 16, 219, 126, 218, 165, 28, - 16, 219, 124, 244, 2, 28, 16, 244, 16, 244, 2, 28, 16, 243, 210, 250, 22, - 28, 16, 243, 210, 250, 23, 226, 140, 254, 150, 28, 16, 243, 210, 250, 23, - 226, 140, 252, 130, 28, 16, 251, 75, 250, 22, 28, 16, 245, 15, 250, 22, - 28, 16, 245, 15, 250, 23, 226, 140, 254, 150, 28, 16, 245, 15, 250, 23, - 226, 140, 252, 130, 28, 16, 246, 91, 250, 21, 28, 16, 246, 91, 250, 20, - 28, 16, 230, 90, 231, 95, 223, 64, 28, 16, 52, 220, 77, 28, 16, 52, 244, - 73, 28, 16, 244, 74, 214, 163, 28, 16, 244, 74, 246, 114, 28, 16, 229, - 193, 214, 163, 28, 16, 229, 193, 246, 114, 28, 16, 220, 78, 214, 163, 28, - 16, 220, 78, 246, 114, 28, 16, 224, 25, 138, 220, 77, 28, 16, 224, 25, - 138, 244, 73, 28, 16, 249, 224, 216, 88, 28, 16, 249, 93, 216, 88, 28, - 16, 226, 140, 254, 150, 28, 16, 226, 140, 252, 130, 28, 16, 224, 7, 254, - 150, 28, 16, 224, 7, 252, 130, 28, 16, 230, 93, 223, 64, 28, 16, 211, - 251, 223, 64, 28, 16, 163, 223, 64, 28, 16, 224, 25, 223, 64, 28, 16, - 245, 197, 223, 64, 28, 16, 219, 120, 223, 64, 28, 16, 216, 161, 223, 64, - 28, 16, 219, 112, 223, 64, 28, 16, 123, 240, 218, 215, 71, 223, 64, 28, - 16, 211, 179, 228, 48, 28, 16, 96, 228, 48, 28, 16, 250, 44, 211, 179, - 228, 48, 28, 16, 42, 228, 49, 211, 253, 28, 16, 42, 228, 49, 251, 229, - 28, 16, 215, 227, 228, 49, 120, 211, 253, 28, 16, 215, 227, 228, 49, 120, - 251, 229, 28, 16, 215, 227, 228, 49, 43, 211, 253, 28, 16, 215, 227, 228, - 49, 43, 251, 229, 28, 16, 215, 227, 228, 49, 44, 211, 253, 28, 16, 215, - 227, 228, 49, 44, 251, 229, 28, 16, 215, 227, 228, 49, 124, 211, 253, 28, - 16, 215, 227, 228, 49, 124, 251, 229, 28, 16, 215, 227, 228, 49, 120, 44, - 211, 253, 28, 16, 215, 227, 228, 49, 120, 44, 251, 229, 28, 16, 230, 134, - 228, 49, 211, 253, 28, 16, 230, 134, 228, 49, 251, 229, 28, 16, 215, 224, - 228, 49, 124, 211, 253, 28, 16, 215, 224, 228, 49, 124, 251, 229, 28, 16, - 226, 8, 228, 48, 28, 16, 213, 132, 228, 48, 28, 16, 228, 49, 251, 229, - 28, 16, 227, 207, 228, 48, 28, 16, 249, 249, 228, 49, 211, 253, 28, 16, - 249, 249, 228, 49, 251, 229, 28, 16, 251, 154, 28, 16, 211, 251, 228, 52, - 28, 16, 163, 228, 52, 28, 16, 224, 25, 228, 52, 28, 16, 245, 197, 228, - 52, 28, 16, 219, 120, 228, 52, 28, 16, 216, 161, 228, 52, 28, 16, 219, - 112, 228, 52, 28, 16, 123, 240, 218, 215, 71, 228, 52, 28, 16, 38, 218, - 141, 28, 16, 38, 218, 242, 218, 141, 28, 16, 38, 215, 235, 28, 16, 38, - 215, 234, 28, 16, 38, 215, 233, 28, 16, 244, 109, 215, 235, 28, 16, 244, - 109, 215, 234, 28, 16, 244, 109, 215, 233, 28, 16, 38, 253, 197, 247, - 128, 28, 16, 38, 244, 80, 28, 16, 38, 244, 79, 28, 16, 38, 244, 78, 28, - 16, 38, 244, 77, 28, 16, 38, 244, 76, 28, 16, 252, 66, 252, 82, 28, 16, - 245, 151, 252, 82, 28, 16, 252, 66, 216, 112, 28, 16, 245, 151, 216, 112, - 28, 16, 252, 66, 219, 82, 28, 16, 245, 151, 219, 82, 28, 16, 252, 66, - 225, 118, 28, 16, 245, 151, 225, 118, 28, 16, 38, 255, 23, 28, 16, 38, - 218, 167, 28, 16, 38, 216, 239, 28, 16, 38, 218, 168, 28, 16, 38, 231, - 167, 28, 16, 38, 231, 166, 28, 16, 38, 255, 22, 28, 16, 38, 232, 118, 28, - 16, 254, 6, 214, 163, 28, 16, 254, 6, 246, 114, 28, 16, 38, 247, 143, 28, - 16, 38, 222, 234, 28, 16, 38, 244, 66, 28, 16, 38, 219, 78, 28, 16, 38, - 252, 46, 28, 16, 38, 52, 216, 20, 28, 16, 38, 215, 212, 216, 20, 28, 16, - 222, 238, 28, 16, 218, 76, 28, 16, 210, 159, 28, 16, 225, 110, 28, 16, - 231, 30, 28, 16, 244, 25, 28, 16, 249, 146, 28, 16, 248, 86, 28, 16, 242, - 157, 228, 53, 219, 97, 28, 16, 242, 157, 228, 53, 228, 80, 219, 97, 28, - 16, 216, 1, 28, 16, 215, 95, 28, 16, 235, 200, 215, 95, 28, 16, 215, 96, - 219, 97, 28, 16, 215, 96, 214, 163, 28, 16, 226, 152, 218, 104, 28, 16, - 226, 152, 218, 101, 28, 16, 226, 152, 218, 100, 28, 16, 226, 152, 218, - 99, 28, 16, 226, 152, 218, 98, 28, 16, 226, 152, 218, 97, 28, 16, 226, - 152, 218, 96, 28, 16, 226, 152, 218, 95, 28, 16, 226, 152, 218, 94, 28, - 16, 226, 152, 218, 103, 28, 16, 226, 152, 218, 102, 28, 16, 241, 252, 28, - 16, 229, 110, 28, 16, 245, 151, 64, 218, 135, 28, 16, 248, 79, 219, 97, - 28, 16, 38, 124, 251, 177, 28, 16, 38, 120, 251, 177, 28, 16, 38, 242, 7, - 28, 16, 38, 219, 69, 225, 46, 28, 16, 225, 219, 79, 28, 16, 225, 219, - 120, 79, 28, 16, 163, 225, 219, 79, 28, 16, 242, 189, 214, 163, 28, 16, - 242, 189, 246, 114, 28, 16, 2, 244, 108, 28, 16, 248, 188, 28, 16, 248, - 189, 254, 163, 28, 16, 231, 138, 28, 16, 232, 135, 28, 16, 251, 151, 28, - 16, 220, 156, 211, 253, 28, 16, 220, 156, 251, 229, 28, 16, 230, 189, 28, - 16, 230, 190, 251, 229, 28, 16, 220, 150, 211, 253, 28, 16, 220, 150, - 251, 229, 28, 16, 243, 227, 211, 253, 28, 16, 243, 227, 251, 229, 28, 16, - 232, 136, 225, 183, 223, 64, 28, 16, 232, 136, 236, 11, 223, 64, 28, 16, - 251, 152, 223, 64, 28, 16, 220, 156, 223, 64, 28, 16, 230, 190, 223, 64, - 28, 16, 220, 150, 223, 64, 28, 16, 216, 250, 225, 181, 249, 115, 224, - 177, 225, 182, 28, 16, 216, 250, 225, 181, 249, 115, 224, 177, 236, 10, - 28, 16, 216, 250, 225, 181, 249, 115, 224, 177, 225, 183, 247, 219, 28, - 16, 216, 250, 236, 9, 249, 115, 224, 177, 225, 182, 28, 16, 216, 250, - 236, 9, 249, 115, 224, 177, 236, 10, 28, 16, 216, 250, 236, 9, 249, 115, - 224, 177, 236, 11, 247, 219, 28, 16, 216, 250, 236, 9, 249, 115, 224, - 177, 236, 11, 247, 218, 28, 16, 216, 250, 236, 9, 249, 115, 224, 177, - 236, 11, 247, 217, 28, 16, 249, 141, 28, 16, 242, 133, 251, 75, 250, 22, - 28, 16, 242, 133, 245, 15, 250, 22, 28, 16, 42, 253, 166, 28, 16, 213, - 151, 28, 16, 225, 17, 28, 16, 250, 13, 28, 16, 221, 205, 28, 16, 250, 17, - 28, 16, 216, 8, 28, 16, 224, 245, 28, 16, 224, 246, 244, 68, 28, 16, 221, - 206, 244, 68, 28, 16, 216, 9, 223, 61, 28, 16, 225, 166, 218, 67, 26, - 213, 137, 189, 217, 230, 26, 213, 137, 189, 217, 219, 26, 213, 137, 189, - 217, 209, 26, 213, 137, 189, 217, 202, 26, 213, 137, 189, 217, 194, 26, - 213, 137, 189, 217, 188, 26, 213, 137, 189, 217, 187, 26, 213, 137, 189, - 217, 186, 26, 213, 137, 189, 217, 185, 26, 213, 137, 189, 217, 229, 26, - 213, 137, 189, 217, 228, 26, 213, 137, 189, 217, 227, 26, 213, 137, 189, - 217, 226, 26, 213, 137, 189, 217, 225, 26, 213, 137, 189, 217, 224, 26, - 213, 137, 189, 217, 223, 26, 213, 137, 189, 217, 222, 26, 213, 137, 189, - 217, 221, 26, 213, 137, 189, 217, 220, 26, 213, 137, 189, 217, 218, 26, - 213, 137, 189, 217, 217, 26, 213, 137, 189, 217, 216, 26, 213, 137, 189, - 217, 215, 26, 213, 137, 189, 217, 214, 26, 213, 137, 189, 217, 193, 26, - 213, 137, 189, 217, 192, 26, 213, 137, 189, 217, 191, 26, 213, 137, 189, - 217, 190, 26, 213, 137, 189, 217, 189, 26, 235, 221, 189, 217, 230, 26, - 235, 221, 189, 217, 219, 26, 235, 221, 189, 217, 202, 26, 235, 221, 189, - 217, 194, 26, 235, 221, 189, 217, 187, 26, 235, 221, 189, 217, 186, 26, - 235, 221, 189, 217, 228, 26, 235, 221, 189, 217, 227, 26, 235, 221, 189, - 217, 226, 26, 235, 221, 189, 217, 225, 26, 235, 221, 189, 217, 222, 26, - 235, 221, 189, 217, 221, 26, 235, 221, 189, 217, 220, 26, 235, 221, 189, - 217, 215, 26, 235, 221, 189, 217, 214, 26, 235, 221, 189, 217, 213, 26, - 235, 221, 189, 217, 212, 26, 235, 221, 189, 217, 211, 26, 235, 221, 189, - 217, 210, 26, 235, 221, 189, 217, 208, 26, 235, 221, 189, 217, 207, 26, - 235, 221, 189, 217, 206, 26, 235, 221, 189, 217, 205, 26, 235, 221, 189, - 217, 204, 26, 235, 221, 189, 217, 203, 26, 235, 221, 189, 217, 201, 26, - 235, 221, 189, 217, 200, 26, 235, 221, 189, 217, 199, 26, 235, 221, 189, - 217, 198, 26, 235, 221, 189, 217, 197, 26, 235, 221, 189, 217, 196, 26, - 235, 221, 189, 217, 195, 26, 235, 221, 189, 217, 193, 26, 235, 221, 189, - 217, 192, 26, 235, 221, 189, 217, 191, 26, 235, 221, 189, 217, 190, 26, - 235, 221, 189, 217, 189, 38, 26, 28, 215, 209, 38, 26, 28, 216, 224, 38, - 26, 28, 225, 191, 26, 28, 233, 37, 230, 147, 31, 245, 231, 247, 232, 31, - 241, 229, 245, 231, 247, 232, 31, 240, 221, 245, 231, 247, 232, 31, 245, - 230, 241, 230, 247, 232, 31, 245, 230, 240, 220, 247, 232, 31, 245, 231, - 180, 31, 250, 182, 180, 31, 243, 236, 250, 43, 180, 31, 230, 182, 180, - 31, 252, 138, 180, 31, 234, 185, 219, 81, 180, 31, 249, 187, 180, 31, - 253, 241, 180, 31, 226, 167, 180, 31, 251, 161, 226, 134, 180, 31, 248, - 81, 177, 247, 187, 180, 31, 247, 184, 180, 31, 210, 222, 180, 31, 235, - 254, 180, 31, 225, 200, 180, 31, 223, 130, 180, 31, 249, 197, 180, 31, - 241, 67, 252, 192, 180, 31, 212, 59, 180, 31, 244, 47, 180, 31, 254, 255, - 180, 31, 223, 92, 180, 31, 223, 68, 180, 31, 245, 229, 180, 31, 235, 59, - 180, 31, 249, 192, 180, 31, 245, 150, 180, 31, 246, 60, 180, 31, 250, - 153, 180, 31, 248, 90, 180, 31, 23, 223, 67, 180, 31, 226, 85, 180, 31, - 233, 40, 180, 31, 250, 6, 180, 31, 234, 83, 180, 31, 243, 93, 180, 31, - 218, 114, 180, 31, 224, 133, 180, 31, 243, 235, 180, 31, 223, 69, 180, - 31, 233, 77, 177, 230, 162, 180, 31, 223, 65, 180, 31, 242, 175, 216, 43, - 231, 81, 180, 31, 245, 152, 180, 31, 218, 126, 180, 31, 242, 135, 180, - 31, 245, 144, 180, 31, 225, 239, 180, 31, 222, 228, 180, 31, 244, 67, - 180, 31, 214, 8, 177, 212, 44, 180, 31, 249, 201, 180, 31, 231, 94, 180, - 31, 245, 69, 180, 31, 214, 172, 180, 31, 247, 220, 180, 31, 250, 8, 230, - 115, 180, 31, 242, 113, 180, 31, 243, 94, 236, 6, 180, 31, 231, 146, 180, - 31, 255, 19, 180, 31, 245, 165, 180, 31, 246, 117, 180, 31, 212, 42, 180, - 31, 219, 152, 180, 31, 235, 229, 180, 31, 248, 50, 180, 31, 248, 168, - 180, 31, 247, 216, 180, 31, 245, 37, 180, 31, 220, 117, 180, 31, 218, - 130, 180, 31, 242, 9, 180, 31, 249, 220, 180, 31, 250, 3, 180, 31, 244, - 185, 180, 31, 254, 221, 180, 31, 249, 219, 180, 31, 226, 201, 216, 197, - 213, 242, 180, 31, 247, 240, 180, 31, 233, 130, 180, 31, 244, 21, 249, - 157, 222, 204, 214, 174, 21, 111, 249, 157, 222, 204, 214, 174, 21, 105, - 249, 157, 222, 204, 214, 174, 21, 158, 249, 157, 222, 204, 214, 174, 21, - 161, 249, 157, 222, 204, 214, 174, 21, 190, 249, 157, 222, 204, 214, 174, - 21, 195, 249, 157, 222, 204, 214, 174, 21, 199, 249, 157, 222, 204, 214, - 174, 21, 196, 249, 157, 222, 204, 214, 174, 21, 201, 249, 157, 222, 204, - 216, 244, 21, 111, 249, 157, 222, 204, 216, 244, 21, 105, 249, 157, 222, - 204, 216, 244, 21, 158, 249, 157, 222, 204, 216, 244, 21, 161, 249, 157, - 222, 204, 216, 244, 21, 190, 249, 157, 222, 204, 216, 244, 21, 195, 249, - 157, 222, 204, 216, 244, 21, 199, 249, 157, 222, 204, 216, 244, 21, 196, - 249, 157, 222, 204, 216, 244, 21, 201, 11, 23, 6, 61, 11, 23, 6, 253, - 166, 11, 23, 6, 251, 74, 11, 23, 6, 249, 68, 11, 23, 6, 76, 11, 23, 6, - 245, 14, 11, 23, 6, 243, 209, 11, 23, 6, 242, 67, 11, 23, 6, 74, 11, 23, - 6, 235, 150, 11, 23, 6, 235, 29, 11, 23, 6, 156, 11, 23, 6, 194, 11, 23, - 6, 230, 30, 11, 23, 6, 78, 11, 23, 6, 226, 109, 11, 23, 6, 224, 99, 11, - 23, 6, 153, 11, 23, 6, 222, 93, 11, 23, 6, 217, 153, 11, 23, 6, 69, 11, - 23, 6, 214, 105, 11, 23, 6, 212, 98, 11, 23, 6, 211, 178, 11, 23, 6, 211, - 117, 11, 23, 6, 210, 159, 11, 23, 4, 61, 11, 23, 4, 253, 166, 11, 23, 4, - 251, 74, 11, 23, 4, 249, 68, 11, 23, 4, 76, 11, 23, 4, 245, 14, 11, 23, - 4, 243, 209, 11, 23, 4, 242, 67, 11, 23, 4, 74, 11, 23, 4, 235, 150, 11, - 23, 4, 235, 29, 11, 23, 4, 156, 11, 23, 4, 194, 11, 23, 4, 230, 30, 11, - 23, 4, 78, 11, 23, 4, 226, 109, 11, 23, 4, 224, 99, 11, 23, 4, 153, 11, - 23, 4, 222, 93, 11, 23, 4, 217, 153, 11, 23, 4, 69, 11, 23, 4, 214, 105, - 11, 23, 4, 212, 98, 11, 23, 4, 211, 178, 11, 23, 4, 211, 117, 11, 23, 4, - 210, 159, 11, 32, 6, 61, 11, 32, 6, 253, 166, 11, 32, 6, 251, 74, 11, 32, - 6, 249, 68, 11, 32, 6, 76, 11, 32, 6, 245, 14, 11, 32, 6, 243, 209, 11, - 32, 6, 242, 67, 11, 32, 6, 74, 11, 32, 6, 235, 150, 11, 32, 6, 235, 29, - 11, 32, 6, 156, 11, 32, 6, 194, 11, 32, 6, 230, 30, 11, 32, 6, 78, 11, - 32, 6, 226, 109, 11, 32, 6, 224, 99, 11, 32, 6, 153, 11, 32, 6, 222, 93, - 11, 32, 6, 217, 153, 11, 32, 6, 69, 11, 32, 6, 214, 105, 11, 32, 6, 212, - 98, 11, 32, 6, 211, 178, 11, 32, 6, 211, 117, 11, 32, 6, 210, 159, 11, - 32, 4, 61, 11, 32, 4, 253, 166, 11, 32, 4, 251, 74, 11, 32, 4, 249, 68, - 11, 32, 4, 76, 11, 32, 4, 245, 14, 11, 32, 4, 243, 209, 11, 32, 4, 74, - 11, 32, 4, 235, 150, 11, 32, 4, 235, 29, 11, 32, 4, 156, 11, 32, 4, 194, - 11, 32, 4, 230, 30, 11, 32, 4, 78, 11, 32, 4, 226, 109, 11, 32, 4, 224, - 99, 11, 32, 4, 153, 11, 32, 4, 222, 93, 11, 32, 4, 217, 153, 11, 32, 4, - 69, 11, 32, 4, 214, 105, 11, 32, 4, 212, 98, 11, 32, 4, 211, 178, 11, 32, - 4, 211, 117, 11, 32, 4, 210, 159, 11, 23, 32, 6, 61, 11, 23, 32, 6, 253, - 166, 11, 23, 32, 6, 251, 74, 11, 23, 32, 6, 249, 68, 11, 23, 32, 6, 76, - 11, 23, 32, 6, 245, 14, 11, 23, 32, 6, 243, 209, 11, 23, 32, 6, 242, 67, - 11, 23, 32, 6, 74, 11, 23, 32, 6, 235, 150, 11, 23, 32, 6, 235, 29, 11, - 23, 32, 6, 156, 11, 23, 32, 6, 194, 11, 23, 32, 6, 230, 30, 11, 23, 32, - 6, 78, 11, 23, 32, 6, 226, 109, 11, 23, 32, 6, 224, 99, 11, 23, 32, 6, - 153, 11, 23, 32, 6, 222, 93, 11, 23, 32, 6, 217, 153, 11, 23, 32, 6, 69, - 11, 23, 32, 6, 214, 105, 11, 23, 32, 6, 212, 98, 11, 23, 32, 6, 211, 178, - 11, 23, 32, 6, 211, 117, 11, 23, 32, 6, 210, 159, 11, 23, 32, 4, 61, 11, - 23, 32, 4, 253, 166, 11, 23, 32, 4, 251, 74, 11, 23, 32, 4, 249, 68, 11, - 23, 32, 4, 76, 11, 23, 32, 4, 245, 14, 11, 23, 32, 4, 243, 209, 11, 23, - 32, 4, 242, 67, 11, 23, 32, 4, 74, 11, 23, 32, 4, 235, 150, 11, 23, 32, - 4, 235, 29, 11, 23, 32, 4, 156, 11, 23, 32, 4, 194, 11, 23, 32, 4, 230, - 30, 11, 23, 32, 4, 78, 11, 23, 32, 4, 226, 109, 11, 23, 32, 4, 224, 99, - 11, 23, 32, 4, 153, 11, 23, 32, 4, 222, 93, 11, 23, 32, 4, 217, 153, 11, - 23, 32, 4, 69, 11, 23, 32, 4, 214, 105, 11, 23, 32, 4, 212, 98, 11, 23, - 32, 4, 211, 178, 11, 23, 32, 4, 211, 117, 11, 23, 32, 4, 210, 159, 11, - 119, 6, 61, 11, 119, 6, 251, 74, 11, 119, 6, 249, 68, 11, 119, 6, 243, - 209, 11, 119, 6, 235, 150, 11, 119, 6, 235, 29, 11, 119, 6, 230, 30, 11, - 119, 6, 78, 11, 119, 6, 226, 109, 11, 119, 6, 224, 99, 11, 119, 6, 222, - 93, 11, 119, 6, 217, 153, 11, 119, 6, 69, 11, 119, 6, 214, 105, 11, 119, - 6, 212, 98, 11, 119, 6, 211, 178, 11, 119, 6, 211, 117, 11, 119, 6, 210, - 159, 11, 119, 4, 61, 11, 119, 4, 253, 166, 11, 119, 4, 251, 74, 11, 119, - 4, 249, 68, 11, 119, 4, 245, 14, 11, 119, 4, 242, 67, 11, 119, 4, 74, 11, - 119, 4, 235, 150, 11, 119, 4, 235, 29, 11, 119, 4, 156, 11, 119, 4, 194, - 11, 119, 4, 230, 30, 11, 119, 4, 226, 109, 11, 119, 4, 224, 99, 11, 119, - 4, 153, 11, 119, 4, 222, 93, 11, 119, 4, 217, 153, 11, 119, 4, 69, 11, - 119, 4, 214, 105, 11, 119, 4, 212, 98, 11, 119, 4, 211, 178, 11, 119, 4, - 211, 117, 11, 119, 4, 210, 159, 11, 23, 119, 6, 61, 11, 23, 119, 6, 253, - 166, 11, 23, 119, 6, 251, 74, 11, 23, 119, 6, 249, 68, 11, 23, 119, 6, - 76, 11, 23, 119, 6, 245, 14, 11, 23, 119, 6, 243, 209, 11, 23, 119, 6, - 242, 67, 11, 23, 119, 6, 74, 11, 23, 119, 6, 235, 150, 11, 23, 119, 6, - 235, 29, 11, 23, 119, 6, 156, 11, 23, 119, 6, 194, 11, 23, 119, 6, 230, - 30, 11, 23, 119, 6, 78, 11, 23, 119, 6, 226, 109, 11, 23, 119, 6, 224, - 99, 11, 23, 119, 6, 153, 11, 23, 119, 6, 222, 93, 11, 23, 119, 6, 217, - 153, 11, 23, 119, 6, 69, 11, 23, 119, 6, 214, 105, 11, 23, 119, 6, 212, - 98, 11, 23, 119, 6, 211, 178, 11, 23, 119, 6, 211, 117, 11, 23, 119, 6, - 210, 159, 11, 23, 119, 4, 61, 11, 23, 119, 4, 253, 166, 11, 23, 119, 4, - 251, 74, 11, 23, 119, 4, 249, 68, 11, 23, 119, 4, 76, 11, 23, 119, 4, - 245, 14, 11, 23, 119, 4, 243, 209, 11, 23, 119, 4, 242, 67, 11, 23, 119, - 4, 74, 11, 23, 119, 4, 235, 150, 11, 23, 119, 4, 235, 29, 11, 23, 119, 4, - 156, 11, 23, 119, 4, 194, 11, 23, 119, 4, 230, 30, 11, 23, 119, 4, 78, - 11, 23, 119, 4, 226, 109, 11, 23, 119, 4, 224, 99, 11, 23, 119, 4, 153, - 11, 23, 119, 4, 222, 93, 11, 23, 119, 4, 217, 153, 11, 23, 119, 4, 69, - 11, 23, 119, 4, 214, 105, 11, 23, 119, 4, 212, 98, 11, 23, 119, 4, 211, - 178, 11, 23, 119, 4, 211, 117, 11, 23, 119, 4, 210, 159, 11, 133, 6, 61, - 11, 133, 6, 253, 166, 11, 133, 6, 249, 68, 11, 133, 6, 76, 11, 133, 6, - 245, 14, 11, 133, 6, 243, 209, 11, 133, 6, 235, 150, 11, 133, 6, 235, 29, - 11, 133, 6, 156, 11, 133, 6, 194, 11, 133, 6, 230, 30, 11, 133, 6, 78, - 11, 133, 6, 226, 109, 11, 133, 6, 224, 99, 11, 133, 6, 222, 93, 11, 133, - 6, 217, 153, 11, 133, 6, 69, 11, 133, 6, 214, 105, 11, 133, 6, 212, 98, - 11, 133, 6, 211, 178, 11, 133, 6, 211, 117, 11, 133, 4, 61, 11, 133, 4, - 253, 166, 11, 133, 4, 251, 74, 11, 133, 4, 249, 68, 11, 133, 4, 76, 11, - 133, 4, 245, 14, 11, 133, 4, 243, 209, 11, 133, 4, 242, 67, 11, 133, 4, - 74, 11, 133, 4, 235, 150, 11, 133, 4, 235, 29, 11, 133, 4, 156, 11, 133, - 4, 194, 11, 133, 4, 230, 30, 11, 133, 4, 78, 11, 133, 4, 226, 109, 11, - 133, 4, 224, 99, 11, 133, 4, 153, 11, 133, 4, 222, 93, 11, 133, 4, 217, - 153, 11, 133, 4, 69, 11, 133, 4, 214, 105, 11, 133, 4, 212, 98, 11, 133, - 4, 211, 178, 11, 133, 4, 211, 117, 11, 133, 4, 210, 159, 11, 139, 6, 61, - 11, 139, 6, 253, 166, 11, 139, 6, 249, 68, 11, 139, 6, 76, 11, 139, 6, - 245, 14, 11, 139, 6, 243, 209, 11, 139, 6, 74, 11, 139, 6, 235, 150, 11, - 139, 6, 235, 29, 11, 139, 6, 156, 11, 139, 6, 194, 11, 139, 6, 78, 11, - 139, 6, 222, 93, 11, 139, 6, 217, 153, 11, 139, 6, 69, 11, 139, 6, 214, - 105, 11, 139, 6, 212, 98, 11, 139, 6, 211, 178, 11, 139, 6, 211, 117, 11, - 139, 4, 61, 11, 139, 4, 253, 166, 11, 139, 4, 251, 74, 11, 139, 4, 249, - 68, 11, 139, 4, 76, 11, 139, 4, 245, 14, 11, 139, 4, 243, 209, 11, 139, - 4, 242, 67, 11, 139, 4, 74, 11, 139, 4, 235, 150, 11, 139, 4, 235, 29, - 11, 139, 4, 156, 11, 139, 4, 194, 11, 139, 4, 230, 30, 11, 139, 4, 78, - 11, 139, 4, 226, 109, 11, 139, 4, 224, 99, 11, 139, 4, 153, 11, 139, 4, - 222, 93, 11, 139, 4, 217, 153, 11, 139, 4, 69, 11, 139, 4, 214, 105, 11, - 139, 4, 212, 98, 11, 139, 4, 211, 178, 11, 139, 4, 211, 117, 11, 139, 4, - 210, 159, 11, 23, 133, 6, 61, 11, 23, 133, 6, 253, 166, 11, 23, 133, 6, - 251, 74, 11, 23, 133, 6, 249, 68, 11, 23, 133, 6, 76, 11, 23, 133, 6, - 245, 14, 11, 23, 133, 6, 243, 209, 11, 23, 133, 6, 242, 67, 11, 23, 133, - 6, 74, 11, 23, 133, 6, 235, 150, 11, 23, 133, 6, 235, 29, 11, 23, 133, 6, - 156, 11, 23, 133, 6, 194, 11, 23, 133, 6, 230, 30, 11, 23, 133, 6, 78, - 11, 23, 133, 6, 226, 109, 11, 23, 133, 6, 224, 99, 11, 23, 133, 6, 153, - 11, 23, 133, 6, 222, 93, 11, 23, 133, 6, 217, 153, 11, 23, 133, 6, 69, - 11, 23, 133, 6, 214, 105, 11, 23, 133, 6, 212, 98, 11, 23, 133, 6, 211, - 178, 11, 23, 133, 6, 211, 117, 11, 23, 133, 6, 210, 159, 11, 23, 133, 4, - 61, 11, 23, 133, 4, 253, 166, 11, 23, 133, 4, 251, 74, 11, 23, 133, 4, - 249, 68, 11, 23, 133, 4, 76, 11, 23, 133, 4, 245, 14, 11, 23, 133, 4, - 243, 209, 11, 23, 133, 4, 242, 67, 11, 23, 133, 4, 74, 11, 23, 133, 4, - 235, 150, 11, 23, 133, 4, 235, 29, 11, 23, 133, 4, 156, 11, 23, 133, 4, - 194, 11, 23, 133, 4, 230, 30, 11, 23, 133, 4, 78, 11, 23, 133, 4, 226, - 109, 11, 23, 133, 4, 224, 99, 11, 23, 133, 4, 153, 11, 23, 133, 4, 222, - 93, 11, 23, 133, 4, 217, 153, 11, 23, 133, 4, 69, 11, 23, 133, 4, 214, - 105, 11, 23, 133, 4, 212, 98, 11, 23, 133, 4, 211, 178, 11, 23, 133, 4, - 211, 117, 11, 23, 133, 4, 210, 159, 11, 35, 6, 61, 11, 35, 6, 253, 166, - 11, 35, 6, 251, 74, 11, 35, 6, 249, 68, 11, 35, 6, 76, 11, 35, 6, 245, - 14, 11, 35, 6, 243, 209, 11, 35, 6, 242, 67, 11, 35, 6, 74, 11, 35, 6, - 235, 150, 11, 35, 6, 235, 29, 11, 35, 6, 156, 11, 35, 6, 194, 11, 35, 6, - 230, 30, 11, 35, 6, 78, 11, 35, 6, 226, 109, 11, 35, 6, 224, 99, 11, 35, - 6, 153, 11, 35, 6, 222, 93, 11, 35, 6, 217, 153, 11, 35, 6, 69, 11, 35, - 6, 214, 105, 11, 35, 6, 212, 98, 11, 35, 6, 211, 178, 11, 35, 6, 211, - 117, 11, 35, 6, 210, 159, 11, 35, 4, 61, 11, 35, 4, 253, 166, 11, 35, 4, - 251, 74, 11, 35, 4, 249, 68, 11, 35, 4, 76, 11, 35, 4, 245, 14, 11, 35, - 4, 243, 209, 11, 35, 4, 242, 67, 11, 35, 4, 74, 11, 35, 4, 235, 150, 11, - 35, 4, 235, 29, 11, 35, 4, 156, 11, 35, 4, 194, 11, 35, 4, 230, 30, 11, - 35, 4, 78, 11, 35, 4, 226, 109, 11, 35, 4, 224, 99, 11, 35, 4, 153, 11, - 35, 4, 222, 93, 11, 35, 4, 217, 153, 11, 35, 4, 69, 11, 35, 4, 214, 105, - 11, 35, 4, 212, 98, 11, 35, 4, 211, 178, 11, 35, 4, 211, 117, 11, 35, 4, - 210, 159, 11, 35, 23, 6, 61, 11, 35, 23, 6, 253, 166, 11, 35, 23, 6, 251, - 74, 11, 35, 23, 6, 249, 68, 11, 35, 23, 6, 76, 11, 35, 23, 6, 245, 14, - 11, 35, 23, 6, 243, 209, 11, 35, 23, 6, 242, 67, 11, 35, 23, 6, 74, 11, - 35, 23, 6, 235, 150, 11, 35, 23, 6, 235, 29, 11, 35, 23, 6, 156, 11, 35, - 23, 6, 194, 11, 35, 23, 6, 230, 30, 11, 35, 23, 6, 78, 11, 35, 23, 6, - 226, 109, 11, 35, 23, 6, 224, 99, 11, 35, 23, 6, 153, 11, 35, 23, 6, 222, - 93, 11, 35, 23, 6, 217, 153, 11, 35, 23, 6, 69, 11, 35, 23, 6, 214, 105, - 11, 35, 23, 6, 212, 98, 11, 35, 23, 6, 211, 178, 11, 35, 23, 6, 211, 117, - 11, 35, 23, 6, 210, 159, 11, 35, 23, 4, 61, 11, 35, 23, 4, 253, 166, 11, - 35, 23, 4, 251, 74, 11, 35, 23, 4, 249, 68, 11, 35, 23, 4, 76, 11, 35, - 23, 4, 245, 14, 11, 35, 23, 4, 243, 209, 11, 35, 23, 4, 242, 67, 11, 35, - 23, 4, 74, 11, 35, 23, 4, 235, 150, 11, 35, 23, 4, 235, 29, 11, 35, 23, - 4, 156, 11, 35, 23, 4, 194, 11, 35, 23, 4, 230, 30, 11, 35, 23, 4, 78, - 11, 35, 23, 4, 226, 109, 11, 35, 23, 4, 224, 99, 11, 35, 23, 4, 153, 11, - 35, 23, 4, 222, 93, 11, 35, 23, 4, 217, 153, 11, 35, 23, 4, 69, 11, 35, - 23, 4, 214, 105, 11, 35, 23, 4, 212, 98, 11, 35, 23, 4, 211, 178, 11, 35, - 23, 4, 211, 117, 11, 35, 23, 4, 210, 159, 11, 35, 32, 6, 61, 11, 35, 32, - 6, 253, 166, 11, 35, 32, 6, 251, 74, 11, 35, 32, 6, 249, 68, 11, 35, 32, - 6, 76, 11, 35, 32, 6, 245, 14, 11, 35, 32, 6, 243, 209, 11, 35, 32, 6, - 242, 67, 11, 35, 32, 6, 74, 11, 35, 32, 6, 235, 150, 11, 35, 32, 6, 235, - 29, 11, 35, 32, 6, 156, 11, 35, 32, 6, 194, 11, 35, 32, 6, 230, 30, 11, - 35, 32, 6, 78, 11, 35, 32, 6, 226, 109, 11, 35, 32, 6, 224, 99, 11, 35, - 32, 6, 153, 11, 35, 32, 6, 222, 93, 11, 35, 32, 6, 217, 153, 11, 35, 32, - 6, 69, 11, 35, 32, 6, 214, 105, 11, 35, 32, 6, 212, 98, 11, 35, 32, 6, - 211, 178, 11, 35, 32, 6, 211, 117, 11, 35, 32, 6, 210, 159, 11, 35, 32, - 4, 61, 11, 35, 32, 4, 253, 166, 11, 35, 32, 4, 251, 74, 11, 35, 32, 4, - 249, 68, 11, 35, 32, 4, 76, 11, 35, 32, 4, 245, 14, 11, 35, 32, 4, 243, - 209, 11, 35, 32, 4, 242, 67, 11, 35, 32, 4, 74, 11, 35, 32, 4, 235, 150, - 11, 35, 32, 4, 235, 29, 11, 35, 32, 4, 156, 11, 35, 32, 4, 194, 11, 35, - 32, 4, 230, 30, 11, 35, 32, 4, 78, 11, 35, 32, 4, 226, 109, 11, 35, 32, - 4, 224, 99, 11, 35, 32, 4, 153, 11, 35, 32, 4, 222, 93, 11, 35, 32, 4, - 217, 153, 11, 35, 32, 4, 69, 11, 35, 32, 4, 214, 105, 11, 35, 32, 4, 212, - 98, 11, 35, 32, 4, 211, 178, 11, 35, 32, 4, 211, 117, 11, 35, 32, 4, 210, - 159, 11, 35, 23, 32, 6, 61, 11, 35, 23, 32, 6, 253, 166, 11, 35, 23, 32, - 6, 251, 74, 11, 35, 23, 32, 6, 249, 68, 11, 35, 23, 32, 6, 76, 11, 35, - 23, 32, 6, 245, 14, 11, 35, 23, 32, 6, 243, 209, 11, 35, 23, 32, 6, 242, - 67, 11, 35, 23, 32, 6, 74, 11, 35, 23, 32, 6, 235, 150, 11, 35, 23, 32, - 6, 235, 29, 11, 35, 23, 32, 6, 156, 11, 35, 23, 32, 6, 194, 11, 35, 23, - 32, 6, 230, 30, 11, 35, 23, 32, 6, 78, 11, 35, 23, 32, 6, 226, 109, 11, - 35, 23, 32, 6, 224, 99, 11, 35, 23, 32, 6, 153, 11, 35, 23, 32, 6, 222, - 93, 11, 35, 23, 32, 6, 217, 153, 11, 35, 23, 32, 6, 69, 11, 35, 23, 32, - 6, 214, 105, 11, 35, 23, 32, 6, 212, 98, 11, 35, 23, 32, 6, 211, 178, 11, - 35, 23, 32, 6, 211, 117, 11, 35, 23, 32, 6, 210, 159, 11, 35, 23, 32, 4, - 61, 11, 35, 23, 32, 4, 253, 166, 11, 35, 23, 32, 4, 251, 74, 11, 35, 23, - 32, 4, 249, 68, 11, 35, 23, 32, 4, 76, 11, 35, 23, 32, 4, 245, 14, 11, - 35, 23, 32, 4, 243, 209, 11, 35, 23, 32, 4, 242, 67, 11, 35, 23, 32, 4, - 74, 11, 35, 23, 32, 4, 235, 150, 11, 35, 23, 32, 4, 235, 29, 11, 35, 23, - 32, 4, 156, 11, 35, 23, 32, 4, 194, 11, 35, 23, 32, 4, 230, 30, 11, 35, - 23, 32, 4, 78, 11, 35, 23, 32, 4, 226, 109, 11, 35, 23, 32, 4, 224, 99, - 11, 35, 23, 32, 4, 153, 11, 35, 23, 32, 4, 222, 93, 11, 35, 23, 32, 4, - 217, 153, 11, 35, 23, 32, 4, 69, 11, 35, 23, 32, 4, 214, 105, 11, 35, 23, - 32, 4, 212, 98, 11, 35, 23, 32, 4, 211, 178, 11, 35, 23, 32, 4, 211, 117, - 11, 35, 23, 32, 4, 210, 159, 11, 230, 143, 6, 61, 11, 230, 143, 6, 253, - 166, 11, 230, 143, 6, 251, 74, 11, 230, 143, 6, 249, 68, 11, 230, 143, 6, - 76, 11, 230, 143, 6, 245, 14, 11, 230, 143, 6, 243, 209, 11, 230, 143, 6, - 242, 67, 11, 230, 143, 6, 74, 11, 230, 143, 6, 235, 150, 11, 230, 143, 6, - 235, 29, 11, 230, 143, 6, 156, 11, 230, 143, 6, 194, 11, 230, 143, 6, - 230, 30, 11, 230, 143, 6, 78, 11, 230, 143, 6, 226, 109, 11, 230, 143, 6, - 224, 99, 11, 230, 143, 6, 153, 11, 230, 143, 6, 222, 93, 11, 230, 143, 6, - 217, 153, 11, 230, 143, 6, 69, 11, 230, 143, 6, 214, 105, 11, 230, 143, - 6, 212, 98, 11, 230, 143, 6, 211, 178, 11, 230, 143, 6, 211, 117, 11, - 230, 143, 6, 210, 159, 11, 230, 143, 4, 61, 11, 230, 143, 4, 253, 166, - 11, 230, 143, 4, 251, 74, 11, 230, 143, 4, 249, 68, 11, 230, 143, 4, 76, - 11, 230, 143, 4, 245, 14, 11, 230, 143, 4, 243, 209, 11, 230, 143, 4, - 242, 67, 11, 230, 143, 4, 74, 11, 230, 143, 4, 235, 150, 11, 230, 143, 4, - 235, 29, 11, 230, 143, 4, 156, 11, 230, 143, 4, 194, 11, 230, 143, 4, - 230, 30, 11, 230, 143, 4, 78, 11, 230, 143, 4, 226, 109, 11, 230, 143, 4, - 224, 99, 11, 230, 143, 4, 153, 11, 230, 143, 4, 222, 93, 11, 230, 143, 4, - 217, 153, 11, 230, 143, 4, 69, 11, 230, 143, 4, 214, 105, 11, 230, 143, - 4, 212, 98, 11, 230, 143, 4, 211, 178, 11, 230, 143, 4, 211, 117, 11, - 230, 143, 4, 210, 159, 11, 32, 4, 247, 127, 74, 11, 32, 4, 247, 127, 235, - 150, 11, 23, 6, 254, 151, 11, 23, 6, 252, 34, 11, 23, 6, 243, 114, 11, - 23, 6, 248, 62, 11, 23, 6, 245, 108, 11, 23, 6, 210, 85, 11, 23, 6, 245, - 71, 11, 23, 6, 216, 180, 11, 23, 6, 235, 192, 11, 23, 6, 234, 228, 11, - 23, 6, 233, 104, 11, 23, 6, 230, 107, 11, 23, 6, 227, 242, 11, 23, 6, - 211, 157, 11, 23, 6, 226, 203, 11, 23, 6, 225, 111, 11, 23, 6, 223, 40, - 11, 23, 6, 216, 181, 87, 11, 23, 6, 219, 179, 11, 23, 6, 217, 42, 11, 23, - 6, 214, 157, 11, 23, 6, 225, 136, 11, 23, 6, 250, 118, 11, 23, 6, 224, - 164, 11, 23, 6, 226, 205, 11, 23, 229, 226, 11, 23, 4, 254, 151, 11, 23, - 4, 252, 34, 11, 23, 4, 243, 114, 11, 23, 4, 248, 62, 11, 23, 4, 245, 108, - 11, 23, 4, 210, 85, 11, 23, 4, 245, 71, 11, 23, 4, 216, 180, 11, 23, 4, - 235, 192, 11, 23, 4, 234, 228, 11, 23, 4, 233, 104, 11, 23, 4, 230, 107, - 11, 23, 4, 227, 242, 11, 23, 4, 211, 157, 11, 23, 4, 226, 203, 11, 23, 4, - 225, 111, 11, 23, 4, 223, 40, 11, 23, 4, 40, 219, 179, 11, 23, 4, 219, - 179, 11, 23, 4, 217, 42, 11, 23, 4, 214, 157, 11, 23, 4, 225, 136, 11, - 23, 4, 250, 118, 11, 23, 4, 224, 164, 11, 23, 4, 226, 205, 11, 23, 226, - 1, 247, 241, 11, 23, 245, 109, 87, 11, 23, 216, 181, 87, 11, 23, 234, - 229, 87, 11, 23, 225, 137, 87, 11, 23, 223, 41, 87, 11, 23, 225, 112, 87, - 11, 32, 6, 254, 151, 11, 32, 6, 252, 34, 11, 32, 6, 243, 114, 11, 32, 6, - 248, 62, 11, 32, 6, 245, 108, 11, 32, 6, 210, 85, 11, 32, 6, 245, 71, 11, - 32, 6, 216, 180, 11, 32, 6, 235, 192, 11, 32, 6, 234, 228, 11, 32, 6, - 233, 104, 11, 32, 6, 230, 107, 11, 32, 6, 227, 242, 11, 32, 6, 211, 157, - 11, 32, 6, 226, 203, 11, 32, 6, 225, 111, 11, 32, 6, 223, 40, 11, 32, 6, - 216, 181, 87, 11, 32, 6, 219, 179, 11, 32, 6, 217, 42, 11, 32, 6, 214, - 157, 11, 32, 6, 225, 136, 11, 32, 6, 250, 118, 11, 32, 6, 224, 164, 11, - 32, 6, 226, 205, 11, 32, 229, 226, 11, 32, 4, 254, 151, 11, 32, 4, 252, - 34, 11, 32, 4, 243, 114, 11, 32, 4, 248, 62, 11, 32, 4, 245, 108, 11, 32, - 4, 210, 85, 11, 32, 4, 245, 71, 11, 32, 4, 216, 180, 11, 32, 4, 235, 192, - 11, 32, 4, 234, 228, 11, 32, 4, 233, 104, 11, 32, 4, 230, 107, 11, 32, 4, - 227, 242, 11, 32, 4, 211, 157, 11, 32, 4, 226, 203, 11, 32, 4, 225, 111, - 11, 32, 4, 223, 40, 11, 32, 4, 40, 219, 179, 11, 32, 4, 219, 179, 11, 32, - 4, 217, 42, 11, 32, 4, 214, 157, 11, 32, 4, 225, 136, 11, 32, 4, 250, - 118, 11, 32, 4, 224, 164, 11, 32, 4, 226, 205, 11, 32, 226, 1, 247, 241, - 11, 32, 245, 109, 87, 11, 32, 216, 181, 87, 11, 32, 234, 229, 87, 11, 32, - 225, 137, 87, 11, 32, 223, 41, 87, 11, 32, 225, 112, 87, 11, 23, 32, 6, - 254, 151, 11, 23, 32, 6, 252, 34, 11, 23, 32, 6, 243, 114, 11, 23, 32, 6, - 248, 62, 11, 23, 32, 6, 245, 108, 11, 23, 32, 6, 210, 85, 11, 23, 32, 6, - 245, 71, 11, 23, 32, 6, 216, 180, 11, 23, 32, 6, 235, 192, 11, 23, 32, 6, - 234, 228, 11, 23, 32, 6, 233, 104, 11, 23, 32, 6, 230, 107, 11, 23, 32, - 6, 227, 242, 11, 23, 32, 6, 211, 157, 11, 23, 32, 6, 226, 203, 11, 23, - 32, 6, 225, 111, 11, 23, 32, 6, 223, 40, 11, 23, 32, 6, 216, 181, 87, 11, - 23, 32, 6, 219, 179, 11, 23, 32, 6, 217, 42, 11, 23, 32, 6, 214, 157, 11, - 23, 32, 6, 225, 136, 11, 23, 32, 6, 250, 118, 11, 23, 32, 6, 224, 164, - 11, 23, 32, 6, 226, 205, 11, 23, 32, 229, 226, 11, 23, 32, 4, 254, 151, - 11, 23, 32, 4, 252, 34, 11, 23, 32, 4, 243, 114, 11, 23, 32, 4, 248, 62, - 11, 23, 32, 4, 245, 108, 11, 23, 32, 4, 210, 85, 11, 23, 32, 4, 245, 71, - 11, 23, 32, 4, 216, 180, 11, 23, 32, 4, 235, 192, 11, 23, 32, 4, 234, - 228, 11, 23, 32, 4, 233, 104, 11, 23, 32, 4, 230, 107, 11, 23, 32, 4, - 227, 242, 11, 23, 32, 4, 211, 157, 11, 23, 32, 4, 226, 203, 11, 23, 32, - 4, 225, 111, 11, 23, 32, 4, 223, 40, 11, 23, 32, 4, 40, 219, 179, 11, 23, - 32, 4, 219, 179, 11, 23, 32, 4, 217, 42, 11, 23, 32, 4, 214, 157, 11, 23, - 32, 4, 225, 136, 11, 23, 32, 4, 250, 118, 11, 23, 32, 4, 224, 164, 11, - 23, 32, 4, 226, 205, 11, 23, 32, 226, 1, 247, 241, 11, 23, 32, 245, 109, - 87, 11, 23, 32, 216, 181, 87, 11, 23, 32, 234, 229, 87, 11, 23, 32, 225, - 137, 87, 11, 23, 32, 223, 41, 87, 11, 23, 32, 225, 112, 87, 11, 35, 23, - 6, 254, 151, 11, 35, 23, 6, 252, 34, 11, 35, 23, 6, 243, 114, 11, 35, 23, - 6, 248, 62, 11, 35, 23, 6, 245, 108, 11, 35, 23, 6, 210, 85, 11, 35, 23, - 6, 245, 71, 11, 35, 23, 6, 216, 180, 11, 35, 23, 6, 235, 192, 11, 35, 23, - 6, 234, 228, 11, 35, 23, 6, 233, 104, 11, 35, 23, 6, 230, 107, 11, 35, - 23, 6, 227, 242, 11, 35, 23, 6, 211, 157, 11, 35, 23, 6, 226, 203, 11, - 35, 23, 6, 225, 111, 11, 35, 23, 6, 223, 40, 11, 35, 23, 6, 216, 181, 87, - 11, 35, 23, 6, 219, 179, 11, 35, 23, 6, 217, 42, 11, 35, 23, 6, 214, 157, - 11, 35, 23, 6, 225, 136, 11, 35, 23, 6, 250, 118, 11, 35, 23, 6, 224, - 164, 11, 35, 23, 6, 226, 205, 11, 35, 23, 229, 226, 11, 35, 23, 4, 254, - 151, 11, 35, 23, 4, 252, 34, 11, 35, 23, 4, 243, 114, 11, 35, 23, 4, 248, - 62, 11, 35, 23, 4, 245, 108, 11, 35, 23, 4, 210, 85, 11, 35, 23, 4, 245, - 71, 11, 35, 23, 4, 216, 180, 11, 35, 23, 4, 235, 192, 11, 35, 23, 4, 234, - 228, 11, 35, 23, 4, 233, 104, 11, 35, 23, 4, 230, 107, 11, 35, 23, 4, - 227, 242, 11, 35, 23, 4, 211, 157, 11, 35, 23, 4, 226, 203, 11, 35, 23, - 4, 225, 111, 11, 35, 23, 4, 223, 40, 11, 35, 23, 4, 40, 219, 179, 11, 35, - 23, 4, 219, 179, 11, 35, 23, 4, 217, 42, 11, 35, 23, 4, 214, 157, 11, 35, - 23, 4, 225, 136, 11, 35, 23, 4, 250, 118, 11, 35, 23, 4, 224, 164, 11, - 35, 23, 4, 226, 205, 11, 35, 23, 226, 1, 247, 241, 11, 35, 23, 245, 109, - 87, 11, 35, 23, 216, 181, 87, 11, 35, 23, 234, 229, 87, 11, 35, 23, 225, - 137, 87, 11, 35, 23, 223, 41, 87, 11, 35, 23, 225, 112, 87, 11, 35, 23, - 32, 6, 254, 151, 11, 35, 23, 32, 6, 252, 34, 11, 35, 23, 32, 6, 243, 114, - 11, 35, 23, 32, 6, 248, 62, 11, 35, 23, 32, 6, 245, 108, 11, 35, 23, 32, - 6, 210, 85, 11, 35, 23, 32, 6, 245, 71, 11, 35, 23, 32, 6, 216, 180, 11, - 35, 23, 32, 6, 235, 192, 11, 35, 23, 32, 6, 234, 228, 11, 35, 23, 32, 6, - 233, 104, 11, 35, 23, 32, 6, 230, 107, 11, 35, 23, 32, 6, 227, 242, 11, - 35, 23, 32, 6, 211, 157, 11, 35, 23, 32, 6, 226, 203, 11, 35, 23, 32, 6, - 225, 111, 11, 35, 23, 32, 6, 223, 40, 11, 35, 23, 32, 6, 216, 181, 87, - 11, 35, 23, 32, 6, 219, 179, 11, 35, 23, 32, 6, 217, 42, 11, 35, 23, 32, - 6, 214, 157, 11, 35, 23, 32, 6, 225, 136, 11, 35, 23, 32, 6, 250, 118, - 11, 35, 23, 32, 6, 224, 164, 11, 35, 23, 32, 6, 226, 205, 11, 35, 23, 32, - 229, 226, 11, 35, 23, 32, 4, 254, 151, 11, 35, 23, 32, 4, 252, 34, 11, - 35, 23, 32, 4, 243, 114, 11, 35, 23, 32, 4, 248, 62, 11, 35, 23, 32, 4, - 245, 108, 11, 35, 23, 32, 4, 210, 85, 11, 35, 23, 32, 4, 245, 71, 11, 35, - 23, 32, 4, 216, 180, 11, 35, 23, 32, 4, 235, 192, 11, 35, 23, 32, 4, 234, - 228, 11, 35, 23, 32, 4, 233, 104, 11, 35, 23, 32, 4, 230, 107, 11, 35, - 23, 32, 4, 227, 242, 11, 35, 23, 32, 4, 211, 157, 11, 35, 23, 32, 4, 226, - 203, 11, 35, 23, 32, 4, 225, 111, 11, 35, 23, 32, 4, 223, 40, 11, 35, 23, - 32, 4, 40, 219, 179, 11, 35, 23, 32, 4, 219, 179, 11, 35, 23, 32, 4, 217, - 42, 11, 35, 23, 32, 4, 214, 157, 11, 35, 23, 32, 4, 225, 136, 11, 35, 23, - 32, 4, 250, 118, 11, 35, 23, 32, 4, 224, 164, 11, 35, 23, 32, 4, 226, - 205, 11, 35, 23, 32, 226, 1, 247, 241, 11, 35, 23, 32, 245, 109, 87, 11, - 35, 23, 32, 216, 181, 87, 11, 35, 23, 32, 234, 229, 87, 11, 35, 23, 32, - 225, 137, 87, 11, 35, 23, 32, 223, 41, 87, 11, 35, 23, 32, 225, 112, 87, - 11, 23, 6, 247, 235, 11, 23, 4, 247, 235, 11, 23, 21, 210, 86, 11, 23, - 21, 111, 11, 23, 21, 105, 11, 23, 21, 158, 11, 23, 21, 161, 11, 23, 21, - 190, 11, 23, 21, 195, 11, 23, 21, 199, 11, 23, 21, 196, 11, 23, 21, 201, - 11, 139, 21, 210, 86, 11, 139, 21, 111, 11, 139, 21, 105, 11, 139, 21, - 158, 11, 139, 21, 161, 11, 139, 21, 190, 11, 139, 21, 195, 11, 139, 21, - 199, 11, 139, 21, 196, 11, 139, 21, 201, 11, 35, 21, 210, 86, 11, 35, 21, - 111, 11, 35, 21, 105, 11, 35, 21, 158, 11, 35, 21, 161, 11, 35, 21, 190, - 11, 35, 21, 195, 11, 35, 21, 199, 11, 35, 21, 196, 11, 35, 21, 201, 11, - 35, 23, 21, 210, 86, 11, 35, 23, 21, 111, 11, 35, 23, 21, 105, 11, 35, - 23, 21, 158, 11, 35, 23, 21, 161, 11, 35, 23, 21, 190, 11, 35, 23, 21, - 195, 11, 35, 23, 21, 199, 11, 35, 23, 21, 196, 11, 35, 23, 21, 201, 11, - 230, 143, 21, 210, 86, 11, 230, 143, 21, 111, 11, 230, 143, 21, 105, 11, - 230, 143, 21, 158, 11, 230, 143, 21, 161, 11, 230, 143, 21, 190, 11, 230, - 143, 21, 195, 11, 230, 143, 21, 199, 11, 230, 143, 21, 196, 11, 230, 143, - 21, 201, 9, 11, 254, 179, 9, 11, 252, 62, 9, 11, 235, 129, 9, 11, 248, - 203, 9, 11, 212, 30, 9, 11, 210, 108, 9, 11, 242, 44, 9, 11, 217, 81, 9, - 11, 211, 43, 9, 11, 235, 0, 9, 11, 233, 108, 9, 11, 231, 83, 9, 11, 228, - 67, 9, 11, 221, 168, 9, 11, 254, 205, 9, 11, 244, 150, 9, 11, 222, 28, 9, - 11, 224, 84, 9, 11, 223, 98, 9, 11, 220, 61, 9, 11, 217, 8, 9, 11, 216, - 193, 9, 11, 234, 135, 9, 11, 216, 203, 9, 11, 248, 224, 9, 11, 210, 111, - 9, 11, 242, 251, 9, 11, 247, 127, 252, 62, 9, 11, 247, 127, 228, 67, 9, - 11, 247, 127, 244, 150, 9, 11, 247, 127, 224, 84, 9, 11, 65, 252, 62, 9, - 11, 65, 235, 129, 9, 11, 65, 241, 225, 9, 11, 65, 242, 44, 9, 11, 65, - 211, 43, 9, 11, 65, 235, 0, 9, 11, 65, 233, 108, 9, 11, 65, 231, 83, 9, - 11, 65, 228, 67, 9, 11, 65, 221, 168, 9, 11, 65, 254, 205, 9, 11, 65, - 244, 150, 9, 11, 65, 222, 28, 9, 11, 65, 224, 84, 9, 11, 65, 220, 61, 9, - 11, 65, 217, 8, 9, 11, 65, 216, 193, 9, 11, 65, 234, 135, 9, 11, 65, 248, - 224, 9, 11, 65, 242, 251, 9, 11, 217, 77, 235, 129, 9, 11, 217, 77, 242, - 44, 9, 11, 217, 77, 211, 43, 9, 11, 217, 77, 233, 108, 9, 11, 217, 77, - 228, 67, 9, 11, 217, 77, 221, 168, 9, 11, 217, 77, 254, 205, 9, 11, 217, - 77, 222, 28, 9, 11, 217, 77, 224, 84, 9, 11, 217, 77, 220, 61, 9, 11, - 217, 77, 234, 135, 9, 11, 217, 77, 248, 224, 9, 11, 217, 77, 242, 251, 9, - 11, 217, 77, 247, 127, 228, 67, 9, 11, 217, 77, 247, 127, 224, 84, 9, 11, - 218, 112, 252, 62, 9, 11, 218, 112, 235, 129, 9, 11, 218, 112, 241, 225, - 9, 11, 218, 112, 242, 44, 9, 11, 218, 112, 217, 81, 9, 11, 218, 112, 211, - 43, 9, 11, 218, 112, 235, 0, 9, 11, 218, 112, 231, 83, 9, 11, 218, 112, - 228, 67, 9, 11, 218, 112, 221, 168, 9, 11, 218, 112, 254, 205, 9, 11, - 218, 112, 244, 150, 9, 11, 218, 112, 222, 28, 9, 11, 218, 112, 224, 84, - 9, 11, 218, 112, 220, 61, 9, 11, 218, 112, 217, 8, 9, 11, 218, 112, 216, - 193, 9, 11, 218, 112, 234, 135, 9, 11, 218, 112, 248, 224, 9, 11, 218, - 112, 210, 111, 9, 11, 218, 112, 242, 251, 9, 11, 218, 112, 247, 127, 252, - 62, 9, 11, 218, 112, 247, 127, 244, 150, 9, 11, 232, 128, 254, 179, 9, - 11, 232, 128, 252, 62, 9, 11, 232, 128, 235, 129, 9, 11, 232, 128, 248, - 203, 9, 11, 232, 128, 241, 225, 9, 11, 232, 128, 212, 30, 9, 11, 232, - 128, 210, 108, 9, 11, 232, 128, 242, 44, 9, 11, 232, 128, 217, 81, 9, 11, - 232, 128, 211, 43, 9, 11, 232, 128, 233, 108, 9, 11, 232, 128, 231, 83, - 9, 11, 232, 128, 228, 67, 9, 11, 232, 128, 221, 168, 9, 11, 232, 128, - 254, 205, 9, 11, 232, 128, 244, 150, 9, 11, 232, 128, 222, 28, 9, 11, - 232, 128, 224, 84, 9, 11, 232, 128, 223, 98, 9, 11, 232, 128, 220, 61, 9, - 11, 232, 128, 217, 8, 9, 11, 232, 128, 216, 193, 9, 11, 232, 128, 234, - 135, 9, 11, 232, 128, 216, 203, 9, 11, 232, 128, 248, 224, 9, 11, 232, - 128, 210, 111, 9, 11, 232, 128, 242, 251, 9, 11, 139, 252, 62, 9, 11, - 139, 235, 129, 9, 11, 139, 248, 203, 9, 11, 139, 212, 30, 9, 11, 139, - 210, 108, 9, 11, 139, 242, 44, 9, 11, 139, 217, 81, 9, 11, 139, 211, 43, - 9, 11, 139, 233, 108, 9, 11, 139, 231, 83, 9, 11, 139, 228, 67, 9, 11, - 139, 221, 168, 9, 11, 139, 254, 205, 9, 11, 139, 244, 150, 9, 11, 139, - 222, 28, 9, 11, 139, 224, 84, 9, 11, 139, 223, 98, 9, 11, 139, 220, 61, - 9, 11, 139, 217, 8, 9, 11, 139, 216, 193, 9, 11, 139, 234, 135, 9, 11, - 139, 216, 203, 9, 11, 139, 248, 224, 9, 11, 139, 210, 111, 9, 11, 139, - 242, 251, 9, 11, 226, 172, 66, 2, 122, 2, 217, 44, 9, 11, 226, 172, 122, - 2, 248, 203, 231, 210, 86, 245, 228, 211, 239, 231, 210, 86, 219, 30, - 211, 239, 231, 210, 86, 212, 9, 211, 239, 231, 210, 86, 228, 61, 211, - 239, 231, 210, 86, 223, 114, 246, 104, 231, 210, 86, 242, 134, 246, 104, - 231, 210, 86, 71, 246, 104, 231, 210, 86, 123, 64, 250, 149, 231, 210, - 86, 113, 64, 250, 149, 231, 210, 86, 134, 64, 250, 149, 231, 210, 86, - 244, 19, 64, 250, 149, 231, 210, 86, 244, 89, 64, 250, 149, 231, 210, 86, - 219, 127, 64, 250, 149, 231, 210, 86, 220, 124, 64, 250, 149, 231, 210, - 86, 245, 201, 64, 250, 149, 231, 210, 86, 228, 205, 64, 250, 149, 231, - 210, 86, 123, 64, 252, 161, 231, 210, 86, 113, 64, 252, 161, 231, 210, - 86, 134, 64, 252, 161, 231, 210, 86, 244, 19, 64, 252, 161, 231, 210, 86, - 244, 89, 64, 252, 161, 231, 210, 86, 219, 127, 64, 252, 161, 231, 210, - 86, 220, 124, 64, 252, 161, 231, 210, 86, 245, 201, 64, 252, 161, 231, - 210, 86, 228, 205, 64, 252, 161, 231, 210, 86, 123, 64, 250, 42, 231, - 210, 86, 113, 64, 250, 42, 231, 210, 86, 134, 64, 250, 42, 231, 210, 86, - 244, 19, 64, 250, 42, 231, 210, 86, 244, 89, 64, 250, 42, 231, 210, 86, - 219, 127, 64, 250, 42, 231, 210, 86, 220, 124, 64, 250, 42, 231, 210, 86, - 245, 201, 64, 250, 42, 231, 210, 86, 228, 205, 64, 250, 42, 231, 210, 86, - 225, 28, 231, 210, 86, 226, 160, 231, 210, 86, 252, 162, 231, 210, 86, - 250, 78, 231, 210, 86, 218, 241, 231, 210, 86, 218, 40, 231, 210, 86, - 253, 187, 231, 210, 86, 211, 232, 231, 210, 86, 235, 68, 231, 210, 86, - 252, 192, 131, 86, 203, 252, 192, 131, 86, 241, 50, 131, 86, 241, 49, - 131, 86, 241, 48, 131, 86, 241, 47, 131, 86, 241, 46, 131, 86, 241, 45, - 131, 86, 241, 44, 131, 86, 241, 43, 131, 86, 241, 42, 131, 86, 241, 41, - 131, 86, 241, 40, 131, 86, 241, 39, 131, 86, 241, 38, 131, 86, 241, 37, - 131, 86, 241, 36, 131, 86, 241, 35, 131, 86, 241, 34, 131, 86, 241, 33, - 131, 86, 241, 32, 131, 86, 241, 31, 131, 86, 241, 30, 131, 86, 241, 29, - 131, 86, 241, 28, 131, 86, 241, 27, 131, 86, 241, 26, 131, 86, 241, 25, - 131, 86, 241, 24, 131, 86, 241, 23, 131, 86, 241, 22, 131, 86, 241, 21, - 131, 86, 241, 20, 131, 86, 241, 19, 131, 86, 241, 18, 131, 86, 241, 17, - 131, 86, 241, 16, 131, 86, 241, 15, 131, 86, 241, 14, 131, 86, 241, 13, - 131, 86, 241, 12, 131, 86, 241, 11, 131, 86, 241, 10, 131, 86, 241, 9, - 131, 86, 241, 8, 131, 86, 241, 7, 131, 86, 241, 6, 131, 86, 241, 5, 131, - 86, 241, 4, 131, 86, 241, 3, 131, 86, 241, 2, 131, 86, 67, 252, 192, 131, - 86, 213, 238, 131, 86, 213, 237, 131, 86, 213, 236, 131, 86, 213, 235, - 131, 86, 213, 234, 131, 86, 213, 233, 131, 86, 213, 232, 131, 86, 213, - 231, 131, 86, 213, 230, 131, 86, 213, 229, 131, 86, 213, 228, 131, 86, - 213, 227, 131, 86, 213, 226, 131, 86, 213, 225, 131, 86, 213, 224, 131, - 86, 213, 223, 131, 86, 213, 222, 131, 86, 213, 221, 131, 86, 213, 220, - 131, 86, 213, 219, 131, 86, 213, 218, 131, 86, 213, 217, 131, 86, 213, - 216, 131, 86, 213, 215, 131, 86, 213, 214, 131, 86, 213, 213, 131, 86, - 213, 212, 131, 86, 213, 211, 131, 86, 213, 210, 131, 86, 213, 209, 131, - 86, 213, 208, 131, 86, 213, 207, 131, 86, 213, 206, 131, 86, 213, 205, - 131, 86, 213, 204, 131, 86, 213, 203, 131, 86, 213, 202, 131, 86, 213, - 201, 131, 86, 213, 200, 131, 86, 213, 199, 131, 86, 213, 198, 131, 86, - 213, 197, 131, 86, 213, 196, 131, 86, 213, 195, 131, 86, 213, 194, 131, - 86, 213, 193, 131, 86, 213, 192, 131, 86, 213, 191, 131, 86, 213, 190, - 225, 36, 250, 251, 252, 192, 225, 36, 250, 251, 255, 18, 64, 219, 17, - 225, 36, 250, 251, 113, 64, 219, 17, 225, 36, 250, 251, 134, 64, 219, 17, - 225, 36, 250, 251, 244, 19, 64, 219, 17, 225, 36, 250, 251, 244, 89, 64, - 219, 17, 225, 36, 250, 251, 219, 127, 64, 219, 17, 225, 36, 250, 251, - 220, 124, 64, 219, 17, 225, 36, 250, 251, 245, 201, 64, 219, 17, 225, 36, - 250, 251, 228, 205, 64, 219, 17, 225, 36, 250, 251, 216, 249, 64, 219, - 17, 225, 36, 250, 251, 235, 145, 64, 219, 17, 225, 36, 250, 251, 234, 37, - 64, 219, 17, 225, 36, 250, 251, 224, 18, 64, 219, 17, 225, 36, 250, 251, - 234, 85, 64, 219, 17, 225, 36, 250, 251, 255, 18, 64, 241, 232, 225, 36, - 250, 251, 113, 64, 241, 232, 225, 36, 250, 251, 134, 64, 241, 232, 225, - 36, 250, 251, 244, 19, 64, 241, 232, 225, 36, 250, 251, 244, 89, 64, 241, - 232, 225, 36, 250, 251, 219, 127, 64, 241, 232, 225, 36, 250, 251, 220, - 124, 64, 241, 232, 225, 36, 250, 251, 245, 201, 64, 241, 232, 225, 36, - 250, 251, 228, 205, 64, 241, 232, 225, 36, 250, 251, 216, 249, 64, 241, - 232, 225, 36, 250, 251, 235, 145, 64, 241, 232, 225, 36, 250, 251, 234, - 37, 64, 241, 232, 225, 36, 250, 251, 224, 18, 64, 241, 232, 225, 36, 250, - 251, 234, 85, 64, 241, 232, 225, 36, 250, 251, 255, 18, 64, 247, 255, - 225, 36, 250, 251, 113, 64, 247, 255, 225, 36, 250, 251, 134, 64, 247, - 255, 225, 36, 250, 251, 244, 19, 64, 247, 255, 225, 36, 250, 251, 244, - 89, 64, 247, 255, 225, 36, 250, 251, 219, 127, 64, 247, 255, 225, 36, - 250, 251, 220, 124, 64, 247, 255, 225, 36, 250, 251, 245, 201, 64, 247, - 255, 225, 36, 250, 251, 228, 205, 64, 247, 255, 225, 36, 250, 251, 216, - 249, 64, 247, 255, 225, 36, 250, 251, 235, 145, 64, 247, 255, 225, 36, - 250, 251, 234, 37, 64, 247, 255, 225, 36, 250, 251, 224, 18, 64, 247, - 255, 225, 36, 250, 251, 234, 85, 64, 247, 255, 225, 36, 250, 251, 85, - 235, 68, 225, 36, 250, 251, 255, 18, 64, 249, 250, 225, 36, 250, 251, - 113, 64, 249, 250, 225, 36, 250, 251, 134, 64, 249, 250, 225, 36, 250, - 251, 244, 19, 64, 249, 250, 225, 36, 250, 251, 244, 89, 64, 249, 250, - 225, 36, 250, 251, 219, 127, 64, 249, 250, 225, 36, 250, 251, 220, 124, - 64, 249, 250, 225, 36, 250, 251, 245, 201, 64, 249, 250, 225, 36, 250, - 251, 228, 205, 64, 249, 250, 225, 36, 250, 251, 216, 249, 64, 249, 250, - 225, 36, 250, 251, 235, 145, 64, 249, 250, 225, 36, 250, 251, 234, 37, - 64, 249, 250, 225, 36, 250, 251, 224, 18, 64, 249, 250, 225, 36, 250, - 251, 234, 85, 64, 249, 250, 225, 36, 250, 251, 71, 235, 68, 21, 210, 87, - 243, 236, 218, 131, 21, 210, 87, 249, 227, 21, 123, 249, 227, 21, 113, - 249, 227, 21, 134, 249, 227, 21, 244, 19, 249, 227, 21, 244, 89, 249, - 227, 21, 219, 127, 249, 227, 21, 220, 124, 249, 227, 21, 245, 201, 249, - 227, 21, 228, 205, 249, 227, 88, 7, 6, 1, 61, 88, 7, 6, 1, 253, 166, 88, - 7, 6, 1, 251, 74, 88, 7, 6, 1, 249, 68, 88, 7, 6, 1, 76, 88, 7, 6, 1, - 245, 14, 88, 7, 6, 1, 243, 209, 88, 7, 6, 1, 242, 67, 88, 7, 6, 1, 74, - 88, 7, 6, 1, 235, 150, 88, 7, 6, 1, 235, 29, 88, 7, 6, 1, 156, 88, 7, 6, - 1, 194, 88, 7, 6, 1, 230, 30, 88, 7, 6, 1, 78, 88, 7, 6, 1, 226, 109, 88, - 7, 6, 1, 224, 99, 88, 7, 6, 1, 153, 88, 7, 6, 1, 222, 93, 88, 7, 6, 1, - 217, 153, 88, 7, 6, 1, 69, 88, 7, 6, 1, 214, 105, 88, 7, 6, 1, 212, 98, - 88, 7, 6, 1, 211, 178, 88, 7, 6, 1, 211, 117, 88, 7, 6, 1, 210, 159, 216, - 7, 220, 55, 251, 165, 7, 6, 1, 222, 93, 37, 32, 7, 6, 1, 251, 74, 37, 32, - 7, 6, 1, 153, 37, 250, 199, 37, 211, 180, 92, 7, 6, 1, 61, 92, 7, 6, 1, - 253, 166, 92, 7, 6, 1, 251, 74, 92, 7, 6, 1, 249, 68, 92, 7, 6, 1, 76, - 92, 7, 6, 1, 245, 14, 92, 7, 6, 1, 243, 209, 92, 7, 6, 1, 242, 67, 92, 7, - 6, 1, 74, 92, 7, 6, 1, 235, 150, 92, 7, 6, 1, 235, 29, 92, 7, 6, 1, 156, - 92, 7, 6, 1, 194, 92, 7, 6, 1, 230, 30, 92, 7, 6, 1, 78, 92, 7, 6, 1, - 226, 109, 92, 7, 6, 1, 224, 99, 92, 7, 6, 1, 153, 92, 7, 6, 1, 222, 93, - 92, 7, 6, 1, 217, 153, 92, 7, 6, 1, 69, 92, 7, 6, 1, 214, 105, 92, 7, 6, - 1, 212, 98, 92, 7, 6, 1, 211, 178, 92, 7, 6, 1, 211, 117, 92, 7, 6, 1, - 210, 159, 92, 240, 208, 92, 230, 54, 92, 221, 185, 92, 218, 228, 92, 224, - 221, 92, 212, 23, 152, 37, 7, 6, 1, 61, 152, 37, 7, 6, 1, 253, 166, 152, - 37, 7, 6, 1, 251, 74, 152, 37, 7, 6, 1, 249, 68, 152, 37, 7, 6, 1, 76, - 152, 37, 7, 6, 1, 245, 14, 152, 37, 7, 6, 1, 243, 209, 152, 37, 7, 6, 1, - 242, 67, 152, 37, 7, 6, 1, 74, 152, 37, 7, 6, 1, 235, 150, 152, 37, 7, 6, - 1, 235, 29, 152, 37, 7, 6, 1, 156, 152, 37, 7, 6, 1, 194, 152, 37, 7, 6, - 1, 230, 30, 152, 37, 7, 6, 1, 78, 152, 37, 7, 6, 1, 226, 109, 152, 37, 7, - 6, 1, 224, 99, 152, 37, 7, 6, 1, 153, 152, 37, 7, 6, 1, 222, 93, 152, 37, - 7, 6, 1, 217, 153, 152, 37, 7, 6, 1, 69, 152, 37, 7, 6, 1, 214, 105, 152, - 37, 7, 6, 1, 212, 98, 152, 37, 7, 6, 1, 211, 178, 152, 37, 7, 6, 1, 211, - 117, 152, 37, 7, 6, 1, 210, 159, 223, 160, 231, 102, 50, 223, 160, 231, - 99, 50, 152, 92, 7, 6, 1, 61, 152, 92, 7, 6, 1, 253, 166, 152, 92, 7, 6, - 1, 251, 74, 152, 92, 7, 6, 1, 249, 68, 152, 92, 7, 6, 1, 76, 152, 92, 7, - 6, 1, 245, 14, 152, 92, 7, 6, 1, 243, 209, 152, 92, 7, 6, 1, 242, 67, - 152, 92, 7, 6, 1, 74, 152, 92, 7, 6, 1, 235, 150, 152, 92, 7, 6, 1, 235, - 29, 152, 92, 7, 6, 1, 156, 152, 92, 7, 6, 1, 194, 152, 92, 7, 6, 1, 230, - 30, 152, 92, 7, 6, 1, 78, 152, 92, 7, 6, 1, 226, 109, 152, 92, 7, 6, 1, - 224, 99, 152, 92, 7, 6, 1, 153, 152, 92, 7, 6, 1, 222, 93, 152, 92, 7, 6, - 1, 217, 153, 152, 92, 7, 6, 1, 69, 152, 92, 7, 6, 1, 214, 105, 152, 92, - 7, 6, 1, 212, 98, 152, 92, 7, 6, 1, 211, 178, 152, 92, 7, 6, 1, 211, 117, - 152, 92, 7, 6, 1, 210, 159, 249, 136, 152, 92, 7, 6, 1, 226, 109, 152, - 92, 240, 120, 152, 92, 191, 152, 92, 206, 152, 92, 255, 34, 152, 92, 212, - 23, 42, 247, 172, 92, 250, 31, 92, 249, 178, 92, 244, 4, 92, 240, 112, - 92, 229, 91, 92, 229, 84, 92, 226, 218, 92, 219, 37, 92, 120, 2, 245, 39, - 79, 92, 213, 119, 223, 106, 235, 246, 16, 1, 61, 223, 106, 235, 246, 16, - 1, 253, 166, 223, 106, 235, 246, 16, 1, 251, 74, 223, 106, 235, 246, 16, - 1, 249, 68, 223, 106, 235, 246, 16, 1, 76, 223, 106, 235, 246, 16, 1, - 245, 14, 223, 106, 235, 246, 16, 1, 243, 209, 223, 106, 235, 246, 16, 1, - 242, 67, 223, 106, 235, 246, 16, 1, 74, 223, 106, 235, 246, 16, 1, 235, - 150, 223, 106, 235, 246, 16, 1, 235, 29, 223, 106, 235, 246, 16, 1, 156, - 223, 106, 235, 246, 16, 1, 194, 223, 106, 235, 246, 16, 1, 230, 30, 223, - 106, 235, 246, 16, 1, 78, 223, 106, 235, 246, 16, 1, 226, 109, 223, 106, - 235, 246, 16, 1, 224, 99, 223, 106, 235, 246, 16, 1, 153, 223, 106, 235, - 246, 16, 1, 222, 93, 223, 106, 235, 246, 16, 1, 217, 153, 223, 106, 235, - 246, 16, 1, 69, 223, 106, 235, 246, 16, 1, 214, 105, 223, 106, 235, 246, - 16, 1, 212, 98, 223, 106, 235, 246, 16, 1, 211, 178, 223, 106, 235, 246, - 16, 1, 211, 117, 223, 106, 235, 246, 16, 1, 210, 159, 42, 141, 241, 70, - 92, 56, 234, 24, 92, 56, 206, 92, 10, 214, 177, 238, 57, 92, 10, 214, - 177, 238, 61, 92, 10, 214, 177, 238, 69, 92, 56, 248, 98, 92, 10, 214, - 177, 238, 76, 92, 10, 214, 177, 238, 63, 92, 10, 214, 177, 238, 35, 92, - 10, 214, 177, 238, 62, 92, 10, 214, 177, 238, 75, 92, 10, 214, 177, 238, - 49, 92, 10, 214, 177, 238, 42, 92, 10, 214, 177, 238, 51, 92, 10, 214, - 177, 238, 72, 92, 10, 214, 177, 238, 58, 92, 10, 214, 177, 238, 74, 92, - 10, 214, 177, 238, 50, 92, 10, 214, 177, 238, 73, 92, 10, 214, 177, 238, - 36, 92, 10, 214, 177, 238, 41, 92, 10, 214, 177, 238, 34, 92, 10, 214, - 177, 238, 64, 92, 10, 214, 177, 238, 66, 92, 10, 214, 177, 238, 44, 92, - 10, 214, 177, 238, 55, 92, 10, 214, 177, 238, 53, 92, 10, 214, 177, 238, - 79, 92, 10, 214, 177, 238, 78, 92, 10, 214, 177, 238, 32, 92, 10, 214, - 177, 238, 59, 92, 10, 214, 177, 238, 77, 92, 10, 214, 177, 238, 68, 92, - 10, 214, 177, 238, 54, 92, 10, 214, 177, 238, 33, 92, 10, 214, 177, 238, - 56, 92, 10, 214, 177, 238, 38, 92, 10, 214, 177, 238, 37, 92, 10, 214, - 177, 238, 67, 92, 10, 214, 177, 238, 45, 92, 10, 214, 177, 238, 47, 92, - 10, 214, 177, 238, 48, 92, 10, 214, 177, 238, 40, 92, 10, 214, 177, 238, - 71, 92, 10, 214, 177, 238, 65, 216, 7, 220, 55, 251, 165, 10, 214, 177, - 238, 46, 216, 7, 220, 55, 251, 165, 10, 214, 177, 238, 78, 216, 7, 220, - 55, 251, 165, 10, 214, 177, 238, 76, 216, 7, 220, 55, 251, 165, 10, 214, - 177, 238, 60, 216, 7, 220, 55, 251, 165, 10, 214, 177, 238, 43, 216, 7, - 220, 55, 251, 165, 10, 214, 177, 238, 56, 216, 7, 220, 55, 251, 165, 10, - 214, 177, 238, 39, 216, 7, 220, 55, 251, 165, 10, 214, 177, 238, 70, 216, - 7, 220, 55, 251, 165, 10, 214, 177, 238, 52, 37, 154, 254, 254, 37, 154, - 255, 21, 249, 79, 244, 50, 250, 8, 214, 194, 228, 218, 2, 218, 155, 218, - 34, 115, 230, 119, 218, 33, 250, 34, 253, 215, 246, 62, 218, 32, 115, - 251, 126, 223, 161, 251, 148, 253, 215, 228, 217, 212, 41, 212, 35, 213, - 131, 230, 200, 212, 25, 245, 232, 242, 188, 245, 53, 245, 232, 242, 188, - 254, 136, 245, 232, 242, 188, 253, 233, 242, 188, 2, 231, 56, 166, 230, - 134, 87, 212, 27, 249, 145, 230, 134, 87, 244, 100, 224, 25, 230, 134, - 87, 212, 27, 242, 217, 230, 134, 87, 243, 236, 230, 134, 87, 212, 52, - 242, 217, 230, 134, 87, 233, 86, 224, 25, 230, 134, 87, 212, 52, 249, - 145, 230, 134, 87, 249, 145, 230, 133, 166, 230, 134, 2, 244, 198, 244, - 100, 224, 25, 230, 134, 2, 244, 198, 233, 86, 224, 25, 230, 134, 2, 244, - 198, 243, 236, 230, 134, 2, 244, 198, 218, 39, 2, 244, 198, 242, 186, - 218, 158, 220, 1, 218, 158, 250, 124, 221, 170, 245, 47, 215, 236, 248, - 92, 215, 236, 226, 63, 215, 236, 251, 35, 215, 110, 250, 126, 251, 218, - 222, 193, 241, 186, 218, 37, 251, 218, 245, 236, 64, 231, 199, 245, 236, - 64, 223, 34, 241, 211, 244, 19, 233, 60, 249, 254, 231, 175, 233, 59, - 244, 184, 233, 59, 233, 60, 244, 55, 236, 7, 211, 239, 230, 63, 216, 35, - 253, 199, 242, 150, 231, 72, 212, 39, 217, 58, 233, 32, 252, 157, 225, - 65, 223, 114, 254, 62, 242, 134, 254, 62, 225, 220, 225, 221, 250, 127, - 218, 116, 242, 30, 219, 92, 64, 225, 47, 231, 92, 226, 201, 251, 202, - 224, 232, 233, 42, 223, 35, 249, 150, 223, 35, 252, 167, 249, 181, 223, - 34, 249, 103, 22, 223, 34, 218, 143, 251, 175, 219, 16, 251, 159, 244, 3, - 243, 255, 222, 209, 217, 247, 224, 234, 248, 183, 226, 240, 218, 8, 244, - 0, 219, 232, 244, 99, 251, 29, 2, 217, 240, 248, 43, 219, 54, 240, 119, - 249, 149, 220, 72, 240, 118, 240, 119, 249, 149, 246, 116, 249, 180, 250, - 92, 130, 251, 6, 232, 147, 249, 96, 241, 62, 224, 236, 219, 242, 252, 44, - 251, 171, 224, 237, 64, 244, 41, 249, 179, 244, 32, 22, 234, 38, 217, 20, - 211, 230, 242, 20, 222, 14, 251, 185, 22, 249, 110, 211, 237, 242, 191, - 249, 243, 242, 191, 215, 194, 246, 98, 252, 70, 230, 98, 250, 15, 252, - 70, 230, 97, 252, 195, 251, 184, 223, 36, 211, 201, 224, 198, 251, 243, - 251, 28, 235, 144, 250, 85, 215, 236, 244, 170, 250, 84, 244, 102, 244, - 103, 219, 14, 252, 166, 225, 254, 224, 247, 249, 212, 252, 167, 217, 60, - 215, 236, 249, 136, 244, 75, 225, 66, 248, 89, 235, 137, 247, 139, 250, - 240, 218, 115, 211, 240, 250, 106, 230, 134, 213, 164, 250, 170, 221, - 201, 221, 226, 242, 155, 251, 3, 250, 241, 240, 252, 244, 138, 212, 0, - 222, 202, 249, 244, 244, 94, 225, 5, 22, 244, 98, 230, 232, 230, 113, - 251, 18, 250, 47, 241, 239, 253, 249, 226, 66, 216, 15, 242, 2, 250, 37, - 216, 243, 216, 114, 250, 28, 251, 210, 225, 180, 253, 248, 213, 172, 243, - 117, 247, 205, 241, 163, 219, 86, 231, 239, 251, 253, 243, 118, 247, 248, - 251, 174, 244, 60, 225, 36, 250, 249, 28, 228, 52, 230, 90, 28, 228, 47, - 221, 214, 242, 106, 28, 234, 143, 215, 191, 213, 154, 28, 221, 194, 222, - 126, 220, 13, 2, 221, 229, 216, 245, 223, 181, 22, 252, 167, 219, 107, - 22, 219, 107, 251, 195, 252, 131, 22, 241, 56, 250, 128, 244, 81, 219, - 65, 222, 127, 218, 13, 215, 195, 240, 253, 223, 182, 254, 137, 244, 39, - 222, 138, 244, 39, 217, 242, 240, 242, 251, 127, 240, 242, 2, 243, 101, - 226, 233, 251, 127, 235, 137, 224, 242, 226, 232, 245, 52, 224, 242, 226, - 232, 240, 251, 252, 153, 253, 189, 216, 253, 231, 239, 240, 247, 232, - 117, 240, 247, 249, 184, 218, 127, 221, 200, 248, 51, 218, 127, 244, 188, - 235, 155, 233, 95, 235, 137, 250, 234, 245, 52, 250, 234, 223, 144, 230, - 117, 226, 118, 212, 41, 251, 131, 249, 153, 216, 107, 233, 24, 223, 183, - 250, 232, 246, 104, 249, 143, 212, 3, 219, 72, 219, 70, 240, 252, 223, - 156, 242, 177, 220, 59, 230, 150, 222, 196, 250, 116, 247, 144, 225, 76, - 251, 211, 245, 177, 226, 242, 218, 254, 220, 54, 251, 130, 254, 100, 241, - 61, 233, 127, 252, 68, 244, 98, 215, 194, 244, 98, 251, 217, 215, 91, - 242, 0, 250, 117, 252, 195, 250, 117, 243, 250, 252, 195, 250, 117, 251, - 245, 225, 198, 234, 32, 224, 251, 246, 95, 251, 19, 252, 185, 251, 19, - 247, 138, 230, 118, 244, 198, 249, 154, 244, 198, 216, 108, 244, 198, - 223, 184, 244, 198, 250, 233, 244, 198, 246, 105, 244, 198, 218, 243, - 212, 3, 240, 253, 244, 198, 230, 151, 244, 198, 247, 145, 244, 198, 225, - 77, 244, 198, 243, 253, 244, 198, 242, 27, 244, 198, 211, 224, 244, 198, - 252, 79, 244, 198, 226, 49, 244, 198, 225, 77, 228, 58, 225, 236, 224, - 189, 245, 21, 245, 235, 228, 58, 230, 115, 216, 20, 71, 120, 225, 10, - 252, 190, 235, 249, 71, 124, 225, 10, 252, 190, 235, 249, 71, 43, 225, - 10, 252, 190, 235, 249, 71, 44, 225, 10, 252, 190, 235, 249, 244, 92, - 242, 23, 50, 212, 33, 242, 23, 50, 226, 219, 242, 23, 50, 216, 136, 120, - 50, 216, 136, 124, 50, 250, 27, 242, 18, 50, 204, 242, 18, 50, 249, 131, - 211, 220, 242, 2, 245, 22, 229, 109, 217, 152, 235, 131, 246, 100, 234, - 88, 251, 255, 211, 220, 250, 1, 224, 130, 242, 21, 224, 233, 231, 182, - 220, 6, 253, 211, 220, 6, 241, 171, 220, 6, 211, 220, 221, 242, 211, 220, - 251, 194, 244, 37, 251, 98, 236, 7, 219, 171, 251, 97, 236, 7, 219, 171, - 251, 170, 242, 201, 231, 190, 211, 221, 244, 182, 231, 191, 22, 211, 222, - 241, 67, 242, 17, 113, 231, 64, 241, 67, 242, 17, 113, 211, 219, 241, 67, - 242, 17, 225, 2, 226, 231, 211, 222, 2, 251, 114, 245, 233, 251, 149, 2, - 213, 246, 225, 171, 2, 251, 220, 242, 41, 231, 191, 2, 242, 117, 225, - 112, 231, 179, 231, 191, 2, 215, 98, 226, 212, 231, 190, 226, 212, 211, - 221, 252, 194, 249, 198, 211, 205, 224, 192, 235, 137, 226, 227, 235, - 137, 242, 176, 242, 229, 252, 195, 254, 121, 245, 26, 254, 169, 254, 170, - 230, 141, 236, 12, 219, 102, 235, 239, 248, 42, 225, 170, 242, 112, 248, - 187, 232, 207, 229, 216, 225, 1, 244, 199, 231, 147, 242, 40, 252, 146, - 225, 4, 217, 172, 225, 69, 234, 70, 79, 232, 117, 233, 16, 222, 236, 243, - 61, 218, 133, 234, 69, 251, 179, 249, 156, 2, 241, 234, 212, 19, 252, 77, - 241, 234, 251, 143, 241, 234, 113, 241, 232, 219, 12, 241, 234, 242, 127, - 241, 234, 241, 235, 2, 75, 251, 216, 241, 234, 242, 134, 241, 234, 211, - 42, 241, 234, 224, 131, 241, 234, 241, 235, 2, 223, 36, 223, 47, 241, - 232, 241, 235, 248, 89, 248, 1, 220, 84, 2, 116, 59, 235, 222, 245, 180, - 193, 251, 124, 254, 120, 87, 251, 203, 219, 94, 87, 249, 236, 87, 218, - 248, 217, 249, 87, 246, 93, 248, 165, 87, 225, 70, 64, 224, 252, 244, 69, - 252, 11, 247, 173, 87, 219, 5, 252, 166, 216, 150, 252, 166, 71, 244, 59, - 240, 218, 225, 8, 87, 230, 154, 252, 180, 249, 106, 245, 40, 114, 247, - 140, 50, 249, 147, 250, 250, 252, 152, 2, 211, 40, 50, 252, 152, 2, 247, - 140, 50, 252, 152, 2, 245, 55, 50, 252, 152, 2, 224, 231, 50, 230, 154, - 2, 211, 235, 250, 146, 2, 214, 153, 215, 232, 22, 211, 40, 50, 221, 180, - 225, 169, 249, 216, 251, 147, 230, 191, 244, 64, 247, 193, 226, 165, 247, - 198, 246, 57, 244, 115, 244, 48, 204, 244, 115, 244, 48, 226, 80, 2, 249, - 108, 226, 80, 244, 191, 214, 163, 251, 24, 217, 19, 251, 24, 250, 251, - 235, 249, 250, 146, 2, 214, 153, 215, 231, 250, 146, 2, 246, 112, 215, - 231, 252, 149, 250, 145, 250, 14, 224, 126, 222, 187, 224, 126, 226, 23, - 218, 123, 222, 133, 215, 223, 222, 133, 251, 199, 217, 92, 233, 57, 228, - 50, 228, 51, 2, 248, 88, 249, 155, 250, 8, 251, 200, 204, 251, 200, 242, - 134, 251, 200, 251, 216, 251, 200, 226, 161, 251, 200, 251, 197, 229, - 210, 252, 183, 221, 188, 231, 65, 217, 2, 223, 126, 226, 78, 244, 167, - 231, 239, 221, 225, 254, 97, 224, 148, 255, 5, 232, 119, 250, 135, 231, - 77, 226, 133, 215, 239, 236, 3, 215, 239, 226, 86, 246, 32, 87, 236, 0, - 245, 127, 245, 128, 2, 246, 112, 80, 48, 250, 8, 231, 205, 2, 232, 113, - 244, 81, 250, 8, 231, 205, 2, 223, 160, 244, 81, 204, 231, 205, 2, 223, - 160, 244, 81, 204, 231, 205, 2, 232, 113, 244, 81, 224, 239, 224, 240, - 240, 255, 229, 89, 230, 164, 225, 120, 230, 164, 225, 121, 2, 97, 80, - 253, 215, 233, 52, 213, 175, 230, 163, 230, 164, 225, 121, 226, 234, 228, - 80, 230, 164, 225, 119, 254, 98, 2, 252, 137, 251, 18, 213, 172, 251, 18, - 216, 255, 223, 176, 213, 171, 215, 60, 97, 253, 255, 250, 10, 97, 22, - 140, 204, 250, 44, 253, 255, 250, 10, 97, 22, 140, 204, 250, 44, 254, 0, - 2, 37, 123, 226, 124, 250, 10, 246, 112, 22, 214, 153, 204, 250, 44, 253, - 255, 254, 96, 246, 112, 22, 214, 153, 204, 250, 44, 253, 255, 121, 251, - 146, 87, 125, 251, 146, 87, 219, 9, 2, 251, 12, 91, 219, 8, 219, 9, 2, - 123, 219, 33, 212, 35, 219, 9, 2, 134, 219, 33, 212, 34, 252, 123, 245, - 180, 225, 30, 233, 48, 231, 216, 242, 191, 222, 250, 231, 216, 242, 191, - 232, 158, 2, 235, 232, 225, 202, 250, 8, 232, 158, 2, 234, 144, 234, 144, - 232, 157, 204, 232, 157, 252, 52, 252, 53, 2, 251, 12, 91, 251, 198, 232, - 210, 87, 223, 177, 251, 94, 252, 193, 2, 140, 80, 48, 245, 151, 2, 140, - 80, 48, 226, 201, 2, 245, 39, 164, 2, 43, 44, 80, 48, 219, 41, 2, 97, 80, - 48, 216, 15, 2, 214, 153, 80, 48, 228, 80, 123, 214, 184, 245, 199, 87, - 234, 142, 216, 248, 235, 226, 16, 31, 7, 6, 233, 15, 235, 226, 16, 31, 7, - 4, 233, 15, 235, 226, 16, 31, 227, 203, 235, 226, 16, 31, 217, 184, 235, - 226, 16, 31, 7, 233, 15, 244, 104, 245, 180, 216, 10, 211, 199, 242, 28, - 227, 186, 22, 251, 205, 241, 73, 225, 53, 230, 231, 217, 0, 249, 122, - 252, 167, 219, 127, 225, 12, 218, 159, 2, 230, 229, 247, 128, 235, 137, - 16, 31, 252, 65, 215, 221, 245, 164, 85, 42, 251, 94, 71, 42, 251, 94, - 233, 91, 223, 114, 250, 43, 233, 91, 251, 216, 250, 43, 233, 91, 226, - 161, 248, 0, 233, 91, 251, 216, 248, 0, 4, 226, 161, 248, 0, 4, 251, 216, - 248, 0, 214, 162, 223, 114, 215, 226, 246, 113, 223, 114, 215, 226, 214, - 162, 4, 223, 114, 215, 226, 246, 113, 4, 223, 114, 215, 226, 37, 249, - 139, 224, 255, 249, 139, 225, 0, 2, 242, 33, 51, 249, 139, 224, 255, 228, - 54, 43, 220, 155, 2, 134, 247, 126, 250, 12, 244, 199, 123, 226, 246, - 250, 12, 244, 199, 113, 226, 246, 250, 12, 244, 199, 134, 226, 246, 250, - 12, 244, 199, 244, 19, 226, 246, 250, 12, 244, 199, 244, 89, 226, 246, - 250, 12, 244, 199, 219, 127, 226, 246, 250, 12, 244, 199, 220, 124, 226, - 246, 250, 12, 244, 199, 245, 201, 226, 246, 250, 12, 244, 199, 228, 205, - 226, 246, 250, 12, 244, 199, 216, 249, 226, 246, 250, 12, 244, 199, 245, - 176, 226, 246, 250, 12, 244, 199, 215, 77, 226, 246, 250, 12, 244, 199, - 226, 196, 250, 12, 244, 199, 215, 56, 250, 12, 244, 199, 216, 141, 250, - 12, 244, 199, 244, 15, 250, 12, 244, 199, 244, 87, 250, 12, 244, 199, - 219, 123, 250, 12, 244, 199, 220, 123, 250, 12, 244, 199, 245, 200, 250, - 12, 244, 199, 228, 204, 250, 12, 244, 199, 216, 247, 250, 12, 244, 199, - 245, 174, 250, 12, 244, 199, 215, 75, 230, 122, 243, 237, 216, 37, 216, - 3, 218, 150, 64, 232, 245, 219, 172, 64, 235, 138, 230, 111, 242, 131, - 244, 198, 242, 131, 244, 199, 2, 219, 76, 245, 21, 244, 199, 2, 217, 15, - 64, 235, 59, 219, 76, 244, 199, 2, 204, 230, 115, 219, 76, 244, 199, 2, - 204, 230, 116, 22, 219, 76, 245, 21, 219, 76, 244, 199, 2, 204, 230, 116, - 22, 249, 238, 217, 248, 219, 76, 244, 199, 2, 204, 230, 116, 22, 216, - 105, 245, 21, 219, 76, 244, 199, 2, 242, 32, 219, 76, 244, 199, 2, 240, - 254, 211, 233, 244, 198, 219, 76, 244, 199, 2, 219, 76, 245, 21, 244, - 199, 221, 219, 248, 70, 244, 41, 223, 91, 244, 198, 219, 76, 244, 199, 2, - 241, 233, 245, 21, 219, 76, 244, 199, 2, 218, 35, 219, 75, 244, 198, 229, - 92, 244, 198, 245, 31, 244, 198, 214, 188, 244, 198, 244, 199, 2, 249, - 238, 217, 248, 225, 195, 244, 198, 249, 209, 244, 198, 249, 210, 244, - 198, 234, 68, 244, 198, 244, 199, 216, 138, 116, 234, 69, 234, 68, 244, - 199, 2, 219, 76, 245, 21, 234, 68, 244, 199, 2, 250, 8, 245, 21, 244, - 199, 2, 218, 89, 216, 20, 244, 199, 2, 218, 89, 216, 21, 22, 211, 233, - 245, 23, 244, 199, 2, 218, 89, 216, 21, 22, 216, 105, 245, 21, 247, 200, - 244, 198, 211, 204, 244, 198, 254, 116, 244, 198, 224, 230, 244, 198, - 249, 124, 244, 198, 225, 173, 244, 198, 244, 199, 2, 232, 132, 64, 215, - 205, 247, 200, 251, 96, 223, 91, 244, 198, 243, 247, 244, 199, 2, 204, - 230, 115, 254, 114, 244, 198, 244, 160, 244, 198, 212, 20, 244, 198, 219, - 93, 244, 198, 216, 72, 244, 198, 242, 132, 244, 198, 232, 120, 249, 124, - 244, 198, 244, 199, 2, 204, 230, 115, 240, 210, 244, 198, 244, 199, 2, - 204, 230, 116, 22, 249, 238, 217, 248, 244, 199, 221, 192, 236, 7, 244, - 161, 253, 221, 244, 198, 244, 57, 244, 198, 219, 94, 244, 198, 247, 173, - 244, 198, 244, 199, 211, 230, 230, 115, 244, 199, 2, 231, 89, 231, 149, - 242, 131, 250, 233, 244, 199, 2, 219, 76, 245, 21, 250, 233, 244, 199, 2, - 217, 15, 64, 235, 59, 219, 76, 250, 233, 244, 199, 2, 204, 230, 115, 219, - 76, 250, 233, 244, 199, 2, 241, 233, 245, 21, 250, 233, 244, 199, 2, 211, - 196, 219, 77, 234, 68, 250, 233, 244, 199, 2, 250, 8, 245, 21, 224, 230, - 250, 233, 244, 198, 249, 124, 250, 233, 244, 198, 212, 20, 250, 233, 244, - 198, 244, 199, 2, 228, 80, 242, 170, 243, 41, 244, 199, 2, 226, 219, 243, - 41, 225, 171, 251, 176, 248, 83, 221, 171, 230, 150, 241, 236, 230, 150, - 219, 10, 230, 150, 242, 12, 225, 171, 223, 159, 123, 242, 22, 225, 171, - 223, 159, 251, 186, 242, 18, 236, 7, 250, 187, 225, 171, 243, 246, 225, - 171, 2, 224, 230, 244, 198, 225, 171, 2, 244, 49, 242, 17, 222, 205, 241, - 221, 218, 145, 232, 155, 223, 165, 250, 252, 241, 169, 215, 249, 241, - 169, 215, 250, 2, 251, 122, 228, 58, 215, 249, 231, 37, 193, 223, 166, - 218, 151, 215, 247, 215, 248, 250, 252, 251, 100, 226, 198, 251, 100, - 215, 202, 251, 101, 218, 131, 230, 192, 254, 138, 244, 105, 245, 145, - 225, 2, 250, 252, 226, 198, 225, 2, 250, 252, 217, 33, 226, 198, 217, 33, - 253, 188, 226, 198, 253, 188, 223, 121, 213, 247, 248, 66, 215, 193, 253, - 250, 232, 123, 215, 255, 230, 144, 230, 121, 223, 164, 218, 7, 223, 164, - 230, 121, 251, 36, 254, 238, 215, 246, 220, 18, 222, 184, 219, 3, 203, - 215, 253, 232, 236, 67, 215, 253, 232, 236, 249, 198, 50, 225, 2, 250, - 237, 223, 47, 232, 236, 215, 223, 244, 82, 226, 201, 224, 241, 247, 131, - 228, 80, 245, 133, 50, 219, 74, 87, 228, 80, 219, 74, 87, 224, 125, 232, - 199, 236, 7, 235, 163, 225, 44, 87, 247, 154, 228, 57, 232, 199, 87, 224, - 235, 212, 41, 87, 228, 71, 212, 41, 87, 252, 10, 228, 80, 252, 9, 252, 8, - 230, 121, 252, 8, 225, 216, 228, 80, 225, 215, 250, 108, 249, 132, 231, - 61, 87, 211, 218, 87, 223, 62, 252, 195, 87, 216, 38, 212, 41, 250, 5, - 219, 236, 252, 126, 252, 124, 225, 246, 249, 185, 249, 94, 252, 177, 250, - 30, 43, 232, 95, 108, 16, 31, 224, 6, 108, 16, 31, 254, 201, 108, 16, 31, - 244, 104, 108, 16, 31, 245, 231, 108, 16, 31, 212, 40, 108, 16, 31, 254, - 51, 108, 16, 31, 254, 52, 223, 108, 108, 16, 31, 254, 52, 223, 107, 108, - 16, 31, 254, 52, 213, 143, 108, 16, 31, 254, 52, 213, 142, 108, 16, 31, - 213, 157, 108, 16, 31, 213, 156, 108, 16, 31, 213, 155, 108, 16, 31, 218, - 45, 108, 16, 31, 225, 128, 218, 45, 108, 16, 31, 85, 218, 45, 108, 16, - 31, 231, 60, 218, 72, 108, 16, 31, 231, 60, 218, 71, 108, 16, 31, 231, - 60, 218, 70, 108, 16, 31, 250, 46, 108, 16, 31, 222, 3, 108, 16, 31, 228, - 193, 108, 16, 31, 213, 141, 108, 16, 31, 213, 140, 108, 16, 31, 222, 206, - 222, 3, 108, 16, 31, 222, 206, 222, 2, 108, 16, 31, 242, 173, 108, 16, - 31, 219, 168, 108, 16, 31, 235, 184, 226, 157, 108, 16, 31, 235, 184, - 226, 156, 108, 16, 31, 249, 142, 64, 235, 183, 108, 16, 31, 223, 104, 64, - 235, 183, 108, 16, 31, 249, 176, 226, 157, 108, 16, 31, 235, 182, 226, - 157, 108, 16, 31, 218, 73, 64, 249, 175, 108, 16, 31, 249, 142, 64, 249, - 175, 108, 16, 31, 249, 142, 64, 249, 174, 108, 16, 31, 249, 176, 254, 91, - 108, 16, 31, 222, 4, 64, 249, 176, 254, 91, 108, 16, 31, 218, 73, 64, - 222, 4, 64, 249, 175, 108, 16, 31, 213, 243, 108, 16, 31, 216, 85, 226, - 157, 108, 16, 31, 233, 63, 226, 157, 108, 16, 31, 254, 90, 226, 157, 108, - 16, 31, 218, 73, 64, 254, 89, 108, 16, 31, 222, 4, 64, 254, 89, 108, 16, - 31, 218, 73, 64, 222, 4, 64, 254, 89, 108, 16, 31, 213, 158, 64, 254, 89, - 108, 16, 31, 223, 104, 64, 254, 89, 108, 16, 31, 223, 104, 64, 254, 88, - 108, 16, 31, 223, 103, 108, 16, 31, 223, 102, 108, 16, 31, 223, 101, 108, - 16, 31, 223, 100, 108, 16, 31, 254, 166, 108, 16, 31, 254, 165, 108, 16, - 31, 231, 168, 108, 16, 31, 222, 9, 108, 16, 31, 253, 254, 108, 16, 31, - 223, 128, 108, 16, 31, 223, 127, 108, 16, 31, 253, 191, 108, 16, 31, 251, - 237, 226, 157, 108, 16, 31, 217, 50, 108, 16, 31, 217, 49, 108, 16, 31, - 224, 11, 232, 228, 108, 16, 31, 251, 191, 108, 16, 31, 251, 190, 108, 16, - 31, 251, 189, 108, 16, 31, 254, 146, 108, 16, 31, 226, 222, 108, 16, 31, - 218, 250, 108, 16, 31, 216, 83, 108, 16, 31, 242, 103, 108, 16, 31, 212, - 28, 108, 16, 31, 224, 229, 108, 16, 31, 251, 22, 108, 16, 31, 215, 86, - 108, 16, 31, 250, 254, 230, 127, 108, 16, 31, 221, 204, 64, 235, 61, 108, - 16, 31, 251, 33, 108, 16, 31, 215, 220, 108, 16, 31, 218, 156, 215, 220, - 108, 16, 31, 232, 154, 108, 16, 31, 219, 58, 108, 16, 31, 214, 142, 108, - 16, 31, 240, 253, 246, 72, 108, 16, 31, 253, 235, 108, 16, 31, 224, 237, - 253, 235, 108, 16, 31, 251, 150, 108, 16, 31, 224, 228, 251, 150, 108, - 16, 31, 254, 143, 108, 16, 31, 218, 119, 218, 27, 218, 118, 108, 16, 31, - 218, 119, 218, 27, 218, 117, 108, 16, 31, 218, 69, 108, 16, 31, 224, 203, - 108, 16, 31, 247, 189, 108, 16, 31, 247, 191, 108, 16, 31, 247, 190, 108, - 16, 31, 224, 134, 108, 16, 31, 224, 123, 108, 16, 31, 249, 130, 108, 16, - 31, 249, 129, 108, 16, 31, 249, 128, 108, 16, 31, 249, 127, 108, 16, 31, - 249, 126, 108, 16, 31, 254, 178, 108, 16, 31, 252, 127, 64, 231, 154, - 108, 16, 31, 252, 127, 64, 214, 17, 108, 16, 31, 223, 60, 108, 16, 31, - 240, 245, 108, 16, 31, 228, 217, 108, 16, 31, 248, 153, 108, 16, 31, 230, - 139, 108, 16, 31, 163, 246, 102, 108, 16, 31, 163, 226, 136, 10, 14, 240, - 109, 10, 14, 240, 108, 10, 14, 240, 107, 10, 14, 240, 106, 10, 14, 240, - 105, 10, 14, 240, 104, 10, 14, 240, 103, 10, 14, 240, 102, 10, 14, 240, - 101, 10, 14, 240, 100, 10, 14, 240, 99, 10, 14, 240, 98, 10, 14, 240, 97, - 10, 14, 240, 96, 10, 14, 240, 95, 10, 14, 240, 94, 10, 14, 240, 93, 10, - 14, 240, 92, 10, 14, 240, 91, 10, 14, 240, 90, 10, 14, 240, 89, 10, 14, - 240, 88, 10, 14, 240, 87, 10, 14, 240, 86, 10, 14, 240, 85, 10, 14, 240, - 84, 10, 14, 240, 83, 10, 14, 240, 82, 10, 14, 240, 81, 10, 14, 240, 80, - 10, 14, 240, 79, 10, 14, 240, 78, 10, 14, 240, 77, 10, 14, 240, 76, 10, - 14, 240, 75, 10, 14, 240, 74, 10, 14, 240, 73, 10, 14, 240, 72, 10, 14, - 240, 71, 10, 14, 240, 70, 10, 14, 240, 69, 10, 14, 240, 68, 10, 14, 240, - 67, 10, 14, 240, 66, 10, 14, 240, 65, 10, 14, 240, 64, 10, 14, 240, 63, - 10, 14, 240, 62, 10, 14, 240, 61, 10, 14, 240, 60, 10, 14, 240, 59, 10, - 14, 240, 58, 10, 14, 240, 57, 10, 14, 240, 56, 10, 14, 240, 55, 10, 14, - 240, 54, 10, 14, 240, 53, 10, 14, 240, 52, 10, 14, 240, 51, 10, 14, 240, - 50, 10, 14, 240, 49, 10, 14, 240, 48, 10, 14, 240, 47, 10, 14, 240, 46, - 10, 14, 240, 45, 10, 14, 240, 44, 10, 14, 240, 43, 10, 14, 240, 42, 10, - 14, 240, 41, 10, 14, 240, 40, 10, 14, 240, 39, 10, 14, 240, 38, 10, 14, - 240, 37, 10, 14, 240, 36, 10, 14, 240, 35, 10, 14, 240, 34, 10, 14, 240, - 33, 10, 14, 240, 32, 10, 14, 240, 31, 10, 14, 240, 30, 10, 14, 240, 29, - 10, 14, 240, 28, 10, 14, 240, 27, 10, 14, 240, 26, 10, 14, 240, 25, 10, - 14, 240, 24, 10, 14, 240, 23, 10, 14, 240, 22, 10, 14, 240, 21, 10, 14, - 240, 20, 10, 14, 240, 19, 10, 14, 240, 18, 10, 14, 240, 17, 10, 14, 240, - 16, 10, 14, 240, 15, 10, 14, 240, 14, 10, 14, 240, 13, 10, 14, 240, 12, - 10, 14, 240, 11, 10, 14, 240, 10, 10, 14, 240, 9, 10, 14, 240, 8, 10, 14, - 240, 7, 10, 14, 240, 6, 10, 14, 240, 5, 10, 14, 240, 4, 10, 14, 240, 3, - 10, 14, 240, 2, 10, 14, 240, 1, 10, 14, 240, 0, 10, 14, 239, 255, 10, 14, - 239, 254, 10, 14, 239, 253, 10, 14, 239, 252, 10, 14, 239, 251, 10, 14, - 239, 250, 10, 14, 239, 249, 10, 14, 239, 248, 10, 14, 239, 247, 10, 14, - 239, 246, 10, 14, 239, 245, 10, 14, 239, 244, 10, 14, 239, 243, 10, 14, - 239, 242, 10, 14, 239, 241, 10, 14, 239, 240, 10, 14, 239, 239, 10, 14, - 239, 238, 10, 14, 239, 237, 10, 14, 239, 236, 10, 14, 239, 235, 10, 14, - 239, 234, 10, 14, 239, 233, 10, 14, 239, 232, 10, 14, 239, 231, 10, 14, - 239, 230, 10, 14, 239, 229, 10, 14, 239, 228, 10, 14, 239, 227, 10, 14, - 239, 226, 10, 14, 239, 225, 10, 14, 239, 224, 10, 14, 239, 223, 10, 14, - 239, 222, 10, 14, 239, 221, 10, 14, 239, 220, 10, 14, 239, 219, 10, 14, - 239, 218, 10, 14, 239, 217, 10, 14, 239, 216, 10, 14, 239, 215, 10, 14, - 239, 214, 10, 14, 239, 213, 10, 14, 239, 212, 10, 14, 239, 211, 10, 14, - 239, 210, 10, 14, 239, 209, 10, 14, 239, 208, 10, 14, 239, 207, 10, 14, - 239, 206, 10, 14, 239, 205, 10, 14, 239, 204, 10, 14, 239, 203, 10, 14, - 239, 202, 10, 14, 239, 201, 10, 14, 239, 200, 10, 14, 239, 199, 10, 14, - 239, 198, 10, 14, 239, 197, 10, 14, 239, 196, 10, 14, 239, 195, 10, 14, - 239, 194, 10, 14, 239, 193, 10, 14, 239, 192, 10, 14, 239, 191, 10, 14, - 239, 190, 10, 14, 239, 189, 10, 14, 239, 188, 10, 14, 239, 187, 10, 14, - 239, 186, 10, 14, 239, 185, 10, 14, 239, 184, 10, 14, 239, 183, 10, 14, - 239, 182, 10, 14, 239, 181, 10, 14, 239, 180, 10, 14, 239, 179, 10, 14, - 239, 178, 10, 14, 239, 177, 10, 14, 239, 176, 10, 14, 239, 175, 10, 14, - 239, 174, 10, 14, 239, 173, 10, 14, 239, 172, 10, 14, 239, 171, 10, 14, - 239, 170, 10, 14, 239, 169, 10, 14, 239, 168, 10, 14, 239, 167, 10, 14, - 239, 166, 10, 14, 239, 165, 10, 14, 239, 164, 10, 14, 239, 163, 10, 14, - 239, 162, 10, 14, 239, 161, 10, 14, 239, 160, 10, 14, 239, 159, 10, 14, - 239, 158, 10, 14, 239, 157, 10, 14, 239, 156, 10, 14, 239, 155, 10, 14, - 239, 154, 10, 14, 239, 153, 10, 14, 239, 152, 10, 14, 239, 151, 10, 14, - 239, 150, 10, 14, 239, 149, 10, 14, 239, 148, 10, 14, 239, 147, 10, 14, - 239, 146, 10, 14, 239, 145, 10, 14, 239, 144, 10, 14, 239, 143, 10, 14, - 239, 142, 10, 14, 239, 141, 10, 14, 239, 140, 10, 14, 239, 139, 10, 14, - 239, 138, 10, 14, 239, 137, 10, 14, 239, 136, 10, 14, 239, 135, 10, 14, - 239, 134, 10, 14, 239, 133, 10, 14, 239, 132, 10, 14, 239, 131, 10, 14, - 239, 130, 10, 14, 239, 129, 10, 14, 239, 128, 10, 14, 239, 127, 10, 14, - 239, 126, 10, 14, 239, 125, 10, 14, 239, 124, 10, 14, 239, 123, 10, 14, - 239, 122, 10, 14, 239, 121, 10, 14, 239, 120, 10, 14, 239, 119, 10, 14, - 239, 118, 10, 14, 239, 117, 10, 14, 239, 116, 10, 14, 239, 115, 10, 14, - 239, 114, 10, 14, 239, 113, 10, 14, 239, 112, 10, 14, 239, 111, 10, 14, - 239, 110, 10, 14, 239, 109, 10, 14, 239, 108, 10, 14, 239, 107, 10, 14, - 239, 106, 10, 14, 239, 105, 10, 14, 239, 104, 10, 14, 239, 103, 10, 14, - 239, 102, 10, 14, 239, 101, 10, 14, 239, 100, 10, 14, 239, 99, 10, 14, - 239, 98, 10, 14, 239, 97, 10, 14, 239, 96, 10, 14, 239, 95, 10, 14, 239, - 94, 10, 14, 239, 93, 10, 14, 239, 92, 10, 14, 239, 91, 10, 14, 239, 90, - 10, 14, 239, 89, 10, 14, 239, 88, 10, 14, 239, 87, 10, 14, 239, 86, 10, - 14, 239, 85, 10, 14, 239, 84, 10, 14, 239, 83, 10, 14, 239, 82, 10, 14, - 239, 81, 10, 14, 239, 80, 10, 14, 239, 79, 10, 14, 239, 78, 10, 14, 239, - 77, 10, 14, 239, 76, 10, 14, 239, 75, 10, 14, 239, 74, 10, 14, 239, 73, - 10, 14, 239, 72, 10, 14, 239, 71, 10, 14, 239, 70, 10, 14, 239, 69, 10, - 14, 239, 68, 10, 14, 239, 67, 10, 14, 239, 66, 10, 14, 239, 65, 10, 14, - 239, 64, 10, 14, 239, 63, 10, 14, 239, 62, 10, 14, 239, 61, 10, 14, 239, - 60, 10, 14, 239, 59, 10, 14, 239, 58, 10, 14, 239, 57, 10, 14, 239, 56, - 10, 14, 239, 55, 10, 14, 239, 54, 10, 14, 239, 53, 10, 14, 239, 52, 10, - 14, 239, 51, 10, 14, 239, 50, 10, 14, 239, 49, 10, 14, 239, 48, 10, 14, - 239, 47, 10, 14, 239, 46, 10, 14, 239, 45, 10, 14, 239, 44, 10, 14, 239, - 43, 10, 14, 239, 42, 10, 14, 239, 41, 10, 14, 239, 40, 10, 14, 239, 39, - 10, 14, 239, 38, 10, 14, 239, 37, 10, 14, 239, 36, 10, 14, 239, 35, 10, - 14, 239, 34, 10, 14, 239, 33, 10, 14, 239, 32, 10, 14, 239, 31, 10, 14, - 239, 30, 10, 14, 239, 29, 10, 14, 239, 28, 10, 14, 239, 27, 10, 14, 239, - 26, 10, 14, 239, 25, 10, 14, 239, 24, 10, 14, 239, 23, 10, 14, 239, 22, - 10, 14, 239, 21, 10, 14, 239, 20, 10, 14, 239, 19, 10, 14, 239, 18, 10, - 14, 239, 17, 10, 14, 239, 16, 10, 14, 239, 15, 10, 14, 239, 14, 10, 14, - 239, 13, 10, 14, 239, 12, 10, 14, 239, 11, 10, 14, 239, 10, 10, 14, 239, - 9, 10, 14, 239, 8, 10, 14, 239, 7, 10, 14, 239, 6, 10, 14, 239, 5, 10, - 14, 239, 4, 10, 14, 239, 3, 10, 14, 239, 2, 10, 14, 239, 1, 10, 14, 239, - 0, 10, 14, 238, 255, 10, 14, 238, 254, 10, 14, 238, 253, 10, 14, 238, - 252, 10, 14, 238, 251, 10, 14, 238, 250, 10, 14, 238, 249, 10, 14, 238, - 248, 10, 14, 238, 247, 10, 14, 238, 246, 10, 14, 238, 245, 10, 14, 238, - 244, 10, 14, 238, 243, 10, 14, 238, 242, 10, 14, 238, 241, 10, 14, 238, - 240, 10, 14, 238, 239, 10, 14, 238, 238, 10, 14, 238, 237, 10, 14, 238, - 236, 10, 14, 238, 235, 10, 14, 238, 234, 10, 14, 238, 233, 10, 14, 238, - 232, 10, 14, 238, 231, 10, 14, 238, 230, 10, 14, 238, 229, 10, 14, 238, - 228, 10, 14, 238, 227, 10, 14, 238, 226, 10, 14, 238, 225, 10, 14, 238, - 224, 10, 14, 238, 223, 10, 14, 238, 222, 10, 14, 238, 221, 10, 14, 238, - 220, 10, 14, 238, 219, 10, 14, 238, 218, 10, 14, 238, 217, 10, 14, 238, - 216, 10, 14, 238, 215, 10, 14, 238, 214, 10, 14, 238, 213, 10, 14, 238, - 212, 10, 14, 238, 211, 10, 14, 238, 210, 10, 14, 238, 209, 10, 14, 238, - 208, 10, 14, 238, 207, 10, 14, 238, 206, 10, 14, 238, 205, 10, 14, 238, - 204, 10, 14, 238, 203, 10, 14, 238, 202, 10, 14, 238, 201, 10, 14, 238, - 200, 10, 14, 238, 199, 10, 14, 238, 198, 10, 14, 238, 197, 10, 14, 238, - 196, 10, 14, 238, 195, 10, 14, 238, 194, 10, 14, 238, 193, 10, 14, 238, - 192, 10, 14, 238, 191, 10, 14, 238, 190, 10, 14, 238, 189, 10, 14, 238, - 188, 10, 14, 238, 187, 10, 14, 238, 186, 10, 14, 238, 185, 10, 14, 238, - 184, 10, 14, 238, 183, 10, 14, 238, 182, 10, 14, 238, 181, 10, 14, 238, - 180, 10, 14, 238, 179, 10, 14, 238, 178, 10, 14, 238, 177, 10, 14, 238, - 176, 10, 14, 238, 175, 10, 14, 238, 174, 10, 14, 238, 173, 10, 14, 238, - 172, 10, 14, 238, 171, 10, 14, 238, 170, 10, 14, 238, 169, 10, 14, 238, - 168, 10, 14, 238, 167, 10, 14, 238, 166, 10, 14, 238, 165, 10, 14, 238, - 164, 10, 14, 238, 163, 10, 14, 238, 162, 10, 14, 238, 161, 10, 14, 238, - 160, 10, 14, 238, 159, 10, 14, 238, 158, 10, 14, 238, 157, 10, 14, 238, - 156, 10, 14, 238, 155, 10, 14, 238, 154, 10, 14, 238, 153, 10, 14, 238, - 152, 10, 14, 238, 151, 10, 14, 238, 150, 10, 14, 238, 149, 10, 14, 238, - 148, 10, 14, 238, 147, 10, 14, 238, 146, 10, 14, 238, 145, 10, 14, 238, - 144, 10, 14, 238, 143, 10, 14, 238, 142, 10, 14, 238, 141, 10, 14, 238, - 140, 10, 14, 238, 139, 10, 14, 238, 138, 10, 14, 238, 137, 10, 14, 238, - 136, 10, 14, 238, 135, 10, 14, 238, 134, 10, 14, 238, 133, 10, 14, 238, - 132, 10, 14, 238, 131, 10, 14, 238, 130, 10, 14, 238, 129, 10, 14, 238, - 128, 10, 14, 238, 127, 10, 14, 238, 126, 10, 14, 238, 125, 10, 14, 238, - 124, 10, 14, 238, 123, 10, 14, 238, 122, 10, 14, 238, 121, 10, 14, 238, - 120, 10, 14, 238, 119, 10, 14, 238, 118, 10, 14, 238, 117, 10, 14, 238, - 116, 10, 14, 238, 115, 10, 14, 238, 114, 10, 14, 238, 113, 10, 14, 238, - 112, 10, 14, 238, 111, 10, 14, 238, 110, 10, 14, 238, 109, 10, 14, 238, - 108, 10, 14, 238, 107, 10, 14, 238, 106, 10, 14, 238, 105, 10, 14, 238, - 104, 10, 14, 238, 103, 10, 14, 238, 102, 10, 14, 238, 101, 10, 14, 238, - 100, 10, 14, 238, 99, 10, 14, 238, 98, 10, 14, 238, 97, 10, 14, 238, 96, - 10, 14, 238, 95, 10, 14, 238, 94, 10, 14, 238, 93, 10, 14, 238, 92, 10, - 14, 238, 91, 10, 14, 238, 90, 10, 14, 238, 89, 10, 14, 238, 88, 10, 14, - 238, 87, 10, 14, 238, 86, 10, 14, 238, 85, 10, 14, 238, 84, 10, 14, 238, - 83, 10, 14, 238, 82, 10, 14, 238, 81, 10, 14, 238, 80, 233, 96, 217, 85, - 129, 219, 20, 129, 245, 39, 79, 129, 224, 1, 79, 129, 54, 50, 129, 247, - 140, 50, 129, 225, 185, 50, 129, 254, 134, 129, 254, 65, 129, 43, 226, 7, - 129, 44, 226, 7, 129, 253, 224, 129, 96, 50, 129, 249, 227, 129, 240, - 174, 129, 243, 236, 218, 131, 129, 219, 48, 129, 21, 210, 86, 129, 21, - 111, 129, 21, 105, 129, 21, 158, 129, 21, 161, 129, 21, 190, 129, 21, - 195, 129, 21, 199, 129, 21, 196, 129, 21, 201, 129, 249, 234, 129, 220, - 152, 129, 233, 21, 50, 129, 245, 106, 50, 129, 242, 137, 50, 129, 224, - 16, 79, 129, 249, 225, 253, 214, 129, 7, 6, 1, 61, 129, 7, 6, 1, 253, - 166, 129, 7, 6, 1, 251, 74, 129, 7, 6, 1, 249, 68, 129, 7, 6, 1, 76, 129, - 7, 6, 1, 245, 14, 129, 7, 6, 1, 243, 209, 129, 7, 6, 1, 242, 67, 129, 7, - 6, 1, 74, 129, 7, 6, 1, 235, 150, 129, 7, 6, 1, 235, 29, 129, 7, 6, 1, - 156, 129, 7, 6, 1, 194, 129, 7, 6, 1, 230, 30, 129, 7, 6, 1, 78, 129, 7, - 6, 1, 226, 109, 129, 7, 6, 1, 224, 99, 129, 7, 6, 1, 153, 129, 7, 6, 1, - 222, 93, 129, 7, 6, 1, 217, 153, 129, 7, 6, 1, 69, 129, 7, 6, 1, 214, - 105, 129, 7, 6, 1, 212, 98, 129, 7, 6, 1, 211, 178, 129, 7, 6, 1, 211, - 117, 129, 7, 6, 1, 210, 159, 129, 43, 42, 127, 129, 223, 53, 219, 48, - 129, 44, 42, 127, 129, 250, 39, 255, 23, 129, 121, 232, 219, 129, 242, - 144, 255, 23, 129, 7, 4, 1, 61, 129, 7, 4, 1, 253, 166, 129, 7, 4, 1, - 251, 74, 129, 7, 4, 1, 249, 68, 129, 7, 4, 1, 76, 129, 7, 4, 1, 245, 14, - 129, 7, 4, 1, 243, 209, 129, 7, 4, 1, 242, 67, 129, 7, 4, 1, 74, 129, 7, - 4, 1, 235, 150, 129, 7, 4, 1, 235, 29, 129, 7, 4, 1, 156, 129, 7, 4, 1, - 194, 129, 7, 4, 1, 230, 30, 129, 7, 4, 1, 78, 129, 7, 4, 1, 226, 109, - 129, 7, 4, 1, 224, 99, 129, 7, 4, 1, 153, 129, 7, 4, 1, 222, 93, 129, 7, - 4, 1, 217, 153, 129, 7, 4, 1, 69, 129, 7, 4, 1, 214, 105, 129, 7, 4, 1, - 212, 98, 129, 7, 4, 1, 211, 178, 129, 7, 4, 1, 211, 117, 129, 7, 4, 1, - 210, 159, 129, 43, 249, 107, 127, 129, 67, 232, 219, 129, 44, 249, 107, - 127, 129, 184, 251, 14, 217, 85, 45, 221, 80, 45, 221, 69, 45, 221, 58, - 45, 221, 46, 45, 221, 35, 45, 221, 24, 45, 221, 13, 45, 221, 2, 45, 220, - 247, 45, 220, 239, 45, 220, 238, 45, 220, 237, 45, 220, 236, 45, 220, - 234, 45, 220, 233, 45, 220, 232, 45, 220, 231, 45, 220, 230, 45, 220, - 229, 45, 220, 228, 45, 220, 227, 45, 220, 226, 45, 220, 225, 45, 220, - 223, 45, 220, 222, 45, 220, 221, 45, 220, 220, 45, 220, 219, 45, 220, - 218, 45, 220, 217, 45, 220, 216, 45, 220, 215, 45, 220, 214, 45, 220, - 212, 45, 220, 211, 45, 220, 210, 45, 220, 209, 45, 220, 208, 45, 220, - 207, 45, 220, 206, 45, 220, 205, 45, 220, 204, 45, 220, 203, 45, 220, - 201, 45, 220, 200, 45, 220, 199, 45, 220, 198, 45, 220, 197, 45, 220, - 196, 45, 220, 195, 45, 220, 194, 45, 220, 193, 45, 220, 192, 45, 220, - 190, 45, 220, 189, 45, 220, 188, 45, 220, 187, 45, 220, 186, 45, 220, - 185, 45, 220, 184, 45, 220, 183, 45, 220, 182, 45, 220, 181, 45, 220, - 179, 45, 220, 178, 45, 220, 177, 45, 220, 176, 45, 220, 175, 45, 220, - 174, 45, 220, 173, 45, 220, 172, 45, 220, 171, 45, 220, 170, 45, 220, - 168, 45, 220, 167, 45, 220, 166, 45, 220, 165, 45, 220, 164, 45, 220, - 163, 45, 220, 162, 45, 220, 161, 45, 220, 160, 45, 220, 159, 45, 221, - 156, 45, 221, 155, 45, 221, 154, 45, 221, 153, 45, 221, 152, 45, 221, - 151, 45, 221, 150, 45, 221, 149, 45, 221, 148, 45, 221, 147, 45, 221, - 145, 45, 221, 144, 45, 221, 143, 45, 221, 142, 45, 221, 141, 45, 221, - 140, 45, 221, 139, 45, 221, 138, 45, 221, 137, 45, 221, 136, 45, 221, - 134, 45, 221, 133, 45, 221, 132, 45, 221, 131, 45, 221, 130, 45, 221, - 129, 45, 221, 128, 45, 221, 127, 45, 221, 126, 45, 221, 125, 45, 221, - 123, 45, 221, 122, 45, 221, 121, 45, 221, 120, 45, 221, 119, 45, 221, - 118, 45, 221, 117, 45, 221, 116, 45, 221, 115, 45, 221, 114, 45, 221, - 112, 45, 221, 111, 45, 221, 110, 45, 221, 109, 45, 221, 108, 45, 221, - 107, 45, 221, 106, 45, 221, 105, 45, 221, 104, 45, 221, 103, 45, 221, - 101, 45, 221, 100, 45, 221, 99, 45, 221, 98, 45, 221, 97, 45, 221, 96, - 45, 221, 95, 45, 221, 94, 45, 221, 93, 45, 221, 92, 45, 221, 90, 45, 221, - 89, 45, 221, 88, 45, 221, 87, 45, 221, 86, 45, 221, 85, 45, 221, 84, 45, - 221, 83, 45, 221, 82, 45, 221, 81, 45, 221, 79, 45, 221, 78, 45, 221, 77, - 45, 221, 76, 45, 221, 75, 45, 221, 74, 45, 221, 73, 45, 221, 72, 45, 221, - 71, 45, 221, 70, 45, 221, 68, 45, 221, 67, 45, 221, 66, 45, 221, 65, 45, - 221, 64, 45, 221, 63, 45, 221, 62, 45, 221, 61, 45, 221, 60, 45, 221, 59, - 45, 221, 57, 45, 221, 56, 45, 221, 55, 45, 221, 54, 45, 221, 53, 45, 221, - 52, 45, 221, 51, 45, 221, 50, 45, 221, 49, 45, 221, 48, 45, 221, 45, 45, - 221, 44, 45, 221, 43, 45, 221, 42, 45, 221, 41, 45, 221, 40, 45, 221, 39, - 45, 221, 38, 45, 221, 37, 45, 221, 36, 45, 221, 34, 45, 221, 33, 45, 221, - 32, 45, 221, 31, 45, 221, 30, 45, 221, 29, 45, 221, 28, 45, 221, 27, 45, - 221, 26, 45, 221, 25, 45, 221, 23, 45, 221, 22, 45, 221, 21, 45, 221, 20, - 45, 221, 19, 45, 221, 18, 45, 221, 17, 45, 221, 16, 45, 221, 15, 45, 221, - 14, 45, 221, 12, 45, 221, 11, 45, 221, 10, 45, 221, 9, 45, 221, 8, 45, - 221, 7, 45, 221, 6, 45, 221, 5, 45, 221, 4, 45, 221, 3, 45, 221, 1, 45, - 221, 0, 45, 220, 255, 45, 220, 254, 45, 220, 253, 45, 220, 252, 45, 220, - 251, 45, 220, 250, 45, 220, 249, 45, 220, 248, 45, 220, 246, 45, 220, - 245, 45, 220, 244, 45, 220, 243, 45, 220, 242, 45, 220, 241, 45, 220, - 240, 227, 206, 227, 208, 218, 154, 64, 241, 240, 219, 50, 218, 154, 64, - 216, 213, 218, 86, 245, 151, 64, 216, 213, 245, 64, 245, 151, 64, 215, - 244, 245, 117, 245, 140, 245, 141, 255, 16, 255, 17, 254, 176, 252, 55, - 252, 187, 251, 139, 135, 217, 90, 203, 217, 90, 240, 234, 217, 94, 232, - 220, 244, 153, 166, 232, 219, 245, 151, 64, 232, 219, 233, 6, 228, 140, - 245, 120, 232, 220, 217, 90, 67, 217, 90, 212, 118, 244, 28, 244, 153, - 244, 133, 250, 238, 223, 56, 249, 151, 220, 30, 226, 134, 232, 156, 111, - 219, 60, 220, 30, 236, 6, 232, 156, 210, 86, 219, 193, 248, 159, 232, - 210, 245, 85, 247, 163, 248, 39, 249, 186, 111, 248, 149, 248, 39, 249, - 186, 105, 248, 148, 248, 39, 249, 186, 158, 248, 147, 248, 39, 249, 186, - 161, 248, 146, 152, 255, 16, 229, 214, 217, 178, 236, 69, 217, 181, 245, - 151, 64, 215, 245, 251, 221, 245, 70, 251, 13, 251, 15, 245, 151, 64, - 231, 86, 245, 118, 218, 62, 218, 79, 245, 85, 245, 86, 235, 239, 220, - 140, 161, 244, 115, 220, 139, 243, 245, 235, 239, 220, 140, 158, 242, - 128, 220, 139, 242, 125, 235, 239, 220, 140, 105, 223, 124, 220, 139, - 222, 147, 235, 239, 220, 140, 111, 214, 174, 220, 139, 214, 133, 219, 23, - 248, 71, 248, 73, 226, 82, 250, 150, 226, 84, 125, 226, 244, 224, 196, - 241, 54, 251, 158, 225, 176, 241, 210, 251, 169, 228, 80, 251, 158, 241, - 210, 229, 180, 235, 249, 235, 251, 229, 87, 232, 219, 229, 104, 218, 154, - 64, 221, 160, 254, 26, 218, 225, 245, 151, 64, 221, 160, 254, 26, 245, - 88, 135, 217, 91, 220, 129, 203, 217, 91, 220, 129, 240, 231, 135, 217, - 91, 2, 235, 41, 203, 217, 91, 2, 235, 41, 240, 232, 232, 220, 217, 91, - 220, 129, 67, 217, 91, 220, 129, 212, 117, 226, 1, 232, 220, 244, 22, - 226, 1, 232, 220, 246, 114, 225, 35, 226, 1, 232, 220, 252, 186, 226, 1, - 232, 220, 214, 163, 225, 31, 223, 53, 232, 220, 244, 153, 223, 53, 235, - 249, 223, 38, 219, 157, 220, 30, 105, 219, 154, 218, 227, 219, 157, 220, - 30, 158, 219, 153, 218, 226, 248, 39, 249, 186, 218, 107, 248, 145, 224, - 186, 214, 132, 111, 224, 186, 214, 130, 224, 152, 224, 186, 214, 132, - 105, 224, 186, 214, 129, 224, 151, 220, 130, 215, 243, 218, 153, 218, 90, - 251, 14, 250, 150, 250, 217, 231, 48, 212, 59, 230, 48, 218, 154, 64, - 242, 114, 254, 26, 218, 154, 64, 224, 169, 254, 26, 219, 22, 245, 151, - 64, 242, 114, 254, 26, 245, 151, 64, 224, 169, 254, 26, 245, 115, 218, - 154, 64, 218, 107, 219, 37, 219, 157, 242, 148, 135, 235, 202, 220, 109, - 219, 157, 135, 235, 202, 221, 196, 249, 186, 220, 137, 235, 202, 249, - 121, 218, 108, 216, 237, 218, 170, 226, 173, 217, 168, 249, 226, 226, - 146, 224, 187, 231, 47, 225, 22, 254, 61, 224, 181, 249, 226, 254, 77, - 229, 168, 219, 202, 7, 6, 1, 243, 0, 7, 4, 1, 243, 0, 250, 167, 254, 157, - 183, 218, 68, 249, 235, 219, 108, 233, 52, 165, 1, 232, 181, 209, 209, 1, - 244, 52, 244, 44, 209, 209, 1, 244, 52, 244, 165, 209, 209, 1, 222, 213, - 209, 209, 1, 232, 162, 63, 164, 251, 231, 220, 5, 242, 222, 230, 253, - 223, 44, 243, 223, 243, 222, 243, 221, 230, 50, 209, 251, 209, 252, 209, - 254, 232, 107, 222, 221, 232, 109, 222, 223, 225, 227, 232, 106, 222, - 220, 228, 111, 230, 170, 211, 229, 232, 108, 222, 222, 243, 244, 225, - 226, 212, 15, 245, 170, 243, 233, 230, 234, 226, 201, 214, 134, 87, 230, - 234, 248, 165, 87, 8, 3, 235, 164, 79, 224, 197, 244, 28, 31, 67, 44, 71, - 233, 26, 127, 213, 118, 213, 7, 212, 195, 212, 184, 212, 173, 212, 162, - 212, 151, 212, 140, 212, 129, 213, 117, 213, 106, 213, 95, 213, 84, 213, - 73, 213, 62, 213, 51, 251, 79, 226, 159, 79, 251, 204, 209, 253, 15, 5, - 227, 215, 216, 240, 15, 5, 227, 215, 115, 227, 215, 251, 107, 115, 251, - 106, 49, 28, 16, 243, 243, 219, 104, 250, 81, 214, 9, 213, 40, 213, 29, - 213, 18, 213, 6, 212, 251, 212, 240, 212, 229, 212, 218, 212, 207, 212, - 199, 212, 198, 212, 197, 212, 196, 212, 194, 212, 193, 212, 192, 212, - 191, 212, 190, 212, 189, 212, 188, 212, 187, 212, 186, 212, 185, 212, - 183, 212, 182, 212, 181, 212, 180, 212, 179, 212, 178, 212, 177, 212, - 176, 212, 175, 212, 174, 212, 172, 212, 171, 212, 170, 212, 169, 212, - 168, 212, 167, 212, 166, 212, 165, 212, 164, 212, 163, 212, 161, 212, - 160, 212, 159, 212, 158, 212, 157, 212, 156, 212, 155, 212, 154, 212, - 153, 212, 152, 212, 150, 212, 149, 212, 148, 212, 147, 212, 146, 212, - 145, 212, 144, 212, 143, 212, 142, 212, 141, 212, 139, 212, 138, 212, - 137, 212, 136, 212, 135, 212, 134, 212, 133, 212, 132, 212, 131, 212, - 130, 212, 128, 212, 127, 212, 126, 212, 125, 212, 124, 212, 123, 212, - 122, 212, 121, 212, 120, 212, 119, 213, 116, 213, 115, 213, 114, 213, - 113, 213, 112, 213, 111, 213, 110, 213, 109, 213, 108, 213, 107, 213, - 105, 213, 104, 213, 103, 213, 102, 213, 101, 213, 100, 213, 99, 213, 98, - 213, 97, 213, 96, 213, 94, 213, 93, 213, 92, 213, 91, 213, 90, 213, 89, - 213, 88, 213, 87, 213, 86, 213, 85, 213, 83, 213, 82, 213, 81, 213, 80, - 213, 79, 213, 78, 213, 77, 213, 76, 213, 75, 213, 74, 213, 72, 213, 71, - 213, 70, 213, 69, 213, 68, 213, 67, 213, 66, 213, 65, 213, 64, 213, 63, - 213, 61, 213, 60, 213, 59, 213, 58, 213, 57, 213, 56, 213, 55, 213, 54, - 213, 53, 213, 52, 213, 50, 213, 49, 213, 48, 213, 47, 213, 46, 213, 45, - 213, 44, 213, 43, 213, 42, 213, 41, 213, 39, 213, 38, 213, 37, 213, 36, - 213, 35, 213, 34, 213, 33, 213, 32, 213, 31, 213, 30, 213, 28, 213, 27, - 213, 26, 213, 25, 213, 24, 213, 23, 213, 22, 213, 21, 213, 20, 213, 19, - 213, 17, 213, 16, 213, 15, 213, 14, 213, 13, 213, 12, 213, 11, 213, 10, - 213, 9, 213, 8, 213, 5, 213, 4, 213, 3, 213, 2, 213, 1, 213, 0, 212, 255, - 212, 254, 212, 253, 212, 252, 212, 250, 212, 249, 212, 248, 212, 247, - 212, 246, 212, 245, 212, 244, 212, 243, 212, 242, 212, 241, 212, 239, - 212, 238, 212, 237, 212, 236, 212, 235, 212, 234, 212, 233, 212, 232, - 212, 231, 212, 230, 212, 228, 212, 227, 212, 226, 212, 225, 212, 224, - 212, 223, 212, 222, 212, 221, 212, 220, 212, 219, 212, 217, 212, 216, - 212, 215, 212, 214, 212, 213, 212, 212, 212, 211, 212, 210, 212, 209, - 212, 208, 212, 206, 212, 205, 212, 204, 212, 203, 212, 202, 212, 201, - 212, 200, 7, 6, 1, 116, 2, 231, 238, 22, 242, 143, 7, 4, 1, 116, 2, 231, - 238, 22, 242, 143, 7, 6, 1, 160, 2, 67, 232, 220, 51, 7, 4, 1, 160, 2, - 67, 232, 220, 51, 7, 6, 1, 160, 2, 67, 232, 220, 252, 51, 22, 242, 143, - 7, 4, 1, 160, 2, 67, 232, 220, 252, 51, 22, 242, 143, 7, 6, 1, 160, 2, - 67, 232, 220, 252, 51, 22, 142, 7, 4, 1, 160, 2, 67, 232, 220, 252, 51, - 22, 142, 7, 6, 1, 160, 2, 250, 39, 22, 231, 237, 7, 4, 1, 160, 2, 250, - 39, 22, 231, 237, 7, 6, 1, 160, 2, 250, 39, 22, 250, 242, 7, 4, 1, 160, - 2, 250, 39, 22, 250, 242, 7, 6, 1, 240, 161, 2, 231, 238, 22, 242, 143, - 7, 4, 1, 240, 161, 2, 231, 238, 22, 242, 143, 7, 4, 1, 240, 161, 2, 59, - 72, 22, 142, 7, 4, 1, 229, 85, 2, 216, 90, 48, 7, 6, 1, 144, 2, 67, 232, - 220, 51, 7, 4, 1, 144, 2, 67, 232, 220, 51, 7, 6, 1, 144, 2, 67, 232, - 220, 252, 51, 22, 242, 143, 7, 4, 1, 144, 2, 67, 232, 220, 252, 51, 22, - 242, 143, 7, 6, 1, 144, 2, 67, 232, 220, 252, 51, 22, 142, 7, 4, 1, 144, - 2, 67, 232, 220, 252, 51, 22, 142, 7, 6, 1, 222, 94, 2, 67, 232, 220, 51, - 7, 4, 1, 222, 94, 2, 67, 232, 220, 51, 7, 6, 1, 104, 2, 231, 238, 22, - 242, 143, 7, 4, 1, 104, 2, 231, 238, 22, 242, 143, 7, 6, 1, 116, 2, 226, - 229, 22, 142, 7, 4, 1, 116, 2, 226, 229, 22, 142, 7, 6, 1, 116, 2, 226, - 229, 22, 184, 7, 4, 1, 116, 2, 226, 229, 22, 184, 7, 6, 1, 160, 2, 226, - 229, 22, 142, 7, 4, 1, 160, 2, 226, 229, 22, 142, 7, 6, 1, 160, 2, 226, - 229, 22, 184, 7, 4, 1, 160, 2, 226, 229, 22, 184, 7, 6, 1, 160, 2, 59, - 72, 22, 142, 7, 4, 1, 160, 2, 59, 72, 22, 142, 7, 6, 1, 160, 2, 59, 72, - 22, 184, 7, 4, 1, 160, 2, 59, 72, 22, 184, 7, 4, 1, 240, 161, 2, 59, 72, - 22, 242, 143, 7, 4, 1, 240, 161, 2, 59, 72, 22, 184, 7, 6, 1, 240, 161, - 2, 226, 229, 22, 142, 7, 4, 1, 240, 161, 2, 226, 229, 22, 59, 72, 22, - 142, 7, 6, 1, 240, 161, 2, 226, 229, 22, 184, 7, 4, 1, 240, 161, 2, 226, - 229, 22, 59, 72, 22, 184, 7, 6, 1, 235, 151, 2, 184, 7, 4, 1, 235, 151, - 2, 59, 72, 22, 184, 7, 6, 1, 233, 155, 2, 184, 7, 4, 1, 233, 155, 2, 184, - 7, 6, 1, 232, 55, 2, 184, 7, 4, 1, 232, 55, 2, 184, 7, 6, 1, 223, 227, 2, - 184, 7, 4, 1, 223, 227, 2, 184, 7, 6, 1, 104, 2, 226, 229, 22, 142, 7, 4, - 1, 104, 2, 226, 229, 22, 142, 7, 6, 1, 104, 2, 226, 229, 22, 184, 7, 4, - 1, 104, 2, 226, 229, 22, 184, 7, 6, 1, 104, 2, 231, 238, 22, 142, 7, 4, - 1, 104, 2, 231, 238, 22, 142, 7, 6, 1, 104, 2, 231, 238, 22, 184, 7, 4, - 1, 104, 2, 231, 238, 22, 184, 7, 4, 1, 254, 253, 2, 242, 143, 7, 4, 1, - 204, 144, 2, 242, 143, 7, 4, 1, 204, 144, 2, 142, 7, 4, 1, 215, 94, 214, - 106, 2, 242, 143, 7, 4, 1, 215, 94, 214, 106, 2, 142, 7, 4, 1, 221, 198, - 2, 242, 143, 7, 4, 1, 221, 198, 2, 142, 7, 4, 1, 241, 58, 221, 198, 2, - 242, 143, 7, 4, 1, 241, 58, 221, 198, 2, 142, 9, 220, 137, 77, 2, 182, - 72, 2, 254, 179, 9, 220, 137, 77, 2, 182, 72, 2, 212, 30, 9, 220, 137, - 77, 2, 182, 72, 2, 109, 231, 197, 9, 220, 137, 77, 2, 182, 72, 2, 226, - 238, 9, 220, 137, 77, 2, 182, 72, 2, 69, 9, 220, 137, 77, 2, 182, 72, 2, - 210, 212, 9, 220, 137, 77, 2, 182, 72, 2, 76, 9, 220, 137, 77, 2, 182, - 72, 2, 254, 252, 9, 220, 137, 228, 68, 2, 234, 180, 146, 1, 234, 115, 36, - 117, 235, 29, 36, 117, 229, 84, 36, 117, 251, 74, 36, 117, 227, 171, 36, - 117, 215, 160, 36, 117, 228, 116, 36, 117, 217, 153, 36, 117, 230, 30, - 36, 117, 226, 109, 36, 117, 194, 36, 117, 211, 117, 36, 117, 153, 36, - 117, 156, 36, 117, 214, 105, 36, 117, 232, 182, 36, 117, 232, 191, 36, - 117, 222, 182, 36, 117, 228, 98, 36, 117, 235, 150, 36, 117, 220, 106, - 36, 117, 218, 228, 36, 117, 222, 93, 36, 117, 242, 67, 36, 117, 233, 238, - 36, 3, 235, 16, 36, 3, 234, 98, 36, 3, 234, 89, 36, 3, 233, 223, 36, 3, - 233, 194, 36, 3, 234, 188, 36, 3, 234, 187, 36, 3, 234, 252, 36, 3, 234, - 34, 36, 3, 234, 16, 36, 3, 234, 201, 36, 3, 229, 81, 36, 3, 229, 32, 36, - 3, 229, 28, 36, 3, 228, 253, 36, 3, 228, 246, 36, 3, 229, 69, 36, 3, 229, - 67, 36, 3, 229, 78, 36, 3, 229, 9, 36, 3, 229, 4, 36, 3, 229, 71, 36, 3, - 251, 40, 36, 3, 250, 59, 36, 3, 250, 49, 36, 3, 249, 120, 36, 3, 249, 91, - 36, 3, 250, 198, 36, 3, 250, 190, 36, 3, 251, 30, 36, 3, 249, 246, 36, 3, - 249, 182, 36, 3, 250, 230, 36, 3, 227, 168, 36, 3, 227, 152, 36, 3, 227, - 147, 36, 3, 227, 132, 36, 3, 227, 125, 36, 3, 227, 160, 36, 3, 227, 159, - 36, 3, 227, 165, 36, 3, 227, 138, 36, 3, 227, 136, 36, 3, 227, 163, 36, - 3, 215, 156, 36, 3, 215, 136, 36, 3, 215, 135, 36, 3, 215, 124, 36, 3, - 215, 121, 36, 3, 215, 152, 36, 3, 215, 151, 36, 3, 215, 155, 36, 3, 215, - 134, 36, 3, 215, 133, 36, 3, 215, 154, 36, 3, 228, 114, 36, 3, 228, 100, - 36, 3, 228, 99, 36, 3, 228, 83, 36, 3, 228, 82, 36, 3, 228, 110, 36, 3, - 228, 109, 36, 3, 228, 113, 36, 3, 228, 85, 36, 3, 228, 84, 36, 3, 228, - 112, 36, 3, 217, 102, 36, 3, 216, 118, 36, 3, 216, 104, 36, 3, 215, 119, - 36, 3, 215, 85, 36, 3, 217, 23, 36, 3, 217, 12, 36, 3, 217, 80, 36, 3, - 112, 36, 3, 216, 18, 36, 3, 217, 42, 36, 3, 229, 230, 36, 3, 228, 238, - 36, 3, 228, 213, 36, 3, 227, 242, 36, 3, 227, 183, 36, 3, 229, 112, 36, - 3, 229, 108, 36, 3, 229, 217, 36, 3, 228, 79, 36, 3, 228, 69, 36, 3, 229, - 192, 36, 3, 226, 93, 36, 3, 225, 111, 36, 3, 225, 74, 36, 3, 224, 153, - 36, 3, 224, 122, 36, 3, 225, 224, 36, 3, 225, 214, 36, 3, 226, 75, 36, 3, - 225, 19, 36, 3, 224, 252, 36, 3, 225, 238, 36, 3, 231, 242, 36, 3, 230, - 235, 36, 3, 230, 206, 36, 3, 230, 107, 36, 3, 230, 59, 36, 3, 231, 96, - 36, 3, 231, 85, 36, 3, 231, 208, 36, 3, 230, 166, 36, 3, 230, 137, 36, 3, - 231, 140, 36, 3, 211, 103, 36, 3, 211, 8, 36, 3, 210, 255, 36, 3, 210, - 212, 36, 3, 210, 181, 36, 3, 211, 47, 36, 3, 211, 44, 36, 3, 211, 82, 36, - 3, 210, 244, 36, 3, 210, 229, 36, 3, 211, 55, 36, 3, 223, 187, 36, 3, - 223, 38, 36, 3, 222, 242, 36, 3, 222, 142, 36, 3, 222, 114, 36, 3, 223, - 131, 36, 3, 223, 111, 36, 3, 223, 169, 36, 3, 222, 213, 36, 3, 222, 199, - 36, 3, 223, 139, 36, 3, 233, 140, 36, 3, 232, 247, 36, 3, 232, 233, 36, - 3, 232, 103, 36, 3, 232, 78, 36, 3, 233, 64, 36, 3, 233, 56, 36, 3, 233, - 115, 36, 3, 232, 162, 36, 3, 232, 133, 36, 3, 233, 80, 36, 3, 214, 26, - 36, 3, 213, 176, 36, 3, 213, 162, 36, 3, 212, 116, 36, 3, 212, 109, 36, - 3, 213, 255, 36, 3, 213, 250, 36, 3, 214, 23, 36, 3, 213, 138, 36, 3, - 213, 127, 36, 3, 214, 5, 36, 3, 232, 180, 36, 3, 232, 175, 36, 3, 232, - 174, 36, 3, 232, 171, 36, 3, 232, 170, 36, 3, 232, 177, 36, 3, 232, 176, - 36, 3, 232, 179, 36, 3, 232, 173, 36, 3, 232, 172, 36, 3, 232, 178, 36, - 3, 232, 189, 36, 3, 232, 184, 36, 3, 232, 183, 36, 3, 232, 167, 36, 3, - 232, 166, 36, 3, 232, 186, 36, 3, 232, 185, 36, 3, 232, 188, 36, 3, 232, - 169, 36, 3, 232, 168, 36, 3, 232, 187, 36, 3, 222, 180, 36, 3, 222, 169, - 36, 3, 222, 168, 36, 3, 222, 162, 36, 3, 222, 155, 36, 3, 222, 176, 36, - 3, 222, 175, 36, 3, 222, 179, 36, 3, 222, 167, 36, 3, 222, 166, 36, 3, - 222, 178, 36, 3, 228, 96, 36, 3, 228, 91, 36, 3, 228, 90, 36, 3, 228, 87, - 36, 3, 228, 86, 36, 3, 228, 93, 36, 3, 228, 92, 36, 3, 228, 95, 36, 3, - 228, 89, 36, 3, 228, 88, 36, 3, 228, 94, 36, 3, 235, 146, 36, 3, 235, - 114, 36, 3, 235, 107, 36, 3, 235, 57, 36, 3, 235, 39, 36, 3, 235, 132, - 36, 3, 235, 130, 36, 3, 235, 141, 36, 3, 235, 74, 36, 3, 235, 65, 36, 3, - 235, 135, 36, 3, 220, 100, 36, 3, 220, 34, 36, 3, 220, 29, 36, 3, 219, - 227, 36, 3, 219, 212, 36, 3, 220, 65, 36, 3, 220, 63, 36, 3, 220, 92, 36, - 3, 220, 9, 36, 3, 220, 3, 36, 3, 220, 73, 36, 3, 218, 224, 36, 3, 218, - 194, 36, 3, 218, 190, 36, 3, 218, 181, 36, 3, 218, 178, 36, 3, 218, 199, - 36, 3, 218, 198, 36, 3, 218, 223, 36, 3, 218, 186, 36, 3, 218, 185, 36, - 3, 218, 201, 36, 3, 222, 33, 36, 3, 219, 193, 36, 3, 219, 177, 36, 3, - 218, 84, 36, 3, 218, 5, 36, 3, 221, 183, 36, 3, 221, 172, 36, 3, 222, 19, - 36, 3, 219, 60, 36, 3, 219, 42, 36, 3, 221, 221, 36, 3, 242, 53, 36, 3, - 241, 187, 36, 3, 241, 168, 36, 3, 240, 229, 36, 3, 240, 209, 36, 3, 241, - 245, 36, 3, 241, 227, 36, 3, 242, 43, 36, 3, 241, 75, 36, 3, 241, 60, 36, - 3, 241, 253, 36, 3, 233, 237, 36, 3, 233, 236, 36, 3, 233, 231, 36, 3, - 233, 230, 36, 3, 233, 227, 36, 3, 233, 226, 36, 3, 233, 233, 36, 3, 233, - 232, 36, 3, 233, 235, 36, 3, 233, 229, 36, 3, 233, 228, 36, 3, 233, 234, - 36, 3, 219, 233, 175, 117, 5, 211, 68, 175, 117, 5, 223, 158, 175, 117, - 5, 223, 81, 98, 1, 215, 28, 70, 117, 5, 249, 241, 176, 70, 117, 5, 249, - 241, 234, 138, 70, 117, 5, 249, 241, 234, 34, 70, 117, 5, 249, 241, 234, - 111, 70, 117, 5, 249, 241, 229, 9, 70, 117, 5, 249, 241, 251, 41, 70, - 117, 5, 249, 241, 250, 165, 70, 117, 5, 249, 241, 249, 246, 70, 117, 5, - 249, 241, 250, 94, 70, 117, 5, 249, 241, 227, 138, 70, 117, 5, 249, 241, - 248, 229, 70, 117, 5, 249, 241, 215, 145, 70, 117, 5, 249, 241, 247, 153, - 70, 117, 5, 249, 241, 215, 140, 70, 117, 5, 249, 241, 198, 70, 117, 5, - 249, 241, 217, 106, 70, 117, 5, 249, 241, 216, 209, 70, 117, 5, 249, 241, - 112, 70, 117, 5, 249, 241, 216, 157, 70, 117, 5, 249, 241, 228, 79, 70, - 117, 5, 249, 241, 252, 199, 70, 117, 5, 249, 241, 225, 150, 70, 117, 5, - 249, 241, 225, 19, 70, 117, 5, 249, 241, 225, 124, 70, 117, 5, 249, 241, - 230, 166, 70, 117, 5, 249, 241, 210, 244, 70, 117, 5, 249, 241, 222, 213, - 70, 117, 5, 249, 241, 232, 162, 70, 117, 5, 249, 241, 213, 138, 70, 117, - 5, 249, 241, 220, 104, 70, 117, 5, 249, 241, 218, 225, 70, 117, 5, 249, - 241, 206, 70, 117, 5, 249, 241, 162, 70, 117, 5, 249, 241, 233, 141, 70, - 25, 5, 249, 241, 224, 91, 70, 235, 250, 25, 5, 249, 241, 224, 33, 70, - 235, 250, 25, 5, 249, 241, 222, 102, 70, 235, 250, 25, 5, 249, 241, 222, - 95, 70, 235, 250, 25, 5, 249, 241, 224, 72, 70, 25, 5, 226, 208, 70, 25, - 5, 255, 43, 141, 1, 252, 7, 229, 82, 141, 1, 252, 7, 229, 32, 141, 1, - 252, 7, 228, 253, 141, 1, 252, 7, 229, 69, 141, 1, 252, 7, 229, 9, 56, 1, - 252, 7, 229, 82, 56, 1, 252, 7, 229, 32, 56, 1, 252, 7, 228, 253, 56, 1, - 252, 7, 229, 69, 56, 1, 252, 7, 229, 9, 56, 1, 254, 203, 250, 198, 56, 1, - 254, 203, 215, 119, 56, 1, 254, 203, 112, 56, 1, 254, 203, 226, 109, 58, - 1, 245, 28, 245, 27, 249, 190, 138, 130, 58, 1, 245, 27, 245, 28, 249, - 190, 138, 130, + 0, 214, 153, 242, 168, 83, 219, 180, 83, 43, 53, 245, 35, 53, 221, 131, + 53, 252, 125, 252, 53, 47, 221, 216, 48, 221, 216, 251, 209, 101, 53, + 247, 155, 237, 238, 241, 82, 213, 251, 214, 180, 18, 205, 85, 18, 102, + 18, 105, 18, 142, 18, 139, 18, 168, 18, 184, 18, 195, 18, 193, 18, 200, + 247, 162, 216, 52, 230, 10, 53, 242, 242, 53, 239, 230, 53, 219, 196, 83, + 247, 153, 251, 199, 7, 6, 1, 62, 7, 6, 1, 251, 150, 7, 6, 1, 249, 34, 7, + 6, 1, 246, 240, 7, 6, 1, 75, 7, 6, 1, 242, 139, 7, 6, 1, 241, 55, 7, 6, + 1, 239, 155, 7, 6, 1, 74, 7, 6, 1, 232, 203, 7, 6, 1, 232, 76, 7, 6, 1, + 149, 7, 6, 1, 229, 28, 7, 6, 1, 226, 33, 7, 6, 1, 76, 7, 6, 1, 222, 67, + 7, 6, 1, 220, 27, 7, 6, 1, 137, 7, 6, 1, 182, 7, 6, 1, 213, 10, 7, 6, 1, + 71, 7, 6, 1, 209, 148, 7, 6, 1, 207, 129, 7, 6, 1, 206, 195, 7, 6, 1, + 206, 123, 7, 6, 1, 205, 159, 47, 49, 145, 218, 225, 214, 180, 48, 49, + 145, 247, 228, 253, 21, 114, 229, 205, 239, 237, 253, 21, 7, 5, 1, 62, 7, + 5, 1, 251, 150, 7, 5, 1, 249, 34, 7, 5, 1, 246, 240, 7, 5, 1, 75, 7, 5, + 1, 242, 139, 7, 5, 1, 241, 55, 7, 5, 1, 239, 155, 7, 5, 1, 74, 7, 5, 1, + 232, 203, 7, 5, 1, 232, 76, 7, 5, 1, 149, 7, 5, 1, 229, 28, 7, 5, 1, 226, + 33, 7, 5, 1, 76, 7, 5, 1, 222, 67, 7, 5, 1, 220, 27, 7, 5, 1, 137, 7, 5, + 1, 182, 7, 5, 1, 213, 10, 7, 5, 1, 71, 7, 5, 1, 209, 148, 7, 5, 1, 207, + 129, 7, 5, 1, 206, 195, 7, 5, 1, 206, 123, 7, 5, 1, 205, 159, 47, 247, + 26, 145, 79, 229, 205, 48, 247, 26, 145, 211, 180, 224, 66, 214, 153, + 233, 2, 242, 168, 83, 248, 131, 53, 220, 165, 53, 247, 25, 53, 206, 43, + 53, 249, 111, 134, 217, 77, 53, 245, 166, 247, 94, 53, 242, 9, 222, 118, + 233, 49, 230, 41, 50, 252, 109, 219, 180, 83, 224, 43, 53, 214, 187, 237, + 239, 219, 23, 53, 228, 13, 245, 245, 53, 220, 217, 53, 213, 139, 105, + 213, 139, 142, 253, 9, 253, 21, 226, 252, 53, 221, 12, 53, 226, 247, 245, + 23, 248, 141, 213, 139, 102, 227, 179, 222, 118, 233, 49, 218, 162, 50, + 252, 109, 219, 180, 83, 207, 146, 241, 116, 119, 219, 204, 207, 146, 241, + 116, 119, 239, 121, 207, 146, 241, 116, 129, 219, 202, 233, 2, 219, 196, + 83, 7, 6, 1, 32, 2, 239, 236, 7, 6, 1, 32, 2, 153, 7, 6, 1, 32, 2, 247, + 227, 7, 6, 1, 32, 2, 211, 180, 7, 6, 1, 32, 2, 245, 166, 7, 6, 1, 32, 2, + 218, 149, 52, 7, 6, 1, 252, 248, 7, 6, 1, 249, 35, 2, 248, 141, 7, 6, 1, + 174, 2, 239, 236, 7, 6, 1, 174, 2, 153, 7, 6, 1, 174, 2, 247, 227, 7, 6, + 1, 174, 2, 245, 166, 7, 6, 1, 237, 225, 2, 239, 236, 7, 6, 1, 237, 225, + 2, 153, 7, 6, 1, 237, 225, 2, 247, 227, 7, 6, 1, 237, 225, 2, 245, 166, + 7, 6, 1, 242, 196, 7, 6, 1, 226, 34, 2, 211, 180, 7, 6, 1, 148, 2, 239, + 236, 7, 6, 1, 148, 2, 153, 7, 6, 1, 148, 2, 247, 227, 7, 6, 1, 148, 2, + 211, 180, 7, 6, 1, 148, 2, 245, 166, 226, 94, 53, 7, 6, 1, 148, 2, 91, 7, + 6, 1, 106, 2, 239, 236, 7, 6, 1, 106, 2, 153, 7, 6, 1, 106, 2, 247, 227, + 7, 6, 1, 106, 2, 245, 166, 7, 6, 1, 206, 124, 2, 153, 7, 6, 1, 211, 246, + 7, 5, 1, 215, 228, 182, 7, 5, 1, 32, 2, 239, 236, 7, 5, 1, 32, 2, 153, 7, + 5, 1, 32, 2, 247, 227, 7, 5, 1, 32, 2, 211, 180, 7, 5, 1, 32, 2, 245, + 166, 7, 5, 1, 32, 2, 218, 149, 52, 7, 5, 1, 252, 248, 7, 5, 1, 249, 35, + 2, 248, 141, 7, 5, 1, 174, 2, 239, 236, 7, 5, 1, 174, 2, 153, 7, 5, 1, + 174, 2, 247, 227, 7, 5, 1, 174, 2, 245, 166, 7, 5, 1, 237, 225, 2, 239, + 236, 7, 5, 1, 237, 225, 2, 153, 7, 5, 1, 237, 225, 2, 247, 227, 7, 5, 1, + 237, 225, 2, 245, 166, 7, 5, 1, 242, 196, 7, 5, 1, 226, 34, 2, 211, 180, + 7, 5, 1, 148, 2, 239, 236, 7, 5, 1, 148, 2, 153, 7, 5, 1, 148, 2, 247, + 227, 7, 5, 1, 148, 2, 211, 180, 7, 5, 1, 148, 2, 245, 166, 245, 75, 53, + 7, 5, 1, 148, 2, 91, 7, 5, 1, 106, 2, 239, 236, 7, 5, 1, 106, 2, 153, 7, + 5, 1, 106, 2, 247, 227, 7, 5, 1, 106, 2, 245, 166, 7, 5, 1, 206, 124, 2, + 153, 7, 5, 1, 211, 246, 7, 5, 1, 206, 124, 2, 245, 166, 7, 6, 1, 32, 2, + 228, 13, 7, 5, 1, 32, 2, 228, 13, 7, 6, 1, 32, 2, 249, 122, 7, 5, 1, 32, + 2, 249, 122, 7, 6, 1, 32, 2, 222, 196, 7, 5, 1, 32, 2, 222, 196, 7, 6, 1, + 249, 35, 2, 153, 7, 5, 1, 249, 35, 2, 153, 7, 6, 1, 249, 35, 2, 247, 227, + 7, 5, 1, 249, 35, 2, 247, 227, 7, 6, 1, 249, 35, 2, 67, 52, 7, 5, 1, 249, + 35, 2, 67, 52, 7, 6, 1, 249, 35, 2, 248, 195, 7, 5, 1, 249, 35, 2, 248, + 195, 7, 6, 1, 246, 241, 2, 248, 195, 7, 5, 1, 246, 241, 2, 248, 195, 7, + 6, 1, 246, 241, 2, 91, 7, 5, 1, 246, 241, 2, 91, 7, 6, 1, 174, 2, 228, + 13, 7, 5, 1, 174, 2, 228, 13, 7, 6, 1, 174, 2, 249, 122, 7, 5, 1, 174, 2, + 249, 122, 7, 6, 1, 174, 2, 67, 52, 7, 5, 1, 174, 2, 67, 52, 7, 6, 1, 174, + 2, 222, 196, 7, 5, 1, 174, 2, 222, 196, 7, 6, 1, 174, 2, 248, 195, 7, 5, + 1, 174, 2, 248, 195, 7, 6, 1, 241, 56, 2, 247, 227, 7, 5, 1, 241, 56, 2, + 247, 227, 7, 6, 1, 241, 56, 2, 249, 122, 7, 5, 1, 241, 56, 2, 249, 122, + 7, 6, 1, 241, 56, 2, 67, 52, 7, 5, 1, 241, 56, 2, 67, 52, 7, 6, 1, 241, + 56, 2, 248, 141, 7, 5, 1, 241, 56, 2, 248, 141, 7, 6, 1, 239, 156, 2, + 247, 227, 7, 5, 1, 239, 156, 2, 247, 227, 7, 6, 1, 239, 156, 2, 91, 7, 5, + 1, 239, 156, 2, 91, 7, 6, 1, 237, 225, 2, 211, 180, 7, 5, 1, 237, 225, 2, + 211, 180, 7, 6, 1, 237, 225, 2, 228, 13, 7, 5, 1, 237, 225, 2, 228, 13, + 7, 6, 1, 237, 225, 2, 249, 122, 7, 5, 1, 237, 225, 2, 249, 122, 7, 6, 1, + 237, 225, 2, 222, 196, 7, 5, 1, 237, 225, 2, 222, 196, 7, 6, 1, 237, 225, + 2, 67, 52, 7, 5, 1, 245, 22, 74, 7, 6, 28, 233, 100, 7, 5, 28, 233, 100, + 7, 6, 1, 232, 204, 2, 247, 227, 7, 5, 1, 232, 204, 2, 247, 227, 7, 6, 1, + 232, 77, 2, 248, 141, 7, 5, 1, 232, 77, 2, 248, 141, 7, 5, 1, 231, 2, 7, + 6, 1, 230, 159, 2, 153, 7, 5, 1, 230, 159, 2, 153, 7, 6, 1, 230, 159, 2, + 248, 141, 7, 5, 1, 230, 159, 2, 248, 141, 7, 6, 1, 230, 159, 2, 248, 195, + 7, 5, 1, 230, 159, 2, 248, 195, 7, 6, 1, 230, 159, 2, 226, 247, 245, 23, + 7, 5, 1, 230, 159, 2, 226, 247, 245, 23, 7, 6, 1, 230, 159, 2, 91, 7, 5, + 1, 230, 159, 2, 91, 7, 6, 1, 226, 34, 2, 153, 7, 5, 1, 226, 34, 2, 153, + 7, 6, 1, 226, 34, 2, 248, 141, 7, 5, 1, 226, 34, 2, 248, 141, 7, 6, 1, + 226, 34, 2, 248, 195, 7, 5, 1, 226, 34, 2, 248, 195, 7, 5, 1, 226, 34, + 220, 141, 249, 46, 252, 53, 7, 6, 1, 243, 28, 7, 5, 1, 243, 28, 7, 6, 1, + 148, 2, 228, 13, 7, 5, 1, 148, 2, 228, 13, 7, 6, 1, 148, 2, 249, 122, 7, + 5, 1, 148, 2, 249, 122, 7, 6, 1, 148, 2, 50, 153, 7, 5, 1, 148, 2, 50, + 153, 7, 6, 28, 222, 206, 7, 5, 28, 222, 206, 7, 6, 1, 219, 150, 2, 153, + 7, 5, 1, 219, 150, 2, 153, 7, 6, 1, 219, 150, 2, 248, 141, 7, 5, 1, 219, + 150, 2, 248, 141, 7, 6, 1, 219, 150, 2, 248, 195, 7, 5, 1, 219, 150, 2, + 248, 195, 7, 6, 1, 218, 1, 2, 153, 7, 5, 1, 218, 1, 2, 153, 7, 6, 1, 218, + 1, 2, 247, 227, 7, 5, 1, 218, 1, 2, 247, 227, 7, 6, 1, 218, 1, 2, 248, + 141, 7, 5, 1, 218, 1, 2, 248, 141, 7, 6, 1, 218, 1, 2, 248, 195, 7, 5, 1, + 218, 1, 2, 248, 195, 7, 6, 1, 213, 11, 2, 248, 141, 7, 5, 1, 213, 11, 2, + 248, 141, 7, 6, 1, 213, 11, 2, 248, 195, 7, 5, 1, 213, 11, 2, 248, 195, + 7, 6, 1, 213, 11, 2, 91, 7, 5, 1, 213, 11, 2, 91, 7, 6, 1, 106, 2, 211, + 180, 7, 5, 1, 106, 2, 211, 180, 7, 6, 1, 106, 2, 228, 13, 7, 5, 1, 106, + 2, 228, 13, 7, 6, 1, 106, 2, 249, 122, 7, 5, 1, 106, 2, 249, 122, 7, 6, + 1, 106, 2, 218, 149, 52, 7, 5, 1, 106, 2, 218, 149, 52, 7, 6, 1, 106, 2, + 50, 153, 7, 5, 1, 106, 2, 50, 153, 7, 6, 1, 106, 2, 222, 196, 7, 5, 1, + 106, 2, 222, 196, 7, 6, 1, 207, 130, 2, 247, 227, 7, 5, 1, 207, 130, 2, + 247, 227, 7, 6, 1, 206, 124, 2, 247, 227, 7, 5, 1, 206, 124, 2, 247, 227, + 7, 6, 1, 206, 124, 2, 245, 166, 7, 6, 1, 205, 160, 2, 153, 7, 5, 1, 205, + 160, 2, 153, 7, 6, 1, 205, 160, 2, 67, 52, 7, 5, 1, 205, 160, 2, 67, 52, + 7, 6, 1, 205, 160, 2, 248, 195, 7, 5, 1, 205, 160, 2, 248, 195, 7, 5, 1, + 152, 182, 7, 5, 1, 63, 2, 91, 7, 6, 1, 63, 2, 109, 7, 6, 1, 63, 2, 211, + 99, 7, 5, 1, 63, 2, 211, 99, 7, 6, 1, 135, 184, 7, 5, 1, 135, 184, 7, 6, + 1, 222, 142, 76, 7, 6, 1, 249, 35, 2, 109, 7, 5, 1, 249, 35, 2, 109, 7, + 6, 1, 252, 223, 246, 240, 7, 6, 1, 246, 241, 2, 109, 7, 6, 1, 246, 241, + 2, 211, 99, 7, 5, 1, 246, 241, 2, 211, 99, 7, 5, 1, 201, 245, 227, 7, 6, + 1, 218, 224, 75, 7, 6, 1, 217, 100, 7, 6, 1, 222, 142, 75, 7, 6, 1, 242, + 140, 2, 109, 7, 5, 1, 242, 140, 2, 109, 7, 6, 1, 241, 56, 2, 109, 7, 6, + 1, 240, 215, 7, 5, 1, 238, 17, 7, 6, 1, 232, 249, 7, 6, 1, 237, 225, 2, + 91, 7, 6, 1, 232, 77, 2, 109, 7, 5, 1, 232, 77, 2, 109, 7, 5, 1, 230, + 159, 2, 134, 7, 5, 1, 230, 104, 2, 91, 7, 6, 1, 201, 229, 28, 7, 6, 1, + 226, 34, 2, 47, 109, 7, 5, 1, 226, 34, 2, 152, 48, 230, 34, 7, 6, 1, 148, + 2, 226, 247, 211, 180, 7, 6, 1, 148, 2, 238, 69, 7, 5, 1, 148, 2, 238, + 69, 7, 6, 1, 222, 191, 7, 5, 1, 222, 191, 7, 6, 1, 222, 68, 2, 109, 7, 5, + 1, 222, 68, 2, 109, 7, 1, 205, 216, 7, 6, 1, 135, 105, 7, 5, 1, 135, 105, + 7, 6, 1, 242, 215, 7, 1, 218, 224, 242, 216, 229, 111, 7, 5, 1, 213, 11, + 2, 222, 26, 109, 7, 6, 1, 213, 11, 2, 109, 7, 5, 1, 213, 11, 2, 109, 7, + 6, 1, 213, 11, 2, 218, 230, 109, 7, 6, 1, 106, 2, 238, 69, 7, 5, 1, 106, + 2, 238, 69, 7, 6, 1, 209, 200, 7, 6, 1, 209, 149, 2, 109, 7, 6, 1, 206, + 124, 2, 109, 7, 5, 1, 206, 124, 2, 109, 7, 6, 1, 205, 160, 2, 91, 7, 5, + 1, 205, 160, 2, 91, 7, 6, 1, 242, 141, 7, 6, 1, 242, 142, 218, 223, 7, 5, + 1, 242, 142, 218, 223, 7, 5, 1, 242, 142, 2, 212, 191, 7, 1, 118, 2, 91, + 7, 6, 1, 135, 168, 7, 5, 1, 135, 168, 7, 1, 233, 2, 240, 25, 213, 252, 2, + 91, 7, 1, 206, 198, 7, 1, 245, 220, 247, 203, 7, 1, 230, 78, 247, 203, 7, + 1, 252, 137, 247, 203, 7, 1, 218, 230, 247, 203, 7, 6, 1, 243, 198, 2, + 248, 195, 7, 6, 1, 246, 241, 2, 5, 1, 205, 160, 2, 248, 195, 7, 5, 1, + 243, 198, 2, 248, 195, 7, 6, 1, 229, 176, 7, 6, 1, 230, 159, 2, 5, 1, + 232, 203, 7, 5, 1, 229, 176, 7, 6, 1, 224, 181, 7, 6, 1, 226, 34, 2, 5, + 1, 232, 203, 7, 5, 1, 224, 181, 7, 6, 1, 32, 2, 248, 195, 7, 5, 1, 32, 2, + 248, 195, 7, 6, 1, 237, 225, 2, 248, 195, 7, 5, 1, 237, 225, 2, 248, 195, + 7, 6, 1, 148, 2, 248, 195, 7, 5, 1, 148, 2, 248, 195, 7, 6, 1, 106, 2, + 248, 195, 7, 5, 1, 106, 2, 248, 195, 7, 6, 1, 106, 2, 245, 167, 23, 228, + 13, 7, 5, 1, 106, 2, 245, 167, 23, 228, 13, 7, 6, 1, 106, 2, 245, 167, + 23, 153, 7, 5, 1, 106, 2, 245, 167, 23, 153, 7, 6, 1, 106, 2, 245, 167, + 23, 248, 195, 7, 5, 1, 106, 2, 245, 167, 23, 248, 195, 7, 6, 1, 106, 2, + 245, 167, 23, 239, 236, 7, 5, 1, 106, 2, 245, 167, 23, 239, 236, 7, 5, 1, + 201, 75, 7, 6, 1, 32, 2, 245, 167, 23, 228, 13, 7, 5, 1, 32, 2, 245, 167, + 23, 228, 13, 7, 6, 1, 32, 2, 67, 84, 23, 228, 13, 7, 5, 1, 32, 2, 67, 84, + 23, 228, 13, 7, 6, 1, 252, 249, 2, 228, 13, 7, 5, 1, 252, 249, 2, 228, + 13, 7, 6, 1, 241, 56, 2, 91, 7, 5, 1, 241, 56, 2, 91, 7, 6, 1, 241, 56, + 2, 248, 195, 7, 5, 1, 241, 56, 2, 248, 195, 7, 6, 1, 232, 77, 2, 248, + 195, 7, 5, 1, 232, 77, 2, 248, 195, 7, 6, 1, 148, 2, 222, 196, 7, 5, 1, + 148, 2, 222, 196, 7, 6, 1, 148, 2, 222, 197, 23, 228, 13, 7, 5, 1, 148, + 2, 222, 197, 23, 228, 13, 7, 6, 1, 242, 142, 2, 248, 195, 7, 5, 1, 242, + 142, 2, 248, 195, 7, 5, 1, 232, 204, 2, 248, 195, 7, 6, 1, 243, 197, 7, + 6, 1, 246, 241, 2, 5, 1, 205, 159, 7, 5, 1, 243, 197, 7, 6, 1, 241, 56, + 2, 153, 7, 5, 1, 241, 56, 2, 153, 7, 6, 1, 238, 14, 7, 6, 1, 206, 198, 7, + 6, 1, 226, 34, 2, 239, 236, 7, 5, 1, 226, 34, 2, 239, 236, 7, 6, 1, 32, + 2, 218, 149, 84, 23, 153, 7, 5, 1, 32, 2, 218, 149, 84, 23, 153, 7, 6, 1, + 252, 249, 2, 153, 7, 5, 1, 252, 249, 2, 153, 7, 6, 1, 148, 2, 213, 225, + 23, 153, 7, 5, 1, 148, 2, 213, 225, 23, 153, 7, 6, 1, 32, 2, 50, 239, + 236, 7, 5, 1, 32, 2, 50, 239, 236, 7, 6, 1, 32, 2, 233, 2, 249, 122, 7, + 5, 1, 32, 2, 233, 2, 249, 122, 7, 6, 1, 174, 2, 50, 239, 236, 7, 5, 1, + 174, 2, 50, 239, 236, 7, 6, 1, 174, 2, 233, 2, 249, 122, 7, 5, 1, 174, 2, + 233, 2, 249, 122, 7, 6, 1, 237, 225, 2, 50, 239, 236, 7, 5, 1, 237, 225, + 2, 50, 239, 236, 7, 6, 1, 237, 225, 2, 233, 2, 249, 122, 7, 5, 1, 237, + 225, 2, 233, 2, 249, 122, 7, 6, 1, 148, 2, 50, 239, 236, 7, 5, 1, 148, 2, + 50, 239, 236, 7, 6, 1, 148, 2, 233, 2, 249, 122, 7, 5, 1, 148, 2, 233, 2, + 249, 122, 7, 6, 1, 219, 150, 2, 50, 239, 236, 7, 5, 1, 219, 150, 2, 50, + 239, 236, 7, 6, 1, 219, 150, 2, 233, 2, 249, 122, 7, 5, 1, 219, 150, 2, + 233, 2, 249, 122, 7, 6, 1, 106, 2, 50, 239, 236, 7, 5, 1, 106, 2, 50, + 239, 236, 7, 6, 1, 106, 2, 233, 2, 249, 122, 7, 5, 1, 106, 2, 233, 2, + 249, 122, 7, 6, 1, 218, 1, 2, 247, 156, 55, 7, 5, 1, 218, 1, 2, 247, 156, + 55, 7, 6, 1, 213, 11, 2, 247, 156, 55, 7, 5, 1, 213, 11, 2, 247, 156, 55, + 7, 6, 1, 205, 234, 7, 5, 1, 205, 234, 7, 6, 1, 239, 156, 2, 248, 195, 7, + 5, 1, 239, 156, 2, 248, 195, 7, 6, 1, 226, 34, 2, 152, 48, 230, 34, 7, 5, + 1, 246, 241, 2, 247, 27, 7, 6, 1, 222, 97, 7, 5, 1, 222, 97, 7, 6, 1, + 205, 160, 2, 109, 7, 5, 1, 205, 160, 2, 109, 7, 6, 1, 32, 2, 67, 52, 7, + 5, 1, 32, 2, 67, 52, 7, 6, 1, 174, 2, 248, 141, 7, 5, 1, 174, 2, 248, + 141, 7, 6, 1, 148, 2, 245, 167, 23, 228, 13, 7, 5, 1, 148, 2, 245, 167, + 23, 228, 13, 7, 6, 1, 148, 2, 211, 181, 23, 228, 13, 7, 5, 1, 148, 2, + 211, 181, 23, 228, 13, 7, 6, 1, 148, 2, 67, 52, 7, 5, 1, 148, 2, 67, 52, + 7, 6, 1, 148, 2, 67, 84, 23, 228, 13, 7, 5, 1, 148, 2, 67, 84, 23, 228, + 13, 7, 6, 1, 206, 124, 2, 228, 13, 7, 5, 1, 206, 124, 2, 228, 13, 7, 5, + 1, 230, 159, 2, 247, 27, 7, 5, 1, 226, 34, 2, 247, 27, 7, 5, 1, 213, 11, + 2, 247, 27, 7, 5, 1, 245, 22, 232, 203, 7, 5, 1, 246, 64, 245, 127, 7, 5, + 1, 219, 215, 245, 127, 7, 6, 1, 32, 2, 91, 7, 6, 1, 249, 35, 2, 91, 7, 5, + 1, 249, 35, 2, 91, 7, 6, 1, 230, 159, 2, 134, 7, 6, 1, 213, 11, 2, 245, + 163, 91, 7, 5, 1, 218, 1, 2, 213, 109, 212, 191, 7, 5, 1, 205, 160, 2, + 213, 109, 212, 191, 7, 6, 1, 240, 25, 213, 251, 7, 5, 1, 240, 25, 213, + 251, 7, 6, 1, 63, 2, 91, 7, 6, 1, 106, 134, 7, 6, 1, 201, 209, 148, 7, 6, + 1, 174, 2, 91, 7, 5, 1, 174, 2, 91, 7, 6, 1, 232, 204, 2, 91, 7, 5, 1, + 232, 204, 2, 91, 7, 6, 1, 5, 220, 28, 2, 238, 130, 212, 191, 7, 5, 1, + 220, 28, 2, 238, 130, 212, 191, 7, 6, 1, 219, 150, 2, 91, 7, 5, 1, 219, + 150, 2, 91, 7, 6, 1, 206, 124, 2, 91, 7, 5, 1, 206, 124, 2, 91, 7, 5, 1, + 201, 62, 7, 5, 1, 252, 144, 7, 5, 1, 201, 252, 144, 7, 5, 1, 63, 2, 109, + 7, 5, 1, 222, 142, 76, 7, 5, 1, 249, 35, 2, 247, 27, 7, 5, 1, 246, 241, + 2, 212, 191, 7, 5, 1, 246, 241, 2, 109, 7, 5, 1, 218, 224, 75, 7, 5, 1, + 217, 100, 7, 5, 1, 217, 101, 2, 109, 7, 5, 1, 222, 142, 75, 7, 5, 1, 218, + 224, 222, 142, 75, 7, 5, 1, 218, 224, 222, 142, 174, 2, 109, 7, 5, 1, + 247, 192, 218, 224, 222, 142, 75, 7, 5, 1, 245, 22, 232, 204, 2, 91, 7, + 5, 1, 241, 56, 2, 109, 7, 5, 1, 121, 241, 55, 7, 1, 5, 6, 241, 55, 7, 5, + 1, 240, 215, 7, 5, 1, 219, 75, 238, 69, 7, 5, 1, 201, 239, 155, 7, 5, 1, + 239, 156, 2, 109, 7, 5, 1, 239, 40, 2, 109, 7, 5, 1, 237, 225, 2, 91, 7, + 5, 1, 232, 249, 7, 1, 5, 6, 74, 7, 5, 1, 230, 159, 2, 226, 247, 211, 180, + 7, 5, 1, 230, 159, 2, 250, 24, 7, 5, 1, 230, 159, 2, 218, 230, 109, 7, 5, + 1, 229, 251, 7, 5, 1, 201, 229, 28, 7, 5, 1, 201, 229, 29, 2, 152, 230, + 34, 7, 5, 1, 229, 29, 2, 109, 7, 5, 1, 226, 34, 2, 47, 109, 7, 5, 1, 226, + 34, 2, 218, 230, 109, 7, 1, 5, 6, 226, 33, 7, 5, 1, 250, 123, 76, 7, 1, + 5, 6, 222, 206, 7, 5, 1, 247, 192, 222, 170, 7, 5, 1, 221, 78, 7, 5, 1, + 201, 137, 7, 5, 1, 201, 219, 150, 2, 152, 230, 34, 7, 5, 1, 201, 219, + 150, 2, 109, 7, 5, 1, 219, 150, 2, 152, 230, 34, 7, 5, 1, 219, 150, 2, + 212, 191, 7, 5, 1, 219, 150, 2, 241, 210, 7, 5, 1, 218, 224, 219, 150, 2, + 241, 210, 7, 1, 5, 6, 137, 7, 1, 5, 6, 233, 2, 137, 7, 5, 1, 218, 1, 2, + 109, 7, 5, 1, 242, 215, 7, 5, 1, 245, 22, 232, 204, 2, 213, 225, 23, 109, + 7, 5, 1, 214, 104, 218, 224, 242, 215, 7, 5, 1, 242, 216, 2, 247, 27, 7, + 5, 1, 201, 213, 10, 7, 5, 1, 213, 11, 2, 218, 230, 109, 7, 5, 1, 106, + 134, 7, 5, 1, 209, 200, 7, 5, 1, 209, 149, 2, 109, 7, 5, 1, 201, 209, + 148, 7, 5, 1, 201, 207, 129, 7, 5, 1, 201, 206, 123, 7, 1, 5, 6, 206, + 123, 7, 5, 1, 205, 160, 2, 218, 230, 109, 7, 5, 1, 205, 160, 2, 247, 27, + 7, 5, 1, 242, 141, 7, 5, 1, 242, 142, 2, 247, 27, 7, 1, 240, 25, 213, + 251, 7, 1, 221, 84, 208, 170, 241, 104, 7, 1, 233, 2, 240, 25, 213, 251, + 7, 1, 213, 232, 249, 34, 7, 1, 249, 228, 247, 203, 7, 1, 5, 6, 251, 150, + 7, 5, 1, 247, 192, 222, 142, 75, 7, 1, 5, 6, 241, 56, 2, 109, 7, 1, 5, 6, + 239, 155, 7, 5, 1, 232, 204, 2, 247, 56, 7, 5, 1, 201, 232, 76, 7, 1, 5, + 6, 149, 7, 5, 1, 220, 28, 2, 109, 7, 1, 240, 25, 213, 252, 2, 91, 7, 1, + 218, 224, 240, 25, 213, 252, 2, 91, 7, 5, 1, 243, 198, 245, 127, 7, 5, 1, + 245, 194, 245, 127, 7, 5, 1, 243, 198, 245, 128, 2, 247, 27, 7, 5, 1, + 210, 245, 245, 127, 7, 5, 1, 212, 85, 245, 127, 7, 5, 1, 212, 138, 245, + 128, 2, 247, 27, 7, 5, 1, 242, 7, 245, 127, 7, 5, 1, 229, 83, 245, 127, + 7, 5, 1, 229, 30, 245, 127, 7, 1, 249, 228, 221, 130, 7, 1, 249, 236, + 221, 130, 7, 5, 1, 201, 239, 156, 2, 241, 210, 7, 5, 1, 201, 239, 156, 2, + 241, 211, 23, 212, 191, 65, 1, 5, 239, 155, 65, 1, 5, 239, 156, 2, 109, + 65, 1, 5, 232, 203, 65, 1, 5, 137, 65, 1, 5, 201, 137, 65, 1, 5, 201, + 219, 150, 2, 109, 65, 1, 5, 6, 233, 2, 137, 65, 1, 5, 207, 129, 65, 1, 5, + 206, 123, 65, 1, 220, 127, 65, 1, 50, 220, 127, 65, 1, 201, 247, 155, 65, + 1, 252, 53, 65, 1, 218, 224, 247, 155, 65, 1, 48, 160, 218, 148, 65, 1, + 47, 160, 218, 148, 65, 1, 240, 25, 213, 251, 65, 1, 218, 224, 240, 25, + 213, 251, 65, 1, 47, 251, 243, 65, 1, 48, 251, 243, 65, 1, 120, 251, 243, + 65, 1, 130, 251, 243, 65, 1, 247, 228, 253, 21, 248, 195, 65, 1, 79, 229, + 205, 65, 1, 228, 13, 65, 1, 253, 9, 253, 21, 65, 1, 239, 237, 253, 21, + 65, 1, 114, 79, 229, 205, 65, 1, 114, 228, 13, 65, 1, 114, 239, 237, 253, + 21, 65, 1, 114, 253, 9, 253, 21, 65, 1, 211, 48, 247, 162, 65, 1, 160, + 211, 48, 247, 162, 65, 1, 248, 127, 48, 160, 218, 148, 65, 1, 248, 127, + 47, 160, 218, 148, 65, 1, 120, 212, 201, 65, 1, 130, 212, 201, 65, 1, + 101, 53, 65, 1, 226, 202, 53, 249, 122, 67, 52, 218, 149, 52, 222, 196, + 5, 211, 180, 50, 253, 9, 253, 21, 65, 1, 218, 209, 109, 65, 1, 247, 60, + 253, 21, 65, 1, 5, 240, 215, 65, 1, 5, 149, 65, 1, 5, 182, 65, 1, 5, 206, + 195, 65, 1, 5, 218, 224, 240, 25, 213, 251, 65, 1, 242, 156, 135, 134, + 65, 1, 127, 135, 134, 65, 1, 226, 249, 135, 134, 65, 1, 114, 135, 134, + 65, 1, 242, 155, 135, 134, 65, 1, 206, 1, 245, 217, 135, 83, 65, 1, 206, + 76, 245, 217, 135, 83, 65, 1, 208, 168, 65, 1, 209, 230, 65, 1, 50, 252, + 53, 65, 1, 114, 130, 251, 243, 65, 1, 114, 120, 251, 243, 65, 1, 114, 47, + 251, 243, 65, 1, 114, 48, 251, 243, 65, 1, 114, 218, 148, 65, 1, 226, + 247, 239, 237, 253, 21, 65, 1, 226, 247, 50, 239, 237, 253, 21, 65, 1, + 226, 247, 50, 253, 9, 253, 21, 65, 1, 114, 211, 180, 65, 1, 219, 81, 247, + 162, 65, 1, 250, 42, 127, 211, 118, 65, 1, 243, 34, 127, 211, 118, 65, 1, + 250, 42, 114, 211, 118, 65, 1, 243, 34, 114, 211, 118, 65, 1, 215, 205, + 65, 1, 222, 142, 215, 205, 65, 1, 114, 47, 45, 36, 239, 237, 253, 21, 36, + 253, 9, 253, 21, 36, 247, 228, 253, 21, 36, 211, 180, 36, 228, 13, 36, + 222, 81, 36, 249, 122, 36, 67, 52, 36, 245, 166, 36, 238, 130, 52, 36, + 218, 149, 52, 36, 50, 253, 9, 253, 21, 36, 248, 195, 36, 79, 229, 206, + 52, 36, 50, 79, 229, 206, 52, 36, 50, 239, 237, 253, 21, 36, 248, 217, + 36, 233, 2, 249, 122, 36, 201, 247, 156, 52, 36, 247, 156, 52, 36, 218, + 224, 247, 156, 52, 36, 247, 156, 84, 218, 167, 36, 239, 237, 253, 22, 55, + 36, 253, 9, 253, 22, 55, 36, 47, 212, 202, 55, 36, 48, 212, 202, 55, 36, + 47, 252, 109, 52, 36, 238, 69, 36, 47, 160, 218, 149, 55, 36, 120, 212, + 202, 55, 36, 130, 212, 202, 55, 36, 101, 3, 55, 36, 226, 202, 3, 55, 36, + 222, 24, 238, 130, 55, 36, 218, 230, 238, 130, 55, 36, 67, 55, 36, 245, + 167, 55, 36, 218, 149, 55, 36, 247, 156, 55, 36, 248, 141, 36, 222, 196, + 36, 79, 229, 206, 55, 36, 249, 116, 55, 36, 233, 2, 50, 252, 20, 55, 36, + 248, 196, 55, 36, 247, 228, 253, 22, 55, 36, 249, 123, 55, 36, 233, 2, + 249, 123, 55, 36, 211, 181, 55, 36, 228, 14, 55, 36, 114, 229, 205, 36, + 50, 114, 229, 205, 36, 211, 181, 222, 82, 36, 215, 144, 213, 225, 222, + 82, 36, 152, 213, 225, 222, 82, 36, 215, 144, 214, 181, 222, 82, 36, 152, + 214, 181, 222, 82, 36, 48, 160, 218, 149, 55, 36, 233, 2, 249, 116, 55, + 36, 49, 55, 36, 217, 85, 55, 36, 206, 196, 52, 36, 79, 211, 180, 36, 50, + 222, 81, 36, 239, 237, 135, 83, 36, 253, 9, 135, 83, 36, 27, 221, 124, + 36, 27, 231, 23, 36, 27, 245, 160, 211, 106, 36, 27, 205, 221, 36, 249, + 116, 52, 36, 242, 242, 3, 55, 36, 50, 79, 229, 206, 55, 36, 47, 252, 109, + 55, 36, 224, 43, 211, 181, 52, 36, 238, 136, 52, 36, 252, 149, 146, 211, + 130, 52, 36, 47, 48, 51, 55, 36, 167, 51, 55, 36, 239, 242, 232, 117, 36, + 48, 251, 244, 52, 36, 47, 160, 218, 149, 52, 36, 242, 4, 36, 206, 196, + 55, 36, 47, 251, 244, 55, 36, 48, 251, 244, 55, 36, 48, 251, 244, 23, + 120, 251, 244, 55, 36, 48, 160, 218, 149, 52, 36, 67, 84, 218, 167, 36, + 251, 210, 55, 36, 50, 218, 149, 55, 36, 205, 31, 52, 36, 50, 249, 123, + 55, 36, 50, 249, 122, 36, 50, 228, 13, 36, 50, 228, 14, 55, 36, 50, 211, + 180, 36, 50, 233, 2, 249, 122, 36, 50, 86, 51, 55, 36, 7, 5, 1, 62, 36, + 7, 5, 1, 75, 36, 7, 5, 1, 74, 36, 7, 5, 1, 76, 36, 7, 5, 1, 71, 36, 7, 5, + 1, 249, 34, 36, 7, 5, 1, 246, 240, 36, 7, 5, 1, 239, 155, 36, 7, 5, 1, + 229, 28, 36, 7, 5, 1, 137, 36, 7, 5, 1, 213, 10, 36, 7, 5, 1, 209, 148, + 36, 7, 5, 1, 206, 195, 27, 6, 1, 239, 28, 27, 5, 1, 239, 28, 27, 6, 1, + 252, 19, 217, 154, 27, 5, 1, 252, 19, 217, 154, 27, 223, 177, 53, 27, + 229, 92, 223, 177, 53, 27, 6, 1, 222, 10, 245, 134, 27, 5, 1, 222, 10, + 245, 134, 27, 205, 221, 27, 5, 218, 224, 229, 64, 215, 64, 93, 27, 5, + 244, 21, 229, 64, 215, 64, 93, 27, 5, 218, 224, 244, 21, 229, 64, 215, + 64, 93, 27, 219, 196, 83, 27, 6, 1, 205, 227, 27, 211, 106, 27, 245, 160, + 211, 106, 27, 6, 1, 252, 145, 2, 211, 106, 27, 252, 96, 212, 109, 27, 6, + 1, 242, 245, 2, 211, 106, 27, 6, 1, 242, 202, 2, 211, 106, 27, 6, 1, 232, + 250, 2, 211, 106, 27, 6, 1, 222, 169, 2, 211, 106, 27, 6, 1, 209, 201, 2, + 211, 106, 27, 6, 1, 222, 171, 2, 211, 106, 27, 5, 1, 232, 250, 2, 245, + 160, 23, 211, 106, 27, 6, 1, 252, 144, 27, 6, 1, 250, 8, 27, 6, 1, 240, + 215, 27, 6, 1, 245, 227, 27, 6, 1, 242, 244, 27, 6, 1, 205, 84, 27, 6, 1, + 242, 201, 27, 6, 1, 212, 23, 27, 6, 1, 232, 249, 27, 6, 1, 232, 14, 27, + 6, 1, 230, 102, 27, 6, 1, 226, 114, 27, 6, 1, 223, 217, 27, 6, 1, 206, + 169, 27, 6, 1, 222, 168, 27, 6, 1, 221, 53, 27, 6, 1, 218, 210, 27, 6, 1, + 215, 63, 27, 6, 1, 212, 151, 27, 6, 1, 209, 200, 27, 6, 1, 221, 78, 27, + 6, 1, 248, 58, 27, 6, 1, 220, 93, 27, 6, 1, 222, 170, 27, 6, 1, 232, 250, + 2, 245, 159, 27, 6, 1, 209, 201, 2, 245, 159, 27, 5, 1, 252, 145, 2, 211, + 106, 27, 5, 1, 242, 245, 2, 211, 106, 27, 5, 1, 242, 202, 2, 211, 106, + 27, 5, 1, 232, 250, 2, 211, 106, 27, 5, 1, 209, 201, 2, 245, 160, 23, + 211, 106, 27, 5, 1, 252, 144, 27, 5, 1, 250, 8, 27, 5, 1, 240, 215, 27, + 5, 1, 245, 227, 27, 5, 1, 242, 244, 27, 5, 1, 205, 84, 27, 5, 1, 242, + 201, 27, 5, 1, 212, 23, 27, 5, 1, 232, 249, 27, 5, 1, 232, 14, 27, 5, 1, + 230, 102, 27, 5, 1, 226, 114, 27, 5, 1, 223, 217, 27, 5, 1, 206, 169, 27, + 5, 1, 222, 168, 27, 5, 1, 221, 53, 27, 5, 1, 218, 210, 27, 5, 1, 42, 215, + 63, 27, 5, 1, 215, 63, 27, 5, 1, 212, 151, 27, 5, 1, 209, 200, 27, 5, 1, + 221, 78, 27, 5, 1, 248, 58, 27, 5, 1, 220, 93, 27, 5, 1, 222, 170, 27, 5, + 1, 232, 250, 2, 245, 159, 27, 5, 1, 209, 201, 2, 245, 159, 27, 5, 1, 222, + 169, 2, 211, 106, 27, 5, 1, 209, 201, 2, 211, 106, 27, 5, 1, 222, 171, 2, + 211, 106, 27, 6, 232, 42, 93, 27, 250, 9, 93, 27, 212, 24, 93, 27, 209, + 201, 2, 238, 130, 93, 27, 209, 201, 2, 253, 9, 23, 238, 130, 93, 27, 209, + 201, 2, 245, 167, 23, 238, 130, 93, 27, 221, 79, 93, 27, 221, 54, 93, 27, + 232, 42, 93, 27, 1, 252, 19, 231, 27, 27, 5, 1, 252, 19, 231, 27, 27, 1, + 214, 5, 27, 5, 1, 214, 5, 27, 1, 245, 134, 27, 5, 1, 245, 134, 27, 1, + 231, 27, 27, 5, 1, 231, 27, 27, 1, 217, 154, 27, 5, 1, 217, 154, 81, 6, + 1, 215, 206, 81, 5, 1, 215, 206, 81, 6, 1, 242, 13, 81, 5, 1, 242, 13, + 81, 6, 1, 231, 150, 81, 5, 1, 231, 150, 81, 6, 1, 238, 122, 81, 5, 1, + 238, 122, 81, 6, 1, 240, 210, 81, 5, 1, 240, 210, 81, 6, 1, 215, 173, 81, + 5, 1, 215, 173, 81, 6, 1, 245, 242, 81, 5, 1, 245, 242, 27, 232, 15, 93, + 27, 218, 211, 93, 27, 229, 64, 215, 64, 93, 27, 1, 205, 227, 27, 6, 212, + 24, 93, 27, 229, 64, 242, 245, 93, 27, 218, 224, 229, 64, 242, 245, 93, + 27, 6, 1, 215, 158, 27, 5, 1, 215, 158, 27, 6, 229, 64, 215, 64, 93, 27, + 6, 1, 217, 151, 27, 5, 1, 217, 151, 27, 218, 211, 2, 213, 225, 93, 27, 6, + 218, 224, 229, 64, 215, 64, 93, 27, 6, 244, 21, 229, 64, 215, 64, 93, 27, + 6, 218, 224, 244, 21, 229, 64, 215, 64, 93, 34, 6, 1, 233, 130, 2, 239, + 236, 34, 6, 1, 232, 253, 34, 6, 1, 245, 68, 34, 6, 1, 240, 32, 34, 6, 1, + 209, 246, 233, 129, 34, 6, 1, 243, 193, 34, 6, 1, 249, 44, 74, 34, 6, 1, + 206, 11, 34, 6, 1, 232, 182, 34, 6, 1, 229, 175, 34, 6, 1, 224, 173, 34, + 6, 1, 210, 231, 34, 6, 1, 231, 74, 34, 6, 1, 237, 225, 2, 239, 236, 34, + 6, 1, 215, 144, 71, 34, 6, 1, 243, 189, 34, 6, 1, 62, 34, 6, 1, 250, 61, + 34, 6, 1, 209, 39, 34, 6, 1, 240, 85, 34, 6, 1, 246, 9, 34, 6, 1, 233, + 129, 34, 6, 1, 205, 72, 34, 6, 1, 205, 93, 34, 6, 1, 74, 34, 6, 1, 215, + 144, 74, 34, 6, 1, 172, 34, 6, 1, 243, 68, 34, 6, 1, 243, 50, 34, 6, 1, + 243, 41, 34, 6, 1, 76, 34, 6, 1, 221, 174, 34, 6, 1, 242, 235, 34, 6, 1, + 242, 225, 34, 6, 1, 212, 131, 34, 6, 1, 71, 34, 6, 1, 243, 97, 34, 6, 1, + 155, 34, 6, 1, 210, 237, 34, 6, 1, 248, 82, 34, 6, 1, 216, 2, 34, 6, 1, + 215, 217, 34, 6, 1, 239, 94, 53, 34, 6, 1, 206, 30, 34, 6, 1, 214, 187, + 53, 34, 6, 1, 75, 34, 6, 1, 205, 213, 34, 6, 1, 190, 34, 5, 1, 62, 34, 5, + 1, 250, 61, 34, 5, 1, 209, 39, 34, 5, 1, 240, 85, 34, 5, 1, 246, 9, 34, + 5, 1, 233, 129, 34, 5, 1, 205, 72, 34, 5, 1, 205, 93, 34, 5, 1, 74, 34, + 5, 1, 215, 144, 74, 34, 5, 1, 172, 34, 5, 1, 243, 68, 34, 5, 1, 243, 50, + 34, 5, 1, 243, 41, 34, 5, 1, 76, 34, 5, 1, 221, 174, 34, 5, 1, 242, 235, + 34, 5, 1, 242, 225, 34, 5, 1, 212, 131, 34, 5, 1, 71, 34, 5, 1, 243, 97, + 34, 5, 1, 155, 34, 5, 1, 210, 237, 34, 5, 1, 248, 82, 34, 5, 1, 216, 2, + 34, 5, 1, 215, 217, 34, 5, 1, 239, 94, 53, 34, 5, 1, 206, 30, 34, 5, 1, + 214, 187, 53, 34, 5, 1, 75, 34, 5, 1, 205, 213, 34, 5, 1, 190, 34, 5, 1, + 233, 130, 2, 239, 236, 34, 5, 1, 232, 253, 34, 5, 1, 245, 68, 34, 5, 1, + 240, 32, 34, 5, 1, 209, 246, 233, 129, 34, 5, 1, 243, 193, 34, 5, 1, 249, + 44, 74, 34, 5, 1, 206, 11, 34, 5, 1, 232, 182, 34, 5, 1, 229, 175, 34, 5, + 1, 224, 173, 34, 5, 1, 210, 231, 34, 5, 1, 231, 74, 34, 5, 1, 237, 225, + 2, 239, 236, 34, 5, 1, 215, 144, 71, 34, 5, 1, 243, 189, 34, 6, 1, 222, + 170, 34, 5, 1, 222, 170, 34, 6, 1, 206, 65, 34, 5, 1, 206, 65, 34, 6, 1, + 232, 247, 75, 34, 5, 1, 232, 247, 75, 34, 6, 1, 229, 180, 205, 183, 34, + 5, 1, 229, 180, 205, 183, 34, 6, 1, 232, 247, 229, 180, 205, 183, 34, 5, + 1, 232, 247, 229, 180, 205, 183, 34, 6, 1, 249, 231, 205, 183, 34, 5, 1, + 249, 231, 205, 183, 34, 6, 1, 232, 247, 249, 231, 205, 183, 34, 5, 1, + 232, 247, 249, 231, 205, 183, 34, 6, 1, 230, 252, 34, 5, 1, 230, 252, 34, + 6, 1, 220, 93, 34, 5, 1, 220, 93, 34, 6, 1, 241, 205, 34, 5, 1, 241, 205, + 34, 6, 1, 232, 205, 34, 5, 1, 232, 205, 34, 6, 1, 232, 206, 2, 50, 239, + 237, 253, 21, 34, 5, 1, 232, 206, 2, 50, 239, 237, 253, 21, 34, 6, 1, + 209, 249, 34, 5, 1, 209, 249, 34, 6, 1, 218, 95, 222, 170, 34, 5, 1, 218, + 95, 222, 170, 34, 6, 1, 222, 171, 2, 211, 154, 34, 5, 1, 222, 171, 2, + 211, 154, 34, 6, 1, 222, 103, 34, 5, 1, 222, 103, 34, 6, 1, 231, 27, 34, + 5, 1, 231, 27, 34, 211, 241, 53, 36, 34, 211, 154, 36, 34, 222, 25, 36, + 34, 246, 76, 220, 213, 36, 34, 220, 87, 220, 213, 36, 34, 220, 197, 36, + 34, 238, 30, 211, 241, 53, 36, 34, 226, 213, 53, 34, 6, 1, 215, 144, 237, + 225, 2, 212, 191, 34, 5, 1, 215, 144, 237, 225, 2, 212, 191, 34, 6, 1, + 216, 48, 53, 34, 5, 1, 216, 48, 53, 34, 6, 1, 242, 236, 2, 211, 207, 34, + 5, 1, 242, 236, 2, 211, 207, 34, 6, 1, 240, 86, 2, 209, 199, 34, 5, 1, + 240, 86, 2, 209, 199, 34, 6, 1, 240, 86, 2, 91, 34, 5, 1, 240, 86, 2, 91, + 34, 6, 1, 240, 86, 2, 226, 247, 109, 34, 5, 1, 240, 86, 2, 226, 247, 109, + 34, 6, 1, 205, 73, 2, 245, 211, 34, 5, 1, 205, 73, 2, 245, 211, 34, 6, 1, + 205, 94, 2, 245, 211, 34, 5, 1, 205, 94, 2, 245, 211, 34, 6, 1, 232, 66, + 2, 245, 211, 34, 5, 1, 232, 66, 2, 245, 211, 34, 6, 1, 232, 66, 2, 79, + 91, 34, 5, 1, 232, 66, 2, 79, 91, 34, 6, 1, 232, 66, 2, 91, 34, 5, 1, + 232, 66, 2, 91, 34, 6, 1, 250, 112, 172, 34, 5, 1, 250, 112, 172, 34, 6, + 1, 243, 42, 2, 245, 211, 34, 5, 1, 243, 42, 2, 245, 211, 34, 6, 28, 243, + 42, 240, 85, 34, 5, 28, 243, 42, 240, 85, 34, 6, 1, 221, 175, 2, 226, + 247, 109, 34, 5, 1, 221, 175, 2, 226, 247, 109, 34, 6, 1, 253, 28, 155, + 34, 5, 1, 253, 28, 155, 34, 6, 1, 242, 226, 2, 245, 211, 34, 5, 1, 242, + 226, 2, 245, 211, 34, 6, 1, 212, 132, 2, 245, 211, 34, 5, 1, 212, 132, 2, + 245, 211, 34, 6, 1, 213, 243, 71, 34, 5, 1, 213, 243, 71, 34, 6, 1, 213, + 243, 106, 2, 91, 34, 5, 1, 213, 243, 106, 2, 91, 34, 6, 1, 239, 144, 2, + 245, 211, 34, 5, 1, 239, 144, 2, 245, 211, 34, 6, 28, 212, 132, 210, 237, + 34, 5, 28, 212, 132, 210, 237, 34, 6, 1, 248, 83, 2, 245, 211, 34, 5, 1, + 248, 83, 2, 245, 211, 34, 6, 1, 248, 83, 2, 79, 91, 34, 5, 1, 248, 83, 2, + 79, 91, 34, 6, 1, 215, 184, 34, 5, 1, 215, 184, 34, 6, 1, 253, 28, 248, + 82, 34, 5, 1, 253, 28, 248, 82, 34, 6, 1, 253, 28, 248, 83, 2, 245, 211, + 34, 5, 1, 253, 28, 248, 83, 2, 245, 211, 34, 1, 222, 17, 34, 6, 1, 205, + 73, 2, 249, 122, 34, 5, 1, 205, 73, 2, 249, 122, 34, 6, 1, 232, 66, 2, + 109, 34, 5, 1, 232, 66, 2, 109, 34, 6, 1, 243, 69, 2, 212, 191, 34, 5, 1, + 243, 69, 2, 212, 191, 34, 6, 1, 243, 42, 2, 109, 34, 5, 1, 243, 42, 2, + 109, 34, 6, 1, 243, 42, 2, 212, 191, 34, 5, 1, 243, 42, 2, 212, 191, 34, + 6, 1, 231, 161, 248, 82, 34, 5, 1, 231, 161, 248, 82, 34, 6, 1, 243, 51, + 2, 212, 191, 34, 5, 1, 243, 51, 2, 212, 191, 34, 5, 1, 222, 17, 34, 6, 1, + 32, 2, 249, 122, 34, 5, 1, 32, 2, 249, 122, 34, 6, 1, 32, 2, 245, 166, + 34, 5, 1, 32, 2, 245, 166, 34, 6, 28, 32, 233, 129, 34, 5, 28, 32, 233, + 129, 34, 6, 1, 233, 130, 2, 249, 122, 34, 5, 1, 233, 130, 2, 249, 122, + 34, 6, 1, 217, 100, 34, 5, 1, 217, 100, 34, 6, 1, 217, 101, 2, 245, 166, + 34, 5, 1, 217, 101, 2, 245, 166, 34, 6, 1, 205, 73, 2, 245, 166, 34, 5, + 1, 205, 73, 2, 245, 166, 34, 6, 1, 205, 94, 2, 245, 166, 34, 5, 1, 205, + 94, 2, 245, 166, 34, 6, 1, 253, 28, 243, 193, 34, 5, 1, 253, 28, 243, + 193, 34, 6, 1, 237, 225, 2, 228, 13, 34, 5, 1, 237, 225, 2, 228, 13, 34, + 6, 1, 237, 225, 2, 245, 166, 34, 5, 1, 237, 225, 2, 245, 166, 34, 6, 1, + 148, 2, 245, 166, 34, 5, 1, 148, 2, 245, 166, 34, 6, 1, 250, 123, 76, 34, + 5, 1, 250, 123, 76, 34, 6, 1, 250, 123, 148, 2, 245, 166, 34, 5, 1, 250, + 123, 148, 2, 245, 166, 34, 6, 1, 174, 2, 245, 166, 34, 5, 1, 174, 2, 245, + 166, 34, 6, 1, 106, 2, 228, 13, 34, 5, 1, 106, 2, 228, 13, 34, 6, 1, 106, + 2, 245, 166, 34, 5, 1, 106, 2, 245, 166, 34, 6, 1, 106, 2, 50, 153, 34, + 5, 1, 106, 2, 50, 153, 34, 6, 1, 248, 83, 2, 245, 166, 34, 5, 1, 248, 83, + 2, 245, 166, 34, 6, 1, 240, 86, 2, 245, 211, 34, 5, 1, 240, 86, 2, 245, + 211, 34, 6, 1, 206, 31, 2, 245, 166, 34, 5, 1, 206, 31, 2, 245, 166, 34, + 6, 1, 240, 86, 2, 213, 225, 23, 109, 34, 5, 1, 240, 86, 2, 213, 225, 23, + 109, 34, 6, 1, 239, 144, 2, 109, 34, 5, 1, 239, 144, 2, 109, 34, 6, 1, + 239, 144, 2, 91, 34, 5, 1, 239, 144, 2, 91, 34, 6, 1, 231, 37, 246, 9, + 34, 5, 1, 231, 37, 246, 9, 34, 6, 1, 231, 37, 245, 68, 34, 5, 1, 231, 37, + 245, 68, 34, 6, 1, 231, 37, 205, 23, 34, 5, 1, 231, 37, 205, 23, 34, 6, + 1, 231, 37, 243, 185, 34, 5, 1, 231, 37, 243, 185, 34, 6, 1, 231, 37, + 229, 175, 34, 5, 1, 231, 37, 229, 175, 34, 6, 1, 231, 37, 224, 173, 34, + 5, 1, 231, 37, 224, 173, 34, 6, 1, 231, 37, 214, 249, 34, 5, 1, 231, 37, + 214, 249, 34, 6, 1, 231, 37, 211, 148, 34, 5, 1, 231, 37, 211, 148, 34, + 6, 1, 218, 224, 205, 93, 34, 5, 1, 218, 224, 205, 93, 34, 6, 1, 243, 69, + 2, 109, 34, 5, 1, 243, 69, 2, 109, 34, 6, 1, 229, 248, 34, 5, 1, 229, + 248, 34, 6, 1, 218, 212, 34, 5, 1, 218, 212, 34, 6, 1, 206, 98, 34, 5, 1, + 206, 98, 34, 6, 1, 220, 19, 34, 5, 1, 220, 19, 34, 6, 1, 207, 51, 34, 5, + 1, 207, 51, 34, 6, 1, 252, 168, 172, 34, 5, 1, 252, 168, 172, 34, 6, 1, + 243, 69, 2, 226, 247, 109, 34, 5, 1, 243, 69, 2, 226, 247, 109, 34, 6, 1, + 243, 42, 2, 226, 247, 109, 34, 5, 1, 243, 42, 2, 226, 247, 109, 34, 6, 1, + 221, 175, 2, 245, 211, 34, 5, 1, 221, 175, 2, 245, 211, 34, 6, 1, 215, + 185, 2, 245, 211, 34, 5, 1, 215, 185, 2, 245, 211, 34, 6, 1, 243, 42, 2, + 47, 109, 34, 5, 1, 243, 42, 2, 47, 109, 34, 6, 1, 243, 178, 34, 5, 1, + 243, 178, 34, 6, 1, 246, 58, 34, 5, 1, 246, 58, 34, 6, 1, 243, 69, 2, + 245, 211, 34, 5, 1, 243, 69, 2, 245, 211, 164, 6, 1, 251, 156, 164, 6, 1, + 250, 22, 164, 6, 1, 240, 49, 164, 6, 1, 246, 145, 164, 6, 1, 243, 108, + 164, 6, 1, 205, 116, 164, 6, 1, 243, 92, 164, 6, 1, 242, 203, 164, 6, 1, + 124, 164, 6, 1, 205, 72, 164, 6, 1, 233, 38, 164, 6, 1, 229, 178, 164, 6, + 1, 206, 173, 164, 6, 1, 249, 1, 164, 6, 1, 231, 203, 164, 6, 1, 238, 149, + 164, 6, 1, 232, 200, 164, 6, 1, 240, 96, 164, 6, 1, 248, 75, 164, 6, 1, + 227, 83, 164, 6, 1, 206, 11, 164, 6, 1, 224, 29, 164, 6, 1, 216, 2, 164, + 6, 1, 208, 173, 164, 6, 1, 248, 110, 164, 6, 1, 221, 157, 164, 6, 1, 232, + 165, 164, 6, 1, 219, 113, 164, 6, 1, 217, 64, 164, 6, 1, 208, 218, 164, + 6, 1, 211, 151, 164, 6, 1, 219, 16, 164, 6, 1, 247, 174, 164, 6, 1, 205, + 252, 164, 6, 1, 220, 244, 164, 6, 1, 231, 214, 164, 6, 1, 222, 194, 164, + 6, 1, 242, 15, 164, 65, 1, 47, 160, 218, 148, 164, 252, 53, 164, 243, 45, + 83, 164, 242, 168, 83, 164, 247, 155, 164, 219, 196, 83, 164, 253, 29, + 83, 164, 5, 1, 251, 156, 164, 5, 1, 250, 22, 164, 5, 1, 240, 49, 164, 5, + 1, 246, 145, 164, 5, 1, 243, 108, 164, 5, 1, 205, 116, 164, 5, 1, 243, + 92, 164, 5, 1, 242, 203, 164, 5, 1, 124, 164, 5, 1, 205, 72, 164, 5, 1, + 233, 38, 164, 5, 1, 229, 178, 164, 5, 1, 206, 173, 164, 5, 1, 249, 1, + 164, 5, 1, 231, 203, 164, 5, 1, 238, 149, 164, 5, 1, 232, 200, 164, 5, 1, + 240, 96, 164, 5, 1, 248, 75, 164, 5, 1, 227, 83, 164, 5, 1, 206, 11, 164, + 5, 1, 224, 29, 164, 5, 1, 216, 2, 164, 5, 1, 208, 173, 164, 5, 1, 248, + 110, 164, 5, 1, 221, 157, 164, 5, 1, 232, 165, 164, 5, 1, 219, 113, 164, + 5, 1, 217, 64, 164, 5, 1, 208, 218, 164, 5, 1, 211, 151, 164, 5, 1, 219, + 16, 164, 5, 1, 247, 174, 164, 5, 1, 205, 252, 164, 5, 1, 220, 244, 164, + 5, 1, 231, 214, 164, 5, 1, 222, 194, 164, 5, 1, 242, 15, 164, 5, 28, 243, + 109, 205, 252, 164, 241, 82, 213, 251, 164, 237, 239, 218, 166, 164, 242, + 199, 53, 230, 45, 164, 242, 199, 53, 164, 243, 254, 53, 103, 253, 22, + 242, 194, 103, 253, 22, 217, 65, 103, 253, 22, 215, 240, 103, 253, 22, + 205, 104, 220, 2, 103, 253, 22, 205, 104, 240, 234, 103, 253, 22, 211, + 165, 103, 253, 22, 218, 221, 103, 253, 22, 205, 102, 103, 253, 22, 221, + 201, 103, 253, 22, 206, 23, 103, 253, 22, 212, 63, 103, 253, 22, 240, + 147, 103, 253, 22, 240, 148, 226, 78, 103, 253, 22, 240, 145, 103, 253, + 22, 220, 3, 221, 230, 103, 253, 22, 212, 104, 240, 163, 103, 253, 22, + 221, 180, 103, 253, 22, 251, 193, 239, 136, 103, 253, 22, 226, 88, 103, + 253, 22, 227, 244, 103, 253, 22, 227, 73, 103, 253, 22, 227, 74, 231, + 215, 103, 253, 22, 246, 85, 103, 253, 22, 220, 14, 103, 253, 22, 212, + 104, 219, 253, 103, 253, 22, 206, 33, 250, 23, 205, 233, 103, 253, 22, + 222, 177, 103, 253, 22, 233, 88, 103, 253, 22, 245, 243, 103, 253, 22, + 205, 29, 103, 141, 227, 174, 247, 233, 103, 220, 205, 215, 187, 103, 220, + 205, 239, 85, 217, 65, 103, 220, 205, 239, 85, 221, 194, 103, 220, 205, + 239, 85, 220, 7, 103, 220, 205, 238, 244, 103, 220, 205, 210, 234, 103, + 220, 205, 217, 65, 103, 220, 205, 221, 194, 103, 220, 205, 220, 7, 103, + 220, 205, 238, 142, 103, 220, 205, 238, 143, 239, 87, 33, 209, 43, 103, + 220, 205, 219, 200, 103, 220, 205, 246, 131, 222, 123, 227, 204, 103, + 220, 205, 227, 62, 103, 220, 72, 227, 201, 103, 220, 205, 219, 93, 103, + 220, 72, 221, 203, 103, 220, 205, 215, 172, 245, 23, 103, 220, 205, 215, + 45, 245, 23, 103, 220, 72, 214, 188, 221, 196, 103, 141, 209, 203, 245, + 23, 103, 141, 229, 92, 245, 23, 103, 220, 72, 223, 174, 239, 135, 103, + 220, 205, 220, 8, 220, 2, 103, 1, 252, 172, 103, 1, 250, 10, 103, 1, 240, + 47, 103, 1, 246, 111, 103, 1, 239, 71, 103, 1, 209, 43, 103, 1, 205, 96, + 103, 1, 239, 29, 103, 1, 212, 80, 103, 1, 205, 236, 103, 1, 42, 232, 45, + 103, 1, 232, 45, 103, 1, 230, 98, 103, 1, 42, 227, 90, 103, 1, 227, 90, + 103, 1, 42, 223, 173, 103, 1, 223, 173, 103, 1, 217, 157, 103, 1, 251, + 154, 103, 1, 42, 221, 174, 103, 1, 221, 174, 103, 1, 42, 210, 238, 103, + 1, 210, 238, 103, 1, 219, 223, 103, 1, 218, 242, 103, 1, 215, 171, 103, + 1, 212, 147, 103, 28, 206, 9, 50, 209, 43, 103, 28, 206, 9, 209, 44, 205, + 236, 103, 28, 206, 9, 50, 205, 236, 103, 220, 72, 240, 147, 103, 220, 72, + 240, 145, 8, 43, 53, 8, 3, 217, 150, 8, 241, 146, 227, 187, 8, 3, 217, + 187, 8, 3, 217, 153, 8, 43, 141, 52, 252, 33, 247, 36, 218, 103, 252, 33, + 241, 118, 218, 103, 8, 219, 58, 252, 33, 221, 132, 226, 215, 53, 252, 33, + 221, 132, 212, 99, 211, 243, 53, 252, 225, 53, 8, 247, 155, 8, 246, 72, + 216, 39, 8, 220, 207, 209, 24, 53, 8, 3, 226, 194, 8, 3, 217, 167, 252, + 175, 207, 75, 8, 3, 252, 175, 251, 214, 8, 3, 219, 91, 252, 174, 8, 3, + 219, 99, 252, 154, 252, 103, 8, 3, 212, 184, 8, 5, 127, 212, 194, 8, 5, + 127, 28, 126, 2, 230, 107, 2, 206, 47, 8, 5, 127, 205, 108, 8, 5, 242, + 39, 8, 5, 246, 106, 8, 5, 231, 252, 8, 216, 52, 8, 1, 83, 8, 211, 36, 67, + 220, 72, 83, 8, 219, 196, 83, 8, 1, 232, 0, 206, 47, 8, 1, 239, 111, 8, + 1, 126, 2, 228, 9, 52, 8, 1, 126, 2, 239, 112, 52, 8, 1, 207, 60, 2, 239, + 112, 52, 8, 1, 126, 2, 239, 112, 55, 8, 1, 87, 2, 239, 112, 52, 8, 1, + 252, 172, 8, 1, 250, 38, 8, 1, 212, 116, 227, 197, 8, 1, 212, 115, 8, 1, + 212, 37, 8, 1, 232, 179, 8, 1, 239, 132, 8, 1, 231, 163, 8, 1, 246, 117, + 8, 1, 212, 49, 8, 1, 219, 16, 8, 1, 205, 108, 8, 1, 217, 70, 8, 1, 215, + 210, 8, 1, 217, 191, 8, 1, 246, 140, 8, 1, 212, 194, 8, 1, 205, 111, 8, + 1, 252, 200, 8, 1, 240, 94, 8, 1, 231, 213, 2, 118, 177, 52, 8, 1, 231, + 213, 2, 129, 177, 55, 8, 1, 242, 42, 87, 2, 233, 2, 209, 148, 8, 1, 242, + 42, 87, 2, 118, 177, 52, 8, 1, 242, 42, 87, 2, 129, 177, 52, 8, 212, 153, + 8, 1, 242, 15, 8, 1, 220, 12, 8, 1, 232, 45, 8, 1, 230, 106, 8, 1, 227, + 104, 8, 1, 224, 54, 8, 1, 239, 50, 8, 1, 207, 59, 8, 1, 126, 227, 228, 8, + 1, 206, 47, 8, 242, 37, 8, 246, 104, 8, 231, 250, 8, 242, 39, 8, 246, + 106, 8, 231, 252, 8, 215, 249, 8, 213, 162, 8, 228, 7, 52, 8, 239, 112, + 52, 8, 239, 112, 55, 8, 213, 183, 252, 172, 8, 233, 2, 246, 106, 8, 141, + 224, 55, 240, 65, 8, 204, 251, 8, 22, 3, 5, 209, 149, 52, 8, 22, 3, 233, + 2, 5, 209, 149, 52, 8, 22, 3, 67, 55, 8, 218, 224, 246, 106, 8, 242, 40, + 2, 118, 245, 21, 8, 207, 61, 239, 112, 55, 252, 33, 18, 205, 85, 252, 33, + 18, 102, 252, 33, 18, 105, 252, 33, 18, 142, 252, 33, 18, 139, 252, 33, + 18, 168, 252, 33, 18, 184, 252, 33, 18, 195, 252, 33, 18, 193, 252, 33, + 18, 200, 8, 221, 131, 53, 8, 246, 2, 216, 39, 8, 211, 241, 216, 39, 8, + 241, 204, 220, 203, 214, 26, 8, 1, 245, 22, 250, 38, 8, 1, 245, 22, 220, + 12, 8, 1, 213, 139, 252, 172, 8, 1, 126, 207, 76, 8, 1, 126, 2, 207, 61, + 239, 112, 52, 8, 1, 126, 2, 207, 61, 239, 112, 55, 8, 1, 127, 239, 111, + 8, 1, 127, 239, 112, 252, 172, 8, 1, 127, 239, 112, 207, 59, 8, 1, 106, + 2, 239, 112, 52, 8, 1, 127, 239, 112, 206, 47, 8, 1, 210, 200, 8, 1, 210, + 198, 8, 1, 250, 48, 8, 1, 212, 116, 2, 218, 148, 8, 1, 212, 116, 2, 129, + 177, 84, 244, 6, 8, 1, 221, 157, 8, 1, 212, 113, 8, 1, 250, 36, 8, 1, + 140, 2, 239, 112, 52, 8, 1, 140, 2, 118, 177, 79, 52, 8, 1, 223, 131, 8, + 1, 243, 201, 8, 1, 140, 2, 129, 177, 52, 8, 1, 212, 135, 8, 1, 212, 133, + 8, 1, 246, 49, 8, 1, 246, 118, 2, 218, 148, 8, 1, 246, 118, 2, 67, 55, 8, + 1, 246, 118, 2, 67, 250, 26, 23, 5, 212, 194, 8, 1, 246, 124, 8, 1, 246, + 51, 8, 1, 243, 229, 8, 1, 246, 118, 2, 129, 177, 84, 244, 6, 8, 1, 246, + 118, 2, 241, 125, 177, 52, 8, 1, 218, 81, 8, 1, 219, 17, 2, 5, 209, 148, + 8, 1, 219, 17, 2, 218, 148, 8, 1, 219, 17, 2, 67, 55, 8, 1, 219, 17, 2, + 5, 209, 149, 55, 8, 1, 219, 17, 2, 67, 250, 26, 23, 67, 52, 8, 1, 219, + 17, 2, 118, 177, 52, 8, 1, 232, 176, 8, 1, 219, 17, 2, 241, 125, 177, 52, + 8, 1, 217, 71, 2, 67, 250, 26, 23, 67, 52, 8, 1, 217, 71, 2, 129, 177, + 55, 8, 1, 217, 71, 2, 129, 177, 250, 26, 23, 129, 177, 52, 8, 1, 217, + 192, 2, 118, 177, 55, 8, 1, 217, 192, 2, 129, 177, 52, 8, 1, 212, 195, 2, + 129, 177, 52, 8, 1, 252, 201, 2, 129, 177, 52, 8, 1, 245, 22, 242, 15, 8, + 1, 242, 16, 2, 67, 226, 122, 55, 8, 1, 242, 16, 2, 67, 55, 8, 1, 209, 32, + 8, 1, 242, 16, 2, 129, 177, 55, 8, 1, 221, 155, 8, 1, 220, 13, 2, 67, 52, + 8, 1, 220, 13, 2, 129, 177, 52, 8, 1, 231, 212, 8, 1, 213, 109, 232, 45, + 8, 1, 232, 46, 2, 218, 148, 8, 1, 232, 46, 2, 67, 52, 8, 1, 225, 79, 8, + 1, 232, 46, 2, 129, 177, 55, 8, 1, 240, 231, 8, 1, 240, 232, 2, 218, 148, + 8, 1, 225, 0, 8, 1, 240, 232, 2, 118, 177, 55, 8, 1, 239, 200, 8, 1, 240, + 232, 2, 129, 177, 52, 8, 1, 230, 107, 2, 5, 209, 148, 8, 1, 230, 107, 2, + 67, 52, 8, 1, 230, 107, 2, 129, 177, 52, 8, 1, 230, 107, 2, 129, 177, 55, + 8, 1, 224, 55, 2, 67, 55, 8, 1, 224, 55, 240, 65, 8, 1, 218, 127, 8, 1, + 224, 55, 2, 218, 148, 8, 1, 224, 55, 2, 129, 177, 52, 8, 1, 239, 51, 245, + 47, 8, 1, 212, 136, 2, 67, 52, 8, 1, 239, 51, 2, 87, 52, 8, 1, 239, 51, + 240, 16, 8, 1, 239, 51, 240, 17, 2, 239, 112, 52, 8, 1, 212, 116, 227, + 198, 240, 16, 8, 1, 207, 60, 2, 218, 148, 8, 1, 231, 101, 222, 206, 8, 1, + 222, 206, 8, 1, 71, 8, 1, 205, 213, 8, 1, 231, 101, 205, 213, 8, 1, 207, + 60, 2, 118, 177, 52, 8, 1, 209, 39, 8, 1, 242, 42, 206, 47, 8, 1, 87, 2, + 212, 191, 8, 1, 87, 2, 5, 209, 148, 8, 1, 207, 60, 2, 67, 52, 8, 1, 75, + 8, 1, 87, 2, 129, 177, 55, 8, 1, 87, 250, 121, 8, 1, 87, 250, 122, 2, + 239, 112, 52, 8, 241, 82, 213, 251, 8, 1, 252, 248, 8, 5, 127, 28, 217, + 192, 2, 230, 107, 2, 126, 227, 228, 8, 5, 127, 28, 220, 13, 2, 230, 107, + 2, 126, 227, 228, 8, 5, 127, 80, 78, 17, 8, 5, 127, 230, 107, 252, 172, + 8, 5, 127, 232, 179, 8, 5, 127, 129, 245, 21, 8, 5, 127, 217, 70, 8, 243, + 34, 73, 251, 158, 8, 214, 22, 73, 218, 48, 243, 69, 238, 240, 8, 5, 127, + 218, 93, 205, 85, 8, 5, 127, 209, 202, 219, 36, 205, 85, 8, 5, 127, 245, + 22, 239, 69, 73, 231, 163, 8, 5, 127, 80, 61, 17, 8, 5, 114, 217, 70, 8, + 5, 127, 228, 8, 8, 5, 207, 59, 8, 5, 206, 47, 8, 5, 127, 206, 47, 8, 5, + 127, 224, 54, 8, 220, 239, 73, 217, 177, 8, 243, 43, 248, 129, 114, 213, + 251, 8, 243, 43, 248, 129, 127, 213, 251, 8, 218, 93, 127, 213, 252, 2, + 241, 233, 248, 128, 8, 5, 114, 227, 104, 8, 1, 246, 118, 2, 233, 2, 209, + 148, 8, 1, 219, 17, 2, 233, 2, 209, 148, 242, 159, 252, 33, 18, 205, 85, + 242, 159, 252, 33, 18, 102, 242, 159, 252, 33, 18, 105, 242, 159, 252, + 33, 18, 142, 242, 159, 252, 33, 18, 139, 242, 159, 252, 33, 18, 168, 242, + 159, 252, 33, 18, 184, 242, 159, 252, 33, 18, 195, 242, 159, 252, 33, 18, + 193, 242, 159, 252, 33, 18, 200, 8, 1, 215, 211, 2, 67, 55, 8, 1, 246, + 141, 2, 67, 55, 8, 1, 240, 95, 2, 67, 55, 8, 3, 215, 44, 252, 125, 8, 3, + 215, 44, 220, 172, 227, 83, 8, 1, 239, 51, 2, 233, 2, 209, 148, 213, 30, + 243, 34, 73, 221, 228, 213, 30, 213, 135, 241, 82, 213, 251, 213, 30, + 213, 185, 241, 82, 213, 251, 213, 30, 213, 135, 247, 162, 213, 30, 213, + 185, 247, 162, 213, 30, 194, 247, 162, 213, 30, 247, 163, 214, 246, 230, + 46, 213, 30, 247, 163, 214, 246, 218, 167, 213, 30, 213, 135, 247, 163, + 214, 246, 230, 46, 213, 30, 213, 185, 247, 163, 214, 246, 218, 167, 213, + 30, 247, 111, 213, 30, 239, 92, 222, 224, 213, 30, 239, 92, 227, 60, 213, + 30, 239, 92, 251, 211, 213, 30, 253, 29, 83, 213, 30, 1, 252, 177, 213, + 30, 1, 213, 139, 252, 177, 213, 30, 1, 250, 7, 213, 30, 1, 240, 221, 213, + 30, 1, 240, 222, 240, 199, 213, 30, 1, 246, 114, 213, 30, 1, 245, 22, + 246, 115, 218, 143, 213, 30, 1, 239, 71, 213, 30, 1, 207, 59, 213, 30, 1, + 205, 108, 213, 30, 1, 239, 27, 213, 30, 1, 212, 76, 213, 30, 1, 212, 77, + 240, 199, 213, 30, 1, 205, 200, 213, 30, 1, 205, 201, 239, 71, 213, 30, + 1, 232, 17, 213, 30, 1, 230, 105, 213, 30, 1, 226, 211, 213, 30, 1, 223, + 173, 213, 30, 1, 216, 45, 213, 30, 1, 42, 216, 45, 213, 30, 1, 75, 213, + 30, 1, 221, 174, 213, 30, 1, 218, 224, 221, 174, 213, 30, 1, 217, 189, + 213, 30, 1, 220, 6, 213, 30, 1, 218, 143, 213, 30, 1, 215, 171, 213, 30, + 1, 212, 145, 213, 30, 1, 221, 116, 249, 250, 213, 30, 1, 221, 116, 240, + 92, 213, 30, 1, 221, 116, 245, 187, 213, 30, 220, 83, 52, 213, 30, 220, + 83, 55, 213, 30, 220, 83, 244, 20, 213, 30, 205, 13, 52, 213, 30, 205, + 13, 55, 213, 30, 205, 13, 244, 20, 213, 30, 219, 54, 52, 213, 30, 219, + 54, 55, 213, 30, 244, 21, 205, 20, 238, 121, 213, 30, 244, 21, 205, 20, + 252, 104, 213, 30, 239, 74, 52, 213, 30, 239, 74, 55, 213, 30, 239, 73, + 244, 20, 213, 30, 242, 219, 52, 213, 30, 242, 219, 55, 213, 30, 218, 16, + 213, 30, 242, 9, 245, 23, 213, 30, 219, 174, 213, 30, 218, 43, 213, 30, + 118, 79, 177, 52, 213, 30, 118, 79, 177, 55, 213, 30, 129, 177, 52, 213, + 30, 129, 177, 55, 213, 30, 222, 222, 229, 206, 52, 213, 30, 222, 222, + 229, 206, 55, 213, 30, 226, 64, 213, 30, 250, 120, 213, 30, 1, 214, 184, + 205, 79, 213, 30, 1, 214, 184, 231, 156, 213, 30, 1, 214, 184, 242, 28, + 8, 1, 250, 39, 2, 129, 177, 238, 71, 55, 8, 1, 250, 39, 2, 67, 250, 26, + 23, 129, 177, 52, 8, 1, 250, 39, 2, 129, 177, 220, 201, 167, 55, 8, 1, + 250, 39, 2, 129, 177, 220, 201, 167, 250, 26, 23, 118, 177, 52, 8, 1, + 250, 39, 2, 118, 177, 250, 26, 23, 67, 52, 8, 1, 250, 39, 2, 233, 2, 5, + 209, 149, 55, 8, 1, 250, 39, 2, 5, 209, 148, 8, 1, 140, 2, 118, 177, 52, + 8, 1, 140, 2, 129, 177, 220, 201, 167, 55, 8, 1, 246, 118, 2, 118, 177, + 208, 228, 250, 26, 23, 5, 212, 194, 8, 1, 246, 118, 2, 233, 2, 5, 209, + 149, 55, 8, 1, 219, 17, 2, 91, 8, 1, 217, 71, 2, 241, 125, 177, 52, 8, 1, + 252, 201, 2, 118, 177, 52, 8, 1, 252, 201, 2, 129, 177, 220, 201, 173, + 52, 8, 1, 252, 201, 2, 118, 177, 208, 228, 52, 8, 1, 242, 16, 2, 118, + 177, 55, 8, 1, 242, 16, 2, 129, 177, 220, 201, 167, 55, 8, 1, 231, 213, + 2, 67, 52, 8, 1, 231, 213, 2, 129, 177, 52, 8, 1, 231, 213, 2, 129, 177, + 220, 201, 167, 55, 8, 1, 80, 2, 67, 52, 8, 1, 80, 2, 67, 55, 8, 1, 224, + 55, 2, 118, 177, 55, 8, 1, 224, 55, 2, 5, 212, 194, 8, 1, 224, 55, 2, 5, + 209, 148, 8, 1, 230, 107, 2, 134, 8, 1, 219, 17, 2, 118, 177, 208, 228, + 52, 8, 1, 219, 17, 2, 239, 112, 52, 8, 1, 217, 71, 2, 118, 177, 208, 228, + 52, 8, 1, 140, 2, 5, 8, 1, 212, 195, 55, 8, 1, 140, 2, 5, 8, 1, 212, 195, + 23, 118, 245, 21, 8, 1, 217, 71, 2, 5, 8, 1, 212, 195, 23, 118, 245, 21, + 8, 1, 219, 17, 2, 5, 8, 1, 212, 195, 23, 118, 245, 21, 8, 1, 140, 2, 5, + 8, 1, 212, 195, 52, 8, 1, 126, 2, 242, 159, 252, 33, 18, 118, 52, 8, 1, + 126, 2, 242, 159, 252, 33, 18, 129, 52, 8, 1, 242, 42, 87, 2, 242, 159, + 252, 33, 18, 118, 52, 8, 1, 242, 42, 87, 2, 242, 159, 252, 33, 18, 129, + 52, 8, 1, 242, 42, 87, 2, 242, 159, 252, 33, 18, 241, 125, 55, 8, 1, 207, + 60, 2, 242, 159, 252, 33, 18, 118, 52, 8, 1, 207, 60, 2, 242, 159, 252, + 33, 18, 129, 52, 8, 1, 87, 250, 122, 2, 242, 159, 252, 33, 18, 118, 52, + 8, 1, 87, 250, 122, 2, 242, 159, 252, 33, 18, 129, 52, 8, 1, 140, 2, 242, + 159, 252, 33, 18, 241, 125, 55, 8, 1, 217, 71, 2, 242, 159, 252, 33, 18, + 241, 125, 52, 8, 1, 217, 71, 2, 233, 2, 209, 148, 8, 1, 232, 46, 2, 118, + 177, 52, 212, 53, 1, 239, 141, 212, 53, 1, 215, 220, 212, 53, 1, 224, 53, + 212, 53, 1, 219, 109, 212, 53, 1, 250, 181, 212, 53, 1, 229, 245, 212, + 53, 1, 232, 60, 212, 53, 1, 252, 161, 212, 53, 1, 209, 68, 212, 53, 1, + 227, 103, 212, 53, 1, 242, 71, 212, 53, 1, 245, 190, 212, 53, 1, 212, 55, + 212, 53, 1, 230, 137, 212, 53, 1, 240, 240, 212, 53, 1, 240, 22, 212, 53, + 1, 217, 69, 212, 53, 1, 246, 70, 212, 53, 1, 205, 99, 212, 53, 1, 212, + 146, 212, 53, 1, 206, 109, 212, 53, 1, 221, 187, 212, 53, 1, 232, 186, + 212, 53, 1, 248, 85, 212, 53, 1, 210, 207, 212, 53, 1, 239, 19, 212, 53, + 1, 231, 166, 212, 53, 1, 212, 54, 212, 53, 1, 205, 115, 212, 53, 1, 215, + 209, 212, 53, 1, 217, 195, 212, 53, 1, 246, 143, 212, 53, 1, 124, 212, + 53, 1, 205, 19, 212, 53, 1, 252, 197, 212, 53, 1, 240, 93, 212, 53, 1, + 220, 16, 212, 53, 1, 207, 94, 212, 53, 253, 31, 212, 53, 253, 129, 212, + 53, 237, 184, 212, 53, 243, 103, 212, 53, 210, 11, 212, 53, 222, 151, + 212, 53, 243, 111, 212, 53, 242, 151, 212, 53, 222, 221, 212, 53, 222, + 229, 212, 53, 213, 162, 212, 53, 1, 225, 232, 224, 131, 18, 205, 85, 224, + 131, 18, 102, 224, 131, 18, 105, 224, 131, 18, 142, 224, 131, 18, 139, + 224, 131, 18, 168, 224, 131, 18, 184, 224, 131, 18, 195, 224, 131, 18, + 193, 224, 131, 18, 200, 224, 131, 1, 62, 224, 131, 1, 243, 104, 224, 131, + 1, 74, 224, 131, 1, 75, 224, 131, 1, 71, 224, 131, 1, 222, 152, 224, 131, + 1, 76, 224, 131, 1, 246, 132, 224, 131, 1, 226, 33, 224, 131, 1, 250, + 183, 224, 131, 1, 179, 224, 131, 1, 212, 219, 224, 131, 1, 232, 200, 224, + 131, 1, 248, 110, 224, 131, 1, 246, 145, 224, 131, 1, 219, 113, 224, 131, + 1, 218, 89, 224, 131, 1, 217, 199, 224, 131, 1, 240, 187, 224, 131, 1, + 242, 73, 224, 131, 1, 172, 224, 131, 1, 230, 141, 224, 131, 1, 225, 237, + 206, 246, 224, 131, 1, 185, 224, 131, 1, 223, 144, 224, 131, 1, 199, 224, + 131, 1, 155, 224, 131, 1, 207, 96, 224, 131, 1, 190, 224, 131, 1, 223, + 145, 206, 246, 224, 131, 1, 232, 115, 232, 200, 224, 131, 1, 232, 115, + 248, 110, 224, 131, 1, 232, 115, 219, 113, 224, 131, 36, 215, 144, 127, + 211, 118, 224, 131, 36, 215, 144, 114, 211, 118, 224, 131, 36, 215, 144, + 218, 142, 211, 118, 224, 131, 36, 152, 245, 210, 211, 118, 224, 131, 36, + 152, 127, 211, 118, 224, 131, 36, 152, 114, 211, 118, 224, 131, 36, 152, + 218, 142, 211, 118, 224, 131, 36, 225, 197, 83, 224, 131, 36, 50, 67, 52, + 224, 131, 127, 135, 252, 53, 224, 131, 114, 135, 252, 53, 224, 131, 16, + 222, 153, 245, 223, 224, 131, 16, 240, 186, 224, 131, 247, 155, 224, 131, + 242, 168, 83, 224, 131, 230, 112, 217, 160, 1, 252, 179, 217, 160, 1, + 249, 209, 217, 160, 1, 240, 220, 217, 160, 1, 246, 116, 217, 160, 1, 232, + 211, 217, 160, 1, 250, 181, 217, 160, 1, 205, 88, 217, 160, 1, 232, 220, + 217, 160, 1, 211, 156, 217, 160, 1, 205, 182, 217, 160, 1, 232, 61, 217, + 160, 1, 230, 134, 217, 160, 1, 226, 211, 217, 160, 1, 223, 173, 217, 160, + 1, 215, 42, 217, 160, 1, 233, 68, 217, 160, 1, 241, 250, 217, 160, 1, + 210, 241, 217, 160, 1, 219, 193, 217, 160, 1, 218, 143, 217, 160, 1, 215, + 237, 217, 160, 1, 212, 214, 217, 160, 141, 233, 68, 217, 160, 141, 233, + 67, 217, 160, 141, 222, 217, 217, 160, 141, 246, 130, 217, 160, 65, 1, + 242, 249, 205, 182, 217, 160, 141, 242, 249, 205, 182, 217, 160, 22, 3, + 152, 75, 217, 160, 22, 3, 75, 217, 160, 22, 3, 222, 80, 253, 164, 217, + 160, 22, 3, 152, 253, 164, 217, 160, 22, 3, 253, 164, 217, 160, 22, 3, + 222, 80, 62, 217, 160, 22, 3, 152, 62, 217, 160, 22, 3, 62, 217, 160, 65, + 1, 215, 144, 62, 217, 160, 22, 3, 215, 144, 62, 217, 160, 22, 3, 152, 71, + 217, 160, 22, 3, 71, 217, 160, 65, 1, 74, 217, 160, 22, 3, 152, 74, 217, + 160, 22, 3, 74, 217, 160, 22, 3, 76, 217, 160, 22, 3, 213, 162, 217, 160, + 141, 225, 94, 217, 160, 220, 72, 225, 94, 217, 160, 220, 72, 252, 222, + 217, 160, 220, 72, 252, 113, 217, 160, 220, 72, 250, 101, 217, 160, 220, + 72, 251, 194, 217, 160, 220, 72, 215, 159, 217, 160, 253, 29, 83, 217, + 160, 220, 72, 227, 93, 219, 229, 217, 160, 220, 72, 205, 27, 217, 160, + 220, 72, 219, 229, 217, 160, 220, 72, 205, 114, 217, 160, 220, 72, 210, + 140, 217, 160, 220, 72, 252, 4, 217, 160, 220, 72, 214, 188, 227, 176, + 217, 160, 220, 72, 252, 99, 227, 217, 1, 239, 118, 227, 217, 1, 253, 115, + 227, 217, 1, 252, 220, 227, 217, 1, 253, 5, 227, 217, 1, 252, 213, 227, + 217, 1, 209, 168, 227, 217, 1, 251, 152, 227, 217, 1, 232, 220, 227, 217, + 1, 251, 191, 227, 217, 1, 252, 184, 227, 217, 1, 252, 189, 227, 217, 1, + 252, 181, 227, 217, 1, 252, 136, 227, 217, 1, 252, 122, 227, 217, 1, 251, + 231, 227, 217, 1, 233, 68, 227, 217, 1, 252, 68, 227, 217, 1, 251, 201, + 227, 217, 1, 252, 41, 227, 217, 1, 252, 37, 227, 217, 1, 251, 225, 227, + 217, 1, 251, 199, 227, 217, 1, 243, 214, 227, 217, 1, 232, 53, 227, 217, + 1, 252, 200, 227, 217, 252, 226, 83, 227, 217, 208, 171, 83, 227, 217, + 240, 159, 83, 227, 217, 220, 71, 8, 1, 250, 39, 2, 5, 209, 149, 55, 8, 1, + 250, 39, 2, 239, 112, 52, 8, 1, 171, 2, 118, 177, 52, 8, 1, 212, 195, 2, + 118, 177, 52, 8, 1, 242, 16, 2, 67, 250, 26, 23, 129, 177, 52, 8, 1, 220, + 13, 2, 67, 55, 8, 1, 230, 107, 2, 50, 134, 8, 1, 80, 2, 129, 177, 52, 8, + 1, 87, 2, 118, 177, 250, 26, 23, 239, 112, 52, 8, 1, 87, 2, 118, 177, + 250, 26, 23, 67, 52, 8, 1, 219, 17, 2, 229, 111, 8, 1, 207, 60, 2, 67, + 206, 254, 8, 1, 218, 113, 206, 47, 8, 1, 114, 252, 172, 8, 1, 246, 118, + 2, 129, 177, 55, 8, 1, 217, 192, 2, 129, 177, 55, 8, 1, 240, 232, 2, 233, + 2, 91, 8, 1, 213, 243, 207, 59, 8, 1, 205, 109, 2, 233, 2, 209, 149, 52, + 8, 247, 26, 242, 39, 8, 247, 26, 246, 106, 8, 247, 26, 231, 252, 8, 247, + 26, 242, 37, 8, 247, 26, 246, 104, 8, 247, 26, 231, 250, 8, 135, 119, 67, + 52, 8, 135, 118, 177, 52, 8, 135, 229, 112, 52, 8, 135, 119, 67, 55, 8, + 135, 118, 177, 55, 8, 135, 229, 112, 55, 8, 222, 142, 242, 37, 8, 222, + 142, 246, 104, 8, 222, 142, 231, 250, 8, 5, 127, 207, 59, 8, 242, 40, 2, + 218, 148, 8, 242, 40, 2, 67, 52, 8, 231, 253, 2, 67, 55, 8, 47, 251, 244, + 52, 8, 48, 251, 244, 52, 8, 47, 251, 244, 55, 8, 48, 251, 244, 55, 8, 50, + 48, 251, 244, 52, 8, 50, 48, 251, 244, 84, 2, 245, 23, 8, 48, 251, 244, + 84, 2, 245, 23, 8, 246, 107, 2, 245, 23, 8, 141, 215, 73, 224, 55, 240, + 65, 89, 3, 233, 2, 248, 217, 89, 3, 248, 217, 89, 3, 252, 73, 89, 3, 208, + 183, 89, 1, 215, 144, 62, 89, 1, 62, 89, 1, 253, 164, 89, 1, 74, 89, 1, + 233, 102, 89, 1, 71, 89, 1, 209, 162, 89, 1, 115, 137, 89, 1, 115, 149, + 89, 1, 248, 220, 75, 89, 1, 215, 144, 75, 89, 1, 75, 89, 1, 252, 205, 89, + 1, 248, 220, 76, 89, 1, 215, 144, 76, 89, 1, 76, 89, 1, 251, 184, 89, 1, + 172, 89, 1, 231, 167, 89, 1, 240, 244, 89, 1, 240, 99, 89, 1, 225, 77, + 89, 1, 249, 1, 89, 1, 248, 110, 89, 1, 232, 200, 89, 1, 232, 170, 89, 1, + 223, 144, 89, 1, 210, 208, 89, 1, 210, 196, 89, 1, 246, 54, 89, 1, 246, + 38, 89, 1, 224, 103, 89, 1, 212, 219, 89, 1, 212, 56, 89, 1, 246, 145, + 89, 1, 245, 192, 89, 1, 199, 89, 1, 224, 85, 89, 1, 179, 89, 1, 221, 93, + 89, 1, 250, 183, 89, 1, 250, 0, 89, 1, 185, 89, 1, 190, 89, 1, 219, 113, + 89, 1, 218, 89, 89, 1, 230, 141, 89, 1, 229, 172, 89, 1, 229, 163, 89, 1, + 209, 70, 89, 1, 216, 2, 89, 1, 214, 96, 89, 1, 217, 199, 89, 1, 155, 89, + 22, 3, 222, 206, 89, 22, 3, 222, 150, 89, 3, 223, 184, 89, 3, 251, 167, + 89, 22, 3, 253, 164, 89, 22, 3, 74, 89, 22, 3, 233, 102, 89, 22, 3, 71, + 89, 22, 3, 209, 162, 89, 22, 3, 115, 137, 89, 22, 3, 115, 218, 90, 89, + 22, 3, 248, 220, 75, 89, 22, 3, 215, 144, 75, 89, 22, 3, 75, 89, 22, 3, + 252, 205, 89, 22, 3, 248, 220, 76, 89, 22, 3, 215, 144, 76, 89, 22, 3, + 76, 89, 22, 3, 251, 184, 89, 3, 208, 188, 89, 22, 3, 220, 120, 75, 89, + 22, 3, 251, 163, 89, 222, 173, 89, 213, 233, 3, 210, 5, 89, 213, 233, 3, + 252, 75, 89, 239, 237, 253, 21, 89, 253, 9, 253, 21, 89, 22, 3, 248, 220, + 152, 75, 89, 22, 3, 210, 3, 89, 22, 3, 209, 161, 89, 1, 220, 19, 89, 1, + 231, 148, 89, 1, 240, 74, 89, 1, 205, 116, 89, 1, 246, 43, 89, 1, 218, + 212, 89, 1, 242, 73, 89, 1, 205, 168, 89, 1, 115, 218, 90, 89, 1, 115, + 229, 173, 89, 22, 3, 115, 149, 89, 22, 3, 115, 229, 173, 89, 246, 100, + 89, 50, 246, 100, 89, 18, 205, 85, 89, 18, 102, 89, 18, 105, 89, 18, 142, + 89, 18, 139, 89, 18, 168, 89, 18, 184, 89, 18, 195, 89, 18, 193, 89, 18, + 200, 89, 253, 29, 53, 89, 3, 127, 214, 152, 245, 23, 89, 1, 248, 220, 62, + 89, 1, 222, 206, 89, 1, 222, 150, 89, 1, 251, 163, 89, 1, 210, 3, 89, 1, + 209, 161, 89, 1, 227, 181, 246, 54, 89, 1, 205, 81, 89, 1, 77, 190, 89, + 1, 240, 135, 89, 1, 232, 150, 89, 1, 240, 25, 213, 251, 89, 1, 246, 44, + 89, 1, 250, 97, 165, 252, 102, 165, 3, 248, 217, 165, 3, 252, 73, 165, 3, + 208, 183, 165, 1, 62, 165, 1, 253, 164, 165, 1, 74, 165, 1, 233, 102, + 165, 1, 71, 165, 1, 209, 162, 165, 1, 115, 137, 165, 1, 115, 149, 165, 1, + 75, 165, 1, 252, 205, 165, 1, 76, 165, 1, 251, 184, 165, 1, 172, 165, 1, + 231, 167, 165, 1, 240, 244, 165, 1, 240, 99, 165, 1, 225, 77, 165, 1, + 249, 1, 165, 1, 248, 110, 165, 1, 232, 200, 165, 1, 232, 170, 165, 1, + 223, 144, 165, 1, 210, 208, 165, 1, 210, 196, 165, 1, 246, 54, 165, 1, + 246, 38, 165, 1, 224, 103, 165, 1, 212, 219, 165, 1, 212, 56, 165, 1, + 246, 145, 165, 1, 245, 192, 165, 1, 199, 165, 1, 179, 165, 1, 221, 93, + 165, 1, 250, 183, 165, 1, 250, 0, 165, 1, 185, 165, 1, 190, 165, 1, 219, + 113, 165, 1, 230, 141, 165, 1, 216, 2, 165, 1, 214, 96, 165, 1, 217, 199, + 165, 1, 155, 165, 3, 223, 184, 165, 3, 251, 167, 165, 22, 3, 253, 164, + 165, 22, 3, 74, 165, 22, 3, 233, 102, 165, 22, 3, 71, 165, 22, 3, 209, + 162, 165, 22, 3, 115, 137, 165, 22, 3, 115, 218, 90, 165, 22, 3, 75, 165, + 22, 3, 252, 205, 165, 22, 3, 76, 165, 22, 3, 251, 184, 165, 3, 208, 188, + 165, 1, 231, 158, 212, 219, 165, 251, 185, 230, 20, 83, 165, 1, 218, 89, + 165, 1, 218, 212, 165, 1, 205, 168, 165, 1, 115, 218, 90, 165, 1, 115, + 229, 173, 165, 22, 3, 115, 149, 165, 22, 3, 115, 229, 173, 165, 18, 205, + 85, 165, 18, 102, 165, 18, 105, 165, 18, 142, 165, 18, 139, 165, 18, 168, + 165, 18, 184, 165, 18, 195, 165, 18, 193, 165, 18, 200, 165, 1, 219, 114, + 2, 226, 247, 245, 162, 165, 1, 219, 114, 2, 229, 92, 245, 162, 165, 218, + 27, 83, 165, 218, 27, 53, 165, 247, 25, 223, 176, 102, 165, 247, 25, 223, + 176, 105, 165, 247, 25, 223, 176, 142, 165, 247, 25, 223, 176, 139, 165, + 247, 25, 223, 176, 119, 230, 11, 212, 47, 212, 42, 245, 221, 165, 247, + 25, 245, 222, 215, 4, 165, 232, 221, 165, 240, 211, 83, 239, 182, 3, 253, + 4, 249, 224, 239, 182, 3, 249, 224, 239, 182, 3, 208, 183, 239, 182, 1, + 62, 239, 182, 1, 253, 164, 239, 182, 1, 74, 239, 182, 1, 233, 102, 239, + 182, 1, 71, 239, 182, 1, 209, 162, 239, 182, 1, 243, 104, 239, 182, 1, + 252, 205, 239, 182, 1, 222, 152, 239, 182, 1, 251, 184, 239, 182, 1, 172, + 239, 182, 1, 231, 167, 239, 182, 1, 240, 244, 239, 182, 1, 240, 99, 239, + 182, 1, 225, 77, 239, 182, 1, 249, 1, 239, 182, 1, 248, 110, 239, 182, 1, + 232, 200, 239, 182, 1, 232, 170, 239, 182, 1, 223, 144, 239, 182, 1, 210, + 208, 239, 182, 1, 210, 196, 239, 182, 1, 246, 54, 239, 182, 1, 246, 38, + 239, 182, 1, 224, 103, 239, 182, 1, 212, 219, 239, 182, 1, 212, 56, 239, + 182, 1, 246, 145, 239, 182, 1, 245, 192, 239, 182, 1, 199, 239, 182, 1, + 179, 239, 182, 1, 221, 93, 239, 182, 1, 250, 183, 239, 182, 1, 250, 0, + 239, 182, 1, 185, 239, 182, 1, 190, 239, 182, 1, 219, 113, 239, 182, 1, + 230, 141, 239, 182, 1, 229, 172, 239, 182, 1, 209, 70, 239, 182, 1, 216, + 2, 239, 182, 1, 217, 199, 239, 182, 1, 155, 239, 182, 3, 223, 184, 239, + 182, 22, 3, 253, 164, 239, 182, 22, 3, 74, 239, 182, 22, 3, 233, 102, + 239, 182, 22, 3, 71, 239, 182, 22, 3, 209, 162, 239, 182, 22, 3, 243, + 104, 239, 182, 22, 3, 252, 205, 239, 182, 22, 3, 222, 152, 239, 182, 22, + 3, 251, 184, 239, 182, 3, 208, 188, 239, 182, 3, 210, 7, 239, 182, 1, + 231, 148, 239, 182, 1, 240, 74, 239, 182, 1, 205, 116, 239, 182, 1, 218, + 89, 239, 182, 1, 242, 73, 239, 182, 18, 205, 85, 239, 182, 18, 102, 239, + 182, 18, 105, 239, 182, 18, 142, 239, 182, 18, 139, 239, 182, 18, 168, + 239, 182, 18, 184, 239, 182, 18, 195, 239, 182, 18, 193, 239, 182, 18, + 200, 239, 182, 211, 164, 239, 182, 253, 3, 239, 182, 232, 241, 239, 182, + 209, 190, 239, 182, 243, 76, 222, 157, 239, 182, 3, 206, 84, 198, 3, 248, + 217, 198, 3, 252, 73, 198, 3, 208, 183, 198, 1, 62, 198, 1, 253, 164, + 198, 1, 74, 198, 1, 233, 102, 198, 1, 71, 198, 1, 209, 162, 198, 1, 115, + 137, 198, 1, 115, 149, 198, 22, 248, 220, 75, 198, 1, 75, 198, 1, 252, + 205, 198, 22, 248, 220, 76, 198, 1, 76, 198, 1, 251, 184, 198, 1, 172, + 198, 1, 231, 167, 198, 1, 240, 244, 198, 1, 240, 99, 198, 1, 225, 77, + 198, 1, 249, 1, 198, 1, 248, 110, 198, 1, 232, 200, 198, 1, 232, 170, + 198, 1, 223, 144, 198, 1, 210, 208, 198, 1, 210, 196, 198, 1, 246, 54, + 198, 1, 246, 38, 198, 1, 224, 103, 198, 1, 212, 219, 198, 1, 212, 56, + 198, 1, 246, 145, 198, 1, 245, 192, 198, 1, 199, 198, 1, 179, 198, 1, + 221, 93, 198, 1, 250, 183, 198, 1, 250, 0, 198, 1, 185, 198, 1, 190, 198, + 1, 219, 113, 198, 1, 230, 141, 198, 1, 229, 172, 198, 1, 209, 70, 198, 1, + 216, 2, 198, 1, 214, 96, 198, 1, 217, 199, 198, 1, 155, 198, 3, 223, 184, + 198, 3, 251, 167, 198, 22, 3, 253, 164, 198, 22, 3, 74, 198, 22, 3, 233, + 102, 198, 22, 3, 71, 198, 22, 3, 209, 162, 198, 22, 3, 115, 137, 198, 22, + 3, 115, 218, 90, 198, 22, 3, 248, 220, 75, 198, 22, 3, 75, 198, 22, 3, + 252, 205, 198, 22, 3, 248, 220, 76, 198, 22, 3, 76, 198, 22, 3, 251, 184, + 198, 3, 208, 188, 198, 222, 173, 198, 1, 115, 218, 90, 198, 1, 115, 229, + 173, 198, 22, 3, 115, 149, 198, 22, 3, 115, 229, 173, 198, 18, 205, 85, + 198, 18, 102, 198, 18, 105, 198, 18, 142, 198, 18, 139, 198, 18, 168, + 198, 18, 184, 198, 18, 195, 198, 18, 193, 198, 18, 200, 198, 253, 29, 53, + 198, 218, 27, 53, 178, 3, 248, 217, 178, 3, 252, 73, 178, 3, 208, 183, + 178, 1, 62, 178, 1, 253, 164, 178, 1, 74, 178, 1, 233, 102, 178, 1, 71, + 178, 1, 209, 162, 178, 1, 115, 137, 178, 1, 115, 149, 178, 1, 75, 178, 1, + 252, 205, 178, 1, 76, 178, 1, 251, 184, 178, 1, 172, 178, 1, 231, 167, + 178, 1, 240, 244, 178, 1, 240, 99, 178, 1, 225, 77, 178, 1, 249, 1, 178, + 1, 248, 110, 178, 1, 232, 200, 178, 1, 232, 170, 178, 1, 223, 144, 178, + 1, 210, 208, 178, 1, 210, 196, 178, 1, 246, 54, 178, 1, 246, 38, 178, 1, + 224, 103, 178, 1, 212, 219, 178, 1, 212, 56, 178, 1, 246, 145, 178, 1, + 245, 192, 178, 1, 199, 178, 1, 179, 178, 1, 221, 93, 178, 1, 250, 183, + 178, 1, 250, 0, 178, 1, 185, 178, 1, 190, 178, 1, 219, 113, 178, 1, 230, + 141, 178, 1, 229, 172, 178, 1, 209, 70, 178, 1, 216, 2, 178, 1, 214, 96, + 178, 1, 217, 199, 178, 1, 155, 178, 3, 223, 184, 178, 3, 251, 167, 178, + 22, 3, 253, 164, 178, 22, 3, 74, 178, 22, 3, 233, 102, 178, 22, 3, 71, + 178, 22, 3, 209, 162, 178, 22, 3, 115, 137, 178, 22, 3, 115, 218, 90, + 178, 22, 3, 75, 178, 22, 3, 252, 205, 178, 22, 3, 76, 178, 22, 3, 251, + 184, 178, 3, 208, 188, 178, 252, 206, 230, 20, 83, 178, 251, 185, 230, + 20, 83, 178, 1, 218, 89, 178, 1, 218, 212, 178, 1, 205, 168, 178, 1, 115, + 218, 90, 178, 1, 115, 229, 173, 178, 22, 3, 115, 149, 178, 22, 3, 115, + 229, 173, 178, 18, 205, 85, 178, 18, 102, 178, 18, 105, 178, 18, 142, + 178, 18, 139, 178, 18, 168, 178, 18, 184, 178, 18, 195, 178, 18, 193, + 178, 18, 200, 178, 232, 221, 178, 1, 207, 96, 178, 241, 116, 119, 219, + 204, 178, 241, 116, 119, 239, 121, 178, 241, 116, 129, 219, 202, 178, + 241, 116, 119, 215, 2, 178, 241, 116, 119, 243, 83, 178, 241, 116, 129, + 215, 1, 40, 3, 252, 73, 40, 3, 208, 183, 40, 1, 62, 40, 1, 253, 164, 40, + 1, 74, 40, 1, 233, 102, 40, 1, 71, 40, 1, 209, 162, 40, 1, 75, 40, 1, + 243, 104, 40, 1, 252, 205, 40, 1, 76, 40, 1, 222, 152, 40, 1, 251, 184, + 40, 1, 172, 40, 1, 225, 77, 40, 1, 249, 1, 40, 1, 232, 200, 40, 1, 223, + 144, 40, 1, 210, 208, 40, 1, 224, 103, 40, 1, 212, 219, 40, 1, 199, 40, + 1, 224, 85, 40, 1, 179, 40, 1, 185, 40, 1, 190, 40, 1, 219, 113, 40, 1, + 218, 89, 40, 1, 230, 141, 40, 1, 229, 172, 40, 1, 229, 163, 40, 1, 209, + 70, 40, 1, 216, 2, 40, 1, 214, 96, 40, 1, 217, 199, 40, 1, 155, 40, 22, + 3, 253, 164, 40, 22, 3, 74, 40, 22, 3, 233, 102, 40, 22, 3, 71, 40, 22, + 3, 209, 162, 40, 22, 3, 75, 40, 22, 3, 243, 104, 40, 22, 3, 252, 205, 40, + 22, 3, 76, 40, 22, 3, 222, 152, 40, 22, 3, 251, 184, 40, 3, 208, 188, 40, + 222, 173, 40, 251, 185, 230, 20, 83, 40, 18, 205, 85, 40, 18, 102, 40, + 18, 105, 40, 18, 142, 40, 18, 139, 40, 18, 168, 40, 18, 184, 40, 18, 195, + 40, 18, 193, 40, 18, 200, 40, 43, 212, 98, 40, 43, 119, 238, 29, 40, 43, + 119, 211, 242, 40, 246, 67, 53, 40, 226, 153, 53, 40, 206, 50, 53, 40, + 246, 6, 53, 40, 247, 68, 53, 40, 251, 232, 84, 53, 40, 218, 27, 53, 40, + 43, 53, 163, 3, 36, 248, 218, 52, 163, 3, 248, 217, 163, 3, 252, 73, 163, + 3, 208, 183, 163, 1, 62, 163, 1, 253, 164, 163, 1, 74, 163, 1, 233, 102, + 163, 1, 71, 163, 1, 209, 162, 163, 1, 115, 137, 163, 1, 115, 149, 163, 1, + 75, 163, 1, 243, 104, 163, 1, 252, 205, 163, 1, 76, 163, 1, 222, 152, + 163, 1, 251, 184, 163, 1, 172, 163, 1, 231, 167, 163, 1, 240, 244, 163, + 1, 240, 99, 163, 1, 225, 77, 163, 1, 249, 1, 163, 1, 248, 110, 163, 1, + 232, 200, 163, 1, 232, 170, 163, 1, 223, 144, 163, 1, 210, 208, 163, 1, + 210, 196, 163, 1, 246, 54, 163, 1, 246, 38, 163, 1, 224, 103, 163, 1, + 212, 219, 163, 1, 212, 56, 163, 1, 246, 145, 163, 1, 245, 192, 163, 1, + 199, 163, 1, 179, 163, 1, 221, 93, 163, 1, 250, 183, 163, 1, 250, 0, 163, + 1, 185, 163, 1, 190, 163, 1, 219, 113, 163, 1, 218, 89, 163, 1, 230, 141, + 163, 1, 229, 172, 163, 1, 229, 163, 163, 1, 209, 70, 163, 1, 216, 2, 163, + 1, 214, 96, 163, 1, 217, 199, 163, 1, 155, 163, 3, 251, 167, 163, 22, 3, + 253, 164, 163, 22, 3, 74, 163, 22, 3, 233, 102, 163, 22, 3, 71, 163, 22, + 3, 209, 162, 163, 22, 3, 115, 137, 163, 22, 3, 115, 218, 90, 163, 22, 3, + 75, 163, 22, 3, 243, 104, 163, 22, 3, 252, 205, 163, 22, 3, 76, 163, 22, + 3, 222, 152, 163, 22, 3, 251, 184, 163, 3, 208, 188, 163, 230, 20, 83, + 163, 252, 206, 230, 20, 83, 163, 1, 210, 243, 163, 1, 243, 196, 163, 1, + 115, 218, 90, 163, 1, 115, 229, 173, 163, 22, 3, 115, 149, 163, 22, 3, + 115, 229, 173, 163, 18, 205, 85, 163, 18, 102, 163, 18, 105, 163, 18, + 142, 163, 18, 139, 163, 18, 168, 163, 18, 184, 163, 18, 195, 163, 18, + 193, 163, 18, 200, 163, 241, 116, 18, 205, 86, 33, 222, 210, 220, 160, + 73, 139, 163, 241, 116, 18, 119, 33, 222, 210, 220, 160, 73, 139, 163, + 241, 116, 18, 118, 33, 222, 210, 220, 160, 73, 139, 163, 241, 116, 18, + 129, 33, 222, 210, 220, 160, 73, 139, 163, 241, 116, 18, 119, 33, 242, + 179, 220, 160, 73, 139, 163, 241, 116, 18, 118, 33, 242, 179, 220, 160, + 73, 139, 163, 241, 116, 18, 129, 33, 242, 179, 220, 160, 73, 139, 163, 3, + 210, 134, 183, 3, 248, 217, 183, 3, 252, 73, 183, 3, 208, 183, 183, 1, + 62, 183, 1, 253, 164, 183, 1, 74, 183, 1, 233, 102, 183, 1, 71, 183, 1, + 209, 162, 183, 1, 115, 137, 183, 1, 115, 149, 183, 1, 75, 183, 1, 243, + 104, 183, 1, 252, 205, 183, 1, 76, 183, 1, 222, 152, 183, 1, 251, 184, + 183, 1, 172, 183, 1, 231, 167, 183, 1, 240, 244, 183, 1, 240, 99, 183, 1, + 225, 77, 183, 1, 249, 1, 183, 1, 248, 110, 183, 1, 232, 200, 183, 1, 232, + 170, 183, 1, 223, 144, 183, 1, 210, 208, 183, 1, 210, 196, 183, 1, 246, + 54, 183, 1, 246, 38, 183, 1, 224, 103, 183, 1, 212, 219, 183, 1, 212, 56, + 183, 1, 246, 145, 183, 1, 245, 192, 183, 1, 199, 183, 1, 179, 183, 1, + 221, 93, 183, 1, 250, 183, 183, 1, 250, 0, 183, 1, 185, 183, 1, 190, 183, + 1, 219, 113, 183, 1, 218, 89, 183, 1, 230, 141, 183, 1, 229, 172, 183, 1, + 209, 70, 183, 1, 216, 2, 183, 1, 214, 96, 183, 1, 217, 199, 183, 1, 155, + 183, 3, 223, 184, 183, 3, 251, 167, 183, 22, 3, 253, 164, 183, 22, 3, 74, + 183, 22, 3, 233, 102, 183, 22, 3, 71, 183, 22, 3, 209, 162, 183, 22, 3, + 115, 137, 183, 22, 3, 115, 218, 90, 183, 22, 3, 75, 183, 22, 3, 243, 104, + 183, 22, 3, 252, 205, 183, 22, 3, 76, 183, 22, 3, 222, 152, 183, 22, 3, + 251, 184, 183, 3, 208, 188, 183, 230, 20, 83, 183, 252, 206, 230, 20, 83, + 183, 1, 242, 73, 183, 1, 115, 218, 90, 183, 1, 115, 229, 173, 183, 22, 3, + 115, 149, 183, 22, 3, 115, 229, 173, 183, 18, 205, 85, 183, 18, 102, 183, + 18, 105, 183, 18, 142, 183, 18, 139, 183, 18, 168, 183, 18, 184, 183, 18, + 195, 183, 18, 193, 183, 18, 200, 183, 3, 232, 156, 183, 3, 209, 204, 156, + 3, 248, 217, 156, 3, 252, 73, 156, 3, 208, 183, 156, 1, 62, 156, 1, 253, + 164, 156, 1, 74, 156, 1, 233, 102, 156, 1, 71, 156, 1, 209, 162, 156, 1, + 115, 137, 156, 1, 115, 149, 156, 1, 75, 156, 1, 243, 104, 156, 1, 252, + 205, 156, 1, 76, 156, 1, 222, 152, 156, 1, 251, 184, 156, 1, 172, 156, 1, + 231, 167, 156, 1, 240, 244, 156, 1, 240, 99, 156, 1, 225, 77, 156, 1, + 249, 1, 156, 1, 248, 110, 156, 1, 232, 200, 156, 1, 232, 170, 156, 1, + 223, 144, 156, 1, 210, 208, 156, 1, 210, 196, 156, 1, 246, 54, 156, 1, + 246, 38, 156, 1, 224, 103, 156, 1, 212, 219, 156, 1, 212, 56, 156, 1, + 246, 145, 156, 1, 245, 192, 156, 1, 199, 156, 1, 224, 85, 156, 1, 179, + 156, 1, 221, 93, 156, 1, 250, 183, 156, 1, 250, 0, 156, 1, 185, 156, 1, + 190, 156, 1, 219, 113, 156, 1, 218, 89, 156, 1, 230, 141, 156, 1, 229, + 172, 156, 1, 229, 163, 156, 1, 209, 70, 156, 1, 216, 2, 156, 1, 214, 96, + 156, 1, 217, 199, 156, 1, 155, 156, 1, 210, 177, 156, 3, 251, 167, 156, + 22, 3, 253, 164, 156, 22, 3, 74, 156, 22, 3, 233, 102, 156, 22, 3, 71, + 156, 22, 3, 209, 162, 156, 22, 3, 115, 137, 156, 22, 3, 115, 218, 90, + 156, 22, 3, 75, 156, 22, 3, 243, 104, 156, 22, 3, 252, 205, 156, 22, 3, + 76, 156, 22, 3, 222, 152, 156, 22, 3, 251, 184, 156, 3, 208, 188, 156, 1, + 67, 218, 248, 156, 251, 185, 230, 20, 83, 156, 1, 115, 218, 90, 156, 1, + 115, 229, 173, 156, 22, 3, 115, 149, 156, 22, 3, 115, 229, 173, 156, 18, + 205, 85, 156, 18, 102, 156, 18, 105, 156, 18, 142, 156, 18, 139, 156, 18, + 168, 156, 18, 184, 156, 18, 195, 156, 18, 193, 156, 18, 200, 156, 43, + 212, 98, 156, 43, 119, 238, 29, 156, 43, 119, 211, 242, 156, 241, 116, + 119, 219, 204, 156, 241, 116, 119, 239, 121, 156, 241, 116, 129, 219, + 202, 156, 246, 72, 83, 156, 1, 248, 47, 224, 104, 156, 1, 248, 47, 226, + 33, 156, 1, 248, 47, 218, 90, 156, 1, 248, 47, 149, 156, 1, 248, 47, 229, + 173, 156, 1, 248, 47, 232, 76, 132, 3, 252, 72, 132, 3, 208, 182, 132, 1, + 251, 157, 132, 1, 253, 118, 132, 1, 252, 228, 132, 1, 252, 243, 132, 1, + 232, 210, 132, 1, 233, 101, 132, 1, 209, 153, 132, 1, 209, 156, 132, 1, + 232, 236, 132, 1, 232, 237, 132, 1, 233, 87, 132, 1, 233, 89, 132, 1, + 242, 152, 132, 1, 243, 99, 132, 1, 252, 191, 132, 1, 222, 70, 132, 1, + 222, 145, 132, 1, 251, 170, 132, 1, 252, 147, 231, 229, 132, 1, 227, 246, + 231, 229, 132, 1, 252, 147, 240, 190, 132, 1, 227, 246, 240, 190, 132, 1, + 232, 22, 225, 229, 132, 1, 217, 143, 240, 190, 132, 1, 252, 147, 248, + 174, 132, 1, 227, 246, 248, 174, 132, 1, 252, 147, 232, 185, 132, 1, 227, + 246, 232, 185, 132, 1, 212, 212, 225, 229, 132, 1, 212, 212, 217, 142, + 225, 230, 132, 1, 217, 143, 232, 185, 132, 1, 252, 147, 210, 204, 132, 1, + 227, 246, 210, 204, 132, 1, 252, 147, 246, 45, 132, 1, 227, 246, 246, 45, + 132, 1, 226, 61, 225, 184, 132, 1, 217, 143, 246, 45, 132, 1, 252, 147, + 212, 139, 132, 1, 227, 246, 212, 139, 132, 1, 252, 147, 246, 65, 132, 1, + 227, 246, 246, 65, 132, 1, 246, 96, 225, 184, 132, 1, 217, 143, 246, 65, + 132, 1, 252, 147, 221, 182, 132, 1, 227, 246, 221, 182, 132, 1, 252, 147, + 250, 99, 132, 1, 227, 246, 250, 99, 132, 1, 227, 161, 132, 1, 252, 131, + 250, 99, 132, 1, 206, 57, 132, 1, 219, 57, 132, 1, 246, 96, 230, 67, 132, + 1, 209, 41, 132, 1, 212, 212, 217, 115, 132, 1, 226, 61, 217, 115, 132, + 1, 246, 96, 217, 115, 132, 1, 239, 75, 132, 1, 226, 61, 230, 67, 132, 1, + 242, 30, 132, 3, 252, 180, 132, 22, 3, 252, 238, 132, 22, 3, 231, 192, + 252, 245, 132, 22, 3, 245, 135, 252, 245, 132, 22, 3, 231, 192, 232, 233, + 132, 22, 3, 245, 135, 232, 233, 132, 22, 3, 231, 192, 222, 50, 132, 22, + 3, 245, 135, 222, 50, 132, 22, 3, 240, 233, 132, 22, 3, 231, 38, 132, 22, + 3, 245, 135, 231, 38, 132, 22, 3, 231, 40, 245, 240, 132, 22, 3, 231, 39, + 239, 142, 252, 238, 132, 22, 3, 231, 39, 239, 142, 245, 135, 252, 238, + 132, 22, 3, 231, 39, 239, 142, 240, 189, 132, 22, 3, 240, 189, 132, 229, + 183, 18, 205, 85, 132, 229, 183, 18, 102, 132, 229, 183, 18, 105, 132, + 229, 183, 18, 142, 132, 229, 183, 18, 139, 132, 229, 183, 18, 168, 132, + 229, 183, 18, 184, 132, 229, 183, 18, 195, 132, 229, 183, 18, 193, 132, + 229, 183, 18, 200, 132, 22, 3, 245, 135, 240, 233, 132, 22, 3, 245, 135, + 240, 189, 132, 220, 72, 230, 221, 189, 157, 231, 54, 232, 41, 189, 157, + 231, 139, 231, 162, 189, 157, 231, 139, 231, 131, 189, 157, 231, 139, + 231, 126, 189, 157, 231, 139, 231, 135, 189, 157, 231, 139, 219, 78, 189, + 157, 225, 3, 224, 246, 189, 157, 248, 33, 248, 100, 189, 157, 248, 33, + 248, 43, 189, 157, 248, 33, 248, 99, 189, 157, 214, 194, 214, 193, 189, + 157, 248, 33, 248, 29, 189, 157, 205, 248, 205, 255, 189, 157, 245, 52, + 248, 107, 189, 157, 211, 130, 221, 193, 189, 157, 211, 254, 212, 46, 189, + 157, 211, 254, 225, 206, 189, 157, 211, 254, 221, 56, 189, 157, 224, 68, + 225, 101, 189, 157, 245, 52, 245, 241, 189, 157, 211, 130, 212, 167, 189, + 157, 211, 254, 211, 225, 189, 157, 211, 254, 212, 52, 189, 157, 211, 254, + 211, 249, 189, 157, 224, 68, 223, 217, 189, 157, 249, 185, 250, 154, 189, + 157, 220, 212, 220, 240, 189, 157, 221, 67, 221, 58, 189, 157, 241, 163, + 242, 73, 189, 157, 221, 67, 221, 86, 189, 157, 241, 163, 242, 47, 189, + 157, 221, 67, 217, 155, 189, 157, 226, 182, 185, 189, 157, 205, 248, 206, + 85, 189, 157, 218, 125, 218, 49, 189, 157, 218, 50, 189, 157, 229, 145, + 229, 198, 189, 157, 229, 81, 189, 157, 206, 251, 207, 91, 189, 157, 214, + 194, 217, 170, 189, 157, 214, 194, 218, 23, 189, 157, 214, 194, 213, 202, + 189, 157, 238, 150, 238, 245, 189, 157, 229, 145, 248, 13, 189, 157, 148, + 252, 114, 189, 157, 238, 150, 224, 63, 189, 157, 222, 28, 189, 157, 217, + 137, 62, 189, 157, 227, 240, 239, 109, 189, 157, 217, 137, 253, 164, 189, + 157, 217, 137, 252, 136, 189, 157, 217, 137, 74, 189, 157, 217, 137, 233, + 102, 189, 157, 217, 137, 210, 3, 189, 157, 217, 137, 210, 1, 189, 157, + 217, 137, 71, 189, 157, 217, 137, 209, 162, 189, 157, 221, 69, 189, 247, + 25, 16, 250, 155, 189, 157, 217, 137, 75, 189, 157, 217, 137, 252, 248, + 189, 157, 217, 137, 76, 189, 157, 217, 137, 252, 206, 227, 234, 189, 157, + 217, 137, 252, 206, 227, 235, 189, 157, 230, 110, 189, 157, 227, 231, + 189, 157, 227, 232, 189, 157, 227, 240, 243, 75, 189, 157, 227, 240, 211, + 253, 189, 157, 227, 240, 211, 54, 189, 157, 227, 240, 248, 87, 189, 157, + 212, 44, 189, 157, 224, 202, 189, 157, 206, 79, 189, 157, 241, 153, 189, + 18, 205, 85, 189, 18, 102, 189, 18, 105, 189, 18, 142, 189, 18, 139, 189, + 18, 168, 189, 18, 184, 189, 18, 195, 189, 18, 193, 189, 18, 200, 189, + 157, 252, 110, 189, 157, 231, 136, 230, 90, 1, 231, 53, 230, 90, 1, 231, + 139, 213, 151, 230, 90, 1, 231, 139, 212, 176, 230, 90, 1, 225, 2, 230, + 90, 1, 247, 174, 230, 90, 1, 214, 194, 212, 176, 230, 90, 1, 223, 110, + 230, 90, 1, 245, 51, 230, 90, 1, 124, 230, 90, 1, 211, 254, 213, 151, + 230, 90, 1, 211, 254, 212, 176, 230, 90, 1, 224, 67, 230, 90, 1, 249, + 184, 230, 90, 1, 220, 211, 230, 90, 1, 221, 67, 213, 151, 230, 90, 1, + 241, 163, 212, 176, 230, 90, 1, 221, 67, 212, 176, 230, 90, 1, 241, 163, + 213, 151, 230, 90, 1, 226, 181, 230, 90, 1, 205, 247, 230, 90, 1, 229, + 145, 229, 198, 230, 90, 1, 229, 145, 229, 109, 230, 90, 1, 206, 250, 230, + 90, 1, 214, 194, 213, 151, 230, 90, 1, 238, 150, 213, 151, 230, 90, 1, + 76, 230, 90, 1, 238, 150, 212, 176, 230, 90, 243, 54, 230, 90, 22, 3, 62, + 230, 90, 22, 3, 227, 240, 232, 27, 230, 90, 22, 3, 253, 164, 230, 90, 22, + 3, 252, 136, 230, 90, 22, 3, 74, 230, 90, 22, 3, 233, 102, 230, 90, 22, + 3, 206, 123, 230, 90, 22, 3, 205, 169, 230, 90, 22, 3, 71, 230, 90, 22, + 3, 209, 162, 230, 90, 22, 3, 227, 240, 231, 36, 230, 90, 216, 47, 3, 229, + 144, 230, 90, 216, 47, 3, 223, 110, 230, 90, 22, 3, 75, 230, 90, 22, 3, + 243, 90, 230, 90, 22, 3, 76, 230, 90, 22, 3, 251, 159, 230, 90, 22, 3, + 252, 205, 230, 90, 231, 54, 230, 141, 230, 90, 135, 227, 240, 243, 75, + 230, 90, 135, 227, 240, 211, 253, 230, 90, 135, 227, 240, 211, 211, 230, + 90, 135, 227, 240, 248, 182, 230, 90, 248, 223, 83, 230, 90, 224, 211, + 230, 90, 18, 205, 85, 230, 90, 18, 102, 230, 90, 18, 105, 230, 90, 18, + 142, 230, 90, 18, 139, 230, 90, 18, 168, 230, 90, 18, 184, 230, 90, 18, + 195, 230, 90, 18, 193, 230, 90, 18, 200, 230, 90, 238, 150, 224, 67, 230, + 90, 238, 150, 226, 181, 230, 90, 1, 231, 140, 240, 19, 230, 90, 1, 231, + 140, 223, 110, 72, 4, 222, 173, 72, 141, 239, 215, 206, 3, 227, 16, 210, + 249, 62, 72, 141, 239, 215, 206, 3, 227, 16, 254, 254, 218, 129, 250, 63, + 185, 72, 141, 239, 215, 206, 3, 227, 16, 254, 254, 239, 215, 210, 229, + 185, 72, 141, 78, 206, 3, 227, 16, 227, 121, 185, 72, 141, 247, 188, 206, + 3, 227, 16, 216, 9, 185, 72, 141, 248, 200, 206, 3, 227, 16, 221, 57, + 215, 252, 185, 72, 141, 206, 3, 227, 16, 210, 229, 215, 252, 185, 72, + 141, 217, 113, 215, 251, 72, 141, 249, 104, 206, 3, 227, 15, 72, 141, + 249, 204, 215, 154, 206, 3, 227, 15, 72, 141, 233, 6, 210, 228, 72, 141, + 245, 234, 210, 229, 249, 103, 72, 141, 215, 251, 72, 141, 223, 115, 215, + 251, 72, 141, 210, 229, 215, 251, 72, 141, 223, 115, 210, 229, 215, 251, + 72, 141, 218, 151, 248, 71, 214, 110, 215, 251, 72, 141, 218, 216, 239, + 246, 215, 251, 72, 141, 248, 200, 255, 2, 218, 54, 227, 120, 152, 248, + 226, 72, 141, 239, 215, 210, 228, 72, 229, 132, 3, 248, 108, 218, 53, 72, + 229, 132, 3, 229, 246, 218, 53, 72, 251, 205, 3, 216, 5, 240, 173, 255, + 3, 218, 53, 72, 251, 205, 3, 255, 0, 179, 72, 251, 205, 3, 217, 87, 210, + 223, 72, 3, 219, 53, 245, 65, 240, 172, 72, 3, 219, 53, 245, 65, 240, 21, + 72, 3, 219, 53, 245, 65, 239, 216, 72, 3, 219, 53, 225, 225, 240, 172, + 72, 3, 219, 53, 225, 225, 240, 21, 72, 3, 219, 53, 245, 65, 219, 53, 225, + 224, 72, 18, 205, 85, 72, 18, 102, 72, 18, 105, 72, 18, 142, 72, 18, 139, + 72, 18, 168, 72, 18, 184, 72, 18, 195, 72, 18, 193, 72, 18, 200, 72, 18, + 160, 102, 72, 18, 160, 105, 72, 18, 160, 142, 72, 18, 160, 139, 72, 18, + 160, 168, 72, 18, 160, 184, 72, 18, 160, 195, 72, 18, 160, 193, 72, 18, + 160, 200, 72, 18, 160, 205, 85, 72, 141, 249, 106, 218, 53, 72, 141, 225, + 68, 249, 36, 223, 126, 205, 21, 72, 141, 248, 200, 255, 2, 218, 54, 249, + 37, 226, 225, 248, 226, 72, 141, 225, 68, 249, 36, 216, 6, 218, 53, 72, + 141, 248, 83, 227, 15, 72, 141, 210, 244, 254, 255, 72, 141, 239, 198, + 218, 54, 239, 158, 72, 141, 239, 198, 218, 54, 239, 164, 72, 141, 252, + 115, 231, 157, 239, 158, 72, 141, 252, 115, 231, 157, 239, 164, 72, 3, + 206, 71, 210, 227, 72, 3, 227, 200, 210, 227, 72, 1, 172, 72, 1, 231, + 167, 72, 1, 240, 244, 72, 1, 240, 99, 72, 1, 225, 77, 72, 1, 249, 1, 72, + 1, 248, 110, 72, 1, 232, 200, 72, 1, 223, 144, 72, 1, 210, 208, 72, 1, + 210, 196, 72, 1, 246, 54, 72, 1, 246, 38, 72, 1, 224, 103, 72, 1, 212, + 219, 72, 1, 212, 56, 72, 1, 246, 145, 72, 1, 245, 192, 72, 1, 199, 72, 1, + 179, 72, 1, 221, 93, 72, 1, 250, 183, 72, 1, 250, 0, 72, 1, 185, 72, 1, + 210, 243, 72, 1, 210, 233, 72, 1, 243, 196, 72, 1, 243, 190, 72, 1, 207, + 96, 72, 1, 205, 81, 72, 1, 205, 116, 72, 1, 255, 5, 72, 1, 190, 72, 1, + 219, 113, 72, 1, 230, 141, 72, 1, 216, 2, 72, 1, 214, 96, 72, 1, 217, + 199, 72, 1, 155, 72, 1, 62, 72, 1, 230, 250, 72, 1, 241, 200, 219, 113, + 72, 1, 231, 72, 72, 1, 218, 89, 72, 22, 3, 253, 164, 72, 22, 3, 74, 72, + 22, 3, 233, 102, 72, 22, 3, 71, 72, 22, 3, 209, 162, 72, 22, 3, 115, 137, + 72, 22, 3, 115, 218, 90, 72, 22, 3, 115, 149, 72, 22, 3, 115, 229, 173, + 72, 22, 3, 75, 72, 22, 3, 243, 104, 72, 22, 3, 76, 72, 22, 3, 222, 152, + 72, 3, 218, 135, 213, 204, 225, 78, 218, 124, 72, 3, 218, 129, 250, 62, + 72, 22, 3, 218, 224, 74, 72, 22, 3, 218, 224, 233, 102, 72, 3, 223, 126, + 205, 22, 225, 233, 246, 145, 72, 3, 214, 207, 230, 60, 72, 141, 239, 123, + 72, 141, 222, 16, 72, 3, 230, 63, 218, 53, 72, 3, 206, 76, 218, 53, 72, + 3, 230, 64, 210, 244, 248, 226, 72, 3, 227, 123, 248, 226, 72, 3, 239, + 219, 248, 227, 218, 214, 72, 3, 239, 219, 227, 113, 218, 214, 72, 3, 233, + 2, 227, 123, 248, 226, 72, 213, 191, 3, 230, 64, 210, 244, 248, 226, 72, + 213, 191, 3, 227, 123, 248, 226, 72, 213, 191, 3, 233, 2, 227, 123, 248, + 226, 72, 213, 191, 1, 172, 72, 213, 191, 1, 231, 167, 72, 213, 191, 1, + 240, 244, 72, 213, 191, 1, 240, 99, 72, 213, 191, 1, 225, 77, 72, 213, + 191, 1, 249, 1, 72, 213, 191, 1, 248, 110, 72, 213, 191, 1, 232, 200, 72, + 213, 191, 1, 223, 144, 72, 213, 191, 1, 210, 208, 72, 213, 191, 1, 210, + 196, 72, 213, 191, 1, 246, 54, 72, 213, 191, 1, 246, 38, 72, 213, 191, 1, + 224, 103, 72, 213, 191, 1, 212, 219, 72, 213, 191, 1, 212, 56, 72, 213, + 191, 1, 246, 145, 72, 213, 191, 1, 245, 192, 72, 213, 191, 1, 199, 72, + 213, 191, 1, 179, 72, 213, 191, 1, 221, 93, 72, 213, 191, 1, 250, 183, + 72, 213, 191, 1, 250, 0, 72, 213, 191, 1, 185, 72, 213, 191, 1, 210, 243, + 72, 213, 191, 1, 210, 233, 72, 213, 191, 1, 243, 196, 72, 213, 191, 1, + 243, 190, 72, 213, 191, 1, 207, 96, 72, 213, 191, 1, 205, 81, 72, 213, + 191, 1, 205, 116, 72, 213, 191, 1, 255, 5, 72, 213, 191, 1, 190, 72, 213, + 191, 1, 219, 113, 72, 213, 191, 1, 230, 141, 72, 213, 191, 1, 216, 2, 72, + 213, 191, 1, 214, 96, 72, 213, 191, 1, 217, 199, 72, 213, 191, 1, 155, + 72, 213, 191, 1, 62, 72, 213, 191, 1, 230, 250, 72, 213, 191, 1, 241, + 200, 207, 96, 72, 213, 191, 1, 241, 200, 190, 72, 213, 191, 1, 241, 200, + 219, 113, 72, 230, 237, 218, 51, 231, 167, 72, 230, 237, 218, 51, 231, + 168, 249, 37, 226, 225, 248, 226, 72, 248, 214, 3, 77, 250, 55, 72, 248, + 214, 3, 147, 250, 55, 72, 248, 214, 3, 248, 215, 212, 129, 72, 248, 214, + 3, 217, 112, 255, 4, 72, 16, 243, 250, 249, 101, 72, 16, 219, 52, 218, + 136, 72, 16, 222, 39, 240, 171, 72, 16, 219, 52, 218, 137, 218, 216, 239, + 245, 72, 16, 221, 57, 179, 72, 16, 224, 51, 249, 101, 72, 16, 224, 51, + 249, 102, 223, 115, 255, 1, 72, 16, 224, 51, 249, 102, 239, 217, 255, 1, + 72, 16, 224, 51, 249, 102, 249, 37, 255, 1, 72, 3, 219, 53, 225, 225, + 219, 53, 245, 64, 72, 3, 219, 53, 225, 225, 239, 216, 72, 141, 249, 105, + 215, 154, 240, 62, 227, 16, 218, 215, 72, 141, 226, 183, 206, 3, 240, 62, + 227, 16, 218, 215, 72, 141, 223, 115, 210, 228, 72, 141, 78, 249, 128, + 218, 126, 206, 3, 227, 16, 227, 121, 185, 72, 141, 247, 188, 249, 128, + 218, 126, 206, 3, 227, 16, 216, 9, 185, 218, 166, 213, 114, 53, 230, 45, + 213, 114, 53, 218, 166, 213, 114, 3, 2, 245, 21, 230, 45, 213, 114, 3, 2, + 245, 21, 72, 141, 230, 55, 227, 124, 218, 53, 72, 141, 211, 76, 227, 124, + 218, 53, 66, 1, 172, 66, 1, 231, 167, 66, 1, 240, 244, 66, 1, 240, 99, + 66, 1, 225, 77, 66, 1, 249, 1, 66, 1, 248, 110, 66, 1, 232, 200, 66, 1, + 232, 170, 66, 1, 223, 144, 66, 1, 224, 69, 66, 1, 210, 208, 66, 1, 210, + 196, 66, 1, 246, 54, 66, 1, 246, 38, 66, 1, 224, 103, 66, 1, 212, 219, + 66, 1, 212, 56, 66, 1, 246, 145, 66, 1, 245, 192, 66, 1, 199, 66, 1, 179, + 66, 1, 221, 93, 66, 1, 250, 183, 66, 1, 250, 0, 66, 1, 185, 66, 1, 190, + 66, 1, 219, 113, 66, 1, 230, 141, 66, 1, 207, 96, 66, 1, 217, 199, 66, 1, + 155, 66, 1, 229, 172, 66, 1, 62, 66, 1, 215, 238, 62, 66, 1, 74, 66, 1, + 233, 102, 66, 1, 71, 66, 1, 209, 162, 66, 1, 75, 66, 1, 226, 169, 75, 66, + 1, 76, 66, 1, 251, 184, 66, 22, 3, 212, 178, 253, 164, 66, 22, 3, 253, + 164, 66, 22, 3, 74, 66, 22, 3, 233, 102, 66, 22, 3, 71, 66, 22, 3, 209, + 162, 66, 22, 3, 75, 66, 22, 3, 252, 205, 66, 22, 3, 226, 169, 233, 102, + 66, 22, 3, 226, 169, 76, 66, 22, 3, 174, 52, 66, 3, 252, 73, 66, 3, 67, + 55, 66, 3, 208, 183, 66, 3, 208, 188, 66, 3, 251, 229, 66, 107, 3, 169, + 190, 66, 107, 3, 169, 219, 113, 66, 107, 3, 169, 207, 96, 66, 107, 3, + 169, 155, 66, 1, 239, 232, 217, 199, 66, 18, 205, 85, 66, 18, 102, 66, + 18, 105, 66, 18, 142, 66, 18, 139, 66, 18, 168, 66, 18, 184, 66, 18, 195, + 66, 18, 193, 66, 18, 200, 66, 3, 229, 180, 217, 76, 66, 3, 217, 76, 66, + 16, 229, 141, 66, 16, 247, 149, 66, 16, 252, 224, 66, 16, 240, 154, 66, + 1, 216, 2, 66, 1, 214, 96, 66, 1, 115, 137, 66, 1, 115, 218, 90, 66, 1, + 115, 149, 66, 1, 115, 229, 173, 66, 22, 3, 115, 137, 66, 22, 3, 115, 218, + 90, 66, 22, 3, 115, 149, 66, 22, 3, 115, 229, 173, 66, 1, 226, 169, 225, + 77, 66, 1, 226, 169, 232, 170, 66, 1, 226, 169, 250, 97, 66, 1, 226, 169, + 250, 92, 66, 107, 3, 226, 169, 169, 199, 66, 107, 3, 226, 169, 169, 185, + 66, 107, 3, 226, 169, 169, 230, 141, 66, 1, 216, 8, 232, 4, 216, 2, 66, + 22, 3, 216, 8, 232, 4, 242, 192, 66, 135, 141, 216, 8, 232, 4, 239, 82, + 66, 135, 141, 216, 8, 232, 4, 231, 225, 221, 66, 66, 1, 207, 34, 220, 39, + 232, 4, 212, 56, 66, 1, 207, 34, 220, 39, 232, 4, 220, 45, 66, 22, 3, + 207, 34, 220, 39, 232, 4, 242, 192, 66, 22, 3, 207, 34, 220, 39, 232, 4, + 210, 3, 66, 3, 207, 34, 220, 39, 232, 4, 211, 117, 66, 3, 207, 34, 220, + 39, 232, 4, 211, 116, 66, 3, 207, 34, 220, 39, 232, 4, 211, 115, 66, 3, + 207, 34, 220, 39, 232, 4, 211, 114, 66, 3, 207, 34, 220, 39, 232, 4, 211, + 113, 66, 1, 243, 115, 220, 39, 232, 4, 224, 103, 66, 1, 243, 115, 220, + 39, 232, 4, 205, 176, 66, 1, 243, 115, 220, 39, 232, 4, 240, 64, 66, 22, + 3, 240, 166, 232, 4, 74, 66, 22, 3, 231, 230, 222, 206, 66, 22, 3, 231, + 230, 71, 66, 22, 3, 231, 230, 243, 104, 66, 1, 215, 238, 172, 66, 1, 215, + 238, 231, 167, 66, 1, 215, 238, 240, 244, 66, 1, 215, 238, 249, 1, 66, 1, + 215, 238, 205, 116, 66, 1, 215, 238, 223, 144, 66, 1, 215, 238, 246, 145, + 66, 1, 215, 238, 199, 66, 1, 215, 238, 221, 93, 66, 1, 215, 238, 242, 73, + 66, 1, 215, 238, 250, 183, 66, 1, 215, 238, 212, 56, 66, 1, 215, 238, + 155, 66, 107, 3, 215, 238, 169, 207, 96, 66, 22, 3, 215, 238, 253, 164, + 66, 22, 3, 215, 238, 75, 66, 22, 3, 215, 238, 174, 52, 66, 22, 3, 215, + 238, 42, 206, 123, 66, 3, 215, 238, 211, 116, 66, 3, 215, 238, 211, 115, + 66, 3, 215, 238, 211, 113, 66, 3, 215, 238, 211, 112, 66, 3, 215, 238, + 247, 82, 211, 116, 66, 3, 215, 238, 247, 82, 211, 115, 66, 3, 215, 238, + 247, 82, 243, 44, 211, 118, 66, 1, 218, 37, 222, 23, 242, 73, 66, 3, 218, + 37, 222, 23, 211, 113, 66, 215, 238, 18, 205, 85, 66, 215, 238, 18, 102, + 66, 215, 238, 18, 105, 66, 215, 238, 18, 142, 66, 215, 238, 18, 139, 66, + 215, 238, 18, 168, 66, 215, 238, 18, 184, 66, 215, 238, 18, 195, 66, 215, + 238, 18, 193, 66, 215, 238, 18, 200, 66, 3, 231, 160, 211, 117, 66, 3, + 231, 160, 211, 115, 66, 22, 3, 252, 193, 62, 66, 22, 3, 252, 193, 252, + 205, 66, 16, 215, 238, 102, 66, 16, 215, 238, 242, 167, 108, 6, 1, 252, + 122, 108, 6, 1, 250, 140, 108, 6, 1, 240, 214, 108, 6, 1, 245, 31, 108, + 6, 1, 243, 41, 108, 6, 1, 208, 197, 108, 6, 1, 205, 88, 108, 6, 1, 212, + 174, 108, 6, 1, 233, 68, 108, 6, 1, 232, 27, 108, 6, 1, 230, 82, 108, 6, + 1, 227, 221, 108, 6, 1, 225, 200, 108, 6, 1, 222, 165, 108, 6, 1, 221, + 231, 108, 6, 1, 205, 77, 108, 6, 1, 219, 95, 108, 6, 1, 217, 151, 108, 6, + 1, 212, 162, 108, 6, 1, 209, 234, 108, 6, 1, 221, 85, 108, 6, 1, 231, + 155, 108, 6, 1, 240, 90, 108, 6, 1, 220, 4, 108, 6, 1, 215, 171, 108, 6, + 1, 248, 45, 108, 6, 1, 248, 226, 108, 6, 1, 232, 154, 108, 6, 1, 247, + 240, 108, 6, 1, 248, 95, 108, 6, 1, 206, 179, 108, 6, 1, 232, 167, 108, + 6, 1, 239, 138, 108, 6, 1, 239, 71, 108, 6, 1, 239, 6, 108, 6, 1, 207, + 51, 108, 6, 1, 239, 95, 108, 6, 1, 238, 146, 108, 6, 1, 205, 249, 108, 6, + 1, 252, 237, 108, 1, 252, 122, 108, 1, 250, 140, 108, 1, 240, 214, 108, + 1, 245, 31, 108, 1, 243, 41, 108, 1, 208, 197, 108, 1, 205, 88, 108, 1, + 212, 174, 108, 1, 233, 68, 108, 1, 232, 27, 108, 1, 230, 82, 108, 1, 227, + 221, 108, 1, 225, 200, 108, 1, 222, 165, 108, 1, 221, 231, 108, 1, 205, + 77, 108, 1, 219, 95, 108, 1, 217, 151, 108, 1, 212, 162, 108, 1, 209, + 234, 108, 1, 221, 85, 108, 1, 231, 155, 108, 1, 240, 90, 108, 1, 220, 4, + 108, 1, 215, 171, 108, 1, 248, 45, 108, 1, 248, 226, 108, 1, 232, 154, + 108, 1, 247, 240, 108, 1, 248, 95, 108, 1, 206, 179, 108, 1, 232, 167, + 108, 1, 239, 138, 108, 1, 239, 71, 108, 1, 239, 6, 108, 1, 207, 51, 108, + 1, 239, 95, 108, 1, 238, 146, 108, 1, 241, 250, 108, 1, 205, 249, 108, 1, + 243, 56, 108, 1, 201, 240, 214, 108, 1, 252, 200, 108, 221, 229, 216, 39, + 65, 1, 108, 225, 200, 108, 1, 252, 237, 108, 1, 239, 94, 53, 108, 1, 230, + 132, 53, 25, 113, 231, 84, 25, 113, 214, 88, 25, 113, 224, 223, 25, 113, + 211, 193, 25, 113, 214, 77, 25, 113, 218, 198, 25, 113, 226, 240, 25, + 113, 221, 39, 25, 113, 214, 85, 25, 113, 215, 33, 25, 113, 214, 82, 25, + 113, 233, 125, 25, 113, 247, 246, 25, 113, 214, 92, 25, 113, 248, 54, 25, + 113, 231, 143, 25, 113, 212, 15, 25, 113, 221, 76, 25, 113, 239, 3, 25, + 113, 224, 219, 25, 113, 214, 86, 25, 113, 224, 213, 25, 113, 224, 217, + 25, 113, 211, 190, 25, 113, 218, 186, 25, 113, 214, 84, 25, 113, 218, + 196, 25, 113, 232, 10, 25, 113, 226, 233, 25, 113, 232, 13, 25, 113, 221, + 34, 25, 113, 221, 32, 25, 113, 221, 20, 25, 113, 221, 28, 25, 113, 221, + 26, 25, 113, 221, 23, 25, 113, 221, 25, 25, 113, 221, 22, 25, 113, 221, + 27, 25, 113, 221, 37, 25, 113, 221, 38, 25, 113, 221, 21, 25, 113, 221, + 31, 25, 113, 232, 11, 25, 113, 232, 9, 25, 113, 215, 26, 25, 113, 215, + 24, 25, 113, 215, 16, 25, 113, 215, 19, 25, 113, 215, 25, 25, 113, 215, + 21, 25, 113, 215, 20, 25, 113, 215, 18, 25, 113, 215, 29, 25, 113, 215, + 31, 25, 113, 215, 32, 25, 113, 215, 27, 25, 113, 215, 17, 25, 113, 215, + 22, 25, 113, 215, 30, 25, 113, 248, 36, 25, 113, 248, 34, 25, 113, 248, + 121, 25, 113, 248, 119, 25, 113, 221, 247, 25, 113, 233, 120, 25, 113, + 233, 111, 25, 113, 233, 119, 25, 113, 233, 116, 25, 113, 233, 114, 25, + 113, 233, 118, 25, 113, 214, 89, 25, 113, 233, 123, 25, 113, 233, 124, + 25, 113, 233, 112, 25, 113, 233, 117, 25, 113, 206, 29, 25, 113, 247, + 245, 25, 113, 248, 37, 25, 113, 248, 35, 25, 113, 248, 122, 25, 113, 248, + 120, 25, 113, 248, 52, 25, 113, 248, 53, 25, 113, 248, 38, 25, 113, 248, + 123, 25, 113, 221, 74, 25, 113, 232, 12, 25, 113, 214, 90, 25, 113, 206, + 35, 25, 113, 231, 75, 25, 113, 224, 215, 25, 113, 224, 221, 25, 113, 224, + 220, 25, 113, 211, 187, 25, 113, 241, 232, 25, 162, 241, 232, 25, 162, + 62, 25, 162, 252, 248, 25, 162, 190, 25, 162, 206, 98, 25, 162, 243, 6, + 25, 162, 75, 25, 162, 206, 39, 25, 162, 206, 52, 25, 162, 76, 25, 162, + 207, 96, 25, 162, 207, 92, 25, 162, 222, 206, 25, 162, 205, 247, 25, 162, + 71, 25, 162, 207, 38, 25, 162, 207, 51, 25, 162, 207, 20, 25, 162, 205, + 213, 25, 162, 242, 192, 25, 162, 206, 11, 25, 162, 74, 25, 162, 254, 252, + 25, 162, 254, 251, 25, 162, 206, 112, 25, 162, 206, 110, 25, 162, 243, 4, + 25, 162, 243, 3, 25, 162, 243, 5, 25, 162, 206, 38, 25, 162, 206, 37, 25, + 162, 223, 58, 25, 162, 223, 59, 25, 162, 223, 52, 25, 162, 223, 57, 25, + 162, 223, 55, 25, 162, 205, 241, 25, 162, 205, 240, 25, 162, 205, 239, + 25, 162, 205, 242, 25, 162, 205, 243, 25, 162, 210, 76, 25, 162, 210, 75, + 25, 162, 210, 73, 25, 162, 210, 69, 25, 162, 210, 70, 25, 162, 205, 212, + 25, 162, 205, 209, 25, 162, 205, 210, 25, 162, 205, 204, 25, 162, 205, + 205, 25, 162, 205, 206, 25, 162, 205, 208, 25, 162, 242, 186, 25, 162, + 242, 188, 25, 162, 206, 10, 25, 162, 237, 224, 25, 162, 237, 216, 25, + 162, 237, 219, 25, 162, 237, 217, 25, 162, 237, 221, 25, 162, 237, 223, + 25, 162, 252, 30, 25, 162, 252, 27, 25, 162, 252, 25, 25, 162, 252, 26, + 25, 162, 214, 93, 25, 162, 254, 253, 25, 162, 206, 111, 25, 162, 206, 36, + 25, 162, 223, 54, 25, 162, 223, 53, 25, 100, 231, 84, 25, 100, 214, 88, + 25, 100, 231, 77, 25, 100, 224, 223, 25, 100, 224, 221, 25, 100, 224, + 220, 25, 100, 211, 193, 25, 100, 218, 198, 25, 100, 218, 193, 25, 100, + 218, 190, 25, 100, 218, 183, 25, 100, 218, 178, 25, 100, 218, 173, 25, + 100, 218, 184, 25, 100, 218, 196, 25, 100, 226, 240, 25, 100, 221, 39, + 25, 100, 221, 28, 25, 100, 215, 33, 25, 100, 214, 82, 25, 100, 233, 125, + 25, 100, 247, 246, 25, 100, 248, 54, 25, 100, 231, 143, 25, 100, 212, 15, + 25, 100, 221, 76, 25, 100, 239, 3, 25, 100, 231, 78, 25, 100, 231, 76, + 25, 100, 224, 219, 25, 100, 224, 213, 25, 100, 224, 215, 25, 100, 224, + 218, 25, 100, 224, 214, 25, 100, 211, 190, 25, 100, 211, 187, 25, 100, + 218, 191, 25, 100, 218, 186, 25, 100, 218, 172, 25, 100, 218, 171, 25, + 100, 214, 84, 25, 100, 218, 188, 25, 100, 218, 187, 25, 100, 218, 180, + 25, 100, 218, 182, 25, 100, 218, 195, 25, 100, 218, 175, 25, 100, 218, + 185, 25, 100, 218, 194, 25, 100, 218, 170, 25, 100, 226, 236, 25, 100, + 226, 231, 25, 100, 226, 233, 25, 100, 226, 230, 25, 100, 226, 228, 25, + 100, 226, 234, 25, 100, 226, 239, 25, 100, 226, 237, 25, 100, 232, 13, + 25, 100, 221, 30, 25, 100, 221, 31, 25, 100, 221, 36, 25, 100, 232, 11, + 25, 100, 215, 26, 25, 100, 215, 16, 25, 100, 215, 19, 25, 100, 215, 21, + 25, 100, 221, 247, 25, 100, 233, 120, 25, 100, 233, 113, 25, 100, 214, + 89, 25, 100, 233, 121, 25, 100, 206, 29, 25, 100, 206, 25, 25, 100, 206, + 26, 25, 100, 221, 74, 25, 100, 232, 12, 25, 100, 239, 1, 25, 100, 238, + 255, 25, 100, 239, 2, 25, 100, 239, 0, 25, 100, 206, 35, 25, 100, 231, + 80, 25, 100, 231, 79, 25, 100, 231, 83, 25, 100, 231, 81, 25, 100, 231, + 82, 25, 100, 214, 86, 31, 4, 155, 31, 4, 238, 42, 31, 4, 239, 11, 31, 4, + 239, 141, 31, 4, 239, 53, 31, 4, 239, 71, 31, 4, 238, 149, 31, 4, 238, + 148, 31, 4, 230, 141, 31, 4, 229, 81, 31, 4, 229, 235, 31, 4, 230, 140, + 31, 4, 230, 50, 31, 4, 230, 58, 31, 4, 229, 144, 31, 4, 229, 50, 31, 4, + 239, 20, 31, 4, 239, 14, 31, 4, 239, 16, 31, 4, 239, 19, 31, 4, 239, 17, + 31, 4, 239, 18, 31, 4, 239, 15, 31, 4, 239, 13, 31, 4, 185, 31, 4, 226, + 114, 31, 4, 226, 254, 31, 4, 228, 18, 31, 4, 227, 107, 31, 4, 227, 119, + 31, 4, 226, 181, 31, 4, 226, 50, 31, 4, 213, 21, 31, 4, 213, 15, 31, 4, + 213, 17, 31, 4, 213, 20, 31, 4, 213, 18, 31, 4, 213, 19, 31, 4, 213, 16, + 31, 4, 213, 14, 31, 4, 219, 113, 31, 4, 218, 50, 31, 4, 218, 208, 31, 4, + 219, 109, 31, 4, 219, 29, 31, 4, 219, 51, 31, 4, 218, 124, 31, 4, 218, + 18, 31, 4, 217, 199, 31, 4, 213, 203, 31, 4, 215, 80, 31, 4, 217, 196, + 31, 4, 217, 74, 31, 4, 217, 86, 31, 4, 214, 193, 31, 4, 213, 112, 31, 4, + 216, 2, 31, 4, 215, 116, 31, 4, 215, 183, 31, 4, 215, 254, 31, 4, 215, + 212, 31, 4, 215, 214, 31, 4, 215, 158, 31, 4, 215, 98, 31, 4, 220, 19, + 31, 4, 219, 214, 31, 4, 219, 237, 31, 4, 220, 18, 31, 4, 219, 254, 31, 4, + 219, 255, 31, 4, 219, 226, 31, 4, 219, 225, 31, 4, 219, 168, 31, 4, 219, + 164, 31, 4, 219, 167, 31, 4, 219, 165, 31, 4, 219, 166, 31, 4, 219, 251, + 31, 4, 219, 243, 31, 4, 219, 246, 31, 4, 219, 250, 31, 4, 219, 247, 31, + 4, 219, 248, 31, 4, 219, 245, 31, 4, 219, 242, 31, 4, 219, 238, 31, 4, + 219, 241, 31, 4, 219, 239, 31, 4, 219, 240, 31, 4, 250, 183, 31, 4, 249, + 101, 31, 4, 249, 244, 31, 4, 250, 181, 31, 4, 250, 50, 31, 4, 250, 61, + 31, 4, 249, 184, 31, 4, 249, 51, 31, 4, 209, 70, 31, 4, 207, 148, 31, 4, + 208, 214, 31, 4, 209, 69, 31, 4, 209, 34, 31, 4, 209, 39, 31, 4, 208, + 173, 31, 4, 207, 139, 31, 4, 212, 219, 31, 4, 210, 170, 31, 4, 211, 211, + 31, 4, 212, 215, 31, 4, 212, 120, 31, 4, 212, 131, 31, 4, 124, 31, 4, + 210, 130, 31, 4, 249, 1, 31, 4, 247, 40, 31, 4, 247, 251, 31, 4, 249, 0, + 31, 4, 248, 140, 31, 4, 248, 148, 31, 4, 247, 174, 31, 4, 247, 7, 31, 4, + 206, 181, 31, 4, 206, 151, 31, 4, 206, 169, 31, 4, 206, 180, 31, 4, 206, + 174, 31, 4, 206, 175, 31, 4, 206, 159, 31, 4, 206, 158, 31, 4, 206, 145, + 31, 4, 206, 141, 31, 4, 206, 144, 31, 4, 206, 142, 31, 4, 206, 143, 31, + 4, 199, 31, 4, 223, 217, 31, 4, 224, 230, 31, 4, 225, 232, 31, 4, 225, + 106, 31, 4, 225, 110, 31, 4, 224, 67, 31, 4, 223, 153, 31, 4, 223, 144, + 31, 4, 223, 103, 31, 4, 223, 125, 31, 4, 223, 143, 31, 4, 223, 133, 31, + 4, 223, 134, 31, 4, 223, 110, 31, 4, 223, 93, 31, 4, 240, 25, 62, 31, 4, + 240, 25, 71, 31, 4, 240, 25, 74, 31, 4, 240, 25, 253, 164, 31, 4, 240, + 25, 243, 104, 31, 4, 240, 25, 75, 31, 4, 240, 25, 76, 31, 4, 240, 25, + 207, 96, 31, 4, 172, 31, 4, 230, 236, 31, 4, 231, 123, 31, 4, 232, 63, + 31, 4, 231, 221, 31, 4, 231, 224, 31, 4, 231, 53, 31, 4, 231, 52, 31, 4, + 230, 195, 31, 4, 230, 188, 31, 4, 230, 194, 31, 4, 230, 189, 31, 4, 230, + 190, 31, 4, 230, 181, 31, 4, 230, 175, 31, 4, 230, 177, 31, 4, 230, 180, + 31, 4, 230, 178, 31, 4, 230, 179, 31, 4, 230, 176, 31, 4, 230, 174, 31, + 4, 230, 170, 31, 4, 230, 173, 31, 4, 230, 171, 31, 4, 230, 172, 31, 4, + 207, 96, 31, 4, 206, 216, 31, 4, 207, 20, 31, 4, 207, 95, 31, 4, 207, 45, + 31, 4, 207, 51, 31, 4, 206, 250, 31, 4, 206, 249, 31, 4, 221, 84, 62, 31, + 4, 221, 84, 71, 31, 4, 221, 84, 74, 31, 4, 221, 84, 253, 164, 31, 4, 221, + 84, 243, 104, 31, 4, 221, 84, 75, 31, 4, 221, 84, 76, 31, 4, 205, 116, + 31, 4, 205, 9, 31, 4, 205, 40, 31, 4, 205, 115, 31, 4, 205, 91, 31, 4, + 205, 93, 31, 4, 205, 19, 31, 4, 204, 252, 31, 4, 205, 81, 31, 4, 205, 58, + 31, 4, 205, 67, 31, 4, 205, 80, 31, 4, 205, 71, 31, 4, 205, 72, 31, 4, + 205, 64, 31, 4, 205, 49, 31, 4, 190, 31, 4, 205, 213, 31, 4, 206, 11, 31, + 4, 206, 109, 31, 4, 206, 49, 31, 4, 206, 52, 31, 4, 205, 247, 31, 4, 205, + 238, 31, 4, 246, 145, 31, 4, 243, 237, 31, 4, 245, 168, 31, 4, 246, 144, + 31, 4, 245, 251, 31, 4, 246, 9, 31, 4, 245, 51, 31, 4, 243, 206, 31, 4, + 246, 54, 31, 4, 246, 19, 31, 4, 246, 31, 31, 4, 246, 53, 31, 4, 246, 41, + 31, 4, 246, 42, 31, 4, 246, 24, 31, 4, 246, 10, 31, 4, 232, 200, 31, 4, + 232, 104, 31, 4, 232, 162, 31, 4, 232, 199, 31, 4, 232, 180, 31, 4, 232, + 182, 31, 4, 232, 122, 31, 4, 232, 84, 31, 4, 240, 244, 31, 4, 239, 213, + 31, 4, 240, 61, 31, 4, 240, 241, 31, 4, 240, 162, 31, 4, 240, 170, 31, 4, + 240, 19, 31, 4, 240, 18, 31, 4, 239, 174, 31, 4, 239, 170, 31, 4, 239, + 173, 31, 4, 239, 171, 31, 4, 239, 172, 31, 4, 240, 135, 31, 4, 240, 115, + 31, 4, 240, 125, 31, 4, 240, 134, 31, 4, 240, 129, 31, 4, 240, 130, 31, + 4, 240, 119, 31, 4, 240, 104, 31, 4, 212, 56, 31, 4, 211, 230, 31, 4, + 212, 19, 31, 4, 212, 55, 31, 4, 212, 39, 31, 4, 212, 41, 31, 4, 211, 253, + 31, 4, 211, 222, 31, 4, 248, 110, 31, 4, 248, 14, 31, 4, 248, 58, 31, 4, + 248, 109, 31, 4, 248, 78, 31, 4, 248, 82, 31, 4, 248, 32, 31, 4, 248, 3, + 31, 4, 221, 93, 31, 4, 221, 59, 31, 4, 221, 78, 31, 4, 221, 92, 31, 4, + 221, 80, 31, 4, 221, 81, 31, 4, 221, 66, 31, 4, 221, 55, 31, 4, 210, 243, + 31, 4, 210, 216, 31, 4, 210, 222, 31, 4, 210, 242, 31, 4, 210, 236, 31, + 4, 210, 237, 31, 4, 210, 220, 31, 4, 210, 214, 31, 4, 210, 85, 31, 4, + 210, 77, 31, 4, 210, 81, 31, 4, 210, 84, 31, 4, 210, 82, 31, 4, 210, 83, + 31, 4, 210, 79, 31, 4, 210, 78, 31, 4, 242, 73, 31, 4, 241, 88, 31, 4, + 241, 250, 31, 4, 242, 72, 31, 4, 242, 21, 31, 4, 242, 28, 31, 4, 241, + 162, 31, 4, 241, 66, 31, 4, 179, 31, 4, 220, 82, 31, 4, 221, 53, 31, 4, + 222, 51, 31, 4, 221, 164, 31, 4, 221, 174, 31, 4, 220, 211, 31, 4, 220, + 45, 31, 4, 218, 8, 31, 4, 226, 39, 31, 4, 241, 60, 31, 36, 240, 159, 23, + 22, 230, 20, 83, 31, 36, 22, 230, 20, 83, 31, 36, 240, 159, 83, 31, 217, + 77, 83, 31, 206, 231, 31, 241, 82, 213, 251, 31, 247, 155, 31, 216, 52, + 31, 247, 162, 31, 220, 136, 247, 162, 31, 219, 196, 83, 31, 221, 229, + 216, 39, 31, 18, 102, 31, 18, 105, 31, 18, 142, 31, 18, 139, 31, 18, 168, + 31, 18, 184, 31, 18, 195, 31, 18, 193, 31, 18, 200, 31, 43, 212, 98, 31, + 43, 210, 123, 31, 43, 212, 3, 31, 43, 241, 130, 31, 43, 241, 243, 31, 43, + 214, 252, 31, 43, 216, 17, 31, 43, 243, 79, 31, 43, 224, 190, 31, 43, + 238, 29, 31, 43, 212, 99, 211, 242, 31, 4, 217, 82, 226, 50, 31, 4, 226, + 46, 31, 4, 226, 47, 31, 4, 226, 48, 31, 4, 217, 82, 249, 51, 31, 4, 249, + 48, 31, 4, 249, 49, 31, 4, 249, 50, 31, 4, 217, 82, 241, 66, 31, 4, 241, + 62, 31, 4, 241, 63, 31, 4, 241, 64, 31, 4, 217, 82, 220, 45, 31, 4, 220, + 41, 31, 4, 220, 42, 31, 4, 220, 43, 31, 211, 119, 141, 205, 250, 31, 211, + 119, 141, 245, 213, 31, 211, 119, 141, 218, 153, 31, 211, 119, 141, 215, + 144, 218, 153, 31, 211, 119, 141, 245, 142, 31, 211, 119, 141, 231, 202, + 31, 211, 119, 141, 248, 40, 31, 211, 119, 141, 239, 8, 31, 211, 119, 141, + 245, 212, 31, 211, 119, 141, 230, 208, 192, 1, 62, 192, 1, 75, 192, 1, + 74, 192, 1, 76, 192, 1, 71, 192, 1, 209, 148, 192, 1, 240, 244, 192, 1, + 172, 192, 1, 240, 170, 192, 1, 240, 61, 192, 1, 240, 19, 192, 1, 239, + 213, 192, 1, 239, 176, 192, 1, 155, 192, 1, 239, 71, 192, 1, 239, 11, + 192, 1, 238, 149, 192, 1, 238, 42, 192, 1, 238, 17, 192, 1, 230, 141, + 192, 1, 230, 58, 192, 1, 229, 235, 192, 1, 229, 144, 192, 1, 229, 81, + 192, 1, 229, 51, 192, 1, 185, 192, 1, 227, 119, 192, 1, 226, 254, 192, 1, + 226, 181, 192, 1, 226, 114, 192, 1, 199, 192, 1, 238, 173, 192, 1, 225, + 219, 192, 1, 225, 110, 192, 1, 224, 230, 192, 1, 224, 67, 192, 1, 223, + 217, 192, 1, 223, 155, 192, 1, 219, 213, 192, 1, 219, 199, 192, 1, 219, + 192, 192, 1, 219, 183, 192, 1, 219, 172, 192, 1, 219, 170, 192, 1, 217, + 199, 192, 1, 182, 192, 1, 217, 86, 192, 1, 215, 80, 192, 1, 214, 193, + 192, 1, 213, 203, 192, 1, 213, 117, 192, 1, 246, 145, 192, 1, 212, 219, + 192, 1, 246, 9, 192, 1, 212, 131, 192, 1, 245, 168, 192, 1, 211, 211, + 192, 1, 245, 51, 192, 1, 243, 237, 192, 1, 243, 209, 192, 1, 245, 62, + 192, 1, 211, 147, 192, 1, 211, 146, 192, 1, 211, 135, 192, 1, 211, 134, + 192, 1, 211, 133, 192, 1, 211, 132, 192, 1, 210, 243, 192, 1, 210, 237, + 192, 1, 210, 222, 192, 1, 210, 220, 192, 1, 210, 216, 192, 1, 210, 215, + 192, 1, 207, 96, 192, 1, 207, 51, 192, 1, 207, 20, 192, 1, 206, 250, 192, + 1, 206, 216, 192, 1, 206, 203, 192, 1, 190, 192, 1, 206, 52, 192, 1, 206, + 11, 192, 1, 205, 247, 192, 1, 205, 213, 192, 1, 205, 177, 19, 20, 237, + 239, 19, 20, 75, 19, 20, 253, 128, 19, 20, 74, 19, 20, 233, 102, 19, 20, + 76, 19, 20, 222, 152, 19, 20, 206, 122, 222, 152, 19, 20, 85, 243, 104, + 19, 20, 85, 74, 19, 20, 62, 19, 20, 253, 164, 19, 20, 207, 51, 19, 20, + 180, 207, 51, 19, 20, 207, 20, 19, 20, 180, 207, 20, 19, 20, 207, 12, 19, + 20, 180, 207, 12, 19, 20, 206, 250, 19, 20, 180, 206, 250, 19, 20, 206, + 238, 19, 20, 180, 206, 238, 19, 20, 225, 194, 206, 238, 19, 20, 207, 96, + 19, 20, 180, 207, 96, 19, 20, 207, 95, 19, 20, 180, 207, 95, 19, 20, 225, + 194, 207, 95, 19, 20, 252, 205, 19, 20, 206, 122, 207, 129, 19, 20, 240, + 25, 213, 251, 19, 20, 42, 153, 19, 20, 42, 239, 236, 19, 20, 42, 249, + 154, 160, 218, 148, 19, 20, 42, 211, 102, 160, 218, 148, 19, 20, 42, 48, + 160, 218, 148, 19, 20, 42, 218, 148, 19, 20, 42, 50, 153, 19, 20, 42, 50, + 215, 144, 79, 213, 212, 19, 20, 42, 226, 247, 245, 23, 19, 20, 42, 215, + 144, 194, 91, 19, 20, 42, 220, 218, 19, 20, 42, 130, 212, 201, 19, 20, + 243, 41, 19, 20, 233, 68, 19, 20, 222, 165, 19, 20, 252, 122, 19, 20, + 221, 174, 19, 20, 222, 49, 19, 20, 221, 53, 19, 20, 221, 15, 19, 20, 220, + 211, 19, 20, 220, 187, 19, 20, 206, 122, 220, 187, 19, 20, 85, 239, 53, + 19, 20, 85, 239, 11, 19, 20, 179, 19, 20, 222, 51, 19, 20, 220, 43, 19, + 20, 180, 220, 43, 19, 20, 220, 41, 19, 20, 180, 220, 41, 19, 20, 220, 40, + 19, 20, 180, 220, 40, 19, 20, 220, 38, 19, 20, 180, 220, 38, 19, 20, 220, + 37, 19, 20, 180, 220, 37, 19, 20, 220, 45, 19, 20, 180, 220, 45, 19, 20, + 220, 44, 19, 20, 180, 220, 44, 19, 20, 206, 122, 220, 44, 19, 20, 222, + 67, 19, 20, 180, 222, 67, 19, 20, 85, 239, 155, 19, 20, 212, 131, 19, 20, + 212, 213, 19, 20, 211, 211, 19, 20, 211, 195, 19, 20, 124, 19, 20, 211, + 105, 19, 20, 206, 122, 211, 105, 19, 20, 85, 245, 251, 19, 20, 85, 245, + 168, 19, 20, 212, 219, 19, 20, 212, 215, 19, 20, 210, 128, 19, 20, 180, + 210, 128, 19, 20, 210, 112, 19, 20, 180, 210, 112, 19, 20, 210, 111, 19, + 20, 180, 210, 111, 19, 20, 105, 19, 20, 180, 105, 19, 20, 210, 104, 19, + 20, 180, 210, 104, 19, 20, 210, 130, 19, 20, 180, 210, 130, 19, 20, 210, + 129, 19, 20, 180, 210, 129, 19, 20, 225, 194, 210, 129, 19, 20, 213, 10, + 19, 20, 210, 203, 19, 20, 210, 187, 19, 20, 210, 185, 19, 20, 210, 208, + 19, 20, 231, 224, 19, 20, 232, 59, 19, 20, 231, 123, 19, 20, 231, 111, + 19, 20, 231, 53, 19, 20, 231, 33, 19, 20, 206, 122, 231, 33, 19, 20, 172, + 19, 20, 232, 63, 19, 20, 230, 190, 19, 20, 180, 230, 190, 19, 20, 230, + 188, 19, 20, 180, 230, 188, 19, 20, 230, 187, 19, 20, 180, 230, 187, 19, + 20, 230, 185, 19, 20, 180, 230, 185, 19, 20, 230, 184, 19, 20, 180, 230, + 184, 19, 20, 230, 195, 19, 20, 180, 230, 195, 19, 20, 230, 194, 19, 20, + 180, 230, 194, 19, 20, 225, 194, 230, 194, 19, 20, 232, 76, 19, 20, 230, + 196, 19, 20, 214, 162, 231, 214, 19, 20, 214, 162, 231, 112, 19, 20, 214, + 162, 231, 47, 19, 20, 214, 162, 232, 43, 19, 20, 248, 148, 19, 20, 248, + 255, 19, 20, 247, 251, 19, 20, 247, 241, 19, 20, 247, 174, 19, 20, 247, + 105, 19, 20, 206, 122, 247, 105, 19, 20, 249, 1, 19, 20, 249, 0, 19, 20, + 247, 5, 19, 20, 180, 247, 5, 19, 20, 247, 3, 19, 20, 180, 247, 3, 19, 20, + 247, 2, 19, 20, 180, 247, 2, 19, 20, 247, 1, 19, 20, 180, 247, 1, 19, 20, + 247, 0, 19, 20, 180, 247, 0, 19, 20, 247, 7, 19, 20, 180, 247, 7, 19, 20, + 247, 6, 19, 20, 180, 247, 6, 19, 20, 225, 194, 247, 6, 19, 20, 249, 34, + 19, 20, 217, 114, 212, 58, 19, 20, 227, 119, 19, 20, 228, 17, 19, 20, + 226, 254, 19, 20, 226, 224, 19, 20, 226, 181, 19, 20, 226, 150, 19, 20, + 206, 122, 226, 150, 19, 20, 185, 19, 20, 228, 18, 19, 20, 226, 48, 19, + 20, 180, 226, 48, 19, 20, 226, 46, 19, 20, 180, 226, 46, 19, 20, 226, 45, + 19, 20, 180, 226, 45, 19, 20, 226, 44, 19, 20, 180, 226, 44, 19, 20, 226, + 43, 19, 20, 180, 226, 43, 19, 20, 226, 50, 19, 20, 180, 226, 50, 19, 20, + 226, 49, 19, 20, 180, 226, 49, 19, 20, 225, 194, 226, 49, 19, 20, 229, + 28, 19, 20, 180, 229, 28, 19, 20, 227, 2, 19, 20, 251, 198, 229, 28, 19, + 20, 217, 114, 229, 28, 19, 20, 225, 110, 19, 20, 225, 231, 19, 20, 224, + 230, 19, 20, 224, 205, 19, 20, 224, 67, 19, 20, 224, 56, 19, 20, 206, + 122, 224, 56, 19, 20, 199, 19, 20, 225, 232, 19, 20, 223, 151, 19, 20, + 180, 223, 151, 19, 20, 223, 153, 19, 20, 180, 223, 153, 19, 20, 223, 152, + 19, 20, 180, 223, 152, 19, 20, 225, 194, 223, 152, 19, 20, 226, 33, 19, + 20, 85, 225, 79, 19, 20, 224, 235, 19, 20, 230, 58, 19, 20, 230, 139, 19, + 20, 229, 235, 19, 20, 229, 219, 19, 20, 229, 144, 19, 20, 229, 115, 19, + 20, 206, 122, 229, 115, 19, 20, 230, 141, 19, 20, 230, 140, 19, 20, 229, + 48, 19, 20, 180, 229, 48, 19, 20, 229, 47, 19, 20, 180, 229, 47, 19, 20, + 229, 46, 19, 20, 180, 229, 46, 19, 20, 229, 45, 19, 20, 180, 229, 45, 19, + 20, 229, 44, 19, 20, 180, 229, 44, 19, 20, 229, 50, 19, 20, 180, 229, 50, + 19, 20, 229, 49, 19, 20, 180, 229, 49, 19, 20, 149, 19, 20, 180, 149, 19, + 20, 169, 149, 19, 20, 217, 86, 19, 20, 217, 194, 19, 20, 215, 80, 19, 20, + 215, 61, 19, 20, 214, 193, 19, 20, 214, 174, 19, 20, 206, 122, 214, 174, + 19, 20, 217, 199, 19, 20, 217, 196, 19, 20, 213, 108, 19, 20, 180, 213, + 108, 19, 20, 213, 102, 19, 20, 180, 213, 102, 19, 20, 213, 101, 19, 20, + 180, 213, 101, 19, 20, 213, 97, 19, 20, 180, 213, 97, 19, 20, 213, 96, + 19, 20, 180, 213, 96, 19, 20, 213, 112, 19, 20, 180, 213, 112, 19, 20, + 213, 111, 19, 20, 180, 213, 111, 19, 20, 225, 194, 213, 111, 19, 20, 182, + 19, 20, 251, 198, 182, 19, 20, 213, 113, 19, 20, 249, 199, 182, 19, 20, + 226, 143, 214, 248, 19, 20, 225, 194, 214, 239, 19, 20, 225, 194, 217, + 255, 19, 20, 225, 194, 214, 109, 19, 20, 225, 194, 213, 206, 19, 20, 225, + 194, 214, 238, 19, 20, 225, 194, 217, 89, 19, 20, 215, 214, 19, 20, 215, + 183, 19, 20, 215, 178, 19, 20, 215, 158, 19, 20, 215, 152, 19, 20, 216, + 2, 19, 20, 215, 254, 19, 20, 215, 95, 19, 20, 180, 215, 95, 19, 20, 215, + 94, 19, 20, 180, 215, 94, 19, 20, 215, 93, 19, 20, 180, 215, 93, 19, 20, + 215, 92, 19, 20, 180, 215, 92, 19, 20, 215, 91, 19, 20, 180, 215, 91, 19, + 20, 215, 98, 19, 20, 180, 215, 98, 19, 20, 215, 97, 19, 20, 180, 215, 97, + 19, 20, 216, 4, 19, 20, 206, 52, 19, 20, 206, 107, 19, 20, 206, 11, 19, + 20, 206, 2, 19, 20, 205, 247, 19, 20, 205, 232, 19, 20, 206, 122, 205, + 232, 19, 20, 190, 19, 20, 206, 109, 19, 20, 205, 174, 19, 20, 180, 205, + 174, 19, 20, 205, 173, 19, 20, 180, 205, 173, 19, 20, 205, 172, 19, 20, + 180, 205, 172, 19, 20, 205, 171, 19, 20, 180, 205, 171, 19, 20, 205, 170, + 19, 20, 180, 205, 170, 19, 20, 205, 176, 19, 20, 180, 205, 176, 19, 20, + 205, 175, 19, 20, 180, 205, 175, 19, 20, 225, 194, 205, 175, 19, 20, 206, + 123, 19, 20, 249, 242, 206, 123, 19, 20, 180, 206, 123, 19, 20, 217, 114, + 206, 11, 19, 20, 219, 51, 19, 20, 219, 149, 219, 51, 19, 20, 180, 230, + 58, 19, 20, 219, 108, 19, 20, 218, 208, 19, 20, 218, 154, 19, 20, 218, + 124, 19, 20, 218, 107, 19, 20, 180, 229, 144, 19, 20, 219, 113, 19, 20, + 219, 109, 19, 20, 180, 230, 141, 19, 20, 218, 17, 19, 20, 180, 218, 17, + 19, 20, 137, 19, 20, 180, 137, 19, 20, 169, 137, 19, 20, 242, 28, 19, 20, + 242, 70, 19, 20, 241, 250, 19, 20, 241, 237, 19, 20, 241, 162, 19, 20, + 241, 151, 19, 20, 242, 73, 19, 20, 242, 72, 19, 20, 241, 65, 19, 20, 180, + 241, 65, 19, 20, 242, 139, 19, 20, 212, 41, 19, 20, 226, 31, 212, 41, 19, + 20, 212, 19, 19, 20, 226, 31, 212, 19, 19, 20, 212, 13, 19, 20, 226, 31, + 212, 13, 19, 20, 211, 253, 19, 20, 211, 248, 19, 20, 212, 56, 19, 20, + 212, 55, 19, 20, 211, 221, 19, 20, 180, 211, 221, 19, 20, 212, 58, 19, + 20, 210, 194, 19, 20, 210, 192, 19, 20, 210, 191, 19, 20, 210, 196, 19, + 20, 210, 197, 19, 20, 210, 98, 19, 20, 210, 97, 19, 20, 210, 96, 19, 20, + 210, 100, 19, 20, 223, 172, 239, 71, 19, 20, 223, 172, 239, 11, 19, 20, + 223, 172, 238, 247, 19, 20, 223, 172, 238, 149, 19, 20, 223, 172, 238, + 131, 19, 20, 223, 172, 155, 19, 20, 223, 172, 239, 141, 19, 20, 223, 172, + 239, 155, 19, 20, 223, 171, 239, 155, 19, 20, 238, 239, 19, 20, 220, 15, + 19, 20, 219, 237, 19, 20, 219, 232, 19, 20, 219, 226, 19, 20, 219, 221, + 19, 20, 220, 19, 19, 20, 220, 18, 19, 20, 220, 27, 19, 20, 211, 143, 19, + 20, 211, 141, 19, 20, 211, 140, 19, 20, 211, 144, 19, 20, 180, 219, 51, + 19, 20, 180, 218, 208, 19, 20, 180, 218, 124, 19, 20, 180, 219, 113, 19, + 20, 225, 75, 19, 20, 225, 25, 19, 20, 225, 21, 19, 20, 225, 2, 19, 20, + 224, 253, 19, 20, 225, 77, 19, 20, 225, 76, 19, 20, 225, 79, 19, 20, 224, + 96, 19, 20, 217, 114, 215, 214, 19, 20, 217, 114, 215, 183, 19, 20, 217, + 114, 215, 158, 19, 20, 217, 114, 216, 2, 19, 20, 206, 236, 212, 41, 19, + 20, 206, 236, 212, 19, 19, 20, 206, 236, 211, 253, 19, 20, 206, 236, 212, + 56, 19, 20, 206, 236, 212, 58, 19, 20, 229, 242, 19, 20, 229, 241, 19, + 20, 229, 240, 19, 20, 229, 239, 19, 20, 229, 248, 19, 20, 229, 247, 19, + 20, 229, 249, 19, 20, 212, 57, 212, 41, 19, 20, 212, 57, 212, 19, 19, 20, + 212, 57, 212, 13, 19, 20, 212, 57, 211, 253, 19, 20, 212, 57, 211, 248, + 19, 20, 212, 57, 212, 56, 19, 20, 212, 57, 212, 55, 19, 20, 212, 57, 212, + 58, 19, 20, 252, 192, 251, 150, 19, 20, 249, 199, 75, 19, 20, 249, 199, + 74, 19, 20, 249, 199, 76, 19, 20, 249, 199, 62, 19, 20, 249, 199, 207, + 51, 19, 20, 249, 199, 207, 20, 19, 20, 249, 199, 206, 250, 19, 20, 249, + 199, 207, 96, 19, 20, 249, 199, 225, 110, 19, 20, 249, 199, 224, 230, 19, + 20, 249, 199, 224, 67, 19, 20, 249, 199, 199, 19, 20, 249, 199, 231, 224, + 19, 20, 249, 199, 231, 123, 19, 20, 249, 199, 231, 53, 19, 20, 249, 199, + 172, 19, 20, 217, 114, 239, 71, 19, 20, 217, 114, 239, 11, 19, 20, 217, + 114, 238, 149, 19, 20, 217, 114, 155, 19, 20, 85, 240, 67, 19, 20, 85, + 240, 71, 19, 20, 85, 240, 85, 19, 20, 85, 240, 84, 19, 20, 85, 240, 73, + 19, 20, 85, 240, 99, 19, 20, 85, 218, 50, 19, 20, 85, 218, 124, 19, 20, + 85, 219, 51, 19, 20, 85, 219, 29, 19, 20, 85, 218, 208, 19, 20, 85, 219, + 113, 19, 20, 85, 206, 216, 19, 20, 85, 206, 250, 19, 20, 85, 207, 51, 19, + 20, 85, 207, 45, 19, 20, 85, 207, 20, 19, 20, 85, 207, 96, 19, 20, 85, + 238, 9, 19, 20, 85, 238, 10, 19, 20, 85, 238, 13, 19, 20, 85, 238, 12, + 19, 20, 85, 238, 11, 19, 20, 85, 238, 16, 19, 20, 85, 211, 230, 19, 20, + 85, 211, 253, 19, 20, 85, 212, 41, 19, 20, 85, 212, 39, 19, 20, 85, 212, + 19, 19, 20, 85, 212, 56, 19, 20, 85, 210, 175, 19, 20, 85, 210, 185, 19, + 20, 85, 210, 203, 19, 20, 85, 210, 202, 19, 20, 85, 210, 187, 19, 20, 85, + 210, 208, 19, 20, 85, 220, 82, 19, 20, 85, 220, 211, 19, 20, 85, 221, + 174, 19, 20, 85, 221, 164, 19, 20, 85, 221, 53, 19, 20, 85, 179, 19, 20, + 85, 222, 67, 19, 20, 85, 239, 213, 19, 20, 85, 240, 19, 19, 20, 85, 240, + 170, 19, 20, 85, 240, 162, 19, 20, 85, 240, 61, 19, 20, 85, 240, 244, 19, + 20, 85, 231, 132, 19, 20, 85, 231, 138, 19, 20, 85, 231, 152, 19, 20, 85, + 231, 151, 19, 20, 85, 231, 145, 19, 20, 85, 231, 167, 19, 20, 85, 231, + 67, 19, 20, 85, 231, 68, 19, 20, 85, 231, 71, 19, 20, 85, 231, 70, 19, + 20, 85, 231, 69, 19, 20, 85, 231, 72, 19, 20, 85, 231, 73, 19, 20, 85, + 223, 217, 19, 20, 85, 224, 67, 19, 20, 85, 225, 110, 19, 20, 85, 225, + 106, 19, 20, 85, 224, 230, 19, 20, 85, 199, 19, 20, 85, 226, 114, 19, 20, + 85, 226, 181, 19, 20, 85, 227, 119, 19, 20, 85, 227, 107, 19, 20, 85, + 226, 254, 19, 20, 85, 185, 19, 20, 85, 205, 213, 19, 20, 85, 205, 247, + 19, 20, 85, 206, 52, 19, 20, 85, 206, 49, 19, 20, 85, 206, 11, 19, 20, + 85, 190, 19, 20, 85, 232, 104, 19, 20, 217, 114, 232, 104, 19, 20, 85, + 232, 122, 19, 20, 85, 232, 182, 19, 20, 85, 232, 180, 19, 20, 85, 232, + 162, 19, 20, 217, 114, 232, 162, 19, 20, 85, 232, 200, 19, 20, 85, 232, + 135, 19, 20, 85, 232, 139, 19, 20, 85, 232, 149, 19, 20, 85, 232, 148, + 19, 20, 85, 232, 147, 19, 20, 85, 232, 150, 19, 20, 85, 229, 81, 19, 20, + 85, 229, 144, 19, 20, 85, 230, 58, 19, 20, 85, 230, 50, 19, 20, 85, 229, + 235, 19, 20, 85, 230, 141, 19, 20, 85, 245, 55, 19, 20, 85, 245, 56, 19, + 20, 85, 245, 61, 19, 20, 85, 245, 60, 19, 20, 85, 245, 57, 19, 20, 85, + 245, 62, 19, 20, 85, 229, 238, 19, 20, 85, 229, 240, 19, 20, 85, 229, + 244, 19, 20, 85, 229, 243, 19, 20, 85, 229, 242, 19, 20, 85, 229, 248, + 19, 20, 85, 211, 138, 19, 20, 85, 211, 140, 19, 20, 85, 211, 143, 19, 20, + 85, 211, 142, 19, 20, 85, 211, 141, 19, 20, 85, 211, 144, 19, 20, 85, + 211, 133, 19, 20, 85, 211, 134, 19, 20, 85, 211, 146, 19, 20, 85, 211, + 145, 19, 20, 85, 211, 135, 19, 20, 85, 211, 147, 19, 20, 85, 205, 9, 19, + 20, 85, 205, 19, 19, 20, 85, 205, 93, 19, 20, 85, 205, 91, 19, 20, 85, + 205, 40, 19, 20, 85, 205, 116, 19, 20, 85, 205, 159, 19, 20, 85, 78, 205, + 159, 19, 20, 85, 243, 183, 19, 20, 85, 243, 184, 19, 20, 85, 243, 193, + 19, 20, 85, 243, 192, 19, 20, 85, 243, 187, 19, 20, 85, 243, 196, 19, 20, + 85, 213, 203, 19, 20, 85, 214, 193, 19, 20, 85, 217, 86, 19, 20, 85, 217, + 74, 19, 20, 85, 215, 80, 19, 20, 85, 217, 199, 19, 20, 85, 215, 116, 19, + 20, 85, 215, 158, 19, 20, 85, 215, 214, 19, 20, 85, 215, 212, 19, 20, 85, + 215, 183, 19, 20, 85, 216, 2, 19, 20, 85, 216, 4, 19, 20, 85, 210, 216, + 19, 20, 85, 210, 220, 19, 20, 85, 210, 237, 19, 20, 85, 210, 236, 19, 20, + 85, 210, 222, 19, 20, 85, 210, 243, 19, 20, 85, 248, 14, 19, 20, 85, 248, + 32, 19, 20, 85, 248, 82, 19, 20, 85, 248, 78, 19, 20, 85, 248, 58, 19, + 20, 85, 248, 110, 19, 20, 85, 210, 178, 19, 20, 85, 210, 179, 19, 20, 85, + 210, 182, 19, 20, 85, 210, 181, 19, 20, 85, 210, 180, 19, 20, 85, 210, + 183, 19, 20, 248, 59, 53, 19, 20, 241, 82, 213, 251, 19, 20, 220, 11, 19, + 20, 225, 73, 19, 20, 224, 93, 19, 20, 224, 92, 19, 20, 224, 91, 19, 20, + 224, 90, 19, 20, 224, 95, 19, 20, 224, 94, 19, 20, 206, 236, 211, 219, + 19, 20, 206, 236, 211, 218, 19, 20, 206, 236, 211, 217, 19, 20, 206, 236, + 211, 216, 19, 20, 206, 236, 211, 215, 19, 20, 206, 236, 211, 222, 19, 20, + 206, 236, 211, 221, 19, 20, 206, 236, 42, 212, 58, 19, 20, 249, 199, 207, + 129, 222, 198, 214, 154, 83, 222, 198, 1, 250, 32, 222, 198, 1, 229, 68, + 222, 198, 1, 242, 25, 222, 198, 1, 217, 179, 222, 198, 1, 224, 188, 222, + 198, 1, 210, 15, 222, 198, 1, 246, 119, 222, 198, 1, 211, 170, 222, 198, + 1, 247, 165, 222, 198, 1, 248, 136, 222, 198, 1, 226, 101, 222, 198, 1, + 240, 0, 222, 198, 1, 225, 63, 222, 198, 1, 213, 244, 222, 198, 1, 218, + 44, 222, 198, 1, 252, 202, 222, 198, 1, 222, 156, 222, 198, 1, 209, 194, + 222, 198, 1, 243, 128, 222, 198, 1, 232, 252, 222, 198, 1, 243, 129, 222, + 198, 1, 222, 122, 222, 198, 1, 209, 250, 222, 198, 1, 233, 108, 222, 198, + 1, 243, 126, 222, 198, 1, 221, 154, 222, 198, 242, 24, 83, 222, 198, 218, + 224, 242, 24, 83, 181, 1, 242, 14, 242, 6, 242, 29, 242, 139, 181, 1, + 209, 148, 181, 1, 209, 179, 209, 195, 71, 181, 1, 205, 216, 181, 1, 206, + 123, 181, 1, 207, 129, 181, 1, 211, 224, 211, 223, 211, 246, 181, 1, 242, + 196, 181, 1, 252, 92, 62, 181, 1, 222, 107, 76, 181, 1, 253, 25, 62, 181, + 1, 252, 232, 181, 1, 229, 121, 76, 181, 1, 215, 137, 76, 181, 1, 76, 181, + 1, 222, 206, 181, 1, 222, 165, 181, 1, 219, 88, 219, 101, 219, 14, 137, + 181, 1, 231, 239, 181, 1, 248, 132, 181, 1, 231, 240, 232, 76, 181, 1, + 241, 55, 181, 1, 243, 28, 181, 1, 240, 165, 239, 161, 241, 55, 181, 1, + 240, 204, 181, 1, 206, 208, 206, 199, 207, 129, 181, 1, 239, 133, 239, + 155, 181, 1, 239, 137, 239, 155, 181, 1, 229, 123, 239, 155, 181, 1, 215, + 140, 239, 155, 181, 1, 225, 189, 223, 135, 225, 190, 226, 33, 181, 1, + 215, 138, 226, 33, 181, 1, 244, 18, 181, 1, 232, 231, 232, 235, 232, 222, + 74, 181, 1, 75, 181, 1, 232, 173, 232, 203, 181, 1, 240, 149, 181, 1, + 229, 124, 252, 248, 181, 1, 215, 142, 62, 181, 1, 232, 214, 243, 2, 181, + 1, 221, 111, 221, 136, 222, 67, 181, 1, 252, 165, 243, 0, 181, 1, 214, + 159, 182, 181, 1, 215, 65, 229, 120, 182, 181, 1, 215, 136, 182, 181, 1, + 249, 34, 181, 1, 205, 159, 181, 1, 211, 152, 211, 163, 210, 87, 213, 10, + 181, 1, 215, 135, 213, 10, 181, 1, 246, 240, 181, 1, 250, 13, 250, 16, + 249, 205, 251, 150, 181, 1, 215, 141, 251, 150, 181, 1, 244, 17, 181, 1, + 222, 136, 181, 1, 243, 91, 243, 93, 75, 181, 1, 227, 212, 227, 222, 229, + 28, 181, 1, 229, 122, 229, 28, 181, 1, 215, 139, 229, 28, 181, 1, 230, + 73, 230, 119, 229, 131, 149, 181, 1, 244, 19, 181, 1, 233, 41, 181, 1, + 233, 42, 181, 1, 246, 133, 246, 139, 246, 240, 181, 1, 222, 101, 242, + 195, 76, 181, 1, 243, 124, 181, 1, 232, 251, 181, 1, 247, 4, 181, 1, 248, + 240, 181, 1, 248, 147, 181, 1, 214, 31, 181, 1, 229, 119, 181, 1, 215, + 134, 181, 1, 237, 180, 181, 1, 220, 27, 181, 1, 206, 195, 181, 215, 41, + 220, 71, 181, 226, 95, 220, 71, 181, 247, 60, 220, 71, 181, 252, 1, 93, + 181, 210, 132, 93, 181, 250, 30, 93, 181, 1, 232, 76, 181, 1, 216, 4, + 181, 1, 222, 152, 181, 1, 241, 109, 248, 186, 222, 106, 181, 1, 241, 109, + 248, 186, 232, 234, 181, 1, 241, 109, 248, 186, 243, 92, 181, 1, 241, + 109, 248, 186, 253, 24, 181, 1, 241, 109, 248, 186, 252, 232, 212, 197, + 1, 62, 212, 197, 1, 74, 212, 197, 1, 71, 212, 197, 1, 172, 212, 197, 1, + 240, 244, 212, 197, 1, 225, 77, 212, 197, 1, 212, 219, 212, 197, 1, 246, + 145, 212, 197, 1, 199, 212, 197, 1, 179, 212, 197, 1, 250, 183, 212, 197, + 1, 185, 212, 197, 1, 190, 212, 197, 1, 230, 141, 212, 197, 1, 207, 96, + 212, 197, 1, 217, 199, 212, 197, 1, 155, 212, 197, 22, 3, 74, 212, 197, + 22, 3, 71, 212, 197, 3, 208, 188, 239, 99, 1, 62, 239, 99, 1, 74, 239, + 99, 1, 71, 239, 99, 1, 172, 239, 99, 1, 240, 244, 239, 99, 1, 225, 77, + 239, 99, 1, 212, 219, 239, 99, 1, 246, 145, 239, 99, 1, 199, 239, 99, 1, + 179, 239, 99, 1, 250, 183, 239, 99, 1, 185, 239, 99, 1, 190, 239, 99, 1, + 219, 113, 239, 99, 1, 230, 141, 239, 99, 1, 207, 96, 239, 99, 1, 217, + 199, 239, 99, 1, 155, 239, 99, 22, 3, 74, 239, 99, 22, 3, 71, 239, 99, 3, + 222, 8, 221, 71, 215, 41, 220, 71, 221, 71, 50, 220, 71, 249, 93, 1, 62, + 249, 93, 1, 74, 249, 93, 1, 71, 249, 93, 1, 172, 249, 93, 1, 240, 244, + 249, 93, 1, 225, 77, 249, 93, 1, 212, 219, 249, 93, 1, 246, 145, 249, 93, + 1, 199, 249, 93, 1, 179, 249, 93, 1, 250, 183, 249, 93, 1, 185, 249, 93, + 1, 190, 249, 93, 1, 219, 113, 249, 93, 1, 230, 141, 249, 93, 1, 207, 96, + 249, 93, 1, 217, 199, 249, 93, 1, 155, 249, 93, 22, 3, 74, 249, 93, 22, + 3, 71, 212, 196, 1, 62, 212, 196, 1, 74, 212, 196, 1, 71, 212, 196, 1, + 172, 212, 196, 1, 240, 244, 212, 196, 1, 225, 77, 212, 196, 1, 212, 219, + 212, 196, 1, 246, 145, 212, 196, 1, 199, 212, 196, 1, 179, 212, 196, 1, + 250, 183, 212, 196, 1, 185, 212, 196, 1, 190, 212, 196, 1, 230, 141, 212, + 196, 1, 207, 96, 212, 196, 1, 217, 199, 212, 196, 22, 3, 74, 212, 196, + 22, 3, 71, 82, 1, 172, 82, 1, 231, 167, 82, 1, 231, 53, 82, 1, 231, 138, + 82, 1, 225, 2, 82, 1, 249, 1, 82, 1, 248, 110, 82, 1, 247, 174, 82, 1, + 248, 32, 82, 1, 223, 110, 82, 1, 246, 145, 82, 1, 210, 196, 82, 1, 245, + 51, 82, 1, 210, 191, 82, 1, 224, 73, 82, 1, 212, 219, 82, 1, 212, 56, 82, + 1, 124, 82, 1, 211, 253, 82, 1, 224, 67, 82, 1, 250, 183, 82, 1, 221, 93, + 82, 1, 220, 211, 82, 1, 221, 66, 82, 1, 226, 181, 82, 1, 205, 247, 82, 1, + 218, 124, 82, 1, 229, 144, 82, 1, 208, 173, 82, 1, 216, 2, 82, 1, 214, + 56, 82, 1, 217, 199, 82, 1, 155, 82, 1, 230, 141, 82, 1, 220, 19, 82, + 233, 55, 22, 220, 5, 82, 233, 55, 22, 220, 18, 82, 233, 55, 22, 219, 237, + 82, 233, 55, 22, 219, 232, 82, 233, 55, 22, 219, 214, 82, 233, 55, 22, + 219, 184, 82, 233, 55, 22, 219, 172, 82, 233, 55, 22, 219, 171, 82, 233, + 55, 22, 218, 9, 82, 233, 55, 22, 218, 2, 82, 233, 55, 22, 229, 42, 82, + 233, 55, 22, 229, 31, 82, 233, 55, 22, 219, 255, 82, 233, 55, 22, 220, + 11, 82, 233, 55, 22, 219, 222, 210, 95, 102, 82, 233, 55, 22, 219, 222, + 210, 95, 105, 82, 233, 55, 22, 220, 1, 82, 22, 233, 40, 252, 41, 82, 22, + 233, 40, 253, 164, 82, 22, 3, 253, 164, 82, 22, 3, 74, 82, 22, 3, 233, + 102, 82, 22, 3, 206, 123, 82, 22, 3, 205, 169, 82, 22, 3, 71, 82, 22, 3, + 209, 162, 82, 22, 3, 210, 18, 82, 22, 3, 222, 206, 82, 22, 3, 190, 82, + 22, 3, 233, 129, 82, 22, 3, 75, 82, 22, 3, 252, 248, 82, 22, 3, 252, 205, + 82, 22, 3, 222, 152, 82, 22, 3, 251, 184, 82, 3, 224, 203, 82, 3, 219, + 49, 82, 3, 205, 180, 82, 3, 226, 60, 82, 3, 211, 39, 82, 3, 250, 131, 82, + 3, 218, 119, 82, 3, 211, 128, 82, 3, 232, 34, 82, 3, 252, 207, 82, 3, + 217, 152, 217, 145, 82, 3, 208, 185, 82, 3, 247, 168, 82, 3, 250, 104, + 82, 3, 231, 159, 82, 3, 250, 126, 82, 3, 248, 229, 221, 16, 230, 201, 82, + 3, 230, 27, 211, 105, 82, 3, 250, 2, 82, 3, 221, 68, 226, 111, 82, 3, + 231, 31, 82, 247, 25, 16, 218, 200, 82, 3, 251, 166, 82, 3, 251, 187, 82, + 18, 205, 85, 82, 18, 102, 82, 18, 105, 82, 18, 142, 82, 18, 139, 82, 18, + 168, 82, 18, 184, 82, 18, 195, 82, 18, 193, 82, 18, 200, 82, 16, 230, 27, + 251, 189, 214, 177, 82, 16, 230, 27, 251, 189, 226, 80, 82, 16, 230, 27, + 251, 189, 221, 15, 82, 16, 230, 27, 251, 189, 250, 33, 82, 16, 230, 27, + 251, 189, 249, 73, 82, 16, 230, 27, 251, 189, 220, 152, 82, 16, 230, 27, + 251, 189, 220, 146, 82, 16, 230, 27, 251, 189, 220, 144, 82, 16, 230, 27, + 251, 189, 220, 150, 82, 16, 230, 27, 251, 189, 220, 148, 90, 249, 217, + 90, 243, 54, 90, 247, 155, 90, 241, 82, 213, 251, 90, 247, 162, 90, 241, + 125, 245, 21, 90, 211, 127, 214, 187, 237, 239, 90, 215, 78, 4, 249, 150, + 227, 187, 90, 227, 218, 247, 155, 90, 227, 218, 241, 82, 213, 251, 90, + 224, 186, 90, 241, 108, 54, 217, 60, 102, 90, 241, 108, 54, 217, 60, 105, + 90, 241, 108, 54, 217, 60, 142, 90, 22, 216, 39, 90, 18, 205, 85, 90, 18, + 102, 90, 18, 105, 90, 18, 142, 90, 18, 139, 90, 18, 168, 90, 18, 184, 90, + 18, 195, 90, 18, 193, 90, 18, 200, 90, 1, 62, 90, 1, 75, 90, 1, 74, 90, + 1, 76, 90, 1, 71, 90, 1, 222, 206, 90, 1, 210, 3, 90, 1, 243, 104, 90, 1, + 199, 90, 1, 252, 114, 90, 1, 250, 183, 90, 1, 179, 90, 1, 220, 19, 90, 1, + 240, 244, 90, 1, 185, 90, 1, 230, 141, 90, 1, 217, 199, 90, 1, 216, 2, + 90, 1, 212, 219, 90, 1, 246, 145, 90, 1, 248, 110, 90, 1, 232, 200, 90, + 1, 190, 90, 1, 219, 113, 90, 1, 207, 96, 90, 1, 242, 73, 90, 1, 172, 90, + 1, 231, 167, 90, 1, 210, 243, 90, 1, 205, 116, 90, 1, 239, 141, 90, 1, + 205, 12, 90, 1, 229, 248, 90, 1, 205, 67, 90, 1, 248, 58, 90, 1, 211, + 127, 152, 22, 53, 90, 1, 211, 127, 75, 90, 1, 211, 127, 74, 90, 1, 211, + 127, 76, 90, 1, 211, 127, 71, 90, 1, 211, 127, 222, 206, 90, 1, 211, 127, + 210, 3, 90, 1, 211, 127, 252, 114, 90, 1, 211, 127, 250, 183, 90, 1, 211, + 127, 179, 90, 1, 211, 127, 220, 19, 90, 1, 211, 127, 240, 244, 90, 1, + 211, 127, 185, 90, 1, 211, 127, 212, 219, 90, 1, 211, 127, 246, 145, 90, + 1, 211, 127, 248, 110, 90, 1, 211, 127, 232, 200, 90, 1, 211, 127, 210, + 243, 90, 1, 211, 127, 190, 90, 1, 211, 127, 207, 96, 90, 1, 211, 127, + 172, 90, 1, 211, 127, 240, 241, 90, 1, 211, 127, 239, 141, 90, 1, 211, + 127, 232, 161, 90, 1, 211, 127, 224, 228, 90, 1, 211, 127, 243, 196, 90, + 1, 215, 78, 75, 90, 1, 215, 78, 74, 90, 1, 215, 78, 232, 211, 90, 1, 215, + 78, 210, 3, 90, 1, 215, 78, 71, 90, 1, 215, 78, 252, 114, 90, 1, 215, 78, + 172, 90, 1, 215, 78, 240, 244, 90, 1, 215, 78, 155, 90, 1, 215, 78, 179, + 90, 1, 215, 78, 216, 2, 90, 1, 215, 78, 212, 219, 90, 1, 215, 78, 246, + 145, 90, 1, 215, 78, 232, 200, 90, 1, 215, 78, 242, 73, 90, 1, 215, 78, + 240, 241, 90, 1, 215, 78, 239, 141, 90, 1, 215, 78, 210, 243, 90, 1, 215, + 78, 205, 116, 90, 1, 215, 78, 219, 109, 90, 1, 215, 78, 248, 110, 90, 1, + 215, 78, 205, 81, 90, 1, 227, 218, 74, 90, 1, 227, 218, 172, 90, 1, 227, + 218, 219, 113, 90, 1, 227, 218, 242, 73, 90, 1, 227, 218, 205, 81, 90, 1, + 252, 164, 240, 224, 252, 74, 102, 90, 1, 252, 164, 240, 224, 208, 184, + 102, 90, 1, 252, 164, 240, 224, 246, 108, 90, 1, 252, 164, 240, 224, 210, + 13, 90, 1, 252, 164, 240, 224, 233, 2, 210, 13, 90, 1, 252, 164, 240, + 224, 250, 143, 90, 1, 252, 164, 240, 224, 129, 250, 143, 90, 1, 252, 164, + 240, 224, 62, 90, 1, 252, 164, 240, 224, 74, 90, 1, 252, 164, 240, 224, + 172, 90, 1, 252, 164, 240, 224, 225, 77, 90, 1, 252, 164, 240, 224, 249, + 1, 90, 1, 252, 164, 240, 224, 210, 208, 90, 1, 252, 164, 240, 224, 210, + 196, 90, 1, 252, 164, 240, 224, 246, 54, 90, 1, 252, 164, 240, 224, 224, + 103, 90, 1, 252, 164, 240, 224, 212, 219, 90, 1, 252, 164, 240, 224, 246, + 145, 90, 1, 252, 164, 240, 224, 179, 90, 1, 252, 164, 240, 224, 221, 93, + 90, 1, 252, 164, 240, 224, 214, 96, 90, 1, 252, 164, 240, 224, 205, 81, + 90, 1, 252, 164, 240, 224, 205, 116, 90, 1, 252, 164, 240, 224, 252, 213, + 90, 1, 211, 127, 252, 164, 240, 224, 212, 219, 90, 1, 211, 127, 252, 164, + 240, 224, 205, 81, 90, 1, 227, 218, 252, 164, 240, 224, 240, 99, 90, 1, + 227, 218, 252, 164, 240, 224, 225, 77, 90, 1, 227, 218, 252, 164, 240, + 224, 249, 1, 90, 1, 227, 218, 252, 164, 240, 224, 232, 170, 90, 1, 227, + 218, 252, 164, 240, 224, 210, 208, 90, 1, 227, 218, 252, 164, 240, 224, + 246, 38, 90, 1, 227, 218, 252, 164, 240, 224, 212, 219, 90, 1, 227, 218, + 252, 164, 240, 224, 245, 192, 90, 1, 227, 218, 252, 164, 240, 224, 214, + 96, 90, 1, 227, 218, 252, 164, 240, 224, 246, 254, 90, 1, 227, 218, 252, + 164, 240, 224, 205, 81, 90, 1, 227, 218, 252, 164, 240, 224, 205, 116, + 90, 1, 252, 164, 240, 224, 160, 71, 90, 1, 252, 164, 240, 224, 160, 190, + 90, 1, 227, 218, 252, 164, 240, 224, 250, 0, 90, 1, 252, 164, 240, 224, + 246, 134, 90, 1, 227, 218, 252, 164, 240, 224, 229, 248, 19, 20, 222, 71, + 19, 20, 251, 159, 19, 20, 253, 119, 19, 20, 207, 54, 19, 20, 220, 158, + 19, 20, 221, 183, 19, 20, 220, 36, 19, 20, 212, 140, 19, 20, 231, 231, + 19, 20, 230, 192, 19, 20, 227, 162, 19, 20, 224, 26, 19, 20, 225, 185, + 19, 20, 230, 68, 19, 20, 214, 157, 19, 20, 217, 116, 19, 20, 215, 124, + 19, 20, 215, 218, 19, 20, 215, 90, 19, 20, 205, 222, 19, 20, 206, 58, 19, + 20, 219, 58, 19, 20, 223, 150, 19, 20, 222, 187, 223, 150, 19, 20, 223, + 149, 19, 20, 222, 187, 223, 149, 19, 20, 223, 148, 19, 20, 222, 187, 223, + 148, 19, 20, 223, 147, 19, 20, 222, 187, 223, 147, 19, 20, 218, 14, 19, + 20, 218, 13, 19, 20, 218, 12, 19, 20, 218, 11, 19, 20, 218, 10, 19, 20, + 218, 18, 19, 20, 222, 187, 222, 67, 19, 20, 222, 187, 213, 10, 19, 20, + 222, 187, 232, 76, 19, 20, 222, 187, 249, 34, 19, 20, 222, 187, 229, 28, + 19, 20, 222, 187, 226, 33, 19, 20, 222, 187, 182, 19, 20, 222, 187, 216, + 4, 19, 20, 243, 115, 207, 129, 19, 20, 207, 34, 207, 129, 19, 20, 42, 5, + 218, 148, 19, 20, 42, 219, 81, 245, 23, 19, 20, 219, 149, 218, 15, 19, + 20, 180, 229, 115, 19, 20, 180, 230, 140, 19, 20, 211, 220, 19, 20, 211, + 222, 19, 20, 210, 188, 19, 20, 210, 190, 19, 20, 210, 195, 19, 20, 211, + 137, 19, 20, 211, 139, 19, 20, 217, 114, 215, 95, 19, 20, 217, 114, 215, + 152, 19, 20, 217, 114, 238, 131, 19, 20, 85, 239, 169, 19, 20, 85, 245, + 225, 240, 162, 19, 20, 85, 240, 241, 19, 20, 85, 239, 174, 19, 20, 217, + 114, 232, 86, 19, 20, 85, 232, 84, 19, 20, 250, 53, 245, 225, 149, 19, + 20, 250, 53, 245, 225, 137, 19, 20, 85, 245, 220, 182, 229, 215, 208, + 154, 230, 5, 229, 215, 1, 172, 229, 215, 1, 231, 167, 229, 215, 1, 240, + 244, 229, 215, 1, 240, 99, 229, 215, 1, 225, 77, 229, 215, 1, 249, 1, + 229, 215, 1, 248, 110, 229, 215, 1, 232, 200, 229, 215, 1, 232, 170, 229, + 215, 1, 206, 77, 229, 215, 1, 212, 219, 229, 215, 1, 212, 56, 229, 215, + 1, 246, 145, 229, 215, 1, 245, 192, 229, 215, 1, 199, 229, 215, 1, 179, + 229, 215, 1, 221, 93, 229, 215, 1, 250, 183, 229, 215, 1, 250, 0, 229, + 215, 1, 185, 229, 215, 1, 190, 229, 215, 1, 219, 113, 229, 215, 1, 230, + 141, 229, 215, 1, 207, 96, 229, 215, 1, 216, 2, 229, 215, 1, 214, 96, + 229, 215, 1, 217, 199, 229, 215, 1, 155, 229, 215, 1, 239, 165, 229, 215, + 1, 211, 83, 229, 215, 22, 3, 62, 229, 215, 22, 3, 74, 229, 215, 22, 3, + 71, 229, 215, 22, 3, 243, 104, 229, 215, 22, 3, 252, 205, 229, 215, 22, + 3, 222, 152, 229, 215, 22, 3, 251, 184, 229, 215, 22, 3, 75, 229, 215, + 22, 3, 76, 229, 215, 213, 191, 1, 190, 229, 215, 213, 191, 1, 219, 113, + 229, 215, 213, 191, 1, 207, 96, 229, 215, 5, 1, 172, 229, 215, 5, 1, 225, + 77, 229, 215, 5, 1, 252, 73, 229, 215, 5, 1, 212, 219, 229, 215, 5, 1, + 199, 229, 215, 5, 1, 179, 229, 215, 5, 1, 185, 229, 215, 5, 1, 219, 113, + 229, 215, 5, 1, 230, 141, 229, 215, 3, 226, 99, 229, 215, 3, 231, 209, + 229, 215, 3, 217, 197, 229, 215, 3, 229, 115, 229, 215, 242, 168, 83, + 229, 215, 219, 196, 83, 229, 215, 18, 205, 85, 229, 215, 18, 102, 229, + 215, 18, 105, 229, 215, 18, 142, 229, 215, 18, 139, 229, 215, 18, 168, + 229, 215, 18, 184, 229, 215, 18, 195, 229, 215, 18, 193, 229, 215, 18, + 200, 41, 230, 59, 1, 172, 41, 230, 59, 1, 206, 181, 41, 230, 59, 1, 225, + 77, 41, 230, 59, 1, 210, 243, 41, 230, 59, 1, 217, 199, 41, 230, 59, 1, + 190, 41, 230, 59, 1, 212, 219, 41, 230, 59, 1, 212, 56, 41, 230, 59, 1, + 230, 141, 41, 230, 59, 1, 179, 41, 230, 59, 1, 221, 93, 41, 230, 59, 1, + 185, 41, 230, 59, 1, 242, 73, 41, 230, 59, 1, 209, 70, 41, 230, 59, 1, + 155, 41, 230, 59, 1, 220, 19, 41, 230, 59, 1, 231, 167, 41, 230, 59, 1, + 210, 233, 41, 230, 59, 1, 199, 41, 230, 59, 1, 62, 41, 230, 59, 1, 74, + 41, 230, 59, 1, 243, 104, 41, 230, 59, 1, 243, 92, 41, 230, 59, 1, 71, + 41, 230, 59, 1, 222, 152, 41, 230, 59, 1, 76, 41, 230, 59, 1, 210, 3, 41, + 230, 59, 1, 75, 41, 230, 59, 1, 251, 182, 41, 230, 59, 1, 252, 205, 41, + 230, 59, 1, 211, 116, 41, 230, 59, 1, 211, 115, 41, 230, 59, 1, 211, 114, + 41, 230, 59, 1, 211, 113, 41, 230, 59, 1, 211, 112, 186, 41, 229, 75, 1, + 127, 220, 19, 186, 41, 229, 75, 1, 114, 220, 19, 186, 41, 229, 75, 1, + 127, 172, 186, 41, 229, 75, 1, 127, 206, 181, 186, 41, 229, 75, 1, 127, + 225, 77, 186, 41, 229, 75, 1, 114, 172, 186, 41, 229, 75, 1, 114, 206, + 181, 186, 41, 229, 75, 1, 114, 225, 77, 186, 41, 229, 75, 1, 127, 210, + 243, 186, 41, 229, 75, 1, 127, 217, 199, 186, 41, 229, 75, 1, 127, 190, + 186, 41, 229, 75, 1, 114, 210, 243, 186, 41, 229, 75, 1, 114, 217, 199, + 186, 41, 229, 75, 1, 114, 190, 186, 41, 229, 75, 1, 127, 212, 219, 186, + 41, 229, 75, 1, 127, 212, 56, 186, 41, 229, 75, 1, 127, 199, 186, 41, + 229, 75, 1, 114, 212, 219, 186, 41, 229, 75, 1, 114, 212, 56, 186, 41, + 229, 75, 1, 114, 199, 186, 41, 229, 75, 1, 127, 179, 186, 41, 229, 75, 1, + 127, 221, 93, 186, 41, 229, 75, 1, 127, 185, 186, 41, 229, 75, 1, 114, + 179, 186, 41, 229, 75, 1, 114, 221, 93, 186, 41, 229, 75, 1, 114, 185, + 186, 41, 229, 75, 1, 127, 242, 73, 186, 41, 229, 75, 1, 127, 209, 70, + 186, 41, 229, 75, 1, 127, 230, 141, 186, 41, 229, 75, 1, 114, 242, 73, + 186, 41, 229, 75, 1, 114, 209, 70, 186, 41, 229, 75, 1, 114, 230, 141, + 186, 41, 229, 75, 1, 127, 155, 186, 41, 229, 75, 1, 127, 246, 145, 186, + 41, 229, 75, 1, 127, 250, 183, 186, 41, 229, 75, 1, 114, 155, 186, 41, + 229, 75, 1, 114, 246, 145, 186, 41, 229, 75, 1, 114, 250, 183, 186, 41, + 229, 75, 1, 127, 230, 197, 186, 41, 229, 75, 1, 127, 206, 148, 186, 41, + 229, 75, 1, 114, 230, 197, 186, 41, 229, 75, 1, 114, 206, 148, 186, 41, + 229, 75, 1, 127, 213, 202, 186, 41, 229, 75, 1, 114, 213, 202, 186, 41, + 229, 75, 22, 3, 22, 215, 132, 186, 41, 229, 75, 22, 3, 253, 164, 186, 41, + 229, 75, 22, 3, 233, 102, 186, 41, 229, 75, 22, 3, 71, 186, 41, 229, 75, + 22, 3, 209, 162, 186, 41, 229, 75, 22, 3, 75, 186, 41, 229, 75, 22, 3, + 252, 248, 186, 41, 229, 75, 22, 3, 76, 186, 41, 229, 75, 22, 3, 222, 230, + 186, 41, 229, 75, 22, 3, 210, 3, 186, 41, 229, 75, 22, 3, 251, 159, 186, + 41, 229, 75, 22, 3, 253, 119, 186, 41, 229, 75, 22, 3, 209, 154, 186, 41, + 229, 75, 22, 3, 222, 71, 186, 41, 229, 75, 22, 3, 222, 227, 186, 41, 229, + 75, 22, 3, 209, 255, 186, 41, 229, 75, 22, 3, 232, 211, 186, 41, 229, 75, + 1, 42, 209, 148, 186, 41, 229, 75, 1, 42, 225, 79, 186, 41, 229, 75, 1, + 42, 226, 33, 186, 41, 229, 75, 1, 42, 229, 28, 186, 41, 229, 75, 1, 42, + 232, 76, 186, 41, 229, 75, 1, 42, 246, 240, 186, 41, 229, 75, 1, 42, 251, + 150, 186, 41, 229, 75, 135, 227, 191, 186, 41, 229, 75, 135, 227, 190, + 186, 41, 229, 75, 18, 205, 85, 186, 41, 229, 75, 18, 102, 186, 41, 229, + 75, 18, 105, 186, 41, 229, 75, 18, 142, 186, 41, 229, 75, 18, 139, 186, + 41, 229, 75, 18, 168, 186, 41, 229, 75, 18, 184, 186, 41, 229, 75, 18, + 195, 186, 41, 229, 75, 18, 193, 186, 41, 229, 75, 18, 200, 186, 41, 229, + 75, 99, 18, 102, 186, 41, 229, 75, 3, 230, 125, 186, 41, 229, 75, 3, 230, + 124, 82, 16, 221, 191, 82, 16, 226, 81, 231, 49, 82, 16, 221, 16, 231, + 49, 82, 16, 250, 34, 231, 49, 82, 16, 249, 74, 231, 49, 82, 16, 220, 153, + 231, 49, 82, 16, 220, 147, 231, 49, 82, 16, 220, 145, 231, 49, 82, 16, + 220, 151, 231, 49, 82, 16, 220, 149, 231, 49, 82, 16, 246, 95, 231, 49, + 82, 16, 246, 91, 231, 49, 82, 16, 246, 90, 231, 49, 82, 16, 246, 93, 231, + 49, 82, 16, 246, 92, 231, 49, 82, 16, 246, 89, 231, 49, 82, 16, 210, 137, + 82, 16, 226, 81, 218, 118, 82, 16, 221, 16, 218, 118, 82, 16, 250, 34, + 218, 118, 82, 16, 249, 74, 218, 118, 82, 16, 220, 153, 218, 118, 82, 16, + 220, 147, 218, 118, 82, 16, 220, 145, 218, 118, 82, 16, 220, 151, 218, + 118, 82, 16, 220, 149, 218, 118, 82, 16, 246, 95, 218, 118, 82, 16, 246, + 91, 218, 118, 82, 16, 246, 90, 218, 118, 82, 16, 246, 93, 218, 118, 82, + 16, 246, 92, 218, 118, 82, 16, 246, 89, 218, 118, 249, 94, 1, 172, 249, + 94, 1, 240, 244, 249, 94, 1, 225, 77, 249, 94, 1, 225, 20, 249, 94, 1, + 179, 249, 94, 1, 250, 183, 249, 94, 1, 185, 249, 94, 1, 226, 118, 249, + 94, 1, 212, 219, 249, 94, 1, 246, 145, 249, 94, 1, 199, 249, 94, 1, 224, + 24, 249, 94, 1, 249, 1, 249, 94, 1, 232, 200, 249, 94, 1, 223, 144, 249, + 94, 1, 223, 136, 249, 94, 1, 190, 249, 94, 1, 219, 113, 249, 94, 1, 230, + 141, 249, 94, 1, 209, 70, 249, 94, 1, 217, 199, 249, 94, 1, 62, 249, 94, + 1, 155, 249, 94, 22, 3, 74, 249, 94, 22, 3, 71, 249, 94, 22, 3, 75, 249, + 94, 22, 3, 76, 249, 94, 22, 3, 252, 248, 249, 94, 222, 20, 249, 94, 243, + 34, 73, 217, 76, 41, 99, 1, 127, 172, 41, 99, 1, 127, 231, 167, 41, 99, + 1, 127, 230, 181, 41, 99, 1, 114, 172, 41, 99, 1, 114, 230, 181, 41, 99, + 1, 114, 231, 167, 41, 99, 1, 225, 77, 41, 99, 1, 127, 249, 1, 41, 99, 1, + 127, 248, 110, 41, 99, 1, 114, 249, 1, 41, 99, 1, 114, 217, 199, 41, 99, + 1, 114, 248, 110, 41, 99, 1, 223, 144, 41, 99, 1, 219, 64, 41, 99, 1, + 127, 219, 62, 41, 99, 1, 246, 145, 41, 99, 1, 114, 219, 62, 41, 99, 1, + 219, 73, 41, 99, 1, 127, 212, 219, 41, 99, 1, 127, 212, 56, 41, 99, 1, + 114, 212, 219, 41, 99, 1, 114, 212, 56, 41, 99, 1, 199, 41, 99, 1, 250, + 183, 41, 99, 1, 127, 179, 41, 99, 1, 127, 221, 93, 41, 99, 1, 127, 242, + 73, 41, 99, 1, 114, 179, 41, 99, 1, 114, 242, 73, 41, 99, 1, 114, 221, + 93, 41, 99, 1, 185, 41, 99, 1, 114, 190, 41, 99, 1, 127, 190, 41, 99, 1, + 219, 113, 41, 99, 1, 218, 46, 41, 99, 1, 230, 141, 41, 99, 1, 229, 74, + 41, 99, 1, 207, 96, 41, 99, 1, 127, 216, 2, 41, 99, 1, 127, 214, 96, 41, + 99, 1, 127, 217, 199, 41, 99, 1, 127, 155, 41, 99, 1, 229, 172, 41, 99, + 1, 62, 41, 99, 1, 114, 155, 41, 99, 1, 74, 41, 99, 1, 233, 102, 41, 99, + 1, 71, 41, 99, 1, 209, 162, 41, 99, 1, 243, 104, 41, 99, 1, 222, 152, 41, + 99, 1, 230, 125, 41, 99, 1, 239, 232, 217, 199, 41, 99, 107, 3, 169, 219, + 113, 41, 99, 107, 3, 169, 230, 141, 41, 99, 107, 3, 230, 142, 212, 172, + 230, 114, 41, 99, 3, 227, 240, 232, 24, 230, 114, 41, 99, 107, 3, 42, + 225, 77, 41, 99, 107, 3, 114, 179, 41, 99, 107, 3, 127, 219, 63, 222, + 123, 114, 179, 41, 99, 107, 3, 185, 41, 99, 107, 3, 250, 183, 41, 99, + 107, 3, 217, 199, 41, 99, 3, 217, 174, 41, 99, 22, 3, 62, 41, 99, 22, 3, + 227, 240, 217, 133, 41, 99, 22, 3, 253, 164, 41, 99, 22, 3, 212, 178, + 253, 164, 41, 99, 22, 3, 74, 41, 99, 22, 3, 233, 102, 41, 99, 22, 3, 210, + 3, 41, 99, 22, 3, 209, 161, 41, 99, 22, 3, 71, 41, 99, 22, 3, 209, 162, + 41, 99, 22, 3, 76, 41, 99, 22, 3, 222, 231, 55, 41, 99, 22, 3, 222, 71, + 41, 99, 22, 3, 75, 41, 99, 22, 3, 252, 248, 41, 99, 22, 3, 222, 152, 41, + 99, 22, 3, 252, 205, 41, 99, 22, 3, 99, 252, 205, 41, 99, 22, 3, 222, + 231, 52, 41, 99, 3, 227, 240, 232, 23, 41, 99, 3, 211, 117, 41, 99, 3, + 211, 116, 41, 99, 3, 231, 128, 211, 115, 41, 99, 3, 231, 128, 211, 114, + 41, 99, 3, 231, 128, 211, 113, 41, 99, 3, 219, 114, 239, 140, 41, 99, 3, + 227, 240, 217, 161, 41, 99, 3, 231, 127, 232, 6, 41, 99, 36, 247, 43, + 245, 23, 41, 99, 238, 123, 18, 205, 85, 41, 99, 238, 123, 18, 102, 41, + 99, 238, 123, 18, 105, 41, 99, 238, 123, 18, 142, 41, 99, 238, 123, 18, + 139, 41, 99, 238, 123, 18, 168, 41, 99, 238, 123, 18, 184, 41, 99, 238, + 123, 18, 195, 41, 99, 238, 123, 18, 193, 41, 99, 238, 123, 18, 200, 41, + 99, 99, 18, 205, 85, 41, 99, 99, 18, 102, 41, 99, 99, 18, 105, 41, 99, + 99, 18, 142, 41, 99, 99, 18, 139, 41, 99, 99, 18, 168, 41, 99, 99, 18, + 184, 41, 99, 99, 18, 195, 41, 99, 99, 18, 193, 41, 99, 99, 18, 200, 41, + 99, 3, 207, 19, 41, 99, 3, 207, 18, 41, 99, 3, 217, 120, 41, 99, 3, 231, + 198, 41, 99, 3, 238, 52, 41, 99, 3, 245, 37, 41, 99, 3, 218, 224, 218, + 97, 219, 73, 41, 99, 3, 227, 240, 206, 78, 41, 99, 3, 232, 58, 41, 99, 3, + 232, 57, 41, 99, 3, 217, 128, 41, 99, 3, 217, 127, 41, 99, 3, 239, 101, + 41, 99, 3, 248, 254, 36, 244, 13, 247, 228, 253, 21, 36, 245, 165, 36, + 233, 45, 36, 173, 45, 36, 211, 36, 245, 23, 36, 206, 194, 55, 36, 207, + 14, 229, 206, 55, 36, 222, 142, 141, 55, 36, 50, 222, 142, 141, 55, 36, + 147, 248, 130, 213, 225, 55, 36, 213, 211, 248, 130, 213, 225, 55, 36, + 221, 218, 52, 36, 50, 221, 218, 52, 36, 221, 218, 55, 36, 221, 218, 222, + 82, 117, 3, 209, 244, 218, 202, 117, 3, 209, 244, 248, 219, 117, 3, 248, + 144, 117, 3, 213, 131, 117, 3, 249, 214, 117, 1, 252, 187, 117, 1, 252, + 188, 212, 122, 117, 1, 233, 98, 117, 1, 233, 99, 212, 122, 117, 1, 209, + 247, 117, 1, 209, 248, 212, 122, 117, 1, 219, 114, 218, 254, 117, 1, 219, + 114, 218, 255, 212, 122, 117, 1, 230, 142, 230, 21, 117, 1, 230, 142, + 230, 22, 212, 122, 117, 1, 243, 73, 117, 1, 252, 203, 117, 1, 222, 183, + 117, 1, 222, 184, 212, 122, 117, 1, 172, 117, 1, 232, 66, 227, 243, 117, + 1, 240, 244, 117, 1, 240, 245, 240, 5, 117, 1, 225, 77, 117, 1, 249, 1, + 117, 1, 249, 2, 230, 128, 117, 1, 232, 200, 117, 1, 232, 201, 232, 174, + 117, 1, 223, 144, 117, 1, 212, 220, 230, 77, 117, 1, 212, 220, 226, 76, + 227, 243, 117, 1, 246, 146, 226, 76, 252, 146, 117, 1, 246, 146, 226, 76, + 227, 243, 117, 1, 225, 237, 219, 76, 117, 1, 212, 219, 117, 1, 212, 220, + 212, 144, 117, 1, 246, 145, 117, 1, 246, 146, 228, 6, 117, 1, 199, 117, + 1, 179, 117, 1, 222, 52, 232, 18, 117, 1, 250, 183, 117, 1, 250, 184, + 231, 210, 117, 1, 185, 117, 1, 190, 117, 1, 219, 113, 117, 1, 230, 141, + 117, 1, 207, 96, 117, 1, 217, 200, 217, 184, 117, 1, 217, 200, 217, 140, + 117, 1, 217, 199, 117, 1, 155, 117, 3, 218, 245, 117, 22, 3, 212, 122, + 117, 22, 3, 209, 243, 117, 22, 3, 209, 244, 217, 136, 117, 22, 3, 213, + 164, 117, 22, 3, 213, 165, 233, 90, 117, 22, 3, 219, 114, 218, 254, 117, + 22, 3, 219, 114, 218, 255, 212, 122, 117, 22, 3, 230, 142, 230, 21, 117, + 22, 3, 230, 142, 230, 22, 212, 122, 117, 22, 3, 212, 179, 117, 22, 3, + 212, 180, 218, 254, 117, 22, 3, 212, 180, 212, 122, 117, 22, 3, 212, 180, + 218, 255, 212, 122, 117, 22, 3, 221, 134, 117, 22, 3, 221, 135, 212, 122, + 117, 253, 0, 252, 255, 117, 1, 232, 46, 217, 135, 117, 1, 231, 134, 217, + 135, 117, 1, 210, 80, 217, 135, 117, 1, 243, 98, 217, 135, 117, 1, 209, + 40, 217, 135, 117, 1, 205, 107, 217, 135, 117, 1, 251, 202, 217, 135, + 117, 18, 205, 85, 117, 18, 102, 117, 18, 105, 117, 18, 142, 117, 18, 139, + 117, 18, 168, 117, 18, 184, 117, 18, 195, 117, 18, 193, 117, 18, 200, + 117, 221, 244, 117, 222, 14, 117, 207, 7, 117, 248, 197, 222, 7, 117, + 248, 197, 215, 58, 117, 248, 197, 221, 215, 117, 222, 13, 117, 30, 16, + 245, 29, 117, 30, 16, 245, 224, 117, 30, 16, 243, 223, 117, 30, 16, 246, + 98, 117, 30, 16, 246, 99, 213, 131, 117, 30, 16, 245, 112, 117, 30, 16, + 246, 138, 117, 30, 16, 245, 201, 117, 30, 16, 246, 120, 117, 30, 16, 246, + 99, 240, 164, 117, 30, 16, 36, 212, 117, 117, 30, 16, 36, 243, 32, 117, + 30, 16, 36, 231, 205, 117, 30, 16, 36, 231, 207, 117, 30, 16, 36, 232, + 178, 117, 30, 16, 36, 231, 206, 2, 232, 178, 117, 30, 16, 36, 231, 208, + 2, 232, 178, 117, 30, 16, 36, 250, 20, 117, 30, 16, 36, 240, 9, 117, 30, + 16, 218, 165, 222, 142, 243, 233, 117, 30, 16, 218, 165, 222, 142, 246, + 136, 117, 30, 16, 218, 165, 247, 192, 210, 162, 117, 30, 16, 218, 165, + 247, 192, 212, 187, 117, 30, 16, 230, 44, 222, 142, 222, 2, 117, 30, 16, + 230, 44, 222, 142, 220, 70, 117, 30, 16, 230, 44, 247, 192, 220, 236, + 117, 30, 16, 230, 44, 247, 192, 220, 222, 117, 30, 16, 230, 44, 222, 142, + 221, 5, 213, 153, 3, 221, 241, 213, 153, 3, 221, 254, 213, 153, 3, 221, + 250, 213, 153, 1, 62, 213, 153, 1, 74, 213, 153, 1, 71, 213, 153, 1, 252, + 248, 213, 153, 1, 76, 213, 153, 1, 75, 213, 153, 1, 242, 192, 213, 153, + 1, 172, 213, 153, 1, 220, 19, 213, 153, 1, 240, 244, 213, 153, 1, 225, + 77, 213, 153, 1, 249, 1, 213, 153, 1, 232, 200, 213, 153, 1, 205, 116, + 213, 153, 1, 223, 144, 213, 153, 1, 212, 219, 213, 153, 1, 246, 145, 213, + 153, 1, 199, 213, 153, 1, 179, 213, 153, 1, 242, 73, 213, 153, 1, 209, + 70, 213, 153, 1, 250, 183, 213, 153, 1, 185, 213, 153, 1, 190, 213, 153, + 1, 219, 113, 213, 153, 1, 230, 141, 213, 153, 1, 207, 96, 213, 153, 1, + 217, 199, 213, 153, 1, 206, 181, 213, 153, 1, 155, 213, 153, 107, 3, 222, + 11, 213, 153, 107, 3, 221, 243, 213, 153, 107, 3, 221, 240, 213, 153, 22, + 3, 222, 1, 213, 153, 22, 3, 221, 239, 213, 153, 22, 3, 222, 5, 213, 153, + 22, 3, 221, 249, 213, 153, 22, 3, 222, 12, 213, 153, 22, 3, 222, 3, 213, + 153, 3, 222, 15, 213, 153, 3, 208, 188, 213, 153, 107, 3, 221, 204, 185, + 213, 153, 107, 3, 221, 204, 207, 96, 213, 153, 1, 231, 167, 213, 153, 1, + 213, 90, 213, 153, 18, 205, 85, 213, 153, 18, 102, 213, 153, 18, 105, + 213, 153, 18, 142, 213, 153, 18, 139, 213, 153, 18, 168, 213, 153, 18, + 184, 213, 153, 18, 195, 213, 153, 18, 193, 213, 153, 18, 200, 213, 153, + 251, 167, 213, 153, 1, 218, 227, 213, 153, 1, 230, 2, 213, 153, 1, 250, + 0, 213, 153, 1, 42, 232, 76, 213, 153, 1, 42, 229, 28, 250, 107, 1, 62, + 250, 107, 1, 215, 50, 62, 250, 107, 1, 155, 250, 107, 1, 215, 50, 155, + 250, 107, 1, 227, 216, 155, 250, 107, 1, 250, 183, 250, 107, 1, 232, 3, + 250, 183, 250, 107, 1, 179, 250, 107, 1, 215, 50, 179, 250, 107, 1, 199, + 250, 107, 1, 227, 216, 199, 250, 107, 1, 207, 96, 250, 107, 1, 215, 50, + 207, 96, 250, 107, 1, 222, 27, 207, 96, 250, 107, 1, 240, 244, 250, 107, + 1, 215, 50, 240, 244, 250, 107, 1, 232, 200, 250, 107, 1, 246, 145, 250, + 107, 1, 219, 113, 250, 107, 1, 215, 50, 219, 113, 250, 107, 1, 185, 250, + 107, 1, 215, 50, 185, 250, 107, 1, 214, 161, 212, 219, 250, 107, 1, 224, + 46, 212, 219, 250, 107, 1, 217, 199, 250, 107, 1, 215, 50, 217, 199, 250, + 107, 1, 227, 216, 217, 199, 250, 107, 1, 190, 250, 107, 1, 215, 50, 190, + 250, 107, 1, 225, 77, 250, 107, 1, 230, 141, 250, 107, 1, 215, 50, 230, + 141, 250, 107, 1, 223, 144, 250, 107, 1, 249, 1, 250, 107, 1, 225, 151, + 250, 107, 1, 227, 153, 250, 107, 1, 74, 250, 107, 1, 71, 250, 107, 3, + 211, 121, 250, 107, 22, 3, 75, 250, 107, 22, 3, 222, 27, 75, 250, 107, + 22, 3, 243, 104, 250, 107, 22, 3, 74, 250, 107, 22, 3, 232, 3, 74, 250, + 107, 22, 3, 76, 250, 107, 22, 3, 232, 3, 76, 250, 107, 22, 3, 71, 250, + 107, 22, 3, 106, 33, 215, 50, 217, 199, 250, 107, 107, 3, 225, 79, 250, + 107, 107, 3, 239, 155, 250, 107, 221, 252, 250, 107, 221, 248, 250, 107, + 16, 249, 222, 225, 237, 227, 61, 250, 107, 16, 249, 222, 221, 8, 250, + 107, 16, 249, 222, 232, 101, 250, 107, 16, 249, 222, 221, 252, 230, 12, + 1, 172, 230, 12, 1, 231, 65, 230, 12, 1, 231, 167, 230, 12, 1, 240, 244, + 230, 12, 1, 240, 31, 230, 12, 1, 225, 77, 230, 12, 1, 249, 1, 230, 12, 1, + 248, 110, 230, 12, 1, 232, 200, 230, 12, 1, 223, 144, 230, 12, 1, 212, + 219, 230, 12, 1, 212, 56, 230, 12, 1, 246, 145, 230, 12, 1, 199, 230, 12, + 1, 179, 230, 12, 1, 220, 240, 230, 12, 1, 221, 93, 230, 12, 1, 242, 73, + 230, 12, 1, 241, 198, 230, 12, 1, 250, 183, 230, 12, 1, 249, 203, 230, + 12, 1, 185, 230, 12, 1, 226, 188, 230, 12, 1, 210, 243, 230, 12, 1, 210, + 233, 230, 12, 1, 243, 196, 230, 12, 1, 190, 230, 12, 1, 219, 113, 230, + 12, 1, 230, 141, 230, 12, 1, 155, 230, 12, 1, 238, 237, 230, 12, 1, 209, + 70, 230, 12, 1, 217, 199, 230, 12, 1, 216, 2, 230, 12, 1, 207, 96, 230, + 12, 1, 62, 230, 12, 213, 191, 1, 190, 230, 12, 213, 191, 1, 219, 113, + 230, 12, 22, 3, 253, 164, 230, 12, 22, 3, 74, 230, 12, 22, 3, 76, 230, + 12, 22, 3, 222, 152, 230, 12, 22, 3, 71, 230, 12, 22, 3, 209, 162, 230, + 12, 22, 3, 75, 230, 12, 107, 3, 232, 76, 230, 12, 107, 3, 229, 28, 230, + 12, 107, 3, 149, 230, 12, 107, 3, 226, 33, 230, 12, 107, 3, 222, 67, 230, + 12, 107, 3, 137, 230, 12, 107, 3, 213, 10, 230, 12, 107, 3, 223, 118, + 230, 12, 107, 3, 232, 23, 230, 12, 3, 219, 74, 230, 12, 3, 223, 184, 230, + 12, 220, 72, 212, 217, 230, 12, 220, 72, 223, 129, 211, 214, 212, 217, + 230, 12, 220, 72, 248, 117, 230, 12, 220, 72, 210, 225, 248, 117, 230, + 12, 220, 72, 210, 224, 230, 12, 18, 205, 85, 230, 12, 18, 102, 230, 12, + 18, 105, 230, 12, 18, 142, 230, 12, 18, 139, 230, 12, 18, 168, 230, 12, + 18, 184, 230, 12, 18, 195, 230, 12, 18, 193, 230, 12, 18, 200, 230, 12, + 1, 210, 208, 230, 12, 1, 210, 196, 230, 12, 1, 246, 54, 222, 181, 248, + 51, 18, 205, 85, 222, 181, 248, 51, 18, 102, 222, 181, 248, 51, 18, 105, + 222, 181, 248, 51, 18, 142, 222, 181, 248, 51, 18, 139, 222, 181, 248, + 51, 18, 168, 222, 181, 248, 51, 18, 184, 222, 181, 248, 51, 18, 195, 222, + 181, 248, 51, 18, 193, 222, 181, 248, 51, 18, 200, 222, 181, 248, 51, 1, + 230, 141, 222, 181, 248, 51, 1, 251, 199, 222, 181, 248, 51, 1, 252, 220, + 222, 181, 248, 51, 1, 252, 114, 222, 181, 248, 51, 1, 252, 181, 222, 181, + 248, 51, 1, 230, 140, 222, 181, 248, 51, 1, 253, 126, 222, 181, 248, 51, + 1, 253, 127, 222, 181, 248, 51, 1, 253, 125, 222, 181, 248, 51, 1, 253, + 120, 222, 181, 248, 51, 1, 229, 235, 222, 181, 248, 51, 1, 232, 234, 222, + 181, 248, 51, 1, 233, 103, 222, 181, 248, 51, 1, 232, 255, 222, 181, 248, + 51, 1, 232, 243, 222, 181, 248, 51, 1, 229, 81, 222, 181, 248, 51, 1, + 210, 10, 222, 181, 248, 51, 1, 210, 8, 222, 181, 248, 51, 1, 209, 211, + 222, 181, 248, 51, 1, 209, 154, 222, 181, 248, 51, 1, 230, 58, 222, 181, + 248, 51, 1, 242, 253, 222, 181, 248, 51, 1, 243, 107, 222, 181, 248, 51, + 1, 243, 41, 222, 181, 248, 51, 1, 242, 229, 222, 181, 248, 51, 1, 229, + 144, 222, 181, 248, 51, 1, 222, 100, 222, 181, 248, 51, 1, 222, 226, 222, + 181, 248, 51, 1, 222, 88, 222, 181, 248, 51, 1, 222, 194, 222, 181, 248, + 51, 226, 115, 210, 173, 222, 181, 248, 51, 240, 239, 210, 174, 222, 181, + 248, 51, 226, 113, 210, 174, 222, 181, 248, 51, 219, 12, 222, 181, 248, + 51, 221, 91, 222, 181, 248, 51, 252, 212, 222, 181, 248, 51, 220, 72, + 226, 109, 222, 181, 248, 51, 220, 72, 50, 226, 109, 213, 153, 220, 72, + 249, 222, 213, 124, 213, 153, 220, 72, 249, 222, 221, 253, 213, 153, 220, + 72, 249, 222, 220, 60, 213, 153, 220, 72, 249, 222, 248, 242, 213, 153, + 220, 72, 249, 222, 230, 3, 217, 132, 213, 153, 220, 72, 249, 222, 232, + 66, 217, 132, 213, 153, 220, 72, 249, 222, 246, 146, 217, 132, 213, 153, + 220, 72, 249, 222, 250, 184, 217, 132, 209, 36, 135, 232, 1, 209, 36, + 135, 215, 229, 209, 36, 135, 220, 135, 209, 36, 3, 224, 206, 209, 36, 3, + 206, 86, 226, 245, 213, 115, 209, 36, 135, 206, 86, 252, 217, 233, 55, + 213, 115, 209, 36, 135, 206, 86, 233, 55, 213, 115, 209, 36, 135, 206, + 86, 231, 245, 233, 55, 213, 115, 209, 36, 135, 248, 220, 55, 209, 36, + 135, 206, 86, 231, 245, 233, 55, 213, 116, 217, 102, 209, 36, 135, 50, + 213, 115, 209, 36, 135, 211, 36, 213, 115, 209, 36, 135, 231, 245, 252, + 75, 209, 36, 135, 67, 55, 209, 36, 135, 118, 177, 55, 209, 36, 135, 129, + 177, 55, 209, 36, 135, 218, 155, 232, 0, 233, 55, 213, 115, 209, 36, 135, + 251, 197, 233, 55, 213, 115, 209, 36, 3, 208, 184, 213, 115, 209, 36, 3, + 208, 184, 210, 5, 209, 36, 3, 218, 224, 208, 184, 210, 5, 209, 36, 3, + 208, 184, 252, 75, 209, 36, 3, 218, 224, 208, 184, 252, 75, 209, 36, 3, + 208, 184, 210, 6, 2, 212, 191, 209, 36, 3, 208, 184, 252, 76, 2, 212, + 191, 209, 36, 3, 252, 74, 252, 90, 209, 36, 3, 252, 74, 250, 156, 209, + 36, 3, 252, 74, 209, 61, 209, 36, 3, 252, 74, 209, 62, 2, 212, 191, 209, + 36, 3, 211, 157, 209, 36, 3, 239, 23, 152, 252, 73, 209, 36, 3, 152, 252, + 73, 209, 36, 3, 218, 52, 152, 252, 73, 209, 36, 3, 252, 74, 210, 12, 226, + 100, 209, 36, 3, 252, 15, 209, 36, 3, 218, 97, 252, 15, 209, 36, 135, + 248, 220, 52, 209, 36, 3, 232, 156, 209, 36, 3, 209, 204, 209, 36, 135, + 218, 149, 52, 209, 36, 135, 50, 218, 149, 52, 7, 1, 5, 6, 62, 7, 1, 5, 6, + 252, 248, 7, 5, 1, 201, 252, 248, 7, 1, 5, 6, 250, 123, 251, 150, 7, 1, + 5, 6, 249, 34, 7, 1, 5, 6, 246, 240, 7, 1, 5, 6, 242, 196, 7, 1, 5, 6, + 75, 7, 5, 1, 201, 222, 142, 75, 7, 5, 1, 201, 74, 7, 1, 5, 6, 232, 203, + 7, 1, 5, 6, 232, 76, 7, 1, 5, 6, 230, 159, 2, 91, 7, 1, 5, 6, 229, 28, 7, + 1, 5, 6, 218, 224, 226, 33, 7, 1, 5, 6, 76, 7, 1, 5, 6, 222, 142, 76, 7, + 5, 1, 215, 73, 76, 7, 5, 1, 215, 73, 222, 142, 76, 7, 5, 1, 215, 73, 148, + 2, 91, 7, 5, 1, 201, 222, 206, 7, 1, 5, 6, 222, 97, 7, 5, 1, 211, 102, + 160, 76, 7, 5, 1, 249, 154, 160, 76, 7, 1, 5, 6, 222, 67, 7, 1, 5, 6, + 218, 224, 137, 7, 1, 5, 6, 201, 137, 7, 1, 5, 6, 213, 10, 7, 1, 5, 6, 71, + 7, 5, 1, 215, 73, 71, 7, 5, 1, 215, 73, 245, 164, 71, 7, 5, 1, 215, 73, + 201, 229, 28, 7, 1, 5, 6, 209, 148, 7, 1, 5, 6, 207, 129, 7, 1, 5, 6, + 205, 159, 7, 1, 5, 6, 242, 141, 7, 1, 208, 170, 230, 83, 214, 126, 7, 1, + 252, 200, 27, 1, 5, 6, 240, 215, 27, 1, 5, 6, 230, 102, 27, 1, 5, 6, 221, + 53, 27, 1, 5, 6, 218, 210, 27, 1, 5, 6, 220, 93, 34, 1, 5, 6, 243, 68, + 65, 1, 6, 62, 65, 1, 6, 252, 248, 65, 1, 6, 251, 150, 65, 1, 6, 250, 123, + 251, 150, 65, 1, 6, 246, 240, 65, 1, 6, 75, 65, 1, 6, 218, 224, 75, 65, + 1, 6, 241, 55, 65, 1, 6, 239, 155, 65, 1, 6, 74, 65, 1, 6, 232, 203, 65, + 1, 6, 232, 76, 65, 1, 6, 149, 65, 1, 6, 229, 28, 65, 1, 6, 226, 33, 65, + 1, 6, 218, 224, 226, 33, 65, 1, 6, 76, 65, 1, 6, 222, 97, 65, 1, 6, 222, + 67, 65, 1, 6, 137, 65, 1, 6, 213, 10, 65, 1, 6, 71, 65, 1, 6, 207, 129, + 65, 1, 5, 62, 65, 1, 5, 201, 62, 65, 1, 5, 252, 144, 65, 1, 5, 201, 252, + 248, 65, 1, 5, 251, 150, 65, 1, 5, 246, 240, 65, 1, 5, 75, 65, 1, 5, 217, + 100, 65, 1, 5, 222, 142, 75, 65, 1, 5, 201, 222, 142, 75, 65, 1, 5, 241, + 55, 65, 1, 5, 201, 74, 65, 1, 5, 232, 76, 65, 1, 5, 229, 28, 65, 1, 5, + 243, 28, 65, 1, 5, 76, 65, 1, 5, 222, 142, 76, 65, 1, 5, 211, 102, 160, + 76, 65, 1, 5, 249, 154, 160, 76, 65, 1, 5, 222, 67, 65, 1, 5, 213, 10, + 65, 1, 5, 71, 65, 1, 5, 215, 73, 71, 65, 1, 5, 201, 229, 28, 65, 1, 5, + 209, 148, 65, 1, 5, 252, 200, 65, 1, 5, 250, 8, 65, 1, 5, 27, 240, 215, + 65, 1, 5, 245, 227, 65, 1, 5, 27, 221, 78, 65, 1, 5, 248, 58, 7, 213, + 183, 5, 1, 74, 7, 213, 183, 5, 1, 137, 7, 213, 183, 5, 1, 71, 7, 213, + 183, 5, 1, 209, 148, 27, 213, 183, 5, 1, 250, 8, 27, 213, 183, 5, 1, 240, + 215, 27, 213, 183, 5, 1, 218, 210, 27, 213, 183, 5, 1, 221, 78, 27, 213, + 183, 5, 1, 248, 58, 7, 5, 1, 210, 3, 7, 5, 1, 63, 2, 226, 247, 211, 180, + 7, 5, 1, 246, 241, 2, 226, 247, 211, 180, 7, 5, 1, 242, 140, 2, 226, 247, + 211, 180, 7, 5, 1, 229, 29, 2, 226, 247, 211, 180, 7, 5, 1, 226, 34, 2, + 226, 247, 211, 180, 7, 5, 1, 222, 68, 2, 226, 247, 211, 180, 7, 5, 1, + 219, 150, 2, 226, 247, 211, 180, 7, 5, 1, 219, 150, 2, 241, 211, 23, 226, + 247, 211, 180, 7, 5, 1, 218, 1, 2, 226, 247, 211, 180, 7, 5, 1, 213, 11, + 2, 226, 247, 211, 180, 7, 5, 1, 205, 160, 2, 226, 247, 211, 180, 7, 5, 1, + 201, 241, 55, 65, 1, 34, 243, 41, 7, 5, 1, 233, 23, 241, 55, 7, 5, 1, + 212, 59, 2, 213, 229, 7, 5, 6, 1, 237, 225, 2, 91, 7, 5, 1, 232, 250, 2, + 91, 7, 5, 1, 222, 68, 2, 91, 7, 5, 6, 1, 106, 2, 91, 7, 5, 1, 209, 201, + 2, 91, 7, 5, 1, 63, 2, 222, 26, 109, 7, 5, 1, 246, 241, 2, 222, 26, 109, + 7, 5, 1, 242, 140, 2, 222, 26, 109, 7, 5, 1, 241, 56, 2, 222, 26, 109, 7, + 5, 1, 232, 77, 2, 222, 26, 109, 7, 5, 1, 230, 159, 2, 222, 26, 109, 7, 5, + 1, 229, 29, 2, 222, 26, 109, 7, 5, 1, 226, 34, 2, 222, 26, 109, 7, 5, 1, + 222, 68, 2, 222, 26, 109, 7, 5, 1, 219, 150, 2, 222, 26, 109, 7, 5, 1, + 218, 1, 2, 222, 26, 109, 7, 5, 1, 242, 216, 2, 222, 26, 109, 7, 5, 1, + 209, 149, 2, 222, 26, 109, 7, 5, 1, 206, 196, 2, 222, 26, 109, 7, 5, 1, + 205, 160, 2, 222, 26, 109, 7, 5, 1, 32, 2, 218, 230, 109, 7, 5, 1, 252, + 145, 2, 218, 230, 109, 7, 5, 1, 246, 241, 2, 238, 130, 23, 212, 191, 7, + 5, 1, 174, 2, 218, 230, 109, 7, 5, 1, 222, 142, 174, 2, 218, 230, 109, 7, + 5, 1, 218, 224, 222, 142, 174, 2, 218, 230, 109, 7, 5, 1, 217, 101, 2, + 218, 230, 109, 7, 5, 1, 237, 225, 2, 218, 230, 109, 7, 5, 1, 222, 142, + 148, 2, 218, 230, 109, 7, 5, 1, 242, 216, 2, 218, 230, 109, 7, 5, 1, 106, + 2, 218, 230, 109, 7, 5, 1, 242, 142, 2, 218, 230, 109, 65, 1, 5, 201, + 252, 144, 65, 1, 5, 249, 34, 65, 1, 5, 249, 35, 2, 247, 27, 65, 1, 5, + 242, 196, 65, 1, 5, 218, 224, 222, 142, 75, 65, 1, 5, 242, 139, 65, 1, 5, + 245, 22, 232, 204, 2, 91, 65, 1, 5, 121, 241, 55, 65, 1, 5, 201, 239, + 155, 65, 1, 5, 237, 225, 2, 91, 65, 1, 5, 232, 249, 65, 1, 5, 6, 74, 65, + 1, 5, 6, 237, 225, 2, 91, 65, 1, 5, 232, 204, 2, 247, 56, 65, 1, 5, 230, + 159, 2, 218, 230, 109, 65, 1, 5, 230, 159, 2, 222, 26, 109, 65, 1, 5, 6, + 149, 65, 1, 5, 229, 29, 2, 109, 65, 1, 5, 201, 229, 29, 2, 152, 230, 34, + 65, 1, 5, 226, 34, 2, 47, 109, 65, 1, 5, 226, 34, 2, 218, 230, 109, 65, + 1, 5, 6, 226, 33, 65, 1, 5, 250, 123, 76, 65, 1, 5, 221, 78, 65, 1, 5, + 218, 1, 2, 109, 65, 1, 5, 242, 215, 65, 1, 5, 213, 11, 2, 222, 26, 109, + 65, 1, 5, 106, 134, 65, 1, 5, 209, 200, 65, 1, 5, 6, 71, 65, 1, 5, 209, + 149, 2, 109, 65, 1, 5, 201, 209, 148, 65, 1, 5, 205, 159, 65, 1, 5, 205, + 160, 2, 218, 230, 109, 65, 1, 5, 205, 160, 2, 247, 27, 65, 1, 5, 242, + 141, 65, 1, 5, 212, 23, 36, 244, 21, 239, 237, 253, 21, 36, 244, 21, 253, + 9, 253, 21, 36, 214, 205, 55, 36, 213, 122, 83, 36, 228, 12, 36, 239, + 234, 36, 228, 10, 36, 253, 7, 36, 239, 235, 36, 253, 8, 36, 7, 5, 1, 219, + 150, 55, 36, 249, 121, 36, 228, 11, 36, 50, 247, 228, 52, 36, 222, 197, + 52, 36, 205, 31, 55, 36, 232, 235, 55, 36, 209, 195, 52, 36, 209, 178, + 52, 36, 7, 5, 1, 241, 185, 222, 142, 32, 52, 36, 7, 5, 1, 252, 248, 36, + 7, 5, 1, 252, 71, 36, 7, 5, 1, 251, 168, 36, 7, 5, 1, 249, 35, 248, 141, + 36, 7, 5, 1, 233, 23, 246, 240, 36, 7, 5, 1, 242, 196, 36, 7, 5, 1, 241, + 55, 36, 7, 1, 5, 6, 241, 55, 36, 7, 5, 1, 232, 76, 36, 7, 5, 1, 149, 36, + 7, 1, 5, 6, 149, 36, 7, 1, 5, 6, 229, 28, 36, 7, 5, 1, 226, 33, 36, 7, 1, + 5, 6, 226, 33, 36, 7, 1, 5, 6, 137, 36, 7, 5, 1, 219, 150, 218, 96, 36, + 7, 5, 1, 182, 36, 7, 5, 1, 152, 182, 36, 7, 5, 1, 205, 159, 36, 7, 5, 1, + 252, 144, 36, 7, 5, 1, 251, 150, 36, 7, 5, 1, 250, 8, 36, 7, 5, 1, 217, + 100, 36, 7, 5, 1, 242, 139, 36, 7, 5, 1, 230, 159, 2, 50, 226, 247, 211, + 180, 36, 7, 5, 1, 148, 2, 147, 248, 130, 91, 36, 7, 5, 1, 222, 67, 36, 7, + 5, 1, 242, 215, 36, 7, 5, 1, 106, 2, 147, 248, 130, 91, 36, 7, 5, 1, 207, + 129, 36, 7, 5, 1, 32, 2, 245, 166, 36, 7, 5, 1, 148, 2, 245, 166, 36, 7, + 5, 1, 106, 2, 245, 166, 36, 120, 212, 202, 52, 36, 50, 233, 2, 249, 123, + 55, 36, 252, 149, 146, 211, 130, 55, 36, 47, 251, 244, 52, 36, 48, 251, + 244, 23, 130, 251, 244, 55, 7, 6, 1, 32, 2, 218, 149, 55, 7, 5, 1, 32, 2, + 218, 149, 55, 7, 6, 1, 63, 2, 67, 52, 7, 5, 1, 63, 2, 67, 52, 7, 6, 1, + 63, 2, 67, 55, 7, 5, 1, 63, 2, 67, 55, 7, 6, 1, 63, 2, 229, 206, 55, 7, + 5, 1, 63, 2, 229, 206, 55, 7, 6, 1, 249, 35, 2, 248, 142, 23, 153, 7, 5, + 1, 249, 35, 2, 248, 142, 23, 153, 7, 6, 1, 246, 241, 2, 67, 52, 7, 5, 1, + 246, 241, 2, 67, 52, 7, 6, 1, 246, 241, 2, 67, 55, 7, 5, 1, 246, 241, 2, + 67, 55, 7, 6, 1, 246, 241, 2, 229, 206, 55, 7, 5, 1, 246, 241, 2, 229, + 206, 55, 7, 6, 1, 246, 241, 2, 248, 141, 7, 5, 1, 246, 241, 2, 248, 141, + 7, 6, 1, 246, 241, 2, 247, 228, 55, 7, 5, 1, 246, 241, 2, 247, 228, 55, + 7, 6, 1, 174, 2, 228, 14, 23, 239, 236, 7, 5, 1, 174, 2, 228, 14, 23, + 239, 236, 7, 6, 1, 174, 2, 228, 14, 23, 153, 7, 5, 1, 174, 2, 228, 14, + 23, 153, 7, 6, 1, 174, 2, 247, 228, 55, 7, 5, 1, 174, 2, 247, 228, 55, 7, + 6, 1, 174, 2, 211, 181, 55, 7, 5, 1, 174, 2, 211, 181, 55, 7, 6, 1, 174, + 2, 248, 142, 23, 249, 122, 7, 5, 1, 174, 2, 248, 142, 23, 249, 122, 7, 6, + 1, 242, 140, 2, 67, 52, 7, 5, 1, 242, 140, 2, 67, 52, 7, 6, 1, 241, 56, + 2, 228, 13, 7, 5, 1, 241, 56, 2, 228, 13, 7, 6, 1, 239, 156, 2, 67, 52, + 7, 5, 1, 239, 156, 2, 67, 52, 7, 6, 1, 239, 156, 2, 67, 55, 7, 5, 1, 239, + 156, 2, 67, 55, 7, 6, 1, 239, 156, 2, 245, 166, 7, 5, 1, 239, 156, 2, + 245, 166, 7, 6, 1, 239, 156, 2, 248, 141, 7, 5, 1, 239, 156, 2, 248, 141, + 7, 6, 1, 239, 156, 2, 249, 123, 55, 7, 5, 1, 239, 156, 2, 249, 123, 55, + 7, 6, 1, 237, 225, 2, 211, 181, 55, 7, 5, 1, 237, 225, 2, 211, 181, 55, + 7, 6, 1, 237, 225, 2, 245, 167, 23, 153, 7, 5, 1, 237, 225, 2, 245, 167, + 23, 153, 7, 6, 1, 232, 77, 2, 153, 7, 5, 1, 232, 77, 2, 153, 7, 6, 1, + 232, 77, 2, 67, 55, 7, 5, 1, 232, 77, 2, 67, 55, 7, 6, 1, 232, 77, 2, + 229, 206, 55, 7, 5, 1, 232, 77, 2, 229, 206, 55, 7, 6, 1, 230, 159, 2, + 67, 55, 7, 5, 1, 230, 159, 2, 67, 55, 7, 6, 1, 230, 159, 2, 67, 250, 26, + 23, 228, 13, 7, 5, 1, 230, 159, 2, 67, 250, 26, 23, 228, 13, 7, 6, 1, + 230, 159, 2, 229, 206, 55, 7, 5, 1, 230, 159, 2, 229, 206, 55, 7, 6, 1, + 230, 159, 2, 247, 228, 55, 7, 5, 1, 230, 159, 2, 247, 228, 55, 7, 6, 1, + 229, 29, 2, 153, 7, 5, 1, 229, 29, 2, 153, 7, 6, 1, 229, 29, 2, 67, 52, + 7, 5, 1, 229, 29, 2, 67, 52, 7, 6, 1, 229, 29, 2, 67, 55, 7, 5, 1, 229, + 29, 2, 67, 55, 7, 6, 1, 226, 34, 2, 67, 52, 7, 5, 1, 226, 34, 2, 67, 52, + 7, 6, 1, 226, 34, 2, 67, 55, 7, 5, 1, 226, 34, 2, 67, 55, 7, 6, 1, 226, + 34, 2, 229, 206, 55, 7, 5, 1, 226, 34, 2, 229, 206, 55, 7, 6, 1, 226, 34, + 2, 247, 228, 55, 7, 5, 1, 226, 34, 2, 247, 228, 55, 7, 6, 1, 148, 2, 211, + 181, 23, 153, 7, 5, 1, 148, 2, 211, 181, 23, 153, 7, 6, 1, 148, 2, 211, + 181, 23, 245, 166, 7, 5, 1, 148, 2, 211, 181, 23, 245, 166, 7, 6, 1, 148, + 2, 228, 14, 23, 239, 236, 7, 5, 1, 148, 2, 228, 14, 23, 239, 236, 7, 6, + 1, 148, 2, 228, 14, 23, 153, 7, 5, 1, 148, 2, 228, 14, 23, 153, 7, 6, 1, + 222, 68, 2, 153, 7, 5, 1, 222, 68, 2, 153, 7, 6, 1, 222, 68, 2, 67, 52, + 7, 5, 1, 222, 68, 2, 67, 52, 7, 6, 1, 219, 150, 2, 67, 52, 7, 5, 1, 219, + 150, 2, 67, 52, 7, 6, 1, 219, 150, 2, 67, 55, 7, 5, 1, 219, 150, 2, 67, + 55, 7, 6, 1, 219, 150, 2, 67, 250, 26, 23, 228, 13, 7, 5, 1, 219, 150, 2, + 67, 250, 26, 23, 228, 13, 7, 6, 1, 219, 150, 2, 229, 206, 55, 7, 5, 1, + 219, 150, 2, 229, 206, 55, 7, 6, 1, 218, 1, 2, 67, 52, 7, 5, 1, 218, 1, + 2, 67, 52, 7, 6, 1, 218, 1, 2, 67, 55, 7, 5, 1, 218, 1, 2, 67, 55, 7, 6, + 1, 218, 1, 2, 253, 9, 23, 67, 52, 7, 5, 1, 218, 1, 2, 253, 9, 23, 67, 52, + 7, 6, 1, 218, 1, 2, 248, 196, 23, 67, 52, 7, 5, 1, 218, 1, 2, 248, 196, + 23, 67, 52, 7, 6, 1, 218, 1, 2, 67, 250, 26, 23, 67, 52, 7, 5, 1, 218, 1, + 2, 67, 250, 26, 23, 67, 52, 7, 6, 1, 213, 11, 2, 67, 52, 7, 5, 1, 213, + 11, 2, 67, 52, 7, 6, 1, 213, 11, 2, 67, 55, 7, 5, 1, 213, 11, 2, 67, 55, + 7, 6, 1, 213, 11, 2, 229, 206, 55, 7, 5, 1, 213, 11, 2, 229, 206, 55, 7, + 6, 1, 213, 11, 2, 247, 228, 55, 7, 5, 1, 213, 11, 2, 247, 228, 55, 7, 6, + 1, 106, 2, 245, 167, 55, 7, 5, 1, 106, 2, 245, 167, 55, 7, 6, 1, 106, 2, + 211, 181, 55, 7, 5, 1, 106, 2, 211, 181, 55, 7, 6, 1, 106, 2, 247, 228, + 55, 7, 5, 1, 106, 2, 247, 228, 55, 7, 6, 1, 106, 2, 211, 181, 23, 153, 7, + 5, 1, 106, 2, 211, 181, 23, 153, 7, 6, 1, 106, 2, 228, 14, 23, 245, 166, + 7, 5, 1, 106, 2, 228, 14, 23, 245, 166, 7, 6, 1, 209, 149, 2, 211, 180, + 7, 5, 1, 209, 149, 2, 211, 180, 7, 6, 1, 209, 149, 2, 67, 55, 7, 5, 1, + 209, 149, 2, 67, 55, 7, 6, 1, 207, 130, 2, 239, 236, 7, 5, 1, 207, 130, + 2, 239, 236, 7, 6, 1, 207, 130, 2, 153, 7, 5, 1, 207, 130, 2, 153, 7, 6, + 1, 207, 130, 2, 245, 166, 7, 5, 1, 207, 130, 2, 245, 166, 7, 6, 1, 207, + 130, 2, 67, 52, 7, 5, 1, 207, 130, 2, 67, 52, 7, 6, 1, 207, 130, 2, 67, + 55, 7, 5, 1, 207, 130, 2, 67, 55, 7, 6, 1, 206, 196, 2, 67, 52, 7, 5, 1, + 206, 196, 2, 67, 52, 7, 6, 1, 206, 196, 2, 245, 166, 7, 5, 1, 206, 196, + 2, 245, 166, 7, 6, 1, 206, 124, 2, 67, 52, 7, 5, 1, 206, 124, 2, 67, 52, + 7, 6, 1, 205, 160, 2, 247, 227, 7, 5, 1, 205, 160, 2, 247, 227, 7, 6, 1, + 205, 160, 2, 67, 55, 7, 5, 1, 205, 160, 2, 67, 55, 7, 6, 1, 205, 160, 2, + 229, 206, 55, 7, 5, 1, 205, 160, 2, 229, 206, 55, 7, 5, 1, 239, 156, 2, + 229, 206, 55, 7, 5, 1, 213, 11, 2, 245, 166, 7, 5, 1, 207, 130, 2, 218, + 149, 52, 7, 5, 1, 206, 124, 2, 218, 149, 52, 7, 5, 1, 32, 2, 48, 160, + 218, 148, 7, 5, 1, 152, 218, 1, 2, 67, 52, 7, 5, 1, 152, 218, 1, 2, 245, + 163, 91, 7, 5, 1, 152, 218, 1, 2, 127, 91, 7, 6, 1, 215, 228, 182, 7, 5, + 1, 245, 227, 7, 6, 1, 32, 2, 67, 55, 7, 5, 1, 32, 2, 67, 55, 7, 6, 1, 32, + 2, 238, 130, 52, 7, 5, 1, 32, 2, 238, 130, 52, 7, 6, 1, 32, 2, 247, 228, + 23, 153, 7, 5, 1, 32, 2, 247, 228, 23, 153, 7, 6, 1, 32, 2, 247, 228, 23, + 239, 236, 7, 5, 1, 32, 2, 247, 228, 23, 239, 236, 7, 6, 1, 32, 2, 247, + 228, 23, 238, 130, 52, 7, 5, 1, 32, 2, 247, 228, 23, 238, 130, 52, 7, 6, + 1, 32, 2, 247, 228, 23, 211, 180, 7, 5, 1, 32, 2, 247, 228, 23, 211, 180, + 7, 6, 1, 32, 2, 247, 228, 23, 67, 55, 7, 5, 1, 32, 2, 247, 228, 23, 67, + 55, 7, 6, 1, 32, 2, 249, 123, 23, 153, 7, 5, 1, 32, 2, 249, 123, 23, 153, + 7, 6, 1, 32, 2, 249, 123, 23, 239, 236, 7, 5, 1, 32, 2, 249, 123, 23, + 239, 236, 7, 6, 1, 32, 2, 249, 123, 23, 238, 130, 52, 7, 5, 1, 32, 2, + 249, 123, 23, 238, 130, 52, 7, 6, 1, 32, 2, 249, 123, 23, 211, 180, 7, 5, + 1, 32, 2, 249, 123, 23, 211, 180, 7, 6, 1, 32, 2, 249, 123, 23, 67, 55, + 7, 5, 1, 32, 2, 249, 123, 23, 67, 55, 7, 6, 1, 174, 2, 67, 55, 7, 5, 1, + 174, 2, 67, 55, 7, 6, 1, 174, 2, 238, 130, 52, 7, 5, 1, 174, 2, 238, 130, + 52, 7, 6, 1, 174, 2, 211, 180, 7, 5, 1, 174, 2, 211, 180, 7, 6, 1, 174, + 2, 247, 228, 23, 153, 7, 5, 1, 174, 2, 247, 228, 23, 153, 7, 6, 1, 174, + 2, 247, 228, 23, 239, 236, 7, 5, 1, 174, 2, 247, 228, 23, 239, 236, 7, 6, + 1, 174, 2, 247, 228, 23, 238, 130, 52, 7, 5, 1, 174, 2, 247, 228, 23, + 238, 130, 52, 7, 6, 1, 174, 2, 247, 228, 23, 211, 180, 7, 5, 1, 174, 2, + 247, 228, 23, 211, 180, 7, 6, 1, 174, 2, 247, 228, 23, 67, 55, 7, 5, 1, + 174, 2, 247, 228, 23, 67, 55, 7, 6, 1, 237, 225, 2, 238, 130, 52, 7, 5, + 1, 237, 225, 2, 238, 130, 52, 7, 6, 1, 237, 225, 2, 67, 55, 7, 5, 1, 237, + 225, 2, 67, 55, 7, 6, 1, 148, 2, 67, 55, 7, 5, 1, 148, 2, 67, 55, 7, 6, + 1, 148, 2, 238, 130, 52, 7, 5, 1, 148, 2, 238, 130, 52, 7, 6, 1, 148, 2, + 247, 228, 23, 153, 7, 5, 1, 148, 2, 247, 228, 23, 153, 7, 6, 1, 148, 2, + 247, 228, 23, 239, 236, 7, 5, 1, 148, 2, 247, 228, 23, 239, 236, 7, 6, 1, + 148, 2, 247, 228, 23, 238, 130, 52, 7, 5, 1, 148, 2, 247, 228, 23, 238, + 130, 52, 7, 6, 1, 148, 2, 247, 228, 23, 211, 180, 7, 5, 1, 148, 2, 247, + 228, 23, 211, 180, 7, 6, 1, 148, 2, 247, 228, 23, 67, 55, 7, 5, 1, 148, + 2, 247, 228, 23, 67, 55, 7, 6, 1, 148, 2, 238, 70, 23, 153, 7, 5, 1, 148, + 2, 238, 70, 23, 153, 7, 6, 1, 148, 2, 238, 70, 23, 239, 236, 7, 5, 1, + 148, 2, 238, 70, 23, 239, 236, 7, 6, 1, 148, 2, 238, 70, 23, 238, 130, + 52, 7, 5, 1, 148, 2, 238, 70, 23, 238, 130, 52, 7, 6, 1, 148, 2, 238, 70, + 23, 211, 180, 7, 5, 1, 148, 2, 238, 70, 23, 211, 180, 7, 6, 1, 148, 2, + 238, 70, 23, 67, 55, 7, 5, 1, 148, 2, 238, 70, 23, 67, 55, 7, 6, 1, 106, + 2, 67, 55, 7, 5, 1, 106, 2, 67, 55, 7, 6, 1, 106, 2, 238, 130, 52, 7, 5, + 1, 106, 2, 238, 130, 52, 7, 6, 1, 106, 2, 238, 70, 23, 153, 7, 5, 1, 106, + 2, 238, 70, 23, 153, 7, 6, 1, 106, 2, 238, 70, 23, 239, 236, 7, 5, 1, + 106, 2, 238, 70, 23, 239, 236, 7, 6, 1, 106, 2, 238, 70, 23, 238, 130, + 52, 7, 5, 1, 106, 2, 238, 70, 23, 238, 130, 52, 7, 6, 1, 106, 2, 238, 70, + 23, 211, 180, 7, 5, 1, 106, 2, 238, 70, 23, 211, 180, 7, 6, 1, 106, 2, + 238, 70, 23, 67, 55, 7, 5, 1, 106, 2, 238, 70, 23, 67, 55, 7, 6, 1, 206, + 124, 2, 239, 236, 7, 5, 1, 206, 124, 2, 239, 236, 7, 6, 1, 206, 124, 2, + 67, 55, 7, 5, 1, 206, 124, 2, 67, 55, 7, 6, 1, 206, 124, 2, 238, 130, 52, + 7, 5, 1, 206, 124, 2, 238, 130, 52, 7, 6, 1, 206, 124, 2, 211, 180, 7, 5, + 1, 206, 124, 2, 211, 180, 7, 6, 1, 226, 246, 229, 173, 7, 5, 1, 226, 246, + 229, 173, 7, 6, 1, 226, 246, 209, 148, 7, 5, 1, 226, 246, 209, 148, 7, 6, + 1, 206, 124, 2, 229, 111, 7, 5, 1, 206, 124, 2, 229, 111, 27, 5, 1, 252, + 145, 2, 220, 86, 27, 5, 1, 252, 145, 2, 246, 75, 27, 5, 1, 252, 145, 2, + 220, 87, 23, 209, 54, 27, 5, 1, 252, 145, 2, 246, 76, 23, 209, 54, 27, 5, + 1, 252, 145, 2, 220, 87, 23, 222, 72, 27, 5, 1, 252, 145, 2, 246, 76, 23, + 222, 72, 27, 5, 1, 252, 145, 2, 220, 87, 23, 221, 124, 27, 5, 1, 252, + 145, 2, 246, 76, 23, 221, 124, 27, 6, 1, 252, 145, 2, 220, 86, 27, 6, 1, + 252, 145, 2, 246, 75, 27, 6, 1, 252, 145, 2, 220, 87, 23, 209, 54, 27, 6, + 1, 252, 145, 2, 246, 76, 23, 209, 54, 27, 6, 1, 252, 145, 2, 220, 87, 23, + 222, 72, 27, 6, 1, 252, 145, 2, 246, 76, 23, 222, 72, 27, 6, 1, 252, 145, + 2, 220, 87, 23, 221, 124, 27, 6, 1, 252, 145, 2, 246, 76, 23, 221, 124, + 27, 5, 1, 242, 245, 2, 220, 86, 27, 5, 1, 242, 245, 2, 246, 75, 27, 5, 1, + 242, 245, 2, 220, 87, 23, 209, 54, 27, 5, 1, 242, 245, 2, 246, 76, 23, + 209, 54, 27, 5, 1, 242, 245, 2, 220, 87, 23, 222, 72, 27, 5, 1, 242, 245, + 2, 246, 76, 23, 222, 72, 27, 6, 1, 242, 245, 2, 220, 86, 27, 6, 1, 242, + 245, 2, 246, 75, 27, 6, 1, 242, 245, 2, 220, 87, 23, 209, 54, 27, 6, 1, + 242, 245, 2, 246, 76, 23, 209, 54, 27, 6, 1, 242, 245, 2, 220, 87, 23, + 222, 72, 27, 6, 1, 242, 245, 2, 246, 76, 23, 222, 72, 27, 5, 1, 242, 202, + 2, 220, 86, 27, 5, 1, 242, 202, 2, 246, 75, 27, 5, 1, 242, 202, 2, 220, + 87, 23, 209, 54, 27, 5, 1, 242, 202, 2, 246, 76, 23, 209, 54, 27, 5, 1, + 242, 202, 2, 220, 87, 23, 222, 72, 27, 5, 1, 242, 202, 2, 246, 76, 23, + 222, 72, 27, 5, 1, 242, 202, 2, 220, 87, 23, 221, 124, 27, 5, 1, 242, + 202, 2, 246, 76, 23, 221, 124, 27, 6, 1, 242, 202, 2, 220, 86, 27, 6, 1, + 242, 202, 2, 246, 75, 27, 6, 1, 242, 202, 2, 220, 87, 23, 209, 54, 27, 6, + 1, 242, 202, 2, 246, 76, 23, 209, 54, 27, 6, 1, 242, 202, 2, 220, 87, 23, + 222, 72, 27, 6, 1, 242, 202, 2, 246, 76, 23, 222, 72, 27, 6, 1, 242, 202, + 2, 220, 87, 23, 221, 124, 27, 6, 1, 242, 202, 2, 246, 76, 23, 221, 124, + 27, 5, 1, 232, 250, 2, 220, 86, 27, 5, 1, 232, 250, 2, 246, 75, 27, 5, 1, + 232, 250, 2, 220, 87, 23, 209, 54, 27, 5, 1, 232, 250, 2, 246, 76, 23, + 209, 54, 27, 5, 1, 232, 250, 2, 220, 87, 23, 222, 72, 27, 5, 1, 232, 250, + 2, 246, 76, 23, 222, 72, 27, 5, 1, 232, 250, 2, 220, 87, 23, 221, 124, + 27, 5, 1, 232, 250, 2, 246, 76, 23, 221, 124, 27, 6, 1, 232, 250, 2, 220, + 86, 27, 6, 1, 232, 250, 2, 246, 75, 27, 6, 1, 232, 250, 2, 220, 87, 23, + 209, 54, 27, 6, 1, 232, 250, 2, 246, 76, 23, 209, 54, 27, 6, 1, 232, 250, + 2, 220, 87, 23, 222, 72, 27, 6, 1, 232, 250, 2, 246, 76, 23, 222, 72, 27, + 6, 1, 232, 250, 2, 220, 87, 23, 221, 124, 27, 6, 1, 232, 250, 2, 246, 76, + 23, 221, 124, 27, 5, 1, 222, 169, 2, 220, 86, 27, 5, 1, 222, 169, 2, 246, + 75, 27, 5, 1, 222, 169, 2, 220, 87, 23, 209, 54, 27, 5, 1, 222, 169, 2, + 246, 76, 23, 209, 54, 27, 5, 1, 222, 169, 2, 220, 87, 23, 222, 72, 27, 5, + 1, 222, 169, 2, 246, 76, 23, 222, 72, 27, 6, 1, 222, 169, 2, 220, 86, 27, + 6, 1, 222, 169, 2, 246, 75, 27, 6, 1, 222, 169, 2, 220, 87, 23, 209, 54, + 27, 6, 1, 222, 169, 2, 246, 76, 23, 209, 54, 27, 6, 1, 222, 169, 2, 220, + 87, 23, 222, 72, 27, 6, 1, 222, 169, 2, 246, 76, 23, 222, 72, 27, 5, 1, + 209, 201, 2, 220, 86, 27, 5, 1, 209, 201, 2, 246, 75, 27, 5, 1, 209, 201, + 2, 220, 87, 23, 209, 54, 27, 5, 1, 209, 201, 2, 246, 76, 23, 209, 54, 27, + 5, 1, 209, 201, 2, 220, 87, 23, 222, 72, 27, 5, 1, 209, 201, 2, 246, 76, + 23, 222, 72, 27, 5, 1, 209, 201, 2, 220, 87, 23, 221, 124, 27, 5, 1, 209, + 201, 2, 246, 76, 23, 221, 124, 27, 6, 1, 209, 201, 2, 246, 75, 27, 6, 1, + 209, 201, 2, 246, 76, 23, 209, 54, 27, 6, 1, 209, 201, 2, 246, 76, 23, + 222, 72, 27, 6, 1, 209, 201, 2, 246, 76, 23, 221, 124, 27, 5, 1, 222, + 171, 2, 220, 86, 27, 5, 1, 222, 171, 2, 246, 75, 27, 5, 1, 222, 171, 2, + 220, 87, 23, 209, 54, 27, 5, 1, 222, 171, 2, 246, 76, 23, 209, 54, 27, 5, + 1, 222, 171, 2, 220, 87, 23, 222, 72, 27, 5, 1, 222, 171, 2, 246, 76, 23, + 222, 72, 27, 5, 1, 222, 171, 2, 220, 87, 23, 221, 124, 27, 5, 1, 222, + 171, 2, 246, 76, 23, 221, 124, 27, 6, 1, 222, 171, 2, 220, 86, 27, 6, 1, + 222, 171, 2, 246, 75, 27, 6, 1, 222, 171, 2, 220, 87, 23, 209, 54, 27, 6, + 1, 222, 171, 2, 246, 76, 23, 209, 54, 27, 6, 1, 222, 171, 2, 220, 87, 23, + 222, 72, 27, 6, 1, 222, 171, 2, 246, 76, 23, 222, 72, 27, 6, 1, 222, 171, + 2, 220, 87, 23, 221, 124, 27, 6, 1, 222, 171, 2, 246, 76, 23, 221, 124, + 27, 5, 1, 252, 145, 2, 209, 54, 27, 5, 1, 252, 145, 2, 222, 72, 27, 5, 1, + 242, 245, 2, 209, 54, 27, 5, 1, 242, 245, 2, 222, 72, 27, 5, 1, 242, 202, + 2, 209, 54, 27, 5, 1, 242, 202, 2, 222, 72, 27, 5, 1, 232, 250, 2, 209, + 54, 27, 5, 1, 232, 250, 2, 222, 72, 27, 5, 1, 222, 169, 2, 209, 54, 27, + 5, 1, 222, 169, 2, 222, 72, 27, 5, 1, 209, 201, 2, 209, 54, 27, 5, 1, + 209, 201, 2, 222, 72, 27, 5, 1, 222, 171, 2, 209, 54, 27, 5, 1, 222, 171, + 2, 222, 72, 27, 5, 1, 252, 145, 2, 220, 87, 23, 205, 221, 27, 5, 1, 252, + 145, 2, 246, 76, 23, 205, 221, 27, 5, 1, 252, 145, 2, 220, 87, 23, 209, + 55, 23, 205, 221, 27, 5, 1, 252, 145, 2, 246, 76, 23, 209, 55, 23, 205, + 221, 27, 5, 1, 252, 145, 2, 220, 87, 23, 222, 73, 23, 205, 221, 27, 5, 1, + 252, 145, 2, 246, 76, 23, 222, 73, 23, 205, 221, 27, 5, 1, 252, 145, 2, + 220, 87, 23, 221, 125, 23, 205, 221, 27, 5, 1, 252, 145, 2, 246, 76, 23, + 221, 125, 23, 205, 221, 27, 6, 1, 252, 145, 2, 220, 87, 23, 220, 100, 27, + 6, 1, 252, 145, 2, 246, 76, 23, 220, 100, 27, 6, 1, 252, 145, 2, 220, 87, + 23, 209, 55, 23, 220, 100, 27, 6, 1, 252, 145, 2, 246, 76, 23, 209, 55, + 23, 220, 100, 27, 6, 1, 252, 145, 2, 220, 87, 23, 222, 73, 23, 220, 100, + 27, 6, 1, 252, 145, 2, 246, 76, 23, 222, 73, 23, 220, 100, 27, 6, 1, 252, + 145, 2, 220, 87, 23, 221, 125, 23, 220, 100, 27, 6, 1, 252, 145, 2, 246, + 76, 23, 221, 125, 23, 220, 100, 27, 5, 1, 242, 202, 2, 220, 87, 23, 205, + 221, 27, 5, 1, 242, 202, 2, 246, 76, 23, 205, 221, 27, 5, 1, 242, 202, 2, + 220, 87, 23, 209, 55, 23, 205, 221, 27, 5, 1, 242, 202, 2, 246, 76, 23, + 209, 55, 23, 205, 221, 27, 5, 1, 242, 202, 2, 220, 87, 23, 222, 73, 23, + 205, 221, 27, 5, 1, 242, 202, 2, 246, 76, 23, 222, 73, 23, 205, 221, 27, + 5, 1, 242, 202, 2, 220, 87, 23, 221, 125, 23, 205, 221, 27, 5, 1, 242, + 202, 2, 246, 76, 23, 221, 125, 23, 205, 221, 27, 6, 1, 242, 202, 2, 220, + 87, 23, 220, 100, 27, 6, 1, 242, 202, 2, 246, 76, 23, 220, 100, 27, 6, 1, + 242, 202, 2, 220, 87, 23, 209, 55, 23, 220, 100, 27, 6, 1, 242, 202, 2, + 246, 76, 23, 209, 55, 23, 220, 100, 27, 6, 1, 242, 202, 2, 220, 87, 23, + 222, 73, 23, 220, 100, 27, 6, 1, 242, 202, 2, 246, 76, 23, 222, 73, 23, + 220, 100, 27, 6, 1, 242, 202, 2, 220, 87, 23, 221, 125, 23, 220, 100, 27, + 6, 1, 242, 202, 2, 246, 76, 23, 221, 125, 23, 220, 100, 27, 5, 1, 222, + 171, 2, 220, 87, 23, 205, 221, 27, 5, 1, 222, 171, 2, 246, 76, 23, 205, + 221, 27, 5, 1, 222, 171, 2, 220, 87, 23, 209, 55, 23, 205, 221, 27, 5, 1, + 222, 171, 2, 246, 76, 23, 209, 55, 23, 205, 221, 27, 5, 1, 222, 171, 2, + 220, 87, 23, 222, 73, 23, 205, 221, 27, 5, 1, 222, 171, 2, 246, 76, 23, + 222, 73, 23, 205, 221, 27, 5, 1, 222, 171, 2, 220, 87, 23, 221, 125, 23, + 205, 221, 27, 5, 1, 222, 171, 2, 246, 76, 23, 221, 125, 23, 205, 221, 27, + 6, 1, 222, 171, 2, 220, 87, 23, 220, 100, 27, 6, 1, 222, 171, 2, 246, 76, + 23, 220, 100, 27, 6, 1, 222, 171, 2, 220, 87, 23, 209, 55, 23, 220, 100, + 27, 6, 1, 222, 171, 2, 246, 76, 23, 209, 55, 23, 220, 100, 27, 6, 1, 222, + 171, 2, 220, 87, 23, 222, 73, 23, 220, 100, 27, 6, 1, 222, 171, 2, 246, + 76, 23, 222, 73, 23, 220, 100, 27, 6, 1, 222, 171, 2, 220, 87, 23, 221, + 125, 23, 220, 100, 27, 6, 1, 222, 171, 2, 246, 76, 23, 221, 125, 23, 220, + 100, 27, 5, 1, 252, 145, 2, 208, 152, 27, 5, 1, 252, 145, 2, 228, 13, 27, + 5, 1, 252, 145, 2, 209, 55, 23, 205, 221, 27, 5, 1, 252, 145, 2, 205, + 221, 27, 5, 1, 252, 145, 2, 222, 73, 23, 205, 221, 27, 5, 1, 252, 145, 2, + 221, 124, 27, 5, 1, 252, 145, 2, 221, 125, 23, 205, 221, 27, 6, 1, 252, + 145, 2, 208, 152, 27, 6, 1, 252, 145, 2, 228, 13, 27, 6, 1, 252, 145, 2, + 209, 54, 27, 6, 1, 252, 145, 2, 222, 72, 27, 6, 1, 252, 145, 2, 220, 100, + 27, 231, 23, 27, 220, 100, 27, 220, 86, 27, 221, 124, 27, 245, 160, 23, + 221, 124, 27, 5, 1, 242, 202, 2, 209, 55, 23, 205, 221, 27, 5, 1, 242, + 202, 2, 205, 221, 27, 5, 1, 242, 202, 2, 222, 73, 23, 205, 221, 27, 5, 1, + 242, 202, 2, 221, 124, 27, 5, 1, 242, 202, 2, 221, 125, 23, 205, 221, 27, + 6, 1, 242, 245, 2, 209, 54, 27, 6, 1, 242, 245, 2, 222, 72, 27, 6, 1, + 242, 202, 2, 209, 54, 27, 6, 1, 242, 202, 2, 222, 72, 27, 6, 1, 242, 202, + 2, 220, 100, 27, 220, 87, 23, 209, 54, 27, 220, 87, 23, 222, 72, 27, 220, + 87, 23, 221, 124, 27, 5, 1, 232, 250, 2, 208, 152, 27, 5, 1, 232, 250, 2, + 228, 13, 27, 5, 1, 232, 250, 2, 245, 160, 23, 209, 54, 27, 5, 1, 232, + 250, 2, 245, 160, 23, 222, 72, 27, 5, 1, 232, 250, 2, 221, 124, 27, 5, 1, + 232, 250, 2, 245, 160, 23, 221, 124, 27, 6, 1, 232, 250, 2, 208, 152, 27, + 6, 1, 232, 250, 2, 228, 13, 27, 6, 1, 232, 250, 2, 209, 54, 27, 6, 1, + 232, 250, 2, 222, 72, 27, 246, 76, 23, 209, 54, 27, 246, 76, 23, 222, 72, + 27, 246, 76, 23, 221, 124, 27, 5, 1, 209, 201, 2, 208, 152, 27, 5, 1, + 209, 201, 2, 228, 13, 27, 5, 1, 209, 201, 2, 245, 160, 23, 209, 54, 27, + 5, 1, 209, 201, 2, 245, 160, 23, 222, 72, 27, 5, 1, 218, 211, 2, 220, 86, + 27, 5, 1, 218, 211, 2, 246, 75, 27, 5, 1, 209, 201, 2, 221, 124, 27, 5, + 1, 209, 201, 2, 245, 160, 23, 221, 124, 27, 6, 1, 209, 201, 2, 208, 152, + 27, 6, 1, 209, 201, 2, 228, 13, 27, 6, 1, 209, 201, 2, 209, 54, 27, 6, 1, + 209, 201, 2, 222, 72, 27, 6, 1, 218, 211, 2, 246, 75, 27, 245, 160, 23, + 209, 54, 27, 245, 160, 23, 222, 72, 27, 209, 54, 27, 5, 1, 222, 171, 2, + 209, 55, 23, 205, 221, 27, 5, 1, 222, 171, 2, 205, 221, 27, 5, 1, 222, + 171, 2, 222, 73, 23, 205, 221, 27, 5, 1, 222, 171, 2, 221, 124, 27, 5, 1, + 222, 171, 2, 221, 125, 23, 205, 221, 27, 6, 1, 222, 169, 2, 209, 54, 27, + 6, 1, 222, 169, 2, 222, 72, 27, 6, 1, 222, 171, 2, 209, 54, 27, 6, 1, + 222, 171, 2, 222, 72, 27, 6, 1, 222, 171, 2, 220, 100, 27, 222, 72, 27, + 246, 75, 243, 42, 219, 211, 243, 51, 219, 211, 243, 42, 214, 153, 243, + 51, 214, 153, 211, 235, 214, 153, 241, 123, 214, 153, 215, 8, 214, 153, + 241, 241, 214, 153, 220, 72, 214, 153, 212, 12, 214, 153, 239, 130, 214, + 153, 205, 86, 207, 15, 214, 153, 205, 86, 207, 15, 224, 59, 205, 86, 207, + 15, 232, 117, 230, 37, 83, 218, 158, 83, 237, 239, 224, 60, 237, 239, + 241, 241, 246, 78, 243, 42, 246, 78, 243, 51, 246, 78, 194, 134, 50, 79, + 229, 205, 50, 114, 229, 205, 47, 215, 41, 219, 180, 83, 48, 215, 41, 219, + 180, 83, 215, 41, 229, 96, 219, 180, 83, 215, 41, 238, 249, 219, 180, 83, + 47, 50, 219, 180, 83, 48, 50, 219, 180, 83, 50, 229, 96, 219, 180, 83, + 50, 238, 249, 219, 180, 83, 246, 128, 50, 246, 128, 249, 85, 211, 48, + 249, 85, 119, 67, 230, 56, 118, 67, 230, 56, 194, 243, 54, 237, 237, 220, + 204, 229, 206, 216, 39, 221, 229, 216, 39, 230, 37, 243, 49, 218, 158, + 243, 49, 220, 184, 245, 103, 241, 134, 230, 37, 222, 79, 218, 158, 222, + 79, 225, 199, 224, 66, 214, 153, 221, 132, 226, 215, 53, 221, 132, 212, + 99, 211, 243, 53, 220, 127, 50, 220, 127, 211, 36, 220, 127, 218, 224, + 220, 127, 218, 224, 50, 220, 127, 218, 224, 211, 36, 220, 127, 248, 199, + 215, 41, 230, 41, 252, 109, 219, 180, 83, 215, 41, 218, 162, 252, 109, + 219, 180, 83, 219, 28, 83, 50, 242, 168, 83, 233, 10, 222, 81, 209, 223, + 157, 211, 203, 248, 200, 233, 27, 220, 204, 251, 207, 237, 240, 249, 85, + 241, 116, 214, 235, 47, 49, 249, 134, 2, 219, 190, 48, 49, 249, 134, 2, + 219, 190, 50, 219, 196, 83, 219, 196, 242, 168, 83, 242, 168, 219, 196, + 83, 211, 159, 3, 242, 203, 218, 224, 221, 12, 53, 60, 92, 249, 85, 60, + 86, 249, 85, 114, 251, 209, 218, 224, 216, 52, 247, 193, 209, 206, 118, + 251, 208, 252, 160, 208, 227, 247, 153, 226, 202, 53, 213, 93, 246, 78, + 233, 2, 209, 223, 241, 173, 220, 72, 83, 129, 67, 220, 71, 219, 207, 220, + 127, 241, 125, 67, 220, 71, 241, 204, 67, 220, 71, 118, 67, 220, 71, 241, + 125, 67, 83, 244, 21, 247, 59, 211, 47, 79, 241, 125, 245, 21, 227, 109, + 11, 214, 153, 206, 232, 232, 117, 241, 80, 252, 48, 233, 0, 211, 175, + 233, 0, 216, 39, 233, 0, 220, 218, 230, 37, 232, 226, 218, 158, 232, 226, + 241, 215, 213, 211, 232, 226, 220, 184, 245, 103, 232, 226, 233, 39, 213, + 41, 213, 110, 253, 11, 213, 41, 213, 110, 233, 39, 8, 241, 136, 215, 232, + 253, 11, 8, 241, 136, 215, 232, 225, 193, 18, 215, 233, 224, 62, 18, 215, + 233, 213, 139, 205, 85, 213, 139, 7, 5, 1, 74, 213, 139, 139, 213, 139, + 168, 213, 139, 184, 213, 139, 195, 213, 139, 193, 213, 139, 200, 213, + 139, 101, 53, 213, 139, 226, 201, 213, 139, 242, 242, 53, 213, 139, 47, + 221, 216, 213, 139, 48, 221, 216, 213, 139, 7, 5, 1, 226, 33, 213, 183, + 205, 85, 213, 183, 102, 213, 183, 105, 213, 183, 142, 213, 183, 139, 213, + 183, 168, 213, 183, 184, 213, 183, 195, 213, 183, 193, 213, 183, 200, + 213, 183, 101, 53, 213, 183, 226, 201, 213, 183, 242, 242, 53, 213, 183, + 47, 221, 216, 213, 183, 48, 221, 216, 7, 213, 183, 5, 1, 62, 7, 213, 183, + 5, 1, 75, 7, 213, 183, 5, 1, 76, 7, 213, 183, 5, 1, 206, 195, 7, 213, + 183, 5, 1, 217, 100, 7, 213, 183, 5, 1, 239, 155, 7, 213, 183, 5, 1, 232, + 76, 7, 213, 183, 5, 1, 149, 7, 213, 183, 5, 1, 229, 28, 7, 213, 183, 5, + 1, 226, 33, 7, 213, 183, 5, 1, 222, 67, 7, 213, 183, 5, 1, 182, 7, 213, + 183, 5, 1, 213, 10, 242, 183, 53, 247, 163, 53, 247, 45, 53, 241, 106, + 241, 110, 53, 229, 188, 53, 226, 216, 53, 225, 216, 53, 221, 109, 53, + 218, 27, 53, 206, 240, 53, 186, 215, 200, 53, 245, 30, 53, 242, 184, 53, + 231, 104, 53, 210, 163, 53, 244, 4, 53, 240, 146, 221, 143, 53, 221, 106, + 53, 239, 208, 53, 251, 174, 53, 238, 48, 53, 248, 143, 53, 229, 179, 211, + 88, 53, 214, 134, 53, 212, 96, 53, 233, 52, 218, 27, 53, 210, 146, 229, + 188, 53, 224, 49, 141, 53, 227, 219, 53, 218, 47, 53, 36, 47, 239, 90, + 52, 36, 48, 239, 90, 52, 36, 152, 79, 229, 206, 222, 82, 36, 215, 144, + 79, 229, 206, 222, 82, 36, 252, 87, 51, 52, 36, 247, 194, 51, 52, 36, 47, + 51, 52, 36, 48, 51, 52, 36, 218, 149, 222, 82, 36, 247, 194, 218, 149, + 222, 82, 36, 252, 87, 218, 149, 222, 82, 36, 129, 177, 52, 36, 241, 125, + 177, 52, 36, 243, 37, 247, 233, 36, 243, 37, 214, 107, 36, 243, 37, 245, + 156, 36, 243, 37, 247, 234, 250, 171, 36, 47, 48, 51, 52, 36, 243, 37, + 217, 93, 36, 243, 37, 231, 170, 36, 243, 37, 209, 198, 220, 201, 211, 51, + 36, 218, 225, 214, 181, 222, 82, 36, 50, 79, 213, 225, 222, 82, 36, 252, + 97, 93, 36, 211, 36, 209, 225, 36, 207, 17, 249, 116, 52, 36, 92, 51, + 222, 82, 36, 152, 50, 214, 181, 222, 82, 36, 86, 239, 90, 2, 138, 244, 6, + 36, 92, 239, 90, 2, 138, 244, 6, 36, 47, 51, 55, 36, 48, 51, 55, 36, 251, + 210, 52, 253, 17, 222, 203, 253, 1, 211, 130, 212, 42, 213, 192, 159, 6, + 249, 34, 245, 245, 248, 134, 248, 129, 229, 206, 93, 248, 201, 222, 203, + 248, 249, 209, 233, 242, 185, 247, 124, 217, 90, 245, 245, 242, 56, 121, + 5, 241, 55, 121, 6, 239, 155, 249, 200, 6, 239, 155, 159, 6, 239, 155, + 220, 235, 247, 124, 220, 235, 247, 125, 131, 118, 221, 53, 121, 6, 74, + 249, 200, 6, 74, 121, 6, 149, 121, 5, 149, 230, 159, 63, 250, 129, 93, + 159, 6, 226, 33, 223, 175, 53, 214, 165, 219, 40, 247, 93, 121, 6, 222, + 67, 159, 6, 222, 67, 159, 6, 220, 27, 121, 6, 137, 249, 200, 6, 137, 159, + 6, 137, 220, 133, 212, 185, 218, 237, 216, 33, 83, 212, 108, 53, 211, 79, + 141, 53, 209, 23, 159, 6, 205, 159, 222, 96, 53, 222, 193, 53, 233, 2, + 222, 193, 53, 249, 200, 6, 205, 159, 201, 27, 5, 1, 232, 249, 231, 211, + 53, 252, 106, 53, 121, 6, 251, 150, 249, 200, 6, 249, 34, 242, 207, 93, + 121, 5, 75, 121, 6, 75, 121, 6, 242, 139, 201, 6, 242, 139, 121, 6, 229, + 28, 121, 5, 76, 126, 93, 250, 11, 93, 240, 48, 93, 246, 112, 93, 233, 43, + 214, 163, 218, 97, 6, 220, 27, 242, 59, 53, 159, 5, 221, 53, 159, 5, 240, + 215, 159, 6, 240, 215, 159, 6, 221, 53, 159, 226, 32, 213, 157, 201, 38, + 6, 241, 55, 201, 38, 6, 149, 218, 224, 38, 6, 149, 201, 38, 6, 206, 123, + 159, 35, 6, 246, 240, 159, 35, 5, 246, 240, 159, 35, 5, 75, 159, 35, 5, + 74, 159, 35, 5, 232, 203, 220, 103, 229, 205, 201, 252, 125, 221, 132, + 53, 252, 183, 201, 5, 242, 139, 16, 33, 217, 160, 214, 163, 207, 146, + 241, 116, 119, 216, 19, 207, 146, 241, 116, 119, 224, 189, 207, 146, 241, + 116, 119, 212, 91, 207, 146, 241, 116, 119, 212, 10, 207, 146, 241, 116, + 118, 212, 7, 207, 146, 241, 116, 119, 241, 246, 207, 146, 241, 116, 118, + 241, 245, 207, 146, 241, 116, 129, 241, 245, 207, 146, 241, 116, 241, + 125, 241, 245, 207, 146, 241, 116, 119, 215, 0, 207, 146, 241, 116, 241, + 204, 214, 254, 207, 146, 241, 116, 119, 243, 83, 207, 146, 241, 116, 129, + 243, 81, 207, 146, 241, 116, 241, 204, 243, 81, 207, 146, 241, 116, 216, + 23, 243, 81, 241, 116, 223, 176, 102, 218, 109, 223, 177, 102, 218, 109, + 223, 177, 105, 218, 109, 223, 177, 142, 218, 109, 223, 177, 139, 218, + 109, 223, 177, 168, 218, 109, 223, 177, 184, 218, 109, 223, 177, 195, + 218, 109, 223, 177, 193, 218, 109, 223, 177, 200, 218, 109, 223, 177, + 212, 98, 218, 109, 223, 177, 243, 58, 218, 109, 223, 177, 210, 126, 218, + 109, 223, 177, 241, 243, 218, 109, 223, 177, 119, 238, 29, 218, 109, 223, + 177, 241, 204, 238, 29, 218, 109, 223, 177, 119, 211, 242, 5, 218, 109, + 223, 177, 102, 5, 218, 109, 223, 177, 105, 5, 218, 109, 223, 177, 142, 5, + 218, 109, 223, 177, 139, 5, 218, 109, 223, 177, 168, 5, 218, 109, 223, + 177, 184, 5, 218, 109, 223, 177, 195, 5, 218, 109, 223, 177, 193, 5, 218, + 109, 223, 177, 200, 5, 218, 109, 223, 177, 212, 98, 5, 218, 109, 223, + 177, 243, 58, 5, 218, 109, 223, 177, 210, 126, 5, 218, 109, 223, 177, + 241, 243, 5, 218, 109, 223, 177, 119, 238, 29, 5, 218, 109, 223, 177, + 241, 204, 238, 29, 5, 218, 109, 223, 177, 119, 211, 242, 218, 109, 223, + 177, 119, 211, 243, 249, 35, 246, 240, 218, 109, 223, 177, 241, 204, 211, + 242, 218, 109, 223, 177, 212, 99, 211, 242, 218, 109, 223, 177, 218, 224, + 119, 238, 29, 7, 5, 1, 218, 224, 249, 34, 218, 109, 223, 177, 215, 10, + 230, 79, 17, 218, 109, 223, 177, 241, 244, 243, 123, 17, 218, 109, 223, + 177, 241, 244, 211, 242, 218, 109, 223, 177, 119, 238, 30, 211, 242, 207, + 146, 241, 116, 205, 86, 212, 7, 92, 45, 167, 45, 86, 45, 173, 45, 47, 48, + 45, 120, 130, 45, 143, 207, 36, 45, 143, 243, 117, 45, 188, 243, 117, 45, + 188, 207, 36, 45, 92, 51, 2, 91, 86, 51, 2, 91, 92, 207, 65, 45, 86, 207, + 65, 45, 92, 118, 239, 67, 45, 167, 118, 239, 67, 45, 86, 118, 239, 67, + 45, 173, 118, 239, 67, 45, 92, 51, 2, 212, 191, 86, 51, 2, 212, 191, 92, + 51, 241, 98, 134, 167, 51, 241, 98, 134, 86, 51, 241, 98, 134, 173, 51, + 241, 98, 134, 120, 130, 51, 2, 250, 116, 92, 51, 2, 109, 86, 51, 2, 109, + 92, 51, 2, 229, 111, 86, 51, 2, 229, 111, 47, 48, 207, 65, 45, 47, 48, + 51, 2, 91, 173, 205, 31, 45, 167, 51, 2, 211, 167, 230, 36, 167, 51, 2, + 211, 167, 218, 156, 173, 51, 2, 211, 167, 230, 36, 173, 51, 2, 211, 167, + 218, 156, 86, 51, 2, 247, 92, 244, 6, 173, 51, 2, 247, 92, 230, 36, 252, + 87, 211, 102, 216, 55, 45, 247, 194, 211, 102, 216, 55, 45, 143, 207, 36, + 51, 211, 130, 152, 134, 92, 51, 211, 130, 250, 129, 131, 86, 51, 211, + 130, 134, 252, 87, 222, 142, 247, 234, 45, 247, 194, 222, 142, 247, 234, + 45, 92, 239, 90, 2, 138, 209, 196, 92, 239, 90, 2, 138, 244, 6, 167, 239, + 90, 2, 138, 218, 156, 167, 239, 90, 2, 138, 230, 36, 86, 239, 90, 2, 138, + 209, 196, 86, 239, 90, 2, 138, 244, 6, 173, 239, 90, 2, 138, 218, 156, + 173, 239, 90, 2, 138, 230, 36, 86, 51, 131, 92, 45, 167, 51, 92, 73, 173, + 45, 92, 51, 131, 86, 45, 92, 222, 30, 251, 241, 167, 222, 30, 251, 241, + 86, 222, 30, 251, 241, 173, 222, 30, 251, 241, 92, 239, 90, 131, 86, 239, + 89, 86, 239, 90, 131, 92, 239, 89, 92, 50, 51, 2, 91, 47, 48, 50, 51, 2, + 91, 86, 50, 51, 2, 91, 92, 50, 45, 167, 50, 45, 86, 50, 45, 173, 50, 45, + 47, 48, 50, 45, 120, 130, 50, 45, 143, 207, 36, 50, 45, 143, 243, 117, + 50, 45, 188, 243, 117, 50, 45, 188, 207, 36, 50, 45, 92, 211, 36, 45, 86, + 211, 36, 45, 92, 214, 103, 45, 86, 214, 103, 45, 167, 51, 2, 50, 91, 173, + 51, 2, 50, 91, 92, 246, 77, 45, 167, 246, 77, 45, 86, 246, 77, 45, 173, + 246, 77, 45, 92, 51, 211, 130, 134, 86, 51, 211, 130, 134, 92, 59, 45, + 167, 59, 45, 86, 59, 45, 173, 59, 45, 167, 59, 51, 241, 98, 134, 167, 59, + 51, 222, 166, 221, 167, 167, 59, 51, 222, 166, 221, 168, 2, 194, 134, + 167, 59, 51, 222, 166, 221, 168, 2, 79, 134, 167, 59, 50, 45, 167, 59, + 50, 51, 222, 166, 221, 167, 86, 59, 51, 241, 98, 207, 86, 143, 207, 36, + 51, 211, 130, 247, 91, 188, 243, 117, 51, 211, 130, 247, 91, 120, 130, + 59, 45, 48, 51, 2, 5, 247, 233, 173, 51, 92, 73, 167, 45, 129, 86, 251, + 241, 92, 51, 2, 79, 91, 86, 51, 2, 79, 91, 47, 48, 51, 2, 79, 91, 92, 51, + 2, 50, 79, 91, 86, 51, 2, 50, 79, 91, 47, 48, 51, 2, 50, 79, 91, 92, 222, + 140, 45, 86, 222, 140, 45, 47, 48, 222, 140, 45, 33, 252, 156, 247, 150, + 221, 209, 245, 140, 212, 32, 242, 164, 212, 32, 245, 42, 224, 43, 242, + 165, 243, 43, 216, 28, 233, 57, 225, 227, 243, 61, 222, 203, 224, 43, + 252, 123, 243, 61, 222, 203, 5, 243, 61, 222, 203, 247, 118, 251, 232, + 227, 87, 245, 42, 224, 43, 247, 120, 251, 232, 227, 87, 5, 247, 118, 251, + 232, 227, 87, 243, 34, 73, 220, 105, 226, 32, 220, 115, 226, 32, 247, 96, + 226, 32, 213, 157, 226, 202, 53, 226, 200, 53, 67, 220, 218, 245, 75, + 214, 235, 216, 29, 226, 201, 251, 210, 222, 132, 218, 149, 222, 132, 249, + 86, 222, 132, 49, 218, 103, 247, 36, 218, 103, 241, 118, 218, 103, 220, + 101, 124, 233, 45, 48, 252, 108, 252, 108, 227, 116, 252, 108, 214, 133, + 252, 108, 245, 77, 245, 42, 224, 43, 245, 81, 221, 222, 124, 224, 43, + 221, 222, 124, 229, 134, 252, 117, 229, 134, 222, 122, 233, 7, 209, 218, + 233, 21, 50, 233, 21, 211, 36, 233, 21, 247, 113, 233, 21, 213, 129, 233, + 21, 208, 163, 233, 21, 247, 194, 233, 21, 247, 194, 247, 113, 233, 21, + 252, 87, 247, 113, 233, 21, 212, 31, 250, 52, 219, 61, 220, 102, 67, 226, + 201, 242, 170, 240, 152, 220, 102, 238, 135, 211, 181, 222, 132, 218, + 224, 211, 180, 233, 2, 230, 65, 182, 215, 43, 207, 64, 206, 221, 220, + 115, 224, 43, 211, 180, 226, 202, 211, 180, 251, 203, 146, 124, 224, 43, + 251, 203, 146, 124, 252, 44, 146, 124, 252, 44, 249, 57, 224, 43, 253, + 10, 146, 124, 225, 103, 252, 44, 224, 51, 253, 10, 146, 124, 252, 149, + 146, 124, 224, 43, 252, 149, 146, 124, 252, 149, 146, 222, 123, 146, 124, + 211, 36, 211, 180, 252, 157, 146, 124, 242, 237, 124, 240, 151, 242, 237, + 124, 245, 141, 250, 5, 252, 46, 212, 42, 229, 213, 240, 151, 146, 124, + 252, 44, 146, 211, 130, 222, 123, 212, 42, 233, 84, 222, 203, 233, 84, + 73, 222, 123, 252, 44, 146, 124, 247, 163, 242, 241, 242, 242, 247, 162, + 218, 149, 233, 69, 146, 124, 218, 149, 146, 124, 247, 85, 124, 242, 206, + 242, 240, 124, 214, 27, 242, 241, 245, 228, 146, 124, 146, 211, 130, 249, + 46, 245, 246, 227, 116, 249, 45, 219, 194, 146, 124, 224, 43, 146, 124, + 237, 173, 124, 224, 43, 237, 173, 124, 213, 231, 242, 237, 124, 230, 10, + 222, 123, 146, 124, 239, 230, 222, 123, 146, 124, 230, 10, 131, 146, 124, + 239, 230, 131, 146, 124, 230, 10, 249, 57, 224, 43, 146, 124, 239, 230, + 249, 57, 224, 43, 146, 124, 226, 108, 230, 9, 226, 108, 239, 229, 250, 5, + 224, 43, 242, 237, 124, 224, 43, 230, 9, 224, 43, 239, 229, 225, 103, + 230, 10, 224, 51, 146, 124, 225, 103, 239, 230, 224, 51, 146, 124, 230, + 10, 222, 123, 242, 237, 124, 239, 230, 222, 123, 242, 237, 124, 225, 103, + 230, 10, 224, 51, 242, 237, 124, 225, 103, 239, 230, 224, 51, 242, 237, + 124, 230, 10, 222, 123, 239, 229, 239, 230, 222, 123, 230, 9, 225, 103, + 230, 10, 224, 51, 239, 229, 225, 103, 239, 230, 224, 51, 230, 9, 220, + 139, 213, 173, 220, 140, 222, 123, 146, 124, 213, 174, 222, 123, 146, + 124, 220, 140, 222, 123, 242, 237, 124, 213, 174, 222, 123, 242, 237, + 124, 245, 42, 224, 43, 220, 142, 245, 42, 224, 43, 213, 175, 213, 182, + 222, 203, 213, 138, 222, 203, 224, 43, 32, 213, 182, 222, 203, 224, 43, + 32, 213, 138, 222, 203, 213, 182, 73, 222, 123, 146, 124, 213, 138, 73, + 222, 123, 146, 124, 225, 103, 32, 213, 182, 73, 224, 51, 146, 124, 225, + 103, 32, 213, 138, 73, 224, 51, 146, 124, 213, 182, 73, 2, 224, 43, 146, + 124, 213, 138, 73, 2, 224, 43, 146, 124, 226, 91, 226, 92, 226, 93, 226, + 92, 209, 218, 49, 233, 84, 222, 203, 49, 222, 114, 222, 203, 49, 233, 84, + 73, 222, 123, 146, 124, 49, 222, 114, 73, 222, 123, 146, 124, 49, 248, + 213, 49, 247, 29, 39, 220, 218, 39, 226, 201, 39, 211, 175, 39, 245, 75, + 214, 235, 39, 67, 222, 132, 39, 218, 149, 222, 132, 39, 251, 210, 222, + 132, 39, 242, 241, 39, 246, 78, 98, 220, 218, 98, 226, 201, 98, 211, 175, + 98, 67, 222, 132, 48, 212, 201, 47, 212, 201, 130, 212, 201, 120, 212, + 201, 251, 213, 226, 176, 211, 16, 241, 141, 211, 36, 79, 250, 129, 48, + 210, 143, 50, 79, 250, 129, 50, 48, 210, 143, 245, 42, 224, 43, 220, 96, + 224, 43, 211, 16, 245, 42, 224, 43, 241, 142, 225, 105, 50, 79, 250, 129, + 50, 48, 210, 143, 220, 140, 209, 227, 219, 11, 213, 174, 209, 227, 219, + 11, 224, 48, 213, 195, 222, 203, 247, 118, 251, 232, 224, 48, 213, 194, + 224, 48, 213, 195, 73, 222, 123, 146, 124, 247, 118, 251, 232, 224, 48, + 213, 195, 222, 123, 146, 124, 222, 114, 222, 203, 233, 84, 222, 203, 226, + 97, 239, 32, 247, 129, 227, 168, 233, 18, 206, 155, 225, 207, 224, 50, + 48, 252, 109, 2, 252, 21, 48, 211, 51, 226, 32, 229, 134, 252, 117, 226, + 32, 229, 134, 222, 122, 226, 32, 233, 7, 226, 32, 209, 218, 245, 157, + 222, 132, 67, 222, 132, 214, 27, 222, 132, 245, 75, 211, 175, 249, 141, + 47, 224, 48, 242, 58, 216, 51, 220, 115, 48, 224, 48, 242, 58, 216, 51, + 220, 115, 47, 216, 51, 220, 115, 48, 216, 51, 220, 115, 218, 224, 211, + 181, 242, 241, 247, 26, 229, 134, 222, 122, 247, 26, 229, 134, 252, 117, + 50, 213, 181, 50, 213, 137, 50, 233, 7, 50, 209, 218, 220, 245, 146, 23, + 221, 222, 124, 230, 10, 2, 245, 23, 239, 230, 2, 245, 23, 208, 226, 226, + 108, 230, 9, 208, 226, 226, 108, 239, 229, 230, 10, 146, 211, 130, 222, + 123, 239, 229, 239, 230, 146, 211, 130, 222, 123, 230, 9, 146, 211, 130, + 222, 123, 230, 9, 146, 211, 130, 222, 123, 239, 229, 146, 211, 130, 222, + 123, 220, 139, 146, 211, 130, 222, 123, 213, 173, 245, 42, 224, 43, 220, + 143, 222, 123, 242, 243, 245, 42, 224, 43, 213, 176, 222, 123, 242, 243, + 224, 43, 49, 233, 84, 73, 222, 123, 146, 124, 224, 43, 49, 222, 114, 73, + 222, 123, 146, 124, 49, 233, 84, 73, 222, 123, 224, 43, 146, 124, 49, + 222, 114, 73, 222, 123, 224, 43, 146, 124, 230, 10, 249, 57, 224, 43, + 242, 237, 124, 239, 230, 249, 57, 224, 43, 242, 237, 124, 220, 140, 249, + 57, 224, 43, 242, 237, 124, 213, 174, 249, 57, 224, 43, 242, 237, 124, + 224, 43, 224, 48, 213, 195, 222, 203, 245, 42, 224, 43, 247, 120, 251, + 232, 224, 48, 213, 194, 224, 43, 224, 48, 213, 195, 73, 222, 123, 146, + 124, 245, 42, 224, 43, 247, 120, 251, 232, 224, 48, 213, 195, 222, 123, + 242, 243, 79, 243, 54, 226, 245, 194, 243, 54, 120, 48, 245, 163, 243, + 54, 130, 48, 245, 163, 243, 54, 243, 61, 73, 2, 152, 194, 91, 243, 61, + 73, 2, 79, 250, 129, 251, 200, 243, 34, 73, 194, 91, 5, 243, 61, 73, 2, + 79, 250, 129, 251, 200, 243, 34, 73, 194, 91, 243, 61, 73, 2, 67, 52, + 243, 61, 73, 2, 222, 86, 5, 243, 61, 73, 2, 222, 86, 243, 61, 73, 2, 209, + 226, 243, 61, 73, 2, 118, 194, 213, 212, 247, 118, 2, 152, 194, 91, 247, + 118, 2, 79, 250, 129, 251, 200, 243, 34, 73, 194, 91, 5, 247, 118, 2, 79, + 250, 129, 251, 200, 243, 34, 73, 194, 91, 247, 118, 2, 222, 86, 5, 247, + 118, 2, 222, 86, 205, 160, 224, 41, 250, 164, 227, 86, 245, 158, 53, 243, + 63, 45, 238, 54, 120, 251, 243, 130, 251, 243, 220, 109, 221, 112, 207, + 61, 229, 205, 47, 248, 137, 48, 248, 137, 47, 241, 178, 48, 241, 178, + 249, 154, 48, 247, 61, 249, 154, 47, 247, 61, 211, 102, 48, 247, 61, 211, + 102, 47, 247, 61, 218, 224, 224, 43, 53, 49, 229, 88, 252, 21, 217, 67, + 217, 75, 212, 108, 219, 41, 220, 178, 233, 49, 208, 202, 214, 107, 220, + 239, 73, 233, 17, 53, 201, 224, 43, 53, 207, 71, 238, 56, 211, 102, 47, + 247, 91, 211, 102, 48, 247, 91, 249, 154, 47, 247, 91, 249, 154, 48, 247, + 91, 211, 102, 160, 233, 21, 249, 154, 160, 233, 21, 241, 95, 214, 211, + 120, 251, 244, 250, 6, 118, 194, 250, 118, 222, 125, 231, 174, 242, 233, + 211, 130, 212, 42, 218, 167, 206, 196, 233, 69, 32, 219, 38, 249, 140, + 231, 172, 230, 41, 252, 109, 145, 218, 162, 252, 109, 145, 242, 233, 211, + 130, 212, 42, 230, 46, 250, 17, 218, 148, 246, 250, 252, 157, 251, 252, + 213, 40, 211, 90, 218, 32, 245, 122, 222, 115, 247, 131, 212, 164, 214, + 222, 247, 81, 247, 80, 252, 62, 241, 78, 16, 237, 222, 252, 62, 241, 78, + 16, 214, 101, 219, 211, 252, 62, 241, 78, 16, 219, 212, 242, 243, 252, + 62, 241, 78, 16, 219, 212, 245, 81, 252, 62, 241, 78, 16, 219, 212, 245, + 156, 252, 62, 241, 78, 16, 219, 212, 232, 110, 252, 62, 241, 78, 16, 219, + 212, 247, 233, 252, 62, 241, 78, 16, 247, 234, 214, 3, 252, 62, 241, 78, + 16, 247, 234, 232, 110, 252, 62, 241, 78, 16, 214, 236, 134, 252, 62, + 241, 78, 16, 250, 172, 134, 252, 62, 241, 78, 16, 219, 212, 214, 235, + 252, 62, 241, 78, 16, 219, 212, 250, 171, 252, 62, 241, 78, 16, 219, 212, + 230, 9, 252, 62, 241, 78, 16, 219, 212, 239, 229, 252, 62, 241, 78, 16, + 92, 209, 60, 252, 62, 241, 78, 16, 86, 209, 60, 252, 62, 241, 78, 16, + 219, 212, 92, 45, 252, 62, 241, 78, 16, 219, 212, 86, 45, 252, 62, 241, + 78, 16, 247, 234, 250, 171, 252, 62, 241, 78, 16, 130, 212, 202, 209, + 226, 252, 62, 241, 78, 16, 245, 228, 214, 3, 252, 62, 241, 78, 16, 219, + 212, 130, 248, 199, 252, 62, 241, 78, 16, 219, 212, 245, 227, 252, 62, + 241, 78, 16, 130, 212, 202, 232, 110, 252, 62, 241, 78, 16, 167, 209, 60, + 252, 62, 241, 78, 16, 219, 212, 167, 45, 252, 62, 241, 78, 16, 120, 212, + 202, 222, 86, 252, 62, 241, 78, 16, 245, 239, 214, 3, 252, 62, 241, 78, + 16, 219, 212, 120, 248, 199, 252, 62, 241, 78, 16, 219, 212, 245, 238, + 252, 62, 241, 78, 16, 120, 212, 202, 232, 110, 252, 62, 241, 78, 16, 173, + 209, 60, 252, 62, 241, 78, 16, 219, 212, 173, 45, 252, 62, 241, 78, 16, + 219, 179, 209, 226, 252, 62, 241, 78, 16, 245, 228, 209, 226, 252, 62, + 241, 78, 16, 245, 157, 209, 226, 252, 62, 241, 78, 16, 232, 111, 209, + 226, 252, 62, 241, 78, 16, 247, 234, 209, 226, 252, 62, 241, 78, 16, 120, + 215, 156, 232, 110, 252, 62, 241, 78, 16, 219, 179, 219, 211, 252, 62, + 241, 78, 16, 247, 234, 214, 26, 252, 62, 241, 78, 16, 219, 212, 247, 162, + 252, 62, 241, 78, 16, 120, 212, 202, 245, 166, 252, 62, 241, 78, 16, 245, + 239, 245, 166, 252, 62, 241, 78, 16, 214, 27, 245, 166, 252, 62, 241, 78, + 16, 232, 111, 245, 166, 252, 62, 241, 78, 16, 247, 234, 245, 166, 252, + 62, 241, 78, 16, 130, 215, 156, 214, 3, 252, 62, 241, 78, 16, 47, 215, + 156, 214, 3, 252, 62, 241, 78, 16, 211, 181, 245, 166, 252, 62, 241, 78, + 16, 239, 230, 245, 166, 252, 62, 241, 78, 16, 247, 156, 134, 252, 62, + 241, 78, 16, 245, 239, 211, 180, 252, 62, 241, 78, 16, 205, 30, 252, 62, + 241, 78, 16, 214, 4, 211, 180, 252, 62, 241, 78, 16, 216, 53, 209, 226, + 252, 62, 241, 78, 16, 219, 212, 224, 43, 242, 243, 252, 62, 241, 78, 16, + 219, 212, 219, 195, 252, 62, 241, 78, 16, 130, 248, 200, 211, 180, 252, + 62, 241, 78, 16, 120, 248, 200, 211, 180, 252, 62, 241, 78, 16, 232, 249, + 252, 62, 241, 78, 16, 218, 210, 252, 62, 241, 78, 16, 222, 170, 252, 62, + 241, 78, 16, 252, 145, 209, 226, 252, 62, 241, 78, 16, 242, 245, 209, + 226, 252, 62, 241, 78, 16, 232, 250, 209, 226, 252, 62, 241, 78, 16, 222, + 171, 209, 226, 252, 62, 241, 78, 16, 252, 144, 224, 43, 248, 81, 83, 48, + 252, 109, 2, 173, 205, 31, 45, 215, 127, 222, 142, 249, 140, 250, 29, 93, + 79, 229, 206, 2, 226, 247, 245, 23, 233, 27, 93, 247, 114, 209, 224, 93, + 245, 96, 209, 224, 93, 243, 45, 93, 247, 146, 93, 59, 49, 2, 248, 129, + 79, 229, 205, 243, 19, 93, 252, 139, 231, 175, 93, 239, 45, 93, 39, 194, + 250, 129, 2, 224, 40, 39, 211, 52, 244, 8, 249, 111, 247, 234, 2, 224, + 45, 45, 209, 222, 93, 226, 155, 93, 237, 235, 93, 222, 141, 239, 154, 93, + 222, 141, 230, 157, 93, 221, 199, 93, 221, 198, 93, 245, 104, 247, 24, + 16, 241, 136, 105, 214, 185, 93, 252, 62, 241, 78, 16, 219, 211, 246, 2, + 216, 40, 231, 175, 93, 220, 129, 222, 37, 225, 82, 222, 37, 220, 125, + 217, 94, 93, 247, 209, 217, 94, 93, 47, 221, 217, 209, 203, 109, 47, 221, + 217, 242, 157, 47, 221, 217, 229, 92, 109, 48, 221, 217, 209, 203, 109, + 48, 221, 217, 242, 157, 48, 221, 217, 229, 92, 109, 47, 49, 249, 134, + 209, 203, 247, 91, 47, 49, 249, 134, 242, 157, 47, 49, 249, 134, 229, 92, + 247, 91, 48, 49, 249, 134, 209, 203, 247, 91, 48, 49, 249, 134, 242, 157, + 48, 49, 249, 134, 229, 92, 247, 91, 47, 247, 26, 249, 134, 209, 203, 109, + 47, 247, 26, 249, 134, 226, 247, 221, 45, 47, 247, 26, 249, 134, 229, 92, + 109, 247, 26, 249, 134, 242, 157, 48, 247, 26, 249, 134, 209, 203, 109, + 48, 247, 26, 249, 134, 226, 247, 221, 45, 48, 247, 26, 249, 134, 229, 92, + 109, 233, 22, 242, 157, 194, 229, 206, 242, 157, 209, 203, 47, 222, 123, + 229, 92, 48, 247, 26, 249, 134, 217, 76, 209, 203, 48, 222, 123, 229, 92, + 47, 247, 26, 249, 134, 217, 76, 213, 158, 211, 101, 213, 158, 249, 153, + 211, 102, 49, 145, 249, 154, 49, 145, 249, 154, 49, 249, 134, 131, 211, + 102, 49, 145, 37, 16, 249, 153, 47, 79, 96, 229, 205, 48, 79, 96, 229, + 205, 194, 217, 110, 229, 204, 194, 217, 110, 229, 203, 194, 217, 110, + 229, 202, 194, 217, 110, 229, 201, 245, 219, 16, 147, 79, 23, 211, 102, + 218, 167, 245, 219, 16, 147, 79, 23, 249, 154, 218, 167, 245, 219, 16, + 147, 79, 2, 247, 233, 245, 219, 16, 147, 130, 23, 194, 2, 247, 233, 245, + 219, 16, 147, 120, 23, 194, 2, 247, 233, 245, 219, 16, 147, 79, 2, 211, + 51, 245, 219, 16, 147, 130, 23, 194, 2, 211, 51, 245, 219, 16, 147, 120, + 23, 194, 2, 211, 51, 245, 219, 16, 147, 79, 23, 207, 64, 245, 219, 16, + 147, 130, 23, 194, 2, 207, 64, 245, 219, 16, 147, 120, 23, 194, 2, 207, + 64, 245, 219, 16, 147, 130, 23, 238, 121, 245, 219, 16, 147, 120, 23, + 238, 121, 245, 219, 16, 147, 79, 23, 211, 102, 230, 46, 245, 219, 16, + 147, 79, 23, 249, 154, 230, 46, 49, 241, 148, 218, 229, 93, 243, 77, 93, + 79, 229, 206, 242, 157, 227, 57, 249, 122, 227, 57, 152, 131, 215, 143, + 227, 57, 215, 144, 131, 229, 125, 227, 57, 152, 131, 118, 215, 129, 227, + 57, 118, 215, 130, 131, 229, 125, 227, 57, 118, 215, 130, 232, 118, 227, + 57, 211, 33, 227, 57, 212, 72, 227, 57, 221, 138, 243, 121, 239, 222, + 241, 72, 211, 102, 221, 216, 249, 154, 221, 216, 211, 102, 247, 26, 145, + 249, 154, 247, 26, 145, 211, 102, 211, 93, 215, 204, 145, 249, 154, 211, + 93, 215, 204, 145, 59, 211, 65, 250, 17, 218, 149, 2, 247, 233, 213, 242, + 241, 186, 253, 25, 247, 23, 243, 62, 233, 7, 246, 2, 242, 161, 93, 60, + 218, 162, 50, 211, 51, 60, 230, 41, 50, 211, 51, 60, 209, 205, 50, 211, + 51, 60, 244, 7, 50, 211, 51, 60, 218, 162, 50, 211, 52, 2, 79, 134, 60, + 230, 41, 50, 211, 52, 2, 79, 134, 60, 218, 162, 211, 52, 2, 50, 79, 134, + 252, 176, 247, 195, 213, 248, 211, 176, 247, 195, 238, 57, 2, 241, 170, + 217, 149, 60, 227, 109, 230, 41, 211, 51, 60, 227, 109, 218, 162, 211, + 51, 60, 227, 109, 209, 205, 211, 51, 60, 227, 109, 244, 7, 211, 51, 50, + 79, 134, 60, 49, 33, 213, 251, 60, 247, 234, 33, 219, 42, 16, 33, 223, + 181, 16, 33, 214, 22, 73, 239, 66, 16, 33, 214, 22, 73, 212, 60, 16, 33, + 243, 34, 73, 212, 60, 16, 33, 243, 34, 73, 211, 69, 16, 33, 243, 21, 16, + 33, 253, 13, 16, 33, 250, 28, 16, 33, 250, 170, 16, 33, 194, 212, 203, + 16, 33, 229, 206, 242, 19, 16, 33, 79, 212, 203, 16, 33, 241, 136, 242, + 19, 16, 33, 248, 191, 218, 228, 16, 33, 215, 179, 222, 93, 16, 33, 215, + 179, 233, 68, 16, 33, 246, 73, 229, 196, 242, 217, 16, 33, 245, 199, 247, + 109, 102, 16, 33, 245, 199, 247, 109, 105, 16, 33, 245, 199, 247, 109, + 142, 16, 33, 245, 199, 247, 109, 139, 16, 33, 170, 253, 13, 16, 33, 213, + 36, 233, 131, 16, 33, 243, 34, 73, 211, 70, 249, 193, 16, 33, 248, 224, + 16, 33, 243, 34, 73, 227, 108, 16, 33, 213, 179, 16, 33, 242, 217, 16, + 33, 241, 236, 216, 39, 16, 33, 239, 221, 216, 39, 16, 33, 219, 43, 216, + 39, 16, 33, 209, 217, 216, 39, 16, 33, 214, 153, 16, 33, 245, 236, 249, + 196, 93, 222, 142, 249, 140, 16, 33, 225, 85, 16, 33, 245, 237, 241, 136, + 105, 16, 33, 213, 180, 241, 136, 105, 222, 215, 109, 222, 215, 248, 105, + 222, 215, 241, 139, 222, 215, 233, 2, 241, 139, 222, 215, 250, 25, 249, + 98, 222, 215, 249, 147, 211, 203, 222, 215, 249, 131, 250, 134, 237, 172, + 222, 215, 252, 127, 73, 248, 80, 222, 215, 246, 78, 222, 215, 247, 13, + 253, 17, 223, 179, 222, 215, 50, 250, 171, 39, 18, 102, 39, 18, 105, 39, + 18, 142, 39, 18, 139, 39, 18, 168, 39, 18, 184, 39, 18, 195, 39, 18, 193, + 39, 18, 200, 39, 43, 212, 98, 39, 43, 243, 58, 39, 43, 210, 126, 39, 43, + 212, 5, 39, 43, 241, 119, 39, 43, 241, 247, 39, 43, 215, 4, 39, 43, 216, + 20, 39, 43, 243, 85, 39, 43, 224, 192, 39, 43, 210, 123, 97, 18, 102, 97, + 18, 105, 97, 18, 142, 97, 18, 139, 97, 18, 168, 97, 18, 184, 97, 18, 195, + 97, 18, 193, 97, 18, 200, 97, 43, 212, 98, 97, 43, 243, 58, 97, 43, 210, + 126, 97, 43, 212, 5, 97, 43, 241, 119, 97, 43, 241, 247, 97, 43, 215, 4, + 97, 43, 216, 20, 97, 43, 243, 85, 97, 43, 224, 192, 97, 43, 210, 123, 18, + 119, 241, 82, 213, 251, 18, 118, 241, 82, 213, 251, 18, 129, 241, 82, + 213, 251, 18, 241, 125, 241, 82, 213, 251, 18, 241, 204, 241, 82, 213, + 251, 18, 215, 10, 241, 82, 213, 251, 18, 216, 23, 241, 82, 213, 251, 18, + 243, 88, 241, 82, 213, 251, 18, 224, 195, 241, 82, 213, 251, 43, 212, 99, + 241, 82, 213, 251, 43, 243, 59, 241, 82, 213, 251, 43, 210, 127, 241, 82, + 213, 251, 43, 212, 6, 241, 82, 213, 251, 43, 241, 120, 241, 82, 213, 251, + 43, 241, 248, 241, 82, 213, 251, 43, 215, 5, 241, 82, 213, 251, 43, 216, + 21, 241, 82, 213, 251, 43, 243, 86, 241, 82, 213, 251, 43, 224, 193, 241, + 82, 213, 251, 43, 210, 124, 241, 82, 213, 251, 97, 7, 5, 1, 62, 97, 7, 5, + 1, 251, 150, 97, 7, 5, 1, 249, 34, 97, 7, 5, 1, 246, 240, 97, 7, 5, 1, + 75, 97, 7, 5, 1, 242, 139, 97, 7, 5, 1, 241, 55, 97, 7, 5, 1, 239, 155, + 97, 7, 5, 1, 74, 97, 7, 5, 1, 232, 203, 97, 7, 5, 1, 232, 76, 97, 7, 5, + 1, 149, 97, 7, 5, 1, 229, 28, 97, 7, 5, 1, 226, 33, 97, 7, 5, 1, 76, 97, + 7, 5, 1, 222, 67, 97, 7, 5, 1, 220, 27, 97, 7, 5, 1, 137, 97, 7, 5, 1, + 182, 97, 7, 5, 1, 213, 10, 97, 7, 5, 1, 71, 97, 7, 5, 1, 209, 148, 97, 7, + 5, 1, 207, 129, 97, 7, 5, 1, 206, 195, 97, 7, 5, 1, 206, 123, 97, 7, 5, + 1, 205, 159, 39, 7, 6, 1, 62, 39, 7, 6, 1, 251, 150, 39, 7, 6, 1, 249, + 34, 39, 7, 6, 1, 246, 240, 39, 7, 6, 1, 75, 39, 7, 6, 1, 242, 139, 39, 7, + 6, 1, 241, 55, 39, 7, 6, 1, 239, 155, 39, 7, 6, 1, 74, 39, 7, 6, 1, 232, + 203, 39, 7, 6, 1, 232, 76, 39, 7, 6, 1, 149, 39, 7, 6, 1, 229, 28, 39, 7, + 6, 1, 226, 33, 39, 7, 6, 1, 76, 39, 7, 6, 1, 222, 67, 39, 7, 6, 1, 220, + 27, 39, 7, 6, 1, 137, 39, 7, 6, 1, 182, 39, 7, 6, 1, 213, 10, 39, 7, 6, + 1, 71, 39, 7, 6, 1, 209, 148, 39, 7, 6, 1, 207, 129, 39, 7, 6, 1, 206, + 195, 39, 7, 6, 1, 206, 123, 39, 7, 6, 1, 205, 159, 39, 7, 5, 1, 62, 39, + 7, 5, 1, 251, 150, 39, 7, 5, 1, 249, 34, 39, 7, 5, 1, 246, 240, 39, 7, 5, + 1, 75, 39, 7, 5, 1, 242, 139, 39, 7, 5, 1, 241, 55, 39, 7, 5, 1, 239, + 155, 39, 7, 5, 1, 74, 39, 7, 5, 1, 232, 203, 39, 7, 5, 1, 232, 76, 39, 7, + 5, 1, 149, 39, 7, 5, 1, 229, 28, 39, 7, 5, 1, 226, 33, 39, 7, 5, 1, 76, + 39, 7, 5, 1, 222, 67, 39, 7, 5, 1, 220, 27, 39, 7, 5, 1, 137, 39, 7, 5, + 1, 182, 39, 7, 5, 1, 213, 10, 39, 7, 5, 1, 71, 39, 7, 5, 1, 209, 148, 39, + 7, 5, 1, 207, 129, 39, 7, 5, 1, 206, 195, 39, 7, 5, 1, 206, 123, 39, 7, + 5, 1, 205, 159, 39, 18, 205, 85, 170, 39, 43, 243, 58, 170, 39, 43, 210, + 126, 170, 39, 43, 212, 5, 170, 39, 43, 241, 119, 170, 39, 43, 241, 247, + 170, 39, 43, 215, 4, 170, 39, 43, 216, 20, 170, 39, 43, 243, 85, 170, 39, + 43, 224, 192, 170, 39, 43, 210, 123, 50, 39, 18, 102, 50, 39, 18, 105, + 50, 39, 18, 142, 50, 39, 18, 139, 50, 39, 18, 168, 50, 39, 18, 184, 50, + 39, 18, 195, 50, 39, 18, 193, 50, 39, 18, 200, 50, 39, 43, 212, 98, 170, + 39, 18, 205, 85, 96, 110, 147, 238, 121, 96, 110, 77, 238, 121, 96, 110, + 147, 209, 22, 96, 110, 77, 209, 22, 96, 110, 147, 211, 36, 246, 79, 238, + 121, 96, 110, 77, 211, 36, 246, 79, 238, 121, 96, 110, 147, 211, 36, 246, + 79, 209, 22, 96, 110, 77, 211, 36, 246, 79, 209, 22, 96, 110, 147, 219, + 207, 246, 79, 238, 121, 96, 110, 77, 219, 207, 246, 79, 238, 121, 96, + 110, 147, 219, 207, 246, 79, 209, 22, 96, 110, 77, 219, 207, 246, 79, + 209, 22, 96, 110, 147, 130, 23, 218, 167, 96, 110, 130, 147, 23, 48, 239, + 54, 96, 110, 130, 77, 23, 48, 229, 223, 96, 110, 77, 130, 23, 218, 167, + 96, 110, 147, 130, 23, 230, 46, 96, 110, 130, 147, 23, 47, 239, 54, 96, + 110, 130, 77, 23, 47, 229, 223, 96, 110, 77, 130, 23, 230, 46, 96, 110, + 147, 120, 23, 218, 167, 96, 110, 120, 147, 23, 48, 239, 54, 96, 110, 120, + 77, 23, 48, 229, 223, 96, 110, 77, 120, 23, 218, 167, 96, 110, 147, 120, + 23, 230, 46, 96, 110, 120, 147, 23, 47, 239, 54, 96, 110, 120, 77, 23, + 47, 229, 223, 96, 110, 77, 120, 23, 230, 46, 96, 110, 147, 79, 23, 218, + 167, 96, 110, 79, 147, 23, 48, 239, 54, 96, 110, 120, 77, 23, 48, 130, + 229, 223, 96, 110, 130, 77, 23, 48, 120, 229, 223, 96, 110, 79, 77, 23, + 48, 229, 223, 96, 110, 130, 147, 23, 48, 120, 239, 54, 96, 110, 120, 147, + 23, 48, 130, 239, 54, 96, 110, 77, 79, 23, 218, 167, 96, 110, 147, 79, + 23, 230, 46, 96, 110, 79, 147, 23, 47, 239, 54, 96, 110, 120, 77, 23, 47, + 130, 229, 223, 96, 110, 130, 77, 23, 47, 120, 229, 223, 96, 110, 79, 77, + 23, 47, 229, 223, 96, 110, 130, 147, 23, 47, 120, 239, 54, 96, 110, 120, + 147, 23, 47, 130, 239, 54, 96, 110, 77, 79, 23, 230, 46, 96, 110, 147, + 130, 23, 238, 121, 96, 110, 47, 77, 23, 48, 130, 229, 223, 96, 110, 48, + 77, 23, 47, 130, 229, 223, 96, 110, 130, 147, 23, 194, 239, 54, 96, 110, + 130, 77, 23, 194, 229, 223, 96, 110, 48, 147, 23, 47, 130, 239, 54, 96, + 110, 47, 147, 23, 48, 130, 239, 54, 96, 110, 77, 130, 23, 238, 121, 96, + 110, 147, 120, 23, 238, 121, 96, 110, 47, 77, 23, 48, 120, 229, 223, 96, + 110, 48, 77, 23, 47, 120, 229, 223, 96, 110, 120, 147, 23, 194, 239, 54, + 96, 110, 120, 77, 23, 194, 229, 223, 96, 110, 48, 147, 23, 47, 120, 239, + 54, 96, 110, 47, 147, 23, 48, 120, 239, 54, 96, 110, 77, 120, 23, 238, + 121, 96, 110, 147, 79, 23, 238, 121, 96, 110, 47, 77, 23, 48, 79, 229, + 223, 96, 110, 48, 77, 23, 47, 79, 229, 223, 96, 110, 79, 147, 23, 194, + 239, 54, 96, 110, 120, 77, 23, 130, 194, 229, 223, 96, 110, 130, 77, 23, + 120, 194, 229, 223, 96, 110, 79, 77, 23, 194, 229, 223, 96, 110, 47, 120, + 77, 23, 48, 130, 229, 223, 96, 110, 48, 120, 77, 23, 47, 130, 229, 223, + 96, 110, 47, 130, 77, 23, 48, 120, 229, 223, 96, 110, 48, 130, 77, 23, + 47, 120, 229, 223, 96, 110, 130, 147, 23, 120, 194, 239, 54, 96, 110, + 120, 147, 23, 130, 194, 239, 54, 96, 110, 48, 147, 23, 47, 79, 239, 54, + 96, 110, 47, 147, 23, 48, 79, 239, 54, 96, 110, 77, 79, 23, 238, 121, 96, + 110, 147, 50, 246, 79, 238, 121, 96, 110, 77, 50, 246, 79, 238, 121, 96, + 110, 147, 50, 246, 79, 209, 22, 96, 110, 77, 50, 246, 79, 209, 22, 96, + 110, 50, 238, 121, 96, 110, 50, 209, 22, 96, 110, 130, 215, 41, 23, 48, + 244, 16, 96, 110, 130, 50, 23, 48, 215, 40, 96, 110, 50, 130, 23, 218, + 167, 96, 110, 130, 215, 41, 23, 47, 244, 16, 96, 110, 130, 50, 23, 47, + 215, 40, 96, 110, 50, 130, 23, 230, 46, 96, 110, 120, 215, 41, 23, 48, + 244, 16, 96, 110, 120, 50, 23, 48, 215, 40, 96, 110, 50, 120, 23, 218, + 167, 96, 110, 120, 215, 41, 23, 47, 244, 16, 96, 110, 120, 50, 23, 47, + 215, 40, 96, 110, 50, 120, 23, 230, 46, 96, 110, 79, 215, 41, 23, 48, + 244, 16, 96, 110, 79, 50, 23, 48, 215, 40, 96, 110, 50, 79, 23, 218, 167, + 96, 110, 79, 215, 41, 23, 47, 244, 16, 96, 110, 79, 50, 23, 47, 215, 40, + 96, 110, 50, 79, 23, 230, 46, 96, 110, 130, 215, 41, 23, 194, 244, 16, + 96, 110, 130, 50, 23, 194, 215, 40, 96, 110, 50, 130, 23, 238, 121, 96, + 110, 120, 215, 41, 23, 194, 244, 16, 96, 110, 120, 50, 23, 194, 215, 40, + 96, 110, 50, 120, 23, 238, 121, 96, 110, 79, 215, 41, 23, 194, 244, 16, + 96, 110, 79, 50, 23, 194, 215, 40, 96, 110, 50, 79, 23, 238, 121, 96, + 110, 147, 252, 22, 130, 23, 218, 167, 96, 110, 147, 252, 22, 130, 23, + 230, 46, 96, 110, 147, 252, 22, 120, 23, 230, 46, 96, 110, 147, 252, 22, + 120, 23, 218, 167, 96, 110, 147, 245, 163, 209, 203, 48, 211, 130, 229, + 92, 230, 46, 96, 110, 147, 245, 163, 209, 203, 47, 211, 130, 229, 92, + 218, 167, 96, 110, 147, 245, 163, 247, 59, 96, 110, 147, 230, 46, 96, + 110, 147, 209, 206, 96, 110, 147, 218, 167, 96, 110, 147, 244, 8, 96, + 110, 77, 230, 46, 96, 110, 77, 209, 206, 96, 110, 77, 218, 167, 96, 110, + 77, 244, 8, 96, 110, 147, 47, 23, 77, 218, 167, 96, 110, 147, 120, 23, + 77, 244, 8, 96, 110, 77, 47, 23, 147, 218, 167, 96, 110, 77, 120, 23, + 147, 244, 8, 209, 203, 160, 249, 193, 229, 92, 119, 243, 84, 249, 193, + 229, 92, 119, 219, 205, 249, 193, 229, 92, 129, 243, 82, 249, 193, 229, + 92, 160, 249, 193, 229, 92, 241, 204, 243, 82, 249, 193, 229, 92, 129, + 219, 203, 249, 193, 229, 92, 216, 23, 243, 82, 249, 193, 241, 82, 249, + 193, 47, 216, 23, 243, 82, 249, 193, 47, 129, 219, 203, 249, 193, 47, + 241, 204, 243, 82, 249, 193, 47, 160, 249, 193, 47, 129, 243, 82, 249, + 193, 47, 119, 219, 205, 249, 193, 47, 119, 243, 84, 249, 193, 48, 160, + 249, 193, 147, 215, 248, 227, 109, 215, 248, 246, 84, 215, 248, 209, 203, + 119, 243, 84, 249, 193, 48, 119, 243, 84, 249, 193, 219, 209, 229, 92, + 230, 46, 219, 209, 229, 92, 218, 167, 219, 209, 209, 203, 230, 46, 219, + 209, 209, 203, 47, 23, 229, 92, 47, 23, 229, 92, 218, 167, 219, 209, 209, + 203, 47, 23, 229, 92, 218, 167, 219, 209, 209, 203, 47, 23, 209, 203, 48, + 23, 229, 92, 230, 46, 219, 209, 209, 203, 47, 23, 209, 203, 48, 23, 229, + 92, 218, 167, 219, 209, 209, 203, 218, 167, 219, 209, 209, 203, 48, 23, + 229, 92, 230, 46, 219, 209, 209, 203, 48, 23, 229, 92, 47, 23, 229, 92, + 218, 167, 60, 214, 107, 59, 214, 107, 59, 49, 2, 218, 93, 247, 90, 59, + 49, 247, 119, 60, 5, 214, 107, 49, 2, 194, 241, 234, 49, 2, 79, 241, 234, + 49, 2, 222, 108, 247, 55, 241, 234, 49, 2, 209, 203, 47, 211, 130, 229, + 92, 48, 241, 234, 49, 2, 209, 203, 48, 211, 130, 229, 92, 47, 241, 234, + 49, 2, 245, 163, 247, 55, 241, 234, 60, 5, 214, 107, 59, 5, 214, 107, 60, + 219, 37, 59, 219, 37, 60, 79, 219, 37, 59, 79, 219, 37, 60, 221, 220, 59, + 221, 220, 60, 209, 205, 211, 51, 59, 209, 205, 211, 51, 60, 209, 205, 5, + 211, 51, 59, 209, 205, 5, 211, 51, 60, 218, 162, 211, 51, 59, 218, 162, + 211, 51, 60, 218, 162, 5, 211, 51, 59, 218, 162, 5, 211, 51, 60, 218, + 162, 220, 202, 59, 218, 162, 220, 202, 60, 244, 7, 211, 51, 59, 244, 7, + 211, 51, 60, 244, 7, 5, 211, 51, 59, 244, 7, 5, 211, 51, 60, 230, 41, + 211, 51, 59, 230, 41, 211, 51, 60, 230, 41, 5, 211, 51, 59, 230, 41, 5, + 211, 51, 60, 230, 41, 220, 202, 59, 230, 41, 220, 202, 60, 245, 156, 59, + 245, 156, 59, 245, 157, 247, 119, 60, 5, 245, 156, 241, 212, 229, 88, 59, + 247, 233, 244, 21, 247, 233, 247, 234, 2, 79, 241, 234, 249, 81, 60, 247, + 233, 247, 234, 2, 47, 160, 249, 202, 247, 234, 2, 48, 160, 249, 202, 247, + 234, 2, 229, 92, 160, 249, 202, 247, 234, 2, 209, 203, 160, 249, 202, + 247, 234, 2, 209, 203, 48, 219, 209, 249, 202, 247, 234, 2, 252, 157, + 249, 57, 209, 203, 47, 219, 209, 249, 202, 47, 160, 60, 247, 233, 48, + 160, 60, 247, 233, 233, 3, 249, 85, 233, 3, 59, 247, 233, 209, 203, 160, + 233, 3, 59, 247, 233, 229, 92, 160, 233, 3, 59, 247, 233, 209, 203, 47, + 219, 209, 247, 230, 252, 21, 209, 203, 48, 219, 209, 247, 230, 252, 21, + 229, 92, 48, 219, 209, 247, 230, 252, 21, 229, 92, 47, 219, 209, 247, + 230, 252, 21, 209, 203, 160, 247, 233, 229, 92, 160, 247, 233, 60, 229, + 92, 48, 211, 51, 60, 229, 92, 47, 211, 51, 60, 209, 203, 47, 211, 51, 60, + 209, 203, 48, 211, 51, 59, 249, 85, 49, 2, 47, 160, 249, 202, 49, 2, 48, + 160, 249, 202, 49, 2, 209, 203, 47, 245, 163, 160, 249, 202, 49, 2, 229, + 92, 48, 245, 163, 160, 249, 202, 59, 49, 2, 79, 249, 213, 229, 205, 59, + 209, 205, 211, 52, 2, 245, 23, 209, 205, 211, 52, 2, 47, 160, 249, 202, + 209, 205, 211, 52, 2, 48, 160, 249, 202, 230, 86, 247, 233, 59, 49, 2, + 209, 203, 47, 219, 208, 59, 49, 2, 229, 92, 47, 219, 208, 59, 49, 2, 229, + 92, 48, 219, 208, 59, 49, 2, 209, 203, 48, 219, 208, 59, 247, 234, 2, + 209, 203, 47, 219, 208, 59, 247, 234, 2, 229, 92, 47, 219, 208, 59, 247, + 234, 2, 229, 92, 48, 219, 208, 59, 247, 234, 2, 209, 203, 48, 219, 208, + 209, 203, 47, 211, 51, 209, 203, 48, 211, 51, 229, 92, 47, 211, 51, 59, + 227, 109, 214, 107, 60, 227, 109, 214, 107, 59, 227, 109, 5, 214, 107, + 60, 227, 109, 5, 214, 107, 229, 92, 48, 211, 51, 60, 213, 155, 2, 219, + 55, 247, 183, 209, 238, 214, 195, 247, 158, 60, 214, 26, 59, 214, 26, + 229, 220, 211, 226, 213, 154, 251, 228, 224, 64, 245, 210, 224, 64, 247, + 128, 222, 128, 60, 212, 107, 59, 212, 107, 250, 146, 249, 140, 250, 146, + 96, 2, 248, 80, 250, 146, 96, 2, 206, 195, 217, 162, 209, 239, 2, 219, + 84, 243, 243, 238, 63, 250, 4, 59, 215, 153, 221, 45, 60, 215, 153, 221, + 45, 215, 239, 218, 224, 218, 97, 241, 176, 239, 61, 249, 85, 60, 47, 220, + 201, 233, 53, 60, 48, 220, 201, 233, 53, 59, 47, 220, 201, 233, 53, 59, + 120, 220, 201, 233, 53, 59, 48, 220, 201, 233, 53, 59, 130, 220, 201, + 233, 53, 214, 241, 23, 247, 58, 248, 177, 53, 219, 96, 53, 249, 220, 53, + 248, 248, 252, 101, 222, 109, 247, 59, 248, 59, 218, 210, 247, 60, 73, + 229, 106, 247, 60, 73, 232, 172, 214, 27, 23, 247, 65, 242, 42, 93, 252, + 254, 215, 241, 239, 115, 23, 215, 77, 221, 173, 93, 206, 1, 206, 75, 211, + 41, 33, 239, 56, 211, 41, 33, 230, 111, 211, 41, 33, 241, 219, 211, 41, + 33, 211, 227, 211, 41, 33, 207, 9, 211, 41, 33, 207, 69, 211, 41, 33, + 226, 128, 211, 41, 33, 243, 120, 207, 27, 73, 245, 184, 59, 241, 94, 242, + 67, 59, 214, 210, 242, 67, 60, 214, 210, 242, 67, 59, 213, 155, 2, 219, + 55, 241, 215, 219, 205, 226, 144, 230, 81, 219, 205, 226, 144, 227, 78, + 242, 11, 53, 243, 120, 227, 226, 53, 232, 91, 217, 126, 209, 189, 225, + 95, 220, 215, 252, 7, 212, 149, 240, 158, 248, 222, 230, 15, 208, 186, + 229, 232, 217, 96, 217, 183, 248, 208, 252, 38, 220, 250, 59, 248, 65, + 231, 106, 59, 248, 65, 219, 197, 59, 248, 65, 218, 105, 59, 248, 65, 249, + 212, 59, 248, 65, 231, 56, 59, 248, 65, 221, 185, 60, 248, 65, 231, 106, + 60, 248, 65, 219, 197, 60, 248, 65, 218, 105, 60, 248, 65, 249, 212, 60, + 248, 65, 231, 56, 60, 248, 65, 221, 185, 60, 214, 151, 213, 167, 59, 239, + 61, 213, 167, 59, 245, 157, 213, 167, 60, 247, 181, 213, 167, 59, 214, + 151, 213, 167, 60, 239, 61, 213, 167, 60, 245, 157, 213, 167, 59, 247, + 181, 213, 167, 238, 63, 214, 112, 219, 205, 224, 37, 243, 84, 224, 37, + 250, 58, 243, 84, 224, 32, 250, 58, 215, 3, 224, 32, 226, 65, 241, 188, + 53, 226, 65, 225, 192, 53, 226, 65, 215, 228, 53, 207, 36, 213, 30, 247, + 59, 243, 117, 213, 30, 247, 59, 209, 214, 219, 33, 93, 219, 33, 16, 33, + 210, 94, 220, 232, 219, 33, 16, 33, 210, 93, 220, 232, 219, 33, 16, 33, + 210, 92, 220, 232, 219, 33, 16, 33, 210, 91, 220, 232, 219, 33, 16, 33, + 210, 90, 220, 232, 219, 33, 16, 33, 210, 89, 220, 232, 219, 33, 16, 33, + 210, 88, 220, 232, 219, 33, 16, 33, 240, 156, 227, 169, 60, 209, 214, + 219, 33, 93, 219, 34, 221, 235, 93, 221, 208, 221, 235, 93, 221, 123, + 221, 235, 53, 207, 25, 93, 245, 149, 242, 66, 245, 149, 242, 65, 245, + 149, 242, 64, 245, 149, 242, 63, 245, 149, 242, 62, 245, 149, 242, 61, + 59, 247, 234, 2, 67, 218, 167, 59, 247, 234, 2, 118, 245, 21, 60, 247, + 234, 2, 59, 67, 218, 167, 60, 247, 234, 2, 118, 59, 245, 21, 226, 160, + 33, 206, 75, 226, 160, 33, 206, 0, 245, 131, 33, 239, 231, 206, 75, 245, + 131, 33, 230, 8, 206, 0, 245, 131, 33, 230, 8, 206, 75, 245, 131, 33, + 239, 231, 206, 0, 59, 241, 196, 60, 241, 196, 239, 115, 23, 221, 49, 252, + 119, 247, 57, 213, 94, 214, 35, 73, 252, 231, 217, 111, 252, 171, 241, + 172, 240, 167, 214, 35, 73, 239, 34, 251, 192, 93, 241, 184, 222, 89, 59, + 214, 26, 129, 229, 200, 247, 106, 218, 167, 129, 229, 200, 247, 106, 230, + 46, 207, 80, 53, 127, 208, 164, 53, 244, 13, 242, 11, 53, 244, 13, 227, + 226, 53, 233, 13, 242, 11, 23, 227, 226, 53, 227, 226, 23, 242, 11, 53, + 227, 226, 2, 213, 225, 53, 227, 226, 2, 213, 225, 23, 227, 226, 23, 242, + 11, 53, 79, 227, 226, 2, 213, 225, 53, 194, 227, 226, 2, 213, 225, 53, + 227, 109, 59, 247, 233, 227, 109, 60, 247, 233, 227, 109, 5, 59, 247, + 233, 227, 185, 93, 245, 73, 93, 209, 212, 221, 207, 93, 247, 167, 241, + 77, 209, 185, 225, 89, 248, 114, 222, 21, 232, 97, 208, 224, 248, 39, 60, + 226, 145, 229, 217, 216, 13, 216, 49, 219, 187, 216, 31, 214, 190, 250, + 149, 250, 115, 98, 231, 174, 59, 243, 252, 227, 221, 59, 243, 252, 231, + 106, 60, 243, 252, 227, 221, 60, 243, 252, 231, 106, 214, 196, 206, 253, + 214, 199, 213, 155, 250, 35, 247, 183, 219, 83, 60, 214, 195, 211, 228, + 247, 184, 23, 219, 83, 201, 59, 215, 153, 221, 45, 201, 60, 215, 153, + 221, 45, 59, 245, 157, 233, 69, 214, 107, 247, 54, 230, 93, 245, 100, + 248, 204, 222, 131, 221, 49, 248, 205, 214, 226, 239, 44, 2, 59, 247, 59, + 39, 247, 54, 230, 93, 248, 106, 224, 68, 243, 13, 252, 141, 222, 160, 47, + 207, 55, 211, 77, 60, 210, 105, 47, 207, 55, 211, 77, 59, 210, 105, 47, + 207, 55, 211, 77, 60, 47, 230, 94, 227, 77, 59, 47, 230, 94, 227, 77, + 243, 248, 214, 218, 53, 77, 59, 244, 7, 211, 51, 47, 247, 192, 243, 13, + 98, 217, 162, 242, 50, 245, 163, 233, 69, 59, 247, 234, 233, 69, 60, 214, + 107, 60, 211, 17, 218, 235, 47, 243, 12, 218, 235, 47, 243, 11, 251, 204, + 16, 33, 209, 189, 77, 247, 234, 2, 213, 225, 23, 118, 177, 52, 221, 139, + 218, 164, 233, 15, 221, 139, 230, 43, 233, 15, 221, 139, 233, 2, 221, + 139, 60, 247, 60, 222, 166, 215, 180, 215, 168, 215, 120, 248, 6, 248, + 185, 238, 243, 215, 11, 240, 168, 206, 253, 238, 39, 240, 168, 2, 239, + 104, 227, 206, 16, 33, 229, 222, 226, 128, 209, 239, 222, 166, 239, 222, + 241, 126, 241, 197, 233, 69, 238, 140, 242, 2, 217, 178, 49, 241, 125, + 247, 90, 214, 244, 237, 182, 214, 247, 221, 115, 2, 250, 149, 212, 92, + 232, 189, 250, 134, 93, 239, 64, 239, 233, 93, 241, 85, 220, 73, 247, 30, + 222, 166, 60, 214, 107, 59, 241, 197, 2, 194, 226, 247, 60, 213, 226, 60, + 217, 188, 217, 98, 209, 203, 249, 197, 217, 98, 60, 217, 98, 229, 92, + 249, 197, 217, 98, 59, 217, 98, 59, 77, 248, 81, 83, 212, 108, 229, 142, + 53, 212, 165, 243, 247, 252, 194, 243, 8, 219, 81, 241, 208, 219, 81, + 239, 107, 208, 212, 239, 107, 206, 219, 239, 107, 229, 92, 48, 221, 149, + 221, 149, 209, 203, 48, 221, 149, 59, 224, 227, 60, 224, 227, 248, 81, + 83, 77, 248, 81, 83, 226, 94, 206, 195, 77, 226, 94, 206, 195, 250, 146, + 206, 195, 77, 250, 146, 206, 195, 222, 89, 27, 247, 59, 77, 27, 247, 59, + 222, 142, 248, 129, 247, 59, 77, 222, 142, 248, 129, 247, 59, 7, 247, 59, + 215, 246, 59, 7, 247, 59, 222, 89, 7, 247, 59, 227, 223, 247, 59, 214, + 27, 73, 246, 71, 241, 125, 212, 124, 251, 209, 241, 125, 250, 147, 251, + 209, 77, 241, 125, 250, 147, 251, 209, 241, 125, 247, 179, 251, 209, 60, + 241, 125, 220, 203, 214, 26, 59, 241, 125, 220, 203, 214, 26, 214, 146, + 213, 233, 222, 89, 59, 214, 26, 39, 59, 214, 26, 222, 142, 248, 129, 60, + 214, 26, 60, 248, 129, 59, 214, 26, 222, 89, 60, 214, 26, 77, 222, 89, + 60, 214, 26, 221, 4, 214, 26, 215, 246, 59, 214, 26, 77, 251, 209, 222, + 142, 248, 129, 251, 209, 243, 88, 214, 119, 251, 209, 243, 88, 220, 203, + 60, 214, 26, 243, 88, 220, 203, 221, 4, 214, 26, 215, 10, 220, 203, 60, + 214, 26, 243, 88, 220, 203, 219, 35, 60, 214, 26, 77, 243, 88, 220, 203, + 219, 35, 60, 214, 26, 210, 127, 220, 203, 60, 214, 26, 215, 5, 220, 203, + 251, 209, 212, 124, 251, 209, 222, 142, 248, 129, 212, 124, 251, 209, 77, + 212, 124, 251, 209, 215, 10, 221, 103, 60, 23, 59, 241, 175, 60, 241, + 175, 59, 241, 175, 243, 88, 221, 103, 222, 89, 60, 241, 175, 39, 222, + 142, 248, 129, 243, 88, 220, 203, 214, 26, 77, 212, 124, 221, 4, 251, + 209, 214, 197, 211, 197, 211, 44, 214, 197, 77, 248, 62, 214, 197, 214, + 148, 77, 214, 148, 250, 147, 251, 209, 243, 88, 212, 124, 220, 104, 251, + 209, 77, 243, 88, 212, 124, 220, 104, 251, 209, 247, 60, 83, 215, 246, + 59, 247, 233, 170, 98, 247, 60, 83, 229, 92, 48, 243, 245, 59, 214, 107, + 209, 203, 48, 243, 245, 59, 214, 107, 229, 92, 48, 215, 246, 59, 214, + 107, 209, 203, 48, 215, 246, 59, 214, 107, 60, 219, 196, 141, 222, 111, + 59, 219, 196, 141, 222, 111, 59, 242, 168, 141, 222, 111, 60, 245, 157, + 226, 202, 59, 206, 195, 77, 242, 168, 141, 93, 147, 79, 134, 227, 109, + 79, 134, 77, 79, 134, 77, 215, 41, 201, 247, 156, 219, 180, 141, 222, + 111, 77, 215, 41, 247, 156, 219, 180, 141, 222, 111, 77, 50, 201, 247, + 156, 219, 180, 141, 222, 111, 77, 50, 247, 156, 219, 180, 141, 222, 111, + 77, 114, 215, 41, 247, 156, 219, 180, 141, 222, 111, 77, 114, 50, 247, + 156, 219, 180, 141, 222, 111, 247, 18, 214, 10, 221, 229, 3, 222, 111, + 77, 242, 168, 141, 222, 111, 77, 239, 61, 242, 168, 141, 222, 111, 77, + 60, 239, 60, 218, 97, 77, 60, 239, 61, 249, 85, 241, 176, 239, 60, 218, + 97, 241, 176, 239, 61, 249, 85, 227, 109, 47, 221, 217, 222, 111, 227, + 109, 48, 221, 217, 222, 111, 227, 109, 241, 185, 47, 221, 217, 222, 111, + 227, 109, 241, 185, 48, 221, 217, 222, 111, 227, 109, 230, 41, 252, 109, + 249, 134, 222, 111, 227, 109, 218, 162, 252, 109, 249, 134, 222, 111, 77, + 230, 41, 252, 109, 219, 180, 141, 222, 111, 77, 218, 162, 252, 109, 219, + 180, 141, 222, 111, 77, 230, 41, 252, 109, 249, 134, 222, 111, 77, 218, + 162, 252, 109, 249, 134, 222, 111, 147, 47, 211, 93, 215, 204, 249, 134, + 222, 111, 147, 48, 211, 93, 215, 204, 249, 134, 222, 111, 227, 109, 47, + 247, 26, 249, 134, 222, 111, 227, 109, 48, 247, 26, 249, 134, 222, 111, + 245, 111, 170, 39, 18, 102, 245, 111, 170, 39, 18, 105, 245, 111, 170, + 39, 18, 142, 245, 111, 170, 39, 18, 139, 245, 111, 170, 39, 18, 168, 245, + 111, 170, 39, 18, 184, 245, 111, 170, 39, 18, 195, 245, 111, 170, 39, 18, + 193, 245, 111, 170, 39, 18, 200, 245, 111, 170, 39, 43, 212, 98, 245, + 111, 39, 38, 18, 102, 245, 111, 39, 38, 18, 105, 245, 111, 39, 38, 18, + 142, 245, 111, 39, 38, 18, 139, 245, 111, 39, 38, 18, 168, 245, 111, 39, + 38, 18, 184, 245, 111, 39, 38, 18, 195, 245, 111, 39, 38, 18, 193, 245, + 111, 39, 38, 18, 200, 245, 111, 39, 38, 43, 212, 98, 245, 111, 170, 39, + 38, 18, 102, 245, 111, 170, 39, 38, 18, 105, 245, 111, 170, 39, 38, 18, + 142, 245, 111, 170, 39, 38, 18, 139, 245, 111, 170, 39, 38, 18, 168, 245, + 111, 170, 39, 38, 18, 184, 245, 111, 170, 39, 38, 18, 195, 245, 111, 170, + 39, 38, 18, 193, 245, 111, 170, 39, 38, 18, 200, 245, 111, 170, 39, 38, + 43, 212, 98, 77, 207, 16, 86, 45, 77, 101, 53, 77, 226, 202, 53, 77, 245, + 75, 53, 77, 188, 243, 117, 45, 77, 86, 45, 77, 143, 243, 117, 45, 244, 1, + 220, 205, 86, 45, 77, 218, 94, 86, 45, 211, 50, 86, 45, 77, 211, 50, 86, + 45, 246, 77, 211, 50, 86, 45, 77, 246, 77, 211, 50, 86, 45, 60, 86, 45, + 211, 238, 211, 100, 86, 251, 243, 211, 238, 249, 152, 86, 251, 243, 60, + 86, 251, 243, 77, 60, 247, 18, 173, 23, 86, 45, 77, 60, 247, 18, 167, 23, + 86, 45, 214, 104, 60, 86, 45, 77, 247, 139, 60, 86, 45, 218, 161, 59, 86, + 45, 230, 40, 59, 86, 45, 250, 175, 215, 246, 59, 86, 45, 241, 96, 215, + 246, 59, 86, 45, 77, 229, 92, 218, 160, 59, 86, 45, 77, 209, 203, 218, + 160, 59, 86, 45, 224, 39, 229, 92, 218, 160, 59, 86, 45, 247, 26, 229, + 111, 224, 39, 209, 203, 218, 160, 59, 86, 45, 39, 77, 59, 86, 45, 207, + 22, 86, 45, 249, 201, 188, 243, 117, 45, 249, 201, 86, 45, 249, 201, 143, + 243, 117, 45, 77, 249, 201, 188, 243, 117, 45, 77, 249, 201, 86, 45, 77, + 249, 201, 143, 243, 117, 45, 212, 126, 86, 45, 77, 212, 125, 86, 45, 207, + 46, 86, 45, 77, 207, 46, 86, 45, 222, 137, 86, 45, 50, 247, 26, 229, 111, + 129, 245, 121, 252, 108, 59, 211, 52, 247, 119, 5, 59, 211, 51, 221, 118, + 222, 142, 213, 181, 222, 142, 213, 137, 47, 218, 0, 250, 164, 245, 233, + 48, 218, 0, 250, 164, 245, 233, 222, 123, 2, 67, 233, 25, 218, 225, 214, + 181, 220, 138, 213, 181, 213, 138, 220, 138, 214, 180, 79, 250, 129, 2, + 194, 91, 11, 218, 142, 245, 162, 152, 245, 74, 11, 242, 50, 245, 162, 98, + 229, 134, 252, 117, 98, 229, 134, 222, 122, 59, 245, 157, 2, 248, 127, + 245, 23, 23, 2, 245, 23, 243, 61, 73, 222, 135, 209, 196, 229, 92, 48, + 247, 92, 2, 245, 23, 209, 203, 47, 247, 92, 2, 245, 23, 47, 222, 91, 232, + 120, 48, 222, 91, 232, 120, 241, 82, 222, 91, 232, 120, 230, 86, 120, + 212, 201, 230, 86, 130, 212, 201, 47, 23, 48, 50, 210, 143, 47, 23, 48, + 212, 201, 47, 226, 97, 152, 48, 212, 201, 152, 47, 212, 201, 120, 212, + 202, 2, 247, 234, 52, 229, 89, 245, 80, 249, 46, 194, 218, 42, 59, 247, + 138, 245, 156, 59, 247, 138, 245, 157, 2, 92, 211, 207, 59, 247, 138, + 245, 157, 2, 86, 211, 207, 59, 49, 2, 92, 211, 207, 59, 49, 2, 86, 211, + 207, 11, 47, 59, 49, 145, 11, 48, 59, 49, 145, 11, 47, 252, 109, 145, 11, + 48, 252, 109, 145, 11, 47, 50, 252, 109, 145, 11, 48, 50, 252, 109, 145, + 11, 47, 59, 211, 93, 215, 204, 145, 11, 48, 59, 211, 93, 215, 204, 145, + 11, 47, 241, 185, 221, 216, 11, 48, 241, 185, 221, 216, 167, 219, 207, + 45, 173, 219, 207, 45, 252, 87, 240, 206, 247, 234, 45, 247, 194, 240, + 206, 247, 234, 45, 48, 51, 2, 39, 220, 218, 152, 92, 45, 152, 86, 45, + 152, 47, 48, 45, 152, 92, 50, 45, 152, 86, 50, 45, 152, 47, 48, 50, 45, + 152, 92, 51, 241, 98, 134, 152, 86, 51, 241, 98, 134, 152, 92, 50, 51, + 241, 98, 134, 152, 86, 50, 51, 241, 98, 134, 152, 86, 214, 103, 45, 56, + 57, 249, 195, 56, 57, 245, 20, 56, 57, 244, 148, 56, 57, 245, 19, 56, 57, + 244, 84, 56, 57, 244, 211, 56, 57, 244, 147, 56, 57, 245, 18, 56, 57, + 244, 52, 56, 57, 244, 179, 56, 57, 244, 115, 56, 57, 244, 242, 56, 57, + 244, 83, 56, 57, 244, 210, 56, 57, 244, 146, 56, 57, 245, 17, 56, 57, + 244, 36, 56, 57, 244, 163, 56, 57, 244, 99, 56, 57, 244, 226, 56, 57, + 244, 67, 56, 57, 244, 194, 56, 57, 244, 130, 56, 57, 245, 1, 56, 57, 244, + 51, 56, 57, 244, 178, 56, 57, 244, 114, 56, 57, 244, 241, 56, 57, 244, + 82, 56, 57, 244, 209, 56, 57, 244, 145, 56, 57, 245, 16, 56, 57, 244, 28, + 56, 57, 244, 155, 56, 57, 244, 91, 56, 57, 244, 218, 56, 57, 244, 59, 56, + 57, 244, 186, 56, 57, 244, 122, 56, 57, 244, 249, 56, 57, 244, 43, 56, + 57, 244, 170, 56, 57, 244, 106, 56, 57, 244, 233, 56, 57, 244, 74, 56, + 57, 244, 201, 56, 57, 244, 137, 56, 57, 245, 8, 56, 57, 244, 35, 56, 57, + 244, 162, 56, 57, 244, 98, 56, 57, 244, 225, 56, 57, 244, 66, 56, 57, + 244, 193, 56, 57, 244, 129, 56, 57, 245, 0, 56, 57, 244, 50, 56, 57, 244, + 177, 56, 57, 244, 113, 56, 57, 244, 240, 56, 57, 244, 81, 56, 57, 244, + 208, 56, 57, 244, 144, 56, 57, 245, 15, 56, 57, 244, 24, 56, 57, 244, + 151, 56, 57, 244, 87, 56, 57, 244, 214, 56, 57, 244, 55, 56, 57, 244, + 182, 56, 57, 244, 118, 56, 57, 244, 245, 56, 57, 244, 39, 56, 57, 244, + 166, 56, 57, 244, 102, 56, 57, 244, 229, 56, 57, 244, 70, 56, 57, 244, + 197, 56, 57, 244, 133, 56, 57, 245, 4, 56, 57, 244, 31, 56, 57, 244, 158, + 56, 57, 244, 94, 56, 57, 244, 221, 56, 57, 244, 62, 56, 57, 244, 189, 56, + 57, 244, 125, 56, 57, 244, 252, 56, 57, 244, 46, 56, 57, 244, 173, 56, + 57, 244, 109, 56, 57, 244, 236, 56, 57, 244, 77, 56, 57, 244, 204, 56, + 57, 244, 140, 56, 57, 245, 11, 56, 57, 244, 27, 56, 57, 244, 154, 56, 57, + 244, 90, 56, 57, 244, 217, 56, 57, 244, 58, 56, 57, 244, 185, 56, 57, + 244, 121, 56, 57, 244, 248, 56, 57, 244, 42, 56, 57, 244, 169, 56, 57, + 244, 105, 56, 57, 244, 232, 56, 57, 244, 73, 56, 57, 244, 200, 56, 57, + 244, 136, 56, 57, 245, 7, 56, 57, 244, 34, 56, 57, 244, 161, 56, 57, 244, + 97, 56, 57, 244, 224, 56, 57, 244, 65, 56, 57, 244, 192, 56, 57, 244, + 128, 56, 57, 244, 255, 56, 57, 244, 49, 56, 57, 244, 176, 56, 57, 244, + 112, 56, 57, 244, 239, 56, 57, 244, 80, 56, 57, 244, 207, 56, 57, 244, + 143, 56, 57, 245, 14, 56, 57, 244, 22, 56, 57, 244, 149, 56, 57, 244, 85, + 56, 57, 244, 212, 56, 57, 244, 53, 56, 57, 244, 180, 56, 57, 244, 116, + 56, 57, 244, 243, 56, 57, 244, 37, 56, 57, 244, 164, 56, 57, 244, 100, + 56, 57, 244, 227, 56, 57, 244, 68, 56, 57, 244, 195, 56, 57, 244, 131, + 56, 57, 245, 2, 56, 57, 244, 29, 56, 57, 244, 156, 56, 57, 244, 92, 56, + 57, 244, 219, 56, 57, 244, 60, 56, 57, 244, 187, 56, 57, 244, 123, 56, + 57, 244, 250, 56, 57, 244, 44, 56, 57, 244, 171, 56, 57, 244, 107, 56, + 57, 244, 234, 56, 57, 244, 75, 56, 57, 244, 202, 56, 57, 244, 138, 56, + 57, 245, 9, 56, 57, 244, 25, 56, 57, 244, 152, 56, 57, 244, 88, 56, 57, + 244, 215, 56, 57, 244, 56, 56, 57, 244, 183, 56, 57, 244, 119, 56, 57, + 244, 246, 56, 57, 244, 40, 56, 57, 244, 167, 56, 57, 244, 103, 56, 57, + 244, 230, 56, 57, 244, 71, 56, 57, 244, 198, 56, 57, 244, 134, 56, 57, + 245, 5, 56, 57, 244, 32, 56, 57, 244, 159, 56, 57, 244, 95, 56, 57, 244, + 222, 56, 57, 244, 63, 56, 57, 244, 190, 56, 57, 244, 126, 56, 57, 244, + 253, 56, 57, 244, 47, 56, 57, 244, 174, 56, 57, 244, 110, 56, 57, 244, + 237, 56, 57, 244, 78, 56, 57, 244, 205, 56, 57, 244, 141, 56, 57, 245, + 12, 56, 57, 244, 23, 56, 57, 244, 150, 56, 57, 244, 86, 56, 57, 244, 213, + 56, 57, 244, 54, 56, 57, 244, 181, 56, 57, 244, 117, 56, 57, 244, 244, + 56, 57, 244, 38, 56, 57, 244, 165, 56, 57, 244, 101, 56, 57, 244, 228, + 56, 57, 244, 69, 56, 57, 244, 196, 56, 57, 244, 132, 56, 57, 245, 3, 56, + 57, 244, 30, 56, 57, 244, 157, 56, 57, 244, 93, 56, 57, 244, 220, 56, 57, + 244, 61, 56, 57, 244, 188, 56, 57, 244, 124, 56, 57, 244, 251, 56, 57, + 244, 45, 56, 57, 244, 172, 56, 57, 244, 108, 56, 57, 244, 235, 56, 57, + 244, 76, 56, 57, 244, 203, 56, 57, 244, 139, 56, 57, 245, 10, 56, 57, + 244, 26, 56, 57, 244, 153, 56, 57, 244, 89, 56, 57, 244, 216, 56, 57, + 244, 57, 56, 57, 244, 184, 56, 57, 244, 120, 56, 57, 244, 247, 56, 57, + 244, 41, 56, 57, 244, 168, 56, 57, 244, 104, 56, 57, 244, 231, 56, 57, + 244, 72, 56, 57, 244, 199, 56, 57, 244, 135, 56, 57, 245, 6, 56, 57, 244, + 33, 56, 57, 244, 160, 56, 57, 244, 96, 56, 57, 244, 223, 56, 57, 244, 64, + 56, 57, 244, 191, 56, 57, 244, 127, 56, 57, 244, 254, 56, 57, 244, 48, + 56, 57, 244, 175, 56, 57, 244, 111, 56, 57, 244, 238, 56, 57, 244, 79, + 56, 57, 244, 206, 56, 57, 244, 142, 56, 57, 245, 13, 86, 210, 108, 51, 2, + 79, 91, 86, 210, 108, 51, 2, 50, 79, 91, 92, 50, 51, 2, 79, 91, 86, 50, + 51, 2, 79, 91, 47, 48, 50, 51, 2, 79, 91, 86, 210, 108, 51, 241, 98, 134, + 92, 50, 51, 241, 98, 134, 86, 50, 51, 241, 98, 134, 173, 51, 2, 194, 91, + 167, 51, 2, 194, 91, 167, 211, 36, 45, 173, 211, 36, 45, 92, 50, 246, 79, + 45, 86, 50, 246, 79, 45, 92, 211, 36, 246, 79, 45, 86, 211, 36, 246, 79, + 45, 86, 210, 108, 211, 36, 246, 79, 45, 86, 51, 2, 244, 21, 214, 9, 167, + 51, 211, 130, 134, 173, 51, 211, 130, 134, 86, 51, 2, 212, 192, 2, 79, + 91, 86, 51, 2, 212, 192, 2, 50, 79, 91, 86, 210, 108, 51, 2, 212, 191, + 86, 210, 108, 51, 2, 212, 192, 2, 79, 91, 86, 210, 108, 51, 2, 212, 192, + 2, 50, 79, 91, 92, 251, 245, 86, 251, 245, 92, 50, 251, 245, 86, 50, 251, + 245, 92, 51, 211, 130, 60, 245, 156, 86, 51, 211, 130, 60, 245, 156, 92, + 51, 241, 98, 250, 129, 211, 130, 60, 245, 156, 86, 51, 241, 98, 250, 129, + 211, 130, 60, 245, 156, 143, 207, 36, 23, 188, 243, 117, 45, 143, 243, + 117, 23, 188, 207, 36, 45, 143, 207, 36, 51, 2, 109, 143, 243, 117, 51, + 2, 109, 188, 243, 117, 51, 2, 109, 188, 207, 36, 51, 2, 109, 143, 207, + 36, 51, 23, 143, 243, 117, 45, 143, 243, 117, 51, 23, 188, 243, 117, 45, + 188, 243, 117, 51, 23, 188, 207, 36, 45, 188, 207, 36, 51, 23, 143, 207, + 36, 45, 218, 142, 245, 163, 247, 54, 242, 50, 245, 162, 242, 50, 245, + 163, 247, 54, 218, 142, 245, 162, 188, 243, 117, 51, 247, 54, 143, 243, + 117, 45, 143, 243, 117, 51, 247, 54, 188, 243, 117, 45, 242, 50, 245, + 163, 247, 54, 143, 243, 117, 45, 218, 142, 245, 163, 247, 54, 188, 243, + 117, 45, 143, 243, 117, 51, 247, 54, 143, 207, 36, 45, 143, 207, 36, 51, + 247, 54, 143, 243, 117, 45, 207, 65, 51, 220, 201, 245, 102, 218, 167, + 51, 220, 201, 86, 212, 33, 247, 17, 209, 196, 51, 220, 201, 86, 212, 33, + 247, 17, 244, 6, 51, 220, 201, 173, 212, 33, 247, 17, 230, 36, 51, 220, + 201, 173, 212, 33, 247, 17, 218, 156, 218, 159, 252, 22, 247, 194, 45, + 230, 39, 252, 22, 252, 87, 45, 211, 102, 252, 22, 252, 87, 45, 249, 154, + 252, 22, 252, 87, 45, 211, 102, 252, 22, 247, 194, 51, 2, 226, 201, 211, + 102, 252, 22, 252, 87, 51, 2, 220, 218, 229, 92, 48, 216, 54, 247, 194, + 45, 229, 92, 47, 216, 54, 252, 87, 45, 252, 87, 247, 192, 247, 234, 45, + 247, 194, 247, 192, 247, 234, 45, 86, 51, 84, 215, 144, 92, 45, 92, 51, + 84, 215, 144, 86, 45, 215, 144, 86, 51, 84, 92, 45, 86, 51, 2, 101, 55, + 92, 51, 2, 101, 55, 86, 51, 211, 233, 206, 195, 47, 48, 51, 211, 233, 5, + 247, 233, 167, 210, 108, 51, 241, 98, 5, 247, 233, 47, 138, 120, 48, 138, + 130, 239, 89, 47, 138, 130, 48, 138, 120, 239, 89, 120, 138, 48, 130, + 138, 47, 239, 89, 120, 138, 47, 130, 138, 48, 239, 89, 47, 138, 120, 48, + 138, 120, 239, 89, 120, 138, 48, 130, 138, 48, 239, 89, 47, 138, 130, 48, + 138, 130, 239, 89, 120, 138, 47, 130, 138, 47, 239, 89, 92, 239, 90, 2, + 138, 120, 211, 130, 134, 86, 239, 90, 2, 138, 120, 211, 130, 134, 167, + 239, 90, 2, 138, 48, 211, 130, 134, 173, 239, 90, 2, 138, 48, 211, 130, + 134, 92, 239, 90, 2, 138, 130, 211, 130, 134, 86, 239, 90, 2, 138, 130, + 211, 130, 134, 167, 239, 90, 2, 138, 47, 211, 130, 134, 173, 239, 90, 2, + 138, 47, 211, 130, 134, 92, 239, 90, 2, 138, 120, 241, 98, 134, 86, 239, + 90, 2, 138, 120, 241, 98, 134, 167, 239, 90, 2, 138, 48, 241, 98, 134, + 173, 239, 90, 2, 138, 48, 241, 98, 134, 92, 239, 90, 2, 138, 130, 241, + 98, 134, 86, 239, 90, 2, 138, 130, 241, 98, 134, 167, 239, 90, 2, 138, + 47, 241, 98, 134, 173, 239, 90, 2, 138, 47, 241, 98, 134, 92, 239, 90, 2, + 138, 120, 84, 92, 239, 90, 2, 138, 244, 8, 167, 239, 90, 2, 138, 47, 250, + 12, 167, 239, 90, 2, 138, 218, 167, 86, 239, 90, 2, 138, 120, 84, 86, + 239, 90, 2, 138, 244, 8, 173, 239, 90, 2, 138, 47, 250, 12, 173, 239, 90, + 2, 138, 218, 167, 92, 239, 90, 2, 138, 120, 84, 86, 239, 90, 2, 138, 209, + 206, 92, 239, 90, 2, 138, 130, 84, 86, 239, 90, 2, 138, 244, 8, 86, 239, + 90, 2, 138, 120, 84, 92, 239, 90, 2, 138, 209, 206, 86, 239, 90, 2, 138, + 130, 84, 92, 239, 90, 2, 138, 244, 8, 92, 239, 90, 2, 138, 120, 84, 152, + 246, 78, 92, 239, 90, 2, 138, 130, 250, 26, 152, 246, 78, 86, 239, 90, 2, + 138, 120, 84, 152, 246, 78, 86, 239, 90, 2, 138, 130, 250, 26, 152, 246, + 78, 167, 239, 90, 2, 138, 47, 250, 12, 173, 239, 90, 2, 138, 218, 167, + 173, 239, 90, 2, 138, 47, 250, 12, 167, 239, 90, 2, 138, 218, 167, 48, + 50, 51, 2, 218, 93, 239, 68, 242, 242, 3, 84, 86, 45, 211, 181, 222, 133, + 84, 86, 45, 92, 51, 84, 211, 181, 222, 132, 86, 51, 84, 211, 181, 222, + 132, 86, 51, 84, 252, 149, 146, 124, 230, 10, 84, 92, 45, 92, 51, 211, + 233, 230, 9, 239, 230, 84, 86, 45, 213, 182, 84, 86, 45, 92, 51, 211, + 233, 213, 181, 213, 138, 84, 92, 45, 47, 241, 214, 212, 191, 48, 241, + 214, 212, 191, 120, 241, 214, 212, 191, 130, 241, 214, 212, 191, 211, 36, + 79, 250, 129, 245, 233, 205, 160, 224, 41, 214, 116, 205, 160, 224, 41, + 210, 95, 247, 162, 47, 59, 247, 26, 145, 48, 59, 247, 26, 145, 47, 59, + 221, 216, 48, 59, 221, 216, 205, 160, 224, 41, 47, 233, 84, 145, 205, + 160, 224, 41, 48, 233, 84, 145, 205, 160, 224, 41, 47, 249, 223, 145, + 205, 160, 224, 41, 48, 249, 223, 145, 47, 49, 249, 134, 2, 209, 226, 48, + 49, 249, 134, 2, 209, 226, 47, 49, 249, 134, 2, 211, 208, 233, 69, 211, + 102, 247, 91, 48, 49, 249, 134, 2, 211, 208, 233, 69, 249, 154, 247, 91, + 47, 49, 249, 134, 2, 211, 208, 233, 69, 249, 154, 247, 91, 48, 49, 249, + 134, 2, 211, 208, 233, 69, 211, 102, 247, 91, 47, 252, 109, 249, 134, 2, + 245, 23, 48, 252, 109, 249, 134, 2, 245, 23, 47, 252, 22, 230, 10, 145, + 48, 252, 22, 239, 230, 145, 50, 47, 252, 22, 239, 230, 145, 50, 48, 252, + 22, 230, 10, 145, 47, 60, 211, 93, 215, 204, 145, 48, 60, 211, 93, 215, + 204, 145, 244, 21, 242, 8, 79, 205, 31, 229, 205, 227, 116, 252, 109, + 222, 135, 230, 46, 48, 252, 109, 209, 53, 2, 214, 107, 227, 116, 48, 252, + 109, 2, 245, 23, 252, 109, 2, 218, 1, 233, 25, 253, 9, 252, 108, 214, + 133, 252, 109, 222, 135, 230, 46, 214, 133, 252, 109, 222, 135, 209, 206, + 201, 252, 108, 218, 224, 252, 108, 252, 109, 2, 209, 226, 218, 224, 252, + 109, 2, 209, 226, 222, 222, 252, 109, 222, 135, 209, 206, 222, 222, 252, + 109, 222, 135, 244, 8, 227, 116, 252, 109, 2, 222, 142, 252, 0, 243, 31, + 233, 69, 51, 220, 201, 120, 23, 218, 167, 227, 116, 252, 109, 2, 222, + 142, 252, 0, 243, 31, 233, 69, 51, 220, 201, 120, 23, 230, 46, 227, 116, + 252, 109, 2, 222, 142, 252, 0, 243, 31, 233, 69, 51, 220, 201, 130, 23, + 218, 167, 227, 116, 252, 109, 2, 222, 142, 252, 0, 243, 31, 233, 69, 51, + 220, 201, 130, 23, 230, 46, 227, 116, 252, 109, 2, 222, 142, 252, 0, 243, + 31, 233, 69, 51, 220, 201, 48, 23, 209, 206, 227, 116, 252, 109, 2, 222, + 142, 252, 0, 243, 31, 233, 69, 51, 220, 201, 47, 23, 209, 206, 227, 116, + 252, 109, 2, 222, 142, 252, 0, 243, 31, 233, 69, 51, 220, 201, 48, 23, + 244, 8, 227, 116, 252, 109, 2, 222, 142, 252, 0, 243, 31, 233, 69, 51, + 220, 201, 47, 23, 244, 8, 218, 224, 243, 43, 216, 28, 243, 43, 216, 29, + 2, 222, 86, 243, 43, 216, 29, 2, 5, 247, 234, 52, 243, 43, 216, 29, 2, + 48, 51, 52, 243, 43, 216, 29, 2, 47, 51, 52, 247, 234, 2, 194, 134, 39, + 79, 134, 39, 221, 221, 39, 218, 225, 214, 180, 39, 221, 118, 247, 234, + 245, 80, 249, 46, 194, 250, 129, 23, 211, 102, 160, 245, 80, 249, 46, 79, + 134, 247, 234, 2, 213, 140, 206, 195, 39, 252, 85, 245, 75, 53, 120, 51, + 211, 233, 247, 233, 39, 59, 249, 85, 39, 249, 85, 39, 230, 9, 39, 239, + 229, 247, 234, 2, 5, 247, 234, 211, 130, 212, 42, 218, 167, 247, 234, 2, + 118, 194, 213, 213, 211, 130, 212, 42, 218, 167, 98, 218, 142, 245, 163, + 214, 235, 98, 242, 50, 245, 163, 214, 235, 98, 251, 209, 98, 5, 247, 233, + 98, 214, 107, 118, 232, 119, 214, 105, 211, 52, 2, 67, 52, 211, 52, 2, + 209, 226, 218, 1, 233, 69, 211, 51, 211, 52, 2, 216, 35, 251, 200, 249, + 153, 48, 211, 52, 84, 47, 211, 51, 47, 211, 52, 250, 12, 79, 134, 79, + 250, 129, 250, 12, 48, 211, 51, 249, 142, 2, 47, 160, 249, 202, 249, 142, + 2, 48, 160, 249, 202, 60, 249, 141, 29, 2, 47, 160, 249, 202, 29, 2, 48, + 160, 249, 202, 59, 238, 56, 60, 238, 56, 47, 207, 14, 242, 8, 48, 207, + 14, 242, 8, 47, 50, 207, 14, 242, 8, 48, 50, 207, 14, 242, 8, 233, 61, + 233, 45, 211, 204, 131, 233, 45, 233, 46, 225, 105, 2, 79, 134, 244, 15, + 226, 97, 49, 2, 247, 112, 222, 90, 233, 58, 251, 231, 215, 110, 220, 115, + 242, 242, 3, 23, 214, 237, 221, 221, 242, 242, 3, 23, 214, 237, 221, 222, + 2, 211, 181, 52, 237, 173, 211, 130, 23, 214, 237, 221, 221, 240, 28, + 214, 25, 212, 30, 244, 7, 211, 52, 2, 47, 160, 249, 202, 244, 7, 211, 52, + 2, 48, 160, 249, 202, 60, 245, 157, 2, 130, 45, 60, 229, 88, 59, 247, + 234, 2, 130, 45, 60, 247, 234, 2, 130, 45, 242, 228, 59, 214, 107, 242, + 228, 60, 214, 107, 242, 228, 59, 245, 156, 242, 228, 60, 245, 156, 242, + 228, 59, 247, 233, 242, 228, 60, 247, 233, 218, 41, 218, 225, 214, 181, + 222, 132, 214, 181, 2, 222, 86, 218, 225, 214, 181, 2, 194, 91, 249, 231, + 214, 180, 249, 231, 218, 225, 214, 180, 50, 220, 218, 211, 36, 220, 218, + 230, 41, 247, 18, 252, 109, 145, 218, 162, 247, 18, 252, 109, 145, 211, + 168, 226, 199, 226, 32, 39, 67, 222, 132, 226, 32, 39, 101, 222, 132, + 226, 32, 39, 29, 222, 132, 226, 32, 209, 219, 222, 133, 2, 245, 23, 226, + 32, 209, 219, 222, 133, 2, 220, 218, 226, 32, 49, 233, 8, 222, 132, 226, + 32, 49, 209, 219, 222, 132, 118, 229, 134, 23, 222, 132, 118, 229, 134, + 222, 123, 222, 132, 226, 32, 29, 222, 132, 226, 172, 118, 213, 160, 213, + 158, 2, 233, 21, 219, 207, 233, 22, 222, 132, 241, 222, 221, 211, 233, + 21, 233, 22, 2, 50, 91, 233, 22, 251, 165, 2, 214, 235, 247, 229, 241, + 79, 252, 87, 233, 19, 229, 206, 233, 20, 2, 219, 36, 221, 192, 251, 253, + 220, 195, 229, 206, 233, 20, 2, 216, 54, 221, 192, 251, 253, 220, 195, + 229, 206, 233, 20, 224, 43, 233, 63, 212, 42, 220, 195, 233, 22, 251, + 253, 32, 220, 205, 222, 132, 219, 201, 233, 22, 222, 132, 233, 22, 2, 92, + 51, 2, 109, 233, 22, 2, 29, 53, 233, 22, 2, 233, 7, 233, 22, 2, 209, 218, + 233, 22, 2, 222, 86, 233, 22, 2, 209, 226, 232, 120, 230, 86, 47, 211, + 52, 222, 132, 205, 160, 224, 41, 217, 106, 247, 145, 205, 160, 224, 41, + 217, 106, 221, 0, 205, 160, 224, 41, 217, 106, 220, 110, 101, 3, 2, 5, + 247, 234, 52, 101, 3, 2, 247, 228, 253, 22, 52, 101, 3, 2, 211, 181, 52, + 101, 3, 2, 67, 55, 101, 3, 2, 211, 181, 55, 101, 3, 2, 213, 183, 105, + 101, 3, 2, 60, 211, 51, 226, 202, 3, 2, 247, 156, 52, 226, 202, 3, 2, 67, + 55, 226, 202, 3, 2, 242, 50, 245, 21, 226, 202, 3, 2, 218, 142, 245, 21, + 101, 3, 233, 69, 47, 160, 247, 233, 101, 3, 233, 69, 48, 160, 247, 233, + 209, 38, 222, 123, 247, 60, 220, 115, 226, 94, 3, 2, 67, 52, 226, 94, 3, + 2, 209, 226, 216, 51, 220, 116, 2, 249, 154, 247, 191, 214, 213, 220, + 115, 226, 94, 3, 233, 69, 47, 160, 247, 233, 226, 94, 3, 233, 69, 48, + 160, 247, 233, 39, 226, 94, 3, 2, 247, 228, 253, 21, 226, 94, 3, 233, 69, + 50, 247, 233, 39, 245, 75, 53, 101, 3, 233, 69, 211, 51, 226, 202, 3, + 233, 69, 211, 51, 226, 94, 3, 233, 69, 211, 51, 233, 16, 220, 115, 218, + 157, 233, 16, 220, 115, 205, 160, 224, 41, 219, 10, 247, 145, 252, 134, + 222, 123, 247, 96, 233, 8, 2, 245, 23, 209, 219, 2, 226, 202, 53, 209, + 219, 2, 222, 86, 233, 8, 2, 222, 86, 233, 8, 2, 229, 134, 252, 117, 209, + 219, 2, 229, 134, 222, 122, 209, 219, 84, 233, 7, 233, 8, 84, 209, 218, + 209, 219, 84, 250, 129, 84, 233, 7, 233, 8, 84, 250, 129, 84, 209, 218, + 209, 219, 250, 12, 23, 232, 119, 2, 209, 218, 233, 8, 250, 12, 23, 232, + 119, 2, 233, 7, 247, 192, 209, 219, 2, 216, 34, 247, 192, 233, 8, 2, 216, + 34, 50, 49, 233, 7, 50, 49, 209, 218, 247, 192, 209, 219, 2, 216, 35, 23, + 214, 213, 220, 115, 229, 134, 23, 2, 67, 52, 229, 134, 222, 123, 2, 67, + 52, 50, 229, 134, 252, 117, 50, 229, 134, 222, 122, 118, 233, 9, 229, + 134, 252, 117, 118, 233, 9, 229, 134, 222, 122, 214, 221, 230, 86, 222, + 122, 214, 221, 230, 86, 252, 117, 229, 134, 222, 123, 222, 83, 229, 134, + 252, 117, 229, 134, 23, 2, 226, 247, 214, 9, 229, 134, 222, 123, 2, 226, + 247, 214, 9, 229, 134, 23, 2, 194, 246, 78, 229, 134, 222, 123, 2, 194, + 246, 78, 229, 134, 23, 2, 50, 222, 86, 229, 134, 23, 2, 209, 226, 229, + 134, 23, 2, 50, 209, 226, 5, 209, 35, 2, 209, 226, 229, 134, 222, 123, 2, + 50, 222, 86, 229, 134, 222, 123, 2, 50, 209, 226, 205, 160, 224, 41, 245, + 32, 252, 77, 205, 160, 224, 41, 219, 72, 252, 77, 242, 242, 3, 2, 67, 55, + 237, 173, 2, 67, 52, 211, 36, 194, 250, 129, 2, 50, 79, 91, 211, 36, 194, + 250, 129, 2, 211, 36, 79, 91, 211, 181, 222, 133, 2, 67, 52, 211, 181, + 222, 133, 2, 218, 142, 245, 21, 215, 48, 226, 202, 215, 47, 247, 132, 2, + 67, 52, 242, 242, 2, 251, 209, 252, 149, 146, 211, 130, 2, 247, 228, 253, + 21, 252, 44, 146, 222, 123, 146, 124, 242, 242, 3, 84, 101, 53, 101, 3, + 84, 242, 242, 53, 242, 242, 3, 84, 211, 181, 222, 132, 50, 247, 163, 242, + 243, 118, 247, 127, 242, 242, 215, 62, 129, 247, 127, 242, 242, 215, 62, + 242, 242, 3, 2, 118, 177, 84, 23, 118, 177, 55, 242, 237, 2, 241, 125, + 177, 52, 230, 10, 2, 247, 234, 233, 25, 239, 230, 2, 247, 234, 233, 25, + 230, 10, 2, 219, 196, 141, 52, 239, 230, 2, 219, 196, 141, 52, 230, 10, + 222, 123, 214, 237, 146, 124, 239, 230, 222, 123, 214, 237, 146, 124, + 230, 10, 222, 123, 214, 237, 146, 211, 130, 2, 67, 233, 25, 239, 230, + 222, 123, 214, 237, 146, 211, 130, 2, 67, 233, 25, 230, 10, 222, 123, + 214, 237, 146, 211, 130, 2, 67, 52, 239, 230, 222, 123, 214, 237, 146, + 211, 130, 2, 67, 52, 230, 10, 222, 123, 214, 237, 146, 211, 130, 2, 67, + 84, 218, 167, 239, 230, 222, 123, 214, 237, 146, 211, 130, 2, 67, 84, + 230, 46, 230, 10, 222, 123, 252, 45, 239, 230, 222, 123, 252, 45, 230, + 10, 23, 215, 39, 224, 43, 146, 124, 239, 230, 23, 215, 39, 224, 43, 146, + 124, 230, 10, 23, 224, 43, 252, 45, 239, 230, 23, 224, 43, 252, 45, 230, + 10, 84, 244, 14, 146, 84, 239, 229, 239, 230, 84, 244, 14, 146, 84, 230, + 9, 230, 10, 84, 215, 48, 222, 123, 242, 243, 239, 230, 84, 215, 48, 222, + 123, 242, 243, 230, 10, 84, 215, 48, 84, 239, 229, 239, 230, 84, 215, 48, + 84, 230, 9, 230, 10, 84, 239, 230, 84, 244, 14, 242, 243, 239, 230, 84, + 230, 10, 84, 244, 14, 242, 243, 230, 10, 84, 214, 237, 146, 84, 239, 230, + 84, 214, 237, 242, 243, 239, 230, 84, 214, 237, 146, 84, 230, 10, 84, + 214, 237, 242, 243, 214, 237, 146, 211, 130, 222, 123, 230, 9, 214, 237, + 146, 211, 130, 222, 123, 239, 229, 214, 237, 146, 211, 130, 222, 123, + 230, 10, 2, 67, 233, 25, 214, 237, 146, 211, 130, 222, 123, 239, 230, 2, + 67, 233, 25, 244, 14, 146, 211, 130, 222, 123, 230, 9, 244, 14, 146, 211, + 130, 222, 123, 239, 229, 244, 14, 214, 237, 146, 211, 130, 222, 123, 230, + 9, 244, 14, 214, 237, 146, 211, 130, 222, 123, 239, 229, 215, 48, 222, + 123, 230, 9, 215, 48, 222, 123, 239, 229, 215, 48, 84, 230, 10, 84, 242, + 242, 53, 215, 48, 84, 239, 230, 84, 242, 242, 53, 50, 225, 93, 230, 9, + 50, 225, 93, 239, 229, 50, 225, 93, 230, 10, 2, 209, 226, 239, 230, 222, + 83, 230, 9, 239, 230, 250, 12, 230, 9, 230, 10, 247, 192, 249, 46, 247, + 19, 239, 230, 247, 192, 249, 46, 247, 19, 230, 10, 247, 192, 249, 46, + 247, 20, 84, 214, 237, 242, 243, 239, 230, 247, 192, 249, 46, 247, 20, + 84, 214, 237, 242, 243, 214, 214, 212, 46, 230, 84, 212, 46, 214, 214, + 212, 47, 222, 123, 146, 124, 230, 84, 212, 47, 222, 123, 146, 124, 242, + 242, 3, 2, 249, 78, 52, 220, 140, 84, 215, 39, 242, 242, 53, 213, 174, + 84, 215, 39, 242, 242, 53, 220, 140, 84, 215, 39, 224, 43, 146, 124, 213, + 174, 84, 215, 39, 224, 43, 146, 124, 220, 140, 84, 242, 242, 53, 213, + 174, 84, 242, 242, 53, 220, 140, 84, 224, 43, 146, 124, 213, 174, 84, + 224, 43, 146, 124, 220, 140, 84, 252, 149, 146, 124, 213, 174, 84, 252, + 149, 146, 124, 220, 140, 84, 224, 43, 252, 149, 146, 124, 213, 174, 84, + 224, 43, 252, 149, 146, 124, 50, 220, 139, 50, 213, 173, 213, 182, 2, + 245, 23, 213, 138, 2, 245, 23, 213, 182, 2, 101, 3, 55, 213, 138, 2, 101, + 3, 55, 213, 182, 2, 226, 94, 3, 55, 213, 138, 2, 226, 94, 3, 55, 213, + 182, 73, 222, 123, 146, 211, 130, 2, 67, 52, 213, 138, 73, 222, 123, 146, + 211, 130, 2, 67, 52, 213, 182, 73, 84, 242, 242, 53, 213, 138, 73, 84, + 242, 242, 53, 213, 182, 73, 84, 211, 181, 222, 132, 213, 138, 73, 84, + 211, 181, 222, 132, 213, 182, 73, 84, 252, 149, 146, 124, 213, 138, 73, + 84, 252, 149, 146, 124, 213, 182, 73, 84, 224, 43, 146, 124, 213, 138, + 73, 84, 224, 43, 146, 124, 49, 47, 222, 142, 96, 222, 132, 49, 48, 222, + 142, 96, 222, 132, 247, 192, 213, 181, 247, 192, 213, 137, 247, 192, 213, + 182, 222, 123, 146, 124, 247, 192, 213, 138, 222, 123, 146, 124, 213, + 182, 84, 213, 137, 213, 138, 84, 213, 181, 213, 182, 84, 213, 181, 213, + 138, 84, 213, 137, 213, 138, 250, 12, 213, 181, 213, 138, 250, 12, 23, + 232, 119, 249, 46, 246, 79, 2, 213, 181, 243, 61, 73, 222, 135, 244, 6, + 220, 246, 2, 212, 121, 211, 101, 211, 66, 233, 7, 241, 137, 224, 57, 215, + 144, 47, 212, 201, 215, 144, 130, 212, 201, 215, 144, 120, 212, 201, 221, + 119, 2, 182, 79, 250, 129, 211, 36, 48, 210, 143, 50, 79, 250, 129, 47, + 210, 143, 79, 250, 129, 50, 47, 210, 143, 50, 79, 250, 129, 50, 47, 210, + 143, 152, 246, 79, 241, 98, 47, 227, 88, 73, 50, 209, 22, 215, 144, 130, + 212, 202, 2, 222, 86, 215, 144, 120, 212, 202, 2, 209, 226, 215, 144, + 120, 212, 202, 84, 215, 144, 130, 212, 201, 50, 130, 212, 201, 50, 120, + 212, 201, 50, 213, 225, 224, 43, 53, 218, 224, 50, 213, 225, 224, 43, 53, + 245, 42, 224, 43, 245, 82, 2, 218, 224, 225, 104, 214, 235, 79, 229, 206, + 2, 247, 234, 52, 79, 229, 206, 2, 247, 234, 55, 130, 212, 202, 2, 247, + 234, 55, 221, 222, 2, 194, 91, 221, 222, 2, 211, 181, 222, 132, 211, 36, + 79, 250, 129, 249, 225, 219, 11, 211, 36, 79, 250, 129, 2, 194, 91, 211, + 36, 247, 163, 222, 132, 211, 36, 225, 93, 230, 9, 211, 36, 225, 93, 239, + 229, 244, 14, 214, 237, 230, 10, 222, 123, 146, 124, 244, 14, 214, 237, + 239, 230, 222, 123, 146, 124, 211, 36, 214, 181, 249, 225, 219, 11, 230, + 86, 211, 36, 79, 250, 129, 222, 132, 50, 214, 181, 222, 132, 59, 79, 134, + 226, 32, 59, 79, 134, 143, 243, 117, 59, 45, 143, 207, 36, 59, 45, 188, + 243, 117, 59, 45, 188, 207, 36, 59, 45, 47, 48, 59, 45, 92, 60, 45, 167, + 60, 45, 173, 60, 45, 143, 243, 117, 60, 45, 143, 207, 36, 60, 45, 188, + 243, 117, 60, 45, 188, 207, 36, 60, 45, 47, 48, 60, 45, 120, 130, 60, 45, + 86, 51, 2, 211, 167, 244, 6, 86, 51, 2, 211, 167, 209, 196, 92, 51, 2, + 211, 167, 244, 6, 92, 51, 2, 211, 167, 209, 196, 49, 2, 211, 102, 160, + 249, 202, 49, 2, 249, 154, 160, 249, 202, 49, 2, 209, 203, 48, 245, 163, + 160, 249, 202, 49, 2, 229, 92, 47, 245, 163, 160, 249, 202, 245, 157, 2, + 47, 160, 249, 202, 245, 157, 2, 48, 160, 249, 202, 245, 157, 2, 211, 102, + 160, 249, 202, 245, 157, 2, 249, 154, 160, 249, 202, 244, 21, 214, 107, + 60, 230, 86, 214, 107, 59, 230, 86, 214, 107, 60, 208, 226, 5, 214, 107, + 59, 208, 226, 5, 214, 107, 60, 221, 140, 59, 221, 140, 59, 239, 25, 60, + 239, 25, 194, 60, 239, 25, 60, 230, 86, 247, 233, 60, 227, 109, 245, 156, + 59, 227, 109, 245, 156, 60, 227, 109, 229, 88, 59, 227, 109, 229, 88, 60, + 5, 245, 156, 60, 5, 229, 88, 59, 5, 229, 88, 60, 194, 243, 55, 59, 194, + 243, 55, 60, 79, 243, 55, 59, 79, 243, 55, 47, 51, 2, 5, 247, 233, 129, + 92, 251, 241, 47, 51, 2, 39, 220, 218, 152, 92, 214, 103, 45, 92, 210, + 108, 51, 2, 79, 91, 92, 210, 108, 51, 2, 50, 79, 91, 92, 210, 108, 51, + 241, 98, 134, 92, 210, 108, 211, 36, 246, 79, 45, 92, 51, 2, 244, 21, + 214, 9, 92, 51, 2, 212, 192, 2, 79, 91, 92, 51, 2, 212, 192, 2, 50, 79, + 91, 92, 210, 108, 51, 2, 212, 191, 92, 210, 108, 51, 2, 212, 192, 2, 79, + 91, 92, 210, 108, 51, 2, 212, 192, 2, 50, 79, 91, 92, 51, 211, 233, 206, + 195, 207, 65, 51, 220, 201, 245, 102, 230, 46, 242, 242, 3, 84, 92, 45, + 218, 225, 211, 181, 222, 133, 84, 92, 45, 92, 51, 84, 218, 225, 252, 149, + 146, 124, 86, 51, 211, 233, 239, 229, 86, 51, 211, 233, 213, 137, 92, + 219, 207, 45, 86, 219, 207, 45, 218, 225, 211, 181, 222, 133, 84, 86, 45, + 86, 51, 84, 218, 225, 252, 149, 146, 124, 211, 181, 222, 133, 84, 92, 45, + 92, 51, 84, 252, 149, 146, 124, 92, 51, 84, 218, 225, 211, 181, 222, 132, + 86, 51, 84, 218, 225, 211, 181, 222, 132, 173, 211, 50, 205, 31, 45, 215, + 144, 214, 237, 143, 45, 215, 144, 250, 173, 188, 45, 59, 227, 109, 214, + 26, 60, 5, 214, 26, 59, 5, 214, 26, 60, 218, 162, 221, 140, 59, 218, 162, + 221, 140, 77, 230, 86, 247, 233, 77, 222, 87, 2, 222, 87, 233, 25, 77, + 247, 234, 2, 247, 234, 233, 25, 77, 247, 233, 77, 39, 217, 162, 214, 237, + 143, 51, 2, 238, 129, 239, 68, 250, 173, 188, 51, 2, 238, 129, 212, 191, + 214, 237, 143, 51, 2, 194, 212, 191, 250, 173, 188, 51, 2, 194, 212, 191, + 250, 19, 51, 220, 201, 173, 212, 33, 143, 243, 116, 215, 144, 250, 19, + 51, 220, 201, 173, 212, 33, 143, 243, 116, 92, 211, 50, 45, 167, 211, 50, + 45, 86, 211, 50, 45, 173, 211, 50, 45, 47, 48, 211, 50, 45, 120, 130, + 211, 50, 45, 143, 207, 36, 211, 50, 45, 143, 243, 117, 211, 50, 45, 188, + 243, 117, 211, 50, 45, 188, 207, 36, 211, 50, 45, 92, 211, 50, 246, 77, + 45, 167, 211, 50, 246, 77, 45, 86, 211, 50, 246, 77, 45, 173, 211, 50, + 246, 77, 45, 247, 194, 211, 50, 222, 142, 247, 234, 45, 252, 87, 211, 50, + 222, 142, 247, 234, 45, 92, 211, 50, 51, 211, 130, 134, 167, 211, 50, 51, + 211, 130, 134, 86, 211, 50, 51, 211, 130, 134, 173, 211, 50, 51, 211, + 130, 134, 143, 207, 36, 211, 50, 51, 211, 130, 134, 143, 243, 117, 211, + 50, 51, 211, 130, 134, 188, 243, 117, 211, 50, 51, 211, 130, 134, 188, + 207, 36, 211, 50, 51, 211, 130, 134, 92, 211, 50, 51, 2, 50, 194, 91, + 167, 211, 50, 51, 2, 50, 194, 91, 86, 211, 50, 51, 2, 50, 194, 91, 173, + 211, 50, 51, 2, 50, 194, 91, 194, 212, 208, 231, 174, 79, 212, 208, 231, + 174, 92, 211, 50, 51, 131, 86, 211, 50, 45, 167, 211, 50, 51, 92, 73, + 173, 211, 50, 45, 86, 211, 50, 51, 131, 92, 211, 50, 45, 173, 211, 50, + 51, 92, 73, 167, 211, 50, 45, 92, 211, 50, 222, 30, 251, 241, 167, 211, + 50, 222, 30, 251, 241, 86, 211, 50, 222, 30, 251, 241, 173, 211, 50, 222, + 30, 251, 241, 92, 60, 39, 59, 45, 167, 60, 39, 59, 45, 86, 60, 39, 59, + 45, 173, 60, 39, 59, 45, 252, 87, 211, 50, 48, 210, 71, 45, 252, 87, 211, + 50, 249, 154, 210, 71, 45, 252, 87, 211, 50, 47, 210, 71, 45, 252, 87, + 211, 50, 211, 102, 210, 71, 45, 218, 229, 230, 46, 218, 229, 218, 167, + 225, 86, 230, 46, 225, 86, 218, 167, 241, 125, 247, 92, 251, 242, 247, + 231, 252, 86, 86, 60, 45, 211, 238, 211, 100, 92, 242, 238, 251, 243, + 211, 238, 218, 163, 167, 242, 238, 251, 243, 211, 238, 211, 100, 86, 242, + 238, 251, 243, 211, 238, 230, 42, 173, 242, 238, 251, 243, 60, 92, 242, + 238, 251, 243, 60, 167, 242, 238, 251, 243, 60, 86, 242, 238, 251, 243, + 60, 173, 242, 238, 251, 243, 173, 211, 50, 51, 2, 152, 211, 167, 230, 36, + 173, 211, 50, 51, 2, 152, 211, 167, 218, 156, 167, 211, 50, 51, 2, 152, + 211, 167, 230, 36, 167, 211, 50, 51, 2, 152, 211, 167, 218, 156, 92, 211, + 50, 51, 2, 152, 211, 167, 209, 196, 86, 211, 50, 51, 2, 152, 211, 167, + 209, 196, 92, 211, 50, 51, 2, 152, 211, 167, 244, 6, 86, 211, 50, 51, 2, + 152, 211, 167, 244, 6, 60, 247, 18, 173, 23, 92, 45, 60, 247, 18, 173, + 23, 86, 45, 60, 247, 18, 167, 23, 92, 45, 60, 247, 18, 167, 23, 86, 45, + 60, 247, 18, 92, 23, 167, 45, 60, 247, 18, 86, 23, 167, 45, 60, 247, 18, + 92, 23, 173, 45, 60, 247, 18, 86, 23, 173, 45, 218, 206, 51, 130, 230, + 46, 218, 206, 51, 130, 218, 167, 218, 206, 51, 120, 230, 46, 218, 206, + 51, 120, 218, 167, 218, 206, 51, 47, 209, 206, 218, 206, 51, 48, 209, + 206, 218, 206, 51, 47, 244, 8, 218, 206, 51, 48, 244, 8, 167, 59, 51, + 241, 98, 250, 129, 2, 194, 134, 120, 251, 244, 233, 69, 32, 219, 38, 249, + 140, 250, 146, 96, 2, 147, 206, 195, 39, 206, 195, 39, 24, 206, 195, 60, + 49, 248, 126, 60, 245, 157, 248, 126, 201, 60, 221, 140, 194, 60, 222, + 214, 60, 222, 214, 60, 227, 109, 209, 205, 211, 52, 248, 126, 60, 227, + 109, 244, 7, 211, 52, 248, 126, 60, 227, 109, 230, 41, 211, 52, 248, 126, + 60, 227, 109, 218, 162, 211, 52, 248, 126, 211, 102, 160, 60, 247, 233, + 249, 154, 160, 60, 247, 233, 147, 241, 125, 220, 203, 60, 247, 15, 218, + 97, 147, 241, 125, 220, 203, 60, 247, 15, 59, 241, 125, 220, 203, 247, + 15, 218, 97, 59, 241, 125, 220, 203, 247, 15, 49, 220, 178, 233, 49, 209, + 229, 53, 166, 6, 1, 251, 151, 166, 6, 1, 249, 89, 166, 6, 1, 209, 37, + 166, 6, 1, 240, 30, 166, 6, 1, 245, 46, 166, 6, 1, 206, 24, 166, 6, 1, + 205, 65, 166, 6, 1, 243, 191, 166, 6, 1, 205, 90, 166, 6, 1, 232, 207, + 166, 6, 1, 78, 232, 207, 166, 6, 1, 74, 166, 6, 1, 245, 66, 166, 6, 1, + 232, 33, 166, 6, 1, 229, 174, 166, 6, 1, 226, 37, 166, 6, 1, 225, 195, + 166, 6, 1, 222, 154, 166, 6, 1, 220, 198, 166, 6, 1, 218, 141, 166, 6, 1, + 214, 219, 166, 6, 1, 210, 131, 166, 6, 1, 209, 245, 166, 6, 1, 241, 101, + 166, 6, 1, 239, 31, 166, 6, 1, 222, 98, 166, 6, 1, 221, 174, 166, 6, 1, + 215, 119, 166, 6, 1, 210, 222, 166, 6, 1, 248, 20, 166, 6, 1, 216, 2, + 166, 6, 1, 206, 30, 166, 6, 1, 206, 32, 166, 6, 1, 206, 63, 166, 6, 1, + 214, 129, 155, 166, 6, 1, 205, 213, 166, 6, 1, 5, 205, 183, 166, 6, 1, 5, + 205, 184, 2, 212, 191, 166, 6, 1, 205, 247, 166, 6, 1, 232, 248, 5, 205, + 183, 166, 6, 1, 249, 231, 205, 183, 166, 6, 1, 232, 248, 249, 231, 205, + 183, 166, 6, 1, 241, 205, 166, 6, 1, 232, 205, 166, 6, 1, 215, 118, 166, + 6, 1, 211, 27, 62, 166, 6, 1, 230, 76, 226, 37, 166, 5, 1, 251, 151, 166, + 5, 1, 249, 89, 166, 5, 1, 209, 37, 166, 5, 1, 240, 30, 166, 5, 1, 245, + 46, 166, 5, 1, 206, 24, 166, 5, 1, 205, 65, 166, 5, 1, 243, 191, 166, 5, + 1, 205, 90, 166, 5, 1, 232, 207, 166, 5, 1, 78, 232, 207, 166, 5, 1, 74, + 166, 5, 1, 245, 66, 166, 5, 1, 232, 33, 166, 5, 1, 229, 174, 166, 5, 1, + 226, 37, 166, 5, 1, 225, 195, 166, 5, 1, 222, 154, 166, 5, 1, 220, 198, + 166, 5, 1, 218, 141, 166, 5, 1, 214, 219, 166, 5, 1, 210, 131, 166, 5, 1, + 209, 245, 166, 5, 1, 241, 101, 166, 5, 1, 239, 31, 166, 5, 1, 222, 98, + 166, 5, 1, 221, 174, 166, 5, 1, 215, 119, 166, 5, 1, 210, 222, 166, 5, 1, + 248, 20, 166, 5, 1, 216, 2, 166, 5, 1, 206, 30, 166, 5, 1, 206, 32, 166, + 5, 1, 206, 63, 166, 5, 1, 214, 129, 155, 166, 5, 1, 205, 213, 166, 5, 1, + 5, 205, 183, 166, 5, 1, 5, 205, 184, 2, 212, 191, 166, 5, 1, 205, 247, + 166, 5, 1, 232, 248, 5, 205, 183, 166, 5, 1, 249, 231, 205, 183, 166, 5, + 1, 232, 248, 249, 231, 205, 183, 166, 5, 1, 241, 205, 166, 5, 1, 232, + 205, 166, 5, 1, 215, 118, 166, 5, 1, 211, 27, 62, 166, 5, 1, 230, 76, + 226, 37, 7, 6, 1, 230, 159, 2, 50, 134, 7, 5, 1, 230, 159, 2, 50, 134, 7, + 6, 1, 230, 159, 2, 226, 247, 211, 180, 7, 6, 1, 222, 68, 2, 91, 7, 6, 1, + 219, 150, 2, 212, 191, 7, 5, 1, 32, 2, 91, 7, 5, 1, 213, 11, 2, 245, 163, + 91, 7, 6, 1, 239, 156, 2, 245, 211, 7, 5, 1, 239, 156, 2, 245, 211, 7, 6, + 1, 232, 77, 2, 245, 211, 7, 5, 1, 232, 77, 2, 245, 211, 7, 6, 1, 205, + 160, 2, 245, 211, 7, 5, 1, 205, 160, 2, 245, 211, 7, 6, 1, 252, 144, 7, + 6, 1, 229, 29, 2, 109, 7, 6, 1, 201, 62, 7, 6, 1, 201, 252, 144, 7, 5, 1, + 209, 149, 2, 48, 109, 7, 6, 1, 207, 130, 2, 109, 7, 5, 1, 207, 130, 2, + 109, 7, 5, 1, 209, 149, 2, 247, 27, 7, 6, 1, 160, 239, 155, 7, 5, 1, 160, + 239, 155, 7, 5, 1, 212, 189, 221, 78, 7, 5, 1, 174, 2, 224, 40, 7, 5, 1, + 201, 219, 150, 2, 212, 191, 7, 5, 1, 148, 2, 114, 218, 149, 233, 25, 7, + 1, 5, 6, 201, 75, 7, 213, 183, 5, 1, 232, 203, 65, 1, 6, 209, 148, 7, 6, + 1, 218, 1, 2, 213, 109, 212, 191, 7, 6, 1, 205, 160, 2, 213, 109, 212, + 191, 81, 6, 1, 252, 166, 81, 5, 1, 252, 166, 81, 6, 1, 208, 211, 81, 5, + 1, 208, 211, 81, 6, 1, 240, 215, 81, 5, 1, 240, 215, 81, 6, 1, 246, 113, + 81, 5, 1, 246, 113, 81, 6, 1, 243, 89, 81, 5, 1, 243, 89, 81, 6, 1, 214, + 167, 81, 5, 1, 214, 167, 81, 6, 1, 205, 100, 81, 5, 1, 205, 100, 81, 6, + 1, 239, 83, 81, 5, 1, 239, 83, 81, 6, 1, 212, 21, 81, 5, 1, 212, 21, 81, + 6, 1, 237, 187, 81, 5, 1, 237, 187, 81, 6, 1, 232, 19, 81, 5, 1, 232, 19, + 81, 6, 1, 230, 72, 81, 5, 1, 230, 72, 81, 6, 1, 226, 254, 81, 5, 1, 226, + 254, 81, 6, 1, 224, 230, 81, 5, 1, 224, 230, 81, 6, 1, 230, 252, 81, 5, + 1, 230, 252, 81, 6, 1, 76, 81, 5, 1, 76, 81, 6, 1, 221, 53, 81, 5, 1, + 221, 53, 81, 6, 1, 218, 124, 81, 5, 1, 218, 124, 81, 6, 1, 215, 51, 81, + 5, 1, 215, 51, 81, 6, 1, 212, 151, 81, 5, 1, 212, 151, 81, 6, 1, 210, 18, + 81, 5, 1, 210, 18, 81, 6, 1, 241, 250, 81, 5, 1, 241, 250, 81, 6, 1, 231, + 145, 81, 5, 1, 231, 145, 81, 6, 1, 220, 93, 81, 5, 1, 220, 93, 81, 6, 1, + 222, 146, 81, 5, 1, 222, 146, 81, 6, 1, 245, 161, 252, 172, 81, 5, 1, + 245, 161, 252, 172, 81, 6, 1, 44, 81, 252, 200, 81, 5, 1, 44, 81, 252, + 200, 81, 6, 1, 247, 43, 243, 89, 81, 5, 1, 247, 43, 243, 89, 81, 6, 1, + 245, 161, 232, 19, 81, 5, 1, 245, 161, 232, 19, 81, 6, 1, 245, 161, 224, + 230, 81, 5, 1, 245, 161, 224, 230, 81, 6, 1, 247, 43, 224, 230, 81, 5, 1, + 247, 43, 224, 230, 81, 6, 1, 44, 81, 222, 146, 81, 5, 1, 44, 81, 222, + 146, 81, 6, 1, 217, 154, 81, 5, 1, 217, 154, 81, 6, 1, 247, 57, 215, 206, + 81, 5, 1, 247, 57, 215, 206, 81, 6, 1, 44, 81, 215, 206, 81, 5, 1, 44, + 81, 215, 206, 81, 6, 1, 44, 81, 242, 215, 81, 5, 1, 44, 81, 242, 215, 81, + 6, 1, 252, 185, 231, 150, 81, 5, 1, 252, 185, 231, 150, 81, 6, 1, 245, + 161, 238, 122, 81, 5, 1, 245, 161, 238, 122, 81, 6, 1, 44, 81, 238, 122, + 81, 5, 1, 44, 81, 238, 122, 81, 6, 1, 44, 81, 155, 81, 5, 1, 44, 81, 155, + 81, 6, 1, 230, 158, 155, 81, 5, 1, 230, 158, 155, 81, 6, 1, 44, 81, 239, + 49, 81, 5, 1, 44, 81, 239, 49, 81, 6, 1, 44, 81, 239, 86, 81, 5, 1, 44, + 81, 239, 86, 81, 6, 1, 44, 81, 240, 210, 81, 5, 1, 44, 81, 240, 210, 81, + 6, 1, 44, 81, 245, 69, 81, 5, 1, 44, 81, 245, 69, 81, 6, 1, 44, 81, 215, + 173, 81, 5, 1, 44, 81, 215, 173, 81, 6, 1, 44, 223, 187, 215, 173, 81, 5, + 1, 44, 223, 187, 215, 173, 81, 6, 1, 44, 223, 187, 225, 25, 81, 5, 1, 44, + 223, 187, 225, 25, 81, 6, 1, 44, 223, 187, 223, 125, 81, 5, 1, 44, 223, + 187, 223, 125, 81, 6, 1, 44, 223, 187, 207, 66, 81, 5, 1, 44, 223, 187, + 207, 66, 81, 16, 232, 41, 81, 16, 226, 255, 218, 124, 81, 16, 221, 54, + 218, 124, 81, 16, 214, 17, 81, 16, 212, 152, 218, 124, 81, 16, 231, 146, + 218, 124, 81, 16, 215, 174, 215, 51, 81, 6, 1, 247, 43, 215, 206, 81, 5, + 1, 247, 43, 215, 206, 81, 6, 1, 247, 43, 240, 210, 81, 5, 1, 247, 43, + 240, 210, 81, 36, 224, 231, 52, 81, 36, 214, 123, 251, 217, 81, 36, 214, + 123, 230, 17, 81, 6, 1, 249, 178, 231, 150, 81, 5, 1, 249, 178, 231, 150, + 81, 44, 223, 187, 241, 82, 213, 251, 81, 44, 223, 187, 245, 104, 219, + 196, 83, 81, 44, 223, 187, 233, 48, 219, 196, 83, 81, 44, 223, 187, 209, + 24, 245, 79, 81, 241, 116, 119, 239, 121, 81, 241, 82, 213, 251, 81, 226, + 140, 245, 79, 108, 5, 1, 252, 122, 108, 5, 1, 250, 140, 108, 5, 1, 240, + 214, 108, 5, 1, 245, 31, 108, 5, 1, 243, 41, 108, 5, 1, 208, 197, 108, 5, + 1, 205, 88, 108, 5, 1, 212, 174, 108, 5, 1, 233, 68, 108, 5, 1, 232, 27, + 108, 5, 1, 230, 82, 108, 5, 1, 227, 221, 108, 5, 1, 225, 200, 108, 5, 1, + 222, 165, 108, 5, 1, 221, 231, 108, 5, 1, 205, 77, 108, 5, 1, 219, 95, + 108, 5, 1, 217, 151, 108, 5, 1, 212, 162, 108, 5, 1, 209, 234, 108, 5, 1, + 221, 85, 108, 5, 1, 231, 155, 108, 5, 1, 240, 90, 108, 5, 1, 220, 4, 108, + 5, 1, 215, 171, 108, 5, 1, 248, 45, 108, 5, 1, 248, 226, 108, 5, 1, 232, + 154, 108, 5, 1, 247, 240, 108, 5, 1, 248, 95, 108, 5, 1, 206, 179, 108, + 5, 1, 232, 167, 108, 5, 1, 239, 138, 108, 5, 1, 239, 71, 108, 5, 1, 239, + 6, 108, 5, 1, 207, 51, 108, 5, 1, 239, 95, 108, 5, 1, 238, 146, 108, 5, + 1, 205, 249, 108, 5, 1, 252, 237, 211, 200, 1, 190, 211, 200, 1, 206, + 105, 211, 200, 1, 206, 104, 211, 200, 1, 206, 94, 211, 200, 1, 206, 92, + 211, 200, 1, 250, 14, 253, 23, 206, 87, 211, 200, 1, 206, 87, 211, 200, + 1, 206, 102, 211, 200, 1, 206, 99, 211, 200, 1, 206, 101, 211, 200, 1, + 206, 100, 211, 200, 1, 206, 15, 211, 200, 1, 206, 96, 211, 200, 1, 206, + 85, 211, 200, 1, 210, 167, 206, 85, 211, 200, 1, 206, 82, 211, 200, 1, + 206, 90, 211, 200, 1, 250, 14, 253, 23, 206, 90, 211, 200, 1, 210, 167, + 206, 90, 211, 200, 1, 206, 89, 211, 200, 1, 206, 109, 211, 200, 1, 206, + 83, 211, 200, 1, 210, 167, 206, 83, 211, 200, 1, 206, 72, 211, 200, 1, + 210, 167, 206, 72, 211, 200, 1, 206, 11, 211, 200, 1, 206, 54, 211, 200, + 1, 252, 211, 206, 54, 211, 200, 1, 210, 167, 206, 54, 211, 200, 1, 206, + 81, 211, 200, 1, 206, 80, 211, 200, 1, 206, 77, 211, 200, 1, 210, 167, + 206, 91, 211, 200, 1, 210, 167, 206, 75, 211, 200, 1, 206, 73, 211, 200, + 1, 205, 213, 211, 200, 1, 206, 70, 211, 200, 1, 206, 69, 211, 200, 1, + 206, 93, 211, 200, 1, 210, 167, 206, 93, 211, 200, 1, 251, 155, 206, 93, + 211, 200, 1, 206, 68, 211, 200, 1, 206, 66, 211, 200, 1, 206, 67, 211, + 200, 1, 206, 65, 211, 200, 1, 206, 64, 211, 200, 1, 206, 103, 211, 200, + 1, 206, 62, 211, 200, 1, 206, 60, 211, 200, 1, 206, 59, 211, 200, 1, 206, + 58, 211, 200, 1, 206, 55, 211, 200, 1, 212, 143, 206, 55, 211, 200, 1, + 206, 53, 211, 200, 1, 206, 52, 211, 200, 1, 205, 247, 211, 200, 65, 1, + 230, 131, 83, 211, 200, 216, 40, 83, 211, 200, 107, 232, 117, 31, 4, 229, + 143, 31, 4, 226, 180, 31, 4, 218, 122, 31, 4, 214, 192, 31, 4, 215, 157, + 31, 4, 249, 183, 31, 4, 211, 129, 31, 4, 247, 173, 31, 4, 224, 65, 31, 4, + 223, 109, 31, 4, 240, 25, 222, 230, 31, 4, 205, 18, 31, 4, 245, 49, 31, + 4, 246, 23, 31, 4, 232, 121, 31, 4, 211, 252, 31, 4, 248, 31, 31, 4, 221, + 65, 31, 4, 220, 210, 31, 4, 240, 105, 31, 4, 240, 101, 31, 4, 240, 102, + 31, 4, 240, 103, 31, 4, 214, 96, 31, 4, 214, 51, 31, 4, 214, 64, 31, 4, + 214, 95, 31, 4, 214, 69, 31, 4, 214, 70, 31, 4, 214, 56, 31, 4, 248, 171, + 31, 4, 248, 150, 31, 4, 248, 152, 31, 4, 248, 170, 31, 4, 248, 168, 31, + 4, 248, 169, 31, 4, 248, 151, 31, 4, 204, 238, 31, 4, 204, 216, 31, 4, + 204, 229, 31, 4, 204, 237, 31, 4, 204, 232, 31, 4, 204, 233, 31, 4, 204, + 221, 31, 4, 248, 166, 31, 4, 248, 153, 31, 4, 248, 155, 31, 4, 248, 165, + 31, 4, 248, 163, 31, 4, 248, 164, 31, 4, 248, 154, 31, 4, 219, 162, 31, + 4, 219, 152, 31, 4, 219, 158, 31, 4, 219, 161, 31, 4, 219, 159, 31, 4, + 219, 160, 31, 4, 219, 157, 31, 4, 230, 169, 31, 4, 230, 161, 31, 4, 230, + 164, 31, 4, 230, 168, 31, 4, 230, 165, 31, 4, 230, 166, 31, 4, 230, 162, + 31, 4, 206, 139, 31, 4, 206, 126, 31, 4, 206, 134, 31, 4, 206, 138, 31, + 4, 206, 136, 31, 4, 206, 137, 31, 4, 206, 133, 31, 4, 239, 167, 31, 4, + 239, 157, 31, 4, 239, 160, 31, 4, 239, 166, 31, 4, 239, 162, 31, 4, 239, + 163, 31, 4, 239, 159, 36, 34, 1, 250, 61, 36, 34, 1, 209, 39, 36, 34, 1, + 240, 85, 36, 34, 1, 246, 9, 36, 34, 1, 205, 72, 36, 34, 1, 205, 93, 36, + 34, 1, 172, 36, 34, 1, 243, 68, 36, 34, 1, 243, 50, 36, 34, 1, 243, 41, + 36, 34, 1, 76, 36, 34, 1, 221, 174, 36, 34, 1, 242, 235, 36, 34, 1, 242, + 225, 36, 34, 1, 212, 131, 36, 34, 1, 155, 36, 34, 1, 210, 237, 36, 34, 1, + 248, 82, 36, 34, 1, 216, 2, 36, 34, 1, 215, 217, 36, 34, 1, 241, 205, 36, + 34, 1, 242, 221, 36, 34, 1, 62, 36, 34, 1, 233, 129, 36, 34, 1, 245, 67, + 36, 34, 1, 226, 158, 209, 249, 36, 34, 1, 206, 65, 36, 34, 1, 205, 213, + 36, 34, 1, 232, 247, 62, 36, 34, 1, 229, 180, 205, 183, 36, 34, 1, 249, + 231, 205, 183, 36, 34, 1, 232, 247, 249, 231, 205, 183, 48, 252, 109, + 213, 178, 227, 187, 48, 252, 109, 244, 21, 213, 178, 227, 187, 47, 213, + 178, 145, 48, 213, 178, 145, 47, 244, 21, 213, 178, 145, 48, 244, 21, + 213, 178, 145, 219, 81, 233, 12, 227, 187, 219, 81, 244, 21, 233, 12, + 227, 187, 244, 21, 211, 67, 227, 187, 47, 211, 67, 145, 48, 211, 67, 145, + 219, 81, 214, 107, 47, 219, 81, 222, 167, 145, 48, 219, 81, 222, 167, + 145, 243, 105, 247, 89, 221, 227, 241, 138, 221, 227, 218, 224, 241, 138, + 221, 227, 237, 236, 244, 21, 222, 225, 173, 252, 118, 167, 252, 118, 244, + 21, 218, 162, 252, 108, 50, 222, 222, 237, 239, 233, 2, 233, 10, 222, 19, + 249, 130, 237, 240, 2, 245, 166, 211, 181, 2, 218, 149, 52, 47, 114, 221, + 219, 145, 48, 114, 221, 219, 145, 211, 181, 2, 67, 52, 211, 181, 2, 67, + 55, 47, 79, 250, 129, 2, 219, 190, 48, 79, 250, 129, 2, 219, 190, 211, + 102, 47, 160, 145, 211, 102, 48, 160, 145, 249, 154, 47, 160, 145, 249, + 154, 48, 160, 145, 47, 215, 73, 106, 145, 48, 215, 73, 106, 145, 47, 50, + 221, 216, 48, 50, 221, 216, 118, 177, 131, 119, 67, 220, 71, 119, 67, + 131, 118, 177, 220, 71, 98, 241, 125, 67, 220, 71, 241, 204, 67, 83, 218, + 224, 219, 196, 83, 79, 211, 180, 218, 149, 220, 204, 206, 232, 216, 40, + 226, 247, 245, 23, 201, 247, 155, 219, 81, 245, 23, 219, 81, 247, 155, + 201, 216, 52, 246, 129, 2, 47, 239, 207, 246, 129, 2, 48, 239, 207, 201, + 246, 128, 211, 102, 160, 217, 77, 53, 210, 109, 246, 78, 211, 237, 246, + 78, 214, 8, 241, 82, 213, 251, 79, 215, 10, 245, 21, 207, 14, 79, 229, + 205, 248, 211, 50, 237, 239, 218, 224, 247, 155, 50, 229, 93, 219, 180, + 83, 10, 37, 218, 251, 10, 37, 247, 202, 10, 37, 217, 80, 102, 10, 37, + 217, 80, 105, 10, 37, 217, 80, 142, 10, 37, 221, 114, 10, 37, 249, 140, + 10, 37, 212, 206, 10, 37, 231, 59, 102, 10, 37, 231, 59, 105, 10, 37, + 245, 76, 10, 37, 217, 84, 10, 37, 5, 102, 10, 37, 5, 105, 10, 37, 230, + 101, 102, 10, 37, 230, 101, 105, 10, 37, 230, 101, 142, 10, 37, 230, 101, + 139, 10, 37, 214, 204, 10, 37, 211, 239, 10, 37, 214, 202, 102, 10, 37, + 214, 202, 105, 10, 37, 239, 61, 102, 10, 37, 239, 61, 105, 10, 37, 239, + 107, 10, 37, 219, 71, 10, 37, 248, 28, 10, 37, 213, 154, 10, 37, 226, + 144, 10, 37, 246, 7, 10, 37, 226, 136, 10, 37, 247, 220, 10, 37, 207, 70, + 102, 10, 37, 207, 70, 105, 10, 37, 241, 219, 10, 37, 221, 186, 102, 10, + 37, 221, 186, 105, 10, 37, 215, 46, 160, 211, 62, 210, 248, 10, 37, 247, + 75, 10, 37, 245, 40, 10, 37, 232, 195, 10, 37, 249, 177, 73, 247, 186, + 10, 37, 242, 150, 10, 37, 214, 125, 102, 10, 37, 214, 125, 105, 10, 37, + 250, 142, 10, 37, 215, 53, 10, 37, 249, 31, 215, 53, 10, 37, 225, 92, + 102, 10, 37, 225, 92, 105, 10, 37, 225, 92, 142, 10, 37, 225, 92, 139, + 10, 37, 227, 70, 10, 37, 215, 208, 10, 37, 219, 77, 10, 37, 242, 174, 10, + 37, 222, 179, 10, 37, 249, 109, 102, 10, 37, 249, 109, 105, 10, 37, 227, + 114, 10, 37, 226, 139, 10, 37, 239, 240, 102, 10, 37, 239, 240, 105, 10, + 37, 239, 240, 142, 10, 37, 211, 198, 10, 37, 247, 185, 10, 37, 207, 36, + 102, 10, 37, 207, 36, 105, 10, 37, 249, 31, 217, 74, 10, 37, 215, 46, + 238, 69, 10, 37, 238, 69, 10, 37, 249, 31, 214, 136, 10, 37, 249, 31, + 215, 203, 10, 37, 241, 148, 10, 37, 249, 31, 248, 189, 10, 37, 215, 46, + 207, 87, 10, 37, 207, 88, 102, 10, 37, 207, 88, 105, 10, 37, 247, 223, + 10, 37, 249, 31, 240, 11, 10, 37, 152, 102, 10, 37, 152, 105, 10, 37, + 249, 31, 229, 125, 10, 37, 249, 31, 240, 196, 10, 37, 226, 132, 102, 10, + 37, 226, 132, 105, 10, 37, 219, 83, 10, 37, 249, 186, 10, 37, 249, 31, + 212, 168, 230, 52, 10, 37, 249, 31, 230, 53, 10, 37, 249, 31, 207, 9, 10, + 37, 249, 31, 241, 166, 10, 37, 243, 114, 102, 10, 37, 243, 114, 105, 10, + 37, 243, 114, 142, 10, 37, 249, 31, 243, 113, 10, 37, 239, 68, 10, 37, + 249, 31, 238, 65, 10, 37, 249, 173, 10, 37, 240, 69, 10, 37, 249, 31, + 241, 213, 10, 37, 249, 31, 249, 218, 10, 37, 249, 31, 217, 165, 10, 37, + 215, 46, 207, 28, 10, 37, 215, 46, 206, 44, 10, 37, 249, 31, 241, 99, 10, + 37, 232, 202, 242, 178, 10, 37, 249, 31, 242, 178, 10, 37, 232, 202, 211, + 103, 10, 37, 249, 31, 211, 103, 10, 37, 232, 202, 243, 255, 10, 37, 249, + 31, 243, 255, 10, 37, 210, 141, 10, 37, 232, 202, 210, 141, 10, 37, 249, + 31, 210, 141, 68, 37, 102, 68, 37, 229, 205, 68, 37, 245, 23, 68, 37, + 214, 235, 68, 37, 217, 79, 68, 37, 109, 68, 37, 105, 68, 37, 229, 231, + 68, 37, 227, 221, 68, 37, 230, 31, 68, 37, 243, 18, 68, 37, 193, 68, 37, + 130, 249, 140, 68, 37, 247, 77, 68, 37, 237, 181, 68, 37, 212, 206, 68, + 37, 222, 142, 249, 140, 68, 37, 231, 58, 68, 37, 220, 161, 68, 37, 206, + 223, 68, 37, 214, 118, 68, 37, 48, 222, 142, 249, 140, 68, 37, 239, 7, + 243, 36, 68, 37, 212, 98, 68, 37, 245, 76, 68, 37, 217, 84, 68, 37, 247, + 202, 68, 37, 220, 117, 68, 37, 252, 219, 68, 37, 226, 123, 68, 37, 243, + 36, 68, 37, 243, 120, 68, 37, 217, 105, 68, 37, 240, 19, 68, 37, 240, 20, + 214, 217, 68, 37, 242, 177, 68, 37, 249, 230, 68, 37, 206, 244, 68, 37, + 248, 49, 68, 37, 218, 106, 68, 37, 233, 64, 68, 37, 214, 215, 68, 37, + 230, 100, 68, 37, 247, 87, 68, 37, 214, 111, 68, 37, 226, 128, 68, 37, + 218, 138, 68, 37, 206, 229, 68, 37, 222, 159, 68, 37, 210, 148, 68, 37, + 243, 239, 68, 37, 215, 144, 211, 239, 68, 37, 244, 21, 247, 202, 68, 37, + 152, 213, 230, 68, 37, 118, 239, 102, 68, 37, 215, 150, 68, 37, 249, 146, + 68, 37, 214, 201, 68, 37, 249, 113, 68, 37, 214, 7, 68, 37, 239, 60, 68, + 37, 239, 122, 68, 37, 245, 26, 68, 37, 239, 107, 68, 37, 249, 130, 68, + 37, 219, 71, 68, 37, 217, 92, 68, 37, 245, 106, 68, 37, 251, 160, 68, 37, + 214, 107, 68, 37, 224, 42, 68, 37, 213, 154, 68, 37, 217, 116, 68, 37, + 226, 144, 68, 37, 211, 61, 68, 37, 230, 127, 68, 37, 213, 251, 68, 37, + 246, 7, 68, 37, 207, 50, 68, 37, 245, 52, 224, 42, 68, 37, 247, 151, 68, + 37, 241, 75, 68, 37, 247, 214, 68, 37, 214, 12, 68, 37, 207, 69, 68, 37, + 241, 219, 68, 37, 247, 210, 68, 37, 242, 35, 68, 37, 50, 206, 195, 68, + 37, 160, 211, 62, 210, 248, 68, 37, 214, 228, 68, 37, 242, 45, 68, 37, + 247, 75, 68, 37, 245, 40, 68, 37, 220, 114, 68, 37, 232, 195, 68, 37, + 227, 92, 68, 37, 211, 179, 68, 37, 213, 104, 68, 37, 229, 225, 68, 37, + 209, 175, 68, 37, 241, 249, 68, 37, 249, 177, 73, 247, 186, 68, 37, 215, + 76, 68, 37, 244, 21, 212, 92, 68, 37, 207, 23, 68, 37, 214, 243, 68, 37, + 245, 94, 68, 37, 242, 150, 68, 37, 214, 139, 68, 37, 45, 68, 37, 213, + 253, 68, 37, 214, 124, 68, 37, 211, 82, 68, 37, 239, 247, 68, 37, 248, + 176, 68, 37, 214, 30, 68, 37, 250, 142, 68, 37, 218, 203, 68, 37, 215, + 53, 68, 37, 232, 188, 68, 37, 225, 91, 68, 37, 215, 208, 68, 37, 242, 23, + 68, 37, 222, 179, 68, 37, 252, 117, 68, 37, 220, 225, 68, 37, 243, 124, + 68, 37, 249, 108, 68, 37, 227, 114, 68, 37, 226, 203, 68, 37, 216, 58, + 68, 37, 251, 247, 68, 37, 226, 139, 68, 37, 211, 107, 68, 37, 222, 130, + 68, 37, 249, 180, 68, 37, 213, 249, 68, 37, 247, 161, 68, 37, 239, 239, + 68, 37, 211, 198, 68, 37, 233, 28, 68, 37, 249, 191, 68, 37, 207, 88, + 243, 36, 68, 37, 247, 185, 68, 37, 207, 35, 68, 37, 217, 74, 68, 37, 238, + 69, 68, 37, 214, 136, 68, 37, 209, 63, 68, 37, 250, 57, 68, 37, 221, 17, + 68, 37, 250, 165, 68, 37, 215, 203, 68, 37, 219, 31, 68, 37, 218, 35, 68, + 37, 241, 148, 68, 37, 249, 179, 68, 37, 248, 189, 68, 37, 249, 207, 68, + 37, 226, 141, 68, 37, 207, 87, 68, 37, 247, 223, 68, 37, 207, 5, 68, 37, + 245, 87, 68, 37, 208, 198, 68, 37, 240, 11, 68, 37, 229, 125, 68, 37, + 240, 196, 68, 37, 226, 131, 68, 37, 214, 234, 68, 37, 215, 144, 212, 190, + 249, 218, 68, 37, 219, 83, 68, 37, 249, 186, 68, 37, 206, 218, 68, 37, + 242, 67, 68, 37, 230, 52, 68, 37, 212, 168, 230, 52, 68, 37, 230, 48, 68, + 37, 214, 164, 68, 37, 230, 53, 68, 37, 207, 9, 68, 37, 241, 166, 68, 37, + 243, 113, 68, 37, 239, 68, 68, 37, 241, 114, 68, 37, 238, 65, 68, 37, + 249, 173, 68, 37, 212, 177, 68, 37, 239, 129, 68, 37, 241, 242, 68, 37, + 217, 193, 207, 5, 68, 37, 248, 178, 68, 37, 240, 69, 68, 37, 241, 213, + 68, 37, 249, 218, 68, 37, 217, 165, 68, 37, 245, 248, 68, 37, 207, 28, + 68, 37, 239, 42, 68, 37, 206, 44, 68, 37, 226, 214, 68, 37, 249, 202, 68, + 37, 243, 46, 68, 37, 241, 99, 68, 37, 211, 34, 68, 37, 243, 241, 68, 37, + 219, 65, 68, 37, 224, 44, 68, 37, 242, 178, 68, 37, 211, 103, 68, 37, + 243, 255, 68, 37, 210, 141, 68, 37, 241, 168, 128, 245, 209, 157, 47, + 211, 130, 218, 167, 128, 245, 209, 157, 84, 211, 130, 55, 128, 245, 209, + 157, 47, 211, 130, 226, 247, 23, 218, 167, 128, 245, 209, 157, 84, 211, + 130, 226, 247, 23, 55, 128, 245, 209, 157, 241, 82, 213, 126, 128, 245, + 209, 157, 213, 127, 241, 98, 52, 128, 245, 209, 157, 213, 127, 241, 98, + 55, 128, 245, 209, 157, 213, 127, 241, 98, 230, 46, 128, 245, 209, 157, + 213, 127, 241, 98, 209, 203, 230, 46, 128, 245, 209, 157, 213, 127, 241, + 98, 209, 203, 218, 167, 128, 245, 209, 157, 213, 127, 241, 98, 229, 92, + 230, 46, 128, 245, 209, 157, 222, 85, 128, 214, 153, 128, 247, 155, 128, + 241, 82, 213, 251, 245, 84, 83, 232, 189, 233, 47, 214, 29, 93, 128, 232, + 218, 83, 128, 247, 188, 83, 128, 43, 205, 85, 47, 252, 109, 145, 48, 252, + 109, 145, 47, 50, 252, 109, 145, 48, 50, 252, 109, 145, 47, 247, 92, 145, + 48, 247, 92, 145, 47, 59, 247, 92, 145, 48, 59, 247, 92, 145, 47, 60, + 230, 16, 145, 48, 60, 230, 16, 145, 220, 174, 83, 240, 138, 83, 47, 211, + 93, 215, 204, 145, 48, 211, 93, 215, 204, 145, 47, 59, 230, 16, 145, 48, + 59, 230, 16, 145, 47, 59, 211, 93, 215, 204, 145, 48, 59, 211, 93, 215, + 204, 145, 47, 59, 49, 145, 48, 59, 49, 145, 207, 65, 246, 78, 218, 224, + 50, 220, 128, 219, 180, 83, 50, 220, 128, 219, 180, 83, 114, 50, 220, + 128, 219, 180, 83, 220, 174, 141, 242, 67, 239, 100, 223, 177, 102, 239, + 100, 223, 177, 105, 239, 100, 223, 177, 142, 239, 100, 223, 177, 139, + 239, 100, 223, 177, 168, 239, 100, 223, 177, 184, 239, 100, 223, 177, + 195, 239, 100, 223, 177, 193, 239, 100, 223, 177, 200, 128, 229, 254, + 135, 83, 128, 218, 142, 135, 83, 128, 245, 217, 135, 83, 128, 243, 17, + 135, 83, 25, 215, 41, 67, 135, 83, 25, 50, 67, 135, 83, 207, 61, 246, 78, + 79, 232, 26, 218, 252, 83, 79, 232, 26, 218, 252, 2, 208, 170, 214, 165, + 83, 79, 232, 26, 218, 252, 141, 209, 203, 239, 121, 79, 232, 26, 218, + 252, 2, 208, 170, 214, 165, 141, 209, 203, 239, 121, 79, 232, 26, 218, + 252, 141, 229, 92, 239, 121, 39, 220, 174, 83, 128, 212, 110, 229, 206, + 242, 20, 216, 40, 93, 239, 100, 223, 177, 212, 98, 239, 100, 223, 177, + 210, 123, 239, 100, 223, 177, 212, 3, 79, 128, 232, 218, 83, 227, 171, + 83, 221, 211, 252, 140, 83, 128, 54, 233, 49, 128, 160, 241, 235, 214, + 153, 161, 1, 5, 62, 161, 1, 62, 161, 1, 5, 74, 161, 1, 74, 161, 1, 5, 71, + 161, 1, 71, 161, 1, 5, 75, 161, 1, 75, 161, 1, 5, 76, 161, 1, 76, 161, 1, + 172, 161, 1, 240, 244, 161, 1, 231, 123, 161, 1, 240, 61, 161, 1, 230, + 236, 161, 1, 239, 213, 161, 1, 231, 224, 161, 1, 240, 170, 161, 1, 231, + 53, 161, 1, 240, 19, 161, 1, 217, 199, 161, 1, 205, 116, 161, 1, 215, 80, + 161, 1, 205, 40, 161, 1, 213, 203, 161, 1, 205, 9, 161, 1, 217, 86, 161, + 1, 205, 93, 161, 1, 214, 193, 161, 1, 205, 19, 161, 1, 212, 219, 161, 1, + 246, 145, 161, 1, 211, 211, 161, 1, 245, 168, 161, 1, 5, 210, 170, 161, + 1, 210, 170, 161, 1, 243, 237, 161, 1, 212, 131, 161, 1, 246, 9, 161, 1, + 124, 161, 1, 245, 51, 161, 1, 199, 161, 1, 224, 230, 161, 1, 223, 217, + 161, 1, 225, 110, 161, 1, 224, 67, 161, 1, 155, 161, 1, 250, 183, 161, 1, + 179, 161, 1, 239, 11, 161, 1, 249, 244, 161, 1, 221, 53, 161, 1, 238, 42, + 161, 1, 249, 101, 161, 1, 220, 82, 161, 1, 239, 71, 161, 1, 250, 61, 161, + 1, 221, 174, 161, 1, 238, 149, 161, 1, 249, 184, 161, 1, 220, 211, 161, + 1, 185, 161, 1, 226, 254, 161, 1, 226, 114, 161, 1, 227, 119, 161, 1, + 226, 181, 161, 1, 5, 190, 161, 1, 190, 161, 1, 5, 205, 213, 161, 1, 205, + 213, 161, 1, 5, 205, 247, 161, 1, 205, 247, 161, 1, 219, 113, 161, 1, + 218, 208, 161, 1, 218, 50, 161, 1, 219, 51, 161, 1, 218, 124, 161, 1, 5, + 207, 96, 161, 1, 207, 96, 161, 1, 207, 20, 161, 1, 207, 51, 161, 1, 206, + 250, 161, 1, 226, 33, 161, 1, 207, 148, 161, 1, 5, 172, 161, 1, 5, 231, + 224, 36, 231, 248, 208, 170, 214, 165, 83, 36, 231, 248, 216, 57, 214, + 165, 83, 231, 248, 208, 170, 214, 165, 83, 231, 248, 216, 57, 214, 165, + 83, 161, 232, 218, 83, 161, 208, 170, 232, 218, 83, 161, 245, 128, 205, + 228, 231, 248, 50, 237, 239, 64, 1, 5, 62, 64, 1, 62, 64, 1, 5, 74, 64, + 1, 74, 64, 1, 5, 71, 64, 1, 71, 64, 1, 5, 75, 64, 1, 75, 64, 1, 5, 76, + 64, 1, 76, 64, 1, 172, 64, 1, 240, 244, 64, 1, 231, 123, 64, 1, 240, 61, + 64, 1, 230, 236, 64, 1, 239, 213, 64, 1, 231, 224, 64, 1, 240, 170, 64, + 1, 231, 53, 64, 1, 240, 19, 64, 1, 217, 199, 64, 1, 205, 116, 64, 1, 215, + 80, 64, 1, 205, 40, 64, 1, 213, 203, 64, 1, 205, 9, 64, 1, 217, 86, 64, + 1, 205, 93, 64, 1, 214, 193, 64, 1, 205, 19, 64, 1, 212, 219, 64, 1, 246, + 145, 64, 1, 211, 211, 64, 1, 245, 168, 64, 1, 5, 210, 170, 64, 1, 210, + 170, 64, 1, 243, 237, 64, 1, 212, 131, 64, 1, 246, 9, 64, 1, 124, 64, 1, + 245, 51, 64, 1, 199, 64, 1, 224, 230, 64, 1, 223, 217, 64, 1, 225, 110, + 64, 1, 224, 67, 64, 1, 155, 64, 1, 250, 183, 64, 1, 179, 64, 1, 239, 11, + 64, 1, 249, 244, 64, 1, 221, 53, 64, 1, 238, 42, 64, 1, 249, 101, 64, 1, + 220, 82, 64, 1, 239, 71, 64, 1, 250, 61, 64, 1, 221, 174, 64, 1, 238, + 149, 64, 1, 249, 184, 64, 1, 220, 211, 64, 1, 185, 64, 1, 226, 254, 64, + 1, 226, 114, 64, 1, 227, 119, 64, 1, 226, 181, 64, 1, 5, 190, 64, 1, 190, + 64, 1, 5, 205, 213, 64, 1, 205, 213, 64, 1, 5, 205, 247, 64, 1, 205, 247, + 64, 1, 219, 113, 64, 1, 218, 208, 64, 1, 218, 50, 64, 1, 219, 51, 64, 1, + 218, 124, 64, 1, 5, 207, 96, 64, 1, 207, 96, 64, 1, 207, 20, 64, 1, 207, + 51, 64, 1, 206, 250, 64, 1, 226, 33, 64, 1, 207, 148, 64, 1, 5, 172, 64, + 1, 5, 231, 224, 64, 1, 209, 70, 64, 1, 208, 214, 64, 1, 209, 39, 64, 1, + 208, 173, 64, 226, 247, 245, 23, 231, 248, 220, 106, 214, 165, 83, 64, + 232, 218, 83, 64, 208, 170, 232, 218, 83, 64, 245, 128, 231, 20, 249, + 163, 1, 251, 150, 249, 163, 1, 222, 67, 249, 163, 1, 229, 28, 249, 163, + 1, 242, 139, 249, 163, 1, 246, 240, 249, 163, 1, 213, 10, 249, 163, 1, + 226, 33, 249, 163, 1, 149, 249, 163, 1, 241, 55, 249, 163, 1, 232, 76, + 249, 163, 1, 239, 155, 249, 163, 1, 232, 203, 249, 163, 1, 220, 27, 249, + 163, 1, 206, 195, 249, 163, 1, 205, 82, 249, 163, 1, 248, 111, 249, 163, + 1, 216, 4, 249, 163, 1, 137, 249, 163, 1, 205, 159, 249, 163, 1, 249, 34, + 249, 163, 1, 182, 249, 163, 1, 62, 249, 163, 1, 76, 249, 163, 1, 75, 249, + 163, 1, 243, 92, 249, 163, 1, 252, 205, 249, 163, 1, 243, 90, 249, 163, + 1, 251, 184, 249, 163, 1, 222, 97, 249, 163, 1, 252, 122, 249, 163, 1, + 243, 41, 249, 163, 1, 252, 114, 249, 163, 1, 243, 28, 249, 163, 1, 242, + 235, 249, 163, 1, 74, 249, 163, 1, 71, 249, 163, 1, 232, 216, 249, 163, + 1, 209, 148, 249, 163, 1, 225, 79, 249, 163, 1, 240, 23, 249, 163, 1, + 233, 103, 25, 1, 231, 84, 25, 1, 214, 88, 25, 1, 231, 77, 25, 1, 224, + 223, 25, 1, 224, 221, 25, 1, 224, 220, 25, 1, 211, 193, 25, 1, 214, 77, + 25, 1, 218, 198, 25, 1, 218, 193, 25, 1, 218, 190, 25, 1, 218, 183, 25, + 1, 218, 178, 25, 1, 218, 173, 25, 1, 218, 184, 25, 1, 218, 196, 25, 1, + 226, 240, 25, 1, 221, 39, 25, 1, 214, 85, 25, 1, 221, 28, 25, 1, 215, 33, + 25, 1, 214, 82, 25, 1, 233, 125, 25, 1, 247, 246, 25, 1, 214, 92, 25, 1, + 248, 54, 25, 1, 231, 143, 25, 1, 212, 15, 25, 1, 221, 76, 25, 1, 239, 3, + 25, 1, 62, 25, 1, 252, 248, 25, 1, 190, 25, 1, 206, 98, 25, 1, 243, 6, + 25, 1, 75, 25, 1, 206, 39, 25, 1, 206, 52, 25, 1, 76, 25, 1, 207, 96, 25, + 1, 207, 92, 25, 1, 222, 206, 25, 1, 205, 247, 25, 1, 71, 25, 1, 207, 38, + 25, 1, 207, 51, 25, 1, 207, 20, 25, 1, 205, 213, 25, 1, 242, 192, 25, 1, + 206, 11, 25, 1, 74, 25, 241, 232, 25, 1, 214, 86, 25, 1, 224, 213, 25, 1, + 224, 215, 25, 1, 224, 218, 25, 1, 218, 191, 25, 1, 218, 172, 25, 1, 218, + 180, 25, 1, 218, 185, 25, 1, 218, 170, 25, 1, 226, 233, 25, 1, 226, 230, + 25, 1, 226, 234, 25, 1, 232, 13, 25, 1, 221, 34, 25, 1, 221, 20, 25, 1, + 221, 26, 25, 1, 221, 23, 25, 1, 221, 37, 25, 1, 221, 21, 25, 1, 232, 11, + 25, 1, 232, 9, 25, 1, 215, 26, 25, 1, 215, 24, 25, 1, 215, 16, 25, 1, + 215, 21, 25, 1, 215, 31, 25, 1, 221, 247, 25, 1, 214, 89, 25, 1, 206, 29, + 25, 1, 206, 25, 25, 1, 206, 26, 25, 1, 232, 12, 25, 1, 214, 90, 25, 1, + 206, 35, 25, 1, 205, 241, 25, 1, 205, 240, 25, 1, 205, 243, 25, 1, 205, + 204, 25, 1, 205, 205, 25, 1, 205, 208, 25, 1, 252, 30, 25, 1, 252, 24, + 128, 252, 98, 229, 194, 83, 128, 252, 98, 218, 225, 83, 128, 252, 98, + 119, 83, 128, 252, 98, 118, 83, 128, 252, 98, 129, 83, 128, 252, 98, 241, + 125, 83, 128, 252, 98, 211, 102, 83, 128, 252, 98, 226, 247, 83, 128, + 252, 98, 249, 154, 83, 128, 252, 98, 241, 215, 83, 128, 252, 98, 217, 80, + 83, 128, 252, 98, 212, 11, 83, 128, 252, 98, 241, 118, 83, 128, 252, 98, + 239, 57, 83, 128, 252, 98, 243, 121, 83, 128, 252, 98, 227, 222, 83, 249, + 163, 1, 249, 101, 249, 163, 1, 205, 40, 249, 163, 1, 232, 162, 249, 163, + 1, 239, 213, 249, 163, 1, 243, 104, 249, 163, 1, 243, 25, 249, 163, 1, + 222, 152, 249, 163, 1, 222, 156, 249, 163, 1, 232, 243, 249, 163, 1, 252, + 100, 249, 163, 1, 233, 35, 249, 163, 1, 209, 211, 249, 163, 1, 233, 85, + 249, 163, 1, 225, 57, 249, 163, 1, 252, 199, 249, 163, 1, 251, 179, 249, + 163, 1, 252, 136, 249, 163, 1, 222, 173, 249, 163, 1, 222, 158, 249, 163, + 1, 233, 32, 249, 163, 42, 1, 222, 67, 249, 163, 42, 1, 213, 10, 249, 163, + 42, 1, 232, 76, 249, 163, 42, 1, 239, 155, 249, 163, 1, 240, 100, 249, + 163, 1, 229, 249, 249, 163, 1, 204, 245, 10, 213, 225, 213, 10, 10, 213, + 225, 207, 31, 10, 213, 225, 206, 170, 10, 213, 225, 249, 47, 10, 213, + 225, 213, 113, 10, 213, 225, 237, 229, 10, 213, 225, 237, 233, 10, 213, + 225, 238, 51, 10, 213, 225, 237, 230, 10, 213, 225, 213, 13, 10, 213, + 225, 237, 232, 10, 213, 225, 237, 228, 10, 213, 225, 238, 49, 10, 213, + 225, 237, 231, 10, 213, 225, 237, 227, 10, 213, 225, 226, 33, 10, 213, + 225, 239, 155, 10, 213, 225, 182, 10, 213, 225, 222, 67, 10, 213, 225, + 214, 156, 10, 213, 225, 246, 240, 10, 213, 225, 237, 234, 10, 213, 225, + 239, 21, 10, 213, 225, 213, 22, 10, 213, 225, 213, 92, 10, 213, 225, 214, + 40, 10, 213, 225, 216, 10, 10, 213, 225, 221, 178, 10, 213, 225, 220, 29, + 10, 213, 225, 211, 131, 10, 213, 225, 213, 12, 10, 213, 225, 213, 103, + 10, 213, 225, 237, 241, 10, 213, 225, 237, 226, 10, 213, 225, 221, 95, + 10, 213, 225, 220, 27, 64, 1, 5, 230, 236, 64, 1, 5, 215, 80, 64, 1, 5, + 213, 203, 64, 1, 5, 124, 64, 1, 5, 223, 217, 64, 1, 5, 155, 64, 1, 5, + 239, 11, 64, 1, 5, 238, 42, 64, 1, 5, 239, 71, 64, 1, 5, 238, 149, 64, 1, + 5, 226, 114, 64, 1, 5, 219, 113, 64, 1, 5, 218, 208, 64, 1, 5, 218, 50, + 64, 1, 5, 219, 51, 64, 1, 5, 218, 124, 97, 25, 231, 84, 97, 25, 224, 223, + 97, 25, 211, 193, 97, 25, 218, 198, 97, 25, 226, 240, 97, 25, 221, 39, + 97, 25, 215, 33, 97, 25, 233, 125, 97, 25, 247, 246, 97, 25, 248, 54, 97, + 25, 231, 143, 97, 25, 212, 15, 97, 25, 221, 76, 97, 25, 239, 3, 97, 25, + 231, 85, 62, 97, 25, 224, 224, 62, 97, 25, 211, 194, 62, 97, 25, 218, + 199, 62, 97, 25, 226, 241, 62, 97, 25, 221, 40, 62, 97, 25, 215, 34, 62, + 97, 25, 233, 126, 62, 97, 25, 247, 247, 62, 97, 25, 248, 55, 62, 97, 25, + 231, 144, 62, 97, 25, 212, 16, 62, 97, 25, 221, 77, 62, 97, 25, 239, 4, + 62, 97, 25, 247, 247, 71, 97, 231, 24, 157, 222, 188, 97, 231, 24, 157, + 148, 238, 42, 97, 175, 102, 97, 175, 105, 97, 175, 142, 97, 175, 139, 97, + 175, 168, 97, 175, 184, 97, 175, 195, 97, 175, 193, 97, 175, 200, 97, + 175, 212, 98, 97, 175, 226, 144, 97, 175, 241, 219, 97, 175, 207, 69, 97, + 175, 206, 237, 97, 175, 227, 63, 97, 175, 243, 120, 97, 175, 213, 154, + 97, 175, 213, 254, 97, 175, 239, 78, 97, 175, 214, 189, 97, 175, 225, + 210, 97, 175, 214, 138, 97, 175, 241, 229, 97, 175, 247, 133, 97, 175, + 230, 130, 97, 175, 218, 246, 97, 175, 248, 236, 97, 175, 213, 207, 97, + 175, 213, 136, 97, 175, 243, 16, 97, 175, 218, 238, 97, 175, 252, 152, + 97, 175, 242, 1, 97, 175, 218, 236, 97, 175, 216, 58, 97, 175, 219, 50, + 39, 175, 219, 195, 39, 175, 231, 108, 39, 175, 217, 103, 39, 175, 231, + 20, 39, 43, 212, 99, 222, 166, 60, 214, 107, 39, 43, 210, 124, 222, 166, + 60, 214, 107, 39, 43, 212, 4, 222, 166, 60, 214, 107, 39, 43, 241, 131, + 222, 166, 60, 214, 107, 39, 43, 241, 244, 222, 166, 60, 214, 107, 39, 43, + 214, 253, 222, 166, 60, 214, 107, 39, 43, 216, 18, 222, 166, 60, 214, + 107, 39, 43, 243, 80, 222, 166, 60, 214, 107, 221, 207, 53, 39, 43, 210, + 124, 102, 39, 43, 210, 124, 105, 39, 43, 210, 124, 142, 39, 43, 210, 124, + 139, 39, 43, 210, 124, 168, 39, 43, 210, 124, 184, 39, 43, 210, 124, 195, + 39, 43, 210, 124, 193, 39, 43, 210, 124, 200, 39, 43, 212, 3, 39, 43, + 212, 4, 102, 39, 43, 212, 4, 105, 39, 43, 212, 4, 142, 39, 43, 212, 4, + 139, 39, 43, 212, 4, 168, 39, 25, 231, 84, 39, 25, 224, 223, 39, 25, 211, + 193, 39, 25, 218, 198, 39, 25, 226, 240, 39, 25, 221, 39, 39, 25, 215, + 33, 39, 25, 233, 125, 39, 25, 247, 246, 39, 25, 248, 54, 39, 25, 231, + 143, 39, 25, 212, 15, 39, 25, 221, 76, 39, 25, 239, 3, 39, 25, 231, 85, + 62, 39, 25, 224, 224, 62, 39, 25, 211, 194, 62, 39, 25, 218, 199, 62, 39, + 25, 226, 241, 62, 39, 25, 221, 40, 62, 39, 25, 215, 34, 62, 39, 25, 233, + 126, 62, 39, 25, 247, 247, 62, 39, 25, 248, 55, 62, 39, 25, 231, 144, 62, + 39, 25, 212, 16, 62, 39, 25, 221, 77, 62, 39, 25, 239, 4, 62, 39, 231, + 24, 157, 248, 101, 39, 231, 24, 157, 232, 100, 39, 25, 233, 126, 71, 231, + 24, 214, 29, 93, 39, 175, 102, 39, 175, 105, 39, 175, 142, 39, 175, 139, + 39, 175, 168, 39, 175, 184, 39, 175, 195, 39, 175, 193, 39, 175, 200, 39, + 175, 212, 98, 39, 175, 226, 144, 39, 175, 241, 219, 39, 175, 207, 69, 39, + 175, 206, 237, 39, 175, 227, 63, 39, 175, 243, 120, 39, 175, 213, 154, + 39, 175, 213, 254, 39, 175, 239, 78, 39, 175, 214, 189, 39, 175, 225, + 210, 39, 175, 214, 138, 39, 175, 241, 229, 39, 175, 247, 133, 39, 175, + 230, 130, 39, 175, 217, 78, 39, 175, 227, 225, 39, 175, 242, 10, 39, 175, + 213, 166, 39, 175, 242, 171, 39, 175, 220, 124, 39, 175, 251, 188, 39, + 175, 232, 219, 39, 175, 218, 236, 39, 175, 247, 95, 39, 175, 247, 86, 39, + 175, 238, 252, 39, 175, 248, 128, 39, 175, 229, 97, 39, 175, 230, 46, 39, + 175, 218, 167, 39, 175, 227, 110, 39, 175, 219, 7, 39, 175, 213, 207, 39, + 175, 213, 136, 39, 175, 243, 16, 39, 175, 218, 238, 39, 175, 252, 152, + 39, 175, 224, 209, 39, 43, 212, 4, 184, 39, 43, 212, 4, 195, 39, 43, 212, + 4, 193, 39, 43, 212, 4, 200, 39, 43, 241, 130, 39, 43, 241, 131, 102, 39, + 43, 241, 131, 105, 39, 43, 241, 131, 142, 39, 43, 241, 131, 139, 39, 43, + 241, 131, 168, 39, 43, 241, 131, 184, 39, 43, 241, 131, 195, 39, 43, 241, + 131, 193, 39, 43, 241, 131, 200, 39, 43, 241, 243, 128, 212, 110, 16, 33, + 232, 191, 128, 212, 110, 16, 33, 242, 22, 128, 212, 110, 16, 33, 227, + 193, 128, 212, 110, 16, 33, 252, 43, 128, 212, 110, 16, 33, 227, 162, + 128, 212, 110, 16, 33, 232, 98, 128, 212, 110, 16, 33, 232, 99, 128, 212, + 110, 16, 33, 251, 180, 128, 212, 110, 16, 33, 216, 38, 128, 212, 110, 16, + 33, 222, 212, 128, 212, 110, 16, 33, 224, 30, 128, 212, 110, 16, 33, 246, + 4, 49, 239, 21, 49, 242, 231, 49, 242, 180, 229, 211, 229, 234, 53, 39, + 64, 62, 39, 64, 74, 39, 64, 71, 39, 64, 75, 39, 64, 76, 39, 64, 172, 39, + 64, 231, 123, 39, 64, 230, 236, 39, 64, 231, 224, 39, 64, 231, 53, 39, + 64, 217, 199, 39, 64, 215, 80, 39, 64, 213, 203, 39, 64, 217, 86, 39, 64, + 214, 193, 39, 64, 212, 219, 39, 64, 211, 211, 39, 64, 210, 170, 39, 64, + 212, 131, 39, 64, 124, 39, 64, 199, 39, 64, 224, 230, 39, 64, 223, 217, + 39, 64, 225, 110, 39, 64, 224, 67, 39, 64, 155, 39, 64, 239, 11, 39, 64, + 238, 42, 39, 64, 239, 71, 39, 64, 238, 149, 39, 64, 185, 39, 64, 226, + 254, 39, 64, 226, 114, 39, 64, 227, 119, 39, 64, 226, 181, 39, 64, 190, + 39, 64, 205, 213, 39, 64, 205, 247, 39, 64, 219, 113, 39, 64, 218, 208, + 39, 64, 218, 50, 39, 64, 219, 51, 39, 64, 218, 124, 39, 64, 207, 96, 39, + 64, 207, 20, 39, 64, 207, 51, 39, 64, 206, 250, 49, 252, 67, 49, 251, + 233, 49, 252, 94, 49, 253, 122, 49, 233, 37, 49, 233, 5, 49, 209, 209, + 49, 242, 205, 49, 243, 101, 49, 222, 155, 49, 222, 148, 49, 232, 39, 49, + 232, 5, 49, 232, 2, 49, 240, 200, 49, 240, 209, 49, 240, 50, 49, 240, 46, + 49, 230, 160, 49, 240, 38, 49, 231, 100, 49, 231, 99, 49, 231, 98, 49, + 231, 97, 49, 239, 184, 49, 239, 183, 49, 230, 207, 49, 230, 209, 49, 231, + 217, 49, 231, 22, 49, 231, 30, 49, 217, 180, 49, 217, 144, 49, 215, 14, + 49, 216, 43, 49, 216, 42, 49, 246, 142, 49, 245, 205, 49, 245, 24, 49, + 211, 120, 49, 225, 205, 49, 224, 31, 49, 239, 126, 49, 222, 46, 49, 222, + 45, 49, 250, 180, 49, 221, 50, 49, 221, 13, 49, 221, 14, 49, 249, 215, + 49, 238, 40, 49, 238, 36, 49, 249, 60, 49, 238, 22, 49, 239, 47, 49, 221, + 105, 49, 221, 145, 49, 239, 30, 49, 221, 141, 49, 221, 159, 49, 250, 45, + 49, 220, 200, 49, 249, 159, 49, 238, 134, 49, 220, 188, 49, 238, 126, 49, + 238, 128, 49, 227, 237, 49, 227, 233, 49, 227, 242, 49, 227, 182, 49, + 227, 209, 49, 226, 220, 49, 226, 196, 49, 226, 195, 49, 227, 99, 49, 227, + 96, 49, 227, 100, 49, 206, 108, 49, 206, 106, 49, 205, 202, 49, 218, 140, + 49, 218, 144, 49, 218, 26, 49, 218, 20, 49, 219, 4, 49, 219, 1, 49, 207, + 67, 128, 212, 110, 16, 33, 238, 59, 205, 85, 128, 212, 110, 16, 33, 238, + 59, 102, 128, 212, 110, 16, 33, 238, 59, 105, 128, 212, 110, 16, 33, 238, + 59, 142, 128, 212, 110, 16, 33, 238, 59, 139, 128, 212, 110, 16, 33, 238, + 59, 168, 128, 212, 110, 16, 33, 238, 59, 184, 128, 212, 110, 16, 33, 238, + 59, 195, 128, 212, 110, 16, 33, 238, 59, 193, 128, 212, 110, 16, 33, 238, + 59, 200, 128, 212, 110, 16, 33, 238, 59, 212, 98, 128, 212, 110, 16, 33, + 238, 59, 243, 58, 128, 212, 110, 16, 33, 238, 59, 210, 126, 128, 212, + 110, 16, 33, 238, 59, 212, 5, 128, 212, 110, 16, 33, 238, 59, 241, 119, + 128, 212, 110, 16, 33, 238, 59, 241, 247, 128, 212, 110, 16, 33, 238, 59, + 215, 4, 128, 212, 110, 16, 33, 238, 59, 216, 20, 128, 212, 110, 16, 33, + 238, 59, 243, 85, 128, 212, 110, 16, 33, 238, 59, 224, 192, 128, 212, + 110, 16, 33, 238, 59, 210, 123, 128, 212, 110, 16, 33, 238, 59, 210, 117, + 128, 212, 110, 16, 33, 238, 59, 210, 113, 128, 212, 110, 16, 33, 238, 59, + 210, 114, 128, 212, 110, 16, 33, 238, 59, 210, 119, 49, 238, 50, 49, 246, + 145, 49, 251, 184, 49, 134, 49, 222, 88, 49, 221, 179, 49, 245, 53, 49, + 245, 54, 214, 106, 49, 245, 54, 247, 35, 49, 232, 216, 49, 242, 234, 225, + 211, 239, 48, 49, 242, 234, 225, 211, 213, 33, 49, 242, 234, 225, 211, + 212, 188, 49, 242, 234, 225, 211, 227, 95, 49, 247, 88, 49, 222, 52, 252, + 124, 49, 199, 49, 226, 115, 62, 49, 185, 49, 172, 49, 231, 227, 49, 227, + 158, 49, 240, 188, 49, 248, 241, 49, 231, 226, 49, 221, 96, 49, 225, 81, + 49, 226, 115, 242, 139, 49, 226, 115, 241, 55, 49, 227, 39, 49, 231, 169, + 49, 237, 234, 49, 231, 125, 49, 227, 0, 49, 240, 63, 49, 211, 213, 49, + 226, 115, 149, 49, 226, 189, 49, 245, 63, 49, 231, 66, 49, 241, 164, 49, + 224, 105, 49, 226, 115, 229, 28, 49, 226, 186, 49, 247, 175, 49, 231, 60, + 49, 226, 187, 214, 106, 49, 247, 176, 214, 106, 49, 229, 29, 214, 106, + 49, 231, 61, 214, 106, 49, 226, 187, 247, 35, 49, 247, 176, 247, 35, 49, + 229, 29, 247, 35, 49, 231, 61, 247, 35, 49, 229, 29, 131, 182, 49, 229, + 29, 131, 218, 1, 214, 106, 49, 179, 49, 231, 15, 49, 226, 118, 49, 239, + 251, 49, 219, 100, 49, 219, 101, 131, 182, 49, 219, 101, 131, 218, 1, + 214, 106, 49, 220, 95, 49, 223, 255, 49, 226, 115, 182, 49, 226, 116, 49, + 220, 47, 49, 223, 155, 49, 226, 115, 209, 148, 49, 226, 57, 49, 230, 198, + 49, 226, 58, 227, 99, 49, 220, 46, 49, 223, 154, 49, 226, 115, 207, 129, + 49, 226, 51, 49, 230, 196, 49, 226, 52, 227, 99, 49, 232, 77, 222, 192, + 49, 229, 29, 222, 192, 49, 252, 136, 49, 249, 136, 49, 248, 172, 49, 248, + 149, 49, 249, 35, 131, 231, 169, 49, 247, 174, 49, 246, 63, 49, 239, 168, + 49, 155, 49, 238, 51, 49, 233, 68, 49, 231, 73, 49, 231, 61, 248, 212, + 49, 230, 238, 49, 229, 147, 49, 229, 146, 49, 229, 135, 49, 229, 43, 49, + 227, 159, 214, 215, 49, 226, 219, 49, 226, 170, 49, 221, 94, 49, 220, + 214, 49, 220, 156, 49, 220, 154, 49, 214, 100, 49, 213, 117, 49, 207, 53, + 49, 209, 149, 131, 229, 28, 49, 32, 131, 229, 28, 128, 212, 110, 16, 33, + 246, 67, 102, 128, 212, 110, 16, 33, 246, 67, 105, 128, 212, 110, 16, 33, + 246, 67, 142, 128, 212, 110, 16, 33, 246, 67, 139, 128, 212, 110, 16, 33, + 246, 67, 168, 128, 212, 110, 16, 33, 246, 67, 184, 128, 212, 110, 16, 33, + 246, 67, 195, 128, 212, 110, 16, 33, 246, 67, 193, 128, 212, 110, 16, 33, + 246, 67, 200, 128, 212, 110, 16, 33, 246, 67, 212, 98, 128, 212, 110, 16, + 33, 246, 67, 243, 58, 128, 212, 110, 16, 33, 246, 67, 210, 126, 128, 212, + 110, 16, 33, 246, 67, 212, 5, 128, 212, 110, 16, 33, 246, 67, 241, 119, + 128, 212, 110, 16, 33, 246, 67, 241, 247, 128, 212, 110, 16, 33, 246, 67, + 215, 4, 128, 212, 110, 16, 33, 246, 67, 216, 20, 128, 212, 110, 16, 33, + 246, 67, 243, 85, 128, 212, 110, 16, 33, 246, 67, 224, 192, 128, 212, + 110, 16, 33, 246, 67, 210, 123, 128, 212, 110, 16, 33, 246, 67, 210, 117, + 128, 212, 110, 16, 33, 246, 67, 210, 113, 128, 212, 110, 16, 33, 246, 67, + 210, 114, 128, 212, 110, 16, 33, 246, 67, 210, 119, 128, 212, 110, 16, + 33, 246, 67, 210, 120, 128, 212, 110, 16, 33, 246, 67, 210, 115, 128, + 212, 110, 16, 33, 246, 67, 210, 116, 128, 212, 110, 16, 33, 246, 67, 210, + 122, 128, 212, 110, 16, 33, 246, 67, 210, 118, 128, 212, 110, 16, 33, + 246, 67, 212, 3, 128, 212, 110, 16, 33, 246, 67, 212, 2, 49, 240, 226, + 239, 24, 33, 212, 42, 247, 69, 239, 56, 239, 24, 33, 212, 42, 219, 44, + 243, 120, 239, 24, 33, 245, 138, 251, 200, 212, 42, 250, 40, 239, 24, 33, + 205, 226, 241, 156, 239, 24, 33, 207, 89, 239, 24, 33, 247, 136, 239, 24, + 33, 212, 42, 251, 254, 239, 24, 33, 238, 141, 211, 126, 239, 24, 33, 5, + 212, 175, 239, 24, 33, 211, 63, 239, 24, 33, 221, 172, 239, 24, 33, 214, + 28, 239, 24, 33, 242, 12, 239, 24, 33, 239, 232, 220, 177, 239, 24, 33, + 226, 174, 239, 24, 33, 243, 15, 239, 24, 33, 241, 157, 239, 24, 33, 206, + 230, 222, 166, 212, 42, 246, 5, 239, 24, 33, 252, 47, 239, 24, 33, 247, + 117, 239, 24, 33, 249, 208, 211, 232, 239, 24, 33, 239, 249, 239, 24, 33, + 214, 120, 252, 66, 239, 24, 33, 218, 228, 239, 24, 33, 233, 31, 239, 24, + 33, 239, 232, 212, 175, 239, 24, 33, 226, 124, 247, 90, 239, 24, 33, 239, + 232, 220, 134, 239, 24, 33, 212, 42, 253, 26, 207, 69, 239, 24, 33, 212, + 42, 247, 200, 241, 219, 239, 24, 33, 233, 44, 239, 24, 33, 243, 216, 239, + 24, 33, 218, 231, 239, 24, 33, 239, 232, 220, 161, 239, 24, 33, 220, 112, + 239, 24, 33, 246, 83, 73, 212, 42, 229, 223, 239, 24, 33, 212, 42, 242, + 48, 239, 24, 33, 222, 128, 239, 24, 33, 222, 218, 239, 24, 33, 245, 232, + 239, 24, 33, 245, 253, 239, 24, 33, 233, 59, 239, 24, 33, 249, 125, 239, + 24, 33, 247, 157, 211, 130, 227, 102, 239, 24, 33, 240, 195, 211, 126, + 239, 24, 33, 220, 56, 209, 197, 239, 24, 33, 222, 127, 239, 24, 33, 212, + 42, 207, 40, 239, 24, 33, 218, 219, 239, 24, 33, 212, 42, 248, 178, 239, + 24, 33, 212, 42, 251, 250, 211, 227, 239, 24, 33, 212, 42, 231, 218, 214, + 2, 226, 128, 239, 24, 33, 245, 200, 239, 24, 33, 212, 42, 227, 184, 227, + 238, 239, 24, 33, 253, 27, 239, 24, 33, 212, 42, 207, 84, 239, 24, 33, + 212, 42, 240, 153, 207, 9, 239, 24, 33, 212, 42, 232, 106, 230, 111, 239, + 24, 33, 245, 91, 239, 24, 33, 229, 212, 239, 24, 33, 233, 34, 210, 247, + 239, 24, 33, 5, 220, 134, 239, 24, 33, 252, 221, 247, 148, 239, 24, 33, + 250, 43, 247, 148, 9, 4, 232, 220, 9, 4, 232, 212, 9, 4, 74, 9, 4, 232, + 246, 9, 4, 233, 127, 9, 4, 233, 110, 9, 4, 233, 129, 9, 4, 233, 128, 9, + 4, 251, 199, 9, 4, 251, 161, 9, 4, 62, 9, 4, 252, 68, 9, 4, 209, 207, 9, + 4, 209, 210, 9, 4, 209, 208, 9, 4, 222, 103, 9, 4, 222, 76, 9, 4, 76, 9, + 4, 222, 143, 9, 4, 242, 172, 9, 4, 75, 9, 4, 206, 216, 9, 4, 249, 209, 9, + 4, 249, 206, 9, 4, 249, 244, 9, 4, 249, 219, 9, 4, 249, 233, 9, 4, 249, + 232, 9, 4, 249, 235, 9, 4, 249, 234, 9, 4, 250, 108, 9, 4, 250, 100, 9, + 4, 250, 183, 9, 4, 250, 130, 9, 4, 249, 71, 9, 4, 249, 75, 9, 4, 249, 72, + 9, 4, 249, 158, 9, 4, 249, 140, 9, 4, 249, 184, 9, 4, 249, 164, 9, 4, + 250, 3, 9, 4, 250, 61, 9, 4, 250, 15, 9, 4, 249, 56, 9, 4, 249, 52, 9, 4, + 249, 101, 9, 4, 249, 70, 9, 4, 249, 64, 9, 4, 249, 68, 9, 4, 249, 40, 9, + 4, 249, 38, 9, 4, 249, 45, 9, 4, 249, 43, 9, 4, 249, 41, 9, 4, 249, 42, + 9, 4, 220, 247, 9, 4, 220, 243, 9, 4, 221, 53, 9, 4, 221, 3, 9, 4, 221, + 19, 9, 4, 221, 46, 9, 4, 221, 42, 9, 4, 221, 195, 9, 4, 221, 184, 9, 4, + 179, 9, 4, 221, 236, 9, 4, 220, 66, 9, 4, 220, 68, 9, 4, 220, 67, 9, 4, + 220, 170, 9, 4, 220, 159, 9, 4, 220, 211, 9, 4, 220, 183, 9, 4, 220, 52, + 9, 4, 220, 48, 9, 4, 220, 82, 9, 4, 220, 65, 9, 4, 220, 57, 9, 4, 220, + 63, 9, 4, 220, 31, 9, 4, 220, 30, 9, 4, 220, 35, 9, 4, 220, 34, 9, 4, + 220, 32, 9, 4, 220, 33, 9, 4, 250, 82, 9, 4, 250, 81, 9, 4, 250, 88, 9, + 4, 250, 83, 9, 4, 250, 85, 9, 4, 250, 84, 9, 4, 250, 87, 9, 4, 250, 86, + 9, 4, 250, 94, 9, 4, 250, 93, 9, 4, 250, 97, 9, 4, 250, 95, 9, 4, 250, + 73, 9, 4, 250, 75, 9, 4, 250, 74, 9, 4, 250, 78, 9, 4, 250, 77, 9, 4, + 250, 80, 9, 4, 250, 79, 9, 4, 250, 89, 9, 4, 250, 92, 9, 4, 250, 90, 9, + 4, 250, 69, 9, 4, 250, 68, 9, 4, 250, 76, 9, 4, 250, 72, 9, 4, 250, 70, + 9, 4, 250, 71, 9, 4, 250, 65, 9, 4, 250, 64, 9, 4, 250, 67, 9, 4, 250, + 66, 9, 4, 225, 173, 9, 4, 225, 172, 9, 4, 225, 178, 9, 4, 225, 174, 9, 4, + 225, 175, 9, 4, 225, 177, 9, 4, 225, 176, 9, 4, 225, 181, 9, 4, 225, 180, + 9, 4, 225, 183, 9, 4, 225, 182, 9, 4, 225, 169, 9, 4, 225, 168, 9, 4, + 225, 171, 9, 4, 225, 170, 9, 4, 225, 162, 9, 4, 225, 161, 9, 4, 225, 166, + 9, 4, 225, 165, 9, 4, 225, 163, 9, 4, 225, 164, 9, 4, 225, 156, 9, 4, + 225, 155, 9, 4, 225, 160, 9, 4, 225, 159, 9, 4, 225, 157, 9, 4, 225, 158, + 9, 4, 238, 193, 9, 4, 238, 192, 9, 4, 238, 198, 9, 4, 238, 194, 9, 4, + 238, 195, 9, 4, 238, 197, 9, 4, 238, 196, 9, 4, 238, 201, 9, 4, 238, 200, + 9, 4, 238, 203, 9, 4, 238, 202, 9, 4, 238, 184, 9, 4, 238, 186, 9, 4, + 238, 185, 9, 4, 238, 189, 9, 4, 238, 188, 9, 4, 238, 191, 9, 4, 238, 190, + 9, 4, 238, 180, 9, 4, 238, 179, 9, 4, 238, 187, 9, 4, 238, 183, 9, 4, + 238, 181, 9, 4, 238, 182, 9, 4, 238, 174, 9, 4, 238, 178, 9, 4, 238, 177, + 9, 4, 238, 175, 9, 4, 238, 176, 9, 4, 226, 192, 9, 4, 226, 191, 9, 4, + 226, 254, 9, 4, 226, 198, 9, 4, 226, 226, 9, 4, 226, 244, 9, 4, 226, 242, + 9, 4, 227, 170, 9, 4, 227, 165, 9, 4, 185, 9, 4, 227, 205, 9, 4, 226, 83, + 9, 4, 226, 82, 9, 4, 226, 86, 9, 4, 226, 84, 9, 4, 226, 137, 9, 4, 226, + 120, 9, 4, 226, 181, 9, 4, 226, 142, 9, 4, 227, 50, 9, 4, 227, 119, 9, 4, + 226, 63, 9, 4, 226, 59, 9, 4, 226, 114, 9, 4, 226, 79, 9, 4, 226, 72, 9, + 4, 226, 77, 9, 4, 226, 36, 9, 4, 226, 35, 9, 4, 226, 41, 9, 4, 226, 38, + 9, 4, 241, 206, 9, 4, 241, 201, 9, 4, 241, 250, 9, 4, 241, 221, 9, 4, + 242, 41, 9, 4, 242, 32, 9, 4, 242, 73, 9, 4, 242, 44, 9, 4, 241, 117, 9, + 4, 241, 162, 9, 4, 241, 143, 9, 4, 241, 71, 9, 4, 241, 70, 9, 4, 241, 88, + 9, 4, 241, 76, 9, 4, 241, 74, 9, 4, 241, 75, 9, 4, 241, 58, 9, 4, 241, + 57, 9, 4, 241, 61, 9, 4, 241, 59, 9, 4, 208, 180, 9, 4, 208, 175, 9, 4, + 208, 214, 9, 4, 208, 189, 9, 4, 208, 203, 9, 4, 208, 200, 9, 4, 208, 206, + 9, 4, 208, 205, 9, 4, 209, 47, 9, 4, 209, 42, 9, 4, 209, 70, 9, 4, 209, + 59, 9, 4, 208, 157, 9, 4, 208, 153, 9, 4, 208, 173, 9, 4, 208, 159, 9, 4, + 208, 217, 9, 4, 209, 28, 9, 4, 207, 142, 9, 4, 207, 140, 9, 4, 207, 148, + 9, 4, 207, 145, 9, 4, 207, 143, 9, 4, 207, 144, 9, 4, 207, 133, 9, 4, + 207, 132, 9, 4, 207, 137, 9, 4, 207, 136, 9, 4, 207, 134, 9, 4, 207, 135, + 9, 4, 245, 85, 9, 4, 245, 72, 9, 4, 245, 168, 9, 4, 245, 110, 9, 4, 245, + 143, 9, 4, 245, 148, 9, 4, 245, 147, 9, 4, 246, 74, 9, 4, 246, 68, 9, 4, + 246, 145, 9, 4, 246, 94, 9, 4, 243, 221, 9, 4, 243, 222, 9, 4, 245, 23, + 9, 4, 244, 5, 9, 4, 245, 51, 9, 4, 245, 25, 9, 4, 245, 198, 9, 4, 246, 9, + 9, 4, 245, 218, 9, 4, 243, 212, 9, 4, 243, 210, 9, 4, 243, 237, 9, 4, + 243, 220, 9, 4, 243, 215, 9, 4, 243, 218, 9, 4, 211, 156, 9, 4, 211, 149, + 9, 4, 211, 211, 9, 4, 211, 166, 9, 4, 211, 201, 9, 4, 211, 203, 9, 4, + 211, 202, 9, 4, 212, 156, 9, 4, 212, 142, 9, 4, 212, 219, 9, 4, 212, 166, + 9, 4, 210, 153, 9, 4, 210, 152, 9, 4, 210, 155, 9, 4, 210, 154, 9, 4, + 211, 91, 9, 4, 211, 85, 9, 4, 124, 9, 4, 211, 101, 9, 4, 212, 62, 9, 4, + 212, 131, 9, 4, 212, 87, 9, 4, 210, 138, 9, 4, 210, 133, 9, 4, 210, 170, + 9, 4, 210, 151, 9, 4, 210, 139, 9, 4, 210, 149, 9, 4, 246, 26, 9, 4, 246, + 25, 9, 4, 246, 31, 9, 4, 246, 27, 9, 4, 246, 28, 9, 4, 246, 30, 9, 4, + 246, 29, 9, 4, 246, 47, 9, 4, 246, 46, 9, 4, 246, 54, 9, 4, 246, 48, 9, + 4, 246, 16, 9, 4, 246, 18, 9, 4, 246, 17, 9, 4, 246, 21, 9, 4, 246, 20, + 9, 4, 246, 24, 9, 4, 246, 22, 9, 4, 246, 39, 9, 4, 246, 42, 9, 4, 246, + 40, 9, 4, 246, 12, 9, 4, 246, 11, 9, 4, 246, 19, 9, 4, 246, 15, 9, 4, + 246, 13, 9, 4, 246, 14, 9, 4, 225, 129, 9, 4, 225, 128, 9, 4, 225, 136, + 9, 4, 225, 131, 9, 4, 225, 132, 9, 4, 225, 133, 9, 4, 225, 145, 9, 4, + 225, 144, 9, 4, 225, 151, 9, 4, 225, 146, 9, 4, 225, 121, 9, 4, 225, 120, + 9, 4, 225, 127, 9, 4, 225, 122, 9, 4, 225, 137, 9, 4, 225, 143, 9, 4, + 225, 141, 9, 4, 225, 113, 9, 4, 225, 112, 9, 4, 225, 118, 9, 4, 225, 116, + 9, 4, 225, 114, 9, 4, 225, 115, 9, 4, 238, 159, 9, 4, 238, 158, 9, 4, + 238, 165, 9, 4, 238, 160, 9, 4, 238, 162, 9, 4, 238, 161, 9, 4, 238, 164, + 9, 4, 238, 163, 9, 4, 238, 171, 9, 4, 238, 169, 9, 4, 238, 173, 9, 4, + 238, 172, 9, 4, 238, 152, 9, 4, 238, 153, 9, 4, 238, 156, 9, 4, 238, 155, + 9, 4, 238, 157, 9, 4, 238, 166, 9, 4, 238, 168, 9, 4, 238, 167, 9, 4, + 238, 151, 9, 4, 224, 184, 9, 4, 224, 182, 9, 4, 224, 230, 9, 4, 224, 187, + 9, 4, 224, 212, 9, 4, 224, 226, 9, 4, 224, 225, 9, 4, 225, 187, 9, 4, + 199, 9, 4, 225, 202, 9, 4, 223, 165, 9, 4, 223, 167, 9, 4, 223, 166, 9, + 4, 224, 42, 9, 4, 224, 27, 9, 4, 224, 67, 9, 4, 224, 52, 9, 4, 225, 83, + 9, 4, 225, 110, 9, 4, 225, 96, 9, 4, 223, 160, 9, 4, 223, 156, 9, 4, 223, + 217, 9, 4, 223, 164, 9, 4, 223, 162, 9, 4, 223, 163, 9, 4, 238, 224, 9, + 4, 238, 223, 9, 4, 238, 229, 9, 4, 238, 225, 9, 4, 238, 226, 9, 4, 238, + 228, 9, 4, 238, 227, 9, 4, 238, 235, 9, 4, 238, 233, 9, 4, 238, 237, 9, + 4, 238, 236, 9, 4, 238, 216, 9, 4, 238, 218, 9, 4, 238, 217, 9, 4, 238, + 220, 9, 4, 238, 222, 9, 4, 238, 221, 9, 4, 238, 230, 9, 4, 238, 232, 9, + 4, 238, 231, 9, 4, 238, 212, 9, 4, 238, 211, 9, 4, 238, 219, 9, 4, 238, + 215, 9, 4, 238, 213, 9, 4, 238, 214, 9, 4, 238, 206, 9, 4, 238, 205, 9, + 4, 238, 210, 9, 4, 238, 209, 9, 4, 238, 207, 9, 4, 238, 208, 9, 4, 229, + 184, 9, 4, 229, 177, 9, 4, 229, 235, 9, 4, 229, 193, 9, 4, 229, 227, 9, + 4, 229, 226, 9, 4, 229, 230, 9, 4, 229, 228, 9, 4, 230, 80, 9, 4, 230, + 69, 9, 4, 230, 141, 9, 4, 230, 89, 9, 4, 229, 60, 9, 4, 229, 59, 9, 4, + 229, 62, 9, 4, 229, 61, 9, 4, 229, 103, 9, 4, 229, 90, 9, 4, 229, 144, 9, + 4, 229, 108, 9, 4, 229, 252, 9, 4, 230, 58, 9, 4, 230, 13, 9, 4, 229, 54, + 9, 4, 229, 52, 9, 4, 229, 81, 9, 4, 229, 58, 9, 4, 229, 56, 9, 4, 229, + 57, 9, 4, 229, 33, 9, 4, 229, 32, 9, 4, 229, 42, 9, 4, 229, 36, 9, 4, + 229, 34, 9, 4, 229, 35, 9, 4, 240, 34, 9, 4, 240, 33, 9, 4, 240, 61, 9, + 4, 240, 45, 9, 4, 240, 53, 9, 4, 240, 52, 9, 4, 240, 55, 9, 4, 240, 54, + 9, 4, 240, 197, 9, 4, 240, 192, 9, 4, 240, 244, 9, 4, 240, 207, 9, 4, + 239, 189, 9, 4, 239, 188, 9, 4, 239, 191, 9, 4, 239, 190, 9, 4, 239, 254, + 9, 4, 239, 252, 9, 4, 240, 19, 9, 4, 240, 6, 9, 4, 240, 139, 9, 4, 240, + 137, 9, 4, 240, 170, 9, 4, 240, 150, 9, 4, 239, 178, 9, 4, 239, 177, 9, + 4, 239, 213, 9, 4, 239, 187, 9, 4, 239, 179, 9, 4, 239, 186, 9, 4, 231, + 89, 9, 4, 231, 86, 9, 4, 231, 123, 9, 4, 231, 103, 9, 4, 231, 113, 9, 4, + 231, 116, 9, 4, 231, 114, 9, 4, 231, 249, 9, 4, 231, 232, 9, 4, 172, 9, + 4, 232, 20, 9, 4, 230, 214, 9, 4, 230, 219, 9, 4, 230, 216, 9, 4, 231, + 21, 9, 4, 231, 16, 9, 4, 231, 53, 9, 4, 231, 28, 9, 4, 231, 193, 9, 4, + 231, 176, 9, 4, 231, 224, 9, 4, 231, 197, 9, 4, 230, 203, 9, 4, 230, 199, + 9, 4, 230, 236, 9, 4, 230, 213, 9, 4, 230, 206, 9, 4, 230, 210, 9, 4, + 240, 121, 9, 4, 240, 120, 9, 4, 240, 125, 9, 4, 240, 122, 9, 4, 240, 124, + 9, 4, 240, 123, 9, 4, 240, 132, 9, 4, 240, 131, 9, 4, 240, 135, 9, 4, + 240, 133, 9, 4, 240, 112, 9, 4, 240, 111, 9, 4, 240, 114, 9, 4, 240, 113, + 9, 4, 240, 117, 9, 4, 240, 116, 9, 4, 240, 119, 9, 4, 240, 118, 9, 4, + 240, 127, 9, 4, 240, 126, 9, 4, 240, 130, 9, 4, 240, 128, 9, 4, 240, 107, + 9, 4, 240, 106, 9, 4, 240, 115, 9, 4, 240, 110, 9, 4, 240, 108, 9, 4, + 240, 109, 9, 4, 227, 17, 9, 4, 227, 18, 9, 4, 227, 36, 9, 4, 227, 35, 9, + 4, 227, 38, 9, 4, 227, 37, 9, 4, 227, 8, 9, 4, 227, 10, 9, 4, 227, 9, 9, + 4, 227, 13, 9, 4, 227, 12, 9, 4, 227, 15, 9, 4, 227, 14, 9, 4, 227, 19, + 9, 4, 227, 21, 9, 4, 227, 20, 9, 4, 227, 4, 9, 4, 227, 3, 9, 4, 227, 11, + 9, 4, 227, 7, 9, 4, 227, 5, 9, 4, 227, 6, 9, 4, 237, 251, 9, 4, 237, 250, + 9, 4, 238, 1, 9, 4, 237, 252, 9, 4, 237, 254, 9, 4, 237, 253, 9, 4, 238, + 0, 9, 4, 237, 255, 9, 4, 238, 6, 9, 4, 238, 5, 9, 4, 238, 8, 9, 4, 238, + 7, 9, 4, 237, 243, 9, 4, 237, 242, 9, 4, 237, 245, 9, 4, 237, 244, 9, 4, + 237, 247, 9, 4, 237, 246, 9, 4, 237, 249, 9, 4, 237, 248, 9, 4, 238, 2, + 9, 4, 238, 4, 9, 4, 238, 3, 9, 4, 225, 22, 9, 4, 225, 24, 9, 4, 225, 23, + 9, 4, 225, 67, 9, 4, 225, 65, 9, 4, 225, 77, 9, 4, 225, 70, 9, 4, 224, + 240, 9, 4, 224, 239, 9, 4, 224, 241, 9, 4, 224, 250, 9, 4, 224, 247, 9, + 4, 225, 2, 9, 4, 224, 252, 9, 4, 225, 58, 9, 4, 225, 64, 9, 4, 225, 60, + 9, 4, 238, 242, 9, 4, 238, 253, 9, 4, 239, 6, 9, 4, 239, 86, 9, 4, 239, + 76, 9, 4, 155, 9, 4, 239, 97, 9, 4, 238, 24, 9, 4, 238, 23, 9, 4, 238, + 26, 9, 4, 238, 25, 9, 4, 238, 62, 9, 4, 238, 53, 9, 4, 238, 149, 9, 4, + 238, 124, 9, 4, 239, 26, 9, 4, 239, 71, 9, 4, 239, 38, 9, 4, 207, 72, 9, + 4, 207, 57, 9, 4, 207, 96, 9, 4, 207, 81, 9, 4, 206, 205, 9, 4, 206, 207, + 9, 4, 206, 206, 9, 4, 206, 224, 9, 4, 206, 250, 9, 4, 206, 233, 9, 4, + 207, 32, 9, 4, 207, 51, 9, 4, 207, 37, 9, 4, 205, 26, 9, 4, 205, 25, 9, + 4, 205, 40, 9, 4, 205, 28, 9, 4, 205, 33, 9, 4, 205, 35, 9, 4, 205, 34, + 9, 4, 205, 101, 9, 4, 205, 98, 9, 4, 205, 116, 9, 4, 205, 105, 9, 4, 205, + 2, 9, 4, 205, 4, 9, 4, 205, 3, 9, 4, 205, 15, 9, 4, 205, 14, 9, 4, 205, + 19, 9, 4, 205, 16, 9, 4, 205, 83, 9, 4, 205, 93, 9, 4, 205, 87, 9, 4, + 204, 254, 9, 4, 204, 253, 9, 4, 205, 9, 9, 4, 205, 1, 9, 4, 204, 255, 9, + 4, 205, 0, 9, 4, 204, 240, 9, 4, 204, 239, 9, 4, 204, 245, 9, 4, 204, + 243, 9, 4, 204, 241, 9, 4, 204, 242, 9, 4, 247, 225, 9, 4, 247, 219, 9, + 4, 247, 251, 9, 4, 247, 235, 9, 4, 247, 248, 9, 4, 247, 242, 9, 4, 247, + 250, 9, 4, 247, 249, 9, 4, 248, 183, 9, 4, 248, 175, 9, 4, 249, 1, 9, 4, + 248, 213, 9, 4, 247, 31, 9, 4, 247, 33, 9, 4, 247, 32, 9, 4, 247, 84, 9, + 4, 247, 74, 9, 4, 247, 174, 9, 4, 247, 100, 9, 4, 248, 113, 9, 4, 248, + 148, 9, 4, 248, 118, 9, 4, 247, 10, 9, 4, 247, 8, 9, 4, 247, 40, 9, 4, + 247, 29, 9, 4, 247, 16, 9, 4, 247, 28, 9, 4, 246, 243, 9, 4, 246, 242, 9, + 4, 246, 255, 9, 4, 246, 249, 9, 4, 246, 244, 9, 4, 246, 246, 9, 4, 204, + 223, 9, 4, 204, 222, 9, 4, 204, 229, 9, 4, 204, 224, 9, 4, 204, 226, 9, + 4, 204, 225, 9, 4, 204, 228, 9, 4, 204, 227, 9, 4, 204, 235, 9, 4, 204, + 234, 9, 4, 204, 238, 9, 4, 204, 236, 9, 4, 204, 219, 9, 4, 204, 221, 9, + 4, 204, 220, 9, 4, 204, 230, 9, 4, 204, 233, 9, 4, 204, 231, 9, 4, 204, + 212, 9, 4, 204, 216, 9, 4, 204, 215, 9, 4, 204, 213, 9, 4, 204, 214, 9, + 4, 204, 206, 9, 4, 204, 205, 9, 4, 204, 211, 9, 4, 204, 209, 9, 4, 204, + 207, 9, 4, 204, 208, 9, 4, 223, 78, 9, 4, 223, 77, 9, 4, 223, 83, 9, 4, + 223, 79, 9, 4, 223, 80, 9, 4, 223, 82, 9, 4, 223, 81, 9, 4, 223, 88, 9, + 4, 223, 87, 9, 4, 223, 91, 9, 4, 223, 90, 9, 4, 223, 71, 9, 4, 223, 72, + 9, 4, 223, 75, 9, 4, 223, 76, 9, 4, 223, 84, 9, 4, 223, 86, 9, 4, 223, + 66, 9, 4, 223, 74, 9, 4, 223, 70, 9, 4, 223, 67, 9, 4, 223, 68, 9, 4, + 223, 61, 9, 4, 223, 60, 9, 4, 223, 65, 9, 4, 223, 64, 9, 4, 223, 62, 9, + 4, 223, 63, 9, 4, 215, 12, 9, 4, 184, 9, 4, 215, 80, 9, 4, 215, 15, 9, 4, + 215, 69, 9, 4, 215, 72, 9, 4, 215, 70, 9, 4, 217, 133, 9, 4, 217, 119, 9, + 4, 217, 199, 9, 4, 217, 141, 9, 4, 213, 144, 9, 4, 213, 146, 9, 4, 213, + 145, 9, 4, 214, 168, 9, 4, 214, 158, 9, 4, 214, 193, 9, 4, 214, 172, 9, + 4, 216, 15, 9, 4, 217, 86, 9, 4, 216, 41, 9, 4, 213, 121, 9, 4, 213, 118, + 9, 4, 213, 203, 9, 4, 213, 143, 9, 4, 213, 125, 9, 4, 213, 133, 9, 4, + 213, 24, 9, 4, 213, 23, 9, 4, 213, 91, 9, 4, 213, 32, 9, 4, 213, 26, 9, + 4, 213, 31, 9, 4, 214, 58, 9, 4, 214, 57, 9, 4, 214, 64, 9, 4, 214, 59, + 9, 4, 214, 61, 9, 4, 214, 63, 9, 4, 214, 62, 9, 4, 214, 73, 9, 4, 214, + 71, 9, 4, 214, 96, 9, 4, 214, 74, 9, 4, 214, 53, 9, 4, 214, 52, 9, 4, + 214, 56, 9, 4, 214, 54, 9, 4, 214, 67, 9, 4, 214, 70, 9, 4, 214, 68, 9, + 4, 214, 49, 9, 4, 214, 47, 9, 4, 214, 51, 9, 4, 214, 50, 9, 4, 214, 42, + 9, 4, 214, 41, 9, 4, 214, 46, 9, 4, 214, 45, 9, 4, 214, 43, 9, 4, 214, + 44, 9, 4, 205, 76, 9, 4, 205, 75, 9, 4, 205, 81, 9, 4, 205, 78, 9, 4, + 205, 55, 9, 4, 205, 57, 9, 4, 205, 56, 9, 4, 205, 60, 9, 4, 205, 59, 9, + 4, 205, 64, 9, 4, 205, 61, 9, 4, 205, 69, 9, 4, 205, 68, 9, 4, 205, 72, + 9, 4, 205, 70, 9, 4, 205, 51, 9, 4, 205, 50, 9, 4, 205, 58, 9, 4, 205, + 54, 9, 4, 205, 52, 9, 4, 205, 53, 9, 4, 205, 43, 9, 4, 205, 42, 9, 4, + 205, 47, 9, 4, 205, 46, 9, 4, 205, 44, 9, 4, 205, 45, 9, 4, 248, 88, 9, + 4, 248, 84, 9, 4, 248, 110, 9, 4, 248, 97, 9, 4, 248, 10, 9, 4, 248, 9, + 9, 4, 248, 12, 9, 4, 248, 11, 9, 4, 248, 25, 9, 4, 248, 24, 9, 4, 248, + 32, 9, 4, 248, 27, 9, 4, 248, 63, 9, 4, 248, 61, 9, 4, 248, 82, 9, 4, + 248, 70, 9, 4, 248, 4, 9, 4, 248, 14, 9, 4, 248, 8, 9, 4, 248, 5, 9, 4, + 248, 7, 9, 4, 247, 253, 9, 4, 247, 252, 9, 4, 248, 1, 9, 4, 248, 0, 9, 4, + 247, 254, 9, 4, 247, 255, 9, 4, 218, 85, 9, 4, 218, 89, 9, 4, 218, 68, 9, + 4, 218, 69, 9, 4, 218, 72, 9, 4, 218, 71, 9, 4, 218, 75, 9, 4, 218, 73, + 9, 4, 218, 79, 9, 4, 218, 78, 9, 4, 218, 84, 9, 4, 218, 80, 9, 4, 218, + 64, 9, 4, 218, 62, 9, 4, 218, 70, 9, 4, 218, 67, 9, 4, 218, 65, 9, 4, + 218, 66, 9, 4, 218, 57, 9, 4, 218, 56, 9, 4, 218, 61, 9, 4, 218, 60, 9, + 4, 218, 58, 9, 4, 218, 59, 9, 4, 224, 22, 9, 4, 224, 21, 9, 4, 224, 24, + 9, 4, 224, 23, 9, 4, 224, 13, 9, 4, 224, 15, 9, 4, 224, 14, 9, 4, 224, + 17, 9, 4, 224, 16, 9, 4, 224, 20, 9, 4, 224, 19, 9, 4, 224, 7, 9, 4, 224, + 6, 9, 4, 224, 12, 9, 4, 224, 10, 9, 4, 224, 8, 9, 4, 224, 9, 9, 4, 224, + 1, 9, 4, 224, 0, 9, 4, 224, 5, 9, 4, 224, 4, 9, 4, 224, 2, 9, 4, 224, 3, + 9, 4, 215, 224, 9, 4, 215, 219, 9, 4, 216, 2, 9, 4, 215, 235, 9, 4, 215, + 105, 9, 4, 215, 107, 9, 4, 215, 106, 9, 4, 215, 128, 9, 4, 215, 125, 9, + 4, 215, 158, 9, 4, 215, 148, 9, 4, 215, 193, 9, 4, 215, 186, 9, 4, 215, + 214, 9, 4, 215, 201, 9, 4, 215, 101, 9, 4, 215, 99, 9, 4, 215, 116, 9, 4, + 215, 104, 9, 4, 215, 102, 9, 4, 215, 103, 9, 4, 215, 83, 9, 4, 215, 82, + 9, 4, 215, 89, 9, 4, 215, 86, 9, 4, 215, 84, 9, 4, 215, 85, 9, 4, 219, + 65, 9, 4, 219, 59, 9, 4, 219, 113, 9, 4, 219, 71, 9, 4, 218, 29, 9, 4, + 218, 31, 9, 4, 218, 30, 9, 4, 218, 98, 9, 4, 218, 91, 9, 4, 218, 124, 9, + 4, 218, 102, 9, 4, 218, 217, 9, 4, 219, 51, 9, 4, 219, 0, 9, 4, 218, 22, + 9, 4, 218, 19, 9, 4, 218, 50, 9, 4, 218, 28, 9, 4, 218, 24, 9, 4, 218, + 25, 9, 4, 218, 4, 9, 4, 218, 3, 9, 4, 218, 9, 9, 4, 218, 7, 9, 4, 218, 5, + 9, 4, 218, 6, 9, 4, 232, 152, 9, 4, 232, 151, 9, 4, 232, 162, 9, 4, 232, + 153, 9, 4, 232, 158, 9, 4, 232, 157, 9, 4, 232, 160, 9, 4, 232, 159, 9, + 4, 232, 94, 9, 4, 232, 93, 9, 4, 232, 96, 9, 4, 232, 95, 9, 4, 232, 110, + 9, 4, 232, 108, 9, 4, 232, 122, 9, 4, 232, 112, 9, 4, 232, 87, 9, 4, 232, + 85, 9, 4, 232, 104, 9, 4, 232, 92, 9, 4, 232, 89, 9, 4, 232, 90, 9, 4, + 232, 79, 9, 4, 232, 78, 9, 4, 232, 83, 9, 4, 232, 82, 9, 4, 232, 80, 9, + 4, 232, 81, 9, 4, 219, 230, 9, 4, 219, 228, 9, 4, 219, 237, 9, 4, 219, + 231, 9, 4, 219, 234, 9, 4, 219, 233, 9, 4, 219, 236, 9, 4, 219, 235, 9, + 4, 219, 181, 9, 4, 219, 178, 9, 4, 219, 183, 9, 4, 219, 182, 9, 4, 219, + 217, 9, 4, 219, 216, 9, 4, 219, 226, 9, 4, 219, 220, 9, 4, 219, 173, 9, + 4, 219, 169, 9, 4, 219, 214, 9, 4, 219, 177, 9, 4, 219, 175, 9, 4, 219, + 176, 9, 4, 219, 153, 9, 4, 219, 151, 9, 4, 219, 163, 9, 4, 219, 156, 9, + 4, 219, 154, 9, 4, 219, 155, 9, 4, 232, 141, 9, 4, 232, 140, 9, 4, 232, + 147, 9, 4, 232, 142, 9, 4, 232, 144, 9, 4, 232, 143, 9, 4, 232, 146, 9, + 4, 232, 145, 9, 4, 232, 132, 9, 4, 232, 134, 9, 4, 232, 133, 9, 4, 232, + 137, 9, 4, 232, 136, 9, 4, 232, 139, 9, 4, 232, 138, 9, 4, 232, 128, 9, + 4, 232, 127, 9, 4, 232, 135, 9, 4, 232, 131, 9, 4, 232, 129, 9, 4, 232, + 130, 9, 4, 232, 124, 9, 4, 232, 123, 9, 4, 232, 126, 9, 4, 232, 125, 9, + 4, 224, 157, 9, 4, 224, 156, 9, 4, 224, 164, 9, 4, 224, 158, 9, 4, 224, + 160, 9, 4, 224, 159, 9, 4, 224, 163, 9, 4, 224, 161, 9, 4, 224, 146, 9, + 4, 224, 147, 9, 4, 224, 152, 9, 4, 224, 151, 9, 4, 224, 155, 9, 4, 224, + 153, 9, 4, 224, 141, 9, 4, 224, 150, 9, 4, 224, 145, 9, 4, 224, 142, 9, + 4, 224, 143, 9, 4, 224, 136, 9, 4, 224, 135, 9, 4, 224, 140, 9, 4, 224, + 139, 9, 4, 224, 137, 9, 4, 224, 138, 9, 4, 223, 113, 9, 4, 223, 112, 9, + 4, 223, 125, 9, 4, 223, 117, 9, 4, 223, 122, 9, 4, 223, 121, 9, 4, 223, + 124, 9, 4, 223, 123, 9, 4, 223, 98, 9, 4, 223, 100, 9, 4, 223, 99, 9, 4, + 223, 105, 9, 4, 223, 104, 9, 4, 223, 110, 9, 4, 223, 106, 9, 4, 223, 96, + 9, 4, 223, 94, 9, 4, 223, 103, 9, 4, 223, 97, 9, 4, 206, 161, 9, 4, 206, + 160, 9, 4, 206, 169, 9, 4, 206, 163, 9, 4, 206, 165, 9, 4, 206, 164, 9, + 4, 206, 167, 9, 4, 206, 166, 9, 4, 206, 149, 9, 4, 206, 150, 9, 4, 206, + 154, 9, 4, 206, 153, 9, 4, 206, 159, 9, 4, 206, 157, 9, 4, 206, 127, 9, + 4, 206, 125, 9, 4, 206, 140, 9, 4, 206, 130, 9, 4, 206, 128, 9, 4, 206, + 129, 9, 4, 205, 253, 9, 4, 205, 251, 9, 4, 206, 11, 9, 4, 205, 254, 9, 4, + 206, 5, 9, 4, 206, 4, 9, 4, 206, 8, 9, 4, 206, 6, 9, 4, 205, 191, 9, 4, + 205, 190, 9, 4, 205, 194, 9, 4, 205, 192, 9, 4, 205, 227, 9, 4, 205, 223, + 9, 4, 205, 247, 9, 4, 205, 231, 9, 4, 205, 182, 9, 4, 205, 178, 9, 4, + 205, 213, 9, 4, 205, 189, 9, 4, 205, 185, 9, 4, 205, 186, 9, 4, 205, 162, + 9, 4, 205, 161, 9, 4, 205, 169, 9, 4, 205, 165, 9, 4, 205, 163, 9, 4, + 205, 164, 9, 37, 219, 217, 9, 37, 229, 235, 9, 37, 231, 89, 9, 37, 223, + 117, 9, 37, 246, 249, 9, 37, 214, 64, 9, 37, 240, 118, 9, 37, 240, 150, + 9, 37, 226, 254, 9, 37, 237, 251, 9, 37, 229, 35, 9, 37, 250, 69, 9, 37, + 226, 142, 9, 37, 205, 247, 9, 37, 220, 52, 9, 37, 237, 245, 9, 37, 212, + 156, 9, 37, 240, 244, 9, 37, 205, 1, 9, 37, 246, 243, 9, 37, 246, 14, 9, + 37, 249, 68, 9, 37, 240, 114, 9, 37, 223, 106, 9, 37, 210, 170, 9, 37, + 222, 143, 9, 37, 232, 128, 9, 37, 205, 15, 9, 37, 220, 31, 9, 37, 238, + 191, 9, 37, 205, 253, 9, 37, 207, 144, 9, 37, 215, 89, 9, 37, 209, 28, 9, + 37, 205, 116, 9, 37, 232, 122, 9, 37, 223, 70, 9, 37, 232, 126, 9, 37, + 239, 254, 9, 37, 232, 146, 9, 37, 206, 250, 9, 37, 243, 237, 9, 37, 215, + 103, 9, 37, 229, 230, 9, 37, 246, 255, 9, 37, 247, 32, 9, 37, 247, 235, + 9, 37, 237, 248, 9, 37, 215, 224, 9, 37, 205, 0, 9, 37, 215, 148, 9, 37, + 248, 82, 9, 37, 204, 226, 9, 37, 225, 177, 9, 37, 231, 224, 229, 185, 1, + 250, 183, 229, 185, 1, 179, 229, 185, 1, 221, 93, 229, 185, 1, 246, 145, + 229, 185, 1, 212, 219, 229, 185, 1, 212, 56, 229, 185, 1, 240, 244, 229, + 185, 1, 172, 229, 185, 1, 231, 167, 229, 185, 1, 232, 200, 229, 185, 1, + 249, 1, 229, 185, 1, 248, 110, 229, 185, 1, 243, 196, 229, 185, 1, 210, + 243, 229, 185, 1, 210, 233, 229, 185, 1, 185, 229, 185, 1, 199, 229, 185, + 1, 230, 141, 229, 185, 1, 217, 199, 229, 185, 1, 205, 81, 229, 185, 1, + 205, 116, 229, 185, 1, 225, 77, 229, 185, 1, 155, 229, 185, 1, 206, 181, + 229, 185, 1, 239, 20, 229, 185, 1, 242, 73, 229, 185, 1, 207, 96, 229, + 185, 1, 216, 2, 229, 185, 1, 190, 229, 185, 1, 240, 99, 229, 185, 1, 62, + 229, 185, 1, 252, 248, 229, 185, 1, 75, 229, 185, 1, 242, 192, 229, 185, + 1, 74, 229, 185, 1, 76, 229, 185, 1, 71, 229, 185, 1, 210, 3, 229, 185, + 1, 209, 253, 229, 185, 1, 222, 206, 229, 185, 1, 135, 226, 40, 211, 211, + 229, 185, 1, 135, 225, 237, 220, 211, 229, 185, 1, 135, 226, 40, 246, + 254, 229, 185, 1, 135, 226, 40, 249, 184, 229, 185, 1, 135, 226, 40, 199, + 229, 185, 1, 135, 226, 40, 232, 171, 229, 185, 220, 72, 247, 155, 229, + 185, 220, 72, 241, 82, 213, 251, 46, 4, 243, 104, 46, 4, 243, 100, 46, 4, + 239, 53, 46, 4, 207, 45, 46, 4, 207, 44, 46, 4, 221, 164, 46, 4, 249, + 251, 46, 4, 250, 50, 46, 4, 227, 145, 46, 4, 231, 10, 46, 4, 227, 30, 46, + 4, 240, 183, 46, 4, 242, 21, 46, 4, 209, 34, 46, 4, 212, 120, 46, 4, 212, + 39, 46, 4, 245, 182, 46, 4, 245, 179, 46, 4, 230, 50, 46, 4, 219, 29, 46, + 4, 245, 251, 46, 4, 225, 142, 46, 4, 217, 74, 46, 4, 215, 212, 46, 4, + 205, 91, 46, 4, 205, 71, 46, 4, 248, 140, 46, 4, 232, 180, 46, 4, 224, + 171, 46, 4, 206, 49, 46, 4, 231, 221, 46, 4, 225, 50, 46, 4, 240, 162, + 46, 4, 227, 107, 46, 4, 225, 106, 46, 4, 223, 133, 46, 4, 74, 46, 4, 233, + 68, 46, 4, 239, 11, 46, 4, 238, 246, 46, 4, 207, 20, 46, 4, 207, 11, 46, + 4, 221, 53, 46, 4, 249, 249, 46, 4, 249, 244, 46, 4, 227, 138, 46, 4, + 231, 7, 46, 4, 227, 27, 46, 4, 240, 179, 46, 4, 241, 250, 46, 4, 208, + 214, 46, 4, 211, 211, 46, 4, 212, 19, 46, 4, 245, 174, 46, 4, 245, 178, + 46, 4, 229, 235, 46, 4, 218, 208, 46, 4, 245, 168, 46, 4, 225, 136, 46, + 4, 215, 80, 46, 4, 215, 183, 46, 4, 205, 40, 46, 4, 205, 67, 46, 4, 247, + 251, 46, 4, 232, 162, 46, 4, 224, 164, 46, 4, 206, 11, 46, 4, 231, 123, + 46, 4, 225, 42, 46, 4, 240, 61, 46, 4, 226, 254, 46, 4, 224, 230, 46, 4, + 223, 125, 46, 4, 62, 46, 4, 252, 122, 46, 4, 225, 72, 46, 4, 155, 46, 4, + 239, 110, 46, 4, 207, 96, 46, 4, 207, 85, 46, 4, 179, 46, 4, 250, 0, 46, + 4, 250, 183, 46, 4, 227, 153, 46, 4, 231, 15, 46, 4, 231, 13, 46, 4, 227, + 34, 46, 4, 240, 187, 46, 4, 242, 73, 46, 4, 209, 70, 46, 4, 212, 219, 46, + 4, 212, 56, 46, 4, 245, 192, 46, 4, 245, 181, 46, 4, 230, 141, 46, 4, + 219, 113, 46, 4, 246, 145, 46, 4, 225, 151, 46, 4, 217, 199, 46, 4, 216, + 2, 46, 4, 205, 116, 46, 4, 205, 81, 46, 4, 249, 1, 46, 4, 232, 200, 46, + 4, 224, 180, 46, 4, 190, 46, 4, 172, 46, 4, 232, 27, 46, 4, 225, 56, 46, + 4, 240, 244, 46, 4, 185, 46, 4, 199, 46, 4, 223, 144, 46, 4, 222, 152, + 46, 4, 222, 147, 46, 4, 238, 131, 46, 4, 206, 238, 46, 4, 206, 234, 46, + 4, 220, 187, 46, 4, 249, 247, 46, 4, 249, 172, 46, 4, 227, 133, 46, 4, + 231, 5, 46, 4, 227, 23, 46, 4, 240, 175, 46, 4, 241, 151, 46, 4, 208, + 161, 46, 4, 211, 105, 46, 4, 211, 248, 46, 4, 245, 171, 46, 4, 245, 176, + 46, 4, 229, 115, 46, 4, 218, 107, 46, 4, 245, 28, 46, 4, 225, 123, 46, 4, + 214, 174, 46, 4, 215, 152, 46, 4, 205, 17, 46, 4, 205, 62, 46, 4, 247, + 105, 46, 4, 232, 113, 46, 4, 224, 154, 46, 4, 205, 232, 46, 4, 231, 33, + 46, 4, 225, 40, 46, 4, 240, 8, 46, 4, 226, 150, 46, 4, 224, 56, 46, 4, + 223, 107, 46, 4, 71, 46, 4, 209, 234, 46, 4, 238, 42, 46, 4, 238, 31, 46, + 4, 206, 216, 46, 4, 206, 209, 46, 4, 220, 82, 46, 4, 249, 246, 46, 4, + 249, 101, 46, 4, 227, 132, 46, 4, 231, 3, 46, 4, 227, 22, 46, 4, 240, + 174, 46, 4, 241, 88, 46, 4, 207, 148, 46, 4, 210, 170, 46, 4, 211, 230, + 46, 4, 245, 169, 46, 4, 245, 175, 46, 4, 229, 81, 46, 4, 218, 50, 46, 4, + 243, 237, 46, 4, 225, 118, 46, 4, 213, 203, 46, 4, 215, 116, 46, 4, 205, + 9, 46, 4, 205, 58, 46, 4, 247, 40, 46, 4, 232, 104, 46, 4, 224, 150, 46, + 4, 205, 213, 46, 4, 230, 236, 46, 4, 225, 39, 46, 4, 239, 213, 46, 4, + 226, 114, 46, 4, 223, 217, 46, 4, 223, 103, 46, 4, 76, 46, 4, 222, 165, + 46, 4, 224, 254, 46, 4, 238, 149, 46, 4, 238, 134, 46, 4, 206, 250, 46, + 4, 206, 239, 46, 4, 220, 211, 46, 4, 249, 248, 46, 4, 249, 184, 46, 4, + 227, 134, 46, 4, 231, 6, 46, 4, 227, 25, 46, 4, 240, 177, 46, 4, 240, + 176, 46, 4, 241, 162, 46, 4, 208, 173, 46, 4, 124, 46, 4, 211, 253, 46, + 4, 245, 172, 46, 4, 245, 177, 46, 4, 229, 144, 46, 4, 218, 124, 46, 4, + 245, 51, 46, 4, 225, 127, 46, 4, 214, 193, 46, 4, 215, 158, 46, 4, 205, + 19, 46, 4, 205, 64, 46, 4, 247, 174, 46, 4, 232, 122, 46, 4, 224, 155, + 46, 4, 205, 247, 46, 4, 231, 53, 46, 4, 225, 41, 46, 4, 240, 19, 46, 4, + 226, 181, 46, 4, 224, 67, 46, 4, 223, 110, 46, 4, 75, 46, 4, 243, 41, 46, + 4, 225, 61, 46, 4, 239, 71, 46, 4, 239, 41, 46, 4, 207, 51, 46, 4, 207, + 39, 46, 4, 221, 174, 46, 4, 249, 252, 46, 4, 250, 61, 46, 4, 227, 146, + 46, 4, 231, 11, 46, 4, 231, 9, 46, 4, 227, 31, 46, 4, 240, 184, 46, 4, + 240, 182, 46, 4, 242, 28, 46, 4, 209, 39, 46, 4, 212, 131, 46, 4, 212, + 41, 46, 4, 245, 183, 46, 4, 245, 180, 46, 4, 230, 58, 46, 4, 219, 51, 46, + 4, 246, 9, 46, 4, 225, 143, 46, 4, 217, 86, 46, 4, 215, 214, 46, 4, 205, + 93, 46, 4, 205, 72, 46, 4, 248, 148, 46, 4, 232, 182, 46, 4, 224, 173, + 46, 4, 206, 52, 46, 4, 231, 224, 46, 4, 225, 51, 46, 4, 225, 47, 46, 4, + 240, 170, 46, 4, 240, 157, 46, 4, 227, 119, 46, 4, 225, 110, 46, 4, 223, + 134, 46, 4, 225, 79, 46, 4, 230, 19, 46, 247, 155, 46, 241, 82, 213, 251, + 46, 219, 196, 83, 46, 4, 225, 126, 242, 73, 46, 4, 225, 126, 172, 46, 4, + 225, 126, 214, 174, 46, 16, 242, 17, 46, 16, 231, 219, 46, 16, 211, 171, + 46, 16, 224, 205, 46, 16, 250, 135, 46, 16, 242, 72, 46, 16, 212, 215, + 46, 16, 246, 98, 46, 16, 245, 27, 46, 16, 230, 220, 46, 16, 211, 109, 46, + 16, 245, 50, 46, 16, 232, 114, 46, 18, 205, 85, 46, 18, 102, 46, 18, 105, + 46, 18, 142, 46, 18, 139, 46, 18, 168, 46, 18, 184, 46, 18, 195, 46, 18, + 193, 46, 18, 200, 46, 4, 225, 126, 185, 46, 4, 225, 126, 245, 51, 34, 6, + 1, 205, 89, 34, 5, 1, 205, 89, 34, 6, 1, 243, 191, 34, 5, 1, 243, 191, + 34, 6, 1, 218, 224, 243, 193, 34, 5, 1, 218, 224, 243, 193, 34, 6, 1, + 232, 249, 34, 5, 1, 232, 249, 34, 6, 1, 245, 67, 34, 5, 1, 245, 67, 34, + 6, 1, 226, 158, 209, 249, 34, 5, 1, 226, 158, 209, 249, 34, 6, 1, 249, + 112, 222, 170, 34, 5, 1, 249, 112, 222, 170, 34, 6, 1, 225, 88, 206, 34, + 34, 5, 1, 225, 88, 206, 34, 34, 6, 1, 206, 31, 2, 250, 177, 206, 34, 34, + 5, 1, 206, 31, 2, 250, 177, 206, 34, 34, 6, 1, 232, 247, 206, 65, 34, 5, + 1, 232, 247, 206, 65, 34, 6, 1, 218, 224, 205, 213, 34, 5, 1, 218, 224, + 205, 213, 34, 6, 1, 232, 247, 62, 34, 5, 1, 232, 247, 62, 34, 6, 1, 247, + 192, 229, 180, 205, 183, 34, 5, 1, 247, 192, 229, 180, 205, 183, 34, 6, + 1, 249, 194, 205, 183, 34, 5, 1, 249, 194, 205, 183, 34, 6, 1, 232, 247, + 247, 192, 229, 180, 205, 183, 34, 5, 1, 232, 247, 247, 192, 229, 180, + 205, 183, 34, 6, 1, 205, 249, 34, 5, 1, 205, 249, 34, 6, 1, 218, 224, + 210, 237, 34, 5, 1, 218, 224, 210, 237, 34, 6, 1, 214, 187, 246, 9, 34, + 5, 1, 214, 187, 246, 9, 34, 6, 1, 214, 187, 243, 68, 34, 5, 1, 214, 187, + 243, 68, 34, 6, 1, 214, 187, 243, 50, 34, 5, 1, 214, 187, 243, 50, 34, 6, + 1, 226, 162, 76, 34, 5, 1, 226, 162, 76, 34, 6, 1, 249, 221, 76, 34, 5, + 1, 249, 221, 76, 34, 6, 1, 50, 226, 162, 76, 34, 5, 1, 50, 226, 162, 76, + 34, 1, 226, 96, 76, 36, 34, 207, 131, 36, 34, 212, 99, 226, 213, 53, 36, + 34, 238, 30, 226, 213, 53, 36, 34, 211, 243, 226, 213, 53, 214, 233, 251, + 209, 36, 34, 1, 209, 246, 233, 129, 36, 34, 1, 74, 36, 34, 1, 206, 11, + 36, 34, 1, 71, 36, 34, 1, 239, 94, 53, 36, 34, 1, 206, 30, 36, 34, 1, + 214, 187, 53, 36, 34, 1, 222, 170, 36, 34, 231, 236, 36, 34, 221, 181, + 34, 231, 236, 34, 221, 181, 34, 6, 1, 243, 205, 34, 5, 1, 243, 205, 34, + 6, 1, 243, 182, 34, 5, 1, 243, 182, 34, 6, 1, 205, 48, 34, 5, 1, 205, 48, + 34, 6, 1, 248, 164, 34, 5, 1, 248, 164, 34, 6, 1, 243, 179, 34, 5, 1, + 243, 179, 34, 6, 1, 212, 132, 2, 226, 247, 109, 34, 5, 1, 212, 132, 2, + 226, 247, 109, 34, 6, 1, 210, 128, 34, 5, 1, 210, 128, 34, 6, 1, 210, + 212, 34, 5, 1, 210, 212, 34, 6, 1, 210, 217, 34, 5, 1, 210, 217, 34, 6, + 1, 212, 137, 34, 5, 1, 212, 137, 34, 6, 1, 238, 13, 34, 5, 1, 238, 13, + 34, 6, 1, 215, 95, 34, 5, 1, 215, 95, 34, 6, 1, 50, 76, 34, 5, 1, 50, 76, + 34, 6, 1, 247, 57, 76, 34, 5, 1, 247, 57, 76, 65, 1, 34, 239, 94, 53, 65, + 1, 34, 214, 187, 53, 36, 34, 1, 232, 247, 75, 21, 1, 62, 21, 1, 172, 21, + 1, 71, 21, 1, 230, 236, 21, 1, 243, 104, 21, 1, 219, 29, 21, 1, 212, 200, + 21, 1, 76, 21, 1, 223, 125, 21, 1, 74, 21, 1, 230, 141, 21, 1, 179, 21, + 1, 218, 154, 21, 1, 218, 201, 21, 1, 230, 49, 21, 1, 227, 106, 21, 1, + 212, 215, 21, 1, 225, 149, 21, 1, 224, 178, 21, 1, 229, 28, 21, 1, 213, + 119, 21, 1, 226, 114, 21, 1, 215, 178, 21, 1, 215, 80, 21, 1, 215, 188, + 21, 1, 216, 24, 21, 1, 230, 165, 21, 1, 231, 193, 21, 1, 223, 188, 21, 1, + 223, 217, 21, 1, 224, 149, 21, 1, 205, 229, 21, 1, 215, 116, 21, 1, 205, + 187, 21, 1, 190, 21, 1, 223, 251, 21, 1, 231, 179, 21, 1, 221, 97, 21, 1, + 224, 171, 21, 1, 223, 232, 21, 1, 220, 75, 21, 1, 206, 213, 21, 1, 221, + 164, 21, 1, 242, 21, 21, 1, 218, 50, 21, 1, 229, 81, 21, 1, 226, 254, 21, + 1, 224, 230, 21, 1, 218, 226, 21, 1, 219, 95, 21, 1, 231, 203, 21, 1, + 225, 5, 21, 1, 225, 56, 21, 1, 225, 77, 21, 1, 215, 158, 21, 1, 220, 79, + 21, 1, 241, 88, 21, 1, 241, 155, 21, 1, 207, 96, 21, 1, 199, 21, 1, 229, + 235, 21, 1, 221, 53, 21, 1, 229, 107, 21, 1, 231, 53, 21, 1, 227, 143, + 21, 1, 219, 2, 21, 1, 227, 83, 21, 1, 185, 21, 1, 211, 211, 21, 1, 231, + 123, 21, 1, 226, 181, 21, 1, 227, 151, 21, 1, 212, 80, 21, 1, 231, 15, + 21, 1, 212, 98, 21, 1, 223, 219, 21, 1, 217, 159, 21, 1, 242, 69, 21, 1, + 231, 17, 21, 1, 231, 48, 21, 36, 141, 231, 26, 21, 36, 141, 210, 161, 21, + 224, 177, 21, 241, 82, 213, 251, 21, 247, 162, 21, 247, 155, 21, 216, 52, + 21, 219, 196, 83, 65, 1, 248, 44, 135, 206, 1, 221, 5, 65, 1, 248, 44, + 135, 206, 76, 221, 5, 65, 1, 248, 44, 135, 206, 1, 215, 236, 65, 1, 248, + 44, 135, 206, 76, 215, 236, 65, 1, 248, 44, 135, 206, 1, 219, 214, 65, 1, + 248, 44, 135, 206, 76, 219, 214, 65, 1, 248, 44, 135, 206, 1, 218, 50, + 65, 1, 248, 44, 135, 206, 76, 218, 50, 65, 1, 242, 156, 244, 21, 135, + 134, 65, 1, 127, 244, 21, 135, 134, 65, 1, 226, 249, 244, 21, 135, 134, + 65, 1, 114, 244, 21, 135, 134, 65, 1, 242, 155, 244, 21, 135, 134, 65, 1, + 242, 156, 244, 21, 230, 38, 135, 134, 65, 1, 127, 244, 21, 230, 38, 135, + 134, 65, 1, 226, 249, 244, 21, 230, 38, 135, 134, 65, 1, 114, 244, 21, + 230, 38, 135, 134, 65, 1, 242, 155, 244, 21, 230, 38, 135, 134, 65, 1, + 242, 156, 230, 38, 135, 134, 65, 1, 127, 230, 38, 135, 134, 65, 1, 226, + 249, 230, 38, 135, 134, 65, 1, 114, 230, 38, 135, 134, 65, 1, 242, 155, + 230, 38, 135, 134, 65, 1, 67, 79, 134, 65, 1, 67, 214, 235, 65, 1, 67, + 194, 134, 65, 1, 229, 92, 48, 247, 92, 252, 108, 65, 1, 219, 81, 120, 45, + 65, 1, 219, 81, 130, 45, 65, 1, 219, 81, 242, 168, 83, 65, 1, 219, 81, + 233, 2, 242, 168, 83, 65, 1, 114, 233, 2, 242, 168, 83, 65, 1, 213, 233, + 23, 127, 211, 118, 65, 1, 213, 233, 23, 114, 211, 118, 7, 6, 1, 243, 94, + 252, 172, 7, 5, 1, 243, 94, 252, 172, 7, 6, 1, 243, 94, 252, 200, 7, 5, + 1, 243, 94, 252, 200, 7, 6, 1, 239, 39, 7, 5, 1, 239, 39, 7, 6, 1, 210, + 86, 7, 5, 1, 210, 86, 7, 6, 1, 211, 55, 7, 5, 1, 211, 55, 7, 6, 1, 247, + 37, 7, 5, 1, 247, 37, 7, 6, 1, 247, 38, 2, 247, 155, 7, 5, 1, 247, 38, 2, + 247, 155, 7, 1, 5, 6, 242, 139, 7, 1, 5, 6, 182, 7, 6, 1, 253, 164, 7, 5, + 1, 253, 164, 7, 6, 1, 252, 71, 7, 5, 1, 252, 71, 7, 6, 1, 251, 184, 7, 5, + 1, 251, 184, 7, 6, 1, 251, 168, 7, 5, 1, 251, 168, 7, 6, 1, 251, 169, 2, + 194, 134, 7, 5, 1, 251, 169, 2, 194, 134, 7, 6, 1, 251, 159, 7, 5, 1, + 251, 159, 7, 6, 1, 218, 224, 249, 35, 2, 245, 23, 7, 5, 1, 218, 224, 249, + 35, 2, 245, 23, 7, 6, 1, 232, 77, 2, 91, 7, 5, 1, 232, 77, 2, 91, 7, 6, + 1, 232, 77, 2, 245, 163, 91, 7, 5, 1, 232, 77, 2, 245, 163, 91, 7, 6, 1, + 232, 77, 2, 213, 225, 23, 245, 163, 91, 7, 5, 1, 232, 77, 2, 213, 225, + 23, 245, 163, 91, 7, 6, 1, 249, 111, 149, 7, 5, 1, 249, 111, 149, 7, 6, + 1, 230, 159, 2, 127, 91, 7, 5, 1, 230, 159, 2, 127, 91, 7, 6, 1, 148, 2, + 152, 213, 225, 222, 82, 7, 5, 1, 148, 2, 152, 213, 225, 222, 82, 7, 6, 1, + 148, 2, 229, 111, 7, 5, 1, 148, 2, 229, 111, 7, 6, 1, 222, 152, 7, 5, 1, + 222, 152, 7, 6, 1, 222, 68, 2, 213, 225, 211, 233, 245, 211, 7, 5, 1, + 222, 68, 2, 213, 225, 211, 233, 245, 211, 7, 6, 1, 222, 68, 2, 241, 174, + 7, 5, 1, 222, 68, 2, 241, 174, 7, 6, 1, 222, 68, 2, 214, 102, 212, 191, + 7, 5, 1, 222, 68, 2, 214, 102, 212, 191, 7, 6, 1, 220, 28, 2, 213, 225, + 211, 233, 245, 211, 7, 5, 1, 220, 28, 2, 213, 225, 211, 233, 245, 211, 7, + 6, 1, 220, 28, 2, 245, 163, 91, 7, 5, 1, 220, 28, 2, 245, 163, 91, 7, 6, + 1, 219, 150, 218, 96, 7, 5, 1, 219, 150, 218, 96, 7, 6, 1, 218, 39, 218, + 96, 7, 5, 1, 218, 39, 218, 96, 7, 6, 1, 209, 149, 2, 245, 163, 91, 7, 5, + 1, 209, 149, 2, 245, 163, 91, 7, 6, 1, 207, 137, 7, 5, 1, 207, 137, 7, 6, + 1, 208, 181, 205, 159, 7, 5, 1, 208, 181, 205, 159, 7, 6, 1, 211, 247, 2, + 91, 7, 5, 1, 211, 247, 2, 91, 7, 6, 1, 211, 247, 2, 213, 225, 211, 233, + 245, 211, 7, 5, 1, 211, 247, 2, 213, 225, 211, 233, 245, 211, 7, 6, 1, + 209, 29, 7, 5, 1, 209, 29, 7, 6, 1, 242, 203, 7, 5, 1, 242, 203, 7, 6, 1, + 232, 234, 7, 5, 1, 232, 234, 7, 6, 1, 247, 140, 7, 5, 1, 247, 140, 65, 1, + 209, 177, 7, 5, 1, 243, 228, 7, 5, 1, 229, 65, 7, 5, 1, 226, 90, 7, 5, 1, + 223, 180, 7, 5, 1, 218, 38, 7, 1, 5, 6, 218, 38, 7, 5, 1, 210, 159, 7, 5, + 1, 209, 241, 7, 6, 1, 233, 23, 246, 240, 7, 5, 1, 233, 23, 246, 240, 7, + 6, 1, 233, 23, 242, 139, 7, 5, 1, 233, 23, 242, 139, 7, 6, 1, 233, 23, + 241, 55, 7, 6, 1, 201, 233, 23, 241, 55, 7, 5, 1, 201, 233, 23, 241, 55, + 7, 6, 1, 201, 149, 7, 5, 1, 201, 149, 7, 6, 1, 233, 23, 137, 7, 5, 1, + 233, 23, 137, 7, 6, 1, 233, 23, 182, 7, 5, 1, 233, 23, 182, 7, 6, 1, 233, + 23, 213, 10, 7, 5, 1, 233, 23, 213, 10, 65, 1, 114, 247, 228, 253, 21, + 65, 1, 247, 162, 65, 1, 215, 144, 242, 242, 53, 7, 6, 1, 217, 163, 7, 5, + 1, 217, 163, 7, 6, 1, 201, 239, 155, 7, 5, 1, 230, 159, 2, 218, 230, 238, + 130, 23, 250, 24, 7, 6, 1, 226, 34, 2, 245, 211, 7, 5, 1, 226, 34, 2, + 245, 211, 7, 6, 1, 249, 35, 2, 134, 7, 5, 1, 249, 35, 2, 134, 7, 5, 1, + 249, 35, 2, 222, 26, 109, 7, 5, 1, 239, 156, 2, 222, 26, 109, 7, 6, 1, + 63, 2, 241, 174, 7, 5, 1, 63, 2, 241, 174, 7, 6, 1, 242, 140, 2, 91, 7, + 5, 1, 242, 140, 2, 91, 7, 6, 1, 208, 166, 252, 248, 7, 5, 1, 208, 166, + 252, 248, 7, 6, 1, 208, 166, 222, 206, 7, 5, 1, 208, 166, 222, 206, 7, 6, + 1, 208, 166, 210, 3, 7, 5, 1, 208, 166, 210, 3, 7, 6, 1, 241, 56, 2, 222, + 222, 91, 7, 5, 1, 241, 56, 2, 222, 222, 91, 7, 6, 1, 232, 77, 2, 222, + 222, 91, 7, 5, 1, 232, 77, 2, 222, 222, 91, 7, 6, 1, 226, 34, 2, 222, + 222, 91, 7, 5, 1, 226, 34, 2, 222, 222, 91, 7, 6, 1, 219, 150, 2, 222, + 222, 91, 7, 5, 1, 219, 150, 2, 222, 222, 91, 7, 6, 1, 218, 1, 2, 222, + 222, 91, 7, 5, 1, 218, 1, 2, 222, 222, 91, 7, 6, 1, 239, 156, 2, 109, 7, + 6, 1, 218, 224, 222, 142, 75, 7, 6, 1, 121, 241, 55, 7, 6, 1, 230, 159, + 2, 250, 24, 7, 6, 1, 201, 232, 76, 7, 6, 1, 201, 213, 10, 7, 242, 247, 1, + 215, 73, 74, 65, 1, 6, 239, 156, 2, 91, 65, 1, 5, 28, 222, 206, 7, 1, 5, + 6, 201, 229, 28, 7, 242, 247, 1, 218, 224, 242, 139, 7, 242, 247, 1, 218, + 224, 222, 67, 7, 242, 247, 1, 233, 2, 229, 28, 7, 242, 247, 1, 237, 225, + 229, 117, 7, 242, 247, 1, 252, 19, 229, 28, 213, 89, 225, 220, 1, 62, + 213, 89, 225, 220, 1, 74, 213, 89, 225, 220, 3, 243, 207, 213, 89, 225, + 220, 1, 71, 213, 89, 225, 220, 1, 75, 213, 89, 225, 220, 1, 76, 213, 89, + 225, 220, 3, 239, 88, 213, 89, 225, 220, 1, 231, 53, 213, 89, 225, 220, + 1, 231, 138, 213, 89, 225, 220, 1, 240, 19, 213, 89, 225, 220, 1, 240, + 71, 213, 89, 225, 220, 3, 252, 73, 213, 89, 225, 220, 1, 247, 174, 213, + 89, 225, 220, 1, 248, 32, 213, 89, 225, 220, 1, 232, 122, 213, 89, 225, + 220, 1, 232, 164, 213, 89, 225, 220, 1, 210, 185, 213, 89, 225, 220, 1, + 210, 191, 213, 89, 225, 220, 1, 246, 24, 213, 89, 225, 220, 1, 246, 33, + 213, 89, 225, 220, 1, 124, 213, 89, 225, 220, 1, 211, 253, 213, 89, 225, + 220, 1, 245, 51, 213, 89, 225, 220, 1, 245, 172, 213, 89, 225, 220, 1, + 224, 67, 213, 89, 225, 220, 1, 220, 211, 213, 89, 225, 220, 1, 221, 66, + 213, 89, 225, 220, 1, 249, 184, 213, 89, 225, 220, 1, 249, 248, 213, 89, + 225, 220, 1, 226, 181, 213, 89, 225, 220, 1, 218, 124, 213, 89, 225, 220, + 1, 229, 144, 213, 89, 225, 220, 1, 218, 75, 213, 89, 225, 220, 1, 214, + 193, 213, 89, 225, 220, 1, 238, 149, 213, 89, 225, 220, 22, 3, 62, 213, + 89, 225, 220, 22, 3, 74, 213, 89, 225, 220, 22, 3, 71, 213, 89, 225, 220, + 22, 3, 75, 213, 89, 225, 220, 22, 3, 222, 152, 213, 89, 225, 220, 220, + 206, 227, 191, 213, 89, 225, 220, 220, 206, 227, 190, 213, 89, 225, 220, + 220, 206, 227, 189, 213, 89, 225, 220, 220, 206, 227, 188, 143, 233, 51, + 241, 116, 119, 219, 204, 143, 233, 51, 241, 116, 119, 239, 121, 143, 233, + 51, 241, 116, 129, 219, 202, 143, 233, 51, 241, 116, 119, 215, 2, 143, + 233, 51, 241, 116, 119, 243, 83, 143, 233, 51, 241, 116, 129, 215, 1, + 143, 233, 51, 219, 205, 83, 143, 233, 51, 220, 238, 83, 143, 233, 51, + 218, 27, 83, 143, 233, 51, 219, 206, 83, 221, 89, 1, 172, 221, 89, 1, + 231, 167, 221, 89, 1, 240, 244, 221, 89, 1, 225, 77, 221, 89, 1, 249, 1, + 221, 89, 1, 248, 110, 221, 89, 1, 232, 200, 221, 89, 1, 223, 144, 221, + 89, 1, 212, 219, 221, 89, 1, 212, 56, 221, 89, 1, 246, 145, 221, 89, 1, + 199, 221, 89, 1, 179, 221, 89, 1, 221, 93, 221, 89, 1, 250, 183, 221, 89, + 1, 185, 221, 89, 1, 210, 243, 221, 89, 1, 210, 233, 221, 89, 1, 243, 196, + 221, 89, 1, 207, 96, 221, 89, 1, 205, 81, 221, 89, 1, 205, 116, 221, 89, + 1, 5, 62, 221, 89, 1, 190, 221, 89, 1, 219, 113, 221, 89, 1, 230, 141, + 221, 89, 1, 216, 2, 221, 89, 1, 217, 199, 221, 89, 1, 155, 221, 89, 1, + 62, 221, 89, 1, 74, 221, 89, 1, 71, 221, 89, 1, 75, 221, 89, 1, 76, 221, + 89, 1, 220, 19, 221, 89, 1, 206, 181, 221, 89, 1, 242, 73, 221, 89, 1, + 240, 135, 221, 89, 1, 243, 104, 221, 89, 213, 191, 1, 207, 96, 221, 89, + 213, 191, 1, 190, 221, 89, 1, 210, 208, 221, 89, 1, 210, 196, 221, 89, 1, + 246, 54, 221, 89, 1, 224, 103, 221, 89, 1, 252, 141, 190, 221, 89, 1, + 208, 169, 216, 2, 221, 89, 1, 208, 170, 155, 221, 89, 1, 251, 216, 242, + 73, 221, 89, 213, 191, 1, 219, 113, 221, 89, 213, 141, 1, 219, 113, 221, + 89, 1, 248, 217, 221, 89, 215, 41, 239, 69, 83, 221, 89, 50, 239, 69, 83, + 221, 89, 141, 215, 251, 221, 89, 141, 50, 215, 251, 217, 123, 3, 252, 73, + 217, 123, 3, 208, 183, 217, 123, 1, 62, 217, 123, 1, 253, 164, 217, 123, + 1, 74, 217, 123, 1, 233, 102, 217, 123, 1, 71, 217, 123, 1, 209, 162, + 217, 123, 1, 115, 137, 217, 123, 1, 115, 218, 90, 217, 123, 1, 115, 149, + 217, 123, 1, 115, 229, 173, 217, 123, 1, 75, 217, 123, 1, 243, 104, 217, + 123, 1, 252, 205, 217, 123, 1, 76, 217, 123, 1, 222, 152, 217, 123, 1, + 251, 184, 217, 123, 1, 172, 217, 123, 1, 231, 167, 217, 123, 1, 240, 244, + 217, 123, 1, 240, 99, 217, 123, 1, 225, 77, 217, 123, 1, 249, 1, 217, + 123, 1, 248, 110, 217, 123, 1, 232, 200, 217, 123, 1, 232, 170, 217, 123, + 1, 223, 144, 217, 123, 1, 210, 208, 217, 123, 1, 210, 196, 217, 123, 1, + 246, 54, 217, 123, 1, 246, 38, 217, 123, 1, 224, 103, 217, 123, 1, 212, + 219, 217, 123, 1, 212, 56, 217, 123, 1, 246, 145, 217, 123, 1, 245, 192, + 217, 123, 1, 199, 217, 123, 1, 179, 217, 123, 1, 221, 93, 217, 123, 1, + 250, 183, 217, 123, 1, 250, 0, 217, 123, 1, 185, 217, 123, 1, 190, 217, + 123, 1, 219, 113, 217, 123, 1, 230, 141, 217, 123, 1, 209, 70, 217, 123, + 1, 216, 2, 217, 123, 1, 214, 96, 217, 123, 1, 217, 199, 217, 123, 1, 155, + 217, 123, 1, 229, 172, 217, 123, 107, 3, 239, 139, 217, 123, 22, 3, 253, + 164, 217, 123, 22, 3, 74, 217, 123, 22, 3, 233, 102, 217, 123, 22, 3, 71, + 217, 123, 22, 3, 209, 162, 217, 123, 22, 3, 115, 137, 217, 123, 22, 3, + 115, 218, 90, 217, 123, 22, 3, 115, 149, 217, 123, 22, 3, 115, 229, 173, + 217, 123, 22, 3, 75, 217, 123, 22, 3, 243, 104, 217, 123, 22, 3, 252, + 205, 217, 123, 22, 3, 76, 217, 123, 22, 3, 222, 152, 217, 123, 22, 3, + 251, 184, 217, 123, 3, 208, 188, 217, 123, 246, 100, 217, 123, 50, 246, + 100, 217, 123, 18, 205, 85, 217, 123, 18, 102, 217, 123, 18, 105, 217, + 123, 18, 142, 217, 123, 18, 139, 217, 123, 18, 168, 217, 123, 18, 184, + 217, 123, 18, 195, 217, 123, 18, 193, 217, 123, 18, 200, 36, 89, 18, 205, + 85, 36, 89, 18, 102, 36, 89, 18, 105, 36, 89, 18, 142, 36, 89, 18, 139, + 36, 89, 18, 168, 36, 89, 18, 184, 36, 89, 18, 195, 36, 89, 18, 193, 36, + 89, 18, 200, 36, 89, 1, 62, 36, 89, 1, 71, 36, 89, 1, 172, 36, 89, 1, + 199, 36, 89, 1, 179, 36, 89, 1, 219, 113, 36, 89, 1, 208, 214, 36, 89, 3, + 251, 167, 89, 3, 214, 152, 248, 217, 89, 3, 248, 218, 208, 188, 89, 3, + 50, 248, 218, 208, 188, 89, 3, 248, 218, 105, 89, 3, 248, 218, 142, 89, + 3, 248, 218, 251, 167, 89, 3, 220, 55, 89, 240, 208, 241, 232, 89, 248, + 199, 89, 239, 63, 231, 230, 229, 236, 18, 205, 85, 231, 230, 229, 236, + 18, 102, 231, 230, 229, 236, 18, 105, 231, 230, 229, 236, 18, 142, 231, + 230, 229, 236, 18, 139, 231, 230, 229, 236, 18, 168, 231, 230, 229, 236, + 18, 184, 231, 230, 229, 236, 18, 195, 231, 230, 229, 236, 18, 193, 231, + 230, 229, 236, 18, 200, 231, 230, 229, 236, 1, 172, 231, 230, 229, 236, + 1, 231, 167, 231, 230, 229, 236, 1, 240, 244, 231, 230, 229, 236, 1, 225, + 77, 231, 230, 229, 236, 1, 217, 199, 231, 230, 229, 236, 1, 216, 2, 231, + 230, 229, 236, 1, 205, 116, 231, 230, 229, 236, 1, 223, 144, 231, 230, + 229, 236, 1, 212, 219, 231, 230, 229, 236, 1, 238, 46, 231, 230, 229, + 236, 1, 199, 231, 230, 229, 236, 1, 179, 231, 230, 229, 236, 1, 221, 93, + 231, 230, 229, 236, 1, 185, 231, 230, 229, 236, 1, 246, 145, 231, 230, + 229, 236, 1, 250, 183, 231, 230, 229, 236, 1, 219, 113, 231, 230, 229, + 236, 1, 190, 231, 230, 229, 236, 1, 230, 141, 231, 230, 229, 236, 1, 207, + 96, 231, 230, 229, 236, 1, 212, 56, 231, 230, 229, 236, 1, 155, 231, 230, + 229, 236, 1, 209, 70, 231, 230, 229, 236, 1, 249, 1, 231, 230, 229, 236, + 1, 62, 231, 230, 229, 236, 1, 222, 206, 231, 230, 229, 236, 1, 74, 231, + 230, 229, 236, 1, 222, 152, 231, 230, 229, 236, 22, 210, 3, 231, 230, + 229, 236, 22, 75, 231, 230, 229, 236, 22, 71, 231, 230, 229, 236, 22, + 243, 104, 231, 230, 229, 236, 22, 76, 231, 230, 229, 236, 135, 220, 226, + 231, 230, 229, 236, 135, 248, 233, 231, 230, 229, 236, 135, 248, 234, + 220, 226, 231, 230, 229, 236, 3, 247, 3, 231, 230, 229, 236, 3, 215, 88, + 219, 13, 1, 172, 219, 13, 1, 240, 244, 219, 13, 1, 225, 77, 219, 13, 1, + 212, 219, 219, 13, 1, 246, 145, 219, 13, 1, 199, 219, 13, 1, 179, 219, + 13, 1, 250, 183, 219, 13, 1, 185, 219, 13, 1, 249, 1, 219, 13, 1, 232, + 200, 219, 13, 1, 223, 144, 219, 13, 1, 217, 199, 219, 13, 1, 219, 113, + 219, 13, 1, 230, 141, 219, 13, 1, 190, 219, 13, 1, 207, 96, 219, 13, 1, + 155, 219, 13, 1, 227, 153, 219, 13, 1, 225, 56, 219, 13, 1, 225, 151, + 219, 13, 1, 223, 111, 219, 13, 1, 62, 219, 13, 22, 3, 74, 219, 13, 22, 3, + 71, 219, 13, 22, 3, 75, 219, 13, 22, 3, 252, 205, 219, 13, 22, 3, 76, + 219, 13, 22, 3, 251, 184, 219, 13, 22, 3, 242, 192, 219, 13, 22, 3, 243, + 130, 219, 13, 107, 3, 225, 79, 219, 13, 107, 3, 226, 33, 219, 13, 107, 3, + 137, 219, 13, 107, 3, 239, 155, 219, 13, 208, 188, 219, 13, 217, 77, 83, + 25, 113, 211, 189, 25, 113, 211, 188, 25, 113, 211, 186, 25, 113, 211, + 191, 25, 113, 218, 193, 25, 113, 218, 177, 25, 113, 218, 172, 25, 113, + 218, 174, 25, 113, 218, 190, 25, 113, 218, 183, 25, 113, 218, 176, 25, + 113, 218, 195, 25, 113, 218, 178, 25, 113, 218, 197, 25, 113, 218, 194, + 25, 113, 226, 236, 25, 113, 226, 227, 25, 113, 226, 230, 25, 113, 221, + 24, 25, 113, 221, 35, 25, 113, 221, 36, 25, 113, 214, 80, 25, 113, 233, + 115, 25, 113, 233, 122, 25, 113, 214, 91, 25, 113, 214, 78, 25, 113, 221, + 75, 25, 113, 238, 254, 25, 113, 214, 75, 176, 3, 221, 242, 176, 3, 248, + 145, 176, 3, 230, 66, 176, 3, 207, 13, 176, 1, 62, 176, 1, 237, 225, 231, + 234, 176, 1, 74, 176, 1, 233, 102, 176, 1, 71, 176, 1, 222, 52, 248, 116, + 176, 1, 225, 78, 230, 25, 176, 1, 225, 78, 230, 26, 219, 66, 176, 1, 75, + 176, 1, 252, 205, 176, 1, 76, 176, 1, 172, 176, 1, 232, 66, 217, 135, + 176, 1, 232, 66, 226, 75, 176, 1, 240, 244, 176, 1, 240, 245, 226, 75, + 176, 1, 225, 77, 176, 1, 249, 1, 176, 1, 249, 2, 226, 75, 176, 1, 232, + 200, 176, 1, 223, 145, 226, 75, 176, 1, 232, 201, 227, 243, 176, 1, 223, + 144, 176, 1, 210, 208, 176, 1, 210, 209, 227, 243, 176, 1, 246, 54, 176, + 1, 246, 55, 227, 243, 176, 1, 225, 237, 226, 75, 176, 1, 212, 219, 176, + 1, 212, 220, 226, 75, 176, 1, 246, 145, 176, 1, 246, 146, 227, 243, 176, + 1, 199, 176, 1, 179, 176, 1, 222, 52, 226, 75, 176, 1, 250, 183, 176, 1, + 250, 184, 226, 75, 176, 1, 185, 176, 1, 190, 176, 1, 219, 113, 176, 1, + 219, 114, 252, 214, 176, 1, 230, 141, 176, 1, 207, 96, 176, 1, 217, 200, + 226, 75, 176, 1, 217, 200, 227, 243, 176, 1, 217, 199, 176, 1, 155, 176, + 3, 248, 146, 212, 101, 176, 22, 3, 212, 158, 176, 22, 3, 211, 123, 176, + 22, 3, 206, 210, 176, 22, 3, 206, 211, 227, 94, 176, 22, 3, 213, 164, + 176, 22, 3, 213, 165, 227, 82, 176, 22, 3, 212, 179, 176, 22, 3, 245, + 101, 226, 74, 176, 22, 3, 221, 134, 176, 107, 3, 231, 196, 176, 107, 3, + 221, 147, 176, 107, 3, 248, 242, 176, 221, 255, 176, 47, 218, 244, 176, + 48, 218, 244, 176, 222, 41, 252, 116, 176, 222, 41, 228, 5, 176, 222, 41, + 229, 69, 176, 222, 41, 207, 7, 176, 222, 41, 222, 0, 176, 222, 41, 229, + 197, 176, 222, 41, 229, 63, 176, 222, 41, 252, 255, 176, 222, 41, 253, 0, + 252, 255, 176, 222, 41, 220, 249, 176, 201, 222, 41, 220, 249, 176, 221, + 251, 176, 18, 205, 85, 176, 18, 102, 176, 18, 105, 176, 18, 142, 176, 18, + 139, 176, 18, 168, 176, 18, 184, 176, 18, 195, 176, 18, 193, 176, 18, + 200, 176, 222, 41, 211, 158, 210, 157, 176, 222, 41, 232, 230, 66, 1, + 215, 238, 240, 99, 66, 1, 215, 238, 248, 110, 66, 1, 215, 238, 232, 170, + 66, 1, 215, 238, 224, 103, 66, 1, 215, 238, 250, 0, 66, 3, 215, 238, 217, + 121, 66, 65, 1, 215, 238, 219, 30, 66, 1, 41, 230, 113, 223, 144, 66, 1, + 41, 230, 113, 242, 73, 66, 1, 41, 230, 113, 240, 244, 66, 1, 41, 230, + 113, 240, 99, 66, 1, 41, 230, 113, 232, 200, 66, 1, 41, 230, 113, 232, + 170, 66, 1, 41, 230, 113, 246, 54, 66, 1, 41, 230, 113, 246, 38, 66, 1, + 41, 230, 113, 224, 103, 66, 41, 230, 113, 18, 205, 85, 66, 41, 230, 113, + 18, 102, 66, 41, 230, 113, 18, 105, 66, 41, 230, 113, 18, 142, 66, 41, + 230, 113, 18, 139, 66, 41, 230, 113, 18, 168, 66, 41, 230, 113, 18, 184, + 66, 41, 230, 113, 18, 195, 66, 41, 230, 113, 18, 193, 66, 41, 230, 113, + 18, 200, 66, 1, 41, 230, 113, 229, 172, 66, 1, 41, 230, 113, 246, 145, + 66, 1, 41, 230, 113, 245, 192, 66, 1, 41, 230, 113, 250, 183, 66, 1, 41, + 230, 113, 250, 0, 203, 1, 62, 203, 1, 74, 203, 1, 71, 203, 1, 75, 203, 1, + 252, 205, 203, 1, 76, 203, 1, 172, 203, 1, 231, 167, 203, 1, 240, 244, + 203, 1, 240, 99, 203, 1, 224, 242, 203, 1, 225, 77, 203, 1, 248, 110, + 203, 1, 248, 60, 203, 1, 232, 200, 203, 1, 232, 170, 203, 1, 224, 232, + 203, 1, 224, 234, 203, 1, 224, 233, 203, 1, 212, 219, 203, 1, 212, 56, + 203, 1, 246, 145, 203, 1, 245, 192, 203, 1, 223, 186, 203, 1, 199, 203, + 1, 246, 54, 203, 1, 179, 203, 1, 220, 157, 203, 1, 221, 93, 203, 1, 250, + 183, 203, 1, 250, 0, 203, 1, 226, 106, 203, 1, 185, 203, 1, 250, 97, 203, + 1, 190, 203, 1, 219, 113, 203, 1, 230, 141, 203, 1, 209, 70, 203, 1, 214, + 96, 203, 1, 217, 199, 203, 1, 155, 203, 22, 3, 253, 164, 203, 22, 3, 74, + 203, 22, 3, 233, 102, 203, 22, 3, 243, 90, 203, 22, 3, 71, 203, 22, 3, + 222, 206, 203, 22, 3, 76, 203, 22, 3, 252, 205, 203, 22, 3, 251, 184, + 203, 22, 3, 210, 3, 203, 107, 3, 190, 203, 107, 3, 219, 113, 203, 107, 3, + 230, 141, 203, 107, 3, 207, 96, 203, 1, 42, 232, 76, 203, 1, 42, 241, 55, + 203, 1, 42, 225, 79, 203, 107, 3, 42, 225, 79, 203, 1, 42, 248, 111, 203, + 1, 42, 213, 10, 203, 1, 42, 226, 33, 203, 1, 42, 222, 67, 203, 1, 42, + 206, 123, 203, 1, 42, 137, 203, 1, 42, 149, 203, 1, 42, 214, 99, 203, + 107, 3, 42, 229, 28, 203, 107, 3, 42, 239, 155, 203, 18, 205, 85, 203, + 18, 102, 203, 18, 105, 203, 18, 142, 203, 18, 139, 203, 18, 168, 203, 18, + 184, 203, 18, 195, 203, 18, 193, 203, 18, 200, 203, 220, 72, 214, 127, + 203, 220, 72, 246, 100, 203, 220, 72, 50, 246, 100, 203, 220, 72, 211, + 36, 246, 100, 66, 1, 231, 160, 240, 244, 66, 1, 231, 160, 249, 1, 66, 1, + 231, 160, 248, 110, 66, 1, 231, 160, 232, 200, 66, 1, 231, 160, 232, 170, + 66, 1, 231, 160, 223, 144, 66, 1, 231, 160, 210, 208, 66, 1, 231, 160, + 210, 196, 66, 1, 231, 160, 246, 54, 66, 1, 231, 160, 246, 38, 66, 1, 231, + 160, 245, 192, 66, 1, 231, 160, 199, 66, 1, 231, 160, 217, 199, 66, 1, + 231, 160, 155, 66, 1, 231, 160, 239, 20, 66, 1, 231, 160, 242, 73, 66, + 65, 1, 231, 160, 219, 30, 66, 1, 231, 160, 206, 181, 66, 1, 231, 160, + 205, 116, 66, 1, 231, 160, 219, 113, 66, 229, 133, 231, 160, 222, 227, + 66, 229, 133, 231, 160, 219, 227, 66, 229, 133, 231, 160, 238, 204, 66, + 16, 252, 193, 242, 167, 66, 16, 252, 193, 102, 66, 16, 252, 193, 105, 66, + 1, 252, 193, 219, 113, 66, 3, 221, 238, 232, 4, 211, 118, 66, 3, 41, 230, + 113, 211, 116, 66, 3, 41, 230, 113, 211, 113, 66, 1, 215, 96, 222, 23, + 248, 110, 66, 1, 215, 96, 222, 23, 216, 2, 41, 208, 204, 1, 114, 231, 53, + 41, 208, 204, 1, 127, 231, 53, 41, 208, 204, 1, 114, 231, 138, 41, 208, + 204, 1, 127, 231, 138, 41, 208, 204, 1, 114, 231, 147, 41, 208, 204, 1, + 127, 231, 147, 41, 208, 204, 1, 114, 240, 19, 41, 208, 204, 1, 127, 240, + 19, 41, 208, 204, 1, 114, 225, 2, 41, 208, 204, 1, 127, 225, 2, 41, 208, + 204, 1, 114, 247, 174, 41, 208, 204, 1, 127, 247, 174, 41, 208, 204, 1, + 114, 248, 32, 41, 208, 204, 1, 127, 248, 32, 41, 208, 204, 1, 114, 214, + 193, 41, 208, 204, 1, 127, 214, 193, 41, 208, 204, 1, 114, 223, 110, 41, + 208, 204, 1, 127, 223, 110, 41, 208, 204, 1, 114, 245, 51, 41, 208, 204, + 1, 127, 245, 51, 41, 208, 204, 1, 114, 124, 41, 208, 204, 1, 127, 124, + 41, 208, 204, 1, 114, 211, 253, 41, 208, 204, 1, 127, 211, 253, 41, 208, + 204, 1, 114, 224, 67, 41, 208, 204, 1, 127, 224, 67, 41, 208, 204, 1, + 114, 249, 184, 41, 208, 204, 1, 127, 249, 184, 41, 208, 204, 1, 114, 220, + 211, 41, 208, 204, 1, 127, 220, 211, 41, 208, 204, 1, 114, 221, 66, 41, + 208, 204, 1, 127, 221, 66, 41, 208, 204, 1, 114, 241, 162, 41, 208, 204, + 1, 127, 241, 162, 41, 208, 204, 1, 114, 226, 181, 41, 208, 204, 1, 127, + 226, 181, 41, 208, 204, 1, 114, 205, 247, 41, 208, 204, 1, 127, 205, 247, + 41, 208, 204, 1, 114, 218, 124, 41, 208, 204, 1, 127, 218, 124, 41, 208, + 204, 1, 114, 229, 144, 41, 208, 204, 1, 127, 229, 144, 41, 208, 204, 1, + 114, 208, 173, 41, 208, 204, 1, 127, 208, 173, 41, 208, 204, 1, 114, 238, + 149, 41, 208, 204, 1, 127, 238, 149, 41, 208, 204, 1, 114, 76, 41, 208, + 204, 1, 127, 76, 41, 208, 204, 227, 240, 232, 23, 41, 208, 204, 22, 253, + 164, 41, 208, 204, 22, 74, 41, 208, 204, 22, 210, 3, 41, 208, 204, 22, + 71, 41, 208, 204, 22, 75, 41, 208, 204, 22, 76, 41, 208, 204, 227, 240, + 231, 141, 41, 208, 204, 22, 237, 190, 41, 208, 204, 22, 210, 2, 41, 208, + 204, 22, 210, 18, 41, 208, 204, 22, 251, 182, 41, 208, 204, 22, 251, 159, + 41, 208, 204, 22, 252, 122, 41, 208, 204, 22, 252, 136, 41, 208, 204, + 135, 227, 240, 243, 75, 41, 208, 204, 135, 227, 240, 223, 185, 41, 208, + 204, 135, 227, 240, 211, 253, 41, 208, 204, 135, 227, 240, 214, 176, 41, + 208, 204, 16, 231, 36, 41, 208, 204, 16, 223, 185, 41, 208, 204, 16, 217, + 161, 41, 208, 204, 16, 238, 150, 238, 145, 41, 208, 204, 16, 231, 46, + 231, 45, 227, 101, 227, 160, 1, 75, 227, 101, 227, 160, 1, 76, 227, 101, + 227, 160, 1, 248, 110, 227, 101, 227, 160, 1, 223, 144, 227, 101, 227, + 160, 1, 210, 208, 227, 101, 227, 160, 1, 210, 196, 227, 101, 227, 160, 1, + 246, 54, 227, 101, 227, 160, 1, 246, 38, 227, 101, 227, 160, 1, 224, 103, + 227, 101, 227, 160, 1, 216, 2, 227, 101, 227, 160, 1, 214, 96, 227, 101, + 227, 160, 22, 3, 233, 102, 227, 101, 227, 160, 22, 3, 209, 162, 227, 101, + 227, 160, 22, 3, 253, 128, 227, 101, 227, 160, 22, 3, 251, 184, 227, 101, + 227, 160, 22, 3, 253, 121, 227, 101, 227, 160, 248, 74, 227, 101, 227, + 160, 252, 210, 231, 130, 227, 101, 227, 160, 252, 102, 227, 101, 227, + 160, 4, 218, 249, 83, 227, 101, 227, 160, 206, 232, 218, 249, 83, 227, + 101, 227, 160, 22, 3, 208, 183, 227, 101, 227, 160, 208, 188, 31, 4, 210, + 189, 31, 4, 210, 192, 31, 4, 210, 195, 31, 4, 210, 193, 31, 4, 210, 194, + 31, 4, 210, 191, 31, 4, 246, 32, 31, 4, 246, 34, 31, 4, 246, 37, 31, 4, + 246, 35, 31, 4, 246, 36, 31, 4, 246, 33, 31, 4, 243, 183, 31, 4, 243, + 187, 31, 4, 243, 195, 31, 4, 243, 192, 31, 4, 243, 193, 31, 4, 243, 184, + 31, 4, 248, 162, 31, 4, 248, 156, 31, 4, 248, 158, 31, 4, 248, 161, 31, + 4, 248, 159, 31, 4, 248, 160, 31, 4, 248, 157, 31, 4, 250, 97, 31, 4, + 250, 76, 31, 4, 250, 88, 31, 4, 250, 96, 31, 4, 250, 91, 31, 4, 250, 92, + 31, 4, 250, 80, 7, 5, 1, 250, 123, 252, 144, 7, 5, 1, 32, 218, 222, 7, 5, + 1, 249, 198, 75, 7, 5, 1, 250, 123, 75, 7, 5, 1, 174, 2, 241, 174, 7, 5, + 1, 230, 18, 242, 139, 7, 5, 1, 121, 241, 56, 2, 247, 56, 7, 5, 1, 230, + 159, 2, 233, 2, 230, 65, 182, 7, 5, 1, 230, 159, 2, 50, 226, 247, 211, + 180, 7, 5, 1, 230, 159, 2, 226, 247, 218, 148, 7, 5, 1, 229, 29, 2, 247, + 56, 7, 5, 1, 226, 34, 2, 247, 56, 7, 5, 1, 243, 29, 2, 247, 56, 7, 5, 1, + 249, 198, 76, 7, 5, 1, 249, 198, 148, 2, 91, 7, 5, 1, 222, 142, 148, 2, + 91, 7, 5, 1, 233, 2, 222, 206, 7, 5, 1, 201, 222, 207, 2, 91, 7, 5, 1, + 201, 222, 207, 2, 194, 91, 7, 5, 1, 201, 148, 222, 138, 7, 5, 1, 201, + 148, 222, 139, 2, 91, 7, 5, 1, 214, 0, 137, 7, 1, 5, 6, 219, 150, 2, 48, + 230, 34, 7, 5, 1, 219, 150, 206, 253, 239, 105, 7, 5, 1, 50, 137, 7, 5, + 1, 219, 150, 2, 247, 56, 7, 5, 1, 50, 219, 150, 2, 247, 56, 7, 5, 1, 121, + 137, 7, 5, 1, 121, 219, 150, 2, 218, 148, 7, 5, 1, 250, 114, 242, 215, 7, + 5, 1, 106, 2, 215, 144, 48, 230, 34, 7, 5, 1, 106, 250, 129, 2, 215, 144, + 48, 230, 34, 7, 5, 1, 209, 252, 7, 5, 1, 201, 209, 252, 7, 5, 1, 106, 2, + 47, 109, 7, 5, 1, 248, 58, 7, 5, 1, 248, 59, 2, 114, 48, 218, 148, 7, 5, + 1, 248, 59, 2, 114, 47, 216, 36, 7, 5, 1, 206, 196, 2, 114, 48, 218, 148, + 7, 5, 1, 206, 196, 2, 152, 47, 230, 34, 7, 5, 1, 206, 196, 2, 152, 47, + 230, 35, 23, 114, 48, 218, 148, 7, 5, 1, 206, 196, 2, 152, 47, 230, 35, + 2, 216, 36, 7, 5, 1, 206, 124, 2, 215, 144, 48, 230, 34, 65, 249, 123, 2, + 233, 2, 249, 122, 65, 1, 5, 239, 39, 65, 1, 5, 230, 159, 2, 233, 2, 230, + 65, 182, 65, 1, 5, 230, 159, 2, 226, 247, 211, 180, 65, 1, 5, 106, 2, 47, + 109, 7, 5, 1, 233, 2, 252, 144, 27, 1, 5, 6, 222, 170, 227, 101, 227, + 160, 1, 231, 43, 227, 101, 227, 160, 1, 217, 161, 227, 101, 227, 160, 1, + 230, 114, 227, 101, 227, 160, 1, 226, 192, 227, 101, 227, 160, 1, 179, + 227, 101, 227, 160, 1, 199, 227, 101, 227, 160, 1, 248, 50, 227, 101, + 227, 160, 1, 211, 182, 227, 101, 227, 160, 1, 231, 133, 227, 101, 227, + 160, 1, 224, 248, 227, 101, 227, 160, 1, 211, 245, 227, 101, 227, 160, 1, + 207, 90, 227, 101, 227, 160, 1, 206, 75, 227, 101, 227, 160, 1, 238, 35, + 227, 101, 227, 160, 1, 209, 234, 227, 101, 227, 160, 1, 74, 227, 101, + 227, 160, 1, 221, 87, 227, 101, 227, 160, 1, 251, 195, 227, 101, 227, + 160, 1, 240, 12, 227, 101, 227, 160, 1, 232, 168, 227, 101, 227, 160, 1, + 219, 90, 227, 101, 227, 160, 1, 250, 183, 227, 101, 227, 160, 1, 232, + 154, 227, 101, 227, 160, 1, 245, 126, 227, 101, 227, 160, 1, 240, 68, + 227, 101, 227, 160, 1, 245, 170, 227, 101, 227, 160, 1, 249, 254, 227, + 101, 227, 160, 1, 231, 44, 229, 116, 227, 101, 227, 160, 1, 230, 115, + 229, 116, 227, 101, 227, 160, 1, 226, 193, 229, 116, 227, 101, 227, 160, + 1, 222, 52, 229, 116, 227, 101, 227, 160, 1, 225, 237, 229, 116, 227, + 101, 227, 160, 1, 211, 183, 229, 116, 227, 101, 227, 160, 1, 224, 249, + 229, 116, 227, 101, 227, 160, 1, 237, 225, 229, 116, 227, 101, 227, 160, + 22, 3, 222, 164, 227, 101, 227, 160, 22, 3, 233, 66, 227, 101, 227, 160, + 22, 3, 252, 121, 227, 101, 227, 160, 22, 3, 206, 41, 227, 101, 227, 160, + 22, 3, 214, 166, 227, 101, 227, 160, 22, 3, 209, 231, 227, 101, 227, 160, + 22, 3, 248, 72, 227, 101, 227, 160, 22, 3, 223, 170, 227, 101, 227, 160, + 248, 73, 227, 101, 227, 160, 229, 66, 232, 209, 227, 101, 227, 160, 252, + 42, 232, 209, 227, 101, 227, 160, 18, 205, 85, 227, 101, 227, 160, 18, + 102, 227, 101, 227, 160, 18, 105, 227, 101, 227, 160, 18, 142, 227, 101, + 227, 160, 18, 139, 227, 101, 227, 160, 18, 168, 227, 101, 227, 160, 18, + 184, 227, 101, 227, 160, 18, 195, 227, 101, 227, 160, 18, 193, 227, 101, + 227, 160, 18, 200, 25, 162, 223, 51, 25, 162, 223, 56, 25, 162, 205, 246, + 25, 162, 205, 245, 25, 162, 205, 244, 25, 162, 210, 68, 25, 162, 210, 72, + 25, 162, 205, 211, 25, 162, 205, 207, 25, 162, 242, 191, 25, 162, 242, + 189, 25, 162, 242, 190, 25, 162, 242, 187, 25, 162, 237, 215, 25, 162, + 237, 214, 25, 162, 237, 212, 25, 162, 237, 213, 25, 162, 237, 218, 25, + 162, 237, 211, 25, 162, 237, 210, 25, 162, 237, 220, 25, 162, 252, 29, + 25, 162, 252, 28, 25, 100, 224, 216, 25, 100, 224, 222, 25, 100, 214, 77, + 25, 100, 214, 76, 25, 100, 211, 188, 25, 100, 211, 186, 25, 100, 211, + 185, 25, 100, 211, 191, 25, 100, 211, 192, 25, 100, 211, 184, 25, 100, + 218, 177, 25, 100, 218, 192, 25, 100, 214, 83, 25, 100, 218, 189, 25, + 100, 218, 179, 25, 100, 218, 181, 25, 100, 218, 168, 25, 100, 218, 169, + 25, 100, 232, 10, 25, 100, 226, 235, 25, 100, 226, 229, 25, 100, 214, 87, + 25, 100, 226, 232, 25, 100, 226, 238, 25, 100, 221, 20, 25, 100, 221, 29, + 25, 100, 221, 33, 25, 100, 214, 85, 25, 100, 221, 23, 25, 100, 221, 37, + 25, 100, 221, 38, 25, 100, 215, 25, 25, 100, 215, 28, 25, 100, 214, 81, + 25, 100, 214, 79, 25, 100, 215, 23, 25, 100, 215, 31, 25, 100, 215, 32, + 25, 100, 215, 17, 25, 100, 215, 30, 25, 100, 221, 245, 25, 100, 221, 246, + 25, 100, 206, 27, 25, 100, 206, 28, 25, 100, 247, 244, 25, 100, 247, 243, + 25, 100, 214, 92, 25, 100, 221, 73, 25, 100, 221, 72, 10, 15, 235, 93, + 10, 15, 235, 92, 10, 15, 235, 91, 10, 15, 235, 90, 10, 15, 235, 89, 10, + 15, 235, 88, 10, 15, 235, 87, 10, 15, 235, 86, 10, 15, 235, 85, 10, 15, + 235, 84, 10, 15, 235, 83, 10, 15, 235, 82, 10, 15, 235, 81, 10, 15, 235, + 80, 10, 15, 235, 79, 10, 15, 235, 78, 10, 15, 235, 77, 10, 15, 235, 76, + 10, 15, 235, 75, 10, 15, 235, 74, 10, 15, 235, 73, 10, 15, 235, 72, 10, + 15, 235, 71, 10, 15, 235, 70, 10, 15, 235, 69, 10, 15, 235, 68, 10, 15, + 235, 67, 10, 15, 235, 66, 10, 15, 235, 65, 10, 15, 235, 64, 10, 15, 235, + 63, 10, 15, 235, 62, 10, 15, 235, 61, 10, 15, 235, 60, 10, 15, 235, 59, + 10, 15, 235, 58, 10, 15, 235, 57, 10, 15, 235, 56, 10, 15, 235, 55, 10, + 15, 235, 54, 10, 15, 235, 53, 10, 15, 235, 52, 10, 15, 235, 51, 10, 15, + 235, 50, 10, 15, 235, 49, 10, 15, 235, 48, 10, 15, 235, 47, 10, 15, 235, + 46, 10, 15, 235, 45, 10, 15, 235, 44, 10, 15, 235, 43, 10, 15, 235, 42, + 10, 15, 235, 41, 10, 15, 235, 40, 10, 15, 235, 39, 10, 15, 235, 38, 10, + 15, 235, 37, 10, 15, 235, 36, 10, 15, 235, 35, 10, 15, 235, 34, 10, 15, + 235, 33, 10, 15, 235, 32, 10, 15, 235, 31, 10, 15, 235, 30, 10, 15, 235, + 29, 10, 15, 235, 28, 10, 15, 235, 27, 10, 15, 235, 26, 10, 15, 235, 25, + 10, 15, 235, 24, 10, 15, 235, 23, 10, 15, 235, 22, 10, 15, 235, 21, 10, + 15, 235, 20, 10, 15, 235, 19, 10, 15, 235, 18, 10, 15, 235, 17, 10, 15, + 235, 16, 10, 15, 235, 15, 10, 15, 235, 14, 10, 15, 235, 13, 10, 15, 235, + 12, 10, 15, 235, 11, 10, 15, 235, 10, 10, 15, 235, 9, 10, 15, 235, 8, 10, + 15, 235, 7, 10, 15, 235, 6, 10, 15, 235, 5, 10, 15, 235, 4, 10, 15, 235, + 3, 10, 15, 235, 2, 10, 15, 235, 1, 10, 15, 235, 0, 10, 15, 234, 255, 10, + 15, 234, 254, 10, 15, 234, 253, 10, 15, 234, 252, 10, 15, 234, 251, 10, + 15, 234, 250, 10, 15, 234, 249, 10, 15, 234, 248, 10, 15, 234, 247, 10, + 15, 234, 246, 10, 15, 234, 245, 10, 15, 234, 244, 10, 15, 234, 243, 10, + 15, 234, 242, 10, 15, 234, 241, 10, 15, 234, 240, 10, 15, 234, 239, 10, + 15, 234, 238, 10, 15, 234, 237, 10, 15, 234, 236, 10, 15, 234, 235, 10, + 15, 234, 234, 10, 15, 234, 233, 10, 15, 234, 232, 10, 15, 234, 231, 10, + 15, 234, 230, 10, 15, 234, 229, 10, 15, 234, 228, 10, 15, 234, 227, 10, + 15, 234, 226, 10, 15, 234, 225, 10, 15, 234, 224, 10, 15, 234, 223, 10, + 15, 234, 222, 10, 15, 234, 221, 10, 15, 234, 220, 10, 15, 234, 219, 10, + 15, 234, 218, 10, 15, 234, 217, 10, 15, 234, 216, 10, 15, 234, 215, 10, + 15, 234, 214, 10, 15, 234, 213, 10, 15, 234, 212, 10, 15, 234, 211, 10, + 15, 234, 210, 10, 15, 234, 209, 10, 15, 234, 208, 10, 15, 234, 207, 10, + 15, 234, 206, 10, 15, 234, 205, 10, 15, 234, 204, 10, 15, 234, 203, 10, + 15, 234, 202, 10, 15, 234, 201, 10, 15, 234, 200, 10, 15, 234, 199, 10, + 15, 234, 198, 10, 15, 234, 197, 10, 15, 234, 196, 10, 15, 234, 195, 10, + 15, 234, 194, 10, 15, 234, 193, 10, 15, 234, 192, 10, 15, 234, 191, 10, + 15, 234, 190, 10, 15, 234, 189, 10, 15, 234, 188, 10, 15, 234, 187, 10, + 15, 234, 186, 10, 15, 234, 185, 10, 15, 234, 184, 10, 15, 234, 183, 10, + 15, 234, 182, 10, 15, 234, 181, 10, 15, 234, 180, 10, 15, 234, 179, 10, + 15, 234, 178, 10, 15, 234, 177, 10, 15, 234, 176, 10, 15, 234, 175, 10, + 15, 234, 174, 10, 15, 234, 173, 10, 15, 234, 172, 10, 15, 234, 171, 10, + 15, 234, 170, 10, 15, 234, 169, 10, 15, 234, 168, 10, 15, 234, 167, 10, + 15, 234, 166, 10, 15, 234, 165, 10, 15, 234, 164, 10, 15, 234, 163, 10, + 15, 234, 162, 10, 15, 234, 161, 10, 15, 234, 160, 10, 15, 234, 159, 10, + 15, 234, 158, 10, 15, 234, 157, 10, 15, 234, 156, 10, 15, 234, 155, 10, + 15, 234, 154, 10, 15, 234, 153, 10, 15, 234, 152, 10, 15, 234, 151, 10, + 15, 234, 150, 10, 15, 234, 149, 10, 15, 234, 148, 10, 15, 234, 147, 10, + 15, 234, 146, 10, 15, 234, 145, 10, 15, 234, 144, 10, 15, 234, 143, 10, + 15, 234, 142, 10, 15, 234, 141, 10, 15, 234, 140, 10, 15, 234, 139, 10, + 15, 234, 138, 10, 15, 234, 137, 10, 15, 234, 136, 10, 15, 234, 135, 10, + 15, 234, 134, 10, 15, 234, 133, 10, 15, 234, 132, 10, 15, 234, 131, 10, + 15, 234, 130, 10, 15, 234, 129, 10, 15, 234, 128, 10, 15, 234, 127, 10, + 15, 234, 126, 10, 15, 234, 125, 10, 15, 234, 124, 10, 15, 234, 123, 10, + 15, 234, 122, 10, 15, 234, 121, 10, 15, 234, 120, 10, 15, 234, 119, 10, + 15, 234, 118, 10, 15, 234, 117, 10, 15, 234, 116, 10, 15, 234, 115, 10, + 15, 234, 114, 10, 15, 234, 113, 10, 15, 234, 112, 10, 15, 234, 111, 10, + 15, 234, 110, 10, 15, 234, 109, 10, 15, 234, 108, 10, 15, 234, 107, 10, + 15, 234, 106, 10, 15, 234, 105, 10, 15, 234, 104, 10, 15, 234, 103, 10, + 15, 234, 102, 10, 15, 234, 101, 10, 15, 234, 100, 10, 15, 234, 99, 10, + 15, 234, 98, 10, 15, 234, 97, 10, 15, 234, 96, 10, 15, 234, 95, 10, 15, + 234, 94, 10, 15, 234, 93, 10, 15, 234, 92, 10, 15, 234, 91, 10, 15, 234, + 90, 10, 15, 234, 89, 10, 15, 234, 88, 10, 15, 234, 87, 10, 15, 234, 86, + 10, 15, 234, 85, 10, 15, 234, 84, 10, 15, 234, 83, 10, 15, 234, 82, 10, + 15, 234, 81, 10, 15, 234, 80, 10, 15, 234, 79, 10, 15, 234, 78, 10, 15, + 234, 77, 10, 15, 234, 76, 10, 15, 234, 75, 10, 15, 234, 74, 10, 15, 234, + 73, 10, 15, 234, 72, 10, 15, 234, 71, 10, 15, 234, 70, 10, 15, 234, 69, + 10, 15, 234, 68, 10, 15, 234, 67, 10, 15, 234, 66, 10, 15, 234, 65, 10, + 15, 234, 64, 10, 15, 234, 63, 10, 15, 234, 62, 10, 15, 234, 61, 10, 15, + 234, 60, 10, 15, 234, 59, 10, 15, 234, 58, 10, 15, 234, 57, 10, 15, 234, + 56, 10, 15, 234, 55, 10, 15, 234, 54, 10, 15, 234, 53, 10, 15, 234, 52, + 10, 15, 234, 51, 10, 15, 234, 50, 10, 15, 234, 49, 10, 15, 234, 48, 10, + 15, 234, 47, 10, 15, 234, 46, 10, 15, 234, 45, 10, 15, 234, 44, 10, 15, + 234, 43, 10, 15, 234, 42, 10, 15, 234, 41, 10, 15, 234, 40, 10, 15, 234, + 39, 10, 15, 234, 38, 10, 15, 234, 37, 10, 15, 234, 36, 10, 15, 234, 35, + 10, 15, 234, 34, 10, 15, 234, 33, 10, 15, 234, 32, 10, 15, 234, 31, 10, + 15, 234, 30, 10, 15, 234, 29, 10, 15, 234, 28, 10, 15, 234, 27, 10, 15, + 234, 26, 10, 15, 234, 25, 10, 15, 234, 24, 10, 15, 234, 23, 10, 15, 234, + 22, 10, 15, 234, 21, 10, 15, 234, 20, 10, 15, 234, 19, 10, 15, 234, 18, + 10, 15, 234, 17, 10, 15, 234, 16, 10, 15, 234, 15, 10, 15, 234, 14, 10, + 15, 234, 13, 10, 15, 234, 12, 10, 15, 234, 11, 10, 15, 234, 10, 10, 15, + 234, 9, 10, 15, 234, 8, 10, 15, 234, 7, 10, 15, 234, 6, 10, 15, 234, 5, + 10, 15, 234, 4, 10, 15, 234, 3, 10, 15, 234, 2, 10, 15, 234, 1, 10, 15, + 234, 0, 10, 15, 233, 255, 10, 15, 233, 254, 10, 15, 233, 253, 10, 15, + 233, 252, 10, 15, 233, 251, 10, 15, 233, 250, 10, 15, 233, 249, 10, 15, + 233, 248, 10, 15, 233, 247, 10, 15, 233, 246, 10, 15, 233, 245, 10, 15, + 233, 244, 10, 15, 233, 243, 10, 15, 233, 242, 10, 15, 233, 241, 10, 15, + 233, 240, 10, 15, 233, 239, 10, 15, 233, 238, 10, 15, 233, 237, 10, 15, + 233, 236, 10, 15, 233, 235, 10, 15, 233, 234, 10, 15, 233, 233, 10, 15, + 233, 232, 10, 15, 233, 231, 10, 15, 233, 230, 10, 15, 233, 229, 10, 15, + 233, 228, 10, 15, 233, 227, 10, 15, 233, 226, 10, 15, 233, 225, 10, 15, + 233, 224, 10, 15, 233, 223, 10, 15, 233, 222, 10, 15, 233, 221, 10, 15, + 233, 220, 10, 15, 233, 219, 10, 15, 233, 218, 10, 15, 233, 217, 10, 15, + 233, 216, 10, 15, 233, 215, 10, 15, 233, 214, 10, 15, 233, 213, 10, 15, + 233, 212, 10, 15, 233, 211, 10, 15, 233, 210, 10, 15, 233, 209, 10, 15, + 233, 208, 10, 15, 233, 207, 10, 15, 233, 206, 10, 15, 233, 205, 10, 15, + 233, 204, 10, 15, 233, 203, 10, 15, 233, 202, 10, 15, 233, 201, 10, 15, + 233, 200, 10, 15, 233, 199, 10, 15, 233, 198, 10, 15, 233, 197, 10, 15, + 233, 196, 10, 15, 233, 195, 10, 15, 233, 194, 10, 15, 233, 193, 10, 15, + 233, 192, 10, 15, 233, 191, 10, 15, 233, 190, 10, 15, 233, 189, 10, 15, + 233, 188, 10, 15, 233, 187, 10, 15, 233, 186, 10, 15, 233, 185, 10, 15, + 233, 184, 10, 15, 233, 183, 10, 15, 233, 182, 10, 15, 233, 181, 10, 15, + 233, 180, 10, 15, 233, 179, 10, 15, 233, 178, 10, 15, 233, 177, 10, 15, + 233, 176, 10, 15, 233, 175, 10, 15, 233, 174, 10, 15, 233, 173, 10, 15, + 233, 172, 10, 15, 233, 171, 10, 15, 233, 170, 10, 15, 233, 169, 10, 15, + 233, 168, 10, 15, 233, 167, 10, 15, 233, 166, 10, 15, 233, 165, 10, 15, + 233, 164, 10, 15, 233, 163, 10, 15, 233, 162, 10, 15, 233, 161, 10, 15, + 233, 160, 10, 15, 233, 159, 10, 15, 233, 158, 10, 15, 233, 157, 10, 15, + 233, 156, 10, 15, 233, 155, 10, 15, 233, 154, 10, 15, 233, 153, 10, 15, + 233, 152, 10, 15, 233, 151, 10, 15, 233, 150, 10, 15, 233, 149, 10, 15, + 233, 148, 10, 15, 233, 147, 10, 15, 233, 146, 10, 15, 233, 145, 10, 15, + 233, 144, 10, 15, 233, 143, 10, 15, 233, 142, 10, 15, 233, 141, 10, 15, + 233, 140, 10, 15, 233, 139, 10, 15, 233, 138, 10, 15, 233, 137, 10, 15, + 233, 136, 10, 15, 233, 135, 10, 15, 233, 134, 7, 5, 28, 241, 254, 7, 5, + 28, 241, 250, 7, 5, 28, 241, 199, 7, 5, 28, 241, 253, 7, 5, 28, 241, 252, + 7, 5, 28, 152, 218, 1, 213, 10, 7, 5, 28, 214, 40, 164, 5, 28, 227, 84, + 224, 29, 164, 5, 28, 227, 84, 243, 108, 164, 5, 28, 227, 84, 233, 38, + 164, 5, 28, 208, 219, 224, 29, 164, 5, 28, 227, 84, 206, 173, 103, 1, + 205, 237, 2, 238, 244, 103, 220, 205, 232, 103, 209, 51, 103, 28, 206, 9, + 205, 237, 205, 237, 221, 194, 103, 1, 252, 139, 251, 154, 103, 1, 207, + 17, 252, 172, 103, 1, 207, 17, 246, 111, 103, 1, 207, 17, 239, 71, 103, + 1, 207, 17, 232, 45, 103, 1, 207, 17, 230, 98, 103, 1, 207, 17, 42, 227, + 90, 103, 1, 207, 17, 218, 242, 103, 1, 207, 17, 212, 147, 103, 1, 252, + 139, 101, 53, 103, 1, 215, 172, 2, 215, 172, 245, 23, 103, 1, 215, 172, + 2, 215, 45, 245, 23, 103, 1, 215, 172, 2, 246, 131, 23, 215, 172, 245, + 23, 103, 1, 215, 172, 2, 246, 131, 23, 215, 45, 245, 23, 103, 1, 126, 2, + 221, 194, 103, 1, 126, 2, 220, 7, 103, 1, 126, 2, 227, 204, 103, 1, 250, + 11, 2, 246, 130, 103, 1, 240, 48, 2, 246, 130, 103, 1, 246, 112, 2, 246, + 130, 103, 1, 239, 72, 2, 227, 204, 103, 1, 209, 44, 2, 246, 130, 103, 1, + 205, 97, 2, 246, 130, 103, 1, 212, 81, 2, 246, 130, 103, 1, 205, 237, 2, + 246, 130, 103, 1, 42, 232, 46, 2, 246, 130, 103, 1, 232, 46, 2, 246, 130, + 103, 1, 230, 99, 2, 246, 130, 103, 1, 227, 91, 2, 246, 130, 103, 1, 223, + 174, 2, 246, 130, 103, 1, 217, 158, 2, 246, 130, 103, 1, 42, 221, 175, 2, + 246, 130, 103, 1, 221, 175, 2, 246, 130, 103, 1, 210, 239, 2, 246, 130, + 103, 1, 219, 224, 2, 246, 130, 103, 1, 218, 243, 2, 246, 130, 103, 1, + 215, 172, 2, 246, 130, 103, 1, 212, 148, 2, 246, 130, 103, 1, 209, 44, 2, + 238, 142, 103, 1, 250, 11, 2, 219, 93, 103, 1, 232, 46, 2, 219, 93, 103, + 1, 221, 175, 2, 219, 93, 103, 28, 126, 230, 98, 8, 1, 126, 207, 77, 61, + 17, 8, 1, 126, 207, 77, 42, 17, 8, 1, 250, 49, 61, 17, 8, 1, 250, 49, 42, + 17, 8, 1, 250, 49, 78, 17, 8, 1, 250, 49, 169, 17, 8, 1, 221, 158, 61, + 17, 8, 1, 221, 158, 42, 17, 8, 1, 221, 158, 78, 17, 8, 1, 221, 158, 169, + 17, 8, 1, 250, 37, 61, 17, 8, 1, 250, 37, 42, 17, 8, 1, 250, 37, 78, 17, + 8, 1, 250, 37, 169, 17, 8, 1, 210, 199, 61, 17, 8, 1, 210, 199, 42, 17, + 8, 1, 210, 199, 78, 17, 8, 1, 210, 199, 169, 17, 8, 1, 212, 114, 61, 17, + 8, 1, 212, 114, 42, 17, 8, 1, 212, 114, 78, 17, 8, 1, 212, 114, 169, 17, + 8, 1, 210, 201, 61, 17, 8, 1, 210, 201, 42, 17, 8, 1, 210, 201, 78, 17, + 8, 1, 210, 201, 169, 17, 8, 1, 209, 33, 61, 17, 8, 1, 209, 33, 42, 17, 8, + 1, 209, 33, 78, 17, 8, 1, 209, 33, 169, 17, 8, 1, 221, 156, 61, 17, 8, 1, + 221, 156, 42, 17, 8, 1, 221, 156, 78, 17, 8, 1, 221, 156, 169, 17, 8, 1, + 243, 202, 61, 17, 8, 1, 243, 202, 42, 17, 8, 1, 243, 202, 78, 17, 8, 1, + 243, 202, 169, 17, 8, 1, 223, 132, 61, 17, 8, 1, 223, 132, 42, 17, 8, 1, + 223, 132, 78, 17, 8, 1, 223, 132, 169, 17, 8, 1, 212, 136, 61, 17, 8, 1, + 212, 136, 42, 17, 8, 1, 212, 136, 78, 17, 8, 1, 212, 136, 169, 17, 8, 1, + 212, 134, 61, 17, 8, 1, 212, 134, 42, 17, 8, 1, 212, 134, 78, 17, 8, 1, + 212, 134, 169, 17, 8, 1, 246, 52, 61, 17, 8, 1, 246, 52, 42, 17, 8, 1, + 246, 125, 61, 17, 8, 1, 246, 125, 42, 17, 8, 1, 243, 230, 61, 17, 8, 1, + 243, 230, 42, 17, 8, 1, 246, 50, 61, 17, 8, 1, 246, 50, 42, 17, 8, 1, + 232, 177, 61, 17, 8, 1, 232, 177, 42, 17, 8, 1, 218, 82, 61, 17, 8, 1, + 218, 82, 42, 17, 8, 1, 231, 213, 61, 17, 8, 1, 231, 213, 42, 17, 8, 1, + 231, 213, 78, 17, 8, 1, 231, 213, 169, 17, 8, 1, 240, 232, 61, 17, 8, 1, + 240, 232, 42, 17, 8, 1, 240, 232, 78, 17, 8, 1, 240, 232, 169, 17, 8, 1, + 239, 201, 61, 17, 8, 1, 239, 201, 42, 17, 8, 1, 239, 201, 78, 17, 8, 1, + 239, 201, 169, 17, 8, 1, 225, 1, 61, 17, 8, 1, 225, 1, 42, 17, 8, 1, 225, + 1, 78, 17, 8, 1, 225, 1, 169, 17, 8, 1, 224, 55, 240, 66, 61, 17, 8, 1, + 224, 55, 240, 66, 42, 17, 8, 1, 218, 128, 61, 17, 8, 1, 218, 128, 42, 17, + 8, 1, 218, 128, 78, 17, 8, 1, 218, 128, 169, 17, 8, 1, 239, 51, 2, 87, + 84, 61, 17, 8, 1, 239, 51, 2, 87, 84, 42, 17, 8, 1, 239, 51, 240, 17, 61, + 17, 8, 1, 239, 51, 240, 17, 42, 17, 8, 1, 239, 51, 240, 17, 78, 17, 8, 1, + 239, 51, 240, 17, 169, 17, 8, 1, 239, 51, 245, 48, 61, 17, 8, 1, 239, 51, + 245, 48, 42, 17, 8, 1, 239, 51, 245, 48, 78, 17, 8, 1, 239, 51, 245, 48, + 169, 17, 8, 1, 87, 250, 122, 61, 17, 8, 1, 87, 250, 122, 42, 17, 8, 1, + 87, 250, 122, 2, 239, 112, 84, 61, 17, 8, 1, 87, 250, 122, 2, 239, 112, + 84, 42, 17, 8, 16, 67, 52, 8, 16, 67, 55, 8, 16, 118, 177, 52, 8, 16, + 118, 177, 55, 8, 16, 129, 177, 52, 8, 16, 129, 177, 55, 8, 16, 129, 177, + 220, 201, 173, 52, 8, 16, 129, 177, 220, 201, 173, 55, 8, 16, 241, 125, + 177, 52, 8, 16, 241, 125, 177, 55, 8, 16, 50, 79, 250, 129, 55, 8, 16, + 118, 177, 208, 228, 52, 8, 16, 118, 177, 208, 228, 55, 8, 16, 218, 148, + 8, 16, 5, 212, 195, 52, 8, 16, 5, 212, 195, 55, 8, 1, 225, 80, 61, 17, 8, + 1, 225, 80, 42, 17, 8, 1, 225, 80, 78, 17, 8, 1, 225, 80, 169, 17, 8, 1, + 106, 61, 17, 8, 1, 106, 42, 17, 8, 1, 222, 207, 61, 17, 8, 1, 222, 207, + 42, 17, 8, 1, 205, 214, 61, 17, 8, 1, 205, 214, 42, 17, 8, 1, 106, 2, + 239, 112, 84, 61, 17, 8, 1, 209, 40, 61, 17, 8, 1, 209, 40, 42, 17, 8, 1, + 231, 101, 222, 207, 61, 17, 8, 1, 231, 101, 222, 207, 42, 17, 8, 1, 231, + 101, 205, 214, 61, 17, 8, 1, 231, 101, 205, 214, 42, 17, 8, 1, 174, 61, + 17, 8, 1, 174, 42, 17, 8, 1, 174, 78, 17, 8, 1, 174, 169, 17, 8, 1, 209, + 251, 231, 228, 231, 101, 126, 227, 229, 78, 17, 8, 1, 209, 251, 231, 228, + 231, 101, 126, 227, 229, 169, 17, 8, 28, 87, 2, 239, 112, 84, 2, 126, 61, + 17, 8, 28, 87, 2, 239, 112, 84, 2, 126, 42, 17, 8, 28, 87, 2, 239, 112, + 84, 2, 252, 249, 61, 17, 8, 28, 87, 2, 239, 112, 84, 2, 252, 249, 42, 17, + 8, 28, 87, 2, 239, 112, 84, 2, 207, 60, 61, 17, 8, 28, 87, 2, 239, 112, + 84, 2, 207, 60, 42, 17, 8, 28, 87, 2, 239, 112, 84, 2, 106, 61, 17, 8, + 28, 87, 2, 239, 112, 84, 2, 106, 42, 17, 8, 28, 87, 2, 239, 112, 84, 2, + 222, 207, 61, 17, 8, 28, 87, 2, 239, 112, 84, 2, 222, 207, 42, 17, 8, 28, + 87, 2, 239, 112, 84, 2, 205, 214, 61, 17, 8, 28, 87, 2, 239, 112, 84, 2, + 205, 214, 42, 17, 8, 28, 87, 2, 239, 112, 84, 2, 174, 61, 17, 8, 28, 87, + 2, 239, 112, 84, 2, 174, 42, 17, 8, 28, 87, 2, 239, 112, 84, 2, 174, 78, + 17, 8, 28, 209, 251, 231, 101, 87, 2, 239, 112, 84, 2, 126, 227, 229, 61, + 17, 8, 28, 209, 251, 231, 101, 87, 2, 239, 112, 84, 2, 126, 227, 229, 42, + 17, 8, 28, 209, 251, 231, 101, 87, 2, 239, 112, 84, 2, 126, 227, 229, 78, + 17, 8, 1, 242, 42, 87, 61, 17, 8, 1, 242, 42, 87, 42, 17, 8, 1, 242, 42, + 87, 78, 17, 8, 1, 242, 42, 87, 169, 17, 8, 28, 87, 2, 239, 112, 84, 2, + 171, 61, 17, 8, 28, 87, 2, 239, 112, 84, 2, 140, 61, 17, 8, 28, 87, 2, + 239, 112, 84, 2, 80, 61, 17, 8, 28, 87, 2, 239, 112, 84, 2, 126, 227, + 229, 61, 17, 8, 28, 87, 2, 239, 112, 84, 2, 87, 61, 17, 8, 28, 250, 39, + 2, 171, 61, 17, 8, 28, 250, 39, 2, 140, 61, 17, 8, 28, 250, 39, 2, 231, + 164, 61, 17, 8, 28, 250, 39, 2, 80, 61, 17, 8, 28, 250, 39, 2, 126, 227, + 229, 61, 17, 8, 28, 250, 39, 2, 87, 61, 17, 8, 28, 212, 116, 2, 171, 61, + 17, 8, 28, 212, 116, 2, 140, 61, 17, 8, 28, 212, 116, 2, 231, 164, 61, + 17, 8, 28, 212, 116, 2, 80, 61, 17, 8, 28, 212, 116, 2, 126, 227, 229, + 61, 17, 8, 28, 212, 116, 2, 87, 61, 17, 8, 28, 212, 38, 2, 171, 61, 17, + 8, 28, 212, 38, 2, 80, 61, 17, 8, 28, 212, 38, 2, 126, 227, 229, 61, 17, + 8, 28, 212, 38, 2, 87, 61, 17, 8, 28, 171, 2, 140, 61, 17, 8, 28, 171, 2, + 80, 61, 17, 8, 28, 140, 2, 171, 61, 17, 8, 28, 140, 2, 80, 61, 17, 8, 28, + 231, 164, 2, 171, 61, 17, 8, 28, 231, 164, 2, 140, 61, 17, 8, 28, 231, + 164, 2, 80, 61, 17, 8, 28, 217, 71, 2, 171, 61, 17, 8, 28, 217, 71, 2, + 140, 61, 17, 8, 28, 217, 71, 2, 231, 164, 61, 17, 8, 28, 217, 71, 2, 80, + 61, 17, 8, 28, 217, 192, 2, 140, 61, 17, 8, 28, 217, 192, 2, 80, 61, 17, + 8, 28, 246, 141, 2, 171, 61, 17, 8, 28, 246, 141, 2, 140, 61, 17, 8, 28, + 246, 141, 2, 231, 164, 61, 17, 8, 28, 246, 141, 2, 80, 61, 17, 8, 28, + 212, 195, 2, 140, 61, 17, 8, 28, 212, 195, 2, 80, 61, 17, 8, 28, 205, + 112, 2, 80, 61, 17, 8, 28, 252, 201, 2, 171, 61, 17, 8, 28, 252, 201, 2, + 80, 61, 17, 8, 28, 240, 95, 2, 171, 61, 17, 8, 28, 240, 95, 2, 80, 61, + 17, 8, 28, 242, 16, 2, 171, 61, 17, 8, 28, 242, 16, 2, 140, 61, 17, 8, + 28, 242, 16, 2, 231, 164, 61, 17, 8, 28, 242, 16, 2, 80, 61, 17, 8, 28, + 242, 16, 2, 126, 227, 229, 61, 17, 8, 28, 242, 16, 2, 87, 61, 17, 8, 28, + 220, 13, 2, 140, 61, 17, 8, 28, 220, 13, 2, 80, 61, 17, 8, 28, 220, 13, + 2, 126, 227, 229, 61, 17, 8, 28, 220, 13, 2, 87, 61, 17, 8, 28, 232, 46, + 2, 126, 61, 17, 8, 28, 232, 46, 2, 171, 61, 17, 8, 28, 232, 46, 2, 140, + 61, 17, 8, 28, 232, 46, 2, 231, 164, 61, 17, 8, 28, 232, 46, 2, 230, 107, + 61, 17, 8, 28, 232, 46, 2, 80, 61, 17, 8, 28, 232, 46, 2, 126, 227, 229, + 61, 17, 8, 28, 232, 46, 2, 87, 61, 17, 8, 28, 230, 107, 2, 171, 61, 17, + 8, 28, 230, 107, 2, 140, 61, 17, 8, 28, 230, 107, 2, 231, 164, 61, 17, 8, + 28, 230, 107, 2, 80, 61, 17, 8, 28, 230, 107, 2, 126, 227, 229, 61, 17, + 8, 28, 230, 107, 2, 87, 61, 17, 8, 28, 80, 2, 171, 61, 17, 8, 28, 80, 2, + 140, 61, 17, 8, 28, 80, 2, 231, 164, 61, 17, 8, 28, 80, 2, 80, 61, 17, 8, + 28, 80, 2, 126, 227, 229, 61, 17, 8, 28, 80, 2, 87, 61, 17, 8, 28, 224, + 55, 2, 171, 61, 17, 8, 28, 224, 55, 2, 140, 61, 17, 8, 28, 224, 55, 2, + 231, 164, 61, 17, 8, 28, 224, 55, 2, 80, 61, 17, 8, 28, 224, 55, 2, 126, + 227, 229, 61, 17, 8, 28, 224, 55, 2, 87, 61, 17, 8, 28, 239, 51, 2, 171, + 61, 17, 8, 28, 239, 51, 2, 80, 61, 17, 8, 28, 239, 51, 2, 126, 227, 229, + 61, 17, 8, 28, 239, 51, 2, 87, 61, 17, 8, 28, 87, 2, 171, 61, 17, 8, 28, + 87, 2, 140, 61, 17, 8, 28, 87, 2, 231, 164, 61, 17, 8, 28, 87, 2, 80, 61, + 17, 8, 28, 87, 2, 126, 227, 229, 61, 17, 8, 28, 87, 2, 87, 61, 17, 8, 28, + 212, 50, 2, 213, 139, 126, 61, 17, 8, 28, 219, 17, 2, 213, 139, 126, 61, + 17, 8, 28, 126, 227, 229, 2, 213, 139, 126, 61, 17, 8, 28, 215, 250, 2, + 246, 105, 61, 17, 8, 28, 215, 250, 2, 231, 251, 61, 17, 8, 28, 215, 250, + 2, 242, 40, 61, 17, 8, 28, 215, 250, 2, 246, 107, 61, 17, 8, 28, 215, + 250, 2, 231, 253, 61, 17, 8, 28, 215, 250, 2, 213, 139, 126, 61, 17, 8, + 28, 87, 2, 239, 112, 84, 2, 219, 17, 42, 17, 8, 28, 87, 2, 239, 112, 84, + 2, 205, 109, 42, 17, 8, 28, 87, 2, 239, 112, 84, 2, 80, 42, 17, 8, 28, + 87, 2, 239, 112, 84, 2, 224, 55, 42, 17, 8, 28, 87, 2, 239, 112, 84, 2, + 126, 227, 229, 42, 17, 8, 28, 87, 2, 239, 112, 84, 2, 87, 42, 17, 8, 28, + 250, 39, 2, 219, 17, 42, 17, 8, 28, 250, 39, 2, 205, 109, 42, 17, 8, 28, + 250, 39, 2, 80, 42, 17, 8, 28, 250, 39, 2, 224, 55, 42, 17, 8, 28, 250, + 39, 2, 126, 227, 229, 42, 17, 8, 28, 250, 39, 2, 87, 42, 17, 8, 28, 212, + 116, 2, 219, 17, 42, 17, 8, 28, 212, 116, 2, 205, 109, 42, 17, 8, 28, + 212, 116, 2, 80, 42, 17, 8, 28, 212, 116, 2, 224, 55, 42, 17, 8, 28, 212, + 116, 2, 126, 227, 229, 42, 17, 8, 28, 212, 116, 2, 87, 42, 17, 8, 28, + 212, 38, 2, 219, 17, 42, 17, 8, 28, 212, 38, 2, 205, 109, 42, 17, 8, 28, + 212, 38, 2, 80, 42, 17, 8, 28, 212, 38, 2, 224, 55, 42, 17, 8, 28, 212, + 38, 2, 126, 227, 229, 42, 17, 8, 28, 212, 38, 2, 87, 42, 17, 8, 28, 242, + 16, 2, 126, 227, 229, 42, 17, 8, 28, 242, 16, 2, 87, 42, 17, 8, 28, 220, + 13, 2, 126, 227, 229, 42, 17, 8, 28, 220, 13, 2, 87, 42, 17, 8, 28, 232, + 46, 2, 126, 42, 17, 8, 28, 232, 46, 2, 230, 107, 42, 17, 8, 28, 232, 46, + 2, 80, 42, 17, 8, 28, 232, 46, 2, 126, 227, 229, 42, 17, 8, 28, 232, 46, + 2, 87, 42, 17, 8, 28, 230, 107, 2, 80, 42, 17, 8, 28, 230, 107, 2, 126, + 227, 229, 42, 17, 8, 28, 230, 107, 2, 87, 42, 17, 8, 28, 80, 2, 126, 42, + 17, 8, 28, 80, 2, 80, 42, 17, 8, 28, 224, 55, 2, 219, 17, 42, 17, 8, 28, + 224, 55, 2, 205, 109, 42, 17, 8, 28, 224, 55, 2, 80, 42, 17, 8, 28, 224, + 55, 2, 224, 55, 42, 17, 8, 28, 224, 55, 2, 126, 227, 229, 42, 17, 8, 28, + 224, 55, 2, 87, 42, 17, 8, 28, 126, 227, 229, 2, 213, 139, 126, 42, 17, + 8, 28, 87, 2, 219, 17, 42, 17, 8, 28, 87, 2, 205, 109, 42, 17, 8, 28, 87, + 2, 80, 42, 17, 8, 28, 87, 2, 224, 55, 42, 17, 8, 28, 87, 2, 126, 227, + 229, 42, 17, 8, 28, 87, 2, 87, 42, 17, 8, 28, 87, 2, 239, 112, 84, 2, + 171, 78, 17, 8, 28, 87, 2, 239, 112, 84, 2, 140, 78, 17, 8, 28, 87, 2, + 239, 112, 84, 2, 231, 164, 78, 17, 8, 28, 87, 2, 239, 112, 84, 2, 80, 78, + 17, 8, 28, 87, 2, 239, 112, 84, 2, 239, 51, 78, 17, 8, 28, 250, 39, 2, + 171, 78, 17, 8, 28, 250, 39, 2, 140, 78, 17, 8, 28, 250, 39, 2, 231, 164, + 78, 17, 8, 28, 250, 39, 2, 80, 78, 17, 8, 28, 250, 39, 2, 239, 51, 78, + 17, 8, 28, 212, 116, 2, 171, 78, 17, 8, 28, 212, 116, 2, 140, 78, 17, 8, + 28, 212, 116, 2, 231, 164, 78, 17, 8, 28, 212, 116, 2, 80, 78, 17, 8, 28, + 212, 116, 2, 239, 51, 78, 17, 8, 28, 212, 38, 2, 80, 78, 17, 8, 28, 171, + 2, 140, 78, 17, 8, 28, 171, 2, 80, 78, 17, 8, 28, 140, 2, 171, 78, 17, 8, + 28, 140, 2, 80, 78, 17, 8, 28, 231, 164, 2, 171, 78, 17, 8, 28, 231, 164, + 2, 80, 78, 17, 8, 28, 217, 71, 2, 171, 78, 17, 8, 28, 217, 71, 2, 140, + 78, 17, 8, 28, 217, 71, 2, 231, 164, 78, 17, 8, 28, 217, 71, 2, 80, 78, + 17, 8, 28, 217, 192, 2, 140, 78, 17, 8, 28, 217, 192, 2, 231, 164, 78, + 17, 8, 28, 217, 192, 2, 80, 78, 17, 8, 28, 246, 141, 2, 171, 78, 17, 8, + 28, 246, 141, 2, 140, 78, 17, 8, 28, 246, 141, 2, 231, 164, 78, 17, 8, + 28, 246, 141, 2, 80, 78, 17, 8, 28, 212, 195, 2, 140, 78, 17, 8, 28, 205, + 112, 2, 80, 78, 17, 8, 28, 252, 201, 2, 171, 78, 17, 8, 28, 252, 201, 2, + 80, 78, 17, 8, 28, 240, 95, 2, 171, 78, 17, 8, 28, 240, 95, 2, 80, 78, + 17, 8, 28, 242, 16, 2, 171, 78, 17, 8, 28, 242, 16, 2, 140, 78, 17, 8, + 28, 242, 16, 2, 231, 164, 78, 17, 8, 28, 242, 16, 2, 80, 78, 17, 8, 28, + 220, 13, 2, 140, 78, 17, 8, 28, 220, 13, 2, 80, 78, 17, 8, 28, 232, 46, + 2, 171, 78, 17, 8, 28, 232, 46, 2, 140, 78, 17, 8, 28, 232, 46, 2, 231, + 164, 78, 17, 8, 28, 232, 46, 2, 230, 107, 78, 17, 8, 28, 232, 46, 2, 80, + 78, 17, 8, 28, 230, 107, 2, 171, 78, 17, 8, 28, 230, 107, 2, 140, 78, 17, + 8, 28, 230, 107, 2, 231, 164, 78, 17, 8, 28, 230, 107, 2, 80, 78, 17, 8, + 28, 230, 107, 2, 239, 51, 78, 17, 8, 28, 80, 2, 171, 78, 17, 8, 28, 80, + 2, 140, 78, 17, 8, 28, 80, 2, 231, 164, 78, 17, 8, 28, 80, 2, 80, 78, 17, + 8, 28, 224, 55, 2, 171, 78, 17, 8, 28, 224, 55, 2, 140, 78, 17, 8, 28, + 224, 55, 2, 231, 164, 78, 17, 8, 28, 224, 55, 2, 80, 78, 17, 8, 28, 224, + 55, 2, 239, 51, 78, 17, 8, 28, 239, 51, 2, 171, 78, 17, 8, 28, 239, 51, + 2, 80, 78, 17, 8, 28, 239, 51, 2, 213, 139, 126, 78, 17, 8, 28, 87, 2, + 171, 78, 17, 8, 28, 87, 2, 140, 78, 17, 8, 28, 87, 2, 231, 164, 78, 17, + 8, 28, 87, 2, 80, 78, 17, 8, 28, 87, 2, 239, 51, 78, 17, 8, 28, 87, 2, + 239, 112, 84, 2, 80, 169, 17, 8, 28, 87, 2, 239, 112, 84, 2, 239, 51, + 169, 17, 8, 28, 250, 39, 2, 80, 169, 17, 8, 28, 250, 39, 2, 239, 51, 169, + 17, 8, 28, 212, 116, 2, 80, 169, 17, 8, 28, 212, 116, 2, 239, 51, 169, + 17, 8, 28, 212, 38, 2, 80, 169, 17, 8, 28, 212, 38, 2, 239, 51, 169, 17, + 8, 28, 217, 71, 2, 80, 169, 17, 8, 28, 217, 71, 2, 239, 51, 169, 17, 8, + 28, 215, 211, 2, 80, 169, 17, 8, 28, 215, 211, 2, 239, 51, 169, 17, 8, + 28, 232, 46, 2, 230, 107, 169, 17, 8, 28, 232, 46, 2, 80, 169, 17, 8, 28, + 230, 107, 2, 80, 169, 17, 8, 28, 224, 55, 2, 80, 169, 17, 8, 28, 224, 55, + 2, 239, 51, 169, 17, 8, 28, 87, 2, 80, 169, 17, 8, 28, 87, 2, 239, 51, + 169, 17, 8, 28, 215, 250, 2, 242, 40, 169, 17, 8, 28, 215, 250, 2, 246, + 107, 169, 17, 8, 28, 215, 250, 2, 231, 253, 169, 17, 8, 28, 212, 195, 2, + 126, 227, 229, 61, 17, 8, 28, 212, 195, 2, 87, 61, 17, 8, 28, 252, 201, + 2, 126, 227, 229, 61, 17, 8, 28, 252, 201, 2, 87, 61, 17, 8, 28, 240, 95, + 2, 126, 227, 229, 61, 17, 8, 28, 240, 95, 2, 87, 61, 17, 8, 28, 217, 71, + 2, 126, 227, 229, 61, 17, 8, 28, 217, 71, 2, 87, 61, 17, 8, 28, 215, 211, + 2, 126, 227, 229, 61, 17, 8, 28, 215, 211, 2, 87, 61, 17, 8, 28, 140, 2, + 126, 227, 229, 61, 17, 8, 28, 140, 2, 87, 61, 17, 8, 28, 171, 2, 126, + 227, 229, 61, 17, 8, 28, 171, 2, 87, 61, 17, 8, 28, 231, 164, 2, 126, + 227, 229, 61, 17, 8, 28, 231, 164, 2, 87, 61, 17, 8, 28, 217, 192, 2, + 126, 227, 229, 61, 17, 8, 28, 217, 192, 2, 87, 61, 17, 8, 28, 246, 141, + 2, 126, 227, 229, 61, 17, 8, 28, 246, 141, 2, 87, 61, 17, 8, 28, 215, + 211, 2, 171, 61, 17, 8, 28, 215, 211, 2, 140, 61, 17, 8, 28, 215, 211, 2, + 231, 164, 61, 17, 8, 28, 215, 211, 2, 80, 61, 17, 8, 28, 215, 211, 2, + 219, 17, 61, 17, 8, 28, 217, 71, 2, 219, 17, 61, 17, 8, 28, 217, 192, 2, + 219, 17, 61, 17, 8, 28, 246, 141, 2, 219, 17, 61, 17, 8, 28, 212, 195, 2, + 126, 227, 229, 42, 17, 8, 28, 212, 195, 2, 87, 42, 17, 8, 28, 252, 201, + 2, 126, 227, 229, 42, 17, 8, 28, 252, 201, 2, 87, 42, 17, 8, 28, 240, 95, + 2, 126, 227, 229, 42, 17, 8, 28, 240, 95, 2, 87, 42, 17, 8, 28, 217, 71, + 2, 126, 227, 229, 42, 17, 8, 28, 217, 71, 2, 87, 42, 17, 8, 28, 215, 211, + 2, 126, 227, 229, 42, 17, 8, 28, 215, 211, 2, 87, 42, 17, 8, 28, 140, 2, + 126, 227, 229, 42, 17, 8, 28, 140, 2, 87, 42, 17, 8, 28, 171, 2, 126, + 227, 229, 42, 17, 8, 28, 171, 2, 87, 42, 17, 8, 28, 231, 164, 2, 126, + 227, 229, 42, 17, 8, 28, 231, 164, 2, 87, 42, 17, 8, 28, 217, 192, 2, + 126, 227, 229, 42, 17, 8, 28, 217, 192, 2, 87, 42, 17, 8, 28, 246, 141, + 2, 126, 227, 229, 42, 17, 8, 28, 246, 141, 2, 87, 42, 17, 8, 28, 215, + 211, 2, 171, 42, 17, 8, 28, 215, 211, 2, 140, 42, 17, 8, 28, 215, 211, 2, + 231, 164, 42, 17, 8, 28, 215, 211, 2, 80, 42, 17, 8, 28, 215, 211, 2, + 219, 17, 42, 17, 8, 28, 217, 71, 2, 219, 17, 42, 17, 8, 28, 217, 192, 2, + 219, 17, 42, 17, 8, 28, 246, 141, 2, 219, 17, 42, 17, 8, 28, 215, 211, 2, + 171, 78, 17, 8, 28, 215, 211, 2, 140, 78, 17, 8, 28, 215, 211, 2, 231, + 164, 78, 17, 8, 28, 215, 211, 2, 80, 78, 17, 8, 28, 217, 71, 2, 239, 51, + 78, 17, 8, 28, 215, 211, 2, 239, 51, 78, 17, 8, 28, 212, 195, 2, 80, 78, + 17, 8, 28, 217, 71, 2, 171, 169, 17, 8, 28, 217, 71, 2, 140, 169, 17, 8, + 28, 217, 71, 2, 231, 164, 169, 17, 8, 28, 215, 211, 2, 171, 169, 17, 8, + 28, 215, 211, 2, 140, 169, 17, 8, 28, 215, 211, 2, 231, 164, 169, 17, 8, + 28, 212, 195, 2, 80, 169, 17, 8, 28, 205, 112, 2, 80, 169, 17, 8, 28, + 126, 2, 242, 38, 42, 17, 8, 28, 126, 2, 242, 38, 61, 17, 222, 110, 47, + 221, 216, 222, 110, 48, 221, 216, 8, 28, 212, 116, 2, 171, 2, 80, 78, 17, + 8, 28, 212, 116, 2, 140, 2, 171, 42, 17, 8, 28, 212, 116, 2, 140, 2, 171, + 78, 17, 8, 28, 212, 116, 2, 140, 2, 80, 78, 17, 8, 28, 212, 116, 2, 231, + 164, 2, 80, 78, 17, 8, 28, 212, 116, 2, 80, 2, 171, 78, 17, 8, 28, 212, + 116, 2, 80, 2, 140, 78, 17, 8, 28, 212, 116, 2, 80, 2, 231, 164, 78, 17, + 8, 28, 171, 2, 80, 2, 140, 42, 17, 8, 28, 171, 2, 80, 2, 140, 78, 17, 8, + 28, 140, 2, 80, 2, 87, 42, 17, 8, 28, 140, 2, 80, 2, 126, 227, 229, 42, + 17, 8, 28, 217, 71, 2, 140, 2, 171, 78, 17, 8, 28, 217, 71, 2, 171, 2, + 140, 78, 17, 8, 28, 217, 71, 2, 171, 2, 126, 227, 229, 42, 17, 8, 28, + 217, 71, 2, 80, 2, 140, 42, 17, 8, 28, 217, 71, 2, 80, 2, 140, 78, 17, 8, + 28, 217, 71, 2, 80, 2, 171, 78, 17, 8, 28, 217, 71, 2, 80, 2, 80, 42, 17, + 8, 28, 217, 71, 2, 80, 2, 80, 78, 17, 8, 28, 217, 192, 2, 140, 2, 140, + 42, 17, 8, 28, 217, 192, 2, 140, 2, 140, 78, 17, 8, 28, 217, 192, 2, 80, + 2, 80, 42, 17, 8, 28, 215, 211, 2, 140, 2, 80, 42, 17, 8, 28, 215, 211, + 2, 140, 2, 80, 78, 17, 8, 28, 215, 211, 2, 171, 2, 87, 42, 17, 8, 28, + 215, 211, 2, 80, 2, 231, 164, 42, 17, 8, 28, 215, 211, 2, 80, 2, 231, + 164, 78, 17, 8, 28, 215, 211, 2, 80, 2, 80, 42, 17, 8, 28, 215, 211, 2, + 80, 2, 80, 78, 17, 8, 28, 246, 141, 2, 140, 2, 126, 227, 229, 42, 17, 8, + 28, 246, 141, 2, 231, 164, 2, 80, 42, 17, 8, 28, 246, 141, 2, 231, 164, + 2, 80, 78, 17, 8, 28, 212, 195, 2, 80, 2, 140, 42, 17, 8, 28, 212, 195, + 2, 80, 2, 140, 78, 17, 8, 28, 212, 195, 2, 80, 2, 80, 78, 17, 8, 28, 212, + 195, 2, 80, 2, 87, 42, 17, 8, 28, 252, 201, 2, 171, 2, 80, 42, 17, 8, 28, + 252, 201, 2, 80, 2, 80, 42, 17, 8, 28, 252, 201, 2, 80, 2, 80, 78, 17, 8, + 28, 252, 201, 2, 80, 2, 126, 227, 229, 42, 17, 8, 28, 240, 95, 2, 80, 2, + 80, 42, 17, 8, 28, 240, 95, 2, 80, 2, 87, 42, 17, 8, 28, 240, 95, 2, 80, + 2, 126, 227, 229, 42, 17, 8, 28, 242, 16, 2, 231, 164, 2, 80, 42, 17, 8, + 28, 242, 16, 2, 231, 164, 2, 80, 78, 17, 8, 28, 220, 13, 2, 80, 2, 140, + 42, 17, 8, 28, 220, 13, 2, 80, 2, 80, 42, 17, 8, 28, 230, 107, 2, 140, 2, + 80, 42, 17, 8, 28, 230, 107, 2, 140, 2, 87, 42, 17, 8, 28, 230, 107, 2, + 140, 2, 126, 227, 229, 42, 17, 8, 28, 230, 107, 2, 171, 2, 171, 78, 17, + 8, 28, 230, 107, 2, 171, 2, 171, 42, 17, 8, 28, 230, 107, 2, 231, 164, 2, + 80, 42, 17, 8, 28, 230, 107, 2, 231, 164, 2, 80, 78, 17, 8, 28, 230, 107, + 2, 80, 2, 140, 42, 17, 8, 28, 230, 107, 2, 80, 2, 140, 78, 17, 8, 28, 80, + 2, 140, 2, 171, 78, 17, 8, 28, 80, 2, 140, 2, 80, 78, 17, 8, 28, 80, 2, + 140, 2, 87, 42, 17, 8, 28, 80, 2, 171, 2, 140, 78, 17, 8, 28, 80, 2, 171, + 2, 80, 78, 17, 8, 28, 80, 2, 231, 164, 2, 171, 78, 17, 8, 28, 80, 2, 231, + 164, 2, 80, 78, 17, 8, 28, 80, 2, 171, 2, 231, 164, 78, 17, 8, 28, 239, + 51, 2, 80, 2, 171, 78, 17, 8, 28, 239, 51, 2, 80, 2, 80, 78, 17, 8, 28, + 224, 55, 2, 140, 2, 80, 78, 17, 8, 28, 224, 55, 2, 140, 2, 126, 227, 229, + 42, 17, 8, 28, 224, 55, 2, 171, 2, 80, 42, 17, 8, 28, 224, 55, 2, 171, 2, + 80, 78, 17, 8, 28, 224, 55, 2, 171, 2, 126, 227, 229, 42, 17, 8, 28, 224, + 55, 2, 80, 2, 87, 42, 17, 8, 28, 224, 55, 2, 80, 2, 126, 227, 229, 42, + 17, 8, 28, 87, 2, 80, 2, 80, 42, 17, 8, 28, 87, 2, 80, 2, 80, 78, 17, 8, + 28, 250, 39, 2, 231, 164, 2, 87, 42, 17, 8, 28, 212, 116, 2, 171, 2, 87, + 42, 17, 8, 28, 212, 116, 2, 171, 2, 126, 227, 229, 42, 17, 8, 28, 212, + 116, 2, 231, 164, 2, 87, 42, 17, 8, 28, 212, 116, 2, 231, 164, 2, 126, + 227, 229, 42, 17, 8, 28, 212, 116, 2, 80, 2, 87, 42, 17, 8, 28, 212, 116, + 2, 80, 2, 126, 227, 229, 42, 17, 8, 28, 171, 2, 80, 2, 87, 42, 17, 8, 28, + 171, 2, 140, 2, 126, 227, 229, 42, 17, 8, 28, 171, 2, 80, 2, 126, 227, + 229, 42, 17, 8, 28, 217, 71, 2, 231, 164, 2, 126, 227, 229, 42, 17, 8, + 28, 217, 192, 2, 140, 2, 87, 42, 17, 8, 28, 215, 211, 2, 140, 2, 87, 42, + 17, 8, 28, 246, 141, 2, 140, 2, 87, 42, 17, 8, 28, 230, 107, 2, 171, 2, + 87, 42, 17, 8, 28, 230, 107, 2, 80, 2, 87, 42, 17, 8, 28, 87, 2, 140, 2, + 87, 42, 17, 8, 28, 87, 2, 171, 2, 87, 42, 17, 8, 28, 87, 2, 80, 2, 87, + 42, 17, 8, 28, 80, 2, 80, 2, 87, 42, 17, 8, 28, 220, 13, 2, 80, 2, 87, + 42, 17, 8, 28, 224, 55, 2, 140, 2, 87, 42, 17, 8, 28, 220, 13, 2, 80, 2, + 140, 78, 17, 8, 28, 230, 107, 2, 140, 2, 80, 78, 17, 8, 28, 252, 201, 2, + 80, 2, 87, 42, 17, 8, 28, 232, 46, 2, 80, 2, 87, 42, 17, 8, 28, 224, 55, + 2, 171, 2, 140, 78, 17, 8, 28, 80, 2, 231, 164, 2, 87, 42, 17, 8, 28, + 230, 107, 2, 171, 2, 80, 78, 17, 8, 28, 232, 46, 2, 80, 2, 80, 42, 17, 8, + 28, 230, 107, 2, 171, 2, 80, 42, 17, 8, 28, 224, 55, 2, 171, 2, 140, 42, + 17, 8, 28, 171, 2, 140, 2, 87, 42, 17, 8, 28, 140, 2, 171, 2, 87, 42, 17, + 8, 28, 80, 2, 171, 2, 87, 42, 17, 8, 28, 242, 16, 2, 80, 2, 87, 42, 17, + 8, 28, 250, 39, 2, 140, 2, 87, 42, 17, 8, 28, 232, 46, 2, 80, 2, 80, 78, + 17, 8, 28, 252, 201, 2, 171, 2, 80, 78, 17, 8, 28, 217, 192, 2, 80, 2, + 80, 78, 17, 8, 28, 217, 71, 2, 231, 164, 2, 87, 42, 17, 8, 28, 224, 55, + 2, 171, 2, 87, 42, 17, 8, 28, 217, 168, 209, 172, 251, 232, 231, 25, 213, + 252, 3, 61, 17, 8, 28, 220, 9, 209, 172, 251, 232, 231, 25, 213, 252, 3, + 61, 17, 8, 28, 252, 155, 61, 17, 8, 28, 252, 186, 61, 17, 8, 28, 226, + 171, 61, 17, 8, 28, 217, 169, 61, 17, 8, 28, 219, 67, 61, 17, 8, 28, 252, + 175, 61, 17, 8, 28, 207, 79, 61, 17, 8, 28, 217, 168, 61, 17, 8, 28, 217, + 167, 252, 175, 207, 78, 8, 28, 232, 192, 218, 207, 53, 8, 28, 249, 211, + 252, 35, 252, 36, 54, 217, 58, 54, 216, 203, 54, 216, 135, 54, 216, 124, + 54, 216, 113, 54, 216, 102, 54, 216, 91, 54, 216, 80, 54, 216, 69, 54, + 217, 57, 54, 217, 46, 54, 217, 35, 54, 217, 24, 54, 217, 13, 54, 217, 2, + 54, 216, 247, 220, 131, 241, 136, 33, 79, 247, 155, 220, 131, 241, 136, + 33, 79, 128, 247, 155, 220, 131, 241, 136, 33, 79, 128, 241, 82, 213, + 251, 220, 131, 241, 136, 33, 79, 247, 162, 220, 131, 241, 136, 33, 79, + 216, 52, 220, 131, 241, 136, 33, 79, 242, 168, 83, 220, 131, 241, 136, + 33, 79, 219, 196, 83, 220, 131, 241, 136, 33, 79, 47, 59, 230, 16, 145, + 220, 131, 241, 136, 33, 79, 48, 59, 230, 16, 249, 132, 220, 131, 241, + 136, 33, 79, 194, 243, 54, 36, 28, 47, 239, 121, 36, 28, 48, 239, 121, + 36, 50, 211, 181, 47, 239, 121, 36, 50, 211, 181, 48, 239, 121, 36, 228, + 14, 47, 239, 121, 36, 228, 14, 48, 239, 121, 36, 247, 130, 228, 13, 36, + 28, 47, 160, 55, 36, 28, 48, 160, 55, 36, 211, 181, 47, 160, 55, 36, 211, + 181, 48, 160, 55, 36, 228, 14, 47, 160, 55, 36, 228, 14, 48, 160, 55, 36, + 247, 130, 228, 14, 55, 220, 131, 241, 136, 33, 79, 118, 67, 230, 56, 220, + 131, 241, 136, 33, 79, 243, 51, 246, 78, 220, 131, 241, 136, 33, 79, 243, + 42, 246, 78, 220, 131, 241, 136, 33, 79, 114, 229, 205, 220, 131, 241, + 136, 33, 79, 207, 61, 114, 229, 205, 220, 131, 241, 136, 33, 79, 47, 221, + 216, 220, 131, 241, 136, 33, 79, 48, 221, 216, 220, 131, 241, 136, 33, + 79, 47, 247, 26, 145, 220, 131, 241, 136, 33, 79, 48, 247, 26, 145, 220, + 131, 241, 136, 33, 79, 47, 211, 93, 215, 204, 145, 220, 131, 241, 136, + 33, 79, 48, 211, 93, 215, 204, 145, 220, 131, 241, 136, 33, 79, 47, 60, + 230, 16, 145, 220, 131, 241, 136, 33, 79, 48, 60, 230, 16, 145, 220, 131, + 241, 136, 33, 79, 47, 50, 252, 109, 145, 220, 131, 241, 136, 33, 79, 48, + 50, 252, 109, 145, 220, 131, 241, 136, 33, 79, 47, 252, 109, 145, 220, + 131, 241, 136, 33, 79, 48, 252, 109, 145, 220, 131, 241, 136, 33, 79, 47, + 247, 92, 145, 220, 131, 241, 136, 33, 79, 48, 247, 92, 145, 220, 131, + 241, 136, 33, 79, 47, 59, 247, 92, 145, 220, 131, 241, 136, 33, 79, 48, + 59, 247, 92, 145, 216, 32, 245, 23, 59, 216, 32, 245, 23, 220, 131, 241, + 136, 33, 79, 47, 49, 145, 220, 131, 241, 136, 33, 79, 48, 49, 145, 246, + 77, 222, 81, 248, 125, 222, 81, 207, 61, 222, 81, 50, 207, 61, 222, 81, + 246, 77, 114, 229, 205, 248, 125, 114, 229, 205, 207, 61, 114, 229, 205, + 5, 247, 155, 5, 128, 247, 155, 5, 241, 82, 213, 251, 5, 216, 52, 5, 247, + 162, 5, 219, 196, 83, 5, 242, 168, 83, 5, 243, 51, 246, 78, 5, 47, 221, + 216, 5, 48, 221, 216, 5, 47, 247, 26, 145, 5, 48, 247, 26, 145, 5, 47, + 211, 93, 215, 204, 145, 5, 48, 211, 93, 215, 204, 145, 5, 43, 53, 5, 252, + 125, 5, 251, 209, 5, 101, 53, 5, 237, 238, 5, 230, 10, 53, 5, 239, 230, + 53, 5, 242, 242, 53, 5, 218, 225, 214, 180, 5, 245, 35, 53, 5, 221, 131, + 53, 5, 247, 153, 251, 199, 8, 242, 38, 61, 17, 8, 212, 154, 2, 242, 38, + 52, 8, 246, 105, 61, 17, 8, 212, 192, 241, 115, 8, 231, 251, 61, 17, 8, + 242, 40, 61, 17, 8, 242, 40, 169, 17, 8, 246, 107, 61, 17, 8, 246, 107, + 169, 17, 8, 231, 253, 61, 17, 8, 231, 253, 169, 17, 8, 215, 250, 61, 17, + 8, 215, 250, 169, 17, 8, 213, 163, 61, 17, 8, 213, 163, 169, 17, 8, 1, + 239, 112, 61, 17, 8, 1, 126, 2, 228, 9, 84, 61, 17, 8, 1, 126, 2, 228, 9, + 84, 42, 17, 8, 1, 126, 2, 239, 112, 84, 61, 17, 8, 1, 126, 2, 239, 112, + 84, 42, 17, 8, 1, 207, 60, 2, 239, 112, 84, 61, 17, 8, 1, 207, 60, 2, + 239, 112, 84, 42, 17, 8, 1, 126, 2, 239, 112, 250, 26, 61, 17, 8, 1, 126, + 2, 239, 112, 250, 26, 42, 17, 8, 1, 87, 2, 239, 112, 84, 61, 17, 8, 1, + 87, 2, 239, 112, 84, 42, 17, 8, 1, 87, 2, 239, 112, 84, 78, 17, 8, 1, 87, + 2, 239, 112, 84, 169, 17, 8, 1, 126, 61, 17, 8, 1, 126, 42, 17, 8, 1, + 250, 39, 61, 17, 8, 1, 250, 39, 42, 17, 8, 1, 250, 39, 78, 17, 8, 1, 250, + 39, 169, 17, 8, 1, 212, 116, 227, 198, 61, 17, 8, 1, 212, 116, 227, 198, + 42, 17, 8, 1, 212, 116, 61, 17, 8, 1, 212, 116, 42, 17, 8, 1, 212, 116, + 78, 17, 8, 1, 212, 116, 169, 17, 8, 1, 212, 38, 61, 17, 8, 1, 212, 38, + 42, 17, 8, 1, 212, 38, 78, 17, 8, 1, 212, 38, 169, 17, 8, 1, 171, 61, 17, + 8, 1, 171, 42, 17, 8, 1, 171, 78, 17, 8, 1, 171, 169, 17, 8, 1, 140, 61, + 17, 8, 1, 140, 42, 17, 8, 1, 140, 78, 17, 8, 1, 140, 169, 17, 8, 1, 231, + 164, 61, 17, 8, 1, 231, 164, 42, 17, 8, 1, 231, 164, 78, 17, 8, 1, 231, + 164, 169, 17, 8, 1, 246, 118, 61, 17, 8, 1, 246, 118, 42, 17, 8, 1, 212, + 50, 61, 17, 8, 1, 212, 50, 42, 17, 8, 1, 219, 17, 61, 17, 8, 1, 219, 17, + 42, 17, 8, 1, 205, 109, 61, 17, 8, 1, 205, 109, 42, 17, 8, 1, 217, 71, + 61, 17, 8, 1, 217, 71, 42, 17, 8, 1, 217, 71, 78, 17, 8, 1, 217, 71, 169, + 17, 8, 1, 215, 211, 61, 17, 8, 1, 215, 211, 42, 17, 8, 1, 215, 211, 78, + 17, 8, 1, 215, 211, 169, 17, 8, 1, 217, 192, 61, 17, 8, 1, 217, 192, 42, + 17, 8, 1, 217, 192, 78, 17, 8, 1, 217, 192, 169, 17, 8, 1, 246, 141, 61, + 17, 8, 1, 246, 141, 42, 17, 8, 1, 246, 141, 78, 17, 8, 1, 246, 141, 169, + 17, 8, 1, 212, 195, 61, 17, 8, 1, 212, 195, 42, 17, 8, 1, 212, 195, 78, + 17, 8, 1, 212, 195, 169, 17, 8, 1, 205, 112, 61, 17, 8, 1, 205, 112, 42, + 17, 8, 1, 205, 112, 78, 17, 8, 1, 205, 112, 169, 17, 8, 1, 252, 201, 61, + 17, 8, 1, 252, 201, 42, 17, 8, 1, 252, 201, 78, 17, 8, 1, 252, 201, 169, + 17, 8, 1, 240, 95, 61, 17, 8, 1, 240, 95, 42, 17, 8, 1, 240, 95, 78, 17, + 8, 1, 240, 95, 169, 17, 8, 1, 242, 16, 61, 17, 8, 1, 242, 16, 42, 17, 8, + 1, 242, 16, 78, 17, 8, 1, 242, 16, 169, 17, 8, 1, 220, 13, 61, 17, 8, 1, + 220, 13, 42, 17, 8, 1, 220, 13, 78, 17, 8, 1, 220, 13, 169, 17, 8, 1, + 232, 46, 61, 17, 8, 1, 232, 46, 42, 17, 8, 1, 232, 46, 78, 17, 8, 1, 232, + 46, 169, 17, 8, 1, 230, 107, 61, 17, 8, 1, 230, 107, 42, 17, 8, 1, 230, + 107, 78, 17, 8, 1, 230, 107, 169, 17, 8, 1, 80, 61, 17, 8, 1, 80, 42, 17, + 8, 1, 80, 78, 17, 8, 1, 80, 169, 17, 8, 1, 224, 55, 61, 17, 8, 1, 224, + 55, 42, 17, 8, 1, 224, 55, 78, 17, 8, 1, 224, 55, 169, 17, 8, 1, 239, 51, + 61, 17, 8, 1, 239, 51, 42, 17, 8, 1, 239, 51, 78, 17, 8, 1, 239, 51, 169, + 17, 8, 1, 207, 60, 61, 17, 8, 1, 207, 60, 42, 17, 8, 1, 126, 227, 229, + 61, 17, 8, 1, 126, 227, 229, 42, 17, 8, 1, 87, 61, 17, 8, 1, 87, 42, 17, + 8, 1, 87, 78, 17, 8, 1, 87, 169, 17, 8, 28, 230, 107, 2, 126, 2, 228, 9, + 84, 61, 17, 8, 28, 230, 107, 2, 126, 2, 228, 9, 84, 42, 17, 8, 28, 230, + 107, 2, 126, 2, 239, 112, 84, 61, 17, 8, 28, 230, 107, 2, 126, 2, 239, + 112, 84, 42, 17, 8, 28, 230, 107, 2, 126, 2, 239, 112, 250, 26, 61, 17, + 8, 28, 230, 107, 2, 126, 2, 239, 112, 250, 26, 42, 17, 8, 28, 230, 107, + 2, 126, 61, 17, 8, 28, 230, 107, 2, 126, 42, 17, 205, 86, 207, 15, 224, + 66, 214, 153, 144, 242, 168, 83, 144, 219, 180, 83, 144, 43, 53, 144, + 245, 35, 53, 144, 221, 131, 53, 144, 252, 125, 144, 252, 53, 144, 47, + 221, 216, 144, 48, 221, 216, 144, 251, 209, 144, 101, 53, 144, 247, 155, + 144, 237, 238, 144, 241, 82, 213, 251, 144, 214, 180, 144, 18, 205, 85, + 144, 18, 102, 144, 18, 105, 144, 18, 142, 144, 18, 139, 144, 18, 168, + 144, 18, 184, 144, 18, 195, 144, 18, 193, 144, 18, 200, 144, 247, 162, + 144, 216, 52, 144, 230, 10, 53, 144, 242, 242, 53, 144, 239, 230, 53, + 144, 219, 196, 83, 144, 247, 153, 251, 199, 144, 7, 6, 1, 62, 144, 7, 6, + 1, 251, 150, 144, 7, 6, 1, 249, 34, 144, 7, 6, 1, 246, 240, 144, 7, 6, 1, + 75, 144, 7, 6, 1, 242, 139, 144, 7, 6, 1, 241, 55, 144, 7, 6, 1, 239, + 155, 144, 7, 6, 1, 74, 144, 7, 6, 1, 232, 203, 144, 7, 6, 1, 232, 76, + 144, 7, 6, 1, 149, 144, 7, 6, 1, 229, 28, 144, 7, 6, 1, 226, 33, 144, 7, + 6, 1, 76, 144, 7, 6, 1, 222, 67, 144, 7, 6, 1, 220, 27, 144, 7, 6, 1, + 137, 144, 7, 6, 1, 182, 144, 7, 6, 1, 213, 10, 144, 7, 6, 1, 71, 144, 7, + 6, 1, 209, 148, 144, 7, 6, 1, 207, 129, 144, 7, 6, 1, 206, 195, 144, 7, + 6, 1, 206, 123, 144, 7, 6, 1, 205, 159, 144, 47, 49, 145, 144, 218, 225, + 214, 180, 144, 48, 49, 145, 144, 247, 228, 253, 21, 144, 114, 229, 205, + 144, 239, 237, 253, 21, 144, 7, 5, 1, 62, 144, 7, 5, 1, 251, 150, 144, 7, + 5, 1, 249, 34, 144, 7, 5, 1, 246, 240, 144, 7, 5, 1, 75, 144, 7, 5, 1, + 242, 139, 144, 7, 5, 1, 241, 55, 144, 7, 5, 1, 239, 155, 144, 7, 5, 1, + 74, 144, 7, 5, 1, 232, 203, 144, 7, 5, 1, 232, 76, 144, 7, 5, 1, 149, + 144, 7, 5, 1, 229, 28, 144, 7, 5, 1, 226, 33, 144, 7, 5, 1, 76, 144, 7, + 5, 1, 222, 67, 144, 7, 5, 1, 220, 27, 144, 7, 5, 1, 137, 144, 7, 5, 1, + 182, 144, 7, 5, 1, 213, 10, 144, 7, 5, 1, 71, 144, 7, 5, 1, 209, 148, + 144, 7, 5, 1, 207, 129, 144, 7, 5, 1, 206, 195, 144, 7, 5, 1, 206, 123, + 144, 7, 5, 1, 205, 159, 144, 47, 247, 26, 145, 144, 79, 229, 205, 144, + 48, 247, 26, 145, 144, 211, 180, 144, 47, 59, 221, 216, 144, 48, 59, 221, + 216, 116, 128, 241, 82, 213, 251, 116, 47, 247, 92, 145, 116, 48, 247, + 92, 145, 116, 128, 247, 155, 116, 64, 226, 247, 245, 23, 116, 64, 1, 206, + 250, 116, 64, 1, 5, 62, 116, 64, 1, 5, 74, 116, 64, 1, 5, 71, 116, 64, 1, + 5, 75, 116, 64, 1, 5, 76, 116, 64, 1, 5, 190, 116, 64, 1, 5, 205, 213, + 116, 64, 1, 5, 205, 247, 116, 64, 1, 5, 210, 170, 116, 231, 248, 220, + 106, 214, 165, 83, 116, 64, 1, 62, 116, 64, 1, 74, 116, 64, 1, 71, 116, + 64, 1, 75, 116, 64, 1, 76, 116, 64, 1, 172, 116, 64, 1, 231, 123, 116, + 64, 1, 230, 236, 116, 64, 1, 231, 224, 116, 64, 1, 231, 53, 116, 64, 1, + 217, 199, 116, 64, 1, 215, 80, 116, 64, 1, 213, 203, 116, 64, 1, 217, 86, + 116, 64, 1, 214, 193, 116, 64, 1, 212, 219, 116, 64, 1, 211, 211, 116, + 64, 1, 210, 170, 116, 64, 1, 212, 131, 116, 64, 1, 124, 116, 64, 1, 199, + 116, 64, 1, 224, 230, 116, 64, 1, 223, 217, 116, 64, 1, 225, 110, 116, + 64, 1, 224, 67, 116, 64, 1, 155, 116, 64, 1, 239, 11, 116, 64, 1, 238, + 42, 116, 64, 1, 239, 71, 116, 64, 1, 238, 149, 116, 64, 1, 185, 116, 64, + 1, 226, 254, 116, 64, 1, 226, 114, 116, 64, 1, 227, 119, 116, 64, 1, 226, + 181, 116, 64, 1, 190, 116, 64, 1, 205, 213, 116, 64, 1, 205, 247, 116, + 64, 1, 219, 113, 116, 64, 1, 218, 208, 116, 64, 1, 218, 50, 116, 64, 1, + 219, 51, 116, 64, 1, 218, 124, 116, 64, 1, 207, 96, 116, 64, 1, 226, 33, + 116, 64, 208, 170, 214, 165, 83, 116, 64, 216, 57, 214, 165, 83, 116, 25, + 241, 232, 116, 25, 1, 231, 84, 116, 25, 1, 214, 88, 116, 25, 1, 231, 77, + 116, 25, 1, 224, 223, 116, 25, 1, 224, 221, 116, 25, 1, 224, 220, 116, + 25, 1, 211, 193, 116, 25, 1, 214, 77, 116, 25, 1, 218, 198, 116, 25, 1, + 218, 193, 116, 25, 1, 218, 190, 116, 25, 1, 218, 183, 116, 25, 1, 218, + 178, 116, 25, 1, 218, 173, 116, 25, 1, 218, 184, 116, 25, 1, 218, 196, + 116, 25, 1, 226, 240, 116, 25, 1, 221, 39, 116, 25, 1, 214, 85, 116, 25, + 1, 221, 28, 116, 25, 1, 215, 33, 116, 25, 1, 214, 82, 116, 25, 1, 233, + 125, 116, 25, 1, 247, 246, 116, 25, 1, 214, 92, 116, 25, 1, 248, 54, 116, + 25, 1, 231, 143, 116, 25, 1, 212, 15, 116, 25, 1, 221, 76, 116, 25, 1, + 239, 3, 116, 25, 1, 62, 116, 25, 1, 252, 248, 116, 25, 1, 190, 116, 25, + 1, 206, 98, 116, 25, 1, 243, 6, 116, 25, 1, 75, 116, 25, 1, 206, 39, 116, + 25, 1, 206, 52, 116, 25, 1, 76, 116, 25, 1, 207, 96, 116, 25, 1, 207, 92, + 116, 25, 1, 222, 206, 116, 25, 1, 205, 247, 116, 25, 1, 71, 116, 25, 1, + 207, 38, 116, 25, 1, 207, 51, 116, 25, 1, 207, 20, 116, 25, 1, 205, 213, + 116, 25, 1, 242, 192, 116, 25, 1, 206, 11, 116, 25, 1, 74, 144, 248, 131, + 53, 144, 220, 165, 53, 144, 224, 43, 53, 144, 228, 13, 144, 249, 111, + 134, 144, 206, 43, 53, 144, 206, 240, 53, 116, 241, 133, 147, 209, 22, + 116, 92, 45, 116, 167, 45, 116, 86, 45, 116, 173, 45, 116, 60, 214, 107, + 116, 59, 247, 233, 233, 14, 252, 98, 252, 119, 233, 14, 252, 98, 216, 39, + 233, 14, 252, 98, 212, 86, 222, 223, 218, 247, 248, 94, 218, 247, 248, + 94, 26, 63, 4, 251, 134, 62, 26, 63, 4, 251, 103, 75, 26, 63, 4, 251, + 112, 74, 26, 63, 4, 251, 80, 76, 26, 63, 4, 251, 130, 71, 26, 63, 4, 251, + 149, 246, 145, 26, 63, 4, 251, 96, 246, 9, 26, 63, 4, 251, 136, 245, 168, + 26, 63, 4, 251, 126, 245, 51, 26, 63, 4, 251, 90, 243, 237, 26, 63, 4, + 251, 84, 232, 200, 26, 63, 4, 251, 95, 232, 182, 26, 63, 4, 251, 105, + 232, 122, 26, 63, 4, 251, 76, 232, 104, 26, 63, 4, 251, 64, 172, 26, 63, + 4, 251, 97, 231, 224, 26, 63, 4, 251, 74, 231, 123, 26, 63, 4, 251, 71, + 231, 53, 26, 63, 4, 251, 60, 230, 236, 26, 63, 4, 251, 61, 185, 26, 63, + 4, 251, 127, 227, 119, 26, 63, 4, 251, 68, 226, 254, 26, 63, 4, 251, 125, + 226, 181, 26, 63, 4, 251, 117, 226, 114, 26, 63, 4, 251, 138, 199, 26, + 63, 4, 251, 116, 225, 110, 26, 63, 4, 251, 110, 224, 230, 26, 63, 4, 251, + 89, 224, 67, 26, 63, 4, 251, 86, 223, 217, 26, 63, 4, 251, 145, 179, 26, + 63, 4, 251, 69, 221, 174, 26, 63, 4, 251, 102, 221, 53, 26, 63, 4, 251, + 129, 220, 211, 26, 63, 4, 251, 91, 220, 82, 26, 63, 4, 251, 124, 220, 19, + 26, 63, 4, 251, 63, 219, 255, 26, 63, 4, 251, 119, 219, 237, 26, 63, 4, + 251, 108, 219, 226, 26, 63, 4, 251, 81, 219, 113, 26, 63, 4, 251, 113, + 219, 51, 26, 63, 4, 251, 88, 218, 208, 26, 63, 4, 251, 147, 218, 124, 26, + 63, 4, 251, 114, 218, 50, 26, 63, 4, 251, 109, 217, 199, 26, 63, 4, 251, + 132, 217, 86, 26, 63, 4, 251, 100, 215, 80, 26, 63, 4, 251, 128, 214, + 193, 26, 63, 4, 251, 83, 213, 203, 26, 63, 4, 251, 82, 212, 219, 26, 63, + 4, 251, 143, 212, 131, 26, 63, 4, 251, 104, 211, 211, 26, 63, 4, 251, + 141, 124, 26, 63, 4, 251, 72, 210, 170, 26, 63, 4, 251, 87, 207, 96, 26, + 63, 4, 251, 66, 207, 51, 26, 63, 4, 251, 101, 207, 20, 26, 63, 4, 251, + 99, 206, 250, 26, 63, 4, 251, 123, 205, 116, 26, 63, 4, 251, 67, 205, 93, + 26, 63, 4, 251, 120, 205, 19, 26, 63, 4, 251, 115, 254, 166, 26, 63, 4, + 251, 98, 254, 165, 26, 63, 4, 251, 57, 251, 184, 26, 63, 4, 251, 70, 243, + 205, 26, 63, 4, 251, 53, 243, 204, 26, 63, 4, 251, 93, 223, 153, 26, 63, + 4, 251, 111, 220, 80, 26, 63, 4, 251, 79, 220, 84, 26, 63, 4, 251, 65, + 219, 111, 26, 63, 4, 251, 107, 219, 110, 26, 63, 4, 251, 73, 218, 123, + 26, 63, 4, 251, 75, 212, 216, 26, 63, 4, 251, 55, 210, 128, 26, 63, 4, + 251, 52, 105, 26, 63, 16, 251, 122, 26, 63, 16, 251, 121, 26, 63, 16, + 251, 118, 26, 63, 16, 251, 106, 26, 63, 16, 251, 94, 26, 63, 16, 251, 92, + 26, 63, 16, 251, 85, 26, 63, 16, 251, 78, 26, 63, 16, 251, 77, 26, 63, + 16, 251, 62, 26, 63, 16, 251, 59, 26, 63, 16, 251, 58, 26, 63, 16, 251, + 56, 26, 63, 16, 251, 54, 26, 63, 122, 251, 51, 227, 221, 26, 63, 122, + 251, 50, 206, 244, 26, 63, 122, 251, 49, 245, 248, 26, 63, 122, 251, 48, + 242, 239, 26, 63, 122, 251, 47, 227, 192, 26, 63, 122, 251, 46, 214, 33, + 26, 63, 122, 251, 45, 242, 174, 26, 63, 122, 251, 44, 219, 77, 26, 63, + 122, 251, 43, 215, 213, 26, 63, 122, 251, 42, 239, 70, 26, 63, 122, 251, + 41, 214, 160, 26, 63, 122, 251, 40, 249, 182, 26, 63, 122, 251, 39, 247, + 75, 26, 63, 122, 251, 38, 249, 87, 26, 63, 122, 251, 37, 207, 28, 26, 63, + 122, 251, 36, 250, 125, 26, 63, 122, 251, 35, 222, 175, 26, 63, 122, 251, + 34, 214, 132, 26, 63, 122, 251, 33, 246, 248, 26, 63, 226, 160, 251, 32, + 232, 16, 26, 63, 226, 160, 251, 31, 232, 25, 26, 63, 122, 251, 30, 222, + 189, 26, 63, 122, 251, 29, 207, 5, 26, 63, 122, 251, 28, 26, 63, 226, + 160, 251, 27, 252, 12, 26, 63, 226, 160, 251, 26, 227, 76, 26, 63, 122, + 251, 25, 249, 110, 26, 63, 122, 251, 24, 240, 11, 26, 63, 122, 251, 23, + 26, 63, 122, 251, 22, 206, 235, 26, 63, 122, 251, 21, 26, 63, 122, 251, + 20, 26, 63, 122, 251, 19, 238, 69, 26, 63, 122, 251, 18, 26, 63, 122, + 251, 17, 26, 63, 122, 251, 16, 26, 63, 226, 160, 251, 14, 210, 142, 26, + 63, 122, 251, 13, 26, 63, 122, 251, 12, 26, 63, 122, 251, 11, 247, 186, + 26, 63, 122, 251, 10, 26, 63, 122, 251, 9, 26, 63, 122, 251, 8, 240, 201, + 26, 63, 122, 251, 7, 251, 255, 26, 63, 122, 251, 6, 26, 63, 122, 251, 5, + 26, 63, 122, 251, 4, 26, 63, 122, 251, 3, 26, 63, 122, 251, 2, 26, 63, + 122, 251, 1, 26, 63, 122, 251, 0, 26, 63, 122, 250, 255, 26, 63, 122, + 250, 254, 26, 63, 122, 250, 253, 226, 152, 26, 63, 122, 250, 252, 26, 63, + 122, 250, 251, 211, 61, 26, 63, 122, 250, 250, 26, 63, 122, 250, 249, 26, + 63, 122, 250, 248, 26, 63, 122, 250, 247, 26, 63, 122, 250, 246, 26, 63, + 122, 250, 245, 26, 63, 122, 250, 244, 26, 63, 122, 250, 243, 26, 63, 122, + 250, 242, 26, 63, 122, 250, 241, 26, 63, 122, 250, 240, 26, 63, 122, 250, + 239, 239, 43, 26, 63, 122, 250, 218, 241, 144, 26, 63, 122, 250, 215, + 250, 103, 26, 63, 122, 250, 210, 214, 139, 26, 63, 122, 250, 209, 45, 26, + 63, 122, 250, 208, 26, 63, 122, 250, 207, 213, 95, 26, 63, 122, 250, 206, + 26, 63, 122, 250, 205, 26, 63, 122, 250, 204, 207, 24, 248, 91, 26, 63, + 122, 250, 203, 248, 91, 26, 63, 122, 250, 202, 248, 92, 241, 112, 26, 63, + 122, 250, 201, 207, 26, 26, 63, 122, 250, 200, 26, 63, 122, 250, 199, 26, + 63, 226, 160, 250, 198, 245, 105, 26, 63, 122, 250, 197, 26, 63, 122, + 250, 196, 26, 63, 122, 250, 194, 26, 63, 122, 250, 193, 26, 63, 122, 250, + 192, 26, 63, 122, 250, 191, 246, 81, 26, 63, 122, 250, 190, 26, 63, 122, + 250, 189, 26, 63, 122, 250, 188, 26, 63, 122, 250, 187, 26, 63, 122, 250, + 186, 26, 63, 122, 208, 225, 251, 15, 26, 63, 122, 208, 225, 250, 238, 26, + 63, 122, 208, 225, 250, 237, 26, 63, 122, 208, 225, 250, 236, 26, 63, + 122, 208, 225, 250, 235, 26, 63, 122, 208, 225, 250, 234, 26, 63, 122, + 208, 225, 250, 233, 26, 63, 122, 208, 225, 250, 232, 26, 63, 122, 208, + 225, 250, 231, 26, 63, 122, 208, 225, 250, 230, 26, 63, 122, 208, 225, + 250, 229, 26, 63, 122, 208, 225, 250, 228, 26, 63, 122, 208, 225, 250, + 227, 26, 63, 122, 208, 225, 250, 226, 26, 63, 122, 208, 225, 250, 225, + 26, 63, 122, 208, 225, 250, 224, 26, 63, 122, 208, 225, 250, 223, 26, 63, + 122, 208, 225, 250, 222, 26, 63, 122, 208, 225, 250, 221, 26, 63, 122, + 208, 225, 250, 220, 26, 63, 122, 208, 225, 250, 219, 26, 63, 122, 208, + 225, 250, 217, 26, 63, 122, 208, 225, 250, 216, 26, 63, 122, 208, 225, + 250, 214, 26, 63, 122, 208, 225, 250, 213, 26, 63, 122, 208, 225, 250, + 212, 26, 63, 122, 208, 225, 250, 211, 26, 63, 122, 208, 225, 250, 195, + 26, 63, 122, 208, 225, 250, 185, 252, 241, 206, 232, 216, 40, 229, 205, + 252, 241, 206, 232, 216, 40, 245, 23, 252, 241, 248, 81, 83, 252, 241, + 43, 102, 252, 241, 43, 105, 252, 241, 43, 142, 252, 241, 43, 139, 252, + 241, 43, 168, 252, 241, 43, 184, 252, 241, 43, 195, 252, 241, 43, 193, + 252, 241, 43, 200, 252, 241, 43, 212, 98, 252, 241, 43, 210, 123, 252, + 241, 43, 212, 3, 252, 241, 43, 241, 130, 252, 241, 43, 241, 243, 252, + 241, 43, 214, 252, 252, 241, 43, 216, 17, 252, 241, 43, 243, 79, 252, + 241, 43, 224, 190, 252, 241, 43, 119, 238, 29, 252, 241, 43, 118, 238, + 29, 252, 241, 43, 129, 238, 29, 252, 241, 43, 241, 125, 238, 29, 252, + 241, 43, 241, 204, 238, 29, 252, 241, 43, 215, 10, 238, 29, 252, 241, 43, + 216, 23, 238, 29, 252, 241, 43, 243, 88, 238, 29, 252, 241, 43, 224, 195, + 238, 29, 252, 241, 43, 119, 211, 242, 252, 241, 43, 118, 211, 242, 252, + 241, 43, 129, 211, 242, 252, 241, 43, 241, 125, 211, 242, 252, 241, 43, + 241, 204, 211, 242, 252, 241, 43, 215, 10, 211, 242, 252, 241, 43, 216, + 23, 211, 242, 252, 241, 43, 243, 88, 211, 242, 252, 241, 43, 224, 195, + 211, 242, 252, 241, 43, 212, 99, 211, 242, 252, 241, 43, 210, 124, 211, + 242, 252, 241, 43, 212, 4, 211, 242, 252, 241, 43, 241, 131, 211, 242, + 252, 241, 43, 241, 244, 211, 242, 252, 241, 43, 214, 253, 211, 242, 252, + 241, 43, 216, 18, 211, 242, 252, 241, 43, 243, 80, 211, 242, 252, 241, + 43, 224, 191, 211, 242, 252, 241, 207, 41, 250, 117, 209, 216, 252, 241, + 207, 41, 241, 215, 213, 177, 252, 241, 207, 41, 217, 80, 213, 177, 252, + 241, 207, 41, 212, 11, 213, 177, 252, 241, 207, 41, 241, 118, 213, 177, + 252, 241, 243, 240, 227, 118, 241, 215, 213, 177, 252, 241, 229, 189, + 227, 118, 241, 215, 213, 177, 252, 241, 227, 118, 217, 80, 213, 177, 252, + 241, 227, 118, 212, 11, 213, 177, 27, 253, 12, 251, 186, 119, 219, 204, + 27, 253, 12, 251, 186, 119, 239, 121, 27, 253, 12, 251, 186, 119, 244, 3, + 27, 253, 12, 251, 186, 168, 27, 253, 12, 251, 186, 241, 243, 27, 253, 12, + 251, 186, 241, 204, 238, 29, 27, 253, 12, 251, 186, 241, 204, 211, 242, + 27, 253, 12, 251, 186, 241, 244, 211, 242, 27, 253, 12, 251, 186, 241, + 204, 212, 181, 27, 253, 12, 251, 186, 212, 99, 212, 181, 27, 253, 12, + 251, 186, 241, 244, 212, 181, 27, 253, 12, 251, 186, 119, 238, 30, 212, + 181, 27, 253, 12, 251, 186, 241, 204, 238, 30, 212, 181, 27, 253, 12, + 251, 186, 119, 211, 243, 212, 181, 27, 253, 12, 251, 186, 241, 204, 211, + 243, 212, 181, 27, 253, 12, 251, 186, 241, 204, 214, 20, 27, 253, 12, + 251, 186, 212, 99, 214, 20, 27, 253, 12, 251, 186, 241, 244, 214, 20, 27, + 253, 12, 251, 186, 119, 238, 30, 214, 20, 27, 253, 12, 251, 186, 241, + 204, 238, 30, 214, 20, 27, 253, 12, 251, 186, 119, 211, 243, 214, 20, 27, + 253, 12, 251, 186, 212, 99, 211, 243, 214, 20, 27, 253, 12, 251, 186, + 241, 244, 211, 243, 214, 20, 27, 253, 12, 251, 186, 212, 99, 226, 184, + 27, 253, 12, 239, 37, 119, 220, 228, 27, 253, 12, 212, 25, 102, 27, 253, + 12, 239, 33, 102, 27, 253, 12, 242, 248, 105, 27, 253, 12, 212, 25, 105, + 27, 253, 12, 246, 245, 118, 244, 2, 27, 253, 12, 242, 248, 118, 244, 2, + 27, 253, 12, 211, 28, 168, 27, 253, 12, 211, 28, 212, 98, 27, 253, 12, + 211, 28, 212, 99, 252, 141, 17, 27, 253, 12, 239, 33, 212, 98, 27, 253, + 12, 227, 65, 212, 98, 27, 253, 12, 212, 25, 212, 98, 27, 253, 12, 212, + 25, 212, 3, 27, 253, 12, 211, 28, 241, 243, 27, 253, 12, 211, 28, 241, + 244, 252, 141, 17, 27, 253, 12, 239, 33, 241, 243, 27, 253, 12, 212, 25, + 241, 243, 27, 253, 12, 212, 25, 119, 238, 29, 27, 253, 12, 212, 25, 129, + 238, 29, 27, 253, 12, 242, 248, 241, 204, 238, 29, 27, 253, 12, 211, 28, + 241, 204, 238, 29, 27, 253, 12, 212, 25, 241, 204, 238, 29, 27, 253, 12, + 248, 187, 241, 204, 238, 29, 27, 253, 12, 225, 186, 241, 204, 238, 29, + 27, 253, 12, 212, 25, 119, 211, 242, 27, 253, 12, 212, 25, 241, 204, 211, + 242, 27, 253, 12, 245, 230, 241, 204, 226, 184, 27, 253, 12, 213, 240, + 241, 244, 226, 184, 27, 119, 160, 53, 27, 119, 160, 3, 252, 141, 17, 27, + 118, 212, 8, 53, 27, 129, 219, 203, 53, 27, 206, 50, 53, 27, 212, 182, + 53, 27, 244, 4, 53, 27, 222, 220, 53, 27, 118, 222, 219, 53, 27, 129, + 222, 219, 53, 27, 241, 125, 222, 219, 53, 27, 241, 204, 222, 219, 53, 27, + 227, 59, 53, 27, 230, 167, 250, 117, 53, 27, 229, 182, 53, 27, 222, 94, + 53, 27, 206, 172, 53, 27, 251, 237, 53, 27, 251, 251, 53, 27, 239, 244, + 53, 27, 210, 246, 250, 117, 53, 27, 205, 86, 53, 27, 119, 219, 205, 53, + 27, 215, 35, 53, 218, 109, 216, 14, 53, 218, 109, 209, 228, 53, 218, 109, + 216, 44, 53, 218, 109, 216, 12, 53, 218, 109, 245, 120, 216, 12, 53, 218, + 109, 215, 54, 53, 218, 109, 245, 226, 53, 218, 109, 219, 188, 53, 218, + 109, 216, 30, 53, 218, 109, 243, 219, 53, 218, 109, 251, 232, 53, 218, + 109, 248, 124, 53, 27, 16, 212, 152, 218, 210, 221, 88, 245, 98, 3, 221, + 166, 221, 88, 245, 98, 3, 220, 220, 239, 68, 221, 88, 245, 98, 3, 212, + 155, 239, 68, 221, 88, 245, 98, 3, 248, 207, 221, 88, 245, 98, 3, 248, + 49, 221, 88, 245, 98, 3, 206, 244, 221, 88, 245, 98, 3, 239, 43, 221, 88, + 245, 98, 3, 240, 193, 221, 88, 245, 98, 3, 211, 209, 221, 88, 245, 98, 3, + 45, 221, 88, 245, 98, 3, 249, 146, 221, 88, 245, 98, 3, 215, 180, 221, + 88, 245, 98, 3, 247, 180, 221, 88, 245, 98, 3, 227, 220, 221, 88, 245, + 98, 3, 227, 167, 221, 88, 245, 98, 3, 217, 121, 221, 88, 245, 98, 3, 229, + 231, 221, 88, 245, 98, 3, 249, 167, 221, 88, 245, 98, 3, 248, 192, 220, + 233, 221, 88, 245, 98, 3, 245, 36, 221, 88, 245, 98, 3, 247, 159, 221, + 88, 245, 98, 3, 214, 224, 221, 88, 245, 98, 3, 247, 160, 221, 88, 245, + 98, 3, 250, 47, 221, 88, 245, 98, 3, 215, 167, 221, 88, 245, 98, 3, 238, + 69, 221, 88, 245, 98, 3, 239, 9, 221, 88, 245, 98, 3, 249, 82, 230, 34, + 221, 88, 245, 98, 3, 248, 183, 221, 88, 245, 98, 3, 219, 77, 221, 88, + 245, 98, 3, 243, 127, 221, 88, 245, 98, 3, 244, 9, 221, 88, 245, 98, 3, + 210, 156, 221, 88, 245, 98, 3, 250, 50, 221, 88, 245, 98, 3, 220, 234, + 211, 61, 221, 88, 245, 98, 3, 208, 195, 221, 88, 245, 98, 3, 221, 232, + 221, 88, 245, 98, 3, 218, 100, 221, 88, 245, 98, 3, 229, 216, 221, 88, + 245, 98, 3, 222, 77, 250, 176, 221, 88, 245, 98, 3, 241, 168, 221, 88, + 245, 98, 3, 239, 238, 221, 88, 245, 98, 3, 213, 241, 221, 88, 245, 98, 3, + 5, 251, 160, 221, 88, 245, 98, 3, 207, 61, 250, 136, 221, 88, 245, 98, 3, + 36, 222, 222, 91, 229, 40, 1, 62, 229, 40, 1, 75, 229, 40, 1, 251, 150, + 229, 40, 1, 250, 1, 229, 40, 1, 241, 55, 229, 40, 1, 246, 240, 229, 40, + 1, 74, 229, 40, 1, 207, 129, 229, 40, 1, 205, 159, 229, 40, 1, 212, 58, + 229, 40, 1, 232, 203, 229, 40, 1, 232, 76, 229, 40, 1, 220, 27, 229, 40, + 1, 149, 229, 40, 1, 229, 28, 229, 40, 1, 226, 33, 229, 40, 1, 226, 186, + 229, 40, 1, 224, 104, 229, 40, 1, 71, 229, 40, 1, 222, 67, 229, 40, 1, + 231, 73, 229, 40, 1, 137, 229, 40, 1, 182, 229, 40, 1, 213, 10, 229, 40, + 1, 210, 211, 229, 40, 1, 252, 122, 229, 40, 1, 243, 41, 229, 40, 1, 239, + 155, 229, 40, 1, 206, 195, 248, 198, 1, 62, 248, 198, 1, 222, 53, 248, + 198, 1, 246, 240, 248, 198, 1, 149, 248, 198, 1, 209, 160, 248, 198, 1, + 137, 248, 198, 1, 230, 62, 248, 198, 1, 254, 166, 248, 198, 1, 220, 27, + 248, 198, 1, 251, 150, 248, 198, 1, 229, 28, 248, 198, 1, 76, 248, 198, + 1, 246, 147, 248, 198, 1, 213, 10, 248, 198, 1, 216, 4, 248, 198, 1, 216, + 3, 248, 198, 1, 182, 248, 198, 1, 249, 33, 248, 198, 1, 71, 248, 198, 1, + 224, 104, 248, 198, 1, 206, 195, 248, 198, 1, 226, 33, 248, 198, 1, 210, + 210, 248, 198, 1, 222, 67, 248, 198, 1, 214, 99, 248, 198, 1, 74, 248, + 198, 1, 75, 248, 198, 1, 209, 157, 248, 198, 1, 232, 76, 248, 198, 1, + 232, 67, 248, 198, 1, 225, 153, 248, 198, 1, 209, 162, 248, 198, 1, 241, + 55, 248, 198, 1, 240, 246, 248, 198, 1, 214, 40, 248, 198, 1, 214, 39, + 248, 198, 1, 225, 79, 248, 198, 1, 233, 102, 248, 198, 1, 249, 32, 248, + 198, 1, 210, 211, 248, 198, 1, 209, 159, 248, 198, 1, 218, 90, 248, 198, + 1, 227, 158, 248, 198, 1, 227, 157, 248, 198, 1, 227, 156, 248, 198, 1, + 227, 155, 248, 198, 1, 230, 61, 248, 198, 1, 243, 131, 248, 198, 1, 209, + 158, 81, 242, 251, 211, 241, 83, 81, 242, 251, 18, 102, 81, 242, 251, 18, + 105, 81, 242, 251, 18, 142, 81, 242, 251, 18, 139, 81, 242, 251, 18, 168, + 81, 242, 251, 18, 184, 81, 242, 251, 18, 195, 81, 242, 251, 18, 193, 81, + 242, 251, 18, 200, 81, 242, 251, 43, 212, 98, 81, 242, 251, 43, 210, 123, + 81, 242, 251, 43, 212, 3, 81, 242, 251, 43, 241, 130, 81, 242, 251, 43, + 241, 243, 81, 242, 251, 43, 214, 252, 81, 242, 251, 43, 216, 17, 81, 242, + 251, 43, 243, 79, 81, 242, 251, 43, 224, 190, 81, 242, 251, 43, 119, 238, + 29, 81, 242, 251, 43, 118, 238, 29, 81, 242, 251, 43, 129, 238, 29, 81, + 242, 251, 43, 241, 125, 238, 29, 81, 242, 251, 43, 241, 204, 238, 29, 81, + 242, 251, 43, 215, 10, 238, 29, 81, 242, 251, 43, 216, 23, 238, 29, 81, + 242, 251, 43, 243, 88, 238, 29, 81, 242, 251, 43, 224, 195, 238, 29, 44, + 35, 1, 62, 44, 35, 1, 250, 61, 44, 35, 1, 231, 224, 44, 35, 1, 246, 9, + 44, 35, 1, 75, 44, 35, 1, 209, 39, 44, 35, 1, 205, 93, 44, 35, 1, 239, + 71, 44, 35, 1, 212, 41, 44, 35, 1, 74, 44, 35, 1, 172, 44, 35, 1, 243, + 68, 44, 35, 1, 243, 50, 44, 35, 1, 243, 41, 44, 35, 1, 242, 215, 44, 35, + 1, 76, 44, 35, 1, 221, 174, 44, 35, 1, 215, 214, 44, 35, 1, 230, 236, 44, + 35, 1, 242, 235, 44, 35, 1, 242, 225, 44, 35, 1, 212, 131, 44, 35, 1, 71, + 44, 35, 1, 243, 71, 44, 35, 1, 221, 81, 44, 35, 1, 231, 152, 44, 35, 1, + 243, 97, 44, 35, 1, 242, 227, 44, 35, 1, 248, 82, 44, 35, 1, 233, 102, + 44, 35, 1, 209, 162, 44, 35, 1, 242, 208, 44, 35, 223, 177, 102, 44, 35, + 223, 177, 168, 44, 35, 223, 177, 212, 98, 44, 35, 223, 177, 241, 243, + 239, 253, 1, 252, 208, 239, 253, 1, 250, 153, 239, 253, 1, 240, 58, 239, + 253, 1, 246, 127, 239, 253, 1, 252, 204, 239, 253, 1, 220, 10, 239, 253, + 1, 232, 215, 239, 253, 1, 239, 134, 239, 253, 1, 211, 255, 239, 253, 1, + 243, 78, 239, 253, 1, 230, 204, 239, 253, 1, 230, 118, 239, 253, 1, 227, + 213, 239, 253, 1, 225, 188, 239, 253, 1, 232, 175, 239, 253, 1, 209, 180, + 239, 253, 1, 222, 29, 239, 253, 1, 224, 190, 239, 253, 1, 219, 89, 239, + 253, 1, 217, 124, 239, 253, 1, 212, 112, 239, 253, 1, 207, 3, 239, 253, + 1, 242, 54, 239, 253, 1, 233, 106, 239, 253, 1, 238, 14, 239, 253, 1, + 222, 102, 239, 253, 1, 224, 195, 238, 29, 44, 221, 122, 1, 252, 122, 44, + 221, 122, 1, 249, 68, 44, 221, 122, 1, 240, 228, 44, 221, 122, 1, 245, + 39, 44, 221, 122, 1, 75, 44, 221, 122, 1, 205, 63, 44, 221, 122, 1, 243, + 188, 44, 221, 122, 1, 205, 100, 44, 221, 122, 1, 243, 186, 44, 221, 122, + 1, 74, 44, 221, 122, 1, 231, 42, 44, 221, 122, 1, 230, 30, 44, 221, 122, + 1, 227, 81, 44, 221, 122, 1, 225, 99, 44, 221, 122, 1, 208, 160, 44, 221, + 122, 1, 221, 163, 44, 221, 122, 1, 219, 15, 44, 221, 122, 1, 215, 61, 44, + 221, 122, 1, 212, 193, 44, 221, 122, 1, 71, 44, 221, 122, 1, 248, 66, 44, + 221, 122, 1, 215, 151, 44, 221, 122, 1, 215, 216, 44, 221, 122, 1, 205, + 215, 44, 221, 122, 1, 206, 30, 44, 221, 122, 1, 76, 44, 221, 122, 1, 222, + 152, 44, 221, 122, 1, 243, 97, 44, 221, 122, 1, 155, 44, 221, 122, 1, + 210, 221, 44, 221, 122, 1, 209, 27, 44, 221, 122, 1, 206, 34, 44, 221, + 122, 1, 206, 32, 44, 221, 122, 1, 206, 65, 44, 221, 122, 1, 233, 129, 44, + 221, 122, 1, 205, 213, 44, 221, 122, 1, 190, 44, 221, 122, 1, 237, 190, + 36, 44, 221, 122, 1, 252, 122, 36, 44, 221, 122, 1, 245, 39, 36, 44, 221, + 122, 1, 205, 100, 36, 44, 221, 122, 1, 225, 99, 36, 44, 221, 122, 1, 215, + 61, 209, 254, 1, 252, 148, 209, 254, 1, 250, 8, 209, 254, 1, 240, 216, + 209, 254, 1, 231, 167, 209, 254, 1, 245, 227, 209, 254, 1, 238, 149, 209, + 254, 1, 206, 250, 209, 254, 1, 205, 84, 209, 254, 1, 238, 61, 209, 254, + 1, 212, 80, 209, 254, 1, 205, 236, 209, 254, 1, 232, 45, 209, 254, 1, + 215, 171, 209, 254, 1, 230, 102, 209, 254, 1, 227, 90, 209, 254, 1, 245, + 188, 209, 254, 1, 223, 173, 209, 254, 1, 205, 9, 209, 254, 1, 217, 156, + 209, 254, 1, 252, 200, 209, 254, 1, 220, 82, 209, 254, 1, 217, 190, 209, + 254, 1, 219, 219, 209, 254, 1, 219, 68, 209, 254, 1, 212, 45, 209, 254, + 1, 240, 94, 209, 254, 1, 124, 209, 254, 1, 74, 209, 254, 1, 71, 209, 254, + 1, 214, 51, 209, 254, 206, 232, 245, 79, 44, 221, 116, 3, 62, 44, 221, + 116, 3, 74, 44, 221, 116, 3, 71, 44, 221, 116, 3, 172, 44, 221, 116, 3, + 230, 236, 44, 221, 116, 3, 240, 244, 44, 221, 116, 3, 239, 213, 44, 221, + 116, 3, 206, 181, 44, 221, 116, 3, 249, 1, 44, 221, 116, 3, 232, 200, 44, + 221, 116, 3, 232, 162, 44, 221, 116, 3, 212, 219, 44, 221, 116, 3, 210, + 170, 44, 221, 116, 3, 246, 145, 44, 221, 116, 3, 245, 168, 44, 221, 116, + 3, 243, 237, 44, 221, 116, 3, 212, 56, 44, 221, 116, 3, 179, 44, 221, + 116, 3, 250, 183, 44, 221, 116, 3, 242, 73, 44, 221, 116, 3, 199, 44, + 221, 116, 3, 223, 217, 44, 221, 116, 3, 185, 44, 221, 116, 3, 226, 254, + 44, 221, 116, 3, 226, 114, 44, 221, 116, 3, 190, 44, 221, 116, 3, 209, + 70, 44, 221, 116, 3, 208, 214, 44, 221, 116, 3, 219, 113, 44, 221, 116, + 3, 218, 50, 44, 221, 116, 3, 230, 141, 44, 221, 116, 3, 217, 199, 44, + 221, 116, 3, 205, 116, 44, 221, 116, 3, 216, 2, 44, 221, 116, 3, 214, 96, + 44, 221, 116, 3, 155, 44, 221, 116, 3, 251, 178, 44, 221, 116, 3, 251, + 177, 44, 221, 116, 3, 251, 176, 44, 221, 116, 3, 206, 152, 44, 221, 116, + 3, 246, 123, 44, 221, 116, 3, 246, 122, 44, 221, 116, 3, 250, 161, 44, + 221, 116, 3, 249, 53, 44, 221, 116, 206, 232, 245, 79, 44, 221, 116, 43, + 102, 44, 221, 116, 43, 105, 44, 221, 116, 43, 212, 98, 44, 221, 116, 43, + 210, 123, 44, 221, 116, 43, 238, 29, 245, 208, 6, 1, 152, 74, 245, 208, + 6, 1, 152, 75, 245, 208, 6, 1, 152, 62, 245, 208, 6, 1, 152, 252, 213, + 245, 208, 6, 1, 152, 76, 245, 208, 6, 1, 152, 222, 152, 245, 208, 6, 1, + 215, 144, 74, 245, 208, 6, 1, 215, 144, 75, 245, 208, 6, 1, 215, 144, 62, + 245, 208, 6, 1, 215, 144, 252, 213, 245, 208, 6, 1, 215, 144, 76, 245, + 208, 6, 1, 215, 144, 222, 152, 245, 208, 6, 1, 251, 159, 245, 208, 6, 1, + 222, 78, 245, 208, 6, 1, 206, 216, 245, 208, 6, 1, 206, 49, 245, 208, 6, + 1, 239, 155, 245, 208, 6, 1, 221, 164, 245, 208, 6, 1, 250, 50, 245, 208, + 6, 1, 212, 120, 245, 208, 6, 1, 245, 251, 245, 208, 6, 1, 248, 78, 245, + 208, 6, 1, 232, 180, 245, 208, 6, 1, 231, 231, 245, 208, 6, 1, 240, 191, + 245, 208, 6, 1, 243, 97, 245, 208, 6, 1, 209, 34, 245, 208, 6, 1, 242, + 196, 245, 208, 6, 1, 212, 39, 245, 208, 6, 1, 242, 225, 245, 208, 6, 1, + 205, 91, 245, 208, 6, 1, 242, 215, 245, 208, 6, 1, 205, 71, 245, 208, 6, + 1, 242, 235, 245, 208, 6, 1, 243, 68, 245, 208, 6, 1, 243, 50, 245, 208, + 6, 1, 243, 41, 245, 208, 6, 1, 243, 28, 245, 208, 6, 1, 222, 191, 245, + 208, 6, 1, 242, 175, 245, 208, 5, 1, 152, 74, 245, 208, 5, 1, 152, 75, + 245, 208, 5, 1, 152, 62, 245, 208, 5, 1, 152, 252, 213, 245, 208, 5, 1, + 152, 76, 245, 208, 5, 1, 152, 222, 152, 245, 208, 5, 1, 215, 144, 74, + 245, 208, 5, 1, 215, 144, 75, 245, 208, 5, 1, 215, 144, 62, 245, 208, 5, + 1, 215, 144, 252, 213, 245, 208, 5, 1, 215, 144, 76, 245, 208, 5, 1, 215, + 144, 222, 152, 245, 208, 5, 1, 251, 159, 245, 208, 5, 1, 222, 78, 245, + 208, 5, 1, 206, 216, 245, 208, 5, 1, 206, 49, 245, 208, 5, 1, 239, 155, + 245, 208, 5, 1, 221, 164, 245, 208, 5, 1, 250, 50, 245, 208, 5, 1, 212, + 120, 245, 208, 5, 1, 245, 251, 245, 208, 5, 1, 248, 78, 245, 208, 5, 1, + 232, 180, 245, 208, 5, 1, 231, 231, 245, 208, 5, 1, 240, 191, 245, 208, + 5, 1, 243, 97, 245, 208, 5, 1, 209, 34, 245, 208, 5, 1, 242, 196, 245, + 208, 5, 1, 212, 39, 245, 208, 5, 1, 242, 225, 245, 208, 5, 1, 205, 91, + 245, 208, 5, 1, 242, 215, 245, 208, 5, 1, 205, 71, 245, 208, 5, 1, 242, + 235, 245, 208, 5, 1, 243, 68, 245, 208, 5, 1, 243, 50, 245, 208, 5, 1, + 243, 41, 245, 208, 5, 1, 243, 28, 245, 208, 5, 1, 222, 191, 245, 208, 5, + 1, 242, 175, 215, 221, 1, 221, 161, 215, 221, 1, 211, 91, 215, 221, 1, + 231, 119, 215, 221, 1, 242, 21, 215, 221, 1, 212, 14, 215, 221, 1, 214, + 193, 215, 221, 1, 213, 130, 215, 221, 1, 248, 6, 215, 221, 1, 206, 51, + 215, 221, 1, 238, 27, 215, 221, 1, 249, 243, 215, 221, 1, 246, 8, 215, + 221, 1, 240, 230, 215, 221, 1, 208, 155, 215, 221, 1, 212, 20, 215, 221, + 1, 205, 17, 215, 221, 1, 227, 117, 215, 221, 1, 232, 102, 215, 221, 1, + 206, 248, 215, 221, 1, 239, 143, 215, 221, 1, 229, 130, 215, 221, 1, 226, + 210, 215, 221, 1, 233, 109, 215, 221, 1, 243, 96, 215, 221, 1, 251, 225, + 215, 221, 1, 252, 252, 215, 221, 1, 222, 165, 215, 221, 1, 206, 235, 215, + 221, 1, 222, 93, 215, 221, 1, 252, 213, 215, 221, 1, 218, 121, 215, 221, + 1, 223, 173, 215, 221, 1, 243, 113, 215, 221, 1, 252, 218, 215, 221, 1, + 237, 181, 215, 221, 1, 209, 206, 215, 221, 1, 222, 228, 215, 221, 1, 222, + 144, 215, 221, 1, 222, 189, 215, 221, 1, 251, 162, 215, 221, 1, 252, 14, + 215, 221, 1, 222, 122, 215, 221, 1, 252, 196, 215, 221, 1, 242, 229, 215, + 221, 1, 251, 248, 215, 221, 1, 243, 124, 215, 221, 1, 237, 189, 215, 221, + 1, 206, 16, 222, 104, 1, 252, 172, 222, 104, 1, 250, 183, 222, 104, 1, + 212, 219, 222, 104, 1, 232, 200, 222, 104, 1, 206, 181, 222, 104, 1, 231, + 167, 222, 104, 1, 245, 250, 222, 104, 1, 219, 113, 222, 104, 1, 217, 199, + 222, 104, 1, 215, 177, 222, 104, 1, 245, 192, 222, 104, 1, 248, 173, 222, + 104, 1, 240, 244, 222, 104, 1, 242, 73, 222, 104, 1, 220, 17, 222, 104, + 1, 232, 61, 222, 104, 1, 230, 136, 222, 104, 1, 226, 223, 222, 104, 1, + 223, 157, 222, 104, 1, 207, 59, 222, 104, 1, 155, 222, 104, 1, 190, 222, + 104, 1, 62, 222, 104, 1, 75, 222, 104, 1, 74, 222, 104, 1, 76, 222, 104, + 1, 71, 222, 104, 1, 253, 164, 222, 104, 1, 243, 104, 222, 104, 1, 222, + 152, 222, 104, 18, 205, 85, 222, 104, 18, 102, 222, 104, 18, 105, 222, + 104, 18, 142, 222, 104, 18, 139, 222, 104, 18, 168, 222, 104, 18, 184, + 222, 104, 18, 195, 222, 104, 18, 193, 222, 104, 18, 200, 243, 64, 1, 62, + 243, 64, 1, 250, 61, 243, 64, 1, 248, 148, 243, 64, 1, 248, 82, 243, 64, + 1, 246, 9, 243, 64, 1, 225, 143, 243, 64, 1, 245, 183, 243, 64, 1, 243, + 90, 243, 64, 1, 75, 243, 64, 1, 242, 28, 243, 64, 1, 240, 170, 243, 64, + 1, 240, 32, 243, 64, 1, 239, 71, 243, 64, 1, 74, 243, 64, 1, 232, 182, + 243, 64, 1, 231, 224, 243, 64, 1, 230, 58, 243, 64, 1, 229, 168, 243, 64, + 1, 227, 119, 243, 64, 1, 225, 110, 243, 64, 1, 199, 243, 64, 1, 224, 173, + 243, 64, 1, 76, 243, 64, 1, 221, 174, 243, 64, 1, 219, 255, 243, 64, 1, + 219, 51, 243, 64, 1, 218, 84, 243, 64, 1, 217, 86, 243, 64, 1, 215, 214, + 243, 64, 1, 212, 131, 243, 64, 1, 212, 41, 243, 64, 1, 71, 243, 64, 1, + 209, 39, 243, 64, 1, 206, 175, 243, 64, 1, 206, 123, 243, 64, 1, 205, 93, + 243, 64, 1, 205, 72, 243, 64, 1, 240, 85, 243, 64, 1, 240, 91, 243, 64, + 1, 231, 152, 248, 180, 252, 173, 1, 252, 143, 248, 180, 252, 173, 1, 250, + 10, 248, 180, 252, 173, 1, 240, 49, 248, 180, 252, 173, 1, 246, 74, 248, + 180, 252, 173, 1, 243, 112, 248, 180, 252, 173, 1, 205, 103, 248, 180, + 252, 173, 1, 242, 147, 248, 180, 252, 173, 1, 205, 66, 248, 180, 252, + 173, 1, 212, 157, 248, 180, 252, 173, 1, 248, 110, 248, 180, 252, 173, 1, + 205, 224, 248, 180, 252, 173, 1, 205, 81, 248, 180, 252, 173, 1, 232, + 242, 248, 180, 252, 173, 1, 216, 2, 248, 180, 252, 173, 1, 230, 95, 248, + 180, 252, 173, 1, 232, 254, 248, 180, 252, 173, 1, 206, 171, 248, 180, + 252, 173, 1, 243, 203, 248, 180, 252, 173, 1, 248, 204, 248, 180, 252, + 173, 1, 232, 163, 248, 180, 252, 173, 1, 232, 7, 248, 180, 252, 173, 1, + 229, 37, 248, 180, 252, 173, 1, 239, 22, 248, 180, 252, 173, 1, 220, 0, + 248, 180, 252, 173, 1, 252, 70, 248, 180, 252, 173, 1, 248, 23, 248, 180, + 252, 173, 1, 248, 58, 248, 180, 252, 173, 1, 246, 252, 248, 180, 252, + 173, 1, 227, 202, 248, 180, 252, 173, 1, 220, 4, 248, 180, 252, 173, 1, + 224, 28, 248, 180, 252, 173, 1, 243, 181, 248, 180, 252, 173, 1, 215, + 242, 248, 180, 252, 173, 1, 232, 183, 248, 180, 252, 173, 1, 222, 165, + 248, 180, 252, 173, 1, 210, 99, 248, 180, 252, 173, 1, 242, 49, 248, 180, + 252, 173, 1, 243, 194, 248, 180, 252, 173, 1, 248, 88, 248, 180, 252, + 173, 1, 221, 150, 248, 180, 252, 173, 1, 240, 75, 248, 180, 252, 173, 1, + 219, 65, 248, 180, 252, 173, 1, 216, 11, 248, 180, 252, 173, 1, 208, 216, + 248, 180, 252, 173, 1, 211, 150, 248, 180, 252, 173, 1, 215, 124, 248, + 180, 252, 173, 1, 232, 213, 248, 180, 252, 173, 1, 246, 253, 248, 180, + 252, 173, 1, 248, 173, 248, 180, 252, 173, 1, 206, 56, 248, 180, 252, + 173, 1, 220, 244, 248, 180, 252, 173, 1, 231, 87, 248, 180, 252, 173, + 247, 224, 83, 26, 32, 3, 253, 114, 26, 32, 3, 253, 113, 26, 32, 3, 253, + 112, 26, 32, 3, 253, 111, 26, 32, 3, 253, 110, 26, 32, 3, 253, 109, 26, + 32, 3, 253, 108, 26, 32, 3, 253, 107, 26, 32, 3, 253, 106, 26, 32, 3, + 253, 105, 26, 32, 3, 253, 104, 26, 32, 3, 253, 103, 26, 32, 3, 253, 102, + 26, 32, 3, 253, 101, 26, 32, 3, 253, 100, 26, 32, 3, 253, 99, 26, 32, 3, + 253, 98, 26, 32, 3, 253, 97, 26, 32, 3, 253, 96, 26, 32, 3, 253, 95, 26, + 32, 3, 253, 94, 26, 32, 3, 253, 93, 26, 32, 3, 253, 92, 26, 32, 3, 253, + 91, 26, 32, 3, 253, 90, 26, 32, 3, 253, 89, 26, 32, 3, 253, 88, 26, 32, + 3, 254, 217, 26, 32, 3, 253, 87, 26, 32, 3, 253, 86, 26, 32, 3, 253, 85, + 26, 32, 3, 253, 84, 26, 32, 3, 253, 83, 26, 32, 3, 253, 82, 26, 32, 3, + 253, 81, 26, 32, 3, 253, 80, 26, 32, 3, 253, 79, 26, 32, 3, 253, 78, 26, + 32, 3, 253, 77, 26, 32, 3, 253, 76, 26, 32, 3, 253, 75, 26, 32, 3, 253, + 74, 26, 32, 3, 253, 73, 26, 32, 3, 253, 72, 26, 32, 3, 253, 71, 26, 32, + 3, 253, 70, 26, 32, 3, 253, 69, 26, 32, 3, 253, 68, 26, 32, 3, 253, 67, + 26, 32, 3, 253, 66, 26, 32, 3, 253, 65, 26, 32, 3, 253, 64, 26, 32, 3, + 253, 63, 26, 32, 3, 253, 62, 26, 32, 3, 253, 61, 26, 32, 3, 253, 60, 26, + 32, 3, 253, 59, 26, 32, 3, 253, 58, 26, 32, 3, 253, 57, 26, 32, 3, 253, + 56, 26, 32, 3, 253, 55, 26, 32, 3, 253, 54, 26, 32, 3, 253, 53, 26, 32, + 3, 253, 52, 26, 32, 3, 253, 51, 26, 32, 3, 253, 50, 26, 32, 3, 253, 49, + 26, 32, 3, 253, 48, 26, 32, 3, 253, 47, 26, 32, 3, 253, 46, 26, 32, 3, + 253, 45, 26, 32, 3, 254, 169, 26, 32, 3, 253, 44, 26, 32, 3, 253, 43, 26, + 32, 3, 254, 168, 26, 32, 3, 253, 42, 26, 32, 3, 253, 41, 26, 32, 3, 253, + 40, 26, 32, 3, 253, 39, 26, 32, 3, 254, 167, 26, 32, 3, 253, 38, 26, 32, + 3, 253, 37, 26, 32, 3, 253, 36, 26, 32, 3, 253, 35, 26, 32, 3, 253, 34, + 26, 32, 3, 254, 164, 26, 32, 3, 254, 163, 26, 32, 3, 254, 162, 26, 32, 3, + 254, 161, 26, 32, 3, 254, 160, 26, 32, 3, 254, 159, 26, 32, 3, 254, 158, + 26, 32, 3, 254, 157, 26, 32, 3, 254, 156, 26, 32, 3, 254, 155, 26, 32, 3, + 254, 154, 26, 32, 3, 254, 153, 26, 32, 3, 254, 152, 26, 32, 3, 254, 151, + 26, 32, 3, 254, 150, 26, 32, 3, 254, 149, 26, 32, 3, 254, 148, 26, 32, 3, + 254, 147, 26, 32, 3, 254, 146, 26, 32, 3, 254, 145, 26, 32, 3, 254, 144, + 26, 32, 3, 254, 143, 26, 32, 3, 254, 142, 26, 32, 3, 254, 141, 26, 32, 3, + 254, 140, 26, 32, 3, 254, 139, 26, 32, 3, 254, 138, 26, 32, 3, 254, 137, + 26, 32, 3, 254, 136, 26, 32, 3, 254, 135, 26, 32, 3, 254, 134, 26, 32, 3, + 254, 133, 26, 32, 3, 254, 132, 26, 32, 3, 254, 131, 26, 32, 3, 254, 130, + 26, 32, 3, 254, 129, 26, 32, 3, 254, 128, 26, 32, 3, 254, 127, 26, 32, 3, + 254, 126, 26, 32, 3, 254, 125, 26, 32, 3, 254, 124, 26, 32, 3, 254, 123, + 26, 32, 3, 254, 122, 26, 32, 3, 254, 121, 26, 32, 3, 254, 120, 26, 32, 3, + 254, 119, 26, 32, 3, 254, 118, 26, 32, 3, 254, 117, 26, 32, 3, 254, 116, + 26, 32, 3, 254, 115, 26, 32, 3, 254, 114, 26, 32, 3, 254, 113, 26, 32, 3, + 254, 112, 26, 32, 3, 254, 111, 26, 32, 3, 254, 110, 26, 32, 3, 254, 109, + 26, 32, 3, 254, 108, 26, 32, 3, 254, 107, 26, 32, 3, 254, 106, 26, 32, 3, + 254, 105, 26, 32, 3, 254, 104, 26, 32, 3, 254, 103, 26, 32, 3, 254, 102, + 26, 32, 3, 254, 101, 26, 32, 3, 254, 100, 26, 32, 3, 254, 99, 26, 32, 3, + 254, 98, 26, 32, 3, 254, 97, 26, 32, 3, 254, 96, 26, 32, 3, 254, 95, 26, + 32, 3, 254, 94, 26, 32, 3, 254, 93, 26, 32, 3, 254, 92, 26, 32, 3, 254, + 91, 26, 32, 3, 254, 90, 26, 32, 3, 254, 89, 26, 32, 3, 254, 88, 26, 32, + 3, 254, 87, 26, 32, 3, 254, 86, 26, 32, 3, 254, 85, 26, 32, 3, 254, 84, + 26, 32, 3, 254, 83, 26, 32, 3, 254, 82, 26, 32, 3, 254, 81, 26, 32, 3, + 254, 80, 26, 32, 3, 254, 79, 26, 32, 3, 254, 78, 26, 32, 3, 254, 77, 26, + 32, 3, 254, 76, 26, 32, 3, 254, 75, 26, 32, 3, 254, 74, 26, 32, 3, 254, + 73, 26, 32, 3, 254, 72, 26, 32, 3, 254, 71, 26, 32, 3, 254, 70, 26, 32, + 3, 254, 69, 26, 32, 3, 254, 68, 26, 32, 3, 254, 67, 26, 32, 3, 254, 66, + 26, 32, 3, 254, 65, 26, 32, 3, 254, 64, 26, 32, 3, 254, 63, 26, 32, 3, + 254, 62, 26, 32, 3, 254, 61, 26, 32, 3, 254, 60, 26, 32, 3, 254, 59, 26, + 32, 3, 254, 58, 26, 32, 3, 254, 57, 26, 32, 3, 254, 56, 26, 32, 3, 254, + 55, 26, 32, 3, 254, 54, 26, 32, 3, 254, 53, 26, 32, 3, 254, 52, 26, 32, + 3, 254, 51, 26, 32, 3, 254, 50, 26, 32, 3, 254, 49, 26, 32, 3, 254, 48, + 26, 32, 3, 254, 47, 26, 32, 3, 254, 46, 26, 32, 3, 254, 45, 26, 32, 3, + 254, 44, 26, 32, 3, 254, 43, 26, 32, 3, 254, 42, 26, 32, 3, 254, 41, 26, + 32, 3, 254, 40, 26, 32, 3, 254, 39, 26, 32, 3, 254, 38, 26, 32, 3, 254, + 37, 26, 32, 3, 254, 36, 26, 32, 3, 254, 35, 26, 32, 3, 254, 34, 26, 32, + 3, 254, 33, 26, 32, 3, 254, 32, 26, 32, 3, 254, 31, 26, 32, 3, 254, 30, + 26, 32, 3, 254, 29, 26, 32, 3, 254, 28, 26, 32, 3, 254, 27, 26, 32, 3, + 254, 26, 26, 32, 3, 254, 25, 26, 32, 3, 254, 24, 26, 32, 3, 254, 23, 26, + 32, 3, 254, 22, 26, 32, 3, 254, 21, 26, 32, 3, 254, 20, 26, 32, 3, 254, + 19, 26, 32, 3, 254, 18, 26, 32, 3, 254, 17, 26, 32, 3, 254, 16, 26, 32, + 3, 254, 15, 26, 32, 3, 254, 14, 26, 32, 3, 254, 13, 26, 32, 3, 254, 12, + 26, 32, 3, 254, 11, 26, 32, 3, 254, 10, 26, 32, 3, 254, 9, 26, 32, 3, + 254, 8, 26, 32, 3, 254, 7, 26, 32, 3, 254, 6, 26, 32, 3, 254, 5, 26, 32, + 3, 254, 4, 26, 32, 3, 254, 3, 26, 32, 3, 254, 2, 26, 32, 3, 254, 1, 26, + 32, 3, 254, 0, 26, 32, 3, 253, 255, 26, 32, 3, 253, 254, 26, 32, 3, 253, + 253, 26, 32, 3, 253, 252, 26, 32, 3, 253, 251, 26, 32, 3, 253, 250, 26, + 32, 3, 253, 249, 26, 32, 3, 253, 248, 26, 32, 3, 253, 247, 26, 32, 3, + 253, 246, 26, 32, 3, 253, 245, 26, 32, 3, 253, 244, 26, 32, 3, 253, 243, + 26, 32, 3, 253, 242, 26, 32, 3, 253, 241, 26, 32, 3, 253, 240, 26, 32, 3, + 253, 239, 26, 32, 3, 253, 238, 26, 32, 3, 253, 237, 26, 32, 3, 253, 236, + 26, 32, 3, 253, 235, 26, 32, 3, 253, 234, 26, 32, 3, 253, 233, 26, 32, 3, + 253, 232, 26, 32, 3, 253, 231, 26, 32, 3, 253, 230, 26, 32, 3, 253, 229, + 26, 32, 3, 253, 228, 26, 32, 3, 253, 227, 26, 32, 3, 253, 226, 26, 32, 3, + 253, 225, 26, 32, 3, 253, 224, 26, 32, 3, 253, 223, 26, 32, 3, 253, 222, + 26, 32, 3, 253, 221, 26, 32, 3, 253, 220, 26, 32, 3, 253, 219, 26, 32, 3, + 253, 218, 26, 32, 3, 253, 217, 26, 32, 3, 253, 216, 26, 32, 3, 253, 215, + 26, 32, 3, 253, 214, 26, 32, 3, 253, 213, 26, 32, 3, 253, 212, 26, 32, 3, + 253, 211, 26, 32, 3, 253, 210, 26, 32, 3, 253, 209, 26, 32, 3, 253, 208, + 26, 32, 3, 253, 207, 26, 32, 3, 253, 206, 26, 32, 3, 253, 205, 26, 32, 3, + 253, 204, 26, 32, 3, 253, 203, 26, 32, 3, 253, 202, 26, 32, 3, 253, 201, + 26, 32, 3, 253, 200, 26, 32, 3, 253, 199, 26, 32, 3, 253, 198, 26, 32, 3, + 253, 197, 26, 32, 3, 253, 196, 26, 32, 3, 253, 195, 26, 32, 3, 253, 194, + 62, 26, 32, 3, 253, 193, 251, 150, 26, 32, 3, 253, 192, 246, 240, 26, 32, + 3, 253, 191, 75, 26, 32, 3, 253, 190, 242, 139, 26, 32, 3, 253, 189, 239, + 155, 26, 32, 3, 253, 188, 232, 203, 26, 32, 3, 253, 187, 232, 76, 26, 32, + 3, 253, 186, 149, 26, 32, 3, 253, 185, 230, 146, 26, 32, 3, 253, 184, + 230, 145, 26, 32, 3, 253, 183, 230, 144, 26, 32, 3, 253, 182, 230, 143, + 26, 32, 3, 253, 181, 207, 129, 26, 32, 3, 253, 180, 206, 195, 26, 32, 3, + 253, 179, 206, 123, 26, 32, 3, 253, 178, 222, 170, 26, 32, 3, 253, 177, + 253, 30, 26, 32, 3, 253, 176, 250, 98, 26, 32, 3, 253, 175, 246, 56, 26, + 32, 3, 253, 174, 242, 146, 26, 32, 3, 253, 173, 232, 182, 26, 32, 3, 253, + 172, 26, 32, 3, 253, 171, 26, 32, 3, 253, 170, 26, 32, 3, 253, 169, 26, + 32, 3, 253, 168, 26, 32, 3, 253, 167, 26, 32, 3, 253, 166, 26, 32, 3, + 253, 165, 246, 247, 4, 62, 246, 247, 4, 75, 246, 247, 4, 74, 246, 247, 4, + 76, 246, 247, 4, 71, 246, 247, 4, 232, 200, 246, 247, 4, 232, 122, 246, + 247, 4, 172, 246, 247, 4, 231, 224, 246, 247, 4, 231, 123, 246, 247, 4, + 231, 53, 246, 247, 4, 230, 236, 246, 247, 4, 230, 141, 246, 247, 4, 230, + 58, 246, 247, 4, 229, 235, 246, 247, 4, 229, 144, 246, 247, 4, 229, 81, + 246, 247, 4, 185, 246, 247, 4, 227, 119, 246, 247, 4, 226, 254, 246, 247, + 4, 226, 181, 246, 247, 4, 226, 114, 246, 247, 4, 199, 246, 247, 4, 225, + 110, 246, 247, 4, 224, 230, 246, 247, 4, 224, 67, 246, 247, 4, 223, 217, + 246, 247, 4, 179, 246, 247, 4, 221, 174, 246, 247, 4, 221, 53, 246, 247, + 4, 220, 211, 246, 247, 4, 220, 82, 246, 247, 4, 219, 113, 246, 247, 4, + 219, 51, 246, 247, 4, 218, 208, 246, 247, 4, 218, 124, 246, 247, 4, 218, + 50, 246, 247, 4, 217, 199, 246, 247, 4, 217, 86, 246, 247, 4, 215, 80, + 246, 247, 4, 214, 193, 246, 247, 4, 213, 203, 246, 247, 4, 212, 219, 246, + 247, 4, 212, 131, 246, 247, 4, 211, 211, 246, 247, 4, 124, 246, 247, 4, + 210, 170, 246, 247, 4, 207, 96, 246, 247, 4, 207, 51, 246, 247, 4, 207, + 20, 246, 247, 4, 206, 250, 246, 247, 4, 206, 181, 246, 247, 4, 206, 175, + 246, 247, 4, 205, 116, 246, 247, 4, 205, 19, 233, 70, 252, 23, 1, 252, + 170, 233, 70, 252, 23, 1, 250, 7, 233, 70, 252, 23, 1, 240, 47, 233, 70, + 252, 23, 1, 246, 110, 233, 70, 252, 23, 1, 239, 71, 233, 70, 252, 23, 1, + 207, 59, 233, 70, 252, 23, 1, 205, 96, 233, 70, 252, 23, 1, 239, 27, 233, + 70, 252, 23, 1, 212, 76, 233, 70, 252, 23, 1, 205, 235, 233, 70, 252, 23, + 1, 232, 17, 233, 70, 252, 23, 1, 230, 97, 233, 70, 252, 23, 1, 227, 90, + 233, 70, 252, 23, 1, 223, 173, 233, 70, 252, 23, 1, 217, 157, 233, 70, + 252, 23, 1, 251, 154, 233, 70, 252, 23, 1, 221, 174, 233, 70, 252, 23, 1, + 217, 189, 233, 70, 252, 23, 1, 219, 218, 233, 70, 252, 23, 1, 218, 242, + 233, 70, 252, 23, 1, 215, 171, 233, 70, 252, 23, 1, 212, 145, 233, 70, + 252, 23, 217, 77, 53, 233, 70, 252, 23, 43, 102, 233, 70, 252, 23, 43, + 105, 233, 70, 252, 23, 43, 142, 233, 70, 252, 23, 43, 212, 98, 233, 70, + 252, 23, 43, 210, 123, 233, 70, 252, 23, 43, 119, 238, 29, 233, 70, 252, + 23, 43, 119, 211, 242, 233, 70, 252, 23, 43, 212, 99, 211, 242, 222, 18, + 1, 252, 170, 222, 18, 1, 250, 7, 222, 18, 1, 240, 47, 222, 18, 1, 246, + 110, 222, 18, 1, 239, 71, 222, 18, 1, 207, 59, 222, 18, 1, 205, 96, 222, + 18, 1, 239, 27, 222, 18, 1, 212, 76, 222, 18, 1, 205, 235, 222, 18, 1, + 232, 17, 222, 18, 1, 230, 97, 222, 18, 1, 227, 90, 222, 18, 1, 42, 223, + 173, 222, 18, 1, 223, 173, 222, 18, 1, 217, 157, 222, 18, 1, 251, 154, + 222, 18, 1, 221, 174, 222, 18, 1, 217, 189, 222, 18, 1, 219, 218, 222, + 18, 1, 218, 242, 222, 18, 1, 215, 171, 222, 18, 1, 212, 145, 222, 18, + 230, 41, 241, 183, 222, 18, 218, 162, 241, 183, 222, 18, 43, 102, 222, + 18, 43, 105, 222, 18, 43, 142, 222, 18, 43, 139, 222, 18, 43, 168, 222, + 18, 43, 212, 98, 222, 18, 43, 210, 123, 225, 228, 1, 42, 252, 170, 225, + 228, 1, 252, 170, 225, 228, 1, 42, 250, 7, 225, 228, 1, 250, 7, 225, 228, + 1, 240, 47, 225, 228, 1, 246, 110, 225, 228, 1, 42, 239, 71, 225, 228, 1, + 239, 71, 225, 228, 1, 207, 59, 225, 228, 1, 205, 96, 225, 228, 1, 239, + 27, 225, 228, 1, 212, 76, 225, 228, 1, 42, 205, 235, 225, 228, 1, 205, + 235, 225, 228, 1, 42, 232, 17, 225, 228, 1, 232, 17, 225, 228, 1, 42, + 230, 97, 225, 228, 1, 230, 97, 225, 228, 1, 42, 227, 90, 225, 228, 1, + 227, 90, 225, 228, 1, 42, 223, 173, 225, 228, 1, 223, 173, 225, 228, 1, + 217, 157, 225, 228, 1, 251, 154, 225, 228, 1, 221, 174, 225, 228, 1, 217, + 189, 225, 228, 1, 219, 218, 225, 228, 1, 218, 242, 225, 228, 1, 42, 215, + 171, 225, 228, 1, 215, 171, 225, 228, 1, 212, 145, 225, 228, 43, 102, + 225, 228, 43, 105, 225, 228, 43, 142, 225, 228, 43, 139, 225, 228, 247, + 46, 43, 139, 225, 228, 43, 168, 225, 228, 43, 212, 98, 225, 228, 43, 210, + 123, 225, 228, 43, 119, 238, 29, 221, 64, 1, 252, 167, 221, 64, 1, 250, + 10, 221, 64, 1, 240, 217, 221, 64, 1, 245, 229, 221, 64, 1, 239, 71, 221, + 64, 1, 207, 66, 221, 64, 1, 205, 110, 221, 64, 1, 239, 29, 221, 64, 1, + 212, 80, 221, 64, 1, 205, 236, 221, 64, 1, 232, 45, 221, 64, 1, 230, 103, + 221, 64, 1, 227, 90, 221, 64, 1, 223, 173, 221, 64, 1, 216, 46, 221, 64, + 1, 252, 200, 221, 64, 1, 221, 174, 221, 64, 1, 217, 190, 221, 64, 1, 219, + 223, 221, 64, 1, 218, 99, 221, 64, 1, 215, 171, 221, 64, 1, 212, 151, + 221, 64, 43, 102, 221, 64, 43, 212, 98, 221, 64, 43, 210, 123, 221, 64, + 43, 119, 238, 29, 221, 64, 43, 105, 221, 64, 43, 142, 221, 64, 206, 232, + 216, 39, 229, 39, 1, 62, 229, 39, 1, 251, 150, 229, 39, 1, 241, 55, 229, + 39, 1, 246, 240, 229, 39, 1, 75, 229, 39, 1, 209, 148, 229, 39, 1, 74, + 229, 39, 1, 206, 123, 229, 39, 1, 232, 76, 229, 39, 1, 149, 229, 39, 1, + 229, 28, 229, 39, 1, 226, 33, 229, 39, 1, 76, 229, 39, 1, 137, 229, 39, + 1, 214, 99, 229, 39, 1, 213, 10, 229, 39, 1, 71, 229, 39, 1, 242, 139, + 229, 39, 1, 220, 27, 229, 39, 1, 182, 229, 39, 1, 210, 211, 229, 39, 1, + 252, 122, 229, 39, 1, 243, 41, 229, 39, 1, 229, 42, 229, 39, 1, 224, 104, + 229, 39, 1, 249, 34, 229, 39, 211, 48, 83, 227, 72, 239, 5, 1, 62, 227, + 72, 239, 5, 1, 75, 227, 72, 239, 5, 1, 74, 227, 72, 239, 5, 1, 76, 227, + 72, 239, 5, 1, 190, 227, 72, 239, 5, 1, 207, 96, 227, 72, 239, 5, 1, 250, + 183, 227, 72, 239, 5, 1, 250, 182, 227, 72, 239, 5, 1, 179, 227, 72, 239, + 5, 1, 185, 227, 72, 239, 5, 1, 199, 227, 72, 239, 5, 1, 225, 236, 227, + 72, 239, 5, 1, 225, 110, 227, 72, 239, 5, 1, 225, 109, 227, 72, 239, 5, + 1, 219, 113, 227, 72, 239, 5, 1, 219, 112, 227, 72, 239, 5, 1, 230, 141, + 227, 72, 239, 5, 1, 231, 167, 227, 72, 239, 5, 1, 239, 20, 227, 72, 239, + 5, 1, 217, 199, 227, 72, 239, 5, 1, 217, 198, 227, 72, 239, 5, 1, 217, + 86, 227, 72, 239, 5, 1, 172, 227, 72, 239, 5, 1, 220, 19, 227, 72, 239, + 5, 1, 212, 219, 227, 72, 239, 5, 1, 212, 218, 227, 72, 239, 5, 1, 212, + 131, 227, 72, 239, 5, 1, 212, 130, 227, 72, 239, 5, 1, 124, 227, 72, 239, + 5, 1, 246, 145, 227, 72, 239, 5, 16, 208, 208, 227, 72, 239, 5, 16, 208, + 207, 227, 72, 247, 21, 1, 62, 227, 72, 247, 21, 1, 75, 227, 72, 247, 21, + 1, 74, 227, 72, 247, 21, 1, 76, 227, 72, 247, 21, 1, 190, 227, 72, 247, + 21, 1, 207, 96, 227, 72, 247, 21, 1, 250, 183, 227, 72, 247, 21, 1, 179, + 227, 72, 247, 21, 1, 185, 227, 72, 247, 21, 1, 199, 227, 72, 247, 21, 1, + 225, 110, 227, 72, 247, 21, 1, 219, 113, 227, 72, 247, 21, 1, 230, 141, + 227, 72, 247, 21, 1, 231, 167, 227, 72, 247, 21, 1, 239, 20, 227, 72, + 247, 21, 1, 217, 199, 227, 72, 247, 21, 1, 252, 19, 217, 199, 227, 72, + 247, 21, 1, 217, 86, 227, 72, 247, 21, 1, 172, 227, 72, 247, 21, 1, 220, + 19, 227, 72, 247, 21, 1, 212, 219, 227, 72, 247, 21, 1, 212, 131, 227, + 72, 247, 21, 1, 124, 227, 72, 247, 21, 1, 246, 145, 227, 72, 247, 21, + 229, 133, 218, 130, 227, 72, 247, 21, 229, 133, 233, 75, 231, 154, 1, 62, + 231, 154, 22, 3, 74, 231, 154, 22, 3, 71, 231, 154, 22, 3, 115, 137, 231, + 154, 22, 3, 75, 231, 154, 22, 3, 76, 231, 154, 22, 230, 20, 83, 231, 154, + 3, 50, 218, 149, 55, 231, 154, 3, 252, 73, 231, 154, 3, 208, 183, 231, + 154, 1, 172, 231, 154, 1, 231, 167, 231, 154, 1, 240, 244, 231, 154, 1, + 240, 99, 231, 154, 1, 249, 1, 231, 154, 1, 248, 110, 231, 154, 1, 232, + 200, 231, 154, 1, 223, 144, 231, 154, 1, 210, 208, 231, 154, 1, 210, 196, + 231, 154, 1, 246, 54, 231, 154, 1, 246, 38, 231, 154, 1, 224, 103, 231, + 154, 1, 212, 219, 231, 154, 1, 212, 56, 231, 154, 1, 246, 145, 231, 154, + 1, 245, 192, 231, 154, 1, 199, 231, 154, 1, 179, 231, 154, 1, 221, 93, + 231, 154, 1, 250, 183, 231, 154, 1, 250, 0, 231, 154, 1, 185, 231, 154, + 1, 190, 231, 154, 1, 219, 113, 231, 154, 1, 230, 141, 231, 154, 1, 209, + 70, 231, 154, 1, 216, 2, 231, 154, 1, 214, 96, 231, 154, 1, 217, 199, + 231, 154, 1, 205, 116, 231, 154, 1, 155, 231, 154, 1, 231, 72, 231, 154, + 1, 210, 176, 231, 154, 3, 250, 129, 52, 231, 154, 3, 248, 179, 231, 154, + 3, 67, 55, 231, 154, 208, 188, 231, 154, 18, 102, 231, 154, 18, 105, 231, + 154, 18, 142, 231, 154, 18, 139, 231, 154, 43, 212, 98, 231, 154, 43, + 210, 123, 231, 154, 43, 119, 238, 29, 231, 154, 43, 119, 211, 242, 231, + 154, 220, 72, 245, 23, 231, 154, 220, 72, 5, 247, 233, 231, 154, 220, 72, + 247, 233, 231, 154, 220, 72, 247, 66, 134, 231, 154, 220, 72, 227, 215, + 231, 154, 220, 72, 229, 102, 231, 154, 220, 72, 246, 100, 231, 154, 220, + 72, 50, 246, 100, 231, 154, 220, 72, 229, 199, 44, 188, 252, 34, 1, 239, + 71, 44, 188, 252, 34, 1, 230, 97, 44, 188, 252, 34, 1, 239, 27, 44, 188, + 252, 34, 1, 227, 90, 44, 188, 252, 34, 1, 219, 218, 44, 188, 252, 34, 1, + 207, 59, 44, 188, 252, 34, 1, 215, 171, 44, 188, 252, 34, 1, 218, 242, + 44, 188, 252, 34, 1, 250, 7, 44, 188, 252, 34, 1, 212, 145, 44, 188, 252, + 34, 1, 217, 133, 44, 188, 252, 34, 1, 232, 17, 44, 188, 252, 34, 1, 223, + 173, 44, 188, 252, 34, 1, 231, 149, 44, 188, 252, 34, 1, 217, 189, 44, + 188, 252, 34, 1, 217, 157, 44, 188, 252, 34, 1, 242, 28, 44, 188, 252, + 34, 1, 252, 172, 44, 188, 252, 34, 1, 251, 153, 44, 188, 252, 34, 1, 245, + 189, 44, 188, 252, 34, 1, 240, 47, 44, 188, 252, 34, 1, 246, 110, 44, + 188, 252, 34, 1, 240, 87, 44, 188, 252, 34, 1, 212, 76, 44, 188, 252, 34, + 1, 205, 95, 44, 188, 252, 34, 1, 245, 186, 44, 188, 252, 34, 1, 205, 235, + 44, 188, 252, 34, 1, 212, 43, 44, 188, 252, 34, 1, 212, 22, 44, 188, 252, + 34, 43, 102, 44, 188, 252, 34, 43, 241, 243, 44, 188, 252, 34, 133, 233, + 49, 44, 143, 252, 34, 1, 239, 50, 44, 143, 252, 34, 1, 230, 106, 44, 143, + 252, 34, 1, 239, 132, 44, 143, 252, 34, 1, 227, 104, 44, 143, 252, 34, 1, + 220, 12, 44, 143, 252, 34, 1, 207, 59, 44, 143, 252, 34, 1, 242, 223, 44, + 143, 252, 34, 1, 219, 16, 44, 143, 252, 34, 1, 250, 38, 44, 143, 252, 34, + 1, 212, 115, 44, 143, 252, 34, 1, 242, 224, 44, 143, 252, 34, 1, 232, 45, + 44, 143, 252, 34, 1, 224, 54, 44, 143, 252, 34, 1, 231, 163, 44, 143, + 252, 34, 1, 217, 191, 44, 143, 252, 34, 1, 242, 222, 44, 143, 252, 34, 1, + 242, 15, 44, 143, 252, 34, 1, 252, 172, 44, 143, 252, 34, 1, 252, 200, + 44, 143, 252, 34, 1, 246, 140, 44, 143, 252, 34, 1, 240, 161, 44, 143, + 252, 34, 1, 246, 117, 44, 143, 252, 34, 1, 240, 94, 44, 143, 252, 34, 1, + 212, 194, 44, 143, 252, 34, 1, 205, 108, 44, 143, 252, 34, 1, 212, 49, + 44, 143, 252, 34, 1, 206, 47, 44, 143, 252, 34, 1, 212, 37, 44, 143, 252, + 34, 1, 205, 111, 44, 143, 252, 34, 43, 102, 44, 143, 252, 34, 43, 212, + 98, 44, 143, 252, 34, 43, 210, 123, 227, 214, 1, 252, 170, 227, 214, 1, + 250, 7, 227, 214, 1, 249, 250, 227, 214, 1, 240, 47, 227, 214, 1, 240, + 72, 227, 214, 1, 246, 110, 227, 214, 1, 239, 71, 227, 214, 1, 207, 59, + 227, 214, 3, 210, 8, 227, 214, 1, 205, 96, 227, 214, 1, 205, 74, 227, + 214, 1, 232, 184, 227, 214, 1, 232, 166, 227, 214, 1, 239, 27, 227, 214, + 1, 212, 76, 227, 214, 1, 205, 235, 227, 214, 1, 232, 17, 227, 214, 1, + 206, 178, 227, 214, 1, 231, 156, 227, 214, 1, 230, 97, 227, 214, 1, 245, + 185, 227, 214, 1, 212, 48, 227, 214, 1, 227, 90, 227, 214, 1, 223, 173, + 227, 214, 1, 217, 157, 227, 214, 1, 251, 154, 227, 214, 1, 253, 117, 227, + 214, 1, 221, 174, 227, 214, 1, 242, 28, 227, 214, 1, 217, 189, 227, 214, + 1, 219, 218, 227, 214, 1, 206, 156, 227, 214, 1, 219, 244, 227, 214, 1, + 218, 242, 227, 214, 1, 215, 171, 227, 214, 1, 214, 65, 227, 214, 1, 212, + 145, 227, 214, 253, 29, 141, 52, 227, 214, 253, 29, 141, 55, 227, 214, + 43, 102, 227, 214, 43, 168, 227, 214, 43, 212, 98, 227, 214, 43, 210, + 123, 227, 214, 43, 119, 238, 29, 227, 214, 220, 72, 214, 26, 227, 214, + 220, 72, 241, 183, 227, 214, 220, 72, 50, 67, 206, 255, 245, 23, 227, + 214, 220, 72, 67, 206, 255, 245, 23, 227, 214, 220, 72, 245, 23, 227, + 214, 220, 72, 118, 245, 21, 227, 214, 220, 72, 229, 206, 241, 232, 251, + 164, 1, 62, 251, 164, 1, 253, 164, 251, 164, 1, 252, 71, 251, 164, 1, + 253, 123, 251, 164, 1, 252, 122, 251, 164, 1, 253, 124, 251, 164, 1, 252, + 248, 251, 164, 1, 252, 244, 251, 164, 1, 75, 251, 164, 1, 243, 104, 251, + 164, 1, 76, 251, 164, 1, 222, 152, 251, 164, 1, 74, 251, 164, 1, 233, + 102, 251, 164, 1, 71, 251, 164, 1, 209, 162, 251, 164, 1, 231, 224, 251, + 164, 1, 206, 175, 251, 164, 1, 206, 137, 251, 164, 1, 206, 147, 251, 164, + 1, 240, 170, 251, 164, 1, 240, 130, 251, 164, 1, 240, 85, 251, 164, 1, + 248, 148, 251, 164, 1, 232, 182, 251, 164, 1, 212, 131, 251, 164, 1, 212, + 41, 251, 164, 1, 246, 9, 251, 164, 1, 245, 183, 251, 164, 1, 210, 203, + 251, 164, 1, 221, 174, 251, 164, 1, 242, 28, 251, 164, 1, 250, 61, 251, + 164, 1, 249, 252, 251, 164, 1, 225, 64, 251, 164, 1, 224, 236, 251, 164, + 1, 224, 237, 251, 164, 1, 225, 110, 251, 164, 1, 223, 134, 251, 164, 1, + 224, 98, 251, 164, 1, 227, 119, 251, 164, 1, 238, 199, 251, 164, 1, 205, + 166, 251, 164, 1, 206, 52, 251, 164, 1, 209, 39, 251, 164, 1, 219, 51, + 251, 164, 1, 230, 58, 251, 164, 1, 217, 86, 251, 164, 1, 205, 93, 251, + 164, 1, 215, 214, 251, 164, 1, 205, 72, 251, 164, 1, 215, 87, 251, 164, + 1, 214, 66, 251, 164, 1, 239, 71, 251, 164, 253, 29, 83, 211, 169, 118, + 177, 131, 119, 67, 220, 71, 5, 118, 177, 131, 119, 67, 220, 71, 230, 86, + 118, 177, 131, 119, 67, 220, 71, 230, 86, 119, 67, 131, 118, 177, 220, + 71, 230, 86, 118, 218, 146, 131, 119, 218, 149, 220, 71, 230, 86, 119, + 218, 149, 131, 118, 218, 146, 220, 71, 233, 29, 221, 210, 1, 252, 170, + 233, 29, 221, 210, 1, 250, 7, 233, 29, 221, 210, 1, 240, 47, 233, 29, + 221, 210, 1, 246, 110, 233, 29, 221, 210, 1, 239, 71, 233, 29, 221, 210, + 1, 207, 59, 233, 29, 221, 210, 1, 205, 96, 233, 29, 221, 210, 1, 239, 27, + 233, 29, 221, 210, 1, 212, 76, 233, 29, 221, 210, 1, 205, 235, 233, 29, + 221, 210, 1, 232, 17, 233, 29, 221, 210, 1, 230, 97, 233, 29, 221, 210, + 1, 227, 90, 233, 29, 221, 210, 1, 223, 173, 233, 29, 221, 210, 1, 217, + 157, 233, 29, 221, 210, 1, 251, 154, 233, 29, 221, 210, 1, 221, 174, 233, + 29, 221, 210, 1, 217, 189, 233, 29, 221, 210, 1, 219, 218, 233, 29, 221, + 210, 1, 218, 242, 233, 29, 221, 210, 1, 215, 171, 233, 29, 221, 210, 1, + 212, 145, 233, 29, 221, 210, 43, 102, 233, 29, 221, 210, 43, 105, 233, + 29, 221, 210, 43, 142, 233, 29, 221, 210, 43, 139, 233, 29, 221, 210, 43, + 212, 98, 233, 29, 221, 210, 43, 210, 123, 233, 29, 221, 210, 43, 119, + 238, 29, 233, 29, 221, 210, 43, 119, 211, 242, 233, 29, 222, 33, 1, 252, + 170, 233, 29, 222, 33, 1, 250, 7, 233, 29, 222, 33, 1, 240, 47, 233, 29, + 222, 33, 1, 246, 110, 233, 29, 222, 33, 1, 239, 71, 233, 29, 222, 33, 1, + 207, 58, 233, 29, 222, 33, 1, 205, 96, 233, 29, 222, 33, 1, 239, 27, 233, + 29, 222, 33, 1, 212, 76, 233, 29, 222, 33, 1, 205, 235, 233, 29, 222, 33, + 1, 232, 17, 233, 29, 222, 33, 1, 230, 97, 233, 29, 222, 33, 1, 227, 89, + 233, 29, 222, 33, 1, 223, 173, 233, 29, 222, 33, 1, 217, 157, 233, 29, + 222, 33, 1, 221, 174, 233, 29, 222, 33, 1, 217, 189, 233, 29, 222, 33, 1, + 215, 171, 233, 29, 222, 33, 1, 212, 145, 233, 29, 222, 33, 43, 102, 233, + 29, 222, 33, 43, 105, 233, 29, 222, 33, 43, 142, 233, 29, 222, 33, 43, + 139, 233, 29, 222, 33, 43, 212, 98, 233, 29, 222, 33, 43, 210, 123, 233, + 29, 222, 33, 43, 119, 238, 29, 233, 29, 222, 33, 43, 119, 211, 242, 220, + 94, 222, 33, 1, 252, 170, 220, 94, 222, 33, 1, 250, 7, 220, 94, 222, 33, + 1, 240, 47, 220, 94, 222, 33, 1, 246, 110, 220, 94, 222, 33, 1, 239, 71, + 220, 94, 222, 33, 1, 207, 58, 220, 94, 222, 33, 1, 205, 96, 220, 94, 222, + 33, 1, 239, 27, 220, 94, 222, 33, 1, 205, 235, 220, 94, 222, 33, 1, 232, + 17, 220, 94, 222, 33, 1, 230, 97, 220, 94, 222, 33, 1, 227, 89, 220, 94, + 222, 33, 1, 223, 173, 220, 94, 222, 33, 1, 217, 157, 220, 94, 222, 33, 1, + 221, 174, 220, 94, 222, 33, 1, 217, 189, 220, 94, 222, 33, 1, 215, 171, + 220, 94, 222, 33, 1, 212, 145, 220, 94, 222, 33, 217, 77, 83, 220, 94, + 222, 33, 201, 217, 77, 83, 220, 94, 222, 33, 241, 125, 177, 2, 247, 59, + 220, 94, 222, 33, 241, 125, 177, 2, 245, 23, 220, 94, 222, 33, 43, 102, + 220, 94, 222, 33, 43, 105, 220, 94, 222, 33, 43, 142, 220, 94, 222, 33, + 43, 139, 220, 94, 222, 33, 43, 212, 98, 220, 94, 222, 33, 43, 210, 123, + 220, 94, 222, 33, 43, 119, 238, 29, 44, 210, 147, 1, 222, 113, 62, 44, + 210, 147, 1, 206, 40, 62, 44, 210, 147, 1, 206, 40, 252, 248, 44, 210, + 147, 1, 222, 113, 74, 44, 210, 147, 1, 206, 40, 74, 44, 210, 147, 1, 206, + 40, 75, 44, 210, 147, 1, 222, 113, 76, 44, 210, 147, 1, 222, 113, 222, + 206, 44, 210, 147, 1, 206, 40, 222, 206, 44, 210, 147, 1, 222, 113, 253, + 115, 44, 210, 147, 1, 206, 40, 253, 115, 44, 210, 147, 1, 222, 113, 252, + 247, 44, 210, 147, 1, 206, 40, 252, 247, 44, 210, 147, 1, 222, 113, 252, + 220, 44, 210, 147, 1, 206, 40, 252, 220, 44, 210, 147, 1, 222, 113, 252, + 242, 44, 210, 147, 1, 206, 40, 252, 242, 44, 210, 147, 1, 222, 113, 253, + 5, 44, 210, 147, 1, 206, 40, 253, 5, 44, 210, 147, 1, 222, 113, 252, 246, + 44, 210, 147, 1, 222, 113, 242, 145, 44, 210, 147, 1, 206, 40, 242, 145, + 44, 210, 147, 1, 222, 113, 251, 159, 44, 210, 147, 1, 206, 40, 251, 159, + 44, 210, 147, 1, 222, 113, 252, 229, 44, 210, 147, 1, 206, 40, 252, 229, + 44, 210, 147, 1, 222, 113, 252, 240, 44, 210, 147, 1, 206, 40, 252, 240, + 44, 210, 147, 1, 222, 113, 222, 205, 44, 210, 147, 1, 206, 40, 222, 205, + 44, 210, 147, 1, 222, 113, 252, 181, 44, 210, 147, 1, 206, 40, 252, 181, + 44, 210, 147, 1, 222, 113, 252, 239, 44, 210, 147, 1, 222, 113, 243, 52, + 44, 210, 147, 1, 222, 113, 243, 50, 44, 210, 147, 1, 222, 113, 252, 122, + 44, 210, 147, 1, 222, 113, 252, 237, 44, 210, 147, 1, 206, 40, 252, 237, + 44, 210, 147, 1, 222, 113, 243, 20, 44, 210, 147, 1, 206, 40, 243, 20, + 44, 210, 147, 1, 222, 113, 243, 38, 44, 210, 147, 1, 206, 40, 243, 38, + 44, 210, 147, 1, 222, 113, 243, 7, 44, 210, 147, 1, 206, 40, 243, 7, 44, + 210, 147, 1, 206, 40, 252, 114, 44, 210, 147, 1, 222, 113, 243, 28, 44, + 210, 147, 1, 206, 40, 252, 236, 44, 210, 147, 1, 222, 113, 242, 253, 44, + 210, 147, 1, 222, 113, 222, 143, 44, 210, 147, 1, 222, 113, 237, 183, 44, + 210, 147, 1, 222, 113, 243, 110, 44, 210, 147, 1, 206, 40, 243, 110, 44, + 210, 147, 1, 222, 113, 252, 41, 44, 210, 147, 1, 206, 40, 252, 41, 44, + 210, 147, 1, 222, 113, 232, 245, 44, 210, 147, 1, 206, 40, 232, 245, 44, + 210, 147, 1, 222, 113, 222, 124, 44, 210, 147, 1, 206, 40, 222, 124, 44, + 210, 147, 1, 222, 113, 252, 37, 44, 210, 147, 1, 206, 40, 252, 37, 44, + 210, 147, 1, 222, 113, 252, 235, 44, 210, 147, 1, 222, 113, 251, 231, 44, + 210, 147, 1, 222, 113, 252, 233, 44, 210, 147, 1, 222, 113, 251, 225, 44, + 210, 147, 1, 206, 40, 251, 225, 44, 210, 147, 1, 222, 113, 242, 215, 44, + 210, 147, 1, 206, 40, 242, 215, 44, 210, 147, 1, 222, 113, 251, 199, 44, + 210, 147, 1, 206, 40, 251, 199, 44, 210, 147, 1, 222, 113, 252, 230, 44, + 210, 147, 1, 206, 40, 252, 230, 44, 210, 147, 1, 222, 113, 222, 103, 44, + 210, 147, 1, 222, 113, 250, 113, 218, 36, 18, 102, 218, 36, 18, 105, 218, + 36, 18, 142, 218, 36, 18, 139, 218, 36, 18, 168, 218, 36, 18, 184, 218, + 36, 18, 195, 218, 36, 18, 193, 218, 36, 18, 200, 218, 36, 43, 212, 98, + 218, 36, 43, 210, 123, 218, 36, 43, 212, 3, 218, 36, 43, 241, 130, 218, + 36, 43, 241, 243, 218, 36, 43, 214, 252, 218, 36, 43, 216, 17, 218, 36, + 43, 243, 79, 218, 36, 43, 224, 190, 218, 36, 43, 119, 238, 29, 218, 36, + 43, 118, 238, 29, 218, 36, 43, 129, 238, 29, 218, 36, 43, 241, 125, 238, + 29, 218, 36, 43, 241, 204, 238, 29, 218, 36, 43, 215, 10, 238, 29, 218, + 36, 43, 216, 23, 238, 29, 218, 36, 43, 243, 88, 238, 29, 218, 36, 43, + 224, 195, 238, 29, 218, 36, 241, 116, 119, 239, 121, 218, 36, 241, 116, + 119, 219, 204, 218, 36, 241, 116, 119, 212, 10, 218, 36, 241, 116, 118, + 212, 7, 136, 3, 248, 217, 136, 3, 252, 73, 136, 3, 208, 183, 136, 3, 232, + 156, 136, 3, 209, 204, 136, 1, 62, 136, 1, 253, 164, 136, 1, 74, 136, 1, + 233, 102, 136, 1, 71, 136, 1, 209, 162, 136, 1, 115, 137, 136, 1, 115, + 218, 90, 136, 1, 115, 149, 136, 1, 115, 229, 173, 136, 1, 75, 136, 1, + 252, 205, 136, 1, 76, 136, 1, 251, 184, 136, 1, 172, 136, 1, 231, 167, + 136, 1, 240, 244, 136, 1, 240, 99, 136, 1, 225, 77, 136, 1, 249, 1, 136, + 1, 248, 110, 136, 1, 232, 200, 136, 1, 232, 170, 136, 1, 223, 144, 136, + 1, 210, 208, 136, 1, 210, 196, 136, 1, 246, 54, 136, 1, 246, 38, 136, 1, + 224, 103, 136, 1, 212, 219, 136, 1, 212, 56, 136, 1, 246, 145, 136, 1, + 245, 192, 136, 1, 199, 136, 1, 179, 136, 1, 221, 93, 136, 1, 250, 183, + 136, 1, 250, 0, 136, 1, 185, 136, 1, 190, 136, 1, 219, 113, 136, 1, 230, + 141, 136, 1, 209, 70, 136, 1, 216, 2, 136, 1, 214, 96, 136, 1, 217, 199, + 136, 1, 155, 136, 1, 229, 172, 136, 1, 44, 40, 229, 163, 136, 1, 44, 40, + 218, 89, 136, 1, 44, 40, 224, 85, 136, 22, 3, 253, 164, 136, 22, 3, 249, + 253, 253, 164, 136, 22, 3, 74, 136, 22, 3, 233, 102, 136, 22, 3, 71, 136, + 22, 3, 209, 162, 136, 22, 3, 115, 137, 136, 22, 3, 115, 218, 90, 136, 22, + 3, 115, 149, 136, 22, 3, 115, 229, 173, 136, 22, 3, 75, 136, 22, 3, 252, + 205, 136, 22, 3, 76, 136, 22, 3, 251, 184, 136, 208, 188, 136, 246, 100, + 136, 50, 246, 100, 136, 220, 72, 245, 23, 136, 220, 72, 50, 245, 23, 136, + 220, 72, 229, 205, 136, 220, 72, 247, 66, 134, 136, 220, 72, 229, 102, + 136, 43, 102, 136, 43, 105, 136, 43, 142, 136, 43, 139, 136, 43, 168, + 136, 43, 184, 136, 43, 195, 136, 43, 193, 136, 43, 200, 136, 43, 212, 98, + 136, 43, 210, 123, 136, 43, 212, 3, 136, 43, 241, 130, 136, 43, 241, 243, + 136, 43, 214, 252, 136, 43, 216, 17, 136, 43, 243, 79, 136, 43, 224, 190, + 136, 43, 119, 238, 29, 136, 43, 119, 211, 242, 136, 18, 205, 85, 136, 18, + 102, 136, 18, 105, 136, 18, 142, 136, 18, 139, 136, 18, 168, 136, 18, + 184, 136, 18, 195, 136, 18, 193, 136, 18, 200, 136, 43, 232, 117, 232, + 38, 3, 248, 217, 232, 38, 3, 252, 73, 232, 38, 3, 208, 183, 232, 38, 1, + 62, 232, 38, 1, 253, 164, 232, 38, 1, 74, 232, 38, 1, 233, 102, 232, 38, + 1, 71, 232, 38, 1, 209, 162, 232, 38, 1, 75, 232, 38, 1, 252, 205, 232, + 38, 1, 76, 232, 38, 1, 251, 184, 232, 38, 1, 172, 232, 38, 1, 231, 167, + 232, 38, 1, 240, 244, 232, 38, 1, 240, 99, 232, 38, 1, 225, 77, 232, 38, + 1, 249, 1, 232, 38, 1, 248, 110, 232, 38, 1, 232, 200, 232, 38, 1, 232, + 170, 232, 38, 1, 223, 144, 232, 38, 1, 210, 208, 232, 38, 1, 210, 196, + 232, 38, 1, 246, 54, 232, 38, 1, 246, 43, 232, 38, 1, 246, 38, 232, 38, + 1, 218, 212, 232, 38, 1, 224, 103, 232, 38, 1, 212, 219, 232, 38, 1, 212, + 56, 232, 38, 1, 246, 145, 232, 38, 1, 245, 192, 232, 38, 1, 199, 232, 38, + 1, 179, 232, 38, 1, 221, 93, 232, 38, 1, 250, 183, 232, 38, 1, 250, 0, + 232, 38, 1, 185, 232, 38, 1, 190, 232, 38, 1, 219, 113, 232, 38, 1, 230, + 141, 232, 38, 1, 209, 70, 232, 38, 1, 216, 2, 232, 38, 1, 214, 96, 232, + 38, 1, 217, 199, 232, 38, 1, 155, 232, 38, 22, 3, 253, 164, 232, 38, 22, + 3, 74, 232, 38, 22, 3, 233, 102, 232, 38, 22, 3, 71, 232, 38, 22, 3, 209, + 162, 232, 38, 22, 3, 75, 232, 38, 22, 3, 252, 205, 232, 38, 22, 3, 76, + 232, 38, 22, 3, 251, 184, 232, 38, 3, 208, 188, 232, 38, 3, 223, 184, + 232, 38, 253, 29, 53, 232, 38, 243, 10, 53, 232, 38, 43, 53, 232, 38, + 217, 77, 83, 232, 38, 50, 217, 77, 83, 232, 38, 246, 100, 232, 38, 50, + 246, 100, 214, 170, 214, 178, 1, 217, 182, 214, 170, 214, 178, 1, 212, + 194, 214, 170, 214, 178, 1, 250, 158, 214, 170, 214, 178, 1, 248, 246, + 214, 170, 214, 178, 1, 246, 126, 214, 170, 214, 178, 1, 240, 229, 214, + 170, 214, 178, 1, 227, 247, 214, 170, 214, 178, 1, 225, 74, 214, 170, + 214, 178, 1, 230, 117, 214, 170, 214, 178, 1, 225, 219, 214, 170, 214, + 178, 1, 209, 66, 214, 170, 214, 178, 1, 222, 34, 214, 170, 214, 178, 1, + 206, 90, 214, 170, 214, 178, 1, 219, 92, 214, 170, 214, 178, 1, 239, 132, + 214, 170, 214, 178, 1, 232, 43, 214, 170, 214, 178, 1, 232, 194, 214, + 170, 214, 178, 1, 223, 141, 214, 170, 214, 178, 1, 252, 213, 214, 170, + 214, 178, 1, 243, 102, 214, 170, 214, 178, 1, 233, 103, 214, 170, 214, + 178, 1, 209, 253, 214, 170, 214, 178, 1, 222, 194, 214, 170, 214, 178, 1, + 243, 92, 214, 170, 214, 178, 1, 228, 4, 214, 170, 214, 178, 18, 205, 85, + 214, 170, 214, 178, 18, 102, 214, 170, 214, 178, 18, 105, 214, 170, 214, + 178, 18, 142, 214, 170, 214, 178, 18, 139, 214, 170, 214, 178, 18, 168, + 214, 170, 214, 178, 18, 184, 214, 170, 214, 178, 18, 195, 214, 170, 214, + 178, 18, 193, 214, 170, 214, 178, 18, 200, 248, 104, 3, 248, 217, 248, + 104, 3, 252, 73, 248, 104, 3, 208, 183, 248, 104, 1, 253, 164, 248, 104, + 1, 74, 248, 104, 1, 71, 248, 104, 1, 75, 248, 104, 1, 232, 63, 248, 104, + 1, 231, 166, 248, 104, 1, 240, 241, 248, 104, 1, 240, 98, 248, 104, 1, + 225, 76, 248, 104, 1, 249, 0, 248, 104, 1, 248, 109, 248, 104, 1, 232, + 199, 248, 104, 1, 232, 169, 248, 104, 1, 223, 143, 248, 104, 1, 210, 207, + 248, 104, 1, 210, 195, 248, 104, 1, 246, 53, 248, 104, 1, 246, 37, 248, + 104, 1, 224, 102, 248, 104, 1, 212, 215, 248, 104, 1, 212, 55, 248, 104, + 1, 246, 144, 248, 104, 1, 245, 191, 248, 104, 1, 225, 232, 248, 104, 1, + 222, 51, 248, 104, 1, 221, 92, 248, 104, 1, 250, 181, 248, 104, 1, 249, + 255, 248, 104, 1, 228, 18, 248, 104, 1, 205, 167, 248, 104, 1, 206, 109, + 248, 104, 1, 219, 109, 248, 104, 1, 230, 140, 248, 104, 1, 207, 95, 248, + 104, 1, 217, 196, 248, 104, 1, 239, 141, 248, 104, 22, 3, 62, 248, 104, + 22, 3, 74, 248, 104, 22, 3, 233, 102, 248, 104, 22, 3, 71, 248, 104, 22, + 3, 209, 162, 248, 104, 22, 3, 75, 248, 104, 22, 3, 252, 205, 248, 104, + 22, 3, 76, 248, 104, 22, 3, 251, 184, 248, 104, 22, 3, 222, 191, 248, + 104, 148, 83, 248, 104, 251, 185, 83, 248, 104, 208, 188, 248, 104, 228, + 16, 248, 104, 18, 205, 85, 248, 104, 18, 102, 248, 104, 18, 105, 248, + 104, 18, 142, 248, 104, 18, 139, 248, 104, 18, 168, 248, 104, 18, 184, + 248, 104, 18, 195, 248, 104, 18, 193, 248, 104, 18, 200, 248, 104, 217, + 77, 83, 248, 104, 246, 100, 248, 104, 50, 246, 100, 248, 104, 219, 196, + 83, 227, 245, 1, 62, 227, 245, 1, 74, 227, 245, 1, 71, 227, 245, 1, 75, + 227, 245, 1, 76, 227, 245, 1, 172, 227, 245, 1, 231, 167, 227, 245, 1, + 240, 244, 227, 245, 1, 240, 99, 227, 245, 1, 249, 1, 227, 245, 1, 248, + 110, 227, 245, 1, 232, 200, 227, 245, 1, 232, 170, 227, 245, 1, 223, 144, + 227, 245, 1, 210, 208, 227, 245, 1, 210, 196, 227, 245, 1, 246, 54, 227, + 245, 1, 246, 38, 227, 245, 1, 224, 103, 227, 245, 1, 212, 219, 227, 245, + 1, 212, 56, 227, 245, 1, 246, 145, 227, 245, 1, 245, 192, 227, 245, 1, + 199, 227, 245, 1, 179, 227, 245, 1, 221, 93, 227, 245, 1, 250, 183, 227, + 245, 1, 250, 0, 227, 245, 1, 185, 227, 245, 1, 219, 113, 227, 245, 1, + 230, 141, 227, 245, 1, 209, 70, 227, 245, 1, 217, 199, 227, 245, 1, 155, + 227, 245, 1, 218, 89, 227, 245, 3, 223, 184, 227, 245, 253, 29, 53, 227, + 245, 217, 77, 83, 227, 245, 28, 215, 123, 196, 3, 248, 217, 196, 3, 252, + 73, 196, 3, 208, 183, 196, 1, 62, 196, 1, 253, 164, 196, 1, 74, 196, 1, + 233, 102, 196, 1, 71, 196, 1, 209, 162, 196, 1, 115, 137, 196, 1, 115, + 218, 90, 196, 1, 115, 149, 196, 1, 115, 229, 173, 196, 1, 75, 196, 1, + 252, 205, 196, 1, 76, 196, 1, 251, 184, 196, 1, 172, 196, 1, 231, 167, + 196, 1, 240, 244, 196, 1, 240, 99, 196, 1, 225, 77, 196, 1, 249, 1, 196, + 1, 248, 110, 196, 1, 232, 200, 196, 1, 232, 170, 196, 1, 223, 144, 196, + 1, 210, 208, 196, 1, 210, 196, 196, 1, 246, 54, 196, 1, 246, 38, 196, 1, + 224, 103, 196, 1, 212, 219, 196, 1, 212, 56, 196, 1, 246, 145, 196, 1, + 245, 192, 196, 1, 199, 196, 1, 179, 196, 1, 221, 93, 196, 1, 250, 183, + 196, 1, 250, 0, 196, 1, 185, 196, 1, 190, 196, 1, 219, 113, 196, 1, 230, + 141, 196, 1, 229, 172, 196, 1, 209, 70, 196, 1, 216, 2, 196, 1, 214, 96, + 196, 1, 217, 199, 196, 1, 155, 196, 22, 3, 253, 164, 196, 22, 3, 74, 196, + 22, 3, 233, 102, 196, 22, 3, 71, 196, 22, 3, 209, 162, 196, 22, 3, 115, + 137, 196, 22, 3, 115, 218, 90, 196, 22, 3, 115, 149, 196, 22, 3, 115, + 229, 173, 196, 22, 3, 75, 196, 22, 3, 252, 205, 196, 22, 3, 76, 196, 22, + 3, 251, 184, 196, 3, 208, 188, 196, 3, 251, 167, 196, 3, 232, 156, 196, + 3, 209, 204, 196, 222, 173, 196, 246, 100, 196, 50, 246, 100, 196, 253, + 29, 53, 196, 216, 39, 196, 213, 120, 83, 196, 18, 205, 85, 196, 18, 102, + 196, 18, 105, 196, 18, 142, 196, 18, 139, 196, 18, 168, 196, 18, 184, + 196, 18, 195, 196, 18, 193, 196, 18, 200, 196, 243, 74, 132, 252, 19, 18, + 102, 132, 252, 19, 18, 105, 132, 252, 19, 18, 142, 132, 252, 19, 18, 139, + 132, 252, 19, 18, 168, 132, 252, 19, 18, 184, 132, 252, 19, 18, 195, 132, + 252, 19, 18, 193, 132, 252, 19, 18, 200, 132, 252, 19, 43, 212, 98, 132, + 252, 19, 43, 210, 123, 132, 252, 19, 43, 212, 3, 132, 252, 19, 43, 241, + 130, 132, 252, 19, 43, 241, 243, 132, 252, 19, 43, 214, 252, 132, 252, + 19, 43, 216, 17, 132, 252, 19, 43, 243, 79, 132, 252, 19, 43, 224, 190, + 132, 252, 19, 43, 119, 238, 29, 132, 252, 19, 43, 119, 211, 242, 231, + 137, 1, 62, 231, 137, 1, 253, 164, 231, 137, 1, 74, 231, 137, 1, 71, 231, + 137, 1, 75, 231, 137, 1, 252, 205, 231, 137, 1, 76, 231, 137, 1, 251, + 184, 231, 137, 1, 172, 231, 137, 1, 231, 167, 231, 137, 1, 240, 244, 231, + 137, 1, 240, 135, 231, 137, 1, 240, 99, 231, 137, 1, 225, 77, 231, 137, + 1, 249, 1, 231, 137, 1, 248, 110, 231, 137, 1, 232, 200, 231, 137, 1, + 232, 150, 231, 137, 1, 223, 144, 231, 137, 1, 210, 208, 231, 137, 1, 210, + 196, 231, 137, 1, 246, 54, 231, 137, 1, 246, 38, 231, 137, 1, 224, 103, + 231, 137, 1, 212, 219, 231, 137, 1, 212, 56, 231, 137, 1, 246, 145, 231, + 137, 1, 246, 44, 231, 137, 1, 245, 192, 231, 137, 1, 199, 231, 137, 1, + 179, 231, 137, 1, 221, 93, 231, 137, 1, 250, 183, 231, 137, 1, 250, 97, + 231, 137, 1, 250, 0, 231, 137, 1, 185, 231, 137, 1, 190, 231, 137, 1, + 219, 113, 231, 137, 1, 230, 141, 231, 137, 1, 209, 70, 231, 137, 1, 217, + 199, 231, 137, 1, 155, 231, 137, 1, 229, 172, 231, 137, 22, 3, 253, 164, + 231, 137, 22, 3, 74, 231, 137, 22, 3, 233, 102, 231, 137, 22, 3, 71, 231, + 137, 22, 3, 75, 231, 137, 22, 3, 252, 205, 231, 137, 22, 3, 76, 231, 137, + 22, 3, 251, 184, 231, 137, 3, 252, 73, 231, 137, 3, 208, 188, 231, 137, + 3, 223, 184, 231, 137, 3, 215, 249, 231, 137, 246, 100, 231, 137, 50, + 246, 100, 231, 137, 206, 232, 216, 39, 231, 137, 217, 77, 83, 231, 137, + 50, 217, 77, 83, 231, 137, 253, 29, 53, 231, 129, 1, 62, 231, 129, 1, + 253, 164, 231, 129, 1, 74, 231, 129, 1, 233, 102, 231, 129, 1, 71, 231, + 129, 1, 209, 162, 231, 129, 1, 75, 231, 129, 1, 252, 205, 231, 129, 1, + 76, 231, 129, 1, 251, 184, 231, 129, 1, 172, 231, 129, 1, 231, 167, 231, + 129, 1, 240, 244, 231, 129, 1, 240, 135, 231, 129, 1, 240, 99, 231, 129, + 1, 225, 77, 231, 129, 1, 249, 1, 231, 129, 1, 248, 110, 231, 129, 1, 232, + 200, 231, 129, 1, 232, 150, 231, 129, 1, 232, 170, 231, 129, 1, 223, 144, + 231, 129, 1, 210, 208, 231, 129, 1, 210, 196, 231, 129, 1, 246, 54, 231, + 129, 1, 246, 44, 231, 129, 1, 218, 89, 231, 129, 1, 246, 38, 231, 129, 1, + 224, 103, 231, 129, 1, 212, 219, 231, 129, 1, 212, 56, 231, 129, 1, 246, + 145, 231, 129, 1, 245, 192, 231, 129, 1, 199, 231, 129, 1, 179, 231, 129, + 1, 221, 93, 231, 129, 1, 250, 183, 231, 129, 1, 250, 97, 231, 129, 1, + 250, 0, 231, 129, 1, 185, 231, 129, 1, 190, 231, 129, 1, 219, 113, 231, + 129, 1, 230, 141, 231, 129, 1, 209, 70, 231, 129, 1, 216, 2, 231, 129, 1, + 217, 199, 231, 129, 1, 155, 231, 129, 3, 252, 73, 231, 129, 22, 3, 253, + 164, 231, 129, 22, 3, 74, 231, 129, 22, 3, 233, 102, 231, 129, 22, 3, 71, + 231, 129, 22, 3, 209, 162, 231, 129, 22, 3, 75, 231, 129, 22, 3, 252, + 205, 231, 129, 22, 3, 76, 231, 129, 22, 3, 251, 184, 231, 129, 3, 223, + 184, 231, 129, 3, 208, 188, 231, 129, 18, 205, 85, 231, 129, 18, 102, + 231, 129, 18, 105, 231, 129, 18, 142, 231, 129, 18, 139, 231, 129, 18, + 168, 231, 129, 18, 184, 231, 129, 18, 195, 231, 129, 18, 193, 231, 129, + 18, 200, 204, 204, 3, 248, 217, 204, 204, 3, 252, 73, 204, 204, 3, 208, + 183, 204, 204, 1, 62, 204, 204, 1, 253, 164, 204, 204, 1, 74, 204, 204, + 1, 233, 102, 204, 204, 1, 71, 204, 204, 1, 209, 162, 204, 204, 1, 115, + 137, 204, 204, 1, 115, 149, 204, 204, 1, 243, 104, 204, 204, 1, 252, 205, + 204, 204, 1, 222, 152, 204, 204, 1, 251, 184, 204, 204, 1, 172, 204, 204, + 1, 231, 167, 204, 204, 1, 240, 244, 204, 204, 1, 240, 99, 204, 204, 1, + 225, 77, 204, 204, 1, 249, 1, 204, 204, 1, 248, 110, 204, 204, 1, 232, + 200, 204, 204, 1, 232, 170, 204, 204, 1, 223, 144, 204, 204, 1, 210, 208, + 204, 204, 1, 210, 196, 204, 204, 1, 246, 54, 204, 204, 1, 246, 38, 204, + 204, 1, 224, 103, 204, 204, 1, 212, 219, 204, 204, 1, 212, 56, 204, 204, + 1, 246, 145, 204, 204, 1, 245, 192, 204, 204, 1, 199, 204, 204, 1, 179, + 204, 204, 1, 221, 93, 204, 204, 1, 250, 183, 204, 204, 1, 250, 0, 204, + 204, 1, 185, 204, 204, 1, 190, 204, 204, 1, 219, 113, 204, 204, 1, 230, + 141, 204, 204, 1, 229, 172, 204, 204, 1, 209, 70, 204, 204, 1, 216, 2, + 204, 204, 1, 214, 96, 204, 204, 1, 217, 199, 204, 204, 1, 155, 204, 204, + 3, 223, 184, 204, 204, 3, 251, 167, 204, 204, 22, 3, 253, 164, 204, 204, + 22, 3, 74, 204, 204, 22, 3, 233, 102, 204, 204, 22, 3, 71, 204, 204, 22, + 3, 209, 162, 204, 204, 22, 3, 115, 137, 204, 204, 22, 3, 115, 218, 90, + 204, 204, 22, 3, 243, 104, 204, 204, 22, 3, 252, 205, 204, 204, 22, 3, + 222, 152, 204, 204, 22, 3, 251, 184, 204, 204, 3, 208, 188, 204, 204, + 251, 185, 230, 20, 83, 204, 204, 3, 220, 216, 204, 204, 1, 209, 36, 252, + 73, 204, 204, 1, 209, 36, 50, 252, 73, 204, 204, 1, 115, 218, 90, 204, + 204, 1, 115, 229, 173, 204, 204, 22, 3, 115, 149, 204, 204, 22, 3, 115, + 229, 173, 36, 204, 204, 18, 205, 85, 36, 204, 204, 18, 102, 36, 204, 204, + 18, 105, 36, 204, 204, 18, 142, 36, 204, 204, 18, 139, 36, 204, 204, 18, + 168, 36, 204, 204, 18, 184, 36, 204, 204, 1, 62, 36, 204, 204, 1, 172, + 36, 204, 204, 1, 199, 36, 204, 204, 1, 208, 214, 36, 204, 204, 1, 179, + 211, 160, 252, 102, 211, 160, 1, 62, 211, 160, 1, 253, 164, 211, 160, 1, + 74, 211, 160, 1, 233, 102, 211, 160, 1, 71, 211, 160, 1, 209, 162, 211, + 160, 1, 115, 137, 211, 160, 1, 115, 218, 90, 211, 160, 1, 115, 149, 211, + 160, 1, 115, 229, 173, 211, 160, 1, 75, 211, 160, 1, 252, 205, 211, 160, + 1, 76, 211, 160, 1, 251, 184, 211, 160, 1, 172, 211, 160, 1, 231, 167, + 211, 160, 1, 240, 244, 211, 160, 1, 240, 99, 211, 160, 1, 225, 77, 211, + 160, 1, 249, 1, 211, 160, 1, 248, 110, 211, 160, 1, 232, 200, 211, 160, + 1, 232, 170, 211, 160, 1, 223, 144, 211, 160, 1, 210, 208, 211, 160, 1, + 210, 196, 211, 160, 1, 246, 54, 211, 160, 1, 246, 38, 211, 160, 1, 224, + 103, 211, 160, 1, 212, 219, 211, 160, 1, 212, 56, 211, 160, 1, 246, 145, + 211, 160, 1, 245, 192, 211, 160, 1, 199, 211, 160, 1, 179, 211, 160, 1, + 221, 93, 211, 160, 1, 250, 183, 211, 160, 1, 250, 0, 211, 160, 1, 185, + 211, 160, 1, 190, 211, 160, 1, 219, 113, 211, 160, 1, 230, 141, 211, 160, + 1, 209, 70, 211, 160, 1, 216, 2, 211, 160, 1, 214, 96, 211, 160, 1, 217, + 199, 211, 160, 1, 155, 211, 160, 22, 3, 253, 164, 211, 160, 22, 3, 74, + 211, 160, 22, 3, 233, 102, 211, 160, 22, 3, 71, 211, 160, 22, 3, 209, + 162, 211, 160, 22, 3, 115, 137, 211, 160, 22, 3, 115, 218, 90, 211, 160, + 22, 3, 115, 149, 211, 160, 22, 3, 115, 229, 173, 211, 160, 22, 3, 75, + 211, 160, 22, 3, 215, 144, 75, 211, 160, 22, 3, 252, 205, 211, 160, 22, + 3, 76, 211, 160, 22, 3, 215, 144, 76, 211, 160, 22, 3, 251, 184, 211, + 160, 3, 248, 217, 211, 160, 3, 252, 73, 211, 160, 3, 208, 183, 211, 160, + 3, 208, 188, 211, 160, 3, 223, 184, 211, 160, 3, 251, 167, 211, 160, 239, + 175, 211, 160, 253, 29, 53, 211, 160, 222, 173, 211, 160, 18, 205, 85, + 211, 160, 18, 102, 211, 160, 18, 105, 211, 160, 18, 142, 211, 160, 18, + 139, 211, 160, 18, 168, 211, 160, 18, 184, 211, 160, 18, 195, 211, 160, + 18, 193, 211, 160, 18, 200, 215, 75, 1, 62, 215, 75, 1, 253, 164, 215, + 75, 1, 74, 215, 75, 1, 233, 102, 215, 75, 1, 71, 215, 75, 1, 209, 162, + 215, 75, 1, 115, 137, 215, 75, 1, 115, 218, 90, 215, 75, 1, 115, 149, + 215, 75, 1, 115, 229, 173, 215, 75, 1, 75, 215, 75, 1, 252, 205, 215, 75, + 1, 76, 215, 75, 1, 251, 184, 215, 75, 1, 172, 215, 75, 1, 231, 167, 215, + 75, 1, 240, 244, 215, 75, 1, 240, 99, 215, 75, 1, 225, 77, 215, 75, 1, + 249, 1, 215, 75, 1, 248, 110, 215, 75, 1, 232, 200, 215, 75, 1, 232, 170, + 215, 75, 1, 223, 144, 215, 75, 1, 210, 208, 215, 75, 1, 210, 196, 215, + 75, 1, 246, 54, 215, 75, 1, 246, 38, 215, 75, 1, 224, 103, 215, 75, 1, + 212, 219, 215, 75, 1, 212, 56, 215, 75, 1, 246, 145, 215, 75, 1, 245, + 192, 215, 75, 1, 199, 215, 75, 1, 179, 215, 75, 1, 221, 93, 215, 75, 1, + 250, 183, 215, 75, 1, 250, 0, 215, 75, 1, 185, 215, 75, 1, 190, 215, 75, + 1, 219, 113, 215, 75, 1, 230, 141, 215, 75, 1, 209, 70, 215, 75, 1, 216, + 2, 215, 75, 1, 214, 96, 215, 75, 1, 217, 199, 215, 75, 1, 155, 215, 75, + 22, 3, 253, 164, 215, 75, 22, 3, 74, 215, 75, 22, 3, 233, 102, 215, 75, + 22, 3, 71, 215, 75, 22, 3, 209, 162, 215, 75, 22, 3, 115, 137, 215, 75, + 22, 3, 115, 218, 90, 215, 75, 22, 3, 75, 215, 75, 22, 3, 252, 205, 215, + 75, 22, 3, 76, 215, 75, 22, 3, 251, 184, 215, 75, 3, 248, 217, 215, 75, + 3, 252, 73, 215, 75, 3, 208, 183, 215, 75, 3, 208, 188, 215, 75, 3, 223, + 184, 215, 75, 3, 215, 74, 215, 75, 246, 100, 215, 75, 50, 246, 100, 215, + 75, 216, 40, 245, 23, 215, 75, 216, 40, 134, 215, 75, 218, 249, 227, 191, + 215, 75, 218, 249, 227, 190, 215, 75, 218, 249, 227, 189, 215, 75, 243, + 34, 73, 212, 61, 83, 226, 173, 1, 62, 226, 173, 1, 253, 164, 226, 173, 1, + 74, 226, 173, 1, 233, 102, 226, 173, 1, 71, 226, 173, 1, 209, 162, 226, + 173, 1, 115, 137, 226, 173, 1, 115, 218, 90, 226, 173, 1, 115, 149, 226, + 173, 1, 115, 229, 173, 226, 173, 1, 75, 226, 173, 1, 252, 205, 226, 173, + 1, 76, 226, 173, 1, 251, 184, 226, 173, 1, 172, 226, 173, 1, 231, 167, + 226, 173, 1, 240, 244, 226, 173, 1, 240, 99, 226, 173, 1, 225, 77, 226, + 173, 1, 249, 1, 226, 173, 1, 248, 110, 226, 173, 1, 232, 200, 226, 173, + 1, 232, 170, 226, 173, 1, 223, 144, 226, 173, 1, 210, 208, 226, 173, 1, + 210, 196, 226, 173, 1, 246, 54, 226, 173, 1, 246, 38, 226, 173, 1, 224, + 103, 226, 173, 1, 212, 219, 226, 173, 1, 212, 56, 226, 173, 1, 246, 145, + 226, 173, 1, 245, 192, 226, 173, 1, 199, 226, 173, 1, 179, 226, 173, 1, + 221, 93, 226, 173, 1, 250, 183, 226, 173, 1, 250, 0, 226, 173, 1, 185, + 226, 173, 1, 190, 226, 173, 1, 219, 113, 226, 173, 1, 230, 141, 226, 173, + 1, 209, 70, 226, 173, 1, 216, 2, 226, 173, 1, 214, 96, 226, 173, 1, 217, + 199, 226, 173, 1, 155, 226, 173, 1, 229, 172, 226, 173, 22, 3, 253, 164, + 226, 173, 22, 3, 74, 226, 173, 22, 3, 233, 102, 226, 173, 22, 3, 71, 226, + 173, 22, 3, 209, 162, 226, 173, 22, 3, 115, 137, 226, 173, 22, 3, 115, + 218, 90, 226, 173, 22, 3, 115, 149, 226, 173, 22, 3, 115, 229, 173, 226, + 173, 22, 3, 75, 226, 173, 22, 3, 252, 205, 226, 173, 22, 3, 76, 226, 173, + 22, 3, 251, 184, 226, 173, 3, 252, 73, 226, 173, 3, 208, 183, 226, 173, + 3, 208, 188, 226, 173, 3, 252, 16, 226, 173, 246, 100, 226, 173, 50, 246, + 100, 226, 173, 253, 29, 53, 226, 173, 3, 238, 18, 226, 173, 18, 205, 85, + 226, 173, 18, 102, 226, 173, 18, 105, 226, 173, 18, 142, 226, 173, 18, + 139, 226, 173, 18, 168, 226, 173, 18, 184, 226, 173, 18, 195, 226, 173, + 18, 193, 226, 173, 18, 200, 212, 183, 1, 62, 212, 183, 1, 253, 164, 212, + 183, 1, 74, 212, 183, 1, 233, 102, 212, 183, 1, 71, 212, 183, 1, 209, + 162, 212, 183, 1, 75, 212, 183, 1, 252, 205, 212, 183, 1, 76, 212, 183, + 1, 251, 184, 212, 183, 1, 172, 212, 183, 1, 231, 167, 212, 183, 1, 240, + 244, 212, 183, 1, 240, 99, 212, 183, 1, 225, 77, 212, 183, 1, 249, 1, + 212, 183, 1, 248, 110, 212, 183, 1, 232, 200, 212, 183, 1, 232, 170, 212, + 183, 1, 223, 144, 212, 183, 1, 210, 208, 212, 183, 1, 210, 196, 212, 183, + 1, 246, 54, 212, 183, 1, 246, 38, 212, 183, 1, 224, 103, 212, 183, 1, + 212, 219, 212, 183, 1, 212, 56, 212, 183, 1, 246, 145, 212, 183, 1, 245, + 192, 212, 183, 1, 199, 212, 183, 1, 179, 212, 183, 1, 221, 93, 212, 183, + 1, 250, 183, 212, 183, 1, 250, 0, 212, 183, 1, 185, 212, 183, 1, 190, + 212, 183, 1, 219, 113, 212, 183, 1, 230, 141, 212, 183, 1, 209, 70, 212, + 183, 1, 216, 2, 212, 183, 1, 217, 199, 212, 183, 1, 155, 212, 183, 1, + 218, 89, 212, 183, 3, 252, 73, 212, 183, 3, 208, 183, 212, 183, 22, 3, + 253, 164, 212, 183, 22, 3, 74, 212, 183, 22, 3, 233, 102, 212, 183, 22, + 3, 71, 212, 183, 22, 3, 209, 162, 212, 183, 22, 3, 75, 212, 183, 22, 3, + 252, 205, 212, 183, 22, 3, 76, 212, 183, 22, 3, 251, 184, 212, 183, 3, + 208, 188, 212, 183, 3, 223, 184, 212, 183, 18, 205, 85, 212, 183, 18, + 102, 212, 183, 18, 105, 212, 183, 18, 142, 212, 183, 18, 139, 212, 183, + 18, 168, 212, 183, 18, 184, 212, 183, 18, 195, 212, 183, 18, 193, 212, + 183, 18, 200, 202, 197, 6, 1, 225, 76, 202, 197, 6, 1, 62, 202, 197, 6, + 1, 207, 20, 202, 197, 6, 1, 205, 213, 202, 197, 6, 1, 190, 202, 197, 6, + 1, 205, 247, 202, 197, 6, 1, 233, 102, 202, 197, 6, 1, 209, 162, 202, + 197, 6, 1, 75, 202, 197, 6, 1, 76, 202, 197, 6, 1, 252, 114, 202, 197, 6, + 1, 240, 244, 202, 197, 6, 1, 231, 53, 202, 197, 6, 1, 243, 7, 202, 197, + 6, 1, 205, 197, 202, 197, 6, 1, 210, 10, 202, 197, 6, 1, 243, 25, 202, + 197, 6, 1, 222, 209, 202, 197, 6, 1, 210, 203, 202, 197, 6, 1, 223, 170, + 202, 197, 6, 1, 246, 145, 202, 197, 6, 1, 251, 199, 202, 197, 6, 1, 252, + 136, 202, 197, 6, 1, 249, 101, 202, 197, 6, 1, 220, 82, 202, 197, 6, 1, + 238, 241, 202, 197, 6, 1, 238, 138, 202, 197, 6, 1, 238, 67, 202, 197, 6, + 1, 239, 95, 202, 197, 6, 1, 214, 48, 202, 197, 6, 1, 215, 61, 202, 197, + 6, 1, 208, 174, 202, 197, 5, 1, 225, 76, 202, 197, 5, 1, 62, 202, 197, 5, + 1, 207, 20, 202, 197, 5, 1, 205, 213, 202, 197, 5, 1, 190, 202, 197, 5, + 1, 205, 247, 202, 197, 5, 1, 233, 102, 202, 197, 5, 1, 209, 162, 202, + 197, 5, 1, 75, 202, 197, 5, 1, 76, 202, 197, 5, 1, 252, 114, 202, 197, 5, + 1, 240, 244, 202, 197, 5, 1, 231, 53, 202, 197, 5, 1, 243, 7, 202, 197, + 5, 1, 205, 197, 202, 197, 5, 1, 210, 10, 202, 197, 5, 1, 243, 25, 202, + 197, 5, 1, 222, 209, 202, 197, 5, 1, 210, 203, 202, 197, 5, 1, 223, 170, + 202, 197, 5, 1, 246, 145, 202, 197, 5, 1, 251, 199, 202, 197, 5, 1, 252, + 136, 202, 197, 5, 1, 249, 101, 202, 197, 5, 1, 220, 82, 202, 197, 5, 1, + 238, 241, 202, 197, 5, 1, 238, 138, 202, 197, 5, 1, 238, 67, 202, 197, 5, + 1, 239, 95, 202, 197, 5, 1, 214, 48, 202, 197, 5, 1, 215, 61, 202, 197, + 5, 1, 208, 174, 202, 197, 18, 205, 85, 202, 197, 18, 102, 202, 197, 18, + 105, 202, 197, 18, 142, 202, 197, 18, 139, 202, 197, 18, 168, 202, 197, + 18, 184, 202, 197, 18, 195, 202, 197, 18, 193, 202, 197, 18, 200, 202, + 197, 43, 212, 98, 202, 197, 43, 210, 123, 202, 197, 43, 212, 3, 202, 197, + 43, 241, 130, 202, 197, 43, 241, 243, 202, 197, 43, 214, 252, 202, 197, + 43, 216, 17, 202, 197, 43, 243, 79, 202, 197, 43, 224, 190, 202, 197, + 222, 173, 221, 189, 247, 238, 239, 81, 1, 179, 221, 189, 247, 238, 239, + 81, 1, 172, 221, 189, 247, 238, 239, 81, 1, 230, 141, 221, 189, 247, 238, + 239, 81, 1, 185, 221, 189, 247, 238, 239, 81, 1, 246, 145, 221, 189, 247, + 238, 239, 81, 1, 205, 116, 221, 189, 247, 238, 239, 81, 1, 209, 70, 221, + 189, 247, 238, 239, 81, 1, 225, 77, 221, 189, 247, 238, 239, 81, 1, 155, + 221, 189, 247, 238, 239, 81, 1, 240, 244, 221, 189, 247, 238, 239, 81, 1, + 231, 167, 221, 189, 247, 238, 239, 81, 1, 217, 199, 221, 189, 247, 238, + 239, 81, 1, 250, 183, 221, 189, 247, 238, 239, 81, 1, 249, 1, 221, 189, + 247, 238, 239, 81, 1, 212, 219, 221, 189, 247, 238, 239, 81, 1, 212, 56, + 221, 189, 247, 238, 239, 81, 1, 199, 221, 189, 247, 238, 239, 81, 1, 221, + 93, 221, 189, 247, 238, 239, 81, 1, 219, 113, 221, 189, 247, 238, 239, + 81, 1, 242, 73, 221, 189, 247, 238, 239, 81, 1, 248, 110, 221, 189, 247, + 238, 239, 81, 1, 62, 221, 189, 247, 238, 239, 81, 1, 75, 221, 189, 247, + 238, 239, 81, 1, 74, 221, 189, 247, 238, 239, 81, 1, 76, 221, 189, 247, + 238, 239, 81, 1, 71, 221, 189, 247, 238, 239, 81, 1, 210, 18, 221, 189, + 247, 238, 239, 81, 1, 237, 190, 221, 189, 247, 238, 239, 81, 1, 42, 222, + 67, 221, 189, 247, 238, 239, 81, 1, 42, 232, 76, 221, 189, 247, 238, 239, + 81, 1, 42, 213, 10, 221, 189, 247, 238, 239, 81, 1, 42, 229, 28, 221, + 189, 247, 238, 239, 81, 1, 42, 226, 33, 221, 189, 247, 238, 239, 81, 1, + 42, 149, 221, 189, 247, 238, 239, 81, 1, 42, 207, 129, 221, 189, 247, + 238, 239, 81, 1, 42, 225, 79, 221, 189, 247, 238, 239, 81, 1, 42, 206, + 123, 221, 189, 247, 238, 239, 81, 218, 142, 135, 229, 125, 221, 189, 247, + 238, 239, 81, 218, 142, 211, 118, 221, 189, 247, 238, 239, 81, 217, 147, + 240, 25, 213, 251, 221, 189, 247, 238, 239, 81, 218, 142, 135, 152, 241, + 230, 221, 189, 247, 238, 239, 81, 218, 142, 135, 241, 230, 221, 189, 247, + 238, 239, 81, 217, 147, 240, 25, 213, 252, 241, 230, 221, 189, 247, 238, + 239, 81, 217, 147, 135, 229, 125, 221, 189, 247, 238, 239, 81, 217, 147, + 211, 118, 221, 189, 247, 238, 239, 81, 217, 147, 135, 152, 241, 230, 221, + 189, 247, 238, 239, 81, 217, 147, 135, 241, 230, 221, 189, 247, 238, 239, + 81, 226, 248, 211, 118, 221, 189, 247, 238, 239, 81, 240, 25, 213, 252, + 209, 52, 221, 189, 247, 238, 239, 81, 226, 248, 135, 152, 241, 230, 221, + 189, 247, 238, 239, 81, 226, 248, 135, 241, 230, 221, 189, 247, 238, 239, + 81, 229, 95, 135, 229, 125, 221, 189, 247, 238, 239, 81, 229, 95, 211, + 118, 221, 189, 247, 238, 239, 81, 240, 25, 213, 251, 221, 189, 247, 238, + 239, 81, 229, 95, 135, 152, 241, 230, 221, 189, 247, 238, 239, 81, 229, + 95, 135, 241, 230, 221, 189, 247, 238, 239, 81, 240, 25, 213, 252, 241, + 230, 14, 3, 62, 14, 3, 32, 29, 62, 14, 3, 32, 29, 250, 167, 14, 3, 32, + 29, 240, 213, 212, 89, 14, 3, 32, 29, 155, 14, 3, 32, 29, 233, 104, 14, + 3, 32, 29, 230, 121, 239, 192, 14, 3, 32, 29, 226, 69, 14, 3, 32, 29, + 217, 185, 14, 3, 254, 166, 14, 3, 253, 115, 14, 3, 253, 116, 29, 251, + 223, 14, 3, 253, 116, 29, 243, 226, 239, 192, 14, 3, 253, 116, 29, 240, + 226, 14, 3, 253, 116, 29, 240, 213, 212, 89, 14, 3, 253, 116, 29, 155, + 14, 3, 253, 116, 29, 233, 105, 239, 192, 14, 3, 253, 116, 29, 233, 78, + 14, 3, 253, 116, 29, 230, 122, 14, 3, 253, 116, 29, 215, 199, 14, 3, 253, + 116, 29, 106, 101, 106, 101, 71, 14, 3, 253, 116, 239, 192, 14, 3, 253, + 32, 14, 3, 253, 33, 29, 250, 150, 14, 3, 253, 33, 29, 240, 213, 212, 89, + 14, 3, 253, 33, 29, 227, 120, 101, 243, 41, 14, 3, 253, 33, 29, 216, 0, + 14, 3, 253, 33, 29, 212, 186, 14, 3, 253, 5, 14, 3, 252, 189, 14, 3, 252, + 190, 29, 242, 230, 14, 3, 252, 190, 29, 215, 161, 101, 240, 35, 14, 3, + 252, 181, 14, 3, 252, 182, 29, 252, 181, 14, 3, 252, 182, 29, 245, 123, + 14, 3, 252, 182, 29, 240, 35, 14, 3, 252, 182, 29, 155, 14, 3, 252, 182, + 29, 232, 50, 14, 3, 252, 182, 29, 231, 123, 14, 3, 252, 182, 29, 215, + 214, 14, 3, 252, 182, 29, 209, 170, 14, 3, 252, 178, 14, 3, 252, 170, 14, + 3, 252, 132, 14, 3, 252, 133, 29, 215, 214, 14, 3, 252, 122, 14, 3, 252, + 123, 131, 252, 122, 14, 3, 252, 123, 129, 211, 175, 14, 3, 252, 123, 101, + 225, 223, 222, 129, 252, 123, 101, 225, 222, 14, 3, 252, 123, 101, 225, + 223, 214, 106, 14, 3, 252, 93, 14, 3, 252, 63, 14, 3, 252, 31, 14, 3, + 252, 32, 29, 230, 210, 14, 3, 252, 3, 14, 3, 251, 230, 14, 3, 251, 225, + 14, 3, 251, 226, 205, 36, 212, 89, 14, 3, 251, 226, 232, 54, 212, 89, 14, + 3, 251, 226, 131, 251, 226, 210, 165, 131, 210, 165, 210, 165, 131, 210, + 165, 221, 236, 14, 3, 251, 226, 131, 251, 226, 131, 251, 225, 14, 3, 251, + 226, 131, 251, 226, 131, 251, 226, 247, 54, 251, 226, 131, 251, 226, 131, + 251, 225, 14, 3, 251, 223, 14, 3, 251, 219, 14, 3, 250, 183, 14, 3, 250, + 167, 14, 3, 250, 162, 14, 3, 250, 157, 14, 3, 250, 151, 14, 3, 250, 152, + 131, 250, 151, 14, 3, 250, 150, 14, 3, 134, 14, 3, 250, 128, 14, 3, 249, + 244, 14, 3, 249, 245, 29, 62, 14, 3, 249, 245, 29, 240, 204, 14, 3, 249, + 245, 29, 233, 105, 239, 192, 14, 3, 249, 101, 14, 3, 249, 102, 131, 249, + 102, 253, 115, 14, 3, 249, 102, 131, 249, 102, 209, 234, 14, 3, 249, 102, + 247, 54, 249, 101, 14, 3, 249, 79, 14, 3, 249, 80, 131, 249, 79, 14, 3, + 249, 68, 14, 3, 249, 67, 14, 3, 246, 145, 14, 3, 246, 136, 14, 3, 246, + 137, 231, 94, 29, 32, 101, 227, 178, 14, 3, 246, 137, 231, 94, 29, 252, + 132, 14, 3, 246, 137, 231, 94, 29, 250, 150, 14, 3, 246, 137, 231, 94, + 29, 249, 244, 14, 3, 246, 137, 231, 94, 29, 240, 244, 14, 3, 246, 137, + 231, 94, 29, 240, 245, 101, 227, 178, 14, 3, 246, 137, 231, 94, 29, 240, + 61, 14, 3, 246, 137, 231, 94, 29, 240, 43, 14, 3, 246, 137, 231, 94, 29, + 239, 202, 14, 3, 246, 137, 231, 94, 29, 155, 14, 3, 246, 137, 231, 94, + 29, 232, 243, 14, 3, 246, 137, 231, 94, 29, 232, 244, 101, 229, 81, 14, + 3, 246, 137, 231, 94, 29, 232, 35, 14, 3, 246, 137, 231, 94, 29, 230, + 141, 14, 3, 246, 137, 231, 94, 29, 229, 81, 14, 3, 246, 137, 231, 94, 29, + 229, 82, 101, 227, 177, 14, 3, 246, 137, 231, 94, 29, 229, 65, 14, 3, + 246, 137, 231, 94, 29, 225, 110, 14, 3, 246, 137, 231, 94, 29, 221, 237, + 101, 221, 236, 14, 3, 246, 137, 231, 94, 29, 215, 80, 14, 3, 246, 137, + 231, 94, 29, 212, 186, 14, 3, 246, 137, 231, 94, 29, 210, 20, 101, 240, + 43, 14, 3, 246, 137, 231, 94, 29, 209, 170, 14, 3, 246, 109, 14, 3, 246, + 88, 14, 3, 246, 87, 14, 3, 246, 86, 14, 3, 245, 168, 14, 3, 245, 150, 14, + 3, 245, 124, 14, 3, 245, 125, 29, 215, 214, 14, 3, 245, 123, 14, 3, 245, + 113, 14, 3, 245, 114, 231, 255, 106, 239, 193, 245, 94, 14, 3, 245, 94, + 14, 3, 243, 237, 14, 3, 243, 238, 131, 243, 237, 14, 3, 243, 238, 239, + 192, 14, 3, 243, 238, 215, 196, 14, 3, 243, 235, 14, 3, 243, 236, 29, + 242, 212, 14, 3, 243, 234, 14, 3, 243, 233, 14, 3, 243, 232, 14, 3, 243, + 231, 14, 3, 243, 227, 14, 3, 243, 225, 14, 3, 243, 226, 239, 192, 14, 3, + 243, 226, 239, 193, 239, 192, 14, 3, 243, 224, 14, 3, 243, 217, 14, 3, + 75, 14, 3, 174, 29, 221, 236, 14, 3, 174, 131, 174, 223, 174, 131, 223, + 173, 14, 3, 243, 131, 14, 3, 243, 132, 29, 32, 101, 239, 144, 101, 246, + 145, 14, 3, 243, 132, 29, 240, 204, 14, 3, 243, 132, 29, 226, 254, 14, 3, + 243, 132, 29, 217, 172, 14, 3, 243, 132, 29, 215, 214, 14, 3, 243, 132, + 29, 71, 14, 3, 243, 106, 14, 3, 243, 95, 14, 3, 243, 68, 14, 3, 243, 41, + 14, 3, 243, 42, 29, 240, 212, 14, 3, 243, 42, 29, 240, 213, 212, 89, 14, + 3, 243, 42, 29, 227, 119, 14, 3, 243, 42, 247, 54, 243, 41, 14, 3, 243, + 42, 222, 129, 243, 41, 14, 3, 243, 42, 214, 106, 14, 3, 242, 232, 14, 3, + 242, 230, 14, 3, 242, 212, 14, 3, 242, 143, 14, 3, 242, 144, 29, 62, 14, + 3, 242, 144, 29, 32, 101, 230, 108, 14, 3, 242, 144, 29, 32, 101, 230, + 109, 29, 230, 108, 14, 3, 242, 144, 29, 252, 122, 14, 3, 242, 144, 29, + 250, 167, 14, 3, 242, 144, 29, 243, 226, 239, 192, 14, 3, 242, 144, 29, + 243, 226, 239, 193, 239, 192, 14, 3, 242, 144, 29, 155, 14, 3, 242, 144, + 29, 239, 144, 239, 192, 14, 3, 242, 144, 29, 233, 105, 239, 192, 14, 3, + 242, 144, 29, 231, 254, 14, 3, 242, 144, 29, 231, 255, 214, 106, 14, 3, + 242, 144, 29, 230, 234, 14, 3, 242, 144, 29, 230, 141, 14, 3, 242, 144, + 29, 230, 109, 29, 230, 108, 14, 3, 242, 144, 29, 229, 235, 14, 3, 242, + 144, 29, 229, 81, 14, 3, 242, 144, 29, 210, 19, 14, 3, 242, 144, 29, 210, + 8, 14, 3, 240, 244, 14, 3, 240, 245, 239, 192, 14, 3, 240, 242, 14, 3, + 240, 243, 29, 32, 101, 246, 146, 101, 155, 14, 3, 240, 243, 29, 32, 101, + 155, 14, 3, 240, 243, 29, 32, 101, 233, 104, 14, 3, 240, 243, 29, 253, + 33, 212, 90, 101, 212, 207, 14, 3, 240, 243, 29, 252, 122, 14, 3, 240, + 243, 29, 251, 225, 14, 3, 240, 243, 29, 251, 224, 101, 240, 226, 14, 3, + 240, 243, 29, 250, 167, 14, 3, 240, 243, 29, 250, 129, 101, 219, 113, 14, + 3, 240, 243, 29, 249, 68, 14, 3, 240, 243, 29, 249, 69, 101, 219, 113, + 14, 3, 240, 243, 29, 246, 145, 14, 3, 240, 243, 29, 245, 168, 14, 3, 240, + 243, 29, 245, 125, 29, 215, 214, 14, 3, 240, 243, 29, 243, 235, 14, 3, + 240, 243, 29, 243, 68, 14, 3, 240, 243, 29, 243, 69, 101, 230, 141, 14, + 3, 240, 243, 29, 243, 41, 14, 3, 240, 243, 29, 243, 42, 29, 240, 213, + 212, 89, 14, 3, 240, 243, 29, 240, 213, 212, 89, 14, 3, 240, 243, 29, + 240, 204, 14, 3, 240, 243, 29, 240, 61, 14, 3, 240, 243, 29, 240, 59, 14, + 3, 240, 243, 29, 240, 60, 101, 62, 14, 3, 240, 243, 29, 240, 44, 101, + 213, 203, 14, 3, 240, 243, 29, 239, 144, 101, 229, 82, 101, 242, 212, 14, + 3, 240, 243, 29, 239, 124, 14, 3, 240, 243, 29, 239, 125, 101, 230, 141, + 14, 3, 240, 243, 29, 239, 12, 101, 229, 235, 14, 3, 240, 243, 29, 238, + 37, 14, 3, 240, 243, 29, 233, 105, 239, 192, 14, 3, 240, 243, 29, 232, + 229, 101, 238, 43, 101, 251, 225, 14, 3, 240, 243, 29, 232, 35, 14, 3, + 240, 243, 29, 231, 254, 14, 3, 240, 243, 29, 231, 117, 14, 3, 240, 243, + 29, 231, 118, 101, 230, 108, 14, 3, 240, 243, 29, 230, 235, 101, 252, + 122, 14, 3, 240, 243, 29, 230, 141, 14, 3, 240, 243, 29, 227, 120, 101, + 243, 41, 14, 3, 240, 243, 29, 226, 254, 14, 3, 240, 243, 29, 223, 173, + 14, 3, 240, 243, 29, 223, 174, 131, 223, 173, 14, 3, 240, 243, 29, 179, + 14, 3, 240, 243, 29, 217, 172, 14, 3, 240, 243, 29, 217, 138, 14, 3, 240, + 243, 29, 215, 214, 14, 3, 240, 243, 29, 215, 215, 101, 210, 149, 14, 3, + 240, 243, 29, 215, 181, 14, 3, 240, 243, 29, 213, 160, 14, 3, 240, 243, + 29, 212, 186, 14, 3, 240, 243, 29, 71, 14, 3, 240, 243, 29, 210, 8, 14, + 3, 240, 243, 29, 210, 9, 101, 243, 237, 14, 3, 240, 243, 131, 240, 242, + 14, 3, 240, 237, 14, 3, 240, 238, 247, 54, 240, 237, 14, 3, 240, 235, 14, + 3, 240, 236, 131, 240, 236, 240, 205, 131, 240, 204, 14, 3, 240, 226, 14, + 3, 240, 227, 240, 236, 131, 240, 236, 240, 205, 131, 240, 204, 14, 3, + 240, 225, 14, 3, 240, 223, 14, 3, 240, 214, 14, 3, 240, 212, 14, 3, 240, + 213, 212, 89, 14, 3, 240, 213, 131, 240, 212, 14, 3, 240, 213, 247, 54, + 240, 212, 14, 3, 240, 204, 14, 3, 240, 203, 14, 3, 240, 198, 14, 3, 240, + 142, 14, 3, 240, 143, 29, 230, 210, 14, 3, 240, 61, 14, 3, 240, 62, 29, + 75, 14, 3, 240, 62, 29, 71, 14, 3, 240, 62, 247, 54, 240, 61, 14, 3, 240, + 59, 14, 3, 240, 60, 131, 240, 59, 14, 3, 240, 60, 247, 54, 240, 59, 14, + 3, 240, 56, 14, 3, 240, 43, 14, 3, 240, 44, 239, 192, 14, 3, 240, 41, 14, + 3, 240, 42, 29, 32, 101, 233, 104, 14, 3, 240, 42, 29, 240, 213, 212, 89, + 14, 3, 240, 42, 29, 233, 104, 14, 3, 240, 42, 29, 229, 82, 101, 233, 104, + 14, 3, 240, 42, 29, 179, 14, 3, 240, 37, 14, 3, 240, 35, 14, 3, 240, 36, + 247, 54, 240, 35, 14, 3, 240, 36, 29, 250, 167, 14, 3, 240, 36, 29, 212, + 186, 14, 3, 240, 36, 212, 89, 14, 3, 239, 213, 14, 3, 239, 214, 247, 54, + 239, 213, 14, 3, 239, 211, 14, 3, 239, 212, 29, 232, 35, 14, 3, 239, 212, + 29, 232, 36, 29, 233, 105, 239, 192, 14, 3, 239, 212, 29, 223, 173, 14, + 3, 239, 212, 29, 217, 173, 101, 210, 164, 14, 3, 239, 212, 239, 192, 14, + 3, 239, 202, 14, 3, 239, 203, 29, 32, 101, 230, 210, 14, 3, 239, 203, 29, + 230, 210, 14, 3, 239, 203, 131, 239, 203, 229, 72, 14, 3, 239, 196, 14, + 3, 239, 194, 14, 3, 239, 195, 29, 215, 214, 14, 3, 239, 186, 14, 3, 239, + 185, 14, 3, 239, 181, 14, 3, 239, 180, 14, 3, 155, 14, 3, 239, 144, 212, + 89, 14, 3, 239, 144, 239, 192, 14, 3, 239, 124, 14, 3, 239, 11, 14, 3, + 239, 12, 29, 251, 225, 14, 3, 239, 12, 29, 251, 223, 14, 3, 239, 12, 29, + 250, 167, 14, 3, 239, 12, 29, 245, 94, 14, 3, 239, 12, 29, 240, 235, 14, + 3, 239, 12, 29, 231, 109, 14, 3, 239, 12, 29, 223, 173, 14, 3, 239, 12, + 29, 215, 214, 14, 3, 239, 12, 29, 71, 14, 3, 238, 42, 14, 3, 238, 37, 14, + 3, 238, 38, 29, 252, 122, 14, 3, 238, 38, 29, 239, 124, 14, 3, 238, 38, + 29, 231, 254, 14, 3, 238, 38, 29, 229, 186, 14, 3, 238, 38, 29, 210, 8, + 14, 3, 238, 34, 14, 3, 74, 14, 3, 237, 225, 62, 14, 3, 237, 185, 14, 3, + 233, 132, 14, 3, 233, 133, 131, 233, 133, 249, 68, 14, 3, 233, 133, 131, + 233, 133, 214, 106, 14, 3, 233, 107, 14, 3, 233, 104, 14, 3, 233, 105, + 245, 150, 14, 3, 233, 105, 218, 208, 14, 3, 233, 105, 131, 233, 105, 215, + 165, 131, 215, 165, 210, 9, 131, 210, 8, 14, 3, 233, 105, 239, 192, 14, + 3, 233, 96, 14, 3, 233, 97, 29, 240, 213, 212, 89, 14, 3, 233, 95, 14, 3, + 233, 85, 14, 3, 233, 86, 29, 212, 186, 14, 3, 233, 86, 247, 54, 233, 85, + 14, 3, 233, 86, 222, 129, 233, 85, 14, 3, 233, 86, 214, 106, 14, 3, 233, + 78, 14, 3, 233, 68, 14, 3, 232, 243, 14, 3, 232, 228, 14, 3, 172, 14, 3, + 232, 66, 29, 62, 14, 3, 232, 66, 29, 253, 5, 14, 3, 232, 66, 29, 253, 6, + 101, 230, 234, 14, 3, 232, 66, 29, 251, 223, 14, 3, 232, 66, 29, 250, + 167, 14, 3, 232, 66, 29, 250, 150, 14, 3, 232, 66, 29, 134, 14, 3, 232, + 66, 29, 249, 244, 14, 3, 232, 66, 29, 242, 230, 14, 3, 232, 66, 29, 242, + 212, 14, 3, 232, 66, 29, 240, 244, 14, 3, 232, 66, 29, 240, 226, 14, 3, + 232, 66, 29, 240, 213, 212, 89, 14, 3, 232, 66, 29, 240, 204, 14, 3, 232, + 66, 29, 240, 205, 101, 216, 1, 101, 62, 14, 3, 232, 66, 29, 240, 61, 14, + 3, 232, 66, 29, 240, 43, 14, 3, 232, 66, 29, 240, 36, 101, 217, 138, 14, + 3, 232, 66, 29, 240, 36, 247, 54, 240, 35, 14, 3, 232, 66, 29, 239, 213, + 14, 3, 232, 66, 29, 239, 185, 14, 3, 232, 66, 29, 233, 104, 14, 3, 232, + 66, 29, 233, 85, 14, 3, 232, 66, 29, 232, 35, 14, 3, 232, 66, 29, 231, + 123, 14, 3, 232, 66, 29, 231, 117, 14, 3, 232, 66, 29, 229, 235, 14, 3, + 232, 66, 29, 229, 81, 14, 3, 232, 66, 29, 227, 119, 14, 3, 232, 66, 29, + 227, 120, 101, 243, 237, 14, 3, 232, 66, 29, 227, 120, 101, 240, 61, 14, + 3, 232, 66, 29, 227, 120, 101, 212, 131, 14, 3, 232, 66, 29, 226, 254, + 14, 3, 232, 66, 29, 226, 255, 101, 223, 168, 14, 3, 232, 66, 29, 225, + 110, 14, 3, 232, 66, 29, 223, 173, 14, 3, 232, 66, 29, 221, 53, 14, 3, + 232, 66, 29, 218, 50, 14, 3, 232, 66, 29, 217, 199, 14, 3, 232, 66, 29, + 217, 138, 14, 3, 232, 66, 29, 216, 2, 14, 3, 232, 66, 29, 215, 214, 14, + 3, 232, 66, 29, 215, 181, 14, 3, 232, 66, 29, 215, 116, 14, 3, 232, 66, + 29, 215, 68, 14, 3, 232, 66, 29, 213, 169, 14, 3, 232, 66, 29, 212, 162, + 14, 3, 232, 66, 29, 71, 14, 3, 232, 66, 29, 210, 19, 14, 3, 232, 66, 29, + 210, 8, 14, 3, 232, 66, 29, 209, 237, 29, 179, 14, 3, 232, 66, 29, 209, + 170, 14, 3, 232, 66, 29, 205, 40, 14, 3, 232, 64, 14, 3, 232, 65, 247, + 54, 232, 64, 14, 3, 232, 55, 14, 3, 232, 52, 14, 3, 232, 50, 14, 3, 232, + 49, 14, 3, 232, 47, 14, 3, 232, 48, 131, 232, 47, 14, 3, 232, 35, 14, 3, + 232, 36, 29, 233, 105, 239, 192, 14, 3, 232, 31, 14, 3, 232, 32, 29, 250, + 167, 14, 3, 232, 32, 247, 54, 232, 31, 14, 3, 232, 29, 14, 3, 232, 28, + 14, 3, 231, 254, 14, 3, 231, 255, 230, 123, 29, 106, 131, 230, 123, 29, + 71, 14, 3, 231, 255, 131, 231, 255, 230, 123, 29, 106, 131, 230, 123, 29, + 71, 14, 3, 231, 194, 14, 3, 231, 123, 14, 3, 231, 124, 29, 250, 167, 14, + 3, 231, 124, 29, 71, 14, 3, 231, 124, 29, 210, 8, 14, 3, 231, 117, 14, 3, + 231, 109, 14, 3, 231, 96, 14, 3, 231, 95, 14, 3, 231, 93, 14, 3, 231, 94, + 131, 231, 93, 14, 3, 230, 236, 14, 3, 230, 237, 131, 239, 12, 29, 251, + 224, 230, 237, 131, 239, 12, 29, 251, 223, 14, 3, 230, 234, 14, 3, 230, + 232, 14, 3, 230, 233, 209, 53, 17, 14, 3, 230, 231, 14, 3, 230, 223, 14, + 3, 230, 224, 239, 192, 14, 3, 230, 222, 14, 3, 230, 210, 14, 3, 230, 211, + 222, 129, 230, 210, 14, 3, 230, 205, 14, 3, 230, 183, 14, 3, 230, 141, + 14, 3, 230, 122, 14, 3, 230, 123, 29, 62, 14, 3, 230, 123, 29, 32, 101, + 246, 146, 101, 155, 14, 3, 230, 123, 29, 32, 101, 240, 204, 14, 3, 230, + 123, 29, 32, 101, 230, 108, 14, 3, 230, 123, 29, 252, 181, 14, 3, 230, + 123, 29, 252, 122, 14, 3, 230, 123, 29, 251, 226, 205, 36, 212, 89, 14, + 3, 230, 123, 29, 250, 167, 14, 3, 230, 123, 29, 249, 244, 14, 3, 230, + 123, 29, 246, 88, 14, 3, 230, 123, 29, 243, 41, 14, 3, 230, 123, 29, 240, + 244, 14, 3, 230, 123, 29, 240, 204, 14, 3, 230, 123, 29, 239, 202, 14, 3, + 230, 123, 29, 239, 203, 101, 239, 202, 14, 3, 230, 123, 29, 155, 14, 3, + 230, 123, 29, 239, 124, 14, 3, 230, 123, 29, 239, 12, 29, 223, 173, 14, + 3, 230, 123, 29, 233, 105, 239, 192, 14, 3, 230, 123, 29, 233, 85, 14, 3, + 230, 123, 29, 233, 86, 101, 155, 14, 3, 230, 123, 29, 233, 86, 101, 229, + 81, 14, 3, 230, 123, 29, 231, 123, 14, 3, 230, 123, 29, 231, 109, 14, 3, + 230, 123, 29, 230, 234, 14, 3, 230, 123, 29, 230, 223, 14, 3, 230, 123, + 29, 230, 224, 101, 239, 12, 101, 62, 14, 3, 230, 123, 29, 230, 122, 14, + 3, 230, 123, 29, 229, 186, 14, 3, 230, 123, 29, 229, 81, 14, 3, 230, 123, + 29, 229, 67, 14, 3, 230, 123, 29, 227, 119, 14, 3, 230, 123, 29, 227, + 120, 101, 243, 41, 14, 3, 230, 123, 29, 226, 69, 14, 3, 230, 123, 29, + 225, 110, 14, 3, 230, 123, 29, 215, 215, 101, 213, 160, 14, 3, 230, 123, + 29, 215, 161, 101, 240, 36, 101, 242, 230, 14, 3, 230, 123, 29, 215, 161, + 101, 240, 36, 212, 89, 14, 3, 230, 123, 29, 215, 114, 14, 3, 230, 123, + 29, 215, 115, 101, 215, 114, 14, 3, 230, 123, 29, 213, 160, 14, 3, 230, + 123, 29, 212, 198, 14, 3, 230, 123, 29, 212, 186, 14, 3, 230, 123, 29, + 212, 132, 101, 32, 101, 213, 204, 101, 199, 14, 3, 230, 123, 29, 71, 14, + 3, 230, 123, 29, 106, 101, 62, 14, 3, 230, 123, 29, 106, 101, 106, 101, + 71, 14, 3, 230, 123, 29, 210, 20, 101, 251, 225, 14, 3, 230, 123, 29, + 210, 8, 14, 3, 230, 123, 29, 209, 170, 14, 3, 230, 123, 214, 106, 14, 3, + 230, 120, 14, 3, 230, 121, 29, 215, 214, 14, 3, 230, 121, 29, 215, 215, + 101, 213, 160, 14, 3, 230, 121, 239, 192, 14, 3, 230, 121, 239, 193, 131, + 230, 121, 239, 193, 215, 214, 14, 3, 230, 116, 14, 3, 230, 108, 14, 3, + 230, 109, 29, 230, 108, 14, 3, 230, 106, 14, 3, 230, 107, 29, 230, 210, + 14, 3, 230, 107, 29, 230, 211, 101, 218, 50, 14, 3, 229, 235, 14, 3, 229, + 218, 14, 3, 229, 208, 14, 3, 229, 186, 14, 3, 229, 81, 14, 3, 229, 82, + 29, 250, 167, 14, 3, 229, 79, 14, 3, 229, 80, 29, 252, 181, 14, 3, 229, + 80, 29, 250, 167, 14, 3, 229, 80, 29, 242, 212, 14, 3, 229, 80, 29, 242, + 213, 212, 89, 14, 3, 229, 80, 29, 240, 213, 212, 89, 14, 3, 229, 80, 29, + 239, 12, 29, 250, 167, 14, 3, 229, 80, 29, 233, 85, 14, 3, 229, 80, 29, + 232, 52, 14, 3, 229, 80, 29, 232, 50, 14, 3, 229, 80, 29, 232, 51, 101, + 251, 225, 14, 3, 229, 80, 29, 231, 123, 14, 3, 229, 80, 29, 230, 142, + 101, 251, 225, 14, 3, 229, 80, 29, 230, 122, 14, 3, 229, 80, 29, 227, + 120, 101, 243, 41, 14, 3, 229, 80, 29, 225, 110, 14, 3, 229, 80, 29, 223, + 217, 14, 3, 229, 80, 29, 215, 81, 101, 251, 225, 14, 3, 229, 80, 29, 215, + 60, 101, 249, 101, 14, 3, 229, 80, 29, 210, 164, 14, 3, 229, 80, 212, 89, + 14, 3, 229, 80, 247, 54, 229, 79, 14, 3, 229, 80, 222, 129, 229, 79, 14, + 3, 229, 80, 214, 106, 14, 3, 229, 80, 215, 196, 14, 3, 229, 78, 14, 3, + 229, 72, 14, 3, 229, 73, 131, 229, 72, 14, 3, 229, 73, 222, 129, 229, 72, + 14, 3, 229, 73, 215, 196, 14, 3, 229, 70, 14, 3, 229, 67, 14, 3, 229, 65, + 14, 3, 229, 66, 131, 229, 65, 14, 3, 229, 66, 131, 229, 66, 240, 205, + 131, 240, 204, 14, 3, 185, 14, 3, 228, 20, 29, 212, 186, 14, 3, 228, 20, + 239, 192, 14, 3, 228, 19, 14, 3, 227, 247, 14, 3, 227, 199, 14, 3, 227, + 178, 14, 3, 227, 177, 14, 3, 227, 119, 14, 3, 227, 71, 14, 3, 226, 254, + 14, 3, 226, 209, 14, 3, 226, 114, 14, 3, 226, 115, 131, 226, 114, 14, 3, + 226, 103, 14, 3, 226, 104, 239, 192, 14, 3, 226, 87, 14, 3, 226, 73, 14, + 3, 226, 69, 14, 3, 226, 70, 29, 62, 14, 3, 226, 70, 29, 230, 210, 14, 3, + 226, 70, 29, 205, 116, 14, 3, 226, 70, 131, 226, 69, 14, 3, 226, 70, 131, + 226, 70, 29, 32, 101, 199, 14, 3, 226, 70, 247, 54, 226, 69, 14, 3, 226, + 67, 14, 3, 226, 68, 29, 62, 14, 3, 226, 68, 29, 32, 101, 245, 168, 14, 3, + 226, 68, 29, 245, 168, 14, 3, 226, 68, 239, 192, 14, 3, 199, 14, 3, 225, + 235, 14, 3, 225, 222, 14, 3, 225, 223, 233, 1, 14, 3, 225, 223, 29, 215, + 117, 212, 89, 14, 3, 225, 223, 222, 129, 225, 222, 14, 3, 225, 221, 14, + 3, 225, 214, 223, 159, 14, 3, 225, 213, 14, 3, 225, 212, 14, 3, 225, 110, + 14, 3, 225, 111, 29, 62, 14, 3, 225, 111, 29, 210, 8, 14, 3, 225, 111, + 215, 196, 14, 3, 224, 230, 14, 3, 224, 231, 29, 75, 14, 3, 224, 229, 14, + 3, 224, 200, 14, 3, 224, 201, 29, 240, 213, 212, 89, 14, 3, 224, 201, 29, + 240, 205, 101, 240, 213, 212, 89, 14, 3, 224, 196, 14, 3, 224, 197, 29, + 252, 122, 14, 3, 224, 197, 29, 251, 225, 14, 3, 224, 197, 29, 251, 226, + 101, 251, 225, 14, 3, 224, 197, 29, 239, 202, 14, 3, 224, 197, 29, 227, + 120, 101, 240, 213, 212, 89, 14, 3, 224, 197, 29, 225, 110, 14, 3, 224, + 197, 29, 223, 173, 14, 3, 224, 197, 29, 215, 214, 14, 3, 224, 197, 29, + 215, 215, 101, 32, 252, 122, 14, 3, 224, 197, 29, 215, 215, 101, 251, + 225, 14, 3, 224, 197, 29, 215, 215, 101, 251, 226, 101, 251, 225, 14, 3, + 224, 197, 29, 210, 20, 101, 251, 225, 14, 3, 224, 197, 29, 209, 170, 14, + 3, 224, 185, 14, 3, 223, 217, 14, 3, 223, 189, 14, 3, 223, 173, 14, 3, + 223, 174, 230, 121, 29, 240, 204, 14, 3, 223, 174, 230, 121, 29, 227, + 178, 14, 3, 223, 174, 230, 121, 29, 217, 172, 14, 3, 223, 174, 230, 121, + 29, 217, 173, 131, 223, 174, 230, 121, 29, 217, 172, 14, 3, 223, 174, + 230, 121, 29, 209, 170, 14, 3, 223, 174, 212, 89, 14, 3, 223, 174, 131, + 223, 173, 14, 3, 223, 174, 247, 54, 223, 173, 14, 3, 223, 174, 247, 54, + 223, 174, 230, 121, 131, 230, 120, 14, 3, 223, 168, 14, 3, 223, 169, 253, + 33, 29, 251, 219, 14, 3, 223, 169, 253, 33, 29, 249, 244, 14, 3, 223, + 169, 253, 33, 29, 243, 233, 14, 3, 223, 169, 253, 33, 29, 239, 202, 14, + 3, 223, 169, 253, 33, 29, 233, 105, 239, 192, 14, 3, 223, 169, 253, 33, + 29, 232, 50, 14, 3, 223, 169, 253, 33, 29, 230, 141, 14, 3, 223, 169, + 253, 33, 29, 225, 110, 14, 3, 223, 169, 253, 33, 29, 215, 57, 14, 3, 223, + 169, 253, 33, 29, 210, 19, 14, 3, 223, 169, 231, 94, 29, 249, 244, 14, 3, + 223, 169, 231, 94, 29, 249, 245, 71, 14, 3, 179, 14, 3, 222, 42, 14, 3, + 222, 6, 14, 3, 221, 236, 14, 3, 221, 107, 14, 3, 221, 53, 14, 3, 221, 54, + 29, 62, 14, 3, 221, 54, 29, 253, 115, 14, 3, 221, 54, 29, 249, 244, 14, + 3, 221, 54, 29, 249, 101, 14, 3, 221, 54, 29, 75, 14, 3, 221, 54, 29, 74, + 14, 3, 221, 54, 29, 237, 185, 14, 3, 221, 54, 29, 71, 14, 3, 221, 54, 29, + 210, 19, 14, 3, 221, 54, 247, 54, 221, 53, 14, 3, 220, 251, 14, 3, 220, + 252, 29, 232, 31, 14, 3, 220, 252, 29, 210, 8, 14, 3, 220, 252, 29, 205, + 116, 14, 3, 220, 252, 222, 129, 220, 251, 14, 3, 219, 113, 14, 3, 219, + 107, 14, 3, 218, 208, 14, 3, 218, 50, 14, 3, 217, 199, 14, 3, 217, 186, + 223, 159, 14, 3, 217, 185, 14, 3, 217, 186, 29, 62, 14, 3, 217, 186, 29, + 243, 237, 14, 3, 217, 186, 29, 243, 235, 14, 3, 217, 186, 29, 155, 14, 3, + 217, 186, 29, 232, 35, 14, 3, 217, 186, 29, 230, 210, 14, 3, 217, 186, + 29, 229, 65, 14, 3, 217, 186, 29, 226, 254, 14, 3, 217, 186, 29, 223, + 173, 14, 3, 217, 186, 29, 217, 172, 14, 3, 217, 186, 29, 215, 181, 14, 3, + 217, 186, 29, 212, 207, 14, 3, 217, 186, 29, 210, 19, 14, 3, 217, 186, + 29, 210, 14, 14, 3, 217, 186, 29, 209, 241, 14, 3, 217, 186, 29, 209, + 194, 14, 3, 217, 186, 29, 209, 170, 14, 3, 217, 186, 131, 217, 185, 14, + 3, 217, 186, 239, 192, 14, 3, 217, 172, 14, 3, 217, 173, 230, 123, 29, + 251, 223, 14, 3, 217, 146, 14, 3, 217, 138, 14, 3, 216, 2, 14, 3, 216, 0, + 14, 3, 216, 1, 29, 62, 14, 3, 216, 1, 29, 250, 167, 14, 3, 216, 1, 29, + 240, 35, 14, 3, 216, 1, 29, 225, 110, 14, 3, 216, 1, 29, 215, 114, 14, 3, + 216, 1, 29, 210, 149, 14, 3, 216, 1, 29, 71, 14, 3, 216, 1, 29, 106, 101, + 62, 14, 3, 215, 255, 14, 3, 215, 253, 14, 3, 215, 230, 14, 3, 215, 214, + 14, 3, 215, 215, 238, 42, 14, 3, 215, 215, 131, 215, 215, 240, 236, 131, + 240, 236, 240, 205, 131, 240, 204, 14, 3, 215, 215, 131, 215, 215, 212, + 208, 131, 212, 208, 240, 205, 131, 240, 204, 14, 3, 215, 207, 14, 3, 215, + 202, 14, 3, 215, 199, 14, 3, 215, 198, 14, 3, 215, 195, 14, 3, 215, 181, + 14, 3, 215, 182, 29, 62, 14, 3, 215, 182, 29, 233, 85, 14, 3, 215, 175, + 14, 3, 215, 176, 29, 62, 14, 3, 215, 176, 29, 250, 151, 14, 3, 215, 176, + 29, 249, 79, 14, 3, 215, 176, 29, 245, 113, 14, 3, 215, 176, 29, 240, + 204, 14, 3, 215, 176, 29, 233, 104, 14, 3, 215, 176, 29, 233, 105, 239, + 192, 14, 3, 215, 176, 29, 230, 205, 14, 3, 215, 176, 29, 229, 67, 14, 3, + 215, 176, 29, 226, 103, 14, 3, 215, 176, 29, 217, 172, 14, 3, 215, 169, + 14, 3, 215, 164, 14, 3, 215, 165, 212, 89, 14, 3, 215, 165, 131, 215, + 165, 249, 69, 131, 249, 68, 14, 3, 215, 160, 14, 3, 215, 116, 14, 3, 215, + 117, 131, 233, 2, 215, 116, 14, 3, 215, 114, 14, 3, 215, 113, 14, 3, 215, + 80, 14, 3, 215, 81, 239, 192, 14, 3, 215, 68, 14, 3, 215, 66, 14, 3, 215, + 67, 131, 215, 67, 215, 114, 14, 3, 215, 59, 14, 3, 215, 57, 14, 3, 213, + 203, 14, 3, 213, 204, 131, 213, 203, 14, 3, 213, 172, 14, 3, 213, 171, + 14, 3, 213, 169, 14, 3, 213, 160, 14, 3, 213, 159, 14, 3, 213, 133, 14, + 3, 213, 132, 14, 3, 212, 219, 14, 3, 212, 220, 251, 209, 14, 3, 212, 220, + 29, 239, 11, 14, 3, 212, 220, 29, 226, 254, 14, 3, 212, 220, 239, 192, + 14, 3, 212, 207, 14, 3, 212, 208, 131, 212, 208, 224, 231, 131, 224, 231, + 245, 95, 131, 245, 94, 14, 3, 212, 208, 214, 106, 14, 3, 212, 198, 14, 3, + 150, 29, 249, 244, 14, 3, 150, 29, 239, 202, 14, 3, 150, 29, 215, 214, + 14, 3, 150, 29, 215, 116, 14, 3, 150, 29, 210, 164, 14, 3, 150, 29, 210, + 8, 14, 3, 212, 186, 14, 3, 212, 162, 14, 3, 212, 131, 14, 3, 212, 132, + 239, 192, 14, 3, 211, 211, 14, 3, 211, 212, 212, 89, 14, 3, 211, 182, 14, + 3, 211, 162, 14, 3, 211, 163, 29, 212, 186, 14, 3, 211, 163, 131, 211, + 162, 14, 3, 211, 163, 131, 211, 163, 240, 236, 131, 240, 236, 240, 205, + 131, 240, 204, 14, 3, 210, 170, 14, 3, 210, 164, 14, 3, 210, 162, 14, 3, + 210, 159, 14, 3, 210, 149, 14, 3, 210, 150, 131, 210, 150, 205, 117, 131, + 205, 116, 14, 3, 71, 14, 3, 106, 239, 202, 14, 3, 106, 106, 71, 14, 3, + 106, 131, 106, 222, 52, 131, 222, 52, 240, 205, 131, 240, 204, 14, 3, + 106, 131, 106, 213, 134, 131, 213, 133, 14, 3, 106, 131, 106, 106, 218, + 224, 131, 106, 218, 223, 14, 3, 210, 19, 14, 3, 210, 14, 14, 3, 210, 8, + 14, 3, 210, 9, 230, 205, 14, 3, 210, 9, 29, 250, 167, 14, 3, 210, 9, 29, + 226, 254, 14, 3, 210, 9, 29, 106, 101, 106, 101, 71, 14, 3, 210, 9, 29, + 106, 101, 106, 101, 106, 239, 192, 14, 3, 210, 9, 239, 192, 14, 3, 210, + 9, 215, 196, 14, 3, 210, 9, 215, 197, 29, 250, 167, 14, 3, 210, 4, 14, 3, + 209, 241, 14, 3, 209, 242, 29, 230, 122, 14, 3, 209, 242, 29, 227, 120, + 101, 246, 145, 14, 3, 209, 242, 29, 216, 0, 14, 3, 209, 242, 29, 71, 14, + 3, 209, 240, 14, 3, 209, 236, 14, 3, 209, 237, 29, 231, 254, 14, 3, 209, + 237, 29, 179, 14, 3, 209, 234, 14, 3, 209, 235, 239, 192, 14, 3, 209, + 194, 14, 3, 209, 195, 247, 54, 209, 194, 14, 3, 209, 195, 215, 196, 14, + 3, 209, 192, 14, 3, 209, 193, 29, 32, 101, 155, 14, 3, 209, 193, 29, 32, + 101, 199, 14, 3, 209, 193, 29, 252, 181, 14, 3, 209, 193, 29, 155, 14, 3, + 209, 193, 29, 223, 173, 14, 3, 209, 193, 29, 210, 19, 14, 3, 209, 193, + 29, 210, 20, 101, 251, 225, 14, 3, 209, 193, 29, 210, 20, 101, 249, 244, + 14, 3, 209, 191, 14, 3, 209, 188, 14, 3, 209, 187, 14, 3, 209, 183, 14, + 3, 209, 184, 29, 62, 14, 3, 209, 184, 29, 251, 219, 14, 3, 209, 184, 29, + 134, 14, 3, 209, 184, 29, 243, 227, 14, 3, 209, 184, 29, 240, 244, 14, 3, + 209, 184, 29, 240, 226, 14, 3, 209, 184, 29, 240, 213, 212, 89, 14, 3, + 209, 184, 29, 240, 204, 14, 3, 209, 184, 29, 239, 213, 14, 3, 209, 184, + 29, 155, 14, 3, 209, 184, 29, 233, 104, 14, 3, 209, 184, 29, 233, 85, 14, + 3, 209, 184, 29, 232, 228, 14, 3, 209, 184, 29, 231, 123, 14, 3, 209, + 184, 29, 229, 65, 14, 3, 209, 184, 29, 226, 209, 14, 3, 209, 184, 29, + 179, 14, 3, 209, 184, 29, 215, 214, 14, 3, 209, 184, 29, 215, 66, 14, 3, + 209, 184, 29, 210, 170, 14, 3, 209, 184, 29, 106, 101, 239, 202, 14, 3, + 209, 184, 29, 210, 8, 14, 3, 209, 184, 29, 209, 181, 14, 3, 209, 181, 14, + 3, 209, 182, 29, 71, 14, 3, 209, 170, 14, 3, 209, 171, 29, 62, 14, 3, + 209, 171, 29, 230, 236, 14, 3, 209, 171, 29, 230, 210, 14, 3, 209, 171, + 29, 212, 186, 14, 3, 209, 166, 14, 3, 209, 169, 14, 3, 209, 167, 14, 3, + 209, 163, 14, 3, 209, 151, 14, 3, 209, 152, 29, 231, 254, 14, 3, 209, + 150, 14, 3, 205, 116, 14, 3, 205, 117, 212, 89, 14, 3, 205, 117, 98, 29, + 230, 210, 14, 3, 205, 113, 14, 3, 205, 106, 14, 3, 205, 92, 14, 3, 205, + 40, 14, 3, 205, 41, 131, 205, 40, 14, 3, 205, 39, 14, 3, 205, 37, 14, 3, + 205, 38, 232, 54, 212, 89, 14, 3, 205, 32, 14, 3, 205, 24, 14, 3, 205, 9, + 14, 3, 205, 7, 14, 3, 205, 8, 29, 62, 14, 3, 205, 6, 14, 3, 205, 5, 14, + 3, 232, 21, 243, 65, 14, 3, 253, 116, 29, 223, 173, 14, 3, 253, 33, 29, + 62, 14, 3, 252, 133, 29, 230, 225, 14, 3, 246, 137, 231, 94, 29, 210, 20, + 101, 227, 178, 14, 3, 246, 135, 14, 3, 245, 95, 101, 215, 116, 14, 3, + 243, 236, 29, 215, 214, 14, 3, 242, 144, 29, 239, 202, 14, 3, 242, 144, + 29, 215, 214, 14, 3, 240, 243, 29, 252, 123, 101, 232, 36, 101, 62, 14, + 3, 240, 243, 29, 251, 223, 14, 3, 240, 169, 14, 3, 240, 51, 14, 3, 238, + 21, 14, 3, 232, 66, 29, 252, 93, 14, 3, 232, 66, 29, 251, 222, 14, 3, + 232, 66, 29, 240, 35, 14, 3, 232, 66, 29, 239, 202, 14, 3, 232, 66, 29, + 239, 12, 29, 251, 223, 14, 3, 232, 66, 29, 229, 65, 14, 3, 232, 66, 29, + 179, 14, 3, 232, 66, 29, 215, 109, 14, 3, 232, 66, 29, 210, 170, 14, 3, + 232, 66, 29, 209, 192, 14, 3, 230, 123, 29, 240, 61, 14, 3, 229, 80, 215, + 197, 29, 250, 167, 14, 3, 229, 80, 29, 242, 213, 101, 230, 108, 14, 3, + 229, 80, 29, 215, 116, 14, 3, 227, 70, 14, 3, 226, 68, 29, 205, 116, 14, + 3, 225, 234, 14, 3, 224, 199, 14, 3, 224, 198, 14, 3, 224, 197, 29, 250, + 151, 14, 3, 224, 197, 29, 240, 61, 14, 3, 223, 190, 218, 97, 224, 191, + 245, 244, 14, 3, 221, 108, 251, 209, 14, 3, 220, 255, 14, 3, 217, 186, + 29, 233, 105, 239, 192, 14, 3, 211, 210, 14, 3, 209, 242, 29, 227, 119, + 14, 133, 3, 118, 251, 225, 14, 133, 3, 129, 251, 225, 14, 133, 3, 241, + 125, 251, 225, 14, 133, 3, 241, 204, 251, 225, 14, 133, 3, 215, 10, 251, + 225, 14, 133, 3, 216, 23, 251, 225, 14, 133, 3, 243, 88, 251, 225, 14, + 133, 3, 224, 195, 251, 225, 14, 133, 3, 129, 245, 94, 14, 133, 3, 241, + 125, 245, 94, 14, 133, 3, 241, 204, 245, 94, 14, 133, 3, 215, 10, 245, + 94, 14, 133, 3, 216, 23, 245, 94, 14, 133, 3, 243, 88, 245, 94, 14, 133, + 3, 224, 195, 245, 94, 14, 133, 3, 241, 125, 71, 14, 133, 3, 241, 204, 71, + 14, 133, 3, 215, 10, 71, 14, 133, 3, 216, 23, 71, 14, 133, 3, 243, 88, + 71, 14, 133, 3, 224, 195, 71, 14, 133, 3, 119, 240, 144, 14, 133, 3, 118, + 240, 144, 14, 133, 3, 129, 240, 144, 14, 133, 3, 241, 125, 240, 144, 14, + 133, 3, 241, 204, 240, 144, 14, 133, 3, 215, 10, 240, 144, 14, 133, 3, + 216, 23, 240, 144, 14, 133, 3, 243, 88, 240, 144, 14, 133, 3, 224, 195, + 240, 144, 14, 133, 3, 119, 240, 141, 14, 133, 3, 118, 240, 141, 14, 133, + 3, 129, 240, 141, 14, 133, 3, 241, 125, 240, 141, 14, 133, 3, 241, 204, + 240, 141, 14, 133, 3, 118, 215, 230, 14, 133, 3, 129, 215, 230, 14, 133, + 3, 129, 215, 231, 209, 53, 17, 14, 133, 3, 241, 125, 215, 230, 14, 133, + 3, 241, 204, 215, 230, 14, 133, 3, 215, 10, 215, 230, 14, 133, 3, 216, + 23, 215, 230, 14, 133, 3, 243, 88, 215, 230, 14, 133, 3, 224, 195, 215, + 230, 14, 133, 3, 119, 215, 225, 14, 133, 3, 118, 215, 225, 14, 133, 3, + 129, 215, 225, 14, 133, 3, 129, 215, 226, 209, 53, 17, 14, 133, 3, 241, + 125, 215, 225, 14, 133, 3, 241, 204, 215, 225, 14, 133, 3, 215, 231, 29, + 240, 227, 101, 245, 94, 14, 133, 3, 215, 231, 29, 240, 227, 101, 226, + 209, 14, 133, 3, 119, 249, 65, 14, 133, 3, 118, 249, 65, 14, 133, 3, 129, + 249, 65, 14, 133, 3, 129, 249, 66, 209, 53, 17, 14, 133, 3, 241, 125, + 249, 65, 14, 133, 3, 241, 204, 249, 65, 14, 133, 3, 129, 209, 53, 241, + 136, 242, 214, 14, 133, 3, 129, 209, 53, 241, 136, 242, 211, 14, 133, 3, + 241, 125, 209, 53, 241, 136, 229, 209, 14, 133, 3, 241, 125, 209, 53, + 241, 136, 229, 207, 14, 133, 3, 241, 125, 209, 53, 241, 136, 229, 210, + 62, 14, 133, 3, 241, 125, 209, 53, 241, 136, 229, 210, 251, 150, 14, 133, + 3, 215, 10, 209, 53, 241, 136, 251, 221, 14, 133, 3, 216, 23, 209, 53, + 241, 136, 233, 77, 14, 133, 3, 216, 23, 209, 53, 241, 136, 233, 79, 62, + 14, 133, 3, 216, 23, 209, 53, 241, 136, 233, 79, 251, 150, 14, 133, 3, + 243, 88, 209, 53, 241, 136, 209, 165, 14, 133, 3, 243, 88, 209, 53, 241, + 136, 209, 164, 14, 133, 3, 224, 195, 209, 53, 241, 136, 233, 93, 14, 133, + 3, 224, 195, 209, 53, 241, 136, 233, 92, 14, 133, 3, 224, 195, 209, 53, + 241, 136, 233, 91, 14, 133, 3, 224, 195, 209, 53, 241, 136, 233, 94, 62, + 14, 133, 3, 118, 251, 226, 212, 89, 14, 133, 3, 129, 251, 226, 212, 89, + 14, 133, 3, 241, 125, 251, 226, 212, 89, 14, 133, 3, 241, 204, 251, 226, + 212, 89, 14, 133, 3, 215, 10, 251, 226, 212, 89, 14, 133, 3, 119, 250, + 138, 14, 133, 3, 118, 250, 138, 14, 133, 3, 129, 250, 138, 14, 133, 3, + 241, 125, 250, 138, 14, 133, 3, 241, 125, 250, 139, 209, 53, 17, 14, 133, + 3, 241, 204, 250, 138, 14, 133, 3, 241, 204, 250, 139, 209, 53, 17, 14, + 133, 3, 224, 207, 14, 133, 3, 224, 208, 14, 133, 3, 119, 242, 210, 14, + 133, 3, 118, 242, 210, 14, 133, 3, 119, 212, 11, 245, 94, 14, 133, 3, + 118, 212, 8, 245, 94, 14, 133, 3, 241, 204, 214, 255, 245, 94, 14, 133, + 3, 119, 212, 11, 209, 53, 241, 136, 62, 14, 133, 3, 118, 212, 8, 209, 53, + 241, 136, 62, 14, 133, 3, 119, 243, 84, 251, 225, 14, 133, 3, 119, 219, + 205, 251, 225, 14, 133, 3, 44, 251, 212, 119, 215, 0, 14, 133, 3, 44, + 251, 212, 119, 219, 204, 14, 133, 3, 119, 219, 205, 239, 186, 14, 133, 3, + 119, 160, 239, 186, 14, 133, 3, 243, 66, 119, 212, 10, 14, 133, 3, 243, + 66, 118, 212, 7, 14, 133, 3, 243, 66, 241, 130, 14, 133, 3, 243, 66, 241, + 243, 14, 133, 3, 241, 125, 106, 209, 53, 17, 14, 133, 3, 241, 204, 106, + 209, 53, 17, 14, 133, 3, 215, 10, 106, 209, 53, 17, 14, 133, 3, 216, 23, + 106, 209, 53, 17, 14, 133, 3, 243, 88, 106, 209, 53, 17, 14, 133, 3, 224, + 195, 106, 209, 53, 17, 14, 220, 72, 3, 44, 251, 212, 206, 232, 245, 79, + 14, 220, 72, 3, 79, 247, 162, 14, 220, 72, 3, 245, 163, 247, 162, 14, + 220, 72, 3, 245, 163, 211, 47, 14, 220, 72, 3, 245, 163, 219, 210, 12, + 13, 254, 250, 12, 13, 254, 249, 12, 13, 254, 248, 12, 13, 254, 247, 12, + 13, 254, 246, 12, 13, 254, 245, 12, 13, 254, 244, 12, 13, 254, 243, 12, + 13, 254, 242, 12, 13, 254, 241, 12, 13, 254, 240, 12, 13, 254, 239, 12, + 13, 254, 238, 12, 13, 254, 237, 12, 13, 254, 236, 12, 13, 254, 235, 12, + 13, 254, 234, 12, 13, 254, 233, 12, 13, 254, 232, 12, 13, 254, 231, 12, + 13, 254, 230, 12, 13, 254, 229, 12, 13, 254, 228, 12, 13, 254, 227, 12, + 13, 254, 226, 12, 13, 254, 225, 12, 13, 254, 224, 12, 13, 254, 223, 12, + 13, 254, 222, 12, 13, 254, 221, 12, 13, 254, 220, 12, 13, 254, 219, 12, + 13, 254, 218, 12, 13, 254, 216, 12, 13, 254, 215, 12, 13, 254, 214, 12, + 13, 254, 213, 12, 13, 254, 212, 12, 13, 254, 211, 12, 13, 254, 210, 12, + 13, 254, 209, 12, 13, 254, 208, 12, 13, 254, 207, 12, 13, 254, 206, 12, + 13, 254, 205, 12, 13, 254, 204, 12, 13, 254, 203, 12, 13, 254, 202, 12, + 13, 254, 201, 12, 13, 254, 200, 12, 13, 254, 199, 12, 13, 254, 198, 12, + 13, 254, 197, 12, 13, 254, 196, 12, 13, 254, 195, 12, 13, 254, 194, 12, + 13, 254, 193, 12, 13, 254, 192, 12, 13, 254, 191, 12, 13, 254, 190, 12, + 13, 254, 189, 12, 13, 254, 188, 12, 13, 254, 187, 12, 13, 254, 186, 12, + 13, 254, 185, 12, 13, 254, 184, 12, 13, 254, 183, 12, 13, 254, 182, 12, + 13, 254, 181, 12, 13, 254, 180, 12, 13, 254, 179, 12, 13, 254, 178, 12, + 13, 254, 177, 12, 13, 254, 176, 12, 13, 254, 175, 12, 13, 254, 174, 12, + 13, 254, 173, 12, 13, 254, 172, 12, 13, 254, 171, 12, 13, 254, 170, 12, + 13, 251, 148, 12, 13, 251, 146, 12, 13, 251, 144, 12, 13, 251, 142, 12, + 13, 251, 140, 12, 13, 251, 139, 12, 13, 251, 137, 12, 13, 251, 135, 12, + 13, 251, 133, 12, 13, 251, 131, 12, 13, 249, 30, 12, 13, 249, 29, 12, 13, + 249, 28, 12, 13, 249, 27, 12, 13, 249, 26, 12, 13, 249, 25, 12, 13, 249, + 24, 12, 13, 249, 23, 12, 13, 249, 22, 12, 13, 249, 21, 12, 13, 249, 20, + 12, 13, 249, 19, 12, 13, 249, 18, 12, 13, 249, 17, 12, 13, 249, 16, 12, + 13, 249, 15, 12, 13, 249, 14, 12, 13, 249, 13, 12, 13, 249, 12, 12, 13, + 249, 11, 12, 13, 249, 10, 12, 13, 249, 9, 12, 13, 249, 8, 12, 13, 249, 7, + 12, 13, 249, 6, 12, 13, 249, 5, 12, 13, 249, 4, 12, 13, 249, 3, 12, 13, + 246, 239, 12, 13, 246, 238, 12, 13, 246, 237, 12, 13, 246, 236, 12, 13, + 246, 235, 12, 13, 246, 234, 12, 13, 246, 233, 12, 13, 246, 232, 12, 13, + 246, 231, 12, 13, 246, 230, 12, 13, 246, 229, 12, 13, 246, 228, 12, 13, + 246, 227, 12, 13, 246, 226, 12, 13, 246, 225, 12, 13, 246, 224, 12, 13, + 246, 223, 12, 13, 246, 222, 12, 13, 246, 221, 12, 13, 246, 220, 12, 13, + 246, 219, 12, 13, 246, 218, 12, 13, 246, 217, 12, 13, 246, 216, 12, 13, + 246, 215, 12, 13, 246, 214, 12, 13, 246, 213, 12, 13, 246, 212, 12, 13, + 246, 211, 12, 13, 246, 210, 12, 13, 246, 209, 12, 13, 246, 208, 12, 13, + 246, 207, 12, 13, 246, 206, 12, 13, 246, 205, 12, 13, 246, 204, 12, 13, + 246, 203, 12, 13, 246, 202, 12, 13, 246, 201, 12, 13, 246, 200, 12, 13, + 246, 199, 12, 13, 246, 198, 12, 13, 246, 197, 12, 13, 246, 196, 12, 13, + 246, 195, 12, 13, 246, 194, 12, 13, 246, 193, 12, 13, 246, 192, 12, 13, + 246, 191, 12, 13, 246, 190, 12, 13, 246, 189, 12, 13, 246, 188, 12, 13, + 246, 187, 12, 13, 246, 186, 12, 13, 246, 185, 12, 13, 246, 184, 12, 13, + 246, 183, 12, 13, 246, 182, 12, 13, 246, 181, 12, 13, 246, 180, 12, 13, + 246, 179, 12, 13, 246, 178, 12, 13, 246, 177, 12, 13, 246, 176, 12, 13, + 246, 175, 12, 13, 246, 174, 12, 13, 246, 173, 12, 13, 246, 172, 12, 13, + 246, 171, 12, 13, 246, 170, 12, 13, 246, 169, 12, 13, 246, 168, 12, 13, + 246, 167, 12, 13, 246, 166, 12, 13, 246, 165, 12, 13, 246, 164, 12, 13, + 246, 163, 12, 13, 246, 162, 12, 13, 246, 161, 12, 13, 246, 160, 12, 13, + 246, 159, 12, 13, 246, 158, 12, 13, 246, 157, 12, 13, 246, 156, 12, 13, + 246, 155, 12, 13, 246, 154, 12, 13, 246, 153, 12, 13, 246, 152, 12, 13, + 246, 151, 12, 13, 246, 150, 12, 13, 246, 149, 12, 13, 246, 148, 12, 13, + 243, 176, 12, 13, 243, 175, 12, 13, 243, 174, 12, 13, 243, 173, 12, 13, + 243, 172, 12, 13, 243, 171, 12, 13, 243, 170, 12, 13, 243, 169, 12, 13, + 243, 168, 12, 13, 243, 167, 12, 13, 243, 166, 12, 13, 243, 165, 12, 13, + 243, 164, 12, 13, 243, 163, 12, 13, 243, 162, 12, 13, 243, 161, 12, 13, + 243, 160, 12, 13, 243, 159, 12, 13, 243, 158, 12, 13, 243, 157, 12, 13, + 243, 156, 12, 13, 243, 155, 12, 13, 243, 154, 12, 13, 243, 153, 12, 13, + 243, 152, 12, 13, 243, 151, 12, 13, 243, 150, 12, 13, 243, 149, 12, 13, + 243, 148, 12, 13, 243, 147, 12, 13, 243, 146, 12, 13, 243, 145, 12, 13, + 243, 144, 12, 13, 243, 143, 12, 13, 243, 142, 12, 13, 243, 141, 12, 13, + 243, 140, 12, 13, 243, 139, 12, 13, 243, 138, 12, 13, 243, 137, 12, 13, + 243, 136, 12, 13, 243, 135, 12, 13, 243, 134, 12, 13, 243, 133, 12, 13, + 242, 138, 12, 13, 242, 137, 12, 13, 242, 136, 12, 13, 242, 135, 12, 13, + 242, 134, 12, 13, 242, 133, 12, 13, 242, 132, 12, 13, 242, 131, 12, 13, + 242, 130, 12, 13, 242, 129, 12, 13, 242, 128, 12, 13, 242, 127, 12, 13, + 242, 126, 12, 13, 242, 125, 12, 13, 242, 124, 12, 13, 242, 123, 12, 13, + 242, 122, 12, 13, 242, 121, 12, 13, 242, 120, 12, 13, 242, 119, 12, 13, + 242, 118, 12, 13, 242, 117, 12, 13, 242, 116, 12, 13, 242, 115, 12, 13, + 242, 114, 12, 13, 242, 113, 12, 13, 242, 112, 12, 13, 242, 111, 12, 13, + 242, 110, 12, 13, 242, 109, 12, 13, 242, 108, 12, 13, 242, 107, 12, 13, + 242, 106, 12, 13, 242, 105, 12, 13, 242, 104, 12, 13, 242, 103, 12, 13, + 242, 102, 12, 13, 242, 101, 12, 13, 242, 100, 12, 13, 242, 99, 12, 13, + 242, 98, 12, 13, 242, 97, 12, 13, 242, 96, 12, 13, 242, 95, 12, 13, 242, + 94, 12, 13, 242, 93, 12, 13, 242, 92, 12, 13, 242, 91, 12, 13, 242, 90, + 12, 13, 242, 89, 12, 13, 242, 88, 12, 13, 242, 87, 12, 13, 242, 86, 12, + 13, 242, 85, 12, 13, 242, 84, 12, 13, 242, 83, 12, 13, 242, 82, 12, 13, + 242, 81, 12, 13, 242, 80, 12, 13, 242, 79, 12, 13, 242, 78, 12, 13, 242, + 77, 12, 13, 242, 76, 12, 13, 242, 75, 12, 13, 242, 74, 12, 13, 241, 54, + 12, 13, 241, 53, 12, 13, 241, 52, 12, 13, 241, 51, 12, 13, 241, 50, 12, + 13, 241, 49, 12, 13, 241, 48, 12, 13, 241, 47, 12, 13, 241, 46, 12, 13, + 241, 45, 12, 13, 241, 44, 12, 13, 241, 43, 12, 13, 241, 42, 12, 13, 241, + 41, 12, 13, 241, 40, 12, 13, 241, 39, 12, 13, 241, 38, 12, 13, 241, 37, + 12, 13, 241, 36, 12, 13, 241, 35, 12, 13, 241, 34, 12, 13, 241, 33, 12, + 13, 241, 32, 12, 13, 241, 31, 12, 13, 241, 30, 12, 13, 241, 29, 12, 13, + 241, 28, 12, 13, 241, 27, 12, 13, 241, 26, 12, 13, 241, 25, 12, 13, 241, + 24, 12, 13, 241, 23, 12, 13, 241, 22, 12, 13, 241, 21, 12, 13, 241, 20, + 12, 13, 241, 19, 12, 13, 241, 18, 12, 13, 241, 17, 12, 13, 241, 16, 12, + 13, 241, 15, 12, 13, 241, 14, 12, 13, 241, 13, 12, 13, 241, 12, 12, 13, + 241, 11, 12, 13, 241, 10, 12, 13, 241, 9, 12, 13, 241, 8, 12, 13, 241, 7, + 12, 13, 241, 6, 12, 13, 241, 5, 12, 13, 241, 4, 12, 13, 241, 3, 12, 13, + 241, 2, 12, 13, 241, 1, 12, 13, 241, 0, 12, 13, 240, 255, 12, 13, 240, + 254, 12, 13, 240, 253, 12, 13, 240, 252, 12, 13, 240, 251, 12, 13, 240, + 250, 12, 13, 240, 249, 12, 13, 240, 248, 12, 13, 240, 247, 12, 13, 239, + 153, 12, 13, 239, 152, 12, 13, 239, 151, 12, 13, 239, 150, 12, 13, 239, + 149, 12, 13, 239, 148, 12, 13, 239, 147, 12, 13, 239, 146, 12, 13, 239, + 145, 12, 13, 237, 209, 12, 13, 237, 208, 12, 13, 237, 207, 12, 13, 237, + 206, 12, 13, 237, 205, 12, 13, 237, 204, 12, 13, 237, 203, 12, 13, 237, + 202, 12, 13, 237, 201, 12, 13, 237, 200, 12, 13, 237, 199, 12, 13, 237, + 198, 12, 13, 237, 197, 12, 13, 237, 196, 12, 13, 237, 195, 12, 13, 237, + 194, 12, 13, 237, 193, 12, 13, 237, 192, 12, 13, 237, 191, 12, 13, 232, + 75, 12, 13, 232, 74, 12, 13, 232, 73, 12, 13, 232, 72, 12, 13, 232, 71, + 12, 13, 232, 70, 12, 13, 232, 69, 12, 13, 232, 68, 12, 13, 230, 156, 12, + 13, 230, 155, 12, 13, 230, 154, 12, 13, 230, 153, 12, 13, 230, 152, 12, + 13, 230, 151, 12, 13, 230, 150, 12, 13, 230, 149, 12, 13, 230, 148, 12, + 13, 230, 147, 12, 13, 229, 26, 12, 13, 229, 25, 12, 13, 229, 24, 12, 13, + 229, 22, 12, 13, 229, 20, 12, 13, 229, 19, 12, 13, 229, 17, 12, 13, 229, + 15, 12, 13, 229, 13, 12, 13, 229, 11, 12, 13, 229, 9, 12, 13, 229, 7, 12, + 13, 229, 5, 12, 13, 229, 4, 12, 13, 229, 2, 12, 13, 229, 0, 12, 13, 228, + 255, 12, 13, 228, 254, 12, 13, 228, 253, 12, 13, 228, 252, 12, 13, 228, + 251, 12, 13, 228, 250, 12, 13, 228, 249, 12, 13, 228, 248, 12, 13, 228, + 246, 12, 13, 228, 244, 12, 13, 228, 242, 12, 13, 228, 241, 12, 13, 228, + 239, 12, 13, 228, 238, 12, 13, 228, 236, 12, 13, 228, 235, 12, 13, 228, + 233, 12, 13, 228, 231, 12, 13, 228, 229, 12, 13, 228, 227, 12, 13, 228, + 225, 12, 13, 228, 224, 12, 13, 228, 222, 12, 13, 228, 220, 12, 13, 228, + 219, 12, 13, 228, 217, 12, 13, 228, 215, 12, 13, 228, 213, 12, 13, 228, + 211, 12, 13, 228, 210, 12, 13, 228, 208, 12, 13, 228, 206, 12, 13, 228, + 204, 12, 13, 228, 203, 12, 13, 228, 201, 12, 13, 228, 199, 12, 13, 228, + 198, 12, 13, 228, 197, 12, 13, 228, 195, 12, 13, 228, 193, 12, 13, 228, + 191, 12, 13, 228, 189, 12, 13, 228, 187, 12, 13, 228, 185, 12, 13, 228, + 183, 12, 13, 228, 182, 12, 13, 228, 180, 12, 13, 228, 178, 12, 13, 228, + 176, 12, 13, 228, 174, 12, 13, 226, 30, 12, 13, 226, 29, 12, 13, 226, 28, + 12, 13, 226, 27, 12, 13, 226, 26, 12, 13, 226, 25, 12, 13, 226, 24, 12, + 13, 226, 23, 12, 13, 226, 22, 12, 13, 226, 21, 12, 13, 226, 20, 12, 13, + 226, 19, 12, 13, 226, 18, 12, 13, 226, 17, 12, 13, 226, 16, 12, 13, 226, + 15, 12, 13, 226, 14, 12, 13, 226, 13, 12, 13, 226, 12, 12, 13, 226, 11, + 12, 13, 226, 10, 12, 13, 226, 9, 12, 13, 226, 8, 12, 13, 226, 7, 12, 13, + 226, 6, 12, 13, 226, 5, 12, 13, 226, 4, 12, 13, 226, 3, 12, 13, 226, 2, + 12, 13, 226, 1, 12, 13, 226, 0, 12, 13, 225, 255, 12, 13, 225, 254, 12, + 13, 225, 253, 12, 13, 225, 252, 12, 13, 225, 251, 12, 13, 225, 250, 12, + 13, 225, 249, 12, 13, 225, 248, 12, 13, 225, 247, 12, 13, 225, 246, 12, + 13, 225, 245, 12, 13, 225, 244, 12, 13, 225, 243, 12, 13, 225, 242, 12, + 13, 225, 241, 12, 13, 225, 240, 12, 13, 225, 239, 12, 13, 225, 238, 12, + 13, 224, 128, 12, 13, 224, 127, 12, 13, 224, 126, 12, 13, 224, 125, 12, + 13, 224, 124, 12, 13, 224, 123, 12, 13, 224, 122, 12, 13, 224, 121, 12, + 13, 224, 120, 12, 13, 224, 119, 12, 13, 224, 118, 12, 13, 224, 117, 12, + 13, 224, 116, 12, 13, 224, 115, 12, 13, 224, 114, 12, 13, 224, 113, 12, + 13, 224, 112, 12, 13, 224, 111, 12, 13, 224, 110, 12, 13, 224, 109, 12, + 13, 224, 108, 12, 13, 224, 107, 12, 13, 223, 216, 12, 13, 223, 215, 12, + 13, 223, 214, 12, 13, 223, 213, 12, 13, 223, 212, 12, 13, 223, 211, 12, + 13, 223, 210, 12, 13, 223, 209, 12, 13, 223, 208, 12, 13, 223, 207, 12, + 13, 223, 206, 12, 13, 223, 205, 12, 13, 223, 204, 12, 13, 223, 203, 12, + 13, 223, 202, 12, 13, 223, 201, 12, 13, 223, 200, 12, 13, 223, 199, 12, + 13, 223, 198, 12, 13, 223, 197, 12, 13, 223, 196, 12, 13, 223, 195, 12, + 13, 223, 194, 12, 13, 223, 193, 12, 13, 223, 192, 12, 13, 223, 191, 12, + 13, 223, 50, 12, 13, 223, 49, 12, 13, 223, 48, 12, 13, 223, 47, 12, 13, + 223, 46, 12, 13, 223, 45, 12, 13, 223, 44, 12, 13, 223, 43, 12, 13, 223, + 42, 12, 13, 223, 41, 12, 13, 223, 40, 12, 13, 223, 39, 12, 13, 223, 38, + 12, 13, 223, 37, 12, 13, 223, 36, 12, 13, 223, 35, 12, 13, 223, 34, 12, + 13, 223, 33, 12, 13, 223, 32, 12, 13, 223, 31, 12, 13, 223, 30, 12, 13, + 223, 29, 12, 13, 223, 28, 12, 13, 223, 27, 12, 13, 223, 26, 12, 13, 223, + 25, 12, 13, 223, 24, 12, 13, 223, 23, 12, 13, 223, 22, 12, 13, 223, 21, + 12, 13, 223, 20, 12, 13, 223, 19, 12, 13, 223, 18, 12, 13, 223, 17, 12, + 13, 223, 16, 12, 13, 223, 15, 12, 13, 223, 14, 12, 13, 223, 13, 12, 13, + 223, 12, 12, 13, 223, 11, 12, 13, 223, 10, 12, 13, 223, 9, 12, 13, 223, + 8, 12, 13, 223, 7, 12, 13, 223, 6, 12, 13, 223, 5, 12, 13, 223, 4, 12, + 13, 223, 3, 12, 13, 223, 2, 12, 13, 223, 1, 12, 13, 223, 0, 12, 13, 222, + 255, 12, 13, 222, 254, 12, 13, 222, 253, 12, 13, 222, 252, 12, 13, 222, + 251, 12, 13, 222, 250, 12, 13, 222, 249, 12, 13, 222, 248, 12, 13, 222, + 247, 12, 13, 222, 246, 12, 13, 222, 245, 12, 13, 222, 244, 12, 13, 222, + 243, 12, 13, 222, 242, 12, 13, 222, 241, 12, 13, 222, 240, 12, 13, 222, + 239, 12, 13, 222, 238, 12, 13, 222, 237, 12, 13, 222, 236, 12, 13, 222, + 235, 12, 13, 222, 234, 12, 13, 222, 233, 12, 13, 222, 232, 12, 13, 222, + 66, 12, 13, 222, 65, 12, 13, 222, 64, 12, 13, 222, 63, 12, 13, 222, 62, + 12, 13, 222, 61, 12, 13, 222, 60, 12, 13, 222, 59, 12, 13, 222, 58, 12, + 13, 222, 57, 12, 13, 222, 56, 12, 13, 222, 55, 12, 13, 222, 54, 12, 13, + 220, 26, 12, 13, 220, 25, 12, 13, 220, 24, 12, 13, 220, 23, 12, 13, 220, + 22, 12, 13, 220, 21, 12, 13, 220, 20, 12, 13, 219, 148, 12, 13, 219, 147, + 12, 13, 219, 146, 12, 13, 219, 145, 12, 13, 219, 144, 12, 13, 219, 143, + 12, 13, 219, 142, 12, 13, 219, 141, 12, 13, 219, 140, 12, 13, 219, 139, + 12, 13, 219, 138, 12, 13, 219, 137, 12, 13, 219, 136, 12, 13, 219, 135, + 12, 13, 219, 134, 12, 13, 219, 133, 12, 13, 219, 132, 12, 13, 219, 131, + 12, 13, 219, 130, 12, 13, 219, 129, 12, 13, 219, 128, 12, 13, 219, 127, + 12, 13, 219, 126, 12, 13, 219, 125, 12, 13, 219, 124, 12, 13, 219, 123, + 12, 13, 219, 122, 12, 13, 219, 121, 12, 13, 219, 120, 12, 13, 219, 119, + 12, 13, 219, 118, 12, 13, 219, 117, 12, 13, 219, 116, 12, 13, 219, 115, + 12, 13, 217, 254, 12, 13, 217, 253, 12, 13, 217, 252, 12, 13, 217, 251, + 12, 13, 217, 250, 12, 13, 217, 249, 12, 13, 217, 248, 12, 13, 217, 247, + 12, 13, 217, 246, 12, 13, 217, 245, 12, 13, 217, 244, 12, 13, 217, 243, + 12, 13, 217, 242, 12, 13, 217, 241, 12, 13, 217, 240, 12, 13, 217, 239, + 12, 13, 217, 238, 12, 13, 217, 237, 12, 13, 217, 236, 12, 13, 217, 235, + 12, 13, 217, 234, 12, 13, 217, 233, 12, 13, 217, 232, 12, 13, 217, 231, + 12, 13, 217, 230, 12, 13, 217, 229, 12, 13, 217, 228, 12, 13, 217, 227, + 12, 13, 217, 226, 12, 13, 217, 225, 12, 13, 217, 224, 12, 13, 217, 223, + 12, 13, 217, 222, 12, 13, 217, 221, 12, 13, 217, 220, 12, 13, 217, 219, + 12, 13, 217, 218, 12, 13, 217, 217, 12, 13, 217, 216, 12, 13, 217, 215, + 12, 13, 217, 214, 12, 13, 217, 213, 12, 13, 217, 212, 12, 13, 217, 211, + 12, 13, 217, 210, 12, 13, 217, 209, 12, 13, 217, 208, 12, 13, 217, 207, + 12, 13, 217, 206, 12, 13, 217, 205, 12, 13, 217, 204, 12, 13, 217, 203, + 12, 13, 217, 202, 12, 13, 217, 201, 12, 13, 213, 8, 12, 13, 213, 7, 12, + 13, 213, 6, 12, 13, 213, 5, 12, 13, 213, 4, 12, 13, 213, 3, 12, 13, 213, + 2, 12, 13, 213, 1, 12, 13, 213, 0, 12, 13, 212, 255, 12, 13, 212, 254, + 12, 13, 212, 253, 12, 13, 212, 252, 12, 13, 212, 251, 12, 13, 212, 250, + 12, 13, 212, 249, 12, 13, 212, 248, 12, 13, 212, 247, 12, 13, 212, 246, + 12, 13, 212, 245, 12, 13, 212, 244, 12, 13, 212, 243, 12, 13, 212, 242, + 12, 13, 212, 241, 12, 13, 212, 240, 12, 13, 212, 239, 12, 13, 212, 238, + 12, 13, 212, 237, 12, 13, 212, 236, 12, 13, 212, 235, 12, 13, 212, 234, + 12, 13, 212, 233, 12, 13, 212, 232, 12, 13, 212, 231, 12, 13, 212, 230, + 12, 13, 212, 229, 12, 13, 212, 228, 12, 13, 212, 227, 12, 13, 212, 226, + 12, 13, 212, 225, 12, 13, 212, 224, 12, 13, 212, 223, 12, 13, 212, 222, + 12, 13, 212, 221, 12, 13, 210, 67, 12, 13, 210, 66, 12, 13, 210, 65, 12, + 13, 210, 64, 12, 13, 210, 63, 12, 13, 210, 62, 12, 13, 210, 61, 12, 13, + 210, 60, 12, 13, 210, 59, 12, 13, 210, 58, 12, 13, 210, 57, 12, 13, 210, + 56, 12, 13, 210, 55, 12, 13, 210, 54, 12, 13, 210, 53, 12, 13, 210, 52, + 12, 13, 210, 51, 12, 13, 210, 50, 12, 13, 210, 49, 12, 13, 210, 48, 12, + 13, 210, 47, 12, 13, 210, 46, 12, 13, 210, 45, 12, 13, 210, 44, 12, 13, + 210, 43, 12, 13, 210, 42, 12, 13, 210, 41, 12, 13, 210, 40, 12, 13, 210, + 39, 12, 13, 210, 38, 12, 13, 210, 37, 12, 13, 210, 36, 12, 13, 210, 35, + 12, 13, 210, 34, 12, 13, 210, 33, 12, 13, 210, 32, 12, 13, 210, 31, 12, + 13, 210, 30, 12, 13, 210, 29, 12, 13, 210, 28, 12, 13, 210, 27, 12, 13, + 210, 26, 12, 13, 210, 25, 12, 13, 210, 24, 12, 13, 210, 23, 12, 13, 210, + 22, 12, 13, 210, 21, 12, 13, 209, 147, 12, 13, 209, 146, 12, 13, 209, + 145, 12, 13, 209, 144, 12, 13, 209, 143, 12, 13, 209, 142, 12, 13, 209, + 141, 12, 13, 209, 140, 12, 13, 209, 139, 12, 13, 209, 138, 12, 13, 209, + 137, 12, 13, 209, 136, 12, 13, 209, 135, 12, 13, 209, 134, 12, 13, 209, + 133, 12, 13, 209, 132, 12, 13, 209, 131, 12, 13, 209, 130, 12, 13, 209, + 129, 12, 13, 209, 128, 12, 13, 209, 127, 12, 13, 209, 126, 12, 13, 209, + 125, 12, 13, 209, 124, 12, 13, 209, 123, 12, 13, 209, 122, 12, 13, 209, + 121, 12, 13, 209, 120, 12, 13, 209, 119, 12, 13, 209, 118, 12, 13, 209, + 117, 12, 13, 209, 116, 12, 13, 209, 115, 12, 13, 209, 114, 12, 13, 209, + 113, 12, 13, 209, 112, 12, 13, 209, 111, 12, 13, 209, 110, 12, 13, 209, + 109, 12, 13, 209, 108, 12, 13, 209, 107, 12, 13, 209, 106, 12, 13, 209, + 105, 12, 13, 209, 104, 12, 13, 209, 103, 12, 13, 209, 102, 12, 13, 209, + 101, 12, 13, 209, 100, 12, 13, 209, 99, 12, 13, 209, 98, 12, 13, 209, 97, + 12, 13, 209, 96, 12, 13, 209, 95, 12, 13, 209, 94, 12, 13, 209, 93, 12, + 13, 209, 92, 12, 13, 209, 91, 12, 13, 209, 90, 12, 13, 209, 89, 12, 13, + 209, 88, 12, 13, 209, 87, 12, 13, 209, 86, 12, 13, 209, 85, 12, 13, 209, + 84, 12, 13, 209, 83, 12, 13, 209, 82, 12, 13, 209, 81, 12, 13, 209, 80, + 12, 13, 209, 79, 12, 13, 209, 78, 12, 13, 209, 77, 12, 13, 209, 76, 12, + 13, 209, 75, 12, 13, 209, 74, 12, 13, 209, 73, 12, 13, 209, 72, 12, 13, + 209, 71, 12, 13, 207, 128, 12, 13, 207, 127, 12, 13, 207, 126, 12, 13, + 207, 125, 12, 13, 207, 124, 12, 13, 207, 123, 12, 13, 207, 122, 12, 13, + 207, 121, 12, 13, 207, 120, 12, 13, 207, 119, 12, 13, 207, 118, 12, 13, + 207, 117, 12, 13, 207, 116, 12, 13, 207, 115, 12, 13, 207, 114, 12, 13, + 207, 113, 12, 13, 207, 112, 12, 13, 207, 111, 12, 13, 207, 110, 12, 13, + 207, 109, 12, 13, 207, 108, 12, 13, 207, 107, 12, 13, 207, 106, 12, 13, + 207, 105, 12, 13, 207, 104, 12, 13, 207, 103, 12, 13, 207, 102, 12, 13, + 207, 101, 12, 13, 207, 100, 12, 13, 207, 99, 12, 13, 207, 98, 12, 13, + 207, 97, 12, 13, 206, 193, 12, 13, 206, 192, 12, 13, 206, 191, 12, 13, + 206, 190, 12, 13, 206, 189, 12, 13, 206, 188, 12, 13, 206, 187, 12, 13, + 206, 186, 12, 13, 206, 185, 12, 13, 206, 184, 12, 13, 206, 183, 12, 13, + 206, 182, 12, 13, 206, 121, 12, 13, 206, 120, 12, 13, 206, 119, 12, 13, + 206, 118, 12, 13, 206, 117, 12, 13, 206, 116, 12, 13, 206, 115, 12, 13, + 206, 114, 12, 13, 206, 113, 12, 13, 205, 158, 12, 13, 205, 157, 12, 13, + 205, 156, 12, 13, 205, 155, 12, 13, 205, 154, 12, 13, 205, 153, 12, 13, + 205, 152, 12, 13, 205, 151, 12, 13, 205, 150, 12, 13, 205, 149, 12, 13, + 205, 148, 12, 13, 205, 147, 12, 13, 205, 146, 12, 13, 205, 145, 12, 13, + 205, 144, 12, 13, 205, 143, 12, 13, 205, 142, 12, 13, 205, 141, 12, 13, + 205, 140, 12, 13, 205, 139, 12, 13, 205, 138, 12, 13, 205, 137, 12, 13, + 205, 136, 12, 13, 205, 135, 12, 13, 205, 134, 12, 13, 205, 133, 12, 13, + 205, 132, 12, 13, 205, 131, 12, 13, 205, 130, 12, 13, 205, 129, 12, 13, + 205, 128, 12, 13, 205, 127, 12, 13, 205, 126, 12, 13, 205, 125, 12, 13, + 205, 124, 12, 13, 205, 123, 12, 13, 205, 122, 12, 13, 205, 121, 12, 13, + 205, 120, 12, 13, 205, 119, 12, 13, 205, 118, 12, 13, 253, 163, 12, 13, + 253, 162, 12, 13, 253, 161, 12, 13, 253, 160, 12, 13, 253, 159, 12, 13, + 253, 158, 12, 13, 253, 157, 12, 13, 253, 156, 12, 13, 253, 155, 12, 13, + 253, 154, 12, 13, 253, 153, 12, 13, 253, 152, 12, 13, 253, 151, 12, 13, + 253, 150, 12, 13, 253, 149, 12, 13, 253, 148, 12, 13, 253, 147, 12, 13, + 253, 146, 12, 13, 253, 145, 12, 13, 253, 144, 12, 13, 253, 143, 12, 13, + 253, 142, 12, 13, 253, 141, 12, 13, 253, 140, 12, 13, 253, 139, 12, 13, + 253, 138, 12, 13, 253, 137, 12, 13, 253, 136, 12, 13, 253, 135, 12, 13, + 253, 134, 12, 13, 253, 133, 12, 13, 253, 132, 12, 13, 253, 131, 12, 13, + 253, 130, 21, 1, 187, 225, 10, 227, 40, 21, 1, 187, 240, 178, 241, 154, + 21, 1, 187, 220, 189, 227, 41, 221, 1, 21, 1, 187, 220, 189, 227, 41, + 221, 2, 21, 1, 187, 225, 233, 227, 40, 21, 1, 187, 215, 112, 21, 1, 187, + 211, 155, 227, 40, 21, 1, 187, 223, 92, 227, 40, 21, 1, 187, 215, 170, + 222, 52, 224, 164, 21, 1, 187, 220, 189, 222, 52, 224, 165, 221, 1, 21, + 1, 187, 220, 189, 222, 52, 224, 165, 221, 2, 21, 1, 187, 227, 255, 21, 1, + 187, 210, 171, 228, 0, 21, 1, 187, 225, 71, 21, 1, 187, 227, 252, 21, 1, + 187, 227, 210, 21, 1, 187, 226, 56, 21, 1, 187, 216, 25, 21, 1, 187, 223, + 224, 21, 1, 187, 231, 186, 21, 1, 187, 224, 132, 21, 1, 187, 213, 119, + 21, 1, 187, 225, 9, 21, 1, 187, 230, 88, 21, 1, 187, 230, 7, 230, 203, + 21, 1, 187, 223, 234, 227, 48, 21, 1, 187, 228, 3, 21, 1, 187, 221, 202, + 21, 1, 187, 240, 80, 21, 1, 187, 222, 9, 21, 1, 187, 226, 169, 225, 44, + 21, 1, 187, 223, 73, 227, 51, 21, 1, 187, 106, 205, 188, 225, 226, 21, 1, + 187, 240, 81, 21, 1, 187, 223, 234, 223, 235, 21, 1, 187, 215, 13, 21, 1, + 187, 227, 33, 21, 1, 187, 227, 54, 21, 1, 187, 226, 146, 21, 1, 187, 232, + 44, 21, 1, 187, 222, 52, 230, 47, 21, 1, 187, 225, 152, 230, 47, 21, 1, + 187, 221, 104, 21, 1, 187, 227, 253, 21, 1, 187, 224, 204, 21, 1, 187, + 220, 65, 21, 1, 187, 210, 168, 21, 1, 187, 229, 77, 21, 1, 187, 214, 175, + 21, 1, 187, 212, 65, 21, 1, 187, 227, 250, 21, 1, 187, 231, 193, 21, 1, + 187, 225, 148, 21, 1, 187, 230, 215, 21, 1, 187, 226, 147, 21, 1, 187, + 215, 108, 21, 1, 187, 229, 126, 21, 1, 187, 241, 216, 21, 1, 187, 218, + 110, 21, 1, 187, 231, 4, 21, 1, 187, 214, 171, 21, 1, 187, 227, 206, 221, + 43, 21, 1, 187, 215, 163, 21, 1, 187, 223, 233, 21, 1, 187, 215, 146, + 223, 244, 205, 196, 21, 1, 187, 223, 114, 226, 166, 21, 1, 187, 222, 47, + 21, 1, 187, 224, 134, 21, 1, 187, 209, 213, 21, 1, 187, 225, 47, 21, 1, + 187, 227, 249, 21, 1, 187, 224, 176, 21, 1, 187, 227, 148, 21, 1, 187, + 223, 128, 21, 1, 187, 212, 69, 21, 1, 187, 214, 168, 21, 1, 187, 222, 48, + 21, 1, 187, 223, 248, 21, 1, 187, 228, 1, 21, 1, 187, 223, 125, 21, 1, + 187, 232, 8, 21, 1, 187, 223, 251, 21, 1, 187, 209, 34, 21, 1, 187, 229, + 81, 21, 1, 187, 225, 101, 21, 1, 187, 225, 201, 21, 1, 187, 227, 147, 21, + 1, 221, 83, 223, 246, 21, 1, 221, 83, 210, 171, 227, 254, 21, 1, 221, 83, + 215, 71, 21, 1, 221, 83, 216, 29, 210, 170, 21, 1, 221, 83, 229, 128, + 223, 230, 21, 1, 221, 83, 227, 154, 228, 2, 21, 1, 221, 83, 231, 115, 21, + 1, 221, 83, 206, 18, 21, 1, 221, 83, 227, 149, 21, 1, 221, 83, 232, 30, + 21, 1, 221, 83, 221, 160, 21, 1, 221, 83, 206, 95, 230, 47, 21, 1, 221, + 83, 230, 107, 223, 244, 223, 139, 21, 1, 221, 83, 223, 227, 215, 189, 21, + 1, 221, 83, 225, 119, 224, 179, 21, 1, 221, 83, 240, 78, 21, 1, 221, 83, + 220, 247, 21, 1, 221, 83, 210, 171, 223, 242, 21, 1, 221, 83, 215, 194, + 224, 174, 21, 1, 221, 83, 215, 190, 21, 1, 221, 83, 227, 41, 212, 68, 21, + 1, 221, 83, 227, 136, 227, 150, 21, 1, 221, 83, 223, 126, 223, 230, 21, + 1, 221, 83, 231, 182, 21, 1, 221, 83, 240, 79, 21, 1, 221, 83, 231, 178, + 21, 1, 221, 83, 230, 135, 21, 1, 221, 83, 221, 205, 21, 1, 221, 83, 208, + 221, 21, 1, 221, 83, 225, 11, 226, 54, 21, 1, 221, 83, 225, 46, 227, 132, + 21, 1, 221, 83, 206, 214, 21, 1, 221, 83, 217, 175, 21, 1, 221, 83, 212, + 211, 21, 1, 221, 83, 227, 53, 21, 1, 221, 83, 225, 30, 21, 1, 221, 83, + 225, 31, 230, 85, 21, 1, 221, 83, 227, 43, 21, 1, 221, 83, 213, 170, 21, + 1, 221, 83, 227, 140, 21, 1, 221, 83, 226, 151, 21, 1, 221, 83, 223, 142, + 21, 1, 221, 83, 220, 69, 21, 1, 221, 83, 227, 52, 225, 48, 21, 1, 221, + 83, 241, 255, 21, 1, 221, 83, 227, 127, 21, 1, 221, 83, 242, 21, 21, 1, + 221, 83, 231, 190, 21, 1, 221, 83, 228, 20, 224, 168, 21, 1, 221, 83, + 228, 20, 224, 144, 21, 1, 221, 83, 230, 6, 21, 1, 221, 83, 225, 54, 21, + 1, 221, 83, 223, 253, 21, 1, 221, 83, 185, 21, 1, 221, 83, 231, 102, 21, + 1, 221, 83, 224, 255, 21, 1, 158, 225, 10, 228, 0, 21, 1, 158, 223, 91, + 21, 1, 158, 205, 196, 21, 1, 158, 207, 83, 21, 1, 158, 225, 47, 21, 1, + 158, 225, 140, 21, 1, 158, 225, 17, 21, 1, 158, 240, 88, 21, 1, 158, 227, + 144, 21, 1, 158, 240, 185, 21, 1, 158, 223, 116, 226, 190, 227, 55, 21, + 1, 158, 223, 222, 227, 135, 21, 1, 158, 227, 141, 21, 1, 158, 220, 253, + 21, 1, 158, 225, 125, 21, 1, 158, 227, 152, 248, 253, 21, 1, 158, 231, + 180, 21, 1, 158, 240, 89, 21, 1, 158, 231, 187, 21, 1, 158, 205, 214, + 226, 85, 21, 1, 158, 223, 85, 21, 1, 158, 227, 129, 21, 1, 158, 223, 252, + 21, 1, 158, 227, 135, 21, 1, 158, 206, 19, 21, 1, 158, 231, 12, 21, 1, + 158, 232, 63, 21, 1, 158, 216, 24, 21, 1, 158, 225, 134, 21, 1, 158, 212, + 209, 21, 1, 158, 224, 148, 21, 1, 158, 211, 155, 205, 199, 21, 1, 158, + 213, 198, 21, 1, 158, 225, 37, 223, 139, 21, 1, 158, 208, 220, 21, 1, + 158, 225, 204, 21, 1, 158, 228, 20, 231, 189, 21, 1, 158, 223, 235, 21, + 1, 158, 225, 32, 21, 1, 158, 230, 89, 21, 1, 158, 227, 137, 21, 1, 158, + 227, 32, 21, 1, 158, 223, 229, 21, 1, 158, 212, 64, 21, 1, 158, 225, 34, + 21, 1, 158, 241, 86, 21, 1, 158, 225, 139, 21, 1, 158, 223, 254, 21, 1, + 158, 223, 250, 21, 1, 158, 249, 77, 21, 1, 158, 208, 222, 21, 1, 158, + 227, 142, 21, 1, 158, 218, 50, 21, 1, 158, 224, 178, 21, 1, 158, 230, + 106, 21, 1, 158, 211, 153, 21, 1, 158, 223, 236, 224, 255, 21, 1, 158, + 224, 170, 21, 1, 158, 231, 193, 21, 1, 158, 225, 39, 21, 1, 158, 227, + 249, 21, 1, 158, 227, 130, 21, 1, 158, 229, 81, 21, 1, 158, 230, 203, 21, + 1, 158, 224, 176, 21, 1, 158, 224, 255, 21, 1, 158, 206, 204, 21, 1, 158, + 225, 35, 21, 1, 158, 223, 239, 21, 1, 158, 223, 231, 21, 1, 158, 230, + 217, 224, 134, 21, 1, 158, 223, 237, 21, 1, 158, 225, 147, 21, 1, 158, + 228, 20, 223, 242, 21, 1, 158, 206, 109, 21, 1, 158, 225, 146, 21, 1, + 158, 215, 111, 21, 1, 158, 216, 27, 21, 1, 158, 227, 138, 21, 1, 158, + 228, 0, 21, 1, 158, 227, 148, 21, 1, 158, 231, 181, 21, 1, 158, 227, 139, + 21, 1, 158, 231, 185, 21, 1, 158, 227, 152, 221, 48, 21, 1, 158, 205, + 179, 21, 1, 158, 224, 166, 21, 1, 158, 226, 243, 21, 1, 158, 226, 112, + 21, 1, 158, 215, 166, 21, 1, 158, 231, 204, 230, 70, 21, 1, 158, 231, + 204, 242, 34, 21, 1, 158, 225, 69, 21, 1, 158, 225, 201, 21, 1, 158, 229, + 190, 21, 1, 158, 221, 9, 21, 1, 158, 221, 150, 21, 1, 158, 212, 80, 21, + 1, 123, 227, 128, 21, 1, 123, 207, 81, 21, 1, 123, 224, 164, 21, 1, 123, + 227, 40, 21, 1, 123, 224, 162, 21, 1, 123, 229, 229, 21, 1, 123, 224, + 167, 21, 1, 123, 223, 249, 21, 1, 123, 225, 53, 21, 1, 123, 223, 139, 21, + 1, 123, 206, 215, 21, 1, 123, 225, 7, 21, 1, 123, 215, 212, 21, 1, 123, + 225, 18, 21, 1, 123, 231, 188, 21, 1, 123, 212, 66, 21, 1, 123, 215, 192, + 21, 1, 123, 224, 175, 21, 1, 123, 213, 170, 21, 1, 123, 231, 193, 21, 1, + 123, 206, 97, 21, 1, 123, 230, 218, 21, 1, 123, 217, 141, 21, 1, 123, + 227, 45, 21, 1, 123, 225, 138, 21, 1, 123, 227, 224, 21, 1, 123, 227, 51, + 21, 1, 123, 216, 26, 21, 1, 123, 206, 42, 21, 1, 123, 224, 169, 21, 1, + 123, 231, 184, 227, 131, 21, 1, 123, 225, 14, 21, 1, 123, 210, 170, 21, + 1, 123, 240, 98, 21, 1, 123, 225, 4, 21, 1, 123, 242, 0, 21, 1, 123, 225, + 142, 21, 1, 123, 227, 24, 21, 1, 123, 230, 0, 21, 1, 123, 225, 124, 21, + 1, 123, 226, 165, 21, 1, 123, 227, 28, 21, 1, 123, 220, 49, 21, 1, 123, + 227, 26, 21, 1, 123, 227, 42, 21, 1, 123, 229, 65, 21, 1, 123, 223, 241, + 21, 1, 123, 227, 151, 21, 1, 123, 230, 193, 21, 1, 123, 223, 128, 21, 1, + 123, 212, 69, 21, 1, 123, 214, 168, 21, 1, 123, 205, 179, 21, 1, 123, + 231, 185, 21, 1, 123, 219, 94, 21, 1, 123, 212, 119, 21, 1, 123, 225, 15, + 21, 1, 123, 227, 47, 21, 1, 123, 223, 240, 21, 1, 123, 231, 183, 21, 1, + 123, 221, 3, 21, 1, 123, 221, 98, 21, 1, 123, 223, 102, 21, 1, 123, 230, + 6, 21, 1, 123, 225, 54, 21, 1, 123, 227, 44, 21, 1, 123, 225, 27, 21, 1, + 123, 205, 193, 21, 1, 123, 221, 236, 21, 1, 123, 205, 192, 21, 1, 123, + 225, 147, 21, 1, 123, 223, 230, 21, 1, 123, 213, 200, 21, 1, 123, 230, + 222, 21, 1, 123, 225, 43, 21, 1, 123, 225, 12, 21, 1, 123, 210, 153, 21, + 1, 123, 227, 55, 21, 1, 123, 230, 212, 21, 1, 123, 223, 238, 21, 1, 123, + 212, 67, 21, 1, 123, 227, 251, 21, 1, 123, 225, 52, 21, 1, 123, 229, 255, + 21, 1, 123, 225, 33, 21, 1, 123, 223, 243, 21, 1, 123, 224, 148, 21, 1, + 123, 240, 82, 21, 1, 123, 230, 236, 21, 1, 123, 219, 3, 222, 179, 21, 1, + 123, 212, 200, 21, 1, 123, 211, 98, 21, 1, 123, 223, 125, 21, 1, 123, + 218, 154, 21, 1, 123, 230, 49, 21, 1, 123, 227, 106, 21, 1, 123, 229, 28, + 21, 1, 123, 213, 119, 21, 1, 123, 226, 114, 21, 1, 123, 215, 178, 21, 1, + 123, 215, 188, 21, 1, 123, 230, 165, 21, 1, 123, 223, 217, 21, 1, 123, + 215, 116, 21, 1, 123, 223, 232, 21, 1, 123, 221, 164, 21, 1, 123, 224, + 230, 21, 1, 123, 215, 145, 21, 1, 123, 220, 64, 21, 1, 123, 226, 54, 21, + 1, 123, 229, 107, 21, 1, 123, 219, 3, 226, 107, 21, 1, 123, 211, 211, 21, + 1, 123, 223, 219, 21, 1, 123, 227, 152, 195, 21, 1, 123, 217, 139, 21, 1, + 123, 242, 72, 21, 1, 88, 225, 146, 21, 1, 88, 211, 104, 21, 1, 88, 227, + 141, 21, 1, 88, 230, 89, 21, 1, 88, 208, 162, 21, 1, 88, 229, 113, 21, 1, + 88, 222, 51, 21, 1, 88, 214, 179, 21, 1, 88, 219, 69, 21, 1, 88, 223, + 245, 21, 1, 88, 225, 117, 21, 1, 88, 220, 79, 21, 1, 88, 212, 176, 21, 1, + 88, 225, 20, 21, 1, 88, 231, 8, 21, 1, 88, 206, 207, 21, 1, 88, 217, 74, + 21, 1, 88, 225, 44, 21, 1, 88, 222, 48, 21, 1, 88, 211, 105, 21, 1, 88, + 230, 216, 21, 1, 88, 229, 127, 21, 1, 88, 223, 248, 21, 1, 88, 224, 252, + 21, 1, 88, 228, 1, 21, 1, 88, 225, 13, 21, 1, 88, 224, 251, 21, 1, 88, + 223, 247, 21, 1, 88, 218, 152, 21, 1, 88, 224, 166, 21, 1, 88, 221, 162, + 21, 1, 88, 217, 196, 21, 1, 88, 225, 28, 21, 1, 88, 227, 34, 21, 1, 88, + 240, 76, 21, 1, 88, 225, 16, 21, 1, 88, 224, 177, 21, 1, 88, 227, 205, + 21, 1, 88, 229, 109, 21, 1, 88, 225, 49, 21, 1, 88, 225, 130, 21, 1, 88, + 212, 199, 223, 230, 21, 1, 88, 216, 28, 21, 1, 88, 220, 74, 21, 1, 88, + 225, 150, 214, 186, 21, 1, 88, 225, 36, 223, 139, 21, 1, 88, 206, 7, 21, + 1, 88, 240, 77, 21, 1, 88, 210, 169, 21, 1, 88, 206, 22, 21, 1, 88, 220, + 211, 21, 1, 88, 210, 158, 21, 1, 88, 231, 191, 21, 1, 88, 213, 199, 21, + 1, 88, 212, 68, 21, 1, 88, 208, 223, 21, 1, 88, 207, 33, 21, 1, 88, 230, + 138, 21, 1, 88, 220, 82, 21, 1, 88, 212, 210, 21, 1, 88, 240, 97, 21, 1, + 88, 225, 59, 21, 1, 88, 215, 191, 21, 1, 88, 227, 29, 21, 1, 88, 227, + 145, 21, 1, 88, 223, 89, 21, 1, 88, 224, 130, 21, 1, 88, 240, 181, 21, 1, + 88, 210, 159, 21, 1, 88, 230, 226, 21, 1, 88, 206, 73, 21, 1, 88, 223, + 126, 247, 208, 21, 1, 88, 205, 253, 21, 1, 88, 227, 46, 21, 1, 88, 225, + 135, 21, 1, 88, 221, 44, 21, 1, 88, 205, 198, 21, 1, 88, 230, 1, 21, 1, + 88, 241, 86, 21, 1, 88, 240, 180, 21, 1, 88, 225, 6, 21, 1, 88, 231, 193, + 21, 1, 88, 228, 4, 21, 1, 88, 225, 19, 21, 1, 88, 240, 83, 21, 1, 88, + 242, 73, 21, 1, 88, 223, 220, 21, 1, 88, 221, 99, 21, 1, 88, 206, 20, 21, + 1, 88, 225, 45, 21, 1, 88, 223, 126, 250, 5, 21, 1, 88, 223, 69, 21, 1, + 88, 220, 185, 21, 1, 88, 226, 243, 21, 1, 88, 241, 84, 21, 1, 88, 225, + 226, 21, 1, 88, 226, 112, 21, 1, 88, 240, 82, 21, 1, 88, 241, 89, 74, 21, + 1, 88, 226, 55, 21, 1, 88, 220, 78, 21, 1, 88, 225, 8, 21, 1, 88, 230, + 203, 21, 1, 88, 221, 41, 21, 1, 88, 223, 233, 21, 1, 88, 206, 21, 21, 1, + 88, 225, 29, 21, 1, 88, 222, 52, 221, 137, 21, 1, 88, 241, 89, 248, 236, + 21, 1, 88, 241, 155, 21, 1, 88, 224, 171, 21, 1, 88, 62, 21, 1, 88, 211, + 98, 21, 1, 88, 76, 21, 1, 88, 74, 21, 1, 88, 230, 87, 21, 1, 88, 222, 52, + 220, 219, 21, 1, 88, 212, 215, 21, 1, 88, 212, 163, 21, 1, 88, 225, 150, + 226, 42, 238, 54, 21, 1, 88, 215, 166, 21, 1, 88, 206, 17, 21, 1, 88, + 224, 245, 21, 1, 88, 205, 203, 21, 1, 88, 205, 230, 213, 99, 21, 1, 88, + 205, 230, 247, 77, 21, 1, 88, 205, 187, 21, 1, 88, 205, 195, 21, 1, 88, + 231, 179, 21, 1, 88, 221, 97, 21, 1, 88, 224, 172, 242, 246, 21, 1, 88, + 220, 75, 21, 1, 88, 206, 213, 21, 1, 88, 242, 21, 21, 1, 88, 209, 34, 21, + 1, 88, 229, 81, 21, 1, 88, 226, 254, 21, 1, 88, 218, 226, 21, 1, 88, 219, + 95, 21, 1, 88, 224, 244, 21, 1, 88, 225, 77, 21, 1, 88, 215, 158, 21, 1, + 88, 215, 145, 21, 1, 88, 241, 89, 219, 6, 21, 1, 88, 199, 21, 1, 88, 221, + 53, 21, 1, 88, 229, 107, 21, 1, 88, 231, 53, 21, 1, 88, 227, 83, 21, 1, + 88, 185, 21, 1, 88, 227, 202, 21, 1, 88, 212, 70, 21, 1, 88, 231, 123, + 21, 1, 88, 226, 168, 21, 1, 88, 212, 98, 21, 1, 88, 242, 43, 21, 1, 88, + 240, 70, 21, 1, 221, 82, 172, 21, 1, 221, 82, 71, 21, 1, 221, 82, 230, + 236, 21, 1, 221, 82, 243, 104, 21, 1, 221, 82, 219, 29, 21, 1, 221, 82, + 212, 200, 21, 1, 221, 82, 223, 125, 21, 1, 221, 82, 230, 141, 21, 1, 221, + 82, 218, 154, 21, 1, 221, 82, 218, 201, 21, 1, 221, 82, 227, 106, 21, 1, + 221, 82, 212, 215, 21, 1, 221, 82, 225, 149, 21, 1, 221, 82, 224, 178, + 21, 1, 221, 82, 229, 28, 21, 1, 221, 82, 213, 119, 21, 1, 221, 82, 215, + 178, 21, 1, 221, 82, 215, 80, 21, 1, 221, 82, 216, 24, 21, 1, 221, 82, + 230, 165, 21, 1, 221, 82, 231, 193, 21, 1, 221, 82, 223, 188, 21, 1, 221, + 82, 223, 217, 21, 1, 221, 82, 224, 149, 21, 1, 221, 82, 205, 229, 21, 1, + 221, 82, 215, 116, 21, 1, 221, 82, 190, 21, 1, 221, 82, 223, 251, 21, 1, + 221, 82, 221, 97, 21, 1, 221, 82, 223, 232, 21, 1, 221, 82, 206, 213, 21, + 1, 221, 82, 221, 164, 21, 1, 221, 82, 218, 50, 21, 1, 221, 82, 224, 230, + 21, 1, 221, 82, 218, 226, 21, 1, 221, 82, 231, 203, 21, 1, 221, 82, 225, + 5, 21, 1, 221, 82, 225, 56, 21, 1, 221, 82, 215, 158, 21, 1, 221, 82, + 220, 79, 21, 1, 221, 82, 241, 155, 21, 1, 221, 82, 207, 96, 21, 1, 221, + 82, 229, 235, 21, 1, 221, 82, 229, 107, 21, 1, 221, 82, 231, 53, 21, 1, + 221, 82, 227, 143, 21, 1, 221, 82, 219, 2, 21, 1, 221, 82, 185, 21, 1, + 221, 82, 226, 181, 21, 1, 221, 82, 227, 151, 21, 1, 221, 82, 212, 80, 21, + 1, 221, 82, 231, 15, 21, 1, 221, 82, 217, 159, 21, 1, 221, 82, 207, 147, + 226, 117, 1, 212, 219, 226, 117, 1, 225, 25, 226, 117, 1, 205, 247, 226, + 117, 1, 226, 211, 226, 117, 1, 250, 183, 226, 117, 1, 246, 145, 226, 117, + 1, 62, 226, 117, 1, 221, 78, 226, 117, 1, 231, 162, 226, 117, 1, 239, 98, + 226, 117, 1, 246, 121, 226, 117, 1, 248, 14, 226, 117, 1, 231, 223, 226, + 117, 1, 222, 180, 226, 117, 1, 228, 1, 226, 117, 1, 224, 199, 226, 117, + 1, 179, 226, 117, 1, 222, 152, 226, 117, 1, 76, 226, 117, 1, 218, 124, + 226, 117, 1, 215, 183, 226, 117, 1, 212, 40, 226, 117, 1, 243, 130, 226, + 117, 1, 207, 96, 226, 117, 1, 75, 226, 117, 1, 231, 53, 226, 117, 1, 230, + 95, 226, 117, 1, 230, 141, 226, 117, 1, 239, 131, 226, 117, 1, 218, 208, + 226, 117, 1, 212, 111, 226, 117, 18, 205, 85, 226, 117, 18, 102, 226, + 117, 18, 105, 226, 117, 18, 142, 226, 117, 18, 139, 226, 117, 18, 168, + 226, 117, 18, 184, 226, 117, 18, 195, 226, 117, 18, 193, 226, 117, 18, + 200, 226, 117, 246, 100, 226, 117, 50, 246, 100, 250, 110, 209, 67, 1, + 243, 24, 250, 110, 209, 67, 1, 172, 250, 110, 209, 67, 1, 217, 86, 250, + 110, 209, 67, 1, 242, 73, 250, 110, 209, 67, 1, 227, 146, 250, 110, 209, + 67, 1, 206, 8, 250, 110, 209, 67, 1, 240, 229, 250, 110, 209, 67, 1, 245, + 173, 250, 110, 209, 67, 1, 231, 14, 250, 110, 209, 67, 1, 232, 122, 250, + 110, 209, 67, 1, 238, 15, 250, 110, 209, 67, 1, 207, 96, 250, 110, 209, + 67, 1, 205, 19, 250, 110, 209, 67, 1, 240, 174, 250, 110, 209, 67, 1, + 245, 51, 250, 110, 209, 67, 1, 248, 148, 250, 110, 209, 67, 1, 209, 155, + 250, 110, 209, 67, 1, 124, 250, 110, 209, 67, 1, 250, 183, 250, 110, 209, + 67, 1, 207, 148, 250, 110, 209, 67, 1, 206, 46, 250, 110, 209, 67, 1, + 179, 250, 110, 209, 67, 1, 207, 93, 250, 110, 209, 67, 1, 62, 250, 110, + 209, 67, 1, 76, 250, 110, 209, 67, 1, 222, 152, 250, 110, 209, 67, 1, 71, + 250, 110, 209, 67, 1, 243, 104, 250, 110, 209, 67, 1, 75, 250, 110, 209, + 67, 1, 74, 250, 110, 209, 67, 36, 127, 211, 118, 250, 110, 209, 67, 36, + 114, 211, 118, 250, 110, 209, 67, 36, 226, 249, 211, 118, 250, 110, 209, + 67, 36, 229, 94, 211, 118, 250, 110, 209, 67, 36, 238, 250, 211, 118, + 250, 110, 209, 67, 241, 82, 213, 251, 112, 111, 22, 231, 220, 112, 111, + 22, 231, 216, 112, 111, 22, 231, 120, 112, 111, 22, 231, 88, 112, 111, + 22, 231, 241, 112, 111, 22, 231, 238, 112, 111, 22, 230, 227, 112, 111, + 22, 230, 200, 112, 111, 22, 231, 222, 112, 111, 22, 231, 177, 112, 111, + 22, 232, 40, 112, 111, 22, 232, 37, 112, 111, 22, 231, 32, 112, 111, 22, + 231, 29, 112, 111, 22, 231, 235, 112, 111, 22, 231, 233, 112, 111, 22, + 230, 229, 112, 111, 22, 230, 228, 112, 111, 22, 231, 50, 112, 111, 22, + 231, 18, 112, 111, 22, 231, 122, 112, 111, 22, 231, 121, 112, 111, 22, + 232, 55, 112, 111, 22, 231, 237, 112, 111, 22, 230, 191, 112, 111, 22, + 230, 182, 112, 111, 22, 232, 62, 112, 111, 22, 232, 56, 112, 111, 107, + 209, 45, 112, 111, 107, 223, 223, 112, 111, 107, 230, 75, 112, 111, 107, + 239, 80, 112, 111, 107, 224, 106, 112, 111, 107, 219, 60, 112, 111, 107, + 224, 133, 112, 111, 107, 219, 249, 112, 111, 107, 206, 61, 112, 111, 107, + 238, 234, 112, 111, 107, 227, 166, 112, 111, 107, 248, 86, 112, 111, 107, + 225, 154, 112, 111, 107, 238, 170, 112, 111, 107, 220, 227, 112, 111, + 107, 223, 228, 112, 111, 107, 225, 191, 112, 111, 107, 251, 184, 112, + 111, 107, 206, 177, 112, 111, 107, 248, 181, 112, 111, 141, 247, 239, + 210, 166, 112, 111, 141, 247, 239, 214, 193, 112, 111, 141, 247, 239, + 231, 195, 112, 111, 141, 247, 239, 231, 153, 112, 111, 141, 247, 239, + 213, 197, 112, 111, 141, 247, 239, 238, 137, 112, 111, 141, 247, 239, + 212, 150, 112, 111, 3, 208, 158, 211, 250, 112, 111, 3, 208, 158, 210, + 232, 248, 139, 112, 111, 3, 247, 239, 248, 77, 112, 111, 3, 208, 158, + 212, 18, 112, 111, 3, 208, 158, 242, 18, 112, 111, 3, 206, 135, 223, 218, + 112, 111, 3, 206, 135, 218, 210, 112, 111, 3, 206, 135, 211, 87, 112, + 111, 3, 206, 135, 242, 55, 112, 111, 3, 208, 158, 217, 68, 112, 111, 3, + 227, 105, 213, 201, 112, 111, 3, 208, 158, 224, 11, 112, 111, 3, 237, + 186, 206, 80, 112, 111, 3, 206, 176, 112, 111, 3, 247, 239, 210, 219, + 218, 114, 112, 111, 18, 205, 85, 112, 111, 18, 102, 112, 111, 18, 105, + 112, 111, 18, 142, 112, 111, 18, 139, 112, 111, 18, 168, 112, 111, 18, + 184, 112, 111, 18, 195, 112, 111, 18, 193, 112, 111, 18, 200, 112, 111, + 43, 212, 93, 112, 111, 43, 238, 28, 112, 111, 43, 212, 99, 211, 240, 112, + 111, 43, 226, 212, 112, 111, 43, 238, 30, 226, 212, 112, 111, 43, 212, + 99, 249, 226, 112, 111, 43, 211, 38, 112, 111, 3, 208, 158, 229, 76, 112, + 111, 3, 206, 132, 112, 111, 3, 238, 229, 112, 111, 3, 212, 9, 238, 229, + 112, 111, 3, 204, 250, 212, 51, 112, 111, 3, 238, 154, 112, 111, 3, 224, + 25, 112, 111, 3, 206, 168, 112, 111, 3, 223, 221, 112, 111, 3, 251, 168, + 112, 111, 3, 210, 103, 248, 138, 112, 111, 3, 227, 105, 210, 235, 112, + 111, 3, 212, 151, 112, 111, 3, 229, 104, 112, 111, 3, 226, 71, 112, 111, + 3, 247, 239, 239, 127, 229, 55, 223, 226, 223, 225, 112, 111, 3, 247, + 239, 247, 39, 210, 226, 112, 111, 3, 247, 239, 210, 101, 112, 111, 3, + 247, 239, 210, 102, 248, 2, 112, 111, 3, 247, 239, 220, 77, 246, 69, 112, + 111, 3, 247, 239, 224, 18, 211, 92, 112, 111, 247, 215, 3, 210, 230, 112, + 111, 247, 215, 3, 206, 48, 112, 111, 247, 215, 3, 229, 187, 112, 111, + 247, 215, 3, 230, 74, 112, 111, 247, 215, 3, 206, 131, 112, 111, 247, + 215, 3, 231, 33, 112, 111, 247, 215, 3, 239, 77, 112, 111, 247, 215, 3, + 226, 110, 112, 111, 247, 215, 3, 211, 251, 112, 111, 247, 215, 3, 210, + 240, 112, 111, 247, 215, 3, 221, 90, 112, 111, 247, 215, 3, 231, 165, + 112, 111, 247, 215, 3, 239, 117, 112, 111, 247, 215, 3, 209, 64, 112, + 111, 247, 215, 3, 242, 52, 112, 111, 247, 215, 3, 206, 87, 112, 111, 247, + 215, 3, 210, 213, 112, 111, 247, 215, 3, 230, 186, 112, 111, 247, 215, 3, + 207, 138, 104, 1, 179, 104, 1, 250, 183, 104, 1, 9, 179, 104, 1, 220, + 240, 104, 1, 185, 104, 1, 227, 1, 104, 1, 252, 19, 185, 104, 1, 242, 73, + 104, 1, 209, 70, 104, 1, 208, 215, 104, 1, 212, 219, 104, 1, 246, 145, + 104, 1, 9, 210, 208, 104, 1, 9, 212, 219, 104, 1, 210, 208, 104, 1, 246, + 54, 104, 1, 199, 104, 1, 224, 234, 104, 1, 9, 224, 103, 104, 1, 252, 19, + 199, 104, 1, 224, 103, 104, 1, 224, 89, 104, 1, 230, 141, 104, 1, 229, + 41, 104, 1, 229, 248, 104, 1, 229, 237, 104, 1, 211, 144, 104, 1, 245, + 59, 104, 1, 211, 136, 104, 1, 245, 58, 104, 1, 172, 104, 1, 240, 244, + 104, 1, 9, 172, 104, 1, 220, 19, 104, 1, 219, 252, 104, 1, 225, 77, 104, + 1, 225, 26, 104, 1, 252, 19, 225, 77, 104, 1, 155, 104, 1, 206, 181, 104, + 1, 240, 99, 104, 1, 240, 74, 104, 1, 210, 218, 104, 1, 243, 180, 104, 1, + 223, 144, 104, 1, 223, 127, 104, 1, 210, 233, 104, 1, 243, 190, 104, 1, + 9, 210, 233, 104, 1, 9, 243, 190, 104, 1, 219, 27, 210, 233, 104, 1, 216, + 2, 104, 1, 214, 96, 104, 1, 205, 81, 104, 1, 205, 10, 104, 1, 210, 243, + 104, 1, 243, 196, 104, 1, 9, 210, 243, 104, 1, 217, 199, 104, 1, 205, + 116, 104, 1, 205, 11, 104, 1, 204, 238, 104, 1, 204, 218, 104, 1, 252, + 19, 204, 238, 104, 1, 204, 210, 104, 1, 204, 217, 104, 1, 207, 96, 104, + 1, 252, 213, 104, 1, 239, 20, 104, 1, 225, 196, 104, 3, 251, 215, 104, 3, + 219, 27, 208, 168, 104, 3, 219, 27, 251, 215, 104, 22, 3, 62, 104, 22, 3, + 253, 164, 104, 22, 3, 252, 209, 104, 22, 3, 252, 122, 104, 22, 3, 252, + 114, 104, 22, 3, 76, 104, 22, 3, 222, 152, 104, 22, 3, 206, 250, 104, 22, + 3, 207, 129, 104, 22, 3, 75, 104, 22, 3, 243, 41, 104, 22, 3, 243, 28, + 104, 22, 3, 222, 204, 104, 22, 3, 74, 104, 22, 3, 237, 190, 104, 22, 3, + 237, 189, 104, 22, 3, 237, 188, 104, 22, 3, 232, 253, 104, 22, 3, 233, + 129, 104, 22, 3, 233, 102, 104, 22, 3, 232, 216, 104, 22, 3, 233, 42, + 104, 22, 3, 71, 104, 22, 3, 210, 18, 104, 22, 3, 210, 17, 104, 22, 3, + 210, 16, 104, 22, 3, 209, 162, 104, 22, 3, 210, 0, 104, 22, 3, 209, 221, + 104, 22, 3, 206, 123, 104, 22, 3, 206, 11, 104, 22, 3, 252, 248, 104, 22, + 3, 252, 244, 104, 22, 3, 242, 229, 104, 22, 3, 218, 93, 242, 229, 104, + 22, 3, 242, 235, 104, 22, 3, 218, 93, 242, 235, 104, 22, 3, 252, 205, + 104, 22, 3, 243, 90, 104, 22, 3, 251, 184, 104, 22, 3, 222, 97, 104, 22, + 3, 226, 33, 104, 22, 3, 225, 79, 104, 135, 218, 167, 104, 135, 211, 102, + 218, 167, 104, 135, 52, 104, 135, 55, 104, 1, 211, 116, 104, 1, 211, 115, + 104, 1, 211, 114, 104, 1, 211, 113, 104, 1, 211, 112, 104, 1, 211, 111, + 104, 1, 211, 110, 104, 1, 219, 27, 211, 117, 104, 1, 219, 27, 211, 116, + 104, 1, 219, 27, 211, 114, 104, 1, 219, 27, 211, 113, 104, 1, 219, 27, + 211, 112, 104, 1, 219, 27, 211, 110, 64, 1, 252, 19, 75, 161, 1, 252, 19, + 206, 52, 95, 1, 239, 155, 95, 1, 206, 195, 95, 1, 222, 67, 95, 1, 213, + 10, 95, 1, 242, 139, 95, 1, 232, 76, 95, 1, 149, 95, 1, 251, 150, 95, 1, + 246, 240, 95, 1, 209, 148, 95, 1, 241, 55, 95, 1, 137, 95, 1, 222, 68, + 226, 33, 95, 1, 246, 241, 182, 95, 1, 242, 140, 226, 33, 95, 1, 232, 77, + 229, 28, 95, 1, 219, 150, 182, 95, 1, 212, 58, 95, 1, 214, 223, 245, 193, + 95, 1, 245, 193, 95, 1, 231, 73, 95, 1, 214, 223, 232, 203, 95, 1, 238, + 238, 95, 1, 229, 249, 95, 1, 218, 213, 95, 1, 229, 28, 95, 1, 226, 33, + 95, 1, 232, 203, 95, 1, 182, 95, 1, 229, 29, 226, 33, 95, 1, 226, 34, + 229, 28, 95, 1, 232, 204, 229, 28, 95, 1, 218, 1, 232, 203, 95, 1, 229, + 29, 2, 245, 23, 95, 1, 226, 34, 2, 245, 23, 95, 1, 232, 204, 2, 245, 23, + 95, 1, 232, 204, 2, 177, 233, 26, 23, 52, 95, 1, 218, 1, 2, 245, 23, 95, + 1, 218, 1, 2, 67, 55, 95, 1, 229, 29, 182, 95, 1, 226, 34, 182, 95, 1, + 232, 204, 182, 95, 1, 218, 1, 182, 95, 1, 229, 29, 226, 34, 182, 95, 1, + 226, 34, 229, 29, 182, 95, 1, 232, 204, 229, 29, 182, 95, 1, 218, 1, 232, + 204, 182, 95, 1, 232, 204, 218, 1, 2, 245, 23, 95, 1, 232, 204, 226, 33, + 95, 1, 232, 204, 226, 34, 182, 95, 1, 218, 1, 213, 10, 95, 1, 218, 1, + 213, 11, 137, 95, 1, 218, 1, 222, 67, 95, 1, 218, 1, 222, 68, 137, 95, 1, + 213, 11, 182, 95, 1, 213, 11, 219, 150, 182, 95, 1, 207, 129, 95, 1, 207, + 30, 95, 1, 207, 130, 137, 95, 1, 218, 1, 226, 33, 95, 1, 218, 1, 229, 28, + 95, 1, 232, 77, 219, 150, 182, 95, 1, 241, 56, 219, 150, 182, 95, 1, 218, + 1, 232, 76, 95, 1, 218, 1, 232, 77, 137, 95, 1, 62, 95, 1, 214, 223, 222, + 78, 95, 1, 222, 230, 95, 1, 76, 95, 1, 252, 69, 95, 1, 74, 95, 1, 75, 95, + 1, 233, 129, 95, 1, 215, 144, 74, 95, 1, 209, 252, 95, 1, 243, 104, 95, + 1, 214, 223, 243, 92, 95, 1, 218, 108, 74, 95, 1, 214, 223, 243, 104, 95, + 1, 152, 74, 95, 1, 206, 52, 95, 1, 71, 95, 1, 242, 192, 95, 1, 206, 146, + 95, 1, 106, 226, 33, 95, 1, 152, 71, 95, 1, 218, 108, 71, 95, 1, 209, + 253, 95, 1, 214, 223, 71, 95, 1, 222, 149, 95, 1, 222, 78, 95, 1, 222, + 97, 95, 1, 207, 96, 95, 1, 206, 250, 95, 1, 207, 20, 95, 1, 207, 43, 95, + 1, 206, 225, 95, 1, 225, 198, 71, 95, 1, 225, 198, 76, 95, 1, 225, 198, + 74, 95, 1, 225, 198, 62, 95, 1, 221, 120, 252, 122, 95, 1, 221, 120, 252, + 136, 95, 1, 214, 223, 243, 41, 95, 1, 214, 223, 252, 122, 95, 1, 214, + 223, 222, 165, 95, 1, 115, 229, 28, 95, 252, 227, 47, 194, 217, 81, 95, + 252, 227, 226, 249, 194, 217, 81, 95, 252, 227, 48, 194, 217, 81, 95, + 252, 227, 114, 79, 217, 81, 95, 252, 227, 226, 249, 79, 217, 81, 95, 252, + 227, 127, 79, 217, 81, 95, 252, 227, 251, 190, 217, 81, 95, 252, 227, + 251, 190, 230, 37, 217, 81, 95, 252, 227, 251, 190, 212, 170, 95, 252, + 227, 251, 190, 212, 191, 95, 252, 227, 251, 190, 174, 109, 95, 252, 227, + 251, 190, 237, 225, 109, 95, 252, 227, 251, 190, 212, 171, 109, 95, 252, + 227, 127, 153, 95, 252, 227, 127, 211, 197, 153, 95, 252, 227, 127, 239, + 236, 95, 252, 227, 127, 152, 239, 236, 95, 252, 227, 127, 245, 23, 95, + 252, 227, 127, 247, 233, 95, 252, 227, 127, 229, 205, 95, 252, 227, 127, + 207, 64, 95, 252, 227, 127, 209, 22, 95, 252, 227, 114, 153, 95, 252, + 227, 114, 211, 197, 153, 95, 252, 227, 114, 239, 236, 95, 252, 227, 114, + 152, 239, 236, 95, 252, 227, 114, 245, 23, 95, 252, 227, 114, 247, 233, + 95, 252, 227, 114, 229, 205, 95, 252, 227, 114, 207, 64, 95, 252, 227, + 114, 209, 22, 95, 252, 227, 114, 45, 95, 3, 148, 2, 247, 59, 95, 212, 17, + 1, 217, 59, 95, 50, 83, 95, 220, 72, 248, 42, 241, 82, 213, 251, 215, + 131, 241, 135, 1, 222, 84, 215, 131, 241, 135, 247, 115, 222, 84, 215, + 131, 241, 135, 130, 214, 7, 215, 131, 241, 135, 120, 214, 7, 58, 30, 16, + 220, 86, 58, 30, 16, 246, 80, 58, 30, 16, 221, 124, 58, 30, 16, 222, 75, + 243, 72, 58, 30, 16, 222, 75, 245, 108, 58, 30, 16, 209, 57, 243, 72, 58, + 30, 16, 209, 57, 245, 108, 58, 30, 16, 231, 244, 58, 30, 16, 213, 27, 58, + 30, 16, 221, 223, 58, 30, 16, 205, 219, 58, 30, 16, 205, 220, 245, 108, + 58, 30, 16, 230, 253, 58, 30, 16, 252, 64, 243, 72, 58, 30, 16, 242, 163, + 243, 72, 58, 30, 16, 212, 109, 58, 30, 16, 231, 199, 58, 30, 16, 252, 54, + 58, 30, 16, 252, 55, 245, 108, 58, 30, 16, 213, 34, 58, 30, 16, 212, 0, + 58, 30, 16, 222, 176, 252, 17, 58, 30, 16, 240, 3, 252, 17, 58, 30, 16, + 220, 85, 58, 30, 16, 248, 102, 58, 30, 16, 209, 46, 58, 30, 16, 232, 225, + 252, 17, 58, 30, 16, 231, 201, 252, 17, 58, 30, 16, 231, 200, 252, 17, + 58, 30, 16, 217, 118, 58, 30, 16, 221, 213, 58, 30, 16, 214, 16, 252, 57, + 58, 30, 16, 222, 74, 252, 17, 58, 30, 16, 209, 56, 252, 17, 58, 30, 16, + 252, 58, 252, 17, 58, 30, 16, 252, 52, 58, 30, 16, 231, 63, 58, 30, 16, + 218, 220, 58, 30, 16, 221, 51, 252, 17, 58, 30, 16, 211, 173, 58, 30, 16, + 252, 120, 58, 30, 16, 217, 62, 58, 30, 16, 213, 37, 252, 17, 58, 30, 16, + 213, 37, 227, 64, 214, 14, 58, 30, 16, 222, 69, 252, 17, 58, 30, 16, 212, + 35, 58, 30, 16, 230, 24, 58, 30, 16, 243, 199, 58, 30, 16, 211, 53, 58, + 30, 16, 212, 82, 58, 30, 16, 231, 0, 58, 30, 16, 252, 64, 242, 163, 225, + 97, 58, 30, 16, 241, 90, 252, 17, 58, 30, 16, 233, 81, 58, 30, 16, 211, + 24, 252, 17, 58, 30, 16, 231, 247, 211, 23, 58, 30, 16, 221, 152, 58, 30, + 16, 220, 90, 58, 30, 16, 231, 34, 58, 30, 16, 248, 26, 252, 17, 58, 30, + 16, 219, 70, 58, 30, 16, 221, 226, 252, 17, 58, 30, 16, 221, 224, 252, + 17, 58, 30, 16, 237, 179, 58, 30, 16, 225, 208, 58, 30, 16, 221, 102, 58, + 30, 16, 231, 35, 252, 151, 58, 30, 16, 211, 24, 252, 151, 58, 30, 16, + 213, 245, 58, 30, 16, 239, 223, 58, 30, 16, 232, 225, 225, 97, 58, 30, + 16, 222, 176, 225, 97, 58, 30, 16, 222, 75, 225, 97, 58, 30, 16, 221, + 101, 58, 30, 16, 231, 19, 58, 30, 16, 221, 100, 58, 30, 16, 230, 255, 58, + 30, 16, 221, 153, 225, 97, 58, 30, 16, 231, 200, 225, 98, 252, 95, 58, + 30, 16, 231, 201, 225, 98, 252, 95, 58, 30, 16, 205, 217, 58, 30, 16, + 252, 55, 225, 97, 58, 30, 16, 252, 56, 213, 35, 225, 97, 58, 30, 16, 205, + 218, 58, 30, 16, 230, 254, 58, 30, 16, 243, 67, 58, 30, 16, 248, 103, 58, + 30, 16, 226, 221, 232, 224, 58, 30, 16, 209, 57, 225, 97, 58, 30, 16, + 221, 51, 225, 97, 58, 30, 16, 220, 91, 225, 97, 58, 30, 16, 222, 172, 58, + 30, 16, 252, 82, 58, 30, 16, 229, 38, 58, 30, 16, 221, 224, 225, 97, 58, + 30, 16, 221, 226, 225, 97, 58, 30, 16, 242, 197, 221, 225, 58, 30, 16, + 230, 163, 58, 30, 16, 252, 83, 58, 30, 16, 211, 24, 225, 97, 58, 30, 16, + 243, 70, 58, 30, 16, 213, 37, 225, 97, 58, 30, 16, 213, 28, 58, 30, 16, + 248, 26, 225, 97, 58, 30, 16, 242, 250, 58, 30, 16, 217, 63, 225, 97, 58, + 30, 16, 206, 162, 231, 63, 58, 30, 16, 211, 21, 58, 30, 16, 220, 92, 58, + 30, 16, 211, 25, 58, 30, 16, 211, 22, 58, 30, 16, 220, 89, 58, 30, 16, + 211, 20, 58, 30, 16, 220, 88, 58, 30, 16, 240, 2, 58, 30, 16, 252, 9, 58, + 30, 16, 242, 197, 252, 9, 58, 30, 16, 222, 69, 225, 97, 58, 30, 16, 212, + 34, 242, 209, 58, 30, 16, 212, 34, 242, 162, 58, 30, 16, 212, 36, 252, + 59, 58, 30, 16, 212, 28, 232, 42, 252, 51, 58, 30, 16, 231, 246, 58, 30, + 16, 243, 30, 58, 30, 16, 206, 14, 231, 243, 58, 30, 16, 206, 14, 252, 95, + 58, 30, 16, 214, 15, 58, 30, 16, 231, 64, 252, 95, 58, 30, 16, 245, 109, + 252, 17, 58, 30, 16, 231, 1, 252, 17, 58, 30, 16, 231, 1, 252, 151, 58, + 30, 16, 231, 1, 225, 97, 58, 30, 16, 252, 58, 225, 97, 58, 30, 16, 252, + 60, 58, 30, 16, 245, 108, 58, 30, 16, 211, 35, 58, 30, 16, 212, 73, 58, + 30, 16, 231, 23, 58, 30, 16, 230, 29, 243, 23, 248, 16, 58, 30, 16, 230, + 29, 243, 200, 248, 17, 58, 30, 16, 230, 29, 211, 37, 248, 17, 58, 30, 16, + 230, 29, 212, 84, 248, 17, 58, 30, 16, 230, 29, 233, 76, 248, 16, 58, 30, + 16, 240, 3, 225, 98, 252, 95, 58, 30, 16, 240, 3, 221, 214, 252, 5, 58, + 30, 16, 240, 3, 221, 214, 245, 197, 58, 30, 16, 245, 132, 58, 30, 16, + 245, 133, 221, 214, 252, 6, 231, 243, 58, 30, 16, 245, 133, 221, 214, + 252, 6, 252, 95, 58, 30, 16, 245, 133, 221, 214, 245, 197, 58, 30, 16, + 211, 42, 58, 30, 16, 252, 10, 58, 30, 16, 233, 83, 58, 30, 16, 245, 154, + 58, 30, 16, 252, 215, 220, 194, 252, 11, 58, 30, 16, 252, 215, 252, 8, + 58, 30, 16, 252, 215, 252, 11, 58, 30, 16, 252, 215, 227, 58, 58, 30, 16, + 252, 215, 227, 69, 58, 30, 16, 252, 215, 240, 4, 58, 30, 16, 252, 215, + 240, 1, 58, 30, 16, 252, 215, 220, 194, 240, 4, 58, 30, 16, 227, 183, + 220, 98, 237, 177, 58, 30, 16, 227, 183, 252, 153, 220, 98, 237, 177, 58, + 30, 16, 227, 183, 245, 196, 237, 177, 58, 30, 16, 227, 183, 252, 153, + 245, 196, 237, 177, 58, 30, 16, 227, 183, 211, 30, 237, 177, 58, 30, 16, + 227, 183, 211, 43, 58, 30, 16, 227, 183, 212, 78, 237, 177, 58, 30, 16, + 227, 183, 212, 78, 230, 33, 237, 177, 58, 30, 16, 227, 183, 230, 33, 237, + 177, 58, 30, 16, 227, 183, 220, 237, 237, 177, 58, 30, 16, 232, 232, 212, + 102, 237, 178, 58, 30, 16, 252, 56, 212, 102, 237, 178, 58, 30, 16, 242, + 46, 212, 75, 58, 30, 16, 242, 46, 226, 161, 58, 30, 16, 242, 46, 245, + 137, 58, 30, 16, 227, 183, 209, 50, 237, 177, 58, 30, 16, 227, 183, 220, + 97, 237, 177, 58, 30, 16, 227, 183, 220, 237, 212, 78, 237, 177, 58, 30, + 16, 239, 255, 226, 34, 252, 59, 58, 30, 16, 239, 255, 226, 34, 245, 107, + 58, 30, 16, 243, 39, 232, 42, 241, 90, 208, 156, 58, 30, 16, 233, 82, 58, + 30, 16, 233, 80, 58, 30, 16, 241, 90, 252, 18, 245, 195, 237, 176, 58, + 30, 16, 241, 90, 245, 152, 179, 58, 30, 16, 241, 90, 245, 152, 225, 208, + 58, 30, 16, 241, 90, 225, 203, 237, 177, 58, 30, 16, 241, 90, 245, 152, + 245, 168, 58, 30, 16, 241, 90, 214, 242, 245, 151, 245, 168, 58, 30, 16, + 241, 90, 245, 152, 231, 224, 58, 30, 16, 241, 90, 245, 152, 205, 19, 58, + 30, 16, 241, 90, 245, 152, 224, 231, 231, 243, 58, 30, 16, 241, 90, 245, + 152, 224, 231, 252, 95, 58, 30, 16, 241, 90, 227, 227, 248, 18, 245, 137, + 58, 30, 16, 241, 90, 227, 227, 248, 18, 226, 161, 58, 30, 16, 241, 251, + 214, 242, 248, 18, 209, 49, 58, 30, 16, 241, 90, 214, 242, 248, 18, 213, + 38, 58, 30, 16, 241, 90, 225, 100, 58, 30, 16, 248, 19, 204, 244, 58, 30, + 16, 248, 19, 231, 62, 58, 30, 16, 248, 19, 214, 144, 58, 30, 16, 241, 90, + 237, 225, 206, 13, 212, 79, 58, 30, 16, 241, 90, 243, 40, 252, 84, 58, + 30, 16, 206, 13, 211, 31, 58, 30, 16, 245, 145, 211, 31, 58, 30, 16, 245, + 145, 212, 79, 58, 30, 16, 245, 145, 252, 61, 243, 200, 245, 43, 58, 30, + 16, 245, 145, 226, 159, 212, 83, 245, 43, 58, 30, 16, 245, 145, 245, 129, + 242, 173, 245, 43, 58, 30, 16, 245, 145, 211, 40, 222, 182, 245, 43, 58, + 30, 16, 206, 13, 252, 61, 243, 200, 245, 43, 58, 30, 16, 206, 13, 226, + 159, 212, 83, 245, 43, 58, 30, 16, 206, 13, 245, 129, 242, 173, 245, 43, + 58, 30, 16, 206, 13, 211, 40, 222, 182, 245, 43, 58, 30, 16, 240, 155, + 245, 144, 58, 30, 16, 240, 155, 206, 12, 58, 30, 16, 245, 153, 252, 61, + 226, 222, 58, 30, 16, 245, 153, 252, 61, 227, 98, 58, 30, 16, 245, 153, + 245, 108, 58, 30, 16, 245, 153, 212, 26, 58, 30, 16, 215, 49, 212, 26, + 58, 30, 16, 215, 49, 212, 27, 245, 93, 58, 30, 16, 215, 49, 212, 27, 211, + 32, 58, 30, 16, 215, 49, 212, 27, 212, 71, 58, 30, 16, 215, 49, 251, 238, + 58, 30, 16, 215, 49, 251, 239, 245, 93, 58, 30, 16, 215, 49, 251, 239, + 211, 32, 58, 30, 16, 215, 49, 251, 239, 212, 71, 58, 30, 16, 245, 130, + 240, 136, 58, 30, 16, 245, 136, 222, 97, 58, 30, 16, 214, 5, 58, 30, 16, + 252, 2, 179, 58, 30, 16, 252, 2, 208, 156, 58, 30, 16, 252, 2, 240, 244, + 58, 30, 16, 252, 2, 245, 168, 58, 30, 16, 252, 2, 231, 224, 58, 30, 16, + 252, 2, 205, 19, 58, 30, 16, 252, 2, 224, 230, 58, 30, 16, 231, 200, 225, + 98, 227, 68, 58, 30, 16, 231, 201, 225, 98, 227, 68, 58, 30, 16, 231, + 200, 225, 98, 231, 243, 58, 30, 16, 231, 201, 225, 98, 231, 243, 58, 30, + 16, 231, 64, 231, 243, 58, 30, 16, 240, 3, 225, 98, 231, 243, 30, 16, + 215, 41, 250, 124, 30, 16, 50, 250, 124, 30, 16, 42, 250, 124, 30, 16, + 218, 225, 42, 250, 124, 30, 16, 246, 77, 250, 124, 30, 16, 215, 144, 250, + 124, 30, 16, 47, 218, 252, 53, 30, 16, 48, 218, 252, 53, 30, 16, 218, + 252, 245, 21, 30, 16, 246, 118, 217, 66, 30, 16, 246, 146, 248, 210, 30, + 16, 217, 66, 30, 16, 247, 170, 30, 16, 218, 250, 241, 240, 30, 16, 218, + 250, 241, 239, 30, 16, 218, 250, 241, 238, 30, 16, 242, 4, 30, 16, 242, + 5, 55, 30, 16, 249, 124, 83, 30, 16, 248, 247, 30, 16, 249, 135, 30, 16, + 145, 30, 16, 222, 162, 214, 34, 30, 16, 210, 107, 214, 34, 30, 16, 211, + 236, 214, 34, 30, 16, 241, 124, 214, 34, 30, 16, 241, 203, 214, 34, 30, + 16, 215, 9, 214, 34, 30, 16, 215, 7, 241, 105, 30, 16, 241, 122, 241, + 105, 30, 16, 241, 56, 247, 206, 30, 16, 241, 56, 247, 207, 222, 99, 252, + 142, 30, 16, 241, 56, 247, 207, 222, 99, 250, 109, 30, 16, 249, 35, 247, + 206, 30, 16, 242, 140, 247, 206, 30, 16, 242, 140, 247, 207, 222, 99, + 252, 142, 30, 16, 242, 140, 247, 207, 222, 99, 250, 109, 30, 16, 243, + 242, 247, 205, 30, 16, 243, 242, 247, 204, 30, 16, 226, 95, 227, 118, + 218, 236, 30, 16, 50, 215, 227, 30, 16, 50, 241, 187, 30, 16, 241, 188, + 209, 206, 30, 16, 241, 188, 244, 8, 30, 16, 225, 192, 209, 206, 30, 16, + 225, 192, 244, 8, 30, 16, 215, 228, 209, 206, 30, 16, 215, 228, 244, 8, + 30, 16, 219, 205, 135, 215, 227, 30, 16, 219, 205, 135, 241, 187, 30, 16, + 247, 152, 211, 177, 30, 16, 247, 11, 211, 177, 30, 16, 222, 99, 252, 142, + 30, 16, 222, 99, 250, 109, 30, 16, 219, 186, 252, 142, 30, 16, 219, 186, + 250, 109, 30, 16, 226, 98, 218, 236, 30, 16, 207, 21, 218, 236, 30, 16, + 160, 218, 236, 30, 16, 219, 205, 218, 236, 30, 16, 243, 84, 218, 236, 30, + 16, 215, 3, 218, 236, 30, 16, 212, 1, 218, 236, 30, 16, 214, 251, 218, + 236, 30, 16, 119, 238, 30, 210, 121, 218, 236, 30, 16, 206, 196, 224, 33, + 30, 16, 101, 224, 33, 30, 16, 247, 234, 206, 196, 224, 33, 30, 16, 49, + 224, 34, 207, 23, 30, 16, 49, 224, 34, 249, 202, 30, 16, 211, 52, 224, + 34, 120, 207, 23, 30, 16, 211, 52, 224, 34, 120, 249, 202, 30, 16, 211, + 52, 224, 34, 47, 207, 23, 30, 16, 211, 52, 224, 34, 47, 249, 202, 30, 16, + 211, 52, 224, 34, 48, 207, 23, 30, 16, 211, 52, 224, 34, 48, 249, 202, + 30, 16, 211, 52, 224, 34, 130, 207, 23, 30, 16, 211, 52, 224, 34, 130, + 249, 202, 30, 16, 211, 52, 224, 34, 120, 48, 207, 23, 30, 16, 211, 52, + 224, 34, 120, 48, 249, 202, 30, 16, 226, 145, 224, 34, 207, 23, 30, 16, + 226, 145, 224, 34, 249, 202, 30, 16, 211, 49, 224, 34, 130, 207, 23, 30, + 16, 211, 49, 224, 34, 130, 249, 202, 30, 16, 221, 217, 224, 33, 30, 16, + 208, 167, 224, 33, 30, 16, 224, 34, 249, 202, 30, 16, 223, 182, 224, 33, + 30, 16, 247, 177, 224, 34, 207, 23, 30, 16, 247, 177, 224, 34, 249, 202, + 30, 16, 249, 122, 30, 16, 207, 21, 224, 37, 30, 16, 160, 224, 37, 30, 16, + 219, 205, 224, 37, 30, 16, 243, 84, 224, 37, 30, 16, 215, 3, 224, 37, 30, + 16, 212, 1, 224, 37, 30, 16, 214, 251, 224, 37, 30, 16, 119, 238, 30, + 210, 121, 224, 37, 30, 16, 36, 214, 9, 30, 16, 36, 214, 114, 214, 9, 30, + 16, 36, 211, 60, 30, 16, 36, 211, 59, 30, 16, 36, 211, 58, 30, 16, 241, + 226, 211, 60, 30, 16, 241, 226, 211, 59, 30, 16, 241, 226, 211, 58, 30, + 16, 36, 251, 181, 245, 23, 30, 16, 36, 241, 195, 30, 16, 36, 241, 194, + 30, 16, 36, 241, 193, 30, 16, 36, 241, 192, 30, 16, 36, 241, 191, 30, 16, + 250, 42, 250, 59, 30, 16, 243, 34, 250, 59, 30, 16, 250, 42, 211, 203, + 30, 16, 243, 34, 211, 203, 30, 16, 250, 42, 214, 216, 30, 16, 243, 34, + 214, 216, 30, 16, 250, 42, 221, 60, 30, 16, 243, 34, 221, 60, 30, 16, 36, + 253, 21, 30, 16, 36, 214, 37, 30, 16, 36, 212, 88, 30, 16, 36, 214, 38, + 30, 16, 36, 227, 195, 30, 16, 36, 227, 194, 30, 16, 36, 253, 20, 30, 16, + 36, 229, 99, 30, 16, 251, 249, 209, 206, 30, 16, 251, 249, 244, 8, 30, + 16, 36, 245, 38, 30, 16, 36, 218, 145, 30, 16, 36, 241, 179, 30, 16, 36, + 214, 212, 30, 16, 36, 250, 21, 30, 16, 36, 50, 211, 107, 30, 16, 36, 211, + 36, 211, 107, 30, 16, 218, 150, 30, 16, 213, 193, 30, 16, 205, 159, 30, + 16, 221, 52, 30, 16, 227, 49, 30, 16, 241, 132, 30, 16, 247, 67, 30, 16, + 245, 252, 30, 16, 239, 250, 224, 38, 214, 235, 30, 16, 239, 250, 224, 38, + 224, 68, 214, 235, 30, 16, 211, 84, 30, 16, 210, 144, 30, 16, 233, 2, + 210, 144, 30, 16, 210, 145, 214, 235, 30, 16, 210, 145, 209, 206, 30, 16, + 222, 112, 213, 224, 30, 16, 222, 112, 213, 221, 30, 16, 222, 112, 213, + 220, 30, 16, 222, 112, 213, 219, 30, 16, 222, 112, 213, 218, 30, 16, 222, + 112, 213, 217, 30, 16, 222, 112, 213, 216, 30, 16, 222, 112, 213, 215, + 30, 16, 222, 112, 213, 214, 30, 16, 222, 112, 213, 223, 30, 16, 222, 112, + 213, 222, 30, 16, 239, 79, 30, 16, 225, 108, 30, 16, 243, 34, 73, 214, 1, + 30, 16, 245, 245, 214, 235, 30, 16, 36, 130, 249, 146, 30, 16, 36, 120, + 249, 146, 30, 16, 36, 239, 91, 30, 16, 36, 214, 203, 220, 241, 30, 16, + 221, 169, 83, 30, 16, 221, 169, 120, 83, 30, 16, 160, 221, 169, 83, 30, + 16, 240, 27, 209, 206, 30, 16, 240, 27, 244, 8, 30, 16, 2, 241, 225, 30, + 16, 246, 102, 30, 16, 246, 103, 252, 156, 30, 16, 227, 164, 30, 16, 229, + 117, 30, 16, 249, 119, 30, 16, 216, 56, 207, 23, 30, 16, 216, 56, 249, + 202, 30, 16, 226, 205, 30, 16, 226, 206, 249, 202, 30, 16, 216, 50, 207, + 23, 30, 16, 216, 50, 249, 202, 30, 16, 241, 73, 207, 23, 30, 16, 241, 73, + 249, 202, 30, 16, 229, 118, 221, 129, 218, 236, 30, 16, 229, 118, 233, + 73, 218, 236, 30, 16, 249, 120, 218, 236, 30, 16, 216, 56, 218, 236, 30, + 16, 226, 206, 218, 236, 30, 16, 216, 50, 218, 236, 30, 16, 212, 100, 221, + 127, 247, 34, 220, 107, 221, 128, 30, 16, 212, 100, 221, 127, 247, 34, + 220, 107, 233, 72, 30, 16, 212, 100, 221, 127, 247, 34, 220, 107, 221, + 129, 245, 118, 30, 16, 212, 100, 233, 71, 247, 34, 220, 107, 221, 128, + 30, 16, 212, 100, 233, 71, 247, 34, 220, 107, 233, 72, 30, 16, 212, 100, + 233, 71, 247, 34, 220, 107, 233, 73, 245, 118, 30, 16, 212, 100, 233, 71, + 247, 34, 220, 107, 233, 73, 245, 117, 30, 16, 212, 100, 233, 71, 247, 34, + 220, 107, 233, 73, 245, 116, 30, 16, 247, 62, 30, 16, 239, 226, 249, 35, + 247, 206, 30, 16, 239, 226, 242, 140, 247, 206, 30, 16, 49, 251, 150, 30, + 16, 208, 187, 30, 16, 220, 208, 30, 16, 247, 197, 30, 16, 217, 108, 30, + 16, 247, 201, 30, 16, 211, 95, 30, 16, 220, 180, 30, 16, 220, 181, 241, + 181, 30, 16, 217, 109, 241, 181, 30, 16, 211, 96, 218, 233, 30, 16, 221, + 110, 213, 184, 27, 208, 172, 224, 41, 213, 88, 27, 208, 172, 224, 41, + 213, 77, 27, 208, 172, 224, 41, 213, 67, 27, 208, 172, 224, 41, 213, 60, + 27, 208, 172, 224, 41, 213, 52, 27, 208, 172, 224, 41, 213, 46, 27, 208, + 172, 224, 41, 213, 45, 27, 208, 172, 224, 41, 213, 44, 27, 208, 172, 224, + 41, 213, 43, 27, 208, 172, 224, 41, 213, 87, 27, 208, 172, 224, 41, 213, + 86, 27, 208, 172, 224, 41, 213, 85, 27, 208, 172, 224, 41, 213, 84, 27, + 208, 172, 224, 41, 213, 83, 27, 208, 172, 224, 41, 213, 82, 27, 208, 172, + 224, 41, 213, 81, 27, 208, 172, 224, 41, 213, 80, 27, 208, 172, 224, 41, + 213, 79, 27, 208, 172, 224, 41, 213, 78, 27, 208, 172, 224, 41, 213, 76, + 27, 208, 172, 224, 41, 213, 75, 27, 208, 172, 224, 41, 213, 74, 27, 208, + 172, 224, 41, 213, 73, 27, 208, 172, 224, 41, 213, 72, 27, 208, 172, 224, + 41, 213, 51, 27, 208, 172, 224, 41, 213, 50, 27, 208, 172, 224, 41, 213, + 49, 27, 208, 172, 224, 41, 213, 48, 27, 208, 172, 224, 41, 213, 47, 27, + 233, 24, 224, 41, 213, 88, 27, 233, 24, 224, 41, 213, 77, 27, 233, 24, + 224, 41, 213, 60, 27, 233, 24, 224, 41, 213, 52, 27, 233, 24, 224, 41, + 213, 45, 27, 233, 24, 224, 41, 213, 44, 27, 233, 24, 224, 41, 213, 86, + 27, 233, 24, 224, 41, 213, 85, 27, 233, 24, 224, 41, 213, 84, 27, 233, + 24, 224, 41, 213, 83, 27, 233, 24, 224, 41, 213, 80, 27, 233, 24, 224, + 41, 213, 79, 27, 233, 24, 224, 41, 213, 78, 27, 233, 24, 224, 41, 213, + 73, 27, 233, 24, 224, 41, 213, 72, 27, 233, 24, 224, 41, 213, 71, 27, + 233, 24, 224, 41, 213, 70, 27, 233, 24, 224, 41, 213, 69, 27, 233, 24, + 224, 41, 213, 68, 27, 233, 24, 224, 41, 213, 66, 27, 233, 24, 224, 41, + 213, 65, 27, 233, 24, 224, 41, 213, 64, 27, 233, 24, 224, 41, 213, 63, + 27, 233, 24, 224, 41, 213, 62, 27, 233, 24, 224, 41, 213, 61, 27, 233, + 24, 224, 41, 213, 59, 27, 233, 24, 224, 41, 213, 58, 27, 233, 24, 224, + 41, 213, 57, 27, 233, 24, 224, 41, 213, 56, 27, 233, 24, 224, 41, 213, + 55, 27, 233, 24, 224, 41, 213, 54, 27, 233, 24, 224, 41, 213, 53, 27, + 233, 24, 224, 41, 213, 51, 27, 233, 24, 224, 41, 213, 50, 27, 233, 24, + 224, 41, 213, 49, 27, 233, 24, 224, 41, 213, 48, 27, 233, 24, 224, 41, + 213, 47, 36, 27, 30, 211, 33, 36, 27, 30, 212, 72, 36, 27, 30, 221, 138, + 27, 30, 230, 28, 226, 160, 33, 243, 120, 245, 131, 33, 239, 55, 243, 120, + 245, 131, 33, 238, 33, 243, 120, 245, 131, 33, 243, 119, 239, 56, 245, + 131, 33, 243, 119, 238, 32, 245, 131, 33, 243, 120, 212, 74, 33, 248, + 128, 212, 74, 33, 241, 82, 247, 233, 212, 74, 33, 226, 197, 212, 74, 33, + 250, 119, 212, 74, 33, 231, 218, 214, 215, 212, 74, 33, 247, 110, 212, + 74, 33, 251, 227, 212, 74, 33, 222, 128, 212, 74, 33, 249, 129, 222, 93, + 212, 74, 33, 245, 247, 222, 123, 245, 86, 212, 74, 33, 245, 83, 212, 74, + 33, 205, 225, 212, 74, 33, 233, 59, 212, 74, 33, 221, 148, 212, 74, 33, + 219, 50, 212, 74, 33, 247, 121, 212, 74, 33, 238, 141, 250, 176, 212, 74, + 33, 207, 89, 212, 74, 33, 241, 157, 212, 74, 33, 252, 251, 212, 74, 33, + 219, 9, 212, 74, 33, 218, 240, 212, 74, 33, 243, 118, 212, 74, 33, 232, + 107, 212, 74, 33, 247, 116, 212, 74, 33, 243, 33, 212, 74, 33, 243, 211, + 212, 74, 33, 248, 98, 212, 74, 33, 246, 1, 212, 74, 33, 24, 218, 239, + 212, 74, 33, 222, 43, 212, 74, 33, 230, 32, 212, 74, 33, 247, 190, 212, + 74, 33, 231, 105, 212, 74, 33, 240, 194, 212, 74, 33, 213, 234, 212, 74, + 33, 220, 61, 212, 74, 33, 241, 81, 212, 74, 33, 218, 241, 212, 74, 33, + 230, 71, 222, 123, 226, 177, 212, 74, 33, 218, 237, 212, 74, 33, 240, 13, + 211, 130, 227, 102, 212, 74, 33, 243, 35, 212, 74, 33, 213, 246, 212, 74, + 33, 239, 228, 212, 74, 33, 243, 26, 212, 74, 33, 221, 190, 212, 74, 33, + 218, 139, 212, 74, 33, 241, 180, 212, 74, 33, 209, 48, 222, 123, 207, 73, + 212, 74, 33, 247, 126, 212, 74, 33, 227, 117, 212, 74, 33, 242, 198, 212, + 74, 33, 209, 215, 212, 74, 33, 245, 119, 212, 74, 33, 247, 192, 226, 123, + 212, 74, 33, 239, 205, 212, 74, 33, 240, 195, 233, 68, 212, 74, 33, 227, + 172, 212, 74, 33, 253, 16, 212, 74, 33, 243, 48, 212, 74, 33, 244, 12, + 212, 74, 33, 207, 71, 212, 74, 33, 215, 36, 212, 74, 33, 233, 33, 212, + 74, 33, 245, 215, 212, 74, 33, 246, 82, 212, 74, 33, 245, 115, 212, 74, + 33, 242, 166, 212, 74, 33, 216, 16, 212, 74, 33, 213, 250, 212, 74, 33, + 239, 93, 212, 74, 33, 247, 148, 212, 74, 33, 247, 187, 212, 74, 33, 242, + 53, 212, 74, 33, 252, 216, 212, 74, 33, 247, 147, 212, 74, 33, 222, 166, + 212, 42, 209, 25, 212, 74, 33, 245, 139, 212, 74, 33, 230, 129, 212, 74, + 33, 241, 128, 247, 79, 218, 115, 209, 217, 18, 102, 247, 79, 218, 115, + 209, 217, 18, 105, 247, 79, 218, 115, 209, 217, 18, 142, 247, 79, 218, + 115, 209, 217, 18, 139, 247, 79, 218, 115, 209, 217, 18, 168, 247, 79, + 218, 115, 209, 217, 18, 184, 247, 79, 218, 115, 209, 217, 18, 195, 247, + 79, 218, 115, 209, 217, 18, 193, 247, 79, 218, 115, 209, 217, 18, 200, + 247, 79, 218, 115, 212, 94, 18, 102, 247, 79, 218, 115, 212, 94, 18, 105, + 247, 79, 218, 115, 212, 94, 18, 142, 247, 79, 218, 115, 212, 94, 18, 139, + 247, 79, 218, 115, 212, 94, 18, 168, 247, 79, 218, 115, 212, 94, 18, 184, + 247, 79, 218, 115, 212, 94, 18, 195, 247, 79, 218, 115, 212, 94, 18, 193, + 247, 79, 218, 115, 212, 94, 18, 200, 11, 24, 6, 62, 11, 24, 6, 251, 150, + 11, 24, 6, 249, 34, 11, 24, 6, 246, 240, 11, 24, 6, 75, 11, 24, 6, 242, + 139, 11, 24, 6, 241, 55, 11, 24, 6, 239, 155, 11, 24, 6, 74, 11, 24, 6, + 232, 203, 11, 24, 6, 232, 76, 11, 24, 6, 149, 11, 24, 6, 229, 28, 11, 24, + 6, 226, 33, 11, 24, 6, 76, 11, 24, 6, 222, 67, 11, 24, 6, 220, 27, 11, + 24, 6, 137, 11, 24, 6, 182, 11, 24, 6, 213, 10, 11, 24, 6, 71, 11, 24, 6, + 209, 148, 11, 24, 6, 207, 129, 11, 24, 6, 206, 195, 11, 24, 6, 206, 123, + 11, 24, 6, 205, 159, 11, 24, 5, 62, 11, 24, 5, 251, 150, 11, 24, 5, 249, + 34, 11, 24, 5, 246, 240, 11, 24, 5, 75, 11, 24, 5, 242, 139, 11, 24, 5, + 241, 55, 11, 24, 5, 239, 155, 11, 24, 5, 74, 11, 24, 5, 232, 203, 11, 24, + 5, 232, 76, 11, 24, 5, 149, 11, 24, 5, 229, 28, 11, 24, 5, 226, 33, 11, + 24, 5, 76, 11, 24, 5, 222, 67, 11, 24, 5, 220, 27, 11, 24, 5, 137, 11, + 24, 5, 182, 11, 24, 5, 213, 10, 11, 24, 5, 71, 11, 24, 5, 209, 148, 11, + 24, 5, 207, 129, 11, 24, 5, 206, 195, 11, 24, 5, 206, 123, 11, 24, 5, + 205, 159, 11, 35, 6, 62, 11, 35, 6, 251, 150, 11, 35, 6, 249, 34, 11, 35, + 6, 246, 240, 11, 35, 6, 75, 11, 35, 6, 242, 139, 11, 35, 6, 241, 55, 11, + 35, 6, 239, 155, 11, 35, 6, 74, 11, 35, 6, 232, 203, 11, 35, 6, 232, 76, + 11, 35, 6, 149, 11, 35, 6, 229, 28, 11, 35, 6, 226, 33, 11, 35, 6, 76, + 11, 35, 6, 222, 67, 11, 35, 6, 220, 27, 11, 35, 6, 137, 11, 35, 6, 182, + 11, 35, 6, 213, 10, 11, 35, 6, 71, 11, 35, 6, 209, 148, 11, 35, 6, 207, + 129, 11, 35, 6, 206, 195, 11, 35, 6, 206, 123, 11, 35, 6, 205, 159, 11, + 35, 5, 62, 11, 35, 5, 251, 150, 11, 35, 5, 249, 34, 11, 35, 5, 246, 240, + 11, 35, 5, 75, 11, 35, 5, 242, 139, 11, 35, 5, 241, 55, 11, 35, 5, 74, + 11, 35, 5, 232, 203, 11, 35, 5, 232, 76, 11, 35, 5, 149, 11, 35, 5, 229, + 28, 11, 35, 5, 226, 33, 11, 35, 5, 76, 11, 35, 5, 222, 67, 11, 35, 5, + 220, 27, 11, 35, 5, 137, 11, 35, 5, 182, 11, 35, 5, 213, 10, 11, 35, 5, + 71, 11, 35, 5, 209, 148, 11, 35, 5, 207, 129, 11, 35, 5, 206, 195, 11, + 35, 5, 206, 123, 11, 35, 5, 205, 159, 11, 24, 35, 6, 62, 11, 24, 35, 6, + 251, 150, 11, 24, 35, 6, 249, 34, 11, 24, 35, 6, 246, 240, 11, 24, 35, 6, + 75, 11, 24, 35, 6, 242, 139, 11, 24, 35, 6, 241, 55, 11, 24, 35, 6, 239, + 155, 11, 24, 35, 6, 74, 11, 24, 35, 6, 232, 203, 11, 24, 35, 6, 232, 76, + 11, 24, 35, 6, 149, 11, 24, 35, 6, 229, 28, 11, 24, 35, 6, 226, 33, 11, + 24, 35, 6, 76, 11, 24, 35, 6, 222, 67, 11, 24, 35, 6, 220, 27, 11, 24, + 35, 6, 137, 11, 24, 35, 6, 182, 11, 24, 35, 6, 213, 10, 11, 24, 35, 6, + 71, 11, 24, 35, 6, 209, 148, 11, 24, 35, 6, 207, 129, 11, 24, 35, 6, 206, + 195, 11, 24, 35, 6, 206, 123, 11, 24, 35, 6, 205, 159, 11, 24, 35, 5, 62, + 11, 24, 35, 5, 251, 150, 11, 24, 35, 5, 249, 34, 11, 24, 35, 5, 246, 240, + 11, 24, 35, 5, 75, 11, 24, 35, 5, 242, 139, 11, 24, 35, 5, 241, 55, 11, + 24, 35, 5, 239, 155, 11, 24, 35, 5, 74, 11, 24, 35, 5, 232, 203, 11, 24, + 35, 5, 232, 76, 11, 24, 35, 5, 149, 11, 24, 35, 5, 229, 28, 11, 24, 35, + 5, 226, 33, 11, 24, 35, 5, 76, 11, 24, 35, 5, 222, 67, 11, 24, 35, 5, + 220, 27, 11, 24, 35, 5, 137, 11, 24, 35, 5, 182, 11, 24, 35, 5, 213, 10, + 11, 24, 35, 5, 71, 11, 24, 35, 5, 209, 148, 11, 24, 35, 5, 207, 129, 11, + 24, 35, 5, 206, 195, 11, 24, 35, 5, 206, 123, 11, 24, 35, 5, 205, 159, + 11, 121, 6, 62, 11, 121, 6, 249, 34, 11, 121, 6, 246, 240, 11, 121, 6, + 241, 55, 11, 121, 6, 232, 203, 11, 121, 6, 232, 76, 11, 121, 6, 226, 33, + 11, 121, 6, 76, 11, 121, 6, 222, 67, 11, 121, 6, 220, 27, 11, 121, 6, + 182, 11, 121, 6, 213, 10, 11, 121, 6, 71, 11, 121, 6, 209, 148, 11, 121, + 6, 207, 129, 11, 121, 6, 206, 195, 11, 121, 6, 206, 123, 11, 121, 6, 205, + 159, 11, 121, 5, 62, 11, 121, 5, 251, 150, 11, 121, 5, 249, 34, 11, 121, + 5, 246, 240, 11, 121, 5, 242, 139, 11, 121, 5, 239, 155, 11, 121, 5, 74, + 11, 121, 5, 232, 203, 11, 121, 5, 232, 76, 11, 121, 5, 149, 11, 121, 5, + 229, 28, 11, 121, 5, 226, 33, 11, 121, 5, 222, 67, 11, 121, 5, 220, 27, + 11, 121, 5, 137, 11, 121, 5, 182, 11, 121, 5, 213, 10, 11, 121, 5, 71, + 11, 121, 5, 209, 148, 11, 121, 5, 207, 129, 11, 121, 5, 206, 195, 11, + 121, 5, 206, 123, 11, 121, 5, 205, 159, 11, 24, 121, 6, 62, 11, 24, 121, + 6, 251, 150, 11, 24, 121, 6, 249, 34, 11, 24, 121, 6, 246, 240, 11, 24, + 121, 6, 75, 11, 24, 121, 6, 242, 139, 11, 24, 121, 6, 241, 55, 11, 24, + 121, 6, 239, 155, 11, 24, 121, 6, 74, 11, 24, 121, 6, 232, 203, 11, 24, + 121, 6, 232, 76, 11, 24, 121, 6, 149, 11, 24, 121, 6, 229, 28, 11, 24, + 121, 6, 226, 33, 11, 24, 121, 6, 76, 11, 24, 121, 6, 222, 67, 11, 24, + 121, 6, 220, 27, 11, 24, 121, 6, 137, 11, 24, 121, 6, 182, 11, 24, 121, + 6, 213, 10, 11, 24, 121, 6, 71, 11, 24, 121, 6, 209, 148, 11, 24, 121, 6, + 207, 129, 11, 24, 121, 6, 206, 195, 11, 24, 121, 6, 206, 123, 11, 24, + 121, 6, 205, 159, 11, 24, 121, 5, 62, 11, 24, 121, 5, 251, 150, 11, 24, + 121, 5, 249, 34, 11, 24, 121, 5, 246, 240, 11, 24, 121, 5, 75, 11, 24, + 121, 5, 242, 139, 11, 24, 121, 5, 241, 55, 11, 24, 121, 5, 239, 155, 11, + 24, 121, 5, 74, 11, 24, 121, 5, 232, 203, 11, 24, 121, 5, 232, 76, 11, + 24, 121, 5, 149, 11, 24, 121, 5, 229, 28, 11, 24, 121, 5, 226, 33, 11, + 24, 121, 5, 76, 11, 24, 121, 5, 222, 67, 11, 24, 121, 5, 220, 27, 11, 24, + 121, 5, 137, 11, 24, 121, 5, 182, 11, 24, 121, 5, 213, 10, 11, 24, 121, + 5, 71, 11, 24, 121, 5, 209, 148, 11, 24, 121, 5, 207, 129, 11, 24, 121, + 5, 206, 195, 11, 24, 121, 5, 206, 123, 11, 24, 121, 5, 205, 159, 11, 154, + 6, 62, 11, 154, 6, 251, 150, 11, 154, 6, 246, 240, 11, 154, 6, 75, 11, + 154, 6, 242, 139, 11, 154, 6, 241, 55, 11, 154, 6, 232, 203, 11, 154, 6, + 232, 76, 11, 154, 6, 149, 11, 154, 6, 229, 28, 11, 154, 6, 226, 33, 11, + 154, 6, 76, 11, 154, 6, 222, 67, 11, 154, 6, 220, 27, 11, 154, 6, 182, + 11, 154, 6, 213, 10, 11, 154, 6, 71, 11, 154, 6, 209, 148, 11, 154, 6, + 207, 129, 11, 154, 6, 206, 195, 11, 154, 6, 206, 123, 11, 154, 5, 62, 11, + 154, 5, 251, 150, 11, 154, 5, 249, 34, 11, 154, 5, 246, 240, 11, 154, 5, + 75, 11, 154, 5, 242, 139, 11, 154, 5, 241, 55, 11, 154, 5, 239, 155, 11, + 154, 5, 74, 11, 154, 5, 232, 203, 11, 154, 5, 232, 76, 11, 154, 5, 149, + 11, 154, 5, 229, 28, 11, 154, 5, 226, 33, 11, 154, 5, 76, 11, 154, 5, + 222, 67, 11, 154, 5, 220, 27, 11, 154, 5, 137, 11, 154, 5, 182, 11, 154, + 5, 213, 10, 11, 154, 5, 71, 11, 154, 5, 209, 148, 11, 154, 5, 207, 129, + 11, 154, 5, 206, 195, 11, 154, 5, 206, 123, 11, 154, 5, 205, 159, 11, + 159, 6, 62, 11, 159, 6, 251, 150, 11, 159, 6, 246, 240, 11, 159, 6, 75, + 11, 159, 6, 242, 139, 11, 159, 6, 241, 55, 11, 159, 6, 74, 11, 159, 6, + 232, 203, 11, 159, 6, 232, 76, 11, 159, 6, 149, 11, 159, 6, 229, 28, 11, + 159, 6, 76, 11, 159, 6, 182, 11, 159, 6, 213, 10, 11, 159, 6, 71, 11, + 159, 6, 209, 148, 11, 159, 6, 207, 129, 11, 159, 6, 206, 195, 11, 159, 6, + 206, 123, 11, 159, 5, 62, 11, 159, 5, 251, 150, 11, 159, 5, 249, 34, 11, + 159, 5, 246, 240, 11, 159, 5, 75, 11, 159, 5, 242, 139, 11, 159, 5, 241, + 55, 11, 159, 5, 239, 155, 11, 159, 5, 74, 11, 159, 5, 232, 203, 11, 159, + 5, 232, 76, 11, 159, 5, 149, 11, 159, 5, 229, 28, 11, 159, 5, 226, 33, + 11, 159, 5, 76, 11, 159, 5, 222, 67, 11, 159, 5, 220, 27, 11, 159, 5, + 137, 11, 159, 5, 182, 11, 159, 5, 213, 10, 11, 159, 5, 71, 11, 159, 5, + 209, 148, 11, 159, 5, 207, 129, 11, 159, 5, 206, 195, 11, 159, 5, 206, + 123, 11, 159, 5, 205, 159, 11, 24, 154, 6, 62, 11, 24, 154, 6, 251, 150, + 11, 24, 154, 6, 249, 34, 11, 24, 154, 6, 246, 240, 11, 24, 154, 6, 75, + 11, 24, 154, 6, 242, 139, 11, 24, 154, 6, 241, 55, 11, 24, 154, 6, 239, + 155, 11, 24, 154, 6, 74, 11, 24, 154, 6, 232, 203, 11, 24, 154, 6, 232, + 76, 11, 24, 154, 6, 149, 11, 24, 154, 6, 229, 28, 11, 24, 154, 6, 226, + 33, 11, 24, 154, 6, 76, 11, 24, 154, 6, 222, 67, 11, 24, 154, 6, 220, 27, + 11, 24, 154, 6, 137, 11, 24, 154, 6, 182, 11, 24, 154, 6, 213, 10, 11, + 24, 154, 6, 71, 11, 24, 154, 6, 209, 148, 11, 24, 154, 6, 207, 129, 11, + 24, 154, 6, 206, 195, 11, 24, 154, 6, 206, 123, 11, 24, 154, 6, 205, 159, + 11, 24, 154, 5, 62, 11, 24, 154, 5, 251, 150, 11, 24, 154, 5, 249, 34, + 11, 24, 154, 5, 246, 240, 11, 24, 154, 5, 75, 11, 24, 154, 5, 242, 139, + 11, 24, 154, 5, 241, 55, 11, 24, 154, 5, 239, 155, 11, 24, 154, 5, 74, + 11, 24, 154, 5, 232, 203, 11, 24, 154, 5, 232, 76, 11, 24, 154, 5, 149, + 11, 24, 154, 5, 229, 28, 11, 24, 154, 5, 226, 33, 11, 24, 154, 5, 76, 11, + 24, 154, 5, 222, 67, 11, 24, 154, 5, 220, 27, 11, 24, 154, 5, 137, 11, + 24, 154, 5, 182, 11, 24, 154, 5, 213, 10, 11, 24, 154, 5, 71, 11, 24, + 154, 5, 209, 148, 11, 24, 154, 5, 207, 129, 11, 24, 154, 5, 206, 195, 11, + 24, 154, 5, 206, 123, 11, 24, 154, 5, 205, 159, 11, 38, 6, 62, 11, 38, 6, + 251, 150, 11, 38, 6, 249, 34, 11, 38, 6, 246, 240, 11, 38, 6, 75, 11, 38, + 6, 242, 139, 11, 38, 6, 241, 55, 11, 38, 6, 239, 155, 11, 38, 6, 74, 11, + 38, 6, 232, 203, 11, 38, 6, 232, 76, 11, 38, 6, 149, 11, 38, 6, 229, 28, + 11, 38, 6, 226, 33, 11, 38, 6, 76, 11, 38, 6, 222, 67, 11, 38, 6, 220, + 27, 11, 38, 6, 137, 11, 38, 6, 182, 11, 38, 6, 213, 10, 11, 38, 6, 71, + 11, 38, 6, 209, 148, 11, 38, 6, 207, 129, 11, 38, 6, 206, 195, 11, 38, 6, + 206, 123, 11, 38, 6, 205, 159, 11, 38, 5, 62, 11, 38, 5, 251, 150, 11, + 38, 5, 249, 34, 11, 38, 5, 246, 240, 11, 38, 5, 75, 11, 38, 5, 242, 139, + 11, 38, 5, 241, 55, 11, 38, 5, 239, 155, 11, 38, 5, 74, 11, 38, 5, 232, + 203, 11, 38, 5, 232, 76, 11, 38, 5, 149, 11, 38, 5, 229, 28, 11, 38, 5, + 226, 33, 11, 38, 5, 76, 11, 38, 5, 222, 67, 11, 38, 5, 220, 27, 11, 38, + 5, 137, 11, 38, 5, 182, 11, 38, 5, 213, 10, 11, 38, 5, 71, 11, 38, 5, + 209, 148, 11, 38, 5, 207, 129, 11, 38, 5, 206, 195, 11, 38, 5, 206, 123, + 11, 38, 5, 205, 159, 11, 38, 24, 6, 62, 11, 38, 24, 6, 251, 150, 11, 38, + 24, 6, 249, 34, 11, 38, 24, 6, 246, 240, 11, 38, 24, 6, 75, 11, 38, 24, + 6, 242, 139, 11, 38, 24, 6, 241, 55, 11, 38, 24, 6, 239, 155, 11, 38, 24, + 6, 74, 11, 38, 24, 6, 232, 203, 11, 38, 24, 6, 232, 76, 11, 38, 24, 6, + 149, 11, 38, 24, 6, 229, 28, 11, 38, 24, 6, 226, 33, 11, 38, 24, 6, 76, + 11, 38, 24, 6, 222, 67, 11, 38, 24, 6, 220, 27, 11, 38, 24, 6, 137, 11, + 38, 24, 6, 182, 11, 38, 24, 6, 213, 10, 11, 38, 24, 6, 71, 11, 38, 24, 6, + 209, 148, 11, 38, 24, 6, 207, 129, 11, 38, 24, 6, 206, 195, 11, 38, 24, + 6, 206, 123, 11, 38, 24, 6, 205, 159, 11, 38, 24, 5, 62, 11, 38, 24, 5, + 251, 150, 11, 38, 24, 5, 249, 34, 11, 38, 24, 5, 246, 240, 11, 38, 24, 5, + 75, 11, 38, 24, 5, 242, 139, 11, 38, 24, 5, 241, 55, 11, 38, 24, 5, 239, + 155, 11, 38, 24, 5, 74, 11, 38, 24, 5, 232, 203, 11, 38, 24, 5, 232, 76, + 11, 38, 24, 5, 149, 11, 38, 24, 5, 229, 28, 11, 38, 24, 5, 226, 33, 11, + 38, 24, 5, 76, 11, 38, 24, 5, 222, 67, 11, 38, 24, 5, 220, 27, 11, 38, + 24, 5, 137, 11, 38, 24, 5, 182, 11, 38, 24, 5, 213, 10, 11, 38, 24, 5, + 71, 11, 38, 24, 5, 209, 148, 11, 38, 24, 5, 207, 129, 11, 38, 24, 5, 206, + 195, 11, 38, 24, 5, 206, 123, 11, 38, 24, 5, 205, 159, 11, 38, 35, 6, 62, + 11, 38, 35, 6, 251, 150, 11, 38, 35, 6, 249, 34, 11, 38, 35, 6, 246, 240, + 11, 38, 35, 6, 75, 11, 38, 35, 6, 242, 139, 11, 38, 35, 6, 241, 55, 11, + 38, 35, 6, 239, 155, 11, 38, 35, 6, 74, 11, 38, 35, 6, 232, 203, 11, 38, + 35, 6, 232, 76, 11, 38, 35, 6, 149, 11, 38, 35, 6, 229, 28, 11, 38, 35, + 6, 226, 33, 11, 38, 35, 6, 76, 11, 38, 35, 6, 222, 67, 11, 38, 35, 6, + 220, 27, 11, 38, 35, 6, 137, 11, 38, 35, 6, 182, 11, 38, 35, 6, 213, 10, + 11, 38, 35, 6, 71, 11, 38, 35, 6, 209, 148, 11, 38, 35, 6, 207, 129, 11, + 38, 35, 6, 206, 195, 11, 38, 35, 6, 206, 123, 11, 38, 35, 6, 205, 159, + 11, 38, 35, 5, 62, 11, 38, 35, 5, 251, 150, 11, 38, 35, 5, 249, 34, 11, + 38, 35, 5, 246, 240, 11, 38, 35, 5, 75, 11, 38, 35, 5, 242, 139, 11, 38, + 35, 5, 241, 55, 11, 38, 35, 5, 239, 155, 11, 38, 35, 5, 74, 11, 38, 35, + 5, 232, 203, 11, 38, 35, 5, 232, 76, 11, 38, 35, 5, 149, 11, 38, 35, 5, + 229, 28, 11, 38, 35, 5, 226, 33, 11, 38, 35, 5, 76, 11, 38, 35, 5, 222, + 67, 11, 38, 35, 5, 220, 27, 11, 38, 35, 5, 137, 11, 38, 35, 5, 182, 11, + 38, 35, 5, 213, 10, 11, 38, 35, 5, 71, 11, 38, 35, 5, 209, 148, 11, 38, + 35, 5, 207, 129, 11, 38, 35, 5, 206, 195, 11, 38, 35, 5, 206, 123, 11, + 38, 35, 5, 205, 159, 11, 38, 24, 35, 6, 62, 11, 38, 24, 35, 6, 251, 150, + 11, 38, 24, 35, 6, 249, 34, 11, 38, 24, 35, 6, 246, 240, 11, 38, 24, 35, + 6, 75, 11, 38, 24, 35, 6, 242, 139, 11, 38, 24, 35, 6, 241, 55, 11, 38, + 24, 35, 6, 239, 155, 11, 38, 24, 35, 6, 74, 11, 38, 24, 35, 6, 232, 203, + 11, 38, 24, 35, 6, 232, 76, 11, 38, 24, 35, 6, 149, 11, 38, 24, 35, 6, + 229, 28, 11, 38, 24, 35, 6, 226, 33, 11, 38, 24, 35, 6, 76, 11, 38, 24, + 35, 6, 222, 67, 11, 38, 24, 35, 6, 220, 27, 11, 38, 24, 35, 6, 137, 11, + 38, 24, 35, 6, 182, 11, 38, 24, 35, 6, 213, 10, 11, 38, 24, 35, 6, 71, + 11, 38, 24, 35, 6, 209, 148, 11, 38, 24, 35, 6, 207, 129, 11, 38, 24, 35, + 6, 206, 195, 11, 38, 24, 35, 6, 206, 123, 11, 38, 24, 35, 6, 205, 159, + 11, 38, 24, 35, 5, 62, 11, 38, 24, 35, 5, 251, 150, 11, 38, 24, 35, 5, + 249, 34, 11, 38, 24, 35, 5, 246, 240, 11, 38, 24, 35, 5, 75, 11, 38, 24, + 35, 5, 242, 139, 11, 38, 24, 35, 5, 241, 55, 11, 38, 24, 35, 5, 239, 155, + 11, 38, 24, 35, 5, 74, 11, 38, 24, 35, 5, 232, 203, 11, 38, 24, 35, 5, + 232, 76, 11, 38, 24, 35, 5, 149, 11, 38, 24, 35, 5, 229, 28, 11, 38, 24, + 35, 5, 226, 33, 11, 38, 24, 35, 5, 76, 11, 38, 24, 35, 5, 222, 67, 11, + 38, 24, 35, 5, 220, 27, 11, 38, 24, 35, 5, 137, 11, 38, 24, 35, 5, 182, + 11, 38, 24, 35, 5, 213, 10, 11, 38, 24, 35, 5, 71, 11, 38, 24, 35, 5, + 209, 148, 11, 38, 24, 35, 5, 207, 129, 11, 38, 24, 35, 5, 206, 195, 11, + 38, 24, 35, 5, 206, 123, 11, 38, 24, 35, 5, 205, 159, 11, 226, 156, 6, + 62, 11, 226, 156, 6, 251, 150, 11, 226, 156, 6, 249, 34, 11, 226, 156, 6, + 246, 240, 11, 226, 156, 6, 75, 11, 226, 156, 6, 242, 139, 11, 226, 156, + 6, 241, 55, 11, 226, 156, 6, 239, 155, 11, 226, 156, 6, 74, 11, 226, 156, + 6, 232, 203, 11, 226, 156, 6, 232, 76, 11, 226, 156, 6, 149, 11, 226, + 156, 6, 229, 28, 11, 226, 156, 6, 226, 33, 11, 226, 156, 6, 76, 11, 226, + 156, 6, 222, 67, 11, 226, 156, 6, 220, 27, 11, 226, 156, 6, 137, 11, 226, + 156, 6, 182, 11, 226, 156, 6, 213, 10, 11, 226, 156, 6, 71, 11, 226, 156, + 6, 209, 148, 11, 226, 156, 6, 207, 129, 11, 226, 156, 6, 206, 195, 11, + 226, 156, 6, 206, 123, 11, 226, 156, 6, 205, 159, 11, 226, 156, 5, 62, + 11, 226, 156, 5, 251, 150, 11, 226, 156, 5, 249, 34, 11, 226, 156, 5, + 246, 240, 11, 226, 156, 5, 75, 11, 226, 156, 5, 242, 139, 11, 226, 156, + 5, 241, 55, 11, 226, 156, 5, 239, 155, 11, 226, 156, 5, 74, 11, 226, 156, + 5, 232, 203, 11, 226, 156, 5, 232, 76, 11, 226, 156, 5, 149, 11, 226, + 156, 5, 229, 28, 11, 226, 156, 5, 226, 33, 11, 226, 156, 5, 76, 11, 226, + 156, 5, 222, 67, 11, 226, 156, 5, 220, 27, 11, 226, 156, 5, 137, 11, 226, + 156, 5, 182, 11, 226, 156, 5, 213, 10, 11, 226, 156, 5, 71, 11, 226, 156, + 5, 209, 148, 11, 226, 156, 5, 207, 129, 11, 226, 156, 5, 206, 195, 11, + 226, 156, 5, 206, 123, 11, 226, 156, 5, 205, 159, 11, 35, 5, 245, 22, 74, + 11, 35, 5, 245, 22, 232, 203, 11, 24, 6, 252, 144, 11, 24, 6, 250, 8, 11, + 24, 6, 240, 215, 11, 24, 6, 245, 227, 11, 24, 6, 242, 244, 11, 24, 6, + 205, 84, 11, 24, 6, 242, 201, 11, 24, 6, 212, 23, 11, 24, 6, 232, 249, + 11, 24, 6, 232, 14, 11, 24, 6, 230, 102, 11, 24, 6, 226, 114, 11, 24, 6, + 223, 217, 11, 24, 6, 206, 169, 11, 24, 6, 222, 168, 11, 24, 6, 221, 53, + 11, 24, 6, 218, 210, 11, 24, 6, 212, 24, 93, 11, 24, 6, 215, 63, 11, 24, + 6, 212, 151, 11, 24, 6, 209, 200, 11, 24, 6, 221, 78, 11, 24, 6, 248, 58, + 11, 24, 6, 220, 93, 11, 24, 6, 222, 170, 11, 24, 225, 227, 11, 24, 5, + 252, 144, 11, 24, 5, 250, 8, 11, 24, 5, 240, 215, 11, 24, 5, 245, 227, + 11, 24, 5, 242, 244, 11, 24, 5, 205, 84, 11, 24, 5, 242, 201, 11, 24, 5, + 212, 23, 11, 24, 5, 232, 249, 11, 24, 5, 232, 14, 11, 24, 5, 230, 102, + 11, 24, 5, 226, 114, 11, 24, 5, 223, 217, 11, 24, 5, 206, 169, 11, 24, 5, + 222, 168, 11, 24, 5, 221, 53, 11, 24, 5, 218, 210, 11, 24, 5, 42, 215, + 63, 11, 24, 5, 215, 63, 11, 24, 5, 212, 151, 11, 24, 5, 209, 200, 11, 24, + 5, 221, 78, 11, 24, 5, 248, 58, 11, 24, 5, 220, 93, 11, 24, 5, 222, 170, + 11, 24, 221, 209, 245, 140, 11, 24, 242, 245, 93, 11, 24, 212, 24, 93, + 11, 24, 232, 15, 93, 11, 24, 221, 79, 93, 11, 24, 218, 211, 93, 11, 24, + 221, 54, 93, 11, 35, 6, 252, 144, 11, 35, 6, 250, 8, 11, 35, 6, 240, 215, + 11, 35, 6, 245, 227, 11, 35, 6, 242, 244, 11, 35, 6, 205, 84, 11, 35, 6, + 242, 201, 11, 35, 6, 212, 23, 11, 35, 6, 232, 249, 11, 35, 6, 232, 14, + 11, 35, 6, 230, 102, 11, 35, 6, 226, 114, 11, 35, 6, 223, 217, 11, 35, 6, + 206, 169, 11, 35, 6, 222, 168, 11, 35, 6, 221, 53, 11, 35, 6, 218, 210, + 11, 35, 6, 212, 24, 93, 11, 35, 6, 215, 63, 11, 35, 6, 212, 151, 11, 35, + 6, 209, 200, 11, 35, 6, 221, 78, 11, 35, 6, 248, 58, 11, 35, 6, 220, 93, + 11, 35, 6, 222, 170, 11, 35, 225, 227, 11, 35, 5, 252, 144, 11, 35, 5, + 250, 8, 11, 35, 5, 240, 215, 11, 35, 5, 245, 227, 11, 35, 5, 242, 244, + 11, 35, 5, 205, 84, 11, 35, 5, 242, 201, 11, 35, 5, 212, 23, 11, 35, 5, + 232, 249, 11, 35, 5, 232, 14, 11, 35, 5, 230, 102, 11, 35, 5, 226, 114, + 11, 35, 5, 223, 217, 11, 35, 5, 206, 169, 11, 35, 5, 222, 168, 11, 35, 5, + 221, 53, 11, 35, 5, 218, 210, 11, 35, 5, 42, 215, 63, 11, 35, 5, 215, 63, + 11, 35, 5, 212, 151, 11, 35, 5, 209, 200, 11, 35, 5, 221, 78, 11, 35, 5, + 248, 58, 11, 35, 5, 220, 93, 11, 35, 5, 222, 170, 11, 35, 221, 209, 245, + 140, 11, 35, 242, 245, 93, 11, 35, 212, 24, 93, 11, 35, 232, 15, 93, 11, + 35, 221, 79, 93, 11, 35, 218, 211, 93, 11, 35, 221, 54, 93, 11, 24, 35, + 6, 252, 144, 11, 24, 35, 6, 250, 8, 11, 24, 35, 6, 240, 215, 11, 24, 35, + 6, 245, 227, 11, 24, 35, 6, 242, 244, 11, 24, 35, 6, 205, 84, 11, 24, 35, + 6, 242, 201, 11, 24, 35, 6, 212, 23, 11, 24, 35, 6, 232, 249, 11, 24, 35, + 6, 232, 14, 11, 24, 35, 6, 230, 102, 11, 24, 35, 6, 226, 114, 11, 24, 35, + 6, 223, 217, 11, 24, 35, 6, 206, 169, 11, 24, 35, 6, 222, 168, 11, 24, + 35, 6, 221, 53, 11, 24, 35, 6, 218, 210, 11, 24, 35, 6, 212, 24, 93, 11, + 24, 35, 6, 215, 63, 11, 24, 35, 6, 212, 151, 11, 24, 35, 6, 209, 200, 11, + 24, 35, 6, 221, 78, 11, 24, 35, 6, 248, 58, 11, 24, 35, 6, 220, 93, 11, + 24, 35, 6, 222, 170, 11, 24, 35, 225, 227, 11, 24, 35, 5, 252, 144, 11, + 24, 35, 5, 250, 8, 11, 24, 35, 5, 240, 215, 11, 24, 35, 5, 245, 227, 11, + 24, 35, 5, 242, 244, 11, 24, 35, 5, 205, 84, 11, 24, 35, 5, 242, 201, 11, + 24, 35, 5, 212, 23, 11, 24, 35, 5, 232, 249, 11, 24, 35, 5, 232, 14, 11, + 24, 35, 5, 230, 102, 11, 24, 35, 5, 226, 114, 11, 24, 35, 5, 223, 217, + 11, 24, 35, 5, 206, 169, 11, 24, 35, 5, 222, 168, 11, 24, 35, 5, 221, 53, + 11, 24, 35, 5, 218, 210, 11, 24, 35, 5, 42, 215, 63, 11, 24, 35, 5, 215, + 63, 11, 24, 35, 5, 212, 151, 11, 24, 35, 5, 209, 200, 11, 24, 35, 5, 221, + 78, 11, 24, 35, 5, 248, 58, 11, 24, 35, 5, 220, 93, 11, 24, 35, 5, 222, + 170, 11, 24, 35, 221, 209, 245, 140, 11, 24, 35, 242, 245, 93, 11, 24, + 35, 212, 24, 93, 11, 24, 35, 232, 15, 93, 11, 24, 35, 221, 79, 93, 11, + 24, 35, 218, 211, 93, 11, 24, 35, 221, 54, 93, 11, 38, 24, 6, 252, 144, + 11, 38, 24, 6, 250, 8, 11, 38, 24, 6, 240, 215, 11, 38, 24, 6, 245, 227, + 11, 38, 24, 6, 242, 244, 11, 38, 24, 6, 205, 84, 11, 38, 24, 6, 242, 201, + 11, 38, 24, 6, 212, 23, 11, 38, 24, 6, 232, 249, 11, 38, 24, 6, 232, 14, + 11, 38, 24, 6, 230, 102, 11, 38, 24, 6, 226, 114, 11, 38, 24, 6, 223, + 217, 11, 38, 24, 6, 206, 169, 11, 38, 24, 6, 222, 168, 11, 38, 24, 6, + 221, 53, 11, 38, 24, 6, 218, 210, 11, 38, 24, 6, 212, 24, 93, 11, 38, 24, + 6, 215, 63, 11, 38, 24, 6, 212, 151, 11, 38, 24, 6, 209, 200, 11, 38, 24, + 6, 221, 78, 11, 38, 24, 6, 248, 58, 11, 38, 24, 6, 220, 93, 11, 38, 24, + 6, 222, 170, 11, 38, 24, 225, 227, 11, 38, 24, 5, 252, 144, 11, 38, 24, + 5, 250, 8, 11, 38, 24, 5, 240, 215, 11, 38, 24, 5, 245, 227, 11, 38, 24, + 5, 242, 244, 11, 38, 24, 5, 205, 84, 11, 38, 24, 5, 242, 201, 11, 38, 24, + 5, 212, 23, 11, 38, 24, 5, 232, 249, 11, 38, 24, 5, 232, 14, 11, 38, 24, + 5, 230, 102, 11, 38, 24, 5, 226, 114, 11, 38, 24, 5, 223, 217, 11, 38, + 24, 5, 206, 169, 11, 38, 24, 5, 222, 168, 11, 38, 24, 5, 221, 53, 11, 38, + 24, 5, 218, 210, 11, 38, 24, 5, 42, 215, 63, 11, 38, 24, 5, 215, 63, 11, + 38, 24, 5, 212, 151, 11, 38, 24, 5, 209, 200, 11, 38, 24, 5, 221, 78, 11, + 38, 24, 5, 248, 58, 11, 38, 24, 5, 220, 93, 11, 38, 24, 5, 222, 170, 11, + 38, 24, 221, 209, 245, 140, 11, 38, 24, 242, 245, 93, 11, 38, 24, 212, + 24, 93, 11, 38, 24, 232, 15, 93, 11, 38, 24, 221, 79, 93, 11, 38, 24, + 218, 211, 93, 11, 38, 24, 221, 54, 93, 11, 38, 24, 35, 6, 252, 144, 11, + 38, 24, 35, 6, 250, 8, 11, 38, 24, 35, 6, 240, 215, 11, 38, 24, 35, 6, + 245, 227, 11, 38, 24, 35, 6, 242, 244, 11, 38, 24, 35, 6, 205, 84, 11, + 38, 24, 35, 6, 242, 201, 11, 38, 24, 35, 6, 212, 23, 11, 38, 24, 35, 6, + 232, 249, 11, 38, 24, 35, 6, 232, 14, 11, 38, 24, 35, 6, 230, 102, 11, + 38, 24, 35, 6, 226, 114, 11, 38, 24, 35, 6, 223, 217, 11, 38, 24, 35, 6, + 206, 169, 11, 38, 24, 35, 6, 222, 168, 11, 38, 24, 35, 6, 221, 53, 11, + 38, 24, 35, 6, 218, 210, 11, 38, 24, 35, 6, 212, 24, 93, 11, 38, 24, 35, + 6, 215, 63, 11, 38, 24, 35, 6, 212, 151, 11, 38, 24, 35, 6, 209, 200, 11, + 38, 24, 35, 6, 221, 78, 11, 38, 24, 35, 6, 248, 58, 11, 38, 24, 35, 6, + 220, 93, 11, 38, 24, 35, 6, 222, 170, 11, 38, 24, 35, 225, 227, 11, 38, + 24, 35, 5, 252, 144, 11, 38, 24, 35, 5, 250, 8, 11, 38, 24, 35, 5, 240, + 215, 11, 38, 24, 35, 5, 245, 227, 11, 38, 24, 35, 5, 242, 244, 11, 38, + 24, 35, 5, 205, 84, 11, 38, 24, 35, 5, 242, 201, 11, 38, 24, 35, 5, 212, + 23, 11, 38, 24, 35, 5, 232, 249, 11, 38, 24, 35, 5, 232, 14, 11, 38, 24, + 35, 5, 230, 102, 11, 38, 24, 35, 5, 226, 114, 11, 38, 24, 35, 5, 223, + 217, 11, 38, 24, 35, 5, 206, 169, 11, 38, 24, 35, 5, 222, 168, 11, 38, + 24, 35, 5, 221, 53, 11, 38, 24, 35, 5, 218, 210, 11, 38, 24, 35, 5, 42, + 215, 63, 11, 38, 24, 35, 5, 215, 63, 11, 38, 24, 35, 5, 212, 151, 11, 38, + 24, 35, 5, 209, 200, 11, 38, 24, 35, 5, 221, 78, 11, 38, 24, 35, 5, 248, + 58, 11, 38, 24, 35, 5, 220, 93, 11, 38, 24, 35, 5, 222, 170, 11, 38, 24, + 35, 221, 209, 245, 140, 11, 38, 24, 35, 242, 245, 93, 11, 38, 24, 35, + 212, 24, 93, 11, 38, 24, 35, 232, 15, 93, 11, 38, 24, 35, 221, 79, 93, + 11, 38, 24, 35, 218, 211, 93, 11, 38, 24, 35, 221, 54, 93, 11, 24, 6, + 245, 134, 11, 24, 5, 245, 134, 11, 24, 18, 205, 85, 11, 24, 18, 102, 11, + 24, 18, 105, 11, 24, 18, 142, 11, 24, 18, 139, 11, 24, 18, 168, 11, 24, + 18, 184, 11, 24, 18, 195, 11, 24, 18, 193, 11, 24, 18, 200, 11, 159, 18, + 205, 85, 11, 159, 18, 102, 11, 159, 18, 105, 11, 159, 18, 142, 11, 159, + 18, 139, 11, 159, 18, 168, 11, 159, 18, 184, 11, 159, 18, 195, 11, 159, + 18, 193, 11, 159, 18, 200, 11, 38, 18, 205, 85, 11, 38, 18, 102, 11, 38, + 18, 105, 11, 38, 18, 142, 11, 38, 18, 139, 11, 38, 18, 168, 11, 38, 18, + 184, 11, 38, 18, 195, 11, 38, 18, 193, 11, 38, 18, 200, 11, 38, 24, 18, + 205, 85, 11, 38, 24, 18, 102, 11, 38, 24, 18, 105, 11, 38, 24, 18, 142, + 11, 38, 24, 18, 139, 11, 38, 24, 18, 168, 11, 38, 24, 18, 184, 11, 38, + 24, 18, 195, 11, 38, 24, 18, 193, 11, 38, 24, 18, 200, 11, 226, 156, 18, + 205, 85, 11, 226, 156, 18, 102, 11, 226, 156, 18, 105, 11, 226, 156, 18, + 142, 11, 226, 156, 18, 139, 11, 226, 156, 18, 168, 11, 226, 156, 18, 184, + 11, 226, 156, 18, 195, 11, 226, 156, 18, 193, 11, 226, 156, 18, 200, 70, + 69, 4, 229, 27, 231, 123, 70, 69, 4, 229, 23, 172, 70, 69, 4, 229, 21, + 230, 236, 70, 69, 4, 228, 153, 231, 221, 70, 69, 4, 228, 123, 231, 224, + 70, 69, 4, 228, 142, 231, 33, 70, 69, 4, 228, 170, 231, 53, 70, 69, 4, + 228, 39, 230, 230, 70, 69, 4, 229, 18, 207, 20, 70, 69, 4, 229, 16, 207, + 96, 70, 69, 4, 229, 14, 206, 216, 70, 69, 4, 228, 92, 207, 45, 70, 69, 4, + 228, 100, 207, 51, 70, 69, 4, 228, 104, 206, 238, 70, 69, 4, 228, 173, + 206, 250, 70, 69, 4, 228, 24, 206, 212, 70, 69, 4, 228, 75, 207, 43, 70, + 69, 4, 228, 157, 206, 200, 70, 69, 4, 228, 169, 206, 202, 70, 69, 4, 228, + 79, 206, 201, 70, 69, 4, 229, 12, 226, 209, 70, 69, 4, 229, 10, 227, 221, + 70, 69, 4, 229, 8, 226, 89, 70, 69, 4, 228, 159, 227, 83, 70, 69, 4, 228, + 124, 226, 168, 70, 69, 4, 228, 64, 226, 111, 70, 69, 4, 228, 29, 226, + 105, 70, 69, 4, 229, 6, 249, 244, 70, 69, 4, 229, 3, 250, 183, 70, 69, 4, + 229, 1, 249, 101, 70, 69, 4, 228, 68, 250, 50, 70, 69, 4, 228, 121, 250, + 61, 70, 69, 4, 228, 115, 249, 172, 70, 69, 4, 228, 80, 249, 184, 70, 69, + 4, 228, 247, 74, 70, 69, 4, 228, 245, 62, 70, 69, 4, 228, 243, 71, 70, + 69, 4, 228, 55, 243, 104, 70, 69, 4, 228, 118, 75, 70, 69, 4, 228, 53, + 222, 152, 70, 69, 4, 228, 71, 76, 70, 69, 4, 228, 81, 243, 90, 70, 69, 4, + 228, 87, 233, 68, 70, 69, 4, 228, 83, 233, 68, 70, 69, 4, 228, 23, 252, + 122, 70, 69, 4, 228, 40, 243, 41, 70, 69, 4, 228, 232, 215, 80, 70, 69, + 4, 228, 230, 217, 199, 70, 69, 4, 228, 228, 213, 203, 70, 69, 4, 228, 56, + 217, 74, 70, 69, 4, 228, 102, 217, 86, 70, 69, 4, 228, 82, 214, 174, 70, + 69, 4, 228, 139, 214, 193, 70, 69, 4, 228, 22, 215, 79, 70, 69, 4, 228, + 218, 229, 235, 70, 69, 4, 228, 216, 230, 141, 70, 69, 4, 228, 214, 229, + 81, 70, 69, 4, 228, 134, 230, 50, 70, 69, 4, 228, 145, 230, 58, 70, 69, + 4, 228, 164, 229, 115, 70, 69, 4, 228, 65, 229, 144, 70, 69, 4, 228, 108, + 152, 230, 58, 70, 69, 4, 228, 240, 245, 168, 70, 69, 4, 228, 237, 246, + 145, 70, 69, 4, 228, 234, 243, 237, 70, 69, 4, 228, 129, 245, 251, 70, + 69, 4, 228, 38, 245, 28, 70, 69, 4, 228, 37, 245, 51, 70, 69, 4, 228, + 226, 211, 211, 70, 69, 4, 228, 223, 212, 219, 70, 69, 4, 228, 221, 210, + 170, 70, 69, 4, 228, 127, 212, 120, 70, 69, 4, 228, 163, 212, 131, 70, + 69, 4, 228, 114, 211, 105, 70, 69, 4, 228, 149, 124, 70, 69, 4, 228, 212, + 232, 162, 70, 69, 4, 228, 209, 232, 200, 70, 69, 4, 228, 207, 232, 104, + 70, 69, 4, 228, 61, 232, 180, 70, 69, 4, 228, 105, 232, 182, 70, 69, 4, + 228, 58, 232, 113, 70, 69, 4, 228, 155, 232, 122, 70, 69, 4, 228, 43, + 152, 232, 122, 70, 69, 4, 228, 205, 206, 11, 70, 69, 4, 228, 202, 190, + 70, 69, 4, 228, 200, 205, 213, 70, 69, 4, 228, 109, 206, 49, 70, 69, 4, + 228, 138, 206, 52, 70, 69, 4, 228, 77, 205, 232, 70, 69, 4, 228, 97, 205, + 247, 70, 69, 4, 228, 196, 241, 250, 70, 69, 4, 228, 194, 242, 73, 70, 69, + 4, 228, 192, 241, 88, 70, 69, 4, 228, 140, 242, 21, 70, 69, 4, 228, 143, + 242, 28, 70, 69, 4, 228, 85, 241, 151, 70, 69, 4, 228, 130, 241, 162, 70, + 69, 4, 228, 21, 241, 87, 70, 69, 4, 228, 117, 242, 47, 70, 69, 4, 228, + 190, 224, 199, 70, 69, 4, 228, 188, 225, 209, 70, 69, 4, 228, 186, 223, + 173, 70, 69, 4, 228, 101, 225, 101, 70, 69, 4, 228, 49, 224, 61, 70, 69, + 4, 228, 42, 239, 11, 70, 69, 4, 228, 181, 155, 70, 69, 4, 228, 32, 238, + 42, 70, 69, 4, 228, 184, 239, 53, 70, 69, 4, 228, 122, 239, 71, 70, 69, + 4, 228, 179, 238, 131, 70, 69, 4, 228, 78, 238, 149, 70, 69, 4, 228, 135, + 239, 52, 70, 69, 4, 228, 90, 238, 125, 70, 69, 4, 228, 165, 238, 246, 70, + 69, 4, 228, 88, 239, 110, 70, 69, 4, 228, 131, 238, 31, 70, 69, 4, 228, + 166, 239, 41, 70, 69, 4, 228, 25, 238, 134, 70, 69, 4, 228, 172, 238, 41, + 70, 69, 4, 228, 128, 225, 42, 70, 69, 4, 228, 177, 225, 56, 70, 69, 4, + 228, 136, 225, 39, 70, 69, 4, 228, 103, 225, 50, 70, 69, 4, 228, 72, 225, + 51, 70, 69, 4, 228, 62, 225, 40, 70, 69, 4, 228, 98, 225, 41, 70, 69, 4, + 228, 59, 225, 55, 70, 69, 4, 228, 91, 225, 38, 70, 69, 4, 228, 132, 152, + 225, 51, 70, 69, 4, 228, 112, 152, 225, 40, 70, 69, 4, 228, 35, 152, 225, + 41, 70, 69, 4, 228, 63, 240, 61, 70, 69, 4, 228, 107, 240, 244, 70, 69, + 4, 228, 50, 239, 213, 70, 69, 4, 228, 28, 240, 162, 70, 69, 4, 228, 52, + 239, 199, 70, 69, 4, 228, 51, 239, 209, 70, 69, 4, 228, 34, 225, 61, 70, + 69, 4, 228, 161, 224, 254, 70, 69, 4, 228, 41, 224, 243, 70, 69, 4, 228, + 150, 221, 53, 70, 69, 4, 228, 119, 179, 70, 69, 4, 228, 168, 220, 82, 70, + 69, 4, 228, 137, 221, 164, 70, 69, 4, 228, 167, 221, 174, 70, 69, 4, 228, + 116, 220, 187, 70, 69, 4, 228, 152, 220, 211, 70, 69, 4, 228, 73, 227, + 138, 70, 69, 4, 228, 156, 227, 153, 70, 69, 4, 228, 96, 227, 132, 70, 69, + 4, 228, 171, 227, 145, 70, 69, 4, 228, 30, 227, 145, 70, 69, 4, 228, 146, + 227, 146, 70, 69, 4, 228, 46, 227, 133, 70, 69, 4, 228, 44, 227, 134, 70, + 69, 4, 228, 31, 227, 126, 70, 69, 4, 228, 57, 152, 227, 146, 70, 69, 4, + 228, 113, 152, 227, 133, 70, 69, 4, 228, 76, 152, 227, 134, 70, 69, 4, + 228, 86, 231, 7, 70, 69, 4, 228, 126, 231, 15, 70, 69, 4, 228, 144, 231, + 3, 70, 69, 4, 228, 175, 231, 10, 70, 69, 4, 228, 110, 231, 11, 70, 69, 4, + 228, 106, 231, 5, 70, 69, 4, 228, 60, 231, 6, 70, 69, 4, 228, 94, 240, + 179, 70, 69, 4, 228, 162, 240, 187, 70, 69, 4, 228, 70, 240, 174, 70, 69, + 4, 228, 125, 240, 183, 70, 69, 4, 228, 111, 240, 184, 70, 69, 4, 228, + 147, 240, 175, 70, 69, 4, 228, 148, 240, 177, 70, 69, 4, 228, 47, 219, + 113, 70, 69, 4, 228, 95, 225, 136, 70, 69, 4, 228, 89, 225, 151, 70, 69, + 4, 228, 93, 225, 118, 70, 69, 4, 228, 27, 225, 142, 70, 69, 4, 228, 99, + 225, 143, 70, 69, 4, 228, 151, 225, 123, 70, 69, 4, 228, 154, 225, 127, + 70, 69, 4, 228, 66, 224, 180, 70, 69, 4, 228, 26, 224, 150, 70, 69, 4, + 228, 69, 224, 171, 70, 69, 4, 228, 84, 224, 154, 70, 69, 4, 228, 36, 208, + 214, 70, 69, 4, 228, 33, 209, 70, 70, 69, 4, 228, 67, 207, 148, 70, 69, + 4, 228, 45, 209, 34, 70, 69, 4, 228, 133, 209, 39, 70, 69, 4, 228, 74, + 208, 161, 70, 69, 4, 228, 141, 208, 173, 70, 69, 4, 228, 54, 223, 119, + 70, 69, 4, 228, 160, 223, 138, 70, 69, 4, 228, 48, 223, 101, 70, 69, 4, + 228, 120, 223, 130, 70, 69, 4, 228, 158, 223, 108, 70, 69, 18, 102, 70, + 69, 18, 105, 70, 69, 18, 142, 70, 69, 18, 139, 70, 69, 18, 168, 70, 69, + 18, 184, 70, 69, 18, 195, 70, 69, 18, 193, 70, 69, 18, 200, 70, 69, 36, + 43, 212, 118, 70, 69, 36, 43, 212, 93, 70, 69, 36, 43, 238, 28, 70, 69, + 36, 43, 211, 240, 70, 69, 36, 43, 212, 99, 211, 240, 70, 69, 36, 43, 238, + 30, 211, 240, 70, 69, 36, 43, 226, 212, 8, 11, 252, 172, 8, 11, 250, 38, + 8, 11, 232, 179, 8, 11, 246, 117, 8, 11, 207, 59, 8, 11, 205, 108, 8, 11, + 239, 132, 8, 11, 212, 194, 8, 11, 206, 47, 8, 11, 232, 45, 8, 11, 230, + 106, 8, 11, 227, 104, 8, 11, 224, 54, 8, 11, 217, 70, 8, 11, 252, 200, 8, + 11, 242, 15, 8, 11, 217, 191, 8, 11, 220, 12, 8, 11, 219, 16, 8, 11, 215, + 210, 8, 11, 212, 115, 8, 11, 212, 37, 8, 11, 231, 163, 8, 11, 212, 49, 8, + 11, 246, 140, 8, 11, 205, 111, 8, 11, 240, 94, 8, 11, 245, 22, 250, 38, + 8, 11, 245, 22, 224, 54, 8, 11, 245, 22, 242, 15, 8, 11, 245, 22, 220, + 12, 8, 11, 78, 250, 38, 8, 11, 78, 232, 179, 8, 11, 78, 239, 50, 8, 11, + 78, 239, 132, 8, 11, 78, 206, 47, 8, 11, 78, 232, 45, 8, 11, 78, 230, + 106, 8, 11, 78, 227, 104, 8, 11, 78, 224, 54, 8, 11, 78, 217, 70, 8, 11, + 78, 252, 200, 8, 11, 78, 242, 15, 8, 11, 78, 217, 191, 8, 11, 78, 220, + 12, 8, 11, 78, 215, 210, 8, 11, 78, 212, 115, 8, 11, 78, 212, 37, 8, 11, + 78, 231, 163, 8, 11, 78, 246, 140, 8, 11, 78, 240, 94, 8, 11, 212, 190, + 232, 179, 8, 11, 212, 190, 239, 132, 8, 11, 212, 190, 206, 47, 8, 11, + 212, 190, 230, 106, 8, 11, 212, 190, 224, 54, 8, 11, 212, 190, 217, 70, + 8, 11, 212, 190, 252, 200, 8, 11, 212, 190, 217, 191, 8, 11, 212, 190, + 220, 12, 8, 11, 212, 190, 215, 210, 8, 11, 212, 190, 231, 163, 8, 11, + 212, 190, 246, 140, 8, 11, 212, 190, 240, 94, 8, 11, 212, 190, 245, 22, + 224, 54, 8, 11, 212, 190, 245, 22, 220, 12, 8, 11, 213, 232, 250, 38, 8, + 11, 213, 232, 232, 179, 8, 11, 213, 232, 239, 50, 8, 11, 213, 232, 239, + 132, 8, 11, 213, 232, 212, 194, 8, 11, 213, 232, 206, 47, 8, 11, 213, + 232, 232, 45, 8, 11, 213, 232, 227, 104, 8, 11, 213, 232, 224, 54, 8, 11, + 213, 232, 217, 70, 8, 11, 213, 232, 252, 200, 8, 11, 213, 232, 242, 15, + 8, 11, 213, 232, 217, 191, 8, 11, 213, 232, 220, 12, 8, 11, 213, 232, + 215, 210, 8, 11, 213, 232, 212, 115, 8, 11, 213, 232, 212, 37, 8, 11, + 213, 232, 231, 163, 8, 11, 213, 232, 246, 140, 8, 11, 213, 232, 205, 111, + 8, 11, 213, 232, 240, 94, 8, 11, 213, 232, 245, 22, 250, 38, 8, 11, 213, + 232, 245, 22, 242, 15, 8, 11, 229, 110, 252, 172, 8, 11, 229, 110, 250, + 38, 8, 11, 229, 110, 232, 179, 8, 11, 229, 110, 246, 117, 8, 11, 229, + 110, 239, 50, 8, 11, 229, 110, 207, 59, 8, 11, 229, 110, 205, 108, 8, 11, + 229, 110, 239, 132, 8, 11, 229, 110, 212, 194, 8, 11, 229, 110, 206, 47, + 8, 11, 229, 110, 230, 106, 8, 11, 229, 110, 227, 104, 8, 11, 229, 110, + 224, 54, 8, 11, 229, 110, 217, 70, 8, 11, 229, 110, 252, 200, 8, 11, 229, + 110, 242, 15, 8, 11, 229, 110, 217, 191, 8, 11, 229, 110, 220, 12, 8, 11, + 229, 110, 219, 16, 8, 11, 229, 110, 215, 210, 8, 11, 229, 110, 212, 115, + 8, 11, 229, 110, 212, 37, 8, 11, 229, 110, 231, 163, 8, 11, 229, 110, + 212, 49, 8, 11, 229, 110, 246, 140, 8, 11, 229, 110, 205, 111, 8, 11, + 229, 110, 240, 94, 8, 11, 159, 250, 38, 8, 11, 159, 232, 179, 8, 11, 159, + 246, 117, 8, 11, 159, 207, 59, 8, 11, 159, 205, 108, 8, 11, 159, 239, + 132, 8, 11, 159, 212, 194, 8, 11, 159, 206, 47, 8, 11, 159, 230, 106, 8, + 11, 159, 227, 104, 8, 11, 159, 224, 54, 8, 11, 159, 217, 70, 8, 11, 159, + 252, 200, 8, 11, 159, 242, 15, 8, 11, 159, 217, 191, 8, 11, 159, 220, 12, + 8, 11, 159, 219, 16, 8, 11, 159, 215, 210, 8, 11, 159, 212, 115, 8, 11, + 159, 212, 37, 8, 11, 159, 231, 163, 8, 11, 159, 212, 49, 8, 11, 159, 246, + 140, 8, 11, 159, 205, 111, 8, 11, 159, 240, 94, 8, 11, 222, 133, 80, 2, + 140, 2, 212, 153, 8, 11, 222, 133, 140, 2, 246, 117, 227, 241, 94, 243, + 117, 207, 9, 227, 241, 94, 188, 207, 9, 227, 241, 94, 207, 36, 207, 9, + 227, 241, 94, 143, 207, 9, 227, 241, 94, 219, 32, 243, 255, 227, 241, 94, + 239, 227, 243, 255, 227, 241, 94, 59, 243, 255, 227, 241, 94, 119, 73, + 248, 93, 227, 241, 94, 118, 73, 248, 93, 227, 241, 94, 129, 73, 248, 93, + 227, 241, 94, 241, 125, 73, 248, 93, 227, 241, 94, 241, 204, 73, 248, 93, + 227, 241, 94, 215, 10, 73, 248, 93, 227, 241, 94, 216, 23, 73, 248, 93, + 227, 241, 94, 243, 88, 73, 248, 93, 227, 241, 94, 224, 195, 73, 248, 93, + 227, 241, 94, 119, 73, 250, 141, 227, 241, 94, 118, 73, 250, 141, 227, + 241, 94, 129, 73, 250, 141, 227, 241, 94, 241, 125, 73, 250, 141, 227, + 241, 94, 241, 204, 73, 250, 141, 227, 241, 94, 215, 10, 73, 250, 141, + 227, 241, 94, 216, 23, 73, 250, 141, 227, 241, 94, 243, 88, 73, 250, 141, + 227, 241, 94, 224, 195, 73, 250, 141, 227, 241, 94, 119, 73, 247, 232, + 227, 241, 94, 118, 73, 247, 232, 227, 241, 94, 129, 73, 247, 232, 227, + 241, 94, 241, 125, 73, 247, 232, 227, 241, 94, 241, 204, 73, 247, 232, + 227, 241, 94, 215, 10, 73, 247, 232, 227, 241, 94, 216, 23, 73, 247, 232, + 227, 241, 94, 243, 88, 73, 247, 232, 227, 241, 94, 224, 195, 73, 247, + 232, 227, 241, 94, 220, 221, 227, 241, 94, 222, 120, 227, 241, 94, 250, + 142, 227, 241, 94, 248, 15, 227, 241, 94, 214, 113, 227, 241, 94, 213, + 156, 227, 241, 94, 251, 171, 227, 241, 94, 207, 1, 227, 241, 94, 232, + 116, 227, 241, 94, 250, 176, 151, 94, 194, 250, 176, 151, 94, 238, 120, + 151, 94, 238, 119, 151, 94, 238, 118, 151, 94, 238, 117, 151, 94, 238, + 116, 151, 94, 238, 115, 151, 94, 238, 114, 151, 94, 238, 113, 151, 94, + 238, 112, 151, 94, 238, 111, 151, 94, 238, 110, 151, 94, 238, 109, 151, + 94, 238, 108, 151, 94, 238, 107, 151, 94, 238, 106, 151, 94, 238, 105, + 151, 94, 238, 104, 151, 94, 238, 103, 151, 94, 238, 102, 151, 94, 238, + 101, 151, 94, 238, 100, 151, 94, 238, 99, 151, 94, 238, 98, 151, 94, 238, + 97, 151, 94, 238, 96, 151, 94, 238, 95, 151, 94, 238, 94, 151, 94, 238, + 93, 151, 94, 238, 92, 151, 94, 238, 91, 151, 94, 238, 90, 151, 94, 238, + 89, 151, 94, 238, 88, 151, 94, 238, 87, 151, 94, 238, 86, 151, 94, 238, + 85, 151, 94, 238, 84, 151, 94, 238, 83, 151, 94, 238, 82, 151, 94, 238, + 81, 151, 94, 238, 80, 151, 94, 238, 79, 151, 94, 238, 78, 151, 94, 238, + 77, 151, 94, 238, 76, 151, 94, 238, 75, 151, 94, 238, 74, 151, 94, 238, + 73, 151, 94, 238, 72, 151, 94, 79, 250, 176, 151, 94, 209, 21, 151, 94, + 209, 20, 151, 94, 209, 19, 151, 94, 209, 18, 151, 94, 209, 17, 151, 94, + 209, 16, 151, 94, 209, 15, 151, 94, 209, 14, 151, 94, 209, 13, 151, 94, + 209, 12, 151, 94, 209, 11, 151, 94, 209, 10, 151, 94, 209, 9, 151, 94, + 209, 8, 151, 94, 209, 7, 151, 94, 209, 6, 151, 94, 209, 5, 151, 94, 209, + 4, 151, 94, 209, 3, 151, 94, 209, 2, 151, 94, 209, 1, 151, 94, 209, 0, + 151, 94, 208, 255, 151, 94, 208, 254, 151, 94, 208, 253, 151, 94, 208, + 252, 151, 94, 208, 251, 151, 94, 208, 250, 151, 94, 208, 249, 151, 94, + 208, 248, 151, 94, 208, 247, 151, 94, 208, 246, 151, 94, 208, 245, 151, + 94, 208, 244, 151, 94, 208, 243, 151, 94, 208, 242, 151, 94, 208, 241, + 151, 94, 208, 240, 151, 94, 208, 239, 151, 94, 208, 238, 151, 94, 208, + 237, 151, 94, 208, 236, 151, 94, 208, 235, 151, 94, 208, 234, 151, 94, + 208, 233, 151, 94, 208, 232, 151, 94, 208, 231, 151, 94, 208, 230, 151, + 94, 208, 229, 220, 230, 191, 250, 176, 220, 230, 191, 253, 15, 73, 214, + 150, 220, 230, 191, 118, 73, 214, 150, 220, 230, 191, 129, 73, 214, 150, + 220, 230, 191, 241, 125, 73, 214, 150, 220, 230, 191, 241, 204, 73, 214, + 150, 220, 230, 191, 215, 10, 73, 214, 150, 220, 230, 191, 216, 23, 73, + 214, 150, 220, 230, 191, 243, 88, 73, 214, 150, 220, 230, 191, 224, 195, + 73, 214, 150, 220, 230, 191, 212, 99, 73, 214, 150, 220, 230, 191, 232, + 198, 73, 214, 150, 220, 230, 191, 231, 57, 73, 214, 150, 220, 230, 191, + 219, 198, 73, 214, 150, 220, 230, 191, 231, 107, 73, 214, 150, 220, 230, + 191, 253, 15, 73, 239, 58, 220, 230, 191, 118, 73, 239, 58, 220, 230, + 191, 129, 73, 239, 58, 220, 230, 191, 241, 125, 73, 239, 58, 220, 230, + 191, 241, 204, 73, 239, 58, 220, 230, 191, 215, 10, 73, 239, 58, 220, + 230, 191, 216, 23, 73, 239, 58, 220, 230, 191, 243, 88, 73, 239, 58, 220, + 230, 191, 224, 195, 73, 239, 58, 220, 230, 191, 212, 99, 73, 239, 58, + 220, 230, 191, 232, 198, 73, 239, 58, 220, 230, 191, 231, 57, 73, 239, + 58, 220, 230, 191, 219, 198, 73, 239, 58, 220, 230, 191, 231, 107, 73, + 239, 58, 220, 230, 191, 219, 32, 232, 116, 220, 230, 191, 253, 15, 73, + 245, 155, 220, 230, 191, 118, 73, 245, 155, 220, 230, 191, 129, 73, 245, + 155, 220, 230, 191, 241, 125, 73, 245, 155, 220, 230, 191, 241, 204, 73, + 245, 155, 220, 230, 191, 215, 10, 73, 245, 155, 220, 230, 191, 216, 23, + 73, 245, 155, 220, 230, 191, 243, 88, 73, 245, 155, 220, 230, 191, 224, + 195, 73, 245, 155, 220, 230, 191, 212, 99, 73, 245, 155, 220, 230, 191, + 232, 198, 73, 245, 155, 220, 230, 191, 231, 57, 73, 245, 155, 220, 230, + 191, 219, 198, 73, 245, 155, 220, 230, 191, 231, 107, 73, 245, 155, 220, + 230, 191, 60, 232, 116, 220, 230, 191, 253, 15, 73, 247, 178, 220, 230, + 191, 118, 73, 247, 178, 220, 230, 191, 129, 73, 247, 178, 220, 230, 191, + 241, 125, 73, 247, 178, 220, 230, 191, 241, 204, 73, 247, 178, 220, 230, + 191, 215, 10, 73, 247, 178, 220, 230, 191, 216, 23, 73, 247, 178, 220, + 230, 191, 243, 88, 73, 247, 178, 220, 230, 191, 224, 195, 73, 247, 178, + 220, 230, 191, 212, 99, 73, 247, 178, 220, 230, 191, 232, 198, 73, 247, + 178, 220, 230, 191, 231, 57, 73, 247, 178, 220, 230, 191, 219, 198, 73, + 247, 178, 220, 230, 191, 231, 107, 73, 247, 178, 220, 230, 191, 59, 232, + 116, 220, 230, 191, 241, 149, 220, 230, 191, 211, 15, 220, 230, 191, 211, + 4, 220, 230, 191, 211, 1, 220, 230, 191, 211, 0, 220, 230, 191, 210, 255, + 220, 230, 191, 210, 254, 220, 230, 191, 210, 253, 220, 230, 191, 210, + 252, 220, 230, 191, 210, 251, 220, 230, 191, 211, 14, 220, 230, 191, 211, + 13, 220, 230, 191, 211, 12, 220, 230, 191, 211, 11, 220, 230, 191, 211, + 10, 220, 230, 191, 211, 9, 220, 230, 191, 211, 8, 220, 230, 191, 211, 7, + 220, 230, 191, 211, 6, 220, 230, 191, 211, 5, 220, 230, 191, 211, 3, 220, + 230, 191, 211, 2, 18, 205, 86, 241, 82, 213, 251, 18, 205, 86, 247, 155, + 18, 119, 247, 155, 18, 118, 247, 155, 18, 129, 247, 155, 18, 241, 125, + 247, 155, 18, 241, 204, 247, 155, 18, 215, 10, 247, 155, 18, 216, 23, + 247, 155, 18, 243, 88, 247, 155, 18, 224, 195, 247, 155, 245, 111, 39, + 38, 18, 205, 85, 245, 111, 170, 39, 38, 18, 205, 85, 97, 7, 6, 1, 62, 97, + 7, 6, 1, 251, 150, 97, 7, 6, 1, 249, 34, 97, 7, 6, 1, 246, 240, 97, 7, 6, + 1, 75, 97, 7, 6, 1, 242, 139, 97, 7, 6, 1, 241, 55, 97, 7, 6, 1, 239, + 155, 97, 7, 6, 1, 74, 97, 7, 6, 1, 232, 203, 97, 7, 6, 1, 232, 76, 97, 7, + 6, 1, 149, 97, 7, 6, 1, 229, 28, 97, 7, 6, 1, 226, 33, 97, 7, 6, 1, 76, + 97, 7, 6, 1, 222, 67, 97, 7, 6, 1, 220, 27, 97, 7, 6, 1, 137, 97, 7, 6, + 1, 182, 97, 7, 6, 1, 213, 10, 97, 7, 6, 1, 71, 97, 7, 6, 1, 209, 148, 97, + 7, 6, 1, 207, 129, 97, 7, 6, 1, 206, 195, 97, 7, 6, 1, 206, 123, 97, 7, + 6, 1, 205, 159, 211, 93, 215, 204, 249, 133, 7, 6, 1, 182, 39, 35, 7, 6, + 1, 249, 34, 39, 35, 7, 6, 1, 137, 39, 248, 149, 39, 206, 197, 98, 7, 6, + 1, 62, 98, 7, 6, 1, 251, 150, 98, 7, 6, 1, 249, 34, 98, 7, 6, 1, 246, + 240, 98, 7, 6, 1, 75, 98, 7, 6, 1, 242, 139, 98, 7, 6, 1, 241, 55, 98, 7, + 6, 1, 239, 155, 98, 7, 6, 1, 74, 98, 7, 6, 1, 232, 203, 98, 7, 6, 1, 232, + 76, 98, 7, 6, 1, 149, 98, 7, 6, 1, 229, 28, 98, 7, 6, 1, 226, 33, 98, 7, + 6, 1, 76, 98, 7, 6, 1, 222, 67, 98, 7, 6, 1, 220, 27, 98, 7, 6, 1, 137, + 98, 7, 6, 1, 182, 98, 7, 6, 1, 213, 10, 98, 7, 6, 1, 71, 98, 7, 6, 1, + 209, 148, 98, 7, 6, 1, 207, 129, 98, 7, 6, 1, 206, 195, 98, 7, 6, 1, 206, + 123, 98, 7, 6, 1, 205, 159, 98, 238, 17, 98, 226, 57, 98, 217, 88, 98, + 214, 99, 98, 220, 155, 98, 207, 52, 170, 39, 7, 6, 1, 62, 170, 39, 7, 6, + 1, 251, 150, 170, 39, 7, 6, 1, 249, 34, 170, 39, 7, 6, 1, 246, 240, 170, + 39, 7, 6, 1, 75, 170, 39, 7, 6, 1, 242, 139, 170, 39, 7, 6, 1, 241, 55, + 170, 39, 7, 6, 1, 239, 155, 170, 39, 7, 6, 1, 74, 170, 39, 7, 6, 1, 232, + 203, 170, 39, 7, 6, 1, 232, 76, 170, 39, 7, 6, 1, 149, 170, 39, 7, 6, 1, + 229, 28, 170, 39, 7, 6, 1, 226, 33, 170, 39, 7, 6, 1, 76, 170, 39, 7, 6, + 1, 222, 67, 170, 39, 7, 6, 1, 220, 27, 170, 39, 7, 6, 1, 137, 170, 39, 7, + 6, 1, 182, 170, 39, 7, 6, 1, 213, 10, 170, 39, 7, 6, 1, 71, 170, 39, 7, + 6, 1, 209, 148, 170, 39, 7, 6, 1, 207, 129, 170, 39, 7, 6, 1, 206, 195, + 170, 39, 7, 6, 1, 206, 123, 170, 39, 7, 6, 1, 205, 159, 219, 81, 227, + 125, 53, 219, 81, 227, 122, 53, 170, 98, 7, 6, 1, 62, 170, 98, 7, 6, 1, + 251, 150, 170, 98, 7, 6, 1, 249, 34, 170, 98, 7, 6, 1, 246, 240, 170, 98, + 7, 6, 1, 75, 170, 98, 7, 6, 1, 242, 139, 170, 98, 7, 6, 1, 241, 55, 170, + 98, 7, 6, 1, 239, 155, 170, 98, 7, 6, 1, 74, 170, 98, 7, 6, 1, 232, 203, + 170, 98, 7, 6, 1, 232, 76, 170, 98, 7, 6, 1, 149, 170, 98, 7, 6, 1, 229, + 28, 170, 98, 7, 6, 1, 226, 33, 170, 98, 7, 6, 1, 76, 170, 98, 7, 6, 1, + 222, 67, 170, 98, 7, 6, 1, 220, 27, 170, 98, 7, 6, 1, 137, 170, 98, 7, 6, + 1, 182, 170, 98, 7, 6, 1, 213, 10, 170, 98, 7, 6, 1, 71, 170, 98, 7, 6, + 1, 209, 148, 170, 98, 7, 6, 1, 207, 129, 170, 98, 7, 6, 1, 206, 195, 170, + 98, 7, 6, 1, 206, 123, 170, 98, 7, 6, 1, 205, 159, 247, 57, 170, 98, 7, + 6, 1, 222, 67, 170, 98, 237, 183, 170, 98, 179, 170, 98, 217, 199, 170, + 98, 253, 115, 170, 98, 207, 52, 49, 245, 70, 98, 247, 218, 98, 247, 101, + 98, 241, 107, 98, 237, 174, 98, 225, 87, 98, 225, 79, 98, 222, 185, 98, + 214, 169, 98, 120, 2, 242, 168, 83, 98, 208, 151, 219, 24, 233, 50, 16, + 1, 62, 219, 24, 233, 50, 16, 1, 251, 150, 219, 24, 233, 50, 16, 1, 249, + 34, 219, 24, 233, 50, 16, 1, 246, 240, 219, 24, 233, 50, 16, 1, 75, 219, + 24, 233, 50, 16, 1, 242, 139, 219, 24, 233, 50, 16, 1, 241, 55, 219, 24, + 233, 50, 16, 1, 239, 155, 219, 24, 233, 50, 16, 1, 74, 219, 24, 233, 50, + 16, 1, 232, 203, 219, 24, 233, 50, 16, 1, 232, 76, 219, 24, 233, 50, 16, + 1, 149, 219, 24, 233, 50, 16, 1, 229, 28, 219, 24, 233, 50, 16, 1, 226, + 33, 219, 24, 233, 50, 16, 1, 76, 219, 24, 233, 50, 16, 1, 222, 67, 219, + 24, 233, 50, 16, 1, 220, 27, 219, 24, 233, 50, 16, 1, 137, 219, 24, 233, + 50, 16, 1, 182, 219, 24, 233, 50, 16, 1, 213, 10, 219, 24, 233, 50, 16, + 1, 71, 219, 24, 233, 50, 16, 1, 209, 148, 219, 24, 233, 50, 16, 1, 207, + 129, 219, 24, 233, 50, 16, 1, 206, 195, 219, 24, 233, 50, 16, 1, 206, + 123, 219, 24, 233, 50, 16, 1, 205, 159, 49, 161, 238, 144, 98, 64, 231, + 41, 98, 64, 217, 199, 98, 10, 209, 220, 235, 119, 98, 10, 209, 220, 235, + 123, 98, 10, 209, 220, 235, 131, 98, 64, 246, 9, 98, 10, 209, 220, 235, + 138, 98, 10, 209, 220, 235, 125, 98, 10, 209, 220, 235, 97, 98, 10, 209, + 220, 235, 124, 98, 10, 209, 220, 235, 137, 98, 10, 209, 220, 235, 111, + 98, 10, 209, 220, 235, 104, 98, 10, 209, 220, 235, 113, 98, 10, 209, 220, + 235, 134, 98, 10, 209, 220, 235, 120, 98, 10, 209, 220, 235, 136, 98, 10, + 209, 220, 235, 112, 98, 10, 209, 220, 235, 135, 98, 10, 209, 220, 235, + 98, 98, 10, 209, 220, 235, 103, 98, 10, 209, 220, 235, 96, 98, 10, 209, + 220, 235, 126, 98, 10, 209, 220, 235, 128, 98, 10, 209, 220, 235, 106, + 98, 10, 209, 220, 235, 117, 98, 10, 209, 220, 235, 115, 98, 10, 209, 220, + 235, 141, 98, 10, 209, 220, 235, 140, 98, 10, 209, 220, 235, 94, 98, 10, + 209, 220, 235, 121, 98, 10, 209, 220, 235, 139, 98, 10, 209, 220, 235, + 130, 98, 10, 209, 220, 235, 116, 98, 10, 209, 220, 235, 95, 98, 10, 209, + 220, 235, 118, 98, 10, 209, 220, 235, 100, 98, 10, 209, 220, 235, 99, 98, + 10, 209, 220, 235, 129, 98, 10, 209, 220, 235, 107, 98, 10, 209, 220, + 235, 109, 98, 10, 209, 220, 235, 110, 98, 10, 209, 220, 235, 102, 98, 10, + 209, 220, 235, 133, 98, 10, 209, 220, 235, 127, 211, 93, 215, 204, 249, + 133, 10, 209, 220, 235, 108, 211, 93, 215, 204, 249, 133, 10, 209, 220, + 235, 140, 211, 93, 215, 204, 249, 133, 10, 209, 220, 235, 138, 211, 93, + 215, 204, 249, 133, 10, 209, 220, 235, 122, 211, 93, 215, 204, 249, 133, + 10, 209, 220, 235, 105, 211, 93, 215, 204, 249, 133, 10, 209, 220, 235, + 118, 211, 93, 215, 204, 249, 133, 10, 209, 220, 235, 101, 211, 93, 215, + 204, 249, 133, 10, 209, 220, 235, 132, 211, 93, 215, 204, 249, 133, 10, + 209, 220, 235, 114, 39, 175, 252, 250, 39, 175, 253, 19, 246, 251, 241, + 160, 247, 192, 209, 238, 224, 210, 2, 214, 23, 213, 149, 131, 226, 127, + 213, 148, 247, 222, 251, 200, 243, 213, 213, 147, 131, 249, 90, 219, 82, + 249, 116, 251, 200, 224, 209, 207, 70, 207, 64, 208, 165, 226, 217, 207, + 54, 243, 121, 240, 26, 242, 182, 243, 121, 240, 26, 252, 128, 243, 121, + 240, 26, 251, 218, 240, 26, 2, 227, 75, 186, 226, 145, 93, 207, 56, 247, + 66, 226, 145, 93, 241, 215, 219, 205, 226, 145, 93, 207, 56, 240, 57, + 226, 145, 93, 241, 82, 226, 145, 93, 207, 82, 240, 57, 226, 145, 93, 230, + 81, 219, 205, 226, 145, 93, 207, 82, 247, 66, 226, 145, 93, 247, 66, 226, + 144, 186, 226, 145, 2, 242, 67, 241, 215, 219, 205, 226, 145, 2, 242, 67, + 230, 81, 219, 205, 226, 145, 2, 242, 67, 241, 82, 226, 145, 2, 242, 67, + 213, 155, 2, 242, 67, 240, 24, 214, 26, 215, 149, 214, 26, 212, 29, 60, + 243, 244, 59, 213, 154, 59, 213, 155, 2, 5, 247, 183, 59, 213, 155, 250, + 35, 247, 183, 59, 213, 155, 250, 35, 247, 184, 2, 219, 83, 247, 184, 2, + 219, 83, 247, 184, 2, 214, 199, 247, 184, 2, 229, 220, 247, 184, 2, 211, + 94, 241, 161, 207, 10, 249, 188, 242, 67, 248, 64, 217, 72, 242, 176, + 211, 61, 246, 3, 211, 61, 222, 19, 211, 61, 248, 250, 238, 63, 221, 133, + 210, 160, 248, 67, 249, 190, 218, 101, 239, 10, 213, 152, 249, 190, 243, + 125, 73, 227, 230, 243, 125, 73, 218, 203, 239, 36, 241, 125, 230, 54, + 247, 182, 227, 203, 230, 53, 242, 51, 230, 53, 230, 54, 241, 167, 233, + 69, 207, 9, 226, 66, 211, 122, 251, 183, 239, 243, 227, 92, 207, 68, 212, + 169, 230, 23, 250, 137, 221, 6, 219, 32, 252, 50, 239, 227, 252, 50, 221, + 170, 221, 171, 248, 68, 213, 236, 239, 116, 214, 229, 73, 220, 242, 227, + 115, 222, 166, 249, 173, 220, 166, 230, 34, 218, 204, 247, 72, 218, 204, + 250, 149, 247, 104, 218, 203, 247, 22, 23, 218, 203, 214, 11, 249, 144, + 214, 149, 249, 127, 241, 106, 241, 102, 218, 120, 213, 105, 220, 168, + 246, 97, 222, 208, 213, 123, 241, 103, 215, 121, 241, 214, 248, 244, 2, + 213, 98, 245, 204, 214, 187, 237, 182, 247, 70, 215, 222, 237, 181, 237, + 182, 247, 70, 244, 11, 247, 103, 248, 30, 134, 248, 216, 229, 129, 247, + 14, 238, 133, 220, 170, 215, 133, 250, 18, 249, 140, 220, 171, 73, 241, + 150, 247, 102, 241, 140, 23, 231, 58, 212, 128, 206, 253, 239, 105, 217, + 176, 249, 156, 23, 247, 29, 207, 6, 240, 29, 247, 171, 240, 29, 211, 18, + 243, 249, 250, 46, 226, 103, 247, 199, 250, 46, 226, 102, 250, 179, 249, + 155, 241, 140, 23, 231, 59, 2, 220, 231, 218, 205, 206, 222, 220, 132, + 249, 216, 248, 243, 232, 197, 248, 22, 211, 61, 242, 36, 248, 21, 241, + 217, 241, 218, 214, 147, 250, 148, 221, 206, 220, 182, 247, 137, 250, + 149, 212, 173, 211, 61, 247, 57, 241, 190, 221, 7, 246, 0, 232, 189, 245, + 34, 248, 193, 213, 235, 207, 10, 248, 46, 226, 145, 208, 201, 248, 115, + 217, 104, 217, 131, 239, 248, 248, 213, 239, 61, 2, 211, 167, 222, 166, + 212, 42, 230, 46, 249, 149, 73, 241, 171, 226, 218, 227, 112, 219, 5, + 218, 205, 30, 231, 173, 2, 232, 196, 213, 208, 226, 251, 229, 254, 214, + 227, 247, 109, 231, 55, 250, 58, 251, 228, 30, 224, 32, 250, 58, 245, + 210, 30, 224, 32, 241, 231, 241, 111, 252, 253, 211, 205, 248, 194, 238, + 65, 242, 3, 207, 26, 218, 111, 247, 172, 241, 209, 220, 196, 23, 241, + 213, 226, 251, 226, 121, 248, 230, 247, 237, 239, 65, 251, 235, 222, 22, + 211, 102, 239, 86, 247, 226, 212, 92, 211, 206, 247, 213, 249, 181, 221, + 126, 251, 234, 208, 210, 240, 218, 245, 104, 238, 242, 214, 220, 228, 15, + 249, 227, 240, 219, 245, 148, 249, 143, 241, 173, 220, 230, 248, 202, 30, + 224, 37, 226, 95, 30, 224, 32, 217, 117, 239, 197, 30, 231, 172, 210, + 250, 208, 190, 30, 217, 97, 218, 33, 215, 162, 2, 217, 134, 212, 95, 219, + 102, 23, 250, 149, 214, 245, 23, 214, 245, 249, 166, 250, 111, 23, 238, + 127, 248, 69, 241, 196, 214, 198, 218, 34, 213, 128, 214, 117, 227, 112, + 211, 19, 238, 66, 219, 103, 252, 129, 241, 147, 218, 45, 241, 147, 213, + 100, 207, 41, 229, 224, 240, 10, 219, 104, 226, 134, 219, 104, 248, 204, + 214, 200, 248, 209, 226, 128, 248, 228, 250, 60, 2, 209, 238, 249, 92, + 247, 122, 238, 55, 249, 90, 247, 221, 245, 214, 238, 55, 249, 91, 247, + 211, 249, 91, 245, 206, 245, 207, 232, 227, 225, 193, 221, 212, 214, 36, + 238, 55, 249, 91, 238, 55, 2, 240, 202, 222, 201, 249, 91, 232, 189, 220, + 176, 222, 200, 242, 181, 220, 176, 222, 200, 238, 64, 250, 133, 251, 173, + 212, 103, 228, 15, 238, 60, 229, 98, 238, 60, 247, 107, 213, 247, 217, + 103, 245, 216, 213, 247, 242, 57, 232, 208, 230, 91, 232, 189, 248, 185, + 242, 181, 248, 185, 59, 221, 144, 60, 221, 144, 207, 62, 59, 241, 196, + 207, 62, 60, 241, 196, 218, 100, 60, 218, 100, 230, 133, 219, 65, 226, + 125, 222, 76, 207, 70, 249, 96, 247, 75, 211, 198, 230, 14, 219, 105, + 248, 183, 243, 255, 247, 64, 207, 29, 214, 206, 214, 204, 238, 65, 219, + 77, 240, 15, 215, 208, 226, 163, 218, 104, 248, 56, 245, 40, 221, 17, + 249, 182, 243, 60, 222, 211, 214, 128, 215, 203, 249, 95, 252, 91, 238, + 132, 230, 126, 250, 44, 241, 213, 211, 18, 241, 213, 249, 189, 210, 141, + 239, 84, 248, 57, 250, 179, 248, 57, 241, 97, 250, 179, 248, 57, 249, + 218, 221, 146, 231, 51, 220, 186, 243, 246, 248, 232, 250, 168, 248, 232, + 245, 33, 226, 126, 242, 67, 247, 76, 242, 67, 211, 199, 242, 67, 219, + 106, 242, 67, 248, 184, 242, 67, 244, 0, 242, 67, 214, 115, 207, 29, 238, + 66, 242, 67, 226, 164, 242, 67, 245, 41, 242, 67, 221, 18, 242, 67, 241, + 100, 242, 67, 239, 113, 242, 67, 206, 247, 242, 67, 250, 56, 242, 67, + 222, 4, 242, 67, 221, 18, 224, 44, 221, 186, 220, 121, 248, 41, 242, 148, + 242, 150, 243, 124, 224, 44, 226, 123, 211, 107, 59, 120, 220, 201, 250, + 174, 233, 53, 59, 130, 220, 201, 250, 174, 233, 53, 59, 47, 220, 201, + 250, 174, 233, 53, 59, 48, 220, 201, 250, 174, 233, 53, 241, 207, 239, + 108, 53, 207, 62, 239, 108, 53, 222, 186, 239, 108, 53, 211, 229, 120, + 53, 211, 229, 130, 53, 247, 212, 239, 103, 53, 222, 142, 239, 103, 53, + 247, 52, 206, 243, 239, 86, 242, 149, 225, 107, 213, 9, 232, 181, 243, + 251, 231, 110, 249, 229, 206, 243, 247, 185, 220, 58, 239, 106, 220, 167, + 227, 211, 215, 155, 251, 196, 215, 155, 238, 251, 215, 155, 206, 243, + 217, 148, 206, 243, 249, 165, 241, 145, 249, 59, 233, 69, 215, 55, 249, + 58, 233, 69, 215, 55, 249, 139, 240, 40, 227, 221, 206, 244, 242, 48, + 227, 222, 23, 206, 245, 238, 141, 239, 102, 118, 227, 84, 238, 141, 239, + 102, 118, 206, 242, 238, 141, 239, 102, 220, 193, 222, 199, 206, 245, 2, + 249, 76, 243, 122, 249, 117, 2, 209, 30, 221, 115, 2, 249, 192, 239, 129, + 227, 222, 2, 239, 210, 221, 54, 227, 207, 227, 222, 2, 210, 148, 222, + 178, 227, 221, 222, 178, 206, 244, 250, 178, 247, 123, 206, 228, 220, + 126, 232, 189, 222, 195, 232, 189, 240, 14, 240, 69, 250, 179, 252, 112, + 242, 154, 252, 162, 252, 163, 226, 154, 233, 74, 214, 240, 233, 43, 245, + 203, 221, 114, 239, 204, 246, 101, 229, 191, 225, 217, 220, 192, 242, 68, + 227, 173, 239, 128, 250, 127, 220, 195, 213, 29, 221, 10, 231, 92, 83, + 229, 98, 230, 5, 218, 148, 240, 160, 213, 253, 231, 91, 249, 148, 247, + 78, 2, 239, 60, 207, 47, 250, 54, 239, 60, 249, 111, 239, 60, 118, 239, + 58, 214, 145, 239, 60, 239, 220, 239, 60, 239, 61, 2, 45, 249, 187, 239, + 60, 239, 227, 239, 60, 206, 45, 239, 60, 220, 59, 239, 60, 239, 61, 2, + 218, 205, 218, 218, 239, 58, 239, 61, 246, 0, 245, 157, 215, 234, 2, 32, + 67, 233, 25, 243, 63, 147, 249, 88, 252, 111, 93, 249, 174, 214, 232, 93, + 247, 164, 93, 214, 122, 213, 107, 93, 243, 244, 246, 79, 93, 221, 11, 73, + 220, 187, 241, 182, 249, 241, 245, 71, 93, 214, 137, 250, 148, 211, 244, + 250, 148, 59, 241, 172, 238, 30, 220, 199, 93, 226, 167, 250, 163, 247, + 25, 242, 169, 77, 245, 35, 53, 247, 68, 248, 203, 250, 132, 2, 206, 43, + 53, 250, 132, 2, 245, 35, 53, 250, 132, 2, 242, 184, 53, 250, 132, 2, + 220, 165, 53, 226, 167, 2, 207, 4, 248, 90, 2, 167, 211, 57, 23, 206, 43, + 53, 217, 83, 221, 113, 247, 142, 249, 115, 226, 207, 241, 177, 245, 92, + 222, 126, 245, 97, 243, 208, 241, 236, 241, 158, 222, 142, 241, 236, 241, + 158, 222, 38, 2, 247, 27, 222, 38, 242, 60, 209, 206, 248, 237, 212, 127, + 248, 237, 191, 233, 53, 248, 90, 2, 167, 211, 56, 248, 90, 2, 173, 211, + 56, 250, 129, 248, 89, 247, 198, 220, 54, 218, 95, 220, 54, 221, 234, + 213, 243, 218, 40, 211, 48, 218, 40, 249, 170, 212, 205, 230, 51, 224, + 35, 224, 36, 2, 245, 255, 247, 77, 247, 192, 249, 171, 222, 142, 249, + 171, 239, 227, 249, 171, 249, 187, 249, 171, 222, 121, 249, 171, 249, + 168, 225, 211, 250, 166, 217, 91, 227, 85, 212, 108, 219, 45, 222, 36, + 242, 33, 228, 15, 217, 130, 252, 88, 220, 76, 253, 2, 229, 100, 248, 76, + 227, 97, 222, 92, 211, 64, 233, 65, 211, 64, 222, 44, 243, 177, 93, 233, + 62, 243, 8, 243, 9, 2, 173, 51, 52, 247, 192, 227, 236, 2, 229, 91, 241, + 196, 247, 192, 227, 236, 2, 219, 81, 241, 196, 222, 142, 227, 236, 2, + 219, 81, 241, 196, 222, 142, 227, 236, 2, 229, 91, 241, 196, 220, 173, + 220, 174, 238, 69, 225, 84, 226, 179, 221, 62, 226, 179, 221, 63, 2, 86, + 51, 251, 200, 230, 46, 208, 213, 226, 178, 226, 179, 221, 63, 222, 202, + 224, 68, 226, 179, 221, 61, 252, 89, 2, 250, 118, 248, 230, 248, 231, 2, + 241, 189, 208, 210, 248, 230, 212, 105, 219, 97, 208, 209, 241, 231, 220, + 108, 220, 179, 214, 6, 210, 110, 86, 251, 241, 247, 194, 86, 23, 92, 222, + 142, 247, 234, 251, 241, 247, 194, 86, 23, 92, 222, 142, 247, 234, 251, + 242, 2, 39, 119, 222, 82, 247, 194, 173, 23, 167, 222, 142, 247, 234, + 251, 241, 252, 87, 173, 23, 167, 222, 142, 247, 234, 251, 241, 114, 249, + 114, 93, 127, 249, 114, 93, 214, 142, 2, 248, 223, 91, 214, 141, 214, + 142, 2, 119, 214, 165, 207, 64, 214, 142, 2, 129, 214, 165, 207, 63, 250, + 102, 243, 63, 220, 223, 230, 41, 227, 248, 240, 29, 218, 162, 227, 248, + 240, 29, 229, 140, 2, 233, 36, 221, 150, 247, 192, 229, 140, 2, 231, 174, + 231, 174, 229, 139, 222, 142, 229, 139, 250, 28, 250, 29, 2, 248, 223, + 91, 249, 169, 229, 196, 93, 219, 98, 249, 54, 250, 177, 2, 92, 51, 52, + 243, 34, 2, 92, 51, 52, 222, 166, 2, 242, 168, 141, 2, 47, 48, 51, 52, + 214, 173, 2, 86, 51, 52, 211, 102, 2, 167, 51, 52, 224, 68, 119, 209, + 227, 243, 86, 93, 231, 171, 212, 98, 233, 30, 16, 33, 7, 6, 230, 4, 233, + 30, 16, 33, 7, 5, 230, 4, 233, 30, 16, 33, 223, 178, 233, 30, 16, 33, + 213, 42, 233, 30, 16, 33, 7, 230, 4, 241, 219, 243, 63, 211, 97, 206, + 220, 239, 114, 223, 161, 23, 249, 176, 238, 147, 220, 248, 226, 250, 212, + 106, 247, 42, 250, 149, 215, 10, 220, 203, 214, 27, 2, 226, 247, 245, 23, + 232, 189, 16, 33, 250, 41, 211, 46, 243, 47, 60, 49, 249, 54, 59, 49, + 249, 54, 230, 86, 219, 32, 247, 233, 230, 86, 249, 187, 247, 233, 230, + 86, 222, 121, 245, 156, 230, 86, 249, 187, 245, 156, 5, 222, 121, 245, + 156, 5, 249, 187, 245, 156, 209, 205, 219, 32, 211, 51, 244, 7, 219, 32, + 211, 51, 209, 205, 5, 219, 32, 211, 51, 244, 7, 5, 219, 32, 211, 51, 229, + 92, 48, 215, 246, 59, 247, 233, 209, 203, 48, 215, 246, 59, 247, 233, 39, + 247, 60, 220, 190, 247, 60, 220, 191, 2, 239, 120, 55, 247, 60, 220, 190, + 224, 39, 47, 216, 55, 2, 129, 245, 21, 224, 39, 48, 216, 55, 2, 129, 245, + 21, 16, 33, 227, 186, 248, 96, 59, 7, 247, 59, 77, 7, 247, 59, 248, 133, + 247, 59, 222, 174, 93, 244, 10, 73, 221, 172, 247, 196, 242, 68, 119, + 222, 216, 247, 196, 242, 68, 118, 222, 216, 247, 196, 242, 68, 129, 222, + 216, 247, 196, 242, 68, 241, 125, 222, 216, 247, 196, 242, 68, 241, 204, + 222, 216, 247, 196, 242, 68, 215, 10, 222, 216, 247, 196, 242, 68, 216, + 23, 222, 216, 247, 196, 242, 68, 243, 88, 222, 216, 247, 196, 242, 68, + 224, 195, 222, 216, 247, 196, 242, 68, 212, 99, 222, 216, 247, 196, 242, + 68, 243, 59, 222, 216, 247, 196, 242, 68, 210, 127, 222, 216, 247, 196, + 242, 68, 222, 161, 247, 196, 242, 68, 210, 106, 247, 196, 242, 68, 211, + 234, 247, 196, 242, 68, 241, 121, 247, 196, 242, 68, 241, 202, 247, 196, + 242, 68, 215, 6, 247, 196, 242, 68, 216, 22, 247, 196, 242, 68, 243, 87, + 247, 196, 242, 68, 224, 194, 247, 196, 242, 68, 212, 97, 247, 196, 242, + 68, 243, 57, 247, 196, 242, 68, 210, 125, 48, 214, 141, 48, 214, 142, 2, + 119, 214, 165, 207, 64, 48, 214, 142, 2, 129, 214, 165, 207, 63, 249, 83, + 249, 84, 2, 214, 165, 207, 63, 218, 147, 250, 28, 249, 171, 248, 221, + 227, 208, 247, 195, 60, 214, 241, 23, 247, 58, 224, 68, 220, 254, 238, + 140, 227, 222, 233, 69, 249, 61, 213, 168, 229, 253, 214, 230, 222, 123, + 214, 108, 246, 84, 213, 150, 214, 130, 214, 131, 207, 48, 232, 105, 47, + 239, 108, 212, 108, 219, 45, 212, 108, 219, 46, 2, 222, 37, 48, 239, 108, + 212, 108, 219, 45, 59, 211, 89, 212, 107, 60, 211, 89, 212, 107, 212, + 108, 222, 166, 211, 102, 73, 226, 175, 247, 216, 226, 179, 221, 62, 250, + 177, 73, 243, 8, 214, 32, 243, 8, 243, 9, 2, 229, 220, 241, 165, 243, 8, + 221, 151, 131, 214, 32, 243, 8, 229, 195, 221, 233, 60, 220, 54, 229, 92, + 47, 221, 149, 229, 92, 47, 250, 144, 221, 150, 229, 92, 47, 241, 127, + 221, 150, 229, 92, 47, 222, 31, 229, 92, 47, 247, 71, 47, 206, 219, 239, + 107, 201, 222, 186, 239, 108, 53, 219, 81, 239, 108, 2, 241, 224, 214, + 121, 218, 224, 219, 81, 239, 108, 2, 241, 224, 214, 121, 218, 224, 211, + 229, 120, 53, 218, 224, 211, 229, 130, 53, 218, 224, 208, 212, 239, 107, + 218, 224, 239, 108, 2, 226, 247, 241, 228, 242, 158, 219, 81, 239, 108, + 2, 221, 211, 250, 6, 226, 247, 23, 218, 149, 241, 223, 59, 130, 220, 201, + 47, 239, 108, 233, 53, 215, 73, 59, 47, 220, 201, 233, 53, 215, 73, 59, + 48, 220, 201, 233, 53, 215, 73, 60, 47, 220, 201, 233, 53, 215, 73, 60, + 48, 220, 201, 233, 53, 60, 47, 220, 201, 250, 174, 233, 53, 60, 48, 220, + 201, 250, 174, 233, 53, 215, 73, 59, 120, 220, 201, 233, 53, 215, 73, 59, + 130, 220, 201, 233, 53, 215, 73, 60, 120, 220, 201, 233, 53, 215, 73, 60, + 130, 220, 201, 233, 53, 60, 120, 220, 201, 250, 174, 233, 53, 60, 130, + 220, 201, 250, 174, 233, 53, 245, 202, 247, 142, 231, 173, 23, 226, 125, + 129, 225, 90, 247, 141, 220, 122, 220, 209, 248, 239, 60, 239, 94, 215, + 204, 241, 177, 245, 92, 59, 239, 94, 215, 204, 241, 177, 245, 92, 214, + 187, 215, 204, 241, 177, 245, 92, 212, 165, 248, 188, 207, 0, 231, 172, + 119, 249, 55, 226, 125, 118, 249, 55, 226, 125, 129, 249, 55, 226, 125, + 211, 81, 44, 221, 113, 247, 142, 239, 94, 245, 92, 217, 93, 220, 123, + 237, 175, 242, 33, 237, 175, 222, 126, 245, 98, 237, 175, 245, 45, 2, + 212, 60, 245, 45, 2, 212, 61, 23, 221, 47, 245, 45, 2, 221, 47, 241, 113, + 2, 221, 47, 241, 113, 2, 211, 178, 241, 113, 2, 252, 123, 206, 195, 60, + 241, 158, 241, 158, 222, 142, 241, 158, 191, 233, 54, 245, 78, 191, 241, + 236, 249, 140, 241, 236, 248, 252, 243, 43, 224, 37, 243, 43, 224, 38, + 222, 37, 243, 43, 224, 38, 222, 42, 224, 37, 224, 38, 222, 37, 224, 38, + 222, 42, 243, 43, 245, 44, 243, 43, 222, 37, 243, 43, 222, 35, 245, 44, + 222, 37, 222, 35, 207, 74, 214, 128, 224, 38, 222, 42, 214, 128, 248, + 238, 222, 42, 245, 202, 207, 8, 226, 204, 227, 163, 222, 84, 247, 194, + 48, 23, 47, 216, 55, 251, 241, 248, 223, 206, 195, 233, 60, 241, 152, + 214, 250, 93, 245, 254, 241, 152, 214, 250, 93, 247, 143, 44, 231, 174, + 218, 112, 225, 84, 222, 38, 2, 39, 212, 60, 213, 255, 248, 89, 246, 129, + 231, 58, 229, 192, 214, 140, 239, 69, 233, 69, 215, 55, 129, 219, 56, 52, + 129, 219, 56, 55, 129, 219, 56, 230, 46, 129, 219, 56, 218, 167, 47, 214, + 137, 249, 100, 48, 214, 137, 249, 100, 118, 214, 137, 249, 99, 129, 214, + 137, 249, 99, 47, 211, 244, 249, 100, 48, 211, 244, 249, 100, 47, 252, + 111, 249, 100, 48, 252, 111, 249, 100, 226, 149, 249, 100, 229, 221, 226, + 149, 249, 100, 229, 221, 226, 148, 250, 146, 96, 2, 250, 145, 250, 146, + 121, 206, 195, 250, 146, 96, 2, 121, 206, 195, 250, 146, 24, 121, 206, + 195, 250, 146, 96, 2, 24, 121, 206, 195, 147, 248, 81, 83, 250, 146, 96, + 2, 24, 248, 80, 206, 227, 227, 205, 226, 130, 241, 83, 211, 124, 211, 86, + 214, 18, 73, 229, 233, 215, 56, 73, 232, 190, 226, 119, 239, 224, 242, + 67, 239, 224, 242, 68, 2, 214, 210, 242, 148, 242, 68, 2, 212, 123, 73, + 232, 107, 214, 210, 242, 68, 2, 222, 142, 226, 123, 214, 210, 242, 68, 2, + 222, 142, 226, 124, 23, 214, 210, 242, 148, 214, 210, 242, 68, 2, 222, + 142, 226, 124, 23, 247, 166, 213, 106, 214, 210, 242, 68, 2, 222, 142, + 226, 124, 23, 211, 196, 242, 148, 214, 210, 242, 68, 2, 239, 119, 214, + 210, 242, 68, 2, 238, 68, 207, 2, 242, 67, 214, 210, 242, 68, 2, 214, + 210, 242, 148, 242, 68, 217, 122, 245, 235, 241, 150, 219, 8, 242, 67, + 214, 210, 242, 68, 2, 239, 59, 242, 148, 214, 210, 242, 68, 2, 213, 150, + 214, 209, 242, 67, 225, 88, 242, 67, 242, 160, 242, 67, 209, 232, 242, + 67, 242, 68, 2, 247, 166, 213, 106, 221, 142, 242, 67, 247, 134, 242, 67, + 247, 135, 242, 67, 231, 90, 242, 67, 242, 68, 211, 231, 32, 231, 91, 231, + 90, 242, 68, 2, 214, 210, 242, 148, 231, 90, 242, 68, 2, 247, 192, 242, + 148, 242, 68, 2, 213, 209, 211, 107, 242, 68, 2, 213, 209, 211, 108, 23, + 207, 2, 242, 150, 242, 68, 2, 213, 209, 211, 108, 23, 211, 196, 242, 148, + 245, 99, 242, 67, 206, 226, 242, 67, 252, 107, 242, 67, 220, 164, 242, + 67, 247, 44, 242, 67, 221, 117, 242, 67, 242, 68, 2, 229, 114, 73, 211, + 29, 245, 99, 249, 57, 219, 8, 242, 67, 241, 94, 242, 68, 2, 222, 142, + 226, 123, 252, 105, 242, 67, 242, 26, 242, 67, 207, 49, 242, 67, 214, + 231, 242, 67, 211, 161, 242, 67, 239, 225, 242, 67, 229, 101, 247, 44, + 242, 67, 242, 68, 2, 222, 142, 226, 123, 238, 20, 242, 67, 242, 68, 2, + 222, 142, 226, 124, 23, 247, 166, 213, 106, 242, 68, 217, 95, 233, 69, + 242, 27, 251, 206, 242, 67, 241, 169, 242, 67, 214, 232, 242, 67, 245, + 71, 242, 67, 242, 68, 206, 253, 226, 123, 242, 68, 2, 227, 111, 227, 175, + 239, 224, 248, 184, 242, 68, 2, 214, 210, 242, 148, 248, 184, 242, 68, 2, + 212, 123, 73, 232, 107, 214, 210, 248, 184, 242, 68, 2, 222, 142, 226, + 123, 214, 210, 248, 184, 242, 68, 2, 239, 59, 242, 148, 248, 184, 242, + 68, 2, 206, 217, 214, 211, 231, 90, 248, 184, 242, 68, 2, 247, 192, 242, + 148, 220, 164, 248, 184, 242, 67, 247, 44, 248, 184, 242, 67, 207, 49, + 248, 184, 242, 67, 214, 225, 241, 94, 242, 67, 214, 225, 214, 210, 242, + 67, 242, 68, 2, 224, 68, 240, 7, 240, 140, 242, 68, 2, 222, 186, 240, + 140, 221, 115, 249, 145, 245, 249, 217, 73, 226, 163, 239, 62, 226, 163, + 214, 143, 226, 163, 239, 96, 221, 115, 219, 80, 119, 239, 107, 221, 115, + 219, 80, 249, 157, 239, 103, 233, 69, 248, 135, 221, 115, 241, 93, 221, + 115, 2, 220, 164, 242, 67, 221, 115, 2, 241, 159, 239, 102, 143, 207, 36, + 220, 201, 230, 53, 188, 207, 36, 220, 201, 230, 53, 143, 243, 117, 220, + 201, 230, 53, 188, 243, 117, 220, 201, 230, 53, 201, 143, 207, 36, 220, + 201, 230, 53, 201, 188, 207, 36, 220, 201, 230, 53, 201, 143, 243, 117, + 220, 201, 230, 53, 201, 188, 243, 117, 220, 201, 230, 53, 143, 207, 36, + 220, 201, 208, 196, 230, 53, 188, 207, 36, 220, 201, 208, 196, 230, 53, + 143, 243, 117, 220, 201, 208, 196, 230, 53, 188, 243, 117, 220, 201, 208, + 196, 230, 53, 77, 143, 207, 36, 220, 201, 208, 196, 230, 53, 77, 188, + 207, 36, 220, 201, 208, 196, 230, 53, 77, 143, 243, 117, 220, 201, 208, + 196, 230, 53, 77, 188, 243, 117, 220, 201, 208, 196, 230, 53, 143, 207, + 36, 220, 201, 249, 97, 188, 207, 36, 220, 201, 249, 97, 143, 243, 117, + 220, 201, 249, 97, 188, 243, 117, 220, 201, 249, 97, 77, 143, 207, 36, + 220, 201, 249, 97, 77, 188, 207, 36, 220, 201, 249, 97, 77, 143, 243, + 117, 220, 201, 249, 97, 77, 188, 243, 117, 220, 201, 249, 97, 238, 139, + 219, 189, 49, 222, 111, 238, 139, 219, 189, 49, 222, 112, 233, 69, 60, + 214, 107, 214, 182, 219, 189, 49, 222, 111, 214, 182, 219, 189, 49, 222, + 112, 233, 69, 60, 214, 107, 92, 218, 116, 167, 218, 116, 86, 218, 116, + 173, 218, 116, 121, 28, 242, 204, 222, 111, 77, 121, 28, 242, 204, 222, + 111, 28, 222, 142, 242, 204, 222, 111, 77, 28, 222, 142, 242, 204, 222, + 111, 77, 252, 126, 222, 111, 213, 109, 252, 126, 222, 111, 38, 77, 50, + 201, 247, 156, 219, 180, 141, 222, 111, 38, 77, 50, 247, 156, 219, 180, + 141, 222, 111, 38, 77, 114, 50, 247, 156, 219, 180, 141, 222, 111, 77, + 233, 11, 222, 111, 38, 233, 11, 222, 111, 77, 38, 233, 11, 222, 111, 208, + 226, 77, 214, 180, 208, 226, 77, 218, 225, 214, 180, 248, 79, 249, 181, + 218, 225, 248, 79, 249, 181, 218, 116, 239, 46, 214, 13, 229, 137, 219, + 86, 248, 204, 238, 248, 211, 74, 238, 248, 211, 75, 2, 249, 86, 224, 44, + 211, 74, 227, 56, 147, 219, 87, 214, 19, 211, 72, 211, 73, 248, 204, 249, + 62, 222, 163, 249, 62, 211, 26, 249, 63, 213, 251, 226, 208, 252, 130, + 241, 220, 243, 27, 220, 193, 248, 204, 222, 163, 220, 193, 248, 204, 212, + 141, 222, 163, 212, 141, 251, 172, 222, 163, 251, 172, 219, 39, 209, 31, + 245, 231, 211, 17, 251, 236, 229, 105, 211, 80, 226, 157, 226, 129, 219, + 85, 213, 122, 219, 85, 226, 129, 248, 251, 252, 234, 211, 71, 215, 167, + 218, 92, 214, 135, 194, 211, 78, 229, 223, 79, 211, 78, 229, 223, 247, + 123, 53, 220, 193, 248, 190, 218, 218, 229, 223, 211, 48, 241, 197, 222, + 166, 220, 175, 245, 26, 224, 68, 243, 14, 53, 214, 208, 93, 224, 68, 214, + 208, 93, 220, 53, 229, 181, 233, 69, 232, 217, 220, 239, 93, 245, 52, + 224, 43, 229, 181, 93, 220, 169, 207, 70, 93, 224, 58, 207, 70, 93, 249, + 240, 224, 68, 249, 239, 249, 238, 226, 129, 249, 238, 221, 166, 224, 68, + 221, 165, 248, 48, 247, 53, 227, 80, 93, 206, 241, 93, 218, 234, 250, + 179, 93, 211, 125, 207, 70, 247, 189, 215, 126, 250, 105, 250, 103, 221, + 197, 247, 108, 247, 12, 250, 160, 247, 217, 47, 229, 71, 211, 52, 2, 218, + 93, 247, 90, 220, 111, 53, 39, 233, 43, 214, 163, 249, 138, 93, 240, 39, + 93, 247, 83, 23, 230, 96, 214, 232, 253, 18, 215, 147, 250, 159, 250, 27, + 250, 28, 250, 51, 239, 115, 23, 206, 220, 215, 180, 222, 190, 243, 241, + 226, 133, 219, 86, 211, 82, 226, 135, 249, 180, 209, 205, 226, 218, 252, + 194, 209, 205, 252, 194, 209, 205, 5, 252, 194, 5, 252, 194, 224, 47, + 252, 194, 252, 195, 245, 215, 252, 195, 251, 246, 217, 129, 222, 163, + 241, 220, 243, 27, 245, 146, 229, 137, 221, 200, 215, 167, 125, 16, 33, + 219, 185, 125, 16, 33, 252, 196, 125, 16, 33, 241, 219, 125, 16, 33, 243, + 120, 125, 16, 33, 207, 69, 125, 16, 33, 252, 39, 125, 16, 33, 252, 40, + 219, 26, 125, 16, 33, 252, 40, 219, 25, 125, 16, 33, 252, 40, 208, 179, + 125, 16, 33, 252, 40, 208, 178, 125, 16, 33, 208, 193, 125, 16, 33, 208, + 192, 125, 16, 33, 208, 191, 125, 16, 33, 213, 161, 125, 16, 33, 221, 70, + 213, 161, 125, 16, 33, 60, 213, 161, 125, 16, 33, 227, 79, 213, 189, 125, + 16, 33, 227, 79, 213, 188, 125, 16, 33, 227, 79, 213, 187, 125, 16, 33, + 247, 236, 125, 16, 33, 217, 165, 125, 16, 33, 224, 183, 125, 16, 33, 208, + 177, 125, 16, 33, 208, 176, 125, 16, 33, 218, 117, 217, 165, 125, 16, 33, + 218, 117, 217, 164, 125, 16, 33, 240, 11, 125, 16, 33, 215, 52, 125, 16, + 33, 232, 240, 222, 117, 125, 16, 33, 232, 240, 222, 116, 125, 16, 33, + 247, 63, 73, 232, 239, 125, 16, 33, 219, 22, 73, 232, 239, 125, 16, 33, + 247, 99, 222, 117, 125, 16, 33, 232, 238, 222, 117, 125, 16, 33, 213, + 190, 73, 247, 98, 125, 16, 33, 247, 63, 73, 247, 98, 125, 16, 33, 247, + 63, 73, 247, 97, 125, 16, 33, 247, 99, 252, 81, 125, 16, 33, 217, 166, + 73, 247, 99, 252, 81, 125, 16, 33, 213, 190, 73, 217, 166, 73, 247, 98, + 125, 16, 33, 209, 26, 125, 16, 33, 211, 174, 222, 117, 125, 16, 33, 230, + 57, 222, 117, 125, 16, 33, 252, 80, 222, 117, 125, 16, 33, 213, 190, 73, + 252, 79, 125, 16, 33, 217, 166, 73, 252, 79, 125, 16, 33, 213, 190, 73, + 217, 166, 73, 252, 79, 125, 16, 33, 208, 194, 73, 252, 79, 125, 16, 33, + 219, 22, 73, 252, 79, 125, 16, 33, 219, 22, 73, 252, 78, 125, 16, 33, + 219, 21, 125, 16, 33, 219, 20, 125, 16, 33, 219, 19, 125, 16, 33, 219, + 18, 125, 16, 33, 252, 159, 125, 16, 33, 252, 158, 125, 16, 33, 227, 196, + 125, 16, 33, 217, 171, 125, 16, 33, 251, 240, 125, 16, 33, 219, 48, 125, + 16, 33, 219, 47, 125, 16, 33, 251, 175, 125, 16, 33, 249, 210, 222, 117, + 125, 16, 33, 212, 160, 125, 16, 33, 212, 159, 125, 16, 33, 219, 191, 229, + 214, 125, 16, 33, 249, 162, 125, 16, 33, 249, 161, 125, 16, 33, 249, 160, + 125, 16, 33, 252, 138, 125, 16, 33, 222, 189, 125, 16, 33, 214, 124, 125, + 16, 33, 211, 172, 125, 16, 33, 239, 194, 125, 16, 33, 207, 57, 125, 16, + 33, 220, 163, 125, 16, 33, 248, 235, 125, 16, 33, 210, 136, 125, 16, 33, + 248, 206, 226, 138, 125, 16, 33, 217, 107, 73, 232, 109, 125, 16, 33, + 248, 248, 125, 16, 33, 211, 45, 125, 16, 33, 214, 24, 211, 45, 125, 16, + 33, 229, 136, 125, 16, 33, 214, 191, 125, 16, 33, 209, 186, 125, 16, 33, + 238, 66, 243, 223, 125, 16, 33, 251, 220, 125, 16, 33, 220, 171, 251, + 220, 125, 16, 33, 249, 118, 125, 16, 33, 220, 162, 249, 118, 125, 16, 33, + 252, 135, 125, 16, 33, 213, 239, 213, 142, 213, 238, 125, 16, 33, 213, + 239, 213, 142, 213, 237, 125, 16, 33, 213, 186, 125, 16, 33, 220, 137, + 125, 16, 33, 245, 88, 125, 16, 33, 245, 90, 125, 16, 33, 245, 89, 125, + 16, 33, 220, 62, 125, 16, 33, 220, 51, 125, 16, 33, 247, 51, 125, 16, 33, + 247, 50, 125, 16, 33, 247, 49, 125, 16, 33, 247, 48, 125, 16, 33, 247, + 47, 125, 16, 33, 252, 171, 125, 16, 33, 250, 106, 73, 227, 180, 125, 16, + 33, 250, 106, 73, 209, 58, 125, 16, 33, 218, 232, 125, 16, 33, 238, 58, + 125, 16, 33, 224, 209, 125, 16, 33, 246, 66, 125, 16, 33, 226, 152, 125, + 16, 33, 160, 243, 253, 125, 16, 33, 160, 222, 95, 60, 230, 41, 232, 223, + 48, 211, 51, 60, 209, 205, 232, 223, 48, 211, 51, 60, 218, 162, 232, 223, + 48, 211, 51, 60, 244, 7, 232, 223, 48, 211, 51, 60, 214, 225, 5, 247, + 233, 227, 109, 24, 59, 247, 233, 24, 59, 247, 233, 77, 59, 247, 233, 208, + 226, 77, 59, 247, 233, 242, 153, 77, 59, 247, 233, 59, 247, 234, 247, + 119, 60, 5, 247, 233, 218, 95, 212, 161, 60, 211, 169, 214, 107, 60, 214, + 225, 5, 214, 107, 147, 59, 214, 107, 227, 109, 59, 214, 107, 24, 59, 214, + 107, 77, 59, 214, 107, 208, 226, 77, 59, 214, 107, 242, 153, 77, 59, 214, + 107, 59, 49, 247, 119, 60, 208, 226, 5, 214, 107, 59, 49, 247, 119, 60, + 227, 109, 214, 107, 49, 212, 161, 60, 211, 169, 245, 156, 60, 208, 226, + 5, 245, 156, 60, 227, 109, 5, 245, 156, 59, 245, 157, 247, 119, 60, 208, + 226, 5, 245, 156, 59, 245, 157, 247, 119, 60, 227, 109, 245, 156, 245, + 157, 212, 161, 60, 211, 169, 229, 88, 60, 208, 226, 5, 229, 88, 60, 227, + 109, 5, 229, 88, 59, 229, 89, 247, 119, 60, 5, 229, 88, 212, 12, 27, 247, + 59, 147, 27, 247, 59, 227, 109, 27, 247, 59, 24, 27, 247, 59, 208, 226, + 24, 27, 247, 59, 208, 226, 77, 27, 247, 59, 242, 153, 77, 27, 247, 59, + 212, 12, 217, 162, 147, 217, 162, 227, 109, 217, 162, 24, 217, 162, 77, + 217, 162, 208, 226, 77, 217, 162, 242, 153, 77, 217, 162, 147, 241, 204, + 214, 119, 251, 209, 227, 109, 241, 204, 214, 119, 251, 209, 24, 241, 204, + 214, 119, 251, 209, 77, 241, 204, 214, 119, 251, 209, 208, 226, 77, 241, + 204, 214, 119, 251, 209, 242, 153, 77, 241, 204, 214, 119, 251, 209, 147, + 215, 10, 214, 119, 251, 209, 227, 109, 215, 10, 214, 119, 251, 209, 24, + 215, 10, 214, 119, 251, 209, 77, 215, 10, 214, 119, 251, 209, 208, 226, + 77, 215, 10, 214, 119, 251, 209, 242, 153, 77, 215, 10, 214, 119, 251, + 209, 147, 243, 88, 214, 119, 251, 209, 227, 109, 243, 88, 214, 119, 251, + 209, 24, 243, 88, 214, 119, 251, 209, 77, 243, 88, 214, 119, 251, 209, + 208, 226, 77, 243, 88, 214, 119, 251, 209, 147, 129, 220, 203, 60, 214, + 26, 227, 109, 129, 220, 203, 60, 214, 26, 129, 220, 203, 60, 214, 26, + 227, 109, 129, 220, 203, 221, 4, 214, 26, 147, 241, 125, 220, 203, 60, + 214, 26, 227, 109, 241, 125, 220, 203, 60, 214, 26, 241, 125, 220, 203, + 60, 214, 26, 227, 109, 241, 125, 220, 203, 221, 4, 214, 26, 218, 225, + 147, 241, 125, 220, 203, 221, 4, 214, 26, 147, 241, 204, 220, 203, 60, + 214, 26, 77, 241, 204, 220, 203, 60, 214, 26, 227, 109, 215, 10, 220, + 203, 60, 214, 26, 77, 215, 10, 220, 203, 60, 214, 26, 215, 10, 220, 203, + 221, 4, 214, 26, 227, 109, 243, 88, 220, 203, 60, 214, 26, 77, 243, 88, + 220, 203, 60, 214, 26, 208, 226, 77, 243, 88, 220, 203, 60, 214, 26, 77, + 243, 88, 220, 203, 221, 4, 214, 26, 147, 210, 127, 220, 203, 60, 214, 26, + 77, 210, 127, 220, 203, 60, 214, 26, 77, 210, 127, 220, 203, 221, 4, 214, + 26, 92, 51, 2, 5, 211, 52, 251, 243, 167, 51, 2, 5, 211, 52, 251, 243, + 86, 51, 2, 5, 211, 52, 251, 243, 173, 51, 2, 5, 211, 52, 251, 243, 92, + 51, 2, 227, 109, 211, 52, 251, 243, 167, 51, 2, 227, 109, 211, 52, 251, + 243, 86, 51, 2, 227, 109, 211, 52, 251, 243, 173, 51, 2, 227, 109, 211, + 52, 251, 243, 92, 51, 2, 230, 86, 211, 52, 251, 243, 167, 51, 2, 230, 86, + 211, 52, 251, 243, 86, 51, 2, 230, 86, 211, 52, 251, 243, 173, 51, 2, + 230, 86, 211, 52, 251, 243, 92, 51, 2, 5, 242, 238, 251, 243, 167, 51, 2, + 5, 242, 238, 251, 243, 86, 51, 2, 5, 242, 238, 251, 243, 173, 51, 2, 5, + 242, 238, 251, 243, 92, 51, 2, 242, 238, 251, 243, 167, 51, 2, 242, 238, + 251, 243, 86, 51, 2, 242, 238, 251, 243, 173, 51, 2, 242, 238, 251, 243, + 77, 92, 51, 2, 242, 238, 251, 243, 77, 167, 51, 2, 242, 238, 251, 243, + 77, 86, 51, 2, 242, 238, 251, 243, 77, 173, 51, 2, 242, 238, 251, 243, + 77, 92, 51, 2, 230, 86, 242, 238, 251, 243, 77, 167, 51, 2, 230, 86, 242, + 238, 251, 243, 77, 86, 51, 2, 230, 86, 242, 238, 251, 243, 77, 173, 51, + 2, 230, 86, 242, 238, 251, 243, 92, 211, 50, 51, 2, 225, 199, 215, 244, + 167, 211, 50, 51, 2, 225, 199, 215, 244, 86, 211, 50, 51, 2, 225, 199, + 215, 244, 173, 211, 50, 51, 2, 225, 199, 215, 244, 92, 211, 50, 51, 2, + 227, 109, 215, 244, 167, 211, 50, 51, 2, 227, 109, 215, 244, 86, 211, 50, + 51, 2, 227, 109, 215, 244, 173, 211, 50, 51, 2, 227, 109, 215, 244, 92, + 211, 50, 51, 2, 24, 215, 244, 167, 211, 50, 51, 2, 24, 215, 244, 86, 211, + 50, 51, 2, 24, 215, 244, 173, 211, 50, 51, 2, 24, 215, 244, 92, 211, 50, + 51, 2, 77, 215, 244, 167, 211, 50, 51, 2, 77, 215, 244, 86, 211, 50, 51, + 2, 77, 215, 244, 173, 211, 50, 51, 2, 77, 215, 244, 92, 211, 50, 51, 2, + 208, 226, 77, 215, 244, 167, 211, 50, 51, 2, 208, 226, 77, 215, 244, 86, + 211, 50, 51, 2, 208, 226, 77, 215, 244, 173, 211, 50, 51, 2, 208, 226, + 77, 215, 244, 92, 241, 227, 45, 167, 241, 227, 45, 86, 241, 227, 45, 173, + 241, 227, 45, 92, 98, 45, 167, 98, 45, 86, 98, 45, 173, 98, 45, 92, 247, + 144, 45, 167, 247, 144, 45, 86, 247, 144, 45, 173, 247, 144, 45, 92, 77, + 247, 144, 45, 167, 77, 247, 144, 45, 86, 77, 247, 144, 45, 173, 77, 247, + 144, 45, 92, 77, 45, 167, 77, 45, 86, 77, 45, 173, 77, 45, 92, 38, 45, + 167, 38, 45, 86, 38, 45, 173, 38, 45, 143, 207, 36, 38, 45, 143, 243, + 117, 38, 45, 188, 243, 117, 38, 45, 188, 207, 36, 38, 45, 47, 48, 38, 45, + 120, 130, 38, 45, 207, 16, 92, 147, 138, 45, 207, 16, 167, 147, 138, 45, + 207, 16, 86, 147, 138, 45, 207, 16, 173, 147, 138, 45, 207, 16, 143, 207, + 36, 147, 138, 45, 207, 16, 143, 243, 117, 147, 138, 45, 207, 16, 188, + 243, 117, 147, 138, 45, 207, 16, 188, 207, 36, 147, 138, 45, 207, 16, 92, + 138, 45, 207, 16, 167, 138, 45, 207, 16, 86, 138, 45, 207, 16, 173, 138, + 45, 207, 16, 143, 207, 36, 138, 45, 207, 16, 143, 243, 117, 138, 45, 207, + 16, 188, 243, 117, 138, 45, 207, 16, 188, 207, 36, 138, 45, 207, 16, 92, + 227, 109, 138, 45, 207, 16, 167, 227, 109, 138, 45, 207, 16, 86, 227, + 109, 138, 45, 207, 16, 173, 227, 109, 138, 45, 207, 16, 143, 207, 36, + 227, 109, 138, 45, 207, 16, 143, 243, 117, 227, 109, 138, 45, 207, 16, + 188, 243, 117, 227, 109, 138, 45, 207, 16, 188, 207, 36, 227, 109, 138, + 45, 207, 16, 92, 77, 138, 45, 207, 16, 167, 77, 138, 45, 207, 16, 86, 77, + 138, 45, 207, 16, 173, 77, 138, 45, 207, 16, 143, 207, 36, 77, 138, 45, + 207, 16, 143, 243, 117, 77, 138, 45, 207, 16, 188, 243, 117, 77, 138, 45, + 207, 16, 188, 207, 36, 77, 138, 45, 207, 16, 92, 208, 226, 77, 138, 45, + 207, 16, 167, 208, 226, 77, 138, 45, 207, 16, 86, 208, 226, 77, 138, 45, + 207, 16, 173, 208, 226, 77, 138, 45, 207, 16, 143, 207, 36, 208, 226, 77, + 138, 45, 207, 16, 143, 243, 117, 208, 226, 77, 138, 45, 207, 16, 188, + 243, 117, 208, 226, 77, 138, 45, 207, 16, 188, 207, 36, 208, 226, 77, + 138, 45, 92, 211, 52, 251, 243, 167, 211, 52, 251, 243, 86, 211, 52, 251, + 243, 173, 211, 52, 251, 243, 92, 59, 51, 206, 255, 211, 52, 251, 243, + 167, 59, 51, 206, 255, 211, 52, 251, 243, 86, 59, 51, 206, 255, 211, 52, + 251, 243, 173, 59, 51, 206, 255, 211, 52, 251, 243, 92, 51, 2, 224, 39, + 212, 191, 167, 51, 2, 224, 39, 212, 191, 86, 51, 2, 224, 39, 212, 191, + 173, 51, 2, 224, 39, 212, 191, 77, 51, 215, 245, 207, 15, 102, 77, 51, + 215, 245, 207, 15, 118, 212, 7, 77, 51, 215, 245, 207, 15, 119, 239, 121, + 77, 51, 215, 245, 207, 15, 119, 212, 10, 92, 249, 151, 59, 45, 86, 249, + 154, 215, 247, 59, 45, 92, 211, 102, 215, 247, 59, 45, 86, 211, 102, 215, + 247, 59, 45, 92, 230, 40, 59, 45, 86, 218, 161, 59, 45, 92, 218, 161, 59, + 45, 86, 230, 40, 59, 45, 92, 250, 175, 215, 246, 59, 45, 86, 250, 175, + 215, 246, 59, 45, 92, 241, 96, 215, 246, 59, 45, 86, 241, 96, 215, 246, + 59, 45, 59, 51, 215, 245, 207, 15, 102, 59, 51, 215, 245, 207, 15, 118, + 212, 7, 10, 15, 237, 171, 10, 15, 237, 170, 10, 15, 237, 169, 10, 15, + 237, 168, 10, 15, 237, 167, 10, 15, 237, 166, 10, 15, 237, 165, 10, 15, + 237, 164, 10, 15, 237, 163, 10, 15, 237, 162, 10, 15, 237, 161, 10, 15, + 237, 160, 10, 15, 237, 159, 10, 15, 237, 158, 10, 15, 237, 157, 10, 15, + 237, 156, 10, 15, 237, 155, 10, 15, 237, 154, 10, 15, 237, 153, 10, 15, + 237, 152, 10, 15, 237, 151, 10, 15, 237, 150, 10, 15, 237, 149, 10, 15, + 237, 148, 10, 15, 237, 147, 10, 15, 237, 146, 10, 15, 237, 145, 10, 15, + 237, 144, 10, 15, 237, 143, 10, 15, 237, 142, 10, 15, 237, 141, 10, 15, + 237, 140, 10, 15, 237, 139, 10, 15, 237, 138, 10, 15, 237, 137, 10, 15, + 237, 136, 10, 15, 237, 135, 10, 15, 237, 134, 10, 15, 237, 133, 10, 15, + 237, 132, 10, 15, 237, 131, 10, 15, 237, 130, 10, 15, 237, 129, 10, 15, + 237, 128, 10, 15, 237, 127, 10, 15, 237, 126, 10, 15, 237, 125, 10, 15, + 237, 124, 10, 15, 237, 123, 10, 15, 237, 122, 10, 15, 237, 121, 10, 15, + 237, 120, 10, 15, 237, 119, 10, 15, 237, 118, 10, 15, 237, 117, 10, 15, + 237, 116, 10, 15, 237, 115, 10, 15, 237, 114, 10, 15, 237, 113, 10, 15, + 237, 112, 10, 15, 237, 111, 10, 15, 237, 110, 10, 15, 237, 109, 10, 15, + 237, 108, 10, 15, 237, 107, 10, 15, 237, 106, 10, 15, 237, 105, 10, 15, + 237, 104, 10, 15, 237, 103, 10, 15, 237, 102, 10, 15, 237, 101, 10, 15, + 237, 100, 10, 15, 237, 99, 10, 15, 237, 98, 10, 15, 237, 97, 10, 15, 237, + 96, 10, 15, 237, 95, 10, 15, 237, 94, 10, 15, 237, 93, 10, 15, 237, 92, + 10, 15, 237, 91, 10, 15, 237, 90, 10, 15, 237, 89, 10, 15, 237, 88, 10, + 15, 237, 87, 10, 15, 237, 86, 10, 15, 237, 85, 10, 15, 237, 84, 10, 15, + 237, 83, 10, 15, 237, 82, 10, 15, 237, 81, 10, 15, 237, 80, 10, 15, 237, + 79, 10, 15, 237, 78, 10, 15, 237, 77, 10, 15, 237, 76, 10, 15, 237, 75, + 10, 15, 237, 74, 10, 15, 237, 73, 10, 15, 237, 72, 10, 15, 237, 71, 10, + 15, 237, 70, 10, 15, 237, 69, 10, 15, 237, 68, 10, 15, 237, 67, 10, 15, + 237, 66, 10, 15, 237, 65, 10, 15, 237, 64, 10, 15, 237, 63, 10, 15, 237, + 62, 10, 15, 237, 61, 10, 15, 237, 60, 10, 15, 237, 59, 10, 15, 237, 58, + 10, 15, 237, 57, 10, 15, 237, 56, 10, 15, 237, 55, 10, 15, 237, 54, 10, + 15, 237, 53, 10, 15, 237, 52, 10, 15, 237, 51, 10, 15, 237, 50, 10, 15, + 237, 49, 10, 15, 237, 48, 10, 15, 237, 47, 10, 15, 237, 46, 10, 15, 237, + 45, 10, 15, 237, 44, 10, 15, 237, 43, 10, 15, 237, 42, 10, 15, 237, 41, + 10, 15, 237, 40, 10, 15, 237, 39, 10, 15, 237, 38, 10, 15, 237, 37, 10, + 15, 237, 36, 10, 15, 237, 35, 10, 15, 237, 34, 10, 15, 237, 33, 10, 15, + 237, 32, 10, 15, 237, 31, 10, 15, 237, 30, 10, 15, 237, 29, 10, 15, 237, + 28, 10, 15, 237, 27, 10, 15, 237, 26, 10, 15, 237, 25, 10, 15, 237, 24, + 10, 15, 237, 23, 10, 15, 237, 22, 10, 15, 237, 21, 10, 15, 237, 20, 10, + 15, 237, 19, 10, 15, 237, 18, 10, 15, 237, 17, 10, 15, 237, 16, 10, 15, + 237, 15, 10, 15, 237, 14, 10, 15, 237, 13, 10, 15, 237, 12, 10, 15, 237, + 11, 10, 15, 237, 10, 10, 15, 237, 9, 10, 15, 237, 8, 10, 15, 237, 7, 10, + 15, 237, 6, 10, 15, 237, 5, 10, 15, 237, 4, 10, 15, 237, 3, 10, 15, 237, + 2, 10, 15, 237, 1, 10, 15, 237, 0, 10, 15, 236, 255, 10, 15, 236, 254, + 10, 15, 236, 253, 10, 15, 236, 252, 10, 15, 236, 251, 10, 15, 236, 250, + 10, 15, 236, 249, 10, 15, 236, 248, 10, 15, 236, 247, 10, 15, 236, 246, + 10, 15, 236, 245, 10, 15, 236, 244, 10, 15, 236, 243, 10, 15, 236, 242, + 10, 15, 236, 241, 10, 15, 236, 240, 10, 15, 236, 239, 10, 15, 236, 238, + 10, 15, 236, 237, 10, 15, 236, 236, 10, 15, 236, 235, 10, 15, 236, 234, + 10, 15, 236, 233, 10, 15, 236, 232, 10, 15, 236, 231, 10, 15, 236, 230, + 10, 15, 236, 229, 10, 15, 236, 228, 10, 15, 236, 227, 10, 15, 236, 226, + 10, 15, 236, 225, 10, 15, 236, 224, 10, 15, 236, 223, 10, 15, 236, 222, + 10, 15, 236, 221, 10, 15, 236, 220, 10, 15, 236, 219, 10, 15, 236, 218, + 10, 15, 236, 217, 10, 15, 236, 216, 10, 15, 236, 215, 10, 15, 236, 214, + 10, 15, 236, 213, 10, 15, 236, 212, 10, 15, 236, 211, 10, 15, 236, 210, + 10, 15, 236, 209, 10, 15, 236, 208, 10, 15, 236, 207, 10, 15, 236, 206, + 10, 15, 236, 205, 10, 15, 236, 204, 10, 15, 236, 203, 10, 15, 236, 202, + 10, 15, 236, 201, 10, 15, 236, 200, 10, 15, 236, 199, 10, 15, 236, 198, + 10, 15, 236, 197, 10, 15, 236, 196, 10, 15, 236, 195, 10, 15, 236, 194, + 10, 15, 236, 193, 10, 15, 236, 192, 10, 15, 236, 191, 10, 15, 236, 190, + 10, 15, 236, 189, 10, 15, 236, 188, 10, 15, 236, 187, 10, 15, 236, 186, + 10, 15, 236, 185, 10, 15, 236, 184, 10, 15, 236, 183, 10, 15, 236, 182, + 10, 15, 236, 181, 10, 15, 236, 180, 10, 15, 236, 179, 10, 15, 236, 178, + 10, 15, 236, 177, 10, 15, 236, 176, 10, 15, 236, 175, 10, 15, 236, 174, + 10, 15, 236, 173, 10, 15, 236, 172, 10, 15, 236, 171, 10, 15, 236, 170, + 10, 15, 236, 169, 10, 15, 236, 168, 10, 15, 236, 167, 10, 15, 236, 166, + 10, 15, 236, 165, 10, 15, 236, 164, 10, 15, 236, 163, 10, 15, 236, 162, + 10, 15, 236, 161, 10, 15, 236, 160, 10, 15, 236, 159, 10, 15, 236, 158, + 10, 15, 236, 157, 10, 15, 236, 156, 10, 15, 236, 155, 10, 15, 236, 154, + 10, 15, 236, 153, 10, 15, 236, 152, 10, 15, 236, 151, 10, 15, 236, 150, + 10, 15, 236, 149, 10, 15, 236, 148, 10, 15, 236, 147, 10, 15, 236, 146, + 10, 15, 236, 145, 10, 15, 236, 144, 10, 15, 236, 143, 10, 15, 236, 142, + 10, 15, 236, 141, 10, 15, 236, 140, 10, 15, 236, 139, 10, 15, 236, 138, + 10, 15, 236, 137, 10, 15, 236, 136, 10, 15, 236, 135, 10, 15, 236, 134, + 10, 15, 236, 133, 10, 15, 236, 132, 10, 15, 236, 131, 10, 15, 236, 130, + 10, 15, 236, 129, 10, 15, 236, 128, 10, 15, 236, 127, 10, 15, 236, 126, + 10, 15, 236, 125, 10, 15, 236, 124, 10, 15, 236, 123, 10, 15, 236, 122, + 10, 15, 236, 121, 10, 15, 236, 120, 10, 15, 236, 119, 10, 15, 236, 118, + 10, 15, 236, 117, 10, 15, 236, 116, 10, 15, 236, 115, 10, 15, 236, 114, + 10, 15, 236, 113, 10, 15, 236, 112, 10, 15, 236, 111, 10, 15, 236, 110, + 10, 15, 236, 109, 10, 15, 236, 108, 10, 15, 236, 107, 10, 15, 236, 106, + 10, 15, 236, 105, 10, 15, 236, 104, 10, 15, 236, 103, 10, 15, 236, 102, + 10, 15, 236, 101, 10, 15, 236, 100, 10, 15, 236, 99, 10, 15, 236, 98, 10, + 15, 236, 97, 10, 15, 236, 96, 10, 15, 236, 95, 10, 15, 236, 94, 10, 15, + 236, 93, 10, 15, 236, 92, 10, 15, 236, 91, 10, 15, 236, 90, 10, 15, 236, + 89, 10, 15, 236, 88, 10, 15, 236, 87, 10, 15, 236, 86, 10, 15, 236, 85, + 10, 15, 236, 84, 10, 15, 236, 83, 10, 15, 236, 82, 10, 15, 236, 81, 10, + 15, 236, 80, 10, 15, 236, 79, 10, 15, 236, 78, 10, 15, 236, 77, 10, 15, + 236, 76, 10, 15, 236, 75, 10, 15, 236, 74, 10, 15, 236, 73, 10, 15, 236, + 72, 10, 15, 236, 71, 10, 15, 236, 70, 10, 15, 236, 69, 10, 15, 236, 68, + 10, 15, 236, 67, 10, 15, 236, 66, 10, 15, 236, 65, 10, 15, 236, 64, 10, + 15, 236, 63, 10, 15, 236, 62, 10, 15, 236, 61, 10, 15, 236, 60, 10, 15, + 236, 59, 10, 15, 236, 58, 10, 15, 236, 57, 10, 15, 236, 56, 10, 15, 236, + 55, 10, 15, 236, 54, 10, 15, 236, 53, 10, 15, 236, 52, 10, 15, 236, 51, + 10, 15, 236, 50, 10, 15, 236, 49, 10, 15, 236, 48, 10, 15, 236, 47, 10, + 15, 236, 46, 10, 15, 236, 45, 10, 15, 236, 44, 10, 15, 236, 43, 10, 15, + 236, 42, 10, 15, 236, 41, 10, 15, 236, 40, 10, 15, 236, 39, 10, 15, 236, + 38, 10, 15, 236, 37, 10, 15, 236, 36, 10, 15, 236, 35, 10, 15, 236, 34, + 10, 15, 236, 33, 10, 15, 236, 32, 10, 15, 236, 31, 10, 15, 236, 30, 10, + 15, 236, 29, 10, 15, 236, 28, 10, 15, 236, 27, 10, 15, 236, 26, 10, 15, + 236, 25, 10, 15, 236, 24, 10, 15, 236, 23, 10, 15, 236, 22, 10, 15, 236, + 21, 10, 15, 236, 20, 10, 15, 236, 19, 10, 15, 236, 18, 10, 15, 236, 17, + 10, 15, 236, 16, 10, 15, 236, 15, 10, 15, 236, 14, 10, 15, 236, 13, 10, + 15, 236, 12, 10, 15, 236, 11, 10, 15, 236, 10, 10, 15, 236, 9, 10, 15, + 236, 8, 10, 15, 236, 7, 10, 15, 236, 6, 10, 15, 236, 5, 10, 15, 236, 4, + 10, 15, 236, 3, 10, 15, 236, 2, 10, 15, 236, 1, 10, 15, 236, 0, 10, 15, + 235, 255, 10, 15, 235, 254, 10, 15, 235, 253, 10, 15, 235, 252, 10, 15, + 235, 251, 10, 15, 235, 250, 10, 15, 235, 249, 10, 15, 235, 248, 10, 15, + 235, 247, 10, 15, 235, 246, 10, 15, 235, 245, 10, 15, 235, 244, 10, 15, + 235, 243, 10, 15, 235, 242, 10, 15, 235, 241, 10, 15, 235, 240, 10, 15, + 235, 239, 10, 15, 235, 238, 10, 15, 235, 237, 10, 15, 235, 236, 10, 15, + 235, 235, 10, 15, 235, 234, 10, 15, 235, 233, 10, 15, 235, 232, 10, 15, + 235, 231, 10, 15, 235, 230, 10, 15, 235, 229, 10, 15, 235, 228, 10, 15, + 235, 227, 10, 15, 235, 226, 10, 15, 235, 225, 10, 15, 235, 224, 10, 15, + 235, 223, 10, 15, 235, 222, 10, 15, 235, 221, 10, 15, 235, 220, 10, 15, + 235, 219, 10, 15, 235, 218, 10, 15, 235, 217, 10, 15, 235, 216, 10, 15, + 235, 215, 10, 15, 235, 214, 10, 15, 235, 213, 10, 15, 235, 212, 10, 15, + 235, 211, 10, 15, 235, 210, 10, 15, 235, 209, 10, 15, 235, 208, 10, 15, + 235, 207, 10, 15, 235, 206, 10, 15, 235, 205, 10, 15, 235, 204, 10, 15, + 235, 203, 10, 15, 235, 202, 10, 15, 235, 201, 10, 15, 235, 200, 10, 15, + 235, 199, 10, 15, 235, 198, 10, 15, 235, 197, 10, 15, 235, 196, 10, 15, + 235, 195, 10, 15, 235, 194, 10, 15, 235, 193, 10, 15, 235, 192, 10, 15, + 235, 191, 10, 15, 235, 190, 10, 15, 235, 189, 10, 15, 235, 188, 10, 15, + 235, 187, 10, 15, 235, 186, 10, 15, 235, 185, 10, 15, 235, 184, 10, 15, + 235, 183, 10, 15, 235, 182, 10, 15, 235, 181, 10, 15, 235, 180, 10, 15, + 235, 179, 10, 15, 235, 178, 10, 15, 235, 177, 10, 15, 235, 176, 10, 15, + 235, 175, 10, 15, 235, 174, 10, 15, 235, 173, 10, 15, 235, 172, 10, 15, + 235, 171, 10, 15, 235, 170, 10, 15, 235, 169, 10, 15, 235, 168, 10, 15, + 235, 167, 10, 15, 235, 166, 10, 15, 235, 165, 10, 15, 235, 164, 10, 15, + 235, 163, 10, 15, 235, 162, 10, 15, 235, 161, 10, 15, 235, 160, 10, 15, + 235, 159, 10, 15, 235, 158, 10, 15, 235, 157, 10, 15, 235, 156, 10, 15, + 235, 155, 10, 15, 235, 154, 10, 15, 235, 153, 10, 15, 235, 152, 10, 15, + 235, 151, 10, 15, 235, 150, 10, 15, 235, 149, 10, 15, 235, 148, 10, 15, + 235, 147, 10, 15, 235, 146, 10, 15, 235, 145, 10, 15, 235, 144, 10, 15, + 235, 143, 10, 15, 235, 142, 230, 92, 212, 198, 150, 214, 153, 150, 242, + 168, 83, 150, 219, 180, 83, 150, 43, 53, 150, 245, 35, 53, 150, 221, 131, + 53, 150, 252, 125, 150, 252, 53, 150, 47, 221, 216, 150, 48, 221, 216, + 150, 251, 209, 150, 101, 53, 150, 247, 155, 150, 237, 238, 150, 241, 82, + 213, 251, 150, 214, 180, 150, 18, 205, 85, 150, 18, 102, 150, 18, 105, + 150, 18, 142, 150, 18, 139, 150, 18, 168, 150, 18, 184, 150, 18, 195, + 150, 18, 193, 150, 18, 200, 150, 247, 162, 150, 216, 52, 150, 230, 10, + 53, 150, 242, 242, 53, 150, 239, 230, 53, 150, 219, 196, 83, 150, 247, + 153, 251, 199, 150, 7, 6, 1, 62, 150, 7, 6, 1, 251, 150, 150, 7, 6, 1, + 249, 34, 150, 7, 6, 1, 246, 240, 150, 7, 6, 1, 75, 150, 7, 6, 1, 242, + 139, 150, 7, 6, 1, 241, 55, 150, 7, 6, 1, 239, 155, 150, 7, 6, 1, 74, + 150, 7, 6, 1, 232, 203, 150, 7, 6, 1, 232, 76, 150, 7, 6, 1, 149, 150, 7, + 6, 1, 229, 28, 150, 7, 6, 1, 226, 33, 150, 7, 6, 1, 76, 150, 7, 6, 1, + 222, 67, 150, 7, 6, 1, 220, 27, 150, 7, 6, 1, 137, 150, 7, 6, 1, 182, + 150, 7, 6, 1, 213, 10, 150, 7, 6, 1, 71, 150, 7, 6, 1, 209, 148, 150, 7, + 6, 1, 207, 129, 150, 7, 6, 1, 206, 195, 150, 7, 6, 1, 206, 123, 150, 7, + 6, 1, 205, 159, 150, 47, 49, 145, 150, 218, 225, 214, 180, 150, 48, 49, + 145, 150, 247, 228, 253, 21, 150, 114, 229, 205, 150, 239, 237, 253, 21, + 150, 7, 5, 1, 62, 150, 7, 5, 1, 251, 150, 150, 7, 5, 1, 249, 34, 150, 7, + 5, 1, 246, 240, 150, 7, 5, 1, 75, 150, 7, 5, 1, 242, 139, 150, 7, 5, 1, + 241, 55, 150, 7, 5, 1, 239, 155, 150, 7, 5, 1, 74, 150, 7, 5, 1, 232, + 203, 150, 7, 5, 1, 232, 76, 150, 7, 5, 1, 149, 150, 7, 5, 1, 229, 28, + 150, 7, 5, 1, 226, 33, 150, 7, 5, 1, 76, 150, 7, 5, 1, 222, 67, 150, 7, + 5, 1, 220, 27, 150, 7, 5, 1, 137, 150, 7, 5, 1, 182, 150, 7, 5, 1, 213, + 10, 150, 7, 5, 1, 71, 150, 7, 5, 1, 209, 148, 150, 7, 5, 1, 207, 129, + 150, 7, 5, 1, 206, 195, 150, 7, 5, 1, 206, 123, 150, 7, 5, 1, 205, 159, + 150, 47, 247, 26, 145, 150, 79, 229, 205, 150, 48, 247, 26, 145, 150, + 211, 180, 248, 225, 212, 198, 54, 216, 236, 54, 216, 225, 54, 216, 214, + 54, 216, 202, 54, 216, 191, 54, 216, 180, 54, 216, 169, 54, 216, 158, 54, + 216, 147, 54, 216, 139, 54, 216, 138, 54, 216, 137, 54, 216, 136, 54, + 216, 134, 54, 216, 133, 54, 216, 132, 54, 216, 131, 54, 216, 130, 54, + 216, 129, 54, 216, 128, 54, 216, 127, 54, 216, 126, 54, 216, 125, 54, + 216, 123, 54, 216, 122, 54, 216, 121, 54, 216, 120, 54, 216, 119, 54, + 216, 118, 54, 216, 117, 54, 216, 116, 54, 216, 115, 54, 216, 114, 54, + 216, 112, 54, 216, 111, 54, 216, 110, 54, 216, 109, 54, 216, 108, 54, + 216, 107, 54, 216, 106, 54, 216, 105, 54, 216, 104, 54, 216, 103, 54, + 216, 101, 54, 216, 100, 54, 216, 99, 54, 216, 98, 54, 216, 97, 54, 216, + 96, 54, 216, 95, 54, 216, 94, 54, 216, 93, 54, 216, 92, 54, 216, 90, 54, + 216, 89, 54, 216, 88, 54, 216, 87, 54, 216, 86, 54, 216, 85, 54, 216, 84, + 54, 216, 83, 54, 216, 82, 54, 216, 81, 54, 216, 79, 54, 216, 78, 54, 216, + 77, 54, 216, 76, 54, 216, 75, 54, 216, 74, 54, 216, 73, 54, 216, 72, 54, + 216, 71, 54, 216, 70, 54, 216, 68, 54, 216, 67, 54, 216, 66, 54, 216, 65, + 54, 216, 64, 54, 216, 63, 54, 216, 62, 54, 216, 61, 54, 216, 60, 54, 216, + 59, 54, 217, 56, 54, 217, 55, 54, 217, 54, 54, 217, 53, 54, 217, 52, 54, + 217, 51, 54, 217, 50, 54, 217, 49, 54, 217, 48, 54, 217, 47, 54, 217, 45, + 54, 217, 44, 54, 217, 43, 54, 217, 42, 54, 217, 41, 54, 217, 40, 54, 217, + 39, 54, 217, 38, 54, 217, 37, 54, 217, 36, 54, 217, 34, 54, 217, 33, 54, + 217, 32, 54, 217, 31, 54, 217, 30, 54, 217, 29, 54, 217, 28, 54, 217, 27, + 54, 217, 26, 54, 217, 25, 54, 217, 23, 54, 217, 22, 54, 217, 21, 54, 217, + 20, 54, 217, 19, 54, 217, 18, 54, 217, 17, 54, 217, 16, 54, 217, 15, 54, + 217, 14, 54, 217, 12, 54, 217, 11, 54, 217, 10, 54, 217, 9, 54, 217, 8, + 54, 217, 7, 54, 217, 6, 54, 217, 5, 54, 217, 4, 54, 217, 3, 54, 217, 1, + 54, 217, 0, 54, 216, 255, 54, 216, 254, 54, 216, 253, 54, 216, 252, 54, + 216, 251, 54, 216, 250, 54, 216, 249, 54, 216, 248, 54, 216, 246, 54, + 216, 245, 54, 216, 244, 54, 216, 243, 54, 216, 242, 54, 216, 241, 54, + 216, 240, 54, 216, 239, 54, 216, 238, 54, 216, 237, 54, 216, 235, 54, + 216, 234, 54, 216, 233, 54, 216, 232, 54, 216, 231, 54, 216, 230, 54, + 216, 229, 54, 216, 228, 54, 216, 227, 54, 216, 226, 54, 216, 224, 54, + 216, 223, 54, 216, 222, 54, 216, 221, 54, 216, 220, 54, 216, 219, 54, + 216, 218, 54, 216, 217, 54, 216, 216, 54, 216, 215, 54, 216, 213, 54, + 216, 212, 54, 216, 211, 54, 216, 210, 54, 216, 209, 54, 216, 208, 54, + 216, 207, 54, 216, 206, 54, 216, 205, 54, 216, 204, 54, 216, 201, 54, + 216, 200, 54, 216, 199, 54, 216, 198, 54, 216, 197, 54, 216, 196, 54, + 216, 195, 54, 216, 194, 54, 216, 193, 54, 216, 192, 54, 216, 190, 54, + 216, 189, 54, 216, 188, 54, 216, 187, 54, 216, 186, 54, 216, 185, 54, + 216, 184, 54, 216, 183, 54, 216, 182, 54, 216, 181, 54, 216, 179, 54, + 216, 178, 54, 216, 177, 54, 216, 176, 54, 216, 175, 54, 216, 174, 54, + 216, 173, 54, 216, 172, 54, 216, 171, 54, 216, 170, 54, 216, 168, 54, + 216, 167, 54, 216, 166, 54, 216, 165, 54, 216, 164, 54, 216, 163, 54, + 216, 162, 54, 216, 161, 54, 216, 160, 54, 216, 159, 54, 216, 157, 54, + 216, 156, 54, 216, 155, 54, 216, 154, 54, 216, 153, 54, 216, 152, 54, + 216, 151, 54, 216, 150, 54, 216, 149, 54, 216, 148, 54, 216, 146, 54, + 216, 145, 54, 216, 144, 54, 216, 143, 54, 216, 142, 54, 216, 141, 54, + 216, 140, 223, 181, 223, 183, 214, 22, 73, 239, 66, 214, 183, 214, 22, + 73, 212, 60, 213, 205, 243, 34, 73, 212, 60, 242, 193, 243, 34, 73, 211, + 69, 242, 254, 243, 21, 243, 22, 253, 13, 253, 14, 252, 169, 250, 31, 250, + 170, 249, 107, 157, 212, 203, 194, 212, 203, 238, 47, 212, 207, 229, 206, + 242, 19, 186, 229, 205, 243, 34, 73, 229, 205, 229, 250, 224, 129, 243, + 1, 229, 206, 212, 203, 79, 212, 203, 207, 150, 241, 136, 242, 19, 241, + 254, 248, 191, 218, 228, 247, 73, 215, 179, 222, 93, 229, 138, 102, 214, + 193, 215, 179, 233, 68, 229, 138, 205, 85, 215, 80, 246, 73, 229, 196, + 242, 217, 245, 61, 245, 199, 247, 109, 102, 246, 62, 245, 199, 247, 109, + 105, 246, 61, 245, 199, 247, 109, 142, 246, 60, 245, 199, 247, 109, 139, + 246, 59, 170, 253, 13, 225, 215, 213, 36, 233, 131, 213, 39, 243, 34, 73, + 211, 70, 249, 193, 242, 200, 248, 224, 248, 226, 243, 34, 73, 227, 108, + 242, 255, 213, 179, 213, 196, 242, 217, 242, 218, 233, 43, 216, 40, 139, + 241, 236, 216, 39, 241, 92, 233, 43, 216, 40, 142, 239, 221, 216, 39, + 239, 218, 233, 43, 216, 40, 105, 219, 43, 216, 39, 218, 55, 233, 43, 216, + 40, 102, 209, 217, 216, 39, 209, 177, 214, 156, 245, 236, 245, 238, 222, + 40, 248, 94, 222, 42, 127, 222, 213, 220, 130, 238, 124, 249, 126, 221, + 121, 239, 35, 249, 137, 224, 68, 249, 126, 239, 35, 225, 179, 233, 53, + 233, 56, 225, 82, 229, 205, 225, 102, 214, 22, 73, 217, 61, 252, 13, 214, + 96, 243, 34, 73, 217, 61, 252, 13, 242, 220, 157, 212, 204, 216, 28, 194, + 212, 204, 216, 28, 238, 44, 157, 212, 204, 2, 232, 88, 194, 212, 204, 2, + 232, 88, 238, 45, 229, 206, 212, 204, 216, 28, 79, 212, 204, 216, 28, + 207, 149, 221, 209, 229, 206, 241, 129, 221, 209, 229, 206, 244, 8, 220, + 229, 221, 209, 229, 206, 250, 169, 221, 209, 229, 206, 209, 206, 220, + 224, 218, 225, 229, 206, 242, 19, 218, 225, 233, 53, 218, 208, 215, 41, + 215, 179, 105, 215, 38, 214, 98, 215, 41, 215, 179, 142, 215, 37, 214, + 97, 245, 199, 247, 109, 213, 227, 246, 57, 220, 118, 209, 176, 102, 220, + 118, 209, 174, 220, 81, 220, 118, 209, 176, 105, 220, 118, 209, 173, 220, + 80, 216, 29, 211, 68, 214, 21, 213, 210, 248, 225, 248, 94, 248, 167, + 227, 67, 207, 89, 226, 51, 214, 22, 73, 239, 206, 252, 13, 214, 22, 73, + 220, 99, 252, 13, 214, 155, 243, 34, 73, 239, 206, 252, 13, 243, 34, 73, + 220, 99, 252, 13, 242, 252, 214, 22, 73, 213, 227, 214, 169, 215, 41, + 239, 241, 157, 233, 4, 216, 7, 215, 41, 157, 233, 4, 217, 99, 247, 109, + 216, 37, 233, 4, 247, 41, 213, 228, 212, 86, 214, 40, 222, 134, 213, 25, + 247, 154, 222, 105, 220, 119, 227, 66, 220, 214, 252, 49, 220, 113, 247, + 154, 252, 65, 225, 167, 215, 89, 7, 6, 1, 240, 99, 7, 5, 1, 240, 99, 248, + 112, 252, 150, 213, 30, 213, 185, 247, 163, 214, 246, 230, 46, 183, 1, + 229, 163, 230, 90, 1, 241, 163, 241, 154, 230, 90, 1, 241, 163, 242, 31, + 230, 90, 1, 218, 124, 230, 90, 1, 229, 144, 72, 141, 249, 204, 215, 154, + 240, 62, 227, 16, 218, 215, 241, 69, 241, 68, 241, 67, 226, 53, 204, 246, + 204, 247, 204, 249, 229, 85, 218, 132, 229, 87, 218, 134, 221, 177, 229, + 84, 218, 131, 224, 99, 226, 185, 206, 252, 229, 86, 218, 133, 241, 91, + 221, 176, 207, 42, 243, 53, 241, 79, 226, 253, 222, 166, 209, 178, 93, + 226, 253, 246, 79, 93, 9, 4, 232, 218, 83, 220, 131, 241, 136, 33, 79, + 48, 59, 230, 16, 145, 208, 150, 208, 39, 207, 227, 207, 216, 207, 205, + 207, 194, 207, 183, 207, 172, 207, 161, 208, 149, 208, 138, 208, 127, + 208, 116, 208, 105, 208, 94, 208, 83, 249, 39, 222, 119, 83, 249, 175, + 204, 248, 14, 3, 223, 190, 212, 89, 14, 3, 223, 190, 131, 223, 190, 249, + 69, 131, 249, 68, 58, 30, 16, 241, 90, 214, 242, 248, 18, 209, 49, 208, + 72, 208, 61, 208, 50, 208, 38, 208, 27, 208, 16, 208, 5, 207, 250, 207, + 239, 207, 231, 207, 230, 207, 229, 207, 228, 207, 226, 207, 225, 207, + 224, 207, 223, 207, 222, 207, 221, 207, 220, 207, 219, 207, 218, 207, + 217, 207, 215, 207, 214, 207, 213, 207, 212, 207, 211, 207, 210, 207, + 209, 207, 208, 207, 207, 207, 206, 207, 204, 207, 203, 207, 202, 207, + 201, 207, 200, 207, 199, 207, 198, 207, 197, 207, 196, 207, 195, 207, + 193, 207, 192, 207, 191, 207, 190, 207, 189, 207, 188, 207, 187, 207, + 186, 207, 185, 207, 184, 207, 182, 207, 181, 207, 180, 207, 179, 207, + 178, 207, 177, 207, 176, 207, 175, 207, 174, 207, 173, 207, 171, 207, + 170, 207, 169, 207, 168, 207, 167, 207, 166, 207, 165, 207, 164, 207, + 163, 207, 162, 207, 160, 207, 159, 207, 158, 207, 157, 207, 156, 207, + 155, 207, 154, 207, 153, 207, 152, 207, 151, 208, 148, 208, 147, 208, + 146, 208, 145, 208, 144, 208, 143, 208, 142, 208, 141, 208, 140, 208, + 139, 208, 137, 208, 136, 208, 135, 208, 134, 208, 133, 208, 132, 208, + 131, 208, 130, 208, 129, 208, 128, 208, 126, 208, 125, 208, 124, 208, + 123, 208, 122, 208, 121, 208, 120, 208, 119, 208, 118, 208, 117, 208, + 115, 208, 114, 208, 113, 208, 112, 208, 111, 208, 110, 208, 109, 208, + 108, 208, 107, 208, 106, 208, 104, 208, 103, 208, 102, 208, 101, 208, + 100, 208, 99, 208, 98, 208, 97, 208, 96, 208, 95, 208, 93, 208, 92, 208, + 91, 208, 90, 208, 89, 208, 88, 208, 87, 208, 86, 208, 85, 208, 84, 208, + 82, 208, 81, 208, 80, 208, 79, 208, 78, 208, 77, 208, 76, 208, 75, 208, + 74, 208, 73, 208, 71, 208, 70, 208, 69, 208, 68, 208, 67, 208, 66, 208, + 65, 208, 64, 208, 63, 208, 62, 208, 60, 208, 59, 208, 58, 208, 57, 208, + 56, 208, 55, 208, 54, 208, 53, 208, 52, 208, 51, 208, 49, 208, 48, 208, + 47, 208, 46, 208, 45, 208, 44, 208, 43, 208, 42, 208, 41, 208, 40, 208, + 37, 208, 36, 208, 35, 208, 34, 208, 33, 208, 32, 208, 31, 208, 30, 208, + 29, 208, 28, 208, 26, 208, 25, 208, 24, 208, 23, 208, 22, 208, 21, 208, + 20, 208, 19, 208, 18, 208, 17, 208, 15, 208, 14, 208, 13, 208, 12, 208, + 11, 208, 10, 208, 9, 208, 8, 208, 7, 208, 6, 208, 4, 208, 3, 208, 2, 208, + 1, 208, 0, 207, 255, 207, 254, 207, 253, 207, 252, 207, 251, 207, 249, + 207, 248, 207, 247, 207, 246, 207, 245, 207, 244, 207, 243, 207, 242, + 207, 241, 207, 240, 207, 238, 207, 237, 207, 236, 207, 235, 207, 234, + 207, 233, 207, 232, 7, 6, 1, 32, 2, 228, 14, 23, 239, 236, 7, 5, 1, 32, + 2, 228, 14, 23, 239, 236, 7, 6, 1, 174, 2, 79, 229, 206, 55, 7, 5, 1, + 174, 2, 79, 229, 206, 55, 7, 6, 1, 174, 2, 79, 229, 206, 250, 26, 23, + 239, 236, 7, 5, 1, 174, 2, 79, 229, 206, 250, 26, 23, 239, 236, 7, 6, 1, + 174, 2, 79, 229, 206, 250, 26, 23, 153, 7, 5, 1, 174, 2, 79, 229, 206, + 250, 26, 23, 153, 7, 6, 1, 174, 2, 247, 228, 23, 228, 13, 7, 5, 1, 174, + 2, 247, 228, 23, 228, 13, 7, 6, 1, 174, 2, 247, 228, 23, 248, 195, 7, 5, + 1, 174, 2, 247, 228, 23, 248, 195, 7, 6, 1, 237, 225, 2, 228, 14, 23, + 239, 236, 7, 5, 1, 237, 225, 2, 228, 14, 23, 239, 236, 7, 5, 1, 237, 225, + 2, 67, 84, 23, 153, 7, 5, 1, 225, 80, 2, 211, 181, 52, 7, 6, 1, 148, 2, + 79, 229, 206, 55, 7, 5, 1, 148, 2, 79, 229, 206, 55, 7, 6, 1, 148, 2, 79, + 229, 206, 250, 26, 23, 239, 236, 7, 5, 1, 148, 2, 79, 229, 206, 250, 26, + 23, 239, 236, 7, 6, 1, 148, 2, 79, 229, 206, 250, 26, 23, 153, 7, 5, 1, + 148, 2, 79, 229, 206, 250, 26, 23, 153, 7, 6, 1, 218, 1, 2, 79, 229, 206, + 55, 7, 5, 1, 218, 1, 2, 79, 229, 206, 55, 7, 6, 1, 106, 2, 228, 14, 23, + 239, 236, 7, 5, 1, 106, 2, 228, 14, 23, 239, 236, 7, 6, 1, 32, 2, 222, + 197, 23, 153, 7, 5, 1, 32, 2, 222, 197, 23, 153, 7, 6, 1, 32, 2, 222, + 197, 23, 211, 180, 7, 5, 1, 32, 2, 222, 197, 23, 211, 180, 7, 6, 1, 174, + 2, 222, 197, 23, 153, 7, 5, 1, 174, 2, 222, 197, 23, 153, 7, 6, 1, 174, + 2, 222, 197, 23, 211, 180, 7, 5, 1, 174, 2, 222, 197, 23, 211, 180, 7, 6, + 1, 174, 2, 67, 84, 23, 153, 7, 5, 1, 174, 2, 67, 84, 23, 153, 7, 6, 1, + 174, 2, 67, 84, 23, 211, 180, 7, 5, 1, 174, 2, 67, 84, 23, 211, 180, 7, + 5, 1, 237, 225, 2, 67, 84, 23, 239, 236, 7, 5, 1, 237, 225, 2, 67, 84, + 23, 211, 180, 7, 6, 1, 237, 225, 2, 222, 197, 23, 153, 7, 5, 1, 237, 225, + 2, 222, 197, 23, 67, 84, 23, 153, 7, 6, 1, 237, 225, 2, 222, 197, 23, + 211, 180, 7, 5, 1, 237, 225, 2, 222, 197, 23, 67, 84, 23, 211, 180, 7, 6, + 1, 232, 204, 2, 211, 180, 7, 5, 1, 232, 204, 2, 67, 84, 23, 211, 180, 7, + 6, 1, 230, 159, 2, 211, 180, 7, 5, 1, 230, 159, 2, 211, 180, 7, 6, 1, + 229, 29, 2, 211, 180, 7, 5, 1, 229, 29, 2, 211, 180, 7, 6, 1, 219, 150, + 2, 211, 180, 7, 5, 1, 219, 150, 2, 211, 180, 7, 6, 1, 106, 2, 222, 197, + 23, 153, 7, 5, 1, 106, 2, 222, 197, 23, 153, 7, 6, 1, 106, 2, 222, 197, + 23, 211, 180, 7, 5, 1, 106, 2, 222, 197, 23, 211, 180, 7, 6, 1, 106, 2, + 228, 14, 23, 153, 7, 5, 1, 106, 2, 228, 14, 23, 153, 7, 6, 1, 106, 2, + 228, 14, 23, 211, 180, 7, 5, 1, 106, 2, 228, 14, 23, 211, 180, 7, 5, 1, + 252, 249, 2, 239, 236, 7, 5, 1, 222, 142, 148, 2, 239, 236, 7, 5, 1, 222, + 142, 148, 2, 153, 7, 5, 1, 201, 209, 149, 2, 239, 236, 7, 5, 1, 201, 209, + 149, 2, 153, 7, 5, 1, 217, 101, 2, 239, 236, 7, 5, 1, 217, 101, 2, 153, + 7, 5, 1, 238, 129, 217, 101, 2, 239, 236, 7, 5, 1, 238, 129, 217, 101, 2, + 153, 8, 216, 37, 87, 2, 239, 112, 84, 2, 252, 172, 8, 216, 37, 87, 2, + 239, 112, 84, 2, 207, 59, 8, 216, 37, 87, 2, 239, 112, 84, 2, 126, 227, + 228, 8, 216, 37, 87, 2, 239, 112, 84, 2, 222, 206, 8, 216, 37, 87, 2, + 239, 112, 84, 2, 71, 8, 216, 37, 87, 2, 239, 112, 84, 2, 205, 213, 8, + 216, 37, 87, 2, 239, 112, 84, 2, 75, 8, 216, 37, 87, 2, 239, 112, 84, 2, + 252, 248, 8, 216, 37, 224, 55, 2, 231, 212, 165, 1, 231, 142, 40, 107, + 232, 76, 40, 107, 225, 79, 40, 107, 249, 34, 40, 107, 223, 146, 40, 107, + 210, 211, 40, 107, 224, 104, 40, 107, 213, 10, 40, 107, 226, 33, 40, 107, + 222, 67, 40, 107, 229, 28, 40, 107, 206, 123, 40, 107, 137, 40, 107, 149, + 40, 107, 209, 148, 40, 107, 229, 164, 40, 107, 229, 173, 40, 107, 218, + 90, 40, 107, 224, 86, 40, 107, 232, 203, 40, 107, 216, 4, 40, 107, 214, + 99, 40, 107, 182, 40, 107, 239, 155, 40, 107, 230, 251, 40, 4, 232, 63, + 40, 4, 231, 123, 40, 4, 231, 111, 40, 4, 230, 236, 40, 4, 230, 202, 40, + 4, 231, 224, 40, 4, 231, 221, 40, 4, 232, 41, 40, 4, 231, 53, 40, 4, 231, + 33, 40, 4, 231, 242, 40, 4, 225, 76, 40, 4, 225, 25, 40, 4, 225, 21, 40, + 4, 224, 246, 40, 4, 224, 238, 40, 4, 225, 64, 40, 4, 225, 62, 40, 4, 225, + 73, 40, 4, 225, 2, 40, 4, 224, 253, 40, 4, 225, 66, 40, 4, 249, 0, 40, 4, + 247, 251, 40, 4, 247, 241, 40, 4, 247, 40, 40, 4, 247, 9, 40, 4, 248, + 148, 40, 4, 248, 140, 40, 4, 248, 245, 40, 4, 247, 174, 40, 4, 247, 105, + 40, 4, 248, 181, 40, 4, 223, 143, 40, 4, 223, 125, 40, 4, 223, 120, 40, + 4, 223, 103, 40, 4, 223, 95, 40, 4, 223, 134, 40, 4, 223, 133, 40, 4, + 223, 140, 40, 4, 223, 110, 40, 4, 223, 107, 40, 4, 223, 137, 40, 4, 210, + 207, 40, 4, 210, 187, 40, 4, 210, 186, 40, 4, 210, 175, 40, 4, 210, 172, + 40, 4, 210, 203, 40, 4, 210, 202, 40, 4, 210, 206, 40, 4, 210, 185, 40, + 4, 210, 184, 40, 4, 210, 205, 40, 4, 224, 102, 40, 4, 224, 88, 40, 4, + 224, 87, 40, 4, 224, 71, 40, 4, 224, 70, 40, 4, 224, 98, 40, 4, 224, 97, + 40, 4, 224, 101, 40, 4, 224, 73, 40, 4, 224, 72, 40, 4, 224, 100, 40, 4, + 212, 215, 40, 4, 211, 211, 40, 4, 211, 195, 40, 4, 210, 170, 40, 4, 210, + 135, 40, 4, 212, 131, 40, 4, 212, 120, 40, 4, 212, 193, 40, 4, 124, 40, + 4, 211, 105, 40, 4, 212, 151, 40, 4, 225, 232, 40, 4, 224, 230, 40, 4, + 224, 205, 40, 4, 223, 217, 40, 4, 223, 158, 40, 4, 225, 110, 40, 4, 225, + 106, 40, 4, 225, 218, 40, 4, 224, 67, 40, 4, 224, 56, 40, 4, 225, 191, + 40, 4, 222, 51, 40, 4, 221, 53, 40, 4, 221, 15, 40, 4, 220, 82, 40, 4, + 220, 50, 40, 4, 221, 174, 40, 4, 221, 164, 40, 4, 222, 32, 40, 4, 220, + 211, 40, 4, 220, 187, 40, 4, 221, 188, 40, 4, 228, 18, 40, 4, 226, 254, + 40, 4, 226, 224, 40, 4, 226, 114, 40, 4, 226, 62, 40, 4, 227, 119, 40, 4, + 227, 107, 40, 4, 227, 239, 40, 4, 226, 181, 40, 4, 226, 150, 40, 4, 227, + 166, 40, 4, 206, 109, 40, 4, 206, 11, 40, 4, 206, 2, 40, 4, 205, 213, 40, + 4, 205, 181, 40, 4, 206, 52, 40, 4, 206, 49, 40, 4, 206, 88, 40, 4, 205, + 247, 40, 4, 205, 232, 40, 4, 206, 61, 40, 4, 219, 109, 40, 4, 218, 208, + 40, 4, 218, 154, 40, 4, 218, 50, 40, 4, 218, 21, 40, 4, 219, 51, 40, 4, + 219, 29, 40, 4, 219, 90, 40, 4, 218, 124, 40, 4, 218, 107, 40, 4, 219, + 60, 40, 4, 230, 140, 40, 4, 229, 235, 40, 4, 229, 219, 40, 4, 229, 81, + 40, 4, 229, 53, 40, 4, 230, 58, 40, 4, 230, 50, 40, 4, 230, 114, 40, 4, + 229, 144, 40, 4, 229, 115, 40, 4, 230, 75, 40, 4, 209, 69, 40, 4, 208, + 214, 40, 4, 208, 199, 40, 4, 207, 148, 40, 4, 207, 141, 40, 4, 209, 39, + 40, 4, 209, 34, 40, 4, 209, 65, 40, 4, 208, 173, 40, 4, 208, 161, 40, 4, + 209, 45, 40, 4, 229, 162, 40, 4, 229, 157, 40, 4, 229, 156, 40, 4, 229, + 153, 40, 4, 229, 152, 40, 4, 229, 159, 40, 4, 229, 158, 40, 4, 229, 161, + 40, 4, 229, 155, 40, 4, 229, 154, 40, 4, 229, 160, 40, 4, 229, 171, 40, + 4, 229, 166, 40, 4, 229, 165, 40, 4, 229, 149, 40, 4, 229, 148, 40, 4, + 229, 168, 40, 4, 229, 167, 40, 4, 229, 170, 40, 4, 229, 151, 40, 4, 229, + 150, 40, 4, 229, 169, 40, 4, 218, 88, 40, 4, 218, 77, 40, 4, 218, 76, 40, + 4, 218, 70, 40, 4, 218, 63, 40, 4, 218, 84, 40, 4, 218, 83, 40, 4, 218, + 87, 40, 4, 218, 75, 40, 4, 218, 74, 40, 4, 218, 86, 40, 4, 224, 84, 40, + 4, 224, 79, 40, 4, 224, 78, 40, 4, 224, 75, 40, 4, 224, 74, 40, 4, 224, + 81, 40, 4, 224, 80, 40, 4, 224, 83, 40, 4, 224, 77, 40, 4, 224, 76, 40, + 4, 224, 82, 40, 4, 232, 199, 40, 4, 232, 162, 40, 4, 232, 155, 40, 4, + 232, 104, 40, 4, 232, 86, 40, 4, 232, 182, 40, 4, 232, 180, 40, 4, 232, + 193, 40, 4, 232, 122, 40, 4, 232, 113, 40, 4, 232, 187, 40, 4, 215, 254, + 40, 4, 215, 183, 40, 4, 215, 178, 40, 4, 215, 116, 40, 4, 215, 100, 40, + 4, 215, 214, 40, 4, 215, 212, 40, 4, 215, 243, 40, 4, 215, 158, 40, 4, + 215, 152, 40, 4, 215, 223, 40, 4, 214, 95, 40, 4, 214, 64, 40, 4, 214, + 60, 40, 4, 214, 51, 40, 4, 214, 48, 40, 4, 214, 70, 40, 4, 214, 69, 40, + 4, 214, 94, 40, 4, 214, 56, 40, 4, 214, 55, 40, 4, 214, 72, 40, 4, 217, + 196, 40, 4, 215, 80, 40, 4, 215, 61, 40, 4, 213, 203, 40, 4, 213, 119, + 40, 4, 217, 86, 40, 4, 217, 74, 40, 4, 217, 181, 40, 4, 214, 193, 40, 4, + 214, 174, 40, 4, 217, 125, 40, 4, 239, 141, 40, 4, 239, 11, 40, 4, 238, + 247, 40, 4, 238, 42, 40, 4, 238, 19, 40, 4, 239, 71, 40, 4, 239, 53, 40, + 4, 239, 131, 40, 4, 238, 149, 40, 4, 238, 131, 40, 4, 239, 80, 40, 4, + 230, 250, 40, 4, 230, 249, 40, 4, 230, 244, 40, 4, 230, 243, 40, 4, 230, + 240, 40, 4, 230, 239, 40, 4, 230, 246, 40, 4, 230, 245, 40, 4, 230, 248, + 40, 4, 230, 242, 40, 4, 230, 241, 40, 4, 230, 247, 40, 4, 215, 122, 132, + 107, 3, 206, 74, 132, 107, 3, 219, 79, 132, 107, 3, 218, 253, 108, 1, + 210, 74, 82, 107, 3, 247, 169, 172, 82, 107, 3, 247, 169, 231, 167, 82, + 107, 3, 247, 169, 231, 53, 82, 107, 3, 247, 169, 231, 138, 82, 107, 3, + 247, 169, 225, 2, 82, 107, 3, 247, 169, 249, 1, 82, 107, 3, 247, 169, + 248, 110, 82, 107, 3, 247, 169, 247, 174, 82, 107, 3, 247, 169, 248, 32, + 82, 107, 3, 247, 169, 223, 110, 82, 107, 3, 247, 169, 246, 145, 82, 107, + 3, 247, 169, 210, 196, 82, 107, 3, 247, 169, 245, 51, 82, 107, 3, 247, + 169, 210, 191, 82, 107, 3, 247, 169, 199, 82, 107, 3, 247, 169, 212, 219, + 82, 107, 3, 247, 169, 212, 56, 82, 107, 3, 247, 169, 124, 82, 107, 3, + 247, 169, 211, 253, 82, 107, 3, 247, 169, 224, 67, 82, 107, 3, 247, 169, + 250, 183, 82, 107, 3, 247, 169, 221, 93, 82, 107, 3, 247, 169, 220, 211, + 82, 107, 3, 247, 169, 221, 66, 82, 107, 3, 247, 169, 226, 181, 82, 107, + 3, 247, 169, 205, 247, 82, 107, 3, 247, 169, 218, 124, 82, 107, 3, 247, + 169, 229, 144, 82, 107, 3, 247, 169, 208, 173, 82, 107, 3, 247, 169, 216, + 2, 82, 107, 3, 247, 169, 214, 96, 82, 107, 3, 247, 169, 217, 199, 82, + 107, 3, 247, 169, 155, 82, 107, 3, 247, 169, 230, 141, 82, 22, 3, 247, + 169, 220, 19, 82, 233, 55, 22, 3, 247, 169, 219, 214, 82, 233, 55, 22, 3, + 247, 169, 218, 9, 82, 233, 55, 22, 3, 247, 169, 218, 2, 82, 233, 55, 22, + 3, 247, 169, 219, 255, 82, 22, 3, 222, 173, 82, 22, 3, 253, 125, 161, 1, + 249, 237, 225, 77, 161, 1, 249, 237, 225, 25, 161, 1, 249, 237, 224, 246, + 161, 1, 249, 237, 225, 64, 161, 1, 249, 237, 225, 2, 64, 1, 249, 237, + 225, 77, 64, 1, 249, 237, 225, 25, 64, 1, 249, 237, 224, 246, 64, 1, 249, + 237, 225, 64, 64, 1, 249, 237, 225, 2, 64, 1, 252, 198, 248, 148, 64, 1, + 252, 198, 210, 170, 64, 1, 252, 198, 124, 64, 1, 252, 198, 222, 67, 65, + 1, 242, 156, 242, 155, 247, 113, 135, 134, 65, 1, 242, 155, 242, 156, + 247, 113, 135, 134, }; static unsigned char phrasebook_offset1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, - 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, - 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 104, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 105, 106, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, - 124, 125, 126, 127, 128, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 129, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 130, 131, - 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, - 146, 147, 87, 148, 149, 150, 151, 152, 87, 87, 87, 87, 87, 87, 153, 87, - 154, 155, 156, 87, 157, 87, 158, 87, 87, 87, 159, 87, 87, 87, 160, 161, - 162, 163, 87, 87, 87, 87, 87, 87, 87, 87, 87, 164, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 165, 166, 167, 168, - 169, 170, 171, 87, 172, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 173, 174, 175, 176, 177, 178, - 179, 180, 181, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 182, - 183, 184, 185, 186, 87, 87, 87, 87, 87, 87, 87, 87, 87, 187, 188, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 189, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 190, 191, 192, 193, 194, 87, 195, - 87, 196, 197, 198, 199, 200, 201, 202, 203, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 204, 205, 87, 87, 206, 207, 208, 209, 210, 87, 211, 212, 213, 214, - 215, 216, 217, 218, 219, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 220, 221, - 222, 223, 224, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 225, 87, 226, 227, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 228, 229, 230, 231, 232, 233, 234, 235, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 53, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 66, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 52, 87, 52, 88, + 89, 90, 91, 92, 93, 94, 52, 95, 52, 96, 52, 52, 52, 52, 52, 97, 98, 99, + 100, 101, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 102, 103, 104, 105, + 106, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 107, 108, + 109, 110, 52, 52, 52, 111, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 112, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 113, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 114, 115, 116, 117, + 118, 119, 120, 121, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 122, 52, 52, 52, 52, 52, 123, 52, 124, 125, 126, 127, 128, + 129, 130, 131, 132, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 133, 134, 135, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 136, 137, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 138, 139, 140, 141, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, }; static unsigned int phrasebook_offset2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 6, 9, 11, 14, 17, 19, 21, 24, 27, 29, 31, 33, 35, 39, 41, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 69, 72, - 75, 78, 82, 86, 91, 96, 101, 105, 110, 115, 120, 124, 129, 134, 138, 142, - 147, 151, 156, 161, 165, 170, 175, 179, 184, 189, 194, 199, 204, 207, + 75, 78, 82, 86, 91, 96, 101, 105, 110, 115, 120, 124, 129, 134, 138, 143, + 148, 152, 157, 162, 166, 170, 175, 179, 184, 189, 194, 199, 204, 207, 211, 214, 218, 221, 225, 229, 234, 239, 244, 248, 253, 258, 263, 267, - 272, 277, 281, 285, 290, 294, 299, 304, 308, 313, 318, 322, 327, 332, + 272, 277, 281, 286, 291, 295, 300, 305, 309, 313, 318, 322, 327, 332, 337, 342, 347, 351, 354, 358, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 359, 363, 368, - 371, 374, 377, 380, 383, 386, 388, 391, 397, 405, 408, 412, 415, 417, - 420, 423, 426, 429, 433, 436, 439, 443, 445, 448, 454, 462, 469, 476, - 483, 488, 495, 501, 508, 514, 521, 529, 534, 542, 549, 555, 562, 569, - 577, 584, 592, 600, 605, 612, 619, 625, 632, 638, 645, 648, 654, 661, - 667, 674, 681, 688, 693, 700, 707, 713, 720, 726, 733, 741, 746, 754, - 761, 767, 774, 781, 789, 796, 804, 812, 817, 824, 831, 837, 844, 850, - 857, 860, 866, 873, 879, 886, 893, 900, 905, 913, 920, 927, 934, 941, - 948, 955, 962, 969, 977, 985, 993, 1001, 1009, 1017, 1025, 1033, 1040, - 1047, 1054, 1061, 1068, 1075, 1082, 1089, 1096, 1103, 1110, 1117, 1125, - 1133, 1141, 1149, 1157, 1165, 1173, 1181, 1189, 1197, 1204, 1211, 1218, - 1225, 1233, 1241, 1249, 1257, 1265, 1273, 1281, 1287, 1292, 1297, 1305, - 1313, 1321, 1329, 1334, 1341, 1348, 1356, 1364, 1372, 1380, 1390, 1400, - 1407, 1414, 1421, 1428, 1436, 1444, 1452, 1460, 1471, 1476, 1481, 1488, - 1495, 1502, 1509, 1516, 1523, 1528, 1533, 1540, 1547, 1555, 1563, 1571, - 1579, 1586, 1593, 1601, 1609, 1617, 1625, 1633, 1641, 1649, 1657, 1665, - 1673, 1680, 1687, 1693, 1699, 1706, 1713, 1720, 1727, 1735, 1743, 1750, - 1757, 1764, 1771, 1779, 1787, 1795, 1803, 1811, 1818, 1825, 1833, 1841, - 1849, 1857, 1863, 1869, 1875, 1882, 1889, 1894, 1899, 1904, 1911, 1918, - 1925, 1932, 1940, 1948, 1955, 1961, 1966, 1971, 1978, 1985, 1992, 1997, - 2002, 2007, 2014, 2021, 2028, 2035, 2042, 2048, 2056, 2066, 2074, 2081, - 2088, 2093, 2098, 2105, 2112, 2116, 2121, 2126, 2131, 2139, 2148, 2155, - 2162, 2171, 2178, 2185, 2190, 2197, 2204, 2211, 2218, 2225, 2230, 2237, - 2244, 2252, 2257, 2262, 2267, 2277, 2281, 2287, 2293, 2299, 2305, 2313, - 2326, 2334, 2339, 2349, 2354, 2359, 2369, 2374, 2381, 2388, 2396, 2404, - 2411, 2418, 2425, 2432, 2442, 2452, 2461, 2470, 2480, 2490, 2500, 2510, - 2516, 2526, 2536, 2546, 2556, 2564, 2572, 2579, 2586, 2594, 2602, 2610, - 2618, 2625, 2632, 2642, 2652, 2660, 2668, 2676, 2681, 2691, 2696, 2703, - 2710, 2715, 2720, 2728, 2736, 2746, 2756, 2763, 2770, 2779, 2788, 2796, - 2804, 2813, 2822, 2830, 2838, 2847, 2856, 2865, 2874, 2884, 2894, 2902, - 2910, 2919, 2928, 2937, 2946, 2956, 2966, 2974, 2982, 2991, 3000, 3009, - 3018, 3027, 3036, 3041, 3046, 3054, 3062, 3072, 3080, 3085, 3090, 3097, - 3104, 3111, 3118, 3125, 3132, 3142, 3152, 3162, 3172, 3179, 3186, 3196, - 3206, 3214, 3222, 3230, 3238, 3246, 3253, 3260, 3267, 3273, 3280, 3287, - 3294, 3303, 3313, 3323, 3330, 3337, 3343, 3348, 3355, 3361, 3367, 3374, - 3381, 3392, 3402, 3409, 3416, 3423, 3430, 3436, 3441, 3448, 3454, 3459, - 3467, 3475, 3482, 3488, 3493, 3500, 3505, 3512, 3521, 3530, 3539, 3546, - 3552, 3558, 3563, 3570, 3577, 3584, 3591, 3598, 3603, 3608, 3617, 3625, - 3634, 3639, 3645, 3656, 3663, 3671, 3680, 3686, 3692, 3698, 3705, 3710, - 3716, 3727, 3736, 3745, 3753, 3761, 3771, 3776, 3783, 3790, 3795, 3807, - 3816, 3824, 3831, 3840, 3845, 3850, 3857, 3864, 3871, 3878, 3884, 3893, - 3901, 3906, 3914, 3920, 3928, 3936, 3942, 3948, 3954, 3961, 3969, 3975, - 3983, 3990, 3995, 4002, 4010, 4020, 4027, 4034, 4044, 4051, 4058, 4068, - 4075, 4082, 4089, 4095, 4101, 4111, 4124, 4129, 4136, 4141, 4145, 4151, - 4160, 4167, 4172, 4177, 4181, 4186, 4192, 4196, 4202, 4208, 4214, 4220, - 4228, 4233, 4238, 4243, 4248, 4254, 4256, 4261, 4265, 4271, 4277, 4283, - 4288, 4295, 4302, 4308, 4315, 4323, 4331, 4336, 4341, 4345, 4350, 4352, - 4354, 4357, 4359, 4361, 4366, 4371, 4377, 4382, 4386, 4391, 4396, 4405, - 4411, 4416, 4422, 4427, 4433, 4441, 4449, 4453, 4457, 4462, 4468, 4474, - 4480, 4486, 4491, 4499, 4508, 4517, 4521, 4527, 4534, 4541, 4548, 4555, - 4559, 4564, 4569, 4574, 4579, 4584, 4586, 4589, 4592, 4595, 4598, 4601, - 4605, 4609, 4615, 4618, 4623, 4629, 4635, 4638, 4643, 4649, 4653, 4659, - 4665, 4671, 4677, 4682, 4687, 4692, 4695, 4701, 4706, 4711, 4715, 4720, - 4726, 4732, 4735, 4739, 4743, 4747, 4750, 4753, 4758, 4762, 4769, 4773, - 4779, 4783, 4789, 4793, 4797, 4801, 4806, 4811, 4818, 4824, 4831, 4837, - 4843, 4849, 4852, 4856, 4860, 4863, 4867, 4872, 4877, 4881, 4885, 4891, - 4895, 4899, 4904, 4910, 4915, 4921, 4925, 4932, 4937, 4942, 4947, 4952, - 4958, 4961, 4965, 4970, 4975, 4984, 4990, 4995, 4999, 5004, 5008, 5013, - 5017, 5021, 5026, 5029, 5035, 5040, 5045, 5050, 5055, 5060, 5065, 5071, - 5077, 5083, 5088, 5093, 5099, 5105, 5111, 5116, 5121, 5128, 5135, 5139, - 5145, 5152, 0, 0, 5159, 5162, 5171, 5180, 5191, 0, 0, 0, 0, 0, 5195, - 5198, 5203, 5211, 5216, 5224, 5232, 0, 5240, 0, 5248, 5256, 5264, 5275, - 5280, 5285, 5290, 5295, 5300, 5305, 5310, 5315, 5320, 5325, 5330, 5335, - 5340, 5345, 5350, 5355, 0, 5360, 5365, 5370, 5375, 5380, 5385, 5390, - 5395, 5403, 5411, 5419, 5427, 5435, 5443, 5454, 5459, 5464, 5469, 5474, - 5479, 5484, 5489, 5494, 5499, 5504, 5509, 5514, 5519, 5524, 5529, 5534, - 5539, 5545, 5550, 5555, 5560, 5565, 5570, 5575, 5580, 5588, 5596, 5604, - 5612, 5620, 5625, 5629, 5633, 5640, 5650, 5660, 5664, 5668, 5672, 5678, - 5685, 5689, 5694, 5698, 5703, 5707, 5712, 5716, 5721, 5726, 5731, 5736, - 5741, 5746, 5751, 5756, 5761, 5766, 5771, 5776, 5781, 5786, 5791, 5795, - 5799, 5805, 5809, 5814, 5820, 5828, 5833, 5838, 5845, 5850, 5855, 5862, - 5871, 5880, 5891, 5899, 5904, 5909, 5914, 5921, 5926, 5932, 5937, 5942, - 5947, 5952, 5957, 5962, 5970, 5976, 5981, 5985, 5990, 5995, 6000, 6005, - 6010, 6015, 6020, 6024, 6030, 6034, 6039, 6044, 6049, 6053, 6058, 6063, - 6068, 6073, 6077, 6082, 6086, 6091, 6096, 6101, 6106, 6112, 6117, 6123, - 6127, 6132, 6136, 6140, 6145, 6150, 6155, 6160, 6165, 6170, 6175, 6179, - 6185, 6189, 6194, 6199, 6204, 6208, 6213, 6218, 6223, 6228, 6232, 6237, - 6241, 6246, 6251, 6256, 6261, 6267, 6272, 6278, 6282, 6287, 6291, 6299, - 6304, 6309, 6314, 6321, 6326, 6332, 6337, 6342, 6347, 6352, 6357, 6362, - 6370, 6376, 6381, 6386, 6391, 6396, 6401, 6407, 6413, 6420, 6427, 6436, - 6445, 6452, 6459, 6468, 6477, 6482, 6487, 6492, 6497, 6502, 6507, 6512, - 6517, 6528, 6539, 6544, 6549, 6556, 6563, 6571, 6579, 6584, 6589, 6594, - 6599, 6603, 6607, 6611, 6617, 6623, 6627, 6634, 6639, 6649, 6659, 6665, - 6671, 6679, 6687, 6695, 6703, 6710, 6717, 6726, 6735, 6743, 6751, 6759, - 6767, 6775, 6783, 6791, 6799, 6806, 6813, 6819, 6825, 6833, 6841, 6848, - 6855, 6864, 6873, 6879, 6885, 6893, 6901, 6909, 6917, 6923, 6929, 6937, - 6945, 6953, 6961, 6968, 6975, 6983, 6991, 6999, 7007, 7012, 7017, 7024, - 7031, 7041, 7051, 7055, 7063, 7071, 7078, 7085, 7093, 7101, 7108, 7115, - 7123, 7131, 7138, 7145, 7153, 7161, 7166, 7173, 7180, 7187, 7194, 7200, - 7206, 7214, 7222, 7227, 7232, 7240, 7248, 7256, 7264, 7272, 7280, 7287, - 7294, 7302, 7310, 7318, 7326, 7333, 7340, 7346, 7352, 7361, 7370, 7377, - 7384, 7391, 7398, 7405, 7412, 7419, 7426, 7434, 7442, 7450, 7458, 7466, - 7474, 7484, 7494, 7501, 7508, 7515, 7522, 7529, 7536, 7543, 7550, 7557, - 7564, 7571, 7578, 7585, 7592, 7599, 7606, 7613, 7620, 7627, 7634, 7641, - 7648, 7655, 7662, 7667, 7672, 7677, 7682, 7687, 7692, 7697, 7702, 7707, - 7712, 7718, 7724, 7733, 7742, 7751, 7760, 7768, 7776, 7784, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 7792, 7797, 7802, 7807, 7812, 7817, 7822, 7827, 7832, - 7836, 7841, 7846, 7851, 7856, 7861, 7866, 7871, 7876, 7881, 7886, 7891, - 7896, 7901, 7906, 7911, 7916, 7921, 7926, 7930, 7935, 7940, 7945, 7950, - 7955, 7960, 7965, 7970, 7975, 0, 0, 7980, 7987, 7990, 7994, 7998, 8001, - 8005, 0, 8009, 8014, 8019, 8024, 8029, 8034, 8039, 8044, 8049, 8053, - 8058, 8063, 8068, 8073, 8078, 8083, 8088, 8093, 8098, 8103, 8108, 8113, - 8118, 8123, 8128, 8133, 8138, 8143, 8147, 8152, 8157, 8162, 8167, 8172, - 8177, 8182, 8187, 8192, 8197, 0, 8204, 8209, 0, 0, 0, 0, 8212, 0, 8216, - 8221, 8226, 8231, 8238, 8245, 8250, 8255, 8260, 8265, 8270, 8275, 8280, - 8287, 8292, 8299, 8306, 8311, 8318, 8323, 8328, 8333, 8340, 8345, 8350, - 8357, 8366, 8371, 8376, 8381, 8386, 8392, 8397, 8404, 8411, 8418, 8423, - 8428, 8433, 8438, 8443, 8448, 8458, 8463, 8471, 8476, 8481, 8486, 8491, - 8498, 8505, 8512, 8518, 8524, 8531, 0, 0, 0, 0, 0, 0, 0, 0, 8538, 8542, - 8546, 8550, 8554, 8558, 8562, 8566, 8570, 8574, 8578, 8583, 8587, 8591, - 8596, 8600, 8605, 8609, 8613, 8617, 8622, 8626, 8631, 8635, 8639, 8643, - 8647, 0, 0, 0, 0, 0, 8651, 8658, 8666, 8673, 8678, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 8683, 8686, 8690, 8695, 8699, 0, 8703, 8709, 8715, 8718, - 8725, 8734, 8737, 8740, 8745, 8751, 8755, 8763, 8769, 8775, 8783, 8787, - 8792, 8803, 8808, 8812, 8816, 8820, 8823, 0, 8826, 8833, 8837, 8843, - 8847, 8854, 8860, 8867, 8873, 8879, 8883, 8887, 8893, 8897, 8901, 8905, - 8909, 8913, 8917, 8921, 8925, 8929, 8933, 8937, 8941, 8945, 8949, 8953, - 8957, 8961, 8969, 8977, 8987, 8996, 9005, 9008, 9012, 9016, 9020, 9024, - 9028, 9032, 9036, 9040, 9045, 9049, 9052, 9055, 9058, 9061, 9064, 9067, - 9070, 9073, 9077, 9080, 9083, 9088, 9093, 9099, 9102, 9109, 9118, 9123, - 9128, 9135, 9140, 9145, 9149, 9153, 9157, 9161, 9165, 9169, 9173, 9177, - 9181, 9185, 9190, 9195, 9202, 9208, 9214, 9220, 9225, 9233, 9241, 9246, - 9252, 9258, 9264, 9270, 9274, 9278, 9282, 9289, 9299, 9303, 9307, 9311, - 9317, 9325, 9329, 9333, 9340, 9344, 9348, 9352, 9359, 9366, 9378, 9382, - 9386, 9390, 9400, 9409, 9413, 9421, 9428, 9435, 9444, 9455, 9463, 9467, - 9476, 9487, 9495, 9508, 9516, 9524, 9532, 9540, 9546, 9555, 9562, 9566, - 9574, 9578, 9585, 9593, 9597, 9603, 9610, 9617, 9621, 9629, 9633, 9640, - 9644, 9652, 9656, 9664, 9672, 9679, 9687, 9695, 9702, 9708, 9712, 9719, - 9727, 9733, 9740, 9747, 9753, 9762, 9770, 9777, 9783, 9787, 9790, 9794, - 9800, 9808, 9812, 9818, 9824, 9831, 9838, 9841, 9848, 9853, 9861, 9866, - 9870, 9883, 9896, 9902, 9909, 9914, 9920, 9925, 9931, 9941, 9948, 9957, - 9967, 9973, 9978, 9983, 9987, 9991, 9996, 10001, 10007, 10015, 10023, - 10034, 10039, 10048, 10057, 10064, 10070, 10076, 10082, 10088, 10094, - 10100, 10106, 10112, 10118, 10125, 10132, 10139, 10145, 10153, 10162, - 10168, 10175, 10182, 10187, 10192, 10196, 10203, 10210, 10219, 10228, - 10231, 10236, 10241, 0, 10246, 10250, 10254, 10260, 10264, 10268, 10274, - 10278, 10286, 10290, 10294, 10298, 10302, 10306, 10312, 10316, 10322, - 10326, 10330, 10334, 10338, 10342, 10347, 10350, 10354, 10360, 10364, - 10368, 10372, 10376, 10380, 10386, 10392, 10398, 10402, 10406, 10411, - 10415, 10419, 10424, 10428, 10432, 10439, 10446, 10450, 10454, 10459, - 10463, 10467, 10470, 10475, 10478, 10481, 10486, 10491, 10495, 10499, - 10505, 10511, 10514, 0, 0, 10517, 10523, 10529, 10535, 10545, 10557, - 10569, 10586, 10598, 10609, 10617, 10624, 10635, 10650, 10661, 10667, - 10676, 10684, 10696, 10706, 10714, 10726, 10733, 10741, 10753, 10759, - 10765, 10773, 10781, 10789, 10795, 10805, 10812, 10822, 10832, 10845, - 10859, 10873, 10883, 10894, 10905, 10918, 10931, 10945, 10957, 10969, - 10982, 10995, 11007, 11020, 11029, 11037, 11042, 11047, 11052, 11057, - 11062, 11067, 11072, 11077, 11082, 11087, 11092, 11097, 11102, 11107, - 11112, 11117, 11122, 11127, 11132, 11137, 11142, 11147, 11152, 11157, - 11162, 11167, 11172, 11177, 11182, 11187, 11192, 11197, 11201, 11206, - 11211, 11216, 11221, 11226, 11230, 11234, 11238, 11242, 11246, 11250, - 11254, 11258, 11262, 11266, 11270, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 11275, 11280, 11284, 11288, 11292, 11296, 11300, 11304, 11308, 11312, - 11316, 11320, 11325, 11329, 11333, 11337, 11342, 11346, 11351, 11356, - 11361, 11365, 11370, 11375, 11380, 11385, 11389, 11394, 11398, 11403, - 11408, 11412, 11417, 11424, 11428, 11433, 11437, 11441, 11446, 11450, - 11457, 11464, 11471, 11477, 11485, 11493, 11502, 11510, 11517, 11524, - 11532, 11538, 11544, 11550, 11556, 11563, 11568, 11572, 11577, 0, 0, 0, - 0, 0, 11581, 11586, 11591, 11596, 11601, 11606, 11611, 11616, 11621, - 11626, 11631, 11636, 11641, 11646, 11651, 11656, 11661, 11666, 11671, - 11676, 11681, 11686, 11691, 11696, 11701, 11706, 11711, 11719, 11726, - 11732, 11737, 11745, 11752, 11758, 11765, 11771, 11776, 11783, 11790, - 11796, 11801, 11806, 11812, 11817, 11822, 11828, 0, 0, 11833, 11839, - 11845, 11851, 11857, 11863, 11869, 11874, 11882, 11888, 11894, 11900, - 11906, 11912, 11920, 0, 11926, 11931, 11936, 11941, 11946, 11951, 11956, - 11961, 11966, 11971, 11976, 11981, 11986, 11991, 11996, 12001, 12006, - 12011, 12016, 12021, 12026, 12031, 12036, 12041, 12046, 12051, 12056, - 12061, 0, 0, 12066, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 360, 364, 369, + 372, 375, 378, 381, 384, 387, 389, 392, 398, 406, 409, 413, 416, 418, + 421, 424, 427, 430, 434, 437, 440, 444, 446, 449, 455, 463, 470, 477, + 484, 489, 496, 502, 509, 516, 523, 531, 536, 544, 551, 557, 564, 571, + 579, 586, 594, 602, 607, 615, 622, 628, 635, 642, 649, 652, 658, 665, + 671, 678, 685, 692, 697, 703, 710, 716, 723, 730, 737, 745, 750, 758, + 765, 771, 778, 785, 793, 800, 808, 816, 821, 829, 836, 842, 849, 856, + 863, 866, 872, 879, 885, 892, 899, 906, 911, 919, 926, 933, 940, 947, + 954, 961, 968, 975, 983, 991, 999, 1007, 1015, 1023, 1031, 1039, 1046, + 1053, 1060, 1067, 1074, 1081, 1088, 1095, 1102, 1109, 1116, 1123, 1131, + 1139, 1147, 1155, 1163, 1171, 1179, 1187, 1195, 1203, 1210, 1217, 1225, + 1233, 1241, 1249, 1257, 1265, 1273, 1281, 1289, 1295, 1300, 1305, 1313, + 1321, 1329, 1337, 1342, 1349, 1356, 1364, 1372, 1380, 1388, 1398, 1408, + 1415, 1422, 1429, 1436, 1444, 1452, 1460, 1468, 1479, 1484, 1489, 1496, + 1503, 1510, 1517, 1524, 1531, 1536, 1541, 1548, 1555, 1563, 1571, 1579, + 1587, 1594, 1601, 1609, 1617, 1625, 1633, 1641, 1649, 1657, 1665, 1673, + 1681, 1688, 1695, 1702, 1709, 1716, 1723, 1730, 1737, 1745, 1753, 1760, + 1767, 1774, 1781, 1789, 1797, 1805, 1813, 1821, 1828, 1835, 1843, 1851, + 1859, 1867, 1872, 1878, 1884, 1891, 1898, 1903, 1908, 1914, 1921, 1928, + 1935, 1942, 1950, 1958, 1964, 1970, 1975, 1981, 1988, 1995, 2002, 2007, + 2012, 2017, 2024, 2031, 2038, 2045, 2052, 2058, 2066, 2076, 2085, 2092, + 2099, 2104, 2109, 2116, 2123, 2127, 2132, 2137, 2142, 2150, 2159, 2166, + 2173, 2182, 2189, 2196, 2201, 2208, 2215, 2222, 2229, 2236, 2241, 2248, + 2255, 2263, 2268, 2273, 2278, 2288, 2292, 2298, 2304, 2310, 2316, 2324, + 2337, 2345, 2350, 2360, 2365, 2370, 2380, 2385, 2392, 2399, 2407, 2415, + 2422, 2429, 2436, 2443, 2453, 2463, 2472, 2481, 2491, 2501, 2511, 2521, + 2526, 2536, 2546, 2556, 2566, 2574, 2582, 2589, 2596, 2604, 2612, 2620, + 2628, 2635, 2642, 2652, 2662, 2670, 2678, 2686, 2691, 2701, 2706, 2713, + 2720, 2725, 2730, 2738, 2746, 2756, 2766, 2773, 2780, 2789, 2798, 2806, + 2814, 2823, 2832, 2840, 2848, 2857, 2866, 2875, 2884, 2894, 2904, 2912, + 2920, 2929, 2938, 2947, 2956, 2966, 2976, 2984, 2992, 3001, 3010, 3019, + 3028, 3037, 3046, 3051, 3056, 3064, 3072, 3082, 3090, 3095, 3100, 3107, + 3114, 3121, 3128, 3135, 3142, 3152, 3162, 3172, 3182, 3189, 3196, 3206, + 3216, 3224, 3232, 3240, 3248, 3256, 3263, 3270, 3277, 3283, 3290, 3297, + 3304, 3313, 3323, 3333, 3340, 3347, 3353, 3358, 3364, 3370, 3376, 3383, + 3390, 3401, 3411, 3418, 3425, 3432, 3439, 3444, 3449, 3455, 3461, 3467, + 3475, 3483, 3490, 3496, 3501, 3508, 3514, 3522, 3532, 3542, 3551, 3558, + 3564, 3570, 3575, 3582, 3588, 3595, 3602, 3609, 3614, 3619, 3629, 3637, + 3646, 3651, 3657, 3667, 3674, 3682, 3691, 3697, 3703, 3709, 3716, 3721, + 3726, 3736, 3744, 3753, 3761, 3769, 3779, 3784, 3791, 3798, 3803, 3815, + 3824, 3832, 3838, 3847, 3852, 3857, 3864, 3870, 3876, 3882, 3888, 3897, + 3905, 3910, 3918, 3924, 3932, 3940, 3946, 3952, 3958, 3966, 3974, 3980, + 3988, 3994, 3999, 4006, 4014, 4024, 4031, 4038, 4048, 4055, 4062, 4072, + 4079, 4086, 4093, 4099, 4105, 4114, 4126, 4131, 4138, 4143, 4147, 4152, + 4160, 4167, 4172, 4177, 4181, 4186, 4191, 4195, 4201, 4207, 4213, 4219, + 4227, 4232, 4237, 4242, 4247, 4253, 4255, 4260, 4264, 4270, 4276, 4282, + 4287, 4294, 4301, 4307, 4314, 4322, 4330, 4335, 4340, 4344, 4349, 4351, + 4353, 4356, 4358, 4361, 4366, 4371, 4377, 4382, 4386, 4390, 4395, 4404, + 4410, 4415, 4421, 4426, 4432, 4440, 4448, 4452, 4456, 4461, 4467, 4473, + 4479, 4485, 4490, 4498, 4507, 4516, 4521, 4527, 4534, 4541, 4548, 4555, + 4559, 4565, 4570, 4575, 4580, 4585, 4588, 4591, 4594, 4597, 4600, 4603, + 4607, 4611, 4617, 4620, 4625, 4631, 4637, 4640, 4645, 4650, 4654, 4660, + 4666, 4672, 4678, 4683, 4688, 4693, 4696, 4702, 4707, 4712, 4716, 4721, + 4727, 4733, 4736, 4740, 4744, 4748, 4751, 4754, 4759, 4763, 4770, 4774, + 4780, 4784, 4790, 4794, 4798, 4802, 4807, 4812, 4819, 4825, 4832, 4838, + 4844, 4850, 4853, 4857, 4861, 4865, 4869, 4874, 4879, 4883, 4887, 4893, + 4897, 4901, 4906, 4912, 4917, 4923, 4927, 4934, 4939, 4943, 4948, 4953, + 4959, 4962, 4966, 4971, 4976, 4985, 4991, 4996, 5000, 5005, 5009, 5014, + 5018, 5022, 5027, 5031, 5037, 5042, 5047, 5052, 5057, 5062, 5067, 5073, + 5079, 5085, 5091, 5096, 5102, 5108, 5114, 5119, 5124, 5131, 5138, 5142, + 5148, 5155, 0, 0, 5162, 5165, 5174, 5183, 5194, 5198, 0, 0, 0, 0, 5203, + 5206, 5211, 5219, 5224, 5232, 5240, 0, 5248, 0, 5256, 5264, 5272, 5283, + 5288, 5293, 5298, 5303, 5308, 5313, 5318, 5323, 5328, 5333, 5338, 5343, + 5348, 5353, 5358, 5363, 0, 5368, 5373, 5378, 5383, 5388, 5393, 5398, + 5403, 5411, 5419, 5427, 5435, 5443, 5451, 5462, 5467, 5472, 5477, 5482, + 5487, 5492, 5497, 5502, 5507, 5512, 5517, 5522, 5527, 5532, 5537, 5542, + 5547, 5553, 5558, 5563, 5568, 5573, 5578, 5583, 5588, 5596, 5604, 5612, + 5620, 5628, 5633, 5637, 5641, 5648, 5658, 5668, 5672, 5676, 5680, 5686, + 5693, 5697, 5702, 5706, 5711, 5715, 5720, 5724, 5729, 5734, 5739, 5744, + 5749, 5754, 5759, 5764, 5769, 5774, 5779, 5784, 5789, 5794, 5799, 5803, + 5807, 5813, 5817, 5822, 5828, 5836, 5841, 5846, 5853, 5858, 5863, 5870, + 5879, 5888, 5899, 5907, 5912, 5917, 5922, 5929, 5934, 5940, 5945, 5950, + 5955, 5960, 5965, 5970, 5978, 5984, 5989, 5993, 5998, 6003, 6008, 6013, + 6018, 6023, 6028, 6032, 6038, 6042, 6047, 6052, 6057, 6061, 6066, 6071, + 6076, 6081, 6085, 6090, 6094, 6099, 6104, 6109, 6114, 6120, 6125, 6131, + 6135, 6140, 6144, 6148, 6153, 6158, 6163, 6168, 6173, 6178, 6183, 6187, + 6193, 6197, 6202, 6207, 6212, 6216, 6221, 6226, 6231, 6236, 6240, 6245, + 6249, 6254, 6259, 6264, 6269, 6275, 6280, 6286, 6290, 6295, 6299, 6307, + 6312, 6317, 6322, 6329, 6334, 6340, 6345, 6350, 6355, 6360, 6365, 6370, + 6378, 6384, 6389, 6394, 6399, 6404, 6409, 6415, 6421, 6428, 6435, 6444, + 6453, 6460, 6467, 6476, 6485, 6490, 6495, 6500, 6505, 6510, 6515, 6520, + 6525, 6536, 6547, 6552, 6557, 6564, 6571, 6579, 6587, 6592, 6597, 6602, + 6607, 6611, 6615, 6619, 6625, 6631, 6635, 6642, 6647, 6657, 6667, 6673, + 6679, 6687, 6695, 6703, 6711, 6718, 6725, 6734, 6743, 6751, 6759, 6767, + 6775, 6783, 6791, 6799, 6807, 6814, 6821, 6827, 6833, 6841, 6849, 6856, + 6863, 6872, 6881, 6887, 6893, 6901, 6909, 6917, 6925, 6931, 6937, 6945, + 6953, 6961, 6969, 6976, 6983, 6991, 6999, 7007, 7015, 7020, 7025, 7032, + 7039, 7049, 7059, 7063, 7071, 7079, 7086, 7093, 7101, 7109, 7116, 7123, + 7131, 7139, 7146, 7153, 7161, 7169, 7174, 7181, 7188, 7195, 7202, 7208, + 7214, 7222, 7230, 7235, 7240, 7248, 7256, 7264, 7272, 7280, 7288, 7295, + 7302, 7310, 7318, 7326, 7334, 7341, 7348, 7354, 7360, 7369, 7378, 7385, + 7392, 7399, 7406, 7413, 7420, 7427, 7434, 7442, 7450, 7458, 7466, 7474, + 7482, 7492, 7502, 7509, 7516, 7523, 7530, 7537, 7544, 7551, 7558, 7565, + 7572, 7579, 7586, 7593, 7600, 7607, 7614, 7621, 7628, 7635, 7642, 7649, + 7656, 7663, 7670, 7675, 7680, 7685, 7690, 7695, 7700, 7705, 7710, 7715, + 7720, 7726, 7732, 7741, 7750, 7759, 7768, 7776, 7784, 7792, 7800, 7808, + 7816, 7821, 7826, 7831, 7836, 7844, 0, 7852, 7857, 7862, 7867, 7872, + 7877, 7882, 7887, 7892, 7896, 7901, 7906, 7911, 7916, 7921, 7926, 7931, + 7936, 7941, 7946, 7951, 7956, 7961, 7966, 7971, 7976, 7981, 7986, 7991, + 7996, 8001, 8006, 8011, 8016, 8021, 8026, 8031, 8036, 0, 0, 8041, 8048, + 8051, 8055, 8059, 8062, 8066, 0, 8070, 8075, 8080, 8085, 8090, 8095, + 8100, 8105, 8110, 8114, 8119, 8124, 8129, 8134, 8139, 8144, 8149, 8154, + 8159, 8164, 8169, 8174, 8179, 8184, 8189, 8194, 8199, 8204, 8209, 8214, + 8219, 8224, 8229, 8234, 8239, 8244, 8249, 8254, 8259, 0, 8266, 8271, 0, + 0, 8274, 8280, 8286, 0, 8290, 8295, 8300, 8305, 8312, 8319, 8324, 8329, + 8334, 8339, 8344, 8349, 8354, 8361, 8366, 8373, 8380, 8385, 8392, 8397, + 8402, 8407, 8414, 8419, 8424, 8431, 8440, 8445, 8450, 8455, 8460, 8466, + 8471, 8478, 8485, 8492, 8497, 8502, 8507, 8512, 8517, 8522, 8532, 8537, + 8546, 8551, 8556, 8561, 8566, 8573, 8580, 8587, 8593, 8599, 8606, 0, 0, + 0, 0, 0, 0, 0, 0, 8613, 8617, 8621, 8625, 8629, 8633, 8637, 8641, 8645, + 8649, 8653, 8658, 8662, 8666, 8671, 8675, 8680, 8684, 8688, 8692, 8697, + 8701, 8706, 8710, 8714, 8718, 8722, 0, 0, 0, 0, 0, 8726, 8733, 8741, + 8748, 8753, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8758, 8761, 8765, 8770, + 8774, 8778, 8782, 8788, 8794, 8797, 8804, 8813, 8816, 8819, 8824, 8830, + 8834, 8842, 8848, 8854, 8862, 8866, 8871, 8882, 8887, 8891, 8895, 8899, + 8902, 0, 8905, 8912, 8916, 8922, 8926, 8933, 8940, 8948, 8955, 8962, + 8966, 8970, 8976, 8980, 8984, 8988, 8992, 8996, 9000, 9004, 9008, 9012, + 9016, 9020, 9024, 9028, 9032, 9036, 9040, 9044, 9052, 9060, 9070, 9079, + 9088, 9091, 9095, 9099, 9103, 9107, 9111, 9115, 9119, 9123, 9128, 9132, + 9135, 9138, 9141, 9144, 9147, 9150, 9153, 9156, 9160, 9164, 9168, 9173, + 9178, 9184, 9187, 9194, 9203, 9208, 9213, 9220, 9226, 9231, 9235, 9239, + 9243, 9247, 9251, 9255, 9259, 9263, 9267, 9271, 9276, 9281, 9288, 9294, + 9300, 9306, 9311, 9320, 9329, 9334, 9341, 9348, 9355, 9362, 9366, 9370, + 9374, 9381, 9391, 9395, 9399, 9403, 9410, 9418, 9422, 9426, 9433, 9437, + 9441, 9445, 9452, 9459, 9471, 9475, 9479, 9483, 9493, 9502, 9506, 9514, + 9521, 9528, 9537, 9548, 9556, 9560, 9569, 9580, 9588, 9601, 9609, 9617, + 9625, 9633, 9639, 9648, 9655, 9659, 9667, 9671, 9678, 9686, 9690, 9696, + 9703, 9710, 9714, 9722, 9726, 9733, 9737, 9745, 9749, 9757, 9765, 9772, + 9780, 9788, 9795, 9801, 9805, 9812, 9820, 9826, 9833, 9840, 9846, 9856, + 9864, 9871, 9877, 9881, 9884, 9888, 9894, 9902, 9906, 9912, 9918, 9925, + 9932, 9935, 9942, 9947, 9956, 9961, 9965, 9978, 9991, 9997, 10004, 10009, + 10015, 10020, 10026, 10036, 10043, 10052, 10062, 10068, 10073, 10078, + 10082, 10086, 10091, 10096, 10102, 10110, 10118, 10129, 10134, 10143, + 10152, 10159, 10165, 10171, 10177, 10183, 10189, 10195, 10201, 10207, + 10213, 10220, 10227, 10234, 10240, 10248, 10257, 10264, 10272, 10280, + 10286, 10292, 10297, 10305, 10313, 10323, 10333, 10337, 10343, 10349, 0, + 10355, 10360, 10365, 10372, 10377, 10382, 10389, 10394, 10403, 10408, + 10413, 10418, 10423, 10428, 10435, 10440, 10447, 10452, 10457, 10462, + 10467, 10472, 10478, 10482, 10487, 10494, 10499, 10504, 10509, 10514, + 10519, 10526, 10533, 10540, 10545, 10550, 10556, 10561, 10566, 10572, + 10577, 10582, 10590, 10598, 10603, 10608, 10614, 10619, 10624, 10628, + 10634, 10638, 10642, 10648, 10654, 10659, 10664, 10671, 10678, 10682, 0, + 0, 10686, 10693, 10700, 10707, 10717, 10729, 10740, 10756, 10768, 10779, + 10787, 10794, 10804, 10819, 10830, 10836, 10845, 10853, 10864, 10874, + 10882, 10893, 10900, 10908, 10919, 10925, 10931, 10939, 10947, 10955, + 10961, 10971, 10979, 10989, 10999, 11012, 11026, 11040, 11050, 11061, + 11072, 11085, 11098, 11112, 11124, 11136, 11149, 11162, 11174, 11187, + 11196, 11204, 11209, 11214, 11219, 11224, 11229, 11234, 11239, 11244, + 11249, 11254, 11259, 11264, 11269, 11274, 11279, 11284, 11289, 11294, + 11299, 11304, 11309, 11314, 11319, 11324, 11329, 11334, 11339, 11344, + 11349, 11354, 11359, 11364, 11368, 11373, 11378, 11383, 11388, 11393, + 11397, 11401, 11405, 11409, 11413, 11417, 11421, 11425, 11429, 11433, + 11437, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11442, 11447, 11451, + 11455, 11459, 11463, 11467, 11471, 11475, 11479, 11483, 11487, 11492, + 11496, 11500, 11504, 11509, 11513, 11518, 11523, 11528, 11532, 11537, + 11542, 11547, 11552, 11557, 11562, 11567, 11572, 11577, 11581, 11586, + 11593, 11597, 11602, 11606, 11610, 11615, 11619, 11626, 11633, 11640, + 11647, 11655, 11663, 11672, 11680, 11687, 11694, 11702, 11708, 11714, + 11720, 11726, 11733, 11738, 11742, 11747, 0, 0, 0, 0, 0, 11751, 11756, + 11761, 11766, 11771, 11776, 11781, 11786, 11791, 11796, 11801, 11806, + 11811, 11816, 11821, 11826, 11831, 11836, 11841, 11846, 11851, 11856, + 11861, 11866, 11871, 11876, 11881, 11889, 11896, 11902, 11907, 11915, + 11922, 11928, 11935, 11941, 11946, 11953, 11960, 11966, 11971, 11976, + 11982, 11987, 11992, 11998, 0, 0, 12003, 12009, 12015, 12021, 12027, + 12033, 12039, 12044, 12052, 12058, 12064, 12070, 12076, 12082, 12090, 0, + 12096, 12101, 12106, 12111, 12116, 12121, 12126, 12131, 12136, 12141, + 12146, 12151, 12156, 12161, 12166, 12171, 12176, 12181, 12186, 12191, + 12196, 12201, 12206, 12211, 12216, 12221, 12226, 12231, 0, 0, 12236, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12240, 12249, 12257, + 12264, 12272, 12284, 12291, 12298, 12305, 12317, 12328, 12335, 12343, + 12349, 12354, 12362, 12370, 12378, 12384, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12394, 12399, 12404, 12409, + 12414, 12419, 12424, 12429, 12434, 12439, 12444, 12449, 12454, 12459, + 12464, 12469, 12474, 12480, 12486, 12492, 12497, 12502, 12507, 12512, + 12518, 12527, 12535, 12541, 12549, 12555, 12559, 12563, 12567, 12572, + 12575, 12579, 12582, 12586, 12589, 12593, 12597, 12601, 12606, 12611, + 12614, 12618, 12623, 12628, 12631, 12635, 12638, 12642, 12646, 12650, + 12654, 12658, 12662, 12666, 12670, 12674, 12678, 12682, 12686, 12690, + 12694, 12698, 12702, 12706, 12710, 12713, 12717, 12720, 12724, 12728, + 12732, 12735, 12738, 12742, 12746, 12750, 12754, 12758, 12762, 12766, + 12770, 12774, 12777, 12782, 12787, 12791, 12795, 12800, 12804, 12809, + 12813, 12818, 12823, 12829, 12835, 12841, 12845, 12850, 12856, 12862, + 12866, 12871, 12875, 12881, 12886, 12889, 12895, 12901, 12906, 12911, + 12918, 12923, 12928, 12932, 12936, 12940, 12944, 12948, 12952, 12956, + 12960, 12965, 12970, 12975, 12981, 12984, 12988, 12992, 12995, 12998, + 13001, 13004, 13007, 13010, 13013, 13016, 13019, 13023, 13030, 13035, + 13039, 13043, 13047, 13051, 13055, 13061, 13065, 13069, 13073, 13077, + 13083, 13087, 13091, 13094, 13098, 13102, 0, 13106, 13109, 13113, 13116, + 13120, 13123, 13127, 13131, 0, 0, 13135, 13138, 0, 0, 13142, 13145, + 13149, 13152, 13156, 13160, 13164, 13168, 13172, 13176, 13180, 13184, + 13188, 13192, 13196, 13200, 13204, 13208, 13212, 13216, 13220, 13224, 0, + 13227, 13230, 13234, 13238, 13242, 13245, 13248, 0, 13252, 0, 0, 0, + 13256, 13260, 13264, 13268, 0, 0, 13271, 13275, 13279, 13284, 13288, + 13293, 13297, 13302, 13307, 0, 0, 13313, 13317, 0, 0, 13322, 13326, + 13331, 13335, 0, 0, 0, 0, 0, 0, 0, 0, 13341, 0, 0, 0, 0, 13347, 13351, 0, + 13355, 13359, 13364, 13369, 13374, 0, 0, 13380, 13384, 13387, 13390, + 13393, 13396, 13399, 13402, 13405, 13408, 13411, 13420, 13429, 13433, + 13437, 13443, 13449, 13455, 13461, 13475, 13482, 13485, 0, 0, 0, 0, 0, + 13489, 13496, 13501, 0, 13506, 13510, 13515, 13519, 13524, 13528, 0, 0, + 0, 0, 13533, 13538, 0, 0, 13543, 13548, 13553, 13557, 13562, 13567, + 13572, 13577, 13582, 13587, 13592, 13597, 13602, 13607, 13612, 13617, + 13622, 13627, 13632, 13637, 13642, 13647, 0, 13651, 13655, 13660, 13665, + 13670, 13674, 13678, 0, 13683, 13688, 0, 13693, 13698, 0, 13703, 13708, + 0, 0, 13712, 0, 13717, 13723, 13728, 13734, 13739, 0, 0, 0, 0, 13745, + 13751, 0, 0, 13757, 13763, 13769, 0, 0, 0, 13774, 0, 0, 0, 0, 0, 0, 0, + 13779, 13784, 13789, 13794, 0, 13799, 0, 0, 0, 0, 0, 0, 0, 13804, 13809, + 13813, 13817, 13821, 13825, 13829, 13833, 13837, 13841, 13845, 13849, + 13853, 13857, 13861, 13867, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13872, + 13876, 13880, 0, 13884, 13887, 13891, 13894, 13898, 13901, 13905, 13909, + 13913, 0, 13918, 13921, 13925, 0, 13930, 13933, 13937, 13940, 13944, + 13948, 13952, 13956, 13960, 13964, 13968, 13972, 13976, 13980, 13984, + 13988, 13992, 13996, 14000, 14004, 14008, 14012, 0, 14015, 14018, 14022, + 14026, 14030, 14033, 14036, 0, 14040, 14044, 0, 14048, 14052, 14056, + 14060, 14064, 0, 0, 14067, 14071, 14075, 14080, 14084, 14089, 14093, + 14098, 14103, 14109, 0, 14115, 14119, 14124, 0, 14130, 14134, 14139, 0, + 0, 14143, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14146, 14151, + 14156, 14161, 0, 0, 14167, 14171, 14174, 14177, 14180, 14183, 14186, + 14189, 14192, 14195, 14198, 14202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 14206, 14210, 14214, 0, 14218, 14221, 14225, 14228, 14232, 14235, + 14239, 14243, 0, 0, 14247, 14250, 0, 0, 14254, 14257, 14261, 14264, + 14268, 14272, 14276, 14280, 14284, 14288, 14292, 14296, 14300, 14304, + 14308, 14312, 14316, 14320, 14324, 14328, 14332, 14336, 0, 14339, 14342, + 14346, 14350, 14354, 14357, 14360, 0, 14364, 14368, 0, 14372, 14376, + 14380, 14384, 14388, 0, 0, 14391, 14395, 14399, 14404, 14408, 14413, + 14417, 14422, 14427, 0, 0, 14433, 14437, 0, 0, 14442, 14446, 14451, 0, 0, + 0, 0, 0, 0, 0, 0, 14455, 14461, 0, 0, 0, 0, 14467, 14471, 0, 14475, + 14479, 14484, 14489, 14494, 0, 0, 14500, 14504, 14507, 14510, 14513, + 14516, 14519, 14522, 14525, 14528, 14531, 14534, 14538, 14544, 14550, + 14556, 14562, 14568, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14574, 14578, 0, + 14582, 14585, 14589, 14592, 14596, 14599, 0, 0, 0, 14603, 14606, 14610, + 0, 14614, 14617, 14621, 14625, 0, 0, 0, 14628, 14632, 0, 14636, 0, 14640, + 14644, 0, 0, 0, 14648, 14652, 0, 0, 0, 14656, 14659, 14663, 0, 0, 0, + 14666, 14669, 14672, 14676, 14680, 14684, 14688, 14692, 14696, 14700, + 14704, 14708, 0, 0, 0, 0, 14711, 14716, 14720, 14725, 14729, 0, 0, 0, + 14734, 14738, 14743, 0, 14748, 14752, 14757, 14762, 0, 0, 14766, 0, 0, 0, + 0, 0, 0, 14769, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14775, 14779, + 14782, 14785, 14788, 14791, 14794, 14797, 14800, 14803, 14806, 14810, + 14815, 14820, 14824, 14828, 14832, 14836, 14840, 14845, 14849, 0, 0, 0, + 0, 0, 14852, 14858, 14862, 14866, 0, 14870, 14873, 14877, 14880, 14884, + 14887, 14891, 14895, 0, 14899, 14902, 14906, 0, 14910, 14913, 14917, + 14921, 14924, 14928, 14932, 14936, 14940, 14944, 14948, 14952, 14956, + 14960, 14964, 14968, 14972, 14976, 14980, 14984, 14988, 14992, 14996, 0, + 14999, 15002, 15006, 15010, 15014, 15017, 15020, 15024, 15028, 15032, + 15036, 15040, 15044, 15048, 15052, 15056, 0, 0, 0, 15059, 15063, 15068, + 15072, 15077, 15081, 15086, 15091, 0, 15097, 15101, 15106, 0, 15111, + 15115, 15120, 15125, 0, 0, 0, 0, 0, 0, 0, 15129, 15133, 0, 15139, 15143, + 0, 0, 0, 0, 0, 0, 15147, 15152, 15157, 15162, 0, 0, 15168, 15172, 15175, + 15178, 15181, 15184, 15187, 15190, 15193, 15196, 0, 0, 0, 0, 0, 0, 0, 0, + 15199, 15212, 15224, 15236, 15248, 15260, 15272, 15284, 0, 15288, 15292, + 15296, 0, 15300, 15303, 15307, 15310, 15314, 15317, 15321, 15325, 0, + 15329, 15332, 15336, 0, 15340, 15343, 15347, 15351, 15354, 15358, 15362, + 15366, 15370, 15374, 15378, 15382, 15386, 15390, 15394, 15398, 15402, + 15406, 15410, 15414, 15418, 15422, 15426, 0, 15429, 15432, 15436, 15440, + 15444, 15447, 15450, 15454, 15458, 15462, 0, 15466, 15470, 15474, 15478, + 15482, 0, 0, 15485, 15489, 15493, 15498, 15502, 15507, 15511, 15516, + 15521, 0, 15527, 15531, 15536, 0, 15541, 15545, 15550, 15555, 0, 0, 0, 0, + 0, 0, 0, 15559, 15563, 0, 0, 0, 0, 0, 0, 0, 15569, 0, 15573, 15578, + 15583, 15588, 0, 0, 15594, 15598, 15601, 15604, 15607, 15610, 15613, + 15616, 15619, 15622, 0, 15625, 15629, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 15633, 15637, 15641, 0, 15645, 15648, 15652, 15655, 15659, 15662, + 15666, 15670, 0, 15674, 15677, 15681, 0, 15685, 15688, 15692, 15696, + 15699, 15703, 15707, 15711, 15715, 15719, 15723, 15727, 15731, 15735, + 15739, 15743, 15747, 15751, 15755, 15759, 15763, 15767, 15771, 15774, + 15778, 15781, 15785, 15789, 15793, 15796, 15799, 15803, 15807, 15811, + 15815, 15819, 15823, 15827, 15831, 15835, 15838, 0, 0, 15842, 15846, + 15851, 15855, 15860, 15864, 15869, 15874, 0, 15880, 15884, 15889, 0, + 15894, 15898, 15903, 15908, 15912, 0, 0, 0, 0, 0, 0, 0, 0, 15917, 0, 0, + 0, 0, 0, 0, 0, 0, 15923, 15928, 15933, 15938, 0, 0, 15944, 15948, 15951, + 15954, 15957, 15960, 15963, 15966, 15969, 15972, 15975, 15979, 15984, + 15989, 15995, 16001, 0, 0, 0, 16007, 16011, 16017, 16023, 16029, 16034, + 16040, 0, 0, 16046, 16050, 0, 16054, 16058, 16062, 16066, 16070, 16074, + 16078, 16082, 16086, 16090, 16094, 16098, 16102, 16106, 16110, 16114, + 16118, 16122, 0, 0, 0, 16126, 16132, 16138, 16144, 16150, 16156, 16162, + 16168, 16174, 16180, 16186, 16192, 16200, 16206, 16212, 16218, 16224, + 16230, 16236, 16242, 16248, 16254, 16260, 16266, 0, 16272, 16278, 16284, + 16290, 16296, 16302, 16306, 16312, 16316, 0, 16320, 0, 0, 16326, 16330, + 16336, 16342, 16348, 16352, 16358, 0, 0, 0, 16362, 0, 0, 0, 0, 16366, + 16371, 16378, 16385, 16392, 16399, 0, 16406, 0, 16413, 16418, 16423, + 16430, 16437, 16446, 16457, 16466, 0, 0, 0, 0, 0, 0, 16471, 16477, 16482, + 16487, 16492, 16497, 16502, 16507, 16512, 16517, 0, 0, 16522, 16529, + 16536, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16541, 16547, 16553, 16559, + 16565, 16571, 16577, 16583, 16589, 16595, 16601, 16607, 16613, 16619, + 16625, 16631, 16637, 16643, 16649, 16655, 16661, 16667, 16673, 16679, + 16685, 16691, 16697, 16703, 16709, 16715, 16721, 16727, 16733, 16738, + 16744, 16750, 16754, 16760, 16764, 16770, 16776, 16782, 16788, 16794, + 16800, 16805, 16811, 16815, 16820, 16826, 16832, 16838, 16843, 16849, + 16855, 16861, 16866, 16872, 0, 0, 0, 0, 16876, 16882, 16887, 16893, + 16898, 16906, 16914, 16918, 16922, 16926, 16932, 16938, 16944, 16950, + 16954, 16958, 16962, 16966, 16970, 16973, 16976, 16979, 16982, 16985, + 16988, 16991, 16994, 16997, 17001, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 17005, 17010, 0, 17017, 0, 0, 17024, 17029, 0, 17034, 0, 0, 17041, 0, 0, + 0, 0, 0, 0, 17046, 17051, 17055, 17062, 0, 17069, 17074, 17079, 17084, + 17091, 17098, 17105, 0, 17112, 17117, 17122, 0, 17129, 0, 17136, 0, 0, + 17141, 17148, 0, 17155, 17159, 17166, 17170, 17175, 17183, 17189, 17195, + 17200, 17206, 17212, 17218, 17223, 0, 17229, 17237, 17244, 0, 0, 17251, + 17256, 17262, 17267, 17273, 0, 17279, 0, 17285, 17292, 17299, 17306, + 17313, 17318, 0, 0, 17322, 17327, 17331, 17335, 17339, 17343, 17347, + 17351, 17355, 17359, 0, 0, 17363, 17369, 17375, 17382, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 17389, 17393, 17404, 17419, 17434, 17444, 17455, 17468, 17479, + 17485, 17493, 17503, 17509, 17517, 17521, 17527, 17533, 17541, 17551, + 17559, 17572, 17578, 17586, 17594, 17606, 17613, 17621, 17629, 17637, + 17645, 17653, 17661, 17671, 17675, 17678, 17681, 17684, 17687, 17690, + 17693, 17696, 17699, 17702, 17706, 17710, 17714, 17718, 17722, 17726, + 17730, 17734, 17738, 17743, 17749, 17759, 17773, 17783, 17789, 17795, + 17803, 17811, 17819, 17827, 17833, 17839, 17842, 17846, 17850, 17854, + 17858, 17862, 17866, 0, 17870, 17874, 17878, 17882, 17886, 17890, 17894, + 17898, 17902, 17906, 17910, 17913, 17916, 17920, 17924, 17928, 17931, + 17935, 17939, 17943, 17947, 17951, 17955, 17959, 17963, 17966, 17970, + 17974, 17978, 17982, 17986, 17989, 17992, 17996, 18002, 18006, 0, 0, 0, + 0, 18010, 18015, 18019, 18024, 18028, 18033, 18038, 18044, 18049, 18055, + 18059, 18064, 18068, 18073, 18083, 18089, 18095, 18102, 18112, 18118, + 18122, 18126, 18132, 18138, 18146, 18152, 18160, 18168, 18176, 18186, + 18194, 18204, 18209, 18215, 18221, 18227, 18233, 18239, 18245, 0, 18251, + 18257, 18263, 18269, 18275, 18281, 18287, 18293, 18299, 18305, 18311, + 18316, 18321, 18327, 18333, 18339, 18344, 18350, 18356, 18362, 18368, + 18374, 18380, 18386, 18392, 18397, 18403, 18409, 18415, 18421, 18427, + 18432, 18437, 18443, 18451, 18458, 0, 18466, 18473, 18486, 18493, 18500, + 18508, 18516, 18522, 18528, 18534, 18544, 18549, 18555, 18565, 18575, 0, + 18585, 18595, 18603, 18615, 18627, 18633, 18647, 18662, 18667, 18672, + 18680, 18688, 18696, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18704, 18707, + 18711, 18715, 18719, 18723, 18727, 18731, 18735, 18739, 18743, 18747, + 18751, 18755, 18759, 18763, 18767, 18771, 18775, 18779, 18783, 18786, + 18789, 18793, 18797, 18801, 18804, 18807, 18811, 18815, 18819, 18823, + 18826, 18830, 18833, 18838, 18841, 18845, 18848, 18852, 18855, 18860, + 18863, 18867, 18874, 18879, 18883, 18888, 18892, 18897, 18901, 18906, + 18913, 18919, 18924, 18928, 18932, 18936, 18940, 18944, 18949, 18955, + 18961, 18966, 18972, 18976, 18979, 18982, 18985, 18988, 18991, 18994, + 18997, 19000, 19003, 19009, 19013, 19017, 19021, 19025, 19029, 19033, + 19037, 19041, 19046, 19050, 19055, 19060, 19066, 19071, 19077, 19083, + 19089, 19095, 19101, 19108, 19115, 19123, 19131, 19140, 19149, 19160, + 19170, 19180, 19191, 19202, 19212, 19222, 19232, 19242, 19252, 19262, + 19272, 19282, 19290, 19297, 19303, 19310, 19315, 19321, 19327, 19333, + 19339, 19345, 19351, 19356, 19362, 19368, 19374, 19380, 19385, 19393, + 19400, 19406, 19413, 19421, 19427, 19433, 19439, 19445, 19453, 19461, + 19471, 19479, 19487, 19493, 19498, 19503, 19508, 19513, 19518, 19523, + 19528, 19533, 19538, 19544, 19550, 19556, 19563, 19568, 19574, 19579, + 19584, 19589, 19594, 19599, 19604, 19609, 19614, 19619, 19624, 19629, + 19634, 19639, 19644, 19649, 19654, 19659, 19664, 19669, 19674, 19679, + 19684, 19689, 19694, 19699, 19704, 19709, 19714, 19719, 19724, 19729, + 19734, 19739, 19744, 19749, 19754, 19759, 0, 19764, 0, 0, 0, 0, 0, 19769, + 0, 0, 19774, 19778, 19782, 19786, 19790, 19794, 19798, 19802, 19806, + 19810, 19814, 19818, 19822, 19826, 19830, 19834, 19838, 19842, 19846, + 19850, 19854, 19858, 19862, 19866, 19870, 19874, 19878, 19882, 19886, + 19890, 19894, 19898, 19902, 19906, 19910, 19914, 19918, 19922, 19926, + 19930, 19934, 19938, 19943, 19947, 19952, 19957, 19961, 19966, 19971, + 19975, 19979, 19983, 19987, 19991, 19995, 19999, 20003, 20007, 20011, + 20015, 20019, 20023, 20027, 20031, 20035, 20039, 20043, 20047, 20051, + 20055, 20059, 20063, 20067, 20071, 20075, 20079, 20083, 20087, 20091, + 20095, 20099, 20103, 20107, 20111, 20115, 20119, 20123, 20127, 20131, + 20135, 20139, 20143, 20147, 20151, 20155, 20159, 20163, 20167, 20171, + 20175, 20179, 20183, 20187, 20191, 20195, 20199, 20203, 20207, 20211, + 20215, 20219, 20223, 20227, 20231, 20235, 20239, 20243, 20247, 20251, + 20255, 20259, 20263, 20267, 20271, 20275, 20279, 20283, 20287, 20291, + 20295, 20299, 20303, 20307, 20311, 20315, 20319, 20323, 20327, 20331, + 20335, 20339, 20343, 20347, 20351, 20355, 20359, 20362, 20366, 20369, + 20373, 20377, 20380, 20384, 20388, 20391, 20395, 20399, 20403, 20407, + 20410, 20414, 20418, 20422, 20426, 20430, 20434, 20437, 20441, 20445, + 20449, 20453, 20457, 20461, 20465, 20469, 20473, 20477, 20481, 20485, + 20489, 20493, 20497, 20501, 20505, 20509, 20513, 20517, 20521, 20525, + 20529, 20533, 20537, 20541, 20545, 20549, 20553, 20557, 20561, 20565, + 20569, 20573, 20577, 20581, 20585, 20589, 20593, 20597, 20601, 20605, + 20609, 20613, 20617, 20621, 20625, 20629, 20633, 20637, 20641, 20645, + 20649, 20653, 20657, 20661, 20665, 20669, 20673, 20677, 20681, 20685, + 20689, 20693, 20697, 20701, 20705, 20709, 20713, 20717, 20721, 20725, + 20729, 20733, 20737, 20741, 20745, 20749, 20753, 20757, 20761, 20765, + 20769, 20773, 20777, 20781, 20785, 20789, 20793, 20797, 20801, 20805, + 20809, 20813, 20817, 20821, 20825, 20829, 20833, 20837, 20841, 20845, + 20849, 20853, 20857, 20861, 20865, 20869, 20873, 20877, 20881, 20885, + 20889, 20893, 20897, 20901, 20905, 20909, 20913, 20917, 20921, 20925, + 20929, 20933, 20937, 20941, 20945, 20949, 20953, 20957, 20961, 20965, + 20969, 20973, 20977, 20981, 20985, 20989, 20992, 20996, 21000, 21004, + 21008, 21012, 21016, 21020, 21024, 21028, 21032, 21036, 21040, 21044, + 21048, 21052, 21056, 21060, 21064, 21068, 21072, 21076, 21080, 21084, + 21087, 21091, 21095, 21099, 21103, 21107, 21111, 21115, 21119, 21123, + 21127, 21131, 21135, 21139, 21143, 21147, 21151, 21155, 21159, 21163, + 21167, 21171, 21175, 21179, 21183, 21187, 21191, 21195, 21199, 21203, + 21207, 21211, 21215, 21219, 21223, 21227, 21231, 21235, 21239, 21243, + 21247, 21251, 21255, 21259, 21263, 21267, 21271, 21275, 0, 21279, 21283, + 21287, 21291, 0, 0, 21295, 21299, 21303, 21307, 21311, 21315, 21319, 0, + 21323, 0, 21327, 21331, 21335, 21339, 0, 0, 21343, 21347, 21351, 21355, + 21359, 21363, 21367, 21371, 21375, 21379, 21383, 21387, 21391, 21395, + 21399, 21403, 21407, 21411, 21415, 21419, 21423, 21427, 21431, 21434, + 21438, 21442, 21446, 21450, 21454, 21458, 21462, 21466, 21470, 21474, + 21478, 21482, 21486, 21490, 21494, 21498, 21502, 0, 21506, 21510, 21514, + 21518, 0, 0, 21522, 21525, 21529, 21533, 21537, 21541, 21545, 21549, + 21553, 21557, 21561, 21565, 21569, 21573, 21577, 21581, 21585, 21590, + 21595, 21600, 21606, 21612, 21617, 21622, 21628, 21631, 21635, 21639, + 21643, 21647, 21651, 21655, 21659, 0, 21663, 21667, 21671, 21675, 0, 0, + 21679, 21683, 21687, 21691, 21695, 21699, 21703, 0, 21707, 0, 21711, + 21715, 21719, 21723, 0, 0, 21727, 21731, 21735, 21739, 21743, 21747, + 21751, 21755, 21759, 21764, 21769, 21774, 21780, 21786, 21791, 0, 21796, + 21800, 21804, 21808, 21812, 21816, 21820, 21824, 21828, 21832, 21836, + 21840, 21844, 21848, 21852, 21856, 21860, 21863, 21867, 21871, 21875, + 21879, 21883, 21887, 21891, 21895, 21899, 21903, 21907, 21911, 21915, + 21919, 21923, 21927, 21931, 21935, 21939, 21943, 21947, 21951, 21955, + 21959, 21963, 21967, 21971, 21975, 21979, 21983, 21987, 21991, 21995, + 21999, 22003, 22007, 22011, 22015, 22019, 0, 22023, 22027, 22031, 22035, + 0, 0, 22039, 22043, 22047, 22051, 22055, 22059, 22063, 22067, 22071, + 22075, 22079, 22083, 22087, 22091, 22095, 22099, 22103, 22107, 22111, + 22115, 22119, 22123, 22127, 22131, 22135, 22139, 22143, 22147, 22151, + 22155, 22159, 22163, 22167, 22171, 22175, 22179, 22183, 22187, 22191, + 22195, 22199, 22203, 22207, 22211, 22215, 22219, 22223, 22227, 22231, + 22235, 22239, 22243, 22247, 22251, 22255, 22259, 22263, 22266, 22270, + 22274, 22278, 22282, 22286, 22290, 22294, 22298, 22302, 0, 0, 22306, + 22315, 22321, 22326, 22330, 22333, 22338, 22341, 22344, 22347, 22352, + 22356, 22361, 22364, 22367, 22370, 22373, 22376, 22379, 22382, 22385, + 22388, 22392, 22396, 22400, 22404, 22408, 22412, 22416, 22420, 22424, + 22428, 0, 0, 0, 22434, 22440, 22444, 22448, 22452, 22458, 22462, 22466, + 22470, 22476, 22480, 22484, 22488, 22494, 22498, 22502, 22506, 22512, + 22518, 22524, 22532, 22538, 22544, 22550, 22556, 22562, 0, 0, 0, 0, 0, 0, + 22568, 22571, 22574, 22577, 22580, 22583, 22587, 22591, 22594, 22598, + 22602, 22606, 22610, 22614, 22617, 22621, 22625, 22629, 22633, 22637, + 22641, 22645, 22649, 22653, 22657, 22661, 22664, 22668, 22672, 22676, + 22680, 22683, 22687, 22691, 22695, 22699, 22703, 22707, 22711, 22715, + 22719, 22723, 22727, 22731, 22735, 22739, 22742, 22746, 22750, 22754, + 22758, 22762, 22766, 22770, 22774, 22778, 22782, 22786, 22790, 22794, + 22798, 22802, 22806, 22810, 22814, 22818, 22822, 22826, 22830, 22834, + 22838, 22842, 22846, 22850, 22854, 22858, 22862, 22866, 22870, 22874, + 22877, 22881, 22885, 22889, 22893, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 22897, 22901, 22904, 22908, 22911, 22915, 22918, 22922, 22928, 22933, + 22937, 22940, 22944, 22948, 22953, 22957, 22962, 22966, 22971, 22975, + 22980, 22984, 22989, 22995, 22999, 23004, 23008, 23013, 23019, 23023, + 23029, 23035, 23039, 23044, 23052, 23060, 23067, 23072, 23077, 23086, + 23093, 23100, 23105, 23111, 23115, 23119, 23123, 23127, 23131, 23135, + 23139, 23143, 23147, 23151, 23157, 23162, 23167, 23170, 23174, 23178, + 23183, 23187, 23192, 23196, 23201, 23205, 23210, 23214, 23219, 23223, + 23228, 23232, 23237, 23243, 23247, 23252, 23257, 23261, 23265, 23269, + 23273, 23276, 23280, 23286, 23291, 23296, 23300, 23304, 23308, 23313, + 23317, 23322, 23326, 23331, 23334, 23338, 23342, 23347, 23351, 23356, + 23360, 23365, 23371, 23375, 23379, 23383, 23387, 23391, 23395, 23399, + 23403, 23407, 23411, 23415, 23421, 23424, 23428, 23432, 23437, 23441, + 23446, 23450, 23455, 23459, 23464, 23468, 23473, 23477, 23482, 23486, + 23491, 23497, 23501, 23505, 23511, 23517, 23523, 23529, 23533, 23537, + 23541, 23545, 23549, 23553, 23559, 23563, 23567, 23571, 23576, 23580, + 23585, 23589, 23594, 23598, 23603, 23607, 23612, 23616, 23621, 23625, + 23630, 23636, 23640, 23646, 23650, 23654, 23658, 23662, 23666, 23670, + 23676, 23679, 23683, 23687, 23692, 23696, 23701, 23705, 23710, 23714, + 23719, 23723, 23728, 23732, 23737, 23741, 23746, 23752, 23756, 23761, + 23765, 23771, 23777, 23781, 23785, 23789, 23793, 23797, 23801, 23807, + 23810, 23814, 23818, 23823, 23827, 23832, 23836, 23841, 23847, 23851, + 23856, 23860, 23864, 23868, 23872, 23876, 23880, 23884, 23890, 23894, + 23898, 23902, 23907, 23911, 23916, 23920, 23925, 23929, 23934, 23938, + 23943, 23947, 23952, 23956, 23961, 23964, 23968, 23972, 23976, 23980, + 23984, 23988, 23992, 23996, 24002, 24006, 24010, 24014, 24019, 24023, + 24028, 24032, 24037, 24041, 24046, 24050, 24055, 24059, 24064, 24068, + 24073, 24079, 24082, 24087, 24091, 24096, 24102, 24108, 24114, 24120, + 24126, 24132, 24138, 24142, 24146, 24150, 24154, 24158, 24162, 24166, + 24170, 24175, 24179, 24184, 24188, 24193, 24197, 24202, 24206, 24211, + 24215, 24220, 24224, 24229, 24233, 24237, 24241, 24245, 24249, 24253, + 24257, 24263, 24266, 24270, 24274, 24279, 24283, 24288, 24292, 24297, + 24301, 24306, 24310, 24315, 24319, 24324, 24328, 24333, 24339, 24343, + 24349, 24354, 24360, 24364, 24370, 24375, 24379, 24383, 24387, 24391, + 24395, 24400, 24404, 24408, 24413, 24417, 24422, 24425, 24429, 24433, + 24437, 24441, 24445, 24449, 24453, 24457, 24461, 24465, 24469, 24474, + 24478, 24482, 24488, 24492, 24498, 24502, 24508, 24512, 24516, 24520, + 24524, 24528, 24533, 24537, 24541, 24545, 24549, 24553, 24557, 24561, + 24565, 24569, 24573, 24579, 24585, 24591, 24597, 24603, 24608, 24614, + 24620, 24626, 24630, 24634, 24638, 24642, 24646, 24650, 24654, 24658, + 24662, 24666, 24670, 24674, 24678, 24683, 24688, 24693, 24698, 24702, + 24706, 24710, 24714, 24718, 24722, 24726, 24730, 24734, 24740, 24746, + 24752, 24758, 24764, 24770, 24776, 24782, 24788, 24792, 24796, 24800, + 24804, 24808, 24812, 24816, 24822, 24828, 24834, 24840, 24846, 24852, + 24858, 24864, 24870, 24875, 24880, 24885, 24890, 24896, 24902, 24908, + 24914, 24920, 24926, 24932, 24937, 24943, 24949, 24955, 24960, 24966, + 24972, 24978, 24983, 24988, 24993, 24998, 25003, 25008, 25013, 25018, + 25023, 25028, 25033, 25038, 25043, 25048, 25053, 25058, 25063, 25068, + 25073, 25078, 25083, 25088, 25093, 25098, 25103, 25108, 25113, 25118, + 25123, 25128, 25133, 25138, 25143, 25148, 25153, 25158, 25163, 25168, + 25173, 25178, 25183, 25188, 25192, 25197, 25202, 25207, 25212, 25217, + 25222, 25227, 25232, 25237, 25242, 25247, 25252, 25257, 25262, 25267, + 25272, 25277, 25282, 25287, 25292, 25297, 25302, 25307, 25312, 25317, + 25321, 25326, 25331, 25336, 25341, 25346, 25350, 25355, 25360, 25365, + 25370, 25375, 25379, 25384, 25390, 25395, 25400, 25405, 25410, 25416, + 25421, 25426, 25431, 25436, 25441, 25446, 25451, 25456, 25461, 25466, + 25471, 25476, 25481, 25486, 25491, 25496, 25501, 25506, 25511, 25516, + 25521, 25526, 25531, 25536, 25541, 25546, 25551, 25556, 25561, 25566, + 25571, 25576, 25581, 25586, 25591, 25596, 25601, 25606, 25611, 25616, + 25621, 25626, 25631, 25636, 25642, 25647, 25652, 25657, 25662, 25667, + 25672, 25677, 25682, 25687, 25692, 25697, 25702, 25707, 25712, 25717, + 25722, 25727, 25732, 25737, 25742, 25747, 25752, 25757, 25762, 25767, + 25772, 25777, 25782, 25787, 25792, 25797, 25802, 25807, 25812, 25817, + 25822, 25827, 25832, 25838, 25842, 25846, 25850, 25854, 25858, 25862, + 25866, 25870, 25876, 25882, 25888, 25894, 25900, 25906, 25912, 25919, + 25925, 25930, 25935, 25940, 25945, 25950, 25955, 25960, 25965, 25970, + 25975, 25980, 25985, 25990, 25995, 26000, 26005, 26010, 26015, 26020, + 26025, 26030, 26035, 26040, 26045, 26050, 26055, 26060, 26065, 0, 0, 0, + 26072, 26082, 26086, 26093, 26097, 26101, 26105, 26113, 26117, 26122, + 26127, 26132, 26136, 26141, 26146, 26149, 26153, 26157, 26166, 26170, + 26174, 26180, 26184, 26188, 26196, 26200, 26208, 26214, 26220, 26226, + 26232, 26242, 26248, 26252, 26261, 26264, 26270, 26274, 26280, 26285, + 26291, 26299, 26305, 26310, 26317, 26322, 26326, 26330, 26340, 26346, + 26350, 26360, 26366, 26370, 26374, 26381, 26389, 26395, 26401, 26410, + 26414, 26418, 26422, 26430, 26437, 26441, 26445, 26449, 26453, 26457, + 26461, 26465, 26469, 26473, 26477, 26481, 26486, 26491, 26496, 26500, + 26504, 26508, 26512, 26516, 26520, 26528, 26536, 26544, 26552, 0, 0, 0, + 0, 0, 0, 0, 26560, 26564, 26568, 26572, 26576, 26581, 26586, 26591, + 26596, 26600, 26604, 26609, 26613, 0, 26617, 26622, 26627, 26632, 26636, + 26641, 26646, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26651, 26655, 26659, + 26663, 26667, 26672, 26677, 26682, 26687, 26691, 26695, 26700, 26704, + 26708, 26713, 26718, 26723, 26728, 26732, 26737, 26742, 26747, 26753, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 26758, 26762, 26766, 26770, 26774, 26779, 26784, + 26789, 26794, 26798, 26802, 26807, 26811, 26815, 26820, 26825, 26830, + 26835, 26839, 26844, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26849, 26853, + 26857, 26861, 26865, 26870, 26875, 26880, 26885, 26889, 26893, 26898, + 26902, 0, 26906, 26911, 26916, 0, 26921, 26926, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 26931, 26934, 26938, 26942, 26946, 26950, 26954, 26958, + 26962, 26966, 26970, 26974, 26978, 26982, 26986, 26990, 26994, 26998, + 27001, 27005, 27009, 27013, 27017, 27021, 27025, 27029, 27033, 27037, + 27041, 27045, 27049, 27053, 27057, 27060, 27064, 27068, 27074, 27080, + 27086, 27092, 27098, 27104, 27110, 27116, 27122, 27128, 27134, 27140, + 27146, 27152, 27161, 27170, 27176, 27182, 27188, 27193, 27197, 27202, + 27207, 27212, 27216, 27221, 27226, 27231, 27235, 27240, 27244, 27249, + 27254, 27259, 27264, 27268, 27272, 27276, 27280, 27284, 27288, 27292, + 27296, 27300, 27304, 27310, 27314, 27318, 27322, 27326, 27330, 27338, + 27344, 27348, 27354, 27358, 27364, 27368, 0, 0, 27372, 27376, 27379, + 27382, 27385, 27388, 27391, 27394, 27397, 27400, 0, 0, 0, 0, 0, 0, 27403, + 27411, 27419, 27427, 27435, 27443, 27451, 27459, 27467, 27475, 0, 0, 0, + 0, 0, 0, 27483, 27486, 27489, 27492, 27497, 27500, 27505, 27512, 27520, + 27525, 27532, 27535, 27542, 27549, 27556, 0, 27560, 27564, 27567, 27570, + 27573, 27576, 27579, 27582, 27585, 27588, 0, 0, 0, 0, 0, 0, 27591, 27594, + 27597, 27600, 27603, 27606, 27610, 27614, 27618, 27621, 27625, 27629, + 27632, 27636, 27640, 27643, 27647, 27651, 27655, 27659, 27663, 27667, + 27671, 27674, 27678, 27682, 27686, 27689, 27693, 27697, 27701, 27705, + 27709, 27713, 27717, 27721, 27728, 27733, 27738, 27743, 27748, 27754, + 27760, 27766, 27772, 27777, 27783, 27789, 27794, 27800, 27806, 27812, + 27818, 27824, 27829, 27835, 27840, 27846, 27852, 27858, 27864, 27870, + 27875, 27880, 27886, 27892, 27897, 27903, 27908, 27914, 27919, 27924, + 27930, 27936, 27942, 27948, 27954, 27960, 27966, 27972, 27978, 27984, + 27990, 27996, 28001, 28006, 28012, 28018, 0, 0, 0, 0, 0, 0, 0, 0, 28024, + 28033, 28042, 28050, 28058, 28068, 28076, 28085, 28092, 28099, 28106, + 28114, 28122, 28130, 28138, 28146, 28154, 28162, 28170, 28177, 28185, + 28193, 28201, 28209, 28217, 28227, 28237, 28247, 28257, 28267, 28277, + 28287, 28297, 28307, 28317, 28327, 28337, 28347, 28357, 28365, 28373, + 28383, 28391, 0, 0, 0, 0, 0, 28401, 28405, 28409, 28413, 28417, 28421, + 28425, 28429, 28433, 28437, 28441, 28445, 28449, 28453, 28457, 28461, + 28465, 28469, 28473, 28477, 28481, 28485, 28489, 28493, 28499, 28503, + 28509, 28513, 28519, 28523, 28529, 28533, 28537, 28541, 28545, 28549, + 28553, 28559, 28565, 28571, 28577, 28583, 28589, 28594, 28600, 28606, + 28612, 28618, 28625, 28631, 28636, 28641, 28645, 28649, 28653, 28657, + 28661, 28665, 28669, 28675, 28681, 28687, 28692, 28699, 28704, 28709, + 28715, 28720, 28727, 28734, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28740, 28746, + 28750, 28755, 28760, 28765, 28770, 28775, 28780, 28785, 28790, 28795, + 28800, 28805, 28810, 28815, 28819, 28823, 28828, 28833, 28838, 28842, + 28846, 28851, 28856, 28861, 28866, 28871, 28876, 28880, 28885, 0, 28890, + 28895, 28900, 28905, 28911, 28917, 28923, 28929, 28934, 28939, 28945, + 28952, 0, 0, 0, 0, 28959, 28964, 28970, 28976, 28982, 28987, 28992, + 28997, 29003, 29009, 29014, 29019, 0, 0, 0, 0, 29024, 0, 0, 0, 29029, + 29034, 29039, 29044, 29048, 29052, 29056, 29060, 29064, 29068, 29072, + 29076, 29080, 29085, 29091, 29097, 29103, 29109, 29114, 29120, 29126, + 29132, 29137, 29143, 29148, 29154, 29160, 29165, 29171, 29177, 29183, + 29188, 29193, 29198, 29204, 29210, 29215, 29221, 29226, 29232, 29237, + 29243, 0, 0, 29249, 29255, 29261, 29267, 29273, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 29279, 29287, 29295, 29302, 29310, 29318, 29325, 29333, 29341, + 29349, 29357, 29364, 29372, 29380, 29387, 29395, 29403, 29410, 29418, + 29426, 29433, 29440, 29448, 29455, 29462, 29470, 29477, 29485, 29493, + 29501, 29509, 29517, 29525, 29532, 29540, 29548, 29555, 29563, 29571, + 29579, 29587, 29595, 29603, 29611, 0, 0, 0, 0, 29619, 29628, 29636, + 29644, 29651, 29659, 29666, 29674, 29681, 29689, 29697, 29705, 29713, + 29721, 29729, 29737, 29745, 29753, 29761, 29769, 29777, 29785, 29793, + 29801, 29809, 29816, 0, 0, 0, 0, 0, 0, 29823, 29830, 29836, 29842, 29848, + 29854, 29860, 29866, 29872, 29878, 29884, 0, 0, 0, 29891, 29898, 29905, + 29909, 29915, 29921, 29927, 29933, 29939, 29945, 29951, 29957, 29963, + 29969, 29975, 29981, 29987, 29993, 29999, 30003, 30009, 30015, 30021, + 30027, 30033, 30039, 30045, 30051, 30057, 30063, 30069, 30075, 30081, + 30087, 30093, 30097, 30102, 30107, 30112, 30116, 30121, 30125, 30130, + 30135, 30140, 30144, 30149, 30154, 30159, 30164, 30169, 30173, 30178, + 30183, 30188, 30193, 30197, 30201, 30206, 30211, 30216, 30221, 0, 0, + 30227, 30231, 30238, 30243, 30249, 30255, 30260, 30266, 30272, 30277, + 30283, 30289, 30295, 30301, 30307, 30312, 30317, 30323, 30328, 30334, + 30339, 30345, 30351, 30357, 30363, 30367, 30372, 30377, 30383, 30389, + 30394, 30400, 30406, 30410, 30415, 30420, 30425, 30430, 30435, 30440, + 30445, 30451, 30457, 30463, 30468, 30473, 30477, 30482, 30486, 30491, + 30495, 30500, 30505, 30510, 30515, 30522, 30529, 30536, 30546, 30555, + 30562, 30568, 30579, 30584, 30590, 0, 30596, 30601, 30606, 30614, 30620, + 30628, 30633, 30639, 30645, 30651, 30656, 30662, 30667, 30674, 30680, + 30685, 30691, 30697, 30703, 30710, 30717, 30724, 30729, 30734, 30741, + 30748, 30755, 30762, 30769, 0, 0, 30776, 30783, 30790, 30796, 30802, + 30808, 30814, 30820, 30826, 30832, 30838, 0, 0, 0, 0, 0, 0, 30844, 30850, + 30855, 30860, 30865, 30870, 30875, 30880, 30885, 30890, 0, 0, 0, 0, 0, 0, + 30895, 30900, 30905, 30910, 30915, 30920, 30925, 30934, 30941, 30946, + 30951, 30956, 30961, 30966, 0, 0, 30971, 30978, 30981, 30984, 30987, + 30992, 30996, 31002, 31007, 31013, 31020, 31028, 31032, 31037, 31041, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31046, 31052, 31058, + 31062, 31066, 31070, 31074, 31080, 31084, 31090, 31094, 31100, 31106, + 31114, 31120, 31128, 31132, 31136, 31140, 31146, 31149, 31155, 31159, + 31165, 31169, 31173, 31179, 31183, 31189, 31193, 31199, 31207, 31215, + 31223, 31229, 31233, 31239, 31243, 31249, 31252, 31255, 31261, 31265, + 31271, 31274, 31277, 31281, 31285, 31289, 31295, 31301, 31305, 31308, + 31312, 31317, 31322, 31329, 31334, 31341, 31348, 31357, 31364, 31373, + 31378, 31385, 31392, 31401, 31406, 31413, 31418, 31424, 31430, 31436, + 31442, 31448, 31454, 0, 0, 0, 0, 31460, 31464, 31467, 31470, 31473, + 31476, 31479, 31482, 31485, 31488, 31491, 31494, 31497, 31500, 31505, + 31510, 31515, 31518, 31523, 31528, 31533, 31538, 31545, 31550, 31555, + 31560, 31565, 31572, 31578, 31584, 31590, 31596, 31602, 31611, 31620, + 31626, 31632, 31641, 31650, 31659, 31668, 31677, 31686, 31695, 31704, 0, + 0, 0, 31713, 31718, 31723, 31728, 31732, 31736, 31740, 31745, 31749, + 31753, 31758, 31762, 31767, 31772, 31777, 31782, 31787, 31792, 31797, + 31802, 31807, 31811, 31815, 31820, 31825, 31830, 31834, 31838, 31843, + 31848, 31853, 31858, 31863, 31867, 31873, 31879, 31885, 31891, 31897, + 31903, 31909, 31915, 31921, 31926, 31931, 31938, 31946, 31951, 31956, + 31961, 31965, 31969, 31973, 31977, 31981, 31985, 31989, 31993, 31997, + 32001, 32006, 32011, 32016, 32022, 32028, 32032, 32038, 32042, 32048, + 32054, 32059, 32066, 32070, 32076, 32080, 32086, 32091, 32098, 32105, + 32110, 32117, 32122, 32127, 32132, 32139, 32143, 32149, 32156, 32163, + 32168, 32175, 32182, 32186, 32192, 32197, 32202, 32209, 32214, 32219, + 32224, 32229, 32233, 32237, 32242, 32247, 32254, 32260, 32265, 32272, + 32277, 32284, 32289, 32299, 32305, 32311, 32315, 0, 0, 0, 0, 0, 0, 0, 0, + 32319, 32328, 32335, 32342, 32349, 32353, 32358, 32363, 32368, 32373, + 32378, 32383, 32388, 32393, 32398, 32403, 32408, 32413, 32417, 32421, + 32426, 32431, 32436, 32441, 32446, 32451, 32455, 32460, 32465, 32470, + 32475, 32479, 32484, 32489, 32493, 32498, 32503, 32508, 32513, 32518, + 32522, 32528, 32535, 32541, 32546, 32551, 32557, 32562, 32568, 32573, + 32579, 32585, 32590, 32596, 32602, 32607, 32613, 32619, 32625, 32630, 0, + 0, 0, 32635, 32641, 32651, 32657, 32665, 32671, 32676, 32680, 32684, + 32688, 32692, 32696, 32700, 32704, 32708, 0, 0, 0, 32712, 32717, 32722, + 32727, 32734, 32740, 32746, 32752, 32758, 32764, 32770, 32776, 32782, + 32788, 32795, 32802, 32809, 32816, 32823, 32830, 32837, 32844, 32851, + 32858, 32865, 32872, 32879, 32886, 32893, 32900, 32907, 32914, 32921, + 32928, 32935, 32942, 32949, 32956, 32963, 32970, 32977, 32984, 32991, + 32998, 33006, 33014, 33022, 33028, 33034, 33040, 33048, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 12070, 0, 12079, 12086, 12094, 12106, 12113, 12120, 12127, 12138, 12149, - 12156, 12164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12170, 12175, 12180, 12185, 12190, - 12195, 12200, 12205, 12210, 12215, 12220, 12225, 12230, 12234, 12238, - 12242, 12247, 12253, 12259, 12265, 12270, 12275, 12280, 12285, 12291, - 12300, 12308, 0, 12314, 12320, 12324, 12328, 12332, 12337, 12340, 12344, - 12347, 12351, 12354, 12358, 12362, 12366, 12371, 12376, 12379, 12383, - 12388, 12393, 12396, 12400, 12403, 12407, 12411, 12415, 12419, 12423, - 12427, 12431, 12435, 12439, 12443, 12447, 12451, 12455, 12459, 12463, - 12467, 12471, 12475, 12478, 12482, 12485, 12489, 12493, 12497, 12500, - 12503, 12506, 12510, 12514, 12518, 12522, 12526, 12530, 12534, 12537, - 12540, 12545, 12550, 12554, 12558, 12563, 12567, 12572, 12576, 12581, - 12586, 12592, 12598, 12604, 12608, 12613, 12619, 12625, 12629, 12634, - 12638, 12644, 12649, 12652, 12658, 12664, 12669, 12674, 12681, 12686, - 12691, 12695, 12699, 12703, 12707, 12711, 12715, 12719, 12723, 12728, - 12733, 12738, 12744, 12747, 12751, 12755, 12758, 12761, 12764, 12767, - 12770, 12773, 12776, 12779, 12782, 12786, 12793, 12798, 12802, 12806, - 12810, 12814, 0, 12818, 12822, 12826, 12830, 12834, 12840, 12844, 0, - 12848, 12852, 12856, 0, 12860, 12863, 12867, 12870, 12874, 12877, 12881, - 12885, 0, 0, 12889, 12892, 0, 0, 12896, 12899, 12903, 12906, 12910, - 12914, 12918, 12922, 12926, 12930, 12934, 12938, 12942, 12946, 12950, - 12954, 12958, 12962, 12966, 12970, 12974, 12978, 0, 12981, 12984, 12988, - 12992, 12996, 12999, 13002, 0, 13005, 0, 0, 0, 13009, 13013, 13017, - 13020, 0, 0, 13023, 13027, 13031, 13036, 13040, 13045, 13049, 13054, - 13059, 0, 0, 13065, 13069, 0, 0, 13074, 13078, 13083, 13087, 0, 0, 0, 0, - 0, 0, 0, 0, 13093, 0, 0, 0, 0, 13099, 13103, 0, 13107, 13111, 13116, - 13121, 13126, 0, 0, 13132, 13136, 13139, 13142, 13145, 13148, 13151, - 13154, 13157, 13160, 13163, 13172, 13181, 13185, 13189, 13195, 13201, - 13207, 13213, 13227, 13234, 13237, 0, 0, 0, 0, 0, 13241, 13247, 13251, 0, - 13255, 13258, 13262, 13265, 13269, 13272, 0, 0, 0, 0, 13276, 13280, 0, 0, - 13284, 13288, 13292, 13295, 13299, 13303, 13307, 13311, 13315, 13319, - 13323, 13327, 13331, 13335, 13339, 13343, 13347, 13351, 13355, 13359, - 13363, 13367, 0, 13370, 13373, 13377, 13381, 13385, 13388, 13391, 0, - 13394, 13398, 0, 13402, 13406, 0, 13410, 13413, 0, 0, 13416, 0, 13420, - 13425, 13429, 13434, 13438, 0, 0, 0, 0, 13443, 13448, 0, 0, 13453, 13458, - 13463, 0, 0, 0, 13467, 0, 0, 0, 0, 0, 0, 0, 13471, 13475, 13479, 13483, - 0, 13487, 0, 0, 0, 0, 0, 0, 0, 13491, 13495, 13498, 13501, 13504, 13507, - 13510, 13513, 13516, 13519, 13522, 13525, 13528, 13531, 13534, 13539, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13543, 13547, 13551, 0, 13555, 13558, - 13562, 13565, 13569, 13572, 13576, 13580, 13584, 0, 13589, 13592, 13596, - 0, 13601, 13604, 13608, 13611, 13615, 13619, 13623, 13627, 13631, 13635, - 13639, 13643, 13647, 13651, 13655, 13659, 13663, 13667, 13671, 13675, - 13679, 13683, 0, 13686, 13689, 13693, 13697, 13701, 13704, 13707, 0, - 13710, 13714, 0, 13718, 13722, 13726, 13730, 13733, 0, 0, 13736, 13740, - 13744, 13749, 13753, 13758, 13762, 13767, 13772, 13778, 0, 13784, 13788, - 13793, 0, 13799, 13803, 13808, 0, 0, 13812, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 13815, 13820, 13825, 13830, 0, 0, 13836, 13840, 13843, - 13846, 13849, 13852, 13855, 13858, 13861, 13864, 13867, 13871, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13875, 13879, 13883, 0, 13887, 13890, - 13894, 13897, 13901, 13904, 13908, 13912, 0, 0, 13916, 13919, 0, 0, - 13923, 13926, 13930, 13933, 13937, 13941, 13945, 13949, 13953, 13957, - 13961, 13965, 13969, 13973, 13977, 13981, 13985, 13989, 13993, 13997, - 14001, 14005, 0, 14008, 14011, 14015, 14019, 14023, 14026, 14029, 0, - 14032, 14036, 0, 14040, 14044, 14048, 14052, 14055, 0, 0, 14058, 14062, - 14066, 14071, 14075, 14080, 14084, 14089, 14094, 0, 0, 14100, 14104, 0, - 0, 14109, 14113, 14118, 0, 0, 0, 0, 0, 0, 0, 0, 14122, 14128, 0, 0, 0, 0, - 14134, 14138, 0, 14142, 14146, 14151, 14156, 14161, 0, 0, 14167, 14171, - 14174, 14177, 14180, 14183, 14186, 14189, 14192, 14195, 14198, 14201, - 14205, 14211, 14217, 14223, 14229, 14235, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 14241, 14245, 0, 14249, 14252, 14256, 14259, 14263, 14266, 0, 0, 0, - 14270, 14273, 14277, 0, 14281, 14284, 14288, 14292, 0, 0, 0, 14295, - 14299, 0, 14303, 0, 14307, 14311, 0, 0, 0, 14315, 14319, 0, 0, 0, 14323, - 14326, 14330, 0, 0, 0, 14333, 14336, 14339, 14342, 14346, 14350, 14354, - 14358, 14362, 14366, 14370, 14373, 0, 0, 0, 0, 14376, 14381, 14385, - 14390, 14394, 0, 0, 0, 14399, 14403, 14408, 0, 14413, 14417, 14422, - 14427, 0, 0, 14431, 0, 0, 0, 0, 0, 0, 14434, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 14440, 14444, 14447, 14450, 14453, 14456, 14459, 14462, - 14465, 14468, 14471, 14475, 14480, 14485, 14489, 14493, 14497, 14501, - 14505, 14510, 14514, 0, 0, 0, 0, 0, 0, 14517, 14521, 14525, 0, 14529, - 14532, 14536, 14539, 14543, 14546, 14550, 14554, 0, 14558, 14561, 14565, - 0, 14569, 14572, 14576, 14580, 14583, 14587, 14591, 14595, 14599, 14603, - 14607, 14611, 14615, 14619, 14623, 14627, 14631, 14635, 14639, 14643, - 14647, 14651, 14655, 0, 14658, 14661, 14665, 14669, 14673, 14676, 14679, - 14682, 14686, 14690, 0, 14694, 14698, 14702, 14706, 14709, 0, 0, 0, - 14712, 14716, 14721, 14725, 14730, 14734, 14739, 14744, 0, 14750, 14754, - 14759, 0, 14764, 14768, 14773, 14778, 0, 0, 0, 0, 0, 0, 0, 14782, 14786, - 0, 14792, 14796, 0, 0, 0, 0, 0, 0, 14800, 14805, 14810, 14815, 0, 0, - 14821, 14825, 14828, 14831, 14834, 14837, 14840, 14843, 14846, 14849, 0, - 0, 0, 0, 0, 0, 0, 0, 14852, 14865, 14877, 14889, 14901, 14913, 14925, - 14937, 0, 0, 14941, 14945, 0, 14949, 14952, 14956, 14959, 14963, 14966, - 14970, 14974, 0, 14978, 14981, 14985, 0, 14989, 14992, 14996, 15000, - 15003, 15007, 15011, 15015, 15019, 15023, 15027, 15031, 15035, 15039, - 15043, 15047, 15051, 15055, 15059, 15063, 15067, 15071, 15075, 0, 15078, - 15081, 15085, 15089, 15093, 15096, 15099, 15102, 15106, 15110, 0, 15114, - 15118, 15122, 15126, 15129, 0, 0, 15132, 15136, 15140, 15145, 15149, - 15154, 15158, 15163, 15168, 0, 15174, 15178, 15183, 0, 15188, 15192, - 15197, 15202, 0, 0, 0, 0, 0, 0, 0, 15206, 15210, 0, 0, 0, 0, 0, 0, 0, - 15216, 0, 15220, 15225, 15230, 15235, 0, 0, 15241, 15245, 15248, 15251, - 15254, 15257, 15260, 15263, 15266, 15269, 0, 15272, 15276, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15280, 15284, 0, 15288, 15291, 15295, - 15298, 15302, 15305, 15309, 15313, 0, 15317, 15320, 15324, 0, 15328, - 15331, 15335, 15339, 15342, 15346, 15350, 15354, 15358, 15362, 15366, - 15370, 15374, 15378, 15382, 15386, 15390, 15394, 15398, 15402, 15406, - 15410, 15414, 15417, 15421, 15424, 15428, 15432, 15436, 15439, 15442, - 15445, 15449, 15453, 15457, 15461, 15465, 15469, 15473, 15476, 15479, 0, - 0, 15483, 15487, 15492, 15496, 15501, 15505, 15510, 15515, 0, 15521, - 15525, 15530, 0, 15535, 15539, 15544, 15549, 15553, 0, 0, 0, 0, 0, 0, 0, - 0, 15558, 0, 0, 0, 0, 0, 0, 0, 0, 15564, 15569, 15574, 15579, 0, 0, - 15585, 15589, 15592, 15595, 15598, 15601, 15604, 15607, 15610, 15613, - 15616, 15620, 15625, 15630, 15636, 15642, 0, 0, 0, 15648, 15652, 15658, - 15664, 15670, 15675, 15681, 0, 0, 15687, 15691, 0, 15695, 15699, 15703, - 15707, 15711, 15715, 15719, 15723, 15727, 15731, 15735, 15739, 15743, - 15747, 15751, 15755, 15759, 15763, 0, 0, 0, 15767, 15773, 15779, 15785, - 15791, 15797, 15803, 15809, 15815, 15821, 15827, 15833, 15841, 15847, - 15853, 15859, 15865, 15871, 15877, 15883, 15889, 15895, 15901, 15907, 0, - 15913, 15919, 15925, 15931, 15937, 15943, 15947, 15953, 15957, 0, 15961, - 0, 0, 15967, 15971, 15977, 15983, 15989, 15993, 15999, 0, 0, 0, 16003, 0, - 0, 0, 0, 16007, 16012, 16019, 16026, 16033, 16040, 0, 16047, 0, 16054, - 16059, 16064, 16071, 16078, 16087, 16098, 16107, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16112, 16119, 16126, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 16131, 16137, 16143, 16149, 16155, 16161, 16167, 16173, - 16179, 16185, 16191, 16197, 16203, 16209, 16215, 16221, 16227, 16233, - 16239, 16245, 16251, 16257, 16263, 16269, 16275, 16281, 16287, 16293, - 16299, 16305, 16311, 16317, 16323, 16328, 16334, 16340, 16344, 16350, - 16354, 16360, 16366, 16372, 16378, 16384, 16390, 16395, 16401, 16405, - 16410, 16416, 16422, 16428, 16433, 16439, 16445, 16451, 16456, 16462, 0, - 0, 0, 0, 16466, 16472, 16477, 16483, 16488, 16496, 16504, 16508, 16512, - 16516, 16522, 16528, 16534, 16540, 16544, 16548, 16552, 16556, 16560, - 16563, 16566, 16569, 16572, 16575, 16578, 16581, 16584, 16587, 16591, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33057, 33065, 33073, 33081, 33089, 33099, + 33109, 33119, 0, 0, 0, 0, 0, 0, 0, 0, 33129, 33134, 33139, 33144, 33149, + 33158, 33169, 33178, 33189, 33195, 33208, 33214, 33221, 33228, 33233, + 33239, 33245, 33256, 33265, 33272, 33279, 33288, 33295, 33304, 33314, + 33324, 33331, 33338, 33345, 33355, 33360, 33368, 33374, 33382, 33391, + 33396, 33403, 33409, 33414, 0, 33419, 33425, 0, 0, 0, 0, 0, 0, 33432, + 33437, 33443, 33449, 33457, 33463, 33469, 33475, 33480, 33487, 33492, + 33498, 33504, 33512, 33518, 33526, 33531, 33538, 33544, 33552, 33560, + 33566, 33572, 33579, 33586, 33592, 33599, 33605, 33611, 33616, 33622, + 33630, 33638, 33644, 33650, 33656, 33662, 33670, 33674, 33680, 33686, + 33692, 33698, 33704, 33710, 33714, 33719, 33724, 33731, 33736, 33740, + 33746, 33751, 33756, 33760, 33765, 33770, 33774, 33779, 33784, 33791, + 33795, 33800, 33805, 33809, 33814, 33818, 33823, 33827, 33832, 33837, + 33843, 33848, 33853, 33857, 33862, 33868, 33875, 33880, 33885, 33890, + 33895, 33900, 33904, 33910, 33917, 33924, 33929, 33934, 33938, 33944, + 33950, 33955, 33960, 33965, 33971, 33976, 33982, 33987, 33993, 33999, + 34005, 34012, 34019, 34026, 34033, 34040, 34047, 34052, 34061, 34071, + 34081, 34091, 34101, 34111, 34121, 34134, 34144, 34154, 34164, 34170, + 34175, 34182, 34190, 34198, 34205, 34212, 34219, 34226, 34234, 34243, + 34252, 34261, 34270, 34279, 34288, 34297, 34306, 34315, 34324, 34333, + 34342, 34351, 34360, 34368, 34377, 34388, 34396, 34406, 34418, 34427, + 34436, 34446, 34455, 34463, 34472, 34478, 34483, 34491, 34496, 34504, + 34509, 34518, 34524, 34530, 34537, 34542, 34547, 34555, 34563, 34572, + 34581, 34586, 34593, 34603, 34611, 34620, 34626, 34632, 34637, 34644, + 34649, 34658, 34663, 34668, 34673, 34680, 34686, 34691, 34700, 34708, + 34713, 34718, 34725, 34732, 34736, 34740, 34743, 34746, 34749, 34752, + 34755, 34758, 34765, 34768, 34771, 34776, 34780, 34784, 34788, 34792, + 34796, 34806, 34812, 34818, 34824, 34832, 34840, 34846, 34852, 34859, + 34865, 34870, 34876, 34883, 34889, 34896, 34902, 34910, 34915, 34921, + 34927, 34933, 34939, 34945, 34951, 34957, 34969, 34979, 34985, 34991, + 35001, 35007, 35015, 35023, 35031, 0, 0, 0, 0, 0, 0, 35036, 35043, 35050, + 35055, 35064, 35072, 35080, 35087, 35094, 35101, 35108, 35116, 35124, + 35134, 35144, 35152, 35160, 35168, 35176, 35185, 35194, 35202, 35210, + 35219, 35228, 35238, 35248, 35257, 35266, 35274, 35282, 35290, 35298, + 35308, 35318, 35326, 35334, 35342, 35350, 35358, 35366, 35374, 35382, + 35390, 35398, 35406, 35414, 35423, 35432, 35441, 35450, 35460, 35470, + 35477, 35484, 35492, 35500, 35509, 35518, 35526, 35534, 35546, 35558, + 35567, 35576, 35585, 35594, 35601, 35608, 35616, 35624, 35632, 35640, + 35648, 35656, 35664, 35672, 35681, 35690, 35699, 35708, 35717, 35726, + 35736, 35746, 35756, 35766, 35775, 35784, 35791, 35798, 35806, 35814, + 35822, 35830, 35838, 35846, 35858, 35870, 35879, 35888, 35896, 35904, + 35912, 35920, 35931, 35942, 35953, 35964, 35976, 35988, 35996, 36004, + 36012, 36020, 36029, 36038, 36047, 36056, 36064, 36072, 36080, 36088, + 36096, 36104, 36113, 36122, 36132, 36142, 36150, 36158, 36166, 36174, + 36182, 36190, 36197, 36204, 36212, 36220, 36228, 36236, 36244, 36252, + 36260, 36268, 36276, 36284, 36292, 36300, 36308, 36316, 36324, 36332, + 36341, 36350, 36359, 36367, 36376, 36385, 36394, 36403, 36413, 36422, + 36428, 36433, 36440, 36447, 36455, 36463, 36472, 36481, 36491, 36501, + 36512, 36523, 36533, 36543, 36553, 36563, 36572, 36581, 36591, 36601, + 36612, 36623, 36633, 36643, 36653, 36663, 36670, 36677, 36685, 36693, + 36700, 36707, 36716, 36725, 36735, 36745, 36756, 36767, 36777, 36787, + 36797, 36807, 36816, 36825, 36833, 36841, 36848, 36855, 36863, 36871, + 36880, 36889, 36899, 36909, 36920, 36931, 36941, 36951, 36961, 36971, + 36980, 36989, 36999, 37009, 37020, 37031, 37041, 37051, 37061, 37071, + 37078, 37085, 37093, 37101, 37110, 37119, 37129, 37139, 37150, 37161, + 37171, 37181, 37191, 37201, 37209, 37217, 37225, 37233, 37242, 37251, + 37259, 37267, 37274, 37281, 37288, 37295, 37303, 37311, 37319, 37327, + 37338, 37349, 37360, 37371, 37382, 37393, 37401, 37409, 37420, 37431, + 37442, 37453, 37464, 37475, 37483, 37491, 37502, 37513, 37524, 0, 0, + 37535, 37543, 37551, 37562, 37573, 37584, 0, 0, 37595, 37603, 37611, + 37622, 37633, 37644, 37655, 37666, 37677, 37685, 37693, 37704, 37715, + 37726, 37737, 37748, 37759, 37767, 37775, 37786, 37797, 37808, 37819, + 37830, 37841, 37849, 37857, 37868, 37879, 37890, 37901, 37912, 37923, + 37931, 37939, 37950, 37961, 37972, 0, 0, 37983, 37991, 37999, 38010, + 38021, 38032, 0, 0, 38043, 38051, 38059, 38070, 38081, 38092, 38103, + 38114, 0, 38125, 0, 38133, 0, 38144, 0, 38155, 38166, 38174, 38182, + 38193, 38204, 38215, 38226, 38237, 38248, 38256, 38264, 38275, 38286, + 38297, 38308, 38319, 38330, 38338, 38346, 38354, 38362, 38370, 38378, + 38386, 38394, 38402, 38410, 38418, 38426, 38434, 0, 0, 38442, 38453, + 38464, 38478, 38492, 38506, 38520, 38534, 38548, 38559, 38570, 38584, + 38598, 38612, 38626, 38640, 38654, 38665, 38676, 38690, 38704, 38718, + 38732, 38746, 38760, 38771, 38782, 38796, 38810, 38824, 38838, 38852, + 38866, 38877, 38888, 38902, 38916, 38930, 38944, 38958, 38972, 38983, + 38994, 39008, 39022, 39036, 39050, 39064, 39078, 39086, 39094, 39105, + 39113, 0, 39124, 39132, 39143, 39151, 39159, 39167, 39175, 39183, 39186, + 39189, 39192, 39195, 39201, 39212, 39220, 0, 39231, 39239, 39250, 39258, + 39266, 39274, 39282, 39290, 39296, 39302, 39308, 39316, 39324, 39335, 0, + 0, 39346, 39354, 39365, 39373, 39381, 39389, 0, 39397, 39403, 39409, + 39415, 39423, 39431, 39442, 39453, 39461, 39469, 39477, 39488, 39496, + 39504, 39512, 39520, 39528, 39534, 39540, 0, 0, 39543, 39554, 39562, 0, + 39573, 39581, 39592, 39600, 39608, 39616, 39624, 39632, 39635, 0, 39638, + 39642, 39646, 39650, 39654, 39658, 39662, 39666, 39670, 39674, 39678, + 39682, 39688, 39694, 39700, 39703, 39706, 39708, 39712, 39716, 39720, + 39724, 39726, 39730, 39734, 39740, 39746, 39753, 39760, 39765, 39770, + 39776, 39782, 39784, 39787, 39789, 39793, 39797, 39801, 39804, 39808, + 39812, 39816, 39820, 39824, 39830, 39834, 39838, 39844, 39849, 39856, + 39858, 39861, 39865, 39869, 39874, 39880, 39882, 39891, 39900, 39903, + 39907, 39909, 39911, 39913, 39916, 39922, 39924, 39928, 39932, 39939, + 39946, 39950, 39955, 39960, 39965, 39970, 39974, 39978, 39981, 39985, + 39989, 39996, 40001, 40005, 40009, 40014, 40018, 40022, 40027, 40032, + 40036, 40040, 40044, 40046, 40051, 40056, 40060, 40064, 40068, 40072, 0, + 40076, 40080, 40084, 40090, 40096, 40102, 40108, 40115, 40122, 40127, + 40132, 40136, 0, 0, 40142, 40145, 40148, 40151, 40154, 40157, 40160, + 40164, 40168, 40173, 40178, 40183, 40190, 40194, 40197, 40200, 40203, + 40206, 40209, 40212, 40215, 40218, 40221, 40225, 40229, 40234, 40239, 0, + 40244, 40250, 40256, 40262, 40269, 40276, 40283, 40290, 40296, 40303, + 40310, 40317, 40323, 0, 0, 0, 40330, 40333, 40336, 40339, 40344, 40347, + 40350, 40353, 40356, 40359, 40362, 40366, 40369, 40372, 40375, 40378, + 40381, 40386, 40389, 40392, 40395, 40398, 40401, 40406, 40409, 40412, + 40417, 40422, 40426, 40429, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 40432, 40437, 40442, 40449, 40457, 40462, 40467, 40471, 40475, + 40480, 40487, 40494, 40498, 40503, 40508, 40513, 40518, 40525, 40530, + 40535, 40540, 40549, 40556, 40563, 40567, 40572, 40578, 40583, 40590, + 40598, 40606, 40610, 40614, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 40618, 40622, 40630, 40634, 40638, 40643, 40647, 40651, 40655, 40657, + 40661, 40665, 40669, 40674, 40678, 40682, 40690, 40693, 40697, 40700, + 40703, 40709, 40713, 40716, 40722, 40726, 40730, 40734, 40737, 40741, + 40744, 40748, 40750, 40753, 40756, 40760, 40762, 40766, 40769, 40772, + 40777, 40782, 40788, 40791, 40794, 40798, 40803, 40806, 40809, 40812, + 40816, 40820, 40824, 40827, 40829, 40832, 40835, 40838, 40842, 40847, + 40850, 40854, 40858, 40862, 40866, 40871, 40876, 40880, 40885, 40890, + 40895, 40900, 40904, 40908, 40913, 40917, 40920, 40923, 40925, 40929, + 40935, 40942, 40949, 40956, 40963, 40970, 40977, 40984, 40991, 40999, + 41006, 41014, 41021, 41028, 41036, 41044, 41049, 41054, 41059, 41064, + 41069, 41074, 41079, 41084, 41089, 41094, 41100, 41106, 41112, 41118, + 41125, 41133, 41140, 41146, 41152, 41158, 41164, 41170, 41176, 41182, + 41188, 41194, 41201, 41208, 41215, 41222, 41230, 41239, 41247, 41258, + 41266, 41274, 41283, 41290, 41299, 41308, 41316, 41325, 0, 0, 0, 0, 0, 0, + 41333, 41335, 41337, 41339, 41341, 41344, 41347, 41351, 41355, 41359, + 41363, 41367, 41371, 41375, 41379, 41384, 41389, 41394, 41399, 41404, + 41409, 41414, 41419, 41424, 41429, 41435, 41439, 41443, 41448, 41453, + 41458, 41463, 41467, 41474, 41481, 41488, 41495, 41502, 41509, 41516, + 41523, 41531, 41543, 41550, 41557, 41564, 41571, 41578, 41585, 41592, + 41599, 41606, 41613, 41618, 41624, 41629, 41634, 41639, 41644, 41649, + 41656, 41663, 41668, 41674, 41679, 41682, 41685, 41688, 41691, 41695, + 41699, 41704, 41709, 41714, 41719, 41723, 41727, 41731, 41735, 41740, + 41745, 41749, 41753, 41757, 41761, 41766, 41771, 41774, 41777, 41780, + 41783, 41789, 41796, 41806, 41816, 41820, 41828, 41835, 41843, 41851, + 41855, 41861, 41867, 41871, 41876, 41881, 41887, 41893, 41899, 41906, + 41910, 41914, 41919, 41922, 41924, 41928, 41932, 41940, 41944, 41946, + 41948, 41952, 41960, 41965, 41971, 41981, 41988, 41993, 41997, 42001, + 42005, 42008, 42011, 42014, 42018, 42022, 42026, 42030, 42034, 42037, + 42041, 42045, 42048, 42050, 42053, 42055, 42059, 42063, 42065, 42071, + 42074, 42079, 42083, 42087, 42089, 42091, 42093, 42096, 42100, 42104, + 42108, 42112, 42116, 42122, 42128, 42130, 42132, 42134, 42136, 42139, + 42141, 42145, 42147, 42151, 42155, 42160, 42164, 42168, 42172, 42176, + 42180, 42186, 42190, 42200, 42210, 42214, 42220, 42227, 42231, 42235, + 42238, 42243, 42247, 42253, 42257, 42270, 42279, 42283, 42287, 42293, + 42297, 42300, 42302, 42305, 42309, 42313, 42320, 42324, 42328, 42332, + 42335, 42340, 42345, 42351, 42357, 42362, 42367, 42375, 42383, 42387, + 42391, 42393, 42398, 42402, 42406, 42414, 42422, 42429, 42436, 42445, + 42454, 42460, 42466, 42474, 42482, 42484, 42486, 42492, 42498, 42505, + 42512, 42518, 42524, 42528, 42532, 42539, 42546, 42553, 42560, 42570, + 42580, 42588, 42596, 42598, 42602, 42606, 42611, 42616, 42624, 42632, + 42635, 42638, 42641, 42644, 42647, 42652, 42656, 42661, 42666, 42669, + 42672, 42675, 42678, 42681, 42685, 42688, 42691, 42694, 42697, 42699, + 42701, 42703, 42705, 42713, 42721, 42727, 42731, 42737, 42747, 42753, + 42759, 42765, 42773, 42782, 42794, 42798, 42802, 42804, 42810, 42812, + 42814, 42816, 42818, 42824, 42827, 42833, 42839, 42843, 42847, 42851, + 42854, 42858, 42862, 42864, 42873, 42882, 42887, 42892, 42898, 42904, + 42910, 42913, 42916, 42919, 42922, 42924, 42929, 42934, 42939, 42945, + 42951, 42960, 42969, 42976, 42983, 42990, 42997, 43007, 43017, 43027, + 43037, 43047, 43057, 43066, 43075, 43084, 43093, 43101, 43113, 43124, + 43140, 43143, 43148, 43154, 43160, 43167, 43181, 43196, 43202, 43208, + 43215, 43221, 43229, 43235, 43248, 43262, 43267, 43273, 43281, 43284, + 43287, 43289, 43292, 43295, 43297, 43299, 43303, 43306, 43309, 43312, + 43315, 43320, 43325, 43330, 43335, 43340, 43343, 43345, 43347, 43349, + 43353, 43357, 43361, 43367, 43371, 43373, 43375, 43380, 43385, 43390, + 43395, 43400, 43405, 43407, 43409, 43418, 43422, 43430, 43439, 43441, + 43446, 43451, 43459, 43463, 43465, 43469, 43471, 43475, 43479, 43483, + 43485, 43487, 43489, 43496, 43505, 43514, 43523, 43532, 43541, 43550, + 43559, 43568, 43576, 43584, 43593, 43602, 43611, 43620, 43628, 43636, + 43645, 43654, 43663, 43673, 43682, 43692, 43701, 43711, 43719, 43728, + 43738, 43747, 43757, 43766, 43776, 43784, 43793, 43802, 43811, 43820, + 43829, 43838, 43848, 43857, 43866, 43875, 43885, 43894, 43903, 43912, + 43921, 43931, 43941, 43950, 43959, 43967, 43976, 43983, 43992, 44001, + 44012, 44021, 44031, 44041, 44048, 44055, 44062, 44071, 44080, 44089, + 44098, 44105, 44110, 44118, 44124, 44127, 44135, 44138, 44143, 44148, + 44151, 44154, 44162, 44165, 44170, 44173, 44180, 44185, 44193, 44196, + 44199, 44202, 44207, 44212, 44215, 44218, 44226, 44229, 44236, 44243, + 44247, 44251, 44256, 44261, 44267, 44272, 44278, 44284, 44289, 44295, + 44303, 44309, 44317, 44325, 44331, 44339, 44347, 44356, 44364, 44370, + 44378, 44387, 44395, 44399, 44404, 44418, 44432, 44436, 44440, 44444, + 44448, 44458, 44462, 44467, 44472, 44477, 44482, 44487, 44492, 44502, + 44512, 44520, 44530, 44540, 44548, 44558, 44568, 44576, 44586, 44596, + 44604, 44612, 44622, 44632, 44635, 44638, 44641, 44646, 44650, 44656, + 44663, 44670, 44678, 44685, 44689, 44693, 44697, 44701, 44703, 44707, + 44711, 44716, 44721, 44728, 44735, 44738, 44745, 44747, 44749, 44753, + 44757, 44762, 44768, 44774, 44780, 44786, 44795, 44804, 44813, 44817, + 44819, 44823, 44830, 44837, 44844, 44851, 44858, 44861, 44866, 0, 0, 0, + 0, 0, 44872, 44876, 44883, 44890, 44897, 44904, 44908, 44912, 44916, + 44920, 44925, 44931, 44936, 44942, 44948, 44954, 44960, 44968, 44975, + 44982, 44989, 44996, 45001, 45007, 45016, 45020, 45027, 45031, 45035, + 45041, 45047, 45053, 45059, 45063, 45067, 45070, 45074, 45078, 45085, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16595, 16600, 0, 16607, 0, 0, 16614, - 16619, 0, 16624, 0, 0, 16631, 0, 0, 0, 0, 0, 0, 16636, 16641, 16645, - 16652, 0, 16659, 16664, 16669, 16674, 16681, 16688, 16695, 0, 16702, - 16707, 16712, 0, 16719, 0, 16726, 0, 0, 16731, 16738, 0, 16745, 16749, - 16756, 16760, 16765, 16773, 16779, 16785, 16790, 16796, 16802, 16808, - 16813, 0, 16819, 16827, 16834, 0, 0, 16841, 16846, 16852, 16857, 16863, - 0, 16869, 0, 16875, 16882, 16889, 16896, 16903, 16908, 0, 0, 16912, - 16917, 16921, 16925, 16929, 16933, 16937, 16941, 16945, 16949, 0, 0, - 16953, 16959, 16965, 16972, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16979, 16983, 16994, - 17009, 17024, 17034, 17045, 17058, 17069, 17075, 17083, 17093, 17099, - 17107, 17111, 17117, 17123, 17131, 17141, 17149, 17162, 17168, 17176, - 17184, 17196, 17203, 17211, 17219, 17227, 17235, 17243, 17251, 17261, - 17265, 17268, 17271, 17274, 17277, 17280, 17283, 17286, 17289, 17292, - 17296, 17300, 17304, 17308, 17312, 17316, 17320, 17324, 17328, 17333, - 17339, 17349, 17363, 17373, 17379, 17385, 17393, 17401, 17409, 17417, - 17423, 17429, 17432, 17436, 17440, 17444, 17448, 17452, 17456, 0, 17460, - 17464, 17468, 17472, 17476, 17480, 17484, 17488, 17492, 17496, 17500, - 17503, 17506, 17510, 17514, 17518, 17521, 17525, 17529, 17533, 17537, - 17541, 17545, 17549, 17553, 17556, 17559, 17563, 17567, 17571, 17574, - 17577, 17580, 17584, 17589, 17593, 0, 0, 0, 0, 17597, 17602, 17606, - 17611, 17615, 17620, 17625, 17631, 17636, 17642, 17646, 17651, 17655, - 17660, 17670, 17676, 17682, 17689, 17699, 17705, 17709, 17713, 17719, - 17725, 17733, 17739, 17747, 17755, 17763, 17773, 17781, 17791, 17796, - 17802, 17808, 17814, 17820, 17826, 17832, 0, 17838, 17844, 17850, 17856, - 17862, 17868, 17874, 17880, 17886, 17892, 17898, 17903, 17908, 17914, - 17920, 17926, 17931, 17937, 17943, 17949, 17955, 17961, 17967, 17973, - 17979, 17984, 17989, 17995, 18001, 18007, 18012, 18017, 18022, 18028, - 18036, 18043, 0, 18050, 18057, 18070, 18077, 18084, 18092, 18100, 18106, - 18112, 18118, 18128, 18133, 18139, 18149, 18159, 0, 18169, 18179, 18187, - 18199, 18211, 18217, 18231, 18246, 18251, 18256, 18264, 18272, 18280, 0, + 45092, 45095, 45099, 45103, 45109, 45115, 45121, 45129, 45136, 45140, + 45148, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 45153, 45156, 45159, 45162, 45165, 45168, 45171, 45174, 45177, 45180, + 45184, 45188, 45192, 45196, 45200, 45204, 45208, 45212, 45216, 45220, + 45224, 45227, 45230, 45233, 45236, 45239, 45242, 45245, 45248, 45251, + 45255, 45259, 45263, 45267, 45271, 45275, 45279, 45283, 45287, 45291, + 45295, 45301, 45307, 45313, 45320, 45327, 45334, 45341, 45348, 45355, + 45362, 45369, 45376, 45383, 45390, 45397, 45404, 45411, 45418, 45425, + 45432, 45437, 45443, 45449, 45455, 45460, 45466, 45472, 45478, 45483, + 45489, 45495, 45500, 45506, 45512, 45517, 45523, 45529, 45534, 45539, + 45545, 45550, 45556, 45562, 45568, 45574, 45580, 45585, 45591, 45597, + 45603, 45608, 45614, 45620, 45626, 45631, 45637, 45643, 45648, 45654, + 45660, 45665, 45671, 45677, 45682, 45687, 45693, 45698, 45704, 45710, + 45716, 45722, 45728, 45733, 45739, 45745, 45751, 45756, 45762, 45768, + 45774, 45779, 45785, 45791, 45796, 45802, 45808, 45813, 45819, 45825, + 45830, 45835, 45841, 45846, 45852, 45858, 45864, 45870, 45876, 45880, + 45885, 45890, 45895, 45900, 45905, 45910, 45915, 45920, 45925, 45930, + 45934, 45938, 45942, 45946, 45950, 45954, 45958, 45962, 45966, 45971, + 45976, 45981, 45986, 45991, 45996, 46005, 46014, 46023, 46032, 46041, + 46050, 46059, 46068, 46075, 46083, 46091, 46098, 46105, 46113, 46121, + 46128, 46135, 46143, 46151, 46158, 46165, 46173, 46181, 46188, 46195, + 46203, 46212, 46221, 46229, 46238, 46247, 46254, 46261, 46269, 46278, + 46287, 46295, 46304, 46313, 46320, 46327, 46336, 46345, 46353, 46361, + 46370, 46379, 46386, 46393, 46402, 46411, 46419, 46427, 46436, 46445, + 46452, 46459, 46468, 46477, 46485, 46494, 46503, 46511, 46521, 46531, + 46541, 46551, 46560, 46569, 46578, 46587, 46594, 46602, 46610, 46618, + 46626, 46631, 46636, 46645, 46653, 46660, 46669, 46677, 46684, 46693, + 46701, 46708, 46717, 46725, 46732, 46741, 46749, 46756, 46765, 46773, + 46780, 46789, 46797, 46804, 46813, 46821, 46828, 46837, 46845, 46852, + 46861, 46870, 46879, 46888, 46902, 46916, 46923, 46928, 46933, 46938, + 46943, 46948, 46953, 46958, 46963, 46971, 46979, 46987, 46995, 47000, + 47007, 47014, 47021, 47026, 47034, 47041, 47049, 47053, 47060, 47066, + 47073, 47077, 47083, 47089, 47095, 47099, 47102, 47106, 47110, 47117, + 47123, 47129, 47135, 47141, 47155, 47165, 47179, 47193, 47199, 47209, + 47223, 47226, 47229, 47236, 47244, 47249, 47254, 47262, 47274, 47286, + 47294, 47298, 47302, 47305, 47308, 47312, 47316, 47319, 47322, 47327, + 47332, 47338, 47344, 47349, 47354, 47360, 47366, 47371, 47376, 47381, + 47386, 47392, 47398, 47403, 47408, 47414, 47420, 47425, 47430, 47433, + 47436, 47445, 47447, 47449, 47452, 47456, 47462, 47464, 47467, 47474, + 47481, 47489, 47497, 47507, 47521, 47526, 47531, 47535, 47540, 47548, + 47556, 47565, 47574, 47583, 47592, 47597, 47602, 47608, 47614, 47620, + 47626, 47629, 47635, 47641, 47651, 47661, 47669, 47677, 47686, 47695, + 47699, 47707, 47715, 47723, 47731, 47740, 47749, 47758, 47767, 47772, + 47777, 47782, 47787, 47792, 47798, 47804, 47809, 47815, 47817, 47819, + 47821, 47823, 47826, 47829, 47831, 47833, 47835, 47839, 47843, 47845, + 47847, 47850, 47853, 47857, 47863, 47869, 47871, 47878, 47882, 47887, + 47892, 47894, 47904, 47910, 47916, 47922, 47928, 47934, 47940, 47945, + 47948, 47951, 47954, 47956, 47958, 47962, 47966, 47971, 47976, 47981, + 47984, 47988, 47993, 47996, 48000, 48005, 48010, 48015, 48020, 48025, + 48030, 48035, 48040, 48045, 48050, 48055, 48060, 48066, 48072, 48078, + 48080, 48083, 48085, 48088, 48090, 48092, 48094, 48096, 48098, 48100, + 48102, 48104, 48106, 48108, 48110, 48112, 48114, 48116, 48118, 48120, + 48122, 48127, 48132, 48137, 48142, 48147, 48152, 48157, 48162, 48167, + 48172, 48177, 48182, 48187, 48192, 48197, 48202, 48207, 48212, 48217, + 48222, 48226, 48230, 48234, 48240, 48246, 48251, 48256, 48261, 48267, + 48273, 48278, 48286, 48294, 48302, 48310, 48318, 48326, 48334, 48342, + 48348, 48353, 48358, 48363, 48366, 48370, 48374, 48378, 48382, 48386, + 48390, 48397, 48404, 48412, 48420, 48425, 48430, 48437, 48444, 48451, + 48458, 48461, 48464, 48469, 48471, 48475, 48480, 48482, 48484, 48486, + 48488, 48493, 48496, 48498, 48503, 48510, 48517, 48520, 48524, 48529, + 48534, 48542, 48548, 48554, 48566, 48573, 48580, 48585, 48590, 48596, + 48599, 48602, 48607, 48609, 48613, 48615, 48617, 48619, 48621, 48623, + 48625, 48630, 48632, 48634, 48636, 48638, 48642, 48644, 48647, 48652, + 48657, 48662, 48667, 48673, 48679, 48681, 48684, 48691, 48697, 48703, + 48710, 48714, 48718, 48720, 48722, 48726, 48732, 48737, 48739, 48743, + 48752, 48760, 48768, 48774, 48780, 48785, 48791, 48796, 48799, 48813, + 48816, 48821, 48826, 48832, 48842, 48844, 48850, 48856, 48860, 48867, + 48871, 48873, 48875, 48879, 48885, 48890, 48896, 48898, 48904, 48906, + 48912, 48914, 48916, 48921, 48923, 48927, 48932, 48934, 48939, 48944, + 48948, 48955, 48965, 48970, 48976, 48979, 48985, 48988, 48993, 48998, + 49002, 49004, 49006, 49010, 49014, 49018, 49022, 49027, 49029, 49034, + 49037, 49040, 49043, 49047, 49051, 49056, 49060, 49065, 49070, 49074, + 49080, 49087, 49090, 49096, 49101, 49105, 49110, 49116, 49122, 49129, + 49135, 49142, 49149, 49151, 49158, 49162, 49169, 49175, 49180, 49186, + 49190, 49195, 49198, 49204, 49210, 49217, 49225, 49232, 49241, 49251, + 49258, 49264, 49268, 49276, 49281, 49290, 49293, 49296, 49305, 49316, + 49323, 49325, 49331, 49336, 49338, 49341, 49345, 49353, 49362, 49365, + 49370, 49375, 49383, 49391, 49399, 49407, 49413, 49419, 49425, 49433, + 49438, 49441, 49445, 49448, 49459, 49469, 49479, 49488, 49499, 49509, + 49518, 49524, 49532, 49536, 49544, 49548, 49556, 49563, 49570, 49579, + 49588, 49598, 49608, 49618, 49628, 49637, 49646, 49656, 49666, 49675, + 49684, 49690, 49696, 49702, 49708, 49714, 49720, 49726, 49732, 49738, + 49745, 49751, 49757, 49763, 49769, 49775, 49781, 49787, 49793, 49799, + 49806, 49813, 49820, 49827, 49834, 49841, 49848, 49855, 49862, 49869, + 49877, 49882, 49885, 49889, 49893, 49898, 49901, 49906, 49912, 49917, + 49921, 49926, 49932, 49939, 49942, 49949, 49956, 49960, 49968, 49976, + 49981, 49987, 49992, 49997, 50004, 50011, 50019, 50027, 50036, 50040, + 50049, 50054, 50058, 50064, 50068, 50074, 50081, 50086, 50093, 50097, + 50102, 50106, 50111, 50115, 50120, 50125, 50134, 50136, 50140, 50144, + 50151, 50158, 50164, 50172, 50178, 50184, 50189, 50192, 50197, 50202, + 50207, 50215, 50219, 50226, 50234, 50242, 50247, 50252, 50258, 50263, + 50268, 50274, 50279, 50282, 50286, 50290, 50297, 50306, 50311, 50320, + 50329, 50335, 50341, 50346, 50351, 50356, 50361, 50367, 50373, 50381, + 50389, 50395, 50401, 50405, 50409, 50416, 50423, 50429, 50432, 50435, + 50439, 50443, 50447, 50452, 50458, 50464, 50471, 50478, 50483, 50487, + 50491, 50495, 50499, 50503, 50507, 50511, 50515, 50519, 50523, 50527, + 50531, 50535, 50539, 50543, 50547, 50551, 50555, 50559, 50563, 50567, + 50571, 50575, 50579, 50583, 50587, 50591, 50595, 50599, 50603, 50607, + 50611, 50615, 50619, 50623, 50627, 50631, 50635, 50639, 50643, 50647, + 50651, 50655, 50659, 50663, 50667, 50671, 50675, 50679, 50683, 50687, + 50691, 50695, 50699, 50703, 50707, 50711, 50715, 50719, 50723, 50727, + 50731, 50735, 50739, 50743, 50747, 50751, 50755, 50759, 50763, 50767, + 50771, 50775, 50779, 50783, 50787, 50791, 50795, 50799, 50803, 50807, + 50811, 50815, 50819, 50823, 50827, 50831, 50835, 50839, 50843, 50847, + 50851, 50855, 50859, 50863, 50867, 50871, 50875, 50879, 50883, 50887, + 50891, 50895, 50899, 50903, 50907, 50911, 50915, 50919, 50923, 50927, + 50931, 50935, 50939, 50943, 50947, 50951, 50955, 50959, 50963, 50967, + 50971, 50975, 50979, 50983, 50987, 50991, 50995, 50999, 51003, 51007, + 51011, 51015, 51019, 51023, 51027, 51031, 51035, 51039, 51043, 51047, + 51051, 51055, 51059, 51063, 51067, 51071, 51075, 51079, 51083, 51087, + 51091, 51095, 51099, 51103, 51107, 51111, 51115, 51119, 51123, 51127, + 51131, 51135, 51139, 51143, 51147, 51151, 51155, 51159, 51163, 51167, + 51171, 51175, 51179, 51183, 51187, 51191, 51195, 51199, 51203, 51207, + 51211, 51215, 51219, 51223, 51227, 51231, 51235, 51239, 51243, 51247, + 51251, 51255, 51259, 51263, 51267, 51271, 51275, 51279, 51283, 51287, + 51291, 51295, 51299, 51303, 51307, 51311, 51315, 51319, 51323, 51327, + 51331, 51335, 51339, 51343, 51347, 51351, 51355, 51359, 51363, 51367, + 51371, 51375, 51379, 51383, 51387, 51391, 51395, 51399, 51403, 51407, + 51411, 51415, 51419, 51423, 51427, 51431, 51435, 51439, 51443, 51447, + 51451, 51455, 51459, 51463, 51467, 51471, 51475, 51479, 51483, 51487, + 51491, 51495, 51499, 51503, 51507, 51514, 51522, 51528, 51534, 51541, + 51548, 51554, 51560, 51565, 51570, 51574, 51578, 51583, 51588, 51594, + 51600, 51608, 51615, 51620, 51625, 51633, 51642, 51649, 51659, 51670, + 51673, 51676, 51680, 51684, 51691, 51698, 51709, 51720, 51728, 51736, + 51742, 51748, 51754, 51760, 51769, 51778, 51787, 51796, 51806, 51816, + 51826, 51836, 51846, 51856, 51866, 51876, 51885, 51895, 51905, 51915, + 51925, 51932, 51939, 51946, 51953, 51963, 51973, 51981, 51989, 51996, + 52003, 52010, 52017, 52024, 52029, 52034, 52040, 52048, 52057, 52065, + 52073, 52081, 52089, 52097, 52105, 52113, 52121, 52130, 52139, 52148, + 52157, 52166, 52175, 52184, 52193, 52202, 52211, 52220, 52229, 52238, + 52247, 52256, 52265, 52279, 52294, 52308, 52323, 52337, 52351, 52365, + 52379, 52389, 52400, 52410, 52421, 52436, 52451, 52459, 52465, 52472, + 52479, 52486, 52493, 52498, 52504, 52509, 52514, 52520, 52525, 52530, + 52535, 52540, 52545, 52552, 52558, 52566, 52571, 52576, 52580, 52584, + 52592, 52600, 52608, 52616, 52623, 52630, 52643, 52656, 52669, 52682, + 52690, 52698, 52704, 52710, 52717, 52724, 52731, 52738, 52742, 52747, + 52755, 52763, 52771, 52778, 52782, 52790, 52798, 52801, 52805, 52810, + 52817, 52825, 52833, 52853, 52873, 52893, 52913, 52933, 52953, 52973, + 52993, 52999, 53006, 53015, 53023, 53031, 53036, 53039, 53042, 53047, + 53050, 53069, 53076, 53082, 53088, 53092, 53095, 53098, 53101, 53113, + 53126, 53133, 53140, 53143, 53147, 53150, 53155, 53160, 53165, 53171, + 53180, 53187, 53194, 53202, 53209, 53216, 53219, 53225, 53231, 53234, + 53237, 53242, 53247, 53253, 53259, 53263, 53268, 53275, 53279, 53285, + 53289, 53293, 53301, 53313, 53322, 53326, 53328, 53337, 53346, 53352, + 53355, 53361, 53367, 53372, 53377, 53382, 53387, 53392, 53397, 53399, + 53405, 53410, 53417, 53421, 53427, 53430, 53434, 53441, 53448, 53450, + 53452, 53458, 53464, 53470, 53479, 53488, 53495, 53502, 53508, 53515, + 53520, 53525, 53530, 53536, 53542, 53547, 53554, 53558, 53562, 53575, + 53588, 53600, 53609, 53615, 53622, 53627, 53632, 53637, 53642, 53647, + 53649, 53656, 53664, 53672, 53680, 53687, 53695, 53701, 53706, 53712, + 53718, 53724, 53731, 53737, 53745, 53753, 53761, 53769, 53777, 53783, + 53789, 53798, 53802, 53811, 53820, 53829, 53837, 53841, 53847, 53854, + 53861, 53865, 53871, 53879, 53885, 53890, 53896, 53901, 53906, 53913, + 53920, 53925, 53930, 53938, 53946, 53956, 53966, 53973, 53980, 53984, + 53988, 54000, 54006, 54013, 54018, 54023, 54030, 54037, 54043, 54049, + 54059, 54067, 54076, 54083, 54091, 54098, 54104, 54111, 54117, 54125, + 54133, 54141, 54149, 54155, 54160, 54169, 54179, 54186, 54195, 54201, + 54206, 54211, 54221, 54228, 54234, 54240, 54248, 54253, 54260, 54267, + 54278, 54285, 54292, 54299, 54306, 54313, 54321, 54329, 54342, 54355, + 54367, 54379, 54393, 54407, 54413, 54419, 54428, 54437, 54444, 54451, + 54460, 54469, 54478, 54487, 54495, 54503, 54513, 54523, 54537, 54551, + 54560, 54569, 54582, 54595, 54604, 54613, 54624, 54635, 54641, 54647, + 54656, 54665, 54670, 54675, 54683, 54689, 54695, 54703, 54711, 54724, + 54737, 54741, 54745, 54753, 54761, 54768, 54776, 54784, 54793, 54802, + 54808, 54814, 54821, 54828, 54835, 54842, 54851, 54860, 54863, 54866, + 54871, 54876, 54882, 54888, 54895, 54902, 54913, 54924, 54931, 54938, + 54946, 54954, 54962, 54970, 54978, 54986, 54993, 55000, 55004, 55008, + 55016, 55024, 55029, 55034, 55039, 55044, 55050, 55064, 55071, 55078, + 55082, 55084, 55086, 55091, 55096, 55101, 55105, 55113, 55120, 55127, + 55135, 55147, 55155, 55163, 55174, 55178, 55182, 55188, 55196, 55209, + 55216, 55223, 55230, 55235, 55242, 55251, 55259, 55265, 55271, 55277, + 55287, 55297, 55305, 55314, 55319, 55322, 55327, 55332, 55337, 55342, + 55347, 55351, 55354, 55357, 55360, 55365, 55370, 55375, 55380, 55384, + 55388, 55395, 55402, 55409, 55416, 55423, 55430, 55440, 55450, 55457, + 55464, 55472, 55480, 55484, 55489, 55494, 55500, 55506, 55509, 55512, + 55515, 55518, 55522, 55527, 55532, 55537, 55542, 55547, 55551, 55555, + 55559, 55563, 55567, 55571, 55575, 55581, 55585, 55591, 55596, 55603, + 55611, 55618, 55626, 55633, 55641, 55650, 55657, 55667, 55678, 55684, + 55693, 55699, 55708, 55717, 55723, 55729, 55733, 55737, 55746, 55755, + 55762, 55769, 55778, 55787, 55793, 55799, 55805, 55810, 55814, 55818, + 55823, 55828, 55833, 55841, 55849, 55852, 55856, 55865, 55874, 55882, + 55890, 55901, 55914, 55918, 55922, 55926, 55930, 55935, 55940, 55946, + 55952, 55958, 55964, 55970, 55976, 55982, 55988, 55997, 56006, 56013, + 56020, 56027, 0, 0, 56034, 56043, 56052, 56061, 56070, 56078, 56086, + 56094, 56102, 56107, 56112, 56121, 56131, 56140, 56150, 56157, 56164, + 56171, 56178, 56183, 56188, 56193, 56198, 56206, 56215, 56223, 56232, + 56236, 56240, 56244, 56248, 56258, 0, 0, 56261, 56270, 56279, 56288, + 56297, 56303, 56309, 56315, 56321, 56331, 56341, 56351, 56361, 56371, + 56381, 56391, 56401, 56408, 56415, 56422, 56429, 56436, 56443, 56450, + 56457, 56463, 56469, 56475, 56481, 56487, 56493, 56499, 56505, 56515, 0, + 0, 0, 56525, 56532, 56535, 56539, 56543, 56548, 56552, 56556, 56559, + 56568, 56577, 56586, 0, 56595, 56601, 56607, 56615, 56625, 56632, 56641, + 56646, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 56649, 56654, 56659, 56664, 56669, 56674, 56679, 56684, 56689, 56694, + 56699, 56705, 56709, 56714, 56719, 56724, 56729, 56734, 56739, 56744, + 56749, 56754, 56759, 56764, 56769, 56774, 56779, 56784, 56789, 56794, + 56799, 56804, 56809, 56814, 56819, 56825, 56830, 56836, 56845, 56850, + 56858, 56865, 56874, 56879, 56884, 56889, 56895, 0, 56902, 56907, 56912, + 56917, 56922, 56927, 56932, 56937, 56942, 56947, 56952, 56958, 56962, + 56967, 56972, 56977, 56982, 56987, 56992, 56997, 57002, 57007, 57012, + 57017, 57022, 57027, 57032, 57037, 57042, 57047, 57052, 57057, 57062, + 57067, 57072, 57078, 57083, 57089, 57098, 57103, 57111, 57118, 57127, + 57132, 57137, 57142, 57148, 0, 57155, 57163, 57171, 57181, 57188, 57196, + 57202, 57211, 57219, 57227, 57235, 57243, 57251, 57259, 57264, 57271, + 57276, 57282, 57290, 57297, 57304, 57312, 57318, 57324, 57331, 57338, + 57347, 57357, 57363, 57370, 57375, 57385, 57395, 57400, 57405, 57410, + 57415, 57420, 57425, 57430, 57435, 57440, 57445, 57450, 57455, 57460, + 57465, 57470, 57475, 57480, 57485, 57490, 57495, 57500, 57505, 57510, + 57515, 57520, 57525, 57530, 57535, 57540, 57545, 57549, 57553, 57558, + 57563, 57568, 57573, 57578, 57583, 57588, 57593, 57598, 57603, 57608, + 57613, 57618, 57623, 57628, 57633, 57638, 57643, 57650, 57657, 57664, + 57671, 57678, 57685, 57692, 57699, 57706, 57713, 57720, 57727, 57734, + 57741, 57746, 57751, 57758, 57765, 57772, 57779, 57786, 57793, 57800, + 57807, 57814, 57821, 57828, 57835, 57841, 57847, 57853, 57859, 57866, + 57873, 57880, 57887, 57894, 57901, 57908, 57915, 57922, 57929, 57937, + 57945, 57953, 57961, 57969, 57977, 57985, 57993, 57997, 58003, 58009, + 58013, 58019, 58025, 58031, 58038, 58045, 58052, 58059, 58064, 58070, + 58076, 58083, 0, 0, 0, 0, 0, 58090, 58098, 58107, 58116, 58124, 58130, + 58135, 58140, 58145, 58150, 58155, 58160, 58165, 58170, 58175, 58180, + 58185, 58190, 58195, 58200, 58205, 58210, 58215, 58220, 58225, 58230, + 58235, 58240, 58245, 58250, 58255, 58260, 58265, 58270, 58275, 58280, + 58285, 58290, 58295, 58300, 58305, 58310, 58315, 58320, 58325, 0, 58330, + 0, 0, 0, 0, 0, 58335, 0, 0, 58340, 58344, 58349, 58354, 58359, 58364, + 58373, 58378, 58383, 58388, 58393, 58398, 58403, 58408, 58413, 58420, + 58425, 58430, 58439, 58446, 58451, 58456, 58461, 58468, 58473, 58480, + 58485, 58490, 58497, 58504, 58509, 58514, 58519, 58526, 58533, 58538, + 58543, 58548, 58553, 58558, 58565, 58572, 58577, 58582, 58587, 58592, + 58597, 58602, 58607, 58612, 58617, 58622, 58627, 58634, 58639, 58644, 0, + 0, 0, 0, 0, 0, 0, 58649, 58656, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 58661, 58666, 58670, 58674, 58678, 58682, 58686, 58690, 58694, 58698, + 58702, 58706, 58712, 58716, 58720, 58724, 58728, 58732, 58736, 58740, + 58744, 58748, 58752, 58756, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58760, 58764, + 58768, 58772, 58776, 58780, 58784, 0, 58788, 58792, 58796, 58800, 58804, + 58808, 58812, 0, 58816, 58820, 58824, 58828, 58832, 58836, 58840, 0, + 58844, 58848, 58852, 58856, 58860, 58864, 58868, 0, 58872, 58876, 58880, + 58884, 58888, 58892, 58896, 0, 58900, 58904, 58908, 58912, 58916, 58920, + 58924, 0, 58928, 58932, 58936, 58940, 58944, 58948, 58952, 0, 58956, + 58960, 58964, 58968, 58972, 58976, 58980, 0, 58984, 58989, 58994, 58999, + 59004, 59009, 59014, 59018, 59023, 59028, 59033, 59037, 59042, 59047, + 59052, 59057, 59061, 59066, 59071, 59076, 59081, 59086, 59091, 59095, + 59100, 59105, 59112, 59117, 59122, 59128, 59135, 59142, 59151, 59158, + 59167, 59171, 59175, 59181, 59187, 59193, 59201, 59207, 59211, 59215, + 59219, 59225, 59231, 59235, 59237, 59241, 59247, 59249, 59253, 59256, + 59259, 59265, 59270, 59274, 59278, 59283, 59289, 59294, 59299, 59304, + 59309, 59316, 59323, 59328, 59333, 59338, 59343, 59348, 59353, 59357, + 59361, 59368, 59375, 59381, 59385, 59390, 59393, 59397, 59405, 59408, + 59412, 59416, 59419, 59425, 59431, 59434, 59440, 59444, 59448, 59454, + 59459, 59464, 59466, 59469, 59473, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 59479, 59483, 59487, 59492, 59497, 59502, 59506, 59510, 59514, 59519, + 59524, 59528, 59532, 59536, 59540, 59545, 59550, 59555, 59560, 59564, + 59568, 59573, 59578, 59583, 59588, 59592, 0, 59596, 59600, 59604, 59608, + 59612, 59616, 59620, 59625, 59630, 59634, 59639, 59644, 59653, 59657, + 59661, 59665, 59672, 59676, 59681, 59686, 59690, 59694, 59700, 59705, + 59710, 59715, 59720, 59724, 59728, 59732, 59736, 59740, 59745, 59750, + 59754, 59758, 59763, 59768, 59773, 59777, 59781, 59786, 59791, 59797, + 59803, 59807, 59813, 59819, 59823, 59829, 59835, 59840, 59845, 59849, + 59855, 59859, 59863, 59869, 59875, 59880, 59885, 59889, 59893, 59901, + 59907, 59913, 59919, 59924, 59929, 59934, 59940, 59944, 59950, 59954, + 59958, 59964, 59970, 59976, 59982, 59988, 59994, 60000, 60006, 60012, + 60018, 60024, 60030, 60034, 60040, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 60046, 60049, 60053, 60057, 60061, 60065, 60068, 60071, 60075, 60079, + 60083, 60087, 60090, 60095, 60099, 60103, 60107, 60113, 60117, 60121, + 60125, 60129, 60136, 60142, 60146, 60150, 60154, 60158, 60162, 60166, + 60170, 60174, 60178, 60182, 60186, 60192, 60196, 60200, 60204, 60208, + 60212, 60216, 60220, 60224, 60228, 60232, 60236, 60240, 60244, 60248, + 60252, 60256, 60262, 60268, 60273, 60278, 60282, 60286, 60290, 60294, + 60298, 60302, 60306, 60310, 60314, 60318, 60322, 60326, 60330, 60334, + 60338, 60342, 60346, 60350, 60354, 60358, 60362, 60366, 60370, 60374, + 60380, 60384, 60388, 60392, 60396, 60400, 60404, 60408, 60412, 60417, + 60424, 60428, 60432, 60436, 60440, 60444, 60448, 60452, 60456, 60460, + 60464, 60468, 60472, 60479, 60483, 60489, 60493, 60497, 60501, 60505, + 60509, 60512, 60516, 60520, 60524, 60528, 60532, 60536, 60540, 60544, + 60548, 60552, 60556, 60560, 60564, 60568, 60572, 60576, 60580, 60584, + 60588, 60592, 60596, 60600, 60604, 60608, 60612, 60616, 60620, 60624, + 60628, 60632, 60636, 60640, 60646, 60650, 60654, 60658, 60662, 60666, + 60670, 60674, 60678, 60682, 60686, 60690, 60694, 60698, 60702, 60706, + 60710, 60714, 60718, 60722, 60726, 60730, 60734, 60738, 60742, 60746, + 60750, 60754, 60762, 60766, 60770, 60774, 60778, 60782, 60788, 60792, + 60796, 60800, 60804, 60808, 60812, 60816, 60820, 60824, 60828, 60832, + 60836, 60840, 60846, 60850, 60854, 60858, 60862, 60866, 60870, 60874, + 60878, 60882, 60886, 60890, 60894, 60898, 60902, 60906, 60910, 60914, + 60918, 60922, 60926, 60930, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60934, 60943, 60951, 60963, 60974, + 60982, 60991, 61000, 61010, 61022, 61034, 61046, 0, 0, 0, 0, 61052, + 61055, 61058, 61063, 61066, 61073, 61077, 61081, 61085, 61089, 61093, + 61098, 61103, 61107, 61111, 61116, 61121, 61126, 61131, 61134, 61137, + 61143, 61149, 61154, 61159, 61166, 61173, 61177, 61181, 61185, 61193, + 61199, 61206, 61211, 61216, 61221, 61226, 61231, 61236, 61241, 61246, + 61251, 61256, 61261, 61266, 61271, 61276, 61282, 61287, 61291, 61297, + 61308, 61318, 61333, 61343, 61347, 61357, 61363, 61369, 61375, 61380, + 61383, 61388, 61392, 0, 61398, 61402, 61405, 61409, 61412, 61416, 61419, + 61423, 61426, 61430, 61433, 61436, 61440, 61444, 61448, 61452, 61456, + 61460, 61464, 61468, 61472, 61476, 61480, 61484, 61488, 61492, 61496, + 61500, 61504, 61508, 61512, 61516, 61520, 61524, 61528, 61533, 61537, + 61541, 61545, 61549, 61552, 61556, 61559, 61563, 61567, 61571, 61575, + 61578, 61582, 61585, 61589, 61593, 61597, 61601, 61605, 61609, 61613, + 61617, 61621, 61625, 61629, 61633, 61636, 61640, 61644, 61648, 61652, + 61656, 61659, 61664, 61668, 61673, 61677, 61681, 61685, 61689, 61693, + 61697, 61702, 61706, 61710, 61714, 61718, 61722, 61726, 61730, 0, 0, + 61735, 61743, 61751, 61758, 61765, 61769, 61775, 61780, 61785, 61789, + 61792, 61796, 61799, 61803, 61806, 61810, 61813, 61817, 61820, 61823, + 61827, 61831, 61835, 61839, 61843, 61847, 61851, 61855, 61859, 61863, + 61867, 61871, 61875, 61879, 61883, 61887, 61891, 61895, 61899, 61903, + 61907, 61911, 61915, 61920, 61924, 61928, 61932, 61936, 61939, 61943, + 61946, 61950, 61954, 61958, 61962, 61965, 61969, 61972, 61976, 61980, + 61984, 61988, 61992, 61996, 62000, 62004, 62008, 62012, 62016, 62020, + 62023, 62027, 62031, 62035, 62039, 62043, 62046, 62051, 62055, 62060, + 62064, 62068, 62072, 62076, 62080, 62084, 62089, 62093, 62097, 62101, + 62105, 62109, 62113, 62117, 62122, 62126, 62130, 62134, 62138, 62143, + 62150, 62154, 62160, 0, 0, 0, 0, 0, 62165, 62170, 62175, 62180, 62185, + 62190, 62195, 62200, 62204, 62209, 62214, 62219, 62224, 62229, 62234, + 62239, 62244, 62249, 62253, 62258, 62263, 62267, 62271, 62275, 62279, + 62284, 62289, 62294, 62299, 62304, 62309, 62314, 62319, 62324, 62329, + 62333, 62337, 62342, 62347, 62352, 62357, 0, 0, 0, 62362, 62366, 62370, + 62374, 62378, 62382, 62386, 62390, 62394, 62398, 62402, 62406, 62410, + 62414, 62418, 62422, 62426, 62430, 62434, 62438, 62442, 62446, 62450, + 62454, 62458, 62462, 62466, 62470, 62474, 62478, 62482, 62485, 62489, + 62492, 62496, 62500, 62503, 62507, 62511, 62514, 62518, 62522, 62526, + 62530, 62533, 62537, 62541, 62545, 62549, 62553, 62557, 62560, 62563, + 62567, 62571, 62575, 62579, 62583, 62587, 62591, 62595, 62599, 62603, + 62607, 62611, 62615, 62619, 62623, 62627, 62631, 62635, 62639, 62643, + 62647, 62651, 62655, 62659, 62663, 62667, 62671, 62675, 62679, 62683, + 62687, 62691, 62695, 62699, 62703, 62707, 62711, 62715, 62719, 62723, + 62727, 0, 62731, 62737, 62743, 62748, 62753, 62758, 62764, 62770, 62776, + 62782, 62788, 62794, 62800, 62806, 62812, 62818, 62824, 62829, 62834, + 62839, 62844, 62849, 62854, 62859, 62864, 62869, 62874, 62879, 62884, + 62889, 62894, 62899, 62904, 62909, 62914, 62919, 62924, 62930, 62936, + 62942, 62948, 62953, 62958, 0, 0, 0, 0, 0, 62963, 62968, 62973, 62978, + 62983, 62988, 62993, 62998, 63003, 63008, 63013, 63018, 63023, 63028, + 63033, 63038, 63043, 63048, 63052, 63057, 63062, 63067, 63072, 63077, + 63082, 63087, 63092, 63097, 63102, 63107, 63112, 63117, 63122, 63127, + 63132, 63137, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63142, 63147, 63152, + 63157, 63161, 63166, 63170, 63175, 63180, 63185, 63190, 63195, 63200, + 63205, 63210, 63215, 63220, 63224, 63228, 63232, 63236, 63240, 63244, + 63248, 63252, 63256, 63260, 63264, 63268, 63272, 63276, 63281, 63286, + 63291, 63296, 63301, 63306, 63311, 63316, 63321, 63326, 63331, 63336, + 63341, 63346, 63351, 63357, 0, 63364, 63367, 63370, 63373, 63376, 63379, + 63382, 63385, 63388, 63391, 63395, 63399, 63403, 63407, 63411, 63415, + 63419, 63423, 63427, 63431, 63435, 63439, 63443, 63447, 63451, 63455, + 63459, 63463, 63467, 63471, 63475, 63479, 63483, 63487, 63491, 63495, + 63499, 63503, 63507, 63511, 63515, 63524, 63533, 63542, 63551, 63560, + 63569, 63578, 63587, 63590, 63595, 63600, 63605, 63610, 63615, 63620, + 63625, 63630, 63635, 63639, 63644, 63649, 63654, 63659, 63664, 63668, + 63672, 63676, 63680, 63684, 63688, 63692, 63696, 63700, 63704, 63708, + 63712, 63716, 63720, 63725, 63730, 63735, 63740, 63745, 63750, 63755, + 63760, 63765, 63770, 63775, 63780, 63785, 63790, 63796, 63802, 63807, + 63812, 63815, 63818, 63821, 63824, 63827, 63830, 63833, 63836, 63839, + 63843, 63847, 63851, 63855, 63859, 63863, 63867, 63871, 63875, 63879, + 63883, 63887, 63891, 63895, 63899, 63903, 63907, 63911, 63915, 63919, + 63923, 63927, 63931, 63935, 63939, 63943, 63947, 63951, 63955, 63959, + 63963, 63967, 63971, 63975, 63979, 63983, 63987, 63991, 63995, 63999, + 64004, 64009, 64014, 64019, 64023, 64028, 64033, 64038, 64043, 64048, + 64053, 64058, 64063, 64068, 64072, 64079, 64086, 64093, 64100, 64107, + 64114, 64121, 64128, 64135, 64142, 64149, 64156, 64159, 64162, 64165, + 64170, 64173, 64176, 64179, 64182, 64185, 64188, 64192, 64196, 64200, + 64204, 64208, 64212, 64216, 64220, 64224, 64228, 64232, 64236, 64240, + 64243, 64246, 64250, 64254, 64258, 64262, 64265, 64269, 64273, 64277, + 64281, 64284, 64288, 64292, 64296, 64300, 64303, 64307, 64311, 64315, + 64319, 64323, 64327, 64331, 64335, 64339, 64343, 0, 64347, 64350, 64353, + 64356, 64359, 64362, 64365, 64368, 64371, 64374, 64377, 64380, 64383, + 64386, 64389, 64392, 64395, 64398, 64401, 64404, 64407, 64410, 64413, + 64416, 64419, 64422, 64425, 64428, 64431, 64434, 64437, 64440, 64443, + 64446, 64449, 64452, 64455, 64458, 64461, 64464, 64467, 64470, 64473, + 64476, 64479, 64482, 64485, 64488, 64491, 64494, 64497, 64500, 64503, + 64506, 64509, 64512, 64515, 64518, 64521, 64524, 64527, 64530, 64533, + 64536, 64539, 64542, 64545, 64548, 64551, 64554, 64557, 64560, 64563, + 64566, 64569, 64572, 64575, 64578, 64581, 64584, 64587, 64590, 64593, + 64596, 64599, 64602, 64605, 64608, 64611, 64620, 64628, 64636, 64644, + 64652, 64660, 64668, 64676, 64684, 64692, 64701, 64710, 64719, 64728, + 64737, 64746, 64755, 64764, 64773, 64782, 64791, 64800, 64809, 64818, + 64827, 64830, 64833, 64836, 64838, 64841, 64844, 64847, 64852, 64857, + 64860, 64867, 64874, 64881, 64888, 64891, 64896, 64898, 64902, 64904, + 64906, 64909, 64912, 64915, 64918, 64921, 64924, 64927, 64932, 64937, + 64940, 64943, 64946, 64949, 64952, 64955, 64958, 64962, 64965, 64968, + 64971, 64974, 64977, 64982, 64985, 64988, 64991, 64996, 65001, 65006, + 65011, 65016, 65021, 65026, 65031, 65036, 65044, 65046, 65049, 65052, + 65055, 65058, 65063, 65071, 65074, 65077, 65081, 65084, 65087, 65090, + 65095, 65098, 65101, 65106, 65109, 65112, 65117, 65120, 65123, 65128, + 65133, 65138, 65141, 65144, 65147, 65150, 65156, 65159, 65162, 65165, + 65167, 65170, 65173, 65176, 65181, 65184, 65187, 65190, 65193, 65196, + 65201, 65204, 65207, 65210, 65213, 65216, 65219, 65222, 65225, 65228, + 65234, 65239, 65247, 65255, 65263, 65271, 65279, 65287, 65295, 65303, + 65311, 65320, 65329, 65338, 65347, 65356, 65365, 65374, 65383, 65392, + 65401, 65410, 65419, 65428, 65437, 65446, 65455, 65464, 65473, 65482, + 65491, 65500, 65509, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18288, 18291, 18295, 18299, 18303, - 18307, 18311, 18315, 18319, 18323, 18327, 18331, 18335, 18339, 18343, - 18347, 18351, 18355, 18359, 18363, 18367, 18370, 18373, 18377, 18381, - 18385, 18388, 18391, 18394, 18398, 18402, 18405, 18408, 18412, 18415, - 18420, 18423, 18427, 18430, 18434, 18437, 18442, 18445, 18449, 18456, - 18461, 18465, 18470, 18474, 18479, 18483, 18488, 18495, 18501, 18506, - 18510, 18514, 18518, 18522, 18526, 18531, 18536, 18542, 18547, 18552, - 18556, 18559, 18562, 18565, 18568, 18571, 18574, 18577, 18580, 18583, - 18589, 18593, 18597, 18601, 18605, 18609, 18613, 18617, 18621, 18626, - 18630, 18635, 18640, 18646, 18651, 18657, 18663, 18669, 18675, 18681, - 18688, 18695, 18703, 18711, 18720, 18729, 18740, 18750, 18760, 18771, - 18782, 18792, 18802, 18812, 18822, 18832, 18842, 18852, 18862, 18870, - 18877, 18883, 18890, 18895, 18901, 18907, 18913, 18919, 18925, 18931, - 18936, 18942, 18948, 18954, 18960, 18965, 18973, 18980, 18986, 18993, - 19001, 19007, 19013, 19019, 19025, 19033, 19041, 19051, 19059, 19067, - 19073, 19078, 19083, 19088, 19093, 19098, 19103, 19108, 19113, 19118, - 19124, 19130, 19136, 19143, 19148, 19154, 19159, 19164, 19169, 19174, - 19179, 19184, 19189, 19194, 19199, 19204, 19209, 19214, 19219, 19224, - 19229, 19234, 19239, 19244, 19249, 19254, 19259, 19264, 19269, 19274, - 19279, 19284, 19289, 19294, 19299, 19304, 19309, 19314, 19319, 19324, - 19329, 19334, 19339, 0, 19344, 0, 0, 0, 0, 0, 19349, 0, 0, 19354, 19358, - 19362, 19366, 19370, 19374, 19378, 19382, 19386, 19390, 19394, 19398, - 19402, 19406, 19410, 19414, 19418, 19422, 19426, 19430, 19434, 19438, - 19442, 19446, 19450, 19454, 19458, 19462, 19466, 19470, 19474, 19478, - 19482, 19486, 19490, 19494, 19498, 19502, 19506, 19510, 19514, 19518, - 19524, 19528, 19533, 19538, 19542, 19547, 19552, 19556, 19560, 19564, - 19568, 19572, 19576, 19580, 19584, 19588, 19592, 19596, 19600, 19604, - 19608, 19612, 19616, 19620, 19624, 19628, 19632, 19636, 19640, 19644, - 19648, 19652, 19656, 19660, 19664, 19668, 19672, 19676, 19680, 19684, - 19688, 19692, 19696, 19700, 19704, 19708, 19712, 19716, 19720, 19724, - 19728, 19732, 19736, 19740, 19744, 19748, 19752, 19756, 19760, 19764, - 19768, 19772, 19776, 19780, 19784, 19788, 19792, 19796, 19800, 19804, - 19808, 19812, 19816, 19820, 19824, 19828, 19832, 19836, 19840, 19844, - 19848, 19852, 19856, 19860, 19864, 19868, 19872, 19876, 19880, 19884, - 19888, 19892, 19896, 19900, 19904, 19908, 19912, 19916, 19920, 19924, - 19928, 19932, 19936, 19940, 19943, 19947, 19950, 19954, 19958, 19961, - 19965, 19969, 19972, 19976, 19980, 19984, 19988, 19991, 19995, 19999, - 20003, 20007, 20011, 20015, 20018, 20022, 20026, 20030, 20034, 20038, - 20042, 20046, 20050, 20054, 20058, 20062, 20066, 20070, 20074, 20078, - 20082, 20086, 20090, 20094, 20098, 20102, 20106, 20110, 20114, 20118, - 20122, 20126, 20130, 20134, 20138, 20142, 20146, 20150, 20154, 20158, - 20162, 20166, 20170, 20174, 20178, 20182, 20186, 20190, 20194, 20198, - 20202, 20206, 20210, 20214, 20218, 20222, 20226, 20230, 20234, 20238, - 20242, 20246, 20250, 20254, 20258, 20262, 20266, 20270, 20274, 20278, - 20282, 20286, 20290, 20294, 20298, 20302, 20306, 20310, 20314, 20318, - 20322, 20326, 20330, 20334, 20338, 20342, 20346, 20350, 20354, 20358, - 20362, 20366, 20370, 20374, 20378, 20382, 20386, 20390, 20394, 20398, - 20402, 20406, 20410, 20414, 20418, 20422, 20426, 20430, 20434, 20438, - 20442, 20446, 20450, 20454, 20458, 20462, 20466, 20470, 20474, 20478, - 20482, 20486, 20490, 20494, 20498, 20502, 20506, 20510, 20514, 20518, - 20522, 20526, 20530, 20534, 20538, 20542, 20546, 20550, 20554, 20558, - 20562, 20566, 20570, 20573, 20577, 20581, 20585, 20589, 20593, 20597, - 20601, 20605, 20609, 20613, 20617, 20621, 20625, 20629, 20633, 20637, - 20641, 20645, 20649, 20653, 20657, 20661, 20665, 20668, 20672, 20676, - 20680, 20684, 20688, 20692, 20696, 20700, 20704, 20708, 20712, 20716, - 20720, 20724, 20728, 20731, 20735, 20739, 20743, 20747, 20751, 20755, - 20759, 20762, 20766, 20770, 20774, 20778, 20782, 20786, 20790, 20794, - 20798, 20802, 20806, 20810, 20814, 20818, 20822, 20826, 20830, 20834, - 20838, 20842, 20846, 20850, 20854, 0, 20858, 20862, 20866, 20870, 0, 0, - 20874, 20878, 20882, 20886, 20890, 20894, 20898, 0, 20902, 0, 20906, - 20910, 20914, 20918, 0, 0, 20922, 20926, 20930, 20934, 20938, 20942, - 20946, 20950, 20954, 20958, 20962, 20966, 20970, 20974, 20978, 20982, - 20986, 20990, 20994, 20998, 21002, 21006, 21010, 21013, 21017, 21021, - 21025, 21029, 21033, 21037, 21041, 21045, 21049, 21053, 21057, 21061, - 21065, 21069, 21073, 21077, 21081, 0, 21085, 21089, 21093, 21097, 0, 0, - 21101, 21104, 21108, 21112, 21116, 21120, 21124, 21128, 21132, 21136, - 21140, 21144, 21148, 21152, 21156, 21160, 21164, 21169, 21174, 21179, - 21185, 21191, 21196, 21201, 21207, 21210, 21214, 21218, 21222, 21226, - 21230, 21234, 21238, 0, 21242, 21246, 21250, 21254, 0, 0, 21258, 21262, - 21266, 21270, 21274, 21278, 21282, 0, 21286, 0, 21290, 21294, 21298, - 21302, 0, 0, 21306, 21310, 21314, 21318, 21322, 21326, 21330, 21334, - 21338, 21343, 21348, 21353, 21359, 21365, 21370, 0, 21375, 21379, 21383, - 21387, 21391, 21395, 21399, 21403, 21407, 21411, 21415, 21419, 21423, - 21427, 21431, 21435, 21439, 21442, 21446, 21450, 21454, 21458, 21462, - 21466, 21470, 21474, 21478, 21482, 21486, 21490, 21494, 21498, 21502, - 21506, 21510, 21514, 21518, 21522, 21526, 21530, 21534, 21538, 21542, - 21546, 21550, 21554, 21558, 21562, 21566, 21570, 21574, 21578, 21582, - 21586, 21590, 21594, 21598, 0, 21602, 21606, 21610, 21614, 0, 0, 21618, - 21622, 21626, 21630, 21634, 21638, 21642, 21646, 21650, 21654, 21658, - 21662, 21666, 21670, 21674, 21678, 21682, 21686, 21690, 21694, 21698, - 21702, 21706, 21710, 21714, 21718, 21722, 21726, 21730, 21734, 21738, - 21742, 21746, 21750, 21754, 21758, 21762, 21766, 21770, 21774, 21778, - 21782, 21786, 21790, 21794, 21798, 21802, 21806, 21810, 21814, 21818, - 21822, 21826, 21830, 21834, 21838, 21842, 21845, 21849, 21853, 21857, - 21861, 21865, 21869, 21873, 21877, 21881, 0, 0, 21885, 21894, 21900, - 21905, 21909, 21912, 21917, 21920, 21923, 21926, 21931, 21935, 21940, - 21943, 21946, 21949, 21952, 21955, 21958, 21961, 21964, 21967, 21971, - 21975, 21979, 21983, 21987, 21991, 21995, 21999, 22003, 22007, 0, 0, 0, - 22013, 22019, 22023, 22027, 22031, 22037, 22041, 22045, 22049, 22055, - 22059, 22063, 22067, 22073, 22077, 22081, 22085, 22091, 22097, 22103, - 22111, 22117, 22123, 22129, 22135, 22141, 0, 0, 0, 0, 0, 0, 22147, 22150, - 22153, 22156, 22159, 22162, 22166, 22170, 22173, 22177, 22181, 22185, - 22189, 22193, 22196, 22200, 22204, 22208, 22212, 22216, 22220, 22224, - 22228, 22232, 22236, 22240, 22243, 22247, 22251, 22255, 22259, 22262, - 22266, 22270, 22274, 22278, 22282, 22286, 22290, 22294, 22298, 22302, - 22306, 22310, 22314, 22317, 22321, 22325, 22329, 22333, 22337, 22341, - 22345, 22349, 22353, 22357, 22361, 22365, 22369, 22373, 22377, 22381, - 22385, 22389, 22393, 22397, 22401, 22405, 22409, 22413, 22417, 22421, - 22425, 22429, 22433, 22437, 22441, 22445, 22449, 22453, 22456, 22460, - 22464, 22468, 22472, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22476, 22480, - 22483, 22487, 22490, 22494, 22497, 22501, 22507, 22512, 22516, 22519, - 22523, 22527, 22532, 22536, 22541, 22545, 22550, 22554, 22559, 22563, - 22568, 22574, 22578, 22583, 22587, 22592, 22598, 22602, 22608, 22614, - 22618, 22623, 22631, 22639, 22646, 22651, 22656, 22665, 22672, 22679, - 22684, 22690, 22694, 22698, 22702, 22706, 22710, 22714, 22718, 22722, - 22726, 22730, 22736, 22741, 22746, 22749, 22753, 22757, 22762, 22766, - 22771, 22775, 22780, 22784, 22789, 22793, 22798, 22802, 22807, 22811, - 22816, 22822, 22826, 22831, 22836, 22840, 22844, 22848, 22852, 22855, - 22859, 22865, 22870, 22875, 22879, 22883, 22887, 22892, 22896, 22901, - 22905, 22910, 22913, 22917, 22921, 22926, 22930, 22935, 22939, 22944, - 22950, 22954, 22958, 22962, 22966, 22970, 22974, 22978, 22982, 22986, - 22990, 22994, 23000, 23003, 23007, 23011, 23016, 23020, 23025, 23029, - 23034, 23038, 23043, 23047, 23052, 23056, 23061, 23065, 23070, 23076, - 23080, 23084, 23090, 23096, 23102, 23108, 23112, 23116, 23120, 23124, - 23128, 23132, 23138, 23142, 23146, 23150, 23155, 23159, 23164, 23168, - 23173, 23177, 23182, 23186, 23191, 23195, 23200, 23204, 23209, 23215, - 23219, 23225, 23229, 23233, 23237, 23241, 23245, 23249, 23255, 23258, - 23262, 23266, 23271, 23275, 23280, 23284, 23289, 23293, 23298, 23302, - 23307, 23311, 23316, 23320, 23325, 23331, 23334, 23338, 23342, 23347, - 23352, 23356, 23360, 23364, 23368, 23372, 23376, 23382, 23385, 23389, - 23393, 23398, 23402, 23407, 23411, 23416, 23422, 23426, 23431, 23435, - 23439, 23443, 23447, 23451, 23455, 23459, 23465, 23469, 23473, 23477, - 23482, 23486, 23491, 23495, 23500, 23504, 23509, 23513, 23518, 23522, - 23527, 23531, 23536, 23539, 23543, 23547, 23551, 23555, 23559, 23563, - 23567, 23571, 23577, 23580, 23584, 23588, 23593, 23597, 23602, 23606, - 23611, 23615, 23620, 23624, 23629, 23633, 23638, 23642, 23647, 23653, - 23657, 23663, 23667, 23673, 23679, 23685, 23691, 23697, 23703, 23709, - 23715, 23719, 23723, 23727, 23731, 23735, 23739, 23743, 23747, 23752, - 23756, 23761, 23765, 23770, 23774, 23779, 23783, 23788, 23792, 23797, - 23801, 23806, 23810, 23814, 23818, 23822, 23826, 23830, 23834, 23840, - 23843, 23847, 23851, 23856, 23860, 23865, 23869, 23874, 23878, 23883, - 23887, 23892, 23896, 23901, 23905, 23910, 23916, 23920, 23926, 23931, - 23937, 23941, 23947, 23952, 23956, 23960, 23964, 23968, 23972, 23977, - 23980, 23984, 23989, 23993, 23998, 24001, 24005, 24009, 24013, 24017, - 24021, 24025, 24029, 24033, 24037, 24041, 24045, 24050, 24054, 24058, - 24064, 24068, 24074, 24078, 24084, 24088, 24092, 24096, 24100, 24104, - 24109, 24113, 24117, 24121, 24125, 24129, 24133, 24137, 24141, 24145, - 24149, 24155, 24161, 24167, 24173, 24179, 24184, 24190, 24196, 24202, - 24206, 24210, 24214, 24218, 24222, 24226, 24230, 24234, 24238, 24242, - 24246, 24250, 24254, 24259, 24264, 24269, 24273, 24277, 24281, 24285, - 24289, 24293, 24297, 24301, 24305, 24309, 24315, 24321, 24327, 24333, - 24339, 24345, 24351, 24357, 24363, 24367, 24371, 24375, 24379, 24383, - 24387, 24391, 24397, 24403, 24409, 24415, 24421, 24427, 24433, 24439, - 24445, 24450, 24455, 24460, 24465, 24471, 24477, 24483, 24489, 24495, - 24501, 24507, 24512, 24518, 24524, 24530, 24535, 24541, 24547, 24553, - 24558, 24563, 24568, 24573, 24578, 24583, 24588, 24593, 24598, 24603, - 24608, 24613, 24617, 24622, 24627, 24632, 24637, 24642, 24647, 24652, - 24657, 24662, 24667, 24672, 24677, 24682, 24687, 24692, 24697, 24702, - 24707, 24712, 24717, 24722, 24727, 24732, 24737, 24742, 24747, 24752, - 24757, 24762, 24766, 24771, 24776, 24781, 24786, 24791, 24796, 24801, - 24806, 24811, 24816, 24821, 24826, 24831, 24836, 24841, 24846, 24851, - 24856, 24861, 24866, 24871, 24876, 24881, 24886, 24891, 24895, 24900, - 24905, 24910, 24915, 24920, 24924, 24929, 24934, 24939, 24944, 24949, - 24953, 24958, 24964, 24969, 24974, 24979, 24984, 24990, 24995, 25000, - 25005, 25010, 25015, 25020, 25025, 25030, 25035, 25040, 25045, 25050, - 25055, 25060, 25065, 25070, 25075, 25080, 25085, 25090, 25095, 25100, - 25105, 25110, 25115, 25120, 25125, 25130, 25135, 25140, 25145, 25150, - 25155, 25160, 25165, 25170, 25175, 25180, 25185, 25190, 25195, 25200, - 25205, 25210, 25216, 25221, 25226, 25231, 25236, 25241, 25246, 25251, - 25256, 25261, 25266, 25271, 25275, 25280, 25285, 25290, 25295, 25300, - 25305, 25310, 25315, 25320, 25325, 25330, 25335, 25340, 25345, 25350, - 25355, 25360, 25365, 25370, 25375, 25380, 25385, 25390, 25395, 25400, - 25405, 25411, 25415, 25419, 25423, 25427, 25431, 25435, 25439, 25443, - 25449, 25455, 25461, 25467, 25473, 25479, 25485, 25492, 25498, 25503, - 25508, 25513, 25518, 25523, 25528, 25533, 25538, 25543, 25548, 25553, - 25558, 25563, 25568, 25573, 25578, 25583, 25588, 25593, 25598, 25603, - 25608, 25613, 25618, 25623, 25628, 25633, 25638, 0, 0, 0, 25645, 25655, - 25659, 25666, 25670, 25674, 25678, 25686, 25690, 25695, 25700, 25705, - 25709, 25714, 25719, 25722, 25726, 25730, 25739, 25743, 25747, 25753, - 25757, 25761, 25769, 25773, 25781, 25787, 25793, 25799, 25805, 25815, - 25821, 25825, 25834, 25837, 25843, 25847, 25853, 25858, 25864, 25872, - 25878, 25884, 25892, 25898, 25902, 25906, 25916, 25922, 25926, 25936, - 25942, 25946, 25950, 25957, 25964, 25969, 25974, 25983, 25987, 25991, - 25995, 26003, 26010, 26014, 26018, 26022, 26026, 26030, 26034, 26038, - 26042, 26046, 26050, 26054, 26059, 26064, 26069, 26073, 26077, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26081, 26085, 26089, 26093, 26097, - 26102, 26107, 26112, 26117, 26121, 26125, 26130, 26134, 0, 26138, 26143, - 26148, 26152, 26156, 26161, 26166, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 26171, 26175, 26179, 26183, 26187, 26192, 26197, 26202, 26207, 26211, - 26215, 26220, 26224, 26228, 26232, 26237, 26242, 26246, 26250, 26255, - 26260, 26265, 26271, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26276, 26280, 26284, - 26288, 26292, 26297, 26302, 26307, 26312, 26316, 26320, 26325, 26329, - 26333, 26337, 26342, 26347, 26351, 26355, 26360, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 26365, 26369, 26373, 26377, 26381, 26386, 26391, 26396, - 26401, 26405, 26409, 26414, 26418, 0, 26422, 26427, 26432, 0, 26436, - 26441, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26446, 26449, 26453, 26457, - 26461, 26465, 26469, 26473, 26477, 26481, 26485, 26489, 26493, 26497, - 26501, 26505, 26509, 26513, 26516, 26520, 26524, 26528, 26532, 26536, - 26540, 26544, 26548, 26552, 26556, 26560, 26564, 26568, 26571, 26574, - 26578, 26582, 26588, 26594, 26600, 26606, 26612, 26618, 26624, 26630, - 26636, 26642, 26648, 26654, 26660, 26666, 26675, 26684, 26690, 26696, - 26702, 26707, 26711, 26716, 26721, 26726, 26730, 26735, 26740, 26745, - 26749, 26754, 26758, 26763, 26768, 26773, 26778, 26782, 26786, 26790, - 26794, 26798, 26802, 26806, 26810, 26814, 26818, 26824, 26828, 26832, - 26836, 26840, 26844, 26852, 26858, 26862, 26868, 26872, 26878, 26882, 0, - 0, 26886, 26890, 26893, 26896, 26899, 26902, 26905, 26908, 26911, 26914, - 0, 0, 0, 0, 0, 0, 26917, 26925, 26933, 26941, 26949, 26957, 26965, 26973, - 26981, 26989, 0, 0, 0, 0, 0, 0, 26997, 27000, 27003, 27006, 27011, 27014, - 27019, 27026, 27034, 27039, 27046, 27049, 27056, 27063, 27070, 0, 27074, - 27078, 27081, 27084, 27087, 27090, 27093, 27096, 27099, 27102, 0, 0, 0, - 0, 0, 0, 27105, 27108, 27111, 27114, 27117, 27120, 27124, 27128, 27132, - 27135, 27139, 27143, 27146, 27150, 27154, 27157, 27161, 27164, 27168, - 27172, 27176, 27180, 27184, 27187, 27190, 27194, 27198, 27201, 27205, - 27209, 27213, 27217, 27221, 27225, 27229, 27233, 27240, 27245, 27250, - 27255, 27260, 27266, 27272, 27278, 27284, 27289, 27295, 27301, 27306, - 27312, 27318, 27324, 27330, 27336, 27341, 27347, 27352, 27358, 27364, - 27370, 27376, 27382, 27387, 27392, 27398, 27404, 27409, 27415, 27420, - 27426, 27431, 27436, 27442, 27448, 27454, 27460, 27466, 27472, 27478, - 27484, 27490, 27496, 27502, 27508, 27513, 27518, 27523, 27529, 0, 0, 0, - 0, 0, 0, 0, 0, 27535, 27544, 27553, 27561, 27569, 27579, 27587, 27596, - 27603, 27610, 27617, 27625, 27633, 27641, 27649, 27657, 27665, 27673, - 27681, 27688, 27696, 27704, 27712, 27720, 27728, 27738, 27748, 27758, - 27768, 27778, 27788, 27798, 27808, 27818, 27828, 27838, 27848, 27858, - 27868, 27876, 27884, 27894, 27902, 0, 0, 0, 0, 0, 27912, 27916, 27920, - 27924, 27928, 27932, 27936, 27940, 27944, 27948, 27952, 27956, 27960, - 27964, 27968, 27972, 27976, 27980, 27984, 27988, 27992, 27996, 28000, - 28004, 28010, 28014, 28020, 28024, 28030, 28034, 28040, 28044, 28048, - 28052, 28056, 28060, 28064, 28070, 28076, 28082, 28088, 28093, 28099, - 28105, 28111, 28117, 28123, 28129, 28136, 28142, 28147, 28152, 28156, - 28160, 28164, 28168, 28172, 28176, 28180, 28186, 28192, 28198, 28203, - 28210, 28215, 28220, 28226, 28231, 28238, 28245, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 28252, 28258, 28262, 28267, 28272, 28277, 28282, 28287, 28292, - 28297, 28302, 28307, 28312, 28317, 28322, 28327, 28331, 28335, 28340, - 28345, 28350, 28354, 28358, 28362, 28367, 28372, 28377, 28382, 28386, 0, - 0, 0, 28390, 28395, 28400, 28405, 28411, 28417, 28423, 28429, 28434, - 28439, 28445, 28451, 0, 0, 0, 0, 28458, 28463, 28469, 28475, 28481, - 28486, 28491, 28496, 28501, 28507, 28512, 28517, 0, 0, 0, 0, 28522, 0, 0, - 0, 28527, 28532, 28537, 28542, 28546, 28550, 28554, 28558, 28562, 28566, - 28570, 28574, 28578, 28583, 28589, 28595, 28601, 28606, 28611, 28617, - 28623, 28629, 28634, 28640, 28645, 28651, 28657, 28662, 28668, 28674, - 28680, 28685, 28690, 28695, 28701, 28707, 28712, 28718, 28723, 28729, - 28734, 28740, 0, 0, 28746, 28752, 28758, 28764, 28770, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 28776, 28783, 28790, 28796, 28803, 28810, 28816, 28823, - 28830, 28837, 28843, 28849, 28856, 28862, 28868, 28875, 28882, 28888, - 28895, 28902, 28908, 28914, 28921, 28927, 28933, 28940, 28946, 28953, - 28960, 28967, 28974, 28981, 28988, 28994, 29001, 29008, 29014, 29021, - 29028, 29035, 29042, 29049, 29056, 29063, 0, 0, 0, 0, 29070, 29078, - 29085, 29092, 29098, 29105, 29111, 29118, 29124, 29131, 29138, 29145, - 29152, 29159, 29166, 29173, 29180, 29187, 29194, 29201, 29208, 29214, - 29221, 29228, 29235, 29241, 0, 0, 0, 0, 0, 0, 29247, 29253, 29258, 29263, - 29268, 29273, 29278, 29283, 29288, 29293, 29298, 0, 0, 0, 29304, 29310, - 29316, 29320, 29326, 29332, 29338, 29344, 29350, 29356, 29362, 29368, - 29374, 29380, 29386, 29392, 29398, 29404, 29410, 29414, 29420, 29426, - 29432, 29438, 29444, 29450, 29456, 29462, 29468, 29474, 29480, 29486, - 29492, 29498, 29504, 29508, 29513, 29518, 29523, 29527, 29532, 29536, - 29541, 29546, 29551, 29555, 29560, 29565, 29570, 29575, 29580, 29584, - 29588, 29593, 29598, 29602, 29606, 29610, 29615, 29620, 29625, 29630, 0, - 0, 29636, 29640, 29647, 29652, 29658, 29664, 29669, 29675, 29681, 29686, - 29692, 29698, 29704, 29709, 29715, 29720, 29725, 29731, 29736, 29742, - 29747, 29753, 29759, 29765, 29771, 29775, 29780, 29785, 29791, 29797, - 29802, 29808, 29814, 29818, 29823, 29828, 29832, 29837, 29842, 29847, - 29852, 29858, 29864, 29869, 29874, 29879, 29883, 29888, 29892, 29897, - 29901, 29906, 29911, 29916, 29921, 29927, 29933, 29940, 29950, 29959, - 29966, 29972, 29982, 29987, 29993, 0, 29998, 30003, 30008, 30016, 30022, - 30030, 30035, 30041, 30047, 30053, 30058, 30064, 30069, 30076, 30082, - 30087, 30093, 30099, 30105, 30112, 30119, 30126, 30131, 30136, 30143, - 30150, 30157, 30164, 30171, 0, 0, 30178, 30185, 30192, 30198, 30204, - 30210, 30216, 30222, 30228, 30234, 30240, 0, 0, 0, 0, 0, 0, 30246, 30252, - 30257, 30262, 30267, 30272, 30277, 30282, 30287, 30292, 0, 0, 0, 0, 0, 0, - 30297, 30302, 30307, 30312, 30317, 30322, 30327, 30336, 30343, 30348, - 30353, 30358, 30363, 30368, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30373, 30379, - 30385, 30389, 30393, 30397, 30401, 30407, 30411, 30417, 30421, 30427, - 30433, 30441, 30447, 30455, 30459, 30463, 30467, 30473, 30476, 30482, - 30486, 30492, 30496, 30500, 30506, 30510, 30516, 30520, 30526, 30534, - 30542, 30550, 30556, 30560, 30566, 30570, 30576, 30579, 30582, 30588, - 30592, 30598, 30601, 30604, 30607, 30611, 30615, 30621, 30627, 30630, - 30633, 30637, 30642, 30647, 30654, 30659, 30666, 30673, 30682, 30689, - 30698, 30703, 30710, 30717, 30726, 30731, 30738, 30743, 30749, 30755, - 30761, 30767, 30773, 30779, 0, 0, 0, 0, 30785, 30789, 30792, 30795, - 30798, 30801, 30804, 30807, 30810, 30813, 30816, 30819, 30822, 30825, - 30830, 30835, 30840, 30843, 30848, 30853, 30858, 30863, 30870, 30875, - 30880, 30885, 30890, 30897, 30903, 30909, 30915, 30921, 30927, 30936, - 30945, 30951, 30957, 30965, 30973, 30982, 30991, 30999, 31007, 31016, - 31025, 0, 0, 0, 31033, 31037, 31041, 31045, 31048, 31051, 31054, 31058, - 31061, 31064, 31068, 31071, 31075, 31079, 31083, 31087, 31091, 31095, - 31099, 31103, 31107, 31110, 31113, 31117, 31121, 31125, 31128, 31131, - 31134, 31138, 31142, 31145, 31149, 31152, 31157, 31162, 31167, 31172, - 31177, 31182, 31187, 31192, 31197, 31201, 31205, 31211, 31218, 31222, - 31226, 31230, 31233, 31236, 31239, 31242, 31245, 31248, 31251, 31254, - 31257, 31260, 31264, 31268, 31272, 31277, 31281, 31285, 31291, 31295, - 31301, 31307, 31312, 31319, 31323, 31329, 31333, 31339, 31344, 31351, - 31358, 31363, 31370, 31375, 31380, 31384, 31390, 31394, 31400, 31407, - 31414, 31418, 31424, 31430, 31434, 31440, 31445, 31450, 31457, 31462, - 31467, 31472, 31477, 31481, 31485, 31490, 31495, 31502, 31508, 31513, - 31520, 31525, 31532, 31537, 31546, 31552, 31558, 31562, 0, 0, 0, 0, 0, 0, - 0, 0, 31566, 31575, 31582, 31589, 31596, 31599, 31603, 31607, 31611, - 31615, 31619, 31623, 31627, 31631, 31635, 31639, 31643, 31647, 31650, - 31653, 31657, 31661, 31665, 31669, 31673, 31677, 31680, 31684, 31688, - 31692, 31696, 31699, 31702, 31706, 31709, 31713, 31717, 31720, 31724, - 31728, 31731, 31736, 31741, 31746, 31750, 31754, 31759, 31763, 31768, - 31772, 31777, 31781, 31785, 31790, 31795, 31799, 31804, 31809, 31814, - 31818, 0, 0, 0, 31822, 31827, 31836, 31841, 31848, 31853, 31857, 31860, - 31863, 31866, 31869, 31872, 31875, 31878, 31881, 0, 0, 0, 31884, 31888, - 31892, 31896, 31903, 31909, 31915, 31921, 31927, 31933, 31939, 31945, - 31951, 31957, 31964, 31971, 31978, 31985, 31992, 31999, 32006, 32013, - 32020, 32027, 32034, 32041, 32048, 32055, 32062, 32069, 32076, 32083, - 32090, 32097, 32104, 32111, 32118, 32125, 32132, 32139, 32146, 32153, - 32160, 32167, 32175, 32183, 32191, 32197, 32203, 32209, 32217, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32226, 32233, 32240, 32247, 32254, - 32263, 32272, 32281, 0, 0, 0, 0, 0, 0, 0, 0, 32290, 32295, 32300, 32305, - 32310, 32319, 32330, 32339, 32350, 32356, 32369, 32375, 32382, 32389, - 32394, 32400, 32406, 32417, 32426, 32433, 32440, 32449, 32456, 32465, - 32475, 32485, 32492, 32499, 32506, 32516, 32521, 32529, 32535, 32543, - 32552, 32557, 32564, 32570, 32575, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32580, - 32585, 32591, 32598, 32606, 32612, 32618, 32624, 32629, 32636, 32642, - 32648, 32654, 32662, 32667, 32675, 32680, 32686, 32692, 32699, 32707, - 32714, 32720, 32727, 32734, 32740, 32747, 32754, 32760, 32765, 32771, - 32779, 32787, 32793, 32799, 32805, 32811, 32819, 32823, 32829, 32835, - 32841, 32847, 32853, 32859, 32863, 32868, 32873, 32880, 32885, 32889, - 32895, 32900, 32905, 32909, 32914, 32919, 32923, 32927, 32932, 32939, - 32943, 32948, 32953, 32957, 32962, 32966, 32971, 32975, 32981, 32986, - 32993, 32998, 33003, 33007, 33012, 33017, 33024, 33029, 33035, 33040, - 33044, 33049, 33053, 33058, 33065, 33072, 33077, 33082, 33086, 33092, - 33098, 33103, 33108, 33113, 33119, 33124, 33130, 33135, 33141, 33147, - 33153, 33160, 33167, 33174, 33181, 33188, 33195, 33200, 33208, 33217, - 33226, 33235, 33244, 33253, 33262, 33274, 33283, 33292, 33301, 33308, - 33313, 33320, 33328, 33336, 33343, 33350, 33357, 33364, 33372, 33381, - 33390, 33399, 33408, 33417, 33426, 33435, 33444, 33453, 33462, 33471, - 33480, 33489, 33498, 33506, 33515, 33526, 33534, 33543, 33554, 33563, - 33572, 33581, 33590, 33598, 33607, 33614, 33619, 33627, 33632, 33639, - 33644, 33653, 33659, 33666, 33673, 33678, 33683, 33691, 33699, 33708, - 33717, 33722, 33729, 33740, 33748, 33757, 33763, 33769, 33774, 33781, - 33786, 33795, 33800, 33805, 33810, 33817, 33824, 33829, 33838, 33846, - 33851, 33856, 33863, 33870, 33874, 33878, 33881, 33884, 33887, 33890, - 33893, 33896, 33903, 33906, 33909, 33914, 33918, 33922, 33926, 33930, - 33934, 33943, 33949, 33955, 33961, 33969, 33977, 33983, 33989, 33996, - 34002, 34007, 34013, 34019, 34025, 34032, 34038, 34046, 34052, 34059, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34065, 34072, - 34079, 34084, 34093, 34101, 34109, 34116, 34123, 34130, 34137, 34145, - 34153, 34163, 34173, 34181, 34189, 34197, 34205, 34214, 34223, 34231, - 34239, 34248, 34257, 34267, 34277, 34286, 34295, 34303, 34311, 34319, - 34327, 34337, 34347, 34355, 34363, 34371, 34379, 34387, 34395, 34403, - 34411, 34419, 34427, 34435, 34443, 34452, 34461, 34470, 34479, 34489, - 34499, 34506, 34513, 34521, 34529, 34538, 34547, 34555, 34563, 34575, - 34587, 34596, 34605, 34614, 34623, 34630, 34637, 34645, 34653, 34661, - 34669, 34677, 34685, 34693, 34701, 34710, 34719, 34728, 34737, 34746, - 34755, 34765, 34775, 34785, 34795, 34804, 34813, 34820, 34827, 34835, - 34843, 34851, 34859, 34867, 34875, 34887, 34899, 34908, 34917, 34925, - 34933, 34941, 34949, 34960, 34971, 34982, 34993, 35005, 35017, 35025, - 35033, 35041, 35049, 35058, 35067, 35076, 35085, 35093, 35101, 35109, - 35117, 35125, 35133, 35142, 35151, 35161, 35171, 35178, 35185, 35193, - 35201, 35209, 35217, 35224, 35231, 35239, 35247, 35255, 35263, 35271, - 35279, 35287, 35295, 35303, 35311, 35319, 35327, 35335, 35343, 35351, - 35359, 35368, 35377, 35386, 35394, 35403, 35412, 35421, 35430, 35440, - 35449, 35456, 35461, 35468, 35475, 35483, 35491, 35500, 35509, 35519, - 35529, 35540, 35551, 35560, 35569, 35579, 35589, 35598, 35607, 35617, - 35627, 35638, 35649, 35658, 35667, 35677, 35687, 35694, 35701, 35709, - 35717, 35723, 35729, 35738, 35747, 35757, 35767, 35778, 35789, 35798, - 35807, 35817, 35827, 35836, 35845, 35853, 35861, 35868, 35875, 35883, - 35891, 35900, 35909, 35919, 35929, 35940, 35951, 35960, 35969, 35979, - 35989, 35998, 36007, 36017, 36027, 36038, 36049, 36058, 36067, 36077, - 36087, 36094, 36101, 36109, 36117, 36126, 36135, 36145, 36155, 36166, - 36177, 36186, 36195, 36205, 36215, 36223, 36231, 36239, 36247, 36256, - 36265, 36272, 36279, 36286, 36293, 36300, 36307, 36315, 36323, 36331, - 36339, 36350, 36361, 36372, 36383, 36394, 36405, 36413, 36421, 36432, - 36443, 36454, 36465, 36476, 36487, 36495, 36503, 36514, 36525, 36536, 0, - 0, 36547, 36555, 36563, 36574, 36585, 36596, 0, 0, 36607, 36615, 36623, - 36634, 36645, 36656, 36667, 36678, 36689, 36697, 36705, 36716, 36727, - 36738, 36749, 36760, 36771, 36779, 36787, 36798, 36809, 36820, 36831, - 36842, 36853, 36861, 36869, 36880, 36891, 36902, 36913, 36924, 36935, - 36943, 36951, 36962, 36973, 36984, 0, 0, 36995, 37003, 37011, 37022, - 37033, 37044, 0, 0, 37055, 37063, 37071, 37082, 37093, 37104, 37115, - 37126, 0, 37137, 0, 37145, 0, 37156, 0, 37167, 37178, 37186, 37194, - 37205, 37216, 37227, 37238, 37249, 37260, 37268, 37276, 37287, 37298, - 37309, 37320, 37331, 37342, 37350, 37358, 37366, 37374, 37382, 37390, - 37398, 37406, 37414, 37422, 37430, 37438, 37446, 0, 0, 37454, 37465, - 37476, 37490, 37504, 37518, 37532, 37546, 37560, 37571, 37582, 37596, - 37610, 37624, 37638, 37652, 37666, 37677, 37688, 37702, 37716, 37730, - 37744, 37758, 37772, 37783, 37794, 37808, 37822, 37836, 37850, 37864, - 37878, 37889, 37900, 37914, 37928, 37942, 37956, 37970, 37984, 37995, - 38006, 38020, 38034, 38048, 38062, 38076, 38090, 38098, 38106, 38117, - 38125, 0, 38136, 38144, 38155, 38163, 38171, 38179, 38187, 38195, 38198, - 38201, 38204, 38207, 38213, 38224, 38232, 0, 38243, 38251, 38262, 38270, - 38278, 38286, 38294, 38302, 38308, 38314, 38320, 38328, 38336, 38347, 0, - 0, 38358, 38366, 38377, 38385, 38393, 38401, 0, 38409, 38415, 38421, - 38427, 38435, 38443, 38454, 38465, 38473, 38481, 38489, 38500, 38508, - 38516, 38524, 38532, 38540, 38546, 38552, 0, 0, 38555, 38566, 38574, 0, - 38585, 38593, 38604, 38612, 38620, 38628, 38636, 38644, 38647, 0, 38650, - 38654, 38658, 38662, 38666, 38670, 38674, 38678, 38682, 38686, 38690, - 38694, 38700, 38706, 38712, 38715, 38718, 38720, 38724, 38728, 38732, - 38736, 38738, 38742, 38746, 38752, 38758, 38765, 38772, 38777, 38782, - 38788, 38794, 38796, 38799, 38801, 38805, 38809, 38813, 38816, 38820, - 38824, 38828, 38832, 38836, 38842, 38846, 38850, 38856, 38861, 38868, - 38870, 38873, 38877, 38881, 38886, 38892, 38894, 38903, 38912, 38915, - 38919, 38921, 38923, 38925, 38928, 38934, 38936, 38940, 38944, 38951, - 38958, 38962, 38967, 38972, 38977, 38982, 38986, 38990, 38993, 38997, - 39001, 39008, 39013, 39017, 39021, 39026, 39030, 39034, 39039, 39044, - 39048, 39052, 39056, 39058, 39063, 39068, 39072, 39076, 39080, 39084, 0, - 39088, 39092, 39096, 39102, 39108, 39114, 39120, 39127, 39134, 39139, - 39144, 39148, 0, 0, 39154, 39157, 39160, 39163, 39166, 39169, 39172, - 39176, 39180, 39185, 39190, 39195, 39202, 39206, 39209, 39212, 39215, - 39218, 39221, 39224, 39227, 39230, 39233, 39237, 39241, 39246, 39251, 0, - 39256, 39262, 39268, 39274, 39281, 39288, 39295, 39302, 39308, 39314, - 39321, 39328, 39335, 0, 0, 0, 39342, 39345, 39348, 39351, 39356, 39359, - 39362, 39365, 39368, 39371, 39374, 39378, 39381, 39384, 39387, 39390, - 39393, 39398, 39401, 39404, 39407, 39410, 39413, 39418, 39421, 39424, - 39429, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 39434, 39439, 39444, 39451, 39459, 39464, 39469, 39473, 39477, 39482, - 39489, 39496, 39500, 39505, 39510, 39515, 39520, 39527, 39532, 39537, - 39542, 39551, 39558, 39565, 39569, 39574, 39580, 39585, 39592, 39601, - 39610, 39614, 39618, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39622, - 39626, 39634, 39638, 39642, 39647, 39651, 39655, 39659, 39661, 39665, - 39669, 39673, 39678, 39682, 39686, 39694, 39697, 39701, 39704, 39707, - 39713, 39717, 39720, 39726, 39730, 39734, 39738, 39741, 39745, 39748, - 39752, 39754, 39757, 39760, 39764, 39766, 39770, 39773, 39776, 39781, - 39786, 39793, 39796, 39799, 39803, 39808, 39811, 39814, 39817, 39821, - 39826, 39829, 39832, 39834, 39837, 39840, 39843, 39847, 39852, 39855, - 39859, 39863, 39867, 39871, 39876, 39882, 39887, 39892, 39898, 39903, - 39908, 39912, 39916, 39921, 39925, 39929, 39932, 39934, 39939, 39945, - 39952, 39959, 39966, 39973, 39980, 39987, 39994, 40001, 40009, 40016, - 40024, 40031, 40038, 40046, 40054, 40059, 40064, 40069, 40074, 40079, - 40084, 40089, 40094, 40099, 40104, 40110, 40116, 40122, 40128, 40135, - 40143, 40150, 40156, 40162, 40168, 40174, 40180, 40186, 40192, 40198, - 40204, 40211, 40218, 40225, 40232, 40240, 40249, 40257, 40268, 40276, - 40284, 40293, 40300, 40309, 40318, 40326, 40335, 0, 0, 0, 0, 0, 0, 40343, - 40345, 40348, 40350, 40353, 40356, 40359, 40364, 40369, 40374, 40379, - 40383, 40387, 40391, 40395, 40400, 40406, 40411, 40417, 40422, 40427, - 40432, 40438, 40443, 40449, 40455, 40459, 40463, 40468, 40473, 40478, - 40483, 40488, 40496, 40504, 40512, 40520, 40527, 40535, 40542, 40549, - 40558, 40570, 40576, 40582, 40590, 40598, 40607, 40616, 40624, 40632, - 40641, 40650, 40655, 40663, 40668, 40673, 40679, 40684, 40690, 40697, - 40704, 40709, 40715, 40720, 40723, 40727, 40730, 40734, 40738, 40742, - 40748, 40754, 40760, 40766, 40770, 40774, 40778, 40782, 40788, 40794, - 40798, 40803, 40807, 40812, 40817, 40822, 40825, 40829, 40832, 40836, - 40843, 40851, 40862, 40873, 40878, 40887, 40894, 40903, 40912, 40916, - 40922, 40930, 40934, 40939, 40944, 40950, 40956, 40962, 40969, 40973, - 40977, 40982, 40985, 40987, 40991, 40995, 41003, 41007, 41009, 41011, - 41015, 41023, 41028, 41034, 41044, 41051, 41056, 41060, 41064, 41068, - 41071, 41074, 41077, 41081, 41085, 41089, 41093, 41097, 41100, 41104, - 41108, 41111, 41113, 41116, 41118, 41122, 41126, 41128, 41134, 41137, - 41142, 41146, 41150, 41152, 41154, 41156, 41159, 41163, 41167, 41171, - 41175, 41179, 41185, 41191, 41193, 41195, 41197, 41199, 41202, 41204, - 41208, 41210, 41214, 41217, 41223, 41227, 41231, 41234, 41237, 41241, - 41247, 41251, 41261, 41271, 41275, 41281, 41287, 41290, 41294, 41297, - 41302, 41306, 41312, 41316, 41328, 41336, 41340, 41344, 41350, 41354, - 41357, 41359, 41362, 41366, 41370, 41377, 41381, 41385, 41389, 41392, - 41397, 41402, 41407, 41412, 41417, 41422, 41430, 41438, 41442, 41446, - 41448, 41453, 41457, 41461, 41469, 41477, 41483, 41489, 41498, 41507, - 41512, 41517, 41525, 41533, 41535, 41537, 41542, 41547, 41553, 41559, - 41565, 41571, 41575, 41579, 41586, 41593, 41599, 41605, 41615, 41625, - 41633, 41641, 41643, 41647, 41651, 41656, 41661, 41668, 41675, 41678, - 41681, 41684, 41687, 41690, 41695, 41699, 41704, 41709, 41712, 41715, - 41718, 41721, 41724, 41728, 41731, 41734, 41737, 41740, 41742, 41744, - 41746, 41748, 41756, 41764, 41770, 41774, 41780, 41790, 41796, 41802, - 41808, 41816, 41824, 41835, 41839, 41843, 41845, 41851, 41853, 41855, - 41857, 41859, 41865, 41868, 41874, 41880, 41884, 41888, 41892, 41895, - 41899, 41903, 41905, 41914, 41923, 41928, 41933, 41939, 41945, 41951, - 41954, 41957, 41960, 41963, 41965, 41970, 41975, 41980, 41986, 41992, - 42000, 42008, 42014, 42020, 42026, 42032, 42041, 42050, 42059, 42068, - 42077, 42086, 42095, 42104, 42113, 42122, 42130, 42142, 42152, 42167, - 42170, 42175, 42181, 42187, 42194, 42208, 42223, 42229, 42235, 42242, - 42248, 42256, 42262, 42275, 42289, 42294, 42300, 42307, 42310, 42313, - 42315, 42318, 42321, 42323, 42325, 42329, 42332, 42335, 42338, 42341, - 42346, 42351, 42356, 42361, 42366, 42369, 42371, 42373, 42375, 42379, - 42383, 42387, 42393, 42398, 42400, 42402, 42407, 42412, 42417, 42422, - 42427, 42432, 42434, 42436, 42445, 42449, 42457, 42466, 42468, 42473, - 42478, 42486, 42490, 42492, 42496, 42498, 42502, 42506, 42510, 42512, - 42514, 42516, 42523, 42532, 42541, 42550, 42559, 42568, 42577, 42586, - 42595, 42603, 42611, 42620, 42629, 42638, 42647, 42655, 42663, 42672, - 42681, 42690, 42700, 42709, 42719, 42728, 42738, 42747, 42757, 42767, - 42776, 42786, 42795, 42805, 42814, 42824, 42833, 42842, 42851, 42860, - 42869, 42879, 42888, 42897, 42906, 42916, 42925, 42934, 42943, 42952, - 42962, 42972, 42981, 42990, 42998, 43006, 43013, 43021, 43030, 43041, - 43050, 43059, 43068, 43075, 43082, 43089, 43098, 43107, 43116, 43125, - 43132, 43137, 43146, 43151, 43154, 43162, 43165, 43170, 43175, 43178, - 43181, 43189, 43192, 43197, 43200, 43207, 43212, 43220, 43223, 43226, - 43229, 43234, 43239, 43242, 43245, 43253, 43256, 43263, 43270, 43274, - 43278, 43283, 43288, 43294, 43299, 43305, 43311, 43316, 43322, 43330, - 43336, 43344, 43352, 43358, 43366, 43374, 43383, 43391, 43397, 43405, - 43414, 43422, 43426, 43431, 43444, 43457, 43461, 43465, 43469, 43473, - 43483, 43487, 43492, 43497, 43502, 43507, 43512, 43517, 43527, 43537, - 43545, 43555, 43565, 43573, 43583, 43593, 43601, 43611, 43621, 43629, - 43637, 43647, 43657, 43660, 43663, 43666, 43671, 43675, 43681, 43688, - 43695, 43703, 43710, 43714, 43718, 43722, 43726, 43728, 43732, 43736, - 43741, 43746, 43753, 43760, 43763, 43770, 43772, 43774, 43778, 43782, - 43787, 43793, 43799, 43805, 43811, 43820, 43829, 43838, 43842, 43844, - 43848, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43855, 43859, 43866, 43873, - 43880, 43887, 43891, 43895, 43899, 43903, 43908, 43914, 43919, 43925, - 43931, 43937, 43943, 43951, 43958, 43965, 43972, 43979, 43984, 43990, - 43999, 44003, 44010, 44014, 44018, 44024, 44030, 44036, 44042, 44046, - 44050, 44053, 44056, 44060, 44067, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44074, 44077, 44081, 44085, 44091, - 44097, 44103, 44111, 44118, 44122, 44130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44135, 44138, 44141, 44144, 44147, - 44150, 44153, 44156, 44159, 44162, 44166, 44170, 44174, 44178, 44182, - 44186, 44190, 44194, 44198, 44202, 44206, 44209, 44212, 44215, 44218, - 44221, 44224, 44227, 44230, 44233, 44237, 44241, 44245, 44249, 44253, - 44257, 44261, 44265, 44269, 44273, 44277, 44283, 44289, 44295, 44302, - 44309, 44316, 44323, 44330, 44337, 44344, 44351, 44358, 44365, 44372, - 44379, 44386, 44393, 44400, 44407, 44414, 44419, 44425, 44431, 44437, - 44442, 44448, 44454, 44460, 44465, 44471, 44477, 44482, 44487, 44493, - 44498, 44504, 44510, 44515, 44521, 44527, 44532, 44538, 44544, 44550, - 44556, 44562, 44567, 44573, 44579, 44585, 44590, 44596, 44602, 44608, - 44613, 44619, 44625, 44630, 44635, 44641, 44646, 44652, 44658, 44663, - 44669, 44675, 44680, 44686, 44692, 44698, 44704, 44710, 44715, 44721, - 44727, 44733, 44738, 44744, 44750, 44756, 44761, 44767, 44773, 44778, - 44783, 44789, 44794, 44800, 44806, 44811, 44817, 44823, 44828, 44834, - 44840, 44846, 44852, 44858, 44862, 44867, 44872, 44877, 44882, 44887, - 44892, 44897, 44902, 44907, 44912, 44916, 44920, 44924, 44928, 44932, - 44936, 44940, 44944, 44948, 44953, 44958, 44963, 44968, 44973, 44978, - 44987, 44996, 45005, 45014, 45023, 45032, 45041, 45050, 45057, 45065, - 45073, 45080, 45087, 45095, 45103, 45110, 45117, 45125, 45133, 45140, - 45147, 45155, 45163, 45170, 45177, 45185, 45194, 45203, 45211, 45220, - 45229, 45236, 45243, 45251, 45260, 45269, 45277, 45286, 45295, 45302, - 45309, 45318, 45327, 45335, 45343, 45352, 45361, 45368, 45375, 45384, - 45393, 45401, 45409, 45418, 45427, 45434, 45441, 45450, 45459, 45467, - 45476, 45485, 45493, 45503, 45513, 45523, 45533, 45542, 45551, 45560, - 45569, 45576, 45584, 45592, 45600, 45608, 45613, 45618, 45627, 45635, - 45642, 45651, 45659, 45666, 45675, 45683, 45690, 45699, 45707, 45714, - 45723, 45731, 45738, 45747, 45755, 45762, 45771, 45779, 45786, 45795, - 45803, 45810, 45819, 45827, 45834, 45843, 45852, 45861, 45870, 45884, - 45898, 45905, 45910, 45915, 45920, 45925, 45930, 45935, 45940, 45945, - 45953, 45961, 45969, 45977, 45982, 45989, 45996, 46003, 46008, 46016, - 46023, 46031, 46035, 46042, 46048, 46055, 46059, 46065, 46071, 46077, - 46081, 46084, 46088, 46092, 46099, 46105, 46111, 46117, 46123, 46137, - 46147, 46161, 46175, 46181, 46191, 46205, 46208, 46211, 46218, 46226, - 46231, 46236, 46244, 46256, 46268, 46276, 46280, 46284, 46287, 46290, - 46294, 46298, 46301, 46304, 46309, 46314, 46320, 46326, 46331, 46336, - 46342, 46348, 46353, 46358, 46363, 46368, 46374, 46380, 46385, 46390, - 46396, 46402, 46407, 46412, 46415, 46418, 46427, 46429, 46431, 46434, - 46438, 46444, 46446, 46449, 46456, 46463, 46471, 46479, 46489, 46503, - 46508, 46513, 46517, 46522, 46530, 46538, 46547, 46556, 46565, 46574, - 46579, 46584, 46590, 46596, 46602, 46608, 46611, 46617, 46623, 46633, - 46643, 46651, 46659, 46668, 46677, 46681, 46689, 46697, 46705, 46713, - 46722, 46731, 46740, 46749, 46754, 46759, 46764, 46769, 46774, 46780, - 46786, 46791, 46797, 46799, 46801, 46803, 46805, 46808, 46811, 46813, - 46815, 46817, 46821, 46825, 46827, 46829, 46832, 46835, 46839, 46845, - 46851, 46853, 46860, 46864, 46869, 46874, 46876, 46886, 46892, 46898, - 46904, 46910, 46916, 46922, 46927, 46930, 46933, 46936, 46938, 46940, - 46944, 46948, 46953, 46958, 46963, 46966, 46970, 46975, 46978, 46982, - 46987, 46992, 46997, 47002, 47007, 47012, 47017, 47022, 47027, 47032, - 47037, 47042, 47048, 47054, 47060, 47062, 47065, 47067, 47070, 47072, - 47074, 47076, 47078, 47080, 47082, 47084, 47086, 47088, 47090, 47092, - 47094, 47096, 47098, 47100, 47102, 47104, 47109, 47114, 47119, 47124, - 47129, 47134, 47139, 47144, 47149, 47154, 47159, 47164, 47169, 47174, - 47179, 47184, 47189, 47194, 47199, 47204, 47208, 47212, 47216, 47222, - 47228, 47233, 47238, 47243, 47248, 47253, 47258, 47266, 47274, 47282, - 47290, 47298, 47306, 47314, 47322, 47328, 47333, 47338, 47343, 47346, - 47350, 47354, 47358, 47362, 47366, 47370, 47377, 47384, 47392, 47400, - 47405, 47410, 47417, 47424, 47431, 47438, 47441, 47444, 47449, 47451, - 47455, 47460, 47462, 47464, 47466, 47468, 47473, 47476, 47478, 47483, - 47490, 47497, 47500, 47504, 47509, 47514, 47522, 47528, 47534, 47546, - 47553, 47560, 47565, 47570, 47576, 47579, 47582, 47587, 47589, 47593, - 47595, 47597, 47599, 47601, 47603, 47605, 47610, 47612, 47614, 47616, - 47618, 47622, 47624, 47627, 47632, 47637, 47642, 47647, 47653, 47659, - 47661, 47664, 47671, 47678, 47685, 47692, 47696, 47700, 47702, 47704, - 47708, 47714, 47719, 47721, 47725, 47734, 47742, 47750, 47756, 47762, - 47767, 47773, 47778, 47781, 47795, 47798, 47803, 47808, 47814, 47824, - 47826, 47832, 47838, 47842, 47849, 47853, 47855, 47857, 47861, 47867, - 47872, 47878, 47880, 47886, 47888, 47894, 47896, 47898, 47903, 47905, - 47909, 47914, 47916, 47921, 47926, 47930, 47937, 0, 47947, 47953, 47956, - 47962, 47965, 47970, 47975, 47979, 47981, 47983, 47987, 47991, 47995, - 47999, 48004, 48006, 48011, 48014, 48017, 48020, 48024, 48028, 48033, - 48037, 48042, 48047, 48051, 48056, 48062, 48065, 48071, 48076, 48080, - 48085, 48091, 48097, 48104, 48110, 48117, 48124, 48126, 48133, 48137, - 48143, 48149, 48154, 48160, 48164, 48169, 48172, 48177, 48183, 48190, - 48198, 48205, 48214, 48224, 48231, 48237, 48241, 48248, 48253, 48262, - 48265, 48268, 48277, 48287, 48294, 48296, 48302, 48307, 48309, 48312, - 48316, 48324, 48333, 48336, 48341, 48346, 48354, 48362, 48370, 48378, - 48384, 48390, 48396, 48404, 48409, 48412, 48416, 48419, 48431, 48441, - 48452, 48461, 48472, 48482, 48491, 48497, 48505, 48509, 48517, 48521, - 48529, 48536, 48543, 48552, 48561, 48571, 48581, 48591, 48601, 48610, - 48619, 48629, 48639, 48648, 48657, 48663, 48669, 48675, 48681, 48687, - 48693, 48699, 48705, 48711, 48718, 48724, 48730, 48736, 48742, 48748, - 48754, 48760, 48766, 48772, 48779, 48786, 48793, 48800, 48807, 48814, - 48821, 48828, 48835, 48842, 48850, 48855, 48858, 48862, 48866, 48872, - 48875, 48881, 48887, 48892, 48896, 48901, 48907, 48914, 48917, 48924, - 48931, 48935, 48944, 48953, 48958, 48964, 48969, 48974, 48981, 48988, - 48996, 49004, 49013, 49017, 49026, 49031, 49035, 49042, 49046, 49053, - 49061, 49066, 49074, 49078, 49083, 49087, 49092, 49096, 49101, 49106, - 49115, 49117, 49120, 49123, 49130, 49137, 49142, 49150, 49156, 49162, - 49167, 49170, 49175, 49180, 49185, 49193, 49197, 49204, 49212, 49220, - 49225, 49230, 49236, 49241, 49246, 49252, 49257, 49260, 49264, 49268, - 49275, 49284, 49289, 49298, 49307, 49313, 49319, 49324, 49329, 49334, - 49339, 49345, 49351, 49359, 49367, 49373, 49379, 49384, 49389, 49396, - 49403, 49409, 49412, 49415, 49419, 49423, 49427, 49432, 49438, 49444, - 49451, 49458, 49463, 49467, 49471, 49475, 49479, 49483, 49487, 49491, - 49495, 49499, 49503, 49507, 49511, 49515, 49519, 49523, 49527, 49531, - 49535, 49539, 49543, 49547, 49551, 49555, 49559, 49563, 49567, 49571, - 49575, 49579, 49583, 49587, 49591, 49595, 49599, 49603, 49607, 49611, - 49615, 49619, 49623, 49627, 49631, 49635, 49639, 49643, 49647, 49651, - 49655, 49659, 49663, 49667, 49671, 49675, 49679, 49683, 49687, 49691, - 49695, 49699, 49703, 49707, 49711, 49715, 49719, 49723, 49727, 49731, - 49735, 49739, 49743, 49747, 49751, 49755, 49759, 49763, 49767, 49771, - 49775, 49779, 49783, 49787, 49791, 49795, 49799, 49803, 49807, 49811, - 49815, 49819, 49823, 49827, 49831, 49835, 49839, 49843, 49847, 49851, - 49855, 49859, 49863, 49867, 49871, 49875, 49879, 49883, 49887, 49891, - 49895, 49899, 49903, 49907, 49911, 49915, 49919, 49923, 49927, 49931, - 49935, 49939, 49943, 49947, 49951, 49955, 49959, 49963, 49967, 49971, - 49975, 49979, 49983, 49987, 49991, 49995, 49999, 50003, 50007, 50011, - 50015, 50019, 50023, 50027, 50031, 50035, 50039, 50043, 50047, 50051, - 50055, 50059, 50063, 50067, 50071, 50075, 50079, 50083, 50087, 50091, - 50095, 50099, 50103, 50107, 50111, 50115, 50119, 50123, 50127, 50131, - 50135, 50139, 50143, 50147, 50151, 50155, 50159, 50163, 50167, 50171, - 50175, 50179, 50183, 50187, 50191, 50195, 50199, 50203, 50207, 50211, - 50215, 50219, 50223, 50227, 50231, 50235, 50239, 50243, 50247, 50251, - 50255, 50259, 50263, 50267, 50271, 50275, 50279, 50283, 50287, 50291, - 50295, 50299, 50303, 50307, 50311, 50315, 50319, 50323, 50327, 50331, - 50335, 50339, 50343, 50347, 50351, 50355, 50359, 50363, 50367, 50371, - 50375, 50379, 50383, 50387, 50391, 50395, 50399, 50403, 50407, 50411, - 50415, 50419, 50423, 50427, 50431, 50435, 50439, 50443, 50447, 50451, - 50455, 50459, 50463, 50467, 50471, 50475, 50479, 50483, 50487, 50494, - 50502, 50508, 50514, 50521, 50528, 50534, 50540, 50546, 50552, 50557, - 50562, 50567, 50572, 50578, 50584, 50592, 50599, 50605, 50611, 50619, - 50628, 50635, 50645, 50656, 50659, 50662, 50666, 50670, 50677, 50684, - 50695, 50706, 50716, 50726, 50733, 50740, 50747, 50754, 50765, 50776, - 50787, 50798, 50808, 50818, 50830, 50842, 50853, 50864, 50876, 50888, - 50897, 50907, 50917, 50928, 50939, 50946, 50953, 50960, 50967, 50977, - 50987, 50995, 51003, 51010, 51017, 51024, 51031, 51038, 51043, 51048, - 51054, 51062, 51072, 51082, 51092, 51102, 51112, 51122, 51132, 51142, - 51152, 51162, 51172, 51183, 51194, 51204, 51214, 51225, 51236, 51246, - 51256, 51267, 51278, 51288, 51298, 51309, 51320, 51336, 51355, 51371, - 51390, 51406, 51422, 51438, 51454, 51465, 51477, 51488, 51500, 51519, - 51538, 51546, 51552, 51559, 51566, 51573, 51580, 51585, 51591, 51596, - 51601, 51607, 51612, 51617, 51622, 51627, 51632, 51639, 51644, 51651, - 51656, 51661, 51665, 51669, 51676, 51683, 51690, 51697, 51704, 51711, - 51724, 51737, 51750, 51763, 51771, 51779, 51785, 51791, 51798, 51805, - 51812, 51819, 51823, 51828, 51836, 51844, 51852, 51859, 51863, 51871, - 51879, 51883, 51887, 51892, 51899, 51907, 51915, 51934, 51953, 51972, - 51991, 52010, 52029, 52048, 52067, 52073, 52080, 52089, 52097, 52105, - 52110, 52113, 52116, 52121, 52124, 52143, 52150, 52156, 52162, 52166, - 52169, 52172, 52175, 52187, 52200, 52207, 52214, 52217, 52221, 52224, - 52229, 52234, 52239, 52245, 52254, 52261, 52268, 52276, 52283, 52290, - 52293, 52299, 52305, 52308, 52311, 52316, 52321, 52327, 52333, 52337, - 52342, 52349, 52353, 52359, 52363, 52367, 52375, 52387, 52396, 52400, - 52402, 52411, 52420, 52426, 52429, 52435, 52441, 52446, 52451, 52456, - 52461, 52466, 52471, 52473, 52479, 52484, 52491, 52495, 52501, 52504, - 52508, 52515, 52522, 52524, 52526, 52532, 52538, 52544, 52553, 52562, - 52569, 52576, 52582, 52588, 52593, 52598, 52603, 52609, 52615, 52620, - 52627, 52631, 52635, 52648, 52661, 52673, 52682, 52688, 52695, 52700, - 52705, 52710, 52715, 52720, 52722, 52729, 52736, 52743, 52750, 52757, - 52765, 52771, 52776, 52782, 52788, 52794, 52801, 52807, 52815, 52823, - 52831, 52839, 52846, 52852, 52858, 52867, 52871, 52880, 52889, 52898, - 52906, 52910, 52916, 52923, 52930, 52934, 52940, 52947, 52952, 52957, - 52963, 52968, 52973, 52980, 52987, 52992, 52997, 53005, 53013, 53023, - 53033, 53040, 53047, 53051, 53055, 53067, 53073, 53079, 53084, 53089, - 53096, 53103, 53109, 53115, 53124, 53132, 53140, 53147, 53154, 53161, - 53167, 53174, 53180, 53187, 53194, 53201, 53208, 53214, 53219, 53228, - 53238, 53245, 53254, 53260, 53265, 53270, 53280, 53286, 53292, 53298, - 53306, 53311, 53318, 53325, 53336, 53343, 53350, 53357, 53364, 53371, - 53378, 53385, 53397, 53409, 53420, 53431, 53444, 53457, 53462, 53467, - 53476, 53485, 53492, 53499, 53508, 53517, 53525, 53533, 53541, 53549, - 53559, 53569, 53583, 53597, 53605, 53613, 53625, 53637, 53645, 53653, - 53663, 53673, 53678, 53683, 53692, 53701, 53706, 53711, 53719, 53725, - 53731, 53739, 53747, 53760, 53773, 53777, 53781, 53788, 53795, 53802, - 53810, 53818, 53827, 53836, 53842, 53848, 53855, 53862, 53869, 53876, - 53885, 53894, 53897, 53900, 53905, 53910, 53916, 53922, 53929, 53936, - 53946, 53956, 53963, 53970, 53978, 53986, 53994, 54002, 54010, 54018, - 54024, 54030, 54034, 54038, 54045, 54052, 54057, 54062, 54067, 54072, - 54078, 54092, 54099, 54106, 54110, 54112, 54114, 54119, 54124, 54129, - 54134, 54142, 54149, 54156, 54164, 54176, 54184, 54192, 54203, 54207, - 54211, 54217, 54225, 54238, 54245, 54252, 54259, 54264, 54271, 54280, - 54288, 54294, 54300, 54306, 54315, 54324, 54332, 54341, 54346, 54349, - 54354, 54360, 54366, 54372, 54378, 54382, 54385, 54389, 54393, 54399, - 54405, 54411, 54417, 54421, 54425, 54432, 54439, 54446, 54453, 54460, - 54467, 54477, 54487, 54494, 54501, 54509, 54517, 54521, 54526, 54531, - 54537, 54543, 54546, 54549, 54552, 54555, 54559, 54564, 54569, 54574, - 54579, 54584, 54588, 54592, 54596, 54600, 54604, 54608, 54612, 54618, - 54622, 54628, 54633, 54640, 54648, 54655, 54663, 54670, 54678, 54687, - 54694, 54704, 54715, 54721, 54730, 54736, 54745, 54754, 54760, 54766, - 54770, 54774, 54783, 54792, 54799, 54806, 54815, 0, 0, 0, 54824, 54829, - 54833, 54837, 54842, 54847, 54852, 54860, 54868, 54871, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54875, 54880, 54885, - 54890, 54895, 54900, 54905, 54910, 54915, 54920, 54925, 54931, 54935, - 54940, 54945, 54950, 54955, 54960, 54965, 54970, 54975, 54980, 54985, - 54990, 54995, 55000, 55005, 55010, 55015, 55020, 55025, 55030, 55035, - 55040, 55045, 55051, 55056, 55062, 55071, 55076, 55084, 55091, 55100, - 55105, 55110, 55115, 55121, 0, 55128, 55133, 55138, 55143, 55148, 55153, - 55158, 55163, 55168, 55173, 55178, 55184, 55188, 55193, 55198, 55203, - 55208, 55213, 55218, 55223, 55228, 55233, 55238, 55243, 55248, 55253, - 55258, 55263, 55268, 55273, 55278, 55283, 55288, 55293, 55298, 55304, - 55309, 55315, 55324, 55329, 55337, 55344, 55353, 55358, 55363, 55368, - 55374, 0, 55381, 55389, 55397, 55406, 55413, 55421, 55427, 55436, 55444, - 55452, 55460, 55468, 55476, 55484, 55489, 55496, 55502, 55509, 55517, - 55524, 55531, 55539, 55545, 55551, 55558, 55565, 55575, 55585, 55592, - 55599, 55604, 55614, 55624, 55629, 55634, 55639, 55644, 55649, 55654, - 55659, 55664, 55669, 55674, 55679, 55684, 55689, 55694, 55699, 55704, - 55709, 55714, 55719, 55724, 55729, 55734, 55739, 55744, 55749, 55754, - 55759, 55764, 55769, 55774, 55778, 55782, 55787, 55792, 55797, 55802, - 55807, 55812, 55817, 55822, 55827, 55832, 55837, 55842, 55847, 55852, - 55857, 55862, 55867, 55872, 55879, 55886, 55893, 55900, 55907, 55914, - 55921, 55928, 55935, 55942, 55949, 55956, 55963, 55970, 55975, 55980, - 55987, 55994, 56001, 56008, 56015, 56022, 56029, 56036, 56043, 56050, - 56057, 56064, 56070, 56076, 56082, 56088, 56095, 56102, 56109, 56116, - 56123, 56130, 56137, 56144, 56151, 56158, 56166, 56174, 56182, 56190, - 56198, 56206, 56214, 56222, 56226, 56232, 56238, 56242, 56248, 56254, - 56260, 56267, 56274, 56281, 56288, 56293, 56299, 56305, 56312, 0, 0, 0, - 0, 0, 56319, 56327, 56336, 56345, 56353, 56359, 56364, 56369, 56374, - 56379, 56384, 56389, 56394, 56399, 56404, 56409, 56414, 56419, 56424, - 56429, 56434, 56439, 56444, 56449, 56454, 56459, 56464, 56469, 56474, - 56479, 56484, 56489, 56494, 56499, 56504, 56509, 56514, 56519, 56524, - 56529, 56534, 56539, 56544, 56549, 56554, 0, 56559, 0, 0, 0, 0, 0, 56564, - 0, 0, 56569, 56573, 56578, 56583, 56588, 56593, 56602, 56607, 56612, - 56617, 56622, 56627, 56632, 56637, 56642, 56649, 56654, 56659, 56668, - 56675, 56680, 56685, 56690, 56697, 56702, 56709, 56714, 56719, 56726, - 56733, 56738, 56743, 56748, 56755, 56762, 56767, 56772, 56777, 56782, - 56787, 56794, 56801, 56806, 56811, 56816, 56821, 56826, 56831, 56836, - 56841, 56846, 56851, 56856, 56863, 56868, 56873, 0, 0, 0, 0, 0, 0, 0, - 56878, 56885, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56890, 56895, - 56899, 56903, 56907, 56911, 56915, 56919, 56923, 56927, 56931, 56935, - 56941, 56945, 56949, 56953, 56957, 56961, 56965, 56969, 56973, 56977, - 56981, 56985, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56989, 56993, 56997, 57001, - 57005, 57009, 57013, 0, 57017, 57021, 57025, 57029, 57033, 57037, 57041, - 0, 57045, 57049, 57053, 57057, 57061, 57065, 57069, 0, 57073, 57077, - 57081, 57085, 57089, 57093, 57097, 0, 57101, 57105, 57109, 57113, 57117, - 57121, 57125, 0, 57129, 57133, 57137, 57141, 57145, 57149, 57153, 0, - 57157, 57161, 57165, 57169, 57173, 57177, 57181, 0, 57185, 57189, 57193, - 57197, 57201, 57205, 57209, 0, 57213, 57218, 57223, 57228, 57233, 57238, - 57243, 57247, 57252, 57257, 57262, 57266, 57271, 57276, 57281, 57286, - 57290, 57295, 57300, 57305, 57310, 57315, 57320, 57324, 57329, 57334, - 57341, 57346, 57351, 57357, 57364, 57371, 57380, 57387, 57396, 57400, - 57404, 57410, 57416, 57422, 57430, 57436, 57440, 57444, 57448, 57454, - 57460, 57464, 57466, 57470, 57476, 57478, 57482, 57486, 57490, 57496, - 57501, 57505, 57509, 57514, 57520, 57525, 57530, 57535, 57540, 57547, - 57554, 57559, 57564, 57569, 57574, 57579, 57584, 57588, 57592, 57599, - 57606, 57612, 57616, 57621, 57623, 57627, 57635, 57639, 57643, 57647, - 57651, 57657, 57663, 57667, 57673, 57677, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57681, 57685, 57689, 57694, 57699, 57704, - 57708, 57712, 57716, 57721, 57726, 57730, 57734, 57738, 57742, 57747, - 57752, 57757, 57762, 57766, 57770, 57775, 57780, 57785, 57790, 57794, 0, - 57798, 57802, 57806, 57810, 57814, 57818, 57822, 57827, 57832, 57836, - 57841, 57846, 57855, 57859, 57863, 57867, 57874, 57878, 57883, 57888, - 57892, 57896, 57902, 57907, 57912, 57917, 57922, 57926, 57930, 57934, - 57938, 57942, 57947, 57952, 57956, 57960, 57965, 57970, 57975, 57979, - 57983, 57988, 57993, 57999, 58005, 58009, 58015, 58021, 58025, 58031, - 58037, 58042, 58047, 58051, 58057, 58061, 58065, 58071, 58077, 58082, - 58087, 58091, 58095, 58103, 58109, 58115, 58121, 58126, 58131, 58136, - 58142, 58146, 58152, 58156, 58160, 58166, 58172, 58178, 58184, 58190, - 58196, 58202, 58208, 58214, 58220, 58226, 58232, 58236, 58242, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 58248, 58251, 58255, 58259, 58263, 58267, - 58270, 58273, 58277, 58281, 58285, 58289, 58292, 58297, 58301, 58305, - 58309, 58314, 58318, 58322, 58326, 58330, 58336, 58342, 58346, 58350, - 58354, 58358, 58362, 58366, 58370, 58374, 58378, 58382, 58386, 58392, - 58396, 58400, 58404, 58408, 58412, 58416, 58420, 58424, 58428, 58432, - 58436, 58440, 58444, 58448, 58452, 58456, 58462, 58468, 58473, 58478, - 58482, 58486, 58490, 58494, 58498, 58502, 58506, 58510, 58514, 58518, - 58522, 58526, 58530, 58534, 58538, 58542, 58546, 58550, 58554, 58558, - 58562, 58566, 58570, 58574, 58580, 58584, 58588, 58592, 58596, 58600, - 58604, 58608, 58612, 58617, 58624, 58628, 58632, 58636, 58640, 58644, - 58648, 58652, 58656, 58660, 58664, 58668, 58672, 58679, 58683, 58689, - 58693, 58697, 58701, 58705, 58709, 58712, 58716, 58720, 58724, 58728, - 58732, 58736, 58740, 58744, 58748, 58752, 58756, 58760, 58764, 58768, - 58772, 58776, 58780, 58784, 58788, 58792, 58796, 58800, 58804, 58808, - 58812, 58816, 58820, 58824, 58828, 58832, 58836, 58840, 58846, 58850, - 58854, 58858, 58862, 58866, 58870, 58874, 58878, 58882, 58886, 58890, - 58894, 58898, 58902, 58906, 58910, 58914, 58918, 58922, 58926, 58930, - 58934, 58938, 58942, 58946, 58950, 58954, 58962, 58966, 58970, 58974, - 58978, 58982, 58988, 58992, 58996, 59000, 59004, 59008, 59012, 59016, - 59020, 59024, 59028, 59032, 59036, 59040, 59046, 59050, 59054, 59058, - 59062, 59066, 59070, 59074, 59078, 59082, 59086, 59090, 59094, 59098, - 59102, 59106, 59110, 59114, 59118, 59122, 59126, 59130, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59134, 59143, - 59151, 59163, 59174, 59182, 59191, 59200, 59210, 59222, 59234, 59246, 0, - 0, 0, 0, 59252, 59255, 59258, 59263, 59266, 59273, 59277, 59281, 59285, - 59289, 59293, 59298, 59303, 59307, 59311, 59316, 59321, 59326, 59331, - 59334, 59337, 59343, 59349, 59354, 59359, 59366, 59373, 59377, 59381, - 59385, 59393, 59399, 59406, 59411, 59416, 59421, 59426, 59431, 59436, - 59441, 59446, 59451, 59456, 59461, 59466, 59471, 59476, 59482, 59487, - 59491, 59497, 59508, 59518, 59533, 59543, 59547, 59557, 59563, 59569, - 59575, 59580, 59583, 59588, 59592, 0, 59598, 59602, 59605, 59609, 59612, - 59616, 59619, 59623, 59626, 59630, 59633, 59636, 59640, 59644, 59648, - 59652, 59656, 59660, 59664, 59668, 59672, 59675, 59679, 59683, 59687, - 59691, 59695, 59699, 59703, 59707, 59711, 59715, 59719, 59723, 59727, - 59732, 59736, 59740, 59744, 59748, 59751, 59755, 59758, 59762, 59766, - 59770, 59774, 59777, 59781, 59784, 59788, 59792, 59796, 59800, 59804, - 59808, 59812, 59816, 59820, 59824, 59828, 59832, 59835, 59839, 59843, - 59847, 59851, 59855, 59858, 59863, 59867, 59872, 59876, 59879, 59883, - 59887, 59891, 59895, 59900, 59904, 59908, 59912, 59916, 59920, 59924, - 59928, 0, 0, 59933, 59941, 59949, 59956, 59963, 59967, 59973, 59978, - 59983, 59987, 59990, 59994, 59997, 60001, 60004, 60008, 60011, 60015, - 60018, 60021, 60025, 60029, 60033, 60037, 60041, 60045, 60049, 60053, - 60057, 60060, 60064, 60068, 60072, 60076, 60080, 60084, 60088, 60092, - 60096, 60100, 60104, 60108, 60112, 60117, 60121, 60125, 60129, 60133, - 60136, 60140, 60143, 60147, 60151, 60155, 60159, 60162, 60166, 60169, - 60173, 60177, 60181, 60185, 60189, 60193, 60197, 60201, 60205, 60209, - 60213, 60217, 60220, 60224, 60228, 60232, 60236, 60240, 60243, 60248, - 60252, 60257, 60261, 60264, 60268, 60272, 60276, 60280, 60285, 60289, - 60293, 60297, 60301, 60305, 60309, 60313, 60318, 60322, 60326, 60330, - 60334, 60339, 60346, 60350, 60356, 0, 0, 0, 0, 0, 60361, 60366, 60371, - 60375, 60380, 60385, 60390, 60395, 60399, 60404, 60409, 60414, 60419, - 60424, 60429, 60434, 60439, 60444, 60448, 60453, 60458, 60463, 60467, - 60471, 60475, 60480, 60485, 60490, 60495, 60500, 60505, 60510, 60515, - 60520, 60525, 60529, 60533, 60538, 60543, 60548, 60553, 0, 0, 0, 60558, - 60562, 60566, 60570, 60574, 60578, 60582, 60586, 60590, 60594, 60598, - 60602, 60606, 60610, 60614, 60618, 60622, 60626, 60630, 60634, 60638, - 60642, 60646, 60650, 60654, 60658, 60662, 60666, 60670, 60674, 60678, - 60681, 60685, 60688, 60692, 60696, 60699, 60703, 60707, 60710, 60714, - 60718, 60722, 60726, 60729, 60733, 60737, 60741, 60745, 60749, 60753, - 60756, 60759, 60763, 60767, 60771, 60775, 60779, 60783, 60787, 60791, - 60795, 60799, 60803, 60807, 60811, 60815, 60819, 60823, 60827, 60831, - 60835, 60839, 60843, 60847, 60851, 60855, 60859, 60863, 60867, 60871, - 60875, 60879, 60883, 60887, 60891, 60895, 60899, 60903, 60907, 60911, - 60915, 60919, 60923, 0, 60927, 60933, 60939, 60944, 60949, 60954, 60960, - 60966, 60972, 60978, 60984, 60990, 60996, 61002, 61008, 61014, 61020, - 61025, 61030, 61035, 61040, 61045, 61050, 61055, 61060, 61065, 61070, - 61075, 61080, 61085, 61090, 61095, 61100, 61105, 61110, 61115, 61120, - 61126, 61132, 61138, 61144, 61149, 61154, 0, 0, 0, 0, 0, 61159, 61164, - 61169, 61174, 61179, 61184, 61189, 61194, 61199, 61204, 61209, 61214, - 61219, 61224, 61229, 61234, 61239, 61244, 61249, 61254, 61259, 61264, - 61269, 61274, 61279, 61284, 61289, 61294, 61299, 61304, 61309, 61314, - 61319, 61324, 61329, 61334, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61339, - 61344, 61349, 61354, 61358, 61363, 61367, 61372, 61377, 61382, 61387, - 61392, 61396, 61401, 61406, 61411, 61416, 61420, 61424, 61428, 61432, - 61436, 61440, 61444, 61448, 61452, 61456, 61460, 61464, 61468, 61472, - 61477, 61482, 61487, 61492, 61497, 61502, 61507, 61512, 61517, 61522, - 61527, 61532, 61537, 61542, 61547, 61553, 0, 61560, 61563, 61566, 61569, - 61572, 61575, 61578, 61581, 61584, 61587, 61591, 61595, 61599, 61603, - 61607, 61611, 61615, 61619, 61623, 61627, 61631, 61635, 61639, 61643, - 61647, 61651, 61655, 61659, 61663, 61667, 61671, 61675, 61679, 61683, - 61687, 61691, 61695, 61699, 61703, 61707, 61711, 61720, 61729, 61738, - 61747, 61756, 61765, 61774, 61783, 61786, 61791, 61796, 61801, 61806, - 61811, 61816, 61821, 61826, 61831, 61835, 61840, 61845, 61850, 61855, - 61860, 61864, 61868, 61872, 61876, 61880, 61884, 61888, 61892, 61896, - 61900, 61904, 61908, 61912, 61916, 61921, 61926, 61931, 61936, 61941, - 61946, 61951, 61956, 61961, 61966, 61971, 61976, 61981, 61986, 61992, - 61998, 62003, 62008, 62011, 62014, 62017, 62020, 62023, 62026, 62029, - 62032, 62035, 62039, 62043, 62047, 62051, 62055, 62059, 62063, 62067, - 62071, 62075, 62079, 62083, 62087, 62091, 62095, 62099, 62103, 62107, - 62111, 62115, 62119, 62123, 62127, 62131, 62135, 62139, 62143, 62147, - 62151, 62155, 62159, 62163, 62167, 62171, 62175, 62179, 62183, 62187, - 62191, 62195, 62200, 62205, 62210, 62215, 62219, 62224, 62229, 62234, - 62239, 62244, 62249, 62254, 62259, 62264, 62268, 62275, 62282, 62289, - 62296, 62303, 62310, 62317, 62324, 62331, 62338, 62345, 62352, 62355, - 62358, 62361, 62366, 62369, 62372, 62375, 62378, 62381, 62384, 62388, - 62392, 62396, 62400, 62403, 62407, 62411, 62415, 62419, 62423, 62427, - 62431, 62435, 62438, 62441, 62445, 62449, 62453, 62457, 62460, 62464, - 62468, 62472, 62476, 62479, 62483, 62487, 62491, 62495, 62498, 62502, - 62506, 62509, 62513, 62517, 62521, 62525, 62529, 62533, 62537, 0, 62541, - 62544, 62547, 62550, 62553, 62556, 62559, 62562, 62565, 62568, 62571, - 62574, 62577, 62580, 62583, 62586, 62589, 62592, 62595, 62598, 62601, - 62604, 62607, 62610, 62613, 62616, 62619, 62622, 62625, 62628, 62631, - 62634, 62637, 62640, 62643, 62646, 62649, 62652, 62655, 62658, 62661, - 62664, 62667, 62670, 62673, 62676, 62679, 62682, 62685, 62688, 62691, - 62694, 62697, 62700, 62703, 62706, 62709, 62712, 62715, 62718, 62721, - 62724, 62727, 62730, 62733, 62736, 62739, 62742, 62745, 62748, 62751, - 62754, 62757, 62760, 62763, 62766, 62769, 62772, 62775, 62778, 62781, - 62784, 62787, 62790, 62793, 62796, 62799, 62802, 62805, 62814, 62822, - 62830, 62838, 62846, 62854, 62862, 62870, 62878, 62886, 62895, 62904, - 62913, 62922, 62931, 62940, 62949, 62958, 62967, 62976, 62985, 62994, - 63003, 63012, 63021, 63024, 63027, 63030, 63032, 63035, 63038, 63041, - 63046, 63051, 63054, 63061, 63068, 63075, 63082, 63085, 63090, 63092, - 63096, 63098, 63100, 63103, 63106, 63109, 63112, 63115, 63118, 63121, - 63126, 63131, 63134, 63137, 63140, 63143, 63146, 63149, 63152, 63156, - 63159, 63162, 63165, 63168, 63171, 63175, 63178, 63181, 63184, 63189, - 63194, 63199, 63204, 63209, 63214, 63219, 63224, 63230, 63238, 63240, - 63243, 63246, 63249, 63252, 63258, 63266, 63269, 63272, 63277, 63280, - 63283, 63286, 63291, 63294, 63297, 63302, 63305, 63308, 63313, 63316, - 63319, 63324, 63329, 63334, 63337, 63340, 63343, 63346, 63352, 63355, - 63358, 63361, 63363, 63366, 63369, 63372, 63377, 63380, 63383, 63386, - 63389, 63392, 63397, 63400, 63403, 63406, 63409, 63412, 63415, 63418, - 63421, 63424, 63429, 63433, 63441, 63449, 63457, 63465, 63473, 63481, - 63489, 63497, 63505, 63514, 63523, 63532, 63541, 63550, 63559, 63568, - 63577, 63586, 63595, 63604, 63613, 63622, 63631, 63640, 63649, 63658, - 63667, 63676, 63685, 63694, 63703, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 63706, 63715, 63724, 63735, 63742, 63747, 63752, 63759, 63766, - 63772, 63777, 63782, 63787, 63792, 63799, 63804, 63809, 63814, 63825, - 63830, 63835, 63842, 63847, 63854, 63859, 63864, 63871, 63878, 63885, - 63894, 63903, 63908, 63913, 63918, 63925, 63930, 63940, 63947, 63952, - 63957, 63962, 63967, 63972, 63977, 63986, 63993, 64000, 64005, 64012, - 64017, 64024, 64033, 64044, 64049, 64058, 64063, 64070, 64079, 64088, - 64093, 64098, 64105, 64111, 64118, 64125, 64129, 64133, 64136, 64140, - 64144, 64148, 64152, 64156, 64160, 64164, 64167, 64171, 64175, 64179, - 64183, 64187, 64191, 64194, 64198, 64202, 64205, 64209, 64213, 64217, - 64221, 64225, 64229, 64233, 64237, 64241, 64245, 64249, 64253, 64257, - 64261, 64265, 64269, 64273, 64277, 64281, 64285, 64289, 64293, 64297, - 64301, 64305, 64309, 64313, 64317, 64321, 64325, 64329, 64333, 64337, - 64341, 64345, 64349, 64353, 64357, 64361, 64365, 64369, 64373, 64377, - 64381, 64384, 64388, 64392, 64396, 64400, 64404, 64408, 64412, 64416, - 64420, 64424, 64428, 64432, 64436, 64440, 64444, 64448, 64452, 64456, - 64460, 64464, 64468, 64472, 64476, 64480, 64484, 64488, 64492, 64496, - 64500, 64504, 64508, 64512, 64516, 64520, 64524, 64528, 64532, 64536, - 64540, 64544, 64548, 64552, 64556, 64560, 64564, 64568, 64572, 64576, - 64580, 64584, 64588, 64592, 64596, 64600, 64604, 64608, 64612, 64616, - 64620, 64624, 64628, 64632, 64636, 64640, 64644, 64648, 64652, 64656, - 64660, 64664, 64668, 64672, 64676, 64680, 64684, 64688, 64692, 64696, - 64700, 64704, 64708, 64712, 64716, 64720, 64724, 64728, 64732, 64736, - 64740, 64744, 64748, 64752, 64756, 64760, 64764, 64768, 64772, 64776, - 64780, 64784, 64788, 64792, 64796, 64800, 64804, 64808, 64812, 64816, - 64820, 64824, 64828, 64832, 64836, 64840, 64844, 64848, 64852, 64855, - 64859, 64863, 64867, 64871, 64875, 64879, 64883, 64887, 64891, 64895, - 64899, 64903, 64907, 64911, 64915, 64919, 64923, 64927, 64931, 64935, - 64939, 64943, 64947, 64951, 64955, 64959, 64963, 64967, 64971, 64975, - 64979, 64983, 64987, 64991, 64995, 64999, 65003, 65007, 65011, 65015, - 65019, 65023, 65027, 65031, 65035, 65039, 65043, 65047, 65051, 65055, - 65059, 65063, 65067, 65071, 65075, 65079, 65083, 65087, 65091, 65095, - 65099, 65103, 65107, 65111, 65115, 65119, 65123, 65127, 65131, 65135, - 65139, 65143, 65147, 65151, 65155, 65159, 65163, 65167, 65171, 65175, - 65179, 65183, 65187, 65191, 65195, 65199, 65203, 65207, 65211, 65215, - 65219, 65223, 65227, 65231, 65235, 65239, 65243, 65247, 65251, 65255, - 65259, 65263, 65267, 65271, 65275, 65279, 65283, 65287, 65291, 65295, - 65299, 65303, 65307, 65311, 65315, 65318, 65322, 65326, 65330, 65334, - 65338, 65342, 65346, 65350, 65354, 65358, 65362, 65366, 65370, 65374, - 65378, 65382, 65386, 65390, 65394, 65398, 65402, 65406, 65410, 65414, - 65418, 65422, 65426, 65430, 65434, 65438, 65442, 65446, 65450, 65454, - 65458, 65462, 65466, 65470, 65474, 65478, 65482, 65486, 65490, 65494, - 65498, 65502, 65506, 65510, 65514, 65518, 65522, 65526, 65530, 65534, - 65538, 65542, 65546, 65550, 65554, 65558, 65562, 65566, 65570, 65574, - 65578, 65582, 65586, 65590, 65594, 65598, 65602, 65606, 65610, 65614, - 65618, 65622, 65626, 65630, 65634, 65638, 65642, 65646, 65650, 65654, - 65658, 65662, 65666, 65670, 65674, 65677, 65681, 65685, 65689, 65693, - 65697, 65701, 65705, 65709, 65713, 65717, 65721, 65725, 65729, 65733, - 65737, 65741, 65745, 65749, 65753, 65757, 65761, 65765, 65769, 65773, - 65777, 65781, 65785, 65789, 65793, 65797, 65801, 65805, 65809, 65813, - 65817, 65821, 65825, 65829, 65833, 65837, 65841, 65845, 65849, 65853, - 65857, 65861, 65865, 65869, 65873, 65877, 65881, 65885, 65889, 65893, - 65897, 65901, 65905, 65909, 65913, 65917, 65921, 65925, 65929, 65933, - 65937, 65941, 65945, 65949, 65953, 65957, 65961, 65965, 65969, 65973, - 65977, 65981, 65985, 65989, 65993, 65997, 66001, 66005, 66009, 66013, - 66017, 66021, 66025, 66029, 66033, 66037, 66041, 66045, 66049, 66053, - 66057, 66061, 66065, 66069, 66073, 66077, 66081, 66085, 66089, 66093, - 66097, 66101, 66105, 66109, 66113, 66117, 66121, 66125, 66129, 66133, - 66137, 66141, 66145, 66149, 66153, 66157, 66161, 66165, 66169, 66172, - 66176, 66180, 66184, 66188, 66192, 66196, 66200, 66204, 66208, 66212, - 66216, 66220, 66224, 66228, 66232, 66236, 66240, 66244, 66248, 66252, - 66256, 66260, 66264, 66268, 66272, 66276, 66280, 66284, 66288, 66292, - 66296, 66300, 66304, 66308, 66312, 66316, 66320, 66324, 66328, 66332, - 66336, 66340, 66344, 66348, 66352, 66356, 66360, 66364, 66368, 66372, - 66376, 66380, 66384, 66388, 66392, 66396, 66400, 66404, 66408, 66412, - 66416, 66420, 66424, 66428, 66432, 66436, 66440, 66444, 66448, 66452, - 66456, 66460, 66464, 66468, 66472, 66476, 66480, 66484, 66488, 66492, - 66496, 66500, 66504, 66508, 66512, 66516, 66520, 66524, 66528, 66532, - 66536, 66540, 66544, 66548, 66552, 66556, 66560, 66564, 66568, 66572, - 66576, 66580, 66584, 66588, 66592, 66596, 66600, 66604, 66608, 66612, - 66616, 66620, 66624, 66627, 66631, 66635, 66639, 66643, 66647, 66651, - 66655, 66659, 66663, 66667, 66671, 66675, 66679, 66683, 66687, 66691, - 66695, 66699, 66703, 66707, 66711, 66715, 66719, 66723, 66727, 66731, - 66735, 66739, 66743, 66747, 66751, 66755, 66759, 66763, 66767, 66771, - 66775, 66779, 66783, 66787, 66791, 66795, 66799, 66803, 66807, 66811, - 66815, 66819, 66823, 66827, 66831, 66835, 66839, 66843, 66847, 66851, - 66855, 66859, 66863, 66867, 66871, 66875, 66879, 66883, 66887, 66891, - 66895, 66899, 66903, 66907, 66911, 66915, 66919, 66923, 66927, 66931, - 66935, 66939, 66943, 66947, 66951, 66955, 66959, 66963, 66967, 66971, - 66975, 66979, 66983, 66987, 66991, 66995, 66999, 67003, 67007, 67011, - 67015, 67019, 67023, 67027, 67031, 67035, 67039, 67043, 67047, 67051, - 67055, 67059, 67063, 67067, 67071, 67075, 67079, 67083, 67087, 67091, - 67095, 67099, 67103, 67107, 67111, 67115, 67119, 67123, 67127, 67131, - 67135, 67139, 67143, 67147, 67151, 67155, 67159, 67163, 67167, 67171, - 67175, 67179, 67183, 67187, 67191, 67195, 67199, 67203, 67207, 67211, - 67215, 67219, 67223, 67227, 67230, 67234, 67238, 67242, 67246, 67250, - 67254, 67258, 67261, 67265, 67269, 67273, 67277, 67281, 67285, 67289, - 67293, 67297, 67301, 67305, 67309, 67313, 67317, 67321, 67325, 67329, - 67333, 67337, 67341, 67345, 67349, 67353, 67357, 67361, 67365, 67369, - 67373, 67377, 67381, 67385, 67389, 67393, 67397, 67401, 67405, 67409, - 67413, 67417, 67421, 67425, 67429, 67433, 67437, 67441, 67445, 67449, - 67453, 67457, 67461, 67465, 67469, 67473, 67477, 67481, 67485, 67489, - 67493, 67497, 67501, 67505, 67509, 67513, 67517, 67521, 67525, 67529, - 67533, 67537, 67541, 67545, 67549, 67553, 67557, 67561, 67565, 67569, - 67573, 67577, 67581, 67585, 67589, 67593, 67597, 67601, 67605, 67609, - 67613, 67617, 67621, 67625, 67629, 67633, 67637, 67641, 67645, 67649, - 67653, 67657, 67661, 67665, 67669, 67673, 67677, 67681, 67685, 67689, - 67693, 67697, 67701, 67705, 67709, 67713, 67717, 67721, 67725, 67729, - 67733, 67737, 67741, 67745, 67749, 67753, 67757, 67761, 67765, 67769, - 67773, 67777, 67781, 67785, 67789, 67793, 67797, 67801, 67805, 67809, - 67813, 67817, 67821, 67825, 67829, 67833, 67837, 67841, 67845, 67849, - 67853, 67857, 67861, 67865, 67869, 67873, 67877, 67881, 67885, 67889, - 67893, 67897, 67901, 67905, 67909, 67913, 67917, 67921, 67925, 67929, - 67933, 67937, 67941, 67945, 67949, 67953, 67957, 67961, 67965, 67969, - 67973, 67977, 67981, 67985, 67988, 67992, 67996, 68000, 68004, 68008, - 68012, 68016, 68020, 68024, 68028, 68032, 68036, 68040, 68044, 68048, - 68052, 68056, 68060, 68064, 68068, 68072, 68076, 68080, 68084, 68088, - 68092, 68096, 68100, 68104, 68108, 68112, 68116, 68120, 68124, 68128, - 68132, 68136, 68140, 68144, 68148, 68152, 68156, 68160, 68164, 68168, - 68172, 68176, 68180, 68184, 68188, 68192, 68196, 68200, 68204, 68208, - 68212, 68216, 68220, 68224, 68228, 68232, 68236, 68240, 68244, 68248, - 68252, 68256, 68260, 68264, 68268, 68272, 68276, 68280, 68284, 68288, - 68292, 68296, 68300, 68304, 68308, 68312, 68316, 68320, 68324, 68328, - 68332, 68336, 68340, 68344, 68348, 68352, 68356, 68360, 68364, 68368, - 68372, 68376, 68380, 68384, 68388, 68392, 68396, 68400, 68404, 68408, - 68412, 68416, 68420, 68424, 68428, 68432, 68436, 68440, 68444, 68448, - 68452, 68456, 68460, 68464, 68468, 68472, 68476, 68480, 68484, 68488, - 68492, 68496, 68500, 68504, 68508, 68512, 68516, 68520, 68524, 68528, - 68532, 68536, 68540, 68544, 68548, 68552, 68556, 68560, 68564, 68568, - 68572, 68576, 68580, 68584, 68588, 68592, 68596, 68600, 68604, 68608, - 68612, 68616, 68620, 68624, 68628, 68632, 68636, 68640, 68644, 68648, - 68652, 68656, 68660, 68664, 68668, 68672, 68676, 68680, 68684, 68688, - 68692, 68696, 68700, 68704, 68708, 68712, 68716, 68720, 68724, 68728, - 68732, 68736, 68740, 68744, 68748, 68752, 68756, 68760, 68764, 68768, 0, - 0, 0, 68772, 68776, 68780, 68784, 68788, 68792, 68796, 68800, 68804, - 68808, 68812, 68816, 68820, 68824, 68828, 68832, 68836, 68840, 68844, - 68848, 68852, 68856, 68860, 68864, 68868, 68872, 68876, 68880, 68884, - 68888, 68892, 68896, 68900, 68904, 68908, 68912, 68916, 68920, 68924, - 68928, 68932, 68936, 68940, 68944, 68948, 68952, 68956, 68960, 68964, - 68968, 68972, 68976, 68980, 68984, 68988, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68992, 68997, 69001, 69006, 69011, 69016, 69021, 69026, 69030, 69035, - 69040, 69045, 69050, 69055, 69060, 69065, 69069, 69073, 69078, 69082, - 69087, 69092, 69097, 69101, 69106, 69111, 69116, 69121, 69126, 69130, - 69135, 69139, 69144, 69148, 69153, 69157, 69161, 69165, 69170, 69175, - 69180, 69188, 69196, 69204, 69212, 69219, 69227, 69233, 69241, 69245, - 69249, 69253, 69257, 69261, 69265, 69269, 69273, 69277, 69281, 69285, - 69289, 69293, 69297, 69301, 69305, 69309, 69313, 69317, 69321, 69325, - 69329, 69333, 69337, 69341, 69345, 69349, 69353, 69357, 69361, 69365, - 69369, 69373, 69377, 69381, 69385, 69388, 69392, 69396, 69400, 69404, - 69408, 69412, 69416, 69420, 69424, 69428, 69432, 69436, 69440, 69444, - 69448, 69452, 69456, 69460, 69464, 69468, 69472, 69476, 69480, 69484, - 69488, 69492, 69496, 69500, 69504, 69508, 69512, 69516, 69520, 69524, - 69528, 69532, 69535, 69539, 69543, 69546, 69550, 69554, 69558, 69561, - 69565, 69569, 69573, 69577, 69581, 69585, 69589, 69593, 69597, 69601, - 69605, 69609, 69613, 69617, 69620, 69624, 69628, 69631, 69635, 69639, - 69643, 69647, 69651, 69655, 69658, 69661, 69665, 69669, 69673, 69676, - 69679, 69683, 69687, 69691, 69695, 69699, 69703, 69707, 69711, 69715, - 69719, 69723, 69727, 69731, 69735, 69739, 69743, 69747, 69751, 69755, - 69759, 69763, 69767, 69771, 69775, 69779, 69783, 69787, 69791, 69795, - 69799, 69803, 69807, 69811, 69815, 69819, 69823, 69827, 69830, 69834, - 69838, 69842, 69846, 69850, 69854, 69858, 69862, 69866, 69870, 69874, - 69878, 69882, 69886, 69890, 69894, 69898, 69902, 69906, 69910, 69914, - 69918, 69922, 69926, 69930, 69934, 69938, 69942, 69946, 69950, 69954, - 69958, 69962, 69966, 69970, 69974, 69977, 69981, 69985, 69989, 69993, - 69997, 70001, 70005, 70009, 70013, 70017, 70021, 70025, 70029, 70033, - 70037, 70041, 70044, 70048, 70052, 70056, 70060, 70064, 70068, 70072, - 70076, 70080, 70084, 70088, 70092, 70096, 70100, 70104, 70108, 70112, - 70116, 70120, 70124, 70128, 70131, 70135, 70139, 70143, 70147, 70151, - 70155, 70159, 70163, 70167, 70171, 70175, 70179, 70183, 70187, 70191, - 70195, 70199, 70203, 70207, 70211, 70215, 70219, 70223, 70227, 70231, - 70235, 70239, 70243, 70247, 70251, 70255, 70259, 70263, 70267, 70271, - 70275, 70279, 70283, 70287, 70291, 70295, 70299, 70303, 70306, 70311, - 70315, 70321, 70326, 70332, 70336, 70340, 70344, 70348, 70352, 70356, - 70360, 70364, 70368, 70372, 70376, 70380, 70384, 70388, 70391, 70394, - 70397, 70400, 70403, 70406, 70409, 70412, 70415, 70420, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70426, 70431, 70436, 70441, - 70446, 70453, 70460, 70465, 70470, 70475, 70480, 70487, 70494, 70501, - 70508, 70515, 70522, 70532, 70542, 70549, 70556, 70563, 70570, 70576, - 70582, 70591, 70600, 70607, 70614, 70625, 70636, 70641, 70646, 70653, - 70660, 70667, 70674, 70681, 70688, 70695, 70702, 70708, 70714, 70720, - 70726, 70733, 70740, 70745, 70749, 70756, 70763, 70770, 70774, 70781, - 70785, 70790, 70794, 70800, 70805, 70811, 70816, 70820, 70824, 70827, - 70830, 70835, 70840, 70845, 70850, 70855, 70860, 70865, 70870, 70875, - 70880, 70889, 70898, 70903, 70908, 70913, 70918, 70923, 70928, 70933, - 70938, 70943, 70948, 70953, 0, 0, 0, 0, 0, 0, 0, 70958, 70964, 70967, - 70970, 70973, 70977, 70981, 70985, 70989, 70992, 70996, 70999, 71003, - 71006, 71010, 71014, 71018, 71022, 71026, 71030, 71034, 71037, 71041, - 71045, 71049, 71053, 71057, 71061, 71065, 71069, 71073, 71077, 71081, - 71085, 71089, 71093, 71096, 71100, 71104, 71108, 71112, 71116, 71120, - 71124, 71128, 71132, 71136, 71140, 71144, 71148, 71152, 71156, 71160, - 71164, 71168, 71172, 71176, 71180, 71184, 71188, 71192, 71195, 71199, - 71203, 71207, 71211, 71215, 71219, 71223, 71226, 71230, 71234, 71238, - 71242, 71246, 71250, 71254, 71258, 71262, 71266, 71270, 71274, 71279, - 71284, 71287, 71292, 71295, 71298, 71301, 0, 0, 0, 0, 0, 0, 0, 0, 71305, - 71314, 71323, 71332, 71341, 71350, 71359, 71368, 71377, 71385, 71392, - 71400, 71407, 71415, 71425, 71434, 71444, 71453, 71463, 71471, 71478, - 71486, 71493, 71501, 71506, 71511, 71516, 71525, 71531, 71537, 71544, - 71553, 71561, 71569, 71577, 71584, 71591, 71598, 71605, 71610, 71615, - 71620, 71625, 71630, 71635, 71640, 71645, 71653, 71661, 71667, 71673, - 71678, 71683, 71688, 71693, 71698, 71703, 71708, 71713, 71721, 71729, - 71734, 71739, 71749, 71759, 71766, 71773, 71782, 71791, 71803, 71815, - 71821, 71827, 71835, 71843, 71853, 71863, 71870, 71877, 71882, 71887, - 71899, 71911, 71919, 71927, 71937, 71947, 71959, 71971, 71980, 71989, - 71996, 72003, 72010, 72017, 72026, 72035, 72040, 72045, 72052, 72059, - 72066, 72073, 72085, 72097, 72102, 72107, 72112, 72117, 72122, 72127, - 72132, 72137, 72141, 72146, 72151, 72156, 72161, 72166, 72172, 72177, - 72182, 72189, 72196, 72203, 72210, 72217, 72226, 72235, 72241, 72247, - 72253, 72259, 72266, 72273, 72280, 72287, 72294, 72298, 72305, 72310, - 72315, 72322, 0, 72335, 72343, 72351, 72358, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 72365, 72374, 72383, 72392, 72401, 72410, 72419, 72428, 72437, - 72446, 72455, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 72462, 72469, 72475, 72482, 72490, 72498, - 72505, 72513, 72520, 72526, 72532, 72539, 72545, 72551, 72557, 72564, - 72571, 72578, 72585, 72592, 72599, 72606, 72613, 72620, 72627, 72634, - 72641, 72648, 72655, 72661, 72668, 72675, 72682, 72689, 72696, 72703, - 72710, 72717, 72724, 72731, 72738, 72745, 72752, 72759, 72766, 72773, - 72780, 72787, 72795, 72803, 72811, 72819, 0, 0, 0, 0, 72827, 72836, - 72845, 72854, 72863, 72872, 72881, 72888, 72895, 72902, 0, 0, 0, 0, 0, 0, - 72909, 72913, 72918, 72923, 72928, 72933, 72938, 72943, 72948, 72953, - 72958, 72963, 72967, 72971, 72976, 72981, 72985, 72990, 72995, 73000, - 73005, 73010, 73015, 73020, 73024, 73028, 73033, 73038, 73042, 73046, - 73050, 73054, 73058, 73062, 73066, 73071, 73076, 73081, 73086, 73091, - 73098, 73104, 73109, 73114, 73119, 73124, 73130, 73137, 73143, 73150, - 73156, 73162, 73167, 73174, 73180, 73185, 0, 0, 0, 0, 0, 0, 0, 0, 73191, - 73195, 73199, 73202, 73206, 73209, 73213, 73216, 73220, 73224, 73229, - 73233, 73238, 73241, 73245, 73249, 73252, 73256, 73260, 73263, 73267, - 73271, 73275, 73279, 73283, 73287, 73291, 73295, 73299, 73303, 73307, - 73311, 73315, 73319, 73323, 73327, 73331, 73335, 73338, 73341, 73345, - 73349, 73353, 73356, 73359, 73362, 73366, 73370, 73374, 73378, 73381, - 73384, 73388, 73393, 73398, 73402, 73407, 73411, 73416, 73421, 73427, - 73432, 73438, 73442, 73447, 73452, 73456, 73461, 73466, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 73470, 73473, 73477, 73481, 73484, 73487, 73490, 73493, 73496, - 73499, 73502, 73505, 0, 0, 0, 0, 0, 0, 73508, 73513, 73517, 73521, 73525, - 73529, 73533, 73537, 73541, 73545, 73549, 73553, 73557, 73561, 73565, - 73569, 73573, 73578, 73583, 73589, 73595, 73602, 73607, 73612, 73618, - 73622, 73627, 73630, 0, 0, 0, 0, 73633, 73640, 73646, 73652, 73658, - 73664, 73670, 73676, 73682, 73688, 73694, 73700, 73707, 73714, 73721, - 73727, 73734, 73741, 73748, 73755, 73762, 73768, 73774, 73781, 73787, - 73794, 73801, 73807, 73813, 73820, 73827, 73834, 73840, 73847, 73854, - 73860, 73867, 73873, 73880, 73887, 73893, 73899, 73906, 73912, 73919, - 73926, 73935, 73942, 73949, 73953, 73958, 73963, 73968, 73973, 73977, - 73981, 73986, 73990, 73995, 74000, 74005, 74009, 74013, 74018, 74022, - 74027, 74031, 74036, 74041, 74046, 74051, 74055, 74060, 74065, 74070, - 74076, 74081, 74087, 74093, 74099, 74105, 74111, 74116, 74122, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 74126, 74131, 74135, 74139, 74143, 74147, 74151, - 74155, 74159, 74163, 74167, 74171, 74175, 74179, 74183, 74187, 74191, - 74195, 74199, 74203, 74207, 74211, 74215, 74219, 74223, 74227, 74231, - 74235, 74239, 74243, 0, 0, 0, 74247, 74251, 74255, 74259, 74263, 74266, - 74272, 74275, 74279, 74282, 74288, 74294, 74302, 74305, 74309, 74312, - 74315, 74321, 74327, 74331, 74337, 74341, 74345, 74351, 74355, 74361, - 74367, 74371, 74375, 74381, 74385, 74391, 74397, 74401, 74407, 74411, - 74417, 74420, 74423, 74429, 74433, 74439, 74442, 74445, 74448, 74454, - 74458, 74462, 74468, 74474, 74477, 74480, 74486, 74491, 74496, 74501, - 74508, 74513, 74520, 74525, 74532, 74537, 74542, 74547, 74552, 74555, - 74559, 74563, 74568, 74573, 74578, 74583, 74588, 74593, 74598, 74603, - 74610, 74615, 0, 74622, 74625, 74629, 74632, 74635, 74638, 74641, 74644, - 74647, 74650, 74653, 0, 0, 0, 0, 74656, 74663, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 74668, 74671, 74674, 74677, 74680, 74684, 74687, 74690, 74694, 74698, - 74702, 74706, 74710, 74714, 74718, 74722, 74726, 74730, 74734, 74738, - 74742, 74746, 74750, 74754, 74758, 74761, 74765, 74768, 74772, 74776, - 74780, 74784, 74788, 74791, 74795, 74798, 74801, 74805, 74809, 74813, - 74816, 74819, 74824, 74828, 74833, 74838, 74842, 74847, 74851, 74856, - 74861, 74866, 74870, 74874, 74879, 0, 0, 0, 0, 0, 0, 0, 0, 0, 74884, - 74889, 74894, 74899, 74905, 74910, 74915, 74920, 74925, 74930, 74934, - 74938, 74943, 74948, 0, 0, 74954, 74958, 74961, 74964, 74967, 74970, - 74973, 74976, 74979, 74982, 0, 0, 74985, 74990, 74995, 75001, 75008, - 75014, 75020, 75026, 75032, 75038, 75044, 75050, 75056, 75062, 75068, - 75074, 75079, 75084, 75089, 75095, 75101, 75108, 75114, 75120, 75125, - 75132, 75139, 75146, 75152, 75157, 75162, 75167, 0, 0, 0, 0, 75175, - 75181, 75187, 75193, 75199, 75205, 75211, 75217, 75223, 75229, 75235, - 75241, 75247, 75253, 75259, 75265, 75271, 75277, 75283, 75289, 75295, - 75300, 75305, 75311, 75317, 75323, 75329, 75335, 75341, 75347, 75353, - 75359, 75365, 75371, 75377, 75383, 75389, 75395, 75401, 75407, 75413, - 75419, 75425, 75431, 75437, 75443, 75449, 75454, 75459, 75465, 75470, - 75474, 75479, 75483, 75487, 75491, 75497, 75502, 75507, 75512, 75517, - 75522, 75527, 75532, 75539, 75546, 75553, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 75560, 75565, 75570, 75575, - 75582, 75589, 75593, 75597, 75602, 75607, 75612, 75617, 75622, 75627, - 75632, 75637, 75642, 75648, 75654, 75660, 75666, 75672, 75676, 75682, - 75686, 75692, 75699, 75705, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 75709, 75713, - 75717, 75721, 75725, 75729, 0, 0, 75733, 75737, 75741, 75745, 75749, - 75753, 0, 0, 75757, 75761, 75765, 75769, 75773, 75777, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 75781, 75785, 75789, 75793, 75797, 75801, 75805, 0, 75809, - 75813, 75817, 75821, 75825, 75829, 75833, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 65512, 65521, 65530, 65541, 65548, 65553, 65558, 65565, 65572, 65578, + 65583, 65588, 65593, 65598, 65605, 65610, 65615, 65620, 65631, 65636, + 65641, 65648, 65653, 65660, 65665, 65670, 65677, 65684, 65691, 65700, + 65709, 65714, 65719, 65724, 65731, 65736, 65746, 65753, 65758, 65763, + 65768, 65773, 65778, 65783, 65792, 65799, 65806, 65811, 65818, 65823, + 65830, 65839, 65850, 65855, 65864, 65869, 65876, 65885, 65894, 65899, + 65904, 65911, 65917, 65924, 65931, 65935, 65939, 65942, 65946, 65950, + 65954, 65958, 65962, 65966, 65970, 65973, 65977, 65981, 65985, 65989, + 65993, 65997, 66000, 66004, 66008, 66011, 66015, 66019, 66023, 66027, + 66031, 66035, 66039, 66043, 66047, 66051, 66055, 66059, 66063, 66067, + 66071, 66075, 66079, 66083, 66087, 66091, 66095, 66099, 66103, 66107, + 66111, 66115, 66119, 66123, 66127, 66131, 66135, 66139, 66143, 66147, + 66151, 66155, 66159, 66163, 66167, 66171, 66175, 66179, 66183, 66187, + 66190, 66194, 66198, 66202, 66206, 66210, 66214, 66218, 66222, 66226, + 66230, 66234, 66238, 66242, 66246, 66250, 66254, 66258, 66262, 66266, + 66270, 66274, 66278, 66282, 66286, 66290, 66294, 66298, 66302, 66306, + 66310, 66314, 66318, 66322, 66326, 66330, 66334, 66338, 66342, 66346, + 66350, 66354, 66358, 66362, 66366, 66370, 66374, 66378, 66382, 66386, + 66390, 66394, 66398, 66402, 66406, 66410, 66414, 66418, 66422, 66426, + 66430, 66434, 66438, 66442, 66446, 66450, 66454, 66458, 66462, 66466, + 66470, 66474, 66478, 66482, 66486, 66490, 66494, 66498, 66502, 66506, + 66510, 66514, 66518, 66522, 66526, 66530, 66534, 66538, 66542, 66546, + 66550, 66554, 66558, 66562, 66566, 66570, 66574, 66578, 66582, 66586, + 66590, 66594, 66598, 66602, 66606, 66610, 66614, 66618, 66622, 66626, + 66630, 66634, 66638, 66642, 66646, 66650, 66654, 66658, 66661, 66665, + 66669, 66673, 66677, 66681, 66685, 66689, 66693, 66697, 66701, 66705, + 66709, 66713, 66717, 66721, 66725, 66729, 66733, 66737, 66741, 66745, + 66749, 66753, 66757, 66761, 66765, 66769, 66773, 66777, 66781, 66785, + 66789, 66793, 66797, 66801, 66805, 66809, 66813, 66817, 66821, 66825, + 66829, 66833, 66837, 66841, 66845, 66849, 66853, 66857, 66861, 66865, + 66869, 66873, 66877, 66881, 66885, 66889, 66893, 66897, 66901, 66905, + 66909, 66913, 66917, 66921, 66925, 66929, 66933, 66937, 66941, 66945, + 66949, 66953, 66957, 66961, 66965, 66969, 66973, 66977, 66981, 66985, + 66989, 66993, 66997, 67001, 67005, 67009, 67013, 67017, 67021, 67025, + 67029, 67033, 67037, 67041, 67045, 67049, 67053, 67057, 67061, 67065, + 67069, 67073, 67077, 67081, 67085, 67089, 67093, 67097, 67101, 67105, + 67109, 67113, 67117, 67121, 67124, 67128, 67132, 67136, 67140, 67144, + 67148, 67152, 67156, 67160, 67164, 67168, 67172, 67176, 67180, 67184, + 67188, 67192, 67196, 67200, 67204, 67208, 67212, 67216, 67220, 67224, + 67228, 67232, 67236, 67240, 67244, 67248, 67252, 67256, 67260, 67264, + 67268, 67272, 67276, 67280, 67284, 67288, 67292, 67296, 67300, 67304, + 67308, 67312, 67316, 67320, 67324, 67328, 67332, 67336, 67340, 67344, + 67348, 67352, 67356, 67360, 67364, 67368, 67372, 67376, 67380, 67384, + 67388, 67392, 67396, 67400, 67404, 67408, 67412, 67416, 67420, 67424, + 67428, 67432, 67436, 67440, 67444, 67448, 67452, 67456, 67460, 67464, + 67468, 67472, 67476, 67480, 67483, 67487, 67491, 67495, 67499, 67503, + 67507, 67511, 67515, 67519, 67523, 67527, 67531, 67535, 67539, 67543, + 67547, 67551, 67555, 67559, 67563, 67567, 67571, 67575, 67579, 67583, + 67587, 67591, 67595, 67599, 67603, 67607, 67611, 67615, 67619, 67623, + 67627, 67631, 67635, 67639, 67643, 67647, 67651, 67655, 67659, 67663, + 67667, 67671, 67675, 67679, 67683, 67687, 67691, 67695, 67699, 67703, + 67707, 67711, 67715, 67719, 67723, 67727, 67731, 67735, 67739, 67743, + 67747, 67751, 67755, 67759, 67763, 67767, 67771, 67775, 67779, 67783, + 67787, 67791, 67795, 67799, 67803, 67807, 67811, 67815, 67819, 67823, + 67827, 67831, 67835, 67839, 67843, 67847, 67851, 67855, 67859, 67863, + 67867, 67871, 67875, 67879, 67883, 67887, 67891, 67895, 67899, 67903, + 67907, 67911, 67915, 67919, 67923, 67927, 67931, 67935, 67939, 67943, + 67947, 67951, 67955, 67959, 67963, 67967, 67971, 67975, 67978, 67982, + 67986, 67990, 67994, 67998, 68002, 68006, 68010, 68014, 68018, 68022, + 68026, 68030, 68034, 68038, 68042, 68046, 68050, 68054, 68058, 68062, + 68066, 68070, 68074, 68078, 68082, 68086, 68090, 68094, 68098, 68102, + 68106, 68110, 68114, 68118, 68122, 68126, 68130, 68134, 68138, 68142, + 68146, 68150, 68154, 68158, 68162, 68166, 68170, 68174, 68178, 68182, + 68186, 68190, 68194, 68198, 68202, 68206, 68210, 68214, 68218, 68222, + 68226, 68230, 68234, 68238, 68242, 68246, 68250, 68254, 68258, 68262, + 68266, 68270, 68274, 68278, 68282, 68286, 68290, 68294, 68298, 68302, + 68306, 68310, 68314, 68318, 68322, 68326, 68330, 68334, 68338, 68342, + 68346, 68350, 68354, 68358, 68362, 68366, 68370, 68374, 68378, 68382, + 68386, 68390, 68394, 68398, 68402, 68406, 68410, 68414, 68418, 68422, + 68426, 68430, 68433, 68437, 68441, 68445, 68449, 68453, 68457, 68461, + 68465, 68469, 68473, 68477, 68481, 68485, 68489, 68493, 68497, 68501, + 68505, 68509, 68513, 68517, 68521, 68525, 68529, 68533, 68537, 68541, + 68545, 68549, 68553, 68557, 68561, 68565, 68569, 68573, 68577, 68581, + 68585, 68589, 68593, 68597, 68601, 68605, 68609, 68613, 68617, 68621, + 68625, 68629, 68633, 68637, 68641, 68645, 68649, 68653, 68657, 68661, + 68665, 68669, 68673, 68677, 68681, 68685, 68689, 68693, 68697, 68701, + 68705, 68709, 68713, 68717, 68721, 68725, 68729, 68733, 68737, 68741, + 68745, 68749, 68753, 68757, 68761, 68765, 68769, 68773, 68777, 68781, + 68785, 68789, 68793, 68797, 68801, 68805, 68809, 68813, 68817, 68821, + 68825, 68829, 68833, 68837, 68841, 68845, 68849, 68853, 68857, 68861, + 68865, 68869, 68873, 68877, 68881, 68885, 68889, 68893, 68897, 68901, + 68905, 68909, 68913, 68917, 68921, 68925, 68929, 68933, 68937, 68941, + 68945, 68949, 68953, 68957, 68961, 68965, 68969, 68973, 68977, 68981, + 68985, 68989, 68993, 68997, 69001, 69005, 69009, 69013, 69017, 69021, + 69025, 69029, 69033, 69036, 69040, 69044, 69048, 69052, 69056, 69060, + 69064, 69068, 69072, 69076, 69080, 69084, 69088, 69092, 69096, 69100, + 69104, 69108, 69112, 69116, 69120, 69124, 69128, 69132, 69136, 69140, + 69144, 69148, 69152, 69156, 69160, 69164, 69168, 69172, 69176, 69180, + 69184, 69188, 69192, 69196, 69200, 69204, 69208, 69212, 69216, 69220, + 69224, 69228, 69232, 69236, 69240, 69244, 69248, 69252, 69256, 69260, + 69264, 69268, 69272, 69276, 69280, 69284, 69288, 69292, 69296, 69300, + 69304, 69308, 69312, 69316, 69320, 69324, 69328, 69332, 69336, 69340, + 69344, 69348, 69352, 69356, 69360, 69364, 69368, 69372, 69376, 69380, + 69384, 69388, 69392, 69396, 69400, 69404, 69408, 69412, 69416, 69420, + 69424, 69428, 69432, 69436, 69440, 69444, 69448, 69452, 69456, 69460, + 69464, 69468, 69472, 69476, 69480, 69484, 69488, 69492, 69496, 69500, + 69504, 69508, 69512, 69516, 69520, 69524, 69528, 69532, 69536, 69540, + 69544, 69548, 69552, 69556, 69560, 69564, 69568, 69572, 69576, 69580, + 69584, 69588, 69592, 69596, 69600, 69604, 69608, 69612, 69616, 69620, + 69624, 69628, 69632, 69636, 69640, 69644, 69648, 69652, 69656, 69660, + 69664, 69668, 69672, 69676, 69680, 69684, 69688, 69692, 69696, 69700, + 69704, 69708, 69712, 69716, 69720, 69724, 69728, 69732, 69736, 69740, + 69744, 69748, 69752, 69756, 69760, 69764, 69768, 69772, 69776, 69780, + 69784, 69788, 69792, 69796, 69800, 69804, 69808, 69812, 69816, 69820, + 69824, 69828, 69832, 69836, 69840, 69844, 69848, 69852, 69856, 69860, + 69864, 69868, 69872, 69876, 69880, 69884, 69888, 69892, 69896, 69900, + 69904, 69908, 69912, 69916, 69920, 69924, 69928, 69932, 69936, 69940, + 69944, 69948, 69952, 69956, 69960, 69964, 69968, 69972, 69976, 69980, + 69984, 69988, 69992, 69996, 70000, 70004, 70008, 70012, 70016, 70020, + 70024, 70028, 70032, 70036, 70040, 70044, 70048, 70052, 70056, 70060, + 70064, 70068, 70072, 70076, 70080, 70084, 70088, 70092, 70096, 70100, + 70104, 70108, 70112, 70116, 70120, 70124, 70128, 70132, 70136, 70140, + 70144, 70148, 70152, 70156, 70160, 70164, 70168, 70172, 70176, 70180, + 70184, 70188, 70192, 70196, 70200, 70204, 70208, 70212, 70216, 70220, + 70224, 70228, 70232, 70236, 70240, 70244, 70248, 70252, 70256, 70260, + 70264, 70268, 70272, 70276, 70280, 70284, 70288, 70292, 70296, 70300, + 70304, 70308, 70312, 70316, 70320, 70324, 70328, 70332, 70336, 70340, + 70344, 70348, 70352, 70356, 70360, 70364, 70368, 70372, 70376, 70380, + 70384, 70388, 70392, 70396, 70400, 70404, 70408, 70412, 70416, 70420, + 70424, 70428, 70432, 70436, 70440, 70444, 70448, 70452, 70456, 70460, + 70464, 70468, 70472, 70476, 70480, 70484, 70488, 70492, 70496, 70500, + 70504, 70508, 70512, 70516, 70520, 70524, 70528, 70532, 70536, 70540, + 70544, 70548, 70552, 70556, 70560, 70564, 70568, 70572, 70576, 0, 0, 0, + 70580, 70584, 70588, 70592, 70596, 70600, 70604, 70608, 70612, 70616, + 70620, 70624, 70628, 70632, 70636, 70640, 70644, 70648, 70652, 70656, + 70660, 70664, 70668, 70672, 70676, 70680, 70684, 70688, 70692, 70696, + 70700, 70704, 70708, 70712, 70716, 70720, 70724, 70728, 70732, 70736, + 70740, 70744, 70748, 70752, 70756, 70760, 70764, 70768, 70772, 70776, + 70780, 70784, 70788, 70792, 70796, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70800, + 70805, 70809, 70814, 70819, 70824, 70829, 70834, 70838, 70843, 70848, + 70853, 70858, 70863, 70868, 70873, 70877, 70881, 70886, 70891, 70896, + 70901, 70906, 70910, 70915, 70920, 70925, 70930, 70935, 70939, 70944, + 70948, 70953, 70957, 70962, 70966, 70970, 70974, 70979, 70984, 70989, + 70997, 71005, 71013, 71021, 71028, 71036, 71042, 71050, 71054, 71058, + 71062, 71066, 71070, 71074, 71078, 71082, 71086, 71090, 71094, 71098, + 71102, 71106, 71110, 71114, 71118, 71122, 71126, 71130, 71134, 71138, + 71142, 71146, 71150, 71154, 71158, 71162, 71166, 71170, 71174, 71178, + 71182, 71186, 71190, 71194, 71197, 71201, 71205, 71209, 71213, 71217, + 71221, 71225, 71229, 71233, 71237, 71241, 71245, 71249, 71253, 71257, + 71261, 71265, 71269, 71273, 71277, 71281, 71285, 71289, 71293, 71297, + 71301, 71305, 71309, 71313, 71317, 71321, 71325, 71329, 71333, 71337, + 71341, 71344, 71348, 71352, 71355, 71359, 71363, 71367, 71370, 71374, + 71378, 71382, 71386, 71390, 71394, 71398, 71402, 71406, 71410, 71414, + 71418, 71422, 71426, 71430, 71434, 71438, 71442, 71446, 71450, 71454, + 71458, 71462, 71466, 71469, 71472, 71476, 71480, 71484, 71487, 71490, + 71494, 71498, 71502, 71506, 71510, 71514, 71518, 71522, 71526, 71530, + 71534, 71538, 71542, 71546, 71550, 71554, 71558, 71562, 71566, 71570, + 71574, 71578, 71582, 71586, 71590, 71594, 71598, 71602, 71606, 71610, + 71614, 71618, 71622, 71626, 71630, 71634, 71638, 71641, 71645, 71649, + 71653, 71657, 71661, 71665, 71669, 71673, 71677, 71681, 71685, 71689, + 71693, 71697, 71701, 71705, 71709, 71713, 71717, 71721, 71725, 71729, + 71733, 71737, 71741, 71745, 71749, 71753, 71757, 71761, 71765, 71769, + 71773, 71777, 71781, 71785, 71788, 71792, 71796, 71800, 71804, 71808, + 71812, 71816, 71820, 71824, 71828, 71832, 71836, 71840, 71844, 71848, + 71852, 71855, 71859, 71863, 71867, 71871, 71875, 71879, 71883, 71887, + 71891, 71895, 71899, 71903, 71907, 71911, 71915, 71919, 71923, 71927, + 71931, 71935, 71939, 71942, 71946, 71950, 71954, 71958, 71962, 71966, + 71970, 71974, 71978, 71982, 71986, 71990, 71994, 71998, 72002, 72006, + 72010, 72014, 72018, 72022, 72026, 72030, 72034, 72038, 72042, 72046, + 72050, 72054, 72058, 72062, 72066, 72070, 72074, 72078, 72082, 72086, + 72090, 72094, 72098, 72102, 72106, 72110, 72114, 72117, 72122, 72126, + 72132, 72137, 72143, 72147, 72151, 72155, 72159, 72163, 72167, 72171, + 72175, 72179, 72183, 72187, 72191, 72195, 72199, 72202, 72205, 72208, + 72211, 72214, 72217, 72220, 72223, 72226, 72231, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72237, 72242, 72247, 72252, 72257, + 72264, 72271, 72276, 72281, 72286, 72291, 72298, 72305, 72312, 72319, + 72326, 72333, 72343, 72353, 72360, 72367, 72374, 72381, 72387, 72393, + 72402, 72411, 72418, 72425, 72436, 72447, 72452, 72457, 72464, 72471, + 72478, 72485, 72492, 72499, 72506, 72513, 72519, 72525, 72531, 72537, + 72544, 72551, 72556, 72560, 72567, 72574, 72581, 72585, 72592, 72596, + 72601, 72605, 72611, 72616, 72622, 72627, 72631, 72635, 72638, 72641, + 72646, 72651, 72656, 72661, 72666, 72671, 72676, 72681, 72686, 72691, + 72700, 72709, 72714, 72719, 72724, 72729, 72734, 72739, 72744, 72749, + 72754, 72759, 72764, 72769, 72774, 72779, 72785, 72791, 72797, 0, 72803, + 72809, 72812, 72815, 72818, 72822, 72826, 72830, 72834, 72837, 72841, + 72844, 72848, 72851, 72855, 72859, 72863, 72867, 72871, 72875, 72879, + 72883, 72887, 72891, 72895, 72899, 72903, 72907, 72911, 72915, 72919, + 72923, 72927, 72931, 72935, 72939, 72942, 72946, 72950, 72954, 72958, + 72962, 72966, 72970, 72974, 72978, 72982, 72986, 72990, 72994, 72998, + 73002, 73006, 73010, 73014, 73018, 73022, 73026, 73030, 73034, 73038, + 73041, 73045, 73049, 73053, 73057, 73061, 73065, 73069, 73072, 73076, + 73080, 73084, 73088, 73092, 73096, 73100, 73104, 73108, 73112, 73116, + 73120, 73125, 73130, 73133, 73138, 73141, 73144, 73147, 0, 0, 0, 0, 0, 0, + 0, 0, 73151, 73160, 73169, 73178, 73187, 73196, 73205, 73214, 73223, + 73231, 73238, 73246, 73253, 73261, 73271, 73280, 73290, 73299, 73309, + 73317, 73324, 73332, 73339, 73347, 73352, 73357, 73362, 73371, 73377, + 73383, 73390, 73399, 73407, 73415, 73423, 73430, 73437, 73444, 73451, + 73456, 73461, 73466, 73471, 73476, 73481, 73486, 73491, 73499, 73507, + 73513, 73518, 73523, 73528, 73533, 73538, 73543, 73548, 73553, 73558, + 73566, 73574, 73579, 73584, 73594, 73604, 73611, 73618, 73627, 73636, + 73648, 73660, 73666, 73672, 73680, 73688, 73698, 73708, 73715, 73722, + 73727, 73732, 73744, 73756, 73764, 73772, 73782, 73792, 73804, 73816, + 73825, 73834, 73841, 73848, 73855, 73862, 73871, 73880, 73885, 73890, + 73897, 73904, 73911, 73918, 73930, 73942, 73947, 73952, 73957, 73962, + 73967, 73972, 73977, 73982, 73986, 73991, 73996, 74001, 74006, 74011, + 74017, 74022, 74027, 74034, 74041, 74048, 74055, 74062, 74070, 74078, + 74083, 74088, 74094, 74100, 74106, 74112, 74119, 74126, 74133, 74137, + 74144, 74149, 74154, 74160, 0, 74173, 74181, 74189, 74196, 74203, 74212, + 74221, 74228, 74235, 74242, 74249, 74256, 74263, 74270, 74277, 74284, + 74291, 74300, 74309, 74318, 74327, 74336, 74345, 74354, 74363, 74372, + 74381, 74388, 74396, 74402, 0, 0, 74410, 74416, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 74422, 74429, 74436, 74442, 74449, + 74457, 74465, 74473, 74481, 74489, 74495, 74501, 74508, 74514, 74520, + 74526, 74533, 74540, 74547, 74554, 74561, 74568, 74575, 74582, 74589, + 74596, 74603, 74610, 74617, 74624, 74630, 74637, 74644, 74651, 74658, + 74665, 74672, 74679, 74686, 74693, 74700, 74707, 74714, 74721, 74728, + 74735, 74742, 74749, 74756, 74764, 74772, 74780, 74788, 0, 0, 0, 0, + 74796, 74804, 74812, 74820, 74828, 74836, 74844, 74850, 74856, 74862, 0, + 0, 0, 0, 0, 0, 74868, 74872, 74877, 74882, 74887, 74892, 74897, 74902, + 74907, 74912, 74917, 74922, 74926, 74930, 74935, 74940, 74944, 74949, + 74954, 74959, 74964, 74969, 74974, 74979, 74983, 74988, 74993, 74998, + 75003, 75007, 75011, 75015, 75019, 75023, 75027, 75032, 75037, 75042, + 75047, 75052, 75059, 75065, 75070, 75075, 75080, 75085, 75091, 75098, + 75104, 75111, 75118, 75125, 75130, 75137, 75143, 75148, 0, 0, 0, 0, 0, 0, + 0, 0, 75154, 75159, 75164, 75168, 75173, 75177, 75182, 75186, 75191, + 75196, 75202, 75207, 75213, 75217, 75222, 75227, 75231, 75236, 75241, + 75245, 75250, 75255, 75260, 75265, 75270, 75275, 75280, 75285, 75290, + 75295, 75300, 75305, 75310, 75315, 75320, 75325, 75330, 75335, 75339, + 75343, 75348, 75353, 75358, 75362, 75366, 75371, 75376, 75381, 75386, + 75391, 75396, 75400, 75405, 75411, 75417, 75422, 75428, 75433, 75439, + 75445, 75452, 75458, 75465, 75470, 75476, 75482, 75487, 75493, 75499, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 75504, 75508, 75513, 75518, 75522, 75526, 75530, + 75534, 75538, 75542, 75546, 75550, 0, 0, 0, 0, 0, 0, 75554, 75559, 75563, + 75567, 75571, 75575, 75579, 75583, 75587, 75591, 75595, 75599, 75603, + 75607, 75611, 75615, 75620, 75625, 75630, 75636, 75642, 75649, 75654, + 75659, 75665, 75669, 75674, 75677, 0, 0, 0, 0, 75680, 75687, 75693, + 75699, 75705, 75711, 75717, 75723, 75729, 75735, 75741, 75747, 75754, + 75761, 75768, 75775, 75782, 75789, 75796, 75803, 75810, 75816, 75822, + 75829, 75835, 75842, 75849, 75856, 75862, 75869, 75876, 75883, 75889, + 75896, 75903, 75909, 75916, 75922, 75929, 75936, 75942, 75948, 75955, + 75961, 75968, 75975, 75984, 75991, 75998, 76002, 76007, 76012, 76017, + 76022, 76026, 76030, 76035, 76039, 76044, 76049, 76054, 76059, 76064, + 76069, 76073, 76078, 76082, 76087, 76092, 76097, 76102, 76106, 76111, + 76116, 76121, 76127, 76132, 76138, 76144, 76150, 76156, 76162, 76167, + 76173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76177, 76182, 76186, 76190, + 76194, 76198, 76202, 76206, 76210, 76214, 76218, 76222, 76226, 76230, + 76234, 76238, 76242, 76246, 76250, 76254, 76258, 76262, 76266, 76270, + 76274, 76278, 76282, 76286, 76290, 76294, 0, 0, 0, 76298, 76302, 76306, + 76310, 76314, 76317, 76323, 76326, 76330, 76333, 76339, 76345, 76353, + 76356, 76360, 76363, 76366, 76372, 76378, 76382, 76388, 76392, 76396, + 76402, 76406, 76412, 76418, 76422, 76426, 76432, 76436, 76442, 76448, + 76452, 76458, 76462, 76468, 76471, 76474, 76480, 76484, 76490, 76493, + 76496, 76500, 76506, 76510, 76514, 76520, 76526, 76530, 76533, 76539, + 76544, 76549, 76554, 76561, 76566, 76573, 76578, 76585, 76590, 76595, + 76600, 76605, 76608, 76612, 76616, 76621, 76626, 76631, 76636, 76641, + 76646, 76651, 76656, 76663, 76668, 0, 76674, 76677, 76681, 76684, 76687, + 76690, 76693, 76696, 76699, 76702, 76705, 0, 0, 0, 0, 76708, 76715, + 76720, 76726, 76732, 76738, 76744, 76750, 76756, 76763, 76770, 76777, + 76784, 76791, 76798, 76805, 76812, 76819, 76826, 76833, 76839, 76845, + 76851, 76857, 76863, 76869, 76875, 76881, 76887, 76894, 76901, 76908, + 76915, 0, 76922, 76925, 76928, 76931, 76934, 76938, 76941, 76944, 76948, + 76952, 76956, 76960, 76964, 76968, 76972, 76976, 76980, 76984, 76988, + 76992, 76996, 77000, 77004, 77008, 77012, 77015, 77019, 77022, 77026, + 77030, 77034, 77038, 77042, 77045, 77049, 77052, 77056, 77060, 77064, + 77068, 77072, 77075, 77080, 77084, 77089, 77094, 77098, 77103, 77107, + 77112, 77117, 77122, 77126, 77131, 77136, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 77141, 77146, 77151, 77156, 77162, 77167, 77172, 77177, 77182, 77187, + 77191, 77195, 77200, 77206, 0, 0, 77212, 77216, 77219, 77222, 77225, + 77228, 77231, 77234, 77237, 77240, 0, 0, 77243, 77248, 77253, 77259, + 77266, 77272, 77278, 77284, 77290, 77296, 77302, 77308, 77314, 77320, + 77326, 77332, 77337, 77343, 77348, 77354, 77360, 77367, 77373, 77379, + 77385, 77392, 77399, 77406, 77412, 77417, 77422, 77428, 77436, 77443, + 77450, 77458, 77466, 77473, 77480, 77487, 77494, 77501, 77508, 77515, + 77522, 77529, 77536, 77543, 77550, 77557, 77564, 77571, 77578, 77585, + 77592, 77599, 77606, 77612, 77618, 77625, 77632, 77639, 77646, 77653, + 77660, 77667, 77674, 77681, 77688, 77695, 77702, 77709, 77716, 77723, + 77730, 77737, 77744, 77751, 77758, 77765, 77772, 77779, 77786, 77792, + 77798, 77805, 77811, 77816, 77822, 77827, 77832, 77837, 77844, 77850, + 77856, 77862, 77868, 77874, 77880, 77886, 77894, 77902, 77910, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77918, + 77924, 77930, 77936, 77944, 77952, 77958, 77964, 77971, 77978, 77985, + 77992, 77999, 78006, 78013, 78020, 78027, 78035, 78043, 78051, 78059, + 78067, 78073, 78081, 78087, 78095, 78104, 78112, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 78118, 78122, 78126, 78130, 78134, 78138, 0, 0, 78142, 78146, + 78150, 78154, 78158, 78162, 0, 0, 78166, 78170, 78174, 78178, 78182, + 78186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 78190, 78194, 78198, 78202, 78206, + 78210, 78214, 0, 78218, 78222, 78226, 78230, 78234, 78238, 78242, 0, + 78246, 78253, 78259, 78265, 78271, 78278, 78285, 78294, 78305, 78316, + 78326, 78334, 78342, 78350, 78356, 78364, 78372, 78379, 78387, 78396, + 78403, 78412, 78418, 78428, 78437, 78442, 78450, 78459, 78464, 78473, + 78480, 78490, 78502, 78507, 78513, 78520, 78525, 78535, 78545, 78555, + 78565, 78580, 78593, 78604, 78612, 78617, 78628, 78638, 0, 0, 0, 0, + 78645, 78652, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 78658, + 78665, 78672, 78679, 78686, 78692, 78698, 78705, 78712, 78719, 78726, + 78733, 78740, 78747, 78754, 78761, 78767, 78774, 78781, 78788, 78795, + 78802, 78809, 78816, 78823, 78830, 78837, 78844, 78853, 78862, 78871, + 78880, 78889, 78898, 78907, 78916, 78924, 78932, 78940, 78948, 78956, + 78964, 78972, 78980, 78986, 78994, 0, 0, 79002, 79009, 79015, 79021, + 79027, 79033, 79039, 79045, 79051, 79057, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 75837, 75842, 75847, 75852, - 75857, 75861, 75865, 75870, 75875, 75880, 75885, 75890, 75895, 75900, - 75905, 75910, 75914, 75919, 75924, 75929, 75934, 75939, 75944, 75949, - 75954, 75959, 75964, 75969, 75976, 75983, 75990, 75997, 76004, 76011, - 76018, 76025, 76031, 76037, 76043, 76049, 76055, 76061, 76067, 76073, - 76077, 76083, 0, 0, 76089, 76094, 76098, 76102, 76106, 76110, 76114, - 76118, 76122, 76126, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76130, 76134, 76138, 76142, 76146, - 76150, 76154, 76158, 76162, 76166, 76170, 76174, 76178, 76182, 76186, - 76190, 76194, 76198, 76202, 76206, 76210, 76214, 76218, 0, 0, 0, 0, - 76222, 76226, 76230, 76234, 76238, 76242, 76246, 76250, 76254, 76258, - 76262, 76266, 76270, 76274, 76278, 76282, 76286, 76290, 76294, 76298, - 76302, 76306, 76310, 76314, 76318, 76322, 76326, 76330, 76334, 76338, - 76342, 76346, 76350, 76354, 76358, 76362, 76366, 76370, 76374, 76378, - 76382, 76386, 76390, 76394, 76398, 76402, 76406, 76410, 76414, 0, 0, 0, - 0, 76418, 76422, 76426, 76430, 76434, 76438, 76442, 76446, 76450, 76454, - 76458, 76462, 76466, 76470, 76474, 76478, 76482, 76486, 76490, 76494, - 76498, 76502, 76506, 76510, 76514, 76518, 76522, 76526, 76530, 76534, - 76538, 76542, 76546, 76550, 76554, 76558, 76562, 76566, 76570, 76574, - 76578, 76582, 76586, 76590, 76594, 76598, 76602, 76606, 76610, 76614, - 76618, 76622, 76626, 76630, 76634, 76638, 76642, 76646, 76650, 76654, - 76658, 76662, 76666, 76670, 76674, 76678, 76682, 76686, 76690, 76694, - 76698, 76702, 76706, 76710, 76714, 76718, 76722, 76726, 76730, 76734, - 76738, 76742, 76746, 76750, 76754, 76758, 76762, 76766, 76770, 76774, - 76778, 76782, 76786, 76790, 76794, 76798, 76802, 76806, 76810, 76814, - 76818, 76822, 76826, 76830, 76834, 76838, 76842, 76846, 76850, 76854, - 76858, 76862, 76866, 76870, 76874, 76878, 76882, 76886, 76890, 76894, - 76898, 76902, 76906, 76910, 76914, 76918, 76922, 76926, 76930, 76934, - 76938, 76942, 76946, 76950, 76954, 76958, 76962, 76966, 76970, 76974, - 76978, 76982, 76986, 76990, 76994, 76998, 77002, 77006, 77010, 77014, - 77018, 77022, 77026, 77030, 77034, 77038, 77042, 77046, 77050, 77054, - 77058, 77062, 77066, 77070, 77074, 77078, 77082, 77086, 77090, 77094, - 77098, 77102, 77106, 77110, 77114, 77118, 77122, 77126, 77130, 77134, - 77138, 77142, 77146, 77150, 77154, 77158, 77162, 77166, 77170, 77174, - 77178, 77182, 77186, 77190, 77194, 77198, 77202, 77206, 77210, 77214, - 77218, 77222, 77226, 77230, 77234, 77238, 77242, 77246, 77250, 77254, - 77258, 77262, 77266, 77270, 77274, 77278, 77282, 77286, 77290, 77294, - 77298, 77302, 77306, 77310, 77314, 77318, 77322, 77326, 77330, 77334, - 77338, 77342, 77346, 77350, 77354, 77358, 77362, 77366, 77370, 77374, - 77378, 77382, 77386, 77390, 77394, 77398, 77402, 77406, 77410, 77414, - 77418, 77422, 77426, 77430, 77434, 77438, 77442, 77446, 77450, 77454, - 77458, 77462, 77466, 77470, 77474, 77478, 77482, 77486, 77490, 77494, - 77498, 77502, 77506, 77510, 77514, 77518, 77522, 77526, 77530, 77534, - 77538, 77542, 77546, 77550, 77554, 77558, 77562, 77566, 77570, 77574, - 77578, 77582, 77586, 77590, 77594, 77598, 77602, 77606, 77610, 77614, - 77618, 77622, 77626, 77630, 77634, 77638, 77642, 77646, 77650, 77654, - 77658, 77662, 77666, 77670, 77674, 77678, 77682, 77686, 77690, 77694, - 77698, 77702, 77706, 77710, 77714, 77718, 77722, 77726, 77730, 77734, - 77738, 77742, 77746, 77750, 77754, 77758, 77762, 77766, 77770, 77774, - 77778, 77782, 77786, 77790, 77794, 77798, 77802, 77806, 77810, 77814, - 77818, 77822, 77826, 77830, 77834, 77838, 77842, 77846, 77850, 77854, - 77858, 77862, 77866, 77870, 77874, 77878, 0, 0, 77882, 77886, 77890, - 77894, 77898, 77902, 77906, 77910, 77914, 77918, 77922, 77926, 77930, - 77934, 77938, 77942, 77946, 77950, 77954, 77958, 77962, 77966, 77970, - 77974, 77978, 77982, 77986, 77990, 77994, 77998, 78002, 78006, 78010, - 78014, 78018, 78022, 78026, 78030, 78034, 78038, 78042, 78046, 78050, - 78054, 78058, 78062, 78066, 78070, 78074, 78078, 78082, 78086, 78090, - 78094, 78098, 78102, 78106, 78110, 78114, 78118, 78122, 78126, 78130, - 78134, 78138, 78142, 78146, 78150, 78154, 78158, 78162, 78166, 78170, - 78174, 78178, 78182, 78186, 78190, 78194, 78198, 78202, 78206, 78210, - 78214, 78218, 78222, 78226, 78230, 78234, 78238, 78242, 78246, 78250, - 78254, 78258, 78262, 78266, 78270, 78274, 78278, 78282, 78286, 78290, - 78294, 78298, 78302, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 78306, - 78311, 78316, 78321, 78326, 78331, 78339, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 78344, 78351, 78358, 78365, 78372, 0, 0, 0, 0, 0, 78379, 78386, - 78393, 78403, 78409, 78415, 78421, 78427, 78433, 78439, 78446, 78452, - 78458, 78464, 78473, 78482, 78494, 78506, 78512, 78518, 78524, 78531, - 78538, 78545, 78552, 78559, 0, 78566, 78573, 78580, 78588, 78595, 0, - 78602, 0, 78609, 78616, 0, 78623, 78631, 0, 78638, 78645, 78652, 78659, - 78666, 78673, 78680, 78687, 78694, 78701, 78706, 78713, 78720, 78726, - 78732, 78738, 78744, 78750, 78756, 78762, 78768, 78774, 78780, 78786, - 78792, 78798, 78804, 78810, 78816, 78822, 78828, 78834, 78840, 78846, - 78852, 78858, 78864, 78870, 78876, 78882, 78888, 78894, 78900, 78906, - 78912, 78918, 78924, 78930, 78936, 78942, 78948, 78954, 78960, 78966, - 78972, 78978, 78984, 78990, 78996, 79002, 79008, 79014, 79020, 79026, - 79032, 79038, 79044, 79050, 79056, 79062, 79068, 79074, 79080, 79086, - 79092, 79098, 79104, 79110, 79116, 79122, 79128, 79134, 79140, 79146, - 79152, 79158, 79164, 79170, 79176, 79184, 79192, 79198, 79204, 79210, - 79216, 79225, 79234, 79242, 79250, 79258, 79266, 79274, 79282, 79290, - 79298, 79305, 79312, 79322, 79332, 79336, 79340, 79345, 79350, 79355, - 79360, 79369, 79378, 79384, 79390, 79397, 79404, 79411, 79415, 79421, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79427, 79433, 79439, - 79445, 79451, 79456, 79461, 79467, 79473, 79479, 79485, 79493, 79499, - 79505, 79513, 79521, 79529, 79537, 79542, 79547, 79552, 79557, 79570, - 79583, 79593, 79603, 79614, 79625, 79636, 79647, 79657, 79667, 79678, - 79689, 79700, 79711, 79721, 79731, 79741, 79757, 79773, 79789, 79796, - 79803, 79810, 79817, 79827, 79837, 79847, 79859, 79869, 79877, 79885, - 79894, 79902, 79912, 79920, 79928, 79936, 79945, 79953, 79963, 79971, - 79979, 79987, 79997, 80005, 80012, 80019, 80026, 80033, 80041, 80049, - 80057, 80065, 80073, 80082, 80090, 80098, 80106, 80114, 80122, 80131, - 80139, 80147, 80155, 80163, 80171, 80179, 80187, 80195, 80203, 80211, - 80220, 80228, 80238, 80246, 80254, 80262, 80272, 80280, 80288, 80296, - 80304, 80313, 80322, 80330, 80340, 80348, 80356, 80364, 80373, 80381, - 80391, 80399, 80406, 80413, 80421, 80428, 80437, 80444, 80452, 80460, - 80469, 80477, 80487, 80495, 80503, 80511, 80521, 80529, 80536, 80543, - 80551, 80558, 80567, 80574, 80584, 80594, 80605, 80614, 80623, 80632, - 80641, 80650, 80660, 80671, 80682, 80692, 80703, 80715, 80725, 80734, - 80743, 80751, 80760, 80770, 80778, 80787, 80796, 80804, 80813, 80823, - 80831, 80840, 80849, 80857, 80866, 80876, 80884, 80894, 80902, 80912, - 80920, 80928, 80937, 80945, 80955, 80963, 80971, 80981, 80989, 80996, - 81003, 81012, 81021, 81029, 81038, 81048, 81056, 81067, 81075, 81083, - 81090, 81098, 81107, 81114, 81124, 81134, 81145, 81155, 81166, 81174, - 81182, 81191, 81199, 81208, 81216, 81224, 81233, 81241, 81250, 81258, - 81265, 81272, 81279, 81286, 81294, 81302, 81310, 81318, 81327, 81335, - 81343, 81352, 81360, 81368, 81376, 81385, 81393, 81401, 81409, 81417, - 81425, 81433, 81441, 81449, 81457, 81466, 81474, 81482, 81490, 81498, - 81506, 81515, 81524, 81532, 81540, 81548, 81557, 81565, 81574, 81581, - 81588, 81596, 81603, 81611, 81619, 81628, 81636, 81645, 81653, 81661, - 81671, 81678, 81685, 81693, 81700, 81708, 81718, 81729, 81737, 81746, - 81754, 81763, 81771, 81780, 81788, 81797, 81805, 81814, 81823, 81831, - 81839, 81847, 81856, 81863, 81871, 81880, 81889, 81898, 81908, 81916, - 81926, 81934, 81944, 81952, 81962, 81970, 81980, 81988, 81997, 82004, - 82013, 82020, 82030, 82038, 82048, 82056, 82066, 82074, 82082, 82090, - 82099, 82107, 82116, 82125, 82134, 82143, 82153, 82161, 82171, 82179, - 82189, 82197, 82207, 82215, 82225, 82233, 82242, 82249, 82258, 82265, - 82275, 82283, 82293, 82301, 82311, 82319, 82327, 82335, 82344, 82352, - 82361, 82370, 82379, 82388, 82396, 82404, 82413, 82421, 82430, 82439, - 82447, 82455, 82463, 82472, 82480, 82488, 82497, 82505, 82513, 82521, - 82529, 82534, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82539, - 82549, 82559, 82569, 82579, 82590, 82600, 82610, 82621, 82630, 82639, - 82648, 82659, 82669, 82679, 82691, 82701, 82711, 82721, 82731, 82741, - 82751, 82761, 82771, 82781, 82791, 82801, 82812, 82823, 82833, 82843, - 82855, 82866, 82877, 82887, 82897, 82907, 82917, 82927, 82937, 82947, - 82959, 82969, 82979, 82991, 83002, 83013, 83023, 83033, 83043, 83053, - 83065, 83075, 83085, 83096, 83107, 83117, 83127, 83136, 83145, 83154, - 83163, 83172, 83182, 0, 0, 83192, 83202, 83212, 83222, 83232, 83244, - 83254, 83264, 83276, 83286, 83298, 83307, 83316, 83327, 83337, 83349, - 83360, 83373, 83383, 83395, 83404, 83415, 83426, 83439, 83449, 83459, - 83469, 83479, 83489, 83498, 83507, 83516, 83525, 83535, 83545, 83555, - 83565, 83575, 83585, 83595, 83605, 83615, 83625, 83635, 83645, 83654, - 83663, 83672, 83682, 83692, 83702, 83712, 83722, 83733, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83743, 83758, 83773, 83779, 83785, 83791, - 83797, 83803, 83809, 83815, 83821, 83829, 83833, 83836, 0, 0, 83844, - 83847, 83850, 83853, 83856, 83859, 83862, 83865, 83868, 83871, 83874, - 83877, 83880, 83883, 83886, 83889, 83892, 83900, 83909, 83920, 83928, - 83936, 83945, 83954, 83965, 83977, 0, 0, 0, 0, 0, 0, 83986, 83991, 83996, - 84003, 84010, 84016, 84022, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84027, 84037, - 84047, 84057, 84066, 84077, 84086, 84095, 84105, 84115, 84127, 84139, - 84150, 84161, 84172, 84183, 84193, 84203, 84213, 84223, 84234, 84245, - 84249, 84254, 84263, 84272, 84276, 84280, 84284, 84289, 84294, 84299, - 84304, 84307, 84311, 0, 84316, 84319, 84322, 84326, 84330, 84335, 84339, - 84343, 84348, 84353, 84360, 84367, 84370, 84373, 84376, 84379, 84382, - 84386, 84390, 0, 84394, 84399, 84403, 84407, 0, 0, 0, 0, 84412, 84417, - 84424, 84429, 84434, 0, 84439, 84444, 84449, 84454, 84459, 84464, 84469, - 84474, 84479, 84484, 84489, 84494, 84503, 84512, 84520, 84528, 84537, - 84546, 84555, 84564, 84572, 84580, 84588, 84596, 84601, 84606, 84612, - 84618, 84624, 84630, 84638, 84646, 84652, 84658, 84664, 84670, 84676, - 84682, 84688, 84694, 84699, 84704, 84709, 84714, 84719, 84724, 84729, - 84734, 84740, 84746, 84752, 84758, 84764, 84770, 84776, 84782, 84788, - 84794, 84800, 84806, 84812, 84818, 84824, 84830, 84836, 84842, 84848, - 84854, 84860, 84866, 84872, 84878, 84884, 84890, 84896, 84902, 84908, - 84914, 84920, 84926, 84932, 84938, 84944, 84950, 84956, 84962, 84968, - 84974, 84980, 84986, 84992, 84998, 85004, 85010, 85016, 85022, 85028, - 85034, 85040, 85046, 85052, 85058, 85064, 85070, 85076, 85082, 85088, - 85094, 85099, 85104, 85109, 85114, 85120, 85126, 85132, 85138, 85144, - 85150, 85156, 85162, 85168, 85174, 85181, 85188, 85193, 85198, 85203, - 85208, 85220, 85232, 85243, 85254, 85266, 85278, 85286, 0, 0, 85294, 0, - 85302, 85306, 85310, 85313, 85317, 85321, 85324, 85327, 85331, 85335, - 85338, 85341, 85344, 85347, 85352, 85355, 85359, 85362, 85365, 85368, - 85371, 85374, 85377, 85380, 85383, 85386, 85389, 85392, 85396, 85400, - 85404, 85408, 85413, 85418, 85424, 85430, 85436, 85441, 85447, 85453, - 85459, 85464, 85470, 85476, 85481, 85486, 85492, 85497, 85503, 85509, - 85514, 85520, 85526, 85531, 85537, 85543, 85549, 85555, 85561, 85565, - 85570, 85574, 85579, 85583, 85588, 85593, 85599, 85605, 85611, 85616, - 85622, 85628, 85634, 85639, 85645, 85651, 85656, 85661, 85667, 85672, - 85678, 85684, 85689, 85695, 85701, 85706, 85712, 85718, 85724, 85730, - 85736, 85741, 85745, 85750, 85752, 85757, 85762, 85768, 85773, 85778, - 85782, 85788, 85793, 85798, 85803, 85808, 85813, 85818, 85823, 85829, - 85835, 85841, 85849, 85853, 85857, 85861, 85865, 85869, 85873, 85878, - 85883, 85888, 85893, 85897, 85902, 85907, 85912, 85917, 85922, 85927, - 85932, 85937, 85941, 85945, 85950, 85955, 85960, 85965, 85969, 85974, - 85979, 85984, 85989, 85993, 85998, 86003, 86008, 86013, 86017, 86022, - 86027, 86031, 86036, 86041, 86046, 86051, 86056, 86061, 86068, 86075, - 86079, 86084, 86089, 86094, 86099, 86104, 86109, 86114, 86119, 86124, - 86129, 86134, 86139, 86144, 86149, 86154, 86159, 86164, 86169, 86174, - 86179, 86184, 86189, 86194, 86199, 86204, 86209, 86214, 86219, 86224, 0, - 0, 0, 86229, 86233, 86238, 86242, 86247, 86252, 0, 0, 86256, 86261, - 86266, 86270, 86275, 86280, 0, 0, 86285, 86290, 86294, 86299, 86304, - 86309, 0, 0, 86314, 86319, 86324, 0, 0, 0, 86328, 86332, 86336, 86340, - 86343, 86347, 86351, 0, 86355, 86361, 86364, 86368, 86371, 86375, 86379, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86383, 86389, 86395, 86401, 86407, 0, 0, - 86411, 86417, 86423, 86429, 86435, 86441, 86448, 86455, 86462, 86469, - 86476, 86483, 0, 86490, 86497, 86504, 86510, 86517, 86524, 86531, 86538, - 86544, 86551, 86558, 86565, 86572, 86578, 86585, 86592, 86599, 86606, - 86612, 86619, 86626, 86633, 86640, 86647, 86654, 86661, 0, 86668, 86674, - 86681, 86688, 86695, 86702, 86708, 86715, 86722, 86729, 86736, 86743, - 86750, 86757, 86763, 86770, 86777, 86784, 86791, 0, 86798, 86805, 0, - 86812, 86819, 86826, 86833, 86840, 86847, 86854, 86861, 86868, 86875, - 86882, 86889, 86896, 86903, 86910, 0, 0, 86916, 86921, 86926, 86931, - 86936, 86941, 86946, 86951, 86956, 86961, 86966, 86971, 86976, 86981, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 86986, 86993, 87000, 87007, 87014, 87021, - 87028, 87035, 87042, 87049, 87056, 87063, 87070, 87077, 87084, 87091, - 87098, 87105, 87112, 87119, 87127, 87135, 87142, 87149, 87154, 87162, - 87170, 87177, 87184, 87189, 87196, 87201, 87206, 87213, 87218, 87223, - 87228, 87236, 87241, 87246, 87253, 87258, 87263, 87270, 87277, 87282, - 87287, 87292, 87297, 87302, 87307, 87312, 87317, 87322, 87329, 87334, - 87341, 87346, 87351, 87356, 87361, 87366, 87371, 87376, 87381, 87386, - 87391, 87396, 87403, 87410, 87417, 87424, 87430, 87435, 87442, 87447, - 87452, 87461, 87468, 87477, 87484, 87489, 87494, 87502, 87507, 87512, - 87517, 87522, 87527, 87534, 87539, 87544, 87549, 87554, 87559, 87566, - 87573, 87580, 87587, 87594, 87601, 87608, 87615, 87622, 87629, 87636, - 87643, 87650, 87657, 87664, 87671, 87678, 87685, 87692, 87699, 87706, - 87713, 87720, 87727, 87734, 87741, 87748, 87755, 0, 0, 0, 0, 0, 87762, - 87770, 87778, 0, 0, 0, 0, 87783, 87787, 87791, 87795, 87799, 87803, - 87807, 87811, 87815, 87819, 87824, 87829, 87834, 87839, 87844, 87849, - 87854, 87859, 87864, 87870, 87876, 87882, 87889, 87896, 87903, 87910, - 87917, 87924, 87930, 87936, 87942, 87949, 87956, 87963, 87970, 87977, - 87984, 87991, 87998, 88005, 88012, 88019, 88026, 88033, 88040, 0, 0, 0, - 88047, 88055, 88063, 88071, 88079, 88087, 88097, 88107, 88115, 88123, - 88131, 88139, 88147, 88153, 88160, 88169, 88178, 88187, 88196, 88205, - 88214, 88224, 88235, 88245, 88256, 88265, 88274, 88283, 88293, 88304, - 88314, 88325, 88336, 88345, 88353, 88359, 88365, 88371, 88377, 88385, - 88393, 88399, 88406, 88416, 88423, 88430, 88437, 88444, 88451, 88461, - 88468, 88475, 88483, 88491, 88500, 88509, 88518, 88527, 88536, 88544, - 88553, 88562, 88571, 88575, 88582, 88587, 88592, 88596, 88600, 88604, - 88608, 88613, 88618, 88624, 88630, 88634, 88640, 88644, 88648, 88652, - 88656, 88660, 88664, 88670, 0, 0, 0, 0, 0, 88674, 88679, 88684, 88689, - 88694, 88701, 88706, 88711, 88716, 88721, 88726, 88731, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88736, - 88743, 88752, 88761, 88768, 88775, 88782, 88789, 88796, 88803, 88809, - 88816, 88823, 88830, 88837, 88844, 88851, 88858, 88865, 88874, 88881, - 88888, 88895, 88902, 88909, 88916, 88923, 88930, 88939, 88946, 88953, - 88960, 88967, 88974, 88981, 88990, 88997, 89004, 89011, 89018, 89027, - 89034, 89041, 89048, 89056, 89065, 0, 0, 89074, 89078, 89082, 89087, - 89092, 89097, 89102, 89106, 89111, 89116, 89121, 89126, 89131, 89136, - 89140, 89144, 89149, 89154, 89159, 89163, 89168, 89173, 89177, 89182, - 89187, 89192, 89197, 89202, 89207, 0, 0, 0, 89212, 89216, 89221, 89226, - 89230, 89235, 89239, 89244, 89249, 89254, 89259, 89263, 89267, 89272, - 89277, 89282, 89287, 89292, 89297, 89301, 89306, 89311, 89316, 89321, - 89326, 89331, 89335, 89339, 89344, 89349, 89354, 89359, 89364, 89369, - 89374, 89379, 89384, 89389, 89394, 89399, 89404, 89409, 89414, 89419, - 89424, 89429, 89434, 89439, 89444, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89449, 89453, 89458, 89463, 89468, 89472, - 89477, 89482, 89487, 89492, 89496, 89500, 89505, 89510, 89515, 89520, - 89524, 89529, 89534, 89539, 89544, 89549, 89554, 89558, 89563, 89568, - 89573, 89578, 89583, 89588, 89593, 0, 89598, 89603, 89608, 89614, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89620, 89625, 89630, 89635, 89640, 89645, - 89650, 89655, 89660, 89665, 89670, 89675, 89680, 89685, 89690, 89695, - 89700, 89705, 89710, 89715, 89720, 89725, 89730, 89735, 89740, 89745, - 89750, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 89757, 89762, 89767, 89772, 89777, 89782, 89787, - 89792, 89797, 89802, 89807, 89812, 89817, 89822, 89827, 89832, 89837, - 89842, 89847, 89852, 89857, 89862, 89867, 89872, 89877, 89882, 89887, - 89891, 89895, 89899, 0, 89904, 89910, 89915, 89920, 89925, 89930, 89936, - 89942, 89948, 89954, 89960, 89966, 89972, 89978, 89984, 89990, 89996, - 90002, 90008, 90013, 90019, 90025, 90030, 90036, 90041, 90047, 90053, - 90058, 90064, 90070, 90075, 90081, 90087, 90092, 90098, 90104, 90110, 0, - 0, 0, 0, 90115, 90121, 90127, 90133, 90139, 90145, 90151, 90157, 90163, - 90170, 90175, 90180, 90186, 90192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 79063, 79067, 79071, 79075, 79079, 79083, 79087, 79091, + 79095, 79099, 79103, 79107, 79111, 79115, 79119, 79123, 79127, 79131, + 79135, 79139, 79143, 79147, 79151, 0, 0, 0, 0, 79155, 79159, 79163, + 79167, 79171, 79175, 79179, 79183, 79187, 79191, 79195, 79199, 79203, + 79207, 79211, 79215, 79219, 79223, 79227, 79231, 79235, 79239, 79243, + 79247, 79251, 79255, 79259, 79263, 79267, 79271, 79275, 79279, 79283, + 79287, 79291, 79295, 79299, 79303, 79307, 79311, 79315, 79319, 79323, + 79327, 79331, 79335, 79339, 79343, 79347, 0, 0, 0, 0, 79351, 79355, + 79359, 79363, 79367, 79371, 79375, 79379, 79383, 79387, 79391, 79395, + 79399, 79403, 79407, 79411, 79415, 79419, 79423, 79427, 79431, 79435, + 79439, 79443, 79447, 79451, 79455, 79459, 79463, 79467, 79471, 79475, + 79479, 79483, 79487, 79491, 79495, 79499, 79503, 79507, 79511, 79515, + 79519, 79523, 79527, 79531, 79535, 79539, 79543, 79547, 79551, 79555, + 79559, 79563, 79567, 79571, 79575, 79579, 79583, 79587, 79591, 79595, + 79599, 79603, 79607, 79611, 79615, 79619, 79623, 79627, 79631, 79635, + 79639, 79643, 79647, 79651, 79655, 79659, 79663, 79667, 79671, 79675, + 79679, 79683, 79687, 79691, 79695, 79699, 79703, 79707, 79711, 79715, + 79719, 79723, 79727, 79731, 79735, 79739, 79743, 79747, 79751, 79755, + 79759, 79763, 79767, 79771, 79775, 79779, 79783, 79787, 79791, 79795, + 79799, 79803, 79807, 79811, 79815, 79819, 79823, 79827, 79831, 79835, + 79839, 79843, 79847, 79851, 79855, 79859, 79863, 79867, 79871, 79875, + 79879, 79883, 79887, 79891, 79895, 79899, 79903, 79907, 79911, 79915, + 79919, 79923, 79927, 79931, 79935, 79939, 79943, 79947, 79951, 79955, + 79959, 79963, 79967, 79971, 79975, 79979, 79983, 79987, 79991, 79995, + 79999, 80003, 80007, 80011, 80015, 80019, 80023, 80027, 80031, 80035, + 80039, 80043, 80047, 80051, 80055, 80059, 80063, 80067, 80071, 80075, + 80079, 80083, 80087, 80091, 80095, 80099, 80103, 80107, 80111, 80115, + 80119, 80123, 80127, 80131, 80135, 80139, 80143, 80147, 80151, 80155, + 80159, 80163, 80167, 80171, 80175, 80179, 80183, 80187, 80191, 80195, + 80199, 80203, 80207, 80211, 80215, 80219, 80223, 80227, 80231, 80235, + 80239, 80243, 80247, 80251, 80255, 80259, 80263, 80267, 80271, 80275, + 80279, 80283, 80287, 80291, 80295, 80299, 80303, 80307, 80311, 80315, + 80319, 80323, 80327, 80331, 80335, 80339, 80343, 80347, 80351, 80355, + 80359, 80363, 80367, 80371, 80375, 80379, 80383, 80387, 80391, 80395, + 80399, 80403, 80407, 80411, 80415, 80419, 80423, 80427, 80431, 80435, + 80439, 80443, 80447, 80451, 80455, 80459, 80463, 80467, 80471, 80475, + 80479, 80483, 80487, 80491, 80495, 80499, 80503, 80507, 80511, 80515, + 80519, 80523, 80527, 80531, 80535, 80539, 80543, 80547, 80551, 80555, + 80559, 80563, 80567, 80571, 80575, 80579, 80583, 80587, 80591, 80595, + 80599, 80603, 80607, 80611, 80615, 80619, 80623, 80627, 80631, 80635, + 80639, 80643, 80647, 80651, 80655, 80659, 80663, 80667, 80671, 80675, + 80679, 80683, 80687, 80691, 80695, 80699, 80703, 80707, 80711, 80715, + 80719, 80723, 80727, 80731, 80735, 80739, 80743, 80747, 80751, 80755, + 80759, 80763, 80767, 80771, 80775, 80779, 80783, 80787, 80791, 80795, + 80799, 80803, 80807, 80811, 0, 0, 80815, 80819, 80823, 80827, 80831, + 80835, 80839, 80843, 80847, 80851, 80855, 80859, 80863, 80867, 80871, + 80875, 80879, 80883, 80887, 80891, 80895, 80899, 80903, 80907, 80911, + 80915, 80919, 80923, 80927, 80931, 80935, 80939, 80943, 80947, 80951, + 80955, 80959, 80963, 80967, 80971, 80975, 80979, 80983, 80987, 80991, + 80995, 80999, 81003, 81007, 81011, 81015, 81019, 81023, 81027, 81031, + 81035, 81039, 81043, 81047, 81051, 81055, 81059, 81063, 81067, 81071, + 81075, 81079, 81083, 81087, 81091, 81095, 81099, 81103, 81107, 81111, + 81115, 81119, 81123, 81127, 81131, 81135, 81139, 81143, 81147, 81151, + 81155, 81159, 81163, 81167, 81171, 81175, 81179, 81183, 81187, 81191, + 81195, 81199, 81203, 81207, 81211, 81215, 81219, 81223, 81227, 81231, + 81235, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81239, 81244, 81249, + 81254, 81259, 81264, 81272, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81277, + 81284, 81291, 81298, 81305, 0, 0, 0, 0, 0, 81312, 81319, 81326, 81336, + 81342, 81348, 81354, 81360, 81366, 81372, 81379, 81385, 81391, 81397, + 81406, 81415, 81427, 81439, 81445, 81451, 81457, 81464, 81471, 81478, + 81485, 81492, 0, 81499, 81506, 81513, 81521, 81528, 0, 81535, 0, 81542, + 81549, 0, 81556, 81564, 0, 81571, 81578, 81585, 81592, 81599, 81606, + 81613, 81620, 81627, 81634, 81639, 81646, 81653, 81659, 81665, 81671, + 81677, 81683, 81689, 81695, 81701, 81707, 81713, 81719, 81725, 81731, + 81737, 81743, 81749, 81755, 81761, 81767, 81773, 81779, 81785, 81791, + 81797, 81803, 81809, 81815, 81821, 81827, 81833, 81839, 81845, 81851, + 81857, 81863, 81869, 81875, 81881, 81887, 81893, 81899, 81905, 81911, + 81917, 81923, 81929, 81935, 81941, 81947, 81953, 81959, 81965, 81971, + 81977, 81983, 81989, 81995, 82001, 82007, 82013, 82019, 82025, 82031, + 82037, 82043, 82049, 82055, 82061, 82067, 82073, 82079, 82085, 82091, + 82097, 82103, 82109, 82117, 82125, 82131, 82137, 82143, 82149, 82158, + 82167, 82175, 82183, 82191, 82199, 82207, 82215, 82223, 82231, 82238, + 82245, 82256, 82267, 82271, 82275, 82280, 82285, 82290, 82295, 82303, + 82311, 82317, 82323, 82330, 82337, 82344, 82348, 82354, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82360, 82366, 82372, 82378, 82384, + 82389, 82394, 82400, 82406, 82412, 82418, 82427, 82433, 82439, 82447, + 82455, 82463, 82471, 82476, 82481, 82486, 82491, 82504, 82517, 82528, + 82539, 82551, 82563, 82575, 82587, 82598, 82609, 82621, 82633, 82645, + 82657, 82668, 82679, 82690, 82707, 82724, 82741, 82748, 82755, 82762, + 82769, 82780, 82791, 82802, 82815, 82826, 82834, 82842, 82851, 82859, + 82869, 82877, 82885, 82893, 82902, 82910, 82920, 82928, 82936, 82944, + 82954, 82962, 82969, 82976, 82983, 82990, 82998, 83006, 83014, 83022, + 83030, 83039, 83047, 83055, 83063, 83071, 83079, 83088, 83096, 83104, + 83112, 83120, 83128, 83136, 83144, 83152, 83160, 83168, 83177, 83185, + 83195, 83203, 83211, 83219, 83229, 83237, 83245, 83253, 83261, 83270, + 83279, 83287, 83297, 83305, 83313, 83321, 83330, 83338, 83348, 83356, + 83363, 83370, 83378, 83385, 83394, 83401, 83409, 83417, 83426, 83434, + 83444, 83452, 83460, 83468, 83478, 83486, 83493, 83500, 83508, 83515, + 83524, 83531, 83541, 83551, 83562, 83571, 83580, 83589, 83598, 83607, + 83617, 83629, 83641, 83652, 83664, 83677, 83688, 83697, 83706, 83714, + 83723, 83733, 83741, 83750, 83759, 83767, 83776, 83786, 83794, 83803, + 83812, 83820, 83829, 83839, 83847, 83857, 83865, 83875, 83883, 83891, + 83900, 83908, 83918, 83926, 83934, 83944, 83952, 83959, 83966, 83975, + 83984, 83992, 84001, 84011, 84019, 84030, 84038, 84046, 84053, 84061, + 84070, 84077, 84088, 84099, 84111, 84122, 84134, 84142, 84150, 84159, + 84167, 84176, 84184, 84192, 84201, 84209, 84218, 84226, 84233, 84240, + 84247, 84254, 84262, 84270, 84278, 84286, 84295, 84303, 84311, 84320, + 84328, 84336, 84344, 84353, 84361, 84369, 84377, 84385, 84393, 84401, + 84409, 84417, 84425, 84434, 84442, 84450, 84458, 84466, 84474, 84483, + 84492, 84500, 84508, 84516, 84525, 84533, 84542, 84549, 84556, 84564, + 84571, 84579, 84587, 84596, 84604, 84613, 84621, 84629, 84639, 84646, + 84653, 84661, 84668, 84676, 84687, 84699, 84707, 84716, 84724, 84733, + 84741, 84750, 84758, 84767, 84775, 84784, 84793, 84801, 84809, 84817, + 84826, 84833, 84841, 84850, 84859, 84868, 84878, 84886, 84896, 84904, + 84914, 84922, 84932, 84940, 84950, 84958, 84967, 84974, 84983, 84990, + 85000, 85008, 85018, 85026, 85036, 85044, 85052, 85060, 85069, 85077, + 85086, 85095, 85104, 85113, 85123, 85131, 85141, 85149, 85159, 85167, + 85177, 85185, 85195, 85203, 85212, 85219, 85228, 85235, 85245, 85253, + 85263, 85271, 85281, 85289, 85297, 85305, 85314, 85322, 85331, 85340, + 85349, 85358, 85366, 85374, 85383, 85391, 85400, 85409, 85417, 85425, + 85433, 85442, 85450, 85458, 85467, 85475, 85483, 85491, 85499, 85504, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85509, 85519, 85529, 85539, + 85549, 85560, 85570, 85580, 85591, 85600, 85609, 85618, 85629, 85639, + 85649, 85661, 85671, 85681, 85691, 85701, 85711, 85721, 85731, 85741, + 85751, 85761, 85771, 85782, 85793, 85803, 85813, 85825, 85836, 85847, + 85857, 85867, 85877, 85887, 85897, 85907, 85917, 85929, 85939, 85949, + 85961, 85972, 85983, 85993, 86003, 86013, 86023, 86035, 86045, 86055, + 86066, 86077, 86087, 86097, 86106, 86115, 86124, 86133, 86142, 86152, 0, + 0, 86162, 86172, 86182, 86192, 86202, 86214, 86224, 86234, 86246, 86256, + 86268, 86277, 86286, 86297, 86307, 86319, 86330, 86343, 86353, 86365, + 86374, 86385, 86396, 86409, 86419, 86429, 86439, 86449, 86459, 86468, + 86477, 86486, 86495, 86505, 86515, 86525, 86535, 86545, 86555, 86565, + 86575, 86585, 86595, 86605, 86615, 86624, 86633, 86642, 86652, 86662, + 86672, 86682, 86692, 86703, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 90198, 90203, 90208, 90213, 90219, 90224, 90230, 90236, - 90242, 90248, 90255, 90261, 90268, 90273, 90278, 90283, 90288, 90293, - 90298, 90303, 90308, 90313, 90318, 90323, 90328, 90333, 90338, 90343, - 90348, 90353, 90358, 90363, 90368, 90373, 90378, 90383, 90388, 90393, - 90398, 90403, 90408, 90413, 90418, 90423, 90429, 90434, 90440, 90446, - 90452, 90458, 90465, 90471, 90478, 90483, 90488, 90493, 90498, 90503, - 90508, 90513, 90518, 90523, 90528, 90533, 90538, 90543, 90548, 90553, - 90558, 90563, 90568, 90573, 90578, 90583, 90588, 90593, 90598, 90603, - 90608, 90613, 90618, 90623, 90628, 90633, 90638, 90643, 90648, 90653, - 90658, 90663, 90668, 90673, 90678, 90683, 90688, 90693, 90698, 90703, - 90708, 90713, 90718, 90723, 90728, 90733, 90738, 90743, 90748, 90753, - 90758, 90763, 90768, 90773, 90778, 90783, 90788, 90793, 90798, 90803, - 90808, 90813, 90818, 90823, 90828, 90833, 90838, 90843, 90848, 90853, - 90858, 90863, 90868, 90873, 90878, 90883, 90888, 90893, 90897, 90901, - 90906, 90911, 90916, 90921, 90926, 90931, 90936, 90941, 90946, 90951, - 90956, 90960, 90964, 90968, 90972, 90976, 90980, 90984, 90989, 90994, 0, - 0, 90999, 91004, 91008, 91012, 91016, 91020, 91024, 91028, 91032, 91036, + 0, 86713, 86728, 86743, 86749, 86755, 86761, 86767, 86773, 86779, 86785, + 86791, 86799, 86803, 86806, 0, 0, 86814, 86817, 86820, 86823, 86826, + 86829, 86832, 86835, 86838, 86841, 86844, 86847, 86850, 86853, 86856, + 86859, 86862, 86870, 86879, 86890, 86898, 86906, 86915, 86924, 86935, + 86947, 0, 0, 0, 0, 0, 0, 86956, 86961, 86966, 86973, 86980, 86986, 86992, + 86997, 87002, 87007, 87013, 87019, 87025, 87031, 0, 0, 87037, 87047, + 87057, 87067, 87076, 87087, 87096, 87105, 87115, 87125, 87137, 87149, + 87160, 87171, 87182, 87193, 87203, 87213, 87223, 87233, 87244, 87255, + 87259, 87264, 87273, 87282, 87286, 87290, 87294, 87299, 87304, 87309, + 87314, 87317, 87321, 0, 87326, 87329, 87332, 87336, 87340, 87345, 87349, + 87353, 87358, 87363, 87370, 87377, 87380, 87383, 87386, 87389, 87392, + 87396, 87400, 0, 87404, 87409, 87413, 87417, 0, 0, 0, 0, 87422, 87427, + 87434, 87439, 87444, 0, 87449, 87454, 87459, 87464, 87469, 87474, 87479, + 87484, 87489, 87494, 87499, 87505, 87514, 87523, 87532, 87541, 87551, + 87561, 87571, 87581, 87590, 87599, 87608, 87617, 87622, 87627, 87633, + 87639, 87645, 87651, 87659, 87667, 87673, 87679, 87685, 87691, 87697, + 87703, 87709, 87715, 87720, 87725, 87730, 87735, 87740, 87745, 87750, + 87755, 87761, 87767, 87773, 87779, 87785, 87791, 87797, 87803, 87809, + 87815, 87821, 87827, 87833, 87839, 87845, 87851, 87857, 87863, 87869, + 87875, 87881, 87887, 87893, 87899, 87905, 87911, 87917, 87923, 87929, + 87935, 87941, 87947, 87953, 87959, 87965, 87971, 87977, 87983, 87989, + 87995, 88001, 88007, 88013, 88019, 88025, 88031, 88037, 88043, 88049, + 88055, 88061, 88067, 88073, 88079, 88085, 88091, 88097, 88103, 88109, + 88115, 88120, 88125, 88130, 88135, 88141, 88147, 88153, 88159, 88165, + 88171, 88177, 88183, 88189, 88195, 88202, 88209, 88214, 88219, 88224, + 88229, 88241, 88253, 88265, 88277, 88290, 88303, 88311, 0, 0, 88319, 0, + 88327, 88331, 88335, 88338, 88342, 88346, 88349, 88352, 88356, 88360, + 88363, 88366, 88369, 88372, 88377, 88380, 88384, 88387, 88390, 88393, + 88396, 88399, 88402, 88405, 88408, 88411, 88414, 88417, 88421, 88425, + 88429, 88433, 88438, 88443, 88449, 88455, 88461, 88466, 88472, 88478, + 88484, 88489, 88495, 88501, 88506, 88512, 88518, 88523, 88529, 88535, + 88540, 88545, 88551, 88556, 88562, 88568, 88574, 88580, 88586, 88590, + 88595, 88599, 88604, 88608, 88613, 88618, 88624, 88630, 88636, 88641, + 88647, 88653, 88659, 88664, 88670, 88676, 88681, 88687, 88693, 88698, + 88704, 88710, 88715, 88720, 88726, 88731, 88737, 88743, 88749, 88755, + 88761, 88766, 88770, 88775, 88778, 88783, 88788, 88794, 88799, 88804, + 88808, 88814, 88819, 88824, 88829, 88834, 88839, 88844, 88849, 88855, + 88861, 88867, 88875, 88879, 88883, 88887, 88891, 88895, 88899, 88904, + 88909, 88914, 88919, 88924, 88929, 88934, 88939, 88944, 88949, 88954, + 88959, 88964, 88968, 88972, 88977, 88982, 88987, 88992, 88996, 89001, + 89006, 89011, 89016, 89020, 89025, 89030, 89035, 89040, 89044, 89049, + 89054, 89059, 89064, 89069, 89074, 89079, 89084, 89089, 89096, 89103, + 89107, 89112, 89117, 89122, 89127, 89132, 89137, 89142, 89147, 89152, + 89157, 89162, 89167, 89172, 89177, 89182, 89187, 89192, 89197, 89202, + 89207, 89212, 89217, 89222, 89227, 89232, 89237, 89242, 89247, 89252, 0, + 0, 0, 89257, 89261, 89266, 89270, 89275, 89280, 0, 0, 89284, 89289, + 89294, 89298, 89303, 89308, 0, 0, 89313, 89318, 89322, 89327, 89332, + 89337, 0, 0, 89342, 89347, 89352, 0, 0, 0, 89356, 89360, 89364, 89368, + 89371, 89375, 89379, 0, 89383, 89389, 89392, 89395, 89398, 89401, 89405, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89409, 89415, 89421, 89427, 89433, 0, 0, + 89437, 89443, 89449, 89455, 89461, 89467, 89474, 89481, 89488, 89495, + 89502, 89509, 0, 89516, 89523, 89530, 89536, 89543, 89550, 89557, 89564, + 89570, 89577, 89584, 89591, 89598, 89604, 89611, 89618, 89625, 89632, + 89638, 89645, 89652, 89659, 89666, 89673, 89680, 89687, 0, 89694, 89701, + 89708, 89715, 89722, 89729, 89736, 89743, 89750, 89757, 89764, 89771, + 89778, 89785, 89791, 89798, 89805, 89812, 89819, 0, 89826, 89833, 0, + 89840, 89847, 89854, 89861, 89868, 89875, 89882, 89889, 89896, 89903, + 89910, 89917, 89924, 89931, 89938, 0, 0, 89944, 89949, 89954, 89959, + 89964, 89969, 89974, 89979, 89984, 89989, 89994, 89999, 90004, 90009, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 90014, 90021, 90028, 90035, 90042, 90049, + 90056, 90063, 90070, 90077, 90084, 90091, 90098, 90105, 90112, 90119, + 90126, 90133, 90140, 90147, 90155, 90163, 90170, 90177, 90182, 90190, + 90198, 90205, 90212, 90217, 90224, 90229, 90234, 90241, 90246, 90251, + 90256, 90264, 90269, 90274, 90281, 90286, 90291, 90298, 90305, 90310, + 90315, 90320, 90325, 90330, 90335, 90340, 90345, 90350, 90357, 90362, + 90369, 90374, 90379, 90384, 90389, 90394, 90399, 90404, 90409, 90414, + 90419, 90424, 90431, 90438, 90445, 90452, 90458, 90463, 90470, 90475, + 90480, 90489, 90496, 90505, 90512, 90517, 90522, 90530, 90535, 90540, + 90545, 90550, 90555, 90562, 90567, 90572, 90577, 90582, 90587, 90594, + 90601, 90608, 90615, 90622, 90629, 90636, 90643, 90650, 90657, 90664, + 90671, 90678, 90685, 90692, 90699, 90706, 90713, 90720, 90727, 90734, + 90741, 90748, 90755, 90762, 90769, 90776, 90783, 0, 0, 0, 0, 0, 90790, + 90798, 90806, 0, 0, 0, 0, 90811, 90815, 90819, 90823, 90827, 90831, + 90835, 90839, 90843, 90847, 90852, 90857, 90862, 90867, 90872, 90877, + 90882, 90887, 90892, 90898, 90904, 90910, 90917, 90924, 90931, 90938, + 90945, 90952, 90958, 90964, 90970, 90977, 90984, 90991, 90998, 91005, + 91012, 91019, 91026, 91033, 91040, 91047, 91054, 91061, 91068, 0, 0, 0, + 91075, 91083, 91091, 91099, 91107, 91115, 91125, 91135, 91143, 91151, + 91159, 91167, 91175, 91181, 91188, 91197, 91206, 91215, 91224, 91233, + 91242, 91252, 91263, 91273, 91284, 91293, 91302, 91311, 91321, 91332, + 91342, 91353, 91364, 91373, 91381, 91387, 91393, 91399, 91405, 91413, + 91421, 91427, 91434, 91444, 91451, 91458, 91465, 91472, 91479, 91489, + 91496, 91503, 91511, 91519, 91528, 91537, 91546, 91555, 91564, 91572, + 91581, 91590, 91599, 91603, 91610, 91615, 91620, 91624, 91628, 91632, + 91636, 91641, 91646, 91652, 91658, 91662, 91668, 91672, 91676, 91680, + 91684, 91688, 91692, 91698, 91702, 91707, 0, 0, 0, 91711, 91716, 91721, + 91726, 91731, 91738, 91743, 91748, 91753, 91758, 91763, 91768, 0, 0, 0, + 0, 91773, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 91779, 91786, 91795, 91804, 91811, 91818, 91825, 91832, 91839, + 91846, 91852, 91859, 91866, 91873, 91880, 91887, 91894, 91901, 91908, + 91917, 91924, 91931, 91938, 91945, 91952, 91959, 91966, 91973, 91982, + 91989, 91996, 92003, 92010, 92017, 92024, 92033, 92040, 92047, 92054, + 92061, 92070, 92077, 92084, 92091, 92099, 92108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 91040, 91044, 91048, 91052, - 91056, 91060, 0, 0, 91065, 0, 91070, 91074, 91079, 91084, 91089, 91094, - 91099, 91104, 91109, 91114, 91119, 91123, 91128, 91133, 91138, 91143, - 91147, 91152, 91157, 91162, 91167, 91171, 91176, 91181, 91186, 91191, - 91195, 91200, 91205, 91210, 91215, 91219, 91224, 91229, 91234, 91239, - 91244, 91249, 91254, 91258, 91263, 91268, 91273, 91278, 0, 91283, 91288, - 0, 0, 0, 91293, 0, 0, 91298, 91303, 91310, 91317, 91324, 91331, 91338, - 91345, 91352, 91359, 91366, 91373, 91380, 91387, 91394, 91401, 91408, - 91415, 91422, 91429, 91436, 91443, 91450, 0, 91457, 91464, 91470, 91476, - 91482, 91489, 91496, 91504, 91512, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 91521, 91526, - 91531, 91536, 91541, 91546, 91551, 91556, 91561, 91566, 91571, 91576, - 91581, 91586, 91591, 91596, 91601, 91606, 91611, 91616, 91621, 91626, - 91631, 91635, 91640, 91645, 91651, 91655, 0, 0, 0, 91659, 91665, 91669, - 91674, 91679, 91684, 91688, 91693, 91697, 91702, 91707, 91711, 91715, - 91720, 91724, 91728, 91733, 91738, 91742, 91747, 91752, 91757, 91762, - 91767, 91772, 91777, 91782, 0, 0, 0, 0, 0, 91787, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 91792, 91798, 91804, 91810, 91816, 91822, 91829, - 91836, 91843, 91849, 91855, 91861, 91868, 91875, 91882, 91888, 91895, - 91902, 91909, 91916, 91922, 91929, 91936, 91942, 91949, 91956, 91963, - 91970, 91977, 91983, 91990, 91997, 92004, 92010, 92016, 92022, 92028, - 92034, 92041, 92048, 92054, 92060, 92066, 92073, 92079, 92086, 92093, - 92100, 92106, 92114, 92121, 92127, 92134, 92141, 92148, 92154, 0, 0, 0, - 0, 0, 0, 92161, 92169, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 92177, 92181, 92186, 92191, 0, 92197, 92202, 0, 0, 0, 0, 0, 92207, 92213, - 92220, 92225, 92230, 92234, 92239, 92244, 0, 92249, 92254, 92259, 0, - 92264, 92269, 92274, 92279, 92284, 92289, 92294, 92299, 92304, 92309, - 92314, 92318, 92322, 92327, 92332, 92337, 92341, 92345, 92349, 92354, - 92359, 92364, 92369, 92373, 92378, 92382, 92387, 0, 0, 0, 0, 92392, - 92398, 92403, 0, 0, 0, 0, 92408, 92412, 92416, 92420, 92424, 92428, - 92433, 92438, 92444, 0, 0, 0, 0, 0, 0, 0, 0, 92450, 92456, 92463, 92469, - 92476, 92482, 92488, 92494, 92501, 0, 0, 0, 0, 0, 0, 0, 92507, 92515, - 92523, 92531, 92539, 92547, 92555, 92563, 92571, 92579, 92587, 92595, - 92603, 92611, 92619, 92627, 92635, 92643, 92651, 92659, 92667, 92675, - 92683, 92691, 92699, 92707, 92715, 92723, 92731, 92739, 92746, 92754, - 92762, 92766, 92771, 92776, 92781, 92786, 92791, 92796, 92801, 92805, - 92810, 92814, 92819, 92823, 92828, 92832, 92837, 92842, 92847, 92852, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 92117, 92121, 92125, 92130, 92135, 92140, 92145, 92149, 92154, + 92159, 92164, 92169, 92174, 92179, 92183, 92188, 92193, 92198, 92203, + 92207, 92212, 92217, 92221, 92225, 92230, 92235, 92240, 92245, 92250, 0, + 0, 0, 92255, 92259, 92264, 92269, 92273, 92278, 92282, 92287, 92292, + 92297, 92302, 92307, 92311, 92316, 92321, 92326, 92331, 92335, 92340, + 92344, 92349, 92354, 92359, 92364, 92369, 92374, 92378, 92382, 92387, + 92392, 92397, 92402, 92407, 92412, 92417, 92422, 92427, 92432, 92437, + 92442, 92447, 92452, 92457, 92462, 92467, 92472, 92477, 92482, 92487, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92492, 92498, 92503, 92508, + 92513, 92518, 92523, 92528, 92533, 92538, 92543, 92549, 92555, 92561, + 92567, 92573, 92579, 92585, 92591, 92597, 92604, 92611, 92618, 92626, + 92634, 92642, 92650, 92658, 0, 0, 0, 0, 92666, 92670, 92675, 92680, + 92685, 92689, 92694, 92699, 92704, 92709, 92713, 92717, 92722, 92727, + 92732, 92737, 92741, 92746, 92751, 92756, 92761, 92766, 92771, 92775, + 92780, 92785, 92790, 92795, 92800, 92805, 92810, 92815, 92820, 92825, + 92830, 92836, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92842, 92847, 92852, 92857, 92862, 92867, 92872, 92877, 92882, 92887, 92892, 92897, 92902, 92907, 92912, 92917, 92922, 92927, 92932, 92937, 92942, 92947, 92952, - 92957, 92962, 92967, 92972, 92977, 92982, 92987, 92992, 92997, 93002, - 93007, 93012, 93017, 93022, 0, 0, 0, 93027, 93032, 93041, 93049, 93058, - 93067, 93078, 93089, 93096, 93103, 93110, 93117, 93124, 93131, 93138, - 93145, 93152, 93159, 93166, 93173, 93180, 93187, 93194, 93201, 93208, - 93215, 93222, 93229, 93236, 0, 0, 93243, 93249, 93255, 93261, 93267, - 93274, 93281, 93289, 93297, 93304, 93311, 93318, 93325, 93332, 93339, - 93346, 93353, 93360, 93367, 93374, 93381, 93388, 93395, 93402, 93409, - 93416, 93423, 0, 0, 0, 0, 0, 93430, 93436, 93442, 93448, 93454, 93461, - 93468, 93476, 93484, 93490, 93496, 93503, 93509, 93515, 93521, 93527, - 93534, 93541, 93548, 93555, 93562, 93569, 93576, 93583, 93590, 93597, - 93604, 93611, 93618, 93625, 93632, 93639, 93646, 93653, 93660, 93667, - 93674, 93681, 93688, 93695, 93702, 93709, 93716, 93723, 93730, 93737, - 93744, 93751, 93758, 93765, 93772, 93779, 93786, 93793, 93800, 93807, - 93814, 93821, 93828, 93835, 93842, 93849, 93856, 93863, 93870, 93877, - 93884, 93891, 93898, 93905, 93912, 93919, 93926, 93933, 93940, 93947, - 93954, 93961, 93968, 93975, 93982, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 92957, 92962, 92967, 92972, 0, 0, 0, 0, 0, 92979, 92985, 92991, 92997, + 93003, 93008, 93014, 93020, 93026, 93032, 93037, 93043, 93049, 93055, + 93061, 93067, 93073, 93079, 93085, 93091, 93096, 93102, 93108, 93114, + 93120, 93126, 93131, 93137, 93143, 93148, 93154, 93160, 93166, 93172, + 93178, 93184, 93190, 93195, 93201, 93208, 93215, 93222, 93229, 0, 0, 0, + 0, 0, 93236, 93241, 93246, 93251, 93256, 93261, 93266, 93271, 93276, + 93281, 93286, 93291, 93296, 93301, 93306, 93311, 93316, 93321, 93326, + 93331, 93336, 93341, 93346, 93351, 93356, 93361, 93366, 93370, 93374, + 93378, 0, 93383, 93389, 93394, 93399, 93404, 93409, 93415, 93421, 93427, + 93433, 93439, 93445, 93451, 93457, 93463, 93469, 93475, 93481, 93487, + 93492, 93498, 93504, 93509, 93515, 93520, 93526, 93532, 93537, 93543, + 93549, 93555, 93561, 93567, 93573, 93579, 93585, 93591, 0, 0, 0, 0, + 93596, 93602, 93608, 93614, 93620, 93626, 93632, 93638, 93644, 93651, + 93656, 93661, 93667, 93673, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 93679, 93685, 93691, 93697, 93704, 93710, 93717, 93724, 93731, + 93738, 93746, 93753, 93761, 93767, 93773, 93779, 93785, 93791, 93797, + 93803, 93809, 93815, 93821, 93827, 93833, 93839, 93845, 93851, 93857, + 93863, 93869, 93875, 93881, 93887, 93893, 93899, 93905, 93911, 93917, + 93923, 93929, 93935, 93941, 93947, 93954, 93960, 93967, 93974, 93981, + 93988, 93996, 94003, 94011, 94017, 94023, 94029, 94035, 94041, 94047, + 94053, 94059, 94065, 94071, 94077, 94083, 94089, 94095, 94101, 94107, + 94113, 94119, 94125, 94131, 94137, 94143, 94149, 94155, 94161, 94167, + 94173, 94179, 94184, 94189, 94194, 94199, 94204, 94209, 94214, 94219, + 94224, 94229, 94234, 94239, 94244, 94249, 94254, 94259, 94264, 94269, + 94274, 94279, 94284, 94289, 94294, 94299, 94304, 94309, 94314, 94319, + 94324, 94329, 94334, 94339, 94344, 94349, 94354, 94359, 94364, 94369, + 94374, 94379, 94384, 94389, 94394, 94399, 94404, 94409, 94414, 94419, + 94424, 94429, 94434, 94439, 94444, 94449, 94454, 94459, 94464, 94469, + 94474, 94479, 94484, 94489, 94494, 94499, 94504, 94509, 94514, 94519, + 94523, 94527, 94531, 94535, 94539, 94543, 94547, 94552, 94557, 0, 0, + 94562, 94567, 94571, 94575, 94579, 94583, 94587, 94591, 94595, 94599, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 94603, 94607, 94612, 94617, 94622, + 94627, 94632, 94637, 94642, 94646, 94651, 94656, 94661, 94666, 94670, + 94675, 94680, 94685, 94690, 94695, 94700, 94704, 94709, 94713, 94718, + 94723, 94728, 94733, 94738, 94743, 94748, 94753, 94757, 94762, 94767, + 94772, 94777, 94782, 94787, 94792, 0, 0, 0, 0, 0, 0, 0, 0, 94797, 94804, + 94811, 94818, 94825, 94832, 94839, 94846, 94853, 94860, 94867, 94874, + 94881, 94888, 94895, 94902, 94909, 94916, 94923, 94930, 94937, 94944, + 94951, 94958, 94965, 94972, 94979, 94986, 94993, 95000, 95007, 95014, + 95021, 95028, 95035, 95042, 95049, 95056, 95063, 95070, 95077, 95084, + 95091, 95098, 95105, 95112, 95119, 95126, 95133, 95140, 95147, 95154, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95168, 95173, 95178, 95183, 95188, + 95193, 95198, 95203, 95208, 95213, 95218, 95223, 95228, 95233, 95238, + 95243, 95248, 95253, 95258, 95263, 95268, 95273, 95278, 95283, 95288, + 95293, 95298, 95303, 95308, 95313, 95318, 95323, 95328, 95333, 95338, + 95343, 95348, 95353, 95358, 95363, 95368, 95373, 95378, 95383, 95388, + 95393, 95398, 95403, 95408, 95413, 95418, 95423, 95428, 95433, 95438, + 95443, 95448, 95453, 95458, 95463, 95468, 95473, 95478, 95483, 95488, + 95493, 95498, 95503, 95508, 95513, 95518, 95523, 95528, 95533, 95538, + 95543, 95548, 95553, 95558, 95563, 95568, 95573, 95578, 95583, 95588, + 95593, 95598, 95603, 95608, 95613, 95618, 95623, 95628, 95633, 95638, + 95643, 95648, 95653, 95658, 95663, 95668, 95673, 95678, 95683, 95688, + 95693, 95698, 95703, 95708, 95713, 95718, 95723, 95728, 95733, 95738, + 95743, 95748, 95753, 95758, 95763, 95768, 95773, 95778, 95783, 95788, + 95793, 95798, 95803, 95808, 95813, 95818, 95823, 95828, 95833, 95838, + 95843, 95848, 95853, 95858, 95863, 95868, 95873, 95878, 95883, 95888, + 95893, 95898, 95903, 95908, 95913, 95918, 95923, 95928, 95933, 95938, + 95943, 95948, 95953, 95958, 95963, 95968, 95973, 95978, 95983, 95988, + 95993, 95998, 96003, 96008, 96013, 96018, 96023, 96028, 96033, 96038, + 96043, 96048, 96053, 96058, 96063, 96068, 96073, 96078, 96083, 96088, + 96093, 96098, 96103, 96108, 96113, 96118, 96123, 96128, 96133, 96138, + 96143, 96148, 96153, 96158, 96163, 96168, 96173, 96178, 96183, 96188, + 96193, 96198, 96203, 96208, 96213, 96218, 96223, 96228, 96233, 96238, + 96243, 96248, 96253, 96258, 96263, 96268, 96273, 96278, 96283, 96288, + 96293, 96298, 96303, 96308, 96313, 96318, 96323, 96328, 96333, 96338, + 96343, 96348, 96353, 96358, 96363, 96368, 96373, 96378, 96383, 96388, + 96393, 96398, 96403, 96408, 96413, 96418, 96423, 96428, 96433, 96438, + 96443, 96448, 96453, 96458, 96463, 96468, 96473, 96478, 96483, 96488, + 96493, 96498, 96503, 96508, 96513, 96518, 96523, 96528, 96533, 96538, + 96543, 96548, 96553, 96558, 96563, 96568, 96573, 96578, 96583, 96588, + 96593, 96598, 96603, 96608, 96613, 96618, 96623, 96628, 96633, 96638, + 96643, 96648, 96653, 96658, 96663, 96668, 96673, 96678, 96683, 96688, + 96693, 96698, 96703, 96708, 96713, 96718, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 96723, 96729, 96736, 96743, 96749, 96756, 96763, 96770, 96777, 96783, + 96790, 96797, 96804, 96811, 96818, 96825, 96832, 96839, 96846, 96853, + 96860, 96867, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96874, 96879, 96884, 96889, + 96894, 96899, 96904, 96909, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96914, 96918, 96922, + 96926, 96930, 96934, 0, 0, 96939, 0, 96944, 96948, 96953, 96958, 96963, + 96968, 96973, 96978, 96983, 96988, 96993, 96997, 97002, 97007, 97012, + 97017, 97021, 97026, 97031, 97036, 97041, 97045, 97050, 97055, 97060, + 97065, 97070, 97075, 97080, 97085, 97090, 97095, 97100, 97105, 97110, + 97115, 97120, 97125, 97130, 97134, 97139, 97144, 97149, 97154, 0, 97159, + 97164, 0, 0, 0, 97169, 0, 0, 97174, 97179, 97186, 97193, 97200, 97207, + 97214, 97221, 97228, 97235, 97242, 97249, 97256, 97263, 97270, 97277, + 97284, 97291, 97298, 97305, 97312, 97319, 97326, 0, 97333, 97340, 97346, + 97352, 97358, 97365, 97372, 97380, 97388, 97397, 97402, 97407, 97412, + 97417, 97422, 97427, 97432, 97437, 97442, 97447, 97452, 97457, 97462, + 97468, 97473, 97478, 97483, 97488, 97493, 97498, 97503, 97508, 97513, + 97519, 97525, 97529, 97533, 97537, 97541, 97545, 97550, 97555, 97561, + 97566, 97572, 97577, 97582, 97587, 97593, 97598, 97603, 97608, 97613, + 97618, 97624, 97629, 97635, 97640, 97646, 97651, 97657, 97662, 97668, + 97673, 97678, 97683, 97688, 97693, 97698, 97703, 97709, 97714, 0, 0, 0, + 0, 0, 0, 0, 0, 97719, 97723, 97727, 97731, 97735, 97741, 97745, 97750, + 97755, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97761, 97766, 97771, 97776, 97781, 97786, + 97791, 97796, 97801, 97806, 97811, 97816, 97821, 97826, 97831, 97836, + 97841, 97846, 97851, 97856, 97861, 97866, 97871, 97875, 97880, 97885, + 97891, 97895, 0, 0, 0, 97899, 97905, 97909, 97914, 97919, 97924, 97928, + 97933, 97937, 97942, 97947, 97951, 97956, 97961, 97965, 97969, 97974, + 97979, 97983, 97988, 97993, 97997, 98002, 98007, 98012, 98017, 98022, 0, + 0, 0, 0, 0, 98027, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 98032, + 98038, 98044, 98050, 98056, 98062, 98069, 98076, 98083, 98089, 98095, + 98101, 98108, 98115, 98122, 98129, 98136, 98143, 98150, 98157, 98164, + 98171, 98178, 98184, 98191, 98198, 98205, 98212, 98219, 98225, 98232, + 98239, 98246, 98252, 98258, 98264, 98270, 98276, 98283, 98290, 98296, + 98302, 98308, 98315, 98322, 98329, 98336, 98343, 98350, 98359, 98366, + 98372, 98379, 98386, 98393, 98399, 0, 0, 0, 0, 0, 0, 98406, 98414, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 98422, 98426, 98431, 98436, 0, + 98442, 98447, 0, 0, 0, 0, 0, 98452, 98458, 98465, 98470, 98475, 98479, + 98484, 98489, 0, 98494, 98499, 98504, 0, 98509, 98514, 98519, 98524, + 98529, 98534, 98539, 98544, 98549, 98554, 98559, 98563, 98567, 98572, + 98577, 98582, 98586, 98590, 98595, 98600, 98605, 98610, 98615, 98620, + 98625, 98629, 98634, 0, 0, 0, 0, 98639, 98645, 98650, 0, 0, 0, 0, 98655, + 98659, 98663, 98667, 98671, 98675, 98680, 98685, 98691, 0, 0, 0, 0, 0, 0, + 0, 0, 98697, 98703, 98710, 98716, 98723, 98729, 98735, 98741, 98748, 0, + 0, 0, 0, 0, 0, 0, 98754, 98761, 98768, 98775, 98782, 98789, 98796, 98803, + 98810, 98817, 98824, 98831, 98838, 98845, 98852, 98859, 98866, 98873, + 98880, 98887, 98894, 98901, 98908, 98915, 98922, 98929, 98936, 98943, + 98950, 98957, 98963, 98970, 98977, 98984, 98991, 98998, 99005, 99012, + 99019, 99026, 99033, 99040, 99047, 99054, 99061, 99068, 99075, 99082, + 99089, 99096, 99103, 99110, 99117, 99124, 99131, 99138, 99145, 99152, + 99159, 99166, 99173, 99180, 99186, 99193, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99200, + 99205, 99210, 99215, 99220, 99225, 99230, 99235, 99240, 99245, 99250, + 99255, 99260, 99265, 99270, 99275, 99280, 99285, 99290, 99295, 99300, + 99305, 99310, 99315, 99320, 99325, 99330, 99335, 99340, 99345, 99350, + 99355, 99360, 99365, 99370, 99375, 99380, 99385, 99391, 0, 0, 0, 0, + 99397, 99401, 99405, 99410, 99415, 99421, 99427, 99433, 99443, 99452, + 99458, 99465, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99473, 99477, 99482, 99487, + 99492, 99497, 99502, 99507, 99512, 99516, 99521, 99525, 99530, 99534, + 99539, 99543, 99548, 99553, 99558, 99563, 99568, 99573, 99578, 99583, + 99588, 99593, 99598, 99603, 99608, 99613, 99618, 99623, 99628, 99633, + 99638, 99643, 99648, 99653, 99658, 99663, 99668, 99673, 99678, 99683, + 99688, 99693, 99698, 99703, 99708, 99713, 99718, 99723, 99728, 99733, 0, + 0, 0, 99738, 99743, 99752, 99760, 99769, 99778, 99789, 99800, 99807, + 99814, 99821, 99828, 99835, 99842, 99849, 99856, 99863, 99870, 99877, + 99884, 99891, 99898, 99905, 99912, 99919, 99926, 99933, 99940, 99947, 0, + 0, 99954, 99960, 99966, 99972, 99978, 99985, 99992, 100000, 100008, + 100015, 100022, 100029, 100036, 100043, 100050, 100057, 100064, 100071, + 100078, 100085, 100092, 100099, 100106, 100113, 100120, 100127, 100134, + 0, 0, 0, 0, 0, 100141, 100147, 100153, 100159, 100165, 100172, 100179, + 100187, 100195, 100202, 100209, 100216, 100223, 100230, 100237, 100244, + 100251, 100258, 100265, 100272, 100279, 100286, 100293, 100300, 100307, + 100314, 0, 0, 0, 0, 0, 0, 0, 100321, 100328, 100336, 100346, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 100356, 100362, 100368, 100374, 100380, 100387, + 100394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100402, 100409, 100416, 100424, 100431, + 100438, 100445, 100452, 100460, 100468, 100476, 100484, 100492, 100500, + 100508, 100516, 100524, 100532, 100540, 100548, 100556, 100564, 100572, + 100580, 100588, 100596, 100604, 100612, 100620, 100628, 100636, 100644, + 100652, 100660, 100668, 100676, 100684, 100692, 100700, 100708, 100716, + 100724, 100732, 100740, 100748, 100756, 100764, 100772, 100780, 100788, + 100796, 100804, 100812, 100820, 100828, 100836, 100844, 100852, 100860, + 100868, 100876, 100884, 100892, 100900, 100908, 100916, 100924, 100932, + 100940, 100948, 100956, 100964, 100972, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 100980, 100984, 100988, 100992, 100996, 101000, 101004, + 101008, 101012, 101016, 101021, 101026, 101031, 101036, 101041, 101046, + 101051, 101056, 101061, 101067, 101073, 101079, 101086, 101093, 101100, + 101107, 101114, 101121, 101128, 101135, 101142, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 101149, 101153, 101157, 101161, 101165, 101169, 101172, 101176, + 101179, 101183, 101186, 101190, 101194, 101199, 101203, 101208, 101211, + 101215, 101218, 101222, 101225, 101229, 101233, 101237, 101241, 101245, + 101249, 101253, 101257, 101261, 101265, 101269, 101273, 101277, 101281, + 101285, 101289, 101293, 101297, 101300, 101303, 101307, 101311, 101315, + 101318, 101321, 101325, 101329, 101333, 101337, 101341, 101345, 101348, + 101352, 101358, 101364, 101370, 101375, 101382, 101386, 101391, 101395, + 101400, 101405, 101411, 101416, 101422, 101426, 101431, 101435, 101440, + 101443, 101446, 101450, 101455, 101461, 101466, 101472, 0, 0, 0, 0, + 101477, 101480, 101483, 101486, 101489, 101492, 101495, 101498, 101501, + 101504, 101508, 101512, 101516, 101520, 101524, 101528, 101532, 101536, + 101540, 101545, 101550, 101554, 101557, 101560, 101563, 101566, 101569, + 101572, 101575, 101578, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 101581, 101585, 101590, 101595, 101600, 101604, 101609, 101613, 101618, + 101622, 101627, 101631, 101636, 101640, 101645, 101649, 101654, 101659, + 101664, 101669, 101674, 101679, 101684, 101689, 101694, 101699, 101704, + 101709, 101714, 101719, 101724, 101729, 101734, 101739, 101744, 101749, + 101753, 101757, 101762, 101767, 101772, 101776, 101780, 101785, 101790, + 101795, 101800, 101805, 101810, 101814, 101820, 101825, 101831, 101836, + 101842, 101847, 101853, 101858, 101864, 101869, 101874, 101879, 101884, + 101888, 101893, 101899, 101903, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 101908, 101915, 101922, 101929, 101936, 101943, 101950, 101957, 101964, + 101971, 101978, 101985, 101992, 101999, 102006, 102013, 102020, 102027, + 102034, 102041, 102048, 102055, 102062, 102069, 102076, 0, 0, 0, 0, 0, 0, + 0, 102083, 102090, 102096, 102102, 102108, 102114, 102120, 102126, + 102132, 102138, 0, 0, 0, 0, 0, 0, 102144, 102149, 102154, 102159, 102164, + 102168, 102172, 102176, 102181, 102186, 102191, 102196, 102201, 102206, + 102211, 102216, 102221, 102226, 102231, 102236, 102241, 102246, 102251, + 102256, 102261, 102266, 102271, 102276, 102281, 102286, 102291, 102296, + 102301, 102306, 102311, 102316, 102321, 102326, 102331, 102336, 102341, + 102346, 102352, 102357, 102363, 102368, 102374, 102379, 102385, 102391, + 102395, 102400, 102404, 0, 102408, 102413, 102417, 102421, 102425, + 102429, 102433, 102437, 102441, 102445, 102449, 102454, 102458, 102463, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102468, 102472, 102476, 102480, + 102484, 102488, 102492, 102497, 102502, 102507, 102512, 102517, 102522, + 102527, 102532, 102537, 102542, 102547, 102552, 102557, 102562, 102567, + 102572, 102577, 102581, 102585, 102590, 102595, 102600, 102604, 102609, + 102614, 102619, 102624, 102628, 102633, 102638, 102643, 102648, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 102653, 102657, 102661, 102665, 102668, 102672, 102675, + 102679, 102682, 102686, 102690, 102695, 102699, 102704, 102707, 102711, + 102714, 102718, 102721, 102725, 102729, 102733, 102737, 102741, 102745, + 102749, 102753, 102757, 102761, 102765, 102769, 102773, 102777, 102781, + 102785, 102789, 102793, 102796, 102799, 102803, 102807, 102811, 102814, + 102817, 102821, 102825, 102829, 102833, 102837, 102841, 102845, 102848, + 102853, 102857, 102862, 102866, 102871, 102876, 102882, 102887, 102893, + 102897, 102902, 102906, 102911, 102915, 102919, 102923, 102927, 102930, + 102933, 102937, 102941, 0, 0, 0, 0, 102944, 0, 0, 102948, 102952, 102955, + 102958, 102961, 102964, 102967, 102970, 102973, 102976, 102979, 0, 0, 0, + 0, 0, 0, 102982, 102987, 102992, 102997, 103002, 103007, 103012, 103017, + 103022, 103027, 103033, 103039, 103045, 103051, 103057, 103063, 103069, + 103075, 103081, 103088, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 103095, 103099, + 103104, 103108, 103112, 103116, 103121, 103125, 103130, 103134, 103139, + 103144, 103149, 103154, 103159, 103164, 103169, 103174, 0, 103179, + 103184, 103189, 103194, 103199, 103204, 103209, 103214, 103219, 103224, + 103229, 103234, 103238, 103242, 103247, 103252, 103257, 103262, 103266, + 103270, 103275, 103280, 103285, 103290, 103294, 103299, 103305, 103310, + 103316, 103321, 103326, 103332, 103337, 103343, 103348, 103353, 103358, + 103363, 103367, 103372, 103378, 103383, 103389, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 103394, 103398, 103403, 103407, 103412, + 103416, 103421, 103425, 103430, 103434, 103439, 103443, 103448, 103453, + 103458, 103463, 103468, 103473, 103478, 103483, 103488, 103493, 103498, + 103503, 103508, 103513, 103518, 103523, 103528, 103533, 103538, 103543, + 103548, 103553, 103557, 103561, 103566, 103571, 103576, 103581, 103585, + 103589, 103594, 103599, 103604, 103609, 103614, 103618, 103623, 103629, + 103634, 103640, 103645, 103651, 103656, 103662, 103667, 103673, 103678, + 0, 0, 0, 0, 0, 103683, 103688, 103692, 103696, 103700, 103704, 103708, + 103712, 103716, 103720, 0, 0, 0, 0, 0, 0, 0, 103724, 103729, 103734, 0, + 103739, 103743, 103748, 103752, 103757, 103761, 103766, 103771, 0, 0, + 103776, 103781, 0, 0, 103786, 103791, 103796, 103800, 103805, 103810, + 103815, 103820, 103825, 103830, 103835, 103840, 103845, 103850, 103855, + 103860, 103865, 103870, 103875, 103880, 103885, 103890, 0, 103894, + 103898, 103903, 103908, 103913, 103917, 103921, 0, 103926, 103931, 0, + 103936, 103941, 103946, 103951, 103956, 0, 0, 103960, 103965, 103970, + 103976, 103981, 103987, 103992, 103998, 104004, 0, 0, 104011, 104017, 0, + 0, 104023, 104029, 104035, 0, 0, 0, 0, 0, 0, 0, 0, 0, 104040, 0, 0, 0, 0, + 0, 104047, 104052, 104059, 104067, 104073, 104079, 104085, 0, 0, 104092, + 104098, 104103, 104108, 104113, 104118, 104123, 0, 0, 0, 104128, 104133, + 104138, 104143, 104149, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 104154, 104158, 104162, 104167, 104171, + 104176, 104180, 104185, 104190, 104196, 104201, 104207, 104211, 104216, + 104220, 104225, 104229, 104234, 104239, 104244, 104249, 104254, 104259, + 104264, 104269, 104274, 104279, 104284, 104289, 104294, 104299, 104304, + 104309, 104314, 104319, 104323, 104327, 104332, 104337, 104342, 104346, + 104350, 104355, 104360, 104365, 104370, 104375, 104380, 104384, 104390, + 104395, 104401, 104406, 104412, 104418, 104425, 104431, 104438, 104443, + 104450, 104456, 104461, 104468, 104474, 104479, 104484, 104489, 104494, + 104499, 104504, 104508, 104513, 0, 0, 0, 0, 0, 0, 0, 0, 104517, 104522, + 104526, 104530, 104534, 104538, 104542, 104546, 104550, 104554, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 104558, 104562, + 104567, 104571, 104576, 104580, 104585, 104590, 104596, 104601, 104607, + 104611, 104616, 104620, 104625, 104629, 104634, 104639, 104644, 104649, + 104654, 104659, 104664, 104669, 104674, 104679, 104684, 104689, 104694, + 104699, 104704, 104709, 104714, 104719, 104723, 104727, 104732, 104737, + 104742, 104746, 104750, 104755, 104760, 104765, 104770, 104775, 104780, + 104784, 104790, 104795, 104801, 104806, 104812, 104818, 0, 0, 104825, + 104830, 104836, 104841, 104847, 104852, 104857, 104862, 104867, 104872, + 104877, 104881, 104886, 104892, 104897, 104903, 104909, 104915, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 104923, 104927, 104932, 104936, 104941, 104945, 104950, 104955, + 104961, 104966, 104972, 104976, 104981, 104985, 104990, 104994, 104999, + 105004, 105009, 105014, 105019, 105024, 105029, 105034, 105039, 105044, + 105049, 105054, 105059, 105064, 105069, 105074, 105079, 105084, 105088, + 105092, 105097, 105102, 105107, 105111, 105115, 105120, 105125, 105130, + 105135, 105140, 105145, 105149, 105154, 105160, 105165, 105171, 105176, + 105182, 105188, 105195, 105201, 105208, 105213, 105219, 105224, 105230, + 105235, 105240, 105245, 105250, 105254, 105259, 105264, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 105269, 105274, 105278, 105282, 105286, 105290, 105294, + 105298, 105302, 105306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 105310, + 105314, 105319, 105323, 105328, 105332, 105337, 105341, 105346, 105350, + 105355, 105359, 105364, 105369, 105374, 105379, 105384, 105389, 105394, + 105399, 105404, 105409, 105414, 105419, 105424, 105429, 105434, 105439, + 105444, 105449, 105453, 105457, 105462, 105467, 105472, 105476, 105480, + 105485, 105490, 105495, 105500, 105505, 105509, 105514, 105519, 105524, + 105530, 105535, 105541, 105546, 105552, 105557, 105563, 105568, 105574, + 105579, 0, 0, 0, 0, 0, 0, 0, 0, 105584, 105589, 105593, 105597, 105601, + 105605, 105609, 105613, 105617, 105621, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 105625, 105631, 105636, 105642, 105648, + 105653, 105659, 105665, 105671, 105676, 105681, 105687, 105693, 105699, + 105705, 105711, 105717, 105723, 105729, 105735, 105741, 105747, 105753, + 105759, 105765, 105771, 105777, 105783, 105789, 105795, 105801, 105807, + 105813, 105819, 105824, 105830, 105836, 105841, 105847, 105853, 105859, + 105864, 105869, 105875, 105881, 105887, 105893, 105899, 105905, 105911, + 105917, 105923, 105929, 105935, 105941, 105947, 105953, 105959, 105965, + 105971, 105977, 105983, 105989, 105995, 106001, 106006, 106010, 106014, + 106018, 106022, 106026, 106030, 106034, 106038, 106042, 106047, 106052, + 106057, 106062, 106067, 106072, 106077, 106082, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 106087, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 106091, 106099, 106107, 106116, 106124, 106133, 106142, + 106151, 106160, 106168, 106177, 106186, 106195, 106204, 106213, 106222, + 106231, 106239, 106248, 106257, 106266, 106275, 106283, 106291, 106299, + 106307, 106315, 106324, 106333, 106343, 106353, 106363, 106373, 106383, + 106392, 106402, 106412, 106422, 106433, 106443, 106455, 106467, 106478, + 106492, 106503, 106513, 106525, 106536, 106546, 106558, 106570, 106581, + 106592, 106602, 106612, 106624, 106635, 0, 0, 0, 0, 0, 0, 0, 106647, + 106650, 106655, 106661, 106669, 106674, 106680, 106688, 106694, 106700, + 106704, 106708, 106715, 106724, 106731, 106740, 106746, 106755, 106762, + 106769, 106776, 106786, 106792, 106796, 106803, 106812, 106822, 106829, + 106836, 106840, 106844, 106851, 106861, 106865, 106872, 106879, 106886, + 106892, 106899, 106906, 106913, 106920, 106924, 106928, 106932, 106939, + 106943, 106950, 106957, 106971, 106980, 106984, 106988, 106992, 106999, + 107003, 107007, 107011, 107019, 107027, 107046, 107056, 107076, 107080, + 107084, 107088, 107092, 107096, 107100, 107104, 107111, 107115, 107118, + 107122, 107126, 107132, 107139, 107148, 107152, 107161, 107170, 107178, + 107182, 107189, 107193, 107197, 107201, 107205, 107216, 107225, 107234, + 107243, 107252, 107264, 107273, 107282, 107291, 107299, 107308, 107320, + 107329, 107338, 107347, 107359, 107368, 107377, 107389, 107398, 107407, + 107419, 107428, 107432, 107436, 107440, 107444, 107448, 107452, 107456, + 107463, 107467, 107471, 107482, 107486, 107490, 107497, 107503, 107509, + 107513, 107520, 107524, 107528, 107532, 107536, 107540, 107544, 107550, + 107558, 107562, 107566, 107569, 107575, 107585, 107589, 107601, 107608, + 107615, 107622, 107629, 107635, 107639, 107643, 107647, 107651, 107658, + 107667, 107674, 107682, 107690, 107696, 107700, 107704, 107708, 107712, + 107718, 107727, 107739, 107746, 107753, 107762, 107773, 107779, 107788, + 107797, 107804, 107813, 107820, 107827, 107837, 107844, 107851, 107858, + 107865, 107869, 107875, 107879, 107890, 107898, 107907, 107919, 107926, + 107933, 107943, 107950, 107960, 107967, 107977, 107984, 107991, 108001, + 108008, 108015, 108025, 108032, 108044, 108053, 108060, 108067, 108074, + 108083, 108093, 108106, 108113, 108123, 108133, 108140, 108149, 108162, + 108169, 108176, 108183, 108193, 108203, 108210, 108220, 108227, 108234, + 108244, 108250, 108257, 108264, 108271, 108281, 108288, 108295, 108302, + 108308, 108315, 108325, 108332, 108336, 108344, 108348, 108360, 108364, + 108378, 108382, 108386, 108390, 108394, 108400, 108407, 108415, 108419, + 108423, 108427, 108431, 108438, 108442, 108448, 108454, 108462, 108466, + 108473, 108481, 108485, 108489, 108495, 108499, 108508, 108517, 108524, + 108534, 108540, 108544, 108548, 108556, 108563, 108570, 108576, 108580, + 108588, 108592, 108599, 108611, 108618, 108628, 108634, 108638, 108647, + 108654, 108663, 108667, 108671, 108678, 108682, 108686, 108690, 108694, + 108697, 108703, 108709, 108713, 108717, 108724, 108731, 108738, 108745, + 108752, 108759, 108766, 108773, 108779, 108783, 108787, 108794, 108801, + 108808, 108815, 108822, 108826, 108829, 108834, 108838, 108842, 108851, + 108860, 108864, 108868, 108874, 108880, 108897, 108903, 108907, 108916, + 108920, 108924, 108931, 108939, 108947, 108953, 108957, 108961, 108965, + 108969, 108972, 108978, 108985, 108995, 109002, 109009, 109016, 109022, + 109029, 109036, 109043, 109050, 109057, 109066, 109073, 109085, 109092, + 109099, 109109, 109120, 109127, 109134, 109141, 109148, 109155, 109162, + 109169, 109176, 109183, 109190, 109200, 109210, 109220, 109227, 109237, + 109244, 109251, 109258, 109265, 109272, 109279, 109286, 109293, 109300, + 109307, 109314, 109321, 109328, 109334, 109341, 109348, 109357, 109364, + 109371, 109375, 109383, 109387, 109391, 109395, 109399, 109403, 109410, + 109414, 109423, 109427, 109434, 109442, 109446, 109450, 109454, 109467, + 109483, 109487, 109491, 109498, 109504, 109511, 109515, 109519, 109523, + 109527, 109531, 109538, 109542, 109560, 109564, 109568, 109575, 109579, + 109583, 109589, 109593, 109597, 109605, 109609, 109613, 109617, 109621, + 109627, 109638, 109647, 109656, 109663, 109670, 109681, 109688, 109695, + 109702, 109709, 109716, 109723, 109730, 109740, 109746, 109753, 109763, + 109772, 109779, 109788, 109798, 109805, 109812, 109819, 109826, 109838, + 109845, 109852, 109859, 109866, 109873, 109883, 109890, 109897, 109907, + 109920, 109932, 109939, 109949, 109956, 109963, 109970, 109984, 109990, + 109998, 110008, 110018, 110025, 110032, 110038, 110042, 110049, 110059, + 110065, 110078, 110082, 110086, 110093, 110097, 110104, 110114, 110118, + 110122, 110126, 110130, 110134, 110141, 110145, 110152, 110159, 110166, + 110175, 110184, 110194, 110201, 110208, 110215, 110225, 110232, 110242, + 110249, 110259, 110266, 110273, 110283, 110293, 110300, 110306, 110314, + 110322, 110328, 110334, 110338, 110342, 110349, 110357, 110363, 110367, + 110371, 110375, 110382, 110394, 110397, 110404, 110410, 110414, 110418, + 110422, 110426, 110430, 110434, 110438, 110442, 110446, 110450, 110457, + 110461, 110467, 110471, 110475, 110479, 110485, 110492, 110499, 110506, + 110517, 110525, 110529, 110535, 110544, 110551, 110557, 110560, 110564, + 110568, 110574, 110583, 110591, 110595, 110601, 110605, 110609, 110613, + 110619, 110626, 110632, 110636, 110642, 110646, 110650, 110659, 110671, + 110675, 110682, 110689, 110699, 110706, 110718, 110725, 110732, 110739, + 110750, 110760, 110773, 110783, 110790, 110794, 110798, 110802, 110806, + 110815, 110824, 110833, 110850, 110859, 110865, 110872, 110880, 110893, + 110897, 110906, 110915, 110924, 110933, 110944, 110953, 110962, 110971, + 110980, 110989, 110998, 111008, 111011, 111015, 111019, 111023, 111027, + 111031, 111037, 111044, 111051, 111058, 111064, 111070, 111077, 111083, + 111090, 111098, 111102, 111109, 111116, 111123, 111131, 111135, 111139, + 111143, 111147, 111151, 111157, 111161, 111167, 111174, 111181, 111187, + 111194, 111201, 111208, 111215, 111222, 111229, 111236, 111243, 111250, + 111257, 111264, 111271, 111278, 111285, 111291, 111295, 111304, 111308, + 111312, 111316, 111320, 111326, 111333, 111340, 111347, 111354, 111361, + 111367, 111375, 111379, 111383, 111387, 111391, 111397, 111414, 111431, + 111435, 111439, 111443, 111447, 111451, 111455, 111461, 111468, 111472, + 111478, 111485, 111492, 111499, 111506, 111513, 111522, 111529, 111536, + 111543, 111550, 111554, 111558, 111564, 111576, 111580, 111584, 111593, + 111597, 111601, 111605, 111611, 111615, 111619, 111628, 111632, 111636, + 111640, 111647, 111651, 111655, 111659, 111663, 111667, 111671, 111675, + 111679, 111685, 111692, 111699, 111705, 111709, 111726, 111732, 111736, + 111742, 111748, 111754, 111760, 111766, 111772, 111776, 111780, 111784, + 111790, 111794, 111800, 111804, 111808, 111815, 111822, 111839, 111843, + 111847, 111851, 111855, 111859, 111871, 111874, 111879, 111884, 111899, + 111909, 111921, 111925, 111929, 111933, 111939, 111946, 111953, 111963, + 111975, 111981, 111987, 111996, 112000, 112004, 112011, 112021, 112028, + 112034, 112038, 112042, 112049, 112055, 112059, 112065, 112069, 112077, + 112083, 112087, 112095, 112103, 112110, 112116, 112123, 112130, 112140, + 112150, 112154, 112158, 112162, 112166, 112172, 112179, 112185, 112192, + 112199, 112206, 112215, 112222, 112229, 112235, 112242, 112249, 112256, + 112263, 112270, 112277, 112283, 112290, 112297, 112304, 112313, 112320, + 112327, 112331, 112337, 112341, 112347, 112354, 112361, 112368, 112372, + 112376, 112380, 112384, 112388, 112395, 112399, 112403, 112409, 112417, + 112421, 112425, 112429, 112433, 112440, 112444, 112448, 112456, 112460, + 112464, 112468, 112472, 112478, 112482, 112486, 112492, 112499, 112505, + 112512, 112524, 112528, 112535, 112542, 112549, 112556, 112568, 112575, + 112579, 112583, 112587, 112594, 112601, 112608, 112615, 112625, 112632, + 112638, 112645, 112652, 112659, 112666, 112675, 112685, 112692, 112696, + 112703, 112707, 112711, 112715, 112722, 112729, 112739, 112745, 112749, + 112758, 112762, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 112769, 112775, 112781, 112788, + 112795, 112802, 112809, 112816, 112823, 112829, 112836, 112843, 112850, + 112857, 112864, 112871, 112877, 112883, 112889, 112895, 112901, 112907, + 112913, 112919, 112925, 112932, 112939, 112946, 112953, 112960, 112967, + 112973, 112979, 112985, 112992, 112999, 113005, 113011, 113020, 113027, + 113034, 113041, 113048, 113055, 113062, 113068, 113074, 113080, 113089, + 113096, 113103, 113114, 113125, 113131, 113137, 113143, 113152, 113159, + 113166, 113176, 113186, 113197, 113208, 113220, 113233, 113244, 113255, + 113267, 113280, 113291, 113302, 113313, 113324, 113335, 113347, 113355, + 113363, 113372, 113381, 113390, 113396, 113402, 113408, 113415, 113425, + 113432, 113442, 113447, 113452, 113458, 113464, 113472, 113480, 113489, + 113500, 113511, 113519, 113527, 113536, 113545, 113553, 113560, 113568, + 113576, 113583, 113590, 113599, 113608, 113617, 113626, 113635, 0, + 113644, 113655, 113662, 113670, 113678, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 113686, 113690, 113694, 113698, 113702, 113706, + 113710, 113714, 113718, 113722, 113726, 113730, 113734, 113738, 113742, + 113746, 113750, 113754, 113758, 113762, 113766, 113770, 113774, 113778, + 113782, 113786, 113790, 113794, 113798, 113802, 113806, 113810, 113814, + 113818, 113822, 113826, 113830, 113834, 113838, 113842, 113846, 113850, + 113854, 113858, 113862, 113866, 113870, 113874, 113878, 113882, 113886, + 113890, 113894, 113898, 113902, 113906, 113910, 113914, 113918, 113922, + 113926, 113930, 113934, 113938, 113942, 113946, 113950, 113954, 113958, + 113962, 113966, 113970, 113974, 113978, 113982, 113986, 113990, 113994, + 113998, 114002, 114006, 114010, 114014, 114018, 114022, 114026, 114030, + 114034, 114038, 114042, 114046, 114050, 114054, 114058, 114062, 114066, + 114070, 114074, 114078, 114082, 114086, 114090, 114094, 114098, 114102, + 114106, 114110, 114114, 114118, 114122, 114126, 114130, 114134, 114138, + 114142, 114146, 114150, 114154, 114158, 114162, 114166, 114170, 114174, + 114178, 114182, 114186, 114190, 114194, 114198, 114202, 114206, 114210, + 114214, 114218, 114222, 114226, 114230, 114234, 114238, 114242, 114246, + 114250, 114254, 114258, 114262, 114266, 114270, 114274, 114278, 114282, + 114286, 114290, 114294, 114298, 114302, 114306, 114310, 114314, 114318, + 114322, 114326, 114330, 114334, 114338, 114342, 114346, 114350, 114354, + 114358, 114362, 114366, 114370, 114374, 114378, 114382, 114386, 114390, + 114394, 114398, 114402, 114406, 114410, 114414, 114418, 114422, 114426, + 114430, 114434, 114438, 114442, 114446, 114450, 114454, 114458, 114462, + 114466, 114470, 114474, 114478, 114482, 114486, 114490, 114494, 114498, + 114502, 114506, 114510, 114514, 114518, 114522, 114526, 114530, 114534, + 114538, 114542, 114546, 114550, 114554, 114558, 114562, 114566, 114570, + 114574, 114578, 114582, 114586, 114590, 114594, 114598, 114602, 114606, + 114610, 114614, 114618, 114622, 114626, 114630, 114634, 114638, 114642, + 114646, 114650, 114654, 114658, 114662, 114666, 114670, 114674, 114678, + 114682, 114686, 114690, 114694, 114698, 114702, 114706, 114710, 114714, + 114718, 114722, 114726, 114730, 114734, 114738, 114742, 114746, 114750, + 114754, 114758, 114762, 114766, 114770, 114774, 114778, 114782, 114786, + 114790, 114794, 114798, 114802, 114806, 114810, 114814, 114818, 114822, + 114826, 114830, 114834, 114838, 114842, 114846, 114850, 114854, 114858, + 114862, 114866, 114870, 114874, 114878, 114882, 114886, 114890, 114894, + 114898, 114902, 114906, 114910, 114914, 114918, 114922, 114926, 114930, + 114934, 114938, 114942, 114946, 114950, 114954, 114958, 114962, 114966, + 114970, 114974, 114978, 114982, 114986, 114990, 114994, 114998, 115002, + 115006, 115010, 115014, 115018, 115022, 115026, 115030, 115034, 115038, + 115042, 115046, 115050, 115054, 115058, 115062, 115066, 115070, 115074, + 115078, 115082, 115086, 115090, 115094, 115098, 115102, 115106, 115110, + 115114, 115118, 115122, 115126, 115130, 115134, 115138, 115142, 115146, + 115150, 115154, 115158, 115162, 115166, 115170, 115174, 115178, 115182, + 115186, 115190, 115194, 115198, 115202, 115206, 115210, 115214, 115218, + 115222, 115226, 115230, 115234, 115238, 115242, 115246, 115250, 115254, + 115258, 115262, 115266, 115270, 115274, 115278, 115282, 115286, 115290, + 115294, 115298, 115302, 115306, 115310, 115314, 115318, 115322, 115326, + 115330, 115334, 115338, 115342, 115346, 115350, 115354, 115358, 115362, + 115366, 115370, 115374, 115378, 115382, 115386, 115390, 115394, 115398, + 115402, 115406, 115410, 115414, 115418, 115422, 115426, 115430, 115434, + 115438, 115442, 115446, 115450, 115454, 115458, 115462, 115466, 115470, + 115474, 115478, 115482, 115486, 115490, 115494, 115498, 115502, 115506, + 115510, 115514, 115518, 115522, 115526, 115530, 115534, 115538, 115542, + 115546, 115550, 115554, 115558, 115562, 115566, 115570, 115574, 115578, + 115582, 115586, 115590, 115594, 115598, 115602, 115606, 115610, 115614, + 115618, 115622, 115626, 115630, 115634, 115638, 115642, 115646, 115650, + 115654, 115658, 115662, 115666, 115670, 115674, 115678, 115682, 115686, + 115690, 115694, 115698, 115702, 115706, 115710, 115714, 115718, 115722, + 115726, 115730, 115734, 115738, 115742, 115746, 115750, 115754, 115758, + 115762, 115766, 115770, 115774, 115778, 115782, 115786, 115790, 115794, + 115798, 115802, 115806, 115810, 115814, 115818, 115822, 115826, 115830, + 115834, 115838, 115842, 115846, 115850, 115854, 115858, 115862, 115866, + 115870, 115874, 115878, 115882, 115886, 115890, 115894, 115898, 115902, + 115906, 115910, 115914, 115918, 115922, 115926, 115930, 115934, 115938, + 115942, 115946, 115950, 115954, 115958, 115962, 115966, 115970, 115974, + 115978, 115982, 115986, 115990, 115994, 115998, 116002, 116006, 116010, + 116014, 116018, 116022, 116026, 116030, 116034, 116038, 116042, 116046, + 116050, 116054, 116058, 116062, 116066, 116070, 116074, 116078, 116082, + 116086, 116090, 116094, 116098, 116102, 116106, 116110, 116114, 116118, + 116122, 116126, 116130, 116134, 116138, 116142, 116146, 116150, 116154, + 116158, 116162, 116166, 116170, 116174, 116178, 116182, 116186, 116190, + 116194, 116198, 116202, 116206, 116210, 116214, 116218, 116222, 116226, + 116230, 116234, 116238, 116242, 116246, 116250, 116254, 116258, 116262, + 116266, 116270, 116274, 116278, 116282, 116286, 116290, 116294, 116298, + 116302, 116306, 116310, 116314, 116318, 116322, 116326, 116330, 116334, + 116338, 116342, 116346, 116350, 116354, 116358, 116362, 116366, 116370, + 116374, 116378, 116382, 116386, 116390, 116394, 116398, 116402, 116406, + 116410, 116414, 116418, 116422, 116426, 116430, 116434, 116438, 116442, + 116446, 116450, 116454, 116458, 116462, 116466, 116470, 116474, 116478, + 116482, 116486, 116490, 116494, 116498, 116502, 116506, 116510, 116514, + 116518, 116522, 116526, 116530, 116534, 116538, 116542, 116546, 116550, + 116554, 116558, 116562, 116566, 116570, 116574, 116578, 116582, 116586, + 116590, 116594, 116598, 116602, 116606, 116610, 116614, 116618, 116622, + 116626, 116630, 116634, 116638, 116642, 116646, 116650, 116654, 116658, + 116662, 116666, 116670, 116674, 116678, 116682, 116686, 116690, 116694, + 116698, 116702, 116706, 116710, 116714, 116718, 116722, 116726, 116730, + 116734, 116738, 116742, 116746, 116750, 116754, 116758, 116762, 116766, + 116770, 116774, 116778, 116782, 116786, 116790, 116794, 116798, 116802, + 116806, 116810, 116814, 116818, 116822, 116826, 116830, 116834, 116838, + 116842, 116846, 116850, 116854, 116858, 116862, 116866, 116870, 116874, + 116878, 116882, 116886, 116890, 116894, 116898, 116902, 116906, 116910, + 116914, 116918, 116922, 116926, 116930, 116934, 116938, 116942, 116946, + 116950, 116954, 116958, 116962, 116966, 116970, 116974, 116978, 116982, + 116986, 116990, 116994, 116998, 117002, 117006, 117010, 117014, 117018, + 117022, 117026, 117030, 117034, 117038, 117042, 117046, 117050, 117054, + 117058, 117062, 117066, 117070, 117074, 117078, 117082, 117086, 117090, + 117094, 117098, 117102, 117106, 117110, 117114, 117118, 117122, 117126, + 117130, 117134, 117138, 117142, 117146, 117150, 117154, 117158, 117162, + 117166, 117170, 117174, 117178, 117182, 117186, 117190, 117194, 117198, + 117202, 117206, 117210, 117214, 117218, 117222, 117226, 117230, 117234, + 117238, 117242, 117246, 117250, 117254, 117258, 117262, 117266, 117270, + 117274, 117278, 117282, 117286, 117290, 117294, 117298, 117302, 117306, + 117310, 117314, 117318, 117322, 117326, 117330, 117334, 117338, 117342, + 117346, 117350, 117354, 117358, 117362, 117366, 117370, 117374, 117378, + 117382, 117386, 117390, 117394, 117398, 117402, 117406, 117410, 117414, + 117418, 117422, 117426, 117430, 117434, 117438, 117442, 117446, 117450, + 117454, 117458, 117462, 117466, 117470, 117474, 117478, 117482, 117486, + 117490, 117494, 117498, 117502, 117506, 117510, 117514, 117518, 117522, + 117526, 117530, 117534, 117538, 117542, 117546, 117550, 117554, 117558, + 117562, 117566, 117570, 117574, 117578, 117582, 117586, 117590, 117594, + 117598, 117602, 117606, 117610, 117614, 117618, 117622, 117626, 117630, + 117634, 117638, 117642, 117646, 117650, 117654, 117658, 117662, 117666, + 117670, 117674, 117678, 117682, 117686, 117690, 117694, 117698, 117702, + 117706, 117710, 117714, 117718, 117722, 117726, 117730, 117734, 117738, + 117742, 117746, 117750, 117754, 117758, 117762, 117766, 117770, 117774, + 117778, 117782, 117786, 117790, 117794, 117798, 117802, 117806, 117810, + 117814, 117818, 117822, 117826, 117830, 117834, 117838, 117842, 117846, + 117850, 117854, 117858, 117862, 117866, 117870, 117874, 117878, 117882, + 117886, 117890, 117894, 117898, 117902, 117906, 117910, 117914, 117918, + 117922, 117926, 117930, 117934, 117938, 117942, 117946, 117950, 117954, + 117958, 117962, 117966, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 117970, 117977, 117984, 117993, 118002, 118009, 118014, 118021, + 118028, 118037, 118048, 118059, 118064, 118071, 118076, 118081, 118086, + 118091, 118096, 118101, 118106, 118111, 118116, 118121, 118126, 118133, + 118140, 118145, 118150, 118155, 118160, 118167, 118174, 118182, 118187, + 118194, 118199, 118204, 118209, 118214, 118219, 118226, 118233, 118238, + 118243, 118248, 118253, 118258, 118263, 118268, 118273, 118278, 118283, + 118288, 118293, 118298, 118303, 118308, 118313, 118318, 118323, 118328, + 118335, 118340, 118345, 118354, 118361, 118366, 118371, 118376, 118381, + 118386, 118391, 118396, 118401, 118406, 118411, 118416, 118421, 118426, + 118431, 118436, 118441, 118446, 118451, 118456, 118461, 118466, 118472, + 118480, 118486, 118494, 118502, 118510, 118516, 118522, 118528, 118534, + 118540, 118548, 118558, 118566, 118574, 118580, 118586, 118594, 118602, + 118608, 118616, 118624, 118632, 118638, 118644, 118650, 118656, 118662, + 118668, 118676, 118684, 118690, 118696, 118702, 118708, 118714, 118722, + 118728, 118734, 118740, 118746, 118752, 118758, 118766, 118772, 118778, + 118784, 118790, 118798, 118806, 118812, 118818, 118824, 118829, 118835, + 118841, 118848, 118853, 118858, 118863, 118868, 118873, 118878, 118883, + 118888, 118893, 118902, 118909, 118914, 118919, 118924, 118931, 118936, + 118941, 118946, 118953, 118958, 118963, 118968, 118973, 118978, 118983, + 118988, 118993, 118998, 119003, 119008, 119015, 119020, 119027, 119032, + 119037, 119044, 119049, 119054, 119059, 119064, 119069, 119074, 119079, + 119084, 119089, 119094, 119099, 119104, 119109, 119114, 119119, 119124, + 119129, 119134, 119139, 119146, 119151, 119156, 119161, 119166, 119171, + 119176, 119181, 119186, 119191, 119196, 119201, 119206, 119211, 119218, + 119223, 119228, 119235, 119240, 119245, 119250, 119255, 119260, 119265, + 119270, 119275, 119280, 119285, 119292, 119297, 119302, 119307, 119312, + 119317, 119324, 119331, 119336, 119341, 119346, 119351, 119356, 119361, + 119366, 119371, 119376, 119381, 119386, 119391, 119396, 119401, 119406, + 119411, 119416, 119421, 119426, 119431, 119436, 119441, 119446, 119451, + 119456, 119461, 119466, 119471, 119476, 119481, 119486, 119491, 119496, + 119501, 119506, 119511, 119518, 119523, 119528, 119533, 119538, 119543, + 119548, 119553, 119558, 119563, 119568, 119573, 119578, 119583, 119588, + 119593, 119598, 119603, 119608, 119613, 119618, 119623, 119628, 119633, + 119638, 119643, 119648, 119653, 119658, 119663, 119668, 119673, 119678, + 119683, 119688, 119693, 119698, 119703, 119708, 119713, 119718, 119723, + 119728, 119733, 119738, 119743, 119748, 119753, 119758, 119763, 119768, + 119773, 119778, 119783, 119788, 119793, 119798, 119803, 119808, 119815, + 119820, 119825, 119830, 119835, 119840, 119845, 119850, 119855, 119860, + 119865, 119870, 119875, 119880, 119885, 119890, 119895, 119900, 119905, + 119910, 119915, 119920, 119927, 119932, 119937, 119943, 119948, 119953, + 119958, 119963, 119968, 119973, 119978, 119983, 119988, 119993, 119998, + 120003, 120008, 120013, 120018, 120023, 120028, 120033, 120038, 120043, + 120048, 120053, 120058, 120063, 120068, 120073, 120078, 120083, 120088, + 120093, 120098, 120103, 120108, 120113, 120118, 120123, 120128, 120133, + 120138, 120143, 120148, 120153, 120158, 120165, 120170, 120175, 120182, + 120189, 120194, 120199, 120204, 120209, 120214, 120219, 120224, 120229, + 120234, 120239, 120244, 120249, 120254, 120259, 120264, 120269, 120274, + 120279, 120284, 120289, 120294, 120299, 120304, 120309, 120314, 120321, + 120326, 120331, 120336, 120341, 120346, 120351, 120356, 120361, 120366, + 120371, 120376, 120381, 120386, 120391, 120396, 120401, 120406, 120411, + 120418, 120423, 120428, 120433, 120438, 120443, 120448, 120453, 120459, + 120464, 120469, 120474, 120479, 120484, 120489, 120494, 120499, 120506, + 120513, 120518, 120523, 120527, 120532, 120536, 120540, 120545, 120552, + 120557, 120562, 120571, 120576, 120581, 120586, 120591, 120598, 120605, + 120610, 120615, 120620, 120625, 120632, 120637, 120642, 120647, 120652, + 120657, 120662, 120667, 120672, 120677, 120682, 120687, 120692, 120699, + 120703, 120708, 120713, 120718, 120723, 120727, 120732, 120737, 120742, + 120747, 120752, 120757, 120762, 120767, 120772, 120778, 120784, 120790, + 120796, 120802, 120808, 120814, 120820, 120826, 120832, 120838, 120844, + 120850, 120856, 120862, 120868, 120874, 120880, 120886, 120892, 120898, + 120904, 120910, 120916, 120921, 120927, 120933, 120939, 120945, 120951, + 120957, 120963, 120969, 120975, 120981, 120987, 120993, 120999, 121005, + 121011, 121017, 121023, 121029, 121035, 121041, 121046, 121052, 121058, + 121064, 121070, 121076, 0, 0, 0, 0, 0, 0, 0, 121082, 121087, 121092, + 121097, 121102, 121107, 121112, 121116, 121121, 121126, 121131, 121136, + 121141, 121146, 121151, 121156, 121161, 121165, 121170, 121174, 121179, + 121184, 121189, 121194, 121199, 121203, 121208, 121213, 121218, 121223, + 121228, 0, 121233, 121238, 121242, 121246, 121250, 121254, 121258, + 121262, 121266, 121270, 0, 0, 0, 0, 121274, 121278, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 121283, 121290, + 121296, 121303, 121310, 121317, 121324, 121331, 121338, 121345, 121352, + 121359, 121366, 121373, 121380, 121387, 121394, 121401, 121407, 121414, + 121421, 121428, 121434, 121441, 121447, 121453, 121460, 121466, 121473, + 121479, 0, 0, 121485, 121493, 121501, 121510, 121519, 121528, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 121536, 121541, 121546, 121551, 121556, 121561, 121566, + 121571, 121576, 121581, 121586, 121591, 121596, 121601, 121606, 121611, + 121616, 121621, 121626, 121631, 121636, 121641, 121646, 121651, 121656, + 121661, 121666, 121671, 121676, 121681, 121686, 121691, 121696, 121701, + 121706, 121711, 121716, 121721, 121726, 121731, 121736, 121741, 121746, + 121751, 121756, 121761, 121766, 121771, 121776, 121783, 121790, 121797, + 121804, 121811, 121818, 121825, 121832, 121841, 121848, 121855, 121862, + 121869, 121876, 121883, 121890, 121897, 121904, 121911, 121918, 121923, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 121932, 121937, 121941, 121945, 121949, + 121953, 121957, 121961, 121965, 121969, 0, 121973, 121978, 121983, + 121990, 121995, 122002, 122009, 0, 122014, 122021, 122026, 122031, + 122038, 122045, 122050, 122055, 122060, 122065, 122070, 122077, 122084, + 122089, 122094, 122099, 122112, 122121, 122128, 122137, 122146, 0, 0, 0, + 0, 0, 122155, 122162, 122169, 122176, 122183, 122190, 122197, 122204, + 122211, 122218, 122225, 122232, 122239, 122246, 122253, 122260, 122267, + 122274, 122281, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122288, + 122291, 122295, 122299, 122303, 122306, 122310, 122315, 122319, 122323, + 122327, 122331, 122335, 122340, 122345, 122349, 122353, 122356, 122360, + 122365, 122370, 122374, 122378, 122382, 122386, 122390, 122394, 122398, + 122402, 122406, 122410, 122413, 122417, 122421, 122425, 122429, 122433, + 122437, 122443, 122446, 122450, 122454, 122458, 122462, 122466, 122470, + 122474, 122478, 122482, 122487, 122492, 122498, 122502, 122506, 122510, + 122514, 122518, 122522, 122527, 122531, 122535, 122539, 122543, 122547, + 122553, 122557, 122561, 122565, 122569, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 122573, 122577, 122581, 122587, 122593, 122597, 122602, 122607, 122612, + 122617, 122621, 122626, 122631, 122636, 122640, 122645, 122650, 122655, + 122659, 122664, 122669, 122674, 122679, 122684, 122689, 122694, 122699, + 122703, 122708, 122713, 122718, 122723, 122728, 122733, 122738, 122743, + 122748, 122753, 122758, 122765, 122770, 122777, 122782, 122787, 122792, + 122797, 122802, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122807, + 122811, 122817, 122820, 122823, 122827, 122831, 122835, 122839, 122843, + 122847, 122851, 122857, 122863, 122869, 122875, 122881, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122887, 122892, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122898, 122902, 122906, 122910, + 122914, 122918, 122922, 122925, 122929, 122933, 122937, 122941, 122944, + 122950, 122955, 122961, 122967, 122972, 122976, 122982, 122986, 122990, + 122996, 123000, 123004, 123008, 123012, 123016, 123020, 123023, 123029, + 123035, 123041, 123047, 123054, 123061, 123068, 123078, 123085, 123092, + 123097, 123102, 123107, 123112, 123119, 123126, 123133, 123140, 123149, + 123155, 123162, 123168, 123175, 123181, 123188, 123193, 123200, 123204, + 123208, 123213, 123219, 123225, 123232, 123239, 123245, 123252, 123255, + 123261, 123265, 123268, 123272, 123275, 123278, 123282, 123287, 123291, + 123295, 123301, 123306, 123312, 123316, 123320, 123323, 123327, 123331, + 123336, 123340, 123345, 123349, 123354, 123358, 123362, 123366, 123370, + 123374, 123378, 123382, 123386, 123391, 123396, 123401, 123406, 123412, + 123418, 123424, 123430, 123436, 0, 0, 0, 0, 0, 123441, 123448, 123456, + 123463, 123470, 123478, 123485, 123492, 123501, 123508, 123515, 123522, + 123530, 0, 0, 0, 123538, 123543, 123550, 123556, 123563, 123569, 123575, + 123581, 123587, 0, 0, 0, 0, 0, 0, 0, 123593, 123598, 123605, 123611, + 123618, 123624, 123630, 123636, 123642, 123648, 0, 0, 123653, 123659, + 123665, 123668, 123677, 123684, 123692, 123699, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 123706, 123711, 123716, 123721, + 123728, 123735, 123742, 123749, 123754, 123759, 123764, 123769, 123776, + 123781, 123788, 123795, 123800, 123805, 123810, 123817, 123822, 123827, + 123834, 123841, 123846, 123851, 123856, 123863, 123870, 123877, 123882, + 123887, 123894, 123901, 123908, 123915, 123920, 123925, 123930, 123937, + 123942, 123947, 123952, 123959, 123968, 123975, 123980, 123985, 123990, + 123995, 124000, 124005, 124014, 124021, 124026, 124033, 124040, 124045, + 124050, 124055, 124062, 124067, 124074, 124081, 124086, 124091, 124096, + 124103, 124110, 124115, 124120, 124127, 124134, 124141, 124146, 124151, + 124156, 124161, 124168, 124177, 124186, 124191, 124198, 124207, 124212, + 124217, 124222, 124227, 124234, 124241, 124248, 124255, 124260, 124265, + 124270, 124277, 124284, 124291, 124296, 124301, 124308, 124313, 124320, + 124325, 124332, 124337, 124344, 124351, 124356, 124361, 124366, 124371, + 124376, 124381, 124386, 124391, 124396, 124403, 124410, 124417, 124424, + 124431, 124440, 124445, 124450, 124457, 124464, 124469, 124476, 124483, + 124490, 124497, 124504, 124511, 124516, 124521, 124526, 124531, 124536, + 124545, 124554, 124563, 124572, 124581, 124590, 124599, 124608, 124613, + 124624, 124635, 124644, 124649, 124654, 124659, 124664, 124673, 124680, + 124687, 124694, 124701, 124708, 124715, 124724, 124733, 124744, 124753, + 124764, 124773, 124780, 124789, 124800, 124809, 124818, 124827, 124836, + 124843, 124850, 124857, 124866, 124875, 124886, 124895, 124904, 124915, + 124920, 124925, 124936, 124944, 124953, 124962, 124971, 124982, 124991, + 125000, 125011, 125022, 125033, 125044, 125055, 125066, 125073, 125080, + 125087, 125094, 125105, 125114, 125121, 125128, 125135, 125146, 125157, + 125168, 125179, 125190, 125201, 125212, 125223, 125230, 125237, 125246, + 125255, 125262, 125269, 125276, 125285, 125294, 125303, 125310, 125319, + 125328, 125337, 125344, 125351, 125356, 125362, 125369, 125376, 125383, + 125390, 125397, 125404, 125413, 125422, 125431, 125440, 125447, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 125456, 125462, 125467, 125472, 125479, 125485, + 125491, 125497, 125503, 125509, 125515, 125521, 125525, 125529, 125535, + 125541, 125547, 125551, 125556, 125561, 125565, 125569, 125572, 125578, + 125584, 125590, 125596, 125602, 125608, 125614, 125620, 125626, 125636, + 125646, 125652, 125658, 125668, 125678, 125684, 0, 0, 125690, 125698, + 125703, 125708, 125714, 125720, 125726, 125732, 125738, 125744, 125751, + 125758, 125764, 125770, 125776, 125782, 125788, 125794, 125800, 125806, + 125811, 125817, 125823, 125829, 125835, 125841, 125850, 125856, 125861, + 125869, 125876, 125883, 125892, 125901, 125910, 125919, 125928, 125937, + 125946, 125955, 125965, 125975, 125983, 125991, 126000, 126009, 126015, + 126021, 126027, 126033, 126041, 126049, 126053, 126059, 126064, 126070, + 126076, 126082, 126088, 126094, 126103, 126108, 126115, 126120, 126125, + 126130, 126136, 126142, 126148, 126155, 126160, 126165, 126170, 126175, + 126180, 126186, 126192, 126198, 126204, 126210, 126216, 126222, 126228, + 126233, 126238, 126243, 126248, 126253, 126258, 126263, 126268, 126274, + 126280, 126285, 126290, 126295, 126300, 126305, 126311, 126318, 126322, + 126326, 126330, 126334, 126338, 126342, 126346, 126350, 126358, 126368, + 126372, 126376, 126382, 126388, 126394, 126400, 126406, 126412, 126418, + 126424, 126430, 126436, 126442, 126448, 126454, 126460, 126464, 126468, + 126475, 126481, 126487, 126493, 126498, 126505, 126510, 126516, 126522, + 126528, 126534, 126539, 126543, 126549, 126553, 126557, 126561, 126567, + 126573, 126577, 126583, 126589, 126595, 126601, 126607, 126615, 126623, + 126629, 126635, 126641, 126647, 126659, 126671, 126685, 126697, 126709, + 126723, 126737, 126751, 126755, 126763, 126771, 126776, 126780, 126784, + 126788, 126792, 126796, 126800, 126804, 126810, 126816, 126822, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 126828, 126835, 126842, 126849, 126856, 126863, + 126870, 126877, 126884, 126891, 126898, 126905, 126912, 126919, 126926, + 126933, 126940, 126947, 126954, 126961, 126968, 126975, 126982, 126989, + 126996, 127003, 127010, 127017, 127024, 127031, 127038, 127045, 127052, + 127059, 127066, 127073, 127080, 127087, 127094, 127101, 127108, 127115, + 127122, 127129, 127136, 127143, 127150, 127157, 127164, 127171, 127178, + 127185, 127192, 127199, 127206, 127213, 127220, 127227, 127234, 127241, + 127248, 127255, 127262, 127269, 127276, 127283, 127290, 127295, 127300, + 127305, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 93989, 93993, - 93997, 94001, 94005, 94009, 94013, 94017, 94021, 94025, 94030, 94035, - 94040, 94045, 94050, 94055, 94060, 94065, 94070, 94076, 94082, 94088, - 94095, 94102, 94109, 94116, 94123, 94130, 94137, 94144, 94151, 0, 94158, - 94162, 94166, 94170, 94174, 94178, 94181, 94185, 94188, 94192, 94195, - 94199, 94203, 94208, 94212, 94217, 94220, 94224, 94227, 94231, 94234, - 94238, 94242, 94246, 94250, 94254, 94258, 94262, 94266, 94270, 94274, - 94278, 94282, 94286, 94290, 94294, 94298, 94302, 94306, 94309, 94312, - 94316, 94320, 94324, 94327, 94330, 94333, 94337, 94341, 94345, 94349, - 94352, 94355, 94359, 94365, 94371, 94377, 94382, 94389, 94393, 94398, - 94402, 94407, 94412, 94418, 94423, 94429, 94433, 94438, 94442, 94447, - 94450, 94453, 94457, 94462, 94468, 94473, 94479, 0, 0, 0, 0, 94484, - 94487, 94490, 94493, 94496, 94499, 94502, 94505, 94508, 94511, 94515, - 94519, 94523, 94527, 94531, 94535, 94539, 94543, 94547, 94552, 94557, - 94561, 94564, 94567, 94570, 94573, 94576, 94579, 94582, 94585, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 94588, 94593, 94598, 94603, 94607, - 94612, 94616, 94621, 94625, 94630, 94634, 94639, 94643, 94648, 94652, - 94657, 94662, 94667, 94672, 94677, 94682, 94687, 94692, 94697, 94702, - 94707, 94712, 94717, 94722, 94727, 94732, 94737, 94742, 94747, 94752, - 94756, 94760, 94765, 94770, 94775, 94779, 94783, 94787, 94792, 94797, - 94802, 94807, 94811, 94815, 94821, 94826, 94832, 94837, 94843, 94848, - 94854, 94859, 94865, 94870, 94875, 94880, 94885, 94889, 94894, 94900, - 94904, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 94909, 94916, 94923, - 94930, 94937, 94944, 94951, 94958, 94965, 94972, 94979, 94986, 94993, - 95000, 95007, 95014, 95021, 95028, 95035, 95042, 95049, 95056, 95063, - 95070, 95077, 0, 0, 0, 0, 0, 0, 0, 95084, 95091, 95097, 95103, 95109, - 95115, 95121, 95127, 95133, 95139, 0, 0, 0, 0, 0, 0, 95145, 95150, 95155, - 95160, 95165, 95169, 95173, 95177, 95182, 95187, 95192, 95197, 95202, - 95207, 95212, 95217, 95222, 95227, 95232, 95237, 95242, 95247, 95252, - 95257, 95262, 95267, 95272, 95277, 95282, 95287, 95292, 95297, 95302, - 95307, 95312, 95317, 95322, 95327, 95332, 95337, 95342, 95347, 95353, - 95358, 95364, 95369, 95375, 95380, 95386, 95392, 95396, 95401, 95405, 0, - 95409, 95414, 95418, 95422, 95426, 95430, 95434, 95438, 95442, 95446, - 95450, 95455, 95459, 95464, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95469, - 95473, 95477, 95481, 95484, 95488, 95491, 95495, 95498, 95502, 95506, - 95511, 95515, 95520, 95523, 95527, 95530, 95534, 95537, 95541, 95545, - 95549, 95553, 95557, 95561, 95565, 95569, 95573, 95577, 95581, 95585, - 95589, 95593, 95597, 95601, 95605, 95609, 95612, 95615, 95619, 95623, - 95627, 95630, 95633, 95636, 95640, 95644, 95648, 95652, 95656, 95659, - 95662, 95667, 95671, 95676, 95680, 95685, 95690, 95696, 95701, 95707, - 95711, 95716, 95720, 95725, 95729, 95733, 95737, 95741, 95744, 95747, - 95751, 95755, 0, 0, 0, 0, 0, 0, 0, 95758, 95762, 95765, 95768, 95771, - 95774, 95777, 95780, 95783, 95786, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 95789, 95793, 95798, 95802, 95807, 95811, 95816, 95820, 95825, 95829, - 95834, 95838, 95843, 95848, 95853, 95858, 95863, 95868, 95873, 95878, - 95883, 95888, 95893, 95898, 95903, 95908, 95913, 95918, 95923, 95928, - 95932, 95936, 95941, 95946, 95951, 95955, 95959, 95963, 95968, 95973, - 95978, 95982, 95986, 95991, 95996, 96001, 96007, 96012, 96018, 96023, - 96029, 96034, 96040, 96045, 96051, 96056, 0, 0, 0, 0, 0, 0, 0, 0, 96061, - 96066, 96070, 96074, 96078, 96082, 96086, 96090, 96094, 96098, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127309, + 127314, 127321, 127328, 127335, 127342, 127347, 127352, 127359, 127364, + 127369, 127376, 127381, 127386, 127391, 127398, 127407, 127412, 127417, + 127422, 127427, 127432, 127437, 127444, 127449, 127454, 127459, 127464, + 127469, 127474, 127479, 127484, 127489, 127494, 127499, 127504, 127510, + 127515, 127520, 127525, 127530, 127535, 127540, 127545, 127550, 127555, + 127564, 127569, 127578, 127583, 127588, 127593, 127598, 127603, 127608, + 127613, 127622, 127627, 127632, 127637, 127642, 127647, 127654, 127659, + 127666, 127671, 127676, 127681, 127686, 127691, 127696, 127701, 127706, + 127711, 127716, 127721, 127726, 127731, 127736, 127741, 127746, 127751, + 127756, 127761, 127770, 127775, 127780, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 127785, 127793, 127801, 127809, 127817, 127825, 127833, 127841, 127849, + 127857, 127865, 127873, 127881, 127889, 127897, 127905, 127913, 127921, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 96102, 96105, 96110, 96116, 96124, 96129, 96135, 96143, 96149, - 96155, 96159, 96163, 96170, 96179, 96186, 96195, 96201, 96210, 96217, - 96224, 96231, 96241, 96247, 96251, 96258, 96267, 96277, 96284, 96291, - 96295, 96299, 96306, 96316, 96320, 96327, 96334, 96341, 96347, 96354, - 96361, 96368, 96375, 96379, 96383, 96387, 96394, 96398, 96405, 96412, - 96426, 96435, 96439, 96443, 96447, 96454, 96458, 96462, 96466, 96474, - 96482, 96501, 96511, 96531, 96535, 96539, 96543, 96547, 96551, 96555, - 96559, 96566, 96570, 96573, 96577, 96581, 96587, 96594, 96603, 96607, - 96616, 96625, 96633, 96637, 96644, 96648, 96652, 96656, 96660, 96671, - 96680, 96689, 96698, 96707, 96719, 96728, 96737, 96746, 96754, 96763, - 96775, 96784, 96793, 96802, 96814, 96823, 96832, 96844, 96853, 96862, - 96874, 96883, 96887, 96891, 96895, 96899, 96903, 96907, 96911, 96918, - 96922, 96926, 96937, 96941, 96945, 96952, 96958, 96964, 96968, 96975, - 96979, 96983, 96987, 96991, 96995, 96999, 97005, 97013, 97017, 97021, - 97024, 97030, 97040, 97044, 97056, 97063, 97070, 97077, 97084, 97090, - 97094, 97098, 97102, 97106, 97113, 97122, 97129, 97137, 97145, 97151, - 97155, 97159, 97163, 97167, 97173, 97182, 97194, 97201, 97208, 97217, - 97228, 97234, 97243, 97252, 97259, 97268, 97275, 97282, 97292, 97299, - 97306, 97313, 97320, 97324, 97330, 97334, 97345, 97353, 97362, 97374, - 97381, 97388, 97398, 97405, 97414, 97421, 97430, 97437, 97444, 97454, - 97461, 97468, 97478, 97485, 97497, 97506, 97513, 97520, 97527, 97536, - 97546, 97559, 97566, 97576, 97586, 97593, 97602, 97615, 97622, 97629, - 97636, 97646, 97656, 97663, 97673, 97680, 97687, 97697, 97703, 97710, - 97717, 97724, 97734, 97741, 97748, 97755, 97761, 97768, 97778, 97785, - 97789, 97797, 97801, 97813, 97817, 97831, 97835, 97839, 97843, 97847, - 97853, 97860, 97868, 97872, 97876, 97880, 97884, 97891, 97895, 97901, - 97907, 97915, 97919, 97926, 97934, 97938, 97942, 97948, 97952, 97961, - 97970, 97977, 97987, 97993, 97997, 98001, 98009, 98016, 98023, 98029, - 98033, 98041, 98045, 98052, 98064, 98071, 98081, 98087, 98091, 98100, - 98107, 98116, 98120, 98124, 98131, 98135, 98139, 98143, 98147, 98150, - 98156, 98162, 98166, 98170, 98177, 98184, 98191, 98198, 98205, 98212, - 98219, 98226, 98232, 98236, 98240, 98247, 98254, 98261, 98268, 98275, - 98279, 98282, 98287, 98291, 98295, 98304, 98313, 98317, 98321, 98327, - 98333, 98350, 98356, 98360, 98369, 98373, 98377, 98384, 98392, 98400, - 98406, 98410, 98414, 98418, 98422, 98425, 98431, 98438, 98448, 98455, - 98462, 98469, 98475, 98482, 98489, 98496, 98503, 98510, 98519, 98526, - 98538, 98545, 98552, 98562, 98573, 98580, 98587, 98594, 98601, 98608, - 98615, 98622, 98629, 98636, 98643, 98653, 98663, 98673, 98680, 98690, - 98697, 98704, 98711, 98718, 98724, 98731, 98738, 98745, 98752, 98759, - 98766, 98773, 98780, 98786, 98793, 98800, 98809, 98816, 98823, 98827, - 98835, 98839, 98843, 98847, 98851, 98855, 98862, 98866, 98875, 98879, - 98886, 98894, 98898, 98902, 98906, 98919, 98935, 98939, 98943, 98950, - 98956, 98963, 98967, 98971, 98975, 98979, 98983, 98990, 98994, 99012, - 99016, 99020, 99027, 99031, 99035, 99041, 99045, 99049, 99057, 99061, - 99065, 99069, 99073, 99079, 99090, 99099, 99108, 99115, 99122, 99133, - 99140, 99147, 99154, 99161, 99168, 99175, 99182, 99192, 99198, 99205, - 99215, 99224, 99231, 99240, 99250, 99257, 99264, 99271, 99278, 99290, - 99297, 99304, 99311, 99318, 99325, 99335, 99342, 99349, 99359, 99372, - 99384, 99391, 99401, 99408, 99415, 99422, 99436, 99442, 99450, 99460, - 99470, 99477, 99484, 99490, 99494, 99501, 99511, 99517, 99530, 99534, - 99538, 99545, 99549, 99556, 99566, 99570, 99574, 99578, 99582, 99586, - 99593, 99597, 99604, 99611, 99618, 99627, 99636, 99646, 99653, 99660, - 99667, 99677, 99684, 99694, 99701, 99711, 99718, 99725, 99735, 99745, - 99752, 99758, 99766, 99774, 99780, 99786, 99790, 99794, 99801, 99809, - 99815, 99819, 99823, 99827, 99834, 99846, 99849, 99856, 99862, 99866, - 99870, 99874, 99878, 99882, 99886, 99890, 99894, 99898, 99902, 99909, - 99913, 99919, 99923, 99927, 99931, 99937, 99944, 99951, 99958, 99969, - 99977, 99981, 99987, 99996, 100003, 100009, 100012, 100016, 100020, - 100026, 100035, 100043, 100047, 100053, 100057, 100061, 100065, 100071, - 100078, 100084, 100088, 100094, 100098, 100102, 100111, 100123, 100127, - 100134, 100141, 100151, 100158, 100170, 100177, 100184, 100191, 100202, - 100212, 100225, 100235, 100242, 100246, 100250, 100254, 100258, 100267, - 100276, 100285, 100302, 100311, 100317, 100324, 100332, 100345, 100349, - 100358, 100367, 100376, 100385, 100396, 100405, 100414, 100423, 100432, - 100441, 100450, 100460, 100463, 100467, 100471, 100475, 100479, 100483, - 100489, 100496, 100503, 100510, 100516, 100522, 100529, 100535, 100542, - 100550, 100554, 100561, 100568, 100575, 100583, 100586, 100590, 100594, - 100598, 100601, 100607, 100611, 100617, 100624, 100631, 100637, 100644, - 100651, 100658, 100665, 100672, 100679, 100686, 100693, 100700, 100707, - 100714, 100721, 100728, 100735, 100741, 100745, 100754, 100758, 100762, - 100766, 100770, 100776, 100783, 100790, 100797, 100804, 100811, 100817, - 100825, 100829, 100833, 100837, 100841, 100847, 100864, 100881, 100885, - 100889, 100893, 100897, 100901, 100905, 100911, 100918, 100922, 100928, - 100935, 100942, 100949, 100956, 100963, 100972, 100979, 100986, 100993, - 101000, 101004, 101008, 101014, 101026, 101030, 101034, 101043, 101047, - 101051, 101055, 101061, 101065, 101069, 101078, 101082, 101086, 101090, - 101097, 101101, 101105, 101109, 101113, 101117, 101121, 101125, 101129, - 101135, 101142, 101149, 101155, 101159, 101176, 101182, 101186, 101192, - 101198, 101204, 101210, 101216, 101222, 101226, 101230, 101234, 101240, - 101244, 101250, 101254, 101258, 101265, 101272, 101289, 101293, 101297, - 101301, 101305, 101309, 101321, 101324, 101329, 101334, 101349, 101359, - 101371, 101375, 101379, 101383, 101389, 101396, 101403, 101413, 101425, - 101431, 101437, 101446, 101450, 101454, 101461, 101471, 101478, 101484, - 101488, 101492, 101499, 101505, 101509, 101515, 101519, 101527, 101533, - 101537, 101545, 101553, 101560, 101566, 101573, 101580, 101590, 101600, - 101604, 101608, 101612, 101616, 101622, 101629, 101635, 101642, 101649, - 101656, 101665, 101672, 101679, 101685, 101692, 101699, 101706, 101713, - 101720, 101727, 101733, 101740, 101747, 101754, 101763, 101770, 101777, - 101781, 101787, 101791, 101797, 101804, 101811, 101818, 101822, 101826, - 101830, 101834, 101838, 101845, 101849, 101853, 101859, 101867, 101871, - 101875, 101879, 101883, 101890, 101894, 101898, 101906, 101910, 101914, - 101918, 101922, 101928, 101932, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 101936, 101942, 101948, 101955, 101962, 101969, 101976, 101983, - 101990, 101996, 102003, 102010, 102017, 102024, 102031, 102038, 102044, - 102050, 102056, 102062, 102068, 102074, 102080, 102086, 102092, 102099, - 102106, 102113, 102120, 102127, 102134, 102140, 102146, 102152, 102159, - 102166, 102172, 102178, 102187, 102194, 102201, 102208, 102215, 102222, - 102229, 102235, 102241, 102247, 102256, 102263, 102270, 102281, 102292, - 102298, 102304, 102310, 102319, 102326, 102333, 102343, 102353, 102364, - 102375, 102387, 102400, 102411, 102422, 102434, 102447, 102458, 102469, - 102480, 102491, 102502, 102514, 102522, 102530, 102539, 102548, 102557, - 102563, 102569, 102575, 102582, 102592, 102599, 102609, 102614, 102619, - 102625, 102631, 102639, 102647, 102656, 102667, 102678, 102686, 102694, - 102703, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102712, 102723, 102730, - 102738, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102746, 102750, 102754, - 102758, 102762, 102766, 102770, 102774, 102778, 102782, 102786, 102790, - 102794, 102798, 102802, 102806, 102810, 102814, 102818, 102822, 102826, - 102830, 102834, 102838, 102842, 102846, 102850, 102854, 102858, 102862, - 102866, 102870, 102874, 102878, 102882, 102886, 102890, 102894, 102898, - 102902, 102906, 102910, 102914, 102918, 102922, 102926, 102930, 102934, - 102938, 102942, 102946, 102950, 102954, 102958, 102962, 102966, 102970, - 102974, 102978, 102982, 102986, 102990, 102994, 102998, 103002, 103006, - 103010, 103014, 103018, 103022, 103026, 103030, 103034, 103038, 103042, - 103046, 103050, 103054, 103058, 103062, 103066, 103070, 103074, 103078, - 103082, 103086, 103090, 103094, 103098, 103102, 103106, 103110, 103114, - 103118, 103122, 103126, 103130, 103134, 103138, 103142, 103146, 103150, - 103154, 103158, 103162, 103166, 103170, 103174, 103178, 103182, 103186, - 103190, 103194, 103198, 103202, 103206, 103210, 103214, 103218, 103222, - 103226, 103230, 103234, 103238, 103242, 103246, 103250, 103254, 103258, - 103262, 103266, 103270, 103274, 103278, 103282, 103286, 103290, 103294, - 103298, 103302, 103306, 103310, 103314, 103318, 103322, 103326, 103330, - 103334, 103338, 103342, 103346, 103350, 103354, 103358, 103362, 103366, - 103370, 103374, 103378, 103382, 103386, 103390, 103394, 103398, 103402, - 103406, 103410, 103414, 103418, 103422, 103426, 103430, 103434, 103438, - 103442, 103446, 103450, 103454, 103458, 103462, 103466, 103470, 103474, - 103478, 103482, 103486, 103490, 103494, 103498, 103502, 103506, 103510, - 103514, 103518, 103522, 103526, 103530, 103534, 103538, 103542, 103546, - 103550, 103554, 103558, 103562, 103566, 103570, 103574, 103578, 103582, - 103586, 103590, 103594, 103598, 103602, 103606, 103610, 103614, 103618, - 103622, 103626, 103630, 103634, 103638, 103642, 103646, 103650, 103654, - 103658, 103662, 103666, 103670, 103674, 103678, 103682, 103686, 103690, - 103694, 103698, 103702, 103706, 103710, 103714, 103718, 103722, 103726, - 103730, 103734, 103738, 103742, 103746, 103750, 103754, 103758, 103762, - 103766, 103770, 103774, 103778, 103782, 103786, 103790, 103794, 103798, - 103802, 103806, 103810, 103814, 103818, 103822, 103826, 103830, 103834, - 103838, 103842, 103846, 103850, 103854, 103858, 103862, 103866, 103870, - 103874, 103878, 103882, 103886, 103890, 103894, 103898, 103902, 103906, - 103910, 103914, 103918, 103922, 103926, 103930, 103934, 103938, 103942, - 103946, 103950, 103954, 103958, 103962, 103966, 103970, 103974, 103978, - 103982, 103986, 103990, 103994, 103998, 104002, 104006, 104010, 104014, - 104018, 104022, 104026, 104030, 104034, 104038, 104042, 104046, 104050, - 104054, 104058, 104062, 104066, 104070, 104074, 104078, 104082, 104086, - 104090, 104094, 104098, 104102, 104106, 104110, 104114, 104118, 104122, - 104126, 104130, 104134, 104138, 104142, 104146, 104150, 104154, 104158, - 104162, 104166, 104170, 104174, 104178, 104182, 104186, 104190, 104194, - 104198, 104202, 104206, 104210, 104214, 104218, 104222, 104226, 104230, - 104234, 104238, 104242, 104246, 104250, 104254, 104258, 104262, 104266, - 104270, 104274, 104278, 104282, 104286, 104290, 104294, 104298, 104302, - 104306, 104310, 104314, 104318, 104322, 104326, 104330, 104334, 104338, - 104342, 104346, 104350, 104354, 104358, 104362, 104366, 104370, 104374, - 104378, 104382, 104386, 104390, 104394, 104398, 104402, 104406, 104410, - 104414, 104418, 104422, 104426, 104430, 104434, 104438, 104442, 104446, - 104450, 104454, 104458, 104462, 104466, 104470, 104474, 104478, 104482, - 104486, 104490, 104494, 104498, 104502, 104506, 104510, 104514, 104518, - 104522, 104526, 104530, 104534, 104538, 104542, 104546, 104550, 104554, - 104558, 104562, 104566, 104570, 104574, 104578, 104582, 104586, 104590, - 104594, 104598, 104602, 104606, 104610, 104614, 104618, 104622, 104626, - 104630, 104634, 104638, 104642, 104646, 104650, 104654, 104658, 104662, - 104666, 104670, 104674, 104678, 104682, 104686, 104690, 104694, 104698, - 104702, 104706, 104710, 104714, 104718, 104722, 104726, 104730, 104734, - 104738, 104742, 104746, 104750, 104754, 104758, 104762, 104766, 104770, - 104774, 104778, 104782, 104786, 104790, 104794, 104798, 104802, 104806, - 104810, 104814, 104818, 104822, 104826, 104830, 104834, 104838, 104842, - 104846, 104850, 104854, 104858, 104862, 104866, 104870, 104874, 104878, - 104882, 104886, 104890, 104894, 104898, 104902, 104906, 104910, 104914, - 104918, 104922, 104926, 104930, 104934, 104938, 104942, 104946, 104950, - 104954, 104958, 104962, 104966, 104970, 104974, 104978, 104982, 104986, - 104990, 104994, 104998, 105002, 105006, 105010, 105014, 105018, 105022, - 105026, 105030, 105034, 105038, 105042, 105046, 105050, 105054, 105058, - 105062, 105066, 105070, 105074, 105078, 105082, 105086, 105090, 105094, - 105098, 105102, 105106, 105110, 105114, 105118, 105122, 105126, 105130, - 105134, 105138, 105142, 105146, 105150, 105154, 105158, 105162, 105166, - 105170, 105174, 105178, 105182, 105186, 105190, 105194, 105198, 105202, - 105206, 105210, 105214, 105218, 105222, 105226, 105230, 105234, 105238, - 105242, 105246, 105250, 105254, 105258, 105262, 105266, 105270, 105274, - 105278, 105282, 105286, 105290, 105294, 105298, 105302, 105306, 105310, - 105314, 105318, 105322, 105326, 105330, 105334, 105338, 105342, 105346, - 105350, 105354, 105358, 105362, 105366, 105370, 105374, 105378, 105382, - 105386, 105390, 105394, 105398, 105402, 105406, 105410, 105414, 105418, - 105422, 105426, 105430, 105434, 105438, 105442, 105446, 105450, 105454, - 105458, 105462, 105466, 105470, 105474, 105478, 105482, 105486, 105490, - 105494, 105498, 105502, 105506, 105510, 105514, 105518, 105522, 105526, - 105530, 105534, 105538, 105542, 105546, 105550, 105554, 105558, 105562, - 105566, 105570, 105574, 105578, 105582, 105586, 105590, 105594, 105598, - 105602, 105606, 105610, 105614, 105618, 105622, 105626, 105630, 105634, - 105638, 105642, 105646, 105650, 105654, 105658, 105662, 105666, 105670, - 105674, 105678, 105682, 105686, 105690, 105694, 105698, 105702, 105706, - 105710, 105714, 105718, 105722, 105726, 105730, 105734, 105738, 105742, - 105746, 105750, 105754, 105758, 105762, 105766, 105770, 105774, 105778, - 105782, 105786, 105790, 105794, 105798, 105802, 105806, 105810, 105814, - 105818, 105822, 105826, 105830, 105834, 105838, 105842, 105846, 105850, - 105854, 105858, 105862, 105866, 105870, 105874, 105878, 105882, 105886, - 105890, 105894, 105898, 105902, 105906, 105910, 105914, 105918, 105922, - 105926, 105930, 105934, 105938, 105942, 105946, 105950, 105954, 105958, - 105962, 105966, 105970, 105974, 105978, 105982, 105986, 105990, 105994, - 105998, 106002, 106006, 106010, 106014, 106018, 106022, 106026, 106030, - 106034, 106038, 106042, 106046, 106050, 106054, 106058, 106062, 106066, - 106070, 106074, 106078, 106082, 106086, 106090, 106094, 106098, 106102, - 106106, 106110, 106114, 106118, 106122, 106126, 106130, 106134, 106138, - 106142, 106146, 106150, 106154, 106158, 106162, 106166, 106170, 106174, - 106178, 106182, 106186, 106190, 106194, 106198, 106202, 106206, 106210, - 106214, 106218, 106222, 106226, 106230, 106234, 106238, 106242, 106246, - 106250, 106254, 106258, 106262, 106266, 106270, 106274, 106278, 106282, - 106286, 106290, 106294, 106298, 106302, 106306, 106310, 106314, 106318, - 106322, 106326, 106330, 106334, 106338, 106342, 106346, 106350, 106354, - 106358, 106362, 106366, 106370, 106374, 106378, 106382, 106386, 106390, - 106394, 106398, 106402, 106406, 106410, 106414, 106418, 106422, 106426, - 106430, 106434, 106438, 106442, 106446, 106450, 106454, 106458, 106462, - 106466, 106470, 106474, 106478, 106482, 106486, 106490, 106494, 106498, - 106502, 106506, 106510, 106514, 106518, 106522, 106526, 106530, 106534, - 106538, 106542, 106546, 106550, 106554, 106558, 106562, 106566, 106570, - 106574, 106578, 106582, 106586, 106590, 106594, 106598, 106602, 106606, - 106610, 106614, 106618, 106622, 106626, 106630, 106634, 106638, 106642, - 106646, 106650, 106654, 106658, 106662, 106666, 106670, 106674, 106678, - 106682, 106686, 106690, 106694, 106698, 106702, 106706, 106710, 106714, - 106718, 106722, 106726, 106730, 106734, 106738, 106742, 106746, 106750, - 106754, 106758, 106762, 106766, 106770, 106774, 106778, 106782, 106786, - 106790, 106794, 106798, 106802, 106806, 106810, 106814, 106818, 106822, - 106826, 106830, 106834, 106838, 106842, 106846, 106850, 106854, 106858, - 106862, 106866, 106870, 106874, 106878, 106882, 106886, 106890, 106894, - 106898, 106902, 106906, 106910, 106914, 106918, 106922, 106926, 106930, - 106934, 106938, 106942, 106946, 106950, 106954, 106958, 106962, 106966, - 106970, 106974, 106978, 106982, 106986, 106990, 106994, 106998, 107002, - 107006, 107010, 107014, 107018, 107022, 107026, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 107030, 107037, 107044, 107053, 107062, 107069, 107074, 107081, - 107088, 107097, 107108, 107119, 107124, 107131, 107136, 107141, 107146, - 107151, 107156, 107161, 107166, 107171, 107176, 107181, 107186, 107193, - 107200, 107205, 107210, 107215, 107220, 107227, 107234, 107242, 107247, - 107254, 107259, 107264, 107269, 107274, 107279, 107286, 107293, 107298, - 107303, 107308, 107313, 107318, 107323, 107328, 107333, 107338, 107343, - 107348, 107353, 107358, 107363, 107368, 107373, 107378, 107383, 107388, - 107395, 107400, 107405, 107414, 107421, 107426, 107431, 107436, 107441, - 107446, 107451, 107456, 107461, 107466, 107471, 107476, 107481, 107486, - 107491, 107496, 107501, 107506, 107511, 107516, 107521, 107526, 107532, - 107540, 107546, 107554, 107562, 107570, 107576, 107582, 107588, 107594, - 107600, 107608, 107618, 107626, 107634, 107640, 107646, 107654, 107662, - 107668, 107676, 107684, 107692, 107698, 107704, 107710, 107716, 107722, - 107728, 107736, 107744, 107750, 107756, 107762, 107768, 107774, 107782, - 107788, 107794, 107800, 107806, 107812, 107818, 107826, 107832, 107838, - 107844, 107850, 107858, 107866, 107872, 107878, 107884, 107889, 107895, - 107901, 107908, 107913, 107918, 107923, 107928, 107933, 107938, 107943, - 107948, 107953, 107962, 107969, 107974, 107979, 107984, 107991, 107996, - 108001, 108006, 108013, 108018, 108023, 108028, 108033, 108038, 108043, - 108048, 108053, 108058, 108063, 108068, 108075, 108080, 108087, 108092, - 108097, 108104, 108109, 108114, 108119, 108124, 108129, 108134, 108139, - 108144, 108149, 108154, 108159, 108164, 108169, 108174, 108179, 108184, - 108189, 108194, 108199, 108206, 108211, 108216, 108221, 108226, 108231, - 108236, 108241, 108246, 108251, 108256, 108261, 108266, 108271, 108278, - 108283, 108288, 108295, 108300, 108305, 108310, 108315, 108320, 108325, - 108330, 108335, 108340, 108345, 108352, 108357, 108362, 108367, 108372, - 108377, 108384, 108391, 108396, 108401, 108406, 108411, 108416, 108421, - 108426, 108431, 108436, 108441, 108446, 108451, 108456, 108461, 108466, - 108471, 108476, 108481, 108486, 108491, 108496, 108501, 108506, 108511, - 108516, 108521, 108526, 108531, 108536, 108541, 108546, 108551, 108556, - 108561, 108566, 108571, 108578, 108583, 108588, 108593, 108598, 108603, - 108608, 108613, 108618, 108623, 108628, 108633, 108638, 108643, 108648, - 108653, 108658, 108663, 108668, 108673, 108678, 108683, 108688, 108693, - 108698, 108703, 108708, 108713, 108718, 108723, 108728, 108733, 108738, - 108743, 108748, 108753, 108758, 108763, 108768, 108773, 108778, 108783, - 108788, 108793, 108798, 108803, 108808, 108813, 108818, 108823, 108828, - 108833, 108838, 108843, 108848, 108853, 108858, 108863, 108868, 108875, - 108880, 108885, 108890, 108895, 108900, 108905, 108909, 108914, 108919, - 108924, 108929, 108934, 108939, 108944, 108949, 108954, 108959, 108964, - 108969, 108974, 108979, 108986, 108991, 108996, 109002, 109007, 109012, - 109017, 109022, 109027, 109032, 109037, 109042, 109047, 109052, 109057, - 109062, 109067, 109072, 109077, 109082, 109087, 109092, 109097, 109102, - 109107, 109112, 109117, 109122, 109127, 109132, 109137, 109142, 109147, - 109152, 109157, 109162, 109167, 109172, 109177, 109182, 109187, 109192, - 109197, 109202, 109207, 109212, 109217, 109224, 109229, 109234, 109241, - 109248, 109253, 109258, 109263, 109268, 109273, 109278, 109283, 109288, - 109293, 109298, 109303, 109308, 109313, 109318, 109323, 109328, 109333, - 109338, 109343, 109348, 109353, 109358, 109363, 109368, 109373, 109380, - 109385, 109390, 109395, 109400, 109405, 109410, 109415, 109420, 109425, - 109430, 109435, 109440, 109445, 109450, 109455, 109460, 109465, 109470, - 109477, 109482, 109487, 109492, 109497, 109502, 109507, 109512, 109518, - 109523, 109528, 109533, 109538, 109543, 109548, 109553, 109558, 109565, - 109572, 109577, 109582, 109586, 109591, 109595, 109599, 109604, 109611, - 109616, 109621, 109630, 109635, 109640, 109645, 109650, 109657, 109664, - 109669, 109674, 109679, 109684, 109691, 109696, 109701, 109706, 109711, - 109716, 109721, 109726, 109731, 109736, 109741, 109746, 109751, 109758, - 109762, 109767, 109772, 109777, 109782, 109786, 109791, 109796, 109801, - 109806, 109811, 109816, 109821, 109826, 109831, 109837, 109843, 109849, - 109855, 109861, 109867, 109873, 109879, 109885, 109891, 109897, 109903, - 109908, 109914, 109920, 109926, 109932, 109938, 109944, 109950, 109956, - 109962, 109968, 109974, 109979, 109985, 109991, 109997, 110003, 110009, - 110015, 110021, 110027, 110033, 110039, 110045, 110051, 110057, 110063, - 110069, 110075, 110081, 110087, 110093, 110099, 110104, 110110, 110116, - 110122, 110128, 110134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127929, + 127933, 127938, 127943, 127948, 127952, 127957, 127962, 127967, 127971, + 127976, 127981, 127985, 127990, 127995, 127999, 128004, 128009, 128013, + 128017, 128022, 128026, 128031, 128036, 128041, 128046, 128051, 128055, + 128060, 128065, 128070, 128074, 128079, 128084, 128089, 128093, 128098, + 128103, 128107, 128112, 128117, 128121, 128126, 128131, 128135, 128139, + 128144, 128148, 128153, 128158, 128163, 128168, 128173, 128177, 128182, + 128187, 128192, 128196, 128201, 128206, 128211, 128215, 128220, 128225, + 128229, 128234, 128239, 128243, 128248, 128253, 128257, 128261, 128266, + 128270, 128275, 128280, 128285, 128290, 128295, 128299, 128304, 128309, + 128314, 128318, 128323, 0, 128328, 128332, 128337, 128342, 128346, + 128351, 128356, 128360, 128365, 128370, 128374, 128378, 128383, 128387, + 128392, 128397, 128402, 128407, 128412, 128417, 128423, 128429, 128435, + 128440, 128446, 128452, 128458, 128463, 128469, 128475, 128480, 128486, + 128492, 128497, 128503, 128509, 128514, 128519, 128525, 128530, 128536, + 128542, 128548, 128554, 128560, 128565, 128571, 128577, 128583, 128588, + 128594, 128600, 128606, 128611, 128617, 128623, 128628, 128634, 128640, + 128645, 128651, 128657, 128662, 128667, 128673, 128678, 128684, 128690, + 128696, 128702, 128708, 0, 128712, 128717, 0, 0, 128722, 0, 0, 128727, + 128732, 0, 0, 128737, 128742, 128746, 128751, 0, 128756, 128760, 128765, + 128769, 128774, 128779, 128784, 128789, 128794, 128798, 128803, 128808, + 0, 128813, 0, 128818, 128823, 128827, 128832, 128837, 128841, 128846, 0, + 128851, 128856, 128861, 128865, 128869, 128874, 128878, 128883, 128888, + 128893, 128898, 128903, 128908, 128914, 128920, 128926, 128931, 128937, + 128943, 128949, 128954, 128960, 128966, 128971, 128977, 128983, 128988, + 128994, 129000, 129005, 129010, 129016, 129021, 129027, 129033, 129039, + 129045, 129051, 129056, 129062, 129068, 129074, 129079, 129085, 129091, + 129097, 129102, 129108, 129114, 129119, 129125, 129131, 129136, 129142, + 129148, 129153, 129158, 129164, 129169, 129175, 129181, 129187, 129193, + 129199, 129203, 0, 129208, 129213, 129217, 129222, 0, 0, 129227, 129232, + 129237, 129241, 129246, 129251, 129255, 129260, 0, 129265, 129269, + 129274, 129278, 129283, 129288, 129293, 0, 129298, 129302, 129307, + 129312, 129317, 129321, 129326, 129331, 129336, 129340, 129345, 129350, + 129354, 129359, 129364, 129368, 129373, 129378, 129382, 129386, 129391, + 129395, 129400, 129405, 129410, 129415, 129420, 129424, 0, 129429, + 129434, 129438, 129443, 0, 129448, 129452, 129457, 129462, 129466, 0, + 129471, 0, 0, 0, 129475, 129479, 129484, 129488, 129493, 129498, 129503, + 0, 129508, 129512, 129517, 129522, 129527, 129531, 129536, 129541, + 129546, 129550, 129555, 129560, 129564, 129569, 129574, 129578, 129583, + 129588, 129592, 129596, 129601, 129605, 129610, 129615, 129620, 129625, + 129630, 129635, 129641, 129647, 129653, 129658, 129664, 129670, 129676, + 129681, 129687, 129693, 129698, 129704, 129710, 129715, 129721, 129727, + 129732, 129737, 129743, 129748, 129754, 129760, 129766, 129772, 129778, + 129783, 129789, 129795, 129801, 129806, 129812, 129818, 129824, 129829, + 129835, 129841, 129846, 129852, 129858, 129863, 129869, 129875, 129880, + 129885, 129891, 129896, 129902, 129908, 129914, 129920, 129926, 129930, + 129935, 129940, 129945, 129949, 129954, 129959, 129964, 129968, 129973, + 129978, 129982, 129987, 129992, 129996, 130001, 130006, 130010, 130014, + 130019, 130023, 130028, 130033, 130038, 130043, 130048, 130052, 130057, + 130062, 130067, 130071, 130076, 130081, 130086, 130090, 130095, 130100, + 130104, 130109, 130114, 130118, 130123, 130128, 130132, 130136, 130141, + 130145, 130150, 130155, 130160, 130165, 130170, 130175, 130181, 130187, + 130193, 130198, 130204, 130210, 130216, 130221, 130227, 130233, 130238, + 130244, 130250, 130255, 130261, 130267, 130272, 130277, 130283, 130288, + 130294, 130300, 130306, 130312, 130318, 130323, 130329, 130335, 130341, + 130346, 130352, 130358, 130364, 130369, 130375, 130381, 130386, 130392, + 130398, 130403, 130409, 130415, 130420, 130425, 130431, 130436, 130442, + 130448, 130454, 130460, 130466, 130471, 130477, 130483, 130489, 130494, + 130500, 130506, 130512, 130517, 130523, 130529, 130534, 130540, 130546, + 130551, 130557, 130563, 130568, 130573, 130579, 130584, 130590, 130596, + 130602, 130608, 130614, 130619, 130625, 130631, 130637, 130642, 130648, + 130654, 130660, 130665, 130671, 130677, 130682, 130688, 130694, 130699, + 130705, 130711, 130716, 130721, 130727, 130732, 130738, 130744, 130750, + 130756, 130762, 130768, 130775, 130782, 130789, 130795, 130802, 130809, + 130816, 130822, 130829, 130836, 130842, 130849, 130856, 130862, 130869, + 130876, 130882, 130888, 130895, 130901, 130908, 130915, 130922, 130929, + 130936, 130942, 130949, 130956, 130963, 130969, 130976, 130983, 130990, + 130996, 131003, 131010, 131016, 131023, 131030, 131036, 131043, 131050, + 131056, 131062, 131069, 131075, 131082, 131089, 131096, 131103, 131110, + 131115, 131121, 131127, 131133, 131138, 131144, 131150, 131156, 131161, + 131167, 131173, 131178, 131184, 131190, 131195, 131201, 131207, 131212, + 131217, 131223, 131228, 131234, 131240, 131246, 131252, 131258, 131263, + 131269, 131275, 131281, 131286, 131292, 131298, 131304, 131309, 131315, + 131321, 131326, 131332, 131338, 131343, 131349, 131355, 131360, 131365, + 131371, 131376, 131382, 131388, 131394, 131400, 131406, 131412, 0, 0, + 131419, 131424, 131429, 131434, 131439, 131444, 131449, 131454, 131459, + 131464, 131469, 131474, 131479, 131484, 131489, 131494, 131499, 131504, + 131510, 131515, 131520, 131525, 131530, 131535, 131540, 131545, 131549, + 131554, 131559, 131564, 131569, 131574, 131579, 131584, 131589, 131594, + 131599, 131604, 131609, 131614, 131619, 131624, 131629, 131634, 131640, + 131645, 131650, 131655, 131660, 131665, 131670, 131675, 131681, 131686, + 131691, 131696, 131701, 131706, 131711, 131716, 131721, 131726, 131731, + 131736, 131741, 131746, 131751, 131756, 131761, 131766, 131771, 131776, + 131781, 131786, 131791, 131796, 131802, 131807, 131812, 131817, 131822, + 131827, 131832, 131837, 131841, 131846, 131851, 131856, 131861, 131866, + 131871, 131876, 131881, 131886, 131891, 131896, 131901, 131906, 131911, + 131916, 131921, 131926, 131932, 131937, 131942, 131947, 131952, 131957, + 131962, 131967, 131973, 131978, 131983, 131988, 131993, 131998, 132003, + 132009, 132015, 132021, 132027, 132033, 132039, 132045, 132051, 132057, + 132063, 132069, 132075, 132081, 132087, 132093, 132099, 132105, 132112, + 132118, 132124, 132130, 132136, 132142, 132148, 132154, 132159, 132165, + 132171, 132177, 132183, 132189, 132195, 132201, 132207, 132213, 132219, + 132225, 132231, 132237, 132243, 132249, 132255, 132261, 132268, 132274, + 132280, 132286, 132292, 132298, 132304, 132310, 132317, 132323, 132329, + 132335, 132341, 132347, 132353, 132359, 132365, 132371, 132377, 132383, + 132389, 132395, 132401, 132407, 132413, 132419, 132425, 132431, 132437, + 132443, 132449, 132455, 132462, 132468, 132474, 132480, 132486, 132492, + 132498, 132504, 132509, 132515, 132521, 132527, 132533, 132539, 132545, + 132551, 132557, 132563, 132569, 132575, 132581, 132587, 132593, 132599, + 132605, 132611, 132618, 132624, 132630, 132636, 132642, 132648, 132654, + 132660, 132667, 132673, 132679, 132685, 132691, 132697, 132703, 132710, + 132717, 132724, 132731, 132738, 132745, 132752, 132759, 132766, 132773, + 132780, 132787, 132794, 132801, 132808, 132815, 132822, 132830, 132837, + 132844, 132851, 132858, 132865, 132872, 132879, 132885, 132892, 132899, + 132906, 132913, 132920, 132927, 132934, 132941, 132948, 132955, 132962, + 132969, 132976, 132983, 132990, 132997, 133004, 133012, 133019, 133026, + 133033, 133040, 133047, 133054, 133061, 133069, 133076, 133083, 133090, + 133097, 133104, 133111, 133116, 0, 0, 133121, 133126, 133130, 133134, + 133138, 133142, 133146, 133150, 133154, 133158, 133162, 133167, 133171, + 133175, 133179, 133183, 133187, 133191, 133195, 133199, 133203, 133208, + 133212, 133216, 133220, 133224, 133228, 133232, 133236, 133240, 133244, + 133250, 133255, 133260, 133265, 133270, 133275, 133280, 133285, 133290, + 133295, 133301, 133306, 133311, 133316, 133321, 133326, 133331, 133336, + 133341, 133346, 133353, 133359, 133366, 133373, 133380, 133387, 133394, + 133401, 133408, 133415, 133422, 133429, 133436, 133443, 133450, 133457, + 133464, 133471, 133478, 133485, 133492, 133499, 133506, 133513, 133520, + 133527, 133534, 133541, 133548, 133555, 133562, 133569, 133576, 133583, + 133589, 133595, 133601, 133608, 133614, 133621, 133627, 133634, 133641, + 133648, 133655, 133662, 133669, 133676, 133683, 133690, 133697, 133704, + 133711, 133718, 133725, 133732, 133739, 133746, 133753, 133760, 133767, + 133775, 133782, 133789, 133796, 133803, 133810, 133817, 133824, 133831, + 133838, 133845, 133852, 133859, 133865, 133872, 133879, 133886, 133893, + 133900, 133907, 133914, 133922, 133929, 133935, 133942, 133949, 133956, + 133963, 133970, 133977, 133984, 133991, 133998, 134005, 134012, 134019, + 134026, 134033, 134040, 134047, 134054, 134061, 134068, 134075, 134081, + 134088, 134095, 134102, 134109, 134116, 134123, 134130, 134137, 134144, + 134151, 134158, 134165, 134172, 134179, 134186, 134193, 134200, 134207, + 134214, 134221, 134228, 134235, 134243, 134251, 134259, 134266, 134273, + 134280, 134287, 134294, 134301, 134308, 134315, 134322, 134329, 134335, + 134342, 134349, 134356, 134363, 134370, 134377, 134384, 134391, 134398, + 134405, 134412, 134419, 134426, 134433, 134441, 134449, 134457, 134464, + 134471, 134478, 134485, 134492, 134499, 134506, 134513, 134520, 134527, + 134534, 134541, 134548, 134555, 134562, 134569, 134576, 134583, 134590, + 134597, 134604, 134611, 134618, 134625, 134632, 134639, 134646, 134653, + 134660, 134667, 134674, 134681, 134688, 134695, 134702, 134709, 134716, + 0, 0, 134723, 134727, 134731, 134735, 134739, 134743, 134747, 134751, + 134755, 134759, 134765, 134771, 134777, 134783, 134791, 134799, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 134805, 134809, 134813, 134817, + 0, 134821, 134825, 134829, 134833, 134837, 134841, 134845, 134849, + 134853, 134857, 134861, 134865, 134869, 134873, 134877, 134881, 134885, + 134889, 134893, 134897, 134901, 134905, 134909, 134913, 134919, 134925, + 134931, 0, 134937, 134942, 0, 134947, 0, 0, 134952, 0, 134957, 134962, + 134967, 134972, 134977, 134982, 134987, 134992, 134997, 135002, 0, + 135007, 135012, 135017, 135022, 0, 135027, 0, 135032, 0, 0, 0, 0, 0, 0, + 135037, 0, 0, 0, 0, 135043, 0, 135049, 0, 135055, 0, 135061, 135067, + 135073, 0, 135079, 135085, 0, 135091, 0, 0, 135097, 0, 135103, 0, 135109, + 0, 135115, 0, 135123, 0, 135131, 135137, 0, 135143, 0, 0, 135149, 135155, + 135161, 135167, 0, 135173, 135179, 135185, 135191, 135197, 135203, + 135209, 0, 135215, 135221, 135227, 135233, 0, 135239, 135245, 135251, + 135257, 0, 135265, 0, 135273, 135279, 135285, 135291, 135297, 135303, + 135309, 135315, 135321, 135327, 0, 135333, 135339, 135345, 135351, + 135357, 135363, 135369, 135375, 135381, 135387, 135393, 135399, 135405, + 135411, 135417, 135423, 135429, 0, 0, 0, 0, 0, 135435, 135440, 135445, 0, + 135450, 135455, 135460, 135465, 135470, 0, 135475, 135480, 135485, + 135490, 135495, 135500, 135505, 135510, 135515, 135520, 135525, 135530, + 135535, 135540, 135545, 135550, 135555, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 110140, 110143, 110147, 110151, 110155, 110158, - 110162, 110167, 110171, 110175, 110179, 110183, 110187, 110192, 110197, - 110201, 110205, 110208, 110212, 110217, 110222, 110226, 110230, 110234, - 110238, 110242, 110246, 110250, 110254, 110258, 110262, 110265, 110269, - 110273, 110277, 110281, 110285, 110289, 110295, 110298, 110302, 110306, - 110310, 110314, 110318, 110322, 110326, 110330, 110334, 110339, 110344, - 110350, 110354, 110358, 110362, 110366, 110370, 110374, 110379, 110382, - 110386, 110390, 110394, 110398, 110404, 110408, 110412, 110416, 110420, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110424, 110428, 110432, 110438, 110444, - 110448, 110453, 110458, 110463, 110468, 110472, 110477, 110482, 110487, - 110491, 110496, 110501, 110506, 110510, 110515, 110520, 110525, 110530, - 110535, 110540, 110545, 110550, 110554, 110559, 110564, 110569, 110574, - 110579, 110584, 110589, 110594, 110599, 110604, 110609, 110616, 110621, - 110628, 110633, 110638, 110643, 110648, 110653, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 110658, 110662, 110668, 110671, 110674, 110678, - 110682, 110686, 110690, 110694, 110698, 110702, 110708, 110714, 110720, - 110726, 110732, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135560, 135570, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135578, 135585, 135591, 135598, + 135604, 135611, 135618, 135624, 135631, 135638, 135645, 135653, 135661, + 135669, 135677, 135685, 135693, 135700, 135707, 135714, 135722, 135730, + 135738, 135746, 135754, 135762, 135769, 135776, 135783, 135791, 135799, + 135807, 135815, 135823, 135831, 135836, 135841, 135846, 135851, 135856, + 135861, 135866, 135871, 135876, 0, 0, 0, 0, 135881, 135886, 135890, + 135894, 135898, 135902, 135906, 135910, 135914, 135918, 135922, 135926, + 135930, 135934, 135938, 135942, 135946, 135950, 135954, 135958, 135962, + 135966, 135970, 135974, 135978, 135982, 135986, 135990, 135994, 135998, + 136002, 136006, 136010, 136014, 136018, 136022, 136026, 136030, 136034, + 136038, 136042, 136046, 136050, 136054, 136058, 136062, 136066, 136070, + 136074, 136078, 136082, 136087, 136091, 136095, 136099, 136103, 136107, + 136111, 136115, 136119, 136123, 136127, 136131, 136135, 136139, 136143, + 136147, 136151, 136155, 136159, 136163, 136167, 136171, 136175, 136179, + 136183, 136187, 136191, 136195, 136199, 136203, 136207, 136211, 136215, + 136219, 136223, 136227, 136231, 136235, 136239, 136243, 136247, 136251, + 136255, 136259, 136263, 136267, 136271, 136275, 136279, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 136283, 136288, 136296, 136303, 136310, 136318, 136326, + 136334, 136342, 136350, 136358, 136366, 136374, 136382, 136390, 0, 0, + 136398, 136406, 136413, 136420, 136428, 136436, 136444, 136452, 136460, + 136468, 136476, 136484, 136492, 136500, 136508, 0, 136515, 136523, + 136530, 136537, 136545, 136553, 136561, 136569, 136577, 136585, 136593, + 136601, 136609, 136617, 136625, 0, 136631, 136639, 136646, 136653, + 136661, 136669, 136677, 136685, 136693, 136701, 136709, 136717, 136725, + 136733, 136741, 136747, 136752, 136757, 136762, 136767, 136772, 136777, + 136782, 136787, 136792, 136797, 136802, 136807, 136812, 136817, 136822, + 136827, 136832, 136837, 136842, 136847, 136852, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 136857, 136864, 136869, 136873, 136877, 136881, 136886, 136891, + 136896, 136901, 136906, 136911, 136918, 0, 0, 0, 136926, 136931, 136937, + 136943, 136949, 136954, 136960, 136966, 136972, 136977, 136983, 136989, + 136994, 137000, 137006, 137011, 137017, 137023, 137028, 137033, 137039, + 137044, 137050, 137056, 137062, 137068, 137074, 137084, 137091, 137097, + 137100, 0, 137103, 137108, 137114, 137120, 137126, 137131, 137137, + 137143, 137149, 137154, 137160, 137166, 137171, 137177, 137183, 137188, + 137194, 137200, 137205, 137210, 137216, 137221, 137227, 137233, 137239, + 137245, 137251, 137254, 137257, 137260, 137263, 137266, 137269, 137275, + 137282, 137289, 137296, 137302, 137309, 137316, 137323, 137329, 137336, + 137343, 137349, 137356, 137363, 137369, 137376, 137383, 137389, 137395, + 137402, 137408, 137415, 137422, 137429, 137436, 137443, 137448, 0, 0, 0, + 0, 137453, 137459, 137466, 137473, 137480, 137486, 137493, 137500, + 137507, 137513, 137520, 137527, 137533, 137540, 137547, 137553, 137560, + 137567, 137573, 137579, 137586, 137592, 137599, 137606, 137613, 137620, + 137627, 137636, 137640, 137643, 137647, 137651, 137655, 137658, 137661, + 137664, 137667, 137670, 137673, 137676, 137679, 137682, 137688, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 110738, 110743, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 137691, 137698, 137706, 137714, 137722, 137729, 137737, 137745, 137753, + 137760, 137768, 137776, 137783, 137791, 137799, 137806, 137814, 137822, + 137829, 137836, 137844, 137851, 137859, 137867, 137875, 137883, 137891, + 137895, 137899, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 137903, 137909, + 137915, 137921, 137925, 137931, 137937, 137943, 137949, 137955, 137961, + 137967, 137973, 137979, 137985, 137991, 137997, 138003, 138009, 138015, + 138021, 138027, 138033, 138039, 138045, 138051, 138057, 138063, 138069, + 138075, 138081, 138087, 138093, 138099, 138105, 138111, 138117, 138123, + 138129, 138135, 138141, 138147, 138153, 0, 0, 0, 0, 0, 138159, 138170, + 138181, 138192, 138203, 138214, 138225, 138236, 138247, 0, 0, 0, 0, 0, 0, + 0, 138258, 138262, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110749, 110754, 110759, - 110764, 110771, 110778, 110785, 110792, 110797, 110802, 110807, 110812, - 110819, 110824, 110831, 110838, 110843, 110848, 110853, 110860, 110865, - 110870, 110877, 110884, 110889, 110894, 110899, 110906, 110913, 110920, - 110925, 110930, 110937, 110944, 110951, 110958, 110963, 110968, 110973, - 110980, 110985, 110990, 110995, 111002, 111011, 111018, 111023, 111028, - 111033, 111038, 111043, 111048, 111057, 111064, 111069, 111076, 111083, - 111088, 111093, 111098, 111105, 111110, 111117, 111124, 111129, 111134, - 111139, 111146, 111153, 111158, 111163, 111170, 111177, 111184, 111189, - 111194, 111199, 111204, 111211, 111220, 111229, 111234, 111241, 111250, - 111255, 111260, 111265, 111270, 111277, 111284, 111291, 111298, 111303, - 111308, 111313, 111320, 111327, 111334, 111339, 111344, 111351, 111356, - 111363, 111368, 111375, 111380, 111387, 111394, 111399, 111404, 111409, - 111414, 111419, 111424, 111429, 111434, 111439, 111446, 111453, 111460, - 111467, 111474, 111483, 111488, 111493, 111500, 111507, 111512, 111519, - 111526, 111533, 111540, 111547, 111554, 111559, 111564, 111569, 111574, - 111579, 111588, 111597, 111606, 111615, 111624, 111633, 111642, 111651, - 111656, 111667, 111678, 111687, 111692, 111697, 111702, 111707, 111716, - 111723, 111730, 111737, 111744, 111751, 111758, 111767, 111776, 111787, - 111796, 111807, 111816, 111823, 111832, 111843, 111852, 111861, 111870, - 111879, 111886, 111893, 111900, 111909, 111918, 111929, 111938, 111947, - 111958, 111963, 111968, 111979, 111987, 111996, 112005, 112014, 112025, - 112034, 112043, 112054, 112065, 112076, 112087, 112098, 112109, 112116, - 112123, 112130, 112137, 112148, 112157, 112164, 112171, 112178, 112189, - 112200, 112211, 112222, 112233, 112244, 112255, 112266, 112273, 112280, - 112289, 112298, 112305, 112312, 112319, 112328, 112337, 112346, 112353, - 112362, 112371, 112380, 112387, 112394, 112399, 112405, 112412, 112419, - 112426, 112433, 112440, 112447, 112456, 112465, 112474, 112483, 112490, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 112499, 112505, 112510, 112515, 112522, - 112528, 112534, 112540, 112546, 112552, 112558, 112564, 112568, 112572, - 112578, 112584, 112590, 112594, 112599, 112604, 112608, 112612, 112615, - 112621, 112627, 112633, 112639, 112645, 112651, 112657, 112663, 112669, - 112679, 112689, 112695, 112701, 112711, 112721, 112727, 0, 0, 112733, - 112741, 112746, 112751, 112757, 112763, 112769, 112775, 112781, 112787, - 112794, 112801, 112807, 112813, 112819, 112825, 112831, 112837, 112843, - 112849, 112854, 112860, 112866, 112872, 112878, 112884, 112893, 112899, - 112904, 112912, 112919, 112926, 112935, 112944, 112953, 112962, 112971, - 112980, 112989, 112998, 113008, 113018, 113026, 113034, 113043, 113052, - 113058, 113064, 113070, 113076, 113084, 113092, 113096, 113102, 113107, - 113113, 113119, 113125, 113131, 113137, 113146, 113151, 113158, 113163, - 113168, 113173, 113179, 113185, 113191, 113198, 113203, 113208, 113213, - 113218, 113223, 113229, 113235, 113241, 113247, 113253, 113259, 113265, - 113271, 113276, 113281, 113286, 113291, 113296, 113301, 113306, 113311, - 113317, 113323, 113328, 113333, 113338, 113343, 113348, 113354, 113361, - 113365, 113369, 113373, 113377, 113381, 113385, 113389, 113393, 113401, - 113411, 113415, 113419, 113425, 113431, 113437, 113443, 113449, 113455, - 113461, 113467, 113473, 113479, 113485, 113491, 113497, 113503, 113507, - 113511, 113518, 113524, 113530, 113536, 113541, 113548, 113553, 113559, - 113565, 113571, 113577, 113582, 113586, 113592, 113596, 113600, 113604, - 113610, 113616, 113620, 113626, 113632, 113638, 113644, 113650, 113658, - 113666, 113672, 113678, 113684, 113690, 113702, 113714, 113728, 113740, - 113752, 113766, 113780, 113794, 113798, 113806, 113814, 113819, 113823, - 113827, 113831, 113835, 113839, 113843, 113847, 113853, 113859, 113865, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113871, 113877, 113883, 113889, 113895, - 113901, 113907, 113913, 113919, 113925, 113931, 113937, 113943, 113949, - 113955, 113961, 113967, 113973, 113979, 113985, 113991, 113997, 114003, - 114009, 114015, 114021, 114027, 114033, 114039, 114045, 114051, 114057, - 114063, 114069, 114075, 114081, 114087, 114093, 114099, 114105, 114111, - 114117, 114123, 114129, 114135, 114141, 114147, 114153, 114159, 114165, - 114171, 114177, 114183, 114189, 114195, 114201, 114207, 114213, 114219, - 114225, 114231, 114237, 114243, 114249, 114255, 114261, 114267, 114272, - 114277, 114282, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 114286, 114291, 114298, - 114305, 114312, 114319, 114324, 114328, 114334, 114338, 114342, 114348, - 114352, 114356, 114360, 114366, 114373, 114377, 114381, 114385, 114389, - 114393, 114397, 114403, 114407, 114411, 114415, 114419, 114423, 114427, - 114431, 114435, 114439, 114443, 114447, 114451, 114456, 114460, 114464, - 114468, 114472, 114476, 114480, 114484, 114488, 114492, 114499, 114503, - 114511, 114515, 114519, 114523, 114527, 114531, 114535, 114539, 114546, - 114550, 114554, 114558, 114562, 114566, 114572, 114576, 114582, 114586, - 114590, 114594, 114598, 114602, 114606, 114610, 114614, 114618, 114622, - 114626, 114630, 114634, 114638, 114642, 114646, 114650, 114654, 114658, - 114666, 114670, 114674, 0, 0, 0, 0, 0, 0, 0, 0, 0, 114678, 114686, - 114694, 114702, 114710, 114718, 114726, 114734, 114742, 114750, 114758, - 114766, 114774, 114782, 114790, 114798, 114806, 114814, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 114822, 114826, 114831, 114836, 114841, 114845, - 114850, 114855, 114860, 114864, 114869, 114874, 114878, 114882, 114887, - 114891, 114896, 114901, 114905, 114910, 114915, 114919, 114924, 114929, - 114934, 114939, 114944, 114948, 114953, 114958, 114963, 114967, 114972, - 114977, 114982, 114986, 114991, 114996, 115000, 115004, 115009, 115013, - 115018, 115023, 115027, 115032, 115037, 115041, 115046, 115051, 115056, - 115061, 115066, 115070, 115075, 115080, 115085, 115089, 115094, 115099, - 115104, 115108, 115113, 115118, 115122, 115126, 115131, 115135, 115140, - 115145, 115149, 115154, 115159, 115163, 115168, 115173, 115178, 115183, - 115188, 115192, 115197, 115202, 115207, 115211, 115216, 0, 115221, - 115225, 115230, 115235, 115239, 115243, 115248, 115252, 115257, 115262, - 115266, 115271, 115276, 115280, 115285, 115290, 115295, 115300, 115305, - 115310, 115316, 115322, 115328, 115333, 115339, 115345, 115351, 115356, - 115362, 115368, 115373, 115378, 115384, 115389, 115395, 115401, 115406, - 115412, 115418, 115423, 115429, 115435, 115441, 115447, 115453, 115458, - 115464, 115470, 115476, 115481, 115487, 115493, 115499, 115504, 115510, - 115516, 115521, 115526, 115532, 115537, 115543, 115549, 115554, 115560, - 115566, 115571, 115577, 115583, 115589, 115595, 115601, 0, 115605, - 115610, 0, 0, 115615, 0, 0, 115620, 115625, 0, 0, 115630, 115635, 115639, - 115644, 0, 115649, 115654, 115659, 115663, 115668, 115673, 115678, - 115683, 115688, 115692, 115697, 115702, 0, 115707, 0, 115712, 115717, - 115721, 115726, 115731, 115735, 115739, 0, 115744, 115749, 115754, - 115758, 115763, 115768, 115772, 115777, 115782, 115787, 115792, 115797, - 115802, 115808, 115814, 115820, 115825, 115831, 115837, 115843, 115848, - 115854, 115860, 115865, 115870, 115876, 115881, 115887, 115893, 115898, - 115904, 115910, 115915, 115921, 115927, 115933, 115939, 115945, 115950, - 115956, 115962, 115968, 115973, 115979, 115985, 115991, 115996, 116002, - 116008, 116013, 116018, 116024, 116029, 116035, 116041, 116046, 116052, - 116058, 116063, 116069, 116075, 116081, 116087, 116093, 116097, 0, - 116102, 116107, 116111, 116116, 0, 0, 116121, 116126, 116131, 116135, - 116139, 116144, 116148, 116153, 0, 116158, 116163, 116168, 116172, - 116177, 116182, 116187, 0, 116192, 116196, 116201, 116206, 116211, - 116215, 116220, 116225, 116230, 116234, 116239, 116244, 116248, 116252, - 116257, 116261, 116266, 116271, 116275, 116280, 116285, 116289, 116294, - 116299, 116304, 116309, 116314, 116318, 0, 116323, 116328, 116332, - 116337, 0, 116342, 116346, 116351, 116356, 116360, 0, 116364, 0, 0, 0, - 116368, 116373, 116378, 116382, 116387, 116392, 116397, 0, 116402, - 116406, 116411, 116416, 116421, 116425, 116430, 116435, 116440, 116444, - 116449, 116454, 116458, 116462, 116467, 116471, 116476, 116481, 116485, - 116490, 116495, 116499, 116504, 116509, 116514, 116519, 116524, 116529, - 116535, 116541, 116547, 116552, 116558, 116564, 116570, 116575, 116581, - 116587, 116592, 116597, 116603, 116608, 116614, 116620, 116625, 116631, - 116637, 116642, 116648, 116654, 116660, 116666, 116672, 116677, 116683, - 116689, 116695, 116700, 116706, 116712, 116718, 116723, 116729, 116735, - 116740, 116745, 116751, 116756, 116762, 116768, 116773, 116779, 116785, - 116790, 116796, 116802, 116808, 116814, 116820, 116824, 116829, 116834, - 116839, 116843, 116848, 116853, 116858, 116862, 116867, 116872, 116876, - 116880, 116885, 116889, 116894, 116899, 116903, 116908, 116913, 116917, - 116922, 116927, 116932, 116937, 116942, 116946, 116951, 116956, 116961, - 116965, 116970, 116975, 116980, 116984, 116989, 116994, 116998, 117002, - 117007, 117011, 117016, 117021, 117025, 117030, 117035, 117039, 117044, - 117049, 117054, 117059, 117064, 117069, 117075, 117081, 117087, 117092, - 117098, 117104, 117110, 117115, 117121, 117127, 117132, 117137, 117143, - 117148, 117154, 117160, 117165, 117171, 117177, 117182, 117188, 117194, - 117200, 117206, 117212, 117217, 117223, 117229, 117235, 117240, 117246, - 117252, 117258, 117263, 117269, 117275, 117280, 117285, 117291, 117296, - 117302, 117308, 117313, 117319, 117325, 117330, 117336, 117342, 117348, - 117354, 117360, 117365, 117371, 117377, 117383, 117388, 117394, 117400, - 117406, 117411, 117417, 117423, 117428, 117433, 117439, 117444, 117450, - 117456, 117461, 117467, 117473, 117478, 117484, 117490, 117496, 117502, - 117508, 117513, 117519, 117525, 117531, 117536, 117542, 117548, 117554, - 117559, 117565, 117571, 117576, 117581, 117587, 117592, 117598, 117604, - 117609, 117615, 117621, 117626, 117632, 117638, 117644, 117650, 117656, - 117662, 117669, 117676, 117683, 117689, 117696, 117703, 117710, 117716, - 117723, 117730, 117736, 117742, 117749, 117755, 117762, 117769, 117775, - 117782, 117789, 117795, 117802, 117809, 117816, 117823, 117830, 117836, - 117843, 117850, 117857, 117863, 117870, 117877, 117884, 117890, 117897, - 117904, 117910, 117916, 117923, 117929, 117936, 117943, 117949, 117956, - 117963, 117969, 117976, 117983, 117990, 117997, 118004, 118009, 118015, - 118021, 118027, 118032, 118038, 118044, 118050, 118055, 118061, 118067, - 118072, 118077, 118083, 118088, 118094, 118100, 118105, 118111, 118117, - 118122, 118128, 118134, 118140, 118146, 118152, 118157, 118163, 118169, - 118175, 118180, 118186, 118192, 118198, 118203, 118209, 118215, 118220, - 118225, 118231, 118236, 118242, 118248, 118253, 118259, 118265, 118270, - 118276, 118282, 118288, 118294, 118300, 118306, 0, 0, 118313, 118318, - 118323, 118328, 118333, 118338, 118343, 118348, 118353, 118358, 118363, - 118368, 118373, 118378, 118383, 118388, 118393, 118398, 118404, 118409, - 118414, 118419, 118424, 118429, 118434, 118439, 118443, 118448, 118453, - 118458, 118463, 118468, 118473, 118478, 118483, 118488, 118493, 118498, - 118503, 118508, 118513, 118518, 118523, 118528, 118534, 118539, 118544, - 118549, 118554, 118559, 118564, 118569, 118575, 118580, 118585, 118590, - 118595, 118600, 118605, 118610, 118615, 118620, 118625, 118630, 118635, - 118640, 118645, 118650, 118655, 118660, 118665, 118670, 118675, 118680, - 118685, 118690, 118696, 118701, 118706, 118711, 118716, 118721, 118726, - 118731, 118735, 118740, 118745, 118750, 118755, 118760, 118765, 118770, - 118775, 118780, 118785, 118790, 118795, 118800, 118805, 118810, 118815, - 118820, 118826, 118831, 118836, 118841, 118846, 118851, 118856, 118861, - 118867, 118872, 118877, 118882, 118887, 118892, 118897, 118903, 118909, - 118915, 118921, 118927, 118933, 118939, 118945, 118951, 118957, 118963, - 118969, 118975, 118981, 118987, 118993, 118999, 119006, 119012, 119018, - 119024, 119030, 119036, 119042, 119048, 119053, 119059, 119065, 119071, - 119077, 119083, 119089, 119095, 119101, 119107, 119113, 119119, 119125, - 119131, 119137, 119143, 119149, 119155, 119162, 119168, 119174, 119180, - 119186, 119192, 119198, 119204, 119211, 119217, 119223, 119229, 119235, - 119241, 119247, 119253, 119259, 119265, 119271, 119277, 119283, 119289, - 119295, 119301, 119307, 119313, 119319, 119325, 119331, 119337, 119343, - 119349, 119356, 119362, 119368, 119374, 119380, 119386, 119392, 119398, - 119403, 119409, 119415, 119421, 119427, 119433, 119439, 119445, 119451, - 119457, 119463, 119469, 119475, 119481, 119487, 119493, 119499, 119505, - 119512, 119518, 119524, 119530, 119536, 119542, 119548, 119554, 119561, - 119567, 119573, 119579, 119585, 119591, 119597, 119604, 119611, 119618, - 119625, 119632, 119639, 119646, 119653, 119660, 119667, 119674, 119681, - 119688, 119695, 119702, 119709, 119716, 119724, 119731, 119738, 119745, - 119752, 119759, 119766, 119773, 119779, 119786, 119793, 119800, 119807, - 119814, 119821, 119828, 119835, 119842, 119849, 119856, 119863, 119870, - 119877, 119884, 119891, 119898, 119906, 119913, 119920, 119927, 119934, - 119941, 119948, 119955, 119963, 119970, 119977, 119984, 119991, 119998, - 120005, 120010, 0, 0, 120015, 120020, 120024, 120028, 120032, 120036, - 120040, 120044, 120048, 120052, 120056, 120061, 120065, 120069, 120073, - 120077, 120081, 120085, 120089, 120093, 120097, 120102, 120106, 120110, - 120114, 120118, 120122, 120126, 120130, 120134, 120138, 120144, 120149, - 120154, 120159, 120164, 120169, 120174, 120179, 120184, 120189, 120195, - 120200, 120205, 120210, 120215, 120220, 120225, 120230, 120235, 120240, - 120244, 120248, 120252, 0, 120256, 120260, 120264, 120268, 120272, - 120276, 120280, 120284, 120288, 120292, 120296, 120300, 120304, 120308, - 120312, 120316, 120320, 120324, 120328, 120332, 120336, 120340, 120344, - 120348, 120354, 120360, 120366, 0, 120372, 120377, 0, 120382, 0, 0, - 120387, 0, 120392, 120397, 120402, 120407, 120412, 120417, 120422, - 120427, 120432, 120437, 0, 120442, 120447, 120452, 120457, 0, 120462, 0, - 120467, 0, 0, 0, 0, 0, 0, 120472, 0, 0, 0, 0, 120478, 0, 120484, 0, - 120490, 0, 120496, 120502, 120508, 0, 120514, 120520, 0, 120526, 0, 0, - 120532, 0, 120538, 0, 120544, 0, 120550, 0, 120558, 0, 120566, 120572, 0, - 120578, 0, 0, 120584, 120590, 120596, 120602, 0, 120608, 120614, 120620, - 120626, 120632, 120638, 120644, 0, 120650, 120656, 120662, 120668, 0, - 120674, 120680, 120686, 120692, 0, 120700, 0, 120708, 120714, 120720, - 120726, 120732, 120738, 120744, 120750, 120756, 120762, 0, 120768, - 120774, 120780, 120786, 120792, 120798, 120804, 120810, 120816, 120822, - 120828, 120834, 120840, 120846, 120852, 120858, 120864, 0, 0, 0, 0, 0, - 120870, 120875, 120880, 0, 120885, 120890, 120895, 120900, 120905, 0, - 120910, 120915, 120920, 120925, 120930, 120935, 120940, 120945, 120950, - 120955, 120960, 120965, 120970, 120975, 120980, 120985, 120990, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138266, 138268, 138270, 138274, + 138279, 138284, 138286, 138292, 138297, 138299, 138305, 138309, 138311, + 138315, 138321, 138327, 138333, 138338, 138342, 138349, 138356, 138363, + 138368, 138375, 138382, 138389, 138393, 138399, 138408, 138417, 138424, + 138429, 138433, 138437, 138439, 138442, 138445, 138452, 138459, 138469, + 138474, 138479, 138484, 138489, 138491, 0, 0, 0, 138497, 138499, 138501, + 138505, 138509, 138513, 138515, 138519, 138521, 138525, 138527, 138529, + 138531, 138533, 138538, 138543, 138545, 138551, 138555, 138559, 138567, + 138569, 138571, 138573, 138575, 138577, 138579, 138581, 138583, 138585, + 138587, 138591, 138595, 138597, 138599, 138601, 138603, 138605, 138610, + 138616, 138620, 138624, 138628, 138632, 138637, 138641, 138643, 138645, + 138649, 138655, 138657, 138659, 138661, 138665, 138674, 138680, 138684, + 138688, 138690, 138692, 138695, 138697, 138699, 138701, 138705, 138707, + 138711, 138716, 138718, 138723, 138729, 138736, 138740, 138744, 138748, + 138752, 138758, 138762, 0, 0, 138770, 138772, 138776, 138780, 138782, + 138786, 138790, 138792, 138796, 138798, 138802, 138806, 138810, 138814, + 138818, 138822, 138826, 138830, 138836, 138840, 138844, 138855, 138860, + 138864, 138868, 138874, 138878, 138882, 138886, 138893, 138900, 138904, + 138908, 138912, 138916, 138920, 138927, 138929, 138933, 138935, 138937, + 138941, 138945, 138949, 138951, 138955, 138959, 138963, 138967, 138971, + 138973, 138977, 138979, 138985, 138988, 138993, 138995, 138997, 139000, + 139002, 139004, 139007, 139014, 139021, 139028, 139033, 139037, 139039, + 139041, 139043, 139047, 139049, 139053, 139057, 139061, 139063, 139067, + 139069, 139073, 0, 0, 0, 0, 0, 139077, 139083, 139085, 139090, 139094, + 139098, 139100, 139106, 139110, 139112, 139116, 139120, 139122, 139126, + 139131, 139135, 139141, 139147, 139149, 139151, 139157, 139159, 139163, + 139167, 139169, 139173, 139175, 139179, 139183, 139187, 139190, 139193, + 139198, 139203, 139205, 139208, 0, 0, 0, 0, 0, 0, 0, 0, 139210, 139212, + 139214, 139216, 139220, 139222, 139224, 139226, 139228, 139230, 139232, + 139234, 139236, 139238, 139240, 139242, 139244, 139246, 139248, 139250, + 139252, 139254, 139256, 139258, 139260, 139262, 139264, 139268, 139270, + 139272, 139274, 139278, 139280, 139284, 139286, 139288, 139292, 139296, + 139302, 139304, 139306, 139308, 139310, 139314, 139318, 139320, 139324, + 139328, 139332, 139336, 139340, 139344, 139348, 139352, 139356, 139360, + 139364, 139368, 139372, 139376, 139380, 139384, 139388, 139392, 139394, + 139396, 139398, 139400, 139402, 139404, 139406, 139414, 139422, 139430, + 139438, 139443, 139448, 139453, 139457, 139461, 139466, 139471, 139473, + 139477, 139479, 139481, 139483, 139485, 139487, 139489, 139491, 139495, + 139497, 139499, 139501, 139505, 139509, 139513, 139517, 139521, 139523, + 139529, 139535, 139537, 139539, 139541, 139543, 139545, 139554, 139561, + 139568, 139572, 139579, 139584, 139591, 139600, 139605, 139609, 139613, + 139615, 139619, 139621, 139625, 139629, 139631, 139635, 139639, 139643, + 139645, 139647, 139653, 139655, 139657, 139659, 139663, 139667, 139669, + 139673, 139675, 139677, 139680, 139684, 139686, 139690, 139692, 139694, + 139699, 139701, 139705, 139709, 139712, 139716, 139720, 139724, 139728, + 139732, 139736, 139740, 139745, 139749, 139753, 139762, 139767, 139770, + 139772, 139775, 139778, 139783, 139785, 139788, 139793, 139797, 139800, + 139804, 139808, 139811, 139816, 139820, 139824, 139828, 139832, 139838, + 139844, 139850, 139856, 139861, 139871, 139873, 139877, 139879, 139881, + 139885, 139889, 139891, 139895, 139901, 139906, 139912, 139914, 139918, + 139921, 139927, 139933, 139937, 139939, 139941, 139945, 139947, 139951, + 139955, 139959, 139961, 139963, 139970, 139974, 139978, 139982, 139986, + 139990, 139992, 139996, 139998, 140000, 140004, 140006, 140010, 140014, + 140020, 140024, 140028, 140032, 140034, 140037, 140041, 140047, 140056, + 140065, 140074, 140083, 140085, 140089, 140091, 140095, 140106, 140110, + 140116, 140122, 140127, 140129, 140134, 140138, 140140, 140142, 140144, + 140148, 0, 140152, 140157, 140168, 140184, 140195, 140206, 140210, + 140214, 140220, 140222, 140230, 140238, 140240, 140244, 140250, 140256, + 140263, 140270, 140272, 140274, 140278, 140280, 140286, 140288, 140291, + 140295, 140301, 140307, 140318, 140324, 140330, 140338, 140342, 140350, + 140358, 140364, 140370, 140377, 140379, 140383, 140385, 140387, 140392, + 140394, 140396, 140398, 140400, 140404, 140415, 140421, 140425, 140429, + 140433, 140439, 140445, 140451, 140457, 140462, 140467, 140473, 140479, + 140486, 140493, 140501, 140509, 140514, 140522, 140526, 140535, 140544, + 140550, 140554, 140558, 140562, 140565, 0, 0, 0, 0, 0, 140570, 140577, + 140584, 140591, 140599, 140607, 140615, 140623, 140631, 140639, 140647, + 140655, 140663, 140669, 140675, 140681, 140687, 140693, 140699, 140705, + 140711, 140717, 140723, 140729, 140735, 140738, 140747, 140756, 140758, + 140765, 140769, 140771, 140773, 140777, 140783, 140787, 140789, 140799, + 140805, 140809, 140811, 140815, 0, 140817, 140824, 140831, 140838, + 140843, 140848, 140857, 140863, 140868, 140872, 140877, 140881, 140888, + 140892, 140895, 140900, 140907, 140914, 140919, 140924, 140929, 140935, + 140944, 140955, 140961, 140967, 140973, 140984, 141000, 141009, 141017, + 141025, 141033, 141041, 141049, 141057, 141065, 141073, 141081, 141089, + 141097, 0, 141105, 141109, 141114, 141119, 141121, 141125, 141134, + 141143, 141151, 141155, 141159, 141164, 141169, 141174, 141176, 141181, + 141185, 141187, 141191, 141195, 141201, 141206, 141214, 141219, 141224, + 141229, 141236, 141239, 141241, 141245, 141250, 141255, 141259, 141263, + 141269, 141275, 141277, 141281, 141285, 141289, 141293, 141297, 141299, + 141301, 141303, 141305, 141311, 141317, 141321, 141323, 141325, 141327, + 141336, 141340, 141347, 141354, 141356, 141359, 141363, 141369, 141373, + 141377, 141379, 141387, 141391, 141395, 141400, 141405, 141410, 141415, + 141420, 141425, 141430, 141435, 141440, 141445, 141449, 141455, 141459, + 141465, 141470, 141477, 141483, 141491, 141495, 141502, 141506, 141510, + 141514, 141519, 141524, 141526, 141530, 141539, 141547, 141556, 141570, + 141584, 141598, 141605, 141612, 141616, 141625, 141633, 141637, 141646, + 141653, 141657, 141661, 141665, 141669, 141676, 141680, 141684, 141688, + 141692, 141699, 141708, 141717, 141724, 141736, 141748, 141752, 141756, + 141760, 141764, 141768, 141772, 141780, 141788, 141797, 141801, 141805, + 141809, 141813, 141817, 141821, 141827, 141834, 141838, 141850, 141858, + 141862, 141866, 141870, 141874, 141880, 141887, 141898, 141908, 141919, + 141930, 141939, 141950, 141956, 141962, 141968, 141974, 0, 0, 141980, + 141989, 141996, 142002, 142006, 142010, 142014, 142023, 142035, 142039, + 142046, 142053, 142060, 142067, 142074, 142081, 142089, 142097, 142105, + 142113, 142122, 142131, 142140, 142149, 142159, 142169, 142179, 142189, + 142196, 142203, 142210, 142217, 142225, 142233, 142241, 142249, 142256, + 142268, 142275, 142287, 142290, 142293, 142296, 142299, 142305, 142312, + 142319, 142327, 142332, 142338, 142349, 142359, 142370, 142375, 142380, + 142386, 142391, 142398, 142402, 142408, 142410, 142412, 142416, 142420, + 142424, 142433, 142435, 142437, 142440, 142442, 142444, 142448, 142450, + 142454, 142456, 142460, 142462, 142464, 142468, 142472, 142478, 142480, + 142484, 142486, 142490, 142494, 142498, 142502, 142504, 142506, 142510, + 142514, 142518, 142522, 142524, 142526, 142528, 142533, 142538, 142541, + 142549, 142557, 142559, 142564, 142567, 142572, 142583, 142590, 142595, + 142600, 142602, 142606, 142608, 142612, 142614, 142618, 142622, 142625, + 142628, 142630, 142633, 142635, 142639, 142641, 142643, 142645, 142649, + 142651, 142655, 142658, 142665, 142668, 142673, 142676, 142679, 142684, + 142688, 142692, 142696, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 142698, 142703, 142705, 142709, 142711, 142715, 142719, 142725, 142729, + 142734, 142737, 142741, 142745, 0, 0, 0, 142749, 142751, 142757, 142761, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 142765, 142770, 142775, 142780, + 142785, 142790, 142795, 142802, 142809, 142816, 142823, 142828, 142833, + 142838, 142843, 142850, 142856, 142863, 142870, 142877, 142882, 142887, + 142892, 142897, 142902, 142909, 142916, 142921, 142926, 142933, 142940, + 142948, 142956, 142963, 142970, 142978, 142986, 142994, 143001, 143011, + 143022, 143027, 143034, 143041, 143048, 143056, 143064, 143075, 143083, + 143091, 143099, 143104, 143109, 143114, 143119, 143124, 143129, 143134, + 143139, 143144, 143149, 143154, 143159, 143166, 143171, 143176, 143183, + 143188, 143193, 143198, 143203, 143208, 143213, 143218, 143223, 143228, + 143233, 143238, 143243, 143250, 143258, 143263, 143268, 143275, 143280, + 143285, 143290, 143297, 143302, 143309, 143314, 143321, 143326, 143335, + 143344, 143349, 143354, 143359, 143364, 143369, 143374, 143379, 143384, + 143389, 143394, 143399, 143404, 143409, 143417, 143425, 143430, 143435, + 143440, 143445, 143450, 143456, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 143462, 143470, 143478, 143486, 143494, 143500, 143506, 143510, 143514, + 143520, 143526, 143535, 143539, 143544, 143550, 143554, 143559, 143563, + 143567, 143573, 143579, 143589, 143598, 143601, 143606, 143612, 143618, + 143629, 143639, 143643, 143648, 143654, 143660, 143669, 143674, 143678, + 143683, 143687, 143693, 143699, 143705, 143709, 143712, 143716, 143719, + 143722, 143727, 143732, 143739, 143747, 143754, 143761, 143770, 143779, + 143786, 143794, 143801, 143808, 143817, 143826, 143833, 143841, 143848, + 143855, 143864, 143871, 143879, 143885, 143894, 143902, 143911, 143918, + 143928, 143939, 143947, 143955, 143964, 143972, 143980, 143989, 143997, + 144007, 144016, 144024, 144032, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 144041, 144049, 144057, 144065, 144073, 144082, 144091, + 144100, 144109, 144118, 144127, 144136, 0, 0, 0, 0, 144145, 144153, + 144161, 144169, 144177, 144184, 144191, 144198, 144205, 144213, 144221, + 144229, 144237, 144247, 144257, 144267, 144277, 144286, 144295, 144304, + 144313, 144322, 144331, 144340, 144349, 144357, 144365, 144373, 144381, + 144389, 144397, 144405, 144413, 144423, 144433, 144443, 144453, 144457, + 144461, 144465, 144469, 144472, 144475, 144478, 144481, 144485, 144489, + 144493, 144497, 144502, 144507, 144512, 144517, 144520, 144523, 144526, + 0, 0, 0, 0, 0, 0, 0, 0, 144529, 144532, 144535, 144538, 144541, 144546, + 144551, 144556, 144561, 144565, 0, 0, 0, 0, 0, 0, 144569, 144575, 144581, + 144587, 144593, 144601, 144609, 144617, 144625, 144630, 144635, 144640, + 144645, 144652, 144659, 144666, 144673, 144680, 144687, 144694, 144701, + 144710, 144719, 144728, 144737, 144743, 144749, 144755, 144761, 144769, + 144777, 144785, 144793, 144801, 144809, 144817, 144825, 144835, 144845, + 144855, 0, 0, 0, 0, 0, 0, 0, 0, 144865, 144870, 144875, 144880, 144885, + 144894, 144903, 144912, 144921, 144928, 144935, 144942, 144949, 144956, + 144965, 144974, 144983, 144988, 144995, 145002, 145009, 145014, 145019, + 145024, 145029, 145036, 145043, 145050, 145057, 145064, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 120995, 121005, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 121013, - 121020, 121027, 121034, 121041, 121048, 121055, 121061, 121068, 121075, - 121082, 121090, 121098, 121106, 121114, 121122, 121130, 121137, 121144, - 121151, 121159, 121167, 121175, 121183, 121191, 121199, 121206, 121213, - 121220, 121228, 121236, 121244, 121252, 121260, 121268, 121273, 121278, - 121283, 121288, 121293, 121298, 121303, 121308, 121313, 0, 0, 0, 0, - 121318, 121323, 121327, 121331, 121335, 121339, 121343, 121347, 121351, - 121355, 121359, 121363, 121367, 121371, 121375, 121379, 121383, 121387, - 121391, 121395, 121399, 121403, 121407, 121411, 121415, 121419, 121423, - 121427, 121431, 121435, 121439, 121443, 121447, 121451, 121455, 121459, - 121463, 121467, 121471, 121475, 121479, 121483, 121487, 121491, 121495, - 121499, 121503, 121507, 121511, 121515, 121519, 121524, 121528, 121532, - 121536, 121540, 121544, 121548, 121552, 121556, 121560, 121564, 121568, - 121572, 121576, 121580, 121584, 121588, 121592, 121596, 121600, 121604, - 121608, 121612, 121616, 121620, 121624, 121628, 121632, 121636, 121640, - 121644, 121648, 121652, 121656, 121660, 121664, 121668, 121672, 121676, - 121680, 121684, 121688, 121692, 121696, 121700, 121704, 121708, 121712, - 121716, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 121720, 121726, 121735, - 121743, 121751, 121760, 121769, 121778, 121787, 121796, 121805, 121814, - 121823, 121832, 121841, 0, 0, 121850, 121859, 121867, 121875, 121884, - 121893, 121902, 121911, 121920, 121929, 121938, 121947, 121956, 121965, - 0, 0, 121974, 121983, 121991, 121999, 122008, 122017, 122026, 122035, - 122044, 122053, 122062, 122071, 122080, 122089, 122098, 0, 122105, - 122114, 122122, 122130, 122139, 122148, 122157, 122166, 122175, 122184, - 122193, 122202, 122211, 122220, 122229, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122236, - 122243, 122248, 122252, 122256, 122260, 122265, 122270, 122275, 122280, - 122285, 0, 0, 0, 0, 0, 122290, 122295, 122301, 122307, 122313, 122318, - 122324, 122330, 122336, 122341, 122347, 122353, 122358, 122363, 122369, - 122374, 122380, 122386, 122391, 122397, 122403, 122408, 122414, 122420, - 122426, 122432, 122438, 122449, 122456, 122462, 122465, 0, 122468, - 122473, 122479, 122485, 122491, 122496, 122502, 122508, 122514, 122519, - 122525, 122531, 122536, 122541, 122547, 122552, 122558, 122564, 122569, - 122575, 122581, 122586, 122592, 122598, 122604, 122610, 122616, 122619, - 122622, 122625, 122628, 122631, 122634, 122640, 122647, 122654, 122661, - 122667, 122674, 122681, 122688, 122694, 122701, 122708, 122714, 122720, - 122727, 122733, 122740, 122747, 122753, 122760, 122767, 122773, 122780, - 122787, 122794, 122801, 122808, 122813, 0, 0, 0, 0, 122818, 122824, - 122831, 122838, 122845, 122851, 122858, 122865, 122872, 122878, 122885, - 122892, 122898, 122904, 122911, 122917, 122924, 122931, 122937, 122944, - 122951, 122957, 122964, 122971, 122978, 122985, 122992, 123001, 123005, - 123008, 123011, 123015, 123019, 123022, 123025, 123028, 123031, 123034, - 123037, 123040, 123043, 123046, 123052, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 123055, 123062, 123070, - 123078, 123086, 123093, 123101, 123109, 123117, 123124, 123132, 123140, - 123147, 123154, 123162, 123169, 123177, 123185, 123192, 123200, 123208, - 123215, 123223, 123231, 123239, 123247, 123255, 123259, 123263, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 123266, 123272, 123278, 123284, 123288, - 123294, 123300, 123306, 123312, 123318, 123324, 123330, 123336, 123342, - 123348, 123354, 123360, 123366, 123372, 123378, 123384, 123390, 123396, - 123402, 123408, 123414, 123420, 123426, 123432, 123438, 123444, 123450, - 123456, 123462, 123468, 123474, 123480, 123486, 123492, 123498, 123504, - 123510, 123516, 0, 0, 0, 0, 0, 123522, 123533, 123544, 123555, 123566, - 123577, 123588, 123599, 123610, 0, 0, 0, 0, 0, 0, 0, 123621, 123625, 0, + 0, 0, 0, 0, 145073, 145077, 145081, 145085, 145089, 145093, 145097, + 145101, 145105, 145109, 145113, 145117, 145121, 145125, 145129, 145133, + 145137, 145141, 145145, 145149, 145153, 145157, 145161, 145165, 145169, + 145173, 145177, 145181, 145185, 145189, 145193, 145197, 145201, 145205, + 145209, 145213, 145217, 145221, 145225, 145229, 145233, 145237, 145241, + 145245, 145249, 145253, 145257, 145261, 145265, 145269, 145273, 145277, + 145281, 145285, 145289, 145293, 145297, 145301, 145305, 145309, 145313, + 145317, 145321, 145325, 145329, 145333, 145337, 145341, 145345, 145349, + 145353, 145357, 145361, 145365, 145369, 145373, 145377, 145381, 145385, + 145389, 145393, 145397, 145401, 145405, 145409, 145413, 145417, 145421, + 145425, 145429, 145433, 145437, 145441, 145445, 145449, 145453, 145457, + 145461, 145465, 145469, 145473, 145477, 145481, 145485, 145489, 145493, + 145497, 145501, 145505, 145509, 145513, 145517, 145521, 145525, 145529, + 145533, 145537, 145541, 145545, 145549, 145553, 145557, 145561, 145565, + 145569, 145573, 145577, 145581, 145585, 145589, 145593, 145597, 145601, + 145605, 145609, 145613, 145617, 145621, 145625, 145629, 145633, 145637, + 145641, 145645, 145649, 145653, 145657, 145661, 145665, 145669, 145673, + 145677, 145681, 145685, 145689, 145693, 145697, 145701, 145705, 145709, + 145713, 145717, 145721, 145725, 145729, 145733, 145737, 145741, 145745, + 145749, 145753, 145757, 145761, 145765, 145769, 145773, 145777, 145781, + 145785, 145789, 145793, 145797, 145801, 145805, 145809, 145813, 145817, + 145821, 145825, 145829, 145833, 145837, 145841, 145845, 145849, 145853, + 145857, 145861, 145865, 145869, 145873, 145877, 145881, 145885, 145889, + 145893, 145897, 145901, 145905, 145909, 145913, 145917, 145921, 145925, + 145929, 145933, 145937, 145941, 145945, 145949, 145953, 145957, 145961, + 145965, 145969, 145973, 145977, 145981, 145985, 145989, 145993, 145997, + 146001, 146005, 146009, 146013, 146017, 146021, 146025, 146029, 146033, + 146037, 146041, 146045, 146049, 146053, 146057, 146061, 146065, 146069, + 146073, 146077, 146081, 146085, 146089, 146093, 146097, 146101, 146105, + 146109, 146113, 146117, 146121, 146125, 146129, 146133, 146137, 146141, + 146145, 146149, 146153, 146157, 146161, 146165, 146169, 146173, 146177, + 146181, 146185, 146189, 146193, 146197, 146201, 146205, 146209, 146213, + 146217, 146221, 146225, 146229, 146233, 146237, 146241, 146245, 146249, + 146253, 146257, 146261, 146265, 146269, 146273, 146277, 146281, 146285, + 146289, 146293, 146297, 146301, 146305, 146309, 146313, 146317, 146321, + 146325, 146329, 146333, 146337, 146341, 146345, 146349, 146353, 146357, + 146361, 146365, 146369, 146373, 146377, 146381, 146385, 146389, 146393, + 146397, 146401, 146405, 146409, 146413, 146417, 146421, 146425, 146429, + 146433, 146437, 146441, 146445, 146449, 146453, 146457, 146461, 146465, + 146469, 146473, 146477, 146481, 146485, 146489, 146493, 146497, 146501, + 146505, 146509, 146513, 146517, 146521, 146525, 146529, 146533, 146537, + 146541, 146545, 146549, 146553, 146557, 146561, 146565, 146569, 146573, + 146577, 146581, 146585, 146589, 146593, 146597, 146601, 146605, 146609, + 146613, 146617, 146621, 146625, 146629, 146633, 146637, 146641, 146645, + 146649, 146653, 146657, 146661, 146665, 146669, 146673, 146677, 146681, + 146685, 146689, 146693, 146697, 146701, 146705, 146709, 146713, 146717, + 146721, 146725, 146729, 146733, 146737, 146741, 146745, 146749, 146753, + 146757, 146761, 146765, 146769, 146773, 146777, 146781, 146785, 146789, + 146793, 146797, 146801, 146805, 146809, 146813, 146817, 146821, 146825, + 146829, 146833, 146837, 146841, 146845, 146849, 146853, 146857, 146861, + 146865, 146869, 146873, 146877, 146881, 146885, 146889, 146893, 146897, + 146901, 146905, 146909, 146913, 146917, 146921, 146925, 146929, 146933, + 146937, 146941, 146945, 146949, 146953, 146957, 146961, 146965, 146969, + 146973, 146977, 146981, 146985, 146989, 146993, 146997, 147001, 147005, + 147009, 147013, 147017, 147021, 147025, 147029, 147033, 147037, 147041, + 147045, 147049, 147053, 147057, 147061, 147065, 147069, 147073, 147077, + 147081, 147085, 147089, 147093, 147097, 147101, 147105, 147109, 147113, + 147117, 147121, 147125, 147129, 147133, 147137, 147141, 147145, 147149, + 147153, 147157, 147161, 147165, 147169, 147173, 147177, 147181, 147185, + 147189, 147193, 147197, 147201, 147205, 147209, 147213, 147217, 147221, + 147225, 147229, 147233, 147237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 123629, - 123631, 123633, 123637, 123642, 123647, 123649, 123655, 123660, 123662, - 123668, 123672, 123674, 123678, 123684, 123690, 123696, 123701, 123705, - 123712, 123719, 123726, 123731, 123738, 123745, 123752, 123756, 123762, - 123771, 123780, 123787, 123792, 123796, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 123800, 123802, 123804, 123808, 123812, 123816, 0, 123818, - 123820, 123824, 123826, 123828, 123830, 123832, 123837, 123842, 123844, - 123850, 123854, 123858, 123866, 123868, 123870, 123872, 123874, 123876, - 123878, 123880, 123882, 123884, 123886, 123890, 123894, 123896, 123898, - 123900, 123902, 123904, 123909, 123915, 123919, 123923, 123927, 123931, - 123936, 123940, 123942, 123944, 123948, 123954, 123956, 123958, 123960, - 123964, 123973, 123979, 123983, 123987, 123989, 123991, 123994, 123996, - 123998, 124000, 124004, 124006, 124010, 124015, 124017, 124022, 124028, - 124035, 124039, 124043, 124047, 124051, 124057, 0, 0, 0, 124061, 124063, - 124067, 124071, 124073, 124077, 124081, 124083, 124087, 124089, 124093, - 124097, 124101, 124105, 124109, 124113, 124117, 124121, 124127, 124131, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 124135, 124139, 124143, 124147, - 124154, 124156, 124160, 124162, 124164, 124168, 124172, 124176, 124178, - 124182, 124186, 124190, 124194, 124198, 124200, 124204, 124206, 124212, - 124215, 124220, 124222, 124224, 124227, 124229, 124231, 124234, 124241, - 124248, 124255, 124260, 124264, 124266, 124268, 0, 124270, 124272, - 124276, 124280, 124284, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 124286, 124290, 124295, 124299, 124305, 124311, 124313, - 124315, 124321, 124323, 124327, 124331, 124333, 124337, 124339, 124343, - 124347, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 124351, 124353, - 124355, 124357, 124361, 124363, 124365, 124367, 124369, 124371, 124373, - 124375, 124377, 124379, 124381, 124383, 124385, 124387, 124389, 124391, - 124393, 124395, 124397, 124399, 124401, 124403, 124405, 124409, 124411, - 124413, 124415, 124419, 124421, 124425, 124427, 124429, 124433, 124437, - 124443, 124445, 124447, 124449, 124451, 124455, 124459, 124461, 124465, - 124469, 124473, 124477, 124481, 124485, 124489, 124493, 124497, 124501, - 124505, 124509, 124513, 124517, 124521, 124525, 124529, 0, 124533, 0, - 124535, 124537, 124539, 124541, 124543, 124551, 124559, 124567, 124575, - 124580, 124585, 124590, 124594, 124598, 124603, 124607, 124609, 124613, - 124615, 124617, 124619, 124621, 124623, 124625, 124627, 124631, 124633, - 124635, 124637, 124641, 124645, 124649, 124653, 124657, 124659, 124665, - 124671, 124673, 124675, 124677, 124679, 124681, 124690, 124697, 124704, - 124708, 124715, 124720, 124727, 124736, 124741, 124745, 124749, 124751, - 124755, 124757, 124761, 124765, 124767, 124771, 124775, 124779, 124781, - 124783, 124789, 124791, 124793, 124795, 124799, 124803, 124805, 124809, - 124811, 124813, 124816, 124820, 124822, 124826, 124828, 124830, 124835, - 124837, 124841, 124845, 124848, 124852, 124856, 124860, 124864, 124868, - 124872, 124876, 124881, 124885, 124889, 124898, 124903, 124906, 124908, - 124911, 124914, 124919, 124921, 124924, 124929, 124933, 124936, 124940, - 124944, 124947, 124952, 124956, 124960, 124964, 124968, 124974, 124980, - 124986, 124992, 124997, 125008, 125010, 125014, 125016, 125018, 125022, - 125026, 125028, 125032, 125037, 125042, 125048, 125050, 125054, 125058, - 125065, 125072, 125076, 125078, 125080, 125084, 125086, 125090, 125094, - 125098, 125100, 125102, 125109, 125113, 125116, 125120, 125124, 125128, - 125130, 125134, 125136, 125138, 125142, 125144, 125148, 125152, 125158, - 125162, 125166, 125170, 125172, 125175, 125179, 125186, 125195, 125204, - 125212, 125220, 125222, 125226, 125228, 125232, 125243, 125247, 125253, - 125259, 125264, 0, 125266, 125270, 125272, 125274, 0, 0, 0, 125276, - 125281, 125291, 125306, 125318, 125330, 125334, 125338, 125344, 125346, - 125354, 125362, 125364, 125368, 125374, 125380, 125387, 125394, 125396, - 125398, 125401, 125403, 125409, 125411, 125414, 125418, 125424, 125430, - 125441, 125447, 125454, 125462, 125466, 125474, 125482, 125488, 125494, - 125501, 125503, 125507, 125509, 125511, 125516, 125518, 125520, 125522, - 125524, 125528, 125539, 125545, 125549, 125553, 125557, 125563, 125569, - 125575, 125581, 125586, 125591, 125597, 125603, 125610, 0, 0, 125617, - 125622, 125630, 125634, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 125643, - 125650, 125657, 125664, 125672, 125680, 125688, 125696, 125704, 125712, - 125720, 125728, 125736, 125742, 125748, 125754, 125760, 125766, 125772, - 125778, 125784, 125790, 125796, 125802, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 125808, 125812, 125816, - 125821, 125826, 125828, 125832, 125841, 125849, 125857, 125870, 125883, - 125896, 125903, 125910, 125914, 125923, 125931, 125935, 125944, 125951, - 125955, 125959, 125963, 125967, 125974, 125978, 125982, 125986, 125990, - 125997, 126006, 126015, 126022, 126034, 126046, 126050, 126054, 126058, - 126062, 126066, 126070, 126078, 126086, 126094, 126098, 126102, 126106, - 126110, 126114, 126118, 126124, 126130, 126134, 126145, 126153, 126157, - 126161, 126165, 126169, 126175, 126182, 126193, 126203, 126213, 126224, - 126233, 126244, 126250, 126256, 0, 0, 0, 0, 126262, 126271, 126278, - 126284, 126288, 126292, 126296, 126305, 126317, 126321, 126328, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 126335, - 126337, 126339, 126343, 126347, 126351, 126360, 126362, 126364, 126367, - 126369, 126371, 126375, 126377, 126381, 126383, 126387, 126389, 126391, - 126395, 126399, 126405, 126407, 126411, 126413, 126417, 126421, 126425, - 126429, 126431, 126433, 126437, 126441, 126445, 126449, 126451, 126453, - 126455, 126460, 126465, 126468, 126476, 126484, 126486, 126491, 126494, - 126499, 126510, 126517, 126522, 126527, 126529, 126533, 126535, 126539, - 126541, 126545, 126549, 126552, 126555, 126557, 126560, 126562, 126566, - 126568, 126570, 126572, 126576, 126578, 126582, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 147241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 126585, 126590, 126595, 126600, 126605, 126610, 126615, 126622, - 126629, 126636, 126643, 126648, 126653, 126658, 126663, 126670, 126676, - 126683, 126690, 126697, 126702, 126707, 126712, 126717, 126722, 126729, - 126736, 126741, 126746, 126753, 126760, 126768, 126776, 126783, 126790, - 126798, 126806, 126814, 126821, 126831, 126842, 126847, 126854, 126861, - 126868, 126876, 126884, 126895, 126903, 126911, 126919, 126924, 126929, - 126934, 126939, 126944, 126949, 126954, 126959, 126964, 126969, 126974, - 126979, 126986, 126991, 126996, 127003, 127008, 127013, 127018, 127023, - 127028, 127033, 127038, 127043, 127048, 127053, 127058, 127063, 127070, - 127078, 127083, 127088, 127095, 127100, 127105, 127110, 127117, 127122, - 127129, 127134, 127141, 127146, 127155, 127164, 127169, 127174, 127179, - 127184, 127189, 127194, 127199, 127204, 127209, 127214, 127219, 127224, - 127229, 127237, 127245, 127250, 127255, 127260, 127265, 127270, 127276, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127282, 127286, 127290, 127294, - 127298, 127302, 127306, 127310, 127314, 127318, 127322, 127326, 127330, - 127334, 127338, 127342, 127346, 127350, 127354, 127358, 127362, 127366, - 127370, 127374, 127378, 127382, 127386, 127390, 127394, 127398, 127402, - 127406, 127410, 127414, 127418, 127422, 127426, 127430, 127434, 127438, - 127442, 127446, 127450, 127454, 127458, 127462, 127466, 127470, 127474, - 127478, 127482, 127486, 127490, 127494, 127498, 127502, 127506, 127510, - 127514, 127518, 127522, 127526, 127530, 127534, 127538, 127542, 127546, - 127550, 127554, 127558, 127562, 127566, 127570, 127574, 127578, 127582, - 127586, 127590, 127594, 127598, 127602, 127606, 127610, 127614, 127618, - 127622, 127626, 127630, 127634, 127638, 127642, 127646, 127650, 127654, - 127658, 127662, 127666, 127670, 127674, 127678, 127682, 127686, 127690, - 127694, 127698, 127702, 127706, 127710, 127714, 127718, 127722, 127726, - 127730, 127734, 127738, 127742, 127746, 127750, 127754, 127758, 127762, - 127766, 127770, 127774, 127778, 127782, 127786, 127790, 127794, 127798, - 127802, 127806, 127810, 127814, 127818, 127822, 127826, 127830, 127834, - 127838, 127842, 127846, 127850, 127854, 127858, 127862, 127866, 127870, - 127874, 127878, 127882, 127886, 127890, 127894, 127898, 127902, 127906, - 127910, 127914, 127918, 127922, 127926, 127930, 127934, 127938, 127942, - 127946, 127950, 127954, 127958, 127962, 127966, 127970, 127974, 127978, - 127982, 127986, 127990, 127994, 127998, 128002, 128006, 128010, 128014, - 128018, 128022, 128026, 128030, 128034, 128038, 128042, 128046, 128050, - 128054, 128058, 128062, 128066, 128070, 128074, 128078, 128082, 128086, - 128090, 128094, 128098, 128102, 128106, 128110, 128114, 128118, 128122, - 128126, 128130, 128134, 128138, 128142, 128146, 128150, 128154, 128158, - 128162, 128166, 128170, 128174, 128178, 128182, 128186, 128190, 128194, - 128198, 128202, 128206, 128210, 128214, 128218, 128222, 128226, 128230, - 128234, 128238, 128242, 128246, 128250, 128254, 128258, 128262, 128266, - 128270, 128274, 128278, 128282, 128286, 128290, 128294, 128298, 128302, - 128306, 128310, 128314, 128318, 128322, 128326, 128330, 128334, 128338, - 128342, 128346, 128350, 128354, 128358, 128362, 128366, 128370, 128374, - 128378, 128382, 128386, 128390, 128394, 128398, 128402, 128406, 128410, - 128414, 128418, 128422, 128426, 128430, 128434, 128438, 128442, 128446, - 128450, 128454, 128458, 128462, 128466, 128470, 128474, 128478, 128482, - 128486, 128490, 128494, 128498, 128502, 128506, 128510, 128514, 128518, - 128522, 128526, 128530, 128534, 128538, 128542, 128546, 128550, 128554, - 128558, 128562, 128566, 128570, 128574, 128578, 128582, 128586, 128590, - 128594, 128598, 128602, 128606, 128610, 128614, 128618, 128622, 128626, - 128630, 128634, 128638, 128642, 128646, 128650, 128654, 128658, 128662, - 128666, 128670, 128674, 128678, 128682, 128686, 128690, 128694, 128698, - 128702, 128706, 128710, 128714, 128718, 128722, 128726, 128730, 128734, - 128738, 128742, 128746, 128750, 128754, 128758, 128762, 128766, 128770, - 128774, 128778, 128782, 128786, 128790, 128794, 128798, 128802, 128806, - 128810, 128814, 128818, 128822, 128826, 128830, 128834, 128838, 128842, - 128846, 128850, 128854, 128858, 128862, 128866, 128870, 128874, 128878, - 128882, 128886, 128890, 128894, 128898, 128902, 128906, 128910, 128914, - 128918, 128922, 128926, 128930, 128934, 128938, 128942, 128946, 128950, - 128954, 128958, 128962, 128966, 128970, 128974, 128978, 128982, 128986, - 128990, 128994, 128998, 129002, 129006, 129010, 129014, 129018, 129022, - 129026, 129030, 129034, 129038, 129042, 129046, 129050, 129054, 129058, - 129062, 129066, 129070, 129074, 129078, 129082, 129086, 129090, 129094, - 129098, 129102, 129106, 129110, 129114, 129118, 129122, 129126, 129130, - 129134, 129138, 129142, 129146, 129150, 129154, 129158, 129162, 129166, - 129170, 129174, 129178, 129182, 129186, 129190, 129194, 129198, 129202, - 129206, 129210, 129214, 129218, 129222, 129226, 129230, 129234, 129238, - 129242, 129246, 129250, 129254, 129258, 129262, 129266, 129270, 129274, - 129278, 129282, 129286, 129290, 129294, 129298, 129302, 129306, 129310, - 129314, 129318, 129322, 129326, 129330, 129334, 129338, 129342, 129346, - 129350, 129354, 129358, 129362, 129366, 129370, 129374, 129378, 129382, - 129386, 129390, 129394, 129398, 129402, 129406, 129410, 129414, 129418, - 129422, 129426, 129430, 129434, 129438, 129442, 129446, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 147245, 147248, 147252, 147256, 147259, 147263, 147267, + 147270, 147273, 147277, 147281, 147284, 147287, 147290, 147293, 147298, + 147301, 147305, 147308, 147311, 147314, 147317, 147320, 147323, 147326, + 147329, 147332, 147335, 147338, 147342, 147346, 147350, 147354, 147359, + 147364, 147370, 147376, 147382, 147387, 147393, 147399, 147405, 147410, + 147416, 147422, 147427, 147433, 147439, 147444, 147450, 147456, 147461, + 147466, 147472, 147477, 147483, 147489, 147495, 147501, 147507, 147511, + 147516, 147520, 147525, 147529, 147534, 147539, 147545, 147551, 147557, + 147562, 147568, 147574, 147580, 147585, 147591, 147597, 147602, 147608, + 147614, 147619, 147625, 147631, 147636, 147641, 147647, 147652, 147658, + 147664, 147670, 147676, 147682, 147687, 147691, 147696, 147699, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129450, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 129454, 129457, 129461, 129465, 129468, 129472, 129476, - 129479, 129482, 129486, 129490, 129493, 129496, 129499, 129502, 129507, - 129510, 129514, 129517, 129520, 129523, 129526, 129529, 129532, 129535, - 129538, 129541, 129544, 129547, 129551, 129555, 129559, 129563, 129568, - 129573, 129579, 129585, 129591, 129596, 129602, 129608, 129614, 129619, - 129625, 129631, 129636, 129641, 129647, 129652, 129658, 129664, 129669, - 129675, 129681, 129686, 129692, 129698, 129704, 129710, 129716, 129720, - 129725, 129729, 129734, 129738, 129743, 129748, 129754, 129760, 129766, - 129771, 129777, 129783, 129789, 129794, 129800, 129806, 129811, 129816, - 129822, 129827, 129833, 129839, 129844, 129850, 129856, 129861, 129867, - 129873, 129879, 129885, 129891, 129896, 129900, 129905, 129907, 129911, - 129914, 129917, 129920, 129923, 129926, 129929, 129932, 129935, 129938, - 129941, 129944, 129947, 129950, 129953, 129956, 129959, 129962, 129965, - 129968, 129971, 129974, 129977, 129980, 129983, 129986, 129989, 129992, - 129995, 129998, 130001, 130004, 130007, 130010, 130013, 130016, 130019, - 130022, 130025, 130028, 130031, 130034, 130037, 130040, 130043, 130046, - 130049, 130052, 130055, 130058, 130061, 130064, 130067, 130070, 130073, - 130076, 130079, 130082, 130085, 130088, 130091, 130094, 130097, 130100, - 130103, 130106, 130109, 130112, 130115, 130118, 130121, 130124, 130127, - 130130, 130133, 130136, 130139, 130142, 130145, 130148, 130151, 130154, - 130157, 130160, 130163, 130166, 130169, 130172, 130175, 130178, 130181, - 130184, 130187, 130190, 130193, 130196, 130199, 130202, 130205, 130208, - 130211, 130214, 130217, 130220, 130223, 130226, 130229, 130232, 130235, - 130238, 130241, 130244, 130247, 130250, 130253, 130256, 130259, 130262, - 130265, 130268, 130271, 130274, 130277, 130280, 130283, 130286, 130289, - 130292, 130295, 130298, 130301, 130304, 130307, 130310, 130313, 130316, - 130319, 130322, 130325, 130328, 130331, 130334, 130337, 130340, 130343, - 130346, 130349, 130352, 130355, 130358, 130361, 130364, 130367, 130370, - 130373, 130376, 130379, 130382, 130385, 130388, 130391, 130394, 130397, - 130400, 130403, 130406, 130409, 130412, 130415, 130418, 130421, 130424, - 130427, 130430, 130433, 130436, 130439, 130442, 130445, 130448, 130451, - 130454, 130457, 130460, 130463, 130466, 130469, 130472, 130475, 130478, - 130481, 130484, 130487, 130490, 130493, 130496, 130499, 130502, 130505, - 130508, 130511, 130514, 130517, 130520, 130523, 130526, 130529, 130532, - 130535, 130538, 130541, 130544, 130547, 130550, 130553, 130556, 130559, - 130562, 130565, 130568, 130571, 130574, 130577, 130580, 130583, 130586, - 130589, 130592, 130595, 130598, 130601, 130604, 130607, 130610, 130613, - 130616, 130619, 130622, 130625, 130628, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 130631, 130633, 130635, 130640, 130642, 130647, 130649, - 130654, 130656, 130661, 130663, 130665, 130667, 130669, 130671, 130673, - 130675, 130677, 130679, 130682, 130685, 130687, 130689, 130693, 130696, - 130701, 130703, 130705, 130707, 130711, 130714, 130716, 130720, 130722, - 130726, 130728, 130732, 130735, 130737, 130741, 130745, 130747, 130753, - 130755, 130760, 130762, 130767, 130769, 130774, 130776, 130781, 130783, - 130786, 130788, 130792, 130794, 130801, 130803, 130805, 130807, 130812, - 130814, 130816, 130818, 130820, 130822, 130827, 130831, 130833, 130838, - 130842, 130844, 130849, 130853, 130855, 130860, 130864, 130866, 130868, - 130870, 130872, 130876, 130878, 130883, 130885, 130891, 130893, 130899, - 130901, 130903, 130905, 130909, 130911, 130918, 130920, 130927, 130929, - 130934, 130939, 130941, 130947, 130953, 130955, 130961, 130966, 130968, - 130974, 130980, 130982, 130988, 130994, 130996, 131002, 131006, 131008, - 131013, 131015, 131017, 131022, 131024, 131026, 131032, 131034, 131039, - 131043, 131045, 131050, 131054, 131056, 131062, 131064, 131068, 131070, - 131074, 131076, 131083, 131090, 131092, 131099, 131106, 131108, 131113, - 131115, 131122, 131124, 131129, 131131, 131137, 131139, 131143, 131145, - 131151, 131153, 131157, 131159, 131165, 131167, 131169, 131171, 131176, - 131181, 131183, 131185, 131194, 131198, 131205, 131212, 131217, 131222, - 131234, 131236, 131238, 131240, 131242, 131244, 131246, 131248, 131250, - 131252, 131254, 131256, 131258, 131260, 131262, 131264, 131266, 131268, - 131270, 131272, 131274, 131276, 131282, 131289, 131294, 131299, 131310, - 131312, 131314, 131316, 131318, 131320, 131322, 131324, 131326, 131328, - 131330, 131332, 131334, 131336, 131338, 131340, 131342, 131347, 131349, - 131351, 131357, 131369, 131380, 131382, 131384, 131386, 131388, 131390, - 131392, 131394, 131396, 131398, 131400, 131402, 131404, 131406, 131408, - 131410, 131412, 131414, 131416, 131418, 131420, 131422, 131424, 131426, - 131428, 131430, 131432, 131434, 131436, 131438, 131440, 131442, 131444, - 131446, 131448, 131450, 131452, 131454, 131456, 131458, 131460, 131462, - 131464, 131466, 131468, 131470, 131472, 131474, 131476, 131478, 131480, - 131482, 131484, 131486, 131488, 131490, 131492, 131494, 131496, 131498, - 131500, 131502, 131504, 131506, 131508, 131510, 131512, 131514, 131516, - 131518, 131520, 131522, 131524, 131526, 131528, 131530, 131532, 131534, - 131536, 131538, 131540, 131542, 131544, 131546, 131548, 131550, 131552, - 131554, 131556, 131558, 131560, 131562, 131564, 131566, 131568, 131570, - 131572, 131574, 131576, 131578, 131580, 131582, 131584, 131586, 131588, - 131590, 131592, 131594, 131596, 131598, 131600, 131602, 131604, 131606, - 131608, 131610, 131612, 131614, 131616, 131618, 131620, 131622, 131624, - 131626, 131628, 131630, 131632, 131634, 131636, 131638, 131640, 131642, - 131644, 131646, 131648, 131650, 131652, 131654, 131656, 131658, 131660, - 131662, 131664, 131666, 131668, 131670, 131672, 131674, 131676, 131678, - 131680, 131682, 131684, 131686, 131688, 131690, 131692, 131694, 131696, - 131698, 131700, 131702, 131704, 131706, 131708, 131710, 131712, 131714, - 131716, 131718, 131720, 131722, 131724, 131726, 131728, 131730, 131732, - 131734, 131736, 131738, 131740, 131742, 131744, 131746, 131748, 131750, - 131752, 131754, 131756, 131758, 131760, 131762, 131764, 131766, 131768, - 131770, 131772, 131774, 131776, 131778, 131780, 131782, 131784, 131786, - 131788, 131790, 131792, 131794, 131796, 131798, 131800, 131802, 131804, - 131806, 131808, 131810, 131812, 131814, 131816, 131818, 131820, 131822, - 131824, 131826, 131828, 131830, 131832, 131834, 131836, 131838, 131840, - 131842, 131844, 131846, 131848, 131850, 131852, 131854, 131856, 131858, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 147703, 147706, 147709, 147712, 147715, 147718, 147721, + 147724, 147727, 147730, 147733, 147736, 147739, 147742, 147745, 147748, + 147751, 147754, 147757, 147760, 147763, 147766, 147769, 147772, 147775, + 147778, 147781, 147784, 147787, 147790, 147793, 147796, 147799, 147802, + 147805, 147808, 147811, 147814, 147817, 147820, 147823, 147826, 147829, + 147832, 147835, 147838, 147841, 147844, 147847, 147850, 147853, 147856, + 147859, 147862, 147865, 147868, 147871, 147874, 147877, 147880, 147883, + 147886, 147889, 147892, 147895, 147898, 147901, 147904, 147907, 147910, + 147913, 147916, 147919, 147922, 147925, 147928, 147931, 147934, 147937, + 147940, 147943, 147946, 147949, 147952, 147955, 147958, 147961, 147964, + 147967, 147970, 147973, 147976, 147979, 147982, 147985, 147988, 147991, + 147994, 147997, 148000, 148003, 148006, 148009, 148012, 148015, 148018, + 148021, 148024, 148027, 148030, 148033, 148036, 148039, 148042, 148045, + 148048, 148051, 148054, 148057, 148060, 148063, 148066, 148069, 148072, + 148075, 148078, 148081, 148084, 148087, 148090, 148093, 148096, 148099, + 148102, 148105, 148108, 148111, 148114, 148117, 148120, 148123, 148126, + 148129, 148132, 148135, 148138, 148141, 148144, 148147, 148150, 148153, + 148156, 148159, 148162, 148165, 148168, 148171, 148174, 148177, 148180, + 148183, 148186, 148189, 148192, 148195, 148198, 148201, 148204, 148207, + 148210, 148213, 148216, 148219, 148222, 148225, 148228, 148231, 148234, + 148237, 148240, 148243, 148246, 148249, 148252, 148255, 148258, 148261, + 148264, 148267, 148270, 148273, 148276, 148279, 148282, 148285, 148288, + 148291, 148294, 148297, 148300, 148303, 148306, 148309, 148312, 148315, + 148318, 148321, 148324, 148327, 148330, 148333, 148336, 148339, 148342, + 148345, 148348, 148351, 148354, 148357, 148360, 148363, 148366, 148369, + 148372, 148375, 148378, 148381, 148384, 148387, 148390, 148393, 148396, + 148399, 148402, 148405, 148408, 148411, 148414, 148417, 148420, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148423, 148425, 148427, 148432, + 148434, 148439, 148441, 148446, 148448, 148453, 148455, 148457, 148459, + 148461, 148463, 148465, 148467, 148469, 148471, 148474, 148477, 148479, + 148481, 148485, 148488, 148493, 148495, 148497, 148499, 148503, 148506, + 148508, 148512, 148514, 148518, 148520, 148524, 148527, 148529, 148533, + 148537, 148539, 148545, 148547, 148552, 148554, 148559, 148561, 148566, + 148568, 148573, 148575, 148578, 148580, 148584, 148586, 148593, 148595, + 148597, 148599, 148604, 148606, 148608, 148610, 148612, 148614, 148619, + 148623, 148625, 148630, 148634, 148636, 148641, 148645, 148647, 148652, + 148656, 148658, 148660, 148662, 148664, 148668, 148670, 148675, 148677, + 148683, 148685, 148691, 148693, 148695, 148697, 148701, 148703, 148710, + 148712, 148719, 148721, 148726, 148731, 148733, 148739, 148745, 148747, + 148753, 148758, 148760, 148766, 148772, 148774, 148780, 148786, 148788, + 148794, 148798, 148800, 148805, 148807, 148809, 148814, 148816, 148818, + 148824, 148826, 148831, 148835, 148837, 148842, 148846, 148848, 148854, + 148856, 148860, 148862, 148866, 148868, 148875, 148882, 148884, 148891, + 148898, 148900, 148905, 148907, 148914, 148916, 148921, 148923, 148929, + 148931, 148935, 148937, 148943, 148945, 148949, 148951, 148957, 148959, + 148961, 148963, 148968, 148973, 148975, 148977, 148987, 148991, 148998, + 149005, 149010, 149015, 149027, 149029, 149031, 149033, 149035, 149037, + 149039, 149041, 149043, 149045, 149047, 149049, 149051, 149053, 149055, + 149057, 149059, 149061, 149063, 149065, 149067, 149069, 149075, 149082, + 149087, 149092, 149103, 149105, 149107, 149109, 149111, 149113, 149115, + 149117, 149119, 149121, 149123, 149125, 149127, 149129, 149131, 149133, + 149135, 149140, 149142, 149144, 149150, 149162, 149173, 149175, 149177, + 149179, 149181, 149183, 149185, 149187, 149189, 149191, 149193, 149195, + 149197, 149199, 149201, 149203, 149205, 149207, 149209, 149211, 149213, + 149215, 149217, 149219, 149221, 149223, 149225, 149227, 149229, 149231, + 149233, 149235, 149237, 149239, 149241, 149243, 149245, 149247, 149249, + 149251, 149253, 149255, 149257, 149259, 149261, 149263, 149265, 149267, + 149269, 149271, 149273, 149275, 149277, 149279, 149281, 149283, 149285, + 149287, 149289, 149291, 149293, 149295, 149297, 149299, 149301, 149303, + 149305, 149307, 149309, 149311, 149313, 149315, 149317, 149319, 149321, + 149323, 149325, 149327, 149329, 149331, 149333, 149335, 149337, 149339, + 149341, 149343, 149345, 149347, 149349, 149351, 149353, 149355, 149357, + 149359, 149361, 149363, 149365, 149367, 149369, 149371, 149373, 149375, + 149377, 149379, 149381, 149383, 149385, 149387, 149389, 149391, 149393, + 149395, 149397, 149399, 149401, 149403, 149405, 149407, 149409, 149411, + 149413, 149415, 149417, 149419, 149421, 149423, 149425, 149427, 149429, + 149431, 149433, 149435, 149437, 149439, 149441, 149443, 149445, 149447, + 149449, 149451, 149453, 149455, 149457, 149459, 149461, 149463, 149465, + 149467, 149469, 149471, 149473, 149475, 149477, 149479, 149481, 149483, + 149485, 149487, 149489, 149491, 149493, 149495, 149497, 149499, 149501, + 149503, 149505, 149507, 149509, 149511, 149513, 149515, 149517, 149519, + 149521, 149523, 149525, 149527, 149529, 149531, 149533, 149535, 149537, + 149539, 149541, 149543, 149545, 149547, 149549, 149551, 149553, 149555, + 149557, 149559, 149561, 149563, 149565, 149567, 149569, 149571, 149573, + 149575, 149577, 149579, 149581, 149583, 149585, 149587, 149589, 149591, + 149593, 149595, 149597, 149599, 149601, 149603, 149605, 149607, 149609, + 149611, 149613, 149615, 149617, 149619, 149621, 149623, 149625, 149627, + 149629, 149631, 149633, 149635, 149637, 149639, 149641, 149643, 149645, + 149647, 149649, 149651, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 131860, 131870, 131880, 131889, 131898, 131911, - 131924, 131936, 131948, 131958, 131968, 131978, 131988, 131999, 132010, - 132020, 132029, 132038, 132047, 132060, 132073, 132085, 132097, 132107, - 132117, 132127, 132137, 132146, 132155, 132164, 132173, 132182, 132191, - 132200, 132209, 132218, 132227, 132236, 132245, 132256, 132266, 132276, - 132289, 132299, 132312, 132319, 132329, 132336, 132343, 132350, 132357, - 132364, 132371, 132380, 132389, 132398, 132407, 132416, 132425, 132434, - 132443, 132451, 132459, 132466, 132476, 132485, 132493, 132500, 132510, - 132519, 132529, 132539, 132550, 132560, 132569, 132579, 132588, 132598, - 132606, 132610, 132614, 132618, 132622, 132626, 132630, 132634, 132638, - 132642, 132646, 132649, 132653, 132656, 132659, 132663, 132667, 132671, - 132675, 132679, 132683, 132687, 132691, 132695, 132699, 132703, 132707, - 132711, 132715, 132719, 132723, 132727, 132731, 132735, 132739, 132743, - 132747, 132751, 132755, 132759, 132763, 132767, 132771, 132775, 132779, - 132783, 132787, 132791, 132795, 132799, 132803, 132807, 132811, 132815, - 132819, 132823, 132827, 132831, 132835, 132839, 132843, 132847, 132851, - 132855, 132859, 132863, 132867, 132871, 132875, 132879, 132883, 132887, - 132891, 132895, 132899, 132903, 132907, 132911, 132915, 132919, 132923, - 132927, 132931, 132935, 132939, 132943, 132947, 132951, 132955, 132959, - 132963, 132967, 132971, 132975, 132979, 132983, 132987, 132991, 132995, - 132999, 133002, 133006, 133010, 133014, 133018, 133022, 133026, 133030, - 133034, 133038, 133042, 133046, 133050, 133054, 133058, 133062, 133066, - 133070, 133074, 133078, 133082, 133086, 133090, 133094, 133098, 133102, - 133106, 133110, 133114, 133118, 133122, 133126, 133130, 133134, 133138, - 133142, 133146, 133150, 133154, 133158, 133162, 133166, 133170, 133174, - 133178, 133182, 133186, 133190, 133194, 133198, 133202, 133206, 133210, - 133214, 133218, 133222, 133226, 133230, 133234, 133238, 133242, 133246, - 133250, 133254, 133258, 133262, 133266, 133270, 133274, 133278, 133282, - 133286, 133290, 133294, 133298, 133302, 133306, 133310, 133314, 133318, - 133322, 133326, 133330, 133334, 133338, 133342, 133346, 133350, 133354, - 133358, 133362, 133366, 133370, 133374, 133378, 133382, 133386, 133390, - 133394, 133398, 133402, 133406, 133410, 133414, 133418, 133422, 133426, - 133430, 133434, 133438, 133442, 133446, 133450, 133454, 133458, 133462, - 133466, 133470, 133474, 133478, 133482, 133486, 133490, 133494, 133498, - 133502, 133506, 133510, 133514, 133518, 133522, 133526, 133530, 133534, - 133538, 133542, 133546, 133550, 133554, 133558, 133562, 133566, 133570, - 133574, 133578, 133582, 133586, 133590, 133594, 133598, 133602, 133606, - 133610, 133614, 133618, 133622, 133626, 133630, 133634, 133638, 133642, - 133646, 133650, 133654, 133658, 133662, 133666, 133670, 133674, 133678, - 133682, 133686, 133690, 133694, 133698, 133702, 133706, 133710, 133714, - 133718, 133722, 133726, 133730, 133734, 133738, 133742, 133746, 133750, - 133754, 133758, 133762, 133766, 133771, 133776, 133781, 133785, 133791, - 133798, 133805, 133812, 133819, 133826, 133833, 133840, 133847, 133854, - 133861, 133868, 133875, 133882, 133888, 133895, 133902, 133908, 133915, - 133922, 133929, 133936, 133943, 133950, 133957, 133964, 133971, 133978, - 133985, 133992, 133999, 134005, 134011, 134018, 134025, 134034, 134043, - 134052, 134061, 134066, 134071, 134077, 134083, 134089, 134095, 134101, - 134107, 134113, 134119, 134125, 134131, 134137, 134143, 134148, 134154, - 134164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 149653, 149663, 149673, + 149682, 149691, 149704, 149717, 149729, 149741, 149751, 149761, 149771, + 149781, 149792, 149803, 149813, 149822, 149831, 149840, 149853, 149866, + 149878, 149890, 149900, 149910, 149920, 149930, 149939, 149948, 149958, + 149968, 149977, 149986, 149996, 150006, 150015, 150024, 150034, 150044, + 150055, 150066, 150076, 150089, 150100, 150114, 150122, 150133, 150141, + 150149, 150157, 150165, 150173, 150181, 150190, 150199, 150209, 150219, + 150228, 150237, 150247, 150257, 150265, 150274, 150282, 150291, 150299, + 150307, 150314, 150324, 150333, 150344, 150355, 150367, 150378, 150388, + 150399, 150409, 150420, 150428, 150432, 150436, 150440, 150444, 150448, + 150452, 150456, 150460, 150464, 150468, 150472, 150476, 150479, 150482, + 150486, 150490, 150494, 150498, 150502, 150506, 150510, 150514, 150517, + 150521, 150525, 150529, 150533, 150537, 150541, 150545, 150549, 150553, + 150557, 150561, 150565, 150569, 150573, 150577, 150581, 150585, 150589, + 150593, 150597, 150601, 150605, 150609, 150613, 150617, 150621, 150625, + 150629, 150633, 150637, 150641, 150645, 150649, 150653, 150657, 150661, + 150665, 150669, 150673, 150677, 150681, 150685, 150689, 150693, 150697, + 150701, 150705, 150709, 150713, 150717, 150721, 150725, 150729, 150733, + 150737, 150741, 150745, 150749, 150753, 150757, 150761, 150765, 150769, + 150773, 150777, 150781, 150785, 150789, 150793, 150797, 150801, 150805, + 150809, 150813, 150817, 150821, 150824, 150828, 150832, 150836, 150840, + 150844, 150848, 150852, 150856, 150860, 150864, 150868, 150872, 150876, + 150880, 150884, 150888, 150892, 150896, 150900, 150904, 150908, 150912, + 150916, 150920, 150924, 150928, 150932, 150936, 150940, 150944, 150948, + 150952, 150956, 150960, 150964, 150968, 150972, 150976, 150980, 150984, + 150988, 150992, 150996, 151000, 151004, 151008, 151012, 151016, 151020, + 151024, 151028, 151032, 151036, 151040, 151044, 151048, 151052, 151056, + 151060, 151064, 151068, 151072, 151076, 151080, 151084, 151088, 151092, + 151096, 151100, 151104, 151108, 151112, 151116, 151120, 151124, 151128, + 151132, 151136, 151140, 151144, 151148, 151152, 151156, 151160, 151164, + 151168, 151172, 151176, 151180, 151184, 151188, 151192, 151196, 151200, + 151204, 151208, 151212, 151216, 151220, 151224, 151228, 151232, 151236, + 151240, 151244, 151248, 151252, 151256, 151260, 151264, 151268, 151272, + 151276, 151280, 151284, 151288, 151292, 151296, 151300, 151304, 151308, + 151312, 151316, 151320, 151324, 151328, 151332, 151336, 151340, 151344, + 151348, 151352, 151356, 151360, 151364, 151368, 151372, 151376, 151380, + 151384, 151388, 151392, 151396, 151400, 151404, 151408, 151412, 151416, + 151420, 151424, 151428, 151432, 151436, 151440, 151444, 151448, 151452, + 151456, 151460, 151464, 151468, 151472, 151476, 151480, 151484, 151488, + 151492, 151496, 151500, 151504, 151508, 151512, 151516, 151520, 151524, + 151528, 151532, 151536, 151540, 151544, 151548, 151552, 151556, 151560, + 151564, 151568, 151572, 151576, 151580, 151584, 151588, 151593, 151598, + 151603, 151607, 151613, 151620, 151627, 151634, 151641, 151648, 151655, + 151662, 151669, 151676, 151683, 151690, 151697, 151704, 151710, 151717, + 151724, 151730, 151737, 151744, 151751, 151758, 151765, 151772, 151779, + 151786, 151793, 151800, 151807, 151814, 151821, 151828, 151834, 151841, + 151848, 151857, 151866, 151875, 151884, 151889, 151894, 151900, 151906, + 151912, 151918, 151924, 151930, 151936, 151942, 151948, 151954, 151960, + 151966, 151971, 151977, 151987, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; /* name->code dictionary */ static unsigned int code_hash[] = { - 74224, 4851, 0, 78156, 78499, 128685, 7929, 0, 194682, 127766, 78500, - 66480, 0, 42833, 74529, 12064, 0, 596, 983821, 69850, 13192, 8651, 0, 0, - 120218, 12995, 64865, 1373, 0, 0, 5816, 119067, 64810, 4231, 6825, 42897, - 4233, 4234, 4232, 917836, 74415, 120210, 6384, 917840, 78108, 8851, 0, - 128553, 0, 41601, 8874, 983783, 7748, 0, 0, 0, 127939, 41603, 9784, 0, - 9188, 41600, 0, 120618, 128343, 1457, 3535, 0, 0, 0, 0, 65240, 11951, 0, - 3404, 0, 0, 0, 1759, 0, 41076, 68383, 120572, 119205, 66577, 94014, - 127764, 65859, 0, 7404, 0, 0, 0, 0, 65908, 9834, 3055, 9852, 983860, - 65288, 0, 11398, 0, 92417, 119255, 0, 0, 603, 74398, 43548, 0, 0, 917824, - 3350, 120817, 64318, 917828, 127089, 3390, 74483, 43265, 120599, 917830, - 78573, 0, 1919, 3400, 120651, 127944, 11647, 917540, 66446, 64141, 8562, + 74224, 4851, 125138, 78156, 78499, 72391, 7929, 66910, 194682, 127766, + 78500, 66480, 64038, 42833, 74529, 12064, 72385, 596, 983821, 69850, + 13192, 8651, 120217, 126542, 120218, 12995, 64865, 1373, 0, 113752, 5816, + 119067, 64810, 4231, 6825, 42897, 4233, 4234, 4232, 917836, 74415, + 120210, 6384, 70351, 78108, 8851, 67698, 128553, 0, 41601, 8874, 72392, + 7748, 0, 0, 127026, 127939, 41603, 9784, 0, 9188, 41600, 0, 120618, + 128343, 1457, 3535, 128635, 6381, 0, 0, 65240, 11951, 0, 3404, 0, 70487, + 72411, 1759, 0, 41076, 68383, 69972, 119205, 66577, 94014, 127764, 65859, + 0, 7404, 0, 0, 69970, 128387, 65908, 9834, 3055, 9852, 983860, 65288, 0, + 11398, 0, 92417, 93016, 128380, 0, 603, 74398, 43548, 0, 71865, 917824, + 3350, 120817, 64318, 917828, 78121, 3390, 74483, 43265, 120599, 917830, + 78573, 0, 1919, 3400, 120651, 119949, 11647, 917540, 66446, 64141, 8562, 2121, 64138, 4043, 8712, 64134, 64133, 11297, 983688, 983152, 11966, - 64128, 128587, 0, 0, 64132, 10867, 64130, 64129, 983844, 43374, 9779, - 2764, 66002, 10167, 9471, 0, 66021, 0, 0, 5457, 5440, 8857, 93981, 65282, - 2843, 5355, 127928, 983965, 0, 5194, 11657, 43984, 128292, 0, 983620, 0, - 0, 127027, 10717, 64570, 5630, 5396, 64143, 10682, 0, 10602, 800, 42499, - 66186, 0, 0, 64930, 11631, 64146, 64145, 64144, 762, 13172, 118859, - 194661, 64468, 10906, 1353, 6960, 0, 0, 5828, 8724, 917806, 8933, 1601, - 42244, 858, 7080, 64109, 64108, 8090, 0, 74401, 917811, 587, 0, 128131, - 0, 0, 0, 78214, 2750, 74218, 556, 64158, 64157, 983949, 12213, 194678, - 2760, 0, 0, 0, 194794, 64156, 64155, 42496, 0, 64151, 64150, 12679, - 10053, 10421, 11093, 64153, 64152, 0, 0, 4839, 0, 0, 1874, 119016, 0, - 6577, 64125, 64124, 64123, 0, 127531, 92534, 7007, 7590, 65443, 9036, - 92550, 64122, 74422, 66609, 0, 64117, 64116, 6287, 64114, 2725, 64120, - 64119, 43981, 42128, 127842, 1177, 65601, 12322, 64106, 69640, 127306, - 64102, 7859, 1945, 64099, 0, 10453, 64104, 7188, 7997, 0, 7389, 983161, - 8705, 64097, 64096, 9571, 528, 128671, 44017, 11429, 71347, 0, 983077, - 917990, 73841, 0, 0, 9056, 64313, 6188, 120019, 6155, 64068, 1823, 64066, - 64065, 64072, 64071, 63, 7233, 92212, 0, 41904, 6639, 64064, 983775, - 128344, 0, 1176, 118959, 127930, 8162, 128667, 983831, 0, 120519, 66376, - 66242, 11415, 4333, 9855, 64112, 64642, 0, 5388, 0, 0, 0, 7714, 66222, - 69902, 7768, 0, 4199, 64708, 983421, 0, 0, 8708, 9560, 64077, 64076, - 8996, 4992, 4471, 42622, 64079, 64078, 92179, 0, 126570, 0, 64615, 41915, - 0, 12075, 70062, 0, 5174, 983217, 0, 127557, 3123, 0, 12685, 127904, - 8408, 64704, 0, 0, 9223, 0, 41616, 67999, 73797, 0, 1116, 128204, 43049, - 7136, 43050, 8548, 120485, 0, 119061, 917999, 0, 13115, 43675, 64091, - 9322, 0, 120595, 64095, 64094, 8111, 66247, 42332, 64089, 64088, 6199, 0, - 0, 11434, 64083, 64082, 11329, 7737, 64087, 64086, 64085, 64084, 194817, - 9927, 41335, 4118, 1797, 0, 41334, 0, 46, 43448, 127881, 298, 0, 128114, - 0, 42627, 0, 32, 6187, 119052, 11495, 11459, 3665, 983600, 42871, 0, - 19923, 74335, 0, 127192, 66239, 42264, 64403, 4412, 7240, 92495, 0, - 983466, 65758, 12750, 4181, 8544, 0, 120199, 917897, 120198, 69809, 6181, - 65014, 0, 0, 983196, 3639, 119588, 0, 0, 118904, 10073, 120206, 128862, - 127186, 68409, 42844, 7498, 1098, 92565, 120205, 0, 983118, 10207, 8789, - 983225, 0, 0, 983472, 9234, 0, 6182, 983474, 65058, 0, 983478, 983475, 0, - 5471, 9461, 5573, 118936, 5473, 44, 0, 66244, 94072, 0, 66238, 12844, 0, - 1622, 7767, 1900, 41339, 11458, 0, 0, 6581, 5576, 0, 64405, 41337, 0, - 41631, 8947, 68390, 127844, 41694, 0, 0, 7908, 0, 10408, 6579, 0, 64618, - 0, 120147, 2138, 6583, 7761, 127010, 120504, 194828, 0, 5058, 41010, - 9992, 128299, 5057, 0, 0, 74538, 5054, 118951, 194971, 78606, 0, 1437, - 41617, 658, 3497, 128509, 7486, 5061, 5060, 4235, 127878, 0, 128529, - 12113, 4236, 4727, 0, 0, 7693, 10749, 0, 7488, 5773, 978, 128134, 0, - 41619, 10239, 68611, 0, 66209, 0, 128700, 9748, 983956, 127524, 0, 0, 0, - 0, 195083, 0, 983843, 0, 0, 0, 0, 0, 9341, 119596, 2379, 11325, 0, 64668, - 67854, 8125, 120545, 6743, 119175, 917940, 2369, 0, 983972, 983973, - 119235, 74092, 73936, 7008, 43660, 0, 0, 0, 2367, 127827, 983857, 264, - 2375, 8060, 6194, 119858, 1844, 119084, 0, 6019, 0, 0, 6961, 0, 118839, - 0, 8800, 0, 42862, 4463, 65581, 6192, 194676, 42771, 0, 92333, 725, - 65042, 118797, 120800, 983040, 12892, 0, 0, 0, 0, 0, 0, 127261, 120707, - 983128, 0, 5074, 5073, 128790, 8983, 118981, 74493, 983561, 5072, 93977, - 6198, 11614, 0, 196, 0, 0, 0, 4929, 120342, 0, 0, 0, 0, 42847, 0, 0, 0, - 4934, 0, 41323, 9758, 0, 92289, 127917, 42584, 0, 4329, 41321, 4979, - 3048, 7752, 41320, 983042, 74418, 12819, 0, 5071, 0, 3642, 0, 5070, - 10042, 118835, 3987, 5068, 0, 8909, 78650, 78649, 69917, 10636, 73981, - 11806, 43167, 4531, 1245, 9105, 66463, 4921, 120219, 4926, 65544, 73884, - 194619, 0, 0, 64709, 0, 194620, 78880, 4922, 325, 992, 119568, 4925, 0, - 0, 9526, 4920, 0, 948, 0, 120208, 4930, 0, 92175, 120275, 4933, 120211, - 0, 118985, 4928, 0, 0, 74770, 120194, 126548, 722, 194934, 19908, 12637, - 127485, 119855, 8753, 1509, 0, 5468, 9511, 127474, 127477, 1672, 6205, - 10864, 74586, 127480, 70103, 127466, 78555, 127468, 73863, 126577, - 126503, 41607, 120115, 1679, 120116, 120180, 120113, 127462, 7005, 41609, - 9580, 0, 401, 69949, 43779, 6968, 5761, 342, 8553, 0, 8143, 127115, - 11983, 92249, 624, 74508, 4057, 43788, 5078, 74258, 12478, 0, 5076, 0, - 194609, 0, 8295, 685, 9025, 1524, 12618, 0, 5539, 0, 92523, 120102, 7138, - 120552, 0, 194611, 78752, 0, 12520, 8058, 9732, 0, 5080, 64775, 5036, - 5035, 120590, 42604, 983656, 0, 8074, 275, 13291, 1907, 78838, 4432, - 127271, 5033, 127273, 127272, 4836, 3888, 73792, 10729, 64546, 127262, - 43704, 127264, 127251, 67588, 119000, 127252, 127255, 8858, 6409, 127256, - 120252, 128100, 0, 0, 66321, 0, 12814, 127248, 3432, 10218, 0, 6094, - 7641, 42445, 0, 92487, 42406, 1676, 74320, 194607, 983177, 5030, 0, 0, 0, - 73869, 9622, 0, 69944, 6787, 0, 0, 0, 983583, 10544, 12919, 0, 92218, 0, - 0, 69906, 120789, 0, 947, 119835, 194586, 194585, 10969, 119935, 7613, - 92562, 119936, 4795, 119930, 7018, 7376, 120181, 120192, 120268, 0, - 43567, 74056, 917910, 11833, 119919, 7216, 65232, 7217, 251, 7218, 7895, - 4395, 43538, 119926, 119929, 119928, 7213, 119922, 7214, 7215, 983836, - 74141, 8880, 7685, 66459, 120173, 65540, 119618, 625, 8187, 42861, 1113, - 7236, 7915, 3630, 120176, 8179, 74264, 67886, 9316, 10980, 2489, 65624, - 8150, 1359, 67652, 127329, 127330, 73756, 5042, 5041, 42769, 12084, - 127324, 127321, 92279, 127319, 127320, 127317, 127318, 127315, 12283, - 1616, 3795, 0, 8795, 66245, 0, 0, 0, 1138, 73905, 12677, 0, 0, 3239, - 127311, 0, 0, 8431, 0, 42164, 0, 11778, 12620, 6826, 73773, 119073, 5040, - 0, 0, 983443, 78420, 0, 5039, 0, 78418, 0, 5038, 0, 0, 13184, 74293, 0, - 64648, 0, 9359, 78416, 0, 128770, 65157, 6662, 0, 0, 3863, 73909, 4835, - 55266, 43432, 127822, 4309, 7127, 194569, 0, 194568, 1301, 0, 42589, 569, - 0, 73813, 711, 4389, 7133, 0, 73880, 11610, 11368, 0, 194570, 41331, - 1006, 74240, 0, 1550, 8201, 73737, 7627, 5499, 5031, 77908, 42738, 65784, - 77907, 65267, 3758, 0, 65781, 64734, 70073, 2440, 65780, 77913, 8449, 0, - 5008, 983572, 2118, 0, 12121, 8255, 5512, 73875, 2128, 2130, 2131, 2126, - 2133, 1119, 127068, 2114, 2116, 2455, 0, 2122, 2123, 2124, 2125, 127486, - 8714, 983820, 2113, 0, 2115, 128177, 127907, 43713, 5052, 66220, 5821, - 6186, 65778, 65775, 5051, 65773, 1429, 42647, 5050, 302, 388, 41115, 735, - 6637, 5907, 65088, 0, 12726, 74594, 9117, 983181, 12003, 5513, 6666, - 5053, 74230, 5510, 78451, 0, 78447, 2470, 78437, 0, 1925, 0, 92237, - 74807, 0, 5048, 5047, 0, 0, 0, 92313, 0, 74497, 92395, 8089, 6929, 639, - 983563, 68179, 64442, 0, 92348, 4599, 41402, 6674, 43397, 43294, 1476, - 648, 0, 65819, 3233, 0, 41782, 6951, 94017, 983976, 3530, 9750, 128317, - 0, 6656, 42618, 0, 5046, 8512, 65856, 74261, 8967, 0, 5045, 42026, 1916, - 7986, 5044, 120556, 9006, 13128, 5043, 0, 7853, 74068, 74004, 9669, - 12341, 12703, 8402, 0, 119070, 917600, 41750, 3586, 64508, 43148, 0, 0, - 119606, 67983, 13296, 517, 0, 128534, 194946, 41528, 123, 65454, 0, 0, - 74478, 10531, 7784, 41526, 10829, 73991, 8057, 1126, 73895, 0, 194591, 0, - 3925, 4251, 8069, 10517, 120439, 489, 0, 4250, 120441, 120452, 43151, - 983178, 194851, 66200, 0, 0, 0, 78423, 0, 0, 8711, 6183, 0, 0, 0, 120448, - 7623, 118925, 118889, 9235, 12760, 74176, 69662, 66445, 43540, 10062, - 3743, 11514, 11078, 0, 12136, 0, 126597, 120435, 0, 7726, 0, 19922, 267, - 3393, 42198, 1371, 194849, 69233, 2458, 0, 6201, 0, 41074, 4266, 10652, - 41612, 41077, 3402, 9050, 3398, 0, 983348, 0, 3391, 41075, 2476, 0, - 128017, 0, 10625, 0, 12767, 13017, 78743, 64261, 64934, 127537, 13014, - 13013, 0, 6673, 0, 0, 0, 12438, 0, 983342, 0, 983880, 126638, 9053, - 13015, 74523, 0, 704, 66215, 6195, 983828, 6660, 78758, 917760, 917793, - 42212, 12629, 11435, 0, 55256, 65538, 0, 127940, 983341, 74547, 126585, - 65448, 78100, 12948, 119001, 195002, 119238, 195004, 78099, 127085, 0, - 128320, 4287, 8276, 4902, 1131, 0, 78458, 66728, 1816, 0, 42533, 168, - 42845, 4898, 64298, 983141, 0, 4901, 1821, 0, 578, 3653, 0, 791, 9162, - 6977, 0, 78889, 74561, 0, 73731, 8354, 43590, 119303, 983449, 7557, - 119339, 119301, 8234, 7241, 0, 120671, 119167, 194996, 12811, 65925, - 3946, 78078, 10998, 78080, 673, 194867, 64397, 128276, 74599, 78449, - 8890, 194977, 194976, 2448, 78085, 10267, 8424, 2452, 78083, 128824, - 8729, 78456, 0, 7845, 917917, 71302, 4408, 4122, 6772, 11039, 8723, - 194990, 71310, 119302, 731, 119304, 92286, 2438, 64855, 119300, 119299, - 1175, 0, 42135, 373, 119172, 2119, 11457, 11521, 7723, 0, 0, 0, 41952, 0, - 5273, 2127, 5269, 6337, 5202, 2404, 5267, 42823, 11291, 19915, 5277, - 12963, 127864, 6189, 4125, 1314, 12133, 120340, 118873, 1271, 983640, 0, - 66024, 41482, 3864, 74539, 0, 3879, 0, 12978, 4166, 4574, 0, 7567, 7459, - 983160, 41390, 5384, 41882, 67647, 92548, 5759, 983912, 0, 41388, 64446, - 41392, 64288, 41387, 0, 8706, 5552, 983187, 700, 0, 5553, 0, 7088, 5356, - 7499, 68007, 66596, 74066, 0, 10263, 5554, 0, 12344, 10311, 78113, 6665, - 92626, 0, 7618, 8517, 11455, 78440, 64632, 64447, 5555, 78088, 78093, - 78091, 0, 42803, 65033, 9143, 6668, 195067, 67995, 195069, 656, 195071, - 65037, 4577, 64624, 0, 0, 0, 983649, 4269, 73885, 917775, 42846, 69644, - 950, 0, 92273, 66580, 118895, 66683, 10554, 917778, 119121, 0, 5098, - 917770, 0, 119099, 5097, 4935, 9848, 10381, 0, 128870, 983701, 3651, 0, - 120730, 127556, 5102, 5101, 10269, 12983, 8138, 4517, 1932, 5100, 1439, - 12093, 1247, 10034, 195064, 5099, 78373, 1441, 42087, 3063, 650, 0, 7838, - 0, 195041, 195040, 119142, 9031, 120790, 128582, 9078, 8545, 66356, - 128799, 0, 9154, 9118, 126543, 0, 2676, 2277, 0, 73812, 6190, 8599, - 195053, 69918, 10795, 9857, 7014, 9856, 195033, 92620, 12129, 0, 8481, 0, - 6202, 195035, 10920, 128237, 5203, 195039, 195038, 5108, 5107, 65818, - 66019, 9762, 0, 5541, 74772, 0, 12613, 5284, 6657, 207, 128806, 4275, - 74819, 854, 68147, 74381, 0, 78786, 5103, 127861, 64348, 41368, 43974, - 488, 69811, 0, 71339, 10157, 0, 43034, 11438, 64674, 0, 92694, 68431, - 41771, 5106, 6669, 8504, 65154, 69813, 41367, 5105, 127509, 69720, 6476, - 5104, 983749, 304, 3176, 119010, 0, 932, 120633, 6567, 238, 69656, - 195011, 194595, 19905, 120577, 195015, 78870, 41044, 67640, 194902, - 42055, 9912, 65939, 10670, 74093, 13273, 0, 12552, 195019, 8803, 309, - 6622, 8151, 10858, 78706, 67636, 0, 12568, 0, 12553, 10814, 43275, 6950, - 9712, 68680, 43970, 983198, 65165, 92725, 0, 66466, 0, 0, 0, 66725, 6191, - 11351, 10437, 11316, 67634, 43763, 0, 41754, 67635, 9370, 2720, 194975, - 68462, 8232, 118817, 0, 3222, 0, 0, 0, 66663, 0, 0, 10834, 0, 0, 65732, - 94095, 917547, 92682, 67679, 195020, 0, 7781, 41383, 64568, 0, 120738, - 12077, 0, 64586, 917620, 42396, 55255, 3475, 128035, 2479, 0, 3632, - 120728, 10698, 8376, 3648, 194960, 74844, 67639, 3636, 67894, 3650, 8837, - 65229, 1843, 42283, 43250, 41562, 9100, 74548, 917630, 3640, 127190, - 42321, 7284, 194974, 194973, 194950, 194949, 194952, 194951, 126649, - 194953, 42080, 2529, 0, 0, 0, 42083, 120678, 68398, 194957, 67619, 66367, - 194958, 9634, 92380, 9988, 0, 41068, 0, 4295, 65264, 68006, 0, 92545, 0, - 785, 8236, 128647, 9027, 68160, 67623, 64383, 120265, 925, 127156, 0, - 41985, 41071, 9586, 0, 41984, 9217, 0, 0, 0, 9186, 2067, 4016, 983803, 0, - 381, 12936, 0, 42077, 0, 69880, 5184, 42078, 194947, 10810, 128531, 4585, - 19943, 5860, 67633, 0, 0, 812, 3615, 0, 5178, 44000, 120548, 78807, 5188, - 74287, 67629, 3605, 10692, 1166, 64429, 42639, 924, 0, 67631, 42616, - 120670, 2442, 10703, 78789, 67632, 917924, 12771, 12736, 12753, 66708, - 73933, 67626, 42401, 0, 69872, 127373, 42288, 12751, 0, 8542, 13145, - 194963, 2468, 66706, 41294, 3626, 3883, 64388, 42479, 0, 41117, 0, 92580, - 0, 0, 67624, 0, 1290, 0, 65585, 2715, 806, 65208, 41884, 917883, 1318, - 64731, 126578, 0, 0, 66325, 3465, 2405, 9240, 0, 12756, 65259, 0, 983781, - 12752, 5833, 1432, 0, 41883, 73912, 9799, 0, 41886, 2480, 0, 2062, - 127293, 6494, 5537, 78656, 0, 194587, 0, 1211, 0, 0, 0, 118832, 12318, 0, - 0, 68005, 10622, 983779, 0, 78654, 6566, 78659, 0, 73780, 119196, 64864, - 0, 78660, 0, 8284, 13081, 0, 3589, 42051, 4035, 6492, 92236, 4265, 6642, - 3977, 74186, 41778, 836, 119216, 2488, 0, 4582, 0, 0, 41777, 12926, - 983377, 7528, 10550, 0, 92706, 0, 10961, 0, 1374, 64878, 119014, 0, - 42389, 41374, 2286, 0, 78492, 41377, 127909, 0, 400, 12597, 120586, 0, 0, - 6661, 983145, 64827, 0, 73817, 390, 0, 71301, 983862, 3473, 7718, 0, 0, - 0, 55285, 0, 0, 0, 11969, 983390, 127841, 6365, 1887, 6763, 983370, 8080, - 7006, 0, 983371, 6757, 64351, 1544, 0, 6766, 64677, 120716, 983372, 6146, - 0, 771, 983373, 0, 12812, 13168, 42272, 12200, 917927, 7904, 0, 953, - 12917, 119560, 12300, 0, 11491, 9724, 10341, 983773, 9524, 7490, 11389, - 7489, 3379, 0, 7487, 0, 471, 7484, 7482, 6753, 7480, 5764, 7478, 7477, - 6501, 7475, 6918, 7473, 7472, 2474, 7470, 7468, 10232, 10615, 10213, - 127288, 92357, 10049, 11834, 3544, 0, 6017, 65311, 127481, 120216, 13306, - 10533, 7870, 73949, 7625, 0, 120544, 0, 0, 92660, 0, 0, 0, 19961, 2472, - 42665, 92341, 0, 2139, 4256, 120776, 74380, 0, 42675, 42658, 12845, 0, 0, - 65138, 119355, 67862, 0, 65671, 7083, 120008, 8066, 7678, 74865, 0, 0, 0, - 0, 7186, 0, 120555, 0, 445, 120566, 128308, 0, 0, 8330, 0, 0, 42797, - 983150, 120215, 0, 3902, 0, 1770, 0, 128866, 1560, 120209, 194972, 4584, - 73843, 0, 11712, 10866, 118928, 1118, 71334, 0, 0, 1081, 7436, 68420, - 7252, 0, 5996, 69921, 4903, 0, 41386, 5162, 119189, 1330, 0, 7139, 0, - 12047, 41384, 0, 0, 1848, 4334, 6324, 41975, 64777, 10674, 12308, 12186, - 0, 0, 983741, 12715, 68002, 983479, 126630, 2018, 66672, 41979, 66685, - 119157, 68000, 92464, 0, 126984, 68001, 9334, 92705, 92315, 70101, 7975, - 0, 77957, 0, 66621, 4884, 66597, 69732, 0, 0, 6313, 65513, 69857, 0, 0, - 0, 2345, 43697, 463, 0, 0, 119607, 3117, 5460, 0, 0, 983387, 0, 42279, - 194577, 0, 78415, 0, 195008, 983384, 13248, 0, 0, 0, 0, 0, 0, 5663, 0, 0, - 0, 0, 2482, 1471, 0, 0, 42247, 12378, 73925, 69664, 0, 12374, 0, 0, 0, - 983694, 2460, 0, 11944, 12376, 127868, 64679, 0, 12380, 10557, 64473, - 5870, 0, 2024, 127180, 0, 0, 539, 0, 127765, 94052, 3853, 65180, 127923, - 120796, 120245, 92324, 0, 8659, 0, 12474, 92579, 9503, 194969, 2478, 0, - 4162, 0, 4260, 12953, 69633, 120089, 12470, 0, 74189, 2742, 12476, 11798, - 10946, 127310, 5000, 0, 983579, 0, 69672, 8213, 74017, 7771, 6161, 68018, - 6709, 0, 78885, 983708, 127971, 120582, 78547, 0, 10301, 10333, 10397, 0, - 0, 73791, 0, 0, 0, 0, 119123, 4014, 12842, 73952, 12015, 127290, 8275, - 3893, 983264, 0, 12210, 7221, 42147, 0, 74550, 74465, 64747, 118841, 0, - 12516, 4444, 0, 92271, 74537, 10892, 8231, 0, 6473, 41968, 78388, 41973, - 3591, 41969, 0, 2453, 128549, 92666, 64705, 0, 0, 10349, 10413, 43591, - 41962, 3202, 74353, 0, 8316, 0, 0, 94060, 687, 0, 0, 0, 1840, 0, 68671, - 119809, 4883, 285, 4723, 70099, 92692, 4459, 74577, 42921, 41720, 11089, - 240, 19906, 0, 42323, 0, 9743, 120232, 13134, 126535, 0, 0, 0, 0, 42634, - 983343, 43437, 3081, 11463, 120154, 0, 0, 10445, 0, 0, 66717, 2614, 9125, - 119023, 1729, 0, 120236, 65221, 63883, 43334, 64852, 0, 65194, 66201, 0, - 66578, 5001, 41879, 74427, 4121, 5003, 884, 66700, 63879, 4943, 5150, - 73889, 74182, 127915, 643, 3086, 0, 42448, 42299, 58, 0, 917952, 120083, - 63873, 8491, 0, 0, 983623, 4530, 42409, 7126, 194575, 2721, 120074, - 119096, 19929, 0, 194574, 0, 4242, 4264, 120077, 120530, 66179, 42412, - 65941, 13114, 64522, 10740, 3094, 0, 9754, 119102, 4437, 73948, 127074, - 983238, 55280, 42174, 194925, 42430, 0, 0, 42355, 66026, 4306, 41380, - 68432, 92586, 0, 66667, 127309, 0, 126521, 42200, 42566, 0, 0, 5088, - 6948, 0, 8524, 0, 0, 12385, 0, 0, 69646, 1386, 64580, 11480, 6116, 65039, - 65038, 12392, 65036, 8064, 0, 12101, 5822, 119004, 2080, 710, 77999, - 11663, 1666, 42091, 119657, 12383, 43671, 42092, 68418, 4289, 0, 63896, - 12061, 42096, 43621, 3362, 12377, 983832, 983834, 68449, 7461, 73901, - 1244, 331, 73786, 12683, 10662, 0, 8112, 0, 65852, 0, 12379, 194877, - 120818, 41964, 42208, 63843, 2084, 41965, 0, 65866, 4327, 0, 63840, - 78549, 41220, 13032, 0, 584, 12933, 43177, 12373, 69855, 13000, 1351, - 2935, 8698, 12665, 0, 1930, 0, 78229, 12427, 66514, 69859, 13031, 0, - 63901, 0, 3657, 128572, 65202, 6000, 119206, 12426, 127181, 0, 41740, - 12428, 41283, 41916, 119210, 0, 0, 12429, 6727, 0, 7562, 0, 5170, 0, - 41755, 676, 0, 66704, 66664, 9978, 66491, 3536, 0, 9752, 92397, 6162, 0, - 69228, 10113, 41829, 65886, 5159, 12422, 41832, 439, 43077, 0, 42207, - 74549, 11796, 40970, 41830, 0, 917799, 8308, 917797, 917796, 0, 67864, - 917801, 917800, 12336, 4135, 69805, 341, 2727, 4129, 3539, 0, 63861, 0, - 7913, 0, 63859, 4131, 63868, 0, 63867, 4133, 11371, 210, 4600, 0, 74560, - 4137, 8082, 78506, 119062, 78504, 6704, 4591, 128029, 0, 0, 9680, 0, - 120623, 561, 12159, 195, 78508, 41501, 0, 42031, 5719, 7172, 42687, 8368, - 0, 41499, 0, 0, 42242, 41498, 917794, 42025, 78565, 65805, 42463, 0, - 2924, 0, 120510, 0, 0, 119213, 73941, 0, 42330, 917784, 3969, 0, 0, 7169, - 1992, 9652, 73977, 7246, 42086, 126615, 2219, 0, 0, 128801, 194837, 0, - 327, 0, 9042, 917777, 917776, 65148, 12433, 917781, 127276, 917779, - 12431, 8668, 12434, 983835, 917782, 5999, 0, 7712, 12432, 128243, 43653, - 1726, 1015, 0, 8212, 0, 128014, 42423, 119066, 0, 128108, 66709, 0, 8811, - 927, 0, 0, 12436, 983245, 42021, 0, 0, 1299, 12240, 42350, 65143, 0, - 195016, 0, 78197, 11348, 0, 78037, 9194, 983184, 0, 19914, 12179, 983812, - 2296, 194923, 63836, 63832, 917773, 10967, 63816, 2594, 3444, 63817, - 64651, 0, 41503, 127478, 11265, 0, 120756, 194922, 0, 5664, 3972, 0, 0, - 0, 128508, 12416, 917764, 119608, 10816, 917769, 917768, 12418, 74111, - 3882, 8532, 917771, 1573, 128648, 119847, 4596, 66339, 12417, 66001, - 65343, 126491, 12414, 8287, 68219, 195017, 68108, 1143, 119169, 119846, - 12415, 6626, 42763, 0, 118884, 9021, 120783, 0, 11724, 0, 0, 127104, - 126619, 0, 0, 8027, 10997, 9171, 12741, 11400, 71305, 194799, 0, 128239, - 0, 128881, 119604, 127523, 120190, 194773, 67608, 128214, 42368, 0, 7715, - 3881, 41487, 12118, 42514, 68651, 0, 983895, 3009, 41476, 41489, 69825, - 3007, 1448, 3018, 194809, 3889, 8521, 5083, 5082, 119859, 120184, 8519, - 983241, 3014, 5081, 65853, 120715, 0, 68014, 69951, 5079, 64802, 42210, - 4597, 65532, 11828, 120185, 12371, 0, 8407, 0, 10805, 8518, 10779, - 120188, 71303, 983933, 12367, 42170, 0, 92557, 629, 1924, 0, 12037, - 74366, 5987, 8462, 8005, 12365, 63933, 69735, 120815, 12369, 10649, - 67981, 5077, 120174, 10880, 63927, 5075, 917881, 0, 65075, 0, 11007, - 983705, 66659, 92607, 0, 66684, 0, 3434, 4954, 1904, 0, 5266, 126980, - 5272, 10499, 4507, 9578, 63923, 120177, 7979, 0, 9831, 0, 194926, 461, - 9803, 0, 4504, 1505, 0, 6325, 5276, 43021, 120488, 0, 55236, 0, 66461, - 5177, 41324, 12055, 8722, 0, 41327, 0, 66695, 4114, 409, 4383, 8900, - 8948, 41325, 0, 721, 10182, 9108, 71311, 0, 119185, 42229, 194912, 0, - 5998, 0, 42353, 74825, 0, 12587, 94104, 78571, 0, 71328, 194562, 41576, - 42215, 78570, 119207, 0, 8578, 5995, 7573, 41575, 74789, 74752, 63944, - 63949, 64767, 2670, 4167, 194796, 11723, 0, 74120, 0, 65076, 938, 43414, - 73854, 11737, 9721, 0, 0, 0, 11742, 2419, 0, 11493, 12334, 194913, 4153, - 12302, 10793, 5250, 12407, 11978, 4404, 9189, 12401, 42007, 5775, 6759, - 65806, 43997, 0, 42002, 12404, 983553, 0, 4940, 12410, 7683, 1167, 73729, - 4983, 120507, 861, 0, 0, 0, 0, 43757, 43370, 0, 0, 11956, 0, 0, 0, 9616, - 6631, 0, 12816, 43759, 42218, 12710, 68674, 12721, 4101, 66185, 0, 5992, - 7616, 195044, 0, 12577, 0, 983884, 853, 42693, 195014, 0, 983647, 5016, - 43535, 63893, 42835, 9491, 917913, 0, 917914, 0, 12712, 7105, 127807, - 65060, 120797, 9900, 7750, 0, 194919, 0, 127830, 0, 64778, 12585, 10565, - 128151, 12177, 0, 0, 0, 77824, 0, 4900, 127874, 12878, 92630, 8984, 4119, - 74768, 8971, 78593, 43113, 9702, 78594, 11025, 9245, 13048, 4927, 4138, - 74185, 92481, 92710, 12397, 77827, 0, 13054, 12394, 0, 0, 0, 13053, 0, - 3948, 10781, 1546, 0, 5010, 1680, 10507, 78590, 78583, 0, 0, 0, 194915, - 7267, 0, 74833, 128181, 5993, 2819, 0, 12706, 77840, 1893, 7266, 63915, - 7264, 7265, 0, 1363, 0, 63997, 63910, 63996, 3077, 0, 0, 1512, 69929, - 12589, 41479, 128313, 0, 43339, 73776, 9836, 120727, 0, 41481, 43335, - 7832, 42343, 3090, 43337, 817, 1664, 1850, 128841, 3079, 11340, 42408, - 42447, 127140, 120020, 42307, 12386, 42304, 917555, 0, 12389, 0, 92366, - 41996, 11526, 63985, 5864, 1147, 63992, 42887, 1987, 92718, 5480, 7858, - 11653, 4116, 12391, 66193, 0, 4939, 12384, 0, 0, 41686, 63905, 119601, - 194688, 983190, 0, 12649, 0, 0, 8247, 507, 91, 2042, 120775, 43643, - 194689, 66028, 10036, 41844, 119813, 774, 119829, 0, 119815, 5994, 12539, - 0, 78375, 120597, 119833, 983105, 119600, 0, 0, 7719, 6026, 2486, 128312, - 119808, 162, 0, 65219, 41073, 9687, 41681, 6304, 119812, 66196, 194881, - 5262, 0, 55233, 12681, 42379, 0, 7534, 12219, 0, 127528, 42810, 10492, 0, - 983661, 0, 43119, 0, 120753, 12403, 2500, 195013, 0, 4899, 12729, 0, 0, - 74113, 2343, 4103, 19946, 74112, 77851, 13112, 0, 195012, 12859, 70087, - 120148, 66369, 5861, 127758, 11999, 12400, 0, 983839, 12645, 5146, 11320, - 68410, 6748, 65040, 0, 64184, 12974, 64183, 67613, 120645, 5147, 0, 0, - 74524, 0, 1928, 0, 67649, 5991, 3445, 67609, 4976, 64176, 0, 67610, 8241, - 0, 77868, 4206, 0, 0, 0, 128298, 0, 10138, 0, 0, 8897, 120234, 0, 8357, - 4124, 77862, 65836, 120641, 127926, 77859, 0, 0, 1123, 963, 41553, 10120, - 12405, 120150, 92664, 398, 13278, 9723, 6366, 120311, 7945, 0, 4402, - 9970, 12402, 983136, 42392, 1305, 12408, 0, 44007, 0, 0, 41464, 12411, - 12969, 120824, 41465, 983565, 8528, 1575, 0, 63955, 165, 3024, 41467, - 119163, 0, 9093, 0, 9147, 128787, 63958, 0, 9148, 9692, 4096, 53, 8296, - 6750, 195018, 0, 9594, 0, 0, 43527, 0, 727, 194703, 195023, 5805, 0, - 6726, 0, 42176, 12370, 11655, 119095, 10591, 2280, 0, 12372, 120642, - 120307, 0, 92343, 0, 12366, 10963, 6066, 1329, 0, 3052, 9220, 0, 64478, - 194701, 10803, 4132, 120306, 68474, 92473, 0, 983313, 74837, 120155, - 1499, 0, 8055, 42740, 63965, 0, 63962, 74042, 8924, 43123, 5988, 3660, - 63969, 11781, 42718, 8788, 1357, 64851, 65743, 0, 8774, 0, 127086, 9941, - 120172, 0, 1933, 69655, 9564, 0, 92435, 73866, 0, 0, 2487, 67614, 3121, - 1804, 3311, 67615, 70081, 78302, 12220, 67616, 120598, 127475, 0, 68200, - 6675, 128144, 0, 67592, 120685, 0, 64771, 1198, 9132, 0, 64619, 510, - 64663, 0, 0, 4561, 2101, 1398, 0, 92554, 74034, 41569, 92684, 11406, - 8167, 12127, 0, 840, 0, 126518, 7101, 6967, 0, 194898, 9796, 0, 333, - 69891, 0, 8144, 2117, 0, 983595, 12406, 0, 19931, 119089, 6678, 7769, 0, - 12621, 0, 127366, 10227, 4764, 43101, 9981, 0, 40986, 4127, 66487, 0, - 42202, 12754, 195022, 0, 0, 94097, 67594, 2048, 12944, 4050, 67595, - 917967, 43102, 10581, 12985, 4533, 195021, 74003, 6490, 0, 12038, 0, 0, - 120704, 65461, 9798, 69704, 0, 1948, 69841, 0, 952, 128235, 0, 0, 120802, - 6449, 9494, 120313, 0, 43098, 4843, 8142, 64160, 4098, 64170, 0, 0, 3436, - 119973, 0, 12817, 67597, 6676, 3930, 42615, 0, 0, 67598, 0, 0, 0, 65591, - 41581, 65916, 1453, 0, 0, 0, 8500, 42222, 120142, 73743, 120400, 4317, - 11543, 67676, 64676, 0, 0, 67606, 119083, 0, 42217, 13102, 0, 66003, - 6672, 0, 0, 0, 983747, 63841, 9613, 9001, 4526, 11274, 67601, 64520, - 64210, 6664, 78704, 42056, 10228, 64957, 11281, 0, 3807, 1469, 66640, - 65381, 42197, 4988, 42372, 0, 9598, 904, 352, 42225, 1451, 8061, 8453, - 4134, 0, 74847, 66576, 127916, 0, 10520, 8575, 9960, 1201, 127289, 12846, - 127291, 127292, 11919, 64962, 127287, 43739, 127281, 8511, 9460, 823, - 11587, 12305, 0, 64695, 127305, 12387, 1253, 13183, 65766, 500, 42783, - 65765, 64208, 64369, 65760, 65761, 119585, 11606, 64784, 11702, 66498, - 9821, 64304, 0, 5152, 11048, 7533, 68366, 64410, 92305, 0, 4323, 120062, - 92669, 71332, 127052, 42587, 42214, 41394, 0, 4763, 4112, 118935, 0, - 5260, 43143, 94038, 326, 120131, 68423, 0, 10771, 2876, 74074, 92530, - 194924, 41398, 7382, 9802, 127077, 127076, 453, 41396, 120524, 42720, - 12140, 9572, 0, 7003, 194883, 42334, 7704, 126490, 194885, 43144, 4123, - 8494, 43146, 9977, 0, 0, 65759, 10765, 64061, 4465, 9808, 64056, 65582, - 4126, 0, 9521, 9589, 64755, 0, 64020, 126604, 10464, 0, 0, 194869, 64514, - 11528, 64024, 128072, 679, 64013, 0, 5850, 758, 7536, 0, 92234, 41441, - 10693, 64006, 983567, 64005, 4058, 119019, 126487, 64660, 0, 119050, 0, - 983069, 1139, 43298, 64027, 64029, 8970, 0, 9934, 983094, 10774, 128020, - 42201, 12421, 128216, 0, 1852, 3057, 64046, 73744, 64034, 64039, 0, 0, 0, - 194899, 92322, 7645, 12854, 74338, 3496, 0, 0, 0, 9102, 627, 127795, - 6158, 8327, 74553, 66632, 12419, 13309, 11570, 127811, 19960, 11696, 0, - 1018, 118970, 194909, 194897, 1682, 194896, 194911, 42756, 6765, 194906, - 0, 0, 73814, 11412, 6768, 10728, 194830, 71316, 118863, 43311, 64966, - 11577, 0, 43040, 1833, 11576, 0, 74779, 0, 185, 65085, 74533, 64754, - 194848, 7535, 8085, 42525, 120387, 9749, 41701, 6131, 1949, 4117, 7847, - 120489, 194711, 64483, 65693, 0, 0, 0, 69695, 42240, 0, 126651, 42864, - 126498, 64667, 41868, 1184, 0, 815, 11484, 127535, 67840, 983651, 0, - 66197, 0, 10986, 64683, 983785, 0, 3455, 0, 0, 9879, 0, 0, 4158, 128050, + 64128, 66286, 93042, 128830, 64132, 10867, 64130, 64129, 983844, 43374, + 9779, 2764, 66002, 10167, 9471, 0, 66021, 74509, 0, 5457, 5440, 8857, + 93981, 65282, 2843, 5355, 127928, 983965, 69971, 5194, 11657, 43984, + 128292, 113724, 128872, 0, 0, 72393, 10717, 64570, 5630, 5396, 64143, + 10682, 0, 10602, 800, 42499, 66186, 0, 0, 64930, 11631, 64146, 64145, + 64144, 762, 13172, 118859, 194661, 64468, 10906, 1353, 6960, 0, 128779, + 5828, 8724, 917806, 8933, 1601, 42244, 858, 7080, 64109, 64108, 8090, + 70455, 72388, 74606, 587, 0, 128131, 0, 0, 0, 78214, 2750, 74218, 556, + 64158, 64157, 78707, 12213, 194678, 2760, 0, 0, 78708, 194794, 64156, + 64155, 42496, 0, 64151, 64150, 12679, 10053, 10421, 11093, 64153, 64152, + 125016, 0, 4839, 68527, 0, 1874, 119016, 120091, 6577, 64125, 64124, + 64123, 0, 127531, 92534, 7007, 7590, 65443, 9036, 78847, 64122, 66389, + 66609, 0, 64117, 64116, 6287, 64114, 2725, 64120, 64119, 43981, 42128, + 127842, 1177, 65601, 12322, 64106, 69640, 92895, 64102, 7859, 1945, + 64099, 0, 10453, 64104, 7188, 7997, 0, 7389, 983161, 8705, 64097, 64096, + 9571, 528, 128671, 44017, 11429, 71347, 0, 983077, 917990, 73841, 0, 0, + 9056, 64313, 6188, 120019, 6155, 64068, 1823, 64066, 64065, 64072, 64071, + 63, 7233, 92212, 72414, 41904, 6639, 64064, 983775, 128344, 0, 1176, + 118959, 127930, 8162, 127019, 983831, 92747, 120519, 66376, 66242, 11415, + 4333, 9855, 64112, 64642, 0, 5388, 0, 0, 0, 7714, 66222, 69902, 7768, + 72403, 4199, 64708, 65064, 70117, 0, 8708, 9560, 64077, 64076, 8996, + 4992, 4471, 42622, 64079, 64078, 92179, 71878, 126570, 129120, 64615, + 41915, 0, 12075, 42041, 194825, 5174, 983217, 0, 127557, 3123, 0, 12685, + 119216, 8408, 64704, 0, 0, 9223, 0, 41616, 67999, 73797, 0, 1116, 128204, + 43049, 7136, 43050, 8548, 120485, 0, 119061, 917999, 0, 13115, 43675, + 64091, 9322, 0, 120595, 64095, 64094, 8111, 66247, 42332, 64089, 64088, + 6199, 67249, 66398, 11434, 64083, 64082, 11329, 7737, 64087, 64086, + 64085, 64084, 194703, 9927, 41335, 4118, 1797, 0, 41334, 0, 46, 43448, + 127881, 298, 0, 128114, 0, 42627, 125011, 32, 6187, 119052, 11495, 11459, + 3665, 983600, 42871, 0, 19923, 74335, 0, 127192, 66239, 42264, 64403, + 4412, 7240, 92495, 917900, 983466, 65758, 12750, 4181, 8544, 119849, + 120199, 917897, 120198, 69809, 6181, 65014, 983420, 0, 983196, 3639, + 119588, 118851, 0, 118904, 10073, 120206, 128862, 127186, 68409, 42844, + 7498, 1098, 92565, 120205, 0, 128915, 10207, 8789, 93070, 0, 92973, + 128325, 9234, 0, 6182, 983473, 65058, 0, 983478, 194973, 0, 5471, 9461, + 5573, 118936, 5473, 44, 0, 66244, 94072, 0, 66238, 12844, 66894, 1622, + 7767, 1900, 41339, 11458, 0, 0, 6581, 5576, 983495, 43855, 41337, 0, + 41631, 8947, 68390, 69683, 41694, 0, 72396, 7908, 0, 10408, 6579, 0, + 64618, 0, 120147, 2138, 6583, 7761, 70005, 120504, 194828, 0, 5058, + 41010, 9992, 128299, 5057, 917941, 0, 74538, 5054, 118951, 194971, 78606, + 0, 1437, 41617, 658, 3497, 128509, 7486, 5061, 5060, 4235, 127878, 0, + 128529, 12113, 4236, 4727, 128487, 0, 7693, 10749, 120332, 7488, 5773, + 978, 128134, 0, 41619, 10239, 68611, 71864, 66209, 983423, 74135, 9748, + 983956, 127524, 0, 0, 0, 0, 195083, 0, 983843, 983300, 0, 0, 0, 92776, + 9341, 78821, 2379, 11325, 983951, 64668, 67854, 8125, 120545, 6743, + 119175, 917940, 2369, 0, 983972, 127966, 119235, 71868, 73936, 7008, + 43660, 0, 0, 43841, 2367, 127827, 983857, 264, 2375, 8060, 6194, 119858, + 1844, 119084, 129049, 6019, 0, 0, 6961, 0, 70435, 67171, 8800, 0, 42862, + 4463, 65581, 6192, 127900, 42771, 0, 92333, 725, 65042, 93014, 120800, + 983040, 12892, 0, 67149, 0, 0, 0, 0, 127261, 12224, 983128, 129061, 5074, + 5073, 128790, 8983, 118981, 74493, 71231, 5072, 74547, 6198, 11614, 0, + 196, 0, 0, 0, 4929, 120342, 0, 0, 127987, 0, 42847, 119856, 0, 67754, + 4934, 0, 41323, 9758, 0, 92289, 70181, 42584, 0, 4329, 41321, 4979, 3048, + 7752, 41320, 983042, 64667, 12819, 983870, 5071, 127915, 3642, 67334, + 5070, 10042, 113813, 3987, 5068, 0, 8909, 78650, 78649, 69917, 10636, + 73981, 11806, 43167, 4531, 1245, 9105, 66463, 4921, 120219, 4926, 65544, + 73884, 194619, 0, 0, 64709, 0, 194620, 78880, 4922, 325, 992, 119568, + 4925, 127218, 0, 9526, 4920, 128617, 948, 0, 120208, 4930, 983225, 92175, + 120275, 4933, 113779, 0, 118985, 4928, 0, 0, 74770, 120194, 126548, 722, + 194934, 19908, 12637, 127485, 119855, 8753, 1509, 0, 5468, 9511, 43493, + 127477, 1672, 6205, 10864, 74586, 127480, 70103, 92694, 78555, 127468, + 73863, 126577, 68336, 41607, 120115, 1679, 120116, 120180, 92761, 127462, + 7005, 41609, 9580, 70431, 401, 69949, 43779, 6968, 5761, 342, 8553, 0, + 8143, 127115, 11983, 92249, 624, 74508, 4057, 43788, 5078, 74258, 12478, + 0, 5076, 0, 194609, 0, 8295, 685, 9025, 1524, 12618, 0, 5539, 129182, + 92523, 120101, 7138, 120552, 43504, 194611, 66914, 65794, 12520, 8058, + 9732, 92480, 5080, 64775, 5036, 5035, 120590, 42604, 983656, 0, 8074, + 275, 13291, 1907, 78838, 4432, 127271, 5033, 127273, 120818, 4836, 3888, + 73792, 10729, 64546, 127262, 43704, 127264, 92957, 67588, 119000, 124983, + 70360, 8858, 6409, 7663, 120252, 128100, 119007, 0, 66321, 94052, 12814, + 127248, 3432, 10218, 0, 6094, 7641, 42445, 128792, 92487, 42406, 1676, + 67362, 74862, 67365, 5030, 67364, 118810, 195008, 73869, 9622, 113763, + 69944, 6787, 67361, 0, 0, 68319, 10544, 12919, 73812, 72397, 0, 0, 69906, + 120789, 983041, 947, 67695, 67367, 194585, 10969, 67228, 7613, 92562, + 119936, 4795, 119930, 7018, 7376, 120181, 120192, 120268, 0, 43567, + 74056, 917910, 11833, 119919, 7216, 65232, 7217, 251, 7218, 7895, 4395, + 43538, 119926, 119929, 119928, 7213, 68476, 7214, 7215, 5879, 74141, + 8880, 7685, 66459, 120173, 65540, 67359, 625, 8187, 42861, 1113, 7236, + 7915, 3630, 120176, 8179, 70163, 67886, 9316, 10980, 2489, 65624, 8150, + 1359, 67652, 70464, 127330, 73756, 5042, 5041, 42769, 12084, 127324, + 127321, 74410, 127319, 127320, 127317, 127318, 127315, 12283, 1616, 3795, + 67732, 8795, 66245, 0, 0, 0, 1138, 73905, 12677, 0, 67724, 3239, 66893, + 0, 0, 8431, 0, 42164, 71229, 11778, 12620, 6826, 73773, 70169, 5040, 0, + 0, 67094, 78420, 0, 5039, 983678, 78418, 0, 5038, 0, 0, 13184, 74293, 0, + 64648, 0, 9359, 78416, 917623, 128770, 65157, 6662, 0, 70182, 3863, + 73909, 4835, 55266, 43432, 127822, 4309, 7127, 194569, 0, 194568, 1301, + 0, 42589, 569, 128804, 73813, 711, 4389, 7133, 120643, 73880, 11610, + 11368, 0, 194570, 41331, 1006, 74240, 67224, 1550, 8201, 70453, 7627, + 5499, 5031, 77908, 42738, 65784, 77907, 65267, 3758, 0, 65781, 64734, + 67222, 2440, 65780, 70787, 8449, 0, 5008, 983572, 2118, 126508, 12121, + 8255, 5512, 73875, 2128, 2130, 2131, 2126, 2133, 1119, 127067, 2114, + 2116, 2455, 113798, 2122, 2123, 2124, 2125, 127486, 8714, 983820, 2113, + 917985, 2115, 128177, 127907, 43713, 5052, 66220, 5821, 6186, 65778, + 65775, 5051, 65773, 1429, 42647, 5050, 302, 388, 41115, 735, 6637, 5907, + 65088, 0, 12726, 74594, 9117, 983181, 12003, 5513, 6666, 5053, 74230, + 5510, 78451, 0, 78447, 2470, 78437, 0, 1925, 71251, 92237, 74807, 0, + 5048, 5047, 0, 0, 74201, 92313, 0, 74497, 92395, 8089, 6929, 639, 983563, + 68179, 64442, 70180, 92348, 4599, 41402, 6674, 43397, 43294, 1476, 648, + 0, 65819, 3233, 0, 41782, 6951, 94017, 983976, 3530, 9750, 128317, + 128122, 6656, 42618, 70175, 5046, 8512, 65856, 74261, 8967, 0, 5045, + 42026, 1916, 7986, 5044, 120556, 9006, 13128, 5043, 0, 7853, 74068, + 74004, 9669, 12341, 12703, 8402, 0, 119070, 70174, 41750, 3586, 64508, + 43148, 0, 127971, 119606, 67983, 13296, 517, 0, 128534, 194946, 41528, + 123, 65454, 0, 194856, 74478, 10531, 7784, 41526, 10829, 73991, 8057, + 1126, 73895, 194857, 194591, 0, 3925, 4251, 8069, 10517, 71112, 489, + 71110, 4250, 120441, 120452, 43151, 983178, 92738, 66200, 0, 0, 125026, + 74298, 128879, 983474, 8711, 6183, 0, 983952, 72402, 120448, 7623, + 118925, 118889, 9235, 12760, 74176, 69662, 66445, 43540, 10062, 3743, + 11514, 11078, 0, 12136, 0, 126597, 120435, 194850, 7726, 195095, 19922, + 267, 3393, 42198, 1371, 194849, 69233, 2458, 0, 6201, 0, 41074, 4266, + 10652, 41612, 41077, 3402, 9050, 3398, 917796, 983348, 0, 3391, 41075, + 2476, 0, 128017, 0, 10625, 129106, 12767, 13017, 78743, 64261, 64934, + 70152, 13014, 13013, 0, 6673, 0, 0, 0, 12438, 0, 983342, 0, 983880, + 126638, 9053, 13015, 74523, 0, 704, 66215, 6195, 983828, 6660, 78758, + 917760, 74861, 42212, 12629, 11435, 0, 55256, 65538, 67343, 127940, + 129086, 43876, 126585, 65448, 78100, 12948, 119001, 195002, 119238, + 195004, 78099, 127085, 0, 128320, 4287, 8276, 4902, 1131, 983606, 78458, + 66728, 1816, 0, 42533, 168, 42845, 4898, 64298, 195012, 78105, 4901, + 1821, 0, 578, 3653, 128946, 791, 9162, 6977, 74196, 78889, 70160, 0, + 73731, 8354, 43590, 119303, 983449, 7557, 119108, 67378, 8234, 7241, + 983448, 113735, 119167, 194996, 12811, 65925, 3946, 78078, 10998, 78080, + 673, 194867, 64397, 128276, 74599, 78449, 8890, 194977, 194976, 2448, + 78085, 10267, 8424, 2452, 78083, 67217, 8729, 78456, 0, 7845, 126564, + 71302, 4408, 4122, 6772, 11039, 8723, 65896, 71310, 119302, 731, 119304, + 71904, 2438, 64855, 119300, 119299, 1175, 0, 42135, 373, 119172, 2119, + 11457, 11521, 7723, 128639, 0, 0, 41952, 93023, 5273, 2127, 5269, 6337, + 5202, 2404, 5267, 42823, 11291, 19915, 5277, 12963, 70320, 6189, 4125, + 1314, 12133, 120340, 118873, 1271, 983640, 0, 66024, 41482, 3864, 9204, + 0, 3879, 0, 12978, 4166, 4574, 0, 7567, 7459, 78128, 41390, 5384, 41882, + 67647, 70154, 5759, 983912, 0, 41388, 64446, 41392, 64288, 41387, 67201, + 8706, 5552, 983187, 700, 0, 5553, 0, 7088, 5356, 7499, 68007, 66596, + 74066, 67251, 10263, 5554, 0, 12344, 10311, 78113, 6665, 11115, 0, 7618, + 8517, 11455, 78440, 64632, 64447, 5555, 78088, 78093, 78091, 0, 42803, + 65033, 9143, 6668, 67288, 67995, 195069, 656, 195071, 65037, 4577, 64624, + 0, 0, 71912, 983649, 4269, 73885, 917775, 42846, 69644, 950, 0, 92273, + 66580, 118895, 66683, 10554, 119008, 119121, 6832, 5098, 917768, 194668, + 70403, 5097, 4935, 9848, 10381, 0, 67296, 92896, 3651, 0, 67294, 70848, + 5102, 5101, 10269, 12983, 8138, 4517, 1932, 5100, 1439, 12093, 1247, + 10034, 195064, 5099, 78373, 1441, 42087, 3063, 650, 119953, 7838, 0, + 128655, 195040, 119142, 9031, 70829, 78427, 9078, 8545, 66356, 128799, + 194923, 9154, 9118, 126543, 0, 2676, 2277, 128422, 68237, 6190, 8599, + 125118, 69918, 10795, 9857, 7014, 9856, 195033, 71903, 12129, 0, 8481, 0, + 6202, 67711, 10920, 113726, 5203, 195039, 195038, 5108, 5107, 65818, + 66019, 9762, 11205, 5541, 74772, 0, 12613, 5284, 6657, 207, 128806, 4275, + 74819, 854, 68147, 74381, 66816, 78786, 5103, 127861, 64348, 41368, + 43974, 488, 69811, 0, 71339, 10157, 194737, 43034, 11438, 64674, 0, + 70158, 68431, 41771, 5106, 6669, 8504, 65154, 69813, 41367, 5105, 127509, + 69720, 6476, 5104, 983749, 304, 3176, 78871, 70149, 932, 113683, 6567, + 238, 69656, 78432, 194595, 19905, 43850, 195015, 78870, 41044, 67640, + 67302, 42055, 9912, 65939, 10670, 74093, 13273, 0, 12552, 93039, 8803, + 309, 6622, 8151, 10858, 78706, 67636, 70171, 12568, 0, 12553, 10814, + 43275, 6950, 9712, 68680, 43970, 126535, 65165, 92725, 0, 66466, 124986, + 0, 0, 66725, 6191, 11351, 10437, 11316, 67634, 43763, 0, 41754, 67635, + 9370, 2720, 194600, 68462, 8232, 118817, 0, 3222, 0, 0, 0, 66663, 983047, + 93067, 10834, 983127, 0, 65732, 94095, 917547, 92682, 67679, 129150, + 67309, 7781, 41383, 64568, 67311, 120738, 12077, 74433, 64586, 917620, + 42396, 55255, 3475, 67260, 2479, 67306, 3632, 120728, 10698, 8376, 3648, + 67263, 74844, 67639, 3636, 67894, 3650, 8837, 65229, 1843, 42283, 43250, + 41562, 9100, 74548, 917630, 3640, 127190, 42321, 7284, 92880, 118987, + 194950, 194949, 74115, 194951, 126649, 194953, 42080, 2529, 0, 983784, 0, + 42083, 120678, 68398, 194957, 67619, 66367, 194958, 9634, 92380, 9988, 0, + 41068, 0, 4295, 65264, 68006, 0, 92545, 0, 785, 8236, 128647, 9027, + 68160, 67623, 64383, 120265, 925, 127156, 0, 41985, 41071, 9586, 194908, + 41984, 9217, 128372, 92510, 92218, 9186, 2067, 4016, 983803, 0, 381, + 12936, 0, 42077, 92985, 69880, 5184, 42078, 194607, 10810, 128531, 4585, + 19943, 5860, 67633, 0, 983279, 812, 3615, 72401, 5178, 44000, 120548, + 78807, 5188, 74287, 67629, 3605, 10692, 1166, 64429, 42639, 924, 0, + 67631, 42616, 120670, 2442, 10703, 67317, 67632, 67316, 12771, 12736, + 12753, 66708, 73933, 67626, 42401, 0, 69872, 127373, 42288, 12751, + 983064, 8542, 13145, 194963, 2468, 66706, 41294, 3626, 3883, 64388, + 42479, 71220, 41117, 0, 92580, 0, 0, 67624, 0, 1290, 0, 65585, 2715, 806, + 65208, 41884, 917883, 1318, 64731, 126578, 0, 0, 66325, 3465, 2405, 9240, + 983858, 12756, 65259, 0, 983781, 12752, 5833, 1432, 66396, 41883, 73912, + 9799, 0, 41886, 2480, 0, 2062, 67326, 6494, 5537, 78656, 0, 194587, + 124969, 1211, 0, 0, 67269, 118832, 12318, 129024, 113796, 68005, 10622, + 983779, 0, 78654, 6566, 71195, 0, 73780, 119196, 64864, 0, 78660, 0, + 8284, 13081, 119206, 3589, 42051, 4035, 6492, 92236, 4265, 6642, 3977, + 74186, 41778, 836, 92947, 2488, 129176, 4582, 0, 0, 41777, 12926, 983377, + 7528, 10550, 113761, 92706, 0, 10961, 93977, 1374, 64878, 119014, 67720, + 42389, 41374, 2286, 917604, 78492, 41377, 127909, 0, 400, 12597, 120586, + 0, 0, 6661, 983145, 64827, 0, 73817, 390, 0, 71301, 983862, 3473, 7718, + 113755, 127011, 0, 55285, 73784, 66394, 0, 11969, 120461, 127841, 6365, + 1887, 6763, 92551, 8080, 7006, 0, 118902, 6757, 64351, 1544, 67156, 6766, + 64677, 120716, 67088, 6146, 74031, 771, 120682, 0, 12812, 13168, 42272, + 12200, 66423, 7904, 0, 953, 12917, 119560, 12300, 67089, 11491, 9724, + 10341, 983773, 9524, 7490, 11389, 7489, 3379, 0, 7487, 194624, 471, 7484, + 7482, 6753, 7480, 5764, 7478, 7477, 6501, 7475, 6918, 7473, 7472, 2474, + 7470, 7468, 10232, 10615, 10213, 127288, 92357, 10049, 11834, 3544, 0, + 6017, 65311, 127481, 120216, 13306, 10533, 7870, 73949, 7625, 194882, + 120544, 0, 127950, 92660, 0, 77889, 0, 19961, 2472, 42665, 92341, 0, + 2139, 4256, 120776, 74380, 43836, 42675, 42658, 12845, 70345, 70508, + 65138, 119355, 67862, 0, 65671, 7083, 120008, 8066, 7678, 74865, 125134, + 120321, 0, 983394, 7186, 0, 120555, 0, 445, 120566, 66849, 983477, 0, + 8330, 0, 0, 42797, 113736, 120215, 93036, 3902, 0, 1770, 67091, 125067, + 1560, 120209, 194972, 4584, 73843, 0, 11712, 10866, 67092, 1118, 71334, + 0, 0, 1081, 7436, 11147, 7252, 70093, 5996, 69921, 4903, 68142, 41386, + 5162, 119189, 1330, 128613, 7139, 0, 12047, 41384, 0, 0, 1848, 4334, + 6324, 41975, 64777, 10674, 12308, 12186, 0, 0, 983741, 12715, 68002, + 983479, 126630, 2018, 66672, 41979, 66685, 119157, 68000, 78490, 0, + 126984, 68001, 9334, 92705, 70800, 70101, 7975, 0, 77957, 0, 43494, 4884, + 66597, 69732, 0, 0, 6313, 65513, 69857, 0, 0, 0, 2345, 43697, 463, 0, 0, + 68178, 3117, 5460, 0, 128717, 983387, 0, 42279, 194577, 0, 78415, 983228, + 68524, 983384, 13248, 125027, 0, 128471, 128415, 983153, 0, 5663, 127942, + 128472, 0, 0, 2482, 1471, 194583, 113747, 42247, 12378, 73925, 69664, 0, + 12374, 0, 195023, 0, 118828, 2460, 71882, 11944, 12376, 127868, 64679, + 92893, 12380, 10557, 64473, 5870, 11122, 2024, 127180, 0, 71879, 539, 0, + 127765, 70120, 3853, 65180, 127923, 120796, 120245, 92324, 0, 8659, 0, + 12474, 67241, 9503, 194969, 2478, 120248, 4162, 0, 4260, 12953, 69633, + 120089, 12470, 92640, 74189, 2742, 12476, 11798, 10946, 127310, 5000, + 113687, 983579, 128777, 69672, 8213, 43824, 7771, 6161, 68018, 6709, + 194967, 78885, 119243, 68235, 120582, 78547, 113709, 10301, 10333, 10397, + 124934, 0, 73791, 0, 0, 0, 0, 119123, 4014, 12842, 73952, 12015, 127290, + 8275, 3893, 983264, 0, 12210, 7221, 42147, 74868, 74550, 71215, 64747, + 118841, 0, 12516, 4444, 0, 92271, 74537, 10892, 8231, 0, 6473, 41968, + 78388, 41973, 3591, 41969, 0, 2453, 128549, 92666, 64705, 71068, 0, + 10349, 10413, 43591, 41962, 3202, 74353, 129175, 8316, 129174, 0, 94060, + 687, 125089, 129074, 0, 1840, 0, 68671, 11121, 4883, 285, 4723, 11175, + 92692, 4459, 74577, 42921, 41720, 11089, 240, 19906, 0, 42323, 74640, + 9743, 120232, 13134, 93065, 128956, 65931, 92579, 128329, 42634, 983343, + 43437, 3081, 11463, 120154, 0, 195013, 10445, 0, 92969, 66717, 2614, + 9125, 119023, 1729, 0, 72420, 65221, 63883, 43334, 64852, 124929, 65194, + 66201, 0, 66578, 5001, 41879, 74427, 4121, 5003, 884, 66700, 63879, 4943, + 5150, 73889, 73764, 4039, 643, 3086, 92961, 42448, 42299, 58, 0, 917952, + 120083, 63873, 8491, 0, 0, 983623, 4530, 42409, 7126, 194575, 2721, + 120073, 119096, 19929, 0, 194574, 92975, 4242, 4264, 120077, 120530, + 66179, 42412, 65941, 13114, 64522, 10740, 3094, 983199, 9754, 119102, + 4437, 73948, 127074, 983238, 55280, 42174, 194925, 42430, 0, 983450, + 42355, 66026, 4306, 41380, 68432, 92586, 68314, 66667, 119351, 0, 126521, + 42200, 42566, 70000, 128928, 5088, 6948, 0, 8524, 125040, 0, 12385, 0, 0, + 69646, 1386, 64580, 11480, 6116, 65039, 65038, 12392, 65036, 8064, 0, + 12101, 5822, 119004, 2080, 710, 77999, 11663, 1666, 42091, 119657, 12383, + 43671, 42092, 68418, 4289, 127897, 63896, 12061, 42096, 43621, 3362, + 12377, 119934, 983834, 68449, 7461, 73901, 1244, 331, 73786, 12683, + 10662, 0, 8112, 0, 65852, 74629, 12379, 194877, 92930, 41964, 42208, + 63843, 2084, 41965, 125099, 65866, 4327, 0, 63840, 66413, 41220, 13032, + 92980, 584, 12933, 43177, 12373, 69855, 13000, 1351, 2935, 8698, 12665, + 0, 1930, 0, 78229, 12427, 66514, 69859, 13031, 0, 63901, 0, 3657, 119611, + 65202, 6000, 113786, 12426, 127181, 119935, 41740, 12428, 41283, 41916, + 119210, 128318, 0, 12429, 6727, 0, 7562, 983248, 5170, 983915, 41755, + 676, 0, 66704, 66664, 9978, 66491, 3536, 0, 9752, 92397, 6162, 92928, + 69228, 10113, 41829, 65886, 5159, 12422, 41832, 439, 3072, 983464, 42207, + 74549, 11796, 40970, 41830, 125021, 70151, 8308, 917797, 70807, 119258, + 67864, 113696, 917800, 12336, 4135, 67231, 341, 2727, 4129, 3539, 0, + 63861, 0, 7913, 0, 63859, 4131, 63868, 129085, 63867, 4133, 11371, 210, + 4600, 0, 74560, 4137, 8082, 78506, 119062, 78504, 6704, 4591, 128029, + 125018, 120753, 9680, 12937, 120623, 561, 12159, 195, 68321, 41501, + 983371, 42031, 5719, 7172, 42687, 8368, 128306, 41499, 93068, 71047, + 42242, 41498, 917794, 42025, 78565, 65805, 42463, 67182, 2924, 67183, + 120510, 0, 0, 92766, 73941, 67186, 42330, 67187, 3969, 128484, 0, 7169, + 1992, 9652, 73977, 7246, 42086, 126615, 2219, 127177, 0, 128801, 67180, + 0, 327, 128300, 9042, 917777, 917776, 65148, 12433, 917781, 120222, + 917779, 12431, 8668, 12434, 67194, 917782, 5999, 0, 7712, 12432, 128243, + 43653, 1726, 1015, 0, 8212, 0, 113754, 42423, 119066, 194613, 72398, + 66709, 0, 8811, 927, 128461, 0, 12436, 120087, 42021, 0, 67644, 1299, + 12240, 42350, 65143, 0, 195016, 127972, 78197, 11348, 0, 78037, 9194, + 983184, 0, 19914, 12179, 128740, 2296, 128932, 63836, 63832, 917773, + 10967, 63816, 2594, 3444, 63817, 11178, 0, 41503, 127478, 11265, 68295, + 120756, 194922, 67285, 5664, 3972, 0, 128583, 0, 67284, 12416, 917764, + 119608, 10816, 917769, 11210, 12418, 74111, 3882, 8532, 917771, 1573, + 128018, 119847, 4596, 66339, 12417, 66001, 65343, 126491, 12414, 8287, + 68219, 195017, 68108, 1143, 119169, 119846, 12415, 6626, 42763, 0, + 118884, 9021, 120783, 119931, 11724, 0, 0, 127104, 126619, 0, 0, 8027, + 10997, 9171, 12741, 11400, 71305, 194799, 66833, 128239, 0, 92557, + 119604, 127523, 120190, 1324, 67608, 128214, 42368, 0, 7715, 3881, 41487, + 12118, 42514, 68651, 0, 128594, 3009, 41476, 41489, 69825, 3007, 1448, + 3018, 194809, 3889, 8521, 5083, 5082, 119859, 78255, 8519, 983241, 3014, + 5081, 65853, 120715, 0, 68014, 69951, 5079, 64802, 42210, 4597, 65532, + 11828, 120185, 12371, 11105, 8407, 67163, 10805, 8518, 10779, 120188, + 71303, 983933, 12367, 42170, 0, 67290, 629, 1924, 128435, 12037, 67158, + 5987, 8462, 8005, 12365, 63933, 69735, 120815, 12369, 10649, 67981, 5077, + 120174, 10880, 63927, 5075, 917881, 127300, 65075, 0, 11007, 70851, + 66659, 92607, 917933, 66684, 128063, 3434, 4954, 1904, 92679, 5266, + 126980, 5272, 10499, 4507, 9578, 63923, 120177, 7979, 0, 9831, 0, 194926, + 461, 9803, 42282, 4504, 1505, 0, 6325, 5276, 43021, 120488, 0, 55236, + 92659, 66461, 5177, 41324, 12055, 8722, 120805, 41327, 983732, 66695, + 4114, 409, 4383, 8900, 8948, 41325, 0, 721, 10182, 9108, 71311, 0, + 119185, 42229, 194912, 0, 5998, 0, 42353, 74825, 0, 12587, 94104, 78571, + 0, 71328, 128955, 41576, 42215, 78570, 74037, 0, 8578, 5995, 7573, 41575, + 74789, 74752, 63944, 63949, 64767, 2670, 4167, 194796, 11723, 0, 74120, + 0, 65076, 938, 43414, 73854, 11737, 9721, 0, 67179, 67168, 11742, 2419, + 67177, 11493, 12334, 194913, 4153, 12302, 10793, 5250, 12407, 11978, + 4404, 9189, 12401, 42007, 5775, 6759, 65806, 43997, 0, 42002, 12404, + 70388, 129093, 4940, 12410, 7683, 1167, 73729, 4983, 120507, 861, 67699, + 0, 68297, 0, 43757, 43370, 0, 0, 11956, 124967, 0, 70815, 9616, 6631, + 92338, 12816, 43759, 42218, 12710, 68674, 12721, 4101, 66185, 0, 5992, + 7616, 195044, 0, 12577, 93017, 983884, 853, 42693, 194647, 119027, + 983647, 5016, 43535, 63893, 42835, 9491, 917913, 0, 917914, 0, 12712, + 7105, 127807, 65060, 66875, 9900, 7750, 917946, 127896, 74619, 127830, + 983587, 64778, 12585, 10565, 128151, 12177, 119843, 983258, 0, 77824, 0, + 4900, 127874, 12878, 92630, 8984, 4119, 74768, 8971, 78593, 43113, 9702, + 66852, 11025, 9245, 13048, 4927, 4138, 74185, 92481, 92710, 12397, 77827, + 119040, 13054, 12394, 0, 0, 194954, 13053, 118974, 3948, 10781, 1546, 0, + 5010, 1680, 10507, 78590, 78583, 92431, 0, 0, 194915, 7267, 0, 74833, + 128181, 5993, 2819, 128788, 12706, 71063, 1893, 7266, 63915, 7264, 7265, + 0, 1363, 0, 42923, 63910, 63996, 3077, 120018, 0, 1512, 69929, 12589, + 41479, 128313, 71048, 43339, 73776, 9836, 120727, 0, 41481, 43335, 7832, + 42343, 3090, 43337, 817, 1664, 1850, 128841, 3079, 11340, 42408, 42447, + 127140, 120020, 42307, 12386, 42304, 917555, 0, 12389, 128398, 92366, + 41996, 11526, 63985, 5864, 1147, 43849, 42887, 1987, 92718, 5480, 7858, + 11653, 4116, 12391, 66193, 129197, 4939, 12384, 0, 0, 41686, 63905, + 119601, 194688, 67398, 128820, 12649, 129056, 0, 8247, 507, 91, 2042, + 120775, 43643, 194689, 66028, 10036, 41844, 119813, 774, 119829, 77840, + 119815, 5994, 12539, 0, 78375, 120597, 119833, 983105, 78377, 0, 917628, + 7719, 6026, 2486, 128312, 119808, 162, 0, 65219, 41073, 9687, 41681, + 6304, 119812, 66196, 194881, 5262, 0, 55233, 12681, 42379, 0, 7534, + 12219, 2226, 70499, 42810, 10492, 127015, 983661, 126704, 43119, 0, + 78537, 12403, 2500, 70145, 0, 4899, 12729, 983397, 0, 74113, 2343, 4103, + 19946, 74112, 77851, 13112, 129046, 74834, 12859, 70087, 120148, 66369, + 5861, 127758, 11999, 12400, 43641, 983839, 12645, 5146, 11320, 68410, + 6748, 65040, 983491, 64184, 12974, 64183, 67613, 120645, 5147, 125019, 0, + 74524, 128356, 1928, 0, 67649, 5991, 3445, 67609, 4976, 64176, 0, 67610, + 8241, 0, 77868, 4206, 0, 78662, 0, 128298, 67277, 10138, 67238, 128785, + 8897, 120234, 1422, 8357, 4124, 77862, 65836, 120641, 127926, 77859, 0, + 194696, 1123, 963, 41553, 10120, 12405, 120150, 92664, 398, 13278, 9723, + 6366, 120311, 7945, 983163, 4402, 9970, 12402, 93062, 42392, 1305, 12408, + 92384, 44007, 128563, 127216, 41464, 12411, 12969, 67268, 41465, 983565, + 8528, 1575, 0, 63955, 165, 3024, 41467, 119163, 70119, 9093, 0, 6833, + 92574, 63958, 0, 9148, 9692, 4096, 53, 8296, 6750, 66855, 0, 9594, + 120308, 129186, 43527, 194622, 727, 74192, 93060, 5805, 0, 6726, 0, + 42176, 12370, 11655, 119095, 10591, 2280, 0, 12372, 120642, 120307, + 71209, 92343, 0, 12366, 10963, 6066, 1329, 0, 3052, 9220, 0, 64478, + 194701, 10803, 4132, 120306, 68474, 92473, 0, 120712, 74837, 120155, + 1499, 0, 8055, 42740, 63965, 120305, 63962, 74042, 8924, 43123, 5988, + 3660, 63969, 11781, 42718, 8788, 1357, 64851, 65743, 92894, 8774, 70337, + 127086, 9941, 120172, 92748, 1933, 69655, 9564, 0, 92435, 73866, 0, + 983583, 2487, 67614, 3121, 1804, 3311, 67615, 70081, 78302, 12220, 67616, + 92769, 127475, 0, 68200, 6675, 128144, 0, 67592, 120685, 0, 64771, 1198, + 9132, 0, 64619, 510, 64663, 0, 0, 4561, 2101, 1398, 917972, 92554, 74034, + 41569, 92684, 11406, 8167, 12127, 0, 840, 983281, 69992, 7101, 6967, 0, + 194898, 9796, 0, 333, 69891, 0, 8144, 2117, 0, 983595, 12406, 0, 19931, + 66388, 6678, 7769, 0, 12621, 0, 127366, 10227, 4764, 43101, 9981, 0, + 40986, 4127, 66487, 983576, 42202, 12754, 195022, 0, 0, 94097, 67594, + 2048, 12944, 4050, 67595, 917967, 43102, 10581, 11184, 4533, 195021, + 74003, 6490, 0, 12038, 0, 0, 68225, 65461, 9798, 69704, 0, 1948, 69841, + 0, 952, 128235, 125107, 0, 120802, 6449, 9494, 120313, 0, 43098, 4843, + 8142, 64160, 4098, 64170, 983339, 0, 3436, 119973, 0, 12817, 67597, 6676, + 3930, 42615, 0, 69991, 67598, 0, 0, 0, 65591, 41581, 65916, 1453, 0, 0, + 127859, 8500, 42222, 120142, 73743, 120400, 4317, 11543, 67676, 64676, 0, + 127833, 67606, 119083, 127892, 42217, 13102, 0, 66003, 6672, 0, 0, 66880, + 983747, 63841, 9613, 9001, 4526, 11274, 67601, 64520, 64210, 6664, 78704, + 42056, 10228, 64957, 11281, 0, 3807, 1469, 66640, 65381, 42197, 4988, + 42372, 0, 9598, 904, 352, 42225, 1451, 8061, 8453, 4134, 127052, 67223, + 66576, 127916, 127831, 10520, 8575, 9960, 1201, 127289, 12846, 127291, + 127292, 11919, 64962, 127287, 43739, 127281, 8511, 9460, 823, 11587, + 12305, 0, 64695, 127305, 12387, 1253, 13183, 65766, 500, 42783, 65765, + 64208, 64369, 65760, 65761, 70334, 11606, 64784, 11702, 66498, 9821, + 64304, 0, 5152, 11048, 7533, 68366, 64410, 92305, 0, 4323, 120062, 92669, + 71332, 120158, 42587, 42214, 41394, 11188, 4763, 4112, 118935, 0, 5260, + 43143, 94038, 326, 120131, 68423, 194904, 10771, 2876, 74074, 92530, + 128460, 41398, 7382, 9802, 127077, 127076, 453, 41396, 120524, 13159, + 12140, 9572, 0, 7003, 194883, 42334, 7704, 125069, 125020, 43144, 4123, + 8494, 43146, 9977, 0, 126473, 65759, 10765, 64061, 4465, 9808, 64056, + 65582, 4126, 0, 9521, 9589, 64755, 0, 64020, 126604, 10464, 0, 92968, + 194869, 64514, 11528, 64024, 128072, 679, 64013, 983555, 5850, 758, 7536, + 128663, 92234, 41441, 10693, 64006, 983567, 64005, 4058, 119019, 126487, + 64660, 128176, 119050, 0, 983069, 1139, 43298, 64027, 64029, 8970, 0, + 9934, 128685, 10774, 67104, 42201, 12421, 128216, 0, 1852, 3057, 64046, + 73744, 64034, 64039, 129127, 0, 0, 194899, 92322, 7645, 12854, 74338, + 3496, 0, 0, 113710, 9102, 627, 127795, 6158, 8327, 74553, 66632, 12419, + 13309, 11570, 127811, 19960, 11696, 0, 1018, 118970, 129075, 194897, + 1682, 43863, 194911, 42756, 6765, 194906, 67717, 74358, 73814, 11412, + 6768, 10728, 119982, 71316, 71099, 43311, 64966, 11577, 0, 43040, 1833, + 11576, 0, 74779, 0, 185, 65085, 74533, 64754, 119334, 7535, 8085, 42525, + 120387, 9749, 41701, 6131, 1949, 4117, 7847, 120489, 124992, 64483, + 65693, 983711, 0, 0, 69695, 42240, 128587, 126651, 42864, 126498, 43168, + 41868, 1184, 0, 815, 11484, 127535, 67840, 983651, 0, 66197, 983472, + 10986, 64683, 983785, 128454, 3455, 0, 0, 9879, 0, 0, 4158, 128050, 68166, 0, 0, 0, 0, 69645, 332, 118808, 0, 5142, 2407, 69643, 42199, 0, - 92404, 74373, 0, 55217, 0, 63870, 43163, 0, 0, 92390, 42867, 1834, 0, - 92461, 69817, 10940, 65249, 119040, 8662, 0, 0, 2652, 120527, 7164, + 92404, 74373, 0, 55217, 92436, 63870, 43163, 0, 0, 12985, 42867, 1834, 0, + 92461, 69817, 10940, 65249, 70385, 8662, 120324, 0, 2652, 120527, 7164, 10784, 195093, 67674, 0, 92233, 92482, 194749, 74562, 917505, 1828, - 74474, 120327, 78620, 8531, 12499, 6280, 12324, 118854, 65238, 68374, - 4832, 65573, 0, 6279, 12508, 12904, 12502, 9161, 0, 1620, 64436, 3601, - 195094, 128073, 983562, 609, 11555, 983099, 12496, 127839, 74181, 4343, - 12505, 0, 127863, 0, 11377, 239, 0, 637, 0, 0, 42671, 0, 0, 0, 43565, - 71306, 126493, 12696, 128256, 0, 94062, 12929, 0, 712, 0, 4197, 983206, - 42818, 126632, 0, 120490, 0, 119137, 1506, 43562, 0, 92491, 0, 12651, 0, - 64628, 74517, 12058, 74084, 917838, 7494, 0, 4924, 65592, 118844, 0, - 127088, 355, 9719, 127087, 13066, 64796, 0, 0, 12033, 42178, 0, 69760, - 42571, 92635, 0, 0, 0, 0, 0, 127176, 3178, 0, 0, 92704, 0, 9080, 127000, - 120352, 0, 68209, 0, 11082, 0, 5699, 195100, 66000, 9488, 65166, 119112, - 0, 0, 0, 0, 71313, 0, 5265, 69235, 0, 11487, 67858, 12464, 0, 43045, 0, - 0, 43345, 0, 10770, 118994, 6807, 465, 9829, 0, 74348, 0, 43346, 8116, - 795, 0, 0, 12462, 10930, 10831, 0, 118952, 64362, 74334, 983602, 120811, - 0, 12468, 8607, 1008, 0, 10092, 195078, 917842, 67855, 55257, 73771, - 1766, 11282, 11996, 1820, 4547, 0, 0, 0, 0, 13223, 128665, 64595, 127294, - 0, 92311, 4345, 12616, 0, 0, 0, 74467, 0, 0, 0, 5382, 0, 0, 0, 119060, - 64953, 5406, 19920, 69897, 66510, 3590, 194864, 1130, 0, 0, 42016, 11823, - 43023, 0, 118896, 7742, 0, 13280, 71323, 9326, 73826, 5310, 74812, 78584, - 92229, 8959, 43589, 6747, 66723, 0, 8568, 0, 120496, 73816, 120803, - 983848, 42670, 0, 11621, 12460, 0, 120631, 0, 43063, 74519, 127182, 0, - 73917, 7843, 69783, 11689, 5410, 5783, 10468, 8403, 5400, 11594, 128247, - 0, 118990, 10491, 69842, 64412, 0, 0, 5587, 42865, 64404, 8268, 4923, - 65086, 8981, 12382, 42133, 120755, 9706, 69738, 0, 66610, 10461, 12103, - 0, 8642, 0, 42766, 983866, 2210, 9983, 0, 94009, 0, 0, 0, 7398, 41515, 0, - 11802, 8041, 1461, 910, 119133, 0, 6749, 3658, 93964, 120525, 0, 7617, - 194841, 12888, 127983, 67668, 13143, 0, 9193, 11097, 5703, 0, 41517, - 41504, 41519, 10016, 64305, 0, 65864, 623, 781, 670, 10660, 5769, 613, - 7543, 120279, 477, 41083, 92521, 0, 592, 1578, 12459, 43449, 0, 0, 8225, - 0, 654, 11345, 653, 652, 0, 647, 0, 633, 120744, 0, 126472, 12480, 43243, - 0, 39, 12487, 0, 120529, 74199, 12482, 0, 12489, 0, 3195, 5550, 983554, - 7897, 0, 1203, 74396, 1813, 64544, 41311, 12090, 0, 2877, 0, 0, 1675, - 69840, 0, 0, 0, 10070, 10595, 0, 119077, 194777, 983611, 0, 0, 0, 43244, - 0, 0, 983916, 119561, 983078, 0, 194921, 128160, 9939, 0, 983151, 77860, - 0, 0, 270, 0, 10714, 0, 0, 0, 0, 0, 65372, 0, 74038, 119558, 6273, 66679, - 364, 9595, 194908, 0, 0, 707, 0, 0, 9282, 66489, 224, 0, 68670, 9332, - 4966, 68677, 0, 68644, 0, 3841, 68634, 0, 10732, 68640, 850, 4972, 0, - 12890, 2909, 68619, 44008, 68627, 983718, 11544, 10203, 9608, 0, 0, - 11962, 194694, 12507, 1196, 128687, 128311, 777, 120187, 4375, 65271, - 67678, 0, 12198, 0, 64824, 119343, 983236, 9454, 63778, 8658, 42528, - 78000, 2705, 917975, 41520, 0, 0, 11986, 7765, 42502, 8280, 74520, 2701, - 0, 127002, 5767, 0, 0, 9809, 8353, 63747, 66701, 63772, 983814, 63745, - 1748, 63770, 0, 0, 0, 65542, 63766, 55244, 3061, 0, 63764, 63787, 9067, - 6096, 0, 7694, 0, 7257, 63768, 3485, 12987, 0, 127522, 120628, 63807, - 1591, 0, 6386, 63783, 0, 0, 92535, 0, 0, 0, 74575, 0, 65719, 13083, - 64574, 65012, 0, 1640, 12495, 66691, 7624, 3138, 10996, 92247, 1922, 0, - 12498, 10987, 69936, 69939, 3894, 65543, 0, 194842, 983588, 493, 0, - 43197, 1717, 4228, 479, 10303, 74020, 0, 917935, 10335, 3520, 917932, - 12490, 64315, 0, 127039, 12493, 6233, 42681, 1002, 12491, 0, 64911, - 92615, 2096, 65120, 0, 78219, 983081, 8378, 11632, 127041, 66213, 63864, - 66221, 66226, 66229, 13218, 66231, 66216, 8507, 66236, 66211, 66218, - 92672, 66240, 78041, 66233, 8928, 983552, 7909, 66234, 11605, 63759, - 983654, 66208, 73999, 63799, 63803, 244, 11542, 12898, 12494, 73761, - 12492, 12669, 0, 0, 74153, 0, 128278, 120680, 4882, 13040, 0, 8612, 4885, - 74053, 0, 13042, 4880, 64662, 2429, 1360, 248, 0, 63797, 92394, 42358, 0, + 74474, 120327, 78620, 8531, 12499, 6280, 12324, 72434, 65238, 68374, + 4832, 65573, 43851, 6279, 12508, 12904, 12502, 9161, 0, 1620, 64436, + 3601, 124944, 128073, 67246, 609, 11555, 92409, 12496, 67250, 74181, + 4343, 12505, 0, 127863, 0, 11377, 239, 129190, 637, 0, 128678, 42671, 0, + 93032, 0, 43565, 71306, 126493, 12696, 128256, 917600, 94062, 12929, 0, + 712, 0, 4197, 983206, 42818, 126632, 0, 120490, 70333, 119137, 1506, + 43562, 0, 92491, 0, 12651, 0, 64628, 74517, 12058, 74084, 917838, 7494, + 0, 4924, 65592, 118844, 194823, 127088, 355, 9719, 127087, 13066, 64796, + 0, 0, 12033, 42178, 0, 69760, 42571, 92635, 11430, 0, 0, 0, 124951, + 68324, 3178, 917835, 128633, 92704, 0, 9080, 127000, 67697, 195101, + 68209, 72418, 11082, 0, 5699, 195100, 66000, 9488, 65166, 119112, 70477, + 11170, 68662, 128120, 71313, 0, 5265, 69235, 0, 11487, 67858, 12464, 0, + 43045, 0, 0, 43345, 0, 10770, 118994, 6807, 465, 9829, 69997, 74348, 0, + 43346, 8116, 795, 120352, 72412, 12462, 10930, 10831, 0, 118952, 64362, + 74334, 93056, 120811, 0, 12468, 8607, 1008, 0, 10092, 125122, 917842, + 67855, 55257, 73771, 1766, 11282, 11996, 1820, 4547, 0, 11202, 983222, + 983872, 13223, 128665, 64595, 127294, 0, 68489, 4345, 12616, 917784, + 128947, 983155, 74467, 0, 0, 0, 5382, 0, 0, 67233, 119060, 64953, 5406, + 19920, 69897, 66510, 3590, 194864, 1130, 917766, 194692, 42016, 11823, + 43023, 125129, 118896, 7742, 0, 13280, 71323, 9326, 73826, 5310, 43509, + 78584, 92229, 8959, 43589, 6747, 66723, 64757, 8568, 194684, 120496, + 73816, 120803, 983848, 42670, 0, 11621, 12460, 1326, 120631, 983334, + 43063, 43239, 127182, 194840, 73917, 7843, 69783, 11689, 5410, 5783, + 10468, 8403, 5400, 11594, 120405, 68333, 118990, 10491, 69842, 64412, 0, + 0, 5587, 42865, 64404, 8268, 4923, 65086, 8981, 12382, 42133, 120755, + 9706, 69738, 0, 66610, 10461, 12103, 0, 8642, 194707, 42766, 128247, + 2210, 9983, 0, 94009, 0, 0, 0, 7398, 41515, 0, 11802, 8041, 1461, 910, + 119133, 0, 6749, 3658, 93964, 120525, 0, 7617, 194841, 12888, 127983, + 67668, 13143, 0, 9193, 11097, 5703, 983475, 41517, 41504, 41519, 10016, + 64305, 0, 65864, 623, 781, 670, 10660, 5769, 613, 7543, 120279, 477, + 41083, 92521, 0, 592, 1578, 12459, 43449, 0, 0, 8225, 0, 654, 11345, 653, + 652, 0, 647, 0, 633, 120744, 0, 126472, 12480, 43243, 0, 39, 12487, 0, + 120529, 74199, 12482, 0, 12489, 119607, 3195, 5550, 129121, 7897, 127089, + 1203, 74396, 1813, 64544, 41311, 12090, 983634, 2877, 128394, 70496, + 1675, 69840, 0, 0, 119078, 10070, 10595, 0, 119077, 194777, 983611, + 67170, 120790, 118787, 43244, 0, 0, 983916, 119561, 983078, 194914, + 194921, 128160, 9939, 0, 983151, 77860, 128948, 0, 270, 0, 10714, 118983, + 72437, 0, 0, 119338, 65372, 73803, 74038, 68251, 6273, 66679, 364, 9595, + 127137, 0, 0, 707, 0, 128409, 9282, 11163, 224, 128588, 68670, 9332, + 4966, 68677, 0, 68644, 983131, 3841, 67357, 67341, 10732, 68640, 850, + 4972, 0, 12890, 2909, 68619, 44008, 68627, 120699, 11544, 10203, 9608, 0, + 917943, 11962, 194694, 12507, 1196, 67684, 67100, 777, 120187, 4375, + 65271, 67678, 0, 12198, 917887, 64824, 119343, 127243, 9454, 63778, 8658, + 42528, 70073, 2705, 128680, 41520, 195098, 128447, 11986, 7765, 42502, + 8280, 74520, 2701, 0, 120240, 5767, 0, 0, 9809, 8353, 63747, 66701, + 63772, 983814, 63745, 1748, 63770, 0, 129137, 0, 65542, 63766, 55244, + 3061, 78609, 63764, 63787, 9067, 6096, 0, 7694, 0, 7257, 63768, 3485, + 12987, 127781, 127522, 120628, 63807, 1591, 0, 6386, 63783, 0, 125041, + 92535, 0, 0, 68249, 74575, 0, 65719, 13083, 64574, 65012, 983958, 1640, + 12495, 66691, 7624, 3138, 10996, 11171, 1922, 0, 12498, 10987, 69936, + 69939, 3894, 65543, 129183, 194842, 983588, 493, 0, 43197, 1717, 4228, + 479, 10303, 74020, 0, 917935, 10335, 3520, 917932, 12490, 64315, 92170, + 127039, 12493, 6233, 42681, 1002, 12491, 113695, 64911, 92615, 2096, + 65120, 0, 78219, 128912, 8378, 11632, 127041, 66213, 63864, 66221, 66226, + 66229, 13218, 66231, 66216, 8507, 66236, 66211, 66218, 92672, 66240, + 78041, 66233, 8928, 983552, 7909, 66234, 11605, 63759, 983654, 66208, + 67339, 13002, 63803, 244, 11542, 12898, 12494, 73761, 12492, 12669, 0, 0, + 74153, 120310, 128278, 120680, 4882, 13040, 0, 8612, 4885, 74053, 0, + 13042, 4880, 64662, 2429, 1360, 248, 129066, 63797, 92394, 42358, 0, 7292, 0, 63756, 42786, 66693, 0, 1870, 78040, 470, 78038, 78035, 78036, - 70028, 78034, 4579, 128090, 0, 12511, 74453, 12514, 0, 74579, 7239, 7001, - 8623, 94011, 128052, 128048, 7378, 12512, 11615, 6104, 0, 0, 659, 6098, - 0, 12234, 127307, 127067, 8311, 12510, 41803, 13039, 127072, 12513, - 10202, 12471, 0, 8747, 983920, 0, 0, 2323, 0, 2319, 77917, 12477, 77916, - 2311, 0, 4415, 237, 6281, 127280, 0, 0, 2309, 1312, 8173, 128871, 12469, - 0, 78505, 64335, 10609, 0, 128111, 9397, 11524, 9395, 9396, 9393, 9394, - 9391, 9392, 9389, 6209, 9387, 9388, 4932, 9386, 9383, 9384, 6740, 0, - 65451, 8185, 0, 917832, 43024, 43336, 67659, 2313, 128167, 7948, 9236, - 92571, 0, 0, 10570, 43473, 6289, 10484, 0, 0, 11998, 12082, 10924, 3147, - 0, 120684, 12524, 119081, 2310, 11818, 9381, 9382, 9379, 9380, 9377, - 9378, 9375, 9376, 1683, 9374, 983778, 9372, 12444, 0, 0, 13016, 8210, - 983958, 42029, 11079, 12331, 43451, 42032, 8744, 726, 0, 983837, 4155, 0, - 0, 42030, 5007, 12522, 43088, 0, 4951, 127805, 127240, 0, 9922, 43309, - 983841, 12525, 983471, 12016, 65770, 9548, 67665, 403, 78230, 12503, 0, - 0, 11030, 0, 92567, 65691, 63998, 1819, 10496, 0, 0, 119920, 0, 194668, - 0, 12506, 0, 12231, 0, 12500, 44023, 12509, 64393, 78830, 3389, 10589, - 6608, 41047, 120321, 78395, 78394, 74069, 77995, 78391, 3608, 8281, - 120320, 1107, 0, 9076, 8862, 69743, 41052, 13084, 64766, 43217, 7803, - 13222, 74165, 74782, 126514, 8546, 11553, 63995, 13177, 9043, 6303, - 983947, 498, 64471, 120324, 128567, 12529, 8042, 0, 2344, 12528, 8031, - 2414, 0, 69719, 3231, 0, 6422, 66512, 69653, 12530, 2537, 78405, 41429, - 12658, 13036, 65772, 0, 78738, 41433, 4719, 469, 0, 4363, 3313, 41428, - 78407, 2023, 1772, 78224, 78225, 65706, 10051, 64812, 78220, 0, 9920, - 12215, 0, 4931, 1951, 12497, 119363, 9607, 0, 9663, 983228, 119634, 6503, - 41110, 0, 1491, 0, 0, 127304, 41061, 0, 194838, 127187, 65026, 41993, - 41509, 11045, 65028, 78602, 66476, 41108, 9738, 41995, 1075, 1958, 12535, - 41992, 41506, 0, 41687, 0, 120717, 127776, 9940, 127299, 7692, 983833, - 8008, 41131, 330, 8566, 65083, 41133, 9816, 126517, 12532, 78550, 78546, - 3508, 127058, 43235, 0, 127298, 64139, 78231, 6411, 12910, 78554, 66644, - 13028, 6737, 12537, 0, 0, 64136, 12536, 2350, 13029, 78233, 0, 983103, - 13030, 6702, 4527, 0, 12538, 128810, 983645, 65599, 65717, 9966, 0, 4948, - 12484, 4032, 128149, 12623, 0, 6207, 0, 6117, 65930, 8412, 0, 7438, 1296, - 2325, 41511, 126625, 10149, 74118, 0, 127286, 12481, 0, 12488, 66713, 0, - 41556, 64414, 118802, 2354, 42619, 73766, 0, 6295, 901, 41510, 7953, 0, - 65032, 41513, 983166, 11927, 66584, 78559, 78560, 78557, 78558, 0, 78556, - 848, 9868, 0, 6424, 78568, 119338, 69922, 74031, 78563, 78564, 2352, - 78572, 893, 64576, 11289, 1407, 67973, 0, 13026, 6762, 78579, 78580, - 13023, 8903, 9777, 66715, 1871, 8099, 0, 0, 1343, 983823, 0, 9325, 6818, - 6283, 11738, 0, 983934, 0, 11741, 0, 0, 9216, 8263, 11279, 194752, - 983825, 194754, 13021, 64494, 3136, 194758, 194757, 194760, 13022, 42737, - 9956, 0, 0, 74552, 10014, 0, 41260, 119340, 13020, 10024, 194764, 74583, - 74340, 69681, 0, 43001, 8029, 0, 0, 983780, 3335, 0, 0, 9776, 120526, - 194748, 5215, 42644, 3333, 1632, 194751, 64849, 3342, 78582, 5363, 12957, - 78581, 4156, 0, 0, 6421, 78591, 1611, 78589, 13018, 74257, 78588, 74542, + 70028, 78034, 4579, 69232, 0, 12511, 74453, 12514, 0, 74579, 7239, 7001, + 8623, 94011, 125137, 128048, 7378, 12512, 11615, 6104, 0, 0, 659, 6098, + 0, 12234, 127307, 67358, 8311, 12510, 7669, 13039, 127072, 12513, 10202, + 12471, 0, 8747, 125049, 70193, 128354, 2323, 0, 2319, 77917, 12477, + 77916, 2311, 7666, 4415, 237, 6281, 127280, 0, 0, 2309, 1312, 8173, + 128871, 12469, 0, 78505, 64335, 10609, 0, 128111, 9397, 11524, 9395, + 9396, 9393, 9394, 9391, 9392, 9389, 6209, 9387, 9388, 4932, 9386, 9383, + 9384, 6740, 0, 65451, 8185, 128931, 917832, 43024, 43336, 67659, 2313, + 128167, 7948, 9236, 77942, 0, 0, 10570, 43473, 6289, 10484, 0, 0, 11998, + 12082, 10924, 3147, 0, 66406, 12524, 119081, 2310, 11818, 9381, 9382, + 9379, 9380, 9377, 9378, 9375, 9376, 1683, 9374, 983778, 9372, 12444, 0, + 0, 13016, 8210, 129178, 42029, 11079, 12331, 43451, 42032, 8744, 726, 0, + 917922, 4155, 0, 120704, 42030, 5007, 12522, 43088, 0, 4951, 113826, + 127240, 0, 9922, 43309, 11211, 12525, 983471, 12016, 65770, 9548, 67665, + 403, 78230, 12503, 0, 0, 11030, 0, 92567, 65691, 63998, 1819, 10496, 0, + 0, 119920, 0, 129143, 0, 12506, 983838, 11146, 127751, 12500, 44023, + 12509, 64393, 78830, 3389, 10589, 6608, 11208, 120236, 78395, 78394, + 74069, 77995, 78391, 3608, 8281, 113732, 1107, 113745, 9076, 8862, 69743, + 41052, 13084, 64766, 43217, 7803, 13222, 74165, 74782, 43499, 8546, + 11553, 63995, 13177, 9043, 6303, 113664, 498, 64471, 77987, 92974, 12529, + 8042, 0, 2344, 12528, 8031, 2414, 74506, 69719, 3231, 0, 6422, 66512, + 69653, 12530, 2537, 78405, 41429, 12658, 13036, 65772, 0, 78738, 41433, + 4719, 469, 0, 4363, 3313, 41428, 78407, 2023, 1772, 78224, 78225, 65706, + 10051, 64812, 78220, 0, 9920, 12215, 127876, 4931, 1951, 12497, 119363, + 9607, 70368, 9663, 66838, 119634, 6503, 41110, 983465, 1491, 66847, + 129169, 127304, 41061, 70454, 194838, 127187, 65026, 41993, 41509, 11045, + 65028, 71181, 66476, 41108, 9738, 41995, 1075, 1958, 12535, 41992, 41506, + 0, 41687, 0, 120717, 127776, 9940, 127299, 7692, 983833, 8008, 41131, + 330, 8566, 65083, 6839, 9816, 126517, 12532, 78550, 78546, 3508, 127058, + 43235, 120351, 127298, 64139, 78231, 6411, 12910, 67710, 66644, 13028, + 6737, 12537, 0, 43506, 64136, 12536, 2350, 13029, 78233, 127763, 983103, + 13030, 6702, 4527, 71250, 12538, 128810, 983645, 65599, 65717, 9966, + 128499, 4948, 12484, 4032, 128149, 12623, 0, 6207, 0, 6117, 65930, 8412, + 127183, 7438, 1296, 2325, 41511, 126625, 10149, 74118, 0, 120233, 12481, + 0, 12488, 66713, 0, 41556, 64414, 118802, 2354, 42619, 73766, 0, 6295, + 901, 41510, 7953, 0, 65032, 41513, 983166, 11927, 66584, 78559, 78560, + 78557, 78558, 0, 67603, 848, 9868, 67220, 6424, 78568, 67226, 69922, + 70190, 78563, 78564, 2352, 67219, 893, 64576, 11289, 1407, 67973, 0, + 13026, 6762, 78579, 70192, 13023, 8903, 9777, 66715, 1871, 8099, 127984, + 0, 1343, 983823, 120784, 9325, 6818, 6283, 11738, 0, 72436, 113713, + 11741, 0, 93038, 9216, 8263, 11279, 194752, 983453, 194754, 13021, 64494, + 3136, 194758, 194757, 194760, 13022, 42737, 9956, 0, 127787, 74552, + 10014, 0, 41260, 119340, 13020, 10024, 194764, 74583, 74340, 69681, 0, + 43001, 8029, 0, 0, 983780, 3335, 119341, 9209, 9776, 120526, 194748, + 5215, 42644, 3333, 1632, 194751, 64849, 3342, 78582, 5363, 12957, 78581, + 4156, 0, 127329, 6421, 78039, 1611, 78589, 13018, 74257, 78588, 74542, 3337, 4537, 67895, 11736, 0, 68608, 6482, 4214, 73790, 11945, 0, 13046, - 8838, 425, 4025, 10709, 78595, 2108, 2392, 13047, 0, 0, 6819, 13049, - 6499, 92243, 12424, 68614, 73944, 13050, 9924, 194745, 6507, 127919, + 8838, 425, 4025, 10709, 78595, 2108, 2392, 13047, 92745, 0, 6819, 13049, + 6499, 92243, 12424, 68614, 65827, 13050, 9924, 194745, 6507, 127919, 94073, 128069, 3277, 8929, 4947, 41055, 0, 194722, 194721, 194724, 13045, 64626, 66034, 7751, 194727, 8371, 194729, 3997, 12806, 8768, 13044, 0, - 12420, 4024, 194730, 41054, 1078, 9757, 69736, 41057, 0, 0, 0, 0, 983791, - 92210, 92411, 0, 41496, 0, 9165, 1572, 11911, 0, 118842, 2346, 13270, - 8958, 0, 9646, 3773, 43183, 6401, 5831, 0, 0, 13043, 8056, 92494, 65681, - 208, 127382, 41514, 0, 0, 0, 10699, 6408, 92227, 7825, 5661, 0, 120630, - 3603, 41109, 2398, 3548, 126596, 0, 119933, 0, 3115, 9918, 0, 8294, - 42912, 0, 0, 194726, 4876, 65804, 0, 0, 43468, 983274, 41558, 41471, - 73950, 8158, 9944, 41472, 120298, 13051, 78689, 3143, 194674, 6701, - 41559, 1896, 66256, 13052, 194680, 5665, 0, 119071, 7025, 63974, 0, - 74352, 74161, 4154, 9863, 43550, 12310, 5662, 42382, 1564, 73924, 1121, - 78319, 63959, 0, 9942, 13231, 0, 64752, 4732, 194666, 11596, 119931, - 65187, 1626, 63983, 10110, 64772, 42024, 6420, 42028, 0, 10509, 2795, - 4910, 194728, 69231, 64753, 6275, 93957, 118830, 63978, 11044, 3229, - 6423, 42774, 0, 0, 0, 12823, 2331, 917810, 7085, 6137, 0, 7524, 0, - 917809, 8346, 0, 8338, 128315, 65043, 0, 822, 127984, 9903, 64721, 42722, - 69877, 194659, 78655, 78661, 194660, 78662, 41265, 5311, 1795, 965, - 118791, 10587, 78055, 11278, 78632, 194640, 0, 12946, 194641, 119341, - 120349, 6294, 3144, 194648, 194647, 65019, 194649, 73990, 0, 983960, 748, - 41067, 2330, 535, 3148, 12375, 78799, 194629, 10556, 2475, 12388, 4889, - 8968, 67863, 3593, 0, 0, 2342, 0, 194634, 65206, 4894, 194635, 4890, - 194637, 917804, 581, 4893, 983616, 6571, 65545, 4888, 4157, 78048, 78049, - 78046, 78047, 0, 10119, 6415, 42893, 0, 69702, 0, 0, 11375, 64746, 2332, - 78063, 412, 78061, 64932, 42880, 43587, 0, 0, 0, 0, 65197, 78066, 12203, - 78064, 78065, 8913, 65854, 4875, 65811, 120381, 120389, 118888, 9344, - 8826, 120386, 120395, 13104, 74781, 11997, 120393, 78075, 0, 3134, 0, - 65696, 92331, 0, 66217, 0, 8334, 119344, 0, 3449, 0, 0, 78414, 78413, - 118950, 74011, 0, 0, 0, 0, 1908, 120167, 4328, 10734, 127014, 0, 127914, - 7804, 78272, 10811, 6250, 11339, 4914, 11367, 0, 78054, 4917, 74516, - 74208, 64285, 4912, 5464, 127836, 118893, 2361, 7971, 78072, 78073, - 55243, 78071, 0, 8086, 74317, 6707, 8319, 2312, 40977, 10960, 40962, - 8305, 12573, 983608, 40980, 983964, 13202, 0, 12582, 78282, 983048, - 69856, 42438, 55221, 6288, 78280, 127946, 5653, 42400, 10891, 7698, 5658, - 74045, 70039, 0, 0, 4913, 0, 983959, 71333, 42326, 128194, 12728, 92685, - 42478, 2327, 0, 12563, 42287, 12705, 0, 0, 12588, 8821, 6153, 2867, - 194708, 66312, 698, 128007, 194606, 10356, 70017, 194713, 651, 12641, 0, - 0, 0, 0, 41552, 65115, 78465, 78467, 78463, 78464, 128851, 78461, 194697, - 74356, 64945, 4716, 43277, 0, 78474, 12340, 120568, 0, 194700, 55264, - 41211, 120676, 8703, 5462, 917629, 983495, 10101, 0, 70049, 8479, 4151, - 41933, 0, 0, 66254, 120821, 0, 0, 128654, 0, 119194, 74050, 92701, 0, 0, - 0, 0, 0, 12278, 0, 0, 0, 2700, 12576, 7842, 12899, 0, 0, 2699, 0, 73845, - 2985, 92568, 126475, 917845, 12192, 119314, 0, 119312, 9827, 119310, - 119311, 119308, 119309, 119306, 11481, 41210, 119305, 0, 35, 78481, - 78482, 66694, 68479, 78477, 78478, 43596, 6090, 64257, 7812, 10534, 0, - 78485, 73848, 67975, 4272, 0, 40967, 40964, 917825, 12704, 78487, 43306, - 0, 64497, 12138, 7930, 0, 2292, 68216, 0, 917826, 5244, 4189, 94108, - 67596, 127504, 4188, 1879, 0, 968, 0, 43743, 0, 8873, 2279, 0, 917827, - 65555, 12574, 0, 0, 0, 74490, 127099, 43657, 0, 0, 0, 42682, 12578, - 12720, 0, 41227, 0, 12346, 127101, 64848, 0, 0, 7251, 0, 0, 118850, - 119141, 128546, 66015, 0, 959, 8885, 12564, 66457, 78808, 9469, 9632, - 92323, 74761, 64323, 127335, 0, 0, 0, 310, 0, 41281, 10976, 0, 71325, 0, - 74266, 10054, 6497, 8574, 0, 9012, 19958, 74420, 65089, 13215, 12730, - 65163, 74044, 374, 43195, 816, 120161, 0, 0, 41934, 7465, 0, 128168, - 983268, 4715, 6101, 94106, 41936, 0, 4879, 0, 65446, 0, 307, 127147, - 9585, 5374, 983267, 128059, 0, 0, 126618, 120390, 0, 65567, 120614, 1929, - 0, 12142, 0, 12236, 41419, 194618, 120610, 12982, 194623, 5378, 78791, - 128679, 41421, 0, 4462, 0, 126599, 128092, 821, 0, 2498, 5800, 120157, - 983115, 1760, 2421, 4469, 2324, 828, 3611, 78400, 757, 1185, 0, 78770, - 43597, 10628, 74808, 194572, 7999, 43971, 0, 0, 10634, 10942, 7713, 2348, - 0, 64374, 4380, 194608, 119044, 9982, 64324, 41240, 862, 65626, 78462, - 1810, 3673, 5137, 194617, 0, 7277, 65622, 0, 7566, 64688, 194593, 194592, - 78092, 74357, 194597, 4748, 92228, 194598, 194601, 42260, 5871, 119075, - 0, 74576, 44019, 0, 128189, 3967, 194604, 13137, 8775, 127945, 0, 2963, - 0, 8410, 4454, 723, 127882, 966, 4449, 92330, 92238, 0, 7819, 2320, - 194589, 339, 4968, 194590, 120399, 8075, 55276, 0, 8047, 0, 78827, 12634, - 41542, 78780, 7466, 6705, 12174, 42610, 0, 74452, 983763, 1584, 66645, - 6045, 6729, 120640, 65218, 11559, 0, 78062, 7537, 0, 11370, 0, 10330, 0, - 10394, 0, 74194, 0, 127929, 9780, 0, 13092, 194576, 77950, 194578, 7074, - 92648, 194579, 194582, 11414, 128868, 2531, 13034, 0, 0, 4211, 1259, - 7517, 0, 0, 194561, 40996, 13037, 7092, 641, 5219, 94034, 194566, 11064, - 41129, 0, 42850, 13035, 9075, 92387, 5466, 128153, 0, 64098, 65793, 4535, - 194573, 4271, 78417, 128357, 6769, 41410, 983452, 64262, 6767, 41407, 0, - 0, 6755, 118864, 9046, 127934, 126608, 0, 0, 0, 0, 67675, 0, 0, 0, 64338, - 2563, 13033, 247, 118915, 0, 12338, 4651, 69895, 11270, 0, 0, 11933, 0, - 0, 41903, 43447, 11001, 0, 42255, 0, 92661, 69821, 41905, 0, 0, 10775, - 9793, 5009, 0, 42269, 64587, 983063, 42535, 69812, 64529, 41408, 42853, - 3877, 120795, 42674, 8147, 43566, 119021, 983776, 10236, 65918, 43782, 0, - 0, 64506, 69652, 118921, 4747, 128058, 69844, 43200, 5832, 0, 0, 5141, - 42600, 0, 43203, 0, 983799, 43286, 0, 128211, 43778, 0, 41305, 78776, - 43781, 11303, 65547, 0, 7031, 859, 0, 0, 0, 6059, 126985, 55235, 0, 8535, - 0, 65196, 194787, 66032, 11488, 120481, 120786, 42233, 64140, 9946, - 63885, 194792, 11822, 0, 43189, 983898, 0, 1788, 1579, 120482, 71298, 0, - 0, 0, 9028, 119571, 69234, 94055, 0, 1285, 64882, 41242, 70086, 0, 12640, - 0, 7401, 0, 12625, 68198, 0, 70082, 3940, 41597, 43754, 3396, 12642, - 8665, 0, 0, 12630, 1653, 917815, 10153, 0, 6166, 120516, 118989, 0, 8815, - 66673, 65046, 9285, 913, 42259, 119317, 119318, 2142, 68454, 42485, - 94012, 7878, 8211, 42293, 64377, 0, 92643, 0, 194673, 12032, 0, 9725, 0, + 12420, 4024, 194730, 41054, 1078, 9757, 69736, 41057, 68307, 0, 0, 0, + 983791, 92210, 92411, 0, 41496, 0, 9165, 1572, 11911, 124990, 118842, + 2346, 13270, 8958, 0, 9646, 3773, 43183, 6401, 5831, 0, 0, 13043, 8056, + 92494, 65681, 208, 127382, 41514, 0, 0, 0, 10699, 6408, 92227, 7825, + 5661, 0, 120630, 3603, 41109, 2398, 3548, 126596, 128434, 119933, 0, + 3115, 9918, 127823, 8294, 42912, 0, 0, 194726, 4876, 65804, 0, 0, 43468, + 983274, 41558, 41471, 73950, 8158, 9944, 41472, 120298, 13051, 78689, + 3143, 194674, 6701, 41559, 1896, 66256, 13052, 194680, 5665, 78594, + 119071, 7025, 63974, 0, 74352, 74161, 4154, 9863, 43550, 12310, 5662, + 42382, 1564, 73924, 1121, 78319, 63959, 0, 9942, 13231, 983578, 64752, + 4732, 194666, 11596, 78142, 65187, 1626, 63983, 10110, 64772, 42024, + 6420, 42028, 92294, 10509, 2795, 4910, 129193, 69231, 64753, 6275, 93957, + 118830, 63978, 11044, 3229, 6423, 42774, 0, 0, 68526, 12823, 2331, + 127788, 7085, 6137, 0, 7524, 0, 917809, 8346, 128438, 8338, 128315, + 65043, 983237, 822, 70412, 9903, 64721, 42722, 69877, 194659, 78655, + 66882, 194660, 78484, 41265, 5311, 1795, 965, 118791, 10587, 73931, + 11278, 78632, 194640, 0, 12946, 194641, 71921, 120349, 6294, 3144, + 194648, 127967, 65019, 194649, 73990, 65111, 983960, 748, 41067, 2330, + 535, 3148, 12375, 78799, 194629, 10556, 2475, 12388, 4889, 8968, 67863, + 3593, 74076, 0, 2342, 0, 126541, 65206, 4894, 194635, 4890, 194637, + 129147, 581, 4893, 42929, 6571, 65545, 4888, 4157, 78048, 78049, 64651, + 78047, 0, 10119, 6415, 42893, 0, 69702, 983937, 0, 11375, 64746, 2332, + 78063, 412, 78061, 42928, 42880, 43587, 0, 0, 0, 70461, 65197, 78066, + 12203, 78064, 78065, 8913, 65854, 4875, 65811, 120381, 120389, 71854, + 9344, 8826, 92916, 120395, 13104, 74781, 11997, 120393, 78075, 0, 3134, + 0, 65696, 72432, 0, 66217, 0, 8334, 92755, 0, 3449, 0, 0, 78414, 78413, + 118950, 66405, 70430, 0, 0, 0, 1908, 120167, 4328, 10734, 127014, 0, + 127914, 7804, 78272, 10811, 6250, 11339, 4914, 11367, 125001, 78054, + 4917, 74516, 74208, 64285, 4912, 5464, 127836, 118893, 2361, 7971, 78072, + 78073, 55243, 78071, 0, 8086, 74317, 6707, 8319, 2312, 40977, 10960, + 40962, 8305, 12573, 983608, 40980, 983964, 13202, 127816, 12582, 78282, + 983048, 69856, 42438, 55221, 6288, 78280, 127946, 5653, 42400, 10891, + 7698, 5658, 70401, 70039, 0, 70460, 4913, 71060, 128562, 71333, 42326, + 128194, 12728, 92685, 42478, 2327, 0, 12563, 42287, 12705, 0, 120824, + 12588, 8821, 6153, 2867, 194708, 66312, 698, 127059, 194606, 10356, + 70017, 194713, 651, 12641, 0, 125098, 120710, 129064, 41552, 65115, + 78465, 78467, 78463, 78464, 128851, 78461, 92960, 66927, 64945, 4716, + 43277, 0, 78474, 12340, 120568, 0, 194700, 55264, 41211, 120676, 8703, + 5462, 120793, 128944, 10101, 0, 70049, 8479, 4151, 41933, 0, 0, 66254, + 120821, 68497, 0, 128654, 113799, 119194, 74050, 42651, 0, 0, 0, 129151, + 0, 12278, 127167, 128405, 0, 2700, 12576, 7842, 12899, 0, 0, 2699, 0, + 73845, 2985, 92568, 68648, 917845, 12192, 119314, 0, 66489, 9827, 119310, + 8609, 119308, 67426, 119306, 11481, 41210, 119305, 0, 35, 70838, 67431, + 66694, 68479, 78477, 67428, 43596, 6090, 64257, 7812, 10534, 0, 78485, + 73848, 67975, 4272, 78321, 40967, 40964, 917825, 12704, 78487, 43306, 0, + 64497, 12138, 7930, 0, 2292, 68216, 194871, 917826, 5244, 4189, 94108, + 67596, 127504, 4188, 1879, 70463, 968, 0, 43743, 0, 8873, 2279, 0, + 917827, 65555, 12574, 0, 92749, 92753, 74490, 127099, 11838, 983920, 0, + 0, 42682, 12578, 12720, 0, 41227, 0, 12346, 127101, 64848, 69950, 917950, + 7251, 0, 120382, 118850, 119141, 128546, 66015, 67332, 959, 8885, 12564, + 66457, 78808, 9469, 9632, 92323, 74761, 64323, 127335, 0, 0, 11132, 310, + 0, 41281, 10976, 0, 71325, 128364, 74266, 10054, 6497, 8574, 0, 9012, + 19958, 74420, 65089, 13215, 12730, 65163, 74044, 374, 43195, 816, 120161, + 0, 0, 41934, 7465, 74615, 92752, 983268, 4715, 6101, 71089, 41936, 0, + 4879, 0, 65446, 0, 307, 127147, 9585, 5374, 983267, 128059, 0, 129189, + 126618, 120390, 129146, 65567, 120614, 1929, 0, 12142, 0, 12236, 41419, + 194618, 120610, 12982, 128228, 5378, 78791, 128679, 41421, 195075, 4462, + 0, 126599, 128092, 821, 0, 2498, 5800, 120157, 67758, 1760, 2421, 4469, + 2324, 828, 3611, 78400, 757, 1185, 0, 78770, 43597, 10628, 74808, 194572, + 7999, 43971, 11217, 0, 10634, 10942, 7713, 2348, 0, 64374, 4380, 194608, + 119044, 9982, 64324, 41240, 862, 65626, 78462, 1810, 3673, 5137, 194617, + 0, 7277, 65622, 65069, 7566, 64688, 67143, 194592, 78092, 70422, 128385, + 4748, 92228, 129185, 194601, 42260, 5871, 119075, 0, 74576, 44019, 0, + 128189, 3967, 71098, 13137, 8775, 127945, 0, 2963, 0, 8410, 4454, 723, + 127882, 966, 4449, 92330, 92238, 128428, 7819, 2320, 194589, 339, 4968, + 194590, 120399, 8075, 55276, 0, 8047, 0, 78827, 12634, 41542, 78780, + 7466, 6705, 12174, 42610, 0, 74452, 983763, 1584, 66645, 6045, 6729, + 120640, 65218, 11559, 0, 78062, 7537, 124991, 11370, 0, 10330, 0, 10394, + 0, 74194, 0, 127929, 9780, 0, 11117, 194576, 77950, 194578, 7074, 92648, + 194579, 194582, 11414, 124960, 2531, 13034, 0, 0, 4211, 1259, 7517, + 70866, 70198, 194561, 40996, 13037, 7092, 641, 5219, 94034, 194566, + 11064, 41129, 0, 42850, 13035, 9075, 92387, 5466, 128153, 0, 64098, + 65793, 4535, 194573, 4271, 78417, 128357, 6769, 41410, 194675, 64262, + 6767, 41407, 66273, 917816, 6755, 118864, 9046, 127934, 126608, 70830, 0, + 0, 0, 67675, 983694, 0, 0, 64338, 2563, 13033, 247, 118915, 0, 12338, + 4651, 67355, 11270, 0, 74630, 11933, 0, 0, 41903, 43447, 11001, 73827, + 42255, 113760, 92661, 69821, 41905, 67350, 0, 10775, 9793, 5009, 128774, + 42269, 64587, 983063, 42535, 69812, 64529, 41408, 42853, 3877, 120795, + 42674, 8147, 43566, 119021, 67342, 10236, 65918, 43782, 0, 127556, 64506, + 69652, 118921, 4747, 128058, 69844, 43200, 5832, 71253, 0, 5141, 42600, + 71866, 43203, 127208, 120129, 43286, 0, 128211, 43778, 7657, 41305, + 78776, 43781, 11303, 65547, 128609, 7031, 859, 128488, 0, 0, 6059, + 126985, 55235, 194817, 8535, 128638, 65196, 125084, 66032, 11488, 120481, + 120786, 42233, 64140, 9946, 7667, 194792, 11822, 0, 11135, 983898, 0, + 1788, 1579, 120482, 71298, 0, 983459, 0, 9028, 119571, 69234, 71061, + 194738, 1285, 64882, 41242, 70086, 129041, 12640, 0, 7401, 0, 12625, + 68198, 0, 70082, 3940, 41597, 43754, 3396, 12642, 8665, 983610, 983609, + 12630, 1653, 917815, 10153, 0, 6166, 70825, 118989, 0, 8815, 66673, + 65046, 9285, 913, 42259, 11180, 119318, 2142, 68454, 42485, 94012, 7878, + 8211, 42293, 64377, 120478, 92643, 0, 194673, 12032, 0, 9725, 983489, 78431, 5263, 12818, 78430, 41939, 10022, 65387, 78419, 42777, 10139, 980, - 43698, 65386, 2208, 0, 43701, 43198, 7184, 120673, 194797, 917819, 10085, - 119992, 0, 119993, 6634, 92373, 0, 119323, 8072, 119321, 43700, 0, 8872, - 7783, 917992, 12398, 8237, 0, 0, 12395, 0, 126977, 120565, 9914, 2217, - 917854, 73975, 6367, 6351, 66688, 0, 78107, 0, 64735, 41243, 92199, 7808, - 1829, 0, 41937, 4358, 43272, 6353, 0, 0, 120422, 0, 1710, 0, 0, 65607, 0, - 49, 6627, 0, 6258, 10683, 78672, 9741, 78329, 5649, 78441, 43443, 64418, - 1643, 65213, 8405, 3470, 128225, 13213, 42452, 78331, 120664, 78445, 0, - 1072, 78457, 78452, 78454, 6576, 41988, 41132, 65675, 1080, 120002, 9886, - 55225, 1101, 68404, 12309, 55227, 0, 12632, 1086, 1869, 78685, 7680, 0, - 65458, 120714, 12639, 3380, 8123, 1091, 12638, 7977, 4501, 41099, 0, - 66309, 0, 0, 1494, 983146, 126613, 0, 11693, 126513, 10494, 92655, 65872, - 12363, 11386, 0, 0, 0, 0, 64582, 0, 73794, 0, 8022, 0, 120462, 74106, - 12413, 94069, 917994, 917993, 917995, 5570, 1881, 7210, 0, 1012, 43752, - 0, 120709, 7208, 66442, 5569, 983242, 42339, 0, 6063, 0, 78383, 119594, - 6053, 65602, 0, 92201, 64727, 9160, 194827, 0, 0, 92180, 10503, 118810, - 6055, 3870, 4279, 8490, 120114, 4319, 64786, 8602, 120110, 11326, 92204, - 983116, 0, 120119, 78333, 120117, 120118, 120099, 120100, 65087, 5571, - 3674, 9740, 9121, 5568, 120107, 120108, 42085, 10107, 42159, 42870, - 120101, 589, 7050, 983800, 43281, 10233, 41263, 66251, 65729, 66253, - 126497, 74099, 42645, 0, 194815, 8583, 0, 5847, 6928, 128074, 0, 0, 0, 0, - 66592, 12204, 917962, 19966, 77856, 42561, 120626, 983251, 0, 8120, - 120701, 0, 0, 128012, 41063, 0, 10664, 0, 8369, 0, 4551, 194964, 3369, 0, - 0, 9673, 66334, 65580, 10478, 118960, 12517, 557, 9457, 12034, 983671, - 6355, 12519, 41004, 0, 195025, 74094, 0, 0, 77970, 983560, 0, 128175, - 12111, 3927, 0, 12515, 1474, 67893, 5492, 6923, 92281, 10441, 73836, 0, - 43990, 5493, 0, 74319, 0, 66635, 12019, 0, 1618, 0, 120474, 9645, 10430, - 917959, 5853, 13063, 10363, 0, 12956, 128169, 120729, 11314, 917582, - 12060, 0, 78392, 12826, 6329, 0, 10514, 65517, 74395, 2707, 8309, 0, - 127054, 78398, 43570, 2697, 43420, 78396, 127057, 2695, 42171, 0, 0, 0, - 67617, 118971, 0, 2693, 12125, 12766, 0, 1164, 128817, 0, 41918, 983168, - 127542, 8687, 66009, 12178, 7053, 128001, 7469, 0, 5248, 12218, 120538, - 6427, 42884, 41123, 0, 0, 42873, 41126, 9991, 41128, 74371, 127031, 0, - 9873, 0, 42877, 7994, 64762, 2053, 42843, 6591, 9340, 0, 1589, 0, 296, - 74438, 78852, 0, 67841, 74370, 0, 8922, 128068, 74600, 12700, 74836, 0, - 12579, 0, 12575, 6416, 5656, 2891, 13262, 65590, 5299, 0, 11473, 5449, - 1252, 0, 78404, 41431, 74369, 65373, 5295, 917569, 74114, 1223, 1642, - 174, 78399, 883, 4161, 12691, 42603, 41413, 3212, 41459, 3211, 74810, - 41425, 127029, 78412, 74450, 9728, 3846, 8070, 6150, 6636, 4370, 0, 0, - 74178, 74587, 74117, 0, 0, 0, 4986, 12189, 0, 67648, 120499, 94001, 4257, - 12104, 77942, 6220, 9004, 65561, 0, 77949, 0, 68135, 917576, 77946, 0, - 69679, 69684, 9890, 78561, 12971, 78453, 92556, 73898, 11979, 70051, - 118900, 917894, 0, 9635, 12600, 8871, 0, 0, 0, 6469, 74227, 0, 65304, - 4679, 10230, 64300, 64867, 3427, 4240, 0, 0, 0, 0, 42916, 0, 0, 0, 7282, - 78728, 65733, 4445, 127138, 128082, 3494, 74606, 6555, 0, 77976, 0, 0, - 78566, 0, 983189, 65898, 983244, 65312, 5447, 0, 12895, 65593, 4010, 0, - 41106, 0, 64448, 0, 41105, 0, 65820, 6232, 0, 128280, 0, 43608, 119091, - 0, 6538, 4335, 78364, 3941, 41122, 11061, 78363, 64892, 9113, 1954, - 12155, 983674, 42878, 11500, 0, 0, 74578, 0, 65832, 0, 0, 0, 77975, - 119230, 4586, 0, 350, 10951, 0, 509, 0, 0, 92307, 0, 0, 5133, 0, 0, 9500, - 0, 4957, 64741, 2422, 2212, 983080, 0, 0, 2496, 11516, 944, 118851, 3890, - 12168, 1438, 0, 983117, 0, 41947, 1220, 120828, 128555, 0, 0, 1571, - 42630, 41949, 42805, 8270, 943, 564, 0, 312, 41980, 983944, 0, 78120, - 8877, 269, 4429, 6272, 9617, 1460, 6954, 78657, 41120, 65121, 10862, - 6060, 41119, 41416, 74355, 4173, 0, 0, 0, 1906, 917986, 11532, 74073, - 127338, 0, 1985, 6296, 9582, 917895, 64287, 0, 78115, 11428, 1730, 2457, - 917808, 19918, 10469, 0, 0, 7703, 8840, 8035, 0, 0, 92230, 0, 6129, 0, - 128528, 128268, 0, 7874, 8681, 119092, 0, 13136, 0, 0, 70102, 63886, - 118881, 9605, 71308, 13220, 128776, 120274, 5514, 0, 9228, 0, 0, 0, 5240, - 9811, 10012, 3096, 0, 0, 983351, 66676, 65873, 0, 0, 0, 9501, 0, 1272, - 64536, 65465, 64654, 7467, 0, 1467, 10158, 10040, 0, 9519, 0, 917812, 0, - 118899, 12193, 0, 0, 0, 0, 983353, 19935, 0, 92162, 69676, 0, 0, 0, 5275, - 0, 0, 8637, 0, 0, 3789, 63880, 11471, 43554, 65862, 11474, 66332, 66603, - 128138, 2426, 12042, 92194, 983911, 9537, 3961, 12115, 77953, 2605, 4500, - 64561, 55224, 4981, 0, 0, 63876, 11667, 42686, 77973, 42362, 64686, 4499, - 41649, 7589, 0, 0, 3237, 0, 68215, 917904, 8541, 78298, 70034, 41866, 0, - 0, 0, 0, 69924, 43555, 2823, 9559, 10060, 41940, 8299, 41945, 7132, - 41941, 3308, 7190, 64880, 8614, 65220, 41493, 0, 41699, 10762, 43780, - 12999, 0, 0, 8106, 4128, 0, 6274, 4494, 0, 4012, 10395, 983591, 43633, - 65447, 126511, 0, 11004, 695, 739, 696, 7611, 0, 42755, 74802, 9227, - 7506, 7510, 69937, 691, 738, 7511, 7512, 7515, 3868, 688, 41847, 690, - 2548, 737, 974, 8003, 7406, 917911, 0, 128688, 3985, 917912, 65860, - 63921, 7051, 69777, 4682, 917805, 12809, 6406, 4685, 92505, 10879, 10347, - 4680, 6341, 0, 3851, 8132, 74325, 0, 917907, 0, 41958, 119176, 917908, 0, - 0, 42657, 92468, 7643, 42373, 11714, 67587, 43568, 983175, 11717, 7650, - 10594, 64951, 7647, 7649, 128155, 7646, 0, 78082, 9651, 0, 3891, 0, 0, - 2337, 1735, 74324, 67860, 2363, 983135, 0, 43561, 0, 0, 74146, 1860, - 7495, 7580, 5812, 7497, 7584, 119140, 127853, 0, 120347, 7727, 0, 8498, - 69818, 8949, 3065, 42719, 7135, 1569, 92375, 12534, 12124, 7690, 0, - 12533, 983879, 6418, 4543, 78086, 6969, 0, 74800, 0, 67974, 11980, - 128650, 983801, 63894, 120760, 12282, 66192, 0, 74592, 8850, 74275, 9238, - 10617, 917545, 0, 92625, 0, 12791, 0, 0, 127843, 4447, 73732, 12793, - 12900, 92377, 10950, 0, 78087, 12790, 41400, 119128, 66607, 12792, 42232, - 194938, 1744, 12789, 10366, 12317, 41310, 983869, 41399, 0, 0, 55258, 0, - 12690, 0, 0, 43672, 127840, 41652, 2974, 9010, 11315, 0, 278, 0, 41405, - 119254, 0, 10077, 63853, 74557, 42586, 0, 0, 6002, 0, 43553, 0, 67903, 0, - 12787, 41308, 7934, 65306, 0, 0, 0, 8646, 983186, 77829, 71360, 0, 6413, - 6550, 0, 1940, 0, 43637, 220, 65193, 43551, 10678, 10044, 128322, 0, 0, - 68659, 6403, 5707, 10393, 127532, 0, 66614, 0, 0, 0, 10297, 0, 3742, 0, - 3959, 0, 0, 0, 2467, 0, 6003, 63844, 6663, 8040, 0, 43758, 4182, 78171, - 4676, 120501, 0, 0, 2510, 0, 10208, 78168, 92361, 11540, 43546, 6692, 0, - 41060, 0, 4668, 9083, 0, 0, 78144, 1559, 63831, 9677, 120260, 0, 65256, - 0, 74070, 0, 0, 365, 12056, 43027, 120423, 41716, 128236, 0, 120472, - 5516, 2845, 7717, 8036, 41717, 73827, 544, 12045, 6278, 0, 5515, 0, 0, - 983051, 65339, 43221, 2211, 0, 5517, 0, 0, 74841, 67884, 0, 67890, 67885, - 67880, 67881, 67882, 67883, 0, 0, 67879, 127188, 1902, 67887, 9638, - 12976, 126546, 12483, 12368, 41769, 42726, 41765, 7361, 6667, 67874, - 7556, 67878, 74351, 11264, 989, 42677, 67889, 0, 1311, 917966, 4326, - 11000, 63824, 13068, 10932, 128880, 6917, 78155, 0, 949, 78162, 0, 6148, - 8605, 42253, 78177, 0, 0, 42715, 0, 0, 0, 63871, 0, 41796, 1269, 6530, 0, - 65057, 0, 5144, 12221, 42716, 0, 4431, 4331, 983729, 128675, 41834, 5279, - 0, 10336, 8312, 0, 42701, 128825, 0, 78165, 66036, 0, 0, 6428, 42270, 0, - 983596, 43059, 42666, 5256, 1067, 255, 12131, 983722, 9493, 983968, - 41014, 11793, 194920, 0, 74394, 43460, 10653, 42723, 983854, 119632, 0, - 6560, 7016, 74274, 983615, 43556, 3929, 67977, 6614, 2768, 92504, 9746, - 5135, 11811, 12796, 11953, 0, 69761, 5139, 346, 74303, 6305, 12795, 4675, - 5168, 78552, 127753, 74315, 74361, 8253, 8817, 1136, 0, 43563, 92232, 0, - 194750, 7392, 8230, 9365, 0, 0, 983607, 0, 0, 4041, 0, 2357, 43240, - 12786, 229, 119885, 119884, 44004, 7142, 119881, 12350, 65554, 119882, - 119877, 119876, 12785, 63863, 43795, 7770, 10712, 64853, 12686, 118916, - 42375, 0, 127238, 66352, 10470, 0, 11059, 10791, 917944, 450, 119328, 0, - 10432, 12097, 5450, 64691, 1233, 0, 44009, 78284, 66338, 0, 0, 1839, - 118799, 983219, 10927, 1701, 983664, 2388, 41749, 41761, 5453, 8361, - 119865, 41758, 5444, 41763, 64889, 7143, 92493, 78677, 0, 92429, 78174, - 66432, 8801, 3053, 4340, 983044, 0, 65812, 917831, 0, 41824, 67985, - 120203, 194800, 194803, 42700, 194805, 127980, 194807, 78676, 92356, - 194808, 0, 0, 4493, 4336, 0, 2314, 43602, 78826, 119325, 194811, 42439, - 64638, 42327, 43528, 4489, 71331, 0, 194793, 1912, 42385, 10306, 10370, - 0, 0, 8867, 10250, 10258, 2712, 1635, 78821, 1410, 92671, 983250, 118878, - 0, 0, 9919, 120528, 559, 128157, 41825, 127975, 78188, 4892, 74016, - 194781, 6542, 41957, 128865, 5777, 0, 759, 65749, 2079, 65248, 12788, - 64487, 64552, 0, 10223, 42062, 0, 0, 126573, 3668, 65754, 43560, 12226, - 67991, 65149, 2340, 41959, 194786, 194785, 194788, 43618, 65747, 10937, - 2962, 0, 2321, 3587, 65745, 92436, 8921, 9952, 0, 0, 42714, 9951, 43409, + 43698, 65386, 2208, 983454, 43701, 43198, 7184, 92542, 128423, 128875, + 10085, 113812, 0, 67394, 6634, 92373, 125085, 119323, 8072, 119321, + 43700, 0, 8872, 7783, 917991, 12398, 8237, 0, 0, 12395, 0, 126977, + 120565, 9914, 2217, 194586, 73975, 6367, 6351, 66688, 92740, 78107, 0, + 64735, 41243, 92199, 7808, 1829, 0, 41937, 4358, 43272, 6353, 0, 0, + 120422, 93045, 1710, 120140, 0, 65607, 67234, 49, 6627, 0, 6258, 10683, + 78672, 9741, 78329, 5649, 78441, 43443, 64418, 1643, 65213, 8405, 3470, + 67244, 13213, 42452, 78331, 120664, 78445, 125124, 1072, 78457, 78452, + 78454, 6576, 41988, 41132, 65675, 1080, 70824, 9886, 55225, 1101, 68404, + 12309, 55227, 71082, 12632, 1086, 1869, 78685, 7680, 0, 65458, 120714, + 12639, 3380, 8123, 1091, 12638, 7977, 4501, 41099, 0, 66309, 120141, + 92758, 1494, 113716, 126613, 0, 11693, 71255, 10494, 92655, 65872, 12363, + 11386, 113727, 0, 0, 0, 64582, 0, 73794, 67395, 8022, 0, 120462, 74106, + 12413, 66883, 917994, 93035, 917995, 5570, 1881, 7210, 120425, 1012, + 43752, 0, 120709, 7208, 66442, 5569, 983242, 42339, 92997, 6063, 67888, + 69981, 119594, 6053, 65602, 0, 92201, 64727, 9160, 128397, 0, 92905, + 92180, 10503, 70387, 6055, 3870, 4279, 8490, 120114, 4319, 64786, 8602, + 120110, 11326, 92204, 983116, 0, 120119, 78333, 120117, 120118, 120099, + 92385, 65087, 5571, 3674, 9740, 9121, 5568, 120107, 120108, 42085, 10107, + 42159, 42870, 113700, 589, 7050, 983800, 43281, 10233, 41263, 66251, + 65729, 66253, 126497, 74099, 42645, 0, 128424, 8583, 0, 5847, 6928, + 128074, 0, 0, 0, 0, 66592, 12204, 917962, 19966, 77856, 42561, 120626, + 129170, 66854, 8120, 120701, 0, 0, 128012, 41063, 0, 10664, 0, 8369, 0, + 4551, 194964, 3369, 983739, 129026, 9673, 66334, 65580, 10478, 118960, + 12517, 557, 9457, 12034, 68496, 6355, 12519, 41004, 0, 195025, 74094, 0, + 0, 77970, 92171, 127219, 128175, 12111, 3927, 0, 12515, 1474, 67893, + 5492, 6923, 92281, 10441, 73836, 0, 43990, 5493, 0, 74319, 0, 66635, + 12019, 0, 1618, 0, 120474, 9645, 10430, 126636, 5853, 13063, 10363, 0, + 12956, 113666, 120729, 11314, 917582, 12060, 0, 78392, 12826, 6329, 0, + 10514, 65517, 74395, 2707, 8309, 0, 127054, 78398, 43570, 2697, 43420, + 78396, 127057, 2695, 42171, 70809, 68334, 0, 67617, 118971, 0, 2693, + 12125, 12766, 0, 1164, 113729, 0, 41918, 77849, 67150, 8687, 66009, + 12178, 7053, 128001, 7469, 0, 5248, 12218, 69988, 6427, 42884, 41123, + 11176, 0, 42873, 41126, 9991, 41128, 74371, 127031, 0, 9873, 0, 42877, + 7994, 64762, 2053, 42843, 6591, 9340, 0, 1589, 128691, 296, 67712, 78852, + 0, 67841, 74370, 128504, 8922, 128068, 43829, 12700, 74836, 0, 12579, 0, + 12575, 6416, 5656, 2891, 13262, 65590, 5299, 0, 11473, 5449, 1252, 0, + 78404, 41431, 74369, 65373, 5295, 917569, 68320, 1223, 1642, 174, 78399, + 883, 4161, 12691, 42603, 41413, 3212, 41459, 3211, 74810, 41425, 74598, + 78412, 74450, 9728, 3846, 8070, 6150, 6636, 4370, 0, 0, 74178, 74587, + 74117, 195094, 0, 0, 4986, 12189, 127512, 67648, 120499, 94001, 4257, + 12104, 71176, 6220, 9004, 65561, 983881, 77949, 0, 68135, 917576, 77946, + 0, 69679, 69684, 9890, 78561, 12971, 78453, 92556, 73898, 11979, 70051, + 71897, 119552, 0, 9635, 12600, 8871, 67366, 68491, 0, 6469, 74227, + 118900, 65304, 4679, 10230, 64300, 64867, 3427, 4240, 67376, 67375, + 67374, 67373, 42916, 129155, 128279, 67377, 7282, 78728, 65733, 4445, + 67372, 67371, 3494, 67369, 6555, 129148, 77976, 0, 0, 78566, 0, 983189, + 65898, 983244, 65312, 5447, 0, 12895, 65593, 4010, 0, 41106, 74357, + 64448, 93994, 41105, 74114, 65820, 6232, 68233, 128280, 0, 43608, 119091, + 124962, 6538, 4335, 78364, 3941, 41122, 11061, 78363, 64892, 9113, 1954, + 12155, 983674, 42878, 11500, 67405, 0, 74578, 0, 65832, 128667, 0, 70789, + 67333, 119230, 4586, 0, 350, 10951, 0, 509, 67336, 0, 92307, 0, 0, 5133, + 67382, 0, 9500, 0, 4957, 64741, 2422, 2212, 983080, 67381, 67380, 2496, + 11516, 944, 78891, 3890, 12168, 1438, 0, 68335, 70003, 41947, 1220, + 120828, 128555, 70854, 74058, 1571, 42630, 41949, 42805, 8270, 943, 564, + 0, 312, 41980, 983944, 0, 70797, 8877, 269, 4429, 6272, 9617, 1460, 6954, + 78657, 41120, 65121, 10862, 6060, 41119, 41416, 74355, 4173, 0, 0, 0, + 1906, 917898, 11532, 74073, 127338, 0, 1985, 6296, 9582, 917895, 64287, + 128406, 78115, 11428, 1730, 2457, 917808, 19918, 10469, 0, 983079, 7703, + 8840, 8035, 0, 0, 92230, 0, 6129, 128437, 78586, 128268, 0, 7874, 8681, + 119092, 11206, 13136, 0, 0, 70102, 63886, 70450, 9605, 71308, 13220, + 67348, 67354, 5514, 0, 9228, 67349, 67356, 67346, 5240, 9811, 10012, + 3096, 0, 0, 74526, 66676, 65873, 0, 0, 0, 9501, 917959, 1272, 64536, + 65465, 64654, 7467, 0, 1467, 10158, 10040, 0, 9519, 120270, 917812, 0, + 118899, 12193, 0, 0, 0, 0, 983353, 19935, 120733, 92162, 69676, 0, + 917811, 93057, 5275, 194596, 128632, 8637, 129082, 0, 3789, 63880, 11471, + 43554, 65862, 11474, 66332, 66603, 128138, 2426, 12042, 92194, 983911, + 9537, 3961, 12115, 77953, 2605, 4500, 64561, 55224, 4981, 74644, 0, + 41646, 11667, 42686, 77973, 42362, 64686, 4499, 41649, 7589, 128776, 0, + 3237, 0, 66895, 68296, 8541, 78298, 70034, 41866, 0, 0, 94056, 11174, + 69924, 43555, 2823, 9559, 10060, 41940, 8299, 41945, 7132, 41941, 3308, + 7190, 64880, 8614, 65220, 41493, 0, 41699, 10762, 43780, 12999, 0, + 128494, 8106, 4128, 0, 6274, 4494, 0, 4012, 10395, 983591, 43633, 65447, + 126511, 0, 11004, 695, 739, 696, 7611, 0, 42755, 74802, 9227, 7506, 7510, + 69937, 691, 738, 7511, 7512, 7515, 3868, 688, 41847, 690, 2548, 737, 974, + 8003, 7406, 127353, 0, 128688, 3985, 66425, 65860, 41851, 7051, 69777, + 4682, 71873, 12809, 6406, 4685, 92505, 10879, 10347, 4680, 6341, 0, 3851, + 8132, 74325, 0, 917907, 127948, 41958, 119176, 917908, 194855, 0, 42657, + 71075, 7643, 42373, 11714, 67587, 43568, 983175, 11717, 7650, 10594, + 64951, 7647, 7649, 128155, 7646, 0, 78082, 9651, 126475, 3891, 127205, 0, + 2337, 1735, 74324, 11134, 2363, 125061, 92443, 43561, 67706, 128032, + 74146, 1860, 7495, 7580, 5812, 7497, 7584, 119140, 127853, 78753, 120347, + 7727, 0, 8498, 69818, 8949, 3065, 42719, 7135, 1569, 92375, 12534, 12124, + 7690, 0, 12533, 983879, 6418, 4543, 78086, 6969, 0, 74800, 71051, 67974, + 11980, 128650, 983801, 63894, 120760, 12282, 66192, 0, 74592, 8850, + 74275, 9238, 10617, 917545, 917909, 92625, 917801, 12791, 0, 94069, + 127843, 4447, 71065, 12793, 12900, 92377, 10950, 983447, 74639, 12790, + 41400, 119128, 66607, 12792, 42232, 194938, 1744, 12789, 10366, 12317, + 41310, 120730, 41399, 0, 0, 55258, 0, 12690, 0, 0, 43672, 127840, 41652, + 2974, 9010, 11315, 0, 278, 0, 41405, 43871, 0, 10077, 63853, 74557, + 42586, 0, 0, 6002, 67335, 43553, 11189, 67338, 67337, 12787, 41308, 7934, + 65306, 0, 128421, 0, 8646, 983186, 77829, 71360, 0, 6413, 6550, 113759, + 1940, 0, 43637, 220, 65193, 43551, 10678, 10044, 128322, 128121, 983816, + 68290, 6403, 5707, 10393, 127532, 0, 66614, 0, 0, 0, 10297, 0, 3742, + 67331, 3959, 0, 120466, 0, 2467, 69739, 6003, 63844, 6663, 8040, 0, + 43758, 4182, 78171, 4676, 120501, 9210, 0, 2510, 0, 10208, 78168, 92361, + 11540, 43546, 6692, 6837, 41060, 0, 4668, 9083, 0, 0, 78144, 1559, 63831, + 9677, 67340, 67347, 65256, 67345, 67344, 0, 0, 365, 12056, 43027, 120423, + 41716, 128236, 67352, 67351, 5516, 2845, 7717, 8036, 41717, 67353, 544, + 12045, 6278, 74632, 5515, 0, 0, 983051, 65339, 43221, 2211, 0, 5517, + 70116, 74225, 74841, 67884, 128414, 67890, 67885, 67880, 67881, 67882, + 67883, 0, 118883, 67879, 127188, 1902, 67887, 9638, 12976, 126546, 12483, + 12368, 41769, 42726, 41765, 7361, 6667, 67874, 7556, 67878, 74351, 11264, + 989, 42677, 67889, 93040, 1311, 128949, 4326, 11000, 63824, 13068, 10932, + 128880, 6917, 78155, 983615, 949, 77882, 0, 6148, 8605, 42253, 78177, + 66906, 0, 42715, 0, 0, 0, 63871, 0, 41796, 1269, 6530, 0, 65057, 70493, + 5144, 12221, 42716, 68299, 4431, 4331, 983729, 128675, 41834, 5279, 0, + 10336, 8312, 0, 42701, 92959, 0, 78165, 66036, 70166, 124935, 6428, + 42270, 0, 983596, 43059, 42666, 5256, 1067, 255, 12131, 128742, 9493, + 983968, 41014, 11793, 194920, 0, 74394, 43460, 10653, 42723, 983854, + 119632, 70427, 6560, 7016, 74274, 69986, 43556, 3929, 67977, 6614, 2768, + 92504, 9746, 5135, 11811, 12796, 11953, 0, 69761, 5139, 346, 74303, 6305, + 12795, 4675, 5168, 78552, 43845, 74315, 74361, 8253, 8817, 1136, 0, + 43563, 92232, 128914, 66410, 7392, 8230, 9365, 71194, 0, 983607, 66915, + 128402, 4041, 0, 2357, 43240, 12786, 229, 43834, 119884, 44004, 7142, + 119881, 12350, 65554, 119882, 119877, 119876, 12785, 63863, 43795, 7770, + 10712, 64853, 12686, 43831, 42375, 0, 127238, 66352, 10470, 0, 11059, + 10791, 917944, 450, 119328, 0, 10432, 12097, 5450, 64691, 1233, 0, 44009, + 78284, 66338, 66395, 0, 1839, 118799, 983219, 10927, 1701, 983664, 2388, + 41749, 41761, 5453, 8361, 119865, 895, 5444, 41763, 64889, 7143, 92493, + 78677, 983137, 92429, 69983, 66432, 8801, 3053, 4340, 983044, 0, 65812, + 120675, 70001, 41824, 67985, 120203, 92600, 127053, 42700, 194805, + 127980, 194807, 78676, 92356, 194808, 127844, 0, 4493, 4336, 129171, + 2314, 43602, 78826, 119325, 194811, 42439, 64638, 42327, 43528, 4489, + 71331, 128006, 194793, 1912, 42385, 10306, 10370, 0, 0, 8867, 10250, + 10258, 2712, 1635, 71064, 1410, 78763, 983250, 118878, 0, 128715, 9919, + 120528, 559, 128157, 41825, 127975, 74641, 4892, 74016, 194781, 6542, + 41957, 128865, 5777, 0, 759, 65749, 2079, 65248, 12788, 64487, 64552, + 93063, 10223, 42062, 0, 0, 74246, 3668, 65754, 43560, 12226, 67991, + 65149, 2340, 41959, 194786, 194785, 194788, 43618, 65747, 10937, 2962, 0, + 2321, 3587, 65745, 67236, 8921, 9952, 128941, 0, 42714, 9951, 43409, 194770, 2949, 66012, 194775, 194774, 2958, 68359, 41820, 2300, 2395, - 128563, 9976, 120043, 120050, 120058, 68220, 128143, 42809, 42807, 0, - 120046, 10198, 4150, 64371, 8318, 41790, 67976, 41898, 2360, 41794, - 917942, 71314, 127818, 0, 0, 2418, 983098, 2411, 11336, 799, 63823, + 120061, 9976, 120043, 120050, 71896, 68220, 128143, 42809, 42807, 70798, + 66290, 10198, 4150, 64371, 8318, 41790, 67976, 41898, 2360, 41794, + 917942, 70796, 92163, 93033, 0, 2418, 983098, 2411, 11336, 799, 63823, 10276, 10308, 10372, 917541, 41772, 42813, 2317, 10260, 118980, 55284, - 92203, 0, 10384, 983220, 0, 0, 7753, 2351, 6655, 64489, 69931, 0, 77872, - 4443, 42779, 230, 0, 0, 43549, 4855, 42150, 65739, 5441, 41896, 10288, - 10320, 0, 855, 7046, 6109, 65045, 63839, 78198, 2049, 10098, 0, 74145, - 127943, 10264, 10280, 9184, 10376, 7013, 4467, 0, 0, 0, 41887, 0, 4862, - 9735, 6537, 120591, 74286, 3914, 92178, 93976, 9065, 12961, 0, 0, 92253, - 0, 289, 0, 4694, 11420, 4690, 0, 120514, 917978, 4693, 73893, 42724, 0, - 4688, 120454, 0, 0, 67994, 8238, 3110, 120162, 983908, 120163, 6528, - 127553, 43035, 69898, 218, 0, 1520, 0, 4786, 0, 43225, 4602, 0, 78167, - 10088, 6548, 0, 120156, 43978, 8988, 8888, 0, 0, 0, 0, 10666, 0, 73902, - 69740, 0, 0, 9975, 128039, 119902, 4689, 8932, 0, 65560, 119209, 74441, - 78810, 0, 0, 67987, 0, 0, 0, 67989, 0, 10065, 8207, 0, 92613, 128011, 0, - 662, 0, 9244, 194863, 0, 119261, 983428, 0, 0, 0, 41929, 0, 0, 66674, - 41926, 120408, 120443, 10513, 64637, 194862, 68013, 52, 13118, 6475, 0, - 120341, 12095, 10225, 4812, 92578, 0, 67992, 74085, 0, 3978, 0, 917945, - 127823, 11582, 120761, 12281, 0, 6544, 13241, 93961, 69782, 128557, + 78686, 0, 10384, 983220, 0, 129111, 7753, 2351, 6655, 64489, 69931, + 70199, 77872, 4443, 42779, 230, 0, 128969, 43549, 4855, 42150, 65739, + 5441, 41896, 10288, 10320, 0, 855, 7046, 6109, 65045, 63839, 78198, 2049, + 10098, 0, 74145, 127943, 10264, 10280, 9184, 10376, 7013, 4467, 78684, 0, + 0, 41887, 0, 4862, 9735, 6537, 120591, 74286, 3914, 92178, 93976, 9065, + 12961, 0, 0, 92253, 0, 289, 128714, 4694, 11420, 4690, 0, 120514, 917978, + 4693, 73893, 42724, 69977, 4688, 120454, 0, 0, 67994, 8238, 3110, 120162, + 3565, 120163, 6528, 127553, 43035, 69898, 218, 983850, 1520, 0, 4786, + 983168, 43225, 4602, 917982, 78167, 10088, 6548, 0, 120156, 43978, 8988, + 8888, 92724, 74812, 69709, 0, 10666, 0, 73902, 69740, 127793, 0, 9975, + 113704, 119902, 4689, 8932, 0, 65560, 119209, 74441, 78810, 0, 0, 67987, + 0, 128828, 0, 67989, 119029, 10065, 8207, 71900, 92613, 128011, 0, 662, + 0, 9244, 194863, 0, 119261, 983428, 0, 0, 0, 41929, 0, 71084, 66674, + 41926, 69994, 120443, 10513, 64637, 194862, 68013, 52, 13118, 6475, 0, + 120341, 12095, 10225, 4812, 92578, 128486, 67992, 74085, 0, 3978, 128425, + 917945, 74015, 11582, 92768, 12281, 0, 6544, 13241, 93961, 69782, 128557, 194860, 11765, 65258, 10369, 0, 1585, 7192, 10249, 422, 1500, 2036, 986, 194859, 64394, 5781, 5599, 64294, 2494, 120450, 4861, 74021, 64334, - 78203, 127808, 0, 92266, 65102, 8961, 65842, 10243, 10245, 74191, 120410, + 78203, 127808, 0, 92266, 65102, 8961, 65842, 10243, 10245, 71907, 120410, 0, 120453, 64821, 9478, 2508, 92683, 0, 202, 128246, 74131, 1242, 65514, - 0, 63940, 128706, 64533, 120129, 0, 67842, 11990, 92430, 63939, 43375, - 65440, 2504, 0, 78671, 64829, 983910, 6943, 917934, 5859, 0, 2858, - 983361, 74294, 983914, 69239, 0, 119027, 12992, 2753, 1936, 70078, 92574, - 2751, 12662, 2763, 8953, 64701, 10731, 12922, 7052, 917839, 0, 0, 0, - 63920, 74128, 2856, 119910, 47, 69908, 126986, 65858, 0, 0, 0, 7899, 0, + 128913, 63940, 127118, 64533, 71883, 120446, 67842, 11990, 92405, 63939, + 43375, 65440, 2504, 0, 78671, 64829, 93020, 6943, 917934, 5859, 0, 2858, + 983361, 74294, 983914, 69239, 0, 67871, 12992, 2753, 1936, 70078, 67701, + 2751, 12662, 2763, 8953, 64701, 10731, 12922, 7052, 917839, 66424, 63992, + 0, 63920, 74128, 2856, 119910, 47, 69908, 71053, 65858, 0, 0, 0, 7899, 0, 8417, 43798, 7072, 0, 0, 4033, 128164, 43992, 0, 0, 212, 64600, 1903, - 12320, 0, 0, 194563, 0, 8915, 2759, 945, 6689, 0, 0, 0, 0, 1291, 74828, - 0, 0, 9531, 13155, 8505, 68379, 12062, 0, 0, 65487, 92189, 41837, 120611, - 120432, 0, 0, 0, 120433, 0, 63935, 73962, 120806, 64787, 43524, 0, 64426, - 0, 194948, 0, 0, 65664, 6693, 9843, 0, 8674, 119887, 128812, 92715, 0, - 12624, 0, 1673, 4811, 92383, 5986, 9338, 3046, 74480, 5985, 917928, - 119598, 9820, 0, 12187, 0, 0, 5984, 0, 43308, 4393, 67650, 0, 0, 0, 0, - 74826, 64733, 0, 0, 3491, 0, 0, 128219, 3514, 65485, 0, 7492, 0, 74605, - 92483, 7514, 983367, 0, 194731, 7502, 7587, 68353, 0, 0, 63925, 0, 7610, - 219, 0, 0, 692, 43588, 74433, 41635, 43241, 9688, 7147, 9535, 0, 93991, - 0, 64530, 0, 64610, 11804, 0, 7149, 7453, 0, 8013, 0, 92301, 0, 8895, - 5253, 70025, 5458, 0, 2866, 0, 127860, 65111, 68433, 6700, 120484, 0, - 120583, 0, 8962, 77960, 9641, 43694, 7059, 983677, 0, 9604, 78700, 7441, - 63826, 67970, 118941, 64392, 194735, 983687, 2844, 983941, 41974, 0, - 12139, 67971, 0, 0, 3358, 65295, 0, 3104, 194734, 0, 194765, 983233, - 5308, 0, 290, 0, 0, 2862, 2792, 195088, 983070, 0, 3268, 66591, 0, 6552, - 42367, 7035, 120558, 0, 0, 1814, 0, 10240, 92338, 74305, 0, 74528, 65903, - 0, 42646, 7606, 2591, 2837, 4341, 77956, 64482, 127337, 8163, 65270, 0, - 77932, 0, 9112, 74431, 863, 9490, 119898, 128349, 43323, 120513, 119897, - 9071, 127333, 0, 3654, 7789, 9637, 0, 2535, 65504, 7653, 40993, 119899, - 66587, 195098, 0, 92401, 983894, 11006, 12927, 7807, 8073, 0, 10629, 0, - 74088, 3056, 10823, 128797, 127327, 8762, 10508, 69689, 73770, 43969, - 43193, 10737, 3463, 983065, 0, 66633, 8695, 4815, 11322, 5811, 12345, - 7049, 119911, 5195, 195081, 0, 66639, 0, 0, 0, 128041, 0, 92385, 1262, 0, - 6561, 19939, 0, 0, 128535, 119906, 0, 0, 983097, 0, 983667, 119907, - 64612, 11991, 0, 0, 0, 1502, 917568, 0, 9107, 127316, 5702, 3655, 67661, - 8430, 0, 74132, 120758, 0, 74057, 9603, 0, 5254, 120742, 7724, 74388, - 68375, 10796, 5129, 0, 0, 590, 7579, 5614, 5893, 92280, 11720, 92496, - 11721, 0, 4798, 0, 119316, 66038, 4793, 67851, 11726, 127541, 74204, - 68610, 0, 68626, 894, 300, 917813, 12306, 66235, 8004, 0, 0, 2562, - 126555, 0, 42503, 0, 11652, 0, 0, 119241, 64699, 126569, 5096, 5095, - 2863, 3424, 92244, 10454, 42530, 5094, 119638, 0, 13156, 0, 10832, 5093, - 0, 69852, 0, 5092, 10708, 11327, 0, 5091, 176, 0, 9153, 4104, 78599, + 12320, 0, 125002, 194563, 0, 8915, 2759, 945, 6689, 93064, 0, 0, 118798, + 1291, 74828, 0, 0, 9531, 13155, 8505, 68379, 12062, 128198, 0, 65487, + 92189, 41837, 120611, 8246, 0, 93066, 0, 120433, 0, 63935, 73962, 120806, + 64787, 43524, 0, 64426, 0, 194948, 0, 0, 65664, 6693, 9843, 0, 8674, + 119887, 128812, 92715, 70788, 1320, 0, 1673, 4811, 92383, 5986, 9338, + 3046, 74480, 5985, 917928, 119598, 9820, 119892, 12187, 983841, 71041, + 5984, 0, 43308, 4393, 67650, 983227, 0, 125112, 0, 74826, 64733, 0, + 127898, 3491, 67146, 983710, 128219, 3514, 65485, 72428, 7492, 0, 74605, + 92483, 7514, 983367, 0, 194731, 7502, 7587, 68353, 63921, 0, 63925, 0, + 7610, 219, 0, 78722, 692, 43588, 68485, 41635, 43241, 9688, 7147, 9535, + 0, 93991, 0, 64530, 0, 64610, 11804, 0, 7149, 7453, 0, 8013, 0, 92301, 0, + 8895, 5253, 70025, 5458, 0, 2866, 129045, 127860, 11098, 68433, 6700, + 120484, 0, 120583, 0, 8962, 77960, 9641, 43694, 7059, 983677, 63997, + 9604, 78700, 7441, 63826, 67970, 118941, 64392, 92626, 983687, 2844, + 74610, 41974, 67397, 12139, 67971, 0, 0, 3358, 65295, 0, 3104, 194734, 0, + 194765, 983233, 5308, 0, 290, 0, 0, 2862, 2792, 195088, 92963, 0, 3268, + 66591, 0, 6552, 42367, 7035, 120558, 0, 0, 1814, 128572, 10240, 66285, + 74305, 128382, 74528, 65903, 0, 42646, 7606, 2591, 2837, 4341, 43513, + 64482, 127337, 8163, 65270, 0, 77932, 0, 9112, 74431, 863, 9490, 119898, + 128349, 43323, 120513, 119897, 9071, 127333, 0, 3654, 7789, 9637, 0, + 2535, 65504, 7653, 40993, 119899, 66587, 124987, 0, 92401, 983894, 11006, + 12927, 7807, 8073, 0, 10629, 127869, 74088, 3056, 10823, 128797, 113762, + 8762, 10508, 69689, 73770, 43969, 43193, 10737, 3463, 983065, 0, 66633, + 8695, 4815, 11322, 5811, 12345, 7049, 118811, 5195, 195081, 0, 66639, + 92939, 0, 0, 128041, 67903, 67739, 1262, 120165, 6561, 19939, 0, 0, + 128535, 119906, 0, 0, 983097, 0, 983667, 119907, 64612, 11991, 0, 0, + 92943, 1502, 917568, 127988, 9107, 127316, 5702, 3655, 67661, 8430, 0, + 71223, 120758, 0, 74057, 9603, 128079, 5254, 120742, 7724, 74388, 68375, + 10796, 5129, 0, 70816, 590, 7579, 5614, 5893, 92280, 11720, 92496, 11721, + 70804, 4798, 0, 119316, 66038, 4793, 67851, 11726, 127541, 74204, 68610, + 0, 68626, 894, 300, 917813, 12306, 66235, 8004, 0, 195056, 2562, 70156, + 0, 42503, 128864, 11652, 0, 0, 119241, 64699, 126569, 5096, 5095, 2863, + 3424, 92244, 10454, 42530, 5094, 70873, 0, 13156, 129057, 10832, 5093, 0, + 69852, 72430, 5092, 10708, 11327, 0, 5091, 176, 0, 9153, 4104, 78599, 78601, 1215, 42712, 5744, 12272, 9832, 11777, 71299, 127371, 42881, 0, - 8980, 118988, 67861, 8844, 7209, 0, 0, 4278, 0, 0, 194789, 0, 9074, 4348, - 0, 65558, 65946, 8113, 7087, 5255, 1786, 661, 0, 0, 0, 74423, 71345, 586, - 74414, 64359, 1267, 128269, 65468, 0, 65731, 0, 127179, 3621, 120473, - 66666, 64211, 0, 6562, 12928, 0, 1228, 65490, 11383, 0, 0, 0, 1714, - 74406, 127831, 0, 983921, 0, 66225, 0, 0, 42660, 11436, 2070, 64, 120694, - 0, 10291, 10323, 2826, 0, 0, 0, 42008, 9708, 42710, 0, 42011, 41999, - 92164, 12206, 5839, 1702, 1240, 74065, 6286, 0, 983969, 65833, 77848, 0, - 1765, 0, 0, 65588, 0, 0, 0, 8401, 0, 42014, 0, 7030, 194704, 10479, - 64959, 2852, 0, 0, 0, 0, 128586, 917951, 6963, 0, 12667, 64540, 74786, - 10147, 12935, 127568, 126483, 0, 0, 0, 78757, 0, 0, 0, 0, 9994, 12467, - 2864, 64719, 1148, 10435, 11462, 41675, 7084, 2765, 0, 43382, 0, 120719, - 128188, 92516, 66662, 0, 78133, 9364, 194685, 74416, 0, 0, 77988, 263, - 10449, 41288, 0, 41839, 78387, 983742, 77986, 0, 6931, 69722, 64355, - 7177, 70105, 0, 0, 0, 4262, 10285, 10722, 42020, 126575, 6806, 6992, - 42019, 0, 41290, 983716, 750, 0, 71304, 10163, 63913, 71300, 7032, 5954, - 64931, 4314, 0, 198, 68453, 730, 120094, 63907, 77993, 78891, 13165, - 7107, 74171, 42804, 678, 8240, 78015, 128784, 41378, 11008, 6938, 70026, - 92637, 2097, 66246, 120560, 0, 0, 0, 3892, 68632, 69642, 6712, 66045, - 41470, 64805, 0, 0, 128215, 64801, 0, 497, 12100, 5953, 92667, 7796, - 69669, 43254, 73831, 0, 10293, 5952, 1281, 43747, 0, 0, 10677, 604, - 41097, 9182, 1859, 0, 92603, 3425, 127488, 0, 2836, 0, 0, 9707, 0, 43202, - 0, 0, 65199, 1738, 917818, 128158, 2832, 92702, 9670, 12937, 0, 66374, - 917956, 0, 2822, 68122, 4436, 92519, 983723, 73752, 0, 64872, 92340, - 1331, 0, 0, 0, 12708, 0, 5090, 5089, 127977, 0, 119109, 0, 128681, 319, - 118847, 43479, 9477, 0, 0, 5087, 92325, 7640, 96, 5086, 0, 92379, 0, - 5085, 64286, 92665, 0, 41422, 0, 119901, 42356, 3772, 0, 0, 5011, 0, 0, - 126587, 0, 127165, 127241, 6677, 7601, 0, 591, 64419, 118953, 92262, 0, - 118923, 70084, 0, 10939, 6106, 6933, 41271, 6760, 71343, 4534, 41270, - 128876, 0, 65574, 0, 9224, 69853, 3671, 8976, 126474, 0, 41275, 6372, - 128084, 55261, 7963, 6371, 0, 568, 0, 41273, 983730, 0, 6728, 0, 9715, 0, - 8258, 11753, 74820, 0, 9602, 118919, 42, 0, 43688, 0, 0, 7458, 0, 0, - 65385, 119900, 0, 11958, 0, 917822, 0, 6254, 42721, 66336, 8045, 11550, - 0, 0, 983597, 42858, 11789, 65868, 5557, 10133, 9737, 13109, 0, 9467, - 5558, 8878, 128136, 195036, 7451, 6706, 10146, 0, 9086, 64566, 0, 64584, - 7437, 7454, 12594, 128690, 68362, 4546, 7731, 0, 70048, 74243, 0, 3805, - 0, 194565, 44001, 41008, 0, 6307, 19949, 983790, 7544, 983045, 43469, 0, - 0, 10152, 64422, 65091, 119113, 7602, 64729, 0, 43521, 0, 42302, 43711, - 43523, 41447, 5559, 0, 8704, 2397, 5556, 0, 0, 0, 9011, 9630, 92633, 0, - 93998, 5506, 0, 1911, 66652, 0, 9961, 8845, 66698, 0, 10792, 8889, 0, - 2098, 0, 64751, 0, 66622, 0, 0, 74364, 0, 0, 983805, 74365, 7552, 0, 0, - 65384, 7223, 4559, 0, 1956, 43138, 7024, 65728, 64501, 1210, 195077, - 65175, 10184, 43140, 43654, 0, 0, 0, 38, 8533, 66669, 119124, 983293, + 8980, 118988, 67861, 8844, 7209, 0, 0, 4278, 128809, 0, 127947, 70821, + 9074, 4348, 0, 65558, 65946, 8113, 7087, 5255, 1786, 661, 0, 0, 0, 74423, + 71345, 586, 74414, 64359, 1267, 128269, 65468, 0, 65731, 0, 72405, 3621, + 92932, 66666, 64211, 0, 6562, 12928, 983891, 1228, 65490, 11383, 0, 0, + 70343, 1714, 74406, 120751, 0, 983921, 0, 66225, 128608, 70867, 42660, + 11436, 2070, 64, 120694, 0, 10291, 10323, 2826, 113809, 917629, 0, 42008, + 9708, 42710, 0, 42011, 41999, 92164, 12206, 5839, 1702, 1240, 74065, + 6286, 9689, 983969, 65833, 77848, 0, 1765, 0, 0, 65588, 0, 0, 0, 8401, + 983924, 42014, 0, 7030, 194704, 10479, 64959, 2852, 0, 0, 0, 70819, + 128586, 917951, 6963, 0, 12667, 64540, 74786, 10147, 12935, 127568, + 126483, 127782, 0, 0, 78757, 0, 113815, 128968, 0, 9994, 12467, 2864, + 64719, 1148, 10435, 11462, 41675, 7084, 2765, 78466, 43382, 0, 120719, + 128188, 92516, 66662, 0, 78133, 9364, 194685, 74416, 127797, 0, 77988, + 263, 10449, 41288, 0, 41839, 78387, 983742, 77986, 129140, 6931, 69722, + 64355, 7177, 70105, 0, 0, 0, 4262, 10285, 10722, 42020, 126575, 6806, + 6992, 42019, 0, 41290, 983716, 750, 0, 71304, 10163, 63913, 71300, 7032, + 5954, 64931, 4314, 128600, 198, 68453, 730, 120094, 63907, 77993, 70818, + 13165, 7107, 74171, 42804, 678, 8240, 78015, 128784, 41378, 11008, 6938, + 70026, 92637, 2097, 66246, 120560, 70823, 194990, 983604, 3892, 68632, + 69642, 6712, 66045, 41470, 64805, 0, 983213, 128215, 64801, 0, 497, + 12100, 5953, 92667, 7796, 69669, 43254, 73831, 0, 10293, 5952, 1281, + 43747, 0, 0, 10677, 604, 41097, 9182, 1859, 0, 92603, 3425, 127488, 0, + 2836, 0, 0, 9707, 113718, 43202, 0, 0, 65199, 1738, 128311, 67707, 2832, + 92702, 9670, 11101, 0, 66374, 917956, 0, 2822, 68122, 4436, 92519, + 983081, 73752, 0, 64872, 92340, 1331, 0, 0, 0, 12708, 917954, 5090, 5089, + 127977, 983561, 119109, 0, 70826, 319, 118847, 43479, 9477, 0, 0, 5087, + 92325, 7640, 96, 5086, 0, 92379, 0, 5085, 64286, 92665, 113717, 41422, + 119617, 119901, 42356, 3772, 119042, 0, 5011, 0, 0, 126587, 0, 127165, + 127241, 6677, 7601, 0, 591, 64419, 118953, 92262, 0, 70799, 70084, 0, + 10939, 6106, 6933, 41271, 6760, 71343, 4534, 41270, 128876, 67138, 65574, + 194947, 9224, 67140, 3671, 8976, 67139, 0, 41275, 6372, 128084, 55261, + 7963, 6371, 0, 568, 92368, 41273, 983730, 74531, 6728, 0, 9715, 0, 8258, + 11753, 74820, 0, 9602, 118919, 42, 11191, 43688, 68243, 0, 7458, 0, 0, + 65385, 67135, 67134, 11958, 11165, 917822, 125087, 6254, 42721, 66336, + 8045, 11550, 0, 67132, 67131, 42858, 11789, 65868, 5557, 10133, 9737, + 13109, 0, 9467, 5558, 8878, 43844, 195036, 7451, 6706, 10146, 0, 9086, + 64566, 0, 64584, 7437, 7454, 12594, 73749, 68362, 4546, 7731, 0, 70048, + 74243, 125092, 3805, 0, 67128, 44001, 41008, 128052, 6307, 19949, 67129, + 7544, 983045, 43469, 0, 0, 10152, 64422, 65091, 67124, 7602, 64729, 0, + 43521, 0, 42302, 43711, 43523, 41447, 5559, 68483, 8704, 2397, 5556, 0, + 0, 0, 9011, 9630, 11166, 0, 93998, 5506, 92498, 1911, 66652, 67686, 9961, + 8845, 66698, 68325, 10792, 8889, 0, 2098, 0, 64751, 128360, 66622, + 983122, 0, 74364, 113708, 129152, 983805, 42909, 7552, 128622, 0, 65384, + 7223, 4559, 93015, 1956, 43138, 7024, 65728, 43490, 1210, 195077, 65175, + 10184, 43140, 43654, 0, 0, 125045, 38, 8533, 66669, 119124, 983293, 983792, 0, 4357, 0, 119837, 917863, 74233, 9967, 78884, 42860, 119838, - 10941, 65721, 6962, 0, 0, 119324, 0, 11014, 127972, 8942, 12000, 69224, - 92267, 128536, 11974, 92213, 42772, 127518, 11650, 5013, 92663, 126583, - 66210, 118914, 6613, 92476, 0, 43819, 983770, 0, 64714, 0, 0, 12162, - 12120, 43476, 983766, 11024, 74811, 66228, 10563, 0, 127196, 43522, 2462, - 0, 1837, 0, 63972, 6957, 0, 120559, 4952, 65718, 65827, 5504, 65720, - 65714, 65715, 65716, 0, 127005, 127119, 3109, 63975, 74028, 0, 8107, - 119234, 1127, 455, 0, 63968, 127924, 3483, 119593, 1989, 0, 69678, 9104, - 3503, 65375, 92509, 6694, 42633, 1864, 0, 74306, 41446, 2540, 7736, 0, - 74064, 0, 10521, 0, 42173, 9705, 74124, 8604, 6955, 10916, 43684, 6149, - 3887, 19956, 1411, 2824, 0, 10106, 127862, 1403, 128839, 1347, 9631, - 74444, 0, 0, 0, 0, 8640, 0, 258, 1654, 0, 0, 0, 43314, 0, 0, 4042, 11478, - 2873, 63977, 11522, 41668, 8549, 10861, 0, 63976, 0, 68623, 0, 74585, - 41391, 0, 917903, 376, 6987, 9221, 0, 0, 8823, 128697, 12943, 65185, - 41869, 12619, 0, 10154, 983043, 74439, 2039, 0, 7446, 1684, 63979, 10974, - 458, 120620, 0, 69791, 127161, 11916, 65016, 0, 69671, 42115, 983133, - 12288, 78057, 0, 1493, 42111, 7553, 4097, 128199, 13080, 0, 65808, 6610, - 6030, 8059, 7508, 13131, 0, 983431, 0, 8794, 41278, 41629, 12154, 128192, - 41277, 64658, 0, 64380, 6625, 74354, 19904, 0, 0, 0, 65371, 7078, 0, 833, - 0, 6369, 0, 10979, 41953, 0, 41434, 6062, 0, 0, 19916, 6913, 933, 1341, - 9842, 6720, 65744, 0, 983592, 128295, 0, 7405, 10105, 65810, 0, 41632, - 7493, 55290, 0, 41622, 0, 0, 119556, 74584, 7632, 9716, 19954, 9805, - 5990, 900, 0, 63957, 0, 0, 3612, 0, 64376, 93987, 5389, 92597, 0, 65938, - 2839, 9621, 582, 0, 74368, 3749, 6949, 7569, 74061, 0, 0, 6956, 4403, - 19962, 65559, 3299, 0, 917566, 119127, 9002, 0, 74372, 74236, 8478, 7598, - 546, 42469, 65569, 1918, 9542, 472, 7716, 10319, 10383, 6996, 0, 63952, - 8425, 3602, 8328, 11764, 118894, 0, 69796, 41183, 12907, 10271, 10287, - 684, 43525, 0, 2854, 119586, 4592, 65755, 0, 92256, 11963, 43620, 0, - 78249, 0, 128551, 128809, 9881, 43115, 65757, 3415, 119131, 0, 8648, 0, - 6741, 43047, 0, 13180, 128517, 418, 917972, 64495, 10295, 10327, 10391, - 41752, 74339, 8641, 41449, 0, 74100, 0, 10911, 6942, 0, 1024, 42849, - 41751, 69776, 8941, 983556, 4554, 0, 9023, 11685, 0, 9928, 78617, 0, - 11437, 43741, 92163, 120700, 63967, 983483, 41206, 120724, 9049, 41185, - 43166, 0, 11680, 92619, 11686, 78544, 65224, 4565, 4655, 119553, 0, - 92183, 64523, 10343, 10407, 0, 66671, 11466, 0, 128003, 42890, 74013, - 12050, 68201, 2860, 0, 0, 0, 42792, 5743, 10424, 12065, 42872, 0, 92342, - 0, 8875, 0, 0, 917991, 7531, 12847, 2413, 0, 78635, 962, 0, 12855, 41196, - 42564, 0, 1582, 983715, 5508, 0, 0, 0, 10801, 69876, 92354, 0, 7173, 496, - 10439, 4313, 64607, 69638, 7860, 0, 906, 42793, 2842, 6405, 64722, 13132, - 798, 64694, 12801, 8406, 1153, 92173, 64788, 0, 8054, 9174, 128652, - 917976, 9964, 74409, 41611, 4642, 66574, 11556, 917982, 0, 78857, 42089, - 78855, 9008, 0, 126592, 195096, 42079, 917981, 77924, 42513, 77927, - 42842, 73985, 65285, 118974, 127003, 983702, 0, 0, 0, 11335, 64069, - 42093, 3920, 0, 0, 0, 0, 4580, 41967, 983732, 64384, 92167, 93984, 3021, - 42004, 0, 0, 42317, 41998, 0, 6946, 0, 0, 0, 128193, 65204, 0, 68113, - 42690, 9880, 42010, 74824, 64589, 10111, 64875, 127880, 68399, 43998, - 11360, 0, 0, 0, 118826, 42149, 0, 0, 0, 64941, 77919, 120421, 128077, 0, - 55247, 4110, 66005, 6959, 10929, 119110, 0, 66703, 77921, 8617, 41982, - 6025, 69242, 983176, 0, 0, 0, 9597, 42099, 43172, 983376, 10117, 983169, - 92297, 41636, 0, 0, 120681, 8301, 0, 0, 187, 0, 65669, 128339, 4963, 0, - 127517, 0, 8964, 65676, 7775, 0, 41948, 0, 0, 0, 41942, 65449, 3160, - 10081, 13226, 42121, 42475, 42663, 128210, 41766, 119114, 65882, 78849, - 41760, 1189, 905, 480, 10985, 41733, 67859, 9629, 6742, 1745, 43625, - 73835, 7888, 0, 3980, 0, 42656, 41507, 8806, 7023, 0, 74279, 9447, 78651, - 7867, 69218, 6236, 983134, 0, 10505, 0, 12851, 118948, 348, 5474, 128843, - 3103, 0, 41753, 128540, 0, 0, 78844, 78845, 41739, 78843, 42515, 10931, - 41756, 43347, 42560, 5391, 41746, 119147, 92591, 41259, 5561, 69930, - 2691, 0, 65553, 7933, 5562, 69800, 128265, 41262, 128146, 64421, 74846, - 41251, 0, 0, 3979, 0, 0, 74813, 983739, 0, 0, 0, 92524, 41266, 0, 66566, - 128836, 10585, 65741, 41737, 9574, 2666, 0, 41738, 831, 419, 13126, - 10716, 0, 42822, 0, 6434, 0, 6939, 7766, 6432, 128106, 69932, 916, 769, - 41742, 11968, 74805, 6433, 5563, 547, 1943, 6439, 5560, 4994, 487, - 126537, 4497, 3754, 127056, 120424, 9039, 0, 41776, 0, 8716, 1595, 41615, - 0, 0, 74260, 0, 42854, 43219, 128709, 983460, 12185, 128879, 70072, - 68355, 68357, 0, 42856, 8634, 0, 983397, 4209, 120702, 0, 65879, 41538, - 65612, 127543, 669, 5679, 0, 69786, 92540, 0, 983464, 5678, 11821, 0, - 6711, 460, 0, 0, 983461, 0, 120747, 0, 0, 78050, 119022, 0, 983462, 0, - 7782, 9044, 4974, 11760, 78494, 7577, 65711, 41912, 1216, 0, 128079, - 5792, 0, 0, 78501, 0, 2933, 12244, 0, 5683, 983392, 0, 78119, 1549, 0, 0, - 120398, 5682, 6206, 8670, 10256, 5680, 69935, 10001, 128512, 69768, 1449, - 10241, 78290, 128228, 0, 10552, 64342, 41922, 128548, 8584, 68030, 5567, + 10941, 65721, 6962, 0, 0, 113808, 0, 11014, 120126, 8942, 12000, 69224, + 92267, 128536, 11974, 67363, 42772, 42650, 11650, 5013, 92663, 126583, + 66210, 118914, 6613, 92476, 0, 11193, 983770, 0, 64714, 0, 70802, 12162, + 12120, 43476, 983766, 11024, 74811, 66228, 10563, 92954, 127196, 43522, + 2462, 92955, 1837, 125086, 63972, 6957, 0, 113820, 4952, 65718, 64405, + 5504, 65720, 65714, 65715, 65716, 0, 127005, 127119, 3109, 63975, 74028, + 127213, 8107, 67154, 1127, 455, 0, 63968, 127835, 3483, 119593, 1989, 0, + 69678, 9104, 3503, 65375, 68300, 6694, 42633, 1864, 0, 74306, 41446, + 2540, 7736, 917916, 74064, 128601, 10521, 70786, 42173, 9705, 74124, + 8604, 6955, 10916, 43684, 6149, 3887, 19956, 1411, 2824, 0, 10106, + 127862, 1403, 125053, 1347, 9631, 74444, 983753, 0, 92951, 0, 8640, 0, + 258, 1654, 0, 0, 0, 43314, 0, 0, 4042, 11478, 2873, 63977, 11522, 41668, + 8549, 10861, 128430, 63976, 70377, 68623, 67082, 67081, 41391, 67084, + 917903, 376, 6987, 9221, 0, 0, 8823, 128697, 12943, 65185, 41869, 12619, + 0, 10154, 983043, 74439, 2039, 0, 7446, 1684, 63979, 10974, 458, 120620, + 0, 69791, 127161, 11916, 65016, 0, 69671, 42115, 983133, 12288, 78057, + 67080, 1493, 42111, 7553, 4097, 128199, 13080, 0, 65808, 6610, 6030, + 8059, 7508, 13131, 67074, 67073, 0, 8794, 41278, 41629, 12154, 128192, + 41277, 64658, 0, 64380, 6625, 42911, 19904, 0, 0, 71193, 65371, 7078, 0, + 833, 0, 6369, 0, 10979, 41953, 0, 41434, 6062, 0, 0, 19916, 6913, 933, + 1341, 9842, 6720, 65744, 71200, 983592, 128295, 0, 7405, 10105, 65810, 0, + 41632, 7493, 55290, 92890, 41622, 0, 0, 119556, 74584, 7632, 9716, 19954, + 9805, 5990, 900, 0, 63957, 119638, 0, 3612, 0, 64376, 93987, 5389, 92597, + 0, 65938, 2839, 9621, 582, 0, 74368, 3749, 6949, 7569, 74061, 0, 0, 6956, + 4403, 19962, 65559, 3299, 0, 917566, 119127, 9002, 0, 74372, 74236, 8478, + 7598, 546, 42469, 65569, 1918, 9542, 472, 7716, 10319, 10383, 6996, + 43077, 63952, 8425, 3602, 8328, 11764, 118894, 983750, 65065, 41183, + 12907, 10271, 10287, 684, 43525, 0, 2854, 119586, 4592, 65755, 983276, + 67120, 11963, 43620, 67117, 78249, 67123, 67122, 67121, 9881, 43115, + 65757, 3415, 69677, 67116, 8648, 128377, 6741, 43047, 917970, 13180, + 78077, 418, 120653, 64495, 10295, 10327, 10391, 41752, 66846, 8641, + 41449, 0, 74100, 0, 10911, 6942, 0, 1024, 42849, 41751, 69776, 8941, + 983556, 4554, 66892, 9023, 11685, 0, 9928, 67109, 66865, 11437, 43741, + 67113, 67112, 63967, 983483, 41206, 12624, 9049, 41185, 43166, 0, 8159, + 92619, 11686, 78544, 65224, 4565, 4655, 119553, 129090, 92183, 64523, + 10343, 10407, 92764, 66671, 11466, 0, 128003, 42890, 74013, 12050, 68201, + 2860, 0, 0, 70828, 42792, 5743, 10424, 12065, 42872, 0, 92342, 67103, + 8875, 0, 67102, 67105, 7531, 12847, 2413, 118917, 67404, 962, 0, 12855, + 41196, 42564, 0, 1582, 983715, 5508, 0, 0, 0, 10801, 69876, 92354, + 119207, 7173, 496, 10439, 4313, 64607, 69638, 7860, 0, 906, 42793, 2842, + 6405, 64722, 13132, 798, 64694, 12801, 8406, 1153, 92173, 64788, 127007, + 8054, 9174, 67087, 67086, 9964, 67096, 41611, 4642, 66574, 11556, 42512, + 0, 78857, 42089, 74613, 9008, 0, 126592, 195096, 42079, 917981, 77924, + 42513, 77927, 42842, 73985, 65285, 68338, 127003, 983702, 0, 194761, + 983590, 11335, 64069, 42093, 3920, 0, 0, 11110, 0, 4580, 41967, 129043, + 64384, 92167, 93984, 3021, 42004, 0, 983372, 42317, 41998, 0, 6946, + 194755, 92967, 0, 128193, 65204, 0, 68113, 42690, 9880, 42010, 74824, + 64589, 10111, 64875, 127880, 68399, 43998, 11360, 0, 74182, 128648, + 92633, 42149, 0, 68508, 917993, 64941, 77919, 120421, 128077, 0, 55247, + 4110, 66005, 6959, 10929, 42907, 0, 66703, 77921, 8617, 41982, 6025, + 69242, 983176, 194854, 125139, 0, 9597, 42099, 43172, 983376, 10117, + 983169, 92297, 41636, 194889, 73738, 120681, 8301, 0, 0, 187, 128237, + 65669, 128339, 4963, 0, 127517, 0, 8964, 65676, 7775, 0, 41948, 125003, + 0, 0, 41942, 65449, 3160, 10081, 13226, 42121, 42475, 42663, 128210, + 41766, 119114, 65882, 78849, 41760, 1189, 905, 480, 10985, 41733, 67859, + 9629, 6742, 1745, 43625, 73835, 7888, 0, 3980, 70373, 42656, 41507, 8806, + 7023, 0, 74279, 9447, 78651, 7867, 69218, 6236, 983134, 0, 10505, 129135, + 12851, 118948, 348, 5474, 128843, 3103, 0, 41753, 71109, 128604, 0, + 78844, 78845, 41739, 78843, 42515, 10931, 41756, 43347, 42560, 5391, + 41746, 119147, 92591, 41259, 5561, 69930, 2691, 92941, 65553, 7933, 5562, + 69800, 128265, 41262, 128146, 64421, 74846, 41251, 0, 0, 3979, 71248, 0, + 68331, 917912, 0, 0, 0, 74633, 41266, 0, 66566, 128836, 10585, 65741, + 41737, 9574, 2666, 0, 41738, 831, 419, 13126, 10716, 0, 42822, 0, 6434, + 74857, 6939, 7766, 6432, 128106, 69932, 916, 769, 41742, 11968, 74805, + 6433, 5563, 547, 1943, 6439, 5560, 4994, 487, 126537, 4497, 3754, 127056, + 120424, 9039, 0, 41776, 0, 8716, 1595, 41615, 0, 0, 74260, 74860, 42854, + 43219, 128709, 129083, 12185, 113810, 70072, 68355, 68357, 68421, 42856, + 8634, 0, 119988, 4209, 120702, 78046, 65879, 41538, 65612, 127543, 669, + 5679, 0, 69786, 92540, 0, 70445, 5678, 11821, 0, 6711, 460, 0, 0, 983461, + 70114, 120747, 0, 128412, 78050, 119022, 0, 983462, 983174, 7782, 9044, + 4974, 11760, 78494, 7577, 65711, 41912, 1216, 0, 127017, 5792, 0, 128319, + 78501, 0, 2933, 12244, 0, 5683, 917896, 0, 78119, 1549, 0, 0, 120398, + 5682, 6206, 8670, 10256, 5680, 69935, 10001, 67237, 69768, 1449, 10241, + 78290, 119587, 194891, 10552, 64342, 41922, 70330, 8584, 68030, 5567, 2717, 0, 0, 5564, 42886, 41908, 42882, 5565, 983256, 128026, 0, 65708, 65709, 5566, 69803, 65704, 65705, 11904, 42875, 43373, 42539, 5942, 8468, - 120561, 10361, 10425, 65697, 65698, 65699, 0, 66598, 0, 64664, 10647, - 78702, 78703, 78690, 457, 78502, 65701, 1934, 43006, 119903, 8802, 78710, - 65130, 11747, 78709, 6087, 78705, 78716, 41757, 78711, 8043, 8950, 65694, - 64485, 43534, 10457, 0, 11961, 78725, 78722, 78723, 78720, 78721, 0, - 65515, 9499, 10035, 13069, 71309, 0, 9889, 68184, 42806, 0, 7256, 0, 0, - 1667, 42161, 0, 42428, 0, 6934, 0, 10802, 64861, 6556, 78390, 0, 8101, - 3610, 983199, 41748, 4995, 955, 65907, 119208, 5350, 64339, 78306, 64549, - 10875, 128662, 5477, 65692, 0, 128532, 120397, 12896, 10456, 917954, 0, - 3874, 0, 0, 983619, 120331, 0, 0, 65603, 0, 65687, 0, 41038, 74009, - 119570, 42239, 8536, 78740, 78324, 78726, 74432, 724, 0, 1455, 78749, - 7183, 64583, 78747, 68443, 4175, 78741, 43614, 69801, 939, 0, 43520, - 68613, 74569, 917958, 0, 78763, 78764, 78760, 10788, 6088, 78759, 78755, - 190, 0, 12593, 0, 8188, 64408, 0, 4417, 983213, 92261, 6370, 0, 7827, - 68441, 6965, 0, 0, 13201, 128205, 69896, 0, 74382, 73781, 7918, 73988, 0, - 0, 917884, 1728, 0, 43764, 178, 12972, 92679, 0, 917887, 92563, 983381, - 0, 78327, 120405, 65690, 0, 0, 119054, 0, 9252, 917889, 4652, 68371, 0, - 0, 0, 13065, 9923, 10806, 0, 11763, 70016, 120688, 6723, 78187, 0, 6993, - 0, 0, 8333, 0, 0, 11390, 0, 74464, 0, 92320, 74080, 983315, 69911, 11910, + 120561, 10361, 10425, 65697, 65698, 65699, 0, 66598, 110592, 64664, + 10647, 78702, 78703, 78690, 457, 78502, 65701, 1934, 43006, 119903, 8802, + 78710, 65130, 11747, 78709, 6087, 78705, 78716, 41757, 78711, 8043, 8950, + 65694, 64485, 43534, 10457, 0, 11961, 78725, 66850, 78723, 78720, 78721, + 0, 65515, 9499, 10035, 13069, 71309, 0, 9889, 68184, 42806, 0, 7256, 0, + 983179, 1667, 42161, 0, 42428, 0, 6934, 0, 10802, 64861, 6556, 78390, 0, + 8101, 3610, 68420, 41748, 4995, 955, 65907, 119208, 5350, 64339, 78306, + 64549, 10875, 125052, 5477, 65692, 0, 128532, 120397, 12896, 10456, + 68298, 0, 3874, 0, 0, 983619, 120331, 0, 113665, 65603, 0, 65687, 0, + 41038, 74009, 9207, 42239, 8536, 78740, 78324, 78726, 74432, 724, 0, + 1455, 78749, 7183, 64583, 78747, 68443, 4175, 78741, 43614, 69801, 939, + 0, 43520, 68613, 74569, 917958, 0, 70168, 78764, 78760, 10788, 6088, + 78759, 78755, 190, 0, 12593, 0, 8188, 64408, 0, 4417, 128615, 92261, + 6370, 125128, 7827, 68441, 6965, 128581, 128868, 13201, 128205, 69896, + 78868, 74382, 11841, 7918, 73988, 0, 113668, 917884, 1728, 0, 43764, 178, + 12972, 74620, 113671, 71103, 11168, 983381, 113672, 78327, 119904, 65690, + 0, 71107, 119054, 0, 9252, 917889, 4652, 68371, 0, 917891, 74070, 13065, + 9923, 10806, 0, 11763, 70016, 120688, 6723, 78187, 0, 6993, 71044, 0, + 8333, 0, 0, 11390, 0, 74464, 0, 92320, 74080, 983315, 69911, 11910, 92559, 8278, 8963, 4034, 128560, 0, 65344, 120517, 41747, 0, 0, 8677, 0, - 12707, 9350, 66037, 128180, 8836, 12315, 12747, 8300, 983750, 0, 7491, + 12707, 9350, 66037, 128180, 8836, 12315, 12747, 8300, 194562, 0, 7491, 8856, 71361, 0, 43150, 127768, 120404, 65389, 120402, 120403, 10813, - 2592, 12853, 43269, 7263, 120244, 6536, 120238, 120239, 65516, 12321, - 120391, 120388, 55287, 10007, 120246, 9588, 120248, 1596, 120383, 41994, - 65801, 128808, 0, 66572, 0, 0, 10613, 6697, 12805, 41928, 40981, 78403, - 78409, 5006, 64328, 0, 9931, 0, 8825, 74555, 65940, 43259, 0, 6107, 0, - 119177, 0, 78401, 128641, 11783, 335, 120227, 64689, 438, 4510, 5765, - 8721, 120233, 119227, 6092, 12840, 43112, 8876, 120231, 8096, 10284, - 128515, 0, 0, 10380, 8733, 983072, 128240, 41602, 0, 92308, 74831, - 917901, 0, 73747, 65399, 0, 64591, 42405, 0, 120820, 843, 11541, 0, - 917898, 2065, 41935, 74496, 41902, 0, 0, 215, 41258, 77875, 43159, 1953, - 9579, 41938, 1256, 3910, 9407, 6242, 0, 983100, 41257, 41900, 8675, - 10700, 8805, 1742, 0, 9333, 8202, 127750, 0, 983197, 0, 0, 73882, 499, - 983049, 43467, 0, 43818, 0, 1712, 5932, 77845, 41762, 983104, 0, 11967, - 1775, 0, 0, 0, 0, 128009, 9458, 0, 6470, 9180, 120380, 43176, 0, 0, - 42782, 0, 0, 0, 128309, 74777, 120669, 9414, 120382, 73782, 73969, 565, - 42484, 5794, 201, 2662, 42292, 0, 8254, 0, 10975, 0, 120625, 74763, 1022, - 4108, 3880, 74247, 0, 0, 92263, 917980, 7507, 0, 43149, 0, 65031, 7961, - 1636, 0, 65029, 65024, 0, 12473, 6534, 0, 99, 98, 97, 120571, 67584, - 4049, 74163, 127065, 7090, 0, 7892, 917969, 10777, 917803, 65310, 65562, - 66599, 66722, 0, 8039, 3363, 66594, 43434, 0, 0, 12596, 66595, 42258, - 42570, 5593, 119148, 120711, 92425, 10100, 6061, 64854, 119, 118, 117, - 116, 12998, 122, 121, 120, 111, 110, 109, 108, 115, 114, 113, 112, 103, - 102, 101, 100, 107, 106, 105, 104, 6436, 73974, 534, 41212, 77931, 1536, + 2592, 12853, 43269, 7263, 120244, 6536, 120238, 71891, 65516, 12321, + 120391, 120388, 55287, 10007, 120246, 9588, 68494, 1596, 120383, 41994, + 65801, 128808, 6838, 3561, 0, 0, 10613, 6697, 12805, 41928, 40981, 10804, + 78409, 5006, 64328, 0, 9931, 0, 8825, 74555, 65940, 43259, 126586, 6107, + 0, 119177, 77941, 78401, 128641, 11783, 335, 120227, 64689, 438, 4510, + 5765, 8721, 119570, 119227, 6092, 12840, 43112, 8876, 120231, 8096, + 10284, 128515, 0, 0, 10380, 8733, 10316, 70121, 41602, 0, 92308, 74831, + 917901, 0, 68482, 65399, 0, 64591, 42405, 0, 120820, 843, 11541, 128326, + 70321, 2065, 41935, 74496, 41902, 0, 983304, 215, 41258, 77875, 43159, + 1953, 9579, 41938, 1256, 3910, 9407, 6242, 0, 983100, 41257, 41900, 8675, + 10700, 8805, 1742, 113722, 9333, 8202, 72399, 0, 983197, 127252, 0, + 73882, 499, 983049, 43467, 0, 43818, 0, 1712, 5932, 77845, 41762, 983104, + 0, 11967, 1775, 125006, 0, 11118, 0, 128009, 9458, 0, 6470, 9180, 120380, + 43176, 0, 0, 42782, 0, 124999, 983135, 128309, 73849, 120669, 9414, + 74647, 73782, 73969, 565, 42484, 5794, 201, 2662, 42292, 0, 8254, 0, + 10975, 43518, 120625, 74763, 1022, 4108, 3880, 74247, 0, 0, 92263, + 917980, 7507, 983118, 43149, 71059, 65031, 7961, 1636, 0, 65029, 65024, + 119099, 12473, 6534, 120633, 99, 98, 97, 68226, 67584, 4049, 74163, + 127065, 7090, 0, 7892, 917969, 10777, 917803, 65310, 65562, 66599, 66722, + 194955, 8039, 3363, 66594, 43434, 0, 71191, 12596, 66595, 42258, 42570, + 5593, 119148, 120711, 92425, 10100, 6061, 64854, 119, 118, 117, 116, + 12998, 122, 121, 120, 111, 110, 109, 108, 115, 114, 113, 112, 103, 102, + 101, 100, 107, 106, 105, 104, 6436, 73974, 534, 41212, 67713, 1536, 64093, 73970, 77930, 127157, 0, 6020, 12716, 127112, 12744, 475, 120394, - 13266, 127813, 127111, 0, 73926, 0, 10645, 1212, 6543, 983307, 8134, - 128028, 2913, 73870, 127113, 1866, 983229, 195095, 0, 8923, 1645, 12059, - 66585, 71297, 3196, 0, 0, 5935, 1250, 127066, 8174, 9787, 6733, 9859, - 7916, 9861, 9860, 5258, 1882, 1892, 6731, 10882, 405, 11454, 73911, 0, - 128781, 41169, 8939, 41245, 0, 41170, 1454, 11369, 6477, 12157, 0, 0, 0, - 41172, 7855, 0, 0, 10480, 0, 0, 77936, 8264, 12610, 983308, 645, 126616, - 7609, 40973, 69943, 73833, 69948, 5824, 984, 77918, 10688, 5851, 0, 7729, - 73982, 120518, 0, 195086, 43369, 0, 128140, 68415, 983093, 4538, 120406, - 43141, 0, 983210, 74214, 73886, 0, 0, 118902, 43005, 78448, 9552, 0, 0, - 983159, 12997, 0, 0, 0, 0, 2381, 12883, 10994, 10529, 41906, 0, 0, 0, - 12425, 10661, 10856, 9614, 2428, 41478, 8582, 10064, 73930, 0, 0, 0, - 64896, 119162, 1952, 92181, 8455, 10082, 11575, 983490, 119566, 0, 12808, - 12183, 6145, 118955, 64929, 92433, 0, 983193, 43186, 42509, 0, 3922, - 9187, 983614, 0, 10191, 119057, 11752, 3353, 9358, 0, 71366, 66680, - 120090, 8248, 7931, 8558, 9795, 68380, 983297, 0, 120082, 120081, 120084, - 41027, 120086, 0, 120088, 7366, 7019, 120073, 0, 11751, 120078, 78294, - 64657, 8657, 120048, 8594, 120068, 0, 0, 120069, 120072, 120071, 0, 0, - 43154, 41029, 0, 11332, 65380, 7728, 94077, 11294, 0, 66665, 7851, 0, - 8375, 8699, 0, 42524, 0, 9085, 94041, 7504, 9327, 6160, 128095, 983864, - 0, 8088, 0, 74012, 92500, 0, 4439, 6926, 983047, 12924, 128227, 42369, + 13266, 127813, 127111, 78842, 73926, 66291, 10645, 1212, 6543, 983307, + 8134, 128028, 2913, 73870, 127113, 1866, 983229, 71892, 0, 8923, 1645, + 12059, 66585, 71297, 3196, 72404, 194827, 5935, 1250, 127066, 8174, 9787, + 6733, 9859, 7916, 9861, 9860, 5258, 1882, 1892, 6731, 10882, 405, 11454, + 73911, 113787, 92529, 41169, 8939, 41245, 0, 41170, 1454, 11369, 6477, + 12157, 0, 0, 0, 41172, 7855, 0, 0, 10480, 43258, 917819, 77936, 8264, + 12610, 983308, 645, 126616, 7609, 40973, 69943, 73833, 69948, 5824, 984, + 77918, 10688, 5851, 0, 7729, 73982, 120518, 0, 195086, 43369, 0, 128140, + 68415, 92644, 4538, 93978, 43141, 0, 983210, 74214, 73886, 67709, 917599, + 71918, 43005, 78448, 9552, 0, 70129, 129173, 12997, 0, 0, 0, 0, 2381, + 12883, 10994, 10529, 41906, 0, 74618, 0, 12425, 10661, 10856, 9614, 2428, + 41478, 8582, 10064, 73930, 0, 70437, 0, 64896, 119162, 1952, 92181, 8455, + 10082, 11575, 129062, 119566, 128093, 12808, 12183, 6145, 118955, 64929, + 92433, 71916, 983193, 43186, 42509, 0, 3922, 9187, 126513, 0, 10191, + 119057, 11752, 3353, 9358, 983460, 71366, 66680, 120090, 8248, 7931, + 8558, 9795, 68380, 983297, 0, 120082, 120081, 120084, 41027, 120086, 0, + 120088, 7366, 7019, 70378, 0, 11751, 120078, 78294, 64657, 8657, 120048, + 8594, 120068, 0, 0, 120069, 120072, 120071, 0, 113711, 43154, 41029, 0, + 11332, 65380, 7728, 94077, 11294, 0, 66665, 7851, 0, 8375, 8699, 127949, + 42524, 68419, 9085, 94041, 7504, 9327, 6160, 128095, 983864, 194929, + 8088, 128937, 74012, 66562, 0, 4439, 6926, 72423, 12924, 128227, 42369, 4350, 65491, 65145, 9041, 43559, 64577, 10826, 0, 11296, 983283, 0, 0, - 65825, 9577, 68199, 0, 64670, 983121, 78056, 6793, 11295, 0, 78053, - 73872, 0, 0, 10902, 0, 0, 78070, 78068, 10472, 2995, 0, 0, 64682, 2371, - 78069, 120808, 259, 1009, 92171, 2402, 2333, 6440, 194741, 0, 65125, - 41244, 0, 13271, 9103, 2278, 0, 0, 0, 0, 10219, 0, 0, 0, 0, 43178, - 127070, 41261, 119362, 43640, 8613, 0, 94049, 6736, 195092, 41492, 12005, - 69927, 0, 1890, 120056, 0, 0, 0, 7293, 7991, 0, 10578, 0, 78076, 194738, - 78077, 69928, 0, 78800, 92653, 64445, 42668, 6635, 0, 6164, 65170, 0, 0, - 7676, 11664, 0, 983658, 69707, 0, 118812, 0, 0, 128045, 9175, 11925, - 78045, 9088, 0, 64545, 1396, 0, 7546, 3847, 127177, 127835, 4985, 13288, - 672, 8098, 43196, 194746, 983096, 128126, 42655, 74043, 65072, 1577, - 11772, 13041, 5928, 4525, 10658, 65911, 1266, 10180, 0, 128584, 12622, 0, - 0, 0, 194714, 127139, 13310, 773, 19933, 1539, 0, 126983, 42731, 67972, - 0, 0, 0, 3051, 5862, 7823, 92478, 0, 120411, 3250, 43991, 69687, 66649, - 9510, 66237, 983302, 0, 41066, 64673, 917963, 917964, 0, 3505, 8707, - 917968, 6725, 128013, 917971, 92314, 3471, 917970, 5479, 882, 6686, - 119584, 11613, 120772, 42754, 0, 983306, 92696, 0, 0, 0, 128523, 3225, - 917996, 4433, 41156, 43973, 43173, 1443, 4381, 0, 0, 10926, 11756, 11757, - 64879, 917949, 917950, 127848, 13227, 0, 10021, 5160, 1387, 0, 917953, - 41418, 0, 65914, 6721, 217, 917955, 917960, 917961, 10443, 10789, 41158, - 119257, 4274, 983300, 41483, 0, 41250, 0, 42179, 0, 5931, 11744, 69232, - 0, 41252, 66682, 0, 119637, 41249, 1366, 64635, 65047, 12466, 0, 0, 4397, - 128037, 128336, 41296, 9545, 41291, 128049, 0, 41485, 3511, 41282, 5923, - 10400, 0, 128818, 760, 0, 12088, 5786, 0, 42256, 119869, 119860, 417, - 41474, 119562, 41565, 0, 5934, 119867, 66583, 119231, 64877, 2284, 64481, - 78614, 66013, 41956, 43455, 126995, 0, 0, 0, 42273, 5819, 0, 917556, 0, + 65825, 9577, 68199, 983391, 64670, 983121, 78056, 6793, 11295, 70409, + 78053, 73872, 78055, 119993, 10902, 0, 0, 78070, 11200, 10472, 2995, 0, + 120138, 64682, 2371, 78069, 120808, 259, 1009, 70405, 2402, 2333, 6440, + 194741, 113757, 65125, 41244, 70407, 13271, 9103, 2278, 0, 194728, 0, 0, + 10219, 0, 194740, 0, 67718, 43178, 127070, 41261, 119362, 43640, 8613, 0, + 94049, 6736, 195092, 41492, 12005, 69927, 127068, 1890, 120056, 0, + 128450, 0, 7293, 7991, 74052, 10578, 917998, 78076, 128620, 67368, 69928, + 71850, 78800, 92653, 64445, 42668, 6635, 128308, 6164, 65170, 0, 0, 7676, + 11664, 0, 93025, 69707, 93022, 118812, 0, 71096, 128045, 9175, 11925, + 78045, 9088, 119145, 64545, 1396, 0, 7546, 3847, 71088, 93037, 4985, + 13288, 672, 8098, 43196, 194746, 120723, 128126, 42655, 74043, 65072, + 1577, 11772, 13041, 5928, 4525, 10658, 65911, 1266, 10180, 0, 128371, + 12622, 0, 124948, 0, 128858, 127139, 13310, 773, 19933, 1539, 0, 126983, + 42731, 67972, 0, 71066, 983200, 3051, 5862, 7823, 92478, 92746, 120411, + 3250, 43991, 69687, 66649, 9510, 66237, 983302, 0, 41066, 64673, 917963, + 917964, 128636, 3505, 8707, 917968, 6725, 128013, 917971, 92314, 3471, + 66391, 5479, 882, 6686, 119584, 11613, 120772, 42754, 74608, 983306, + 92696, 0, 0, 0, 128523, 3225, 917996, 4433, 41156, 43973, 43173, 1443, + 4381, 0, 0, 10926, 11756, 11757, 64879, 917949, 195053, 127848, 13227, + 120320, 10021, 5160, 1387, 0, 917953, 41418, 128933, 65914, 6721, 217, + 917955, 917960, 917961, 10443, 10789, 41158, 119257, 4274, 11143, 41483, + 0, 41250, 128904, 42179, 128375, 5931, 11744, 11215, 74446, 41252, 66682, + 0, 119637, 41249, 1366, 64635, 65047, 12466, 983456, 0, 4397, 128037, + 128336, 41296, 9545, 41291, 128049, 0, 41485, 3511, 41282, 5923, 10400, + 0, 128818, 760, 0, 12088, 5786, 68252, 42256, 119869, 67145, 417, 41474, + 119562, 41565, 0, 5934, 74572, 66583, 119231, 64877, 2284, 64481, 78614, + 66013, 41956, 43455, 67240, 194656, 0, 0, 42273, 5819, 0, 917556, 0, 126643, 0, 65910, 127747, 10246, 120816, 65785, 1237, 10274, 4552, - 119576, 0, 0, 1375, 66705, 43573, 65260, 42063, 0, 42811, 10312, 69845, - 120794, 7840, 0, 43630, 10252, 0, 128104, 43185, 0, 4396, 0, 119880, - 10769, 9676, 119041, 0, 9753, 0, 8944, 0, 0, 10473, 0, 0, 6072, 43025, - 10299, 0, 0, 120608, 66326, 983447, 127794, 0, 43811, 9330, 120596, 7222, - 10283, 10315, 10379, 4996, 983782, 13281, 66517, 7865, 10087, 78343, 0, - 78347, 0, 0, 7565, 66363, 12952, 64806, 43180, 77928, 7414, 77929, 43982, - 74288, 622, 74023, 885, 43405, 1602, 0, 0, 852, 0, 12160, 0, 10212, - 65435, 0, 12071, 9609, 12156, 917983, 917984, 43586, 11035, 10411, - 917988, 10255, 6710, 10279, 4194, 10375, 73900, 0, 4315, 12644, 127516, - 77937, 43639, 43343, 78777, 917998, 11501, 41177, 128689, 0, 917792, 0, - 92413, 8715, 0, 41179, 0, 43313, 0, 41176, 0, 994, 0, 8452, 127103, - 73966, 0, 0, 5921, 0, 2597, 0, 5922, 118903, 77943, 4186, 92531, 119967, + 119576, 983863, 0, 1375, 66705, 43573, 65260, 3329, 0, 42811, 10312, + 69845, 120794, 7840, 0, 43630, 10252, 119242, 128104, 43185, 0, 4396, + 195051, 119880, 10769, 9676, 119041, 0, 9753, 0, 8944, 0, 0, 10473, 0, + 120472, 6072, 43025, 10299, 128436, 0, 120608, 66326, 67412, 92952, 0, + 43811, 9330, 120596, 7222, 10283, 10315, 10379, 4996, 127902, 13281, + 66517, 7865, 10087, 78343, 0, 43324, 0, 0, 7565, 66363, 12952, 64806, + 43180, 77928, 7414, 77929, 43982, 74288, 622, 74023, 885, 43405, 1602, 0, + 983731, 852, 0, 12160, 120212, 10212, 65435, 129092, 12071, 9609, 12156, + 917983, 917984, 43586, 11035, 10411, 917988, 10255, 6710, 10279, 4194, + 10375, 43853, 128599, 4315, 12644, 127516, 77937, 43639, 43343, 67408, + 128945, 11501, 41177, 128689, 128866, 43431, 127097, 92413, 8715, 0, + 41179, 983356, 43313, 120230, 41176, 0, 994, 0, 8452, 120505, 73966, + 66890, 70812, 5921, 0, 2597, 0, 5922, 118903, 66873, 4186, 92531, 119967, 127105, 6718, 0, 4406, 74601, 8480, 9192, 9747, 126530, 4413, 92196, 42268, 3198, 5924, 5920, 92469, 6921, 78081, 74007, 42869, 8418, 11681, 43169, 10176, 0, 742, 0, 2893, 10772, 65276, 5937, 1914, 2553, 11682, - 6756, 128590, 128646, 8363, 0, 2993, 7772, 3916, 4301, 120494, 1141, - 42407, 8159, 718, 7572, 973, 0, 120718, 3235, 2415, 43164, 0, 8018, - 42333, 74756, 10675, 6937, 42486, 43381, 65390, 10067, 0, 1202, 0, 0, - 65863, 0, 0, 94013, 78182, 64542, 3260, 73829, 65388, 9945, 8419, 78042, - 6738, 0, 43681, 69728, 2059, 0, 0, 55237, 1431, 0, 66565, 10821, 0, - 12804, 128076, 8229, 1235, 3307, 11472, 78089, 78184, 4544, 0, 0, 0, - 1740, 78097, 8758, 985, 12872, 64511, 78094, 12068, 78102, 0, 10141, 0, - 63761, 8785, 4476, 78109, 63763, 12655, 8907, 78105, 78106, 78103, 78104, - 0, 119572, 10665, 64616, 41572, 0, 127160, 0, 41573, 0, 3931, 120295, - 74143, 0, 0, 0, 78460, 11982, 0, 0, 0, 128016, 64484, 0, 41167, 0, 41735, - 94019, 717, 10754, 0, 0, 127979, 0, 63767, 0, 1780, 6936, 0, 92254, 819, - 10611, 9694, 126978, 0, 0, 0, 0, 8343, 8342, 8345, 8344, 6578, 7009, - 7523, 6922, 8348, 8347, 7525, 3346, 8339, 128165, 128338, 575, 268, - 78111, 8563, 5754, 120343, 41541, 65565, 8336, 5936, 7290, 78117, 8337, - 8341, 308, 11388, 7522, 120721, 78123, 65466, 11090, 6953, 0, 120346, 0, - 78132, 5926, 78128, 78130, 78126, 78127, 78124, 78125, 9038, 7887, 43456, - 7830, 11651, 13093, 64002, 0, 65742, 12874, 119597, 11590, 0, 74048, - 128350, 8595, 0, 917947, 43703, 13097, 0, 64643, 13283, 12697, 0, 12381, - 3488, 5933, 10033, 73738, 66241, 65570, 0, 12297, 119153, 1955, 0, 5349, - 42538, 0, 0, 7411, 9462, 917554, 0, 0, 0, 42736, 0, 5756, 983221, 7638, - 41642, 42764, 0, 43109, 7637, 5752, 74037, 0, 73832, 128827, 120635, - 128231, 78334, 0, 7636, 65171, 9124, 0, 78892, 120798, 291, 0, 0, 2027, - 66230, 10080, 78136, 10403, 0, 4640, 64713, 10224, 120429, 42512, 120431, - 120430, 0, 128351, 127489, 127148, 0, 92499, 0, 119094, 74213, 7824, 0, - 0, 41274, 5778, 6302, 0, 0, 12680, 119130, 1417, 77889, 194914, 9452, 0, - 74393, 11552, 0, 127855, 128217, 65391, 0, 10172, 65453, 63789, 41264, - 78658, 6426, 4641, 9179, 64819, 55278, 41255, 42036, 41469, 41269, - 120412, 41267, 4646, 120425, 865, 42034, 78274, 78273, 4645, 42033, - 78270, 127982, 983172, 64728, 0, 78673, 78674, 1659, 919, 42784, 1671, - 195089, 6069, 9219, 128558, 1661, 13120, 63784, 69819, 10140, 9713, + 6756, 125104, 128646, 8363, 0, 2993, 7772, 3916, 4301, 120494, 1141, + 42407, 7417, 718, 7572, 973, 119599, 120718, 3235, 2415, 43164, 0, 8018, + 42333, 74756, 10675, 6937, 42486, 43381, 65390, 10067, 0, 1202, 0, + 983910, 65863, 0, 68484, 94013, 78182, 64542, 3260, 73829, 65388, 9945, + 8419, 78042, 6738, 0, 43681, 69728, 2059, 92422, 0, 55237, 1431, 983226, + 66565, 10821, 0, 12804, 128076, 8229, 1235, 3307, 11472, 78089, 78184, + 4544, 71228, 0, 917975, 1740, 78097, 8758, 985, 12872, 64511, 78094, + 12068, 78102, 71226, 10141, 0, 63761, 8785, 4476, 78109, 63763, 12655, + 8907, 9147, 78106, 78103, 78104, 0, 119572, 10665, 64616, 41572, 127979, + 127160, 0, 41573, 0, 3931, 120295, 74143, 0, 0, 983743, 78460, 11982, 0, + 0, 128381, 92712, 64484, 0, 41167, 0, 41735, 94019, 717, 10754, 0, 0, + 72413, 92935, 63767, 0, 1780, 6936, 0, 92254, 819, 10611, 9694, 126978, + 0, 0, 0, 129069, 8343, 8342, 8345, 8344, 6578, 7009, 7523, 6922, 8348, + 8347, 7525, 3346, 8339, 128165, 128208, 575, 268, 78111, 8563, 5754, + 120343, 41541, 65565, 8336, 5936, 7290, 78117, 8337, 8341, 308, 11388, + 7522, 120721, 78123, 65466, 11090, 6953, 0, 120346, 128939, 78132, 5926, + 68250, 78130, 78126, 78127, 78124, 78125, 9038, 7887, 43456, 7830, 11651, + 13093, 64002, 983559, 65742, 12874, 119597, 11590, 0, 74048, 67379, 8595, + 9835, 917947, 43703, 13097, 0, 64643, 13283, 12697, 0, 12381, 3488, 5933, + 10033, 71101, 66241, 65570, 0, 12297, 71212, 1955, 127970, 5349, 42538, + 0, 0, 7411, 9462, 917554, 0, 128465, 0, 42736, 0, 5756, 128324, 7638, + 41642, 42764, 0, 43109, 7637, 5752, 11213, 0, 73832, 128827, 120635, + 128231, 78334, 0, 7636, 65171, 9124, 0, 78892, 120798, 291, 0, 983221, + 2027, 66230, 10080, 78136, 10403, 70869, 4640, 64713, 10224, 120429, + 11183, 120431, 120430, 0, 128351, 127489, 127138, 0, 92499, 0, 119094, + 74213, 7824, 0, 0, 41274, 5778, 6302, 0, 0, 12680, 119130, 1417, 67242, + 93041, 9452, 0, 74393, 11552, 0, 127855, 128217, 65391, 128614, 10172, + 65453, 63789, 41264, 78658, 6426, 4641, 9179, 64819, 55278, 41255, 42036, + 41469, 41269, 120412, 41267, 4646, 67759, 865, 42034, 78274, 78273, 4645, + 42033, 78270, 127982, 983172, 64728, 0, 78673, 78674, 1659, 919, 42784, + 1671, 195089, 6069, 9219, 128558, 1661, 13120, 63784, 69819, 10140, 9713, 119143, 0, 0, 94050, 2306, 10485, 118943, 6068, 10612, 195099, 119567, - 195101, 92561, 41462, 120470, 195079, 5422, 128234, 983629, 0, 0, 10229, - 10635, 826, 128081, 195082, 195085, 195084, 195087, 6483, 92211, 1808, - 7848, 0, 8100, 78227, 78669, 78670, 13301, 78667, 9667, 78665, 78872, 0, - 11003, 9904, 0, 0, 120690, 9144, 10921, 0, 78680, 9840, 65131, 78678, - 77841, 10313, 0, 0, 64320, 10265, 78686, 10962, 78684, 43008, 8945, - 78683, 0, 41, 195072, 1792, 120515, 195073, 8655, 195075, 92544, 77951, - 12066, 0, 385, 4152, 2585, 127804, 119068, 3126, 0, 74136, 10957, 983703, - 43258, 119116, 127873, 13157, 0, 917544, 3570, 0, 7443, 0, 44006, 6997, - 68004, 126631, 7879, 8739, 11075, 0, 65216, 0, 69795, 2593, 8463, 7810, - 917862, 7839, 119913, 78806, 119912, 9691, 4411, 78802, 0, 0, 43442, - 69851, 65254, 10066, 983889, 0, 0, 0, 13061, 8016, 78687, 19932, 64831, - 0, 119923, 12390, 119171, 1634, 68115, 0, 11056, 983574, 119925, 0, - 41165, 11328, 12450, 0, 41166, 0, 12456, 119914, 171, 5941, 12452, - 194709, 12458, 12531, 78779, 43013, 63800, 74162, 127569, 120483, 9969, - 120767, 12454, 63806, 42132, 12063, 78425, 78424, 3230, 0, 0, 0, 5209, - 297, 5810, 8522, 8415, 119937, 78429, 78428, 7077, 2497, 128651, 960, - 74156, 6981, 92374, 12938, 4292, 0, 74815, 10512, 0, 74814, 78875, - 127505, 78876, 2503, 73778, 1762, 69794, 2495, 78873, 5844, 68031, - 118838, 0, 12654, 4663, 1899, 78877, 2507, 64121, 8726, 65594, 0, 0, 0, - 8892, 0, 92339, 0, 983073, 5782, 420, 0, 0, 43796, 10797, 63794, 0, 0, - 64814, 63796, 77965, 0, 66581, 119204, 41608, 0, 0, 63792, 4659, 120788, - 0, 43676, 0, 69673, 0, 0, 0, 329, 77968, 92707, 917548, 7399, 0, 41188, - 13244, 120466, 42167, 7435, 78193, 5380, 119086, 69225, 1155, 11365, - 43126, 77972, 0, 65684, 0, 5601, 65192, 42765, 63752, 0, 7987, 128543, - 1172, 69799, 6786, 43601, 120476, 74126, 5603, 0, 4473, 0, 194823, 0, - 65347, 65346, 65345, 0, 127384, 5347, 69802, 983632, 73868, 118944, - 10588, 0, 0, 63755, 0, 5343, 78422, 120661, 4555, 5341, 0, 70071, 128670, - 5351, 78675, 43104, 65244, 917892, 64541, 42519, 74472, 0, 0, 74765, - 917888, 127510, 6638, 0, 65113, 271, 74180, 65370, 8835, 65368, 12653, - 65366, 42172, 41086, 65363, 65362, 65361, 11912, 43410, 11323, 65357, - 11800, 65355, 5345, 65353, 65352, 65351, 761, 65349, 19959, 69718, 63856, - 126635, 2423, 77958, 64647, 77959, 11957, 4699, 0, 0, 0, 0, 64605, 0, 0, - 0, 4916, 0, 380, 10958, 66563, 77955, 69773, 9773, 13167, 12918, 41096, - 73980, 69245, 78254, 917893, 10684, 0, 917896, 0, 7946, 12541, 8182, - 67586, 69780, 0, 0, 0, 0, 9005, 1225, 6630, 0, 0, 0, 68011, 8847, 0, - 65876, 5535, 8329, 74590, 983208, 92609, 0, 0, 3127, 2595, 65713, 42013, - 983858, 5607, 41089, 0, 0, 74256, 2665, 11304, 43751, 74200, 4970, 8764, - 120459, 8934, 92726, 41566, 4492, 0, 65011, 41090, 0, 0, 1188, 7254, - 1100, 0, 128301, 41081, 2912, 11749, 69792, 0, 68019, 3572, 10023, 4959, - 13079, 0, 983276, 9729, 0, 0, 0, 43361, 0, 0, 11803, 7996, 9907, 41450, - 13304, 128290, 127260, 41451, 0, 11095, 8273, 127533, 3451, 983309, 972, - 41453, 983442, 0, 73883, 68022, 73945, 983735, 2288, 19955, 9538, 0, - 69807, 0, 0, 0, 0, 11396, 983440, 11019, 0, 0, 0, 68020, 41078, 71365, - 261, 5927, 7791, 0, 7362, 0, 10696, 0, 6073, 9838, 118920, 0, 6075, - 93995, 282, 126510, 6437, 74078, 128000, 9801, 0, 74177, 0, 0, 3474, - 118787, 0, 120655, 6081, 0, 78874, 74076, 78879, 0, 0, 0, 0, 0, 8751, - 11499, 120273, 7816, 12636, 4665, 12628, 4670, 92608, 120272, 68017, - 9642, 10912, 958, 0, 11387, 78878, 4666, 0, 4915, 0, 4669, 0, 68099, - 13287, 4664, 10836, 120550, 0, 69775, 0, 43595, 7450, 0, 917875, 8664, - 9697, 3606, 917873, 0, 0, 64815, 1063, 120250, 120251, 9772, 7255, 8886, - 1389, 127932, 120257, 120258, 120259, 12941, 42661, 92381, 120255, - 120256, 12301, 120266, 69820, 41102, 64428, 120262, 120263, 120264, 1017, - 66600, 523, 505, 1447, 74436, 0, 0, 0, 8608, 42789, 120613, 128704, 0, - 73855, 11307, 66707, 917871, 127751, 11745, 7919, 0, 1641, 0, 0, 8966, 0, - 0, 5908, 0, 0, 6744, 128355, 1699, 69861, 74843, 917933, 0, 6306, 10169, - 71324, 119251, 10068, 3766, 2389, 120456, 120455, 6611, 257, 43170, - 13153, 0, 42386, 0, 9436, 2599, 0, 6496, 9449, 5930, 11476, 11033, 11447, - 10541, 5622, 120436, 8477, 3760, 1718, 9442, 66433, 3776, 0, 41435, 4352, - 983610, 2435, 120809, 5621, 120385, 4201, 3778, 4203, 4202, 4205, 4204, - 120447, 3768, 68142, 765, 41440, 3764, 8473, 6373, 8469, 120438, 12947, - 4564, 0, 0, 74271, 73753, 8374, 983156, 0, 6829, 5225, 128807, 127385, 0, - 0, 119615, 0, 74793, 5626, 73807, 11771, 74075, 127236, 128019, 42614, - 5353, 5625, 74179, 0, 0, 1010, 64572, 41780, 42623, 64277, 69942, 6952, - 983272, 120752, 78762, 2590, 5629, 65552, 7551, 10325, 5632, 10471, - 120038, 120027, 120028, 120025, 5628, 120031, 970, 120029, 4772, 2400, - 5627, 120017, 120018, 120023, 64275, 120021, 8786, 0, 203, 0, 0, 0, 0, - 78350, 0, 64378, 42054, 0, 0, 554, 119649, 11358, 0, 12182, 42048, 11065, - 126464, 73891, 0, 0, 5694, 7689, 69798, 9323, 4325, 3047, 10317, 175, 0, - 0, 69764, 0, 0, 1243, 42154, 5431, 6652, 0, 69770, 43651, 0, 68118, - 128024, 1129, 126574, 0, 65900, 1986, 7846, 78804, 8661, 917772, 65255, - 0, 3845, 4490, 118969, 6649, 74400, 1456, 7530, 11977, 7249, 8366, 0, - 7756, 12342, 128568, 51, 41516, 0, 8570, 9568, 71318, 456, 7026, 8145, - 1168, 9251, 9082, 119964, 64055, 42781, 3866, 12323, 41512, 73805, 68121, - 0, 41494, 92316, 4660, 0, 10405, 0, 78803, 0, 0, 42040, 73918, 119627, - 7944, 41454, 12605, 0, 42205, 41455, 236, 64051, 78867, 8214, 0, 0, 0, - 41457, 983970, 119589, 1969, 2384, 8097, 917864, 7413, 68012, 78029, - 8766, 0, 78079, 5854, 127974, 10583, 0, 119989, 0, 10416, 917869, 3872, - 917868, 0, 8429, 0, 118806, 2838, 128802, 0, 917866, 0, 0, 0, 983967, - 94005, 11096, 120813, 10553, 1662, 8483, 120396, 43605, 5892, 43418, 0, - 73742, 66, 65, 68, 67, 70, 69, 72, 71, 74, 73, 76, 75, 78, 77, 80, 79, - 82, 81, 84, 83, 86, 85, 88, 87, 90, 89, 119862, 10357, 7385, 8170, 1704, - 8556, 0, 9659, 0, 0, 0, 9556, 0, 4503, 11353, 9647, 0, 78185, 0, 0, - 92713, 78886, 0, 0, 74229, 66593, 6438, 917979, 9109, 78882, 1289, 64599, - 0, 68009, 0, 65507, 2447, 0, 0, 128042, 126545, 983137, 0, 6334, 0, 0, - 19937, 0, 92368, 0, 5675, 254, 0, 0, 69686, 42425, 8918, 64003, 5716, - 42312, 0, 0, 6972, 42826, 0, 42464, 120567, 0, 92645, 74796, 64400, - 64693, 0, 77861, 65429, 9515, 4435, 0, 42522, 0, 68008, 11785, 7412, - 64671, 41978, 1412, 4594, 1391, 10536, 8067, 9901, 7103, 128293, 7102, - 74588, 120748, 3140, 128854, 7960, 43271, 0, 12518, 10909, 127508, 1428, - 12472, 0, 69864, 7699, 12393, 0, 0, 0, 74518, 8223, 0, 4261, 0, 0, 0, 0, - 0, 128302, 0, 128046, 43419, 0, 64554, 10574, 3878, 0, 42352, 1752, - 73785, 0, 42506, 128541, 10199, 0, 0, 68021, 65919, 0, 6695, 720, 324, 0, - 0, 43406, 983736, 1464, 40985, 0, 7974, 0, 43474, 0, 64488, 0, 0, 64041, - 74787, 0, 78865, 92258, 65597, 0, 78863, 0, 1302, 0, 78861, 119134, 0, 0, - 5204, 74774, 43404, 11835, 0, 3995, 68360, 65608, 3714, 92190, 0, 0, - 10999, 11750, 0, 43251, 68660, 43301, 0, 120557, 8130, 8672, 10845, - 11964, 0, 983185, 0, 0, 68455, 42863, 73839, 0, 0, 0, 0, 126629, 0, 468, - 612, 0, 64401, 66448, 68376, 0, 1674, 0, 5823, 983163, 12280, 0, 540, - 74564, 119017, 0, 8432, 0, 11073, 0, 64316, 0, 0, 820, 41741, 0, 120667, - 0, 64684, 126992, 3359, 7800, 69934, 65177, 6226, 353, 12396, 0, 119612, - 64742, 128682, 120282, 0, 983450, 12412, 19941, 0, 120277, 78847, 1884, - 9481, 42418, 70059, 41157, 0, 1195, 64898, 7924, 0, 41151, 2010, 0, - 41328, 42344, 0, 12409, 0, 4360, 127009, 9739, 128550, 69933, 73921, 0, - 42521, 8539, 983725, 0, 118986, 0, 4788, 0, 68023, 65734, 983455, 43790, - 0, 13075, 74429, 94063, 64569, 43532, 10837, 2492, 127197, 118901, 68637, - 41136, 43785, 11813, 9649, 41154, 119617, 5128, 4038, 41143, 65604, - 64859, 41592, 6771, 1648, 5435, 917837, 6734, 41343, 119848, 65439, - 12709, 6986, 92364, 68015, 0, 41349, 70021, 12581, 10374, 5175, 0, 73806, - 10254, 0, 10278, 10262, 69858, 41346, 0, 607, 0, 119852, 128846, 12923, - 10314, 10282, 65477, 10378, 120297, 40976, 8265, 0, 119834, 40975, 5840, - 42838, 0, 40978, 983897, 119840, 0, 983071, 0, 66444, 10538, 0, 2550, - 119836, 6779, 0, 0, 3525, 6824, 118886, 0, 0, 5619, 65822, 126567, - 194882, 7455, 0, 5616, 11486, 9656, 0, 0, 10727, 5615, 0, 120551, 42380, - 64895, 43693, 66451, 808, 5455, 11347, 0, 1026, 5620, 194887, 0, 11350, - 5617, 0, 9225, 64639, 127073, 9145, 128060, 1338, 120581, 983158, 12739, - 4603, 3084, 983155, 92484, 9858, 6037, 0, 3974, 78213, 10290, 983704, - 3083, 10322, 0, 0, 0, 41036, 0, 0, 43321, 65606, 0, 41032, 42388, 0, - 64700, 10011, 1445, 40961, 0, 119105, 0, 40960, 0, 194891, 0, 40963, - 64952, 10402, 0, 0, 92304, 10603, 0, 0, 983113, 0, 6714, 10083, 127069, - 194895, 78367, 127377, 0, 93963, 9073, 42585, 64302, 10704, 65030, 4787, - 0, 74829, 0, 65423, 0, 128118, 9570, 55260, 9525, 2689, 917626, 65426, 0, - 917624, 43740, 0, 40966, 917622, 13286, 3998, 42598, 42596, 503, 74237, - 8735, 2690, 66488, 42836, 127150, 41954, 917617, 1652, 772, 6688, 8310, - 65428, 3487, 43416, 3585, 10194, 43320, 119159, 128183, 194874, 6468, - 41976, 9720, 917606, 11767, 41970, 194596, 5836, 12358, 0, 4355, 9048, + 67705, 92561, 41462, 120470, 195079, 5422, 128234, 983629, 128611, + 126516, 10229, 10635, 826, 128081, 195082, 195085, 195084, 195087, 6483, + 92211, 1808, 7848, 113788, 8100, 78227, 71198, 78670, 13301, 78667, 9667, + 78665, 67704, 0, 11003, 9904, 0, 983919, 120690, 9144, 10921, 92992, + 78680, 9840, 65131, 78678, 71092, 10313, 0, 0, 64320, 10265, 67252, + 10962, 66904, 43008, 8945, 78683, 0, 41, 195072, 1792, 120515, 195073, + 8655, 68254, 92544, 77951, 12066, 67258, 385, 4152, 2585, 127804, 119068, + 3126, 0, 73983, 10957, 127037, 11160, 119116, 127873, 13157, 0, 917544, + 3570, 129187, 7443, 118804, 44006, 6997, 68004, 126631, 7879, 8739, + 11075, 0, 65216, 70196, 69795, 2593, 8463, 7810, 128543, 7839, 119913, + 78806, 119912, 9691, 4411, 78802, 129032, 124970, 43442, 69851, 65254, + 10066, 983889, 72419, 0, 0, 13061, 8016, 78687, 19932, 64831, 0, 113684, + 12390, 119171, 1634, 68115, 983962, 11056, 983574, 119925, 983099, 41165, + 11328, 12450, 983811, 41166, 0, 12456, 119914, 171, 5941, 12452, 194709, + 12458, 12531, 78779, 43013, 63800, 74162, 127569, 120483, 9969, 120767, + 12454, 63806, 42132, 12063, 78425, 78424, 3230, 0, 0, 125029, 5209, 297, + 5810, 8522, 8415, 119937, 78429, 78428, 7077, 2497, 128651, 960, 74156, + 6981, 92374, 12938, 4292, 78893, 74815, 10512, 0, 74814, 78875, 127505, + 78876, 2503, 73778, 1762, 69794, 2495, 78873, 5844, 68031, 118838, + 194658, 12654, 4663, 1899, 78877, 2507, 64121, 8726, 65594, 0, 0, 0, + 8892, 78872, 92339, 71232, 983073, 5782, 420, 129034, 917871, 43796, + 10797, 63794, 0, 0, 64814, 63796, 43861, 0, 66581, 119204, 41608, 128479, + 0, 63792, 4659, 120788, 77971, 43676, 92956, 69673, 0, 11129, 92929, 329, + 77968, 92707, 917548, 7399, 0, 41188, 13244, 67692, 42167, 7435, 78193, + 5380, 119086, 69225, 1155, 11365, 43126, 77972, 0, 65684, 0, 5601, 65192, + 42765, 63752, 0, 7987, 93055, 1172, 69799, 6786, 43601, 120476, 74126, + 5603, 0, 4473, 0, 72426, 124947, 65347, 65346, 65345, 128548, 119213, + 5347, 69802, 983632, 73868, 70852, 10588, 0, 0, 63755, 0, 5343, 78422, + 120661, 4555, 5341, 0, 70071, 128670, 5351, 78675, 43104, 65244, 917892, + 64541, 42519, 68134, 128916, 126986, 74765, 917888, 127510, 6638, 0, + 65113, 271, 74180, 65370, 8835, 65368, 12653, 65366, 42172, 41086, 65363, + 65362, 65361, 11912, 43410, 11323, 65357, 11800, 65355, 5345, 11103, + 65352, 65351, 761, 65349, 19959, 69718, 63856, 126635, 2423, 74518, + 64647, 77959, 11957, 4699, 126573, 0, 0, 0, 64605, 0, 0, 0, 4916, 0, 380, + 10958, 66563, 77955, 69773, 9773, 13167, 12918, 41096, 73980, 69245, + 78254, 917893, 10684, 0, 125063, 92906, 7946, 12541, 8182, 67586, 69780, + 0, 0, 0, 0, 9005, 1225, 6630, 0, 0, 118854, 68011, 8847, 92371, 65876, + 5535, 8329, 74590, 125036, 92609, 0, 66874, 3127, 2595, 65713, 42013, + 129188, 5607, 41089, 128626, 0, 74256, 2665, 11304, 43751, 74200, 4970, + 8764, 120459, 8934, 92726, 41566, 4492, 67271, 65011, 41090, 0, 92909, + 1188, 7254, 1100, 0, 67270, 41081, 2912, 11749, 67282, 67281, 67280, + 3572, 10023, 4959, 13079, 0, 67275, 9729, 125110, 0, 67278, 43361, + 983733, 67276, 11803, 7996, 9907, 41450, 13304, 128290, 127260, 41451, 0, + 11095, 8273, 74322, 3451, 983309, 972, 41453, 68164, 119327, 73883, + 68022, 73945, 983735, 2288, 19955, 9538, 92953, 69807, 0, 129095, 0, + 128897, 11396, 983440, 11019, 0, 128416, 0, 68020, 41078, 71365, 261, + 5927, 7791, 983087, 7362, 0, 10696, 70124, 6073, 9838, 118920, 0, 6075, + 93995, 282, 126510, 6437, 74078, 128000, 9801, 66399, 74177, 0, 0, 3474, + 67287, 0, 67286, 6081, 127217, 78874, 67289, 67283, 0, 70002, 128908, 0, + 93013, 8751, 11499, 67297, 7816, 12636, 4665, 12628, 4670, 67298, 120272, + 68017, 9642, 10912, 958, 67293, 11387, 67291, 4666, 70792, 4915, 67715, + 4669, 0, 68099, 13287, 4664, 10836, 120550, 0, 69775, 0, 43595, 7450, 0, + 917875, 8664, 9697, 3606, 917873, 983978, 0, 64815, 1063, 120250, 67312, + 9772, 7255, 8886, 1389, 127932, 120257, 120258, 120259, 12941, 42661, + 92381, 120255, 120256, 12301, 120266, 69820, 41102, 64428, 120262, + 120263, 120264, 1017, 66600, 523, 505, 1447, 74436, 0, 70340, 0, 8608, + 42789, 120613, 128704, 0, 73855, 11307, 66707, 67301, 67300, 11745, 7919, + 67304, 1641, 0, 0, 8966, 0, 127212, 5908, 71870, 67853, 6744, 67310, + 1699, 67308, 67307, 67314, 67313, 6306, 10169, 71324, 119251, 10068, + 3766, 2389, 67305, 120455, 6611, 257, 43170, 13153, 0, 42386, 0, 9436, + 2599, 0, 6496, 9449, 5930, 11476, 11033, 11447, 10541, 5622, 120436, + 8477, 3760, 1718, 9442, 66433, 3776, 917837, 41435, 4352, 67324, 2435, + 71211, 5621, 120385, 4201, 3778, 4203, 4202, 4205, 4204, 120447, 3768, + 41774, 765, 41440, 3764, 8473, 6373, 8469, 120438, 12947, 4564, 0, 74623, + 74271, 73753, 8374, 127201, 0, 6829, 5225, 66901, 127385, 0, 0, 119615, + 67319, 67318, 5626, 43507, 11771, 67322, 67321, 67320, 42614, 5353, 5625, + 74179, 67315, 0, 1010, 64572, 41780, 42623, 64277, 69942, 6952, 67329, + 67328, 67327, 2590, 5629, 65552, 7551, 10325, 5632, 10471, 120038, + 120027, 120028, 120025, 5628, 120031, 970, 120029, 4772, 2400, 5627, + 120017, 67330, 120023, 64275, 120021, 8786, 113693, 203, 74365, 0, 0, + 69985, 78350, 113703, 64378, 42054, 983150, 0, 554, 119649, 11358, 71172, + 12182, 42048, 11065, 126464, 73891, 0, 0, 5694, 7689, 69798, 9323, 4325, + 3047, 10317, 175, 0, 93029, 69764, 0, 0, 1243, 42154, 5431, 6652, 917561, + 67753, 43651, 129129, 68118, 128024, 1129, 126574, 0, 65900, 1986, 7846, + 78804, 8661, 917772, 65255, 0, 3845, 4490, 118969, 6649, 74136, 1456, + 7530, 11977, 7249, 8366, 0, 7756, 12342, 128568, 51, 41516, 0, 8570, + 9568, 71318, 456, 7026, 8145, 1168, 9251, 9082, 119964, 64055, 42781, + 3866, 12323, 41512, 73805, 68121, 0, 41494, 92316, 4660, 67114, 10405, + 127195, 78803, 0, 0, 42040, 73918, 119627, 7944, 41454, 12605, 0, 42205, + 41455, 236, 64051, 78867, 8214, 0, 113784, 120037, 41457, 983970, 119589, + 1969, 2384, 8097, 917864, 7413, 68012, 78029, 8766, 43864, 78079, 5854, + 125000, 10583, 0, 119989, 0, 10416, 917869, 3872, 917868, 0, 8429, 0, + 118806, 2838, 6429, 0, 917866, 0, 128478, 0, 983967, 94005, 11096, + 120813, 10553, 1662, 8483, 120396, 43605, 5892, 43418, 0, 73742, 66, 65, + 68, 67, 70, 69, 72, 71, 74, 73, 76, 75, 78, 77, 80, 79, 82, 81, 84, 83, + 86, 85, 88, 87, 90, 89, 119862, 10357, 7385, 8170, 1704, 8556, 0, 9659, + 0, 0, 0, 9556, 0, 4503, 11353, 9647, 125015, 78185, 128959, 0, 92713, + 78886, 0, 0, 74229, 66593, 6438, 917979, 9109, 78882, 1289, 64599, 0, + 68009, 128302, 65507, 2447, 119911, 0, 128042, 126545, 66589, 0, 6334, 0, + 0, 19937, 917793, 1322, 92359, 5675, 254, 0, 0, 69686, 42425, 8918, + 64003, 5716, 42312, 0, 0, 6972, 42826, 74409, 42464, 120567, 66899, + 67155, 74796, 64400, 64693, 0, 67687, 65429, 9515, 4435, 0, 42522, 0, + 68008, 11785, 7412, 43867, 41978, 1412, 4594, 1391, 10536, 8067, 9901, + 7103, 128293, 7102, 74588, 120748, 3140, 127276, 7960, 43271, 0, 12518, + 10909, 127508, 1428, 12472, 67254, 67253, 7699, 12393, 67257, 0, 67256, + 67255, 8223, 0, 4261, 0, 0, 74308, 0, 113712, 67153, 0, 128046, 43419, 0, + 64554, 10574, 3878, 67691, 42352, 1752, 73785, 0, 42506, 128541, 10199, + 917865, 125142, 68021, 65919, 0, 6695, 720, 324, 0, 129035, 43406, + 983736, 1464, 40985, 0, 7974, 0, 43474, 0, 64488, 128977, 0, 64041, + 74787, 0, 78865, 92258, 65597, 0, 78863, 0, 1302, 66288, 78861, 119134, + 0, 67152, 5204, 74774, 43404, 11835, 0, 3995, 68360, 65608, 3714, 92190, + 120026, 67262, 10999, 11750, 67259, 43251, 67264, 43301, 0, 120557, 8130, + 8672, 10845, 11964, 0, 128014, 0, 0, 68455, 42863, 73839, 0, 0, 67700, 0, + 113701, 43645, 468, 612, 0, 64401, 66448, 68376, 0, 1674, 0, 5823, + 129126, 12280, 70367, 540, 74564, 119017, 66422, 8432, 0, 11073, 0, + 64316, 0, 0, 820, 41741, 0, 120667, 124981, 64684, 126992, 3359, 7800, + 69934, 65177, 6226, 353, 12396, 0, 119612, 64742, 128682, 78879, 0, + 127938, 12412, 19941, 0, 120277, 70352, 1884, 9481, 42418, 70059, 41157, + 0, 1195, 64898, 7924, 0, 41151, 2010, 128883, 41328, 42344, 0, 12409, 0, + 4360, 127009, 9739, 128550, 69933, 73921, 917631, 42521, 8539, 128606, 0, + 118986, 127148, 4788, 0, 68023, 65734, 983455, 43790, 120274, 13075, + 74429, 94063, 64569, 43532, 10837, 2492, 127197, 118901, 68637, 41136, + 43785, 11813, 9649, 41154, 113731, 5128, 4038, 41143, 65604, 64859, + 41592, 6771, 1648, 5435, 67295, 6734, 41343, 119848, 65439, 12709, 6986, + 92364, 68015, 120533, 41349, 70021, 12581, 10374, 5175, 0, 73806, 10254, + 113681, 10278, 10262, 69858, 41346, 0, 607, 0, 119852, 128846, 12923, + 10314, 10282, 65477, 10378, 120297, 40976, 8265, 129149, 78639, 40975, + 5840, 42838, 0, 40978, 983897, 92945, 128020, 119809, 0, 66444, 10538, + 120810, 2550, 119836, 6779, 129130, 0, 3525, 6824, 118886, 983582, 0, + 5619, 65822, 113751, 113738, 7455, 917966, 5616, 11486, 9656, 0, 0, + 10727, 5615, 129071, 120551, 42380, 64895, 43693, 66451, 808, 5455, + 11347, 0, 1026, 5620, 194887, 0, 11350, 5617, 0, 9225, 64639, 127073, + 9145, 128060, 1338, 120581, 983158, 12739, 4603, 3084, 70408, 92484, + 9858, 6037, 0, 3974, 78213, 10290, 983704, 3083, 10322, 129048, 129030, + 0, 41036, 66897, 0, 43321, 65606, 127071, 41032, 42388, 0, 64700, 10011, + 1445, 40961, 0, 119105, 0, 40960, 0, 67727, 125106, 2223, 64952, 10402, + 0, 127179, 92304, 10603, 0, 0, 983113, 0, 6714, 10083, 127069, 194895, + 78367, 69976, 0, 93963, 9073, 42585, 64302, 10704, 65030, 4787, 0, 74829, + 0, 65423, 0, 128118, 9570, 55260, 9525, 2689, 917626, 65426, 194872, + 917624, 43740, 983177, 40966, 917622, 13286, 3998, 42598, 42596, 503, + 74237, 8735, 2690, 66488, 42836, 127150, 41954, 917617, 1652, 772, 6688, + 8310, 65428, 3487, 43416, 3585, 10194, 43320, 119159, 73955, 92315, 6468, + 41976, 9720, 917606, 11179, 41970, 66255, 5836, 12358, 0, 4355, 9048, 12180, 65027, 64680, 13038, 43699, 0, 41488, 128087, 8527, 194917, 12362, - 12435, 12360, 41053, 3266, 0, 12356, 8616, 41466, 0, 92588, 11450, 0, - 3638, 12354, 0, 3216, 0, 2358, 92606, 8633, 0, 983745, 119182, 69244, 0, - 0, 11759, 194903, 6368, 74823, 0, 41423, 8078, 10504, 127558, 41698, - 42237, 0, 7002, 983678, 41430, 42267, 41051, 41484, 0, 0, 41050, 41473, - 10466, 13099, 0, 0, 0, 6435, 0, 11362, 0, 0, 65382, 0, 41420, 0, 3625, - 78157, 41409, 0, 69639, 2041, 9178, 9672, 41427, 43541, 43317, 0, 0, 0, - 41424, 917598, 120546, 0, 128212, 0, 41417, 1261, 0, 0, 12102, 119662, - 41401, 0, 127538, 0, 78251, 0, 42290, 3275, 92472, 42329, 74759, 0, 0, 0, - 92388, 69649, 10989, 74234, 983140, 10598, 7410, 2669, 903, 0, 2920, 0, - 127232, 74603, 64504, 19928, 0, 0, 3917, 0, 11732, 0, 983180, 41448, - 41461, 128823, 0, 127912, 0, 8819, 12663, 0, 41184, 74014, 232, 74835, - 120646, 9168, 65786, 0, 0, 0, 9094, 0, 11758, 68425, 0, 1064, 42467, - 128044, 10115, 19924, 92711, 0, 7862, 64551, 13224, 8516, 41862, 66650, - 7561, 78618, 69793, 1878, 0, 983269, 2911, 0, 41178, 5427, 64823, 0, 0, - 3787, 41174, 0, 41458, 0, 41463, 42413, 11292, 2406, 775, 0, 65584, - 69923, 6074, 9618, 128668, 983952, 43440, 0, 194901, 41436, 3656, 0, - 120600, 41456, 0, 1599, 11333, 0, 6703, 8513, 0, 1613, 0, 68456, 12598, - 983191, 120734, 78745, 74500, 41460, 10145, 10542, 9937, 78746, 70029, - 9905, 0, 65730, 0, 120374, 8427, 120375, 55246, 120376, 0, 11497, 64687, - 74008, 42592, 3871, 0, 128305, 9111, 5741, 0, 194846, 120366, 119111, - 120745, 0, 120368, 0, 11648, 0, 194873, 120364, 41587, 120365, 0, 74322, - 42113, 0, 127155, 12172, 0, 74530, 65298, 65723, 194840, 73871, 65724, - 7928, 120354, 983095, 41595, 73730, 0, 42118, 73830, 66042, 10355, - 983110, 7875, 0, 41598, 3993, 0, 1545, 40971, 536, 128521, 43029, 0, 0, - 65173, 65286, 0, 0, 0, 0, 0, 0, 41375, 5402, 0, 0, 1687, 120503, 917817, - 0, 78194, 64326, 40969, 10526, 78753, 8323, 40968, 1339, 11731, 78756, 0, - 65460, 12242, 128513, 8020, 10843, 11554, 0, 0, 8266, 41006, 65722, 0, - 10710, 0, 118942, 67667, 64567, 119155, 195091, 0, 119636, 67857, 120687, - 0, 983066, 11755, 66305, 0, 0, 10917, 93979, 0, 11272, 2040, 41247, - 41326, 195060, 1741, 42370, 1227, 0, 0, 11413, 0, 0, 5283, 1586, 4978, 0, - 1984, 11830, 0, 92293, 40984, 128306, 9373, 0, 12916, 6284, 0, 41663, 0, - 0, 0, 9237, 9385, 41648, 0, 194580, 2299, 41666, 1830, 73783, 2056, - 41287, 92610, 0, 0, 42219, 128257, 0, 41987, 41676, 983059, 120823, - 983144, 41670, 0, 92590, 2796, 55291, 11683, 9902, 74521, 67988, 11451, - 983111, 128822, 42631, 2359, 0, 67844, 74164, 41238, 548, 11405, 13133, - 64368, 983239, 128795, 0, 397, 43622, 42139, 9547, 9590, 128238, 1614, - 43661, 64356, 66307, 6651, 1358, 0, 428, 9620, 1466, 78112, 10982, - 118831, 1333, 7104, 407, 6425, 128834, 74253, 0, 0, 0, 5804, 11976, 8554, - 92721, 0, 0, 9057, 42294, 41218, 0, 0, 78137, 1883, 10952, 8048, 78142, - 41225, 92621, 42915, 983676, 128684, 0, 4407, 0, 65809, 119074, 194821, - 8448, 7141, 74183, 0, 12675, 12659, 0, 42363, 120624, 194824, 55273, - 10766, 12012, 2386, 64732, 9170, 917821, 9123, 64585, 120500, 119158, - 7140, 10977, 127378, 4164, 9081, 0, 120569, 42049, 42042, 8709, 128283, - 126477, 120637, 42419, 64799, 42047, 0, 0, 8470, 11807, 65897, 577, 0, - 983760, 74300, 0, 127308, 74840, 0, 0, 128791, 92224, 8736, 1414, 42643, - 9683, 43486, 74344, 0, 2536, 0, 66330, 0, 0, 0, 0, 0, 0, 0, 66317, 69945, - 66315, 2106, 120222, 11273, 0, 43004, 7541, 0, 0, 961, 64307, 66324, - 64906, 128591, 3106, 65917, 41284, 1696, 0, 891, 12105, 0, 42624, 12802, - 3264, 8824, 13268, 43003, 10936, 0, 0, 0, 194826, 92688, 0, 2322, 120371, - 983584, 11449, 128187, 42868, 41285, 3547, 0, 0, 128793, 983398, 43216, - 6089, 78682, 0, 120578, 4170, 1029, 127761, 127036, 119224, 42374, 0, - 744, 0, 0, 0, 65823, 127826, 0, 3551, 0, 0, 4623, 55268, 0, 4598, 983162, - 65136, 127136, 0, 0, 10851, 0, 6179, 92602, 6180, 0, 11952, 120778, - 78648, 11972, 78646, 78647, 78644, 78645, 177, 78643, 6176, 120580, 0, 0, + 12435, 12360, 41053, 3266, 0, 12356, 8616, 41466, 42924, 92588, 11450, 0, + 3638, 12354, 67299, 3216, 0, 2358, 92606, 8633, 71201, 983745, 119182, + 69244, 128418, 70375, 11759, 194903, 6368, 74823, 67303, 41423, 8078, + 10504, 127558, 41698, 42237, 983452, 7002, 125135, 41430, 42267, 41051, + 41484, 0, 128056, 41050, 41473, 10466, 13099, 983327, 70371, 983777, + 6435, 0, 11362, 128973, 0, 65382, 92770, 41420, 983655, 3625, 78157, + 41409, 0, 69639, 2041, 9178, 9672, 41427, 43541, 43317, 0, 0, 0, 41424, + 917598, 120546, 0, 128212, 0, 41417, 1261, 0, 0, 12102, 119662, 41401, 0, + 127538, 0, 78251, 124943, 42290, 3275, 92472, 42329, 74759, 125141, 0, + 128257, 92388, 69649, 10989, 74234, 113781, 10598, 7410, 2669, 903, 0, + 2920, 0, 127232, 74603, 64504, 19928, 0, 128411, 3917, 0, 11732, 0, + 983180, 41448, 41461, 128823, 0, 113721, 113758, 8819, 12663, 0, 41184, + 74014, 232, 74835, 120646, 9168, 65786, 0, 0, 0, 9094, 0, 11758, 68425, + 71886, 1064, 42467, 128044, 10115, 19924, 92711, 0, 7862, 64551, 13224, + 8516, 41862, 66650, 7561, 78618, 69793, 1878, 0, 983269, 2911, 128218, + 41178, 5427, 64823, 0, 0, 3787, 41174, 0, 41458, 67147, 41463, 42413, + 11292, 2406, 775, 0, 65584, 69923, 6074, 9618, 128668, 983727, 43440, + 74539, 194901, 41436, 3656, 917805, 120600, 41456, 67694, 1599, 11333, + 194896, 6703, 8513, 0, 1613, 0, 68456, 12598, 983191, 120734, 78745, + 74500, 41460, 10145, 10542, 9937, 78746, 67144, 9905, 0, 65730, 0, + 120374, 8427, 120375, 55246, 120376, 194940, 11497, 64687, 74008, 42592, + 3871, 983584, 128305, 9111, 5741, 0, 194846, 120366, 119111, 11150, 0, + 120368, 983570, 11648, 0, 194873, 120364, 41587, 70391, 127061, 71108, + 42113, 0, 127155, 12172, 92988, 74530, 65298, 65723, 68289, 73871, 65724, + 7928, 120354, 983095, 41595, 73730, 64671, 42118, 73830, 66042, 10355, + 983110, 7875, 0, 41598, 3993, 194909, 1545, 40971, 536, 128521, 43029, 0, + 0, 65173, 65286, 0, 70331, 917799, 0, 94065, 0, 41375, 5402, 128748, 0, + 1687, 120503, 917817, 0, 78194, 64326, 40969, 10526, 73747, 8323, 40968, + 1339, 11731, 78756, 127108, 65460, 12242, 128513, 8020, 10843, 11554, 0, + 0, 8266, 41006, 65722, 0, 10710, 74045, 118942, 67667, 64567, 119155, + 92900, 0, 71889, 67857, 120687, 0, 92958, 11755, 66305, 68332, 0, 10917, + 93979, 0, 11272, 2040, 41247, 41326, 195060, 1741, 42370, 1227, 0, + 128958, 11413, 127250, 0, 5283, 1586, 4978, 0, 1984, 11830, 43819, 92293, + 40984, 42904, 9373, 0, 12916, 6284, 194888, 41663, 983093, 0, 68313, + 9237, 9385, 41648, 0, 128953, 2299, 41666, 1830, 73783, 2056, 41287, + 92610, 0, 71917, 42219, 70118, 0, 41987, 41676, 983059, 120823, 983144, + 41670, 0, 92590, 2796, 55291, 11683, 9902, 74521, 67988, 11451, 983111, + 78855, 42631, 2359, 71890, 67844, 74164, 41238, 548, 11405, 13133, 64368, + 127270, 128795, 66272, 397, 43622, 42139, 9547, 9590, 128238, 1614, + 43661, 64356, 66307, 6651, 1358, 127962, 428, 9620, 1466, 78112, 10982, + 113785, 1333, 7104, 407, 6425, 128834, 74253, 0, 0, 0, 5804, 11976, 8554, + 92721, 0, 70167, 9057, 42294, 41218, 125097, 0, 78137, 1883, 10952, 8048, + 70443, 41225, 92621, 42915, 128616, 128512, 0, 4407, 74648, 65809, 11837, + 194821, 8448, 7141, 74183, 120334, 12675, 12659, 74634, 42363, 120624, + 194824, 55273, 10766, 12012, 2386, 64732, 9170, 917821, 9123, 64585, + 10296, 119158, 7140, 10977, 127378, 4164, 9081, 0, 120569, 42049, 42042, + 8709, 128283, 126477, 120637, 42419, 64799, 42047, 0, 194820, 8470, + 11807, 65897, 577, 0, 983760, 74300, 0, 127308, 74840, 126474, 0, 128791, + 92224, 8736, 1414, 42643, 9683, 43486, 74344, 0, 2536, 0, 66330, 0, 0, 0, + 0, 0, 0, 194830, 66317, 69945, 66315, 2106, 92762, 11273, 125068, 43004, + 7541, 0, 0, 961, 64307, 66324, 64906, 128591, 3106, 65917, 41284, 1696, + 0, 891, 12105, 0, 42624, 12802, 3264, 8824, 13268, 43003, 10936, 0, 0, 0, + 194826, 92688, 3566, 2322, 120371, 70831, 11449, 128187, 42868, 41285, + 3547, 0, 0, 113746, 983398, 43216, 6089, 78682, 68490, 120578, 4170, + 1029, 127761, 127036, 119224, 42374, 0, 744, 92883, 113739, 0, 65823, + 127826, 11182, 3551, 92938, 0, 4623, 55268, 128738, 4598, 983162, 65136, + 127136, 0, 128169, 10851, 0, 6179, 92602, 6180, 0, 11952, 120778, 78648, + 11972, 78646, 78647, 78644, 78645, 177, 78643, 6176, 120580, 983696, 0, 6177, 9020, 78652, 78653, 6178, 120249, 120242, 128027, 67673, 2214, - 8754, 0, 120237, 2137, 43081, 0, 0, 9136, 120240, 4401, 41280, 0, 8974, - 2308, 0, 74149, 0, 2318, 983183, 66361, 8198, 0, 64360, 12601, 42536, - 65266, 120827, 74307, 92462, 6970, 5404, 43332, 3667, 7936, 12925, - 126989, 6385, 0, 0, 118949, 10874, 65505, 128083, 0, 42053, 2075, 42057, - 11083, 42052, 0, 0, 67651, 0, 9665, 92300, 983666, 13181, 0, 0, 0, 70088, - 74148, 0, 0, 120225, 120229, 120224, 74172, 41145, 0, 94096, 983946, - 41148, 8683, 7594, 127519, 0, 119090, 10869, 43458, 41146, 92407, 11441, - 0, 3512, 119633, 983709, 8103, 0, 0, 65184, 11780, 41563, 42796, 0, - 69742, 41544, 65146, 0, 0, 0, 0, 19942, 0, 118908, 7988, 10436, 74273, - 3271, 73804, 64711, 0, 94064, 0, 0, 3804, 13070, 11557, 42044, 0, 1095, - 0, 3599, 127774, 0, 128861, 8514, 0, 0, 0, 74346, 66697, 0, 11684, 0, - 92486, 917603, 0, 42043, 43232, 66677, 0, 42046, 78241, 4036, 126481, 0, - 128213, 194861, 0, 11954, 93978, 1450, 12986, 1340, 0, 65441, 92722, 0, - 0, 127772, 0, 917542, 0, 0, 6539, 0, 0, 0, 194856, 0, 120492, 41190, - 3973, 119365, 4575, 41193, 7982, 429, 0, 127194, 0, 194854, 65792, 0, - 118968, 6417, 118918, 78178, 0, 194850, 0, 0, 4919, 10590, 128556, 7755, - 0, 0, 64548, 120506, 1621, 10214, 65126, 0, 127004, 0, 12188, 983668, - 1617, 8050, 0, 5015, 0, 119174, 42590, 194871, 1756, 78181, 0, 65768, - 6352, 41892, 0, 7555, 13103, 5408, 2817, 1214, 69919, 92335, 983125, 0, - 0, 0, 127195, 7957, 8689, 64723, 1056, 42896, 74147, 194813, 0, 55286, - 7073, 65850, 12327, 983948, 119028, 0, 0, 0, 2341, 8450, 8484, 8474, - 983260, 0, 70079, 8461, 128102, 12153, 12799, 0, 43709, 43708, 9451, - 7571, 13073, 0, 0, 681, 983252, 703, 0, 3272, 8781, 12894, 70077, 11709, - 92288, 74446, 0, 92532, 0, 11338, 120768, 3276, 0, 0, 65928, 0, 0, 65021, - 64795, 74574, 0, 10047, 78814, 3262, 78811, 42711, 0, 0, 68478, 163, 576, - 9895, 1655, 78817, 74591, 78815, 78816, 983122, 0, 0, 0, 10039, 0, - 983945, 5623, 5717, 5776, 0, 0, 0, 41591, 11036, 65252, 92382, 0, 0, 0, - 67848, 0, 0, 0, 8887, 127521, 7295, 11031, 0, 43157, 0, 8946, 10348, - 10412, 8755, 0, 0, 5718, 13221, 0, 0, 78135, 0, 983711, 8810, 74499, 686, - 0, 71362, 4619, 118954, 6654, 73769, 74426, 0, 12040, 65689, 10128, - 65118, 0, 119151, 74205, 92651, 0, 2401, 68144, 8792, 983648, 0, 65455, - 0, 92246, 0, 119129, 0, 12886, 127920, 66624, 0, 43557, 10300, 10161, - 10396, 74135, 983453, 118945, 78118, 73851, 3010, 6441, 78122, 1458, - 41475, 128672, 93975, 0, 11479, 0, 120356, 6350, 12864, 69674, 78114, - 1061, 64780, 2001, 43111, 55230, 128686, 4052, 0, 7626, 0, 0, 1045, 0, - 5631, 41113, 0, 0, 43707, 74127, 0, 0, 8486, 0, 73758, 2335, 4362, - 983195, 126561, 69221, 1025, 0, 42625, 917627, 78084, 41443, 0, 128206, - 0, 1774, 1523, 0, 0, 41445, 78236, 0, 8567, 41442, 3988, 0, 78237, - 118910, 0, 65274, 8564, 78199, 78238, 127515, 0, 0, 43446, 0, 66513, - 6256, 0, 579, 55218, 10206, 983075, 6375, 2673, 0, 11814, 0, 4488, 0, - 127336, 68451, 10444, 118846, 127334, 11799, 74407, 68466, 4487, 127849, - 42832, 1032, 120267, 43450, 78257, 7203, 0, 614, 78191, 127325, 120615, - 0, 78262, 128669, 127323, 0, 43121, 0, 0, 92513, 1050, 7549, 0, 0, 9314, - 0, 0, 120616, 0, 10057, 0, 127313, 0, 66504, 983171, 0, 2307, 0, 64333, - 127312, 128547, 73873, 0, 94035, 0, 127973, 128708, 0, 10360, 6746, 0, - 92245, 440, 0, 13085, 9233, 74216, 0, 0, 9957, 128285, 66447, 8046, - 64963, 65777, 10125, 74212, 42819, 10910, 0, 1521, 9896, 93965, 10487, - 69878, 12527, 0, 7970, 0, 128660, 0, 65769, 5243, 9849, 5239, 65771, - 983235, 0, 5237, 69714, 0, 10103, 5247, 4769, 0, 118977, 12873, 2283, - 983237, 0, 3008, 4896, 0, 12087, 0, 55231, 41103, 0, 64565, 4773, 0, - 92717, 70074, 4770, 0, 917567, 8731, 65378, 127362, 120619, 9122, 128033, - 126600, 4774, 3019, 9997, 12834, 0, 9456, 10215, 120547, 0, 0, 0, 0, - 74776, 4281, 4768, 0, 41535, 4099, 9017, 0, 0, 78095, 0, 78096, 0, 0, 0, - 78098, 0, 42814, 880, 0, 0, 128021, 2134, 0, 10116, 9877, 92329, 0, 0, - 7095, 0, 74116, 6778, 0, 78090, 8243, 2427, 128141, 7093, 0, 11585, - 195003, 9962, 0, 12223, 0, 0, 1434, 120254, 5637, 11573, 0, 0, 0, 19951, - 0, 78121, 0, 0, 55283, 0, 0, 74437, 1156, 8740, 92415, 3782, 64331, 0, - 41370, 1014, 8261, 0, 0, 10835, 0, 65536, 0, 120463, 0, 7702, 118824, 0, - 43010, 65779, 65783, 1150, 10547, 5700, 0, 120603, 65383, 2339, 42594, - 5697, 118788, 0, 128576, 0, 42257, 5696, 92677, 120465, 3862, 9643, 0, 0, - 7634, 65167, 9845, 0, 0, 5701, 9722, 41490, 983153, 1426, 68217, 0, - 68447, 42204, 55270, 8571, 194991, 78067, 0, 78818, 92719, 43182, 12184, - 0, 42022, 0, 10281, 0, 5650, 43194, 64712, 10744, 0, 990, 5647, 0, 7387, - 78734, 41114, 11477, 5646, 12879, 11018, 983930, 3945, 92589, 0, 0, 0, 0, - 78212, 127746, 1020, 73763, 0, 78731, 5648, 64748, 194910, 78733, 10205, - 3545, 983585, 6984, 0, 74051, 983655, 43242, 120458, 2667, 0, 0, 0, 9911, - 0, 65020, 10097, 119166, 127145, 983662, 118836, 983748, 78427, 1140, - 78426, 0, 10159, 0, 0, 8128, 0, 0, 917965, 1815, 19910, 890, 0, 3267, + 8754, 128652, 120237, 2137, 43081, 194663, 120239, 9136, 66889, 4401, + 41280, 70801, 8974, 2308, 194750, 74149, 128327, 2318, 983183, 66361, + 8198, 0, 64360, 12601, 42536, 65266, 120827, 67279, 92462, 6970, 5404, + 43332, 3667, 7936, 12925, 126989, 6385, 128482, 128403, 118949, 10874, + 65505, 120002, 0, 42053, 2075, 42057, 11083, 42052, 0, 67266, 67651, 0, + 9665, 92300, 983666, 13181, 0, 0, 0, 70088, 74148, 0, 70419, 120225, + 120229, 120224, 74172, 41145, 66404, 94096, 74422, 41148, 8683, 7594, + 113686, 0, 119090, 10869, 43458, 41146, 92407, 11441, 0, 3512, 119633, + 92965, 8103, 0, 0, 65184, 11780, 41563, 42796, 129055, 69742, 41544, + 65146, 71314, 0, 0, 129177, 19942, 0, 118908, 7988, 10436, 74273, 3271, + 73804, 64711, 0, 94064, 983071, 0, 3804, 13070, 11557, 42044, 0, 1095, 0, + 3599, 127774, 0, 128861, 8514, 0, 0, 0, 74346, 66697, 0, 11684, 0, 92486, + 917603, 0, 42043, 43232, 66677, 0, 42046, 74157, 4036, 126481, 0, 128213, + 194861, 0, 11954, 70348, 1450, 12986, 1340, 0, 65441, 92722, 0, 0, + 125117, 0, 917542, 0, 0, 6539, 92948, 126607, 124961, 125060, 0, 120492, + 41190, 3973, 119365, 4575, 41193, 7982, 429, 0, 119129, 0, 194848, 65792, + 128408, 118968, 6417, 118918, 78178, 0, 128970, 0, 0, 4919, 10590, + 128556, 7755, 0, 92942, 64548, 120506, 1621, 10214, 65126, 68253, 127004, + 983616, 12188, 983668, 1617, 8050, 0, 5015, 0, 119174, 42590, 70354, + 1756, 78181, 0, 65768, 6352, 41892, 0, 7555, 13103, 5408, 2817, 1214, + 69919, 92335, 983125, 0, 68224, 125055, 41764, 7957, 8689, 64723, 1056, + 42896, 74147, 3559, 983918, 55286, 7073, 65850, 12327, 70853, 119028, 0, + 0, 128442, 2341, 8450, 8484, 8474, 194884, 68322, 70079, 8461, 67721, + 12153, 12799, 0, 43709, 43708, 9451, 7571, 13073, 43847, 0, 681, 983252, + 703, 0, 3272, 8781, 12894, 70077, 11709, 92288, 70514, 0, 92532, 0, + 11338, 120768, 3276, 0, 0, 65928, 0, 0, 65021, 64795, 74574, 0, 10047, + 78814, 3262, 78811, 42711, 0, 0, 68478, 163, 576, 9895, 1655, 70131, + 74591, 78815, 78816, 66888, 0, 0, 70513, 10039, 0, 983945, 5623, 5717, + 5776, 43488, 0, 66885, 41591, 11036, 65252, 92382, 0, 0, 0, 67848, + 128128, 0, 0, 8887, 127521, 7295, 11031, 0, 43157, 0, 8946, 10348, 10412, + 8755, 0, 0, 5718, 13221, 0, 0, 78135, 70515, 917616, 8810, 74499, 686, 0, + 71362, 4619, 118954, 6654, 73769, 74426, 0, 12040, 65689, 10128, 65118, + 0, 119151, 74205, 92651, 128902, 2401, 68144, 8792, 983648, 0, 65455, 0, + 74328, 0, 74561, 983718, 12886, 127920, 66624, 128350, 43557, 10300, + 10161, 10396, 71210, 78602, 118945, 9984, 73851, 3010, 6441, 70349, 1458, + 41475, 72429, 93975, 127910, 11479, 0, 120356, 6350, 12864, 69674, 78114, + 1061, 64780, 2001, 43111, 55230, 124946, 4052, 113673, 7626, 0, 0, 1045, + 0, 5631, 41113, 127544, 0, 43707, 74127, 0, 0, 8486, 0, 73758, 2335, + 4362, 983195, 126561, 69221, 1025, 127277, 42625, 70325, 78084, 41443, 0, + 128206, 0, 1774, 1523, 0, 0, 41445, 78236, 11207, 8567, 41442, 3988, + 74843, 78237, 118910, 0, 65274, 8564, 78199, 78238, 127515, 0, 0, 43446, + 0, 66513, 6256, 917807, 579, 55218, 10206, 78878, 6375, 2673, 0, 11814, + 0, 4488, 128716, 120554, 68451, 10444, 118846, 127334, 11799, 74407, + 68466, 4487, 127849, 42832, 1032, 120267, 43450, 78257, 7203, 124998, + 614, 70361, 127215, 120615, 119622, 78262, 128669, 127323, 0, 43121, + 127211, 128366, 92513, 1050, 7549, 0, 0, 9314, 70365, 92898, 120616, 0, + 10057, 70434, 127313, 128577, 66504, 983171, 0, 2307, 128456, 64333, + 127312, 128547, 73873, 0, 94035, 0, 127973, 128708, 70446, 10360, 6746, + 120473, 92245, 440, 0, 13085, 9233, 74216, 0, 127785, 9957, 128285, + 66447, 8046, 64963, 65777, 10125, 74212, 42819, 10910, 0, 1521, 9896, + 93965, 10487, 69878, 12527, 0, 7970, 125073, 128660, 0, 65769, 5243, + 9849, 5239, 65771, 983235, 0, 5237, 69714, 0, 10103, 5247, 4769, 983139, + 118977, 12873, 2283, 92931, 0, 3008, 4896, 128102, 12087, 0, 55231, + 41103, 92256, 64565, 4773, 0, 78549, 70074, 4770, 66891, 917567, 8731, + 65378, 66911, 120619, 9122, 128033, 126600, 4774, 3019, 9997, 12834, 0, + 9456, 10215, 120547, 0, 78556, 0, 0, 74776, 4281, 4768, 120572, 41535, + 4099, 9017, 69993, 0, 78095, 2225, 78096, 118946, 0, 0, 78098, 0, 42814, + 880, 0, 113764, 66870, 2134, 0, 10116, 9877, 92329, 0, 0, 7095, 8379, + 74116, 6778, 0, 78090, 8243, 2427, 128141, 7093, 0, 11585, 195003, 9962, + 0, 12223, 128485, 92430, 1434, 120254, 5637, 11573, 0, 0, 0, 19951, + 113730, 74419, 0, 0, 55283, 0, 70363, 74437, 1156, 8740, 92415, 3782, + 64331, 0, 41370, 1014, 8261, 128595, 0, 10835, 0, 65536, 0, 120463, + 125051, 7702, 118824, 128976, 43010, 65779, 65783, 1150, 10547, 5700, 0, + 120603, 65383, 2339, 42594, 5697, 118788, 120479, 128576, 0, 42257, 5696, + 92677, 120465, 3862, 9643, 0, 70183, 7634, 65167, 9845, 0, 0, 5701, 9722, + 41490, 128719, 1426, 68217, 983614, 68447, 42204, 55270, 8571, 67403, + 78067, 43859, 78818, 92719, 43182, 12184, 0, 42022, 0, 10281, 0, 5650, + 43194, 64712, 10744, 0, 990, 5647, 0, 7387, 78734, 41114, 11477, 5646, + 12879, 11018, 128362, 3945, 92589, 0, 194989, 194718, 0, 78212, 127746, + 1020, 73763, 983835, 78731, 5648, 64748, 194910, 78733, 10205, 3545, + 983585, 6984, 0, 74051, 128901, 43242, 120458, 2667, 0, 125037, 0, 9911, + 0, 65020, 10097, 119166, 127145, 983662, 118836, 983748, 78208, 1140, + 78426, 0, 10159, 0, 0, 8128, 0, 68326, 917965, 1815, 19910, 890, 0, 3267, 92291, 0, 10123, 0, 4410, 1041, 10576, 6354, 92581, 580, 74232, 0, 128347, 0, 0, 0, 19938, 65906, 127819, 0, 0, 3298, 5375, 10142, 0, 8215, - 0, 6134, 41246, 64402, 0, 69899, 0, 0, 0, 41382, 0, 128653, 5173, 65348, - 527, 0, 0, 92612, 128250, 78797, 11915, 0, 0, 10072, 0, 42695, 2329, - 42250, 0, 128864, 69667, 12245, 1568, 94033, 0, 0, 128120, 0, 74328, - 92708, 74769, 0, 119087, 9069, 6144, 0, 0, 73822, 0, 128010, 64917, - 41521, 118934, 494, 13250, 0, 65098, 6364, 956, 0, 12830, 10462, 73740, - 73734, 0, 0, 0, 66449, 13263, 74281, 69217, 13171, 127796, 0, 0, 92294, - 0, 1044, 41276, 0, 0, 0, 42068, 11795, 0, 0, 0, 0, 42450, 3907, 0, 64526, - 11829, 68197, 12295, 0, 11475, 0, 3020, 11537, 0, 66441, 983454, 7098, 0, - 0, 1057, 566, 42696, 0, 3016, 42274, 43464, 66490, 12921, 66571, 78472, - 92510, 3006, 4620, 127237, 983578, 0, 0, 64659, 0, 127749, 55253, 6357, - 6362, 8626, 71337, 2216, 9090, 65377, 41596, 0, 42920, 1698, 0, 64477, 0, - 43813, 1053, 0, 78269, 0, 126586, 1052, 1051, 459, 1060, 74349, 66479, 0, - 0, 0, 0, 42490, 689, 6508, 4163, 42298, 8639, 66641, 4246, 0, 0, 12130, - 0, 42337, 64596, 64375, 66481, 127850, 0, 0, 6359, 0, 43471, 983768, 0, - 0, 127274, 0, 6358, 6361, 1926, 6356, 92627, 7898, 8110, 10935, 0, 10069, - 5830, 0, 43685, 0, 0, 0, 0, 8693, 78611, 119565, 983808, 120413, 0, - 127257, 65894, 0, 0, 0, 983923, 0, 0, 119187, 2135, 78868, 0, 0, 78869, - 42313, 5579, 92412, 0, 983082, 94002, 0, 5578, 41774, 128115, 42023, - 6234, 5669, 92275, 0, 0, 0, 127506, 68202, 5583, 0, 0, 42426, 5580, - 42276, 2923, 892, 2220, 42465, 41330, 194987, 5795, 65512, 119006, 65702, - 0, 120801, 65251, 0, 65710, 0, 0, 67672, 0, 5370, 0, 2931, 1638, 10966, - 10188, 65878, 118848, 0, 69694, 69879, 128830, 8172, 42017, 0, 10844, 0, - 128195, 92424, 6374, 0, 0, 286, 78023, 1062, 0, 119999, 0, 7395, 0, 1070, - 64900, 7153, 6095, 41865, 0, 3015, 128023, 126465, 5211, 983083, 6400, 0, - 194983, 70054, 8189, 11276, 0, 0, 372, 128829, 0, 118874, 42102, 41585, - 128202, 0, 42101, 276, 78402, 0, 33, 74226, 127303, 9007, 118796, 41588, - 66033, 427, 10763, 118819, 0, 127884, 0, 1031, 6257, 0, 42104, 0, 983980, - 2328, 92409, 1071, 42899, 0, 74848, 0, 983580, 0, 1047, 0, 0, 64790, 0, - 69723, 10651, 0, 0, 0, 0, 92206, 119181, 5711, 41633, 12098, 65571, 9166, - 0, 5710, 0, 6790, 65168, 13216, 0, 69716, 69726, 0, 64611, 41623, 195001, - 5715, 69654, 0, 0, 5712, 2761, 41620, 68124, 3074, 5722, 0, 8643, 73768, - 0, 118906, 2757, 11067, 9718, 74498, 8910, 10689, 6479, 0, 0, 0, 78607, - 9196, 69670, 0, 0, 0, 0, 118911, 0, 0, 0, 0, 0, 120010, 0, 8701, 68130, - 119616, 120522, 0, 42477, 194994, 12123, 4495, 43569, 0, 0, 0, 64946, - 10992, 0, 120009, 0, 0, 9318, 93986, 13249, 65679, 73808, 0, 65457, - 42249, 7639, 43995, 67845, 42641, 5454, 0, 0, 194997, 120005, 0, 983966, - 5084, 0, 0, 118861, 0, 733, 917876, 78014, 78436, 78435, 41677, 0, 9218, - 1731, 0, 983746, 0, 67990, 0, 0, 0, 120001, 127018, 92492, 5155, 120000, - 5358, 983744, 0, 917767, 64424, 983231, 3840, 64314, 41432, 0, 78315, - 68430, 67980, 43253, 65943, 0, 3371, 10988, 0, 8771, 1479, 0, 0, 1109, - 11580, 0, 64601, 12205, 0, 0, 64507, 8868, 399, 67978, 74842, 983284, - 983721, 12149, 13088, 551, 0, 10156, 12119, 92572, 0, 2544, 65074, - 119211, 0, 0, 78011, 351, 119149, 0, 0, 55229, 0, 74268, 0, 0, 0, 42377, - 0, 0, 0, 983924, 0, 9013, 4054, 0, 983570, 983628, 0, 73960, 5585, 65881, - 2549, 74469, 0, 0, 5584, 8358, 0, 64215, 92219, 10919, 0, 7980, 126601, - 983784, 2218, 41800, 5589, 0, 2664, 41613, 5586, 118890, 0, 11356, 0, 0, - 43452, 78609, 0, 42573, 67856, 0, 78129, 0, 0, 74392, 8135, 6450, 10055, - 77996, 0, 0, 119225, 5657, 0, 9626, 0, 77994, 10179, 5654, 12939, 92573, - 120799, 0, 0, 5652, 10945, 0, 66486, 0, 3661, 7863, 0, 0, 0, 74509, - 983852, 5659, 0, 78692, 66729, 5655, 983626, 42168, 0, 1055, 917628, - 127792, 66310, 74030, 0, 12146, 73955, 73956, 11618, 0, 126990, 0, 10272, - 10304, 10368, 42518, 594, 10244, 10248, 7407, 983887, 64870, 0, 3467, - 983891, 0, 3331, 946, 10231, 1495, 8131, 74330, 0, 9562, 69222, 65927, 0, - 70036, 69696, 69769, 64656, 983726, 0, 94020, 70056, 5666, 65227, 5318, - 63994, 0, 9091, 10798, 0, 128166, 10186, 0, 7732, 983724, 64556, 0, 0, - 5668, 74445, 0, 128663, 5670, 126610, 127297, 11820, 2992, 7826, 5667, - 19952, 120807, 0, 12749, 74551, 0, 0, 66496, 4361, 119260, 1306, 9286, - 1497, 128286, 94004, 0, 0, 3571, 13247, 0, 7973, 66353, 68435, 78278, - 67896, 43192, 0, 78265, 553, 120653, 0, 128554, 5829, 0, 4587, 78285, - 65912, 0, 12746, 0, 0, 119924, 5633, 119927, 94101, 94102, 94099, 64905, - 94105, 9512, 94103, 12742, 6443, 983806, 0, 9135, 0, 41564, 0, 55219, - 128832, 983851, 0, 12148, 0, 78297, 0, 64256, 0, 11669, 0, 5634, 4524, 0, - 127270, 0, 118880, 2425, 65182, 128769, 43636, 5221, 78410, 328, 0, - 983809, 69815, 5636, 0, 5329, 0, 5638, 119918, 7940, 64938, 43223, 43760, - 5635, 3373, 2986, 78292, 74223, 3437, 78291, 6203, 4247, 0, 11920, 8274, - 0, 0, 1657, 41561, 78299, 78295, 5639, 2954, 5660, 5640, 78303, 983685, - 78300, 42227, 0, 0, 41637, 67872, 0, 78310, 41625, 43362, 78309, 120713, - 11705, 5642, 0, 5486, 0, 4356, 11710, 0, 12051, 69938, 0, 5641, 8259, 0, - 1058, 0, 67630, 0, 0, 1144, 78750, 0, 42228, 0, 73890, 118972, 0, 2800, - 0, 5645, 64964, 8652, 2547, 66484, 43634, 0, 5608, 65890, 43808, 0, - 67621, 119934, 9000, 0, 0, 92673, 1865, 0, 5613, 69950, 0, 0, 5610, 0, 0, - 65826, 2069, 0, 10787, 43999, 2997, 0, 5609, 78316, 65319, 78313, 12316, - 65376, 2412, 0, 8186, 9807, 74269, 92547, 13130, 65874, 0, 5807, 0, - 10030, 5306, 12364, 128064, 0, 11704, 0, 92583, 10211, 0, 0, 0, 0, 11706, - 9710, 0, 0, 0, 413, 65623, 7118, 0, 9133, 74262, 0, 1042, 0, 64779, - 12171, 119240, 6185, 64776, 4984, 0, 708, 11391, 0, 12241, 92720, 983899, - 1308, 0, 2534, 810, 0, 0, 0, 0, 0, 1917, 3000, 0, 0, 120739, 2364, 92443, - 74470, 66618, 65680, 120779, 10027, 0, 128154, 12337, 120722, 127368, - 983167, 2980, 755, 69774, 931, 13124, 68182, 6363, 2748, 0, 0, 65041, - 92276, 44011, 8730, 983067, 127854, 78312, 7274, 119250, 0, 7275, 78304, - 935, 0, 65840, 377, 42325, 11649, 127363, 65253, 64301, 128835, 78308, - 42341, 65284, 2417, 0, 12884, 19912, 7907, 10768, 0, 194998, 0, 10673, - 119217, 7248, 0, 128346, 1781, 5496, 3627, 62, 1649, 0, 964, 0, 127876, - 78226, 128775, 127512, 0, 0, 0, 0, 43689, 127911, 13142, 78812, 42415, - 66575, 4542, 69909, 43547, 0, 0, 7677, 2991, 4946, 42454, 11565, 7949, 0, - 983918, 11341, 42494, 3073, 65625, 9714, 11692, 4657, 0, 92724, 6478, - 9898, 43673, 65237, 6241, 7106, 4877, 983795, 6238, 0, 10548, 127049, - 4409, 0, 0, 64798, 0, 5346, 0, 94047, 6237, 4874, 0, 9176, 0, 126553, - 65231, 65884, 12678, 78748, 118912, 11378, 44018, 42785, 2408, 3251, 0, - 0, 5685, 0, 2461, 11052, 7091, 5342, 8317, 0, 68163, 5340, 0, 127820, - 43635, 73928, 127529, 0, 0, 0, 128510, 65482, 0, 9142, 0, 126470, 0, - 10938, 0, 118790, 1182, 2542, 4826, 0, 0, 128176, 529, 8580, 0, 0, 10586, - 10790, 10839, 66023, 41593, 41207, 0, 0, 41594, 225, 42828, 0, 0, 983938, - 11376, 74379, 10721, 67664, 3438, 42097, 127267, 11084, 3194, 41870, 266, - 78305, 120183, 41873, 120575, 11324, 120531, 0, 8420, 64918, 128844, - 41871, 41338, 3734, 7734, 43683, 8750, 66605, 66011, 92514, 40965, - 127937, 0, 5161, 10572, 0, 0, 0, 64349, 7287, 42162, 127552, 0, 126605, - 11948, 69220, 12359, 43429, 41369, 1697, 12191, 0, 68633, 7286, 0, 68635, - 10031, 0, 9870, 68645, 8620, 65824, 0, 11938, 0, 7285, 0, 119577, 42678, - 0, 43677, 41583, 0, 65799, 92623, 0, 0, 983936, 78169, 66199, 0, 3609, - 68624, 0, 832, 120693, 120770, 78473, 66007, 78471, 65703, 0, 0, 42732, - 5180, 92699, 41395, 41530, 11691, 64773, 92214, 74002, 0, 0, 128645, - 6348, 243, 13200, 983813, 6024, 92309, 9979, 10037, 41529, 10648, 8538, - 43687, 0, 0, 4285, 66195, 0, 4230, 0, 7367, 43256, 92353, 7563, 42376, 0, - 68442, 120512, 0, 0, 214, 0, 0, 78466, 65893, 12208, 9973, 0, 66311, - 65589, 128277, 2603, 0, 0, 0, 70047, 0, 6022, 0, 2884, 0, 11620, 0, 43, - 0, 66453, 1016, 41107, 0, 41121, 3885, 92, 65456, 64608, 0, 74801, 0, - 2074, 0, 78283, 0, 12453, 128128, 983826, 74241, 126568, 6791, 12457, - 78268, 0, 0, 0, 78279, 0, 0, 92358, 66637, 7995, 8759, 43421, 78277, - 12449, 128552, 0, 0, 8752, 3197, 4720, 10165, 0, 119249, 0, 11595, 64893, - 0, 43435, 0, 0, 4993, 0, 6168, 10934, 1946, 741, 0, 5494, 4639, 983147, - 1990, 66589, 4498, 78664, 119183, 0, 0, 69734, 2960, 73779, 0, 8969, - 128117, 43424, 127059, 0, 2950, 119579, 6210, 65753, 370, 0, 0, 0, 4953, - 983682, 0, 0, 0, 69230, 0, 0, 65688, 983246, 5063, 3517, 2964, 43663, - 917762, 6344, 74791, 10566, 10144, 66333, 8252, 729, 66016, 78253, 0, - 71317, 64923, 128040, 43669, 9032, 78263, 78264, 0, 41215, 0, 65883, 0, - 917774, 120602, 3761, 0, 0, 70068, 0, 12912, 119012, 3850, 128191, 0, 0, - 0, 0, 908, 0, 8611, 0, 0, 127555, 43691, 41197, 0, 8978, 120540, 119135, - 41586, 10527, 0, 917848, 3848, 78739, 194937, 127536, 65241, 5336, - 983259, 128786, 663, 0, 10780, 0, 0, 78767, 983257, 127163, 68193, 347, - 0, 0, 78775, 64675, 41582, 78774, 78744, 65579, 12980, 78769, 12143, - 69657, 78512, 0, 43441, 41804, 78523, 0, 78525, 0, 128859, 41584, 10681, - 0, 983695, 73938, 0, 128022, 4800, 66661, 0, 66306, 64715, 78534, 9518, - 6609, 10434, 0, 11319, 1097, 0, 917850, 41730, 983214, 0, 73847, 78761, - 65172, 41728, 41721, 0, 0, 0, 41203, 917612, 13110, 41726, 983855, 0, - 1000, 69651, 0, 41140, 1209, 73978, 0, 73750, 1073, 6321, 77878, 41138, - 0, 68213, 0, 12167, 1115, 41605, 9794, 127062, 67671, 55248, 12237, - 78787, 66314, 6587, 9290, 78782, 78783, 9231, 78781, 2959, 7926, 0, 0, 0, - 64398, 0, 119970, 12311, 983727, 78796, 78798, 78794, 78795, 68434, - 78793, 66670, 0, 0, 12290, 120169, 0, 119873, 42142, 9968, 8205, 0, 5131, - 0, 9627, 78536, 78542, 78535, 983212, 1944, 1248, 10148, 127755, 119990, - 119991, 12701, 78376, 11308, 119995, 0, 119997, 119998, 65305, 65100, - 4031, 42794, 120003, 7075, 8154, 119985, 120007, 41817, 73934, 42275, - 120011, 120012, 78526, 120014, 120015, 6041, 0, 41899, 0, 8002, 0, 4364, - 0, 0, 64332, 0, 7813, 9064, 119986, 10124, 7526, 8601, 7281, 78455, 7279, - 12041, 1418, 10885, 12673, 0, 0, 9660, 983280, 13012, 4571, 0, 0, 120164, - 12078, 2970, 0, 10933, 0, 77870, 0, 127015, 0, 41599, 0, 128831, 0, - 12950, 92160, 3486, 0, 78311, 4239, 0, 127799, 66511, 0, 2637, 64629, - 8460, 127053, 8476, 983975, 0, 0, 0, 65673, 1019, 78495, 4148, 0, 12289, - 0, 4316, 0, 13119, 8488, 5412, 66243, 9935, 0, 73864, 983203, 41734, - 8206, 74081, 9163, 3286, 9072, 5867, 13302, 7622, 7120, 41736, 92546, - 41731, 0, 7400, 5416, 68663, 118924, 10817, 0, 41539, 127284, 0, 73963, - 41855, 41867, 65564, 11277, 65892, 11536, 10620, 92272, 7115, 66030, - 73932, 5498, 73942, 41536, 0, 68204, 92587, 3459, 8997, 0, 0, 0, 0, - 92512, 0, 66377, 69781, 0, 983699, 78511, 3161, 295, 120207, 0, 92223, - 127856, 78742, 9016, 43454, 63903, 63902, 43641, 0, 3971, 0, 70063, 2952, - 78765, 11038, 10901, 63900, 63899, 63898, 94043, 667, 12332, 63887, 6086, - 41722, 0, 5172, 0, 983278, 4159, 0, 0, 9815, 63884, 19934, 63882, 41198, - 8555, 63878, 63877, 42460, 6050, 42708, 63881, 63872, 0, 42421, 0, 41723, - 63875, 63874, 11460, 7432, 1913, 41913, 63852, 126636, 0, 42348, 73892, - 6752, 446, 41911, 127906, 63851, 63850, 41910, 0, 63846, 2972, 12932, - 7262, 0, 63849, 63848, 63847, 128070, 6570, 8302, 7259, 63842, 4178, - 10746, 7250, 13214, 10041, 8105, 63892, 0, 118983, 1105, 4180, 0, 12094, - 9497, 0, 63891, 63890, 63889, 63888, 5538, 9987, 0, 118932, 1678, 13274, - 552, 120654, 44010, 10785, 0, 119170, 4557, 74459, 9159, 10171, 13125, - 63860, 5540, 63858, 63865, 281, 13242, 63862, 74154, 0, 5536, 65568, - 63857, 1388, 74169, 0, 1077, 983577, 65099, 11531, 5834, 0, 0, 0, 0, - 42773, 0, 0, 0, 119220, 0, 3663, 0, 1112, 119122, 8686, 0, 5334, 65081, - 43249, 74778, 127968, 11077, 0, 6509, 0, 5327, 0, 19907, 63869, 3478, - 7583, 7679, 2903, 0, 3001, 1158, 8745, 43746, 73748, 63866, 78626, 1915, - 4846, 0, 66371, 118984, 42105, 2990, 120128, 805, 69238, 64438, 12070, - 8760, 1117, 118987, 12212, 120123, 65174, 42357, 63835, 63834, 0, 78240, - 12225, 63838, 63837, 983853, 983804, 63833, 6042, 66360, 8083, 0, 0, - 63821, 63820, 63819, 63818, 983904, 5227, 9047, 63822, 127162, 6091, 0, - 10691, 560, 5643, 8226, 119578, 63812, 63811, 63810, 63809, 2289, 63815, - 63814, 63813, 6047, 1597, 120143, 780, 206, 77925, 4936, 65147, 8168, - 63930, 2076, 1093, 9882, 63934, 2082, 63932, 128150, 63929, 3546, 1605, - 77934, 9806, 43472, 77933, 8400, 11343, 2086, 0, 63926, 2984, 5968, 9287, - 0, 4618, 42209, 43431, 13169, 5290, 2089, 1695, 10743, 1088, 63825, 7268, - 1084, 1085, 63829, 1083, 10131, 7283, 0, 63970, 128358, 1092, 4754, 7273, - 5252, 44016, 43627, 127921, 0, 7408, 11809, 917618, 0, 0, 2965, 7258, - 8808, 0, 1089, 4187, 63937, 42119, 42120, 0, 940, 5787, 10099, 63938, 0, - 74494, 12463, 2994, 0, 118827, 0, 9664, 77939, 77940, 67892, 77938, - 74343, 0, 0, 660, 10127, 666, 9022, 5532, 43667, 5533, 77941, 78507, - 6118, 222, 979, 3884, 0, 74151, 92652, 6502, 0, 127118, 128695, 63951, - 12465, 0, 0, 128782, 63946, 1707, 63924, 12461, 63950, 63897, 63948, - 63947, 63945, 6038, 63943, 63942, 64685, 63895, 65838, 2276, 7776, 94076, - 0, 127773, 120444, 69730, 801, 43165, 1690, 63919, 63918, 63917, 13277, - 43659, 12951, 120638, 9906, 2054, 2334, 78515, 63916, 5483, 63914, 69737, - 63911, 5484, 63909, 63908, 2539, 0, 43980, 5485, 0, 42697, 9061, 5534, - 10672, 4502, 0, 253, 0, 68208, 0, 9203, 74231, 0, 11530, 92542, 68668, 0, - 118907, 0, 10474, 43426, 13257, 42354, 128099, 983698, 70044, 195065, 0, - 8413, 983816, 0, 5693, 7272, 0, 13209, 64470, 65831, 74350, 195063, 0, 0, - 0, 126639, 120097, 0, 94078, 128133, 127767, 66608, 3111, 41863, 8804, - 42913, 92187, 7270, 0, 66606, 6628, 1076, 7433, 1436, 73844, 55226, - 128353, 63982, 7393, 12807, 43413, 63906, 1598, 63904, 0, 0, 41729, 4423, - 1307, 0, 10515, 41589, 128698, 0, 6218, 0, 1430, 0, 0, 120606, 78754, - 5413, 7619, 3255, 3493, 74032, 11549, 10735, 41743, 73937, 6801, 983633, - 4518, 10990, 65073, 5167, 4481, 3771, 120158, 2710, 0, 69243, 41724, 0, - 43073, 41690, 12479, 983635, 0, 0, 983818, 70046, 1628, 127149, 983487, - 983731, 65262, 6333, 10783, 42315, 0, 63855, 94056, 0, 0, 5339, 74323, 0, - 13004, 0, 4457, 0, 0, 194818, 0, 5684, 8678, 10914, 0, 5689, 65807, 0, + 0, 6134, 41246, 64402, 983147, 69899, 0, 0, 0, 41382, 0, 128653, 5173, + 65348, 527, 0, 113782, 92612, 128250, 78797, 11915, 0, 0, 10072, 0, + 42695, 2329, 42250, 0, 11187, 69667, 12245, 1568, 94033, 0, 0, 113705, 0, + 11201, 92708, 74769, 126470, 67680, 9069, 6144, 0, 0, 73822, 0, 128010, + 64917, 41521, 118934, 494, 13250, 92250, 65098, 6364, 956, 113792, 12830, + 10462, 73740, 73734, 0, 0, 0, 66449, 13263, 74281, 69217, 13171, 127796, + 0, 0, 63885, 128528, 1044, 41276, 128363, 0, 0, 42068, 11795, 124985, 0, + 0, 0, 42450, 3907, 0, 64526, 11829, 68197, 12295, 0, 11475, 70329, 3020, + 11537, 0, 66441, 120761, 7098, 125071, 0, 1057, 566, 42696, 0, 3016, + 42274, 43464, 66490, 12921, 66571, 78472, 71207, 3006, 4620, 127237, + 983328, 0, 0, 64659, 0, 127749, 55253, 6357, 6362, 8626, 71337, 2216, + 9090, 65377, 41596, 0, 42920, 1698, 0, 64477, 0, 43813, 1053, 0, 78269, + 0, 92977, 1052, 1051, 459, 1060, 74349, 66479, 67689, 66871, 0, 70327, + 42490, 689, 6508, 4163, 42298, 8639, 66641, 4246, 0, 43514, 12130, + 983620, 42337, 64596, 64375, 66481, 127850, 0, 0, 6359, 0, 43471, 983768, + 0, 120379, 127274, 0, 6358, 6361, 1926, 6356, 92627, 7898, 8110, 10935, + 0, 10069, 5830, 127773, 43685, 74307, 0, 42910, 0, 8693, 78611, 119565, + 128621, 120413, 92192, 127257, 65894, 983566, 0, 64296, 983923, 0, 0, + 119187, 2135, 11836, 0, 0, 78869, 42313, 5579, 92412, 70384, 129113, + 43854, 71913, 5578, 11840, 128115, 42023, 6234, 5669, 92275, 0, 128439, + 0, 127506, 68202, 5583, 0, 0, 42426, 5580, 42276, 2923, 892, 2220, 42465, + 41330, 194987, 5795, 65512, 119006, 65702, 0, 120801, 65251, 68228, + 65710, 128399, 128429, 67672, 0, 5370, 70465, 2931, 1638, 10966, 10188, + 65878, 118848, 0, 69694, 69879, 74585, 8172, 42017, 92756, 10844, 0, + 128195, 92424, 6374, 119998, 128690, 286, 78023, 1062, 0, 119999, 0, + 7395, 127783, 1070, 64900, 7153, 6095, 41865, 0, 3015, 128023, 126465, + 5211, 983083, 6400, 0, 194983, 70054, 8189, 11276, 0, 0, 372, 128829, 0, + 113783, 42102, 41585, 128202, 0, 42101, 276, 78402, 67427, 33, 67425, + 67424, 9007, 67430, 41588, 66033, 427, 10763, 118819, 70872, 127884, + 983943, 1031, 6257, 0, 42104, 0, 983980, 2328, 66837, 1071, 42899, + 125088, 74848, 0, 113793, 194981, 1047, 0, 194943, 42908, 128480, 69723, + 10651, 70356, 0, 125113, 72433, 66829, 70817, 5711, 41633, 12098, 65571, + 9166, 0, 5710, 128551, 6790, 65168, 13216, 0, 69716, 69726, 0, 64611, + 41623, 195001, 5715, 69654, 71915, 0, 5712, 2761, 41620, 68124, 3074, + 5722, 0, 8643, 68525, 0, 118906, 2757, 11067, 9718, 66419, 8910, 10689, + 6479, 0, 0, 71173, 78607, 9196, 69670, 125070, 0, 128338, 0, 118911, 0, + 113682, 129194, 0, 0, 120010, 73795, 8701, 68130, 119616, 120522, 0, + 42477, 194994, 12123, 4495, 43569, 0, 0, 0, 64946, 10992, 0, 120009, + 70336, 113688, 9318, 93986, 13249, 42902, 73808, 0, 65457, 42249, 7639, + 43995, 67845, 42641, 5454, 0, 0, 70366, 120005, 119585, 983966, 5084, 0, + 0, 118861, 0, 733, 74646, 78014, 78436, 78435, 11204, 0, 9218, 1731, 0, + 92937, 71070, 67990, 0, 0, 0, 70323, 127018, 92492, 5155, 120000, 5358, + 983744, 0, 917767, 64424, 71236, 3840, 64314, 41432, 0, 78315, 68430, + 67980, 43253, 65943, 0, 3371, 10988, 127960, 8771, 1479, 0, 0, 1109, + 11580, 43657, 64601, 12205, 92782, 0, 64507, 8868, 399, 67978, 74842, + 983284, 983721, 12149, 13088, 551, 0, 10156, 12119, 92572, 118916, 2544, + 65074, 119211, 983296, 0, 78011, 351, 78013, 0, 128713, 55229, 0, 74268, + 78008, 128094, 0, 42377, 0, 0, 0, 113767, 74320, 9013, 4054, 0, 194580, + 113740, 0, 73960, 5585, 65881, 2549, 74469, 74457, 11104, 5584, 8358, + 128975, 64215, 66864, 10919, 71208, 7980, 126601, 113698, 2218, 41800, + 5589, 0, 2664, 41613, 5586, 118890, 0, 11356, 0, 0, 43452, 67245, 92993, + 42573, 66879, 0, 78129, 69767, 78752, 74392, 8135, 6450, 10055, 77996, 0, + 0, 119225, 5657, 0, 9626, 0, 77994, 10179, 5654, 12939, 92573, 120799, + 71860, 0, 5652, 10945, 917927, 66486, 0, 3661, 7863, 0, 0, 0, 70332, + 127194, 5659, 0, 78692, 66729, 5655, 983626, 42168, 194581, 1055, 71171, + 71888, 66310, 74030, 70516, 12146, 70362, 73956, 11618, 0, 42720, 92949, + 10272, 10304, 10368, 42518, 594, 10244, 10248, 7407, 983887, 64870, + 74191, 3467, 71073, 7881, 3331, 946, 10231, 1495, 8131, 74330, 0, 9562, + 69222, 65927, 0, 70036, 69696, 69769, 64656, 983726, 0, 94020, 70056, + 5666, 65227, 5318, 63994, 119596, 9091, 10798, 78664, 78508, 10186, 0, + 7732, 983724, 64556, 0, 983979, 5668, 74445, 0, 74645, 5670, 113795, + 127297, 11820, 2992, 7826, 5667, 19952, 120807, 113766, 12749, 74551, + 67757, 0, 66496, 4361, 119260, 1306, 9286, 1497, 128286, 94004, 70359, 0, + 3571, 13247, 5874, 7973, 66353, 68435, 78278, 67896, 43192, 74621, 78265, + 553, 113768, 127012, 93053, 5829, 0, 4587, 78285, 65912, 194919, 12746, + 0, 70338, 119924, 5633, 119927, 74259, 94102, 94099, 64905, 94105, 9512, + 94103, 12742, 6443, 983806, 0, 9135, 128863, 41564, 0, 55219, 128832, + 983851, 0, 12148, 0, 78297, 0, 64256, 0, 11669, 0, 5634, 4524, 0, 124936, + 128390, 118880, 2425, 65182, 128769, 43636, 5221, 78410, 328, 0, 983809, + 69815, 5636, 119917, 5329, 0, 5638, 119918, 7940, 64938, 43223, 43760, + 5635, 3373, 2986, 78292, 74223, 3437, 78291, 6203, 4247, 71169, 11920, + 8274, 68240, 983658, 1657, 41561, 78299, 78295, 5639, 2954, 5660, 5640, + 78303, 983685, 71179, 42227, 68301, 0, 41637, 67872, 194813, 78310, + 41625, 43362, 78309, 120713, 11705, 5642, 0, 5486, 0, 4356, 11710, 0, + 12051, 69938, 0, 5641, 8259, 0, 1058, 0, 67630, 0, 0, 1144, 78750, + 127293, 42228, 983714, 73890, 118972, 127352, 2800, 0, 5645, 64964, 8652, + 2547, 66484, 43634, 0, 5608, 65890, 43808, 0, 67621, 64932, 9000, 71204, + 67235, 92673, 1865, 128706, 5613, 66401, 0, 0, 5610, 0, 71199, 65826, + 2069, 0, 10787, 43999, 2997, 0, 5609, 78316, 65319, 78313, 12316, 5875, + 2412, 0, 8186, 9807, 74269, 66294, 13130, 65874, 0, 5807, 113678, 10030, + 5306, 12364, 118863, 92970, 11704, 0, 92583, 10211, 0, 120579, 0, 983202, + 11706, 9710, 125022, 0, 120655, 413, 65623, 7118, 983949, 9133, 74262, 0, + 1042, 0, 64779, 12171, 119240, 6185, 64776, 4984, 0, 708, 11391, 0, + 12241, 92720, 983899, 1308, 194992, 2534, 810, 0, 0, 128016, 71849, + 71869, 1917, 3000, 125140, 120184, 120739, 2364, 66387, 74470, 66618, + 65680, 66411, 10027, 71841, 128154, 12337, 74283, 127368, 983167, 2980, + 755, 69774, 931, 13124, 68182, 6363, 2748, 0, 0, 65041, 92276, 44011, + 8730, 194997, 127854, 78312, 7274, 119250, 0, 7275, 78304, 935, 0, 65840, + 377, 42325, 11649, 127363, 65253, 64301, 128835, 78308, 42341, 65284, + 2417, 0, 12884, 19912, 7907, 10768, 78300, 194998, 0, 10673, 119217, + 7248, 0, 43515, 1781, 5496, 3627, 62, 1649, 67876, 964, 0, 66403, 78226, + 66393, 92897, 70355, 66409, 0, 127534, 43689, 127911, 13142, 78812, + 42415, 66575, 4542, 69909, 43547, 0, 0, 7677, 2991, 4946, 42454, 11565, + 7949, 0, 69759, 11341, 42494, 3073, 65625, 9714, 11692, 4657, 0, 70810, + 6478, 9898, 43673, 65237, 6241, 7106, 4877, 129108, 6238, 0, 10548, + 127049, 4409, 0, 0, 64798, 70805, 5346, 128240, 94047, 6237, 4874, 66851, + 9176, 92882, 126553, 65231, 65884, 12678, 78748, 118912, 11378, 44018, + 42785, 2408, 3251, 11203, 983159, 5685, 0, 2461, 11052, 7091, 5342, 8317, + 0, 68163, 5340, 120559, 127820, 43635, 73928, 127529, 71069, 128395, 0, + 128510, 65482, 983580, 9142, 0, 68506, 0, 10938, 0, 118790, 1182, 2542, + 4826, 0, 0, 72438, 529, 8580, 0, 0, 10586, 10790, 10839, 66023, 41593, + 41207, 0, 983825, 41594, 225, 42828, 0, 0, 983938, 11376, 74379, 10721, + 67664, 3438, 42097, 127267, 11084, 3194, 41870, 266, 78305, 120183, + 41873, 120575, 11324, 120531, 0, 8420, 64918, 128839, 41871, 41338, 3734, + 7734, 43683, 8750, 66605, 66011, 92514, 40965, 127937, 0, 5161, 10572, 0, + 42906, 0, 64349, 7287, 42162, 120406, 983643, 126605, 11167, 69220, + 12359, 43429, 41369, 1697, 12191, 0, 68633, 7286, 0, 68635, 10031, + 125058, 9870, 67726, 8620, 65824, 0, 11938, 0, 7285, 983557, 119577, + 42678, 66842, 43677, 41583, 0, 65799, 92623, 0, 129168, 983936, 78169, + 66199, 0, 3609, 68624, 0, 832, 120693, 120770, 78473, 66007, 78471, + 65703, 71256, 128517, 42732, 5180, 92699, 41395, 41530, 11691, 64773, + 92214, 74002, 0, 0, 128645, 6348, 243, 13200, 983813, 6024, 92309, 9979, + 10037, 41529, 10648, 8538, 43687, 0, 0, 4285, 66195, 0, 4230, 92886, + 7367, 43256, 92353, 7563, 42376, 0, 68442, 120512, 0, 0, 214, 128578, 0, + 74856, 65893, 12208, 9973, 128386, 66311, 65589, 128277, 2603, 0, 70155, + 0, 70047, 0, 6022, 0, 2884, 0, 11620, 0, 43, 195020, 12682, 1016, 41107, + 0, 41121, 3885, 92, 65456, 64608, 0, 74801, 70855, 2074, 113742, 78283, + 0, 12453, 70847, 983826, 74241, 126568, 6791, 12457, 78268, 0, 66278, 0, + 78279, 0, 0, 92358, 66637, 7995, 8759, 43421, 78277, 12449, 128552, + 71224, 43868, 8752, 3197, 4720, 10165, 0, 119249, 113715, 11595, 64893, + 118905, 43435, 124964, 125030, 4993, 0, 6168, 10934, 1946, 741, 0, 5494, + 4639, 127559, 1990, 11107, 4498, 74169, 67736, 0, 127272, 69734, 2960, + 73779, 0, 8969, 128117, 43424, 73959, 0, 2950, 119579, 6210, 65753, 370, + 0, 0, 0, 4953, 983682, 983701, 0, 0, 69230, 0, 0, 65688, 983246, 5063, + 3517, 2964, 43663, 917762, 6344, 74791, 10566, 10144, 66333, 8252, 729, + 66016, 78253, 0, 71317, 64923, 120571, 43669, 9032, 78263, 78264, 0, + 41215, 0, 65883, 0, 917774, 120602, 3761, 0, 0, 70068, 120408, 12912, + 119012, 3850, 128191, 0, 128389, 0, 0, 908, 0, 8611, 0, 0, 74642, 43691, + 41197, 0, 8978, 120540, 119135, 41586, 10527, 71079, 917848, 3848, 78739, + 113800, 127536, 65241, 5336, 983259, 128786, 663, 0, 10780, 0, 0, 78767, + 983257, 127163, 68193, 347, 0, 983086, 78775, 64675, 41582, 78774, 78744, + 65579, 12980, 78769, 12143, 69657, 78512, 128493, 11153, 41804, 78523, 0, + 78525, 0, 128859, 41584, 10681, 0, 983695, 73938, 73781, 128022, 4800, + 66661, 0, 66306, 64715, 66384, 9518, 6609, 10434, 70845, 11319, 1097, + 128964, 917850, 41730, 129181, 0, 73847, 78761, 65172, 41728, 41721, + 917911, 194769, 983795, 41203, 917612, 13110, 41726, 983855, 67077, 1000, + 69651, 0, 41140, 1209, 73978, 125059, 73750, 1073, 6321, 77878, 41138, 0, + 68213, 78000, 12167, 1115, 41605, 9794, 127062, 67671, 55248, 12237, + 78787, 66314, 6587, 9290, 78782, 78783, 9231, 78781, 2959, 7926, 0, + 983948, 128833, 64398, 0, 119970, 12311, 119181, 78796, 78798, 78794, + 78795, 68434, 78793, 66670, 113797, 0, 12290, 120169, 0, 119873, 42142, + 9968, 8205, 0, 5131, 113694, 9627, 43646, 78542, 78535, 983212, 1944, + 1248, 10148, 127755, 119990, 119991, 12701, 78376, 11308, 119995, 0, + 113702, 66836, 65305, 65100, 4031, 42794, 120003, 7075, 8154, 119985, + 120007, 41817, 73934, 42275, 120011, 120012, 78526, 120014, 120015, 6041, + 0, 41899, 983286, 8002, 128367, 4364, 73732, 0, 64332, 0, 7813, 9064, + 119986, 10124, 7526, 8601, 7281, 68246, 7279, 12041, 1418, 10885, 12673, + 0, 129123, 9660, 983280, 13012, 4571, 917588, 0, 120164, 12078, 2970, + 129122, 10933, 0, 77870, 0, 77841, 0, 41599, 70159, 128831, 0, 12950, + 92160, 3486, 983973, 78311, 4239, 0, 127799, 66511, 92739, 2637, 64629, + 8460, 66834, 8476, 983975, 0, 68312, 78489, 65673, 1019, 78495, 4148, 0, + 12289, 0, 4316, 0, 13119, 8488, 5412, 66243, 9935, 92777, 73864, 983203, + 41734, 8206, 74081, 9163, 3286, 9072, 5867, 13302, 7622, 7120, 41736, + 92546, 41731, 0, 7400, 5416, 68663, 118924, 10817, 0, 41539, 127284, + 66853, 73963, 41855, 41867, 65564, 11277, 65892, 11536, 10620, 92272, + 7115, 66030, 73932, 5498, 63876, 41536, 0, 68204, 92587, 3459, 8997, 0, + 92714, 0, 129027, 92512, 0, 66377, 69781, 0, 124972, 78511, 3161, 295, + 71257, 0, 92223, 127856, 78742, 9016, 43454, 63903, 63902, 43501, 0, + 3971, 983959, 70063, 2952, 78765, 11038, 10901, 63900, 63899, 63898, + 94043, 667, 12332, 63887, 6086, 41722, 0, 5172, 0, 983278, 4159, 983562, + 0, 9815, 63884, 19934, 63882, 41198, 8555, 63878, 63877, 42460, 6050, + 42708, 63881, 63872, 0, 42421, 0, 41723, 63875, 63874, 11460, 7432, 1913, + 41913, 63852, 66869, 128971, 42348, 73892, 6752, 446, 41911, 127906, + 63851, 63850, 41910, 128637, 63846, 2972, 12932, 7262, 69968, 63849, + 63848, 63847, 113749, 6570, 8302, 7259, 63842, 4178, 10746, 7250, 13214, + 10041, 8105, 63892, 127780, 69969, 1105, 4180, 127786, 12094, 9497, 0, + 63891, 63890, 63889, 63888, 5538, 9987, 0, 118932, 1678, 13274, 552, + 120654, 44010, 10785, 0, 11192, 4557, 74459, 9159, 10171, 13125, 63860, + 5540, 63858, 63865, 281, 13242, 63862, 74154, 0, 5536, 65568, 63857, + 1388, 71902, 0, 1077, 195000, 65099, 11531, 5834, 0, 0, 0, 0, 42773, + 127899, 0, 0, 119220, 0, 3663, 127027, 1112, 70335, 8686, 126611, 5334, + 65081, 43249, 74778, 127968, 11077, 125017, 6509, 0, 5327, 127965, 19907, + 63869, 3478, 7583, 7679, 2903, 0, 3001, 1158, 8745, 43746, 73748, 63866, + 78626, 1915, 4846, 67755, 66371, 118984, 42105, 2990, 120128, 805, 69238, + 64438, 12070, 8760, 1117, 113750, 12212, 120123, 65174, 42357, 63835, + 63834, 0, 78240, 12225, 63838, 63837, 983853, 70173, 63833, 6042, 66360, + 8083, 128166, 0, 63821, 63820, 63819, 63818, 983904, 5227, 9047, 63822, + 127162, 6091, 0, 10691, 560, 5643, 8226, 119578, 63812, 63811, 63810, + 63809, 2289, 63815, 63814, 63813, 6047, 1597, 120143, 780, 206, 70126, + 4936, 65147, 8168, 63930, 2076, 1093, 9882, 63934, 2082, 63932, 128150, + 63929, 3546, 1605, 77934, 9806, 43472, 77933, 8400, 11343, 2086, 0, + 63926, 2984, 5968, 9287, 0, 4618, 42209, 11137, 13169, 5290, 2089, 1695, + 10743, 1088, 63825, 7268, 1084, 1085, 63829, 1083, 10131, 7283, 0, 63970, + 128358, 1092, 4754, 7273, 5252, 44016, 43627, 127921, 128920, 7408, + 11809, 917618, 127917, 0, 2965, 7258, 8808, 66572, 1089, 4187, 63937, + 42119, 42120, 11106, 940, 5787, 10099, 63938, 0, 74494, 12463, 2994, 0, + 118827, 68522, 9664, 70834, 77940, 67892, 77938, 74343, 67370, 0, 660, + 10127, 666, 9022, 5532, 43667, 5533, 12580, 78507, 6118, 222, 979, 3884, + 983392, 74151, 92652, 6502, 0, 11085, 128695, 63951, 12465, 917862, 0, + 128782, 63946, 1707, 63924, 12461, 63950, 63897, 63948, 63947, 63945, + 6038, 63943, 63942, 64685, 63895, 65838, 2276, 7776, 94076, 0, 92464, + 120444, 69730, 801, 43165, 1690, 63919, 63918, 63917, 13277, 43659, + 12951, 120638, 9906, 2054, 2334, 78515, 63916, 5483, 63914, 69737, 63911, + 5484, 63909, 63908, 2539, 120102, 43980, 5485, 0, 42697, 9061, 5534, + 10672, 4502, 124932, 253, 0, 68208, 120439, 9203, 74231, 0, 11530, 68634, + 68668, 0, 11127, 0, 10474, 43426, 13257, 42354, 128099, 983698, 70044, + 195065, 0, 8413, 66841, 0, 5693, 7272, 0, 13209, 64470, 65831, 74350, + 195063, 0, 0, 0, 126639, 120097, 0, 94078, 66840, 127767, 66608, 3111, + 41863, 8804, 42913, 78347, 7270, 0, 66606, 6628, 1076, 7433, 1436, 73844, + 55226, 128353, 63982, 7393, 12807, 43413, 63906, 1598, 63904, 71187, + 70393, 41729, 4423, 1307, 113692, 10515, 41589, 128698, 128918, 6218, + 113675, 1430, 0, 127778, 120606, 78754, 5413, 7619, 3255, 3493, 74032, + 11549, 10735, 41743, 73937, 6801, 983633, 4518, 10990, 65073, 5167, 4481, + 3771, 67093, 2710, 0, 66277, 41724, 67716, 43073, 41690, 12479, 983635, + 8380, 0, 71852, 70046, 1628, 127149, 128817, 129067, 65262, 6333, 10783, + 11172, 0, 63855, 70840, 113679, 0, 5339, 74323, 0, 13004, 66843, 4457, 0, + 127756, 194818, 127116, 5684, 8678, 10914, 43632, 5689, 65807, 70814, 68464, 12633, 12870, 69705, 65183, 5688, 11926, 6033, 6310, 5686, 0, - 74251, 0, 120647, 0, 50, 10558, 9871, 42612, 43655, 0, 0, 0, 66468, 0, - 13259, 4448, 0, 983845, 0, 70043, 67853, 0, 10640, 11539, 1151, 0, - 917607, 127544, 127079, 195050, 127852, 0, 0, 0, 12501, 64604, 0, 11527, - 118870, 8812, 0, 11538, 8673, 12650, 11020, 0, 66467, 2105, 8087, 78163, - 69632, 9894, 0, 0, 0, 4636, 55262, 78513, 4515, 2382, 0, 127055, 0, - 120495, 0, 128284, 12277, 194627, 11995, 92553, 0, 12158, 0, 8741, 10197, - 0, 92426, 0, 6531, 0, 127846, 473, 43415, 0, 983650, 1873, 1087, 0, 0, 0, - 78527, 66439, 43218, 983123, 194716, 7237, 12504, 74282, 0, 983571, 0, - 9489, 0, 0, 4384, 74220, 63845, 2058, 128863, 13295, 43191, 128030, 0, - 1154, 3857, 1205, 0, 0, 13100, 12958, 120706, 74168, 0, 0, 4421, 10592, - 0, 495, 119007, 41712, 7983, 0, 93997, 0, 6347, 120165, 7654, 41710, - 4196, 0, 437, 41709, 73772, 0, 0, 9465, 13290, 119180, 4997, 64306, 0, 0, - 4999, 194642, 0, 126582, 4711, 120769, 0, 2739, 0, 8044, 74834, 194643, - 41789, 128142, 10809, 0, 0, 0, 1779, 6600, 6601, 41543, 5325, 642, 64187, - 13058, 120449, 12875, 0, 92186, 13229, 0, 10575, 43399, 0, 0, 41791, - 1104, 0, 0, 10655, 0, 0, 0, 0, 1082, 195049, 8428, 6569, 0, 0, 0, 69849, - 6783, 0, 12993, 8049, 41548, 44021, 6458, 983807, 128882, 4761, 63828, - 4766, 64623, 1273, 43407, 0, 118876, 195045, 6912, 1313, 6322, 10483, - 983603, 41545, 0, 92449, 0, 0, 0, 0, 78624, 3484, 74337, 0, 0, 8503, - 5122, 41527, 0, 66320, 983811, 0, 0, 0, 41537, 69683, 8303, 8282, 11817, - 73857, 10003, 73859, 65904, 7363, 1686, 0, 78406, 11467, 3664, 65921, - 64299, 194664, 0, 0, 4324, 126, 42246, 119152, 0, 74378, 65926, 7744, - 194636, 74277, 74302, 78052, 43817, 6966, 43822, 8136, 0, 65600, 1633, 0, - 0, 4762, 1103, 0, 0, 4765, 983492, 13078, 0, 4760, 63827, 2050, 10871, - 43199, 1102, 0, 42236, 128867, 194667, 11546, 74794, 337, 0, 42591, 8627, - 12279, 1111, 0, 92161, 4707, 68206, 10143, 7883, 127081, 7880, 4522, - 8645, 5704, 13010, 0, 8304, 917561, 0, 119575, 2293, 0, 66654, 0, 92676, - 0, 13008, 0, 4385, 0, 13011, 0, 92569, 119161, 13009, 160, 2677, 0, 0, - 41793, 65763, 74221, 120141, 41792, 42770, 94054, 65762, 118829, 43821, - 5709, 0, 94053, 43816, 0, 0, 1079, 3867, 5708, 0, 0, 43797, 5706, 64768, - 5705, 8791, 4005, 0, 10237, 10991, 128816, 43459, 9173, 917581, 917580, - 13170, 12540, 917577, 42605, 120765, 126617, 68647, 917572, 10058, 0, - 74867, 194654, 127078, 3339, 11448, 1106, 917591, 917590, 917593, 3340, - 917587, 917586, 917589, 917588, 120541, 10605, 1309, 63966, 120743, 1754, - 92226, 13246, 864, 0, 118926, 8972, 0, 7849, 120092, 92533, 13240, - 195068, 5192, 4338, 67982, 10948, 917601, 13199, 92575, 1236, 13208, - 13261, 13189, 13188, 93993, 0, 7440, 0, 120153, 9553, 1590, 63777, 63776, - 13178, 63782, 63781, 63780, 63779, 1583, 0, 13260, 4550, 0, 64205, 0, 0, - 41522, 983915, 92168, 983772, 917858, 11354, 94071, 0, 42795, 0, 119195, - 11394, 194646, 13236, 13272, 13194, 1334, 69926, 4479, 1178, 65586, - 120663, 66681, 119193, 4601, 0, 0, 983765, 0, 0, 194658, 0, 6809, 63786, - 6031, 0, 63791, 63790, 1145, 63788, 7910, 63785, 43153, 754, 10192, - 13105, 8183, 120741, 2037, 0, 0, 10747, 125, 0, 64890, 0, 983131, 0, - 41719, 63758, 3523, 1074, 13258, 9536, 74077, 0, 4427, 74242, 63757, - 43145, 12217, 63754, 41532, 1349, 63750, 63749, 0, 0, 0, 63753, 63802, - 41084, 120622, 68133, 41930, 63805, 63804, 43632, 63801, 41082, 8140, - 63798, 6260, 0, 0, 94074, 63793, 11988, 3898, 128241, 10201, 12238, - 63795, 42194, 10367, 12521, 10431, 42114, 41932, 1068, 0, 12523, 12945, - 983329, 42203, 7950, 10804, 63771, 42787, 4386, 12224, 6973, 2793, 12475, - 0, 0, 63769, 9530, 983119, 12232, 13135, 8596, 5681, 63762, 4595, 63760, - 792, 0, 64803, 0, 8742, 0, 11053, 128796, 63744, 128107, 0, 7588, 63748, - 1693, 63746, 43204, 5055, 68426, 917853, 1090, 120679, 128356, 11665, - 74133, 4558, 65685, 9523, 0, 0, 78681, 11513, 0, 6157, 63775, 63774, - 63773, 13191, 12170, 3500, 3139, 0, 3170, 12485, 0, 10872, 78271, 13006, - 64433, 0, 0, 941, 0, 0, 0, 65541, 11063, 0, 8228, 0, 42065, 0, 0, 94039, - 0, 92455, 7386, 0, 64444, 0, 119863, 43603, 94075, 65397, 288, 0, 0, 0, - 10025, 69915, 2918, 0, 65300, 119871, 9883, 64726, 2790, 65395, 3793, 0, - 127829, 65393, 0, 74138, 0, 0, 0, 74139, 92712, 65394, 11548, 5270, 0, - 65396, 0, 65813, 13256, 1282, 120771, 0, 0, 10888, 983604, 65242, 0, - 3330, 0, 0, 983974, 0, 0, 74259, 3304, 42753, 0, 0, 0, 1627, 0, 0, 0, - 5371, 13116, 0, 1826, 118794, 0, 43094, 70023, 43650, 94037, 0, 9035, 0, - 0, 128005, 0, 92207, 68125, 0, 164, 0, 94067, 94000, 6958, 0, 43116, 0, - 70019, 13245, 0, 0, 127376, 0, 70031, 127756, 12666, 13175, 13207, - 120414, 66014, 120428, 7447, 5929, 0, 65509, 0, 7449, 11306, 0, 73920, - 3180, 0, 63808, 9054, 971, 13062, 0, 0, 65195, 10164, 92252, 74428, 0, - 78146, 92611, 0, 0, 0, 10045, 12882, 13275, 128161, 11057, 0, 13276, 0, - 41525, 78150, 7271, 11444, 0, 0, 0, 12229, 41523, 0, 43411, 73751, 0, - 64813, 0, 0, 10476, 3858, 0, 3932, 64958, 0, 0, 73989, 68192, 0, 69847, - 369, 0, 41784, 0, 64163, 0, 0, 0, 65474, 4796, 12292, 126595, 65479, 0, - 41781, 10486, 41480, 43002, 9899, 0, 0, 404, 12821, 3741, 0, 5788, 8092, - 68212, 41222, 1831, 66020, 3982, 0, 4388, 0, 746, 120784, 0, 0, 12018, - 65294, 0, 0, 0, 0, 4422, 4708, 3799, 74292, 119357, 0, 74430, 0, 11700, - 4374, 0, 128179, 1364, 0, 8038, 0, 917597, 12868, 69814, 0, 6735, 73979, - 13174, 73968, 13225, 0, 69808, 65835, 0, 2365, 7841, 0, 42855, 118856, - 42866, 0, 0, 0, 66438, 41785, 12617, 64172, 13173, 4372, 119354, 0, - 983568, 0, 0, 92402, 128062, 12965, 384, 64512, 10404, 10340, 119352, - 1556, 5274, 13210, 120125, 10017, 9733, 41787, 983243, 126994, 41373, - 78039, 12303, 0, 13232, 13233, 349, 4863, 41371, 11656, 0, 120703, - 119883, 12861, 4398, 8543, 65618, 128018, 1096, 0, 0, 42688, 12441, - 12355, 119348, 119347, 4318, 10452, 0, 8032, 13243, 13237, 12719, 126646, - 119101, 0, 64884, 119872, 119345, 8597, 0, 0, 9864, 0, 120785, 119874, - 94107, 13195, 41452, 64961, 7722, 0, 10459, 119878, 0, 119879, 66590, - 128123, 41533, 66337, 0, 92184, 0, 4965, 43445, 917536, 73849, 0, 43638, - 78537, 128287, 6261, 119342, 43147, 66570, 1957, 10420, 982, 2756, 13292, - 13206, 128828, 0, 2925, 73809, 13056, 127559, 13212, 43238, 0, 13190, - 13187, 92541, 13198, 118793, 0, 5242, 119179, 64476, 1694, 8216, 71369, - 6770, 43331, 0, 65620, 983728, 43544, 126466, 0, 41444, 65621, 69955, - 9197, 5246, 119106, 13185, 9709, 120323, 120322, 12314, 65616, 5238, - 119333, 0, 119337, 5236, 40979, 0, 74201, 8286, 128537, 3936, 119331, - 11699, 41347, 127249, 13235, 8842, 41248, 0, 4379, 13239, 12692, 7969, - 127266, 7219, 127250, 128251, 120509, 0, 66224, 734, 2979, 120303, 65619, - 9872, 957, 64921, 1846, 66631, 41477, 119256, 120310, 74511, 41770, 1670, - 6442, 120317, 42446, 5379, 120318, 41163, 74832, 120315, 120314, 11506, - 0, 42841, 13267, 0, 0, 41775, 0, 7130, 41773, 0, 10663, 0, 0, 0, 6151, - 12110, 42673, 65572, 65293, 65250, 13265, 13264, 64518, 0, 6100, 0, - 92647, 5808, 65922, 0, 12967, 66041, 5612, 4583, 0, 0, 68097, 64575, - 126637, 11965, 0, 68358, 0, 69789, 0, 92260, 68102, 9698, 7814, 74476, - 119651, 128514, 0, 41921, 118858, 9756, 6985, 119258, 78490, 74219, 0, 0, - 118997, 8012, 5674, 12353, 0, 12361, 5677, 5588, 0, 41925, 128124, 41920, - 5673, 120534, 5676, 41923, 12694, 118978, 5672, 1294, 0, 78059, 0, 42511, - 1727, 120725, 42436, 0, 0, 0, 74222, 8718, 3550, 736, 10268, 4505, 10316, - 74090, 5826, 55232, 5813, 0, 120712, 5841, 5837, 55234, 0, 3105, 12829, - 5838, 5796, 0, 119592, 5793, 0, 5866, 5797, 41011, 5865, 120091, 7956, - 598, 0, 64649, 5806, 42398, 0, 9037, 5671, 120041, 983255, 0, 0, 128855, - 0, 847, 128242, 9529, 0, 66657, 6980, 78483, 120035, 78484, 983491, 0, - 120033, 78486, 0, 0, 120039, 42683, 0, 983055, 7114, 0, 0, 43190, 65463, - 1554, 0, 42611, 42563, 0, 5651, 2929, 6792, 43201, 0, 19963, 5698, 0, 0, - 0, 0, 5644, 10292, 65546, 69727, 68141, 8372, 0, 65116, 0, 120022, 10175, - 10388, 42799, 94100, 41013, 10568, 0, 983618, 2869, 0, 41015, 194692, - 2785, 4366, 0, 10954, 41802, 0, 42608, 78469, 9884, 4759, 0, 0, 10266, - 41359, 1170, 43365, 69810, 73908, 1609, 902, 0, 63936, 128875, 11661, - 8122, 5818, 0, 0, 3861, 9540, 11028, 2554, 5158, 5714, 2213, 0, 0, 807, - 43079, 0, 78475, 976, 5511, 64553, 0, 42155, 0, 41356, 74110, 118801, - 126614, 0, 8676, 983291, 0, 5582, 451, 63941, 5798, 9349, 42018, 127858, - 0, 0, 43609, 5906, 120553, 1440, 0, 128853, 120016, 74283, 11005, 0, - 66656, 66044, 0, 194698, 0, 0, 43393, 10094, 0, 11529, 10857, 120643, - 66436, 6546, 93, 8102, 0, 68405, 0, 0, 8171, 0, 119097, 127064, 917543, - 383, 7154, 41656, 92634, 94040, 0, 5187, 71296, 127277, 11286, 68620, - 64217, 0, 5232, 0, 41009, 0, 41005, 0, 0, 983827, 8292, 195074, 4980, - 8860, 73947, 10028, 65291, 7076, 13182, 194705, 0, 0, 10631, 66031, 7972, - 0, 78785, 0, 7900, 0, 11309, 3806, 4198, 42725, 0, 67656, 9995, 0, 92552, - 0, 12931, 0, 42684, 74285, 2088, 64213, 64366, 65156, 8814, 42238, 74771, - 0, 0, 12836, 0, 0, 74342, 8593, 0, 0, 68445, 13255, 0, 0, 7464, 0, 65865, - 0, 194650, 127144, 0, 9342, 120464, 0, 64516, 0, 78792, 10129, 41007, - 74375, 0, 40995, 12209, 41012, 119136, 0, 0, 69724, 40992, 92264, 127153, - 68653, 43558, 5522, 0, 61, 0, 74105, 3633, 983900, 65162, 41234, 12089, - 78281, 9771, 983905, 13251, 128701, 0, 6262, 2784, 42743, 0, 8126, 66483, - 0, 0, 441, 42621, 0, 0, 41002, 40999, 119623, 43266, 7108, 194779, 10890, - 74481, 65834, 8324, 119103, 64417, 74817, 127465, 64737, 0, 983659, 8930, - 66678, 74249, 1193, 10056, 1800, 13253, 13252, 7829, 0, 0, 7743, 0, 0, - 77904, 92640, 77905, 9034, 6039, 0, 10075, 0, 41018, 65683, 10338, 66469, - 0, 0, 0, 42815, 0, 41966, 0, 127471, 0, 11792, 43064, 41025, 911, 7539, - 0, 0, 120339, 65159, 64390, 0, 0, 5520, 11662, 0, 65330, 42812, 0, 0, - 12326, 983856, 0, 42808, 128337, 9348, 64901, 983861, 0, 0, 0, 0, 0, - 917584, 43702, 983576, 5857, 65342, 92727, 119120, 120079, 8644, 0, 0, 0, - 74296, 41909, 0, 120332, 2791, 69663, 1891, 69824, 0, 41907, 66647, - 118939, 8761, 12942, 5748, 0, 10773, 0, 0, 8796, 78149, 6412, 2061, 8520, - 13146, 127185, 63931, 0, 65902, 2882, 0, 0, 12843, 4520, 120345, 92459, - 0, 983660, 0, 73860, 0, 0, 64345, 0, 9201, 128314, 194940, 0, 0, 43679, - 917585, 65117, 92270, 0, 10427, 0, 3844, 120675, 9755, 1110, 6612, 12222, - 0, 128789, 0, 0, 783, 194935, 0, 0, 983064, 194720, 65056, 3620, 41180, - 68378, 4556, 0, 0, 194933, 74250, 0, 67657, 10510, 4382, 66482, 0, 0, - 127527, 9177, 8902, 93958, 9839, 0, 12891, 983755, 983636, 63999, 2016, - 41917, 9788, 63928, 0, 1862, 65800, 9155, 66623, 9786, 65082, 41919, - 8579, 41914, 7981, 0, 66017, 4508, 64883, 92456, 92522, 127814, 0, 64592, - 74276, 120080, 6784, 78788, 68181, 0, 0, 0, 127534, 12147, 9024, 66378, - 66472, 983929, 64289, 65289, 78151, 66658, 194929, 64509, 78152, 0, - 126505, 11051, 983296, 0, 11355, 65885, 0, 128310, 41214, 0, 12299, 0, - 7500, 4506, 7773, 0, 0, 9963, 68649, 126609, 4040, 120570, 6167, 0, - 63922, 6594, 983740, 0, 0, 3624, 43036, 0, 6387, 63990, 19947, 63988, - 41955, 0, 63993, 10440, 9611, 65605, 6803, 0, 7738, 63986, 11446, 63984, - 92641, 3435, 78164, 43814, 43810, 7029, 64258, 41292, 118898, 12748, - 42742, 9517, 11518, 0, 78790, 0, 67993, 63956, 42458, 63954, 63953, - 63960, 9591, 4516, 10217, 68370, 11469, 69697, 42306, 2723, 118947, 0, 0, - 0, 0, 0, 11397, 2880, 0, 0, 2872, 0, 0, 3498, 4378, 917539, 4270, 0, - 65551, 68205, 6633, 43387, 0, 5230, 0, 0, 0, 0, 0, 8161, 393, 12013, 0, - 0, 126479, 415, 63964, 63963, 42345, 92310, 5183, 1877, 42498, 0, 2927, - 0, 63961, 4472, 0, 0, 78159, 69699, 917936, 42340, 4756, 128078, 7081, - 10730, 7691, 10331, 63830, 119625, 42922, 42103, 8628, 9813, 0, 42453, - 1604, 9565, 10539, 69701, 65764, 41415, 65767, 0, 8457, 42301, 11372, - 64873, 11992, 0, 0, 63980, 11801, 3622, 983124, 64336, 12017, 10463, - 63981, 4967, 64189, 1966, 43628, 0, 983292, 0, 0, 63971, 4347, 4416, - 42098, 11009, 10694, 63973, 402, 0, 13147, 128692, 42100, 64646, 13228, - 0, 41875, 3515, 74252, 11805, 0, 11302, 6259, 43395, 0, 0, 194670, 0, - 92351, 0, 74425, 11299, 1561, 0, 92359, 64942, 983559, 194733, 983686, - 194732, 0, 74301, 0, 11280, 0, 69784, 74060, 0, 0, 119664, 5145, 12486, - 65018, 66516, 5409, 127379, 194669, 7402, 5399, 9685, 74089, 7952, 5401, - 0, 66616, 68421, 983919, 0, 5405, 127875, 64866, 0, 119583, 128345, - 78784, 74248, 11330, 194723, 64690, 3254, 0, 0, 128207, 42390, 43678, - 194725, 983909, 65077, 0, 6388, 3355, 9508, 9867, 5723, 11520, 5611, 0, - 3377, 0, 0, 0, 0, 78228, 0, 983762, 42691, 917886, 127198, 74767, 0, - 127075, 1379, 246, 0, 983761, 3788, 983106, 11041, 92549, 66304, 0, 0, - 8917, 42403, 301, 0, 0, 0, 0, 0, 983697, 10656, 0, 65214, 119242, 42567, - 92217, 13163, 983204, 120831, 74597, 3182, 0, 0, 0, 65034, 65889, 42169, - 4755, 74244, 194621, 11443, 0, 66319, 74598, 608, 600, 0, 1219, 3934, - 64206, 11483, 74510, 0, 74485, 42442, 65470, 983907, 64202, 13160, 7759, - 42482, 485, 128006, 0, 9828, 0, 0, 42280, 0, 9351, 7778, 64379, 7496, - 42431, 6916, 1208, 0, 119631, 11002, 42470, 0, 118946, 0, 0, 74041, 0, - 70045, 43539, 5411, 42196, 0, 0, 0, 9150, 0, 42393, 13086, 1310, 194687, - 9337, 12052, 10643, 55271, 983179, 12166, 2546, 194683, 213, 118852, - 65611, 0, 0, 194756, 74310, 6554, 0, 11914, 5452, 0, 0, 0, 0, 0, 194681, - 92560, 2713, 0, 9650, 43330, 0, 194675, 1406, 0, 0, 92659, 0, 68223, - 4143, 194677, 0, 65748, 4141, 9682, 65287, 1508, 127013, 8779, 10569, - 8725, 13299, 66638, 65750, 42263, 4145, 6380, 65751, 66613, 43994, 65738, - 55250, 9185, 9550, 0, 43403, 0, 0, 0, 65736, 41951, 64816, 65756, 983205, - 12955, 10596, 2888, 194645, 0, 0, 9657, 9019, 194766, 0, 2878, 5390, 0, - 194961, 0, 68679, 43552, 7501, 6328, 0, 10429, 10365, 0, 0, 41946, 7503, - 5235, 803, 68381, 0, 0, 8986, 126542, 10632, 11934, 11452, 1332, 0, 0, - 126647, 0, 118887, 1791, 5191, 9288, 64822, 2892, 0, 43394, 555, 0, 0, - 66646, 0, 119002, 13151, 74512, 7289, 74055, 64161, 8854, 64162, 5858, - 41927, 10582, 0, 1784, 1361, 195047, 0, 7905, 0, 64868, 128813, 13158, - 92166, 7211, 0, 9371, 73973, 917553, 6828, 1625, 92302, 0, 1342, 68440, - 64171, 126704, 10903, 983494, 0, 0, 0, 0, 4482, 41606, 0, 128569, 983112, - 0, 64381, 0, 0, 195090, 42245, 126467, 41972, 0, 444, 0, 9127, 66687, - 66619, 126489, 78025, 0, 11349, 40991, 917570, 0, 119599, 120830, 0, - 1197, 128282, 1149, 194970, 0, 0, 40990, 43765, 0, 3492, 0, 127942, 0, 0, - 0, 12838, 983978, 19948, 0, 3099, 0, 0, 41087, 0, 0, 0, 119059, 12036, - 41309, 0, 0, 8152, 0, 41550, 12227, 983613, 0, 12828, 127511, 0, 0, - 120708, 0, 0, 10386, 119574, 0, 0, 92680, 983789, 68154, 0, 1743, 0, 0, - 92239, 65186, 917571, 0, 9606, 0, 0, 64439, 0, 0, 92686, 0, 0, 194967, 0, - 0, 3395, 9362, 10878, 0, 0, 78362, 64830, 0, 126557, 41091, 3426, 1344, - 8870, 0, 0, 4735, 127017, 6119, 12822, 42699, 0, 983824, 74818, 1423, 0, - 42637, 41080, 0, 12039, 10559, 0, 118892, 0, 9472, 0, 11929, 0, 7170, - 9596, 6130, 128826, 43629, 11579, 78713, 0, 194740, 128691, 92185, 66699, - 64440, 1004, 92584, 194737, 43234, 66008, 12627, 0, 68414, 0, 43619, - 43303, 11300, 43304, 9686, 5890, 11776, 7558, 127158, 65627, 0, 10718, - 13154, 3461, 9139, 0, 0, 0, 0, 65365, 73877, 65628, 78019, 120319, 0, - 41708, 12860, 2641, 12069, 10838, 5403, 10352, 70085, 10061, 43237, 0, - 5140, 209, 128847, 41704, 41056, 43078, 128125, 118809, 0, 10899, 65469, - 92362, 0, 0, 2410, 993, 0, 120589, 120689, 78693, 0, 0, 7232, 0, 119253, - 0, 7110, 74462, 2066, 10489, 42166, 43463, 10659, 3600, 0, 4224, 1336, - 41518, 0, 0, 0, 0, 41139, 64820, 92538, 12966, 41134, 0, 0, 0, 0, 272, - 4263, 8793, 0, 0, 41502, 0, 983, 12549, 0, 0, 1190, 4109, 1335, 841, - 5888, 41358, 64863, 9544, 43481, 0, 194806, 70027, 2099, 5120, 2409, - 7799, 0, 74424, 0, 0, 4731, 0, 66629, 0, 0, 1255, 4149, 9247, 0, 9913, 0, - 0, 64914, 917787, 65101, 0, 11694, 92475, 11690, 5835, 127164, 66625, - 10842, 41354, 42123, 43097, 11688, 66634, 1094, 194, 64692, 0, 8180, 0, - 0, 9972, 73865, 4519, 6114, 10898, 43072, 0, 0, 93960, 983322, 126581, - 10695, 0, 7540, 0, 881, 7857, 6067, 65164, 0, 0, 0, 13311, 68403, 41857, - 64321, 8359, 0, 12689, 0, 194594, 0, 983312, 983881, 68183, 0, 983314, - 1287, 5436, 0, 983317, 74142, 92328, 74152, 119078, 6051, 10497, 69668, - 8985, 12109, 983323, 0, 127242, 0, 0, 3652, 10537, 0, 1276, 120440, 6549, - 279, 73745, 0, 0, 0, 1489, 0, 0, 0, 3899, 1007, 42124, 983557, 42122, - 92337, 92367, 0, 11985, 1345, 78600, 0, 0, 8956, 43083, 94057, 42138, - 78610, 0, 12151, 78608, 78604, 78605, 6285, 78603, 78612, 78613, 65942, - 492, 8685, 0, 983759, 0, 78622, 43712, 2582, 11470, 64538, 7444, 78615, + 74251, 0, 120647, 128930, 50, 10558, 9871, 42612, 43655, 0, 983818, + 74284, 66468, 66905, 13259, 4448, 917804, 983845, 113734, 70043, 1321, 0, + 10640, 11539, 1151, 0, 917607, 124958, 127079, 71106, 127852, 0, 0, + 983075, 12501, 64604, 128657, 11527, 118870, 8812, 0, 11538, 8673, 12650, + 11020, 0, 66467, 2105, 8087, 78163, 69632, 9894, 0, 128943, 69995, 4636, + 55262, 78513, 4515, 2382, 0, 127055, 0, 120495, 0, 128284, 12277, 194627, + 11995, 92553, 0, 12158, 70170, 8741, 10197, 0, 92426, 0, 6531, 0, 127846, + 473, 43415, 92936, 983650, 1873, 1087, 124966, 0, 74280, 78527, 66439, + 43218, 983123, 194716, 7237, 12504, 71113, 0, 983571, 983886, 9489, 0, + 70843, 4384, 74220, 63845, 2058, 69741, 13295, 43191, 128030, 195054, + 1154, 3857, 1205, 0, 0, 13100, 12958, 120706, 74168, 0, 70846, 4421, + 10592, 0, 495, 66400, 41712, 7983, 70833, 93997, 983330, 6347, 78715, + 7654, 41710, 4196, 0, 437, 41709, 73772, 70832, 0, 9465, 13290, 119180, + 4997, 64306, 0, 0, 4999, 194642, 67401, 126582, 4711, 120769, 0, 2739, 0, + 8044, 74313, 194643, 41789, 128142, 10809, 66279, 0, 0, 1779, 6600, 6601, + 41543, 5325, 642, 64187, 13058, 120449, 12875, 983804, 92186, 13229, + 71845, 10575, 43399, 0, 0, 41791, 1104, 0, 983725, 10655, 0, 0, 0, 0, + 1082, 195049, 8428, 6569, 0, 0, 78534, 69849, 6783, 0, 12993, 8049, + 41548, 44021, 6458, 983807, 128882, 4761, 63828, 4766, 64623, 1273, + 43407, 120677, 118876, 195045, 6912, 1313, 6322, 10483, 128627, 41545, 0, + 92449, 0, 11216, 0, 0, 78624, 3484, 74337, 0, 0, 8503, 5122, 41527, + 71910, 66320, 70161, 92972, 0, 0, 41537, 66453, 8303, 8282, 11817, 73857, + 10003, 73859, 65904, 7363, 1686, 0, 70115, 11467, 3664, 65921, 64299, + 124939, 128462, 0, 4324, 126, 42246, 119152, 69984, 67725, 65926, 7744, + 194636, 74277, 66283, 78052, 43817, 6966, 43822, 8136, 0, 65600, 1633, 0, + 126614, 4762, 1103, 70827, 70157, 4765, 983492, 13078, 0, 4760, 63827, + 2050, 10871, 43199, 1102, 0, 42236, 128867, 194667, 11546, 74794, 337, 0, + 42591, 8627, 12279, 1111, 0, 92161, 4707, 68206, 10143, 7883, 127081, + 7880, 4522, 8645, 5704, 13010, 69796, 8304, 92982, 0, 119575, 2293, + 70195, 66654, 129077, 92676, 0, 13008, 127121, 4385, 128736, 13011, 0, + 92569, 119161, 13009, 160, 2677, 0, 0, 41793, 65763, 74221, 70790, 41792, + 42770, 94054, 65762, 118829, 43821, 5709, 128296, 71076, 43816, 0, + 983896, 1079, 3867, 5708, 0, 0, 43797, 5706, 64768, 5705, 8791, 4005, 0, + 10237, 10991, 128816, 43459, 9173, 917581, 917580, 13170, 12540, 917577, + 42605, 120765, 126617, 68647, 917572, 10058, 0, 74867, 67730, 127078, + 3339, 11448, 1106, 917591, 917590, 917593, 3340, 74017, 917586, 917589, + 129141, 120541, 10605, 1309, 63966, 120743, 1754, 92226, 13246, 864, 0, + 118926, 8972, 128410, 7849, 120092, 92533, 13240, 195068, 5192, 4338, + 67982, 10948, 66825, 13199, 92575, 1236, 13208, 13261, 13189, 13188, + 93993, 71847, 7440, 0, 120153, 9553, 1590, 63777, 63776, 13178, 63782, + 63781, 63780, 63779, 1583, 119923, 13260, 4550, 120598, 64205, 983245, + 71071, 41522, 41523, 68523, 983772, 118923, 11354, 94071, 0, 42795, 0, + 119195, 11394, 194646, 13236, 13272, 13194, 1334, 69926, 4479, 1178, + 65586, 68311, 66681, 119193, 4601, 0, 0, 983765, 66828, 0, 127839, 0, + 6809, 63786, 6031, 67402, 63791, 63790, 1145, 63788, 7910, 63785, 43153, + 754, 10192, 13105, 8183, 120741, 2037, 0, 64710, 10747, 125, 0, 64890, 0, + 127376, 0, 41719, 63758, 3523, 1074, 13258, 9536, 71056, 0, 4427, 74242, + 63757, 43145, 12217, 63754, 41532, 1349, 63750, 63749, 129025, 0, 0, + 63753, 63802, 41084, 120622, 68133, 41930, 63805, 63804, 11140, 63801, + 41082, 8140, 63798, 6260, 0, 128391, 94074, 63793, 11988, 3898, 92246, + 10201, 12238, 63795, 42194, 10367, 12521, 10431, 42114, 41932, 1068, 0, + 12523, 12945, 983329, 42203, 7950, 3124, 63771, 42787, 4386, 11148, 6973, + 2793, 12475, 129180, 128501, 63769, 9530, 983119, 12232, 13135, 8596, + 5681, 63762, 4595, 63760, 792, 113674, 64803, 0, 8742, 195029, 11053, + 128796, 63744, 128107, 128942, 7588, 63748, 1693, 63746, 43204, 5055, + 68426, 42063, 1090, 120679, 125008, 11665, 74133, 4558, 65685, 9523, + 983451, 0, 71216, 11513, 0, 6157, 63775, 63774, 63773, 13191, 12170, + 3500, 3139, 120538, 3170, 12485, 0, 10872, 78271, 13006, 64433, 120074, + 0, 941, 0, 129079, 917853, 65541, 11063, 0, 8228, 0, 42065, 128368, 0, + 94039, 0, 92455, 7386, 0, 64444, 0, 119863, 43603, 94075, 65397, 288, 0, + 0, 0, 10025, 69915, 2918, 66820, 65300, 119871, 9883, 64726, 2790, 65395, + 3793, 0, 127829, 65393, 120592, 74138, 0, 92751, 77958, 74139, 78777, + 65394, 11548, 5270, 983236, 65396, 0, 65813, 13256, 1282, 120771, 0, 0, + 10888, 127490, 65242, 0, 3330, 0, 0, 68340, 0, 0, 71202, 3304, 42753, + 93046, 0, 74643, 1627, 0, 0, 0, 5371, 13116, 0, 1826, 118794, 0, 43094, + 70023, 43650, 94037, 68317, 9035, 11141, 0, 128005, 0, 92207, 68125, + 128467, 164, 68309, 94067, 94000, 6958, 0, 43116, 67719, 70019, 13245, 0, + 0, 66818, 0, 70031, 11099, 12666, 13175, 13207, 120414, 66014, 120428, + 7447, 5929, 0, 65509, 129192, 7449, 11306, 0, 73920, 3180, 125102, 63808, + 9054, 971, 13062, 71090, 0, 65195, 10164, 92252, 74428, 0, 78146, 92611, + 0, 70204, 0, 10045, 12882, 13275, 2303, 11057, 0, 13276, 125133, 41525, + 78150, 7271, 11444, 126479, 129158, 128112, 12229, 11680, 0, 43411, + 73751, 0, 64813, 0, 0, 10476, 3858, 64175, 3932, 64958, 120432, 0, 73989, + 68192, 0, 69847, 369, 0, 41784, 0, 64163, 77997, 0, 92645, 65474, 4796, + 12292, 126595, 65479, 128631, 41781, 10486, 41480, 43002, 9899, 92608, 0, + 404, 12821, 3741, 0, 5788, 8092, 68212, 41222, 1831, 66020, 3982, 0, + 4388, 0, 746, 118826, 74783, 0, 12018, 65294, 127545, 0, 0, 0, 4422, + 4708, 3799, 74292, 119357, 0, 74430, 0, 11700, 4374, 0, 128179, 1364, 0, + 8038, 0, 917597, 12868, 69814, 70425, 6735, 73979, 13174, 73968, 13225, + 194902, 69808, 65835, 0, 2365, 7841, 0, 42855, 118856, 42866, 0, 0, + 127986, 66438, 41785, 12617, 64172, 13173, 4372, 119354, 0, 983568, 0, + 127821, 67685, 128062, 12965, 384, 64512, 10404, 10340, 119352, 1556, + 5274, 13210, 120125, 10017, 9733, 41787, 983243, 126994, 41373, 68486, + 12303, 128476, 13232, 13233, 349, 4863, 41371, 11656, 0, 120703, 119883, + 12861, 4398, 8543, 65618, 92737, 1096, 43852, 0, 42688, 12441, 12355, + 119348, 119347, 4318, 10452, 92902, 8032, 13243, 13237, 12719, 126646, + 119101, 0, 64884, 119872, 119345, 8597, 71100, 0, 9864, 0, 120785, + 119874, 94107, 13195, 41452, 64961, 7722, 0, 10459, 119878, 124949, + 119879, 66590, 128123, 41533, 66337, 0, 92184, 0, 4965, 43445, 917536, + 67856, 0, 43638, 78536, 128287, 6261, 119342, 43147, 66570, 1957, 10420, + 982, 2756, 13292, 13206, 125064, 0, 2925, 73809, 13056, 92914, 13212, + 43238, 983142, 13190, 13187, 92541, 13198, 118793, 0, 5242, 119179, + 64476, 1694, 8216, 71369, 6770, 43331, 0, 65620, 983728, 43544, 126466, + 0, 41444, 65621, 69955, 9197, 5246, 119106, 13185, 9709, 120323, 120322, + 12314, 65616, 5238, 43825, 71085, 119337, 5236, 40979, 983140, 71874, + 8286, 128537, 3936, 119331, 11699, 41347, 127249, 13235, 8842, 41248, 0, + 4379, 13239, 12692, 7969, 127266, 7219, 71875, 128251, 120509, 92907, + 66224, 734, 2979, 120303, 65619, 9872, 957, 64921, 1846, 66631, 41477, + 119256, 71192, 74511, 41770, 1670, 6442, 120317, 42446, 5379, 120318, + 41163, 74832, 11136, 71876, 11506, 0, 42841, 13267, 0, 0, 41775, 0, 7130, + 41773, 0, 10663, 70130, 0, 983974, 6151, 12110, 42673, 65572, 65293, + 65250, 13265, 13264, 64518, 0, 6100, 127964, 92647, 5808, 65922, 0, + 12967, 66041, 5612, 4583, 70004, 43386, 68097, 64575, 126637, 11965, 0, + 68358, 0, 69789, 42653, 92260, 68102, 9698, 7814, 71045, 119651, 128514, + 0, 41921, 118858, 9756, 6985, 66418, 66621, 74219, 66412, 128822, 118997, + 8012, 5674, 12353, 66421, 12361, 5677, 5588, 125005, 41925, 128124, + 41920, 5673, 120534, 5676, 41923, 12694, 118978, 5672, 1294, 0, 78059, 0, + 42511, 1727, 120725, 42436, 124928, 0, 0, 74222, 8718, 3550, 736, 10268, + 4505, 5873, 74090, 5826, 55232, 5813, 0, 92889, 5841, 5837, 55234, 0, + 3105, 12829, 5838, 5796, 0, 119592, 5793, 0, 5866, 5797, 41011, 5865, + 93009, 7956, 598, 0, 64649, 5806, 42398, 0, 9037, 5671, 120041, 983255, + 0, 0, 128855, 0, 847, 128242, 9529, 128019, 66657, 6980, 78483, 43510, + 78122, 92219, 0, 67411, 78486, 0, 0, 120039, 42683, 71848, 983055, 7114, + 0, 0, 43190, 65463, 1554, 0, 42611, 42563, 0, 5651, 2929, 6792, 43201, 0, + 19963, 5698, 194768, 983941, 92933, 71887, 5644, 10292, 65546, 69727, + 68141, 8372, 0, 65116, 0, 120022, 10175, 10388, 42799, 94100, 41013, + 10568, 0, 983618, 2869, 917843, 41015, 74473, 2785, 4366, 0, 10954, + 41802, 0, 42608, 78469, 9884, 4759, 73768, 120296, 10266, 41359, 1170, + 43365, 69810, 73908, 1609, 902, 92773, 63936, 127239, 11661, 8122, 5818, + 0, 0, 3861, 9540, 11028, 2554, 5158, 5714, 2213, 0, 0, 807, 43079, 0, + 78475, 976, 5511, 64553, 0, 42155, 983317, 41356, 74110, 118801, 71043, + 120080, 8676, 983291, 94002, 5582, 451, 63941, 5798, 9349, 42018, 127858, + 0, 78681, 43609, 5906, 120553, 1440, 0, 128853, 120016, 70342, 11005, + 983697, 66656, 66044, 0, 128592, 128793, 0, 43393, 10094, 70164, 11529, + 10857, 92944, 66436, 6546, 93, 8102, 67323, 68405, 0, 194714, 8171, + 118888, 119097, 127064, 917543, 383, 7154, 41656, 43495, 94040, 67162, + 5187, 71296, 71086, 11286, 68620, 64217, 0, 5232, 0, 41009, 127377, + 41005, 0, 0, 983827, 8292, 125108, 4980, 8860, 71054, 10028, 65291, 7076, + 13182, 194705, 128224, 127974, 10631, 66031, 7972, 0, 78785, 0, 7900, + 128590, 11309, 3806, 4198, 42725, 0, 67656, 9995, 0, 92552, 0, 12931, + 983690, 42684, 74285, 2088, 64213, 64366, 65156, 8814, 42238, 74771, 0, + 917831, 12836, 0, 0, 74342, 8593, 0, 0, 68445, 13255, 0, 0, 7464, 0, + 65865, 0, 194650, 127144, 0, 9342, 120464, 70376, 64516, 0, 78792, 10129, + 41007, 74375, 0, 40995, 12209, 41012, 119136, 0, 0, 69724, 40992, 92264, + 127153, 68653, 43558, 5522, 0, 61, 194780, 74105, 3633, 983900, 65162, + 41234, 12089, 78281, 9771, 983905, 13251, 128701, 0, 6262, 2784, 42743, + 71078, 8126, 66483, 0, 0, 441, 42621, 0, 0, 41002, 40999, 119623, 43266, + 7108, 194779, 10890, 74481, 65834, 8324, 118944, 64417, 74817, 127465, + 64737, 74853, 983659, 8930, 66678, 67216, 1193, 10056, 1800, 13253, + 13252, 7829, 0, 0, 7743, 0, 124996, 77904, 77913, 77905, 9034, 6039, + 129139, 10075, 0, 41018, 65683, 10338, 66469, 0, 0, 0, 42815, 92984, + 41966, 0, 127471, 0, 11792, 43064, 41025, 911, 7539, 0, 40963, 120339, + 65159, 64390, 0, 983160, 5520, 11662, 128468, 65330, 42812, 0, 0, 12326, + 71081, 194638, 42808, 128337, 9348, 64901, 983861, 0, 128328, 66839, 0, + 0, 917584, 43702, 983148, 5857, 65342, 92727, 119120, 120079, 8644, 0, 0, + 11186, 74296, 41909, 0, 66900, 2791, 69663, 1891, 69824, 66397, 41907, + 66647, 118939, 8761, 12942, 5748, 0, 10773, 70868, 983295, 8796, 78149, + 6412, 2061, 8520, 13146, 127185, 63931, 0, 65902, 2882, 0, 0, 12843, + 4520, 120345, 92459, 0, 983660, 0, 73860, 0, 0, 64345, 0, 9201, 128314, + 70871, 0, 0, 43679, 917585, 65117, 92270, 0, 10427, 0, 3844, 6842, 9755, + 1110, 6612, 12222, 93030, 128789, 0, 983096, 783, 194935, 0, 127221, + 92549, 194720, 65056, 3620, 41180, 68378, 4556, 0, 68480, 194933, 74250, + 0, 67657, 10510, 4382, 66482, 0, 0, 127527, 9177, 8902, 93958, 9839, + 120700, 12891, 983755, 983636, 63999, 2016, 41917, 9788, 63928, 67696, + 1862, 65800, 9155, 66623, 9786, 65082, 41919, 8579, 41914, 7981, 0, + 66017, 4508, 64883, 92456, 92522, 127814, 0, 64592, 74276, 67688, 6784, + 78788, 68181, 0, 71218, 113821, 66366, 12147, 9024, 66378, 66472, 983929, + 64289, 65289, 78151, 66658, 71935, 64509, 78152, 113697, 126505, 11051, + 194928, 0, 11355, 65885, 128773, 127941, 41214, 0, 12299, 0, 7500, 4506, + 7773, 0, 0, 9963, 68649, 126609, 4040, 120570, 6167, 74519, 63922, 6594, + 983740, 0, 0, 3624, 43036, 0, 6387, 63990, 19947, 63988, 41955, 126990, + 63993, 10440, 9611, 65605, 6803, 0, 7738, 63986, 11446, 63984, 92641, + 3435, 78164, 43814, 43810, 7029, 64258, 41292, 118898, 12748, 42742, + 9517, 11518, 128168, 78790, 0, 67993, 63956, 42458, 63954, 63953, 63960, + 9591, 4516, 10217, 68370, 11469, 69697, 42306, 2723, 118947, 0, 0, 0, 0, + 0, 11397, 2880, 70806, 0, 2872, 0, 128506, 3498, 4378, 917539, 4270, 0, + 65551, 68205, 6633, 43387, 0, 5230, 194991, 0, 0, 0, 0, 8161, 393, 12013, + 0, 983198, 119103, 415, 63964, 63963, 42345, 92310, 5183, 1877, 42498, 0, + 2927, 71058, 63961, 4472, 0, 0, 78159, 69699, 917936, 42340, 4756, + 128078, 7081, 10730, 7691, 10331, 63830, 119625, 42922, 42103, 8628, + 9813, 0, 42453, 1604, 9565, 10539, 69701, 65764, 41415, 65767, 129196, + 8457, 42301, 11372, 64873, 11992, 0, 0, 63980, 11801, 3622, 983124, + 64336, 12017, 10463, 63981, 4967, 64189, 1966, 43628, 983908, 983292, + 194766, 0, 63971, 4347, 4416, 42098, 11009, 10694, 63973, 402, 92213, + 13147, 128692, 42100, 64646, 13228, 0, 41875, 3515, 74252, 11805, 0, + 11302, 6259, 43395, 0, 0, 194670, 0, 92351, 74813, 74425, 11299, 1561, + 118881, 92318, 64942, 93021, 194733, 70411, 194732, 0, 74301, 127893, + 11280, 128489, 69784, 74060, 0, 0, 119664, 5145, 12486, 65018, 66516, + 5409, 127379, 194669, 7402, 5399, 9685, 74089, 7952, 5401, 0, 66616, + 66832, 92966, 129105, 5405, 127875, 64866, 127864, 119583, 119122, 78784, + 74248, 11330, 194723, 64690, 3254, 0, 0, 128207, 42390, 43678, 194725, + 983909, 65077, 129059, 6388, 3355, 9508, 9867, 5723, 11520, 5611, 0, + 3377, 0, 0, 74354, 0, 78228, 983722, 983762, 42691, 127886, 127198, + 74767, 0, 127075, 1379, 246, 0, 983761, 3788, 983106, 11041, 67202, + 66304, 0, 0, 8917, 42403, 301, 0, 128500, 127046, 0, 0, 113822, 10656, + 125042, 65214, 92987, 42567, 92217, 13163, 983204, 120831, 74597, 3182, + 0, 0, 0, 65034, 65889, 42169, 4755, 74244, 194621, 11443, 983603, 66319, + 6841, 608, 600, 0, 1219, 3934, 64206, 11483, 74510, 119117, 74485, 42442, + 65470, 983907, 64202, 13160, 7759, 42482, 485, 69982, 70505, 9828, 0, + 43505, 42280, 0, 9351, 7778, 64379, 7496, 42431, 6916, 1208, 0, 119631, + 11002, 42470, 0, 68315, 0, 0, 74041, 0, 70045, 43539, 5411, 42196, 0, 0, + 0, 9150, 66831, 42393, 13086, 1310, 66848, 9337, 12052, 10643, 55271, + 128951, 12166, 2546, 194683, 213, 118852, 65611, 0, 194822, 194756, + 74310, 6554, 0, 11914, 5452, 0, 0, 92772, 0, 0, 194681, 92560, 2713, + 129029, 9650, 43330, 0, 128505, 1406, 125007, 42925, 74638, 194593, + 68223, 4143, 128136, 0, 65748, 4141, 9682, 65287, 1508, 127013, 8779, + 10569, 8725, 13299, 66638, 65750, 42263, 4145, 6380, 65751, 66613, 43994, + 65738, 55250, 9185, 9550, 0, 43403, 0, 0, 194783, 65736, 41951, 64816, + 65756, 983205, 12955, 10596, 2888, 194645, 0, 0, 9657, 9019, 125077, 0, + 2878, 5390, 0, 194961, 67325, 68679, 43552, 7501, 6328, 194960, 10429, + 10365, 0, 0, 41946, 7503, 5235, 803, 68381, 0, 0, 8986, 43838, 10632, + 11934, 11452, 1332, 0, 194970, 126647, 0, 118887, 1791, 5191, 9288, + 64822, 2892, 127242, 43394, 555, 0, 0, 66646, 128980, 119002, 13151, + 74512, 7289, 74055, 64161, 8854, 64162, 5858, 41927, 10582, 120457, 1784, + 1361, 195047, 0, 7905, 0, 64868, 128813, 13158, 92166, 7211, 71884, 9371, + 73973, 128441, 6828, 1625, 7664, 0, 1342, 68440, 64171, 92642, 10903, + 983494, 0, 92527, 0, 70438, 4482, 41606, 0, 128569, 983112, 0, 64381, 0, + 194974, 195090, 42245, 126467, 41972, 0, 444, 0, 9127, 66687, 66619, + 126489, 78025, 0, 11349, 40991, 917570, 0, 70177, 120830, 0, 1197, + 128282, 1149, 68316, 0, 0, 40990, 43765, 0, 3492, 917906, 118784, 0, 0, + 0, 12838, 67208, 19948, 41677, 3099, 0, 0, 41087, 0, 0, 0, 119059, 12036, + 41309, 128161, 0, 8152, 0, 41550, 12227, 983613, 0, 12828, 127511, 0, + 983971, 120708, 0, 0, 10386, 119574, 129159, 0, 92680, 983789, 68154, 0, + 1743, 0, 0, 92239, 65186, 917571, 0, 9606, 0, 0, 64439, 0, 0, 92686, + 983875, 0, 43866, 128881, 0, 3395, 9362, 10878, 128376, 0, 78362, 64830, + 0, 125046, 41091, 3426, 1344, 8870, 0, 71344, 4735, 11111, 6119, 12822, + 42699, 0, 983824, 74818, 1423, 128923, 42637, 41080, 0, 12039, 10559, + 128634, 118892, 0, 9472, 67734, 11929, 128905, 7170, 9596, 6130, 128826, + 43629, 11579, 78713, 0, 92501, 125081, 92185, 66699, 64440, 1004, 92584, + 194736, 43234, 66008, 12627, 0, 68414, 74614, 43619, 43303, 11300, 43304, + 9686, 5890, 11776, 7558, 127158, 65627, 0, 10718, 13154, 3461, 9139, 0, + 983094, 0, 0, 65365, 73877, 65628, 78019, 120319, 0, 41708, 12860, 2641, + 12069, 10838, 5403, 10352, 70085, 10061, 43237, 125057, 5140, 209, + 128847, 41704, 41056, 43078, 128125, 118809, 67232, 10899, 65469, 70125, + 0, 0, 2410, 993, 0, 120589, 120689, 78693, 0, 0, 7232, 0, 119253, 124963, + 7110, 74462, 2066, 10489, 42166, 43463, 10659, 3600, 78118, 4224, 1336, + 41518, 983932, 0, 0, 0, 41139, 64820, 92538, 12966, 41134, 0, 0, 119153, + 0, 272, 4263, 8793, 983856, 0, 41502, 128133, 983, 12549, 124940, 0, + 1190, 4109, 1335, 841, 5888, 41358, 64863, 9544, 43481, 0, 194806, 70027, + 2099, 5120, 2409, 7799, 0, 74424, 0, 0, 4731, 92279, 66629, 0, 0, 1255, + 4149, 9247, 0, 9913, 0, 0, 64914, 917787, 65101, 113714, 11694, 92475, + 11690, 5835, 127164, 66625, 10842, 41354, 42123, 43097, 11688, 66634, + 1094, 194, 64692, 0, 8180, 0, 0, 9972, 73865, 4519, 6114, 10898, 43072, + 92465, 0, 93960, 983322, 126581, 10695, 0, 7540, 0, 881, 7857, 6067, + 65164, 0, 0, 129134, 13311, 68403, 41857, 64321, 8359, 983311, 12689, + 983310, 194594, 0, 983312, 71859, 68183, 0, 983314, 1287, 5436, 0, 71097, + 74142, 92328, 74152, 70205, 6051, 10497, 69668, 8985, 12109, 983323, 0, + 93043, 0, 0, 3652, 10537, 120282, 1276, 120440, 6549, 279, 73745, 0, + 128664, 0, 1489, 0, 0, 0, 3899, 1007, 42124, 43828, 42122, 92337, 92367, + 0, 11985, 1345, 78600, 119832, 917601, 8956, 43083, 94057, 42138, 78610, + 129131, 6430, 78608, 78604, 78605, 6285, 78603, 78612, 78613, 65942, 492, + 8685, 128481, 983759, 0, 78622, 43712, 2582, 11470, 64538, 7444, 78615, 78616, 2297, 0, 73837, 119823, 2527, 119824, 197, 2799, 92594, 41944, - 120276, 9933, 0, 66515, 767, 5524, 7028, 0, 0, 119827, 119817, 119828, + 120276, 9933, 74011, 66515, 767, 5524, 7028, 0, 0, 119827, 119817, 92950, 78633, 10896, 0, 1799, 120497, 6971, 74336, 128342, 0, 65340, 118979, - 41551, 2434, 94018, 0, 120579, 0, 4631, 0, 0, 6407, 0, 6338, 43214, 0, - 7570, 0, 3192, 0, 8414, 0, 93983, 0, 0, 0, 9164, 66612, 93959, 3171, - 6623, 4961, 68396, 886, 55216, 8654, 78832, 9993, 74390, 64603, 70066, - 69241, 9599, 78629, 43084, 78627, 78628, 78625, 2399, 69693, 8994, 10944, - 41208, 983713, 41168, 8178, 0, 3367, 92334, 42510, 78641, 78636, 6804, - 78634, 1947, 0, 0, 92681, 42759, 11068, 1705, 9331, 0, 74798, 9181, - 65359, 0, 8017, 119831, 65096, 66720, 0, 43475, 0, 4909, 12126, 128673, - 120696, 4904, 983333, 69650, 1365, 9253, 42757, 43436, 7462, 0, 0, 0, 0, - 119587, 64415, 0, 0, 5398, 0, 127386, 93953, 0, 0, 119015, 0, 0, 9476, 0, - 983777, 12763, 126603, 3629, 0, 13005, 0, 3628, 0, 0, 92502, 3469, 42107, - 42116, 917578, 64809, 2928, 4905, 9853, 851, 9040, 0, 64665, 43086, 9114, - 0, 42583, 9315, 4822, 4906, 3852, 2847, 119821, 3236, 11317, 1251, 7777, - 41852, 11410, 10964, 0, 43222, 12646, 120269, 10259, 9865, 65821, 0, - 6018, 92290, 0, 12276, 0, 68372, 0, 92259, 119244, 0, 983230, 10467, 0, - 2443, 10918, 78217, 119825, 1001, 9241, 1927, 0, 0, 73987, 127885, 0, 0, - 118828, 120271, 65678, 12867, 0, 8260, 77945, 7519, 11505, 12274, 8904, - 518, 65857, 0, 128674, 13204, 4387, 857, 0, 65369, 0, 92336, 43125, - 120592, 0, 0, 0, 0, 5136, 1968, 983041, 126627, 1337, 64967, 1629, 0, - 796, 66506, 0, 74123, 12877, 120649, 42314, 43388, 0, 74403, 6120, 478, - 65151, 68128, 128147, 43082, 6016, 0, 42284, 128507, 4276, 1206, 3619, - 41638, 69691, 3843, 12011, 8853, 3361, 0, 490, 10715, 7578, 68384, 0, - 65350, 10530, 12348, 8653, 74314, 42435, 6154, 9551, 65354, 78522, 784, - 42397, 334, 0, 42416, 65356, 65273, 77987, 69666, 4442, 10364, 0, 778, - 41626, 42455, 7989, 74063, 3227, 69907, 127275, 73983, 2915, 11502, - 41022, 41702, 10309, 127035, 78320, 0, 6975, 0, 5415, 12176, 0, 74193, - 3462, 65215, 42629, 78691, 73784, 0, 0, 9759, 0, 70057, 127254, 8114, - 78698, 78697, 78696, 78695, 8710, 42495, 118956, 0, 4051, 10460, 43364, - 118917, 1356, 12161, 42713, 128857, 127268, 1619, 9703, 43152, 42489, - 42112, 127978, 1875, 10808, 42109, 120284, 41860, 64862, 13305, 64907, - 5289, 13144, 128658, 0, 5575, 9675, 0, 5940, 226, 2649, 6336, 983277, - 119830, 43236, 3382, 42449, 6498, 1658, 11936, 78232, 0, 11269, 10151, - 73759, 43100, 69888, 65508, 0, 0, 0, 8935, 917985, 0, 0, 0, 616, 74753, - 65178, 4684, 78701, 119653, 0, 126551, 0, 6048, 74460, 42110, 73965, - 10870, 8557, 11054, 68664, 119049, 9681, 4475, 0, 41142, 2100, 0, 120731, - 6035, 0, 7651, 10296, 64443, 0, 983295, 917987, 0, 118966, 74144, 40997, - 0, 10392, 10328, 40998, 43462, 74488, 0, 9800, 8979, 0, 13307, 41000, 0, - 119239, 6487, 3386, 0, 10344, 0, 65299, 5394, 43246, 78243, 10220, 66505, - 41200, 128583, 4425, 0, 0, 0, 43074, 73799, 983200, 78147, 0, 12173, - 78545, 0, 127011, 65338, 0, 0, 119582, 4474, 0, 43093, 128644, 1587, 0, - 127372, 64475, 128098, 1369, 983672, 9959, 7927, 0, 4560, 0, 0, 92277, - 983621, 64948, 4430, 74347, 42601, 4514, 66434, 93955, 8194, 65462, - 10626, 10965, 0, 8893, 983301, 12542, 0, 65341, 0, 65829, 7925, 119822, - 10475, 0, 0, 1352, 11069, 7707, 127560, 126486, 65279, 127102, 68207, - 127100, 7099, 6040, 127097, 10071, 0, 9336, 43750, 0, 8899, 7798, 64474, - 64259, 69873, 65188, 7820, 43018, 127082, 0, 7746, 1492, 78551, 10884, - 77982, 0, 5127, 11285, 42501, 5495, 4273, 43095, 41426, 10849, 5730, - 2999, 6342, 68636, 74304, 371, 64373, 6023, 169, 5497, 11708, 0, 0, 6323, - 194684, 8224, 0, 8938, 6043, 12738, 0, 983076, 5321, 0, 194798, 0, 2589, - 74332, 1689, 7802, 4683, 74318, 42704, 120296, 11905, 0, 0, 128516, - 128163, 74513, 6049, 0, 4027, 834, 118962, 1803, 0, 1503, 0, 0, 71312, - 5731, 1381, 2387, 0, 0, 8289, 64525, 65817, 2881, 43142, 0, 9601, 2879, - 9668, 9766, 0, 5729, 917833, 74410, 6036, 64881, 4026, 9361, 127091, - 2887, 0, 3526, 6298, 0, 77897, 120095, 78519, 0, 8572, 6021, 77896, - 128288, 77895, 43155, 0, 119849, 3146, 10959, 9483, 0, 77893, 10981, 166, - 917841, 8635, 983606, 10623, 408, 119058, 127507, 13298, 0, 7426, 41641, - 12717, 0, 7607, 10639, 43396, 0, 0, 41643, 74134, 983054, 8713, 41640, - 10221, 41645, 66712, 6645, 646, 66726, 66711, 42129, 93994, 77901, 3472, - 8697, 0, 0, 983815, 0, 0, 0, 5809, 1950, 119356, 92432, 74572, 0, 42136, - 0, 0, 0, 0, 3247, 119854, 65017, 983953, 68428, 66668, 0, 0, 10983, 0, 0, - 0, 41567, 0, 0, 0, 194624, 119853, 0, 0, 8285, 0, 4509, 0, 66471, 12216, - 0, 40988, 92592, 74809, 41727, 0, 42848, 2396, 917766, 0, 74018, 917538, - 64940, 7027, 3886, 0, 42457, 119008, 0, 996, 68123, 94058, 4249, 0, - 917594, 11707, 8222, 0, 7939, 92454, 92460, 127801, 917592, 128359, 8534, - 127154, 40983, 0, 983240, 0, 7201, 12561, 0, 42371, 12558, 1540, 917549, - 10052, 40982, 0, 0, 1488, 0, 0, 0, 917559, 0, 0, 1563, 128034, 9619, - 983940, 0, 0, 127872, 71363, 5803, 7797, 6070, 10006, 0, 2922, 6082, 0, - 65009, 983942, 12567, 128703, 0, 41412, 0, 0, 3607, 9200, 10046, 9612, - 42153, 8218, 9485, 0, 2032, 78354, 0, 0, 0, 0, 0, 43085, 6057, 508, - 93968, 128015, 67968, 0, 92405, 0, 0, 638, 6083, 119072, 0, 0, 2305, - 78348, 68096, 0, 6056, 6659, 67969, 0, 6085, 0, 0, 3915, 41634, 0, 41639, - 63912, 11941, 0, 4028, 1787, 42180, 43096, 43753, 3249, 1768, 93982, - 12328, 501, 93985, 10601, 0, 583, 0, 41977, 0, 66004, 119350, 6505, - 74010, 0, 13064, 55267, 120810, 6500, 5526, 65049, 0, 73764, 0, 92376, - 12745, 9678, 0, 120587, 9869, 128815, 1771, 0, 8936, 0, 0, 4208, 78341, - 78567, 78342, 0, 983456, 74101, 0, 11762, 0, 92422, 77997, 68010, 66475, - 0, 5027, 78172, 128878, 0, 5069, 73862, 5028, 9897, 0, 73739, 5026, + 41551, 2434, 94018, 126642, 65353, 0, 4631, 118996, 0, 6407, 113737, + 6338, 43214, 0, 7570, 0, 3192, 0, 8414, 983390, 93983, 0, 0, 0, 9164, + 66612, 93959, 3171, 6623, 4961, 68396, 886, 55216, 8654, 78832, 9993, + 74390, 64603, 70066, 69241, 9599, 78629, 43084, 78627, 78628, 78625, + 2399, 69693, 8994, 10944, 41208, 983713, 41168, 8178, 74859, 3367, 92334, + 42510, 78641, 78636, 6804, 70475, 1947, 917579, 0, 92681, 42759, 11068, + 1705, 9331, 0, 74798, 9181, 65359, 125065, 8017, 119831, 65096, 66720, + 71906, 43475, 0, 4909, 12126, 128673, 120696, 4904, 983333, 43503, 1365, + 9253, 42757, 43436, 7462, 127772, 0, 0, 0, 66845, 64415, 120500, 128869, + 5398, 125035, 127386, 93953, 127362, 983782, 119015, 0, 128083, 9476, 0, + 120695, 12763, 126603, 3629, 126626, 13005, 11181, 3628, 0, 0, 92502, + 3469, 42107, 42116, 917578, 64809, 2928, 4905, 9853, 851, 9040, 0, 64665, + 43086, 9114, 43870, 42583, 9315, 4822, 4906, 3852, 2847, 119821, 3236, + 11317, 1251, 7777, 41852, 11410, 10964, 0, 43222, 12646, 120269, 10259, + 9865, 65821, 0, 6018, 68293, 917917, 12276, 119110, 68372, 0, 92259, + 71893, 0, 119828, 10467, 0, 2443, 10918, 78217, 77947, 1001, 9241, 1927, + 0, 124942, 73987, 127885, 71895, 93012, 7992, 77943, 65678, 12867, + 128787, 8260, 77945, 7519, 11505, 12274, 8904, 518, 65857, 128361, + 128674, 13204, 4387, 857, 983866, 65369, 0, 92336, 43125, 11842, 0, + 71072, 0, 0, 5136, 1968, 128906, 126627, 1337, 64967, 1629, 0, 796, + 66506, 0, 74123, 12877, 120649, 42314, 43388, 43826, 74403, 6120, 478, + 65151, 68128, 128147, 43082, 6016, 0, 42284, 71894, 4276, 1206, 3619, + 41638, 69691, 3843, 12011, 8853, 3361, 0, 490, 10715, 7578, 68384, 92754, + 65350, 10530, 12348, 8653, 68245, 42435, 6154, 9551, 65354, 78522, 784, + 42397, 334, 194676, 42416, 65356, 65273, 67243, 69666, 4442, 10364, 0, + 778, 41626, 42455, 7989, 74063, 3227, 69907, 125116, 11102, 2915, 11502, + 41022, 41702, 10309, 127035, 78320, 120273, 6975, 0, 5415, 12176, 0, + 74193, 3462, 65215, 42629, 78691, 71175, 0, 127256, 9759, 127255, 70057, + 127254, 8114, 78698, 78697, 78696, 78695, 8710, 42495, 118956, 70189, + 4051, 10460, 43364, 71206, 1356, 12161, 42713, 128857, 127268, 1619, + 9703, 43152, 42489, 42112, 66896, 1875, 10808, 42109, 120284, 41860, + 64862, 13305, 64907, 5289, 13144, 128658, 983224, 5575, 9675, 195018, + 5940, 226, 2649, 6336, 983277, 92979, 43236, 3382, 42449, 6498, 1658, + 11936, 78232, 113814, 11269, 10151, 73759, 43100, 69888, 65508, 0, 0, 0, + 8935, 78234, 0, 983757, 0, 616, 74753, 65178, 4684, 78701, 119653, 74631, + 126551, 0, 6048, 74460, 42110, 73965, 10870, 8557, 11054, 68664, 119049, + 9681, 4475, 67429, 41142, 2100, 125024, 120731, 6035, 73796, 7651, 6846, + 64443, 983957, 983294, 917987, 0, 118966, 74144, 40997, 68488, 10392, + 10328, 40998, 43462, 74488, 71182, 9800, 8979, 0, 13307, 41000, 0, + 119239, 6487, 3386, 129094, 10344, 0, 65299, 5394, 43246, 78243, 10220, + 66505, 41200, 128582, 4425, 0, 0, 0, 43074, 73799, 129076, 78147, 0, + 12173, 78545, 0, 66824, 65338, 983676, 0, 119582, 4474, 128936, 43093, + 128644, 1587, 0, 127372, 64475, 128098, 1369, 983672, 9959, 7927, 0, + 4560, 0, 0, 92277, 983621, 64948, 4430, 74347, 42601, 4514, 66434, 93955, + 8194, 65462, 10626, 10965, 0, 8893, 983301, 12542, 0, 65341, 67703, + 65829, 7925, 119822, 10475, 113825, 0, 1352, 11069, 7707, 127560, 126486, + 65279, 127102, 68207, 127100, 7099, 6040, 67681, 10071, 78554, 9336, + 43750, 128507, 8899, 7798, 64474, 64259, 69873, 65188, 7820, 43018, + 127082, 128898, 7746, 1492, 78551, 10884, 77982, 66866, 5127, 11285, + 42501, 5495, 4273, 43095, 41426, 10849, 5730, 2999, 6342, 68636, 74304, + 371, 64373, 6023, 169, 5497, 11708, 0, 128603, 6323, 129065, 8224, + 128417, 8938, 6043, 12738, 120671, 983076, 5321, 68645, 194798, 120251, + 2589, 74332, 1689, 7802, 4683, 74318, 42704, 92940, 11905, 0, 0, 128516, + 128163, 74513, 6049, 0, 4027, 834, 118962, 1803, 983822, 1503, 0, 0, + 71312, 5731, 1381, 2387, 126610, 70808, 8289, 64525, 65817, 2881, 43142, + 0, 9601, 2879, 9668, 9766, 0, 5729, 129110, 71230, 6036, 64881, 4026, + 9361, 127091, 2887, 70389, 3526, 6298, 119851, 77897, 120095, 78519, + 118964, 8572, 6021, 77896, 128288, 71174, 43155, 0, 71197, 3146, 10959, + 9483, 0, 77893, 10981, 166, 917841, 8635, 917840, 10623, 408, 119058, + 127507, 13298, 0, 7426, 41641, 12717, 0, 7607, 10639, 43396, 0, 119089, + 41643, 74134, 983054, 8713, 41640, 10221, 41645, 66293, 6645, 646, 66726, + 66711, 42129, 68255, 77901, 3472, 8697, 0, 0, 983815, 0, 194599, 0, 5809, + 1950, 119356, 92432, 68339, 0, 42136, 0, 0, 0, 0, 3247, 92402, 65017, + 128794, 68428, 66668, 0, 0, 10983, 0, 0, 0, 41567, 0, 0, 0, 78446, + 119853, 127922, 0, 8285, 0, 4509, 917802, 66471, 12216, 0, 40988, 92592, + 74809, 41727, 0, 42848, 2396, 129078, 0, 74018, 917538, 64940, 7027, + 3886, 0, 42457, 92888, 119834, 996, 68123, 94058, 4249, 92410, 69650, + 11707, 8222, 73825, 7939, 71213, 92460, 127801, 917592, 128359, 8534, + 69853, 40983, 0, 983240, 0, 7201, 12561, 0, 42371, 12558, 1540, 917549, + 10052, 40982, 0, 0, 1488, 71177, 0, 194831, 917559, 128401, 0, 1563, + 128034, 9619, 983940, 0, 983082, 127872, 71363, 3560, 7797, 6070, 10006, + 128922, 2922, 6082, 70147, 65009, 983942, 12567, 66712, 0, 41412, 0, 0, + 3607, 9200, 10046, 9612, 42153, 8218, 9485, 0, 2032, 78354, 917904, + 119131, 0, 0, 0, 43085, 6057, 508, 93968, 92989, 67968, 0, 92198, 0, 0, + 638, 6083, 119072, 124950, 0, 2305, 78348, 68096, 0, 6056, 6659, 67969, + 983288, 6085, 0, 0, 3915, 41634, 0, 41639, 63912, 11941, 983783, 4028, + 1787, 42180, 43096, 43753, 3249, 1768, 93982, 12328, 501, 93985, 10601, + 0, 583, 0, 41977, 0, 66004, 66416, 6505, 74010, 0, 13064, 55267, 119113, + 6500, 5526, 65049, 0, 12990, 0, 92376, 12745, 9678, 983143, 120587, 9869, + 128815, 1771, 128965, 8936, 92964, 0, 4208, 78341, 78567, 78342, 67742, + 983208, 74101, 128605, 11762, 0, 70096, 6835, 68010, 66475, 120260, 5027, + 78172, 128878, 119830, 5069, 73736, 5028, 9897, 92774, 73739, 5026, 983253, 68639, 6331, 10079, 8931, 0, 1415, 8866, 41901, 74790, 78138, - 119361, 983564, 43106, 5029, 65309, 1580, 3598, 68424, 41070, 77903, 0, - 3440, 78215, 1562, 128656, 127175, 119358, 1716, 983679, 10600, 917867, - 620, 41001, 6028, 0, 42892, 0, 74822, 5024, 120829, 41003, 0, 5025, - 69892, 983209, 0, 118885, 0, 65557, 0, 74541, 983587, 11599, 128209, - 11602, 6243, 11574, 11581, 11597, 11598, 6253, 6105, 11584, 74195, 11569, - 65275, 8906, 127096, 5755, 2636, 983227, 10815, 11619, 2301, 41540, 7815, - 11616, 6979, 12080, 7721, 11604, 7869, 1592, 0, 42152, 78498, 41048, - 917763, 829, 0, 92406, 19950, 0, 126482, 6616, 0, 118875, 10953, 391, 0, - 69785, 482, 42296, 11588, 0, 43606, 0, 68397, 66370, 74506, 42335, - 983188, 0, 0, 7538, 5315, 120644, 42491, 0, 42061, 128088, 4576, 0, - 68417, 43809, 4277, 0, 4039, 64472, 42338, 368, 42058, 3960, 11043, - 11337, 78209, 917820, 63989, 3958, 12132, 1849, 0, 9921, 42451, 4253, - 41147, 42064, 11959, 42404, 41160, 0, 3618, 78338, 0, 43300, 5156, 92629, - 0, 929, 6827, 42035, 42437, 1555, 0, 8691, 66435, 2215, 41662, 94010, 0, - 0, 0, 93952, 4578, 64513, 41664, 983734, 42578, 128794, 41661, 78715, - 43267, 9356, 0, 0, 0, 1286, 10166, 0, 0, 64707, 983127, 42476, 7730, - 983859, 128522, 42483, 0, 0, 42324, 42291, 10020, 43359, 0, 6641, 525, - 41627, 917923, 8763, 128304, 41628, 533, 11931, 65225, 8321, 42504, - 42581, 0, 6915, 42310, 4377, 8559, 0, 74360, 0, 13193, 64350, 11666, - 8679, 41924, 1576, 7735, 92398, 0, 73840, 983092, 11374, 78043, 10889, - 43461, 7757, 42462, 120226, 10029, 66493, 2718, 4168, 73842, 13308, - 120112, 0, 1179, 4440, 0, 77948, 363, 11015, 77947, 77944, 64296, 127090, - 66692, 120826, 0, 66492, 6593, 64625, 41963, 92177, 119329, 0, 10013, - 64434, 92520, 127095, 9492, 11782, 64382, 12833, 77830, 0, 1297, 41630, - 630, 127094, 0, 120774, 92465, 1043, 43652, 66223, 10090, 0, 128664, 313, - 917563, 41881, 0, 42311, 7445, 0, 5750, 10759, 9419, 55222, 9405, 11268, - 42919, 9398, 8526, 9399, 9422, 0, 66495, 0, 0, 127239, 41718, 10707, - 1603, 0, 119003, 0, 631, 77952, 69703, 13161, 65272, 0, 10546, 74210, - 78101, 11600, 77961, 2797, 73821, 42427, 306, 714, 3058, 42381, 77962, - 127080, 12351, 42395, 0, 11607, 0, 42282, 77971, 77967, 9157, 73765, - 66364, 42433, 77964, 7603, 12803, 180, 42141, 0, 120612, 66494, 12674, - 8244, 362, 92439, 0, 8037, 43777, 11535, 0, 74845, 5185, 7165, 5521, - 10334, 2093, 71329, 10302, 128112, 10104, 1027, 5181, 0, 0, 10523, 1446, - 42320, 41646, 991, 5189, 42472, 41647, 120105, 1722, 5581, 42898, 3405, - 0, 194644, 5523, 0, 42620, 92447, 983819, 9549, 0, 10549, 55282, 9661, - 43682, 0, 77910, 120026, 78708, 0, 77911, 0, 41991, 983893, 0, 7630, - 9846, 7684, 10350, 0, 1174, 77981, 42733, 77978, 77980, 66485, 77977, - 42277, 77974, 42456, 65667, 127037, 12330, 128272, 0, 42417, 42383, - 66630, 41344, 6293, 0, 66252, 77984, 74443, 0, 10209, 8313, 4195, 74435, - 1316, 66690, 120032, 6332, 64894, 0, 65871, 78060, 1736, 983684, 3901, - 12228, 120151, 65200, 3383, 10446, 78841, 693, 9130, 314, 64149, 42420, - 11949, 983669, 120152, 11026, 128788, 5332, 6940, 64154, 12635, 127007, - 42706, 1751, 273, 8165, 13166, 120763, 78840, 71368, 12824, 0, 4528, - 5320, 6301, 43662, 6133, 9339, 9463, 42346, 10922, 64560, 3757, 0, 0, 0, - 65869, 73760, 2569, 0, 2326, 65740, 2565, 42459, 7596, 7921, 983868, - 74095, 127981, 41848, 2567, 66006, 0, 4044, 92646, 0, 12233, 983871, - 1023, 474, 0, 119818, 0, 0, 42487, 65556, 0, 127866, 42295, 0, 0, 71322, - 92518, 9835, 66499, 0, 5417, 12275, 10895, 0, 274, 0, 1858, 0, 0, 55251, - 10118, 3133, 128008, 73795, 0, 9610, 8068, 8197, 0, 699, 0, 41665, 5868, - 0, 92695, 42182, 7581, 19940, 43668, 41667, 128057, 0, 1923, 65583, - 65802, 93970, 64597, 43444, 119184, 92197, 0, 6464, 7036, 2996, 1937, - 983751, 0, 41835, 4047, 41842, 0, 64107, 0, 0, 11017, 120601, 0, 293, - 77966, 92169, 64791, 41827, 42466, 43422, 10579, 8560, 71350, 65413, - 77963, 4803, 12964, 1739, 1941, 3900, 0, 1713, 77969, 0, 73957, 11407, - 42441, 41971, 6297, 120098, 64105, 128080, 42481, 11716, 66473, 7179, - 42289, 0, 64103, 969, 0, 9352, 0, 6165, 64100, 0, 6632, 73861, 42402, - 74327, 7806, 0, 8914, 0, 0, 3183, 1435, 64876, 2969, 6046, 64441, 6208, - 67849, 5746, 73749, 0, 64416, 42422, 0, 983046, 7082, 73775, 338, 5059, - 194719, 0, 42328, 10767, 0, 8115, 0, 74758, 0, 8227, 2073, 1218, 917790, - 0, 65848, 0, 0, 69863, 0, 126987, 4486, 0, 0, 0, 10925, 0, 0, 0, 983586, - 42309, 10257, 65191, 10273, 0, 10305, 42461, 0, 42349, 8832, 78051, - 64127, 10644, 42662, 78828, 42278, 74451, 126988, 69874, 7794, 0, 42429, - 6377, 42316, 119026, 3669, 3968, 42468, 71319, 69658, 0, 65402, 119581, - 0, 0, 64933, 0, 41960, 6699, 0, 0, 128354, 6823, 42391, 1588, 65400, - 8409, 78223, 19967, 65398, 787, 71315, 917939, 127744, 6115, 2078, 41654, - 42480, 0, 92650, 41655, 65401, 43975, 0, 0, 0, 644, 65500, 41657, 10778, - 3659, 9533, 184, 1553, 13107, 65484, 69648, 10502, 74457, 0, 0, 41554, 0, - 8220, 917943, 41557, 0, 0, 11070, 119221, 5157, 4020, 73858, 41555, 9514, - 64818, 65103, 64641, 64303, 78131, 7520, 0, 74377, 11029, 66651, 983068, - 0, 118930, 64527, 0, 7877, 73803, 983798, 127348, 120096, 74602, 9955, + 119361, 983564, 43106, 5029, 65309, 1580, 3598, 68424, 41070, 77903, + 7658, 3440, 78215, 1562, 128656, 127175, 119358, 1716, 983679, 10600, + 917867, 620, 41001, 6028, 0, 42892, 0, 74822, 5024, 120829, 41003, 68137, + 5025, 69892, 983209, 0, 118885, 127956, 65557, 0, 74541, 128924, 11599, + 128209, 11602, 6243, 11574, 11581, 11597, 11598, 6253, 6105, 11584, + 74195, 11569, 65275, 8906, 127096, 5755, 2636, 71203, 10815, 11619, 2301, + 41540, 7815, 11616, 6979, 12080, 7721, 11604, 7869, 1592, 0, 42152, + 78498, 41048, 917763, 829, 0, 92406, 19950, 66886, 126482, 6616, 0, + 118875, 10953, 391, 0, 69785, 482, 42296, 11588, 0, 43606, 71185, 68397, + 66370, 74282, 42335, 983188, 72421, 983799, 7538, 5315, 120644, 42491, + 92901, 42061, 128002, 4576, 0, 68417, 43809, 4277, 0, 3563, 64472, 42338, + 368, 42058, 3960, 11043, 11337, 78209, 917820, 63989, 3958, 12132, 1849, + 0, 9921, 42451, 4253, 41147, 42064, 11959, 42404, 41160, 0, 3618, 78338, + 194924, 43300, 5156, 92629, 70350, 929, 6827, 42035, 42437, 1555, 0, + 8691, 66435, 2215, 41662, 94010, 0, 0, 128824, 93952, 4578, 64513, 41664, + 983734, 42578, 71049, 41661, 78351, 43267, 9356, 0, 0, 0, 1286, 10166, + 983117, 0, 64707, 128925, 42476, 7730, 11156, 128522, 42483, 0, 128404, + 42324, 42291, 10020, 43359, 0, 6641, 525, 41627, 917923, 8763, 128304, + 41628, 533, 11931, 65225, 8321, 42504, 42581, 0, 6915, 42310, 4377, 8559, + 128321, 74360, 125100, 13193, 64350, 11666, 8679, 41924, 1576, 7735, + 92398, 0, 73840, 983092, 11374, 78043, 10889, 43461, 7757, 42462, 120226, + 10029, 66493, 2718, 4168, 73842, 13308, 120112, 0, 1179, 4440, 0, 77948, + 363, 11015, 66817, 77944, 43857, 127090, 66692, 120826, 0, 66492, 6593, + 64625, 41963, 92177, 119329, 0, 10013, 64434, 92520, 127095, 9492, 11782, + 64382, 12833, 77830, 0, 1297, 41630, 630, 127094, 0, 120774, 70165, 1043, + 43652, 66223, 10090, 0, 124945, 313, 129033, 41881, 0, 42311, 7445, + 119244, 5750, 10759, 9419, 55222, 9405, 11268, 42919, 9398, 8526, 9399, + 9422, 0, 66495, 69990, 0, 92990, 41718, 10707, 1603, 983703, 119003, 0, + 631, 77952, 69703, 13161, 65272, 71067, 10546, 74210, 78101, 11600, + 77961, 2797, 73821, 42427, 306, 714, 3058, 42381, 77962, 127080, 12351, + 42395, 0, 11607, 127528, 11198, 66821, 77967, 9157, 73765, 66364, 42433, + 77964, 7603, 12803, 180, 42141, 0, 120612, 66494, 12674, 8244, 362, + 92439, 125096, 8037, 43777, 11535, 0, 74845, 5185, 7165, 5521, 10334, + 2093, 71329, 10302, 125131, 10104, 1027, 5181, 983146, 0, 10523, 1446, + 42320, 6845, 991, 5189, 42472, 41647, 120105, 1722, 5581, 42898, 3405, 0, + 194644, 5523, 0, 42620, 92447, 124988, 9549, 0, 10549, 55282, 9661, + 43682, 0, 77910, 78068, 68247, 0, 71184, 983070, 41991, 983893, 0, 7630, + 9846, 7684, 10350, 128453, 1174, 77981, 42733, 77978, 77980, 66485, + 77977, 42277, 77974, 42456, 65667, 74438, 12330, 128272, 0, 42417, 42383, + 66630, 41344, 6293, 0, 66252, 77984, 74443, 127894, 10209, 8313, 4195, + 74435, 1316, 66690, 120032, 6332, 64894, 983156, 65871, 78060, 1736, + 983684, 3901, 12228, 120151, 65200, 3383, 10446, 78241, 693, 9130, 314, + 64149, 42420, 11949, 983669, 120152, 11026, 120516, 5332, 6940, 64154, + 12635, 124980, 42706, 1751, 273, 8165, 13166, 120763, 78840, 71368, + 12824, 0, 4528, 5320, 6301, 43662, 6133, 9339, 9463, 42346, 10922, 64560, + 3757, 0, 0, 74302, 65869, 73760, 2569, 0, 2326, 65740, 2565, 42459, 7596, + 7921, 983868, 73862, 127981, 41848, 2567, 66006, 92622, 4044, 92646, 0, + 12233, 983871, 1023, 474, 0, 119818, 0, 0, 42487, 65556, 0, 127866, + 42295, 0, 125114, 71322, 92518, 2222, 66499, 0, 5417, 12275, 10895, 0, + 274, 0, 1858, 0, 0, 55251, 10118, 3133, 128008, 71857, 0, 9610, 8068, + 8197, 0, 699, 0, 41665, 5868, 128710, 92695, 42182, 7581, 19940, 43668, + 41667, 128057, 0, 1923, 65583, 65802, 93970, 64597, 43444, 119184, 71855, + 0, 6464, 7036, 2996, 1937, 983751, 68481, 41835, 4047, 41842, 0, 64107, + 77965, 983746, 11017, 120601, 0, 293, 77966, 92169, 64791, 41827, 42466, + 43422, 10579, 8560, 71350, 65413, 77963, 4803, 12964, 1739, 1941, 3900, + 128967, 1713, 77969, 0, 73957, 11407, 42441, 41971, 6297, 120098, 64105, + 128080, 42481, 11716, 66473, 7179, 42289, 125095, 64103, 969, 0, 9352, + 983149, 6165, 64100, 0, 6632, 73861, 42402, 74327, 7806, 0, 8914, 66908, + 124954, 3183, 1435, 64876, 2969, 6046, 64441, 6208, 67849, 5746, 66408, + 0, 64416, 42422, 0, 983046, 7082, 73775, 338, 5059, 194719, 129145, + 42328, 10767, 0, 8115, 0, 74758, 0, 8227, 2073, 1218, 917790, 983230, + 65848, 92884, 0, 69863, 0, 126987, 4486, 128082, 0, 0, 10925, 0, 119868, + 0, 124952, 42309, 10257, 65191, 10273, 7668, 10305, 42461, 0, 42349, + 8832, 78051, 64127, 10644, 42662, 78828, 42278, 74451, 126988, 69874, + 7794, 119867, 42429, 6377, 42316, 119026, 3669, 3968, 42468, 71319, + 69658, 0, 65402, 119581, 0, 128747, 64933, 194815, 41960, 6699, 42903, + 128755, 125013, 6823, 42391, 1588, 43502, 8409, 78223, 19967, 65398, 787, + 71315, 917939, 127744, 6115, 2078, 41654, 42480, 0, 92650, 41655, 65401, + 43975, 72427, 0, 113816, 644, 65500, 41657, 10778, 3659, 9533, 184, 1553, + 13107, 65484, 69648, 10502, 66296, 0, 0, 41554, 0, 8220, 129031, 41557, + 0, 128938, 11070, 119221, 5157, 4020, 73858, 41555, 9514, 64818, 65103, + 64641, 64303, 78131, 7520, 73888, 74377, 11029, 66651, 983068, 128492, + 118930, 64527, 0, 7877, 12723, 983798, 127348, 120096, 74602, 9955, 119557, 4055, 42817, 0, 65212, 11715, 12190, 12319, 78630, 0, 78631, - 9502, 65427, 0, 65424, 12607, 0, 9734, 65425, 0, 0, 127357, 78835, 92410, - 10112, 10827, 0, 9866, 74527, 66675, 0, 8625, 64346, 11290, 10477, 0, - 8636, 983927, 8315, 65444, 983793, 0, 74595, 6152, 0, 0, 6629, 127108, - 120171, 0, 74589, 43993, 0, 69790, 64435, 0, 43690, 11046, 11490, 42730, - 4485, 127107, 0, 64926, 0, 0, 0, 5869, 12437, 42728, 0, 7040, 3588, 0, - 12825, 0, 0, 12725, 0, 127106, 78642, 223, 0, 69675, 120166, 42444, 0, - 64499, 65245, 0, 1171, 0, 69717, 0, 1805, 8772, 43820, 0, 9930, 65247, - 78619, 120111, 2338, 0, 118853, 0, 42676, 0, 64800, 65236, 67644, 68126, - 1213, 0, 64075, 797, 64074, 8734, 4212, 127369, 64387, 4115, 0, 5005, - 64070, 64073, 10679, 0, 77954, 9402, 64276, 426, 0, 0, 8251, 10136, - 65436, 0, 2120, 43302, 1224, 0, 65576, 74192, 10701, 1764, 3101, 127815, - 12858, 120159, 0, 11373, 6378, 127859, 120103, 8663, 9312, 41644, 4539, - 2129, 0, 9222, 983738, 0, 4259, 9092, 74567, 41961, 0, 12724, 66357, - 42331, 64935, 0, 0, 1293, 7947, 2132, 983767, 74593, 120308, 2454, 42717, - 3613, 128837, 0, 0, 65888, 8816, 10978, 10840, 0, 10668, 0, 43087, 12595, - 120304, 983114, 8822, 0, 1157, 64903, 8638, 0, 0, 0, 0, 69848, 8235, - 120316, 4405, 10086, 120247, 0, 69216, 0, 65430, 71321, 6079, 6817, - 10764, 127910, 64291, 128051, 998, 120312, 11062, 1317, 64327, 1558, 0, - 1991, 7882, 42254, 0, 41700, 530, 0, 10428, 119335, 12002, 119336, 5742, - 43076, 4692, 64630, 41823, 4007, 5004, 119334, 7896, 751, 6595, 6596, - 120325, 66373, 0, 0, 64908, 92691, 6311, 0, 12004, 119192, 12049, 43108, - 120326, 0, 41705, 92188, 6598, 0, 6599, 120334, 0, 42148, 118825, 66027, - 0, 6597, 9412, 8340, 11824, 64745, 2281, 69904, 0, 1988, 5407, 67865, - 2430, 41678, 0, 120243, 2336, 983903, 0, 78871, 120442, 983769, 1921, - 10947, 19927, 0, 65406, 0, 19913, 4284, 13217, 0, 43789, 12841, 9229, - 10956, 42285, 41674, 19964, 41679, 65084, 3521, 0, 5774, 8325, 0, 65403, - 983089, 1854, 10794, 0, 67660, 69846, 0, 78359, 5280, 0, 4344, 12905, - 65433, 6076, 64793, 41610, 768, 12074, 442, 0, 68162, 64081, 12934, - 41682, 65432, 41693, 0, 6071, 65434, 127467, 4804, 4053, 0, 127469, - 194653, 41696, 467, 69823, 127463, 69797, 194652, 127473, 8421, 127472, - 69682, 43705, 502, 0, 65431, 119056, 69954, 12043, 1303, 316, 7364, 2029, - 2136, 119246, 11533, 64365, 43480, 92639, 4860, 126648, 127877, 42488, 0, - 9583, 128849, 5546, 8019, 73856, 0, 0, 0, 5544, 2355, 12150, 65725, 5543, - 77989, 63751, 12137, 5548, 77985, 0, 65727, 68388, 65726, 6077, 128352, - 65452, 0, 11301, 78013, 78008, 78010, 9874, 78007, 0, 1319, 3050, 65410, - 0, 0, 78016, 78017, 42830, 43996, 66716, 128137, 4691, 92242, 9345, 621, - 92709, 128222, 0, 65411, 0, 41182, 73881, 65408, 73899, 78024, 9474, - 10545, 119118, 10887, 3786, 65409, 8894, 43179, 119611, 7923, 3716, - 92363, 9996, 8508, 0, 7012, 8195, 127834, 9566, 0, 3722, 0, 41707, 8493, - 545, 9575, 41379, 10050, 12718, 69854, 8859, 6820, 74345, 65110, 120740, - 0, 0, 9119, 2787, 7920, 118823, 4021, 2012, 7985, 0, 119663, 0, 0, 78021, - 78022, 410, 78020, 1802, 78018, 74107, 0, 41659, 41671, 1827, 0, 64396, - 10126, 12116, 41673, 120370, 11422, 78141, 120373, 3860, 120367, 68412, - 41345, 120362, 120363, 11748, 42158, 7941, 11076, 8749, 120361, 2104, - 64858, 361, 120357, 845, 0, 41560, 11970, 4562, 917920, 2926, 917919, - 4569, 74130, 0, 43487, 194630, 611, 74129, 64871, 118891, 65629, 0, - 194858, 0, 0, 127545, 120543, 0, 0, 6291, 0, 78639, 41669, 7094, 917921, - 0, 983581, 74054, 127754, 195029, 0, 839, 983319, 7695, 8769, 65246, - 4829, 194663, 4859, 64467, 0, 983963, 118998, 7206, 0, 6647, 43986, 0, - 69766, 0, 64764, 4210, 983863, 127936, 804, 0, 0, 12298, 0, 66653, 0, - 64924, 10091, 73931, 9468, 74245, 0, 0, 74246, 92503, 12839, 64669, - 92202, 0, 1279, 1425, 6224, 119229, 11049, 0, 92697, 43239, 8482, 92440, - 0, 5032, 69677, 11940, 67888, 664, 120437, 5034, 0, 0, 127525, 42702, - 73888, 983149, 13294, 67873, 64869, 6032, 0, 9115, 7430, 120377, 0, - 120819, 68387, 120168, 73913, 120170, 41161, 5518, 4174, 10993, 41162, - 120160, 64528, 1169, 434, 41437, 1905, 6034, 41164, 64744, 9528, 118867, - 128800, 524, 0, 74029, 788, 74027, 0, 194638, 0, 1663, 10419, 74025, - 42636, 0, 69725, 0, 120656, 0, 67876, 0, 0, 0, 67897, 74039, 0, 0, 11395, - 0, 119107, 43612, 64344, 0, 0, 10855, 5445, 9355, 0, 65198, 7391, 8989, - 221, 65686, 0, 0, 8010, 7191, 4962, 69772, 8855, 0, 0, 64469, 120426, - 10555, 0, 43333, 92299, 0, 120427, 10451, 0, 67653, 7245, 12443, 74405, - 9947, 120149, 78317, 3873, 8367, 0, 120146, 43433, 43649, 11987, 0, 0, - 11010, 12723, 74059, 74062, 6217, 5896, 0, 7682, 74049, 1462, 10235, 0, - 0, 0, 0, 0, 0, 42595, 0, 74402, 118860, 0, 120419, 92497, 74052, 0, - 92378, 120549, 119082, 64295, 120418, 0, 64765, 73923, 120417, 120662, - 69920, 194702, 6216, 0, 10755, 9455, 0, 8124, 127042, 9470, 6944, 127540, - 0, 69680, 2828, 0, 531, 42638, 0, 0, 0, 43428, 8204, 3614, 2827, 9696, 0, - 0, 8728, 4354, 10904, 78562, 19936, 7833, 120691, 0, 42599, 42597, 42709, - 120409, 127044, 0, 8537, 0, 0, 9354, 983164, 128833, 41199, 10121, 2028, - 0, 983194, 69715, 0, 3062, 0, 74447, 12608, 0, 66440, 7545, 9700, 12580, - 92205, 120777, 120502, 41155, 0, 74071, 0, 983457, 12713, 0, 0, 0, 78772, - 0, 1734, 0, 0, 127040, 64594, 2456, 231, 0, 74167, 542, 0, 118786, 0, - 983979, 1230, 0, 0, 3597, 4446, 10584, 74235, 92215, 4037, 127938, 8352, - 0, 5687, 0, 64515, 0, 194801, 55265, 67846, 78434, 9704, 0, 0, 70080, - 71338, 0, 8660, 126495, 0, 0, 78773, 74482, 4483, 1709, 69721, 9909, - 6080, 0, 120358, 1746, 1315, 8667, 0, 0, 13140, 65899, 10604, 0, 4480, - 11266, 128152, 1226, 6930, 67979, 983690, 6360, 10897, 41230, 605, 0, - 74785, 69875, 0, 0, 41500, 0, 311, 11453, 6221, 10608, 64943, 74280, - 10877, 118868, 64885, 74272, 0, 0, 128559, 120736, 74312, 345, 0, 74456, - 64606, 9917, 0, 92231, 5037, 0, 1776, 8422, 0, 118814, 41508, 41201, 323, - 43328, 0, 42698, 1295, 194853, 4625, 0, 4630, 13117, 0, 128772, 65123, + 9502, 65427, 125048, 65424, 12607, 0, 9734, 65425, 0, 983808, 127357, + 78835, 78836, 10112, 10827, 0, 9866, 74527, 66675, 118867, 8625, 64346, + 11290, 10477, 67738, 8636, 983927, 8315, 65444, 983793, 195011, 74595, + 6152, 0, 73947, 6629, 125056, 120171, 0, 74589, 43993, 128346, 69790, + 64435, 64955, 43690, 11046, 11490, 42730, 4485, 127107, 0, 64926, 0, 0, + 43830, 5869, 12437, 42728, 0, 7040, 3588, 0, 12825, 0, 0, 12725, 74092, + 127106, 78634, 223, 78635, 69675, 120166, 42444, 128449, 64499, 65245, + 129104, 1171, 128802, 69717, 120113, 1805, 8772, 43820, 0, 9930, 65247, + 78619, 120111, 2338, 0, 118853, 0, 42676, 0, 64800, 13092, 11185, 68126, + 1213, 128419, 64075, 797, 64074, 8734, 4212, 127369, 64387, 4115, 0, + 5005, 64070, 64073, 10679, 0, 77954, 9402, 64276, 426, 0, 0, 8251, 10136, + 65436, 0, 2120, 43302, 1224, 0, 65576, 70795, 10701, 1764, 3101, 127815, + 12858, 120159, 0, 11373, 6378, 71093, 120103, 8663, 9312, 41644, 4539, + 2129, 70785, 9222, 983738, 118907, 4259, 9092, 74567, 41961, 0, 12724, + 66357, 42331, 64935, 0, 0, 1293, 7947, 2132, 983767, 71858, 72440, 2454, + 42717, 3613, 128837, 0, 0, 65888, 8816, 10978, 10840, 0, 10668, 113723, + 43087, 12595, 120304, 983114, 8822, 0, 1157, 64903, 8638, 127265, 917886, + 0, 0, 69848, 8235, 120316, 4405, 10086, 120247, 11128, 69216, 0, 65430, + 71321, 6079, 6817, 10764, 120314, 64291, 120315, 998, 120312, 11062, + 1317, 64327, 1558, 983934, 1991, 7882, 42254, 128954, 41700, 530, 0, + 10428, 119335, 12002, 119336, 5742, 43076, 4692, 64630, 41823, 4007, + 5004, 74033, 7896, 751, 6595, 6596, 120325, 66373, 983247, 0, 64908, + 92691, 6311, 93019, 12004, 119192, 12049, 43108, 120326, 71083, 41705, + 92188, 6598, 0, 6599, 66822, 93031, 42148, 118825, 66027, 0, 6597, 9412, + 8340, 11824, 64745, 2281, 69904, 128495, 1988, 5407, 67865, 2430, 41678, + 93059, 120243, 2336, 983903, 0, 67169, 120442, 127092, 1921, 10947, + 19927, 70390, 65406, 0, 19913, 4284, 13217, 0, 43789, 12841, 9229, 10956, + 42285, 41674, 19964, 41679, 65084, 3521, 124957, 5774, 8325, 69864, + 65403, 983089, 1854, 10794, 93054, 67660, 69846, 0, 78359, 5280, 0, 4344, + 12905, 65433, 6076, 64793, 41610, 768, 12074, 442, 0, 68162, 64081, + 12934, 41682, 65432, 41693, 0, 6071, 65434, 127467, 4804, 4053, 0, + 127469, 194653, 41696, 467, 69823, 127463, 69797, 194652, 127473, 8421, + 127472, 69682, 43705, 502, 0, 65431, 119056, 69954, 12043, 1303, 316, + 7364, 2029, 2136, 119246, 11533, 64365, 43480, 92639, 4860, 126648, + 127877, 42488, 70339, 9583, 128849, 5546, 8019, 73856, 0, 0, 0, 5544, + 2355, 12150, 65725, 5543, 77989, 63751, 12137, 5548, 77985, 0, 65727, + 68388, 65726, 6077, 128352, 65452, 0, 11301, 11214, 65952, 78010, 9874, + 78007, 983115, 1319, 3050, 65410, 67399, 0, 78016, 78017, 42830, 43996, + 66716, 128137, 4691, 92242, 9345, 621, 92709, 128222, 0, 65411, 0, 41182, + 73881, 65408, 73899, 78024, 9474, 10545, 119118, 10887, 3786, 65409, + 8894, 43179, 71042, 7923, 3716, 92363, 9996, 8508, 127794, 7012, 8195, + 127834, 9566, 0, 3722, 0, 41707, 8493, 545, 9575, 41379, 10050, 12718, + 69854, 8859, 6820, 74345, 65110, 120740, 128978, 0, 9119, 2787, 7920, + 118823, 4021, 2012, 7985, 0, 119663, 917792, 0, 78021, 78022, 410, 78020, + 1802, 78018, 74107, 0, 41659, 41671, 1827, 0, 64396, 10126, 12116, 41673, + 120370, 11422, 71846, 120373, 3860, 120367, 68412, 41345, 120362, 120363, + 11748, 42158, 7941, 11076, 8749, 120361, 2104, 64858, 361, 120357, 845, + 0, 41560, 11970, 4562, 917920, 2926, 68495, 4569, 74130, 128659, 43487, + 194630, 611, 74129, 64871, 118891, 65629, 0, 194858, 74854, 0, 70466, + 67392, 66385, 0, 6291, 0, 68487, 41669, 7094, 917921, 0, 983581, 74054, + 127754, 128917, 0, 839, 983319, 7695, 8769, 65246, 4829, 67756, 4859, + 64467, 0, 983963, 118998, 7206, 119636, 6647, 43986, 983796, 69766, + 194664, 64764, 4210, 983254, 127936, 804, 194651, 0, 12298, 70344, 66653, + 0, 64924, 10091, 67200, 9468, 67206, 67205, 67204, 67203, 92503, 12839, + 64669, 92202, 71851, 1279, 1425, 6224, 119229, 11049, 127123, 92697, + 42649, 8482, 92440, 0, 5032, 67209, 11940, 67207, 664, 120437, 5034, 0, + 70200, 127525, 42702, 70194, 93061, 13294, 67873, 64869, 6032, 67218, + 9115, 7430, 120377, 70191, 120819, 68387, 120168, 73913, 120170, 41161, + 5518, 4174, 10993, 41162, 120160, 64528, 1169, 434, 41437, 1905, 6034, + 41164, 64744, 9528, 67741, 128800, 524, 0, 74029, 788, 74027, 0, 71881, + 0, 1663, 10419, 42901, 42636, 67211, 67210, 0, 120656, 67215, 67214, + 67213, 67212, 0, 67897, 74039, 0, 0, 11395, 0, 119107, 43612, 64344, 0, + 0, 10855, 5445, 9355, 67221, 65198, 7391, 8989, 221, 65686, 0, 0, 8010, + 7191, 4962, 69772, 8855, 74612, 70820, 64469, 120426, 10555, 67227, + 43333, 67225, 128483, 120427, 10451, 67229, 67653, 7245, 12443, 74405, + 9947, 120149, 78317, 3873, 8367, 77842, 120146, 43433, 43649, 11987, 0, + 0, 11010, 11164, 74059, 74062, 6217, 5896, 43846, 7682, 74049, 1462, + 10235, 0, 0, 0, 43441, 127924, 127777, 42595, 0, 74402, 118860, 78661, + 120419, 92497, 66287, 120420, 92378, 120549, 119082, 64295, 120418, 0, + 64765, 73923, 120417, 120662, 69920, 194702, 6216, 67230, 10755, 9455, + 11155, 8124, 127042, 9470, 6944, 127540, 0, 69680, 2828, 0, 531, 42638, + 0, 0, 0, 43428, 8204, 3614, 2827, 9696, 120365, 0, 8728, 4354, 10904, + 78562, 19936, 7833, 120691, 0, 42599, 42597, 42709, 120409, 125012, 0, + 8537, 127306, 0, 9354, 983164, 127959, 41199, 10121, 2028, 0, 120253, + 69715, 0, 3062, 0, 74447, 12608, 0, 66440, 7545, 9700, 11948, 92205, + 120777, 120502, 41155, 68306, 74071, 0, 983457, 12713, 127519, 70402, 0, + 78772, 113770, 1734, 0, 78141, 127040, 64594, 2456, 231, 68227, 74167, + 542, 0, 118786, 983859, 194797, 1230, 983953, 126555, 3597, 4446, 10584, + 74235, 92215, 4037, 67737, 8352, 0, 5687, 0, 64515, 0, 194801, 55265, + 67846, 78434, 9704, 0, 0, 70080, 71338, 0, 8660, 126478, 0, 0, 78773, + 74482, 4483, 1709, 69721, 9909, 6080, 194851, 120358, 1746, 1315, 8667, + 983101, 0, 13140, 65899, 10604, 0, 4480, 11266, 128152, 1226, 6930, + 67979, 195019, 6360, 10897, 41230, 605, 68302, 74785, 69875, 0, 917986, + 41500, 0, 311, 11453, 6221, 10608, 64943, 67682, 10877, 118868, 64885, + 74272, 0, 194672, 128559, 120736, 74312, 345, 124933, 74456, 64606, 9917, + 0, 74855, 5037, 0, 1776, 8422, 128935, 118814, 41508, 41201, 323, 43328, + 0, 42698, 1295, 194853, 4625, 77855, 4630, 13117, 0, 128772, 65123, 11293, 2668, 11288, 0, 42640, 65666, 2519, 92369, 65420, 92479, 0, 4252, - 5049, 42659, 119011, 706, 7754, 10854, 8738, 0, 65419, 0, 0, 649, 65421, - 0, 66702, 0, 12670, 1013, 0, 64919, 705, 0, 65422, 127803, 1183, 126519, - 7017, 42852, 0, 8157, 9736, 64503, 65418, 0, 983878, 74035, 0, 11913, - 73874, 6696, 0, 8920, 119298, 0, 7962, 12211, 9837, 2051, 66227, 0, 4184, - 0, 0, 10177, 73777, 1857, 194657, 4626, 8464, 8472, 0, 4629, 8499, 78321, - 78322, 4624, 7818, 119173, 0, 0, 7805, 0, 94007, 6935, 92292, 78325, - 78326, 78323, 43327, 43989, 119046, 8492, 8250, 8459, 0, 8497, 8496, 0, - 0, 78336, 78339, 9543, 78335, 78332, 77832, 65849, 77831, 983961, 0, - 12451, 0, 8684, 0, 6102, 0, 5298, 0, 5294, 0, 0, 983459, 195062, 9949, - 119826, 43617, 119215, 0, 12073, 0, 0, 77863, 13108, 120617, 11439, - 41468, 983757, 0, 5292, 55272, 983883, 1939, 5302, 3970, 917879, 12455, - 1793, 0, 0, 0, 6643, 92477, 65263, 0, 78330, 41293, 78328, 65923, 0, - 13219, 9569, 0, 74383, 0, 74197, 0, 5500, 8813, 0, 0, 74566, 5322, 0, - 78340, 43631, 5324, 66443, 3784, 41614, 65269, 6230, 78349, 78345, 43324, - 3360, 78344, 11523, 0, 92488, 9926, 7197, 0, 68429, 42894, 41821, 1249, + 5049, 42659, 119011, 706, 7754, 10854, 8738, 0, 65419, 0, 128496, 649, + 65421, 0, 66702, 0, 12670, 1013, 0, 64919, 705, 0, 65422, 127803, 1183, + 126519, 7017, 42852, 0, 8157, 9736, 64503, 65418, 0, 983878, 74035, 0, + 11913, 73874, 6696, 128775, 8920, 119298, 128426, 7962, 12211, 9837, + 2051, 66227, 0, 4184, 119825, 128598, 10177, 73777, 1857, 194657, 4626, + 8464, 8472, 0, 4629, 8499, 74627, 78322, 4624, 7818, 119173, 128108, 0, + 7805, 128754, 94007, 6935, 92292, 78325, 78326, 78323, 43327, 43989, + 119046, 8492, 8250, 8459, 0, 8497, 8496, 0, 74582, 78336, 78339, 9543, + 67860, 78332, 77832, 65849, 77831, 983961, 0, 12451, 0, 8684, 128301, + 6102, 0, 5298, 0, 5294, 0, 0, 128746, 195062, 9949, 119826, 43617, + 119215, 0, 12073, 0, 0, 77863, 13108, 120617, 11439, 41468, 119076, 0, + 5292, 55272, 983883, 1939, 5302, 3970, 917879, 12455, 1793, 124982, 0, 0, + 6643, 92477, 65263, 0, 78330, 41293, 78328, 65923, 0, 13219, 9569, 0, + 74383, 0, 74197, 129089, 5500, 8813, 0, 128612, 74566, 5322, 0, 78340, + 43631, 5324, 66443, 3784, 41614, 65269, 6230, 78349, 78345, 13282, 3360, + 78344, 11523, 0, 92488, 9926, 7197, 128248, 68429, 42894, 41821, 1249, 78360, 78361, 78356, 78358, 78353, 64899, 64763, 41149, 41807, 43162, - 41815, 41150, 0, 10571, 10096, 0, 0, 78074, 6947, 41152, 887, 9249, 6565, - 78510, 41990, 78509, 41811, 74466, 93966, 6670, 77882, 0, 0, 43092, - 43325, 0, 10168, 0, 9781, 128655, 9190, 0, 9666, 8269, 65944, 74005, - 13019, 11670, 69860, 315, 12813, 983458, 78432, 78256, 78351, 78352, 0, - 983657, 0, 0, 1378, 9509, 0, 0, 74475, 3066, 92220, 67847, 0, 92355, 0, - 78365, 8787, 120379, 194616, 41618, 194615, 78261, 194614, 0, 64652, 0, - 194612, 0, 78366, 42088, 0, 195061, 7176, 43756, 10137, 6121, 10995, - 78259, 74534, 8119, 64874, 917816, 127199, 194939, 0, 74525, 0, 0, 12930, - 1394, 74514, 0, 74515, 0, 118804, 2998, 9527, 120659, 65190, 12977, - 42090, 119165, 0, 119100, 41236, 92235, 42005, 42003, 41237, 5848, 0, 0, - 3670, 128657, 194600, 0, 0, 7890, 0, 11298, 43315, 0, 6229, 1593, 0, 0, - 619, 4635, 65080, 0, 128002, 4120, 65337, 65336, 0, 11808, 119214, 74115, + 41815, 41150, 128911, 10571, 10096, 67161, 67160, 67159, 6947, 41152, + 887, 9249, 6565, 78510, 41990, 78509, 41811, 67157, 93966, 6670, 67175, + 67174, 0, 43092, 43325, 67178, 10168, 67176, 9781, 68248, 9190, 128497, + 9666, 8269, 65944, 74005, 13019, 11670, 69860, 315, 12813, 983458, 72409, + 78256, 72408, 78352, 0, 983657, 0, 0, 1378, 9509, 0, 92996, 72407, 3066, + 92220, 67847, 72406, 92355, 0, 78365, 8787, 67189, 194616, 41618, 194615, + 78261, 127384, 0, 64652, 0, 194612, 0, 78366, 42088, 71040, 195061, 7176, + 43756, 10137, 6121, 10995, 78259, 71050, 8119, 64874, 71052, 78174, + 194939, 128630, 74525, 0, 0, 12930, 1394, 74514, 128413, 74515, 0, 67184, + 2998, 9527, 67181, 65190, 12977, 42090, 67185, 0, 119100, 41236, 92235, + 42005, 42003, 41237, 5848, 67193, 67192, 3670, 67190, 67197, 67196, + 67195, 7890, 128070, 11298, 43315, 983313, 6229, 1593, 0, 125120, 619, + 4635, 65080, 127779, 12194, 4120, 65337, 65336, 0, 11808, 67199, 67198, 9366, 42790, 42006, 119115, 65327, 65326, 65325, 10757, 1507, 42216, 65321, 65320, 65335, 65334, 65333, 65332, 65331, 42059, 65329, 42689, 92427, 9128, 94045, 42073, 6785, 64590, 983830, 4371, 7196, 65318, 2035, - 65316, 4106, 65314, 65313, 42074, 127847, 41228, 0, 65609, 41241, 7903, - 41239, 43533, 78459, 7189, 0, 0, 0, 12357, 42802, 78450, 8487, 9131, 0, - 4615, 12695, 127752, 0, 12175, 0, 64535, 0, 7809, 0, 0, 562, 12169, 6590, - 69762, 66455, 64738, 3219, 68654, 983787, 0, 1037, 0, 2025, 128263, - 13098, 78442, 10637, 4568, 549, 1570, 0, 2835, 0, 10624, 43623, 11072, - 127191, 0, 0, 12606, 78433, 2825, 0, 10825, 8079, 2821, 41046, 92327, - 7365, 983753, 120593, 13071, 0, 452, 41049, 42840, 6346, 2831, 5461, - 74596, 11465, 5212, 0, 64703, 119191, 42308, 7181, 0, 41332, 0, 12333, 0, - 1668, 0, 0, 0, 1187, 983385, 42628, 78575, 0, 128777, 0, 3240, 128518, - 12194, 0, 11591, 41065, 5323, 8166, 0, 0, 0, 74535, 1623, 65297, 128856, - 571, 0, 4918, 0, 5288, 127295, 8916, 65048, 1909, 8864, 0, 0, 10736, - 92508, 11571, 7615, 127300, 92296, 4237, 92576, 1035, 65815, 0, 7881, - 701, 65936, 3489, 0, 0, 120751, 11403, 0, 0, 127146, 3796, 6800, 0, 3994, - 11421, 0, 195076, 0, 983922, 0, 0, 64857, 128105, 2855, 127828, 66308, - 41621, 68214, 127283, 127817, 10654, 0, 119226, 12164, 3246, 7906, 43972, - 65847, 7182, 0, 13024, 194822, 74270, 128289, 0, 0, 0, 1496, 747, 0, 942, - 2378, 43136, 127905, 8466, 983575, 9320, 8001, 1232, 8139, 11617, 0, 0, - 11409, 68373, 6382, 0, 64634, 128279, 0, 11612, 0, 67600, 2374, 94066, - 8475, 11609, 66313, 0, 0, 5286, 119297, 0, 0, 64925, 120283, 194584, - 118982, 194583, 7705, 11942, 11305, 194581, 3309, 0, 0, 0, 0, 6802, 0, - 41653, 1280, 1241, 7168, 12096, 0, 66615, 42565, 41651, 0, 0, 0, 41650, - 66507, 66470, 0, 12914, 41491, 66010, 119552, 6078, 9954, 0, 1475, - 119247, 9938, 6084, 917546, 41064, 41062, 0, 0, 3256, 10189, 42076, - 43252, 78823, 917906, 8727, 0, 65875, 0, 0, 127762, 10562, 74215, 43065, - 0, 0, 3248, 74297, 3261, 9015, 71351, 0, 3635, 64337, 983281, 0, 0, 7195, - 0, 2007, 64431, 0, 0, 0, 0, 635, 0, 0, 65613, 77909, 92420, 73997, 0, 0, - 119218, 7984, 8600, 74434, 127770, 4176, 70050, 2034, 92551, 120805, - 65891, 127038, 0, 318, 2038, 128860, 78596, 0, 3649, 13149, 42145, 42798, - 3634, 120291, 118927, 67677, 120124, 7866, 0, 11402, 42146, 94032, 74238, - 42664, 2849, 127034, 0, 7938, 12960, 1761, 11812, 65379, 68386, 128185, - 1159, 0, 69729, 0, 0, 7178, 194632, 0, 41680, 0, 128203, 11534, 1514, - 11668, 67891, 9313, 7015, 0, 67877, 194567, 12989, 66474, 9368, 12848, - 1624, 43270, 0, 74278, 10818, 126644, 9953, 0, 78421, 1194, 3242, 9761, - 9555, 8598, 120299, 6169, 12871, 1551, 2798, 65176, 4958, 42752, 119025, - 0, 67875, 120301, 3495, 66648, 194768, 0, 68364, 983224, 4891, 0, 10641, - 0, 73746, 0, 68352, 0, 73787, 194829, 194633, 7199, 64955, 0, 0, 0, 0, 0, - 42685, 42679, 193, 0, 0, 0, 42667, 0, 5271, 92318, 92517, 118882, 1362, - 13297, 0, 128094, 0, 983331, 73789, 0, 6658, 4426, 0, 92628, 983842, - 92319, 7276, 42163, 5220, 0, 0, 983330, 2416, 3310, 42703, 0, 379, 0, - 43755, 0, 0, 3223, 65492, 1284, 194771, 4549, 0, 0, 983154, 127763, - 10807, 9558, 194613, 0, 8515, 8688, 12866, 65308, 3294, 983332, 8529, - 128101, 43385, 7564, 0, 43329, 0, 92458, 73757, 66456, 42359, 0, 2031, 0, - 7202, 0, 12676, 42729, 92198, 3215, 0, 7710, 1610, 73801, 0, 0, 65682, 0, - 120537, 65924, 9974, 228, 66354, 1501, 0, 64395, 5179, 7200, 6225, 0, - 65794, 1725, 65533, 8196, 7476, 74399, 0, 0, 7152, 8502, 5762, 1967, - 7483, 0, 0, 8104, 0, 7474, 77979, 0, 126507, 10414, 13001, 8141, 0, - 42537, 1557, 43594, 128642, 6330, 6805, 8631, 2545, 70052, 127166, 0, - 74190, 0, 0, 983786, 42762, 0, 42914, 1650, 262, 1637, 0, 7901, 3238, - 128173, 41861, 0, 128585, 65158, 10860, 94059, 43658, 7527, 0, 43319, - 6419, 0, 45, 0, 64588, 93989, 0, 119810, 7194, 5291, 0, 43666, 13129, 0, - 9084, 0, 8737, 0, 12881, 0, 12906, 9639, 7912, 2620, 0, 0, 0, 983875, - 179, 65896, 0, 64756, 2853, 78443, 118813, 983890, 118996, 119009, 2850, - 8084, 983085, 73850, 2801, 92284, 42069, 119839, 74754, 119841, 42072, - 119843, 119842, 10398, 983056, 0, 8377, 127116, 8245, 68401, 3158, 92396, - 3983, 43656, 923, 119857, 119856, 292, 13002, 119845, 119844, 3221, 1763, - 92463, 4612, 119851, 119850, 7253, 127110, 68391, 0, 10782, 3637, 12996, - 43542, 0, 64578, 983675, 3228, 69636, 8783, 0, 119614, 2731, 0, 0, 78585, - 4102, 7696, 73878, 0, 0, 78586, 43316, 4177, 11283, 9089, 0, 73996, - 983173, 64500, 43674, 0, 64947, 1856, 0, 0, 6379, 0, 0, 0, 3208, 12975, - 74775, 127380, 983931, 92389, 74072, 55269, 0, 0, 983683, 2033, 78577, - 78576, 195026, 55254, 7740, 0, 0, 0, 73964, 0, 93988, 67612, 65674, - 128244, 94110, 41689, 0, 74006, 64909, 6646, 11790, 74019, 0, 128066, - 128031, 8561, 4573, 0, 5326, 0, 120605, 7230, 8257, 0, 8778, 41688, 0, - 65776, 2071, 8314, 6459, 0, 7628, 65092, 73903, 66721, 11342, 128561, 0, - 0, 128226, 127001, 0, 11810, 13164, 10723, 967, 983951, 126469, 11946, 0, - 3257, 0, 12307, 1845, 983157, 43526, 0, 0, 1886, 42342, 10089, 870, 7648, - 3499, 8609, 7652, 876, 871, 877, 0, 878, 42015, 879, 43692, 4563, 0, 0, - 7591, 65887, 867, 9520, 872, 126607, 868, 873, 7642, 0, 869, 874, 7644, - 120674, 875, 790, 128303, 0, 0, 0, 66182, 983258, 5429, 195055, 66180, - 126480, 66181, 68452, 983289, 983248, 42067, 0, 5433, 10657, 7911, - 194622, 1547, 66176, 42012, 120576, 5425, 4977, 9999, 5317, 5423, 4611, - 0, 67637, 0, 9679, 74122, 0, 0, 0, 66194, 4418, 66184, 4628, 4245, - 119648, 0, 0, 1851, 0, 127189, 11908, 0, 9360, 118897, 983202, 42776, - 66187, 12837, 8829, 7711, 92714, 0, 92321, 43318, 0, 8809, 69881, 0, - 983142, 120604, 983052, 983882, 0, 983270, 0, 0, 7427, 9958, 4588, 43680, - 0, 74484, 194968, 2433, 0, 119622, 3352, 74363, 983885, 0, 793, 74404, 0, - 305, 567, 67662, 842, 128519, 8208, 0, 41695, 1647, 118877, 0, 7837, - 917625, 818, 5337, 194628, 917621, 41376, 119978, 126576, 120594, 74086, - 917615, 917614, 917613, 10973, 66359, 1372, 127172, 917608, 4969, 1254, - 917605, 917604, 93967, 917602, 65228, 78221, 126612, 0, 2840, 0, 119982, - 983939, 0, 3245, 9068, 68194, 64725, 0, 0, 12991, 0, 2651, 68016, 983265, - 917611, 127026, 128883, 0, 0, 43648, 120812, 0, 43322, 92662, 0, 0, - 64372, 92698, 3226, 655, 752, 7457, 7456, 7452, 3285, 128779, 127821, - 119988, 65610, 2391, 0, 92248, 671, 250, 7434, 618, 668, 610, 42800, - 7431, 1152, 42801, 640, 120666, 7448, 7439, 628, 3905, 73810, 0, 128266, - 64749, 67850, 2107, 0, 0, 4605, 128174, 983192, 43372, 65945, 128838, 0, - 119590, 0, 0, 0, 987, 6927, 11572, 42261, 11464, 3365, 9971, 0, 0, - 128297, 0, 0, 0, 0, 11334, 43326, 12609, 11519, 11503, 5530, 5210, 0, - 4627, 983892, 5208, 0, 128842, 10332, 5218, 7976, 9156, 0, 3244, 5529, - 69647, 73894, 128852, 5432, 64965, 5527, 74033, 10516, 7790, 5528, 0, - 42140, 120281, 0, 0, 43545, 9887, 0, 4000, 7429, 7428, 665, 7424, 3206, - 120278, 7884, 0, 128566, 917989, 128666, 211, 2509, 128858, 120573, - 68672, 3220, 42235, 0, 10690, 8951, 5214, 42474, 8118, 0, 7048, 4590, - 127258, 5852, 0, 0, 127259, 1708, 0, 983165, 2623, 11943, 0, 69226, 0, - 4698, 66509, 1066, 119921, 4701, 983876, 120285, 74225, 94111, 8267, 0, - 127265, 0, 7516, 0, 2625, 983977, 8034, 74309, 0, 3631, 10955, 7850, - 120293, 8416, 0, 0, 0, 43384, 12660, 0, 0, 0, 74850, 41069, 0, 128156, - 12099, 4310, 10032, 6252, 713, 7990, 0, 3990, 0, 983262, 66368, 5017, - 64956, 7071, 0, 119144, 1030, 118800, 983120, 9513, 41059, 9357, 0, 1773, - 0, 120350, 0, 6339, 7745, 9844, 0, 64650, 94, 1880, 74766, 983838, 8908, - 0, 128707, 65913, 78470, 10752, 13003, 0, 126572, 41307, 8732, 120338, 0, - 1757, 6964, 4696, 0, 120335, 64785, 7394, 3641, 5419, 128055, 0, 127883, - 0, 120344, 43988, 0, 8610, 43062, 7592, 856, 74299, 936, 13289, 69894, - 43171, 1459, 0, 65243, 78638, 19953, 0, 1504, 70064, 0, 12913, 74206, - 7529, 0, 128699, 983957, 120782, 4113, 0, 2372, 336, 0, 7509, 12152, 0, - 682, 66458, 41505, 0, 64743, 10593, 1703, 0, 983955, 8033, 69953, 0, - 9810, 127269, 0, 12970, 0, 42351, 10109, 917623, 0, 194693, 0, 92690, 0, - 0, 74291, 1965, 7069, 43312, 0, 73887, 0, 2087, 64370, 6314, 41714, 8501, - 0, 0, 74239, 41317, 92614, 2091, 74545, 2090, 0, 9353, 7117, 2077, 77886, - 0, 10498, 2083, 77888, 0, 0, 119236, 634, 0, 0, 0, 69779, 4165, 8746, 0, - 9654, 12856, 6924, 0, 7066, 983719, 0, 128135, 41037, 42692, 7786, 12959, - 41039, 127483, 0, 680, 2302, 128200, 1181, 7056, 3174, 126516, 0, 92668, - 65665, 127375, 126506, 6920, 0, 92295, 0, 118965, 0, 64644, 126981, - 74119, 0, 41028, 0, 6231, 2613, 65302, 40989, 0, 194696, 0, 42760, 0, - 983566, 0, 40987, 4667, 0, 983932, 8828, 0, 0, 1246, 4746, 0, 0, 11021, - 4749, 92675, 0, 921, 4744, 0, 12702, 242, 0, 1566, 8217, 0, 64653, 78386, - 128121, 74036, 74505, 43274, 5313, 951, 0, 0, 983867, 7604, 983290, 4009, - 127816, 983710, 120562, 0, 983720, 64860, 119138, 119069, 0, 127370, - 4048, 983598, 0, 70024, 1646, 77890, 64534, 73995, 120705, 0, 119890, + 65316, 4106, 65314, 65313, 42074, 127847, 41228, 128960, 65609, 41241, + 7903, 41239, 43533, 78459, 7189, 0, 0, 128753, 12357, 42802, 78450, 8487, + 9131, 66292, 4615, 12695, 127752, 0, 12175, 0, 64535, 0, 7809, 0, 0, 562, + 12169, 6590, 69762, 66455, 64738, 3219, 68654, 983787, 128281, 1037, + 128677, 2025, 128263, 13098, 78442, 10637, 4568, 549, 1570, 43839, 2835, + 0, 10624, 43623, 11072, 127191, 0, 0, 12606, 78433, 2825, 0, 10825, 8079, + 2821, 41046, 92327, 7365, 92634, 120593, 13071, 129052, 452, 41049, + 42840, 6346, 2831, 5461, 74596, 11465, 5212, 0, 64703, 119191, 42308, + 7181, 0, 41332, 0, 12333, 41047, 1668, 0, 0, 0, 1187, 983385, 42628, + 78575, 0, 71863, 0, 3240, 128518, 12151, 0, 11591, 41065, 5323, 8166, 0, + 0, 0, 66827, 1623, 65297, 128856, 571, 0, 4918, 0, 5288, 127295, 1541, + 65048, 1909, 8864, 0, 66402, 10736, 92508, 11571, 7615, 70476, 92296, + 4237, 92576, 1035, 65815, 119301, 3567, 701, 65936, 3489, 0, 70462, + 70172, 11403, 0, 0, 127146, 3796, 6800, 70472, 3994, 11421, 74611, + 195076, 195078, 983922, 0, 0, 64857, 128105, 2855, 74418, 66308, 41621, + 68214, 127283, 127817, 10654, 127818, 119226, 12164, 3246, 7906, 43972, + 65847, 7182, 0, 13024, 66276, 74270, 128289, 125090, 0, 0, 1496, 747, 0, + 942, 2378, 43136, 127905, 8466, 983575, 9320, 8001, 1232, 8139, 11617, + 74637, 0, 11409, 68373, 6382, 126500, 64634, 92362, 70202, 11612, 93008, + 67600, 2374, 94066, 8475, 11609, 66313, 983769, 0, 5286, 119297, 0, + 983251, 64925, 120283, 127204, 118982, 71905, 7705, 11942, 11305, 127203, + 3309, 128619, 9206, 119165, 113824, 6802, 70353, 41653, 1280, 1241, 7168, + 12096, 0, 66615, 42565, 41651, 0, 917627, 0, 41650, 66507, 66470, 74472, + 12914, 41491, 66010, 94106, 6078, 9954, 78822, 1475, 119247, 9938, 6084, + 917546, 41064, 41062, 0, 0, 3256, 10189, 42076, 43252, 78823, 71861, + 8727, 0, 65875, 0, 0, 127762, 10562, 74215, 43065, 0, 0, 3248, 74297, + 3261, 9015, 71351, 0, 3635, 64337, 92759, 125054, 0, 7195, 0, 2007, + 64431, 0, 0, 92197, 0, 635, 0, 0, 65613, 77909, 92420, 73997, 0, 0, + 119218, 7984, 8600, 74434, 127770, 4176, 70050, 2034, 78423, 11154, + 65891, 127038, 0, 318, 2038, 128860, 78596, 194602, 3649, 13149, 42145, + 42798, 3634, 120291, 71885, 67677, 120124, 7866, 0, 11402, 42146, 94032, + 74238, 42664, 2849, 127034, 0, 7938, 12960, 1761, 11812, 65379, 68386, + 128185, 1159, 71183, 69729, 0, 120797, 7178, 194632, 983836, 41680, 0, + 128203, 11534, 1514, 11668, 67891, 9313, 7015, 128490, 67877, 194567, + 12989, 66474, 9368, 12848, 1624, 43270, 0, 74278, 10818, 126644, 9953, 0, + 78421, 1194, 3242, 9761, 9555, 8598, 120299, 6169, 12871, 1551, 2798, + 65176, 4958, 42752, 119025, 0, 67875, 120301, 3495, 66648, 125079, + 113780, 68364, 120779, 4891, 0, 10641, 0, 73746, 983837, 68352, 0, 73787, + 194829, 194633, 7199, 11131, 0, 0, 0, 983852, 0, 42685, 42679, 193, + 78789, 0, 0, 42667, 0, 5271, 68323, 92517, 118882, 1362, 13297, 0, 71880, + 0, 983331, 73789, 0, 6658, 4426, 0, 66830, 983842, 92319, 7276, 42163, + 5220, 0, 0, 125080, 2416, 3310, 42703, 127828, 379, 0, 43755, 70504, + 43647, 3223, 65492, 1284, 194771, 4549, 0, 0, 983154, 70784, 10807, 9558, + 93027, 0, 8515, 8688, 12866, 65308, 3294, 983332, 8529, 128101, 43385, + 7564, 0, 43329, 0, 92458, 73757, 66456, 42359, 0, 2031, 983890, 7202, + 128618, 12676, 42729, 74777, 3215, 0, 7710, 1610, 73801, 0, 0, 65682, 0, + 120537, 65924, 9974, 228, 66354, 1501, 0, 64395, 5179, 7200, 6225, + 118927, 42999, 1725, 65533, 8196, 7476, 74399, 0, 66868, 7152, 8502, + 5762, 1967, 7483, 125083, 0, 8104, 70128, 7474, 77979, 127200, 126507, + 10414, 13001, 8141, 0, 42537, 1557, 43594, 128642, 6330, 6805, 8631, + 2545, 70052, 127166, 0, 74190, 0, 70410, 983786, 42762, 0, 42914, 1650, + 262, 1637, 128502, 7901, 3238, 128173, 41861, 0, 120211, 65158, 10860, + 94059, 43658, 7527, 0, 43319, 6419, 0, 45, 0, 64588, 93989, 127753, + 119810, 7194, 5291, 0, 43666, 13129, 128684, 9084, 0, 8737, 983165, + 12881, 0, 12906, 9639, 7912, 2620, 983882, 3564, 0, 69978, 179, 43644, + 126503, 64756, 2853, 78443, 118813, 129042, 70347, 119009, 2850, 8084, + 983085, 73850, 2801, 92284, 42069, 119839, 74754, 119841, 42072, 92736, + 119842, 10398, 983056, 0, 8377, 119312, 8245, 68401, 3158, 92396, 3983, + 43656, 923, 119857, 92470, 292, 11119, 119845, 119844, 3221, 1763, 92463, + 4612, 67729, 119850, 7253, 70456, 68391, 0, 10782, 3637, 12996, 43542, + 113676, 64578, 983675, 3228, 69636, 8783, 0, 119614, 2731, 0, 0, 78585, + 4102, 7696, 73878, 0, 129128, 70813, 43316, 4177, 11283, 9089, 0, 73996, + 983173, 64500, 43674, 0, 64947, 1856, 0, 0, 6379, 0, 11142, 127176, 3208, + 12975, 74775, 127380, 983931, 92389, 74072, 55269, 0, 0, 983683, 2033, + 78577, 78576, 195026, 55254, 7740, 0, 70448, 127895, 73964, 68505, 93988, + 67612, 65674, 128244, 94110, 41689, 0, 74006, 64909, 6646, 11790, 74019, + 0, 128066, 128031, 8561, 4573, 0, 5326, 92571, 120605, 7230, 8257, + 194937, 8778, 41688, 0, 65776, 2071, 8314, 6459, 43511, 7628, 65092, + 73903, 66721, 11342, 128561, 0, 983432, 128226, 127001, 0, 11810, 13164, + 10723, 967, 983717, 126469, 11946, 983602, 3257, 127209, 12307, 1845, + 983157, 43526, 0, 0, 1886, 42342, 10089, 870, 7648, 3499, 7662, 7652, + 876, 871, 877, 7665, 878, 42015, 879, 43692, 4563, 0, 0, 7591, 65887, + 867, 9520, 872, 7656, 868, 873, 7642, 7659, 869, 874, 7644, 120674, 875, + 790, 128303, 118938, 0, 983641, 66182, 194623, 5429, 195055, 66180, + 126480, 66181, 68452, 983289, 917929, 42067, 0, 5433, 10657, 7911, + 125119, 1547, 66176, 42012, 120576, 5425, 4977, 9999, 5317, 5423, 4611, + 125094, 67637, 127286, 9679, 74122, 92978, 0, 0, 66194, 4418, 66184, + 4628, 4245, 119648, 0, 0, 1851, 124995, 127189, 11908, 0, 9360, 118897, + 194880, 42776, 66187, 12837, 8829, 7711, 11112, 0, 92321, 43318, 92302, + 8809, 69881, 0, 126518, 120604, 983052, 983275, 983431, 983270, 0, + 120577, 7427, 9958, 4588, 43680, 0, 74484, 194968, 2433, 128602, 69973, + 3352, 74363, 983885, 0, 793, 74404, 11197, 305, 567, 67662, 842, 69979, + 8208, 68308, 41695, 1647, 118877, 70841, 7837, 917625, 818, 5337, 194628, + 917621, 41376, 119978, 126576, 120594, 74086, 917615, 70179, 917613, + 10973, 66359, 1372, 127172, 917608, 4969, 1254, 917605, 194654, 93967, + 917602, 65228, 78221, 126612, 67723, 2840, 0, 78829, 983939, 66887, 3245, + 9068, 68194, 64725, 0, 128051, 12991, 124971, 2651, 68016, 983265, + 917611, 125038, 70835, 0, 70844, 43648, 120812, 917833, 43322, 92662, 0, + 0, 64372, 92698, 3226, 655, 752, 7457, 7456, 7452, 3285, 128475, 11152, + 92903, 65610, 2391, 92908, 92248, 671, 250, 7434, 618, 668, 610, 42800, + 7431, 1152, 42801, 640, 120666, 7448, 7439, 628, 3905, 73810, 128340, + 128266, 64749, 67850, 2107, 128345, 74249, 4605, 128174, 983192, 43372, + 65945, 128838, 11113, 119590, 0, 0, 70495, 987, 6927, 11572, 42261, + 11464, 3365, 9971, 0, 0, 128297, 0, 78762, 0, 0, 11334, 43326, 12609, + 11519, 11503, 5530, 5210, 0, 4627, 127784, 5208, 0, 128842, 10332, 2424, + 7976, 9156, 0, 3244, 5529, 69647, 73894, 128852, 5432, 64965, 5527, + 42315, 10516, 7790, 5528, 983699, 42140, 120281, 0, 0, 43545, 9887, + 129044, 4000, 7429, 7428, 665, 7424, 3206, 120278, 7884, 0, 128566, + 917989, 128666, 211, 2509, 92904, 70822, 68672, 3220, 42235, 78480, + 10690, 8951, 5214, 42474, 8118, 0, 7048, 4590, 127258, 5852, 0, 78482, + 127259, 1708, 0, 78481, 2623, 11943, 128700, 69226, 69974, 4698, 66509, + 1066, 119921, 4701, 983876, 120285, 70447, 94111, 8267, 0, 1421, 66426, + 7516, 127552, 2625, 983977, 8034, 74309, 0, 3631, 10955, 7850, 120293, + 8416, 0, 0, 0, 43384, 12660, 128693, 0, 0, 74850, 41069, 70185, 128156, + 12099, 4310, 10032, 6252, 713, 7990, 983487, 3990, 125050, 983262, 66368, + 5017, 64956, 7071, 0, 70457, 1030, 118800, 92563, 9513, 41059, 9357, 0, + 1773, 77939, 120350, 0, 6339, 7745, 9844, 127220, 64650, 94, 1880, 74766, + 113719, 8908, 0, 128707, 65913, 78470, 10752, 13003, 0, 126572, 41307, + 8732, 120338, 0, 1757, 6964, 4696, 0, 120335, 64785, 7394, 3641, 5419, + 128055, 0, 127883, 0, 120344, 43988, 70423, 8610, 43062, 7592, 856, + 74299, 936, 13289, 69894, 43171, 1459, 0, 65243, 78638, 19953, 0, 1504, + 70064, 0, 12913, 74206, 7529, 128745, 128699, 70203, 120782, 4113, 0, + 2372, 336, 0, 7509, 12152, 194885, 682, 7655, 41505, 0, 64743, 10593, + 1703, 92467, 77911, 8033, 69953, 0, 9810, 127269, 120013, 12970, 0, + 42351, 10109, 74535, 0, 194693, 0, 92690, 0, 65068, 74291, 1965, 7069, + 43312, 0, 73887, 11130, 2087, 64370, 6314, 41714, 8501, 11145, 0, 74239, + 41317, 92614, 2091, 74545, 2090, 69912, 9353, 7117, 2077, 77886, 11161, + 10498, 2083, 77888, 71196, 0, 119236, 634, 0, 92290, 0, 69779, 4165, + 8746, 195048, 9654, 12856, 6924, 7660, 7066, 983719, 70415, 128135, + 41037, 42692, 7786, 12959, 41039, 127483, 124965, 680, 2302, 128200, + 1181, 7056, 3174, 67248, 0, 92668, 65665, 127375, 113776, 6920, 0, 92295, + 0, 118965, 68318, 64644, 126981, 74119, 68238, 41028, 74025, 6231, 2613, + 65302, 40989, 68239, 68230, 68234, 42760, 0, 124989, 0, 40987, 4667, 0, + 71843, 8828, 0, 70506, 1246, 4746, 0, 128508, 11021, 4749, 92675, 917882, + 921, 4744, 0, 12702, 242, 0, 1566, 8217, 127210, 64653, 78386, 74617, + 74036, 74505, 43274, 5313, 951, 74568, 92983, 983867, 7604, 983290, 4009, + 70426, 71844, 120562, 0, 983720, 64860, 119138, 119069, 0, 127370, 4048, + 983598, 0, 70024, 1646, 77890, 64534, 73995, 120705, 129047, 119890, 2579, 119905, 3177, 11357, 9099, 4107, 3441, 119894, 2975, 74442, 9822, 983935, 55220, 10084, 73943, 118840, 0, 917562, 194610, 3399, 9851, - 983717, 11909, 9059, 0, 7687, 0, 6789, 0, 0, 0, 71367, 0, 0, 1777, 9151, - 1137, 69767, 749, 42366, 0, 5385, 128574, 128218, 0, 0, 5989, 0, 0, - 128091, 0, 41685, 69223, 0, 9769, 41684, 983216, 519, 0, 11740, 5766, 0, - 0, 2600, 8848, 120138, 41297, 0, 3666, 74473, 41300, 74468, 65160, 0, - 69688, 69771, 74479, 0, 6558, 0, 0, 69765, 120750, 252, 0, 41302, 0, 0, - 0, 69763, 0, 11729, 8719, 9060, 0, 120139, 10761, 0, 0, 0, 118792, 11734, - 983223, 11730, 0, 9593, 5757, 2403, 64808, 55275, 0, 11728, 43572, 0, 0, - 7764, 983714, 11094, 120825, 0, 983226, 4282, 8298, 0, 0, 0, 0, 0, 64449, - 0, 126650, 63854, 8456, 0, 74783, 65670, 0, 78250, 0, 7774, 10607, 9792, - 0, 0, 0, 0, 120764, 0, 10019, 74762, 0, 3458, 4365, 70053, 983712, 3647, - 0, 2602, 128341, 0, 194707, 41135, 0, 0, 0, 64631, 172, 4971, 41219, - 41137, 1889, 7238, 6545, 126476, 92193, 7597, 10528, 0, 0, 3732, 73910, - 194588, 5344, 0, 43366, 43363, 9062, 119252, 0, 0, 0, 64479, 9232, 92596, - 0, 0, 194712, 10900, 41531, 1263, 3720, 12048, 0, 64292, 41524, 7227, - 119635, 6099, 41534, 0, 127354, 127345, 299, 917957, 8525, 127347, 3524, - 917565, 8831, 127349, 92564, 3075, 67867, 127352, 0, 66362, 0, 64353, 0, - 0, 5845, 0, 0, 0, 2581, 8200, 65114, 68460, 0, 43283, 5551, 0, 120735, - 983201, 6340, 118855, 0, 78134, 8680, 7204, 70065, 2588, 2914, 7011, - 55281, 0, 2471, 194631, 2883, 2749, 119563, 73774, 10913, 0, 0, 8666, - 675, 42493, 0, 43571, 0, 6219, 0, 9980, 41232, 10928, 0, 41153, 41229, - 118967, 0, 3738, 94016, 0, 12711, 3181, 66212, 74289, 68472, 42857, 8262, - 983379, 0, 983222, 0, 42347, 12092, 9615, 7234, 74047, 983088, 0, 43744, - 0, 0, 73846, 2934, 12722, 120762, 922, 43983, 74507, 983126, 74461, 3218, + 917609, 11909, 9059, 0, 7687, 0, 6789, 128392, 0, 71842, 70178, 0, 0, + 1777, 9151, 1137, 66867, 749, 42366, 70444, 5385, 70791, 72435, 70127, + 128972, 5989, 0, 74636, 128091, 0, 41685, 69223, 0, 9769, 41684, 983216, + 519, 0, 11740, 5766, 0, 0, 2600, 8848, 70416, 41297, 0, 3666, 70420, + 41300, 74468, 65160, 0, 69688, 69771, 74479, 0, 6558, 0, 128064, 69765, + 92775, 252, 0, 41302, 119350, 127002, 118839, 69763, 0, 11729, 8719, + 9060, 129091, 120139, 10761, 0, 0, 0, 118792, 11734, 93011, 11730, + 113741, 9593, 5757, 2403, 64808, 55275, 0, 11728, 43572, 0, 0, 7764, + 129132, 11094, 120825, 0, 43489, 4282, 8298, 0, 0, 70328, 0, 70324, + 64449, 0, 126650, 63854, 8456, 65587, 70442, 65670, 0, 78250, 0, 7774, + 10607, 9792, 0, 70326, 0, 0, 120764, 70322, 10019, 74762, 0, 3458, 4365, + 70053, 983712, 3647, 120207, 2602, 128341, 0, 125043, 41135, 0, 0, + 128455, 64631, 172, 4971, 41219, 41137, 1889, 7238, 6545, 126476, 77926, + 7597, 10528, 0, 0, 3732, 73910, 194588, 5344, 0, 43366, 43363, 9062, + 119252, 0, 92528, 0, 64479, 9232, 92596, 0, 113707, 194712, 10900, 41531, + 1263, 3720, 12048, 74075, 64292, 41524, 7227, 119635, 6099, 41534, 0, + 127354, 127345, 299, 917957, 8525, 127347, 3524, 917565, 8831, 127349, + 92564, 3075, 67867, 94053, 0, 66362, 0, 64353, 70440, 0, 5845, 0, 0, 0, + 2581, 8200, 65114, 68460, 983693, 43283, 5551, 0, 120735, 983201, 6340, + 118855, 128934, 78134, 8680, 7204, 70065, 2588, 2914, 7011, 55281, 0, + 2471, 194631, 2883, 2749, 119563, 73774, 10913, 0, 0, 8666, 675, 42493, + 0, 43571, 0, 6219, 128584, 9980, 41232, 10928, 0, 41153, 41229, 118967, + 0, 3738, 94016, 0, 12711, 3181, 66212, 74289, 68472, 42857, 8262, 983379, + 0, 74476, 0, 42347, 12092, 9615, 7234, 74047, 983088, 983819, 43744, 0, + 0, 73846, 2934, 12722, 120762, 922, 43983, 74507, 983126, 74461, 3218, 120471, 74290, 120469, 64562, 120475, 8569, 11404, 11932, 73728, 3214, - 120461, 120468, 12128, 3207, 65486, 78729, 1901, 78727, 127326, 120460, + 11212, 120468, 12128, 3207, 65486, 78729, 1901, 78727, 127326, 120460, 7425, 3205, 68003, 78737, 78736, 78735, 43383, 69940, 65459, 2606, 78730, - 73897, 0, 11496, 1173, 0, 41272, 119661, 0, 0, 983321, 120737, 0, 983971, - 983320, 378, 2610, 0, 65079, 983325, 65695, 126559, 37, 7068, 0, 120480, - 120479, 3209, 120477, 0, 10638, 9768, 69952, 119909, 983399, 0, 0, 0, 0, - 65510, 0, 0, 5233, 983335, 64792, 983334, 0, 126633, 0, 7060, 9847, - 120144, 1685, 595, 0, 73971, 1292, 8940, 7380, 11088, 0, 10004, 126997, - 0, 6541, 0, 0, 0, 3243, 9014, 5606, 0, 538, 64620, 5602, 8467, 74391, - 6547, 128132, 8203, 78488, 983090, 8458, 65211, 8495, 119904, 0, 917552, - 779, 78314, 64367, 2465, 69901, 8193, 55279, 9730, 9280, 0, 7065, 74155, - 4346, 0, 73798, 504, 0, 92414, 8982, 0, 0, 0, 782, 0, 10883, 0, 194852, - 732, 3737, 127253, 1548, 68650, 92507, 1832, 5604, 5735, 41141, 119020, - 4376, 0, 11787, 3745, 0, 0, 42888, 65712, 983304, 3869, 11937, 5725, - 127539, 1783, 68648, 5728, 0, 0, 0, 11918, 66567, 5724, 0, 5727, 78521, - 0, 0, 764, 0, 128116, 43531, 0, 9033, 0, 42532, 6223, 11042, 120749, - 11423, 0, 119861, 71344, 43465, 0, 128267, 6559, 64557, 71348, 92649, - 120648, 43019, 43477, 10238, 74491, 0, 43377, 92282, 71346, 1478, 9783, - 11825, 2607, 64740, 0, 7739, 74543, 0, 0, 0, 6132, 0, 63765, 0, 70058, - 41144, 0, 92438, 43537, 6761, 10093, 4369, 917791, 0, 983148, 8820, 3947, - 0, 0, 11515, 526, 128103, 41295, 194603, 917785, 194932, 0, 7688, 917786, - 7686, 8288, 11815, 0, 0, 983382, 1543, 3713, 41221, 12423, 42281, 917788, - 74024, 12293, 0, 64357, 11794, 42082, 0, 1737, 8987, 42081, 0, 7205, 0, - 9335, 12850, 119870, 6553, 7055, 0, 8277, 0, 0, 5475, 74795, 6780, 0, 0, - 12990, 1160, 42084, 119650, 41217, 119660, 10018, 360, 0, 0, 68176, 5863, - 3137, 0, 4147, 983170, 41216, 7844, 2616, 119190, 68461, 65234, 983294, + 73897, 0, 11496, 1173, 0, 41272, 119661, 0, 0, 983321, 120737, 126557, + 194773, 983320, 378, 2610, 983326, 65079, 983325, 65695, 126559, 37, + 7068, 0, 120480, 68236, 3209, 120477, 0, 10638, 9768, 69952, 119909, + 983399, 92225, 0, 983338, 0, 43840, 0, 0, 5233, 983335, 64792, 71233, 0, + 126633, 128919, 7060, 9847, 120144, 1685, 595, 0, 70428, 1292, 8940, + 7380, 11088, 0, 10004, 126997, 0, 6541, 43837, 0, 0, 3243, 9014, 5606, 0, + 538, 64620, 5602, 8467, 74391, 6547, 128132, 8203, 66420, 68241, 8458, + 65211, 8495, 92311, 0, 917552, 779, 78314, 64367, 2465, 69901, 8193, + 55279, 9730, 9280, 0, 7065, 74155, 4346, 0, 73798, 504, 125115, 92414, + 8982, 0, 128711, 119170, 782, 129028, 10883, 128446, 194852, 732, 3737, + 127253, 1548, 68650, 92507, 1832, 5604, 5735, 41141, 119020, 4376, + 983370, 11787, 3745, 0, 119885, 42888, 65712, 127913, 3869, 11937, 5725, + 127539, 1783, 7416, 5728, 0, 128457, 119554, 11918, 66567, 5724, 0, 5727, + 78521, 0, 0, 764, 0, 128116, 43531, 113670, 9033, 0, 42532, 6223, 11042, + 120749, 11423, 74852, 119861, 68303, 43465, 0, 128267, 6559, 64557, + 71348, 92649, 120648, 43019, 43477, 10238, 74491, 0, 43377, 92282, 71346, + 1478, 9783, 11825, 2607, 64740, 113689, 7739, 74543, 917765, 67393, 0, + 6132, 0, 63765, 128396, 70058, 41144, 71899, 92438, 43537, 6761, 10093, + 4369, 917791, 0, 194776, 8820, 3947, 0, 0, 11515, 526, 128103, 41295, + 194603, 917785, 194932, 113691, 7688, 917786, 7686, 8288, 11815, 0, 0, + 983382, 1543, 3713, 41221, 12423, 42281, 917788, 74024, 12293, 0, 64357, + 11794, 42082, 0, 1737, 8987, 42081, 0, 7205, 0, 9335, 12850, 119870, + 6553, 7055, 0, 8277, 0, 67751, 5475, 74795, 6780, 65067, 0, 1327, 1160, + 42084, 119650, 41217, 119660, 10018, 360, 129070, 983865, 68176, 5863, + 3137, 0, 4147, 983170, 41216, 7844, 2616, 70197, 68461, 65234, 68341, 13076, 3135, 983287, 78143, 119139, 3142, 92451, 94068, 10819, 119580, - 10183, 0, 2608, 1470, 73967, 94008, 6227, 0, 127173, 69741, 983582, 6163, - 983558, 0, 127314, 0, 0, 8603, 0, 119866, 3306, 10876, 43392, 119573, - 127931, 5751, 0, 6222, 0, 0, 12086, 7403, 1600, 64309, 64939, 0, 64783, - 92658, 11310, 0, 8882, 0, 0, 2570, 7021, 0, 0, 43110, 0, 1234, 6540, - 6974, 0, 0, 983211, 5002, 0, 41286, 69946, 127019, 0, 43585, 0, 6551, - 983962, 128229, 0, 41289, 0, 194602, 0, 8977, 602, 120814, 0, 128778, - 128661, 0, 983375, 41279, 0, 0, 0, 11081, 43615, 0, 0, 0, 983612, 12727, - 0, 0, 78397, 9475, 7112, 65105, 0, 9633, 10886, 43592, 7831, 983829, - 194571, 0, 73915, 8076, 43048, 8290, 8291, 43051, 92570, 0, 2596, 43584, - 0, 13113, 0, 127757, 2393, 7058, 9087, 74067, 68673, 41574, 78337, 0, - 74058, 6376, 0, 0, 0, 0, 9854, 127748, 64696, 0, 128220, 0, 6994, 0, - 1720, 0, 0, 0, 6529, 7063, 983182, 3751, 9120, 983485, 0, 1798, 709, 0, - 1354, 1876, 13152, 6557, 12430, 8137, 94098, 92642, 0, 0, 245, 128097, - 11456, 41233, 7070, 0, 94046, 6136, 917609, 65677, 8682, 41235, 92595, - 42045, 9804, 118963, 432, 3595, 194945, 65437, 0, 74455, 42399, 0, 0, - 128274, 0, 119658, 0, 0, 0, 77894, 8797, 0, 9052, 64888, 7167, 2356, 95, - 74784, 10580, 0, 42286, 0, 64640, 0, 94109, 0, 74137, 70035, 10063, - 12652, 12199, 92480, 0, 2566, 11971, 983737, 0, 1065, 0, 0, 43400, 2576, - 66696, 93999, 0, 43604, 0, 0, 74082, 514, 74502, 70032, 2921, 43215, - 64493, 5772, 12968, 70055, 194944, 74580, 43398, 2580, 983810, 41341, - 41223, 6564, 1463, 41342, 0, 5293, 70020, 0, 3733, 11346, 0, 12054, 0, - 74098, 42827, 0, 13091, 0, 0, 0, 917915, 0, 127025, 0, 74821, 0, 983733, - 119042, 0, 127865, 13090, 66643, 0, 1270, 1132, 42360, 0, 74096, 66655, - 42569, 127824, 0, 64761, 0, 41021, 8510, 42432, 0, 0, 194782, 0, 64496, - 74109, 70030, 9915, 0, 983218, 7061, 41336, 3854, 69700, 13141, 68413, - 43401, 42319, 13082, 0, 7067, 68221, 0, 127383, 127171, 0, 0, 127797, - 9029, 43543, 119315, 2353, 6308, 0, 74792, 2611, 119186, 0, 0, 0, 43664, - 92399, 66627, 0, 4484, 8509, 118976, 11066, 65233, 0, 41224, 41017, 0, - 3747, 10522, 0, 0, 1691, 41226, 0, 12107, 7100, 10905, 65010, 194986, - 697, 66018, 9284, 4244, 0, 0, 92644, 13121, 120036, 0, 12010, 128573, - 128221, 0, 0, 0, 127193, 65816, 68111, 0, 127933, 65668, 92257, 6618, - 118784, 66365, 0, 42234, 12648, 78110, 7123, 70038, 5785, 9198, 9764, - 41316, 65877, 7383, 13230, 41299, 0, 0, 68365, 128258, 0, 0, 0, 13122, 0, - 191, 70060, 8585, 8000, 64411, 120652, 42889, 64850, 41072, 41578, 0, - 41577, 0, 10002, 0, 6533, 73802, 41570, 0, 683, 396, 41580, 68146, 0, - 12901, 43058, 0, 343, 7129, 42680, 41360, 78154, 0, 4743, 0, 0, 74040, - 74108, 8743, 1724, 1433, 119322, 0, 3739, 6263, 71349, 0, 3964, 6592, 0, - 128693, 66040, 0, 42568, 69806, 128113, 1778, 3956, 0, 42070, 6563, - 43075, 9018, 94006, 983396, 12067, 41312, 0, 5547, 74531, 127969, 0, - 8175, 0, 284, 8108, 934, 0, 74001, 173, 66460, 7174, 92703, 118822, 1750, - 0, 4394, 68368, 1807, 983888, 92298, 0, 5889, 0, 7180, 0, 119145, 0, - 917558, 42471, 6982, 1721, 44022, 7891, 42243, 42160, 2583, 4512, 119360, - 65230, 128109, 0, 0, 3855, 0, 0, 0, 0, 74295, 0, 0, 92416, 3975, 0, - 74087, 0, 12672, 3798, 2703, 983599, 0, 2109, 9774, 1275, 0, 0, 41095, - 3962, 0, 2932, 41101, 3954, 6457, 4513, 0, 0, 73994, 73992, 1468, 0, 0, - 41851, 128230, 41846, 0, 55238, 7633, 41849, 68385, 4320, 3224, 0, - 128032, 0, 42531, 119108, 1510, 0, 8256, 0, 11393, 0, 8879, 128075, - 92474, 8770, 0, 0, 78377, 1910, 8671, 78374, 4283, 0, 127117, 68361, - 78318, 2654, 7893, 195007, 0, 0, 0, 65106, 42761, 12857, 4581, 8411, - 78372, 78371, 78370, 78369, 78368, 0, 0, 0, 1733, 4392, 2568, 10786, - 69661, 0, 8184, 41486, 0, 7396, 7116, 0, 69788, 0, 7185, 7965, 0, 0, - 92347, 983087, 41350, 9129, 0, 0, 2294, 0, 92489, 0, 10481, 0, 70022, - 7171, 0, 340, 92498, 93972, 0, 0, 92200, 0, 0, 6764, 127487, 0, 0, 0, 0, - 65203, 11392, 119098, 119359, 0, 3210, 0, 0, 118795, 0, 0, 127970, - 917619, 0, 0, 10043, 0, 1186, 41571, 6999, 617, 9464, 126642, 3675, 5207, - 65062, 5213, 194769, 2617, 41348, 41568, 128803, 3253, 120535, 0, 8630, - 128544, 0, 5596, 5545, 7288, 2586, 64887, 0, 5217, 71336, 0, 0, 0, 64293, - 68098, 2635, 0, 0, 983846, 0, 983641, 7835, 70040, 0, 194988, 92285, - 64558, 127122, 0, 127121, 0, 127913, 0, 5784, 983102, 0, 0, 70033, 4011, - 917616, 68101, 0, 7864, 4254, 65095, 983496, 5600, 3903, 127083, 10447, - 5598, 1207, 120521, 66689, 3501, 42582, 43600, 194780, 0, 1124, 5597, - 194778, 194772, 9321, 983484, 983481, 983482, 0, 1719, 68356, 68354, - 9671, 1125, 4399, 127479, 917610, 983488, 7631, 5488, 7128, 120532, 0, - 5491, 0, 8937, 43044, 2604, 74187, 5490, 43046, 5489, 7212, 11768, 43043, - 6300, 0, 7122, 0, 4390, 454, 41397, 0, 9875, 7593, 194791, 92274, 118913, - 7207, 0, 65901, 2394, 2575, 0, 3746, 11016, 65752, 120037, 0, 43423, - 128683, 11989, 0, 0, 0, 0, 0, 8249, 128172, 0, 78531, 6640, 74806, 2598, - 513, 0, 6586, 8656, 0, 120710, 65008, 0, 194784, 194989, 194795, 983473, - 92515, 68475, 93973, 0, 0, 78637, 12647, 0, 128043, 69893, 1036, 983477, - 92419, 1723, 128056, 74217, 0, 41579, 2444, 0, 10705, 73876, 983469, - 74486, 983467, 740, 119222, 194978, 194984, 0, 4238, 11071, 9459, 68437, - 78140, 78139, 194985, 8121, 10438, 74487, 42574, 13285, 55263, 11907, - 195000, 5690, 92255, 93992, 0, 43181, 13095, 0, 127857, 64498, 0, 9506, - 6978, 194993, 77992, 0, 0, 194992, 0, 127845, 1122, 317, 0, 0, 0, 0, - 1920, 0, 10173, 827, 0, 0, 78378, 120126, 5223, 1304, 0, 119564, 5226, - 12602, 94044, 0, 9329, 7758, 9239, 41173, 5224, 5487, 1222, 5692, 41725, - 69229, 9674, 5695, 41711, 64627, 19909, 0, 74604, 5691, 287, 866, 233, - 127490, 983441, 42816, 94036, 65140, 74797, 0, 8830, 6568, 42300, 10524, - 41175, 983448, 983445, 983446, 5296, 983444, 42492, 43402, 92466, 3302, - 0, 0, 6516, 6515, 6514, 6513, 6512, 0, 7856, 8690, 0, 0, 12122, 119602, - 43976, 0, 1785, 69925, 68622, 65153, 194810, 5138, 0, 0, 118869, 0, 4540, - 41181, 0, 6200, 0, 5134, 0, 322, 4643, 5132, 0, 6389, 128533, 5143, 0, - 8790, 128694, 0, 194802, 0, 8869, 69916, 0, 42060, 71326, 9648, 194804, - 127012, 10270, 10286, 10318, 10382, 43529, 66477, 0, 0, 74170, 0, 3234, - 0, 0, 74376, 43139, 118815, 127084, 120627, 8767, 0, 74489, 9695, 120746, - 5201, 0, 6215, 12714, 6214, 13101, 0, 194999, 65268, 0, 0, 0, 11027, 0, - 10059, 10511, 42075, 9767, 789, 1749, 78890, 127071, 983670, 320, 0, - 8647, 0, 3049, 0, 6471, 42071, 43156, 9925, 127356, 127355, 66478, 4960, + 10183, 74635, 2608, 1470, 73967, 94008, 6227, 0, 127173, 65236, 917878, + 6163, 983558, 113728, 127314, 0, 0, 8603, 0, 119866, 3306, 10876, 43392, + 119573, 127931, 5751, 0, 6222, 0, 127466, 12086, 7403, 1600, 64309, + 64939, 0, 64783, 92658, 11310, 0, 8882, 0, 0, 2570, 7021, 0, 0, 43110, 0, + 1234, 6540, 6974, 92750, 0, 983211, 5002, 0, 41286, 69946, 74465, 71074, + 43585, 113720, 6551, 983373, 128229, 983272, 41289, 125130, 71080, + 127958, 8977, 602, 120814, 0, 128778, 128661, 194890, 983375, 41279, 0, + 0, 917795, 11081, 43615, 0, 0, 0, 983612, 12727, 0, 0, 78397, 9475, 7112, + 65105, 0, 9633, 10886, 43592, 7831, 983829, 194571, 0, 73915, 8076, + 43048, 8290, 8291, 43051, 92570, 0, 2596, 43584, 0, 13113, 0, 127757, + 2393, 7058, 9087, 74067, 68673, 41574, 78337, 70498, 42900, 6376, 0, 0, + 0, 0, 9854, 127748, 64696, 73879, 128220, 120752, 6994, 0, 1720, 0, 0, 0, + 6529, 7063, 983182, 3751, 9120, 983485, 0, 1798, 709, 0, 1354, 1876, + 13152, 6557, 12430, 8137, 94098, 67752, 70850, 0, 245, 128097, 11456, + 41233, 7070, 0, 94046, 6136, 68304, 65677, 8682, 41235, 92595, 42045, + 9804, 118963, 432, 3595, 127901, 65437, 0, 74455, 42399, 983136, 0, + 128274, 0, 119658, 128184, 0, 0, 77894, 8797, 0, 9052, 64888, 7167, 2356, + 95, 74784, 10580, 0, 42286, 92231, 64640, 69999, 94109, 128625, 74137, + 70035, 10063, 12652, 12199, 74622, 43492, 2566, 11971, 983737, 0, 1065, + 0, 0, 43400, 2576, 66696, 66819, 128624, 43604, 127891, 0, 3201, 514, + 74502, 70032, 2921, 43215, 64493, 5772, 12968, 70055, 194944, 74580, + 43398, 2580, 983810, 41341, 41223, 6564, 1463, 41342, 0, 5293, 70020, + 983185, 3733, 11346, 0, 12054, 0, 74098, 42827, 195074, 13091, 0, 0, 0, + 917915, 127961, 127025, 0, 74821, 71104, 66295, 92765, 0, 127865, 13090, + 66643, 0, 1270, 1132, 42360, 0, 74096, 66655, 42569, 127824, 66898, + 64761, 0, 41021, 8510, 42432, 0, 119317, 194782, 0, 64496, 74109, 70030, + 9915, 0, 983218, 7061, 41336, 3854, 69700, 13141, 68413, 43401, 42319, + 13082, 124976, 7067, 68221, 0, 127383, 127171, 0, 120745, 74209, 9029, + 43543, 70836, 2353, 6308, 129154, 74792, 2611, 119186, 66881, 0, 65063, + 43664, 92399, 66627, 125093, 4484, 8509, 118976, 11066, 65233, 0, 41224, + 41017, 0, 3747, 10522, 0, 0, 1691, 41226, 127214, 12107, 7100, 10905, + 65010, 127275, 697, 66018, 9284, 4244, 0, 93058, 77861, 13121, 120036, 0, + 12010, 128573, 128221, 125014, 0, 0, 127193, 65816, 68111, 0, 127933, + 65668, 92257, 6618, 3562, 66365, 0, 42234, 12648, 78110, 7123, 70038, + 5785, 9198, 9764, 41316, 65877, 7383, 13230, 41299, 0, 0, 68365, 128258, + 0, 0, 0, 13122, 0, 191, 70060, 8585, 8000, 64411, 120652, 42889, 64850, + 41072, 41578, 0, 41577, 0, 10002, 195028, 6533, 73802, 41570, 917919, + 683, 396, 41580, 68146, 983067, 12901, 43058, 0, 343, 7129, 42680, 41360, + 78154, 0, 4743, 69987, 0, 74040, 74108, 8743, 1724, 1433, 119322, 0, + 3739, 6263, 71349, 0, 3964, 6592, 0, 68288, 66040, 0, 42568, 69806, + 128113, 1778, 3956, 128443, 42070, 6563, 43075, 9018, 94006, 983396, + 12067, 41312, 92763, 5547, 8916, 127969, 128950, 8175, 0, 284, 8108, 934, + 128039, 74001, 173, 66460, 7174, 92703, 118822, 1750, 128686, 4394, + 68368, 1807, 983888, 92298, 0, 5889, 0, 7180, 0, 67127, 0, 67126, 42471, + 6982, 1721, 44022, 7891, 42243, 42160, 2583, 4512, 119360, 65230, 128109, + 0, 0, 3855, 194986, 11767, 0, 0, 74295, 0, 0, 92416, 3975, 67125, 74087, + 0, 12672, 3798, 2703, 983599, 0, 2109, 9774, 1275, 0, 0, 41095, 3962, + 68242, 2932, 41101, 3954, 6457, 4513, 74536, 0, 73994, 73992, 1468, + 120033, 983057, 41803, 128230, 41846, 127244, 55238, 7633, 41849, 68385, + 4320, 3224, 0, 92741, 66281, 42531, 74593, 1510, 128384, 8256, 0, 11393, + 0, 8879, 128075, 92474, 8770, 72416, 0, 72415, 1910, 8671, 78374, 4283, + 0, 127117, 68361, 78318, 2654, 7893, 195007, 128241, 0, 72394, 65106, + 42761, 12857, 4581, 8411, 78372, 78371, 78370, 78369, 78368, 74475, + 983442, 0, 1733, 4392, 2568, 10786, 69661, 0, 8184, 41486, 0, 7396, 7116, + 0, 69788, 0, 7185, 7965, 119144, 0, 92347, 195066, 41350, 9129, 0, 0, + 2294, 64501, 92489, 0, 10481, 0, 70022, 7171, 0, 340, 71105, 93972, + 67360, 0, 92200, 128249, 124979, 6764, 127487, 128393, 0, 92509, 128962, + 65203, 11392, 119098, 119359, 119073, 3210, 0, 0, 118795, 127976, 94101, + 127484, 917619, 119149, 0, 10043, 0, 1186, 41571, 6999, 617, 9464, + 125123, 3675, 5207, 65062, 5213, 74616, 2617, 41348, 41568, 128803, 3253, + 120535, 0, 8630, 128544, 0, 5596, 5545, 7288, 2586, 64887, 983644, 5217, + 71336, 128687, 917614, 0, 64293, 68098, 2635, 92760, 0, 983846, 0, 92742, + 7835, 70040, 120707, 194988, 92285, 64558, 127122, 0, 67083, 67085, + 70099, 0, 5784, 983102, 195050, 983812, 70033, 4011, 194565, 68101, + 124978, 7864, 4254, 65095, 983496, 5600, 3903, 127083, 10447, 5598, 1207, + 120521, 66689, 3501, 42582, 43600, 129054, 127103, 1124, 5597, 194778, + 194772, 9321, 983484, 113706, 983482, 67400, 1719, 68356, 68354, 9671, + 1125, 4399, 127479, 66274, 983488, 7631, 5488, 7128, 120532, 0, 5491, + 118797, 8937, 43044, 2604, 74187, 5490, 43046, 5489, 7212, 11768, 43043, + 6300, 194837, 7122, 983090, 4390, 454, 41397, 0, 9875, 7593, 194791, + 92274, 118913, 7207, 0, 65901, 2394, 2575, 0, 3746, 11016, 65752, 92757, + 0, 43423, 128683, 11989, 0, 0, 0, 78296, 0, 8249, 128172, 11109, 78531, + 6640, 74806, 2598, 513, 0, 6586, 8656, 0, 69792, 65008, 194597, 71111, + 78383, 194795, 127474, 92515, 68475, 93973, 194584, 63799, 78637, 12647, + 0, 128043, 69893, 1036, 194982, 92419, 1723, 68215, 74217, 0, 41579, + 2444, 120722, 10705, 73876, 983469, 74486, 983467, 740, 119222, 194978, + 194984, 0, 4238, 11071, 9459, 68437, 78140, 78139, 194985, 8121, 10438, + 74487, 42574, 13285, 55263, 11907, 129107, 5690, 92255, 93992, 0, 43181, + 13095, 77925, 127857, 64498, 0, 9506, 6978, 70176, 77992, 0, 113743, + 78379, 0, 127845, 1122, 317, 0, 71055, 0, 0, 1920, 0, 10173, 827, 0, 0, + 78378, 119600, 5223, 1304, 0, 119564, 5226, 12602, 94044, 5880, 9329, + 7758, 9239, 41173, 5224, 5487, 1222, 5692, 41725, 69229, 9674, 5695, + 41711, 64627, 19909, 71077, 74604, 5691, 287, 866, 233, 68138, 983441, + 42816, 94036, 65140, 74797, 128158, 8830, 6568, 42300, 10524, 41175, + 125033, 983445, 983446, 5296, 983444, 42492, 43402, 92466, 3302, 0, + 74858, 6516, 6515, 6514, 6513, 6512, 0, 7856, 8690, 983686, 70870, 12122, + 119602, 43976, 0, 1785, 69925, 68622, 65153, 194810, 5138, 0, 71922, + 118869, 0, 4540, 41181, 0, 6200, 0, 5134, 69980, 322, 4643, 5132, 0, + 6389, 128533, 5143, 0, 8790, 128694, 120121, 194802, 71168, 8869, 69916, + 93069, 42060, 71326, 9648, 194804, 71170, 10270, 10286, 10318, 10382, + 43529, 66477, 194800, 0, 74170, 0, 3234, 43835, 0, 74376, 43139, 118815, + 127084, 120627, 8767, 68231, 74489, 9695, 72439, 5201, 0, 6215, 12714, + 6214, 13101, 0, 194999, 65268, 7661, 0, 128444, 11027, 128596, 10059, + 10511, 42075, 9767, 789, 1749, 78890, 67115, 983670, 320, 0, 8647, + 983705, 3049, 0, 6471, 42071, 43156, 9925, 127356, 127355, 66478, 4960, 5549, 127359, 127346, 8485, 4671, 5418, 127350, 3351, 127006, 127351, 10610, 5414, 3064, 6212, 4286, 5421, 127344, 9554, 0, 94048, 127109, 6653, 128811, 0, 64510, 6213, 12885, 0, 119045, 64720, 0, 120759, 73741, - 12603, 7131, 11430, 4566, 7518, 9317, 3801, 10342, 10406, 0, 119259, - 42576, 0, 5200, 126611, 917948, 0, 9183, 127361, 74458, 73825, 395, 5482, - 5198, 4349, 10390, 74202, 5196, 43224, 6113, 42009, 5205, 0, 43307, 0, - 118973, 0, 12134, 0, 0, 118843, 9126, 435, 983624, 12014, 10377, 8093, - 9079, 3203, 192, 65109, 3385, 0, 64430, 5383, 10294, 10326, 128178, 5738, - 983215, 3336, 78355, 5361, 3623, 41159, 0, 68112, 7872, 8581, 0, 1260, - 3149, 5359, 120134, 0, 7914, 5357, 92170, 128659, 2624, 5364, 0, 11431, - 120030, 9101, 11058, 78288, 0, 78293, 42271, 78289, 42917, 120793, 0, - 65566, 6717, 10619, 43360, 78385, 78384, 11832, 78382, 78381, 78380, - 78379, 9319, 7097, 119055, 77906, 3232, 73824, 74581, 120632, 0, 0, - 41889, 92453, 0, 1161, 41895, 74103, 9701, 8622, 0, 0, 73819, 120588, - 5012, 77912, 41362, 69862, 78296, 11921, 0, 11769, 0, 68609, 41364, 0, - 74228, 41352, 41361, 0, 41366, 0, 3356, 11611, 917, 68422, 119915, 7134, - 8199, 78389, 119917, 677, 119916, 0, 119932, 127169, 0, 0, 0, 3349, - 74125, 7022, 8927, 4739, 0, 5802, 0, 8615, 0, 0, 491, 128819, 10190, - 120698, 65837, 128820, 8426, 11092, 9891, 0, 42497, 7113, 7586, 42305, - 10852, 0, 0, 4606, 68448, 9095, 7741, 12684, 41885, 1046, 7124, 0, 0, - 5815, 5171, 65539, 68612, 6932, 74267, 42394, 41878, 74849, 120621, 0, - 5169, 11935, 0, 0, 3175, 120822, 1537, 120804, 5176, 8905, 4136, 4871, - 78287, 0, 9833, 0, 0, 1128, 65920, 0, 9711, 7057, 9408, 9409, 9410, 9411, - 3662, 9413, 3378, 9415, 9416, 9417, 9418, 6320, 9420, 9421, 5897, 9423, - 5165, 5126, 41385, 0, 41389, 917938, 8955, 3374, 9400, 9401, 7119, 9403, - 9404, 3507, 9406, 7629, 983617, 19925, 42669, 68463, 183, 43985, 2631, 0, - 10627, 41130, 78260, 3996, 0, 78771, 0, 119313, 119307, 78768, 6580, - 4332, 64825, 66329, 10726, 66686, 41125, 5899, 41365, 917918, 12085, 0, - 574, 917922, 77825, 73828, 5448, 41058, 5446, 69709, 41322, 42211, 5442, - 4190, 77834, 77835, 5451, 77833, 3616, 77828, 77837, 77838, 7708, 77836, - 10859, 65867, 10345, 10409, 4191, 0, 77844, 73800, 42181, 77843, 77839, - 2060, 0, 7111, 11788, 65587, 68129, 10415, 74102, 0, 205, 0, 10351, - 119076, 0, 9862, 6588, 43257, 64697, 73998, 41355, 5505, 119154, 5503, - 8021, 0, 7125, 9819, 41357, 8011, 42885, 5507, 12044, 92636, 0, 10026, - 5472, 7109, 1191, 13106, 5470, 10329, 5476, 8991, 66322, 69778, 78267, - 42874, 8550, 42876, 5592, 2919, 0, 2675, 5595, 78411, 43762, 4367, 0, 0, - 5478, 5904, 5594, 0, 74150, 7291, 5590, 43761, 13067, 118909, 120372, - 983108, 9731, 69731, 64633, 77857, 77854, 77855, 77852, 77853, 77850, - 10750, 43714, 77858, 7137, 0, 128296, 12887, 10551, 194564, 77866, 77867, - 77864, 77865, 9929, 5199, 9936, 1120, 42387, 0, 1444, 9486, 7554, 65839, - 55252, 73972, 1442, 0, 5894, 70069, 0, 41171, 92511, 74313, 0, 13162, 0, - 3334, 195010, 118803, 77881, 66022, 0, 0, 1651, 128771, 8861, 0, 0, 1142, - 0, 8271, 0, 983058, 126645, 12903, 0, 4002, 43626, 10442, 10676, 3344, 0, - 0, 12920, 194560, 0, 0, 66642, 1277, 0, 7871, 0, 194686, 78853, 0, 78854, - 120360, 0, 11784, 0, 78012, 4700, 66366, 78858, 120359, 11012, 0, 78856, - 92400, 77879, 4973, 8784, 77877, 74804, 77874, 77869, 77871, 42440, 0, - 43118, 0, 42364, 6774, 6773, 917560, 120369, 10346, 10410, 78859, 9243, - 2464, 74263, 6108, 3372, 0, 6247, 43117, 74526, 7121, 74166, 0, 120355, - 92537, 0, 0, 195034, 0, 0, 0, 70083, 3354, 195037, 4192, 9289, 118999, - 41191, 3876, 0, 70067, 120660, 43696, 43380, 0, 983091, 0, 0, 11603, - 983954, 0, 6589, 128588, 194679, 0, 0, 983700, 0, 0, 42572, 128264, - 10630, 74827, 1963, 11622, 127098, 11654, 0, 7550, 10686, 5903, 0, 78009, - 41329, 9662, 917937, 64698, 3366, 10399, 0, 5542, 11013, 127927, 128300, - 0, 78621, 194672, 6925, 0, 0, 917929, 0, 11568, 983673, 43367, 64579, - 917930, 7852, 0, 0, 6754, 6312, 0, 64672, 65296, 0, 118957, 0, 416, - 12296, 68457, 73834, 68177, 11050, 10984, 92208, 0, 0, 92182, 0, 983605, - 9532, 66355, 0, 983234, 917925, 64343, 195032, 128281, 195031, 0, 195030, - 195057, 11445, 0, 2112, 195056, 128814, 10185, 1021, 128130, 9507, 10210, - 74544, 8023, 1200, 12243, 78001, 5282, 78003, 9624, 11545, 0, 120493, - 3343, 4424, 11047, 1885, 43268, 3896, 78444, 66497, 2947, 392, 7894, - 4391, 68139, 983062, 13059, 74816, 77998, 3381, 7942, 0, 69219, 0, 64757, - 0, 3913, 0, 0, 78235, 7044, 1265, 0, 6309, 7045, 7175, 7047, 78239, - 11791, 0, 0, 8221, 78307, 41864, 0, 0, 0, 0, 167, 983906, 78301, 983653, - 74211, 41897, 68477, 0, 917583, 983634, 94065, 2493, 0, 118811, 0, 0, - 64354, 0, 8777, 0, 406, 8884, 2385, 0, 92450, 0, 917573, 43030, 42027, - 12114, 0, 917579, 64936, 194695, 0, 120629, 10561, 0, 8365, 120539, - 983774, 65841, 120787, 11601, 0, 74121, 0, 917575, 7834, 74159, 0, - 917574, 10298, 6624, 4908, 917596, 1639, 0, 0, 74157, 6327, 6724, 0, - 128086, 92566, 69910, 4817, 78446, 194759, 92536, 7043, 9600, 11022, 0, - 0, 0, 0, 0, 0, 7548, 64794, 42050, 12291, 55289, 194761, 12343, 657, - 195054, 42705, 4461, 1134, 1838, 78438, 2057, 0, 4468, 0, 0, 0, 4456, - 5206, 10720, 0, 42523, 127520, 0, 0, 917595, 65550, 260, 4816, 67658, - 10687, 0, 4821, 4466, 0, 195043, 4818, 195048, 41403, 119977, 0, 0, - 41406, 43273, 74160, 119983, 73939, 92638, 119984, 119979, 41404, 1165, - 119980, 4451, 13087, 0, 11284, 119987, 70097, 65155, 43014, 5439, 9363, - 70070, 3375, 128869, 5900, 93990, 7889, 2722, 42262, 0, 0, 128774, 0, - 2282, 0, 127810, 11401, 983822, 0, 68459, 0, 0, 0, 0, 65438, 0, 7280, - 127887, 0, 127381, 4868, 8297, 119966, 118798, 0, 0, 43161, 0, 92360, 0, - 5182, 0, 120542, 0, 0, 4226, 119243, 12135, 5732, 4464, 0, 71330, 977, - 4458, 0, 0, 64770, 74838, 0, 344, 0, 194790, 1395, 64279, 0, 92240, 0, - 786, 0, 43174, 64340, 0, 194767, 120723, 43026, 7612, 10132, 64413, - 65025, 0, 0, 0, 93956, 0, 68444, 0, 92437, 0, 119160, 10204, 92656, 0, - 127809, 983644, 1399, 983652, 65217, 0, 8852, 128571, 241, 128780, 4907, - 0, 983639, 7932, 9727, 128873, 74255, 8748, 0, 0, 983643, 0, 42780, 0, 0, - 0, 4217, 0, 8650, 0, 0, 0, 69900, 118872, 43099, 3965, 119119, 6719, 0, - 13300, 78439, 93971, 43057, 66588, 118991, 0, 0, 73815, 4420, 0, 6410, - 7760, 0, 0, 0, 0, 0, 7294, 0, 0, 0, 9066, 0, 11993, 43188, 2626, 7762, 0, - 0, 0, 92601, 42825, 41854, 5304, 0, 78516, 6919, 8619, 119655, 10038, - 66454, 9592, 42851, 126993, 1542, 92303, 0, 0, 0, 0, 74311, 78497, 0, - 10181, 0, 43624, 0, 7779, 0, 10195, 9479, 6029, 0, 92268, 9689, 0, 65577, - 8993, 66358, 0, 42378, 3368, 606, 127030, 7697, 69237, 69787, 2030, 0, - 6027, 8370, 4322, 0, 65207, 0, 983339, 983338, 983337, 983336, 2735, - 42831, 77935, 127120, 74866, 8881, 119047, 0, 0, 73946, 0, 0, 0, 68140, - 983928, 9576, 128872, 3347, 4160, 5154, 55288, 3794, 66564, 8530, 127063, - 7709, 41112, 983132, 66560, 42041, 4572, 12876, 66561, 983758, 6758, - 983926, 1615, 5855, 809, 0, 92283, 128316, 128004, 5799, 983328, 70100, - 983326, 7260, 983324, 43031, 64425, 65128, 78819, 64386, 65257, 0, 68616, - 120607, 9347, 128067, 6532, 0, 0, 0, 127060, 65828, 0, 283, 68665, 78813, - 532, 78663, 0, 983796, 120609, 0, 3370, 0, 11361, 5443, 78778, 8153, - 73767, 0, 10741, 0, 2298, 0, 983917, 65495, 64706, 983318, 43344, 983316, - 7144, 9466, 78866, 9824, 983311, 983310, 0, 0, 915, 43425, 0, 0, 0, 0, - 127178, 43264, 70096, 0, 0, 43038, 78864, 6730, 78862, 68161, 64550, - 5186, 7360, 127837, 0, 12108, 0, 65124, 43127, 66043, 0, 6326, 43107, - 77826, 0, 42562, 0, 128821, 0, 128520, 11485, 6103, 127123, 983305, - 11718, 983303, 12889, 92657, 127137, 0, 0, 0, 55245, 0, 1630, 128232, - 65483, 0, 12565, 0, 65476, 120013, 0, 119554, 9283, 7700, 917537, 9690, - 65499, 0, 64593, 512, 3376, 68210, 0, 128677, 77892, 632, 12940, 77891, - 42529, 78587, 0, 5957, 110593, 8926, 983299, 983298, 128273, 10745, - 10174, 7379, 64581, 5386, 120686, 11713, 10633, 69708, 5056, 0, 0, 0, - 120773, 0, 9812, 0, 4460, 0, 0, 71307, 128038, 0, 0, 127174, 64278, - 92370, 43466, 0, 0, 64389, 2953, 73879, 1801, 12835, 119029, 0, 73823, 0, - 66375, 2085, 702, 42579, 77884, 77885, 13074, 77883, 983286, 983285, - 128570, 12106, 983282, 74207, 1755, 10482, 12863, 77898, 1163, 2951, - 9522, 74079, 78266, 66604, 0, 3384, 69227, 10702, 830, 77902, 77899, - 77900, 8451, 0, 0, 0, 69739, 0, 0, 0, 0, 2908, 0, 43386, 64902, 4243, 0, - 12239, 0, 0, 4441, 0, 983279, 73940, 64352, 127513, 983275, 411, 983273, - 9199, 983271, 4056, 118992, 41890, 0, 2730, 41604, 983937, 5428, 194743, - 3364, 42265, 64437, 127935, 118816, 194742, 9684, 216, 0, 1401, 128053, - 44012, 0, 0, 92585, 9158, 77842, 69905, 5768, 0, 0, 0, 484, 194739, 0, 0, - 65895, 0, 0, 3338, 73935, 572, 7041, 2736, 67605, 983263, 93962, 2794, - 8807, 64491, 77847, 5438, 5222, 5381, 43114, 0, 5193, 5125, 5456, 5509, - 77846, 194747, 9534, 0, 0, 0, 3430, 0, 0, 78717, 0, 981, 0, 4330, 73929, - 120536, 1824, 10908, 0, 7034, 41683, 64617, 0, 73754, 3957, 64358, 64547, - 128259, 674, 63991, 983249, 2946, 5354, 5251, 5328, 5307, 3759, 11411, - 8364, 5123, 119628, 5281, 5469, 5121, 119245, 118993, 0, 5130, 0, 0, - 77990, 0, 120726, 1221, 2733, 11746, 77991, 5216, 0, 0, 0, 0, 3468, 7033, - 9230, 5939, 195052, 0, 0, 120677, 68400, 7278, 10321, 10289, 64613, - 10385, 41706, 0, 0, 983413, 0, 11739, 983426, 41981, 0, 5938, 0, 43766, - 12448, 7576, 10401, 10337, 73852, 0, 13057, 0, 126976, 0, 10009, 0, - 41703, 983638, 12165, 0, 0, 9885, 0, 8077, 0, 127908, 0, 0, 0, 92457, 0, - 4220, 10725, 10433, 0, 68395, 4987, 64519, 0, 128340, 0, 0, 0, 10970, - 11733, 0, 120792, 0, 19944, 0, 9009, 8551, 92345, 11468, 64636, 7575, 0, - 2724, 0, 0, 12313, 110592, 515, 119947, 42791, 63987, 78286, 119943, - 119940, 119941, 119938, 9775, 4046, 4589, 4521, 68629, 9141, 0, 78850, - 2741, 64399, 6197, 1370, 0, 0, 0, 0, 0, 0, 6184, 8606, 3303, 41372, - 11786, 9473, 66203, 66177, 92446, 11593, 43007, 4478, 66178, 0, 0, 2744, - 0, 4477, 118964, 814, 42066, 66183, 66204, 43786, 119961, 66198, 41880, - 66188, 11623, 78148, 11955, 66190, 66191, 41111, 66189, 73788, 7788, - 4847, 0, 127759, 0, 0, 0, 1581, 6535, 78161, 12954, 430, 78160, 55259, - 78158, 128036, 5278, 4945, 42883, 4950, 983438, 68625, 983436, 7269, 0, - 5964, 12908, 983555, 0, 74764, 74477, 119146, 194936, 4949, 983429, 443, - 983427, 4944, 5467, 119603, 983254, 65137, 6044, 65392, 0, 4213, 0, - 41303, 0, 194931, 119962, 41306, 73984, 2698, 127159, 0, 12072, 3193, 0, - 41304, 824, 128676, 12091, 78893, 78894, 119816, 4673, 64804, 4678, - 119820, 119819, 65059, 0, 6739, 0, 5481, 3490, 1199, 119811, 8356, 69947, - 119832, 4677, 12688, 3102, 0, 4672, 78173, 78175, 5531, 68367, 42575, - 78170, 78166, 4674, 4548, 44005, 119949, 68658, 119946, 8025, 68630, - 127024, 1855, 983412, 68669, 983410, 92445, 127554, 0, 127339, 119652, - 2745, 11797, 983418, 128159, 9202, 4654, 983414, 983416, 68638, 73993, - 10525, 4649, 65209, 983417, 0, 4648, 43080, 983406, 983407, 983404, 6246, - 64950, 7828, 4650, 6777, 6776, 6775, 4653, 7822, 78005, 92384, 43187, - 8669, 983415, 6821, 65093, 0, 78881, 2716, 0, 983060, 983419, 0, 68369, - 120054, 11060, 8547, 2711, 42165, 78027, 78026, 7992, 0, 0, 4662, 78033, - 78032, 9149, 9146, 599, 2081, 78031, 78030, 194962, 4656, 10130, 68450, - 7811, 40994, 194965, 6414, 5967, 4658, 3725, 5713, 5814, 4661, 42434, - 983411, 0, 0, 64904, 9026, 10833, 74864, 7547, 4867, 0, 10008, 10222, - 3054, 194956, 9744, 78860, 7605, 4622, 119656, 983395, 94070, 983393, - 983394, 983391, 9045, 78888, 4225, 19926, 78887, 12880, 65307, 4617, - 78883, 983386, 41732, 4616, 10518, 10423, 10359, 983380, 5958, 0, 983433, - 4215, 9789, 917941, 4321, 4621, 983389, 41313, 522, 5368, 0, 65803, 0, - 5366, 12201, 5372, 0, 983409, 0, 7720, 7390, 2696, 983400, 0, 4638, - 983405, 1790, 78242, 5965, 64363, 66569, 68646, 127833, 5376, 1835, 5335, - 194966, 128089, 4633, 0, 68119, 1180, 4632, 128093, 5387, 5333, 0, 0, - 42094, 5331, 4634, 11928, 983594, 5338, 4637, 128170, 5971, 42414, 0, - 1268, 65097, 42361, 0, 0, 73853, 1427, 0, 0, 5970, 3431, 0, 10358, 10422, - 4758, 983374, 1608, 2738, 0, 10455, 4753, 74026, 11344, 4222, 6240, 5231, - 74384, 983378, 68377, 6248, 983362, 983363, 983360, 42318, 92582, 5229, - 4757, 0, 0, 2728, 4752, 64563, 65235, 5234, 0, 128145, 0, 10713, 7166, 0, - 2622, 7460, 127302, 0, 0, 8954, 74760, 65189, 2632, 42617, 10108, 1011, - 5574, 1853, 2709, 65139, 5577, 0, 0, 118871, 68641, 8965, 7635, 42177, - 5316, 0, 5314, 6451, 5572, 66464, 5312, 0, 5525, 5330, 5319, 983420, - 983872, 194907, 44003, 0, 983480, 983423, 120498, 127851, 195009, 983865, - 74022, 983422, 64609, 68643, 120634, 983489, 5721, 983401, 5519, 8632, - 66465, 11267, 73961, 92278, 5720, 983352, 1692, 4219, 4610, 8696, 4305, - 0, 4609, 43478, 4614, 541, 983355, 5287, 5309, 5285, 68389, 5961, 4647, - 56, 4216, 10577, 41381, 601, 4613, 983349, 983346, 77849, 4608, 64260, - 41124, 5190, 67628, 0, 68145, 7086, 0, 67998, 67620, 0, 2734, 11074, 0, - 67627, 43593, 0, 67625, 5960, 0, 8992, 42593, 128260, 1782, 67622, 68114, + 12603, 7131, 11108, 4566, 7518, 9317, 3801, 10342, 10406, 124938, 119259, + 42576, 0, 5200, 92946, 129142, 983895, 9183, 127361, 74458, 66282, 395, + 5482, 5198, 4349, 10390, 74202, 5196, 43224, 6113, 42009, 5205, 128383, + 43307, 128369, 118973, 70467, 12134, 0, 0, 118843, 9126, 435, 983624, + 12014, 10377, 8093, 9079, 3203, 192, 65109, 3385, 125075, 64430, 5383, + 10294, 10326, 127309, 5738, 983215, 3336, 78355, 5361, 3623, 41159, 0, + 68112, 7872, 8581, 0, 1260, 3149, 5359, 120134, 0, 7914, 5357, 71190, + 74339, 2624, 5364, 0, 11431, 120030, 9101, 11058, 78288, 67107, 78293, + 42271, 78289, 42917, 67111, 129179, 65566, 6717, 10619, 43360, 78385, + 78384, 11832, 78382, 78381, 78380, 69861, 9319, 7097, 119055, 77906, + 3232, 73824, 74581, 78087, 0, 71205, 41889, 92453, 0, 1161, 41895, 74103, + 9701, 8622, 125025, 0, 73819, 120588, 5012, 77912, 41362, 69862, 68507, + 11921, 0, 11769, 128477, 68609, 41364, 0, 74228, 41352, 41361, 0, 41366, + 0, 3356, 11611, 917, 68422, 119915, 7134, 8199, 78389, 119618, 677, + 119916, 917876, 119932, 127169, 0, 0, 125136, 3349, 74125, 7022, 8927, + 4739, 92599, 5802, 194874, 8615, 0, 0, 491, 74401, 10190, 120698, 65837, + 119900, 8426, 11092, 9891, 0, 42497, 7113, 7586, 42305, 10852, 0, 42648, + 4606, 68448, 9095, 7741, 12684, 41885, 1046, 7124, 128610, 0, 5815, 5171, + 65539, 68612, 6932, 74267, 42394, 41878, 74849, 120621, 72424, 5169, + 11935, 0, 0, 3175, 120822, 1537, 120804, 5176, 8905, 4136, 4871, 78287, + 120663, 9833, 0, 983341, 1128, 65920, 0, 9711, 7057, 9408, 9409, 9410, + 9411, 3662, 9413, 3378, 9415, 9416, 9417, 9418, 6320, 9420, 9421, 5897, + 9423, 5165, 5126, 41385, 0, 41389, 127963, 8955, 3374, 9400, 9401, 7119, + 9403, 9404, 3507, 9406, 7629, 983617, 19925, 42669, 68463, 183, 43985, + 2631, 70811, 10627, 41130, 78260, 3996, 0, 78771, 0, 119313, 119307, + 78768, 6580, 4332, 64825, 66329, 10726, 66686, 41125, 5899, 41365, + 127206, 12085, 66902, 574, 126705, 77825, 73828, 5448, 41058, 5446, + 65932, 41322, 42211, 5442, 4190, 77834, 77835, 5451, 77833, 3616, 77828, + 77837, 77838, 7708, 77836, 10859, 65867, 10345, 10409, 4191, 120378, + 77844, 73800, 42181, 77843, 77839, 2060, 0, 7111, 11788, 65376, 68129, + 10415, 74102, 0, 205, 0, 10351, 67151, 0, 9862, 6588, 43257, 64697, + 73998, 41355, 5505, 119154, 5503, 8021, 128035, 7125, 9819, 41357, 8011, + 42885, 5507, 12044, 92636, 0, 10026, 5472, 7109, 1191, 13106, 5470, + 10329, 5476, 8991, 66322, 69778, 11133, 42874, 8550, 42876, 5592, 2919, + 0, 2675, 5595, 78411, 43762, 4367, 127912, 0, 5478, 5904, 5594, 0, 74150, + 7291, 5590, 43761, 13067, 118909, 120372, 983108, 9731, 69731, 64633, + 77857, 77854, 71217, 77852, 71227, 77850, 10750, 43714, 77858, 7137, 0, + 66909, 12887, 10551, 194564, 77866, 77867, 77864, 77865, 9929, 5199, + 9936, 1120, 42387, 0, 1444, 9486, 7554, 65839, 55252, 73972, 1442, + 129080, 5894, 70069, 128672, 41171, 92511, 70358, 1323, 13162, 0, 3334, + 195010, 118803, 77881, 66022, 0, 69770, 1651, 128771, 8861, 0, 0, 1142, + 983869, 8271, 0, 983058, 126645, 12903, 0, 4002, 43626, 10442, 10676, + 3344, 128910, 194787, 12920, 194560, 70497, 194687, 66642, 1277, 66876, + 7871, 67106, 194686, 78853, 129068, 78854, 120360, 983490, 11784, 0, + 78012, 4700, 43856, 78858, 120359, 11012, 0, 78856, 92400, 77879, 4973, + 8784, 77877, 74804, 77874, 77869, 77871, 42440, 71225, 43118, 0, 42364, + 6774, 6773, 917560, 120369, 10346, 10410, 78859, 9243, 2464, 74263, 6108, + 3372, 0, 6247, 43117, 70364, 7121, 74166, 124973, 120355, 92537, 195035, + 0, 195034, 70357, 119922, 0, 67119, 3354, 195037, 4192, 9289, 118999, + 41191, 3876, 0, 70067, 120660, 43696, 43380, 0, 983091, 0, 983758, 11603, + 983954, 0, 6589, 128564, 194679, 128961, 0, 983700, 0, 129087, 42572, + 128264, 10630, 74827, 1963, 11622, 127098, 11654, 0, 7550, 10686, 5903, + 67098, 78009, 41329, 9662, 917937, 64698, 3366, 10399, 917938, 5542, + 11013, 127927, 71062, 194677, 78621, 67090, 6925, 0, 0, 92892, 71856, + 11568, 983673, 43367, 64579, 917930, 7852, 11138, 0, 6754, 6312, 77956, + 64672, 65296, 0, 118957, 0, 416, 12296, 68457, 73834, 68177, 11050, + 10984, 92208, 0, 0, 92182, 0, 983605, 9532, 66355, 0, 983234, 917925, + 64343, 195032, 92744, 195031, 0, 195030, 195057, 11445, 68294, 2112, + 128741, 128814, 10185, 1021, 128130, 9507, 10210, 74544, 8023, 1200, + 12243, 78001, 5282, 78003, 9624, 11545, 0, 120493, 3343, 4424, 11047, + 1885, 43268, 3896, 78444, 66497, 2947, 392, 7894, 4391, 68139, 983062, + 13059, 74816, 77998, 3381, 7942, 0, 69219, 0, 3558, 0, 3913, 70429, 0, + 78235, 7044, 1265, 0, 6309, 7045, 7175, 7047, 78239, 11791, 0, 917587, + 8221, 78307, 41864, 0, 0, 67075, 71219, 167, 983906, 78301, 983653, + 74211, 41897, 67072, 0, 917583, 917594, 67076, 2493, 0, 113778, 0, 92331, + 64354, 0, 8777, 0, 406, 8884, 2385, 78210, 92450, 0, 917573, 43030, + 42027, 12114, 0, 128597, 64936, 194695, 0, 120629, 10561, 128940, 8365, + 120539, 983774, 65841, 120787, 11601, 0, 74121, 128896, 917575, 7834, + 74159, 0, 917574, 10298, 6624, 4908, 917596, 1639, 0, 0, 70803, 6327, + 6724, 124953, 128086, 92566, 69910, 4817, 11087, 194759, 92536, 7043, + 9600, 11022, 0, 0, 0, 0, 0, 73954, 7548, 64794, 42050, 12291, 55289, + 128781, 12343, 657, 67110, 42705, 4461, 1134, 1838, 78438, 2057, 0, 4468, + 92891, 194945, 0, 4456, 5206, 10720, 0, 42523, 127520, 0, 93044, 917595, + 65550, 260, 4816, 67658, 10687, 0, 4821, 4466, 0, 195043, 4818, 129058, + 41403, 119977, 72422, 128458, 41406, 43273, 74160, 69805, 73939, 92638, + 119984, 119979, 41404, 1165, 119980, 4451, 13087, 0, 11284, 119987, + 70097, 65155, 43014, 5439, 9363, 70070, 3375, 128448, 5900, 93990, 7889, + 2722, 42262, 0, 0, 67078, 128451, 2282, 0, 127810, 11401, 67079, 0, + 68459, 125028, 983141, 0, 70150, 65438, 0, 7280, 127887, 0, 70146, 4868, + 8297, 119966, 70148, 0, 128744, 43161, 70144, 92360, 0, 5182, 0, 120542, + 0, 0, 4226, 70186, 12135, 5732, 4464, 0, 71330, 977, 4458, 43827, 92971, + 64770, 74838, 0, 344, 0, 194790, 1395, 64279, 0, 92240, 0, 786, 126995, + 43174, 64340, 0, 194767, 73971, 43026, 7612, 10132, 64413, 65025, 0, 0, + 0, 93956, 0, 68444, 0, 92437, 0, 119160, 10204, 92656, 0, 127809, 128431, + 1399, 983652, 65217, 983637, 8852, 128571, 241, 128780, 4907, 128427, + 983639, 7932, 9727, 128463, 74255, 8748, 0, 0, 983631, 0, 42780, 0, + 113677, 0, 4217, 93034, 8650, 0, 120673, 0, 69900, 118872, 43099, 3965, + 119119, 6719, 128007, 13300, 78439, 93971, 43057, 66588, 118991, 66289, + 0, 73815, 4420, 983120, 6410, 7760, 0, 70468, 128752, 120684, 0, 7294, 0, + 43869, 125032, 9066, 0, 11993, 43188, 2626, 7762, 0, 118831, 92899, + 92601, 42825, 41854, 5304, 0, 78516, 6919, 8619, 119655, 10038, 66454, + 9592, 42851, 126993, 1542, 92303, 128819, 0, 127327, 983597, 74311, + 78497, 0, 10181, 124937, 43624, 129060, 7779, 917551, 10195, 9479, 6029, + 128374, 92268, 2224, 0, 65577, 8993, 66358, 0, 42378, 3368, 606, 127030, + 7697, 69237, 69787, 2030, 70106, 6027, 8370, 4322, 0, 65207, 0, 70386, + 127903, 983337, 983336, 2735, 42831, 77935, 70439, 74866, 8881, 119047, + 0, 70433, 73946, 0, 0, 0, 68140, 983928, 9576, 92783, 3347, 4160, 5154, + 55288, 3794, 66564, 8530, 127063, 7709, 41112, 983132, 66560, 8381, 4572, + 12876, 66561, 128921, 6758, 983926, 1615, 5855, 809, 0, 92283, 128316, + 128004, 5799, 128929, 70100, 128607, 7260, 983324, 43031, 64425, 65128, + 78819, 64386, 65257, 0, 68616, 120607, 9347, 128067, 6532, 0, 917918, 0, + 127060, 65828, 120006, 283, 68665, 78813, 532, 78663, 78817, 128021, + 120609, 0, 3370, 0, 11361, 5443, 78778, 8153, 73767, 0, 10741, 0, 2298, + 0, 125039, 65495, 64706, 983318, 43344, 983316, 7144, 9466, 78866, 9824, + 67142, 128963, 67133, 67130, 915, 43425, 67292, 43865, 68232, 0, 127178, + 43264, 67136, 67137, 0, 43038, 78864, 6730, 78862, 68161, 64550, 5186, + 7360, 127837, 70451, 12108, 0, 65124, 43127, 66043, 0, 6326, 43107, + 77826, 0, 42562, 0, 128821, 128178, 128520, 11485, 6103, 92468, 983305, + 11718, 983303, 12889, 92657, 125034, 0, 0, 127476, 55245, 128927, 1630, + 128232, 65483, 120634, 12565, 0, 65476, 70369, 983072, 119214, 9283, + 7700, 917537, 9690, 65499, 0, 64593, 512, 3376, 68210, 0, 128253, 77892, + 632, 12940, 77891, 42529, 78587, 194604, 5957, 110593, 8926, 983299, + 983298, 128273, 10745, 10174, 7379, 64581, 5386, 120686, 11713, 10633, + 69708, 5056, 0, 0, 0, 120773, 94055, 9812, 0, 4460, 0, 124956, 71307, + 128038, 0, 0, 127174, 64278, 92370, 43466, 0, 0, 64389, 2953, 70122, + 1801, 12835, 74847, 0, 73823, 128681, 66375, 2085, 702, 42579, 77884, + 77885, 13074, 77883, 66299, 983285, 128570, 12106, 983282, 74207, 1755, + 10482, 12863, 77898, 1163, 2951, 9522, 74079, 78266, 66604, 0, 3384, + 69227, 10702, 830, 77902, 77899, 77900, 8451, 0, 0, 0, 66458, 128957, + 128870, 0, 0, 2908, 0, 11177, 64902, 4243, 92454, 12239, 917872, 124959, + 4441, 0, 113765, 73940, 64352, 127513, 125031, 411, 983273, 9199, 983271, + 4056, 118992, 41890, 194698, 2730, 41604, 128355, 5428, 194743, 3364, + 42265, 64437, 127935, 118816, 194742, 9684, 216, 71367, 1401, 128053, + 44012, 92628, 0, 92585, 9158, 66878, 11126, 5768, 0, 0, 0, 484, 194739, + 0, 0, 65895, 125076, 0, 3338, 73935, 572, 7041, 2736, 67605, 983263, + 93962, 2794, 8807, 64491, 77847, 5438, 5222, 5381, 43114, 0, 5193, 5125, + 5456, 5509, 77846, 194747, 9534, 129109, 129040, 0, 3430, 0, 42905, + 78717, 128903, 981, 129184, 4330, 73929, 120536, 1824, 10908, 126506, + 7034, 41683, 64617, 0, 73754, 3957, 64358, 64547, 128259, 674, 63991, + 983249, 2946, 5354, 5251, 5328, 5307, 3759, 11411, 8364, 5123, 119628, + 5281, 5469, 5121, 119245, 118993, 0, 5130, 0, 0, 77990, 0, 120726, 1221, + 2733, 11746, 77991, 5216, 0, 0, 0, 92187, 3468, 7033, 9230, 5939, 195052, + 0, 5803, 71867, 68400, 7278, 10321, 10289, 64613, 10385, 41706, 0, 0, + 983413, 0, 11739, 92524, 41981, 92743, 5938, 0, 43766, 12448, 7576, + 10401, 10337, 73852, 124994, 13057, 0, 126976, 0, 10009, 0, 41703, + 983638, 12165, 129191, 0, 9885, 0, 8077, 92620, 127908, 0, 983439, 0, + 92457, 129138, 4220, 10725, 10433, 0, 68395, 4987, 64519, 0, 125078, 0, + 983426, 128574, 10970, 11733, 0, 120792, 126490, 19944, 74356, 9009, + 8551, 92345, 11468, 64636, 7575, 0, 2724, 128899, 0, 12313, 11151, 515, + 119947, 42791, 63987, 78286, 119943, 119940, 119941, 119938, 9775, 4046, + 4589, 4521, 68629, 9141, 0, 78850, 2741, 64399, 6197, 1370, 0, 0, 0, 0, + 0, 983560, 6184, 8606, 3303, 41372, 11786, 9473, 66203, 66177, 92446, + 11593, 43007, 4478, 66178, 0, 0, 2744, 0, 4477, 78267, 814, 42066, 66183, + 66204, 43786, 119961, 66198, 41880, 66188, 11623, 78148, 11955, 66190, + 66191, 41111, 66189, 73788, 7788, 4847, 0, 127759, 0, 128433, 2221, 1581, + 6535, 78161, 12954, 430, 78160, 55259, 73944, 128036, 5278, 4945, 42883, + 4950, 983438, 68625, 983436, 7269, 0, 5964, 12908, 124997, 0, 74764, + 43512, 119146, 194936, 4949, 983429, 443, 983427, 4944, 5467, 119603, + 70865, 65137, 6044, 65392, 0, 4213, 0, 41303, 0, 194931, 119962, 41306, + 73984, 2698, 127159, 0, 12072, 3193, 0, 41304, 824, 128676, 12091, 67118, + 78894, 119816, 4673, 64804, 4678, 119820, 119819, 65059, 43860, 6739, + 66844, 5481, 3490, 1199, 119811, 8356, 69947, 67702, 4677, 12688, 3102, + 0, 4672, 78173, 78175, 5531, 68367, 42575, 78170, 78166, 4674, 4548, + 44005, 71087, 68658, 119946, 8025, 68630, 127024, 1855, 983412, 68669, + 983410, 92445, 127554, 983417, 127339, 119652, 2745, 11797, 983418, + 128159, 9202, 4654, 6840, 983414, 68638, 73993, 10525, 4649, 65209, + 983416, 0, 4648, 43080, 983406, 983407, 983404, 6246, 64950, 7828, 4650, + 6777, 6776, 6775, 4653, 7822, 78005, 74624, 43187, 8669, 120659, 6821, + 65093, 0, 78881, 2716, 0, 983060, 70503, 194952, 68369, 120054, 11060, + 8547, 2711, 42165, 78027, 78026, 6836, 983421, 0, 4662, 78033, 78032, + 9149, 9146, 599, 2081, 78031, 78030, 194962, 4656, 10130, 68450, 7811, + 40994, 194965, 6414, 5967, 4658, 3725, 5713, 5814, 4661, 42434, 983411, + 128737, 11190, 64904, 9026, 10833, 74864, 7547, 4867, 11100, 10008, + 10222, 3054, 194956, 9744, 78860, 7605, 4622, 119656, 983395, 94070, + 983393, 69905, 67188, 9045, 78888, 4225, 19926, 78887, 12880, 65307, + 4617, 78883, 983386, 41732, 4616, 10518, 10423, 10359, 983380, 5958, 0, + 983433, 4215, 9789, 119619, 4321, 4621, 983389, 41313, 522, 5368, 11139, + 65803, 0, 5366, 12201, 5372, 0, 983409, 194975, 7720, 7390, 2696, 983400, + 0, 4638, 983405, 1790, 78242, 5965, 64363, 66569, 68646, 68477, 5376, + 1835, 5335, 194966, 128089, 4633, 0, 68119, 1180, 4632, 67191, 5387, + 5333, 0, 125132, 42094, 5331, 4634, 11928, 983594, 5338, 4637, 128170, + 5971, 42414, 43500, 1268, 65097, 42361, 0, 0, 73853, 1427, 128440, 0, + 5970, 3431, 0, 10358, 10422, 4758, 983374, 1608, 2738, 125066, 10455, + 4753, 74026, 11344, 4222, 6240, 5231, 74384, 983378, 68377, 6248, 983362, + 128432, 983360, 42318, 92582, 5229, 4757, 0, 0, 2728, 4752, 64563, 65235, + 5234, 0, 128145, 128926, 10713, 7166, 0, 2622, 7460, 127302, 67101, + 126495, 8954, 74760, 65189, 2632, 42617, 10108, 1011, 5574, 1853, 2709, + 65139, 5577, 128966, 0, 118871, 68641, 8965, 7635, 42177, 5316, 0, 5314, + 6451, 5572, 66464, 5312, 0, 5525, 5330, 5319, 68292, 127311, 65066, + 44003, 120650, 983480, 43843, 120498, 127851, 195009, 74851, 74022, + 983422, 64609, 68643, 67410, 128593, 5721, 983401, 5519, 8632, 66465, + 11267, 73961, 92278, 5720, 983352, 1692, 4219, 4610, 8696, 4305, 0, 4609, + 43478, 4614, 541, 983355, 5287, 5309, 5285, 68389, 5961, 4647, 56, 4216, + 10577, 41381, 601, 4613, 983349, 983346, 9208, 4608, 64260, 41124, 5190, + 67628, 66826, 68145, 7086, 0, 67998, 67620, 93047, 2734, 11074, 0, 67627, + 43593, 0, 67625, 5960, 67722, 8992, 42593, 128260, 1782, 67622, 68114, 119939, 0, 68180, 5501, 119952, 42508, 7442, 43665, 359, 41253, 68392, - 6239, 119956, 41256, 0, 68134, 0, 74209, 917550, 9346, 69660, 41254, + 6239, 119956, 41256, 74132, 67740, 0, 71178, 917550, 9346, 69660, 41254, 128047, 43291, 3767, 5737, 0, 4865, 0, 5740, 917997, 5736, 4368, 64724, - 7193, 68137, 0, 5739, 41024, 4866, 0, 73904, 983840, 4869, 120563, 0, - 4223, 128201, 6650, 126509, 0, 983463, 127890, 4870, 120445, 68661, 6716, - 78176, 68667, 68382, 68676, 127925, 10122, 4864, 66568, 4144, 7937, 0, - 6245, 68652, 2732, 42734, 745, 0, 195097, 92195, 4777, 7821, 0, 68631, - 42775, 0, 194954, 0, 3097, 0, 5966, 983486, 4778, 0, 10863, 0, 4781, 0, - 64407, 0, 128323, 8577, 128562, 68196, 43285, 10216, 4782, 0, 0, 120757, - 68618, 12325, 43056, 8717, 0, 0, 4776, 73818, 11492, 8700, 0, 13176, - 68363, 10426, 0, 917599, 10362, 194706, 1715, 4849, 8242, 9561, 73922, - 43278, 42635, 0, 0, 5963, 917926, 0, 0, 4850, 0, 1607, 466, 4853, 118995, - 4854, 127918, 5164, 983870, 1350, 5124, 64420, 1993, 5362, 8471, 2708, - 92471, 12445, 3785, 234, 3199, 0, 41268, 4848, 2530, 917909, 2068, 1964, - 0, 73762, 10458, 0, 8576, 78543, 0, 2704, 4794, 0, 68211, 8322, 4797, - 5753, 0, 2694, 4792, 0, 2439, 65104, 69804, 983424, 303, 983101, 92622, - 983425, 2437, 0, 4221, 4844, 92216, 0, 0, 0, 70042, 0, 43292, 0, 2441, - 10739, 65090, 0, 119327, 126541, 2451, 2714, 119326, 0, 43379, 4937, - 43376, 753, 5849, 10597, 43089, 11722, 9248, 92555, 42879, 11725, 0, 0, - 2726, 3107, 73958, 4941, 64937, 119233, 9140, 1408, 5261, 4607, 0, 181, - 983430, 4942, 9539, 4938, 0, 65201, 5259, 9369, 64185, 4142, 5257, - 983601, 0, 4964, 5264, 64178, 64177, 12979, 41411, 64182, 64181, 64180, - 64179, 9482, 4873, 41231, 1822, 42526, 128581, 12758, 3865, 0, 0, 10500, - 0, 119024, 78028, 92408, 9830, 43642, 389, 10893, 7521, 127879, 4872, - 5463, 0, 3125, 9567, 0, 4878, 5459, 4604, 917931, 9557, 5465, 68617, 0, - 11494, 126492, 9563, 10865, 74570, 43279, 64186, 983439, 78714, 64191, - 64190, 8898, 64188, 0, 41030, 78836, 0, 917835, 78820, 917834, 0, 78805, + 7193, 67097, 128844, 5739, 41024, 4866, 0, 73904, 983840, 4869, 120563, + 0, 4223, 128201, 6650, 126509, 0, 983463, 127890, 4870, 120445, 68661, + 6716, 78176, 68667, 68382, 68676, 127925, 10122, 4864, 66568, 4144, 7937, + 0, 6245, 68652, 2732, 42734, 745, 0, 195097, 92195, 4777, 7821, 129136, + 68631, 42775, 0, 128445, 0, 3097, 0, 5966, 983486, 4778, 0, 10863, 0, + 4781, 92986, 64407, 128503, 128323, 8577, 71221, 68196, 43285, 10216, + 4782, 0, 0, 120757, 68618, 12325, 43056, 8717, 0, 0, 4776, 73818, 11492, + 8700, 983955, 13176, 68363, 10426, 67247, 71091, 10362, 194706, 1715, + 4849, 8242, 9561, 73922, 43278, 42635, 0, 127207, 5963, 917926, 983481, + 0, 4850, 73900, 1607, 466, 4853, 118995, 4854, 127918, 5164, 73807, 1350, + 5124, 64420, 1993, 5362, 8471, 2708, 92471, 12445, 3785, 234, 3199, + 128768, 41268, 4848, 2530, 194711, 2068, 1964, 0, 73762, 10458, 983415, + 8576, 78543, 0, 2704, 4794, 0, 68211, 8322, 4797, 5753, 0, 2694, 4792, 0, + 2439, 65104, 69804, 983424, 303, 74625, 68229, 983425, 2437, 78659, 4221, + 4844, 92216, 0, 0, 0, 70042, 74095, 43292, 0, 2441, 10739, 65090, 0, + 70436, 118929, 2451, 2714, 119326, 0, 43379, 4937, 43376, 753, 5849, + 10597, 43089, 11722, 9248, 92555, 42879, 11725, 0, 0, 2726, 3107, 73958, + 4941, 64937, 119233, 9140, 1408, 5261, 4607, 0, 181, 983430, 4942, 9539, + 4938, 0, 65201, 5259, 9369, 64185, 4142, 5257, 983601, 6844, 4964, 5264, + 64178, 64177, 12979, 41411, 64182, 64181, 64180, 64179, 9482, 4873, + 41231, 1822, 42526, 127989, 12758, 3865, 0, 128473, 10500, 0, 119024, + 78028, 92408, 9830, 43642, 389, 10893, 7521, 127879, 4872, 5463, 128119, + 3125, 9567, 0, 4878, 5459, 4604, 917931, 9557, 5465, 68617, 0, 11494, + 126492, 9563, 10865, 74570, 43279, 64186, 68521, 78714, 64191, 64190, + 8898, 64188, 129153, 41030, 74226, 0, 74600, 78820, 917834, 0, 78805, 41031, 78801, 11960, 6745, 3082, 983437, 78539, 73919, 10573, 41744, - 7079, 5856, 127043, 5163, 78809, 128162, 1817, 66724, 78538, 0, 10564, - 7763, 13077, 41813, 4400, 41745, 64207, 10275, 8925, 10371, 10307, 41814, - 4248, 0, 0, 4541, 6299, 64204, 64203, 64201, 64200, 64199, 64198, 126471, - 42156, 78688, 0, 64193, 64192, 65223, 9943, 64197, 64196, 64195, 64194, - 13282, 64175, 64174, 64173, 78189, 846, 78186, 9965, 0, 0, 0, 0, 2543, - 12163, 3108, 9745, 64167, 64166, 64165, 64164, 2110, 92176, 64169, 64168, - 64949, 10972, 10251, 10247, 42768, 715, 2295, 43299, 9453, 5348, 10943, - 120378, 0, 11352, 550, 9910, 126705, 0, 66579, 11551, 0, 195080, 9504, - 7187, 0, 10373, 0, 120791, 10261, 10253, 6404, 10277, 78183, 11984, 1552, - 65222, 6998, 78180, 0, 3128, 4789, 5067, 5066, 118849, 4784, 0, 8827, - 1146, 5065, 69890, 78192, 68136, 78190, 43412, 5064, 2431, 0, 9450, 1809, - 0, 78200, 78201, 5062, 1264, 64817, 13254, 11697, 126598, 9785, 64716, 0, - 3933, 74559, 4740, 7954, 0, 0, 42609, 0, 74175, 0, 127016, 0, 983873, - 42130, 0, 5151, 917829, 917823, 0, 93980, 0, 7620, 3800, 65122, 0, 0, - 8355, 7854, 0, 954, 64927, 4185, 41045, 127141, 41438, 41439, 68666, - 10711, 4593, 127745, 120584, 983408, 64774, 8053, 10532, 66727, 0, 0, 0, - 64759, 6381, 5166, 9888, 127800, 5148, 42834, 0, 78205, 78206, 43787, - 78204, 64131, 3119, 917814, 0, 3060, 64135, 9986, 0, 77876, 636, 11698, - 0, 983451, 9916, 11701, 7836, 42741, 64137, 8320, 78640, 8863, 92431, - 119960, 1477, 43289, 0, 74358, 8618, 983402, 9908, 983981, 0, 0, 3937, - 12312, 0, 983403, 0, 64781, 912, 6349, 4536, 93954, 74532, 126594, 6244, - 92209, 71341, 3935, 120665, 983476, 0, 11950, 5392, 42248, 65129, 68656, - 5397, 0, 12046, 12599, 0, 128261, 5395, 0, 5393, 354, 68615, 119948, - 78503, 0, 0, 42039, 0, 0, 64142, 626, 0, 5895, 0, 0, 5780, 0, 0, 128874, - 0, 0, 43297, 983079, 4311, 4644, 8818, 0, 128186, 0, 7145, 3918, 66452, - 3797, 1644, 92346, 9658, 4140, 11385, 65947, 6455, 9030, 813, 119945, - 68131, 4146, 119957, 5360, 2466, 0, 67669, 119942, 6249, 42117, 92287, - 128224, 0, 0, 74046, 43745, 4911, 988, 917807, 0, 983468, 43061, 7054, - 64147, 0, 64920, 68195, 6698, 118933, 92506, 0, 120006, 11981, 12202, 0, - 11032, 67654, 6093, 11608, 975, 68662, 65843, 170, 0, 0, 4169, 0, 41859, - 6058, 120401, 13203, 120657, 0, 0, 68657, 9818, 10178, 10324, 42106, - 5898, 74540, 4738, 41856, 7062, 917865, 4737, 11779, 4742, 120564, 92391, - 73736, 983364, 9825, 6448, 6715, 127008, 4831, 0, 92525, 0, 5300, 4741, - 42108, 983354, 64159, 4736, 64148, 0, 849, 92191, 78491, 43288, 0, 66620, - 917916, 127331, 65549, 9496, 64598, 118866, 983366, 7876, 68132, 917872, - 3928, 917870, 43378, 10706, 7198, 0, 4842, 12053, 128129, 0, 4841, 0, - 4171, 12008, 6251, 3923, 1490, 0, 119591, 126512, 40972, 5245, 0, 10114, - 42001, 41888, 4845, 8332, 40974, 64347, 4840, 9077, 78346, 1747, 917849, - 4825, 69240, 917852, 68655, 0, 983388, 0, 0, 68628, 983347, 9850, 118937, - 367, 1472, 917859, 6687, 1274, 0, 5905, 12339, 8919, 73953, 10907, 65261, - 11023, 119559, 4830, 9134, 78666, 64126, 43011, 0, 126626, 64101, 0, 0, - 4824, 10614, 119659, 0, 1888, 1960, 7861, 917856, 78524, 41836, 43012, - 6052, 6064, 54, 43009, 12214, 0, 6211, 0, 358, 41997, 41833, 11442, - 10758, 65774, 0, 120384, 64115, 92221, 70018, 0, 0, 119053, 0, 12765, - 64118, 126998, 12962, 0, 126580, 4017, 12827, 5241, 120392, 0, 41118, - 3924, 0, 11366, 917843, 0, 0, 917846, 41116, 917844, 917564, 0, 11363, - 12057, 11917, 1567, 74000, 4721, 126641, 66202, 8957, 4139, 0, 0, 0, 0, - 0, 12740, 128702, 4722, 6816, 127793, 12759, 4725, 983383, 4726, 0, - 194892, 983622, 128321, 917905, 0, 12755, 12762, 4015, 0, 8052, 476, 0, - 0, 128294, 64212, 41020, 1382, 64209, 64216, 44002, 64214, 1656, 41831, - 0, 0, 41843, 8720, 3908, 1452, 13111, 0, 64067, 127328, 8552, 64113, - 41845, 3849, 78732, 66232, 9778, 120066, 5891, 7064, 55, 9948, 119085, 0, - 0, 7935, 2420, 0, 1114, 92599, 67585, 70104, 120053, 92350, 120051, 3938, - 120057, 65417, 64717, 120060, 120061, 65415, 120059, 6292, 65303, 7955, - 6452, 4713, 128196, 66249, 917885, 917890, 917891, 65152, 719, 120044, + 7079, 5856, 127043, 5163, 78809, 128162, 1817, 66724, 78538, 119010, + 10564, 7763, 13077, 41813, 4400, 41745, 64207, 10275, 8925, 10371, 10307, + 41814, 4248, 0, 0, 4541, 6299, 64204, 64203, 64201, 64200, 64199, 64198, + 126471, 42156, 78688, 0, 64193, 64192, 65223, 9943, 64197, 64196, 64195, + 64194, 12231, 42652, 64174, 64173, 78189, 846, 78186, 9965, 74495, 0, + 917924, 0, 2543, 12163, 3108, 9745, 64167, 64166, 64165, 64164, 2110, + 92176, 64169, 64168, 64949, 10972, 10251, 10247, 42768, 715, 2295, 43299, + 9453, 5348, 10943, 66390, 0, 11352, 550, 9910, 125127, 0, 66579, 11551, + 128464, 195080, 9504, 7187, 0, 10373, 0, 120791, 10261, 10253, 6404, + 10277, 78183, 11984, 1552, 65222, 6998, 78180, 0, 3128, 4789, 5067, 5066, + 118849, 4784, 0, 8827, 1146, 5065, 69890, 78192, 68136, 78190, 43412, + 5064, 2431, 0, 9450, 1809, 0, 78200, 78201, 5062, 1264, 64817, 13254, + 11697, 126598, 9785, 64716, 0, 3933, 74559, 4740, 7954, 0, 125023, 42609, + 128388, 74175, 66912, 127016, 0, 983873, 42130, 983223, 5151, 917829, + 917823, 0, 93980, 0, 7620, 3800, 65122, 0, 127792, 8355, 7854, 0, 954, + 64927, 4185, 41045, 127141, 41438, 41439, 68666, 10711, 4593, 127745, + 120584, 983408, 64774, 8053, 10532, 66727, 0, 0, 78642, 64759, 1325, + 5166, 9888, 127800, 5148, 42834, 0, 78205, 78206, 43787, 78204, 64131, + 3119, 917814, 0, 3060, 64135, 9986, 0, 77876, 636, 11698, 0, 917810, + 9916, 11701, 7836, 42741, 64137, 8320, 78640, 8863, 70201, 119960, 1477, + 43289, 68492, 67164, 8618, 983402, 9908, 983981, 0, 0, 3937, 12312, 0, + 983403, 0, 64781, 912, 6349, 4536, 93954, 74532, 126594, 6244, 92209, + 71341, 3935, 120665, 983476, 0, 11950, 5392, 42248, 65129, 68656, 5397, + 128310, 12046, 12599, 67407, 128261, 5395, 0, 5393, 354, 68615, 77853, + 74366, 0, 0, 42039, 113817, 0, 64142, 626, 0, 5895, 0, 0, 5780, 0, 66407, + 128874, 0, 0, 43297, 70188, 4311, 4644, 8818, 78158, 128186, 0, 7145, + 3918, 66452, 3797, 1644, 92346, 9658, 4140, 11385, 65947, 6455, 9030, + 813, 119945, 68131, 4146, 119957, 5360, 2466, 0, 67669, 119942, 6249, + 42117, 92287, 92206, 0, 119255, 74046, 43745, 4911, 988, 71180, 0, + 983468, 43061, 7054, 64147, 0, 64920, 68195, 6698, 118933, 92506, 0, + 70849, 11981, 12202, 0, 11032, 67654, 6093, 11608, 975, 66415, 65843, + 170, 0, 67239, 4169, 0, 41859, 6058, 120401, 13203, 120657, 70507, + 125091, 68657, 9818, 10178, 10324, 42106, 5898, 74540, 4738, 41856, 7062, + 127120, 4737, 11779, 4742, 120564, 92391, 68342, 983364, 9825, 6448, + 6715, 127008, 4831, 983363, 92525, 67731, 5300, 4741, 42108, 983354, + 64159, 4736, 64148, 0, 849, 92191, 78491, 43288, 0, 66620, 127533, + 127331, 65549, 9496, 64598, 118866, 983366, 7876, 68132, 66280, 3928, + 917870, 43378, 10706, 7198, 0, 4842, 12053, 128129, 127303, 4841, 0, + 4171, 12008, 6251, 3923, 1490, 0, 119591, 126512, 40972, 5245, 70794, + 10114, 42001, 41888, 4845, 8332, 40974, 64347, 4840, 9077, 78346, 1747, + 917849, 4825, 69240, 917852, 68655, 0, 983388, 0, 0, 68628, 983347, 9850, + 118937, 367, 1472, 917859, 6687, 1274, 0, 5905, 12339, 8919, 73953, + 10907, 65261, 11023, 119559, 4830, 9134, 78666, 64126, 43011, 0, 78669, + 64101, 0, 0, 4824, 10614, 119659, 0, 1888, 1960, 7861, 917856, 78524, + 41836, 43012, 6052, 6064, 54, 43009, 12214, 0, 6211, 120386, 358, 41997, + 41833, 11442, 10758, 65774, 113823, 120384, 64115, 92221, 70018, 0, + 983708, 119053, 0, 12765, 64118, 126998, 12962, 0, 126580, 4017, 12827, + 5241, 120392, 0, 41118, 3924, 0, 11366, 129084, 0, 0, 917846, 41116, + 917844, 917564, 129081, 11363, 12057, 11917, 1567, 74000, 4721, 126641, + 66202, 8957, 4139, 70512, 0, 983074, 0, 0, 12740, 128702, 4722, 6816, + 124974, 12759, 4725, 67099, 4726, 0, 194892, 983622, 70029, 917905, + 92912, 12755, 12762, 4015, 67690, 8052, 476, 0, 0, 128294, 64212, 41020, + 1382, 64209, 64216, 44002, 64214, 1656, 41831, 0, 125121, 41843, 8720, + 3908, 1452, 13111, 983419, 64067, 127328, 8552, 64113, 41845, 3849, + 78732, 66232, 9778, 120066, 5891, 7064, 55, 9948, 119085, 0, 917610, + 7935, 2420, 0, 1114, 78120, 67585, 70104, 70432, 92168, 120051, 3938, + 120057, 65417, 64717, 120060, 71920, 65415, 66884, 6292, 65303, 7955, + 6452, 4713, 128196, 66249, 917885, 917890, 129073, 65152, 719, 120044, 78623, 120042, 6713, 4532, 65412, 69822, 10868, 4717, 2349, 5902, 66450, - 4712, 917902, 917899, 917900, 65416, 8155, 4718, 3942, 4714, 9625, 0, - 6383, 194744, 12006, 128565, 0, 0, 0, 0, 65414, 6454, 1229, 126606, - 66437, 66025, 78699, 0, 42500, 120508, 4809, 9623, 917874, 78694, 917880, - 917877, 917878, 65405, 68159, 12893, 917882, 5365, 4545, 8901, 92421, - 119555, 4813, 128262, 0, 5925, 4808, 64330, 0, 65475, 118940, 195028, - 4814, 0, 4810, 0, 0, 64928, 10543, 0, 3522, 71335, 414, 65404, 0, 195027, - 6456, 73820, 0, 6691, 42193, 92225, 128171, 0, 74495, 0, 0, 0, 118820, - 9751, 65407, 128085, 11770, 3919, 0, 0, 65061, 0, 0, 0, 12235, 0, 0, - 127233, 64092, 983470, 64080, 0, 64090, 0, 69913, 10162, 10310, 0, 8454, - 127888, 42038, 387, 41363, 12737, 0, 4780, 43368, 0, 64310, 64621, 6732, - 78116, 0, 983139, 0, 983074, 8896, 0, 375, 6976, 66582, 119005, 983874, - 0, 983434, 119202, 119203, 12526, 43120, 2315, 0, 1938, 119197, 0, 4529, - 119200, 119201, 119198, 119199, 69692, 983432, 69698, 13150, 64492, 0, 0, - 2291, 12902, 0, 42891, 66327, 74298, 917857, 10799, 69690, 2587, 66372, - 0, 4193, 92250, 4241, 983057, 7998, 0, 0, 0, 126640, 2316, 118821, 0, 0, - 0, 64297, 74799, 92442, 74140, 0, 5373, 0, 983886, 3762, 10015, 120672, - 119232, 0, 41590, 0, 70098, 3780, 7485, 5779, 0, 42037, 0, 3906, 12349, - 0, 8326, 0, 65498, 3763, 6983, 5618, 0, 3779, 0, 43613, 0, 0, 0, 0, 0, 0, - 280, 74558, 127332, 68138, 13072, 1894, 0, 0, 65478, 43310, 7231, 0, - 11773, 0, 0, 0, 0, 2551, 0, 6453, 10200, 6235, 983752, 119237, 0, 128805, - 4470, 11826, 917557, 7780, 5369, 118958, 5249, 0, 5367, 8756, 127143, 0, - 5377, 120585, 68143, 1688, 78245, 983356, 69685, 983756, 0, 0, 44020, - 6808, 41319, 1300, 10650, 41692, 64505, 2290, 0, 119624, 1465, 10850, - 3943, 0, 41205, 41315, 118961, 0, 0, 5352, 0, 0, 8839, 41314, 7384, 7785, - 41204, 127322, 41209, 69637, 92241, 43607, 0, 0, 5420, 3897, 10134, 0, - 74417, 4018, 7150, 68127, 0, 0, 0, 0, 127526, 2561, 68621, 3542, 7148, - 12076, 7951, 68152, 118857, 5303, 6276, 1706, 0, 78751, 7146, 0, 65150, - 41819, 0, 73951, 10847, 41822, 9985, 860, 0, 10506, 983435, 69641, 10753, - 10830, 0, 615, 64490, 7574, 92617, 77922, 0, 12909, 43016, 64559, 127028, - 0, 0, 67996, 2020, 0, 4022, 128783, 0, 77923, 126593, 41691, 0, 0, 74329, - 0, 64622, 9070, 0, 68411, 3911, 42829, 43122, 1033, 74440, 0, 7000, 3904, - 0, 128198, 0, 118931, 119630, 13123, 10846, 3450, 127360, 7397, 118807, - 0, 42778, 10000, 41088, 449, 0, 3777, 68458, 0, 9636, 0, 10738, 69634, - 9367, 593, 41085, 3999, 65226, 41713, 12764, 0, 64409, 3596, 0, 0, 9763, - 120280, 92192, 12347, 124, 12981, 41127, 2092, 92687, 0, 0, 0, 10820, - 43987, 0, 0, 1769, 41715, 2463, 78489, 0, 12770, 126500, 1538, 0, 43124, - 0, 195058, 7795, 120300, 0, 4828, 1258, 127802, 2006, 0, 0, 9498, 127032, - 127033, 120289, 120288, 3939, 120290, 8846, 8943, 120287, 120286, 2650, - 4491, 1961, 42602, 11525, 120292, 1959, 120294, 55228, 11774, 41016, 0, - 68675, 128054, 1511, 9324, 78211, 10519, 66331, 3454, 19930, 0, 41019, 0, - 0, 65292, 6822, 12862, 0, 0, 42143, 41828, 78207, 65531, 78208, 118879, - 55223, 0, 128071, 41826, 8865, 6402, 0, 13279, 7917, 74755, 0, 7733, 0, - 4998, 983896, 92332, 41950, 0, 4268, 0, 0, 70061, 4013, 0, 10881, 0, 0, - 0, 74788, 2014, 0, 0, 9765, 0, 0, 0, 195059, 78357, 65281, 127825, 10949, - 0, 0, 0, 2015, 0, 0, 0, 66318, 43233, 0, 42517, 0, 0, 0, 12698, 8094, - 10135, 65909, 6474, 794, 0, 12656, 128122, 119353, 128270, 1665, 0, 4833, - 983053, 119351, 127367, 0, 189, 12611, 0, 0, 2859, 4838, 0, 4834, 65078, - 0, 0, 4837, 127061, 770, 0, 811, 0, 41042, 917551, 41318, 64427, 0, - 128208, 78848, 3895, 0, 74341, 3976, 0, 42859, 10193, 3116, 7747, 0, 0, - 0, 0, 0, 43686, 78846, 41877, 0, 2871, 64614, 128785, 999, 0, 6345, + 4712, 917902, 917899, 65400, 65416, 8155, 4718, 3942, 4714, 9625, 0, + 6383, 194744, 12006, 128565, 194789, 0, 113756, 0, 65414, 6454, 1229, + 126606, 66437, 66025, 78699, 0, 42500, 120508, 4809, 9623, 917874, 78694, + 917880, 917877, 917858, 65405, 68159, 12893, 78617, 5365, 4545, 8901, + 92421, 119555, 4813, 128262, 0, 5925, 4808, 64330, 128400, 65475, 118940, + 68244, 4814, 0, 4810, 0, 0, 64928, 10543, 71249, 3522, 71335, 414, 65404, + 0, 195027, 6456, 73820, 0, 6691, 42193, 66284, 128171, 0, 68337, 0, + 43858, 43832, 118820, 9751, 65407, 128085, 11770, 3919, 120724, 0, 65061, + 0, 917894, 0, 12235, 0, 92701, 127233, 64092, 983470, 64080, 0, 64090, + 983586, 69913, 10162, 10310, 0, 8454, 127888, 42038, 387, 41363, 12737, + 0, 4780, 43368, 0, 64310, 64621, 6732, 78116, 0, 194959, 195024, 92193, + 8896, 0, 375, 6976, 66582, 119005, 983874, 127325, 983434, 119202, + 119203, 12526, 43120, 2315, 0, 1938, 119197, 128452, 4529, 119200, + 119201, 119198, 119199, 69692, 129124, 69698, 13150, 64492, 128974, 0, + 2291, 12902, 0, 42891, 66327, 70502, 917857, 10799, 69690, 2587, 66372, + 128628, 4193, 66823, 4241, 129195, 7998, 119840, 0, 983554, 126640, 2316, + 118821, 0, 0, 0, 64297, 74799, 92442, 74140, 128148, 5373, 128798, 70370, + 3762, 10015, 120672, 119232, 125109, 41590, 0, 70098, 3780, 7485, 5779, + 0, 42037, 0, 3906, 12349, 74793, 8326, 0, 65498, 3763, 6983, 5618, 0, + 3779, 983194, 43613, 70132, 0, 0, 78335, 983892, 0, 280, 74558, 127332, + 67396, 13072, 1894, 0, 67735, 65478, 43310, 7231, 0, 11773, 0, 0, 11144, + 917778, 2551, 0, 6453, 10200, 6235, 983752, 119237, 71877, 128805, 4470, + 11826, 917557, 7780, 5369, 118958, 5249, 983066, 5367, 8756, 127143, + 119183, 5377, 120585, 68143, 1688, 78245, 5218, 69685, 983756, 0, 113794, + 44020, 6808, 41319, 1300, 10650, 41692, 64505, 2290, 71057, 119624, 1465, + 10850, 3943, 0, 41205, 41315, 118961, 119333, 67148, 5352, 113753, 0, + 8839, 41314, 7384, 7785, 41204, 127322, 41209, 69637, 92241, 43607, + 71254, 0, 5420, 3897, 10134, 0, 74417, 4018, 7150, 68127, 0, 0, 0, 0, + 127526, 2561, 68621, 3542, 7148, 12076, 7951, 68152, 118857, 5303, 6276, + 1706, 120750, 78751, 7146, 0, 65150, 41819, 0, 73951, 10847, 41822, 9985, + 860, 0, 10506, 983435, 69641, 10753, 10830, 119339, 615, 64490, 7574, + 74082, 77922, 0, 12909, 43016, 64559, 127028, 0, 127029, 67996, 2020, + 983350, 4022, 128783, 0, 77923, 126593, 41691, 0, 917818, 74329, 0, + 64622, 9070, 0, 68411, 3911, 42829, 43122, 1033, 74440, 0, 7000, 3904, + 983628, 73737, 125105, 118931, 119630, 13123, 10846, 3450, 127360, 7397, + 118807, 0, 42778, 10000, 41088, 449, 0, 3777, 68458, 113725, 9636, 0, + 10738, 69634, 9367, 593, 41085, 3999, 65226, 41713, 12764, 983723, 64409, + 3596, 0, 128090, 9763, 120280, 74609, 12347, 124, 12981, 41127, 2092, + 92687, 0, 127555, 0, 10820, 43987, 0, 128907, 1769, 41715, 2463, 71214, + 983947, 12770, 71222, 1538, 92617, 43124, 194614, 195058, 7795, 120300, + 129053, 4828, 1258, 127802, 2006, 0, 0, 9498, 127032, 127033, 120289, + 120288, 3939, 120290, 8846, 8943, 120287, 120286, 2650, 4491, 1961, + 42602, 11525, 120292, 1959, 120294, 55228, 11774, 41016, 983260, 68675, + 128054, 1511, 9324, 78211, 10519, 66331, 3454, 19930, 0, 41019, 127944, + 0, 65292, 6822, 12862, 0, 0, 42143, 41828, 78207, 65531, 70864, 118879, + 55223, 0, 128071, 41826, 8865, 6402, 113827, 13279, 7917, 74755, 917948, + 7733, 0, 4998, 68493, 92332, 41950, 0, 4268, 0, 0, 70061, 4013, 128718, + 10881, 0, 0, 0, 74788, 2014, 2432, 71901, 9765, 0, 0, 917854, 195059, + 78357, 65281, 127825, 10949, 0, 0, 119315, 2015, 0, 0, 71840, 66318, + 43233, 917992, 42517, 0, 0, 0, 12698, 8094, 10135, 65909, 6474, 794, + 43497, 12656, 66335, 119353, 128270, 1665, 71853, 4833, 983053, 71188, + 127367, 0, 189, 12611, 0, 0, 2859, 4838, 0, 4834, 65078, 0, 92991, 4837, + 67413, 770, 92671, 811, 70062, 41042, 92915, 41318, 64427, 73999, 67693, + 78848, 3895, 0, 74341, 3976, 128466, 42859, 10193, 3116, 7747, 78488, 0, + 43496, 0, 0, 43686, 78846, 41877, 0, 2871, 64614, 127010, 999, 0, 6345, 41876, 2663, 2017, 0, 0, 11040, 10150, 0, 64308, 1522, 597, 4775, 12555, 12571, 12550, 12583, 12560, 2019, 12556, 12584, 3092, 0, 12562, 4783, - 12566, 12569, 12554, 0, 10812, 78851, 0, 0, 3078, 1402, 0, 128275, 0, 0, - 119248, 394, 3088, 0, 92172, 0, 3991, 64391, 0, 128524, 424, 66328, 1999, - 69659, 73914, 0, 0, 0, 0, 42231, 8246, 0, 0, 0, 41840, 983609, 2377, - 1298, 64011, 12572, 11318, 12557, 12559, 12570, 7479, 1003, 2373, 9446, - 7481, 9448, 48, 0, 9480, 481, 0, 9438, 9439, 9440, 9441, 8465, 9443, - 9444, 9445, 9430, 9431, 9432, 9433, 9434, 9435, 3984, 9437, 0, 0, 9424, - 9425, 9426, 9427, 9428, 9429, 64758, 2362, 9655, 0, 2004, 9096, 9782, - 128848, 9172, 128545, 19965, 0, 5955, 67666, 1108, 0, 74773, 0, 0, 64782, - 3926, 92448, 65210, 8798, 0, 92165, 1392, 0, 0, 127364, 10606, 8065, - 118805, 10353, 10417, 0, 0, 64524, 92418, 4019, 0, 983288, 43280, 8219, - 68402, 1812, 119963, 983692, 0, 126488, 42410, 74448, 119132, 6054, - 10697, 3169, 42297, 42322, 10642, 3909, 9950, 0, 128139, 983261, 68678, - 0, 0, 1049, 0, 65707, 2304, 41806, 92326, 42336, 3921, 0, 11775, 64760, + 12566, 12569, 12554, 0, 10812, 78851, 0, 917563, 3078, 1402, 0, 128275, + 0, 125072, 119248, 394, 3088, 0, 92172, 0, 3991, 64391, 129072, 128524, + 424, 66328, 1999, 69659, 73914, 0, 0, 66903, 0, 42231, 2209, 125103, 0, + 0, 41840, 66913, 2377, 1298, 64011, 12572, 11318, 12557, 12559, 12570, + 7479, 1003, 2373, 9446, 7481, 9448, 48, 0, 9480, 481, 0, 9438, 9439, + 9440, 9441, 8465, 9443, 9444, 9445, 9430, 9431, 9432, 9433, 9434, 9435, + 3984, 9437, 0, 92934, 9424, 9425, 9426, 9427, 9428, 9429, 64758, 2362, + 9655, 983709, 2004, 9096, 9782, 70842, 9172, 128545, 19965, 0, 5955, + 67666, 1108, 0, 74773, 0, 128909, 64782, 3926, 92448, 65210, 8798, 0, + 92165, 1392, 0, 983214, 127364, 10606, 8065, 118805, 10353, 10417, 0, + 128739, 64524, 92418, 4019, 0, 125082, 43280, 8219, 68402, 1812, 119963, + 983692, 129144, 126488, 42410, 74448, 119132, 6054, 10697, 3169, 42297, + 42322, 10642, 3909, 9950, 128848, 128139, 983261, 68678, 92917, 983790, + 1049, 43517, 65707, 2304, 41806, 92326, 42336, 3921, 0, 11775, 64760, 11766, 1038, 42303, 9823, 127278, 69236, 4008, 64004, 8773, 10733, 36, 0, - 5153, 41805, 0, 73735, 763, 41808, 64910, 983130, 2009, 0, 0, 127142, - 9640, 119951, 0, 120695, 8621, 120523, 12852, 3031, 983050, 64361, 0, - 182, 194718, 92716, 92598, 119950, 42613, 9058, 366, 0, 9892, 5969, - 11754, 10848, 4570, 65301, 44013, 4255, 127889, 10102, 41189, 4003, - 41026, 68109, 13293, 41192, 69635, 0, 42251, 0, 42534, 65179, 11287, - 6128, 0, 11034, 10923, 64423, 0, 65506, 0, 65861, 74083, 92600, 9932, 0, - 92423, 119955, 0, 9817, 0, 120140, 0, 12117, 66586, 4183, 10540, 66250, - 9063, 127045, 0, 119954, 0, 12897, 3792, 2011, 0, 6065, 43160, 0, 194715, - 8692, 41186, 41816, 41023, 41818, 41187, 11659, 7922, 12614, 2005, 8523, - 78002, 0, 7513, 1863, 4710, 0, 5956, 7621, 78006, 92624, 4705, 716, - 78004, 0, 4704, 120040, 120270, 42241, 161, 43977, 74546, 66214, 4706, 0, - 69914, 42672, 4709, 10680, 119065, 43293, 119944, 0, 119164, 120328, - 92467, 10187, 1700, 119223, 0, 0, 128119, 4004, 0, 10968, 43296, 983642, - 8506, 0, 0, 126996, 1005, 937, 78216, 4734, 2870, 0, 78218, 983109, 7463, - 4729, 0, 235, 1384, 4728, 0, 120420, 92490, 74449, 8109, 43105, 983174, - 4730, 447, 13186, 1513, 4733, 120415, 0, 0, 42527, 12911, 43427, 1383, - 8565, 2469, 120024, 6690, 6156, 68117, 43439, 7993, 4288, 120416, 2674, - 13238, 11922, 0, 120330, 3510, 13234, 0, 120407, 5605, 42095, 11364, 0, - 1380, 65617, 120253, 120261, 13196, 13197, 120309, 120682, 9495, 119346, - 0, 5959, 67984, 73976, 120305, 43371, 6941, 119349, 13205, 13211, 5801, + 5153, 41805, 0, 73735, 763, 41808, 64910, 983130, 2009, 0, 127985, 74245, + 9640, 119951, 0, 69895, 8621, 120523, 12852, 3031, 983050, 64361, 129088, + 182, 66414, 92716, 92598, 119950, 42613, 9058, 366, 0, 9892, 5969, 11754, + 10848, 4570, 65301, 44013, 4255, 127889, 10102, 41189, 4003, 41026, + 68109, 13293, 41192, 69635, 124977, 42251, 0, 42534, 65179, 11287, 6128, + 113811, 11034, 10923, 64423, 0, 65506, 0, 65861, 74083, 66872, 9932, + 43516, 92423, 119955, 119948, 9817, 0, 71234, 0, 12117, 66586, 4183, + 10540, 66250, 9063, 127045, 0, 119954, 113685, 12897, 3792, 2011, 0, + 6065, 43160, 128379, 194715, 8692, 41186, 41816, 41023, 41818, 41187, + 11659, 7922, 12614, 2005, 8523, 78002, 120035, 7513, 1863, 4710, 0, 5956, + 7621, 78006, 92624, 4705, 716, 78004, 0, 4704, 120040, 93024, 42241, 161, + 43977, 74546, 66214, 4706, 74077, 69914, 42672, 4709, 10680, 119065, + 43293, 119944, 983190, 119164, 120328, 92350, 10187, 1700, 119223, 0, 0, + 127202, 4004, 0, 10968, 43296, 983642, 8506, 113744, 194812, 126996, + 1005, 937, 78216, 4734, 2870, 0, 78218, 983109, 7463, 4729, 0, 235, 1384, + 4728, 0, 70494, 92490, 74449, 8109, 43105, 128623, 4730, 447, 13186, + 1513, 4733, 120415, 92548, 0, 42527, 12911, 43427, 1383, 8565, 2469, + 120024, 6690, 6156, 68117, 43439, 7993, 4288, 120416, 2674, 13238, 11922, + 0, 120330, 3510, 13234, 983832, 120407, 5605, 42095, 11364, 92286, 1380, + 65617, 11162, 120261, 13196, 13197, 120309, 67708, 9495, 119346, 127154, + 5959, 67984, 73976, 66275, 43371, 6941, 119349, 13205, 13211, 5801, 12769, 65905, 41697, 1283, 120302, 4779, 0, 3719, 4006, 983569, 19957, - 128773, 2021, 119332, 120699, 119150, 43028, 65493, 41838, 3875, 5962, - 64341, 92616, 9814, 43457, 5827, 3314, 7787, 78234, 65494, 68153, 0, 0, - 120636, 64531, 120692, 194626, 0, 0, 66316, 65467, 5771, 41298, 983794, - 9742, 521, 0, 10800, 92222, 8404, 194625, 483, 7096, 7089, 66323, 928, 0, - 0, 119018, 10599, 11586, 3989, 10971, 43748, 65782, 9841, 8843, 12145, - 92470, 10074, 78548, 0, 3769, 0, 0, 0, 983107, 9573, 0, 65290, 8849, 0, - 65855, 65112, 1796, 120505, 0, 69665, 8164, 41301, 3502, 0, 7388, 10621, - 73838, 78553, 5825, 13007, 68165, 0, 120457, 12661, 7608, 10354, 10418, - 42411, 2022, 0, 1409, 12195, 4001, 3112, 10824, 120639, 1390, 0, 0, 421, - 43536, 5846, 120120, 4130, 127775, 7595, 42588, 7600, 120121, 66035, - 983913, 0, 65851, 42607, 128190, 92403, 3168, 0, 42134, 11831, 2370, - 2846, 92605, 0, 0, 120132, 0, 1836, 0, 0, 92558, 3740, 69843, 6290, - 65374, 120451, 2390, 3944, 66628, 120434, 0, 6135, 3118, 74265, 119093, - 120446, 0, 0, 8127, 8975, 64739, 7943, 983743, 0, 10618, 2584, 0, 0, 0, - 9998, 128564, 0, 0, 0, 0, 6204, 0, 0, 8279, 8776, 64954, 4975, 70075, - 120130, 4267, 1631, 42206, 77983, 0, 195046, 65700, 66562, 0, 64645, 0, - 0, 126588, 12586, 0, 9242, 127922, 0, 4523, 5842, 10495, 3122, 983797, - 7793, 78275, 9328, 119104, 78393, 12604, 0, 6615, 2285, 92344, 3986, - 44025, 0, 8912, 64555, 7409, 0, 983358, 9541, 78276, 0, 11275, 8540, - 11498, 0, 983357, 41040, 2459, 0, 13060, 41041, 74413, 983138, 0, 0, - 68427, 10450, 12551, 41043, 7020, 120353, 3765, 983350, 0, 1606, 120348, - 120351, 3093, 68436, 0, 983061, 119613, 0, 0, 4312, 74091, 120337, - 120336, 11923, 4023, 120333, 5763, 94015, 4827, 10894, 12810, 64406, - 118785, 4455, 74321, 433, 119620, 66660, 2499, 0, 0, 118837, 11973, - 13089, 4293, 120329, 42224, 42758, 12196, 42837, 42226, 119319, 0, - 119126, 5817, 127806, 55277, 3120, 9797, 0, 0, 0, 10389, 126485, 0, 4895, - 65358, 0, 4359, 585, 2383, 3509, 70037, 486, 4290, 5758, 127546, 0, 0, - 7004, 0, 65880, 127886, 119048, 2380, 11380, 0, 93996, 2376, 0, 119320, - 0, 5197, 127046, 127047, 127048, 2366, 127050, 127051, 120554, 120045, 0, - 0, 0, 983084, 0, 0, 0, 74188, 71342, 983086, 983573, 120047, 128575, 0, - 0, 120049, 0, 1847, 0, 10339, 983365, 42384, 0, 4227, 74158, 0, 92501, - 43032, 0, 42365, 0, 12671, 11384, 0, 983465, 0, 64797, 983345, 5820, - 983344, 120052, 120065, 0, 120064, 120650, 42137, 9893, 2754, 12664, - 120063, 0, 7377, 127867, 41799, 65530, 1711, 12984, 43039, 3114, 6255, - 983340, 118938, 0, 10853, 926, 983369, 74184, 983368, 120055, 0, 43175, - 0, 43037, 41798, 41035, 11583, 127769, 41801, 119088, 119605, 520, 4200, - 12699, 8331, 0, 3091, 41034, 127353, 983681, 8360, 0, 78044, 321, 4229, - 64543, 917946, 65563, 0, 917974, 2861, 43793, 10095, 0, 9195, 92386, - 1861, 0, 73733, 0, 0, 43041, 0, 43794, 128530, 3859, 12181, 41660, 8209, - 0, 73867, 12973, 0, 74757, 127514, 41658, 0, 0, 5760, 0, 743, 4414, - 120766, 0, 42632, 917973, 65161, 73896, 128589, 0, 1405, 119063, 43220, - 43341, 0, 19919, 0, 64532, 65367, 43710, 0, 0, 3513, 0, 118883, 43342, - 119064, 65529, 65364, 128197, 0, 6485, 1397, 0, 41986, 92678, 0, 0, - 74097, 0, 7471, 12079, 67997, 12682, 43287, 92317, 0, 983143, 983707, 0, - 0, 1099, 10490, 0, 10501, 65181, 74463, 0, 464, 41624, 65283, 67663, - 78222, 1346, 0, 917631, 64573, 64897, 423, 1818, 65144, 0, 8272, 127812, - 19911, 4218, 3087, 64960, 127234, 43564, 0, 0, 9584, 10465, 983902, - 74359, 12626, 9106, 0, 42642, 120230, 64750, 9390, 0, 41797, 0, 0, 265, - 41795, 64666, 126508, 43530, 2752, 0, 0, 983493, 59, 0, 983593, 0, 92371, - 77873, 41810, 0, 7010, 0, 41809, 41495, 119364, 0, 42252, 42213, 8009, - 3305, 43033, 511, 92700, 66255, 13127, 120067, 0, 74397, 120235, 917977, - 65915, 1400, 41812, 10685, 194870, 2103, 10387, 4453, 43276, 917783, - 13159, 0, 6481, 41213, 0, 0, 0, 0, 41983, 74198, 6617, 9116, 119654, 0, - 462, 68110, 10493, 0, 8129, 0, 0, 74471, 6644, 11658, 0, 128245, 3452, - 11906, 9581, 1385, 3098, 0, 119013, 43340, 0, 41033, 6493, 42626, 0, 0, - 11426, 77887, 1681, 118789, 1204, 3755, 64661, 7235, 10170, 3966, 8911, - 0, 41841, 43338, 0, 0, 5726, 64915, 42175, 0, 0, 41497, 65044, 120109, - 2851, 43017, 983589, 0, 4373, 78058, 0, 9587, 1789, 6671, 128840, 3100, - 0, 65360, 0, 92365, 917789, 64922, 0, 8190, 12083, 0, 0, 6506, 64312, - 74374, 2368, 0, 4419, 983847, 119125, 3439, 1825, 1192, 120106, 8891, - 3080, 120228, 2347, 5430, 0, 8990, 2848, 0, 128223, 92528, 249, 0, 0, 0, - 120658, 0, 0, 8883, 917802, 728, 68178, 995, 0, 0, 64826, 0, 917798, - 128348, 0, 19945, 8091, 558, 0, 12273, 194814, 983850, 12112, 69912, 0, - 0, 74419, 12335, 120104, 917795, 3443, 3129, 0, 2102, 65445, 78258, - 64891, 0, 7725, 65108, 78255, 0, 8624, 69246, 12446, 43295, 0, 41894, 0, - 6277, 41672, 41893, 10010, 128678, 3540, 128649, 835, 71340, 69816, - 119868, 74408, 0, 73959, 5426, 4258, 0, 0, 5424, 128127, 8283, 0, 5434, - 983590, 0, 19917, 11408, 0, 11947, 0, 1404, 3095, 11432, 128307, 3464, - 6486, 4819, 128233, 0, 570, 8095, 3672, 119864, 1498, 67866, 0, 128539, - 431, 0, 0, 128182, 128096, 68167, 983663, 13096, 128643, 0, 43408, 9516, - 128538, 5268, 42230, 42220, 0, 4450, 120511, 11547, 43417, 128542, 356, - 3477, 227, 10488, 68203, 382, 11418, 0, 195066, 0, 0, 0, 0, 6484, 2541, - 66039, 0, 78718, 92723, 3549, 0, 9110, 119665, 2743, 0, 43290, 194812, - 9097, 0, 43015, 8782, 0, 776, 2524, 42707, 8573, 0, 126494, 0, 0, 42694, - 64944, 8952, 3856, 118818, 0, 5872, 6495, 0, 0, 0, 92543, 0, 120733, - 12849, 3953, 1897, 0, 65094, 11994, 4339, 74556, 92654, 67843, 0, 0, 0, - 68473, 74104, 5228, 128804, 7868, 43184, 0, 0, 73986, 43438, 0, 43022, 0, - 1162, 917847, 2671, 0, 0, 92632, 92631, 118865, 4553, 73811, 0, 195005, - 0, 0, 19921, 74331, 11424, 195006, 4567, 41891, 0, 983788, 55249, 4820, - 65239, 194662, 0, 194665, 43042, 119212, 1377, 12869, 4897, 42821, 9250, - 0, 4438, 64385, 0, 1753, 11331, 6147, 194941, 43282, 8833, 0, 0, 6504, - 78408, 126979, 10719, 0, 1898, 1413, 42443, 0, 802, 12141, 0, 194671, - 6648, 10671, 2528, 0, 64789, 9169, 838, 120087, 120697, 844, 5014, 0, - 256, 0, 9990, 0, 42739, 917851, 7542, 65464, 9726, 0, 6489, 10048, 74326, - 78719, 66573, 0, 78724, 78712, 11761, 194655, 0, 41094, 0, 0, 194893, 0, - 92689, 6196, 6945, 93969, 194890, 128184, 120491, 11816, 194943, 5733, - 2930, 0, 0, 41098, 0, 41093, 0, 66626, 588, 9760, 0, 194717, 1238, 200, - 983207, 1660, 73916, 0, 118905, 74362, 0, 92485, 194651, 0, 983706, 3394, - 194894, 120668, 0, 0, 127358, 66219, 127183, 43284, 194656, 7817, 1841, - 11055, 120533, 194979, 194982, 1669, 10776, 194981, 7701, 194980, 0, - 194995, 1732, 4030, 0, 3963, 66611, 127530, 41768, 6491, 0, 65324, 914, - 65323, 8071, 3538, 0, 2287, 65328, 92441, 74367, 7614, 0, 11819, 0, - 12009, 12399, 0, 67852, 65537, 0, 10841, 43430, 5301, 0, 92618, 5734, - 8960, 0, 92527, 65317, 77880, 0, 0, 0, 12304, 0, 0, 65315, 92670, 128511, - 0, 0, 0, 119621, 92529, 74536, 12447, 64486, 127374, 126562, 983129, 0, - 0, 983802, 42767, 10915, 0, 12007, 43695, 120520, 11975, 194878, 0, - 92604, 2555, 8629, 128640, 43168, 41872, 43706, 4496, 194879, 128148, - 120241, 0, 0, 0, 0, 64730, 70041, 66714, 68222, 0, 70076, 65596, 92306, - 11416, 4280, 67655, 8765, 12784, 7792, 1393, 126473, 67871, 74386, 0, - 8233, 12820, 0, 6683, 194876, 3442, 12144, 2841, 12543, 0, 1473, 42820, - 64329, 127832, 0, 68642, 6488, 357, 1048, 41100, 0, 41104, 94003, 3406, - 1054, 71320, 1040, 65450, 0, 4434, 1069, 0, 118862, 65737, 917765, - 128705, 0, 983693, 9693, 41943, 126564, 41931, 41759, 12757, 4353, 0, - 1059, 9790, 8995, 119974, 983696, 65937, 0, 41764, 10646, 0, 118833, - 92372, 0, 74830, 78569, 12743, 983689, 6480, 917761, 41779, 42580, 66601, - 12207, 119619, 6335, 66602, 11312, 64807, 0, 0, 41767, 119629, 983764, - 43020, 128271, 3955, 74254, 0, 983754, 917861, 0, 77926, 9770, 9246, - 12230, 0, 0, 0, 10448, 41783, 41786, 127093, 12797, 2755, 64571, 78578, - 194927, 4857, 0, 4428, 12794, 73755, 128061, 78574, 0, 74284, 0, 5747, - 78825, 0, 7978, 41092, 74571, 0, 11924, 43812, 42144, 65015, 0, 563, 0, - 983691, 12798, 11271, 57, 0, 0, 917860, 119043, 0, 94051, 43137, 694, 0, - 9876, 0, 119168, 0, 78822, 64537, 0, 277, 74385, 7229, 12761, 0, 0, - 13025, 64811, 8757, 78824, 126478, 1574, 7381, 0, 2525, 4852, 5749, - 68465, 13027, 42824, 120574, 1039, 7151, 10155, 5745, 188, 41858, 11592, - 0, 74015, 9055, 41853, 4858, 917780, 0, 436, 4771, 0, 2786, 0, 4856, - 8051, 0, 119609, 71327, 9644, 0, 0, 0, 194916, 120732, 66710, 118834, - 983359, 73906, 128680, 127114, 0, 10234, 5843, 11939, 0, 42157, 0, 3157, - 194918, 68393, 0, 3504, 119178, 0, 10822, 5149, 66029, 10226, 65142, - 128025, 3594, 42424, 194959, 40, 12657, 983665, 0, 386, 0, 8834, 0, - 12815, 43574, 0, 73907, 0, 74196, 7220, 74504, 0, 74316, 0, 65322, 4304, - 74503, 8160, 78707, 194753, 0, 0, 128526, 1348, 92349, 78597, 126539, - 13303, 0, 92392, 194755, 7599, 1278, 43616, 13269, 0, 0, 74387, 78179, - 78598, 74492, 6097, 7568, 8780, 4982, 127464, 74501, 194763, 78592, - 194762, 2672, 3735, 127470, 13138, 42266, 9484, 10724, 41202, 71364, 0, - 43742, 0, 9487, 119959, 119117, 3842, 128768, 78668, 12442, 6193, 9791, - 127976, 0, 42516, 7228, 7559, 74803, 78468, 7873, 11399, 119219, 194691, - 194855, 194690, 194857, 3604, 120683, 119188, 128877, 78540, 78541, - 42507, 1962, 43305, 78476, 42505, 11660, 0, 2072, 92312, 6995, 74173, - 5437, 74174, 10669, 8702, 7964, 92352, 0, 199, 194843, 4105, 194845, - 194699, 194847, 194710, 119875, 13148, 7560, 78479, 9226, 78480, 195070, - 6472, 65814, 73954, 0, 4724, 0, 0, 9191, 0, 64432, 983817, 983247, - 195024, 10196, 7886, 0, 6585, 0, 6680, 195042, 0, 195051, 6679, 74412, - 92251, 194866, 74421, 11382, 983631, 983637, 127891, 127484, 194833, + 71186, 2021, 119332, 43877, 119150, 43028, 65493, 41838, 3875, 5962, + 64341, 92616, 9814, 43457, 5827, 3314, 7787, 71189, 65494, 68153, 126991, + 194697, 120636, 64531, 120692, 194626, 0, 0, 66316, 65467, 5771, 41298, + 983794, 9742, 521, 0, 10800, 92222, 8404, 194625, 483, 7096, 7089, 66323, + 928, 0, 0, 119018, 10599, 11586, 3989, 10971, 43748, 65782, 9841, 8843, + 12145, 67261, 10074, 78548, 93999, 3769, 0, 0, 128703, 983107, 9573, 0, + 65290, 8849, 119254, 65855, 65112, 1796, 71046, 0, 69665, 8164, 41301, + 3502, 0, 7388, 10621, 73838, 78553, 5825, 13007, 68165, 92203, 120456, + 12661, 7608, 10354, 10418, 42411, 2022, 0, 1409, 12195, 4001, 3112, + 10824, 120639, 1390, 70184, 0, 421, 43536, 5846, 120120, 4130, 127775, + 7595, 42588, 7600, 74400, 66035, 195091, 0, 65851, 42607, 128190, 92403, + 3168, 67733, 42134, 11831, 2370, 2846, 92605, 128183, 0, 120132, 0, 1836, + 0, 0, 92558, 3740, 69843, 6290, 65374, 120451, 2390, 3944, 66628, 120434, + 0, 6135, 3118, 74265, 119093, 113690, 77975, 0, 8127, 8975, 64739, 7943, + 124968, 119234, 10618, 2584, 0, 0, 128225, 9998, 120573, 0, 0, 127750, + 43508, 6204, 127044, 0, 8279, 8776, 64954, 4975, 70075, 120130, 4267, + 1631, 42206, 77983, 128015, 195046, 65700, 66386, 0, 64645, 0, 92887, + 126588, 12586, 0, 9242, 120100, 0, 4523, 5842, 10495, 3122, 983797, 7793, + 78275, 9328, 119104, 78393, 12604, 92885, 6615, 2285, 92344, 3986, 44025, + 0, 8912, 64555, 7409, 92247, 983358, 9541, 78276, 113669, 11275, 8540, + 11498, 0, 983357, 41040, 2459, 128629, 13060, 41041, 74413, 983138, 0, + 77931, 68427, 10450, 12551, 41043, 7020, 120353, 3765, 92881, 0, 1606, + 120348, 92299, 3093, 68436, 128040, 983061, 119613, 0, 0, 4312, 74091, + 120337, 120336, 11923, 4023, 120333, 5763, 94015, 4827, 10894, 12810, + 64406, 118785, 4455, 74321, 433, 119620, 66660, 2499, 67167, 67166, + 118837, 11973, 13089, 4293, 120329, 42224, 42758, 12196, 42837, 42226, + 119319, 0, 119126, 5817, 127806, 55277, 3120, 9797, 0, 0, 11086, 10389, + 126485, 0, 4895, 65358, 124941, 4359, 585, 2383, 3509, 70037, 486, 4290, + 5758, 127546, 0, 0, 7004, 113667, 65880, 126514, 119048, 2380, 11380, 0, + 93996, 2376, 78841, 119320, 0, 5197, 70839, 127047, 127048, 2366, 127050, + 127051, 70837, 120045, 0, 128554, 0, 983084, 0, 0, 0, 74188, 71342, + 78455, 983573, 120047, 128575, 120046, 127542, 120049, 0, 1847, 0, 10339, + 983365, 42384, 0, 4227, 74158, 0, 74498, 43032, 125010, 42365, 0, 12671, + 11384, 120059, 74264, 120058, 64797, 983345, 5820, 983344, 120052, + 120065, 128825, 120064, 120053, 42137, 9893, 2754, 12664, 120063, 128900, + 7377, 127867, 41799, 65530, 1711, 12984, 43039, 3114, 6255, 983340, + 68660, 0, 10853, 926, 983369, 74184, 983368, 120055, 194993, 43175, 0, + 43037, 41798, 41035, 11583, 127769, 41801, 119088, 119605, 520, 4200, + 12699, 8331, 0, 3091, 41034, 66298, 983681, 8360, 983443, 78044, 321, + 4229, 64543, 128470, 65563, 0, 917974, 2861, 43793, 10095, 194735, 9195, + 92386, 1861, 0, 73733, 0, 0, 43041, 0, 43794, 128530, 3859, 12181, 41660, + 8209, 70793, 73867, 12973, 0, 74757, 127514, 41658, 0, 0, 5760, 113699, + 743, 4414, 120766, 0, 42632, 917973, 65161, 73896, 128589, 0, 1405, + 119063, 43220, 43341, 0, 19919, 0, 64532, 65367, 43710, 11199, 194907, + 3513, 128854, 70341, 43342, 119064, 65529, 65364, 128197, 0, 6485, 1397, + 0, 41986, 92678, 0, 194784, 74097, 0, 7471, 12079, 67997, 6843, 43287, + 92317, 0, 67406, 983707, 0, 71914, 1099, 10490, 0, 10501, 65181, 74463, + 128952, 464, 41624, 65283, 67663, 78222, 1346, 0, 65679, 64573, 64897, + 423, 1818, 65144, 113748, 8272, 127812, 19911, 4218, 3087, 64960, 127234, + 43564, 0, 0, 9584, 10465, 983902, 74359, 12626, 9106, 0, 42642, 71235, + 64750, 9390, 0, 41797, 0, 0, 265, 41795, 64666, 74628, 43530, 2752, + 127365, 128459, 983493, 59, 983671, 983593, 11149, 78074, 77873, 41810, + 0, 7010, 0, 41809, 41495, 119364, 5877, 42252, 42213, 8009, 3305, 43033, + 511, 92700, 43848, 13127, 120067, 983946, 74397, 120235, 917977, 65915, + 1400, 41812, 10685, 194870, 2103, 10387, 4453, 43276, 917783, 11169, 0, + 6481, 41213, 0, 0, 129133, 129050, 41983, 74198, 6617, 9116, 119654, + 92995, 462, 68110, 10493, 917976, 8129, 92994, 128365, 74471, 6644, + 11658, 0, 128245, 3452, 11906, 9581, 1385, 3098, 0, 119013, 43340, 11123, + 41033, 6493, 42626, 0, 129051, 11426, 77887, 1681, 118789, 1204, 3755, + 64661, 7235, 10170, 3966, 8911, 0, 41841, 43338, 0, 0, 5726, 64915, + 42175, 983913, 0, 41497, 65044, 120109, 2851, 43017, 983589, 0, 4373, + 78058, 0, 9587, 1789, 6671, 128840, 3100, 0, 65360, 0, 92365, 917789, + 64922, 0, 8190, 12083, 0, 983930, 6506, 64312, 74374, 2368, 0, 4419, + 983847, 119125, 3439, 1825, 1192, 120106, 8891, 3080, 120228, 2347, 5430, + 0, 8990, 2848, 92981, 128223, 73942, 249, 0, 0, 0, 120658, 119324, + 128712, 8883, 119860, 728, 11173, 995, 0, 0, 64826, 124931, 917798, + 128348, 0, 19945, 8091, 558, 0, 12273, 194814, 67714, 12112, 67272, + 67265, 67273, 67274, 12335, 120104, 68019, 3443, 3129, 67267, 2102, + 65445, 78258, 64891, 0, 7725, 65108, 11120, 9205, 8624, 69246, 12446, + 43295, 128519, 41894, 0, 6277, 41672, 41893, 10010, 127381, 3540, 128649, + 835, 71340, 69816, 119854, 74408, 0, 67108, 5426, 4258, 983231, 0, 5424, + 128127, 8283, 127978, 5434, 125004, 0, 19917, 11408, 0, 11947, 128330, + 1404, 3095, 11432, 128307, 3464, 6486, 4819, 128233, 0, 570, 8095, 3672, + 119864, 1498, 67866, 0, 128539, 431, 125062, 0, 128182, 128096, 68167, + 983663, 13096, 128643, 0, 43408, 9516, 128538, 5268, 42230, 42220, 0, + 4450, 120511, 11547, 43417, 128542, 356, 3477, 227, 10488, 68203, 382, + 11418, 0, 5878, 0, 0, 0, 0, 6484, 2541, 66039, 113777, 78718, 92723, + 3549, 195067, 9110, 119665, 2743, 0, 43290, 128585, 9097, 0, 43015, 8782, + 0, 776, 2524, 42707, 8573, 0, 126494, 0, 71102, 42694, 64944, 8952, 3856, + 118818, 125111, 5872, 6495, 129125, 0, 0, 92543, 67173, 67172, 12849, + 3953, 1897, 93071, 65094, 11994, 4339, 74556, 92654, 67843, 0, 0, 119087, + 68473, 74104, 5228, 119835, 7868, 43184, 0, 0, 73986, 43438, 0, 43022, + 917553, 1162, 917847, 2671, 128567, 0, 92632, 92631, 118865, 4553, 73811, + 0, 195005, 118928, 0, 19921, 74331, 11424, 195006, 4567, 41891, 0, + 983788, 55249, 4820, 65239, 194662, 0, 194665, 43042, 119212, 1377, + 12869, 4897, 42821, 9250, 917558, 4438, 64385, 0, 1753, 11331, 6147, + 194941, 43282, 8833, 69998, 0, 6504, 78408, 126979, 10719, 128469, 1898, + 1413, 42443, 0, 802, 12141, 0, 194671, 6648, 10671, 2528, 0, 64789, 9169, + 838, 70372, 120697, 844, 5014, 66297, 256, 0, 9990, 0, 42739, 917851, + 7542, 65464, 9726, 0, 6489, 10048, 74326, 78719, 66573, 0, 78724, 78712, + 11761, 194655, 118874, 41094, 0, 129172, 194893, 78403, 92689, 6196, + 6945, 93969, 127990, 67095, 120491, 11816, 126567, 5733, 2930, 78406, 0, + 41098, 92771, 41093, 0, 66626, 588, 9760, 129112, 194717, 1238, 200, + 983207, 1660, 73916, 0, 67141, 74362, 0, 92485, 124930, 0, 983706, 3394, + 194894, 120668, 0, 69996, 127358, 66219, 72425, 43284, 127236, 7817, + 1841, 11055, 66835, 194979, 74607, 1669, 10776, 74534, 7701, 194980, 0, + 194995, 1732, 4030, 0, 3963, 66611, 127530, 41768, 6491, 127518, 65324, + 914, 65323, 8071, 3538, 0, 2287, 65328, 92441, 74367, 7614, 0, 11819, + 71908, 12009, 12399, 0, 67852, 65537, 0, 10841, 43430, 5301, 0, 92618, + 5734, 8960, 0, 70123, 65317, 77880, 0, 5876, 70374, 12304, 0, 0, 65315, + 92670, 128511, 71862, 0, 0, 119621, 11114, 71909, 12447, 64486, 127374, + 126562, 983129, 0, 0, 983802, 42767, 10915, 0, 12007, 43695, 120520, + 11975, 194878, 0, 92604, 2555, 8629, 128640, 41133, 41872, 43706, 4496, + 194879, 128065, 120241, 0, 0, 0, 983553, 64730, 70041, 66714, 68222, 0, + 70076, 65596, 92306, 11416, 4280, 67655, 8765, 12784, 7792, 1393, 78191, + 11157, 74386, 0, 8233, 12820, 0, 6683, 194876, 3442, 12144, 2841, 12543, + 0, 1473, 42820, 64329, 127832, 0, 68642, 6488, 357, 1048, 41100, 72417, + 41104, 94003, 3406, 1054, 71320, 1040, 65450, 983383, 4434, 1069, 0, + 118862, 65737, 194634, 128705, 0, 124955, 9693, 41943, 68305, 41931, + 41759, 12757, 4353, 983351, 1059, 9790, 8995, 119974, 917770, 65937, + 78572, 41758, 10646, 0, 118833, 92372, 70424, 74830, 78569, 12743, + 983689, 6480, 917761, 41779, 42580, 66601, 12207, 77895, 6335, 66602, + 11312, 64807, 92962, 69989, 41767, 119629, 983764, 43020, 128271, 3955, + 74254, 120632, 983754, 917861, 70187, 69975, 9770, 9246, 12230, 125047, + 0, 78580, 10448, 41783, 41786, 127093, 12797, 2755, 64571, 78578, 194927, + 4857, 983577, 4428, 12794, 73755, 128061, 78574, 0, 11116, 43842, 5747, + 78825, 70471, 7978, 41092, 74571, 0, 11924, 43812, 42144, 65015, 0, 563, + 0, 983691, 12798, 11271, 57, 92717, 983239, 917860, 119043, 0, 94051, + 43137, 694, 0, 9876, 0, 119168, 0, 70392, 64537, 0, 277, 74385, 7229, + 12761, 0, 74466, 13025, 64811, 8757, 78824, 78188, 1574, 7381, 0, 2525, + 4852, 5749, 68465, 13027, 42824, 120574, 1039, 7151, 10155, 5745, 188, + 41858, 11592, 129156, 69725, 9055, 41853, 4858, 917780, 0, 436, 4771, 0, + 2786, 93028, 4856, 8051, 92500, 119609, 71327, 9644, 0, 125009, 128873, + 194916, 120732, 66710, 118834, 983359, 73906, 67409, 127114, 0, 10234, + 5843, 11939, 70346, 42157, 0, 3157, 194918, 68393, 0, 3504, 119178, 0, + 10822, 5149, 66029, 10226, 65142, 128025, 3594, 42424, 124993, 40, 12657, + 983665, 0, 386, 0, 8834, 0, 12815, 43574, 128407, 73907, 0, 70113, 7220, + 11839, 124984, 74316, 0, 65322, 4304, 74503, 8160, 74314, 194753, 0, 0, + 128526, 1348, 92349, 78597, 126539, 13303, 70406, 92392, 128474, 7599, + 1278, 43616, 13269, 127805, 127110, 74387, 78179, 78598, 74492, 6097, + 7568, 8780, 4982, 127464, 74501, 194763, 78592, 194762, 2672, 3735, + 127470, 13138, 42266, 9484, 10724, 41202, 71364, 128370, 43742, 128373, + 9487, 119959, 92913, 3842, 71911, 78668, 12442, 6193, 9791, 119344, 0, + 42516, 7228, 7559, 74803, 78468, 7873, 11399, 119219, 194691, 70006, + 194690, 127537, 3604, 120683, 119188, 128877, 78540, 78541, 42507, 1962, + 43305, 78476, 42505, 11660, 0, 2072, 92312, 6995, 74173, 5437, 74174, + 10669, 8702, 7964, 92352, 983776, 199, 194843, 4105, 194845, 194699, + 194847, 194710, 119875, 13148, 7560, 78479, 9226, 78478, 195070, 6472, + 65814, 71919, 0, 4724, 128491, 195041, 9191, 0, 64432, 983817, 113680, + 119190, 10196, 7886, 0, 6585, 0, 6680, 195042, 0, 71872, 6679, 74412, + 92251, 194866, 74421, 11382, 128254, 43862, 78591, 113733, 194833, 194832, 6681, 127482, 12693, 194836, 42727, 78196, 128252, 78195, 65442, - 119610, 69733, 9989, 43248, 66248, 194816, 0, 11321, 128845, 194820, - 194819, 5297, 7042, 13284, 6112, 7968, 194825, 73927, 92444, 194736, - 65746, 127476, 69889, 74389, 128696, 4342, 42839, 194831, 1677, 0, 0, + 119610, 69733, 9989, 43248, 66248, 194816, 0, 11321, 128845, 120809, + 194819, 5297, 7042, 13284, 6112, 7968, 93010, 73927, 92444, 127336, + 65746, 118796, 69889, 74389, 128696, 4342, 42839, 128979, 1677, 0, 0, 126590, 917855, 11091, 11011, 2719, 0, 0, 119595, 10160, 0, 0, 7585, - 65169, 2052, 4308, 92174, 43000, 7505, 543, 64916, 64736, 0, 0, 64655, 0, - 118922, 2064, 0, 43158, 7902, 0, 65265, 194639, 0, 127170, 0, 983625, 0, - 0, 12994, 92728, 10828, 983943, 6228, 4307, 3482, 128527, 0, 0, 0, 506, - 74573, 41194, 65735, 2055, 43255, 41195, 0, 8169, 983680, 8841, 0, 516, - 93974, 2063, 119051, 34, 128850, 120186, 11504, 1612, 74333, 120182, - 11827, 74308, 12001, 120178, 10242, 64564, 120179, 67986, 6584, 7749, - 11037, 0, 1758, 127092, 10667, 10560, 120197, 92593, 1935, 11517, 120193, - 120196, 120195, 1931, 120189, 74839, 120191, 1217, 64702, 12643, 825, - 127838, 194905, 12294, 92428, 78834, 9138, 78831, 78833, 12631, 78829, - 11080, 74554, 64000, 5591, 1239, 0, 11313, 0, 3403, 0, 0, 64364, 92269, - 0, 74582, 8998, 12988, 0, 9152, 983849, 0, 126484, 67589, 41850, 64290, - 3433, 92393, 12615, 1594, 42192, 6914, 67603, 0, 119569, 74565, 41353, - 67602, 67611, 4337, 0, 127296, 918, 65035, 41351, 7681, 194900, 42577, - 41393, 12668, 194904, 2477, 127285, 0, 127301, 0, 67604, 194880, 127235, - 573, 127282, 194884, 11417, 194886, 119814, 194888, 67599, 0, 194889, - 67607, 11482, 0, 3981, 3357, 0, 42223, 4207, 1288, 78842, 78839, 68419, - 78837, 11589, 42195, 194872, 194599, 127263, 64602, 67618, 92539, 0, - 42788, 68416, 64480, 194875, 8423, 3348, 448, 68476, 9717, 0, 0, 997, 0, - 0, 92577, 0, 11440, 11379, 42000, 13139, 42221, 65013, 126999, 127760, - 73796, 0, 119228, 12035, 0, 2818, 0, 74411, 73793, 0, 4172, 0, 0, 8373, - 10873, 12197, 0, 0, 92265, 69706, 0, 78210, 0, 128110, 194865, 126982, - 74563, 64828, 11419, 194868, 766, 1257, 0, 118845, 11381, 3265, 66617, - 3274, 127365, 126523, 94042, 983950, 74522, 41989, 0, 0, 128798, 3263, 0, - 65672, 0, 3270, 64539, 11489, 0, 0, 0, 0, 9505, 65518, 194776, 756, - 194605, 0, 0, 0, 7261, 0, 186, 0, 119156, 5770, 13179, 65830, 12612, - 12949, 64856, 12800, 983901, 74203, 64718, 11507, 0, 92434, 118929, 0, - 11578, 0, 119296, 0, 0, 0, 0, 74568, 9254, 0, 1794, 120217, 64521, 5624, - 120220, 120221, 119958, 120223, 3617, 66636, 64886, 94061, 120212, - 120213, 120214, 1872, 66508, 120467, 41079, 10748, 5502, 119330, 4452, 0, - 983771, 92526, 4511, 0, 983877, 64678, 11425, 0, 43245, 1231, 194783, - 69903, 0, 9003, 8192, 0, 5305, 9653, 10616, 8694, 9546, 0, 0, 120478, - 120200, 65205, 120202, 64063, 9878, 74780, 119626, 78202, 64058, 8799, - 42131, 0, 64062, 1028, 64060, 64059, 837, 10567, 0, 43103, 0, 120754, - 11427, 2902, 64043, 64042, 43749, 10756, 64047, 42606, 64045, 64044, - 43979, 10076, 64040, 43060, 194942, 1034, 3392, 127771, 43091, 64033, - 64032, 42735, 64038, 64037, 64036, 64035, 4291, 194928, 64015, 64014, - 64681, 194930, 0, 78145, 0, 43090, 0, 3476, 8973, 64012, 42473, 64010, - 64008, 64007, 2003, 7706, 64517, 78153, 2538, 64009, 204, 0, 4802, 4111, - 8239, 9098, 4805, 64001, 64057, 7885, 7247, 64054, 983266, 0, 4767, 9343, - 64049, 64048, 120034, 1133, 64053, 64052, 43453, 64050, 41340, 118975, - 194835, 10005, 12329, 41333, 0, 8489, 1942, 0, 194834, 42520, 128249, 0, - 0, 10760, 64023, 64022, 64021, 6582, 43670, 0, 64025, 9167, 42151, 78244, - 983232, 2026, 64019, 64018, 64017, 64016, 12768, 0, 7582, 78252, 78248, - 77914, 78246, 78247, 0, 77915, 78766, 6788, 13094, 77920, 7532, 41414, - 78520, 3179, 78518, 64769, 78514, 78517, 11461, 74454, 10751, 9051, - 120720, 6708, 10535, 983627, 68218, 55274, 2008, 64031, 64030, 294, - 41874, 0, 126991, 65929, 0, 0, 0, 0, 64028, 8146, 64026, 41788, 194844, - 0, 4351, 6343, 43247, 119888, 0, 119886, 119891, 119892, 119889, 11433, - 119895, 119896, 0, 7801, 65578, 194839, 12915, 43968, 3297, 9699, 194955, - 1135, 0, 0, 128525, 1995, 6722, 983925, 0, 2552, 41546, 60, 68394, 8649, - 41549, 78496, 983327, 0, 6682, 0, 78679, 64710, 41547, 983630, 2013, - 128291, 78530, 78532, 78528, 78529, 12832, 78493, 8081, 8362, 3537, - 119908, 9137, 7155, 8999, 0, 78533, 3466, 0, 0, 1996, 0, 3453, 6282, 0, - 2002, 2000, 120175, 537, 0, 4179, 65119, 1998, 0, 1842, 0, 92674, 9628, - 68446, 12081, 9826, 64502, 1767, 0, 0, 0, 120201, 983646, 0, 0, 3059, - 44024, 120204, 119953, 92693, 0, 0, 92452, 4100, 920, 1811, 1355, 0, 0, - 3592, 10078, 0, 0, 0, 8592, 65870, 68164, 128792, 10742, 0, 42918, 1994, - 9281, 3296, 12865, 1997, 1895, + 65169, 2052, 4308, 92174, 43000, 7505, 543, 64916, 64736, 118835, 0, + 64655, 0, 118922, 2064, 0, 43158, 7902, 0, 65265, 194639, 0, 127170, 0, + 983625, 92550, 0, 12994, 92728, 10828, 74378, 6228, 4307, 3482, 128527, + 0, 72389, 0, 506, 74573, 41194, 65735, 2055, 43255, 41195, 0, 8169, + 983680, 8841, 0, 516, 93974, 2063, 119051, 34, 128850, 120186, 11504, + 1612, 74333, 120182, 11827, 67165, 12001, 120178, 10242, 64564, 120179, + 67986, 6584, 7749, 11037, 128743, 1758, 119074, 10667, 10560, 120197, + 92593, 1935, 11517, 120193, 120196, 120195, 1931, 120189, 74839, 120191, + 1217, 64702, 12643, 825, 127838, 194905, 12294, 92428, 78834, 9138, + 78831, 78833, 12631, 71871, 11080, 74554, 64000, 5591, 1239, 127199, + 11313, 194803, 3403, 0, 120271, 64364, 92269, 127904, 72431, 8998, 12988, + 119983, 9152, 983849, 0, 126484, 67589, 41850, 64290, 3433, 92393, 12615, + 1594, 42192, 6914, 66392, 0, 119569, 74565, 41353, 67602, 67611, 4337, 0, + 127296, 918, 65035, 41351, 7681, 194900, 42577, 41393, 12668, 72395, + 2477, 127285, 0, 127301, 0, 67604, 67683, 127235, 573, 127282, 120543, + 11417, 194886, 119814, 119309, 67599, 0, 72410, 67607, 11482, 0, 3981, + 3357, 0, 42223, 4207, 1288, 78503, 78839, 67728, 78837, 11589, 42195, + 74477, 119997, 127263, 64602, 67618, 92539, 0, 42788, 68416, 64480, + 194875, 8423, 3348, 448, 66907, 9717, 119311, 0, 997, 0, 0, 92577, 0, + 11440, 11379, 42000, 13139, 42221, 65013, 126999, 127760, 72390, 0, + 119228, 12035, 0, 2818, 0, 74411, 73793, 0, 4172, 71252, 119992, 8373, + 10873, 12197, 125074, 195014, 92265, 69706, 128540, 6834, 127251, 128110, + 194865, 126982, 74563, 64828, 11419, 194868, 766, 1257, 194598, 118845, + 11381, 3265, 66617, 3274, 126629, 126523, 94042, 983950, 74522, 41989, 0, + 0, 113769, 3263, 0, 65672, 69243, 3270, 64539, 11489, 0, 0, 0, 0, 9505, + 65518, 128498, 756, 194605, 0, 0, 0, 7261, 92547, 186, 0, 119156, 5770, + 13179, 65830, 12612, 12949, 64856, 12800, 983901, 74203, 64718, 11507, 0, + 92434, 74626, 0, 11578, 0, 119296, 0, 0, 125101, 0, 70083, 9254, 66877, + 1794, 68310, 64521, 5624, 120220, 120221, 119958, 120223, 3617, 66636, + 64886, 94061, 68659, 120213, 120214, 1872, 66508, 120467, 41079, 10748, + 5502, 119330, 4452, 128088, 983771, 92526, 4511, 0, 983877, 64678, 11425, + 0, 43245, 1231, 92390, 69903, 0, 9003, 8192, 0, 5305, 9653, 10616, 8694, + 9546, 0, 0, 70421, 120200, 65205, 120202, 64063, 9878, 74780, 119626, + 78202, 64058, 8799, 42131, 128662, 64062, 1028, 64060, 64059, 837, 10567, + 72384, 43103, 0, 120754, 11427, 2902, 64043, 64042, 43749, 10756, 64047, + 42606, 64045, 64044, 43979, 10076, 64040, 43060, 194942, 1034, 3392, + 127771, 43091, 64033, 64032, 42735, 43498, 64037, 64036, 64035, 4291, + 129157, 64015, 64014, 64681, 194930, 127142, 78145, 71898, 43090, 0, + 3476, 8973, 64012, 42473, 64010, 64008, 64007, 2003, 7706, 64517, 78153, + 2538, 64009, 204, 0, 4802, 4111, 8239, 9098, 4805, 64001, 64057, 7885, + 7247, 64054, 983266, 0, 4767, 9343, 64049, 64048, 120034, 1133, 64053, + 64052, 43453, 64050, 41340, 118975, 194835, 10005, 12329, 41333, 0, 8489, + 1942, 0, 194834, 42520, 65510, 125044, 68291, 10760, 64023, 64022, 64021, + 6582, 43670, 127798, 64025, 9167, 42151, 78244, 983232, 2026, 64019, + 64018, 64017, 64016, 12768, 0, 7582, 78252, 78248, 77914, 78246, 78247, + 0, 77915, 78766, 6788, 13094, 77920, 7532, 41414, 78520, 3179, 78518, + 64769, 78514, 78517, 11461, 74454, 10751, 9051, 120720, 6708, 10535, + 983627, 68218, 55274, 2008, 64031, 64030, 294, 41874, 0, 64790, 65929, 0, + 129063, 0, 0, 64028, 8146, 64026, 41788, 194844, 0, 4351, 6343, 43247, + 119888, 70153, 119886, 119891, 72387, 119889, 11433, 119895, 119896, 0, + 7801, 65578, 194839, 12915, 43968, 3297, 9699, 127957, 1135, 0, 128807, + 128525, 1995, 6722, 983925, 0, 2552, 41546, 60, 68394, 8649, 41549, + 78496, 72386, 0, 6682, 983917, 78679, 43833, 41547, 983630, 2013, 128291, + 78530, 78532, 78528, 78529, 12832, 78493, 8081, 8362, 3537, 119908, 9137, + 7155, 8999, 0, 78533, 3466, 0, 0, 1996, 0, 3453, 6282, 0, 2002, 2000, + 120175, 537, 92976, 4179, 65119, 1998, 120746, 1842, 0, 92674, 9628, + 68446, 12081, 9826, 64502, 1767, 0, 0, 120001, 120201, 983646, 124975, + 127991, 3059, 44024, 120204, 43491, 92693, 0, 0, 92452, 4100, 920, 1811, + 1355, 43189, 0, 3592, 10078, 0, 78162, 119558, 8592, 65870, 66417, 74504, + 10742, 72400, 42918, 1994, 9281, 3296, 12865, 1997, 1895, }; #define code_magic 47 diff --git a/Modules/winreparse.h b/Modules/winreparse.h new file mode 100644 index 000000000000..66f7775dd2e8 --- /dev/null +++ b/Modules/winreparse.h @@ -0,0 +1,53 @@ +#ifndef Py_WINREPARSE_H +#define Py_WINREPARSE_H + +#ifdef MS_WINDOWS +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* The following structure was copied from + http://msdn.microsoft.com/en-us/library/ff552012.aspx as the required + include doesn't seem to be present in the Windows SDK (at least as included + with Visual Studio Express). */ +typedef struct _REPARSE_DATA_BUFFER { + ULONG ReparseTag; + USHORT ReparseDataLength; + USHORT Reserved; + union { + struct { + USHORT SubstituteNameOffset; + USHORT SubstituteNameLength; + USHORT PrintNameOffset; + USHORT PrintNameLength; + ULONG Flags; + WCHAR PathBuffer[1]; + } SymbolicLinkReparseBuffer; + + struct { + USHORT SubstituteNameOffset; + USHORT SubstituteNameLength; + USHORT PrintNameOffset; + USHORT PrintNameLength; + WCHAR PathBuffer[1]; + } MountPointReparseBuffer; + + struct { + UCHAR DataBuffer[1]; + } GenericReparseBuffer; + }; +} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; + +#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\ + GenericReparseBuffer) +#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 ) + +#ifdef __cplusplus +} +#endif + +#endif /* MS_WINDOWS */ + +#endif /* !Py_WINREPARSE_H */ diff --git a/Modules/xxlimited.c b/Modules/xxlimited.c index 661b6e294af3..eecdab96975d 100644 --- a/Modules/xxlimited.c +++ b/Modules/xxlimited.c @@ -44,7 +44,7 @@ static void Xxo_dealloc(XxoObject *self) { Py_XDECREF(self->x_attr); - PyObject_Del(self); + ((freefunc)PyType_GetSlot(Py_TYPE(self), Py_tp_free))(self); } static PyObject * diff --git a/Modules/zipimport.c b/Modules/zipimport.c index 8fe919539fdf..f2cc245b7d88 100644 --- a/Modules/zipimport.c +++ b/Modules/zipimport.c @@ -233,7 +233,7 @@ make_filename(PyObject *prefix, PyObject *name) Py_ssize_t len; len = PyUnicode_GET_LENGTH(prefix) + PyUnicode_GET_LENGTH(name) + 1; - p = buf = PyMem_Malloc(sizeof(Py_UCS4) * len); + p = buf = PyMem_New(Py_UCS4, len); if (buf == NULL) { PyErr_NoMemory(); return NULL; diff --git a/Modules/zlibmodule.c b/Modules/zlibmodule.c index bf8c8e4d1212..0d2e188b433d 100644 --- a/Modules/zlibmodule.c +++ b/Modules/zlibmodule.c @@ -3,6 +3,7 @@ /* Windows users: read Python's PCbuild\readme.txt */ +#define PY_SSIZE_T_CLEAN #include "Python.h" #include "structmember.h" @@ -28,10 +29,9 @@ #else # define DEF_MEM_LEVEL MAX_MEM_LEVEL #endif -#define DEF_WBITS MAX_WBITS -/* The output buffer will be increased in chunks of DEFAULTALLOC bytes. */ -#define DEFAULTALLOC (16*1024) +/* Initial buffer size. */ +#define DEF_BUF_SIZE (16*1024) static PyTypeObject Comptype; static PyTypeObject Decomptype; @@ -81,42 +81,13 @@ zlib_error(z_stream zst, int err, char *msg) PyErr_Format(ZlibError, "Error %d %s: %.200s", err, msg, zmsg); } -/*[clinic] +/*[clinic input] +output preset file module zlib -class zlib.Compress -class zlib.Decompress -[clinic]*/ -/*[clinic checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ - -PyDoc_STRVAR(compressobj__doc__, -"compressobj(level=-1, method=DEFLATED, wbits=15, memlevel=8,\n" -" strategy=Z_DEFAULT_STRATEGY[, zdict])\n" -" -- Return a compressor object.\n" -"\n" -"level is the compression level (an integer in the range 0-9; default is 6).\n" -"Higher compression levels are slower, but produce smaller results.\n" -"\n" -"method is the compression algorithm. If given, this must be DEFLATED.\n" -"\n" -"wbits is the base two logarithm of the window size (range: 8..15).\n" -"\n" -"memlevel controls the amount of memory used for internal compression state.\n" -"Valid values range from 1 to 9. Higher values result in higher memory usage,\n" -"faster compression, and smaller output.\n" -"\n" -"strategy is used to tune the compression algorithm. Possible values are\n" -"Z_DEFAULT_STRATEGY, Z_FILTERED, and Z_HUFFMAN_ONLY.\n" -"\n" -"zdict is the predefined compression dictionary - a sequence of bytes\n" -"containing subsequences that are likely to occur in the input data."); - -PyDoc_STRVAR(decompressobj__doc__, -"decompressobj([wbits[, zdict]]) -- Return a decompressor object.\n" -"\n" -"Optional arg wbits is the window buffer size.\n" -"\n" -"Optional arg zdict is the predefined compression dictionary. This must be\n" -"the same dictionary as used by the compressor that produced the input data."); +class zlib.Compress "compobject *" "&Comptype" +class zlib.Decompress "compobject *" "&Decomptype" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=bfd4c340573ba91d]*/ static compobject * newcompobject(PyTypeObject *type) @@ -164,70 +135,21 @@ PyZlib_Free(voidpf ctx, void *ptr) PyMem_RawFree(ptr); } -/*[clinic] - +/*[clinic input] zlib.compress + bytes: Py_buffer Binary data to be compressed. - [ - level: int + level: int(c_default="Z_DEFAULT_COMPRESSION") = Z_DEFAULT_COMPRESSION Compression level, in 0-9. - ] / -Returns compressed string. - -[clinic]*/ - -PyDoc_STRVAR(zlib_compress__doc__, -"compress(bytes, [level])\n" -"Returns compressed string.\n" -"\n" -" bytes\n" -" Binary data to be compressed.\n" -" level\n" -" Compression level, in 0-9."); - -#define ZLIB_COMPRESS_METHODDEF \ - {"compress", (PyCFunction)zlib_compress, METH_VARARGS, zlib_compress__doc__}, +Returns a bytes object containing compressed data. +[clinic start generated code]*/ static PyObject * -zlib_compress_impl(PyModuleDef *module, Py_buffer *bytes, int group_right_1, int level); - -static PyObject * -zlib_compress(PyModuleDef *module, PyObject *args) -{ - PyObject *return_value = NULL; - Py_buffer bytes; - int group_right_1 = 0; - int level = 0; - - switch (PyTuple_Size(args)) { - case 1: - if (!PyArg_ParseTuple(args, "y*:compress", &bytes)) - return NULL; - break; - case 2: - if (!PyArg_ParseTuple(args, "y*i:compress", &bytes, &level)) - return NULL; - group_right_1 = 1; - break; - default: - PyErr_SetString(PyExc_TypeError, "zlib.compress requires 1 to 2 arguments"); - return NULL; - } - return_value = zlib_compress_impl(module, &bytes, group_right_1, level); - - /* Cleanup for bytes */ - if (bytes.buf) - PyBuffer_Release(&bytes); - - return return_value; -} - -static PyObject * -zlib_compress_impl(PyModuleDef *module, Py_buffer *bytes, int group_right_1, int level) -/*[clinic checksum: f490708eff84be652b5ebe7fe622ab73ac12c888]*/ +zlib_compress_impl(PyModuleDef *module, Py_buffer *bytes, int level) +/*[clinic end generated code: output=5d7dd4588788efd3 input=be3abe9934bda4b3]*/ { PyObject *ReturnVal = NULL; Byte *input, *output = NULL; @@ -235,9 +157,6 @@ zlib_compress_impl(PyModuleDef *module, Py_buffer *bytes, int group_right_1, int int err; z_stream zst; - if (!group_right_1) - level = Z_DEFAULT_COMPRESSION; - if ((size_t)bytes->len > UINT_MAX) { PyErr_SetString(PyExc_OverflowError, "Size does not fit in an unsigned int"); @@ -306,17 +225,15 @@ zlib_compress_impl(PyModuleDef *module, Py_buffer *bytes, int group_right_1, int return ReturnVal; } -/*[python] +/*[python input] class uint_converter(CConverter): type = 'unsigned int' converter = 'uint_converter' + c_ignored_default = "0" -class compobject_converter(self_converter): - type = "compobject *" - -[python]*/ -/*[python checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=22263855f7a3ebfd]*/ static int uint_converter(PyObject *obj, void *ptr) @@ -329,11 +246,6 @@ uint_converter(PyObject *obj, void *ptr) uval = PyLong_AsUnsignedLong(obj); if (uval == (unsigned long)-1 && PyErr_Occurred()) return 0; - if (uval > UINT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "Python int too large for C unsigned int"); - return 0; - } } else { if (val < 0) { @@ -344,39 +256,48 @@ uint_converter(PyObject *obj, void *ptr) uval = (unsigned long)val; } + if (uval > UINT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "Python int too large for C unsigned int"); + return 0; + } + *(unsigned int *)ptr = Py_SAFE_DOWNCAST(uval, unsigned long, unsigned int); return 1; } -PyDoc_STRVAR(decompress__doc__, -"decompress(string[, wbits[, bufsize]]) -- Return decompressed string.\n" -"\n" -"Optional arg wbits is the window buffer size. Optional arg bufsize is\n" -"the initial output buffer size."); +/*[clinic input] +zlib.decompress + + data: Py_buffer + Compressed data. + wbits: int(c_default="MAX_WBITS") = MAX_WBITS + The window buffer size. + bufsize: uint(c_default="DEF_BUF_SIZE") = DEF_BUF_SIZE + The initial output buffer size. + / + +Returns a bytes object containing the uncompressed data. +[clinic start generated code]*/ static PyObject * -PyZlib_decompress(PyObject *self, PyObject *args) +zlib_decompress_impl(PyModuleDef *module, Py_buffer *data, int wbits, unsigned int bufsize) +/*[clinic end generated code: output=9e5464e72df9cb5f input=0f4b9abb7103f50e]*/ { PyObject *result_str = NULL; - Py_buffer pinput; Byte *input; unsigned int length; int err; - int wsize=DEF_WBITS; - unsigned int bufsize = DEFAULTALLOC, new_bufsize; + unsigned int new_bufsize; z_stream zst; - if (!PyArg_ParseTuple(args, "y*|iO&:decompress", - &pinput, &wsize, uint_converter, &bufsize)) - return NULL; - - if ((size_t)pinput.len > UINT_MAX) { + if ((size_t)data->len > UINT_MAX) { PyErr_SetString(PyExc_OverflowError, "Size does not fit in an unsigned int"); goto error; } - input = pinput.buf; - length = (unsigned int)pinput.len; + input = data->buf; + length = (unsigned int)data->len; if (bufsize == 0) bufsize = 1; @@ -392,7 +313,7 @@ PyZlib_decompress(PyObject *self, PyObject *args) zst.zfree = PyZlib_Free; zst.next_out = (Byte *)PyBytes_AS_STRING(result_str); zst.next_in = (Byte *)input; - err = inflateInit2(&zst, wsize); + err = inflateInit2(&zst, wbits); switch(err) { case(Z_OK): @@ -458,32 +379,45 @@ PyZlib_decompress(PyObject *self, PyObject *args) if (_PyBytes_Resize(&result_str, zst.total_out) < 0) goto error; - PyBuffer_Release(&pinput); return result_str; error: - PyBuffer_Release(&pinput); Py_XDECREF(result_str); return NULL; } +/*[clinic input] +zlib.compressobj + + level: int(c_default="Z_DEFAULT_COMPRESSION") = Z_DEFAULT_COMPRESSION + The compression level (an integer in the range 0-9; default is 6). + Higher compression levels are slower, but produce smaller results. + method: int(c_default="DEFLATED") = DEFLATED + The compression algorithm. If given, this must be DEFLATED. + wbits: int(c_default="MAX_WBITS") = MAX_WBITS + The base two logarithm of the window size (range: 8..15). + memLevel: int(c_default="DEF_MEM_LEVEL") = DEF_MEM_LEVEL + Controls the amount of memory used for internal compression state. + Valid values range from 1 to 9. Higher values result in higher memory + usage, faster compression, and smaller output. + strategy: int(c_default="Z_DEFAULT_STRATEGY") = Z_DEFAULT_STRATEGY + Used to tune the compression algorithm. Possible values are + Z_DEFAULT_STRATEGY, Z_FILTERED, and Z_HUFFMAN_ONLY. + zdict: Py_buffer = None + The predefined compression dictionary - a sequence of bytes + containing subsequences that are likely to occur in the input data. + +Return a compressor object. +[clinic start generated code]*/ + static PyObject * -PyZlib_compressobj(PyObject *selfptr, PyObject *args, PyObject *kwargs) +zlib_compressobj_impl(PyModuleDef *module, int level, int method, int wbits, int memLevel, int strategy, Py_buffer *zdict) +/*[clinic end generated code: output=89e5a6c1449caa9e input=b034847f8821f6af]*/ { compobject *self = NULL; - int level=Z_DEFAULT_COMPRESSION, method=DEFLATED; - int wbits=MAX_WBITS, memLevel=DEF_MEM_LEVEL, strategy=0, err; - Py_buffer zdict; - static char *kwlist[] = {"level", "method", "wbits", - "memLevel", "strategy", "zdict", NULL}; - - zdict.buf = NULL; /* Sentinel, so we can tell whether zdict was supplied. */ - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iiiiiy*:compressobj", - kwlist, &level, &method, &wbits, - &memLevel, &strategy, &zdict)) - return NULL; + int err; - if (zdict.buf != NULL && (size_t)zdict.len > UINT_MAX) { + if (zdict->buf != NULL && (size_t)zdict->len > UINT_MAX) { PyErr_SetString(PyExc_OverflowError, "zdict length does not fit in an unsigned int"); goto error; @@ -501,11 +435,11 @@ PyZlib_compressobj(PyObject *selfptr, PyObject *args, PyObject *kwargs) switch(err) { case (Z_OK): self->is_initialised = 1; - if (zdict.buf == NULL) { + if (zdict->buf == NULL) { goto success; } else { err = deflateSetDictionary(&self->zst, - zdict.buf, (unsigned int)zdict.len); + zdict->buf, (unsigned int)zdict->len); switch (err) { case (Z_OK): goto success; @@ -530,25 +464,30 @@ PyZlib_compressobj(PyObject *selfptr, PyObject *args, PyObject *kwargs) } error: - Py_XDECREF(self); - self = NULL; + Py_CLEAR(self); success: - if (zdict.buf != NULL) - PyBuffer_Release(&zdict); return (PyObject*)self; } +/*[clinic input] +zlib.decompressobj + + wbits: int(c_default="MAX_WBITS") = MAX_WBITS + The window buffer size. + zdict: object(c_default="NULL") = b'' + The predefined compression dictionary. This must be the same + dictionary as used by the compressor that produced the input data. + +Return a decompressor object. +[clinic start generated code]*/ + static PyObject * -PyZlib_decompressobj(PyObject *selfptr, PyObject *args, PyObject *kwargs) +zlib_decompressobj_impl(PyModuleDef *module, int wbits, PyObject *zdict) +/*[clinic end generated code: output=8ccd583fbd631798 input=67f05145a6920127]*/ { - static char *kwlist[] = {"wbits", "zdict", NULL}; - int wbits=DEF_WBITS, err; + int err; compobject *self; - PyObject *zdict=NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iO:decompressobj", - kwlist, &wbits, &zdict)) - return NULL; if (zdict != NULL && !PyObject_CheckBuffer(zdict)) { PyErr_SetString(PyExc_TypeError, "zdict argument must support the buffer protocol"); @@ -616,37 +555,41 @@ Decomp_dealloc(compobject *self) Dealloc(self); } -PyDoc_STRVAR(comp_compress__doc__, -"compress(data) -- Return a string containing data compressed.\n" -"\n" -"After calling this function, some of the input data may still\n" -"be stored in internal buffers for later processing.\n" -"Call the flush() method to clear these buffers."); +/*[clinic input] +zlib.Compress.compress + + data: Py_buffer + Binary data to be compressed. + / +Returns a bytes object containing compressed data. + +After calling this function, some of the input data may still +be stored in internal buffers for later processing. +Call the flush() method to clear these buffers. +[clinic start generated code]*/ static PyObject * -PyZlib_objcompress(compobject *self, PyObject *args) +zlib_Compress_compress_impl(compobject *self, Py_buffer *data) +/*[clinic end generated code: output=5d5cd791cbc6a7f4 input=0d95908d6e64fab8]*/ { int err; unsigned int inplen; - unsigned int length = DEFAULTALLOC, new_length; - PyObject *RetVal = NULL; - Py_buffer pinput; + unsigned int length = DEF_BUF_SIZE, new_length; + PyObject *RetVal; Byte *input; unsigned long start_total_out; - if (!PyArg_ParseTuple(args, "y*:compress", &pinput)) - return NULL; - if ((size_t)pinput.len > UINT_MAX) { + if ((size_t)data->len > UINT_MAX) { PyErr_SetString(PyExc_OverflowError, "Size does not fit in an unsigned int"); - goto error_outer; + return NULL; } - input = pinput.buf; - inplen = (unsigned int)pinput.len; + input = data->buf; + inplen = (unsigned int)data->len; if (!(RetVal = PyBytes_FromStringAndSize(NULL, length))) - goto error_outer; + return NULL; ENTER_ZLIB(self); @@ -669,7 +612,7 @@ PyZlib_objcompress(compobject *self, PyObject *args) new_length = UINT_MAX; if (_PyBytes_Resize(&RetVal, new_length) < 0) { Py_CLEAR(RetVal); - goto error; + goto done; } self->zst.next_out = (unsigned char *)PyBytes_AS_STRING(RetVal) + length; @@ -687,18 +630,15 @@ PyZlib_objcompress(compobject *self, PyObject *args) if (err != Z_OK && err != Z_BUF_ERROR) { zlib_error(self->zst, err, "while compressing data"); - Py_DECREF(RetVal); - RetVal = NULL; - goto error; + Py_CLEAR(RetVal); + goto done; } if (_PyBytes_Resize(&RetVal, self->zst.total_out - start_total_out) < 0) { Py_CLEAR(RetVal); } - error: + done: LEAVE_ZLIB(self); - error_outer: - PyBuffer_Release(&pinput); return RetVal; } @@ -745,12 +685,9 @@ save_unconsumed_input(compobject *self, int err) return 0; } -/*[clinic] - +/*[clinic input] zlib.Decompress.decompress - self: compobject - data: Py_buffer The binary data to decompress. max_length: uint = 0 @@ -759,61 +696,19 @@ zlib.Decompress.decompress the unconsumed_tail attribute. / -Return a string containing the decompressed version of the data. +Return a bytes object containing the decompressed version of the data. After calling this function, some of the input data may still be stored in internal buffers for later processing. Call the flush() method to clear these buffers. -[clinic]*/ - -PyDoc_STRVAR(zlib_Decompress_decompress__doc__, -"decompress(data, max_length=0)\n" -"Return a string containing the decompressed version of the data.\n" -"\n" -" data\n" -" The binary data to decompress.\n" -" max_length\n" -" The maximum allowable length of the decompressed data.\n" -" Unconsumed input data will be stored in\n" -" the unconsumed_tail attribute.\n" -"\n" -"After calling this function, some of the input data may still be stored in\n" -"internal buffers for later processing.\n" -"Call the flush() method to clear these buffers."); - -#define ZLIB_DECOMPRESS_DECOMPRESS_METHODDEF \ - {"decompress", (PyCFunction)zlib_Decompress_decompress, METH_VARARGS, zlib_Decompress_decompress__doc__}, - -static PyObject * -zlib_Decompress_decompress_impl(compobject *self, Py_buffer *data, unsigned int max_length); - -static PyObject * -zlib_Decompress_decompress(PyObject *self, PyObject *args) -{ - PyObject *return_value = NULL; - Py_buffer data; - unsigned int max_length = 0; - - if (!PyArg_ParseTuple(args, - "y*|O&:decompress", - &data, uint_converter, &max_length)) - goto exit; - return_value = zlib_Decompress_decompress_impl((compobject *)self, &data, max_length); - -exit: - /* Cleanup for data */ - if (data.buf) - PyBuffer_Release(&data); - - return return_value; -} +[clinic start generated code]*/ static PyObject * zlib_Decompress_decompress_impl(compobject *self, Py_buffer *data, unsigned int max_length) -/*[clinic checksum: 3599698948f5a712f5a8309491671cc2ce969d2c]*/ +/*[clinic end generated code: output=755cccc9087bfe55 input=02cfc047377cec86]*/ { int err; - unsigned int old_length, length = DEFAULTALLOC; + unsigned int old_length, length = DEF_BUF_SIZE; PyObject *RetVal = NULL; unsigned long start_total_out; @@ -930,29 +825,31 @@ zlib_Decompress_decompress_impl(compobject *self, Py_buffer *data, unsigned int return RetVal; } -PyDoc_STRVAR(comp_flush__doc__, -"flush( [mode] ) -- Return a string containing any remaining compressed data.\n" -"\n" -"mode can be one of the constants Z_SYNC_FLUSH, Z_FULL_FLUSH, Z_FINISH; the\n" -"default value used when mode is not specified is Z_FINISH.\n" -"If mode == Z_FINISH, the compressor object can no longer be used after\n" -"calling the flush() method. Otherwise, more data can still be compressed."); +/*[clinic input] +zlib.Compress.flush + + mode: int(c_default="Z_FINISH") = zlib.Z_FINISH + One of the constants Z_SYNC_FLUSH, Z_FULL_FLUSH, Z_FINISH. + If mode == Z_FINISH, the compressor object can no longer be + used after calling the flush() method. Otherwise, more data + can still be compressed. + / + +Return a bytes object containing any remaining compressed data. +[clinic start generated code]*/ static PyObject * -PyZlib_flush(compobject *self, PyObject *args) +zlib_Compress_flush_impl(compobject *self, int mode) +/*[clinic end generated code: output=a203f4cefc9de727 input=73ed066794bd15bc]*/ { int err; - unsigned int length = DEFAULTALLOC, new_length; + unsigned int length = DEF_BUF_SIZE, new_length; PyObject *RetVal; - int flushmode = Z_FINISH; unsigned long start_total_out; - if (!PyArg_ParseTuple(args, "|i:flush", &flushmode)) - return NULL; - /* Flushing with Z_NO_FLUSH is a no-op, so there's no point in doing any work at all; just return an empty string. */ - if (flushmode == Z_NO_FLUSH) { + if (mode == Z_NO_FLUSH) { return PyBytes_FromStringAndSize(NULL, 0); } @@ -967,7 +864,7 @@ PyZlib_flush(compobject *self, PyObject *args) self->zst.next_out = (unsigned char *)PyBytes_AS_STRING(RetVal); Py_BEGIN_ALLOW_THREADS - err = deflate(&(self->zst), flushmode); + err = deflate(&(self->zst), mode); Py_END_ALLOW_THREADS /* while Z_OK and the output buffer is full, there might be more output, @@ -987,14 +884,14 @@ PyZlib_flush(compobject *self, PyObject *args) length = new_length; Py_BEGIN_ALLOW_THREADS - err = deflate(&(self->zst), flushmode); + err = deflate(&(self->zst), mode); Py_END_ALLOW_THREADS } - /* If flushmode is Z_FINISH, we also have to call deflateEnd() to free + /* If mode is Z_FINISH, we also have to call deflateEnd() to free various data structures. Note we should only get Z_STREAM_END when - flushmode is Z_FINISH, but checking both for safety*/ - if (err == Z_STREAM_END && flushmode == Z_FINISH) { + mode is Z_FINISH, but checking both for safety*/ + if (err == Z_STREAM_END && mode == Z_FINISH) { err = deflateEnd(&(self->zst)); if (err != Z_OK) { zlib_error(self->zst, err, "while finishing compression"); @@ -1028,24 +925,15 @@ PyZlib_flush(compobject *self, PyObject *args) #ifdef HAVE_ZLIB_COPY -/*[clinic] +/*[clinic input] zlib.Compress.copy - self: compobject - Return a copy of the compression object. -[clinic]*/ - -PyDoc_STRVAR(zlib_Compress_copy__doc__, -"copy()\n" -"Return a copy of the compression object."); - -#define ZLIB_COMPRESS_COPY_METHODDEF \ - {"copy", (PyCFunction)zlib_Compress_copy, METH_NOARGS, zlib_Compress_copy__doc__}, +[clinic start generated code]*/ static PyObject * -zlib_Compress_copy(compobject *self) -/*[clinic checksum: 0b37c07f8f27deb7d4769951fbecf600a1006ef8]*/ +zlib_Compress_copy_impl(compobject *self) +/*[clinic end generated code: output=5144aa153c21e805 input=c656351f94b82718]*/ { compobject *retval = NULL; int err; @@ -1095,11 +983,15 @@ zlib_Compress_copy(compobject *self) return NULL; } -PyDoc_STRVAR(decomp_copy__doc__, -"copy() -- Return a copy of the decompression object."); +/*[clinic input] +zlib.Decompress.copy + +Return a copy of the decompression object. +[clinic start generated code]*/ static PyObject * -PyZlib_uncopy(compobject *self) +zlib_Decompress_copy_impl(compobject *self) +/*[clinic end generated code: output=02a883a2a510c8cc input=ba6c3e96712a596b]*/ { compobject *retval = NULL; int err; @@ -1151,24 +1043,26 @@ PyZlib_uncopy(compobject *self) } #endif -PyDoc_STRVAR(decomp_flush__doc__, -"flush( [length] ) -- Return a string containing any remaining\n" -"decompressed data. length, if given, is the initial size of the\n" -"output buffer.\n" -"\n" -"The decompressor object can no longer be used after this call."); +/*[clinic input] +zlib.Decompress.flush + + length: uint(c_default="DEF_BUF_SIZE") = zlib.DEF_BUF_SIZE + the initial size of the output buffer. + / + +Return a bytes object containing any remaining decompressed data. +[clinic start generated code]*/ static PyObject * -PyZlib_unflush(compobject *self, PyObject *args) +zlib_Decompress_flush_impl(compobject *self, unsigned int length) +/*[clinic end generated code: output=db6fb753ab698e22 input=1580956505978993]*/ { int err; - unsigned int length = DEFAULTALLOC, new_length; + unsigned int new_length; PyObject * retval = NULL; unsigned long start_total_out; Py_ssize_t size; - if (!PyArg_ParseTuple(args, "|O&:flush", uint_converter, &length)) - return NULL; if (length == 0) { PyErr_SetString(PyExc_ValueError, "length must be greater than zero"); return NULL; @@ -1244,12 +1138,12 @@ PyZlib_unflush(compobject *self, PyObject *args) return retval; } +#include "clinic/zlibmodule.c.h" + static PyMethodDef comp_methods[] = { - {"compress", (binaryfunc)PyZlib_objcompress, METH_VARARGS, - comp_compress__doc__}, - {"flush", (binaryfunc)PyZlib_flush, METH_VARARGS, - comp_flush__doc__}, + ZLIB_COMPRESS_COMPRESS_METHODDEF + ZLIB_COMPRESS_FLUSH_METHODDEF #ifdef HAVE_ZLIB_COPY ZLIB_COMPRESS_COPY_METHODDEF #endif @@ -1259,11 +1153,9 @@ static PyMethodDef comp_methods[] = static PyMethodDef Decomp_methods[] = { ZLIB_DECOMPRESS_DECOMPRESS_METHODDEF - {"flush", (binaryfunc)PyZlib_unflush, METH_VARARGS, - decomp_flush__doc__}, + ZLIB_DECOMPRESS_FLUSH_METHODDEF #ifdef HAVE_ZLIB_COPY - {"copy", (PyCFunction)PyZlib_uncopy, METH_NOARGS, - decomp_copy__doc__}, + ZLIB_DECOMPRESS_COPY_METHODDEF #endif {NULL, NULL} }; @@ -1276,95 +1168,95 @@ static PyMemberDef Decomp_members[] = { {NULL}, }; -PyDoc_STRVAR(adler32__doc__, -"adler32(string[, start]) -- Compute an Adler-32 checksum of string.\n" -"\n" -"An optional starting value can be specified. The returned checksum is\n" -"an integer."); +/*[clinic input] +zlib.adler32 + + data: Py_buffer + value: unsigned_int(bitwise=True) = 1 + Starting value of the checksum. + / + +Compute an Adler-32 checksum of data. + +The returned checksum is an integer. +[clinic start generated code]*/ static PyObject * -PyZlib_adler32(PyObject *self, PyObject *args) +zlib_adler32_impl(PyModuleDef *module, Py_buffer *data, unsigned int value) +/*[clinic end generated code: output=51d6d75ee655c78a input=6ff4557872160e88]*/ { - unsigned int adler32val = 1; /* adler32(0L, Z_NULL, 0) */ - Py_buffer pbuf; - - if (!PyArg_ParseTuple(args, "y*|I:adler32", &pbuf, &adler32val)) - return NULL; /* Releasing the GIL for very small buffers is inefficient and may lower performance */ - if (pbuf.len > 1024*5) { - unsigned char *buf = pbuf.buf; - Py_ssize_t len = pbuf.len; + if (data->len > 1024*5) { + unsigned char *buf = data->buf; + Py_ssize_t len = data->len; Py_BEGIN_ALLOW_THREADS /* Avoid truncation of length for very large buffers. adler32() takes length as an unsigned int, which may be narrower than Py_ssize_t. */ while ((size_t)len > UINT_MAX) { - adler32val = adler32(adler32val, buf, UINT_MAX); + value = adler32(value, buf, UINT_MAX); buf += (size_t) UINT_MAX; len -= (size_t) UINT_MAX; } - adler32val = adler32(adler32val, buf, (unsigned int)len); + value = adler32(value, buf, (unsigned int)len); Py_END_ALLOW_THREADS } else { - adler32val = adler32(adler32val, pbuf.buf, (unsigned int)pbuf.len); + value = adler32(value, data->buf, (unsigned int)data->len); } - PyBuffer_Release(&pbuf); - return PyLong_FromUnsignedLong(adler32val & 0xffffffffU); + return PyLong_FromUnsignedLong(value & 0xffffffffU); } -PyDoc_STRVAR(crc32__doc__, -"crc32(string[, start]) -- Compute a CRC-32 checksum of string.\n" -"\n" -"An optional starting value can be specified. The returned checksum is\n" -"an integer."); +/*[clinic input] +zlib.crc32 + + data: Py_buffer + value: unsigned_int(bitwise=True) = 0 + Starting value of the checksum. + / + +Compute a CRC-32 checksum of data. + +The returned checksum is an integer. +[clinic start generated code]*/ static PyObject * -PyZlib_crc32(PyObject *self, PyObject *args) +zlib_crc32_impl(PyModuleDef *module, Py_buffer *data, unsigned int value) +/*[clinic end generated code: output=c1e986e74fe7b623 input=26c3ed430fa00b4c]*/ { - unsigned int crc32val = 0; /* crc32(0L, Z_NULL, 0) */ - Py_buffer pbuf; int signed_val; - if (!PyArg_ParseTuple(args, "y*|I:crc32", &pbuf, &crc32val)) - return NULL; /* Releasing the GIL for very small buffers is inefficient and may lower performance */ - if (pbuf.len > 1024*5) { - unsigned char *buf = pbuf.buf; - Py_ssize_t len = pbuf.len; + if (data->len > 1024*5) { + unsigned char *buf = data->buf; + Py_ssize_t len = data->len; Py_BEGIN_ALLOW_THREADS /* Avoid truncation of length for very large buffers. crc32() takes length as an unsigned int, which may be narrower than Py_ssize_t. */ while ((size_t)len > UINT_MAX) { - crc32val = crc32(crc32val, buf, UINT_MAX); + value = crc32(value, buf, UINT_MAX); buf += (size_t) UINT_MAX; len -= (size_t) UINT_MAX; } - signed_val = crc32(crc32val, buf, (unsigned int)len); + signed_val = crc32(value, buf, (unsigned int)len); Py_END_ALLOW_THREADS } else { - signed_val = crc32(crc32val, pbuf.buf, (unsigned int)pbuf.len); + signed_val = crc32(value, data->buf, (unsigned int)data->len); } - PyBuffer_Release(&pbuf); return PyLong_FromUnsignedLong(signed_val & 0xffffffffU); } static PyMethodDef zlib_methods[] = { - {"adler32", (PyCFunction)PyZlib_adler32, METH_VARARGS, - adler32__doc__}, + ZLIB_ADLER32_METHODDEF ZLIB_COMPRESS_METHODDEF - {"compressobj", (PyCFunction)PyZlib_compressobj, METH_VARARGS|METH_KEYWORDS, - compressobj__doc__}, - {"crc32", (PyCFunction)PyZlib_crc32, METH_VARARGS, - crc32__doc__}, - {"decompress", (PyCFunction)PyZlib_decompress, METH_VARARGS, - decompress__doc__}, - {"decompressobj", (PyCFunction)PyZlib_decompressobj, METH_VARARGS|METH_KEYWORDS, - decompressobj__doc__}, + ZLIB_COMPRESSOBJ_METHODDEF + ZLIB_CRC32_METHODDEF + ZLIB_DECOMPRESS_METHODDEF + ZLIB_DECOMPRESSOBJ_METHODDEF {NULL, NULL} }; @@ -1478,6 +1370,7 @@ PyInit_zlib(void) PyModule_AddIntMacro(m, MAX_WBITS); PyModule_AddIntMacro(m, DEFLATED); PyModule_AddIntMacro(m, DEF_MEM_LEVEL); + PyModule_AddIntMacro(m, DEF_BUF_SIZE); PyModule_AddIntMacro(m, Z_BEST_SPEED); PyModule_AddIntMacro(m, Z_BEST_COMPRESSION); PyModule_AddIntMacro(m, Z_DEFAULT_COMPRESSION); diff --git a/Objects/README b/Objects/README new file mode 100644 index 000000000000..854b103f7bd6 --- /dev/null +++ b/Objects/README @@ -0,0 +1 @@ +Source files for various builtin objects diff --git a/Objects/abstract.c b/Objects/abstract.c index 91df5da65579..06e33829e818 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -250,28 +250,7 @@ PyObject_AsCharBuffer(PyObject *obj, const char **buffer, Py_ssize_t *buffer_len) { - PyBufferProcs *pb; - Py_buffer view; - - if (obj == NULL || buffer == NULL || buffer_len == NULL) { - null_error(); - return -1; - } - pb = obj->ob_type->tp_as_buffer; - if (pb == NULL || pb->bf_getbuffer == NULL) { - PyErr_SetString(PyExc_TypeError, - "expected bytes, bytearray " - "or buffer compatible object"); - return -1; - } - if ((*pb->bf_getbuffer)(obj, &view, PyBUF_SIMPLE)) return -1; - - *buffer = view.buf; - *buffer_len = view.len; - if (pb->bf_releasebuffer != NULL) - (*pb->bf_releasebuffer)(obj, &view); - Py_XDECREF(view.obj); - return 0; + return PyObject_AsReadBuffer(obj, (const void **)buffer, buffer_len); } int @@ -295,28 +274,18 @@ int PyObject_AsReadBuffer(PyObject *obj, const void **buffer, Py_ssize_t *buffer_len) { - PyBufferProcs *pb; Py_buffer view; if (obj == NULL || buffer == NULL || buffer_len == NULL) { null_error(); return -1; } - pb = obj->ob_type->tp_as_buffer; - if (pb == NULL || - pb->bf_getbuffer == NULL) { - PyErr_SetString(PyExc_TypeError, - "expected an object with a buffer interface"); + if (PyObject_GetBuffer(obj, &view, PyBUF_SIMPLE) != 0) return -1; - } - - if ((*pb->bf_getbuffer)(obj, &view, PyBUF_SIMPLE)) return -1; *buffer = view.buf; *buffer_len = view.len; - if (pb->bf_releasebuffer != NULL) - (*pb->bf_releasebuffer)(obj, &view); - Py_XDECREF(view.obj); + PyBuffer_Release(&view); return 0; } @@ -336,15 +305,13 @@ int PyObject_AsWriteBuffer(PyObject *obj, pb->bf_getbuffer == NULL || ((*pb->bf_getbuffer)(obj, &view, PyBUF_WRITABLE) != 0)) { PyErr_SetString(PyExc_TypeError, - "expected an object with a writable buffer interface"); + "expected a writable bytes-like object"); return -1; } *buffer = view.buf; *buffer_len = view.len; - if (pb->bf_releasebuffer != NULL) - (*pb->bf_releasebuffer)(obj, &view); - Py_XDECREF(view.obj); + PyBuffer_Release(&view); return 0; } @@ -353,13 +320,15 @@ int PyObject_AsWriteBuffer(PyObject *obj, int PyObject_GetBuffer(PyObject *obj, Py_buffer *view, int flags) { - if (!PyObject_CheckBuffer(obj)) { + PyBufferProcs *pb = obj->ob_type->tp_as_buffer; + + if (pb == NULL || pb->bf_getbuffer == NULL) { PyErr_Format(PyExc_TypeError, - "'%.100s' does not support the buffer interface", + "a bytes-like object is required, not '%.100s'", Py_TYPE(obj)->tp_name); return -1; } - return (*(obj->ob_type->tp_as_buffer->bf_getbuffer))(obj, view, flags); + return (*pb->bf_getbuffer)(obj, view, flags); } static int @@ -368,16 +337,35 @@ _IsFortranContiguous(const Py_buffer *view) Py_ssize_t sd, dim; int i; - if (view->ndim == 0) return 1; - if (view->strides == NULL) return (view->ndim == 1); + /* 1) len = product(shape) * itemsize + 2) itemsize > 0 + 3) len = 0 <==> exists i: shape[i] = 0 */ + if (view->len == 0) return 1; + if (view->strides == NULL) { /* C-contiguous by definition */ + /* Trivially F-contiguous */ + if (view->ndim <= 1) return 1; + + /* ndim > 1 implies shape != NULL */ + assert(view->shape != NULL); + + /* Effectively 1-d */ + sd = 0; + for (i=0; indim; i++) { + if (view->shape[i] > 1) sd += 1; + } + return sd <= 1; + } + + /* strides != NULL implies both of these */ + assert(view->ndim > 0); + assert(view->shape != NULL); sd = view->itemsize; - if (view->ndim == 1) return (view->shape[0] == 1 || - sd == view->strides[0]); for (i=0; indim; i++) { dim = view->shape[i]; - if (dim == 0) return 1; - if (view->strides[i] != sd) return 0; + if (dim > 1 && view->strides[i] != sd) { + return 0; + } sd *= dim; } return 1; @@ -389,16 +377,22 @@ _IsCContiguous(const Py_buffer *view) Py_ssize_t sd, dim; int i; - if (view->ndim == 0) return 1; - if (view->strides == NULL) return 1; + /* 1) len = product(shape) * itemsize + 2) itemsize > 0 + 3) len = 0 <==> exists i: shape[i] = 0 */ + if (view->len == 0) return 1; + if (view->strides == NULL) return 1; /* C-contiguous by definition */ + + /* strides != NULL implies both of these */ + assert(view->ndim > 0); + assert(view->shape != NULL); sd = view->itemsize; - if (view->ndim == 1) return (view->shape[0] == 1 || - sd == view->strides[0]); for (i=view->ndim-1; i>=0; i--) { dim = view->shape[i]; - if (dim == 0) return 1; - if (view->strides[i] != sd) return 0; + if (dim > 1 && view->strides[i] != sd) { + return 0; + } sd *= dim; } return 1; @@ -488,7 +482,7 @@ PyBuffer_FromContiguous(Py_buffer *view, void *buf, Py_ssize_t len, char fort) /* Otherwise a more elaborate scheme is needed */ - /* XXX(nnorwitz): need to check for overflow! */ + /* view->ndim <= 64 */ indices = (Py_ssize_t *)PyMem_Malloc(sizeof(Py_ssize_t)*(view->ndim)); if (indices == NULL) { PyErr_NoMemory(); @@ -510,10 +504,10 @@ PyBuffer_FromContiguous(Py_buffer *view, void *buf, Py_ssize_t len, char fort) */ elements = len / view->itemsize; while (elements--) { - addone(view->ndim, indices, view->shape); ptr = PyBuffer_GetPointer(view, indices); memcpy(ptr, src, view->itemsize); src += view->itemsize; + addone(view->ndim, indices, view->shape); } PyMem_Free(indices); @@ -530,8 +524,8 @@ int PyObject_CopyData(PyObject *dest, PyObject *src) if (!PyObject_CheckBuffer(dest) || !PyObject_CheckBuffer(src)) { PyErr_SetString(PyExc_TypeError, - "both destination and source must have the "\ - "buffer interface"); + "both destination and source must be "\ + "bytes-like objects"); return -1; } @@ -618,7 +612,12 @@ int PyBuffer_FillInfo(Py_buffer *view, PyObject *obj, void *buf, Py_ssize_t len, int readonly, int flags) { - if (view == NULL) return 0; /* XXX why not -1? */ + if (view == NULL) { + PyErr_SetString(PyExc_BufferError, + "PyBuffer_FillInfo: view==NULL argument is obsolete"); + return -1; + } + if (((flags & PyBUF_WRITABLE) == PyBUF_WRITABLE) && (readonly == 1)) { PyErr_SetString(PyExc_BufferError, @@ -652,10 +651,14 @@ void PyBuffer_Release(Py_buffer *view) { PyObject *obj = view->obj; - if (obj && Py_TYPE(obj)->tp_as_buffer && Py_TYPE(obj)->tp_as_buffer->bf_releasebuffer) - Py_TYPE(obj)->tp_as_buffer->bf_releasebuffer(obj, view); - Py_XDECREF(obj); + PyBufferProcs *pb; + if (obj == NULL) + return; + pb = Py_TYPE(obj)->tp_as_buffer; + if (pb && pb->bf_releasebuffer) + pb->bf_releasebuffer(obj, view); view->obj = NULL; + Py_DECREF(obj); } PyObject * @@ -687,8 +690,9 @@ PyObject_Format(PyObject *obj, PyObject *format_spec) Py_DECREF(meth); if (result && !PyUnicode_Check(result)) { - PyErr_SetString(PyExc_TypeError, - "__format__ method did not return string"); + PyErr_Format(PyExc_TypeError, + "__format__ must return a str, not %.200s", + Py_TYPE(result)->tp_name); Py_DECREF(result); result = NULL; goto done; @@ -931,6 +935,12 @@ PyNumber_Multiply(PyObject *v, PyObject *w) return result; } +PyObject * +PyNumber_MatrixMultiply(PyObject *v, PyObject *w) +{ + return binary_op(v, w, NB_SLOT(nb_matrix_multiply), "@"); +} + PyObject * PyNumber_FloorDivide(PyObject *v, PyObject *w) { @@ -1012,6 +1022,7 @@ INPLACE_BINOP(PyNumber_InPlaceAnd, nb_inplace_and, nb_and, "&=") INPLACE_BINOP(PyNumber_InPlaceLshift, nb_inplace_lshift, nb_lshift, "<<=") INPLACE_BINOP(PyNumber_InPlaceRshift, nb_inplace_rshift, nb_rshift, ">>=") INPLACE_BINOP(PyNumber_InPlaceSubtract, nb_inplace_subtract, nb_subtract, "-=") +INPLACE_BINOP(PyNumber_InMatrixMultiply, nb_inplace_matrix_multiply, nb_matrix_multiply, "@=") PyObject * PyNumber_InPlaceFloorDivide(PyObject *v, PyObject *w) @@ -1077,6 +1088,13 @@ PyNumber_InPlaceMultiply(PyObject *v, PyObject *w) return result; } +PyObject * +PyNumber_InPlaceMatrixMultiply(PyObject *v, PyObject *w) +{ + return binary_iop(v, w, NB_SLOT(nb_inplace_matrix_multiply), + NB_SLOT(nb_matrix_multiply), "@="); +} + PyObject * PyNumber_InPlaceRemainder(PyObject *v, PyObject *w) { @@ -1155,7 +1173,7 @@ PyNumber_Absolute(PyObject *o) return type_error("bad operand type for abs(): '%.200s'", o); } -/* Return a Python int from the object item +/* Return a Python int from the object item. Raise TypeError if the result is not an int or if the object cannot be interpreted as an index. */ @@ -1169,21 +1187,30 @@ PyNumber_Index(PyObject *item) Py_INCREF(item); return item; } - if (PyIndex_Check(item)) { - result = item->ob_type->tp_as_number->nb_index(item); - if (result && !PyLong_Check(result)) { - PyErr_Format(PyExc_TypeError, - "__index__ returned non-int " - "(type %.200s)", - result->ob_type->tp_name); - Py_DECREF(result); - return NULL; - } - } - else { + if (!PyIndex_Check(item)) { PyErr_Format(PyExc_TypeError, "'%.200s' object cannot be interpreted " "as an integer", item->ob_type->tp_name); + return NULL; + } + result = item->ob_type->tp_as_number->nb_index(item); + if (!result || PyLong_CheckExact(result)) + return result; + if (!PyLong_Check(result)) { + PyErr_Format(PyExc_TypeError, + "__index__ returned non-int (type %.200s)", + result->ob_type->tp_name); + Py_DECREF(result); + return NULL; + } + /* Issue #17576: warn if 'result' not of exact type int. */ + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "__index__ returned non-int (type %.200s). " + "The ability to return an instance of a strict subclass of int " + "is deprecated, and may be removed in a future version of Python.", + result->ob_type->tp_name)) { + Py_DECREF(result); + return NULL; } return result; } @@ -1235,41 +1262,12 @@ PyNumber_AsSsize_t(PyObject *item, PyObject *err) } -/* - Returns the Integral instance converted to an int. The instance is expected - to be an int or have an __int__ method. Steals integral's - reference. error_format will be used to create the TypeError if integral - isn't actually an Integral instance. error_format should be a format string - that can accept a char* naming integral's type. -*/ -static PyObject * -convert_integral_to_int(PyObject *integral, const char *error_format) -{ - PyNumberMethods *nb; - if (PyLong_Check(integral)) - return integral; - nb = Py_TYPE(integral)->tp_as_number; - if (nb->nb_int) { - PyObject *as_int = nb->nb_int(integral); - if (!as_int || PyLong_Check(as_int)) { - Py_DECREF(integral); - return as_int; - } - Py_DECREF(as_int); - } - PyErr_Format(PyExc_TypeError, error_format, Py_TYPE(integral)->tp_name); - Py_DECREF(integral); - return NULL; -} - - PyObject * PyNumber_Long(PyObject *o) { PyNumberMethods *m; PyObject *trunc_func; - const char *buffer; - Py_ssize_t buffer_len; + Py_buffer view; _Py_IDENTIFIER(__trunc__); if (o == NULL) @@ -1280,49 +1278,49 @@ PyNumber_Long(PyObject *o) } m = o->ob_type->tp_as_number; if (m && m->nb_int) { /* This should include subclasses of int */ - PyObject *res = m->nb_int(o); - if (res && !PyLong_Check(res)) { - PyErr_Format(PyExc_TypeError, - "__int__ returned non-int (type %.200s)", - res->ob_type->tp_name); - Py_DECREF(res); - return NULL; - } - return res; + return (PyObject *)_PyLong_FromNbInt(o); } - if (PyLong_Check(o)) /* An int subclass without nb_int */ - return _PyLong_Copy((PyLongObject *)o); trunc_func = _PyObject_LookupSpecial(o, &PyId___trunc__); if (trunc_func) { PyObject *truncated = PyEval_CallObject(trunc_func, NULL); PyObject *int_instance; Py_DECREF(trunc_func); - if (truncated == NULL) - return NULL; + if (truncated == NULL || PyLong_Check(truncated)) + return truncated; /* __trunc__ is specified to return an Integral type, but int() needs to return a int. */ - int_instance = convert_integral_to_int(truncated, - "__trunc__ returned non-Integral (type %.200s)"); + m = truncated->ob_type->tp_as_number; + if (m == NULL || m->nb_int == NULL) { + PyErr_Format( + PyExc_TypeError, + "__trunc__ returned non-Integral (type %.200s)", + truncated->ob_type->tp_name); + Py_DECREF(truncated); + return NULL; + } + int_instance = (PyObject *)_PyLong_FromNbInt(truncated); + Py_DECREF(truncated); return int_instance; } if (PyErr_Occurred()) return NULL; - if (PyBytes_Check(o)) + if (PyUnicode_Check(o)) + /* The below check is done in PyLong_FromUnicode(). */ + return PyLong_FromUnicodeObject(o, 10); + + if (PyObject_GetBuffer(o, &view, PyBUF_SIMPLE) == 0) { /* need to do extra error checking that PyLong_FromString() * doesn't do. In particular int('9\x005') must raise an * exception, not truncate at the null. */ - return _PyLong_FromBytes(PyBytes_AS_STRING(o), - PyBytes_GET_SIZE(o), 10); - if (PyUnicode_Check(o)) - /* The above check is done in PyLong_FromUnicode(). */ - return PyLong_FromUnicodeObject(o, 10); - if (!PyObject_AsCharBuffer(o, &buffer, &buffer_len)) - return _PyLong_FromBytes(buffer, buffer_len, 10); + PyObject *result = _PyLong_FromBytes(view.buf, view.len, 10); + PyBuffer_Release(&view); + return result; + } - return type_error("int() argument must be a string or a " - "number, not '%.200s'", o); + return type_error("int() argument must be a string, a bytes-like object " + "or a number, not '%.200s'", o); } PyObject * @@ -2080,6 +2078,11 @@ PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) { ternaryfunc call; + /* PyObject_Call() must not be called with an exception set, + because it may clear it (directly or indirectly) and so the + caller looses its exception */ + assert(!PyErr_Occurred()); + if ((call = func->ob_type->tp_call) != NULL) { PyObject *result; if (Py_EnterRecursiveCall(" while calling a Python object")) @@ -2093,7 +2096,8 @@ PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) "NULL result without error in PyObject_Call"); } #else - assert(result != NULL || PyErr_Occurred()); + assert((result != NULL && !PyErr_Occurred()) + || (result == NULL && PyErr_Occurred())); #endif return result; } @@ -2210,9 +2214,8 @@ PyObject_CallMethod(PyObject *o, const char *name, const char *format, ...) return null_error(); func = PyObject_GetAttrString(o, name); - if (func == NULL) { - return 0; - } + if (func == NULL) + return NULL; va_start(va, format); retval = callmethod(func, format, va, 0); @@ -2232,9 +2235,8 @@ _PyObject_CallMethodId(PyObject *o, _Py_Identifier *name, return null_error(); func = _PyObject_GetAttrId(o, name); - if (func == NULL) { - return 0; - } + if (func == NULL) + return NULL; va_start(va, format); retval = callmethod(func, format, va, 0); @@ -2254,9 +2256,8 @@ _PyObject_CallMethod_SizeT(PyObject *o, const char *name, return null_error(); func = PyObject_GetAttrString(o, name); - if (func == NULL) { - return 0; - } + if (func == NULL) + return NULL; va_start(va, format); retval = callmethod(func, format, va, 1); va_end(va); @@ -2541,6 +2542,11 @@ PyObject_IsInstance(PyObject *inst, PyObject *cls) if (Py_TYPE(inst) == (PyTypeObject *)cls) return 1; + /* We know what type's __instancecheck__ does. */ + if (PyType_CheckExact(cls)) { + return recursive_isinstance(inst, cls); + } + if (PyTuple_Check(cls)) { Py_ssize_t i; Py_ssize_t n; @@ -2579,6 +2585,7 @@ PyObject_IsInstance(PyObject *inst, PyObject *cls) } else if (PyErr_Occurred()) return -1; + /* Probably never reached anymore. */ return recursive_isinstance(inst, cls); } @@ -2606,6 +2613,14 @@ PyObject_IsSubclass(PyObject *derived, PyObject *cls) _Py_IDENTIFIER(__subclasscheck__); PyObject *checker; + /* We know what type's __subclasscheck__ does. */ + if (PyType_CheckExact(cls)) { + /* Quick test for an exact match */ + if (derived == cls) + return 1; + return recursive_issubclass(derived, cls); + } + if (PyTuple_Check(cls)) { Py_ssize_t i; Py_ssize_t n; @@ -2644,6 +2659,7 @@ PyObject_IsSubclass(PyObject *derived, PyObject *cls) } else if (PyErr_Occurred()) return -1; + /* Probably never reached anymore. */ return recursive_issubclass(derived, cls); } diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index 31cc4ccebdc3..8b3267e74508 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -4,6 +4,12 @@ #include "Python.h" #include "structmember.h" #include "bytes_methods.h" +#include "bytesobject.h" + +/*[clinic input] +class bytearray "PyByteArrayObject *" "&PyByteArray_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=5535b77c37a119e0]*/ char _PyByteArray_empty_string[] = ""; @@ -54,18 +60,17 @@ _getbytevalue(PyObject* arg, int *value) static int bytearray_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags) { - int ret; void *ptr; if (view == NULL) { - obj->ob_exports++; - return 0; + PyErr_SetString(PyExc_BufferError, + "bytearray_getbuffer: view==NULL argument is obsolete"); + return -1; } ptr = (void *) PyByteArray_AS_STRING(obj); - ret = PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags); - if (ret >= 0) { - obj->ob_exports++; - } - return ret; + /* cannot fail if view != NULL and readonly == 0 */ + (void)PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags); + obj->ob_exports++; + return 0; } static void @@ -74,24 +79,6 @@ bytearray_releasebuffer(PyByteArrayObject *obj, Py_buffer *view) obj->ob_exports--; } -static Py_ssize_t -_getbuffer(PyObject *obj, Py_buffer *view) -{ - PyBufferProcs *buffer = Py_TYPE(obj)->tp_as_buffer; - - if (buffer == NULL || buffer->bf_getbuffer == NULL) - { - PyErr_Format(PyExc_TypeError, - "Type %.100s doesn't support the buffer API", - Py_TYPE(obj)->tp_name); - return -1; - } - - if (buffer->bf_getbuffer(obj, view, PyBUF_SIMPLE) < 0) - return -1; - return view->len; -} - static int _canresize(PyByteArrayObject *self) { @@ -175,20 +162,22 @@ PyByteArray_AsString(PyObject *self) } int -PyByteArray_Resize(PyObject *self, Py_ssize_t size) +PyByteArray_Resize(PyObject *self, Py_ssize_t requested_size) { void *sval; PyByteArrayObject *obj = ((PyByteArrayObject *)self); - Py_ssize_t alloc = obj->ob_alloc; - Py_ssize_t logical_offset = obj->ob_start - obj->ob_bytes; + /* All computations are done unsigned to avoid integer overflows + (see issue #22335). */ + size_t alloc = (size_t) obj->ob_alloc; + size_t logical_offset = (size_t) (obj->ob_start - obj->ob_bytes); + size_t size = (size_t) requested_size; assert(self != NULL); assert(PyByteArray_Check(self)); - assert(size >= 0); - assert(logical_offset >= 0); assert(logical_offset <= alloc); + assert(requested_size >= 0); - if (size == Py_SIZE(self)) { + if (requested_size == Py_SIZE(self)) { return 0; } if (!_canresize(obj)) { @@ -220,6 +209,10 @@ PyByteArray_Resize(PyObject *self, Py_ssize_t size) alloc = size + 1; } } + if (alloc > PY_SSIZE_T_MAX) { + PyErr_NoMemory(); + return -1; + } if (logical_offset > 0) { sval = PyObject_Malloc(alloc); @@ -227,7 +220,8 @@ PyByteArray_Resize(PyObject *self, Py_ssize_t size) PyErr_NoMemory(); return -1; } - memcpy(sval, PyByteArray_AS_STRING(self), Py_MIN(size, Py_SIZE(self))); + memcpy(sval, PyByteArray_AS_STRING(self), + Py_MIN(requested_size, Py_SIZE(self))); PyObject_Free(obj->ob_bytes); } else { @@ -255,8 +249,8 @@ PyByteArray_Concat(PyObject *a, PyObject *b) va.len = -1; vb.len = -1; - if (_getbuffer(a, &va) < 0 || - _getbuffer(b, &vb) < 0) { + if (PyObject_GetBuffer(a, &va, PyBUF_SIMPLE) != 0 || + PyObject_GetBuffer(b, &vb, PyBUF_SIMPLE) != 0) { PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s", Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name); goto done; @@ -282,6 +276,31 @@ PyByteArray_Concat(PyObject *a, PyObject *b) return (PyObject *)result; } +static PyObject * +bytearray_format(PyByteArrayObject *self, PyObject *args) +{ + PyObject *bytes_in, *bytes_out, *res; + char *bytestring; + + if (self == NULL || !PyByteArray_Check(self) || args == NULL) { + PyErr_BadInternalCall(); + return NULL; + } + bytestring = PyByteArray_AS_STRING(self); + bytes_in = PyBytes_FromString(bytestring); + if (bytes_in == NULL) + return NULL; + bytes_out = _PyBytes_Format(bytes_in, args); + Py_DECREF(bytes_in); + if (bytes_out == NULL) + return NULL; + res = PyByteArray_FromObject(bytes_out); + Py_DECREF(bytes_out); + if (res == NULL) + return NULL; + return res; +} + /* Functions stuffed into the type object */ static Py_ssize_t @@ -297,7 +316,7 @@ bytearray_iconcat(PyByteArrayObject *self, PyObject *other) Py_ssize_t size; Py_buffer vo; - if (_getbuffer(other, &vo) < 0) { + if (PyObject_GetBuffer(other, &vo, PyBUF_SIMPLE) != 0) { PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s", Py_TYPE(other)->tp_name, Py_TYPE(self)->tp_name); return NULL; @@ -440,7 +459,9 @@ bytearray_subscript(PyByteArrayObject *self, PyObject *index) } } else { - PyErr_SetString(PyExc_TypeError, "bytearray indices must be integers"); + PyErr_Format(PyExc_TypeError, + "bytearray indices must be integers or slices, not %.200s", + Py_TYPE(index)->tp_name); return NULL; } } @@ -555,14 +576,14 @@ bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi, needed = 0; } else { - if (_getbuffer(values, &vbytes) < 0) { - PyErr_Format(PyExc_TypeError, - "can't set bytearray slice from %.100s", - Py_TYPE(values)->tp_name); - return -1; - } - needed = vbytes.len; - bytes = vbytes.buf; + if (PyObject_GetBuffer(values, &vbytes, PyBUF_SIMPLE) != 0) { + PyErr_Format(PyExc_TypeError, + "can't set bytearray slice from %.100s", + Py_TYPE(values)->tp_name); + return -1; + } + needed = vbytes.len; + bytes = vbytes.buf; } if (lo < 0) @@ -645,7 +666,9 @@ bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *valu } } else { - PyErr_SetString(PyExc_TypeError, "bytearray indices must be integer"); + PyErr_Format(PyExc_TypeError, + "bytearray indices must be integers or slices, not %.200s", + Py_TYPE(index)->tp_name); return -1; } @@ -1005,18 +1028,18 @@ bytearray_richcompare(PyObject *self, PyObject *other, int op) Py_RETURN_NOTIMPLEMENTED; } - self_size = _getbuffer(self, &self_bytes); - if (self_size < 0) { + if (PyObject_GetBuffer(self, &self_bytes, PyBUF_SIMPLE) != 0) { PyErr_Clear(); Py_RETURN_NOTIMPLEMENTED; } + self_size = self_bytes.len; - other_size = _getbuffer(other, &other_bytes); - if (other_size < 0) { + if (PyObject_GetBuffer(other, &other_bytes, PyBUF_SIMPLE) != 0) { PyErr_Clear(); PyBuffer_Release(&self_bytes); Py_RETURN_NOTIMPLEMENTED; } + other_size = other_bytes.len; if (self_size != other_size && (op == Py_EQ || op == Py_NE)) { /* Shortcut: if the lengths differ, the objects differ */ @@ -1128,7 +1151,7 @@ bytearray_find_internal(PyByteArrayObject *self, PyObject *args, int dir) return -2; if (subobj) { - if (_getbuffer(subobj, &subbuf) < 0) + if (PyObject_GetBuffer(subobj, &subbuf, PyBUF_SIMPLE) != 0) return -2; sub = subbuf.buf; @@ -1196,7 +1219,7 @@ bytearray_count(PyByteArrayObject *self, PyObject *args) return NULL; if (sub_obj) { - if (_getbuffer(sub_obj, &vsub) < 0) + if (PyObject_GetBuffer(sub_obj, &vsub, PyBUF_SIMPLE) != 0) return NULL; sub = vsub.buf; @@ -1219,26 +1242,70 @@ bytearray_count(PyByteArrayObject *self, PyObject *args) return count_obj; } -PyDoc_STRVAR(clear__doc__, -"B.clear() -> None\n\ -\n\ -Remove all items from B."); +/*[clinic input] +bytearray.clear + + self: self(type="PyByteArrayObject *") + +Remove all items from the bytearray. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytearray_clear__doc__, +"clear($self, /)\n" +"--\n" +"\n" +"Remove all items from the bytearray."); + +#define BYTEARRAY_CLEAR_METHODDEF \ + {"clear", (PyCFunction)bytearray_clear, METH_NOARGS, bytearray_clear__doc__}, + +static PyObject * +bytearray_clear_impl(PyByteArrayObject *self); + +static PyObject * +bytearray_clear(PyByteArrayObject *self, PyObject *Py_UNUSED(ignored)) +{ + return bytearray_clear_impl(self); +} static PyObject * -bytearray_clear(PyByteArrayObject *self) +bytearray_clear_impl(PyByteArrayObject *self) +/*[clinic end generated code: output=5344093031e2f36c input=e524fd330abcdc18]*/ { if (PyByteArray_Resize((PyObject *)self, 0) < 0) return NULL; Py_RETURN_NONE; } -PyDoc_STRVAR(copy__doc__, -"B.copy() -> bytearray\n\ -\n\ -Return a copy of B."); +/*[clinic input] +bytearray.copy + + self: self(type="PyByteArrayObject *") + +Return a copy of B. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytearray_copy__doc__, +"copy($self, /)\n" +"--\n" +"\n" +"Return a copy of B."); + +#define BYTEARRAY_COPY_METHODDEF \ + {"copy", (PyCFunction)bytearray_copy, METH_NOARGS, bytearray_copy__doc__}, + +static PyObject * +bytearray_copy_impl(PyByteArrayObject *self); static PyObject * -bytearray_copy(PyByteArrayObject *self) +bytearray_copy(PyByteArrayObject *self, PyObject *Py_UNUSED(ignored)) +{ + return bytearray_copy_impl(self); +} + +static PyObject * +bytearray_copy_impl(PyByteArrayObject *self) +/*[clinic end generated code: output=8788ed299f7f2214 input=6d5d2975aa0f33f3]*/ { return PyByteArray_FromStringAndSize(PyByteArray_AS_STRING((PyObject *)self), PyByteArray_GET_SIZE(self)); @@ -1311,7 +1378,7 @@ bytearray_contains(PyObject *self, PyObject *arg) Py_buffer varg; Py_ssize_t pos; PyErr_Clear(); - if (_getbuffer(arg, &varg) < 0) + if (PyObject_GetBuffer(arg, &varg, PyBUF_SIMPLE) != 0) return -1; pos = stringlib_find(PyByteArray_AS_STRING(self), Py_SIZE(self), varg.buf, varg.len, 0); @@ -1342,7 +1409,7 @@ _bytearray_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start str = PyByteArray_AS_STRING(self); - if (_getbuffer(substr, &vsubstr) < 0) + if (PyObject_GetBuffer(substr, &vsubstr, PyBUF_SIMPLE) != 0) return -1; ADJUST_INDICES(start, end, len); @@ -1457,36 +1524,85 @@ bytearray_endswith(PyByteArrayObject *self, PyObject *args) } -PyDoc_STRVAR(translate__doc__, -"B.translate(table[, deletechars]) -> bytearray\n\ -\n\ -Return a copy of B, where all characters occurring in the\n\ -optional argument deletechars are removed, and the remaining\n\ -characters have been mapped through the given translation\n\ -table, which must be a bytes object of length 256."); +/*[clinic input] +bytearray.translate + + self: self(type="PyByteArrayObject *") + table: object + Translation table, which must be a bytes object of length 256. + [ + deletechars: object + ] + / + +Return a copy with each character mapped by the given translation table. + +All characters occurring in the optional argument deletechars are removed. +The remaining characters are mapped through the given translation table. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytearray_translate__doc__, +"translate(table, [deletechars])\n" +"Return a copy with each character mapped by the given translation table.\n" +"\n" +" table\n" +" Translation table, which must be a bytes object of length 256.\n" +"\n" +"All characters occurring in the optional argument deletechars are removed.\n" +"The remaining characters are mapped through the given translation table."); + +#define BYTEARRAY_TRANSLATE_METHODDEF \ + {"translate", (PyCFunction)bytearray_translate, METH_VARARGS, bytearray_translate__doc__}, + +static PyObject * +bytearray_translate_impl(PyByteArrayObject *self, PyObject *table, int group_right_1, PyObject *deletechars); static PyObject * bytearray_translate(PyByteArrayObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *table; + int group_right_1 = 0; + PyObject *deletechars = NULL; + + switch (PyTuple_GET_SIZE(args)) { + case 1: + if (!PyArg_ParseTuple(args, "O:translate", &table)) + goto exit; + break; + case 2: + if (!PyArg_ParseTuple(args, "OO:translate", &table, &deletechars)) + goto exit; + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "bytearray.translate requires 1 to 2 arguments"); + goto exit; + } + return_value = bytearray_translate_impl(self, table, group_right_1, deletechars); + +exit: + return return_value; +} + +static PyObject * +bytearray_translate_impl(PyByteArrayObject *self, PyObject *table, int group_right_1, PyObject *deletechars) +/*[clinic end generated code: output=a709df81d41db4b7 input=b749ad85f4860824]*/ { char *input, *output; - const char *table; + const char *table_chars; Py_ssize_t i, c; PyObject *input_obj = (PyObject*)self; const char *output_start; Py_ssize_t inlen; PyObject *result = NULL; int trans_table[256]; - PyObject *tableobj = NULL, *delobj = NULL; Py_buffer vtable, vdel; - if (!PyArg_UnpackTuple(args, "translate", 1, 2, - &tableobj, &delobj)) - return NULL; - - if (tableobj == Py_None) { + if (table == Py_None) { + table_chars = NULL; table = NULL; - tableobj = NULL; - } else if (_getbuffer(tableobj, &vtable) < 0) { + } else if (PyObject_GetBuffer(table, &vtable, PyBUF_SIMPLE) != 0) { return NULL; } else { if (vtable.len != 256) { @@ -1495,12 +1611,12 @@ bytearray_translate(PyByteArrayObject *self, PyObject *args) PyBuffer_Release(&vtable); return NULL; } - table = (const char*)vtable.buf; + table_chars = (const char*)vtable.buf; } - if (delobj != NULL) { - if (_getbuffer(delobj, &vdel) < 0) { - if (tableobj != NULL) + if (deletechars != NULL) { + if (PyObject_GetBuffer(deletechars, &vdel, PyBUF_SIMPLE) != 0) { + if (table != NULL) PyBuffer_Release(&vtable); return NULL; } @@ -1517,21 +1633,21 @@ bytearray_translate(PyByteArrayObject *self, PyObject *args) output_start = output = PyByteArray_AsString(result); input = PyByteArray_AS_STRING(input_obj); - if (vdel.len == 0 && table != NULL) { + if (vdel.len == 0 && table_chars != NULL) { /* If no deletions are required, use faster code */ for (i = inlen; --i >= 0; ) { c = Py_CHARMASK(*input++); - *output++ = table[c]; + *output++ = table_chars[c]; } goto done; } - if (table == NULL) { + if (table_chars == NULL) { for (i = 0; i < 256; i++) trans_table[i] = Py_CHARMASK(i); } else { for (i = 0; i < 256; i++) - trans_table[i] = Py_CHARMASK(table[i]); + trans_table[i] = Py_CHARMASK(table_chars[i]); } for (i = 0; i < vdel.len; i++) @@ -1551,18 +1667,77 @@ bytearray_translate(PyByteArrayObject *self, PyObject *args) } done: - if (tableobj != NULL) + if (table != NULL) PyBuffer_Release(&vtable); - if (delobj != NULL) + if (deletechars != NULL) PyBuffer_Release(&vdel); return result; } +/*[clinic input] + +@staticmethod +bytearray.maketrans + + frm: Py_buffer + to: Py_buffer + / + +Return a translation table useable for the bytes or bytearray translate method. + +The returned table will be one where each byte in frm is mapped to the byte at +the same position in to. + +The bytes objects frm and to must be of the same length. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytearray_maketrans__doc__, +"maketrans(frm, to, /)\n" +"--\n" +"\n" +"Return a translation table useable for the bytes or bytearray translate method.\n" +"\n" +"The returned table will be one where each byte in frm is mapped to the byte at\n" +"the same position in to.\n" +"\n" +"The bytes objects frm and to must be of the same length."); + +#define BYTEARRAY_MAKETRANS_METHODDEF \ + {"maketrans", (PyCFunction)bytearray_maketrans, METH_VARARGS|METH_STATIC, bytearray_maketrans__doc__}, + +static PyObject * +bytearray_maketrans_impl(Py_buffer *frm, Py_buffer *to); + +static PyObject * +bytearray_maketrans(void *null, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer frm = {NULL, NULL}; + Py_buffer to = {NULL, NULL}; + + if (!PyArg_ParseTuple(args, + "y*y*:maketrans", + &frm, &to)) + goto exit; + return_value = bytearray_maketrans_impl(&frm, &to); + +exit: + /* Cleanup for frm */ + if (frm.obj) + PyBuffer_Release(&frm); + /* Cleanup for to */ + if (to.obj) + PyBuffer_Release(&to); + + return return_value; +} + static PyObject * -bytearray_maketrans(PyObject *null, PyObject *args) +bytearray_maketrans_impl(Py_buffer *frm, Py_buffer *to) +/*[clinic end generated code: output=d332622814c26f4b input=5925a81d2fbbf151]*/ { - return _Py_bytes_maketrans(args); + return _Py_bytes_maketrans(frm, to); } @@ -2053,67 +2228,143 @@ replace(PyByteArrayObject *self, } -PyDoc_STRVAR(replace__doc__, -"B.replace(old, new[, count]) -> bytearray\n\ -\n\ -Return a copy of B with all occurrences of subsection\n\ -old replaced by new. If the optional argument count is\n\ -given, only the first count occurrences are replaced."); +/*[clinic input] +bytearray.replace + + old: Py_buffer + new: Py_buffer + count: Py_ssize_t = -1 + Maximum number of occurrences to replace. + -1 (the default value) means replace all occurrences. + / + +Return a copy with all occurrences of substring old replaced by new. + +If the optional argument count is given, only the first count occurrences are +replaced. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytearray_replace__doc__, +"replace($self, old, new, count=-1, /)\n" +"--\n" +"\n" +"Return a copy with all occurrences of substring old replaced by new.\n" +"\n" +" count\n" +" Maximum number of occurrences to replace.\n" +" -1 (the default value) means replace all occurrences.\n" +"\n" +"If the optional argument count is given, only the first count occurrences are\n" +"replaced."); + +#define BYTEARRAY_REPLACE_METHODDEF \ + {"replace", (PyCFunction)bytearray_replace, METH_VARARGS, bytearray_replace__doc__}, + +static PyObject * +bytearray_replace_impl(PyByteArrayObject *self, Py_buffer *old, Py_buffer *new, Py_ssize_t count); static PyObject * bytearray_replace(PyByteArrayObject *self, PyObject *args) { + PyObject *return_value = NULL; + Py_buffer old = {NULL, NULL}; + Py_buffer new = {NULL, NULL}; Py_ssize_t count = -1; - PyObject *from, *to, *res; - Py_buffer vfrom, vto; - - if (!PyArg_ParseTuple(args, "OO|n:replace", &from, &to, &count)) - return NULL; - if (_getbuffer(from, &vfrom) < 0) - return NULL; - if (_getbuffer(to, &vto) < 0) { - PyBuffer_Release(&vfrom); - return NULL; - } + if (!PyArg_ParseTuple(args, + "y*y*|n:replace", + &old, &new, &count)) + goto exit; + return_value = bytearray_replace_impl(self, &old, &new, count); - res = (PyObject *)replace((PyByteArrayObject *) self, - vfrom.buf, vfrom.len, - vto.buf, vto.len, count); +exit: + /* Cleanup for old */ + if (old.obj) + PyBuffer_Release(&old); + /* Cleanup for new */ + if (new.obj) + PyBuffer_Release(&new); - PyBuffer_Release(&vfrom); - PyBuffer_Release(&vto); - return res; + return return_value; } -PyDoc_STRVAR(split__doc__, -"B.split(sep=None, maxsplit=-1) -> list of bytearrays\n\ -\n\ -Return a list of the sections in B, using sep as the delimiter.\n\ -If sep is not given, B is split on ASCII whitespace characters\n\ -(space, tab, return, newline, formfeed, vertical tab).\n\ -If maxsplit is given, at most maxsplit splits are done."); +static PyObject * +bytearray_replace_impl(PyByteArrayObject *self, Py_buffer *old, Py_buffer *new, Py_ssize_t count) +/*[clinic end generated code: output=9997fbbd5bac4883 input=aa379d988637c7fb]*/ +{ + return (PyObject *)replace((PyByteArrayObject *) self, + old->buf, old->len, + new->buf, new->len, count); +} + +/*[clinic input] +bytearray.split + + sep: object = None + The delimiter according which to split the bytearray. + None (the default value) means split on ASCII whitespace characters + (space, tab, return, newline, formfeed, vertical tab). + maxsplit: Py_ssize_t = -1 + Maximum number of splits to do. + -1 (the default value) means no limit. + +Return a list of the sections in the bytearray, using sep as the delimiter. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytearray_split__doc__, +"split($self, /, sep=None, maxsplit=-1)\n" +"--\n" +"\n" +"Return a list of the sections in the bytearray, using sep as the delimiter.\n" +"\n" +" sep\n" +" The delimiter according which to split the bytearray.\n" +" None (the default value) means split on ASCII whitespace characters\n" +" (space, tab, return, newline, formfeed, vertical tab).\n" +" maxsplit\n" +" Maximum number of splits to do.\n" +" -1 (the default value) means no limit."); + +#define BYTEARRAY_SPLIT_METHODDEF \ + {"split", (PyCFunction)bytearray_split, METH_VARARGS|METH_KEYWORDS, bytearray_split__doc__}, static PyObject * -bytearray_split(PyByteArrayObject *self, PyObject *args, PyObject *kwds) +bytearray_split_impl(PyByteArrayObject *self, PyObject *sep, Py_ssize_t maxsplit); + +static PyObject * +bytearray_split(PyByteArrayObject *self, PyObject *args, PyObject *kwargs) { - static char *kwlist[] = {"sep", "maxsplit", 0}; - Py_ssize_t len = PyByteArray_GET_SIZE(self), n; + PyObject *return_value = NULL; + static char *_keywords[] = {"sep", "maxsplit", NULL}; + PyObject *sep = Py_None; Py_ssize_t maxsplit = -1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "|On:split", _keywords, + &sep, &maxsplit)) + goto exit; + return_value = bytearray_split_impl(self, sep, maxsplit); + +exit: + return return_value; +} + +static PyObject * +bytearray_split_impl(PyByteArrayObject *self, PyObject *sep, Py_ssize_t maxsplit) +/*[clinic end generated code: output=062a3d87d6f918fa input=24f82669f41bf523]*/ +{ + Py_ssize_t len = PyByteArray_GET_SIZE(self), n; const char *s = PyByteArray_AS_STRING(self), *sub; - PyObject *list, *subobj = Py_None; + PyObject *list; Py_buffer vsub; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|On:split", - kwlist, &subobj, &maxsplit)) - return NULL; if (maxsplit < 0) maxsplit = PY_SSIZE_T_MAX; - if (subobj == Py_None) + if (sep == Py_None) return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit); - if (_getbuffer(subobj, &vsub) < 0) + if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0) return NULL; sub = vsub.buf; n = vsub.len; @@ -2125,19 +2376,46 @@ bytearray_split(PyByteArrayObject *self, PyObject *args, PyObject *kwds) return list; } -PyDoc_STRVAR(partition__doc__, -"B.partition(sep) -> (head, sep, tail)\n\ -\n\ -Search for the separator sep in B, and return the part before it,\n\ -the separator itself, and the part after it. If the separator is not\n\ -found, returns B and two empty bytearray objects."); +/*[clinic input] +bytearray.partition + + self: self(type="PyByteArrayObject *") + sep: object + / + +Partition the bytearray into three parts using the given separator. + +This will search for the separator sep in the bytearray. If the separator is +found, returns a 3-tuple containing the part before the separator, the +separator itself, and the part after it. + +If the separator is not found, returns a 3-tuple containing the original +bytearray object and two empty bytearray objects. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytearray_partition__doc__, +"partition($self, sep, /)\n" +"--\n" +"\n" +"Partition the bytearray into three parts using the given separator.\n" +"\n" +"This will search for the separator sep in the bytearray. If the separator is\n" +"found, returns a 3-tuple containing the part before the separator, the\n" +"separator itself, and the part after it.\n" +"\n" +"If the separator is not found, returns a 3-tuple containing the original\n" +"bytearray object and two empty bytearray objects."); + +#define BYTEARRAY_PARTITION_METHODDEF \ + {"partition", (PyCFunction)bytearray_partition, METH_O, bytearray_partition__doc__}, static PyObject * -bytearray_partition(PyByteArrayObject *self, PyObject *sep_obj) +bytearray_partition(PyByteArrayObject *self, PyObject *sep) +/*[clinic end generated code: output=2645138221fe6f4d input=7d7fe37b1696d506]*/ { PyObject *bytesep, *result; - bytesep = PyByteArray_FromObject(sep_obj); + bytesep = PyByteArray_FromObject(sep); if (! bytesep) return NULL; @@ -2152,20 +2430,46 @@ bytearray_partition(PyByteArrayObject *self, PyObject *sep_obj) return result; } -PyDoc_STRVAR(rpartition__doc__, -"B.rpartition(sep) -> (head, sep, tail)\n\ -\n\ -Search for the separator sep in B, starting at the end of B,\n\ -and return the part before it, the separator itself, and the\n\ -part after it. If the separator is not found, returns two empty\n\ -bytearray objects and B."); +/*[clinic input] +bytearray.rpartition + + self: self(type="PyByteArrayObject *") + sep: object + / + +Partition the bytes into three parts using the given separator. + +This will search for the separator sep in the bytearray, starting and the end. +If the separator is found, returns a 3-tuple containing the part before the +separator, the separator itself, and the part after it. + +If the separator is not found, returns a 3-tuple containing two empty bytearray +objects and the original bytearray object. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytearray_rpartition__doc__, +"rpartition($self, sep, /)\n" +"--\n" +"\n" +"Partition the bytes into three parts using the given separator.\n" +"\n" +"This will search for the separator sep in the bytearray, starting and the end.\n" +"If the separator is found, returns a 3-tuple containing the part before the\n" +"separator, the separator itself, and the part after it.\n" +"\n" +"If the separator is not found, returns a 3-tuple containing two empty bytearray\n" +"objects and the original bytearray object."); + +#define BYTEARRAY_RPARTITION_METHODDEF \ + {"rpartition", (PyCFunction)bytearray_rpartition, METH_O, bytearray_rpartition__doc__}, static PyObject * -bytearray_rpartition(PyByteArrayObject *self, PyObject *sep_obj) +bytearray_rpartition(PyByteArrayObject *self, PyObject *sep) +/*[clinic end generated code: output=ed13e54605d007de input=9b8cd540c1b75853]*/ { PyObject *bytesep, *result; - bytesep = PyByteArray_FromObject(sep_obj); + bytesep = PyByteArray_FromObject(sep); if (! bytesep) return NULL; @@ -2180,35 +2484,70 @@ bytearray_rpartition(PyByteArrayObject *self, PyObject *sep_obj) return result; } -PyDoc_STRVAR(rsplit__doc__, -"B.rsplit(sep=None, maxsplit=-1) -> list of bytearrays\n\ -\n\ -Return a list of the sections in B, using sep as the delimiter,\n\ -starting at the end of B and working to the front.\n\ -If sep is not given, B is split on ASCII whitespace characters\n\ -(space, tab, return, newline, formfeed, vertical tab).\n\ -If maxsplit is given, at most maxsplit splits are done."); +/*[clinic input] +bytearray.rsplit = bytearray.split + +Return a list of the sections in the bytearray, using sep as the delimiter. + +Splitting is done starting at the end of the bytearray and working to the front. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytearray_rsplit__doc__, +"rsplit($self, /, sep=None, maxsplit=-1)\n" +"--\n" +"\n" +"Return a list of the sections in the bytearray, using sep as the delimiter.\n" +"\n" +" sep\n" +" The delimiter according which to split the bytearray.\n" +" None (the default value) means split on ASCII whitespace characters\n" +" (space, tab, return, newline, formfeed, vertical tab).\n" +" maxsplit\n" +" Maximum number of splits to do.\n" +" -1 (the default value) means no limit.\n" +"\n" +"Splitting is done starting at the end of the bytearray and working to the front."); + +#define BYTEARRAY_RSPLIT_METHODDEF \ + {"rsplit", (PyCFunction)bytearray_rsplit, METH_VARARGS|METH_KEYWORDS, bytearray_rsplit__doc__}, + +static PyObject * +bytearray_rsplit_impl(PyByteArrayObject *self, PyObject *sep, Py_ssize_t maxsplit); static PyObject * -bytearray_rsplit(PyByteArrayObject *self, PyObject *args, PyObject *kwds) +bytearray_rsplit(PyByteArrayObject *self, PyObject *args, PyObject *kwargs) { - static char *kwlist[] = {"sep", "maxsplit", 0}; - Py_ssize_t len = PyByteArray_GET_SIZE(self), n; + PyObject *return_value = NULL; + static char *_keywords[] = {"sep", "maxsplit", NULL}; + PyObject *sep = Py_None; Py_ssize_t maxsplit = -1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "|On:rsplit", _keywords, + &sep, &maxsplit)) + goto exit; + return_value = bytearray_rsplit_impl(self, sep, maxsplit); + +exit: + return return_value; +} + +static PyObject * +bytearray_rsplit_impl(PyByteArrayObject *self, PyObject *sep, Py_ssize_t maxsplit) +/*[clinic end generated code: output=affaf9fc2aae8d41 input=a68286e4dd692ffe]*/ +{ + Py_ssize_t len = PyByteArray_GET_SIZE(self), n; const char *s = PyByteArray_AS_STRING(self), *sub; - PyObject *list, *subobj = Py_None; + PyObject *list; Py_buffer vsub; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|On:rsplit", - kwlist, &subobj, &maxsplit)) - return NULL; if (maxsplit < 0) maxsplit = PY_SSIZE_T_MAX; - if (subobj == Py_None) + if (sep == Py_None) return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit); - if (_getbuffer(subobj, &vsub) < 0) + if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0) return NULL; sub = vsub.buf; n = vsub.len; @@ -2220,12 +2559,35 @@ bytearray_rsplit(PyByteArrayObject *self, PyObject *args, PyObject *kwds) return list; } -PyDoc_STRVAR(reverse__doc__, -"B.reverse() -> None\n\ -\n\ -Reverse the order of the values in B in place."); +/*[clinic input] +bytearray.reverse + + self: self(type="PyByteArrayObject *") + +Reverse the order of the values in B in place. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytearray_reverse__doc__, +"reverse($self, /)\n" +"--\n" +"\n" +"Reverse the order of the values in B in place."); + +#define BYTEARRAY_REVERSE_METHODDEF \ + {"reverse", (PyCFunction)bytearray_reverse, METH_NOARGS, bytearray_reverse__doc__}, + +static PyObject * +bytearray_reverse_impl(PyByteArrayObject *self); + +static PyObject * +bytearray_reverse(PyByteArrayObject *self, PyObject *Py_UNUSED(ignored)) +{ + return bytearray_reverse_impl(self); +} + static PyObject * -bytearray_reverse(PyByteArrayObject *self, PyObject *unused) +bytearray_reverse_impl(PyByteArrayObject *self) +/*[clinic end generated code: output=5d5e5f0bfc67f476 input=7933a499b8597bd1]*/ { char swap, *head, *tail; Py_ssize_t i, j, n = Py_SIZE(self); @@ -2242,57 +2604,139 @@ bytearray_reverse(PyByteArrayObject *self, PyObject *unused) Py_RETURN_NONE; } -PyDoc_STRVAR(insert__doc__, -"B.insert(index, int) -> None\n\ -\n\ -Insert a single item into the bytearray before the given index."); + +/*[python input] +class bytesvalue_converter(CConverter): + type = 'int' + converter = '_getbytevalue' +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=29c2e7c26c212812]*/ + + +/*[clinic input] +bytearray.insert + + self: self(type="PyByteArrayObject *") + index: Py_ssize_t + The index where the value is to be inserted. + item: bytesvalue + The item to be inserted. + / + +Insert a single item into the bytearray before the given index. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytearray_insert__doc__, +"insert($self, index, item, /)\n" +"--\n" +"\n" +"Insert a single item into the bytearray before the given index.\n" +"\n" +" index\n" +" The index where the value is to be inserted.\n" +" item\n" +" The item to be inserted."); + +#define BYTEARRAY_INSERT_METHODDEF \ + {"insert", (PyCFunction)bytearray_insert, METH_VARARGS, bytearray_insert__doc__}, + +static PyObject * +bytearray_insert_impl(PyByteArrayObject *self, Py_ssize_t index, int item); + static PyObject * bytearray_insert(PyByteArrayObject *self, PyObject *args) { - PyObject *value; - int ival; - Py_ssize_t where, n = Py_SIZE(self); - char *buf; + PyObject *return_value = NULL; + Py_ssize_t index; + int item; - if (!PyArg_ParseTuple(args, "nO:insert", &where, &value)) - return NULL; + if (!PyArg_ParseTuple(args, + "nO&:insert", + &index, _getbytevalue, &item)) + goto exit; + return_value = bytearray_insert_impl(self, index, item); + +exit: + return return_value; +} + +static PyObject * +bytearray_insert_impl(PyByteArrayObject *self, Py_ssize_t index, int item) +/*[clinic end generated code: output=5ec9340d4ad19080 input=833766836ba30e1e]*/ +{ + Py_ssize_t n = Py_SIZE(self); + char *buf; if (n == PY_SSIZE_T_MAX) { PyErr_SetString(PyExc_OverflowError, "cannot add more objects to bytearray"); return NULL; } - if (!_getbytevalue(value, &ival)) - return NULL; if (PyByteArray_Resize((PyObject *)self, n + 1) < 0) return NULL; buf = PyByteArray_AS_STRING(self); - if (where < 0) { - where += n; - if (where < 0) - where = 0; + if (index < 0) { + index += n; + if (index < 0) + index = 0; } - if (where > n) - where = n; - memmove(buf + where + 1, buf + where, n - where); - buf[where] = ival; + if (index > n) + index = n; + memmove(buf + index + 1, buf + index, n - index); + buf[index] = item; Py_RETURN_NONE; } -PyDoc_STRVAR(append__doc__, -"B.append(int) -> None\n\ -\n\ -Append a single item to the end of B."); +/*[clinic input] +bytearray.append + + self: self(type="PyByteArrayObject *") + item: bytesvalue + The item to be appended. + / + +Append a single item to the end of the bytearray. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytearray_append__doc__, +"append($self, item, /)\n" +"--\n" +"\n" +"Append a single item to the end of the bytearray.\n" +"\n" +" item\n" +" The item to be appended."); + +#define BYTEARRAY_APPEND_METHODDEF \ + {"append", (PyCFunction)bytearray_append, METH_VARARGS, bytearray_append__doc__}, + static PyObject * -bytearray_append(PyByteArrayObject *self, PyObject *arg) +bytearray_append_impl(PyByteArrayObject *self, int item); + +static PyObject * +bytearray_append(PyByteArrayObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int item; + + if (!PyArg_ParseTuple(args, + "O&:append", + _getbytevalue, &item)) + goto exit; + return_value = bytearray_append_impl(self, item); + +exit: + return return_value; +} + +static PyObject * +bytearray_append_impl(PyByteArrayObject *self, int item) +/*[clinic end generated code: output=b5b3325bb3bbaf85 input=ae56ea87380407cc]*/ { - int value; Py_ssize_t n = Py_SIZE(self); - if (! _getbytevalue(arg, &value)) - return NULL; if (n == PY_SSIZE_T_MAX) { PyErr_SetString(PyExc_OverflowError, "cannot add more objects to bytearray"); @@ -2301,18 +2745,37 @@ bytearray_append(PyByteArrayObject *self, PyObject *arg) if (PyByteArray_Resize((PyObject *)self, n + 1) < 0) return NULL; - PyByteArray_AS_STRING(self)[n] = value; + PyByteArray_AS_STRING(self)[n] = item; Py_RETURN_NONE; } -PyDoc_STRVAR(extend__doc__, -"B.extend(iterable_of_ints) -> None\n\ -\n\ -Append all the elements from the iterator or sequence to the\n\ -end of B."); +/*[clinic input] +bytearray.extend + + self: self(type="PyByteArrayObject *") + iterable_of_ints: object + The iterable of items to append. + / + +Append all the items from the iterator or sequence to the end of the bytearray. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytearray_extend__doc__, +"extend($self, iterable_of_ints, /)\n" +"--\n" +"\n" +"Append all the items from the iterator or sequence to the end of the bytearray.\n" +"\n" +" iterable_of_ints\n" +" The iterable of items to append."); + +#define BYTEARRAY_EXTEND_METHODDEF \ + {"extend", (PyCFunction)bytearray_extend, METH_O, bytearray_extend__doc__}, + static PyObject * -bytearray_extend(PyByteArrayObject *self, PyObject *arg) +bytearray_extend(PyByteArrayObject *self, PyObject *iterable_of_ints) +/*[clinic end generated code: output=13b0c13ad5110dfb input=ce83a5d75b70d850]*/ { PyObject *it, *item, *bytearray_obj; Py_ssize_t buf_size = 0, len = 0; @@ -2320,19 +2783,19 @@ bytearray_extend(PyByteArrayObject *self, PyObject *arg) char *buf; /* bytearray_setslice code only accepts something supporting PEP 3118. */ - if (PyObject_CheckBuffer(arg)) { - if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), arg) == -1) + if (PyObject_CheckBuffer(iterable_of_ints)) { + if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), iterable_of_ints) == -1) return NULL; Py_RETURN_NONE; } - it = PyObject_GetIter(arg); + it = PyObject_GetIter(iterable_of_ints); if (it == NULL) return NULL; /* Try to determine the length of the argument. 32 is arbitrary. */ - buf_size = PyObject_LengthHint(arg, 32); + buf_size = PyObject_LengthHint(iterable_of_ints, 32); if (buf_size == -1) { Py_DECREF(it); return NULL; @@ -2384,29 +2847,70 @@ bytearray_extend(PyByteArrayObject *self, PyObject *arg) Py_RETURN_NONE; } -PyDoc_STRVAR(pop__doc__, -"B.pop([index]) -> int\n\ -\n\ -Remove and return a single item from B. If no index\n\ -argument is given, will pop the last value."); +/*[clinic input] +bytearray.pop + + self: self(type="PyByteArrayObject *") + index: Py_ssize_t = -1 + The index from where to remove the item. + -1 (the default value) means remove the last item. + / + +Remove and return a single item from B. + +If no index argument is given, will pop the last item. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytearray_pop__doc__, +"pop($self, index=-1, /)\n" +"--\n" +"\n" +"Remove and return a single item from B.\n" +"\n" +" index\n" +" The index from where to remove the item.\n" +" -1 (the default value) means remove the last item.\n" +"\n" +"If no index argument is given, will pop the last item."); + +#define BYTEARRAY_POP_METHODDEF \ + {"pop", (PyCFunction)bytearray_pop, METH_VARARGS, bytearray_pop__doc__}, + +static PyObject * +bytearray_pop_impl(PyByteArrayObject *self, Py_ssize_t index); + static PyObject * bytearray_pop(PyByteArrayObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + Py_ssize_t index = -1; + + if (!PyArg_ParseTuple(args, + "|n:pop", + &index)) + goto exit; + return_value = bytearray_pop_impl(self, index); + +exit: + return return_value; +} + +static PyObject * +bytearray_pop_impl(PyByteArrayObject *self, Py_ssize_t index) +/*[clinic end generated code: output=3b763e548e79af96 input=0797e6c0ca9d5a85]*/ { int value; - Py_ssize_t where = -1, n = Py_SIZE(self); + Py_ssize_t n = Py_SIZE(self); char *buf; - if (!PyArg_ParseTuple(args, "|n:pop", &where)) - return NULL; - if (n == 0) { PyErr_SetString(PyExc_IndexError, "pop from empty bytearray"); return NULL; } - if (where < 0) - where += Py_SIZE(self); - if (where < 0 || where >= Py_SIZE(self)) { + if (index < 0) + index += Py_SIZE(self); + if (index < 0 || index >= Py_SIZE(self)) { PyErr_SetString(PyExc_IndexError, "pop index out of range"); return NULL; } @@ -2414,28 +2918,63 @@ bytearray_pop(PyByteArrayObject *self, PyObject *args) return NULL; buf = PyByteArray_AS_STRING(self); - value = buf[where]; - memmove(buf + where, buf + where + 1, n - where); + value = buf[index]; + memmove(buf + index, buf + index + 1, n - index); if (PyByteArray_Resize((PyObject *)self, n - 1) < 0) return NULL; return PyLong_FromLong((unsigned char)value); } -PyDoc_STRVAR(remove__doc__, -"B.remove(int) -> None\n\ -\n\ -Remove the first occurrence of a value in B."); +/*[clinic input] +bytearray.remove + + self: self(type="PyByteArrayObject *") + value: bytesvalue + The value to remove. + / + +Remove the first occurrence of a value in the bytearray. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytearray_remove__doc__, +"remove($self, value, /)\n" +"--\n" +"\n" +"Remove the first occurrence of a value in the bytearray.\n" +"\n" +" value\n" +" The value to remove."); + +#define BYTEARRAY_REMOVE_METHODDEF \ + {"remove", (PyCFunction)bytearray_remove, METH_VARARGS, bytearray_remove__doc__}, + static PyObject * -bytearray_remove(PyByteArrayObject *self, PyObject *arg) +bytearray_remove_impl(PyByteArrayObject *self, int value); + +static PyObject * +bytearray_remove(PyByteArrayObject *self, PyObject *args) { + PyObject *return_value = NULL; int value; + + if (!PyArg_ParseTuple(args, + "O&:remove", + _getbytevalue, &value)) + goto exit; + return_value = bytearray_remove_impl(self, value); + +exit: + return return_value; +} + +static PyObject * +bytearray_remove_impl(PyByteArrayObject *self, int value) +/*[clinic end generated code: output=c71c8bcf4703abfc input=47560b11fd856c24]*/ +{ Py_ssize_t where, n = Py_SIZE(self); char *buf = PyByteArray_AS_STRING(self); - if (! _getbytevalue(arg, &value)) - return NULL; - for (where = 0; where < n; where++) { if (buf[where] == value) break; @@ -2476,132 +3015,273 @@ rstrip_helper(char *myptr, Py_ssize_t mysize, return i + 1; } -PyDoc_STRVAR(strip__doc__, -"B.strip([bytes]) -> bytearray\n\ -\n\ -Strip leading and trailing bytes contained in the argument\n\ -and return the result as a new bytearray.\n\ -If the argument is omitted, strip ASCII whitespace."); +/*[clinic input] +bytearray.strip + + bytes: object = None + / + +Strip leading and trailing bytes contained in the argument. + +If the argument is omitted or None, strip leading and trailing ASCII whitespace. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytearray_strip__doc__, +"strip($self, bytes=None, /)\n" +"--\n" +"\n" +"Strip leading and trailing bytes contained in the argument.\n" +"\n" +"If the argument is omitted or None, strip leading and trailing ASCII whitespace."); + +#define BYTEARRAY_STRIP_METHODDEF \ + {"strip", (PyCFunction)bytearray_strip, METH_VARARGS, bytearray_strip__doc__}, + +static PyObject * +bytearray_strip_impl(PyByteArrayObject *self, PyObject *bytes); + static PyObject * bytearray_strip(PyByteArrayObject *self, PyObject *args) { - Py_ssize_t left, right, mysize, argsize; - char *myptr, *argptr; - PyObject *arg = Py_None; - Py_buffer varg; - if (!PyArg_ParseTuple(args, "|O:strip", &arg)) - return NULL; - if (arg == Py_None) { - argptr = "\t\n\r\f\v "; - argsize = 6; + PyObject *return_value = NULL; + PyObject *bytes = Py_None; + + if (!PyArg_UnpackTuple(args, "strip", + 0, 1, + &bytes)) + goto exit; + return_value = bytearray_strip_impl(self, bytes); + +exit: + return return_value; +} + +static PyObject * +bytearray_strip_impl(PyByteArrayObject *self, PyObject *bytes) +/*[clinic end generated code: output=2e3d3358acc4c235 input=ef7bb59b09c21d62]*/ +{ + Py_ssize_t left, right, mysize, byteslen; + char *myptr, *bytesptr; + Py_buffer vbytes; + + if (bytes == Py_None) { + bytesptr = "\t\n\r\f\v "; + byteslen = 6; } else { - if (_getbuffer(arg, &varg) < 0) + if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0) return NULL; - argptr = (char *) varg.buf; - argsize = varg.len; + bytesptr = (char *) vbytes.buf; + byteslen = vbytes.len; } myptr = PyByteArray_AS_STRING(self); mysize = Py_SIZE(self); - left = lstrip_helper(myptr, mysize, argptr, argsize); + left = lstrip_helper(myptr, mysize, bytesptr, byteslen); if (left == mysize) right = left; else - right = rstrip_helper(myptr, mysize, argptr, argsize); - if (arg != Py_None) - PyBuffer_Release(&varg); + right = rstrip_helper(myptr, mysize, bytesptr, byteslen); + if (bytes != Py_None) + PyBuffer_Release(&vbytes); return PyByteArray_FromStringAndSize(myptr + left, right - left); } -PyDoc_STRVAR(lstrip__doc__, -"B.lstrip([bytes]) -> bytearray\n\ -\n\ -Strip leading bytes contained in the argument\n\ -and return the result as a new bytearray.\n\ -If the argument is omitted, strip leading ASCII whitespace."); +/*[clinic input] +bytearray.lstrip + + bytes: object = None + / + +Strip leading bytes contained in the argument. + +If the argument is omitted or None, strip leading ASCII whitespace. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytearray_lstrip__doc__, +"lstrip($self, bytes=None, /)\n" +"--\n" +"\n" +"Strip leading bytes contained in the argument.\n" +"\n" +"If the argument is omitted or None, strip leading ASCII whitespace."); + +#define BYTEARRAY_LSTRIP_METHODDEF \ + {"lstrip", (PyCFunction)bytearray_lstrip, METH_VARARGS, bytearray_lstrip__doc__}, + +static PyObject * +bytearray_lstrip_impl(PyByteArrayObject *self, PyObject *bytes); + static PyObject * bytearray_lstrip(PyByteArrayObject *self, PyObject *args) { - Py_ssize_t left, right, mysize, argsize; - char *myptr, *argptr; - PyObject *arg = Py_None; - Py_buffer varg; - if (!PyArg_ParseTuple(args, "|O:lstrip", &arg)) - return NULL; - if (arg == Py_None) { - argptr = "\t\n\r\f\v "; - argsize = 6; + PyObject *return_value = NULL; + PyObject *bytes = Py_None; + + if (!PyArg_UnpackTuple(args, "lstrip", + 0, 1, + &bytes)) + goto exit; + return_value = bytearray_lstrip_impl(self, bytes); + +exit: + return return_value; +} + +static PyObject * +bytearray_lstrip_impl(PyByteArrayObject *self, PyObject *bytes) +/*[clinic end generated code: output=2599309808a9ec02 input=80843f975dd7c480]*/ +{ + Py_ssize_t left, right, mysize, byteslen; + char *myptr, *bytesptr; + Py_buffer vbytes; + + if (bytes == Py_None) { + bytesptr = "\t\n\r\f\v "; + byteslen = 6; } else { - if (_getbuffer(arg, &varg) < 0) + if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0) return NULL; - argptr = (char *) varg.buf; - argsize = varg.len; + bytesptr = (char *) vbytes.buf; + byteslen = vbytes.len; } myptr = PyByteArray_AS_STRING(self); mysize = Py_SIZE(self); - left = lstrip_helper(myptr, mysize, argptr, argsize); + left = lstrip_helper(myptr, mysize, bytesptr, byteslen); right = mysize; - if (arg != Py_None) - PyBuffer_Release(&varg); + if (bytes != Py_None) + PyBuffer_Release(&vbytes); return PyByteArray_FromStringAndSize(myptr + left, right - left); } -PyDoc_STRVAR(rstrip__doc__, -"B.rstrip([bytes]) -> bytearray\n\ -\n\ -Strip trailing bytes contained in the argument\n\ -and return the result as a new bytearray.\n\ -If the argument is omitted, strip trailing ASCII whitespace."); +/*[clinic input] +bytearray.rstrip + + bytes: object = None + / + +Strip trailing bytes contained in the argument. + +If the argument is omitted or None, strip trailing ASCII whitespace. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytearray_rstrip__doc__, +"rstrip($self, bytes=None, /)\n" +"--\n" +"\n" +"Strip trailing bytes contained in the argument.\n" +"\n" +"If the argument is omitted or None, strip trailing ASCII whitespace."); + +#define BYTEARRAY_RSTRIP_METHODDEF \ + {"rstrip", (PyCFunction)bytearray_rstrip, METH_VARARGS, bytearray_rstrip__doc__}, + +static PyObject * +bytearray_rstrip_impl(PyByteArrayObject *self, PyObject *bytes); + static PyObject * bytearray_rstrip(PyByteArrayObject *self, PyObject *args) { - Py_ssize_t right, mysize, argsize; - char *myptr, *argptr; - PyObject *arg = Py_None; - Py_buffer varg; - if (!PyArg_ParseTuple(args, "|O:rstrip", &arg)) - return NULL; - if (arg == Py_None) { - argptr = "\t\n\r\f\v "; - argsize = 6; + PyObject *return_value = NULL; + PyObject *bytes = Py_None; + + if (!PyArg_UnpackTuple(args, "rstrip", + 0, 1, + &bytes)) + goto exit; + return_value = bytearray_rstrip_impl(self, bytes); + +exit: + return return_value; +} + +static PyObject * +bytearray_rstrip_impl(PyByteArrayObject *self, PyObject *bytes) +/*[clinic end generated code: output=b5ca6259f4f4f2a3 input=e728b994954cfd91]*/ +{ + Py_ssize_t right, mysize, byteslen; + char *myptr, *bytesptr; + Py_buffer vbytes; + + if (bytes == Py_None) { + bytesptr = "\t\n\r\f\v "; + byteslen = 6; } else { - if (_getbuffer(arg, &varg) < 0) + if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0) return NULL; - argptr = (char *) varg.buf; - argsize = varg.len; + bytesptr = (char *) vbytes.buf; + byteslen = vbytes.len; } myptr = PyByteArray_AS_STRING(self); mysize = Py_SIZE(self); - right = rstrip_helper(myptr, mysize, argptr, argsize); - if (arg != Py_None) - PyBuffer_Release(&varg); + right = rstrip_helper(myptr, mysize, bytesptr, byteslen); + if (bytes != Py_None) + PyBuffer_Release(&vbytes); return PyByteArray_FromStringAndSize(myptr, right); } -PyDoc_STRVAR(decode_doc, -"B.decode(encoding='utf-8', errors='strict') -> str\n\ -\n\ -Decode B using the codec registered for encoding. Default encoding\n\ -is 'utf-8'. errors may be given to set a different error\n\ -handling scheme. Default is 'strict' meaning that encoding errors raise\n\ -a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'\n\ -as well as any other name registered with codecs.register_error that is\n\ -able to handle UnicodeDecodeErrors."); +/*[clinic input] +bytearray.decode + + encoding: str(c_default="NULL") = 'utf-8' + The encoding with which to decode the bytearray. + errors: str(c_default="NULL") = 'strict' + The error handling scheme to use for the handling of decoding errors. + The default is 'strict' meaning that decoding errors raise a + UnicodeDecodeError. Other possible values are 'ignore' and 'replace' + as well as any other name registered with codecs.register_error that + can handle UnicodeDecodeErrors. + +Decode the bytearray using the codec registered for encoding. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytearray_decode__doc__, +"decode($self, /, encoding=\'utf-8\', errors=\'strict\')\n" +"--\n" +"\n" +"Decode the bytearray using the codec registered for encoding.\n" +"\n" +" encoding\n" +" The encoding with which to decode the bytearray.\n" +" errors\n" +" The error handling scheme to use for the handling of decoding errors.\n" +" The default is \'strict\' meaning that decoding errors raise a\n" +" UnicodeDecodeError. Other possible values are \'ignore\' and \'replace\'\n" +" as well as any other name registered with codecs.register_error that\n" +" can handle UnicodeDecodeErrors."); + +#define BYTEARRAY_DECODE_METHODDEF \ + {"decode", (PyCFunction)bytearray_decode, METH_VARARGS|METH_KEYWORDS, bytearray_decode__doc__}, static PyObject * -bytearray_decode(PyObject *self, PyObject *args, PyObject *kwargs) +bytearray_decode_impl(PyByteArrayObject *self, const char *encoding, const char *errors); + +static PyObject * +bytearray_decode(PyByteArrayObject *self, PyObject *args, PyObject *kwargs) { + PyObject *return_value = NULL; + static char *_keywords[] = {"encoding", "errors", NULL}; const char *encoding = NULL; const char *errors = NULL; - static char *kwlist[] = {"encoding", "errors", 0}; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode", kwlist, &encoding, &errors)) - return NULL; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "|ss:decode", _keywords, + &encoding, &errors)) + goto exit; + return_value = bytearray_decode_impl(self, encoding, errors); + +exit: + return return_value; +} + +static PyObject * +bytearray_decode_impl(PyByteArrayObject *self, const char *encoding, const char *errors) +/*[clinic end generated code: output=38b83681f1e38a6c input=f28d8f903020257b]*/ +{ if (encoding == NULL) encoding = PyUnicode_GetDefaultEncoding(); - return PyUnicode_FromEncodedObject(self, encoding, errors); + return PyUnicode_FromEncodedObject((PyObject*)self, encoding, errors); } PyDoc_STRVAR(alloc_doc, @@ -2615,48 +3295,92 @@ bytearray_alloc(PyByteArrayObject *self) return PyLong_FromSsize_t(self->ob_alloc); } -PyDoc_STRVAR(join_doc, -"B.join(iterable_of_bytes) -> bytearray\n\ -\n\ -Concatenate any number of bytes/bytearray objects, with B\n\ -in between each pair, and return the result as a new bytearray."); +/*[clinic input] +bytearray.join + + iterable_of_bytes: object + / + +Concatenate any number of bytes/bytearray objects. + +The bytearray whose method is called is inserted in between each pair. + +The result is returned as a new bytearray object. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytearray_join__doc__, +"join($self, iterable_of_bytes, /)\n" +"--\n" +"\n" +"Concatenate any number of bytes/bytearray objects.\n" +"\n" +"The bytearray whose method is called is inserted in between each pair.\n" +"\n" +"The result is returned as a new bytearray object."); + +#define BYTEARRAY_JOIN_METHODDEF \ + {"join", (PyCFunction)bytearray_join, METH_O, bytearray_join__doc__}, static PyObject * -bytearray_join(PyObject *self, PyObject *iterable) +bytearray_join(PyByteArrayObject *self, PyObject *iterable_of_bytes) +/*[clinic end generated code: output=544e7430032dfdf4 input=aba6b1f9b30fcb8e]*/ { - return stringlib_bytes_join(self, iterable); + return stringlib_bytes_join((PyObject*)self, iterable_of_bytes); } -PyDoc_STRVAR(splitlines__doc__, -"B.splitlines([keepends]) -> list of lines\n\ -\n\ -Return a list of the lines in B, breaking at line boundaries.\n\ -Line breaks are not included in the resulting list unless keepends\n\ -is given and true."); +/*[clinic input] +bytearray.splitlines + + keepends: int(py_default="False") = 0 + +Return a list of the lines in the bytearray, breaking at line boundaries. + +Line breaks are not included in the resulting list unless keepends is given and +true. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytearray_splitlines__doc__, +"splitlines($self, /, keepends=False)\n" +"--\n" +"\n" +"Return a list of the lines in the bytearray, breaking at line boundaries.\n" +"\n" +"Line breaks are not included in the resulting list unless keepends is given and\n" +"true."); + +#define BYTEARRAY_SPLITLINES_METHODDEF \ + {"splitlines", (PyCFunction)bytearray_splitlines, METH_VARARGS|METH_KEYWORDS, bytearray_splitlines__doc__}, -static PyObject* -bytearray_splitlines(PyObject *self, PyObject *args, PyObject *kwds) +static PyObject * +bytearray_splitlines_impl(PyByteArrayObject *self, int keepends); + +static PyObject * +bytearray_splitlines(PyByteArrayObject *self, PyObject *args, PyObject *kwargs) { - static char *kwlist[] = {"keepends", 0}; + PyObject *return_value = NULL; + static char *_keywords[] = {"keepends", NULL}; int keepends = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:splitlines", - kwlist, &keepends)) - return NULL; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "|i:splitlines", _keywords, + &keepends)) + goto exit; + return_value = bytearray_splitlines_impl(self, keepends); + +exit: + return return_value; +} +static PyObject * +bytearray_splitlines_impl(PyByteArrayObject *self, int keepends) +/*[clinic end generated code: output=a837fd0512ad46ff input=36f0b25bc792f6c0]*/ +{ return stringlib_splitlines( (PyObject*) self, PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), keepends ); } -PyDoc_STRVAR(fromhex_doc, -"bytearray.fromhex(string) -> bytearray (static method)\n\ -\n\ -Create a bytearray object from a string of hexadecimal numbers.\n\ -Spaces between two numbers are accepted.\n\ -Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef')."); - static int hex_digit_to_int(Py_UCS4 c) { @@ -2673,24 +3397,68 @@ hex_digit_to_int(Py_UCS4 c) return -1; } +/*[clinic input] +@classmethod +bytearray.fromhex + + cls: self(type="PyObject*") + string: unicode + / + +Create a bytearray object from a string of hexadecimal numbers. + +Spaces between two numbers are accepted. +Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef') +[clinic start generated code]*/ + +PyDoc_STRVAR(bytearray_fromhex__doc__, +"fromhex($type, string, /)\n" +"--\n" +"\n" +"Create a bytearray object from a string of hexadecimal numbers.\n" +"\n" +"Spaces between two numbers are accepted.\n" +"Example: bytearray.fromhex(\'B9 01EF\') -> bytearray(b\'\\\\xb9\\\\x01\\\\xef\')"); + +#define BYTEARRAY_FROMHEX_METHODDEF \ + {"fromhex", (PyCFunction)bytearray_fromhex, METH_VARARGS|METH_CLASS, bytearray_fromhex__doc__}, + +static PyObject * +bytearray_fromhex_impl(PyObject*cls, PyObject *string); + +static PyObject * +bytearray_fromhex(PyTypeObject *cls, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *string; + + if (!PyArg_ParseTuple(args, + "U:fromhex", + &string)) + goto exit; + return_value = bytearray_fromhex_impl((PyObject*)cls, string); + +exit: + return return_value; +} + static PyObject * -bytearray_fromhex(PyObject *cls, PyObject *args) +bytearray_fromhex_impl(PyObject*cls, PyObject *string) +/*[clinic end generated code: output=adc3c804a74e56d4 input=907bbd2d34d9367a]*/ { - PyObject *newbytes, *hexobj; + PyObject *newbytes; char *buf; Py_ssize_t hexlen, byteslen, i, j; int top, bot; void *data; unsigned int kind; - if (!PyArg_ParseTuple(args, "U:fromhex", &hexobj)) - return NULL; - assert(PyUnicode_Check(hexobj)); - if (PyUnicode_READY(hexobj)) + assert(PyUnicode_Check(string)); + if (PyUnicode_READY(string)) return NULL; - kind = PyUnicode_KIND(hexobj); - data = PyUnicode_DATA(hexobj); - hexlen = PyUnicode_GET_LENGTH(hexobj); + kind = PyUnicode_KIND(string); + data = PyUnicode_DATA(string); + hexlen = PyUnicode_GET_LENGTH(string); byteslen = hexlen/2; /* This overestimates if there are spaces */ newbytes = PyByteArray_FromStringAndSize(NULL, byteslen); @@ -2758,33 +3526,113 @@ _common_reduce(PyByteArrayObject *self, int proto) } } -PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); +/*[clinic input] +bytearray.__reduce__ as bytearray_reduce + + self: self(type="PyByteArrayObject *") + +Return state information for pickling. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytearray_reduce__doc__, +"__reduce__($self, /)\n" +"--\n" +"\n" +"Return state information for pickling."); + +#define BYTEARRAY_REDUCE_METHODDEF \ + {"__reduce__", (PyCFunction)bytearray_reduce, METH_NOARGS, bytearray_reduce__doc__}, + +static PyObject * +bytearray_reduce_impl(PyByteArrayObject *self); static PyObject * -bytearray_reduce(PyByteArrayObject *self) +bytearray_reduce(PyByteArrayObject *self, PyObject *Py_UNUSED(ignored)) +{ + return bytearray_reduce_impl(self); +} + +static PyObject * +bytearray_reduce_impl(PyByteArrayObject *self) +/*[clinic end generated code: output=b1b56fe87bf30fb0 input=fbb07de4d102a03a]*/ { return _common_reduce(self, 2); } -PyDoc_STRVAR(reduce_ex_doc, "Return state information for pickling."); +/*[clinic input] +bytearray.__reduce_ex__ as bytearray_reduce_ex + + self: self(type="PyByteArrayObject *") + proto: int = 0 + / + +Return state information for pickling. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytearray_reduce_ex__doc__, +"__reduce_ex__($self, proto=0, /)\n" +"--\n" +"\n" +"Return state information for pickling."); + +#define BYTEARRAY_REDUCE_EX_METHODDEF \ + {"__reduce_ex__", (PyCFunction)bytearray_reduce_ex, METH_VARARGS, bytearray_reduce_ex__doc__}, + +static PyObject * +bytearray_reduce_ex_impl(PyByteArrayObject *self, int proto); static PyObject * bytearray_reduce_ex(PyByteArrayObject *self, PyObject *args) { + PyObject *return_value = NULL; int proto = 0; - if (!PyArg_ParseTuple(args, "|i:__reduce_ex__", &proto)) - return NULL; + if (!PyArg_ParseTuple(args, + "|i:__reduce_ex__", + &proto)) + goto exit; + return_value = bytearray_reduce_ex_impl(self, proto); +exit: + return return_value; +} + +static PyObject * +bytearray_reduce_ex_impl(PyByteArrayObject *self, int proto) +/*[clinic end generated code: output=bbd9afb2f5953dc1 input=0e091a42ca6dbd91]*/ +{ return _common_reduce(self, proto); } -PyDoc_STRVAR(sizeof_doc, -"B.__sizeof__() -> int\n\ - \n\ -Returns the size of B in memory, in bytes"); +/*[clinic input] +bytearray.__sizeof__ as bytearray_sizeof + + self: self(type="PyByteArrayObject *") + +Returns the size of the bytearray object in memory, in bytes. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytearray_sizeof__doc__, +"__sizeof__($self, /)\n" +"--\n" +"\n" +"Returns the size of the bytearray object in memory, in bytes."); + +#define BYTEARRAY_SIZEOF_METHODDEF \ + {"__sizeof__", (PyCFunction)bytearray_sizeof, METH_NOARGS, bytearray_sizeof__doc__}, + +static PyObject * +bytearray_sizeof_impl(PyByteArrayObject *self); + +static PyObject * +bytearray_sizeof(PyByteArrayObject *self, PyObject *Py_UNUSED(ignored)) +{ + return bytearray_sizeof_impl(self); +} + static PyObject * -bytearray_sizeof(PyByteArrayObject *self) +bytearray_sizeof_impl(PyByteArrayObject *self) +/*[clinic end generated code: output=4a2254b0a85630c6 input=6b23d305362b462b]*/ { Py_ssize_t res; @@ -2819,26 +3667,25 @@ static PyBufferProcs bytearray_as_buffer = { static PyMethodDef bytearray_methods[] = { {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc}, - {"__reduce__", (PyCFunction)bytearray_reduce, METH_NOARGS, reduce_doc}, - {"__reduce_ex__", (PyCFunction)bytearray_reduce_ex, METH_VARARGS, reduce_ex_doc}, - {"__sizeof__", (PyCFunction)bytearray_sizeof, METH_NOARGS, sizeof_doc}, - {"append", (PyCFunction)bytearray_append, METH_O, append__doc__}, + BYTEARRAY_REDUCE_METHODDEF + BYTEARRAY_REDUCE_EX_METHODDEF + BYTEARRAY_SIZEOF_METHODDEF + BYTEARRAY_APPEND_METHODDEF {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS, _Py_capitalize__doc__}, {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__}, - {"clear", (PyCFunction)bytearray_clear, METH_NOARGS, clear__doc__}, - {"copy", (PyCFunction)bytearray_copy, METH_NOARGS, copy__doc__}, + BYTEARRAY_CLEAR_METHODDEF + BYTEARRAY_COPY_METHODDEF {"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__}, - {"decode", (PyCFunction)bytearray_decode, METH_VARARGS | METH_KEYWORDS, decode_doc}, + BYTEARRAY_DECODE_METHODDEF {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__}, {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS | METH_KEYWORDS, expandtabs__doc__}, - {"extend", (PyCFunction)bytearray_extend, METH_O, extend__doc__}, + BYTEARRAY_EXTEND_METHODDEF {"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__}, - {"fromhex", (PyCFunction)bytearray_fromhex, METH_VARARGS|METH_CLASS, - fromhex_doc}, + BYTEARRAY_FROMHEX_METHODDEF {"index", (PyCFunction)bytearray_index, METH_VARARGS, index__doc__}, - {"insert", (PyCFunction)bytearray_insert, METH_VARARGS, insert__doc__}, + BYTEARRAY_INSERT_METHODDEF {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS, _Py_isalnum__doc__}, {"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS, @@ -2853,39 +3700,51 @@ bytearray_methods[] = { _Py_istitle__doc__}, {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS, _Py_isupper__doc__}, - {"join", (PyCFunction)bytearray_join, METH_O, join_doc}, + BYTEARRAY_JOIN_METHODDEF {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__}, {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__}, - {"lstrip", (PyCFunction)bytearray_lstrip, METH_VARARGS, lstrip__doc__}, - {"maketrans", (PyCFunction)bytearray_maketrans, METH_VARARGS|METH_STATIC, - _Py_maketrans__doc__}, - {"partition", (PyCFunction)bytearray_partition, METH_O, partition__doc__}, - {"pop", (PyCFunction)bytearray_pop, METH_VARARGS, pop__doc__}, - {"remove", (PyCFunction)bytearray_remove, METH_O, remove__doc__}, - {"replace", (PyCFunction)bytearray_replace, METH_VARARGS, replace__doc__}, - {"reverse", (PyCFunction)bytearray_reverse, METH_NOARGS, reverse__doc__}, + BYTEARRAY_LSTRIP_METHODDEF + BYTEARRAY_MAKETRANS_METHODDEF + BYTEARRAY_PARTITION_METHODDEF + BYTEARRAY_POP_METHODDEF + BYTEARRAY_REMOVE_METHODDEF + BYTEARRAY_REPLACE_METHODDEF + BYTEARRAY_REVERSE_METHODDEF {"rfind", (PyCFunction)bytearray_rfind, METH_VARARGS, rfind__doc__}, {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, rindex__doc__}, {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__}, - {"rpartition", (PyCFunction)bytearray_rpartition, METH_O, rpartition__doc__}, - {"rsplit", (PyCFunction)bytearray_rsplit, METH_VARARGS | METH_KEYWORDS, rsplit__doc__}, - {"rstrip", (PyCFunction)bytearray_rstrip, METH_VARARGS, rstrip__doc__}, - {"split", (PyCFunction)bytearray_split, METH_VARARGS | METH_KEYWORDS, split__doc__}, - {"splitlines", (PyCFunction)bytearray_splitlines, - METH_VARARGS | METH_KEYWORDS, splitlines__doc__}, + BYTEARRAY_RPARTITION_METHODDEF + BYTEARRAY_RSPLIT_METHODDEF + BYTEARRAY_RSTRIP_METHODDEF + BYTEARRAY_SPLIT_METHODDEF + BYTEARRAY_SPLITLINES_METHODDEF {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS , startswith__doc__}, - {"strip", (PyCFunction)bytearray_strip, METH_VARARGS, strip__doc__}, + BYTEARRAY_STRIP_METHODDEF {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS, _Py_swapcase__doc__}, {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__}, - {"translate", (PyCFunction)bytearray_translate, METH_VARARGS, - translate__doc__}, + BYTEARRAY_TRANSLATE_METHODDEF {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__}, {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__}, {NULL} }; +static PyObject * +bytearray_mod(PyObject *v, PyObject *w) +{ + if (!PyByteArray_Check(v)) + Py_RETURN_NOTIMPLEMENTED; + return bytearray_format((PyByteArrayObject *)v, w); +} + +static PyNumberMethods bytearray_as_number = { + 0, /*nb_add*/ + 0, /*nb_subtract*/ + 0, /*nb_multiply*/ + bytearray_mod, /*nb_remainder*/ +}; + PyDoc_STRVAR(bytearray_doc, "bytearray(iterable_of_ints) -> bytearray\n\ bytearray(string, encoding[, errors]) -> bytearray\n\ @@ -2914,7 +3773,7 @@ PyTypeObject PyByteArray_Type = { 0, /* tp_setattr */ 0, /* tp_reserved */ (reprfunc)bytearray_repr, /* tp_repr */ - 0, /* tp_as_number */ + &bytearray_as_number, /* tp_as_number */ &bytearray_as_sequence, /* tp_as_sequence */ &bytearray_as_mapping, /* tp_as_mapping */ 0, /* tp_hash */ @@ -3025,9 +3884,13 @@ bytearrayiter_setstate(bytesiterobject *it, PyObject *state) Py_ssize_t index = PyLong_AsSsize_t(state); if (index == -1 && PyErr_Occurred()) return NULL; - if (index < 0) - index = 0; - it->it_index = index; + if (it->it_seq != NULL) { + if (index < 0) + index = 0; + else if (index > PyByteArray_GET_SIZE(it->it_seq)) + index = PyByteArray_GET_SIZE(it->it_seq); /* iterator exhausted */ + it->it_index = index; + } Py_RETURN_NONE; } @@ -3037,7 +3900,7 @@ static PyMethodDef bytearrayiter_methods[] = { {"__length_hint__", (PyCFunction)bytearrayiter_length_hint, METH_NOARGS, length_hint_doc}, {"__reduce__", (PyCFunction)bytearrayiter_reduce, METH_NOARGS, - reduce_doc}, + bytearray_reduce__doc__}, {"__setstate__", (PyCFunction)bytearrayiter_setstate, METH_O, setstate_doc}, {NULL, NULL} /* sentinel */ diff --git a/Objects/bytes_methods.c b/Objects/bytes_methods.c index 4e8107b49112..a29991584a09 100644 --- a/Objects/bytes_methods.c +++ b/Objects/bytes_methods.c @@ -363,61 +363,27 @@ for use in the bytes or bytearray translate method where each byte\n\ in frm is mapped to the byte at the same position in to.\n\ The bytes objects frm and to must be of the same length."); -static Py_ssize_t -_getbuffer(PyObject *obj, Py_buffer *view) -{ - PyBufferProcs *buffer = Py_TYPE(obj)->tp_as_buffer; - - if (buffer == NULL || buffer->bf_getbuffer == NULL) - { - PyErr_Format(PyExc_TypeError, - "Type %.100s doesn't support the buffer API", - Py_TYPE(obj)->tp_name); - return -1; - } - - if (buffer->bf_getbuffer(obj, view, PyBUF_SIMPLE) < 0) - return -1; - return view->len; -} - PyObject * -_Py_bytes_maketrans(PyObject *args) +_Py_bytes_maketrans(Py_buffer *frm, Py_buffer *to) { - PyObject *frm, *to, *res = NULL; - Py_buffer bfrm, bto; + PyObject *res = NULL; Py_ssize_t i; char *p; - bfrm.len = -1; - bto.len = -1; - - if (!PyArg_ParseTuple(args, "OO:maketrans", &frm, &to)) - return NULL; - if (_getbuffer(frm, &bfrm) < 0) - return NULL; - if (_getbuffer(to, &bto) < 0) - goto done; - if (bfrm.len != bto.len) { + if (frm->len != to->len) { PyErr_Format(PyExc_ValueError, "maketrans arguments must have same length"); - goto done; + return NULL; } res = PyBytes_FromStringAndSize(NULL, 256); - if (!res) { - goto done; - } + if (!res) + return NULL; p = PyBytes_AS_STRING(res); for (i = 0; i < 256; i++) p[i] = (char) i; - for (i = 0; i < bfrm.len; i++) { - p[((unsigned char *)bfrm.buf)[i]] = ((char *)bto.buf)[i]; + for (i = 0; i < frm->len; i++) { + p[((unsigned char *)frm->buf)[i]] = ((char *)to->buf)[i]; } -done: - if (bfrm.len != -1) - PyBuffer_Release(&bfrm); - if (bto.len != -1) - PyBuffer_Release(&bto); return res; } diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 8217b1eab30a..b015974f7c30 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -7,32 +7,10 @@ #include "bytes_methods.h" #include -static Py_ssize_t -_getbuffer(PyObject *obj, Py_buffer *view) -{ - PyBufferProcs *bufferprocs; - if (PyBytes_CheckExact(obj)) { - /* Fast path, e.g. for .join() of many bytes objects */ - Py_INCREF(obj); - view->obj = obj; - view->buf = PyBytes_AS_STRING(obj); - view->len = PyBytes_GET_SIZE(obj); - return view->len; - } - - bufferprocs = Py_TYPE(obj)->tp_as_buffer; - if (bufferprocs == NULL || bufferprocs->bf_getbuffer == NULL) - { - PyErr_Format(PyExc_TypeError, - "Type %.100s doesn't support the buffer API", - Py_TYPE(obj)->tp_name); - return -1; - } - - if (bufferprocs->bf_getbuffer(obj, view, PyBUF_SIMPLE) < 0) - return -1; - return view->len; -} +/*[clinic input] +class bytes "PyBytesObject*" "&PyBytes_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=1a1d9102afc1b00c]*/ #ifdef COUNT_ALLOCS Py_ssize_t null_strings, one_strings; @@ -71,15 +49,12 @@ static PyBytesObject *nullstring; PyBytes_FromStringAndSize()) or the length of the string in the `str' parameter (for PyBytes_FromString()). */ -PyObject * -PyBytes_FromStringAndSize(const char *str, Py_ssize_t size) +static PyObject * +_PyBytes_FromSize(Py_ssize_t size, int use_calloc) { PyBytesObject *op; - if (size < 0) { - PyErr_SetString(PyExc_SystemError, - "Negative size passed to PyBytes_FromStringAndSize"); - return NULL; - } + assert(size >= 0); + if (size == 0 && (op = nullstring) != NULL) { #ifdef COUNT_ALLOCS null_strings++; @@ -87,36 +62,60 @@ PyBytes_FromStringAndSize(const char *str, Py_ssize_t size) Py_INCREF(op); return (PyObject *)op; } - if (size == 1 && str != NULL && - (op = characters[*str & UCHAR_MAX]) != NULL) - { -#ifdef COUNT_ALLOCS - one_strings++; -#endif - Py_INCREF(op); - return (PyObject *)op; - } - if (size > PY_SSIZE_T_MAX - PyBytesObject_SIZE) { + if ((size_t)size > (size_t)PY_SSIZE_T_MAX - PyBytesObject_SIZE) { PyErr_SetString(PyExc_OverflowError, "byte string is too large"); return NULL; } /* Inline PyObject_NewVar */ - op = (PyBytesObject *)PyObject_MALLOC(PyBytesObject_SIZE + size); + if (use_calloc) + op = (PyBytesObject *)PyObject_Calloc(1, PyBytesObject_SIZE + size); + else + op = (PyBytesObject *)PyObject_Malloc(PyBytesObject_SIZE + size); if (op == NULL) return PyErr_NoMemory(); - PyObject_INIT_VAR(op, &PyBytes_Type, size); + (void)PyObject_INIT_VAR(op, &PyBytes_Type, size); op->ob_shash = -1; - if (str != NULL) - Py_MEMCPY(op->ob_sval, str, size); - op->ob_sval[size] = '\0'; - /* share short strings */ + if (!use_calloc) + op->ob_sval[size] = '\0'; + /* empty byte string singleton */ if (size == 0) { nullstring = op; Py_INCREF(op); - } else if (size == 1 && str != NULL) { + } + return (PyObject *) op; +} + +PyObject * +PyBytes_FromStringAndSize(const char *str, Py_ssize_t size) +{ + PyBytesObject *op; + if (size < 0) { + PyErr_SetString(PyExc_SystemError, + "Negative size passed to PyBytes_FromStringAndSize"); + return NULL; + } + if (size == 1 && str != NULL && + (op = characters[*str & UCHAR_MAX]) != NULL) + { +#ifdef COUNT_ALLOCS + one_strings++; +#endif + Py_INCREF(op); + return (PyObject *)op; + } + + op = (PyBytesObject *)_PyBytes_FromSize(size, 0); + if (op == NULL) + return NULL; + if (str == NULL) + return (PyObject *) op; + + Py_MEMCPY(op->ob_sval, str, size); + /* share short strings */ + if (size == 1) { characters[*str & UCHAR_MAX] = op; Py_INCREF(op); } @@ -155,7 +154,7 @@ PyBytes_FromString(const char *str) op = (PyBytesObject *)PyObject_MALLOC(PyBytesObject_SIZE + size); if (op == NULL) return PyErr_NoMemory(); - PyObject_INIT_VAR(op, &PyBytes_Type, size); + (void)PyObject_INIT_VAR(op, &PyBytes_Type, size); op->ob_shash = -1; Py_MEMCPY(op->ob_sval, str, size+1); /* share short strings */ @@ -195,8 +194,17 @@ PyBytes_FromFormatV(const char *format, va_list vargs) switch (*f) { case 'c': - (void)va_arg(count, int); - /* fall through... */ + { + int c = va_arg(count, int); + if (c < 0 || c > 255) { + PyErr_SetString(PyExc_OverflowError, + "PyBytes_FromFormatV(): %c format " + "expects an integer in range [0; 255]"); + return NULL; + } + n++; + break; + } case '%': n++; break; @@ -276,8 +284,12 @@ PyBytes_FromFormatV(const char *format, va_list vargs) switch (*f) { case 'c': - *s++ = va_arg(vargs, int); + { + int c = va_arg(vargs, int); + /* c has been checked for overflow in the first step */ + *s++ = (unsigned char)c; break; + } case 'd': if (longflag) sprintf(s, "%ld", va_arg(vargs, long)); @@ -361,6 +373,544 @@ PyBytes_FromFormat(const char *format, ...) return ret; } +/* Helpers for formatstring */ + +Py_LOCAL_INLINE(PyObject *) +getnextarg(PyObject *args, Py_ssize_t arglen, Py_ssize_t *p_argidx) +{ + Py_ssize_t argidx = *p_argidx; + if (argidx < arglen) { + (*p_argidx)++; + if (arglen < 0) + return args; + else + return PyTuple_GetItem(args, argidx); + } + PyErr_SetString(PyExc_TypeError, + "not enough arguments for format string"); + return NULL; +} + +/* Format codes + * F_LJUST '-' + * F_SIGN '+' + * F_BLANK ' ' + * F_ALT '#' + * F_ZERO '0' + */ +#define F_LJUST (1<<0) +#define F_SIGN (1<<1) +#define F_BLANK (1<<2) +#define F_ALT (1<<3) +#define F_ZERO (1<<4) + +/* Returns a new reference to a PyBytes object, or NULL on failure. */ + +static PyObject * +formatfloat(PyObject *v, int flags, int prec, int type) +{ + char *p; + PyObject *result; + double x; + + x = PyFloat_AsDouble(v); + if (x == -1.0 && PyErr_Occurred()) { + PyErr_Format(PyExc_TypeError, "float argument required, " + "not %.200s", Py_TYPE(v)->tp_name); + return NULL; + } + + if (prec < 0) + prec = 6; + + p = PyOS_double_to_string(x, type, prec, + (flags & F_ALT) ? Py_DTSF_ALT : 0, NULL); + + if (p == NULL) + return NULL; + result = PyBytes_FromStringAndSize(p, strlen(p)); + PyMem_Free(p); + return result; +} + +Py_LOCAL_INLINE(int) +byte_converter(PyObject *arg, char *p) +{ + if (PyBytes_Check(arg) && PyBytes_Size(arg) == 1) { + *p = PyBytes_AS_STRING(arg)[0]; + return 1; + } + else if (PyByteArray_Check(arg) && PyByteArray_Size(arg) == 1) { + *p = PyByteArray_AS_STRING(arg)[0]; + return 1; + } + else { + long ival = PyLong_AsLong(arg); + if (0 <= ival && ival <= 255) { + *p = (char)ival; + return 1; + } + } + PyErr_SetString(PyExc_TypeError, + "%c requires an integer in range(256) or a single byte"); + return 0; +} + +static PyObject * +format_obj(PyObject *v, const char **pbuf, Py_ssize_t *plen) +{ + PyObject *func, *result; + _Py_IDENTIFIER(__bytes__); + /* is it a bytes object? */ + if (PyBytes_Check(v)) { + *pbuf = PyBytes_AS_STRING(v); + *plen = PyBytes_GET_SIZE(v); + Py_INCREF(v); + return v; + } + if (PyByteArray_Check(v)) { + *pbuf = PyByteArray_AS_STRING(v); + *plen = PyByteArray_GET_SIZE(v); + Py_INCREF(v); + return v; + } + /* does it support __bytes__? */ + func = _PyObject_LookupSpecial(v, &PyId___bytes__); + if (func != NULL) { + result = PyObject_CallFunctionObjArgs(func, NULL); + Py_DECREF(func); + if (result == NULL) + return NULL; + if (!PyBytes_Check(result)) { + PyErr_Format(PyExc_TypeError, + "__bytes__ returned non-bytes (type %.200s)", + Py_TYPE(result)->tp_name); + Py_DECREF(result); + return NULL; + } + *pbuf = PyBytes_AS_STRING(result); + *plen = PyBytes_GET_SIZE(result); + return result; + } + PyErr_Format(PyExc_TypeError, + "%%b requires bytes, or an object that implements __bytes__, not '%.100s'", + Py_TYPE(v)->tp_name); + return NULL; +} + +/* fmt%(v1,v2,...) is roughly equivalent to sprintf(fmt, v1, v2, ...) + + FORMATBUFLEN is the length of the buffer in which the ints & + chars are formatted. XXX This is a magic number. Each formatting + routine does bounds checking to ensure no overflow, but a better + solution may be to malloc a buffer of appropriate size for each + format. For now, the current solution is sufficient. +*/ +#define FORMATBUFLEN (size_t)120 + +PyObject * +_PyBytes_Format(PyObject *format, PyObject *args) +{ + char *fmt, *res; + Py_ssize_t arglen, argidx; + Py_ssize_t reslen, rescnt, fmtcnt; + int args_owned = 0; + PyObject *result; + PyObject *dict = NULL; + if (format == NULL || !PyBytes_Check(format) || args == NULL) { + PyErr_BadInternalCall(); + return NULL; + } + fmt = PyBytes_AS_STRING(format); + fmtcnt = PyBytes_GET_SIZE(format); + reslen = rescnt = fmtcnt + 100; + result = PyBytes_FromStringAndSize((char *)NULL, reslen); + if (result == NULL) + return NULL; + res = PyBytes_AsString(result); + if (PyTuple_Check(args)) { + arglen = PyTuple_GET_SIZE(args); + argidx = 0; + } + else { + arglen = -1; + argidx = -2; + } + if (Py_TYPE(args)->tp_as_mapping && Py_TYPE(args)->tp_as_mapping->mp_subscript && + !PyTuple_Check(args) && !PyBytes_Check(args) && !PyUnicode_Check(args) && + !PyByteArray_Check(args)) { + dict = args; + } + while (--fmtcnt >= 0) { + if (*fmt != '%') { + if (--rescnt < 0) { + rescnt = fmtcnt + 100; + reslen += rescnt; + if (_PyBytes_Resize(&result, reslen)) + return NULL; + res = PyBytes_AS_STRING(result) + + reslen - rescnt; + --rescnt; + } + *res++ = *fmt++; + } + else { + /* Got a format specifier */ + int flags = 0; + Py_ssize_t width = -1; + int prec = -1; + int c = '\0'; + int fill; + PyObject *iobj; + PyObject *v = NULL; + PyObject *temp = NULL; + const char *pbuf = NULL; + int sign; + Py_ssize_t len = 0; + char onechar; /* For byte_converter() */ + + fmt++; + if (*fmt == '(') { + char *keystart; + Py_ssize_t keylen; + PyObject *key; + int pcount = 1; + + if (dict == NULL) { + PyErr_SetString(PyExc_TypeError, + "format requires a mapping"); + goto error; + } + ++fmt; + --fmtcnt; + keystart = fmt; + /* Skip over balanced parentheses */ + while (pcount > 0 && --fmtcnt >= 0) { + if (*fmt == ')') + --pcount; + else if (*fmt == '(') + ++pcount; + fmt++; + } + keylen = fmt - keystart - 1; + if (fmtcnt < 0 || pcount > 0) { + PyErr_SetString(PyExc_ValueError, + "incomplete format key"); + goto error; + } + key = PyBytes_FromStringAndSize(keystart, + keylen); + if (key == NULL) + goto error; + if (args_owned) { + Py_DECREF(args); + args_owned = 0; + } + args = PyObject_GetItem(dict, key); + Py_DECREF(key); + if (args == NULL) { + goto error; + } + args_owned = 1; + arglen = -1; + argidx = -2; + } + while (--fmtcnt >= 0) { + switch (c = *fmt++) { + case '-': flags |= F_LJUST; continue; + case '+': flags |= F_SIGN; continue; + case ' ': flags |= F_BLANK; continue; + case '#': flags |= F_ALT; continue; + case '0': flags |= F_ZERO; continue; + } + break; + } + if (c == '*') { + v = getnextarg(args, arglen, &argidx); + if (v == NULL) + goto error; + if (!PyLong_Check(v)) { + PyErr_SetString(PyExc_TypeError, + "* wants int"); + goto error; + } + width = PyLong_AsSsize_t(v); + if (width == -1 && PyErr_Occurred()) + goto error; + if (width < 0) { + flags |= F_LJUST; + width = -width; + } + if (--fmtcnt >= 0) + c = *fmt++; + } + else if (c >= 0 && isdigit(c)) { + width = c - '0'; + while (--fmtcnt >= 0) { + c = Py_CHARMASK(*fmt++); + if (!isdigit(c)) + break; + if (width > (PY_SSIZE_T_MAX - ((int)c - '0')) / 10) { + PyErr_SetString( + PyExc_ValueError, + "width too big"); + goto error; + } + width = width*10 + (c - '0'); + } + } + if (c == '.') { + prec = 0; + if (--fmtcnt >= 0) + c = *fmt++; + if (c == '*') { + v = getnextarg(args, arglen, &argidx); + if (v == NULL) + goto error; + if (!PyLong_Check(v)) { + PyErr_SetString( + PyExc_TypeError, + "* wants int"); + goto error; + } + prec = _PyLong_AsInt(v); + if (prec == -1 && PyErr_Occurred()) + goto error; + if (prec < 0) + prec = 0; + if (--fmtcnt >= 0) + c = *fmt++; + } + else if (c >= 0 && isdigit(c)) { + prec = c - '0'; + while (--fmtcnt >= 0) { + c = Py_CHARMASK(*fmt++); + if (!isdigit(c)) + break; + if (prec > (INT_MAX - ((int)c - '0')) / 10) { + PyErr_SetString( + PyExc_ValueError, + "prec too big"); + goto error; + } + prec = prec*10 + (c - '0'); + } + } + } /* prec */ + if (fmtcnt >= 0) { + if (c == 'h' || c == 'l' || c == 'L') { + if (--fmtcnt >= 0) + c = *fmt++; + } + } + if (fmtcnt < 0) { + PyErr_SetString(PyExc_ValueError, + "incomplete format"); + goto error; + } + if (c != '%') { + v = getnextarg(args, arglen, &argidx); + if (v == NULL) + goto error; + } + sign = 0; + fill = ' '; + switch (c) { + case '%': + pbuf = "%"; + len = 1; + break; + case 'a': + temp = PyObject_ASCII(v); + if (temp == NULL) + goto error; + assert(PyUnicode_IS_ASCII(temp)); + pbuf = (const char *)PyUnicode_1BYTE_DATA(temp); + len = PyUnicode_GET_LENGTH(temp); + if (prec >= 0 && len > prec) + len = prec; + break; + case 's': + // %s is only for 2/3 code; 3 only code should use %b + case 'b': + temp = format_obj(v, &pbuf, &len); + if (temp == NULL) + goto error; + if (prec >= 0 && len > prec) + len = prec; + break; + case 'i': + case 'd': + case 'u': + case 'o': + case 'x': + case 'X': + if (c == 'i') + c = 'd'; + iobj = NULL; + if (PyNumber_Check(v)) { + if ((PyLong_Check(v))) { + iobj = v; + Py_INCREF(iobj); + } + else { + iobj = PyNumber_Long(v); + if (iobj != NULL && !PyLong_Check(iobj)) + Py_CLEAR(iobj); + } + } + if (iobj == NULL) { + PyErr_Format(PyExc_TypeError, + "%%%c format: a number is required, " + "not %.200s", c, Py_TYPE(v)->tp_name); + goto error; + } + temp = _PyUnicode_FormatLong(iobj, flags & F_ALT, prec, c); + Py_DECREF(iobj); + if (!temp) + goto error; + assert(PyUnicode_IS_ASCII(temp)); + pbuf = (const char *)PyUnicode_1BYTE_DATA(temp); + len = PyUnicode_GET_LENGTH(temp); + sign = 1; + if (flags & F_ZERO) + fill = '0'; + break; + case 'e': + case 'E': + case 'f': + case 'F': + case 'g': + case 'G': + temp = formatfloat(v, flags, prec, c); + if (temp == NULL) + goto error; + pbuf = PyBytes_AS_STRING(temp); + len = PyBytes_GET_SIZE(temp); + sign = 1; + if (flags & F_ZERO) + fill = '0'; + break; + case 'c': + pbuf = &onechar; + len = byte_converter(v, &onechar); + if (!len) + goto error; + break; + default: + PyErr_Format(PyExc_ValueError, + "unsupported format character '%c' (0x%x) " + "at index %zd", + c, c, + (Py_ssize_t)(fmt - 1 - + PyBytes_AsString(format))); + goto error; + } + if (sign) { + if (*pbuf == '-' || *pbuf == '+') { + sign = *pbuf++; + len--; + } + else if (flags & F_SIGN) + sign = '+'; + else if (flags & F_BLANK) + sign = ' '; + else + sign = 0; + } + if (width < len) + width = len; + if (rescnt - (sign != 0) < width) { + reslen -= rescnt; + rescnt = width + fmtcnt + 100; + reslen += rescnt; + if (reslen < 0) { + Py_DECREF(result); + Py_XDECREF(temp); + return PyErr_NoMemory(); + } + if (_PyBytes_Resize(&result, reslen)) { + Py_XDECREF(temp); + return NULL; + } + res = PyBytes_AS_STRING(result) + + reslen - rescnt; + } + if (sign) { + if (fill != ' ') + *res++ = sign; + rescnt--; + if (width > len) + width--; + } + if ((flags & F_ALT) && (c == 'x' || c == 'X')) { + assert(pbuf[0] == '0'); + assert(pbuf[1] == c); + if (fill != ' ') { + *res++ = *pbuf++; + *res++ = *pbuf++; + } + rescnt -= 2; + width -= 2; + if (width < 0) + width = 0; + len -= 2; + } + if (width > len && !(flags & F_LJUST)) { + do { + --rescnt; + *res++ = fill; + } while (--width > len); + } + if (fill == ' ') { + if (sign) + *res++ = sign; + if ((flags & F_ALT) && + (c == 'x' || c == 'X')) { + assert(pbuf[0] == '0'); + assert(pbuf[1] == c); + *res++ = *pbuf++; + *res++ = *pbuf++; + } + } + Py_MEMCPY(res, pbuf, len); + res += len; + rescnt -= len; + while (--width >= len) { + --rescnt; + *res++ = ' '; + } + if (dict && (argidx < arglen) && c != '%') { + PyErr_SetString(PyExc_TypeError, + "not all arguments converted during bytes formatting"); + Py_XDECREF(temp); + goto error; + } + Py_XDECREF(temp); + } /* '%' */ + } /* until end */ + if (argidx < arglen && !dict) { + PyErr_SetString(PyExc_TypeError, + "not all arguments converted during bytes formatting"); + goto error; + } + if (args_owned) { + Py_DECREF(args); + } + if (_PyBytes_Resize(&result, reslen - rescnt)) + return NULL; + return result; + + error: + Py_DECREF(result); + if (args_owned) { + Py_DECREF(args); + } + return NULL; +} + +/* =-= */ + static void bytes_dealloc(PyObject *op) { @@ -554,8 +1104,8 @@ PyBytes_AsStringAndSize(PyObject *obj, if (len != NULL) *len = PyBytes_GET_SIZE(obj); else if (strlen(*s) != (size_t)PyBytes_GET_SIZE(obj)) { - PyErr_SetString(PyExc_TypeError, - "expected bytes with no null"); + PyErr_SetString(PyExc_ValueError, + "embedded null byte"); return -1; } return 0; @@ -581,7 +1131,7 @@ PyBytes_Repr(PyObject *obj, int smartquotes) { PyBytesObject* op = (PyBytesObject*) obj; Py_ssize_t i, length = Py_SIZE(op); - size_t newsize, squotes, dquotes; + Py_ssize_t newsize, squotes, dquotes; PyObject *v; unsigned char quote, *s, *p; @@ -590,28 +1140,27 @@ PyBytes_Repr(PyObject *obj, int smartquotes) newsize = 3; /* b'' */ s = (unsigned char*)op->ob_sval; for (i = 0; i < length; i++) { + Py_ssize_t incr = 1; switch(s[i]) { - case '\'': squotes++; newsize++; break; - case '"': dquotes++; newsize++; break; + case '\'': squotes++; break; + case '"': dquotes++; break; case '\\': case '\t': case '\n': case '\r': - newsize += 2; break; /* \C */ + incr = 2; break; /* \C */ default: if (s[i] < ' ' || s[i] >= 0x7f) - newsize += 4; /* \xHH */ - else - newsize++; + incr = 4; /* \xHH */ } + if (newsize > PY_SSIZE_T_MAX - incr) + goto overflow; + newsize += incr; } quote = '\''; if (smartquotes && squotes && !dquotes) quote = '"'; - if (squotes && quote == '\'') + if (squotes && quote == '\'') { + if (newsize > PY_SSIZE_T_MAX - squotes) + goto overflow; newsize += squotes; - - if (newsize > (PY_SSIZE_T_MAX - sizeof(PyUnicodeObject) - 1)) { - PyErr_SetString(PyExc_OverflowError, - "bytes object is too large to make repr"); - return NULL; } v = PyUnicode_New(newsize, 127); @@ -643,6 +1192,11 @@ PyBytes_Repr(PyObject *obj, int smartquotes) *p++ = quote; assert(_PyUnicode_CheckConsistency(v, 1)); return v; + + overflow: + PyErr_SetString(PyExc_OverflowError, + "bytes object is too large to make repr"); + return NULL; } static PyObject * @@ -678,8 +1232,8 @@ bytes_concat(PyObject *a, PyObject *b) va.len = -1; vb.len = -1; - if (_getbuffer(a, &va) < 0 || - _getbuffer(b, &vb) < 0) { + if (PyObject_GetBuffer(a, &va, PyBUF_SIMPLE) != 0 || + PyObject_GetBuffer(b, &vb, PyBUF_SIMPLE) != 0) { PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s", Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name); goto done; @@ -749,7 +1303,7 @@ bytes_repeat(PyBytesObject *a, Py_ssize_t n) op = (PyBytesObject *)PyObject_MALLOC(PyBytesObject_SIZE + nbytes); if (op == NULL) return PyErr_NoMemory(); - PyObject_INIT_VAR(op, &PyBytes_Type, size); + (void)PyObject_INIT_VAR(op, &PyBytes_Type, size); op->ob_shash = -1; op->ob_sval[size] = '\0'; if (Py_SIZE(a) == 1 && n > 0) { @@ -777,7 +1331,7 @@ bytes_contains(PyObject *self, PyObject *arg) Py_buffer varg; Py_ssize_t pos; PyErr_Clear(); - if (_getbuffer(arg, &varg) < 0) + if (PyObject_GetBuffer(arg, &varg, PyBUF_SIMPLE) != 0) return -1; pos = stringlib_find(PyBytes_AS_STRING(self), Py_SIZE(self), varg.buf, varg.len, 0); @@ -961,7 +1515,7 @@ bytes_subscript(PyBytesObject* self, PyObject* item) } else { PyErr_Format(PyExc_TypeError, - "byte indices must be integers, not %.200s", + "byte indices must be integers or slices, not %.200s", Py_TYPE(item)->tp_name); return NULL; } @@ -1001,37 +1555,72 @@ static PyBufferProcs bytes_as_buffer = { #define RIGHTSTRIP 1 #define BOTHSTRIP 2 -/* Arrays indexed by above */ -static const char *stripformat[] = {"|O:lstrip", "|O:rstrip", "|O:strip"}; +/*[clinic input] +bytes.split + + sep: object = None + The delimiter according which to split the bytes. + None (the default value) means split on ASCII whitespace characters + (space, tab, return, newline, formfeed, vertical tab). + maxsplit: Py_ssize_t = -1 + Maximum number of splits to do. + -1 (the default value) means no limit. + +Return a list of the sections in the bytes, using sep as the delimiter. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytes_split__doc__, +"split($self, /, sep=None, maxsplit=-1)\n" +"--\n" +"\n" +"Return a list of the sections in the bytes, using sep as the delimiter.\n" +"\n" +" sep\n" +" The delimiter according which to split the bytes.\n" +" None (the default value) means split on ASCII whitespace characters\n" +" (space, tab, return, newline, formfeed, vertical tab).\n" +" maxsplit\n" +" Maximum number of splits to do.\n" +" -1 (the default value) means no limit."); + +#define BYTES_SPLIT_METHODDEF \ + {"split", (PyCFunction)bytes_split, METH_VARARGS|METH_KEYWORDS, bytes_split__doc__}, -#define STRIPNAME(i) (stripformat[i]+3) +static PyObject * +bytes_split_impl(PyBytesObject*self, PyObject *sep, Py_ssize_t maxsplit); -PyDoc_STRVAR(split__doc__, -"B.split(sep=None, maxsplit=-1) -> list of bytes\n\ -\n\ -Return a list of the sections in B, using sep as the delimiter.\n\ -If sep is not specified or is None, B is split on ASCII whitespace\n\ -characters (space, tab, return, newline, formfeed, vertical tab).\n\ -If maxsplit is given, at most maxsplit splits are done."); +static PyObject * +bytes_split(PyBytesObject*self, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"sep", "maxsplit", NULL}; + PyObject *sep = Py_None; + Py_ssize_t maxsplit = -1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "|On:split", _keywords, + &sep, &maxsplit)) + goto exit; + return_value = bytes_split_impl(self, sep, maxsplit); + +exit: + return return_value; +} static PyObject * -bytes_split(PyBytesObject *self, PyObject *args, PyObject *kwds) +bytes_split_impl(PyBytesObject*self, PyObject *sep, Py_ssize_t maxsplit) +/*[clinic end generated code: output=c80a47afdd505975 input=8b809b39074abbfa]*/ { - static char *kwlist[] = {"sep", "maxsplit", 0}; Py_ssize_t len = PyBytes_GET_SIZE(self), n; - Py_ssize_t maxsplit = -1; const char *s = PyBytes_AS_STRING(self), *sub; Py_buffer vsub; - PyObject *list, *subobj = Py_None; + PyObject *list; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|On:split", - kwlist, &subobj, &maxsplit)) - return NULL; if (maxsplit < 0) maxsplit = PY_SSIZE_T_MAX; - if (subobj == Py_None) + if (sep == Py_None) return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit); - if (_getbuffer(subobj, &vsub) < 0) + if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0) return NULL; sub = vsub.buf; n = vsub.len; @@ -1041,89 +1630,202 @@ bytes_split(PyBytesObject *self, PyObject *args, PyObject *kwds) return list; } -PyDoc_STRVAR(partition__doc__, -"B.partition(sep) -> (head, sep, tail)\n\ -\n\ -Search for the separator sep in B, and return the part before it,\n\ -the separator itself, and the part after it. If the separator is not\n\ -found, returns B and two empty bytes objects."); +/*[clinic input] +bytes.partition + + self: self(type="PyBytesObject *") + sep: Py_buffer + / + +Partition the bytes into three parts using the given separator. + +This will search for the separator sep in the bytes. If the separator is found, +returns a 3-tuple containing the part before the separator, the separator +itself, and the part after it. + +If the separator is not found, returns a 3-tuple containing the original bytes +object and two empty bytes objects. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytes_partition__doc__, +"partition($self, sep, /)\n" +"--\n" +"\n" +"Partition the bytes into three parts using the given separator.\n" +"\n" +"This will search for the separator sep in the bytes. If the separator is found,\n" +"returns a 3-tuple containing the part before the separator, the separator\n" +"itself, and the part after it.\n" +"\n" +"If the separator is not found, returns a 3-tuple containing the original bytes\n" +"object and two empty bytes objects."); + +#define BYTES_PARTITION_METHODDEF \ + {"partition", (PyCFunction)bytes_partition, METH_VARARGS, bytes_partition__doc__}, + +static PyObject * +bytes_partition_impl(PyBytesObject *self, Py_buffer *sep); static PyObject * -bytes_partition(PyBytesObject *self, PyObject *sep_obj) +bytes_partition(PyBytesObject *self, PyObject *args) { - const char *sep; - Py_ssize_t sep_len; + PyObject *return_value = NULL; + Py_buffer sep = {NULL, NULL}; - if (PyBytes_Check(sep_obj)) { - sep = PyBytes_AS_STRING(sep_obj); - sep_len = PyBytes_GET_SIZE(sep_obj); - } - else if (PyObject_AsCharBuffer(sep_obj, &sep, &sep_len)) - return NULL; + if (!PyArg_ParseTuple(args, + "y*:partition", + &sep)) + goto exit; + return_value = bytes_partition_impl(self, &sep); + +exit: + /* Cleanup for sep */ + if (sep.obj) + PyBuffer_Release(&sep); + return return_value; +} + +static PyObject * +bytes_partition_impl(PyBytesObject *self, Py_buffer *sep) +/*[clinic end generated code: output=3006727cfbf83aa4 input=bc855dc63ca949de]*/ +{ return stringlib_partition( (PyObject*) self, PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), - sep_obj, sep, sep_len + sep->obj, (const char *)sep->buf, sep->len ); } -PyDoc_STRVAR(rpartition__doc__, -"B.rpartition(sep) -> (head, sep, tail)\n\ -\n\ -Search for the separator sep in B, starting at the end of B,\n\ -and return the part before it, the separator itself, and the\n\ -part after it. If the separator is not found, returns two empty\n\ -bytes objects and B."); +/*[clinic input] +bytes.rpartition + + self: self(type="PyBytesObject *") + sep: Py_buffer + / + +Partition the bytes into three parts using the given separator. + +This will search for the separator sep in the bytes, starting and the end. If +the separator is found, returns a 3-tuple containing the part before the +separator, the separator itself, and the part after it. + +If the separator is not found, returns a 3-tuple containing two empty bytes +objects and the original bytes object. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytes_rpartition__doc__, +"rpartition($self, sep, /)\n" +"--\n" +"\n" +"Partition the bytes into three parts using the given separator.\n" +"\n" +"This will search for the separator sep in the bytes, starting and the end. If\n" +"the separator is found, returns a 3-tuple containing the part before the\n" +"separator, the separator itself, and the part after it.\n" +"\n" +"If the separator is not found, returns a 3-tuple containing two empty bytes\n" +"objects and the original bytes object."); + +#define BYTES_RPARTITION_METHODDEF \ + {"rpartition", (PyCFunction)bytes_rpartition, METH_VARARGS, bytes_rpartition__doc__}, static PyObject * -bytes_rpartition(PyBytesObject *self, PyObject *sep_obj) +bytes_rpartition_impl(PyBytesObject *self, Py_buffer *sep); + +static PyObject * +bytes_rpartition(PyBytesObject *self, PyObject *args) { - const char *sep; - Py_ssize_t sep_len; + PyObject *return_value = NULL; + Py_buffer sep = {NULL, NULL}; - if (PyBytes_Check(sep_obj)) { - sep = PyBytes_AS_STRING(sep_obj); - sep_len = PyBytes_GET_SIZE(sep_obj); - } - else if (PyObject_AsCharBuffer(sep_obj, &sep, &sep_len)) - return NULL; + if (!PyArg_ParseTuple(args, + "y*:rpartition", + &sep)) + goto exit; + return_value = bytes_rpartition_impl(self, &sep); +exit: + /* Cleanup for sep */ + if (sep.obj) + PyBuffer_Release(&sep); + + return return_value; +} + +static PyObject * +bytes_rpartition_impl(PyBytesObject *self, Py_buffer *sep) +/*[clinic end generated code: output=57b169dc47fa90e8 input=6588fff262a9170e]*/ +{ return stringlib_rpartition( (PyObject*) self, PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), - sep_obj, sep, sep_len + sep->obj, (const char *)sep->buf, sep->len ); } -PyDoc_STRVAR(rsplit__doc__, -"B.rsplit(sep=None, maxsplit=-1) -> list of bytes\n\ -\n\ -Return a list of the sections in B, using sep as the delimiter,\n\ -starting at the end of B and working to the front.\n\ -If sep is not given, B is split on ASCII whitespace characters\n\ -(space, tab, return, newline, formfeed, vertical tab).\n\ -If maxsplit is given, at most maxsplit splits are done."); +/*[clinic input] +bytes.rsplit = bytes.split + +Return a list of the sections in the bytes, using sep as the delimiter. + +Splitting is done starting at the end of the bytes and working to the front. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytes_rsplit__doc__, +"rsplit($self, /, sep=None, maxsplit=-1)\n" +"--\n" +"\n" +"Return a list of the sections in the bytes, using sep as the delimiter.\n" +"\n" +" sep\n" +" The delimiter according which to split the bytes.\n" +" None (the default value) means split on ASCII whitespace characters\n" +" (space, tab, return, newline, formfeed, vertical tab).\n" +" maxsplit\n" +" Maximum number of splits to do.\n" +" -1 (the default value) means no limit.\n" +"\n" +"Splitting is done starting at the end of the bytes and working to the front."); + +#define BYTES_RSPLIT_METHODDEF \ + {"rsplit", (PyCFunction)bytes_rsplit, METH_VARARGS|METH_KEYWORDS, bytes_rsplit__doc__}, +static PyObject * +bytes_rsplit_impl(PyBytesObject*self, PyObject *sep, Py_ssize_t maxsplit); static PyObject * -bytes_rsplit(PyBytesObject *self, PyObject *args, PyObject *kwds) +bytes_rsplit(PyBytesObject*self, PyObject *args, PyObject *kwargs) { - static char *kwlist[] = {"sep", "maxsplit", 0}; - Py_ssize_t len = PyBytes_GET_SIZE(self), n; + PyObject *return_value = NULL; + static char *_keywords[] = {"sep", "maxsplit", NULL}; + PyObject *sep = Py_None; Py_ssize_t maxsplit = -1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "|On:rsplit", _keywords, + &sep, &maxsplit)) + goto exit; + return_value = bytes_rsplit_impl(self, sep, maxsplit); + +exit: + return return_value; +} + +static PyObject * +bytes_rsplit_impl(PyBytesObject*self, PyObject *sep, Py_ssize_t maxsplit) +/*[clinic end generated code: output=f86feddedbd7b26d input=0f86c9f28f7d7b7b]*/ +{ + Py_ssize_t len = PyBytes_GET_SIZE(self), n; const char *s = PyBytes_AS_STRING(self), *sub; Py_buffer vsub; - PyObject *list, *subobj = Py_None; + PyObject *list; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|On:rsplit", - kwlist, &subobj, &maxsplit)) - return NULL; if (maxsplit < 0) maxsplit = PY_SSIZE_T_MAX; - if (subobj == Py_None) + if (sep == Py_None) return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit); - if (_getbuffer(subobj, &vsub) < 0) + if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0) return NULL; sub = vsub.buf; n = vsub.len; @@ -1134,16 +1836,41 @@ bytes_rsplit(PyBytesObject *self, PyObject *args, PyObject *kwds) } -PyDoc_STRVAR(join__doc__, -"B.join(iterable_of_bytes) -> bytes\n\ -\n\ -Concatenate any number of bytes objects, with B in between each pair.\n\ -Example: b'.'.join([b'ab', b'pq', b'rs']) -> b'ab.pq.rs'."); +/*[clinic input] +bytes.join + + iterable_of_bytes: object + / + +Concatenate any number of bytes objects. + +The bytes whose method is called is inserted in between each pair. + +The result is returned as a new bytes object. + +Example: b'.'.join([b'ab', b'pq', b'rs']) -> b'ab.pq.rs'. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytes_join__doc__, +"join($self, iterable_of_bytes, /)\n" +"--\n" +"\n" +"Concatenate any number of bytes objects.\n" +"\n" +"The bytes whose method is called is inserted in between each pair.\n" +"\n" +"The result is returned as a new bytes object.\n" +"\n" +"Example: b\'.\'.join([b\'ab\', b\'pq\', b\'rs\']) -> b\'ab.pq.rs\'."); + +#define BYTES_JOIN_METHODDEF \ + {"join", (PyCFunction)bytes_join, METH_O, bytes_join__doc__}, static PyObject * -bytes_join(PyObject *self, PyObject *iterable) +bytes_join(PyBytesObject*self, PyObject *iterable_of_bytes) +/*[clinic end generated code: output=e541a14a8da97908 input=7fe377b95bd549d2]*/ { - return stringlib_bytes_join(self, iterable); + return stringlib_bytes_join((PyObject*)self, iterable_of_bytes); } PyObject * @@ -1151,7 +1878,7 @@ _PyBytes_Join(PyObject *sep, PyObject *x) { assert(sep != NULL && PyBytes_Check(sep)); assert(x != NULL); - return bytes_join(sep, x); + return bytes_join((PyBytesObject*)sep, x); } /* helper macro to fixup start/end slice values */ @@ -1185,7 +1912,7 @@ bytes_find_internal(PyBytesObject *self, PyObject *args, int dir) return -2; if (subobj) { - if (_getbuffer(subobj, &subbuf) < 0) + if (PyObject_GetBuffer(subobj, &subbuf, PyBUF_SIMPLE) != 0) return -2; sub = subbuf.buf; @@ -1300,7 +2027,7 @@ do_xstrip(PyBytesObject *self, int striptype, PyObject *sepobj) Py_ssize_t seplen; Py_ssize_t i, j; - if (_getbuffer(sepobj, &vsep) < 0) + if (PyObject_GetBuffer(sepobj, &vsep, PyBUF_SIMPLE) != 0) return NULL; sep = vsep.buf; seplen = vsep.len; @@ -1362,62 +2089,159 @@ do_strip(PyBytesObject *self, int striptype) Py_LOCAL_INLINE(PyObject *) -do_argstrip(PyBytesObject *self, int striptype, PyObject *args) +do_argstrip(PyBytesObject *self, int striptype, PyObject *bytes) { - PyObject *sep = NULL; - - if (!PyArg_ParseTuple(args, stripformat[striptype], &sep)) - return NULL; - - if (sep != NULL && sep != Py_None) { - return do_xstrip(self, striptype, sep); + if (bytes != NULL && bytes != Py_None) { + return do_xstrip(self, striptype, bytes); } return do_strip(self, striptype); } +/*[clinic input] +bytes.strip + + self: self(type="PyBytesObject *") + bytes: object = None + / + +Strip leading and trailing bytes contained in the argument. + +If the argument is omitted or None, strip leading and trailing ASCII whitespace. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytes_strip__doc__, +"strip($self, bytes=None, /)\n" +"--\n" +"\n" +"Strip leading and trailing bytes contained in the argument.\n" +"\n" +"If the argument is omitted or None, strip leading and trailing ASCII whitespace."); + +#define BYTES_STRIP_METHODDEF \ + {"strip", (PyCFunction)bytes_strip, METH_VARARGS, bytes_strip__doc__}, + +static PyObject * +bytes_strip_impl(PyBytesObject *self, PyObject *bytes); -PyDoc_STRVAR(strip__doc__, -"B.strip([bytes]) -> bytes\n\ -\n\ -Strip leading and trailing bytes contained in the argument.\n\ -If the argument is omitted, strip leading and trailing ASCII whitespace."); static PyObject * bytes_strip(PyBytesObject *self, PyObject *args) { - if (PyTuple_GET_SIZE(args) == 0) - return do_strip(self, BOTHSTRIP); /* Common case */ - else - return do_argstrip(self, BOTHSTRIP, args); + PyObject *return_value = NULL; + PyObject *bytes = Py_None; + + if (!PyArg_UnpackTuple(args, "strip", + 0, 1, + &bytes)) + goto exit; + return_value = bytes_strip_impl(self, bytes); + +exit: + return return_value; } +static PyObject * +bytes_strip_impl(PyBytesObject *self, PyObject *bytes) +/*[clinic end generated code: output=c8234a599ba5ec35 input=37daa5fad1395d95]*/ +{ + return do_argstrip(self, BOTHSTRIP, bytes); +} + +/*[clinic input] +bytes.lstrip + + self: self(type="PyBytesObject *") + bytes: object = None + / + +Strip leading bytes contained in the argument. + +If the argument is omitted or None, strip leading ASCII whitespace. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytes_lstrip__doc__, +"lstrip($self, bytes=None, /)\n" +"--\n" +"\n" +"Strip leading bytes contained in the argument.\n" +"\n" +"If the argument is omitted or None, strip leading ASCII whitespace."); + +#define BYTES_LSTRIP_METHODDEF \ + {"lstrip", (PyCFunction)bytes_lstrip, METH_VARARGS, bytes_lstrip__doc__}, + +static PyObject * +bytes_lstrip_impl(PyBytesObject *self, PyObject *bytes); -PyDoc_STRVAR(lstrip__doc__, -"B.lstrip([bytes]) -> bytes\n\ -\n\ -Strip leading bytes contained in the argument.\n\ -If the argument is omitted, strip leading ASCII whitespace."); static PyObject * bytes_lstrip(PyBytesObject *self, PyObject *args) { - if (PyTuple_GET_SIZE(args) == 0) - return do_strip(self, LEFTSTRIP); /* Common case */ - else - return do_argstrip(self, LEFTSTRIP, args); + PyObject *return_value = NULL; + PyObject *bytes = Py_None; + + if (!PyArg_UnpackTuple(args, "lstrip", + 0, 1, + &bytes)) + goto exit; + return_value = bytes_lstrip_impl(self, bytes); + +exit: + return return_value; } +static PyObject * +bytes_lstrip_impl(PyBytesObject *self, PyObject *bytes) +/*[clinic end generated code: output=529e8511ab6f1115 input=88811b09dfbc2988]*/ +{ + return do_argstrip(self, LEFTSTRIP, bytes); +} + +/*[clinic input] +bytes.rstrip + + self: self(type="PyBytesObject *") + bytes: object = None + / + +Strip trailing bytes contained in the argument. + +If the argument is omitted or None, strip trailing ASCII whitespace. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytes_rstrip__doc__, +"rstrip($self, bytes=None, /)\n" +"--\n" +"\n" +"Strip trailing bytes contained in the argument.\n" +"\n" +"If the argument is omitted or None, strip trailing ASCII whitespace."); + +#define BYTES_RSTRIP_METHODDEF \ + {"rstrip", (PyCFunction)bytes_rstrip, METH_VARARGS, bytes_rstrip__doc__}, + +static PyObject * +bytes_rstrip_impl(PyBytesObject *self, PyObject *bytes); -PyDoc_STRVAR(rstrip__doc__, -"B.rstrip([bytes]) -> bytes\n\ -\n\ -Strip trailing bytes contained in the argument.\n\ -If the argument is omitted, strip trailing ASCII whitespace."); static PyObject * bytes_rstrip(PyBytesObject *self, PyObject *args) { - if (PyTuple_GET_SIZE(args) == 0) - return do_strip(self, RIGHTSTRIP); /* Common case */ - else - return do_argstrip(self, RIGHTSTRIP, args); + PyObject *return_value = NULL; + PyObject *bytes = Py_None; + + if (!PyArg_UnpackTuple(args, "rstrip", + 0, 1, + &bytes)) + goto exit; + return_value = bytes_rstrip_impl(self, bytes); + +exit: + return return_value; +} + +static PyObject * +bytes_rstrip_impl(PyBytesObject *self, PyObject *bytes) +/*[clinic end generated code: output=e98730bd133e6593 input=8f93c9cd361f0140]*/ +{ + return do_argstrip(self, RIGHTSTRIP, bytes); } @@ -1445,7 +2269,7 @@ bytes_count(PyBytesObject *self, PyObject *args) return NULL; if (sub_obj) { - if (_getbuffer(sub_obj, &vsub) < 0) + if (PyObject_GetBuffer(sub_obj, &vsub, PyBUF_SIMPLE) != 0) return NULL; sub = vsub.buf; @@ -1469,92 +2293,162 @@ bytes_count(PyBytesObject *self, PyObject *args) } -PyDoc_STRVAR(translate__doc__, -"B.translate(table[, deletechars]) -> bytes\n\ -\n\ -Return a copy of B, where all characters occurring in the\n\ -optional argument deletechars are removed, and the remaining\n\ -characters have been mapped through the given translation\n\ -table, which must be a bytes object of length 256."); +/*[clinic input] +bytes.translate + + self: self(type="PyBytesObject *") + table: object + Translation table, which must be a bytes object of length 256. + [ + deletechars: object + ] + / + +Return a copy with each character mapped by the given translation table. + +All characters occurring in the optional argument deletechars are removed. +The remaining characters are mapped through the given translation table. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytes_translate__doc__, +"translate(table, [deletechars])\n" +"Return a copy with each character mapped by the given translation table.\n" +"\n" +" table\n" +" Translation table, which must be a bytes object of length 256.\n" +"\n" +"All characters occurring in the optional argument deletechars are removed.\n" +"The remaining characters are mapped through the given translation table."); + +#define BYTES_TRANSLATE_METHODDEF \ + {"translate", (PyCFunction)bytes_translate, METH_VARARGS, bytes_translate__doc__}, + +static PyObject * +bytes_translate_impl(PyBytesObject *self, PyObject *table, int group_right_1, PyObject *deletechars); static PyObject * bytes_translate(PyBytesObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *table; + int group_right_1 = 0; + PyObject *deletechars = NULL; + + switch (PyTuple_GET_SIZE(args)) { + case 1: + if (!PyArg_ParseTuple(args, "O:translate", &table)) + goto exit; + break; + case 2: + if (!PyArg_ParseTuple(args, "OO:translate", &table, &deletechars)) + goto exit; + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "bytes.translate requires 1 to 2 arguments"); + goto exit; + } + return_value = bytes_translate_impl(self, table, group_right_1, deletechars); + +exit: + return return_value; +} + +static PyObject * +bytes_translate_impl(PyBytesObject *self, PyObject *table, int group_right_1, PyObject *deletechars) +/*[clinic end generated code: output=f0f29a57f41df5d8 input=d8fa5519d7cc4be7]*/ { char *input, *output; - const char *table; + Py_buffer table_view = {NULL, NULL}; + Py_buffer del_table_view = {NULL, NULL}; + const char *table_chars; Py_ssize_t i, c, changed = 0; PyObject *input_obj = (PyObject*)self; - const char *output_start, *del_table=NULL; + const char *output_start, *del_table_chars=NULL; Py_ssize_t inlen, tablen, dellen = 0; PyObject *result; int trans_table[256]; - PyObject *tableobj, *delobj = NULL; - - if (!PyArg_UnpackTuple(args, "translate", 1, 2, - &tableobj, &delobj)) - return NULL; - if (PyBytes_Check(tableobj)) { - table = PyBytes_AS_STRING(tableobj); - tablen = PyBytes_GET_SIZE(tableobj); + if (PyBytes_Check(table)) { + table_chars = PyBytes_AS_STRING(table); + tablen = PyBytes_GET_SIZE(table); } - else if (tableobj == Py_None) { - table = NULL; + else if (table == Py_None) { + table_chars = NULL; tablen = 256; } - else if (PyObject_AsCharBuffer(tableobj, &table, &tablen)) - return NULL; + else { + if (PyObject_GetBuffer(table, &table_view, PyBUF_SIMPLE) != 0) + return NULL; + table_chars = table_view.buf; + tablen = table_view.len; + } if (tablen != 256) { PyErr_SetString(PyExc_ValueError, "translation table must be 256 characters long"); + PyBuffer_Release(&table_view); return NULL; } - if (delobj != NULL) { - if (PyBytes_Check(delobj)) { - del_table = PyBytes_AS_STRING(delobj); - dellen = PyBytes_GET_SIZE(delobj); + if (deletechars != NULL) { + if (PyBytes_Check(deletechars)) { + del_table_chars = PyBytes_AS_STRING(deletechars); + dellen = PyBytes_GET_SIZE(deletechars); + } + else { + if (PyObject_GetBuffer(deletechars, &del_table_view, PyBUF_SIMPLE) != 0) { + PyBuffer_Release(&table_view); + return NULL; + } + del_table_chars = del_table_view.buf; + dellen = del_table_view.len; } - else if (PyObject_AsCharBuffer(delobj, &del_table, &dellen)) - return NULL; } else { - del_table = NULL; + del_table_chars = NULL; dellen = 0; } inlen = PyBytes_GET_SIZE(input_obj); result = PyBytes_FromStringAndSize((char *)NULL, inlen); - if (result == NULL) + if (result == NULL) { + PyBuffer_Release(&del_table_view); + PyBuffer_Release(&table_view); return NULL; + } output_start = output = PyBytes_AsString(result); input = PyBytes_AS_STRING(input_obj); - if (dellen == 0 && table != NULL) { + if (dellen == 0 && table_chars != NULL) { /* If no deletions are required, use faster code */ for (i = inlen; --i >= 0; ) { c = Py_CHARMASK(*input++); - if (Py_CHARMASK((*output++ = table[c])) != c) + if (Py_CHARMASK((*output++ = table_chars[c])) != c) changed = 1; } - if (changed || !PyBytes_CheckExact(input_obj)) - return result; - Py_DECREF(result); - Py_INCREF(input_obj); - return input_obj; + if (!changed && PyBytes_CheckExact(input_obj)) { + Py_INCREF(input_obj); + Py_DECREF(result); + result = input_obj; + } + PyBuffer_Release(&del_table_view); + PyBuffer_Release(&table_view); + return result; } - if (table == NULL) { + if (table_chars == NULL) { for (i = 0; i < 256; i++) trans_table[i] = Py_CHARMASK(i); } else { for (i = 0; i < 256; i++) - trans_table[i] = Py_CHARMASK(table[i]); + trans_table[i] = Py_CHARMASK(table_chars[i]); } + PyBuffer_Release(&table_view); for (i = 0; i < dellen; i++) - trans_table[(int) Py_CHARMASK(del_table[i])] = -1; + trans_table[(int) Py_CHARMASK(del_table_chars[i])] = -1; + PyBuffer_Release(&del_table_view); for (i = inlen; --i >= 0; ) { c = Py_CHARMASK(*input++); @@ -1575,10 +2469,69 @@ bytes_translate(PyBytesObject *self, PyObject *args) } +/*[clinic input] + +@staticmethod +bytes.maketrans + + frm: Py_buffer + to: Py_buffer + / + +Return a translation table useable for the bytes or bytearray translate method. + +The returned table will be one where each byte in frm is mapped to the byte at +the same position in to. + +The bytes objects frm and to must be of the same length. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytes_maketrans__doc__, +"maketrans(frm, to, /)\n" +"--\n" +"\n" +"Return a translation table useable for the bytes or bytearray translate method.\n" +"\n" +"The returned table will be one where each byte in frm is mapped to the byte at\n" +"the same position in to.\n" +"\n" +"The bytes objects frm and to must be of the same length."); + +#define BYTES_MAKETRANS_METHODDEF \ + {"maketrans", (PyCFunction)bytes_maketrans, METH_VARARGS|METH_STATIC, bytes_maketrans__doc__}, + +static PyObject * +bytes_maketrans_impl(Py_buffer *frm, Py_buffer *to); + static PyObject * -bytes_maketrans(PyObject *null, PyObject *args) +bytes_maketrans(void *null, PyObject *args) { - return _Py_bytes_maketrans(args); + PyObject *return_value = NULL; + Py_buffer frm = {NULL, NULL}; + Py_buffer to = {NULL, NULL}; + + if (!PyArg_ParseTuple(args, + "y*y*:maketrans", + &frm, &to)) + goto exit; + return_value = bytes_maketrans_impl(&frm, &to); + +exit: + /* Cleanup for frm */ + if (frm.obj) + PyBuffer_Release(&frm); + /* Cleanup for to */ + if (to.obj) + PyBuffer_Release(&to); + + return return_value; +} + +static PyObject * +bytes_maketrans_impl(Py_buffer *frm, Py_buffer *to) +/*[clinic end generated code: output=7df47390c476ac60 input=de7a8fc5632bb8f1]*/ +{ + return _Py_bytes_maketrans(frm, to); } /* find and count characters and substrings */ @@ -2073,41 +3026,74 @@ replace(PyBytesObject *self, } } -PyDoc_STRVAR(replace__doc__, -"B.replace(old, new[, count]) -> bytes\n\ -\n\ -Return a copy of B with all occurrences of subsection\n\ -old replaced by new. If the optional argument count is\n\ -given, only first count occurances are replaced."); + +/*[clinic input] +bytes.replace + + old: Py_buffer + new: Py_buffer + count: Py_ssize_t = -1 + Maximum number of occurrences to replace. + -1 (the default value) means replace all occurrences. + / + +Return a copy with all occurrences of substring old replaced by new. + +If the optional argument count is given, only the first count occurrences are +replaced. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytes_replace__doc__, +"replace($self, old, new, count=-1, /)\n" +"--\n" +"\n" +"Return a copy with all occurrences of substring old replaced by new.\n" +"\n" +" count\n" +" Maximum number of occurrences to replace.\n" +" -1 (the default value) means replace all occurrences.\n" +"\n" +"If the optional argument count is given, only the first count occurrences are\n" +"replaced."); + +#define BYTES_REPLACE_METHODDEF \ + {"replace", (PyCFunction)bytes_replace, METH_VARARGS, bytes_replace__doc__}, static PyObject * -bytes_replace(PyBytesObject *self, PyObject *args) +bytes_replace_impl(PyBytesObject*self, Py_buffer *old, Py_buffer *new, Py_ssize_t count); + +static PyObject * +bytes_replace(PyBytesObject*self, PyObject *args) { + PyObject *return_value = NULL; + Py_buffer old = {NULL, NULL}; + Py_buffer new = {NULL, NULL}; Py_ssize_t count = -1; - PyObject *from, *to; - const char *from_s, *to_s; - Py_ssize_t from_len, to_len; - - if (!PyArg_ParseTuple(args, "OO|n:replace", &from, &to, &count)) - return NULL; - if (PyBytes_Check(from)) { - from_s = PyBytes_AS_STRING(from); - from_len = PyBytes_GET_SIZE(from); - } - else if (PyObject_AsCharBuffer(from, &from_s, &from_len)) - return NULL; - - if (PyBytes_Check(to)) { - to_s = PyBytes_AS_STRING(to); - to_len = PyBytes_GET_SIZE(to); - } - else if (PyObject_AsCharBuffer(to, &to_s, &to_len)) - return NULL; + if (!PyArg_ParseTuple(args, + "y*y*|n:replace", + &old, &new, &count)) + goto exit; + return_value = bytes_replace_impl(self, &old, &new, count); + +exit: + /* Cleanup for old */ + if (old.obj) + PyBuffer_Release(&old); + /* Cleanup for new */ + if (new.obj) + PyBuffer_Release(&new); + + return return_value; +} +static PyObject * +bytes_replace_impl(PyBytesObject*self, Py_buffer *old, Py_buffer *new, Py_ssize_t count) +/*[clinic end generated code: output=f07bd9ecf29ee8d8 input=b2fbbf0bf04de8e5]*/ +{ return (PyObject *)replace((PyBytesObject *) self, - from_s, from_len, - to_s, to_len, count); + (const char *)old->buf, old->len, + (const char *)new->buf, new->len, count); } /** End DALKE **/ @@ -2122,6 +3108,7 @@ _bytes_tailmatch(PyBytesObject *self, PyObject *substr, Py_ssize_t start, { Py_ssize_t len = PyBytes_GET_SIZE(self); Py_ssize_t slen; + Py_buffer sub_view = {NULL, NULL}; const char* sub; const char* str; @@ -2129,8 +3116,12 @@ _bytes_tailmatch(PyBytesObject *self, PyObject *substr, Py_ssize_t start, sub = PyBytes_AS_STRING(substr); slen = PyBytes_GET_SIZE(substr); } - else if (PyObject_AsCharBuffer(substr, &sub, &slen)) - return -1; + else { + if (PyObject_GetBuffer(substr, &sub_view, PyBUF_SIMPLE) != 0) + return -1; + sub = sub_view.buf; + slen = sub_view.len; + } str = PyBytes_AS_STRING(self); ADJUST_INDICES(start, end, len); @@ -2138,17 +3129,25 @@ _bytes_tailmatch(PyBytesObject *self, PyObject *substr, Py_ssize_t start, if (direction < 0) { /* startswith */ if (start+slen > len) - return 0; + goto notfound; } else { /* endswith */ if (end-start < slen || start > len) - return 0; + goto notfound; if (end-slen > start) start = end - slen; } - if (end-start >= slen) - return ! memcmp(str+start, sub, slen); + if (end-start < slen) + goto notfound; + if (memcmp(str+start, sub, slen) != 0) + goto notfound; + + PyBuffer_Release(&sub_view); + return 1; + +notfound: + PyBuffer_Release(&sub_view); return 0; } @@ -2241,60 +3240,121 @@ bytes_endswith(PyBytesObject *self, PyObject *args) } -PyDoc_STRVAR(decode__doc__, -"B.decode(encoding='utf-8', errors='strict') -> str\n\ -\n\ -Decode B using the codec registered for encoding. Default encoding\n\ -is 'utf-8'. errors may be given to set a different error\n\ -handling scheme. Default is 'strict' meaning that encoding errors raise\n\ -a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'\n\ -as well as any other name registerd with codecs.register_error that is\n\ -able to handle UnicodeDecodeErrors."); +/*[clinic input] +bytes.decode + + encoding: str(c_default="NULL") = 'utf-8' + The encoding with which to decode the bytes. + errors: str(c_default="NULL") = 'strict' + The error handling scheme to use for the handling of decoding errors. + The default is 'strict' meaning that decoding errors raise a + UnicodeDecodeError. Other possible values are 'ignore' and 'replace' + as well as any other name registered with codecs.register_error that + can handle UnicodeDecodeErrors. + +Decode the bytes using the codec registered for encoding. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytes_decode__doc__, +"decode($self, /, encoding=\'utf-8\', errors=\'strict\')\n" +"--\n" +"\n" +"Decode the bytes using the codec registered for encoding.\n" +"\n" +" encoding\n" +" The encoding with which to decode the bytes.\n" +" errors\n" +" The error handling scheme to use for the handling of decoding errors.\n" +" The default is \'strict\' meaning that decoding errors raise a\n" +" UnicodeDecodeError. Other possible values are \'ignore\' and \'replace\'\n" +" as well as any other name registered with codecs.register_error that\n" +" can handle UnicodeDecodeErrors."); + +#define BYTES_DECODE_METHODDEF \ + {"decode", (PyCFunction)bytes_decode, METH_VARARGS|METH_KEYWORDS, bytes_decode__doc__}, static PyObject * -bytes_decode(PyObject *self, PyObject *args, PyObject *kwargs) +bytes_decode_impl(PyBytesObject*self, const char *encoding, const char *errors); + +static PyObject * +bytes_decode(PyBytesObject*self, PyObject *args, PyObject *kwargs) { + PyObject *return_value = NULL; + static char *_keywords[] = {"encoding", "errors", NULL}; const char *encoding = NULL; const char *errors = NULL; - static char *kwlist[] = {"encoding", "errors", 0}; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode", kwlist, &encoding, &errors)) - return NULL; - return PyUnicode_FromEncodedObject(self, encoding, errors); + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "|ss:decode", _keywords, + &encoding, &errors)) + goto exit; + return_value = bytes_decode_impl(self, encoding, errors); + +exit: + return return_value; } +static PyObject * +bytes_decode_impl(PyBytesObject*self, const char *encoding, const char *errors) +/*[clinic end generated code: output=61a80290bbfce696 input=958174769d2a40ca]*/ +{ + return PyUnicode_FromEncodedObject((PyObject*)self, encoding, errors); +} -PyDoc_STRVAR(splitlines__doc__, -"B.splitlines([keepends]) -> list of lines\n\ -\n\ -Return a list of the lines in B, breaking at line boundaries.\n\ -Line breaks are not included in the resulting list unless keepends\n\ -is given and true."); -static PyObject* -bytes_splitlines(PyObject *self, PyObject *args, PyObject *kwds) +/*[clinic input] +bytes.splitlines + + keepends: int(py_default="False") = 0 + +Return a list of the lines in the bytes, breaking at line boundaries. + +Line breaks are not included in the resulting list unless keepends is given and +true. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytes_splitlines__doc__, +"splitlines($self, /, keepends=False)\n" +"--\n" +"\n" +"Return a list of the lines in the bytes, breaking at line boundaries.\n" +"\n" +"Line breaks are not included in the resulting list unless keepends is given and\n" +"true."); + +#define BYTES_SPLITLINES_METHODDEF \ + {"splitlines", (PyCFunction)bytes_splitlines, METH_VARARGS|METH_KEYWORDS, bytes_splitlines__doc__}, + +static PyObject * +bytes_splitlines_impl(PyBytesObject*self, int keepends); + +static PyObject * +bytes_splitlines(PyBytesObject*self, PyObject *args, PyObject *kwargs) { - static char *kwlist[] = {"keepends", 0}; + PyObject *return_value = NULL; + static char *_keywords[] = {"keepends", NULL}; int keepends = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:splitlines", - kwlist, &keepends)) - return NULL; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "|i:splitlines", _keywords, + &keepends)) + goto exit; + return_value = bytes_splitlines_impl(self, keepends); +exit: + return return_value; +} + +static PyObject * +bytes_splitlines_impl(PyBytesObject*self, int keepends) +/*[clinic end generated code: output=79da057d05d126de input=ddb93e3351080c8c]*/ +{ return stringlib_splitlines( (PyObject*) self, PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), keepends ); } - -PyDoc_STRVAR(fromhex_doc, -"bytes.fromhex(string) -> bytes\n\ -\n\ -Create a bytes object from a string of hexadecimal numbers.\n\ -Spaces between two numbers are accepted.\n\ -Example: bytes.fromhex('B9 01EF') -> b'\\xb9\\x01\\xef'."); - static int hex_digit_to_int(Py_UCS4 c) { @@ -2311,24 +3371,67 @@ hex_digit_to_int(Py_UCS4 c) return -1; } +/*[clinic input] +@classmethod +bytes.fromhex + + string: unicode + / + +Create a bytes object from a string of hexadecimal numbers. + +Spaces between two numbers are accepted. +Example: bytes.fromhex('B9 01EF') -> b'\\xb9\\x01\\xef'. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytes_fromhex__doc__, +"fromhex($type, string, /)\n" +"--\n" +"\n" +"Create a bytes object from a string of hexadecimal numbers.\n" +"\n" +"Spaces between two numbers are accepted.\n" +"Example: bytes.fromhex(\'B9 01EF\') -> b\'\\\\xb9\\\\x01\\\\xef\'."); + +#define BYTES_FROMHEX_METHODDEF \ + {"fromhex", (PyCFunction)bytes_fromhex, METH_VARARGS|METH_CLASS, bytes_fromhex__doc__}, + +static PyObject * +bytes_fromhex_impl(PyTypeObject *type, PyObject *string); + +static PyObject * +bytes_fromhex(PyTypeObject *type, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *string; + + if (!PyArg_ParseTuple(args, + "U:fromhex", + &string)) + goto exit; + return_value = bytes_fromhex_impl(type, string); + +exit: + return return_value; +} + static PyObject * -bytes_fromhex(PyObject *cls, PyObject *args) +bytes_fromhex_impl(PyTypeObject *type, PyObject *string) +/*[clinic end generated code: output=09e6cbef56cbbb65 input=bf4d1c361670acd3]*/ { - PyObject *newstring, *hexobj; + PyObject *newstring; char *buf; Py_ssize_t hexlen, byteslen, i, j; int top, bot; void *data; unsigned int kind; - if (!PyArg_ParseTuple(args, "U:fromhex", &hexobj)) + assert(PyUnicode_Check(string)); + if (PyUnicode_READY(string)) return NULL; - assert(PyUnicode_Check(hexobj)); - if (PyUnicode_READY(hexobj)) - return NULL; - kind = PyUnicode_KIND(hexobj); - data = PyUnicode_DATA(hexobj); - hexlen = PyUnicode_GET_LENGTH(hexobj); + kind = PyUnicode_KIND(string); + data = PyUnicode_DATA(string); + hexlen = PyUnicode_GET_LENGTH(string); byteslen = hexlen/2; /* This overestimates if there are spaces */ newstring = PyBytes_FromStringAndSize(NULL, byteslen); @@ -2360,14 +3463,38 @@ bytes_fromhex(PyObject *cls, PyObject *args) return NULL; } -PyDoc_STRVAR(sizeof__doc__, -"B.__sizeof__() -> size of B in memory, in bytes"); +/*[clinic input] +bytes.__sizeof__ as bytes_sizeof + + self: self(type="PyBytesObject *") + +Returns the size of the bytes object in memory, in bytes. +[clinic start generated code]*/ + +PyDoc_STRVAR(bytes_sizeof__doc__, +"__sizeof__($self, /)\n" +"--\n" +"\n" +"Returns the size of the bytes object in memory, in bytes."); + +#define BYTES_SIZEOF_METHODDEF \ + {"__sizeof__", (PyCFunction)bytes_sizeof, METH_NOARGS, bytes_sizeof__doc__}, static PyObject * -bytes_sizeof(PyBytesObject *v) +bytes_sizeof_impl(PyBytesObject *self); + +static PyObject * +bytes_sizeof(PyBytesObject *self, PyObject *Py_UNUSED(ignored)) +{ + return bytes_sizeof_impl(self); +} + +static PyObject * +bytes_sizeof_impl(PyBytesObject *self) +/*[clinic end generated code: output=44933279343f24ae input=bee4c64bb42078ed]*/ { Py_ssize_t res; - res = PyBytesObject_SIZE + Py_SIZE(v) * Py_TYPE(v)->tp_itemsize; + res = PyBytesObject_SIZE + Py_SIZE(self) * Py_TYPE(self)->tp_itemsize; return PyLong_FromSsize_t(res); } @@ -2386,14 +3513,13 @@ bytes_methods[] = { _Py_capitalize__doc__}, {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__}, {"count", (PyCFunction)bytes_count, METH_VARARGS, count__doc__}, - {"decode", (PyCFunction)bytes_decode, METH_VARARGS | METH_KEYWORDS, decode__doc__}, + BYTES_DECODE_METHODDEF {"endswith", (PyCFunction)bytes_endswith, METH_VARARGS, endswith__doc__}, {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS | METH_KEYWORDS, expandtabs__doc__}, {"find", (PyCFunction)bytes_find, METH_VARARGS, find__doc__}, - {"fromhex", (PyCFunction)bytes_fromhex, METH_VARARGS|METH_CLASS, - fromhex_doc}, + BYTES_FROMHEX_METHODDEF {"index", (PyCFunction)bytes_index, METH_VARARGS, index__doc__}, {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS, _Py_isalnum__doc__}, @@ -2409,39 +3535,49 @@ bytes_methods[] = { _Py_istitle__doc__}, {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS, _Py_isupper__doc__}, - {"join", (PyCFunction)bytes_join, METH_O, join__doc__}, + BYTES_JOIN_METHODDEF {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__}, {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__}, - {"lstrip", (PyCFunction)bytes_lstrip, METH_VARARGS, lstrip__doc__}, - {"maketrans", (PyCFunction)bytes_maketrans, METH_VARARGS|METH_STATIC, - _Py_maketrans__doc__}, - {"partition", (PyCFunction)bytes_partition, METH_O, partition__doc__}, - {"replace", (PyCFunction)bytes_replace, METH_VARARGS, replace__doc__}, + BYTES_LSTRIP_METHODDEF + BYTES_MAKETRANS_METHODDEF + BYTES_PARTITION_METHODDEF + BYTES_REPLACE_METHODDEF {"rfind", (PyCFunction)bytes_rfind, METH_VARARGS, rfind__doc__}, {"rindex", (PyCFunction)bytes_rindex, METH_VARARGS, rindex__doc__}, {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__}, - {"rpartition", (PyCFunction)bytes_rpartition, METH_O, - rpartition__doc__}, - {"rsplit", (PyCFunction)bytes_rsplit, METH_VARARGS | METH_KEYWORDS, rsplit__doc__}, - {"rstrip", (PyCFunction)bytes_rstrip, METH_VARARGS, rstrip__doc__}, - {"split", (PyCFunction)bytes_split, METH_VARARGS | METH_KEYWORDS, split__doc__}, - {"splitlines", (PyCFunction)bytes_splitlines, METH_VARARGS | METH_KEYWORDS, - splitlines__doc__}, + BYTES_RPARTITION_METHODDEF + BYTES_RSPLIT_METHODDEF + BYTES_RSTRIP_METHODDEF + BYTES_SPLIT_METHODDEF + BYTES_SPLITLINES_METHODDEF {"startswith", (PyCFunction)bytes_startswith, METH_VARARGS, startswith__doc__}, - {"strip", (PyCFunction)bytes_strip, METH_VARARGS, strip__doc__}, + BYTES_STRIP_METHODDEF {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS, _Py_swapcase__doc__}, {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__}, - {"translate", (PyCFunction)bytes_translate, METH_VARARGS, - translate__doc__}, + BYTES_TRANSLATE_METHODDEF {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__}, {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__}, - {"__sizeof__", (PyCFunction)bytes_sizeof, METH_NOARGS, - sizeof__doc__}, + BYTES_SIZEOF_METHODDEF {NULL, NULL} /* sentinel */ }; +static PyObject * +bytes_mod(PyObject *v, PyObject *w) +{ + if (!PyBytes_Check(v)) + Py_RETURN_NOTIMPLEMENTED; + return _PyBytes_Format(v, w); +} + +static PyNumberMethods bytes_as_number = { + 0, /*nb_add*/ + 0, /*nb_subtract*/ + 0, /*nb_multiply*/ + bytes_mod, /*nb_remainder*/ +}; + static PyObject * str_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds); @@ -2469,7 +3605,7 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds) "argument"); return NULL; } - return PyBytes_FromString(""); + return PyBytes_FromStringAndSize(NULL, 0); } if (PyUnicode_Check(x)) { @@ -2486,6 +3622,13 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return new; } + /* If it's not unicode, there can't be encoding or errors */ + if (encoding != NULL || errors != NULL) { + PyErr_SetString(PyExc_TypeError, + "encoding or errors without a string argument"); + return NULL; + } + /* We'd like to call PyObject_Bytes here, but we need to check for an integer argument before deferring to PyBytes_FromObject, something PyObject_Bytes doesn't do. */ @@ -2519,21 +3662,12 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return NULL; } else { - new = PyBytes_FromStringAndSize(NULL, size); + new = _PyBytes_FromSize(size, 1); if (new == NULL) return NULL; - if (size > 0) - memset(((PyBytesObject*)new)->ob_sval, 0, size); return new; } - /* If it's not unicode, there can't be encoding or errors */ - if (encoding != NULL || errors != NULL) { - PyErr_SetString(PyExc_TypeError, - "encoding or errors without a string argument"); - return NULL; - } - return PyBytes_FromObject(x); } @@ -2628,10 +3762,12 @@ PyBytes_FromObject(PyObject *x) returning a shared empty bytes string. This required because we want to call _PyBytes_Resize() the returned object, which we can only do on bytes objects with refcount == 1. */ - size += 1; + if (size == 0) + size = 1; new = PyBytes_FromStringAndSize(NULL, size); if (new == NULL) return NULL; + assert(Py_REFCNT(new) == 1); /* Get the iterator */ it = PyObject_GetIter(x); @@ -2733,7 +3869,7 @@ PyTypeObject PyBytes_Type = { 0, /* tp_setattr */ 0, /* tp_reserved */ (reprfunc)bytes_repr, /* tp_repr */ - 0, /* tp_as_number */ + &bytes_as_number, /* tp_as_number */ &bytes_as_sequence, /* tp_as_sequence */ &bytes_as_mapping, /* tp_as_mapping */ (hashfunc)bytes_hash, /* tp_hash */ @@ -2768,7 +3904,6 @@ PyTypeObject PyBytes_Type = { void PyBytes_Concat(PyObject **pv, PyObject *w) { - PyObject *v; assert(pv != NULL); if (*pv == NULL) return; @@ -2776,9 +3911,45 @@ PyBytes_Concat(PyObject **pv, PyObject *w) Py_CLEAR(*pv); return; } - v = bytes_concat(*pv, w); - Py_DECREF(*pv); - *pv = v; + + if (Py_REFCNT(*pv) == 1 && PyBytes_CheckExact(*pv)) { + /* Only one reference, so we can resize in place */ + Py_ssize_t oldsize; + Py_buffer wb; + + wb.len = -1; + if (PyObject_GetBuffer(w, &wb, PyBUF_SIMPLE) != 0) { + PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s", + Py_TYPE(w)->tp_name, Py_TYPE(*pv)->tp_name); + Py_CLEAR(*pv); + return; + } + + oldsize = PyBytes_GET_SIZE(*pv); + if (oldsize > PY_SSIZE_T_MAX - wb.len) { + PyErr_NoMemory(); + goto error; + } + if (_PyBytes_Resize(pv, oldsize + wb.len) < 0) + goto error; + + memcpy(PyBytes_AS_STRING(*pv) + oldsize, wb.buf, wb.len); + PyBuffer_Release(&wb); + return; + + error: + PyBuffer_Release(&wb); + Py_CLEAR(*pv); + return; + } + + else { + /* Multiple references, need to create new object */ + PyObject *v; + v = bytes_concat(*pv, w); + Py_DECREF(*pv); + *pv = v; + } } void @@ -2789,14 +3960,14 @@ PyBytes_ConcatAndDel(PyObject **pv, PyObject *w) } -/* The following function breaks the notion that strings are immutable: - it changes the size of a string. We get away with this only if there +/* The following function breaks the notion that bytes are immutable: + it changes the size of a bytes object. We get away with this only if there is only one module referencing the object. You can also think of it - as creating a new string object and destroying the old one, only - more efficiently. In any case, don't use this if the string may + as creating a new bytes object and destroying the old one, only + more efficiently. In any case, don't use this if the bytes object may already be known to some other part of the code... - Note that if there's not enough memory to resize the string, the original - string object at *pv is deallocated, *pv is set to NULL, an "out of + Note that if there's not enough memory to resize the bytes object, the + original bytes object at *pv is deallocated, *pv is set to NULL, an "out of memory" exception is set, and -1 is returned. Else (on success) 0 is returned, and the value in *pv may or may not be the same as on input. As always, an extra byte is allocated for a trailing \0 byte (newsize @@ -2819,7 +3990,7 @@ _PyBytes_Resize(PyObject **pv, Py_ssize_t newsize) _Py_DEC_REFTOTAL; _Py_ForgetReference(v); *pv = (PyObject *) - PyObject_REALLOC((char *)v, PyBytesObject_SIZE + newsize); + PyObject_REALLOC(v, PyBytesObject_SIZE + newsize); if (*pv == NULL) { PyObject_Del(v); PyErr_NoMemory(); @@ -2924,9 +4095,13 @@ striter_setstate(striterobject *it, PyObject *state) Py_ssize_t index = PyLong_AsSsize_t(state); if (index == -1 && PyErr_Occurred()) return NULL; - if (index < 0) - index = 0; - it->it_index = index; + if (it->it_seq != NULL) { + if (index < 0) + index = 0; + else if (index > PyBytes_GET_SIZE(it->it_seq)) + index = PyBytes_GET_SIZE(it->it_seq); /* iterator exhausted */ + it->it_index = index; + } Py_RETURN_NONE; } diff --git a/Objects/classobject.c b/Objects/classobject.c index 272f575dbac8..07cb6395b414 100644 --- a/Objects/classobject.c +++ b/Objects/classobject.c @@ -15,6 +15,7 @@ static int numfree = 0; #endif _Py_IDENTIFIER(__name__); +_Py_IDENTIFIER(__qualname__); PyObject * PyMethod_Function(PyObject *im) @@ -52,7 +53,7 @@ PyMethod_New(PyObject *func, PyObject *self) im = free_list; if (im != NULL) { free_list = (PyMethodObject *)(im->im_self); - PyObject_INIT(im, &PyMethod_Type); + (void)PyObject_INIT(im, &PyMethod_Type); numfree--; } else { @@ -243,51 +244,33 @@ method_repr(PyMethodObject *a) { PyObject *self = a->im_self; PyObject *func = a->im_func; - PyObject *klass; - PyObject *funcname = NULL ,*klassname = NULL, *result = NULL; - char *defname = "?"; + PyObject *funcname = NULL, *result = NULL; + const char *defname = "?"; - if (self == NULL) { - PyErr_BadInternalCall(); - return NULL; - } - klass = (PyObject*)Py_TYPE(self); - - funcname = _PyObject_GetAttrId(func, &PyId___name__); + funcname = _PyObject_GetAttrId(func, &PyId___qualname__); if (funcname == NULL) { if (!PyErr_ExceptionMatches(PyExc_AttributeError)) return NULL; PyErr_Clear(); - } - else if (!PyUnicode_Check(funcname)) { - Py_DECREF(funcname); - funcname = NULL; - } - if (klass == NULL) - klassname = NULL; - else { - klassname = _PyObject_GetAttrId(klass, &PyId___name__); - if (klassname == NULL) { - if (!PyErr_ExceptionMatches(PyExc_AttributeError)) { - Py_XDECREF(funcname); + funcname = _PyObject_GetAttrId(func, &PyId___name__); + if (funcname == NULL) { + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) return NULL; - } PyErr_Clear(); } - else if (!PyUnicode_Check(klassname)) { - Py_DECREF(klassname); - klassname = NULL; - } + } + + if (funcname != NULL && !PyUnicode_Check(funcname)) { + Py_DECREF(funcname); + funcname = NULL; } /* XXX Shouldn't use repr()/%R here! */ - result = PyUnicode_FromFormat("", - klassname, defname, + result = PyUnicode_FromFormat("", funcname, defname, self); Py_XDECREF(funcname); - Py_XDECREF(klassname); return result; } diff --git a/Objects/complexobject.c b/Objects/complexobject.c index 60a388fa2415..dc1212e4b798 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -13,7 +13,7 @@ static Py_complex c_1 = {1., 0.}; Py_complex -c_sum(Py_complex a, Py_complex b) +_Py_c_sum(Py_complex a, Py_complex b) { Py_complex r; r.real = a.real + b.real; @@ -22,7 +22,7 @@ c_sum(Py_complex a, Py_complex b) } Py_complex -c_diff(Py_complex a, Py_complex b) +_Py_c_diff(Py_complex a, Py_complex b) { Py_complex r; r.real = a.real - b.real; @@ -31,7 +31,7 @@ c_diff(Py_complex a, Py_complex b) } Py_complex -c_neg(Py_complex a) +_Py_c_neg(Py_complex a) { Py_complex r; r.real = -a.real; @@ -40,7 +40,7 @@ c_neg(Py_complex a) } Py_complex -c_prod(Py_complex a, Py_complex b) +_Py_c_prod(Py_complex a, Py_complex b) { Py_complex r; r.real = a.real*b.real - a.imag*b.imag; @@ -49,7 +49,7 @@ c_prod(Py_complex a, Py_complex b) } Py_complex -c_quot(Py_complex a, Py_complex b) +_Py_c_quot(Py_complex a, Py_complex b) { /****************************************************************** This was the original algorithm. It's grossly prone to spurious @@ -78,7 +78,7 @@ c_quot(Py_complex a, Py_complex b) const double abs_breal = b.real < 0 ? -b.real : b.real; const double abs_bimag = b.imag < 0 ? -b.imag : b.imag; - if (abs_breal >= abs_bimag) { + if (abs_breal >= abs_bimag) { /* divide tops and bottom by b.real */ if (abs_breal == 0.0) { errno = EDOM; @@ -91,7 +91,7 @@ c_quot(Py_complex a, Py_complex b) r.imag = (a.imag - a.real * ratio) / denom; } } - else { + else if (abs_bimag >= abs_breal) { /* divide tops and bottom by b.imag */ const double ratio = b.real / b.imag; const double denom = b.real * ratio + b.imag; @@ -99,11 +99,15 @@ c_quot(Py_complex a, Py_complex b) r.real = (a.real * ratio + a.imag) / denom; r.imag = (a.imag * ratio - a.real) / denom; } + else { + /* At least one of b.real or b.imag is a NaN */ + r.real = r.imag = Py_NAN; + } return r; } Py_complex -c_pow(Py_complex a, Py_complex b) +_Py_c_pow(Py_complex a, Py_complex b) { Py_complex r; double vabs,len,at,phase; @@ -141,9 +145,9 @@ c_powu(Py_complex x, long n) p = x; while (mask > 0 && n >= mask) { if (n & mask) - r = c_prod(r,p); + r = _Py_c_prod(r,p); mask <<= 1; - p = c_prod(p,p); + p = _Py_c_prod(p,p); } return r; } @@ -156,17 +160,17 @@ c_powi(Py_complex x, long n) if (n > 100 || n < -100) { cn.real = (double) n; cn.imag = 0.; - return c_pow(x,cn); + return _Py_c_pow(x,cn); } else if (n > 0) return c_powu(x,n); else - return c_quot(c_1,c_powu(x,-n)); + return _Py_c_quot(c_1, c_powu(x,-n)); } double -c_abs(Py_complex z) +_Py_c_abs(Py_complex z) { /* sets errno = ERANGE on overflow; otherwise errno = 0 */ double result; @@ -217,7 +221,7 @@ PyComplex_FromCComplex(Py_complex cval) op = (PyComplexObject *) PyObject_MALLOC(sizeof(PyComplexObject)); if (op == NULL) return PyErr_NoMemory(); - PyObject_INIT(op, &PyComplex_Type); + (void)PyObject_INIT(op, &PyComplex_Type); op->cval = cval; return (PyObject *) op; } @@ -441,7 +445,7 @@ complex_add(PyObject *v, PyObject *w) TO_COMPLEX(v, a); TO_COMPLEX(w, b); PyFPE_START_PROTECT("complex_add", return 0) - result = c_sum(a, b); + result = _Py_c_sum(a, b); PyFPE_END_PROTECT(result) return PyComplex_FromCComplex(result); } @@ -454,7 +458,7 @@ complex_sub(PyObject *v, PyObject *w) TO_COMPLEX(v, a); TO_COMPLEX(w, b); PyFPE_START_PROTECT("complex_sub", return 0) - result = c_diff(a, b); + result = _Py_c_diff(a, b); PyFPE_END_PROTECT(result) return PyComplex_FromCComplex(result); } @@ -467,7 +471,7 @@ complex_mul(PyObject *v, PyObject *w) TO_COMPLEX(v, a); TO_COMPLEX(w, b); PyFPE_START_PROTECT("complex_mul", return 0) - result = c_prod(a, b); + result = _Py_c_prod(a, b); PyFPE_END_PROTECT(result) return PyComplex_FromCComplex(result); } @@ -481,7 +485,7 @@ complex_div(PyObject *v, PyObject *w) TO_COMPLEX(w, b); PyFPE_START_PROTECT("complex_div", return 0) errno = 0; - quot = c_quot(a, b); + quot = _Py_c_quot(a, b); PyFPE_END_PROTECT(quot) if (errno == EDOM) { PyErr_SetString(PyExc_ZeroDivisionError, "complex division by zero"); @@ -528,7 +532,7 @@ complex_pow(PyObject *v, PyObject *w, PyObject *z) if (exponent.imag == 0. && exponent.real == int_exponent) p = c_powi(a, int_exponent); else - p = c_pow(a, exponent); + p = _Py_c_pow(a, exponent); PyFPE_END_PROTECT(p) Py_ADJUST_ERANGE2(p.real, p.imag); @@ -579,7 +583,7 @@ complex_abs(PyComplexObject *v) double result; PyFPE_START_PROTECT("complex_abs", return 0) - result = c_abs(v->cval); + result = _Py_c_abs(v->cval); PyFPE_END_PROTECT(result) if (errno == ERANGE) { @@ -763,6 +767,7 @@ complex_subtype_from_string(PyTypeObject *type, PyObject *v) int got_bracket=0; PyObject *s_buffer = NULL; Py_ssize_t len; + Py_buffer view = {NULL, NULL}; if (PyUnicode_Check(v)) { s_buffer = _PyUnicode_TransformDecimalAndSpaceToASCII(v); @@ -772,7 +777,11 @@ complex_subtype_from_string(PyTypeObject *type, PyObject *v) if (s == NULL) goto error; } - else if (PyObject_AsCharBuffer(v, &s, &len)) { + else if (PyObject_GetBuffer(v, &view, PyBUF_SIMPLE) == 0) { + s = (const char *)view.buf; + len = view.len; + } + else { PyErr_Format(PyExc_TypeError, "complex() argument must be a string or a number, not '%.200s'", Py_TYPE(v)->tp_name); @@ -886,6 +895,7 @@ complex_subtype_from_string(PyTypeObject *type, PyObject *v) if (s-start != len) goto parse_error; + PyBuffer_Release(&view); Py_XDECREF(s_buffer); return complex_subtype_from_doubles(type, x, y); @@ -893,6 +903,7 @@ complex_subtype_from_string(PyTypeObject *type, PyObject *v) PyErr_SetString(PyExc_ValueError, "complex() arg is a malformed string"); error: + PyBuffer_Release(&view); Py_XDECREF(s_buffer); return NULL; } diff --git a/Objects/descrobject.c b/Objects/descrobject.c index 312fc402d320..2df5ac5f731b 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -353,11 +353,13 @@ wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds) static PyObject * method_get_doc(PyMethodDescrObject *descr, void *closure) { - if (descr->d_method->ml_doc == NULL) { - Py_INCREF(Py_None); - return Py_None; - } - return PyUnicode_FromString(descr->d_method->ml_doc); + return _PyType_GetDocFromInternalDoc(descr->d_method->ml_name, descr->d_method->ml_doc); +} + +static PyObject * +method_get_text_signature(PyMethodDescrObject *descr, void *closure) +{ + return _PyType_GetTextSignatureFromInternalDoc(descr->d_method->ml_name, descr->d_method->ml_doc); } static PyObject * @@ -425,6 +427,7 @@ static PyMemberDef descr_members[] = { static PyGetSetDef method_getset[] = { {"__doc__", (getter)method_get_doc}, {"__qualname__", (getter)descr_get_qualname}, + {"__text_signature__", (getter)method_get_text_signature}, {0} }; @@ -463,16 +466,19 @@ static PyGetSetDef getset_getset[] = { static PyObject * wrapperdescr_get_doc(PyWrapperDescrObject *descr, void *closure) { - if (descr->d_base->doc == NULL) { - Py_INCREF(Py_None); - return Py_None; - } - return PyUnicode_FromString(descr->d_base->doc); + return _PyType_GetDocFromInternalDoc(descr->d_base->name, descr->d_base->doc); +} + +static PyObject * +wrapperdescr_get_text_signature(PyWrapperDescrObject *descr, void *closure) +{ + return _PyType_GetTextSignatureFromInternalDoc(descr->d_base->name, descr->d_base->doc); } static PyGetSetDef wrapperdescr_getset[] = { {"__doc__", (getter)wrapperdescr_get_doc}, {"__qualname__", (getter)descr_get_qualname}, + {"__text_signature__", (getter)wrapperdescr_get_text_signature}, {0} }; @@ -1143,17 +1149,15 @@ wrapper_name(wrapperobject *wp) } static PyObject * -wrapper_doc(wrapperobject *wp) +wrapper_doc(wrapperobject *wp, void *closure) { - const char *s = wp->descr->d_base->doc; + return _PyType_GetDocFromInternalDoc(wp->descr->d_base->name, wp->descr->d_base->doc); +} - if (s == NULL) { - Py_INCREF(Py_None); - return Py_None; - } - else { - return PyUnicode_FromString(s); - } +static PyObject * +wrapper_text_signature(wrapperobject *wp, void *closure) +{ + return _PyType_GetTextSignatureFromInternalDoc(wp->descr->d_base->name, wp->descr->d_base->doc); } static PyObject * @@ -1167,6 +1171,7 @@ static PyGetSetDef wrapper_getsets[] = { {"__name__", (getter)wrapper_name}, {"__qualname__", (getter)wrapper_qualname}, {"__doc__", (getter)wrapper_doc}, + {"__text_signature__", (getter)wrapper_text_signature}, {0} }; diff --git a/Objects/dictobject.c b/Objects/dictobject.c index bfc730ba705d..a3219f712fff 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -69,10 +69,10 @@ to the combined-table form. #include "Python.h" #include "stringlib/eq.h" -/*[clinic] -class dict -[clinic]*/ -/*[clinic checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ +/*[clinic input] +class dict "PyDictObject *" "&PyDict_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=f157a5a0ce9589d6]*/ typedef struct { /* Cached hash code of me_key. */ @@ -814,13 +814,14 @@ insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value) if (ep == NULL) { return -1; } + assert(PyUnicode_CheckExact(key) || mp->ma_keys->dk_lookup == lookdict); Py_INCREF(value); MAINTAIN_TRACKING(mp, key, value); old_value = *value_addr; if (old_value != NULL) { assert(ep->me_key != NULL && ep->me_key != dummy); *value_addr = value; - Py_DECREF(old_value); /* which **CAN** re-enter */ + Py_DECREF(old_value); /* which **CAN** re-enter (see issue #22653) */ } else { if (ep->me_key == NULL) { @@ -851,9 +852,8 @@ insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value) } mp->ma_used++; *value_addr = value; + assert(ep->me_key != NULL && ep->me_key != dummy); } - assert(ep->me_key != NULL && ep->me_key != dummy); - assert(PyUnicode_CheckExact(key) || mp->ma_keys->dk_lookup == lookdict); return 0; } @@ -1101,6 +1101,44 @@ PyDict_GetItem(PyObject *op, PyObject *key) return *value_addr; } +PyObject * +_PyDict_GetItem_KnownHash(PyObject *op, PyObject *key, Py_hash_t hash) +{ + PyDictObject *mp = (PyDictObject *)op; + PyDictKeyEntry *ep; + PyThreadState *tstate; + PyObject **value_addr; + + if (!PyDict_Check(op)) + return NULL; + + /* We can arrive here with a NULL tstate during initialization: try + running "python -Wi" for an example related to string interning. + Let's just hope that no exception occurs then... This must be + _PyThreadState_Current and not PyThreadState_GET() because in debug + mode, the latter complains if tstate is NULL. */ + tstate = (PyThreadState*)_Py_atomic_load_relaxed( + &_PyThreadState_Current); + if (tstate != NULL && tstate->curexc_type != NULL) { + /* preserve the existing exception */ + PyObject *err_type, *err_value, *err_tb; + PyErr_Fetch(&err_type, &err_value, &err_tb); + ep = (mp->ma_keys->dk_lookup)(mp, key, hash, &value_addr); + /* ignore errors */ + PyErr_Restore(err_type, err_value, err_tb); + if (ep == NULL) + return NULL; + } + else { + ep = (mp->ma_keys->dk_lookup)(mp, key, hash, &value_addr); + if (ep == NULL) { + PyErr_Clear(); + return NULL; + } + } + return *value_addr; +} + /* Variant of PyDict_GetItem() that doesn't suppress exceptions. This returns NULL *with* an exception set if an exception occurred. It returns NULL *without* an exception set if the key wasn't present. @@ -1207,6 +1245,24 @@ PyDict_SetItem(PyObject *op, PyObject *key, PyObject *value) return insertdict(mp, key, hash, value); } +int +_PyDict_SetItem_KnownHash(PyObject *op, PyObject *key, PyObject *value, + Py_hash_t hash) +{ + PyDictObject *mp; + + if (!PyDict_Check(op)) { + PyErr_BadInternalCall(); + return -1; + } + assert(key); + assert(value); + mp = (PyDictObject *)op; + + /* insertdict() handles any resizing that might be necessary */ + return insertdict(mp, key, hash, value); +} + int PyDict_DelItem(PyObject *op, PyObject *key) { @@ -1691,37 +1747,72 @@ dict_items(PyDictObject *mp) return v; } +/*[clinic input] +@classmethod +dict.fromkeys + iterable: object + value: object=None + / + +Returns a new dict with keys from iterable and values equal to value. +[clinic start generated code]*/ + +PyDoc_STRVAR(dict_fromkeys__doc__, +"fromkeys($type, iterable, value=None, /)\n" +"--\n" +"\n" +"Returns a new dict with keys from iterable and values equal to value."); + +#define DICT_FROMKEYS_METHODDEF \ + {"fromkeys", (PyCFunction)dict_fromkeys, METH_VARARGS|METH_CLASS, dict_fromkeys__doc__}, + +static PyObject * +dict_fromkeys_impl(PyTypeObject *type, PyObject *iterable, PyObject *value); + static PyObject * -dict_fromkeys(PyObject *cls, PyObject *args) +dict_fromkeys(PyTypeObject *type, PyObject *args) { - PyObject *seq; + PyObject *return_value = NULL; + PyObject *iterable; PyObject *value = Py_None; + + if (!PyArg_UnpackTuple(args, "fromkeys", + 1, 2, + &iterable, &value)) + goto exit; + return_value = dict_fromkeys_impl(type, iterable, value); + +exit: + return return_value; +} + +static PyObject * +dict_fromkeys_impl(PyTypeObject *type, PyObject *iterable, PyObject *value) +/*[clinic end generated code: output=55f8dc0ffa87406f input=b85a667f9bf4669d]*/ +{ PyObject *it; /* iter(seq) */ PyObject *key; PyObject *d; int status; - if (!PyArg_UnpackTuple(args, "fromkeys", 1, 2, &seq, &value)) - return NULL; - - d = PyObject_CallObject(cls, NULL); + d = PyObject_CallObject((PyObject *)type, NULL); if (d == NULL) return NULL; if (PyDict_CheckExact(d) && ((PyDictObject *)d)->ma_used == 0) { - if (PyDict_CheckExact(seq)) { + if (PyDict_CheckExact(iterable)) { PyDictObject *mp = (PyDictObject *)d; PyObject *oldvalue; Py_ssize_t pos = 0; PyObject *key; Py_hash_t hash; - if (dictresize(mp, Py_SIZE(seq))) { + if (dictresize(mp, Py_SIZE(iterable))) { Py_DECREF(d); return NULL; } - while (_PyDict_Next(seq, &pos, &key, &oldvalue, &hash)) { + while (_PyDict_Next(iterable, &pos, &key, &oldvalue, &hash)) { if (insertdict(mp, key, hash, value)) { Py_DECREF(d); return NULL; @@ -1729,18 +1820,18 @@ dict_fromkeys(PyObject *cls, PyObject *args) } return d; } - if (PyAnySet_CheckExact(seq)) { + if (PyAnySet_CheckExact(iterable)) { PyDictObject *mp = (PyDictObject *)d; Py_ssize_t pos = 0; PyObject *key; Py_hash_t hash; - if (dictresize(mp, PySet_GET_SIZE(seq))) { + if (dictresize(mp, PySet_GET_SIZE(iterable))) { Py_DECREF(d); return NULL; } - while (_PySet_NextEntry(seq, &pos, &key, &hash)) { + while (_PySet_NextEntry(iterable, &pos, &key, &hash)) { if (insertdict(mp, key, hash, value)) { Py_DECREF(d); return NULL; @@ -1750,7 +1841,7 @@ dict_fromkeys(PyObject *cls, PyObject *args) } } - it = PyObject_GetIter(seq); + it = PyObject_GetIter(iterable); if (it == NULL){ Py_DECREF(d); return NULL; @@ -2164,7 +2255,7 @@ dict_richcompare(PyObject *v, PyObject *w, int op) return res; } -/*[clinic] +/*[clinic input] @coexist dict.__contains__ @@ -2172,21 +2263,23 @@ dict.__contains__ key: object / -True if D has a key k, else False" -[clinic]*/ +True if D has a key k, else False. +[clinic start generated code]*/ PyDoc_STRVAR(dict___contains____doc__, -"__contains__(key)\n" -"True if D has a key k, else False\""); +"__contains__($self, key, /)\n" +"--\n" +"\n" +"True if D has a key k, else False."); #define DICT___CONTAINS___METHODDEF \ {"__contains__", (PyCFunction)dict___contains__, METH_O|METH_COEXIST, dict___contains____doc__}, static PyObject * -dict___contains__(PyObject *self, PyObject *key) -/*[clinic checksum: 3bbac5ce898ae630d9668fa1c8b3afb645ff22e8]*/ +dict___contains__(PyDictObject *self, PyObject *key) +/*[clinic end generated code: output=3cf3f8aaf2cc5cc3 input=b852b2a19b51ab24]*/ { - register PyDictObject *mp = (PyDictObject *)self; + register PyDictObject *mp = self; Py_hash_t hash; PyDictKeyEntry *ep; PyObject **value_addr; @@ -2496,10 +2589,6 @@ If E is present and has a .keys() method, then does: for k in E: D[k] = E[k]\n\ If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v\n\ In either case, this is followed by: for k in F: D[k] = F[k]"); -PyDoc_STRVAR(fromkeys__doc__, -"dict.fromkeys(S[,v]) -> New dict with keys from S and values equal to v.\n\ -v defaults to None."); - PyDoc_STRVAR(clear__doc__, "D.clear() -> None. Remove all items from D."); @@ -2540,8 +2629,7 @@ static PyMethodDef mapp_methods[] = { values__doc__}, {"update", (PyCFunction)dict_update, METH_VARARGS | METH_KEYWORDS, update__doc__}, - {"fromkeys", (PyCFunction)dict_fromkeys, METH_VARARGS | METH_CLASS, - fromkeys__doc__}, + DICT_FROMKEYS_METHODDEF {"clear", (PyCFunction)dict_clear, METH_NOARGS, clear__doc__}, {"copy", (PyCFunction)dict_copy, METH_NOARGS, diff --git a/Objects/exceptions.c b/Objects/exceptions.c index af40bc8feae6..e09d384faaec 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -16,9 +16,6 @@ PyObject *PyExc_IOError = NULL; #ifdef MS_WINDOWS PyObject *PyExc_WindowsError = NULL; #endif -#ifdef __VMS -PyObject *PyExc_VMSError = NULL; -#endif /* The dict map from errno codes to OSError subclasses */ static PyObject *errnomap = NULL; @@ -727,13 +724,17 @@ ComplexExtendsException(PyExc_Exception, ImportError, * we hack args so that it only contains two items. This also * means we need our own __str__() which prints out the filename * when it was supplied. + * + * (If a function has two filenames, such as rename(), symlink(), + * or copy(), PyErr_SetFromErrnoWithFilenameObjects() is called, + * which allows passing in a second filename.) */ /* This function doesn't cleanup on error, the caller should */ static int oserror_parse_args(PyObject **p_args, PyObject **myerrno, PyObject **strerror, - PyObject **filename + PyObject **filename, PyObject **filename2 #ifdef MS_WINDOWS , PyObject **winerror #endif @@ -741,14 +742,23 @@ oserror_parse_args(PyObject **p_args, { Py_ssize_t nargs; PyObject *args = *p_args; +#ifndef MS_WINDOWS + /* + * ignored on non-Windows platforms, + * but parsed so OSError has a consistent signature + */ + PyObject *_winerror = NULL; + PyObject **winerror = &_winerror; +#endif /* MS_WINDOWS */ nargs = PyTuple_GET_SIZE(args); -#ifdef MS_WINDOWS - if (nargs >= 2 && nargs <= 4) { - if (!PyArg_UnpackTuple(args, "OSError", 2, 4, - myerrno, strerror, filename, winerror)) + if (nargs >= 2 && nargs <= 5) { + if (!PyArg_UnpackTuple(args, "OSError", 2, 5, + myerrno, strerror, + filename, winerror, filename2)) return -1; +#ifdef MS_WINDOWS if (*winerror && PyLong_Check(*winerror)) { long errcode, winerrcode; PyObject *newargs; @@ -780,14 +790,8 @@ oserror_parse_args(PyObject **p_args, Py_DECREF(args); args = *p_args = newargs; } +#endif /* MS_WINDOWS */ } -#else - if (nargs >= 2 && nargs <= 3) { - if (!PyArg_UnpackTuple(args, "OSError", 2, 3, - myerrno, strerror, filename)) - return -1; - } -#endif return 0; } @@ -795,7 +799,7 @@ oserror_parse_args(PyObject **p_args, static int oserror_init(PyOSErrorObject *self, PyObject **p_args, PyObject *myerrno, PyObject *strerror, - PyObject *filename + PyObject *filename, PyObject *filename2 #ifdef MS_WINDOWS , PyObject *winerror #endif @@ -819,9 +823,14 @@ oserror_init(PyOSErrorObject *self, PyObject **p_args, Py_INCREF(filename); self->filename = filename; - if (nargs >= 2 && nargs <= 3) { - /* filename is removed from the args tuple (for compatibility - purposes, see test_exceptions.py) */ + if (filename2 && filename2 != Py_None) { + Py_INCREF(filename2); + self->filename2 = filename2; + } + + if (nargs >= 2 && nargs <= 5) { + /* filename, filename2, and winerror are removed from the args tuple + (for compatibility purposes, see test_exceptions.py) */ PyObject *subslice = PyTuple_GetSlice(args, 0, 2); if (!subslice) return -1; @@ -880,7 +889,8 @@ static PyObject * OSError_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyOSErrorObject *self = NULL; - PyObject *myerrno = NULL, *strerror = NULL, *filename = NULL; + PyObject *myerrno = NULL, *strerror = NULL; + PyObject *filename = NULL, *filename2 = NULL; #ifdef MS_WINDOWS PyObject *winerror = NULL; #endif @@ -891,7 +901,8 @@ OSError_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (!_PyArg_NoKeywords(type->tp_name, kwds)) goto error; - if (oserror_parse_args(&args, &myerrno, &strerror, &filename + if (oserror_parse_args(&args, &myerrno, &strerror, + &filename, &filename2 #ifdef MS_WINDOWS , &winerror #endif @@ -920,7 +931,7 @@ OSError_new(PyTypeObject *type, PyObject *args, PyObject *kwds) self->written = -1; if (!oserror_use_init(type)) { - if (oserror_init(self, &args, myerrno, strerror, filename + if (oserror_init(self, &args, myerrno, strerror, filename, filename2 #ifdef MS_WINDOWS , winerror #endif @@ -945,7 +956,8 @@ OSError_new(PyTypeObject *type, PyObject *args, PyObject *kwds) static int OSError_init(PyOSErrorObject *self, PyObject *args, PyObject *kwds) { - PyObject *myerrno = NULL, *strerror = NULL, *filename = NULL; + PyObject *myerrno = NULL, *strerror = NULL; + PyObject *filename = NULL, *filename2 = NULL; #ifdef MS_WINDOWS PyObject *winerror = NULL; #endif @@ -958,14 +970,14 @@ OSError_init(PyOSErrorObject *self, PyObject *args, PyObject *kwds) return -1; Py_INCREF(args); - if (oserror_parse_args(&args, &myerrno, &strerror, &filename + if (oserror_parse_args(&args, &myerrno, &strerror, &filename, &filename2 #ifdef MS_WINDOWS , &winerror #endif )) goto error; - if (oserror_init(self, &args, myerrno, strerror, filename + if (oserror_init(self, &args, myerrno, strerror, filename, filename2 #ifdef MS_WINDOWS , winerror #endif @@ -985,6 +997,7 @@ OSError_clear(PyOSErrorObject *self) Py_CLEAR(self->myerrno); Py_CLEAR(self->strerror); Py_CLEAR(self->filename); + Py_CLEAR(self->filename2); #ifdef MS_WINDOWS Py_CLEAR(self->winerror); #endif @@ -1006,6 +1019,7 @@ OSError_traverse(PyOSErrorObject *self, visitproc visit, Py_VISIT(self->myerrno); Py_VISIT(self->strerror); Py_VISIT(self->filename); + Py_VISIT(self->filename2); #ifdef MS_WINDOWS Py_VISIT(self->winerror); #endif @@ -1015,23 +1029,42 @@ OSError_traverse(PyOSErrorObject *self, visitproc visit, static PyObject * OSError_str(PyOSErrorObject *self) { +#define OR_NONE(x) ((x)?(x):Py_None) #ifdef MS_WINDOWS /* If available, winerror has the priority over myerrno */ - if (self->winerror && self->filename) - return PyUnicode_FromFormat("[WinError %S] %S: %R", - self->winerror ? self->winerror: Py_None, - self->strerror ? self->strerror: Py_None, - self->filename); + if (self->winerror && self->filename) { + if (self->filename2) { + return PyUnicode_FromFormat("[WinError %S] %S: %R -> %R", + OR_NONE(self->winerror), + OR_NONE(self->strerror), + self->filename, + self->filename2); + } else { + return PyUnicode_FromFormat("[WinError %S] %S: %R", + OR_NONE(self->winerror), + OR_NONE(self->strerror), + self->filename); + } + } if (self->winerror && self->strerror) return PyUnicode_FromFormat("[WinError %S] %S", self->winerror ? self->winerror: Py_None, self->strerror ? self->strerror: Py_None); #endif - if (self->filename) - return PyUnicode_FromFormat("[Errno %S] %S: %R", - self->myerrno ? self->myerrno: Py_None, - self->strerror ? self->strerror: Py_None, - self->filename); + if (self->filename) { + if (self->filename2) { + return PyUnicode_FromFormat("[Errno %S] %S: %R -> %R", + OR_NONE(self->myerrno), + OR_NONE(self->strerror), + self->filename, + self->filename2); + } else { + return PyUnicode_FromFormat("[Errno %S] %S: %R", + OR_NONE(self->myerrno), + OR_NONE(self->strerror), + self->filename); + } + } if (self->myerrno && self->strerror) return PyUnicode_FromFormat("[Errno %S] %S", self->myerrno ? self->myerrno: Py_None, @@ -1048,7 +1081,8 @@ OSError_reduce(PyOSErrorObject *self) /* self->args is only the first two real arguments if there was a * file name given to OSError. */ if (PyTuple_GET_SIZE(args) == 2 && self->filename) { - args = PyTuple_New(3); + Py_ssize_t size = self->filename2 ? 5 : 3; + args = PyTuple_New(size); if (!args) return NULL; @@ -1062,6 +1096,20 @@ OSError_reduce(PyOSErrorObject *self) Py_INCREF(self->filename); PyTuple_SET_ITEM(args, 2, self->filename); + + if (self->filename2) { + /* + * This tuple is essentially used as OSError(*args). + * So, to recreate filename2, we need to pass in + * winerror as well. + */ + Py_INCREF(Py_None); + PyTuple_SET_ITEM(args, 3, Py_None); + + /* filename2 */ + Py_INCREF(self->filename2); + PyTuple_SET_ITEM(args, 4, self->filename2); + } } else Py_INCREF(args); @@ -1101,6 +1149,8 @@ static PyMemberDef OSError_members[] = { PyDoc_STR("exception strerror")}, {"filename", T_OBJECT, offsetof(PyOSErrorObject, filename), 0, PyDoc_STR("exception filename")}, + {"filename2", T_OBJECT, offsetof(PyOSErrorObject, filename2), 0, + PyDoc_STR("second exception filename")}, #ifdef MS_WINDOWS {"winerror", T_OBJECT, offsetof(PyOSErrorObject, winerror), 0, PyDoc_STR("Win32 exception code")}, @@ -1204,6 +1254,9 @@ SimpleExtendsException(PyExc_Exception, AttributeError, * SyntaxError extends Exception */ +/* Helper function to customise error message for some syntax errors */ +static int _report_missing_parentheses(PySyntaxErrorObject *self); + static int SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds) { @@ -1248,6 +1301,13 @@ SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds) Py_INCREF(self->text); Py_DECREF(info); + + /* Issue #21669: Custom error for 'print' & 'exec' as statements */ + if (self->text && PyUnicode_Check(self->text)) { + if (_report_missing_parentheses(self) < 0) { + return -1; + } + } } return 0; } @@ -1787,6 +1847,10 @@ UnicodeEncodeError_str(PyObject *self) PyObject *reason_str = NULL; PyObject *encoding_str = NULL; + if (!uself->object) + /* Not properly initialized. */ + return PyUnicode_FromString(""); + /* Get reason and encoding as strings, which they might not be if they've been modified after we were contructed. */ reason_str = PyObject_Str(uself->reason); @@ -1858,8 +1922,6 @@ static int UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds) { PyUnicodeErrorObject *ude; - const char *data; - Py_ssize_t size; if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1) return -1; @@ -1880,21 +1942,27 @@ UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds) return -1; } - if (!PyBytes_Check(ude->object)) { - if (PyObject_AsReadBuffer(ude->object, (const void **)&data, &size)) { - ude->encoding = ude->object = ude->reason = NULL; - return -1; - } - ude->object = PyBytes_FromStringAndSize(data, size); - } - else { - Py_INCREF(ude->object); - } - Py_INCREF(ude->encoding); + Py_INCREF(ude->object); Py_INCREF(ude->reason); + if (!PyBytes_Check(ude->object)) { + Py_buffer view; + if (PyObject_GetBuffer(ude->object, &view, PyBUF_SIMPLE) != 0) + goto error; + Py_CLEAR(ude->object); + ude->object = PyBytes_FromStringAndSize(view.buf, view.len); + PyBuffer_Release(&view); + if (!ude->object) + goto error; + } return 0; + +error: + Py_CLEAR(ude->encoding); + Py_CLEAR(ude->object); + Py_CLEAR(ude->reason); + return -1; } static PyObject * @@ -1905,6 +1973,10 @@ UnicodeDecodeError_str(PyObject *self) PyObject *reason_str = NULL; PyObject *encoding_str = NULL; + if (!uself->object) + /* Not properly initialized. */ + return PyUnicode_FromString(""); + /* Get reason and encoding as strings, which they might not be if they've been modified after we were contructed. */ reason_str = PyObject_Str(uself->reason); @@ -1999,6 +2071,10 @@ UnicodeTranslateError_str(PyObject *self) PyObject *result = NULL; PyObject *reason_str = NULL; + if (!uself->object) + /* Not properly initialized. */ + return PyUnicode_FromString(""); + /* Get reason as a string, which it might not be if it's been modified after we were contructed. */ reason_str = PyObject_Str(uself->reason); @@ -2062,7 +2138,7 @@ _PyUnicodeTranslateError_Create( PyObject *object, Py_ssize_t start, Py_ssize_t end, const char *reason) { - return PyObject_CallFunction(PyExc_UnicodeTranslateError, "Ons", + return PyObject_CallFunction(PyExc_UnicodeTranslateError, "Onns", object, start, end, reason); } @@ -2472,9 +2548,6 @@ _PyExc_Init(PyObject *bltinmod) INIT_ALIAS(IOError, OSError) #ifdef MS_WINDOWS INIT_ALIAS(WindowsError, OSError) -#endif -#ifdef __VMS - INIT_ALIAS(VMSError, OSError) #endif POST_INIT(EOFError) POST_INIT(RuntimeError) @@ -2645,7 +2718,7 @@ _PyErr_TrySetFromCause(const char *format, ...) same_basic_size = ( caught_type_size == base_exc_size || (PyType_SUPPORTS_WEAKREFS(caught_type) && - (caught_type_size == base_exc_size + sizeof(PyObject *)) + (caught_type_size == base_exc_size + (Py_ssize_t)sizeof(PyObject *)) ) ); if (caught_type->tp_init != (initproc)BaseException_init || @@ -2695,8 +2768,11 @@ _PyErr_TrySetFromCause(const char *format, ...) * types as well, but that's quite a bit trickier due to the extra * state potentially stored on OSError instances. */ - - Py_XDECREF(tb); + /* Ensure the traceback is set correctly on the existing exception */ + if (tb != NULL) { + PyException_SetTraceback(val, tb); + Py_DECREF(tb); + } #ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); @@ -2721,3 +2797,128 @@ _PyErr_TrySetFromCause(const char *format, ...) PyErr_Restore(new_exc, new_val, new_tb); return new_val; } + + +/* To help with migration from Python 2, SyntaxError.__init__ applies some + * heuristics to try to report a more meaningful exception when print and + * exec are used like statements. + * + * The heuristics are currently expected to detect the following cases: + * - top level statement + * - statement in a nested suite + * - trailing section of a one line complex statement + * + * They're currently known not to trigger: + * - after a semi-colon + * + * The error message can be a bit odd in cases where the "arguments" are + * completely illegal syntactically, but that isn't worth the hassle of + * fixing. + * + * We also can't do anything about cases that are legal Python 3 syntax + * but mean something entirely different from what they did in Python 2 + * (omitting the arguments entirely, printing items preceded by a unary plus + * or minus, using the stream redirection syntax). + */ + +static int +_check_for_legacy_statements(PySyntaxErrorObject *self, Py_ssize_t start) +{ + /* Return values: + * -1: an error occurred + * 0: nothing happened + * 1: the check triggered & the error message was changed + */ + static PyObject *print_prefix = NULL; + static PyObject *exec_prefix = NULL; + Py_ssize_t text_len = PyUnicode_GET_LENGTH(self->text); + int kind = PyUnicode_KIND(self->text); + void *data = PyUnicode_DATA(self->text); + + /* Ignore leading whitespace */ + while (start < text_len) { + Py_UCS4 ch = PyUnicode_READ(kind, data, start); + if (!Py_UNICODE_ISSPACE(ch)) + break; + start++; + } + /* Checking against an empty or whitespace-only part of the string */ + if (start == text_len) { + return 0; + } + + /* Check for legacy print statements */ + if (print_prefix == NULL) { + print_prefix = PyUnicode_InternFromString("print "); + if (print_prefix == NULL) { + return -1; + } + } + if (PyUnicode_Tailmatch(self->text, print_prefix, + start, text_len, -1)) { + Py_CLEAR(self->msg); + self->msg = PyUnicode_FromString( + "Missing parentheses in call to 'print'"); + return 1; + } + + /* Check for legacy exec statements */ + if (exec_prefix == NULL) { + exec_prefix = PyUnicode_InternFromString("exec "); + if (exec_prefix == NULL) { + return -1; + } + } + if (PyUnicode_Tailmatch(self->text, exec_prefix, + start, text_len, -1)) { + Py_CLEAR(self->msg); + self->msg = PyUnicode_FromString( + "Missing parentheses in call to 'exec'"); + return 1; + } + /* Fall back to the default error message */ + return 0; +} + +static int +_report_missing_parentheses(PySyntaxErrorObject *self) +{ + Py_UCS4 left_paren = 40; + Py_ssize_t left_paren_index; + Py_ssize_t text_len = PyUnicode_GET_LENGTH(self->text); + int legacy_check_result = 0; + + /* Skip entirely if there is an opening parenthesis */ + left_paren_index = PyUnicode_FindChar(self->text, left_paren, + 0, text_len, 1); + if (left_paren_index < -1) { + return -1; + } + if (left_paren_index != -1) { + /* Use default error message for any line with an opening paren */ + return 0; + } + /* Handle the simple statement case */ + legacy_check_result = _check_for_legacy_statements(self, 0); + if (legacy_check_result < 0) { + return -1; + + } + if (legacy_check_result == 0) { + /* Handle the one-line complex statement case */ + Py_UCS4 colon = 58; + Py_ssize_t colon_index; + colon_index = PyUnicode_FindChar(self->text, colon, + 0, text_len, 1); + if (colon_index < -1) { + return -1; + } + if (colon_index >= 0 && colon_index < text_len) { + /* Check again, starting from just after the colon */ + if (_check_for_legacy_statements(self, colon_index+1) < 0) { + return -1; + } + } + } + return 0; +} diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 29c3b32763c2..8d8512191009 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -119,7 +119,7 @@ PyFloat_FromDouble(double fval) return PyErr_NoMemory(); } /* Inline PyObject_New */ - PyObject_INIT(op, &PyFloat_Type); + (void)PyObject_INIT(op, &PyFloat_Type); op->ob_fval = fval; return (PyObject *) op; } @@ -131,6 +131,7 @@ PyFloat_FromString(PyObject *v) double x; PyObject *s_buffer = NULL; Py_ssize_t len; + Py_buffer view = {NULL, NULL}; PyObject *result = NULL; if (PyUnicode_Check(v)) { @@ -143,7 +144,11 @@ PyFloat_FromString(PyObject *v) return NULL; } } - else if (PyObject_AsCharBuffer(v, &s, &len)) { + else if (PyObject_GetBuffer(v, &view, PyBUF_SIMPLE) == 0) { + s = (const char *)view.buf; + len = view.len; + } + else { PyErr_Format(PyExc_TypeError, "float() argument must be a string or a number, not '%.200s'", Py_TYPE(v)->tp_name); @@ -170,6 +175,7 @@ PyFloat_FromString(PyObject *v) else result = PyFloat_FromDouble(x); + PyBuffer_Release(&view); Py_XDECREF(s_buffer); return result; } @@ -2026,7 +2032,7 @@ _PyFloat_Pack4(double x, unsigned char *p, int le) } else { float y = (float)x; - const char *s = (char*)&y; + const unsigned char *s = (unsigned char*)&y; int i, incr = 1; if (Py_IS_INFINITY(y) && !Py_IS_INFINITY(x)) @@ -2162,7 +2168,7 @@ _PyFloat_Pack8(double x, unsigned char *p, int le) return -1; } else { - const char *s = (char*)&x; + const unsigned char *s = (unsigned char*)&x; int i, incr = 1; if ((double_format == ieee_little_endian_format && !le) diff --git a/Objects/frameobject.c b/Objects/frameobject.c index 63f03a64e056..55ee5630f67e 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -726,7 +726,6 @@ PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals, Py_INCREF(locals); f->f_locals = locals; } - f->f_tstate = tstate; f->f_lasti = -1; f->f_lineno = code->co_firstlineno; @@ -787,7 +786,7 @@ map_to_dict(PyObject *map, Py_ssize_t nmap, PyObject *dict, PyObject **values, PyObject *key = PyTuple_GET_ITEM(map, j); PyObject *value = values[j]; assert(PyUnicode_Check(key)); - if (deref) { + if (deref && value != NULL) { assert(PyCell_Check(value)); value = PyCell_GET(value); } diff --git a/Objects/genobject.c b/Objects/genobject.c index 08d30bf4b7b7..4be739ab8288 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -12,6 +12,8 @@ gen_traverse(PyGenObject *gen, visitproc visit, void *arg) { Py_VISIT((PyObject *)gen->gi_frame); Py_VISIT(gen->gi_code); + Py_VISIT(gen->gi_name); + Py_VISIT(gen->gi_qualname); return 0; } @@ -58,6 +60,8 @@ gen_dealloc(PyGenObject *gen) _PyObject_GC_UNTRACK(self); Py_CLEAR(gen->gi_frame); Py_CLEAR(gen->gi_code); + Py_CLEAR(gen->gi_name); + Py_CLEAR(gen->gi_qualname); PyObject_GC_Del(gen); } @@ -373,11 +377,7 @@ gen_throw(PyGenObject *gen, PyObject *args) static PyObject * gen_iternext(PyGenObject *gen) { - PyObject *val = NULL; - PyObject *ret; - ret = gen_send_ex(gen, val, 0); - Py_XDECREF(val); - return ret; + return gen_send_ex(gen, NULL, 0); } /* @@ -418,33 +418,73 @@ static PyObject * gen_repr(PyGenObject *gen) { return PyUnicode_FromFormat("", - ((PyCodeObject *)gen->gi_code)->co_name, - gen); + gen->gi_qualname, gen); +} + +static PyObject * +gen_get_name(PyGenObject *op) +{ + Py_INCREF(op->gi_name); + return op->gi_name; } +static int +gen_set_name(PyGenObject *op, PyObject *value) +{ + PyObject *tmp; + + /* Not legal to del gen.gi_name or to set it to anything + * other than a string object. */ + if (value == NULL || !PyUnicode_Check(value)) { + PyErr_SetString(PyExc_TypeError, + "__name__ must be set to a string object"); + return -1; + } + tmp = op->gi_name; + Py_INCREF(value); + op->gi_name = value; + Py_DECREF(tmp); + return 0; +} static PyObject * -gen_get_name(PyGenObject *gen) +gen_get_qualname(PyGenObject *op) { - PyObject *name = ((PyCodeObject *)gen->gi_code)->co_name; - Py_INCREF(name); - return name; + Py_INCREF(op->gi_qualname); + return op->gi_qualname; } +static int +gen_set_qualname(PyGenObject *op, PyObject *value) +{ + PyObject *tmp; -PyDoc_STRVAR(gen__name__doc__, -"Return the name of the generator's associated code object."); + /* Not legal to del gen.__qualname__ or to set it to anything + * other than a string object. */ + if (value == NULL || !PyUnicode_Check(value)) { + PyErr_SetString(PyExc_TypeError, + "__qualname__ must be set to a string object"); + return -1; + } + tmp = op->gi_qualname; + Py_INCREF(value); + op->gi_qualname = value; + Py_DECREF(tmp); + return 0; +} static PyGetSetDef gen_getsetlist[] = { - {"__name__", (getter)gen_get_name, NULL, gen__name__doc__}, - {NULL} + {"__name__", (getter)gen_get_name, (setter)gen_set_name, + PyDoc_STR("name of the generator")}, + {"__qualname__", (getter)gen_get_qualname, (setter)gen_set_qualname, + PyDoc_STR("qualified name of the generator")}, + {NULL} /* Sentinel */ }; - static PyMemberDef gen_memberlist[] = { - {"gi_frame", T_OBJECT, offsetof(PyGenObject, gi_frame), READONLY}, - {"gi_running", T_BOOL, offsetof(PyGenObject, gi_running), READONLY}, - {"gi_code", T_OBJECT, offsetof(PyGenObject, gi_code), READONLY}, + {"gi_frame", T_OBJECT, offsetof(PyGenObject, gi_frame), READONLY}, + {"gi_running", T_BOOL, offsetof(PyGenObject, gi_running), READONLY}, + {"gi_code", T_OBJECT, offsetof(PyGenObject, gi_code), READONLY}, {NULL} /* Sentinel */ }; @@ -510,7 +550,7 @@ PyTypeObject PyGen_Type = { }; PyObject * -PyGen_New(PyFrameObject *f) +PyGen_NewWithQualName(PyFrameObject *f, PyObject *name, PyObject *qualname) { PyGenObject *gen = PyObject_GC_New(PyGenObject, &PyGen_Type); if (gen == NULL) { @@ -523,10 +563,26 @@ PyGen_New(PyFrameObject *f) gen->gi_code = (PyObject *)(f->f_code); gen->gi_running = 0; gen->gi_weakreflist = NULL; + if (name != NULL) + gen->gi_name = name; + else + gen->gi_name = ((PyCodeObject *)gen->gi_code)->co_name; + Py_INCREF(gen->gi_name); + if (qualname != NULL) + gen->gi_qualname = qualname; + else + gen->gi_qualname = gen->gi_name; + Py_INCREF(gen->gi_qualname); _PyObject_GC_TRACK(gen); return (PyObject *)gen; } +PyObject * +PyGen_New(PyFrameObject *f) +{ + return PyGen_NewWithQualName(f, NULL, NULL); +} + int PyGen_NeedsFinalizing(PyGenObject *gen) { diff --git a/Objects/listobject.c b/Objects/listobject.c index 5b75968fb387..e7c4c82703ff 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -1970,7 +1970,7 @@ listsort(PyListObject *self, PyObject *args, PyObject *kwds) if (keys[i] == NULL) { for (i=i-1 ; i>=0 ; i--) Py_DECREF(keys[i]); - if (keys != &ms.temparray[saved_ob_size+1]) + if (saved_ob_size >= MERGESTATE_TEMP_SIZE/2) PyMem_FREE(keys); goto keyfunc_fail; } @@ -2043,7 +2043,7 @@ listsort(PyListObject *self, PyObject *args, PyObject *kwds) if (keys != NULL) { for (i = 0; i < saved_ob_size; i++) Py_DECREF(keys[i]); - if (keys != &ms.temparray[saved_ob_size+1]) + if (saved_ob_size >= MERGESTATE_TEMP_SIZE/2) PyMem_FREE(keys); } @@ -2444,7 +2444,7 @@ list_subscript(PyListObject* self, PyObject* item) } else { PyErr_Format(PyExc_TypeError, - "list indices must be integers, not %.200s", + "list indices must be integers or slices, not %.200s", item->ob_type->tp_name); return NULL; } @@ -2608,7 +2608,7 @@ list_ass_subscript(PyListObject* self, PyObject* item, PyObject* value) } else { PyErr_Format(PyExc_TypeError, - "list indices must be integers, not %.200s", + "list indices must be integers or slices, not %.200s", item->ob_type->tp_name); return -1; } @@ -2811,6 +2811,8 @@ listiter_setstate(listiterobject *it, PyObject *state) if (it->it_seq != NULL) { if (index < 0) index = 0; + else if (index > PyList_GET_SIZE(it->it_seq)) + index = PyList_GET_SIZE(it->it_seq); /* iterator exhausted */ it->it_index = index; } Py_RETURN_NONE; diff --git a/Objects/longobject.c b/Objects/longobject.c index a5c0d1b33f39..27bee50b8ce7 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -21,7 +21,6 @@ Py_SIZE(x) < 0 ? -(sdigit)(x)->ob_digit[0] : \ (Py_SIZE(x) == 0 ? (sdigit)0 : \ (sdigit)(x)->ob_digit[0])) -#define ABS(x) ((x) < 0 ? -(x) : (x)) #if NSMALLNEGINTS + NSMALLPOSINTS > 0 /* Small integers are preallocated in this array so that they @@ -37,7 +36,9 @@ Py_ssize_t quick_int_allocs, quick_neg_int_allocs; static PyObject * get_small_int(sdigit ival) { - PyObject *v = (PyObject*)(small_ints + ival + NSMALLNEGINTS); + PyObject *v; + assert(-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS); + v = (PyObject *)&small_ints[ival + NSMALLNEGINTS]; Py_INCREF(v); #ifdef COUNT_ALLOCS if (ival >= 0) @@ -55,7 +56,7 @@ get_small_int(sdigit ival) static PyLongObject * maybe_small_long(PyLongObject *v) { - if (v && ABS(Py_SIZE(v)) <= 1) { + if (v && Py_ABS(Py_SIZE(v)) <= 1) { sdigit ival = MEDIUM_VALUE(v); if (-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS) { Py_DECREF(v); @@ -112,7 +113,7 @@ _PyLong_Negate(PyLongObject **x_p) static PyLongObject * long_normalize(PyLongObject *v) { - Py_ssize_t j = ABS(Py_SIZE(v)); + Py_ssize_t j = Py_ABS(Py_SIZE(v)); Py_ssize_t i = j; while (i > 0 && v->ob_digit[i-1] == 0) @@ -122,6 +123,56 @@ long_normalize(PyLongObject *v) return v; } +/* _PyLong_FromNbInt: Convert the given object to a PyLongObject + using the nb_int slot, if available. Raise TypeError if either the + nb_int slot is not available or the result of the call to nb_int + returns something not of type int. +*/ +PyLongObject * +_PyLong_FromNbInt(PyObject *integral) +{ + PyNumberMethods *nb; + PyObject *result; + + /* Fast path for the case that we already have an int. */ + if (PyLong_CheckExact(integral)) { + Py_INCREF(integral); + return (PyLongObject *)integral; + } + + nb = Py_TYPE(integral)->tp_as_number; + if (nb == NULL || nb->nb_int == NULL) { + PyErr_Format(PyExc_TypeError, + "an integer is required (got type %.200s)", + Py_TYPE(integral)->tp_name); + return NULL; + } + + /* Convert using the nb_int slot, which should return something + of exact type int. */ + result = nb->nb_int(integral); + if (!result || PyLong_CheckExact(result)) + return (PyLongObject *)result; + if (!PyLong_Check(result)) { + PyErr_Format(PyExc_TypeError, + "__int__ returned non-int (type %.200s)", + result->ob_type->tp_name); + Py_DECREF(result); + return NULL; + } + /* Issue #17576: warn if 'result' not of exact type int. */ + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "__int__ returned non-int (type %.200s). " + "The ability to return an instance of a strict subclass of int " + "is deprecated, and may be removed in a future version of Python.", + result->ob_type->tp_name)) { + Py_DECREF(result); + return NULL; + } + return (PyLongObject *)result; +} + + /* Allocate a new int object with size digits. Return NULL and set exception if we run out of memory. */ @@ -353,28 +404,17 @@ PyLong_AsLongAndOverflow(PyObject *vv, int *overflow) return -1; } - if (!PyLong_Check(vv)) { - PyNumberMethods *nb; - nb = vv->ob_type->tp_as_number; - if (nb == NULL || nb->nb_int == NULL) { - PyErr_SetString(PyExc_TypeError, - "an integer is required"); - return -1; - } - vv = (*nb->nb_int) (vv); - if (vv == NULL) + if (PyLong_Check(vv)) { + v = (PyLongObject *)vv; + } + else { + v = _PyLong_FromNbInt(vv); + if (v == NULL) return -1; do_decref = 1; - if (!PyLong_Check(vv)) { - Py_DECREF(vv); - PyErr_SetString(PyExc_TypeError, - "nb_int should return int object"); - return -1; - } } res = -1; - v = (PyLongObject *)vv; i = Py_SIZE(v); switch (i) { @@ -418,7 +458,7 @@ PyLong_AsLongAndOverflow(PyObject *vv, int *overflow) } exit: if (do_decref) { - Py_DECREF(vv); + Py_DECREF(v); } return res; } @@ -636,36 +676,25 @@ _PyLong_AsUnsignedLongMask(PyObject *vv) unsigned long PyLong_AsUnsignedLongMask(PyObject *op) { - PyNumberMethods *nb; PyLongObject *lo; unsigned long val; - if (op && PyLong_Check(op)) - return _PyLong_AsUnsignedLongMask(op); - - if (op == NULL || (nb = op->ob_type->tp_as_number) == NULL || - nb->nb_int == NULL) { - PyErr_SetString(PyExc_TypeError, "an integer is required"); + if (op == NULL) { + PyErr_BadInternalCall(); return (unsigned long)-1; } - lo = (PyLongObject*) (*nb->nb_int) (op); - if (lo == NULL) - return (unsigned long)-1; - if (PyLong_Check(lo)) { - val = _PyLong_AsUnsignedLongMask((PyObject *)lo); - Py_DECREF(lo); - if (PyErr_Occurred()) - return (unsigned long)-1; - return val; + if (PyLong_Check(op)) { + return _PyLong_AsUnsignedLongMask(op); } - else - { - Py_DECREF(lo); - PyErr_SetString(PyExc_TypeError, - "nb_int should return int object"); + + lo = _PyLong_FromNbInt(op); + if (lo == NULL) return (unsigned long)-1; - } + + val = _PyLong_AsUnsignedLongMask((PyObject *)lo); + Py_DECREF(lo); + return val; } int @@ -688,7 +717,7 @@ _PyLong_NumBits(PyObject *vv) assert(v != NULL); assert(PyLong_Check(v)); - ndigits = ABS(Py_SIZE(v)); + ndigits = Py_ABS(Py_SIZE(v)); assert(ndigits == 0 || v->ob_digit[ndigits - 1] != 0); if (ndigits > 0) { digit msd = v->ob_digit[ndigits - 1]; @@ -1167,40 +1196,41 @@ PyLong_AsLongLong(PyObject *vv) PyLongObject *v; PY_LONG_LONG bytes; int res; + int do_decref = 0; /* if nb_int was called */ if (vv == NULL) { PyErr_BadInternalCall(); return -1; } - if (!PyLong_Check(vv)) { - PyNumberMethods *nb; - PyObject *io; - if ((nb = vv->ob_type->tp_as_number) == NULL || - nb->nb_int == NULL) { - PyErr_SetString(PyExc_TypeError, "an integer is required"); - return -1; - } - io = (*nb->nb_int) (vv); - if (io == NULL) + + if (PyLong_Check(vv)) { + v = (PyLongObject *)vv; + } + else { + v = _PyLong_FromNbInt(vv); + if (v == NULL) return -1; - if (PyLong_Check(io)) { - bytes = PyLong_AsLongLong(io); - Py_DECREF(io); - return bytes; - } - Py_DECREF(io); - PyErr_SetString(PyExc_TypeError, "integer conversion failed"); - return -1; + do_decref = 1; } - v = (PyLongObject*)vv; + res = 0; switch(Py_SIZE(v)) { - case -1: return -(sdigit)v->ob_digit[0]; - case 0: return 0; - case 1: return v->ob_digit[0]; + case -1: + bytes = -(sdigit)v->ob_digit[0]; + break; + case 0: + bytes = 0; + break; + case 1: + bytes = v->ob_digit[0]; + break; + default: + res = _PyLong_AsByteArray((PyLongObject *)v, (unsigned char *)&bytes, + SIZEOF_LONG_LONG, PY_LITTLE_ENDIAN, 1); + } + if (do_decref) { + Py_DECREF(v); } - res = _PyLong_AsByteArray((PyLongObject *)vv, (unsigned char *)&bytes, - SIZEOF_LONG_LONG, PY_LITTLE_ENDIAN, 1); /* Plan 9 can't handle PY_LONG_LONG in ? : expressions */ if (res < 0) @@ -1280,36 +1310,25 @@ _PyLong_AsUnsignedLongLongMask(PyObject *vv) unsigned PY_LONG_LONG PyLong_AsUnsignedLongLongMask(PyObject *op) { - PyNumberMethods *nb; PyLongObject *lo; unsigned PY_LONG_LONG val; - if (op && PyLong_Check(op)) - return _PyLong_AsUnsignedLongLongMask(op); + if (op == NULL) { + PyErr_BadInternalCall(); + return (unsigned long)-1; + } - if (op == NULL || (nb = op->ob_type->tp_as_number) == NULL || - nb->nb_int == NULL) { - PyErr_SetString(PyExc_TypeError, "an integer is required"); - return (unsigned PY_LONG_LONG)-1; + if (PyLong_Check(op)) { + return _PyLong_AsUnsignedLongLongMask(op); } - lo = (PyLongObject*) (*nb->nb_int) (op); + lo = _PyLong_FromNbInt(op); if (lo == NULL) return (unsigned PY_LONG_LONG)-1; - if (PyLong_Check(lo)) { - val = _PyLong_AsUnsignedLongLongMask((PyObject *)lo); - Py_DECREF(lo); - if (PyErr_Occurred()) - return (unsigned PY_LONG_LONG)-1; - return val; - } - else - { - Py_DECREF(lo); - PyErr_SetString(PyExc_TypeError, - "nb_int should return int object"); - return (unsigned PY_LONG_LONG)-1; - } + + val = _PyLong_AsUnsignedLongLongMask((PyObject *)lo); + Py_DECREF(lo); + return val; } /* Get a C long long int from an int object or any object that has an @@ -1339,28 +1358,17 @@ PyLong_AsLongLongAndOverflow(PyObject *vv, int *overflow) return -1; } - if (!PyLong_Check(vv)) { - PyNumberMethods *nb; - nb = vv->ob_type->tp_as_number; - if (nb == NULL || nb->nb_int == NULL) { - PyErr_SetString(PyExc_TypeError, - "an integer is required"); - return -1; - } - vv = (*nb->nb_int) (vv); - if (vv == NULL) + if (PyLong_Check(vv)) { + v = (PyLongObject *)vv; + } + else { + v = _PyLong_FromNbInt(vv); + if (v == NULL) return -1; do_decref = 1; - if (!PyLong_Check(vv)) { - Py_DECREF(vv); - PyErr_SetString(PyExc_TypeError, - "nb_int should return int object"); - return -1; - } } res = -1; - v = (PyLongObject *)vv; i = Py_SIZE(v); switch (i) { @@ -1404,7 +1412,7 @@ PyLong_AsLongLongAndOverflow(PyObject *vv, int *overflow) } exit: if (do_decref) { - Py_DECREF(vv); + Py_DECREF(v); } return res; } @@ -1556,7 +1564,7 @@ inplace_divrem1(digit *pout, digit *pin, Py_ssize_t size, digit n) static PyLongObject * divrem1(PyLongObject *a, digit n, digit *prem) { - const Py_ssize_t size = ABS(Py_SIZE(a)); + const Py_ssize_t size = Py_ABS(Py_SIZE(a)); PyLongObject *z; assert(n > 0 && n <= PyLong_MASK); @@ -1588,7 +1596,7 @@ long_to_decimal_string_internal(PyObject *aa, PyErr_BadInternalCall(); return -1; } - size_a = ABS(Py_SIZE(a)); + size_a = Py_ABS(Py_SIZE(a)); negative = Py_SIZE(a) < 0; /* quick and dirty upper bound for the number of digits @@ -1757,7 +1765,7 @@ long_format_binary(PyObject *aa, int base, int alternate, PyErr_BadInternalCall(); return -1; } - size_a = ABS(Py_SIZE(a)); + size_a = Py_ABS(Py_SIZE(a)); negative = Py_SIZE(a) < 0; /* Compute a rough upper bound for the length of the string */ @@ -2304,7 +2312,7 @@ _PyLong_FromBytes(const char *s, Py_ssize_t len, int base) PyObject *result, *strobj; char *end = NULL; - result = PyLong_FromString((char*)s, &end, base); + result = PyLong_FromString(s, &end, base); if (end == NULL || (result != NULL && end == s + len)) return result; Py_XDECREF(result); @@ -2371,7 +2379,7 @@ static int long_divrem(PyLongObject *a, PyLongObject *b, PyLongObject **pdiv, PyLongObject **prem) { - Py_ssize_t size_a = ABS(Py_SIZE(a)), size_b = ABS(Py_SIZE(b)); + Py_ssize_t size_a = Py_ABS(Py_SIZE(a)), size_b = Py_ABS(Py_SIZE(b)); PyLongObject *z; if (size_b == 0) { @@ -2430,7 +2438,7 @@ long_divrem(PyLongObject *a, PyLongObject *b, } /* Unsigned int division with remainder -- the algorithm. The arguments v1 - and w1 should satisfy 2 <= ABS(Py_SIZE(w1)) <= ABS(Py_SIZE(v1)). */ + and w1 should satisfy 2 <= Py_ABS(Py_SIZE(w1)) <= Py_ABS(Py_SIZE(v1)). */ static PyLongObject * x_divrem(PyLongObject *v1, PyLongObject *w1, PyLongObject **prem) @@ -2450,8 +2458,8 @@ x_divrem(PyLongObject *v1, PyLongObject *w1, PyLongObject **prem) that won't overflow a digit. */ /* allocate space; w will also be used to hold the final remainder */ - size_v = ABS(Py_SIZE(v1)); - size_w = ABS(Py_SIZE(w1)); + size_v = Py_ABS(Py_SIZE(v1)); + size_w = Py_ABS(Py_SIZE(w1)); assert(size_v >= size_w && size_w >= 2); /* Assert checks by div() */ v = _PyLong_New(size_v+1); if (v == NULL) { @@ -2582,7 +2590,7 @@ _PyLong_Frexp(PyLongObject *a, Py_ssize_t *e) multiple of 4, rounding ties to a multiple of 8. */ static const int half_even_correction[8] = {0, -1, -2, 1, 0, -1, 2, 1}; - a_size = ABS(Py_SIZE(a)); + a_size = Py_ABS(Py_SIZE(a)); if (a_size == 0) { /* Special case for 0: significand 0.0, exponent 0. */ *e = 0; @@ -2723,7 +2731,7 @@ long_compare(PyLongObject *a, PyLongObject *b) sign = Py_SIZE(a) - Py_SIZE(b); } else { - Py_ssize_t i = ABS(Py_SIZE(a)); + Py_ssize_t i = Py_ABS(Py_SIZE(a)); while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i]) ; if (i < 0) @@ -2841,7 +2849,7 @@ long_hash(PyLongObject *v) static PyLongObject * x_add(PyLongObject *a, PyLongObject *b) { - Py_ssize_t size_a = ABS(Py_SIZE(a)), size_b = ABS(Py_SIZE(b)); + Py_ssize_t size_a = Py_ABS(Py_SIZE(a)), size_b = Py_ABS(Py_SIZE(b)); PyLongObject *z; Py_ssize_t i; digit carry = 0; @@ -2875,7 +2883,7 @@ x_add(PyLongObject *a, PyLongObject *b) static PyLongObject * x_sub(PyLongObject *a, PyLongObject *b) { - Py_ssize_t size_a = ABS(Py_SIZE(a)), size_b = ABS(Py_SIZE(b)); + Py_ssize_t size_a = Py_ABS(Py_SIZE(a)), size_b = Py_ABS(Py_SIZE(b)); PyLongObject *z; Py_ssize_t i; int sign = 1; @@ -2935,7 +2943,7 @@ long_add(PyLongObject *a, PyLongObject *b) CHECK_BINOP(a, b); - if (ABS(Py_SIZE(a)) <= 1 && ABS(Py_SIZE(b)) <= 1) { + if (Py_ABS(Py_SIZE(a)) <= 1 && Py_ABS(Py_SIZE(b)) <= 1) { PyObject *result = PyLong_FromLong(MEDIUM_VALUE(a) + MEDIUM_VALUE(b)); return result; @@ -2965,7 +2973,7 @@ long_sub(PyLongObject *a, PyLongObject *b) CHECK_BINOP(a, b); - if (ABS(Py_SIZE(a)) <= 1 && ABS(Py_SIZE(b)) <= 1) { + if (Py_ABS(Py_SIZE(a)) <= 1 && Py_ABS(Py_SIZE(b)) <= 1) { PyObject* r; r = PyLong_FromLong(MEDIUM_VALUE(a)-MEDIUM_VALUE(b)); return r; @@ -2994,8 +3002,8 @@ static PyLongObject * x_mul(PyLongObject *a, PyLongObject *b) { PyLongObject *z; - Py_ssize_t size_a = ABS(Py_SIZE(a)); - Py_ssize_t size_b = ABS(Py_SIZE(b)); + Py_ssize_t size_a = Py_ABS(Py_SIZE(a)); + Py_ssize_t size_b = Py_ABS(Py_SIZE(b)); Py_ssize_t i; z = _PyLong_New(size_a + size_b); @@ -3089,7 +3097,7 @@ kmul_split(PyLongObject *n, { PyLongObject *hi, *lo; Py_ssize_t size_lo, size_hi; - const Py_ssize_t size_n = ABS(Py_SIZE(n)); + const Py_ssize_t size_n = Py_ABS(Py_SIZE(n)); size_lo = Py_MIN(size_n, size); size_hi = size_n - size_lo; @@ -3118,8 +3126,8 @@ static PyLongObject *k_lopsided_mul(PyLongObject *a, PyLongObject *b); static PyLongObject * k_mul(PyLongObject *a, PyLongObject *b) { - Py_ssize_t asize = ABS(Py_SIZE(a)); - Py_ssize_t bsize = ABS(Py_SIZE(b)); + Py_ssize_t asize = Py_ABS(Py_SIZE(a)); + Py_ssize_t bsize = Py_ABS(Py_SIZE(b)); PyLongObject *ah = NULL; PyLongObject *al = NULL; PyLongObject *bh = NULL; @@ -3339,8 +3347,8 @@ ah*bh and al*bl too. static PyLongObject * k_lopsided_mul(PyLongObject *a, PyLongObject *b) { - const Py_ssize_t asize = ABS(Py_SIZE(a)); - Py_ssize_t bsize = ABS(Py_SIZE(b)); + const Py_ssize_t asize = Py_ABS(Py_SIZE(a)); + Py_ssize_t bsize = Py_ABS(Py_SIZE(b)); Py_ssize_t nbdone; /* # of b digits already multiplied */ PyLongObject *ret; PyLongObject *bslice = NULL; @@ -3398,7 +3406,7 @@ long_mul(PyLongObject *a, PyLongObject *b) CHECK_BINOP(a, b); /* fast path for single-digit multiplication */ - if (ABS(Py_SIZE(a)) <= 1 && ABS(Py_SIZE(b)) <= 1) { + if (Py_ABS(Py_SIZE(a)) <= 1 && Py_ABS(Py_SIZE(b)) <= 1) { stwodigits v = (stwodigits)(MEDIUM_VALUE(a)) * MEDIUM_VALUE(b); #ifdef HAVE_LONG_LONG return PyLong_FromLongLong((PY_LONG_LONG)v); @@ -3605,8 +3613,8 @@ long_true_divide(PyObject *v, PyObject *w) */ /* Reduce to case where a and b are both positive. */ - a_size = ABS(Py_SIZE(a)); - b_size = ABS(Py_SIZE(b)); + a_size = Py_ABS(Py_SIZE(a)); + b_size = Py_ABS(Py_SIZE(b)); negate = (Py_SIZE(a) < 0) ^ (Py_SIZE(b) < 0); if (b_size == 0) { PyErr_SetString(PyExc_ZeroDivisionError, @@ -3722,7 +3730,7 @@ long_true_divide(PyObject *v, PyObject *w) inexact = 1; Py_DECREF(rem); } - x_size = ABS(Py_SIZE(x)); + x_size = Py_ABS(Py_SIZE(x)); assert(x_size > 0); /* result of division is never zero */ x_bits = (x_size-1)*PyLong_SHIFT+bits_in_digit(x->ob_digit[x_size-1]); @@ -3832,7 +3840,7 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) if (Py_SIZE(b) < 0) { /* if exponent is negative */ if (c) { - PyErr_SetString(PyExc_TypeError, "pow() 2nd argument " + PyErr_SetString(PyExc_ValueError, "pow() 2nd argument " "cannot be negative when 3rd argument specified"); goto Error; } @@ -3994,7 +4002,7 @@ long_invert(PyLongObject *v) /* Implement ~x as -(x+1) */ PyLongObject *x; PyLongObject *w; - if (ABS(Py_SIZE(v)) <=1) + if (Py_ABS(Py_SIZE(v)) <=1) return PyLong_FromLong(-(MEDIUM_VALUE(v)+1)); w = (PyLongObject *)PyLong_FromLong(1L); if (w == NULL) @@ -4011,7 +4019,7 @@ static PyObject * long_neg(PyLongObject *v) { PyLongObject *z; - if (ABS(Py_SIZE(v)) <= 1) + if (Py_ABS(Py_SIZE(v)) <= 1) return PyLong_FromLong(-MEDIUM_VALUE(v)); z = (PyLongObject *)_PyLong_Copy(v); if (z != NULL) @@ -4066,7 +4074,7 @@ long_rshift(PyLongObject *a, PyLongObject *b) goto rshift_error; } wordshift = shiftby / PyLong_SHIFT; - newsize = ABS(Py_SIZE(a)) - wordshift; + newsize = Py_ABS(Py_SIZE(a)) - wordshift; if (newsize <= 0) return PyLong_FromLong(0); loshift = shiftby % PyLong_SHIFT; @@ -4113,7 +4121,7 @@ long_lshift(PyObject *v, PyObject *w) wordshift = shiftby / PyLong_SHIFT; remshift = shiftby - wordshift * PyLong_SHIFT; - oldsize = ABS(Py_SIZE(a)); + oldsize = Py_ABS(Py_SIZE(a)); newsize = oldsize + wordshift; if (remshift) ++newsize; @@ -4174,7 +4182,7 @@ long_bitwise(PyLongObject *a, result back to sign-magnitude at the end. */ /* If a is negative, replace it by its two's complement. */ - size_a = ABS(Py_SIZE(a)); + size_a = Py_ABS(Py_SIZE(a)); nega = Py_SIZE(a) < 0; if (nega) { z = _PyLong_New(size_a); @@ -4188,7 +4196,7 @@ long_bitwise(PyLongObject *a, Py_INCREF(a); /* Same for b. */ - size_b = ABS(Py_SIZE(b)); + size_b = Py_ABS(Py_SIZE(b)); negb = Py_SIZE(b) < 0; if (negb) { z = _PyLong_New(size_b); @@ -4621,7 +4629,7 @@ long_sizeof(PyLongObject *v) { Py_ssize_t res; - res = offsetof(PyLongObject, ob_digit) + ABS(Py_SIZE(v))*sizeof(digit); + res = offsetof(PyLongObject, ob_digit) + Py_ABS(Py_SIZE(v))*sizeof(digit); return PyLong_FromSsize_t(res); } @@ -4635,7 +4643,7 @@ long_bit_length(PyLongObject *v) assert(v != NULL); assert(PyLong_Check(v)); - ndigits = ABS(Py_SIZE(v)); + ndigits = Py_ABS(Py_SIZE(v)); if (ndigits == 0) return PyLong_FromLong(0); @@ -4840,7 +4848,7 @@ long_from_bytes(PyTypeObject *type, PyObject *args, PyObject *kwds) if (type != &PyLong_Type && PyType_IsSubtype(type, &PyLong_Type)) { PyLongObject *newobj; int i; - Py_ssize_t n = ABS(Py_SIZE(long_obj)); + Py_ssize_t n = Py_ABS(Py_SIZE(long_obj)); newobj = (PyLongObject *)type->tp_alloc(type, n); if (newobj == NULL) { @@ -4865,9 +4873,7 @@ PyDoc_STRVAR(long_from_bytes_doc, \n\ Return the integer represented by the given array of bytes.\n\ \n\ -The bytes argument must either support the buffer protocol or be an\n\ -iterable object producing bytes. Bytes and bytearray are examples of\n\ -built-in objects that support the buffer protocol.\n\ +The bytes argument must be a bytes-like object (e.g. bytes or bytearray).\n\ \n\ The byteorder argument determines the byte order used to represent the\n\ integer. If byteorder is 'big', the most significant byte is at the\n\ @@ -5086,13 +5092,13 @@ _PyLong_Init(void) * to the original refcnt + 1 */ Py_REFCNT(op) = refcnt + 1; assert(Py_SIZE(op) == size); - assert(v->ob_digit[0] == abs(ival)); + assert(v->ob_digit[0] == (digit)abs(ival)); } else { - PyObject_INIT(v, &PyLong_Type); + (void)PyObject_INIT(v, &PyLong_Type); } Py_SIZE(v) = size; - v->ob_digit[0] = abs(ival); + v->ob_digit[0] = (digit)abs(ival); } #endif /* initialize int_info */ diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c index cb644b822b7a..b611dc864ce3 100644 --- a/Objects/memoryobject.c +++ b/Objects/memoryobject.c @@ -48,9 +48,6 @@ */ -#define XSTRINGIZE(v) #v -#define STRINGIZE(v) XSTRINGIZE(v) - #define CHECK_MBUF_RELEASED(mbuf) \ if (((_PyManagedBufferObject *)mbuf)->flags&_Py_MANAGED_BUFFER_RELEASED) { \ PyErr_SetString(PyExc_ValueError, \ @@ -223,7 +220,7 @@ PyTypeObject _PyManagedBuffer_Type = { PyDoc_STRVAR(memory_doc, -"memoryview(object)\n\ +"memoryview($module, object)\n--\n\ \n\ Create a new memoryview object which references the given object."); @@ -660,7 +657,7 @@ mbuf_add_view(_PyManagedBufferObject *mbuf, const Py_buffer *src) if (src->ndim > PyBUF_MAX_NDIM) { PyErr_SetString(PyExc_ValueError, "memoryview: number of dimensions must not exceed " - STRINGIZE(PyBUF_MAX_NDIM)); + Py_STRINGIFY(PyBUF_MAX_NDIM)); return NULL; } @@ -795,7 +792,7 @@ PyMemoryView_FromObject(PyObject *v) } PyErr_Format(PyExc_TypeError, - "memoryview: %.200s object does not have the buffer interface", + "memoryview: a bytes-like object is required, not '%.200s'", Py_TYPE(v)->tp_name); return NULL; } @@ -1135,6 +1132,51 @@ get_native_fmtchar(char *result, const char *fmt) return -1; } +Py_LOCAL_INLINE(char *) +get_native_fmtstr(const char *fmt) +{ + int at = 0; + + if (fmt[0] == '@') { + at = 1; + fmt++; + } + if (fmt[0] == '\0' || fmt[1] != '\0') { + return NULL; + } + +#define RETURN(s) do { return at ? "@" s : s; } while (0) + + switch (fmt[0]) { + case 'c': RETURN("c"); + case 'b': RETURN("b"); + case 'B': RETURN("B"); + case 'h': RETURN("h"); + case 'H': RETURN("H"); + case 'i': RETURN("i"); + case 'I': RETURN("I"); + case 'l': RETURN("l"); + case 'L': RETURN("L"); + #ifdef HAVE_LONG_LONG + case 'q': RETURN("q"); + case 'Q': RETURN("Q"); + #endif + case 'n': RETURN("n"); + case 'N': RETURN("N"); + case 'f': RETURN("f"); + case 'd': RETURN("d"); + #ifdef HAVE_C99_BOOL + case '?': RETURN("?"); + #else + case '?': RETURN("?"); + #endif + case 'P': RETURN("P"); + } + + return NULL; +} + + /* Cast a memoryview's data type to 'format'. The input array must be C-contiguous. At least one of input-format, output-format must have byte size. The output array is 1-D, with the same byte length as the @@ -1184,10 +1226,13 @@ cast_to_1D(PyMemoryViewObject *mv, PyObject *format) goto out; } - strncpy(mv->format, PyBytes_AS_STRING(asciifmt), - _Py_MEMORYVIEW_MAX_FORMAT); - mv->format[_Py_MEMORYVIEW_MAX_FORMAT-1] = '\0'; - view->format = mv->format; + view->format = get_native_fmtstr(PyBytes_AS_STRING(asciifmt)); + if (view->format == NULL) { + /* NOT_REACHED: get_native_fmtchar() already validates the format. */ + PyErr_SetString(PyExc_RuntimeError, + "memoryview: internal error"); + goto out; + } view->itemsize = itemsize; view->ndim = 1; @@ -1341,7 +1386,7 @@ memory_cast(PyMemoryViewObject *self, PyObject *args, PyObject *kwds) if (ndim > PyBUF_MAX_NDIM) { PyErr_SetString(PyExc_ValueError, "memoryview: number of dimensions must not exceed " - STRINGIZE(PyBUF_MAX_NDIM)); + Py_STRINGIFY(PyBUF_MAX_NDIM)); return NULL; } if (self->view.ndim != 1 && ndim != 1) { @@ -2900,6 +2945,7 @@ PyDoc_STRVAR(memory_f_contiguous_doc, PyDoc_STRVAR(memory_contiguous_doc, "A bool indicating whether the memory is contiguous."); + static PyGetSetDef memory_getsetlist[] = { {"obj", (getter)memory_obj_get, NULL, memory_obj_doc}, {"nbytes", (getter)memory_nbytes_get, NULL, memory_nbytes_doc}, @@ -2917,19 +2963,19 @@ static PyGetSetDef memory_getsetlist[] = { }; PyDoc_STRVAR(memory_release_doc, -"M.release() -> None\n\ +"release($self, /)\n--\n\ \n\ Release the underlying buffer exposed by the memoryview object."); PyDoc_STRVAR(memory_tobytes_doc, -"M.tobytes() -> bytes\n\ +"tobytes($self, /)\n--\n\ \n\ Return the data in the buffer as a byte string."); PyDoc_STRVAR(memory_tolist_doc, -"M.tolist() -> list\n\ +"tolist($self, /)\n--\n\ \n\ Return the data in the buffer as a list of elements."); PyDoc_STRVAR(memory_cast_doc, -"M.cast(format[, shape]) -> memoryview\n\ +"cast($self, /, format, *, shape)\n--\n\ \n\ Cast a memoryview to a new format or shape."); diff --git a/Objects/methodobject.c b/Objects/methodobject.c index 55a7d6a35eaf..686baf9ece76 100644 --- a/Objects/methodobject.c +++ b/Objects/methodobject.c @@ -29,7 +29,7 @@ PyCFunction_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module) op = free_list; if (op != NULL) { free_list = (PyCFunctionObject *)(op->m_self); - PyObject_INIT(op, &PyCFunction_Type); + (void)PyObject_INIT(op, &PyCFunction_Type); numfree--; } else { @@ -37,6 +37,7 @@ PyCFunction_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module) if (op == NULL) return NULL; } + op->m_weakreflist = NULL; op->m_ml = ml; Py_XINCREF(self); op->m_self = self; @@ -147,6 +148,9 @@ static void meth_dealloc(PyCFunctionObject *m) { _PyObject_GC_UNTRACK(m); + if (m->m_weakreflist != NULL) { + PyObject_ClearWeakRefs((PyObject*) m); + } Py_XDECREF(m->m_self); Py_XDECREF(m->m_module); if (numfree < PyCFunction_MAXFREELIST) { @@ -179,75 +183,16 @@ static PyMethodDef meth_methods[] = { {NULL, NULL} }; -/* - * finds the docstring's introspection signature. - * if present, returns a pointer pointing to the first '('. - * otherwise returns NULL. - */ -static const char *find_signature(PyCFunctionObject *m) -{ - const char *trace = m->m_ml->ml_doc; - const char *name = m->m_ml->ml_name; - size_t length; - if (!trace || !name) - return NULL; - length = strlen(name); - if (strncmp(trace, name, length)) - return NULL; - trace += length; - if (*trace != '(') - return NULL; - return trace; -} - -/* - * skips to the end of the docstring's instrospection signature. - */ -static const char *skip_signature(const char *trace) -{ - while (*trace && *trace != '\n') - trace++; - return trace; -} - -static const char *skip_eols(const char *trace) -{ - while (*trace == '\n') - trace++; - return trace; -} - static PyObject * meth_get__text_signature__(PyCFunctionObject *m, void *closure) { - const char *start = find_signature(m); - const char *trace; - - if (!start) { - Py_INCREF(Py_None); - return Py_None; - } - - trace = skip_signature(start); - return PyUnicode_FromStringAndSize(start, trace - start); + return _PyType_GetTextSignatureFromInternalDoc(m->m_ml->ml_name, m->m_ml->ml_doc); } static PyObject * meth_get__doc__(PyCFunctionObject *m, void *closure) { - const char *doc = find_signature(m); - - if (doc) - doc = skip_eols(skip_signature(doc)); - else - doc = m->m_ml->ml_doc; - - if (!doc) { - Py_INCREF(Py_None); - return Py_None; - } - - return PyUnicode_FromString(doc); + return _PyType_GetDocFromInternalDoc(m->m_ml->ml_name, m->m_ml->ml_doc); } static PyObject * @@ -411,7 +356,7 @@ PyTypeObject PyCFunction_Type = { (traverseproc)meth_traverse, /* tp_traverse */ 0, /* tp_clear */ meth_richcompare, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ + offsetof(PyCFunctionObject, m_weakreflist), /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ meth_methods, /* tp_methods */ diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c index d59475e2f3c3..441e73111b77 100644 --- a/Objects/moduleobject.c +++ b/Objects/moduleobject.c @@ -32,20 +32,26 @@ static int module_init_dict(PyModuleObject *mod, PyObject *md_dict, PyObject *name, PyObject *doc) { + _Py_IDENTIFIER(__name__); + _Py_IDENTIFIER(__doc__); + _Py_IDENTIFIER(__package__); + _Py_IDENTIFIER(__loader__); + _Py_IDENTIFIER(__spec__); + if (md_dict == NULL) return -1; if (doc == NULL) doc = Py_None; - if (PyDict_SetItemString(md_dict, "__name__", name) != 0) + if (_PyDict_SetItemId(md_dict, &PyId___name__, name) != 0) return -1; - if (PyDict_SetItemString(md_dict, "__doc__", doc) != 0) + if (_PyDict_SetItemId(md_dict, &PyId___doc__, doc) != 0) return -1; - if (PyDict_SetItemString(md_dict, "__package__", Py_None) != 0) + if (_PyDict_SetItemId(md_dict, &PyId___package__, Py_None) != 0) return -1; - if (PyDict_SetItemString(md_dict, "__loader__", Py_None) != 0) + if (_PyDict_SetItemId(md_dict, &PyId___loader__, Py_None) != 0) return -1; - if (PyDict_SetItemString(md_dict, "__spec__", Py_None) != 0) + if (_PyDict_SetItemId(md_dict, &PyId___spec__, Py_None) != 0) return -1; if (PyUnicode_CheckExact(name)) { Py_INCREF(name); @@ -184,8 +190,9 @@ PyModule_Create2(struct PyModuleDef* module, int module_api_version) Py_DECREF(n); } if (module->m_doc != NULL) { + _Py_IDENTIFIER(__doc__); v = PyUnicode_FromString(module->m_doc); - if (v == NULL || PyDict_SetItemString(d, "__doc__", v) != 0) { + if (v == NULL || _PyDict_SetItemId(d, &PyId___doc__, v) != 0) { Py_XDECREF(v); Py_DECREF(m); return NULL; @@ -214,6 +221,7 @@ PyModule_GetDict(PyObject *m) PyObject* PyModule_GetNameObject(PyObject *m) { + _Py_IDENTIFIER(__name__); PyObject *d; PyObject *name; if (!PyModule_Check(m)) { @@ -222,7 +230,7 @@ PyModule_GetNameObject(PyObject *m) } d = ((PyModuleObject *)m)->md_dict; if (d == NULL || - (name = PyDict_GetItemString(d, "__name__")) == NULL || + (name = _PyDict_GetItemId(d, &PyId___name__)) == NULL || !PyUnicode_Check(name)) { PyErr_SetString(PyExc_SystemError, "nameless module"); @@ -245,6 +253,7 @@ PyModule_GetName(PyObject *m) PyObject* PyModule_GetFilenameObject(PyObject *m) { + _Py_IDENTIFIER(__file__); PyObject *d; PyObject *fileobj; if (!PyModule_Check(m)) { @@ -253,7 +262,7 @@ PyModule_GetFilenameObject(PyObject *m) } d = ((PyModuleObject *)m)->md_dict; if (d == NULL || - (fileobj = PyDict_GetItemString(d, "__file__")) == NULL || + (fileobj = _PyDict_GetItemId(d, &PyId___file__)) == NULL || !PyUnicode_Check(fileobj)) { PyErr_SetString(PyExc_SystemError, "module filename missing"); @@ -298,6 +307,14 @@ PyModule_GetState(PyObject* m) void _PyModule_Clear(PyObject *m) +{ + PyObject *d = ((PyModuleObject *)m)->md_dict; + if (d != NULL) + _PyModule_ClearDict(d); +} + +void +_PyModule_ClearDict(PyObject *d) { /* To make the execution order of destructors for global objects a bit more predictable, we first zap all objects @@ -308,11 +325,6 @@ _PyModule_Clear(PyObject *m) Py_ssize_t pos; PyObject *key, *value; - PyObject *d; - - d = ((PyModuleObject *)m)->md_dict; - if (d == NULL) - return; /* First, clear only names starting with a single underscore */ pos = 0; @@ -327,7 +339,8 @@ _PyModule_Clear(PyObject *m) else PyErr_Clear(); } - PyDict_SetItem(d, key, Py_None); + if (PyDict_SetItem(d, key, Py_None) != 0) + PyErr_Clear(); } } } @@ -346,7 +359,8 @@ _PyModule_Clear(PyObject *m) else PyErr_Clear(); } - PyDict_SetItem(d, key, Py_None); + if (PyDict_SetItem(d, key, Py_None) != 0) + PyErr_Clear(); } } } @@ -406,6 +420,31 @@ module_repr(PyModuleObject *m) return PyObject_CallMethod(interp->importlib, "_module_repr", "O", m); } +static PyObject* +module_getattro(PyModuleObject *m, PyObject *name) +{ + PyObject *attr, *mod_name; + attr = PyObject_GenericGetAttr((PyObject *)m, name); + if (attr || !PyErr_ExceptionMatches(PyExc_AttributeError)) + return attr; + PyErr_Clear(); + if (m->md_dict) { + _Py_IDENTIFIER(__name__); + mod_name = _PyDict_GetItemId(m->md_dict, &PyId___name__); + if (mod_name) { + PyErr_Format(PyExc_AttributeError, + "module '%U' has no attribute '%U'", mod_name, name); + return NULL; + } + else if (PyErr_Occurred()) { + PyErr_Clear(); + } + } + PyErr_Format(PyExc_AttributeError, + "module has no attribute '%U'", name); + return NULL; +} + static int module_traverse(PyModuleObject *m, visitproc visit, void *arg) { @@ -459,7 +498,6 @@ static PyMethodDef module_methods[] = { {0} }; - PyDoc_STRVAR(module_doc, "module(name[, doc])\n\ \n\ @@ -483,7 +521,7 @@ PyTypeObject PyModule_Type = { 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ + (getattrofunc)module_getattro, /* tp_getattro */ PyObject_GenericSetAttr, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | diff --git a/Objects/object.c b/Objects/object.c index 62bdb49d1366..42cbbcd33fa7 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -33,6 +33,22 @@ _Py_GetRefTotal(void) total -= o->ob_refcnt; return total; } + +void +_PyDebug_PrintTotalRefs(void) { + PyObject *xoptions, *value; + _Py_IDENTIFIER(showrefcount); + + xoptions = PySys_GetXOptions(); + if (xoptions == NULL) + return; + value = _PyDict_GetItemId(xoptions, &PyId_showrefcount); + if (value == Py_True) + fprintf(stderr, + "[%" PY_FORMAT_SIZE_T "d refs, " + "%" PY_FORMAT_SIZE_T "d blocks]\n", + _Py_GetRefTotal(), _Py_GetAllocatedBlocks()); +} #endif /* Py_REF_DEBUG */ /* Object allocation routines used by NEWOBJ and NEWVAROBJ macros. @@ -508,7 +524,7 @@ PyObject_Str(PyObject *v) #ifdef Py_DEBUG /* PyObject_Str() must not be called with an exception set, because it may clear it (directly or indirectly) and so the - caller looses its exception */ + caller loses its exception */ assert(!PyErr_Occurred()); #endif @@ -1543,6 +1559,9 @@ PyObject _Py_NotImplementedStruct = { void _Py_ReadyTypes(void) { + if (PyType_Ready(&PyBaseObject_Type) < 0) + Py_FatalError("Can't initialize object type"); + if (PyType_Ready(&PyType_Type) < 0) Py_FatalError("Can't initialize type type"); @@ -1555,6 +1574,9 @@ _Py_ReadyTypes(void) if (PyType_Ready(&_PyWeakref_ProxyType) < 0) Py_FatalError("Can't initialize weakref proxy type"); + if (PyType_Ready(&PyLong_Type) < 0) + Py_FatalError("Can't initialize int type"); + if (PyType_Ready(&PyBool_Type) < 0) Py_FatalError("Can't initialize bool type"); @@ -1579,9 +1601,6 @@ _Py_ReadyTypes(void) if (PyType_Ready(&PySuper_Type) < 0) Py_FatalError("Can't initialize super type"); - if (PyType_Ready(&PyBaseObject_Type) < 0) - Py_FatalError("Can't initialize object type"); - if (PyType_Ready(&PyRange_Type) < 0) Py_FatalError("Can't initialize range type"); @@ -1606,9 +1625,6 @@ _Py_ReadyTypes(void) if (PyType_Ready(&PyFloat_Type) < 0) Py_FatalError("Can't initialize float type"); - if (PyType_Ready(&PyLong_Type) < 0) - Py_FatalError("Can't initialize int type"); - if (PyType_Ready(&PyFrozenSet_Type) < 0) Py_FatalError("Can't initialize frozenset type"); @@ -1849,6 +1865,8 @@ Py_ReprEnter(PyObject *obj) Py_ssize_t i; dict = PyThreadState_GetDict(); + /* Ignore a missing thread-state, so that this function can be called + early on startup. */ if (dict == NULL) return 0; list = _PyDict_GetItemId(dict, &PyId_Py_Repr); diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c index 004cfaac6174..7cc889f817b6 100644 --- a/Objects/obmalloc.c +++ b/Objects/obmalloc.c @@ -5,6 +5,7 @@ #ifdef PYMALLOC_DEBUG /* WITH_PYMALLOC && PYMALLOC_DEBUG */ /* Forward declaration */ static void* _PyMem_DebugMalloc(void *ctx, size_t size); +static void* _PyMem_DebugCalloc(void *ctx, size_t nelem, size_t elsize); static void _PyMem_DebugFree(void *ctx, void *p); static void* _PyMem_DebugRealloc(void *ctx, void *ptr, size_t size); @@ -43,6 +44,7 @@ static void _PyMem_DebugCheckAddress(char api_id, const void *p); /* Forward declaration */ static void* _PyObject_Malloc(void *ctx, size_t size); +static void* _PyObject_Calloc(void *ctx, size_t nelem, size_t elsize); static void _PyObject_Free(void *ctx, void *p); static void* _PyObject_Realloc(void *ctx, void *ptr, size_t size); #endif @@ -51,7 +53,7 @@ static void* _PyObject_Realloc(void *ctx, void *ptr, size_t size); static void * _PyMem_RawMalloc(void *ctx, size_t size) { - /* PyMem_Malloc(0) means malloc(1). Some systems would return NULL + /* PyMem_RawMalloc(0) means malloc(1). Some systems would return NULL for malloc(0), which would be treated as an error. Some platforms would return a pointer with no memory behind it, which would break pymalloc. To solve these problems, allocate an extra byte. */ @@ -60,6 +62,20 @@ _PyMem_RawMalloc(void *ctx, size_t size) return malloc(size); } +static void * +_PyMem_RawCalloc(void *ctx, size_t nelem, size_t elsize) +{ + /* PyMem_RawCalloc(0, 0) means calloc(1, 1). Some systems would return NULL + for calloc(0, 0), which would be treated as an error. Some platforms + would return a pointer with no memory behind it, which would break + pymalloc. To solve these problems, allocate an extra byte. */ + if (nelem == 0 || elsize == 0) { + nelem = 1; + elsize = 1; + } + return calloc(nelem, elsize); +} + static void * _PyMem_RawRealloc(void *ctx, void *ptr, size_t size) { @@ -123,9 +139,9 @@ _PyObject_ArenaFree(void *ctx, void *ptr, size_t size) #endif -#define PYRAW_FUNCS _PyMem_RawMalloc, _PyMem_RawRealloc, _PyMem_RawFree +#define PYRAW_FUNCS _PyMem_RawMalloc, _PyMem_RawCalloc, _PyMem_RawRealloc, _PyMem_RawFree #ifdef WITH_PYMALLOC -# define PYOBJ_FUNCS _PyObject_Malloc, _PyObject_Realloc, _PyObject_Free +# define PYOBJ_FUNCS _PyObject_Malloc, _PyObject_Calloc, _PyObject_Realloc, _PyObject_Free #else # define PYOBJ_FUNCS PYRAW_FUNCS #endif @@ -135,7 +151,7 @@ _PyObject_ArenaFree(void *ctx, void *ptr, size_t size) typedef struct { /* We tag each block with an API ID in order to tag API violations */ char api_id; - PyMemAllocator alloc; + PyMemAllocatorEx alloc; } debug_alloc_api_t; static struct { debug_alloc_api_t raw; @@ -147,10 +163,10 @@ static struct { {'o', {NULL, PYOBJ_FUNCS}} }; -#define PYDBG_FUNCS _PyMem_DebugMalloc, _PyMem_DebugRealloc, _PyMem_DebugFree +#define PYDBG_FUNCS _PyMem_DebugMalloc, _PyMem_DebugCalloc, _PyMem_DebugRealloc, _PyMem_DebugFree #endif -static PyMemAllocator _PyMem_Raw = { +static PyMemAllocatorEx _PyMem_Raw = { #ifdef PYMALLOC_DEBUG &_PyMem_Debug.raw, PYDBG_FUNCS #else @@ -158,7 +174,7 @@ static PyMemAllocator _PyMem_Raw = { #endif }; -static PyMemAllocator _PyMem = { +static PyMemAllocatorEx _PyMem = { #ifdef PYMALLOC_DEBUG &_PyMem_Debug.mem, PYDBG_FUNCS #else @@ -166,7 +182,7 @@ static PyMemAllocator _PyMem = { #endif }; -static PyMemAllocator _PyObject = { +static PyMemAllocatorEx _PyObject = { #ifdef PYMALLOC_DEBUG &_PyMem_Debug.obj, PYDBG_FUNCS #else @@ -193,9 +209,10 @@ void PyMem_SetupDebugHooks(void) { #ifdef PYMALLOC_DEBUG - PyMemAllocator alloc; + PyMemAllocatorEx alloc; alloc.malloc = _PyMem_DebugMalloc; + alloc.calloc = _PyMem_DebugCalloc; alloc.realloc = _PyMem_DebugRealloc; alloc.free = _PyMem_DebugFree; @@ -220,7 +237,7 @@ PyMem_SetupDebugHooks(void) } void -PyMem_GetAllocator(PyMemAllocatorDomain domain, PyMemAllocator *allocator) +PyMem_GetAllocator(PyMemAllocatorDomain domain, PyMemAllocatorEx *allocator) { switch(domain) { @@ -228,16 +245,17 @@ PyMem_GetAllocator(PyMemAllocatorDomain domain, PyMemAllocator *allocator) case PYMEM_DOMAIN_MEM: *allocator = _PyMem; break; case PYMEM_DOMAIN_OBJ: *allocator = _PyObject; break; default: - /* unknown domain */ + /* unknown domain: set all attributes to NULL */ allocator->ctx = NULL; allocator->malloc = NULL; + allocator->calloc = NULL; allocator->realloc = NULL; allocator->free = NULL; } } void -PyMem_SetAllocator(PyMemAllocatorDomain domain, PyMemAllocator *allocator) +PyMem_SetAllocator(PyMemAllocatorDomain domain, PyMemAllocatorEx *allocator) { switch(domain) { @@ -272,10 +290,18 @@ PyMem_RawMalloc(size_t size) */ if (size > (size_t)PY_SSIZE_T_MAX) return NULL; - return _PyMem_Raw.malloc(_PyMem_Raw.ctx, size); } +void * +PyMem_RawCalloc(size_t nelem, size_t elsize) +{ + /* see PyMem_RawMalloc() */ + if (elsize != 0 && nelem > (size_t)PY_SSIZE_T_MAX / elsize) + return NULL; + return _PyMem_Raw.calloc(_PyMem_Raw.ctx, nelem, elsize); +} + void* PyMem_RawRealloc(void *ptr, size_t new_size) { @@ -299,6 +325,15 @@ PyMem_Malloc(size_t size) return _PyMem.malloc(_PyMem.ctx, size); } +void * +PyMem_Calloc(size_t nelem, size_t elsize) +{ + /* see PyMem_RawMalloc() */ + if (elsize != 0 && nelem > (size_t)PY_SSIZE_T_MAX / elsize) + return NULL; + return _PyMem.calloc(_PyMem.ctx, nelem, elsize); +} + void * PyMem_Realloc(void *ptr, size_t new_size) { @@ -351,6 +386,15 @@ PyObject_Malloc(size_t size) return _PyObject.malloc(_PyObject.ctx, size); } +void * +PyObject_Calloc(size_t nelem, size_t elsize) +{ + /* see PyMem_RawMalloc() */ + if (elsize != 0 && nelem > (size_t)PY_SSIZE_T_MAX / elsize) + return NULL; + return _PyObject.calloc(_PyObject.ctx, nelem, elsize); +} + void * PyObject_Realloc(void *ptr, size_t new_size) { @@ -1122,8 +1166,9 @@ int Py_ADDRESS_IN_RANGE(void *P, poolp pool) Py_NO_INLINE; */ static void * -_PyObject_Malloc(void *ctx, size_t nbytes) +_PyObject_Alloc(int use_calloc, void *ctx, size_t nelem, size_t elsize) { + size_t nbytes; block *bp; poolp pool; poolp next; @@ -1131,6 +1176,9 @@ _PyObject_Malloc(void *ctx, size_t nbytes) _Py_AllocatedBlocks++; + assert(nelem <= PY_SSIZE_T_MAX / elsize); + nbytes = nelem * elsize; + #ifdef WITH_VALGRIND if (UNLIKELY(running_on_valgrind == -1)) running_on_valgrind = RUNNING_ON_VALGRIND; @@ -1138,9 +1186,9 @@ _PyObject_Malloc(void *ctx, size_t nbytes) goto redirect; #endif - /* - * This implicitly redirects malloc(0). - */ + if (nelem == 0 || elsize == 0) + goto redirect; + if ((nbytes - 1) < SMALL_REQUEST_THRESHOLD) { LOCK(); /* @@ -1158,6 +1206,8 @@ _PyObject_Malloc(void *ctx, size_t nbytes) assert(bp != NULL); if ((pool->freeblock = *(block **)bp) != NULL) { UNLOCK(); + if (use_calloc) + memset(bp, 0, nbytes); return (void *)bp; } /* @@ -1170,6 +1220,8 @@ _PyObject_Malloc(void *ctx, size_t nbytes) pool->nextoffset += INDEX2SIZE(size); *(block **)(pool->freeblock) = NULL; UNLOCK(); + if (use_calloc) + memset(bp, 0, nbytes); return (void *)bp; } /* Pool is full, unlink from used pools. */ @@ -1178,6 +1230,8 @@ _PyObject_Malloc(void *ctx, size_t nbytes) next->prevpool = pool; pool->nextpool = next; UNLOCK(); + if (use_calloc) + memset(bp, 0, nbytes); return (void *)bp; } @@ -1257,6 +1311,8 @@ _PyObject_Malloc(void *ctx, size_t nbytes) assert(bp != NULL); pool->freeblock = *(block **)bp; UNLOCK(); + if (use_calloc) + memset(bp, 0, nbytes); return (void *)bp; } /* @@ -1272,6 +1328,8 @@ _PyObject_Malloc(void *ctx, size_t nbytes) pool->freeblock = bp + size; *(block **)(pool->freeblock) = NULL; UNLOCK(); + if (use_calloc) + memset(bp, 0, nbytes); return (void *)bp; } @@ -1281,7 +1339,7 @@ _PyObject_Malloc(void *ctx, size_t nbytes) pool = (poolp)usable_arenas->pool_address; assert((block*)pool <= (block*)usable_arenas->address + ARENA_SIZE - POOL_SIZE); - pool->arenaindex = usable_arenas - arenas; + pool->arenaindex = (uint)(usable_arenas - arenas); assert(&arenas[pool->arenaindex] == usable_arenas); pool->szidx = DUMMY_SIZE_IDX; usable_arenas->pool_address += POOL_SIZE; @@ -1311,13 +1369,29 @@ _PyObject_Malloc(void *ctx, size_t nbytes) * has been reached. */ { - void *result = PyMem_RawMalloc(nbytes); + void *result; + if (use_calloc) + result = PyMem_RawCalloc(nelem, elsize); + else + result = PyMem_RawMalloc(nbytes); if (!result) _Py_AllocatedBlocks--; return result; } } +static void * +_PyObject_Malloc(void *ctx, size_t nbytes) +{ + return _PyObject_Alloc(0, ctx, 1, nbytes); +} + +static void * +_PyObject_Calloc(void *ctx, size_t nelem, size_t elsize) +{ + return _PyObject_Alloc(1, ctx, nelem, elsize); +} + /* free */ ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS @@ -1561,7 +1635,7 @@ _PyObject_Realloc(void *ctx, void *p, size_t nbytes) #endif if (p == NULL) - return _PyObject_Malloc(ctx, nbytes); + return _PyObject_Alloc(0, ctx, 1, nbytes); #ifdef WITH_VALGRIND /* Treat running_on_valgrind == -1 the same as 0 */ @@ -1589,7 +1663,7 @@ _PyObject_Realloc(void *ctx, void *p, size_t nbytes) } size = nbytes; } - bp = _PyObject_Malloc(ctx, nbytes); + bp = _PyObject_Alloc(0, ctx, 1, nbytes); if (bp != NULL) { memcpy(bp, p, size); _PyObject_Free(ctx, p); @@ -1745,7 +1819,7 @@ p[2*S+n+S: 2*S+n+2*S] */ static void * -_PyMem_DebugMalloc(void *ctx, size_t nbytes) +_PyMem_DebugAlloc(int use_calloc, void *ctx, size_t nbytes) { debug_alloc_api_t *api = (debug_alloc_api_t *)ctx; uchar *p; /* base address of malloc'ed block */ @@ -1754,11 +1828,14 @@ _PyMem_DebugMalloc(void *ctx, size_t nbytes) bumpserialno(); total = nbytes + 4*SST; - if (total < nbytes) - /* overflow: can't represent total as a size_t */ + if (nbytes > PY_SSIZE_T_MAX - 4*SST) + /* overflow: can't represent total as a Py_ssize_t */ return NULL; - p = (uchar *)api->alloc.malloc(api->alloc.ctx, total); + if (use_calloc) + p = (uchar *)api->alloc.calloc(api->alloc.ctx, 1, total); + else + p = (uchar *)api->alloc.malloc(api->alloc.ctx, total); if (p == NULL) return NULL; @@ -1767,7 +1844,7 @@ _PyMem_DebugMalloc(void *ctx, size_t nbytes) p[SST] = (uchar)api->api_id; memset(p + SST + 1, FORBIDDENBYTE, SST-1); - if (nbytes > 0) + if (nbytes > 0 && !use_calloc) memset(p + 2*SST, CLEANBYTE, nbytes); /* at tail, write pad (SST bytes) and serialno (SST bytes) */ @@ -1778,6 +1855,21 @@ _PyMem_DebugMalloc(void *ctx, size_t nbytes) return p + 2*SST; } +static void * +_PyMem_DebugMalloc(void *ctx, size_t nbytes) +{ + return _PyMem_DebugAlloc(0, ctx, nbytes); +} + +static void * +_PyMem_DebugCalloc(void *ctx, size_t nelem, size_t elsize) +{ + size_t nbytes; + assert(elsize == 0 || nelem <= PY_SSIZE_T_MAX / elsize); + nbytes = nelem * elsize; + return _PyMem_DebugAlloc(1, ctx, nbytes); +} + /* The debug free first checks the 2*SST bytes on each end for sanity (in particular, that the FORBIDDENBYTEs with the api ID are still intact). Then fills the original bytes with DEADBYTE. @@ -1811,14 +1903,14 @@ _PyMem_DebugRealloc(void *ctx, void *p, size_t nbytes) int i; if (p == NULL) - return _PyMem_DebugMalloc(ctx, nbytes); + return _PyMem_DebugAlloc(0, ctx, nbytes); _PyMem_DebugCheckAddress(api->api_id, p); bumpserialno(); original_nbytes = read_size_t(q - 2*SST); total = nbytes + 4*SST; - if (total < nbytes) - /* overflow: can't represent total as a size_t */ + if (nbytes > PY_SSIZE_T_MAX - 4*SST) + /* overflow: can't represent total as a Py_ssize_t */ return NULL; /* Resize and add decorations. We may get a new pointer here, in which diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c index a4d9fb3244ea..7e6c733f3e28 100644 --- a/Objects/rangeobject.c +++ b/Objects/rangeobject.c @@ -139,7 +139,7 @@ PyDoc_STRVAR(range_doc, "range(stop) -> range object\n\ range(start, stop[, step]) -> range object\n\ \n\ -Return a virtual sequence of numbers from start to stop by step."); +Return a sequence of numbers from start to stop by step."); static void range_dealloc(rangeobject *r) @@ -807,10 +807,11 @@ rangeiter_setstate(rangeiterobject *r, PyObject *state) long index = PyLong_AsLong(state); if (index == -1 && PyErr_Occurred()) return NULL; - if (index < 0 || index >= r->len) { - PyErr_SetString(PyExc_ValueError, "index out of range"); - return NULL; - } + /* silently clip the index value */ + if (index < 0) + index = 0; + else if (index > r->len) + index = r->len; /* exhausted iterator */ r->index = index; Py_RETURN_NONE; } @@ -985,6 +986,28 @@ longrangeiter_reduce(longrangeiterobject *r) static PyObject * longrangeiter_setstate(longrangeiterobject *r, PyObject *state) { + int cmp; + + /* clip the value */ + PyObject *zero = PyLong_FromLong(0); + if (zero == NULL) + return NULL; + cmp = PyObject_RichCompareBool(state, zero, Py_LT); + if (cmp > 0) { + Py_CLEAR(r->index); + r->index = zero; + Py_RETURN_NONE; + } + Py_DECREF(zero); + if (cmp < 0) + return NULL; + + cmp = PyObject_RichCompareBool(r->len, state, Py_LT); + if (cmp < 0) + return NULL; + if (cmp > 0) + state = r->len; + Py_CLEAR(r->index); r->index = state; Py_INCREF(r->index); diff --git a/Objects/setobject.c b/Objects/setobject.c index adc99da62765..8197cd914ade 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -4,7 +4,7 @@ Written and maintained by Raymond D. Hettinger Derived from Lib/sets.py and Objects/dictobject.c. - Copyright (c) 2003-2013 Python Software Foundation. + Copyright (c) 2003-2015 Python Software Foundation. All rights reserved. The basic lookup function used by all operations. @@ -23,7 +23,7 @@ All arithmetic on hash should ignore overflow. - Unlike the dictionary implementation, the lookkey functions can return + Unlike the dictionary implementation, the lookkey function can return NULL if the rich comparison returns an error. */ @@ -36,9 +36,6 @@ static PyObject _dummy_struct; #define dummy (&_dummy_struct) -/* Exported for the gdb plugin's benefit. */ -PyObject *_PySet_Dummy = dummy; - /* ======================================================================== */ /* ======= Begin logic for probing the hash table ========================= */ @@ -59,120 +56,73 @@ set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash) setentry *entry; size_t perturb = hash; size_t mask = so->mask; - size_t i = (size_t)hash; /* Unsigned for defined overflow behavior. */ + size_t i = (size_t)hash & mask; /* Unsigned for defined overflow behavior */ size_t j; int cmp; - entry = &table[i & mask]; + entry = &table[i]; if (entry->key == NULL) return entry; while (1) { - if (entry->key == key) - return entry; - if (entry->hash == hash && entry->key != dummy) { + if (entry->hash == hash) { PyObject *startkey = entry->key; + /* startkey cannot be a dummy because the dummy hash field is -1 */ + assert(startkey != dummy); + if (startkey == key) + return entry; + if (PyUnicode_CheckExact(startkey) + && PyUnicode_CheckExact(key) + && unicode_eq(startkey, key)) + return entry; Py_INCREF(startkey); cmp = PyObject_RichCompareBool(startkey, key, Py_EQ); Py_DECREF(startkey); - if (cmp < 0) + if (cmp < 0) /* unlikely */ return NULL; - if (table != so->table || entry->key != startkey) + if (table != so->table || entry->key != startkey) /* unlikely */ return set_lookkey(so, key, hash); - if (cmp > 0) + if (cmp > 0) /* likely */ return entry; + mask = so->mask; /* help avoid a register spill */ } - if (entry->key == dummy && freeslot == NULL) + if (entry->hash == -1 && freeslot == NULL) freeslot = entry; - for (j = 1 ; j <= LINEAR_PROBES ; j++) { - entry = &table[(i + j) & mask]; - if (entry->key == NULL) - goto found_null; - if (entry->key == key) - return entry; - if (entry->hash == hash && entry->key != dummy) { - PyObject *startkey = entry->key; - Py_INCREF(startkey); - cmp = PyObject_RichCompareBool(startkey, key, Py_EQ); - Py_DECREF(startkey); - if (cmp < 0) - return NULL; - if (table != so->table || entry->key != startkey) - return set_lookkey(so, key, hash); - if (cmp > 0) - return entry; + if (i + LINEAR_PROBES <= mask) { + for (j = 0 ; j < LINEAR_PROBES ; j++) { + entry++; + if (entry->key == NULL) + goto found_null; + if (entry->hash == hash) { + PyObject *startkey = entry->key; + assert(startkey != dummy); + if (startkey == key) + return entry; + if (PyUnicode_CheckExact(startkey) + && PyUnicode_CheckExact(key) + && unicode_eq(startkey, key)) + return entry; + Py_INCREF(startkey); + cmp = PyObject_RichCompareBool(startkey, key, Py_EQ); + Py_DECREF(startkey); + if (cmp < 0) + return NULL; + if (table != so->table || entry->key != startkey) + return set_lookkey(so, key, hash); + if (cmp > 0) + return entry; + mask = so->mask; + } + if (entry->hash == -1 && freeslot == NULL) + freeslot = entry; } - if (entry->key == dummy && freeslot == NULL) - freeslot = entry; } perturb >>= PERTURB_SHIFT; - i = i * 5 + 1 + perturb; + i = (i * 5 + 1 + perturb) & mask; - entry = &table[i & mask]; - if (entry->key == NULL) - goto found_null; - } - found_null: - return freeslot == NULL ? entry : freeslot; -} - -/* - * Hacked up version of set_lookkey which can assume keys are always unicode; - * This means we can always use unicode_eq directly and not have to check to - * see if the comparison altered the table. - */ -static setentry * -set_lookkey_unicode(PySetObject *so, PyObject *key, Py_hash_t hash) -{ - setentry *table = so->table; - setentry *freeslot = NULL; - setentry *entry; - size_t perturb = hash; - size_t mask = so->mask; - size_t i = (size_t)hash; - size_t j; - - /* Make sure this function doesn't have to handle non-unicode keys, - including subclasses of str; e.g., one reason to subclass - strings is to override __eq__, and for speed we don't cater to - that here. */ - if (!PyUnicode_CheckExact(key)) { - so->lookup = set_lookkey; - return set_lookkey(so, key, hash); - } - - entry = &table[i & mask]; - if (entry->key == NULL) - return entry; - - while (1) { - if (entry->key == key - || (entry->hash == hash - && entry->key != dummy - && unicode_eq(entry->key, key))) - return entry; - if (entry->key == dummy && freeslot == NULL) - freeslot = entry; - - for (j = 1 ; j <= LINEAR_PROBES ; j++) { - entry = &table[(i + j) & mask]; - if (entry->key == NULL) - goto found_null; - if (entry->key == key - || (entry->hash == hash - && entry->key != dummy - && unicode_eq(entry->key, key))) - return entry; - if (entry->key == dummy && freeslot == NULL) - freeslot = entry; - } - - perturb >>= PERTURB_SHIFT; - i = i * 5 + 1 + perturb; - - entry = &table[i & mask]; + entry = &table[i]; if (entry->key == NULL) goto found_null; } @@ -195,20 +145,22 @@ set_insert_clean(PySetObject *so, PyObject *key, Py_hash_t hash) setentry *entry; size_t perturb = hash; size_t mask = (size_t)so->mask; - size_t i = (size_t)hash; + size_t i = (size_t)hash & mask; size_t j; while (1) { - entry = &table[i & mask]; + entry = &table[i]; if (entry->key == NULL) goto found_null; - for (j = 1 ; j <= LINEAR_PROBES ; j++) { - entry = &table[(i + j) & mask]; - if (entry->key == NULL) - goto found_null; + if (i + LINEAR_PROBES <= mask) { + for (j = 0; j < LINEAR_PROBES; j++) { + entry++; + if (entry->key == NULL) + goto found_null; + } } perturb >>= PERTURB_SHIFT; - i = i * 5 + 1 + perturb; + i = (i * 5 + 1 + perturb) & mask; } found_null: entry->key = key; @@ -231,15 +183,14 @@ set_insert_key(PySetObject *so, PyObject *key, Py_hash_t hash) { setentry *entry; - assert(so->lookup != NULL); - entry = so->lookup(so, key, hash); + entry = set_lookkey(so, key, hash); if (entry == NULL) return -1; if (entry->key == NULL) { /* UNUSED */ - so->fill++; entry->key = key; entry->hash = hash; + so->fill++; so->used++; } else if (entry->key == dummy) { /* DUMMY */ @@ -263,13 +214,15 @@ set_table_resize(PySetObject *so, Py_ssize_t minused) { Py_ssize_t newsize; setentry *oldtable, *newtable, *entry; - Py_ssize_t i; + Py_ssize_t oldfill = so->fill; + Py_ssize_t oldused = so->used; int is_oldtable_malloced; setentry small_copy[PySet_MINSIZE]; assert(minused >= 0); /* Find the smallest table size > minused. */ + /* XXX speed-up with intrinsics */ for (newsize = PySet_MINSIZE; newsize <= minused && newsize > 0; newsize <<= 1) @@ -313,19 +266,27 @@ set_table_resize(PySetObject *so, Py_ssize_t minused) /* Make the set empty, using the new table. */ assert(newtable != oldtable); - so->table = newtable; - so->mask = newsize - 1; memset(newtable, 0, sizeof(setentry) * newsize); - i = so->used; - so->used = 0; so->fill = 0; + so->used = 0; + so->mask = newsize - 1; + so->table = newtable; /* Copy the data over; this is refcount-neutral for active entries; dummy entries aren't copied over, of course */ - for (entry = oldtable; i > 0; entry++) { - if (entry->key != NULL && entry->key != dummy) { - --i; - set_insert_clean(so, entry->key, entry->hash); + if (oldfill == oldused) { + for (entry = oldtable; oldused > 0; entry++) { + if (entry->key != NULL) { + oldused--; + set_insert_clean(so, entry->key, entry->hash); + } + } + } else { + for (entry = oldtable; oldused > 0; entry++) { + if (entry->key != NULL && entry->key != dummy) { + oldused--; + set_insert_clean(so, entry->key, entry->hash); + } } } @@ -358,8 +319,8 @@ set_add_entry(PySetObject *so, setentry *entry) static int set_add_key(PySetObject *so, PyObject *key) { + setentry entry; Py_hash_t hash; - Py_ssize_t n_used; if (!PyUnicode_CheckExact(key) || (hash = ((PyASCIIObject *) key)->hash) == -1) { @@ -367,16 +328,9 @@ set_add_key(PySetObject *so, PyObject *key) if (hash == -1) return -1; } - assert(so->fill <= so->mask); /* at least one empty slot */ - n_used = so->used; - Py_INCREF(key); - if (set_insert_key(so, key, hash) == -1) { - Py_DECREF(key); - return -1; - } - if (!(so->used > n_used && so->fill*3 >= (so->mask+1)*2)) - return 0; - return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4); + entry.key = key; + entry.hash = hash; + return set_add_entry(so, &entry); } #define DISCARD_NOTFOUND 0 @@ -384,16 +338,18 @@ set_add_key(PySetObject *so, PyObject *key) static int set_discard_entry(PySetObject *so, setentry *oldentry) -{ setentry *entry; +{ + setentry *entry; PyObject *old_key; - entry = (so->lookup)(so, oldentry->key, oldentry->hash); + entry = set_lookkey(so, oldentry->key, oldentry->hash); if (entry == NULL) return -1; if (entry->key == NULL || entry->key == dummy) return DISCARD_NOTFOUND; old_key = entry->key; entry->key = dummy; + entry->hash = -1; so->used--; Py_DECREF(old_key); return DISCARD_FOUND; @@ -402,9 +358,8 @@ set_discard_entry(PySetObject *so, setentry *oldentry) static int set_discard_key(PySetObject *so, PyObject *key) { + setentry entry; Py_hash_t hash; - setentry *entry; - PyObject *old_key; assert (PyAnySet_Check(so)); @@ -414,16 +369,9 @@ set_discard_key(PySetObject *so, PyObject *key) if (hash == -1) return -1; } - entry = (so->lookup)(so, key, hash); - if (entry == NULL) - return -1; - if (entry->key == NULL || entry->key == dummy) - return DISCARD_NOTFOUND; - old_key = entry->key; - entry->key = dummy; - so->used--; - Py_DECREF(old_key); - return DISCARD_FOUND; + entry.key = key; + entry.hash = hash; + return set_discard_entry(so, &entry); } static void @@ -440,20 +388,15 @@ set_empty_to_minsize(PySetObject *so) static int set_clear_internal(PySetObject *so) { - setentry *entry, *table; - int table_is_malloced; - Py_ssize_t fill; + setentry *entry; + setentry *table = so->table; + Py_ssize_t fill = so->fill; + Py_ssize_t used = so->used; + int table_is_malloced = table != so->smalltable; setentry small_copy[PySet_MINSIZE]; -#ifdef Py_DEBUG - Py_ssize_t i = 0; - Py_ssize_t n = so->mask + 1; -#endif - assert (PyAnySet_Check(so)); - table = so->table; assert(table != NULL); - table_is_malloced = table != so->smalltable; /* This is delicate. During the process of clearing the set, * decrefs can cause the set to mutate. To avoid fatal confusion @@ -461,7 +404,6 @@ set_clear_internal(PySetObject *so) * clearing the slots, and never refer to anything via so->ref while * clearing. */ - fill = so->fill; if (table_is_malloced) set_empty_to_minsize(so); @@ -480,20 +422,11 @@ set_clear_internal(PySetObject *so) * assert that the refcount on table is 1 now, i.e. that this function * has unique access to it, so decref side-effects can't alter it. */ - for (entry = table; fill > 0; ++entry) { -#ifdef Py_DEBUG - assert(i < n); - ++i; -#endif - if (entry->key) { - --fill; - if (entry->key != dummy) - Py_DECREF(entry->key); + for (entry = table; used > 0; entry++) { + if (entry->key && entry->key != dummy) { + used--; + Py_DECREF(entry->key); } -#ifdef Py_DEBUG - else - assert(entry->key == NULL); -#endif } if (table_is_malloced) @@ -540,16 +473,16 @@ static void set_dealloc(PySetObject *so) { setentry *entry; - Py_ssize_t fill = so->fill; + Py_ssize_t used = so->used; + PyObject_GC_UnTrack(so); Py_TRASHCAN_SAFE_BEGIN(so) if (so->weakreflist != NULL) PyObject_ClearWeakRefs((PyObject *) so); - for (entry = so->table; fill > 0; entry++) { - if (entry->key) { - --fill; - if (entry->key != dummy) + for (entry = so->table; used > 0; entry++) { + if (entry->key && entry->key != dummy) { + used--; Py_DECREF(entry->key); } } @@ -650,11 +583,24 @@ set_merge(PySetObject *so, PyObject *otherset) return 0; } +static int +set_contains_entry(PySetObject *so, setentry *entry) +{ + PyObject *key; + setentry *lu_entry; + + lu_entry = set_lookkey(so, entry->key, entry->hash); + if (lu_entry == NULL) + return -1; + key = lu_entry->key; + return key != NULL && key != dummy; +} + static int set_contains_key(PySetObject *so, PyObject *key) { + setentry entry; Py_hash_t hash; - setentry *entry; if (!PyUnicode_CheckExact(key) || (hash = ((PyASCIIObject *) key)->hash) == -1) { @@ -662,30 +608,16 @@ set_contains_key(PySetObject *so, PyObject *key) if (hash == -1) return -1; } - entry = (so->lookup)(so, key, hash); - if (entry == NULL) - return -1; - key = entry->key; - return key != NULL && key != dummy; -} - -static int -set_contains_entry(PySetObject *so, setentry *entry) -{ - PyObject *key; - setentry *lu_entry; - - lu_entry = (so->lookup)(so, entry->key, entry->hash); - if (lu_entry == NULL) - return -1; - key = lu_entry->key; - return key != NULL && key != dummy; + entry.key = key; + entry.hash = hash; + return set_contains_entry(so, &entry); } static PyObject * set_pop(PySetObject *so) { - Py_ssize_t i = 0; + /* Make sure the search finger is in bounds */ + Py_ssize_t i = so->finger & so->mask; setentry *entry; PyObject *key; @@ -695,32 +627,16 @@ set_pop(PySetObject *so) return NULL; } - /* Set entry to "the first" unused or dummy set entry. We abuse - * the hash field of slot 0 to hold a search finger: - * If slot 0 has a value, use slot 0. - * Else slot 0 is being used to hold a search finger, - * and we use its hash value as the first index to look. - */ - entry = &so->table[0]; - if (entry->key == NULL || entry->key == dummy) { - i = entry->hash; - /* The hash field may be a real hash value, or it may be a - * legit search finger, or it may be a once-legit search - * finger that's out of bounds now because it wrapped around - * or the table shrunk -- simply make sure it's in bounds now. - */ - if (i > so->mask || i < 1) - i = 1; /* skip slot 0 */ - while ((entry = &so->table[i])->key == NULL || entry->key==dummy) { - i++; - if (i > so->mask) - i = 1; - } + while ((entry = &so->table[i])->key == NULL || entry->key==dummy) { + i++; + if (i > so->mask) + i = 0; } key = entry->key; entry->key = dummy; + entry->hash = -1; so->used--; - so->table[0].hash = i + 1; /* next place to start */ + so->finger = i + 1; /* next place to start */ return key; } @@ -741,6 +657,17 @@ set_traverse(PySetObject *so, visitproc visit, void *arg) static Py_hash_t frozenset_hash(PyObject *self) { + /* Most of the constants in this hash algorithm are randomly choosen + large primes with "interesting bit patterns" and that passed + tests for good collision statistics on a variety of problematic + datasets such as: + + ps = [] + for r in range(21): + ps += itertools.combinations(range(20), r) + num_distinct_hashes = len({hash(frozenset(s)) for s in ps}) + + */ PySetObject *so = (PySetObject *)self; Py_uhash_t h, hash = 1927868237UL; setentry *entry; @@ -752,15 +679,17 @@ frozenset_hash(PyObject *self) hash *= (Py_uhash_t)PySet_GET_SIZE(self) + 1; while (set_next(so, &pos, &entry)) { /* Work to increase the bit dispersion for closely spaced hash - values. The is important because some use cases have many + values. This is important because some use cases have many combinations of a small number of elements with nearby hashes so that many distinct combinations collapse to only a handful of distinct hash values. */ h = entry->hash; - hash ^= (h ^ (h << 16) ^ 89869747UL) * 3644798167UL; + hash ^= ((h ^ 89869747UL) ^ (h << 16)) * 3644798167UL; } + /* Make the final result spread-out in a different pattern + than the algorithm for tuples or other python objects. */ hash = hash * 69069U + 907133923UL; - if (hash == -1) + if (hash == (Py_uhash_t)-1) hash = 590923713UL; so->hash = hash; return hash; @@ -1004,6 +933,12 @@ set_update(PySetObject *so, PyObject *args) PyDoc_STRVAR(update_doc, "Update a set with the union of itself and others."); +/* XXX Todo: + If aligned memory allocations become available, make the + set object 64 byte aligned so that most of the fields + can be retrieved or updated in a single cache line. +*/ + static PyObject * make_new_set(PyTypeObject *type, PyObject *iterable) { @@ -1018,8 +953,8 @@ make_new_set(PyTypeObject *type, PyObject *iterable) so->used = 0; so->mask = PySet_MINSIZE - 1; so->table = so->smalltable; - so->lookup = set_lookkey_unicode; so->hash = -1; + so->finger = 0; so->weakreflist = NULL; if (iterable != NULL) { @@ -1107,10 +1042,8 @@ set_new(PyTypeObject *type, PyObject *args, PyObject *kwds) t=set(a); a.clear(); a.update(b); b.clear(); b.update(t); del t The function always succeeds and it leaves both objects in a stable state. - Useful for creating temporary frozensets from sets for membership testing - in __contains__(), discard(), and remove(). Also useful for operations - that update in-place (by allowing an intermediate result to be swapped - into one of the original inputs). + Useful for operations that update in-place (by allowing an intermediate + result to be swapped into one of the original inputs). */ static void @@ -1118,7 +1051,6 @@ set_swap_bodies(PySetObject *a, PySetObject *b) { Py_ssize_t t; setentry *u; - setentry *(*f)(PySetObject *so, PyObject *key, Py_ssize_t hash); setentry tab[PySet_MINSIZE]; Py_hash_t h; @@ -1134,8 +1066,6 @@ set_swap_bodies(PySetObject *a, PySetObject *b) a->table = a->smalltable; b->table = u; - f = a->lookup; a->lookup = b->lookup; b->lookup = f; - if (a->table == a->smalltable || b->table == b->smalltable) { memcpy(tab, a->smalltable, sizeof(tab)); memcpy(a->smalltable, b->smalltable, sizeof(tab)); @@ -2345,6 +2275,9 @@ _PySet_Update(PyObject *set, PyObject *iterable) return set_update_internal((PySetObject *)set, iterable); } +/* Exported for the gdb plugin's benefit. */ +PyObject *_PySet_Dummy = dummy; + #ifdef Py_DEBUG /* Test code to be called with any three element set. diff --git a/Objects/stringlib/README.txt b/Objects/stringlib/README.txt index ab506d60f94b..8ff6ad8c4fa0 100644 --- a/Objects/stringlib/README.txt +++ b/Objects/stringlib/README.txt @@ -1,4 +1,4 @@ -bits shared by the stringobject and unicodeobject implementations (and +bits shared by the bytesobject and unicodeobject implementations (and possibly other modules, in a not too distant future). the stuff in here is included into relevant places; see the individual diff --git a/Objects/stringlib/join.h b/Objects/stringlib/join.h index 5568b31dab86..cbf81be17068 100644 --- a/Objects/stringlib/join.h +++ b/Objects/stringlib/join.h @@ -53,15 +53,22 @@ STRINGLIB(bytes_join)(PyObject *sep, PyObject *iterable) /* Here is the general case. Do a pre-pass to figure out the total * amount of space we'll need (sz), and see whether all arguments are - * buffer-compatible. + * bytes-like. */ for (i = 0, nbufs = 0; i < seqlen; i++) { Py_ssize_t itemlen; item = PySequence_Fast_GET_ITEM(seq, i); - if (_getbuffer(item, &buffers[i]) < 0) { + if (PyBytes_CheckExact(item)) { + /* Fast path. */ + Py_INCREF(item); + buffers[i].obj = item; + buffers[i].buf = PyBytes_AS_STRING(item); + buffers[i].len = PyBytes_GET_SIZE(item); + } + else if (PyObject_GetBuffer(item, &buffers[i], PyBUF_SIMPLE) != 0) { PyErr_Format(PyExc_TypeError, - "sequence item %zd: expected bytes, bytearray, " - "or an object with the buffer interface, %.80s found", + "sequence item %zd: expected a bytes-like object, " + "%.80s found", i, Py_TYPE(item)->tp_name); goto error; } diff --git a/Objects/stringlib/transmogrify.h b/Objects/stringlib/transmogrify.h index dd00976eacaa..cae6ea113a1d 100644 --- a/Objects/stringlib/transmogrify.h +++ b/Objects/stringlib/transmogrify.h @@ -15,7 +15,7 @@ stringlib_expandtabs(PyObject *self, PyObject *args, PyObject *kwds) { const char *e, *p; char *q; - size_t i, j; + Py_ssize_t i, j; PyObject *u; static char *kwlist[] = {"tabsize", 0}; int tabsize = 8; @@ -27,35 +27,31 @@ stringlib_expandtabs(PyObject *self, PyObject *args, PyObject *kwds) /* First pass: determine size of output string */ i = j = 0; e = STRINGLIB_STR(self) + STRINGLIB_LEN(self); - for (p = STRINGLIB_STR(self); p < e; p++) + for (p = STRINGLIB_STR(self); p < e; p++) { if (*p == '\t') { if (tabsize > 0) { - j += tabsize - (j % tabsize); - if (j > PY_SSIZE_T_MAX) { - PyErr_SetString(PyExc_OverflowError, - "result is too long"); - return NULL; - } + Py_ssize_t incr = tabsize - (j % tabsize); + if (j > PY_SSIZE_T_MAX - incr) + goto overflow; + j += incr; } } else { + if (j > PY_SSIZE_T_MAX - 1) + goto overflow; j++; if (*p == '\n' || *p == '\r') { + if (i > PY_SSIZE_T_MAX - j) + goto overflow; i += j; j = 0; - if (i > PY_SSIZE_T_MAX) { - PyErr_SetString(PyExc_OverflowError, - "result is too long"); - return NULL; - } } } - - if ((i + j) > PY_SSIZE_T_MAX) { - PyErr_SetString(PyExc_OverflowError, "result is too long"); - return NULL; } + if (i > PY_SSIZE_T_MAX - j) + goto overflow; + /* Second pass: create output string and fill it */ u = STRINGLIB_NEW(NULL, i + j); if (!u) @@ -63,8 +59,8 @@ stringlib_expandtabs(PyObject *self, PyObject *args, PyObject *kwds) j = 0; q = STRINGLIB_STR(u); - - for (p = STRINGLIB_STR(self); p < e; p++) + + for (p = STRINGLIB_STR(self); p < e; p++) { if (*p == '\t') { if (tabsize > 0) { i = tabsize - (j % tabsize); @@ -79,8 +75,12 @@ stringlib_expandtabs(PyObject *self, PyObject *args, PyObject *kwds) if (*p == '\n' || *p == '\r') j = 0; } + } return u; + overflow: + PyErr_SetString(PyExc_OverflowError, "result too long"); + return NULL; } Py_LOCAL_INLINE(PyObject *) diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index 5625a6547c56..e45462b9cdc3 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -97,7 +97,7 @@ PyTuple_New(Py_ssize_t size) #endif { /* Check for overflow */ - if (size > (PY_SSIZE_T_MAX - sizeof(PyTupleObject) - + if ((size_t)size > ((size_t)PY_SSIZE_T_MAX - sizeof(PyTupleObject) - sizeof(PyObject *)) / sizeof(PyObject *)) { return PyErr_NoMemory(); } @@ -746,7 +746,7 @@ tuplesubscript(PyTupleObject* self, PyObject* item) } else { PyErr_Format(PyExc_TypeError, - "tuple indices must be integers, not %.200s", + "tuple indices must be integers or slices, not %.200s", Py_TYPE(item)->tp_name); return NULL; } @@ -879,8 +879,7 @@ _PyTuple_Resize(PyObject **pv, Py_ssize_t newsize) _Py_ForgetReference((PyObject *) v); /* DECREF items deleted by shrinkage */ for (i = newsize; i < oldsize; i++) { - Py_XDECREF(v->ob_item[i]); - v->ob_item[i] = NULL; + Py_CLEAR(v->ob_item[i]); } sv = PyObject_GC_Resize(PyTupleObject, v, newsize); if (sv == NULL) { @@ -926,8 +925,7 @@ PyTuple_Fini(void) #if PyTuple_MAXSAVESIZE > 0 /* empty tuples are used all over the place and applications may * rely on the fact that an empty tuple is a singleton. */ - Py_XDECREF(free_list[0]); - free_list[0] = NULL; + Py_CLEAR(free_list[0]); (void)PyTuple_ClearFreeList(); #endif @@ -1013,8 +1011,8 @@ tupleiter_setstate(tupleiterobject *it, PyObject *state) if (it->it_seq != NULL) { if (index < 0) index = 0; - else if (it->it_seq != NULL && index > PyTuple_GET_SIZE(it->it_seq)) - index = PyTuple_GET_SIZE(it->it_seq); + else if (index > PyTuple_GET_SIZE(it->it_seq)) + index = PyTuple_GET_SIZE(it->it_seq); /* exhausted iterator */ it->it_index = index; } Py_RETURN_NONE; diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 8b2ea1c1a667..f0ad7fd560d6 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -14,10 +14,11 @@ MCACHE_MAX_ATTR_SIZE, since it might be a problem if very large strings are used as attribute names. */ #define MCACHE_MAX_ATTR_SIZE 100 -#define MCACHE_SIZE_EXP 9 +#define MCACHE_SIZE_EXP 12 #define MCACHE_HASH(version, name_hash) \ - (((unsigned int)(version) * (unsigned int)(name_hash)) \ - >> (8*sizeof(unsigned int) - MCACHE_SIZE_EXP)) + (((unsigned int)(version) ^ (unsigned int)(name_hash)) \ + & ((1 << MCACHE_SIZE_EXP) - 1)) + #define MCACHE_HASH_METHOD(type, name) \ MCACHE_HASH((type)->tp_version_tag, \ ((PyASCIIObject *)(name))->hash) @@ -35,6 +36,14 @@ struct method_cache_entry { static struct method_cache_entry method_cache[1 << MCACHE_SIZE_EXP]; static unsigned int next_version_tag = 0; +#define MCACHE_STATS 0 + +#if MCACHE_STATS +static size_t method_cache_hits = 0; +static size_t method_cache_misses = 0; +static size_t method_cache_collisions = 0; +#endif + /* alphabetical order */ _Py_IDENTIFIER(__abstractmethods__); _Py_IDENTIFIER(__class__); @@ -54,12 +63,129 @@ _Py_IDENTIFIER(builtins); static PyObject * slot_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds); +static void +clear_slotdefs(void); + +/* + * finds the beginning of the docstring's introspection signature. + * if present, returns a pointer pointing to the first '('. + * otherwise returns NULL. + * + * doesn't guarantee that the signature is valid, only that it + * has a valid prefix. (the signature must also pass skip_signature.) + */ +static const char * +find_signature(const char *name, const char *doc) +{ + const char *dot; + size_t length; + + if (!doc) + return NULL; + + assert(name != NULL); + + /* for dotted names like classes, only use the last component */ + dot = strrchr(name, '.'); + if (dot) + name = dot + 1; + + length = strlen(name); + if (strncmp(doc, name, length)) + return NULL; + doc += length; + if (*doc != '(') + return NULL; + return doc; +} + +#define SIGNATURE_END_MARKER ")\n--\n\n" +#define SIGNATURE_END_MARKER_LENGTH 6 +/* + * skips past the end of the docstring's instrospection signature. + * (assumes doc starts with a valid signature prefix.) + */ +static const char * +skip_signature(const char *doc) +{ + while (*doc) { + if ((*doc == *SIGNATURE_END_MARKER) && + !strncmp(doc, SIGNATURE_END_MARKER, SIGNATURE_END_MARKER_LENGTH)) + return doc + SIGNATURE_END_MARKER_LENGTH; + if ((*doc == '\n') && (doc[1] == '\n')) + return NULL; + doc++; + } + return NULL; +} + +static const char * +_PyType_DocWithoutSignature(const char *name, const char *internal_doc) +{ + const char *doc = find_signature(name, internal_doc); + + if (doc) { + doc = skip_signature(doc); + if (doc) + return doc; + } + return internal_doc; +} + +PyObject * +_PyType_GetDocFromInternalDoc(const char *name, const char *internal_doc) +{ + const char *doc = _PyType_DocWithoutSignature(name, internal_doc); + + if (!doc) { + Py_INCREF(Py_None); + return Py_None; + } + + return PyUnicode_FromString(doc); +} + +PyObject * +_PyType_GetTextSignatureFromInternalDoc(const char *name, const char *internal_doc) +{ + const char *start = find_signature(name, internal_doc); + const char *end; + + if (start) + end = skip_signature(start); + else + end = NULL; + if (!end) { + Py_INCREF(Py_None); + return Py_None; + } + + /* back "end" up until it points just past the final ')' */ + end -= SIGNATURE_END_MARKER_LENGTH - 1; + assert((end - start) >= 2); /* should be "()" at least */ + assert(end[-1] == ')'); + assert(end[0] == '\n'); + return PyUnicode_FromStringAndSize(start, end - start); +} + unsigned int PyType_ClearCache(void) { Py_ssize_t i; unsigned int cur_version_tag = next_version_tag - 1; +#if MCACHE_STATS + size_t total = method_cache_hits + method_cache_collisions + method_cache_misses; + fprintf(stderr, "-- Method cache hits = %zd (%d%%)\n", + method_cache_hits, (int) (100.0 * method_cache_hits / total)); + fprintf(stderr, "-- Method cache true misses = %zd (%d%%)\n", + method_cache_misses, (int) (100.0 * method_cache_misses / total)); + fprintf(stderr, "-- Method cache collisions = %zd (%d%%)\n", + method_cache_collisions, (int) (100.0 * method_cache_collisions / total)); + fprintf(stderr, "-- Method cache size = %zd KB\n", + sizeof(method_cache) / 1024); +#endif + for (i = 0; i < (1 << MCACHE_SIZE_EXP); i++) { method_cache[i].version = 0; Py_CLEAR(method_cache[i].name); @@ -75,6 +201,7 @@ void _PyType_Fini(void) { PyType_ClearCache(); + clear_slotdefs(); } void @@ -437,9 +564,11 @@ type_get_bases(PyTypeObject *type, void *context) } static PyTypeObject *best_base(PyObject *); -static int mro_internal(PyTypeObject *); +static int mro_internal(PyTypeObject *, PyObject **); +Py_LOCAL_INLINE(int) type_is_subtype_base_chain(PyTypeObject *, PyTypeObject *); static int compatible_for_assignment(PyTypeObject *, PyTypeObject *, char *); static int add_subclass(PyTypeObject*, PyTypeObject*); +static int add_all_subclasses(PyTypeObject *type, PyObject *bases); static void remove_subclass(PyTypeObject *, PyTypeObject *); static void remove_all_subclasses(PyTypeObject *type, PyObject *bases); static void update_all_slots(PyTypeObject *); @@ -449,167 +578,194 @@ static int update_subclasses(PyTypeObject *type, PyObject *name, update_callback callback, void *data); static int recurse_down_subclasses(PyTypeObject *type, PyObject *name, update_callback callback, void *data); +static PyObject *type_subclasses(PyTypeObject *type, PyObject *ignored); static int -mro_subclasses(PyTypeObject *type, PyObject* temp) +mro_hierarchy(PyTypeObject *type, PyObject *temp) { - PyTypeObject *subclass; - PyObject *ref, *subclasses, *old_mro; - Py_ssize_t i; + int res; + PyObject *new_mro, *old_mro; + PyObject *tuple; + PyObject *subclasses; + Py_ssize_t i, n; - subclasses = type->tp_subclasses; - if (subclasses == NULL) - return 0; - assert(PyDict_CheckExact(subclasses)); - i = 0; + res = mro_internal(type, &old_mro); + if (res <= 0) + /* error / reentrance */ + return res; + new_mro = type->tp_mro; - while (PyDict_Next(subclasses, &i, NULL, &ref)) { - assert(PyWeakref_CheckRef(ref)); - subclass = (PyTypeObject *)PyWeakref_GET_OBJECT(ref); - assert(subclass != NULL); - if ((PyObject *)subclass == Py_None) - continue; - assert(PyType_Check(subclass)); - old_mro = subclass->tp_mro; - if (mro_internal(subclass) < 0) { - subclass->tp_mro = old_mro; - return -1; - } - else { - PyObject* tuple; - tuple = PyTuple_Pack(2, subclass, old_mro); - Py_DECREF(old_mro); - if (!tuple) - return -1; - if (PyList_Append(temp, tuple) < 0) - return -1; - Py_DECREF(tuple); - } - if (mro_subclasses(subclass, temp) < 0) - return -1; + if (old_mro != NULL) + tuple = PyTuple_Pack(3, type, new_mro, old_mro); + else + tuple = PyTuple_Pack(2, type, new_mro); + + if (tuple != NULL) + res = PyList_Append(temp, tuple); + else + res = -1; + Py_XDECREF(tuple); + + if (res < 0) { + type->tp_mro = old_mro; + Py_DECREF(new_mro); + return -1; } - return 0; + Py_XDECREF(old_mro); + + /* Obtain a copy of subclasses list to iterate over. + + Otherwise type->tp_subclasses might be altered + in the middle of the loop, for example, through a custom mro(), + by invoking type_set_bases on some subclass of the type + which in turn calls remove_subclass/add_subclass on this type. + + Finally, this makes things simple avoiding the need to deal + with dictionary iterators and weak references. + */ + subclasses = type_subclasses(type, NULL); + if (subclasses == NULL) + return -1; + n = PyList_GET_SIZE(subclasses); + for (i = 0; i < n; i++) { + PyTypeObject *subclass; + subclass = (PyTypeObject *)PyList_GET_ITEM(subclasses, i); + res = mro_hierarchy(subclass, temp); + if (res < 0) + break; + } + Py_DECREF(subclasses); + + return res; } static int -type_set_bases(PyTypeObject *type, PyObject *value, void *context) +type_set_bases(PyTypeObject *type, PyObject *new_bases, void *context) { - Py_ssize_t i; - int r = 0; - PyObject *ob, *temp; + int res = 0; + PyObject *temp; + PyObject *old_bases; PyTypeObject *new_base, *old_base; - PyObject *old_bases, *old_mro; + Py_ssize_t i; - if (!check_set_special_type_attr(type, value, "__bases__")) + if (!check_set_special_type_attr(type, new_bases, "__bases__")) return -1; - if (!PyTuple_Check(value)) { + if (!PyTuple_Check(new_bases)) { PyErr_Format(PyExc_TypeError, "can only assign tuple to %s.__bases__, not %s", - type->tp_name, Py_TYPE(value)->tp_name); + type->tp_name, Py_TYPE(new_bases)->tp_name); return -1; } - if (PyTuple_GET_SIZE(value) == 0) { + if (PyTuple_GET_SIZE(new_bases) == 0) { PyErr_Format(PyExc_TypeError, "can only assign non-empty tuple to %s.__bases__, not ()", type->tp_name); return -1; } - for (i = 0; i < PyTuple_GET_SIZE(value); i++) { - ob = PyTuple_GET_ITEM(value, i); + for (i = 0; i < PyTuple_GET_SIZE(new_bases); i++) { + PyObject *ob; + PyTypeObject *base; + + ob = PyTuple_GET_ITEM(new_bases, i); if (!PyType_Check(ob)) { PyErr_Format(PyExc_TypeError, "%s.__bases__ must be tuple of classes, not '%s'", type->tp_name, Py_TYPE(ob)->tp_name); return -1; } - if (PyType_IsSubtype((PyTypeObject*)ob, type)) { + + base = (PyTypeObject*)ob; + if (PyType_IsSubtype(base, type) || + /* In case of reentering here again through a custom mro() + the above check is not enough since it relies on + base->tp_mro which would gonna be updated inside + mro_internal only upon returning from the mro(). + + However, base->tp_base has already been assigned (see + below), which in turn may cause an inheritance cycle + through tp_base chain. And this is definitely + not what you want to ever happen. */ + (base->tp_mro != NULL && type_is_subtype_base_chain(base, type))) { + PyErr_SetString(PyExc_TypeError, "a __bases__ item causes an inheritance cycle"); return -1; } } - new_base = best_base(value); - - if (!new_base) + new_base = best_base(new_bases); + if (new_base == NULL) return -1; if (!compatible_for_assignment(type->tp_base, new_base, "__bases__")) return -1; + Py_INCREF(new_bases); Py_INCREF(new_base); - Py_INCREF(value); old_bases = type->tp_bases; old_base = type->tp_base; - old_mro = type->tp_mro; - type->tp_bases = value; + type->tp_bases = new_bases; type->tp_base = new_base; - if (mro_internal(type) < 0) { - goto bail; - } - temp = PyList_New(0); - if (!temp) - goto bail; - - r = mro_subclasses(type, temp); - - if (r < 0) { - for (i = 0; i < PyList_Size(temp); i++) { - PyTypeObject* cls; - PyObject* mro; - PyArg_UnpackTuple(PyList_GET_ITEM(temp, i), - "", 2, 2, &cls, &mro); - Py_INCREF(mro); - ob = cls->tp_mro; - cls->tp_mro = mro; - Py_DECREF(ob); - } - Py_DECREF(temp); + if (temp == NULL) goto bail; - } - + if (mro_hierarchy(type, temp) < 0) + goto undo; Py_DECREF(temp); - /* any base that was in __bases__ but now isn't, we - need to remove |type| from its tp_subclasses. - conversely, any class now in __bases__ that wasn't - needs to have |type| added to its subclasses. */ - - /* for now, sod that: just remove from all old_bases, - add to all new_bases */ + /* Take no action in case if type->tp_bases has been replaced + through reentrance. */ + if (type->tp_bases == new_bases) { + /* any base that was in __bases__ but now isn't, we + need to remove |type| from its tp_subclasses. + conversely, any class now in __bases__ that wasn't + needs to have |type| added to its subclasses. */ - remove_all_subclasses(type, old_bases); - - for (i = PyTuple_GET_SIZE(value) - 1; i >= 0; i--) { - ob = PyTuple_GET_ITEM(value, i); - if (PyType_Check(ob)) { - if (add_subclass((PyTypeObject*)ob, type) < 0) - r = -1; - } + /* for now, sod that: just remove from all old_bases, + add to all new_bases */ + remove_all_subclasses(type, old_bases); + res = add_all_subclasses(type, new_bases); + update_all_slots(type); } - update_all_slots(type); - Py_DECREF(old_bases); Py_DECREF(old_base); - Py_DECREF(old_mro); - return r; + return res; - bail: - Py_DECREF(type->tp_bases); - Py_DECREF(type->tp_base); - if (type->tp_mro != old_mro) { - Py_DECREF(type->tp_mro); + undo: + for (i = PyList_GET_SIZE(temp) - 1; i >= 0; i--) { + PyTypeObject *cls; + PyObject *new_mro, *old_mro = NULL; + + PyArg_UnpackTuple(PyList_GET_ITEM(temp, i), + "", 2, 3, &cls, &new_mro, &old_mro); + /* Do not rollback if cls has a newer version of MRO. */ + if (cls->tp_mro == new_mro) { + Py_XINCREF(old_mro); + cls->tp_mro = old_mro; + Py_DECREF(new_mro); + } } + Py_DECREF(temp); + + bail: + if (type->tp_bases == new_bases) { + assert(type->tp_base == new_base); - type->tp_bases = old_bases; - type->tp_base = old_base; - type->tp_mro = old_mro; + type->tp_bases = old_bases; + type->tp_base = old_base; + + Py_DECREF(new_bases); + Py_DECREF(new_base); + } + else { + Py_DECREF(old_bases); + Py_DECREF(old_base); + } return -1; } @@ -628,8 +784,9 @@ static PyObject * type_get_doc(PyTypeObject *type, void *context) { PyObject *result; - if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE) && type->tp_doc != NULL) - return PyUnicode_FromString(type->tp_doc); + if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE) && type->tp_doc != NULL) { + return _PyType_GetDocFromInternalDoc(type->tp_name, type->tp_doc); + } result = _PyDict_GetItemId(type->tp_dict, &PyId___doc__); if (result == NULL) { result = Py_None; @@ -645,6 +802,12 @@ type_get_doc(PyTypeObject *type, void *context) return result; } +static PyObject * +type_get_text_signature(PyTypeObject *type, void *context) +{ + return _PyType_GetTextSignatureFromInternalDoc(type->tp_name, type->tp_doc); +} + static int type_set_doc(PyTypeObject *type, PyObject *value, void *context) { @@ -691,6 +854,7 @@ static PyGetSetDef type_getsets[] = { (setter)type_set_abstractmethods, NULL}, {"__dict__", (getter)type_dict, NULL, NULL}, {"__doc__", (getter)type_get_doc, (setter)type_set_doc, NULL}, + {"__text_signature__", (getter)type_get_text_signature, NULL, NULL}, {0} }; @@ -787,7 +951,7 @@ PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems) Py_INCREF(type); if (type->tp_itemsize == 0) - PyObject_INIT(obj, type); + (void)PyObject_INIT(obj, type); else (void) PyObject_INIT_VAR((PyVarObject *)obj, type, nitems); @@ -1061,8 +1225,11 @@ subtype_dealloc(PyObject *self) assert(basedealloc); basedealloc(self); - /* Can't reference self beyond this point */ - Py_DECREF(type); + /* Can't reference self beyond this point. It's possible tp_del switched + our type from a HEAPTYPE to a non-HEAPTYPE, so be careful about + reference counting. */ + if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) + Py_DECREF(type); endlabel: ++_PyTrash_delete_nesting; @@ -1174,6 +1341,18 @@ static PyTypeObject *solid_base(PyTypeObject *type); /* type test with subclassing support */ +Py_LOCAL_INLINE(int) +type_is_subtype_base_chain(PyTypeObject *a, PyTypeObject *b) +{ + do { + if (a == b) + return 1; + a = a->tp_base; + } while (a != NULL); + + return (b == &PyBaseObject_Type); +} + int PyType_IsSubtype(PyTypeObject *a, PyTypeObject *b) { @@ -1192,15 +1371,9 @@ PyType_IsSubtype(PyTypeObject *a, PyTypeObject *b) } return 0; } - else { + else /* a is not completely initilized yet; follow tp_base */ - do { - if (a == b) - return 1; - a = a->tp_base; - } while (a != NULL); - return b == &PyBaseObject_Type; - } + return type_is_subtype_base_chain(a, b); } /* Internal routines to do a method lookup in the type @@ -1467,10 +1640,11 @@ consistent method resolution\norder (MRO) for bases"); } static int -pmerge(PyObject *acc, PyObject* to_merge) { +pmerge(PyObject *acc, PyObject* to_merge) +{ + int res = 0; Py_ssize_t i, j, to_merge_size, empty_cnt; int *remain; - int ok; to_merge_size = PyList_GET_SIZE(to_merge); @@ -1508,15 +1682,13 @@ pmerge(PyObject *acc, PyObject* to_merge) { candidate = PyList_GET_ITEM(cur_list, remain[i]); for (j = 0; j < to_merge_size; j++) { PyObject *j_lst = PyList_GET_ITEM(to_merge, j); - if (tail_contains(j_lst, remain[j], candidate)) { + if (tail_contains(j_lst, remain[j], candidate)) goto skip; /* continue outer loop */ - } - } - ok = PyList_Append(acc, candidate); - if (ok < 0) { - PyMem_FREE(remain); - return -1; } + res = PyList_Append(acc, candidate); + if (res < 0) + goto out; + for (j = 0; j < to_merge_size; j++) { PyObject *j_lst = PyList_GET_ITEM(to_merge, j); if (remain[j] < PyList_GET_SIZE(j_lst) && @@ -1528,22 +1700,25 @@ pmerge(PyObject *acc, PyObject* to_merge) { skip: ; } - if (empty_cnt == to_merge_size) { - PyMem_FREE(remain); - return 0; + if (empty_cnt != to_merge_size) { + set_mro_error(to_merge, remain); + res = -1; } - set_mro_error(to_merge, remain); + + out: PyMem_FREE(remain); - return -1; + + return res; } static PyObject * mro_implementation(PyTypeObject *type) { - Py_ssize_t i, n; - int ok; - PyObject *bases, *result; + PyObject *result = NULL; + PyObject *bases; PyObject *to_merge, *bases_aslist; + int res; + Py_ssize_t i, n; if (type->tp_dict == NULL) { if (PyType_Ready(type) < 0) @@ -1567,42 +1742,44 @@ mro_implementation(PyTypeObject *type) return NULL; for (i = 0; i < n; i++) { - PyObject *base = PyTuple_GET_ITEM(bases, i); - PyObject *parentMRO; - parentMRO = PySequence_List(((PyTypeObject*)base)->tp_mro); - if (parentMRO == NULL) { - Py_DECREF(to_merge); - return NULL; + PyTypeObject *base; + PyObject *base_mro_aslist; + + base = (PyTypeObject *)PyTuple_GET_ITEM(bases, i); + if (base->tp_mro == NULL) { + PyErr_Format(PyExc_TypeError, + "Cannot extend an incomplete type '%.100s'", + base->tp_name); + goto out; } - PyList_SET_ITEM(to_merge, i, parentMRO); + base_mro_aslist = PySequence_List(base->tp_mro); + if (base_mro_aslist == NULL) + goto out; + + PyList_SET_ITEM(to_merge, i, base_mro_aslist); } bases_aslist = PySequence_List(bases); - if (bases_aslist == NULL) { - Py_DECREF(to_merge); - return NULL; - } + if (bases_aslist == NULL) + goto out; /* This is just a basic sanity check. */ if (check_duplicates(bases_aslist) < 0) { - Py_DECREF(to_merge); Py_DECREF(bases_aslist); - return NULL; + goto out; } PyList_SET_ITEM(to_merge, n, bases_aslist); result = Py_BuildValue("[O]", (PyObject *)type); - if (result == NULL) { - Py_DECREF(to_merge); - return NULL; - } + if (result == NULL) + goto out; - ok = pmerge(result, to_merge); + res = pmerge(result, to_merge); + if (res < 0) + Py_CLEAR(result); + + out: Py_DECREF(to_merge); - if (ok < 0) { - Py_DECREF(result); - return NULL; - } return result; } @@ -1616,59 +1793,133 @@ mro_external(PyObject *self) } static int -mro_internal(PyTypeObject *type) +mro_check(PyTypeObject *type, PyObject *mro) { - PyObject *mro, *result, *tuple; - int checkit = 0; + PyTypeObject *solid; + Py_ssize_t i, n; - if (Py_TYPE(type) == &PyType_Type) { - result = mro_implementation(type); + solid = solid_base(type); + + n = PyTuple_GET_SIZE(mro); + for (i = 0; i < n; i++) { + PyTypeObject *base; + PyObject *tmp; + + tmp = PyTuple_GET_ITEM(mro, i); + if (!PyType_Check(tmp)) { + PyErr_Format( + PyExc_TypeError, + "mro() returned a non-class ('%.500s')", + Py_TYPE(tmp)->tp_name); + return -1; + } + + base = (PyTypeObject*)tmp; + if (!PyType_IsSubtype(solid, solid_base(base))) { + PyErr_Format( + PyExc_TypeError, + "mro() returned base with unsuitable layout ('%.500s')", + base->tp_name); + return -1; + } } - else { + + return 0; +} + +/* Lookups an mcls.mro method, invokes it and checks the result (if needed, + in case of a custom mro() implementation). + + Keep in mind that during execution of this function type->tp_mro + can be replaced due to possible reentrance (for example, + through type_set_bases): + + - when looking up the mcls.mro attribute (it could be + a user-provided descriptor); + + - from inside a custom mro() itself; + + - through a finalizer of the return value of mro(). +*/ +static PyObject * +mro_invoke(PyTypeObject *type) +{ + PyObject *mro_result; + PyObject *new_mro; + int custom = (Py_TYPE(type) != &PyType_Type); + + if (custom) { _Py_IDENTIFIER(mro); - checkit = 1; - mro = lookup_method((PyObject *)type, &PyId_mro); - if (mro == NULL) - return -1; - result = PyObject_CallObject(mro, NULL); - Py_DECREF(mro); + PyObject *mro_meth = lookup_method((PyObject *)type, &PyId_mro); + if (mro_meth == NULL) + return NULL; + mro_result = PyObject_CallObject(mro_meth, NULL); + Py_DECREF(mro_meth); } - if (result == NULL) - return -1; - tuple = PySequence_Tuple(result); - Py_DECREF(result); - if (tuple == NULL) - return -1; - if (checkit) { - Py_ssize_t i, len; - PyObject *cls; - PyTypeObject *solid; + else { + mro_result = mro_implementation(type); + } + if (mro_result == NULL) + return NULL; - solid = solid_base(type); + new_mro = PySequence_Tuple(mro_result); + Py_DECREF(mro_result); + if (new_mro == NULL) + return NULL; - len = PyTuple_GET_SIZE(tuple); + if (custom && mro_check(type, new_mro) < 0) { + Py_DECREF(new_mro); + return NULL; + } - for (i = 0; i < len; i++) { - PyTypeObject *t; - cls = PyTuple_GET_ITEM(tuple, i); - if (!PyType_Check(cls)) { - PyErr_Format(PyExc_TypeError, - "mro() returned a non-class ('%.500s')", - Py_TYPE(cls)->tp_name); - Py_DECREF(tuple); - return -1; - } - t = (PyTypeObject*)cls; - if (!PyType_IsSubtype(solid, solid_base(t))) { - PyErr_Format(PyExc_TypeError, - "mro() returned base with unsuitable layout ('%.500s')", - t->tp_name); - Py_DECREF(tuple); - return -1; - } - } + return new_mro; +} + +/* Calculates and assigns a new MRO to type->tp_mro. + Return values and invariants: + + - Returns 1 if a new MRO value has been set to type->tp_mro due to + this call of mro_internal (no tricky reentrancy and no errors). + + In case if p_old_mro argument is not NULL, a previous value + of type->tp_mro is put there, and the ownership of this + reference is transferred to a caller. + Otherwise, the previous value (if any) is decref'ed. + + - Returns 0 in case when type->tp_mro gets changed because of + reentering here through a custom mro() (see a comment to mro_invoke). + + In this case, a refcount of an old type->tp_mro is adjusted + somewhere deeper in the call stack (by the innermost mro_internal + or its caller) and may become zero upon returning from here. + This also implies that the whole hierarchy of subclasses of the type + has seen the new value and updated their MRO accordingly. + + - Returns -1 in case of an error. +*/ +static int +mro_internal(PyTypeObject *type, PyObject **p_old_mro) +{ + PyObject *new_mro, *old_mro; + int reent; + + /* Keep a reference to be able to do a reentrancy check below. + Don't let old_mro be GC'ed and its address be reused for + another object, like (suddenly!) a new tp_mro. */ + old_mro = type->tp_mro; + Py_XINCREF(old_mro); + new_mro = mro_invoke(type); /* might cause reentrance */ + reent = (type->tp_mro != old_mro); + Py_XDECREF(old_mro); + if (new_mro == NULL) + return -1; + + if (reent) { + Py_DECREF(new_mro); + return 0; } - type->tp_mro = tuple; + + type->tp_mro = new_mro; type_mro_modified(type, type->tp_mro); /* corner case: the super class might have been hidden @@ -1677,7 +1928,12 @@ mro_internal(PyTypeObject *type) PyType_Modified(type); - return 0; + if (p_old_mro != NULL) + *p_old_mro = old_mro; /* transfer the ownership */ + else + Py_XDECREF(old_mro); + + return 1; } @@ -2362,9 +2618,6 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) type->tp_dictoffset = slotoffset; slotoffset += sizeof(PyObject *); } - if (type->tp_dictoffset) { - et->ht_cached_keys = _PyDict_NewKeysForClass(); - } if (add_weak) { assert(!base->tp_itemsize); type->tp_weaklistoffset = slotoffset; @@ -2414,6 +2667,10 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) /* Put the proper slots in place */ fixup_slot_dispatchers(type); + if (type->tp_dictoffset) { + et->ht_cached_keys = _PyDict_NewKeysForClass(); + } + Py_DECREF(dict); return (PyObject *)type; @@ -2507,7 +2764,8 @@ PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases) type->tp_itemsize = spec->itemsize; for (slot = spec->slots; slot->slot; slot++) { - if (slot->slot >= Py_ARRAY_LENGTH(slotoffsets)) { + if (slot->slot < 0 + || (size_t)slot->slot >= Py_ARRAY_LENGTH(slotoffsets)) { PyErr_SetString(PyExc_RuntimeError, "invalid slot offset"); goto fail; } @@ -2519,19 +2777,17 @@ PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases) /* need to make a copy of the docstring slot, which usually points to a static string literal */ if (slot->slot == Py_tp_doc) { - size_t len = strlen(slot->pfunc)+1; + const char *old_doc = _PyType_DocWithoutSignature(type->tp_name, slot->pfunc); + size_t len = strlen(old_doc)+1; char *tp_doc = PyObject_MALLOC(len); if (tp_doc == NULL) { PyErr_NoMemory(); goto fail; } - memcpy(tp_doc, slot->pfunc, len); + memcpy(tp_doc, old_doc, len); type->tp_doc = tp_doc; } } - if (type->tp_dictoffset) { - res->ht_cached_keys = _PyDict_NewKeysForClass(); - } if (type->tp_dealloc == NULL) { /* It's a heap type, so needs the heap types' dealloc. subtype_dealloc will call the base type's tp_dealloc, if @@ -2542,6 +2798,10 @@ PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases) if (PyType_Ready(type) < 0) goto fail; + if (type->tp_dictoffset) { + res->ht_cached_keys = _PyDict_NewKeysForClass(); + } + /* Set type.__module__ */ s = strrchr(spec->name, '.'); if (s != NULL) @@ -2562,6 +2822,19 @@ PyType_FromSpec(PyType_Spec *spec) return PyType_FromSpecWithBases(spec, NULL); } +void * +PyType_GetSlot(PyTypeObject *type, int slot) +{ + if (!PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE) || slot < 0) { + PyErr_BadInternalCall(); + return NULL; + } + if ((size_t)slot >= Py_ARRAY_LENGTH(slotoffsets)) { + /* Extension module requesting slot from a future version */ + return NULL; + } + return *(void**)(((char*)type) + slotoffsets[slot]); +} /* Internal API to look for a name through the MRO. This returns a borrowed reference, and doesn't set an exception! */ @@ -2577,8 +2850,12 @@ _PyType_Lookup(PyTypeObject *type, PyObject *name) /* fast path */ h = MCACHE_HASH_METHOD(type, name); if (method_cache[h].version == type->tp_version_tag && - method_cache[h].name == name) + method_cache[h].name == name) { +#if MCACHE_STATS + method_cache_hits++; +#endif return method_cache[h].value; + } } /* Look in tp_dict of types in MRO */ @@ -2612,6 +2889,13 @@ _PyType_Lookup(PyTypeObject *type, PyObject *name) method_cache[h].version = type->tp_version_tag; method_cache[h].value = res; /* borrowed */ Py_INCREF(name); + assert(((PyASCIIObject *)(name))->hash != -1); +#if MCACHE_STATS + if (method_cache[h].name != Py_None && method_cache[h].name != name) + method_cache_collisions++; + else + method_cache_misses++; +#endif Py_DECREF(method_cache[h].name); method_cache[h].name = name; } @@ -2909,6 +3193,8 @@ static PyMethodDef type_methods[] = { }; PyDoc_STRVAR(type_doc, +/* this text signature cannot be accurate yet. will fix. --larry */ +"type(object_or_name, bases, dict)\n" "type(object) -> the object's type\n" "type(name, bases, dict) -> a new type"); @@ -3220,9 +3506,14 @@ object_richcompare(PyObject *self, PyObject *other, int op) break; case Py_NE: - /* By default, != returns the opposite of ==, + /* By default, __ne__() delegates to __eq__() and inverts the result, unless the latter returns NotImplemented. */ - res = PyObject_RichCompare(self, other, Py_EQ); + if (self->ob_type->tp_richcompare == NULL) { + res = Py_NotImplemented; + Py_INCREF(res); + break; + } + res = (*self->ob_type->tp_richcompare)(self, other, Py_EQ); if (res != NULL && res != Py_NotImplemented) { int ok = PyObject_IsTrue(res); Py_DECREF(res); @@ -3255,17 +3546,18 @@ object_get_class(PyObject *self, void *closure) } static int -equiv_structs(PyTypeObject *a, PyTypeObject *b) +compatible_with_tp_base(PyTypeObject *child) { - return a == b || - (a != NULL && - b != NULL && - a->tp_basicsize == b->tp_basicsize && - a->tp_itemsize == b->tp_itemsize && - a->tp_dictoffset == b->tp_dictoffset && - a->tp_weaklistoffset == b->tp_weaklistoffset && - ((a->tp_flags & Py_TPFLAGS_HAVE_GC) == - (b->tp_flags & Py_TPFLAGS_HAVE_GC))); + PyTypeObject *parent = child->tp_base; + return (parent != NULL && + child->tp_basicsize == parent->tp_basicsize && + child->tp_itemsize == parent->tp_itemsize && + child->tp_dictoffset == parent->tp_dictoffset && + child->tp_weaklistoffset == parent->tp_weaklistoffset && + ((child->tp_flags & Py_TPFLAGS_HAVE_GC) == + (parent->tp_flags & Py_TPFLAGS_HAVE_GC)) && + (child->tp_dealloc == subtype_dealloc || + child->tp_dealloc == parent->tp_dealloc)); } static int @@ -3283,6 +3575,10 @@ same_slots_added(PyTypeObject *a, PyTypeObject *b) size += sizeof(PyObject *); /* Check slots compliance */ + if (!(a->tp_flags & Py_TPFLAGS_HEAPTYPE) || + !(b->tp_flags & Py_TPFLAGS_HEAPTYPE)) { + return 0; + } slots_a = ((PyHeapTypeObject *)a)->ht_slots; slots_b = ((PyHeapTypeObject *)b)->ht_slots; if (slots_a && slots_b) { @@ -3298,9 +3594,7 @@ compatible_for_assignment(PyTypeObject* oldto, PyTypeObject* newto, char* attr) { PyTypeObject *newbase, *oldbase; - if (newto->tp_dealloc != oldto->tp_dealloc || - newto->tp_free != oldto->tp_free) - { + if (newto->tp_free != oldto->tp_free) { PyErr_Format(PyExc_TypeError, "%s assignment: " "'%s' deallocator differs from '%s'", @@ -3309,11 +3603,21 @@ compatible_for_assignment(PyTypeObject* oldto, PyTypeObject* newto, char* attr) oldto->tp_name); return 0; } + /* + It's tricky to tell if two arbitrary types are sufficiently compatible as + to be interchangeable; e.g., even if they have the same tp_basicsize, they + might have totally different struct fields. It's much easier to tell if a + type and its supertype are compatible; e.g., if they have the same + tp_basicsize, then that means they have identical fields. So to check + whether two arbitrary types are compatible, we first find the highest + supertype that each is compatible with, and then if those supertypes are + compatible then the original types must also be compatible. + */ newbase = newto; oldbase = oldto; - while (equiv_structs(newbase, newbase->tp_base)) + while (compatible_with_tp_base(newbase)) newbase = newbase->tp_base; - while (equiv_structs(oldbase, oldbase->tp_base)) + while (compatible_with_tp_base(oldbase)) oldbase = oldbase->tp_base; if (newbase != oldbase && (newbase->tp_base != oldbase->tp_base || @@ -3348,17 +3652,12 @@ object_set_class(PyObject *self, PyObject *value, void *closure) return -1; } newto = (PyTypeObject *)value; - if (!(newto->tp_flags & Py_TPFLAGS_HEAPTYPE) || - !(oldto->tp_flags & Py_TPFLAGS_HEAPTYPE)) - { - PyErr_Format(PyExc_TypeError, - "__class__ assignment: only for heap types"); - return -1; - } if (compatible_for_assignment(oldto, newto, "__class__")) { - Py_INCREF(newto); + if (newto->tp_flags & Py_TPFLAGS_HEAPTYPE) + Py_INCREF(newto); Py_TYPE(self) = newto; - Py_DECREF(oldto); + if (oldto->tp_flags & Py_TPFLAGS_HEAPTYPE) + Py_DECREF(oldto); return 0; } else { @@ -3480,7 +3779,7 @@ _PyObject_GetState(PyObject *obj) { PyObject **dict; dict = _PyObject_GetDictPtr(obj); - /* It is possible that the object's dict is not initialized + /* It is possible that the object's dict is not initialized yet. In this case, we will return None for the state. We also return None if the dict is empty to make the behavior consistent regardless whether the dict was initialized or not. @@ -3593,7 +3892,7 @@ _PyObject_GetNewArguments(PyObject *obj, PyObject **args, PyObject **kwargs) /* We first attempt to fetch the arguments for __new__ by calling __getnewargs_ex__ on the object. */ - getnewargs_ex = _PyObject_GetAttrId(obj, &PyId___getnewargs_ex__); + getnewargs_ex = _PyObject_LookupSpecial(obj, &PyId___getnewargs_ex__); if (getnewargs_ex != NULL) { PyObject *newargs = PyObject_CallObject(getnewargs_ex, NULL); Py_DECREF(getnewargs_ex); @@ -3640,16 +3939,13 @@ _PyObject_GetNewArguments(PyObject *obj, PyObject **args, PyObject **kwargs) return -1; } return 0; - } else { - if (!PyErr_ExceptionMatches(PyExc_AttributeError)) { - return -1; - } - PyErr_Clear(); + } else if (PyErr_Occurred()) { + return -1; } /* The object does not have __getnewargs_ex__ so we fallback on using __getnewargs__ instead. */ - getnewargs = _PyObject_GetAttrId(obj, &PyId___getnewargs__); + getnewargs = _PyObject_LookupSpecial(obj, &PyId___getnewargs__); if (getnewargs != NULL) { *args = PyObject_CallObject(getnewargs, NULL); Py_DECREF(getnewargs); @@ -3665,11 +3961,8 @@ _PyObject_GetNewArguments(PyObject *obj, PyObject **args, PyObject **kwargs) } *kwargs = NULL; return 0; - } else { - if (!PyErr_ExceptionMatches(PyExc_AttributeError)) { - return -1; - } - PyErr_Clear(); + } else if (PyErr_Occurred()) { + return -1; } /* The object does not have __getnewargs_ex__ and __getnewargs__. This may @@ -3727,48 +4020,87 @@ _PyObject_GetItemsIter(PyObject *obj, PyObject **listitems, } static PyObject * -reduce_4(PyObject *obj) +reduce_newobj(PyObject *obj, int proto) { PyObject *args = NULL, *kwargs = NULL; PyObject *copyreg; PyObject *newobj, *newargs, *state, *listitems, *dictitems; PyObject *result; - _Py_IDENTIFIER(__newobj_ex__); - if (_PyObject_GetNewArguments(obj, &args, &kwargs) < 0) { + if (_PyObject_GetNewArguments(obj, &args, &kwargs) < 0) return NULL; - } + if (args == NULL) { args = PyTuple_New(0); - if (args == NULL) - return NULL; - } - if (kwargs == NULL) { - kwargs = PyDict_New(); - if (kwargs == NULL) + if (args == NULL) { + Py_XDECREF(kwargs); return NULL; + } } - copyreg = import_copyreg(); if (copyreg == NULL) { Py_DECREF(args); - Py_DECREF(kwargs); + Py_XDECREF(kwargs); return NULL; } - newobj = _PyObject_GetAttrId(copyreg, &PyId___newobj_ex__); - Py_DECREF(copyreg); - if (newobj == NULL) { + if (kwargs == NULL || PyDict_Size(kwargs) == 0) { + _Py_IDENTIFIER(__newobj__); + PyObject *cls; + Py_ssize_t i, n; + + Py_XDECREF(kwargs); + newobj = _PyObject_GetAttrId(copyreg, &PyId___newobj__); + Py_DECREF(copyreg); + if (newobj == NULL) { + Py_DECREF(args); + return NULL; + } + n = PyTuple_GET_SIZE(args); + newargs = PyTuple_New(n+1); + if (newargs == NULL) { + Py_DECREF(args); + Py_DECREF(newobj); + return NULL; + } + cls = (PyObject *) Py_TYPE(obj); + Py_INCREF(cls); + PyTuple_SET_ITEM(newargs, 0, cls); + for (i = 0; i < n; i++) { + PyObject *v = PyTuple_GET_ITEM(args, i); + Py_INCREF(v); + PyTuple_SET_ITEM(newargs, i+1, v); + } + Py_DECREF(args); + } + else if (proto >= 4) { + _Py_IDENTIFIER(__newobj_ex__); + + newobj = _PyObject_GetAttrId(copyreg, &PyId___newobj_ex__); + Py_DECREF(copyreg); + if (newobj == NULL) { + Py_DECREF(args); + Py_DECREF(kwargs); + return NULL; + } + newargs = PyTuple_Pack(3, Py_TYPE(obj), args, kwargs); Py_DECREF(args); Py_DECREF(kwargs); - return NULL; + if (newargs == NULL) { + Py_DECREF(newobj); + return NULL; + } } - newargs = PyTuple_Pack(3, Py_TYPE(obj), args, kwargs); - Py_DECREF(args); - Py_DECREF(kwargs); - if (newargs == NULL) { - Py_DECREF(newobj); + else { + PyErr_SetString(PyExc_ValueError, + "must use protocol 4 or greater to copy this " + "object; since __getnewargs_ex__ returned " + "keyword arguments."); + Py_DECREF(args); + Py_DECREF(kwargs); + Py_DECREF(copyreg); return NULL; } + state = _PyObject_GetState(obj); if (state == NULL) { Py_DECREF(newobj); @@ -3788,80 +4120,7 @@ reduce_4(PyObject *obj) Py_DECREF(state); Py_DECREF(listitems); Py_DECREF(dictitems); - return result; -} - -static PyObject * -reduce_2(PyObject *obj) -{ - PyObject *cls; - PyObject *args = NULL, *args2 = NULL, *kwargs = NULL; - PyObject *state = NULL, *listitems = NULL, *dictitems = NULL; - PyObject *copyreg = NULL, *newobj = NULL, *res = NULL; - Py_ssize_t i, n; - _Py_IDENTIFIER(__newobj__); - - if (_PyObject_GetNewArguments(obj, &args, &kwargs) < 0) { - return NULL; - } - if (args == NULL) { - assert(kwargs == NULL); - args = PyTuple_New(0); - if (args == NULL) { - return NULL; - } - } - else if (kwargs != NULL) { - if (PyDict_Size(kwargs) > 0) { - PyErr_SetString(PyExc_ValueError, - "must use protocol 4 or greater to copy this " - "object; since __getnewargs_ex__ returned " - "keyword arguments."); - Py_DECREF(args); - Py_DECREF(kwargs); - return NULL; - } - Py_CLEAR(kwargs); - } - - state = _PyObject_GetState(obj); - if (state == NULL) - goto end; - - if (_PyObject_GetItemsIter(obj, &listitems, &dictitems) < 0) - goto end; - - copyreg = import_copyreg(); - if (copyreg == NULL) - goto end; - newobj = _PyObject_GetAttrId(copyreg, &PyId___newobj__); - if (newobj == NULL) - goto end; - - n = PyTuple_GET_SIZE(args); - args2 = PyTuple_New(n+1); - if (args2 == NULL) - goto end; - cls = (PyObject *) Py_TYPE(obj); - Py_INCREF(cls); - PyTuple_SET_ITEM(args2, 0, cls); - for (i = 0; i < n; i++) { - PyObject *v = PyTuple_GET_ITEM(args, i); - Py_INCREF(v); - PyTuple_SET_ITEM(args2, i+1, v); - } - - res = PyTuple_Pack(5, newobj, args2, state, listitems, dictitems); - - end: - Py_XDECREF(args); - Py_XDECREF(args2); - Py_XDECREF(state); - Py_XDECREF(listitems); - Py_XDECREF(dictitems); - Py_XDECREF(copyreg); - Py_XDECREF(newobj); - return res; + return result; } /* @@ -3884,10 +4143,8 @@ _common_reduce(PyObject *self, int proto) { PyObject *copyreg, *res; - if (proto >= 4) - return reduce_4(self); - else if (proto >= 2) - return reduce_2(self); + if (proto >= 2) + return reduce_newobj(self, proto); copyreg = import_copyreg(); if (!copyreg) @@ -4103,8 +4360,8 @@ PyTypeObject PyBaseObject_Type = { PyObject_GenericGetAttr, /* tp_getattro */ PyObject_GenericSetAttr, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - PyDoc_STR("The most base type"), /* tp_doc */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + PyDoc_STR("object()\n--\n\nThe most base type"), /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ object_richcompare, /* tp_richcompare */ @@ -4347,6 +4604,8 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base) COPYNUM(nb_inplace_true_divide); COPYNUM(nb_inplace_floor_divide); COPYNUM(nb_index); + COPYNUM(nb_matrix_multiply); + COPYNUM(nb_inplace_matrix_multiply); } if (type->tp_as_sequence != NULL && base->tp_as_sequence != NULL) { @@ -4534,9 +4793,8 @@ PyType_Ready(PyTypeObject *type) } /* Calculate method resolution order */ - if (mro_internal(type) < 0) { + if (mro_internal(type, NULL) < 0) goto error; - } /* Inherit special flags from dominant base */ if (type->tp_base != NULL) @@ -4553,6 +4811,20 @@ PyType_Ready(PyTypeObject *type) inherit_slots(type, (PyTypeObject *)b); } + /* All bases of statically allocated type should be statically allocated */ + if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) + for (i = 0; i < n; i++) { + PyObject *b = PyTuple_GET_ITEM(bases, i); + if (PyType_Check(b) && + (((PyTypeObject *)b)->tp_flags & Py_TPFLAGS_HEAPTYPE)) { + PyErr_Format(PyExc_TypeError, + "type '%.100s' is not dynamically allocated but " + "its base type '%.100s' is dynamically allocated", + type->tp_name, ((PyTypeObject *)b)->tp_name); + goto error; + } + } + /* Sanity check for tp_free. */ if (PyType_IS_GC(type) && (type->tp_flags & Py_TPFLAGS_BASETYPE) && (type->tp_free == NULL || type->tp_free == PyObject_Del)) { @@ -4571,7 +4843,9 @@ PyType_Ready(PyTypeObject *type) */ if (_PyDict_GetItemId(type->tp_dict, &PyId___doc__) == NULL) { if (type->tp_doc != NULL) { - PyObject *doc = PyUnicode_FromString(type->tp_doc); + const char *old_doc = _PyType_DocWithoutSignature(type->tp_name, + type->tp_doc); + PyObject *doc = PyUnicode_FromString(old_doc); if (doc == NULL) goto error; if (_PyDict_SetItemId(type->tp_dict, &PyId___doc__, doc) < 0) { @@ -4669,6 +4943,24 @@ add_subclass(PyTypeObject *base, PyTypeObject *type) return result; } +static int +add_all_subclasses(PyTypeObject *type, PyObject *bases) +{ + int res = 0; + + if (bases) { + Py_ssize_t i; + for (i = 0; i < PyTuple_GET_SIZE(bases); i++) { + PyObject *base = PyTuple_GET_ITEM(bases, i); + if (PyType_Check(base) && + add_subclass((PyTypeObject*)base, type) < 0) + res = -1; + } + } + + return res; +} + static void remove_subclass(PyTypeObject *base, PyTypeObject *type) { @@ -5218,7 +5510,7 @@ tp_new_wrapper(PyObject *self, PyObject *args, PyObject *kwds) "%s.__new__(%s) is not safe, use %s.__new__()", type->tp_name, subtype->tp_name, - staticbase == NULL ? "?" : staticbase->tp_name); + staticbase->tp_name); return NULL; } @@ -5232,8 +5524,9 @@ tp_new_wrapper(PyObject *self, PyObject *args, PyObject *kwds) static struct PyMethodDef tp_new_methoddef[] = { {"__new__", (PyCFunction)tp_new_wrapper, METH_VARARGS|METH_KEYWORDS, - PyDoc_STR("T.__new__(S, ...) -> " - "a new object with type S, a subtype of T")}, + PyDoc_STR("__new__($type, *args, **kwargs)\n--\n\n" + "Create and return a new object. " + "See help(type) for accurate signature.")}, {0} }; @@ -5480,6 +5773,7 @@ slot_mp_ass_subscript(PyObject *self, PyObject *key, PyObject *value) SLOT1BIN(slot_nb_add, nb_add, "__add__", "__radd__") SLOT1BIN(slot_nb_subtract, nb_subtract, "__sub__", "__rsub__") SLOT1BIN(slot_nb_multiply, nb_multiply, "__mul__", "__rmul__") +SLOT1BIN(slot_nb_matrix_multiply, nb_matrix_multiply, "__matmul__", "__rmatmul__") SLOT1BIN(slot_nb_remainder, nb_remainder, "__mod__", "__rmod__") SLOT1BIN(slot_nb_divmod, nb_divmod, "__divmod__", "__rdivmod__") @@ -5573,6 +5867,7 @@ SLOT0(slot_nb_float, "__float__") SLOT1(slot_nb_inplace_add, "__iadd__", PyObject *, "O") SLOT1(slot_nb_inplace_subtract, "__isub__", PyObject *, "O") SLOT1(slot_nb_inplace_multiply, "__imul__", PyObject *, "O") +SLOT1(slot_nb_inplace_matrix_multiply, "__imatmul__", PyObject *, "O") SLOT1(slot_nb_inplace_remainder, "__imod__", PyObject *, "O") /* Can't use SLOT1 here, because nb_inplace_power is ternary */ static PyObject * @@ -6005,22 +6300,22 @@ typedef struct wrapperbase slotdef; ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, DOC) #define UNSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, \ - "x." NAME "() <==> " DOC) + NAME "($self, /)\n--\n\n" DOC) #define IBSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, \ - "x." NAME "(y) <==> x" DOC "y") + NAME "($self, value, /)\n--\n\nReturn self" DOC "value.") #define BINSLOT(NAME, SLOT, FUNCTION, DOC) \ ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_l, \ - "x." NAME "(y) <==> x" DOC "y") + NAME "($self, value, /)\n--\n\nReturn self" DOC "value.") #define RBINSLOT(NAME, SLOT, FUNCTION, DOC) \ ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_r, \ - "x." NAME "(y) <==> y" DOC "x") + NAME "($self, value, /)\n--\n\nReturn value" DOC "self.") #define BINSLOTNOTINFIX(NAME, SLOT, FUNCTION, DOC) \ ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_l, \ - "x." NAME "(y) <==> " DOC) + NAME "($self, value, /)\n--\n\n" DOC) #define RBINSLOTNOTINFIX(NAME, SLOT, FUNCTION, DOC) \ ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_r, \ - "x." NAME "(y) <==> " DOC) + NAME "($self, value, /)\n--\n\n" DOC) static slotdef slotdefs[] = { TPSLOT("__getattribute__", tp_getattr, NULL, NULL, ""), @@ -6028,80 +6323,85 @@ static slotdef slotdefs[] = { TPSLOT("__setattr__", tp_setattr, NULL, NULL, ""), TPSLOT("__delattr__", tp_setattr, NULL, NULL, ""), TPSLOT("__repr__", tp_repr, slot_tp_repr, wrap_unaryfunc, - "x.__repr__() <==> repr(x)"), + "__repr__($self, /)\n--\n\nReturn repr(self)."), TPSLOT("__hash__", tp_hash, slot_tp_hash, wrap_hashfunc, - "x.__hash__() <==> hash(x)"), + "__hash__($self, /)\n--\n\nReturn hash(self)."), FLSLOT("__call__", tp_call, slot_tp_call, (wrapperfunc)wrap_call, - "x.__call__(...) <==> x(...)", PyWrapperFlag_KEYWORDS), + "__call__($self, /, *args, **kwargs)\n--\n\nCall self as a function.", + PyWrapperFlag_KEYWORDS), TPSLOT("__str__", tp_str, slot_tp_str, wrap_unaryfunc, - "x.__str__() <==> str(x)"), + "__str__($self, /)\n--\n\nReturn str(self)."), TPSLOT("__getattribute__", tp_getattro, slot_tp_getattr_hook, - wrap_binaryfunc, "x.__getattribute__('name') <==> x.name"), + wrap_binaryfunc, + "__getattribute__($self, name, /)\n--\n\nReturn getattr(self, name)."), TPSLOT("__getattr__", tp_getattro, slot_tp_getattr_hook, NULL, ""), TPSLOT("__setattr__", tp_setattro, slot_tp_setattro, wrap_setattr, - "x.__setattr__('name', value) <==> x.name = value"), + "__setattr__($self, name, value, /)\n--\n\nImplement setattr(self, name, value)."), TPSLOT("__delattr__", tp_setattro, slot_tp_setattro, wrap_delattr, - "x.__delattr__('name') <==> del x.name"), + "__delattr__($self, name, /)\n--\n\nImplement delattr(self, name)."), TPSLOT("__lt__", tp_richcompare, slot_tp_richcompare, richcmp_lt, - "x.__lt__(y) <==> x x<=y"), + "__le__($self, value, /)\n--\n\nReturn self<=value."), TPSLOT("__eq__", tp_richcompare, slot_tp_richcompare, richcmp_eq, - "x.__eq__(y) <==> x==y"), + "__eq__($self, value, /)\n--\n\nReturn self==value."), TPSLOT("__ne__", tp_richcompare, slot_tp_richcompare, richcmp_ne, - "x.__ne__(y) <==> x!=y"), + "__ne__($self, value, /)\n--\n\nReturn self!=value."), TPSLOT("__gt__", tp_richcompare, slot_tp_richcompare, richcmp_gt, - "x.__gt__(y) <==> x>y"), + "__gt__($self, value, /)\n--\n\nReturn self>value."), TPSLOT("__ge__", tp_richcompare, slot_tp_richcompare, richcmp_ge, - "x.__ge__(y) <==> x>=y"), + "__ge__($self, value, /)\n--\n\nReturn self>=value."), TPSLOT("__iter__", tp_iter, slot_tp_iter, wrap_unaryfunc, - "x.__iter__() <==> iter(x)"), + "__iter__($self, /)\n--\n\nImplement iter(self)."), TPSLOT("__next__", tp_iternext, slot_tp_iternext, wrap_next, - "x.__next__() <==> next(x)"), + "__next__($self, /)\n--\n\nImplement next(self)."), TPSLOT("__get__", tp_descr_get, slot_tp_descr_get, wrap_descr_get, - "descr.__get__(obj[, type]) -> value"), + "__get__($self, instance, owner, /)\n--\n\nReturn an attribute of instance, which is of type owner."), TPSLOT("__set__", tp_descr_set, slot_tp_descr_set, wrap_descr_set, - "descr.__set__(obj, value)"), + "__set__($self, instance, value, /)\n--\n\nSet an attribute of instance to value."), TPSLOT("__delete__", tp_descr_set, slot_tp_descr_set, - wrap_descr_delete, "descr.__delete__(obj)"), + wrap_descr_delete, + "__delete__($self, instance, /)\n--\n\nDelete an attribute of instance."), FLSLOT("__init__", tp_init, slot_tp_init, (wrapperfunc)wrap_init, - "x.__init__(...) initializes x; " - "see help(type(x)) for signature", + "__init__($self, /, *args, **kwargs)\n--\n\n" + "Initialize self. See help(type(self)) for accurate signature.", PyWrapperFlag_KEYWORDS), - TPSLOT("__new__", tp_new, slot_tp_new, NULL, ""), + TPSLOT("__new__", tp_new, slot_tp_new, NULL, + "__new__(type, /, *args, **kwargs)\n--\n\n" + "Create and return new object. See help(type) for accurate signature."), TPSLOT("__del__", tp_finalize, slot_tp_finalize, (wrapperfunc)wrap_del, ""), BINSLOT("__add__", nb_add, slot_nb_add, - "+"), + "+"), RBINSLOT("__radd__", nb_add, slot_nb_add, - "+"), + "+"), BINSLOT("__sub__", nb_subtract, slot_nb_subtract, - "-"), + "-"), RBINSLOT("__rsub__", nb_subtract, slot_nb_subtract, - "-"), + "-"), BINSLOT("__mul__", nb_multiply, slot_nb_multiply, - "*"), + "*"), RBINSLOT("__rmul__", nb_multiply, slot_nb_multiply, - "*"), + "*"), BINSLOT("__mod__", nb_remainder, slot_nb_remainder, - "%"), + "%"), RBINSLOT("__rmod__", nb_remainder, slot_nb_remainder, - "%"), + "%"), BINSLOTNOTINFIX("__divmod__", nb_divmod, slot_nb_divmod, - "divmod(x, y)"), + "Return divmod(self, value)."), RBINSLOTNOTINFIX("__rdivmod__", nb_divmod, slot_nb_divmod, - "divmod(y, x)"), + "Return divmod(value, self)."), NBSLOT("__pow__", nb_power, slot_nb_power, wrap_ternaryfunc, - "x.__pow__(y[, z]) <==> pow(x, y[, z])"), + "__pow__($self, value, mod=None, /)\n--\n\nReturn pow(self, value, mod)."), NBSLOT("__rpow__", nb_power, slot_nb_power, wrap_ternaryfunc_r, - "y.__rpow__(x[, z]) <==> pow(x, y[, z])"), - UNSLOT("__neg__", nb_negative, slot_nb_negative, wrap_unaryfunc, "-x"), - UNSLOT("__pos__", nb_positive, slot_nb_positive, wrap_unaryfunc, "+x"), + "__rpow__($self, value, mod=None, /)\n--\n\nReturn pow(value, self, mod)."), + UNSLOT("__neg__", nb_negative, slot_nb_negative, wrap_unaryfunc, "-self"), + UNSLOT("__pos__", nb_positive, slot_nb_positive, wrap_unaryfunc, "+self"), UNSLOT("__abs__", nb_absolute, slot_nb_absolute, wrap_unaryfunc, - "abs(x)"), + "abs(self)"), UNSLOT("__bool__", nb_bool, slot_nb_bool, wrap_inquirypred, - "x != 0"), - UNSLOT("__invert__", nb_invert, slot_nb_invert, wrap_unaryfunc, "~x"), + "self != 0"), + UNSLOT("__invert__", nb_invert, slot_nb_invert, wrap_unaryfunc, "~self"), BINSLOT("__lshift__", nb_lshift, slot_nb_lshift, "<<"), RBINSLOT("__rlshift__", nb_lshift, slot_nb_lshift, "<<"), BINSLOT("__rshift__", nb_rshift, slot_nb_rshift, ">>"), @@ -6113,9 +6413,9 @@ static slotdef slotdefs[] = { BINSLOT("__or__", nb_or, slot_nb_or, "|"), RBINSLOT("__ror__", nb_or, slot_nb_or, "|"), UNSLOT("__int__", nb_int, slot_nb_int, wrap_unaryfunc, - "int(x)"), + "int(self)"), UNSLOT("__float__", nb_float, slot_nb_float, wrap_unaryfunc, - "float(x)"), + "float(self)"), IBSLOT("__iadd__", nb_inplace_add, slot_nb_inplace_add, wrap_binaryfunc, "+="), IBSLOT("__isub__", nb_inplace_subtract, slot_nb_inplace_subtract, @@ -6141,49 +6441,58 @@ static slotdef slotdefs[] = { BINSLOT("__truediv__", nb_true_divide, slot_nb_true_divide, "/"), RBINSLOT("__rtruediv__", nb_true_divide, slot_nb_true_divide, "/"), IBSLOT("__ifloordiv__", nb_inplace_floor_divide, - slot_nb_inplace_floor_divide, wrap_binaryfunc, "//"), + slot_nb_inplace_floor_divide, wrap_binaryfunc, "//="), IBSLOT("__itruediv__", nb_inplace_true_divide, - slot_nb_inplace_true_divide, wrap_binaryfunc, "/"), + slot_nb_inplace_true_divide, wrap_binaryfunc, "/="), NBSLOT("__index__", nb_index, slot_nb_index, wrap_unaryfunc, - "x[y:z] <==> x[y.__index__():z.__index__()]"), - + "__index__($self, /)\n--\n\n" + "Return self converted to an integer, if self is suitable " + "for use as an index into a list."), + BINSLOT("__matmul__", nb_matrix_multiply, slot_nb_matrix_multiply, + "@"), + RBINSLOT("__rmatmul__", nb_matrix_multiply, slot_nb_matrix_multiply, + "@"), + IBSLOT("__imatmul__", nb_inplace_matrix_multiply, slot_nb_inplace_matrix_multiply, + wrap_binaryfunc, "@="), MPSLOT("__len__", mp_length, slot_mp_length, wrap_lenfunc, - "x.__len__() <==> len(x)"), + "__len__($self, /)\n--\n\nReturn len(self)."), MPSLOT("__getitem__", mp_subscript, slot_mp_subscript, wrap_binaryfunc, - "x.__getitem__(y) <==> x[y]"), + "__getitem__($self, key, /)\n--\n\nReturn self[key]."), MPSLOT("__setitem__", mp_ass_subscript, slot_mp_ass_subscript, wrap_objobjargproc, - "x.__setitem__(i, y) <==> x[i]=y"), + "__setitem__($self, key, value, /)\n--\n\nSet self[key] to value."), MPSLOT("__delitem__", mp_ass_subscript, slot_mp_ass_subscript, wrap_delitem, - "x.__delitem__(y) <==> del x[y]"), + "__delitem__($self, key, /)\n--\n\nDelete self[key]."), SQSLOT("__len__", sq_length, slot_sq_length, wrap_lenfunc, - "x.__len__() <==> len(x)"), + "__len__($self, /)\n--\n\nReturn len(self)."), /* Heap types defining __add__/__mul__ have sq_concat/sq_repeat == NULL. The logic in abstract.c always falls back to nb_add/nb_multiply in this case. Defining both the nb_* and the sq_* slots to call the user-defined methods has unexpected side-effects, as shown by test_descr.notimplemented() */ SQSLOT("__add__", sq_concat, NULL, wrap_binaryfunc, - "x.__add__(y) <==> x+y"), + "__add__($self, value, /)\n--\n\nReturn self+value."), SQSLOT("__mul__", sq_repeat, NULL, wrap_indexargfunc, - "x.__mul__(n) <==> x*n"), + "__mul__($self, value, /)\n--\n\nReturn self*value.n"), SQSLOT("__rmul__", sq_repeat, NULL, wrap_indexargfunc, - "x.__rmul__(n) <==> n*x"), + "__rmul__($self, value, /)\n--\n\nReturn self*value."), SQSLOT("__getitem__", sq_item, slot_sq_item, wrap_sq_item, - "x.__getitem__(y) <==> x[y]"), + "__getitem__($self, key, /)\n--\n\nReturn self[key]."), SQSLOT("__setitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_setitem, - "x.__setitem__(i, y) <==> x[i]=y"), + "__setitem__($self, key, value, /)\n--\n\nSet self[key] to value."), SQSLOT("__delitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_delitem, - "x.__delitem__(y) <==> del x[y]"), + "__delitem__($self, key, /)\n--\n\nDelete self[key]."), SQSLOT("__contains__", sq_contains, slot_sq_contains, wrap_objobjproc, - "x.__contains__(y) <==> y in x"), + "__contains__($self, key, /)\n--\n\nReturn key in self."), SQSLOT("__iadd__", sq_inplace_concat, NULL, - wrap_binaryfunc, "x.__iadd__(y) <==> x+=y"), + wrap_binaryfunc, + "__iadd__($self, value, /)\n--\n\nImplement self+=value."), SQSLOT("__imul__", sq_inplace_repeat, NULL, - wrap_indexargfunc, "x.__imul__(y) <==> x*=y"), + wrap_indexargfunc, + "__imul__($self, value, /)\n--\n\nImplement self*=value."), {NULL} }; @@ -6365,15 +6674,15 @@ update_slots_callback(PyTypeObject *type, void *data) return 0; } +static int slotdefs_initialized = 0; /* Initialize the slotdefs table by adding interned string objects for the - names and sorting the entries. */ + names. */ static void init_slotdefs(void) { slotdef *p; - static int initialized = 0; - if (initialized) + if (slotdefs_initialized) return; for (p = slotdefs; p->name; p++) { /* Slots must be ordered by their offset in the PyHeapTypeObject. */ @@ -6382,7 +6691,17 @@ init_slotdefs(void) if (!p->name_strobj) Py_FatalError("Out of memory interning slotdef names"); } - initialized = 1; + slotdefs_initialized = 1; +} + +/* Undo init_slotdefs, releasing the interned strings. */ +static void clear_slotdefs(void) +{ + slotdef *p; + for (p = slotdefs; p->name; p++) { + Py_CLEAR(p->name_strobj); + } + slotdefs_initialized = 0; } /* Update the slots after assignment to a class (type) attribute. */ @@ -6613,70 +6932,74 @@ static PyObject * super_getattro(PyObject *self, PyObject *name) { superobject *su = (superobject *)self; - int skip = su->obj_type == NULL; + PyTypeObject *starttype; + PyObject *mro; + Py_ssize_t i, n; + + starttype = su->obj_type; + if (starttype == NULL) + goto skip; + + /* We want __class__ to return the class of the super object + (i.e. super, or a subclass), not the class of su->obj. */ + if (PyUnicode_Check(name) && + PyUnicode_GET_LENGTH(name) == 9 && + _PyUnicode_CompareWithId(name, &PyId___class__) == 0) + goto skip; - if (!skip) { - /* We want __class__ to return the class of the super object - (i.e. super, or a subclass), not the class of su->obj. */ - skip = (PyUnicode_Check(name) && - PyUnicode_GET_LENGTH(name) == 9 && - _PyUnicode_CompareWithId(name, &PyId___class__) == 0); + mro = starttype->tp_mro; + if (mro == NULL) + goto skip; + + assert(PyTuple_Check(mro)); + n = PyTuple_GET_SIZE(mro); + + /* No need to check the last one: it's gonna be skipped anyway. */ + for (i = 0; i+1 < n; i++) { + if ((PyObject *)(su->type) == PyTuple_GET_ITEM(mro, i)) + break; } + i++; /* skip su->type (if any) */ + if (i >= n) + goto skip; - if (!skip) { - PyObject *mro, *res, *tmp, *dict; - PyTypeObject *starttype; + /* keep a strong reference to mro because starttype->tp_mro can be + replaced during PyDict_GetItem(dict, name) */ + Py_INCREF(mro); + do { + PyObject *res, *tmp, *dict; descrgetfunc f; - Py_ssize_t i, n; - starttype = su->obj_type; - mro = starttype->tp_mro; + tmp = PyTuple_GET_ITEM(mro, i); + assert(PyType_Check(tmp)); - if (mro == NULL) - n = 0; - else { - assert(PyTuple_Check(mro)); - n = PyTuple_GET_SIZE(mro); - } - for (i = 0; i < n; i++) { - if ((PyObject *)(su->type) == PyTuple_GET_ITEM(mro, i)) - break; - } - i++; - res = NULL; - /* keep a strong reference to mro because starttype->tp_mro can be - replaced during PyDict_GetItem(dict, name) */ - Py_INCREF(mro); - for (; i < n; i++) { - tmp = PyTuple_GET_ITEM(mro, i); - if (PyType_Check(tmp)) - dict = ((PyTypeObject *)tmp)->tp_dict; - else - continue; - res = PyDict_GetItem(dict, name); - if (res != NULL) { - Py_INCREF(res); - f = Py_TYPE(res)->tp_descr_get; - if (f != NULL) { - tmp = f(res, - /* Only pass 'obj' param if - this is instance-mode super - (See SF ID #743627) - */ - (su->obj == (PyObject *) - su->obj_type - ? (PyObject *)NULL - : su->obj), - (PyObject *)starttype); - Py_DECREF(res); - res = tmp; - } - Py_DECREF(mro); - return res; + dict = ((PyTypeObject *)tmp)->tp_dict; + assert(dict != NULL && PyDict_Check(dict)); + + res = PyDict_GetItem(dict, name); + if (res != NULL) { + Py_INCREF(res); + + f = Py_TYPE(res)->tp_descr_get; + if (f != NULL) { + tmp = f(res, + /* Only pass 'obj' param if this is instance-mode super + (See SF ID #743627) */ + (su->obj == (PyObject *)starttype) ? NULL : su->obj, + (PyObject *)starttype); + Py_DECREF(res); + res = tmp; } + + Py_DECREF(mro); + return res; } - Py_DECREF(mro); - } + + i++; + } while (i < n); + Py_DECREF(mro); + + skip: return PyObject_GenericGetAttr(self, name); } @@ -6786,9 +7109,16 @@ super_init(PyObject *self, PyObject *args, PyObject *kwds) if (type == NULL) { /* Call super(), without args -- fill in from __class__ and first local variable on the stack. */ - PyFrameObject *f = PyThreadState_GET()->frame; - PyCodeObject *co = f->f_code; + PyFrameObject *f; + PyCodeObject *co; Py_ssize_t i, n; + f = PyThreadState_GET()->frame; + if (f == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "super(): no current frame"); + return -1; + } + co = f->f_code; if (co == NULL) { PyErr_SetString(PyExc_RuntimeError, "super(): no code object"); diff --git a/Objects/typeslots.inc b/Objects/typeslots.inc index caa1e035d679..2ed99d894df7 100644 --- a/Objects/typeslots.inc +++ b/Objects/typeslots.inc @@ -73,3 +73,5 @@ offsetof(PyHeapTypeObject, ht_type.tp_traverse), offsetof(PyHeapTypeObject, ht_type.tp_members), offsetof(PyHeapTypeObject, ht_type.tp_getset), offsetof(PyHeapTypeObject, ht_type.tp_free), +offsetof(PyHeapTypeObject, as_number.nb_matrix_multiply), +offsetof(PyHeapTypeObject, as_number.nb_inplace_matrix_multiply), diff --git a/Objects/typeslots.py b/Objects/typeslots.py old mode 100644 new mode 100755 diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 34d51e404cc4..8605c92e3f89 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -47,10 +47,10 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #endif -/*[clinic] -class str -[clinic]*/ -/*[clinic checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ +/*[clinic input] +class str "PyUnicodeObject *" "&PyUnicode_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=604e916854800fa8]*/ /* --- Globals ------------------------------------------------------------ @@ -727,7 +727,7 @@ resize_compact(PyObject *unicode, Py_ssize_t length) _Py_DEC_REFTOTAL; _Py_ForgetReference(unicode); - new_unicode = (PyObject *)PyObject_REALLOC((char *)unicode, new_size); + new_unicode = (PyObject *)PyObject_REALLOC(unicode, new_size); if (new_unicode == NULL) { _Py_NewReference(unicode); PyErr_NoMemory(); @@ -816,7 +816,7 @@ resize_inplace(PyObject *unicode, Py_ssize_t length) assert(_PyUnicode_WSTR(unicode) != NULL); /* check for integer overflow */ - if (length > PY_SSIZE_T_MAX / sizeof(wchar_t) - 1) { + if (length > PY_SSIZE_T_MAX / (Py_ssize_t)sizeof(wchar_t) - 1) { PyErr_NoMemory(); return -1; } @@ -888,7 +888,7 @@ _PyUnicode_New(Py_ssize_t length) } /* Ensure we won't overflow the size. */ - if (length > ((PY_SSIZE_T_MAX / sizeof(Py_UNICODE)) - 1)) { + if (length > ((PY_SSIZE_T_MAX / (Py_ssize_t)sizeof(Py_UNICODE)) - 1)) { return (PyUnicodeObject *)PyErr_NoMemory(); } if (length < 0) { @@ -1011,17 +1011,19 @@ _PyUnicode_Dump(PyObject *op) } else data = unicode->data.any; - printf("%s: len=%zu, ",unicode_kind_name(op), ascii->length); + printf("%s: len=%" PY_FORMAT_SIZE_T "u, ", + unicode_kind_name(op), ascii->length); if (ascii->wstr == data) printf("shared "); printf("wstr=%p", ascii->wstr); if (!(ascii->state.ascii == 1 && ascii->state.compact == 1)) { - printf(" (%zu), ", compact->wstr_length); + printf(" (%" PY_FORMAT_SIZE_T "u), ", compact->wstr_length); if (!ascii->state.compact && compact->utf8 == unicode->data.any) printf("shared "); - printf("utf8=%p (%zu)", compact->utf8, compact->utf8_length); + printf("utf8=%p (%" PY_FORMAT_SIZE_T "u)", + compact->utf8, compact->utf8_length); } printf(", data=%p\n", data); } @@ -1533,6 +1535,10 @@ _PyUnicode_Ready(PyObject *unicode) /* in case the native representation is 2-bytes, we need to allocate a new normalized 4-byte version. */ length_wo_surrogates = _PyUnicode_WSTR_LENGTH(unicode) - num_surrogates; + if (length_wo_surrogates > PY_SSIZE_T_MAX / 4 - 1) { + PyErr_NoMemory(); + return -1; + } _PyUnicode_DATA_ANY(unicode) = PyObject_MALLOC(4 * (length_wo_surrogates + 1)); if (!_PyUnicode_DATA_ANY(unicode)) { PyErr_NoMemory(); @@ -1749,7 +1755,6 @@ unicode_write_cstr(PyObject *unicode, Py_ssize_t index, } } - static PyObject* get_latin1_char(unsigned char ch) { @@ -1766,6 +1771,34 @@ get_latin1_char(unsigned char ch) return unicode; } +static PyObject* +unicode_char(Py_UCS4 ch) +{ + PyObject *unicode; + + assert(ch <= MAX_UNICODE); + + if (ch < 256) + return get_latin1_char(ch); + + unicode = PyUnicode_New(1, ch); + if (unicode == NULL) + return NULL; + switch (PyUnicode_KIND(unicode)) { + case PyUnicode_1BYTE_KIND: + PyUnicode_1BYTE_DATA(unicode)[0] = (Py_UCS1)ch; + break; + case PyUnicode_2BYTE_KIND: + PyUnicode_2BYTE_DATA(unicode)[0] = (Py_UCS2)ch; + break; + default: + assert(PyUnicode_KIND(unicode) == PyUnicode_4BYTE_KIND); + PyUnicode_4BYTE_DATA(unicode)[0] = ch; + } + assert(_PyUnicode_CheckConsistency(unicode, 1)); + return unicode; +} + PyObject * PyUnicode_FromUnicode(const Py_UNICODE *u, Py_ssize_t size) { @@ -1875,8 +1908,7 @@ _PyUnicode_ClearStaticStrings() { _Py_Identifier *tmp, *s = static_strings; while (s) { - Py_DECREF(s->object); - s->object = NULL; + Py_CLEAR(s->object); tmp = s->next; s->next = NULL; s = tmp; @@ -1964,22 +1996,8 @@ _PyUnicode_FromUCS2(const Py_UCS2 *u, Py_ssize_t size) if (size == 0) _Py_RETURN_UNICODE_EMPTY(); assert(size > 0); - if (size == 1) { - Py_UCS4 ch = u[0]; - int kind; - void *data; - if (ch < 256) - return get_latin1_char((unsigned char)ch); - - res = PyUnicode_New(1, ch); - if (res == NULL) - return NULL; - kind = PyUnicode_KIND(res); - data = PyUnicode_DATA(res); - PyUnicode_WRITE(kind, data, 0, ch); - assert(_PyUnicode_CheckConsistency(res, 1)); - return res; - } + if (size == 1) + return unicode_char(u[0]); max_char = ucs2lib_find_max_char(u, u + size); res = PyUnicode_New(size, max_char); @@ -2004,22 +2022,8 @@ _PyUnicode_FromUCS4(const Py_UCS4 *u, Py_ssize_t size) if (size == 0) _Py_RETURN_UNICODE_EMPTY(); assert(size > 0); - if (size == 1) { - Py_UCS4 ch = u[0]; - int kind; - void *data; - if (ch < 256) - return get_latin1_char((unsigned char)ch); - - res = PyUnicode_New(1, ch); - if (res == NULL) - return NULL; - kind = PyUnicode_KIND(res); - data = PyUnicode_DATA(res); - PyUnicode_WRITE(kind, data, 0, ch); - assert(_PyUnicode_CheckConsistency(res, 1)); - return res; - } + if (size == 1) + return unicode_char(u[0]); max_char = ucs4lib_find_max_char(u, u + size); res = PyUnicode_New(size, max_char); @@ -2186,7 +2190,7 @@ _PyUnicode_AsKind(PyObject *s, unsigned int kind) } switch (kind) { case PyUnicode_2BYTE_KIND: - result = PyMem_Malloc(len * sizeof(Py_UCS2)); + result = PyMem_New(Py_UCS2, len); if (!result) return PyErr_NoMemory(); assert(skind == PyUnicode_1BYTE_KIND); @@ -2197,7 +2201,7 @@ _PyUnicode_AsKind(PyObject *s, unsigned int kind) result); return result; case PyUnicode_4BYTE_KIND: - result = PyMem_Malloc(len * sizeof(Py_UCS4)); + result = PyMem_New(Py_UCS4, len); if (!result) return PyErr_NoMemory(); if (skind == PyUnicode_2BYTE_KIND) { @@ -2239,11 +2243,7 @@ as_ucs4(PyObject *string, Py_UCS4 *target, Py_ssize_t targetsize, if (copy_null) targetlen++; if (!target) { - if (PY_SSIZE_T_MAX / sizeof(Py_UCS4) < targetlen) { - PyErr_NoMemory(); - return NULL; - } - target = PyMem_Malloc(targetlen * sizeof(Py_UCS4)); + target = PyMem_New(Py_UCS4, targetlen); if (!target) { PyErr_NoMemory(); return NULL; @@ -2313,35 +2313,6 @@ PyUnicode_FromWideChar(const wchar_t *w, Py_ssize_t size) #endif /* HAVE_WCHAR_H */ -static void -makefmt(char *fmt, int longflag, int longlongflag, int size_tflag, - char c) -{ - *fmt++ = '%'; - if (longflag) - *fmt++ = 'l'; - else if (longlongflag) { - /* longlongflag should only ever be nonzero on machines with - HAVE_LONG_LONG defined */ -#ifdef HAVE_LONG_LONG - char *f = PY_FORMAT_LONG_LONG; - while (*f) - *fmt++ = *f++; -#else - /* we shouldn't ever get here */ - assert(0); - *fmt++ = 'l'; -#endif - } - else if (size_tflag) { - char *f = PY_FORMAT_SIZE_T; - while (*f) - *fmt++ = *f++; - } - *fmt++ = c; - *fmt = '\0'; -} - /* maximum number of characters required for output of %lld or %p. We need at most ceil(log10(256)*SIZEOF_LONG_LONG) digits, plus 1 for the sign. 53/22 is an upper bound for log10(256). */ @@ -2517,48 +2488,42 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer, case 'x': { /* used by sprintf */ - char fmt[10]; /* should be enough for "%0lld\0" */ char buffer[MAX_LONG_LONG_CHARS]; Py_ssize_t arglen; if (*f == 'u') { - makefmt(fmt, longflag, longlongflag, size_tflag, *f); - if (longflag) - len = sprintf(buffer, fmt, + len = sprintf(buffer, "%lu", va_arg(*vargs, unsigned long)); #ifdef HAVE_LONG_LONG else if (longlongflag) - len = sprintf(buffer, fmt, + len = sprintf(buffer, "%" PY_FORMAT_LONG_LONG "u", va_arg(*vargs, unsigned PY_LONG_LONG)); #endif else if (size_tflag) - len = sprintf(buffer, fmt, + len = sprintf(buffer, "%" PY_FORMAT_SIZE_T "u", va_arg(*vargs, size_t)); else - len = sprintf(buffer, fmt, + len = sprintf(buffer, "%u", va_arg(*vargs, unsigned int)); } else if (*f == 'x') { - makefmt(fmt, 0, 0, 0, 'x'); - len = sprintf(buffer, fmt, va_arg(*vargs, int)); + len = sprintf(buffer, "%x", va_arg(*vargs, int)); } else { - makefmt(fmt, longflag, longlongflag, size_tflag, *f); - if (longflag) - len = sprintf(buffer, fmt, + len = sprintf(buffer, "%li", va_arg(*vargs, long)); #ifdef HAVE_LONG_LONG else if (longlongflag) - len = sprintf(buffer, fmt, + len = sprintf(buffer, "%" PY_FORMAT_LONG_LONG "i", va_arg(*vargs, PY_LONG_LONG)); #endif else if (size_tflag) - len = sprintf(buffer, fmt, + len = sprintf(buffer, "%" PY_FORMAT_SIZE_T "i", va_arg(*vargs, Py_ssize_t)); else - len = sprintf(buffer, fmt, + len = sprintf(buffer, "%i", va_arg(*vargs, int)); } assert(len >= 0); @@ -2852,12 +2817,7 @@ PyUnicode_AsWideCharString(PyObject *unicode, buflen = unicode_aswidechar(unicode, NULL, 0); if (buflen == -1) return NULL; - if (PY_SSIZE_T_MAX / sizeof(wchar_t) < buflen) { - PyErr_NoMemory(); - return NULL; - } - - buffer = PyMem_MALLOC(buflen * sizeof(wchar_t)); + buffer = PyMem_NEW(wchar_t, buflen); if (buffer == NULL) { PyErr_NoMemory(); return NULL; @@ -2877,27 +2837,13 @@ PyUnicode_AsWideCharString(PyObject *unicode, PyObject * PyUnicode_FromOrdinal(int ordinal) { - PyObject *v; - void *data; - int kind; - if (ordinal < 0 || ordinal > MAX_UNICODE) { PyErr_SetString(PyExc_ValueError, "chr() arg not in range(0x110000)"); return NULL; } - if ((Py_UCS4)ordinal < 256) - return get_latin1_char((unsigned char)ordinal); - - v = PyUnicode_New(1, ordinal); - if (v == NULL) - return NULL; - kind = PyUnicode_KIND(v); - data = PyUnicode_DATA(v); - PyUnicode_WRITE(kind, data, 0, ordinal); - assert(_PyUnicode_CheckConsistency(v, 1)); - return v; + return unicode_char((Py_UCS4)ordinal); } PyObject * @@ -2954,8 +2900,7 @@ PyUnicode_FromEncodedObject(PyObject *obj, /* Retrieve a bytes buffer view through the PEP 3118 buffer interface */ if (PyObject_GetBuffer(obj, &buffer, PyBUF_SIMPLE) < 0) { PyErr_Format(PyExc_TypeError, - "coercing to str: need bytes, bytearray " - "or buffer-like object, %.80s found", + "coercing to str: need a bytes-like object, %.80s found", Py_TYPE(obj)->tp_name); return NULL; } @@ -3261,7 +3206,7 @@ PyUnicode_EncodeLocale(PyObject *unicode, const char *errors) wlen2 = wcslen(wstr); if (wlen2 != wlen) { PyMem_Free(wstr); - PyErr_SetString(PyExc_TypeError, "embedded null character"); + PyErr_SetString(PyExc_ValueError, "embedded null character"); return NULL; } @@ -3269,7 +3214,7 @@ PyUnicode_EncodeLocale(PyObject *unicode, const char *errors) /* "surrogateescape" error handler */ char *str; - str = _Py_wchar2char(wstr, &error_pos); + str = Py_EncodeLocale(wstr, &error_pos); if (str == NULL) { if (error_pos == (size_t)-1) { PyErr_NoMemory(); @@ -3322,7 +3267,7 @@ PyUnicode_EncodeLocale(PyObject *unicode, const char *errors) if (errmsg != NULL) { size_t errlen; - wstr = _Py_char2wchar(errmsg, &errlen); + wstr = Py_DecodeLocale(errmsg, &errlen); if (wstr != NULL) { reason = PyUnicode_FromWideChar(wstr, errlen); PyMem_RawFree(wstr); @@ -3497,7 +3442,7 @@ mbstowcs_errorpos(const char *str, size_t len) memset(&mbs, 0, sizeof mbs); while (len) { - converted = mbrtowc(&ch, (char*)str, len, &mbs); + converted = mbrtowc(&ch, str, len, &mbs); if (converted == 0) /* Reached end of string */ break; @@ -3533,14 +3478,14 @@ PyUnicode_DecodeLocaleAndSize(const char *str, Py_ssize_t len, if (locale_error_handler(errors, &surrogateescape) < 0) return NULL; - if (str[len] != '\0' || len != strlen(str)) { - PyErr_SetString(PyExc_TypeError, "embedded null character"); + if (str[len] != '\0' || (size_t)len != strlen(str)) { + PyErr_SetString(PyExc_ValueError, "embedded null byte"); return NULL; } if (surrogateescape) { /* "surrogateescape" error handler */ - wstr = _Py_char2wchar(str, &wlen); + wstr = Py_DecodeLocale(str, &wlen); if (wstr == NULL) { if (wlen == (size_t)-1) PyErr_NoMemory(); @@ -3565,10 +3510,7 @@ PyUnicode_DecodeLocaleAndSize(const char *str, Py_ssize_t len, wstr = smallbuf; } else { - if (wlen > PY_SSIZE_T_MAX / sizeof(wchar_t) - 1) - return PyErr_NoMemory(); - - wstr = PyMem_Malloc((wlen+1) * sizeof(wchar_t)); + wstr = PyMem_New(wchar_t, wlen+1); if (!wstr) return PyErr_NoMemory(); } @@ -3595,7 +3537,7 @@ PyUnicode_DecodeLocaleAndSize(const char *str, Py_ssize_t len, error_pos = mbstowcs_errorpos(str, len); if (errmsg != NULL) { size_t errlen; - wstr = _Py_char2wchar(errmsg, &errlen); + wstr = Py_DecodeLocale(errmsg, &errlen); if (wstr != NULL) { reason = PyUnicode_FromWideChar(wstr, errlen); PyMem_RawFree(wstr); @@ -3710,8 +3652,8 @@ PyUnicode_FSConverter(PyObject* arg, void* addr) } size = PyBytes_GET_SIZE(output); data = PyBytes_AS_STRING(output); - if (size != strlen(data)) { - PyErr_SetString(PyExc_TypeError, "embedded NUL character"); + if ((size_t)size != strlen(data)) { + PyErr_SetString(PyExc_ValueError, "embedded null byte"); Py_DECREF(output); return 0; } @@ -3755,7 +3697,7 @@ PyUnicode_FSDecoder(PyObject* arg, void* addr) } if (findchar(PyUnicode_DATA(output), PyUnicode_KIND(output), PyUnicode_GET_LENGTH(output), 0, 1) >= 0) { - PyErr_SetString(PyExc_TypeError, "embedded NUL character"); + PyErr_SetString(PyExc_ValueError, "embedded null character"); Py_DECREF(output); return 0; } @@ -3873,6 +3815,11 @@ PyUnicode_AsUnicodeAndSize(PyObject *unicode, Py_ssize_t *size) #endif } else { + if ((size_t)_PyUnicode_LENGTH(unicode) > + PY_SSIZE_T_MAX / sizeof(wchar_t) - 1) { + PyErr_NoMemory(); + return NULL; + } _PyUnicode_WSTR(unicode) = (wchar_t *) PyObject_MALLOC(sizeof(wchar_t) * (_PyUnicode_LENGTH(unicode) + 1)); if (!_PyUnicode_WSTR(unicode)) { @@ -4020,8 +3967,7 @@ make_decode_exception(PyObject **exceptionObject, return; onError: - Py_DECREF(*exceptionObject); - *exceptionObject = NULL; + Py_CLEAR(*exceptionObject); } #ifdef HAVE_MBCS @@ -4108,16 +4054,21 @@ unicode_decode_call_errorhandler_wchar( have+the replacement+the rest of the string (starting at the new input position), so we won't have to check space when there are no errors in the rest of the string) */ - requiredsize = *outpos + repwlen + insize-newpos; + requiredsize = *outpos; + if (requiredsize > PY_SSIZE_T_MAX - repwlen) + goto overflow; + requiredsize += repwlen; + if (requiredsize > PY_SSIZE_T_MAX - (insize - newpos)) + goto overflow; + requiredsize += insize - newpos; if (requiredsize > outsize) { - if (requiredsize < 2*outsize) + if (outsize <= PY_SSIZE_T_MAX/2 && requiredsize < 2*outsize) requiredsize = 2*outsize; if (unicode_resize(output, requiredsize) < 0) goto onError; } wcsncpy(_PyUnicode_WSTR(*output) + *outpos, repwstr, repwlen); *outpos += repwlen; - *endinpos = newpos; *inptr = *input + newpos; @@ -4125,6 +4076,10 @@ unicode_decode_call_errorhandler_wchar( Py_XDECREF(restuple); return 0; + overflow: + PyErr_SetString(PyExc_OverflowError, + "decoded result is too long for a Python string"); + onError: Py_XDECREF(restuple); return -1; @@ -4197,9 +4152,13 @@ unicode_decode_call_errorhandler_writer( if (PyUnicode_READY(repunicode) < 0) goto onError; replen = PyUnicode_GET_LENGTH(repunicode); - writer->min_length += replen; - if (replen > 1) + if (replen > 1) { + writer->min_length += replen - 1; writer->overallocate = 1; + if (_PyUnicodeWriter_Prepare(writer, writer->min_length, + PyUnicode_MAX_CHAR_VALUE(repunicode)) == -1) + goto onError; + } if (_PyUnicodeWriter_WriteStr(writer, repunicode) == -1) goto onError; @@ -4474,8 +4433,16 @@ PyUnicode_DecodeUTF7Stateful(const char *s, /* return state */ if (consumed) { if (inShift) { - writer.pos = shiftOutStart; /* back off output */ *consumed = startinpos; + if (writer.pos != shiftOutStart && writer.maxchar > 127) { + PyObject *result = PyUnicode_FromKindAndData( + writer.kind, writer.data, shiftOutStart); + Py_XDECREF(errorHandler); + Py_XDECREF(exc); + _PyUnicodeWriter_Dealloc(&writer); + return result; + } + writer.pos = shiftOutStart; /* back off output */ } else { *consumed = s-starts; @@ -5047,7 +5014,7 @@ PyUnicode_DecodeUTF32Stateful(const char *s, } if (Py_UNICODE_IS_SURROGATE(ch)) { - errmsg = "codepoint in surrogate code point range(0xd800, 0xe000)"; + errmsg = "code point in surrogate code point range(0xd800, 0xe000)"; startinpos = ((const char *)q) - starts; endinpos = startinpos + 4; } @@ -5066,7 +5033,7 @@ PyUnicode_DecodeUTF32Stateful(const char *s, q += 4; continue; } - errmsg = "codepoint not in range(0x110000)"; + errmsg = "code point not in range(0x110000)"; startinpos = ((const char *)q) - starts; endinpos = startinpos + 4; } @@ -6373,8 +6340,7 @@ make_encode_exception(PyObject **exceptionObject, goto onError; return; onError: - Py_DECREF(*exceptionObject); - *exceptionObject = NULL; + Py_CLEAR(*exceptionObject); } } @@ -6510,7 +6476,7 @@ unicode_encode_ucs1(PyObject *unicode, Py_ssize_t collstart = pos; Py_ssize_t collend = pos; /* find all unecodable characters */ - while ((collend < size) && (PyUnicode_READ(kind, data, collend)>=limit)) + while ((collend < size) && (PyUnicode_READ(kind, data, collend) >= limit)) ++collend; /* cache callback name lookup (if not done yet, i.e. it's the first error) */ if (known_errorHandler==-1) { @@ -6530,36 +6496,43 @@ unicode_encode_ucs1(PyObject *unicode, raise_encode_exception(&exc, encoding, unicode, collstart, collend, reason); goto onError; case 2: /* replace */ - while (collstart++ PY_SSIZE_T_MAX - incr) + goto overflow; + requiredsize += incr; } - requiredsize = respos+repsize+(size-collend); + if (requiredsize > PY_SSIZE_T_MAX - (size - collend)) + goto overflow; + requiredsize += size - collend; if (requiredsize > ressize) { - if (requiredsize<2*ressize) + if (ressize <= PY_SSIZE_T_MAX/2 && requiredsize < 2*ressize) requiredsize = 2*ressize; if (_PyBytes_Resize(&res, requiredsize)) goto onError; @@ -6585,6 +6558,10 @@ unicode_encode_ucs1(PyObject *unicode, if (repsize > 1) { /* Make room for all additional bytes. */ respos = str - PyBytes_AS_STRING(res); + if (ressize > PY_SSIZE_T_MAX - repsize - 1) { + Py_DECREF(repunicode); + goto overflow; + } if (_PyBytes_Resize(&res, ressize+repsize-1)) { Py_DECREF(repunicode); goto onError; @@ -6603,9 +6580,15 @@ unicode_encode_ucs1(PyObject *unicode, we won't have to check space for encodable characters) */ respos = str - PyBytes_AS_STRING(res); repsize = PyUnicode_GET_LENGTH(repunicode); - requiredsize = respos+repsize+(size-collend); + requiredsize = respos; + if (requiredsize > PY_SSIZE_T_MAX - repsize) + goto overflow; + requiredsize += repsize; + if (requiredsize > PY_SSIZE_T_MAX - (size - collend)) + goto overflow; + requiredsize += size - collend; if (requiredsize > ressize) { - if (requiredsize<2*ressize) + if (ressize <= PY_SSIZE_T_MAX/2 && requiredsize < 2*ressize) requiredsize = 2*ressize; if (_PyBytes_Resize(&res, requiredsize)) { Py_DECREF(repunicode); @@ -6643,6 +6626,10 @@ unicode_encode_ucs1(PyObject *unicode, Py_XDECREF(exc); return res; + overflow: + PyErr_SetString(PyExc_OverflowError, + "encoded result is too long for a Python string"); + onError: Py_XDECREF(res); Py_XDECREF(errorHandler); @@ -6827,28 +6814,6 @@ code_page_name(UINT code_page, PyObject **obj) return PyBytes_AS_STRING(*obj); } -static int -is_dbcs_lead_byte(UINT code_page, const char *s, int offset) -{ - const char *curr = s + offset; - const char *prev; - - if (!IsDBCSLeadByteEx(code_page, *curr)) - return 0; - - prev = CharPrevExA(code_page, s, curr, 0); - if (prev == curr) - return 1; - /* FIXME: This code is limited to "true" double-byte encodings, - as it assumes an incomplete character consists of a single - byte. */ - if (curr - prev == 2) - return 1; - if (!IsDBCSLeadByteEx(code_page, *prev)) - return 1; - return 0; -} - static DWORD decode_code_page_flags(UINT code_page) { @@ -6923,7 +6888,7 @@ static int decode_code_page_errors(UINT code_page, PyObject **v, const char *in, const int size, - const char *errors) + const char *errors, int final) { const char *startin = in; const char *endin = in + size; @@ -6950,7 +6915,7 @@ decode_code_page_errors(UINT code_page, if (encoding == NULL) return -1; - if (errors == NULL || strcmp(errors, "strict") == 0) { + if ((errors == NULL || strcmp(errors, "strict") == 0) && final) { /* The last error was ERROR_NO_UNICODE_TRANSLATION, then we raise a UnicodeDecodeError. */ make_decode_exception(&exc, encoding, in, size, 0, 0, reason); @@ -7013,6 +6978,10 @@ decode_code_page_errors(UINT code_page, if (outsize <= 0) { Py_ssize_t startinpos, endinpos, outpos; + /* last character in partial decode? */ + if (in + insize >= endin && !final) + break; + startinpos = in - startin; endinpos = startinpos + 1; outpos = out - PyUnicode_AS_UNICODE(*v); @@ -7041,7 +7010,8 @@ decode_code_page_errors(UINT code_page, assert(outsize <= PyUnicode_WSTR_LENGTH(*v)); if (unicode_resize(v, outsize) < 0) goto error; - ret = size; + /* (in - startin) <= size and size is an int */ + ret = Py_SAFE_DOWNCAST(in - startin, Py_ssize_t, int); error: Py_XDECREF(encoding_obj); @@ -7082,24 +7052,19 @@ decode_code_page_stateful(int code_page, done = 1; } - /* Skip trailing lead-byte unless 'final' is set */ - if (!final && is_dbcs_lead_byte(code_page, s, chunk_size - 1)) - --chunk_size; - if (chunk_size == 0 && done) { if (v != NULL) break; _Py_RETURN_UNICODE_EMPTY(); } - converted = decode_code_page_strict(code_page, &v, s, chunk_size); if (converted == -2) converted = decode_code_page_errors(code_page, &v, s, chunk_size, - errors); - assert(converted != 0); + errors, final); + assert(converted != 0 || done); if (converted < 0) { Py_XDECREF(v); @@ -7463,6 +7428,11 @@ encode_code_page(int code_page, Py_ssize_t offset; int chunk_len, ret, done; + if (!PyUnicode_Check(unicode)) { + PyErr_BadArgument(); + return NULL; + } + if (PyUnicode_READY(unicode) == -1) return NULL; len = PyUnicode_GET_LENGTH(unicode); @@ -7536,10 +7506,6 @@ PyUnicode_EncodeCodePage(int code_page, PyObject * PyUnicode_AsMBCSString(PyObject *unicode) { - if (!PyUnicode_Check(unicode)) { - PyErr_BadArgument(); - return NULL; - } return PyUnicode_EncodeCodePage(CP_ACP, unicode, NULL); } @@ -8417,8 +8383,7 @@ make_translate_exception(PyObject **exceptionObject, goto onError; return; onError: - Py_DECREF(*exceptionObject); - *exceptionObject = NULL; + Py_CLEAR(*exceptionObject); } } @@ -8507,10 +8472,10 @@ charmaptranslate_lookup(Py_UCS4 c, PyObject *mapping, PyObject **result) } else if (PyLong_Check(x)) { long value = PyLong_AS_LONG(x); - long max = PyUnicode_GetMax(); - if (value < 0 || value > max) { - PyErr_Format(PyExc_TypeError, - "character mapping must be in range(0x%x)", max+1); + if (value < 0 || value > MAX_UNICODE) { + PyErr_Format(PyExc_ValueError, + "character mapping must be in range(0x%x)", + MAX_UNICODE+1); Py_DECREF(x); return -1; } @@ -8529,76 +8494,168 @@ charmaptranslate_lookup(Py_UCS4 c, PyObject *mapping, PyObject **result) return -1; } } -/* ensure that *outobj is at least requiredsize characters long, - if not reallocate and adjust various state variables. - Return 0 on success, -1 on error */ + +/* lookup the character, write the result into the writer. + Return 1 if the result was written into the writer, return 0 if the mapping + was undefined, raise an exception return -1 on error. */ static int -charmaptranslate_makespace(Py_UCS4 **outobj, Py_ssize_t *psize, - Py_ssize_t requiredsize) -{ - Py_ssize_t oldsize = *psize; - Py_UCS4 *new_outobj; - if (requiredsize > oldsize) { - /* exponentially overallocate to minimize reallocations */ - if (requiredsize < 2 * oldsize) - requiredsize = 2 * oldsize; - new_outobj = PyMem_Realloc(*outobj, requiredsize * sizeof(Py_UCS4)); - if (new_outobj == 0) +charmaptranslate_output(Py_UCS4 ch, PyObject *mapping, + _PyUnicodeWriter *writer) +{ + PyObject *item; + + if (charmaptranslate_lookup(ch, mapping, &item)) + return -1; + + if (item == NULL) { + /* not found => default to 1:1 mapping */ + if (_PyUnicodeWriter_WriteCharInline(writer, ch) < 0) { return -1; - *outobj = new_outobj; - *psize = requiredsize; + } + return 1; } - return 0; + + if (item == Py_None) { + Py_DECREF(item); + return 0; + } + + if (PyLong_Check(item)) { + long ch = (Py_UCS4)PyLong_AS_LONG(item); + /* PyLong_AS_LONG() cannot fail, charmaptranslate_lookup() already + used it */ + if (_PyUnicodeWriter_WriteCharInline(writer, ch) < 0) { + Py_DECREF(item); + return -1; + } + Py_DECREF(item); + return 1; + } + + if (!PyUnicode_Check(item)) { + Py_DECREF(item); + return -1; + } + + if (_PyUnicodeWriter_WriteStr(writer, item) < 0) { + Py_DECREF(item); + return -1; + } + + Py_DECREF(item); + return 1; } -/* lookup the character, put the result in the output string and adjust - various state variables. Return a new reference to the object that - was put in the output buffer in *result, or Py_None, if the mapping was - undefined (in which case no character was written). - The called must decref result. - Return 0 on success, -1 on error. */ + static int -charmaptranslate_output(PyObject *input, Py_ssize_t ipos, - PyObject *mapping, Py_UCS4 **output, - Py_ssize_t *osize, Py_ssize_t *opos, - PyObject **res) +unicode_fast_translate_lookup(PyObject *mapping, Py_UCS1 ch, + Py_UCS1 *translate) { - Py_UCS4 curinp = PyUnicode_READ_CHAR(input, ipos); - if (charmaptranslate_lookup(curinp, mapping, res)) + PyObject *item = NULL; + int ret = 0; + + if (charmaptranslate_lookup(ch, mapping, &item)) { return -1; - if (*res==NULL) { + } + + if (item == Py_None) { + /* deletion */ + translate[ch] = 0xfe; + } + else if (item == NULL) { /* not found => default to 1:1 mapping */ - (*output)[(*opos)++] = curinp; + translate[ch] = ch; + return 1; } - else if (*res==Py_None) - ; - else if (PyLong_Check(*res)) { - /* no overflow check, because we know that the space is enough */ - (*output)[(*opos)++] = (Py_UCS4)PyLong_AS_LONG(*res); + else if (PyLong_Check(item)) { + long replace = PyLong_AS_LONG(item); + /* PyLong_AS_LONG() cannot fail, charmaptranslate_lookup() already + used it */ + if (127 < replace) { + /* invalid character or character outside ASCII: + skip the fast translate */ + goto exit; + } + translate[ch] = (Py_UCS1)replace; } - else if (PyUnicode_Check(*res)) { - Py_ssize_t repsize; - if (PyUnicode_READY(*res) == -1) + else if (PyUnicode_Check(item)) { + Py_UCS4 replace; + + if (PyUnicode_READY(item) == -1) { + Py_DECREF(item); return -1; - repsize = PyUnicode_GET_LENGTH(*res); - if (repsize==1) { - /* no overflow check, because we know that the space is enough */ - (*output)[(*opos)++] = PyUnicode_READ_CHAR(*res, 0); } - else if (repsize!=0) { - /* more than one character */ - Py_ssize_t requiredsize = *opos + - (PyUnicode_GET_LENGTH(input) - ipos) + - repsize - 1; - Py_ssize_t i; - if (charmaptranslate_makespace(output, osize, requiredsize)) + if (PyUnicode_GET_LENGTH(item) != 1) + goto exit; + + replace = PyUnicode_READ_CHAR(item, 0); + if (replace > 127) + goto exit; + translate[ch] = (Py_UCS1)replace; + } + else { + /* not None, NULL, long or unicode */ + goto exit; + } + ret = 1; + + exit: + Py_DECREF(item); + return ret; +} + +/* Fast path for ascii => ascii translation. Return 1 if the whole string + was translated into writer, return 0 if the input string was partially + translated into writer, raise an exception and return -1 on error. */ +static int +unicode_fast_translate(PyObject *input, PyObject *mapping, + _PyUnicodeWriter *writer, int ignore) +{ + Py_UCS1 ascii_table[128], ch, ch2; + Py_ssize_t len; + Py_UCS1 *in, *end, *out; + int res = 0; + + if (PyUnicode_READY(input) == -1) + return -1; + if (!PyUnicode_IS_ASCII(input)) + return 0; + len = PyUnicode_GET_LENGTH(input); + + memset(ascii_table, 0xff, 128); + + in = PyUnicode_1BYTE_DATA(input); + end = in + len; + + assert(PyUnicode_IS_ASCII(writer->buffer)); + assert(PyUnicode_GET_LENGTH(writer->buffer) == len); + out = PyUnicode_1BYTE_DATA(writer->buffer); + + for (; in < end; in++) { + ch = *in; + ch2 = ascii_table[ch]; + if (ch2 == 0xff) { + int translate = unicode_fast_translate_lookup(mapping, ch, + ascii_table); + if (translate < 0) return -1; - for(i = 0; i < repsize; i++) - (*output)[(*opos)++] = PyUnicode_READ_CHAR(*res, i); + if (translate == 0) + goto exit; + ch2 = ascii_table[ch]; + } + if (ch2 == 0xfe) { + if (ignore) + continue; + goto exit; } + assert(ch2 < 128); + *out = ch2; + out++; } - else - return -1; - return 0; + res = 1; + +exit: + writer->pos = out - PyUnicode_1BYTE_DATA(writer->buffer); + return res; } PyObject * @@ -8607,22 +8664,17 @@ _PyUnicode_TranslateCharmap(PyObject *input, const char *errors) { /* input object */ - char *idata; + char *data; Py_ssize_t size, i; int kind; /* output buffer */ - Py_UCS4 *output = NULL; - Py_ssize_t osize; - PyObject *res; - /* current output position */ - Py_ssize_t opos; + _PyUnicodeWriter writer; + /* error handler */ char *reason = "character maps to "; PyObject *errorHandler = NULL; PyObject *exc = NULL; - /* the following variable is used for caching string comparisons - * -1=not initialized, 0=unknown, 1=strict, 2=replace, - * 3=ignore, 4=xmlcharrefreplace */ - int known_errorHandler = -1; + int ignore; + int res; if (mapping == NULL) { PyErr_BadArgument(); @@ -8631,10 +8683,9 @@ _PyUnicode_TranslateCharmap(PyObject *input, if (PyUnicode_READY(input) == -1) return NULL; - idata = (char*)PyUnicode_DATA(input); + data = (char*)PyUnicode_DATA(input); kind = PyUnicode_KIND(input); size = PyUnicode_GET_LENGTH(input); - i = 0; if (size == 0) { Py_INCREF(input); @@ -8643,121 +8694,81 @@ _PyUnicode_TranslateCharmap(PyObject *input, /* allocate enough for a simple 1:1 translation without replacements, if we need more, we'll resize */ - osize = size; - output = PyMem_Malloc(osize * sizeof(Py_UCS4)); - opos = 0; - if (output == NULL) { - PyErr_NoMemory(); + _PyUnicodeWriter_Init(&writer); + if (_PyUnicodeWriter_Prepare(&writer, size, 127) == -1) goto onError; + + ignore = (errors != NULL && strcmp(errors, "ignore") == 0); + + res = unicode_fast_translate(input, mapping, &writer, ignore); + if (res < 0) { + _PyUnicodeWriter_Dealloc(&writer); + return NULL; } + if (res == 1) + return _PyUnicodeWriter_Finish(&writer); + i = writer.pos; while (i adjust input pointer */ + + if (translate != 0) { + /* it worked => adjust input pointer */ ++i; - else { /* untranslatable character */ - PyObject *repunicode = NULL; /* initialize to prevent gcc warning */ - Py_ssize_t repsize; - Py_ssize_t newpos; - Py_ssize_t uni2; - /* startpos for collecting untranslatable chars */ - Py_ssize_t collstart = i; - Py_ssize_t collend = i+1; - Py_ssize_t coll; - - /* find all untranslatable characters */ - while (collend < size) { - if (charmaptranslate_lookup(PyUnicode_READ(kind,idata, collend), mapping, &x)) - goto onError; - Py_XDECREF(x); - if (x!=Py_None) - break; - ++collend; - } - /* cache callback name lookup - * (if not done yet, i.e. it's the first error) */ - if (known_errorHandler==-1) { - if ((errors==NULL) || (!strcmp(errors, "strict"))) - known_errorHandler = 1; - else if (!strcmp(errors, "replace")) - known_errorHandler = 2; - else if (!strcmp(errors, "ignore")) - known_errorHandler = 3; - else if (!strcmp(errors, "xmlcharrefreplace")) - known_errorHandler = 4; - else - known_errorHandler = 0; - } - switch (known_errorHandler) { - case 1: /* strict */ - make_translate_exception(&exc, - input, collstart, collend, reason); - if (exc != NULL) - PyCodec_StrictErrors(exc); + continue; + } + + /* untranslatable character */ + collstart = i; + collend = i+1; + + /* find all untranslatable characters */ + while (collend < size) { + PyObject *x; + ch = PyUnicode_READ(kind, data, collend); + if (charmaptranslate_lookup(ch, mapping, &x)) goto onError; - case 2: /* replace */ - /* No need to check for space, this is a 1:1 replacement */ - for (coll = collstart; coll0; ++uni2) - output[opos++] = PyUnicode_READ_CHAR(repunicode, uni2); - i = newpos; + ++collend; + } + + if (ignore) { + i = collend; + } + else { + repunicode = unicode_translate_call_errorhandler(errors, &errorHandler, + reason, input, &exc, + collstart, collend, &newpos); + if (repunicode == NULL) + goto onError; + if (_PyUnicodeWriter_WriteStr(&writer, repunicode) < 0) { Py_DECREF(repunicode); + goto onError; } + Py_DECREF(repunicode); + i = newpos; } } - res = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, output, opos); - if (!res) - goto onError; - PyMem_Free(output); Py_XDECREF(exc); Py_XDECREF(errorHandler); - return res; + return _PyUnicodeWriter_Finish(&writer); onError: - PyMem_Free(output); + _PyUnicodeWriter_Dealloc(&writer); Py_XDECREF(exc); Py_XDECREF(errorHandler); return NULL; @@ -8859,7 +8870,7 @@ PyUnicode_TransformDecimalToASCII(Py_UNICODE *s, maxchar = 127; for (i = 0; i < length; i++) { - Py_UNICODE ch = s[i]; + Py_UCS4 ch = s[i]; if (ch > 127) { int decimal = Py_UNICODE_TODECIMAL(ch); if (decimal >= 0) @@ -8876,7 +8887,7 @@ PyUnicode_TransformDecimalToASCII(Py_UNICODE *s, data = PyUnicode_DATA(decimal); /* Iterate over code points */ for (i = 0; i < length; i++) { - Py_UNICODE ch = s[i]; + Py_UCS4 ch = s[i]; if (ch > 127) { int decimal = Py_UNICODE_TODECIMAL(ch); if (decimal >= 0) @@ -9630,6 +9641,10 @@ case_operation(PyObject *self, kind = PyUnicode_KIND(self); data = PyUnicode_DATA(self); length = PyUnicode_GET_LENGTH(self); + if ((size_t) length > PY_SSIZE_T_MAX / (3 * sizeof(Py_UCS4))) { + PyErr_SetString(PyExc_OverflowError, "string is too long"); + return NULL; + } tmp = PyMem_MALLOC(sizeof(Py_UCS4) * 3 * length); if (tmp == NULL) return PyErr_NoMemory(); @@ -9677,7 +9692,7 @@ PyUnicode_Join(PyObject *separator, PyObject *seq) PyObject *last_obj; unsigned int kind = 0; - fseq = PySequence_Fast(seq, ""); + fseq = PySequence_Fast(seq, "can only join an iterable"); if (fseq == NULL) { return NULL; } @@ -9866,8 +9881,8 @@ PyUnicode_Join(PyObject *separator, PyObject *seq) Py_UCS4 * to_ = (Py_UCS4 *)((data)) + (start); \ for (; i_ < (length); ++i_, ++to_) *to_ = (value); \ break; \ - default: assert(0); \ } \ + default: assert(0); \ } \ } while (0) @@ -10818,7 +10833,7 @@ PyUnicode_CompareWithASCIIString(PyObject* uni, const char* str) void *data = PyUnicode_DATA(uni); /* Compare Unicode string and source character set string */ for (i = 0; (chr = PyUnicode_READ(kind, data, i)) && str[i]; i++) - if (chr != str[i]) + if (chr != (unsigned char)str[i]) return (chr < (unsigned char)(str[i])) ? -1 : 1; /* This check keeps Python strings that end in '\0' from comparing equal to C strings identical up to that point. */ @@ -11341,7 +11356,6 @@ unicode_getitem(PyObject *self, Py_ssize_t index) void *data; enum PyUnicode_Kind kind; Py_UCS4 ch; - PyObject *res; if (!PyUnicode_Check(self) || PyUnicode_READY(self) == -1) { PyErr_BadArgument(); @@ -11354,17 +11368,7 @@ unicode_getitem(PyObject *self, Py_ssize_t index) kind = PyUnicode_KIND(self); data = PyUnicode_DATA(self); ch = PyUnicode_READ(kind, data, index); - if (ch < 256) - return get_latin1_char(ch); - - res = PyUnicode_New(1, ch); - if (res == NULL) - return NULL; - kind = PyUnicode_KIND(res); - data = PyUnicode_DATA(res); - PyUnicode_WRITE(kind, data, 0, ch); - assert(_PyUnicode_CheckConsistency(res, 1)); - return res; + return unicode_char(ch); } /* Believe it or not, this produces the same value for ASCII strings @@ -11396,7 +11400,6 @@ unicode_hash(PyObject *self) _PyUnicode_HASH(self) = x; return x; } -#undef HASH PyDoc_STRVAR(index__doc__, "S.index(sub[, start[, end]]) -> int\n\ @@ -12332,28 +12335,34 @@ unicode_repr(PyObject *unicode) ikind = PyUnicode_KIND(unicode); for (i = 0; i < isize; i++) { Py_UCS4 ch = PyUnicode_READ(ikind, idata, i); + Py_ssize_t incr = 1; switch (ch) { - case '\'': squote++; osize++; break; - case '"': dquote++; osize++; break; + case '\'': squote++; break; + case '"': dquote++; break; case '\\': case '\t': case '\r': case '\n': - osize += 2; break; + incr = 2; + break; default: /* Fast-path ASCII */ if (ch < ' ' || ch == 0x7f) - osize += 4; /* \xHH */ + incr = 4; /* \xHH */ else if (ch < 0x7f) - osize++; - else if (Py_UNICODE_ISPRINTABLE(ch)) { - osize++; + ; + else if (Py_UNICODE_ISPRINTABLE(ch)) max = ch > max ? ch : max; - } else if (ch < 0x100) - osize += 4; /* \xHH */ + incr = 4; /* \xHH */ else if (ch < 0x10000) - osize += 6; /* \uHHHH */ + incr = 6; /* \uHHHH */ else - osize += 10; /* \uHHHHHHHH */ + incr = 10; /* \uHHHHHHHH */ } + if (osize > PY_SSIZE_T_MAX - incr) { + PyErr_SetString(PyExc_OverflowError, + "string is too long to generate repr"); + return NULL; + } + osize += incr; } quote = '\''; @@ -12887,7 +12896,7 @@ unicode_swapcase(PyObject *self) return case_operation(self, do_swapcase); } -/*[clinic] +/*[clinic input] @staticmethod str.maketrans as unicode_maketrans @@ -12909,10 +12918,12 @@ If there are two arguments, they must be strings of equal length, and in the resulting dictionary, each character in x will be mapped to the character at the same position in y. If there is a third argument, it must be a string, whose characters will be mapped to None in the result. -[clinic]*/ +[clinic start generated code]*/ PyDoc_STRVAR(unicode_maketrans__doc__, -"maketrans(x, y=None, z=None)\n" +"maketrans(x, y=None, z=None, /)\n" +"--\n" +"\n" "Return a translation table usable for str.translate().\n" "\n" "If there is only one argument, it must be a dictionary mapping Unicode\n" @@ -12927,7 +12938,7 @@ PyDoc_STRVAR(unicode_maketrans__doc__, {"maketrans", (PyCFunction)unicode_maketrans, METH_VARARGS|METH_STATIC, unicode_maketrans__doc__}, static PyObject * -unicode_maketrans_impl(void *null, PyObject *x, PyObject *y, PyObject *z); +unicode_maketrans_impl(PyObject *x, PyObject *y, PyObject *z); static PyObject * unicode_maketrans(void *null, PyObject *args) @@ -12941,15 +12952,15 @@ unicode_maketrans(void *null, PyObject *args) "O|UU:maketrans", &x, &y, &z)) goto exit; - return_value = unicode_maketrans_impl(null, x, y, z); + return_value = unicode_maketrans_impl(x, y, z); exit: return return_value; } static PyObject * -unicode_maketrans_impl(void *null, PyObject *x, PyObject *y, PyObject *z) -/*[clinic checksum: 7f76f414a0dfd0c614e0d4717872eeb520516da7]*/ +unicode_maketrans_impl(PyObject *x, PyObject *y, PyObject *z) +/*[clinic end generated code: output=566edf630f77436a input=7bfbf529a293c6c5]*/ { PyObject *new = NULL, *key, *value; Py_ssize_t i = 0; @@ -13519,8 +13530,7 @@ _PyUnicodeWriter_Finish(_PyUnicodeWriter *writer) PyObject *newbuffer; newbuffer = resize_compact(writer->buffer, writer->pos); if (newbuffer == NULL) { - Py_DECREF(writer->buffer); - writer->buffer = NULL; + Py_CLEAR(writer->buffer); return NULL; } writer->buffer = newbuffer; @@ -13885,8 +13895,8 @@ formatfloat(PyObject *v, struct unicode_format_arg_t *arg, * CAUTION: o, x and X conversions on regular ints can never * produce a '-' sign, but can for Python's unbounded ints. */ -static PyObject* -formatlong(PyObject *val, struct unicode_format_arg_t *arg) +PyObject * +_PyUnicode_FormatLong(PyObject *val, int alt, int prec, int type) { PyObject *result = NULL; char *buf; @@ -13896,8 +13906,6 @@ formatlong(PyObject *val, struct unicode_format_arg_t *arg) Py_ssize_t llen; int numdigits; /* len == numnondigits + numdigits */ int numnondigits = 0; - int prec = arg->prec; - int type = arg->ch; /* Avoid exceeding SSIZE_T_MAX */ if (prec > INT_MAX-3) { @@ -13946,7 +13954,7 @@ formatlong(PyObject *val, struct unicode_format_arg_t *arg) if (llen > INT_MAX) { Py_DECREF(result); PyErr_SetString(PyExc_ValueError, - "string too large in _PyBytes_FormatLong"); + "string too large in _PyUnicode_FormatLong"); return NULL; } len = (int)llen; @@ -13956,7 +13964,7 @@ formatlong(PyObject *val, struct unicode_format_arg_t *arg) assert(numdigits > 0); /* Get rid of base marker unless F_ALT */ - if (((arg->flags & F_ALT) == 0 && + if (((alt) == 0 && (type == 'o' || type == 'x' || type == 'X'))) { assert(buf[sign] == '0'); assert(buf[sign+1] == 'x' || buf[sign+1] == 'X' || @@ -14015,7 +14023,7 @@ formatlong(PyObject *val, struct unicode_format_arg_t *arg) return result; } -/* Format an integer. +/* Format an integer or a float as an integer. * Return 1 if the number has been formatted into the writer, * 0 if the number has been formatted into *p_output * -1 and raise an exception on error */ @@ -14031,12 +14039,23 @@ mainformatlong(PyObject *v, if (!PyNumber_Check(v)) goto wrongtype; + /* make sure number is a type of integer for o, x, and X */ if (!PyLong_Check(v)) { - iobj = PyNumber_Long(v); - if (iobj == NULL) { - if (PyErr_ExceptionMatches(PyExc_TypeError)) - goto wrongtype; - return -1; + if (type == 'o' || type == 'x' || type == 'X') { + iobj = PyNumber_Index(v); + if (iobj == NULL) { + if (PyErr_ExceptionMatches(PyExc_TypeError)) + goto wrongtype; + return -1; + } + } + else { + iobj = PyNumber_Long(v); + if (iobj == NULL ) { + if (PyErr_ExceptionMatches(PyExc_TypeError)) + goto wrongtype; + return -1; + } } assert(PyLong_Check(iobj)); } @@ -14080,7 +14099,7 @@ mainformatlong(PyObject *v, return 1; } - res = formatlong(iobj, arg); + res = _PyUnicode_FormatLong(iobj, arg->flags & F_ALT, arg->prec, type); Py_DECREF(iobj); if (res == NULL) return -1; @@ -14088,10 +14107,23 @@ mainformatlong(PyObject *v, return 0; wrongtype: - PyErr_Format(PyExc_TypeError, - "%%%c format: a number is required, " - "not %.200s", - type, Py_TYPE(v)->tp_name); + switch(type) + { + case 'o': + case 'x': + case 'X': + PyErr_Format(PyExc_TypeError, + "%%%c format: an integer is required, " + "not %.200s", + type, Py_TYPE(v)->tp_name); + break; + default: + PyErr_Format(PyExc_TypeError, + "%%%c format: a number is required, " + "not %.200s", + type, Py_TYPE(v)->tp_name); + break; + } return -1; } @@ -14106,8 +14138,18 @@ formatchar(PyObject *v) goto onError; } else { - /* Integer input truncated to a character */ + PyObject *iobj; long x; + /* make sure number is a type of integer */ + if (!PyLong_Check(v)) { + iobj = PyNumber_Index(v); + if (iobj == NULL) { + goto onError; + } + v = iobj; + Py_DECREF(iobj); + } + /* Integer input truncated to a character */ x = PyLong_AsLong(v); if (x == -1 && PyErr_Occurred()) goto onError; @@ -14309,7 +14351,8 @@ unicode_format_arg_parse(struct unicode_formatter_t *ctx, /* Format one argument. Supported conversion specifiers: - "s", "r", "a": any type - - "i", "d", "u", "o", "x", "X": int + - "i", "d", "u": int or float + - "o", "x", "X": int - "e", "E", "f", "F", "g", "G": float - "c": int or str (1 character) @@ -15174,9 +15217,13 @@ unicodeiter_setstate(unicodeiterobject *it, PyObject *state) Py_ssize_t index = PyLong_AsSsize_t(state); if (index == -1 && PyErr_Occurred()) return NULL; - if (index < 0) - index = 0; - it->it_index = index; + if (it->it_seq != NULL) { + if (index < 0) + index = 0; + else if (index > PyUnicode_GET_LENGTH(it->it_seq)) + index = PyUnicode_GET_LENGTH(it->it_seq); /* iterator truncated */ + it->it_index = index; + } Py_RETURN_NONE; } @@ -15351,7 +15398,7 @@ PyUnicode_AsUnicodeCopy(PyObject *unicode) if (u == NULL) return NULL; /* Ensure we won't overflow the size. */ - if (len > ((PY_SSIZE_T_MAX / sizeof(Py_UNICODE)) - 1)) { + if (len > ((PY_SSIZE_T_MAX / (Py_ssize_t)sizeof(Py_UNICODE)) - 1)) { PyErr_NoMemory(); return NULL; } diff --git a/Objects/unicodetype_db.h b/Objects/unicodetype_db.h index 1fdc092a3dd4..0c1e0b6085e7 100644 --- a/Objects/unicodetype_db.h +++ b/Objects/unicodetype_db.h @@ -82,25 +82,31 @@ const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = { {-205, 0, -205, 0, 0, 9993}, {-202, 0, -202, 0, 0, 9993}, {-203, 0, -203, 0, 0, 9993}, + {42319, 0, 42319, 0, 0, 9993}, + {42315, 0, 42315, 0, 0, 9993}, {-207, 0, -207, 0, 0, 9993}, {42280, 0, 42280, 0, 0, 9993}, {42308, 0, 42308, 0, 0, 9993}, {-209, 0, -209, 0, 0, 9993}, {-211, 0, -211, 0, 0, 9993}, {10743, 0, 10743, 0, 0, 9993}, + {42305, 0, 42305, 0, 0, 9993}, {10749, 0, 10749, 0, 0, 9993}, {-213, 0, -213, 0, 0, 9993}, {-214, 0, -214, 0, 0, 9993}, {10727, 0, 10727, 0, 0, 9993}, {-218, 0, -218, 0, 0, 9993}, + {42282, 0, 42282, 0, 0, 9993}, {-69, 0, -69, 0, 0, 9993}, {-217, 0, -217, 0, 0, 9993}, {-71, 0, -71, 0, 0, 9993}, {-219, 0, -219, 0, 0, 9993}, + {42258, 0, 42258, 0, 0, 9993}, {0, 0, 0, 0, 0, 14089}, {0, 0, 0, 0, 0, 5889}, {16777244, 17825818, 16777244, 0, 0, 30216}, {0, 0, 0, 0, 0, 13321}, + {0, 116, 0, 0, 0, 10113}, {0, 38, 0, 0, 0, 10113}, {0, 37, 0, 0, 0, 10113}, {0, 64, 0, 0, 0, 10113}, @@ -122,6 +128,7 @@ const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = { {16777276, 17825850, 16777276, 0, 0, 26377}, {16777279, 17825853, 16777279, 0, 0, 26377}, {7, 0, 7, 0, 0, 9993}, + {-116, 0, -116, 0, 0, 9993}, {0, -60, 0, 0, 0, 10113}, {16777282, 17825856, 16777282, 0, 0, 26377}, {0, -7, 0, 0, 0, 10113}, @@ -280,6 +287,11 @@ const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = { {0, -35332, 0, 0, 0, 10113}, {0, -42280, 0, 0, 0, 10113}, {0, -42308, 0, 0, 0, 10113}, + {0, -42319, 0, 0, 0, 10113}, + {0, -42315, 0, 0, 0, 10113}, + {0, -42305, 0, 0, 0, 10113}, + {0, -42258, 0, 0, 0, 10113}, + {0, -42282, 0, 0, 0, 10113}, {33555038, 18874971, 33555040, 0, 0, 26377}, {33555045, 18874978, 33555047, 0, 0, 26377}, {33555052, 18874985, 33555054, 0, 0, 26377}, @@ -296,6 +308,7 @@ const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = { {0, 0, 0, 0, 0, 5633}, {0, 40, 0, 0, 0, 10113}, {-40, 0, -40, 0, 0, 9993}, + {0, 0, 0, 0, 0, 9344}, }; /* extended case mappings */ @@ -1029,405 +1042,512 @@ static unsigned char index1[] = { 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 128, 129, 130, 131, 132, 133, 134, 34, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, - 71, 145, 146, 147, 148, 149, 71, 71, 71, 71, 71, 71, 150, 71, 151, 152, - 153, 71, 154, 71, 155, 71, 71, 71, 156, 71, 71, 71, 157, 158, 159, 160, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 161, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 34, 34, 34, 34, 34, 34, 162, 71, - 163, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 34, 34, 34, 34, 34, 34, 34, 34, 164, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 34, 34, 34, 34, 165, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 166, 167, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 168, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 64, 169, 170, 171, 172, 71, 173, 71, 174, 175, 176, 177, 178, - 179, 180, 181, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 182, 183, 71, 71, 184, - 185, 186, 187, 188, 71, 189, 190, 191, 192, 193, 194, 195, 196, 65, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 197, 198, - 199, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 87, 200, - 34, 201, 202, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 145, 146, 147, 148, 149, 150, 151, 145, 34, 34, 152, 145, 153, 154, 155, + 156, 157, 158, 159, 160, 161, 145, 145, 145, 162, 145, 145, 145, 163, + 164, 165, 166, 167, 168, 169, 145, 145, 170, 145, 171, 172, 173, 145, + 145, 145, 174, 145, 145, 145, 175, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 34, 34, 34, 34, 34, 34, 34, 176, 177, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 34, 34, 34, 34, 34, 34, 34, 34, 178, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 34, 34, 34, 34, 179, 180, 181, 182, 145, 145, 145, 145, + 145, 145, 183, 184, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 185, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 186, 187, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 64, + 188, 189, 190, 191, 145, 192, 145, 193, 194, 195, 196, 197, 198, 199, + 200, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 34, 201, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 202, 203, 145, 145, 204, 205, 206, 207, 208, 145, 209, 210, 64, + 211, 212, 213, 214, 215, 216, 217, 218, 219, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 220, 221, 222, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 87, 223, 34, 224, 225, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 203, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 204, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 205, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 226, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 227, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 228, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 206, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 229, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 207, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 208, 34, 209, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 34, 203, 34, 34, 209, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 210, 71, 211, 212, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 127, 127, 127, 127, + 34, 34, 34, 34, 230, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 231, 34, 232, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 34, 226, 34, 34, 232, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 233, 145, 234, 235, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, @@ -1463,8 +1583,8 @@ static unsigned char index1[] = { 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 236, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 213, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, @@ -1500,7 +1620,7 @@ static unsigned char index1[] = { 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 213, + 127, 127, 127, 127, 236, }; static unsigned short index2[] = { @@ -1535,106 +1655,107 @@ static unsigned short index2[] = { 31, 30, 31, 30, 31, 30, 31, 30, 31, 64, 20, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 20, 20, 20, 20, 20, 20, 65, 30, 31, 66, 67, 68, 68, 30, 31, 69, 70, 71, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 72, 73, 74, 75, 76, 20, 77, 77, 20, 78, 20, 79, 20, 20, 20, - 20, 77, 20, 20, 80, 20, 81, 82, 20, 83, 84, 20, 85, 20, 20, 20, 84, 20, - 86, 87, 20, 20, 88, 20, 20, 20, 20, 20, 20, 20, 89, 20, 20, 90, 20, 20, - 90, 20, 20, 20, 20, 90, 91, 92, 92, 93, 20, 20, 20, 20, 20, 94, 20, 55, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 96, 96, 96, 96, 96, 96, 96, 95, 95, 6, 6, 6, 6, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 95, 95, - 95, 95, 95, 6, 6, 6, 6, 6, 6, 6, 96, 6, 96, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 31, 30, 31, 72, 73, 74, 75, 76, 20, 77, 77, 20, 78, 20, 79, 80, 20, 20, + 20, 77, 81, 20, 82, 20, 83, 84, 20, 85, 86, 20, 87, 88, 20, 20, 86, 20, + 89, 90, 20, 20, 91, 20, 20, 20, 20, 20, 20, 20, 92, 20, 20, 93, 20, 20, + 93, 20, 20, 20, 94, 93, 95, 96, 96, 97, 20, 20, 20, 20, 20, 98, 20, 55, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 99, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 100, 100, 100, 100, 100, 100, 100, + 100, 100, 101, 101, 101, 101, 101, 101, 101, 100, 100, 6, 6, 6, 6, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 100, 100, 100, 100, 100, 6, 6, 6, 6, 6, 6, 6, + 101, 6, 101, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 102, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 97, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 30, 31, 30, 31, 96, 6, 30, 31, 0, 0, - 98, 50, 50, 50, 5, 0, 0, 0, 0, 0, 6, 6, 99, 25, 100, 100, 100, 0, 101, 0, - 102, 102, 103, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 104, 105, 105, 105, - 106, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 107, 19, 19, 19, 19, 19, 19, 19, 19, 19, 108, 109, 109, 110, 111, 112, - 113, 113, 113, 114, 115, 116, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 117, 118, 119, 20, - 120, 121, 5, 30, 31, 122, 30, 31, 20, 64, 64, 64, 123, 123, 123, 123, - 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 17, 17, 17, + 25, 25, 30, 31, 30, 31, 101, 6, 30, 31, 0, 0, 103, 50, 50, 50, 5, 104, 0, + 0, 0, 0, 6, 6, 105, 25, 106, 106, 106, 0, 107, 0, 108, 108, 109, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 110, 111, 111, 111, 112, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 113, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 114, 115, 115, 116, 117, 118, 119, 119, 119, 120, 121, + 122, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 123, 124, 125, 126, 127, 128, 5, 30, 31, 129, + 30, 31, 20, 64, 64, 64, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, + 130, 130, 130, 130, 130, 130, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 124, 124, 124, 124, 124, 124, 124, 124, 124, - 124, 124, 124, 124, 124, 124, 124, 30, 31, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 30, 31, 30, 31, 5, 25, 25, 25, 25, 25, 6, 6, 30, 31, 30, 31, + 17, 17, 17, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 5, + 25, 25, 25, 25, 25, 6, 6, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 125, 30, 31, 30, - 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 126, 30, 31, 30, 31, 30, 31, + 30, 31, 30, 31, 30, 31, 132, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 133, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 0, 0, 96, 5, 5, 5, 5, 5, 5, - 0, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 129, 0, 5, 5, 0, 0, 0, - 0, 5, 0, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 0, 134, 134, 134, 134, 134, 134, + 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, + 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, + 134, 134, 134, 134, 0, 0, 101, 5, 5, 5, 5, 5, 5, 0, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 136, 0, 5, 5, 0, 0, 5, 5, 5, 0, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 5, 25, 5, 25, 25, 5, 25, 25, - 5, 25, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, - 0, 0, 0, 55, 55, 55, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 21, - 21, 21, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 5, 21, 0, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 96, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, 5, 5, 5, 5, 55, 55, 25, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 5, 25, 5, 25, 25, 5, 25, 25, 5, 25, 0, 0, 0, 0, + 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 55, 55, + 55, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21, 21, 21, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 5, + 21, 0, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 101, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 5, 5, 5, 5, 55, 55, 25, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 5, 55, 25, 25, 25, 25, 25, 25, 25, 21, 5, 25, 25, 25, - 25, 25, 25, 96, 96, 25, 25, 5, 25, 25, 25, 25, 55, 55, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 55, 55, 55, 5, 5, 55, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 0, 21, 55, 25, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 0, 0, 55, 55, 55, 55, 55, 55, 55, + 55, 5, 55, 25, 25, 25, 25, 25, 25, 25, 21, 5, 25, 25, 25, 25, 25, 25, + 101, 101, 25, 25, 5, 25, 25, 25, 25, 55, 55, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 55, 55, 55, 5, 5, 55, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 0, 21, 55, 25, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 16, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 25, 25, 25, 25, 25, 25, 25, 25, 25, 96, 96, 5, 5, 5, 5, 96, - 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, 96, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 96, 25, 25, 25, 96, 25, 25, 25, 25, 25, 0, 0, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, - 25, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 101, 101, 5, 5, 5, 5, 101, 0, 0, 0, + 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 25, 25, 25, 25, 101, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 101, 25, 25, 25, 101, 25, 25, 25, 25, 25, 0, 0, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 0, 0, + 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 0, 25, 25, 25, 18, 55, 55, 55, 55, 55, 55, 55, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 18, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 18, 25, 55, 18, 18, 18, - 25, 25, 25, 25, 25, 25, 25, 25, 18, 18, 18, 18, 25, 18, 18, 55, 25, 25, - 25, 25, 25, 25, 25, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 5, 5, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 5, 96, 55, 55, 55, 55, 55, 55, 0, - 55, 55, 55, 55, 55, 55, 55, 0, 25, 18, 18, 0, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 18, 25, 55, 18, 18, 18, 25, + 25, 25, 25, 25, 25, 25, 25, 18, 18, 18, 18, 25, 18, 18, 55, 25, 25, 25, + 25, 25, 25, 25, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 5, 5, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 16, 5, 101, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 25, 18, 18, 0, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, 0, 0, 0, 55, 55, 55, 55, 0, 0, 25, 55, 18, 18, 18, 25, 25, 25, 25, 0, @@ -1666,20 +1787,20 @@ static unsigned short index2[] = { 18, 18, 25, 18, 18, 0, 0, 0, 18, 18, 18, 0, 18, 18, 18, 25, 0, 0, 55, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 27, 27, 27, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, - 0, 0, 18, 18, 18, 0, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 0, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, - 55, 55, 55, 0, 0, 0, 55, 25, 25, 25, 18, 18, 18, 18, 0, 25, 25, 25, 0, - 25, 25, 25, 25, 0, 0, 0, 0, 0, 0, 0, 25, 25, 0, 55, 55, 0, 0, 0, 0, 0, 0, - 55, 55, 25, 25, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, - 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 5, 0, 0, 18, 18, 0, 55, 55, 55, 55, - 55, 55, 55, 55, 0, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 0, 0, 25, 55, 18, 25, 18, - 18, 18, 18, 18, 0, 25, 18, 18, 0, 18, 18, 25, 25, 0, 0, 0, 0, 0, 0, 0, - 18, 18, 0, 0, 0, 0, 0, 0, 0, 55, 0, 55, 55, 25, 25, 0, 0, 7, 8, 9, 10, + 0, 25, 18, 18, 18, 0, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 0, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 0, 0, 0, 55, 25, 25, 25, 18, 18, 18, 18, 0, 25, 25, 25, + 0, 25, 25, 25, 25, 0, 0, 0, 0, 0, 0, 0, 25, 25, 0, 55, 55, 0, 0, 0, 0, 0, + 0, 55, 55, 25, 25, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, + 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 5, 0, 25, 18, 18, 0, 55, 55, 55, + 55, 55, 55, 55, 55, 0, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 0, 0, 25, 55, 18, 25, + 18, 18, 18, 18, 18, 0, 25, 18, 18, 0, 18, 18, 25, 25, 0, 0, 0, 0, 0, 0, + 0, 18, 18, 0, 0, 0, 0, 0, 0, 0, 55, 0, 55, 55, 25, 25, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 18, 18, 0, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 0, 55, + 0, 25, 18, 18, 0, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 55, 18, 18, 18, 25, 25, 25, 25, 0, 18, 18, 18, 0, @@ -1690,50 +1811,48 @@ static unsigned short index2[] = { 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 25, 0, 0, 0, 0, 18, 18, 18, 25, - 25, 25, 0, 25, 0, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 25, 25, 0, 25, 0, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 18, 18, 5, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 55, 130, 25, 25, - 25, 25, 25, 25, 25, 0, 0, 0, 0, 5, 55, 55, 55, 55, 55, 55, 96, 25, 25, - 25, 25, 25, 25, 25, 25, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 5, 5, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 0, 55, 0, 0, 55, 55, 0, 55, - 0, 0, 55, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, - 55, 0, 55, 55, 55, 0, 55, 0, 55, 0, 0, 55, 55, 0, 55, 55, 55, 55, 25, 55, - 130, 25, 25, 25, 25, 25, 25, 0, 25, 25, 55, 0, 0, 55, 55, 55, 55, 55, 0, - 96, 0, 25, 25, 25, 25, 25, 25, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 0, 0, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 25, 25, 5, 5, 5, 5, 5, 5, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 16, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 5, 25, 5, 25, 5, 25, 5, 5, 5, 5, 18, 18, 55, 55, 55, 55, 55, 55, 55, 55, - 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 55, 137, + 25, 25, 25, 25, 25, 25, 25, 0, 0, 0, 0, 5, 55, 55, 55, 55, 55, 55, 101, + 25, 25, 25, 25, 25, 25, 25, 25, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 0, 55, 0, 0, 55, 55, + 0, 55, 0, 0, 55, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, + 55, 55, 0, 55, 55, 55, 0, 55, 0, 55, 0, 0, 55, 55, 0, 55, 55, 55, 55, 25, + 55, 137, 25, 25, 25, 25, 25, 25, 0, 25, 25, 55, 0, 0, 55, 55, 55, 55, 55, + 0, 101, 0, 25, 25, 25, 25, 25, 25, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 0, 0, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 25, 25, 5, 5, 5, 5, 5, 5, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 5, 25, 5, 25, 5, 25, 5, 5, 5, 5, 18, 18, 55, 55, 55, 55, 55, 55, 55, + 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 0, 0, 0, 0, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 18, 25, 25, 25, 25, 25, 5, 25, 25, 55, 55, 55, 55, 55, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 0, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 55, 55, 0, 0, 0, 0, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 18, 25, 25, 25, 25, 25, 5, 25, 25, 55, 55, 55, 55, 55, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 0, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 0, 5, 5, 5, 5, 5, 5, 5, 5, 25, 5, 5, 5, - 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 0, 5, 5, 5, 5, 5, 5, 5, 5, 25, 5, 5, + 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 18, 25, 25, 25, 25, 18, - 25, 25, 25, 25, 25, 25, 18, 25, 25, 18, 18, 25, 25, 55, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 5, 5, 5, 5, 5, 5, 55, 55, 55, 55, 55, 55, 18, 18, 25, - 25, 55, 55, 55, 55, 25, 25, 25, 55, 18, 18, 18, 55, 55, 18, 18, 18, 18, - 18, 18, 18, 55, 55, 55, 25, 25, 25, 25, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 25, 18, 18, 25, 25, 18, 18, 18, 18, 18, 18, 25, 55, - 18, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 18, 18, 25, 5, 5, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 0, 131, 0, 0, 0, 0, 0, 131, 0, 0, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 5, 96, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 18, 25, 25, 25, 25, + 18, 25, 25, 25, 25, 25, 25, 18, 25, 25, 18, 18, 25, 25, 55, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 5, 5, 5, 5, 5, 5, 55, 55, 55, 55, 55, 55, 18, 18, + 25, 25, 55, 55, 55, 55, 25, 25, 25, 55, 18, 18, 18, 55, 55, 18, 18, 18, + 18, 18, 18, 18, 55, 55, 55, 25, 25, 25, 25, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 25, 18, 18, 25, 25, 18, 18, 18, 18, 18, 18, 25, + 55, 18, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 18, 18, 25, 5, 5, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 0, 138, 0, 0, 0, 0, 0, 138, + 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 5, 101, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, @@ -1742,26 +1861,28 @@ static unsigned short index2[] = { 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, - 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, 0, 55, 55, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, + 55, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, 0, 55, 55, 55, 55, + 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 0, 0, 55, 55, 55, 55, - 55, 55, 55, 0, 55, 0, 55, 55, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 0, 0, 55, 55, 55, + 55, 55, 55, 55, 0, 55, 0, 55, 55, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 0, + 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 25, 25, 25, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 132, 133, 134, 135, 136, 137, 138, 139, 140, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, - 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 25, 25, 25, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 139, 140, 141, 142, 143, 144, 145, 146, 147, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, @@ -1786,28 +1907,28 @@ static unsigned short index2[] = { 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 5, 5, 5, 141, 141, 141, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 0, 55, 55, 55, 55, 25, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, - 25, 25, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, - 55, 55, 0, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 18, 25, 25, 25, - 25, 25, 25, 25, 18, 18, 18, 18, 18, 18, 18, 18, 25, 18, 18, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 5, 5, 5, 96, 5, 5, 5, 5, 55, 25, 0, 0, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 25, 25, 25, 21, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 96, + 55, 55, 55, 55, 55, 55, 55, 5, 5, 5, 148, 148, 148, 55, 55, 55, 55, 55, + 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 0, 55, 55, 55, 55, 25, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 25, 25, 25, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, + 55, 55, 55, 0, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 18, 25, 25, + 25, 25, 25, 25, 25, 18, 18, 18, 18, 18, 18, 18, 18, 25, 18, 18, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 5, 5, 5, 101, 5, 5, 5, 5, 55, 25, 0, + 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 25, 25, 25, 21, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, + 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 101, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, - 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, + 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 55, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, @@ -1815,71 +1936,73 @@ static unsigned short index2[] = { 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 25, 25, 25, - 18, 18, 18, 18, 25, 25, 18, 18, 18, 0, 0, 0, 0, 18, 18, 25, 18, 18, 18, - 18, 18, 18, 25, 25, 25, 0, 0, 0, 0, 5, 0, 0, 0, 5, 5, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, - 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 25, 25, + 25, 18, 18, 18, 18, 25, 25, 18, 18, 18, 0, 0, 0, 0, 18, 18, 25, 18, 18, + 18, 18, 18, 18, 25, 25, 25, 0, 0, 0, 0, 5, 0, 0, 0, 5, 5, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 0, 0, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 55, 55, 55, 55, 55, 55, 55, 18, 18, 0, 0, 0, 0, 0, 0, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 132, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, + 55, 55, 55, 55, 55, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 55, 55, 55, 55, 55, 55, 55, 18, 18, 0, 0, 0, + 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 139, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 25, 25, 18, 18, 25, 0, 0, 5, 5, 55, 55, 55, + 5, 5, 5, 5, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 18, 18, 25, 0, 0, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 25, 18, 25, - 25, 25, 25, 25, 25, 25, 0, 25, 18, 25, 18, 18, 25, 25, 25, 25, 25, 25, - 25, 25, 18, 18, 18, 18, 18, 18, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 0, 0, 25, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 96, 5, - 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 25, + 18, 25, 25, 25, 25, 25, 25, 25, 0, 25, 18, 25, 18, 18, 25, 25, 25, 25, + 25, 25, 25, 25, 18, 18, 18, 18, 18, 18, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 0, 0, 25, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, + 5, 101, 5, 5, 5, 5, 5, 5, 0, 0, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25, 25, 18, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, + 25, 25, 25, 18, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 18, 25, 25, 25, 25, 25, 18, 25, - 18, 18, 18, 18, 18, 25, 18, 18, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 25, 25, 25, 25, 25, 25, 25, 25, 25, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 0, 0, 0, 25, 25, 18, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 18, 25, + 25, 25, 25, 25, 18, 25, 18, 18, 18, 18, 18, 25, 18, 18, 55, 55, 55, 55, + 55, 55, 55, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 25, 25, 18, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 18, 25, 25, 25, 25, 18, 18, 25, 25, 18, 25, 18, 18, 55, 55, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 18, 25, 25, 25, 25, 18, 18, 25, 25, 18, 25, + 25, 25, 55, 55, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 18, 25, - 25, 18, 18, 18, 25, 18, 25, 25, 25, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, - 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 18, 18, 18, 18, 18, 18, 18, 18, 25, 25, 25, 25, 25, 25, 25, 25, 18, - 18, 25, 25, 0, 0, 0, 5, 5, 5, 5, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 0, 0, 0, 55, 55, 55, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 55, 55, 55, 55, + 55, 55, 55, 25, 18, 25, 25, 18, 18, 18, 25, 18, 25, 25, 25, 18, 18, 0, 0, + 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 96, 96, 96, 96, 96, 96, 5, 5, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 55, 55, 55, 55, 55, 55, 55, 18, 18, 18, 18, 18, 18, 18, 18, 25, 25, 25, + 25, 25, 25, 25, 25, 18, 18, 25, 25, 0, 0, 0, 5, 5, 5, 5, 5, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 0, 0, 0, 55, 55, 55, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 101, 101, 101, + 101, 101, 101, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, - 0, 0, 0, 0, 25, 25, 25, 5, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 18, 25, 25, 25, 25, 25, 25, 25, 55, 55, 55, 55, 25, 55, 55, 55, - 55, 18, 18, 25, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 95, 142, 20, 20, 20, 143, 20, 20, 20, 20, 20, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, + 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25, 5, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 18, 25, 25, 25, 25, 25, 25, 25, + 55, 55, 55, 55, 25, 55, 55, 55, 55, 18, 18, 25, 55, 55, 0, 25, 25, 0, 0, + 0, 0, 0, 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 100, 100, 100, 100, 100, 100, + 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, + 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, + 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, + 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, + 100, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 100, 149, 20, + 20, 20, 150, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 100, 100, 100, + 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, + 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, + 100, 100, 100, 100, 100, 100, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25, 25, 30, 31, 30, 31, 30, 31, 30, + 25, 25, 25, 25, 25, 25, 25, 0, 0, 0, 0, 0, 0, 25, 25, 25, 25, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, @@ -1887,51 +2010,51 @@ static unsigned short index2[] = { 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 144, - 145, 146, 147, 148, 149, 20, 20, 150, 20, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 151, 151, - 151, 151, 151, 151, 151, 151, 152, 152, 152, 152, 152, 152, 152, 152, - 151, 151, 151, 151, 151, 151, 0, 0, 152, 152, 152, 152, 152, 152, 0, 0, - 151, 151, 151, 151, 151, 151, 151, 151, 152, 152, 152, 152, 152, 152, - 152, 152, 151, 151, 151, 151, 151, 151, 151, 151, 152, 152, 152, 152, - 152, 152, 152, 152, 151, 151, 151, 151, 151, 151, 0, 0, 152, 152, 152, - 152, 152, 152, 0, 0, 153, 151, 154, 151, 155, 151, 156, 151, 0, 152, 0, - 152, 0, 152, 0, 152, 151, 151, 151, 151, 151, 151, 151, 151, 152, 152, - 152, 152, 152, 152, 152, 152, 157, 157, 158, 158, 158, 158, 159, 159, - 160, 160, 161, 161, 162, 162, 0, 0, 163, 164, 165, 166, 167, 168, 169, - 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, - 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, - 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 151, - 151, 211, 212, 213, 0, 214, 215, 152, 152, 216, 216, 217, 6, 218, 6, 6, - 6, 219, 220, 221, 0, 222, 223, 224, 224, 224, 224, 225, 6, 6, 6, 151, - 151, 226, 227, 0, 0, 228, 229, 152, 152, 230, 230, 0, 6, 6, 6, 151, 151, - 231, 232, 233, 119, 234, 235, 152, 152, 236, 236, 122, 6, 6, 6, 0, 0, - 237, 238, 239, 0, 240, 241, 242, 242, 243, 243, 244, 6, 6, 0, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 21, 21, 21, 21, 21, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 6, 3, 3, 21, 21, 21, 21, 21, 2, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 18, 18, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 18, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 21, - 21, 21, 21, 21, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 245, 95, 0, 0, - 246, 247, 248, 249, 250, 251, 5, 5, 5, 5, 5, 95, 245, 26, 22, 23, 246, - 247, 248, 249, 250, 251, 5, 5, 5, 5, 5, 0, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 6, 6, 6, 6, 25, 6, 6, 6, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 113, 5, 5, - 5, 5, 113, 5, 5, 20, 113, 113, 113, 20, 20, 113, 113, 113, 20, 5, 113, 5, - 5, 252, 113, 113, 113, 113, 113, 5, 5, 5, 5, 5, 5, 113, 5, 253, 5, 113, - 5, 254, 255, 113, 113, 252, 20, 113, 113, 256, 113, 20, 55, 55, 55, 55, - 20, 5, 5, 20, 20, 113, 113, 5, 5, 5, 5, 5, 113, 20, 20, 20, 20, 5, 5, 5, - 5, 257, 5, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, - 258, 258, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, - 259, 259, 259, 259, 141, 141, 141, 30, 31, 141, 141, 141, 141, 27, 0, 0, - 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 151, 152, 153, 154, 155, 156, 20, 20, 157, 20, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 158, 158, 158, 158, 158, 158, 158, 158, 159, 159, 159, 159, + 159, 159, 159, 159, 158, 158, 158, 158, 158, 158, 0, 0, 159, 159, 159, + 159, 159, 159, 0, 0, 158, 158, 158, 158, 158, 158, 158, 158, 159, 159, + 159, 159, 159, 159, 159, 159, 158, 158, 158, 158, 158, 158, 158, 158, + 159, 159, 159, 159, 159, 159, 159, 159, 158, 158, 158, 158, 158, 158, 0, + 0, 159, 159, 159, 159, 159, 159, 0, 0, 160, 158, 161, 158, 162, 158, 163, + 158, 0, 159, 0, 159, 0, 159, 0, 159, 158, 158, 158, 158, 158, 158, 158, + 158, 159, 159, 159, 159, 159, 159, 159, 159, 164, 164, 165, 165, 165, + 165, 166, 166, 167, 167, 168, 168, 169, 169, 0, 0, 170, 171, 172, 173, + 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, + 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, + 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, + 216, 217, 158, 158, 218, 219, 220, 0, 221, 222, 159, 159, 223, 223, 224, + 6, 225, 6, 6, 6, 226, 227, 228, 0, 229, 230, 231, 231, 231, 231, 232, 6, + 6, 6, 158, 158, 233, 234, 0, 0, 235, 236, 159, 159, 237, 237, 0, 6, 6, 6, + 158, 158, 238, 239, 240, 125, 241, 242, 159, 159, 243, 243, 129, 6, 6, 6, + 0, 0, 244, 245, 246, 0, 247, 248, 249, 249, 250, 250, 251, 6, 6, 0, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 21, 21, 21, 21, 21, 5, 5, 5, 5, 5, 5, 5, 5, 6, + 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 6, 3, 3, 21, 21, 21, 21, 21, 2, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 18, 18, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 18, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, + 21, 21, 21, 21, 21, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 252, 100, + 0, 0, 253, 254, 255, 256, 257, 258, 5, 5, 5, 5, 5, 100, 252, 26, 22, 23, + 253, 254, 255, 256, 257, 258, 5, 5, 5, 5, 5, 0, 100, 100, 100, 100, 100, + 100, 100, 100, 100, 100, 100, 100, 100, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 6, 6, 6, 6, 25, 6, 6, 6, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5, 5, 119, 5, 5, 5, 5, 119, 5, 5, 20, 119, 119, 119, 20, 20, 119, 119, + 119, 20, 5, 119, 5, 5, 259, 119, 119, 119, 119, 119, 5, 5, 5, 5, 5, 5, + 119, 5, 260, 5, 119, 5, 261, 262, 119, 119, 259, 20, 119, 119, 263, 119, + 20, 55, 55, 55, 55, 20, 5, 5, 20, 20, 119, 119, 5, 5, 5, 5, 5, 119, 20, + 20, 20, 20, 5, 5, 5, 5, 264, 5, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 265, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 266, 266, 266, 266, 266, 266, 266, 266, + 266, 266, 266, 266, 266, 266, 266, 266, 148, 148, 148, 30, 31, 148, 148, + 148, 148, 27, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, @@ -1946,134 +2069,134 @@ static unsigned short index2[] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 22, 23, 246, 247, 248, 249, 250, - 251, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 26, 22, 23, 246, 247, - 248, 249, 250, 251, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 26, 22, - 23, 246, 247, 248, 249, 250, 251, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, - 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 261, - 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, - 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 245, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 26, 22, 23, 246, 247, 248, 249, 250, 251, 27, - 245, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 22, 23, 253, + 254, 255, 256, 257, 258, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 26, + 22, 23, 253, 254, 255, 256, 257, 258, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 26, 22, 23, 253, 254, 255, 256, 257, 258, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, + 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, + 267, 267, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 252, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 26, 22, 23, 253, 254, 255, + 256, 257, 258, 27, 252, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 26, - 22, 23, 246, 247, 248, 249, 250, 251, 27, 26, 22, 23, 246, 247, 248, 249, - 250, 251, 27, 26, 22, 23, 246, 247, 248, 249, 250, 251, 27, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 26, 22, 23, 253, 254, 255, 256, 257, 258, 27, 26, 22, + 23, 253, 254, 255, 256, 257, 258, 27, 26, 22, 23, 253, 254, 255, 256, + 257, 258, 27, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, + 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, + 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, + 134, 134, 134, 134, 134, 134, 134, 134, 134, 0, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 0, + 30, 31, 269, 270, 271, 272, 273, 30, 31, 30, 31, 30, 31, 274, 275, 276, + 277, 20, 30, 31, 20, 30, 31, 20, 20, 20, 20, 20, 100, 100, 278, 278, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 20, 5, 5, 5, 5, 5, 5, 30, 31, 30, 31, + 25, 25, 25, 30, 31, 0, 0, 0, 0, 0, 5, 5, 5, 5, 27, 5, 5, 279, 279, 279, + 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, + 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, + 279, 279, 279, 279, 279, 279, 279, 0, 279, 0, 0, 0, 0, 0, 279, 0, 0, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 0, 0, 0, 0, 0, 0, 0, 101, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 25, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, + 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, + 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, + 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, + 55, 55, 0, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 280, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 0, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 0, 30, 31, 262, 263, - 264, 265, 266, 30, 31, 30, 31, 30, 31, 267, 268, 269, 270, 20, 30, 31, - 20, 30, 31, 20, 20, 20, 20, 20, 95, 95, 271, 271, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 20, 5, 5, 5, 5, 5, 5, 30, 31, 30, 31, 25, 25, 25, 30, 31, - 0, 0, 0, 0, 0, 5, 5, 5, 5, 27, 5, 5, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 0, 272, 0, 0, 0, 0, 0, 272, 0, 0, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, - 0, 96, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, - 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, - 55, 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, - 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 0, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 273, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 2, 5, 5, 5, 5, 96, 55, 141, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 141, - 141, 141, 141, 141, 141, 141, 141, 141, 25, 25, 25, 25, 18, 18, 5, 96, - 96, 96, 96, 96, 5, 5, 141, 141, 141, 96, 55, 5, 5, 5, 0, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 2, 5, + 5, 5, 5, 101, 55, 148, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 148, 148, 148, 148, 148, 148, 148, 148, 148, 25, + 25, 25, 25, 18, 18, 5, 101, 101, 101, 101, 101, 5, 5, 148, 148, 148, 101, + 55, 5, 5, 5, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 25, 25, 6, 6, 96, 96, 55, - 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 0, 0, 25, 25, 6, 6, 101, 101, 55, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 5, 96, 96, 96, 55, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 5, 101, 101, 101, 55, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 0, 5, 5, 27, 27, 27, 27, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 5, 5, 27, 27, 27, 27, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, + 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 27, 27, 27, 27, 27, 27, 27, 27, 5, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 27, 27, 27, 27, 27, 27, 27, 27, 5, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 55, 55, 55, - 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 5, 5, 5, 5, 5, 5, 5, 5, 0, 55, 55, 55, 55, 55, 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, @@ -2082,7 +2205,7 @@ static unsigned short index2[] = { 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, @@ -2091,55 +2214,56 @@ static unsigned short index2[] = { 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 274, 55, 55, 274, 55, 55, 55, 274, 55, 274, 55, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 281, + 55, 55, 281, 55, 55, 55, 281, 55, 281, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 281, 55, 55, 55, + 55, 55, 55, 55, 281, 55, 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 281, 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 274, 55, 274, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 281, 55, 55, 55, 55, 55, 55, 55, 55, 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 274, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, - 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, + 55, 55, 55, 281, 55, 281, 55, 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 274, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 281, 55, 281, 281, 281, 55, 55, 55, 55, 55, 55, 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 274, 274, 274, 55, 55, - 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 274, 274, 274, 274, + 55, 55, 55, 55, 55, 281, 281, 281, 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, @@ -2147,8 +2271,8 @@ static unsigned short index2[] = { 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, @@ -2156,24 +2280,23 @@ static unsigned short index2[] = { 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, - 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 281, 55, 55, 55, 55, 55, 55, 55, 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 274, 274, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 274, 274, 274, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 281, 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 281, 281, 281, 55, 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, @@ -2185,646 +2308,791 @@ static unsigned short index2[] = { 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 274, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 281, 55, 55, 55, 55, + 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, - 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 281, 55, 55, 55, 55, 55, 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 96, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 101, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 96, 96, 96, 96, 96, 96, 5, 5, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 96, 5, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 55, 55, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 101, 101, + 101, 101, 101, 101, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 101, 5, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 55, 25, 6, 6, 6, 5, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 5, 101, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 55, 25, 6, 6, 6, 5, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 5, 96, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 0, 0, 0, 0, 0, 0, 0, 25, 55, + 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 100, 100, 0, 25, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, 25, 25, 5, 5, 5, 5, 5, 5, 0, 0, - 0, 0, 0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 96, 96, 96, 96, 96, 96, 96, 96, 96, 6, 6, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 20, 20, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 95, 20, 20, 20, 20, 20, 20, 20, 20, 30, 31, 30, 31, 275, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 96, 6, 6, 30, 31, 276, 20, 0, 30, 31, 30, - 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 277, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 25, 25, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, + 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 6, 6, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 20, 20, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 100, 20, 20, 20, 20, 20, 20, 20, 20, 30, 31, 30, 31, 282, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 101, 6, 6, 30, 31, 283, 20, 0, 30, 31, 30, + 31, 20, 20, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 284, 285, 286, 287, 0, 0, 288, 289, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 95, 20, 55, 55, 55, 55, 55, 55, 55, 25, - 55, 55, 55, 25, 55, 55, 55, 55, 25, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 18, 25, 25, - 18, 5, 5, 5, 5, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 5, 5, 5, 5, 0, 0, 0, - 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 100, 100, 20, 55, 55, + 55, 55, 55, 55, 55, 25, 55, 55, 55, 25, 55, 55, 55, 55, 25, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 18, 18, 25, 25, 18, 5, 5, 5, 5, 0, 0, 0, 0, 27, 27, 27, 27, 27, + 27, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 55, 55, 55, 55, 55, 55, 5, 5, 5, 55, - 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 25, 25, 25, 25, 25, 25, 25, 25, 5, 5, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 25, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 55, 55, + 55, 55, 55, 55, 5, 5, 5, 55, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, 25, 25, 25, + 25, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 18, 18, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 25, - 25, 25, 18, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 0, 0, 0, 25, 25, 25, 18, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 18, 18, 25, - 25, 25, 25, 18, 18, 25, 18, 18, 18, 18, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 0, 96, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 5, 5, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, 25, 25, 18, 18, 25, - 25, 18, 18, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 25, 55, 55, - 55, 55, 55, 55, 55, 55, 25, 18, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 0, 0, 5, 5, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 96, 55, 55, 55, 55, 55, 55, 5, 5, 5, 55, 18, 0, 0, 0, 0, 55, + 55, 55, 55, 25, 18, 18, 25, 25, 25, 25, 18, 18, 25, 18, 18, 18, 18, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 101, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 0, 0, 0, 0, 5, 5, 55, 55, 55, 55, 55, 25, 101, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 55, 55, 55, 55, 55, + 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, 25, 25, 18, 18, 25, 25, 18, 18, + 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 25, 55, 55, 55, 55, 55, + 55, 55, 55, 25, 18, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 5, + 5, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 101, 55, 55, 55, 55, 55, 55, 5, 5, 5, 55, 18, 25, 18, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 55, 25, 25, 25, 55, 55, - 25, 25, 55, 55, 55, 55, 55, 25, 25, 55, 25, 55, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 96, 5, 5, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 25, 25, 18, 18, 5, 5, 55, 96, 96, - 18, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 0, 0, 55, - 55, 55, 55, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 55, 25, 25, 25, 55, 55, 25, 25, + 55, 55, 55, 55, 55, 25, 25, 55, 25, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 101, 5, 5, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 18, 25, 25, 18, 18, 5, 5, 55, 101, 101, 18, + 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 0, 0, 55, 55, + 55, 55, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 0, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 6, 100, 100, 100, 100, 0, 0, 0, 0, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 18, 25, - 18, 18, 25, 18, 18, 5, 18, 25, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 18, 25, 18, 18, 25, 18, 18, 5, + 18, 25, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 1, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, - 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 281, 55, 55, 55, 55, 55, 55, 55, 281, 55, 55, 55, 55, 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 274, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 281, 55, 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 278, 279, 280, 281, 282, 283, 284, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 285, 286, 287, 288, 289, 0, 0, 0, 0, 0, 55, 25, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 0, 55, 0, 55, 55, 0, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 290, + 291, 292, 293, 294, 295, 296, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 297, + 298, 299, 300, 301, 0, 0, 0, 0, 0, 55, 25, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, + 55, 55, 55, 55, 0, 55, 0, 55, 55, 0, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 302, 302, 302, + 302, 302, 302, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 290, 290, 290, 290, 290, 290, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 290, 290, 5, 5, 0, 0, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 25, 25, - 25, 25, 25, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 18, 18, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 18, 18, - 18, 5, 5, 6, 0, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 0, 5, 5, 5, 5, 0, 0, 0, 0, 290, 55, 290, 55, 290, 0, 290, 55, 290, 55, - 290, 55, 290, 55, 290, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 302, 302, 5, 5, 0, + 0, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 5, 5, + 5, 6, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 0, 0, 5, 5, 5, 18, 18, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 18, 18, 18, 5, 5, 6, 0, 5, + 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 0, + 0, 0, 0, 302, 55, 302, 55, 302, 0, 302, 55, 302, 55, 302, 55, 302, 55, + 302, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 0, 0, 21, 0, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, - 5, 6, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 6, 5, 5, 5, 5, 5, 5, 17, + 55, 0, 0, 21, 0, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 6, 5, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 6, 5, 5, 5, 5, 5, 5, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 5, 5, 5, 6, 18, 6, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 96, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 291, 291, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 55, 55, 55, 55, 55, 55, 0, - 0, 55, 55, 55, 55, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 0, 0, 55, 55, - 55, 0, 0, 0, 5, 5, 5, 6, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 21, 21, 21, 5, 5, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 0, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 17, 17, 5, 5, 5, 6, 18, 6, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 101, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 303, 303, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 0, 0, 0, 55, 55, 55, 55, 55, 55, 0, 0, 55, 55, 55, 55, + 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 0, 0, 55, 55, 55, 0, 0, 0, 5, 5, 5, + 6, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, + 21, 5, 5, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 0, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, - 0, 0, 5, 5, 5, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 5, 5, 5, 0, 0, 0, + 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 141, 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 27, 27, 27, 27, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 27, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 27, 27, 27, 27, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 27, 27, 5, 0, 0, 0, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 25, 0, 0, 55, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 0, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 141, 55, 55, 55, - 55, 55, 55, 55, 55, 141, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 148, 55, 55, 55, 55, 55, 55, 55, 55, 148, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 0, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 5, 141, - 141, 141, 141, 141, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, - 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, - 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 293, 293, - 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, - 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, - 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, 55, 55, 55, 55, 55, 55, + 25, 25, 25, 25, 25, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 0, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 5, 148, 148, + 148, 148, 148, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 304, + 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, + 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, + 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 305, 305, 305, + 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, + 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, + 305, 305, 305, 305, 305, 305, 305, 305, 305, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 0, 0, 55, 0, 55, 55, 55, 55, 55, 55, + 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 0, 55, 55, 0, 0, 0, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 5, 27, 27, 27, - 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 27, 27, 27, 27, - 27, 27, 0, 0, 0, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 5, 0, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, + 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 55, 55, 55, 55, 55, 55, 0, 0, 55, 0, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 0, 55, 55, 0, 0, 0, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 5, 27, 27, 27, 27, + 27, 27, 27, 27, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 5, 5, 27, 27, 27, 27, 27, 27, 27, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 27, 27, 27, 27, 27, 27, 0, 0, 0, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 55, - 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 25, 25, 25, 0, 25, - 25, 0, 0, 0, 0, 0, 25, 25, 25, 25, 55, 55, 55, 55, 0, 55, 55, 55, 0, 55, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 25, 25, 25, 0, 0, 0, 0, 25, - 26, 22, 23, 246, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 27, 27, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 0, 0, 0, 0, 0, 0, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 55, 25, 25, 25, 0, 25, 25, 0, 0, 0, 0, 0, 25, 25, 25, 25, 55, 55, 55, 55, + 0, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 25, 25, + 25, 0, 0, 0, 0, 25, 26, 22, 23, 253, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, + 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 27, 27, - 27, 27, 27, 27, 27, 27, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, - 27, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 27, 27, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, + 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 0, 0, 0, 0, 27, 27, + 27, 27, 27, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 5, + 5, 5, 5, 5, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 5, + 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 22, 23, 246, 247, 248, 249, 250, 251, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 0, 18, 25, 18, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 22, 23, 253, 254, + 255, 256, 257, 258, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 18, 25, 18, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 26, 22, 23, 246, 247, 248, - 249, 250, 251, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 25, 25, 18, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 26, + 22, 23, 253, 254, 255, 256, 257, 258, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 25, 25, 25, 18, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 18, 18, 25, 25, 25, - 25, 18, 18, 25, 25, 5, 5, 21, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 25, 25, 25, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, + 18, 18, 25, 25, 25, 25, 18, 18, 25, 25, 5, 5, 21, 5, 5, 5, 5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, + 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 25, 25, 25, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, 25, - 18, 25, 25, 25, 25, 25, 25, 25, 25, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, + 25, 25, 25, 25, 18, 25, 25, 25, 25, 25, 25, 25, 25, 0, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 5, 5, + 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 18, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 18, 18, 18, 25, 25, 25, 25, 25, 25, 25, 25, 25, 18, + 18, 55, 55, 55, 55, 5, 5, 5, 5, 0, 0, 0, 0, 5, 0, 0, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 55, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 18, 18, 25, 25, 25, 18, 18, 25, + 18, 25, 25, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 18, 55, 55, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 18, 18, 18, + 25, 25, 25, 25, 25, 25, 25, 25, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 25, 18, 18, 0, 55, 55, 55, 55, 55, 55, + 55, 55, 0, 0, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, + 55, 0, 55, 55, 0, 55, 55, 55, 55, 55, 0, 0, 25, 55, 18, 18, 25, 18, 18, + 18, 18, 0, 0, 18, 18, 0, 0, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, + 0, 0, 0, 0, 55, 55, 55, 55, 55, 18, 18, 0, 0, 25, 25, 25, 25, 25, 25, 25, + 0, 0, 0, 25, 25, 25, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 18, 18, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 18, 18, 55, 55, 55, 55, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 18, 18, 25, 25, 25, 25, 25, 25, + 18, 25, 18, 18, 18, 18, 25, 25, 18, 25, 25, 55, 55, 5, 55, 0, 0, 0, 0, 0, + 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 25, 18, 25, 18, 18, 25, 25, 25, 25, 25, - 25, 18, 25, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 18, 18, + 25, 25, 25, 25, 0, 0, 18, 18, 18, 18, 25, 25, 18, 25, 25, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 18, 18, 18, 25, 25, 25, 25, 25, 25, 25, 25, 18, 18, 25, 18, 25, 25, + 5, 5, 5, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 25, 18, 25, 18, 18, 25, 25, 25, 25, 25, 25, 18, 25, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 0, 5, 5, + 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 0, 0, 25, 25, 25, 25, 25, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, 25, 25, + 25, 5, 5, 5, 5, 5, 5, 5, 5, 5, 101, 101, 101, 101, 5, 5, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 27, 27, 27, 27, + 27, 27, 27, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 18, 18, 18, 18, 18, + 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, - 25, 25, 25, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 0, 0, 0, + 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, + 25, 25, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, + 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 5, 25, 25, 5, 21, + 21, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 18, 18, 25, 25, 25, - 5, 5, 5, 18, 18, 18, 18, 18, 18, 21, 21, 21, 21, 21, 21, 21, 21, 25, 25, - 25, 25, 25, 25, 25, 25, 5, 5, 25, 25, 25, 25, 25, 25, 25, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, + 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 25, 25, 25, 25, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 18, 18, 25, 25, 25, 5, 5, 5, 18, + 18, 18, 18, 18, 18, 21, 21, 21, 21, 21, 21, 21, 21, 25, 25, 25, 25, 25, + 25, 25, 25, 5, 5, 25, 25, 25, 25, 25, 25, 25, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 25, 25, + 25, 25, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 25, 25, 25, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5, 5, 5, 5, 5, 5, 25, 25, 25, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 20, 20, 20, 20, - 20, 20, 20, 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 113, 0, 113, 113, 0, 0, 113, 0, 0, - 113, 113, 0, 0, 113, 113, 113, 113, 0, 113, 113, 113, 113, 113, 113, 113, - 113, 20, 20, 20, 20, 0, 20, 0, 20, 20, 20, 20, 20, 20, 20, 0, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 113, 113, 0, 113, - 113, 113, 113, 0, 0, 113, 113, 113, 113, 113, 113, 113, 113, 0, 113, 113, - 113, 113, 113, 113, 113, 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 113, 113, 0, - 113, 113, 113, 113, 0, 113, 113, 113, 113, 113, 0, 113, 0, 0, 0, 113, - 113, 113, 113, 113, 113, 113, 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 20, 20, 20, 20, 20, 20, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 20, 20, 20, 20, 20, 20, 20, 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 20, 20, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 119, 0, 119, 119, 0, 0, 119, 0, 0, 119, 119, 0, 0, + 119, 119, 119, 119, 0, 119, 119, 119, 119, 119, 119, 119, 119, 20, 20, + 20, 20, 0, 20, 0, 20, 20, 20, 20, 20, 20, 20, 0, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 119, 119, 0, 119, 119, 119, 119, + 0, 0, 119, 119, 119, 119, 119, 119, 119, 119, 0, 119, 119, 119, 119, 119, + 119, 119, 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 119, 119, 0, 119, 119, 119, + 119, 0, 119, 119, 119, 119, 119, 0, 119, 0, 0, 0, 119, 119, 119, 119, + 119, 119, 119, 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 20, 20, + 20, 20, 20, 20, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 5, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 5, 20, 20, 20, 20, - 20, 20, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 5, 20, 20, + 20, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 5, 20, 20, 20, 20, 20, 20, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 5, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 5, 20, 20, - 20, 20, 20, 20, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 5, + 20, 20, 20, 20, 20, 20, 20, 0, 0, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 5, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 5, 20, 20, 20, 20, 20, 20, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 5, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 5, 20, 20, 20, 20, 20, 20, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 5, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 5, 20, 20, 20, 20, 20, 20, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 5, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 5, 20, 20, 20, 20, + 20, 20, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 5, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 5, 20, 20, 20, 20, 20, 20, 113, 20, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, - 55, 0, 55, 0, 0, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, - 55, 55, 55, 0, 55, 0, 55, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 0, 55, 0, 55, 0, - 55, 0, 55, 55, 55, 0, 55, 55, 0, 55, 0, 0, 55, 0, 55, 0, 55, 0, 55, 0, - 55, 0, 55, 55, 0, 55, 0, 0, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, - 55, 0, 55, 55, 55, 55, 0, 55, 55, 55, 55, 0, 55, 0, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 55, 55, 55, 0, 55, 55, 55, 55, 55, 0, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, + 20, 20, 20, 20, 20, 5, 20, 20, 20, 20, 20, 20, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 5, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 5, 20, 20, + 20, 20, 20, 20, 119, 20, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 25, 25, 25, 25, 25, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 0, 55, 55, 0, 55, 0, 0, 55, 0, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 0, 55, 55, 55, 55, 0, 55, 0, 55, 0, 0, 0, 0, 0, 0, 55, 0, 0, + 0, 0, 55, 0, 55, 0, 55, 0, 55, 55, 55, 0, 55, 55, 0, 55, 0, 0, 55, 0, 55, + 0, 55, 0, 55, 0, 55, 0, 55, 55, 0, 55, 0, 0, 55, 55, 55, 55, 0, 55, 55, + 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 0, 55, 55, 55, 55, 0, 55, 0, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 55, 55, 55, 0, 55, 55, + 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, + 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 245, 245, 26, 22, 23, 246, 247, 248, 249, - 250, 251, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252, 252, 26, 22, 23, + 253, 254, 255, 256, 257, 258, 27, 27, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 5, 5, 5, 5, 5, 5, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 5, 5, 0, 0, + 0, 0, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, + 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, + 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, + 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 0, 5, + 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, - 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, - 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 0, 0, 0, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, + 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, + 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, + 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, - 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 281, 55, 55, 55, 55, 55, 55, 55, 55, 281, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, @@ -2834,33 +3102,33 @@ static unsigned short index2[] = { 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, @@ -2870,34 +3138,36 @@ static unsigned short index2[] = { 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 281, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, @@ -2910,13 +3180,13 @@ static unsigned short index2[] = { 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, + 0, }; /* Returns the numeric value as double for Unicode characters @@ -2941,6 +3211,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x0C78: case 0x0CE6: case 0x0D66: + case 0x0DE6: case 0x0E50: case 0x0ED0: case 0x0F20: @@ -2969,6 +3240,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0xA8D0: case 0xA900: case 0xA9D0: + case 0xA9F0: case 0xAA50: case 0xABF0: case 0xF9B2: @@ -2979,7 +3251,13 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x110F0: case 0x11136: case 0x111D0: + case 0x112F0: + case 0x114D0: + case 0x11650: case 0x116C0: + case 0x118E0: + case 0x16A60: + case 0x16B50: case 0x1D7CE: case 0x1D7D8: case 0x1D7E2: @@ -2987,6 +3265,8 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1D7F6: case 0x1F100: case 0x1F101: + case 0x1F10B: + case 0x1F10C: return (double) 0.0; case 0x0031: case 0x00B9: @@ -3004,6 +3284,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x0C7C: case 0x0CE7: case 0x0D67: + case 0x0DE7: case 0x0E51: case 0x0ED1: case 0x0F21: @@ -3047,6 +3328,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0xA8D1: case 0xA901: case 0xA9D1: + case 0xA9F1: case 0xAA51: case 0xABF1: case 0xFF11: @@ -3055,34 +3337,48 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x10158: case 0x10159: case 0x1015A: + case 0x102E1: case 0x10320: case 0x103D1: case 0x104A1: case 0x10858: + case 0x10879: + case 0x108A7: case 0x10916: case 0x10A40: case 0x10A7D: + case 0x10A9D: + case 0x10AEB: case 0x10B58: case 0x10B78: + case 0x10BA9: case 0x10E60: case 0x11052: case 0x11067: case 0x110F1: case 0x11137: case 0x111D1: + case 0x111E1: + case 0x112F1: + case 0x114D1: + case 0x11651: case 0x116C1: + case 0x118E1: case 0x12415: case 0x1241E: case 0x1242C: case 0x12434: case 0x1244F: case 0x12458: + case 0x16A61: + case 0x16B51: case 0x1D360: case 0x1D7CF: case 0x1D7D9: case 0x1D7E3: case 0x1D7ED: case 0x1D7F7: + case 0x1E8C7: case 0x1F102: case 0x2092A: return (double) 1.0; @@ -3102,11 +3398,13 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x10175: case 0x10176: case 0x10E7B: + case 0x12464: return (double) 1.0/2.0; case 0x2153: case 0x10E7D: case 0x1245A: case 0x1245D: + case 0x12465: return (double) 1.0/3.0; case 0x00BC: case 0x09F7: @@ -3114,9 +3412,11 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x0D73: case 0xA830: case 0x10140: + case 0x1018B: case 0x10E7C: case 0x12460: case 0x12462: + case 0x12463: return (double) 1.0/4.0; case 0x2155: return (double) 1.0/5.0; @@ -3163,15 +3463,24 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x10162: case 0x10163: case 0x10164: + case 0x102EA: case 0x10322: case 0x103D3: case 0x1085B: + case 0x1087E: + case 0x108AD: case 0x10917: case 0x10A44: + case 0x10A9E: + case 0x10AED: case 0x10B5C: case 0x10B7C: + case 0x10BAD: case 0x10E69: case 0x1105B: + case 0x111EA: + case 0x118EA: + case 0x16B5B: case 0x1D369: return (double) 10.0; case 0x0BF1: @@ -3186,14 +3495,20 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1014B: case 0x10152: case 0x1016A: + case 0x102F3: case 0x103D5: case 0x1085D: + case 0x108AF: case 0x10919: case 0x10A46: + case 0x10AEF: case 0x10B5E: case 0x10B7E: + case 0x10BAF: case 0x10E72: case 0x11064: + case 0x111F3: + case 0x16B5C: return (double) 100.0; case 0x0BF2: case 0x0D72: @@ -3212,6 +3527,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x10B5F: case 0x10B7F: case 0x11065: + case 0x111F4: return (double) 1000.0; case 0x137C: case 0x2182: @@ -3220,13 +3536,20 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1012B: case 0x10155: case 0x1085F: + case 0x16B5D: return (double) 10000.0; case 0x2188: return (double) 100000.0; + case 0x16B5E: + return (double) 1000000.0; case 0x4EBF: case 0x5104: + case 0x16B5F: return (double) 100000000.0; + case 0x16B60: + return (double) 10000000000.0; case 0x5146: + case 0x16B61: return (double) 1000000000000.0; case 0x216A: case 0x217A: @@ -3305,6 +3628,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x0C7D: case 0x0CE8: case 0x0D68: + case 0x0DE8: case 0x0E52: case 0x0ED2: case 0x0F22: @@ -3349,6 +3673,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0xA8D2: case 0xA902: case 0xA9D2: + case 0xA9F2: case 0xAA52: case 0xABF2: case 0xF978: @@ -3358,20 +3683,29 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1015C: case 0x1015D: case 0x1015E: + case 0x102E2: case 0x103D2: case 0x104A2: case 0x10859: + case 0x1087A: + case 0x108A8: case 0x1091A: case 0x10A41: case 0x10B59: case 0x10B79: + case 0x10BAA: case 0x10E61: case 0x11053: case 0x11068: case 0x110F2: case 0x11138: case 0x111D2: + case 0x111E2: + case 0x112F2: + case 0x114D2: + case 0x11652: case 0x116C2: + case 0x118E2: case 0x12400: case 0x12416: case 0x1241F: @@ -3382,12 +3716,15 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x12450: case 0x12456: case 0x12459: + case 0x16A62: + case 0x16B52: case 0x1D361: case 0x1D7D0: case 0x1D7DA: case 0x1D7E4: case 0x1D7EE: case 0x1D7F8: + case 0x1E8C8: case 0x1F103: case 0x22390: return (double) 2.0; @@ -3396,6 +3733,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x10E7E: case 0x1245B: case 0x1245E: + case 0x12466: return (double) 2.0/3.0; case 0x2156: return (double) 2.0/5.0; @@ -3409,17 +3747,26 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x5344: case 0x5EFF: case 0x10111: + case 0x102EB: case 0x103D4: case 0x1085C: + case 0x1087F: + case 0x108AE: case 0x10918: case 0x10A45: + case 0x10A9F: + case 0x10AEE: case 0x10B5D: case 0x10B7D: + case 0x10BAE: case 0x10E6A: case 0x1105C: + case 0x111EB: + case 0x118EB: case 0x1D36A: return (double) 20.0; case 0x1011A: + case 0x102F4: case 0x10E73: return (double) 200.0; case 0x10123: @@ -3462,6 +3809,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x0C7E: case 0x0CE9: case 0x0D69: + case 0x0DE9: case 0x0E53: case 0x0ED3: case 0x0F23: @@ -3505,24 +3853,34 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0xA8D3: case 0xA903: case 0xA9D3: + case 0xA9F3: case 0xAA53: case 0xABF3: case 0xF96B: case 0xFF13: case 0x10109: + case 0x102E3: case 0x104A3: case 0x1085A: + case 0x1087B: + case 0x108A9: case 0x1091B: case 0x10A42: case 0x10B5A: case 0x10B7A: + case 0x10BAB: case 0x10E62: case 0x11054: case 0x11069: case 0x110F3: case 0x11139: case 0x111D3: + case 0x111E3: + case 0x112F3: + case 0x114D3: + case 0x11653: case 0x116C3: + case 0x118E3: case 0x12401: case 0x12408: case 0x12417: @@ -3538,12 +3896,15 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1244B: case 0x12451: case 0x12457: + case 0x16A63: + case 0x16B53: case 0x1D362: case 0x1D7D1: case 0x1D7DB: case 0x1D7E5: case 0x1D7EF: case 0x1D7F9: + case 0x1E8C9: case 0x1F104: case 0x20AFD: case 0x20B19: @@ -3574,13 +3935,17 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x5345: case 0x10112: case 0x10165: + case 0x102EC: case 0x10E6B: case 0x1105D: + case 0x111EC: + case 0x118EC: case 0x1D36B: case 0x20983: return (double) 30.0; case 0x1011B: case 0x1016B: + case 0x102F5: case 0x10E74: return (double) 300.0; case 0x10124: @@ -3618,6 +3983,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x0C6A: case 0x0CEA: case 0x0D6A: + case 0x0DEA: case 0x0E54: case 0x0ED4: case 0x0F24: @@ -3658,21 +4024,32 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0xA8D4: case 0xA904: case 0xA9D4: + case 0xA9F4: case 0xAA54: case 0xABF4: case 0xFF14: case 0x1010A: + case 0x102E4: case 0x104A4: + case 0x1087C: + case 0x108AA: + case 0x108AB: case 0x10A43: case 0x10B5B: case 0x10B7B: + case 0x10BAC: case 0x10E63: case 0x11055: case 0x1106A: case 0x110F4: case 0x1113A: case 0x111D4: + case 0x111E4: + case 0x112F4: + case 0x114D4: + case 0x11654: case 0x116C4: + case 0x118E4: case 0x12402: case 0x12409: case 0x1240F: @@ -3688,12 +4065,16 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1244C: case 0x12452: case 0x12453: + case 0x12469: + case 0x16A64: + case 0x16B54: case 0x1D363: case 0x1D7D2: case 0x1D7DC: case 0x1D7E6: case 0x1D7F0: case 0x1D7FA: + case 0x1E8CA: case 0x1F105: case 0x20064: case 0x200E2: @@ -3706,13 +4087,18 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x32B5: case 0x534C: case 0x10113: + case 0x102ED: case 0x10E6C: case 0x1105E: + case 0x111ED: + case 0x118ED: + case 0x12467: case 0x1D36C: case 0x2098C: case 0x2099C: return (double) 40.0; case 0x1011C: + case 0x102F6: case 0x10E75: return (double) 400.0; case 0x10125: @@ -3752,6 +4138,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x0C6B: case 0x0CEB: case 0x0D6B: + case 0x0DEB: case 0x0E55: case 0x0ED5: case 0x0F25: @@ -3792,6 +4179,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0xA8D5: case 0xA905: case 0xA9D5: + case 0xA9F5: case 0xAA55: case 0xABF5: case 0xFF15: @@ -3801,15 +4189,24 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1014F: case 0x1015F: case 0x10173: + case 0x102E5: case 0x10321: case 0x104A5: + case 0x1087D: + case 0x108AC: + case 0x10AEC: case 0x10E64: case 0x11056: case 0x1106B: case 0x110F5: case 0x1113B: case 0x111D5: + case 0x111E5: + case 0x112F5: + case 0x114D5: + case 0x11655: case 0x116C5: + case 0x118E5: case 0x12403: case 0x1240A: case 0x12410: @@ -3821,12 +4218,16 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1244D: case 0x12454: case 0x12455: + case 0x1246A: + case 0x16A65: + case 0x16B55: case 0x1D364: case 0x1D7D3: case 0x1D7DD: case 0x1D7E7: case 0x1D7F1: case 0x1D7FB: + case 0x1E8CB: case 0x1F106: case 0x20121: return (double) 5.0; @@ -3852,10 +4253,14 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x10168: case 0x10169: case 0x10174: + case 0x102EE: case 0x10323: case 0x10A7E: case 0x10E6D: case 0x1105F: + case 0x111EE: + case 0x118EE: + case 0x12468: case 0x1D36D: return (double) 50.0; case 0x216E: @@ -3869,6 +4274,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1016E: case 0x1016F: case 0x10170: + case 0x102F7: case 0x10E76: return (double) 500.0; case 0x2181: @@ -3895,6 +4301,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x0C6C: case 0x0CEC: case 0x0D6C: + case 0x0DEC: case 0x0E56: case 0x0ED6: case 0x0F26: @@ -3935,12 +4342,14 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0xA8D6: case 0xA906: case 0xA9D6: + case 0xA9F6: case 0xAA56: case 0xABF6: case 0xF9D1: case 0xF9D3: case 0xFF16: case 0x1010C: + case 0x102E6: case 0x104A6: case 0x10E65: case 0x11057: @@ -3948,7 +4357,12 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x110F6: case 0x1113C: case 0x111D6: + case 0x111E6: + case 0x112F6: + case 0x114D6: + case 0x11656: case 0x116C6: + case 0x118E6: case 0x12404: case 0x1240B: case 0x12411: @@ -3956,23 +4370,31 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x12428: case 0x12440: case 0x1244E: + case 0x1246B: + case 0x16A66: + case 0x16B56: case 0x1D365: case 0x1D7D4: case 0x1D7DE: case 0x1D7E8: case 0x1D7F2: case 0x1D7FC: + case 0x1E8CC: case 0x1F107: case 0x20AEA: return (double) 6.0; case 0x1377: case 0x324D: case 0x10115: + case 0x102EF: case 0x10E6E: case 0x11060: + case 0x111EF: + case 0x118EF: case 0x1D36E: return (double) 60.0; case 0x1011E: + case 0x102F8: case 0x10E77: return (double) 600.0; case 0x10127: @@ -3992,6 +4414,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x0C6D: case 0x0CED: case 0x0D6D: + case 0x0DED: case 0x0E57: case 0x0ED7: case 0x0F27: @@ -4032,10 +4455,12 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0xA8D7: case 0xA907: case 0xA9D7: + case 0xA9F7: case 0xAA57: case 0xABF7: case 0xFF17: case 0x1010D: + case 0x102E7: case 0x104A7: case 0x10E66: case 0x11058: @@ -4043,7 +4468,12 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x110F7: case 0x1113D: case 0x111D7: + case 0x111E7: + case 0x112F7: + case 0x114D7: + case 0x11657: case 0x116C7: + case 0x118E7: case 0x12405: case 0x1240C: case 0x12412: @@ -4052,12 +4482,16 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x12441: case 0x12442: case 0x12443: + case 0x1246C: + case 0x16A67: + case 0x16B57: case 0x1D366: case 0x1D7D5: case 0x1D7DF: case 0x1D7E9: case 0x1D7F3: case 0x1D7FD: + case 0x1E8CD: case 0x1F108: case 0x20001: return (double) 7.0; @@ -4068,11 +4502,15 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1378: case 0x324E: case 0x10116: + case 0x102F0: case 0x10E6F: case 0x11061: + case 0x111F0: + case 0x118F0: case 0x1D36F: return (double) 70.0; case 0x1011F: + case 0x102F9: case 0x10E78: return (double) 700.0; case 0x10128: @@ -4092,6 +4530,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x0C6E: case 0x0CEE: case 0x0D6E: + case 0x0DEE: case 0x0E58: case 0x0ED8: case 0x0F28: @@ -4130,10 +4569,12 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0xA8D8: case 0xA908: case 0xA9D8: + case 0xA9F8: case 0xAA58: case 0xABF8: case 0xFF18: case 0x1010E: + case 0x102E8: case 0x104A8: case 0x10E67: case 0x11059: @@ -4141,7 +4582,12 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x110F8: case 0x1113E: case 0x111D8: + case 0x111E8: + case 0x112F8: + case 0x114D8: + case 0x11658: case 0x116C8: + case 0x118E8: case 0x12406: case 0x1240D: case 0x12413: @@ -4149,22 +4595,30 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1242A: case 0x12444: case 0x12445: + case 0x1246D: + case 0x16A68: + case 0x16B58: case 0x1D367: case 0x1D7D6: case 0x1D7E0: case 0x1D7EA: case 0x1D7F4: case 0x1D7FE: + case 0x1E8CE: case 0x1F109: return (double) 8.0; case 0x1379: case 0x324F: case 0x10117: + case 0x102F1: case 0x10E70: case 0x11062: + case 0x111F1: + case 0x118F1: case 0x1D370: return (double) 80.0; case 0x10120: + case 0x102FA: case 0x10E79: return (double) 800.0; case 0x10129: @@ -4184,6 +4638,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x0C6F: case 0x0CEF: case 0x0D6F: + case 0x0DEF: case 0x0E59: case 0x0ED9: case 0x0F29: @@ -4223,10 +4678,12 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0xA8D9: case 0xA909: case 0xA9D9: + case 0xA9F9: case 0xAA59: case 0xABF9: case 0xFF19: case 0x1010F: + case 0x102E9: case 0x104A9: case 0x10E68: case 0x1105A: @@ -4234,7 +4691,12 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x110F9: case 0x1113F: case 0x111D9: + case 0x111E9: + case 0x112F9: + case 0x114D9: + case 0x11659: case 0x116C9: + case 0x118E9: case 0x12407: case 0x1240E: case 0x12414: @@ -4244,12 +4706,16 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x12447: case 0x12448: case 0x12449: + case 0x1246E: + case 0x16A69: + case 0x16B59: case 0x1D368: case 0x1D7D7: case 0x1D7E1: case 0x1D7EB: case 0x1D7F5: case 0x1D7FF: + case 0x1E8CF: case 0x1F10A: case 0x2F890: return (double) 9.0; @@ -4257,12 +4723,16 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) return (double) 9.0/2.0; case 0x137A: case 0x10118: + case 0x102F2: case 0x10341: case 0x10E71: case 0x11063: + case 0x111F2: + case 0x118F2: case 0x1D371: return (double) 90.0; case 0x10121: + case 0x102FB: case 0x1034A: case 0x10E7A: return (double) 900.0; diff --git a/PC/VS9.0/_bz2.vcproj b/PC/VS9.0/_bz2.vcproj deleted file mode 100644 index 7ceb8c7f089b..000000000000 --- a/PC/VS9.0/_bz2.vcproj +++ /dev/null @@ -1,581 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/_ctypes.vcproj b/PC/VS9.0/_ctypes.vcproj deleted file mode 100644 index 8e5cba14fc8d..000000000000 --- a/PC/VS9.0/_ctypes.vcproj +++ /dev/null @@ -1,705 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/_ctypes_test.vcproj b/PC/VS9.0/_ctypes_test.vcproj deleted file mode 100644 index 70335462113d..000000000000 --- a/PC/VS9.0/_ctypes_test.vcproj +++ /dev/null @@ -1,521 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/_decimal.vcproj b/PC/VS9.0/_decimal.vcproj deleted file mode 100644 index b9fabb0cb95f..000000000000 --- a/PC/VS9.0/_decimal.vcproj +++ /dev/null @@ -1,743 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/_elementtree.vcproj b/PC/VS9.0/_elementtree.vcproj deleted file mode 100644 index f9d7375c0c1f..000000000000 --- a/PC/VS9.0/_elementtree.vcproj +++ /dev/null @@ -1,613 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/_hashlib.vcproj b/PC/VS9.0/_hashlib.vcproj deleted file mode 100644 index 77417ec0f5f4..000000000000 --- a/PC/VS9.0/_hashlib.vcproj +++ /dev/null @@ -1,537 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/_lzma.vcproj b/PC/VS9.0/_lzma.vcproj deleted file mode 100644 index 7c6003f10e2a..000000000000 --- a/PC/VS9.0/_lzma.vcproj +++ /dev/null @@ -1,537 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/_msi.vcproj b/PC/VS9.0/_msi.vcproj deleted file mode 100644 index cb230e10d0dc..000000000000 --- a/PC/VS9.0/_msi.vcproj +++ /dev/null @@ -1,529 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/_multiprocessing.vcproj b/PC/VS9.0/_multiprocessing.vcproj deleted file mode 100644 index fb3d1e70bcc6..000000000000 --- a/PC/VS9.0/_multiprocessing.vcproj +++ /dev/null @@ -1,541 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/_sha3.vcproj b/PC/VS9.0/_sha3.vcproj deleted file mode 100644 index 5fe18d5b5738..000000000000 --- a/PC/VS9.0/_sha3.vcproj +++ /dev/null @@ -1,513 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/_socket.vcproj b/PC/VS9.0/_socket.vcproj deleted file mode 100644 index ff1f6d4e3f57..000000000000 --- a/PC/VS9.0/_socket.vcproj +++ /dev/null @@ -1,537 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/_sqlite3.vcproj b/PC/VS9.0/_sqlite3.vcproj deleted file mode 100644 index 82c57ae25fd7..000000000000 --- a/PC/VS9.0/_sqlite3.vcproj +++ /dev/null @@ -1,609 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/_ssl.vcproj b/PC/VS9.0/_ssl.vcproj deleted file mode 100644 index b47dc2740c5b..000000000000 --- a/PC/VS9.0/_ssl.vcproj +++ /dev/null @@ -1,537 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/_testbuffer.vcproj b/PC/VS9.0/_testbuffer.vcproj deleted file mode 100644 index 03377e17721a..000000000000 --- a/PC/VS9.0/_testbuffer.vcproj +++ /dev/null @@ -1,521 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/_testcapi.vcproj b/PC/VS9.0/_testcapi.vcproj deleted file mode 100644 index 453300a64271..000000000000 --- a/PC/VS9.0/_testcapi.vcproj +++ /dev/null @@ -1,521 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/_testimportmultiple.vcproj b/PC/VS9.0/_testimportmultiple.vcproj deleted file mode 100644 index 14d910dfdf51..000000000000 --- a/PC/VS9.0/_testimportmultiple.vcproj +++ /dev/null @@ -1,521 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/_tkinter.vcproj b/PC/VS9.0/_tkinter.vcproj deleted file mode 100644 index 5163317575c6..000000000000 --- a/PC/VS9.0/_tkinter.vcproj +++ /dev/null @@ -1,541 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/bdist_wininst.vcproj b/PC/VS9.0/bdist_wininst.vcproj deleted file mode 100644 index b8cc7ad6a875..000000000000 --- a/PC/VS9.0/bdist_wininst.vcproj +++ /dev/null @@ -1,270 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/debug.vsprops b/PC/VS9.0/debug.vsprops deleted file mode 100644 index bc643cb6be57..000000000000 --- a/PC/VS9.0/debug.vsprops +++ /dev/null @@ -1,15 +0,0 @@ - - - - - diff --git a/PC/VS9.0/kill_python.c b/PC/VS9.0/kill_python.c deleted file mode 100644 index 604731f3f81c..000000000000 --- a/PC/VS9.0/kill_python.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Helper program for killing lingering python[_d].exe processes before - * building, thus attempting to avoid build failures due to files being - * locked. - */ - -#include -#include -#include -#include - -#pragma comment(lib, "psapi") - -#ifdef _DEBUG -#define PYTHON_EXE (L"python_d.exe") -#define PYTHON_EXE_LEN (12) -#define KILL_PYTHON_EXE (L"kill_python_d.exe") -#define KILL_PYTHON_EXE_LEN (17) -#else -#define PYTHON_EXE (L"python.exe") -#define PYTHON_EXE_LEN (10) -#define KILL_PYTHON_EXE (L"kill_python.exe") -#define KILL_PYTHON_EXE_LEN (15) -#endif - -int -main(int argc, char **argv) -{ - HANDLE hp, hsp, hsm; /* process, snapshot processes, snapshot modules */ - DWORD dac, our_pid; - size_t len; - wchar_t path[MAX_PATH+1]; - - MODULEENTRY32W me; - PROCESSENTRY32W pe; - - me.dwSize = sizeof(MODULEENTRY32W); - pe.dwSize = sizeof(PROCESSENTRY32W); - - memset(path, 0, MAX_PATH+1); - - our_pid = GetCurrentProcessId(); - - hsm = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, our_pid); - if (hsm == INVALID_HANDLE_VALUE) { - printf("CreateToolhelp32Snapshot[1] failed: %d\n", GetLastError()); - return 1; - } - - if (!Module32FirstW(hsm, &me)) { - printf("Module32FirstW[1] failed: %d\n", GetLastError()); - CloseHandle(hsm); - return 1; - } - - /* - * Enumerate over the modules for the current process in order to find - * kill_process[_d].exe, then take a note of the directory it lives in. - */ - do { - if (_wcsnicmp(me.szModule, KILL_PYTHON_EXE, KILL_PYTHON_EXE_LEN)) - continue; - - len = wcsnlen_s(me.szExePath, MAX_PATH) - KILL_PYTHON_EXE_LEN; - wcsncpy_s(path, MAX_PATH+1, me.szExePath, len); - - break; - - } while (Module32NextW(hsm, &me)); - - CloseHandle(hsm); - - if (path == NULL) { - printf("failed to discern directory of running process\n"); - return 1; - } - - /* - * Take a snapshot of system processes. Enumerate over the snapshot, - * looking for python processes. When we find one, verify it lives - * in the same directory we live in. If it does, kill it. If we're - * unable to kill it, treat this as a fatal error and return 1. - * - * The rationale behind this is that we're called at the start of the - * build process on the basis that we'll take care of killing any - * running instances, such that the build won't encounter permission - * denied errors during linking. If we can't kill one of the processes, - * we can't provide this assurance, and the build shouldn't start. - */ - - hsp = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); - if (hsp == INVALID_HANDLE_VALUE) { - printf("CreateToolhelp32Snapshot[2] failed: %d\n", GetLastError()); - return 1; - } - - if (!Process32FirstW(hsp, &pe)) { - printf("Process32FirstW failed: %d\n", GetLastError()); - CloseHandle(hsp); - return 1; - } - - dac = PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_TERMINATE; - do { - - /* - * XXX TODO: if we really wanted to be fancy, we could check the - * modules for all processes (not just the python[_d].exe ones) - * and see if any of our DLLs are loaded (i.e. python34[_d].dll), - * as that would also inhibit our ability to rebuild the solution. - * Not worth loosing sleep over though; for now, a simple check - * for just the python executable should be sufficient. - */ - - if (_wcsnicmp(pe.szExeFile, PYTHON_EXE, PYTHON_EXE_LEN)) - /* This isn't a python process. */ - continue; - - /* It's a python process, so figure out which directory it's in... */ - hsm = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pe.th32ProcessID); - if (hsm == INVALID_HANDLE_VALUE) - /* - * If our module snapshot fails (which will happen if we don't own - * the process), just ignore it and continue. (It seems different - * versions of Windows return different values for GetLastError() - * in this situation; it's easier to just ignore it and move on vs. - * stopping the build for what could be a false positive.) - */ - continue; - - if (!Module32FirstW(hsm, &me)) { - printf("Module32FirstW[2] failed: %d\n", GetLastError()); - CloseHandle(hsp); - CloseHandle(hsm); - return 1; - } - - do { - if (_wcsnicmp(me.szModule, PYTHON_EXE, PYTHON_EXE_LEN)) - /* Wrong module, we're looking for python[_d].exe... */ - continue; - - if (_wcsnicmp(path, me.szExePath, len)) - /* Process doesn't live in our directory. */ - break; - - /* Python process residing in the right directory, kill it! */ - hp = OpenProcess(dac, FALSE, pe.th32ProcessID); - if (!hp) { - printf("OpenProcess failed: %d\n", GetLastError()); - CloseHandle(hsp); - CloseHandle(hsm); - return 1; - } - - if (!TerminateProcess(hp, 1)) { - printf("TerminateProcess failed: %d\n", GetLastError()); - CloseHandle(hsp); - CloseHandle(hsm); - CloseHandle(hp); - return 1; - } - - CloseHandle(hp); - break; - - } while (Module32NextW(hsm, &me)); - - CloseHandle(hsm); - - } while (Process32NextW(hsp, &pe)); - - CloseHandle(hsp); - - return 0; -} - -/* vi: set ts=8 sw=4 sts=4 expandtab */ diff --git a/PC/VS9.0/kill_python.vcproj b/PC/VS9.0/kill_python.vcproj deleted file mode 100644 index a34107aab7a2..000000000000 --- a/PC/VS9.0/kill_python.vcproj +++ /dev/null @@ -1,279 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/make_buildinfo.c b/PC/VS9.0/make_buildinfo.c deleted file mode 100644 index fb4a64a97182..000000000000 --- a/PC/VS9.0/make_buildinfo.c +++ /dev/null @@ -1,195 +0,0 @@ -#include -#include -#include -#include -#include - -#define CMD_SIZE 500 - -/* This file creates the getbuildinfo.o object, by first - invoking subwcrev.exe (if found), and then invoking cl.exe. - As a side effect, it might generate PCBuild\getbuildinfo2.c - also. If this isn't a subversion checkout, or subwcrev isn't - found, it compiles ..\\..\\Modules\\getbuildinfo.c instead. - - Currently, subwcrev.exe is found from the registry entries - of TortoiseSVN. - - No attempt is made to place getbuildinfo.o into the proper - binary directory. This isn't necessary, as this tool is - invoked as a pre-link step for pythoncore, so that overwrites - any previous getbuildinfo.o. - - However, if a second argument is provided, this will be used - as a temporary directory where any getbuildinfo2.c and - getbuildinfo.o files are put. This is useful if multiple - configurations are being built in parallel, to avoid them - trampling each other's files. - -*/ - -int make_buildinfo2(const char *tmppath) -{ - struct _stat st; - HKEY hTortoise; - char command[CMD_SIZE+1]; - DWORD type, size; - if (_stat(".svn", &st) < 0) - return 0; - /* Allow suppression of subwcrev.exe invocation if a no_subwcrev file is present. */ - if (_stat("no_subwcrev", &st) == 0) - return 0; - if (RegOpenKey(HKEY_LOCAL_MACHINE, "Software\\TortoiseSVN", &hTortoise) != ERROR_SUCCESS && - RegOpenKey(HKEY_CURRENT_USER, "Software\\TortoiseSVN", &hTortoise) != ERROR_SUCCESS) - /* Tortoise not installed */ - return 0; - command[0] = '"'; /* quote the path to the executable */ - size = sizeof(command) - 1; - if (RegQueryValueEx(hTortoise, "Directory", 0, &type, command+1, &size) != ERROR_SUCCESS || - type != REG_SZ) - /* Registry corrupted */ - return 0; - strcat_s(command, CMD_SIZE, "bin\\subwcrev.exe"); - if (_stat(command+1, &st) < 0) - /* subwcrev.exe not part of the release */ - return 0; - strcat_s(command, CMD_SIZE, "\" ..\\.. ..\\..\\Modules\\getbuildinfo.c \""); - strcat_s(command, CMD_SIZE, tmppath); /* quoted tmppath */ - strcat_s(command, CMD_SIZE, "getbuildinfo2.c\""); - - puts(command); fflush(stdout); - if (system(command) < 0) - return 0; - return 1; -} - -const char DELIMS[] = { " \n" }; - -int get_mercurial_info(char * hgbranch, char * hgtag, char * hgrev, int size) -{ - int result = 0; - char filename[CMD_SIZE]; - char cmdline[CMD_SIZE]; - - strcpy_s(filename, CMD_SIZE, "tmpXXXXXX"); - if (_mktemp_s(filename, CMD_SIZE) == 0) { - int rc; - - strcpy_s(cmdline, CMD_SIZE, "hg id -bit > "); - strcat_s(cmdline, CMD_SIZE, filename); - rc = system(cmdline); - if (rc == 0) { - FILE * fp; - - if (fopen_s(&fp, filename, "r") == 0) { - char * cp = fgets(cmdline, CMD_SIZE, fp); - - if (cp) { - char * context = NULL; - char * tp = strtok_s(cp, DELIMS, &context); - if (tp) { - strcpy_s(hgrev, size, tp); - tp = strtok_s(NULL, DELIMS, &context); - if (tp) { - strcpy_s(hgbranch, size, tp); - tp = strtok_s(NULL, DELIMS, &context); - if (tp) { - strcpy_s(hgtag, size, tp); - result = 1; - } - } - } - } - fclose(fp); - } - } - _unlink(filename); - } - return result; -} - -int main(int argc, char*argv[]) -{ - char command[CMD_SIZE] = "cl.exe -c -D_WIN32 -DUSE_DL_EXPORT -D_WINDOWS -DWIN32 -D_WINDLL "; - char tmppath[CMD_SIZE] = ""; - int do_unlink, result; - char *tmpdir = NULL; - if (argc <= 2 || argc > 3) { - fprintf(stderr, "make_buildinfo $(ConfigurationName) [tmpdir]\n"); - return EXIT_FAILURE; - } - if (strcmp(argv[1], "Release") == 0) { - strcat_s(command, CMD_SIZE, "-MD "); - } - else if (strcmp(argv[1], "Debug") == 0) { - strcat_s(command, CMD_SIZE, "-D_DEBUG -MDd "); - } - else if (strcmp(argv[1], "ReleaseItanium") == 0) { - strcat_s(command, CMD_SIZE, "-MD /USECL:MS_ITANIUM "); - } - else if (strcmp(argv[1], "ReleaseAMD64") == 0) { - strcat_s(command, CMD_SIZE, "-MD "); - strcat_s(command, CMD_SIZE, "-MD /USECL:MS_OPTERON "); - } - else { - fprintf(stderr, "unsupported configuration %s\n", argv[1]); - return EXIT_FAILURE; - } - if (argc > 2) { - tmpdir = argv[2]; - strcat_s(tmppath, _countof(tmppath), tmpdir); - /* Hack fix for bad command line: If the command is issued like this: - * $(SolutionDir)make_buildinfo.exe" Debug "$(IntDir)" - * we will get a trailing quote because IntDir ends with a backslash that then - * escapes the final ". To simplify the life for developers, catch that problem - * here by cutting it off. - * The proper command line, btw is: - * $(SolutionDir)make_buildinfo.exe" Debug "$(IntDir)\" - * Hooray for command line parsing on windows. - */ - if (strlen(tmppath) > 0 && tmppath[strlen(tmppath)-1] == '"') - tmppath[strlen(tmppath)-1] = '\0'; - strcat_s(tmppath, _countof(tmppath), "\\"); - } - - if ((do_unlink = make_buildinfo2(tmppath))) { - strcat_s(command, CMD_SIZE, "\""); - strcat_s(command, CMD_SIZE, tmppath); - strcat_s(command, CMD_SIZE, "getbuildinfo2.c\" -DSUBWCREV "); - } - else { - char hgtag[CMD_SIZE]; - char hgbranch[CMD_SIZE]; - char hgrev[CMD_SIZE]; - - if (get_mercurial_info(hgbranch, hgtag, hgrev, CMD_SIZE)) { - strcat_s(command, CMD_SIZE, "-DHGBRANCH=\\\""); - strcat_s(command, CMD_SIZE, hgbranch); - strcat_s(command, CMD_SIZE, "\\\""); - - strcat_s(command, CMD_SIZE, " -DHGTAG=\\\""); - strcat_s(command, CMD_SIZE, hgtag); - strcat_s(command, CMD_SIZE, "\\\""); - - strcat_s(command, CMD_SIZE, " -DHGVERSION=\\\""); - strcat_s(command, CMD_SIZE, hgrev); - strcat_s(command, CMD_SIZE, "\\\" "); - } - strcat_s(command, CMD_SIZE, "..\\..\\Modules\\getbuildinfo.c"); - } - strcat_s(command, CMD_SIZE, " -Fo\""); - strcat_s(command, CMD_SIZE, tmppath); - strcat_s(command, CMD_SIZE, "getbuildinfo.o\" -I..\\..\\Include -I..\\..\\PC"); - puts(command); fflush(stdout); - result = system(command); - if (do_unlink) { - command[0] = '\0'; - strcat_s(command, CMD_SIZE, "\""); - strcat_s(command, CMD_SIZE, tmppath); - strcat_s(command, CMD_SIZE, "getbuildinfo2.c\""); - _unlink(command); - } - if (result < 0) - return EXIT_FAILURE; - return 0; -} diff --git a/PC/VS9.0/make_buildinfo.vcproj b/PC/VS9.0/make_buildinfo.vcproj deleted file mode 100644 index 924065db42bc..000000000000 --- a/PC/VS9.0/make_buildinfo.vcproj +++ /dev/null @@ -1,101 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/make_versioninfo.vcproj b/PC/VS9.0/make_versioninfo.vcproj deleted file mode 100644 index 0a1fd28bc41d..000000000000 --- a/PC/VS9.0/make_versioninfo.vcproj +++ /dev/null @@ -1,324 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/pcbuild.sln b/PC/VS9.0/pcbuild.sln deleted file mode 100644 index 3b73fce490c8..000000000000 --- a/PC/VS9.0/pcbuild.sln +++ /dev/null @@ -1,692 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual Studio 2008 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "python", "python.vcproj", "{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}" - ProjectSection(ProjectDependencies) = postProject - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - {E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058} = {E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "make_versioninfo", "make_versioninfo.vcproj", "{F0E0541E-F17D-430B-97C4-93ADF0DD284E}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythoncore", "pythoncore.vcproj", "{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}" - ProjectSection(ProjectDependencies) = postProject - {F0E0541E-F17D-430B-97C4-93ADF0DD284E} = {F0E0541E-F17D-430B-97C4-93ADF0DD284E} - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31} = {6DE10744-E396-40A5-B4E2-1B69AA7C8D31} - {C73F0EC1-358B-4177-940F-0846AC8B04CD} = {C73F0EC1-358B-4177-940F-0846AC8B04CD} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythonw", "pythonw.vcproj", "{F4229CC3-873C-49AE-9729-DD308ED4CD4A}" - ProjectSection(ProjectDependencies) = postProject - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "make_buildinfo", "make_buildinfo.vcproj", "{C73F0EC1-358B-4177-940F-0846AC8B04CD}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{553EC33E-9816-4996-A660-5D6186A0B0B3}" - ProjectSection(SolutionItems) = preProject - ..\..\Modules\getbuildinfo.c = ..\..\Modules\getbuildinfo.c - readme.txt = readme.txt - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winsound", "winsound.vcproj", "{28B5D777-DDF2-4B6B-B34F-31D938813856}" - ProjectSection(ProjectDependencies) = postProject - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_decimal", "_decimal.vcproj", "{0E9791DB-593A-465F-98BC-681011311617}" - ProjectSection(ProjectDependencies) = postProject - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_ctypes", "_ctypes.vcproj", "{0E9791DB-593A-465F-98BC-681011311618}" - ProjectSection(ProjectDependencies) = postProject - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_ctypes_test", "_ctypes_test.vcproj", "{9EC7190A-249F-4180-A900-548FDCF3055F}" - ProjectSection(ProjectDependencies) = postProject - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_elementtree", "_elementtree.vcproj", "{17E1E049-C309-4D79-843F-AE483C264AEA}" - ProjectSection(ProjectDependencies) = postProject - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_msi", "_msi.vcproj", "{31FFC478-7B4A-43E8-9954-8D03E2187E9C}" - ProjectSection(ProjectDependencies) = postProject - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_socket", "_socket.vcproj", "{86937F53-C189-40EF-8CE8-8759D8E7D480}" - ProjectSection(ProjectDependencies) = postProject - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_sqlite3", "_sqlite3.vcproj", "{13CECB97-4119-4316-9D42-8534019A5A44}" - ProjectSection(ProjectDependencies) = postProject - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - {A1A295E5-463C-437F-81CA-1F32367685DA} = {A1A295E5-463C-437F-81CA-1F32367685DA} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_ssl", "_ssl.vcproj", "{C6E20F84-3247-4AD6-B051-B073268F73BA}" - ProjectSection(ProjectDependencies) = postProject - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9} = {B11D750F-CD1F-4A96-85CE-E69A5C5259F9} - {86937F53-C189-40EF-8CE8-8759D8E7D480} = {86937F53-C189-40EF-8CE8-8759D8E7D480} - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0} = {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0} - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testcapi", "_testcapi.vcproj", "{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}" - ProjectSection(ProjectDependencies) = postProject - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testimportmultiple", "_testimportmultiple.vcproj", "{36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}" - ProjectSection(ProjectDependencies) = postProject - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_tkinter", "_tkinter.vcproj", "{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}" - ProjectSection(ProjectDependencies) = postProject - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_bz2", "_bz2.vcproj", "{73FCD2BD-F133-46B7-8EC1-144CD82A59D5}" - ProjectSection(ProjectDependencies) = postProject - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_lzma", "_lzma.vcproj", "{F9D71780-F393-11E0-BE50-0800200C9A66}" - ProjectSection(ProjectDependencies) = postProject - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "select", "select.vcproj", "{18CAE28C-B454-46C1-87A0-493D91D97F03}" - ProjectSection(ProjectDependencies) = postProject - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unicodedata", "unicodedata.vcproj", "{ECC7CEAC-A5E5-458E-BB9E-2413CC847881}" - ProjectSection(ProjectDependencies) = postProject - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pyexpat", "pyexpat.vcproj", "{D06B6426-4762-44CC-8BAD-D79052507F2F}" - ProjectSection(ProjectDependencies) = postProject - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bdist_wininst", "bdist_wininst.vcproj", "{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_hashlib", "_hashlib.vcproj", "{447F05A8-F581-4CAC-A466-5AC7936E207E}" - ProjectSection(ProjectDependencies) = postProject - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9} = {B11D750F-CD1F-4A96-85CE-E69A5C5259F9} - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0} = {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0} - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sqlite3", "sqlite3.vcproj", "{A1A295E5-463C-437F-81CA-1F32367685DA}" - ProjectSection(ProjectDependencies) = postProject - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31} = {6DE10744-E396-40A5-B4E2-1B69AA7C8D31} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_multiprocessing", "_multiprocessing.vcproj", "{9E48B300-37D1-11DD-8C41-005056C00008}" - ProjectSection(ProjectDependencies) = postProject - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ssl", "ssl.vcproj", "{E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}" - ProjectSection(ProjectDependencies) = postProject - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9} = {B11D750F-CD1F-4A96-85CE-E69A5C5259F9} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kill_python", "kill_python.vcproj", "{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "python3dll", "python3dll.vcproj", "{885D4898-D08D-4091-9C40-C700CFE3FC5A}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xxlimited", "xxlimited.vcproj", "{F749B822-B489-4CA5-A3AD-CE078F5F338A}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testbuffer", "_testbuffer.vcproj", "{A2697BD3-28C1-4AEC-9106-8B748639FD16}" - ProjectSection(ProjectDependencies) = postProject - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_sha3", "_sha3.vcproj", "{04F37400-883C-42D7-AE28-6CF9953BF975}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - PGInstrument|Win32 = PGInstrument|Win32 - PGInstrument|x64 = PGInstrument|x64 - PGUpdate|Win32 = PGUpdate|Win32 - PGUpdate|x64 = PGUpdate|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|Win32.ActiveCfg = Debug|Win32 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|Win32.Build.0 = Debug|Win32 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|x64.ActiveCfg = Debug|x64 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|x64.Build.0 = Debug|x64 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|Win32.ActiveCfg = Release|Win32 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|Win32.Build.0 = Release|Win32 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|x64.ActiveCfg = Release|x64 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|x64.Build.0 = Release|x64 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Debug|Win32.ActiveCfg = Debug|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Debug|Win32.Build.0 = Debug|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Debug|x64.ActiveCfg = Debug|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Debug|x64.Build.0 = Debug|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGInstrument|Win32.ActiveCfg = Release|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGInstrument|Win32.Build.0 = Release|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGInstrument|x64.ActiveCfg = Release|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGInstrument|x64.Build.0 = Release|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGUpdate|Win32.ActiveCfg = Release|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGUpdate|Win32.Build.0 = Release|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGUpdate|x64.ActiveCfg = Release|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGUpdate|x64.Build.0 = Release|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Release|Win32.ActiveCfg = Release|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Release|Win32.Build.0 = Release|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Release|x64.ActiveCfg = Release|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Release|x64.Build.0 = Release|Win32 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|Win32.ActiveCfg = Debug|Win32 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|Win32.Build.0 = Debug|Win32 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|x64.ActiveCfg = Debug|x64 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|x64.Build.0 = Debug|x64 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Release|Win32.ActiveCfg = Release|Win32 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Release|Win32.Build.0 = Release|Win32 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Release|x64.ActiveCfg = Release|x64 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Release|x64.Build.0 = Release|x64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|Win32.ActiveCfg = Debug|Win32 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|Win32.Build.0 = Debug|Win32 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|x64.ActiveCfg = Debug|x64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|x64.Build.0 = Debug|x64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|Win32.ActiveCfg = Release|Win32 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|Win32.Build.0 = Release|Win32 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|x64.ActiveCfg = Release|x64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|x64.Build.0 = Release|x64 - {E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.Debug|Win32.ActiveCfg = Debug|Win32 - {E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.Debug|Win32.Build.0 = Debug|Win32 - {E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.Debug|x64.ActiveCfg = Debug|x64 - {E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.Debug|x64.Build.0 = Debug|x64 - {E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.Release|Win32.ActiveCfg = Release|Win32 - {E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.Release|Win32.Build.0 = Release|Win32 - {E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.Release|x64.ActiveCfg = Release|x64 - {E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.Release|x64.Build.0 = Release|x64 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.Debug|Win32.ActiveCfg = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.Debug|Win32.Build.0 = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.Debug|x64.ActiveCfg = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.Debug|x64.Build.0 = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGInstrument|Win32.ActiveCfg = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGInstrument|Win32.Build.0 = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGInstrument|x64.ActiveCfg = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGInstrument|x64.Build.0 = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGUpdate|Win32.ActiveCfg = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGUpdate|Win32.Build.0 = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGUpdate|x64.ActiveCfg = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGUpdate|x64.Build.0 = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.Release|Win32.ActiveCfg = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.Release|Win32.Build.0 = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.Release|x64.ActiveCfg = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.Release|x64.Build.0 = Release|Win32 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.Debug|Win32.ActiveCfg = Debug|Win32 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.Debug|Win32.Build.0 = Debug|Win32 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.Debug|x64.ActiveCfg = Debug|x64 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.Debug|x64.Build.0 = Debug|x64 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.Release|Win32.ActiveCfg = Release|Win32 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.Release|Win32.Build.0 = Release|Win32 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.Release|x64.ActiveCfg = Release|x64 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.Release|x64.Build.0 = Release|x64 - {0E9791DB-593A-465F-98BC-681011311617}.Debug|Win32.ActiveCfg = Debug|Win32 - {0E9791DB-593A-465F-98BC-681011311617}.Debug|Win32.Build.0 = Debug|Win32 - {0E9791DB-593A-465F-98BC-681011311617}.Debug|x64.ActiveCfg = Debug|x64 - {0E9791DB-593A-465F-98BC-681011311617}.Debug|x64.Build.0 = Debug|x64 - {0E9791DB-593A-465F-98BC-681011311617}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {0E9791DB-593A-465F-98BC-681011311617}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {0E9791DB-593A-465F-98BC-681011311617}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {0E9791DB-593A-465F-98BC-681011311617}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {0E9791DB-593A-465F-98BC-681011311617}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {0E9791DB-593A-465F-98BC-681011311617}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {0E9791DB-593A-465F-98BC-681011311617}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {0E9791DB-593A-465F-98BC-681011311617}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {0E9791DB-593A-465F-98BC-681011311617}.Release|Win32.ActiveCfg = Release|Win32 - {0E9791DB-593A-465F-98BC-681011311617}.Release|Win32.Build.0 = Release|Win32 - {0E9791DB-593A-465F-98BC-681011311617}.Release|x64.ActiveCfg = Release|x64 - {0E9791DB-593A-465F-98BC-681011311617}.Release|x64.Build.0 = Release|x64 - {0E9791DB-593A-465F-98BC-681011311618}.Debug|Win32.ActiveCfg = Debug|Win32 - {0E9791DB-593A-465F-98BC-681011311618}.Debug|Win32.Build.0 = Debug|Win32 - {0E9791DB-593A-465F-98BC-681011311618}.Debug|x64.ActiveCfg = Debug|x64 - {0E9791DB-593A-465F-98BC-681011311618}.Debug|x64.Build.0 = Debug|x64 - {0E9791DB-593A-465F-98BC-681011311618}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {0E9791DB-593A-465F-98BC-681011311618}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {0E9791DB-593A-465F-98BC-681011311618}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {0E9791DB-593A-465F-98BC-681011311618}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {0E9791DB-593A-465F-98BC-681011311618}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {0E9791DB-593A-465F-98BC-681011311618}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {0E9791DB-593A-465F-98BC-681011311618}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {0E9791DB-593A-465F-98BC-681011311618}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {0E9791DB-593A-465F-98BC-681011311618}.Release|Win32.ActiveCfg = Release|Win32 - {0E9791DB-593A-465F-98BC-681011311618}.Release|Win32.Build.0 = Release|Win32 - {0E9791DB-593A-465F-98BC-681011311618}.Release|x64.ActiveCfg = Release|x64 - {0E9791DB-593A-465F-98BC-681011311618}.Release|x64.Build.0 = Release|x64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.Debug|Win32.ActiveCfg = Debug|Win32 - {9EC7190A-249F-4180-A900-548FDCF3055F}.Debug|Win32.Build.0 = Debug|Win32 - {9EC7190A-249F-4180-A900-548FDCF3055F}.Debug|x64.ActiveCfg = Debug|x64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.Debug|x64.Build.0 = Debug|x64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.Release|Win32.ActiveCfg = Release|Win32 - {9EC7190A-249F-4180-A900-548FDCF3055F}.Release|Win32.Build.0 = Release|Win32 - {9EC7190A-249F-4180-A900-548FDCF3055F}.Release|x64.ActiveCfg = Release|x64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.Release|x64.Build.0 = Release|x64 - {17E1E049-C309-4D79-843F-AE483C264AEA}.Debug|Win32.ActiveCfg = Debug|Win32 - {17E1E049-C309-4D79-843F-AE483C264AEA}.Debug|Win32.Build.0 = Debug|Win32 - {17E1E049-C309-4D79-843F-AE483C264AEA}.Debug|x64.ActiveCfg = Debug|x64 - {17E1E049-C309-4D79-843F-AE483C264AEA}.Debug|x64.Build.0 = Debug|x64 - {17E1E049-C309-4D79-843F-AE483C264AEA}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {17E1E049-C309-4D79-843F-AE483C264AEA}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {17E1E049-C309-4D79-843F-AE483C264AEA}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {17E1E049-C309-4D79-843F-AE483C264AEA}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {17E1E049-C309-4D79-843F-AE483C264AEA}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {17E1E049-C309-4D79-843F-AE483C264AEA}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {17E1E049-C309-4D79-843F-AE483C264AEA}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {17E1E049-C309-4D79-843F-AE483C264AEA}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {17E1E049-C309-4D79-843F-AE483C264AEA}.Release|Win32.ActiveCfg = Release|Win32 - {17E1E049-C309-4D79-843F-AE483C264AEA}.Release|Win32.Build.0 = Release|Win32 - {17E1E049-C309-4D79-843F-AE483C264AEA}.Release|x64.ActiveCfg = Release|x64 - {17E1E049-C309-4D79-843F-AE483C264AEA}.Release|x64.Build.0 = Release|x64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|Win32.ActiveCfg = Debug|Win32 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|Win32.Build.0 = Debug|Win32 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|x64.ActiveCfg = Debug|x64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|x64.Build.0 = Debug|x64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|Win32.ActiveCfg = Release|Win32 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|Win32.Build.0 = Release|Win32 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|x64.ActiveCfg = Release|x64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|x64.Build.0 = Release|x64 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.Debug|Win32.ActiveCfg = Debug|Win32 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.Debug|Win32.Build.0 = Debug|Win32 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.Debug|x64.ActiveCfg = Debug|x64 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.Debug|x64.Build.0 = Debug|x64 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.Release|Win32.ActiveCfg = Release|Win32 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.Release|Win32.Build.0 = Release|Win32 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.Release|x64.ActiveCfg = Release|x64 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.Release|x64.Build.0 = Release|x64 - {13CECB97-4119-4316-9D42-8534019A5A44}.Debug|Win32.ActiveCfg = Debug|Win32 - {13CECB97-4119-4316-9D42-8534019A5A44}.Debug|Win32.Build.0 = Debug|Win32 - {13CECB97-4119-4316-9D42-8534019A5A44}.Debug|x64.ActiveCfg = Debug|x64 - {13CECB97-4119-4316-9D42-8534019A5A44}.Debug|x64.Build.0 = Debug|x64 - {13CECB97-4119-4316-9D42-8534019A5A44}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {13CECB97-4119-4316-9D42-8534019A5A44}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {13CECB97-4119-4316-9D42-8534019A5A44}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {13CECB97-4119-4316-9D42-8534019A5A44}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {13CECB97-4119-4316-9D42-8534019A5A44}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {13CECB97-4119-4316-9D42-8534019A5A44}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {13CECB97-4119-4316-9D42-8534019A5A44}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {13CECB97-4119-4316-9D42-8534019A5A44}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {13CECB97-4119-4316-9D42-8534019A5A44}.Release|Win32.ActiveCfg = Release|Win32 - {13CECB97-4119-4316-9D42-8534019A5A44}.Release|Win32.Build.0 = Release|Win32 - {13CECB97-4119-4316-9D42-8534019A5A44}.Release|x64.ActiveCfg = Release|x64 - {13CECB97-4119-4316-9D42-8534019A5A44}.Release|x64.Build.0 = Release|x64 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|Win32.ActiveCfg = Debug|Win32 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|Win32.Build.0 = Debug|Win32 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|x64.ActiveCfg = Debug|x64 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|x64.Build.0 = Debug|x64 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|Win32.ActiveCfg = Release|Win32 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|Win32.Build.0 = Release|Win32 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|x64.ActiveCfg = Release|x64 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|x64.Build.0 = Release|x64 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Debug|Win32.ActiveCfg = Debug|Win32 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Debug|Win32.Build.0 = Debug|Win32 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Debug|x64.ActiveCfg = Debug|x64 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Debug|x64.Build.0 = Debug|x64 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|Win32.ActiveCfg = Release|Win32 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|Win32.Build.0 = Release|Win32 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|x64.ActiveCfg = Release|x64 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|x64.Build.0 = Release|x64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Debug|Win32.ActiveCfg = Debug|Win32 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Debug|Win32.Build.0 = Debug|Win32 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Debug|x64.ActiveCfg = Debug|x64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Debug|x64.Build.0 = Debug|x64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Release|Win32.ActiveCfg = Release|Win32 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Release|Win32.Build.0 = Release|Win32 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Release|x64.ActiveCfg = Release|x64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Release|x64.Build.0 = Release|x64 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Debug|Win32.ActiveCfg = Debug|Win32 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Debug|Win32.Build.0 = Debug|Win32 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Debug|x64.ActiveCfg = Debug|x64 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Debug|x64.Build.0 = Debug|x64 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Release|Win32.ActiveCfg = Release|Win32 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Release|Win32.Build.0 = Release|Win32 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Release|x64.ActiveCfg = Release|x64 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Release|x64.Build.0 = Release|x64 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Debug|Win32.ActiveCfg = Debug|Win32 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Debug|Win32.Build.0 = Debug|Win32 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Debug|x64.ActiveCfg = Debug|x64 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Debug|x64.Build.0 = Debug|x64 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Release|Win32.ActiveCfg = Release|Win32 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Release|Win32.Build.0 = Release|Win32 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Release|x64.ActiveCfg = Release|x64 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Release|x64.Build.0 = Release|x64 - {F9D71780-F393-11E0-BE50-0800200C9A66}.Debug|Win32.ActiveCfg = Debug|Win32 - {F9D71780-F393-11E0-BE50-0800200C9A66}.Debug|Win32.Build.0 = Debug|Win32 - {F9D71780-F393-11E0-BE50-0800200C9A66}.Debug|x64.ActiveCfg = Debug|x64 - {F9D71780-F393-11E0-BE50-0800200C9A66}.Debug|x64.Build.0 = Debug|x64 - {F9D71780-F393-11E0-BE50-0800200C9A66}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {F9D71780-F393-11E0-BE50-0800200C9A66}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {F9D71780-F393-11E0-BE50-0800200C9A66}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {F9D71780-F393-11E0-BE50-0800200C9A66}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {F9D71780-F393-11E0-BE50-0800200C9A66}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {F9D71780-F393-11E0-BE50-0800200C9A66}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {F9D71780-F393-11E0-BE50-0800200C9A66}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {F9D71780-F393-11E0-BE50-0800200C9A66}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {F9D71780-F393-11E0-BE50-0800200C9A66}.Release|Win32.ActiveCfg = Release|Win32 - {F9D71780-F393-11E0-BE50-0800200C9A66}.Release|Win32.Build.0 = Release|Win32 - {F9D71780-F393-11E0-BE50-0800200C9A66}.Release|x64.ActiveCfg = Release|x64 - {F9D71780-F393-11E0-BE50-0800200C9A66}.Release|x64.Build.0 = Release|x64 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.Debug|Win32.ActiveCfg = Debug|Win32 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.Debug|Win32.Build.0 = Debug|Win32 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.Debug|x64.ActiveCfg = Debug|x64 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.Debug|x64.Build.0 = Debug|x64 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.Release|Win32.ActiveCfg = Release|Win32 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.Release|Win32.Build.0 = Release|Win32 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.Release|x64.ActiveCfg = Release|x64 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.Release|x64.Build.0 = Release|x64 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Debug|Win32.ActiveCfg = Debug|Win32 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Debug|Win32.Build.0 = Debug|Win32 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Debug|x64.ActiveCfg = Debug|x64 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Debug|x64.Build.0 = Debug|x64 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Release|Win32.ActiveCfg = Release|Win32 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Release|Win32.Build.0 = Release|Win32 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Release|x64.ActiveCfg = Release|x64 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Release|x64.Build.0 = Release|x64 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.Debug|Win32.ActiveCfg = Debug|Win32 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.Debug|Win32.Build.0 = Debug|Win32 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.Debug|x64.ActiveCfg = Debug|x64 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.Debug|x64.Build.0 = Debug|x64 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|Win32.ActiveCfg = Release|Win32 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|Win32.Build.0 = Release|Win32 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|x64.ActiveCfg = Release|x64 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|x64.Build.0 = Release|x64 - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Debug|Win32.ActiveCfg = Release|Win32 - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Debug|x64.ActiveCfg = Release|x64 - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGInstrument|Win32.ActiveCfg = Release|Win32 - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGInstrument|x64.ActiveCfg = Release|x64 - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGUpdate|Win32.ActiveCfg = Release|Win32 - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGUpdate|x64.ActiveCfg = Release|x64 - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Release|Win32.ActiveCfg = Release|Win32 - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Release|x64.ActiveCfg = Release|x64 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|Win32.ActiveCfg = Debug|Win32 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|Win32.Build.0 = Debug|Win32 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|x64.ActiveCfg = Debug|x64 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|x64.Build.0 = Debug|x64 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.Release|Win32.ActiveCfg = Release|Win32 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.Release|Win32.Build.0 = Release|Win32 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.Release|x64.ActiveCfg = Release|x64 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.Release|x64.Build.0 = Release|x64 - {A1A295E5-463C-437F-81CA-1F32367685DA}.Debug|Win32.ActiveCfg = Debug|Win32 - {A1A295E5-463C-437F-81CA-1F32367685DA}.Debug|Win32.Build.0 = Debug|Win32 - {A1A295E5-463C-437F-81CA-1F32367685DA}.Debug|x64.ActiveCfg = Debug|x64 - {A1A295E5-463C-437F-81CA-1F32367685DA}.Debug|x64.Build.0 = Debug|x64 - {A1A295E5-463C-437F-81CA-1F32367685DA}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {A1A295E5-463C-437F-81CA-1F32367685DA}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {A1A295E5-463C-437F-81CA-1F32367685DA}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {A1A295E5-463C-437F-81CA-1F32367685DA}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {A1A295E5-463C-437F-81CA-1F32367685DA}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {A1A295E5-463C-437F-81CA-1F32367685DA}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {A1A295E5-463C-437F-81CA-1F32367685DA}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {A1A295E5-463C-437F-81CA-1F32367685DA}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {A1A295E5-463C-437F-81CA-1F32367685DA}.Release|Win32.ActiveCfg = Release|Win32 - {A1A295E5-463C-437F-81CA-1F32367685DA}.Release|Win32.Build.0 = Release|Win32 - {A1A295E5-463C-437F-81CA-1F32367685DA}.Release|x64.ActiveCfg = Release|x64 - {A1A295E5-463C-437F-81CA-1F32367685DA}.Release|x64.Build.0 = Release|x64 - {9E48B300-37D1-11DD-8C41-005056C00008}.Debug|Win32.ActiveCfg = Debug|Win32 - {9E48B300-37D1-11DD-8C41-005056C00008}.Debug|Win32.Build.0 = Debug|Win32 - {9E48B300-37D1-11DD-8C41-005056C00008}.Debug|x64.ActiveCfg = Debug|x64 - {9E48B300-37D1-11DD-8C41-005056C00008}.Debug|x64.Build.0 = Debug|x64 - {9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {9E48B300-37D1-11DD-8C41-005056C00008}.Release|Win32.ActiveCfg = Release|Win32 - {9E48B300-37D1-11DD-8C41-005056C00008}.Release|Win32.Build.0 = Release|Win32 - {9E48B300-37D1-11DD-8C41-005056C00008}.Release|x64.ActiveCfg = Release|x64 - {9E48B300-37D1-11DD-8C41-005056C00008}.Release|x64.Build.0 = Release|x64 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Debug|Win32.ActiveCfg = Debug|Win32 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Debug|Win32.Build.0 = Debug|Win32 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Debug|x64.ActiveCfg = Debug|x64 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Debug|x64.Build.0 = Debug|x64 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Release|Win32.ActiveCfg = Release|Win32 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Release|Win32.Build.0 = Release|Win32 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Release|x64.ActiveCfg = Release|x64 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Release|x64.Build.0 = Release|x64 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Debug|Win32.ActiveCfg = Debug|Win32 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Debug|Win32.Build.0 = Debug|Win32 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Debug|x64.ActiveCfg = Debug|x64 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Debug|x64.Build.0 = Debug|x64 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGInstrument|Win32.ActiveCfg = Release|Win32 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGInstrument|Win32.Build.0 = Release|Win32 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGInstrument|x64.ActiveCfg = Release|x64 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGInstrument|x64.Build.0 = Release|x64 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGUpdate|Win32.ActiveCfg = Release|Win32 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGUpdate|Win32.Build.0 = Release|Win32 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGUpdate|x64.ActiveCfg = Release|x64 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGUpdate|x64.Build.0 = Release|x64 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Release|Win32.ActiveCfg = Release|Win32 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Release|Win32.Build.0 = Release|Win32 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Release|x64.ActiveCfg = Release|x64 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Release|x64.Build.0 = Release|x64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|Win32.ActiveCfg = PGInstrument|Win32 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|x64.ActiveCfg = PGUpdate|x64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|x64.Build.0 = PGUpdate|x64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|Win32.ActiveCfg = Release|Win32 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|Win32.Build.0 = Release|Win32 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|x64.ActiveCfg = Release|x64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|x64.Build.0 = Release|x64 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Debug|Win32.ActiveCfg = Debug|Win32 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Debug|Win32.Build.0 = Debug|Win32 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Debug|x64.ActiveCfg = Debug|x64 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Debug|x64.Build.0 = Debug|x64 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|Win32.ActiveCfg = Release|Win32 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|Win32.Build.0 = Release|Win32 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|x64.ActiveCfg = Release|x64 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|x64.Build.0 = Release|x64 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|Win32.ActiveCfg = Release|Win32 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|Win32.Build.0 = Release|Win32 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|x64.ActiveCfg = Release|x64 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|x64.Build.0 = Release|x64 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Release|Win32.ActiveCfg = Release|Win32 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Release|Win32.Build.0 = Release|Win32 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Release|x64.ActiveCfg = Release|x64 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Release|x64.Build.0 = Release|x64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Debug|Win32.ActiveCfg = Debug|Win32 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Debug|Win32.Build.0 = Debug|Win32 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Debug|x64.ActiveCfg = Debug|x64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Debug|x64.Build.0 = Debug|x64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Release|Win32.ActiveCfg = Release|Win32 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Release|Win32.Build.0 = Release|Win32 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Release|x64.ActiveCfg = Release|x64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Release|x64.Build.0 = Release|x64 - {04F37400-883C-42D7-AE28-6CF9953BF975}.Debug|Win32.ActiveCfg = Debug|Win32 - {04F37400-883C-42D7-AE28-6CF9953BF975}.Debug|Win32.Build.0 = Debug|Win32 - {04F37400-883C-42D7-AE28-6CF9953BF975}.Debug|x64.ActiveCfg = Debug|x64 - {04F37400-883C-42D7-AE28-6CF9953BF975}.Debug|x64.Build.0 = Debug|x64 - {04F37400-883C-42D7-AE28-6CF9953BF975}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {04F37400-883C-42D7-AE28-6CF9953BF975}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {04F37400-883C-42D7-AE28-6CF9953BF975}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {04F37400-883C-42D7-AE28-6CF9953BF975}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {04F37400-883C-42D7-AE28-6CF9953BF975}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {04F37400-883C-42D7-AE28-6CF9953BF975}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {04F37400-883C-42D7-AE28-6CF9953BF975}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {04F37400-883C-42D7-AE28-6CF9953BF975}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {04F37400-883C-42D7-AE28-6CF9953BF975}.Release|Win32.ActiveCfg = Release|Win32 - {04F37400-883C-42D7-AE28-6CF9953BF975}.Release|Win32.Build.0 = Release|Win32 - {04F37400-883C-42D7-AE28-6CF9953BF975}.Release|x64.ActiveCfg = Release|x64 - {04F37400-883C-42D7-AE28-6CF9953BF975}.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/PC/VS9.0/pginstrument.vsprops b/PC/VS9.0/pginstrument.vsprops deleted file mode 100644 index 99c117b15267..000000000000 --- a/PC/VS9.0/pginstrument.vsprops +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - diff --git a/PC/VS9.0/pgupdate.vsprops b/PC/VS9.0/pgupdate.vsprops deleted file mode 100644 index 26cfc2d0dd9c..000000000000 --- a/PC/VS9.0/pgupdate.vsprops +++ /dev/null @@ -1,14 +0,0 @@ - - - - diff --git a/PC/VS9.0/pyd.vsprops b/PC/VS9.0/pyd.vsprops deleted file mode 100644 index 34c21e15c5e6..000000000000 --- a/PC/VS9.0/pyd.vsprops +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - diff --git a/PC/VS9.0/pyd_d.vsprops b/PC/VS9.0/pyd_d.vsprops deleted file mode 100644 index 313a30b782fd..000000000000 --- a/PC/VS9.0/pyd_d.vsprops +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - diff --git a/PC/VS9.0/pyexpat.vcproj b/PC/VS9.0/pyexpat.vcproj deleted file mode 100644 index a8d2cd752728..000000000000 --- a/PC/VS9.0/pyexpat.vcproj +++ /dev/null @@ -1,553 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/pyproject.vsprops b/PC/VS9.0/pyproject.vsprops deleted file mode 100644 index ed5464d202e9..000000000000 --- a/PC/VS9.0/pyproject.vsprops +++ /dev/null @@ -1,91 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/python.vcproj b/PC/VS9.0/python.vcproj deleted file mode 100644 index b07de2183ff1..000000000000 --- a/PC/VS9.0/python.vcproj +++ /dev/null @@ -1,637 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/python3dll.vcproj b/PC/VS9.0/python3dll.vcproj deleted file mode 100644 index ed7333bc5677..000000000000 --- a/PC/VS9.0/python3dll.vcproj +++ /dev/null @@ -1,246 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/pythoncore.vcproj b/PC/VS9.0/pythoncore.vcproj deleted file mode 100644 index cf60470ce2c3..000000000000 --- a/PC/VS9.0/pythoncore.vcproj +++ /dev/null @@ -1,1877 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/pythonw.vcproj b/PC/VS9.0/pythonw.vcproj deleted file mode 100644 index 7f5c04b9b554..000000000000 --- a/PC/VS9.0/pythonw.vcproj +++ /dev/null @@ -1,618 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/release.vsprops b/PC/VS9.0/release.vsprops deleted file mode 100644 index 08def90651b0..000000000000 --- a/PC/VS9.0/release.vsprops +++ /dev/null @@ -1,15 +0,0 @@ - - - - - diff --git a/PC/VS9.0/select.vcproj b/PC/VS9.0/select.vcproj deleted file mode 100644 index 637fd972ce0e..000000000000 --- a/PC/VS9.0/select.vcproj +++ /dev/null @@ -1,537 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/sqlite3.vcproj b/PC/VS9.0/sqlite3.vcproj deleted file mode 100644 index ef8c328c6992..000000000000 --- a/PC/VS9.0/sqlite3.vcproj +++ /dev/null @@ -1,537 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/sqlite3.vsprops b/PC/VS9.0/sqlite3.vsprops deleted file mode 100644 index b502df5ace36..000000000000 --- a/PC/VS9.0/sqlite3.vsprops +++ /dev/null @@ -1,14 +0,0 @@ - - - - diff --git a/PC/VS9.0/ssl.vcproj b/PC/VS9.0/ssl.vcproj deleted file mode 100644 index d30e877024f6..000000000000 --- a/PC/VS9.0/ssl.vcproj +++ /dev/null @@ -1,189 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/unicodedata.vcproj b/PC/VS9.0/unicodedata.vcproj deleted file mode 100644 index b66ff72228fb..000000000000 --- a/PC/VS9.0/unicodedata.vcproj +++ /dev/null @@ -1,533 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/winsound.vcproj b/PC/VS9.0/winsound.vcproj deleted file mode 100644 index 47dbf29322c9..000000000000 --- a/PC/VS9.0/winsound.vcproj +++ /dev/null @@ -1,523 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/x64.vsprops b/PC/VS9.0/x64.vsprops deleted file mode 100644 index d06f470cebad..000000000000 --- a/PC/VS9.0/x64.vsprops +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - diff --git a/PC/VS9.0/xxlimited.vcproj b/PC/VS9.0/xxlimited.vcproj deleted file mode 100644 index a3aaad65836e..000000000000 --- a/PC/VS9.0/xxlimited.vcproj +++ /dev/null @@ -1,417 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/bdist_wininst/archive.h b/PC/bdist_wininst/archive.h index 31a7805fd1d0..50ff15cdddf0 100644 --- a/PC/bdist_wininst/archive.h +++ b/PC/bdist_wininst/archive.h @@ -1,10 +1,9 @@ /* - IMPORTANT NOTE: IF THIS FILE IS CHANGED, WININST-6.EXE MUST BE RECOMPILED - WITH THE MSVC6 WININST.DSW WORKSPACE FILE MANUALLY, AND WININST-7.1.EXE MUST - BE RECOMPILED WITH THE MSVC 2003.NET WININST-7.1.VCPROJ FILE MANUALLY. + IMPORTANT NOTE: IF THIS FILE IS CHANGED, PCBUILD\BDIST_WININST.VCXPROJ MUST + BE REBUILT AS WELL. - IF CHANGES TO THIS FILE ARE CHECKED INTO PYTHON CVS, THE RECOMPILED BINARIES - MUST BE CHECKED IN AS WELL! + IF CHANGES TO THIS FILE ARE CHECKED IN, THE RECOMPILED BINARIES MUST BE + CHECKED IN AS WELL! */ #pragma pack(1) diff --git a/PC/bdist_wininst/bdist_wininst.vcxproj b/PC/bdist_wininst/bdist_wininst.vcxproj new file mode 100644 index 000000000000..2ab474e43967 --- /dev/null +++ b/PC/bdist_wininst/bdist_wininst.vcxproj @@ -0,0 +1,103 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + PGInstrument + Win32 + + + PGInstrument + x64 + + + PGUpdate + Win32 + + + PGUpdate + x64 + + + Release + Win32 + + + Release + x64 + + + + {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C} + wininst + ClCompile + false + + + + + Application + false + NotSet + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(PySourcePath)lib\distutils\command\ + false + wininst-$(VisualStudioVersion) + $(TargetName)-amd64 + .exe + + + + $(OutDir)wininst.tlb + + + MinSpace + $(PySourcePath)Modules\zlib;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) + + + $(PySourcePath)PC\bdist_wininst;%(AdditionalIncludeDirectories) + + + comctl32.lib;imagehlp.lib;%(AdditionalDependencies) + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PCbuild/bdist_wininst.vcxproj.filters b/PC/bdist_wininst/bdist_wininst.vcxproj.filters similarity index 100% rename from PCbuild/bdist_wininst.vcxproj.filters rename to PC/bdist_wininst/bdist_wininst.vcxproj.filters diff --git a/PC/bdist_wininst/build.bat b/PC/bdist_wininst/build.bat new file mode 100644 index 000000000000..ee6856754faa --- /dev/null +++ b/PC/bdist_wininst/build.bat @@ -0,0 +1,22 @@ +@echo off +setlocal + +set D=%~dp0 +set PCBUILD=%~dp0..\..\PCBuild\ + + +echo Building Lib\distutils\command\wininst-xx.0.exe + +call "%PCBUILD%env.bat" x86 +if errorlevel 1 goto :eof + +msbuild "%D%bdist_wininst.vcxproj" "/p:SolutionDir=%PCBUILD%\" /p:Configuration=Release /p:Platform=Win32 +if errorlevel 1 goto :eof + + +echo Building Lib\distutils\command\wininst-xx.0-amd64.exe + +call "%PCBUILD%env.bat" x86_amd64 +if errorlevel 1 goto :eof + +msbuild "%D%bdist_wininst.vcxproj" "/p:SolutionDir=%PCBUILD%\" /p:Configuration=Release /p:Platform=x64 diff --git a/PC/bdist_wininst/extract.c b/PC/bdist_wininst/extract.c index aec8eda2be85..0249d9ff542f 100644 --- a/PC/bdist_wininst/extract.c +++ b/PC/bdist_wininst/extract.c @@ -1,10 +1,9 @@ /* - IMPORTANT NOTE: IF THIS FILE IS CHANGED, WININST-6.EXE MUST BE RECOMPILED - WITH THE MSVC6 WININST.DSW WORKSPACE FILE MANUALLY, AND WININST-7.1.EXE MUST - BE RECOMPILED WITH THE MSVC 2003.NET WININST-7.1.VCPROJ FILE MANUALLY. + IMPORTANT NOTE: IF THIS FILE IS CHANGED, PCBUILD\BDIST_WININST.VCXPROJ MUST + BE REBUILT AS WELL. - IF CHANGES TO THIS FILE ARE CHECKED INTO PYTHON CVS, THE RECOMPILED BINARIES - MUST BE CHECKED IN AS WELL! + IF CHANGES TO THIS FILE ARE CHECKED IN, THE RECOMPILED BINARIES MUST BE + CHECKED IN AS WELL! */ #include diff --git a/PC/bdist_wininst/install.c b/PC/bdist_wininst/install.c index e9401d9f3f57..bb2eb34a67bf 100644 --- a/PC/bdist_wininst/install.c +++ b/PC/bdist_wininst/install.c @@ -1,10 +1,9 @@ /* - IMPORTANT NOTE: IF THIS FILE IS CHANGED, WININST-6.EXE MUST BE RECOMPILED - WITH THE MSVC6 WININST.DSW WORKSPACE FILE MANUALLY, AND WININST-7.1.EXE MUST - BE RECOMPILED WITH THE MSVC 2003.NET WININST-7.1.VCPROJ FILE MANUALLY. + IMPORTANT NOTE: IF THIS FILE IS CHANGED, PCBUILD\BDIST_WININST.VCXPROJ MUST + BE REBUILT AS WELL. - IF CHANGES TO THIS FILE ARE CHECKED INTO PYTHON CVS, THE RECOMPILED BINARIES - MUST BE CHECKED IN AS WELL! + IF CHANGES TO THIS FILE ARE CHECKED IN, THE RECOMPILED BINARIES MUST BE + CHECKED IN AS WELL! */ /* @@ -1216,7 +1215,7 @@ static void CenterWindow(HWND hwnd) #include -BOOL CALLBACK +INT_PTR CALLBACK IntroDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { LPNMHDR lpnm; @@ -1565,7 +1564,7 @@ SCHEME *GetScheme(int major, int minor) return old_scheme; } -BOOL CALLBACK +INT_PTR CALLBACK SelectPythonDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { LPNMHDR lpnm; @@ -1774,6 +1773,16 @@ static BOOL OpenLogfile(char *dir) sprintf(buffer, "%s\\%s-wininst.log", dir, meta_name); logfile = fopen(buffer, "a"); + if (!logfile) { + char error[1024]; + + sprintf(error, "Can't create \"%s\" (%s).\n\n" + "Try to execute the installer as administrator.", + buffer, strerror(errno)); + MessageBox(GetFocus(), error, NULL, MB_OK | MB_ICONSTOP); + return FALSE; + } + time(<ime); now = localtime(<ime); strftime(buffer, sizeof(buffer), @@ -1857,7 +1866,7 @@ static void CloseLogfile(void) fclose(logfile); } -BOOL CALLBACK +INT_PTR CALLBACK InstallFilesDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { LPNMHDR lpnm; @@ -2012,7 +2021,7 @@ InstallFilesDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) } -BOOL CALLBACK +INT_PTR CALLBACK FinishedDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { LPNMHDR lpnm; @@ -2188,23 +2197,6 @@ BOOL NeedAutoUAC() return TRUE; } -// Returns TRUE if the platform supports UAC. -BOOL PlatformSupportsUAC() -{ - // Note that win2k does seem to support ShellExecute with 'runas', - // but does *not* support IsUserAnAdmin - so we just pretend things - // only work on XP and later. - BOOL bIsWindowsXPorLater; - OSVERSIONINFO winverinfo; - winverinfo.dwOSVersionInfoSize = sizeof(winverinfo); - if (!GetVersionEx(&winverinfo)) - return FALSE; // something bad has gone wrong - bIsWindowsXPorLater = - ( (winverinfo.dwMajorVersion > 5) || - ( (winverinfo.dwMajorVersion == 5) && (winverinfo.dwMinorVersion >= 1) )); - return bIsWindowsXPorLater; -} - // Spawn ourself as an elevated application. On failure, a message is // displayed to the user - but this app will always terminate, even // on error. @@ -2260,7 +2252,7 @@ int DoInstall(void) // See if we need to do the Vista UAC magic. if (strcmp(user_access_control, "force")==0) { - if (PlatformSupportsUAC() && !MyIsUserAnAdmin()) { + if (!MyIsUserAnAdmin()) { SpawnUAC(); return 0; } @@ -2268,7 +2260,7 @@ int DoInstall(void) } else if (strcmp(user_access_control, "auto")==0) { // Check if it looks like we need UAC control, based // on how Python itself was installed. - if (PlatformSupportsUAC() && !MyIsUserAnAdmin() && NeedAutoUAC()) { + if (!MyIsUserAnAdmin() && NeedAutoUAC()) { SpawnUAC(); return 0; } diff --git a/PC/bdist_wininst/install.rc b/PC/bdist_wininst/install.rc index d018b484b0a9..dfa2ffcd7415 100644 --- a/PC/bdist_wininst/install.rc +++ b/PC/bdist_wininst/install.rc @@ -1,97 +1,20 @@ /* - IMPORTANT NOTE: IF THIS FILE IS CHANGED, WININST-6.EXE MUST BE RECOMPILED - WITH THE MSVC6 WININST.DSW WORKSPACE FILE MANUALLY, AND WININST-7.1.EXE MUST - BE RECOMPILED WITH THE MSVC 2003.NET WININST-7.1.VCPROJ FILE MANUALLY. + IMPORTANT NOTE: IF THIS FILE IS CHANGED, PCBUILD\BDIST_WININST.VCXPROJ MUST + BE REBUILT AS WELL. - IF CHANGES TO THIS FILE ARE CHECKED INTO PYTHON CVS, THE RECOMPILED BINARIES - MUST BE CHECKED IN AS WELL! + IF CHANGES TO THIS FILE ARE CHECKED IN, THE RECOMPILED BINARIES MUST BE + CHECKED IN AS WELL! */ -//Microsoft Developer Studio generated resource script. -// +#include #include "resource.h" -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "afxres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// Neutral resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) -#ifdef _WIN32 LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL #pragma code_page(1252) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Bitmap -// IDB_BITMAP BITMAP DISCARDABLE "PythonPowered.bmp" -#endif // Neutral resources -///////////////////////////////////////////////////////////////////////////// - - -///////////////////////////////////////////////////////////////////////////// -// German (Germany) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU) -#ifdef _WIN32 -LANGUAGE LANG_GERMAN, SUBLANG_GERMAN -#pragma code_page(1252) -#endif //_WIN32 - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE DISCARDABLE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE DISCARDABLE -BEGIN - "#include ""afxres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE DISCARDABLE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - -#endif // German (Germany) resources -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -// English (U.S.) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - IDD_INTRO DIALOGEX 0, 0, 379, 178 STYLE WS_CHILD | WS_DISABLED | WS_CAPTION CAPTION "Setup" @@ -152,78 +75,3 @@ BEGIN EDITTEXT IDC_INFO,125,40,247,131,ES_MULTILINE | ES_READONLY | WS_VSCROLL | WS_HSCROLL | NOT WS_TABSTOP END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO DISCARDABLE -BEGIN - IDD_INTRO, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 372 - VERTGUIDE, 125 - VERTGUIDE, 372 - TOPMARGIN, 7 - BOTTOMMARGIN, 171 - HORZGUIDE, 8 - HORZGUIDE, 31 - END - - IDD_SELECTPYTHON, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 372 - VERTGUIDE, 125 - VERTGUIDE, 372 - TOPMARGIN, 7 - BOTTOMMARGIN, 171 - HORZGUIDE, 8 - HORZGUIDE, 41 - END - - IDD_INSTALLFILES, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 372 - VERTGUIDE, 125 - VERTGUIDE, 371 - TOPMARGIN, 7 - BOTTOMMARGIN, 171 - HORZGUIDE, 8 - HORZGUIDE, 41 - END - - IDD_FINISHED, DIALOG - BEGIN - LEFTMARGIN, 6 - RIGHTMARGIN, 372 - VERTGUIDE, 125 - VERTGUIDE, 372 - TOPMARGIN, 7 - BOTTOMMARGIN, 171 - HORZGUIDE, 8 - HORZGUIDE, 41 - END -END -#endif // APSTUDIO_INVOKED - -#endif // English (U.S.) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/PC/bdist_wininst/resource.h b/PC/bdist_wininst/resource.h index 35ba3c2534d5..86aeabb13ad5 100644 --- a/PC/bdist_wininst/resource.h +++ b/PC/bdist_wininst/resource.h @@ -1,16 +1,11 @@ /* - IMPORTANT NOTE: IF THIS FILE IS CHANGED, WININST-6.EXE MUST BE RECOMPILED - WITH THE MSVC6 WININST.DSW WORKSPACE FILE MANUALLY, AND WININST-7.1.EXE MUST - BE RECOMPILED WITH THE MSVC 2003.NET WININST-7.1.VCPROJ FILE MANUALLY. + IMPORTANT NOTE: IF THIS FILE IS CHANGED, PCBUILD\BDIST_WININST.VCXPROJ MUST + BE REBUILT AS WELL. - IF CHANGES TO THIS FILE ARE CHECKED INTO PYTHON CVS, THE RECOMPILED BINARIES - MUST BE CHECKED IN AS WELL! + IF CHANGES TO THIS FILE ARE CHECKED IN, THE RECOMPILED BINARIES MUST BE + CHECKED IN AS WELL! */ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by install.rc -// #define IDD_DIALOG1 101 #define IDB_BITMAP1 103 #define IDD_INTRO 107 @@ -34,14 +29,3 @@ #define IDC_BUILD_INFO 1024 #define IDC_BITMAP 1025 #define IDC_OTHERPYTHON 1026 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 112 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1028 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/PC/bdist_wininst/wininst-7.1.sln b/PC/bdist_wininst/wininst-7.1.sln deleted file mode 100644 index e205d25c507a..000000000000 --- a/PC/bdist_wininst/wininst-7.1.sln +++ /dev/null @@ -1,21 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 8.00 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wininst", "wininst-7.1.vcproj", "{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfiguration) = preSolution - Debug = Debug - Release = Release - EndGlobalSection - GlobalSection(ProjectConfiguration) = postSolution - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Debug.ActiveCfg = Debug|Win32 - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Debug.Build.0 = Debug|Win32 - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Release.ActiveCfg = Release|Win32 - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Release.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - EndGlobalSection - GlobalSection(ExtensibilityAddIns) = postSolution - EndGlobalSection -EndGlobal diff --git a/PC/bdist_wininst/wininst-7.1.vcproj b/PC/bdist_wininst/wininst-7.1.vcproj deleted file mode 100644 index 30daae9ff6d1..000000000000 --- a/PC/bdist_wininst/wininst-7.1.vcproj +++ /dev/null @@ -1,214 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/bdist_wininst/wininst-8.sln b/PC/bdist_wininst/wininst-8.sln deleted file mode 100644 index 25f16cfba273..000000000000 --- a/PC/bdist_wininst/wininst-8.sln +++ /dev/null @@ -1,19 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 9.00 -# Visual Studio 2005 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wininst", "wininst-8.vcproj", "{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Debug|Win32.ActiveCfg = Debug|Win32 - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Debug|Win32.Build.0 = Debug|Win32 - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Release|Win32.ActiveCfg = Release|Win32 - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Release|Win32.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/PC/bdist_wininst/wininst-8.vcproj b/PC/bdist_wininst/wininst-8.vcproj deleted file mode 100644 index 0147d1b3fbfa..000000000000 --- a/PC/bdist_wininst/wininst-8.vcproj +++ /dev/null @@ -1,320 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/bdist_wininst/wininst.dsp b/PC/bdist_wininst/wininst.dsp deleted file mode 100644 index 698556980deb..000000000000 --- a/PC/bdist_wininst/wininst.dsp +++ /dev/null @@ -1,123 +0,0 @@ -# Microsoft Developer Studio Project File - Name="wininst" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Application" 0x0101 - -CFG=wininst - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "wininst.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "wininst.mak" CFG="wininst - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "wininst - Win32 Release" (based on "Win32 (x86) Application") -!MESSAGE "wininst - Win32 Debug" (based on "Win32 (x86) Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "wininst - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "..\..\lib\distutils\command" -# PROP Intermediate_Dir "temp-release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /O1 /I "..\..\Include" /I "..\..\..\zlib-1.2.3" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x407 /d "NDEBUG" -# ADD RSC /l 0x407 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 -# ADD LINK32 ..\..\..\zlib-1.2.3\zlib.lib imagehlp.lib comdlg32.lib ole32.lib comctl32.lib kernel32.lib user32.lib gdi32.lib advapi32.lib shell32.lib /nologo /subsystem:windows /machine:I386 /nodefaultlib:"LIBC" /out:"..\..\lib\distutils\command/wininst-6.0.exe" - -!ELSEIF "$(CFG)" == "wininst - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "." -# PROP Intermediate_Dir "temp-debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MD /W3 /Z7 /Od /I "..\..\Include" /I "..\..\..\zlib-1.2.1" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /FR /YX /FD /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x407 /d "_DEBUG" -# ADD RSC /l 0x407 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept -# ADD LINK32 ..\..\..\zlib-1.2.3\zlib.lib imagehlp.lib comdlg32.lib ole32.lib comctl32.lib kernel32.lib user32.lib gdi32.lib advapi32.lib shell32.lib /nologo /subsystem:windows /pdb:none /debug /machine:I386 /nodefaultlib:"LIBC" /out:"..\..\lib\distutils\command/wininst-6.0_d.exe" - -!ENDIF - -# Begin Target - -# Name "wininst - Win32 Release" -# Name "wininst - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=.\extract.c -# End Source File -# Begin Source File - -SOURCE=.\install.c -# End Source File -# Begin Source File - -SOURCE=.\install.rc -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=.\archive.h -# End Source File -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# Begin Source File - -SOURCE=.\PythonPowered.bmp -# End Source File -# End Group -# End Target -# End Project diff --git a/PC/bdist_wininst/wininst.dsw b/PC/bdist_wininst/wininst.dsw deleted file mode 100644 index fbc66aa97349..000000000000 --- a/PC/bdist_wininst/wininst.dsw +++ /dev/null @@ -1,29 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "wininst"=.\wininst.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/PC/config.c b/PC/config.c index 72c938113008..48dbcc027390 100644 --- a/PC/config.c +++ b/PC/config.c @@ -19,7 +19,7 @@ extern PyObject* PyInit_math(void); extern PyObject* PyInit__md5(void); extern PyObject* PyInit_nt(void); extern PyObject* PyInit__operator(void); -extern PyObject* PyInit_signal(void); +extern PyObject* PyInit__signal(void); extern PyObject* PyInit__sha1(void); extern PyObject* PyInit__sha256(void); extern PyObject* PyInit__sha512(void); @@ -91,7 +91,7 @@ struct _inittab _PyImport_Inittab[] = { {"math", PyInit_math}, {"nt", PyInit_nt}, /* Use the NT os functions, not posix */ {"_operator", PyInit__operator}, - {"signal", PyInit_signal}, + {"_signal", PyInit__signal}, {"_md5", PyInit__md5}, {"_sha1", PyInit__sha1}, {"_sha256", PyInit__sha256}, diff --git a/PC/dl_nt.c b/PC/dl_nt.c index ae10fb56231b..c87c51eb559f 100644 --- a/PC/dl_nt.c +++ b/PC/dl_nt.c @@ -12,7 +12,12 @@ forgotten) from the programmer. #include "windows.h" #ifdef Py_ENABLE_SHARED +#ifdef MS_DLL_ID +// The string is available at build, so fill the buffer immediately +char dllVersionBuffer[16] = MS_DLL_ID; +#else char dllVersionBuffer[16] = ""; // a private buffer +#endif // Python Globals HMODULE PyWin_DLLhModule = NULL; @@ -88,8 +93,11 @@ BOOL WINAPI DllMain (HANDLE hInst, { case DLL_PROCESS_ATTACH: PyWin_DLLhModule = hInst; +#ifndef MS_DLL_ID + // If we have MS_DLL_ID, we don't need to load the string. // 1000 is a magic number I picked out of the air. Could do with a #define, I spose... LoadString(hInst, 1000, dllVersionBuffer, sizeof(dllVersionBuffer)); +#endif #if HAVE_SXS // and capture our activation context for use when loading extensions. diff --git a/PC/example_nt/example.vcproj b/PC/example_nt/example.vcproj index df36341137ad..d82f76e6bc78 100644 --- a/PC/example_nt/example.vcproj +++ b/PC/example_nt/example.vcproj @@ -39,7 +39,7 @@ = 0) { - _snwprintf_s(&message[len], MSGSIZE - len, _TRUNCATE, L": %s", + _snwprintf_s(&message[len], MSGSIZE - len, _TRUNCATE, L": %ls", win_message); } } #if !defined(_WINDOWS) - fwprintf(stderr, L"%s\n", message); + fwprintf(stderr, L"%ls\n", message); #else MessageBox(NULL, message, TEXT("Python Launcher is sorry to say ..."), MB_OK); @@ -157,14 +157,19 @@ static INSTALLED_PYTHON installed_pythons[MAX_INSTALLED_PYTHONS]; static size_t num_installed_pythons = 0; -/* to hold SOFTWARE\Python\PythonCore\X.Y\InstallPath */ +/* + * To hold SOFTWARE\Python\PythonCore\X.Y...\InstallPath + * The version name can be longer than MAX_VERSION_SIZE, but will be + * truncated to just X.Y for comparisons. + */ #define IP_BASE_SIZE 40 -#define IP_SIZE (IP_BASE_SIZE + MAX_VERSION_SIZE) +#define IP_VERSION_SIZE 8 +#define IP_SIZE (IP_BASE_SIZE + IP_VERSION_SIZE) #define CORE_PATH L"SOFTWARE\\Python\\PythonCore" static wchar_t * location_checks[] = { L"\\", - L"\\PCBuild\\", + L"\\PCBuild\\win32\\", L"\\PCBuild\\amd64\\", NULL }; @@ -196,35 +201,38 @@ locate_pythons_for_key(HKEY root, REGSAM flags) BOOL ok; DWORD type, data_size, attrs; INSTALLED_PYTHON * ip, * pip; + wchar_t ip_version[IP_VERSION_SIZE]; wchar_t ip_path[IP_SIZE]; wchar_t * check; wchar_t ** checkp; wchar_t *key_name = (root == HKEY_LOCAL_MACHINE) ? L"HKLM" : L"HKCU"; if (status != ERROR_SUCCESS) - debug(L"locate_pythons_for_key: unable to open PythonCore key in %s\n", + debug(L"locate_pythons_for_key: unable to open PythonCore key in %ls\n", key_name); else { ip = &installed_pythons[num_installed_pythons]; for (i = 0; num_installed_pythons < MAX_INSTALLED_PYTHONS; i++) { - status = RegEnumKeyW(core_root, i, ip->version, MAX_VERSION_SIZE); + status = RegEnumKeyW(core_root, i, ip_version, IP_VERSION_SIZE); if (status != ERROR_SUCCESS) { if (status != ERROR_NO_MORE_ITEMS) { /* unexpected error */ winerror(status, message, MSGSIZE); - debug(L"Can't enumerate registry key for version %s: %s\n", - ip->version, message); + debug(L"Can't enumerate registry key for version %ls: %ls\n", + ip_version, message); } break; } else { + wcsncpy_s(ip->version, MAX_VERSION_SIZE, ip_version, + MAX_VERSION_SIZE-1); _snwprintf_s(ip_path, IP_SIZE, _TRUNCATE, - L"%s\\%s\\InstallPath", CORE_PATH, ip->version); + L"%ls\\%ls\\InstallPath", CORE_PATH, ip_version); status = RegOpenKeyExW(root, ip_path, 0, flags, &ip_key); if (status != ERROR_SUCCESS) { winerror(status, message, MSGSIZE); // Note: 'message' already has a trailing \n - debug(L"%s\\%s: %s", key_name, ip_path, message); + debug(L"%ls\\%ls: %ls", key_name, ip_path, message); continue; } data_size = sizeof(ip->executable) - 1; @@ -233,7 +241,7 @@ locate_pythons_for_key(HKEY root, REGSAM flags) RegCloseKey(ip_key); if (status != ERROR_SUCCESS) { winerror(status, message, MSGSIZE); - debug(L"%s\\%s: %s\n", key_name, ip_path, message); + debug(L"%ls\\%ls: %ls\n", key_name, ip_path, message); continue; } if (type == REG_SZ) { @@ -246,27 +254,27 @@ locate_pythons_for_key(HKEY root, REGSAM flags) _snwprintf_s(&ip->executable[data_size], MAX_PATH - data_size, MAX_PATH - data_size, - L"%s%s", check, PYTHON_EXECUTABLE); + L"%ls%ls", check, PYTHON_EXECUTABLE); attrs = GetFileAttributesW(ip->executable); if (attrs == INVALID_FILE_ATTRIBUTES) { winerror(GetLastError(), message, MSGSIZE); - debug(L"locate_pythons_for_key: %s: %s", + debug(L"locate_pythons_for_key: %ls: %ls", ip->executable, message); } else if (attrs & FILE_ATTRIBUTE_DIRECTORY) { - debug(L"locate_pythons_for_key: '%s' is a \ + debug(L"locate_pythons_for_key: '%ls' is a \ directory\n", ip->executable, attrs); } else if (find_existing_python(ip->executable)) { - debug(L"locate_pythons_for_key: %s: already \ -found: %s\n", ip->executable); + debug(L"locate_pythons_for_key: %ls: already \ +found: %ls\n", ip->executable); } else { /* check the executable type. */ ok = GetBinaryTypeW(ip->executable, &attrs); if (!ok) { - debug(L"Failure getting binary type: %s\n", + debug(L"Failure getting binary type: %ls\n", ip->executable); } else { @@ -277,7 +285,7 @@ found: %s\n", ip->executable); else ip->bits = 0; if (ip->bits == 0) { - debug(L"locate_pythons_for_key: %s: \ + debug(L"locate_pythons_for_key: %ls: \ invalid binary type: %X\n", ip->executable, attrs); } @@ -291,7 +299,7 @@ invalid binary type: %X\n", ip->executable[n + 1] = L'\"'; ip->executable[n + 2] = L'\0'; } - debug(L"locate_pythons_for_key: %s \ + debug(L"locate_pythons_for_key: %ls \ is a %dbit executable\n", ip->executable, ip->bits); ++num_installed_pythons; @@ -397,7 +405,7 @@ get_configured_value(wchar_t * key) DWORD size; /* First, search the environment. */ - _snwprintf_s(configured_value, MSGSIZE, _TRUNCATE, L"py_%s", key); + _snwprintf_s(configured_value, MSGSIZE, _TRUNCATE, L"py_%ls", key); result = get_env(configured_value); if (result == NULL && appdata_ini_path[0]) { /* Not in environment: check local configuration. */ @@ -420,10 +428,10 @@ get_configured_value(wchar_t * key) } } if (result) { - debug(L"found configured value '%s=%s' in %s\n", + debug(L"found configured value '%ls=%ls' in %ls\n", key, result, found_in ? found_in : L"(unknown)"); } else { - debug(L"found no configured value for '%s'\n", key); + debug(L"found no configured value for '%ls'\n", key); } return result; } @@ -449,9 +457,9 @@ locate_python(wchar_t * wanted_ver) } if (*wanted_ver) { result = find_python_by_version(wanted_ver); - debug(L"search for Python version '%s' found ", wanted_ver); + debug(L"search for Python version '%ls' found ", wanted_ver); if (result) { - debug(L"'%s'\n", result->executable); + debug(L"'%ls'\n", result->executable); } else { debug(L"no interpreter\n"); } @@ -467,7 +475,7 @@ locate_python(wchar_t * wanted_ver) result = find_python_by_version(L"3"); debug(L"search for default Python found "); if (result) { - debug(L"version %s at '%s'\n", + debug(L"version %ls at '%ls'\n", result->version, result->executable); } else { debug(L"no interpreter\n"); @@ -505,19 +513,19 @@ locate_wrapped_script() plen = GetModuleFileNameW(NULL, wrapped_script_path, MAX_PATH); p = wcsrchr(wrapped_script_path, L'.'); if (p == NULL) { - debug(L"GetModuleFileNameW returned value has no extension: %s\n", + debug(L"GetModuleFileNameW returned value has no extension: %ls\n", wrapped_script_path); - error(RC_NO_SCRIPT, L"Wrapper name '%s' is not valid.", wrapped_script_path); + error(RC_NO_SCRIPT, L"Wrapper name '%ls' is not valid.", wrapped_script_path); } wcsncpy_s(p, MAX_PATH - (p - wrapped_script_path) + 1, SCRIPT_SUFFIX, _TRUNCATE); attrs = GetFileAttributesW(wrapped_script_path); if (attrs == INVALID_FILE_ATTRIBUTES) { - debug(L"File '%s' non-existent\n", wrapped_script_path); - error(RC_NO_SCRIPT, L"Script file '%s' is not present.", wrapped_script_path); + debug(L"File '%ls' non-existent\n", wrapped_script_path); + error(RC_NO_SCRIPT, L"Script file '%ls' is not present.", wrapped_script_path); } - debug(L"Using wrapped script file '%s'\n", wrapped_script_path); + debug(L"Using wrapped script file '%ls'\n", wrapped_script_path); } #endif @@ -579,7 +587,7 @@ run_child(wchar_t * cmdline) GetMessage(&msg, 0, 0, 0); #endif - debug(L"run_child: about to run '%s'\n", cmdline); + debug(L"run_child: about to run '%ls'\n", cmdline); job = CreateJobObject(NULL, NULL); ok = QueryInformationJobObject(job, JobObjectExtendedLimitInformation, &info, sizeof(info), &rc); @@ -611,7 +619,7 @@ run_child(wchar_t * cmdline) ok = CreateProcessW(NULL, cmdline, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi); if (!ok) - error(RC_CREATE_PROCESS, L"Unable to create process using '%s'", cmdline); + error(RC_CREATE_PROCESS, L"Unable to create process using '%ls'", cmdline); AssignProcessToJobObject(job, pi.hProcess); CloseHandle(pi.hThread); WaitForSingleObjectEx(pi.hProcess, INFINITE, FALSE); @@ -648,11 +656,11 @@ invoke_child(wchar_t * executable, wchar_t * suffix, wchar_t * cmdline) child_command_size); if (no_suffix) _snwprintf_s(child_command, child_command_size, - child_command_size - 1, L"%s %s", + child_command_size - 1, L"%ls %ls", executable, cmdline); else _snwprintf_s(child_command, child_command_size, - child_command_size - 1, L"%s %s %s", + child_command_size - 1, L"%ls %ls %ls", executable, suffix, cmdline); run_child(child_command); free(child_command); @@ -791,7 +799,7 @@ static void add_command(wchar_t * name, wchar_t * cmdline) { if (num_commands >= MAX_COMMANDS) { - debug(L"can't add %s = '%s': no room\n", name, cmdline); + debug(L"can't add %ls = '%ls': no room\n", name, cmdline); } else { COMMAND * cp = &commands[num_commands++]; @@ -813,14 +821,14 @@ read_config_file(wchar_t * config_path) read = GetPrivateProfileStringW(L"commands", NULL, NULL, keynames, MSGSIZE, config_path); if (read == MSGSIZE - 1) { - debug(L"read_commands: %s: not enough space for names\n", config_path); + debug(L"read_commands: %ls: not enough space for names\n", config_path); } key = keynames; while (*key) { read = GetPrivateProfileStringW(L"commands", key, NULL, value, MSGSIZE, config_path); if (read == MSGSIZE - 1) { - debug(L"read_commands: %s: not enough space for %s\n", + debug(L"read_commands: %ls: not enough space for %ls\n", config_path, key); } cmdp = skip_whitespace(value); @@ -1097,7 +1105,7 @@ maybe_handle_shebang(wchar_t ** argv, wchar_t * cmdline) if ((read >= 4) && (buffer[3] == '\n') && (buffer[2] == '\r')) { ip = find_by_magic((buffer[1] << 8 | buffer[0]) & 0xFFFF); if (ip != NULL) { - debug(L"script file is compiled against Python %s\n", + debug(L"script file is compiled against Python %ls\n", ip->version); invoke_child(ip->executable, NULL, cmdline); } @@ -1200,7 +1208,7 @@ of bytes: %d\n", header_len); is_virt = parse_shebang(shebang_line, nchars, &command, &suffix, &search); if (command != NULL) { - debug(L"parse_shebang: found command: %s\n", command); + debug(L"parse_shebang: found command: %ls\n", command); if (!is_virt) { invoke_child(command, suffix, cmdline); } @@ -1212,7 +1220,7 @@ of bytes: %d\n", header_len); } if (wcsncmp(command, L"python", 6)) error(RC_BAD_VIRTUAL_PATH, L"Unknown virtual \ -path '%s'", command); +path '%ls'", command); command += 6; /* skip past "python" */ if (search && ((*command == L'\0') || isspace(*command))) { /* Command is eligible for path search, and there @@ -1220,9 +1228,9 @@ path '%s'", command); */ debug(L"searching PATH for python executable\n"); cmd = find_on_path(L"python"); - debug(L"Python on path: %s\n", cmd ? cmd->value : L""); + debug(L"Python on path: %ls\n", cmd ? cmd->value : L""); if (cmd) { - debug(L"located python on PATH: %s\n", cmd->value); + debug(L"located python on PATH: %ls\n", cmd->value); invoke_child(cmd->value, suffix, cmdline); /* Exit here, as we have found the command */ return; @@ -1233,14 +1241,14 @@ path '%s'", command); } if (*command && !validate_version(command)) error(RC_BAD_VIRTUAL_PATH, L"Invalid version \ -specification: '%s'.\nIn the first line of the script, 'python' needs to be \ +specification: '%ls'.\nIn the first line of the script, 'python' needs to be \ followed by a valid version specifier.\nPlease check the documentation.", command); /* TODO could call validate_version(command) */ ip = locate_python(command); if (ip == NULL) { error(RC_NO_PYTHON, L"Requested Python version \ -(%s) is not installed", command); +(%ls) is not installed", command); } else { invoke_child(ip->executable, suffix, cmdline); @@ -1347,17 +1355,17 @@ process(int argc, wchar_t ** argv) wcsncpy_s(p, MAX_PATH - plen, L"\\py.ini", _TRUNCATE); attrs = GetFileAttributesW(appdata_ini_path); if (attrs == INVALID_FILE_ATTRIBUTES) { - debug(L"File '%s' non-existent\n", appdata_ini_path); + debug(L"File '%ls' non-existent\n", appdata_ini_path); appdata_ini_path[0] = L'\0'; } else { - debug(L"Using local configuration file '%s'\n", appdata_ini_path); + debug(L"Using local configuration file '%ls'\n", appdata_ini_path); } } plen = GetModuleFileNameW(NULL, launcher_ini_path, MAX_PATH); size = GetFileVersionInfoSizeW(launcher_ini_path, &size); if (size == 0) { winerror(GetLastError(), message, MSGSIZE); - debug(L"GetFileVersionInfoSize failed: %s\n", message); + debug(L"GetFileVersionInfoSize failed: %ls\n", message); } else { version_data = malloc(size); @@ -1381,7 +1389,7 @@ process(int argc, wchar_t ** argv) } p = wcsrchr(launcher_ini_path, L'\\'); if (p == NULL) { - debug(L"GetModuleFileNameW returned value has no backslash: %s\n", + debug(L"GetModuleFileNameW returned value has no backslash: %ls\n", launcher_ini_path); launcher_ini_path[0] = L'\0'; } @@ -1390,15 +1398,15 @@ process(int argc, wchar_t ** argv) _TRUNCATE); attrs = GetFileAttributesW(launcher_ini_path); if (attrs == INVALID_FILE_ATTRIBUTES) { - debug(L"File '%s' non-existent\n", launcher_ini_path); + debug(L"File '%ls' non-existent\n", launcher_ini_path); launcher_ini_path[0] = L'\0'; } else { - debug(L"Using global configuration file '%s'\n", launcher_ini_path); + debug(L"Using global configuration file '%ls'\n", launcher_ini_path); } } command = skip_me(GetCommandLineW()); - debug(L"Called with command line: %s\n", command); + debug(L"Called with command line: %ls\n", command); #if defined(SCRIPT_WRAPPER) /* The launcher is being used in "script wrapper" mode. @@ -1422,7 +1430,7 @@ process(int argc, wchar_t ** argv) wcscpy_s(newcommand, newlen, wrapped_script_path); wcscat_s(newcommand, newlen, L" "); wcscat_s(newcommand, newlen, command); - debug(L"Running wrapped script with command line '%s'\n", newcommand); + debug(L"Running wrapped script with command line '%ls'\n", newcommand); read_commands(); av[0] = wrapped_script_path; av[1] = NULL; @@ -1443,7 +1451,7 @@ process(int argc, wchar_t ** argv) if (valid) { ip = locate_python(&p[1]); if (ip == NULL) - error(RC_NO_PYTHON, L"Requested Python version (%s) not \ + error(RC_NO_PYTHON, L"Requested Python version (%ls) not \ installed", &p[1]); command += wcslen(p); command = skip_whitespace(command); @@ -1476,9 +1484,9 @@ installed", &p[1]); get_version_info(version_text, MAX_PATH); fwprintf(stdout, L"\ -Python Launcher for Windows Version %s\n\n", version_text); +Python Launcher for Windows Version %ls\n\n", version_text); fwprintf(stdout, L"\ -usage: %s [ launcher-arguments ] [ python-arguments ] script [ script-arguments ]\n\n", argv[0]); +usage: %ls [ launcher-arguments ] [ python-arguments ] script [ script-arguments ]\n\n", argv[0]); fputws(L"\ Launcher arguments:\n\n\ -2 : Launch the latest Python 2.x version\n\ diff --git a/PC/msvcrtmodule.c b/PC/msvcrtmodule.c old mode 100755 new mode 100644 diff --git a/PC/pyconfig.h b/PC/pyconfig.h index 299527db7d40..328be0f362ea 100644 --- a/PC/pyconfig.h +++ b/PC/pyconfig.h @@ -145,9 +145,11 @@ WIN32 is still required for the locale module. #if defined(_M_IA64) #define COMPILER _Py_PASTE_VERSION("64 bit (Itanium)") #define MS_WINI64 +#define PYD_PLATFORM_TAG "win_ia64" #elif defined(_M_X64) || defined(_M_AMD64) #define COMPILER _Py_PASTE_VERSION("64 bit (AMD64)") #define MS_WINX64 +#define PYD_PLATFORM_TAG "win_amd64" #else #define COMPILER _Py_PASTE_VERSION("64 bit (Unknown)") #endif @@ -193,8 +195,10 @@ typedef _W64 int ssize_t; #if defined(MS_WIN32) && !defined(MS_WIN64) #if defined(_M_IX86) #define COMPILER _Py_PASTE_VERSION("32 bit (Intel)") +#define PYD_PLATFORM_TAG "win32" #elif defined(_M_ARM) #define COMPILER _Py_PASTE_VERSION("32 bit (ARM)") +#define PYD_PLATFORM_TAG "win_arm" #else #define COMPILER _Py_PASTE_VERSION("32 bit (Unknown)") #endif @@ -207,7 +211,18 @@ typedef int pid_t; #define Py_IS_INFINITY(X) (!_finite(X) && !_isnan(X)) #define Py_IS_FINITE(X) _finite(X) #define copysign _copysign + +/* VS 2010 and above already defines hypot as _hypot */ +#if _MSC_VER < 1600 #define hypot _hypot +#endif + +/* VS 2015 defines these names with a leading underscore */ +#if _MSC_VER >= 1900 +#define timezone _timezone +#define daylight _daylight +#define tzname _tzname +#endif /* Side by Side assemblies supported in VS 2005 and VS 2008 but not 2010*/ #if _MSC_VER >= 1400 && _MSC_VER < 1600 @@ -222,35 +237,6 @@ typedef int pid_t; #endif /* _MSC_VER */ -/* ------------------------------------------------------------------------*/ -/* The Borland compiler defines __BORLANDC__ */ -/* XXX These defines are likely incomplete, but should be easy to fix. */ -#ifdef __BORLANDC__ -#define COMPILER "[Borland]" - -#ifdef _WIN32 -/* tested with BCC 5.5 (__BORLANDC__ >= 0x0550) - */ - -typedef int pid_t; -/* BCC55 seems to understand __declspec(dllimport), it is used in its - own header files (winnt.h, ...) - so we can do nothing and get the default*/ - -#undef HAVE_SYS_UTIME_H -#define HAVE_UTIME_H -#define HAVE_DIRENT_H - -/* rename a few functions for the Borland compiler */ -#include -#define _chsize chsize -#define _setmode setmode - -#else /* !_WIN32 */ -#error "Only Win32 and later are supported" -#endif /* !_WIN32 */ - -#endif /* BORLANDC */ - /* ------------------------------------------------------------------------*/ /* egcs/gnu-win32 defines __GNUC__ and _WIN32 */ #if defined(__GNUC__) && defined(_WIN32) @@ -318,11 +304,11 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */ their Makefile (other compilers are generally taken care of by distutils.) */ # if defined(_DEBUG) -# pragma comment(lib,"python34_d.lib") +# pragma comment(lib,"python35_d.lib") # elif defined(Py_LIMITED_API) # pragma comment(lib,"python3.lib") # else -# pragma comment(lib,"python34.lib") +# pragma comment(lib,"python35.lib") # endif /* _DEBUG */ # endif /* _MSC_VER */ # endif /* Py_BUILD_CORE */ @@ -386,7 +372,7 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */ #else /* VC6, VS 2002 and eVC4 don't support the C99 LL suffix for 64-bit integer literals */ #define Py_LL(x) x##I64 -#endif /* _MSC_VER > 1200 */ +#endif /* _MSC_VER > 1300 */ #endif /* _MSC_VER */ #endif @@ -432,6 +418,11 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */ /* Define to 1 if you have the `copysign' function. */ #define HAVE_COPYSIGN 1 +/* Define to 1 if you have the `round' function. */ +#if _MSC_VER >= 1800 +#define HAVE_ROUND 1 +#endif + /* Define to 1 if you have the `isinf' macro. */ #define HAVE_DECL_ISINF 1 diff --git a/PC/pylauncher.rc b/PC/pylauncher.rc index df5824a6635e..634b8d6dcbca 100644 --- a/PC/pylauncher.rc +++ b/PC/pylauncher.rc @@ -34,7 +34,7 @@ BEGIN VALUE "FileDescription", "Python Launcher for Windows (Console)" VALUE "FileVersion", PYTHON_VERSION VALUE "InternalName", "py" - VALUE "LegalCopyright", "Copyright (C) 2011-2012 Python Software Foundation" + VALUE "LegalCopyright", "Copyright (C) 2011-2014 Python Software Foundation" VALUE "OriginalFilename", "py" VALUE "ProductName", "Python Launcher for Windows" VALUE "ProductVersion", PYTHON_VERSION diff --git a/PC/python.manifest b/PC/python.manifest new file mode 100644 index 000000000000..3ac2630e2721 --- /dev/null +++ b/PC/python.manifest @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/PC/python3.def b/PC/python3.def index 0cf0d944d9fc..45fda3861e81 100644 --- a/PC/python3.def +++ b/PC/python3.def @@ -1,700 +1,703 @@ -; When changing this file, run python34gen.py +; This file specifies the import forwarding for python3.dll +; It is used when building python3dll.vcxproj LIBRARY "python3" EXPORTS - PyArg_Parse=python34.PyArg_Parse - PyArg_ParseTuple=python34.PyArg_ParseTuple - PyArg_ParseTupleAndKeywords=python34.PyArg_ParseTupleAndKeywords - PyArg_UnpackTuple=python34.PyArg_UnpackTuple - PyArg_VaParse=python34.PyArg_VaParse - PyArg_VaParseTupleAndKeywords=python34.PyArg_VaParseTupleAndKeywords - PyArg_ValidateKeywordArguments=python34.PyArg_ValidateKeywordArguments - PyBaseObject_Type=python34.PyBaseObject_Type DATA - PyBool_FromLong=python34.PyBool_FromLong - PyBool_Type=python34.PyBool_Type DATA - PyByteArrayIter_Type=python34.PyByteArrayIter_Type DATA - PyByteArray_AsString=python34.PyByteArray_AsString - PyByteArray_Concat=python34.PyByteArray_Concat - PyByteArray_FromObject=python34.PyByteArray_FromObject - PyByteArray_FromStringAndSize=python34.PyByteArray_FromStringAndSize - PyByteArray_Resize=python34.PyByteArray_Resize - PyByteArray_Size=python34.PyByteArray_Size - PyByteArray_Type=python34.PyByteArray_Type DATA - PyBytesIter_Type=python34.PyBytesIter_Type DATA - PyBytes_AsString=python34.PyBytes_AsString - PyBytes_AsStringAndSize=python34.PyBytes_AsStringAndSize - PyBytes_Concat=python34.PyBytes_Concat - PyBytes_ConcatAndDel=python34.PyBytes_ConcatAndDel - PyBytes_DecodeEscape=python34.PyBytes_DecodeEscape - PyBytes_FromFormat=python34.PyBytes_FromFormat - PyBytes_FromFormatV=python34.PyBytes_FromFormatV - PyBytes_FromObject=python34.PyBytes_FromObject - PyBytes_FromString=python34.PyBytes_FromString - PyBytes_FromStringAndSize=python34.PyBytes_FromStringAndSize - PyBytes_Repr=python34.PyBytes_Repr - PyBytes_Size=python34.PyBytes_Size - PyBytes_Type=python34.PyBytes_Type DATA - PyCFunction_Call=python34.PyCFunction_Call - PyCFunction_ClearFreeList=python34.PyCFunction_ClearFreeList - PyCFunction_GetFlags=python34.PyCFunction_GetFlags - PyCFunction_GetFunction=python34.PyCFunction_GetFunction - PyCFunction_GetSelf=python34.PyCFunction_GetSelf - PyCFunction_New=python34.PyCFunction_New - PyCFunction_NewEx=python34.PyCFunction_NewEx - PyCFunction_Type=python34.PyCFunction_Type DATA - PyCallIter_New=python34.PyCallIter_New - PyCallIter_Type=python34.PyCallIter_Type DATA - PyCallable_Check=python34.PyCallable_Check - PyCapsule_GetContext=python34.PyCapsule_GetContext - PyCapsule_GetDestructor=python34.PyCapsule_GetDestructor - PyCapsule_GetName=python34.PyCapsule_GetName - PyCapsule_GetPointer=python34.PyCapsule_GetPointer - PyCapsule_Import=python34.PyCapsule_Import - PyCapsule_IsValid=python34.PyCapsule_IsValid - PyCapsule_New=python34.PyCapsule_New - PyCapsule_SetContext=python34.PyCapsule_SetContext - PyCapsule_SetDestructor=python34.PyCapsule_SetDestructor - PyCapsule_SetName=python34.PyCapsule_SetName - PyCapsule_SetPointer=python34.PyCapsule_SetPointer - PyCapsule_Type=python34.PyCapsule_Type DATA - PyClassMethodDescr_Type=python34.PyClassMethodDescr_Type DATA - PyCodec_BackslashReplaceErrors=python34.PyCodec_BackslashReplaceErrors - PyCodec_Decode=python34.PyCodec_Decode - PyCodec_Decoder=python34.PyCodec_Decoder - PyCodec_Encode=python34.PyCodec_Encode - PyCodec_Encoder=python34.PyCodec_Encoder - PyCodec_IgnoreErrors=python34.PyCodec_IgnoreErrors - PyCodec_IncrementalDecoder=python34.PyCodec_IncrementalDecoder - PyCodec_IncrementalEncoder=python34.PyCodec_IncrementalEncoder - PyCodec_KnownEncoding=python34.PyCodec_KnownEncoding - PyCodec_LookupError=python34.PyCodec_LookupError - PyCodec_Register=python34.PyCodec_Register - PyCodec_RegisterError=python34.PyCodec_RegisterError - PyCodec_ReplaceErrors=python34.PyCodec_ReplaceErrors - PyCodec_StreamReader=python34.PyCodec_StreamReader - PyCodec_StreamWriter=python34.PyCodec_StreamWriter - PyCodec_StrictErrors=python34.PyCodec_StrictErrors - PyCodec_XMLCharRefReplaceErrors=python34.PyCodec_XMLCharRefReplaceErrors - PyComplex_FromDoubles=python34.PyComplex_FromDoubles - PyComplex_ImagAsDouble=python34.PyComplex_ImagAsDouble - PyComplex_RealAsDouble=python34.PyComplex_RealAsDouble - PyComplex_Type=python34.PyComplex_Type DATA - PyDescr_NewClassMethod=python34.PyDescr_NewClassMethod - PyDescr_NewGetSet=python34.PyDescr_NewGetSet - PyDescr_NewMember=python34.PyDescr_NewMember - PyDescr_NewMethod=python34.PyDescr_NewMethod - PyDictItems_Type=python34.PyDictItems_Type DATA - PyDictIterItem_Type=python34.PyDictIterItem_Type DATA - PyDictIterKey_Type=python34.PyDictIterKey_Type DATA - PyDictIterValue_Type=python34.PyDictIterValue_Type DATA - PyDictKeys_Type=python34.PyDictKeys_Type DATA - PyDictProxy_New=python34.PyDictProxy_New - PyDictProxy_Type=python34.PyDictProxy_Type DATA - PyDictValues_Type=python34.PyDictValues_Type DATA - PyDict_Clear=python34.PyDict_Clear - PyDict_Contains=python34.PyDict_Contains - PyDict_Copy=python34.PyDict_Copy - PyDict_DelItem=python34.PyDict_DelItem - PyDict_DelItemString=python34.PyDict_DelItemString - PyDict_GetItem=python34.PyDict_GetItem - PyDict_GetItemString=python34.PyDict_GetItemString - PyDict_GetItemWithError=python34.PyDict_GetItemWithError - PyDict_Items=python34.PyDict_Items - PyDict_Keys=python34.PyDict_Keys - PyDict_Merge=python34.PyDict_Merge - PyDict_MergeFromSeq2=python34.PyDict_MergeFromSeq2 - PyDict_New=python34.PyDict_New - PyDict_Next=python34.PyDict_Next - PyDict_SetItem=python34.PyDict_SetItem - PyDict_SetItemString=python34.PyDict_SetItemString - PyDict_Size=python34.PyDict_Size - PyDict_Type=python34.PyDict_Type DATA - PyDict_Update=python34.PyDict_Update - PyDict_Values=python34.PyDict_Values - PyEllipsis_Type=python34.PyEllipsis_Type DATA - PyEnum_Type=python34.PyEnum_Type DATA - PyErr_BadArgument=python34.PyErr_BadArgument - PyErr_BadInternalCall=python34.PyErr_BadInternalCall - PyErr_CheckSignals=python34.PyErr_CheckSignals - PyErr_Clear=python34.PyErr_Clear - PyErr_Display=python34.PyErr_Display - PyErr_ExceptionMatches=python34.PyErr_ExceptionMatches - PyErr_Fetch=python34.PyErr_Fetch - PyErr_Format=python34.PyErr_Format - PyErr_GivenExceptionMatches=python34.PyErr_GivenExceptionMatches - PyErr_NewException=python34.PyErr_NewException - PyErr_NewExceptionWithDoc=python34.PyErr_NewExceptionWithDoc - PyErr_NoMemory=python34.PyErr_NoMemory - PyErr_NormalizeException=python34.PyErr_NormalizeException - PyErr_Occurred=python34.PyErr_Occurred - PyErr_Print=python34.PyErr_Print - PyErr_PrintEx=python34.PyErr_PrintEx - PyErr_ProgramText=python34.PyErr_ProgramText - PyErr_Restore=python34.PyErr_Restore - PyErr_SetFromErrno=python34.PyErr_SetFromErrno - PyErr_SetFromErrnoWithFilename=python34.PyErr_SetFromErrnoWithFilename - PyErr_SetFromErrnoWithFilenameObject=python34.PyErr_SetFromErrnoWithFilenameObject - PyErr_SetInterrupt=python34.PyErr_SetInterrupt - PyErr_SetNone=python34.PyErr_SetNone - PyErr_SetObject=python34.PyErr_SetObject - PyErr_SetString=python34.PyErr_SetString - PyErr_SyntaxLocation=python34.PyErr_SyntaxLocation - PyErr_WarnEx=python34.PyErr_WarnEx - PyErr_WarnExplicit=python34.PyErr_WarnExplicit - PyErr_WarnFormat=python34.PyErr_WarnFormat - PyErr_WriteUnraisable=python34.PyErr_WriteUnraisable - PyEval_AcquireLock=python34.PyEval_AcquireLock - PyEval_AcquireThread=python34.PyEval_AcquireThread - PyEval_CallFunction=python34.PyEval_CallFunction - PyEval_CallMethod=python34.PyEval_CallMethod - PyEval_CallObjectWithKeywords=python34.PyEval_CallObjectWithKeywords - PyEval_EvalCode=python34.PyEval_EvalCode - PyEval_EvalCodeEx=python34.PyEval_EvalCodeEx - PyEval_EvalFrame=python34.PyEval_EvalFrame - PyEval_EvalFrameEx=python34.PyEval_EvalFrameEx - PyEval_GetBuiltins=python34.PyEval_GetBuiltins - PyEval_GetCallStats=python34.PyEval_GetCallStats - PyEval_GetFrame=python34.PyEval_GetFrame - PyEval_GetFuncDesc=python34.PyEval_GetFuncDesc - PyEval_GetFuncName=python34.PyEval_GetFuncName - PyEval_GetGlobals=python34.PyEval_GetGlobals - PyEval_GetLocals=python34.PyEval_GetLocals - PyEval_InitThreads=python34.PyEval_InitThreads - PyEval_ReInitThreads=python34.PyEval_ReInitThreads - PyEval_ReleaseLock=python34.PyEval_ReleaseLock - PyEval_ReleaseThread=python34.PyEval_ReleaseThread - PyEval_RestoreThread=python34.PyEval_RestoreThread - PyEval_SaveThread=python34.PyEval_SaveThread - PyEval_ThreadsInitialized=python34.PyEval_ThreadsInitialized - PyExc_ArithmeticError=python34.PyExc_ArithmeticError DATA - PyExc_AssertionError=python34.PyExc_AssertionError DATA - PyExc_AttributeError=python34.PyExc_AttributeError DATA - PyExc_BaseException=python34.PyExc_BaseException DATA - PyExc_BufferError=python34.PyExc_BufferError DATA - PyExc_BytesWarning=python34.PyExc_BytesWarning DATA - PyExc_DeprecationWarning=python34.PyExc_DeprecationWarning DATA - PyExc_EOFError=python34.PyExc_EOFError DATA - PyExc_EnvironmentError=python34.PyExc_EnvironmentError DATA - PyExc_Exception=python34.PyExc_Exception DATA - PyExc_FloatingPointError=python34.PyExc_FloatingPointError DATA - PyExc_FutureWarning=python34.PyExc_FutureWarning DATA - PyExc_GeneratorExit=python34.PyExc_GeneratorExit DATA - PyExc_IOError=python34.PyExc_IOError DATA - PyExc_ImportError=python34.PyExc_ImportError DATA - PyExc_ImportWarning=python34.PyExc_ImportWarning DATA - PyExc_IndentationError=python34.PyExc_IndentationError DATA - PyExc_IndexError=python34.PyExc_IndexError DATA - PyExc_KeyError=python34.PyExc_KeyError DATA - PyExc_KeyboardInterrupt=python34.PyExc_KeyboardInterrupt DATA - PyExc_LookupError=python34.PyExc_LookupError DATA - PyExc_MemoryError=python34.PyExc_MemoryError DATA - PyExc_MemoryErrorInst=python34.PyExc_MemoryErrorInst DATA - PyExc_NameError=python34.PyExc_NameError DATA - PyExc_NotImplementedError=python34.PyExc_NotImplementedError DATA - PyExc_OSError=python34.PyExc_OSError DATA - PyExc_OverflowError=python34.PyExc_OverflowError DATA - PyExc_PendingDeprecationWarning=python34.PyExc_PendingDeprecationWarning DATA - PyExc_RecursionErrorInst=python34.PyExc_RecursionErrorInst DATA - PyExc_ReferenceError=python34.PyExc_ReferenceError DATA - PyExc_RuntimeError=python34.PyExc_RuntimeError DATA - PyExc_RuntimeWarning=python34.PyExc_RuntimeWarning DATA - PyExc_StopIteration=python34.PyExc_StopIteration DATA - PyExc_SyntaxError=python34.PyExc_SyntaxError DATA - PyExc_SyntaxWarning=python34.PyExc_SyntaxWarning DATA - PyExc_SystemError=python34.PyExc_SystemError DATA - PyExc_SystemExit=python34.PyExc_SystemExit DATA - PyExc_TabError=python34.PyExc_TabError DATA - PyExc_TypeError=python34.PyExc_TypeError DATA - PyExc_UnboundLocalError=python34.PyExc_UnboundLocalError DATA - PyExc_UnicodeDecodeError=python34.PyExc_UnicodeDecodeError DATA - PyExc_UnicodeEncodeError=python34.PyExc_UnicodeEncodeError DATA - PyExc_UnicodeError=python34.PyExc_UnicodeError DATA - PyExc_UnicodeTranslateError=python34.PyExc_UnicodeTranslateError DATA - PyExc_UnicodeWarning=python34.PyExc_UnicodeWarning DATA - PyExc_UserWarning=python34.PyExc_UserWarning DATA - PyExc_ValueError=python34.PyExc_ValueError DATA - PyExc_Warning=python34.PyExc_Warning DATA - PyExc_ZeroDivisionError=python34.PyExc_ZeroDivisionError DATA - PyException_GetCause=python34.PyException_GetCause - PyException_GetContext=python34.PyException_GetContext - PyException_GetTraceback=python34.PyException_GetTraceback - PyException_SetCause=python34.PyException_SetCause - PyException_SetContext=python34.PyException_SetContext - PyException_SetTraceback=python34.PyException_SetTraceback - PyFile_FromFd=python34.PyFile_FromFd - PyFile_GetLine=python34.PyFile_GetLine - PyFile_WriteObject=python34.PyFile_WriteObject - PyFile_WriteString=python34.PyFile_WriteString - PyFilter_Type=python34.PyFilter_Type DATA - PyFloat_AsDouble=python34.PyFloat_AsDouble - PyFloat_FromDouble=python34.PyFloat_FromDouble - PyFloat_FromString=python34.PyFloat_FromString - PyFloat_GetInfo=python34.PyFloat_GetInfo - PyFloat_GetMax=python34.PyFloat_GetMax - PyFloat_GetMin=python34.PyFloat_GetMin - PyFloat_Type=python34.PyFloat_Type DATA - PyFrozenSet_New=python34.PyFrozenSet_New - PyFrozenSet_Type=python34.PyFrozenSet_Type DATA - PyGC_Collect=python34.PyGC_Collect - PyGILState_Ensure=python34.PyGILState_Ensure - PyGILState_GetThisThreadState=python34.PyGILState_GetThisThreadState - PyGILState_Release=python34.PyGILState_Release - PyGetSetDescr_Type=python34.PyGetSetDescr_Type DATA - PyImport_AddModule=python34.PyImport_AddModule - PyImport_AppendInittab=python34.PyImport_AppendInittab - PyImport_Cleanup=python34.PyImport_Cleanup - PyImport_ExecCodeModule=python34.PyImport_ExecCodeModule - PyImport_ExecCodeModuleEx=python34.PyImport_ExecCodeModuleEx - PyImport_ExecCodeModuleWithPathnames=python34.PyImport_ExecCodeModuleWithPathnames - PyImport_GetImporter=python34.PyImport_GetImporter - PyImport_GetMagicNumber=python34.PyImport_GetMagicNumber - PyImport_GetMagicTag=python34.PyImport_GetMagicTag - PyImport_GetModuleDict=python34.PyImport_GetModuleDict - PyImport_Import=python34.PyImport_Import - PyImport_ImportFrozenModule=python34.PyImport_ImportFrozenModule - PyImport_ImportModule=python34.PyImport_ImportModule - PyImport_ImportModuleLevel=python34.PyImport_ImportModuleLevel - PyImport_ImportModuleNoBlock=python34.PyImport_ImportModuleNoBlock - PyImport_ReloadModule=python34.PyImport_ReloadModule - PyInterpreterState_Clear=python34.PyInterpreterState_Clear - PyInterpreterState_Delete=python34.PyInterpreterState_Delete - PyInterpreterState_New=python34.PyInterpreterState_New - PyIter_Next=python34.PyIter_Next - PyListIter_Type=python34.PyListIter_Type DATA - PyListRevIter_Type=python34.PyListRevIter_Type DATA - PyList_Append=python34.PyList_Append - PyList_AsTuple=python34.PyList_AsTuple - PyList_GetItem=python34.PyList_GetItem - PyList_GetSlice=python34.PyList_GetSlice - PyList_Insert=python34.PyList_Insert - PyList_New=python34.PyList_New - PyList_Reverse=python34.PyList_Reverse - PyList_SetItem=python34.PyList_SetItem - PyList_SetSlice=python34.PyList_SetSlice - PyList_Size=python34.PyList_Size - PyList_Sort=python34.PyList_Sort - PyList_Type=python34.PyList_Type DATA - PyLongRangeIter_Type=python34.PyLongRangeIter_Type DATA - PyLong_AsDouble=python34.PyLong_AsDouble - PyLong_AsLong=python34.PyLong_AsLong - PyLong_AsLongAndOverflow=python34.PyLong_AsLongAndOverflow - PyLong_AsLongLong=python34.PyLong_AsLongLong - PyLong_AsLongLongAndOverflow=python34.PyLong_AsLongLongAndOverflow - PyLong_AsSize_t=python34.PyLong_AsSize_t - PyLong_AsSsize_t=python34.PyLong_AsSsize_t - PyLong_AsUnsignedLong=python34.PyLong_AsUnsignedLong - PyLong_AsUnsignedLongLong=python34.PyLong_AsUnsignedLongLong - PyLong_AsUnsignedLongLongMask=python34.PyLong_AsUnsignedLongLongMask - PyLong_AsUnsignedLongMask=python34.PyLong_AsUnsignedLongMask - PyLong_AsVoidPtr=python34.PyLong_AsVoidPtr - PyLong_FromDouble=python34.PyLong_FromDouble - PyLong_FromLong=python34.PyLong_FromLong - PyLong_FromLongLong=python34.PyLong_FromLongLong - PyLong_FromSize_t=python34.PyLong_FromSize_t - PyLong_FromSsize_t=python34.PyLong_FromSsize_t - PyLong_FromString=python34.PyLong_FromString - PyLong_FromUnsignedLong=python34.PyLong_FromUnsignedLong - PyLong_FromUnsignedLongLong=python34.PyLong_FromUnsignedLongLong - PyLong_FromVoidPtr=python34.PyLong_FromVoidPtr - PyLong_GetInfo=python34.PyLong_GetInfo - PyLong_Type=python34.PyLong_Type DATA - PyMap_Type=python34.PyMap_Type DATA - PyMapping_Check=python34.PyMapping_Check - PyMapping_GetItemString=python34.PyMapping_GetItemString - PyMapping_HasKey=python34.PyMapping_HasKey - PyMapping_HasKeyString=python34.PyMapping_HasKeyString - PyMapping_Items=python34.PyMapping_Items - PyMapping_Keys=python34.PyMapping_Keys - PyMapping_Length=python34.PyMapping_Length - PyMapping_SetItemString=python34.PyMapping_SetItemString - PyMapping_Size=python34.PyMapping_Size - PyMapping_Values=python34.PyMapping_Values - PyMem_Free=python34.PyMem_Free - PyMem_Malloc=python34.PyMem_Malloc - PyMem_Realloc=python34.PyMem_Realloc - PyMemberDescr_Type=python34.PyMemberDescr_Type DATA - PyMemoryView_FromObject=python34.PyMemoryView_FromObject - PyMemoryView_GetContiguous=python34.PyMemoryView_GetContiguous - PyMemoryView_Type=python34.PyMemoryView_Type DATA - PyMethodDescr_Type=python34.PyMethodDescr_Type DATA - PyModule_AddIntConstant=python34.PyModule_AddIntConstant - PyModule_AddObject=python34.PyModule_AddObject - PyModule_AddStringConstant=python34.PyModule_AddStringConstant - PyModule_Create2=python34.PyModule_Create2 - PyModule_GetDef=python34.PyModule_GetDef - PyModule_GetDict=python34.PyModule_GetDict - PyModule_GetFilename=python34.PyModule_GetFilename - PyModule_GetFilenameObject=python34.PyModule_GetFilenameObject - PyModule_GetName=python34.PyModule_GetName - PyModule_GetState=python34.PyModule_GetState - PyModule_New=python34.PyModule_New - PyModule_Type=python34.PyModule_Type DATA - PyNullImporter_Type=python34.PyNullImporter_Type DATA - PyNumber_Absolute=python34.PyNumber_Absolute - PyNumber_Add=python34.PyNumber_Add - PyNumber_And=python34.PyNumber_And - PyNumber_AsSsize_t=python34.PyNumber_AsSsize_t - PyNumber_Check=python34.PyNumber_Check - PyNumber_Divmod=python34.PyNumber_Divmod - PyNumber_Float=python34.PyNumber_Float - PyNumber_FloorDivide=python34.PyNumber_FloorDivide - PyNumber_InPlaceAdd=python34.PyNumber_InPlaceAdd - PyNumber_InPlaceAnd=python34.PyNumber_InPlaceAnd - PyNumber_InPlaceFloorDivide=python34.PyNumber_InPlaceFloorDivide - PyNumber_InPlaceLshift=python34.PyNumber_InPlaceLshift - PyNumber_InPlaceMultiply=python34.PyNumber_InPlaceMultiply - PyNumber_InPlaceOr=python34.PyNumber_InPlaceOr - PyNumber_InPlacePower=python34.PyNumber_InPlacePower - PyNumber_InPlaceRemainder=python34.PyNumber_InPlaceRemainder - PyNumber_InPlaceRshift=python34.PyNumber_InPlaceRshift - PyNumber_InPlaceSubtract=python34.PyNumber_InPlaceSubtract - PyNumber_InPlaceTrueDivide=python34.PyNumber_InPlaceTrueDivide - PyNumber_InPlaceXor=python34.PyNumber_InPlaceXor - PyNumber_Index=python34.PyNumber_Index - PyNumber_Invert=python34.PyNumber_Invert - PyNumber_Long=python34.PyNumber_Long - PyNumber_Lshift=python34.PyNumber_Lshift - PyNumber_Multiply=python34.PyNumber_Multiply - PyNumber_Negative=python34.PyNumber_Negative - PyNumber_Or=python34.PyNumber_Or - PyNumber_Positive=python34.PyNumber_Positive - PyNumber_Power=python34.PyNumber_Power - PyNumber_Remainder=python34.PyNumber_Remainder - PyNumber_Rshift=python34.PyNumber_Rshift - PyNumber_Subtract=python34.PyNumber_Subtract - PyNumber_ToBase=python34.PyNumber_ToBase - PyNumber_TrueDivide=python34.PyNumber_TrueDivide - PyNumber_Xor=python34.PyNumber_Xor - PyOS_AfterFork=python34.PyOS_AfterFork - PyOS_InitInterrupts=python34.PyOS_InitInterrupts - PyOS_InputHook=python34.PyOS_InputHook DATA - PyOS_InterruptOccurred=python34.PyOS_InterruptOccurred - PyOS_ReadlineFunctionPointer=python34.PyOS_ReadlineFunctionPointer DATA - PyOS_double_to_string=python34.PyOS_double_to_string - PyOS_getsig=python34.PyOS_getsig - PyOS_mystricmp=python34.PyOS_mystricmp - PyOS_mystrnicmp=python34.PyOS_mystrnicmp - PyOS_setsig=python34.PyOS_setsig - PyOS_snprintf=python34.PyOS_snprintf - PyOS_string_to_double=python34.PyOS_string_to_double - PyOS_strtol=python34.PyOS_strtol - PyOS_strtoul=python34.PyOS_strtoul - PyOS_vsnprintf=python34.PyOS_vsnprintf - PyObject_ASCII=python34.PyObject_ASCII - PyObject_AsCharBuffer=python34.PyObject_AsCharBuffer - PyObject_AsFileDescriptor=python34.PyObject_AsFileDescriptor - PyObject_AsReadBuffer=python34.PyObject_AsReadBuffer - PyObject_AsWriteBuffer=python34.PyObject_AsWriteBuffer - PyObject_Bytes=python34.PyObject_Bytes - PyObject_Call=python34.PyObject_Call - PyObject_CallFunction=python34.PyObject_CallFunction - PyObject_CallFunctionObjArgs=python34.PyObject_CallFunctionObjArgs - PyObject_CallMethod=python34.PyObject_CallMethod - PyObject_CallMethodObjArgs=python34.PyObject_CallMethodObjArgs - PyObject_CallObject=python34.PyObject_CallObject - PyObject_CheckReadBuffer=python34.PyObject_CheckReadBuffer - PyObject_ClearWeakRefs=python34.PyObject_ClearWeakRefs - PyObject_DelItem=python34.PyObject_DelItem - PyObject_DelItemString=python34.PyObject_DelItemString - PyObject_Dir=python34.PyObject_Dir - PyObject_Format=python34.PyObject_Format - PyObject_Free=python34.PyObject_Free - PyObject_GC_Del=python34.PyObject_GC_Del - PyObject_GC_Track=python34.PyObject_GC_Track - PyObject_GC_UnTrack=python34.PyObject_GC_UnTrack - PyObject_GenericGetAttr=python34.PyObject_GenericGetAttr - PyObject_GenericSetAttr=python34.PyObject_GenericSetAttr - PyObject_GetAttr=python34.PyObject_GetAttr - PyObject_GetAttrString=python34.PyObject_GetAttrString - PyObject_GetItem=python34.PyObject_GetItem - PyObject_GetIter=python34.PyObject_GetIter - PyObject_HasAttr=python34.PyObject_HasAttr - PyObject_HasAttrString=python34.PyObject_HasAttrString - PyObject_Hash=python34.PyObject_Hash - PyObject_HashNotImplemented=python34.PyObject_HashNotImplemented - PyObject_Init=python34.PyObject_Init - PyObject_InitVar=python34.PyObject_InitVar - PyObject_IsInstance=python34.PyObject_IsInstance - PyObject_IsSubclass=python34.PyObject_IsSubclass - PyObject_IsTrue=python34.PyObject_IsTrue - PyObject_Length=python34.PyObject_Length - PyObject_Malloc=python34.PyObject_Malloc - PyObject_Not=python34.PyObject_Not - PyObject_Realloc=python34.PyObject_Realloc - PyObject_Repr=python34.PyObject_Repr - PyObject_RichCompare=python34.PyObject_RichCompare - PyObject_RichCompareBool=python34.PyObject_RichCompareBool - PyObject_SelfIter=python34.PyObject_SelfIter - PyObject_SetAttr=python34.PyObject_SetAttr - PyObject_SetAttrString=python34.PyObject_SetAttrString - PyObject_SetItem=python34.PyObject_SetItem - PyObject_Size=python34.PyObject_Size - PyObject_Str=python34.PyObject_Str - PyObject_Type=python34.PyObject_Type DATA - PyParser_SimpleParseFileFlags=python34.PyParser_SimpleParseFileFlags - PyParser_SimpleParseStringFlags=python34.PyParser_SimpleParseStringFlags - PyProperty_Type=python34.PyProperty_Type DATA - PyRangeIter_Type=python34.PyRangeIter_Type DATA - PyRange_Type=python34.PyRange_Type DATA - PyReversed_Type=python34.PyReversed_Type DATA - PySeqIter_New=python34.PySeqIter_New - PySeqIter_Type=python34.PySeqIter_Type DATA - PySequence_Check=python34.PySequence_Check - PySequence_Concat=python34.PySequence_Concat - PySequence_Contains=python34.PySequence_Contains - PySequence_Count=python34.PySequence_Count - PySequence_DelItem=python34.PySequence_DelItem - PySequence_DelSlice=python34.PySequence_DelSlice - PySequence_Fast=python34.PySequence_Fast - PySequence_GetItem=python34.PySequence_GetItem - PySequence_GetSlice=python34.PySequence_GetSlice - PySequence_In=python34.PySequence_In - PySequence_InPlaceConcat=python34.PySequence_InPlaceConcat - PySequence_InPlaceRepeat=python34.PySequence_InPlaceRepeat - PySequence_Index=python34.PySequence_Index - PySequence_Length=python34.PySequence_Length - PySequence_List=python34.PySequence_List - PySequence_Repeat=python34.PySequence_Repeat - PySequence_SetItem=python34.PySequence_SetItem - PySequence_SetSlice=python34.PySequence_SetSlice - PySequence_Size=python34.PySequence_Size - PySequence_Tuple=python34.PySequence_Tuple - PySetIter_Type=python34.PySetIter_Type DATA - PySet_Add=python34.PySet_Add - PySet_Clear=python34.PySet_Clear - PySet_Contains=python34.PySet_Contains - PySet_Discard=python34.PySet_Discard - PySet_New=python34.PySet_New - PySet_Pop=python34.PySet_Pop - PySet_Size=python34.PySet_Size - PySet_Type=python34.PySet_Type DATA - PySlice_GetIndices=python34.PySlice_GetIndices - PySlice_GetIndicesEx=python34.PySlice_GetIndicesEx - PySlice_New=python34.PySlice_New - PySlice_Type=python34.PySlice_Type DATA - PySortWrapper_Type=python34.PySortWrapper_Type DATA - PyState_FindModule=python34.PyState_FindModule - PyState_AddModule=python34.PyState_AddModule - PyState_RemoveModule=python34.PyState_RemoveModule - PyStructSequence_GetItem=python34.PyStructSequence_GetItem - PyStructSequence_New=python34.PyStructSequence_New - PyStructSequence_NewType=python34.PyStructSequence_NewType - PyStructSequence_SetItem=python34.PyStructSequence_SetItem - PySuper_Type=python34.PySuper_Type DATA - PySys_AddWarnOption=python34.PySys_AddWarnOption - PySys_AddWarnOptionUnicode=python34.PySys_AddWarnOptionUnicode - PySys_FormatStderr=python34.PySys_FormatStderr - PySys_FormatStdout=python34.PySys_FormatStdout - PySys_GetObject=python34.PySys_GetObject - PySys_HasWarnOptions=python34.PySys_HasWarnOptions - PySys_ResetWarnOptions=python34.PySys_ResetWarnOptions - PySys_SetArgv=python34.PySys_SetArgv - PySys_SetArgvEx=python34.PySys_SetArgvEx - PySys_SetObject=python34.PySys_SetObject - PySys_SetPath=python34.PySys_SetPath - PySys_WriteStderr=python34.PySys_WriteStderr - PySys_WriteStdout=python34.PySys_WriteStdout - PyThreadState_Clear=python34.PyThreadState_Clear - PyThreadState_Delete=python34.PyThreadState_Delete - PyThreadState_DeleteCurrent=python34.PyThreadState_DeleteCurrent - PyThreadState_Get=python34.PyThreadState_Get - PyThreadState_GetDict=python34.PyThreadState_GetDict - PyThreadState_New=python34.PyThreadState_New - PyThreadState_SetAsyncExc=python34.PyThreadState_SetAsyncExc - PyThreadState_Swap=python34.PyThreadState_Swap - PyTraceBack_Here=python34.PyTraceBack_Here - PyTraceBack_Print=python34.PyTraceBack_Print - PyTraceBack_Type=python34.PyTraceBack_Type DATA - PyTupleIter_Type=python34.PyTupleIter_Type DATA - PyTuple_ClearFreeList=python34.PyTuple_ClearFreeList - PyTuple_GetItem=python34.PyTuple_GetItem - PyTuple_GetSlice=python34.PyTuple_GetSlice - PyTuple_New=python34.PyTuple_New - PyTuple_Pack=python34.PyTuple_Pack - PyTuple_SetItem=python34.PyTuple_SetItem - PyTuple_Size=python34.PyTuple_Size - PyTuple_Type=python34.PyTuple_Type DATA - PyType_ClearCache=python34.PyType_ClearCache - PyType_FromSpec=python34.PyType_FromSpec - PyType_FromSpecWithBases=python34.PyType_FromSpecWithBases - PyType_GenericAlloc=python34.PyType_GenericAlloc - PyType_GenericNew=python34.PyType_GenericNew - PyType_GetFlags=python34.PyType_GetFlags - PyType_IsSubtype=python34.PyType_IsSubtype - PyType_Modified=python34.PyType_Modified - PyType_Ready=python34.PyType_Ready - PyType_Type=python34.PyType_Type DATA - PyUnicodeDecodeError_Create=python34.PyUnicodeDecodeError_Create - PyUnicodeDecodeError_GetEncoding=python34.PyUnicodeDecodeError_GetEncoding - PyUnicodeDecodeError_GetEnd=python34.PyUnicodeDecodeError_GetEnd - PyUnicodeDecodeError_GetObject=python34.PyUnicodeDecodeError_GetObject - PyUnicodeDecodeError_GetReason=python34.PyUnicodeDecodeError_GetReason - PyUnicodeDecodeError_GetStart=python34.PyUnicodeDecodeError_GetStart - PyUnicodeDecodeError_SetEnd=python34.PyUnicodeDecodeError_SetEnd - PyUnicodeDecodeError_SetReason=python34.PyUnicodeDecodeError_SetReason - PyUnicodeDecodeError_SetStart=python34.PyUnicodeDecodeError_SetStart - PyUnicodeEncodeError_GetEncoding=python34.PyUnicodeEncodeError_GetEncoding - PyUnicodeEncodeError_GetEnd=python34.PyUnicodeEncodeError_GetEnd - PyUnicodeEncodeError_GetObject=python34.PyUnicodeEncodeError_GetObject - PyUnicodeEncodeError_GetReason=python34.PyUnicodeEncodeError_GetReason - PyUnicodeEncodeError_GetStart=python34.PyUnicodeEncodeError_GetStart - PyUnicodeEncodeError_SetEnd=python34.PyUnicodeEncodeError_SetEnd - PyUnicodeEncodeError_SetReason=python34.PyUnicodeEncodeError_SetReason - PyUnicodeEncodeError_SetStart=python34.PyUnicodeEncodeError_SetStart - PyUnicodeIter_Type=python34.PyUnicodeIter_Type DATA - PyUnicodeTranslateError_GetEnd=python34.PyUnicodeTranslateError_GetEnd - PyUnicodeTranslateError_GetObject=python34.PyUnicodeTranslateError_GetObject - PyUnicodeTranslateError_GetReason=python34.PyUnicodeTranslateError_GetReason - PyUnicodeTranslateError_GetStart=python34.PyUnicodeTranslateError_GetStart - PyUnicodeTranslateError_SetEnd=python34.PyUnicodeTranslateError_SetEnd - PyUnicodeTranslateError_SetReason=python34.PyUnicodeTranslateError_SetReason - PyUnicodeTranslateError_SetStart=python34.PyUnicodeTranslateError_SetStart - PyUnicode_Append=python34.PyUnicodeUCS2_Append - PyUnicode_AppendAndDel=python34.PyUnicodeUCS2_AppendAndDel - PyUnicode_AsASCIIString=python34.PyUnicodeUCS2_AsASCIIString - PyUnicode_AsCharmapString=python34.PyUnicodeUCS2_AsCharmapString - PyUnicode_AsDecodedObject=python34.PyUnicodeUCS2_AsDecodedObject - PyUnicode_AsDecodedUnicode=python34.PyUnicodeUCS2_AsDecodedUnicode - PyUnicode_AsEncodedObject=python34.PyUnicodeUCS2_AsEncodedObject - PyUnicode_AsEncodedString=python34.PyUnicodeUCS2_AsEncodedString - PyUnicode_AsEncodedUnicode=python34.PyUnicodeUCS2_AsEncodedUnicode - PyUnicode_AsLatin1String=python34.PyUnicodeUCS2_AsLatin1String - PyUnicode_AsRawUnicodeEscapeString=python34.PyUnicodeUCS2_AsRawUnicodeEscapeString - PyUnicode_AsUTF16String=python34.PyUnicodeUCS2_AsUTF16String - PyUnicode_AsUTF32String=python34.PyUnicodeUCS2_AsUTF32String - PyUnicode_AsUTF8String=python34.PyUnicodeUCS2_AsUTF8String - PyUnicode_AsUnicodeEscapeString=python34.PyUnicodeUCS2_AsUnicodeEscapeString - PyUnicode_AsWideChar=python34.PyUnicodeUCS2_AsWideChar - PyUnicode_ClearFreelist=python34.PyUnicodeUCS2_ClearFreelist - PyUnicode_Compare=python34.PyUnicodeUCS2_Compare - PyUnicode_Concat=python34.PyUnicodeUCS2_Concat - PyUnicode_Contains=python34.PyUnicodeUCS2_Contains - PyUnicode_Count=python34.PyUnicodeUCS2_Count - PyUnicode_Decode=python34.PyUnicodeUCS2_Decode - PyUnicode_DecodeASCII=python34.PyUnicodeUCS2_DecodeASCII - PyUnicode_DecodeCharmap=python34.PyUnicodeUCS2_DecodeCharmap - PyUnicode_DecodeFSDefault=python34.PyUnicodeUCS2_DecodeFSDefault - PyUnicode_DecodeFSDefaultAndSize=python34.PyUnicodeUCS2_DecodeFSDefaultAndSize - PyUnicode_DecodeLatin1=python34.PyUnicodeUCS2_DecodeLatin1 - PyUnicode_DecodeRawUnicodeEscape=python34.PyUnicodeUCS2_DecodeRawUnicodeEscape - PyUnicode_DecodeUTF16=python34.PyUnicodeUCS2_DecodeUTF16 - PyUnicode_DecodeUTF16Stateful=python34.PyUnicodeUCS2_DecodeUTF16Stateful - PyUnicode_DecodeUTF32=python34.PyUnicodeUCS2_DecodeUTF32 - PyUnicode_DecodeUTF32Stateful=python34.PyUnicodeUCS2_DecodeUTF32Stateful - PyUnicode_DecodeUTF8=python34.PyUnicodeUCS2_DecodeUTF8 - PyUnicode_DecodeUTF8Stateful=python34.PyUnicodeUCS2_DecodeUTF8Stateful - PyUnicode_DecodeUnicodeEscape=python34.PyUnicodeUCS2_DecodeUnicodeEscape - PyUnicode_FSConverter=python34.PyUnicodeUCS2_FSConverter - PyUnicode_FSDecoder=python34.PyUnicodeUCS2_FSDecoder - PyUnicode_Find=python34.PyUnicodeUCS2_Find - PyUnicode_Format=python34.PyUnicodeUCS2_Format - PyUnicode_FromEncodedObject=python34.PyUnicodeUCS2_FromEncodedObject - PyUnicode_FromFormat=python34.PyUnicodeUCS2_FromFormat - PyUnicode_FromFormatV=python34.PyUnicodeUCS2_FromFormatV - PyUnicode_FromObject=python34.PyUnicodeUCS2_FromObject - PyUnicode_FromOrdinal=python34.PyUnicodeUCS2_FromOrdinal - PyUnicode_FromString=python34.PyUnicodeUCS2_FromString - PyUnicode_FromStringAndSize=python34.PyUnicodeUCS2_FromStringAndSize - PyUnicode_FromWideChar=python34.PyUnicodeUCS2_FromWideChar - PyUnicode_GetDefaultEncoding=python34.PyUnicodeUCS2_GetDefaultEncoding - PyUnicode_GetSize=python34.PyUnicodeUCS2_GetSize - PyUnicode_IsIdentifier=python34.PyUnicodeUCS2_IsIdentifier - PyUnicode_Join=python34.PyUnicodeUCS2_Join - PyUnicode_Partition=python34.PyUnicodeUCS2_Partition - PyUnicode_RPartition=python34.PyUnicodeUCS2_RPartition - PyUnicode_RSplit=python34.PyUnicodeUCS2_RSplit - PyUnicode_Replace=python34.PyUnicodeUCS2_Replace - PyUnicode_Resize=python34.PyUnicodeUCS2_Resize - PyUnicode_RichCompare=python34.PyUnicodeUCS2_RichCompare - PyUnicode_SetDefaultEncoding=python34.PyUnicodeUCS2_SetDefaultEncoding - PyUnicode_Split=python34.PyUnicodeUCS2_Split - PyUnicode_Splitlines=python34.PyUnicodeUCS2_Splitlines - PyUnicode_Tailmatch=python34.PyUnicodeUCS2_Tailmatch - PyUnicode_Translate=python34.PyUnicodeUCS2_Translate - PyUnicode_BuildEncodingMap=python34.PyUnicode_BuildEncodingMap - PyUnicode_CompareWithASCIIString=python34.PyUnicode_CompareWithASCIIString - PyUnicode_DecodeUTF7=python34.PyUnicode_DecodeUTF7 - PyUnicode_DecodeUTF7Stateful=python34.PyUnicode_DecodeUTF7Stateful - PyUnicode_EncodeFSDefault=python34.PyUnicode_EncodeFSDefault - PyUnicode_InternFromString=python34.PyUnicode_InternFromString - PyUnicode_InternImmortal=python34.PyUnicode_InternImmortal - PyUnicode_InternInPlace=python34.PyUnicode_InternInPlace - PyUnicode_Type=python34.PyUnicode_Type DATA - PyWeakref_GetObject=python34.PyWeakref_GetObject DATA - PyWeakref_NewProxy=python34.PyWeakref_NewProxy - PyWeakref_NewRef=python34.PyWeakref_NewRef - PyWrapperDescr_Type=python34.PyWrapperDescr_Type DATA - PyWrapper_New=python34.PyWrapper_New - PyZip_Type=python34.PyZip_Type DATA - Py_AddPendingCall=python34.Py_AddPendingCall - Py_AtExit=python34.Py_AtExit - Py_BuildValue=python34.Py_BuildValue - Py_CompileString=python34.Py_CompileString - Py_DecRef=python34.Py_DecRef - Py_EndInterpreter=python34.Py_EndInterpreter - Py_Exit=python34.Py_Exit - Py_FatalError=python34.Py_FatalError - Py_FileSystemDefaultEncoding=python34.Py_FileSystemDefaultEncoding DATA - Py_Finalize=python34.Py_Finalize - Py_GetBuildInfo=python34.Py_GetBuildInfo - Py_GetCompiler=python34.Py_GetCompiler - Py_GetCopyright=python34.Py_GetCopyright - Py_GetExecPrefix=python34.Py_GetExecPrefix - Py_GetPath=python34.Py_GetPath - Py_GetPlatform=python34.Py_GetPlatform - Py_GetPrefix=python34.Py_GetPrefix - Py_GetProgramFullPath=python34.Py_GetProgramFullPath - Py_GetProgramName=python34.Py_GetProgramName - Py_GetPythonHome=python34.Py_GetPythonHome - Py_GetRecursionLimit=python34.Py_GetRecursionLimit - Py_GetVersion=python34.Py_GetVersion - Py_HasFileSystemDefaultEncoding=python34.Py_HasFileSystemDefaultEncoding DATA - Py_IncRef=python34.Py_IncRef - Py_Initialize=python34.Py_Initialize - Py_InitializeEx=python34.Py_InitializeEx - Py_IsInitialized=python34.Py_IsInitialized - Py_Main=python34.Py_Main - Py_MakePendingCalls=python34.Py_MakePendingCalls - Py_NewInterpreter=python34.Py_NewInterpreter - Py_ReprEnter=python34.Py_ReprEnter - Py_ReprLeave=python34.Py_ReprLeave - Py_SetProgramName=python34.Py_SetProgramName - Py_SetPythonHome=python34.Py_SetPythonHome - Py_SetRecursionLimit=python34.Py_SetRecursionLimit - Py_SymtableString=python34.Py_SymtableString - Py_VaBuildValue=python34.Py_VaBuildValue - _PyErr_BadInternalCall=python34._PyErr_BadInternalCall - _PyObject_CallFunction_SizeT=python34._PyObject_CallFunction_SizeT - _PyObject_CallMethod_SizeT=python34._PyObject_CallMethod_SizeT - _PyObject_GC_Malloc=python34._PyObject_GC_Malloc - _PyObject_GC_New=python34._PyObject_GC_New - _PyObject_GC_NewVar=python34._PyObject_GC_NewVar - _PyObject_GC_Resize=python34._PyObject_GC_Resize - _PyObject_New=python34._PyObject_New - _PyObject_NewVar=python34._PyObject_NewVar - _PyState_AddModule=python34._PyState_AddModule - _PyThreadState_Init=python34._PyThreadState_Init - _PyThreadState_Prealloc=python34._PyThreadState_Prealloc - _PyTrash_delete_later=python34._PyTrash_delete_later DATA - _PyTrash_delete_nesting=python34._PyTrash_delete_nesting DATA - _PyTrash_deposit_object=python34._PyTrash_deposit_object - _PyTrash_destroy_chain=python34._PyTrash_destroy_chain - _PyWeakref_CallableProxyType=python34._PyWeakref_CallableProxyType DATA - _PyWeakref_ProxyType=python34._PyWeakref_ProxyType DATA - _PyWeakref_RefType=python34._PyWeakref_RefType DATA - _Py_BuildValue_SizeT=python34._Py_BuildValue_SizeT - _Py_CheckRecursionLimit=python34._Py_CheckRecursionLimit DATA - _Py_CheckRecursiveCall=python34._Py_CheckRecursiveCall - _Py_Dealloc=python34._Py_Dealloc - _Py_EllipsisObject=python34._Py_EllipsisObject DATA - _Py_FalseStruct=python34._Py_FalseStruct DATA - _Py_NoneStruct=python34._Py_NoneStruct DATA - _Py_NotImplementedStruct=python34._Py_NotImplementedStruct DATA - _Py_SwappedOp=python34._Py_SwappedOp DATA - _Py_TrueStruct=python34._Py_TrueStruct DATA - _Py_VaBuildValue_SizeT=python34._Py_VaBuildValue_SizeT - _PyArg_Parse_SizeT=python34._PyArg_Parse_SizeT - _PyArg_ParseTuple_SizeT=python34._PyArg_ParseTuple_SizeT - _PyArg_ParseTupleAndKeywords_SizeT=python34._PyArg_ParseTupleAndKeywords_SizeT - _PyArg_VaParse_SizeT=python34._PyArg_VaParse_SizeT - _PyArg_VaParseTupleAndKeywords_SizeT=python34._PyArg_VaParseTupleAndKeywords_SizeT - _Py_BuildValue_SizeT=python34._Py_BuildValue_SizeT + PyArg_Parse=python35.PyArg_Parse + PyArg_ParseTuple=python35.PyArg_ParseTuple + PyArg_ParseTupleAndKeywords=python35.PyArg_ParseTupleAndKeywords + PyArg_UnpackTuple=python35.PyArg_UnpackTuple + PyArg_VaParse=python35.PyArg_VaParse + PyArg_VaParseTupleAndKeywords=python35.PyArg_VaParseTupleAndKeywords + PyArg_ValidateKeywordArguments=python35.PyArg_ValidateKeywordArguments + PyBaseObject_Type=python35.PyBaseObject_Type DATA + PyBool_FromLong=python35.PyBool_FromLong + PyBool_Type=python35.PyBool_Type DATA + PyByteArrayIter_Type=python35.PyByteArrayIter_Type DATA + PyByteArray_AsString=python35.PyByteArray_AsString + PyByteArray_Concat=python35.PyByteArray_Concat + PyByteArray_FromObject=python35.PyByteArray_FromObject + PyByteArray_FromStringAndSize=python35.PyByteArray_FromStringAndSize + PyByteArray_Resize=python35.PyByteArray_Resize + PyByteArray_Size=python35.PyByteArray_Size + PyByteArray_Type=python35.PyByteArray_Type DATA + PyBytesIter_Type=python35.PyBytesIter_Type DATA + PyBytes_AsString=python35.PyBytes_AsString + PyBytes_AsStringAndSize=python35.PyBytes_AsStringAndSize + PyBytes_Concat=python35.PyBytes_Concat + PyBytes_ConcatAndDel=python35.PyBytes_ConcatAndDel + PyBytes_DecodeEscape=python35.PyBytes_DecodeEscape + PyBytes_FromFormat=python35.PyBytes_FromFormat + PyBytes_FromFormatV=python35.PyBytes_FromFormatV + PyBytes_FromObject=python35.PyBytes_FromObject + PyBytes_FromString=python35.PyBytes_FromString + PyBytes_FromStringAndSize=python35.PyBytes_FromStringAndSize + PyBytes_Repr=python35.PyBytes_Repr + PyBytes_Size=python35.PyBytes_Size + PyBytes_Type=python35.PyBytes_Type DATA + PyCFunction_Call=python35.PyCFunction_Call + PyCFunction_ClearFreeList=python35.PyCFunction_ClearFreeList + PyCFunction_GetFlags=python35.PyCFunction_GetFlags + PyCFunction_GetFunction=python35.PyCFunction_GetFunction + PyCFunction_GetSelf=python35.PyCFunction_GetSelf + PyCFunction_New=python35.PyCFunction_New + PyCFunction_NewEx=python35.PyCFunction_NewEx + PyCFunction_Type=python35.PyCFunction_Type DATA + PyCallIter_New=python35.PyCallIter_New + PyCallIter_Type=python35.PyCallIter_Type DATA + PyCallable_Check=python35.PyCallable_Check + PyCapsule_GetContext=python35.PyCapsule_GetContext + PyCapsule_GetDestructor=python35.PyCapsule_GetDestructor + PyCapsule_GetName=python35.PyCapsule_GetName + PyCapsule_GetPointer=python35.PyCapsule_GetPointer + PyCapsule_Import=python35.PyCapsule_Import + PyCapsule_IsValid=python35.PyCapsule_IsValid + PyCapsule_New=python35.PyCapsule_New + PyCapsule_SetContext=python35.PyCapsule_SetContext + PyCapsule_SetDestructor=python35.PyCapsule_SetDestructor + PyCapsule_SetName=python35.PyCapsule_SetName + PyCapsule_SetPointer=python35.PyCapsule_SetPointer + PyCapsule_Type=python35.PyCapsule_Type DATA + PyClassMethodDescr_Type=python35.PyClassMethodDescr_Type DATA + PyCodec_BackslashReplaceErrors=python35.PyCodec_BackslashReplaceErrors + PyCodec_Decode=python35.PyCodec_Decode + PyCodec_Decoder=python35.PyCodec_Decoder + PyCodec_Encode=python35.PyCodec_Encode + PyCodec_Encoder=python35.PyCodec_Encoder + PyCodec_IgnoreErrors=python35.PyCodec_IgnoreErrors + PyCodec_IncrementalDecoder=python35.PyCodec_IncrementalDecoder + PyCodec_IncrementalEncoder=python35.PyCodec_IncrementalEncoder + PyCodec_KnownEncoding=python35.PyCodec_KnownEncoding + PyCodec_LookupError=python35.PyCodec_LookupError + PyCodec_Register=python35.PyCodec_Register + PyCodec_RegisterError=python35.PyCodec_RegisterError + PyCodec_ReplaceErrors=python35.PyCodec_ReplaceErrors + PyCodec_StreamReader=python35.PyCodec_StreamReader + PyCodec_StreamWriter=python35.PyCodec_StreamWriter + PyCodec_StrictErrors=python35.PyCodec_StrictErrors + PyCodec_XMLCharRefReplaceErrors=python35.PyCodec_XMLCharRefReplaceErrors + PyComplex_FromDoubles=python35.PyComplex_FromDoubles + PyComplex_ImagAsDouble=python35.PyComplex_ImagAsDouble + PyComplex_RealAsDouble=python35.PyComplex_RealAsDouble + PyComplex_Type=python35.PyComplex_Type DATA + PyDescr_NewClassMethod=python35.PyDescr_NewClassMethod + PyDescr_NewGetSet=python35.PyDescr_NewGetSet + PyDescr_NewMember=python35.PyDescr_NewMember + PyDescr_NewMethod=python35.PyDescr_NewMethod + PyDictItems_Type=python35.PyDictItems_Type DATA + PyDictIterItem_Type=python35.PyDictIterItem_Type DATA + PyDictIterKey_Type=python35.PyDictIterKey_Type DATA + PyDictIterValue_Type=python35.PyDictIterValue_Type DATA + PyDictKeys_Type=python35.PyDictKeys_Type DATA + PyDictProxy_New=python35.PyDictProxy_New + PyDictProxy_Type=python35.PyDictProxy_Type DATA + PyDictValues_Type=python35.PyDictValues_Type DATA + PyDict_Clear=python35.PyDict_Clear + PyDict_Contains=python35.PyDict_Contains + PyDict_Copy=python35.PyDict_Copy + PyDict_DelItem=python35.PyDict_DelItem + PyDict_DelItemString=python35.PyDict_DelItemString + PyDict_GetItem=python35.PyDict_GetItem + PyDict_GetItemString=python35.PyDict_GetItemString + PyDict_GetItemWithError=python35.PyDict_GetItemWithError + PyDict_Items=python35.PyDict_Items + PyDict_Keys=python35.PyDict_Keys + PyDict_Merge=python35.PyDict_Merge + PyDict_MergeFromSeq2=python35.PyDict_MergeFromSeq2 + PyDict_New=python35.PyDict_New + PyDict_Next=python35.PyDict_Next + PyDict_SetItem=python35.PyDict_SetItem + PyDict_SetItemString=python35.PyDict_SetItemString + PyDict_Size=python35.PyDict_Size + PyDict_Type=python35.PyDict_Type DATA + PyDict_Update=python35.PyDict_Update + PyDict_Values=python35.PyDict_Values + PyEllipsis_Type=python35.PyEllipsis_Type DATA + PyEnum_Type=python35.PyEnum_Type DATA + PyErr_BadArgument=python35.PyErr_BadArgument + PyErr_BadInternalCall=python35.PyErr_BadInternalCall + PyErr_CheckSignals=python35.PyErr_CheckSignals + PyErr_Clear=python35.PyErr_Clear + PyErr_Display=python35.PyErr_Display + PyErr_ExceptionMatches=python35.PyErr_ExceptionMatches + PyErr_Fetch=python35.PyErr_Fetch + PyErr_Format=python35.PyErr_Format + PyErr_FormatV=python35.PyErr_FormatV + PyErr_GivenExceptionMatches=python35.PyErr_GivenExceptionMatches + PyErr_NewException=python35.PyErr_NewException + PyErr_NewExceptionWithDoc=python35.PyErr_NewExceptionWithDoc + PyErr_NoMemory=python35.PyErr_NoMemory + PyErr_NormalizeException=python35.PyErr_NormalizeException + PyErr_Occurred=python35.PyErr_Occurred + PyErr_Print=python35.PyErr_Print + PyErr_PrintEx=python35.PyErr_PrintEx + PyErr_ProgramText=python35.PyErr_ProgramText + PyErr_Restore=python35.PyErr_Restore + PyErr_SetFromErrno=python35.PyErr_SetFromErrno + PyErr_SetFromErrnoWithFilename=python35.PyErr_SetFromErrnoWithFilename + PyErr_SetFromErrnoWithFilenameObject=python35.PyErr_SetFromErrnoWithFilenameObject + PyErr_SetInterrupt=python35.PyErr_SetInterrupt + PyErr_SetNone=python35.PyErr_SetNone + PyErr_SetObject=python35.PyErr_SetObject + PyErr_SetString=python35.PyErr_SetString + PyErr_SyntaxLocation=python35.PyErr_SyntaxLocation + PyErr_WarnEx=python35.PyErr_WarnEx + PyErr_WarnExplicit=python35.PyErr_WarnExplicit + PyErr_WarnFormat=python35.PyErr_WarnFormat + PyErr_WriteUnraisable=python35.PyErr_WriteUnraisable + PyEval_AcquireLock=python35.PyEval_AcquireLock + PyEval_AcquireThread=python35.PyEval_AcquireThread + PyEval_CallFunction=python35.PyEval_CallFunction + PyEval_CallMethod=python35.PyEval_CallMethod + PyEval_CallObjectWithKeywords=python35.PyEval_CallObjectWithKeywords + PyEval_EvalCode=python35.PyEval_EvalCode + PyEval_EvalCodeEx=python35.PyEval_EvalCodeEx + PyEval_EvalFrame=python35.PyEval_EvalFrame + PyEval_EvalFrameEx=python35.PyEval_EvalFrameEx + PyEval_GetBuiltins=python35.PyEval_GetBuiltins + PyEval_GetCallStats=python35.PyEval_GetCallStats + PyEval_GetFrame=python35.PyEval_GetFrame + PyEval_GetFuncDesc=python35.PyEval_GetFuncDesc + PyEval_GetFuncName=python35.PyEval_GetFuncName + PyEval_GetGlobals=python35.PyEval_GetGlobals + PyEval_GetLocals=python35.PyEval_GetLocals + PyEval_InitThreads=python35.PyEval_InitThreads + PyEval_ReInitThreads=python35.PyEval_ReInitThreads + PyEval_ReleaseLock=python35.PyEval_ReleaseLock + PyEval_ReleaseThread=python35.PyEval_ReleaseThread + PyEval_RestoreThread=python35.PyEval_RestoreThread + PyEval_SaveThread=python35.PyEval_SaveThread + PyEval_ThreadsInitialized=python35.PyEval_ThreadsInitialized + PyExc_ArithmeticError=python35.PyExc_ArithmeticError DATA + PyExc_AssertionError=python35.PyExc_AssertionError DATA + PyExc_AttributeError=python35.PyExc_AttributeError DATA + PyExc_BaseException=python35.PyExc_BaseException DATA + PyExc_BufferError=python35.PyExc_BufferError DATA + PyExc_BytesWarning=python35.PyExc_BytesWarning DATA + PyExc_DeprecationWarning=python35.PyExc_DeprecationWarning DATA + PyExc_EOFError=python35.PyExc_EOFError DATA + PyExc_EnvironmentError=python35.PyExc_EnvironmentError DATA + PyExc_Exception=python35.PyExc_Exception DATA + PyExc_FloatingPointError=python35.PyExc_FloatingPointError DATA + PyExc_FutureWarning=python35.PyExc_FutureWarning DATA + PyExc_GeneratorExit=python35.PyExc_GeneratorExit DATA + PyExc_IOError=python35.PyExc_IOError DATA + PyExc_ImportError=python35.PyExc_ImportError DATA + PyExc_ImportWarning=python35.PyExc_ImportWarning DATA + PyExc_IndentationError=python35.PyExc_IndentationError DATA + PyExc_IndexError=python35.PyExc_IndexError DATA + PyExc_KeyError=python35.PyExc_KeyError DATA + PyExc_KeyboardInterrupt=python35.PyExc_KeyboardInterrupt DATA + PyExc_LookupError=python35.PyExc_LookupError DATA + PyExc_MemoryError=python35.PyExc_MemoryError DATA + PyExc_MemoryErrorInst=python35.PyExc_MemoryErrorInst DATA + PyExc_NameError=python35.PyExc_NameError DATA + PyExc_NotImplementedError=python35.PyExc_NotImplementedError DATA + PyExc_OSError=python35.PyExc_OSError DATA + PyExc_OverflowError=python35.PyExc_OverflowError DATA + PyExc_PendingDeprecationWarning=python35.PyExc_PendingDeprecationWarning DATA + PyExc_RecursionErrorInst=python35.PyExc_RecursionErrorInst DATA + PyExc_ReferenceError=python35.PyExc_ReferenceError DATA + PyExc_RuntimeError=python35.PyExc_RuntimeError DATA + PyExc_RuntimeWarning=python35.PyExc_RuntimeWarning DATA + PyExc_StopIteration=python35.PyExc_StopIteration DATA + PyExc_SyntaxError=python35.PyExc_SyntaxError DATA + PyExc_SyntaxWarning=python35.PyExc_SyntaxWarning DATA + PyExc_SystemError=python35.PyExc_SystemError DATA + PyExc_SystemExit=python35.PyExc_SystemExit DATA + PyExc_TabError=python35.PyExc_TabError DATA + PyExc_TypeError=python35.PyExc_TypeError DATA + PyExc_UnboundLocalError=python35.PyExc_UnboundLocalError DATA + PyExc_UnicodeDecodeError=python35.PyExc_UnicodeDecodeError DATA + PyExc_UnicodeEncodeError=python35.PyExc_UnicodeEncodeError DATA + PyExc_UnicodeError=python35.PyExc_UnicodeError DATA + PyExc_UnicodeTranslateError=python35.PyExc_UnicodeTranslateError DATA + PyExc_UnicodeWarning=python35.PyExc_UnicodeWarning DATA + PyExc_UserWarning=python35.PyExc_UserWarning DATA + PyExc_ValueError=python35.PyExc_ValueError DATA + PyExc_Warning=python35.PyExc_Warning DATA + PyExc_ZeroDivisionError=python35.PyExc_ZeroDivisionError DATA + PyException_GetCause=python35.PyException_GetCause + PyException_GetContext=python35.PyException_GetContext + PyException_GetTraceback=python35.PyException_GetTraceback + PyException_SetCause=python35.PyException_SetCause + PyException_SetContext=python35.PyException_SetContext + PyException_SetTraceback=python35.PyException_SetTraceback + PyFile_FromFd=python35.PyFile_FromFd + PyFile_GetLine=python35.PyFile_GetLine + PyFile_WriteObject=python35.PyFile_WriteObject + PyFile_WriteString=python35.PyFile_WriteString + PyFilter_Type=python35.PyFilter_Type DATA + PyFloat_AsDouble=python35.PyFloat_AsDouble + PyFloat_FromDouble=python35.PyFloat_FromDouble + PyFloat_FromString=python35.PyFloat_FromString + PyFloat_GetInfo=python35.PyFloat_GetInfo + PyFloat_GetMax=python35.PyFloat_GetMax + PyFloat_GetMin=python35.PyFloat_GetMin + PyFloat_Type=python35.PyFloat_Type DATA + PyFrozenSet_New=python35.PyFrozenSet_New + PyFrozenSet_Type=python35.PyFrozenSet_Type DATA + PyGC_Collect=python35.PyGC_Collect + PyGILState_Ensure=python35.PyGILState_Ensure + PyGILState_GetThisThreadState=python35.PyGILState_GetThisThreadState + PyGILState_Release=python35.PyGILState_Release + PyGetSetDescr_Type=python35.PyGetSetDescr_Type DATA + PyImport_AddModule=python35.PyImport_AddModule + PyImport_AppendInittab=python35.PyImport_AppendInittab + PyImport_Cleanup=python35.PyImport_Cleanup + PyImport_ExecCodeModule=python35.PyImport_ExecCodeModule + PyImport_ExecCodeModuleEx=python35.PyImport_ExecCodeModuleEx + PyImport_ExecCodeModuleWithPathnames=python35.PyImport_ExecCodeModuleWithPathnames + PyImport_GetImporter=python35.PyImport_GetImporter + PyImport_GetMagicNumber=python35.PyImport_GetMagicNumber + PyImport_GetMagicTag=python35.PyImport_GetMagicTag + PyImport_GetModuleDict=python35.PyImport_GetModuleDict + PyImport_Import=python35.PyImport_Import + PyImport_ImportFrozenModule=python35.PyImport_ImportFrozenModule + PyImport_ImportModule=python35.PyImport_ImportModule + PyImport_ImportModuleLevel=python35.PyImport_ImportModuleLevel + PyImport_ImportModuleNoBlock=python35.PyImport_ImportModuleNoBlock + PyImport_ReloadModule=python35.PyImport_ReloadModule + PyInterpreterState_Clear=python35.PyInterpreterState_Clear + PyInterpreterState_Delete=python35.PyInterpreterState_Delete + PyInterpreterState_New=python35.PyInterpreterState_New + PyIter_Next=python35.PyIter_Next + PyListIter_Type=python35.PyListIter_Type DATA + PyListRevIter_Type=python35.PyListRevIter_Type DATA + PyList_Append=python35.PyList_Append + PyList_AsTuple=python35.PyList_AsTuple + PyList_GetItem=python35.PyList_GetItem + PyList_GetSlice=python35.PyList_GetSlice + PyList_Insert=python35.PyList_Insert + PyList_New=python35.PyList_New + PyList_Reverse=python35.PyList_Reverse + PyList_SetItem=python35.PyList_SetItem + PyList_SetSlice=python35.PyList_SetSlice + PyList_Size=python35.PyList_Size + PyList_Sort=python35.PyList_Sort + PyList_Type=python35.PyList_Type DATA + PyLongRangeIter_Type=python35.PyLongRangeIter_Type DATA + PyLong_AsDouble=python35.PyLong_AsDouble + PyLong_AsLong=python35.PyLong_AsLong + PyLong_AsLongAndOverflow=python35.PyLong_AsLongAndOverflow + PyLong_AsLongLong=python35.PyLong_AsLongLong + PyLong_AsLongLongAndOverflow=python35.PyLong_AsLongLongAndOverflow + PyLong_AsSize_t=python35.PyLong_AsSize_t + PyLong_AsSsize_t=python35.PyLong_AsSsize_t + PyLong_AsUnsignedLong=python35.PyLong_AsUnsignedLong + PyLong_AsUnsignedLongLong=python35.PyLong_AsUnsignedLongLong + PyLong_AsUnsignedLongLongMask=python35.PyLong_AsUnsignedLongLongMask + PyLong_AsUnsignedLongMask=python35.PyLong_AsUnsignedLongMask + PyLong_AsVoidPtr=python35.PyLong_AsVoidPtr + PyLong_FromDouble=python35.PyLong_FromDouble + PyLong_FromLong=python35.PyLong_FromLong + PyLong_FromLongLong=python35.PyLong_FromLongLong + PyLong_FromSize_t=python35.PyLong_FromSize_t + PyLong_FromSsize_t=python35.PyLong_FromSsize_t + PyLong_FromString=python35.PyLong_FromString + PyLong_FromUnsignedLong=python35.PyLong_FromUnsignedLong + PyLong_FromUnsignedLongLong=python35.PyLong_FromUnsignedLongLong + PyLong_FromVoidPtr=python35.PyLong_FromVoidPtr + PyLong_GetInfo=python35.PyLong_GetInfo + PyLong_Type=python35.PyLong_Type DATA + PyMap_Type=python35.PyMap_Type DATA + PyMapping_Check=python35.PyMapping_Check + PyMapping_GetItemString=python35.PyMapping_GetItemString + PyMapping_HasKey=python35.PyMapping_HasKey + PyMapping_HasKeyString=python35.PyMapping_HasKeyString + PyMapping_Items=python35.PyMapping_Items + PyMapping_Keys=python35.PyMapping_Keys + PyMapping_Length=python35.PyMapping_Length + PyMapping_SetItemString=python35.PyMapping_SetItemString + PyMapping_Size=python35.PyMapping_Size + PyMapping_Values=python35.PyMapping_Values + PyMem_Free=python35.PyMem_Free + PyMem_Malloc=python35.PyMem_Malloc + PyMem_Realloc=python35.PyMem_Realloc + PyMemberDescr_Type=python35.PyMemberDescr_Type DATA + PyMemoryView_FromObject=python35.PyMemoryView_FromObject + PyMemoryView_GetContiguous=python35.PyMemoryView_GetContiguous + PyMemoryView_Type=python35.PyMemoryView_Type DATA + PyMethodDescr_Type=python35.PyMethodDescr_Type DATA + PyModule_AddIntConstant=python35.PyModule_AddIntConstant + PyModule_AddObject=python35.PyModule_AddObject + PyModule_AddStringConstant=python35.PyModule_AddStringConstant + PyModule_Create2=python35.PyModule_Create2 + PyModule_GetDef=python35.PyModule_GetDef + PyModule_GetDict=python35.PyModule_GetDict + PyModule_GetFilename=python35.PyModule_GetFilename + PyModule_GetFilenameObject=python35.PyModule_GetFilenameObject + PyModule_GetName=python35.PyModule_GetName + PyModule_GetState=python35.PyModule_GetState + PyModule_New=python35.PyModule_New + PyModule_Type=python35.PyModule_Type DATA + PyNullImporter_Type=python35.PyNullImporter_Type DATA + PyNumber_Absolute=python35.PyNumber_Absolute + PyNumber_Add=python35.PyNumber_Add + PyNumber_And=python35.PyNumber_And + PyNumber_AsSsize_t=python35.PyNumber_AsSsize_t + PyNumber_Check=python35.PyNumber_Check + PyNumber_Divmod=python35.PyNumber_Divmod + PyNumber_Float=python35.PyNumber_Float + PyNumber_FloorDivide=python35.PyNumber_FloorDivide + PyNumber_InPlaceAdd=python35.PyNumber_InPlaceAdd + PyNumber_InPlaceAnd=python35.PyNumber_InPlaceAnd + PyNumber_InPlaceFloorDivide=python35.PyNumber_InPlaceFloorDivide + PyNumber_InPlaceLshift=python35.PyNumber_InPlaceLshift + PyNumber_InPlaceMultiply=python35.PyNumber_InPlaceMultiply + PyNumber_InPlaceOr=python35.PyNumber_InPlaceOr + PyNumber_InPlacePower=python35.PyNumber_InPlacePower + PyNumber_InPlaceRemainder=python35.PyNumber_InPlaceRemainder + PyNumber_InPlaceRshift=python35.PyNumber_InPlaceRshift + PyNumber_InPlaceSubtract=python35.PyNumber_InPlaceSubtract + PyNumber_InPlaceTrueDivide=python35.PyNumber_InPlaceTrueDivide + PyNumber_InPlaceXor=python35.PyNumber_InPlaceXor + PyNumber_Index=python35.PyNumber_Index + PyNumber_Invert=python35.PyNumber_Invert + PyNumber_Long=python35.PyNumber_Long + PyNumber_Lshift=python35.PyNumber_Lshift + PyNumber_Multiply=python35.PyNumber_Multiply + PyNumber_Negative=python35.PyNumber_Negative + PyNumber_Or=python35.PyNumber_Or + PyNumber_Positive=python35.PyNumber_Positive + PyNumber_Power=python35.PyNumber_Power + PyNumber_Remainder=python35.PyNumber_Remainder + PyNumber_Rshift=python35.PyNumber_Rshift + PyNumber_Subtract=python35.PyNumber_Subtract + PyNumber_ToBase=python35.PyNumber_ToBase + PyNumber_TrueDivide=python35.PyNumber_TrueDivide + PyNumber_Xor=python35.PyNumber_Xor + PyOS_AfterFork=python35.PyOS_AfterFork + PyOS_InitInterrupts=python35.PyOS_InitInterrupts + PyOS_InputHook=python35.PyOS_InputHook DATA + PyOS_InterruptOccurred=python35.PyOS_InterruptOccurred + PyOS_ReadlineFunctionPointer=python35.PyOS_ReadlineFunctionPointer DATA + PyOS_double_to_string=python35.PyOS_double_to_string + PyOS_getsig=python35.PyOS_getsig + PyOS_mystricmp=python35.PyOS_mystricmp + PyOS_mystrnicmp=python35.PyOS_mystrnicmp + PyOS_setsig=python35.PyOS_setsig + PyOS_snprintf=python35.PyOS_snprintf + PyOS_string_to_double=python35.PyOS_string_to_double + PyOS_strtol=python35.PyOS_strtol + PyOS_strtoul=python35.PyOS_strtoul + PyOS_vsnprintf=python35.PyOS_vsnprintf + PyObject_ASCII=python35.PyObject_ASCII + PyObject_AsCharBuffer=python35.PyObject_AsCharBuffer + PyObject_AsFileDescriptor=python35.PyObject_AsFileDescriptor + PyObject_AsReadBuffer=python35.PyObject_AsReadBuffer + PyObject_AsWriteBuffer=python35.PyObject_AsWriteBuffer + PyObject_Bytes=python35.PyObject_Bytes + PyObject_Call=python35.PyObject_Call + PyObject_CallFunction=python35.PyObject_CallFunction + PyObject_CallFunctionObjArgs=python35.PyObject_CallFunctionObjArgs + PyObject_CallMethod=python35.PyObject_CallMethod + PyObject_CallMethodObjArgs=python35.PyObject_CallMethodObjArgs + PyObject_CallObject=python35.PyObject_CallObject + PyObject_CheckReadBuffer=python35.PyObject_CheckReadBuffer + PyObject_ClearWeakRefs=python35.PyObject_ClearWeakRefs + PyObject_DelItem=python35.PyObject_DelItem + PyObject_DelItemString=python35.PyObject_DelItemString + PyObject_Dir=python35.PyObject_Dir + PyObject_Format=python35.PyObject_Format + PyObject_Free=python35.PyObject_Free + PyObject_GC_Del=python35.PyObject_GC_Del + PyObject_GC_Track=python35.PyObject_GC_Track + PyObject_GC_UnTrack=python35.PyObject_GC_UnTrack + PyObject_GenericGetAttr=python35.PyObject_GenericGetAttr + PyObject_GenericSetAttr=python35.PyObject_GenericSetAttr + PyObject_GetAttr=python35.PyObject_GetAttr + PyObject_GetAttrString=python35.PyObject_GetAttrString + PyObject_GetItem=python35.PyObject_GetItem + PyObject_GetIter=python35.PyObject_GetIter + PyObject_HasAttr=python35.PyObject_HasAttr + PyObject_HasAttrString=python35.PyObject_HasAttrString + PyObject_Hash=python35.PyObject_Hash + PyObject_HashNotImplemented=python35.PyObject_HashNotImplemented + PyObject_Init=python35.PyObject_Init + PyObject_InitVar=python35.PyObject_InitVar + PyObject_IsInstance=python35.PyObject_IsInstance + PyObject_IsSubclass=python35.PyObject_IsSubclass + PyObject_IsTrue=python35.PyObject_IsTrue + PyObject_Length=python35.PyObject_Length + PyObject_Malloc=python35.PyObject_Malloc + PyObject_Not=python35.PyObject_Not + PyObject_Realloc=python35.PyObject_Realloc + PyObject_Repr=python35.PyObject_Repr + PyObject_RichCompare=python35.PyObject_RichCompare + PyObject_RichCompareBool=python35.PyObject_RichCompareBool + PyObject_SelfIter=python35.PyObject_SelfIter + PyObject_SetAttr=python35.PyObject_SetAttr + PyObject_SetAttrString=python35.PyObject_SetAttrString + PyObject_SetItem=python35.PyObject_SetItem + PyObject_Size=python35.PyObject_Size + PyObject_Str=python35.PyObject_Str + PyObject_Type=python35.PyObject_Type DATA + PyParser_SimpleParseFileFlags=python35.PyParser_SimpleParseFileFlags + PyParser_SimpleParseStringFlags=python35.PyParser_SimpleParseStringFlags + PyProperty_Type=python35.PyProperty_Type DATA + PyRangeIter_Type=python35.PyRangeIter_Type DATA + PyRange_Type=python35.PyRange_Type DATA + PyReversed_Type=python35.PyReversed_Type DATA + PySeqIter_New=python35.PySeqIter_New + PySeqIter_Type=python35.PySeqIter_Type DATA + PySequence_Check=python35.PySequence_Check + PySequence_Concat=python35.PySequence_Concat + PySequence_Contains=python35.PySequence_Contains + PySequence_Count=python35.PySequence_Count + PySequence_DelItem=python35.PySequence_DelItem + PySequence_DelSlice=python35.PySequence_DelSlice + PySequence_Fast=python35.PySequence_Fast + PySequence_GetItem=python35.PySequence_GetItem + PySequence_GetSlice=python35.PySequence_GetSlice + PySequence_In=python35.PySequence_In + PySequence_InPlaceConcat=python35.PySequence_InPlaceConcat + PySequence_InPlaceRepeat=python35.PySequence_InPlaceRepeat + PySequence_Index=python35.PySequence_Index + PySequence_Length=python35.PySequence_Length + PySequence_List=python35.PySequence_List + PySequence_Repeat=python35.PySequence_Repeat + PySequence_SetItem=python35.PySequence_SetItem + PySequence_SetSlice=python35.PySequence_SetSlice + PySequence_Size=python35.PySequence_Size + PySequence_Tuple=python35.PySequence_Tuple + PySetIter_Type=python35.PySetIter_Type DATA + PySet_Add=python35.PySet_Add + PySet_Clear=python35.PySet_Clear + PySet_Contains=python35.PySet_Contains + PySet_Discard=python35.PySet_Discard + PySet_New=python35.PySet_New + PySet_Pop=python35.PySet_Pop + PySet_Size=python35.PySet_Size + PySet_Type=python35.PySet_Type DATA + PySlice_GetIndices=python35.PySlice_GetIndices + PySlice_GetIndicesEx=python35.PySlice_GetIndicesEx + PySlice_New=python35.PySlice_New + PySlice_Type=python35.PySlice_Type DATA + PySortWrapper_Type=python35.PySortWrapper_Type DATA + PyState_FindModule=python35.PyState_FindModule + PyState_AddModule=python35.PyState_AddModule + PyState_RemoveModule=python35.PyState_RemoveModule + PyStructSequence_GetItem=python35.PyStructSequence_GetItem + PyStructSequence_New=python35.PyStructSequence_New + PyStructSequence_NewType=python35.PyStructSequence_NewType + PyStructSequence_SetItem=python35.PyStructSequence_SetItem + PySuper_Type=python35.PySuper_Type DATA + PySys_AddWarnOption=python35.PySys_AddWarnOption + PySys_AddWarnOptionUnicode=python35.PySys_AddWarnOptionUnicode + PySys_FormatStderr=python35.PySys_FormatStderr + PySys_FormatStdout=python35.PySys_FormatStdout + PySys_GetObject=python35.PySys_GetObject + PySys_HasWarnOptions=python35.PySys_HasWarnOptions + PySys_ResetWarnOptions=python35.PySys_ResetWarnOptions + PySys_SetArgv=python35.PySys_SetArgv + PySys_SetArgvEx=python35.PySys_SetArgvEx + PySys_SetObject=python35.PySys_SetObject + PySys_SetPath=python35.PySys_SetPath + PySys_WriteStderr=python35.PySys_WriteStderr + PySys_WriteStdout=python35.PySys_WriteStdout + PyThreadState_Clear=python35.PyThreadState_Clear + PyThreadState_Delete=python35.PyThreadState_Delete + PyThreadState_DeleteCurrent=python35.PyThreadState_DeleteCurrent + PyThreadState_Get=python35.PyThreadState_Get + PyThreadState_GetDict=python35.PyThreadState_GetDict + PyThreadState_New=python35.PyThreadState_New + PyThreadState_SetAsyncExc=python35.PyThreadState_SetAsyncExc + PyThreadState_Swap=python35.PyThreadState_Swap + PyTraceBack_Here=python35.PyTraceBack_Here + PyTraceBack_Print=python35.PyTraceBack_Print + PyTraceBack_Type=python35.PyTraceBack_Type DATA + PyTupleIter_Type=python35.PyTupleIter_Type DATA + PyTuple_ClearFreeList=python35.PyTuple_ClearFreeList + PyTuple_GetItem=python35.PyTuple_GetItem + PyTuple_GetSlice=python35.PyTuple_GetSlice + PyTuple_New=python35.PyTuple_New + PyTuple_Pack=python35.PyTuple_Pack + PyTuple_SetItem=python35.PyTuple_SetItem + PyTuple_Size=python35.PyTuple_Size + PyTuple_Type=python35.PyTuple_Type DATA + PyType_ClearCache=python35.PyType_ClearCache + PyType_FromSpec=python35.PyType_FromSpec + PyType_FromSpecWithBases=python35.PyType_FromSpecWithBases + PyType_GenericAlloc=python35.PyType_GenericAlloc + PyType_GenericNew=python35.PyType_GenericNew + PyType_GetFlags=python35.PyType_GetFlags + PyType_GetSlot=python35.PyType_GetSlot + PyType_IsSubtype=python35.PyType_IsSubtype + PyType_Modified=python35.PyType_Modified + PyType_Ready=python35.PyType_Ready + PyType_Type=python35.PyType_Type DATA + PyUnicodeDecodeError_Create=python35.PyUnicodeDecodeError_Create + PyUnicodeDecodeError_GetEncoding=python35.PyUnicodeDecodeError_GetEncoding + PyUnicodeDecodeError_GetEnd=python35.PyUnicodeDecodeError_GetEnd + PyUnicodeDecodeError_GetObject=python35.PyUnicodeDecodeError_GetObject + PyUnicodeDecodeError_GetReason=python35.PyUnicodeDecodeError_GetReason + PyUnicodeDecodeError_GetStart=python35.PyUnicodeDecodeError_GetStart + PyUnicodeDecodeError_SetEnd=python35.PyUnicodeDecodeError_SetEnd + PyUnicodeDecodeError_SetReason=python35.PyUnicodeDecodeError_SetReason + PyUnicodeDecodeError_SetStart=python35.PyUnicodeDecodeError_SetStart + PyUnicodeEncodeError_GetEncoding=python35.PyUnicodeEncodeError_GetEncoding + PyUnicodeEncodeError_GetEnd=python35.PyUnicodeEncodeError_GetEnd + PyUnicodeEncodeError_GetObject=python35.PyUnicodeEncodeError_GetObject + PyUnicodeEncodeError_GetReason=python35.PyUnicodeEncodeError_GetReason + PyUnicodeEncodeError_GetStart=python35.PyUnicodeEncodeError_GetStart + PyUnicodeEncodeError_SetEnd=python35.PyUnicodeEncodeError_SetEnd + PyUnicodeEncodeError_SetReason=python35.PyUnicodeEncodeError_SetReason + PyUnicodeEncodeError_SetStart=python35.PyUnicodeEncodeError_SetStart + PyUnicodeIter_Type=python35.PyUnicodeIter_Type DATA + PyUnicodeTranslateError_GetEnd=python35.PyUnicodeTranslateError_GetEnd + PyUnicodeTranslateError_GetObject=python35.PyUnicodeTranslateError_GetObject + PyUnicodeTranslateError_GetReason=python35.PyUnicodeTranslateError_GetReason + PyUnicodeTranslateError_GetStart=python35.PyUnicodeTranslateError_GetStart + PyUnicodeTranslateError_SetEnd=python35.PyUnicodeTranslateError_SetEnd + PyUnicodeTranslateError_SetReason=python35.PyUnicodeTranslateError_SetReason + PyUnicodeTranslateError_SetStart=python35.PyUnicodeTranslateError_SetStart + PyUnicode_Append=python35.PyUnicode_Append + PyUnicode_AppendAndDel=python35.PyUnicode_AppendAndDel + PyUnicode_AsASCIIString=python35.PyUnicode_AsASCIIString + PyUnicode_AsCharmapString=python35.PyUnicode_AsCharmapString + PyUnicode_AsDecodedObject=python35.PyUnicode_AsDecodedObject + PyUnicode_AsDecodedUnicode=python35.PyUnicode_AsDecodedUnicode + PyUnicode_AsEncodedObject=python35.PyUnicode_AsEncodedObject + PyUnicode_AsEncodedString=python35.PyUnicode_AsEncodedString + PyUnicode_AsEncodedUnicode=python35.PyUnicode_AsEncodedUnicode + PyUnicode_AsLatin1String=python35.PyUnicode_AsLatin1String + PyUnicode_AsRawUnicodeEscapeString=python35.PyUnicode_AsRawUnicodeEscapeString + PyUnicode_AsUTF16String=python35.PyUnicode_AsUTF16String + PyUnicode_AsUTF32String=python35.PyUnicode_AsUTF32String + PyUnicode_AsUTF8String=python35.PyUnicode_AsUTF8String + PyUnicode_AsUnicodeEscapeString=python35.PyUnicode_AsUnicodeEscapeString + PyUnicode_AsWideChar=python35.PyUnicode_AsWideChar + PyUnicode_ClearFreelist=python35.PyUnicode_ClearFreelist + PyUnicode_Compare=python35.PyUnicode_Compare + PyUnicode_Concat=python35.PyUnicode_Concat + PyUnicode_Contains=python35.PyUnicode_Contains + PyUnicode_Count=python35.PyUnicode_Count + PyUnicode_Decode=python35.PyUnicode_Decode + PyUnicode_DecodeASCII=python35.PyUnicode_DecodeASCII + PyUnicode_DecodeCharmap=python35.PyUnicode_DecodeCharmap + PyUnicode_DecodeFSDefault=python35.PyUnicode_DecodeFSDefault + PyUnicode_DecodeFSDefaultAndSize=python35.PyUnicode_DecodeFSDefaultAndSize + PyUnicode_DecodeLatin1=python35.PyUnicode_DecodeLatin1 + PyUnicode_DecodeRawUnicodeEscape=python35.PyUnicode_DecodeRawUnicodeEscape + PyUnicode_DecodeUTF16=python35.PyUnicode_DecodeUTF16 + PyUnicode_DecodeUTF16Stateful=python35.PyUnicode_DecodeUTF16Stateful + PyUnicode_DecodeUTF32=python35.PyUnicode_DecodeUTF32 + PyUnicode_DecodeUTF32Stateful=python35.PyUnicode_DecodeUTF32Stateful + PyUnicode_DecodeUTF8=python35.PyUnicode_DecodeUTF8 + PyUnicode_DecodeUTF8Stateful=python35.PyUnicode_DecodeUTF8Stateful + PyUnicode_DecodeUnicodeEscape=python35.PyUnicode_DecodeUnicodeEscape + PyUnicode_FSConverter=python35.PyUnicode_FSConverter + PyUnicode_FSDecoder=python35.PyUnicode_FSDecoder + PyUnicode_Find=python35.PyUnicode_Find + PyUnicode_Format=python35.PyUnicode_Format + PyUnicode_FromEncodedObject=python35.PyUnicode_FromEncodedObject + PyUnicode_FromFormat=python35.PyUnicode_FromFormat + PyUnicode_FromFormatV=python35.PyUnicode_FromFormatV + PyUnicode_FromObject=python35.PyUnicode_FromObject + PyUnicode_FromOrdinal=python35.PyUnicode_FromOrdinal + PyUnicode_FromString=python35.PyUnicode_FromString + PyUnicode_FromStringAndSize=python35.PyUnicode_FromStringAndSize + PyUnicode_FromWideChar=python35.PyUnicode_FromWideChar + PyUnicode_GetDefaultEncoding=python35.PyUnicode_GetDefaultEncoding + PyUnicode_GetSize=python35.PyUnicode_GetSize + PyUnicode_IsIdentifier=python35.PyUnicode_IsIdentifier + PyUnicode_Join=python35.PyUnicode_Join + PyUnicode_Partition=python35.PyUnicode_Partition + PyUnicode_RPartition=python35.PyUnicode_RPartition + PyUnicode_RSplit=python35.PyUnicode_RSplit + PyUnicode_Replace=python35.PyUnicode_Replace + PyUnicode_Resize=python35.PyUnicode_Resize + PyUnicode_RichCompare=python35.PyUnicode_RichCompare + PyUnicode_SetDefaultEncoding=python35.PyUnicode_SetDefaultEncoding + PyUnicode_Split=python35.PyUnicode_Split + PyUnicode_Splitlines=python35.PyUnicode_Splitlines + PyUnicode_Tailmatch=python35.PyUnicode_Tailmatch + PyUnicode_Translate=python35.PyUnicode_Translate + PyUnicode_BuildEncodingMap=python35.PyUnicode_BuildEncodingMap + PyUnicode_CompareWithASCIIString=python35.PyUnicode_CompareWithASCIIString + PyUnicode_DecodeUTF7=python35.PyUnicode_DecodeUTF7 + PyUnicode_DecodeUTF7Stateful=python35.PyUnicode_DecodeUTF7Stateful + PyUnicode_EncodeFSDefault=python35.PyUnicode_EncodeFSDefault + PyUnicode_InternFromString=python35.PyUnicode_InternFromString + PyUnicode_InternImmortal=python35.PyUnicode_InternImmortal + PyUnicode_InternInPlace=python35.PyUnicode_InternInPlace + PyUnicode_Type=python35.PyUnicode_Type DATA + PyWeakref_GetObject=python35.PyWeakref_GetObject DATA + PyWeakref_NewProxy=python35.PyWeakref_NewProxy + PyWeakref_NewRef=python35.PyWeakref_NewRef + PyWrapperDescr_Type=python35.PyWrapperDescr_Type DATA + PyWrapper_New=python35.PyWrapper_New + PyZip_Type=python35.PyZip_Type DATA + Py_AddPendingCall=python35.Py_AddPendingCall + Py_AtExit=python35.Py_AtExit + Py_BuildValue=python35.Py_BuildValue + Py_CompileString=python35.Py_CompileString + Py_DecRef=python35.Py_DecRef + Py_EndInterpreter=python35.Py_EndInterpreter + Py_Exit=python35.Py_Exit + Py_FatalError=python35.Py_FatalError + Py_FileSystemDefaultEncoding=python35.Py_FileSystemDefaultEncoding DATA + Py_Finalize=python35.Py_Finalize + Py_GetBuildInfo=python35.Py_GetBuildInfo + Py_GetCompiler=python35.Py_GetCompiler + Py_GetCopyright=python35.Py_GetCopyright + Py_GetExecPrefix=python35.Py_GetExecPrefix + Py_GetPath=python35.Py_GetPath + Py_GetPlatform=python35.Py_GetPlatform + Py_GetPrefix=python35.Py_GetPrefix + Py_GetProgramFullPath=python35.Py_GetProgramFullPath + Py_GetProgramName=python35.Py_GetProgramName + Py_GetPythonHome=python35.Py_GetPythonHome + Py_GetRecursionLimit=python35.Py_GetRecursionLimit + Py_GetVersion=python35.Py_GetVersion + Py_HasFileSystemDefaultEncoding=python35.Py_HasFileSystemDefaultEncoding DATA + Py_IncRef=python35.Py_IncRef + Py_Initialize=python35.Py_Initialize + Py_InitializeEx=python35.Py_InitializeEx + Py_IsInitialized=python35.Py_IsInitialized + Py_Main=python35.Py_Main + Py_MakePendingCalls=python35.Py_MakePendingCalls + Py_NewInterpreter=python35.Py_NewInterpreter + Py_ReprEnter=python35.Py_ReprEnter + Py_ReprLeave=python35.Py_ReprLeave + Py_SetProgramName=python35.Py_SetProgramName + Py_SetPythonHome=python35.Py_SetPythonHome + Py_SetRecursionLimit=python35.Py_SetRecursionLimit + Py_SymtableString=python35.Py_SymtableString + Py_VaBuildValue=python35.Py_VaBuildValue + _PyErr_BadInternalCall=python35._PyErr_BadInternalCall + _PyObject_CallFunction_SizeT=python35._PyObject_CallFunction_SizeT + _PyObject_CallMethod_SizeT=python35._PyObject_CallMethod_SizeT + _PyObject_GC_Malloc=python35._PyObject_GC_Malloc + _PyObject_GC_New=python35._PyObject_GC_New + _PyObject_GC_NewVar=python35._PyObject_GC_NewVar + _PyObject_GC_Resize=python35._PyObject_GC_Resize + _PyObject_New=python35._PyObject_New + _PyObject_NewVar=python35._PyObject_NewVar + _PyState_AddModule=python35._PyState_AddModule + _PyThreadState_Init=python35._PyThreadState_Init + _PyThreadState_Prealloc=python35._PyThreadState_Prealloc + _PyTrash_delete_later=python35._PyTrash_delete_later DATA + _PyTrash_delete_nesting=python35._PyTrash_delete_nesting DATA + _PyTrash_deposit_object=python35._PyTrash_deposit_object + _PyTrash_destroy_chain=python35._PyTrash_destroy_chain + _PyWeakref_CallableProxyType=python35._PyWeakref_CallableProxyType DATA + _PyWeakref_ProxyType=python35._PyWeakref_ProxyType DATA + _PyWeakref_RefType=python35._PyWeakref_RefType DATA + _Py_BuildValue_SizeT=python35._Py_BuildValue_SizeT + _Py_CheckRecursionLimit=python35._Py_CheckRecursionLimit DATA + _Py_CheckRecursiveCall=python35._Py_CheckRecursiveCall + _Py_Dealloc=python35._Py_Dealloc + _Py_EllipsisObject=python35._Py_EllipsisObject DATA + _Py_FalseStruct=python35._Py_FalseStruct DATA + _Py_NoneStruct=python35._Py_NoneStruct DATA + _Py_NotImplementedStruct=python35._Py_NotImplementedStruct DATA + _Py_SwappedOp=python35._Py_SwappedOp DATA + _Py_TrueStruct=python35._Py_TrueStruct DATA + _Py_VaBuildValue_SizeT=python35._Py_VaBuildValue_SizeT + _PyArg_Parse_SizeT=python35._PyArg_Parse_SizeT + _PyArg_ParseTuple_SizeT=python35._PyArg_ParseTuple_SizeT + _PyArg_ParseTupleAndKeywords_SizeT=python35._PyArg_ParseTupleAndKeywords_SizeT + _PyArg_VaParse_SizeT=python35._PyArg_VaParse_SizeT + _PyArg_VaParseTupleAndKeywords_SizeT=python35._PyArg_VaParseTupleAndKeywords_SizeT + _Py_BuildValue_SizeT=python35._Py_BuildValue_SizeT diff --git a/PC/python3.mak b/PC/python3.mak deleted file mode 100644 index fb8e7aac0977..000000000000 --- a/PC/python3.mak +++ /dev/null @@ -1,14 +0,0 @@ -$(OutDir)python3.dll: python3.def $(OutDir)python34stub.lib - cl /LD /Fe$(OutDir)python3.dll python3dll.c python3.def $(OutDir)python34stub.lib - -$(OutDir)python34stub.lib: python34stub.def - lib /def:python34stub.def /out:$(OutDir)python34stub.lib /MACHINE:$(MACHINE) - -clean: - IF EXIST $(OutDir)python3.dll del $(OutDir)python3.dll - IF EXIST $(OutDir)python3.lib del $(OutDir)python3.lib - IF EXIST $(OutDir)python34stub.lib del $(OutDir)python34stub.lib - IF EXIST $(OutDir)python3.exp del $(OutDir)python3.exp - IF EXIST $(OutDir)python34stub.exp del $(OutDir)python34stub.exp - -rebuild: clean $(OutDir)python3.dll diff --git a/PC/python34gen.py b/PC/python34gen.py deleted file mode 100644 index 180ce11fd28b..000000000000 --- a/PC/python34gen.py +++ /dev/null @@ -1,26 +0,0 @@ -# Generate python34stub.def out of python3.def -# The regular import library cannot be used, -# since it doesn't provide the right symbols for -# data forwarding -out = open("python34stub.def", "w") -out.write('LIBRARY "python34"\n') -out.write('EXPORTS\n') - -inp = open("python3.def") -line = inp.readline() -while line.strip().startswith(';'): - line = inp.readline() -line = inp.readline() # LIBRARY -assert line.strip()=='EXPORTS' - -for line in inp: - # SYM1=python34.SYM2[ DATA] - head, tail = line.split('.') - if 'DATA' in tail: - symbol, tail = tail.split(' ') - else: - symbol = tail.strip() - out.write(symbol+'\n') - -inp.close() -out.close() diff --git a/PC/python34stub.def b/PC/python34stub.def deleted file mode 100644 index c0f3b35fe9b0..000000000000 --- a/PC/python34stub.def +++ /dev/null @@ -1,699 +0,0 @@ -LIBRARY "python34" -EXPORTS -PyArg_Parse -PyArg_ParseTuple -PyArg_ParseTupleAndKeywords -PyArg_UnpackTuple -PyArg_VaParse -PyArg_VaParseTupleAndKeywords -PyArg_ValidateKeywordArguments -PyBaseObject_Type -PyBool_FromLong -PyBool_Type -PyByteArrayIter_Type -PyByteArray_AsString -PyByteArray_Concat -PyByteArray_FromObject -PyByteArray_FromStringAndSize -PyByteArray_Resize -PyByteArray_Size -PyByteArray_Type -PyBytesIter_Type -PyBytes_AsString -PyBytes_AsStringAndSize -PyBytes_Concat -PyBytes_ConcatAndDel -PyBytes_DecodeEscape -PyBytes_FromFormat -PyBytes_FromFormatV -PyBytes_FromObject -PyBytes_FromString -PyBytes_FromStringAndSize -PyBytes_Repr -PyBytes_Size -PyBytes_Type -PyCFunction_Call -PyCFunction_ClearFreeList -PyCFunction_GetFlags -PyCFunction_GetFunction -PyCFunction_GetSelf -PyCFunction_New -PyCFunction_NewEx -PyCFunction_Type -PyCallIter_New -PyCallIter_Type -PyCallable_Check -PyCapsule_GetContext -PyCapsule_GetDestructor -PyCapsule_GetName -PyCapsule_GetPointer -PyCapsule_Import -PyCapsule_IsValid -PyCapsule_New -PyCapsule_SetContext -PyCapsule_SetDestructor -PyCapsule_SetName -PyCapsule_SetPointer -PyCapsule_Type -PyClassMethodDescr_Type -PyCodec_BackslashReplaceErrors -PyCodec_Decode -PyCodec_Decoder -PyCodec_Encode -PyCodec_Encoder -PyCodec_IgnoreErrors -PyCodec_IncrementalDecoder -PyCodec_IncrementalEncoder -PyCodec_KnownEncoding -PyCodec_LookupError -PyCodec_Register -PyCodec_RegisterError -PyCodec_ReplaceErrors -PyCodec_StreamReader -PyCodec_StreamWriter -PyCodec_StrictErrors -PyCodec_XMLCharRefReplaceErrors -PyComplex_FromDoubles -PyComplex_ImagAsDouble -PyComplex_RealAsDouble -PyComplex_Type -PyDescr_NewClassMethod -PyDescr_NewGetSet -PyDescr_NewMember -PyDescr_NewMethod -PyDictItems_Type -PyDictIterItem_Type -PyDictIterKey_Type -PyDictIterValue_Type -PyDictKeys_Type -PyDictProxy_New -PyDictProxy_Type -PyDictValues_Type -PyDict_Clear -PyDict_Contains -PyDict_Copy -PyDict_DelItem -PyDict_DelItemString -PyDict_GetItem -PyDict_GetItemString -PyDict_GetItemWithError -PyDict_Items -PyDict_Keys -PyDict_Merge -PyDict_MergeFromSeq2 -PyDict_New -PyDict_Next -PyDict_SetItem -PyDict_SetItemString -PyDict_Size -PyDict_Type -PyDict_Update -PyDict_Values -PyEllipsis_Type -PyEnum_Type -PyErr_BadArgument -PyErr_BadInternalCall -PyErr_CheckSignals -PyErr_Clear -PyErr_Display -PyErr_ExceptionMatches -PyErr_Fetch -PyErr_Format -PyErr_GivenExceptionMatches -PyErr_NewException -PyErr_NewExceptionWithDoc -PyErr_NoMemory -PyErr_NormalizeException -PyErr_Occurred -PyErr_Print -PyErr_PrintEx -PyErr_ProgramText -PyErr_Restore -PyErr_SetFromErrno -PyErr_SetFromErrnoWithFilename -PyErr_SetFromErrnoWithFilenameObject -PyErr_SetInterrupt -PyErr_SetNone -PyErr_SetObject -PyErr_SetString -PyErr_SyntaxLocation -PyErr_WarnEx -PyErr_WarnExplicit -PyErr_WarnFormat -PyErr_WriteUnraisable -PyEval_AcquireLock -PyEval_AcquireThread -PyEval_CallFunction -PyEval_CallMethod -PyEval_CallObjectWithKeywords -PyEval_EvalCode -PyEval_EvalCodeEx -PyEval_EvalFrame -PyEval_EvalFrameEx -PyEval_GetBuiltins -PyEval_GetCallStats -PyEval_GetFrame -PyEval_GetFuncDesc -PyEval_GetFuncName -PyEval_GetGlobals -PyEval_GetLocals -PyEval_InitThreads -PyEval_ReInitThreads -PyEval_ReleaseLock -PyEval_ReleaseThread -PyEval_RestoreThread -PyEval_SaveThread -PyEval_ThreadsInitialized -PyExc_ArithmeticError -PyExc_AssertionError -PyExc_AttributeError -PyExc_BaseException -PyExc_BufferError -PyExc_BytesWarning -PyExc_DeprecationWarning -PyExc_EOFError -PyExc_EnvironmentError -PyExc_Exception -PyExc_FloatingPointError -PyExc_FutureWarning -PyExc_GeneratorExit -PyExc_IOError -PyExc_ImportError -PyExc_ImportWarning -PyExc_IndentationError -PyExc_IndexError -PyExc_KeyError -PyExc_KeyboardInterrupt -PyExc_LookupError -PyExc_MemoryError -PyExc_MemoryErrorInst -PyExc_NameError -PyExc_NotImplementedError -PyExc_OSError -PyExc_OverflowError -PyExc_PendingDeprecationWarning -PyExc_RecursionErrorInst -PyExc_ReferenceError -PyExc_RuntimeError -PyExc_RuntimeWarning -PyExc_StopIteration -PyExc_SyntaxError -PyExc_SyntaxWarning -PyExc_SystemError -PyExc_SystemExit -PyExc_TabError -PyExc_TypeError -PyExc_UnboundLocalError -PyExc_UnicodeDecodeError -PyExc_UnicodeEncodeError -PyExc_UnicodeError -PyExc_UnicodeTranslateError -PyExc_UnicodeWarning -PyExc_UserWarning -PyExc_ValueError -PyExc_Warning -PyExc_ZeroDivisionError -PyException_GetCause -PyException_GetContext -PyException_GetTraceback -PyException_SetCause -PyException_SetContext -PyException_SetTraceback -PyFile_FromFd -PyFile_GetLine -PyFile_WriteObject -PyFile_WriteString -PyFilter_Type -PyFloat_AsDouble -PyFloat_FromDouble -PyFloat_FromString -PyFloat_GetInfo -PyFloat_GetMax -PyFloat_GetMin -PyFloat_Type -PyFrozenSet_New -PyFrozenSet_Type -PyGC_Collect -PyGILState_Ensure -PyGILState_GetThisThreadState -PyGILState_Release -PyGetSetDescr_Type -PyImport_AddModule -PyImport_AppendInittab -PyImport_Cleanup -PyImport_ExecCodeModule -PyImport_ExecCodeModuleEx -PyImport_ExecCodeModuleWithPathnames -PyImport_GetImporter -PyImport_GetMagicNumber -PyImport_GetMagicTag -PyImport_GetModuleDict -PyImport_Import -PyImport_ImportFrozenModule -PyImport_ImportModule -PyImport_ImportModuleLevel -PyImport_ImportModuleNoBlock -PyImport_ReloadModule -PyInterpreterState_Clear -PyInterpreterState_Delete -PyInterpreterState_New -PyIter_Next -PyListIter_Type -PyListRevIter_Type -PyList_Append -PyList_AsTuple -PyList_GetItem -PyList_GetSlice -PyList_Insert -PyList_New -PyList_Reverse -PyList_SetItem -PyList_SetSlice -PyList_Size -PyList_Sort -PyList_Type -PyLongRangeIter_Type -PyLong_AsDouble -PyLong_AsLong -PyLong_AsLongAndOverflow -PyLong_AsLongLong -PyLong_AsLongLongAndOverflow -PyLong_AsSize_t -PyLong_AsSsize_t -PyLong_AsUnsignedLong -PyLong_AsUnsignedLongLong -PyLong_AsUnsignedLongLongMask -PyLong_AsUnsignedLongMask -PyLong_AsVoidPtr -PyLong_FromDouble -PyLong_FromLong -PyLong_FromLongLong -PyLong_FromSize_t -PyLong_FromSsize_t -PyLong_FromString -PyLong_FromUnsignedLong -PyLong_FromUnsignedLongLong -PyLong_FromVoidPtr -PyLong_GetInfo -PyLong_Type -PyMap_Type -PyMapping_Check -PyMapping_GetItemString -PyMapping_HasKey -PyMapping_HasKeyString -PyMapping_Items -PyMapping_Keys -PyMapping_Length -PyMapping_SetItemString -PyMapping_Size -PyMapping_Values -PyMem_Free -PyMem_Malloc -PyMem_Realloc -PyMemberDescr_Type -PyMemoryView_FromObject -PyMemoryView_GetContiguous -PyMemoryView_Type -PyMethodDescr_Type -PyModule_AddIntConstant -PyModule_AddObject -PyModule_AddStringConstant -PyModule_Create2 -PyModule_GetDef -PyModule_GetDict -PyModule_GetFilename -PyModule_GetFilenameObject -PyModule_GetName -PyModule_GetState -PyModule_New -PyModule_Type -PyNullImporter_Type -PyNumber_Absolute -PyNumber_Add -PyNumber_And -PyNumber_AsSsize_t -PyNumber_Check -PyNumber_Divmod -PyNumber_Float -PyNumber_FloorDivide -PyNumber_InPlaceAdd -PyNumber_InPlaceAnd -PyNumber_InPlaceFloorDivide -PyNumber_InPlaceLshift -PyNumber_InPlaceMultiply -PyNumber_InPlaceOr -PyNumber_InPlacePower -PyNumber_InPlaceRemainder -PyNumber_InPlaceRshift -PyNumber_InPlaceSubtract -PyNumber_InPlaceTrueDivide -PyNumber_InPlaceXor -PyNumber_Index -PyNumber_Invert -PyNumber_Long -PyNumber_Lshift -PyNumber_Multiply -PyNumber_Negative -PyNumber_Or -PyNumber_Positive -PyNumber_Power -PyNumber_Remainder -PyNumber_Rshift -PyNumber_Subtract -PyNumber_ToBase -PyNumber_TrueDivide -PyNumber_Xor -PyOS_AfterFork -PyOS_InitInterrupts -PyOS_InputHook -PyOS_InterruptOccurred -PyOS_ReadlineFunctionPointer -PyOS_double_to_string -PyOS_getsig -PyOS_mystricmp -PyOS_mystrnicmp -PyOS_setsig -PyOS_snprintf -PyOS_string_to_double -PyOS_strtol -PyOS_strtoul -PyOS_vsnprintf -PyObject_ASCII -PyObject_AsCharBuffer -PyObject_AsFileDescriptor -PyObject_AsReadBuffer -PyObject_AsWriteBuffer -PyObject_Bytes -PyObject_Call -PyObject_CallFunction -PyObject_CallFunctionObjArgs -PyObject_CallMethod -PyObject_CallMethodObjArgs -PyObject_CallObject -PyObject_CheckReadBuffer -PyObject_ClearWeakRefs -PyObject_DelItem -PyObject_DelItemString -PyObject_Dir -PyObject_Format -PyObject_Free -PyObject_GC_Del -PyObject_GC_Track -PyObject_GC_UnTrack -PyObject_GenericGetAttr -PyObject_GenericSetAttr -PyObject_GetAttr -PyObject_GetAttrString -PyObject_GetItem -PyObject_GetIter -PyObject_HasAttr -PyObject_HasAttrString -PyObject_Hash -PyObject_HashNotImplemented -PyObject_Init -PyObject_InitVar -PyObject_IsInstance -PyObject_IsSubclass -PyObject_IsTrue -PyObject_Length -PyObject_Malloc -PyObject_Not -PyObject_Realloc -PyObject_Repr -PyObject_RichCompare -PyObject_RichCompareBool -PyObject_SelfIter -PyObject_SetAttr -PyObject_SetAttrString -PyObject_SetItem -PyObject_Size -PyObject_Str -PyObject_Type -PyParser_SimpleParseFileFlags -PyParser_SimpleParseStringFlags -PyProperty_Type -PyRangeIter_Type -PyRange_Type -PyReversed_Type -PySeqIter_New -PySeqIter_Type -PySequence_Check -PySequence_Concat -PySequence_Contains -PySequence_Count -PySequence_DelItem -PySequence_DelSlice -PySequence_Fast -PySequence_GetItem -PySequence_GetSlice -PySequence_In -PySequence_InPlaceConcat -PySequence_InPlaceRepeat -PySequence_Index -PySequence_Length -PySequence_List -PySequence_Repeat -PySequence_SetItem -PySequence_SetSlice -PySequence_Size -PySequence_Tuple -PySetIter_Type -PySet_Add -PySet_Clear -PySet_Contains -PySet_Discard -PySet_New -PySet_Pop -PySet_Size -PySet_Type -PySlice_GetIndices -PySlice_GetIndicesEx -PySlice_New -PySlice_Type -PySortWrapper_Type -PyState_FindModule -PyState_AddModule -PyState_RemoveModule -PyStructSequence_GetItem -PyStructSequence_New -PyStructSequence_NewType -PyStructSequence_SetItem -PySuper_Type -PySys_AddWarnOption -PySys_AddWarnOptionUnicode -PySys_FormatStderr -PySys_FormatStdout -PySys_GetObject -PySys_HasWarnOptions -PySys_ResetWarnOptions -PySys_SetArgv -PySys_SetArgvEx -PySys_SetObject -PySys_SetPath -PySys_WriteStderr -PySys_WriteStdout -PyThreadState_Clear -PyThreadState_Delete -PyThreadState_DeleteCurrent -PyThreadState_Get -PyThreadState_GetDict -PyThreadState_New -PyThreadState_SetAsyncExc -PyThreadState_Swap -PyTraceBack_Here -PyTraceBack_Print -PyTraceBack_Type -PyTupleIter_Type -PyTuple_ClearFreeList -PyTuple_GetItem -PyTuple_GetSlice -PyTuple_New -PyTuple_Pack -PyTuple_SetItem -PyTuple_Size -PyTuple_Type -PyType_ClearCache -PyType_FromSpec -PyType_FromSpecWithBases -PyType_GenericAlloc -PyType_GenericNew -PyType_GetFlags -PyType_IsSubtype -PyType_Modified -PyType_Ready -PyType_Type -PyUnicodeDecodeError_Create -PyUnicodeDecodeError_GetEncoding -PyUnicodeDecodeError_GetEnd -PyUnicodeDecodeError_GetObject -PyUnicodeDecodeError_GetReason -PyUnicodeDecodeError_GetStart -PyUnicodeDecodeError_SetEnd -PyUnicodeDecodeError_SetReason -PyUnicodeDecodeError_SetStart -PyUnicodeEncodeError_GetEncoding -PyUnicodeEncodeError_GetEnd -PyUnicodeEncodeError_GetObject -PyUnicodeEncodeError_GetReason -PyUnicodeEncodeError_GetStart -PyUnicodeEncodeError_SetEnd -PyUnicodeEncodeError_SetReason -PyUnicodeEncodeError_SetStart -PyUnicodeIter_Type -PyUnicodeTranslateError_GetEnd -PyUnicodeTranslateError_GetObject -PyUnicodeTranslateError_GetReason -PyUnicodeTranslateError_GetStart -PyUnicodeTranslateError_SetEnd -PyUnicodeTranslateError_SetReason -PyUnicodeTranslateError_SetStart -PyUnicodeUCS2_Append -PyUnicodeUCS2_AppendAndDel -PyUnicodeUCS2_AsASCIIString -PyUnicodeUCS2_AsCharmapString -PyUnicodeUCS2_AsDecodedObject -PyUnicodeUCS2_AsDecodedUnicode -PyUnicodeUCS2_AsEncodedObject -PyUnicodeUCS2_AsEncodedString -PyUnicodeUCS2_AsEncodedUnicode -PyUnicodeUCS2_AsLatin1String -PyUnicodeUCS2_AsRawUnicodeEscapeString -PyUnicodeUCS2_AsUTF16String -PyUnicodeUCS2_AsUTF32String -PyUnicodeUCS2_AsUTF8String -PyUnicodeUCS2_AsUnicodeEscapeString -PyUnicodeUCS2_AsWideChar -PyUnicodeUCS2_ClearFreelist -PyUnicodeUCS2_Compare -PyUnicodeUCS2_Concat -PyUnicodeUCS2_Contains -PyUnicodeUCS2_Count -PyUnicodeUCS2_Decode -PyUnicodeUCS2_DecodeASCII -PyUnicodeUCS2_DecodeCharmap -PyUnicodeUCS2_DecodeFSDefault -PyUnicodeUCS2_DecodeFSDefaultAndSize -PyUnicodeUCS2_DecodeLatin1 -PyUnicodeUCS2_DecodeRawUnicodeEscape -PyUnicodeUCS2_DecodeUTF16 -PyUnicodeUCS2_DecodeUTF16Stateful -PyUnicodeUCS2_DecodeUTF32 -PyUnicodeUCS2_DecodeUTF32Stateful -PyUnicodeUCS2_DecodeUTF8 -PyUnicodeUCS2_DecodeUTF8Stateful -PyUnicodeUCS2_DecodeUnicodeEscape -PyUnicodeUCS2_FSConverter -PyUnicodeUCS2_FSDecoder -PyUnicodeUCS2_Find -PyUnicodeUCS2_Format -PyUnicodeUCS2_FromEncodedObject -PyUnicodeUCS2_FromFormat -PyUnicodeUCS2_FromFormatV -PyUnicodeUCS2_FromObject -PyUnicodeUCS2_FromOrdinal -PyUnicodeUCS2_FromString -PyUnicodeUCS2_FromStringAndSize -PyUnicodeUCS2_FromWideChar -PyUnicodeUCS2_GetDefaultEncoding -PyUnicodeUCS2_GetSize -PyUnicodeUCS2_IsIdentifier -PyUnicodeUCS2_Join -PyUnicodeUCS2_Partition -PyUnicodeUCS2_RPartition -PyUnicodeUCS2_RSplit -PyUnicodeUCS2_Replace -PyUnicodeUCS2_Resize -PyUnicodeUCS2_RichCompare -PyUnicodeUCS2_SetDefaultEncoding -PyUnicodeUCS2_Split -PyUnicodeUCS2_Splitlines -PyUnicodeUCS2_Tailmatch -PyUnicodeUCS2_Translate -PyUnicode_BuildEncodingMap -PyUnicode_CompareWithASCIIString -PyUnicode_DecodeUTF7 -PyUnicode_DecodeUTF7Stateful -PyUnicode_EncodeFSDefault -PyUnicode_InternFromString -PyUnicode_InternImmortal -PyUnicode_InternInPlace -PyUnicode_Type -PyWeakref_GetObject -PyWeakref_NewProxy -PyWeakref_NewRef -PyWrapperDescr_Type -PyWrapper_New -PyZip_Type -Py_AddPendingCall -Py_AtExit -Py_BuildValue -Py_CompileString -Py_DecRef -Py_EndInterpreter -Py_Exit -Py_FatalError -Py_FileSystemDefaultEncoding -Py_Finalize -Py_GetBuildInfo -Py_GetCompiler -Py_GetCopyright -Py_GetExecPrefix -Py_GetPath -Py_GetPlatform -Py_GetPrefix -Py_GetProgramFullPath -Py_GetProgramName -Py_GetPythonHome -Py_GetRecursionLimit -Py_GetVersion -Py_HasFileSystemDefaultEncoding -Py_IncRef -Py_Initialize -Py_InitializeEx -Py_IsInitialized -Py_Main -Py_MakePendingCalls -Py_NewInterpreter -Py_ReprEnter -Py_ReprLeave -Py_SetProgramName -Py_SetPythonHome -Py_SetRecursionLimit -Py_SymtableString -Py_VaBuildValue -_PyErr_BadInternalCall -_PyObject_CallFunction_SizeT -_PyObject_CallMethod_SizeT -_PyObject_GC_Malloc -_PyObject_GC_New -_PyObject_GC_NewVar -_PyObject_GC_Resize -_PyObject_New -_PyObject_NewVar -_PyState_AddModule -_PyThreadState_Init -_PyThreadState_Prealloc -_PyTrash_delete_later -_PyTrash_delete_nesting -_PyTrash_deposit_object -_PyTrash_destroy_chain -_PyWeakref_CallableProxyType -_PyWeakref_ProxyType -_PyWeakref_RefType -_Py_BuildValue_SizeT -_Py_CheckRecursionLimit -_Py_CheckRecursiveCall -_Py_Dealloc -_Py_EllipsisObject -_Py_FalseStruct -_Py_NoneStruct -_Py_NotImplementedStruct -_Py_SwappedOp -_Py_TrueStruct -_Py_VaBuildValue_SizeT -_PyArg_Parse_SizeT -_PyArg_ParseTuple_SizeT -_PyArg_ParseTupleAndKeywords_SizeT -_PyArg_VaParse_SizeT -_PyArg_VaParseTupleAndKeywords_SizeT -_Py_BuildValue_SizeT diff --git a/PC/python_exe.rc b/PC/python_exe.rc index 14e2574377b7..91785a1e0640 100644 --- a/PC/python_exe.rc +++ b/PC/python_exe.rc @@ -1 +1,49 @@ -1 ICON DISCARDABLE "pycon.ico" +// Resource script for Python console EXEs. + +#include "python_ver_rc.h" + +// Include the manifest file that indicates we support all +// current versions of Windows. +#include +1 RT_MANIFEST "python.manifest" + +1 ICON DISCARDABLE "pycon.ico" + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION PYVERSION64 + PRODUCTVERSION PYVERSION64 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS VS_FF_DEBUG +#else + FILEFLAGS 0x0L +#endif + FILEOS VOS__WINDOWS32 + FILETYPE VFT_APP + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000004b0" + BEGIN + VALUE "CompanyName", PYTHON_COMPANY "\0" + VALUE "FileDescription", "Python\0" + VALUE "FileVersion", PYTHON_VERSION + VALUE "InternalName", "Python Console\0" + VALUE "LegalCopyright", PYTHON_COPYRIGHT "\0" + VALUE "OriginalFilename", "python" PYTHON_DEBUG_EXT ".exe\0" + VALUE "ProductName", "Python\0" + VALUE "ProductVersion", PYTHON_VERSION + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1200 + END +END diff --git a/PC/python_nt.rc b/PC/python_nt.rc index 199533cad9d7..fac6105d8a77 100644 --- a/PC/python_nt.rc +++ b/PC/python_nt.rc @@ -1,33 +1,11 @@ // Resource script for Python core DLL. -// Currently only holds version information. -// -#include "winver.h" - -#define MS_WINDOWS -#include "modsupport.h" -#include "patchlevel.h" -#ifdef _DEBUG -# include "pythonnt_rc_d.h" -#else -# include "pythonnt_rc.h" -#endif -/* e.g., 3.3.0a1 - * PY_VERSION comes from patchevel.h - */ -#define PYTHON_VERSION PY_VERSION "\0" +#include "python_ver_rc.h" -/* 64-bit version number as comma-separated list of 4 16-bit ints */ -#if PY_MICRO_VERSION > 64 -# error "PY_MICRO_VERSION > 64" -#endif -#if PY_RELEASE_LEVEL > 99 -# error "PY_RELEASE_LEVEL > 99" -#endif -#if PY_RELEASE_SERIAL > 9 -# error "PY_RELEASE_SERIAL > 9" -#endif -#define PYVERSION64 PY_MAJOR_VERSION, PY_MINOR_VERSION, FIELD3, PYTHON_API_VERSION +// Include the manifest file that indicates we support all +// current versions of Windows. +#include +2 RT_MANIFEST "python.manifest" // String Tables STRINGTABLE DISCARDABLE @@ -45,23 +23,23 @@ VS_VERSION_INFO VERSIONINFO PRODUCTVERSION PYVERSION64 FILEFLAGSMASK 0x3fL #ifdef _DEBUG - FILEFLAGS 0x1L + FILEFLAGS VS_FF_DEBUG #else FILEFLAGS 0x0L #endif - FILEOS 0x40004L - FILETYPE 0x1L + FILEOS VOS__WINDOWS32 + FILETYPE VFT_DLL FILESUBTYPE 0x0L BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "000004b0" BEGIN - VALUE "CompanyName", "Python Software Foundation\0" + VALUE "CompanyName", PYTHON_COMPANY "\0" VALUE "FileDescription", "Python Core\0" VALUE "FileVersion", PYTHON_VERSION VALUE "InternalName", "Python DLL\0" - VALUE "LegalCopyright", "Copyright © 2001-2013 Python Software Foundation. Copyright © 2000 BeOpen.com. Copyright © 1995-2001 CNRI. Copyright © 1991-1995 SMC.\0" + VALUE "LegalCopyright", PYTHON_COPYRIGHT "\0" VALUE "OriginalFilename", PYTHON_DLL_NAME "\0" VALUE "ProductName", "Python\0" VALUE "ProductVersion", PYTHON_VERSION diff --git a/PC/python_ver_rc.h b/PC/python_ver_rc.h new file mode 100644 index 000000000000..827e9be52831 --- /dev/null +++ b/PC/python_ver_rc.h @@ -0,0 +1,35 @@ +// Resource script for Python core DLL. +// Currently only holds version information. +// +#include "winver.h" + +#define PYTHON_COMPANY "Python Software Foundation" +#define PYTHON_COPYRIGHT "Copyright \xA9 2001-2015 Python Software Foundation. Copyright \xA9 2000 BeOpen.com. Copyright \xA9 1995-2001 CNRI. Copyright \xA9 1991-1995 SMC." + +#define MS_WINDOWS +#include "modsupport.h" +#include "patchlevel.h" +#ifdef _DEBUG +# include "pythonnt_rc_d.h" +# define PYTHON_DEBUG_EXT "_d" +#else +# include "pythonnt_rc.h" +# define PYTHON_DEBUG_EXT +#endif + +/* e.g., 3.3.0a1 + * PY_VERSION comes from patchlevel.h + */ +#define PYTHON_VERSION PY_VERSION "\0" + +/* 64-bit version number as comma-separated list of 4 16-bit ints */ +#if PY_MICRO_VERSION > 64 +# error "PY_MICRO_VERSION > 64" +#endif +#if PY_RELEASE_LEVEL > 99 +# error "PY_RELEASE_LEVEL > 99" +#endif +#if PY_RELEASE_SERIAL > 9 +# error "PY_RELEASE_SERIAL > 9" +#endif +#define PYVERSION64 PY_MAJOR_VERSION, PY_MINOR_VERSION, FIELD3, PYTHON_API_VERSION diff --git a/PC/readme.txt b/PC/readme.txt index 60f231e513ef..8639dc33d9ab 100644 --- a/PC/readme.txt +++ b/PC/readme.txt @@ -74,11 +74,6 @@ dllbase_nt.txt A (manually maintained) list of base addresses for example_nt A subdirectory showing how to build an extension as a DLL. -Legacy support for older versions of Visual Studio -================================================== -The subdirectories VC6, VS7.1 and VS8.0 contain legacy support older -versions of Microsoft Visual Studio. See PCbuild/readme.txt. - Note for Windows 3.x and DOS users ================================== diff --git a/PC/winreg.c b/PC/winreg.c index 563a3ebcf59a..19d5a7039187 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -871,8 +871,10 @@ Py2Reg(PyObject *value, DWORD typ, BYTE **retDataBuf, DWORD *retDataSize) /* ALSO handle ALL unknown data types here. Even if we can't support it natively, we should handle the bits. */ default: - if (value == Py_None) + if (value == Py_None) { *retDataSize = 0; + *retDataBuf = NULL; + } else { Py_buffer view; @@ -937,14 +939,16 @@ Reg2Py(BYTE *retDataBuf, DWORD retDataSize, DWORD typ) wchar_t *data = (wchar_t *)retDataBuf; int len = retDataSize / 2; int s = countStrings(data, len); - wchar_t **str = (wchar_t **)PyMem_Malloc(sizeof(wchar_t *)*s); + wchar_t **str = PyMem_New(wchar_t *, s); if (str == NULL) return PyErr_NoMemory(); fixupMultiSZ(str, data, len); obData = PyList_New(s); - if (obData == NULL) + if (obData == NULL) { + PyMem_Free(str); return NULL; + } for (index = 0; index < s; index++) { size_t len = wcslen(str[index]); @@ -952,6 +956,7 @@ Reg2Py(BYTE *retDataBuf, DWORD retDataSize, DWORD typ) PyErr_SetString(PyExc_OverflowError, "registry string is too long for a Python string"); Py_DECREF(obData); + PyMem_Free(str); return NULL; } PyList_SetItem(obData, @@ -1201,7 +1206,7 @@ PyEnumValue(PyObject *self, PyObject *args) ++retDataSize; bufDataSize = retDataSize; bufValueSize = retValueSize; - retValueBuf = (wchar_t *)PyMem_Malloc(sizeof(wchar_t) * retValueSize); + retValueBuf = PyMem_New(wchar_t, retValueSize); if (retValueBuf == NULL) return PyErr_NoMemory(); retDataBuf = (BYTE *)PyMem_Malloc(retDataSize); @@ -1272,7 +1277,7 @@ PyExpandEnvironmentStrings(PyObject *self, PyObject *args) return PyErr_SetFromWindowsErrWithFunction(retValueSize, "ExpandEnvironmentStrings"); } - retValue = (wchar_t *)PyMem_Malloc(retValueSize * sizeof(wchar_t)); + retValue = PyMem_New(wchar_t, retValueSize); if (retValue == NULL) { return PyErr_NoMemory(); } diff --git a/PCbuild/_bz2.vcxproj b/PCbuild/_bz2.vcxproj index 9387e54b3a8e..64c3dcde14fa 100644 --- a/PCbuild/_bz2.vcxproj +++ b/PCbuild/_bz2.vcxproj @@ -39,200 +39,34 @@ bz2 Win32Proj + - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - + DynamicLibrary NotSet + + + .pyd + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - $(bz2Dir);%(AdditionalIncludeDirectories) - WIN32;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) - - - 0x1D170000 - - - - - X64 - - - $(bz2Dir);%(AdditionalIncludeDirectories) - WIN32;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) - - - 0x1D170000 - - - - - $(bz2Dir);%(AdditionalIncludeDirectories) - WIN32;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) - - - 0x1D170000 - - - - - X64 - - - $(bz2Dir);%(AdditionalIncludeDirectories) - WIN32;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) - - - 0x1D170000 - - - - - $(bz2Dir);%(AdditionalIncludeDirectories) - WIN32;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) - - - 0x1D170000 - - - - - X64 - - - $(bz2Dir);%(AdditionalIncludeDirectories) - WIN32;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) - - - 0x1D170000 - MachineX64 - - - - - $(bz2Dir);%(AdditionalIncludeDirectories) - WIN32;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) - - - 0x1D170000 - - - - - X64 - + $(bz2Dir);%(AdditionalIncludeDirectories) WIN32;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) 0x1D170000 - MachineX64 diff --git a/PCbuild/_ctypes.vcxproj b/PCbuild/_ctypes.vcxproj index 202cb1f42bbb..68b8e2971d1b 100644 --- a/PCbuild/_ctypes.vcxproj +++ b/PCbuild/_ctypes.vcxproj @@ -39,204 +39,33 @@ _ctypes Win32Proj + - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - + DynamicLibrary NotSet + + .pyd + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + <_ProjectFileVersion>10.0.40219.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - + ..\Modules\_ctypes\libffi_msvc;%(AdditionalIncludeDirectories) 0x1D1A0000 - - - - - X64 - - - ..\Modules\_ctypes\libffi_msvc;%(AdditionalIncludeDirectories) - - - 0x1D1A0000 - - - - - ..\Modules\_ctypes\libffi_msvc;%(AdditionalIncludeDirectories) - - - /EXPORT:DllGetClassObject,PRIVATE /EXPORT:DllCanUnloadNow,PRIVATE %(AdditionalOptions) - NotSet - 0x1D1A0000 - - - - - X64 - - - ..\Modules\_ctypes\libffi_msvc;%(AdditionalIncludeDirectories) - - /EXPORT:DllGetClassObject,PRIVATE /EXPORT:DllCanUnloadNow,PRIVATE %(AdditionalOptions) - NotSet - 0x1D1A0000 - - - - - ..\Modules\_ctypes\libffi_msvc;%(AdditionalIncludeDirectories) - - - /EXPORT:DllGetClassObject,PRIVATE /EXPORT:DllCanUnloadNow,PRIVATE %(AdditionalOptions) - NotSet - 0x1D1A0000 - - - - - X64 - - - ..\Modules\_ctypes\libffi_msvc;%(AdditionalIncludeDirectories) - - - /EXPORT:DllGetClassObject,PRIVATE /EXPORT:DllCanUnloadNow,PRIVATE %(AdditionalOptions) - NotSet - 0x1D1A0000 - MachineX64 - - - - - ..\Modules\_ctypes\libffi_msvc;%(AdditionalIncludeDirectories) - - - /EXPORT:DllGetClassObject,PRIVATE /EXPORT:DllCanUnloadNow,PRIVATE %(AdditionalOptions) - NotSet - 0x1D1A0000 - - - - - X64 - - - ..\Modules\_ctypes\libffi_msvc;%(AdditionalIncludeDirectories) - - - /EXPORT:DllGetClassObject,PRIVATE /EXPORT:DllCanUnloadNow,PRIVATE %(AdditionalOptions) - NotSet - 0x1D1A0000 - MachineX64 @@ -257,30 +86,14 @@ - true - true - true - true + true - true - ml64 /nologo /c /Zi /Fo "$(IntDir)win64.obj" "%(FullPath)" - - $(IntDir)win64.obj;%(Outputs) - true - ml64 /nologo /c /Fo "$(IntDir)win64.obj" "%(FullPath)" - - $(IntDir)win64.obj;%(Outputs) - true - ml64 /nologo /c /Fo "$(IntDir)win64.obj" "%(FullPath)" - - $(IntDir)win64.obj;%(Outputs) - true - ml64 /nologo /c /Fo "$(IntDir)win64.obj" "%(FullPath)" - - $(IntDir)win64.obj;%(Outputs) + true + ml64 /nologo /c /Zi /Fo "$(IntDir)win64.obj" "%(FullPath)" + $(IntDir)win64.obj;%(Outputs) diff --git a/PCbuild/_ctypes_test.vcxproj b/PCbuild/_ctypes_test.vcxproj index 35e299b8867a..c1260b53f3ec 100644 --- a/PCbuild/_ctypes_test.vcxproj +++ b/PCbuild/_ctypes_test.vcxproj @@ -38,143 +38,28 @@ {9EC7190A-249F-4180-A900-548FDCF3055F} _ctypes_test Win32Proj + false + - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - + DynamicLibrary NotSet + + .pyd + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - + <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - X64 - - - - - X64 - - - - - X64 - - - MachineX64 - - - - - X64 - - - MachineX64 - - diff --git a/PCbuild/_decimal.vcxproj b/PCbuild/_decimal.vcxproj index 98ba81db234a..943bfb099034 100644 --- a/PCbuild/_decimal.vcxproj +++ b/PCbuild/_decimal.vcxproj @@ -39,206 +39,35 @@ _decimal Win32Proj + - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - + DynamicLibrary NotSet + + .pyd + - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - + <_ProjectFileVersion>10.0.40219.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - /D_CRT_SECURE_NO_WARNINGS /DCONFIG_32 /DPPRO /DMASM %(AdditionalOptions) - ..\Modules\_decimal;..\Modules\_decimal\libmpdec;%(AdditionalIncludeDirectories) - - - 0x1D1A0000 - - - - - X64 - - - /D_CRT_SECURE_NO_WARNINGS /DCONFIG_64 /DMASM %(AdditionalOptions) - ..\Modules\_decimal;..\Modules\_decimal\libmpdec;%(AdditionalIncludeDirectories) - - - 0x1D1A0000 - - - - - /D_CRT_SECURE_NO_WARNINGS /DCONFIG_32 /DPPRO /DMASM %(AdditionalOptions) - ..\Modules\_decimal;..\Modules\_decimal\libmpdec;%(AdditionalIncludeDirectories) - - - NotSet - 0x1D1A0000 - - - - - X64 - - - /D_CRT_SECURE_NO_WARNINGS /DCONFIG_64 /DMASM %(AdditionalOptions) - ..\Modules\_decimal;..\Modules\_decimal\libmpdec;..\Include;..\PC;%(AdditionalIncludeDirectories) - - - NotSet - 0x1D1A0000 - - - - - /D_CRT_SECURE_NO_WARNINGS /DCONFIG_32 /DPPRO /DMASM %(AdditionalOptions) - ..\Modules\_decimal;..\Modules\_decimal\libmpdec;%(AdditionalIncludeDirectories) - - - NotSet - 0x1D1A0000 - - - - - X64 - - - /D_CRT_SECURE_NO_WARNINGS /DCONFIG_64 /DMASM %(AdditionalOptions) - ..\Modules\_decimal;..\Modules\_decimal\libmpdec;%(AdditionalIncludeDirectories) - - - NotSet - 0x1D1A0000 - MachineX64 - - - - - /D_CRT_SECURE_NO_WARNINGS /DCONFIG_32 /DPPRO /DMASM %(AdditionalOptions) - ..\Modules\_decimal;..\Modules\_decimal\libmpdec;%(AdditionalIncludeDirectories) - - - NotSet - 0x1D1A0000 - - - - - X64 - + - /D_CRT_SECURE_NO_WARNINGS /DCONFIG_64 /DMASM %(AdditionalOptions) + _CRT_SECURE_NO_WARNINGS;MASM;%(PreprocessorDefinitions) + CONFIG_32;PPRO;%(PreprocessorDefinitions) + CONFIG_64;%(PreprocessorDefinitions) ..\Modules\_decimal;..\Modules\_decimal\libmpdec;%(AdditionalIncludeDirectories) - NotSet 0x1D1A0000 - MachineX64 @@ -279,22 +108,9 @@ - true - ml64 /nologo /c /Zi /Fo "$(IntDir)vcdiv64.obj" "%(FullPath)" - - $(IntDir)vcdiv64.obj;%(Outputs) - true - ml64 /nologo /c /Fo "$(IntDir)vcdiv64.obj" "%(FullPath)" - - $(IntDir)vcdiv64.obj;%(Outputs) - true - ml64 /nologo /c /Fo "$(IntDir)vcdiv64.obj" "%(FullPath)" - - $(IntDir)vcdiv64.obj;%(Outputs) - true - ml64 /nologo /c /Zi /Fo "$(IntDir)vcdiv64.obj" "%(FullPath)" - - $(IntDir)vcdiv64.obj;%(Outputs) + true + ml64 /nologo /c /Zi /Fo "$(IntDir)vcdiv64.obj" "%(FullPath)" + $(IntDir)vcdiv64.obj;%(Outputs) diff --git a/PCbuild/_elementtree.vcxproj b/PCbuild/_elementtree.vcxproj index 7802ab30ae22..414bd8bebb82 100644 --- a/PCbuild/_elementtree.vcxproj +++ b/PCbuild/_elementtree.vcxproj @@ -39,200 +39,33 @@ _elementtree Win32Proj + - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - + DynamicLibrary NotSet + + .pyd + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - ..\Modules\expat;%(AdditionalIncludeDirectories) - XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;USE_PYEXPAT_CAPI;XML_STATIC;HAVE_MEMMOVE;%(PreprocessorDefinitions) - - - 0x1D100000 - - - - - X64 - - - ..\Modules\expat;%(AdditionalIncludeDirectories) - XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;USE_PYEXPAT_CAPI;XML_STATIC;HAVE_MEMMOVE;%(PreprocessorDefinitions) - - - 0x1D100000 - - - - - ..\Modules\expat;%(AdditionalIncludeDirectories) - XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;USE_PYEXPAT_CAPI;XML_STATIC;HAVE_MEMMOVE;%(PreprocessorDefinitions) - - - 0x1D100000 - - - - - X64 - - - ..\Modules\expat;%(AdditionalIncludeDirectories) - XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;USE_PYEXPAT_CAPI;XML_STATIC;HAVE_MEMMOVE;%(PreprocessorDefinitions) - - - 0x1D100000 - - - - - ..\Modules\expat;%(AdditionalIncludeDirectories) - XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;USE_PYEXPAT_CAPI;XML_STATIC;HAVE_MEMMOVE;%(PreprocessorDefinitions) - - - 0x1D100000 - - - - - X64 - - - ..\Modules\expat;%(AdditionalIncludeDirectories) - XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;USE_PYEXPAT_CAPI;XML_STATIC;HAVE_MEMMOVE;%(PreprocessorDefinitions) - - - 0x1D100000 - MachineX64 - - - - - ..\Modules\expat;%(AdditionalIncludeDirectories) - XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;USE_PYEXPAT_CAPI;XML_STATIC;HAVE_MEMMOVE;%(PreprocessorDefinitions) - - - 0x1D100000 - - - - - X64 - + ..\Modules\expat;%(AdditionalIncludeDirectories) XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;USE_PYEXPAT_CAPI;XML_STATIC;HAVE_MEMMOVE;%(PreprocessorDefinitions) 0x1D100000 - MachineX64 diff --git a/PCbuild/_freeze_importlib.vcxproj b/PCbuild/_freeze_importlib.vcxproj index 55197af8b281..f7714c003af9 100644 --- a/PCbuild/_freeze_importlib.vcxproj +++ b/PCbuild/_freeze_importlib.vcxproj @@ -9,6 +9,22 @@ Debug x64 + + PGInstrument + Win32 + + + PGInstrument + x64 + + + PGUpdate + Win32 + + + PGUpdate + x64 + Release Win32 @@ -22,152 +38,32 @@ {19C0C13F-47CA-4432-AFF3-799A296A4DDC} Win32Proj _freeze_importlib + false + - - Application - true - Unicode - - - Application - true - Unicode - - - Application - false - true - Unicode - - + Application - false - true Unicode - - - - - - - - - - - - - - - - + - - - true - - - true - - - false - - - false - - - - - - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - - - Console - true - - - $(TargetPath) ..\Lib\importlib\_bootstrap.py ..\Python\importlib.h - - - creating importlib.h - - - - - - - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - - - Console - true - - - $(TargetPath) ..\Lib\importlib\_bootstrap.py ..\Python\importlib.h - - - creating importlib.h - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - - - Console - true - true - true - - - $(TargetPath) ..\Lib\importlib\_bootstrap.py ..\Python\importlib.h - - - creating importlib.h - - - + - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _CONSOLE;%(PreprocessorDefinitions) Console - true - true - true - - $(TargetPath) ..\Lib\importlib\_bootstrap.py ..\Python\importlib.h - - - creating importlib.h - - + @@ -185,4 +81,26 @@ - \ No newline at end of file + + + + + <_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(` `, ` `)) + + + + + + + + + + + + + diff --git a/PCbuild/_freeze_importlib.vcxproj.filters b/PCbuild/_freeze_importlib.vcxproj.filters index 50ec1933f38b..ccad053a9f53 100644 --- a/PCbuild/_freeze_importlib.vcxproj.filters +++ b/PCbuild/_freeze_importlib.vcxproj.filters @@ -15,7 +15,7 @@ - + Source Files @@ -24,4 +24,4 @@ Source Files - \ No newline at end of file + diff --git a/PCbuild/_hashlib.vcxproj b/PCbuild/_hashlib.vcxproj index 52433ed6969e..d82b266902a9 100644 --- a/PCbuild/_hashlib.vcxproj +++ b/PCbuild/_hashlib.vcxproj @@ -39,239 +39,47 @@ _hashlib Win32Proj + - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - + DynamicLibrary NotSet + + .pyd + - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - + <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - $(opensslDir)\inc32;%(AdditionalIncludeDirectories) - - - - - - - ws2_32.lib;$(opensslDir)\out32\libeay32.lib;$(opensslDir)\out32\ssleay32.lib;%(AdditionalDependencies) - - - - - X64 - - - $(opensslDir)\inc64;%(AdditionalIncludeDirectories) - - - - - - - ws2_32.lib;$(opensslDir)\out64\libeay32.lib;$(opensslDir)\out64\ssleay32.lib;%(AdditionalDependencies) - - - - - $(opensslDir)\inc32;%(AdditionalIncludeDirectories) - - - - - - - ws2_32.lib;$(opensslDir)\out32\libeay32.lib;$(opensslDir)\out32\ssleay32.lib;%(AdditionalDependencies) - - - - - X64 - - - $(opensslDir)\inc64;%(AdditionalIncludeDirectories) - - - - - - - ws2_32.lib;$(opensslDir)\out64\libeay32.lib;$(opensslDir)\out64\ssleay32.lib;%(AdditionalDependencies) - - - + - $(opensslDir)\inc32;%(AdditionalIncludeDirectories) + $(opensslDir)include;%(AdditionalIncludeDirectories) - - - - - ws2_32.lib;$(opensslDir)\out32\libeay32.lib;$(opensslDir)\out32\ssleay32.lib;%(AdditionalDependencies) - - - - - X64 - - - $(opensslDir)\inc64;%(AdditionalIncludeDirectories) - - - - - - - ws2_32.lib;$(opensslDir)\out64\libeay32.lib;$(opensslDir)\out64\ssleay32.lib;%(AdditionalDependencies) - MachineX64 - - - - - $(opensslDir)\inc32;%(AdditionalIncludeDirectories) - - - - - - - ws2_32.lib;$(opensslDir)\out32\libeay32.lib;$(opensslDir)\out32\ssleay32.lib;%(AdditionalDependencies) - - - - - X64 - - - $(opensslDir)\inc64;%(AdditionalIncludeDirectories) - - - - - - - ws2_32.lib;$(opensslDir)\out64\libeay32.lib;$(opensslDir)\out64\ssleay32.lib;%(AdditionalDependencies) - MachineX64 + ws2_32.lib;$(OutDir)libeay$(PyDebugExt).lib;$(OutDir)ssleay$(PyDebugExt).lib;%(AdditionalDependencies) - - {b11d750f-cd1f-4a96-85ce-e69a5c5259f9} - false - {cf7ac3d1-e2df-41d2-bea6-1e2556cdea26} false - + + {10615b24-73bf-4efa-93aa-236916321317} + false + + {e5b04cc0-eb4c-42ab-b4dc-18ef95f864b0} false diff --git a/PCbuild/_lzma.vcxproj b/PCbuild/_lzma.vcxproj index ac25c804adde..af50494ebde6 100644 --- a/PCbuild/_lzma.vcxproj +++ b/PCbuild/_lzma.vcxproj @@ -39,200 +39,35 @@ lzma Win32Proj + - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - + DynamicLibrary NotSet + + .pyd + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - + <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - $(lzmaDir)\include;%(AdditionalIncludeDirectories) - WIN32;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;LZMA_API_STATIC;%(PreprocessorDefinitions) - - - $(lzmaDir)\bin_i486\liblzma.a;%(AdditionalDependencies) - - - - - X64 - - - $(lzmaDir)\include;%(AdditionalIncludeDirectories) - WIN32;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;LZMA_API_STATIC;%(PreprocessorDefinitions) - - - $(lzmaDir)\bin_x86-64\liblzma.a;%(AdditionalDependencies) - - - - - $(lzmaDir)\include;%(AdditionalIncludeDirectories) - WIN32;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;LZMA_API_STATIC;%(PreprocessorDefinitions) - - - $(lzmaDir)\bin_i486\liblzma.a;%(AdditionalDependencies) - - - - - X64 - - - $(lzmaDir)\include;%(AdditionalIncludeDirectories) - WIN32;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;LZMA_API_STATIC;%(PreprocessorDefinitions) - - - $(lzmaDir)\bin_x86-64\liblzma.a;%(AdditionalDependencies) - - - - - $(lzmaDir)\include;%(AdditionalIncludeDirectories) - WIN32;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;LZMA_API_STATIC;%(PreprocessorDefinitions) - - - $(lzmaDir)\bin_i486\liblzma.a;%(AdditionalDependencies) - - - - - X64 - - - $(lzmaDir)\include;%(AdditionalIncludeDirectories) - WIN32;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;LZMA_API_STATIC;%(PreprocessorDefinitions) - - - $(lzmaDir)\bin_x86-64\liblzma.a;%(AdditionalDependencies) - MachineX64 - - - - - $(lzmaDir)\include;%(AdditionalIncludeDirectories) - WIN32;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;LZMA_API_STATIC;%(PreprocessorDefinitions) - - - $(lzmaDir)\bin_i486\liblzma.a;%(AdditionalDependencies) - - - - - X64 - + - $(lzmaDir)\include;%(AdditionalIncludeDirectories) + $(lzmaDir)include;%(AdditionalIncludeDirectories) WIN32;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;LZMA_API_STATIC;%(PreprocessorDefinitions) - $(lzmaDir)\bin_x86-64\liblzma.a;%(AdditionalDependencies) - MachineX64 + $(lzmaDir)\bin_i486\liblzma.a;%(AdditionalDependencies) + $(lzmaDir)\bin_x86-64\liblzma.a;%(AdditionalDependencies) + false diff --git a/PCbuild/_msi.vcxproj b/PCbuild/_msi.vcxproj index 1323d169df34..f5ba7bff7627 100644 --- a/PCbuild/_msi.vcxproj +++ b/PCbuild/_msi.vcxproj @@ -39,176 +39,30 @@ _msi Win32Proj + - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - + DynamicLibrary NotSet + + .pyd + - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - + <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - fci.lib;msi.lib;rpcrt4.lib;%(AdditionalDependencies) - 0x1D160000 - - - - - X64 - - - fci.lib;msi.lib;rpcrt4.lib;%(AdditionalDependencies) - 0x1D160000 - - - - - fci.lib;msi.lib;rpcrt4.lib;%(AdditionalDependencies) - 0x1D160000 - - - - - X64 - - - fci.lib;msi.lib;rpcrt4.lib;%(AdditionalDependencies) - 0x1D160000 - - - - - fci.lib;msi.lib;rpcrt4.lib;%(AdditionalDependencies) - 0x1D160000 - - - - - X64 - - - fci.lib;msi.lib;rpcrt4.lib;%(AdditionalDependencies) - 0x1D160000 - MachineX64 - - - - - fci.lib;msi.lib;rpcrt4.lib;%(AdditionalDependencies) - 0x1D160000 - - - - - X64 - + - fci.lib;msi.lib;rpcrt4.lib;%(AdditionalDependencies) + cabinet.lib;msi.lib;rpcrt4.lib;%(AdditionalDependencies) 0x1D160000 - MachineX64 diff --git a/PCbuild/_multiprocessing.vcxproj b/PCbuild/_multiprocessing.vcxproj index b4bb568538a5..1eb92b67dc24 100644 --- a/PCbuild/_multiprocessing.vcxproj +++ b/PCbuild/_multiprocessing.vcxproj @@ -39,176 +39,30 @@ _multiprocessing Win32Proj + - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - + DynamicLibrary NotSet + + .pyd + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - + <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - ws2_32.lib;%(AdditionalDependencies) - 0x1e1D0000 - - - - - X64 - - - ws2_32.lib;%(AdditionalDependencies) - 0x1e1D0000 - - - - - ws2_32.lib;%(AdditionalDependencies) - 0x1e1D0000 - - - - - X64 - - - ws2_32.lib;%(AdditionalDependencies) - 0x1e1D0000 - - - - - ws2_32.lib;%(AdditionalDependencies) - 0x1e1D0000 - - - - - X64 - - - ws2_32.lib;%(AdditionalDependencies) - 0x1e1D0000 - MachineX64 - - - - - ws2_32.lib;%(AdditionalDependencies) - 0x1e1D0000 - - - - - X64 - + ws2_32.lib;%(AdditionalDependencies) 0x1e1D0000 - MachineX64 diff --git a/PCbuild/_overlapped.vcxproj b/PCbuild/_overlapped.vcxproj index d0ee72fb5a13..55301ea9dc29 100644 --- a/PCbuild/_overlapped.vcxproj +++ b/PCbuild/_overlapped.vcxproj @@ -39,184 +39,30 @@ _overlapped Win32Proj + - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - + DynamicLibrary NotSet + + .pyd + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - + <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - ws2_32.lib;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) - 0x1D110000 - - - - - X64 - - - ws2_32.lib;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) - 0x1D110000 - - - - - ws2_32.lib;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) - 0x1D110000 - - - - - X64 - - - ws2_32.lib;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) - 0x1D110000 - - - - - ws2_32.lib;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) - 0x1D110000 - - - - - X64 - - - ws2_32.lib;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) - 0x1D110000 - MachineX64 - - - - - ws2_32.lib;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) - 0x1D110000 - - - - - X64 - + ws2_32.lib;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) 0x1D110000 - MachineX64 diff --git a/PCbuild/kill_python.vcxproj.filters b/PCbuild/_overlapped.vcxproj.filters similarity index 73% rename from PCbuild/kill_python.vcxproj.filters rename to PCbuild/_overlapped.vcxproj.filters index 433d75159687..78de89505590 100644 --- a/PCbuild/kill_python.vcxproj.filters +++ b/PCbuild/_overlapped.vcxproj.filters @@ -2,11 +2,11 @@ - {48606591-c8b6-41a5-95c5-9a0890c5504f} + {6f67c8db-7de7-4714-a967-2b0d4bc71f2e} - + Source Files diff --git a/PCbuild/_sha3.vcxproj b/PCbuild/_sha3.vcxproj deleted file mode 100644 index f24cbdc830d6..000000000000 --- a/PCbuild/_sha3.vcxproj +++ /dev/null @@ -1,218 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - PGInstrument - Win32 - - - PGInstrument - x64 - - - PGUpdate - Win32 - - - PGUpdate - x64 - - - Release - Win32 - - - Release - x64 - - - - {254A0C05-6696-4B08-8CB2-EF7D533AEE01} - _sha3 - Win32Proj - - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - - %(AdditionalDependencies) - - - - - X64 - - - %(AdditionalDependencies) - - - - - %(AdditionalDependencies) - - - - - X64 - - - %(AdditionalDependencies) - - - - - %(AdditionalDependencies) - - - - - X64 - - - %(AdditionalDependencies) - MachineX64 - - - - - %(AdditionalDependencies) - - - - - X64 - - - %(AdditionalDependencies) - MachineX64 - - - - - {cf7ac3d1-e2df-41d2-bea6-1e2556cdea26} - false - - - - - - - - - \ No newline at end of file diff --git a/PCbuild/_socket.vcxproj b/PCbuild/_socket.vcxproj index 63836e9261cc..03b6f7558eb4 100644 --- a/PCbuild/_socket.vcxproj +++ b/PCbuild/_socket.vcxproj @@ -39,176 +39,30 @@ _socket Win32Proj + - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - + DynamicLibrary NotSet + + .pyd + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - + <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - ws2_32.lib;%(AdditionalDependencies) - 0x1e1D0000 - - - - - X64 - - - ws2_32.lib;%(AdditionalDependencies) - 0x1e1D0000 - - - - - ws2_32.lib;%(AdditionalDependencies) - 0x1e1D0000 - - - - - X64 - - - ws2_32.lib;%(AdditionalDependencies) - 0x1e1D0000 - - - - - ws2_32.lib;%(AdditionalDependencies) - 0x1e1D0000 - - - - - X64 - - - ws2_32.lib;%(AdditionalDependencies) - 0x1e1D0000 - MachineX64 - - - - - ws2_32.lib;%(AdditionalDependencies) - 0x1e1D0000 - - - - - X64 - + ws2_32.lib;%(AdditionalDependencies) 0x1e1D0000 - MachineX64 diff --git a/PCbuild/_sqlite3.vcxproj b/PCbuild/_sqlite3.vcxproj index ed35d5bc0c31..5e889d0de00f 100644 --- a/PCbuild/_sqlite3.vcxproj +++ b/PCbuild/_sqlite3.vcxproj @@ -39,200 +39,33 @@ _sqlite3 Win32Proj + - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - + DynamicLibrary NotSet + + .pyd + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - $(sqlite3Dir);%(AdditionalIncludeDirectories) - MODULE_NAME="sqlite3";%(PreprocessorDefinitions) - - - 0x1e180000 - - - - - X64 - - - $(sqlite3Dir);%(AdditionalIncludeDirectories) - MODULE_NAME="sqlite3";%(PreprocessorDefinitions) - - - 0x1e180000 - - - - - $(sqlite3Dir);%(AdditionalIncludeDirectories) - MODULE_NAME="sqlite3";%(PreprocessorDefinitions) - - - 0x1e180000 - - - - - X64 - - - $(sqlite3Dir);%(AdditionalIncludeDirectories) - MODULE_NAME="sqlite3";%(PreprocessorDefinitions) - - - 0x1e180000 - - - - - $(sqlite3Dir);%(AdditionalIncludeDirectories) - MODULE_NAME="sqlite3";%(PreprocessorDefinitions) - - - 0x1e180000 - - - - - X64 - - - $(sqlite3Dir);%(AdditionalIncludeDirectories) - MODULE_NAME="sqlite3";%(PreprocessorDefinitions) - - - 0x1e180000 - MachineX64 - - - - - $(sqlite3Dir);%(AdditionalIncludeDirectories) - MODULE_NAME="sqlite3";%(PreprocessorDefinitions) - - - 0x1e180000 - - - - - X64 - + $(sqlite3Dir);%(AdditionalIncludeDirectories) MODULE_NAME="sqlite3";%(PreprocessorDefinitions) 0x1e180000 - MachineX64 diff --git a/PCbuild/_ssl.vcxproj b/PCbuild/_ssl.vcxproj index 7378794b3d9e..8594a0696602 100644 --- a/PCbuild/_ssl.vcxproj +++ b/PCbuild/_ssl.vcxproj @@ -39,242 +39,50 @@ _ssl Win32Proj + - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - + DynamicLibrary NotSet + + .pyd + - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - + <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - $(opensslDir)\inc32;%(AdditionalIncludeDirectories) - - - - - - - ws2_32.lib;crypt32.lib;$(opensslDir)\out32\libeay32.lib;$(opensslDir)\out32\ssleay32.lib;%(AdditionalDependencies) - - - - - X64 - - - $(opensslDir)\inc64;%(AdditionalIncludeDirectories) - - - - - - - ws2_32.lib;crypt32.lib;$(opensslDir)\out64\libeay32.lib;$(opensslDir)\out64\ssleay32.lib;%(AdditionalDependencies) - - - - - $(opensslDir)\inc32;%(AdditionalIncludeDirectories) - - - - - - - ws2_32.lib;crypt32.lib;$(opensslDir)\out32\libeay32.lib;$(opensslDir)\out32\ssleay32.lib;%(AdditionalDependencies) - - - - - X64 - - - $(opensslDir)\inc64;%(AdditionalIncludeDirectories) - - - - - - - ws2_32.lib;crypt32.lib;$(opensslDir)\out64\libeay32.lib;$(opensslDir)\out64\ssleay32.lib;%(AdditionalDependencies) - - - + - $(opensslDir)\inc32;%(AdditionalIncludeDirectories) + $(opensslDir)include;%(AdditionalIncludeDirectories) - - - - - ws2_32.lib;crypt32.lib;$(opensslDir)\out32\libeay32.lib;$(opensslDir)\out32\ssleay32.lib;%(AdditionalDependencies) - - - - - X64 - - - $(opensslDir)\inc64;%(AdditionalIncludeDirectories) - - - - - - - ws2_32.lib;crypt32.lib;$(opensslDir)\out64\libeay32.lib;$(opensslDir)\out64\ssleay32.lib;%(AdditionalDependencies) - MachineX64 - - - - - $(opensslDir)\inc32;%(AdditionalIncludeDirectories) - - - - - - - ws2_32.lib;crypt32.lib;$(opensslDir)\out32\libeay32.lib;$(opensslDir)\out32\ssleay32.lib;%(AdditionalDependencies) - - - - - X64 - - - $(opensslDir)\inc64;%(AdditionalIncludeDirectories) - - - - - - - ws2_32.lib;crypt32.lib;$(opensslDir)\out64\libeay32.lib;$(opensslDir)\out64\ssleay32.lib;%(AdditionalDependencies) - MachineX64 + ws2_32.lib;crypt32.lib;$(OutDir)libeay$(PyDebugExt).lib;$(OutDir)ssleay$(PyDebugExt).lib;%(AdditionalDependencies) - - {b11d750f-cd1f-4a96-85ce-e69a5c5259f9} - false - {cf7ac3d1-e2df-41d2-bea6-1e2556cdea26} false - + {e5b04cc0-eb4c-42ab-b4dc-18ef95f864b0} false + + {10615b24-73bf-4efa-93aa-236916321317} + false + {86937f53-c189-40ef-8ce8-8759d8e7d480} false diff --git a/PCbuild/_testbuffer.vcxproj b/PCbuild/_testbuffer.vcxproj index e1265f684147..8cbf1251c365 100644 --- a/PCbuild/_testbuffer.vcxproj +++ b/PCbuild/_testbuffer.vcxproj @@ -38,169 +38,31 @@ {A2697BD3-28C1-4AEC-9106-8B748639FD16} _testbuffer Win32Proj + false + - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - + DynamicLibrary NotSet + + .pyd + - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - + <_ProjectFileVersion>10.0.40219.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - 0x1e1F0000 - - - - - X64 - - - 0x1e1F0000 - - - - - 0x1e1F0000 - - - - - X64 - - - 0x1e1F0000 - - - - - 0x1e1F0000 - - - - - X64 - - - 0x1e1F0000 - MachineX64 - - - - - 0x1e1F0000 - - - - - X64 - + 0x1e1F0000 - MachineX64 diff --git a/PCbuild/_testcapi.vcxproj b/PCbuild/_testcapi.vcxproj index e99a7e4f3fe0..dbf44e6e9414 100644 --- a/PCbuild/_testcapi.vcxproj +++ b/PCbuild/_testcapi.vcxproj @@ -38,169 +38,31 @@ {6901D91C-6E48-4BB7-9FEC-700C8131DF1D} _testcapi Win32Proj + false + - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - + DynamicLibrary NotSet + + .pyd + - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - + <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - 0x1e1F0000 - - - - - X64 - - - 0x1e1F0000 - - - - - 0x1e1F0000 - - - - - X64 - - - 0x1e1F0000 - - - - - 0x1e1F0000 - - - - - X64 - - - 0x1e1F0000 - MachineX64 - - - - - 0x1e1F0000 - - - - - X64 - + 0x1e1F0000 - MachineX64 diff --git a/PCbuild/_testembed.vcxproj b/PCbuild/_testembed.vcxproj index 83c7ad21e720..f0e4d9f87465 100644 --- a/PCbuild/_testembed.vcxproj +++ b/PCbuild/_testembed.vcxproj @@ -9,6 +9,22 @@ Debug x64 + + PGInstrument + Win32 + + + PGInstrument + x64 + + + PGUpdate + Win32 + + + PGUpdate + x64 + Release Win32 @@ -22,137 +38,37 @@ {6DAC66D9-E703-4624-BE03-49112AB5AA62} Win32Proj _testembed + false + - - Application - true - Unicode - - - Application - true - Unicode - - - Application - false - true - Unicode - - + Application - false - true Unicode - - - - - - - - - - - - - - - - + - - - false - - - false - - - false - - - false - - - - - - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - - - Console - true - - - - - - - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - - - Console - true - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - - - Console - true - true - true - - - + - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _CONSOLE;%(PreprocessorDefinitions) Console - true - true - true - + {cf7ac3d1-e2df-41d2-bea6-1e2556cdea26} - true - true - false - true - false + false diff --git a/PCbuild/_testembed.vcxproj.filters b/PCbuild/_testembed.vcxproj.filters index dea54d4ad46e..f7f9abeb1dfa 100644 --- a/PCbuild/_testembed.vcxproj.filters +++ b/PCbuild/_testembed.vcxproj.filters @@ -15,7 +15,7 @@ - + Source Files diff --git a/PCbuild/_testimportmultiple.vcxproj b/PCbuild/_testimportmultiple.vcxproj index 84984ff2f704..cec042c202c6 100644 --- a/PCbuild/_testimportmultiple.vcxproj +++ b/PCbuild/_testimportmultiple.vcxproj @@ -38,169 +38,31 @@ {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781} _testimportmultiple Win32Proj + false + - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - + DynamicLibrary NotSet + + .pyd + - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - + <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - 0x1e1F0000 - - - - - X64 - - - 0x1e1F0000 - - - - - 0x1e1F0000 - - - - - X64 - - - 0x1e1F0000 - - - - - 0x1e1F0000 - - - - - X64 - - - 0x1e1F0000 - MachineX64 - - - - - 0x1e1F0000 - - - - - X64 - + 0x1e1F0000 - MachineX64 diff --git a/PCbuild/_tkinter.vcxproj b/PCbuild/_tkinter.vcxproj index 67f72fe38b69..e1408a18ea3e 100644 --- a/PCbuild/_tkinter.vcxproj +++ b/PCbuild/_tkinter.vcxproj @@ -39,202 +39,35 @@ _tkinter Win32Proj + - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - + DynamicLibrary NotSet + + .pyd + - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - + <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - + - $(tcltkDir)\include;%(AdditionalIncludeDirectories) - WITH_APPINIT;%(PreprocessorDefinitions) - - - $(tcltkLibDebug);%(AdditionalDependencies) - - - - - X64 - - - $(tcltk64Dir)\include;%(AdditionalIncludeDirectories) - WITH_APPINIT;%(PreprocessorDefinitions) - - - $(tcltk64LibDebug);%(AdditionalDependencies) - - - - - $(tcltkDir)\include;%(AdditionalIncludeDirectories) + $(tcltkDir)include;%(AdditionalIncludeDirectories) WITH_APPINIT;%(PreprocessorDefinitions) $(tcltkLib);%(AdditionalDependencies) - - - X64 - - - $(tcltk64Dir)\include;%(AdditionalIncludeDirectories) - WITH_APPINIT;%(PreprocessorDefinitions) - - - $(tcltk64Lib);%(AdditionalDependencies) - - - - - $(tcltkDir)\include;%(AdditionalIncludeDirectories) - WITH_APPINIT;%(PreprocessorDefinitions) - - - $(tcltkLib);%(AdditionalDependencies) - - - - - X64 - - - $(tcltk64Dir)\include;%(AdditionalIncludeDirectories) - WITH_APPINIT;%(PreprocessorDefinitions) - - - $(tcltk64Lib);%(AdditionalDependencies) - MachineX64 - - - - - $(tcltkDir)\include;%(AdditionalIncludeDirectories) - WITH_APPINIT;%(PreprocessorDefinitions) - - - $(tcltkLib);%(AdditionalDependencies) - - - - - X64 - - - $(tcltk64Dir)\include;%(AdditionalIncludeDirectories) - WITH_APPINIT;%(PreprocessorDefinitions) - - - $(tcltk64Lib);%(AdditionalDependencies) - MachineX64 - - @@ -244,6 +77,12 @@ {cf7ac3d1-e2df-41d2-bea6-1e2556cdea26} false + + {b5fd6f1d-129e-4bff-9340-03606fac7283} + + + {7e85eccf-a72c-4da4-9e52-884508e80ba1} + diff --git a/PCbuild/bdist_wininst.vcxproj b/PCbuild/bdist_wininst.vcxproj deleted file mode 100644 index 49276a2e41e2..000000000000 --- a/PCbuild/bdist_wininst.vcxproj +++ /dev/null @@ -1,158 +0,0 @@ - - - - - Release - Win32 - - - Release - x64 - - - - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C} - wininst - - - - Application - false - NotSet - - - Application - false - NotSet - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - ..\lib\distutils\command\ - false - ..\lib\distutils\command\ - $(SolutionDir)$(PlatformName)-temp-$(Configuration)\$(ProjectName)\ - false - AllRules.ruleset - - - AllRules.ruleset - - - .exe - .exe - - - - NDEBUG;%(PreprocessorDefinitions) - true - true - Win32 - .\..\lib\distutils\command\wininst.tlb - - - - - MinSpace - OnlyExplicitInline - ..\PC\bdist_wininst;..\Include;..\Modules\zlib;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) - true - MultiThreaded - true - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0000 - ..\PC;..\PC\bdist_wininst;..\Include;%(AdditionalIncludeDirectories) - - - comctl32.lib;imagehlp.lib;%(AdditionalDependencies) - ..\lib\distutils\command\wininst-10.0.exe - true - LIBC;%(IgnoreSpecificDefaultLibraries) - ..\lib\distutils\command\wininst-10.0.pdb - Windows - false - - - MachineX86 - - - - - NDEBUG;%(PreprocessorDefinitions) - true - true - X64 - .\..\lib\distutils\command\wininst.tlb - - - - - MinSpace - OnlyExplicitInline - ..\PC\bdist_wininst;..\Include;..\Modules\zlib;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) - true - MultiThreaded - true - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0000 - ..\PC;..\PC\bdist_wininst;..\Include;%(AdditionalIncludeDirectories) - - - comctl32.lib;imagehlp.lib;%(AdditionalDependencies) - ..\lib\distutils\command\wininst-10.0-amd64.exe - true - LIBC;%(IgnoreSpecificDefaultLibraries) - ..\lib\distutils\command\wininst-9.0-amd64.pdb - Windows - false - - - MachineX64 - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/PCbuild/build.bat b/PCbuild/build.bat index fa0d95b0cc03..2846144ff980 100644 --- a/PCbuild/build.bat +++ b/PCbuild/build.bat @@ -1,19 +1,43 @@ @echo off -rem A batch program to build or rebuild a particular configuration. +rem A batch program to build or rebuild a particular configuration, rem just for convenience. +rem Arguments: +rem -c Set the configuration (default: Release) +rem -p Set the platform (x64 or Win32, default: Win32) +rem -r Target Rebuild instead of Build +rem -t Set the target manually (Build, Rebuild, Clean, or CleanAll) +rem -d Set the configuration to Debug +rem -e Pull in external libraries using get_externals.bat +rem -M Disable parallel build +rem -v Increased output messages + setlocal set platf=Win32 +set vs_platf=x86 set conf=Release -set target=build +set target=Build set dir=%~dp0 +set parallel=/m +set verbose=/nologo /v:m :CheckOpts -if "%1"=="-c" (set conf=%2) & shift & shift & goto CheckOpts -if "%1"=="-p" (set platf=%2) & shift & shift & goto CheckOpts -if "%1"=="-r" (set target=rebuild) & shift & goto CheckOpts -if "%1"=="-d" (set conf=Debug) & shift & goto CheckOpts +if '%1'=='-c' (set conf=%2) & shift & shift & goto CheckOpts +if '%1'=='-p' (set platf=%2) & shift & shift & goto CheckOpts +if '%1'=='-r' (set target=Rebuild) & shift & goto CheckOpts +if '%1'=='-t' (set target=%2) & shift & shift & goto CheckOpts +if '%1'=='-d' (set conf=Debug) & shift & goto CheckOpts +if '%1'=='-e' call "%dir%get_externals.bat" & shift & goto CheckOpts +if '%1'=='-M' (set parallel=) & shift & goto CheckOpts +if '%1'=='-v' (set verbose=/v:n) & shift & goto CheckOpts + +if '%platf%'=='x64' (set vs_platf=x86_amd64) + +rem Setup the environment +call "%dir%env.bat" %vs_platf% >nul -set cmd=msbuild /p:useenv=true %dir%pcbuild.sln /t:%target% /p:Configuration=%conf% /p:Platform=%platf% -echo %cmd% -%cmd% +rem Call on MSBuild to do the work, echo the command. +rem Passing %1-9 is not the preferred option, but argument parsing in +rem batch is, shall we say, "lackluster" +echo on +msbuild "%dir%pcbuild.proj" /t:%target% %parallel% %verbose% /p:Configuration=%conf% /p:Platform=%platf% %1 %2 %3 %4 %5 %6 %7 %8 %9 diff --git a/PCbuild/build_pgo.bat b/PCbuild/build_pgo.bat index 0c0a473b2c45..5988c0a268db 100644 --- a/PCbuild/build_pgo.bat +++ b/PCbuild/build_pgo.bat @@ -7,14 +7,16 @@ rem building the PGUpdate configuration while developing. setlocal set platf=Win32 +set parallel=/m +set dir=%~dp0 rem use the performance testsuite. This is quick and simple -set job1=..\tools\pybench\pybench.py -n 1 -C 1 --with-gc -set path1=..\tools\pybench +set job1="%dir%..\tools\pybench\pybench.py" -n 1 -C 1 --with-gc +set path1="%dir%..\tools\pybench" rem or the whole testsuite for more thorough testing -set job2=..\lib\test\regrtest.py -set path2=..\lib +set job2="%dir%..\lib\test\regrtest.py" +set path2="%dir%..\lib" set job=%job1% set clrpath=%path1% @@ -22,20 +24,25 @@ set clrpath=%path1% :CheckOpts if "%1"=="-p" (set platf=%2) & shift & shift & goto CheckOpts if "%1"=="-2" (set job=%job2%) & (set clrpath=%path2%) & shift & goto CheckOpts +if "%1"=="-M" (set parallel=) & shift & goto CheckOpts + + +rem We cannot cross compile PGO builds, as the optimization needs to be run natively +set vs_platf=x86 +set PGO=%dir%win32-pgo + +if "%platf%"=="x64" (set vs_platf=amd64) & (set PGO=%dir%amd64-pgo) +rem Setup the environment +call "%dir%env.bat" %vs_platf% -set PGI=%platf%-pgi -set PGO=%platf%-pgo -@echo on rem build the instrumented version -call build -p %platf% -c PGInstrument +msbuild "%dir%pcbuild.proj" %parallel% /t:Build /p:Configuration=PGInstrument /p:Platform=%platf% %1 %2 %3 %4 %5 %6 %7 %8 %9 rem remove .pyc files, .pgc files and execute the job -%PGI%\python.exe rmpyc.py %clrpath% -del %PGI%\*.pgc -%PGI%\python.exe %job% - -rem finally build the optimized version -if exist %PGO% del /s /q %PGO% -call build -p %platf% -c PGUpdate +"%PGO%\python.exe" "%dir%rmpyc.py" %clrpath% +del "%PGO%\*.pgc" +"%PGO%\python.exe" %job% +rem build optimized version +msbuild "%dir%pcbuild.proj" %parallel% /t:Build /p:Configuration=PGUpdate /p:Platform=%platf% %1 %2 %3 %4 %5 %6 %7 %8 %9 diff --git a/PCbuild/build_ssl.py b/PCbuild/build_ssl.py deleted file mode 100644 index 5a7a89e4ec9b..000000000000 --- a/PCbuild/build_ssl.py +++ /dev/null @@ -1,253 +0,0 @@ -# Script for building the _ssl and _hashlib modules for Windows. -# Uses Perl to setup the OpenSSL environment correctly -# and build OpenSSL, then invokes a simple nmake session -# for the actual _ssl.pyd and _hashlib.pyd DLLs. - -# THEORETICALLY, you can: -# * Unpack the latest SSL release one level above your main Python source -# directory. It is likely you will already find the zlib library and -# any other external packages there. -# * Install ActivePerl and ensure it is somewhere on your path. -# * Run this script from the PCBuild directory. -# -# it should configure and build SSL, then build the _ssl and _hashlib -# Python extensions without intervention. - -# Modified by Christian Heimes -# Now this script supports pre-generated makefiles and assembly files. -# Developers don't need an installation of Perl anymore to build Python. A svn -# checkout from our svn repository is enough. -# -# In Order to create the files in the case of an update you still need Perl. -# Run build_ssl in this order: -# python.exe build_ssl.py Release x64 -# python.exe build_ssl.py Release Win32 - -import os, sys, re, shutil - -# Find all "foo.exe" files on the PATH. -def find_all_on_path(filename, extras = None): - entries = os.environ["PATH"].split(os.pathsep) - ret = [] - for p in entries: - fname = os.path.abspath(os.path.join(p, filename)) - if os.path.isfile(fname) and fname not in ret: - ret.append(fname) - if extras: - for p in extras: - fname = os.path.abspath(os.path.join(p, filename)) - if os.path.isfile(fname) and fname not in ret: - ret.append(fname) - return ret - -# Find a suitable Perl installation for OpenSSL. -# cygwin perl does *not* work. ActivePerl does. -# Being a Perl dummy, the simplest way I can check is if the "Win32" package -# is available. -def find_working_perl(perls): - for perl in perls: - fh = os.popen('"%s" -e "use Win32;"' % perl) - fh.read() - rc = fh.close() - if rc: - continue - return perl - print("Can not find a suitable PERL:") - if perls: - print(" the following perl interpreters were found:") - for p in perls: - print(" ", p) - print(" None of these versions appear suitable for building OpenSSL") - else: - print(" NO perl interpreters were found on this machine at all!") - print(" Please install ActivePerl and ensure it appears on your path") - return None - -# Fetch SSL directory from VC properties -def get_ssl_dir(): - propfile = (os.path.join(os.path.dirname(__file__), 'pyproject.props')) - with open(propfile) as f: - m = re.search('openssl-([^<]+)<', f.read()) - return "..\..\openssl-"+m.group(1) - - -def create_makefile64(makefile, m32): - """Create and fix makefile for 64bit - - Replace 32 with 64bit directories - """ - if not os.path.isfile(m32): - return - with open(m32) as fin: - with open(makefile, 'w') as fout: - for line in fin: - line = line.replace("=tmp32", "=tmp64") - line = line.replace("=out32", "=out64") - line = line.replace("=inc32", "=inc64") - # force 64 bit machine - line = line.replace("MKLIB=lib", "MKLIB=lib /MACHINE:X64") - line = line.replace("LFLAGS=", "LFLAGS=/MACHINE:X64 ") - # don't link against the lib on 64bit systems - line = line.replace("bufferoverflowu.lib", "") - fout.write(line) - os.unlink(m32) - -def fix_makefile(makefile): - """Fix some stuff in all makefiles - """ - if not os.path.isfile(makefile): - return - with open(makefile) as fin: - lines = fin.readlines() - with open(makefile, 'w') as fout: - for line in lines: - if line.startswith("PERL="): - continue - if line.startswith("CP="): - line = "CP=copy\n" - if line.startswith("MKDIR="): - line = "MKDIR=mkdir\n" - if line.startswith("CFLAG="): - line = line.strip() - for algo in ("RC5", "MDC2", "IDEA"): - noalgo = " -DOPENSSL_NO_%s" % algo - if noalgo not in line: - line = line + noalgo - line = line + '\n' - fout.write(line) - -def run_configure(configure, do_script): - print("perl Configure "+configure+" no-idea no-mdc2") - os.system("perl Configure "+configure+" no-idea no-mdc2") - print(do_script) - os.system(do_script) - -def cmp(f1, f2): - bufsize = 1024 * 8 - with open(f1, 'rb') as fp1, open(f2, 'rb') as fp2: - while True: - b1 = fp1.read(bufsize) - b2 = fp2.read(bufsize) - if b1 != b2: - return False - if not b1: - return True - -def copy(src, dst): - if os.path.isfile(dst) and cmp(src, dst): - return - shutil.copy(src, dst) - -def main(): - build_all = "-a" in sys.argv - if sys.argv[1] == "Release": - debug = False - elif sys.argv[1] == "Debug": - debug = True - else: - raise ValueError(str(sys.argv)) - - if sys.argv[2] == "Win32": - arch = "x86" - configure = "VC-WIN32" - do_script = "ms\\do_nasm" - makefile="ms\\nt.mak" - m32 = makefile - dirsuffix = "32" - elif sys.argv[2] == "x64": - arch="amd64" - configure = "VC-WIN64A" - do_script = "ms\\do_win64a" - makefile = "ms\\nt64.mak" - m32 = makefile.replace('64', '') - dirsuffix = "64" - #os.environ["VSEXTCOMP_USECL"] = "MS_OPTERON" - else: - raise ValueError(str(sys.argv)) - - make_flags = "" - if build_all: - make_flags = "-a" - # perl should be on the path, but we also look in "\perl" and "c:\\perl" - # as "well known" locations - perls = find_all_on_path("perl.exe", ["\\perl\\bin", "C:\\perl\\bin"]) - perl = find_working_perl(perls) - if perl: - print("Found a working perl at '%s'" % (perl,)) - else: - print("No Perl installation was found. Existing Makefiles are used.") - sys.stdout.flush() - # Look for SSL 2 levels up from pcbuild - ie, same place zlib etc all live. - ssl_dir = get_ssl_dir() - if ssl_dir is None: - sys.exit(1) - - old_cd = os.getcwd() - try: - os.chdir(ssl_dir) - # rebuild makefile when we do the role over from 32 to 64 build - if arch == "amd64" and os.path.isfile(m32) and not os.path.isfile(makefile): - os.unlink(m32) - - # If the ssl makefiles do not exist, we invoke Perl to generate them. - # Due to a bug in this script, the makefile sometimes ended up empty - # Force a regeneration if it is. - if not os.path.isfile(makefile) or os.path.getsize(makefile)==0: - if perl is None: - print("Perl is required to build the makefiles!") - sys.exit(1) - - print("Creating the makefiles...") - sys.stdout.flush() - # Put our working Perl at the front of our path - os.environ["PATH"] = os.path.dirname(perl) + \ - os.pathsep + \ - os.environ["PATH"] - run_configure(configure, do_script) - if debug: - print("OpenSSL debug builds aren't supported.") - #if arch=="x86" and debug: - # # the do_masm script in openssl doesn't generate a debug - # # build makefile so we generate it here: - # os.system("perl util\mk1mf.pl debug "+configure+" >"+makefile) - - if arch == "amd64": - create_makefile64(makefile, m32) - fix_makefile(makefile) - copy(r"crypto\buildinf.h", r"crypto\buildinf_%s.h" % arch) - copy(r"crypto\opensslconf.h", r"crypto\opensslconf_%s.h" % arch) - - # If the assembler files don't exist in tmpXX, copy them there - if perl is None and os.path.exists("asm"+dirsuffix): - if not os.path.exists("tmp"+dirsuffix): - os.mkdir("tmp"+dirsuffix) - for f in os.listdir("asm"+dirsuffix): - if not f.endswith(".asm"): continue - if os.path.isfile(r"tmp%s\%s" % (dirsuffix, f)): continue - shutil.copy(r"asm%s\%s" % (dirsuffix, f), "tmp"+dirsuffix) - - # Now run make. - if arch == "amd64": - rc = os.system("nasm -f win64 -DNEAR -Ox -g ms\\uptable.asm") - if rc: - print("nasm assembler has failed.") - sys.exit(rc) - - copy(r"crypto\buildinf_%s.h" % arch, r"crypto\buildinf.h") - copy(r"crypto\opensslconf_%s.h" % arch, r"crypto\opensslconf.h") - - #makeCommand = "nmake /nologo PERL=\"%s\" -f \"%s\"" %(perl, makefile) - makeCommand = "nmake /nologo -f \"%s\"" % makefile - print("Executing ssl makefiles:", makeCommand) - sys.stdout.flush() - rc = os.system(makeCommand) - if rc: - print("Executing "+makefile+" failed") - print(rc) - sys.exit(rc) - finally: - os.chdir(old_cd) - sys.exit(rc) - -if __name__=='__main__': - main() diff --git a/PCbuild/build_tkinter.py b/PCbuild/build_tkinter.py deleted file mode 100644 index c807e7b19cf6..000000000000 --- a/PCbuild/build_tkinter.py +++ /dev/null @@ -1,78 +0,0 @@ -"""Script to compile the dependencies of _tkinter - -Copyright (c) 2007 by Christian Heimes - -Licensed to PSF under a Contributor Agreement. -""" - -import os -import sys - -here = os.path.abspath(os.path.dirname(__file__)) -par = os.path.pardir - -TCL = "tcl8.6.1" -TK = "tk8.6.1" -TIX = "tix-8.4.3.3" - -ROOT = os.path.abspath(os.path.join(here, par, par)) -NMAKE = ('nmake /nologo /f %s %s %s') - -def nmake(makefile, command="", **kw): - defines = ' '.join(k+'='+str(v) for k, v in kw.items()) - cmd = NMAKE % (makefile, defines, command) - print("\n\n"+cmd+"\n") - if os.system(cmd) != 0: - raise RuntimeError(cmd) - -def build(platform, clean): - if platform == "Win32": - dest = os.path.join(ROOT, "tcltk") - machine = "IX86" - elif platform == "AMD64": - dest = os.path.join(ROOT, "tcltk64") - machine = "AMD64" - else: - raise ValueError(platform) - - # TCL - tcldir = os.path.join(ROOT, TCL) - if 1: - os.chdir(os.path.join(tcldir, "win")) - if clean: - nmake("makefile.vc", "clean") - nmake("makefile.vc", MACHINE=machine) - nmake("makefile.vc", "install", INSTALLDIR=dest, MACHINE=machine) - - # TK - if 1: - os.chdir(os.path.join(ROOT, TK, "win")) - if clean: - nmake("makefile.vc", "clean", DEBUG=0, TCLDIR=tcldir) - nmake("makefile.vc", DEBUG=0, MACHINE=machine, TCLDIR=tcldir) - nmake("makefile.vc", "install", DEBUG=0, INSTALLDIR=dest, MACHINE=machine, TCLDIR=tcldir) - - # TIX - if 1: - # python9.mak is available at http://svn.python.org - os.chdir(os.path.join(ROOT, TIX, "win")) - if clean: - nmake("python.mak", "clean") - nmake("python.mak", MACHINE=machine, INSTALL_DIR=dest) - nmake("python.mak", "install", MACHINE=machine, INSTALL_DIR=dest) - -def main(): - if len(sys.argv) < 2 or sys.argv[1] not in ("Win32", "AMD64"): - print("%s Win32|AMD64" % sys.argv[0]) - sys.exit(1) - - if "-c" in sys.argv: - clean = True - else: - clean = False - - build(sys.argv[1], clean) - - -if __name__ == '__main__': - main() diff --git a/PCbuild/clean.bat b/PCbuild/clean.bat new file mode 100644 index 000000000000..6144c715f64e --- /dev/null +++ b/PCbuild/clean.bat @@ -0,0 +1,5 @@ +@echo off +rem A batch program to clean a particular configuration, +rem just for convenience. + +call %~dp0build.bat -t Clean %* diff --git a/PCbuild/debug.props b/PCbuild/debug.props deleted file mode 100644 index 9b7a65af4d00..000000000000 --- a/PCbuild/debug.props +++ /dev/null @@ -1,27 +0,0 @@ - - - - _d - $(OutDir)kill_python_d.exe - - - <_ProjectFileVersion>10.0.30319.1 - $(ProjectName)_d - - - - _DEBUG;%(PreprocessorDefinitions) - - - _DEBUG - - - - - $(PyDebugExt) - - - $(KillPythonExe) - - - \ No newline at end of file diff --git a/PCbuild/env.bat b/PCbuild/env.bat index 08dc8ef5253e..9d4c9d1c32f7 100644 --- a/PCbuild/env.bat +++ b/PCbuild/env.bat @@ -1,9 +1,16 @@ @echo off -set VS10=%ProgramFiles(x86)%\Microsoft Visual Studio 10.0 -IF EXIST "%VS10%" GOTO ok -set VS10=%ProgramFiles%\Microsoft Visual Studio 10.0 -:ok +rem This script adds the latest available tools to the path for the current +rem command window. However, most builds of Python will ignore the version +rem of the tools on PATH and use PlatformToolset instead. Ideally, both sets of +rem tools should be the same version to avoid potential conflicts. +rem +rem To build Python with an earlier toolset, pass "/p:PlatformToolset=v100" (or +rem 'v110', 'v120' or 'v140') to the build script. -echo Build environments: x86, ia64, amd64, x86_amd64, x86_ia64 +echo Build environments: x86, amd64, x86_amd64 echo. -call "%VS10%\VC\vcvarsall.bat" %1 +set VSTOOLS=%VS140COMNTOOLS% +if "%VSTOOLS%"=="" set VSTOOLS=%VS120COMNTOOLS% +if "%VSTOOLS%"=="" set VSTOOLS=%VS110COMNTOOLS% +if "%VSTOOLS%"=="" set VSTOOLS=%VS100COMNTOOLS% +call "%VSTOOLS%..\..\VC\vcvarsall.bat" %* diff --git a/PCbuild/get_externals.bat b/PCbuild/get_externals.bat new file mode 100644 index 000000000000..e9987be3dd8d --- /dev/null +++ b/PCbuild/get_externals.bat @@ -0,0 +1,103 @@ +@echo off +setlocal +rem Simple script to fetch source for external libraries + +if not exist "%~dp0..\externals" mkdir "%~dp0..\externals" +pushd "%~dp0..\externals" + +if "%SVNROOT%"=="" set SVNROOT=http://svn.python.org/projects/external/ + +rem Optionally clean up first. Be warned that this can be very destructive! +if not "%1"=="" ( + for %%c in (-c --clean --clean-only) do ( + if "%1"=="%%c" goto clean + ) + goto usage +) +goto fetch + +:clean +echo.Cleaning up external libraries. +for /D %%d in ( + bzip2-* + db-* + nasm-* + openssl-* + tcl-* + tcltk* + tk-* + tix-* + sqlite-* + xz-* + ) do ( + echo.Removing %%d + rmdir /s /q %%d +) +if "%1"=="--clean-only" ( + goto end +) + +:fetch +rem Fetch current versions + +svn --version > nul 2>&1 +if ERRORLEVEL 9009 ( + echo.svn.exe must be on your PATH. + echo.Try TortoiseSVN (http://tortoisesvn.net/^) and be sure to check the + echo.command line tools option. + popd + exit /b 1 +) + +echo.Fetching external libraries... + +for %%e in ( + bzip2-1.0.6 + nasm-2.11.06 + openssl-1.0.1l + tcl-core-8.6.3.1 + tk-8.6.3.1 + tix-8.4.3.4 + sqlite-3.8.3.1 + xz-5.0.5 + ) do ( + if exist %%e ( + echo.%%e already exists, skipping. + ) else ( + echo.Fetching %%e... + svn export %SVNROOT%%%e + ) +) + +goto end + +:usage +echo.invalid argument: %1 +echo.usage: %~n0 [[ -c ^| --clean ] ^| --clean-only ] +echo. +echo.Pull all sources necessary for compiling optional extension modules +echo.that rely on external libraries. Requires svn.exe to be on your PATH +echo.and pulls sources from %SVNROOT%. +echo. +echo.Use the -c or --clean option to clean up all external library sources +echo.before pulling in the current versions. +echo. +echo.Use the --clean-only option to do the same cleaning, without pulling in +echo.anything new. +echo. +echo.Only the first argument is checked, all others are ignored. +echo. +echo.**WARNING**: the cleaning options unconditionally remove any directory +echo.that is a child of +echo. %CD% +echo.and matches wildcard patterns beginning with bzip2-, db-, nasm-, openssl-, +echo.tcl-, tcltk, tk-, tix-, sqlite-, or xz-, and as such has the potential +echo.to be very destructive if you are not aware of what it is doing. Use with +echo.caution! +popd +exit /b -1 + + +:end +echo Finished. +popd diff --git a/PCbuild/idle.bat b/PCbuild/idle.bat index dcb0485af7d3..1978b99f6ee1 100644 --- a/PCbuild/idle.bat +++ b/PCbuild/idle.bat @@ -4,10 +4,10 @@ rem Usage: idle [-d] rem -d Run Debug build (python_d.exe). Else release build. setlocal -set exe=python -PATH %PATH%;..\..\tcltk\bin +set exe=win32\python +PATH %PATH%;..\externals\tcltk\bin -if "%1"=="-d" (set exe=python_d) & shift +if "%1"=="-d" (set exe=%exe%_d) & shift set cmd=%exe% ../Lib/idlelib/idle.py %1 %2 %3 %4 %5 %6 %7 %8 %9 diff --git a/PCbuild/installer.bmp b/PCbuild/installer.bmp deleted file mode 100644 index 1875e194ba27..000000000000 Binary files a/PCbuild/installer.bmp and /dev/null differ diff --git a/PCbuild/kill_python.c b/PCbuild/kill_python.c deleted file mode 100644 index 604731f3f81c..000000000000 --- a/PCbuild/kill_python.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Helper program for killing lingering python[_d].exe processes before - * building, thus attempting to avoid build failures due to files being - * locked. - */ - -#include -#include -#include -#include - -#pragma comment(lib, "psapi") - -#ifdef _DEBUG -#define PYTHON_EXE (L"python_d.exe") -#define PYTHON_EXE_LEN (12) -#define KILL_PYTHON_EXE (L"kill_python_d.exe") -#define KILL_PYTHON_EXE_LEN (17) -#else -#define PYTHON_EXE (L"python.exe") -#define PYTHON_EXE_LEN (10) -#define KILL_PYTHON_EXE (L"kill_python.exe") -#define KILL_PYTHON_EXE_LEN (15) -#endif - -int -main(int argc, char **argv) -{ - HANDLE hp, hsp, hsm; /* process, snapshot processes, snapshot modules */ - DWORD dac, our_pid; - size_t len; - wchar_t path[MAX_PATH+1]; - - MODULEENTRY32W me; - PROCESSENTRY32W pe; - - me.dwSize = sizeof(MODULEENTRY32W); - pe.dwSize = sizeof(PROCESSENTRY32W); - - memset(path, 0, MAX_PATH+1); - - our_pid = GetCurrentProcessId(); - - hsm = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, our_pid); - if (hsm == INVALID_HANDLE_VALUE) { - printf("CreateToolhelp32Snapshot[1] failed: %d\n", GetLastError()); - return 1; - } - - if (!Module32FirstW(hsm, &me)) { - printf("Module32FirstW[1] failed: %d\n", GetLastError()); - CloseHandle(hsm); - return 1; - } - - /* - * Enumerate over the modules for the current process in order to find - * kill_process[_d].exe, then take a note of the directory it lives in. - */ - do { - if (_wcsnicmp(me.szModule, KILL_PYTHON_EXE, KILL_PYTHON_EXE_LEN)) - continue; - - len = wcsnlen_s(me.szExePath, MAX_PATH) - KILL_PYTHON_EXE_LEN; - wcsncpy_s(path, MAX_PATH+1, me.szExePath, len); - - break; - - } while (Module32NextW(hsm, &me)); - - CloseHandle(hsm); - - if (path == NULL) { - printf("failed to discern directory of running process\n"); - return 1; - } - - /* - * Take a snapshot of system processes. Enumerate over the snapshot, - * looking for python processes. When we find one, verify it lives - * in the same directory we live in. If it does, kill it. If we're - * unable to kill it, treat this as a fatal error and return 1. - * - * The rationale behind this is that we're called at the start of the - * build process on the basis that we'll take care of killing any - * running instances, such that the build won't encounter permission - * denied errors during linking. If we can't kill one of the processes, - * we can't provide this assurance, and the build shouldn't start. - */ - - hsp = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); - if (hsp == INVALID_HANDLE_VALUE) { - printf("CreateToolhelp32Snapshot[2] failed: %d\n", GetLastError()); - return 1; - } - - if (!Process32FirstW(hsp, &pe)) { - printf("Process32FirstW failed: %d\n", GetLastError()); - CloseHandle(hsp); - return 1; - } - - dac = PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_TERMINATE; - do { - - /* - * XXX TODO: if we really wanted to be fancy, we could check the - * modules for all processes (not just the python[_d].exe ones) - * and see if any of our DLLs are loaded (i.e. python34[_d].dll), - * as that would also inhibit our ability to rebuild the solution. - * Not worth loosing sleep over though; for now, a simple check - * for just the python executable should be sufficient. - */ - - if (_wcsnicmp(pe.szExeFile, PYTHON_EXE, PYTHON_EXE_LEN)) - /* This isn't a python process. */ - continue; - - /* It's a python process, so figure out which directory it's in... */ - hsm = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pe.th32ProcessID); - if (hsm == INVALID_HANDLE_VALUE) - /* - * If our module snapshot fails (which will happen if we don't own - * the process), just ignore it and continue. (It seems different - * versions of Windows return different values for GetLastError() - * in this situation; it's easier to just ignore it and move on vs. - * stopping the build for what could be a false positive.) - */ - continue; - - if (!Module32FirstW(hsm, &me)) { - printf("Module32FirstW[2] failed: %d\n", GetLastError()); - CloseHandle(hsp); - CloseHandle(hsm); - return 1; - } - - do { - if (_wcsnicmp(me.szModule, PYTHON_EXE, PYTHON_EXE_LEN)) - /* Wrong module, we're looking for python[_d].exe... */ - continue; - - if (_wcsnicmp(path, me.szExePath, len)) - /* Process doesn't live in our directory. */ - break; - - /* Python process residing in the right directory, kill it! */ - hp = OpenProcess(dac, FALSE, pe.th32ProcessID); - if (!hp) { - printf("OpenProcess failed: %d\n", GetLastError()); - CloseHandle(hsp); - CloseHandle(hsm); - return 1; - } - - if (!TerminateProcess(hp, 1)) { - printf("TerminateProcess failed: %d\n", GetLastError()); - CloseHandle(hsp); - CloseHandle(hsm); - CloseHandle(hp); - return 1; - } - - CloseHandle(hp); - break; - - } while (Module32NextW(hsm, &me)); - - CloseHandle(hsm); - - } while (Process32NextW(hsp, &pe)); - - CloseHandle(hsp); - - return 0; -} - -/* vi: set ts=8 sw=4 sts=4 expandtab */ diff --git a/PCbuild/kill_python.vcxproj b/PCbuild/kill_python.vcxproj deleted file mode 100644 index 9f67c4081fd3..000000000000 --- a/PCbuild/kill_python.vcxproj +++ /dev/null @@ -1,120 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31} - kill_python - Win32Proj - - - - Application - NotSet - true - - - Application - NotSet - - - Application - NotSet - true - - - Application - NotSet - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - - $(OutDir)$(ProjectName)_d.exe - Console - - - - - X64 - - - $(OutDir)$(ProjectName)_d.exe - Console - - - - - Console - - - - - X64 - - - Console - - - - - - - - - \ No newline at end of file diff --git a/PCbuild/libeay.vcxproj b/PCbuild/libeay.vcxproj new file mode 100644 index 000000000000..dff5e71a9829 --- /dev/null +++ b/PCbuild/libeay.vcxproj @@ -0,0 +1,890 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + PGInstrument + Win32 + + + PGInstrument + x64 + + + PGUpdate + Win32 + + + PGUpdate + x64 + + + Debug + x64 + + + Release + x64 + + + + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0} + libeay + + + + + + + StaticLibrary + + + + + + + + <_DATEValue>#define DATE "$([System.DateTime]::Now.ToString(`ddd MMM dd HH':'mm':'ss yyyy`))" + <_CFLAGSValue>#define CFLAGS "cl /MD /Ox -W3 -Gs0 -Gy -nologo @(PreprocessorDefinitions->'-D%(Identity)',' ')" + <_PLATFORMValue Condition="$(Platform)=='Win32'">#define PLATFORM "VC-WIN32" + <_PLATFORMValue Condition="$(Platform)=='x64'">#define PLATFORM "VC-WIN64A" + + + + + + + + + + + + $(IntDir);%(AdditionalIncludeDirectories) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PCbuild/make_buildinfo.c b/PCbuild/make_buildinfo.c deleted file mode 100644 index f9aadee65f97..000000000000 --- a/PCbuild/make_buildinfo.c +++ /dev/null @@ -1,194 +0,0 @@ -#include -#include -#include -#include -#include - -#define CMD_SIZE 500 - -/* This file creates the getbuildinfo.o object, by first - invoking subwcrev.exe (if found), and then invoking cl.exe. - As a side effect, it might generate PCBuild\getbuildinfo2.c - also. If this isn't a subversion checkout, or subwcrev isn't - found, it compiles ..\\Modules\\getbuildinfo.c instead. - - Currently, subwcrev.exe is found from the registry entries - of TortoiseSVN. - - No attempt is made to place getbuildinfo.o into the proper - binary directory. This isn't necessary, as this tool is - invoked as a pre-link step for pythoncore, so that overwrites - any previous getbuildinfo.o. - - However, if a second argument is provided, this will be used - as a temporary directory where any getbuildinfo2.c and - getbuildinfo.o files are put. This is useful if multiple - configurations are being built in parallel, to avoid them - trampling each other's files. - -*/ - -int make_buildinfo2(const char *tmppath) -{ - struct _stat st; - HKEY hTortoise; - char command[CMD_SIZE+1]; - DWORD type, size; - if (_stat(".svn", &st) < 0) - return 0; - /* Allow suppression of subwcrev.exe invocation if a no_subwcrev file is present. */ - if (_stat("no_subwcrev", &st) == 0) - return 0; - if (RegOpenKey(HKEY_LOCAL_MACHINE, "Software\\TortoiseSVN", &hTortoise) != ERROR_SUCCESS && - RegOpenKey(HKEY_CURRENT_USER, "Software\\TortoiseSVN", &hTortoise) != ERROR_SUCCESS) - /* Tortoise not installed */ - return 0; - command[0] = '"'; /* quote the path to the executable */ - size = sizeof(command) - 1; - if (RegQueryValueEx(hTortoise, "Directory", 0, &type, command+1, &size) != ERROR_SUCCESS || - type != REG_SZ) - /* Registry corrupted */ - return 0; - strcat_s(command, CMD_SIZE, "bin\\subwcrev.exe"); - if (_stat(command+1, &st) < 0) - /* subwcrev.exe not part of the release */ - return 0; - strcat_s(command, CMD_SIZE, "\" .. ..\\Modules\\getbuildinfo.c \""); - strcat_s(command, CMD_SIZE, tmppath); /* quoted tmppath */ - strcat_s(command, CMD_SIZE, "getbuildinfo2.c\""); - puts(command); fflush(stdout); - if (system(command) < 0) - return 0; - return 1; -} - -const char DELIMS[] = { " \n" }; - -int get_mercurial_info(char * hgbranch, char * hgtag, char * hgrev, int size) -{ - int result = 0; - char filename[CMD_SIZE]; - char cmdline[CMD_SIZE]; - - strcpy_s(filename, CMD_SIZE, "tmpXXXXXX"); - if (_mktemp_s(filename, CMD_SIZE) == 0) { - int rc; - - strcpy_s(cmdline, CMD_SIZE, "hg id -bit > "); - strcat_s(cmdline, CMD_SIZE, filename); - rc = system(cmdline); - if (rc == 0) { - FILE * fp; - - if (fopen_s(&fp, filename, "r") == 0) { - char * cp = fgets(cmdline, CMD_SIZE, fp); - - if (cp) { - char * context = NULL; - char * tp = strtok_s(cp, DELIMS, &context); - if (tp) { - strcpy_s(hgrev, size, tp); - tp = strtok_s(NULL, DELIMS, &context); - if (tp) { - strcpy_s(hgbranch, size, tp); - tp = strtok_s(NULL, DELIMS, &context); - if (tp) { - strcpy_s(hgtag, size, tp); - result = 1; - } - } - } - } - fclose(fp); - } - } - _unlink(filename); - } - return result; -} - -int main(int argc, char*argv[]) -{ - char command[CMD_SIZE] = "cl.exe -c -D_WIN32 -DUSE_DL_EXPORT -D_WINDOWS -DWIN32 -D_WINDLL "; - char tmppath[CMD_SIZE] = ""; - int do_unlink, result; - char *tmpdir = NULL; - if (argc <= 2 || argc > 3) { - fprintf(stderr, "make_buildinfo $(ConfigurationName) [tmpdir]\n"); - return EXIT_FAILURE; - } - if (strcmp(argv[1], "Release") == 0) { - strcat_s(command, CMD_SIZE, "-MD "); - } - else if (strcmp(argv[1], "Debug") == 0) { - strcat_s(command, CMD_SIZE, "-D_DEBUG -MDd "); - } - else if (strcmp(argv[1], "ReleaseItanium") == 0) { - strcat_s(command, CMD_SIZE, "-MD /USECL:MS_ITANIUM "); - } - else if (strcmp(argv[1], "ReleaseAMD64") == 0) { - strcat_s(command, CMD_SIZE, "-MD "); - strcat_s(command, CMD_SIZE, "-MD /USECL:MS_OPTERON "); - } - else { - fprintf(stderr, "unsupported configuration %s\n", argv[1]); - return EXIT_FAILURE; - } - if (argc > 2) { - tmpdir = argv[2]; - strcat_s(tmppath, _countof(tmppath), tmpdir); - /* Hack fix for bad command line: If the command is issued like this: - * $(SolutionDir)make_buildinfo.exe" Debug "$(IntDir)" - * we will get a trailing quote because IntDir ends with a backslash that then - * escapes the final ". To simplify the life for developers, catch that problem - * here by cutting it off. - * The proper command line, btw is: - * $(SolutionDir)make_buildinfo.exe" Debug "$(IntDir)\" - * Hooray for command line parsing on windows. - */ - if (strlen(tmppath) > 0 && tmppath[strlen(tmppath)-1] == '"') - tmppath[strlen(tmppath)-1] = '\0'; - strcat_s(tmppath, _countof(tmppath), "\\"); - } - - if ((do_unlink = make_buildinfo2(tmppath))) { - strcat_s(command, CMD_SIZE, "\""); - strcat_s(command, CMD_SIZE, tmppath); - strcat_s(command, CMD_SIZE, "getbuildinfo2.c\" -DSUBWCREV "); - } - else { - char hgtag[CMD_SIZE]; - char hgbranch[CMD_SIZE]; - char hgrev[CMD_SIZE]; - - if (get_mercurial_info(hgbranch, hgtag, hgrev, CMD_SIZE)) { - strcat_s(command, CMD_SIZE, "-DHGBRANCH=\\\""); - strcat_s(command, CMD_SIZE, hgbranch); - strcat_s(command, CMD_SIZE, "\\\""); - - strcat_s(command, CMD_SIZE, " -DHGTAG=\\\""); - strcat_s(command, CMD_SIZE, hgtag); - strcat_s(command, CMD_SIZE, "\\\""); - - strcat_s(command, CMD_SIZE, " -DHGVERSION=\\\""); - strcat_s(command, CMD_SIZE, hgrev); - strcat_s(command, CMD_SIZE, "\\\" "); - } - strcat_s(command, CMD_SIZE, "..\\Modules\\getbuildinfo.c"); - } - strcat_s(command, CMD_SIZE, " -Fo\""); - strcat_s(command, CMD_SIZE, tmppath); - strcat_s(command, CMD_SIZE, "getbuildinfo.o\" -I..\\Include -I..\\PC"); - puts(command); fflush(stdout); - result = system(command); - if (do_unlink) { - command[0] = '\0'; - strcat_s(command, CMD_SIZE, "\""); - strcat_s(command, CMD_SIZE, tmppath); - strcat_s(command, CMD_SIZE, "getbuildinfo2.c\""); - _unlink(command); - } - if (result < 0) - return EXIT_FAILURE; - return 0; -} diff --git a/PCbuild/make_buildinfo.vcxproj b/PCbuild/make_buildinfo.vcxproj deleted file mode 100644 index eee7f91eac8c..000000000000 --- a/PCbuild/make_buildinfo.vcxproj +++ /dev/null @@ -1,52 +0,0 @@ - - - - - Release - Win32 - - - - {C73F0EC1-358B-4177-940F-0846AC8B04CD} - make_buildinfo - Win32Proj - - - - Application - NotSet - - - - - - - - - - - - <_ProjectFileVersion>10.0.40219.1 - AllRules.ruleset - - - - - - Disabled - OnlyExplicitInline - _CONSOLE;%(PreprocessorDefinitions) - MultiThreaded - - - $(OutDir)make_buildinfo.exe - Console - - - - - - - - - \ No newline at end of file diff --git a/PCbuild/make_buildinfo.vcxproj.filters b/PCbuild/make_buildinfo.vcxproj.filters deleted file mode 100644 index 2227f8ce7bd7..000000000000 --- a/PCbuild/make_buildinfo.vcxproj.filters +++ /dev/null @@ -1,14 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx - - - - - Source Files - - - \ No newline at end of file diff --git a/PCbuild/make_versioninfo.vcxproj b/PCbuild/make_versioninfo.vcxproj deleted file mode 100644 index 9cf507bbb6a8..000000000000 --- a/PCbuild/make_versioninfo.vcxproj +++ /dev/null @@ -1,200 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {F0E0541E-F17D-430B-97C4-93ADF0DD284E} - make_versioninfo - - - - Application - false - NotSet - - - Application - false - MultiByte - - - Application - - - Application - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.40219.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - - Build PC/pythonnt_rc(_d).h - cd $(SolutionDir) -make_versioninfo.exe > ..\PC\pythonnt_rc.h - - $(SolutionDir)..\PC\pythonnt_rc.h;%(Outputs) - $(SolutionDir)make_versioninfo.exe - - - MaxSpeed - OnlyExplicitInline - true - %(AdditionalIncludeDirectories) - _CONSOLE;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - Default - - - $(SolutionDir)make_versioninfo.exe - Console - 0x1d000000 - - - - - - - - - - Build PC/pythonnt_rc(_d).h - cd $(SolutionDir) -make_versioninfo.exe > ..\PC\pythonnt_rc.h - - $(SolutionDir)..\PC\pythonnt_rc.h;%(Outputs) - - - MaxSpeed - OnlyExplicitInline - true - _CONSOLE;%(PreprocessorDefinitions) - - - $(SolutionDir)make_versioninfo.exe - - - cd $(SolutionDir) -make_versioninfo.exe > ..\PC\python_nt.h - - - - - - Build PC/pythonnt_rc(_d).h - cd $(SolutionDir) -make_versioninfo_d.exe > ..\PC\pythonnt_rc_d.h - - $(SolutionDir)..\PC\pythonnt_rc_d.h;%(Outputs) - $(SolutionDir)make_versioninfo_d.exe - - - Disabled - OnlyExplicitInline - false - %(AdditionalIncludeDirectories) - _CONSOLE;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - Default - - - $(SolutionDir)make_versioninfo_d.exe - Console - 0x1d000000 - - - - - - - - - Build PC/pythonnt_rc(_d).h - cd $(SolutionDir) -make_versioninfo_d.exe > ..\PC\pythonnt_rc_d.h - - $(SolutionDir)..\PC\pythonnt_rc_d.h;%(Outputs) - - - X64 - - - Disabled - OnlyExplicitInline - false - _CONSOLE;%(PreprocessorDefinitions) - - - $(SolutionDir)make_versioninfo_d.exe - MachineX64 - - - cd $(SolutionDir) -make_versioninfo_d.exe > ..\PC\python_nt_d.h - - - - - - - - - - \ No newline at end of file diff --git a/PCbuild/make_versioninfo.vcxproj.filters b/PCbuild/make_versioninfo.vcxproj.filters deleted file mode 100644 index 96c0434e8776..000000000000 --- a/PCbuild/make_versioninfo.vcxproj.filters +++ /dev/null @@ -1,13 +0,0 @@ - - - - - {e4180954-c3a5-4749-b9a4-31b804ee4fa8} - - - - - Source Files - - - \ No newline at end of file diff --git a/PCbuild/openssl.props b/PCbuild/openssl.props new file mode 100644 index 000000000000..356159eca15e --- /dev/null +++ b/PCbuild/openssl.props @@ -0,0 +1,75 @@ + + + + + + StaticLibrary + $(opensslDir)tmp\$(ArchName)_$(Configuration)\$(ProjectName)\ + $(opensslDir)tmp\$(ArchName)\$(ProjectName)\ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_PreprocessorDefinitionList>@(PreprocessorDefinitions) + + + + + + 4244;4267 + $(opensslDir);$(opensslDir)include;$(opensslDir)crypto;$(opensslDir)crypto\asn1;$(opensslDir)crypto\evp;$(opensslDir)crypto\modes + $(_PreprocessorDefinitionList);%(PreprocessorDefinitions) + + + + + + nasm.exe -f win32 + nasm.exe -f win64 -DNEAR -Ox -g + + + + + + + + + + + \ No newline at end of file diff --git a/PCbuild/pcbuild.proj b/PCbuild/pcbuild.proj new file mode 100644 index 000000000000..404b8d4ebfe1 --- /dev/null +++ b/PCbuild/pcbuild.proj @@ -0,0 +1,84 @@ + + + + {CC9B93A2-439D-4058-9D29-6DCF43774405} + Win32 + Release + true + true + true + + + + + $(Platform) + $(Configuration) + + Build + Clean + CleanAll + true + + + + + + + false + + + + + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PCbuild/pcbuild.sln b/PCbuild/pcbuild.sln index e431c914064a..7b37635e3302 100644 --- a/PCbuild/pcbuild.sln +++ b/PCbuild/pcbuild.sln @@ -1,5 +1,7 @@ -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.30501.0 +MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{553EC33E-9816-4996-A660-5D6186A0B0B3}" ProjectSection(SolutionItems) = preProject ..\Modules\getbuildinfo.c = ..\Modules\getbuildinfo.c @@ -8,14 +10,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "python", "python.vcxproj", "{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "make_versioninfo", "make_versioninfo.vcxproj", "{F0E0541E-F17D-430B-97C4-93ADF0DD284E}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythoncore", "pythoncore.vcxproj", "{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythonw", "pythonw.vcxproj", "{F4229CC3-873C-49AE-9729-DD308ED4CD4A}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "make_buildinfo", "make_buildinfo.vcxproj", "{C73F0EC1-358B-4177-940F-0846AC8B04CD}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winsound", "winsound.vcxproj", "{28B5D777-DDF2-4B6B-B34F-31D938813856}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_decimal", "_decimal.vcxproj", "{0E9791DB-593A-465F-98BC-681011311617}" @@ -50,7 +48,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unicodedata", "unicodedata. EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pyexpat", "pyexpat.vcxproj", "{D06B6426-4762-44CC-8BAD-D79052507F2F}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bdist_wininst", "bdist_wininst.vcxproj", "{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bdist_wininst", "..\PC\bdist_wininst\bdist_wininst.vcxproj", "{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_hashlib", "_hashlib.vcxproj", "{447F05A8-F581-4CAC-A466-5AC7936E207E}" EndProject @@ -58,10 +56,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sqlite3", "sqlite3.vcxproj" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_multiprocessing", "_multiprocessing.vcxproj", "{9E48B300-37D1-11DD-8C41-005056C00008}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ssl", "ssl.vcxproj", "{E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kill_python", "kill_python.vcxproj", "{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "python3dll", "python3dll.vcxproj", "{885D4898-D08D-4091-9C40-C700CFE3FC5A}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xxlimited", "xxlimited.vcxproj", "{F749B822-B489-4CA5-A3AD-CE078F5F338A}" @@ -74,12 +68,20 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pywlauncher", "pywlauncher. EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_freeze_importlib", "_freeze_importlib.vcxproj", "{19C0C13F-47CA-4432-AFF3-799A296A4DDC}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_sha3", "_sha3.vcxproj", "{254A0C05-6696-4B08-8CB2-EF7D533AEE01}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_overlapped", "_overlapped.vcxproj", "{EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testembed", "_testembed.vcxproj", "{6DAC66D9-E703-4624-BE03-49112AB5AA62}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tcl", "tcl.vcxproj", "{B5FD6F1D-129E-4BFF-9340-03606FAC7283}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tix", "tix.vcxproj", "{C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tk", "tk.vcxproj", "{7E85ECCF-A72C-4DA4-9E52-884508E80BA1}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libeay", "libeay.vcxproj", "{E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ssleay", "ssleay.vcxproj", "{10615B24-73BF-4EFA-93AA-236916321317}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -108,22 +110,6 @@ Global {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|Win32.Build.0 = Release|Win32 {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|x64.ActiveCfg = Release|x64 {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|x64.Build.0 = Release|x64 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Debug|Win32.ActiveCfg = Debug|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Debug|Win32.Build.0 = Debug|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Debug|x64.ActiveCfg = Debug|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Debug|x64.Build.0 = Debug|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGInstrument|Win32.ActiveCfg = Release|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGInstrument|Win32.Build.0 = Release|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGInstrument|x64.ActiveCfg = Release|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGInstrument|x64.Build.0 = Release|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGUpdate|Win32.ActiveCfg = Release|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGUpdate|Win32.Build.0 = Release|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGUpdate|x64.ActiveCfg = Release|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGUpdate|x64.Build.0 = Release|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Release|Win32.ActiveCfg = Release|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Release|Win32.Build.0 = Release|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Release|x64.ActiveCfg = Release|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Release|x64.Build.0 = Release|Win32 {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|Win32.ActiveCfg = Debug|Win32 {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|Win32.Build.0 = Debug|Win32 {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|x64.ActiveCfg = Debug|x64 @@ -144,34 +130,18 @@ Global {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|Win32.Build.0 = Debug|Win32 {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|x64.ActiveCfg = Debug|x64 {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|x64.Build.0 = Debug|x64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|Win32.Build.0 = Release|Win32 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|x64.ActiveCfg = Release|x64 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|x64.Build.0 = Release|x64 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|Win32.Build.0 = Release|Win32 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|x64.ActiveCfg = Release|x64 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|x64.Build.0 = Release|x64 {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|Win32.ActiveCfg = Release|Win32 {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|Win32.Build.0 = Release|Win32 {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|x64.ActiveCfg = Release|x64 {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|x64.Build.0 = Release|x64 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.Debug|Win32.ActiveCfg = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.Debug|Win32.Build.0 = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.Debug|x64.ActiveCfg = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.Debug|x64.Build.0 = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGInstrument|Win32.ActiveCfg = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGInstrument|Win32.Build.0 = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGInstrument|x64.ActiveCfg = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGInstrument|x64.Build.0 = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGUpdate|Win32.ActiveCfg = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGUpdate|Win32.Build.0 = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGUpdate|x64.ActiveCfg = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGUpdate|x64.Build.0 = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.Release|Win32.ActiveCfg = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.Release|Win32.Build.0 = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.Release|x64.ActiveCfg = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.Release|x64.Build.0 = Release|Win32 {28B5D777-DDF2-4B6B-B34F-31D938813856}.Debug|Win32.ActiveCfg = Debug|Win32 {28B5D777-DDF2-4B6B-B34F-31D938813856}.Debug|Win32.Build.0 = Debug|Win32 {28B5D777-DDF2-4B6B-B34F-31D938813856}.Debug|x64.ActiveCfg = Debug|x64 @@ -224,14 +194,14 @@ Global {9EC7190A-249F-4180-A900-548FDCF3055F}.Debug|Win32.Build.0 = Debug|Win32 {9EC7190A-249F-4180-A900-548FDCF3055F}.Debug|x64.ActiveCfg = Debug|x64 {9EC7190A-249F-4180-A900-548FDCF3055F}.Debug|x64.Build.0 = Debug|x64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|Win32.Build.0 = Release|Win32 + {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|x64.ActiveCfg = Release|x64 + {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|x64.Build.0 = Release|x64 + {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|Win32.Build.0 = Release|Win32 + {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|x64.ActiveCfg = Release|x64 + {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|x64.Build.0 = Release|x64 {9EC7190A-249F-4180-A900-548FDCF3055F}.Release|Win32.ActiveCfg = Release|Win32 {9EC7190A-249F-4180-A900-548FDCF3055F}.Release|Win32.Build.0 = Release|Win32 {9EC7190A-249F-4180-A900-548FDCF3055F}.Release|x64.ActiveCfg = Release|x64 @@ -336,14 +306,14 @@ Global {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Debug|Win32.Build.0 = Debug|Win32 {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Debug|x64.ActiveCfg = Debug|x64 {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Debug|x64.Build.0 = Debug|x64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|Win32.Build.0 = Release|Win32 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|x64.ActiveCfg = Release|x64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|x64.Build.0 = Release|x64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|Win32.Build.0 = Release|Win32 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|x64.ActiveCfg = Release|x64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|x64.Build.0 = Release|x64 {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Release|Win32.ActiveCfg = Release|Win32 {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Release|Win32.Build.0 = Release|Win32 {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Release|x64.ActiveCfg = Release|x64 @@ -444,7 +414,7 @@ Global {D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|Win32.Build.0 = Release|Win32 {D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|x64.ActiveCfg = Release|x64 {D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|x64.Build.0 = Release|x64 - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Debug|Win32.ActiveCfg = Release|Win32 + {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Debug|Win32.ActiveCfg = Debug|Win32 {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Debug|x64.ActiveCfg = Release|x64 {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGInstrument|Win32.ActiveCfg = Release|Win32 {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGInstrument|x64.ActiveCfg = Release|x64 @@ -500,49 +470,18 @@ Global {9E48B300-37D1-11DD-8C41-005056C00008}.Release|Win32.Build.0 = Release|Win32 {9E48B300-37D1-11DD-8C41-005056C00008}.Release|x64.ActiveCfg = Release|x64 {9E48B300-37D1-11DD-8C41-005056C00008}.Release|x64.Build.0 = Release|x64 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Debug|Win32.ActiveCfg = Debug|Win32 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Debug|Win32.Build.0 = Debug|Win32 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Debug|x64.ActiveCfg = Debug|x64 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Debug|x64.Build.0 = Debug|x64 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Release|Win32.ActiveCfg = Release|Win32 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Release|Win32.Build.0 = Release|Win32 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Release|x64.ActiveCfg = Release|x64 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Release|x64.Build.0 = Release|x64 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Debug|Win32.ActiveCfg = Debug|Win32 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Debug|Win32.Build.0 = Debug|Win32 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Debug|x64.ActiveCfg = Debug|x64 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Debug|x64.Build.0 = Debug|x64 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGInstrument|Win32.ActiveCfg = Release|Win32 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGInstrument|Win32.Build.0 = Release|Win32 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGInstrument|x64.ActiveCfg = Release|x64 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGInstrument|x64.Build.0 = Release|x64 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGUpdate|Win32.ActiveCfg = Release|Win32 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGUpdate|Win32.Build.0 = Release|Win32 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGUpdate|x64.ActiveCfg = Release|x64 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGUpdate|x64.Build.0 = Release|x64 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Release|Win32.ActiveCfg = Release|Win32 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Release|Win32.Build.0 = Release|Win32 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Release|x64.ActiveCfg = Release|x64 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Release|x64.Build.0 = Release|x64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|Win32.ActiveCfg = PGInstrument|Win32 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|x64.ActiveCfg = PGUpdate|x64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|x64.Build.0 = PGUpdate|x64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|Win32.ActiveCfg = Debug|Win32 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|Win32.Build.0 = Debug|Win32 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|x64.ActiveCfg = Debug|x64 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|x64.Build.0 = Debug|x64 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|Win32.ActiveCfg = Debug|Win32 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|Win32.Build.0 = Debug|Win32 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|x64.ActiveCfg = Debug|x64 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|x64.Build.0 = Debug|x64 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|Win32.ActiveCfg = Debug|Win32 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|Win32.Build.0 = Debug|Win32 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|x64.ActiveCfg = Debug|x64 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|x64.Build.0 = Debug|x64 {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|Win32.ActiveCfg = Release|Win32 {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|Win32.Build.0 = Release|Win32 {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|x64.ActiveCfg = Release|x64 @@ -565,14 +504,14 @@ Global {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Debug|Win32.Build.0 = Debug|Win32 {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Debug|x64.ActiveCfg = Debug|x64 {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Debug|x64.Build.0 = Debug|x64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|Win32.Build.0 = Release|Win32 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|x64.ActiveCfg = Release|x64 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|x64.Build.0 = Release|x64 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|Win32.Build.0 = Release|Win32 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|x64.ActiveCfg = Release|x64 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|x64.Build.0 = Release|x64 {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Release|Win32.ActiveCfg = Release|Win32 {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Release|Win32.Build.0 = Release|Win32 {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Release|x64.ActiveCfg = Release|x64 @@ -581,34 +520,34 @@ Global {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Debug|Win32.Build.0 = Debug|Win32 {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Debug|x64.ActiveCfg = Debug|x64 {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Debug|x64.Build.0 = Debug|x64 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|x64.ActiveCfg = PGInstrument|Win32 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|x64.Build.0 = PGInstrument|Win32 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|x64.ActiveCfg = PGUpdate|Win32 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|x64.Build.0 = PGUpdate|Win32 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|Win32.Build.0 = Release|Win32 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|x64.ActiveCfg = Release|x64 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|x64.Build.0 = Release|x64 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|Win32.Build.0 = Release|Win32 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|x64.ActiveCfg = Release|x64 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|x64.Build.0 = Release|x64 {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|Win32.ActiveCfg = Release|Win32 {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|Win32.Build.0 = Release|Win32 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|x64.ActiveCfg = Release|Win32 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|x64.Build.0 = Release|Win32 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|x64.ActiveCfg = Release|x64 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|x64.Build.0 = Release|x64 {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|Win32.ActiveCfg = Debug|Win32 {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|Win32.Build.0 = Debug|Win32 {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|x64.ActiveCfg = Debug|x64 {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|x64.Build.0 = Debug|x64 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|x64.ActiveCfg = PGInstrument|Win32 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|x64.Build.0 = PGInstrument|Win32 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|x64.ActiveCfg = PGUpdate|Win32 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|x64.Build.0 = PGUpdate|Win32 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|Win32.Build.0 = Release|Win32 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|x64.ActiveCfg = Release|x64 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|x64.Build.0 = Release|x64 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|Win32.Build.0 = Release|Win32 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|x64.ActiveCfg = Release|x64 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|x64.Build.0 = Release|x64 {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|Win32.ActiveCfg = Release|Win32 {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|Win32.Build.0 = Release|Win32 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|x64.ActiveCfg = Release|Win32 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|x64.Build.0 = Release|Win32 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|x64.ActiveCfg = Release|x64 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|x64.Build.0 = Release|x64 {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Debug|Win32.ActiveCfg = Debug|Win32 {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Debug|x64.ActiveCfg = Debug|x64 {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGInstrument|Win32.ActiveCfg = Release|Win32 @@ -616,39 +555,9 @@ Global {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGUpdate|Win32.ActiveCfg = Release|Win32 {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGUpdate|x64.ActiveCfg = Release|Win32 {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Release|Win32.ActiveCfg = Release|Win32 + {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Release|Win32.Build.0 = Release|Win32 {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Release|x64.ActiveCfg = Release|x64 - {254A0C05-6696-4B08-8CB2-EF7D533AEE01}.Debug|Win32.ActiveCfg = Debug|Win32 - {254A0C05-6696-4B08-8CB2-EF7D533AEE01}.Debug|Win32.Build.0 = Debug|Win32 - {254A0C05-6696-4B08-8CB2-EF7D533AEE01}.Debug|x64.ActiveCfg = Debug|x64 - {254A0C05-6696-4B08-8CB2-EF7D533AEE01}.Debug|x64.Build.0 = Debug|x64 - {254A0C05-6696-4B08-8CB2-EF7D533AEE01}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {254A0C05-6696-4B08-8CB2-EF7D533AEE01}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {254A0C05-6696-4B08-8CB2-EF7D533AEE01}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {254A0C05-6696-4B08-8CB2-EF7D533AEE01}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {254A0C05-6696-4B08-8CB2-EF7D533AEE01}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {254A0C05-6696-4B08-8CB2-EF7D533AEE01}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {254A0C05-6696-4B08-8CB2-EF7D533AEE01}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {254A0C05-6696-4B08-8CB2-EF7D533AEE01}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {254A0C05-6696-4B08-8CB2-EF7D533AEE01}.Release|Win32.ActiveCfg = Release|Win32 - {254A0C05-6696-4B08-8CB2-EF7D533AEE01}.Release|Win32.Build.0 = Release|Win32 - {254A0C05-6696-4B08-8CB2-EF7D533AEE01}.Release|x64.ActiveCfg = Release|x64 - {254A0C05-6696-4B08-8CB2-EF7D533AEE01}.Release|x64.Build.0 = Release|x64 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Debug|Win32.ActiveCfg = Debug|Win32 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Debug|Win32.Build.0 = Debug|Win32 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Debug|x64.ActiveCfg = Debug|x64 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Debug|x64.Build.0 = Debug|x64 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Release|Win32.ActiveCfg = Release|Win32 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Release|Win32.Build.0 = Release|Win32 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Release|x64.ActiveCfg = Release|x64 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Release|x64.Build.0 = Release|x64 + {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Release|x64.Build.0 = Release|x64 {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Debug|Win32.ActiveCfg = Debug|Win32 {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Debug|Win32.Build.0 = Debug|Win32 {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Debug|x64.ActiveCfg = Debug|x64 @@ -665,6 +574,100 @@ Global {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Release|Win32.Build.0 = Release|Win32 {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Release|x64.ActiveCfg = Release|x64 {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Release|x64.Build.0 = Release|x64 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Debug|Win32.ActiveCfg = Debug|Win32 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Debug|Win32.Build.0 = Debug|Win32 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Debug|x64.ActiveCfg = Debug|x64 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Debug|x64.Build.0 = Debug|x64 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGInstrument|x64.ActiveCfg = Release|x64 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGUpdate|Win32.Build.0 = Release|Win32 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGUpdate|x64.ActiveCfg = Release|x64 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGUpdate|x64.Build.0 = Release|x64 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Release|Win32.ActiveCfg = Release|Win32 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Release|Win32.Build.0 = Release|Win32 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Release|x64.ActiveCfg = Release|x64 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Release|x64.Build.0 = Release|x64 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.Debug|Win32.ActiveCfg = Debug|Win32 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.Debug|Win32.Build.0 = Debug|Win32 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.Debug|x64.ActiveCfg = Debug|x64 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.Debug|x64.Build.0 = Debug|x64 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.PGInstrument|Win32.Build.0 = Release|Win32 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.PGInstrument|x64.ActiveCfg = Release|x64 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.PGInstrument|x64.Build.0 = Release|x64 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.PGUpdate|Win32.Build.0 = Release|Win32 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.PGUpdate|x64.ActiveCfg = Release|x64 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.PGUpdate|x64.Build.0 = Release|x64 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.Release|Win32.ActiveCfg = Release|Win32 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.Release|Win32.Build.0 = Release|Win32 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.Release|x64.ActiveCfg = Release|x64 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.Release|x64.Build.0 = Release|x64 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.Debug|Win32.ActiveCfg = Debug|Win32 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.Debug|Win32.Build.0 = Debug|Win32 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.Debug|x64.ActiveCfg = Debug|x64 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.Debug|x64.Build.0 = Debug|x64 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.PGInstrument|Win32.Build.0 = Release|Win32 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.PGInstrument|x64.ActiveCfg = Release|x64 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.PGInstrument|x64.Build.0 = Release|x64 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.PGUpdate|Win32.Build.0 = Release|Win32 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.PGUpdate|x64.ActiveCfg = Release|x64 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.PGUpdate|x64.Build.0 = Release|x64 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.Release|Win32.ActiveCfg = Release|Win32 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.Release|Win32.Build.0 = Release|Win32 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.Release|x64.ActiveCfg = Release|x64 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.Release|x64.Build.0 = Release|x64 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.Debug|Win32.ActiveCfg = Debug|Win32 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.Debug|Win32.Build.0 = Debug|Win32 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.Debug|x64.ActiveCfg = Debug|x64 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.Debug|x64.Build.0 = Debug|x64 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.PGInstrument|Win32.Build.0 = Release|Win32 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.PGInstrument|x64.ActiveCfg = Release|x64 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.PGInstrument|x64.Build.0 = Release|x64 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.PGUpdate|Win32.Build.0 = Release|Win32 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.PGUpdate|x64.ActiveCfg = Release|x64 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.PGUpdate|x64.Build.0 = Release|x64 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.Release|Win32.ActiveCfg = Release|Win32 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.Release|Win32.Build.0 = Release|Win32 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.Release|x64.ActiveCfg = Release|x64 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.Release|x64.Build.0 = Release|x64 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Debug|Win32.ActiveCfg = Debug|Win32 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Debug|Win32.Build.0 = Debug|Win32 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Debug|x64.ActiveCfg = Debug|x64 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Debug|x64.Build.0 = Debug|x64 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGInstrument|Win32.Build.0 = Release|Win32 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGInstrument|x64.ActiveCfg = Release|x64 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGInstrument|x64.Build.0 = Release|x64 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGUpdate|Win32.Build.0 = Release|Win32 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGUpdate|x64.ActiveCfg = Release|x64 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGUpdate|x64.Build.0 = Release|x64 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Release|Win32.ActiveCfg = Release|Win32 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Release|Win32.Build.0 = Release|Win32 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Release|x64.ActiveCfg = Release|x64 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Release|x64.Build.0 = Release|x64 + {10615B24-73BF-4EFA-93AA-236916321317}.Debug|Win32.ActiveCfg = Debug|Win32 + {10615B24-73BF-4EFA-93AA-236916321317}.Debug|Win32.Build.0 = Debug|Win32 + {10615B24-73BF-4EFA-93AA-236916321317}.Debug|x64.ActiveCfg = Debug|x64 + {10615B24-73BF-4EFA-93AA-236916321317}.Debug|x64.Build.0 = Debug|x64 + {10615B24-73BF-4EFA-93AA-236916321317}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {10615B24-73BF-4EFA-93AA-236916321317}.PGInstrument|Win32.Build.0 = Release|Win32 + {10615B24-73BF-4EFA-93AA-236916321317}.PGInstrument|x64.ActiveCfg = Release|x64 + {10615B24-73BF-4EFA-93AA-236916321317}.PGInstrument|x64.Build.0 = Release|x64 + {10615B24-73BF-4EFA-93AA-236916321317}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {10615B24-73BF-4EFA-93AA-236916321317}.PGUpdate|Win32.Build.0 = Release|Win32 + {10615B24-73BF-4EFA-93AA-236916321317}.PGUpdate|x64.ActiveCfg = Release|x64 + {10615B24-73BF-4EFA-93AA-236916321317}.PGUpdate|x64.Build.0 = Release|x64 + {10615B24-73BF-4EFA-93AA-236916321317}.Release|Win32.ActiveCfg = Release|Win32 + {10615B24-73BF-4EFA-93AA-236916321317}.Release|Win32.Build.0 = Release|Win32 + {10615B24-73BF-4EFA-93AA-236916321317}.Release|x64.ActiveCfg = Release|x64 + {10615B24-73BF-4EFA-93AA-236916321317}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/PCbuild/pginstrument.props b/PCbuild/pginstrument.props deleted file mode 100644 index 5584995d2008..000000000000 --- a/PCbuild/pginstrument.props +++ /dev/null @@ -1,38 +0,0 @@ - - - - $(SolutionDir)$(Platform)-pgi\ - - - <_ProjectFileVersion>10.0.30319.1 - $(OutDirPGI)\ - $(SolutionDir)$(PlatformName)-temp-pgi\$(ProjectName)\ - - - - MaxSpeed - OnlyExplicitInline - false - Size - true - false - true - true - - - false - - - true - false - PGInstrument - $(SolutionDir)$(Platform)-pgi\$(TargetName).pgd - $(OutDirPGI)\$(TargetName).lib - - - - - $(OutDirPGI) - - - diff --git a/PCbuild/pgupdate.props b/PCbuild/pgupdate.props deleted file mode 100644 index d775a02c73a9..000000000000 --- a/PCbuild/pgupdate.props +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - <_ProjectFileVersion>10.0.30319.1 - $(SolutionDir)$(PlatformName)-pgo\ - - - - %(AdditionalManifestDependencies) - PGUpdate - $(OutDir)$(TargetName).lib - - - \ No newline at end of file diff --git a/PCbuild/build_ssl.bat b/PCbuild/prepare_ssl.bat similarity index 54% rename from PCbuild/build_ssl.bat rename to PCbuild/prepare_ssl.bat index 805d77a6dc76..cb0650086390 100644 --- a/PCbuild/build_ssl.bat +++ b/PCbuild/prepare_ssl.bat @@ -1,12 +1,12 @@ @echo off if not defined HOST_PYTHON ( if %1 EQU Debug ( + shift set HOST_PYTHON=python_d.exe - if not exist python34_d.dll exit 1 + if not exist python35_d.dll exit 1 ) ELSE ( set HOST_PYTHON=python.exe - if not exist python34.dll exit 1 + if not exist python35.dll exit 1 ) ) -%HOST_PYTHON% build_ssl.py %1 %2 %3 - +%HOST_PYTHON% prepare_ssl.py %1 diff --git a/PCbuild/prepare_ssl.py b/PCbuild/prepare_ssl.py new file mode 100644 index 000000000000..199c4efe2545 --- /dev/null +++ b/PCbuild/prepare_ssl.py @@ -0,0 +1,240 @@ +# Script for preparing OpenSSL for building on Windows. +# Uses Perl to create nmake makefiles and otherwise prepare the way +# for building on 32 or 64 bit platforms. + +# Script originally authored by Mark Hammond. +# Major revisions by: +# Martin v. Löwis +# Christian Heimes +# Zachary Ware + +# THEORETICALLY, you can: +# * Unpack the latest OpenSSL release where $(opensslDir) in +# PCbuild\pyproject.props expects it to be. +# * Install ActivePerl and ensure it is somewhere on your path. +# * Run this script with the OpenSSL source dir as the only argument. +# +# it should configure OpenSSL such that it is ready to be built by +# ssl.vcxproj on 32 or 64 bit platforms. + +import os +import re +import sys +import shutil +import subprocess + +# Find all "foo.exe" files on the PATH. +def find_all_on_path(filename, extras = None): + entries = os.environ["PATH"].split(os.pathsep) + ret = [] + for p in entries: + fname = os.path.abspath(os.path.join(p, filename)) + if os.path.isfile(fname) and fname not in ret: + ret.append(fname) + if extras: + for p in extras: + fname = os.path.abspath(os.path.join(p, filename)) + if os.path.isfile(fname) and fname not in ret: + ret.append(fname) + return ret + +# Find a suitable Perl installation for OpenSSL. +# cygwin perl does *not* work. ActivePerl does. +# Being a Perl dummy, the simplest way I can check is if the "Win32" package +# is available. +def find_working_perl(perls): + for perl in perls: + try: + subprocess.check_output([perl, "-e", "use Win32;"]) + except subprocess.CalledProcessError: + continue + else: + return perl + + if perls: + print("The following perl interpreters were found:") + for p in perls: + print(" ", p) + print(" None of these versions appear suitable for building OpenSSL") + else: + print("NO perl interpreters were found on this machine at all!") + print(" Please install ActivePerl and ensure it appears on your path") + +def create_makefile64(makefile, m32): + """Create and fix makefile for 64bit + + Replace 32 with 64bit directories + """ + if not os.path.isfile(m32): + return + with open(m32) as fin: + with open(makefile, 'w') as fout: + for line in fin: + line = line.replace("=tmp32", "=tmp64") + line = line.replace("=out32", "=out64") + line = line.replace("=inc32", "=inc64") + # force 64 bit machine + line = line.replace("MKLIB=lib", "MKLIB=lib /MACHINE:X64") + line = line.replace("LFLAGS=", "LFLAGS=/MACHINE:X64 ") + # don't link against the lib on 64bit systems + line = line.replace("bufferoverflowu.lib", "") + fout.write(line) + os.unlink(m32) + +def create_asms(makefile): + #create a custom makefile out of the provided one + asm_makefile = os.path.splitext(makefile)[0] + '.asm.mak' + with open(makefile) as fin: + with open(asm_makefile, 'w') as fout: + for line in fin: + # Keep everything up to the install target (it's convenient) + if line.startswith('install: all'): + break + else: + fout.write(line) + asms = [] + for line in fin: + if '.asm' in line and line.strip().endswith('.pl'): + asms.append(line.split(':')[0]) + while line.strip(): + fout.write(line) + line = next(fin) + fout.write('\n') + + fout.write('asms: $(TMP_D) ') + fout.write(' '.join(asms)) + fout.write('\n') + + os.system('nmake /f {} PERL=perl asms'.format(asm_makefile)) + os.unlink(asm_makefile) + + + +def fix_makefile(makefile): + """Fix some stuff in all makefiles + """ + if not os.path.isfile(makefile): + return + with open(makefile) as fin: + lines = fin.readlines() + with open(makefile, 'w') as fout: + for line in lines: + if line.startswith("PERL="): + continue + if line.startswith("CP="): + line = "CP=copy\n" + if line.startswith("MKDIR="): + line = "MKDIR=mkdir\n" + if line.startswith("CFLAG="): + line = line.strip() + for algo in ("RC5", "MDC2", "IDEA"): + noalgo = " -DOPENSSL_NO_%s" % algo + if noalgo not in line: + line = line + noalgo + line = line + '\n' + fout.write(line) + +def run_configure(configure, do_script): + print("perl Configure "+configure+" no-idea no-mdc2") + os.system("perl Configure "+configure+" no-idea no-mdc2") + print(do_script) + os.system(do_script) + +def cmp(f1, f2): + bufsize = 1024 * 8 + with open(f1, 'rb') as fp1, open(f2, 'rb') as fp2: + while True: + b1 = fp1.read(bufsize) + b2 = fp2.read(bufsize) + if b1 != b2: + return False + if not b1: + return True + +def copy(src, dst): + if os.path.isfile(dst) and cmp(src, dst): + return + shutil.copy(src, dst) + +def prep(arch): + if arch == "x86": + configure = "VC-WIN32" + do_script = "ms\\do_nasm" + makefile="ms\\nt.mak" + m32 = makefile + dirsuffix = "32" + elif arch == "amd64": + configure = "VC-WIN64A" + do_script = "ms\\do_win64a" + makefile = "ms\\nt64.mak" + m32 = makefile.replace('64', '') + dirsuffix = "64" + #os.environ["VSEXTCOMP_USECL"] = "MS_OPTERON" + else: + raise ValueError('Unrecognized platform: %s' % arch) + + # rebuild makefile when we do the role over from 32 to 64 build + if arch == "amd64" and os.path.isfile(m32) and not os.path.isfile(makefile): + os.unlink(m32) + + # If the ssl makefiles do not exist, we invoke Perl to generate them. + # Due to a bug in this script, the makefile sometimes ended up empty + # Force a regeneration if it is. + if not os.path.isfile(makefile) or os.path.getsize(makefile)==0: + print("Creating the makefiles...") + sys.stdout.flush() + run_configure(configure, do_script) + + if arch == "amd64": + create_makefile64(makefile, m32) + fix_makefile(makefile) + copy(r"crypto\buildinf.h", r"crypto\buildinf_%s.h" % arch) + copy(r"crypto\opensslconf.h", r"crypto\opensslconf_%s.h" % arch) + else: + print(makefile, 'already exists!') + + print('creating asms...') + create_asms(makefile) + +def main(): + if len(sys.argv) == 1: + print("Not enough arguments: directory containing OpenSSL", + "sources must be supplied") + sys.exit(1) + + if len(sys.argv) > 2: + print("Too many arguments supplied, all we need is the directory", + "containing OpenSSL sources") + sys.exit(1) + + ssl_dir = sys.argv[1] + + if not os.path.isdir(ssl_dir): + print(ssl_dir, "is not an existing directory!") + sys.exit(1) + + # perl should be on the path, but we also look in "\perl" and "c:\\perl" + # as "well known" locations + perls = find_all_on_path("perl.exe", ["\\perl\\bin", "C:\\perl\\bin"]) + perl = find_working_perl(perls) + if perl: + print("Found a working perl at '%s'" % (perl,)) + else: + sys.exit(1) + sys.stdout.flush() + + # Put our working Perl at the front of our path + os.environ["PATH"] = os.path.dirname(perl) + \ + os.pathsep + \ + os.environ["PATH"] + + old_cwd = os.getcwd() + try: + os.chdir(ssl_dir) + for arch in ['amd64', 'x86']: + prep(arch) + finally: + os.chdir(old_cwd) + +if __name__=='__main__': + main() diff --git a/PCbuild/pyd.props b/PCbuild/pyd.props deleted file mode 100644 index 469966ede6b3..000000000000 --- a/PCbuild/pyd.props +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - false - false - .pyd - - - - Py_BUILD_CORE_MODULE;%(PreprocessorDefinitions) - MultiThreadedDLL - - - - - - - - - \ No newline at end of file diff --git a/PCbuild/pyd_d.props b/PCbuild/pyd_d.props deleted file mode 100644 index b023288fbad1..000000000000 --- a/PCbuild/pyd_d.props +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - false - false - false - .pyd - $(ProjectName)_d - - - - Disabled - Default - false - Py_BUILD_CORE_MODULE;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - - - - - - - - - \ No newline at end of file diff --git a/PCbuild/pyexpat.vcxproj b/PCbuild/pyexpat.vcxproj index 974fd3d6cbc4..4e7621ec926b 100644 --- a/PCbuild/pyexpat.vcxproj +++ b/PCbuild/pyexpat.vcxproj @@ -35,185 +35,32 @@ + <_ProjectFileVersion>10.0.30319.1 {D06B6426-4762-44CC-8BAD-D79052507F2F} pyexpat - Win32Proj + - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - + DynamicLibrary NotSet + + .pyd + - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - - .\..\Modules\expat;%(AdditionalIncludeDirectories) - PYEXPAT_EXPORTS;HAVE_EXPAT_H;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;XML_STATIC;HAVE_MEMMOVE;%(PreprocessorDefinitions) - - - - - X64 - - - .\..\Modules\expat;%(AdditionalIncludeDirectories) - PYEXPAT_EXPORTS;HAVE_EXPAT_H;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;XML_STATIC;HAVE_MEMMOVE;%(PreprocessorDefinitions) - - - - - .\..\Modules\expat;%(AdditionalIncludeDirectories) - PYEXPAT_EXPORTS;HAVE_EXPAT_H;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;XML_STATIC;HAVE_MEMMOVE;%(PreprocessorDefinitions) - - - - - X64 - - - .\..\Modules\expat;%(AdditionalIncludeDirectories) - PYEXPAT_EXPORTS;HAVE_EXPAT_H;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;XML_STATIC;HAVE_MEMMOVE;%(PreprocessorDefinitions) - - - - - .\..\Modules\expat;%(AdditionalIncludeDirectories) - PYEXPAT_EXPORTS;HAVE_EXPAT_H;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;XML_STATIC;HAVE_MEMMOVE;%(PreprocessorDefinitions) - - - - - X64 - - - .\..\Modules\expat;%(AdditionalIncludeDirectories) - PYEXPAT_EXPORTS;HAVE_EXPAT_H;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;XML_STATIC;HAVE_MEMMOVE;%(PreprocessorDefinitions) - - - MachineX64 - - - - - .\..\Modules\expat;%(AdditionalIncludeDirectories) - PYEXPAT_EXPORTS;HAVE_EXPAT_H;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;XML_STATIC;HAVE_MEMMOVE;%(PreprocessorDefinitions) - - - - - X64 - + - .\..\Modules\expat;%(AdditionalIncludeDirectories) + $(PySourcePath)Modules\expat;%(AdditionalIncludeDirectories) PYEXPAT_EXPORTS;HAVE_EXPAT_H;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;XML_STATIC;HAVE_MEMMOVE;%(PreprocessorDefinitions) - - MachineX64 - diff --git a/PCbuild/pylauncher.vcxproj b/PCbuild/pylauncher.vcxproj index 9fa93dd141e8..6a2178583e1e 100644 --- a/PCbuild/pylauncher.vcxproj +++ b/PCbuild/pylauncher.vcxproj @@ -37,256 +37,33 @@ {7B2727B5-5A3F-40EE-A866-43A13CD31446} pylauncher + py + ClCompile + false + - - Application - true - MultiByte - - - Application - true - MultiByte - - - Application - false - true - MultiByte - - - Application - false - true - MultiByte - - - Application - false - true - MultiByte - - - Application - false - true - MultiByte - - - Application - false - true - MultiByte - - + Application - false - true MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + ClCompile + + - - - - - py_d - - - py_d - - - py - - - py - - - py - - - py - - - py - - - py - - - - Level3 - Disabled - _CONSOLE;%(PreprocessorDefinitions) - - - true - version.lib;%(AdditionalDependencies) - false - Console - $(OutDir)$(TargetName)$(TargetExt) - - - + - Level3 - Disabled _CONSOLE;%(PreprocessorDefinitions) + MultiThreaded - true - version.lib;%(AdditionalDependencies) - false - Console - $(OutDir)$(TargetName)$(TargetExt) - - - - - Level3 - MaxSpeed - true - true - _CONSOLE;NDEBUG;%(PreprocessorDefinitions) - - - true - false - true - false - version.lib;%(AdditionalDependencies) - Console - - - - - Level3 - MaxSpeed - true - true - _CONSOLE;NDEBUG;%(PreprocessorDefinitions) - - - true - false - true - false - version.lib;%(AdditionalDependencies) - Console - - - - - Level3 - MaxSpeed - true - true - _CONSOLE;NDEBUG;%(PreprocessorDefinitions) - - - true - false - true - false - version.lib;%(AdditionalDependencies) - Console - - - - - Level3 - MaxSpeed - true - true - _CONSOLE;NDEBUG;%(PreprocessorDefinitions) - - - true - false - true - false - version.lib;%(AdditionalDependencies) - Console - - - - - Level3 - MaxSpeed - true - true - _CONSOLE;NDEBUG;%(PreprocessorDefinitions) - - - true - false - true - false - version.lib;%(AdditionalDependencies) - Console - - - - - Level3 - MaxSpeed - true - true - _CONSOLE;NDEBUG;%(PreprocessorDefinitions) - - - true - false - true - false version.lib;%(AdditionalDependencies) Console @@ -300,11 +77,6 @@ - - - {f0e0541e-f17d-430b-97c4-93adf0dd284e} - - diff --git a/PCbuild/pyproject.props b/PCbuild/pyproject.props index 7b65961073c4..1afbfe1639d1 100644 --- a/PCbuild/pyproject.props +++ b/PCbuild/pyproject.props @@ -1,48 +1,49 @@  - + <_ProjectFileVersion>10.0.30319.1 - $(SolutionDir) - $(SolutionDir)$(PlatformName)-temp-$(Configuration)\$(ProjectName)\ - false - - - <_ProjectFileVersion>10.0.30319.1 - <_PropertySheetDisplayName>amd64 - $(SolutionDir)amd64\ - $(SolutionDir)$(PlatformName)-temp-$(Configuration)\$(ProjectName)\ + 10.0 + $(BuildPath) + $(SolutionDir)obj\$(ArchName)_$(Configuration)\$(ProjectName)\ + $(SolutionDir)obj\$(ArchName)\$(ProjectName)\ + $(ProjectName) + $(TargetName)$(PyDebugExt) + false + false + true + true + false + false - - python34$(PyDebugExt) - $(OutDir)python$(PyDebugExt).exe - $(OutDir)kill_python$(PyDebugExt).exe - ..\.. - $(externalsDir)\sqlite-3.8.1 - $(externalsDir)\bzip2-1.0.6 - $(externalsDir)\xz-5.0.5 - $(externalsDir)\openssl-1.0.1e - $(externalsDir)\tcltk - $(externalsDir)\tcltk64 - $(tcltkDir)\lib\tcl86t.lib;$(tcltkDir)\lib\tk86t.lib - $(tcltkDir)\lib\tcl86tg.lib;$(tcltkDir)\lib\tk86tg.lib - $(tcltk64Dir)\lib\tcl86t.lib;$(tcltk64Dir)\lib\tk86t.lib - $(tcltk64Dir)\lib\tcl86tg.lib;$(tcltk64Dir)\lib\tk86tg.lib + + + <_DebugPreprocessorDefinition>NDEBUG; + <_DebugPreprocessorDefinition Condition="$(Configuration) == 'Debug'">_DEBUG; + <_PlatformPreprocessorDefinition>_WIN32; + <_PlatformPreprocessorDefinition Condition="$(Platform) == 'x64'">_WIN64;_M_X64; + <_PydPreprocessorDefinition Condition="$(TargetExt) == '.pyd'">Py_BUILD_CORE_MODULE; + $(PySourcePath)Include;$(PySourcePath)PC;%(AdditionalIncludeDirectories) + WIN32;$(_PlatformPreprocessorDefinition)$(_DebugPreprocessorDefinition)$(_PydPreprocessorDefinition)%(PreprocessorDefinitions) + MaxSpeed - OnlyExplicitInline true - ..\Include; ..\PC;%(AdditionalIncludeDirectories) - _WIN32;%(PreprocessorDefinitions) true - - - MultiThreaded + + MultiThreadedDLL true Level3 ProgramDatabase Default + true + true + + + Disabled + false + MultiThreadedDebugDLL $(OutDir);%(AdditionalLibraryDirectories) @@ -51,54 +52,105 @@ Windows true true + true + LIBC;%(IgnoreSpecificDefaultLibraries) MachineX86 + MachineX64 + $(OutDir)$(TargetName).pgd + UseLinkTimeCodeGeneration + PGInstrument + PGUpdate + + true + true + true + - ..\PC;..\Include;%(AdditionalIncludeDirectories) + $(PySourcePath)PC;$(PySourcePath)Include;%(AdditionalIncludeDirectories) + $(_DebugPreprocessorDefinition)%(PreprocessorDefinitions) + 0x0409 + + $(_DebugPreprocessorDefinition)%(PreprocessorDefinitions) + true + true + Win32 + X64 + $(OutDir)wininst.tlb + + + - - - $(PyDllName) - - - $(PythonExe) - - - $(KillPythonExe) - - - $(externalsDir) - - - $(sqlite3Dir) - - - $(bz2Dir) - - - $(lzmaDir) - - - $(opensslDir) - - - $(tcltkDir) - - - $(tcltk64Dir) - - - $(tcltkLib) - - - $(tcltkLibDebug) - - - $(tcltk64Lib) - - - $(tcltk64LibDebug) - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $(registry:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows Kits\Installed Roots@KitsRoot81)\bin\x86\signtool.exe + $(registry:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows Kits\Installed Roots@KitsRoot)\bin\x86\signtool.exe + $(registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.1A@InstallationFolder)\Bin\signtool.exe + <_SignCommand Condition="Exists($(SignToolPath))">"$(SignToolPath)" sign /q /n "$(SigningCertificate)" /t http://timestamp.verisign.com/scripts/timestamp.dll /d "Python $(PythonVersion)" + + + + + + + \ No newline at end of file diff --git a/PCbuild/python.props b/PCbuild/python.props new file mode 100644 index 000000000000..51eceb8f5947 --- /dev/null +++ b/PCbuild/python.props @@ -0,0 +1,116 @@ + + + + Win32 + Release + + v140 + v120 + v110 + v100 + + + amd64 + win32 + $(ArchName)-pgo + + + $([System.IO.Path]::GetFullPath($(MSBuildThisFileDirectory)\..\)) + $(PySourcePath)\ + + + $(PySourcePath)PCBuild\$(ArchName)\ + $(BuildPath)\ + + + $([System.IO.Path]::GetFullPath(`$(PySourcePath)externals\`)) + $(ExternalsDir)sqlite-3.8.3.1\ + $(ExternalsDir)bzip2-1.0.6\ + $(ExternalsDir)xz-5.0.5\ + $(ExternalsDir)openssl-1.0.1l\ + $(ExternalsDir)\nasm-2.11.06\ + + + _d + + + $(BuildPath)python$(PyDebugExt).exe + + + <_PatchLevelContent>$([System.IO.File]::ReadAllText(`$(PySourcePath)Include\patchlevel.h`)) + $([System.Text.RegularExpressions.Regex]::Match($(_PatchLevelContent), `define\s+PY_MAJOR_VERSION\s+(\d+)`).Groups[1].Value) + $([System.Text.RegularExpressions.Regex]::Match($(_PatchLevelContent), `define\s+PY_MINOR_VERSION\s+(\d+)`).Groups[1].Value) + $([System.Text.RegularExpressions.Regex]::Match($(_PatchLevelContent), `define\s+PY_MICRO_VERSION\s+(\d+)`).Groups[1].Value) + <_ReleaseLevel>$([System.Text.RegularExpressions.Regex]::Match($(_PatchLevelContent), `define\s+PY_RELEASE_LEVEL\s+PY_RELEASE_LEVEL_(\w+)`).Groups[1].Value) + $([System.Text.RegularExpressions.Regex]::Match($(_PatchLevelContent), `define\s+PY_RELEASE_SERIAL\s+(\d+)`).Groups[1].Value) + 15 + 10 + 11 + 12 + a$(ReleaseSerial) + b$(ReleaseSerial) + rc$(ReleaseSerial) + + $(MajorVersionNumber).$(MinorVersionNumber).$(MicroVersionNumber) + $(MajorVersionNumber).$(MinorVersionNumber).$(MicroVersionNumber)$(ReleaseLevelName) + $([msbuild]::BitwiseOr( + $([msbuild]::Multiply($(MajorVersionNumber), 16777216)), + $([msbuild]::BitwiseOr( + $([msbuild]::Multiply($(MinorVersionNumber), 65536)), + $([msbuild]::BitwiseOr( + $([msbuild]::Multiply($(MicroVersionNumber), 256)), + $([msbuild]::BitwiseOr( + $([msbuild]::Multiply($(ReleaseLevelNumber), 16)), + $(ReleaseSerial) + )) + )) + )) + )) + $([msbuild]::Add( + $(ReleaseSerial), + $([msbuild]::Add( + $([msbuild]::Multiply($(ReleaseLevelNumber), 10)), + $([msbuild]::Multiply($(MicroVersionNumber), 1000)) + )) + )) + + + python$(MajorVersionNumber)$(MinorVersionNumber)$(PyDebugExt) + + + .cp$(MajorVersionNumber)$(MinorVersionNumber)-win32 + .cp$(MajorVersionNumber)$(MinorVersionNumber)-win_amd64 + + + $(MajorVersionNumber).$(MinorVersionNumber) + $(SysWinVer)-32 + + + + + + + + + + diff --git a/PCbuild/python.vcxproj b/PCbuild/python.vcxproj index bd1262459636..0ae4882ad16a 100644 --- a/PCbuild/python.vcxproj +++ b/PCbuild/python.vcxproj @@ -36,44 +36,11 @@ {B11D750F-CD1F-4A96-85CE-E69A5C5259F9} + ClCompile + - - Application - false - MultiByte - - - Application - false - MultiByte - - - Application - false - NotSet - - - Application - false - MultiByte - - - Application - false - MultiByte - - - Application - false - MultiByte - - - Application - false - MultiByte - - + Application false MultiByte @@ -81,266 +48,22 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - %(AdditionalIncludeDirectories) - _CONSOLE;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - Default - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)python.exe - Console - 2000000 - 0x1d000000 - - - - - X64 - - - %(AdditionalIncludeDirectories) - _CONSOLE;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - Default - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)python.exe - Console - 2000000 - 0x1d000000 - - - - - Disabled - false - %(AdditionalIncludeDirectories) - _CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - true - Default - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - ..\Include;%(AdditionalIncludeDirectories) - - - $(OutDir)python_d.exe - Console - 2000000 - 0x1d000000 - - - - - X64 - - - Disabled - false - %(AdditionalIncludeDirectories) - _CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - true - Default - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - ..\Include;%(AdditionalIncludeDirectories) - - - $(OutDir)python_d.exe - Console - 4194304 - 0x1d000000 - - - - - %(AdditionalIncludeDirectories) - _CONSOLE;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - Default - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)python.exe - Console - 2000000 - 0x1d000000 - - - - - - - X64 - - - %(AdditionalIncludeDirectories) - _CONSOLE;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - Default - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)python.exe - Console - 2000000 - 0x1d000000 - - - MachineX64 - - - - - %(AdditionalIncludeDirectories) - _CONSOLE;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - Default - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)python.exe - Console - 2000000 - 0x1d000000 - - - - - - - X64 - + - %(AdditionalIncludeDirectories) _CONSOLE;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - Default - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - $(OutDir)python.exe Console 2000000 0x1d000000 - - - MachineX64 @@ -350,7 +73,7 @@ - + @@ -361,4 +84,19 @@ - + + + <_Content>@rem This script invokes the most recently built Python with all arguments +@rem passed through to the interpreter. This file is generated by the +@rem build process and any changes *will* be thrown away by the next +@rem rebuild. +@rem This is only meant as a convenience for developing CPython +@rem and using it outside of that context is ill-advised. +@echo Running $(Configuration)^|$(Platform) interpreter... +@"$(OutDir)python$(PyDebugExt).exe" %* + + <_ExistingContent Condition="Exists('$(PySourcePath)python.bat')">$([System.IO.File]::ReadAllText('$(PySourcePath)python.bat')) + + + + \ No newline at end of file diff --git a/PCbuild/python.vcxproj.filters b/PCbuild/python.vcxproj.filters index e4906a40d7f7..0662a4e7f5f9 100644 --- a/PCbuild/python.vcxproj.filters +++ b/PCbuild/python.vcxproj.filters @@ -19,8 +19,8 @@ - + Source Files - \ No newline at end of file + diff --git a/PCbuild/python3dll.vcxproj b/PCbuild/python3dll.vcxproj index bc8ff31ca223..b03d09fa39f4 100644 --- a/PCbuild/python3dll.vcxproj +++ b/PCbuild/python3dll.vcxproj @@ -1,6 +1,14 @@  + + Debug + Win32 + + + Debug + x64 + PGInstrument Win32 @@ -30,144 +38,43 @@ {885D4898-D08D-4091-9C40-C700CFE3FC5A} python3dll Win32Proj + python3 + ClCompile + false + - - Makefile - - - Makefile - - - Makefile - true - - - Makefile - - - Makefile - - - Makefile + + DynamicLibrary - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - <_ProjectFileVersion>10.0.30319.1 - cd $(ProjectDir)\..\PC -nmake /f python3.mak MACHINE=x86 OutDir=$(OutDir) - cd $(ProjectDir)\..\PC -nmake /f python3.mak MACHINE=x86 OutDir=$(OutDir) rebuild - cd $(ProjectDir)\..\PC -"$(VSInstallDir)\VC\bin\nmake.exe" /f python3.mak MACHINE=x86 OutDir=$(OutDir) clean - $(OutDir)python3.dll - $(NMakePreprocessorDefinitions) - $(NMakeIncludeSearchPath) - $(NMakeForcedIncludes) - $(NMakeAssemblySearchPath) - $(NMakeForcedUsingAssemblies) - cd $(ProjectDir)\..\PC -nmake /f python3.mak MACHINE=x64 OutDir=$(OutDir) - cd $(ProjectDir)\..\PC -nmake /f python3.mak MACHINE=x64 OutDir=$(OutDir) rebuild - cd $(ProjectDir)\..\PC -"$(VSInstallDir)\VC\bin\nmake.exe" /f python3.mak MACHINE=x64 OutDir=$(OutDir) clean - $(OutDir)python3.dll - $(NMakePreprocessorDefinitions) - $(NMakeIncludeSearchPath) - $(NMakeForcedIncludes) - $(NMakeAssemblySearchPath) - $(NMakeForcedUsingAssemblies) - cd $(ProjectDir)\..\PC -nmake /f python3.mak MACHINE=x86 OutDir=$(OutDir) - cd $(ProjectDir)\..\PC -nmake /f python3.mak MACHINE=x86 OutDir=$(OutDir) rebuild - cd $(ProjectDir)\..\PC -"$(VSInstallDir)\VC\bin\nmake.exe" /f python3.mak MACHINE=x86 OutDir=$(OutDir) clean - $(OutDir)python3.dll - $(NMakePreprocessorDefinitions) - $(NMakeIncludeSearchPath) - $(NMakeForcedIncludes) - $(NMakeAssemblySearchPath) - $(NMakeForcedUsingAssemblies) - cd $(ProjectDir)\..\PC -nmake /f python3.mak MACHINE=x64 OutDir=$(OutDir) - cd $(ProjectDir)\..\PC -nmake /f python3.mak MACHINE=x64 OutDir=$(OutDir) rebuild - cd $(ProjectDir)\..\PC -"$(VSInstallDir)\VC\bin\nmake.exe" /f python3.mak MACHINE=x64 OutDir=$(OutDir) clean - $(OutDir)python3.dll - $(NMakePreprocessorDefinitions) - $(NMakeIncludeSearchPath) - $(NMakeForcedIncludes) - $(NMakeAssemblySearchPath) - $(NMakeForcedUsingAssemblies) - cd $(ProjectDir)\..\PC -nmake /f python3.mak MACHINE=x86 OutDir=$(OutDir) - cd $(ProjectDir)\..\PC -nmake /f python3.mak MACHINE=x86 OutDir=$(OutDir) rebuild - cd $(ProjectDir)\..\PC -"$(VSInstallDir)\VC\bin\nmake.exe" /f python3.mak MACHINE=x86 OutDir=$(OutDir) clean - $(OutDir)python3.dll - $(NMakePreprocessorDefinitions) - $(NMakeIncludeSearchPath) - $(NMakeForcedIncludes) - $(NMakeAssemblySearchPath) - $(NMakeForcedUsingAssemblies) - cd $(ProjectDir)\..\PC -nmake /f python3.mak MACHINE=x64 OutDir=$(OutDir) - cd $(ProjectDir)\..\PC -nmake /f python3.mak MACHINE=x64 OutDir=$(OutDir) rebuild - cd $(ProjectDir)\..\PC -"$(VSInstallDir)\VC\bin\nmake.exe" /f python3.mak MACHINE=x64 OutDir=$(OutDir) clean - $(OutDir)python3.dll - $(NMakePreprocessorDefinitions) - $(NMakeIncludeSearchPath) - $(NMakeForcedIncludes) - $(NMakeAssemblySearchPath) - $(NMakeForcedUsingAssemblies) + <_Machine>X86 + <_Machine Condition="$(Platform) == 'x64'">X64 + + false + + + $(OutDir)$(TargetName)stub.lib + $(PySourcePath)PC\python3.def + $(IntDir)python3_d.def + DllMain + + + lib /nologo /def:"$(IntDir)python3stub.def" /out:"$(OutDir)$(TargetName)stub.lib" /MACHINE:$(_Machine) + Rebuilding $(TargetName)stub.lib + $(OutDir)$(TargetName)stub.lib + @@ -181,4 +88,55 @@ nmake /f python3.mak MACHINE=x64 OutDir=$(OutDir) rebuild + + + + <_DefLines Remove="@(_DefLines)" /> + <_Lines Remove="@(_Lines)" /> + + + + + + <_Pattern1>(=python$(MajorVersionNumber)$(MinorVersionNumber))\. + <_Sub1>$1_d. + <_Pattern2>"python3" + <_Sub2>"python3_d" + + + <_Lines Include="@(_DefLines)"> + $([System.Text.RegularExpressions.Regex]::Replace($([System.Text.RegularExpressions.Regex]::Replace(`%(Identity)`, `$(_Pattern1)`, `$(_Sub1)`)), `$(_Pattern2)`, `$(_Sub2)`)) + + + + + + + + + <_DefLines Remove="@(_DefLines)" /> + <_Lines Remove="@(_Lines)" /> + + + + + + <_Pattern>^[\w.]+=.+?\.([^ ]+).*$ + <_Sub>$1 + + + <_Lines Include="EXPORTS" /> + <_Symbols Include="@(_DefLines)" Condition="$([System.Text.RegularExpressions.Regex]::IsMatch(`%(Identity)`, `$(_Pattern)`))"> + $([System.Text.RegularExpressions.Regex]::Replace(`%(Identity)`, `$(_Pattern)`, `$(_Sub)`)) + + <_Lines Include="@(_Symbols->'%(Symbol)')" /> + + + + + + + + + \ No newline at end of file diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index 11b7054d3fb9..479f68df5543 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -38,373 +38,41 @@ {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} pythoncore + - - DynamicLibrary - false - - - DynamicLibrary - false - - - DynamicLibrary - false - NotSet - - - DynamicLibrary - false - - - DynamicLibrary - false - - - DynamicLibrary - false - - - DynamicLibrary - false - - + DynamicLibrary false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + ClCompile + true + + - - <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - $(PyDllName) - $(PyDllName) - $(PyDllName) - $(PyDllName) - $(PyDllName) - $(PyDllName) - $(PyDllName) - $(PyDllName) + $(PyDllName) - - - /Zm200 %(AdditionalOptions) - ..\Python;..\Modules\zlib;%(AdditionalIncludeDirectories) - _USRDLL;Py_BUILD_CORE;Py_ENABLE_SHARED;WIN32;%(PreprocessorDefinitions) - MultiThreadedDLL - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - ..\Include;%(AdditionalIncludeDirectories) - - - Generate build information... - "$(SolutionDir)make_buildinfo.exe" Release "$(IntDir)" - - - $(IntDir)getbuildinfo.o;%(AdditionalDependencies) - $(OutDir)$(PyDllName).dll - libc;%(IgnoreSpecificDefaultLibraries) - 0x1e000000 - - - $(KillPythonExe) - - - Killing any running $(PythonExe) instances... - - - - - X64 - - - /Zm200 %(AdditionalOptions) - ..\Python;..\Modules\zlib;%(AdditionalIncludeDirectories) - _USRDLL;Py_BUILD_CORE;Py_ENABLE_SHARED;WIN32;%(PreprocessorDefinitions) - MultiThreadedDLL - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - ..\Include;%(AdditionalIncludeDirectories) - - - Generate build information... - "$(SolutionDir)make_buildinfo.exe" Release "$(IntDir)" - - - $(IntDir)getbuildinfo.o;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) - 0x1e000000 - - - $(KillPythonExe) - - - Killing any running $(PythonExe) instances... - - - - - /Zm200 %(AdditionalOptions) - Disabled - Default - false - ..\Python;..\Modules\zlib;%(AdditionalIncludeDirectories) - _USRDLL;Py_BUILD_CORE;Py_ENABLE_SHARED;WIN32;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - ..\Include;%(AdditionalIncludeDirectories) - - - Generate build information... - "$(SolutionDir)make_buildinfo.exe" Debug "$(IntDir)" - - - $(IntDir)getbuildinfo.o;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) - 0x1e000000 - - - $(KillPythonExe) - - - Killing any running $(PythonExe) instances... - - - - - X64 - - - /Zm200 %(AdditionalOptions) - Disabled - Default - false - ..\Python;..\Modules\zlib;%(AdditionalIncludeDirectories) - _USRDLL;Py_BUILD_CORE;Py_ENABLE_SHARED;WIN32;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - ..\Include;%(AdditionalIncludeDirectories) - - - Generate build information... - "$(SolutionDir)make_buildinfo.exe" Debug "$(IntDir)" - - - $(IntDir)getbuildinfo.o;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) - 0x1e000000 - - - $(KillPythonExe) - - - Killing any running $(PythonExe) instances... - - - - - /Zm200 %(AdditionalOptions) - ..\Python;..\Modules\zlib;%(AdditionalIncludeDirectories) - _USRDLL;Py_BUILD_CORE;Py_ENABLE_SHARED;WIN32;%(PreprocessorDefinitions) - MultiThreadedDLL - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - ..\Include;%(AdditionalIncludeDirectories) - - - Generate build information... - "$(SolutionDir)make_buildinfo.exe" Release "$(IntDir)" - - - $(IntDir)getbuildinfo.o;%(AdditionalDependencies) - $(OutDir)$(PyDllName).dll - libc;%(IgnoreSpecificDefaultLibraries) - 0x1e000000 - - - $(KillPythonExe) - - - Killing any running $(PythonExe) instances... - - - - - X64 - - - /Zm200 %(AdditionalOptions) - ..\Python;..\Modules\zlib;%(AdditionalIncludeDirectories) - _USRDLL;Py_BUILD_CORE;Py_ENABLE_SHARED;WIN32;%(PreprocessorDefinitions) - MultiThreadedDLL - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - ..\Include;%(AdditionalIncludeDirectories) - - - Generate build information... - "$(SolutionDir)make_buildinfo.exe" Release "$(IntDir)" - - - $(IntDir)getbuildinfo.o;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) - 0x1e000000 - MachineX64 - - - $(KillPythonExe) - - - Killing any running $(PythonExe) instances... - - - - - /Zm200 %(AdditionalOptions) - ..\Python;..\Modules\zlib;%(AdditionalIncludeDirectories) - _USRDLL;Py_BUILD_CORE;Py_ENABLE_SHARED;WIN32;%(PreprocessorDefinitions) - MultiThreadedDLL - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - ..\Include;%(AdditionalIncludeDirectories) - - - Generate build information... - "$(SolutionDir)make_buildinfo.exe" Release "$(IntDir)" - - - $(IntDir)getbuildinfo.o;%(AdditionalDependencies) - $(OutDir)$(PyDllName).dll - libc;%(IgnoreSpecificDefaultLibraries) - 0x1e000000 - - - $(KillPythonExe) - - - Killing any running $(PythonExe) instances... - - - - - X64 - + + Link + + /Zm200 %(AdditionalOptions) - ..\Python;..\Modules\zlib;%(AdditionalIncludeDirectories) - _USRDLL;Py_BUILD_CORE;Py_ENABLE_SHARED;WIN32;%(PreprocessorDefinitions) - MultiThreadedDLL + $(PySourcePath)Python;$(PySourcePath)Modules\zlib;%(AdditionalIncludeDirectories) + _USRDLL;Py_BUILD_CORE;Py_ENABLE_SHARED;MS_DLL_ID="$(SysWinVer)";%(PreprocessorDefinitions) - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - ..\Include;%(AdditionalIncludeDirectories) - - - Generate build information... - "$(SolutionDir)make_buildinfo.exe" Release "$(IntDir)" - - $(IntDir)getbuildinfo.o;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) + ws2_32.lib;%(AdditionalDependencies) 0x1e000000 - MachineX64 - - $(KillPythonExe) - - - Killing any running $(PythonExe) instances... - @@ -470,6 +138,7 @@ + @@ -666,7 +335,6 @@ - @@ -702,6 +370,7 @@ + @@ -717,23 +386,34 @@ - + - - {6de10744-e396-40a5-b4e2-1b69aa7c8d31} - false - - - {c73f0ec1-358b-4177-940f-0846ac8b04cd} - false - - - {f0e0541e-f17d-430b-97c4-93adf0dd284e} - false - + - + + + + + + + + $([System.IO.File]::ReadAllText('$(IntDir)hgbranch.txt').Trim()) + $([System.IO.File]::ReadAllText('$(IntDir)hgversion.txt').Trim()) + $([System.IO.File]::ReadAllText('$(IntDir)hgtag.txt').Trim()) + + + + + HGVERSION="$(HgVersion)";HGTAG="$(HgTag)";HGBRANCH="$(HgBranch)";%(PreprocessorDefinitions) + + + + + + + + \ No newline at end of file diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters index 41fe1b2dbbdc..174140a912d4 100644 --- a/PCbuild/pythoncore.vcxproj.filters +++ b/PCbuild/pythoncore.vcxproj.filters @@ -216,6 +216,9 @@ Include + + Include + Include @@ -414,7 +417,6 @@ Python - Python @@ -424,6 +426,12 @@ Include + + Include + + + Modules + @@ -885,6 +893,9 @@ Python + + Python + Python @@ -930,13 +941,24 @@ PC - Modules Python + + Objects + + + Modules + + + Modules + + + Modules + diff --git a/PCbuild/pythonw.vcxproj b/PCbuild/pythonw.vcxproj index 1214569eb98f..b0a209af42f5 100644 --- a/PCbuild/pythonw.vcxproj +++ b/PCbuild/pythonw.vcxproj @@ -36,296 +36,30 @@ {F4229CC3-873C-49AE-9729-DD308ED4CD4A} + ClCompile + false + - - Application - false - - - Application - false - - - Application - false - - - Application - false - NotSet - - - Application - false - - - Application - false - - - Application - false - - + Application false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - Disabled - false - %(AdditionalIncludeDirectories) - _WINDOWS;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - Default - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)pythonw_d.exe - 2000000 - 0x1d000000 - MachineX86 - - - - - X64 - - - Disabled - false - %(AdditionalIncludeDirectories) - _WINDOWS;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - Default - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)pythonw_d.exe - 2000000 - 0x1d000000 - - - - - %(AdditionalIncludeDirectories) - _WINDOWS;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - Default - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)pythonw.exe - 2000000 - 0x1d000000 - MachineX86 - - - - - X64 - - - %(AdditionalIncludeDirectories) - _WINDOWS;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - Default - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)pythonw.exe - 2000000 - 0x1d000000 - - - - - %(AdditionalIncludeDirectories) - _WINDOWS;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - Default - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)pythonw.exe - 2000000 - 0x1d000000 - - - MachineX86 - - - - - X64 - - - %(AdditionalIncludeDirectories) - _WINDOWS;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - Default - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)pythonw.exe - 2000000 - 0x1d000000 - - - MachineX64 - - - - - %(AdditionalIncludeDirectories) - _WINDOWS;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - Default - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)pythonw.exe - 2000000 - 0x1d000000 - - - MachineX86 - - - - - X64 - - - %(AdditionalIncludeDirectories) - _WINDOWS;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - Default - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - + - $(OutDir)pythonw.exe 2000000 0x1d000000 - - - MachineX64 diff --git a/PCbuild/pywlauncher.vcxproj b/PCbuild/pywlauncher.vcxproj index 08e35a77411a..882f1c4d24bd 100644 --- a/PCbuild/pywlauncher.vcxproj +++ b/PCbuild/pywlauncher.vcxproj @@ -37,200 +37,37 @@ {1D4B18D3-7C12-4ECB-9179-8531FF876CE6} pywlauncher + pyw + ClCompile + false + - - Application - true - Unicode - - - Application - true - Unicode - - - Application - false - true - Unicode - - + Application - false - true - Unicode - - - Unicode - - Unicode - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + ClCompile + + - - - - - pyw_d - - - pyw_d - - - pyw - - - pyw - - - pyw - - - pyw - - + - Level3 - Disabled _WINDOWS;%(PreprocessorDefinitions) + MultiThreaded - true version.lib;%(AdditionalDependencies) - false Windows - $(OutDir)$(TargetName)$(TargetExt) - - - Level3 - Disabled - _WINDOWS;%(PreprocessorDefinitions) - - - true - version.lib;%(AdditionalDependencies) - false - Windows - $(OutDir)$(TargetName)$(TargetExt) - - - - - Level3 - MaxSpeed - true - true - _WINDOWS;NDEBUG;%(PreprocessorDefinitions) - - - true - false - true - false - version.lib;%(AdditionalDependencies) - Windows - - - - - Level3 - MaxSpeed - true - true - _WINDOWS;NDEBUG;%(PreprocessorDefinitions) - - - true - false - true - false - version.lib;%(AdditionalDependencies) - Windows - - - - - version.lib;%(AdditionalDependencies) - - - _WINDOWS;NDEBUG;%(PreprocessorDefinitions) - - - - - version.lib;%(AdditionalDependencies) - - - _WINDOWS;NDEBUG;%(PreprocessorDefinitions) - - - - - version.lib;%(AdditionalDependencies) - - - _WINDOWS;NDEBUG;_WIN64;_M_X64;%(PreprocessorDefinitions) - - - - - version.lib;%(AdditionalDependencies) - - - _WINDOWS;NDEBUG;_WIN64;_M_X64;%(PreprocessorDefinitions) - - diff --git a/PCbuild/readme.txt b/PCbuild/readme.txt index 32635709c132..77bfeeba79fa 100644 --- a/PCbuild/readme.txt +++ b/PCbuild/readme.txt @@ -1,73 +1,110 @@ +Quick Start Guide +----------------- + +1. Install Microsoft Visual Studio 2015, any edition. +2. Install Subversion, and make sure 'svn.exe' is on your PATH. +3. Run "build.bat -e" to build Python in 32-bit Release configuration. +4. (Optional, but recommended) Run the test suite with "rt.bat -q". + + Building Python using Microsoft Visual C++ ------------------------------------------ This directory is used to build CPython for Microsoft Windows NT version -5.1 or higher (Windows XP, Windows Server 2003, or later) on 32 and 64 +6.0 or higher (Windows Vista, Windows Server 2008, or later) on 32 and 64 bit platforms. Using this directory requires an installation of -Microsoft Visual C++ 2010 (MSVC 10.0) of any edition. The specific +Microsoft Visual C++ 2015 (MSVC 14.0) of any edition. The specific requirements are as follows: -Visual C++ 2010 Express Edition - Required for building 32-bit Debug and Release configuration builds. - This edition does not support "solution folders", which pcbuild.sln - uses; this will not prevent building. -Visual Studio 2010 Standard Edition + +Visual Studio Express 2015 for Desktop +Visual Studio Professional 2015 + Either edition is sufficient for building all configurations except + for Profile Guided Optimization. + The Python build solution pcbuild.sln makes use of Solution Folders, + which this edition does not support. Any time pcbuild.sln is opened + or reloaded by Visual Studio, a warning about Solution Folders will + be displayed, which can be safely dismissed with no impact on your + ability to build Python. Required for building 64-bit Debug and Release configuration builds -Visual Studio 2010 Professional Edition +Visual Studio Premium 2015 Required for building Release configuration builds that make use of - Profile Guided Optimization (PGO), on either platform. The official - Python releases are built with Professional Edition using PGO. + Profile Guided Optimization (PGO), on either platform. All you need to do to build is open the solution "pcbuild.sln" in Visual Studio, select the desired combination of configuration and platform, -then build with "Build Solution" or the F7 keyboard shortcut. You can -also build from the command line using the "build.bat" script in this -directory. The solution is configured to build the projects in the -correct order. +then build with "Build Solution". You can also build from the command +line using the "build.bat" script in this directory; see below for +details. The solution is configured to build the projects in the correct +order. The solution currently supports two platforms. The Win32 platform is -used to build standard x86-compatible 32-bit binaries, output into this -directory. The x64 platform is used for building 64-bit AMD64 (aka -x86_64 or EM64T) binaries, output into the amd64 sub-directory which -will be created if it doesn't already exist. The Itanium (IA-64) -platform is no longer supported. See the "Building for AMD64" section -below for more information about 64-bit builds. +used to build standard x86-compatible 32-bit binaries, output into the +win32 sub-directory. The x64 platform is used for building 64-bit AMD64 +(aka x86_64 or EM64T) binaries, output into the amd64 sub-directory. +The Itanium (IA-64) platform is no longer supported. See the "Building +for AMD64" section below for more information about 64-bit builds. Four configuration options are supported by the solution: Debug Used to build Python with extra debugging capabilities, equivalent to using ./configure --with-pydebug on UNIX. All binaries built using this configuration have "_d" added to their name: - python34_d.dll, python_d.exe, parser_d.pyd, and so on. Both the + python35_d.dll, python_d.exe, parser_d.pyd, and so on. Both the build and rt (run test) batch files in this directory accept a -d option for debug builds. If you are building Python to help with development of CPython, you will most likely use this configuration. PGInstrument, PGUpdate Used to build Python in Release configuration using PGO, which - requires Professional Edition of Visual Studio. See the "Profile + requires Premium Edition of Visual Studio. See the "Profile Guided Optimization" section below for more information. Build output from each of these configurations lands in its own - sub-directory of this directory. The official Python releases are - built using these configurations. + sub-directory of this directory. The official Python releases may + be built using these configurations. Release Used to build Python as it is meant to be used in production settings, though without PGO. -Legacy support --------------- +Building Python using the build.bat script +---------------------------------------------- + +In this directory you can find build.bat, a script designed to make +building Python on Windows simpler. This script will use the env.bat +script to detect one of Visual Studio 2015, 2013, 2012, or 2010, any of +which may be used to build Python, though only Visual Studio 2015 is +officially supported. + +By default, build.bat will build Python in Release configuration for +the 32-bit Win32 platform. It accepts several arguments to change +this behavior: -You can find build directories for older versions of Visual Studio and -Visual C++ in the PC directory. The legacy build directories are no -longer actively maintained and may not work out of the box. + -c Set the configuration (see above) + -d Shortcut for "-c Debug" + -p Set the platform to build for ("Win32" or "x64") + -r Rebuild instead of just building + -t Set the target (Build, Rebuild, Clean or CleanAll) + -e Use get_externals.bat to fetch external sources + -M Don't build in parallel + -v Increased output messages -Currently, the only legacy build directory is PC\VS9.0, for Visual -Studio 2008 (9.0). +Up to 9 MSBuild switches can also be passed, though they must be passed +after specifying any of the above switches. For example, use: + + build.bat -e -d /fl + +to do a debug build with externals fetched as needed and write detailed +build logs to a file. If the MSBuild switch requires an equal sign +("="), the entire switch must be quoted: + + build.bat -e -d "/p:ExternalsDir=P:\cpython-externals" + +There may also be other situations where quotes are necessary. C Runtime --------- -Visual Studio 2010 uses version 10 of the C runtime (MSVCRT10). The +Visual Studio 2015 uses version 14 of the C runtime (MSVCRT14). The executables no longer use the "Side by Side" assemblies used in previous versions of the compiler. This simplifies distribution of applications. @@ -92,10 +129,6 @@ pythoncore .dll and .lib python .exe -kill_python - kill_python.exe, a small program designed to kill any instances of - python(_d).exe that are running and live in the build output - directory; this is meant to avoid build issues due to locked files make_buildinfo, make_versioninfo helpers to provide necessary information to the build process @@ -115,13 +148,12 @@ _testembed purposes, used by test_capi.py These are miscellaneous sub-projects that don't really fit the other -categories. By default, these projects do not build in Debug -configuration: +categories: _freeze_importlib _freeze_importlib.exe, used to regenerate Python\importlib.h after changes have been made to Lib\importlib\_bootstrap.py bdist_wininst - ..\Lib\distutils\command\wininst-10.0[-amd64].exe, the base + ..\Lib\distutils\command\wininst-14.0[-amd64].exe, the base executable used by the distutils bdist_wininst command python3dll python3.dll, the PEP 384 Stable ABI dll @@ -140,7 +172,6 @@ _hashlib _msi _multiprocessing _overlapped -_sha3 _socket _testcapi _testbuffer @@ -166,7 +197,7 @@ _lzma Homepage: http://tukaani.org/xz/ _ssl - Python wrapper for version 1.0.1e of the OpenSSL secure sockets + Python wrapper for version 1.0.1j of the OpenSSL secure sockets library, which is built by ssl.vcxproj Homepage: http://www.openssl.org/ @@ -177,37 +208,30 @@ _ssl to be somewhere on your PATH. More recent versions of OpenSSL may need a later version of NASM. If OpenSSL's self tests don't pass, you should first try to update NASM and do a full rebuild of - OpenSSL. + OpenSSL. get_externals.py also downloads a snapshot of NASM, and the + libeay and ssleay sub-projects use that version of nasm.exe. + + The libeay/ssleay sub-projects expect your OpenSSL sources to have + already been configured and be ready to build. If you get your sources + from svn.python.org as suggested in the "Getting External Sources" + section below, the OpenSSL source will already be ready to go. If + you want to build a different version, you will need to run - If you like to use the official sources instead of the files from - python.org's subversion repository, Perl is required to build the - necessary makefiles and assembly files. ActivePerl is available - from + PCbuild\prepare_ssl.py path\to\openssl-source-dir + + That script will prepare your OpenSSL sources in the same way that + those available on svn.python.org have been prepared. Note that + Perl must be installed and available on your PATH to configure + OpenSSL. ActivePerl is recommended and is available from http://www.activestate.com/activeperl/ - The svn.python.org version contains pre-built makefiles and assembly - files. - - The build process makes sure that no patented algorithms are - included. For now RC5, MDC2 and IDEA are excluded from the build. - You may have to manually remove $(OBJ_D)\i_*.obj from ms\nt.mak if - using official sources; the svn.python.org-hosted version is already - fixed. - - The ssl.vcxproj sub-project simply invokes PCbuild/build_ssl.py, - which locates and builds OpenSSL. - - build_ssl.py attempts to catch the most common errors (such as not - being able to find OpenSSL sources, or not being able to find a Perl - that works with OpenSSL) and give a reasonable error message. If - you have a problem that doesn't seem to be handled correctly (e.g., - you know you have ActivePerl but we can't find it), please take a - peek at build_ssl.py and suggest patches. Note that build_ssl.py - should be able to be run directly from the command-line. - - The ssl sub-project does not have the ability to clean the OpenSSL - build; if you need to rebuild, you'll have to clean it by hand. + + The libeay and ssleay sub-projects will build the modules of OpenSSL + required by _ssl and _hashlib and may need to be manually updated when + upgrading to a newer version of OpenSSL or when adding new + functionality to _ssl or _hashlib. They will not clean up their output + with the normal Clean target; CleanAll should be used instead. _sqlite3 - Wraps SQLite 3.8.1, which is itself built by sqlite3.vcxproj + Wraps SQLite 3.8.3.1, which is itself built by sqlite3.vcxproj Homepage: http://www.sqlite.org/ _tkinter @@ -215,11 +239,19 @@ _tkinter Homepage: http://www.tcl.tk/ - Unlike the other external libraries listed above, Tk must be built - separately before the _tkinter module can be built. This means that - a pre-built Tcl/Tk installation is expected in ..\..\tcltk (tcltk64 - for 64-bit) relative to this directory. See "Getting External - Sources" below for the easiest method to ensure Tcl/Tk is built. + Tkinter's dependencies are built by the tcl.vcxproj and tk.vcxproj + projects. The tix.vcxproj project also builds the Tix extended + widget set for use with Tkinter. + + Those three projects install their respective components in a + directory alongside the source directories called "tcltk" on + Win32 and "tcltk64" on x64. They also copy the Tcl and Tk DLLs + into the current output directory, which should ensure that Tkinter + is able to load Tcl/Tk without having to change your PATH. + + The tcl, tk, and tix sub-projects do not clean their builds with + the normal Clean target; if you need to rebuild, you should use the + CleanAll target or manually delete their builds. Getting External Sources @@ -228,45 +260,18 @@ Getting External Sources The last category of sub-projects listed above wrap external projects Python doesn't control, and as such a little more work is required in order to download the relevant source files for each project before they -can be built. The buildbots must ensure that all libraries are present -before building, so the easiest approach is to run either external.bat -or external-amd64.bat (depending on platform) in the ..\Tools\buildbot -directory from ..\, i.e.: - - C:\python\cpython\PCbuild>cd .. - C:\python\cpython>Tools\buildbot\external.bat - -This extracts all the external sub-projects from +can be built. However, a simple script is provided to make this as +painless as possible, called "get_externals.bat" and located in this +directory. This script extracts all the external sub-projects from http://svn.python.org/projects/external -via Subversion (so you'll need an svn.exe on your PATH) and places them -in ..\.. (relative to this directory). +via Subversion (so you'll need svn.exe on your PATH) and places them +in ..\externals (relative to this directory). It is also possible to download sources from each project's homepage, -though you may have to change the names of some folders in order to make -things work. For instance, if you were to download a version 5.0.7 of -XZ Utils, you would need to extract the archive into ..\..\xz-5.0.5 -anyway, since that is where the solution is set to look for xz. The -same is true for all other external projects. - -The external(-amd64).bat scripts will also build a debug build of -Tcl/Tk, but there aren't any equivalent batch files for building release -versions of Tcl/Tk currently available. If you need to build a release -version of Tcl/Tk, just take a look at the relevant external(-amd64).bat -file and find the two nmake lines, then call each one without the -'DEBUG=1' parameter, i.e.: - -The external-amd64.bat file contains this for tcl: - nmake -f makefile.vc DEBUG=1 MACHINE=AMD64 INSTALLDIR=..\..\tcltk64 clean all install - -So for a release build, you'd call it as: - nmake -f makefile.vc MACHINE=AMD64 INSTALLDIR=..\..\tcltk64 clean all install - -Note that the above command is called from within ..\..\tcl-8.6.1.0\win -(relative to this directory); don't forget to build Tk as well as Tcl! - -This will be cleaned up in the future; http://bugs.python.org/issue15968 -tracks adding a new tcltk.vcxproj file that will build Tcl/Tk and Tix -the same way the other external projects listed above are built. +though you may have to change folder names or pass the names to MSBuild +as the values of certain properties in order for the build solution to +find them. This is an advanced topic and not necessarily fully +supported. Building for AMD64 @@ -275,10 +280,7 @@ Building for AMD64 The build process for AMD64 / x64 is very similar to standard builds, you just have to set x64 as platform. In addition, the HOST_PYTHON environment variable must point to a Python interpreter (at least 2.4), -to support cross-compilation from Win32. Note that Visual Studio -requires either Standard Edition or better, or Express Edition with the -Windows SDK 64-bit compilers to be available in order to build 64-bit -binaries. +to support cross-compilation from Win32. Profile Guided Optimization @@ -313,30 +315,22 @@ also have to change the "Runtime Library" from "Multi-threaded DLL Visual Studio properties ------------------------ -The PCbuild solution makes heavy use of Visual Studio property files -(*.props). The properties can be viewed and altered in the Property -Manager (View -> Other Windows -> Property Manager). - -The property files used are (+-- = "also imports"): - * debug (debug macro: _DEBUG) - * pginstrument (PGO) - * pgupdate (PGO) - +-- pginstrument - * pyd (python extension, release build) - +-- release - +-- pyproject - * pyd_d (python extension, debug build) - +-- debug - +-- pyproject - * pyproject (base settings for all projects, user macros like PyDllName) - * release (release macro: NDEBUG) - * sqlite3 (used only by sqlite3.vcxproj) - * x64 (AMD64 / x64 platform specific settings) - -The pyproject property file defines _WIN32 and x64 defines _WIN64 and -_M_X64 although the macros are set by the compiler, too. The GUI doesn't -always know about the macros and confuse the user with false -information. +The PCbuild solution makes use of Visual Studio property files (*.props) +to simplify each project. The properties can be viewed in the Property +Manager (View -> Other Windows -> Property Manager) but should be +carefully modified by hand. + +The property files used are: + * python (versions, directories and build names) + * pyproject (base settings for all projects) + * openssl (used by libeay and ssleay projects) + * tcltk (used by _tkinter, tcl, tk and tix projects) + +The pyproject property file defines all of the build settings for each +project, with some projects overriding certain specific values. The GUI +doesn't always reflect the correct settings and may confuse the user +with false information, especially for settings that automatically adapt +for diffirent configurations. Your Own Extension DLLs diff --git a/PCbuild/release.props b/PCbuild/release.props deleted file mode 100644 index acfe3e45ba2e..000000000000 --- a/PCbuild/release.props +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - <_ProjectFileVersion>10.0.30319.1 - - - - NDEBUG;%(PreprocessorDefinitions) - - - - - $(PyDebugExt) - - - \ No newline at end of file diff --git a/PCbuild/rt.bat b/PCbuild/rt.bat index 7129e203491f..5041cd3ea25e 100644 --- a/PCbuild/rt.bat +++ b/PCbuild/rt.bat @@ -9,7 +9,8 @@ rem -q runs the tests just once, and without deleting .py[co] files. rem -x64 Run the 64-bit build of python (or python_d if -d was specified) rem from the 'amd64' dir instead of the 32-bit build in this dir. rem All leading instances of these switches are shifted off, and -rem whatever remains is passed to regrtest.py. For example, +rem whatever remains (up to 9 arguments) is passed to regrtest.py. +rem For example, rem rt -O -d -x test_thread rem runs rem python_d -O ../lib/test/regrtest.py -x test_thread @@ -26,25 +27,24 @@ rem rt -u "network,largefile" setlocal -set prefix=.\ +set pcbuild=%~dp0 +set prefix=%pcbuild%win32\ set suffix= set qmode= set dashO= -set tcltk=tcltk :CheckOpts if "%1"=="-O" (set dashO=-O) & shift & goto CheckOpts if "%1"=="-q" (set qmode=yes) & shift & goto CheckOpts if "%1"=="-d" (set suffix=_d) & shift & goto CheckOpts -if "%1"=="-x64" (set prefix=amd64) & (set tcltk=tcltk64) & shift & goto CheckOpts +if "%1"=="-x64" (set prefix=%pcbuild%amd64\) & shift & goto CheckOpts -PATH %PATH%;%~dp0..\..\%tcltk%\bin -set exe=%prefix%\python%suffix% -set cmd=%exe% %dashO% -Wd -E -bb ../lib/test/regrtest.py %1 %2 %3 %4 %5 %6 %7 %8 %9 +set exe=%prefix%python%suffix%.exe +set cmd="%exe%" %dashO% -Wd -E -bb "%pcbuild%..\lib\test\regrtest.py" %1 %2 %3 %4 %5 %6 %7 %8 %9 if defined qmode goto Qmode echo Deleting .pyc/.pyo files ... -%exe% rmpyc.py +"%exe%" "%pcbuild%rmpyc.py" echo on %cmd% diff --git a/PCbuild/select.vcxproj b/PCbuild/select.vcxproj index 7c36d646b724..3cd0694baa5f 100644 --- a/PCbuild/select.vcxproj +++ b/PCbuild/select.vcxproj @@ -37,186 +37,31 @@ {18CAE28C-B454-46C1-87A0-493D91D97F03} select - Win32Proj + - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - + DynamicLibrary NotSet + + .pyd + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - + <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - ws2_32.lib;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) - 0x1D110000 - - - - - X64 - - - ws2_32.lib;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) - 0x1D110000 - - - - - ws2_32.lib;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) - 0x1D110000 - - - - - X64 - - - ws2_32.lib;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) - 0x1D110000 - - - - - ws2_32.lib;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) - 0x1D110000 - - - - - X64 - - - ws2_32.lib;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) - 0x1D110000 - MachineX64 - - - - - ws2_32.lib;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) - 0x1D110000 - - - - - X64 - + ws2_32.lib;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) 0x1D110000 - MachineX64 diff --git a/PCbuild/sqlite3.props b/PCbuild/sqlite3.props deleted file mode 100644 index d3ee02cf756d..000000000000 --- a/PCbuild/sqlite3.props +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - <_ProjectFileVersion>10.0.30319.1 - - - - $(sqlite3Dir);%(AdditionalIncludeDirectories) - SQLITE_API=__declspec(dllexport);%(PreprocessorDefinitions) - Level1 - - - \ No newline at end of file diff --git a/PCbuild/sqlite3.vcxproj b/PCbuild/sqlite3.vcxproj index daf010dae045..b6246fa78c54 100644 --- a/PCbuild/sqlite3.vcxproj +++ b/PCbuild/sqlite3.vcxproj @@ -37,188 +37,31 @@ {A1A295E5-463C-437F-81CA-1F32367685DA} sqlite3 - Win32Proj + .pyd + false + - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - + DynamicLibrary NotSet - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - + <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - %(AdditionalIncludeDirectories) - - - $(OutDir)$(ProjectName)_d.dll - - - - - X64 - - - %(AdditionalIncludeDirectories) - - - $(OutDir)$(ProjectName)_d.dll - - - - - %(AdditionalIncludeDirectories) - - - $(OutDir)$(ProjectName).dll - - - - - X64 - - - %(AdditionalIncludeDirectories) - - - $(OutDir)$(ProjectName).dll - - - + $(sqlite3Dir);%(AdditionalIncludeDirectories) - - - $(OutDir)$(ProjectName).dll - - - - - X64 - - - %(AdditionalIncludeDirectories) - - - - - %(AdditionalIncludeDirectories) - - - $(OutDir)$(ProjectName).dll - - - - - X64 - - - %(AdditionalIncludeDirectories) + SQLITE_API=__declspec(dllexport);%(PreprocessorDefinitions) + Level1 @@ -228,12 +71,6 @@ - - - {6de10744-e396-40a5-b4e2-1b69aa7c8d31} - false - - diff --git a/PCbuild/ssl.vcxproj b/PCbuild/ssl.vcxproj deleted file mode 100644 index d5eac9ae0435..000000000000 --- a/PCbuild/ssl.vcxproj +++ /dev/null @@ -1,221 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - PGInstrument - Win32 - - - PGInstrument - x64 - - - PGUpdate - Win32 - - - PGUpdate - x64 - - - Release - Win32 - - - Release - x64 - - - - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0} - ssl - MakeFileProj - - - - Makefile - NotSet - - - Makefile - NotSet - - - Makefile - NotSet - - - Makefile - NotSet - - - Makefile - NotSet - - - Makefile - NotSet - - - Makefile - NotSet - - - Makefile - NotSet - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - cd "$(SolutionDir)" -"$(PythonExe)" build_ssl.py Release $(Platform) -a - - - echo OpenSSL must be cleaned manually if you want to rebuild it. - - $(NMakePreprocessorDefinitions) - $(NMakeIncludeSearchPath) - $(NMakeForcedIncludes) - $(NMakeAssemblySearchPath) - $(NMakeForcedUsingAssemblies) - cd "$(SolutionDir)" -"$(PythonExe)" build_ssl.py Release $(Platform) -a - - - echo OpenSSL must be cleaned manually if you want to rebuild it. - - $(NMakePreprocessorDefinitions) - $(NMakeIncludeSearchPath) - $(NMakeForcedIncludes) - $(NMakeAssemblySearchPath) - $(NMakeForcedUsingAssemblies) - cd "$(SolutionDir)" -"$(PythonExe)" build_ssl.py Release $(Platform) -a - - - echo OpenSSL must be cleaned manually if you want to rebuild it. - - $(NMakePreprocessorDefinitions) - $(NMakeIncludeSearchPath) - $(NMakeForcedIncludes) - $(NMakeAssemblySearchPath) - $(NMakeForcedUsingAssemblies) - cd "$(SolutionDir)" -"$(PythonExe)" build_ssl.py Release $(Platform) -a - - - echo OpenSSL must be cleaned manually if you want to rebuild it. - - $(NMakePreprocessorDefinitions) - $(NMakeIncludeSearchPath) - $(NMakeForcedIncludes) - $(NMakeAssemblySearchPath) - $(NMakeForcedUsingAssemblies) - cd "$(SolutionDir)" -"$(PythonExe)" build_ssl.py Release $(Platform) -a - - - echo OpenSSL must be cleaned manually if you want to rebuild it. - - $(NMakePreprocessorDefinitions) - $(NMakeIncludeSearchPath) - $(NMakeForcedIncludes) - $(NMakeAssemblySearchPath) - $(NMakeForcedUsingAssemblies) - cd "$(SolutionDir)" -"$(PythonExe)" build_ssl.py Release $(Platform) -a - - - echo OpenSSL must be cleaned manually if you want to rebuild it. - - $(NMakePreprocessorDefinitions) - $(NMakeIncludeSearchPath) - $(NMakeForcedIncludes) - $(NMakeAssemblySearchPath) - $(NMakeForcedUsingAssemblies) - cd "$(SolutionDir)" -"$(PythonExe)" build_ssl.py Release $(Platform) -a - - - echo OpenSSL must be cleaned manually if you want to rebuild it. - - $(NMakePreprocessorDefinitions) - $(NMakeIncludeSearchPath) - $(NMakeForcedIncludes) - $(NMakeAssemblySearchPath) - $(NMakeForcedUsingAssemblies) - cd "$(SolutionDir)" -"$(PythonExe)" build_ssl.py Release $(Platform) -a - - - echo OpenSSL must be cleaned manually if you want to rebuild it. - - $(NMakePreprocessorDefinitions) - $(NMakeIncludeSearchPath) - $(NMakeForcedIncludes) - $(NMakeAssemblySearchPath) - $(NMakeForcedUsingAssemblies) - - - - - - {b11d750f-cd1f-4a96-85ce-e69a5c5259f9} - false - - - - - - \ No newline at end of file diff --git a/PCbuild/ssleay.vcxproj b/PCbuild/ssleay.vcxproj new file mode 100644 index 000000000000..fa8c5d364e31 --- /dev/null +++ b/PCbuild/ssleay.vcxproj @@ -0,0 +1,119 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + PGInstrument + Win32 + + + PGInstrument + x64 + + + PGUpdate + Win32 + + + PGUpdate + x64 + + + Debug + x64 + + + Release + x64 + + + + {10615B24-73BF-4EFA-93AA-236916321317} + ssleay + + + + + + + StaticLibrary + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PCbuild/tcl.vcxproj b/PCbuild/tcl.vcxproj new file mode 100644 index 000000000000..8f2544a74e67 --- /dev/null +++ b/PCbuild/tcl.vcxproj @@ -0,0 +1,90 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + PGInstrument + Win32 + + + PGInstrument + x64 + + + PGUpdate + Win32 + + + PGUpdate + x64 + + + Debug + x64 + + + Release + x64 + + + + {B5FD6F1D-129E-4BFF-9340-03606FAC7283} + + + + + + + + Makefile + $(tcltkDir) + $(OutDir)bin\$(tclDLLName) + + + + + + + + + + symbols + INSTALLDIR="$(OutDir.TrimEnd(`\`))" INSTALL_DIR="$(OutDir.TrimEnd(`\`))" + DEBUGFLAGS="-wd4456 -wd4457 -wd4458 -wd4459 -wd4996" + setlocal +@(ExpectedOutputs->'if not exist "%(FullPath)" goto build',' +') +goto :eof +:build +set VCINSTALLDIR=$(VCInstallDir) +cd /D "$(tclDir)win" +nmake -f makefile.vc MACHINE=$(TclMachine) OPTS=$(TclOpts) $(TclDirs) $(DebugFlags) core shell dlls +nmake -f makefile.vc MACHINE=$(TclMachine) OPTS=$(TclOpts) $(TclDirs) $(DebugFlags) install-binaries install-libraries + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PCbuild/tcltk.props b/PCbuild/tcltk.props new file mode 100644 index 000000000000..f5a8643559c7 --- /dev/null +++ b/PCbuild/tcltk.props @@ -0,0 +1,45 @@ + + + + + 8 + 6 + 3 + 1 + $(TclMajorVersion) + $(TclMinorVersion) + $(TclPatchLevel) + $(TclRevision) + 8 + 4 + 3 + 4 + $(ExternalsDir)tcl-core-$(TclMajorVersion).$(TclMinorVersion).$(TclPatchLevel).$(TclRevision)\ + $(ExternalsDir)tk-$(TkMajorVersion).$(TkMinorVersion).$(TkPatchLevel).$(TkRevision)\ + $(ExternalsDir)tix-$(TixMajorVersion).$(TixMinorVersion).$(TixPatchLevel).$(TixRevision)\ + $(ExternalsDir)tcltk\ + $(ExternalsDir)tcltk64\ + g + tcl$(TclMajorVersion)$(TclMinorVersion)t$(TclDebugExt).dll + tcl$(TclMajorVersion)$(TclMinorVersion)t$(TclDebugExt).lib + tclsh$(TclMajorVersion)$(TclMinorVersion)t$(TclDebugExt).exe + tk$(TkMajorVersion)$(TkMinorVersion)t$(TclDebugExt).dll + tk$(TkMajorVersion)$(TkMinorVersion)t$(TclDebugExt).lib + tix$(TixMajorVersion)$(TixMinorVersion)$(TclDebugExt).dll + $(tcltkDir)lib\tix$(TixMajorVersion).$(TixMinorVersion).$(TixPatchLevel)\$(tixDLLName) + $(tcltkDir)lib\tcl$(TclMajorVersion)$(TclMinorVersion)t$(TclDebugExt).lib;$(tcltkDir)lib\tk$(TkMajorVersion)$(TkMinorVersion)t$(TclDebugExt).lib + IX86 + AMD64 + TCL_MAJOR_VERSION=$(TclMajorVersion) TCL_MINOR_VERSION=$(TclMinorVersion) TCL_PATCH_LEVEL=$(TclPatchLevel) + TCL_MAJOR=$(TclMajorVersion) TCL_MINOR=$(TclMinorVersion) TCL_PATCH=$(TclPatchLevel) + TK_MAJOR_VERSION=$(TkMajorVersion) TK_MINOR_VERSION=$(TkMinorVersion) TK_PATCH_LEVEL=$(TkPatchLevel) + + Release + Debug + $(BuildDirTop)_$(TclMachine) + $(BuildDirTop)_VC13 + $(BuildDirTop)_VC12 + $(BuildDirTop)_VC11 + $(BuildDirTop)_VC10 + + \ No newline at end of file diff --git a/PCbuild/tix.vcxproj b/PCbuild/tix.vcxproj new file mode 100644 index 000000000000..74a6b84f5732 --- /dev/null +++ b/PCbuild/tix.vcxproj @@ -0,0 +1,94 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + PGInstrument + Win32 + + + PGInstrument + x64 + + + PGUpdate + Win32 + + + PGUpdate + x64 + + + Debug + x64 + + + Release + x64 + + + + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555} + tix + + + + + + + + Makefile + $(tcltkDir) + $(tixDLLPath) + + + + + + + + + + msvcrt + symbols,msvcrt + BUILDDIRTOP="$(BuildDirTop)" TCL_DIR="$(tclDir.TrimEnd(`\`))" TK_DIR="$(tkDir.TrimEnd(`\`))" INSTALL_DIR="$(OutDir.TrimEnd(`\`))" + DEBUG=1 NODEBUG=0 TCL_DBGX=g DEBUGFLAGS="-wd4456 -wd4457 -wd4458 -wd4459 -wd4996" + DEBUG=0 NODEBUG=1 + setlocal +@(ExpectedOutputs->'if not exist "%(FullPath)" goto build',' +') +goto :eof +:build +set VCINSTALLDIR=$(VCInstallDir) +cd /D "$(tixDir)win" +nmake /nologo -f makefile.vc MACHINE=$(TclMachine) $(DebugFlags) $(TclShortVersions) $(TixDirs) all install + + rmdir /q/s "$(OutDir.TrimEnd(`\`))" + + + + + {b5fd6f1d-129e-4bff-9340-03606fac7283} + false + + + {7e85eccf-a72c-4da4-9e52-884508e80ba1} + false + + + + + + + + + + + \ No newline at end of file diff --git a/PCbuild/tk.vcxproj b/PCbuild/tk.vcxproj new file mode 100644 index 000000000000..20749f719f59 --- /dev/null +++ b/PCbuild/tk.vcxproj @@ -0,0 +1,95 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + PGInstrument + Win32 + + + PGInstrument + x64 + + + PGUpdate + Win32 + + + PGUpdate + x64 + + + Debug + x64 + + + Release + x64 + + + + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1} + tk + + + + + + + + Makefile + $(tcltkDir) + $(OutDir)bin\$(tkDLLName) + + + + + + + + + + msvcrt + symbols,msvcrt + TCLDIR="$(tclDir.TrimEnd(`\`))" INSTALLDIR="$(OutDir.TrimEnd(`\`))" + DEBUGFLAGS="-wd4456 -wd4457 -wd4458 -wd4459 -wd4996" + setlocal +@(ExpectedOutputs->'if not exist "%(FullPath)" goto build',' +') +goto :eof +:build +set VCINSTALLDIR=$(VCInstallDir) +cd /D "$(tkDir)win" +nmake /nologo -f makefile.vc RC=rc MACHINE=$(TclMachine) OPTS=$(TkOpts) $(TkDirs) $(DebugFlags) all +nmake /nologo -f makefile.vc RC=rc MACHINE=$(TclMachine) OPTS=$(TkOpts) $(TkDirs) $(DebugFlags) install-binaries install-libraries + + + + + {b5fd6f1d-129e-4bff-9340-03606fac7283} + false + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PCbuild/unicodedata.vcxproj b/PCbuild/unicodedata.vcxproj index c9d5278684a3..a3071fbf8eea 100644 --- a/PCbuild/unicodedata.vcxproj +++ b/PCbuild/unicodedata.vcxproj @@ -39,168 +39,29 @@ unicodedata Win32Proj + - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - + DynamicLibrary NotSet + + .pyd + - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - + <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - 0x1D120000 - - - - - X64 - - - 0x1D120000 - - - - - 0x1D120000 - - - - - X64 - - - 0x1D120000 - - - - - 0x1D120000 - - - - - X64 - - - 0x1D120000 - MachineX64 - - - - - 0x1D120000 - - - - - X64 - + 0x1D120000 - MachineX64 diff --git a/PCbuild/vs9to10.py b/PCbuild/vs9to10.py deleted file mode 100644 index eb7dab50b882..000000000000 --- a/PCbuild/vs9to10.py +++ /dev/null @@ -1,56 +0,0 @@ -#Run this file after automatic conversion of the VisualStudio 2008 solution by VisualStudio 2010. -#This can be done whenever the 2008 solution changes. -#It will make the necessary cleanup and updates to the vcxproj files -#the .props files need to be maintained by hand if the .vsprops files change - -from __future__ import with_statement -import sys -import os -import os.path - -def vs9to10(src, dest): - for name in os.listdir(src): - path, ext = os.path.splitext(name) - if ext.lower() not in ('.vcxproj',): - continue - - filename = os.path.normpath(os.path.join(src, name)) - destname = os.path.normpath(os.path.join(dest, name)) - print("%s -> %s" % (filename, destname)) - - lines = [] - lastline = b"" - importgroup = False - with open(filename, 'rb') as fin: - for line in fin: - #remove redundant linker output info - if b"" in line: - continue - if b"" in line: - continue - if b"" in line and b"" in line: - continue - - #add new property sheet to the pythoncore - if importgroup and "pythoncore" in name.lower(): - if b"" in line: - if b"debug.props" in lastline: - lines.append(b' \r\n') - elif b"pythoncore" not in lastline: - lines.append(b' \r\n') - if b"" in line: - importgroup = False - lines.append(line) - lastline = line - with open(destname, 'wb') as fout: - for line in lines: - fout.write(line) - -if __name__ == "__main__": - src = "." if len(sys.argv) < 2 else sys.argv[1] - name = os.path.basename(os.path.abspath(src)) - dest = os.path.abspath(os.path.join(src, "..", name + "Upd")) - os.makedirs(dest) - vs9to10(src, dest) diff --git a/PCbuild/vs9to8.py b/PCbuild/vs9to8.py deleted file mode 100644 index 3b88a16c27c5..000000000000 --- a/PCbuild/vs9to8.py +++ /dev/null @@ -1,34 +0,0 @@ -from __future__ import with_statement -import os - -def vs9to8(src, dest): - for name in os.listdir(src): - path, ext = os.path.splitext(name) - if ext.lower() not in ('.sln', '.vcproj', '.vsprops'): - continue - - filename = os.path.normpath(os.path.join(src, name)) - destname = os.path.normpath(os.path.join(dest, name)) - print("%s -> %s" % (filename, destname)) - - with open(filename, 'rU') as fin: - lines = fin.read() - lines = lines.replace('Version="9,00"', 'Version="8.00"') - lines = lines.replace('Version="9.00"', 'Version="8.00"') - lines = lines.replace('Format Version 10.00', 'Format Version 9.00') - lines = lines.replace('Visual Studio 2008', 'Visual Studio 2005') - - lines = lines.replace('wininst-9.0', 'wininst-8.0') - lines = lines.replace('..\\', '..\\..\\') - lines = lines.replace('..\\..\\..\\..\\', '..\\..\\..\\') - - # Bah. VS8.0 does not expand macros in file names. - # Replace them here. - lines = lines.replace('$(sqlite3Dir)', '..\\..\\..\\sqlite-3.6.21') - - with open(destname, 'wb') as fout: - lines = lines.replace("\n", "\r\n").encode() - fout.write(lines) - -if __name__ == "__main__": - vs9to8(src=".", dest="../PC/VS8.0") diff --git a/PCbuild/winsound.vcxproj b/PCbuild/winsound.vcxproj index cf518e993642..540235af22e2 100644 --- a/PCbuild/winsound.vcxproj +++ b/PCbuild/winsound.vcxproj @@ -39,168 +39,29 @@ winsound Win32Proj + - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - + DynamicLibrary NotSet + + .pyd + - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - + <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - winmm.lib;%(AdditionalDependencies) - - - - - X64 - - - winmm.lib;%(AdditionalDependencies) - - - - - winmm.lib;%(AdditionalDependencies) - - - - - X64 - - - winmm.lib;%(AdditionalDependencies) - - - - - winmm.lib;%(AdditionalDependencies) - - - - - X64 - - - winmm.lib;%(AdditionalDependencies) - MachineX64 - - - - - winmm.lib;%(AdditionalDependencies) - - - - - X64 - + winmm.lib;%(AdditionalDependencies) - MachineX64 diff --git a/PCbuild/x64.props b/PCbuild/x64.props deleted file mode 100644 index 985c0ef7f7f8..000000000000 --- a/PCbuild/x64.props +++ /dev/null @@ -1,20 +0,0 @@ - - - - $(HOST_PYTHON) - - - - false - _WIN64;_M_X64;%(PreprocessorDefinitions) - - - MachineX64 - - - - - $(PythonExe) - - - diff --git a/PCbuild/xxlimited.vcxproj b/PCbuild/xxlimited.vcxproj index 26bc20d6ec56..4484dbaa9624 100644 --- a/PCbuild/xxlimited.vcxproj +++ b/PCbuild/xxlimited.vcxproj @@ -1,6 +1,14 @@  + + Debug + Win32 + + + Debug + x64 + PGInstrument Win32 @@ -31,161 +39,42 @@ xxlimited Win32Proj + - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - + DynamicLibrary NotSet - true + false + + .pyd + - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - + <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - NDEBUG;_WIN32;_WINDLL;Py_LIMITED_API - - - wsock32.lib;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) - 0x1D110000 - - - - - X64 - - - wsock32.lib;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) - 0x1D110000 - - - - - Py_LIMITED_API;%(PreprocessorDefinitions) - - - wsock32.lib;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) - 0x1D110000 - - - - - X64 - - - wsock32.lib;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) - 0x1D110000 - MachineX64 - - - + - Py_LIMITED_API;%(PreprocessorDefinitions) + %(PreprocessorDefinitions);Py_LIMITED_API=0x03040000 wsock32.lib;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) - 0x1D110000 - - - - - X64 - - - wsock32.lib;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) 0x1D110000 - MachineX64 - - {cf7ac3d1-e2df-41d2-bea6-1e2556cdea26} + + {885d4898-d08d-4091-9c40-c700cfe3fc5a} diff --git a/Parser/Python.asdl b/Parser/Python.asdl index debd89edb851..792cab78e652 100644 --- a/Parser/Python.asdl +++ b/Parser/Python.asdl @@ -91,7 +91,7 @@ module Python boolop = And | Or - operator = Add | Sub | Mult | Div | Mod | Pow | LShift + operator = Add | Sub | Mult | MatMult | Div | Mod | Pow | LShift | RShift | BitOr | BitXor | BitAnd | FloorDiv unaryop = Invert | Not | UAdd | USub diff --git a/Parser/asdl.py b/Parser/asdl.py index fc1b16c66815..121cdab95203 100644 --- a/Parser/asdl.py +++ b/Parser/asdl.py @@ -1,255 +1,52 @@ -"""An implementation of the Zephyr Abstract Syntax Definition Language. - -See http://asdl.sourceforge.net/ and -http://www.cs.princeton.edu/research/techreps/TR-554-97 - -Only supports top level module decl, not view. I'm guessing that view -is intended to support the browser and I'm not interested in the -browser. - -Changes for Python: Add support for module versions -""" - -import os -import sys -import traceback - -import spark - -def output(*strings): - for s in strings: - sys.stdout.write(str(s) + "\n") - - -class Token(object): - # spark seems to dispatch in the parser based on a token's - # type attribute - def __init__(self, type, lineno): - self.type = type - self.lineno = lineno - - def __str__(self): - return self.type - +#------------------------------------------------------------------------------- +# Parser for ASDL [1] definition files. Reads in an ASDL description and parses +# it into an AST that describes it. +# +# The EBNF we're parsing here: Figure 1 of the paper [1]. Extended to support +# modules and attributes after a product. Words starting with Capital letters +# are terminals. Literal tokens are in "double quotes". Others are +# non-terminals. Id is either TokenId or ConstructorId. +# +# module ::= "module" Id "{" [definitions] "}" +# definitions ::= { TypeId "=" type } +# type ::= product | sum +# product ::= fields ["attributes" fields] +# fields ::= "(" { field, "," } field ")" +# field ::= TypeId ["?" | "*"] [Id] +# sum ::= constructor { "|" constructor } ["attributes" fields] +# constructor ::= ConstructorId [fields] +# +# [1] "The Zephyr Abstract Syntax Description Language" by Wang, et. al. See +# http://asdl.sourceforge.net/ +#------------------------------------------------------------------------------- +from collections import namedtuple +import re + +__all__ = [ + 'builtin_types', 'parse', 'AST', 'Module', 'Type', 'Constructor', + 'Field', 'Sum', 'Product', 'VisitorBase', 'Check', 'check'] + +# The following classes define nodes into which the ASDL description is parsed. +# Note: this is a "meta-AST". ASDL files (such as Python.asdl) describe the AST +# structure used by a programming language. But ASDL files themselves need to be +# parsed. This module parses ASDL files and uses a simple AST to represent them. +# See the EBNF at the top of the file to understand the logical connection +# between the various node types. + +builtin_types = {'identifier', 'string', 'bytes', 'int', 'object', 'singleton'} + +class AST: def __repr__(self): - return str(self) - -class Id(Token): - def __init__(self, value, lineno): - self.type = 'Id' - self.value = value - self.lineno = lineno - - def __str__(self): - return self.value - -class String(Token): - def __init__(self, value, lineno): - self.type = 'String' - self.value = value - self.lineno = lineno - -class ASDLSyntaxError(Exception): - - def __init__(self, lineno, token=None, msg=None): - self.lineno = lineno - self.token = token - self.msg = msg - - def __str__(self): - if self.msg is None: - return "Error at '%s', line %d" % (self.token, self.lineno) - else: - return "%s, line %d" % (self.msg, self.lineno) - -class ASDLScanner(spark.GenericScanner, object): - - def tokenize(self, input): - self.rv = [] - self.lineno = 1 - super(ASDLScanner, self).tokenize(input) - return self.rv - - def t_id(self, s): - r"[\w\.]+" - # XXX doesn't distinguish upper vs. lower, which is - # significant for ASDL. - self.rv.append(Id(s, self.lineno)) - - def t_string(self, s): - r'"[^"]*"' - self.rv.append(String(s, self.lineno)) - - def t_xxx(self, s): # not sure what this production means - r"<=" - self.rv.append(Token(s, self.lineno)) - - def t_punctuation(self, s): - r"[\{\}\*\=\|\(\)\,\?\:]" - self.rv.append(Token(s, self.lineno)) - - def t_comment(self, s): - r"\-\-[^\n]*" - pass - - def t_newline(self, s): - r"\n" - self.lineno += 1 - - def t_whitespace(self, s): - r"[ \t]+" - pass - - def t_default(self, s): - r" . +" - raise ValueError("unmatched input: %r" % s) - -class ASDLParser(spark.GenericParser, object): - def __init__(self): - super(ASDLParser, self).__init__("module") - - def typestring(self, tok): - return tok.type - - def error(self, tok): - raise ASDLSyntaxError(tok.lineno, tok) - - def p_module_0(self, info): - " module ::= Id Id { } " - module, name, _0, _1 = info - if module.value != "module": - raise ASDLSyntaxError(module.lineno, - msg="expected 'module', found %s" % module) - return Module(name, None) - - def p_module(self, info): - " module ::= Id Id { definitions } " - module, name, _0, definitions, _1 = info - if module.value != "module": - raise ASDLSyntaxError(module.lineno, - msg="expected 'module', found %s" % module) - return Module(name, definitions) - - def p_definition_0(self, definition): - " definitions ::= definition " - return definition[0] - - def p_definition_1(self, definitions): - " definitions ::= definition definitions " - return definitions[0] + definitions[1] - - def p_definition(self, info): - " definition ::= Id = type " - id, _, type = info - return [Type(id, type)] - - def p_type_0(self, product): - " type ::= product " - return product[0] - - def p_type_1(self, sum): - " type ::= sum " - return Sum(sum[0]) - - def p_type_2(self, info): - " type ::= sum Id ( fields ) " - sum, id, _0, attributes, _1 = info - if id.value != "attributes": - raise ASDLSyntaxError(id.lineno, - msg="expected attributes, found %s" % id) - return Sum(sum, attributes) - - def p_product_0(self, info): - " product ::= ( fields ) " - _0, fields, _1 = info - return Product(fields) - - def p_product_1(self, info): - " product ::= ( fields ) Id ( fields ) " - _0, fields, _1, id, _2, attributes, _3 = info - if id.value != "attributes": - raise ASDLSyntaxError(id.lineno, - msg="expected attributes, found %s" % id) - return Product(fields, attributes) - - def p_sum_0(self, constructor): - " sum ::= constructor " - return [constructor[0]] - - def p_sum_1(self, info): - " sum ::= constructor | sum " - constructor, _, sum = info - return [constructor] + sum - - def p_sum_2(self, info): - " sum ::= constructor | sum " - constructor, _, sum = info - return [constructor] + sum - - def p_constructor_0(self, id): - " constructor ::= Id " - return Constructor(id[0]) - - def p_constructor_1(self, info): - " constructor ::= Id ( fields ) " - id, _0, fields, _1 = info - return Constructor(id, fields) - - def p_fields_0(self, field): - " fields ::= field " - return [field[0]] - - def p_fields_1(self, info): - " fields ::= fields , field " - fields, _, field = info - return fields + [field] - - def p_field_0(self, type_): - " field ::= Id " - return Field(type_[0]) - - def p_field_1(self, info): - " field ::= Id Id " - type, name = info - return Field(type, name) - - def p_field_2(self, info): - " field ::= Id * Id " - type, _, name = info - return Field(type, name, seq=True) - - def p_field_3(self, info): - " field ::= Id ? Id " - type, _, name = info - return Field(type, name, opt=True) - - def p_field_4(self, type_): - " field ::= Id * " - return Field(type_[0], seq=True) - - def p_field_5(self, type_): - " field ::= Id ? " - return Field(type[0], opt=True) - -builtin_types = ("identifier", "string", "bytes", "int", "object", "singleton") - -# below is a collection of classes to capture the AST of an AST :-) -# not sure if any of the methods are useful yet, but I'm adding them -# piecemeal as they seem helpful - -class AST(object): - pass # a marker class + raise NotImplementedError class Module(AST): def __init__(self, name, dfns): self.name = name self.dfns = dfns - self.types = {} # maps type name to value (from dfns) - for type in dfns: - self.types[type.name.value] = type.value + self.types = {type.name: type.value for type in dfns} def __repr__(self): - return "Module(%s, %s)" % (self.name, self.dfns) + return 'Module({0.name}, {0.dfns})'.format(self) class Type(AST): def __init__(self, name, value): @@ -257,7 +54,7 @@ def __init__(self, name, value): self.value = value def __repr__(self): - return "Type(%s, %s)" % (self.name, self.value) + return 'Type({0.name}, {0.value})'.format(self) class Constructor(AST): def __init__(self, name, fields=None): @@ -265,7 +62,7 @@ def __init__(self, name, fields=None): self.fields = fields or [] def __repr__(self): - return "Constructor(%s, %s)" % (self.name, self.fields) + return 'Constructor({0.name}, {0.fields})'.format(self) class Field(AST): def __init__(self, type, name=None, seq=False, opt=False): @@ -282,9 +79,9 @@ def __repr__(self): else: extra = "" if self.name is None: - return "Field(%s%s)" % (self.type, extra) + return 'Field({0.type}{1})'.format(self, extra) else: - return "Field(%s, %s%s)" % (self.type, self.name, extra) + return 'Field({0.type}, {0.name}{1})'.format(self, extra) class Sum(AST): def __init__(self, types, attributes=None): @@ -292,10 +89,10 @@ def __init__(self, types, attributes=None): self.attributes = attributes or [] def __repr__(self): - if self.attributes is None: - return "Sum(%s)" % self.types + if self.attributes: + return 'Sum({0.types}, {0.attributes})'.format(self) else: - return "Sum(%s, %s)" % (self.types, self.attributes) + return 'Sum({0.types})'.format(self) class Product(AST): def __init__(self, fields, attributes=None): @@ -303,49 +100,43 @@ def __init__(self, fields, attributes=None): self.attributes = attributes or [] def __repr__(self): - if self.attributes is None: - return "Product(%s)" % self.fields + if self.attributes: + return 'Product({0.fields}, {0.attributes})'.format(self) else: - return "Product(%s, %s)" % (self.fields, self.attributes) + return 'Product({0.fields})'.format(self) -class VisitorBase(object): +# A generic visitor for the meta-AST that describes ASDL. This can be used by +# emitters. Note that this visitor does not provide a generic visit method, so a +# subclass needs to define visit methods from visitModule to as deep as the +# interesting node. +# We also define a Check visitor that makes sure the parsed ASDL is well-formed. - def __init__(self, skip=False): +class VisitorBase(object): + """Generic tree visitor for ASTs.""" + def __init__(self): self.cache = {} - self.skip = skip - def visit(self, object, *args): - meth = self._dispatch(object) - if meth is None: - return - try: - meth(object, *args) - except Exception: - output("Error visiting" + repr(object)) - output(str(sys.exc_info()[1])) - traceback.print_exc() - # XXX hack - if hasattr(self, 'file'): - self.file.flush() - os._exit(1) - - def _dispatch(self, object): - assert isinstance(object, AST), repr(object) - klass = object.__class__ + def visit(self, obj, *args): + klass = obj.__class__ meth = self.cache.get(klass) if meth is None: methname = "visit" + klass.__name__ - if self.skip: - meth = getattr(self, methname, None) - else: - meth = getattr(self, methname) + meth = getattr(self, methname, None) self.cache[klass] = meth - return meth + if meth: + try: + meth(obj, *args) + except Exception as e: + print("Error visiting %r: %s" % (obj, e)) + raise class Check(VisitorBase): + """A visitor that checks a parsed ASDL tree for correctness. + Errors are printed and accumulated. + """ def __init__(self): - super(Check, self).__init__(skip=True) + super(Check, self).__init__() self.cons = {} self.errors = 0 self.types = {} @@ -367,8 +158,8 @@ def visitConstructor(self, cons, name): if conflict is None: self.cons[key] = name else: - output("Redefinition of constructor %s" % key) - output("Defined in %s and %s" % (conflict, name)) + print('Redefinition of constructor {}'.format(key)) + print('Defined in {} and {}'.format(conflict, name)) self.errors += 1 for f in cons.fields: self.visit(f, key) @@ -383,6 +174,11 @@ def visitProduct(self, prod, name): self.visit(f, name) def check(mod): + """Check the parsed ASDL tree for correctness. + + Return True if success. For failure, the errors are printed out and False + is returned. + """ v = Check() v.visit(mod) @@ -390,47 +186,190 @@ def check(mod): if t not in mod.types and not t in builtin_types: v.errors += 1 uses = ", ".join(v.types[t]) - output("Undefined type %s, used in %s" % (t, uses)) - + print('Undefined type {}, used in {}'.format(t, uses)) return not v.errors -def parse(file): - scanner = ASDLScanner() - parser = ASDLParser() - - f = open(file) - try: - buf = f.read() - finally: - f.close() - tokens = scanner.tokenize(buf) - try: - return parser.parse(tokens) - except ASDLSyntaxError: - err = sys.exc_info()[1] - output(str(err)) - lines = buf.split("\n") - output(lines[err.lineno - 1]) # lines starts at 0, files at 1 - -if __name__ == "__main__": - import glob - import sys - - if len(sys.argv) > 1: - files = sys.argv[1:] - else: - testdir = "tests" - files = glob.glob(testdir + "/*.asdl") - - for file in files: - output(file) - mod = parse(file) - if not mod: - break - output("module", mod.name) - output(len(mod.dfns), "definitions") - if not check(mod): - output("Check failed") +# The ASDL parser itself comes next. The only interesting external interface +# here is the top-level parse function. + +def parse(filename): + """Parse ASDL from the given file and return a Module node describing it.""" + with open(filename) as f: + parser = ASDLParser() + return parser.parse(f.read()) + +# Types for describing tokens in an ASDL specification. +class TokenKind: + """TokenKind is provides a scope for enumerated token kinds.""" + (ConstructorId, TypeId, Equals, Comma, Question, Pipe, Asterisk, + LParen, RParen, LBrace, RBrace) = range(11) + + operator_table = { + '=': Equals, ',': Comma, '?': Question, '|': Pipe, '(': LParen, + ')': RParen, '*': Asterisk, '{': LBrace, '}': RBrace} + +Token = namedtuple('Token', 'kind value lineno') + +class ASDLSyntaxError(Exception): + def __init__(self, msg, lineno=None): + self.msg = msg + self.lineno = lineno or '' + + def __str__(self): + return 'Syntax error on line {0.lineno}: {0.msg}'.format(self) + +def tokenize_asdl(buf): + """Tokenize the given buffer. Yield Token objects.""" + for lineno, line in enumerate(buf.splitlines(), 1): + for m in re.finditer(r'\s*(\w+|--.*|.)', line.strip()): + c = m.group(1) + if c[0].isalpha(): + # Some kind of identifier + if c[0].isupper(): + yield Token(TokenKind.ConstructorId, c, lineno) + else: + yield Token(TokenKind.TypeId, c, lineno) + elif c[:2] == '--': + # Comment + break + else: + # Operators + try: + op_kind = TokenKind.operator_table[c] + except KeyError: + raise ASDLSyntaxError('Invalid operator %s' % c, lineno) + yield Token(op_kind, c, lineno) + +class ASDLParser: + """Parser for ASDL files. + + Create, then call the parse method on a buffer containing ASDL. + This is a simple recursive descent parser that uses tokenize_asdl for the + lexing. + """ + def __init__(self): + self._tokenizer = None + self.cur_token = None + + def parse(self, buf): + """Parse the ASDL in the buffer and return an AST with a Module root. + """ + self._tokenizer = tokenize_asdl(buf) + self._advance() + return self._parse_module() + + def _parse_module(self): + if self._at_keyword('module'): + self._advance() else: - for dfn in mod.dfns: - output(dfn.name, dfn.value) + raise ASDLSyntaxError( + 'Expected "module" (found {})'.format(self.cur_token.value), + self.cur_token.lineno) + name = self._match(self._id_kinds) + self._match(TokenKind.LBrace) + defs = self._parse_definitions() + self._match(TokenKind.RBrace) + return Module(name, defs) + + def _parse_definitions(self): + defs = [] + while self.cur_token.kind == TokenKind.TypeId: + typename = self._advance() + self._match(TokenKind.Equals) + type = self._parse_type() + defs.append(Type(typename, type)) + return defs + + def _parse_type(self): + if self.cur_token.kind == TokenKind.LParen: + # If we see a (, it's a product + return self._parse_product() + else: + # Otherwise it's a sum. Look for ConstructorId + sumlist = [Constructor(self._match(TokenKind.ConstructorId), + self._parse_optional_fields())] + while self.cur_token.kind == TokenKind.Pipe: + # More constructors + self._advance() + sumlist.append(Constructor( + self._match(TokenKind.ConstructorId), + self._parse_optional_fields())) + return Sum(sumlist, self._parse_optional_attributes()) + + def _parse_product(self): + return Product(self._parse_fields(), self._parse_optional_attributes()) + + def _parse_fields(self): + fields = [] + self._match(TokenKind.LParen) + while self.cur_token.kind == TokenKind.TypeId: + typename = self._advance() + is_seq, is_opt = self._parse_optional_field_quantifier() + id = (self._advance() if self.cur_token.kind in self._id_kinds + else None) + fields.append(Field(typename, id, seq=is_seq, opt=is_opt)) + if self.cur_token.kind == TokenKind.RParen: + break + elif self.cur_token.kind == TokenKind.Comma: + self._advance() + self._match(TokenKind.RParen) + return fields + + def _parse_optional_fields(self): + if self.cur_token.kind == TokenKind.LParen: + return self._parse_fields() + else: + return None + + def _parse_optional_attributes(self): + if self._at_keyword('attributes'): + self._advance() + return self._parse_fields() + else: + return None + + def _parse_optional_field_quantifier(self): + is_seq, is_opt = False, False + if self.cur_token.kind == TokenKind.Asterisk: + is_seq = True + self._advance() + elif self.cur_token.kind == TokenKind.Question: + is_opt = True + self._advance() + return is_seq, is_opt + + def _advance(self): + """ Return the value of the current token and read the next one into + self.cur_token. + """ + cur_val = None if self.cur_token is None else self.cur_token.value + try: + self.cur_token = next(self._tokenizer) + except StopIteration: + self.cur_token = None + return cur_val + + _id_kinds = (TokenKind.ConstructorId, TokenKind.TypeId) + + def _match(self, kind): + """The 'match' primitive of RD parsers. + + * Verifies that the current token is of the given kind (kind can + be a tuple, in which the kind must match one of its members). + * Returns the value of the current token + * Reads in the next token + """ + if (isinstance(kind, tuple) and self.cur_token.kind in kind or + self.cur_token.kind == kind + ): + value = self.cur_token.value + self._advance() + return value + else: + raise ASDLSyntaxError( + 'Unmatched {} (found {})'.format(kind, self.cur_token.kind), + self.cur_token.lineno) + + def _at_keyword(self, keyword): + return (self.cur_token.kind == TokenKind.TypeId and + self.cur_token.value == keyword) diff --git a/Parser/asdl_c.py b/Parser/asdl_c.py index 80e432a3e960..a5e35d93fd29 100755 --- a/Parser/asdl_c.py +++ b/Parser/asdl_c.py @@ -1,9 +1,6 @@ #! /usr/bin/env python """Generate C code from an ASDL description.""" -# TO DO -# handle fields that have a type but no name - import os, sys import asdl @@ -14,12 +11,8 @@ def get_c_type(name): """Return a string for the C name of the type. - This function special cases the default types provided by asdl: - identifier, string, int. + This function special cases the default types provided by asdl. """ - # XXX ack! need to figure out where Id is useful and where string - if isinstance(name, asdl.Id): - name = name.value if name in asdl.builtin_types: return name else: @@ -144,7 +137,7 @@ def visitProduct(self, product, name, depth): class StructVisitor(EmitVisitor): - """Visitor to generate typdefs for AST.""" + """Visitor to generate typedefs for AST.""" def visitModule(self, mod): for dfn in mod.dfns: @@ -188,9 +181,6 @@ def visitConstructor(self, cons, depth): self.visit(f, depth + 1) self.emit("} %s;" % cons.name, depth) self.emit("", depth) - else: - # XXX not sure what I want here, nothing is probably fine - pass def visitField(self, field, depth): # XXX need to lookup field.type, because it might be something @@ -198,7 +188,7 @@ def visitField(self, field, depth): ctype = get_c_type(field.type) name = field.name if field.seq: - if field.type.value in ('cmpop',): + if field.type == 'cmpop': self.emit("asdl_int_seq *%(name)s;" % locals(), depth) else: self.emit("asdl_seq *%(name)s;" % locals(), depth) @@ -253,7 +243,7 @@ def get_args(self, fields): name = f.name # XXX should extend get_c_type() to handle this if f.seq: - if f.type.value in ('cmpop',): + if f.type == 'cmpop': ctype = "asdl_int_seq *" else: ctype = "asdl_seq *" @@ -437,7 +427,7 @@ def complexSum(self, sum, name): self.emit("", 0) for f in t.fields: self.visitField(f, t.name, sum=sum, depth=2) - args = [f.name.value for f in t.fields] + [a.name.value for a in sum.attributes] + args = [f.name for f in t.fields] + [a.name for a in sum.attributes] self.emit("*out = %s(%s);" % (t.name, self.buildArgs(args)), 2) self.emit("if (*out == NULL) goto failed;", 2) self.emit("return 0;", 2) @@ -465,7 +455,7 @@ def visitProduct(self, prod, name): self.emit("", 0) for f in prod.fields: self.visitField(f, name, prod=prod, depth=1) - args = [f.name.value for f in prod.fields] + args = [f.name for f in prod.fields] self.emit("*out = %s(%s);" % (name, self.buildArgs(args)), 1) self.emit("return 0;", 1) self.emit("failed:", 0) @@ -487,8 +477,8 @@ def visitFieldDeclaration(self, field, name, sum=None, prod=None, depth=0): def isSimpleSum(self, field): # XXX can the members of this list be determined automatically? - return field.type.value in ('expr_context', 'boolop', 'operator', - 'unaryop', 'cmpop') + return field.type in ('expr_context', 'boolop', 'operator', + 'unaryop', 'cmpop') def isNumeric(self, field): return get_c_type(field.type) in ("int", "bool") @@ -960,7 +950,7 @@ def visitModule(self, mod): def visitProduct(self, prod, name): if prod.fields: - fields = name.value+"_fields" + fields = name+"_fields" else: fields = "NULL" self.emit('%s_type = make_type("%s", &AST_type, %s, %d);' % @@ -987,7 +977,7 @@ def visitSum(self, sum, name): def visitConstructor(self, cons, name, simple): if cons.fields: - fields = cons.name.value+"_fields" + fields = cons.name+"_fields" else: fields = "NULL" self.emit('%s_type = make_type("%s", %s_type, %s, %d);' % @@ -1170,7 +1160,7 @@ def emitSeq(self, field, value, depth, emit): def set(self, field, value, depth): if field.seq: # XXX should really check for is_simple, but that requires a symbol table - if field.type.value == "cmpop": + if field.type == "cmpop": # While the sequence elements are stored as void*, # ast2obj_cmpop expects an enum self.emit("{", depth) @@ -1203,10 +1193,14 @@ class PartingShots(StaticVisitor): mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode) { mod_ty res; - PyObject *req_type[] = {(PyObject*)Module_type, (PyObject*)Expression_type, - (PyObject*)Interactive_type}; + PyObject *req_type[3]; char *req_name[] = {"Module", "Expression", "Interactive"}; int isinstance; + + req_type[0] = (PyObject*)Module_type; + req_type[1] = (PyObject*)Expression_type; + req_type[2] = (PyObject*)Interactive_type; + assert(0 <= mode && mode <= 2); if (!init_types()) @@ -1245,12 +1239,15 @@ def visit(self, object): common_msg = "/* File automatically generated by %s. */\n\n" -def main(srcfile): +def main(srcfile, dump_module=False): argv0 = sys.argv[0] components = argv0.split(os.sep) argv0 = os.sep.join(components[-2:]) auto_gen_msg = common_msg % argv0 mod = asdl.parse(srcfile) + if dump_module: + print('Parsed Module:') + print(mod) if not asdl.check(mod): sys.exit(1) if INC_DIR: @@ -1297,16 +1294,19 @@ def main(srcfile): INC_DIR = '' SRC_DIR = '' - opts, args = getopt.getopt(sys.argv[1:], "h:c:") - if len(opts) != 1: - sys.stdout.write("Must specify exactly one output file\n") - sys.exit(1) + dump_module = False + opts, args = getopt.getopt(sys.argv[1:], "dh:c:") for o, v in opts: if o == '-h': INC_DIR = v if o == '-c': SRC_DIR = v - if len(args) != 1: - sys.stdout.write("Must specify single input file\n") + if o == '-d': + dump_module = True + if INC_DIR and SRC_DIR: + print('Must specify exactly one output file') + sys.exit(1) + elif len(args) != 1: + print('Must specify single input file') sys.exit(1) - main(args[0]) + main(args[0], dump_module) diff --git a/Parser/myreadline.c b/Parser/myreadline.c index a1c4b5c896ae..28c7b6d7fff8 100644 --- a/Parser/myreadline.c +++ b/Parser/myreadline.c @@ -15,10 +15,6 @@ #include "windows.h" #endif /* MS_WINDOWS */ -#ifdef __VMS -extern char* vms__StdioReadline(FILE *sys_stdin, FILE *sys_stdout, char *prompt); -#endif - PyThreadState* _PyOS_ReadlineTState; @@ -189,11 +185,7 @@ PyOS_Readline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt) if (PyOS_ReadlineFunctionPointer == NULL) { -#ifdef __VMS - PyOS_ReadlineFunctionPointer = vms__StdioReadline; -#else PyOS_ReadlineFunctionPointer = PyOS_StdioReadline; -#endif } #ifdef WITH_THREAD diff --git a/Parser/node.c b/Parser/node.c index b26ce61c015a..00103240afd5 100644 --- a/Parser/node.c +++ b/Parser/node.c @@ -70,8 +70,8 @@ fancy_roundup(int n) * Note that this would be straightforward if a node stored its current * capacity. The code is tricky to avoid that. */ -#define XXXROUNDUP(n) ((n) <= 1 ? (n) : \ - (n) <= 128 ? _Py_SIZE_ROUND_UP((n), 4) : \ +#define XXXROUNDUP(n) ((n) <= 1 ? (n) : \ + (n) <= 128 ? (int)_Py_SIZE_ROUND_UP((n), 4) : \ fancy_roundup(n)) @@ -91,7 +91,7 @@ PyNode_AddChild(node *n1, int type, char *str, int lineno, int col_offset) if (current_capacity < 0 || required_capacity < 0) return E_OVERFLOW; if (current_capacity < required_capacity) { - if (required_capacity > PY_SIZE_MAX / sizeof(node)) { + if ((size_t)required_capacity > PY_SIZE_MAX / sizeof(node)) { return E_NOMEM; } n = n1->n_child; diff --git a/Parser/pgenmain.c b/Parser/pgenmain.c index 017a4f927430..0f055d630874 100644 --- a/Parser/pgenmain.c +++ b/Parser/pgenmain.c @@ -96,10 +96,11 @@ getgrammar(char *filename) fprintf(stderr, "Parsing error %d, line %d.\n", err.error, err.lineno); if (err.text != NULL) { - size_t i; + size_t len; + int i; fprintf(stderr, "%s", err.text); - i = strlen(err.text); - if (i == 0 || err.text[i-1] != '\n') + len = strlen(err.text); + if (len == 0 || err.text[len-1] != '\n') fprintf(stderr, "\n"); for (i = 0; i < err.offset; i++) { if (err.text[i] == '\t') diff --git a/Parser/printgrammar.c b/Parser/printgrammar.c index dd7e6ae2ef20..7311e55170de 100644 --- a/Parser/printgrammar.c +++ b/Parser/printgrammar.c @@ -84,7 +84,7 @@ static void printdfas(grammar *g, FILE *fp) { dfa *d; - int i, j; + int i, j, n; printstates(g, fp); fprintf(fp, "static dfa dfas[%d] = {\n", g->g_ndfas); @@ -93,7 +93,8 @@ printdfas(grammar *g, FILE *fp) fprintf(fp, " {%d, \"%s\", %d, %d, states_%d,\n", d->d_type, d->d_name, d->d_initial, d->d_nstates, i); fprintf(fp, " \""); - for (j = 0; j < NBYTES(g->g_ll.ll_nlabels); j++) + n = NBYTES(g->g_ll.ll_nlabels); + for (j = 0; j < n; j++) fprintf(fp, "\\%03o", d->d_first[j] & 0xff); fprintf(fp, "\"},\n"); } diff --git a/Parser/spark.py b/Parser/spark.py deleted file mode 100644 index 88c1a89a2793..000000000000 --- a/Parser/spark.py +++ /dev/null @@ -1,849 +0,0 @@ -# Copyright (c) 1998-2002 John Aycock -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -__version__ = 'SPARK-0.7 (pre-alpha-5)' - -import re - -# Compatibility with older pythons. -def output(string='', end='\n'): - sys.stdout.write(string + end) - -try: - sorted -except NameError: - def sorted(seq): - seq2 = seq[:] - seq2.sort() - return seq2 - -def _namelist(instance): - namelist, namedict, classlist = [], {}, [instance.__class__] - for c in classlist: - for b in c.__bases__: - classlist.append(b) - for name in c.__dict__.keys(): - if name not in namedict: - namelist.append(name) - namedict[name] = 1 - return namelist - -class GenericScanner: - def __init__(self, flags=0): - pattern = self.reflect() - self.re = re.compile(pattern, re.VERBOSE|flags) - - self.index2func = {} - for name, number in self.re.groupindex.items(): - self.index2func[number-1] = getattr(self, 't_' + name) - - def makeRE(self, name): - doc = getattr(self, name).__doc__ - rv = '(?P<%s>%s)' % (name[2:], doc) - return rv - - def reflect(self): - rv = [] - for name in _namelist(self): - if name[:2] == 't_' and name != 't_default': - rv.append(self.makeRE(name)) - - rv.append(self.makeRE('t_default')) - return '|'.join(rv) - - def error(self, s, pos): - output("Lexical error at position %s" % pos) - raise SystemExit - - def tokenize(self, s): - pos = 0 - n = len(s) - while pos < n: - m = self.re.match(s, pos) - if m is None: - self.error(s, pos) - - groups = m.groups() - for i in range(len(groups)): - if groups[i] and i in self.index2func: - self.index2func[i](groups[i]) - pos = m.end() - - def t_default(self, s): - r'( . | \n )+' - output("Specification error: unmatched input") - raise SystemExit - -# -# Extracted from GenericParser and made global so that [un]picking works. -# -class _State: - def __init__(self, stateno, items): - self.T, self.complete, self.items = [], [], items - self.stateno = stateno - -class GenericParser: - # - # An Earley parser, as per J. Earley, "An Efficient Context-Free - # Parsing Algorithm", CACM 13(2), pp. 94-102. Also J. C. Earley, - # "An Efficient Context-Free Parsing Algorithm", Ph.D. thesis, - # Carnegie-Mellon University, August 1968. New formulation of - # the parser according to J. Aycock, "Practical Earley Parsing - # and the SPARK Toolkit", Ph.D. thesis, University of Victoria, - # 2001, and J. Aycock and R. N. Horspool, "Practical Earley - # Parsing", unpublished paper, 2001. - # - - def __init__(self, start): - self.rules = {} - self.rule2func = {} - self.rule2name = {} - self.collectRules() - self.augment(start) - self.ruleschanged = 1 - - _NULLABLE = '\e_' - _START = 'START' - _BOF = '|-' - - # - # When pickling, take the time to generate the full state machine; - # some information is then extraneous, too. Unfortunately we - # can't save the rule2func map. - # - def __getstate__(self): - if self.ruleschanged: - # - # XXX - duplicated from parse() - # - self.computeNull() - self.newrules = {} - self.new2old = {} - self.makeNewRules() - self.ruleschanged = 0 - self.edges, self.cores = {}, {} - self.states = { 0: self.makeState0() } - self.makeState(0, self._BOF) - # - # XXX - should find a better way to do this.. - # - changes = 1 - while changes: - changes = 0 - for k, v in self.edges.items(): - if v is None: - state, sym = k - if state in self.states: - self.goto(state, sym) - changes = 1 - rv = self.__dict__.copy() - for s in self.states.values(): - del s.items - del rv['rule2func'] - del rv['nullable'] - del rv['cores'] - return rv - - def __setstate__(self, D): - self.rules = {} - self.rule2func = {} - self.rule2name = {} - self.collectRules() - start = D['rules'][self._START][0][1][1] # Blech. - self.augment(start) - D['rule2func'] = self.rule2func - D['makeSet'] = self.makeSet_fast - self.__dict__ = D - - # - # A hook for GenericASTBuilder and GenericASTMatcher. Mess - # thee not with this; nor shall thee toucheth the _preprocess - # argument to addRule. - # - def preprocess(self, rule, func): return rule, func - - def addRule(self, doc, func, _preprocess=1): - fn = func - rules = doc.split() - - index = [] - for i in range(len(rules)): - if rules[i] == '::=': - index.append(i-1) - index.append(len(rules)) - - for i in range(len(index)-1): - lhs = rules[index[i]] - rhs = rules[index[i]+2:index[i+1]] - rule = (lhs, tuple(rhs)) - - if _preprocess: - rule, fn = self.preprocess(rule, func) - - if lhs in self.rules: - self.rules[lhs].append(rule) - else: - self.rules[lhs] = [ rule ] - self.rule2func[rule] = fn - self.rule2name[rule] = func.__name__[2:] - self.ruleschanged = 1 - - def collectRules(self): - for name in _namelist(self): - if name[:2] == 'p_': - func = getattr(self, name) - doc = func.__doc__ - self.addRule(doc, func) - - def augment(self, start): - rule = '%s ::= %s %s' % (self._START, self._BOF, start) - self.addRule(rule, lambda args: args[1], 0) - - def computeNull(self): - self.nullable = {} - tbd = [] - - for rulelist in self.rules.values(): - lhs = rulelist[0][0] - self.nullable[lhs] = 0 - for rule in rulelist: - rhs = rule[1] - if len(rhs) == 0: - self.nullable[lhs] = 1 - continue - # - # We only need to consider rules which - # consist entirely of nonterminal symbols. - # This should be a savings on typical - # grammars. - # - for sym in rhs: - if sym not in self.rules: - break - else: - tbd.append(rule) - changes = 1 - while changes: - changes = 0 - for lhs, rhs in tbd: - if self.nullable[lhs]: - continue - for sym in rhs: - if not self.nullable[sym]: - break - else: - self.nullable[lhs] = 1 - changes = 1 - - def makeState0(self): - s0 = _State(0, []) - for rule in self.newrules[self._START]: - s0.items.append((rule, 0)) - return s0 - - def finalState(self, tokens): - # - # Yuck. - # - if len(self.newrules[self._START]) == 2 and len(tokens) == 0: - return 1 - start = self.rules[self._START][0][1][1] - return self.goto(1, start) - - def makeNewRules(self): - worklist = [] - for rulelist in self.rules.values(): - for rule in rulelist: - worklist.append((rule, 0, 1, rule)) - - for rule, i, candidate, oldrule in worklist: - lhs, rhs = rule - n = len(rhs) - while i < n: - sym = rhs[i] - if sym not in self.rules or \ - not self.nullable[sym]: - candidate = 0 - i = i + 1 - continue - - newrhs = list(rhs) - newrhs[i] = self._NULLABLE+sym - newrule = (lhs, tuple(newrhs)) - worklist.append((newrule, i+1, - candidate, oldrule)) - candidate = 0 - i = i + 1 - else: - if candidate: - lhs = self._NULLABLE+lhs - rule = (lhs, rhs) - if lhs in self.newrules: - self.newrules[lhs].append(rule) - else: - self.newrules[lhs] = [ rule ] - self.new2old[rule] = oldrule - - def typestring(self, token): - return None - - def error(self, token): - output("Syntax error at or near `%s' token" % token) - raise SystemExit - - def parse(self, tokens): - sets = [ [(1,0), (2,0)] ] - self.links = {} - - if self.ruleschanged: - self.computeNull() - self.newrules = {} - self.new2old = {} - self.makeNewRules() - self.ruleschanged = 0 - self.edges, self.cores = {}, {} - self.states = { 0: self.makeState0() } - self.makeState(0, self._BOF) - - for i in range(len(tokens)): - sets.append([]) - - if sets[i] == []: - break - self.makeSet(tokens[i], sets, i) - else: - sets.append([]) - self.makeSet(None, sets, len(tokens)) - - #_dump(tokens, sets, self.states) - - finalitem = (self.finalState(tokens), 0) - if finalitem not in sets[-2]: - if len(tokens) > 0: - self.error(tokens[i-1]) - else: - self.error(None) - - return self.buildTree(self._START, finalitem, - tokens, len(sets)-2) - - def isnullable(self, sym): - # - # For symbols in G_e only. If we weren't supporting 1.5, - # could just use sym.startswith(). - # - return self._NULLABLE == sym[0:len(self._NULLABLE)] - - def skip(self, hs, pos=0): - n = len(hs[1]) - while pos < n: - if not self.isnullable(hs[1][pos]): - break - pos = pos + 1 - return pos - - def makeState(self, state, sym): - assert sym is not None - # - # Compute \epsilon-kernel state's core and see if - # it exists already. - # - kitems = [] - for rule, pos in self.states[state].items: - lhs, rhs = rule - if rhs[pos:pos+1] == (sym,): - kitems.append((rule, self.skip(rule, pos+1))) - core = kitems - - core.sort() - tcore = tuple(core) - if tcore in self.cores: - return self.cores[tcore] - # - # Nope, doesn't exist. Compute it and the associated - # \epsilon-nonkernel state together; we'll need it right away. - # - k = self.cores[tcore] = len(self.states) - K, NK = _State(k, kitems), _State(k+1, []) - self.states[k] = K - predicted = {} - - edges = self.edges - rules = self.newrules - for X in K, NK: - worklist = X.items - for item in worklist: - rule, pos = item - lhs, rhs = rule - if pos == len(rhs): - X.complete.append(rule) - continue - - nextSym = rhs[pos] - key = (X.stateno, nextSym) - if nextSym not in rules: - if key not in edges: - edges[key] = None - X.T.append(nextSym) - else: - edges[key] = None - if nextSym not in predicted: - predicted[nextSym] = 1 - for prule in rules[nextSym]: - ppos = self.skip(prule) - new = (prule, ppos) - NK.items.append(new) - # - # Problem: we know K needs generating, but we - # don't yet know about NK. Can't commit anything - # regarding NK to self.edges until we're sure. Should - # we delay committing on both K and NK to avoid this - # hacky code? This creates other problems.. - # - if X is K: - edges = {} - - if NK.items == []: - return k - - # - # Check for \epsilon-nonkernel's core. Unfortunately we - # need to know the entire set of predicted nonterminals - # to do this without accidentally duplicating states. - # - core = sorted(predicted.keys()) - tcore = tuple(core) - if tcore in self.cores: - self.edges[(k, None)] = self.cores[tcore] - return k - - nk = self.cores[tcore] = self.edges[(k, None)] = NK.stateno - self.edges.update(edges) - self.states[nk] = NK - return k - - def goto(self, state, sym): - key = (state, sym) - if key not in self.edges: - # - # No transitions from state on sym. - # - return None - - rv = self.edges[key] - if rv is None: - # - # Target state isn't generated yet. Remedy this. - # - rv = self.makeState(state, sym) - self.edges[key] = rv - return rv - - def gotoT(self, state, t): - return [self.goto(state, t)] - - def gotoST(self, state, st): - rv = [] - for t in self.states[state].T: - if st == t: - rv.append(self.goto(state, t)) - return rv - - def add(self, set, item, i=None, predecessor=None, causal=None): - if predecessor is None: - if item not in set: - set.append(item) - else: - key = (item, i) - if item not in set: - self.links[key] = [] - set.append(item) - self.links[key].append((predecessor, causal)) - - def makeSet(self, token, sets, i): - cur, next = sets[i], sets[i+1] - - ttype = token is not None and self.typestring(token) or None - if ttype is not None: - fn, arg = self.gotoT, ttype - else: - fn, arg = self.gotoST, token - - for item in cur: - ptr = (item, i) - state, parent = item - add = fn(state, arg) - for k in add: - if k is not None: - self.add(next, (k, parent), i+1, ptr) - nk = self.goto(k, None) - if nk is not None: - self.add(next, (nk, i+1)) - - if parent == i: - continue - - for rule in self.states[state].complete: - lhs, rhs = rule - for pitem in sets[parent]: - pstate, pparent = pitem - k = self.goto(pstate, lhs) - if k is not None: - why = (item, i, rule) - pptr = (pitem, parent) - self.add(cur, (k, pparent), - i, pptr, why) - nk = self.goto(k, None) - if nk is not None: - self.add(cur, (nk, i)) - - def makeSet_fast(self, token, sets, i): - # - # Call *only* when the entire state machine has been built! - # It relies on self.edges being filled in completely, and - # then duplicates and inlines code to boost speed at the - # cost of extreme ugliness. - # - cur, next = sets[i], sets[i+1] - ttype = token is not None and self.typestring(token) or None - - for item in cur: - ptr = (item, i) - state, parent = item - if ttype is not None: - k = self.edges.get((state, ttype), None) - if k is not None: - #self.add(next, (k, parent), i+1, ptr) - #INLINED --v - new = (k, parent) - key = (new, i+1) - if new not in next: - self.links[key] = [] - next.append(new) - self.links[key].append((ptr, None)) - #INLINED --^ - #nk = self.goto(k, None) - nk = self.edges.get((k, None), None) - if nk is not None: - #self.add(next, (nk, i+1)) - #INLINED --v - new = (nk, i+1) - if new not in next: - next.append(new) - #INLINED --^ - else: - add = self.gotoST(state, token) - for k in add: - if k is not None: - self.add(next, (k, parent), i+1, ptr) - #nk = self.goto(k, None) - nk = self.edges.get((k, None), None) - if nk is not None: - self.add(next, (nk, i+1)) - - if parent == i: - continue - - for rule in self.states[state].complete: - lhs, rhs = rule - for pitem in sets[parent]: - pstate, pparent = pitem - #k = self.goto(pstate, lhs) - k = self.edges.get((pstate, lhs), None) - if k is not None: - why = (item, i, rule) - pptr = (pitem, parent) - #self.add(cur, (k, pparent), - # i, pptr, why) - #INLINED --v - new = (k, pparent) - key = (new, i) - if new not in cur: - self.links[key] = [] - cur.append(new) - self.links[key].append((pptr, why)) - #INLINED --^ - #nk = self.goto(k, None) - nk = self.edges.get((k, None), None) - if nk is not None: - #self.add(cur, (nk, i)) - #INLINED --v - new = (nk, i) - if new not in cur: - cur.append(new) - #INLINED --^ - - def predecessor(self, key, causal): - for p, c in self.links[key]: - if c == causal: - return p - assert 0 - - def causal(self, key): - links = self.links[key] - if len(links) == 1: - return links[0][1] - choices = [] - rule2cause = {} - for p, c in links: - rule = c[2] - choices.append(rule) - rule2cause[rule] = c - return rule2cause[self.ambiguity(choices)] - - def deriveEpsilon(self, nt): - if len(self.newrules[nt]) > 1: - rule = self.ambiguity(self.newrules[nt]) - else: - rule = self.newrules[nt][0] - #output(rule) - - rhs = rule[1] - attr = [None] * len(rhs) - - for i in range(len(rhs)-1, -1, -1): - attr[i] = self.deriveEpsilon(rhs[i]) - return self.rule2func[self.new2old[rule]](attr) - - def buildTree(self, nt, item, tokens, k): - state, parent = item - - choices = [] - for rule in self.states[state].complete: - if rule[0] == nt: - choices.append(rule) - rule = choices[0] - if len(choices) > 1: - rule = self.ambiguity(choices) - #output(rule) - - rhs = rule[1] - attr = [None] * len(rhs) - - for i in range(len(rhs)-1, -1, -1): - sym = rhs[i] - if sym not in self.newrules: - if sym != self._BOF: - attr[i] = tokens[k-1] - key = (item, k) - item, k = self.predecessor(key, None) - #elif self.isnullable(sym): - elif self._NULLABLE == sym[0:len(self._NULLABLE)]: - attr[i] = self.deriveEpsilon(sym) - else: - key = (item, k) - why = self.causal(key) - attr[i] = self.buildTree(sym, why[0], - tokens, why[1]) - item, k = self.predecessor(key, why) - return self.rule2func[self.new2old[rule]](attr) - - def ambiguity(self, rules): - # - # XXX - problem here and in collectRules() if the same rule - # appears in >1 method. Also undefined results if rules - # causing the ambiguity appear in the same method. - # - sortlist = [] - name2index = {} - for i in range(len(rules)): - lhs, rhs = rule = rules[i] - name = self.rule2name[self.new2old[rule]] - sortlist.append((len(rhs), name)) - name2index[name] = i - sortlist.sort() - list = [b for a, b in sortlist] - return rules[name2index[self.resolve(list)]] - - def resolve(self, list): - # - # Resolve ambiguity in favor of the shortest RHS. - # Since we walk the tree from the top down, this - # should effectively resolve in favor of a "shift". - # - return list[0] - -# -# GenericASTBuilder automagically constructs a concrete/abstract syntax tree -# for a given input. The extra argument is a class (not an instance!) -# which supports the "__setslice__" and "__len__" methods. -# -# XXX - silently overrides any user code in methods. -# - -class GenericASTBuilder(GenericParser): - def __init__(self, AST, start): - GenericParser.__init__(self, start) - self.AST = AST - - def preprocess(self, rule, func): - rebind = lambda lhs, self=self: \ - lambda args, lhs=lhs, self=self: \ - self.buildASTNode(args, lhs) - lhs, rhs = rule - return rule, rebind(lhs) - - def buildASTNode(self, args, lhs): - children = [] - for arg in args: - if isinstance(arg, self.AST): - children.append(arg) - else: - children.append(self.terminal(arg)) - return self.nonterminal(lhs, children) - - def terminal(self, token): return token - - def nonterminal(self, type, args): - rv = self.AST(type) - rv[:len(args)] = args - return rv - -# -# GenericASTTraversal is a Visitor pattern according to Design Patterns. For -# each node it attempts to invoke the method n_, falling -# back onto the default() method if the n_* can't be found. The preorder -# traversal also looks for an exit hook named n__exit (no default -# routine is called if it's not found). To prematurely halt traversal -# of a subtree, call the prune() method -- this only makes sense for a -# preorder traversal. Node type is determined via the typestring() method. -# - -class GenericASTTraversalPruningException: - pass - -class GenericASTTraversal: - def __init__(self, ast): - self.ast = ast - - def typestring(self, node): - return node.type - - def prune(self): - raise GenericASTTraversalPruningException - - def preorder(self, node=None): - if node is None: - node = self.ast - - try: - name = 'n_' + self.typestring(node) - if hasattr(self, name): - func = getattr(self, name) - func(node) - else: - self.default(node) - except GenericASTTraversalPruningException: - return - - for kid in node: - self.preorder(kid) - - name = name + '_exit' - if hasattr(self, name): - func = getattr(self, name) - func(node) - - def postorder(self, node=None): - if node is None: - node = self.ast - - for kid in node: - self.postorder(kid) - - name = 'n_' + self.typestring(node) - if hasattr(self, name): - func = getattr(self, name) - func(node) - else: - self.default(node) - - - def default(self, node): - pass - -# -# GenericASTMatcher. AST nodes must have "__getitem__" and "__cmp__" -# implemented. -# -# XXX - makes assumptions about how GenericParser walks the parse tree. -# - -class GenericASTMatcher(GenericParser): - def __init__(self, start, ast): - GenericParser.__init__(self, start) - self.ast = ast - - def preprocess(self, rule, func): - rebind = lambda func, self=self: \ - lambda args, func=func, self=self: \ - self.foundMatch(args, func) - lhs, rhs = rule - rhslist = list(rhs) - rhslist.reverse() - - return (lhs, tuple(rhslist)), rebind(func) - - def foundMatch(self, args, func): - func(args[-1]) - return args[-1] - - def match_r(self, node): - self.input.insert(0, node) - children = 0 - - for child in node: - if children == 0: - self.input.insert(0, '(') - children = children + 1 - self.match_r(child) - - if children > 0: - self.input.insert(0, ')') - - def match(self, ast=None): - if ast is None: - ast = self.ast - self.input = [] - - self.match_r(ast) - self.parse(self.input) - - def resolve(self, list): - # - # Resolve ambiguity in favor of the longest RHS. - # - return list[-1] - -def _dump(tokens, sets, states): - for i in range(len(sets)): - output('set %d' % i) - for item in sets[i]: - output('\t', item) - for (lhs, rhs), pos in states[item[0]].items: - output('\t\t', lhs, '::=', end='') - output(' '.join(rhs[:pos]), end='') - output('.', end='') - output(' '.join(rhs[pos:])) - if i < len(tokens): - output() - output('token %s' % str(tokens[i])) - output() diff --git a/Parser/tokenizer.c b/Parser/tokenizer.c index 5bf7e84f2616..ef7b19fb42f6 100644 --- a/Parser/tokenizer.c +++ b/Parser/tokenizer.c @@ -98,6 +98,7 @@ const char *_PyParser_TokenNames[] = { "DOUBLESLASH", "DOUBLESLASHEQUAL", "AT", + "ATEQUAL", "RARROW", "ELLIPSIS", /* This table must match the #defines in token.h! */ @@ -283,13 +284,27 @@ check_coding_spec(const char* line, Py_ssize_t size, struct tok_state *tok, char *cs; int r = 1; - if (tok->cont_line) + if (tok->cont_line) { /* It's a continuation line, so it can't be a coding spec. */ + tok->read_coding_spec = 1; return 1; + } if (!get_coding_spec(line, &cs, size, tok)) return 0; - if (!cs) + if (!cs) { + Py_ssize_t i; + for (i = 0; i < size; i++) { + if (line[i] == '#' || line[i] == '\n' || line[i] == '\r') + break; + if (line[i] != ' ' && line[i] != '\t' && line[i] != '\014') { + /* Stop checking coding spec after a line containing + * anything except a comment. */ + tok->read_coding_spec = 1; + break; + } + } return 1; + } tok->read_coding_spec = 1; if (tok->encoding == NULL) { assert(tok->decoding_state == STATE_RAW); @@ -476,13 +491,21 @@ fp_setreadl(struct tok_state *tok, const char* enc) _Py_IDENTIFIER(open); _Py_IDENTIFIER(readline); int fd; + long pos; io = PyImport_ImportModuleNoBlock("io"); if (io == NULL) goto cleanup; fd = fileno(tok->fp); - if (lseek(fd, 0, SEEK_SET) == (off_t)-1) { + /* Due to buffering the file offset for fd can be different from the file + * position of tok->fp. If tok->fp was opened in text mode on Windows, + * its file position counts CRLF as one char and can't be directly mapped + * to the file offset for fd. Instead we step back one byte and read to + * the end of line.*/ + pos = ftell(tok->fp); + if (pos == -1 || + lseek(fd, (off_t)(pos > 0 ? pos - 1 : pos), SEEK_SET) == (off_t)-1) { PyErr_SetFromErrnoWithFilename(PyExc_OSError, NULL); goto cleanup; } @@ -495,14 +518,12 @@ fp_setreadl(struct tok_state *tok, const char* enc) Py_XDECREF(tok->decoding_readline); readline = _PyObject_GetAttrId(stream, &PyId_readline); tok->decoding_readline = readline; - - /* The file has been reopened; parsing will restart from - * the beginning of the file, we have to reset the line number. - * But this function has been called from inside tok_nextc() which - * will increment lineno before it returns. So we set it -1 so that - * the next call to tok_nextc() will start with tok->lineno == 0. - */ - tok->lineno = -1; + if (pos > 0) { + if (PyObject_CallObject(readline, NULL) == NULL) { + readline = NULL; + goto cleanup; + } + } cleanup: Py_XDECREF(stream); @@ -752,7 +773,7 @@ decode_str(const char *input, int single, struct tok_state *tok) if (newl[0]) { if (!check_coding_spec(str, newl[0] - str, tok, buf_setreadl)) return error_ret(tok); - if (tok->enc == NULL && newl[1]) { + if (tok->enc == NULL && !tok->read_coding_spec && newl[1]) { if (!check_coding_spec(newl[0]+1, newl[1] - newl[0], tok, buf_setreadl)) return error_ret(tok); @@ -1111,7 +1132,7 @@ PyToken_OneChar(int c) case '}': return RBRACE; case '^': return CIRCUMFLEX; case '~': return TILDE; - case '@': return AT; + case '@': return AT; default: return OP; } } @@ -1187,6 +1208,11 @@ PyToken_TwoChars(int c1, int c2) case '=': return CIRCUMFLEXEQUAL; } break; + case '@': + switch (c2) { + case '=': return ATEQUAL; + } + break; } return OP; } @@ -1577,15 +1603,24 @@ tok_get(struct tok_state *tok, char **p_start, char **p_end) } while (isdigit(c)); } if (c == 'e' || c == 'E') { - exponent: + int e; + exponent: + e = c; /* Exponent part */ c = tok_nextc(tok); - if (c == '+' || c == '-') + if (c == '+' || c == '-') { c = tok_nextc(tok); - if (!isdigit(c)) { - tok->done = E_TOKEN; + if (!isdigit(c)) { + tok->done = E_TOKEN; + tok_backup(tok, c); + return ERRORTOKEN; + } + } else if (!isdigit(c)) { tok_backup(tok, c); - return ERRORTOKEN; + tok_backup(tok, e); + *p_start = tok->start; + *p_end = tok->cur; + return NUMBER; } do { c = tok_nextc(tok); diff --git a/Programs/README b/Programs/README new file mode 100644 index 000000000000..c24578bc08d2 --- /dev/null +++ b/Programs/README @@ -0,0 +1 @@ +Source files for binary executables (as opposed to shared modules) diff --git a/Modules/_freeze_importlib.c b/Programs/_freeze_importlib.c similarity index 96% rename from Modules/_freeze_importlib.c rename to Programs/_freeze_importlib.c index 57b1ac06624b..d0c33e233673 100644 --- a/Modules/_freeze_importlib.c +++ b/Programs/_freeze_importlib.c @@ -28,14 +28,14 @@ const static struct _frozen _PyImport_FrozenModules[] = { const struct _frozen *PyImport_FrozenModules; #endif -const char header[] = "/* Auto-generated by Modules/_freeze_importlib.c */"; +const char header[] = "/* Auto-generated by Programs/_freeze_importlib.c */"; int main(int argc, char *argv[]) { char *inpath, *outpath; FILE *infile = NULL, *outfile = NULL; - struct stat st; + struct _Py_stat_struct st; size_t text_size, data_size, n; char *text = NULL; unsigned char *data; @@ -54,7 +54,7 @@ main(int argc, char *argv[]) fprintf(stderr, "cannot open '%s' for reading\n", inpath); goto error; } - if (fstat(fileno(infile), &st)) { + if (_Py_fstat(fileno(infile), &st)) { fprintf(stderr, "cannot fstat '%s'\n", inpath); goto error; } diff --git a/Modules/_testembed.c b/Programs/_testembed.c similarity index 97% rename from Modules/_testembed.c rename to Programs/_testembed.c index a21d2518be34..39ff0977c8fd 100644 --- a/Modules/_testembed.c +++ b/Programs/_testembed.c @@ -109,11 +109,11 @@ static void test_forced_io_encoding(void) printf("--- Use defaults ---\n"); check_stdio_details(NULL, NULL); printf("--- Set errors only ---\n"); - check_stdio_details(NULL, "surrogateescape"); + check_stdio_details(NULL, "ignore"); printf("--- Set encoding only ---\n"); check_stdio_details("latin-1", NULL); printf("--- Set encoding and errors ---\n"); - check_stdio_details("latin-1", "surrogateescape"); + check_stdio_details("latin-1", "replace"); /* Check calling after initialization fails */ Py_Initialize(); diff --git a/Modules/python.c b/Programs/python.c similarity index 97% rename from Modules/python.c rename to Programs/python.c index 9811c01d4918..2e5e4e368f0e 100644 --- a/Modules/python.c +++ b/Programs/python.c @@ -52,7 +52,7 @@ main(int argc, char **argv) setlocale(LC_ALL, ""); for (i = 0; i < argc; i++) { - argv_copy[i] = _Py_char2wchar(argv[i], NULL); + argv_copy[i] = Py_DecodeLocale(argv[i], NULL); if (!argv_copy[i]) { PyMem_RawFree(oldloc); fprintf(stderr, "Fatal Python error: " diff --git a/Python/Python-ast.c b/Python/Python-ast.c index e07a93fee8fb..994e72133759 100644 --- a/Python/Python-ast.c +++ b/Python/Python-ast.c @@ -349,13 +349,14 @@ static PyTypeObject *And_type; static PyTypeObject *Or_type; static PyTypeObject *operator_type; static PyObject *Add_singleton, *Sub_singleton, *Mult_singleton, -*Div_singleton, *Mod_singleton, *Pow_singleton, *LShift_singleton, -*RShift_singleton, *BitOr_singleton, *BitXor_singleton, *BitAnd_singleton, -*FloorDiv_singleton; +*MatMult_singleton, *Div_singleton, *Mod_singleton, *Pow_singleton, +*LShift_singleton, *RShift_singleton, *BitOr_singleton, *BitXor_singleton, +*BitAnd_singleton, *FloorDiv_singleton; static PyObject* ast2obj_operator(operator_ty); static PyTypeObject *Add_type; static PyTypeObject *Sub_type; static PyTypeObject *Mult_type; +static PyTypeObject *MatMult_type; static PyTypeObject *Div_type; static PyTypeObject *Mod_type; static PyTypeObject *Pow_type; @@ -970,6 +971,10 @@ static int init_types(void) if (!Mult_type) return 0; Mult_singleton = PyType_GenericNew(Mult_type, NULL, NULL); if (!Mult_singleton) return 0; + MatMult_type = make_type("MatMult", operator_type, NULL, 0); + if (!MatMult_type) return 0; + MatMult_singleton = PyType_GenericNew(MatMult_type, NULL, NULL); + if (!MatMult_singleton) return 0; Div_type = make_type("Div", operator_type, NULL, 0); if (!Div_type) return 0; Div_singleton = PyType_GenericNew(Div_type, NULL, NULL); @@ -3232,6 +3237,9 @@ PyObject* ast2obj_operator(operator_ty o) case Mult: Py_INCREF(Mult_singleton); return Mult_singleton; + case MatMult: + Py_INCREF(MatMult_singleton); + return MatMult_singleton; case Div: Py_INCREF(Div_singleton); return Div_singleton; @@ -6175,6 +6183,14 @@ obj2ast_operator(PyObject* obj, operator_ty* out, PyArena* arena) *out = Mult; return 0; } + isinstance = PyObject_IsInstance(obj, (PyObject *)MatMult_type); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + *out = MatMult; + return 0; + } isinstance = PyObject_IsInstance(obj, (PyObject *)Div_type); if (isinstance == -1) { return 1; @@ -6956,6 +6972,8 @@ PyInit__ast(void) if (PyDict_SetItemString(d, "Add", (PyObject*)Add_type) < 0) return NULL; if (PyDict_SetItemString(d, "Sub", (PyObject*)Sub_type) < 0) return NULL; if (PyDict_SetItemString(d, "Mult", (PyObject*)Mult_type) < 0) return NULL; + if (PyDict_SetItemString(d, "MatMult", (PyObject*)MatMult_type) < 0) return + NULL; if (PyDict_SetItemString(d, "Div", (PyObject*)Div_type) < 0) return NULL; if (PyDict_SetItemString(d, "Mod", (PyObject*)Mod_type) < 0) return NULL; if (PyDict_SetItemString(d, "Pow", (PyObject*)Pow_type) < 0) return NULL; @@ -7023,10 +7041,14 @@ PyObject* PyAST_mod2obj(mod_ty t) mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode) { mod_ty res; - PyObject *req_type[] = {(PyObject*)Module_type, (PyObject*)Expression_type, - (PyObject*)Interactive_type}; + PyObject *req_type[3]; char *req_name[] = {"Module", "Expression", "Interactive"}; int isinstance; + + req_type[0] = (PyObject*)Module_type; + req_type[1] = (PyObject*)Expression_type; + req_type[2] = (PyObject*)Interactive_type; + assert(0 <= mode && mode <= 2); if (!init_types()) diff --git a/Python/README b/Python/README new file mode 100644 index 000000000000..153b628bd5b4 --- /dev/null +++ b/Python/README @@ -0,0 +1 @@ +Miscellaneous source files for the main Python shared library diff --git a/Python/_warnings.c b/Python/_warnings.c index 6013d7d7d48c..a1f4368ebe92 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -12,6 +12,7 @@ MODULE_NAME " provides basic warning filtering support.\n" static PyObject *_filters; /* List */ static PyObject *_once_registry; /* Dict */ static PyObject *_default_action; /* String */ +static long _filters_version; _Py_IDENTIFIER(argv); _Py_IDENTIFIER(stderr); @@ -178,16 +179,33 @@ get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno, static int already_warned(PyObject *registry, PyObject *key, int should_set) { - PyObject *already_warned; + PyObject *version_obj, *already_warned; + _Py_IDENTIFIER(version); if (key == NULL) return -1; - already_warned = PyDict_GetItem(registry, key); - if (already_warned != NULL) { - int rc = PyObject_IsTrue(already_warned); - if (rc != 0) - return rc; + version_obj = _PyDict_GetItemId(registry, &PyId_version); + if (version_obj == NULL + || !PyLong_CheckExact(version_obj) + || PyLong_AsLong(version_obj) != _filters_version) { + PyDict_Clear(registry); + version_obj = PyLong_FromLong(_filters_version); + if (version_obj == NULL) + return -1; + if (_PyDict_SetItemId(registry, &PyId_version, version_obj) < 0) { + Py_DECREF(version_obj); + return -1; + } + Py_DECREF(version_obj); + } + else { + already_warned = PyDict_GetItem(registry, key); + if (already_warned != NULL) { + int rc = PyObject_IsTrue(already_warned); + if (rc != 0) + return rc; + } } /* This warning wasn't found in the registry, set it. */ @@ -619,16 +637,17 @@ get_category(PyObject *message, PyObject *category) if (rc == 1) category = (PyObject*)message->ob_type; - else if (category == NULL) + else if (category == NULL || category == Py_None) category = PyExc_UserWarning; /* Validate category. */ rc = PyObject_IsSubclass(category, PyExc_Warning); - if (rc == -1) - return NULL; - if (rc == 0) { - PyErr_SetString(PyExc_ValueError, - "category is not a subclass of Warning"); + /* category is not a subclass of PyExc_Warning or + PyObject_IsSubclass raised an error */ + if (rc == -1 || rc == 0) { + PyErr_Format(PyExc_TypeError, + "category must be a Warning subclass, not '%s'", + Py_TYPE(category)->tp_name); return NULL; } @@ -750,6 +769,13 @@ warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds) registry, NULL); } +static PyObject * +warnings_filters_mutated(PyObject *self, PyObject *args) +{ + _filters_version++; + Py_RETURN_NONE; +} + /* Function to issue a warning message; may raise an exception. */ @@ -917,6 +943,8 @@ static PyMethodDef warnings_functions[] = { warn_doc}, {"warn_explicit", (PyCFunction)warnings_warn_explicit, METH_VARARGS | METH_KEYWORDS, warn_explicit_doc}, + {"_filters_mutated", (PyCFunction)warnings_filters_mutated, METH_NOARGS, + NULL}, /* XXX(brett.cannon): add showwarning? */ /* XXX(brett.cannon): Reasonable to add formatwarning? */ {NULL, NULL} /* sentinel */ @@ -1069,5 +1097,7 @@ _PyWarnings_Init(void) Py_INCREF(_default_action); if (PyModule_AddObject(m, "_defaultaction", _default_action) < 0) return NULL; + + _filters_version = 0; return m; } diff --git a/Python/asdl.c b/Python/asdl.c index 74fa9410e493..df387b2119b6 100644 --- a/Python/asdl.c +++ b/Python/asdl.c @@ -5,21 +5,21 @@ asdl_seq * _Py_asdl_seq_new(Py_ssize_t size, PyArena *arena) { asdl_seq *seq = NULL; - size_t n = (size ? (sizeof(void *) * (size - 1)) : 0); + size_t n; /* check size is sane */ - if (size < 0 || size == INT_MIN || - (size && ((size - 1) > (PY_SIZE_MAX / sizeof(void *))))) { + if (size < 0 || + (size && (((size_t)size - 1) > (PY_SIZE_MAX / sizeof(void *))))) { PyErr_NoMemory(); return NULL; } + n = (size ? (sizeof(void *) * (size - 1)) : 0); /* check if size can be added safely */ if (n > PY_SIZE_MAX - sizeof(asdl_seq)) { PyErr_NoMemory(); return NULL; } - n += sizeof(asdl_seq); seq = (asdl_seq *)PyArena_Malloc(arena, n); @@ -36,21 +36,21 @@ asdl_int_seq * _Py_asdl_int_seq_new(Py_ssize_t size, PyArena *arena) { asdl_int_seq *seq = NULL; - size_t n = (size ? (sizeof(void *) * (size - 1)) : 0); + size_t n; /* check size is sane */ - if (size < 0 || size == INT_MIN || - (size && ((size - 1) > (PY_SIZE_MAX / sizeof(void *))))) { + if (size < 0 || + (size && (((size_t)size - 1) > (PY_SIZE_MAX / sizeof(void *))))) { PyErr_NoMemory(); return NULL; } + n = (size ? (sizeof(void *) * (size - 1)) : 0); /* check if size can be added safely */ if (n > PY_SIZE_MAX - sizeof(asdl_seq)) { PyErr_NoMemory(); return NULL; } - n += sizeof(asdl_seq); seq = (asdl_int_seq *)PyArena_Malloc(arena, n); diff --git a/Python/ast.c b/Python/ast.c index 3bd24fdb1410..2f1ae60b6cbd 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -825,6 +825,8 @@ get_operator(const node *n) return Sub; case STAR: return Mult; + case AT: + return MatMult; case SLASH: return Div; case DOUBLESLASH: @@ -1030,6 +1032,8 @@ ast_for_augassign(struct compiling *c, const node *n) return Pow; else return Mult; + case '@': + return MatMult; default: PyErr_Format(PyExc_SystemError, "invalid augassign: %s", STR(n)); return (operator_ty)0; @@ -1123,7 +1127,7 @@ ast_for_arg(struct compiling *c, const node *n) identifier name; expr_ty annotation = NULL; node *ch; - arg_ty tmp; + arg_ty ret; assert(TYPE(n) == tfpdef || TYPE(n) == vfpdef); ch = CHILD(n, 0); @@ -1139,13 +1143,12 @@ ast_for_arg(struct compiling *c, const node *n) return NULL; } - tmp = arg(name, annotation, c->c_arena); - if (!tmp) + ret = arg(name, annotation, c->c_arena); + if (!ret) return NULL; - - tmp->lineno = LINENO(n); - tmp->col_offset = n->n_col_offset; - return tmp; + ret->lineno = LINENO(n); + ret->col_offset = n->n_col_offset; + return ret; } /* returns -1 if failed to handle keyword only arguments @@ -1203,6 +1206,8 @@ handle_keywordonly_args(struct compiling *c, const node *n, int start, arg = arg(argname, annotation, c->c_arena); if (!arg) goto error; + arg->lineno = LINENO(ch); + arg->col_offset = ch->n_col_offset; asdl_seq_SET(kwonlyargs, j++, arg); i += 2; /* the name and the comma */ break; @@ -2101,22 +2106,15 @@ ast_for_trailer(struct compiling *c, const node *n, expr_ty left_expr) if (NCH(n) == 2) return Call(left_expr, NULL, NULL, NULL, NULL, LINENO(n), n->n_col_offset, c->c_arena); - else { - expr_ty tmp = ast_for_call(c, CHILD(n, 1), left_expr); - if (!tmp) - return NULL; - - tmp->lineno = LINENO(n); - tmp->col_offset = n->n_col_offset; - return tmp; - } + else + return ast_for_call(c, CHILD(n, 1), left_expr); } - else if (TYPE(CHILD(n, 0)) == DOT ) { + else if (TYPE(CHILD(n, 0)) == DOT) { PyObject *attr_id = NEW_IDENTIFIER(CHILD(n, 1)); if (!attr_id) return NULL; return Attribute(left_expr, attr_id, Load, - LINENO(CHILD(n, 1)), CHILD(n, 1)->n_col_offset, c->c_arena); + LINENO(n), n->n_col_offset, c->c_arena); } else { REQ(CHILD(n, 0), LSQB); @@ -2217,16 +2215,15 @@ ast_for_power(struct compiling *c, const node *n) tmp = ast_for_trailer(c, ch, e); if (!tmp) return NULL; + tmp->lineno = e->lineno; + tmp->col_offset = e->col_offset; e = tmp; } if (TYPE(CHILD(n, NCH(n) - 1)) == factor) { expr_ty f = ast_for_expr(c, CHILD(n, NCH(n) - 1)); if (!f) return NULL; - tmp = BinOp(e, Pow, f, LINENO(n), n->n_col_offset, c->c_arena); - if (!tmp) - return NULL; - e = tmp; + e = BinOp(e, Pow, f, LINENO(n), n->n_col_offset, c->c_arena); } return e; } @@ -2264,7 +2261,7 @@ ast_for_expr(struct compiling *c, const node *n) and_expr: shift_expr ('&' shift_expr)* shift_expr: arith_expr (('<<'|'>>') arith_expr)* arith_expr: term (('+'|'-') term)* - term: factor (('*'|'/'|'%'|'//') factor)* + term: factor (('*'|'@'|'/'|'%'|'//') factor)* factor: ('+'|'-'|'~') factor | power power: atom trailer* ('**' factor)* */ @@ -2575,7 +2572,7 @@ ast_for_expr_stmt(struct compiling *c, const node *n) /* expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) | ('=' (yield_expr|testlist))*) testlist_star_expr: (test|star_expr) (',' test|star_expr)* [','] - augassign: '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' + augassign: '+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' | '<<=' | '>>=' | '**=' | '//=' test: ... here starts the operator precendence dance */ diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 057ab47e974a..f9bb388b5a25 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -46,6 +46,7 @@ _Py_IDENTIFIER(stdin); _Py_IDENTIFIER(stdout); _Py_IDENTIFIER(stderr); +/* AC: cannot convert yet, waiting for *args support */ static PyObject * builtin___build_class__(PyObject *self, PyObject *args, PyObject *kwds) { @@ -69,7 +70,7 @@ builtin___build_class__(PyObject *self, PyObject *args, PyObject *kwds) func = PyTuple_GET_ITEM(args, 0); /* Better be callable */ if (!PyFunction_Check(func)) { PyErr_SetString(PyExc_TypeError, - "__build__class__: func must be a function"); + "__build_class__: func must be a function"); return NULL; } name = PyTuple_GET_ITEM(args, 1); @@ -229,25 +230,62 @@ absolute or relative imports. 0 is absolute while a positive number\n\ is the number of parent directories to search relative to the current module."); +/*[clinic input] +abs as builtin_abs + + x: 'O' + / + +Return the absolute value of the argument. +[clinic start generated code]*/ + +PyDoc_STRVAR(builtin_abs__doc__, +"abs($module, x, /)\n" +"--\n" +"\n" +"Return the absolute value of the argument."); + +#define BUILTIN_ABS_METHODDEF \ + {"abs", (PyCFunction)builtin_abs, METH_O, builtin_abs__doc__}, + static PyObject * -builtin_abs(PyObject *self, PyObject *v) +builtin_abs(PyModuleDef *module, PyObject *x) +/*[clinic end generated code: output=f85095528ce7e2e5 input=aa29cc07869b4732]*/ { - return PyNumber_Absolute(v); + return PyNumber_Absolute(x); } -PyDoc_STRVAR(abs_doc, -"abs(number) -> number\n\ -\n\ -Return the absolute value of the argument."); +/*[clinic input] +all as builtin_all + + iterable: 'O' + / + +Return True if bool(x) is True for all values x in the iterable. + +If the iterable is empty, return True. +[clinic start generated code]*/ + +PyDoc_STRVAR(builtin_all__doc__, +"all($module, iterable, /)\n" +"--\n" +"\n" +"Return True if bool(x) is True for all values x in the iterable.\n" +"\n" +"If the iterable is empty, return True."); + +#define BUILTIN_ALL_METHODDEF \ + {"all", (PyCFunction)builtin_all, METH_O, builtin_all__doc__}, static PyObject * -builtin_all(PyObject *self, PyObject *v) +builtin_all(PyModuleDef *module, PyObject *iterable) +/*[clinic end generated code: output=d001db739ba83b46 input=dd506dc9998d42bd]*/ { PyObject *it, *item; PyObject *(*iternext)(PyObject *); int cmp; - it = PyObject_GetIter(v); + it = PyObject_GetIter(iterable); if (it == NULL) return NULL; iternext = *Py_TYPE(it)->tp_iternext; @@ -277,20 +315,37 @@ builtin_all(PyObject *self, PyObject *v) Py_RETURN_TRUE; } -PyDoc_STRVAR(all_doc, -"all(iterable) -> bool\n\ -\n\ -Return True if bool(x) is True for all values x in the iterable.\n\ -If the iterable is empty, return True."); +/*[clinic input] +any as builtin_any + + iterable: 'O' + / + +Return True if bool(x) is True for any x in the iterable. + +If the iterable is empty, return False. +[clinic start generated code]*/ + +PyDoc_STRVAR(builtin_any__doc__, +"any($module, iterable, /)\n" +"--\n" +"\n" +"Return True if bool(x) is True for any x in the iterable.\n" +"\n" +"If the iterable is empty, return False."); + +#define BUILTIN_ANY_METHODDEF \ + {"any", (PyCFunction)builtin_any, METH_O, builtin_any__doc__}, static PyObject * -builtin_any(PyObject *self, PyObject *v) +builtin_any(PyModuleDef *module, PyObject *iterable) +/*[clinic end generated code: output=3a4b6dbe6a0d6f61 input=8fe8460f3fbbced8]*/ { PyObject *it, *item; PyObject *(*iternext)(PyObject *); int cmp; - it = PyObject_GetIter(v); + it = PyObject_GetIter(iterable); if (it == NULL) return NULL; iternext = *Py_TYPE(it)->tp_iternext; @@ -320,56 +375,105 @@ builtin_any(PyObject *self, PyObject *v) Py_RETURN_FALSE; } -PyDoc_STRVAR(any_doc, -"any(iterable) -> bool\n\ -\n\ -Return True if bool(x) is True for any x in the iterable.\n\ -If the iterable is empty, return False."); +/*[clinic input] +ascii as builtin_ascii + + obj: 'O' + / + +Return an ASCII-only representation of an object. + +As repr(), return a string containing a printable representation of an +object, but escape the non-ASCII characters in the string returned by +repr() using \\x, \\u or \\U escapes. This generates a string similar +to that returned by repr() in Python 2. +[clinic start generated code]*/ + +PyDoc_STRVAR(builtin_ascii__doc__, +"ascii($module, obj, /)\n" +"--\n" +"\n" +"Return an ASCII-only representation of an object.\n" +"\n" +"As repr(), return a string containing a printable representation of an\n" +"object, but escape the non-ASCII characters in the string returned by\n" +"repr() using \\\\x, \\\\u or \\\\U escapes. This generates a string similar\n" +"to that returned by repr() in Python 2."); + +#define BUILTIN_ASCII_METHODDEF \ + {"ascii", (PyCFunction)builtin_ascii, METH_O, builtin_ascii__doc__}, static PyObject * -builtin_ascii(PyObject *self, PyObject *v) +builtin_ascii(PyModuleDef *module, PyObject *obj) +/*[clinic end generated code: output=f0e6754154c2d30b input=0cbdc1420a306325]*/ { - return PyObject_ASCII(v); + return PyObject_ASCII(obj); } -PyDoc_STRVAR(ascii_doc, -"ascii(object) -> string\n\ -\n\ -As repr(), return a string containing a printable representation of an\n\ -object, but escape the non-ASCII characters in the string returned by\n\ -repr() using \\x, \\u or \\U escapes. This generates a string similar\n\ -to that returned by repr() in Python 2."); +/*[clinic input] +bin as builtin_bin + + number: 'O' + / + +Return the binary representation of an integer. + + >>> bin(2796202) + '0b1010101010101010101010' +[clinic start generated code]*/ + +PyDoc_STRVAR(builtin_bin__doc__, +"bin($module, number, /)\n" +"--\n" +"\n" +"Return the binary representation of an integer.\n" +"\n" +" >>> bin(2796202)\n" +" \'0b1010101010101010101010\'"); + +#define BUILTIN_BIN_METHODDEF \ + {"bin", (PyCFunction)builtin_bin, METH_O, builtin_bin__doc__}, static PyObject * -builtin_bin(PyObject *self, PyObject *v) +builtin_bin(PyModuleDef *module, PyObject *number) +/*[clinic end generated code: output=18fed0e943650da1 input=2a6362ae9a9c9203]*/ { - return PyNumber_ToBase(v, 2); + return PyNumber_ToBase(number, 2); } -PyDoc_STRVAR(bin_doc, -"bin(number) -> string\n\ -\n\ -Return the binary representation of an integer.\n\ -\n\ - >>> bin(2796202)\n\ - '0b1010101010101010101010'\n\ -"); +/*[clinic input] +callable as builtin_callable + + obj: 'O' + / + +Return whether the object is callable (i.e., some kind of function). + +Note that classes are callable, as are instances of classes with a +__call__() method. +[clinic start generated code]*/ + +PyDoc_STRVAR(builtin_callable__doc__, +"callable($module, obj, /)\n" +"--\n" +"\n" +"Return whether the object is callable (i.e., some kind of function).\n" +"\n" +"Note that classes are callable, as are instances of classes with a\n" +"__call__() method."); + +#define BUILTIN_CALLABLE_METHODDEF \ + {"callable", (PyCFunction)builtin_callable, METH_O, builtin_callable__doc__}, static PyObject * -builtin_callable(PyObject *self, PyObject *v) +builtin_callable(PyModuleDef *module, PyObject *obj) +/*[clinic end generated code: output=b3a92cbe635f32af input=bb3bb528fffdade4]*/ { - return PyBool_FromLong((long)PyCallable_Check(v)); + return PyBool_FromLong((long)PyCallable_Check(obj)); } -PyDoc_STRVAR(callable_doc, -"callable(object) -> bool\n\ -\n\ -Return whether the object is callable (i.e., some kind of function).\n\ -Note that classes are callable, as are instances of classes with a\n\ -__call__() method."); - typedef struct { PyObject_HEAD @@ -524,45 +628,105 @@ PyTypeObject PyFilter_Type = { }; +/*[clinic input] +format as builtin_format + + value: 'O' + format_spec: unicode(c_default="NULL") = '' + / + +Return value.__format__(format_spec) + +format_spec defaults to the empty string +[clinic start generated code]*/ + +PyDoc_STRVAR(builtin_format__doc__, +"format($module, value, format_spec=\'\', /)\n" +"--\n" +"\n" +"Return value.__format__(format_spec)\n" +"\n" +"format_spec defaults to the empty string"); + +#define BUILTIN_FORMAT_METHODDEF \ + {"format", (PyCFunction)builtin_format, METH_VARARGS, builtin_format__doc__}, + +static PyObject * +builtin_format_impl(PyModuleDef *module, PyObject *value, PyObject *format_spec); + static PyObject * -builtin_format(PyObject *self, PyObject *args) +builtin_format(PyModuleDef *module, PyObject *args) { + PyObject *return_value = NULL; PyObject *value; PyObject *format_spec = NULL; - if (!PyArg_ParseTuple(args, "O|U:format", &value, &format_spec)) - return NULL; + if (!PyArg_ParseTuple(args, + "O|U:format", + &value, &format_spec)) + goto exit; + return_value = builtin_format_impl(module, value, format_spec); + +exit: + return return_value; +} +static PyObject * +builtin_format_impl(PyModuleDef *module, PyObject *value, PyObject *format_spec) +/*[clinic end generated code: output=39723a58c72e8871 input=e23f2f11e0098c64]*/ +{ return PyObject_Format(value, format_spec); } -PyDoc_STRVAR(format_doc, -"format(value[, format_spec]) -> string\n\ -\n\ -Returns value.__format__(format_spec)\n\ -format_spec defaults to \"\""); +/*[clinic input] +chr as builtin_chr + + i: 'i' + / + +Return a Unicode string of one character with ordinal i; 0 <= i <= 0x10ffff. +[clinic start generated code]*/ + +PyDoc_STRVAR(builtin_chr__doc__, +"chr($module, i, /)\n" +"--\n" +"\n" +"Return a Unicode string of one character with ordinal i; 0 <= i <= 0x10ffff."); + +#define BUILTIN_CHR_METHODDEF \ + {"chr", (PyCFunction)builtin_chr, METH_VARARGS, builtin_chr__doc__}, + +static PyObject * +builtin_chr_impl(PyModuleDef *module, int i); static PyObject * -builtin_chr(PyObject *self, PyObject *args) +builtin_chr(PyModuleDef *module, PyObject *args) { - int x; + PyObject *return_value = NULL; + int i; - if (!PyArg_ParseTuple(args, "i:chr", &x)) - return NULL; + if (!PyArg_ParseTuple(args, + "i:chr", + &i)) + goto exit; + return_value = builtin_chr_impl(module, i); - return PyUnicode_FromOrdinal(x); +exit: + return return_value; } -PyDoc_STRVAR(chr_doc, -"chr(i) -> Unicode character\n\ -\n\ -Return a Unicode string of one character with ordinal i; 0 <= i <= 0x10ffff."); +static PyObject * +builtin_chr_impl(PyModuleDef *module, int i) +/*[clinic end generated code: output=4d6bbe948f56e2ae input=9b1ced29615adf66]*/ +{ + return PyUnicode_FromOrdinal(i); +} -static char * -source_as_string(PyObject *cmd, char *funcname, char *what, PyCompilerFlags *cf) +static const char * +source_as_string(PyObject *cmd, const char *funcname, const char *what, PyCompilerFlags *cf, Py_buffer *view) { - char *str; + const char *str; Py_ssize_t size; if (PyUnicode_Check(cmd)) { @@ -571,52 +735,111 @@ source_as_string(PyObject *cmd, char *funcname, char *what, PyCompilerFlags *cf) if (str == NULL) return NULL; } - else if (!PyObject_CheckReadBuffer(cmd)) { + else if (PyObject_GetBuffer(cmd, view, PyBUF_SIMPLE) == 0) { + str = (const char *)view->buf; + size = view->len; + } + else { PyErr_Format(PyExc_TypeError, "%s() arg 1 must be a %s object", funcname, what); return NULL; } - else if (PyObject_AsReadBuffer(cmd, (const void **)&str, &size) < 0) { - return NULL; - } - if (strlen(str) != size) { - PyErr_SetString(PyExc_TypeError, + if (strlen(str) != (size_t)size) { + PyErr_SetString(PyExc_ValueError, "source code string cannot contain null bytes"); + PyBuffer_Release(view); return NULL; } return str; } +/*[clinic input] +compile as builtin_compile + + source: 'O' + filename: object(converter="PyUnicode_FSDecoder") + mode: 's' + flags: 'i' = 0 + dont_inherit: 'i' = 0 + optimize: 'i' = -1 + +Compile source into a code object that can be executed by exec() or eval(). + +The source code may represent a Python module, statement or expression. +The filename will be used for run-time error messages. +The mode must be 'exec' to compile a module, 'single' to compile a +single (interactive) statement, or 'eval' to compile an expression. +The flags argument, if present, controls which future statements influence +the compilation of the code. +The dont_inherit argument, if non-zero, stops the compilation inheriting +the effects of any future statements in effect in the code calling +compile; if absent or zero these statements do influence the compilation, +in addition to any features explicitly specified. +[clinic start generated code]*/ + +PyDoc_STRVAR(builtin_compile__doc__, +"compile($module, /, source, filename, mode, flags=0, dont_inherit=0,\n" +" optimize=-1)\n" +"--\n" +"\n" +"Compile source into a code object that can be executed by exec() or eval().\n" +"\n" +"The source code may represent a Python module, statement or expression.\n" +"The filename will be used for run-time error messages.\n" +"The mode must be \'exec\' to compile a module, \'single\' to compile a\n" +"single (interactive) statement, or \'eval\' to compile an expression.\n" +"The flags argument, if present, controls which future statements influence\n" +"the compilation of the code.\n" +"The dont_inherit argument, if non-zero, stops the compilation inheriting\n" +"the effects of any future statements in effect in the code calling\n" +"compile; if absent or zero these statements do influence the compilation,\n" +"in addition to any features explicitly specified."); + +#define BUILTIN_COMPILE_METHODDEF \ + {"compile", (PyCFunction)builtin_compile, METH_VARARGS|METH_KEYWORDS, builtin_compile__doc__}, + static PyObject * -builtin_compile(PyObject *self, PyObject *args, PyObject *kwds) +builtin_compile_impl(PyModuleDef *module, PyObject *source, PyObject *filename, const char *mode, int flags, int dont_inherit, int optimize); + +static PyObject * +builtin_compile(PyModuleDef *module, PyObject *args, PyObject *kwargs) { - char *str; + PyObject *return_value = NULL; + static char *_keywords[] = {"source", "filename", "mode", "flags", "dont_inherit", "optimize", NULL}; + PyObject *source; PyObject *filename; - char *startstr; - int mode = -1; + const char *mode; + int flags = 0; int dont_inherit = 0; - int supplied_flags = 0; int optimize = -1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "OO&s|iii:compile", _keywords, + &source, PyUnicode_FSDecoder, &filename, &mode, &flags, &dont_inherit, &optimize)) + goto exit; + return_value = builtin_compile_impl(module, source, filename, mode, flags, dont_inherit, optimize); + +exit: + return return_value; +} + +static PyObject * +builtin_compile_impl(PyModuleDef *module, PyObject *source, PyObject *filename, const char *mode, int flags, int dont_inherit, int optimize) +/*[clinic end generated code: output=c72d197809d178fc input=c6212a9d21472f7e]*/ +{ + Py_buffer view = {NULL, NULL}; + const char *str; + int compile_mode = -1; int is_ast; PyCompilerFlags cf; - PyObject *cmd; - static char *kwlist[] = {"source", "filename", "mode", "flags", - "dont_inherit", "optimize", NULL}; int start[] = {Py_file_input, Py_eval_input, Py_single_input}; PyObject *result; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO&s|iii:compile", kwlist, - &cmd, - PyUnicode_FSDecoder, &filename, - &startstr, &supplied_flags, - &dont_inherit, &optimize)) - return NULL; - - cf.cf_flags = supplied_flags | PyCF_SOURCE_IS_UTF8; + cf.cf_flags = flags | PyCF_SOURCE_IS_UTF8; - if (supplied_flags & + if (flags & ~(PyCF_MASK | PyCF_MASK_OBSOLETE | PyCF_DONT_IMPLY_DEDENT | PyCF_ONLY_AST)) { PyErr_SetString(PyExc_ValueError, @@ -635,25 +858,25 @@ builtin_compile(PyObject *self, PyObject *args, PyObject *kwds) PyEval_MergeCompilerFlags(&cf); } - if (strcmp(startstr, "exec") == 0) - mode = 0; - else if (strcmp(startstr, "eval") == 0) - mode = 1; - else if (strcmp(startstr, "single") == 0) - mode = 2; + if (strcmp(mode, "exec") == 0) + compile_mode = 0; + else if (strcmp(mode, "eval") == 0) + compile_mode = 1; + else if (strcmp(mode, "single") == 0) + compile_mode = 2; else { PyErr_SetString(PyExc_ValueError, - "compile() arg 3 must be 'exec', 'eval' or 'single'"); + "compile() mode must be 'exec', 'eval' or 'single'"); goto error; } - is_ast = PyAST_Check(cmd); + is_ast = PyAST_Check(source); if (is_ast == -1) goto error; if (is_ast) { - if (supplied_flags & PyCF_ONLY_AST) { - Py_INCREF(cmd); - result = cmd; + if (flags & PyCF_ONLY_AST) { + Py_INCREF(source); + result = source; } else { PyArena *arena; @@ -662,7 +885,7 @@ builtin_compile(PyObject *self, PyObject *args, PyObject *kwds) arena = PyArena_New(); if (arena == NULL) goto error; - mod = PyAST_obj2mod(cmd, arena, mode); + mod = PyAST_obj2mod(source, arena, compile_mode); if (mod == NULL) { PyArena_Free(arena); goto error; @@ -678,11 +901,12 @@ builtin_compile(PyObject *self, PyObject *args, PyObject *kwds) goto finally; } - str = source_as_string(cmd, "compile", "string, bytes or AST", &cf); + str = source_as_string(source, "compile", "string, bytes or AST", &cf, &view); if (str == NULL) goto error; - result = Py_CompileStringObject(str, filename, start[mode], &cf, optimize); + result = Py_CompileStringObject(str, filename, start[compile_mode], &cf, optimize); + PyBuffer_Release(&view); goto finally; error: @@ -692,21 +916,7 @@ builtin_compile(PyObject *self, PyObject *args, PyObject *kwds) return result; } -PyDoc_STRVAR(compile_doc, -"compile(source, filename, mode[, flags[, dont_inherit]]) -> code object\n\ -\n\ -Compile the source string (a Python module, statement or expression)\n\ -into a code object that can be executed by exec() or eval().\n\ -The filename will be used for run-time error messages.\n\ -The mode must be 'exec' to compile a module, 'single' to compile a\n\ -single (interactive) statement, or 'eval' to compile an expression.\n\ -The flags argument, if present, controls which future statements influence\n\ -the compilation of the code.\n\ -The dont_inherit argument, if non-zero, stops the compilation inheriting\n\ -the effects of any future statements in effect in the code calling\n\ -compile; if absent or zero these statements do influence the compilation,\n\ -in addition to any features explicitly specified."); - +/* AC: cannot convert yet, as needs PEP 457 group support in inspect */ static PyObject * builtin_dir(PyObject *self, PyObject *args) { @@ -731,32 +941,115 @@ PyDoc_STRVAR(dir_doc, " for any other object: its attributes, its class's attributes, and\n" " recursively the attributes of its class's base classes."); +/*[clinic input] +divmod as builtin_divmod + + x: 'O' + y: 'O' + / + +Return the tuple ((x-x%y)/y, x%y). Invariant: div*y + mod == x. +[clinic start generated code]*/ + +PyDoc_STRVAR(builtin_divmod__doc__, +"divmod($module, x, y, /)\n" +"--\n" +"\n" +"Return the tuple ((x-x%y)/y, x%y). Invariant: div*y + mod == x."); + +#define BUILTIN_DIVMOD_METHODDEF \ + {"divmod", (PyCFunction)builtin_divmod, METH_VARARGS, builtin_divmod__doc__}, + +static PyObject * +builtin_divmod_impl(PyModuleDef *module, PyObject *x, PyObject *y); + static PyObject * -builtin_divmod(PyObject *self, PyObject *args) +builtin_divmod(PyModuleDef *module, PyObject *args) { - PyObject *v, *w; + PyObject *return_value = NULL; + PyObject *x; + PyObject *y; + + if (!PyArg_UnpackTuple(args, "divmod", + 2, 2, + &x, &y)) + goto exit; + return_value = builtin_divmod_impl(module, x, y); + +exit: + return return_value; +} - if (!PyArg_UnpackTuple(args, "divmod", 2, 2, &v, &w)) - return NULL; - return PyNumber_Divmod(v, w); +static PyObject * +builtin_divmod_impl(PyModuleDef *module, PyObject *x, PyObject *y) +/*[clinic end generated code: output=77e8d408b1338886 input=c9c617b7bb74c615]*/ +{ + return PyNumber_Divmod(x, y); } -PyDoc_STRVAR(divmod_doc, -"divmod(x, y) -> (div, mod)\n\ -\n\ -Return the tuple ((x-x%y)/y, x%y). Invariant: div*y + mod == x."); +/*[clinic input] +eval as builtin_eval + + source: 'O' + globals: 'O' = None + locals: 'O' = None + / + +Evaluate the given source in the context of globals and locals. + +The source may be a string representing a Python expression +or a code object as returned by compile(). +The globals must be a dictionary and locals can be any mapping, +defaulting to the current globals and locals. +If only globals is given, locals defaults to it. +[clinic start generated code]*/ + +PyDoc_STRVAR(builtin_eval__doc__, +"eval($module, source, globals=None, locals=None, /)\n" +"--\n" +"\n" +"Evaluate the given source in the context of globals and locals.\n" +"\n" +"The source may be a string representing a Python expression\n" +"or a code object as returned by compile().\n" +"The globals must be a dictionary and locals can be any mapping,\n" +"defaulting to the current globals and locals.\n" +"If only globals is given, locals defaults to it."); + +#define BUILTIN_EVAL_METHODDEF \ + {"eval", (PyCFunction)builtin_eval, METH_VARARGS, builtin_eval__doc__}, + +static PyObject * +builtin_eval_impl(PyModuleDef *module, PyObject *source, PyObject *globals, PyObject *locals); static PyObject * -builtin_eval(PyObject *self, PyObject *args) +builtin_eval(PyModuleDef *module, PyObject *args) { - PyObject *cmd, *result, *tmp = NULL; - PyObject *globals = Py_None, *locals = Py_None; - char *str; + PyObject *return_value = NULL; + PyObject *source; + PyObject *globals = Py_None; + PyObject *locals = Py_None; + + if (!PyArg_UnpackTuple(args, "eval", + 1, 3, + &source, &globals, &locals)) + goto exit; + return_value = builtin_eval_impl(module, source, globals, locals); + +exit: + return return_value; +} + +static PyObject * +builtin_eval_impl(PyModuleDef *module, PyObject *source, PyObject *globals, PyObject *locals) +/*[clinic end generated code: output=644fd59012538ce6 input=31e42c1d2125b50b]*/ +{ + PyObject *result, *tmp = NULL; + Py_buffer view = {NULL, NULL}; + const char *str; PyCompilerFlags cf; - if (!PyArg_UnpackTuple(args, "eval", 1, 3, &cmd, &globals, &locals)) - return NULL; if (locals != Py_None && !PyMapping_Check(locals)) { PyErr_SetString(PyExc_TypeError, "locals must be a mapping"); return NULL; @@ -791,17 +1084,17 @@ builtin_eval(PyObject *self, PyObject *args) return NULL; } - if (PyCode_Check(cmd)) { - if (PyCode_GetNumFree((PyCodeObject *)cmd) > 0) { + if (PyCode_Check(source)) { + if (PyCode_GetNumFree((PyCodeObject *)source) > 0) { PyErr_SetString(PyExc_TypeError, "code object passed to eval() may not contain free variables"); return NULL; } - return PyEval_EvalCode(cmd, globals, locals); + return PyEval_EvalCode(source, globals, locals); } cf.cf_flags = PyCF_SOURCE_IS_UTF8; - str = source_as_string(cmd, "eval", "string, bytes or code", &cf); + str = source_as_string(source, "eval", "string, bytes or code", &cf, &view); if (str == NULL) return NULL; @@ -810,28 +1103,69 @@ builtin_eval(PyObject *self, PyObject *args) (void)PyEval_MergeCompilerFlags(&cf); result = PyRun_StringFlags(str, Py_eval_input, globals, locals, &cf); + PyBuffer_Release(&view); Py_XDECREF(tmp); return result; } -PyDoc_STRVAR(eval_doc, -"eval(source[, globals[, locals]]) -> value\n\ -\n\ -Evaluate the source in the context of globals and locals.\n\ -The source may be a string representing a Python expression\n\ -or a code object as returned by compile().\n\ -The globals must be a dictionary and locals can be any mapping,\n\ -defaulting to the current globals and locals.\n\ -If only globals is given, locals defaults to it.\n"); +/*[clinic input] +exec as builtin_exec + + source: 'O' + globals: 'O' = None + locals: 'O' = None + / + +Execute the given source in the context of globals and locals. + +The source may be a string representing one or more Python statements +or a code object as returned by compile(). +The globals must be a dictionary and locals can be any mapping, +defaulting to the current globals and locals. +If only globals is given, locals defaults to it. +[clinic start generated code]*/ + +PyDoc_STRVAR(builtin_exec__doc__, +"exec($module, source, globals=None, locals=None, /)\n" +"--\n" +"\n" +"Execute the given source in the context of globals and locals.\n" +"\n" +"The source may be a string representing one or more Python statements\n" +"or a code object as returned by compile().\n" +"The globals must be a dictionary and locals can be any mapping,\n" +"defaulting to the current globals and locals.\n" +"If only globals is given, locals defaults to it."); + +#define BUILTIN_EXEC_METHODDEF \ + {"exec", (PyCFunction)builtin_exec, METH_VARARGS, builtin_exec__doc__}, + +static PyObject * +builtin_exec_impl(PyModuleDef *module, PyObject *source, PyObject *globals, PyObject *locals); static PyObject * -builtin_exec(PyObject *self, PyObject *args) +builtin_exec(PyModuleDef *module, PyObject *args) { - PyObject *v; - PyObject *prog, *globals = Py_None, *locals = Py_None; + PyObject *return_value = NULL; + PyObject *source; + PyObject *globals = Py_None; + PyObject *locals = Py_None; + + if (!PyArg_UnpackTuple(args, "exec", + 1, 3, + &source, &globals, &locals)) + goto exit; + return_value = builtin_exec_impl(module, source, globals, locals); + +exit: + return return_value; +} - if (!PyArg_UnpackTuple(args, "exec", 1, 3, &prog, &globals, &locals)) - return NULL; +static PyObject * +builtin_exec_impl(PyModuleDef *module, PyObject *source, PyObject *globals, PyObject *locals) +/*[clinic end generated code: output=0281b48bfa8e3c87 input=536e057b5e00d89e]*/ +{ + PyObject *v; if (globals == Py_None) { globals = PyEval_GetGlobals(); @@ -850,13 +1184,13 @@ builtin_exec(PyObject *self, PyObject *args) locals = globals; if (!PyDict_Check(globals)) { - PyErr_Format(PyExc_TypeError, "exec() arg 2 must be a dict, not %.100s", + PyErr_Format(PyExc_TypeError, "exec() globals must be a dict, not %.100s", globals->ob_type->tp_name); return NULL; } if (!PyMapping_Check(locals)) { PyErr_Format(PyExc_TypeError, - "arg 3 must be a mapping or None, not %.100s", + "locals must be a mapping or None, not %.100s", locals->ob_type->tp_name); return NULL; } @@ -866,21 +1200,22 @@ builtin_exec(PyObject *self, PyObject *args) return NULL; } - if (PyCode_Check(prog)) { - if (PyCode_GetNumFree((PyCodeObject *)prog) > 0) { + if (PyCode_Check(source)) { + if (PyCode_GetNumFree((PyCodeObject *)source) > 0) { PyErr_SetString(PyExc_TypeError, "code object passed to exec() may not " "contain free variables"); return NULL; } - v = PyEval_EvalCode(prog, globals, locals); + v = PyEval_EvalCode(source, globals, locals); } else { - char *str; + Py_buffer view = {NULL, NULL}; + const char *str; PyCompilerFlags cf; cf.cf_flags = PyCF_SOURCE_IS_UTF8; - str = source_as_string(prog, "exec", - "string, bytes or code", &cf); + str = source_as_string(source, "exec", + "string, bytes or code", &cf, &view); if (str == NULL) return NULL; if (PyEval_MergeCompilerFlags(&cf)) @@ -888,6 +1223,7 @@ builtin_exec(PyObject *self, PyObject *args) locals, &cf); else v = PyRun_String(str, Py_file_input, globals, locals); + PyBuffer_Release(&view); } if (v == NULL) return NULL; @@ -895,15 +1231,8 @@ builtin_exec(PyObject *self, PyObject *args) Py_RETURN_NONE; } -PyDoc_STRVAR(exec_doc, -"exec(object[, globals[, locals]])\n\ -\n\ -Read and execute code from an object, which can be a string or a code\n\ -object.\n\ -The globals and locals are dictionaries, defaulting to the current\n\ -globals and locals. If only globals is given, locals defaults to it."); - +/* AC: cannot convert yet, as needs PEP 457 group support in inspect */ static PyObject * builtin_getattr(PyObject *self, PyObject *args) { @@ -937,8 +1266,39 @@ When a default argument is given, it is returned when the attribute doesn't\n\ exist; without it, an exception is raised in that case."); +/*[clinic input] +globals as builtin_globals + +Return the dictionary containing the current scope's global variables. + +NOTE: Updates to this dictionary *will* affect name lookups in the current +global scope and vice-versa. +[clinic start generated code]*/ + +PyDoc_STRVAR(builtin_globals__doc__, +"globals($module, /)\n" +"--\n" +"\n" +"Return the dictionary containing the current scope\'s global variables.\n" +"\n" +"NOTE: Updates to this dictionary *will* affect name lookups in the current\n" +"global scope and vice-versa."); + +#define BUILTIN_GLOBALS_METHODDEF \ + {"globals", (PyCFunction)builtin_globals, METH_NOARGS, builtin_globals__doc__}, + +static PyObject * +builtin_globals_impl(PyModuleDef *module); + +static PyObject * +builtin_globals(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return builtin_globals_impl(module); +} + static PyObject * -builtin_globals(PyObject *self) +builtin_globals_impl(PyModuleDef *module) +/*[clinic end generated code: output=048640f58b1f20ad input=9327576f92bb48ba]*/ { PyObject *d; @@ -947,26 +1307,62 @@ builtin_globals(PyObject *self) return d; } -PyDoc_STRVAR(globals_doc, -"globals() -> dictionary\n\ -\n\ -Return the dictionary containing the current scope's global variables."); +/*[clinic input] +hasattr as builtin_hasattr + + obj: 'O' + name: 'O' + / + +Return whether the object has an attribute with the given name. + +This is done by calling getattr(obj, name) and catching AttributeError. +[clinic start generated code]*/ + +PyDoc_STRVAR(builtin_hasattr__doc__, +"hasattr($module, obj, name, /)\n" +"--\n" +"\n" +"Return whether the object has an attribute with the given name.\n" +"\n" +"This is done by calling getattr(obj, name) and catching AttributeError."); + +#define BUILTIN_HASATTR_METHODDEF \ + {"hasattr", (PyCFunction)builtin_hasattr, METH_VARARGS, builtin_hasattr__doc__}, + +static PyObject * +builtin_hasattr_impl(PyModuleDef *module, PyObject *obj, PyObject *name); static PyObject * -builtin_hasattr(PyObject *self, PyObject *args) +builtin_hasattr(PyModuleDef *module, PyObject *args) { - PyObject *v; + PyObject *return_value = NULL; + PyObject *obj; PyObject *name; - if (!PyArg_UnpackTuple(args, "hasattr", 2, 2, &v, &name)) - return NULL; + if (!PyArg_UnpackTuple(args, "hasattr", + 2, 2, + &obj, &name)) + goto exit; + return_value = builtin_hasattr_impl(module, obj, name); + +exit: + return return_value; +} + +static PyObject * +builtin_hasattr_impl(PyModuleDef *module, PyObject *obj, PyObject *name) +/*[clinic end generated code: output=e0bd996ef73d1217 input=b50bad5f739ea10d]*/ +{ + PyObject *v; + if (!PyUnicode_Check(name)) { PyErr_SetString(PyExc_TypeError, "hasattr(): attribute name must be string"); return NULL; } - v = PyObject_GetAttr(v, name); + v = PyObject_GetAttr(obj, name); if (v == NULL) { if (PyErr_ExceptionMatches(PyExc_AttributeError)) { PyErr_Clear(); @@ -978,25 +1374,43 @@ builtin_hasattr(PyObject *self, PyObject *args) Py_RETURN_TRUE; } -PyDoc_STRVAR(hasattr_doc, -"hasattr(object, name) -> bool\n\ -\n\ -Return whether the object has an attribute with the given name.\n\ -(This is done by calling getattr(object, name) and catching AttributeError.)"); +/* AC: gdb's integration with CPython relies on builtin_id having + * the *exact* parameter names of "self" and "v", so we ensure we + * preserve those name rather than using the AC defaults. + */ +/*[clinic input] +id as builtin_id + + self: self(type="PyModuleDef *") + obj as v: 'O' + / + +Return the identity of an object. + +This is guaranteed to be unique among simultaneously existing objects. +(CPython uses the object's memory address.) +[clinic start generated code]*/ + +PyDoc_STRVAR(builtin_id__doc__, +"id($module, obj, /)\n" +"--\n" +"\n" +"Return the identity of an object.\n" +"\n" +"This is guaranteed to be unique among simultaneously existing objects.\n" +"(CPython uses the object\'s memory address.)"); + +#define BUILTIN_ID_METHODDEF \ + {"id", (PyCFunction)builtin_id, METH_O, builtin_id__doc__}, static PyObject * -builtin_id(PyObject *self, PyObject *v) +builtin_id(PyModuleDef *self, PyObject *v) +/*[clinic end generated code: output=f54da09c91992e63 input=a1f988d98357341d]*/ { return PyLong_FromVoidPtr(v); } -PyDoc_STRVAR(id_doc, -"id(object) -> integer\n\ -\n\ -Return the identity of an object. This is guaranteed to be unique among\n\ -simultaneously existing objects. (Hint: it's the object's memory address.)"); - /* map object ************************************************************/ @@ -1169,6 +1583,8 @@ PyTypeObject PyMap_Type = { PyObject_GC_Del, /* tp_free */ }; + +/* AC: cannot convert yet, as needs PEP 457 group support in inspect */ static PyObject * builtin_next(PyObject *self, PyObject *args) { @@ -1210,83 +1626,186 @@ Return the next item from the iterator. If default is given and the iterator\n\ is exhausted, it is returned instead of raising StopIteration."); +/*[clinic input] +setattr as builtin_setattr + + obj: 'O' + name: 'O' + value: 'O' + / + +Sets the named attribute on the given object to the specified value. + +setattr(x, 'y', v) is equivalent to ``x.y = v'' +[clinic start generated code]*/ + +PyDoc_STRVAR(builtin_setattr__doc__, +"setattr($module, obj, name, value, /)\n" +"--\n" +"\n" +"Sets the named attribute on the given object to the specified value.\n" +"\n" +"setattr(x, \'y\', v) is equivalent to ``x.y = v\'\'"); + +#define BUILTIN_SETATTR_METHODDEF \ + {"setattr", (PyCFunction)builtin_setattr, METH_VARARGS, builtin_setattr__doc__}, + +static PyObject * +builtin_setattr_impl(PyModuleDef *module, PyObject *obj, PyObject *name, PyObject *value); + static PyObject * -builtin_setattr(PyObject *self, PyObject *args) +builtin_setattr(PyModuleDef *module, PyObject *args) { - PyObject *v; + PyObject *return_value = NULL; + PyObject *obj; PyObject *name; PyObject *value; - if (!PyArg_UnpackTuple(args, "setattr", 3, 3, &v, &name, &value)) - return NULL; - if (PyObject_SetAttr(v, name, value) != 0) + if (!PyArg_UnpackTuple(args, "setattr", + 3, 3, + &obj, &name, &value)) + goto exit; + return_value = builtin_setattr_impl(module, obj, name, value); + +exit: + return return_value; +} + +static PyObject * +builtin_setattr_impl(PyModuleDef *module, PyObject *obj, PyObject *name, PyObject *value) +/*[clinic end generated code: output=4336dcbbf7691d2d input=fbe7e53403116b93]*/ +{ + if (PyObject_SetAttr(obj, name, value) != 0) return NULL; Py_INCREF(Py_None); return Py_None; } -PyDoc_STRVAR(setattr_doc, -"setattr(object, name, value)\n\ -\n\ -Set a named attribute on an object; setattr(x, 'y', v) is equivalent to\n\ -``x.y = v''."); +/*[clinic input] +delattr as builtin_delattr + + obj: 'O' + name: 'O' + / + +Deletes the named attribute from the given object. + +delattr(x, 'y') is equivalent to ``del x.y'' +[clinic start generated code]*/ + +PyDoc_STRVAR(builtin_delattr__doc__, +"delattr($module, obj, name, /)\n" +"--\n" +"\n" +"Deletes the named attribute from the given object.\n" +"\n" +"delattr(x, \'y\') is equivalent to ``del x.y\'\'"); + +#define BUILTIN_DELATTR_METHODDEF \ + {"delattr", (PyCFunction)builtin_delattr, METH_VARARGS, builtin_delattr__doc__}, static PyObject * -builtin_delattr(PyObject *self, PyObject *args) +builtin_delattr_impl(PyModuleDef *module, PyObject *obj, PyObject *name); + +static PyObject * +builtin_delattr(PyModuleDef *module, PyObject *args) { - PyObject *v; + PyObject *return_value = NULL; + PyObject *obj; PyObject *name; - if (!PyArg_UnpackTuple(args, "delattr", 2, 2, &v, &name)) - return NULL; - if (PyObject_SetAttr(v, name, (PyObject *)NULL) != 0) + if (!PyArg_UnpackTuple(args, "delattr", + 2, 2, + &obj, &name)) + goto exit; + return_value = builtin_delattr_impl(module, obj, name); + +exit: + return return_value; +} + +static PyObject * +builtin_delattr_impl(PyModuleDef *module, PyObject *obj, PyObject *name) +/*[clinic end generated code: output=319c2d884aa769cf input=647af2ce9183a823]*/ +{ + if (PyObject_SetAttr(obj, name, (PyObject *)NULL) != 0) return NULL; Py_INCREF(Py_None); return Py_None; } -PyDoc_STRVAR(delattr_doc, -"delattr(object, name)\n\ -\n\ -Delete a named attribute on an object; delattr(x, 'y') is equivalent to\n\ -``del x.y''."); +/*[clinic input] +hash as builtin_hash + + obj: 'O' + / + +Return the hash value for the given object. + +Two objects that compare equal must also have the same hash value, but the +reverse is not necessarily true. +[clinic start generated code]*/ + +PyDoc_STRVAR(builtin_hash__doc__, +"hash($module, obj, /)\n" +"--\n" +"\n" +"Return the hash value for the given object.\n" +"\n" +"Two objects that compare equal must also have the same hash value, but the\n" +"reverse is not necessarily true."); + +#define BUILTIN_HASH_METHODDEF \ + {"hash", (PyCFunction)builtin_hash, METH_O, builtin_hash__doc__}, static PyObject * -builtin_hash(PyObject *self, PyObject *v) +builtin_hash(PyModuleDef *module, PyObject *obj) +/*[clinic end generated code: output=1ec467611c13468b input=ccc4d2b9a351df4e]*/ { Py_hash_t x; - x = PyObject_Hash(v); + x = PyObject_Hash(obj); if (x == -1) return NULL; return PyLong_FromSsize_t(x); } -PyDoc_STRVAR(hash_doc, -"hash(object) -> integer\n\ -\n\ -Return a hash value for the object. Two objects with the same value have\n\ -the same hash value. The reverse is not necessarily true, but likely."); +/*[clinic input] +hex as builtin_hex + + number: 'O' + / + +Return the hexadecimal representation of an integer. + + >>> hex(12648430) + '0xc0ffee' +[clinic start generated code]*/ + +PyDoc_STRVAR(builtin_hex__doc__, +"hex($module, number, /)\n" +"--\n" +"\n" +"Return the hexadecimal representation of an integer.\n" +"\n" +" >>> hex(12648430)\n" +" \'0xc0ffee\'"); + +#define BUILTIN_HEX_METHODDEF \ + {"hex", (PyCFunction)builtin_hex, METH_O, builtin_hex__doc__}, static PyObject * -builtin_hex(PyObject *self, PyObject *v) +builtin_hex(PyModuleDef *module, PyObject *number) +/*[clinic end generated code: output=f18e9439aeaa2c6c input=e816200b0a728ebe]*/ { - return PyNumber_ToBase(v, 16); + return PyNumber_ToBase(number, 16); } -PyDoc_STRVAR(hex_doc, -"hex(number) -> string\n\ -\n\ -Return the hexadecimal representation of an integer.\n\ -\n\ - >>> hex(3735928559)\n\ - '0xdeadbeef'\n\ -"); - +/* AC: cannot convert yet, as needs PEP 457 group support in inspect */ static PyObject * builtin_iter(PyObject *self, PyObject *args) { @@ -1313,25 +1832,72 @@ supply its own iterator, or be a sequence.\n\ In the second form, the callable is called until it returns the sentinel."); +/*[clinic input] +len as builtin_len + + obj: 'O' + / + +Return the number of items in a container. +[clinic start generated code]*/ + +PyDoc_STRVAR(builtin_len__doc__, +"len($module, obj, /)\n" +"--\n" +"\n" +"Return the number of items in a container."); + +#define BUILTIN_LEN_METHODDEF \ + {"len", (PyCFunction)builtin_len, METH_O, builtin_len__doc__}, + static PyObject * -builtin_len(PyObject *self, PyObject *v) +builtin_len(PyModuleDef *module, PyObject *obj) +/*[clinic end generated code: output=5a38b0db40761705 input=2e5ff15db9a2de22]*/ { Py_ssize_t res; - res = PyObject_Size(v); + res = PyObject_Size(obj); if (res < 0 && PyErr_Occurred()) return NULL; return PyLong_FromSsize_t(res); } -PyDoc_STRVAR(len_doc, -"len(object) -> integer\n\ -\n\ -Return the number of items of a sequence or mapping."); +/*[clinic input] +locals as builtin_locals + +Return a dictionary containing the current scope's local variables. + +NOTE: Whether or not updates to this dictionary will affect name lookups in +the local scope and vice-versa is *implementation dependent* and not +covered by any backwards compatibility guarantees. +[clinic start generated code]*/ + +PyDoc_STRVAR(builtin_locals__doc__, +"locals($module, /)\n" +"--\n" +"\n" +"Return a dictionary containing the current scope\'s local variables.\n" +"\n" +"NOTE: Whether or not updates to this dictionary will affect name lookups in\n" +"the local scope and vice-versa is *implementation dependent* and not\n" +"covered by any backwards compatibility guarantees."); + +#define BUILTIN_LOCALS_METHODDEF \ + {"locals", (PyCFunction)builtin_locals, METH_NOARGS, builtin_locals__doc__}, + +static PyObject * +builtin_locals_impl(PyModuleDef *module); + +static PyObject * +builtin_locals(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return builtin_locals_impl(module); +} static PyObject * -builtin_locals(PyObject *self) +builtin_locals_impl(PyModuleDef *module) +/*[clinic end generated code: output=8ac52522924346e2 input=7874018d478d5c4b]*/ { PyObject *d; @@ -1340,11 +1906,6 @@ builtin_locals(PyObject *self) return d; } -PyDoc_STRVAR(locals_doc, -"locals() -> dictionary\n\ -\n\ -Update and return a dictionary containing the current scope's local variables."); - static PyObject * min_max(PyObject *args, PyObject *kwds, int op) @@ -1447,6 +2008,7 @@ min_max(PyObject *args, PyObject *kwds, int op) return NULL; } +/* AC: cannot convert yet, waiting for *args support */ static PyObject * builtin_min(PyObject *self, PyObject *args, PyObject *kwds) { @@ -1454,13 +2016,16 @@ builtin_min(PyObject *self, PyObject *args, PyObject *kwds) } PyDoc_STRVAR(min_doc, -"min(iterable[, key=func]) -> value\n\ -min(a, b, c, ...[, key=func]) -> value\n\ +"min(iterable, *[, default=obj, key=func]) -> value\n\ +min(arg1, arg2, *args, *[, key=func]) -> value\n\ \n\ -With a single iterable argument, return its smallest item.\n\ +With a single iterable argument, return its smallest item. The\n\ +default keyword-only argument specifies an object to return if\n\ +the provided iterable is empty.\n\ With two or more arguments, return the smallest argument."); +/* AC: cannot convert yet, waiting for *args support */ static PyObject * builtin_max(PyObject *self, PyObject *args, PyObject *kwds) { @@ -1468,63 +2033,100 @@ builtin_max(PyObject *self, PyObject *args, PyObject *kwds) } PyDoc_STRVAR(max_doc, -"max(iterable[, key=func]) -> value\n\ -max(a, b, c, ...[, key=func]) -> value\n\ +"max(iterable, *[, default=obj, key=func]) -> value\n\ +max(arg1, arg2, *args, *[, key=func]) -> value\n\ \n\ -With a single iterable argument, return its largest item.\n\ +With a single iterable argument, return its biggest item. The\n\ +default keyword-only argument specifies an object to return if\n\ +the provided iterable is empty.\n\ With two or more arguments, return the largest argument."); +/*[clinic input] +oct as builtin_oct + + number: 'O' + / + +Return the octal representation of an integer. + + >>> oct(342391) + '0o1234567' +[clinic start generated code]*/ + +PyDoc_STRVAR(builtin_oct__doc__, +"oct($module, number, /)\n" +"--\n" +"\n" +"Return the octal representation of an integer.\n" +"\n" +" >>> oct(342391)\n" +" \'0o1234567\'"); + +#define BUILTIN_OCT_METHODDEF \ + {"oct", (PyCFunction)builtin_oct, METH_O, builtin_oct__doc__}, + static PyObject * -builtin_oct(PyObject *self, PyObject *v) +builtin_oct(PyModuleDef *module, PyObject *number) +/*[clinic end generated code: output=b99234d1d70a6673 input=a3a372b521b3dd13]*/ { - return PyNumber_ToBase(v, 8); + return PyNumber_ToBase(number, 8); } -PyDoc_STRVAR(oct_doc, -"oct(number) -> string\n\ -\n\ -Return the octal representation of an integer.\n\ -\n\ - >>> oct(342391)\n\ - '0o1234567'\n\ -"); +/*[clinic input] +ord as builtin_ord + + c: 'O' + / + +Return the Unicode code point for a one-character string. +[clinic start generated code]*/ + +PyDoc_STRVAR(builtin_ord__doc__, +"ord($module, c, /)\n" +"--\n" +"\n" +"Return the Unicode code point for a one-character string."); + +#define BUILTIN_ORD_METHODDEF \ + {"ord", (PyCFunction)builtin_ord, METH_O, builtin_ord__doc__}, static PyObject * -builtin_ord(PyObject *self, PyObject* obj) +builtin_ord(PyModuleDef *module, PyObject *c) +/*[clinic end generated code: output=a8466d23bd76db3f input=762355f87451efa3]*/ { long ord; Py_ssize_t size; - if (PyBytes_Check(obj)) { - size = PyBytes_GET_SIZE(obj); + if (PyBytes_Check(c)) { + size = PyBytes_GET_SIZE(c); if (size == 1) { - ord = (long)((unsigned char)*PyBytes_AS_STRING(obj)); + ord = (long)((unsigned char)*PyBytes_AS_STRING(c)); return PyLong_FromLong(ord); } } - else if (PyUnicode_Check(obj)) { - if (PyUnicode_READY(obj) == -1) + else if (PyUnicode_Check(c)) { + if (PyUnicode_READY(c) == -1) return NULL; - size = PyUnicode_GET_LENGTH(obj); + size = PyUnicode_GET_LENGTH(c); if (size == 1) { - ord = (long)PyUnicode_READ_CHAR(obj, 0); + ord = (long)PyUnicode_READ_CHAR(c, 0); return PyLong_FromLong(ord); } } - else if (PyByteArray_Check(obj)) { + else if (PyByteArray_Check(c)) { /* XXX Hopefully this is temporary */ - size = PyByteArray_GET_SIZE(obj); + size = PyByteArray_GET_SIZE(c); if (size == 1) { - ord = (long)((unsigned char)*PyByteArray_AS_STRING(obj)); + ord = (long)((unsigned char)*PyByteArray_AS_STRING(c)); return PyLong_FromLong(ord); } } else { PyErr_Format(PyExc_TypeError, "ord() expected string of length 1, but " \ - "%.200s found", obj->ob_type->tp_name); + "%.200s found", c->ob_type->tp_name); return NULL; } @@ -1535,31 +2137,63 @@ builtin_ord(PyObject *self, PyObject* obj) return NULL; } -PyDoc_VAR(ord_doc) = PyDoc_STR( -"ord(c) -> integer\n\ -\n\ -Return the integer ordinal of a one-character string." -); +/*[clinic input] +pow as builtin_pow + + x: 'O' + y: 'O' + z: 'O' = None + / + +Equivalent to x**y (with two arguments) or x**y % z (with three arguments) + +Some types, such as ints, are able to use a more efficient algorithm when +invoked using the three argument form. +[clinic start generated code]*/ + +PyDoc_STRVAR(builtin_pow__doc__, +"pow($module, x, y, z=None, /)\n" +"--\n" +"\n" +"Equivalent to x**y (with two arguments) or x**y % z (with three arguments)\n" +"\n" +"Some types, such as ints, are able to use a more efficient algorithm when\n" +"invoked using the three argument form."); + +#define BUILTIN_POW_METHODDEF \ + {"pow", (PyCFunction)builtin_pow, METH_VARARGS, builtin_pow__doc__}, static PyObject * -builtin_pow(PyObject *self, PyObject *args) -{ - PyObject *v, *w, *z = Py_None; +builtin_pow_impl(PyModuleDef *module, PyObject *x, PyObject *y, PyObject *z); - if (!PyArg_UnpackTuple(args, "pow", 2, 3, &v, &w, &z)) - return NULL; - return PyNumber_Power(v, w, z); +static PyObject * +builtin_pow(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *x; + PyObject *y; + PyObject *z = Py_None; + + if (!PyArg_UnpackTuple(args, "pow", + 2, 3, + &x, &y, &z)) + goto exit; + return_value = builtin_pow_impl(module, x, y, z); + +exit: + return return_value; } -PyDoc_STRVAR(pow_doc, -"pow(x, y[, z]) -> number\n\ -\n\ -With two arguments, equivalent to x**y. With three arguments,\n\ -equivalent to (x**y) % z, but may be more efficient (e.g. for ints)."); - +static PyObject * +builtin_pow_impl(PyModuleDef *module, PyObject *x, PyObject *y, PyObject *z) +/*[clinic end generated code: output=d0cdf314311dedba input=561a942d5f5c1899]*/ +{ + return PyNumber_Power(x, y, z); +} +/* AC: cannot convert yet, waiting for *args support */ static PyObject * builtin_print(PyObject *self, PyObject *args, PyObject *kwds) { @@ -1655,10 +2289,59 @@ end: string appended after the last value, default a newline.\n\ flush: whether to forcibly flush the stream."); +/*[clinic input] +input as builtin_input + + prompt: object(c_default="NULL") = None + / + +Read a string from standard input. The trailing newline is stripped. + +The prompt string, if given, is printed to standard output without a +trailing newline before reading input. + +If the user hits EOF (*nix: Ctrl-D, Windows: Ctrl-Z+Return), raise EOFError. +On *nix systems, readline is used if available. +[clinic start generated code]*/ + +PyDoc_STRVAR(builtin_input__doc__, +"input($module, prompt=None, /)\n" +"--\n" +"\n" +"Read a string from standard input. The trailing newline is stripped.\n" +"\n" +"The prompt string, if given, is printed to standard output without a\n" +"trailing newline before reading input.\n" +"\n" +"If the user hits EOF (*nix: Ctrl-D, Windows: Ctrl-Z+Return), raise EOFError.\n" +"On *nix systems, readline is used if available."); + +#define BUILTIN_INPUT_METHODDEF \ + {"input", (PyCFunction)builtin_input, METH_VARARGS, builtin_input__doc__}, + static PyObject * -builtin_input(PyObject *self, PyObject *args) +builtin_input_impl(PyModuleDef *module, PyObject *prompt); + +static PyObject * +builtin_input(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *prompt = NULL; + + if (!PyArg_UnpackTuple(args, "input", + 0, 1, + &prompt)) + goto exit; + return_value = builtin_input_impl(module, prompt); + +exit: + return return_value; +} + +static PyObject * +builtin_input_impl(PyModuleDef *module, PyObject *prompt) +/*[clinic end generated code: output=69323bf5695f7c9c input=5e8bb70c2908fe3c]*/ { - PyObject *promptarg = NULL; PyObject *fin = _PySys_GetObjectId(&PyId_stdin); PyObject *fout = _PySys_GetObjectId(&PyId_stdout); PyObject *ferr = _PySys_GetObjectId(&PyId_stderr); @@ -1666,10 +2349,6 @@ builtin_input(PyObject *self, PyObject *args) long fd; int tty; - /* Parse arguments */ - if (!PyArg_UnpackTuple(args, "input", 0, 1, &promptarg)) - return NULL; - /* Check that stdin/out/err are intact */ if (fin == NULL || fin == Py_None) { PyErr_SetString(PyExc_RuntimeError, @@ -1725,7 +2404,7 @@ builtin_input(PyObject *self, PyObject *args) /* If we're interactive, use (GNU) readline */ if (tty) { PyObject *po = NULL; - char *prompt; + char *promptstr; char *s = NULL; PyObject *stdin_encoding = NULL, *stdin_errors = NULL; PyObject *stdout_encoding = NULL, *stdout_errors = NULL; @@ -1748,7 +2427,7 @@ builtin_input(PyObject *self, PyObject *args) PyErr_Clear(); else Py_DECREF(tmp); - if (promptarg != NULL) { + if (prompt != NULL) { /* We have a prompt, encode it as stdout would */ char *stdout_encoding_str, *stdout_errors_str; PyObject *stringpo; @@ -1760,7 +2439,7 @@ builtin_input(PyObject *self, PyObject *args) stdout_errors_str = _PyUnicode_AsString(stdout_errors); if (!stdout_encoding_str || !stdout_errors_str) goto _readline_errors; - stringpo = PyObject_Str(promptarg); + stringpo = PyObject_Str(prompt); if (stringpo == NULL) goto _readline_errors; po = PyUnicode_AsEncodedString(stringpo, @@ -1770,15 +2449,15 @@ builtin_input(PyObject *self, PyObject *args) Py_CLEAR(stringpo); if (po == NULL) goto _readline_errors; - prompt = PyBytes_AsString(po); - if (prompt == NULL) + promptstr = PyBytes_AsString(po); + if (promptstr == NULL) goto _readline_errors; } else { po = NULL; - prompt = ""; + promptstr = ""; } - s = PyOS_Readline(stdin, stdout, prompt); + s = PyOS_Readline(stdin, stdout, promptstr); if (s == NULL) { PyErr_CheckSignals(); if (!PyErr_Occurred()) @@ -1820,8 +2499,8 @@ builtin_input(PyObject *self, PyObject *args) } /* Fallback if we're not interactive */ - if (promptarg != NULL) { - if (PyFile_WriteObject(promptarg, fout, Py_PRINT_RAW) != 0) + if (prompt != NULL) { + if (PyFile_WriteObject(prompt, fout, Py_PRINT_RAW) != 0) return NULL; } tmp = _PyObject_CallMethodId(fout, &PyId_flush, ""); @@ -1832,28 +2511,40 @@ builtin_input(PyObject *self, PyObject *args) return PyFile_GetLine(fin, -1); } -PyDoc_STRVAR(input_doc, -"input([prompt]) -> string\n\ -\n\ -Read a string from standard input. The trailing newline is stripped.\n\ -If the user hits EOF (Unix: Ctl-D, Windows: Ctl-Z+Return), raise EOFError.\n\ -On Unix, GNU readline is used if enabled. The prompt string, if given,\n\ -is printed without a trailing newline before reading."); +/*[clinic input] +repr as builtin_repr + + obj: 'O' + / + +Return the canonical string representation of the object. + +For many object types, including most builtins, eval(repr(obj)) == obj. +[clinic start generated code]*/ + +PyDoc_STRVAR(builtin_repr__doc__, +"repr($module, obj, /)\n" +"--\n" +"\n" +"Return the canonical string representation of the object.\n" +"\n" +"For many object types, including most builtins, eval(repr(obj)) == obj."); + +#define BUILTIN_REPR_METHODDEF \ + {"repr", (PyCFunction)builtin_repr, METH_O, builtin_repr__doc__}, static PyObject * -builtin_repr(PyObject *self, PyObject *v) +builtin_repr(PyModuleDef *module, PyObject *obj) +/*[clinic end generated code: output=988980120f39e2fa input=a2bca0f38a5a924d]*/ { - return PyObject_Repr(v); + return PyObject_Repr(obj); } -PyDoc_STRVAR(repr_doc, -"repr(object) -> string\n\ -\n\ -Return the canonical string representation of the object.\n\ -For most object types, eval(repr(object)) == object."); - +/* AC: cannot convert yet, as needs PEP 457 group support in inspect + * or a semantic change to accept None for "ndigits" + */ static PyObject * builtin_round(PyObject *self, PyObject *args, PyObject *kwds) { @@ -1895,6 +2586,35 @@ This returns an int when called with one argument, otherwise the\n\ same type as the number. ndigits may be negative."); +/*AC: we need to keep the kwds dict intact to easily call into the + * list.sort method, which isn't currently supported in AC. So we just use + * the initially generated signature with a custom implementation. + */ +/* [disabled clinic input] +sorted as builtin_sorted + + iterable as seq: 'O' + key as keyfunc: 'O' = None + reverse: 'O' = False + +Return a new list containing all items from the iterable in ascending order. + +A custom key function can be supplied to customise the sort order, and the +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" +"--\n" +"\n" +"Return a new list containing all items from the iterable in ascending order.\n" +"\n" +"A custom key function can be supplied to customise the sort order, and the\n" +"reverse flag can be set to request the result in descending order."); + +#define BUILTIN_SORTED_METHODDEF \ + {"sorted", (PyCFunction)builtin_sorted, METH_VARARGS|METH_KEYWORDS, builtin_sorted__doc__}, + static PyObject * builtin_sorted(PyObject *self, PyObject *args, PyObject *kwds) { @@ -1936,9 +2656,8 @@ builtin_sorted(PyObject *self, PyObject *args, PyObject *kwds) return newlist; } -PyDoc_STRVAR(sorted_doc, -"sorted(iterable, key=None, reverse=False) --> new sorted list"); +/* AC: cannot convert yet, as needs PEP 457 group support in inspect */ static PyObject * builtin_vars(PyObject *self, PyObject *args) { @@ -1970,17 +2689,62 @@ PyDoc_STRVAR(vars_doc, Without arguments, equivalent to locals().\n\ With an argument, equivalent to object.__dict__."); -static PyObject* -builtin_sum(PyObject *self, PyObject *args) + +/*[clinic input] +sum as builtin_sum + + iterable: 'O' + start: object(c_default="NULL") = 0 + / + +Return the sum of a 'start' value (default: 0) plus an iterable of numbers + +When the iterable is empty, return the start value. +This function is intended specifically for use with numeric values and may +reject non-numeric types. +[clinic start generated code]*/ + +PyDoc_STRVAR(builtin_sum__doc__, +"sum($module, iterable, start=0, /)\n" +"--\n" +"\n" +"Return the sum of a \'start\' value (default: 0) plus an iterable of numbers\n" +"\n" +"When the iterable is empty, return the start value.\n" +"This function is intended specifically for use with numeric values and may\n" +"reject non-numeric types."); + +#define BUILTIN_SUM_METHODDEF \ + {"sum", (PyCFunction)builtin_sum, METH_VARARGS, builtin_sum__doc__}, + +static PyObject * +builtin_sum_impl(PyModuleDef *module, PyObject *iterable, PyObject *start); + +static PyObject * +builtin_sum(PyModuleDef *module, PyObject *args) { - PyObject *seq; - PyObject *result = NULL; - PyObject *temp, *item, *iter; + PyObject *return_value = NULL; + PyObject *iterable; + PyObject *start = NULL; + + if (!PyArg_UnpackTuple(args, "sum", + 1, 2, + &iterable, &start)) + goto exit; + return_value = builtin_sum_impl(module, iterable, start); + +exit: + return return_value; +} - if (!PyArg_UnpackTuple(args, "sum", 1, 2, &seq, &result)) - return NULL; +static PyObject * +builtin_sum_impl(PyModuleDef *module, PyObject *iterable, PyObject *start) +/*[clinic end generated code: output=b42652a0d5f64f6b input=90ae7a242cfcf025]*/ +{ + PyObject *result = start; + PyObject *temp, *item, *iter; - iter = PyObject_GetIter(seq); + iter = PyObject_GetIter(iterable); if (iter == NULL) return NULL; @@ -2010,7 +2774,6 @@ builtin_sum(PyObject *self, PyObject *args) Py_DECREF(iter); return NULL; } - Py_INCREF(result); } @@ -2136,62 +2899,126 @@ builtin_sum(PyObject *self, PyObject *args) return result; } -PyDoc_STRVAR(sum_doc, -"sum(iterable[, start]) -> value\n\ -\n\ -Return the sum of an iterable of numbers (NOT strings) plus the value\n\ -of parameter 'start' (which defaults to 0). When the iterable is\n\ -empty, return start."); +/*[clinic input] +isinstance as builtin_isinstance + + obj: 'O' + class_or_tuple: 'O' + / + +Return whether an object is an instance of a class or of a subclass thereof. + +A tuple, as in ``isinstance(x, (A, B, ...))``, may be given as the target to +check against. This is equivalent to ``isinstance(x, A) or isinstance(x, B) +or ...`` etc. +[clinic start generated code]*/ + +PyDoc_STRVAR(builtin_isinstance__doc__, +"isinstance($module, obj, class_or_tuple, /)\n" +"--\n" +"\n" +"Return whether an object is an instance of a class or of a subclass thereof.\n" +"\n" +"A tuple, as in ``isinstance(x, (A, B, ...))``, may be given as the target to\n" +"check against. This is equivalent to ``isinstance(x, A) or isinstance(x, B)\n" +"or ...`` etc."); + +#define BUILTIN_ISINSTANCE_METHODDEF \ + {"isinstance", (PyCFunction)builtin_isinstance, METH_VARARGS, builtin_isinstance__doc__}, + +static PyObject * +builtin_isinstance_impl(PyModuleDef *module, PyObject *obj, PyObject *class_or_tuple); static PyObject * -builtin_isinstance(PyObject *self, PyObject *args) +builtin_isinstance(PyModuleDef *module, PyObject *args) { - PyObject *inst; - PyObject *cls; - int retval; + PyObject *return_value = NULL; + PyObject *obj; + PyObject *class_or_tuple; + + if (!PyArg_UnpackTuple(args, "isinstance", + 2, 2, + &obj, &class_or_tuple)) + goto exit; + return_value = builtin_isinstance_impl(module, obj, class_or_tuple); + +exit: + return return_value; +} - if (!PyArg_UnpackTuple(args, "isinstance", 2, 2, &inst, &cls)) - return NULL; +static PyObject * +builtin_isinstance_impl(PyModuleDef *module, PyObject *obj, PyObject *class_or_tuple) +/*[clinic end generated code: output=847df57fef8ddea7 input=cf9eb0ad6bb9bad6]*/ +{ + int retval; - retval = PyObject_IsInstance(inst, cls); + retval = PyObject_IsInstance(obj, class_or_tuple); if (retval < 0) return NULL; return PyBool_FromLong(retval); } -PyDoc_STRVAR(isinstance_doc, -"isinstance(object, class-or-type-or-tuple) -> bool\n\ -\n\ -Return whether an object is an instance of a class or of a subclass thereof.\n\ -With a type as second argument, return whether that is the object's type.\n\ -The form using a tuple, isinstance(x, (A, B, ...)), is a shortcut for\n\ -isinstance(x, A) or isinstance(x, B) or ... (etc.)."); +/*[clinic input] +issubclass as builtin_issubclass + + cls: 'O' + class_or_tuple: 'O' + / + +Return whether 'cls' is a derived from another class or is the same class. + +A tuple, as in ``issubclass(x, (A, B, ...))``, may be given as the target to +check against. This is equivalent to ``issubclass(x, A) or issubclass(x, B) +or ...`` etc. +[clinic start generated code]*/ + +PyDoc_STRVAR(builtin_issubclass__doc__, +"issubclass($module, cls, class_or_tuple, /)\n" +"--\n" +"\n" +"Return whether \'cls\' is a derived from another class or is the same class.\n" +"\n" +"A tuple, as in ``issubclass(x, (A, B, ...))``, may be given as the target to\n" +"check against. This is equivalent to ``issubclass(x, A) or issubclass(x, B)\n" +"or ...`` etc."); + +#define BUILTIN_ISSUBCLASS_METHODDEF \ + {"issubclass", (PyCFunction)builtin_issubclass, METH_VARARGS, builtin_issubclass__doc__}, static PyObject * -builtin_issubclass(PyObject *self, PyObject *args) +builtin_issubclass_impl(PyModuleDef *module, PyObject *cls, PyObject *class_or_tuple); + +static PyObject * +builtin_issubclass(PyModuleDef *module, PyObject *args) { - PyObject *derived; + PyObject *return_value = NULL; PyObject *cls; - int retval; + PyObject *class_or_tuple; - if (!PyArg_UnpackTuple(args, "issubclass", 2, 2, &derived, &cls)) - return NULL; + if (!PyArg_UnpackTuple(args, "issubclass", + 2, 2, + &cls, &class_or_tuple)) + goto exit; + return_value = builtin_issubclass_impl(module, cls, class_or_tuple); + +exit: + return return_value; +} - retval = PyObject_IsSubclass(derived, cls); +static PyObject * +builtin_issubclass_impl(PyModuleDef *module, PyObject *cls, PyObject *class_or_tuple) +/*[clinic end generated code: output=a0f8c03692e35474 input=923d03fa41fc352a]*/ +{ + int retval; + + retval = PyObject_IsSubclass(cls, class_or_tuple); if (retval < 0) return NULL; return PyBool_FromLong(retval); } -PyDoc_STRVAR(issubclass_doc, -"issubclass(C, B) -> bool\n\ -\n\ -Return whether class C is a subclass (i.e., a derived class) of class B.\n\ -When using a tuple as the second argument issubclass(X, (A, B, ...)),\n\ -is a shortcut for issubclass(X, A) or issubclass(X, B) or ... (etc.)."); - typedef struct { PyObject_HEAD @@ -2386,44 +3213,44 @@ static PyMethodDef builtin_methods[] = { {"__build_class__", (PyCFunction)builtin___build_class__, METH_VARARGS | METH_KEYWORDS, build_class_doc}, {"__import__", (PyCFunction)builtin___import__, METH_VARARGS | METH_KEYWORDS, import_doc}, - {"abs", builtin_abs, METH_O, abs_doc}, - {"all", builtin_all, METH_O, all_doc}, - {"any", builtin_any, METH_O, any_doc}, - {"ascii", builtin_ascii, METH_O, ascii_doc}, - {"bin", builtin_bin, METH_O, bin_doc}, - {"callable", builtin_callable, METH_O, callable_doc}, - {"chr", builtin_chr, METH_VARARGS, chr_doc}, - {"compile", (PyCFunction)builtin_compile, METH_VARARGS | METH_KEYWORDS, compile_doc}, - {"delattr", builtin_delattr, METH_VARARGS, delattr_doc}, + BUILTIN_ABS_METHODDEF + BUILTIN_ALL_METHODDEF + BUILTIN_ANY_METHODDEF + BUILTIN_ASCII_METHODDEF + BUILTIN_BIN_METHODDEF + BUILTIN_CALLABLE_METHODDEF + BUILTIN_CHR_METHODDEF + BUILTIN_COMPILE_METHODDEF + BUILTIN_DELATTR_METHODDEF {"dir", builtin_dir, METH_VARARGS, dir_doc}, - {"divmod", builtin_divmod, METH_VARARGS, divmod_doc}, - {"eval", builtin_eval, METH_VARARGS, eval_doc}, - {"exec", builtin_exec, METH_VARARGS, exec_doc}, - {"format", builtin_format, METH_VARARGS, format_doc}, + BUILTIN_DIVMOD_METHODDEF + BUILTIN_EVAL_METHODDEF + BUILTIN_EXEC_METHODDEF + BUILTIN_FORMAT_METHODDEF {"getattr", builtin_getattr, METH_VARARGS, getattr_doc}, - {"globals", (PyCFunction)builtin_globals, METH_NOARGS, globals_doc}, - {"hasattr", builtin_hasattr, METH_VARARGS, hasattr_doc}, - {"hash", builtin_hash, METH_O, hash_doc}, - {"hex", builtin_hex, METH_O, hex_doc}, - {"id", builtin_id, METH_O, id_doc}, - {"input", builtin_input, METH_VARARGS, input_doc}, - {"isinstance", builtin_isinstance, METH_VARARGS, isinstance_doc}, - {"issubclass", builtin_issubclass, METH_VARARGS, issubclass_doc}, + BUILTIN_GLOBALS_METHODDEF + BUILTIN_HASATTR_METHODDEF + BUILTIN_HASH_METHODDEF + BUILTIN_HEX_METHODDEF + BUILTIN_ID_METHODDEF + BUILTIN_INPUT_METHODDEF + BUILTIN_ISINSTANCE_METHODDEF + BUILTIN_ISSUBCLASS_METHODDEF {"iter", builtin_iter, METH_VARARGS, iter_doc}, - {"len", builtin_len, METH_O, len_doc}, - {"locals", (PyCFunction)builtin_locals, METH_NOARGS, locals_doc}, + BUILTIN_LEN_METHODDEF + BUILTIN_LOCALS_METHODDEF {"max", (PyCFunction)builtin_max, METH_VARARGS | METH_KEYWORDS, max_doc}, {"min", (PyCFunction)builtin_min, METH_VARARGS | METH_KEYWORDS, min_doc}, {"next", (PyCFunction)builtin_next, METH_VARARGS, next_doc}, - {"oct", builtin_oct, METH_O, oct_doc}, - {"ord", builtin_ord, METH_O, ord_doc}, - {"pow", builtin_pow, METH_VARARGS, pow_doc}, + BUILTIN_OCT_METHODDEF + BUILTIN_ORD_METHODDEF + BUILTIN_POW_METHODDEF {"print", (PyCFunction)builtin_print, METH_VARARGS | METH_KEYWORDS, print_doc}, - {"repr", builtin_repr, METH_O, repr_doc}, + BUILTIN_REPR_METHODDEF {"round", (PyCFunction)builtin_round, METH_VARARGS | METH_KEYWORDS, round_doc}, - {"setattr", builtin_setattr, METH_VARARGS, setattr_doc}, - {"sorted", (PyCFunction)builtin_sorted, METH_VARARGS | METH_KEYWORDS, sorted_doc}, - {"sum", builtin_sum, METH_VARARGS, sum_doc}, + BUILTIN_SETATTR_METHODDEF + BUILTIN_SORTED_METHODDEF + BUILTIN_SUM_METHODDEF {"vars", builtin_vars, METH_VARARGS, vars_doc}, {NULL, NULL}, }; diff --git a/Python/ceval.c b/Python/ceval.c index 82f0651e8997..5cefdcf088be 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -65,9 +65,11 @@ ppc_getcounter(uint64 *v) even in 64-bit mode, we need to use "a" and "d" for the lower and upper 32-bit pieces of the result. */ -#define READ_TIMESTAMP(val) \ - __asm__ __volatile__("rdtsc" : \ - "=a" (((int*)&(val))[0]), "=d" (((int*)&(val))[1])); +#define READ_TIMESTAMP(val) do { \ + unsigned int h, l; \ + __asm__ __volatile__("rdtsc" : "=a" (l), "=d" (h)); \ + (val) = ((uint64)l) | (((uint64)h) << 32); \ + } while(0) #else @@ -123,13 +125,16 @@ static PyObject * load_args(PyObject ***, int); static int lltrace; static int prtrace(PyObject *, char *); #endif -static int call_trace(Py_tracefunc, PyObject *, PyFrameObject *, +static int call_trace(Py_tracefunc, PyObject *, + PyThreadState *, PyFrameObject *, int, PyObject *); static int call_trace_protected(Py_tracefunc, PyObject *, - PyFrameObject *, int, PyObject *); -static void call_exc_trace(Py_tracefunc, PyObject *, PyFrameObject *); + PyThreadState *, PyFrameObject *, + int, PyObject *); +static void call_exc_trace(Py_tracefunc, PyObject *, + PyThreadState *, PyFrameObject *); static int maybe_call_line_trace(Py_tracefunc, PyObject *, - PyFrameObject *, int *, int *, int *); + PyThreadState *, PyFrameObject *, int *, int *, int *); static PyObject * cmp_outcome(int, PyObject *, PyObject *); static PyObject * import_from(PyObject *, PyObject *); @@ -1136,7 +1141,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) whenever an exception is detected. */ if (call_trace_protected(tstate->c_tracefunc, tstate->c_traceobj, - f, PyTrace_CALL, Py_None)) { + tstate, f, PyTrace_CALL, Py_None)) { /* Trace function raised an error */ goto exit_eval_frame; } @@ -1146,7 +1151,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) return itself and isn't called for "line" events */ if (call_trace_protected(tstate->c_profilefunc, tstate->c_profileobj, - f, PyTrace_CALL, Py_None)) { + tstate, f, PyTrace_CALL, Py_None)) { /* Profile function raised an error */ goto exit_eval_frame; } @@ -1184,8 +1189,8 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) f->f_stacktop = NULL; /* remains NULL unless yield suspends frame */ f->f_executing = 1; - if (co->co_flags & CO_GENERATOR && !throwflag) { - if (f->f_exc_type != NULL && f->f_exc_type != Py_None) { + if (co->co_flags & CO_GENERATOR) { + if (!throwflag && f->f_exc_type != NULL && f->f_exc_type != Py_None) { /* We were in an except handler when we left, restore the exception state which was put aside (see YIELD_VALUE). */ @@ -1264,6 +1269,13 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) /* Other threads may run now */ take_gil(tstate); + + /* Check if we should make a quick exit. */ + if (_Py_Finalizing && _Py_Finalizing != tstate) { + drop_gil(tstate); + PyThread_exit_thread(); + } + if (PyThreadState_Swap(tstate) != NULL) Py_FatalError("ceval: orphan tstate"); } @@ -1293,8 +1305,8 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) err = maybe_call_line_trace(tstate->c_tracefunc, tstate->c_traceobj, - f, &instr_lb, &instr_ub, - &instr_prev); + tstate, f, + &instr_lb, &instr_ub, &instr_prev); /* Reload possibly changed frame fields */ JUMPTO(f->f_lasti); if (f->f_stacktop != NULL) { @@ -1492,6 +1504,18 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) DISPATCH(); } + TARGET(BINARY_MATRIX_MULTIPLY) { + PyObject *right = POP(); + PyObject *left = TOP(); + PyObject *res = PyNumber_MatrixMultiply(left, right); + Py_DECREF(left); + Py_DECREF(right); + SET_TOP(res); + if (res == NULL) + goto error; + DISPATCH(); + } + TARGET(BINARY_TRUE_DIVIDE) { PyObject *divisor = POP(); PyObject *dividend = TOP(); @@ -1682,6 +1706,18 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) DISPATCH(); } + TARGET(INPLACE_MATRIX_MULTIPLY) { + PyObject *right = POP(); + PyObject *left = TOP(); + PyObject *res = PyNumber_InPlaceMatrixMultiply(left, right); + Py_DECREF(left); + Py_DECREF(right); + SET_TOP(res); + if (res == NULL) + goto error; + DISPATCH(); + } + TARGET(INPLACE_TRUE_DIVIDE) { PyObject *divisor = POP(); PyObject *dividend = TOP(); @@ -1899,14 +1935,14 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) if (v == Py_None) retval = Py_TYPE(reciever)->tp_iternext(reciever); else - retval = _PyObject_CallMethodId(reciever, &PyId_send, "O", v); + retval = _PyObject_CallMethodIdObjArgs(reciever, &PyId_send, v, NULL); } Py_DECREF(v); if (retval == NULL) { PyObject *val; if (tstate->c_tracefunc != NULL && PyErr_ExceptionMatches(PyExc_StopIteration)) - call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, f); + call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, tstate, f); err = _PyGen_FetchStopIterationValue(&val); if (err < 0) goto error; @@ -2658,7 +2694,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) if (!PyErr_ExceptionMatches(PyExc_StopIteration)) goto error; else if (tstate->c_tracefunc != NULL) - call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, f); + call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, tstate, f); PyErr_Clear(); } /* iterator ended normally */ @@ -3054,7 +3090,8 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) PyTraceBack_Here(f); if (tstate->c_tracefunc != NULL) - call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, f); + call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, + tstate, f); fast_block_end: assert(why != WHY_NOT); @@ -3159,7 +3196,8 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) || (retval == NULL && PyErr_Occurred())); fast_yield: - if (co->co_flags & CO_GENERATOR && (why == WHY_YIELD || why == WHY_RETURN)) { + if (co->co_flags & CO_GENERATOR) { + /* The purpose of this block is to put aside the generator's exception state and restore that of the calling frame. If the current exception state is from the caller, we clear the exception values @@ -3182,30 +3220,29 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) if (tstate->use_tracing) { if (tstate->c_tracefunc) { if (why == WHY_RETURN || why == WHY_YIELD) { - if (call_trace(tstate->c_tracefunc, - tstate->c_traceobj, f, + if (call_trace(tstate->c_tracefunc, tstate->c_traceobj, + tstate, f, PyTrace_RETURN, retval)) { - Py_XDECREF(retval); - retval = NULL; + Py_CLEAR(retval); why = WHY_EXCEPTION; } } else if (why == WHY_EXCEPTION) { - call_trace_protected(tstate->c_tracefunc, - tstate->c_traceobj, f, + call_trace_protected(tstate->c_tracefunc, tstate->c_traceobj, + tstate, f, PyTrace_RETURN, NULL); } } if (tstate->c_profilefunc) { if (why == WHY_EXCEPTION) call_trace_protected(tstate->c_profilefunc, - tstate->c_profileobj, f, + tstate->c_profileobj, + tstate, f, PyTrace_RETURN, NULL); - else if (call_trace(tstate->c_profilefunc, - tstate->c_profileobj, f, + else if (call_trace(tstate->c_profilefunc, tstate->c_profileobj, + tstate, f, PyTrace_RETURN, retval)) { - Py_XDECREF(retval); - retval = NULL; + Py_CLEAR(retval); /* why = WHY_EXCEPTION; */ } } @@ -3374,10 +3411,11 @@ too_many_positional(PyCodeObject *co, int given, int defcount, PyObject **fastlo PyEval_EvalFrame() and PyEval_EvalCodeEx() you will need to adjust the test in the if statements in Misc/gdbinit (pystack and pystackv). */ -PyObject * -PyEval_EvalCodeEx(PyObject *_co, PyObject *globals, PyObject *locals, +static PyObject * +_PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals, PyObject **args, int argcount, PyObject **kws, int kwcount, - PyObject **defs, int defcount, PyObject *kwdefs, PyObject *closure) + PyObject **defs, int defcount, PyObject *kwdefs, PyObject *closure, + PyObject *name, PyObject *qualname) { PyCodeObject* co = (PyCodeObject*)_co; PyFrameObject *f; @@ -3563,14 +3601,13 @@ PyEval_EvalCodeEx(PyObject *_co, PyObject *globals, PyObject *locals, if (co->co_flags & CO_GENERATOR) { /* Don't need to keep the reference to f_back, it will be set * when the generator is resumed. */ - Py_XDECREF(f->f_back); - f->f_back = NULL; + Py_CLEAR(f->f_back); PCALL(PCALL_GENERATOR); /* Create a new generator that owns the ready to run frame * and return that as the value. */ - return PyGen_New(f); + return PyGen_NewWithQualName(f, name, qualname); } retval = PyEval_EvalFrameEx(f,0); @@ -3589,6 +3626,16 @@ PyEval_EvalCodeEx(PyObject *_co, PyObject *globals, PyObject *locals, return retval; } +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) +{ + return _PyEval_EvalCodeWithName(_co, globals, locals, + args, argcount, kws, kwcount, + defs, defcount, kwdefs, closure, + NULL, NULL); +} static PyObject * special_lookup(PyObject *o, _Py_Identifier *id) @@ -3846,7 +3893,8 @@ prtrace(PyObject *v, char *str) #endif static void -call_exc_trace(Py_tracefunc func, PyObject *self, PyFrameObject *f) +call_exc_trace(Py_tracefunc func, PyObject *self, + PyThreadState *tstate, PyFrameObject *f) { PyObject *type, *value, *traceback, *orig_traceback, *arg; int err; @@ -3862,7 +3910,7 @@ call_exc_trace(Py_tracefunc func, PyObject *self, PyFrameObject *f) PyErr_Restore(type, value, orig_traceback); return; } - err = call_trace(func, self, f, PyTrace_EXCEPTION, arg); + err = call_trace(func, self, tstate, f, PyTrace_EXCEPTION, arg); Py_DECREF(arg); if (err == 0) PyErr_Restore(type, value, orig_traceback); @@ -3874,13 +3922,14 @@ call_exc_trace(Py_tracefunc func, PyObject *self, PyFrameObject *f) } static int -call_trace_protected(Py_tracefunc func, PyObject *obj, PyFrameObject *frame, +call_trace_protected(Py_tracefunc func, PyObject *obj, + PyThreadState *tstate, PyFrameObject *frame, int what, PyObject *arg) { PyObject *type, *value, *traceback; int err; PyErr_Fetch(&type, &value, &traceback); - err = call_trace(func, obj, frame, what, arg); + err = call_trace(func, obj, tstate, frame, what, arg); if (err == 0) { PyErr_Restore(type, value, traceback); @@ -3895,10 +3944,10 @@ call_trace_protected(Py_tracefunc func, PyObject *obj, PyFrameObject *frame, } static int -call_trace(Py_tracefunc func, PyObject *obj, PyFrameObject *frame, +call_trace(Py_tracefunc func, PyObject *obj, + PyThreadState *tstate, PyFrameObject *frame, int what, PyObject *arg) { - PyThreadState *tstate = frame->f_tstate; int result; if (tstate->tracing) return 0; @@ -3914,8 +3963,7 @@ call_trace(Py_tracefunc func, PyObject *obj, PyFrameObject *frame, PyObject * _PyEval_CallTracing(PyObject *func, PyObject *args) { - PyFrameObject *frame = PyEval_GetFrame(); - PyThreadState *tstate = frame->f_tstate; + PyThreadState *tstate = PyThreadState_GET(); int save_tracing = tstate->tracing; int save_use_tracing = tstate->use_tracing; PyObject *result; @@ -3932,8 +3980,8 @@ _PyEval_CallTracing(PyObject *func, PyObject *args) /* See Objects/lnotab_notes.txt for a description of how tracing works. */ static int maybe_call_line_trace(Py_tracefunc func, PyObject *obj, - PyFrameObject *frame, int *instr_lb, int *instr_ub, - int *instr_prev) + PyThreadState *tstate, PyFrameObject *frame, + int *instr_lb, int *instr_ub, int *instr_prev) { int result = 0; int line = frame->f_lineno; @@ -3953,7 +4001,7 @@ maybe_call_line_trace(Py_tracefunc func, PyObject *obj, number and call the trace function. */ if (frame->f_lasti == *instr_lb || frame->f_lasti < *instr_prev) { frame->f_lineno = line; - result = call_trace(func, obj, frame, PyTrace_LINE, Py_None); + result = call_trace(func, obj, tstate, frame, PyTrace_LINE, Py_None); } *instr_prev = frame->f_lasti; return result; @@ -4149,10 +4197,9 @@ err_args(PyObject *func, int flags, int nargs) #define C_TRACE(x, call) \ if (tstate->use_tracing && tstate->c_profilefunc) { \ - if (call_trace(tstate->c_profilefunc, \ - tstate->c_profileobj, \ - tstate->frame, PyTrace_C_CALL, \ - func)) { \ + if (call_trace(tstate->c_profilefunc, tstate->c_profileobj, \ + tstate, tstate->frame, \ + PyTrace_C_CALL, func)) { \ x = NULL; \ } \ else { \ @@ -4161,14 +4208,14 @@ if (tstate->use_tracing && tstate->c_profilefunc) { \ if (x == NULL) { \ call_trace_protected(tstate->c_profilefunc, \ tstate->c_profileobj, \ - tstate->frame, PyTrace_C_EXCEPTION, \ - func); \ + tstate, tstate->frame, \ + PyTrace_C_EXCEPTION, func); \ /* XXX should pass (type, value, tb) */ \ } else { \ if (call_trace(tstate->c_profilefunc, \ tstate->c_profileobj, \ - tstate->frame, PyTrace_C_RETURN, \ - func)) { \ + tstate, tstate->frame, \ + PyTrace_C_RETURN, func)) { \ Py_DECREF(x); \ x = NULL; \ } \ @@ -4287,6 +4334,8 @@ fast_function(PyObject *func, PyObject ***pp_stack, int n, int na, int nk) PyObject *globals = PyFunction_GET_GLOBALS(func); PyObject *argdefs = PyFunction_GET_DEFAULTS(func); PyObject *kwdefs = PyFunction_GET_KW_DEFAULTS(func); + PyObject *name = ((PyFunctionObject *)func) -> func_name; + PyObject *qualname = ((PyFunctionObject *)func) -> func_qualname; PyObject **d = NULL; int nd = 0; @@ -4329,10 +4378,11 @@ fast_function(PyObject *func, PyObject ***pp_stack, int n, int na, int nk) d = &PyTuple_GET_ITEM(argdefs, 0); nd = Py_SIZE(argdefs); } - return PyEval_EvalCodeEx((PyObject*)co, globals, - (PyObject *)NULL, (*pp_stack)-n, na, - (*pp_stack)-2*nk, nk, d, nd, kwdefs, - PyFunction_GET_CLOSURE(func)); + return _PyEval_EvalCodeWithName((PyObject*)co, globals, + (PyObject *)NULL, (*pp_stack)-n, na, + (*pp_stack)-2*nk, nk, d, nd, kwdefs, + PyFunction_GET_CLOSURE(func), + name, qualname); } static PyObject * @@ -4556,7 +4606,7 @@ ext_do_call(PyObject *func, PyObject ***pp_stack, int flags, int na, int nk) return result; } -/* Extract a slice index from a PyInt or PyLong or an object with the +/* Extract a slice index from a PyLong or an object with the nb_index slot defined, and store in *pi. Silently reduce values larger than PY_SSIZE_T_MAX to PY_SSIZE_T_MAX, and silently boost values less than -PY_SSIZE_T_MAX-1 to -PY_SSIZE_T_MAX-1. @@ -4646,11 +4696,29 @@ static PyObject * import_from(PyObject *v, PyObject *name) { PyObject *x; + _Py_IDENTIFIER(__name__); + PyObject *fullmodname, *pkgname; x = PyObject_GetAttr(v, name); - if (x == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) { + if (x != NULL || !PyErr_ExceptionMatches(PyExc_AttributeError)) + return x; + /* Issue #17636: in case this failed because of a circular relative + import, try to fallback on reading the module directly from + sys.modules. */ + PyErr_Clear(); + pkgname = _PyObject_GetAttrId(v, &PyId___name__); + if (pkgname == NULL) + return NULL; + fullmodname = PyUnicode_FromFormat("%U.%U", pkgname, name); + Py_DECREF(pkgname); + if (fullmodname == NULL) + return NULL; + x = PyDict_GetItem(PyImport_GetModuleDict(), fullmodname); + if (x == NULL) PyErr_Format(PyExc_ImportError, "cannot import name %R", name); - } + else + Py_INCREF(x); + Py_DECREF(fullmodname); return x; } diff --git a/Python/ceval_gil.h b/Python/ceval_gil.h index 2702d5cbddb2..4db56b6f5cb1 100644 --- a/Python/ceval_gil.h +++ b/Python/ceval_gil.h @@ -191,7 +191,7 @@ static void drop_gil(PyThreadState *tstate) if (_Py_atomic_load_relaxed(&gil_drop_request) && tstate != NULL) { MUTEX_LOCK(switch_mutex); /* Not switched yet => wait */ - if (_Py_atomic_load_relaxed(&gil_last_holder) == tstate) { + if ((PyThreadState*)_Py_atomic_load_relaxed(&gil_last_holder) == tstate) { RESET_GIL_DROP_REQUEST(); /* NOTE: if COND_WAIT does not atomically start waiting when releasing the mutex, another thread can run through, take @@ -239,7 +239,7 @@ static void take_gil(PyThreadState *tstate) _Py_atomic_store_relaxed(&gil_locked, 1); _Py_ANNOTATE_RWLOCK_ACQUIRED(&gil_locked, /*is_write=*/1); - if (tstate != _Py_atomic_load_relaxed(&gil_last_holder)) { + if (tstate != (PyThreadState*)_Py_atomic_load_relaxed(&gil_last_holder)) { _Py_atomic_store_relaxed(&gil_last_holder, tstate); ++gil_switch_number; } diff --git a/Python/clinic/import.c.h b/Python/clinic/import.c.h new file mode 100644 index 000000000000..7618577e6546 --- /dev/null +++ b/Python/clinic/import.c.h @@ -0,0 +1,323 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_imp_lock_held__doc__, +"lock_held($module, /)\n" +"--\n" +"\n" +"Return True if the import lock is currently held, else False.\n" +"\n" +"On platforms without threads, return False."); + +#define _IMP_LOCK_HELD_METHODDEF \ + {"lock_held", (PyCFunction)_imp_lock_held, METH_NOARGS, _imp_lock_held__doc__}, + +static PyObject * +_imp_lock_held_impl(PyModuleDef *module); + +static PyObject * +_imp_lock_held(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return _imp_lock_held_impl(module); +} + +PyDoc_STRVAR(_imp_acquire_lock__doc__, +"acquire_lock($module, /)\n" +"--\n" +"\n" +"Acquires the interpreter\'s import lock for the current thread.\n" +"\n" +"This lock should be used by import hooks to ensure thread-safety when importing\n" +"modules. On platforms without threads, this function does nothing."); + +#define _IMP_ACQUIRE_LOCK_METHODDEF \ + {"acquire_lock", (PyCFunction)_imp_acquire_lock, METH_NOARGS, _imp_acquire_lock__doc__}, + +static PyObject * +_imp_acquire_lock_impl(PyModuleDef *module); + +static PyObject * +_imp_acquire_lock(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return _imp_acquire_lock_impl(module); +} + +PyDoc_STRVAR(_imp_release_lock__doc__, +"release_lock($module, /)\n" +"--\n" +"\n" +"Release the interpreter\'s import lock.\n" +"\n" +"On platforms without threads, this function does nothing."); + +#define _IMP_RELEASE_LOCK_METHODDEF \ + {"release_lock", (PyCFunction)_imp_release_lock, METH_NOARGS, _imp_release_lock__doc__}, + +static PyObject * +_imp_release_lock_impl(PyModuleDef *module); + +static PyObject * +_imp_release_lock(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return _imp_release_lock_impl(module); +} + +PyDoc_STRVAR(_imp__fix_co_filename__doc__, +"_fix_co_filename($module, code, path, /)\n" +"--\n" +"\n" +"Changes code.co_filename to specify the passed-in file path.\n" +"\n" +" code\n" +" Code object to change.\n" +" path\n" +" File path to use."); + +#define _IMP__FIX_CO_FILENAME_METHODDEF \ + {"_fix_co_filename", (PyCFunction)_imp__fix_co_filename, METH_VARARGS, _imp__fix_co_filename__doc__}, + +static PyObject * +_imp__fix_co_filename_impl(PyModuleDef *module, PyCodeObject *code, PyObject *path); + +static PyObject * +_imp__fix_co_filename(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyCodeObject *code; + PyObject *path; + + if (!PyArg_ParseTuple(args, + "O!U:_fix_co_filename", + &PyCode_Type, &code, &path)) + goto exit; + return_value = _imp__fix_co_filename_impl(module, code, path); + +exit: + return return_value; +} + +PyDoc_STRVAR(_imp_extension_suffixes__doc__, +"extension_suffixes($module, /)\n" +"--\n" +"\n" +"Returns the list of file suffixes used to identify extension modules."); + +#define _IMP_EXTENSION_SUFFIXES_METHODDEF \ + {"extension_suffixes", (PyCFunction)_imp_extension_suffixes, METH_NOARGS, _imp_extension_suffixes__doc__}, + +static PyObject * +_imp_extension_suffixes_impl(PyModuleDef *module); + +static PyObject * +_imp_extension_suffixes(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return _imp_extension_suffixes_impl(module); +} + +PyDoc_STRVAR(_imp_init_builtin__doc__, +"init_builtin($module, name, /)\n" +"--\n" +"\n" +"Initializes a built-in module."); + +#define _IMP_INIT_BUILTIN_METHODDEF \ + {"init_builtin", (PyCFunction)_imp_init_builtin, METH_VARARGS, _imp_init_builtin__doc__}, + +static PyObject * +_imp_init_builtin_impl(PyModuleDef *module, PyObject *name); + +static PyObject * +_imp_init_builtin(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *name; + + if (!PyArg_ParseTuple(args, + "U:init_builtin", + &name)) + goto exit; + return_value = _imp_init_builtin_impl(module, name); + +exit: + return return_value; +} + +PyDoc_STRVAR(_imp_init_frozen__doc__, +"init_frozen($module, name, /)\n" +"--\n" +"\n" +"Initializes a frozen module."); + +#define _IMP_INIT_FROZEN_METHODDEF \ + {"init_frozen", (PyCFunction)_imp_init_frozen, METH_VARARGS, _imp_init_frozen__doc__}, + +static PyObject * +_imp_init_frozen_impl(PyModuleDef *module, PyObject *name); + +static PyObject * +_imp_init_frozen(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *name; + + if (!PyArg_ParseTuple(args, + "U:init_frozen", + &name)) + goto exit; + return_value = _imp_init_frozen_impl(module, name); + +exit: + return return_value; +} + +PyDoc_STRVAR(_imp_get_frozen_object__doc__, +"get_frozen_object($module, name, /)\n" +"--\n" +"\n" +"Create a code object for a frozen module."); + +#define _IMP_GET_FROZEN_OBJECT_METHODDEF \ + {"get_frozen_object", (PyCFunction)_imp_get_frozen_object, METH_VARARGS, _imp_get_frozen_object__doc__}, + +static PyObject * +_imp_get_frozen_object_impl(PyModuleDef *module, PyObject *name); + +static PyObject * +_imp_get_frozen_object(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *name; + + if (!PyArg_ParseTuple(args, + "U:get_frozen_object", + &name)) + goto exit; + return_value = _imp_get_frozen_object_impl(module, name); + +exit: + return return_value; +} + +PyDoc_STRVAR(_imp_is_frozen_package__doc__, +"is_frozen_package($module, name, /)\n" +"--\n" +"\n" +"Returns True if the module name is of a frozen package."); + +#define _IMP_IS_FROZEN_PACKAGE_METHODDEF \ + {"is_frozen_package", (PyCFunction)_imp_is_frozen_package, METH_VARARGS, _imp_is_frozen_package__doc__}, + +static PyObject * +_imp_is_frozen_package_impl(PyModuleDef *module, PyObject *name); + +static PyObject * +_imp_is_frozen_package(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *name; + + if (!PyArg_ParseTuple(args, + "U:is_frozen_package", + &name)) + goto exit; + return_value = _imp_is_frozen_package_impl(module, name); + +exit: + return return_value; +} + +PyDoc_STRVAR(_imp_is_builtin__doc__, +"is_builtin($module, name, /)\n" +"--\n" +"\n" +"Returns True if the module name corresponds to a built-in module."); + +#define _IMP_IS_BUILTIN_METHODDEF \ + {"is_builtin", (PyCFunction)_imp_is_builtin, METH_VARARGS, _imp_is_builtin__doc__}, + +static PyObject * +_imp_is_builtin_impl(PyModuleDef *module, PyObject *name); + +static PyObject * +_imp_is_builtin(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *name; + + if (!PyArg_ParseTuple(args, + "U:is_builtin", + &name)) + goto exit; + return_value = _imp_is_builtin_impl(module, name); + +exit: + return return_value; +} + +PyDoc_STRVAR(_imp_is_frozen__doc__, +"is_frozen($module, name, /)\n" +"--\n" +"\n" +"Returns True if the module name corresponds to a frozen module."); + +#define _IMP_IS_FROZEN_METHODDEF \ + {"is_frozen", (PyCFunction)_imp_is_frozen, METH_VARARGS, _imp_is_frozen__doc__}, + +static PyObject * +_imp_is_frozen_impl(PyModuleDef *module, PyObject *name); + +static PyObject * +_imp_is_frozen(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *name; + + if (!PyArg_ParseTuple(args, + "U:is_frozen", + &name)) + goto exit; + return_value = _imp_is_frozen_impl(module, name); + +exit: + return return_value; +} + +#if defined(HAVE_DYNAMIC_LOADING) + +PyDoc_STRVAR(_imp_load_dynamic__doc__, +"load_dynamic($module, name, path, file=None, /)\n" +"--\n" +"\n" +"Loads an extension module."); + +#define _IMP_LOAD_DYNAMIC_METHODDEF \ + {"load_dynamic", (PyCFunction)_imp_load_dynamic, METH_VARARGS, _imp_load_dynamic__doc__}, + +static PyObject * +_imp_load_dynamic_impl(PyModuleDef *module, PyObject *name, PyObject *path, PyObject *file); + +static PyObject * +_imp_load_dynamic(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *name; + PyObject *path; + PyObject *file = NULL; + + if (!PyArg_ParseTuple(args, + "UO&|O:load_dynamic", + &name, PyUnicode_FSDecoder, &path, &file)) + goto exit; + return_value = _imp_load_dynamic_impl(module, name, path, file); + +exit: + return return_value; +} + +#endif /* defined(HAVE_DYNAMIC_LOADING) */ + +#ifndef _IMP_LOAD_DYNAMIC_METHODDEF + #define _IMP_LOAD_DYNAMIC_METHODDEF +#endif /* !defined(_IMP_LOAD_DYNAMIC_METHODDEF) */ +/*[clinic end generated code: output=087a1f22e9febcc7 input=a9049054013a1b77]*/ diff --git a/Python/codecs.c b/Python/codecs.c index 5ff41b57df29..64fc3d633166 100644 --- a/Python/codecs.c +++ b/Python/codecs.c @@ -9,6 +9,7 @@ Copyright (c) Corporation for National Research Initiatives. ------------------------------------------------------------------------ */ #include "Python.h" +#include "ucnhash.h" #include const char *Py_hexdigits = "0123456789abcdef"; @@ -185,6 +186,32 @@ PyObject *_PyCodec_Lookup(const char *encoding) return NULL; } +int _PyCodec_Forget(const char *encoding) +{ + PyInterpreterState *interp; + PyObject *v; + int result; + + interp = PyThreadState_GET()->interp; + if (interp->codec_search_path == NULL) { + return -1; + } + + /* Convert the encoding to a normalized Python string: all + characters are converted to lower case, spaces and hyphens are + replaced with underscores. */ + v = normalizestring(encoding); + if (v == NULL) { + return -1; + } + + /* Drop the named codec from the internal cache */ + result = PyDict_DelItem(interp->codec_search_cache, v); + Py_DECREF(v); + + return result; +} + /* Codec registry encoding check API. */ int PyCodec_KnownEncoding(const char *encoding) @@ -243,20 +270,15 @@ PyObject *codec_getitem(const char *encoding, int index) return v; } -/* Helper function to create an incremental codec. */ - +/* Helper functions to create an incremental codec. */ static -PyObject *codec_getincrementalcodec(const char *encoding, - const char *errors, - const char *attrname) +PyObject *codec_makeincrementalcodec(PyObject *codec_info, + const char *errors, + const char *attrname) { - PyObject *codecs, *ret, *inccodec; + PyObject *ret, *inccodec; - codecs = _PyCodec_Lookup(encoding); - if (codecs == NULL) - return NULL; - inccodec = PyObject_GetAttrString(codecs, attrname); - Py_DECREF(codecs); + inccodec = PyObject_GetAttrString(codec_info, attrname); if (inccodec == NULL) return NULL; if (errors) @@ -267,6 +289,21 @@ PyObject *codec_getincrementalcodec(const char *encoding, return ret; } +static +PyObject *codec_getincrementalcodec(const char *encoding, + const char *errors, + const char *attrname) +{ + PyObject *codec_info, *ret; + + codec_info = _PyCodec_Lookup(encoding); + if (codec_info == NULL) + return NULL; + ret = codec_makeincrementalcodec(codec_info, errors, attrname); + Py_DECREF(codec_info); + return ret; +} + /* Helper function to create a stream codec. */ static @@ -290,6 +327,24 @@ PyObject *codec_getstreamcodec(const char *encoding, return streamcodec; } +/* Helpers to work with the result of _PyCodec_Lookup + + */ +PyObject *_PyCodecInfo_GetIncrementalDecoder(PyObject *codec_info, + const char *errors) +{ + return codec_makeincrementalcodec(codec_info, errors, + "incrementaldecoder"); +} + +PyObject *_PyCodecInfo_GetIncrementalEncoder(PyObject *codec_info, + const char *errors) +{ + return codec_makeincrementalcodec(codec_info, errors, + "incrementalencoder"); +} + + /* Convenience APIs to query the Codec registry. All APIs return a codec object with incremented refcount. @@ -467,15 +522,12 @@ PyObject *PyCodec_Decode(PyObject *object, } /* Text encoding/decoding API */ -static -PyObject *codec_getitem_checked(const char *encoding, - const char *operation_name, - int index) +PyObject * _PyCodec_LookupTextEncoding(const char *encoding, + const char *alternate_command) { _Py_IDENTIFIER(_is_text_encoding); PyObject *codec; PyObject *attr; - PyObject *v; int is_text_codec; codec = _PyCodec_Lookup(encoding); @@ -502,27 +554,44 @@ PyObject *codec_getitem_checked(const char *encoding, Py_DECREF(codec); PyErr_Format(PyExc_LookupError, "'%.400s' is not a text encoding; " - "use codecs.%s() to handle arbitrary codecs", - encoding, operation_name); + "use %s to handle arbitrary codecs", + encoding, alternate_command); return NULL; } } } + /* This appears to be a valid text encoding */ + return codec; +} + + +static +PyObject *codec_getitem_checked(const char *encoding, + const char *alternate_command, + int index) +{ + PyObject *codec; + PyObject *v; + + codec = _PyCodec_LookupTextEncoding(encoding, alternate_command); + if (codec == NULL) + return NULL; + v = PyTuple_GET_ITEM(codec, index); - Py_DECREF(codec); Py_INCREF(v); + Py_DECREF(codec); return v; } static PyObject * _PyCodec_TextEncoder(const char *encoding) { - return codec_getitem_checked(encoding, "encode", 0); + return codec_getitem_checked(encoding, "codecs.encode()", 0); } static PyObject * _PyCodec_TextDecoder(const char *encoding) { - return codec_getitem_checked(encoding, "decode", 1); + return codec_getitem_checked(encoding, "codecs.decode()", 1); } PyObject *_PyCodec_EncodeText(PyObject *object, @@ -705,7 +774,7 @@ PyObject *PyCodec_XMLCharRefReplaceErrors(PyObject *exc) Py_ssize_t end; PyObject *res; unsigned char *outp; - int ressize; + Py_ssize_t ressize; Py_UCS4 ch; if (PyUnicodeEncodeError_GetStart(exc, &start)) return NULL; @@ -713,6 +782,8 @@ PyObject *PyCodec_XMLCharRefReplaceErrors(PyObject *exc) return NULL; if (!(object = PyUnicodeEncodeError_GetObject(exc))) return NULL; + if (end - start > PY_SSIZE_T_MAX / (2+7+1)) + end = start + PY_SSIZE_T_MAX / (2+7+1); for (i = start, ressize = 0; i < end; ++i) { /* object is guaranteed to be "ready" */ ch = PyUnicode_READ_CHAR(object, i); @@ -792,6 +863,119 @@ PyObject *PyCodec_XMLCharRefReplaceErrors(PyObject *exc) } PyObject *PyCodec_BackslashReplaceErrors(PyObject *exc) +{ + PyObject *object; + Py_ssize_t i; + Py_ssize_t start; + Py_ssize_t end; + PyObject *res; + unsigned char *outp; + int ressize; + Py_UCS4 c; + + if (PyObject_IsInstance(exc, PyExc_UnicodeDecodeError)) { + unsigned char *p; + if (PyUnicodeDecodeError_GetStart(exc, &start)) + return NULL; + if (PyUnicodeDecodeError_GetEnd(exc, &end)) + return NULL; + if (!(object = PyUnicodeDecodeError_GetObject(exc))) + return NULL; + if (!(p = (unsigned char*)PyBytes_AsString(object))) { + Py_DECREF(object); + return NULL; + } + res = PyUnicode_New(4 * (end - start), 127); + if (res == NULL) { + Py_DECREF(object); + return NULL; + } + outp = PyUnicode_1BYTE_DATA(res); + for (i = start; i < end; i++, outp += 4) { + unsigned char c = p[i]; + outp[0] = '\\'; + outp[1] = 'x'; + outp[2] = Py_hexdigits[(c>>4)&0xf]; + outp[3] = Py_hexdigits[c&0xf]; + } + + assert(_PyUnicode_CheckConsistency(res, 1)); + Py_DECREF(object); + return Py_BuildValue("(Nn)", res, end); + } + if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) { + if (PyUnicodeEncodeError_GetStart(exc, &start)) + return NULL; + if (PyUnicodeEncodeError_GetEnd(exc, &end)) + return NULL; + if (!(object = PyUnicodeEncodeError_GetObject(exc))) + return NULL; + } + else if (PyObject_IsInstance(exc, PyExc_UnicodeTranslateError)) { + if (PyUnicodeTranslateError_GetStart(exc, &start)) + return NULL; + if (PyUnicodeTranslateError_GetEnd(exc, &end)) + return NULL; + if (!(object = PyUnicodeTranslateError_GetObject(exc))) + return NULL; + } + else { + wrong_exception_type(exc); + return NULL; + } + + if (end - start > PY_SSIZE_T_MAX / (1+1+8)) + end = start + PY_SSIZE_T_MAX / (1+1+8); + for (i = start, ressize = 0; i < end; ++i) { + /* object is guaranteed to be "ready" */ + c = PyUnicode_READ_CHAR(object, i); + if (c >= 0x10000) { + ressize += 1+1+8; + } + else if (c >= 0x100) { + ressize += 1+1+4; + } + else + ressize += 1+1+2; + } + res = PyUnicode_New(ressize, 127); + if (res == NULL) { + Py_DECREF(object); + return NULL; + } + outp = PyUnicode_1BYTE_DATA(res); + for (i = start; i < end; ++i) { + c = PyUnicode_READ_CHAR(object, i); + *outp++ = '\\'; + if (c >= 0x00010000) { + *outp++ = 'U'; + *outp++ = Py_hexdigits[(c>>28)&0xf]; + *outp++ = Py_hexdigits[(c>>24)&0xf]; + *outp++ = Py_hexdigits[(c>>20)&0xf]; + *outp++ = Py_hexdigits[(c>>16)&0xf]; + *outp++ = Py_hexdigits[(c>>12)&0xf]; + *outp++ = Py_hexdigits[(c>>8)&0xf]; + } + else if (c >= 0x100) { + *outp++ = 'u'; + *outp++ = Py_hexdigits[(c>>12)&0xf]; + *outp++ = Py_hexdigits[(c>>8)&0xf]; + } + else + *outp++ = 'x'; + *outp++ = Py_hexdigits[(c>>4)&0xf]; + *outp++ = Py_hexdigits[c&0xf]; + } + + assert(_PyUnicode_CheckConsistency(res, 1)); + Py_DECREF(object); + return Py_BuildValue("(Nn)", res, end); +} + +static _PyUnicode_Name_CAPI *ucnhash_CAPI = NULL; +static int ucnhash_initialized = 0; + +PyObject *PyCodec_NameReplaceErrors(PyObject *exc) { if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) { PyObject *restuple; @@ -801,26 +985,42 @@ PyObject *PyCodec_BackslashReplaceErrors(PyObject *exc) Py_ssize_t end; PyObject *res; unsigned char *outp; - int ressize; + Py_ssize_t ressize; + int replsize; Py_UCS4 c; + char buffer[256]; /* NAME_MAXLEN */ if (PyUnicodeEncodeError_GetStart(exc, &start)) return NULL; if (PyUnicodeEncodeError_GetEnd(exc, &end)) return NULL; if (!(object = PyUnicodeEncodeError_GetObject(exc))) return NULL; + if (!ucnhash_initialized) { + /* load the unicode data module */ + ucnhash_CAPI = (_PyUnicode_Name_CAPI *)PyCapsule_Import( + PyUnicodeData_CAPSULE_NAME, 1); + ucnhash_initialized = 1; + } for (i = start, ressize = 0; i < end; ++i) { /* object is guaranteed to be "ready" */ c = PyUnicode_READ_CHAR(object, i); - if (c >= 0x10000) { - ressize += 1+1+8; + if (ucnhash_CAPI && + ucnhash_CAPI->getname(NULL, c, buffer, sizeof(buffer), 1)) { + replsize = 1+1+1+(int)strlen(buffer)+1; + } + else if (c >= 0x10000) { + replsize = 1+1+8; } else if (c >= 0x100) { - ressize += 1+1+4; + replsize = 1+1+4; } else - ressize += 1+1+2; + replsize = 1+1+2; + if (ressize > PY_SSIZE_T_MAX - replsize) + break; + ressize += replsize; } + end = i; res = PyUnicode_New(ressize, 127); if (res==NULL) return NULL; @@ -828,6 +1028,15 @@ PyObject *PyCodec_BackslashReplaceErrors(PyObject *exc) i < end; ++i) { c = PyUnicode_READ_CHAR(object, i); *outp++ = '\\'; + if (ucnhash_CAPI && + ucnhash_CAPI->getname(NULL, c, buffer, sizeof(buffer), 1)) { + *outp++ = 'N'; + *outp++ = '{'; + strcpy((char *)outp, buffer); + outp += strlen(buffer); + *outp++ = '}'; + continue; + } if (c >= 0x00010000) { *outp++ = 'U'; *outp++ = Py_hexdigits[(c>>28)&0xf]; @@ -848,6 +1057,7 @@ PyObject *PyCodec_BackslashReplaceErrors(PyObject *exc) *outp++ = Py_hexdigits[c&0xf]; } + assert(outp == PyUnicode_1BYTE_DATA(res) + ressize); assert(_PyUnicode_CheckConsistency(res, 1)); restuple = Py_BuildValue("(Nn)", res, end); Py_DECREF(object); @@ -859,6 +1069,7 @@ PyObject *PyCodec_BackslashReplaceErrors(PyObject *exc) } } +#define ENC_UNKNOWN -1 #define ENC_UTF8 0 #define ENC_UTF16BE 1 #define ENC_UTF16LE 2 @@ -874,7 +1085,11 @@ get_standard_encoding(const char *encoding, int *bytelength) encoding += 3; if (*encoding == '-' || *encoding == '_' ) encoding++; - if (encoding[0] == '1' && encoding[1] == '6') { + if (encoding[0] == '8' && encoding[1] == '\0') { + *bytelength = 3; + return ENC_UTF8; + } + else if (encoding[0] == '1' && encoding[1] == '6') { encoding += 2; *bytelength = 2; if (*encoding == '\0') { @@ -913,9 +1128,11 @@ get_standard_encoding(const char *encoding, int *bytelength) } } } - /* utf-8 */ - *bytelength = 3; - return ENC_UTF8; + else if (strcmp(encoding, "CP_UTF8") == 0) { + *bytelength = 3; + return ENC_UTF8; + } + return ENC_UNKNOWN; } /* This handler is declared static until someone demonstrates @@ -952,7 +1169,15 @@ PyCodec_SurrogatePassErrors(PyObject *exc) } code = get_standard_encoding(encoding, &bytelength); Py_DECREF(encode); + if (code == ENC_UNKNOWN) { + /* Not supported, fail with original exception */ + PyErr_SetObject(PyExceptionInstance_Class(exc), exc); + Py_DECREF(object); + return NULL; + } + if (end - start > PY_SSIZE_T_MAX / bytelength) + end = start + PY_SSIZE_T_MAX / bytelength; res = PyBytes_FromStringAndSize(NULL, bytelength*(end-start)); if (!res) { Py_DECREF(object); @@ -1026,6 +1251,12 @@ PyCodec_SurrogatePassErrors(PyObject *exc) } code = get_standard_encoding(encoding, &bytelength); Py_DECREF(encode); + if (code == ENC_UNKNOWN) { + /* Not supported, fail with original exception */ + PyErr_SetObject(PyExceptionInstance_Class(exc), exc); + Py_DECREF(object); + return NULL; + } /* Try decoding a single surrogate character. If there are more, let the codec call us again. */ @@ -1181,6 +1412,11 @@ static PyObject *backslashreplace_errors(PyObject *self, PyObject *exc) return PyCodec_BackslashReplaceErrors(exc); } +static PyObject *namereplace_errors(PyObject *self, PyObject *exc) +{ + return PyCodec_NameReplaceErrors(exc); +} + static PyObject *surrogatepass_errors(PyObject *self, PyObject *exc) { return PyCodec_SurrogatePassErrors(exc); @@ -1246,8 +1482,19 @@ static int _PyCodecRegistry_Init(void) backslashreplace_errors, METH_O, PyDoc_STR("Implements the 'backslashreplace' error handling, " + "which replaces malformed data with a backslashed " + "escape sequence.") + } + }, + { + "namereplace", + { + "namereplace_errors", + namereplace_errors, + METH_O, + PyDoc_STR("Implements the 'namereplace' error handling, " "which replaces an unencodable character with a " - "backslashed escape sequence.") + "\\N{...} escape sequence.") } }, { diff --git a/Python/compile.c b/Python/compile.c index 0fc91864fff0..97fe5c2a3da6 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -30,8 +30,6 @@ #include "symtable.h" #include "opcode.h" -int Py_OptimizeFlag = 0; - #define DEFAULT_BLOCK_SIZE 16 #define DEFAULT_BLOCKS 8 #define DEFAULT_CODE_SIZE 128 @@ -881,6 +879,7 @@ PyCompile_OpcodeStackEffect(int opcode, int oparg) case BINARY_POWER: case BINARY_MULTIPLY: + case BINARY_MATRIX_MULTIPLY: case BINARY_MODULO: case BINARY_ADD: case BINARY_SUBTRACT: @@ -895,6 +894,7 @@ PyCompile_OpcodeStackEffect(int opcode, int oparg) case INPLACE_ADD: case INPLACE_SUBTRACT: case INPLACE_MULTIPLY: + case INPLACE_MATRIX_MULTIPLY: case INPLACE_MODULO: return -1; case STORE_SUBSCR: @@ -1412,12 +1412,12 @@ get_ref_type(struct compiler *c, PyObject *name) PyOS_snprintf(buf, sizeof(buf), "unknown scope for %.100s in %.100s(%s)\n" "symbols: %s\nlocals: %s\nglobals: %s", - PyBytes_AS_STRING(name), - PyBytes_AS_STRING(c->u->u_name), - PyObject_REPR(c->u->u_ste->ste_id), - PyObject_REPR(c->u->u_ste->ste_symbols), - PyObject_REPR(c->u->u_varnames), - PyObject_REPR(c->u->u_names) + PyUnicode_AsUTF8(name), + PyUnicode_AsUTF8(c->u->u_name), + PyUnicode_AsUTF8(PyObject_Repr(c->u->u_ste->ste_id)), + PyUnicode_AsUTF8(PyObject_Repr(c->u->u_ste->ste_symbols)), + PyUnicode_AsUTF8(PyObject_Repr(c->u->u_varnames)), + PyUnicode_AsUTF8(PyObject_Repr(c->u->u_names)) ); Py_FatalError(buf); } @@ -1474,11 +1474,11 @@ compiler_make_closure(struct compiler *c, PyCodeObject *co, Py_ssize_t args, PyO fprintf(stderr, "lookup %s in %s %d %d\n" "freevars of %s: %s\n", - PyObject_REPR(name), - PyBytes_AS_STRING(c->u->u_name), + PyUnicode_AsUTF8(PyObject_Repr(name)), + PyUnicode_AsUTF8(c->u->u_name), reftype, arg, - _PyUnicode_AsString(co->co_name), - PyObject_REPR(co->co_freevars)); + PyUnicode_AsUTF8(co->co_name), + PyUnicode_AsUTF8(PyObject_Repr(co->co_freevars))); Py_FatalError("compiler_make_closure()"); } ADDOP_I(c, LOAD_CLOSURE, arg); @@ -1532,9 +1532,16 @@ compiler_visit_argannotation(struct compiler *c, identifier id, expr_ty annotation, PyObject *names) { if (annotation) { + PyObject *mangled; VISIT(c, expr, annotation); - if (PyList_Append(names, id)) + mangled = _Py_Mangle(c->u->u_private, id); + if (!mangled) + return -1; + if (PyList_Append(names, mangled) < 0) { + Py_DECREF(mangled); return -1; + } + Py_DECREF(mangled); } return 0; } @@ -1931,7 +1938,7 @@ compiler_if(struct compiler *c, stmt_ty s) } else if (constant == 1) { VISIT_SEQ(c, stmt, s->v.If.body); } else { - if (s->v.If.orelse) { + if (asdl_seq_LEN(s->v.If.orelse)) { next = compiler_new_block(c); if (next == NULL) return 0; @@ -1941,8 +1948,8 @@ compiler_if(struct compiler *c, stmt_ty s) VISIT(c, expr, s->v.If.test); ADDOP_JABS(c, POP_JUMP_IF_FALSE, next); VISIT_SEQ(c, stmt, s->v.If.body); - ADDOP_JREL(c, JUMP_FORWARD, end); - if (s->v.If.orelse) { + if (asdl_seq_LEN(s->v.If.orelse)) { + ADDOP_JREL(c, JUMP_FORWARD, end); compiler_use_next_block(c, next); VISIT_SEQ(c, stmt, s->v.If.orelse); } @@ -2022,10 +2029,9 @@ compiler_while(struct compiler *c, stmt_ty s) if there is no else clause ? */ - if (constant == -1) { + if (constant == -1) compiler_use_next_block(c, anchor); - ADDOP(c, POP_BLOCK); - } + ADDOP(c, POP_BLOCK); compiler_pop_fblock(c, LOOP, loop); if (orelse != NULL) /* what if orelse is just pass? */ VISIT_SEQ(c, stmt, s->v.While.orelse); @@ -2618,6 +2624,8 @@ binop(struct compiler *c, operator_ty op) return BINARY_SUBTRACT; case Mult: return BINARY_MULTIPLY; + case MatMult: + return BINARY_MATRIX_MULTIPLY; case Div: return BINARY_TRUE_DIVIDE; case Mod: @@ -2682,6 +2690,8 @@ inplace_binop(struct compiler *c, operator_ty op) return INPLACE_SUBTRACT; case Mult: return INPLACE_MULTIPLY; + case MatMult: + return INPLACE_MATRIX_MULTIPLY; case Div: return INPLACE_TRUE_DIVIDE; case Mod: @@ -3849,12 +3859,16 @@ stackdepth_walk(struct compiler *c, basicblock *b, int depth, int maxdepth) target_depth = depth; if (instr->i_opcode == FOR_ITER) { target_depth = depth-2; - } else if (instr->i_opcode == SETUP_FINALLY || - instr->i_opcode == SETUP_EXCEPT) { + } + else if (instr->i_opcode == SETUP_FINALLY || + instr->i_opcode == SETUP_EXCEPT) { target_depth = depth+3; if (target_depth > maxdepth) maxdepth = target_depth; } + else if (instr->i_opcode == JUMP_IF_TRUE_OR_POP || + instr->i_opcode == JUMP_IF_FALSE_OR_POP) + depth = depth - 1; maxdepth = stackdepth_walk(c, instr->i_target, target_depth, maxdepth); if (instr->i_opcode == JUMP_ABSOLUTE || @@ -3899,7 +3913,7 @@ assemble_init(struct assembler *a, int nblocks, int firstlineno) a->a_lnotab = PyBytes_FromStringAndSize(NULL, DEFAULT_LNOTAB_SIZE); if (!a->a_lnotab) return 0; - if (nblocks > PY_SIZE_MAX / sizeof(basicblock *)) { + if ((size_t)nblocks > PY_SIZE_MAX / sizeof(basicblock *)) { PyErr_NoMemory(); return 0; } diff --git a/Python/condvar.h b/Python/condvar.h index e022dc793883..ef818c4d4b5c 100644 --- a/Python/condvar.h +++ b/Python/condvar.h @@ -60,7 +60,7 @@ #include #define PyCOND_ADD_MICROSECONDS(tv, interval) \ -do { \ +do { /* TODO: add overflow and truncation checks */ \ tv.tv_usec += (long) interval; \ tv.tv_sec += tv.tv_usec / 1000000; \ tv.tv_usec %= 1000000; \ @@ -89,7 +89,7 @@ do { \ /* return 0 for success, 1 on timeout, -1 on error */ Py_LOCAL_INLINE(int) -PyCOND_TIMEDWAIT(PyCOND_T *cond, PyMUTEX_T *mut, long us) +PyCOND_TIMEDWAIT(PyCOND_T *cond, PyMUTEX_T *mut, PY_LONG_LONG us) { int r; struct timespec ts; @@ -270,9 +270,9 @@ PyCOND_WAIT(PyCOND_T *cv, PyMUTEX_T *cs) } Py_LOCAL_INLINE(int) -PyCOND_TIMEDWAIT(PyCOND_T *cv, PyMUTEX_T *cs, long us) +PyCOND_TIMEDWAIT(PyCOND_T *cv, PyMUTEX_T *cs, PY_LONG_LONG us) { - return _PyCOND_WAIT_MS(cv, cs, us/1000); + return _PyCOND_WAIT_MS(cv, cs, (DWORD)(us/1000)); } Py_LOCAL_INLINE(int) @@ -363,9 +363,9 @@ PyCOND_WAIT(PyCOND_T *cv, PyMUTEX_T *cs) * 2 to indicate that we don't know. */ Py_LOCAL_INLINE(int) -PyCOND_TIMEDWAIT(PyCOND_T *cv, PyMUTEX_T *cs, long us) +PyCOND_TIMEDWAIT(PyCOND_T *cv, PyMUTEX_T *cs, PY_LONG_LONG us) { - return SleepConditionVariableSRW(cv, cs, us/1000, 0) ? 2 : -1; + return SleepConditionVariableSRW(cv, cs, (DWORD)(us/1000), 0) ? 2 : -1; } Py_LOCAL_INLINE(int) diff --git a/Python/dynload_shlib.c b/Python/dynload_shlib.c index 888fbfcc68c6..659adace095a 100644 --- a/Python/dynload_shlib.c +++ b/Python/dynload_shlib.c @@ -36,25 +36,16 @@ const char *_PyImport_DynLoadFiletab[] = { #ifdef __CYGWIN__ ".dll", #else /* !__CYGWIN__ */ -#ifdef __VMS - ".exe", - ".EXE", -#else /* !__VMS */ "." SOABI ".so", ".abi" PYTHON_ABI_STRING ".so", ".so", -#endif /* __VMS */ #endif /* __CYGWIN__ */ NULL, }; static struct { dev_t dev; -#ifdef __VMS - ino_t ino[3]; -#else ino_t ino; -#endif void *handle; } handles[128]; static int nhandles = 0; @@ -80,8 +71,8 @@ dl_funcptr _PyImport_GetDynLoadFunc(const char *shortname, if (fp != NULL) { int i; - struct stat statb; - if (fstat(fileno(fp), &statb) == -1) { + struct _Py_stat_struct statb; + if (_Py_fstat(fileno(fp), &statb) == -1) { PyErr_SetFromErrno(PyExc_IOError); return NULL; } @@ -95,29 +86,12 @@ dl_funcptr _PyImport_GetDynLoadFunc(const char *shortname, } if (nhandles < 128) { handles[nhandles].dev = statb.st_dev; -#ifdef __VMS - handles[nhandles].ino[0] = statb.st_ino[0]; - handles[nhandles].ino[1] = statb.st_ino[1]; - handles[nhandles].ino[2] = statb.st_ino[2]; -#else handles[nhandles].ino = statb.st_ino; -#endif } } dlopenflags = PyThreadState_GET()->interp->dlopenflags; -#ifdef __VMS - /* VMS currently don't allow a pathname, use a logical name instead */ - /* Concatenate 'python_module_' and shortname */ - /* so "import vms.bar" will use the logical python_module_bar */ - /* As C module use only one name space this is probably not a */ - /* important limitation */ - PyOS_snprintf(pathbuf, sizeof(pathbuf), "python_module_%-.200s", - shortname); - pathname = pathbuf; -#endif - handle = dlopen(pathname, dlopenflags); if (handle == NULL) { diff --git a/Python/dynload_win.c b/Python/dynload_win.c index ffcf0ee1d739..9ed9eea33373 100644 --- a/Python/dynload_win.c +++ b/Python/dynload_win.c @@ -9,6 +9,7 @@ #include #include "importdl.h" +#include "patchlevel.h" #include // "activation context" magic - see dl_nt.c... @@ -17,16 +18,28 @@ extern ULONG_PTR _Py_ActivateActCtx(); void _Py_DeactivateActCtx(ULONG_PTR cookie); #endif -const char *_PyImport_DynLoadFiletab[] = { #ifdef _DEBUG - "_d.pyd", +#define PYD_DEBUG_SUFFIX "_d" +#else +#define PYD_DEBUG_SUFFIX "" +#endif + +#define STRINGIZE2(x) #x +#define STRINGIZE(x) STRINGIZE2(x) +#ifdef PYD_PLATFORM_TAG +#define PYD_TAGGED_SUFFIX PYD_DEBUG_SUFFIX ".cp" STRINGIZE(PY_MAJOR_VERSION) STRINGIZE(PY_MINOR_VERSION) "-" PYD_PLATFORM_TAG ".pyd" #else - ".pyd", +#define PYD_TAGGED_SUFFIX PYD_DEBUG_SUFFIX ".cp" STRINGIZE(PY_MAJOR_VERSION) STRINGIZE(PY_MINOR_VERSION) ".pyd" #endif + +#define PYD_UNTAGGED_SUFFIX PYD_DEBUG_SUFFIX ".pyd" + +const char *_PyImport_DynLoadFiletab[] = { + PYD_TAGGED_SUFFIX, + PYD_UNTAGGED_SUFFIX, NULL }; - /* Case insensitive string compare, to avoid any dependencies on particular C RTL implementations */ diff --git a/Python/errors.c b/Python/errors.c index 90dc729fd1d1..940aef33a200 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -384,6 +384,30 @@ PyErr_SetExcInfo(PyObject *p_type, PyObject *p_value, PyObject *p_traceback) Py_XDECREF(oldtraceback); } +/* Like PyErr_Restore(), but if an exception is already set, + set the context associated with it. + */ +void +_PyErr_ChainExceptions(PyObject *exc, PyObject *val, PyObject *tb) +{ + if (exc == NULL) + return; + + if (PyErr_Occurred()) { + PyObject *exc2, *val2, *tb2; + PyErr_Fetch(&exc2, &val2, &tb2); + PyErr_NormalizeException(&exc, &val, &tb); + Py_DECREF(exc); + Py_XDECREF(tb); + PyErr_NormalizeException(&exc2, &val2, &tb2); + PyException_SetContext(val2, val); + PyErr_Restore(exc2, val2, tb2); + } + else { + PyErr_Restore(exc, val, tb); + } +} + /* Convenience functions to set a type error exception and return 0 */ int @@ -409,6 +433,12 @@ PyErr_NoMemory(void) PyObject * PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject) +{ + return PyErr_SetFromErrnoWithFilenameObjects(exc, filenameObject, NULL); +} + +PyObject * +PyErr_SetFromErrnoWithFilenameObjects(PyObject *exc, PyObject *filenameObject, PyObject *filenameObject2) { PyObject *message; PyObject *v, *args; @@ -480,10 +510,15 @@ PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject) return NULL; } - if (filenameObject != NULL) - args = Py_BuildValue("(iOO)", i, message, filenameObject); - else + if (filenameObject != NULL) { + if (filenameObject2 != NULL) + args = Py_BuildValue("(iOOiO)", i, message, filenameObject, 0, filenameObject2); + else + args = Py_BuildValue("(iOO)", i, message, filenameObject); + } else { + assert(filenameObject2 == NULL); args = Py_BuildValue("(iO)", i, message); + } Py_DECREF(message); if (args != NULL) { @@ -500,12 +535,11 @@ PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject) return NULL; } - PyObject * PyErr_SetFromErrnoWithFilename(PyObject *exc, const char *filename) { PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL; - PyObject *result = PyErr_SetFromErrnoWithFilenameObject(exc, name); + PyObject *result = PyErr_SetFromErrnoWithFilenameObjects(exc, name, NULL); Py_XDECREF(name); return result; } @@ -517,7 +551,7 @@ PyErr_SetFromErrnoWithUnicodeFilename(PyObject *exc, const Py_UNICODE *filename) PyObject *name = filename ? PyUnicode_FromUnicode(filename, wcslen(filename)) : NULL; - PyObject *result = PyErr_SetFromErrnoWithFilenameObject(exc, name); + PyObject *result = PyErr_SetFromErrnoWithFilenameObjects(exc, name, NULL); Py_XDECREF(name); return result; } @@ -526,7 +560,7 @@ PyErr_SetFromErrnoWithUnicodeFilename(PyObject *exc, const Py_UNICODE *filename) PyObject * PyErr_SetFromErrno(PyObject *exc) { - return PyErr_SetFromErrnoWithFilenameObject(exc, NULL); + return PyErr_SetFromErrnoWithFilenameObjects(exc, NULL, NULL); } #ifdef MS_WINDOWS @@ -535,6 +569,16 @@ PyObject *PyErr_SetExcFromWindowsErrWithFilenameObject( PyObject *exc, int ierr, PyObject *filenameObject) +{ + return PyErr_SetExcFromWindowsErrWithFilenameObjects(exc, ierr, + filenameObject, NULL); +} + +PyObject *PyErr_SetExcFromWindowsErrWithFilenameObjects( + PyObject *exc, + int ierr, + PyObject *filenameObject, + PyObject *filenameObject2) { int len; WCHAR *s_buf = NULL; /* Free via LocalFree */ @@ -571,11 +615,15 @@ PyObject *PyErr_SetExcFromWindowsErrWithFilenameObject( return NULL; } - if (filenameObject == NULL) - filenameObject = Py_None; - /* This is the constructor signature for passing a Windows error code. + if (filenameObject == NULL) { + assert(filenameObject2 == NULL); + filenameObject = filenameObject2 = Py_None; + } + else if (filenameObject2 == NULL) + filenameObject2 = Py_None; + /* This is the constructor signature for OSError. The POSIX translation will be figured out by the constructor. */ - args = Py_BuildValue("(iOOi)", 0, message, filenameObject, err); + args = Py_BuildValue("(iOOiO)", 0, message, filenameObject, err, filenameObject2); Py_DECREF(message); if (args != NULL) { @@ -596,9 +644,10 @@ PyObject *PyErr_SetExcFromWindowsErrWithFilename( const char *filename) { PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL; - PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObject(exc, + PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObjects(exc, ierr, - name); + name, + NULL); Py_XDECREF(name); return ret; } @@ -611,9 +660,10 @@ PyObject *PyErr_SetExcFromWindowsErrWithUnicodeFilename( PyObject *name = filename ? PyUnicode_FromUnicode(filename, wcslen(filename)) : NULL; - PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObject(exc, + PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObjects(exc, ierr, - name); + name, + NULL); Py_XDECREF(name); return ret; } @@ -628,14 +678,15 @@ PyObject *PyErr_SetFromWindowsErr(int ierr) return PyErr_SetExcFromWindowsErrWithFilename(PyExc_OSError, ierr, NULL); } + PyObject *PyErr_SetFromWindowsErrWithFilename( int ierr, const char *filename) { PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL; - PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObject( + PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObjects( PyExc_OSError, - ierr, name); + ierr, name, NULL); Py_XDECREF(name); return result; } @@ -647,9 +698,9 @@ PyObject *PyErr_SetFromWindowsErrWithUnicodeFilename( PyObject *name = filename ? PyUnicode_FromUnicode(filename, wcslen(filename)) : NULL; - PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObject( + PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObjects( PyExc_OSError, - ierr, name); + ierr, name, NULL); Py_XDECREF(name); return result; } @@ -722,19 +773,11 @@ PyErr_BadInternalCall(void) #define PyErr_BadInternalCall() _PyErr_BadInternalCall(__FILE__, __LINE__) - PyObject * -PyErr_Format(PyObject *exception, const char *format, ...) +PyErr_FormatV(PyObject *exception, const char *format, va_list vargs) { - va_list vargs; PyObject* string; -#ifdef HAVE_STDARG_PROTOTYPES - va_start(vargs, format); -#else - va_start(vargs); -#endif - #ifdef Py_DEBUG /* in debug mode, PyEval_EvalFrameEx() fails with an assertion error if an exception is set when it is called */ @@ -744,11 +787,24 @@ PyErr_Format(PyObject *exception, const char *format, ...) string = PyUnicode_FromFormatV(format, vargs); PyErr_SetObject(exception, string); Py_XDECREF(string); - va_end(vargs); return NULL; } +PyObject * +PyErr_Format(PyObject *exception, const char *format, ...) +{ + va_list vargs; +#ifdef HAVE_STDARG_PROTOTYPES + va_start(vargs, format); +#else + va_start(vargs); +#endif + PyErr_FormatV(exception, format, vargs); + va_end(vargs); + return NULL; +} + PyObject * PyErr_NewException(const char *name, PyObject *base, PyObject *dict) diff --git a/Python/fileutils.c b/Python/fileutils.c index 814f0765a3db..e7111c143111 100644 --- a/Python/fileutils.c +++ b/Python/fileutils.c @@ -1,11 +1,12 @@ #include "Python.h" #include "osdefs.h" +#include + #ifdef MS_WINDOWS # include #endif #ifdef HAVE_LANGINFO_H -#include #include #endif @@ -81,11 +82,11 @@ extern int _Py_normalize_encoding(const char *, char *, size_t); Values of force_ascii: - 1: the workaround is used: _Py_wchar2char() uses - encode_ascii_surrogateescape() and _Py_char2wchar() uses + 1: the workaround is used: Py_EncodeLocale() uses + encode_ascii_surrogateescape() and Py_DecodeLocale() uses decode_ascii_surrogateescape() - 0: the workaround is not used: _Py_wchar2char() uses wcstombs() and - _Py_char2wchar() uses mbstowcs() + 0: the workaround is not used: Py_EncodeLocale() uses wcstombs() and + Py_DecodeLocale() uses mbstowcs() -1: unknown, need to call check_force_ascii() to get the value */ static int force_ascii = -1; @@ -219,8 +220,11 @@ decode_ascii_surrogateescape(const char *arg, size_t *size) wchar_t *res; unsigned char *in; wchar_t *out; + size_t argsize = strlen(arg) + 1; - res = PyMem_RawMalloc((strlen(arg)+1)*sizeof(wchar_t)); + if (argsize > PY_SSIZE_T_MAX/sizeof(wchar_t)) + return NULL; + res = PyMem_RawMalloc(argsize*sizeof(wchar_t)); if (!res) return NULL; @@ -240,24 +244,26 @@ decode_ascii_surrogateescape(const char *arg, size_t *size) /* Decode a byte string from the locale encoding with the - surrogateescape error handler (undecodable bytes are decoded as characters - in range U+DC80..U+DCFF). If a byte sequence can be decoded as a surrogate + surrogateescape error handler: undecodable bytes are decoded as characters + in range U+DC80..U+DCFF. If a byte sequence can be decoded as a surrogate character, escape the bytes using the surrogateescape error handler instead of decoding them. - Use _Py_wchar2char() to encode the character string back to a byte string. + Return a pointer to a newly allocated wide character string, use + PyMem_RawFree() to free the memory. If size is not NULL, write the number of + wide characters excluding the null character into *size - Return a pointer to a newly allocated wide character string (use - PyMem_RawFree() to free the memory) and write the number of written wide - characters excluding the null character into *size if size is not NULL, or - NULL on error (decoding or memory allocation error). If size is not NULL, - *size is set to (size_t)-1 on memory error and (size_t)-2 on decoding - error. + Return NULL on decoding error or memory allocation error. If *size* is not + NULL, *size is set to (size_t)-1 on memory error or set to (size_t)-2 on + decoding error. - Conversion errors should never happen, unless there is a bug in the C - library. */ + Decoding errors should never happen, unless there is a bug in the C + library. + + Use the Py_EncodeLocale() function to encode the character string back to a + byte string. */ wchar_t* -_Py_char2wchar(const char* arg, size_t *size) +Py_DecodeLocale(const char* arg, size_t *size) { #ifdef __APPLE__ wchar_t *wstr; @@ -302,10 +308,15 @@ _Py_char2wchar(const char* arg, size_t *size) argsize = mbstowcs(NULL, arg, 0); #endif if (argsize != (size_t)-1) { - res = (wchar_t *)PyMem_RawMalloc((argsize+1)*sizeof(wchar_t)); + if (argsize == PY_SSIZE_T_MAX) + goto oom; + argsize += 1; + if (argsize > PY_SSIZE_T_MAX/sizeof(wchar_t)) + goto oom; + res = (wchar_t *)PyMem_RawMalloc(argsize*sizeof(wchar_t)); if (!res) goto oom; - count = mbstowcs(res, arg, argsize+1); + count = mbstowcs(res, arg, argsize); if (count != (size_t)-1) { wchar_t *tmp; /* Only use the result if it contains no @@ -328,6 +339,8 @@ _Py_char2wchar(const char* arg, size_t *size) /* Overallocate; as multi-byte characters are in the argument, the actual output could use less memory. */ argsize = strlen(arg) + 1; + if (argsize > PY_SSIZE_T_MAX/sizeof(wchar_t)) + goto oom; res = (wchar_t*)PyMem_RawMalloc(argsize*sizeof(wchar_t)); if (!res) goto oom; @@ -388,19 +401,20 @@ _Py_char2wchar(const char* arg, size_t *size) #endif /* __APPLE__ */ } -/* Encode a (wide) character string to the locale encoding with the - surrogateescape error handler (characters in range U+DC80..U+DCFF are - converted to bytes 0x80..0xFF). +/* Encode a wide character string to the locale encoding with the + surrogateescape error handler: surrogate characters in the range + U+DC80..U+DCFF are converted to bytes 0x80..0xFF. - This function is the reverse of _Py_char2wchar(). + Return a pointer to a newly allocated byte string, use PyMem_Free() to free + the memory. Return NULL on encoding or memory allocation error. - Return a pointer to a newly allocated byte string (use PyMem_Free() to free - the memory), or NULL on encoding or memory allocation error. + If error_pos is not NULL, *error_pos is set to the index of the invalid + character on encoding error, or set to (size_t)-1 otherwise. - If error_pos is not NULL: *error_pos is the index of the invalid character - on encoding error, or (size_t)-1 otherwise. */ + Use the Py_DecodeLocale() function to decode the bytes string back to a wide + character string. */ char* -_Py_wchar2char(const wchar_t *text, size_t *error_pos) +Py_EncodeLocale(const wchar_t *text, size_t *error_pos) { #ifdef __APPLE__ Py_ssize_t len; @@ -519,7 +533,7 @@ _Py_wstat(const wchar_t* path, struct stat *buf) { int err; char *fname; - fname = _Py_wchar2char(path, NULL); + fname = Py_EncodeLocale(path, NULL); if (fname == NULL) { errno = EINVAL; return -1; @@ -530,8 +544,143 @@ _Py_wstat(const wchar_t* path, struct stat *buf) } #endif -#ifdef HAVE_STAT +#if defined(HAVE_FSTAT) || defined(MS_WINDOWS) + +#ifdef MS_WINDOWS +static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */ + +static void +FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out) +{ + /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */ + /* Cannot simply cast and dereference in_ptr, + since it might not be aligned properly */ + __int64 in; + memcpy(&in, in_ptr, sizeof(in)); + *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */ + *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t); +} + +void +_Py_time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr) +{ + /* XXX endianness */ + __int64 out; + out = time_in + secs_between_epochs; + out = out * 10000000 + nsec_in / 100; + memcpy(out_ptr, &out, sizeof(out)); +} + +/* Below, we *know* that ugo+r is 0444 */ +#if _S_IREAD != 0400 +#error Unsupported C library +#endif +static int +attributes_to_mode(DWORD attr) +{ + int m = 0; + if (attr & FILE_ATTRIBUTE_DIRECTORY) + m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */ + else + m |= _S_IFREG; + if (attr & FILE_ATTRIBUTE_READONLY) + m |= 0444; + else + m |= 0666; + return m; +} + +void +_Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct _Py_stat_struct *result) +{ + memset(result, 0, sizeof(*result)); + result->st_mode = attributes_to_mode(info->dwFileAttributes); + result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow; + result->st_dev = info->dwVolumeSerialNumber; + result->st_rdev = result->st_dev; + FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec); + FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec); + FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec); + result->st_nlink = info->nNumberOfLinks; + result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow; + if (reparse_tag == IO_REPARSE_TAG_SYMLINK) { + /* first clear the S_IFMT bits */ + result->st_mode ^= (result->st_mode & S_IFMT); + /* now set the bits that make this a symlink */ + result->st_mode |= S_IFLNK; + } + result->st_file_attributes = info->dwFileAttributes; +} +#endif + +/* Return information about a file. + + On POSIX, use fstat(). + + On Windows, use GetFileType() and GetFileInformationByHandle() which support + files larger than 2 GB. fstat() may fail with EOVERFLOW on files larger + than 2 GB because the file size type is an signed 32-bit integer: see issue + #23152. + */ +int +_Py_fstat(int fd, struct _Py_stat_struct *result) +{ +#ifdef MS_WINDOWS + BY_HANDLE_FILE_INFORMATION info; + HANDLE h; + int type; + + if (!_PyVerify_fd(fd)) + h = INVALID_HANDLE_VALUE; + else + h = (HANDLE)_get_osfhandle(fd); + + /* Protocol violation: we explicitly clear errno, instead of + setting it to a POSIX error. Callers should use GetLastError. */ + errno = 0; + + if (h == INVALID_HANDLE_VALUE) { + /* This is really a C library error (invalid file handle). + We set the Win32 error to the closes one matching. */ + SetLastError(ERROR_INVALID_HANDLE); + return -1; + } + memset(result, 0, sizeof(*result)); + + type = GetFileType(h); + if (type == FILE_TYPE_UNKNOWN) { + DWORD error = GetLastError(); + if (error != 0) { + return -1; + } + /* else: valid but unknown file */ + } + + if (type != FILE_TYPE_DISK) { + if (type == FILE_TYPE_CHAR) + result->st_mode = _S_IFCHR; + else if (type == FILE_TYPE_PIPE) + result->st_mode = _S_IFIFO; + return 0; + } + + if (!GetFileInformationByHandle(h, &info)) { + return -1; + } + + _Py_attribute_data_to_stat(&info, 0, result); + /* specific to fstat() */ + result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow; + return 0; +#else + return fstat(fd, result); +#endif +} +#endif /* HAVE_FSTAT || MS_WINDOWS */ + + +#ifdef HAVE_STAT /* Call _wstat() on Windows, or encode the path to the filesystem encoding and call stat() otherwise. Only fill st_mode attribute on Windows. @@ -564,7 +713,8 @@ _Py_stat(PyObject *path, struct stat *statbuf) #endif } -#endif +#endif /* HAVE_STAT */ + static int get_inheritable(int fd, int raise) @@ -621,10 +771,12 @@ set_inheritable(int fd, int inheritable, int raise, int *atomic_flag_works) #ifdef MS_WINDOWS HANDLE handle; DWORD flags; -#elif defined(HAVE_SYS_IOCTL_H) && defined(FIOCLEX) && defined(FIONCLEX) +#else +#if defined(HAVE_SYS_IOCTL_H) && defined(FIOCLEX) && defined(FIONCLEX) + static int ioctl_works = -1; int request; int err; -#elif defined(HAVE_FCNTL_H) +#endif int flags; int res; #endif @@ -670,20 +822,38 @@ set_inheritable(int fd, int inheritable, int raise, int *atomic_flag_works) } return 0; -#elif defined(HAVE_SYS_IOCTL_H) && defined(FIOCLEX) && defined(FIONCLEX) - if (inheritable) - request = FIONCLEX; - else - request = FIOCLEX; - err = ioctl(fd, request, NULL); - if (err) { - if (raise) - PyErr_SetFromErrno(PyExc_OSError); - return -1; +#else + +#if defined(HAVE_SYS_IOCTL_H) && defined(FIOCLEX) && defined(FIONCLEX) + if (ioctl_works != 0) { + /* fast-path: ioctl() only requires one syscall */ + if (inheritable) + request = FIONCLEX; + else + request = FIOCLEX; + err = ioctl(fd, request, NULL); + if (!err) { + ioctl_works = 1; + return 0; + } + + if (errno != ENOTTY) { + if (raise) + PyErr_SetFromErrno(PyExc_OSError); + return -1; + } + else { + /* Issue #22258: Here, ENOTTY means "Inappropriate ioctl for + device". The ioctl is declared but not supported by the kernel. + Remember that ioctl() doesn't work. It is the case on + Illumos-based OS for example. */ + ioctl_works = 0; + } + /* fallback to fcntl() if ioctl() does not work */ } - return 0; +#endif -#else + /* slow-path: fcntl() requires two syscalls */ flags = fcntl(fd, F_GETFD); if (flags < 0) { if (raise) @@ -783,7 +953,7 @@ _Py_wfopen(const wchar_t *path, const wchar_t *mode) errno = EINVAL; return NULL; } - cpath = _Py_wchar2char(path, NULL); + cpath = Py_EncodeLocale(path, NULL); if (cpath == NULL) return NULL; f = fopen(cpath, cmode); @@ -874,7 +1044,7 @@ _Py_wreadlink(const wchar_t *path, wchar_t *buf, size_t bufsiz) int res; size_t r1; - cpath = _Py_wchar2char(path, NULL); + cpath = Py_EncodeLocale(path, NULL); if (cpath == NULL) { errno = EINVAL; return -1; @@ -888,7 +1058,7 @@ _Py_wreadlink(const wchar_t *path, wchar_t *buf, size_t bufsiz) return -1; } cbuf[res] = '\0'; /* buf will be null terminated */ - wbuf = _Py_char2wchar(cbuf, &r1); + wbuf = Py_DecodeLocale(cbuf, &r1); if (wbuf == NULL) { errno = EINVAL; return -1; @@ -919,7 +1089,7 @@ _Py_wrealpath(const wchar_t *path, wchar_t *wresolved_path; char *res; size_t r; - cpath = _Py_wchar2char(path, NULL); + cpath = Py_EncodeLocale(path, NULL); if (cpath == NULL) { errno = EINVAL; return NULL; @@ -929,7 +1099,7 @@ _Py_wrealpath(const wchar_t *path, if (res == NULL) return NULL; - wresolved_path = _Py_char2wchar(cresolved_path, &r); + wresolved_path = Py_DecodeLocale(cresolved_path, &r); if (wresolved_path == NULL) { errno = EINVAL; return NULL; @@ -962,7 +1132,7 @@ _Py_wgetcwd(wchar_t *buf, size_t size) if (getcwd(fname, Py_ARRAY_LENGTH(fname)) == NULL) return NULL; - wname = _Py_char2wchar(fname, &len); + wname = Py_DecodeLocale(fname, &len); if (wname == NULL) return NULL; if (size <= len) { @@ -1044,3 +1214,56 @@ _Py_dup(int fd) return fd; } +#ifndef MS_WINDOWS +/* Get the blocking mode of the file descriptor. + Return 0 if the O_NONBLOCK flag is set, 1 if the flag is cleared, + raise an exception and return -1 on error. */ +int +_Py_get_blocking(int fd) +{ + int flags = fcntl(fd, F_GETFL, 0); + if (flags < 0) { + PyErr_SetFromErrno(PyExc_OSError); + return -1; + } + + return !(flags & O_NONBLOCK); +} + +/* Set the blocking mode of the specified file descriptor. + + Set the O_NONBLOCK flag if blocking is False, clear the O_NONBLOCK flag + otherwise. + + Return 0 on success, raise an exception and return -1 on error. */ +int +_Py_set_blocking(int fd, int blocking) +{ +#if defined(HAVE_SYS_IOCTL_H) && defined(FIONBIO) + int arg = !blocking; + if (ioctl(fd, FIONBIO, &arg) < 0) + goto error; +#else + int flags, res; + + flags = fcntl(fd, F_GETFL, 0); + if (flags < 0) + goto error; + + if (blocking) + flags = flags & (~O_NONBLOCK); + else + flags = flags | O_NONBLOCK; + + res = fcntl(fd, F_SETFL, flags); + if (res < 0) + goto error; +#endif + return 0; + +error: + PyErr_SetFromErrno(PyExc_OSError); + return -1; +} +#endif + diff --git a/Python/formatter_unicode.c b/Python/formatter_unicode.c index 0a3cc593d646..056bb7690259 100644 --- a/Python/formatter_unicode.c +++ b/Python/formatter_unicode.c @@ -156,8 +156,9 @@ parse_internal_render_format_spec(PyObject *format_spec, Py_ssize_t consumed; int align_specified = 0; + int fill_char_specified = 0; - format->fill_char = '\0'; + format->fill_char = ' '; format->align = default_align; format->alternate = 0; format->sign = '\0'; @@ -171,6 +172,7 @@ parse_internal_render_format_spec(PyObject *format_spec, if (end-pos >= 2 && is_alignment_token(READ_spec(pos+1))) { format->align = READ_spec(pos+1); format->fill_char = READ_spec(pos); + fill_char_specified = 1; align_specified = 1; pos += 2; } @@ -194,7 +196,7 @@ parse_internal_render_format_spec(PyObject *format_spec, } /* The special case for 0-padding (backwards compat) */ - if (format->fill_char == '\0' && end-pos >= 1 && READ_spec(pos) == '0') { + if (!fill_char_specified && end-pos >= 1 && READ_spec(pos) == '0') { format->fill_char = '0'; if (!align_specified) { format->align = '='; @@ -784,9 +786,7 @@ format_string_internal(PyObject *value, const InternalFormatSpec *format, goto done; /* Write into that space. First the padding. */ - result = fill_padding(writer, len, - format->fill_char=='\0'?' ':format->fill_char, - lpad, rpad); + result = fill_padding(writer, len, format->fill_char, lpad, rpad); if (result == -1) goto done; @@ -846,6 +846,13 @@ format_long_internal(PyObject *value, const InternalFormatSpec *format, " format specifier 'c'"); goto done; } + /* error to request alternate format */ + if (format->alternate) { + PyErr_SetString(PyExc_ValueError, + "Alternate form (#) not allowed with integer" + " format specifier 'c'"); + goto done; + } /* taken from unicodeobject.c formatchar() */ /* Integer input truncated to a character */ @@ -956,8 +963,7 @@ format_long_internal(PyObject *value, const InternalFormatSpec *format, /* Populate the memory. */ result = fill_number(writer, &spec, tmp, inumeric_chars, inumeric_chars + n_digits, - tmp, prefix, - format->fill_char == '\0' ? ' ' : format->fill_char, + tmp, prefix, format->fill_char, &locale, format->type == 'X'); done: @@ -1104,8 +1110,7 @@ format_float_internal(PyObject *value, /* Populate the memory. */ result = fill_number(writer, &spec, unicode_tmp, index, index + n_digits, - NULL, 0, - format->fill_char == '\0' ? ' ' : format->fill_char, + NULL, 0, format->fill_char, &locale, 0); done: @@ -1311,8 +1316,7 @@ format_complex_internal(PyObject *value, /* Populate the memory. First, the padding. */ result = fill_padding(writer, n_re_total + n_im_total + 1 + add_parens * 2, - format->fill_char=='\0' ? ' ' : format->fill_char, - lpad, rpad); + format->fill_char, lpad, rpad); if (result == -1) goto done; diff --git a/Python/frozenmain.c b/Python/frozenmain.c index 55d05fc26f02..de8bd35453a9 100644 --- a/Python/frozenmain.c +++ b/Python/frozenmain.c @@ -24,11 +24,13 @@ Py_FrozenMain(int argc, char **argv) /* We need a second copies, as Python might modify the first one. */ wchar_t **argv_copy2 = NULL; - argv_copy = PyMem_RawMalloc(sizeof(wchar_t*) * argc); - argv_copy2 = PyMem_RawMalloc(sizeof(wchar_t*) * argc); - if (!argv_copy || !argv_copy2) { - fprintf(stderr, "out of memory\n"); - goto error; + if (argc > 0) { + argv_copy = PyMem_RawMalloc(sizeof(wchar_t*) * argc); + argv_copy2 = PyMem_RawMalloc(sizeof(wchar_t*) * argc); + if (!argv_copy || !argv_copy2) { + fprintf(stderr, "out of memory\n"); + goto error; + } } Py_FrozenFlag = 1; /* Suppress errors from getpath.c */ @@ -52,7 +54,7 @@ Py_FrozenMain(int argc, char **argv) setlocale(LC_ALL, ""); for (i = 0; i < argc; i++) { - argv_copy[i] = _Py_char2wchar(argv[i], NULL); + argv_copy[i] = Py_DecodeLocale(argv[i], NULL); argv_copy2[i] = argv_copy[i]; if (!argv_copy[i]) { fprintf(stderr, "Unable to decode the command line argument #%i\n", @@ -68,7 +70,8 @@ Py_FrozenMain(int argc, char **argv) #ifdef MS_WINDOWS PyInitFrozenExtensions(); #endif /* MS_WINDOWS */ - Py_SetProgramName(argv_copy[0]); + if (argc >= 1) + Py_SetProgramName(argv_copy[0]); Py_Initialize(); #ifdef MS_WINDOWS PyWinFreeze_ExeInit(); diff --git a/Python/getargs.c b/Python/getargs.c index 60845680fc2a..f0f8e39bb478 100644 --- a/Python/getargs.c +++ b/Python/getargs.c @@ -200,8 +200,6 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags) { char msgbuf[256]; int levels[32]; - freelistentry_t static_entries[STATIC_FREELIST_ENTRIES]; - freelist_t freelist = {static_entries, 0, 0}; const char *fname = NULL; const char *message = NULL; int min = -1; @@ -212,6 +210,12 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags) Py_ssize_t i, len; char *msg; int compat = flags & FLAG_COMPAT; + freelistentry_t static_entries[STATIC_FREELIST_ENTRIES]; + freelist_t freelist; + + freelist.entries = static_entries; + freelist.first_available = 0; + freelist.entries_malloced = 0; assert(compat || (args != (PyObject*)NULL)); flags = flags & ~FLAG_COMPAT; @@ -845,7 +849,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, /* XXX WAAAAH! 's', 'y', 'z', 'u', 'Z', 'e', 'w' codes all need to be cleaned up! */ - case 'y': {/* any buffer-like object, but not PyUnicode */ + case 'y': {/* any bytes-like object */ void **p = (void **)va_arg(*p_va, char **); char *buf; Py_ssize_t count; @@ -868,16 +872,16 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, STORE_SIZE(count); format++; } else { - if (strlen(*p) != count) - return converterr( - "bytes without null bytes", - arg, msgbuf, bufsize); + if (strlen(*p) != (size_t)count) { + PyErr_SetString(PyExc_ValueError, "embedded null byte"); + RETURN_ERR_OCCURRED; + } } break; } - case 's': /* text string */ - case 'z': /* text string or None */ + case 's': /* text string or bytes-like object */ + case 'z': /* text string, bytes-like object or None */ { if (*format == '*') { /* "s*" or "z*" */ @@ -893,7 +897,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, arg, msgbuf, bufsize); PyBuffer_FillInfo(p, arg, sarg, len, 1, 0); } - else { /* any buffer-like object */ + else { /* any bytes-like object */ char *buf; if (getbuffer(arg, p, &buf) < 0) return converterr(buf, arg, msgbuf, bufsize); @@ -904,7 +908,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, arg, msgbuf, bufsize); } format++; - } else if (*format == '#') { /* any buffer-like object */ + } else if (*format == '#') { /* a string or read-only bytes-like object */ /* "s#" or "z#" */ void **p = (void **)va_arg(*p_va, char **); FETCH_SIZE; @@ -922,7 +926,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, *p = sarg; STORE_SIZE(len); } - else { /* any buffer-like object */ + else { /* read-only bytes-like object */ /* XXX Really? */ char *buf; Py_ssize_t count = convertbuffer(arg, p, &buf); @@ -944,16 +948,15 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, if (sarg == NULL) return converterr(CONV_UNICODE, arg, msgbuf, bufsize); + if (strlen(sarg) != (size_t)len) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + RETURN_ERR_OCCURRED; + } *p = sarg; } else return converterr(c == 'z' ? "str or None" : "str", arg, msgbuf, bufsize); - if (*p != NULL && sarg != NULL && (Py_ssize_t) strlen(*p) != len) - return converterr( - c == 'z' ? "str without null characters or None" - : "str without null characters", - arg, msgbuf, bufsize); } break; } @@ -963,7 +966,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, { Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **); - if (*format == '#') { /* any buffer-like object */ + if (*format == '#') { /* "s#" or "Z#" */ FETCH_SIZE; @@ -990,10 +993,10 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, *p = PyUnicode_AsUnicodeAndSize(arg, &len); if (*p == NULL) RETURN_ERR_OCCURRED; - if (Py_UNICODE_strlen(*p) != len) - return converterr( - "str without null characters or None", - arg, msgbuf, bufsize); + if (Py_UNICODE_strlen(*p) != (size_t)len) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + RETURN_ERR_OCCURRED; + } } else return converterr(c == 'Z' ? "str or None" : "str", arg, msgbuf, bufsize); @@ -1241,7 +1244,8 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, supports it directly. */ if (PyObject_GetBuffer(arg, (Py_buffer*)p, PyBUF_WRITABLE) < 0) { PyErr_Clear(); - return converterr("read-write buffer", arg, msgbuf, bufsize); + return converterr("read-write bytes-like object", + arg, msgbuf, bufsize); } if (!PyBuffer_IsContiguous((Py_buffer*)p, 'C')) { PyBuffer_Release((Py_buffer*)p); @@ -1279,7 +1283,7 @@ convertbuffer(PyObject *arg, void **p, char **errmsg) *errmsg = NULL; *p = NULL; if (pb != NULL && pb->bf_releasebuffer != NULL) { - *errmsg = "read-only pinned buffer"; + *errmsg = "read-only bytes-like object"; return -1; } @@ -1295,7 +1299,7 @@ static int getbuffer(PyObject *arg, Py_buffer *view, char **errmsg) { if (PyObject_GetBuffer(arg, view, PyBUF_SIMPLE) != 0) { - *errmsg = "bytes or buffer"; + *errmsg = "bytes-like object"; return -1; } if (!PyBuffer_IsContiguous(view, 'C')) { @@ -1439,7 +1443,11 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format, Py_ssize_t nargs, nkeywords; PyObject *current_arg; freelistentry_t static_entries[STATIC_FREELIST_ENTRIES]; - freelist_t freelist = {static_entries, 0, 0}; + freelist_t freelist; + + freelist.entries = static_entries; + freelist.first_available = 0; + freelist.entries_malloced = 0; assert(args != NULL && PyTuple_Check(args)); assert(keywords == NULL || PyDict_Check(keywords)); @@ -1805,7 +1813,7 @@ PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t m /* For type constructors that don't take keyword args * - * Sets a TypeError and returns 0 if the kwds dict is + * Sets a TypeError and returns 0 if the args/kwargs is * not empty, returns 1 otherwise */ int @@ -1824,6 +1832,25 @@ _PyArg_NoKeywords(const char *funcname, PyObject *kw) funcname); return 0; } + + +int +_PyArg_NoPositional(const char *funcname, PyObject *args) +{ + if (args == NULL) + return 1; + if (!PyTuple_CheckExact(args)) { + PyErr_BadInternalCall(); + return 0; + } + if (PyTuple_GET_SIZE(args) == 0) + return 1; + + PyErr_Format(PyExc_TypeError, "%s does not take positional arguments", + funcname); + return 0; +} + #ifdef __cplusplus }; #endif diff --git a/Python/getcopyright.c b/Python/getcopyright.c index 2b19622d4368..2ad2848aa80b 100644 --- a/Python/getcopyright.c +++ b/Python/getcopyright.c @@ -4,7 +4,7 @@ static const char cprt[] = "\ -Copyright (c) 2001-2013 Python Software Foundation.\n\ +Copyright (c) 2001-2015 Python Software Foundation.\n\ All Rights Reserved.\n\ \n\ Copyright (c) 2000 BeOpen.com.\n\ diff --git a/Python/graminit.c b/Python/graminit.c index e04999bbff2f..9f79d593f55b 100644 --- a/Python/graminit.c +++ b/Python/graminit.c @@ -476,7 +476,7 @@ static state states_16[3] = { {2, arcs_16_1}, {3, arcs_16_2}, }; -static arc arcs_17_0[12] = { +static arc arcs_17_0[13] = { {49, 1}, {50, 1}, {51, 1}, @@ -489,19 +489,20 @@ static arc arcs_17_0[12] = { {58, 1}, {59, 1}, {60, 1}, + {61, 1}, }; static arc arcs_17_1[1] = { {0, 1}, }; static state states_17[2] = { - {12, arcs_17_0}, + {13, arcs_17_0}, {1, arcs_17_1}, }; static arc arcs_18_0[1] = { - {61, 1}, + {62, 1}, }; static arc arcs_18_1[1] = { - {62, 2}, + {63, 2}, }; static arc arcs_18_2[1] = { {0, 2}, @@ -512,7 +513,7 @@ static state states_18[3] = { {1, arcs_18_2}, }; static arc arcs_19_0[1] = { - {63, 1}, + {64, 1}, }; static arc arcs_19_1[1] = { {0, 1}, @@ -522,11 +523,11 @@ static state states_19[2] = { {1, arcs_19_1}, }; static arc arcs_20_0[5] = { - {64, 1}, {65, 1}, {66, 1}, {67, 1}, {68, 1}, + {69, 1}, }; static arc arcs_20_1[1] = { {0, 1}, @@ -536,7 +537,7 @@ static state states_20[2] = { {1, arcs_20_1}, }; static arc arcs_21_0[1] = { - {69, 1}, + {70, 1}, }; static arc arcs_21_1[1] = { {0, 1}, @@ -546,7 +547,7 @@ static state states_21[2] = { {1, arcs_21_1}, }; static arc arcs_22_0[1] = { - {70, 1}, + {71, 1}, }; static arc arcs_22_1[1] = { {0, 1}, @@ -556,7 +557,7 @@ static state states_22[2] = { {1, arcs_22_1}, }; static arc arcs_23_0[1] = { - {71, 1}, + {72, 1}, }; static arc arcs_23_1[2] = { {9, 2}, @@ -581,14 +582,14 @@ static state states_24[2] = { {1, arcs_24_1}, }; static arc arcs_25_0[1] = { - {72, 1}, + {73, 1}, }; static arc arcs_25_1[2] = { {24, 2}, {0, 1}, }; static arc arcs_25_2[2] = { - {73, 3}, + {74, 3}, {0, 2}, }; static arc arcs_25_3[1] = { @@ -605,8 +606,8 @@ static state states_25[5] = { {1, arcs_25_4}, }; static arc arcs_26_0[2] = { - {74, 1}, {75, 1}, + {76, 1}, }; static arc arcs_26_1[1] = { {0, 1}, @@ -616,10 +617,10 @@ static state states_26[2] = { {1, arcs_26_1}, }; static arc arcs_27_0[1] = { - {76, 1}, + {77, 1}, }; static arc arcs_27_1[1] = { - {77, 2}, + {78, 2}, }; static arc arcs_27_2[1] = { {0, 2}, @@ -630,32 +631,32 @@ static state states_27[3] = { {1, arcs_27_2}, }; static arc arcs_28_0[1] = { - {73, 1}, + {74, 1}, }; static arc arcs_28_1[3] = { - {78, 2}, {79, 2}, + {80, 2}, {12, 3}, }; static arc arcs_28_2[4] = { - {78, 2}, {79, 2}, + {80, 2}, {12, 3}, - {76, 4}, + {77, 4}, }; static arc arcs_28_3[1] = { - {76, 4}, + {77, 4}, }; static arc arcs_28_4[3] = { {31, 5}, {13, 6}, - {80, 5}, + {81, 5}, }; static arc arcs_28_5[1] = { {0, 5}, }; static arc arcs_28_6[1] = { - {80, 7}, + {81, 7}, }; static arc arcs_28_7[1] = { {15, 5}, @@ -674,7 +675,7 @@ static arc arcs_29_0[1] = { {21, 1}, }; static arc arcs_29_1[2] = { - {82, 2}, + {83, 2}, {0, 1}, }; static arc arcs_29_2[1] = { @@ -693,7 +694,7 @@ static arc arcs_30_0[1] = { {12, 1}, }; static arc arcs_30_1[2] = { - {82, 2}, + {83, 2}, {0, 1}, }; static arc arcs_30_2[1] = { @@ -709,14 +710,14 @@ static state states_30[4] = { {1, arcs_30_3}, }; static arc arcs_31_0[1] = { - {81, 1}, + {82, 1}, }; static arc arcs_31_1[2] = { {30, 2}, {0, 1}, }; static arc arcs_31_2[2] = { - {81, 1}, + {82, 1}, {0, 2}, }; static state states_31[3] = { @@ -725,7 +726,7 @@ static state states_31[3] = { {2, arcs_31_2}, }; static arc arcs_32_0[1] = { - {83, 1}, + {84, 1}, }; static arc arcs_32_1[2] = { {30, 0}, @@ -739,7 +740,7 @@ static arc arcs_33_0[1] = { {21, 1}, }; static arc arcs_33_1[2] = { - {78, 0}, + {79, 0}, {0, 1}, }; static state states_33[2] = { @@ -747,7 +748,7 @@ static state states_33[2] = { {2, arcs_33_1}, }; static arc arcs_34_0[1] = { - {84, 1}, + {85, 1}, }; static arc arcs_34_1[1] = { {21, 2}, @@ -762,7 +763,7 @@ static state states_34[3] = { {2, arcs_34_2}, }; static arc arcs_35_0[1] = { - {85, 1}, + {86, 1}, }; static arc arcs_35_1[1] = { {21, 2}, @@ -777,7 +778,7 @@ static state states_35[3] = { {2, arcs_35_2}, }; static arc arcs_36_0[1] = { - {86, 1}, + {87, 1}, }; static arc arcs_36_1[1] = { {24, 2}, @@ -800,11 +801,11 @@ static state states_36[5] = { {1, arcs_36_4}, }; static arc arcs_37_0[8] = { - {87, 1}, {88, 1}, {89, 1}, {90, 1}, {91, 1}, + {92, 1}, {19, 1}, {18, 1}, {17, 1}, @@ -817,7 +818,7 @@ static state states_37[2] = { {1, arcs_37_1}, }; static arc arcs_38_0[1] = { - {92, 1}, + {93, 1}, }; static arc arcs_38_1[1] = { {24, 2}, @@ -829,8 +830,8 @@ static arc arcs_38_3[1] = { {26, 4}, }; static arc arcs_38_4[3] = { - {93, 1}, - {94, 5}, + {94, 1}, + {95, 5}, {0, 4}, }; static arc arcs_38_5[1] = { @@ -853,7 +854,7 @@ static state states_38[8] = { {1, arcs_38_7}, }; static arc arcs_39_0[1] = { - {95, 1}, + {96, 1}, }; static arc arcs_39_1[1] = { {24, 2}, @@ -865,7 +866,7 @@ static arc arcs_39_3[1] = { {26, 4}, }; static arc arcs_39_4[2] = { - {94, 5}, + {95, 5}, {0, 4}, }; static arc arcs_39_5[1] = { @@ -888,13 +889,13 @@ static state states_39[8] = { {1, arcs_39_7}, }; static arc arcs_40_0[1] = { - {96, 1}, + {97, 1}, }; static arc arcs_40_1[1] = { - {62, 2}, + {63, 2}, }; static arc arcs_40_2[1] = { - {97, 3}, + {98, 3}, }; static arc arcs_40_3[1] = { {9, 4}, @@ -906,7 +907,7 @@ static arc arcs_40_5[1] = { {26, 6}, }; static arc arcs_40_6[2] = { - {94, 7}, + {95, 7}, {0, 6}, }; static arc arcs_40_7[1] = { @@ -931,7 +932,7 @@ static state states_40[10] = { {1, arcs_40_9}, }; static arc arcs_41_0[1] = { - {98, 1}, + {99, 1}, }; static arc arcs_41_1[1] = { {25, 2}, @@ -940,8 +941,8 @@ static arc arcs_41_2[1] = { {26, 3}, }; static arc arcs_41_3[2] = { - {99, 4}, - {100, 5}, + {100, 4}, + {101, 5}, }; static arc arcs_41_4[1] = { {25, 6}, @@ -956,9 +957,9 @@ static arc arcs_41_7[1] = { {26, 9}, }; static arc arcs_41_8[4] = { - {99, 4}, - {94, 10}, - {100, 5}, + {100, 4}, + {95, 10}, + {101, 5}, {0, 8}, }; static arc arcs_41_9[1] = { @@ -971,7 +972,7 @@ static arc arcs_41_11[1] = { {26, 12}, }; static arc arcs_41_12[2] = { - {100, 5}, + {101, 5}, {0, 12}, }; static state states_41[13] = { @@ -990,10 +991,10 @@ static state states_41[13] = { {2, arcs_41_12}, }; static arc arcs_42_0[1] = { - {101, 1}, + {102, 1}, }; static arc arcs_42_1[1] = { - {102, 2}, + {103, 2}, }; static arc arcs_42_2[2] = { {30, 1}, @@ -1016,11 +1017,11 @@ static arc arcs_43_0[1] = { {24, 1}, }; static arc arcs_43_1[2] = { - {82, 2}, + {83, 2}, {0, 1}, }; static arc arcs_43_2[1] = { - {103, 3}, + {104, 3}, }; static arc arcs_43_3[1] = { {0, 3}, @@ -1032,14 +1033,14 @@ static state states_43[4] = { {1, arcs_43_3}, }; static arc arcs_44_0[1] = { - {104, 1}, + {105, 1}, }; static arc arcs_44_1[2] = { {24, 2}, {0, 1}, }; static arc arcs_44_2[2] = { - {82, 3}, + {83, 3}, {0, 2}, }; static arc arcs_44_3[1] = { @@ -1063,14 +1064,14 @@ static arc arcs_45_1[1] = { {0, 1}, }; static arc arcs_45_2[1] = { - {105, 3}, + {106, 3}, }; static arc arcs_45_3[1] = { {6, 4}, }; static arc arcs_45_4[2] = { {6, 4}, - {106, 1}, + {107, 1}, }; static state states_45[5] = { {2, arcs_45_0}, @@ -1080,21 +1081,21 @@ static state states_45[5] = { {2, arcs_45_4}, }; static arc arcs_46_0[2] = { - {107, 1}, - {108, 2}, + {108, 1}, + {109, 2}, }; static arc arcs_46_1[2] = { - {92, 3}, + {93, 3}, {0, 1}, }; static arc arcs_46_2[1] = { {0, 2}, }; static arc arcs_46_3[1] = { - {107, 4}, + {108, 4}, }; static arc arcs_46_4[1] = { - {94, 5}, + {95, 5}, }; static arc arcs_46_5[1] = { {24, 2}, @@ -1108,8 +1109,8 @@ static state states_46[6] = { {1, arcs_46_5}, }; static arc arcs_47_0[2] = { - {107, 1}, - {110, 1}, + {108, 1}, + {111, 1}, }; static arc arcs_47_1[1] = { {0, 1}, @@ -1119,7 +1120,7 @@ static state states_47[2] = { {1, arcs_47_1}, }; static arc arcs_48_0[1] = { - {111, 1}, + {112, 1}, }; static arc arcs_48_1[2] = { {33, 2}, @@ -1142,7 +1143,7 @@ static state states_48[5] = { {1, arcs_48_4}, }; static arc arcs_49_0[1] = { - {111, 1}, + {112, 1}, }; static arc arcs_49_1[2] = { {33, 2}, @@ -1152,7 +1153,7 @@ static arc arcs_49_2[1] = { {25, 3}, }; static arc arcs_49_3[1] = { - {109, 4}, + {110, 4}, }; static arc arcs_49_4[1] = { {0, 4}, @@ -1165,10 +1166,10 @@ static state states_49[5] = { {1, arcs_49_4}, }; static arc arcs_50_0[1] = { - {112, 1}, + {113, 1}, }; static arc arcs_50_1[2] = { - {113, 0}, + {114, 0}, {0, 1}, }; static state states_50[2] = { @@ -1176,10 +1177,10 @@ static state states_50[2] = { {2, arcs_50_1}, }; static arc arcs_51_0[1] = { - {114, 1}, + {115, 1}, }; static arc arcs_51_1[2] = { - {115, 0}, + {116, 0}, {0, 1}, }; static state states_51[2] = { @@ -1187,11 +1188,11 @@ static state states_51[2] = { {2, arcs_51_1}, }; static arc arcs_52_0[2] = { - {116, 1}, - {117, 2}, + {117, 1}, + {118, 2}, }; static arc arcs_52_1[1] = { - {114, 2}, + {115, 2}, }; static arc arcs_52_2[1] = { {0, 2}, @@ -1202,10 +1203,10 @@ static state states_52[3] = { {1, arcs_52_2}, }; static arc arcs_53_0[1] = { - {103, 1}, + {104, 1}, }; static arc arcs_53_1[2] = { - {118, 0}, + {119, 0}, {0, 1}, }; static state states_53[2] = { @@ -1213,25 +1214,25 @@ static state states_53[2] = { {2, arcs_53_1}, }; static arc arcs_54_0[10] = { - {119, 1}, {120, 1}, {121, 1}, {122, 1}, {123, 1}, {124, 1}, {125, 1}, - {97, 1}, - {116, 2}, - {126, 3}, + {126, 1}, + {98, 1}, + {117, 2}, + {127, 3}, }; static arc arcs_54_1[1] = { {0, 1}, }; static arc arcs_54_2[1] = { - {97, 1}, + {98, 1}, }; static arc arcs_54_3[2] = { - {116, 1}, + {117, 1}, {0, 3}, }; static state states_54[4] = { @@ -1244,7 +1245,7 @@ static arc arcs_55_0[1] = { {31, 1}, }; static arc arcs_55_1[1] = { - {103, 2}, + {104, 2}, }; static arc arcs_55_2[1] = { {0, 2}, @@ -1255,10 +1256,10 @@ static state states_55[3] = { {1, arcs_55_2}, }; static arc arcs_56_0[1] = { - {127, 1}, + {128, 1}, }; static arc arcs_56_1[2] = { - {128, 0}, + {129, 0}, {0, 1}, }; static state states_56[2] = { @@ -1266,10 +1267,10 @@ static state states_56[2] = { {2, arcs_56_1}, }; static arc arcs_57_0[1] = { - {129, 1}, + {130, 1}, }; static arc arcs_57_1[2] = { - {130, 0}, + {131, 0}, {0, 1}, }; static state states_57[2] = { @@ -1277,10 +1278,10 @@ static state states_57[2] = { {2, arcs_57_1}, }; static arc arcs_58_0[1] = { - {131, 1}, + {132, 1}, }; static arc arcs_58_1[2] = { - {132, 0}, + {133, 0}, {0, 1}, }; static state states_58[2] = { @@ -1288,11 +1289,11 @@ static state states_58[2] = { {2, arcs_58_1}, }; static arc arcs_59_0[1] = { - {133, 1}, + {134, 1}, }; static arc arcs_59_1[3] = { - {134, 0}, {135, 0}, + {136, 0}, {0, 1}, }; static state states_59[2] = { @@ -1300,11 +1301,11 @@ static state states_59[2] = { {3, arcs_59_1}, }; static arc arcs_60_0[1] = { - {136, 1}, + {137, 1}, }; static arc arcs_60_1[3] = { - {137, 0}, {138, 0}, + {139, 0}, {0, 1}, }; static state states_60[2] = { @@ -1312,27 +1313,28 @@ static state states_60[2] = { {3, arcs_60_1}, }; static arc arcs_61_0[1] = { - {139, 1}, + {140, 1}, }; -static arc arcs_61_1[5] = { +static arc arcs_61_1[6] = { {31, 0}, - {140, 0}, + {11, 0}, {141, 0}, {142, 0}, + {143, 0}, {0, 1}, }; static state states_61[2] = { {1, arcs_61_0}, - {5, arcs_61_1}, + {6, arcs_61_1}, }; static arc arcs_62_0[4] = { - {137, 1}, {138, 1}, - {143, 1}, - {144, 2}, + {139, 1}, + {144, 1}, + {145, 2}, }; static arc arcs_62_1[1] = { - {139, 2}, + {140, 2}, }; static arc arcs_62_2[1] = { {0, 2}, @@ -1343,15 +1345,15 @@ static state states_62[3] = { {1, arcs_62_2}, }; static arc arcs_63_0[1] = { - {145, 1}, + {146, 1}, }; static arc arcs_63_1[3] = { - {146, 1}, + {147, 1}, {32, 2}, {0, 1}, }; static arc arcs_63_2[1] = { - {139, 3}, + {140, 3}, }; static arc arcs_63_3[1] = { {0, 3}, @@ -1364,44 +1366,44 @@ static state states_63[4] = { }; static arc arcs_64_0[10] = { {13, 1}, - {148, 2}, - {150, 3}, + {149, 2}, + {151, 3}, {21, 4}, - {153, 4}, - {154, 5}, - {79, 4}, - {155, 4}, + {154, 4}, + {155, 5}, + {80, 4}, {156, 4}, {157, 4}, + {158, 4}, }; static arc arcs_64_1[3] = { {47, 6}, - {147, 6}, + {148, 6}, {15, 4}, }; static arc arcs_64_2[2] = { - {147, 7}, - {149, 4}, + {148, 7}, + {150, 4}, }; static arc arcs_64_3[2] = { - {151, 8}, - {152, 4}, + {152, 8}, + {153, 4}, }; static arc arcs_64_4[1] = { {0, 4}, }; static arc arcs_64_5[2] = { - {154, 5}, + {155, 5}, {0, 5}, }; static arc arcs_64_6[1] = { {15, 4}, }; static arc arcs_64_7[1] = { - {149, 4}, + {150, 4}, }; static arc arcs_64_8[1] = { - {152, 4}, + {153, 4}, }; static state states_64[9] = { {10, arcs_64_0}, @@ -1419,7 +1421,7 @@ static arc arcs_65_0[2] = { {48, 1}, }; static arc arcs_65_1[3] = { - {158, 2}, + {159, 2}, {30, 3}, {0, 1}, }; @@ -1444,15 +1446,15 @@ static state states_65[5] = { }; static arc arcs_66_0[3] = { {13, 1}, - {148, 2}, - {78, 3}, + {149, 2}, + {79, 3}, }; static arc arcs_66_1[2] = { {14, 4}, {15, 5}, }; static arc arcs_66_2[1] = { - {159, 6}, + {160, 6}, }; static arc arcs_66_3[1] = { {21, 5}, @@ -1464,7 +1466,7 @@ static arc arcs_66_5[1] = { {0, 5}, }; static arc arcs_66_6[1] = { - {149, 5}, + {150, 5}, }; static state states_66[7] = { {3, arcs_66_0}, @@ -1476,14 +1478,14 @@ static state states_66[7] = { {1, arcs_66_6}, }; static arc arcs_67_0[1] = { - {160, 1}, + {161, 1}, }; static arc arcs_67_1[2] = { {30, 2}, {0, 1}, }; static arc arcs_67_2[2] = { - {160, 1}, + {161, 1}, {0, 2}, }; static state states_67[3] = { @@ -1501,11 +1503,11 @@ static arc arcs_68_1[2] = { }; static arc arcs_68_2[3] = { {24, 3}, - {161, 4}, + {162, 4}, {0, 2}, }; static arc arcs_68_3[2] = { - {161, 4}, + {162, 4}, {0, 3}, }; static arc arcs_68_4[1] = { @@ -1534,7 +1536,7 @@ static state states_69[3] = { {1, arcs_69_2}, }; static arc arcs_70_0[2] = { - {103, 1}, + {104, 1}, {48, 1}, }; static arc arcs_70_1[2] = { @@ -1542,7 +1544,7 @@ static arc arcs_70_1[2] = { {0, 1}, }; static arc arcs_70_2[3] = { - {103, 1}, + {104, 1}, {48, 1}, {0, 2}, }; @@ -1572,7 +1574,7 @@ static arc arcs_72_0[1] = { }; static arc arcs_72_1[4] = { {25, 2}, - {158, 3}, + {159, 3}, {30, 4}, {0, 1}, }; @@ -1587,7 +1589,7 @@ static arc arcs_72_4[2] = { {0, 4}, }; static arc arcs_72_5[3] = { - {158, 3}, + {159, 3}, {30, 7}, {0, 5}, }; @@ -1623,7 +1625,7 @@ static state states_72[11] = { {2, arcs_72_10}, }; static arc arcs_73_0[1] = { - {162, 1}, + {163, 1}, }; static arc arcs_73_1[1] = { {21, 2}, @@ -1659,7 +1661,7 @@ static state states_73[8] = { {1, arcs_73_7}, }; static arc arcs_74_0[3] = { - {163, 1}, + {164, 1}, {31, 2}, {32, 3}, }; @@ -1674,7 +1676,7 @@ static arc arcs_74_3[1] = { {24, 6}, }; static arc arcs_74_4[4] = { - {163, 1}, + {164, 1}, {31, 2}, {32, 3}, {0, 4}, @@ -1687,7 +1689,7 @@ static arc arcs_74_6[1] = { {0, 6}, }; static arc arcs_74_7[2] = { - {163, 5}, + {164, 5}, {32, 3}, }; static state states_74[8] = { @@ -1704,7 +1706,7 @@ static arc arcs_75_0[1] = { {24, 1}, }; static arc arcs_75_1[3] = { - {158, 2}, + {159, 2}, {29, 3}, {0, 1}, }; @@ -1721,8 +1723,8 @@ static state states_75[4] = { {1, arcs_75_3}, }; static arc arcs_76_0[2] = { - {158, 1}, - {165, 1}, + {159, 1}, + {166, 1}, }; static arc arcs_76_1[1] = { {0, 1}, @@ -1732,19 +1734,19 @@ static state states_76[2] = { {1, arcs_76_1}, }; static arc arcs_77_0[1] = { - {96, 1}, + {97, 1}, }; static arc arcs_77_1[1] = { - {62, 2}, + {63, 2}, }; static arc arcs_77_2[1] = { - {97, 3}, + {98, 3}, }; static arc arcs_77_3[1] = { - {107, 4}, + {108, 4}, }; static arc arcs_77_4[2] = { - {164, 5}, + {165, 5}, {0, 4}, }; static arc arcs_77_5[1] = { @@ -1759,13 +1761,13 @@ static state states_77[6] = { {1, arcs_77_5}, }; static arc arcs_78_0[1] = { - {92, 1}, + {93, 1}, }; static arc arcs_78_1[1] = { - {109, 2}, + {110, 2}, }; static arc arcs_78_2[2] = { - {164, 3}, + {165, 3}, {0, 2}, }; static arc arcs_78_3[1] = { @@ -1788,10 +1790,10 @@ static state states_79[2] = { {1, arcs_79_1}, }; static arc arcs_80_0[1] = { - {167, 1}, + {168, 1}, }; static arc arcs_80_1[2] = { - {168, 2}, + {169, 2}, {0, 1}, }; static arc arcs_80_2[1] = { @@ -1803,7 +1805,7 @@ static state states_80[3] = { {1, arcs_80_2}, }; static arc arcs_81_0[2] = { - {73, 1}, + {74, 1}, {9, 2}, }; static arc arcs_81_1[1] = { @@ -1819,11 +1821,11 @@ static state states_81[3] = { }; static dfa dfas[82] = { {256, "single_input", 0, 3, states_0, - "\004\050\060\200\000\000\000\240\340\223\160\220\045\200\020\000\000\206\120\076\204\000"}, + "\004\050\060\200\000\000\000\100\301\047\341\040\113\000\041\000\000\014\241\174\010\001"}, {257, "file_input", 0, 2, states_1, - "\204\050\060\200\000\000\000\240\340\223\160\220\045\200\020\000\000\206\120\076\204\000"}, + "\204\050\060\200\000\000\000\100\301\047\341\040\113\000\041\000\000\014\241\174\010\001"}, {258, "eval_input", 0, 3, states_2, - "\000\040\040\000\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000\000"}, + "\000\040\040\000\000\000\000\000\000\000\001\000\000\000\041\000\000\014\241\174\000\000"}, {259, "decorator", 0, 7, states_3, "\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {260, "decorators", 0, 2, states_4, @@ -1843,39 +1845,39 @@ static dfa dfas[82] = { {267, "vfpdef", 0, 2, states_11, "\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {268, "stmt", 0, 2, states_12, - "\000\050\060\200\000\000\000\240\340\223\160\220\045\200\020\000\000\206\120\076\204\000"}, + "\000\050\060\200\000\000\000\100\301\047\341\040\113\000\041\000\000\014\241\174\010\001"}, {269, "simple_stmt", 0, 4, states_13, - "\000\040\040\200\000\000\000\240\340\223\160\000\000\200\020\000\000\206\120\076\200\000"}, + "\000\040\040\200\000\000\000\100\301\047\341\000\000\000\041\000\000\014\241\174\000\001"}, {270, "small_stmt", 0, 2, states_14, - "\000\040\040\200\000\000\000\240\340\223\160\000\000\200\020\000\000\206\120\076\200\000"}, + "\000\040\040\200\000\000\000\100\301\047\341\000\000\000\041\000\000\014\241\174\000\001"}, {271, "expr_stmt", 0, 6, states_15, - "\000\040\040\200\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000\000"}, + "\000\040\040\200\000\000\000\000\000\000\001\000\000\000\041\000\000\014\241\174\000\000"}, {272, "testlist_star_expr", 0, 3, states_16, - "\000\040\040\200\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000\000"}, + "\000\040\040\200\000\000\000\000\000\000\001\000\000\000\041\000\000\014\241\174\000\000"}, {273, "augassign", 0, 2, states_17, - "\000\000\000\000\000\000\376\037\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\376\077\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {274, "del_stmt", 0, 3, states_18, - "\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {275, "pass_stmt", 0, 2, states_19, - "\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {276, "flow_stmt", 0, 2, states_20, - "\000\000\000\000\000\000\000\000\340\001\000\000\000\000\000\000\000\000\000\000\200\000"}, + "\000\000\000\000\000\000\000\000\300\003\000\000\000\000\000\000\000\000\000\000\000\001"}, {277, "break_stmt", 0, 2, states_21, - "\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {278, "continue_stmt", 0, 2, states_22, "\000\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {279, "return_stmt", 0, 3, states_23, + {278, "continue_stmt", 0, 2, states_22, "\000\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {279, "return_stmt", 0, 3, states_23, + "\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000"}, {280, "yield_stmt", 0, 2, states_24, - "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\200\000"}, + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001"}, {281, "raise_stmt", 0, 5, states_25, - "\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000"}, {282, "import_stmt", 0, 2, states_26, - "\000\000\000\000\000\000\000\000\000\022\000\000\000\000\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\000\044\000\000\000\000\000\000\000\000\000\000\000\000"}, {283, "import_name", 0, 3, states_27, - "\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000"}, {284, "import_from", 0, 8, states_28, - "\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000"}, {285, "import_as_name", 0, 4, states_29, "\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {286, "dotted_as_name", 0, 4, states_30, @@ -1887,103 +1889,103 @@ static dfa dfas[82] = { {289, "dotted_name", 0, 2, states_33, "\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {290, "global_stmt", 0, 3, states_34, - "\000\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000\000\000"}, - {291, "nonlocal_stmt", 0, 3, states_35, "\000\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000\000\000"}, - {292, "assert_stmt", 0, 5, states_36, + {291, "nonlocal_stmt", 0, 3, states_35, "\000\000\000\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\000\000\000\000"}, + {292, "assert_stmt", 0, 5, states_36, + "\000\000\000\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000"}, {293, "compound_stmt", 0, 2, states_37, - "\000\010\020\000\000\000\000\000\000\000\000\220\045\000\000\000\000\000\000\000\004\000"}, + "\000\010\020\000\000\000\000\000\000\000\000\040\113\000\000\000\000\000\000\000\010\000"}, {294, "if_stmt", 0, 8, states_38, - "\000\000\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000\000"}, {295, "while_stmt", 0, 8, states_39, - "\000\000\000\000\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000"}, - {296, "for_stmt", 0, 10, states_40, "\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000"}, + {296, "for_stmt", 0, 10, states_40, + "\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000"}, {297, "try_stmt", 0, 13, states_41, - "\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\000\000"}, {298, "with_stmt", 0, 5, states_42, - "\000\000\000\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\000\000"}, {299, "with_item", 0, 4, states_43, - "\000\040\040\000\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000\000"}, + "\000\040\040\000\000\000\000\000\000\000\001\000\000\000\041\000\000\014\241\174\000\000"}, {300, "except_clause", 0, 5, states_44, - "\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000"}, {301, "suite", 0, 5, states_45, - "\004\040\040\200\000\000\000\240\340\223\160\000\000\200\020\000\000\206\120\076\200\000"}, + "\004\040\040\200\000\000\000\100\301\047\341\000\000\000\041\000\000\014\241\174\000\001"}, {302, "test", 0, 6, states_46, - "\000\040\040\000\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000\000"}, + "\000\040\040\000\000\000\000\000\000\000\001\000\000\000\041\000\000\014\241\174\000\000"}, {303, "test_nocond", 0, 2, states_47, - "\000\040\040\000\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000\000"}, + "\000\040\040\000\000\000\000\000\000\000\001\000\000\000\041\000\000\014\241\174\000\000"}, {304, "lambdef", 0, 5, states_48, - "\000\000\000\000\000\000\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000"}, {305, "lambdef_nocond", 0, 5, states_49, - "\000\000\000\000\000\000\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000"}, {306, "or_test", 0, 2, states_50, - "\000\040\040\000\000\000\000\000\000\200\000\000\000\000\020\000\000\206\120\076\000\000"}, + "\000\040\040\000\000\000\000\000\000\000\001\000\000\000\040\000\000\014\241\174\000\000"}, {307, "and_test", 0, 2, states_51, - "\000\040\040\000\000\000\000\000\000\200\000\000\000\000\020\000\000\206\120\076\000\000"}, + "\000\040\040\000\000\000\000\000\000\000\001\000\000\000\040\000\000\014\241\174\000\000"}, {308, "not_test", 0, 3, states_52, - "\000\040\040\000\000\000\000\000\000\200\000\000\000\000\020\000\000\206\120\076\000\000"}, + "\000\040\040\000\000\000\000\000\000\000\001\000\000\000\040\000\000\014\241\174\000\000"}, {309, "comparison", 0, 2, states_53, - "\000\040\040\000\000\000\000\000\000\200\000\000\000\000\000\000\000\206\120\076\000\000"}, + "\000\040\040\000\000\000\000\000\000\000\001\000\000\000\000\000\000\014\241\174\000\000"}, {310, "comp_op", 0, 4, states_54, - "\000\000\000\000\000\000\000\000\000\000\000\000\002\000\220\177\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\000\000\000\000\004\000\040\377\000\000\000\000\000\000"}, {311, "star_expr", 0, 3, states_55, "\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {312, "expr", 0, 2, states_56, - "\000\040\040\000\000\000\000\000\000\200\000\000\000\000\000\000\000\206\120\076\000\000"}, + "\000\040\040\000\000\000\000\000\000\000\001\000\000\000\000\000\000\014\241\174\000\000"}, {313, "xor_expr", 0, 2, states_57, - "\000\040\040\000\000\000\000\000\000\200\000\000\000\000\000\000\000\206\120\076\000\000"}, + "\000\040\040\000\000\000\000\000\000\000\001\000\000\000\000\000\000\014\241\174\000\000"}, {314, "and_expr", 0, 2, states_58, - "\000\040\040\000\000\000\000\000\000\200\000\000\000\000\000\000\000\206\120\076\000\000"}, + "\000\040\040\000\000\000\000\000\000\000\001\000\000\000\000\000\000\014\241\174\000\000"}, {315, "shift_expr", 0, 2, states_59, - "\000\040\040\000\000\000\000\000\000\200\000\000\000\000\000\000\000\206\120\076\000\000"}, + "\000\040\040\000\000\000\000\000\000\000\001\000\000\000\000\000\000\014\241\174\000\000"}, {316, "arith_expr", 0, 2, states_60, - "\000\040\040\000\000\000\000\000\000\200\000\000\000\000\000\000\000\206\120\076\000\000"}, + "\000\040\040\000\000\000\000\000\000\000\001\000\000\000\000\000\000\014\241\174\000\000"}, {317, "term", 0, 2, states_61, - "\000\040\040\000\000\000\000\000\000\200\000\000\000\000\000\000\000\206\120\076\000\000"}, + "\000\040\040\000\000\000\000\000\000\000\001\000\000\000\000\000\000\014\241\174\000\000"}, {318, "factor", 0, 3, states_62, - "\000\040\040\000\000\000\000\000\000\200\000\000\000\000\000\000\000\206\120\076\000\000"}, + "\000\040\040\000\000\000\000\000\000\000\001\000\000\000\000\000\000\014\241\174\000\000"}, {319, "power", 0, 4, states_63, - "\000\040\040\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\120\076\000\000"}, + "\000\040\040\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\240\174\000\000"}, {320, "atom", 0, 9, states_64, - "\000\040\040\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\120\076\000\000"}, + "\000\040\040\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\240\174\000\000"}, {321, "testlist_comp", 0, 5, states_65, - "\000\040\040\200\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000\000"}, + "\000\040\040\200\000\000\000\000\000\000\001\000\000\000\041\000\000\014\241\174\000\000"}, {322, "trailer", 0, 7, states_66, - "\000\040\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\000\020\000\000\000"}, + "\000\040\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\040\000\000\000"}, {323, "subscriptlist", 0, 3, states_67, - "\000\040\040\002\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000\000"}, + "\000\040\040\002\000\000\000\000\000\000\001\000\000\000\041\000\000\014\241\174\000\000"}, {324, "subscript", 0, 5, states_68, - "\000\040\040\002\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000\000"}, + "\000\040\040\002\000\000\000\000\000\000\001\000\000\000\041\000\000\014\241\174\000\000"}, {325, "sliceop", 0, 3, states_69, "\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {326, "exprlist", 0, 3, states_70, - "\000\040\040\200\000\000\000\000\000\200\000\000\000\000\000\000\000\206\120\076\000\000"}, + "\000\040\040\200\000\000\000\000\000\000\001\000\000\000\000\000\000\014\241\174\000\000"}, {327, "testlist", 0, 3, states_71, - "\000\040\040\000\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000\000"}, + "\000\040\040\000\000\000\000\000\000\000\001\000\000\000\041\000\000\014\241\174\000\000"}, {328, "dictorsetmaker", 0, 11, states_72, - "\000\040\040\000\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000\000"}, + "\000\040\040\000\000\000\000\000\000\000\001\000\000\000\041\000\000\014\241\174\000\000"}, {329, "classdef", 0, 8, states_73, - "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000"}, + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\010\000"}, {330, "arglist", 0, 8, states_74, - "\000\040\040\200\001\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000\000"}, + "\000\040\040\200\001\000\000\000\000\000\001\000\000\000\041\000\000\014\241\174\000\000"}, {331, "argument", 0, 4, states_75, - "\000\040\040\000\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000\000"}, + "\000\040\040\000\000\000\000\000\000\000\001\000\000\000\041\000\000\014\241\174\000\000"}, {332, "comp_iter", 0, 2, states_76, - "\000\000\000\000\000\000\000\000\000\000\000\020\001\000\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\000\000\000\040\002\000\000\000\000\000\000\000\000\000"}, {333, "comp_for", 0, 6, states_77, - "\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000"}, {334, "comp_if", 0, 4, states_78, - "\000\000\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000\000"}, {335, "encoding_decl", 0, 2, states_79, "\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {336, "yield_expr", 0, 3, states_80, - "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\200\000"}, + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001"}, {337, "yield_arg", 0, 3, states_81, - "\000\040\040\000\000\000\000\000\000\202\000\000\000\200\020\000\000\206\120\076\000\000"}, + "\000\040\040\000\000\000\000\000\000\004\001\000\000\000\041\000\000\014\241\174\000\000"}, }; -static label labels[169] = { +static label labels[170] = { {0, "EMPTY"}, {256, 0}, {4, 0}, @@ -2007,7 +2009,7 @@ static label labels[169] = { {1, "def"}, {1, 0}, {263, 0}, - {50, 0}, + {51, 0}, {302, 0}, {11, 0}, {301, 0}, @@ -2036,6 +2038,7 @@ static label labels[169] = { {36, 0}, {37, 0}, {38, 0}, + {50, 0}, {39, 0}, {40, 0}, {41, 0}, @@ -2063,7 +2066,7 @@ static label labels[169] = { {1, "import"}, {288, 0}, {23, 0}, - {51, 0}, + {52, 0}, {287, 0}, {285, 0}, {1, "as"}, @@ -2157,6 +2160,6 @@ static label labels[169] = { grammar _PyParser_Grammar = { 82, dfas, - {169, labels}, + {170, labels}, 256 }; diff --git a/Python/import.c b/Python/import.c index 584b1b41cd3c..c3b9e12572a7 100644 --- a/Python/import.c +++ b/Python/import.c @@ -31,14 +31,34 @@ struct _inittab *PyImport_Inittab = _PyImport_Inittab; static PyObject *initstr = NULL; +/*[clinic input] +output preset file +module _imp +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=98c38221164579d5]*/ + +#include "clinic/import.c.h" + +/*[python input] +class fs_unicode_converter(CConverter): + type = 'PyObject *' + converter = 'PyUnicode_FSDecoder' + +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=9d6786230166006e]*/ + /* Initialize things */ void _PyImport_Init(void) { + PyInterpreterState *interp = PyThreadState_Get()->interp; initstr = PyUnicode_InternFromString("__init__"); if (initstr == NULL) Py_FatalError("Can't initialize import variables"); + interp->builtins_copy = PyDict_Copy(interp->builtins); + if (interp->builtins_copy == NULL) + Py_FatalError("Can't backup builtins dict"); } void @@ -210,8 +230,17 @@ _PyImport_ReInitLock(void) #endif +/*[clinic input] +_imp.lock_held + +Return True if the import lock is currently held, else False. + +On platforms without threads, return False. +[clinic start generated code]*/ + static PyObject * -imp_lock_held(PyObject *self, PyObject *noargs) +_imp_lock_held_impl(PyModuleDef *module) +/*[clinic end generated code: output=d7a8cc3a5169081a input=9b088f9b217d9bdf]*/ { #ifdef WITH_THREAD return PyBool_FromLong(import_lock_thread != -1); @@ -220,8 +249,18 @@ imp_lock_held(PyObject *self, PyObject *noargs) #endif } +/*[clinic input] +_imp.acquire_lock + +Acquires the interpreter's import lock for the current thread. + +This lock should be used by import hooks to ensure thread-safety when importing +modules. On platforms without threads, this function does nothing. +[clinic start generated code]*/ + static PyObject * -imp_acquire_lock(PyObject *self, PyObject *noargs) +_imp_acquire_lock_impl(PyModuleDef *module) +/*[clinic end generated code: output=cc143b1d16422cae input=4a2d4381866d5fdc]*/ { #ifdef WITH_THREAD _PyImport_AcquireLock(); @@ -230,8 +269,17 @@ imp_acquire_lock(PyObject *self, PyObject *noargs) return Py_None; } +/*[clinic input] +_imp.release_lock + +Release the interpreter's import lock. + +On platforms without threads, this function does nothing. +[clinic start generated code]*/ + static PyObject * -imp_release_lock(PyObject *self, PyObject *noargs) +_imp_release_lock_impl(PyModuleDef *module) +/*[clinic end generated code: output=74d28e38ebe2b224 input=934fb11516dd778b]*/ { #ifdef WITH_THREAD if (_PyImport_ReleaseLock() < 0) { @@ -247,8 +295,7 @@ imp_release_lock(PyObject *self, PyObject *noargs) void _PyImport_Fini(void) { - Py_XDECREF(extensions); - extensions = NULL; + Py_CLEAR(extensions); #ifdef WITH_THREAD if (import_lock != NULL) { PyThread_free_lock(import_lock); @@ -296,8 +343,8 @@ PyImport_Cleanup(void) PyObject *key, *value, *dict; PyInterpreterState *interp = PyThreadState_GET()->interp; PyObject *modules = interp->modules; - PyObject *builtins = interp->builtins; PyObject *weaklist = NULL; + char **p; if (modules == NULL) return; /* Already done */ @@ -310,31 +357,22 @@ PyImport_Cleanup(void) /* XXX Perhaps these precautions are obsolete. Who knows? */ - value = PyDict_GetItemString(modules, "builtins"); - if (value != NULL && PyModule_Check(value)) { - dict = PyModule_GetDict(value); + if (Py_VerboseFlag) + PySys_WriteStderr("# clear builtins._\n"); + PyDict_SetItemString(interp->builtins, "_", Py_None); + + for (p = sys_deletes; *p != NULL; p++) { if (Py_VerboseFlag) - PySys_WriteStderr("# clear builtins._\n"); - PyDict_SetItemString(dict, "_", Py_None); - } - value = PyDict_GetItemString(modules, "sys"); - if (value != NULL && PyModule_Check(value)) { - char **p; - PyObject *v; - dict = PyModule_GetDict(value); - for (p = sys_deletes; *p != NULL; p++) { - if (Py_VerboseFlag) - PySys_WriteStderr("# clear sys.%s\n", *p); - PyDict_SetItemString(dict, *p, Py_None); - } - for (p = sys_files; *p != NULL; p+=2) { - if (Py_VerboseFlag) - PySys_WriteStderr("# restore sys.%s\n", *p); - v = PyDict_GetItemString(dict, *(p+1)); - if (v == NULL) - v = Py_None; - PyDict_SetItemString(dict, *p, v); - } + PySys_WriteStderr("# clear sys.%s\n", *p); + PyDict_SetItemString(interp->sysdict, *p, Py_None); + } + for (p = sys_files; *p != NULL; p+=2) { + if (Py_VerboseFlag) + PySys_WriteStderr("# restore sys.%s\n", *p); + value = PyDict_GetItemString(interp->sysdict, *(p+1)); + if (value == NULL) + value = Py_None; + PyDict_SetItemString(interp->sysdict, *p, value); } /* We prepare a list which will receive (name, weakref) tuples of @@ -364,7 +402,7 @@ PyImport_Cleanup(void) while (PyDict_Next(modules, &pos, &key, &value)) { if (PyModule_Check(value)) { if (Py_VerboseFlag && PyUnicode_Check(key)) - PySys_FormatStderr("# cleanup[2] removing %U\n", key, value); + PySys_FormatStderr("# cleanup[2] removing %U\n", key); STORE_MODULE_WEAKREF(key, value); PyDict_SetItem(modules, key, Py_None); } @@ -372,11 +410,15 @@ PyImport_Cleanup(void) /* Clear the modules dict. */ PyDict_Clear(modules); - /* Replace the interpreter's reference to builtins with an empty dict - (module globals still have a reference to the original builtins). */ - builtins = interp->builtins; - interp->builtins = PyDict_New(); - Py_DECREF(builtins); + /* Restore the original builtins dict, to ensure that any + user data gets cleared. */ + dict = PyDict_Copy(interp->builtins); + if (dict == NULL) + PyErr_Clear(); + PyDict_Clear(interp->builtins); + if (PyDict_Update(interp->builtins, interp->builtins_copy)) + PyErr_Clear(); + Py_XDECREF(dict); /* Clear module dict copies stored in the interpreter state */ _PyState_ClearModules(); /* Collect references */ @@ -387,7 +429,15 @@ PyImport_Cleanup(void) /* Now, if there are any modules left alive, clear their globals to minimize potential leaks. All C extension modules actually end - up here, since they are kept alive in the interpreter state. */ + up here, since they are kept alive in the interpreter state. + + The special treatment of "builtins" here is because even + when it's not referenced as a module, its dictionary is + referenced by almost every module's __builtins__. Since + deleting a module clears its dictionary (even if there are + references left to it), we need to delete the "builtins" + module last. Likewise, we don't delete sys until the very + end because it is implicitly referenced (e.g. by print). */ if (weaklist != NULL) { Py_ssize_t i, n; n = PyList_GET_SIZE(weaklist); @@ -397,17 +447,27 @@ PyImport_Cleanup(void) PyObject *mod = PyWeakref_GET_OBJECT(PyTuple_GET_ITEM(tup, 1)); if (mod == Py_None) continue; - Py_INCREF(mod); assert(PyModule_Check(mod)); + dict = PyModule_GetDict(mod); + if (dict == interp->builtins || dict == interp->sysdict) + continue; + Py_INCREF(mod); if (Py_VerboseFlag && PyUnicode_Check(name)) - PySys_FormatStderr("# cleanup[3] wiping %U\n", - name, mod); + PySys_FormatStderr("# cleanup[3] wiping %U\n", name); _PyModule_Clear(mod); Py_DECREF(mod); } Py_DECREF(weaklist); } + /* Next, delete sys and builtins (in that order) */ + if (Py_VerboseFlag) + PySys_FormatStderr("# cleanup[3] wiping sys\n"); + _PyModule_ClearDict(interp->sysdict); + if (Py_VerboseFlag) + PySys_FormatStderr("# cleanup[3] wiping builtins\n"); + _PyModule_ClearDict(interp->builtins); + /* Clear and delete the modules directory. Actual modules will still be there only if imported during the execution of some destructor. */ @@ -496,8 +556,7 @@ _PyImport_FixupExtensionObject(PyObject *mod, PyObject *name, /* Somebody already imported the module, likely under a different name. XXX this should really not happen. */ - Py_DECREF(def->m_base.m_copy); - def->m_base.m_copy = NULL; + Py_CLEAR(def->m_base.m_copy); } dict = PyModule_GetDict(mod); if (dict == NULL) @@ -720,12 +779,10 @@ PyImport_ExecCodeModuleWithPathnames(const char *name, PyObject *co, return m; } -PyObject* -PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname, - PyObject *cpathname) +static PyObject * +module_dict_for_exec(PyObject *name) { - PyObject *modules = PyImport_GetModuleDict(); - PyObject *m, *d, *v; + PyObject *m, *d = NULL; m = PyImport_AddModuleObject(name); if (m == NULL) @@ -735,31 +792,26 @@ PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname, d = PyModule_GetDict(m); if (PyDict_GetItemString(d, "__builtins__") == NULL) { if (PyDict_SetItemString(d, "__builtins__", - PyEval_GetBuiltins()) != 0) - goto error; - } - if (pathname != NULL) { - v = pathname; - } - else { - v = ((PyCodeObject *)co)->co_filename; + PyEval_GetBuiltins()) != 0) { + remove_module(name); + return NULL; + } } - Py_INCREF(v); - if (PyDict_SetItemString(d, "__file__", v) != 0) - PyErr_Clear(); /* Not important enough to report */ - Py_DECREF(v); - /* Remember the pyc path name as the __cached__ attribute. */ - if (cpathname != NULL) - v = cpathname; - else - v = Py_None; - if (PyDict_SetItemString(d, "__cached__", v) != 0) - PyErr_Clear(); /* Not important enough to report */ + return d; /* Return a borrowed reference. */ +} - v = PyEval_EvalCode(co, d, d); - if (v == NULL) - goto error; +static PyObject * +exec_code_in_module(PyObject *name, PyObject *module_dict, PyObject *code_object) +{ + PyObject *modules = PyImport_GetModuleDict(); + PyObject *v, *m; + + v = PyEval_EvalCode(code_object, module_dict, module_dict); + if (v == NULL) { + remove_module(name); + return NULL; + } Py_DECREF(v); if ((m = PyDict_GetItem(modules, name)) == NULL) { @@ -772,10 +824,32 @@ PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname, Py_INCREF(m); return m; +} - error: - remove_module(name); - return NULL; +PyObject* +PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname, + PyObject *cpathname) +{ + PyObject *d, *res; + PyInterpreterState *interp = PyThreadState_GET()->interp; + _Py_IDENTIFIER(_fix_up_module); + + d = module_dict_for_exec(name); + if (d == NULL) { + return NULL; + } + + if (pathname == NULL) { + pathname = ((PyCodeObject *)co)->co_filename; + } + res = _PyObject_CallMethodIdObjArgs(interp->importlib, + &PyId__fix_up_module, + d, name, pathname, cpathname, NULL); + if (res != NULL) { + Py_DECREF(res); + res = exec_code_in_module(name, d, co); + } + return res; } @@ -817,28 +891,25 @@ update_compiled_module(PyCodeObject *co, PyObject *newname) Py_DECREF(oldname); } -static PyObject * -imp_fix_co_filename(PyObject *self, PyObject *args) -{ - PyObject *co; - PyObject *file_path; +/*[clinic input] +_imp._fix_co_filename - if (!PyArg_ParseTuple(args, "OO:_fix_co_filename", &co, &file_path)) - return NULL; + code: object(type="PyCodeObject *", subclass_of="&PyCode_Type") + Code object to change. - if (!PyCode_Check(co)) { - PyErr_SetString(PyExc_TypeError, - "first argument must be a code object"); - return NULL; - } + path: unicode + File path to use. + / - if (!PyUnicode_Check(file_path)) { - PyErr_SetString(PyExc_TypeError, - "second argument must be a string"); - return NULL; - } +Changes code.co_filename to specify the passed-in file path. +[clinic start generated code]*/ - update_compiled_module((PyCodeObject*)co, file_path); +static PyObject * +_imp__fix_co_filename_impl(PyModuleDef *module, PyCodeObject *code, PyObject *path) +/*[clinic end generated code: output=7afe5ba6b9d383e4 input=895ba50e78b82f05]*/ + +{ + update_compiled_module(code, path); Py_RETURN_NONE; } @@ -1058,7 +1129,7 @@ int PyImport_ImportFrozenModuleObject(PyObject *name) { const struct _frozen *p; - PyObject *co, *m, *path; + PyObject *co, *m, *d; int ispackage; int size; @@ -1087,7 +1158,7 @@ PyImport_ImportFrozenModuleObject(PyObject *name) } if (ispackage) { /* Set __path__ to the empty list */ - PyObject *d, *l; + PyObject *l; int err; m = PyImport_AddModuleObject(name); if (m == NULL) @@ -1102,11 +1173,11 @@ PyImport_ImportFrozenModuleObject(PyObject *name) if (err != 0) goto err_return; } - path = PyUnicode_FromString(""); - if (path == NULL) + d = module_dict_for_exec(name); + if (d == NULL) { goto err_return; - m = PyImport_ExecCodeModuleObject(name, co, path, NULL); - Py_DECREF(path); + } + m = exec_code_in_module(name, d, co); if (m == NULL) goto err_return; Py_DECREF(co); @@ -1691,8 +1762,15 @@ PyImport_Import(PyObject *module_name) return r; } +/*[clinic input] +_imp.extension_suffixes + +Returns the list of file suffixes used to identify extension modules. +[clinic start generated code]*/ + static PyObject * -imp_extension_suffixes(PyObject *self, PyObject *noargs) +_imp_extension_suffixes_impl(PyModuleDef *module) +/*[clinic end generated code: output=d44c1566ef362229 input=ecdeeecfcb6f839e]*/ { PyObject *list; const char *suffix; @@ -1720,14 +1798,22 @@ imp_extension_suffixes(PyObject *self, PyObject *noargs) return list; } +/*[clinic input] +_imp.init_builtin + + name: unicode + / + +Initializes a built-in module. +[clinic start generated code]*/ + static PyObject * -imp_init_builtin(PyObject *self, PyObject *args) +_imp_init_builtin_impl(PyModuleDef *module, PyObject *name) +/*[clinic end generated code: output=1868f473685f6d67 input=f934d2231ec52a2e]*/ { - PyObject *name; int ret; PyObject *m; - if (!PyArg_ParseTuple(args, "U:init_builtin", &name)) - return NULL; + ret = init_builtin(name); if (ret < 0) return NULL; @@ -1740,14 +1826,22 @@ imp_init_builtin(PyObject *self, PyObject *args) return m; } +/*[clinic input] +_imp.init_frozen + + name: unicode + / + +Initializes a frozen module. +[clinic start generated code]*/ + static PyObject * -imp_init_frozen(PyObject *self, PyObject *args) +_imp_init_frozen_impl(PyModuleDef *module, PyObject *name) +/*[clinic end generated code: output=a9de493bdd711878 input=13019adfc04f3fb3]*/ { - PyObject *name; int ret; PyObject *m; - if (!PyArg_ParseTuple(args, "U:init_frozen", &name)) - return NULL; + ret = PyImport_ImportFrozenModuleObject(name); if (ret < 0) return NULL; @@ -1760,61 +1854,97 @@ imp_init_frozen(PyObject *self, PyObject *args) return m; } +/*[clinic input] +_imp.get_frozen_object + + name: unicode + / + +Create a code object for a frozen module. +[clinic start generated code]*/ + static PyObject * -imp_get_frozen_object(PyObject *self, PyObject *args) +_imp_get_frozen_object_impl(PyModuleDef *module, PyObject *name) +/*[clinic end generated code: output=3114c970a47f2e3c input=ed689bc05358fdbd]*/ { - PyObject *name; - - if (!PyArg_ParseTuple(args, "U:get_frozen_object", &name)) - return NULL; return get_frozen_object(name); } +/*[clinic input] +_imp.is_frozen_package + + name: unicode + / + +Returns True if the module name is of a frozen package. +[clinic start generated code]*/ + static PyObject * -imp_is_frozen_package(PyObject *self, PyObject *args) +_imp_is_frozen_package_impl(PyModuleDef *module, PyObject *name) +/*[clinic end generated code: output=3e4cab802b56d649 input=81b6cdecd080fbb8]*/ { - PyObject *name; - - if (!PyArg_ParseTuple(args, "U:is_frozen_package", &name)) - return NULL; return is_frozen_package(name); } +/*[clinic input] +_imp.is_builtin + + name: unicode + / + +Returns True if the module name corresponds to a built-in module. +[clinic start generated code]*/ + static PyObject * -imp_is_builtin(PyObject *self, PyObject *args) +_imp_is_builtin_impl(PyModuleDef *module, PyObject *name) +/*[clinic end generated code: output=2deec9cac6fb9a7e input=86befdac021dd1c7]*/ { - PyObject *name; - if (!PyArg_ParseTuple(args, "U:is_builtin", &name)) - return NULL; return PyLong_FromLong(is_builtin(name)); } +/*[clinic input] +_imp.is_frozen + + name: unicode + / + +Returns True if the module name corresponds to a frozen module. +[clinic start generated code]*/ + static PyObject * -imp_is_frozen(PyObject *self, PyObject *args) +_imp_is_frozen_impl(PyModuleDef *module, PyObject *name) +/*[clinic end generated code: output=7de8e260c8e36aed input=7301dbca1897d66b]*/ { - PyObject *name; const struct _frozen *p; - if (!PyArg_ParseTuple(args, "U:is_frozen", &name)) - return NULL; + p = find_frozen(name); return PyBool_FromLong((long) (p == NULL ? 0 : p->size)); } #ifdef HAVE_DYNAMIC_LOADING +/*[clinic input] +_imp.load_dynamic + + name: unicode + path: fs_unicode + file: object = NULL + / + +Loads an extension module. +[clinic start generated code]*/ + static PyObject * -imp_load_dynamic(PyObject *self, PyObject *args) +_imp_load_dynamic_impl(PyModuleDef *module, PyObject *name, PyObject *path, PyObject *file) +/*[clinic end generated code: output=8b7ae431d795e1ba input=af64f06e4bad3526]*/ { - PyObject *name, *pathname, *fob = NULL, *mod; + PyObject *mod; FILE *fp; - if (!PyArg_ParseTuple(args, "UO&|O:load_dynamic", - &name, PyUnicode_FSDecoder, &pathname, &fob)) - return NULL; - if (fob != NULL) { - fp = _Py_fopen_obj(pathname, "r"); + if (file != NULL) { + fp = _Py_fopen_obj(path, "r"); if (fp == NULL) { - Py_DECREF(pathname); + Py_DECREF(path); if (!PyErr_Occurred()) PyErr_SetFromErrno(PyExc_IOError); return NULL; @@ -1822,8 +1952,8 @@ imp_load_dynamic(PyObject *self, PyObject *args) } else fp = NULL; - mod = _PyImport_LoadDynamicModule(name, pathname, fp); - Py_DECREF(pathname); + mod = _PyImport_LoadDynamicModule(name, path, fp); + Py_DECREF(path); if (fp) fclose(fp); return mod; @@ -1831,50 +1961,29 @@ imp_load_dynamic(PyObject *self, PyObject *args) #endif /* HAVE_DYNAMIC_LOADING */ +/*[clinic input] +dump buffer +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=524ce2e021e4eba6]*/ -/* Doc strings */ PyDoc_STRVAR(doc_imp, "(Extremely) low-level import machinery bits as used by importlib and imp."); -PyDoc_STRVAR(doc_extension_suffixes, -"extension_suffixes() -> list of strings\n\ -Returns the list of file suffixes used to identify extension modules."); - -PyDoc_STRVAR(doc_lock_held, -"lock_held() -> boolean\n\ -Return True if the import lock is currently held, else False.\n\ -On platforms without threads, return False."); - -PyDoc_STRVAR(doc_acquire_lock, -"acquire_lock() -> None\n\ -Acquires the interpreter's import lock for the current thread.\n\ -This lock should be used by import hooks to ensure thread-safety\n\ -when importing modules.\n\ -On platforms without threads, this function does nothing."); - -PyDoc_STRVAR(doc_release_lock, -"release_lock() -> None\n\ -Release the interpreter's import lock.\n\ -On platforms without threads, this function does nothing."); - static PyMethodDef imp_methods[] = { - {"extension_suffixes", imp_extension_suffixes, METH_NOARGS, - doc_extension_suffixes}, - {"lock_held", imp_lock_held, METH_NOARGS, doc_lock_held}, - {"acquire_lock", imp_acquire_lock, METH_NOARGS, doc_acquire_lock}, - {"release_lock", imp_release_lock, METH_NOARGS, doc_release_lock}, - {"get_frozen_object", imp_get_frozen_object, METH_VARARGS}, - {"is_frozen_package", imp_is_frozen_package, METH_VARARGS}, - {"init_builtin", imp_init_builtin, METH_VARARGS}, - {"init_frozen", imp_init_frozen, METH_VARARGS}, - {"is_builtin", imp_is_builtin, METH_VARARGS}, - {"is_frozen", imp_is_frozen, METH_VARARGS}, -#ifdef HAVE_DYNAMIC_LOADING - {"load_dynamic", imp_load_dynamic, METH_VARARGS}, -#endif - {"_fix_co_filename", imp_fix_co_filename, METH_VARARGS}, - {NULL, NULL} /* sentinel */ + _IMP_EXTENSION_SUFFIXES_METHODDEF + _IMP_LOCK_HELD_METHODDEF + _IMP_ACQUIRE_LOCK_METHODDEF + _IMP_RELEASE_LOCK_METHODDEF + _IMP_GET_FROZEN_OBJECT_METHODDEF + _IMP_IS_FROZEN_PACKAGE_METHODDEF + _IMP_INIT_BUILTIN_METHODDEF + _IMP_INIT_FROZEN_METHODDEF + _IMP_IS_BUILTIN_METHODDEF + _IMP_IS_FROZEN_METHODDEF + _IMP_LOAD_DYNAMIC_METHODDEF + _IMP__FIX_CO_FILENAME_METHODDEF + {NULL, NULL} /* sentinel */ }; @@ -1955,7 +2064,7 @@ PyImport_AppendInittab(const char *name, PyObject* (*initfunc)(void)) memset(newtab, '\0', sizeof newtab); - newtab[0].name = (char *)name; + newtab[0].name = name; newtab[0].initfunc = initfunc; return PyImport_ExtendInittab(newtab); diff --git a/Python/importlib.h b/Python/importlib.h index dd9b97863c2e..0154a7866b71 100644 --- a/Python/importlib.h +++ b/Python/importlib.h @@ -1,8 +1,8 @@ -/* Auto-generated by Modules/_freeze_importlib.c */ +/* Auto-generated by Programs/_freeze_importlib.c */ const unsigned char _Py_M__importlib[] = { 99,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0, - 0,64,0,0,0,115,201,4,0,0,100,0,0,90,0,0, - 100,159,0,90,1,0,100,4,0,100,5,0,132,0,0,90, + 0,64,0,0,0,115,43,5,0,0,100,0,0,90,0,0, + 100,177,0,90,1,0,100,4,0,100,5,0,132,0,0,90, 2,0,100,6,0,100,7,0,132,0,0,90,3,0,100,8, 0,100,9,0,132,0,0,90,4,0,100,10,0,100,11,0, 132,0,0,90,5,0,100,12,0,100,13,0,132,0,0,90, @@ -46,2132 +46,1907 @@ const unsigned char _Py_M__importlib[] = { 132,0,2,90,54,0,101,55,0,131,0,0,90,56,0,100, 53,0,100,95,0,100,53,0,100,96,0,101,56,0,100,97, 0,100,98,0,132,1,2,90,57,0,100,53,0,100,53,0, - 100,99,0,100,100,0,132,2,0,90,58,0,71,100,101,0, - 100,102,0,132,0,0,100,102,0,131,2,0,90,59,0,71, - 100,103,0,100,104,0,132,0,0,100,104,0,131,2,0,90, - 60,0,71,100,105,0,100,106,0,132,0,0,100,106,0,131, - 2,0,90,61,0,71,100,107,0,100,108,0,132,0,0,100, - 108,0,131,2,0,90,62,0,71,100,109,0,100,110,0,132, - 0,0,100,110,0,131,2,0,90,63,0,71,100,111,0,100, - 112,0,132,0,0,100,112,0,101,63,0,131,3,0,90,64, - 0,71,100,113,0,100,114,0,132,0,0,100,114,0,131,2, - 0,90,65,0,71,100,115,0,100,116,0,132,0,0,100,116, - 0,101,65,0,101,64,0,131,4,0,90,66,0,71,100,117, - 0,100,118,0,132,0,0,100,118,0,101,65,0,101,63,0, - 131,4,0,90,67,0,103,0,0,90,68,0,71,100,119,0, - 100,120,0,132,0,0,100,120,0,131,2,0,90,69,0,71, - 100,121,0,100,122,0,132,0,0,100,122,0,131,2,0,90, - 70,0,71,100,123,0,100,124,0,132,0,0,100,124,0,131, - 2,0,90,71,0,71,100,125,0,100,126,0,132,0,0,100, - 126,0,131,2,0,90,72,0,71,100,127,0,100,128,0,132, - 0,0,100,128,0,131,2,0,90,73,0,71,100,129,0,100, - 130,0,132,0,0,100,130,0,131,2,0,90,74,0,100,131, - 0,100,132,0,132,0,0,90,75,0,100,53,0,100,133,0, - 100,134,0,132,1,0,90,76,0,100,135,0,100,136,0,132, - 0,0,90,77,0,100,137,0,90,78,0,101,78,0,100,138, - 0,23,90,79,0,100,139,0,100,140,0,132,0,0,90,80, - 0,100,141,0,100,142,0,132,0,0,90,81,0,100,53,0, - 100,80,0,100,143,0,100,144,0,132,2,0,90,82,0,100, - 145,0,100,146,0,132,0,0,90,83,0,100,147,0,100,148, - 0,132,0,0,90,84,0,100,149,0,100,150,0,132,0,0, - 90,85,0,100,53,0,100,53,0,102,0,0,100,80,0,100, - 151,0,100,152,0,132,4,0,90,86,0,100,153,0,100,154, - 0,132,0,0,90,87,0,100,155,0,100,156,0,132,0,0, - 90,88,0,100,157,0,100,158,0,132,0,0,90,89,0,100, - 53,0,83,41,160,97,83,1,0,0,67,111,114,101,32,105, - 109,112,108,101,109,101,110,116,97,116,105,111,110,32,111,102, - 32,105,109,112,111,114,116,46,10,10,84,104,105,115,32,109, - 111,100,117,108,101,32,105,115,32,78,79,84,32,109,101,97, - 110,116,32,116,111,32,98,101,32,100,105,114,101,99,116,108, - 121,32,105,109,112,111,114,116,101,100,33,32,73,116,32,104, - 97,115,32,98,101,101,110,32,100,101,115,105,103,110,101,100, - 32,115,117,99,104,10,116,104,97,116,32,105,116,32,99,97, - 110,32,98,101,32,98,111,111,116,115,116,114,97,112,112,101, - 100,32,105,110,116,111,32,80,121,116,104,111,110,32,97,115, - 32,116,104,101,32,105,109,112,108,101,109,101,110,116,97,116, - 105,111,110,32,111,102,32,105,109,112,111,114,116,46,32,65, - 115,10,115,117,99,104,32,105,116,32,114,101,113,117,105,114, - 101,115,32,116,104,101,32,105,110,106,101,99,116,105,111,110, - 32,111,102,32,115,112,101,99,105,102,105,99,32,109,111,100, - 117,108,101,115,32,97,110,100,32,97,116,116,114,105,98,117, - 116,101,115,32,105,110,32,111,114,100,101,114,32,116,111,10, - 119,111,114,107,46,32,79,110,101,32,115,104,111,117,108,100, - 32,117,115,101,32,105,109,112,111,114,116,108,105,98,32,97, - 115,32,116,104,101,32,112,117,98,108,105,99,45,102,97,99, - 105,110,103,32,118,101,114,115,105,111,110,32,111,102,32,116, - 104,105,115,32,109,111,100,117,108,101,46,10,10,218,3,119, - 105,110,218,6,99,121,103,119,105,110,218,6,100,97,114,119, - 105,110,99,0,0,0,0,0,0,0,0,1,0,0,0,2, - 0,0,0,67,0,0,0,115,49,0,0,0,116,0,0,106, - 1,0,106,2,0,116,3,0,131,1,0,114,33,0,100,1, - 0,100,2,0,132,0,0,125,0,0,110,12,0,100,3,0, - 100,2,0,132,0,0,125,0,0,124,0,0,83,41,4,78, - 99,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0, - 0,83,0,0,0,115,13,0,0,0,100,1,0,116,0,0, - 106,1,0,107,6,0,83,41,2,122,53,84,114,117,101,32, - 105,102,32,102,105,108,101,110,97,109,101,115,32,109,117,115, - 116,32,98,101,32,99,104,101,99,107,101,100,32,99,97,115, - 101,45,105,110,115,101,110,115,105,116,105,118,101,108,121,46, - 115,12,0,0,0,80,89,84,72,79,78,67,65,83,69,79, - 75,41,2,218,3,95,111,115,90,7,101,110,118,105,114,111, - 110,169,0,114,4,0,0,0,114,4,0,0,0,250,29,60, - 102,114,111,122,101,110,32,105,109,112,111,114,116,108,105,98, - 46,95,98,111,111,116,115,116,114,97,112,62,218,11,95,114, - 101,108,97,120,95,99,97,115,101,30,0,0,0,115,2,0, - 0,0,0,2,122,37,95,109,97,107,101,95,114,101,108,97, - 120,95,99,97,115,101,46,60,108,111,99,97,108,115,62,46, - 95,114,101,108,97,120,95,99,97,115,101,99,0,0,0,0, - 0,0,0,0,0,0,0,0,1,0,0,0,83,0,0,0, - 115,4,0,0,0,100,1,0,83,41,2,122,53,84,114,117, + 100,99,0,100,100,0,132,2,0,90,58,0,100,101,0,100, + 102,0,100,103,0,100,104,0,132,0,1,90,59,0,100,105, + 0,100,106,0,132,0,0,90,60,0,100,107,0,100,108,0, + 132,0,0,90,61,0,100,109,0,100,110,0,132,0,0,90, + 62,0,100,111,0,100,112,0,132,0,0,90,63,0,100,113, + 0,100,114,0,132,0,0,90,64,0,100,115,0,100,116,0, + 132,0,0,90,65,0,100,53,0,100,117,0,100,118,0,132, + 1,0,90,66,0,71,100,119,0,100,120,0,132,0,0,100, + 120,0,131,2,0,90,67,0,71,100,121,0,100,122,0,132, + 0,0,100,122,0,131,2,0,90,68,0,71,100,123,0,100, + 124,0,132,0,0,100,124,0,131,2,0,90,69,0,71,100, + 125,0,100,126,0,132,0,0,100,126,0,131,2,0,90,70, + 0,71,100,127,0,100,128,0,132,0,0,100,128,0,101,70, + 0,131,3,0,90,71,0,71,100,129,0,100,130,0,132,0, + 0,100,130,0,131,2,0,90,72,0,71,100,131,0,100,132, + 0,132,0,0,100,132,0,101,72,0,101,71,0,131,4,0, + 90,73,0,71,100,133,0,100,134,0,132,0,0,100,134,0, + 101,72,0,101,70,0,131,4,0,90,74,0,103,0,0,90, + 75,0,71,100,135,0,100,136,0,132,0,0,100,136,0,131, + 2,0,90,76,0,71,100,137,0,100,138,0,132,0,0,100, + 138,0,131,2,0,90,77,0,71,100,139,0,100,140,0,132, + 0,0,100,140,0,131,2,0,90,78,0,71,100,141,0,100, + 142,0,132,0,0,100,142,0,131,2,0,90,79,0,71,100, + 143,0,100,144,0,132,0,0,100,144,0,131,2,0,90,80, + 0,71,100,145,0,100,146,0,132,0,0,100,146,0,131,2, + 0,90,81,0,100,147,0,100,148,0,132,0,0,90,82,0, + 100,149,0,100,150,0,132,0,0,90,83,0,100,53,0,100, + 151,0,100,152,0,132,1,0,90,84,0,100,153,0,100,154, + 0,132,0,0,90,85,0,100,155,0,90,86,0,101,86,0, + 100,156,0,23,90,87,0,100,157,0,100,158,0,132,0,0, + 90,88,0,100,159,0,100,160,0,132,0,0,90,89,0,100, + 53,0,100,80,0,100,161,0,100,162,0,132,2,0,90,90, + 0,100,163,0,100,164,0,132,0,0,90,91,0,100,165,0, + 100,166,0,132,0,0,90,92,0,100,167,0,100,168,0,132, + 0,0,90,93,0,100,53,0,100,53,0,102,0,0,100,80, + 0,100,169,0,100,170,0,132,4,0,90,94,0,100,171,0, + 100,172,0,132,0,0,90,95,0,100,173,0,100,174,0,132, + 0,0,90,96,0,100,175,0,100,176,0,132,0,0,90,97, + 0,100,53,0,83,41,178,97,83,1,0,0,67,111,114,101, + 32,105,109,112,108,101,109,101,110,116,97,116,105,111,110,32, + 111,102,32,105,109,112,111,114,116,46,10,10,84,104,105,115, + 32,109,111,100,117,108,101,32,105,115,32,78,79,84,32,109, + 101,97,110,116,32,116,111,32,98,101,32,100,105,114,101,99, + 116,108,121,32,105,109,112,111,114,116,101,100,33,32,73,116, + 32,104,97,115,32,98,101,101,110,32,100,101,115,105,103,110, + 101,100,32,115,117,99,104,10,116,104,97,116,32,105,116,32, + 99,97,110,32,98,101,32,98,111,111,116,115,116,114,97,112, + 112,101,100,32,105,110,116,111,32,80,121,116,104,111,110,32, + 97,115,32,116,104,101,32,105,109,112,108,101,109,101,110,116, + 97,116,105,111,110,32,111,102,32,105,109,112,111,114,116,46, + 32,65,115,10,115,117,99,104,32,105,116,32,114,101,113,117, + 105,114,101,115,32,116,104,101,32,105,110,106,101,99,116,105, + 111,110,32,111,102,32,115,112,101,99,105,102,105,99,32,109, + 111,100,117,108,101,115,32,97,110,100,32,97,116,116,114,105, + 98,117,116,101,115,32,105,110,32,111,114,100,101,114,32,116, + 111,10,119,111,114,107,46,32,79,110,101,32,115,104,111,117, + 108,100,32,117,115,101,32,105,109,112,111,114,116,108,105,98, + 32,97,115,32,116,104,101,32,112,117,98,108,105,99,45,102, + 97,99,105,110,103,32,118,101,114,115,105,111,110,32,111,102, + 32,116,104,105,115,32,109,111,100,117,108,101,46,10,10,218, + 3,119,105,110,218,6,99,121,103,119,105,110,218,6,100,97, + 114,119,105,110,99,0,0,0,0,0,0,0,0,1,0,0, + 0,2,0,0,0,67,0,0,0,115,49,0,0,0,116,0, + 0,106,1,0,106,2,0,116,3,0,131,1,0,114,33,0, + 100,1,0,100,2,0,132,0,0,125,0,0,110,12,0,100, + 3,0,100,2,0,132,0,0,125,0,0,124,0,0,83,41, + 4,78,99,0,0,0,0,0,0,0,0,0,0,0,0,2, + 0,0,0,83,0,0,0,115,13,0,0,0,100,1,0,116, + 0,0,106,1,0,107,6,0,83,41,2,122,53,84,114,117, 101,32,105,102,32,102,105,108,101,110,97,109,101,115,32,109, 117,115,116,32,98,101,32,99,104,101,99,107,101,100,32,99, 97,115,101,45,105,110,115,101,110,115,105,116,105,118,101,108, - 121,46,70,114,4,0,0,0,114,4,0,0,0,114,4,0, - 0,0,114,4,0,0,0,114,5,0,0,0,114,6,0,0, - 0,34,0,0,0,115,2,0,0,0,0,2,41,4,218,3, - 115,121,115,218,8,112,108,97,116,102,111,114,109,218,10,115, - 116,97,114,116,115,119,105,116,104,218,27,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,41,1,114,6,0,0,0,114,4,0, - 0,0,114,4,0,0,0,114,5,0,0,0,218,16,95,109, - 97,107,101,95,114,101,108,97,120,95,99,97,115,101,28,0, - 0,0,115,8,0,0,0,0,1,18,1,15,4,12,3,114, - 11,0,0,0,99,1,0,0,0,0,0,0,0,1,0,0, - 0,3,0,0,0,67,0,0,0,115,26,0,0,0,116,0, - 0,124,0,0,131,1,0,100,1,0,64,106,1,0,100,2, - 0,100,3,0,131,2,0,83,41,4,122,42,67,111,110,118, - 101,114,116,32,97,32,51,50,45,98,105,116,32,105,110,116, - 101,103,101,114,32,116,111,32,108,105,116,116,108,101,45,101, - 110,100,105,97,110,46,108,3,0,0,0,255,127,255,127,3, - 0,233,4,0,0,0,218,6,108,105,116,116,108,101,41,2, - 218,3,105,110,116,218,8,116,111,95,98,121,116,101,115,41, - 1,218,1,120,114,4,0,0,0,114,4,0,0,0,114,5, - 0,0,0,218,7,95,119,95,108,111,110,103,40,0,0,0, - 115,2,0,0,0,0,2,114,17,0,0,0,99,1,0,0, - 0,0,0,0,0,1,0,0,0,3,0,0,0,67,0,0, - 0,115,16,0,0,0,116,0,0,106,1,0,124,0,0,100, - 1,0,131,2,0,83,41,2,122,47,67,111,110,118,101,114, - 116,32,52,32,98,121,116,101,115,32,105,110,32,108,105,116, - 116,108,101,45,101,110,100,105,97,110,32,116,111,32,97,110, - 32,105,110,116,101,103,101,114,46,114,13,0,0,0,41,2, - 114,14,0,0,0,218,10,102,114,111,109,95,98,121,116,101, - 115,41,1,90,9,105,110,116,95,98,121,116,101,115,114,4, - 0,0,0,114,4,0,0,0,114,5,0,0,0,218,7,95, - 114,95,108,111,110,103,45,0,0,0,115,2,0,0,0,0, - 2,114,19,0,0,0,99,0,0,0,0,0,0,0,0,1, - 0,0,0,3,0,0,0,71,0,0,0,115,26,0,0,0, - 116,0,0,106,1,0,100,1,0,100,2,0,132,0,0,124, - 0,0,68,131,1,0,131,1,0,83,41,3,122,31,82,101, - 112,108,97,99,101,109,101,110,116,32,102,111,114,32,111,115, - 46,112,97,116,104,46,106,111,105,110,40,41,46,99,1,0, - 0,0,0,0,0,0,2,0,0,0,4,0,0,0,83,0, - 0,0,115,37,0,0,0,103,0,0,124,0,0,93,27,0, - 125,1,0,124,1,0,114,6,0,124,1,0,106,0,0,116, - 1,0,131,1,0,145,2,0,113,6,0,83,114,4,0,0, - 0,41,2,218,6,114,115,116,114,105,112,218,15,112,97,116, - 104,95,115,101,112,97,114,97,116,111,114,115,41,2,218,2, - 46,48,218,4,112,97,114,116,114,4,0,0,0,114,4,0, - 0,0,114,5,0,0,0,250,10,60,108,105,115,116,99,111, - 109,112,62,52,0,0,0,115,2,0,0,0,9,1,122,30, - 95,112,97,116,104,95,106,111,105,110,46,60,108,111,99,97, - 108,115,62,46,60,108,105,115,116,99,111,109,112,62,41,2, - 218,8,112,97,116,104,95,115,101,112,218,4,106,111,105,110, - 41,1,218,10,112,97,116,104,95,112,97,114,116,115,114,4, - 0,0,0,114,4,0,0,0,114,5,0,0,0,218,10,95, - 112,97,116,104,95,106,111,105,110,50,0,0,0,115,4,0, - 0,0,0,2,15,1,114,28,0,0,0,99,1,0,0,0, - 0,0,0,0,5,0,0,0,5,0,0,0,67,0,0,0, - 115,134,0,0,0,116,0,0,116,1,0,131,1,0,100,1, - 0,107,2,0,114,52,0,124,0,0,106,2,0,116,3,0, - 131,1,0,92,3,0,125,1,0,125,2,0,125,3,0,124, - 1,0,124,3,0,102,2,0,83,120,69,0,116,4,0,124, - 0,0,131,1,0,68,93,55,0,125,4,0,124,4,0,116, - 1,0,107,6,0,114,65,0,124,0,0,106,5,0,124,4, - 0,100,2,0,100,1,0,131,1,1,92,2,0,125,1,0, - 125,3,0,124,1,0,124,3,0,102,2,0,83,113,65,0, - 87,100,3,0,124,0,0,102,2,0,83,41,4,122,32,82, - 101,112,108,97,99,101,109,101,110,116,32,102,111,114,32,111, - 115,46,112,97,116,104,46,115,112,108,105,116,40,41,46,233, - 1,0,0,0,90,8,109,97,120,115,112,108,105,116,218,0, - 41,6,218,3,108,101,110,114,21,0,0,0,218,10,114,112, - 97,114,116,105,116,105,111,110,114,25,0,0,0,218,8,114, - 101,118,101,114,115,101,100,218,6,114,115,112,108,105,116,41, - 5,218,4,112,97,116,104,90,5,102,114,111,110,116,218,1, - 95,218,4,116,97,105,108,114,16,0,0,0,114,4,0,0, - 0,114,4,0,0,0,114,5,0,0,0,218,11,95,112,97, - 116,104,95,115,112,108,105,116,56,0,0,0,115,16,0,0, - 0,0,2,18,1,24,1,10,1,19,1,12,1,27,1,14, - 1,114,38,0,0,0,99,1,0,0,0,0,0,0,0,1, - 0,0,0,2,0,0,0,67,0,0,0,115,13,0,0,0, - 116,0,0,106,1,0,124,0,0,131,1,0,83,41,1,122, - 126,83,116,97,116,32,116,104,101,32,112,97,116,104,46,10, - 10,32,32,32,32,77,97,100,101,32,97,32,115,101,112,97, - 114,97,116,101,32,102,117,110,99,116,105,111,110,32,116,111, - 32,109,97,107,101,32,105,116,32,101,97,115,105,101,114,32, - 116,111,32,111,118,101,114,114,105,100,101,32,105,110,32,101, - 120,112,101,114,105,109,101,110,116,115,10,32,32,32,32,40, - 101,46,103,46,32,99,97,99,104,101,32,115,116,97,116,32, - 114,101,115,117,108,116,115,41,46,10,10,32,32,32,32,41, - 2,114,3,0,0,0,90,4,115,116,97,116,41,1,114,35, - 0,0,0,114,4,0,0,0,114,4,0,0,0,114,5,0, - 0,0,218,10,95,112,97,116,104,95,115,116,97,116,68,0, - 0,0,115,2,0,0,0,0,7,114,39,0,0,0,99,2, - 0,0,0,0,0,0,0,3,0,0,0,11,0,0,0,67, - 0,0,0,115,58,0,0,0,121,16,0,116,0,0,124,0, - 0,131,1,0,125,2,0,87,110,22,0,4,116,1,0,107, - 10,0,114,40,0,1,1,1,100,1,0,83,89,110,1,0, - 88,124,2,0,106,2,0,100,2,0,64,124,1,0,107,2, - 0,83,41,3,122,49,84,101,115,116,32,119,104,101,116,104, - 101,114,32,116,104,101,32,112,97,116,104,32,105,115,32,116, - 104,101,32,115,112,101,99,105,102,105,101,100,32,109,111,100, - 101,32,116,121,112,101,46,70,105,0,240,0,0,41,3,114, - 39,0,0,0,218,7,79,83,69,114,114,111,114,218,7,115, - 116,95,109,111,100,101,41,3,114,35,0,0,0,218,4,109, - 111,100,101,90,9,115,116,97,116,95,105,110,102,111,114,4, - 0,0,0,114,4,0,0,0,114,5,0,0,0,218,18,95, - 112,97,116,104,95,105,115,95,109,111,100,101,95,116,121,112, - 101,78,0,0,0,115,10,0,0,0,0,2,3,1,16,1, - 13,1,9,1,114,43,0,0,0,99,1,0,0,0,0,0, - 0,0,1,0,0,0,3,0,0,0,67,0,0,0,115,13, - 0,0,0,116,0,0,124,0,0,100,1,0,131,2,0,83, - 41,2,122,31,82,101,112,108,97,99,101,109,101,110,116,32, - 102,111,114,32,111,115,46,112,97,116,104,46,105,115,102,105, - 108,101,46,105,0,128,0,0,41,1,114,43,0,0,0,41, - 1,114,35,0,0,0,114,4,0,0,0,114,4,0,0,0, - 114,5,0,0,0,218,12,95,112,97,116,104,95,105,115,102, - 105,108,101,87,0,0,0,115,2,0,0,0,0,2,114,44, + 121,46,115,12,0,0,0,80,89,84,72,79,78,67,65,83, + 69,79,75,41,2,218,3,95,111,115,90,7,101,110,118,105, + 114,111,110,169,0,114,4,0,0,0,114,4,0,0,0,250, + 29,60,102,114,111,122,101,110,32,105,109,112,111,114,116,108, + 105,98,46,95,98,111,111,116,115,116,114,97,112,62,218,11, + 95,114,101,108,97,120,95,99,97,115,101,30,0,0,0,115, + 2,0,0,0,0,2,122,37,95,109,97,107,101,95,114,101, + 108,97,120,95,99,97,115,101,46,60,108,111,99,97,108,115, + 62,46,95,114,101,108,97,120,95,99,97,115,101,99,0,0, + 0,0,0,0,0,0,0,0,0,0,1,0,0,0,83,0, + 0,0,115,4,0,0,0,100,1,0,83,41,2,122,53,84, + 114,117,101,32,105,102,32,102,105,108,101,110,97,109,101,115, + 32,109,117,115,116,32,98,101,32,99,104,101,99,107,101,100, + 32,99,97,115,101,45,105,110,115,101,110,115,105,116,105,118, + 101,108,121,46,70,114,4,0,0,0,114,4,0,0,0,114, + 4,0,0,0,114,4,0,0,0,114,5,0,0,0,114,6, + 0,0,0,34,0,0,0,115,2,0,0,0,0,2,41,4, + 218,3,115,121,115,218,8,112,108,97,116,102,111,114,109,218, + 10,115,116,97,114,116,115,119,105,116,104,218,27,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,41,1,114,6,0,0,0,114, + 4,0,0,0,114,4,0,0,0,114,5,0,0,0,218,16, + 95,109,97,107,101,95,114,101,108,97,120,95,99,97,115,101, + 28,0,0,0,115,8,0,0,0,0,1,18,1,15,4,12, + 3,114,11,0,0,0,99,1,0,0,0,0,0,0,0,1, + 0,0,0,3,0,0,0,67,0,0,0,115,26,0,0,0, + 116,0,0,124,0,0,131,1,0,100,1,0,64,106,1,0, + 100,2,0,100,3,0,131,2,0,83,41,4,122,42,67,111, + 110,118,101,114,116,32,97,32,51,50,45,98,105,116,32,105, + 110,116,101,103,101,114,32,116,111,32,108,105,116,116,108,101, + 45,101,110,100,105,97,110,46,108,3,0,0,0,255,127,255, + 127,3,0,233,4,0,0,0,218,6,108,105,116,116,108,101, + 41,2,218,3,105,110,116,218,8,116,111,95,98,121,116,101, + 115,41,1,218,1,120,114,4,0,0,0,114,4,0,0,0, + 114,5,0,0,0,218,7,95,119,95,108,111,110,103,40,0, + 0,0,115,2,0,0,0,0,2,114,17,0,0,0,99,1, + 0,0,0,0,0,0,0,1,0,0,0,3,0,0,0,67, + 0,0,0,115,16,0,0,0,116,0,0,106,1,0,124,0, + 0,100,1,0,131,2,0,83,41,2,122,47,67,111,110,118, + 101,114,116,32,52,32,98,121,116,101,115,32,105,110,32,108, + 105,116,116,108,101,45,101,110,100,105,97,110,32,116,111,32, + 97,110,32,105,110,116,101,103,101,114,46,114,13,0,0,0, + 41,2,114,14,0,0,0,218,10,102,114,111,109,95,98,121, + 116,101,115,41,1,90,9,105,110,116,95,98,121,116,101,115, + 114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,218, + 7,95,114,95,108,111,110,103,45,0,0,0,115,2,0,0, + 0,0,2,114,19,0,0,0,99,0,0,0,0,0,0,0, + 0,1,0,0,0,3,0,0,0,71,0,0,0,115,26,0, + 0,0,116,0,0,106,1,0,100,1,0,100,2,0,132,0, + 0,124,0,0,68,131,1,0,131,1,0,83,41,3,122,31, + 82,101,112,108,97,99,101,109,101,110,116,32,102,111,114,32, + 111,115,46,112,97,116,104,46,106,111,105,110,40,41,46,99, + 1,0,0,0,0,0,0,0,2,0,0,0,4,0,0,0, + 83,0,0,0,115,37,0,0,0,103,0,0,124,0,0,93, + 27,0,125,1,0,124,1,0,114,6,0,124,1,0,106,0, + 0,116,1,0,131,1,0,145,2,0,113,6,0,83,114,4, + 0,0,0,41,2,218,6,114,115,116,114,105,112,218,15,112, + 97,116,104,95,115,101,112,97,114,97,116,111,114,115,41,2, + 218,2,46,48,218,4,112,97,114,116,114,4,0,0,0,114, + 4,0,0,0,114,5,0,0,0,250,10,60,108,105,115,116, + 99,111,109,112,62,52,0,0,0,115,2,0,0,0,9,1, + 122,30,95,112,97,116,104,95,106,111,105,110,46,60,108,111, + 99,97,108,115,62,46,60,108,105,115,116,99,111,109,112,62, + 41,2,218,8,112,97,116,104,95,115,101,112,218,4,106,111, + 105,110,41,1,218,10,112,97,116,104,95,112,97,114,116,115, + 114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,218, + 10,95,112,97,116,104,95,106,111,105,110,50,0,0,0,115, + 4,0,0,0,0,2,15,1,114,28,0,0,0,99,1,0, + 0,0,0,0,0,0,5,0,0,0,5,0,0,0,67,0, + 0,0,115,134,0,0,0,116,0,0,116,1,0,131,1,0, + 100,1,0,107,2,0,114,52,0,124,0,0,106,2,0,116, + 3,0,131,1,0,92,3,0,125,1,0,125,2,0,125,3, + 0,124,1,0,124,3,0,102,2,0,83,120,69,0,116,4, + 0,124,0,0,131,1,0,68,93,55,0,125,4,0,124,4, + 0,116,1,0,107,6,0,114,65,0,124,0,0,106,5,0, + 124,4,0,100,2,0,100,1,0,131,1,1,92,2,0,125, + 1,0,125,3,0,124,1,0,124,3,0,102,2,0,83,113, + 65,0,87,100,3,0,124,0,0,102,2,0,83,41,4,122, + 32,82,101,112,108,97,99,101,109,101,110,116,32,102,111,114, + 32,111,115,46,112,97,116,104,46,115,112,108,105,116,40,41, + 46,233,1,0,0,0,90,8,109,97,120,115,112,108,105,116, + 218,0,41,6,218,3,108,101,110,114,21,0,0,0,218,10, + 114,112,97,114,116,105,116,105,111,110,114,25,0,0,0,218, + 8,114,101,118,101,114,115,101,100,218,6,114,115,112,108,105, + 116,41,5,218,4,112,97,116,104,90,5,102,114,111,110,116, + 218,1,95,218,4,116,97,105,108,114,16,0,0,0,114,4, + 0,0,0,114,4,0,0,0,114,5,0,0,0,218,11,95, + 112,97,116,104,95,115,112,108,105,116,56,0,0,0,115,16, + 0,0,0,0,2,18,1,24,1,10,1,19,1,12,1,27, + 1,14,1,114,38,0,0,0,99,1,0,0,0,0,0,0, + 0,1,0,0,0,2,0,0,0,67,0,0,0,115,13,0, + 0,0,116,0,0,106,1,0,124,0,0,131,1,0,83,41, + 1,122,126,83,116,97,116,32,116,104,101,32,112,97,116,104, + 46,10,10,32,32,32,32,77,97,100,101,32,97,32,115,101, + 112,97,114,97,116,101,32,102,117,110,99,116,105,111,110,32, + 116,111,32,109,97,107,101,32,105,116,32,101,97,115,105,101, + 114,32,116,111,32,111,118,101,114,114,105,100,101,32,105,110, + 32,101,120,112,101,114,105,109,101,110,116,115,10,32,32,32, + 32,40,101,46,103,46,32,99,97,99,104,101,32,115,116,97, + 116,32,114,101,115,117,108,116,115,41,46,10,10,32,32,32, + 32,41,2,114,3,0,0,0,90,4,115,116,97,116,41,1, + 114,35,0,0,0,114,4,0,0,0,114,4,0,0,0,114, + 5,0,0,0,218,10,95,112,97,116,104,95,115,116,97,116, + 68,0,0,0,115,2,0,0,0,0,7,114,39,0,0,0, + 99,2,0,0,0,0,0,0,0,3,0,0,0,11,0,0, + 0,67,0,0,0,115,58,0,0,0,121,16,0,116,0,0, + 124,0,0,131,1,0,125,2,0,87,110,22,0,4,116,1, + 0,107,10,0,114,40,0,1,1,1,100,1,0,83,89,110, + 1,0,88,124,2,0,106,2,0,100,2,0,64,124,1,0, + 107,2,0,83,41,3,122,49,84,101,115,116,32,119,104,101, + 116,104,101,114,32,116,104,101,32,112,97,116,104,32,105,115, + 32,116,104,101,32,115,112,101,99,105,102,105,101,100,32,109, + 111,100,101,32,116,121,112,101,46,70,105,0,240,0,0,41, + 3,114,39,0,0,0,218,7,79,83,69,114,114,111,114,218, + 7,115,116,95,109,111,100,101,41,3,114,35,0,0,0,218, + 4,109,111,100,101,90,9,115,116,97,116,95,105,110,102,111, + 114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,218, + 18,95,112,97,116,104,95,105,115,95,109,111,100,101,95,116, + 121,112,101,78,0,0,0,115,10,0,0,0,0,2,3,1, + 16,1,13,1,9,1,114,43,0,0,0,99,1,0,0,0, + 0,0,0,0,1,0,0,0,3,0,0,0,67,0,0,0, + 115,13,0,0,0,116,0,0,124,0,0,100,1,0,131,2, + 0,83,41,2,122,31,82,101,112,108,97,99,101,109,101,110, + 116,32,102,111,114,32,111,115,46,112,97,116,104,46,105,115, + 102,105,108,101,46,105,0,128,0,0,41,1,114,43,0,0, + 0,41,1,114,35,0,0,0,114,4,0,0,0,114,4,0, + 0,0,114,5,0,0,0,218,12,95,112,97,116,104,95,105, + 115,102,105,108,101,87,0,0,0,115,2,0,0,0,0,2, + 114,44,0,0,0,99,1,0,0,0,0,0,0,0,1,0, + 0,0,3,0,0,0,67,0,0,0,115,31,0,0,0,124, + 0,0,115,18,0,116,0,0,106,1,0,131,0,0,125,0, + 0,116,2,0,124,0,0,100,1,0,131,2,0,83,41,2, + 122,30,82,101,112,108,97,99,101,109,101,110,116,32,102,111, + 114,32,111,115,46,112,97,116,104,46,105,115,100,105,114,46, + 105,0,64,0,0,41,3,114,3,0,0,0,218,6,103,101, + 116,99,119,100,114,43,0,0,0,41,1,114,35,0,0,0, + 114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,218, + 11,95,112,97,116,104,95,105,115,100,105,114,92,0,0,0, + 115,6,0,0,0,0,2,6,1,12,1,114,46,0,0,0, + 105,182,1,0,0,99,3,0,0,0,0,0,0,0,6,0, + 0,0,17,0,0,0,67,0,0,0,115,192,0,0,0,100, + 1,0,106,0,0,124,0,0,116,1,0,124,0,0,131,1, + 0,131,2,0,125,3,0,116,2,0,106,3,0,124,3,0, + 116,2,0,106,4,0,116,2,0,106,5,0,66,116,2,0, + 106,6,0,66,124,2,0,100,2,0,64,131,3,0,125,4, + 0,121,60,0,116,7,0,106,8,0,124,4,0,100,3,0, + 131,2,0,143,20,0,125,5,0,124,5,0,106,9,0,124, + 1,0,131,1,0,1,87,100,4,0,81,88,116,2,0,106, + 10,0,124,3,0,124,0,0,131,2,0,1,87,110,59,0, + 4,116,11,0,107,10,0,114,187,0,1,1,1,121,17,0, + 116,2,0,106,12,0,124,3,0,131,1,0,1,87,110,18, + 0,4,116,11,0,107,10,0,114,179,0,1,1,1,89,110, + 1,0,88,130,0,0,89,110,1,0,88,100,4,0,83,41, + 5,122,162,66,101,115,116,45,101,102,102,111,114,116,32,102, + 117,110,99,116,105,111,110,32,116,111,32,119,114,105,116,101, + 32,100,97,116,97,32,116,111,32,97,32,112,97,116,104,32, + 97,116,111,109,105,99,97,108,108,121,46,10,32,32,32,32, + 66,101,32,112,114,101,112,97,114,101,100,32,116,111,32,104, + 97,110,100,108,101,32,97,32,70,105,108,101,69,120,105,115, + 116,115,69,114,114,111,114,32,105,102,32,99,111,110,99,117, + 114,114,101,110,116,32,119,114,105,116,105,110,103,32,111,102, + 32,116,104,101,10,32,32,32,32,116,101,109,112,111,114,97, + 114,121,32,102,105,108,101,32,105,115,32,97,116,116,101,109, + 112,116,101,100,46,122,5,123,125,46,123,125,105,182,1,0, + 0,90,2,119,98,78,41,13,218,6,102,111,114,109,97,116, + 218,2,105,100,114,3,0,0,0,90,4,111,112,101,110,90, + 6,79,95,69,88,67,76,90,7,79,95,67,82,69,65,84, + 90,8,79,95,87,82,79,78,76,89,218,3,95,105,111,218, + 6,70,105,108,101,73,79,218,5,119,114,105,116,101,218,7, + 114,101,112,108,97,99,101,114,40,0,0,0,90,6,117,110, + 108,105,110,107,41,6,114,35,0,0,0,218,4,100,97,116, + 97,114,42,0,0,0,90,8,112,97,116,104,95,116,109,112, + 90,2,102,100,218,4,102,105,108,101,114,4,0,0,0,114, + 4,0,0,0,114,5,0,0,0,218,13,95,119,114,105,116, + 101,95,97,116,111,109,105,99,99,0,0,0,115,26,0,0, + 0,0,5,24,1,9,1,33,1,3,3,21,1,19,1,20, + 1,13,1,3,1,17,1,13,1,5,1,114,55,0,0,0, + 99,2,0,0,0,0,0,0,0,3,0,0,0,7,0,0, + 0,67,0,0,0,115,92,0,0,0,120,66,0,100,1,0, + 100,2,0,100,3,0,100,4,0,103,4,0,68,93,46,0, + 125,2,0,116,0,0,124,1,0,124,2,0,131,2,0,114, + 19,0,116,1,0,124,0,0,124,2,0,116,2,0,124,1, + 0,124,2,0,131,2,0,131,3,0,1,113,19,0,87,124, + 0,0,106,3,0,106,4,0,124,1,0,106,3,0,131,1, + 0,1,100,5,0,83,41,6,122,47,83,105,109,112,108,101, + 32,115,117,98,115,116,105,116,117,116,101,32,102,111,114,32, + 102,117,110,99,116,111,111,108,115,46,117,112,100,97,116,101, + 95,119,114,97,112,112,101,114,46,218,10,95,95,109,111,100, + 117,108,101,95,95,218,8,95,95,110,97,109,101,95,95,218, + 12,95,95,113,117,97,108,110,97,109,101,95,95,218,7,95, + 95,100,111,99,95,95,78,41,5,218,7,104,97,115,97,116, + 116,114,218,7,115,101,116,97,116,116,114,218,7,103,101,116, + 97,116,116,114,218,8,95,95,100,105,99,116,95,95,218,6, + 117,112,100,97,116,101,41,3,90,3,110,101,119,90,3,111, + 108,100,114,52,0,0,0,114,4,0,0,0,114,4,0,0, + 0,114,5,0,0,0,218,5,95,119,114,97,112,121,0,0, + 0,115,8,0,0,0,0,2,25,1,15,1,29,1,114,65, 0,0,0,99,1,0,0,0,0,0,0,0,1,0,0,0, - 3,0,0,0,67,0,0,0,115,34,0,0,0,124,0,0, - 115,21,0,116,0,0,106,1,0,131,0,0,125,0,0,110, - 0,0,116,2,0,124,0,0,100,1,0,131,2,0,83,41, - 2,122,30,82,101,112,108,97,99,101,109,101,110,116,32,102, - 111,114,32,111,115,46,112,97,116,104,46,105,115,100,105,114, - 46,105,0,64,0,0,41,3,114,3,0,0,0,218,6,103, - 101,116,99,119,100,114,43,0,0,0,41,1,114,35,0,0, + 2,0,0,0,67,0,0,0,115,16,0,0,0,116,0,0, + 116,1,0,131,1,0,124,0,0,131,1,0,83,41,1,78, + 41,2,218,4,116,121,112,101,114,7,0,0,0,41,1,218, + 4,110,97,109,101,114,4,0,0,0,114,4,0,0,0,114, + 5,0,0,0,218,11,95,110,101,119,95,109,111,100,117,108, + 101,129,0,0,0,115,2,0,0,0,0,1,114,68,0,0, + 0,99,0,0,0,0,0,0,0,0,0,0,0,0,2,0, + 0,0,64,0,0,0,115,58,0,0,0,101,0,0,90,1, + 0,100,0,0,90,2,0,100,1,0,90,3,0,100,2,0, + 100,3,0,132,0,0,90,4,0,100,4,0,100,5,0,132, + 0,0,90,5,0,100,6,0,100,7,0,132,0,0,90,6, + 0,100,8,0,83,41,9,218,13,95,77,97,110,97,103,101, + 82,101,108,111,97,100,122,63,77,97,110,97,103,101,115,32, + 116,104,101,32,112,111,115,115,105,98,108,101,32,99,108,101, + 97,110,45,117,112,32,111,102,32,115,121,115,46,109,111,100, + 117,108,101,115,32,102,111,114,32,108,111,97,100,95,109,111, + 100,117,108,101,40,41,46,99,2,0,0,0,0,0,0,0, + 2,0,0,0,2,0,0,0,67,0,0,0,115,13,0,0, + 0,124,1,0,124,0,0,95,0,0,100,0,0,83,41,1, + 78,41,1,218,5,95,110,97,109,101,41,2,218,4,115,101, + 108,102,114,67,0,0,0,114,4,0,0,0,114,4,0,0, + 0,114,5,0,0,0,218,8,95,95,105,110,105,116,95,95, + 141,0,0,0,115,2,0,0,0,0,1,122,22,95,77,97, + 110,97,103,101,82,101,108,111,97,100,46,95,95,105,110,105, + 116,95,95,99,1,0,0,0,0,0,0,0,1,0,0,0, + 2,0,0,0,67,0,0,0,115,25,0,0,0,124,0,0, + 106,0,0,116,1,0,106,2,0,107,6,0,124,0,0,95, + 3,0,100,0,0,83,41,1,78,41,4,114,70,0,0,0, + 114,7,0,0,0,218,7,109,111,100,117,108,101,115,218,10, + 95,105,115,95,114,101,108,111,97,100,41,1,114,71,0,0, 0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, - 218,11,95,112,97,116,104,95,105,115,100,105,114,92,0,0, - 0,115,6,0,0,0,0,2,6,1,15,1,114,46,0,0, - 0,105,182,1,0,0,99,3,0,0,0,0,0,0,0,6, - 0,0,0,17,0,0,0,67,0,0,0,115,192,0,0,0, - 100,1,0,106,0,0,124,0,0,116,1,0,124,0,0,131, - 1,0,131,2,0,125,3,0,116,2,0,106,3,0,124,3, - 0,116,2,0,106,4,0,116,2,0,106,5,0,66,116,2, - 0,106,6,0,66,124,2,0,100,2,0,64,131,3,0,125, - 4,0,121,60,0,116,7,0,106,8,0,124,4,0,100,3, - 0,131,2,0,143,20,0,125,5,0,124,5,0,106,9,0, - 124,1,0,131,1,0,1,87,100,4,0,81,88,116,2,0, - 106,10,0,124,3,0,124,0,0,131,2,0,1,87,110,59, - 0,4,116,11,0,107,10,0,114,187,0,1,1,1,121,17, - 0,116,2,0,106,12,0,124,3,0,131,1,0,1,87,110, - 18,0,4,116,11,0,107,10,0,114,179,0,1,1,1,89, - 110,1,0,88,130,0,0,89,110,1,0,88,100,4,0,83, - 41,5,122,162,66,101,115,116,45,101,102,102,111,114,116,32, - 102,117,110,99,116,105,111,110,32,116,111,32,119,114,105,116, - 101,32,100,97,116,97,32,116,111,32,97,32,112,97,116,104, - 32,97,116,111,109,105,99,97,108,108,121,46,10,32,32,32, - 32,66,101,32,112,114,101,112,97,114,101,100,32,116,111,32, - 104,97,110,100,108,101,32,97,32,70,105,108,101,69,120,105, - 115,116,115,69,114,114,111,114,32,105,102,32,99,111,110,99, - 117,114,114,101,110,116,32,119,114,105,116,105,110,103,32,111, - 102,32,116,104,101,10,32,32,32,32,116,101,109,112,111,114, - 97,114,121,32,102,105,108,101,32,105,115,32,97,116,116,101, - 109,112,116,101,100,46,122,5,123,125,46,123,125,105,182,1, - 0,0,90,2,119,98,78,41,13,218,6,102,111,114,109,97, - 116,218,2,105,100,114,3,0,0,0,90,4,111,112,101,110, - 90,6,79,95,69,88,67,76,90,7,79,95,67,82,69,65, - 84,90,8,79,95,87,82,79,78,76,89,218,3,95,105,111, - 218,6,70,105,108,101,73,79,218,5,119,114,105,116,101,218, - 7,114,101,112,108,97,99,101,114,40,0,0,0,90,6,117, - 110,108,105,110,107,41,6,114,35,0,0,0,218,4,100,97, - 116,97,114,42,0,0,0,90,8,112,97,116,104,95,116,109, - 112,90,2,102,100,218,4,102,105,108,101,114,4,0,0,0, - 114,4,0,0,0,114,5,0,0,0,218,13,95,119,114,105, - 116,101,95,97,116,111,109,105,99,99,0,0,0,115,26,0, - 0,0,0,5,24,1,9,1,33,1,3,3,21,1,19,1, - 20,1,13,1,3,1,17,1,13,1,5,1,114,55,0,0, - 0,99,2,0,0,0,0,0,0,0,3,0,0,0,7,0, - 0,0,67,0,0,0,115,95,0,0,0,120,69,0,100,1, - 0,100,2,0,100,3,0,100,4,0,103,4,0,68,93,49, - 0,125,2,0,116,0,0,124,1,0,124,2,0,131,2,0, - 114,19,0,116,1,0,124,0,0,124,2,0,116,2,0,124, - 1,0,124,2,0,131,2,0,131,3,0,1,113,19,0,113, - 19,0,87,124,0,0,106,3,0,106,4,0,124,1,0,106, - 3,0,131,1,0,1,100,5,0,83,41,6,122,47,83,105, - 109,112,108,101,32,115,117,98,115,116,105,116,117,116,101,32, - 102,111,114,32,102,117,110,99,116,111,111,108,115,46,117,112, - 100,97,116,101,95,119,114,97,112,112,101,114,46,218,10,95, - 95,109,111,100,117,108,101,95,95,218,8,95,95,110,97,109, - 101,95,95,218,12,95,95,113,117,97,108,110,97,109,101,95, - 95,218,7,95,95,100,111,99,95,95,78,41,5,218,7,104, - 97,115,97,116,116,114,218,7,115,101,116,97,116,116,114,218, - 7,103,101,116,97,116,116,114,218,8,95,95,100,105,99,116, - 95,95,218,6,117,112,100,97,116,101,41,3,90,3,110,101, - 119,90,3,111,108,100,114,52,0,0,0,114,4,0,0,0, - 114,4,0,0,0,114,5,0,0,0,218,5,95,119,114,97, - 112,121,0,0,0,115,8,0,0,0,0,2,25,1,15,1, - 32,1,114,65,0,0,0,99,1,0,0,0,0,0,0,0, - 1,0,0,0,2,0,0,0,67,0,0,0,115,16,0,0, - 0,116,0,0,116,1,0,131,1,0,124,0,0,131,1,0, - 83,41,1,78,41,2,218,4,116,121,112,101,114,7,0,0, - 0,41,1,218,4,110,97,109,101,114,4,0,0,0,114,4, - 0,0,0,114,5,0,0,0,218,11,95,110,101,119,95,109, - 111,100,117,108,101,129,0,0,0,115,2,0,0,0,0,1, - 114,68,0,0,0,99,0,0,0,0,0,0,0,0,0,0, - 0,0,2,0,0,0,64,0,0,0,115,58,0,0,0,101, - 0,0,90,1,0,100,0,0,90,2,0,100,1,0,90,3, - 0,100,2,0,100,3,0,132,0,0,90,4,0,100,4,0, - 100,5,0,132,0,0,90,5,0,100,6,0,100,7,0,132, - 0,0,90,6,0,100,8,0,83,41,9,218,13,95,77,97, - 110,97,103,101,82,101,108,111,97,100,122,63,77,97,110,97, - 103,101,115,32,116,104,101,32,112,111,115,115,105,98,108,101, - 32,99,108,101,97,110,45,117,112,32,111,102,32,115,121,115, - 46,109,111,100,117,108,101,115,32,102,111,114,32,108,111,97, - 100,95,109,111,100,117,108,101,40,41,46,99,2,0,0,0, + 218,9,95,95,101,110,116,101,114,95,95,144,0,0,0,115, + 2,0,0,0,0,1,122,23,95,77,97,110,97,103,101,82, + 101,108,111,97,100,46,95,95,101,110,116,101,114,95,95,99, + 1,0,0,0,0,0,0,0,2,0,0,0,11,0,0,0, + 71,0,0,0,115,77,0,0,0,116,0,0,100,1,0,100, + 2,0,132,0,0,124,1,0,68,131,1,0,131,1,0,114, + 73,0,124,0,0,106,1,0,12,114,73,0,121,17,0,116, + 2,0,106,3,0,124,0,0,106,4,0,61,87,110,18,0, + 4,116,5,0,107,10,0,114,72,0,1,1,1,89,110,1, + 0,88,100,0,0,83,41,3,78,99,1,0,0,0,0,0, + 0,0,2,0,0,0,3,0,0,0,115,0,0,0,115,27, + 0,0,0,124,0,0,93,17,0,125,1,0,124,1,0,100, + 0,0,107,9,0,86,1,113,3,0,100,0,0,83,41,1, + 78,114,4,0,0,0,41,2,114,22,0,0,0,218,3,97, + 114,103,114,4,0,0,0,114,4,0,0,0,114,5,0,0, + 0,250,9,60,103,101,110,101,120,112,114,62,148,0,0,0, + 115,2,0,0,0,6,0,122,41,95,77,97,110,97,103,101, + 82,101,108,111,97,100,46,95,95,101,120,105,116,95,95,46, + 60,108,111,99,97,108,115,62,46,60,103,101,110,101,120,112, + 114,62,41,6,218,3,97,110,121,114,74,0,0,0,114,7, + 0,0,0,114,73,0,0,0,114,70,0,0,0,218,8,75, + 101,121,69,114,114,111,114,41,2,114,71,0,0,0,218,4, + 97,114,103,115,114,4,0,0,0,114,4,0,0,0,114,5, + 0,0,0,218,8,95,95,101,120,105,116,95,95,147,0,0, + 0,115,10,0,0,0,0,1,35,1,3,1,17,1,13,1, + 122,22,95,77,97,110,97,103,101,82,101,108,111,97,100,46, + 95,95,101,120,105,116,95,95,78,41,7,114,57,0,0,0, + 114,56,0,0,0,114,58,0,0,0,114,59,0,0,0,114, + 72,0,0,0,114,75,0,0,0,114,81,0,0,0,114,4, + 0,0,0,114,4,0,0,0,114,4,0,0,0,114,5,0, + 0,0,114,69,0,0,0,137,0,0,0,115,8,0,0,0, + 12,2,6,2,12,3,12,3,114,69,0,0,0,99,0,0, + 0,0,0,0,0,0,0,0,0,0,1,0,0,0,64,0, + 0,0,115,16,0,0,0,101,0,0,90,1,0,100,0,0, + 90,2,0,100,1,0,83,41,2,218,14,95,68,101,97,100, + 108,111,99,107,69,114,114,111,114,78,41,3,114,57,0,0, + 0,114,56,0,0,0,114,58,0,0,0,114,4,0,0,0, + 114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,114, + 82,0,0,0,162,0,0,0,115,2,0,0,0,12,1,114, + 82,0,0,0,99,0,0,0,0,0,0,0,0,0,0,0, + 0,2,0,0,0,64,0,0,0,115,82,0,0,0,101,0, + 0,90,1,0,100,0,0,90,2,0,100,1,0,90,3,0, + 100,2,0,100,3,0,132,0,0,90,4,0,100,4,0,100, + 5,0,132,0,0,90,5,0,100,6,0,100,7,0,132,0, + 0,90,6,0,100,8,0,100,9,0,132,0,0,90,7,0, + 100,10,0,100,11,0,132,0,0,90,8,0,100,12,0,83, + 41,13,218,11,95,77,111,100,117,108,101,76,111,99,107,122, + 169,65,32,114,101,99,117,114,115,105,118,101,32,108,111,99, + 107,32,105,109,112,108,101,109,101,110,116,97,116,105,111,110, + 32,119,104,105,99,104,32,105,115,32,97,98,108,101,32,116, + 111,32,100,101,116,101,99,116,32,100,101,97,100,108,111,99, + 107,115,10,32,32,32,32,40,101,46,103,46,32,116,104,114, + 101,97,100,32,49,32,116,114,121,105,110,103,32,116,111,32, + 116,97,107,101,32,108,111,99,107,115,32,65,32,116,104,101, + 110,32,66,44,32,97,110,100,32,116,104,114,101,97,100,32, + 50,32,116,114,121,105,110,103,32,116,111,10,32,32,32,32, + 116,97,107,101,32,108,111,99,107,115,32,66,32,116,104,101, + 110,32,65,41,46,10,32,32,32,32,99,2,0,0,0,0, + 0,0,0,2,0,0,0,2,0,0,0,67,0,0,0,115, + 70,0,0,0,116,0,0,106,1,0,131,0,0,124,0,0, + 95,2,0,116,0,0,106,1,0,131,0,0,124,0,0,95, + 3,0,124,1,0,124,0,0,95,4,0,100,0,0,124,0, + 0,95,5,0,100,1,0,124,0,0,95,6,0,100,1,0, + 124,0,0,95,7,0,100,0,0,83,41,2,78,233,0,0, + 0,0,41,8,218,7,95,116,104,114,101,97,100,90,13,97, + 108,108,111,99,97,116,101,95,108,111,99,107,218,4,108,111, + 99,107,218,6,119,97,107,101,117,112,114,67,0,0,0,218, + 5,111,119,110,101,114,218,5,99,111,117,110,116,218,7,119, + 97,105,116,101,114,115,41,2,114,71,0,0,0,114,67,0, + 0,0,114,4,0,0,0,114,4,0,0,0,114,5,0,0, + 0,114,72,0,0,0,172,0,0,0,115,12,0,0,0,0, + 1,15,1,15,1,9,1,9,1,9,1,122,20,95,77,111, + 100,117,108,101,76,111,99,107,46,95,95,105,110,105,116,95, + 95,99,1,0,0,0,0,0,0,0,4,0,0,0,2,0, + 0,0,67,0,0,0,115,88,0,0,0,116,0,0,106,1, + 0,131,0,0,125,1,0,124,0,0,106,2,0,125,2,0, + 120,60,0,116,3,0,106,4,0,124,2,0,131,1,0,125, + 3,0,124,3,0,100,0,0,107,8,0,114,55,0,100,1, + 0,83,124,3,0,106,2,0,125,2,0,124,2,0,124,1, + 0,107,2,0,114,24,0,100,2,0,83,113,24,0,87,100, + 0,0,83,41,3,78,70,84,41,5,114,85,0,0,0,218, + 9,103,101,116,95,105,100,101,110,116,114,88,0,0,0,218, + 12,95,98,108,111,99,107,105,110,103,95,111,110,218,3,103, + 101,116,41,4,114,71,0,0,0,218,2,109,101,218,3,116, + 105,100,114,86,0,0,0,114,4,0,0,0,114,4,0,0, + 0,114,5,0,0,0,218,12,104,97,115,95,100,101,97,100, + 108,111,99,107,180,0,0,0,115,18,0,0,0,0,2,12, + 1,9,1,3,1,15,1,12,1,4,1,9,1,12,1,122, + 24,95,77,111,100,117,108,101,76,111,99,107,46,104,97,115, + 95,100,101,97,100,108,111,99,107,99,1,0,0,0,0,0, + 0,0,2,0,0,0,16,0,0,0,67,0,0,0,115,209, + 0,0,0,116,0,0,106,1,0,131,0,0,125,1,0,124, + 0,0,116,2,0,124,1,0,60,122,172,0,120,165,0,124, + 0,0,106,3,0,143,124,0,1,124,0,0,106,4,0,100, + 1,0,107,2,0,115,68,0,124,0,0,106,5,0,124,1, + 0,107,2,0,114,96,0,124,1,0,124,0,0,95,5,0, + 124,0,0,4,106,4,0,100,2,0,55,2,95,4,0,100, + 3,0,83,124,0,0,106,6,0,131,0,0,114,124,0,116, + 7,0,100,4,0,124,0,0,22,131,1,0,130,1,0,124, + 0,0,106,8,0,106,9,0,100,5,0,131,1,0,114,157, + 0,124,0,0,4,106,10,0,100,2,0,55,2,95,10,0, + 87,100,6,0,81,88,124,0,0,106,8,0,106,9,0,131, + 0,0,1,124,0,0,106,8,0,106,11,0,131,0,0,1, + 113,28,0,87,87,100,6,0,116,2,0,124,1,0,61,88, + 100,6,0,83,41,7,122,185,10,32,32,32,32,32,32,32, + 32,65,99,113,117,105,114,101,32,116,104,101,32,109,111,100, + 117,108,101,32,108,111,99,107,46,32,32,73,102,32,97,32, + 112,111,116,101,110,116,105,97,108,32,100,101,97,100,108,111, + 99,107,32,105,115,32,100,101,116,101,99,116,101,100,44,10, + 32,32,32,32,32,32,32,32,97,32,95,68,101,97,100,108, + 111,99,107,69,114,114,111,114,32,105,115,32,114,97,105,115, + 101,100,46,10,32,32,32,32,32,32,32,32,79,116,104,101, + 114,119,105,115,101,44,32,116,104,101,32,108,111,99,107,32, + 105,115,32,97,108,119,97,121,115,32,97,99,113,117,105,114, + 101,100,32,97,110,100,32,84,114,117,101,32,105,115,32,114, + 101,116,117,114,110,101,100,46,10,32,32,32,32,32,32,32, + 32,114,84,0,0,0,114,29,0,0,0,84,122,23,100,101, + 97,100,108,111,99,107,32,100,101,116,101,99,116,101,100,32, + 98,121,32,37,114,70,78,41,12,114,85,0,0,0,114,91, + 0,0,0,114,92,0,0,0,114,86,0,0,0,114,89,0, + 0,0,114,88,0,0,0,114,96,0,0,0,114,82,0,0, + 0,114,87,0,0,0,218,7,97,99,113,117,105,114,101,114, + 90,0,0,0,218,7,114,101,108,101,97,115,101,41,2,114, + 71,0,0,0,114,95,0,0,0,114,4,0,0,0,114,4, + 0,0,0,114,5,0,0,0,114,97,0,0,0,192,0,0, + 0,115,32,0,0,0,0,6,12,1,10,1,3,1,3,1, + 10,1,30,1,9,1,15,1,4,1,12,1,16,1,18,1, + 21,2,13,1,21,2,122,19,95,77,111,100,117,108,101,76, + 111,99,107,46,97,99,113,117,105,114,101,99,1,0,0,0, + 0,0,0,0,2,0,0,0,10,0,0,0,67,0,0,0, + 115,156,0,0,0,116,0,0,106,1,0,131,0,0,125,1, + 0,124,0,0,106,2,0,143,129,0,1,124,0,0,106,3, + 0,124,1,0,107,3,0,114,49,0,116,4,0,100,1,0, + 131,1,0,130,1,0,124,0,0,106,5,0,100,2,0,107, + 4,0,115,70,0,116,6,0,130,1,0,124,0,0,4,106, + 5,0,100,3,0,56,2,95,5,0,124,0,0,106,5,0, + 100,2,0,107,2,0,114,146,0,100,0,0,124,0,0,95, + 3,0,124,0,0,106,7,0,114,146,0,124,0,0,4,106, + 7,0,100,3,0,56,2,95,7,0,124,0,0,106,8,0, + 106,9,0,131,0,0,1,87,100,0,0,81,88,100,0,0, + 83,41,4,78,122,31,99,97,110,110,111,116,32,114,101,108, + 101,97,115,101,32,117,110,45,97,99,113,117,105,114,101,100, + 32,108,111,99,107,114,84,0,0,0,114,29,0,0,0,41, + 10,114,85,0,0,0,114,91,0,0,0,114,86,0,0,0, + 114,88,0,0,0,218,12,82,117,110,116,105,109,101,69,114, + 114,111,114,114,89,0,0,0,218,14,65,115,115,101,114,116, + 105,111,110,69,114,114,111,114,114,90,0,0,0,114,87,0, + 0,0,114,98,0,0,0,41,2,114,71,0,0,0,114,95, + 0,0,0,114,4,0,0,0,114,4,0,0,0,114,5,0, + 0,0,114,98,0,0,0,217,0,0,0,115,22,0,0,0, + 0,1,12,1,10,1,15,1,12,1,21,1,15,1,15,1, + 9,1,9,1,15,1,122,19,95,77,111,100,117,108,101,76, + 111,99,107,46,114,101,108,101,97,115,101,99,1,0,0,0, + 0,0,0,0,1,0,0,0,4,0,0,0,67,0,0,0, + 115,25,0,0,0,100,1,0,106,0,0,124,0,0,106,1, + 0,116,2,0,124,0,0,131,1,0,131,2,0,83,41,2, + 78,122,23,95,77,111,100,117,108,101,76,111,99,107,40,123, + 33,114,125,41,32,97,116,32,123,125,41,3,114,47,0,0, + 0,114,67,0,0,0,114,48,0,0,0,41,1,114,71,0, + 0,0,114,4,0,0,0,114,4,0,0,0,114,5,0,0, + 0,218,8,95,95,114,101,112,114,95,95,230,0,0,0,115, + 2,0,0,0,0,1,122,20,95,77,111,100,117,108,101,76, + 111,99,107,46,95,95,114,101,112,114,95,95,78,41,9,114, + 57,0,0,0,114,56,0,0,0,114,58,0,0,0,114,59, + 0,0,0,114,72,0,0,0,114,96,0,0,0,114,97,0, + 0,0,114,98,0,0,0,114,101,0,0,0,114,4,0,0, + 0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, + 114,83,0,0,0,166,0,0,0,115,12,0,0,0,12,4, + 6,2,12,8,12,12,12,25,12,13,114,83,0,0,0,99, + 0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, + 64,0,0,0,115,70,0,0,0,101,0,0,90,1,0,100, + 0,0,90,2,0,100,1,0,90,3,0,100,2,0,100,3, + 0,132,0,0,90,4,0,100,4,0,100,5,0,132,0,0, + 90,5,0,100,6,0,100,7,0,132,0,0,90,6,0,100, + 8,0,100,9,0,132,0,0,90,7,0,100,10,0,83,41, + 11,218,16,95,68,117,109,109,121,77,111,100,117,108,101,76, + 111,99,107,122,86,65,32,115,105,109,112,108,101,32,95,77, + 111,100,117,108,101,76,111,99,107,32,101,113,117,105,118,97, + 108,101,110,116,32,102,111,114,32,80,121,116,104,111,110,32, + 98,117,105,108,100,115,32,119,105,116,104,111,117,116,10,32, + 32,32,32,109,117,108,116,105,45,116,104,114,101,97,100,105, + 110,103,32,115,117,112,112,111,114,116,46,99,2,0,0,0, 0,0,0,0,2,0,0,0,2,0,0,0,67,0,0,0, - 115,13,0,0,0,124,1,0,124,0,0,95,0,0,100,0, - 0,83,41,1,78,41,1,218,5,95,110,97,109,101,41,2, - 218,4,115,101,108,102,114,67,0,0,0,114,4,0,0,0, - 114,4,0,0,0,114,5,0,0,0,218,8,95,95,105,110, - 105,116,95,95,141,0,0,0,115,2,0,0,0,0,1,122, - 22,95,77,97,110,97,103,101,82,101,108,111,97,100,46,95, + 115,22,0,0,0,124,1,0,124,0,0,95,0,0,100,1, + 0,124,0,0,95,1,0,100,0,0,83,41,2,78,114,84, + 0,0,0,41,2,114,67,0,0,0,114,89,0,0,0,41, + 2,114,71,0,0,0,114,67,0,0,0,114,4,0,0,0, + 114,4,0,0,0,114,5,0,0,0,114,72,0,0,0,238, + 0,0,0,115,4,0,0,0,0,1,9,1,122,25,95,68, + 117,109,109,121,77,111,100,117,108,101,76,111,99,107,46,95, 95,105,110,105,116,95,95,99,1,0,0,0,0,0,0,0, - 1,0,0,0,2,0,0,0,67,0,0,0,115,25,0,0, - 0,124,0,0,106,0,0,116,1,0,106,2,0,107,6,0, - 124,0,0,95,3,0,100,0,0,83,41,1,78,41,4,114, - 70,0,0,0,114,7,0,0,0,218,7,109,111,100,117,108, - 101,115,218,10,95,105,115,95,114,101,108,111,97,100,41,1, - 114,71,0,0,0,114,4,0,0,0,114,4,0,0,0,114, - 5,0,0,0,218,9,95,95,101,110,116,101,114,95,95,144, - 0,0,0,115,2,0,0,0,0,1,122,23,95,77,97,110, - 97,103,101,82,101,108,111,97,100,46,95,95,101,110,116,101, - 114,95,95,99,1,0,0,0,0,0,0,0,2,0,0,0, - 12,0,0,0,71,0,0,0,115,80,0,0,0,116,0,0, - 100,1,0,100,2,0,132,0,0,124,1,0,68,131,1,0, - 131,1,0,114,76,0,124,0,0,106,1,0,12,114,76,0, - 121,17,0,116,2,0,106,3,0,124,0,0,106,4,0,61, - 87,113,76,0,4,116,5,0,107,10,0,114,72,0,1,1, - 1,89,113,76,0,88,110,0,0,100,0,0,83,41,3,78, - 99,1,0,0,0,0,0,0,0,2,0,0,0,3,0,0, - 0,115,0,0,0,115,27,0,0,0,124,0,0,93,17,0, - 125,1,0,124,1,0,100,0,0,107,9,0,86,1,113,3, - 0,100,0,0,83,41,1,78,114,4,0,0,0,41,2,114, - 22,0,0,0,218,3,97,114,103,114,4,0,0,0,114,4, - 0,0,0,114,5,0,0,0,250,9,60,103,101,110,101,120, - 112,114,62,148,0,0,0,115,2,0,0,0,6,0,122,41, - 95,77,97,110,97,103,101,82,101,108,111,97,100,46,95,95, - 101,120,105,116,95,95,46,60,108,111,99,97,108,115,62,46, - 60,103,101,110,101,120,112,114,62,41,6,218,3,97,110,121, - 114,74,0,0,0,114,7,0,0,0,114,73,0,0,0,114, - 70,0,0,0,218,8,75,101,121,69,114,114,111,114,41,2, - 114,71,0,0,0,218,4,97,114,103,115,114,4,0,0,0, - 114,4,0,0,0,114,5,0,0,0,218,8,95,95,101,120, - 105,116,95,95,147,0,0,0,115,10,0,0,0,0,1,35, - 1,3,1,17,1,13,1,122,22,95,77,97,110,97,103,101, - 82,101,108,111,97,100,46,95,95,101,120,105,116,95,95,78, - 41,7,114,57,0,0,0,114,56,0,0,0,114,58,0,0, - 0,114,59,0,0,0,114,72,0,0,0,114,75,0,0,0, - 114,81,0,0,0,114,4,0,0,0,114,4,0,0,0,114, - 4,0,0,0,114,5,0,0,0,114,69,0,0,0,137,0, - 0,0,115,8,0,0,0,12,2,6,2,12,3,12,3,114, - 69,0,0,0,99,0,0,0,0,0,0,0,0,0,0,0, - 0,1,0,0,0,64,0,0,0,115,16,0,0,0,101,0, - 0,90,1,0,100,0,0,90,2,0,100,1,0,83,41,2, - 218,14,95,68,101,97,100,108,111,99,107,69,114,114,111,114, - 78,41,3,114,57,0,0,0,114,56,0,0,0,114,58,0, - 0,0,114,4,0,0,0,114,4,0,0,0,114,4,0,0, - 0,114,5,0,0,0,114,82,0,0,0,162,0,0,0,115, - 2,0,0,0,12,1,114,82,0,0,0,99,0,0,0,0, - 0,0,0,0,0,0,0,0,2,0,0,0,64,0,0,0, - 115,82,0,0,0,101,0,0,90,1,0,100,0,0,90,2, - 0,100,1,0,90,3,0,100,2,0,100,3,0,132,0,0, - 90,4,0,100,4,0,100,5,0,132,0,0,90,5,0,100, - 6,0,100,7,0,132,0,0,90,6,0,100,8,0,100,9, - 0,132,0,0,90,7,0,100,10,0,100,11,0,132,0,0, - 90,8,0,100,12,0,83,41,13,218,11,95,77,111,100,117, - 108,101,76,111,99,107,122,169,65,32,114,101,99,117,114,115, - 105,118,101,32,108,111,99,107,32,105,109,112,108,101,109,101, - 110,116,97,116,105,111,110,32,119,104,105,99,104,32,105,115, - 32,97,98,108,101,32,116,111,32,100,101,116,101,99,116,32, - 100,101,97,100,108,111,99,107,115,10,32,32,32,32,40,101, - 46,103,46,32,116,104,114,101,97,100,32,49,32,116,114,121, - 105,110,103,32,116,111,32,116,97,107,101,32,108,111,99,107, - 115,32,65,32,116,104,101,110,32,66,44,32,97,110,100,32, - 116,104,114,101,97,100,32,50,32,116,114,121,105,110,103,32, - 116,111,10,32,32,32,32,116,97,107,101,32,108,111,99,107, - 115,32,66,32,116,104,101,110,32,65,41,46,10,32,32,32, - 32,99,2,0,0,0,0,0,0,0,2,0,0,0,2,0, - 0,0,67,0,0,0,115,70,0,0,0,116,0,0,106,1, - 0,131,0,0,124,0,0,95,2,0,116,0,0,106,1,0, - 131,0,0,124,0,0,95,3,0,124,1,0,124,0,0,95, - 4,0,100,0,0,124,0,0,95,5,0,100,1,0,124,0, - 0,95,6,0,100,1,0,124,0,0,95,7,0,100,0,0, - 83,41,2,78,233,0,0,0,0,41,8,218,7,95,116,104, - 114,101,97,100,90,13,97,108,108,111,99,97,116,101,95,108, - 111,99,107,218,4,108,111,99,107,218,6,119,97,107,101,117, - 112,114,67,0,0,0,218,5,111,119,110,101,114,218,5,99, - 111,117,110,116,218,7,119,97,105,116,101,114,115,41,2,114, - 71,0,0,0,114,67,0,0,0,114,4,0,0,0,114,4, - 0,0,0,114,5,0,0,0,114,72,0,0,0,172,0,0, - 0,115,12,0,0,0,0,1,15,1,15,1,9,1,9,1, - 9,1,122,20,95,77,111,100,117,108,101,76,111,99,107,46, - 95,95,105,110,105,116,95,95,99,1,0,0,0,0,0,0, - 0,4,0,0,0,2,0,0,0,67,0,0,0,115,87,0, - 0,0,116,0,0,106,1,0,131,0,0,125,1,0,124,0, - 0,106,2,0,125,2,0,120,59,0,116,3,0,106,4,0, - 124,2,0,131,1,0,125,3,0,124,3,0,100,0,0,107, - 8,0,114,55,0,100,1,0,83,124,3,0,106,2,0,125, - 2,0,124,2,0,124,1,0,107,2,0,114,24,0,100,2, - 0,83,113,24,0,100,0,0,83,41,3,78,70,84,41,5, - 114,85,0,0,0,218,9,103,101,116,95,105,100,101,110,116, - 114,88,0,0,0,218,12,95,98,108,111,99,107,105,110,103, - 95,111,110,218,3,103,101,116,41,4,114,71,0,0,0,218, - 2,109,101,218,3,116,105,100,114,86,0,0,0,114,4,0, - 0,0,114,4,0,0,0,114,5,0,0,0,218,12,104,97, - 115,95,100,101,97,100,108,111,99,107,180,0,0,0,115,18, - 0,0,0,0,2,12,1,9,1,3,1,15,1,12,1,4, - 1,9,1,12,1,122,24,95,77,111,100,117,108,101,76,111, - 99,107,46,104,97,115,95,100,101,97,100,108,111,99,107,99, - 1,0,0,0,0,0,0,0,2,0,0,0,17,0,0,0, - 67,0,0,0,115,214,0,0,0,116,0,0,106,1,0,131, - 0,0,125,1,0,124,0,0,116,2,0,124,1,0,60,122, - 177,0,120,170,0,124,0,0,106,3,0,143,130,0,1,124, - 0,0,106,4,0,100,1,0,107,2,0,115,68,0,124,0, - 0,106,5,0,124,1,0,107,2,0,114,96,0,124,1,0, - 124,0,0,95,5,0,124,0,0,4,106,4,0,100,2,0, - 55,2,95,4,0,100,3,0,83,124,0,0,106,6,0,131, - 0,0,114,127,0,116,7,0,100,4,0,124,0,0,22,131, - 1,0,130,1,0,110,0,0,124,0,0,106,8,0,106,9, - 0,100,5,0,131,1,0,114,163,0,124,0,0,4,106,10, - 0,100,2,0,55,2,95,10,0,110,0,0,87,100,6,0, - 81,88,124,0,0,106,8,0,106,9,0,131,0,0,1,124, - 0,0,106,8,0,106,11,0,131,0,0,1,113,28,0,87, - 100,6,0,116,2,0,124,1,0,61,88,100,6,0,83,41, - 7,122,185,10,32,32,32,32,32,32,32,32,65,99,113,117, - 105,114,101,32,116,104,101,32,109,111,100,117,108,101,32,108, - 111,99,107,46,32,32,73,102,32,97,32,112,111,116,101,110, - 116,105,97,108,32,100,101,97,100,108,111,99,107,32,105,115, - 32,100,101,116,101,99,116,101,100,44,10,32,32,32,32,32, - 32,32,32,97,32,95,68,101,97,100,108,111,99,107,69,114, - 114,111,114,32,105,115,32,114,97,105,115,101,100,46,10,32, - 32,32,32,32,32,32,32,79,116,104,101,114,119,105,115,101, - 44,32,116,104,101,32,108,111,99,107,32,105,115,32,97,108, - 119,97,121,115,32,97,99,113,117,105,114,101,100,32,97,110, - 100,32,84,114,117,101,32,105,115,32,114,101,116,117,114,110, - 101,100,46,10,32,32,32,32,32,32,32,32,114,84,0,0, - 0,114,29,0,0,0,84,122,23,100,101,97,100,108,111,99, - 107,32,100,101,116,101,99,116,101,100,32,98,121,32,37,114, - 70,78,41,12,114,85,0,0,0,114,91,0,0,0,114,92, - 0,0,0,114,86,0,0,0,114,89,0,0,0,114,88,0, - 0,0,114,96,0,0,0,114,82,0,0,0,114,87,0,0, - 0,218,7,97,99,113,117,105,114,101,114,90,0,0,0,218, - 7,114,101,108,101,97,115,101,41,2,114,71,0,0,0,114, - 95,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5, - 0,0,0,114,97,0,0,0,192,0,0,0,115,32,0,0, - 0,0,6,12,1,10,1,3,1,3,1,10,1,30,1,9, - 1,15,1,4,1,12,1,19,1,18,1,24,2,13,1,20, - 2,122,19,95,77,111,100,117,108,101,76,111,99,107,46,97, - 99,113,117,105,114,101,99,1,0,0,0,0,0,0,0,2, - 0,0,0,10,0,0,0,67,0,0,0,115,165,0,0,0, - 116,0,0,106,1,0,131,0,0,125,1,0,124,0,0,106, - 2,0,143,138,0,1,124,0,0,106,3,0,124,1,0,107, - 3,0,114,52,0,116,4,0,100,1,0,131,1,0,130,1, - 0,110,0,0,124,0,0,106,5,0,100,2,0,107,4,0, - 115,73,0,116,6,0,130,1,0,124,0,0,4,106,5,0, - 100,3,0,56,2,95,5,0,124,0,0,106,5,0,100,2, - 0,107,2,0,114,155,0,100,0,0,124,0,0,95,3,0, - 124,0,0,106,7,0,114,155,0,124,0,0,4,106,7,0, - 100,3,0,56,2,95,7,0,124,0,0,106,8,0,106,9, - 0,131,0,0,1,113,155,0,110,0,0,87,100,0,0,81, - 88,100,0,0,83,41,4,78,122,31,99,97,110,110,111,116, - 32,114,101,108,101,97,115,101,32,117,110,45,97,99,113,117, - 105,114,101,100,32,108,111,99,107,114,84,0,0,0,114,29, - 0,0,0,41,10,114,85,0,0,0,114,91,0,0,0,114, - 86,0,0,0,114,88,0,0,0,218,12,82,117,110,116,105, - 109,101,69,114,114,111,114,114,89,0,0,0,218,14,65,115, - 115,101,114,116,105,111,110,69,114,114,111,114,114,90,0,0, - 0,114,87,0,0,0,114,98,0,0,0,41,2,114,71,0, - 0,0,114,95,0,0,0,114,4,0,0,0,114,4,0,0, - 0,114,5,0,0,0,114,98,0,0,0,217,0,0,0,115, - 22,0,0,0,0,1,12,1,10,1,15,1,15,1,21,1, - 15,1,15,1,9,1,9,1,15,1,122,19,95,77,111,100, - 117,108,101,76,111,99,107,46,114,101,108,101,97,115,101,99, - 1,0,0,0,0,0,0,0,1,0,0,0,4,0,0,0, - 67,0,0,0,115,25,0,0,0,100,1,0,106,0,0,124, - 0,0,106,1,0,116,2,0,124,0,0,131,1,0,131,2, - 0,83,41,2,78,122,23,95,77,111,100,117,108,101,76,111, - 99,107,40,123,33,114,125,41,32,97,116,32,123,125,41,3, - 114,47,0,0,0,114,67,0,0,0,114,48,0,0,0,41, - 1,114,71,0,0,0,114,4,0,0,0,114,4,0,0,0, - 114,5,0,0,0,218,8,95,95,114,101,112,114,95,95,230, - 0,0,0,115,2,0,0,0,0,1,122,20,95,77,111,100, - 117,108,101,76,111,99,107,46,95,95,114,101,112,114,95,95, - 78,41,9,114,57,0,0,0,114,56,0,0,0,114,58,0, - 0,0,114,59,0,0,0,114,72,0,0,0,114,96,0,0, - 0,114,97,0,0,0,114,98,0,0,0,114,101,0,0,0, - 114,4,0,0,0,114,4,0,0,0,114,4,0,0,0,114, - 5,0,0,0,114,83,0,0,0,166,0,0,0,115,12,0, - 0,0,12,4,6,2,12,8,12,12,12,25,12,13,114,83, - 0,0,0,99,0,0,0,0,0,0,0,0,0,0,0,0, - 2,0,0,0,64,0,0,0,115,70,0,0,0,101,0,0, - 90,1,0,100,0,0,90,2,0,100,1,0,90,3,0,100, - 2,0,100,3,0,132,0,0,90,4,0,100,4,0,100,5, - 0,132,0,0,90,5,0,100,6,0,100,7,0,132,0,0, - 90,6,0,100,8,0,100,9,0,132,0,0,90,7,0,100, - 10,0,83,41,11,218,16,95,68,117,109,109,121,77,111,100, - 117,108,101,76,111,99,107,122,86,65,32,115,105,109,112,108, - 101,32,95,77,111,100,117,108,101,76,111,99,107,32,101,113, - 117,105,118,97,108,101,110,116,32,102,111,114,32,80,121,116, - 104,111,110,32,98,117,105,108,100,115,32,119,105,116,104,111, - 117,116,10,32,32,32,32,109,117,108,116,105,45,116,104,114, - 101,97,100,105,110,103,32,115,117,112,112,111,114,116,46,99, - 2,0,0,0,0,0,0,0,2,0,0,0,2,0,0,0, - 67,0,0,0,115,22,0,0,0,124,1,0,124,0,0,95, - 0,0,100,1,0,124,0,0,95,1,0,100,0,0,83,41, - 2,78,114,84,0,0,0,41,2,114,67,0,0,0,114,89, - 0,0,0,41,2,114,71,0,0,0,114,67,0,0,0,114, + 1,0,0,0,3,0,0,0,67,0,0,0,115,19,0,0, + 0,124,0,0,4,106,0,0,100,1,0,55,2,95,0,0, + 100,2,0,83,41,3,78,114,29,0,0,0,84,41,1,114, + 89,0,0,0,41,1,114,71,0,0,0,114,4,0,0,0, + 114,4,0,0,0,114,5,0,0,0,114,97,0,0,0,242, + 0,0,0,115,4,0,0,0,0,1,15,1,122,24,95,68, + 117,109,109,121,77,111,100,117,108,101,76,111,99,107,46,97, + 99,113,117,105,114,101,99,1,0,0,0,0,0,0,0,1, + 0,0,0,3,0,0,0,67,0,0,0,115,46,0,0,0, + 124,0,0,106,0,0,100,1,0,107,2,0,114,27,0,116, + 1,0,100,2,0,131,1,0,130,1,0,124,0,0,4,106, + 0,0,100,3,0,56,2,95,0,0,100,0,0,83,41,4, + 78,114,84,0,0,0,122,31,99,97,110,110,111,116,32,114, + 101,108,101,97,115,101,32,117,110,45,97,99,113,117,105,114, + 101,100,32,108,111,99,107,114,29,0,0,0,41,2,114,89, + 0,0,0,114,99,0,0,0,41,1,114,71,0,0,0,114, + 4,0,0,0,114,4,0,0,0,114,5,0,0,0,114,98, + 0,0,0,246,0,0,0,115,6,0,0,0,0,1,15,1, + 12,1,122,24,95,68,117,109,109,121,77,111,100,117,108,101, + 76,111,99,107,46,114,101,108,101,97,115,101,99,1,0,0, + 0,0,0,0,0,1,0,0,0,4,0,0,0,67,0,0, + 0,115,25,0,0,0,100,1,0,106,0,0,124,0,0,106, + 1,0,116,2,0,124,0,0,131,1,0,131,2,0,83,41, + 2,78,122,28,95,68,117,109,109,121,77,111,100,117,108,101, + 76,111,99,107,40,123,33,114,125,41,32,97,116,32,123,125, + 41,3,114,47,0,0,0,114,67,0,0,0,114,48,0,0, + 0,41,1,114,71,0,0,0,114,4,0,0,0,114,4,0, + 0,0,114,5,0,0,0,114,101,0,0,0,251,0,0,0, + 115,2,0,0,0,0,1,122,25,95,68,117,109,109,121,77, + 111,100,117,108,101,76,111,99,107,46,95,95,114,101,112,114, + 95,95,78,41,8,114,57,0,0,0,114,56,0,0,0,114, + 58,0,0,0,114,59,0,0,0,114,72,0,0,0,114,97, + 0,0,0,114,98,0,0,0,114,101,0,0,0,114,4,0, + 0,0,114,4,0,0,0,114,4,0,0,0,114,5,0,0, + 0,114,102,0,0,0,234,0,0,0,115,10,0,0,0,12, + 2,6,2,12,4,12,4,12,5,114,102,0,0,0,99,0, + 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,64, + 0,0,0,115,52,0,0,0,101,0,0,90,1,0,100,0, + 0,90,2,0,100,1,0,100,2,0,132,0,0,90,3,0, + 100,3,0,100,4,0,132,0,0,90,4,0,100,5,0,100, + 6,0,132,0,0,90,5,0,100,7,0,83,41,8,218,18, + 95,77,111,100,117,108,101,76,111,99,107,77,97,110,97,103, + 101,114,99,2,0,0,0,0,0,0,0,2,0,0,0,2, + 0,0,0,67,0,0,0,115,22,0,0,0,124,1,0,124, + 0,0,95,0,0,100,0,0,124,0,0,95,1,0,100,0, + 0,83,41,1,78,41,2,114,70,0,0,0,218,5,95,108, + 111,99,107,41,2,114,71,0,0,0,114,67,0,0,0,114, 4,0,0,0,114,4,0,0,0,114,5,0,0,0,114,72, - 0,0,0,238,0,0,0,115,4,0,0,0,0,1,9,1, - 122,25,95,68,117,109,109,121,77,111,100,117,108,101,76,111, - 99,107,46,95,95,105,110,105,116,95,95,99,1,0,0,0, - 0,0,0,0,1,0,0,0,3,0,0,0,67,0,0,0, - 115,19,0,0,0,124,0,0,4,106,0,0,100,1,0,55, - 2,95,0,0,100,2,0,83,41,3,78,114,29,0,0,0, - 84,41,1,114,89,0,0,0,41,1,114,71,0,0,0,114, - 4,0,0,0,114,4,0,0,0,114,5,0,0,0,114,97, - 0,0,0,242,0,0,0,115,4,0,0,0,0,1,15,1, - 122,24,95,68,117,109,109,121,77,111,100,117,108,101,76,111, - 99,107,46,97,99,113,117,105,114,101,99,1,0,0,0,0, - 0,0,0,1,0,0,0,3,0,0,0,67,0,0,0,115, - 49,0,0,0,124,0,0,106,0,0,100,1,0,107,2,0, - 114,30,0,116,1,0,100,2,0,131,1,0,130,1,0,110, - 0,0,124,0,0,4,106,0,0,100,3,0,56,2,95,0, - 0,100,0,0,83,41,4,78,114,84,0,0,0,122,31,99, - 97,110,110,111,116,32,114,101,108,101,97,115,101,32,117,110, - 45,97,99,113,117,105,114,101,100,32,108,111,99,107,114,29, - 0,0,0,41,2,114,89,0,0,0,114,99,0,0,0,41, - 1,114,71,0,0,0,114,4,0,0,0,114,4,0,0,0, - 114,5,0,0,0,114,98,0,0,0,246,0,0,0,115,6, - 0,0,0,0,1,15,1,15,1,122,24,95,68,117,109,109, - 121,77,111,100,117,108,101,76,111,99,107,46,114,101,108,101, - 97,115,101,99,1,0,0,0,0,0,0,0,1,0,0,0, - 4,0,0,0,67,0,0,0,115,25,0,0,0,100,1,0, - 106,0,0,124,0,0,106,1,0,116,2,0,124,0,0,131, - 1,0,131,2,0,83,41,2,78,122,28,95,68,117,109,109, - 121,77,111,100,117,108,101,76,111,99,107,40,123,33,114,125, - 41,32,97,116,32,123,125,41,3,114,47,0,0,0,114,67, - 0,0,0,114,48,0,0,0,41,1,114,71,0,0,0,114, - 4,0,0,0,114,4,0,0,0,114,5,0,0,0,114,101, - 0,0,0,251,0,0,0,115,2,0,0,0,0,1,122,25, - 95,68,117,109,109,121,77,111,100,117,108,101,76,111,99,107, - 46,95,95,114,101,112,114,95,95,78,41,8,114,57,0,0, - 0,114,56,0,0,0,114,58,0,0,0,114,59,0,0,0, - 114,72,0,0,0,114,97,0,0,0,114,98,0,0,0,114, - 101,0,0,0,114,4,0,0,0,114,4,0,0,0,114,4, - 0,0,0,114,5,0,0,0,114,102,0,0,0,234,0,0, - 0,115,10,0,0,0,12,2,6,2,12,4,12,4,12,5, - 114,102,0,0,0,99,0,0,0,0,0,0,0,0,0,0, - 0,0,2,0,0,0,64,0,0,0,115,52,0,0,0,101, - 0,0,90,1,0,100,0,0,90,2,0,100,1,0,100,2, - 0,132,0,0,90,3,0,100,3,0,100,4,0,132,0,0, - 90,4,0,100,5,0,100,6,0,132,0,0,90,5,0,100, - 7,0,83,41,8,218,18,95,77,111,100,117,108,101,76,111, - 99,107,77,97,110,97,103,101,114,99,2,0,0,0,0,0, - 0,0,2,0,0,0,2,0,0,0,67,0,0,0,115,22, - 0,0,0,124,1,0,124,0,0,95,0,0,100,0,0,124, - 0,0,95,1,0,100,0,0,83,41,1,78,41,2,114,70, - 0,0,0,218,5,95,108,111,99,107,41,2,114,71,0,0, - 0,114,67,0,0,0,114,4,0,0,0,114,4,0,0,0, - 114,5,0,0,0,114,72,0,0,0,1,1,0,0,115,4, - 0,0,0,0,1,9,1,122,27,95,77,111,100,117,108,101, - 76,111,99,107,77,97,110,97,103,101,114,46,95,95,105,110, - 105,116,95,95,99,1,0,0,0,0,0,0,0,1,0,0, - 0,10,0,0,0,67,0,0,0,115,53,0,0,0,122,22, - 0,116,0,0,124,0,0,106,1,0,131,1,0,124,0,0, - 95,2,0,87,100,0,0,116,3,0,106,4,0,131,0,0, - 1,88,124,0,0,106,2,0,106,5,0,131,0,0,1,100, - 0,0,83,41,1,78,41,6,218,16,95,103,101,116,95,109, - 111,100,117,108,101,95,108,111,99,107,114,70,0,0,0,114, - 104,0,0,0,218,4,95,105,109,112,218,12,114,101,108,101, - 97,115,101,95,108,111,99,107,114,97,0,0,0,41,1,114, - 71,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5, - 0,0,0,114,75,0,0,0,5,1,0,0,115,8,0,0, - 0,0,1,3,1,22,2,11,1,122,28,95,77,111,100,117, - 108,101,76,111,99,107,77,97,110,97,103,101,114,46,95,95, - 101,110,116,101,114,95,95,99,1,0,0,0,0,0,0,0, - 3,0,0,0,1,0,0,0,79,0,0,0,115,17,0,0, - 0,124,0,0,106,0,0,106,1,0,131,0,0,1,100,0, - 0,83,41,1,78,41,2,114,104,0,0,0,114,98,0,0, - 0,41,3,114,71,0,0,0,114,80,0,0,0,218,6,107, - 119,97,114,103,115,114,4,0,0,0,114,4,0,0,0,114, - 5,0,0,0,114,81,0,0,0,12,1,0,0,115,2,0, - 0,0,0,1,122,27,95,77,111,100,117,108,101,76,111,99, - 107,77,97,110,97,103,101,114,46,95,95,101,120,105,116,95, - 95,78,41,6,114,57,0,0,0,114,56,0,0,0,114,58, - 0,0,0,114,72,0,0,0,114,75,0,0,0,114,81,0, - 0,0,114,4,0,0,0,114,4,0,0,0,114,4,0,0, - 0,114,5,0,0,0,114,103,0,0,0,255,0,0,0,115, - 6,0,0,0,12,2,12,4,12,7,114,103,0,0,0,99, - 1,0,0,0,0,0,0,0,3,0,0,0,11,0,0,0, - 3,0,0,0,115,142,0,0,0,100,1,0,125,1,0,121, - 17,0,116,0,0,136,0,0,25,131,0,0,125,1,0,87, - 110,18,0,4,116,1,0,107,10,0,114,43,0,1,1,1, - 89,110,1,0,88,124,1,0,100,1,0,107,8,0,114,138, - 0,116,2,0,100,1,0,107,8,0,114,83,0,116,3,0, - 136,0,0,131,1,0,125,1,0,110,12,0,116,4,0,136, - 0,0,131,1,0,125,1,0,135,0,0,102,1,0,100,2, - 0,100,3,0,134,0,0,125,2,0,116,5,0,106,6,0, - 124,1,0,124,2,0,131,2,0,116,0,0,136,0,0,60, - 110,0,0,124,1,0,83,41,4,122,109,71,101,116,32,111, - 114,32,99,114,101,97,116,101,32,116,104,101,32,109,111,100, - 117,108,101,32,108,111,99,107,32,102,111,114,32,97,32,103, - 105,118,101,110,32,109,111,100,117,108,101,32,110,97,109,101, - 46,10,10,32,32,32,32,83,104,111,117,108,100,32,111,110, - 108,121,32,98,101,32,99,97,108,108,101,100,32,119,105,116, - 104,32,116,104,101,32,105,109,112,111,114,116,32,108,111,99, - 107,32,116,97,107,101,110,46,78,99,1,0,0,0,0,0, - 0,0,1,0,0,0,2,0,0,0,19,0,0,0,115,11, - 0,0,0,116,0,0,136,0,0,61,100,0,0,83,41,1, - 78,41,1,218,13,95,109,111,100,117,108,101,95,108,111,99, - 107,115,41,1,114,36,0,0,0,41,1,114,67,0,0,0, - 114,4,0,0,0,114,5,0,0,0,218,2,99,98,32,1, - 0,0,115,2,0,0,0,0,1,122,28,95,103,101,116,95, - 109,111,100,117,108,101,95,108,111,99,107,46,60,108,111,99, - 97,108,115,62,46,99,98,41,7,114,109,0,0,0,114,79, - 0,0,0,114,85,0,0,0,114,102,0,0,0,114,83,0, - 0,0,218,8,95,119,101,97,107,114,101,102,90,3,114,101, - 102,41,3,114,67,0,0,0,114,86,0,0,0,114,110,0, - 0,0,114,4,0,0,0,41,1,114,67,0,0,0,114,5, - 0,0,0,114,105,0,0,0,18,1,0,0,115,24,0,0, - 0,0,4,6,1,3,1,17,1,13,1,5,1,12,1,12, - 1,15,2,12,1,18,2,25,1,114,105,0,0,0,99,1, - 0,0,0,0,0,0,0,2,0,0,0,11,0,0,0,67, - 0,0,0,115,71,0,0,0,116,0,0,124,0,0,131,1, - 0,125,1,0,116,1,0,106,2,0,131,0,0,1,121,14, - 0,124,1,0,106,3,0,131,0,0,1,87,110,18,0,4, - 116,4,0,107,10,0,114,56,0,1,1,1,89,110,11,0, - 88,124,1,0,106,5,0,131,0,0,1,100,1,0,83,41, - 2,97,21,1,0,0,82,101,108,101,97,115,101,32,116,104, - 101,32,103,108,111,98,97,108,32,105,109,112,111,114,116,32, - 108,111,99,107,44,32,97,110,100,32,97,99,113,117,105,114, - 101,115,32,116,104,101,110,32,114,101,108,101,97,115,101,32, - 116,104,101,10,32,32,32,32,109,111,100,117,108,101,32,108, - 111,99,107,32,102,111,114,32,97,32,103,105,118,101,110,32, - 109,111,100,117,108,101,32,110,97,109,101,46,10,32,32,32, - 32,84,104,105,115,32,105,115,32,117,115,101,100,32,116,111, - 32,101,110,115,117,114,101,32,97,32,109,111,100,117,108,101, - 32,105,115,32,99,111,109,112,108,101,116,101,108,121,32,105, - 110,105,116,105,97,108,105,122,101,100,44,32,105,110,32,116, - 104,101,10,32,32,32,32,101,118,101,110,116,32,105,116,32, - 105,115,32,98,101,105,110,103,32,105,109,112,111,114,116,101, - 100,32,98,121,32,97,110,111,116,104,101,114,32,116,104,114, - 101,97,100,46,10,10,32,32,32,32,83,104,111,117,108,100, - 32,111,110,108,121,32,98,101,32,99,97,108,108,101,100,32, - 119,105,116,104,32,116,104,101,32,105,109,112,111,114,116,32, - 108,111,99,107,32,116,97,107,101,110,46,78,41,6,114,105, - 0,0,0,114,106,0,0,0,114,107,0,0,0,114,97,0, - 0,0,114,82,0,0,0,114,98,0,0,0,41,2,114,67, - 0,0,0,114,86,0,0,0,114,4,0,0,0,114,4,0, - 0,0,114,5,0,0,0,218,19,95,108,111,99,107,95,117, - 110,108,111,99,107,95,109,111,100,117,108,101,37,1,0,0, - 115,14,0,0,0,0,7,12,1,10,1,3,1,14,1,13, - 3,5,2,114,112,0,0,0,99,1,0,0,0,0,0,0, - 0,3,0,0,0,3,0,0,0,79,0,0,0,115,13,0, - 0,0,124,0,0,124,1,0,124,2,0,142,0,0,83,41, - 1,97,46,1,0,0,114,101,109,111,118,101,95,105,109,112, - 111,114,116,108,105,98,95,102,114,97,109,101,115,32,105,110, - 32,105,109,112,111,114,116,46,99,32,119,105,108,108,32,97, - 108,119,97,121,115,32,114,101,109,111,118,101,32,115,101,113, - 117,101,110,99,101,115,10,32,32,32,32,111,102,32,105,109, - 112,111,114,116,108,105,98,32,102,114,97,109,101,115,32,116, - 104,97,116,32,101,110,100,32,119,105,116,104,32,97,32,99, - 97,108,108,32,116,111,32,116,104,105,115,32,102,117,110,99, - 116,105,111,110,10,10,32,32,32,32,85,115,101,32,105,116, - 32,105,110,115,116,101,97,100,32,111,102,32,97,32,110,111, - 114,109,97,108,32,99,97,108,108,32,105,110,32,112,108,97, - 99,101,115,32,119,104,101,114,101,32,105,110,99,108,117,100, - 105,110,103,32,116,104,101,32,105,109,112,111,114,116,108,105, - 98,10,32,32,32,32,102,114,97,109,101,115,32,105,110,116, - 114,111,100,117,99,101,115,32,117,110,119,97,110,116,101,100, - 32,110,111,105,115,101,32,105,110,116,111,32,116,104,101,32, - 116,114,97,99,101,98,97,99,107,32,40,101,46,103,46,32, - 119,104,101,110,32,101,120,101,99,117,116,105,110,103,10,32, - 32,32,32,109,111,100,117,108,101,32,99,111,100,101,41,10, - 32,32,32,32,114,4,0,0,0,41,3,218,1,102,114,80, - 0,0,0,90,4,107,119,100,115,114,4,0,0,0,114,4, - 0,0,0,114,5,0,0,0,218,25,95,99,97,108,108,95, - 119,105,116,104,95,102,114,97,109,101,115,95,114,101,109,111, - 118,101,100,57,1,0,0,115,2,0,0,0,0,8,114,114, - 0,0,0,105,228,12,0,0,233,2,0,0,0,114,13,0, - 0,0,115,2,0,0,0,13,10,90,11,95,95,112,121,99, - 97,99,104,101,95,95,122,3,46,112,121,122,4,46,112,121, - 99,122,4,46,112,121,111,78,99,2,0,0,0,0,0,0, - 0,11,0,0,0,6,0,0,0,67,0,0,0,115,180,0, - 0,0,124,1,0,100,1,0,107,8,0,114,25,0,116,0, - 0,106,1,0,106,2,0,12,110,3,0,124,1,0,125,2, - 0,124,2,0,114,46,0,116,3,0,125,3,0,110,6,0, - 116,4,0,125,3,0,116,5,0,124,0,0,131,1,0,92, - 2,0,125,4,0,125,5,0,124,5,0,106,6,0,100,2, - 0,131,1,0,92,3,0,125,6,0,125,7,0,125,8,0, - 116,0,0,106,7,0,106,8,0,125,9,0,124,9,0,100, - 1,0,107,8,0,114,133,0,116,9,0,100,3,0,131,1, - 0,130,1,0,110,0,0,100,4,0,106,10,0,124,6,0, - 124,7,0,124,9,0,124,3,0,100,5,0,25,103,4,0, - 131,1,0,125,10,0,116,11,0,124,4,0,116,12,0,124, - 10,0,131,3,0,83,41,6,97,244,1,0,0,71,105,118, - 101,110,32,116,104,101,32,112,97,116,104,32,116,111,32,97, - 32,46,112,121,32,102,105,108,101,44,32,114,101,116,117,114, - 110,32,116,104,101,32,112,97,116,104,32,116,111,32,105,116, - 115,32,46,112,121,99,47,46,112,121,111,32,102,105,108,101, - 46,10,10,32,32,32,32,84,104,101,32,46,112,121,32,102, - 105,108,101,32,100,111,101,115,32,110,111,116,32,110,101,101, - 100,32,116,111,32,101,120,105,115,116,59,32,116,104,105,115, - 32,115,105,109,112,108,121,32,114,101,116,117,114,110,115,32, - 116,104,101,32,112,97,116,104,32,116,111,32,116,104,101,10, - 32,32,32,32,46,112,121,99,47,46,112,121,111,32,102,105, - 108,101,32,99,97,108,99,117,108,97,116,101,100,32,97,115, - 32,105,102,32,116,104,101,32,46,112,121,32,102,105,108,101, - 32,119,101,114,101,32,105,109,112,111,114,116,101,100,46,32, - 32,84,104,101,32,101,120,116,101,110,115,105,111,110,10,32, - 32,32,32,119,105,108,108,32,98,101,32,46,112,121,99,32, - 117,110,108,101,115,115,32,115,121,115,46,102,108,97,103,115, - 46,111,112,116,105,109,105,122,101,32,105,115,32,110,111,110, - 45,122,101,114,111,44,32,116,104,101,110,32,105,116,32,119, - 105,108,108,32,98,101,32,46,112,121,111,46,10,10,32,32, - 32,32,73,102,32,100,101,98,117,103,95,111,118,101,114,114, - 105,100,101,32,105,115,32,110,111,116,32,78,111,110,101,44, - 32,116,104,101,110,32,105,116,32,109,117,115,116,32,98,101, - 32,97,32,98,111,111,108,101,97,110,32,97,110,100,32,105, - 115,32,117,115,101,100,32,105,110,10,32,32,32,32,112,108, - 97,99,101,32,111,102,32,115,121,115,46,102,108,97,103,115, - 46,111,112,116,105,109,105,122,101,46,10,10,32,32,32,32, - 73,102,32,115,121,115,46,105,109,112,108,101,109,101,110,116, - 97,116,105,111,110,46,99,97,99,104,101,95,116,97,103,32, - 105,115,32,78,111,110,101,32,116,104,101,110,32,78,111,116, - 73,109,112,108,101,109,101,110,116,101,100,69,114,114,111,114, - 32,105,115,32,114,97,105,115,101,100,46,10,10,32,32,32, - 32,78,218,1,46,122,36,115,121,115,46,105,109,112,108,101, - 109,101,110,116,97,116,105,111,110,46,99,97,99,104,101,95, - 116,97,103,32,105,115,32,78,111,110,101,114,30,0,0,0, - 114,84,0,0,0,41,13,114,7,0,0,0,218,5,102,108, - 97,103,115,218,8,111,112,116,105,109,105,122,101,218,23,68, - 69,66,85,71,95,66,89,84,69,67,79,68,69,95,83,85, - 70,70,73,88,69,83,218,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,38,0,0,0,218,9,112,97,114,116,105,116, - 105,111,110,218,14,105,109,112,108,101,109,101,110,116,97,116, - 105,111,110,218,9,99,97,99,104,101,95,116,97,103,218,19, - 78,111,116,73,109,112,108,101,109,101,110,116,101,100,69,114, - 114,111,114,114,26,0,0,0,114,28,0,0,0,218,8,95, - 80,89,67,65,67,72,69,41,11,114,35,0,0,0,90,14, - 100,101,98,117,103,95,111,118,101,114,114,105,100,101,218,5, - 100,101,98,117,103,218,8,115,117,102,102,105,120,101,115,218, - 4,104,101,97,100,114,37,0,0,0,218,13,98,97,115,101, - 95,102,105,108,101,110,97,109,101,218,3,115,101,112,114,36, - 0,0,0,90,3,116,97,103,218,8,102,105,108,101,110,97, - 109,101,114,4,0,0,0,114,4,0,0,0,114,5,0,0, - 0,218,17,99,97,99,104,101,95,102,114,111,109,95,115,111, - 117,114,99,101,180,1,0,0,115,22,0,0,0,0,13,31, - 1,6,1,9,2,6,1,18,1,24,1,12,1,12,1,15, - 1,31,1,114,132,0,0,0,99,1,0,0,0,0,0,0, - 0,5,0,0,0,5,0,0,0,67,0,0,0,115,193,0, - 0,0,116,0,0,106,1,0,106,2,0,100,1,0,107,8, - 0,114,33,0,116,3,0,100,2,0,131,1,0,130,1,0, - 110,0,0,116,4,0,124,0,0,131,1,0,92,2,0,125, - 1,0,125,2,0,116,4,0,124,1,0,131,1,0,92,2, - 0,125,1,0,125,3,0,124,3,0,116,5,0,107,3,0, - 114,108,0,116,6,0,100,3,0,106,7,0,116,5,0,124, - 0,0,131,2,0,131,1,0,130,1,0,110,0,0,124,2, - 0,106,8,0,100,4,0,131,1,0,100,5,0,107,3,0, - 114,153,0,116,6,0,100,6,0,106,7,0,124,2,0,131, - 1,0,131,1,0,130,1,0,110,0,0,124,2,0,106,9, - 0,100,4,0,131,1,0,100,7,0,25,125,4,0,116,10, - 0,124,1,0,124,4,0,116,11,0,100,7,0,25,23,131, - 2,0,83,41,8,97,121,1,0,0,71,105,118,101,110,32, - 116,104,101,32,112,97,116,104,32,116,111,32,97,32,46,112, - 121,99,46,47,46,112,121,111,32,102,105,108,101,44,32,114, - 101,116,117,114,110,32,116,104,101,32,112,97,116,104,32,116, - 111,32,105,116,115,32,46,112,121,32,102,105,108,101,46,10, - 10,32,32,32,32,84,104,101,32,46,112,121,99,47,46,112, - 121,111,32,102,105,108,101,32,100,111,101,115,32,110,111,116, - 32,110,101,101,100,32,116,111,32,101,120,105,115,116,59,32, - 116,104,105,115,32,115,105,109,112,108,121,32,114,101,116,117, - 114,110,115,32,116,104,101,32,112,97,116,104,32,116,111,10, - 32,32,32,32,116,104,101,32,46,112,121,32,102,105,108,101, - 32,99,97,108,99,117,108,97,116,101,100,32,116,111,32,99, - 111,114,114,101,115,112,111,110,100,32,116,111,32,116,104,101, + 0,0,0,1,1,0,0,115,4,0,0,0,0,1,9,1, + 122,27,95,77,111,100,117,108,101,76,111,99,107,77,97,110, + 97,103,101,114,46,95,95,105,110,105,116,95,95,99,1,0, + 0,0,0,0,0,0,1,0,0,0,10,0,0,0,67,0, + 0,0,115,53,0,0,0,122,22,0,116,0,0,124,0,0, + 106,1,0,131,1,0,124,0,0,95,2,0,87,100,0,0, + 116,3,0,106,4,0,131,0,0,1,88,124,0,0,106,2, + 0,106,5,0,131,0,0,1,100,0,0,83,41,1,78,41, + 6,218,16,95,103,101,116,95,109,111,100,117,108,101,95,108, + 111,99,107,114,70,0,0,0,114,104,0,0,0,218,4,95, + 105,109,112,218,12,114,101,108,101,97,115,101,95,108,111,99, + 107,114,97,0,0,0,41,1,114,71,0,0,0,114,4,0, + 0,0,114,4,0,0,0,114,5,0,0,0,114,75,0,0, + 0,5,1,0,0,115,8,0,0,0,0,1,3,1,22,2, + 11,1,122,28,95,77,111,100,117,108,101,76,111,99,107,77, + 97,110,97,103,101,114,46,95,95,101,110,116,101,114,95,95, + 99,1,0,0,0,0,0,0,0,3,0,0,0,1,0,0, + 0,79,0,0,0,115,17,0,0,0,124,0,0,106,0,0, + 106,1,0,131,0,0,1,100,0,0,83,41,1,78,41,2, + 114,104,0,0,0,114,98,0,0,0,41,3,114,71,0,0, + 0,114,80,0,0,0,218,6,107,119,97,114,103,115,114,4, + 0,0,0,114,4,0,0,0,114,5,0,0,0,114,81,0, + 0,0,12,1,0,0,115,2,0,0,0,0,1,122,27,95, + 77,111,100,117,108,101,76,111,99,107,77,97,110,97,103,101, + 114,46,95,95,101,120,105,116,95,95,78,41,6,114,57,0, + 0,0,114,56,0,0,0,114,58,0,0,0,114,72,0,0, + 0,114,75,0,0,0,114,81,0,0,0,114,4,0,0,0, + 114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,114, + 103,0,0,0,255,0,0,0,115,6,0,0,0,12,2,12, + 4,12,7,114,103,0,0,0,99,1,0,0,0,0,0,0, + 0,3,0,0,0,11,0,0,0,3,0,0,0,115,139,0, + 0,0,100,1,0,125,1,0,121,17,0,116,0,0,136,0, + 0,25,131,0,0,125,1,0,87,110,18,0,4,116,1,0, + 107,10,0,114,43,0,1,1,1,89,110,1,0,88,124,1, + 0,100,1,0,107,8,0,114,135,0,116,2,0,100,1,0, + 107,8,0,114,83,0,116,3,0,136,0,0,131,1,0,125, + 1,0,110,12,0,116,4,0,136,0,0,131,1,0,125,1, + 0,135,0,0,102,1,0,100,2,0,100,3,0,134,0,0, + 125,2,0,116,5,0,106,6,0,124,1,0,124,2,0,131, + 2,0,116,0,0,136,0,0,60,124,1,0,83,41,4,122, + 109,71,101,116,32,111,114,32,99,114,101,97,116,101,32,116, + 104,101,32,109,111,100,117,108,101,32,108,111,99,107,32,102, + 111,114,32,97,32,103,105,118,101,110,32,109,111,100,117,108, + 101,32,110,97,109,101,46,10,10,32,32,32,32,83,104,111, + 117,108,100,32,111,110,108,121,32,98,101,32,99,97,108,108, + 101,100,32,119,105,116,104,32,116,104,101,32,105,109,112,111, + 114,116,32,108,111,99,107,32,116,97,107,101,110,46,78,99, + 1,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0, + 19,0,0,0,115,11,0,0,0,116,0,0,136,0,0,61, + 100,0,0,83,41,1,78,41,1,218,13,95,109,111,100,117, + 108,101,95,108,111,99,107,115,41,1,114,36,0,0,0,41, + 1,114,67,0,0,0,114,4,0,0,0,114,5,0,0,0, + 218,2,99,98,32,1,0,0,115,2,0,0,0,0,1,122, + 28,95,103,101,116,95,109,111,100,117,108,101,95,108,111,99, + 107,46,60,108,111,99,97,108,115,62,46,99,98,41,7,114, + 109,0,0,0,114,79,0,0,0,114,85,0,0,0,114,102, + 0,0,0,114,83,0,0,0,218,8,95,119,101,97,107,114, + 101,102,90,3,114,101,102,41,3,114,67,0,0,0,114,86, + 0,0,0,114,110,0,0,0,114,4,0,0,0,41,1,114, + 67,0,0,0,114,5,0,0,0,114,105,0,0,0,18,1, + 0,0,115,24,0,0,0,0,4,6,1,3,1,17,1,13, + 1,5,1,12,1,12,1,15,2,12,1,18,2,22,1,114, + 105,0,0,0,99,1,0,0,0,0,0,0,0,2,0,0, + 0,11,0,0,0,67,0,0,0,115,71,0,0,0,116,0, + 0,124,0,0,131,1,0,125,1,0,116,1,0,106,2,0, + 131,0,0,1,121,14,0,124,1,0,106,3,0,131,0,0, + 1,87,110,18,0,4,116,4,0,107,10,0,114,56,0,1, + 1,1,89,110,11,0,88,124,1,0,106,5,0,131,0,0, + 1,100,1,0,83,41,2,97,21,1,0,0,82,101,108,101, + 97,115,101,32,116,104,101,32,103,108,111,98,97,108,32,105, + 109,112,111,114,116,32,108,111,99,107,44,32,97,110,100,32, + 97,99,113,117,105,114,101,115,32,116,104,101,110,32,114,101, + 108,101,97,115,101,32,116,104,101,10,32,32,32,32,109,111, + 100,117,108,101,32,108,111,99,107,32,102,111,114,32,97,32, + 103,105,118,101,110,32,109,111,100,117,108,101,32,110,97,109, + 101,46,10,32,32,32,32,84,104,105,115,32,105,115,32,117, + 115,101,100,32,116,111,32,101,110,115,117,114,101,32,97,32, + 109,111,100,117,108,101,32,105,115,32,99,111,109,112,108,101, + 116,101,108,121,32,105,110,105,116,105,97,108,105,122,101,100, + 44,32,105,110,32,116,104,101,10,32,32,32,32,101,118,101, + 110,116,32,105,116,32,105,115,32,98,101,105,110,103,32,105, + 109,112,111,114,116,101,100,32,98,121,32,97,110,111,116,104, + 101,114,32,116,104,114,101,97,100,46,10,10,32,32,32,32, + 83,104,111,117,108,100,32,111,110,108,121,32,98,101,32,99, + 97,108,108,101,100,32,119,105,116,104,32,116,104,101,32,105, + 109,112,111,114,116,32,108,111,99,107,32,116,97,107,101,110, + 46,78,41,6,114,105,0,0,0,114,106,0,0,0,114,107, + 0,0,0,114,97,0,0,0,114,82,0,0,0,114,98,0, + 0,0,41,2,114,67,0,0,0,114,86,0,0,0,114,4, + 0,0,0,114,4,0,0,0,114,5,0,0,0,218,19,95, + 108,111,99,107,95,117,110,108,111,99,107,95,109,111,100,117, + 108,101,37,1,0,0,115,14,0,0,0,0,7,12,1,10, + 1,3,1,14,1,13,3,5,2,114,112,0,0,0,99,1, + 0,0,0,0,0,0,0,3,0,0,0,3,0,0,0,79, + 0,0,0,115,13,0,0,0,124,0,0,124,1,0,124,2, + 0,142,0,0,83,41,1,97,46,1,0,0,114,101,109,111, + 118,101,95,105,109,112,111,114,116,108,105,98,95,102,114,97, + 109,101,115,32,105,110,32,105,109,112,111,114,116,46,99,32, + 119,105,108,108,32,97,108,119,97,121,115,32,114,101,109,111, + 118,101,32,115,101,113,117,101,110,99,101,115,10,32,32,32, + 32,111,102,32,105,109,112,111,114,116,108,105,98,32,102,114, + 97,109,101,115,32,116,104,97,116,32,101,110,100,32,119,105, + 116,104,32,97,32,99,97,108,108,32,116,111,32,116,104,105, + 115,32,102,117,110,99,116,105,111,110,10,10,32,32,32,32, + 85,115,101,32,105,116,32,105,110,115,116,101,97,100,32,111, + 102,32,97,32,110,111,114,109,97,108,32,99,97,108,108,32, + 105,110,32,112,108,97,99,101,115,32,119,104,101,114,101,32, + 105,110,99,108,117,100,105,110,103,32,116,104,101,32,105,109, + 112,111,114,116,108,105,98,10,32,32,32,32,102,114,97,109, + 101,115,32,105,110,116,114,111,100,117,99,101,115,32,117,110, + 119,97,110,116,101,100,32,110,111,105,115,101,32,105,110,116, + 111,32,116,104,101,32,116,114,97,99,101,98,97,99,107,32, + 40,101,46,103,46,32,119,104,101,110,32,101,120,101,99,117, + 116,105,110,103,10,32,32,32,32,109,111,100,117,108,101,32, + 99,111,100,101,41,10,32,32,32,32,114,4,0,0,0,41, + 3,218,1,102,114,80,0,0,0,90,4,107,119,100,115,114, + 4,0,0,0,114,4,0,0,0,114,5,0,0,0,218,25, + 95,99,97,108,108,95,119,105,116,104,95,102,114,97,109,101, + 115,95,114,101,109,111,118,101,100,57,1,0,0,115,2,0, + 0,0,0,8,114,114,0,0,0,105,248,12,0,0,233,2, + 0,0,0,114,13,0,0,0,115,2,0,0,0,13,10,90, + 11,95,95,112,121,99,97,99,104,101,95,95,122,3,46,112, + 121,122,4,46,112,121,99,122,4,46,112,121,111,78,99,2, + 0,0,0,0,0,0,0,11,0,0,0,6,0,0,0,67, + 0,0,0,115,189,0,0,0,124,1,0,100,1,0,107,8, + 0,114,25,0,116,0,0,106,1,0,106,2,0,12,110,3, + 0,124,1,0,125,2,0,124,2,0,114,46,0,116,3,0, + 125,3,0,110,6,0,116,4,0,125,3,0,116,5,0,124, + 0,0,131,1,0,92,2,0,125,4,0,125,5,0,124,5, + 0,106,6,0,100,2,0,131,1,0,92,3,0,125,6,0, + 125,7,0,125,8,0,116,0,0,106,7,0,106,8,0,125, + 9,0,124,9,0,100,1,0,107,8,0,114,130,0,116,9, + 0,100,3,0,131,1,0,130,1,0,100,4,0,106,10,0, + 124,6,0,114,148,0,124,6,0,110,3,0,124,8,0,124, + 7,0,124,9,0,124,3,0,100,5,0,25,103,4,0,131, + 1,0,125,10,0,116,11,0,124,4,0,116,12,0,124,10, + 0,131,3,0,83,41,6,97,244,1,0,0,71,105,118,101, + 110,32,116,104,101,32,112,97,116,104,32,116,111,32,97,32, + 46,112,121,32,102,105,108,101,44,32,114,101,116,117,114,110, + 32,116,104,101,32,112,97,116,104,32,116,111,32,105,116,115, 32,46,112,121,99,47,46,112,121,111,32,102,105,108,101,46, - 32,32,73,102,32,112,97,116,104,32,100,111,101,115,10,32, - 32,32,32,110,111,116,32,99,111,110,102,111,114,109,32,116, - 111,32,80,69,80,32,51,49,52,55,32,102,111,114,109,97, - 116,44,32,86,97,108,117,101,69,114,114,111,114,32,119,105, - 108,108,32,98,101,32,114,97,105,115,101,100,46,32,73,102, - 10,32,32,32,32,115,121,115,46,105,109,112,108,101,109,101, - 110,116,97,116,105,111,110,46,99,97,99,104,101,95,116,97, - 103,32,105,115,32,78,111,110,101,32,116,104,101,110,32,78, - 111,116,73,109,112,108,101,109,101,110,116,101,100,69,114,114, - 111,114,32,105,115,32,114,97,105,115,101,100,46,10,10,32, - 32,32,32,78,122,36,115,121,115,46,105,109,112,108,101,109, + 10,10,32,32,32,32,84,104,101,32,46,112,121,32,102,105, + 108,101,32,100,111,101,115,32,110,111,116,32,110,101,101,100, + 32,116,111,32,101,120,105,115,116,59,32,116,104,105,115,32, + 115,105,109,112,108,121,32,114,101,116,117,114,110,115,32,116, + 104,101,32,112,97,116,104,32,116,111,32,116,104,101,10,32, + 32,32,32,46,112,121,99,47,46,112,121,111,32,102,105,108, + 101,32,99,97,108,99,117,108,97,116,101,100,32,97,115,32, + 105,102,32,116,104,101,32,46,112,121,32,102,105,108,101,32, + 119,101,114,101,32,105,109,112,111,114,116,101,100,46,32,32, + 84,104,101,32,101,120,116,101,110,115,105,111,110,10,32,32, + 32,32,119,105,108,108,32,98,101,32,46,112,121,99,32,117, + 110,108,101,115,115,32,115,121,115,46,102,108,97,103,115,46, + 111,112,116,105,109,105,122,101,32,105,115,32,110,111,110,45, + 122,101,114,111,44,32,116,104,101,110,32,105,116,32,119,105, + 108,108,32,98,101,32,46,112,121,111,46,10,10,32,32,32, + 32,73,102,32,100,101,98,117,103,95,111,118,101,114,114,105, + 100,101,32,105,115,32,110,111,116,32,78,111,110,101,44,32, + 116,104,101,110,32,105,116,32,109,117,115,116,32,98,101,32, + 97,32,98,111,111,108,101,97,110,32,97,110,100,32,105,115, + 32,117,115,101,100,32,105,110,10,32,32,32,32,112,108,97, + 99,101,32,111,102,32,115,121,115,46,102,108,97,103,115,46, + 111,112,116,105,109,105,122,101,46,10,10,32,32,32,32,73, + 102,32,115,121,115,46,105,109,112,108,101,109,101,110,116,97, + 116,105,111,110,46,99,97,99,104,101,95,116,97,103,32,105, + 115,32,78,111,110,101,32,116,104,101,110,32,78,111,116,73, + 109,112,108,101,109,101,110,116,101,100,69,114,114,111,114,32, + 105,115,32,114,97,105,115,101,100,46,10,10,32,32,32,32, + 78,218,1,46,122,36,115,121,115,46,105,109,112,108,101,109, 101,110,116,97,116,105,111,110,46,99,97,99,104,101,95,116, - 97,103,32,105,115,32,78,111,110,101,122,37,123,125,32,110, - 111,116,32,98,111,116,116,111,109,45,108,101,118,101,108,32, - 100,105,114,101,99,116,111,114,121,32,105,110,32,123,33,114, - 125,114,116,0,0,0,114,115,0,0,0,122,28,101,120,112, - 101,99,116,101,100,32,111,110,108,121,32,50,32,100,111,116, - 115,32,105,110,32,123,33,114,125,114,84,0,0,0,41,12, - 114,7,0,0,0,114,122,0,0,0,114,123,0,0,0,114, - 124,0,0,0,114,38,0,0,0,114,125,0,0,0,218,10, - 86,97,108,117,101,69,114,114,111,114,114,47,0,0,0,114, - 89,0,0,0,114,121,0,0,0,114,28,0,0,0,218,15, - 83,79,85,82,67,69,95,83,85,70,70,73,88,69,83,41, - 5,114,35,0,0,0,114,128,0,0,0,90,16,112,121,99, - 97,99,104,101,95,102,105,108,101,110,97,109,101,90,7,112, - 121,99,97,99,104,101,114,129,0,0,0,114,4,0,0,0, - 114,4,0,0,0,114,5,0,0,0,218,17,115,111,117,114, - 99,101,95,102,114,111,109,95,99,97,99,104,101,207,1,0, - 0,115,24,0,0,0,0,9,18,1,15,1,18,1,18,1, - 12,1,3,1,24,1,21,1,3,1,21,1,19,1,114,135, - 0,0,0,99,1,0,0,0,0,0,0,0,5,0,0,0, - 13,0,0,0,67,0,0,0,115,164,0,0,0,116,0,0, - 124,0,0,131,1,0,100,1,0,107,2,0,114,22,0,100, - 2,0,83,124,0,0,106,1,0,100,3,0,131,1,0,92, - 3,0,125,1,0,125,2,0,125,3,0,124,1,0,12,115, - 81,0,124,3,0,106,2,0,131,0,0,100,7,0,100,8, - 0,133,2,0,25,100,6,0,107,3,0,114,85,0,124,0, - 0,83,121,16,0,116,3,0,124,0,0,131,1,0,125,4, - 0,87,110,40,0,4,116,4,0,116,5,0,102,2,0,107, - 10,0,114,143,0,1,1,1,124,0,0,100,2,0,100,9, - 0,133,2,0,25,125,4,0,89,110,1,0,88,116,6,0, - 124,4,0,131,1,0,114,160,0,124,4,0,83,124,0,0, - 83,41,10,122,188,67,111,110,118,101,114,116,32,97,32,98, - 121,116,101,99,111,100,101,32,102,105,108,101,32,112,97,116, - 104,32,116,111,32,97,32,115,111,117,114,99,101,32,112,97, - 116,104,32,40,105,102,32,112,111,115,115,105,98,108,101,41, - 46,10,10,32,32,32,32,84,104,105,115,32,102,117,110,99, - 116,105,111,110,32,101,120,105,115,116,115,32,112,117,114,101, - 108,121,32,102,111,114,32,98,97,99,107,119,97,114,100,115, - 45,99,111,109,112,97,116,105,98,105,108,105,116,121,32,102, - 111,114,10,32,32,32,32,80,121,73,109,112,111,114,116,95, - 69,120,101,99,67,111,100,101,77,111,100,117,108,101,87,105, - 116,104,70,105,108,101,110,97,109,101,115,40,41,32,105,110, - 32,116,104,101,32,67,32,65,80,73,46,10,10,32,32,32, - 32,114,84,0,0,0,78,114,116,0,0,0,233,3,0,0, - 0,114,29,0,0,0,90,2,112,121,233,253,255,255,255,233, - 255,255,255,255,114,138,0,0,0,41,7,114,31,0,0,0, - 114,32,0,0,0,218,5,108,111,119,101,114,114,135,0,0, - 0,114,124,0,0,0,114,133,0,0,0,114,44,0,0,0, - 41,5,218,13,98,121,116,101,99,111,100,101,95,112,97,116, - 104,90,4,114,101,115,116,114,36,0,0,0,90,9,101,120, - 116,101,110,115,105,111,110,218,11,115,111,117,114,99,101,95, - 112,97,116,104,114,4,0,0,0,114,4,0,0,0,114,5, - 0,0,0,218,15,95,103,101,116,95,115,111,117,114,99,101, - 102,105,108,101,230,1,0,0,115,20,0,0,0,0,7,18, - 1,4,1,24,1,35,1,4,1,3,1,16,1,19,1,21, - 1,114,142,0,0,0,99,1,0,0,0,0,0,0,0,2, - 0,0,0,11,0,0,0,67,0,0,0,115,60,0,0,0, - 121,19,0,116,0,0,124,0,0,131,1,0,106,1,0,125, - 1,0,87,110,24,0,4,116,2,0,107,10,0,114,45,0, - 1,1,1,100,1,0,125,1,0,89,110,1,0,88,124,1, - 0,100,2,0,79,125,1,0,124,1,0,83,41,3,122,51, - 67,97,108,99,117,108,97,116,101,32,116,104,101,32,109,111, - 100,101,32,112,101,114,109,105,115,115,105,111,110,115,32,102, - 111,114,32,97,32,98,121,116,101,99,111,100,101,32,102,105, - 108,101,46,105,182,1,0,0,233,128,0,0,0,41,3,114, - 39,0,0,0,114,41,0,0,0,114,40,0,0,0,41,2, - 114,35,0,0,0,114,42,0,0,0,114,4,0,0,0,114, - 4,0,0,0,114,5,0,0,0,218,10,95,99,97,108,99, - 95,109,111,100,101,249,1,0,0,115,12,0,0,0,0,2, - 3,1,19,1,13,1,11,3,10,1,114,144,0,0,0,218, - 9,118,101,114,98,111,115,105,116,121,114,29,0,0,0,99, - 1,0,0,0,1,0,0,0,3,0,0,0,4,0,0,0, - 71,0,0,0,115,81,0,0,0,116,0,0,106,1,0,106, - 2,0,124,1,0,107,5,0,114,77,0,124,0,0,106,3, - 0,100,6,0,131,1,0,115,46,0,100,3,0,124,0,0, - 23,125,0,0,110,0,0,116,4,0,124,0,0,106,5,0, - 124,2,0,140,0,0,100,4,0,116,0,0,106,6,0,131, - 1,1,1,110,0,0,100,5,0,83,41,7,122,61,80,114, - 105,110,116,32,116,104,101,32,109,101,115,115,97,103,101,32, - 116,111,32,115,116,100,101,114,114,32,105,102,32,45,118,47, - 80,89,84,72,79,78,86,69,82,66,79,83,69,32,105,115, - 32,116,117,114,110,101,100,32,111,110,46,250,1,35,250,7, - 105,109,112,111,114,116,32,122,2,35,32,114,54,0,0,0, - 78,41,2,114,146,0,0,0,114,147,0,0,0,41,7,114, - 7,0,0,0,114,117,0,0,0,218,7,118,101,114,98,111, - 115,101,114,9,0,0,0,218,5,112,114,105,110,116,114,47, - 0,0,0,218,6,115,116,100,101,114,114,41,3,218,7,109, - 101,115,115,97,103,101,114,145,0,0,0,114,80,0,0,0, - 114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,218, - 16,95,118,101,114,98,111,115,101,95,109,101,115,115,97,103, - 101,5,2,0,0,115,8,0,0,0,0,2,18,1,15,1, - 13,1,114,152,0,0,0,99,1,0,0,0,0,0,0,0, - 2,0,0,0,4,0,0,0,3,0,0,0,115,38,0,0, - 0,100,1,0,135,0,0,102,1,0,100,2,0,100,3,0, - 134,1,0,125,1,0,116,0,0,124,1,0,136,0,0,131, - 2,0,1,124,1,0,83,41,4,122,252,68,101,99,111,114, - 97,116,111,114,32,116,111,32,118,101,114,105,102,121,32,116, - 104,97,116,32,116,104,101,32,109,111,100,117,108,101,32,98, - 101,105,110,103,32,114,101,113,117,101,115,116,101,100,32,109, - 97,116,99,104,101,115,32,116,104,101,32,111,110,101,32,116, - 104,101,10,32,32,32,32,108,111,97,100,101,114,32,99,97, - 110,32,104,97,110,100,108,101,46,10,10,32,32,32,32,84, - 104,101,32,102,105,114,115,116,32,97,114,103,117,109,101,110, - 116,32,40,115,101,108,102,41,32,109,117,115,116,32,100,101, - 102,105,110,101,32,95,110,97,109,101,32,119,104,105,99,104, - 32,116,104,101,32,115,101,99,111,110,100,32,97,114,103,117, - 109,101,110,116,32,105,115,10,32,32,32,32,99,111,109,112, - 97,114,101,100,32,97,103,97,105,110,115,116,46,32,73,102, - 32,116,104,101,32,99,111,109,112,97,114,105,115,111,110,32, - 102,97,105,108,115,32,116,104,101,110,32,73,109,112,111,114, - 116,69,114,114,111,114,32,105,115,32,114,97,105,115,101,100, - 46,10,10,32,32,32,32,78,99,2,0,0,0,0,0,0, - 0,4,0,0,0,5,0,0,0,31,0,0,0,115,83,0, - 0,0,124,1,0,100,0,0,107,8,0,114,24,0,124,0, - 0,106,0,0,125,1,0,110,40,0,124,0,0,106,0,0, - 124,1,0,107,3,0,114,64,0,116,1,0,100,1,0,124, - 1,0,22,100,2,0,124,1,0,131,1,1,130,1,0,110, - 0,0,136,0,0,124,0,0,124,1,0,124,2,0,124,3, - 0,142,2,0,83,41,3,78,122,23,108,111,97,100,101,114, - 32,99,97,110,110,111,116,32,104,97,110,100,108,101,32,37, - 115,114,67,0,0,0,41,2,114,67,0,0,0,218,11,73, - 109,112,111,114,116,69,114,114,111,114,41,4,114,71,0,0, - 0,114,67,0,0,0,114,80,0,0,0,114,108,0,0,0, - 41,1,218,6,109,101,116,104,111,100,114,4,0,0,0,114, - 5,0,0,0,218,19,95,99,104,101,99,107,95,110,97,109, - 101,95,119,114,97,112,112,101,114,21,2,0,0,115,10,0, - 0,0,0,1,12,1,12,1,15,1,25,1,122,40,95,99, - 104,101,99,107,95,110,97,109,101,46,60,108,111,99,97,108, - 115,62,46,95,99,104,101,99,107,95,110,97,109,101,95,119, - 114,97,112,112,101,114,41,1,114,65,0,0,0,41,2,114, - 154,0,0,0,114,155,0,0,0,114,4,0,0,0,41,1, - 114,154,0,0,0,114,5,0,0,0,218,11,95,99,104,101, - 99,107,95,110,97,109,101,13,2,0,0,115,6,0,0,0, - 0,8,21,6,13,1,114,156,0,0,0,99,1,0,0,0, - 0,0,0,0,2,0,0,0,3,0,0,0,3,0,0,0, - 115,35,0,0,0,135,0,0,102,1,0,100,1,0,100,2, - 0,134,0,0,125,1,0,116,0,0,124,1,0,136,0,0, - 131,2,0,1,124,1,0,83,41,3,122,49,68,101,99,111, + 97,103,32,105,115,32,78,111,110,101,114,30,0,0,0,114, + 84,0,0,0,41,13,114,7,0,0,0,218,5,102,108,97, + 103,115,218,8,111,112,116,105,109,105,122,101,218,23,68,69, + 66,85,71,95,66,89,84,69,67,79,68,69,95,83,85,70, + 70,73,88,69,83,218,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,38,0,0,0,114,32,0,0,0,218,14,105,109, + 112,108,101,109,101,110,116,97,116,105,111,110,218,9,99,97, + 99,104,101,95,116,97,103,218,19,78,111,116,73,109,112,108, + 101,109,101,110,116,101,100,69,114,114,111,114,114,26,0,0, + 0,114,28,0,0,0,218,8,95,80,89,67,65,67,72,69, + 41,11,114,35,0,0,0,90,14,100,101,98,117,103,95,111, + 118,101,114,114,105,100,101,218,5,100,101,98,117,103,218,8, + 115,117,102,102,105,120,101,115,218,4,104,101,97,100,114,37, + 0,0,0,218,4,98,97,115,101,218,3,115,101,112,218,4, + 114,101,115,116,90,3,116,97,103,218,8,102,105,108,101,110, + 97,109,101,114,4,0,0,0,114,4,0,0,0,114,5,0, + 0,0,218,17,99,97,99,104,101,95,102,114,111,109,95,115, + 111,117,114,99,101,182,1,0,0,115,22,0,0,0,0,13, + 31,1,6,1,9,2,6,1,18,1,24,1,12,1,12,1, + 12,1,43,1,114,132,0,0,0,99,1,0,0,0,0,0, + 0,0,5,0,0,0,5,0,0,0,67,0,0,0,115,184, + 0,0,0,116,0,0,106,1,0,106,2,0,100,1,0,107, + 8,0,114,30,0,116,3,0,100,2,0,131,1,0,130,1, + 0,116,4,0,124,0,0,131,1,0,92,2,0,125,1,0, + 125,2,0,116,4,0,124,1,0,131,1,0,92,2,0,125, + 1,0,125,3,0,124,3,0,116,5,0,107,3,0,114,102, + 0,116,6,0,100,3,0,106,7,0,116,5,0,124,0,0, + 131,2,0,131,1,0,130,1,0,124,2,0,106,8,0,100, + 4,0,131,1,0,100,5,0,107,3,0,114,144,0,116,6, + 0,100,6,0,106,7,0,124,2,0,131,1,0,131,1,0, + 130,1,0,124,2,0,106,9,0,100,4,0,131,1,0,100, + 7,0,25,125,4,0,116,10,0,124,1,0,124,4,0,116, + 11,0,100,7,0,25,23,131,2,0,83,41,8,97,121,1, + 0,0,71,105,118,101,110,32,116,104,101,32,112,97,116,104, + 32,116,111,32,97,32,46,112,121,99,46,47,46,112,121,111, + 32,102,105,108,101,44,32,114,101,116,117,114,110,32,116,104, + 101,32,112,97,116,104,32,116,111,32,105,116,115,32,46,112, + 121,32,102,105,108,101,46,10,10,32,32,32,32,84,104,101, + 32,46,112,121,99,47,46,112,121,111,32,102,105,108,101,32, + 100,111,101,115,32,110,111,116,32,110,101,101,100,32,116,111, + 32,101,120,105,115,116,59,32,116,104,105,115,32,115,105,109, + 112,108,121,32,114,101,116,117,114,110,115,32,116,104,101,32, + 112,97,116,104,32,116,111,10,32,32,32,32,116,104,101,32, + 46,112,121,32,102,105,108,101,32,99,97,108,99,117,108,97, + 116,101,100,32,116,111,32,99,111,114,114,101,115,112,111,110, + 100,32,116,111,32,116,104,101,32,46,112,121,99,47,46,112, + 121,111,32,102,105,108,101,46,32,32,73,102,32,112,97,116, + 104,32,100,111,101,115,10,32,32,32,32,110,111,116,32,99, + 111,110,102,111,114,109,32,116,111,32,80,69,80,32,51,49, + 52,55,32,102,111,114,109,97,116,44,32,86,97,108,117,101, + 69,114,114,111,114,32,119,105,108,108,32,98,101,32,114,97, + 105,115,101,100,46,32,73,102,10,32,32,32,32,115,121,115, + 46,105,109,112,108,101,109,101,110,116,97,116,105,111,110,46, + 99,97,99,104,101,95,116,97,103,32,105,115,32,78,111,110, + 101,32,116,104,101,110,32,78,111,116,73,109,112,108,101,109, + 101,110,116,101,100,69,114,114,111,114,32,105,115,32,114,97, + 105,115,101,100,46,10,10,32,32,32,32,78,122,36,115,121, + 115,46,105,109,112,108,101,109,101,110,116,97,116,105,111,110, + 46,99,97,99,104,101,95,116,97,103,32,105,115,32,78,111, + 110,101,122,37,123,125,32,110,111,116,32,98,111,116,116,111, + 109,45,108,101,118,101,108,32,100,105,114,101,99,116,111,114, + 121,32,105,110,32,123,33,114,125,114,116,0,0,0,114,115, + 0,0,0,122,28,101,120,112,101,99,116,101,100,32,111,110, + 108,121,32,50,32,100,111,116,115,32,105,110,32,123,33,114, + 125,114,84,0,0,0,41,12,114,7,0,0,0,114,121,0, + 0,0,114,122,0,0,0,114,123,0,0,0,114,38,0,0, + 0,114,124,0,0,0,218,10,86,97,108,117,101,69,114,114, + 111,114,114,47,0,0,0,114,89,0,0,0,218,9,112,97, + 114,116,105,116,105,111,110,114,28,0,0,0,218,15,83,79, + 85,82,67,69,95,83,85,70,70,73,88,69,83,41,5,114, + 35,0,0,0,114,127,0,0,0,90,16,112,121,99,97,99, + 104,101,95,102,105,108,101,110,97,109,101,90,7,112,121,99, + 97,99,104,101,90,13,98,97,115,101,95,102,105,108,101,110, + 97,109,101,114,4,0,0,0,114,4,0,0,0,114,5,0, + 0,0,218,17,115,111,117,114,99,101,95,102,114,111,109,95, + 99,97,99,104,101,209,1,0,0,115,24,0,0,0,0,9, + 18,1,12,1,18,1,18,1,12,1,9,1,15,1,21,1, + 9,1,12,1,19,1,114,136,0,0,0,99,1,0,0,0, + 0,0,0,0,5,0,0,0,12,0,0,0,67,0,0,0, + 115,164,0,0,0,116,0,0,124,0,0,131,1,0,100,1, + 0,107,2,0,114,22,0,100,2,0,83,124,0,0,106,1, + 0,100,3,0,131,1,0,92,3,0,125,1,0,125,2,0, + 125,3,0,124,1,0,12,115,81,0,124,3,0,106,2,0, + 131,0,0,100,7,0,100,8,0,133,2,0,25,100,6,0, + 107,3,0,114,85,0,124,0,0,83,121,16,0,116,3,0, + 124,0,0,131,1,0,125,4,0,87,110,40,0,4,116,4, + 0,116,5,0,102,2,0,107,10,0,114,143,0,1,1,1, + 124,0,0,100,2,0,100,9,0,133,2,0,25,125,4,0, + 89,110,1,0,88,116,6,0,124,4,0,131,1,0,114,160, + 0,124,4,0,83,124,0,0,83,41,10,122,188,67,111,110, + 118,101,114,116,32,97,32,98,121,116,101,99,111,100,101,32, + 102,105,108,101,32,112,97,116,104,32,116,111,32,97,32,115, + 111,117,114,99,101,32,112,97,116,104,32,40,105,102,32,112, + 111,115,115,105,98,108,101,41,46,10,10,32,32,32,32,84, + 104,105,115,32,102,117,110,99,116,105,111,110,32,101,120,105, + 115,116,115,32,112,117,114,101,108,121,32,102,111,114,32,98, + 97,99,107,119,97,114,100,115,45,99,111,109,112,97,116,105, + 98,105,108,105,116,121,32,102,111,114,10,32,32,32,32,80, + 121,73,109,112,111,114,116,95,69,120,101,99,67,111,100,101, + 77,111,100,117,108,101,87,105,116,104,70,105,108,101,110,97, + 109,101,115,40,41,32,105,110,32,116,104,101,32,67,32,65, + 80,73,46,10,10,32,32,32,32,114,84,0,0,0,78,114, + 116,0,0,0,233,3,0,0,0,114,29,0,0,0,90,2, + 112,121,233,253,255,255,255,233,255,255,255,255,114,139,0,0, + 0,41,7,114,31,0,0,0,114,32,0,0,0,218,5,108, + 111,119,101,114,114,136,0,0,0,114,123,0,0,0,114,133, + 0,0,0,114,44,0,0,0,41,5,218,13,98,121,116,101, + 99,111,100,101,95,112,97,116,104,114,130,0,0,0,114,36, + 0,0,0,90,9,101,120,116,101,110,115,105,111,110,218,11, + 115,111,117,114,99,101,95,112,97,116,104,114,4,0,0,0, + 114,4,0,0,0,114,5,0,0,0,218,15,95,103,101,116, + 95,115,111,117,114,99,101,102,105,108,101,232,1,0,0,115, + 20,0,0,0,0,7,18,1,4,1,24,1,35,1,4,1, + 3,1,16,1,19,1,21,1,114,143,0,0,0,99,1,0, + 0,0,0,0,0,0,2,0,0,0,11,0,0,0,67,0, + 0,0,115,60,0,0,0,121,19,0,116,0,0,124,0,0, + 131,1,0,106,1,0,125,1,0,87,110,24,0,4,116,2, + 0,107,10,0,114,45,0,1,1,1,100,1,0,125,1,0, + 89,110,1,0,88,124,1,0,100,2,0,79,125,1,0,124, + 1,0,83,41,3,122,51,67,97,108,99,117,108,97,116,101, + 32,116,104,101,32,109,111,100,101,32,112,101,114,109,105,115, + 115,105,111,110,115,32,102,111,114,32,97,32,98,121,116,101, + 99,111,100,101,32,102,105,108,101,46,105,182,1,0,0,233, + 128,0,0,0,41,3,114,39,0,0,0,114,41,0,0,0, + 114,40,0,0,0,41,2,114,35,0,0,0,114,42,0,0, + 0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, + 218,10,95,99,97,108,99,95,109,111,100,101,251,1,0,0, + 115,12,0,0,0,0,2,3,1,19,1,13,1,11,3,10, + 1,114,145,0,0,0,218,9,118,101,114,98,111,115,105,116, + 121,114,29,0,0,0,99,1,0,0,0,1,0,0,0,3, + 0,0,0,4,0,0,0,71,0,0,0,115,75,0,0,0, + 116,0,0,106,1,0,106,2,0,124,1,0,107,5,0,114, + 71,0,124,0,0,106,3,0,100,6,0,131,1,0,115,43, + 0,100,3,0,124,0,0,23,125,0,0,116,4,0,124,0, + 0,106,5,0,124,2,0,140,0,0,100,4,0,116,0,0, + 106,6,0,131,1,1,1,100,5,0,83,41,7,122,61,80, + 114,105,110,116,32,116,104,101,32,109,101,115,115,97,103,101, + 32,116,111,32,115,116,100,101,114,114,32,105,102,32,45,118, + 47,80,89,84,72,79,78,86,69,82,66,79,83,69,32,105, + 115,32,116,117,114,110,101,100,32,111,110,46,250,1,35,250, + 7,105,109,112,111,114,116,32,122,2,35,32,114,54,0,0, + 0,78,41,2,114,147,0,0,0,114,148,0,0,0,41,7, + 114,7,0,0,0,114,117,0,0,0,218,7,118,101,114,98, + 111,115,101,114,9,0,0,0,218,5,112,114,105,110,116,114, + 47,0,0,0,218,6,115,116,100,101,114,114,41,3,218,7, + 109,101,115,115,97,103,101,114,146,0,0,0,114,80,0,0, + 0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, + 218,16,95,118,101,114,98,111,115,101,95,109,101,115,115,97, + 103,101,7,2,0,0,115,8,0,0,0,0,2,18,1,15, + 1,10,1,114,153,0,0,0,99,1,0,0,0,0,0,0, + 0,2,0,0,0,4,0,0,0,3,0,0,0,115,38,0, + 0,0,100,1,0,135,0,0,102,1,0,100,2,0,100,3, + 0,134,1,0,125,1,0,116,0,0,124,1,0,136,0,0, + 131,2,0,1,124,1,0,83,41,4,122,252,68,101,99,111, 114,97,116,111,114,32,116,111,32,118,101,114,105,102,121,32, - 116,104,101,32,110,97,109,101,100,32,109,111,100,117,108,101, - 32,105,115,32,98,117,105,108,116,45,105,110,46,99,2,0, - 0,0,0,0,0,0,2,0,0,0,4,0,0,0,19,0, - 0,0,115,58,0,0,0,124,1,0,116,0,0,106,1,0, - 107,7,0,114,45,0,116,2,0,100,1,0,106,3,0,124, - 1,0,131,1,0,100,2,0,124,1,0,131,1,1,130,1, - 0,110,0,0,136,0,0,124,0,0,124,1,0,131,2,0, - 83,41,3,78,122,29,123,33,114,125,32,105,115,32,110,111, - 116,32,97,32,98,117,105,108,116,45,105,110,32,109,111,100, - 117,108,101,114,67,0,0,0,41,4,114,7,0,0,0,218, - 20,98,117,105,108,116,105,110,95,109,111,100,117,108,101,95, - 110,97,109,101,115,114,153,0,0,0,114,47,0,0,0,41, - 2,114,71,0,0,0,218,8,102,117,108,108,110,97,109,101, - 41,1,218,3,102,120,110,114,4,0,0,0,114,5,0,0, - 0,218,25,95,114,101,113,117,105,114,101,115,95,98,117,105, - 108,116,105,110,95,119,114,97,112,112,101,114,33,2,0,0, - 115,8,0,0,0,0,1,15,1,18,1,12,1,122,52,95, - 114,101,113,117,105,114,101,115,95,98,117,105,108,116,105,110, - 46,60,108,111,99,97,108,115,62,46,95,114,101,113,117,105, - 114,101,115,95,98,117,105,108,116,105,110,95,119,114,97,112, - 112,101,114,41,1,114,65,0,0,0,41,2,114,159,0,0, - 0,114,160,0,0,0,114,4,0,0,0,41,1,114,159,0, - 0,0,114,5,0,0,0,218,17,95,114,101,113,117,105,114, - 101,115,95,98,117,105,108,116,105,110,31,2,0,0,115,6, - 0,0,0,0,2,18,5,13,1,114,161,0,0,0,99,1, - 0,0,0,0,0,0,0,2,0,0,0,3,0,0,0,3, - 0,0,0,115,35,0,0,0,135,0,0,102,1,0,100,1, - 0,100,2,0,134,0,0,125,1,0,116,0,0,124,1,0, - 136,0,0,131,2,0,1,124,1,0,83,41,3,122,47,68, - 101,99,111,114,97,116,111,114,32,116,111,32,118,101,114,105, - 102,121,32,116,104,101,32,110,97,109,101,100,32,109,111,100, - 117,108,101,32,105,115,32,102,114,111,122,101,110,46,99,2, - 0,0,0,0,0,0,0,2,0,0,0,4,0,0,0,19, - 0,0,0,115,58,0,0,0,116,0,0,106,1,0,124,1, - 0,131,1,0,115,45,0,116,2,0,100,1,0,106,3,0, - 124,1,0,131,1,0,100,2,0,124,1,0,131,1,1,130, - 1,0,110,0,0,136,0,0,124,0,0,124,1,0,131,2, - 0,83,41,3,78,122,27,123,33,114,125,32,105,115,32,110, - 111,116,32,97,32,102,114,111,122,101,110,32,109,111,100,117, - 108,101,114,67,0,0,0,41,4,114,106,0,0,0,218,9, - 105,115,95,102,114,111,122,101,110,114,153,0,0,0,114,47, - 0,0,0,41,2,114,71,0,0,0,114,158,0,0,0,41, - 1,114,159,0,0,0,114,4,0,0,0,114,5,0,0,0, - 218,24,95,114,101,113,117,105,114,101,115,95,102,114,111,122, - 101,110,95,119,114,97,112,112,101,114,44,2,0,0,115,8, - 0,0,0,0,1,15,1,18,1,12,1,122,50,95,114,101, - 113,117,105,114,101,115,95,102,114,111,122,101,110,46,60,108, - 111,99,97,108,115,62,46,95,114,101,113,117,105,114,101,115, - 95,102,114,111,122,101,110,95,119,114,97,112,112,101,114,41, - 1,114,65,0,0,0,41,2,114,159,0,0,0,114,163,0, - 0,0,114,4,0,0,0,41,1,114,159,0,0,0,114,5, - 0,0,0,218,16,95,114,101,113,117,105,114,101,115,95,102, - 114,111,122,101,110,42,2,0,0,115,6,0,0,0,0,2, - 18,5,13,1,114,164,0,0,0,99,2,0,0,0,0,0, - 0,0,5,0,0,0,5,0,0,0,67,0,0,0,115,87, - 0,0,0,124,0,0,106,0,0,124,1,0,131,1,0,92, - 2,0,125,2,0,125,3,0,124,2,0,100,1,0,107,8, - 0,114,83,0,116,1,0,124,3,0,131,1,0,114,83,0, - 100,2,0,125,4,0,116,2,0,106,3,0,124,4,0,106, - 4,0,124,3,0,100,3,0,25,131,1,0,116,5,0,131, - 2,0,1,110,0,0,124,2,0,83,41,4,122,86,84,114, - 121,32,116,111,32,102,105,110,100,32,97,32,108,111,97,100, - 101,114,32,102,111,114,32,116,104,101,32,115,112,101,99,105, - 102,105,101,100,32,109,111,100,117,108,101,32,98,121,32,100, - 101,108,101,103,97,116,105,110,103,32,116,111,10,32,32,32, - 32,115,101,108,102,46,102,105,110,100,95,108,111,97,100,101, - 114,40,41,46,78,122,44,78,111,116,32,105,109,112,111,114, - 116,105,110,103,32,100,105,114,101,99,116,111,114,121,32,123, - 125,58,32,109,105,115,115,105,110,103,32,95,95,105,110,105, - 116,95,95,114,84,0,0,0,41,6,218,11,102,105,110,100, - 95,108,111,97,100,101,114,114,31,0,0,0,218,9,95,119, - 97,114,110,105,110,103,115,218,4,119,97,114,110,114,47,0, - 0,0,218,13,73,109,112,111,114,116,87,97,114,110,105,110, - 103,41,5,114,71,0,0,0,114,158,0,0,0,218,6,108, - 111,97,100,101,114,218,8,112,111,114,116,105,111,110,115,218, - 3,109,115,103,114,4,0,0,0,114,4,0,0,0,114,5, - 0,0,0,218,17,95,102,105,110,100,95,109,111,100,117,108, - 101,95,115,104,105,109,53,2,0,0,115,10,0,0,0,0, - 6,21,1,24,1,6,1,32,1,114,172,0,0,0,99,2, - 0,0,0,0,0,0,0,5,0,0,0,3,0,0,0,67, - 0,0,0,115,93,0,0,0,116,0,0,124,1,0,124,0, - 0,131,2,0,125,2,0,116,1,0,124,2,0,131,1,0, - 125,3,0,124,1,0,116,2,0,106,3,0,107,6,0,114, - 79,0,116,2,0,106,3,0,124,1,0,25,125,4,0,124, - 3,0,106,4,0,124,4,0,131,1,0,1,116,2,0,106, - 3,0,124,1,0,25,83,124,3,0,106,5,0,131,0,0, - 83,100,1,0,83,41,2,122,57,76,111,97,100,32,116,104, - 101,32,115,112,101,99,105,102,105,101,100,32,109,111,100,117, - 108,101,32,105,110,116,111,32,115,121,115,46,109,111,100,117, - 108,101,115,32,97,110,100,32,114,101,116,117,114,110,32,105, - 116,46,78,41,6,218,16,115,112,101,99,95,102,114,111,109, - 95,108,111,97,100,101,114,218,12,95,83,112,101,99,77,101, - 116,104,111,100,115,114,7,0,0,0,114,73,0,0,0,218, - 4,101,120,101,99,218,4,108,111,97,100,41,5,114,71,0, - 0,0,114,158,0,0,0,218,4,115,112,101,99,218,7,109, - 101,116,104,111,100,115,218,6,109,111,100,117,108,101,114,4, + 116,104,97,116,32,116,104,101,32,109,111,100,117,108,101,32, + 98,101,105,110,103,32,114,101,113,117,101,115,116,101,100,32, + 109,97,116,99,104,101,115,32,116,104,101,32,111,110,101,32, + 116,104,101,10,32,32,32,32,108,111,97,100,101,114,32,99, + 97,110,32,104,97,110,100,108,101,46,10,10,32,32,32,32, + 84,104,101,32,102,105,114,115,116,32,97,114,103,117,109,101, + 110,116,32,40,115,101,108,102,41,32,109,117,115,116,32,100, + 101,102,105,110,101,32,95,110,97,109,101,32,119,104,105,99, + 104,32,116,104,101,32,115,101,99,111,110,100,32,97,114,103, + 117,109,101,110,116,32,105,115,10,32,32,32,32,99,111,109, + 112,97,114,101,100,32,97,103,97,105,110,115,116,46,32,73, + 102,32,116,104,101,32,99,111,109,112,97,114,105,115,111,110, + 32,102,97,105,108,115,32,116,104,101,110,32,73,109,112,111, + 114,116,69,114,114,111,114,32,105,115,32,114,97,105,115,101, + 100,46,10,10,32,32,32,32,78,99,2,0,0,0,0,0, + 0,0,4,0,0,0,5,0,0,0,31,0,0,0,115,80, + 0,0,0,124,1,0,100,0,0,107,8,0,114,24,0,124, + 0,0,106,0,0,125,1,0,110,37,0,124,0,0,106,0, + 0,124,1,0,107,3,0,114,61,0,116,1,0,100,1,0, + 124,1,0,22,100,2,0,124,1,0,131,1,1,130,1,0, + 136,0,0,124,0,0,124,1,0,124,2,0,124,3,0,142, + 2,0,83,41,3,78,122,23,108,111,97,100,101,114,32,99, + 97,110,110,111,116,32,104,97,110,100,108,101,32,37,115,114, + 67,0,0,0,41,2,114,67,0,0,0,218,11,73,109,112, + 111,114,116,69,114,114,111,114,41,4,114,71,0,0,0,114, + 67,0,0,0,114,80,0,0,0,114,108,0,0,0,41,1, + 218,6,109,101,116,104,111,100,114,4,0,0,0,114,5,0, + 0,0,218,19,95,99,104,101,99,107,95,110,97,109,101,95, + 119,114,97,112,112,101,114,23,2,0,0,115,10,0,0,0, + 0,1,12,1,12,1,15,1,22,1,122,40,95,99,104,101, + 99,107,95,110,97,109,101,46,60,108,111,99,97,108,115,62, + 46,95,99,104,101,99,107,95,110,97,109,101,95,119,114,97, + 112,112,101,114,41,1,114,65,0,0,0,41,2,114,155,0, + 0,0,114,156,0,0,0,114,4,0,0,0,41,1,114,155, + 0,0,0,114,5,0,0,0,218,11,95,99,104,101,99,107, + 95,110,97,109,101,15,2,0,0,115,6,0,0,0,0,8, + 21,6,13,1,114,157,0,0,0,99,1,0,0,0,0,0, + 0,0,2,0,0,0,3,0,0,0,3,0,0,0,115,35, + 0,0,0,135,0,0,102,1,0,100,1,0,100,2,0,134, + 0,0,125,1,0,116,0,0,124,1,0,136,0,0,131,2, + 0,1,124,1,0,83,41,3,122,49,68,101,99,111,114,97, + 116,111,114,32,116,111,32,118,101,114,105,102,121,32,116,104, + 101,32,110,97,109,101,100,32,109,111,100,117,108,101,32,105, + 115,32,98,117,105,108,116,45,105,110,46,99,2,0,0,0, + 0,0,0,0,2,0,0,0,4,0,0,0,19,0,0,0, + 115,55,0,0,0,124,1,0,116,0,0,106,1,0,107,7, + 0,114,42,0,116,2,0,100,1,0,106,3,0,124,1,0, + 131,1,0,100,2,0,124,1,0,131,1,1,130,1,0,136, + 0,0,124,0,0,124,1,0,131,2,0,83,41,3,78,122, + 29,123,33,114,125,32,105,115,32,110,111,116,32,97,32,98, + 117,105,108,116,45,105,110,32,109,111,100,117,108,101,114,67, + 0,0,0,41,4,114,7,0,0,0,218,20,98,117,105,108, + 116,105,110,95,109,111,100,117,108,101,95,110,97,109,101,115, + 114,154,0,0,0,114,47,0,0,0,41,2,114,71,0,0, + 0,218,8,102,117,108,108,110,97,109,101,41,1,218,3,102, + 120,110,114,4,0,0,0,114,5,0,0,0,218,25,95,114, + 101,113,117,105,114,101,115,95,98,117,105,108,116,105,110,95, + 119,114,97,112,112,101,114,35,2,0,0,115,8,0,0,0, + 0,1,15,1,18,1,9,1,122,52,95,114,101,113,117,105, + 114,101,115,95,98,117,105,108,116,105,110,46,60,108,111,99, + 97,108,115,62,46,95,114,101,113,117,105,114,101,115,95,98, + 117,105,108,116,105,110,95,119,114,97,112,112,101,114,41,1, + 114,65,0,0,0,41,2,114,160,0,0,0,114,161,0,0, + 0,114,4,0,0,0,41,1,114,160,0,0,0,114,5,0, + 0,0,218,17,95,114,101,113,117,105,114,101,115,95,98,117, + 105,108,116,105,110,33,2,0,0,115,6,0,0,0,0,2, + 18,5,13,1,114,162,0,0,0,99,1,0,0,0,0,0, + 0,0,2,0,0,0,3,0,0,0,3,0,0,0,115,35, + 0,0,0,135,0,0,102,1,0,100,1,0,100,2,0,134, + 0,0,125,1,0,116,0,0,124,1,0,136,0,0,131,2, + 0,1,124,1,0,83,41,3,122,47,68,101,99,111,114,97, + 116,111,114,32,116,111,32,118,101,114,105,102,121,32,116,104, + 101,32,110,97,109,101,100,32,109,111,100,117,108,101,32,105, + 115,32,102,114,111,122,101,110,46,99,2,0,0,0,0,0, + 0,0,2,0,0,0,4,0,0,0,19,0,0,0,115,55, + 0,0,0,116,0,0,106,1,0,124,1,0,131,1,0,115, + 42,0,116,2,0,100,1,0,106,3,0,124,1,0,131,1, + 0,100,2,0,124,1,0,131,1,1,130,1,0,136,0,0, + 124,0,0,124,1,0,131,2,0,83,41,3,78,122,27,123, + 33,114,125,32,105,115,32,110,111,116,32,97,32,102,114,111, + 122,101,110,32,109,111,100,117,108,101,114,67,0,0,0,41, + 4,114,106,0,0,0,218,9,105,115,95,102,114,111,122,101, + 110,114,154,0,0,0,114,47,0,0,0,41,2,114,71,0, + 0,0,114,159,0,0,0,41,1,114,160,0,0,0,114,4, + 0,0,0,114,5,0,0,0,218,24,95,114,101,113,117,105, + 114,101,115,95,102,114,111,122,101,110,95,119,114,97,112,112, + 101,114,46,2,0,0,115,8,0,0,0,0,1,15,1,18, + 1,9,1,122,50,95,114,101,113,117,105,114,101,115,95,102, + 114,111,122,101,110,46,60,108,111,99,97,108,115,62,46,95, + 114,101,113,117,105,114,101,115,95,102,114,111,122,101,110,95, + 119,114,97,112,112,101,114,41,1,114,65,0,0,0,41,2, + 114,160,0,0,0,114,164,0,0,0,114,4,0,0,0,41, + 1,114,160,0,0,0,114,5,0,0,0,218,16,95,114,101, + 113,117,105,114,101,115,95,102,114,111,122,101,110,44,2,0, + 0,115,6,0,0,0,0,2,18,5,13,1,114,165,0,0, + 0,99,2,0,0,0,0,0,0,0,5,0,0,0,4,0, + 0,0,67,0,0,0,115,84,0,0,0,124,0,0,106,0, + 0,124,1,0,131,1,0,92,2,0,125,2,0,125,3,0, + 124,2,0,100,1,0,107,8,0,114,80,0,116,1,0,124, + 3,0,131,1,0,114,80,0,100,2,0,125,4,0,116,2, + 0,106,3,0,124,4,0,106,4,0,124,3,0,100,3,0, + 25,131,1,0,116,5,0,131,2,0,1,124,2,0,83,41, + 4,122,155,84,114,121,32,116,111,32,102,105,110,100,32,97, + 32,108,111,97,100,101,114,32,102,111,114,32,116,104,101,32, + 115,112,101,99,105,102,105,101,100,32,109,111,100,117,108,101, + 32,98,121,32,100,101,108,101,103,97,116,105,110,103,32,116, + 111,10,32,32,32,32,115,101,108,102,46,102,105,110,100,95, + 108,111,97,100,101,114,40,41,46,10,10,32,32,32,32,84, + 104,105,115,32,109,101,116,104,111,100,32,105,115,32,100,101, + 112,114,101,99,97,116,101,100,32,105,110,32,102,97,118,111, + 114,32,111,102,32,102,105,110,100,101,114,46,102,105,110,100, + 95,115,112,101,99,40,41,46,10,10,32,32,32,32,78,122, + 44,78,111,116,32,105,109,112,111,114,116,105,110,103,32,100, + 105,114,101,99,116,111,114,121,32,123,125,58,32,109,105,115, + 115,105,110,103,32,95,95,105,110,105,116,95,95,114,84,0, + 0,0,41,6,218,11,102,105,110,100,95,108,111,97,100,101, + 114,114,31,0,0,0,218,9,95,119,97,114,110,105,110,103, + 115,218,4,119,97,114,110,114,47,0,0,0,218,13,73,109, + 112,111,114,116,87,97,114,110,105,110,103,41,5,114,71,0, + 0,0,114,159,0,0,0,218,6,108,111,97,100,101,114,218, + 8,112,111,114,116,105,111,110,115,218,3,109,115,103,114,4, + 0,0,0,114,4,0,0,0,114,5,0,0,0,218,17,95, + 102,105,110,100,95,109,111,100,117,108,101,95,115,104,105,109, + 55,2,0,0,115,10,0,0,0,0,10,21,1,24,1,6, + 1,29,1,114,173,0,0,0,99,2,0,0,0,0,0,0, + 0,4,0,0,0,3,0,0,0,67,0,0,0,115,81,0, + 0,0,116,0,0,124,1,0,124,0,0,131,2,0,125,2, + 0,124,1,0,116,1,0,106,2,0,107,6,0,114,67,0, + 116,1,0,106,2,0,124,1,0,25,125,3,0,116,3,0, + 124,2,0,124,3,0,131,2,0,1,116,1,0,106,2,0, + 124,1,0,25,83,116,4,0,124,2,0,131,1,0,83,100, + 1,0,83,41,2,122,128,76,111,97,100,32,116,104,101,32, + 115,112,101,99,105,102,105,101,100,32,109,111,100,117,108,101, + 32,105,110,116,111,32,115,121,115,46,109,111,100,117,108,101, + 115,32,97,110,100,32,114,101,116,117,114,110,32,105,116,46, + 10,10,32,32,32,32,84,104,105,115,32,109,101,116,104,111, + 100,32,105,115,32,100,101,112,114,101,99,97,116,101,100,46, + 32,32,85,115,101,32,108,111,97,100,101,114,46,101,120,101, + 99,95,109,111,100,117,108,101,32,105,110,115,116,101,97,100, + 46,10,10,32,32,32,32,78,41,5,218,16,115,112,101,99, + 95,102,114,111,109,95,108,111,97,100,101,114,114,7,0,0, + 0,114,73,0,0,0,218,5,95,101,120,101,99,218,5,95, + 108,111,97,100,41,4,114,71,0,0,0,114,159,0,0,0, + 218,4,115,112,101,99,218,6,109,111,100,117,108,101,114,4, 0,0,0,114,4,0,0,0,114,5,0,0,0,218,17,95, 108,111,97,100,95,109,111,100,117,108,101,95,115,104,105,109, - 66,2,0,0,115,14,0,0,0,0,3,15,1,12,1,15, - 1,13,1,13,1,11,2,114,180,0,0,0,99,4,0,0, - 0,0,0,0,0,11,0,0,0,19,0,0,0,67,0,0, - 0,115,243,1,0,0,105,0,0,125,4,0,124,2,0,100, - 1,0,107,9,0,114,31,0,124,2,0,124,4,0,100,2, - 0,60,110,6,0,100,3,0,125,2,0,124,3,0,100,1, - 0,107,9,0,114,62,0,124,3,0,124,4,0,100,4,0, - 60,110,0,0,124,0,0,100,1,0,100,5,0,133,2,0, - 25,125,5,0,124,0,0,100,5,0,100,6,0,133,2,0, - 25,125,6,0,124,0,0,100,6,0,100,7,0,133,2,0, - 25,125,7,0,124,5,0,116,0,0,107,3,0,114,168,0, - 100,8,0,106,1,0,124,2,0,124,5,0,131,2,0,125, - 8,0,116,2,0,124,8,0,131,1,0,1,116,3,0,124, - 8,0,124,4,0,141,1,0,130,1,0,110,116,0,116,4, - 0,124,6,0,131,1,0,100,5,0,107,3,0,114,226,0, - 100,9,0,106,1,0,124,2,0,131,1,0,125,8,0,116, - 2,0,124,8,0,131,1,0,1,116,5,0,124,8,0,131, - 1,0,130,1,0,110,58,0,116,4,0,124,7,0,131,1, - 0,100,5,0,107,3,0,114,28,1,100,10,0,106,1,0, - 124,2,0,131,1,0,125,8,0,116,2,0,124,8,0,131, - 1,0,1,116,5,0,124,8,0,131,1,0,130,1,0,110, - 0,0,124,1,0,100,1,0,107,9,0,114,229,1,121,20, - 0,116,6,0,124,1,0,100,11,0,25,131,1,0,125,9, - 0,87,110,18,0,4,116,7,0,107,10,0,114,80,1,1, - 1,1,89,110,62,0,88,116,8,0,124,6,0,131,1,0, - 124,9,0,107,3,0,114,142,1,100,12,0,106,1,0,124, - 2,0,131,1,0,125,8,0,116,2,0,124,8,0,131,1, - 0,1,116,3,0,124,8,0,124,4,0,141,1,0,130,1, - 0,110,0,0,121,18,0,124,1,0,100,13,0,25,100,14, - 0,64,125,10,0,87,110,18,0,4,116,7,0,107,10,0, - 114,180,1,1,1,1,89,113,229,1,88,116,8,0,124,7, - 0,131,1,0,124,10,0,107,3,0,114,229,1,116,3,0, - 100,12,0,106,1,0,124,2,0,131,1,0,124,4,0,141, - 1,0,130,1,0,113,229,1,110,0,0,124,0,0,100,7, - 0,100,1,0,133,2,0,25,83,41,15,97,122,1,0,0, - 86,97,108,105,100,97,116,101,32,116,104,101,32,104,101,97, - 100,101,114,32,111,102,32,116,104,101,32,112,97,115,115,101, - 100,45,105,110,32,98,121,116,101,99,111,100,101,32,97,103, - 97,105,110,115,116,32,115,111,117,114,99,101,95,115,116,97, - 116,115,32,40,105,102,10,32,32,32,32,103,105,118,101,110, - 41,32,97,110,100,32,114,101,116,117,114,110,105,110,103,32, - 116,104,101,32,98,121,116,101,99,111,100,101,32,116,104,97, - 116,32,99,97,110,32,98,101,32,99,111,109,112,105,108,101, - 100,32,98,121,32,99,111,109,112,105,108,101,40,41,46,10, - 10,32,32,32,32,65,108,108,32,111,116,104,101,114,32,97, - 114,103,117,109,101,110,116,115,32,97,114,101,32,117,115,101, - 100,32,116,111,32,101,110,104,97,110,99,101,32,101,114,114, - 111,114,32,114,101,112,111,114,116,105,110,103,46,10,10,32, - 32,32,32,73,109,112,111,114,116,69,114,114,111,114,32,105, - 115,32,114,97,105,115,101,100,32,119,104,101,110,32,116,104, - 101,32,109,97,103,105,99,32,110,117,109,98,101,114,32,105, - 115,32,105,110,99,111,114,114,101,99,116,32,111,114,32,116, - 104,101,32,98,121,116,101,99,111,100,101,32,105,115,10,32, - 32,32,32,102,111,117,110,100,32,116,111,32,98,101,32,115, - 116,97,108,101,46,32,69,79,70,69,114,114,111,114,32,105, - 115,32,114,97,105,115,101,100,32,119,104,101,110,32,116,104, - 101,32,100,97,116,97,32,105,115,32,102,111,117,110,100,32, - 116,111,32,98,101,10,32,32,32,32,116,114,117,110,99,97, - 116,101,100,46,10,10,32,32,32,32,78,114,67,0,0,0, - 122,10,60,98,121,116,101,99,111,100,101,62,114,35,0,0, - 0,114,12,0,0,0,233,8,0,0,0,233,12,0,0,0, - 122,30,98,97,100,32,109,97,103,105,99,32,110,117,109,98, - 101,114,32,105,110,32,123,33,114,125,58,32,123,33,114,125, - 122,43,114,101,97,99,104,101,100,32,69,79,70,32,119,104, - 105,108,101,32,114,101,97,100,105,110,103,32,116,105,109,101, - 115,116,97,109,112,32,105,110,32,123,33,114,125,122,48,114, - 101,97,99,104,101,100,32,69,79,70,32,119,104,105,108,101, - 32,114,101,97,100,105,110,103,32,115,105,122,101,32,111,102, - 32,115,111,117,114,99,101,32,105,110,32,123,33,114,125,218, - 5,109,116,105,109,101,122,26,98,121,116,101,99,111,100,101, - 32,105,115,32,115,116,97,108,101,32,102,111,114,32,123,33, - 114,125,218,4,115,105,122,101,108,3,0,0,0,255,127,255, - 127,3,0,41,9,218,12,77,65,71,73,67,95,78,85,77, - 66,69,82,114,47,0,0,0,114,152,0,0,0,114,153,0, - 0,0,114,31,0,0,0,218,8,69,79,70,69,114,114,111, - 114,114,14,0,0,0,114,79,0,0,0,114,19,0,0,0, - 41,11,114,53,0,0,0,218,12,115,111,117,114,99,101,95, - 115,116,97,116,115,114,67,0,0,0,114,35,0,0,0,90, - 11,101,120,99,95,100,101,116,97,105,108,115,90,5,109,97, - 103,105,99,90,13,114,97,119,95,116,105,109,101,115,116,97, - 109,112,90,8,114,97,119,95,115,105,122,101,114,151,0,0, - 0,218,12,115,111,117,114,99,101,95,109,116,105,109,101,218, - 11,115,111,117,114,99,101,95,115,105,122,101,114,4,0,0, - 0,114,4,0,0,0,114,5,0,0,0,218,25,95,118,97, + 73,2,0,0,115,12,0,0,0,0,6,15,1,15,1,13, + 1,13,1,11,2,114,179,0,0,0,99,4,0,0,0,0, + 0,0,0,11,0,0,0,19,0,0,0,67,0,0,0,115, + 228,1,0,0,105,0,0,125,4,0,124,2,0,100,1,0, + 107,9,0,114,31,0,124,2,0,124,4,0,100,2,0,60, + 110,6,0,100,3,0,125,2,0,124,3,0,100,1,0,107, + 9,0,114,59,0,124,3,0,124,4,0,100,4,0,60,124, + 0,0,100,1,0,100,5,0,133,2,0,25,125,5,0,124, + 0,0,100,5,0,100,6,0,133,2,0,25,125,6,0,124, + 0,0,100,6,0,100,7,0,133,2,0,25,125,7,0,124, + 5,0,116,0,0,107,3,0,114,165,0,100,8,0,106,1, + 0,124,2,0,124,5,0,131,2,0,125,8,0,116,2,0, + 124,8,0,131,1,0,1,116,3,0,124,8,0,124,4,0, + 141,1,0,130,1,0,110,113,0,116,4,0,124,6,0,131, + 1,0,100,5,0,107,3,0,114,223,0,100,9,0,106,1, + 0,124,2,0,131,1,0,125,8,0,116,2,0,124,8,0, + 131,1,0,1,116,5,0,124,8,0,131,1,0,130,1,0, + 110,55,0,116,4,0,124,7,0,131,1,0,100,5,0,107, + 3,0,114,22,1,100,10,0,106,1,0,124,2,0,131,1, + 0,125,8,0,116,2,0,124,8,0,131,1,0,1,116,5, + 0,124,8,0,131,1,0,130,1,0,124,1,0,100,1,0, + 107,9,0,114,214,1,121,20,0,116,6,0,124,1,0,100, + 11,0,25,131,1,0,125,9,0,87,110,18,0,4,116,7, + 0,107,10,0,114,74,1,1,1,1,89,110,59,0,88,116, + 8,0,124,6,0,131,1,0,124,9,0,107,3,0,114,133, + 1,100,12,0,106,1,0,124,2,0,131,1,0,125,8,0, + 116,2,0,124,8,0,131,1,0,1,116,3,0,124,8,0, + 124,4,0,141,1,0,130,1,0,121,18,0,124,1,0,100, + 13,0,25,100,14,0,64,125,10,0,87,110,18,0,4,116, + 7,0,107,10,0,114,171,1,1,1,1,89,110,43,0,88, + 116,8,0,124,7,0,131,1,0,124,10,0,107,3,0,114, + 214,1,116,3,0,100,12,0,106,1,0,124,2,0,131,1, + 0,124,4,0,141,1,0,130,1,0,124,0,0,100,7,0, + 100,1,0,133,2,0,25,83,41,15,97,122,1,0,0,86, + 97,108,105,100,97,116,101,32,116,104,101,32,104,101,97,100, + 101,114,32,111,102,32,116,104,101,32,112,97,115,115,101,100, + 45,105,110,32,98,121,116,101,99,111,100,101,32,97,103,97, + 105,110,115,116,32,115,111,117,114,99,101,95,115,116,97,116, + 115,32,40,105,102,10,32,32,32,32,103,105,118,101,110,41, + 32,97,110,100,32,114,101,116,117,114,110,105,110,103,32,116, + 104,101,32,98,121,116,101,99,111,100,101,32,116,104,97,116, + 32,99,97,110,32,98,101,32,99,111,109,112,105,108,101,100, + 32,98,121,32,99,111,109,112,105,108,101,40,41,46,10,10, + 32,32,32,32,65,108,108,32,111,116,104,101,114,32,97,114, + 103,117,109,101,110,116,115,32,97,114,101,32,117,115,101,100, + 32,116,111,32,101,110,104,97,110,99,101,32,101,114,114,111, + 114,32,114,101,112,111,114,116,105,110,103,46,10,10,32,32, + 32,32,73,109,112,111,114,116,69,114,114,111,114,32,105,115, + 32,114,97,105,115,101,100,32,119,104,101,110,32,116,104,101, + 32,109,97,103,105,99,32,110,117,109,98,101,114,32,105,115, + 32,105,110,99,111,114,114,101,99,116,32,111,114,32,116,104, + 101,32,98,121,116,101,99,111,100,101,32,105,115,10,32,32, + 32,32,102,111,117,110,100,32,116,111,32,98,101,32,115,116, + 97,108,101,46,32,69,79,70,69,114,114,111,114,32,105,115, + 32,114,97,105,115,101,100,32,119,104,101,110,32,116,104,101, + 32,100,97,116,97,32,105,115,32,102,111,117,110,100,32,116, + 111,32,98,101,10,32,32,32,32,116,114,117,110,99,97,116, + 101,100,46,10,10,32,32,32,32,78,114,67,0,0,0,122, + 10,60,98,121,116,101,99,111,100,101,62,114,35,0,0,0, + 114,12,0,0,0,233,8,0,0,0,233,12,0,0,0,122, + 30,98,97,100,32,109,97,103,105,99,32,110,117,109,98,101, + 114,32,105,110,32,123,33,114,125,58,32,123,33,114,125,122, + 43,114,101,97,99,104,101,100,32,69,79,70,32,119,104,105, + 108,101,32,114,101,97,100,105,110,103,32,116,105,109,101,115, + 116,97,109,112,32,105,110,32,123,33,114,125,122,48,114,101, + 97,99,104,101,100,32,69,79,70,32,119,104,105,108,101,32, + 114,101,97,100,105,110,103,32,115,105,122,101,32,111,102,32, + 115,111,117,114,99,101,32,105,110,32,123,33,114,125,218,5, + 109,116,105,109,101,122,26,98,121,116,101,99,111,100,101,32, + 105,115,32,115,116,97,108,101,32,102,111,114,32,123,33,114, + 125,218,4,115,105,122,101,108,3,0,0,0,255,127,255,127, + 3,0,41,9,218,12,77,65,71,73,67,95,78,85,77,66, + 69,82,114,47,0,0,0,114,153,0,0,0,114,154,0,0, + 0,114,31,0,0,0,218,8,69,79,70,69,114,114,111,114, + 114,14,0,0,0,114,79,0,0,0,114,19,0,0,0,41, + 11,114,53,0,0,0,218,12,115,111,117,114,99,101,95,115, + 116,97,116,115,114,67,0,0,0,114,35,0,0,0,90,11, + 101,120,99,95,100,101,116,97,105,108,115,90,5,109,97,103, + 105,99,90,13,114,97,119,95,116,105,109,101,115,116,97,109, + 112,90,8,114,97,119,95,115,105,122,101,114,152,0,0,0, + 218,12,115,111,117,114,99,101,95,109,116,105,109,101,218,11, + 115,111,117,114,99,101,95,115,105,122,101,114,4,0,0,0, + 114,4,0,0,0,114,5,0,0,0,218,25,95,118,97,108, + 105,100,97,116,101,95,98,121,116,101,99,111,100,101,95,104, + 101,97,100,101,114,88,2,0,0,115,76,0,0,0,0,11, + 6,1,12,1,13,3,6,1,12,1,10,1,16,1,16,1, + 16,1,12,1,18,1,10,1,18,1,18,1,15,1,10,1, + 15,1,18,1,15,1,10,1,12,1,12,1,3,1,20,1, + 13,1,5,2,18,1,15,1,10,1,15,1,3,1,18,1, + 13,1,5,2,18,1,15,1,9,1,114,189,0,0,0,99, + 4,0,0,0,0,0,0,0,5,0,0,0,6,0,0,0, + 67,0,0,0,115,112,0,0,0,116,0,0,106,1,0,124, + 0,0,131,1,0,125,4,0,116,2,0,124,4,0,116,3, + 0,131,2,0,114,75,0,116,4,0,100,1,0,124,2,0, + 131,2,0,1,124,3,0,100,2,0,107,9,0,114,71,0, + 116,5,0,106,6,0,124,4,0,124,3,0,131,2,0,1, + 124,4,0,83,116,7,0,100,3,0,106,8,0,124,2,0, + 131,1,0,100,4,0,124,1,0,100,5,0,124,2,0,131, + 1,2,130,1,0,100,2,0,83,41,6,122,60,67,111,109, + 112,105,108,101,32,98,121,116,101,99,111,100,101,32,97,115, + 32,114,101,116,117,114,110,101,100,32,98,121,32,95,118,97, 108,105,100,97,116,101,95,98,121,116,101,99,111,100,101,95, - 104,101,97,100,101,114,79,2,0,0,115,76,0,0,0,0, - 11,6,1,12,1,13,3,6,1,12,1,13,1,16,1,16, - 1,16,1,12,1,18,1,10,1,18,1,18,1,15,1,10, - 1,15,1,18,1,15,1,10,1,15,1,12,1,3,1,20, - 1,13,1,5,2,18,1,15,1,10,1,18,1,3,1,18, - 1,13,1,5,2,18,1,15,1,15,1,114,190,0,0,0, - 99,4,0,0,0,0,0,0,0,5,0,0,0,6,0,0, - 0,67,0,0,0,115,115,0,0,0,116,0,0,106,1,0, - 124,0,0,131,1,0,125,4,0,116,2,0,124,4,0,116, - 3,0,131,2,0,114,78,0,116,4,0,100,1,0,124,2, - 0,131,2,0,1,124,3,0,100,2,0,107,9,0,114,74, - 0,116,5,0,106,6,0,124,4,0,124,3,0,131,2,0, - 1,110,0,0,124,4,0,83,116,7,0,100,3,0,106,8, - 0,124,2,0,131,1,0,100,4,0,124,1,0,100,5,0, - 124,2,0,131,1,2,130,1,0,100,2,0,83,41,6,122, - 60,67,111,109,112,105,108,101,32,98,121,116,101,99,111,100, - 101,32,97,115,32,114,101,116,117,114,110,101,100,32,98,121, - 32,95,118,97,108,105,100,97,116,101,95,98,121,116,101,99, - 111,100,101,95,104,101,97,100,101,114,40,41,46,122,21,99, - 111,100,101,32,111,98,106,101,99,116,32,102,114,111,109,32, - 123,33,114,125,78,122,23,78,111,110,45,99,111,100,101,32, - 111,98,106,101,99,116,32,105,110,32,123,33,114,125,114,67, - 0,0,0,114,35,0,0,0,41,9,218,7,109,97,114,115, - 104,97,108,90,5,108,111,97,100,115,218,10,105,115,105,110, - 115,116,97,110,99,101,218,10,95,99,111,100,101,95,116,121, - 112,101,114,152,0,0,0,114,106,0,0,0,90,16,95,102, - 105,120,95,99,111,95,102,105,108,101,110,97,109,101,114,153, - 0,0,0,114,47,0,0,0,41,5,114,53,0,0,0,114, - 67,0,0,0,114,140,0,0,0,114,141,0,0,0,218,4, - 99,111,100,101,114,4,0,0,0,114,4,0,0,0,114,5, - 0,0,0,218,17,95,99,111,109,112,105,108,101,95,98,121, - 116,101,99,111,100,101,134,2,0,0,115,16,0,0,0,0, - 2,15,1,15,1,13,1,12,1,19,1,4,2,18,1,114, - 195,0,0,0,114,84,0,0,0,99,3,0,0,0,0,0, - 0,0,4,0,0,0,3,0,0,0,67,0,0,0,115,76, - 0,0,0,116,0,0,116,1,0,131,1,0,125,3,0,124, - 3,0,106,2,0,116,3,0,124,1,0,131,1,0,131,1, - 0,1,124,3,0,106,2,0,116,3,0,124,2,0,131,1, - 0,131,1,0,1,124,3,0,106,2,0,116,4,0,106,5, - 0,124,0,0,131,1,0,131,1,0,1,124,3,0,83,41, - 1,122,80,67,111,109,112,105,108,101,32,97,32,99,111,100, - 101,32,111,98,106,101,99,116,32,105,110,116,111,32,98,121, - 116,101,99,111,100,101,32,102,111,114,32,119,114,105,116,105, - 110,103,32,111,117,116,32,116,111,32,97,32,98,121,116,101, - 45,99,111,109,112,105,108,101,100,10,32,32,32,32,102,105, - 108,101,46,41,6,218,9,98,121,116,101,97,114,114,97,121, - 114,185,0,0,0,218,6,101,120,116,101,110,100,114,17,0, - 0,0,114,191,0,0,0,90,5,100,117,109,112,115,41,4, - 114,194,0,0,0,114,183,0,0,0,114,189,0,0,0,114, - 53,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5, - 0,0,0,218,17,95,99,111,100,101,95,116,111,95,98,121, - 116,101,99,111,100,101,146,2,0,0,115,10,0,0,0,0, - 3,12,1,19,1,19,1,22,1,114,198,0,0,0,99,1, - 0,0,0,0,0,0,0,5,0,0,0,4,0,0,0,67, - 0,0,0,115,89,0,0,0,100,1,0,100,2,0,108,0, - 0,125,1,0,116,1,0,106,2,0,124,0,0,131,1,0, - 106,3,0,125,2,0,124,1,0,106,4,0,124,2,0,131, - 1,0,125,3,0,116,1,0,106,5,0,100,2,0,100,3, - 0,131,2,0,125,4,0,124,4,0,106,6,0,124,0,0, - 106,6,0,124,3,0,100,1,0,25,131,1,0,131,1,0, - 83,41,4,122,121,68,101,99,111,100,101,32,98,121,116,101, - 115,32,114,101,112,114,101,115,101,110,116,105,110,103,32,115, - 111,117,114,99,101,32,99,111,100,101,32,97,110,100,32,114, - 101,116,117,114,110,32,116,104,101,32,115,116,114,105,110,103, - 46,10,10,32,32,32,32,85,110,105,118,101,114,115,97,108, - 32,110,101,119,108,105,110,101,32,115,117,112,112,111,114,116, - 32,105,115,32,117,115,101,100,32,105,110,32,116,104,101,32, - 100,101,99,111,100,105,110,103,46,10,32,32,32,32,114,84, - 0,0,0,78,84,41,7,218,8,116,111,107,101,110,105,122, - 101,114,49,0,0,0,90,7,66,121,116,101,115,73,79,90, - 8,114,101,97,100,108,105,110,101,90,15,100,101,116,101,99, - 116,95,101,110,99,111,100,105,110,103,90,25,73,110,99,114, - 101,109,101,110,116,97,108,78,101,119,108,105,110,101,68,101, - 99,111,100,101,114,218,6,100,101,99,111,100,101,41,5,218, - 12,115,111,117,114,99,101,95,98,121,116,101,115,114,199,0, - 0,0,90,21,115,111,117,114,99,101,95,98,121,116,101,115, - 95,114,101,97,100,108,105,110,101,218,8,101,110,99,111,100, - 105,110,103,90,15,110,101,119,108,105,110,101,95,100,101,99, - 111,100,101,114,114,4,0,0,0,114,4,0,0,0,114,5, - 0,0,0,218,13,100,101,99,111,100,101,95,115,111,117,114, - 99,101,156,2,0,0,115,10,0,0,0,0,5,12,1,18, - 1,15,1,18,1,114,203,0,0,0,99,1,0,0,0,0, - 0,0,0,5,0,0,0,35,0,0,0,67,0,0,0,115, - 15,1,0,0,116,0,0,124,0,0,100,1,0,100,0,0, - 131,3,0,125,1,0,116,1,0,124,1,0,100,2,0,131, - 2,0,114,74,0,121,17,0,124,1,0,106,2,0,124,0, - 0,131,1,0,83,87,113,74,0,4,116,3,0,107,10,0, - 114,70,0,1,1,1,89,113,74,0,88,110,0,0,121,13, - 0,124,0,0,106,4,0,125,2,0,87,110,18,0,4,116, - 5,0,107,10,0,114,107,0,1,1,1,89,110,29,0,88, - 124,2,0,100,0,0,107,9,0,114,136,0,116,6,0,124, - 2,0,131,1,0,106,2,0,131,0,0,83,121,13,0,124, - 0,0,106,7,0,125,3,0,87,110,24,0,4,116,5,0, - 107,10,0,114,175,0,1,1,1,100,3,0,125,3,0,89, - 110,1,0,88,121,13,0,124,0,0,106,8,0,125,4,0, - 87,110,59,0,4,116,5,0,107,10,0,114,250,0,1,1, - 1,124,1,0,100,0,0,107,8,0,114,230,0,100,4,0, - 106,9,0,124,3,0,131,1,0,83,100,5,0,106,9,0, - 124,3,0,124,1,0,131,2,0,83,89,110,17,0,88,100, - 6,0,106,9,0,124,3,0,124,4,0,131,2,0,83,100, - 0,0,83,41,7,78,218,10,95,95,108,111,97,100,101,114, - 95,95,218,11,109,111,100,117,108,101,95,114,101,112,114,250, - 1,63,122,13,60,109,111,100,117,108,101,32,123,33,114,125, - 62,122,20,60,109,111,100,117,108,101,32,123,33,114,125,32, - 40,123,33,114,125,41,62,122,23,60,109,111,100,117,108,101, - 32,123,33,114,125,32,102,114,111,109,32,123,33,114,125,62, - 41,10,114,62,0,0,0,114,60,0,0,0,114,205,0,0, - 0,218,9,69,120,99,101,112,116,105,111,110,218,8,95,95, - 115,112,101,99,95,95,218,14,65,116,116,114,105,98,117,116, - 101,69,114,114,111,114,114,174,0,0,0,114,57,0,0,0, - 218,8,95,95,102,105,108,101,95,95,114,47,0,0,0,41, - 5,114,179,0,0,0,114,169,0,0,0,114,177,0,0,0, - 114,67,0,0,0,114,131,0,0,0,114,4,0,0,0,114, - 4,0,0,0,114,5,0,0,0,218,12,95,109,111,100,117, - 108,101,95,114,101,112,114,170,2,0,0,115,46,0,0,0, - 0,2,18,1,15,2,3,1,17,1,13,1,8,1,3,1, - 13,1,13,1,5,2,12,1,16,4,3,1,13,1,13,1, - 11,1,3,1,13,1,13,1,12,1,13,2,21,2,114,211, - 0,0,0,99,0,0,0,0,0,0,0,0,0,0,0,0, - 2,0,0,0,64,0,0,0,115,52,0,0,0,101,0,0, - 90,1,0,100,0,0,90,2,0,100,1,0,100,2,0,132, - 0,0,90,3,0,100,3,0,100,4,0,132,0,0,90,4, - 0,100,5,0,100,6,0,132,0,0,90,5,0,100,7,0, - 83,41,8,218,17,95,105,110,115,116,97,108,108,101,100,95, - 115,97,102,101,108,121,99,2,0,0,0,0,0,0,0,2, - 0,0,0,2,0,0,0,67,0,0,0,115,25,0,0,0, - 124,1,0,124,0,0,95,0,0,124,1,0,106,1,0,124, - 0,0,95,2,0,100,0,0,83,41,1,78,41,3,218,7, - 95,109,111,100,117,108,101,114,208,0,0,0,218,5,95,115, - 112,101,99,41,2,114,71,0,0,0,114,179,0,0,0,114, - 4,0,0,0,114,4,0,0,0,114,5,0,0,0,114,72, - 0,0,0,206,2,0,0,115,4,0,0,0,0,1,9,1, - 122,26,95,105,110,115,116,97,108,108,101,100,95,115,97,102, - 101,108,121,46,95,95,105,110,105,116,95,95,99,1,0,0, - 0,0,0,0,0,1,0,0,0,3,0,0,0,67,0,0, - 0,115,38,0,0,0,100,1,0,124,0,0,106,0,0,95, - 1,0,124,0,0,106,2,0,116,3,0,106,4,0,124,0, - 0,106,0,0,106,5,0,60,100,0,0,83,41,2,78,84, - 41,6,114,214,0,0,0,218,13,95,105,110,105,116,105,97, - 108,105,122,105,110,103,114,213,0,0,0,114,7,0,0,0, - 114,73,0,0,0,114,67,0,0,0,41,1,114,71,0,0, - 0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, - 114,75,0,0,0,210,2,0,0,115,4,0,0,0,0,4, - 12,1,122,27,95,105,110,115,116,97,108,108,101,100,95,115, - 97,102,101,108,121,46,95,95,101,110,116,101,114,95,95,99, - 1,0,0,0,0,0,0,0,3,0,0,0,17,0,0,0, - 71,0,0,0,115,121,0,0,0,122,101,0,124,0,0,106, - 0,0,125,2,0,116,1,0,100,1,0,100,2,0,132,0, - 0,124,1,0,68,131,1,0,131,1,0,114,78,0,121,17, - 0,116,2,0,106,3,0,124,2,0,106,4,0,61,87,113, - 100,0,4,116,5,0,107,10,0,114,74,0,1,1,1,89, - 113,100,0,88,110,22,0,116,6,0,100,3,0,124,2,0, - 106,4,0,124,2,0,106,7,0,131,3,0,1,87,100,0, - 0,100,4,0,124,0,0,106,0,0,95,8,0,88,100,0, - 0,83,41,5,78,99,1,0,0,0,0,0,0,0,2,0, - 0,0,3,0,0,0,115,0,0,0,115,27,0,0,0,124, - 0,0,93,17,0,125,1,0,124,1,0,100,0,0,107,9, - 0,86,1,113,3,0,100,0,0,83,41,1,78,114,4,0, - 0,0,41,2,114,22,0,0,0,114,76,0,0,0,114,4, - 0,0,0,114,4,0,0,0,114,5,0,0,0,114,77,0, - 0,0,220,2,0,0,115,2,0,0,0,6,0,122,45,95, - 105,110,115,116,97,108,108,101,100,95,115,97,102,101,108,121, - 46,95,95,101,120,105,116,95,95,46,60,108,111,99,97,108, - 115,62,46,60,103,101,110,101,120,112,114,62,122,18,105,109, - 112,111,114,116,32,123,33,114,125,32,35,32,123,33,114,125, - 70,41,9,114,214,0,0,0,114,78,0,0,0,114,7,0, - 0,0,114,73,0,0,0,114,67,0,0,0,114,79,0,0, - 0,114,152,0,0,0,114,169,0,0,0,114,215,0,0,0, - 41,3,114,71,0,0,0,114,80,0,0,0,114,177,0,0, - 0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, - 114,81,0,0,0,217,2,0,0,115,18,0,0,0,0,1, - 3,1,9,1,25,1,3,1,17,1,13,1,8,2,26,2, - 122,26,95,105,110,115,116,97,108,108,101,100,95,115,97,102, - 101,108,121,46,95,95,101,120,105,116,95,95,78,41,6,114, - 57,0,0,0,114,56,0,0,0,114,58,0,0,0,114,72, - 0,0,0,114,75,0,0,0,114,81,0,0,0,114,4,0, + 104,101,97,100,101,114,40,41,46,122,21,99,111,100,101,32, + 111,98,106,101,99,116,32,102,114,111,109,32,123,33,114,125, + 78,122,23,78,111,110,45,99,111,100,101,32,111,98,106,101, + 99,116,32,105,110,32,123,33,114,125,114,67,0,0,0,114, + 35,0,0,0,41,9,218,7,109,97,114,115,104,97,108,90, + 5,108,111,97,100,115,218,10,105,115,105,110,115,116,97,110, + 99,101,218,10,95,99,111,100,101,95,116,121,112,101,114,153, + 0,0,0,114,106,0,0,0,90,16,95,102,105,120,95,99, + 111,95,102,105,108,101,110,97,109,101,114,154,0,0,0,114, + 47,0,0,0,41,5,114,53,0,0,0,114,67,0,0,0, + 114,141,0,0,0,114,142,0,0,0,218,4,99,111,100,101, + 114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,218, + 17,95,99,111,109,112,105,108,101,95,98,121,116,101,99,111, + 100,101,143,2,0,0,115,16,0,0,0,0,2,15,1,15, + 1,13,1,12,1,16,1,4,2,18,1,114,194,0,0,0, + 114,84,0,0,0,99,3,0,0,0,0,0,0,0,4,0, + 0,0,3,0,0,0,67,0,0,0,115,76,0,0,0,116, + 0,0,116,1,0,131,1,0,125,3,0,124,3,0,106,2, + 0,116,3,0,124,1,0,131,1,0,131,1,0,1,124,3, + 0,106,2,0,116,3,0,124,2,0,131,1,0,131,1,0, + 1,124,3,0,106,2,0,116,4,0,106,5,0,124,0,0, + 131,1,0,131,1,0,1,124,3,0,83,41,1,122,80,67, + 111,109,112,105,108,101,32,97,32,99,111,100,101,32,111,98, + 106,101,99,116,32,105,110,116,111,32,98,121,116,101,99,111, + 100,101,32,102,111,114,32,119,114,105,116,105,110,103,32,111, + 117,116,32,116,111,32,97,32,98,121,116,101,45,99,111,109, + 112,105,108,101,100,10,32,32,32,32,102,105,108,101,46,41, + 6,218,9,98,121,116,101,97,114,114,97,121,114,184,0,0, + 0,218,6,101,120,116,101,110,100,114,17,0,0,0,114,190, + 0,0,0,90,5,100,117,109,112,115,41,4,114,193,0,0, + 0,114,182,0,0,0,114,188,0,0,0,114,53,0,0,0, + 114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,218, + 17,95,99,111,100,101,95,116,111,95,98,121,116,101,99,111, + 100,101,155,2,0,0,115,10,0,0,0,0,3,12,1,19, + 1,19,1,22,1,114,197,0,0,0,99,1,0,0,0,0, + 0,0,0,5,0,0,0,4,0,0,0,67,0,0,0,115, + 89,0,0,0,100,1,0,100,2,0,108,0,0,125,1,0, + 116,1,0,106,2,0,124,0,0,131,1,0,106,3,0,125, + 2,0,124,1,0,106,4,0,124,2,0,131,1,0,125,3, + 0,116,1,0,106,5,0,100,2,0,100,3,0,131,2,0, + 125,4,0,124,4,0,106,6,0,124,0,0,106,6,0,124, + 3,0,100,1,0,25,131,1,0,131,1,0,83,41,4,122, + 121,68,101,99,111,100,101,32,98,121,116,101,115,32,114,101, + 112,114,101,115,101,110,116,105,110,103,32,115,111,117,114,99, + 101,32,99,111,100,101,32,97,110,100,32,114,101,116,117,114, + 110,32,116,104,101,32,115,116,114,105,110,103,46,10,10,32, + 32,32,32,85,110,105,118,101,114,115,97,108,32,110,101,119, + 108,105,110,101,32,115,117,112,112,111,114,116,32,105,115,32, + 117,115,101,100,32,105,110,32,116,104,101,32,100,101,99,111, + 100,105,110,103,46,10,32,32,32,32,114,84,0,0,0,78, + 84,41,7,218,8,116,111,107,101,110,105,122,101,114,49,0, + 0,0,90,7,66,121,116,101,115,73,79,90,8,114,101,97, + 100,108,105,110,101,90,15,100,101,116,101,99,116,95,101,110, + 99,111,100,105,110,103,90,25,73,110,99,114,101,109,101,110, + 116,97,108,78,101,119,108,105,110,101,68,101,99,111,100,101, + 114,218,6,100,101,99,111,100,101,41,5,218,12,115,111,117, + 114,99,101,95,98,121,116,101,115,114,198,0,0,0,90,21, + 115,111,117,114,99,101,95,98,121,116,101,115,95,114,101,97, + 100,108,105,110,101,218,8,101,110,99,111,100,105,110,103,90, + 15,110,101,119,108,105,110,101,95,100,101,99,111,100,101,114, + 114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,218, + 13,100,101,99,111,100,101,95,115,111,117,114,99,101,165,2, + 0,0,115,10,0,0,0,0,5,12,1,18,1,15,1,18, + 1,114,202,0,0,0,99,1,0,0,0,0,0,0,0,5, + 0,0,0,35,0,0,0,67,0,0,0,115,6,1,0,0, + 116,0,0,124,0,0,100,1,0,100,0,0,131,3,0,125, + 1,0,116,1,0,124,1,0,100,2,0,131,2,0,114,71, + 0,121,17,0,124,1,0,106,2,0,124,0,0,131,1,0, + 83,87,110,18,0,4,116,3,0,107,10,0,114,70,0,1, + 1,1,89,110,1,0,88,121,13,0,124,0,0,106,4,0, + 125,2,0,87,110,18,0,4,116,5,0,107,10,0,114,104, + 0,1,1,1,89,110,23,0,88,124,2,0,100,0,0,107, + 9,0,114,127,0,116,6,0,124,2,0,131,1,0,83,121, + 13,0,124,0,0,106,7,0,125,3,0,87,110,24,0,4, + 116,5,0,107,10,0,114,166,0,1,1,1,100,3,0,125, + 3,0,89,110,1,0,88,121,13,0,124,0,0,106,8,0, + 125,4,0,87,110,59,0,4,116,5,0,107,10,0,114,241, + 0,1,1,1,124,1,0,100,0,0,107,8,0,114,221,0, + 100,4,0,106,9,0,124,3,0,131,1,0,83,100,5,0, + 106,9,0,124,3,0,124,1,0,131,2,0,83,89,110,17, + 0,88,100,6,0,106,9,0,124,3,0,124,4,0,131,2, + 0,83,100,0,0,83,41,7,78,218,10,95,95,108,111,97, + 100,101,114,95,95,218,11,109,111,100,117,108,101,95,114,101, + 112,114,250,1,63,122,13,60,109,111,100,117,108,101,32,123, + 33,114,125,62,122,20,60,109,111,100,117,108,101,32,123,33, + 114,125,32,40,123,33,114,125,41,62,122,23,60,109,111,100, + 117,108,101,32,123,33,114,125,32,102,114,111,109,32,123,33, + 114,125,62,41,10,114,62,0,0,0,114,60,0,0,0,114, + 204,0,0,0,218,9,69,120,99,101,112,116,105,111,110,218, + 8,95,95,115,112,101,99,95,95,218,14,65,116,116,114,105, + 98,117,116,101,69,114,114,111,114,218,22,95,109,111,100,117, + 108,101,95,114,101,112,114,95,102,114,111,109,95,115,112,101, + 99,114,57,0,0,0,218,8,95,95,102,105,108,101,95,95, + 114,47,0,0,0,41,5,114,178,0,0,0,114,170,0,0, + 0,114,177,0,0,0,114,67,0,0,0,114,131,0,0,0, + 114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,218, + 12,95,109,111,100,117,108,101,95,114,101,112,114,179,2,0, + 0,115,46,0,0,0,0,2,18,1,15,4,3,1,17,1, + 13,1,5,1,3,1,13,1,13,1,5,2,12,1,10,4, + 3,1,13,1,13,1,11,1,3,1,13,1,13,1,12,1, + 13,2,21,2,114,211,0,0,0,99,0,0,0,0,0,0, + 0,0,0,0,0,0,2,0,0,0,64,0,0,0,115,52, + 0,0,0,101,0,0,90,1,0,100,0,0,90,2,0,100, + 1,0,100,2,0,132,0,0,90,3,0,100,3,0,100,4, + 0,132,0,0,90,4,0,100,5,0,100,6,0,132,0,0, + 90,5,0,100,7,0,83,41,8,218,17,95,105,110,115,116, + 97,108,108,101,100,95,115,97,102,101,108,121,99,2,0,0, + 0,0,0,0,0,2,0,0,0,2,0,0,0,67,0,0, + 0,115,25,0,0,0,124,1,0,124,0,0,95,0,0,124, + 1,0,106,1,0,124,0,0,95,2,0,100,0,0,83,41, + 1,78,41,3,218,7,95,109,111,100,117,108,101,114,207,0, + 0,0,218,5,95,115,112,101,99,41,2,114,71,0,0,0, + 114,178,0,0,0,114,4,0,0,0,114,4,0,0,0,114, + 5,0,0,0,114,72,0,0,0,217,2,0,0,115,4,0, + 0,0,0,1,9,1,122,26,95,105,110,115,116,97,108,108, + 101,100,95,115,97,102,101,108,121,46,95,95,105,110,105,116, + 95,95,99,1,0,0,0,0,0,0,0,1,0,0,0,3, + 0,0,0,67,0,0,0,115,38,0,0,0,100,1,0,124, + 0,0,106,0,0,95,1,0,124,0,0,106,2,0,116,3, + 0,106,4,0,124,0,0,106,0,0,106,5,0,60,100,0, + 0,83,41,2,78,84,41,6,114,214,0,0,0,218,13,95, + 105,110,105,116,105,97,108,105,122,105,110,103,114,213,0,0, + 0,114,7,0,0,0,114,73,0,0,0,114,67,0,0,0, + 41,1,114,71,0,0,0,114,4,0,0,0,114,4,0,0, + 0,114,5,0,0,0,114,75,0,0,0,221,2,0,0,115, + 4,0,0,0,0,4,12,1,122,27,95,105,110,115,116,97, + 108,108,101,100,95,115,97,102,101,108,121,46,95,95,101,110, + 116,101,114,95,95,99,1,0,0,0,0,0,0,0,3,0, + 0,0,17,0,0,0,71,0,0,0,115,121,0,0,0,122, + 101,0,124,0,0,106,0,0,125,2,0,116,1,0,100,1, + 0,100,2,0,132,0,0,124,1,0,68,131,1,0,131,1, + 0,114,78,0,121,17,0,116,2,0,106,3,0,124,2,0, + 106,4,0,61,87,113,100,0,4,116,5,0,107,10,0,114, + 74,0,1,1,1,89,113,100,0,88,110,22,0,116,6,0, + 100,3,0,124,2,0,106,4,0,124,2,0,106,7,0,131, + 3,0,1,87,100,0,0,100,4,0,124,0,0,106,0,0, + 95,8,0,88,100,0,0,83,41,5,78,99,1,0,0,0, + 0,0,0,0,2,0,0,0,3,0,0,0,115,0,0,0, + 115,27,0,0,0,124,0,0,93,17,0,125,1,0,124,1, + 0,100,0,0,107,9,0,86,1,113,3,0,100,0,0,83, + 41,1,78,114,4,0,0,0,41,2,114,22,0,0,0,114, + 76,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5, + 0,0,0,114,77,0,0,0,231,2,0,0,115,2,0,0, + 0,6,0,122,45,95,105,110,115,116,97,108,108,101,100,95, + 115,97,102,101,108,121,46,95,95,101,120,105,116,95,95,46, + 60,108,111,99,97,108,115,62,46,60,103,101,110,101,120,112, + 114,62,122,18,105,109,112,111,114,116,32,123,33,114,125,32, + 35,32,123,33,114,125,70,41,9,114,214,0,0,0,114,78, + 0,0,0,114,7,0,0,0,114,73,0,0,0,114,67,0, + 0,0,114,79,0,0,0,114,153,0,0,0,114,170,0,0, + 0,114,215,0,0,0,41,3,114,71,0,0,0,114,80,0, + 0,0,114,177,0,0,0,114,4,0,0,0,114,4,0,0, + 0,114,5,0,0,0,114,81,0,0,0,228,2,0,0,115, + 18,0,0,0,0,1,3,1,9,1,25,1,3,1,17,1, + 13,1,8,2,26,2,122,26,95,105,110,115,116,97,108,108, + 101,100,95,115,97,102,101,108,121,46,95,95,101,120,105,116, + 95,95,78,41,6,114,57,0,0,0,114,56,0,0,0,114, + 58,0,0,0,114,72,0,0,0,114,75,0,0,0,114,81, + 0,0,0,114,4,0,0,0,114,4,0,0,0,114,4,0, + 0,0,114,5,0,0,0,114,212,0,0,0,215,2,0,0, + 115,6,0,0,0,12,2,12,4,12,7,114,212,0,0,0, + 99,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0, + 0,64,0,0,0,115,172,0,0,0,101,0,0,90,1,0, + 100,0,0,90,2,0,100,1,0,90,3,0,100,2,0,100, + 3,0,100,4,0,100,3,0,100,5,0,100,3,0,100,6, + 0,100,7,0,132,0,3,90,4,0,100,8,0,100,9,0, + 132,0,0,90,5,0,100,10,0,100,11,0,132,0,0,90, + 6,0,101,7,0,100,12,0,100,13,0,132,0,0,131,1, + 0,90,8,0,101,8,0,106,9,0,100,14,0,100,13,0, + 132,0,0,131,1,0,90,8,0,101,7,0,100,15,0,100, + 16,0,132,0,0,131,1,0,90,10,0,101,7,0,100,17, + 0,100,18,0,132,0,0,131,1,0,90,11,0,101,11,0, + 106,9,0,100,19,0,100,18,0,132,0,0,131,1,0,90, + 11,0,100,3,0,83,41,20,218,10,77,111,100,117,108,101, + 83,112,101,99,97,208,5,0,0,84,104,101,32,115,112,101, + 99,105,102,105,99,97,116,105,111,110,32,102,111,114,32,97, + 32,109,111,100,117,108,101,44,32,117,115,101,100,32,102,111, + 114,32,108,111,97,100,105,110,103,46,10,10,32,32,32,32, + 65,32,109,111,100,117,108,101,39,115,32,115,112,101,99,32, + 105,115,32,116,104,101,32,115,111,117,114,99,101,32,102,111, + 114,32,105,110,102,111,114,109,97,116,105,111,110,32,97,98, + 111,117,116,32,116,104,101,32,109,111,100,117,108,101,46,32, + 32,70,111,114,10,32,32,32,32,100,97,116,97,32,97,115, + 115,111,99,105,97,116,101,100,32,119,105,116,104,32,116,104, + 101,32,109,111,100,117,108,101,44,32,105,110,99,108,117,100, + 105,110,103,32,115,111,117,114,99,101,44,32,117,115,101,32, + 116,104,101,32,115,112,101,99,39,115,10,32,32,32,32,108, + 111,97,100,101,114,46,10,10,32,32,32,32,96,110,97,109, + 101,96,32,105,115,32,116,104,101,32,97,98,115,111,108,117, + 116,101,32,110,97,109,101,32,111,102,32,116,104,101,32,109, + 111,100,117,108,101,46,32,32,96,108,111,97,100,101,114,96, + 32,105,115,32,116,104,101,32,108,111,97,100,101,114,10,32, + 32,32,32,116,111,32,117,115,101,32,119,104,101,110,32,108, + 111,97,100,105,110,103,32,116,104,101,32,109,111,100,117,108, + 101,46,32,32,96,112,97,114,101,110,116,96,32,105,115,32, + 116,104,101,32,110,97,109,101,32,111,102,32,116,104,101,10, + 32,32,32,32,112,97,99,107,97,103,101,32,116,104,101,32, + 109,111,100,117,108,101,32,105,115,32,105,110,46,32,32,84, + 104,101,32,112,97,114,101,110,116,32,105,115,32,100,101,114, + 105,118,101,100,32,102,114,111,109,32,116,104,101,32,110,97, + 109,101,46,10,10,32,32,32,32,96,105,115,95,112,97,99, + 107,97,103,101,96,32,100,101,116,101,114,109,105,110,101,115, + 32,105,102,32,116,104,101,32,109,111,100,117,108,101,32,105, + 115,32,99,111,110,115,105,100,101,114,101,100,32,97,32,112, + 97,99,107,97,103,101,32,111,114,10,32,32,32,32,110,111, + 116,46,32,32,79,110,32,109,111,100,117,108,101,115,32,116, + 104,105,115,32,105,115,32,114,101,102,108,101,99,116,101,100, + 32,98,121,32,116,104,101,32,96,95,95,112,97,116,104,95, + 95,96,32,97,116,116,114,105,98,117,116,101,46,10,10,32, + 32,32,32,96,111,114,105,103,105,110,96,32,105,115,32,116, + 104,101,32,115,112,101,99,105,102,105,99,32,108,111,99,97, + 116,105,111,110,32,117,115,101,100,32,98,121,32,116,104,101, + 32,108,111,97,100,101,114,32,102,114,111,109,32,119,104,105, + 99,104,32,116,111,10,32,32,32,32,108,111,97,100,32,116, + 104,101,32,109,111,100,117,108,101,44,32,105,102,32,116,104, + 97,116,32,105,110,102,111,114,109,97,116,105,111,110,32,105, + 115,32,97,118,97,105,108,97,98,108,101,46,32,32,87,104, + 101,110,32,102,105,108,101,110,97,109,101,32,105,115,10,32, + 32,32,32,115,101,116,44,32,111,114,105,103,105,110,32,119, + 105,108,108,32,109,97,116,99,104,46,10,10,32,32,32,32, + 96,104,97,115,95,108,111,99,97,116,105,111,110,96,32,105, + 110,100,105,99,97,116,101,115,32,116,104,97,116,32,97,32, + 115,112,101,99,39,115,32,34,111,114,105,103,105,110,34,32, + 114,101,102,108,101,99,116,115,32,97,32,108,111,99,97,116, + 105,111,110,46,10,32,32,32,32,87,104,101,110,32,116,104, + 105,115,32,105,115,32,84,114,117,101,44,32,96,95,95,102, + 105,108,101,95,95,96,32,97,116,116,114,105,98,117,116,101, + 32,111,102,32,116,104,101,32,109,111,100,117,108,101,32,105, + 115,32,115,101,116,46,10,10,32,32,32,32,96,99,97,99, + 104,101,100,96,32,105,115,32,116,104,101,32,108,111,99,97, + 116,105,111,110,32,111,102,32,116,104,101,32,99,97,99,104, + 101,100,32,98,121,116,101,99,111,100,101,32,102,105,108,101, + 44,32,105,102,32,97,110,121,46,32,32,73,116,10,32,32, + 32,32,99,111,114,114,101,115,112,111,110,100,115,32,116,111, + 32,116,104,101,32,96,95,95,99,97,99,104,101,100,95,95, + 96,32,97,116,116,114,105,98,117,116,101,46,10,10,32,32, + 32,32,96,115,117,98,109,111,100,117,108,101,95,115,101,97, + 114,99,104,95,108,111,99,97,116,105,111,110,115,96,32,105, + 115,32,116,104,101,32,115,101,113,117,101,110,99,101,32,111, + 102,32,112,97,116,104,32,101,110,116,114,105,101,115,32,116, + 111,10,32,32,32,32,115,101,97,114,99,104,32,119,104,101, + 110,32,105,109,112,111,114,116,105,110,103,32,115,117,98,109, + 111,100,117,108,101,115,46,32,32,73,102,32,115,101,116,44, + 32,105,115,95,112,97,99,107,97,103,101,32,115,104,111,117, + 108,100,32,98,101,10,32,32,32,32,84,114,117,101,45,45, + 97,110,100,32,70,97,108,115,101,32,111,116,104,101,114,119, + 105,115,101,46,10,10,32,32,32,32,80,97,99,107,97,103, + 101,115,32,97,114,101,32,115,105,109,112,108,121,32,109,111, + 100,117,108,101,115,32,116,104,97,116,32,40,109,97,121,41, + 32,104,97,118,101,32,115,117,98,109,111,100,117,108,101,115, + 46,32,32,73,102,32,97,32,115,112,101,99,10,32,32,32, + 32,104,97,115,32,97,32,110,111,110,45,78,111,110,101,32, + 118,97,108,117,101,32,105,110,32,96,115,117,98,109,111,100, + 117,108,101,95,115,101,97,114,99,104,95,108,111,99,97,116, + 105,111,110,115,96,44,32,116,104,101,32,105,109,112,111,114, + 116,10,32,32,32,32,115,121,115,116,101,109,32,119,105,108, + 108,32,99,111,110,115,105,100,101,114,32,109,111,100,117,108, + 101,115,32,108,111,97,100,101,100,32,102,114,111,109,32,116, + 104,101,32,115,112,101,99,32,97,115,32,112,97,99,107,97, + 103,101,115,46,10,10,32,32,32,32,79,110,108,121,32,102, + 105,110,100,101,114,115,32,40,115,101,101,32,105,109,112,111, + 114,116,108,105,98,46,97,98,99,46,77,101,116,97,80,97, + 116,104,70,105,110,100,101,114,32,97,110,100,10,32,32,32, + 32,105,109,112,111,114,116,108,105,98,46,97,98,99,46,80, + 97,116,104,69,110,116,114,121,70,105,110,100,101,114,41,32, + 115,104,111,117,108,100,32,109,111,100,105,102,121,32,77,111, + 100,117,108,101,83,112,101,99,32,105,110,115,116,97,110,99, + 101,115,46,10,10,32,32,32,32,218,6,111,114,105,103,105, + 110,78,218,12,108,111,97,100,101,114,95,115,116,97,116,101, + 218,10,105,115,95,112,97,99,107,97,103,101,99,3,0,0, + 0,3,0,0,0,6,0,0,0,2,0,0,0,67,0,0, + 0,115,79,0,0,0,124,1,0,124,0,0,95,0,0,124, + 2,0,124,0,0,95,1,0,124,3,0,124,0,0,95,2, + 0,124,4,0,124,0,0,95,3,0,124,5,0,114,48,0, + 103,0,0,110,3,0,100,0,0,124,0,0,95,4,0,100, + 1,0,124,0,0,95,5,0,100,0,0,124,0,0,95,6, + 0,100,0,0,83,41,2,78,70,41,7,114,67,0,0,0, + 114,170,0,0,0,114,217,0,0,0,114,218,0,0,0,218, + 26,115,117,98,109,111,100,117,108,101,95,115,101,97,114,99, + 104,95,108,111,99,97,116,105,111,110,115,218,13,95,115,101, + 116,95,102,105,108,101,97,116,116,114,218,7,95,99,97,99, + 104,101,100,41,6,114,71,0,0,0,114,67,0,0,0,114, + 170,0,0,0,114,217,0,0,0,114,218,0,0,0,114,219, + 0,0,0,114,4,0,0,0,114,4,0,0,0,114,5,0, + 0,0,114,72,0,0,0,23,3,0,0,115,14,0,0,0, + 0,2,9,1,9,1,9,1,9,1,21,3,9,1,122,19, + 77,111,100,117,108,101,83,112,101,99,46,95,95,105,110,105, + 116,95,95,99,1,0,0,0,0,0,0,0,2,0,0,0, + 4,0,0,0,67,0,0,0,115,147,0,0,0,100,1,0, + 106,0,0,124,0,0,106,1,0,131,1,0,100,2,0,106, + 0,0,124,0,0,106,2,0,131,1,0,103,2,0,125,1, + 0,124,0,0,106,3,0,100,0,0,107,9,0,114,76,0, + 124,1,0,106,4,0,100,3,0,106,0,0,124,0,0,106, + 3,0,131,1,0,131,1,0,1,124,0,0,106,5,0,100, + 0,0,107,9,0,114,116,0,124,1,0,106,4,0,100,4, + 0,106,0,0,124,0,0,106,5,0,131,1,0,131,1,0, + 1,100,5,0,106,0,0,124,0,0,106,6,0,106,7,0, + 100,6,0,106,8,0,124,1,0,131,1,0,131,2,0,83, + 41,7,78,122,9,110,97,109,101,61,123,33,114,125,122,11, + 108,111,97,100,101,114,61,123,33,114,125,122,11,111,114,105, + 103,105,110,61,123,33,114,125,122,29,115,117,98,109,111,100, + 117,108,101,95,115,101,97,114,99,104,95,108,111,99,97,116, + 105,111,110,115,61,123,125,122,6,123,125,40,123,125,41,122, + 2,44,32,41,9,114,47,0,0,0,114,67,0,0,0,114, + 170,0,0,0,114,217,0,0,0,218,6,97,112,112,101,110, + 100,114,220,0,0,0,218,9,95,95,99,108,97,115,115,95, + 95,114,57,0,0,0,114,26,0,0,0,41,2,114,71,0, + 0,0,114,80,0,0,0,114,4,0,0,0,114,4,0,0, + 0,114,5,0,0,0,114,101,0,0,0,35,3,0,0,115, + 16,0,0,0,0,1,15,1,21,1,15,1,25,1,15,1, + 12,1,13,1,122,19,77,111,100,117,108,101,83,112,101,99, + 46,95,95,114,101,112,114,95,95,99,2,0,0,0,0,0, + 0,0,3,0,0,0,11,0,0,0,67,0,0,0,115,145, + 0,0,0,124,0,0,106,0,0,125,2,0,121,107,0,124, + 0,0,106,1,0,124,1,0,106,1,0,107,2,0,111,114, + 0,124,0,0,106,2,0,124,1,0,106,2,0,107,2,0, + 111,114,0,124,0,0,106,3,0,124,1,0,106,3,0,107, + 2,0,111,114,0,124,2,0,124,1,0,106,0,0,107,2, + 0,111,114,0,124,0,0,106,4,0,124,1,0,106,4,0, + 107,2,0,111,114,0,124,0,0,106,5,0,124,1,0,106, + 5,0,107,2,0,83,87,110,22,0,4,116,6,0,107,10, + 0,114,140,0,1,1,1,100,1,0,83,89,110,1,0,88, + 100,0,0,83,41,2,78,70,41,7,114,220,0,0,0,114, + 67,0,0,0,114,170,0,0,0,114,217,0,0,0,218,6, + 99,97,99,104,101,100,218,12,104,97,115,95,108,111,99,97, + 116,105,111,110,114,208,0,0,0,41,3,114,71,0,0,0, + 218,5,111,116,104,101,114,218,4,115,109,115,108,114,4,0, + 0,0,114,4,0,0,0,114,5,0,0,0,218,6,95,95, + 101,113,95,95,45,3,0,0,115,20,0,0,0,0,1,9, + 1,3,1,18,1,18,1,18,1,15,1,18,1,20,1,13, + 1,122,17,77,111,100,117,108,101,83,112,101,99,46,95,95, + 101,113,95,95,99,1,0,0,0,0,0,0,0,2,0,0, + 0,11,0,0,0,67,0,0,0,115,149,0,0,0,124,0, + 0,106,0,0,100,0,0,107,8,0,114,142,0,124,0,0, + 106,1,0,100,0,0,107,9,0,114,142,0,124,0,0,106, + 2,0,114,142,0,124,0,0,106,1,0,125,1,0,124,1, + 0,106,3,0,116,4,0,116,5,0,131,1,0,131,1,0, + 114,112,0,121,19,0,116,6,0,124,1,0,131,1,0,124, + 0,0,95,0,0,87,113,142,0,4,116,7,0,107,10,0, + 114,108,0,1,1,1,89,113,142,0,88,110,30,0,124,1, + 0,106,3,0,116,4,0,116,8,0,131,1,0,131,1,0, + 114,142,0,124,1,0,124,0,0,95,0,0,124,0,0,106, + 0,0,83,41,1,78,41,9,114,222,0,0,0,114,217,0, + 0,0,114,221,0,0,0,218,8,101,110,100,115,119,105,116, + 104,218,5,116,117,112,108,101,114,135,0,0,0,114,132,0, + 0,0,114,123,0,0,0,218,17,66,89,84,69,67,79,68, + 69,95,83,85,70,70,73,88,69,83,41,2,114,71,0,0, + 0,114,131,0,0,0,114,4,0,0,0,114,4,0,0,0, + 114,5,0,0,0,114,225,0,0,0,57,3,0,0,115,22, + 0,0,0,0,2,15,1,24,1,9,1,21,1,3,1,19, + 1,13,1,8,1,21,1,9,1,122,17,77,111,100,117,108, + 101,83,112,101,99,46,99,97,99,104,101,100,99,2,0,0, + 0,0,0,0,0,2,0,0,0,2,0,0,0,67,0,0, + 0,115,13,0,0,0,124,1,0,124,0,0,95,0,0,100, + 0,0,83,41,1,78,41,1,114,222,0,0,0,41,2,114, + 71,0,0,0,114,225,0,0,0,114,4,0,0,0,114,4, + 0,0,0,114,5,0,0,0,114,225,0,0,0,71,3,0, + 0,115,2,0,0,0,0,2,99,1,0,0,0,0,0,0, + 0,1,0,0,0,2,0,0,0,67,0,0,0,115,46,0, + 0,0,124,0,0,106,0,0,100,1,0,107,8,0,114,35, + 0,124,0,0,106,1,0,106,2,0,100,2,0,131,1,0, + 100,3,0,25,83,124,0,0,106,1,0,83,100,1,0,83, + 41,4,122,32,84,104,101,32,110,97,109,101,32,111,102,32, + 116,104,101,32,109,111,100,117,108,101,39,115,32,112,97,114, + 101,110,116,46,78,114,116,0,0,0,114,84,0,0,0,41, + 3,114,220,0,0,0,114,67,0,0,0,114,32,0,0,0, + 41,1,114,71,0,0,0,114,4,0,0,0,114,4,0,0, + 0,114,5,0,0,0,218,6,112,97,114,101,110,116,75,3, + 0,0,115,6,0,0,0,0,3,15,1,20,2,122,17,77, + 111,100,117,108,101,83,112,101,99,46,112,97,114,101,110,116, + 99,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0, + 0,67,0,0,0,115,7,0,0,0,124,0,0,106,0,0, + 83,41,1,78,41,1,114,221,0,0,0,41,1,114,71,0, 0,0,114,4,0,0,0,114,4,0,0,0,114,5,0,0, - 0,114,212,0,0,0,204,2,0,0,115,6,0,0,0,12, - 2,12,4,12,7,114,212,0,0,0,99,0,0,0,0,0, - 0,0,0,0,0,0,0,8,0,0,0,64,0,0,0,115, - 151,0,0,0,101,0,0,90,1,0,100,0,0,90,2,0, - 100,1,0,90,3,0,100,2,0,100,3,0,100,4,0,100, - 3,0,100,5,0,100,3,0,100,6,0,100,7,0,132,0, - 3,90,4,0,100,8,0,100,9,0,132,0,0,90,5,0, - 100,10,0,100,11,0,132,0,0,90,6,0,101,7,0,100, - 12,0,100,13,0,132,0,0,131,1,0,90,8,0,101,8, - 0,106,9,0,100,14,0,100,13,0,132,0,0,131,1,0, - 90,8,0,101,7,0,100,15,0,100,16,0,132,0,0,131, - 1,0,90,10,0,101,7,0,100,17,0,100,18,0,132,0, - 0,131,1,0,90,11,0,100,3,0,83,41,19,218,10,77, - 111,100,117,108,101,83,112,101,99,97,208,5,0,0,84,104, - 101,32,115,112,101,99,105,102,105,99,97,116,105,111,110,32, - 102,111,114,32,97,32,109,111,100,117,108,101,44,32,117,115, - 101,100,32,102,111,114,32,108,111,97,100,105,110,103,46,10, - 10,32,32,32,32,65,32,109,111,100,117,108,101,39,115,32, - 115,112,101,99,32,105,115,32,116,104,101,32,115,111,117,114, - 99,101,32,102,111,114,32,105,110,102,111,114,109,97,116,105, - 111,110,32,97,98,111,117,116,32,116,104,101,32,109,111,100, - 117,108,101,46,32,32,70,111,114,10,32,32,32,32,100,97, - 116,97,32,97,115,115,111,99,105,97,116,101,100,32,119,105, - 116,104,32,116,104,101,32,109,111,100,117,108,101,44,32,105, - 110,99,108,117,100,105,110,103,32,115,111,117,114,99,101,44, - 32,117,115,101,32,116,104,101,32,115,112,101,99,39,115,10, - 32,32,32,32,108,111,97,100,101,114,46,10,10,32,32,32, - 32,96,110,97,109,101,96,32,105,115,32,116,104,101,32,97, - 98,115,111,108,117,116,101,32,110,97,109,101,32,111,102,32, - 116,104,101,32,109,111,100,117,108,101,46,32,32,96,108,111, - 97,100,101,114,96,32,105,115,32,116,104,101,32,108,111,97, - 100,101,114,10,32,32,32,32,116,111,32,117,115,101,32,119, - 104,101,110,32,108,111,97,100,105,110,103,32,116,104,101,32, - 109,111,100,117,108,101,46,32,32,96,112,97,114,101,110,116, - 96,32,105,115,32,116,104,101,32,110,97,109,101,32,111,102, - 32,116,104,101,10,32,32,32,32,112,97,99,107,97,103,101, - 32,116,104,101,32,109,111,100,117,108,101,32,105,115,32,105, - 110,46,32,32,84,104,101,32,112,97,114,101,110,116,32,105, - 115,32,100,101,114,105,118,101,100,32,102,114,111,109,32,116, - 104,101,32,110,97,109,101,46,10,10,32,32,32,32,96,105, - 115,95,112,97,99,107,97,103,101,96,32,100,101,116,101,114, - 109,105,110,101,115,32,105,102,32,116,104,101,32,109,111,100, - 117,108,101,32,105,115,32,99,111,110,115,105,100,101,114,101, - 100,32,97,32,112,97,99,107,97,103,101,32,111,114,10,32, - 32,32,32,110,111,116,46,32,32,79,110,32,109,111,100,117, - 108,101,115,32,116,104,105,115,32,105,115,32,114,101,102,108, - 101,99,116,101,100,32,98,121,32,116,104,101,32,96,95,95, - 112,97,116,104,95,95,96,32,97,116,116,114,105,98,117,116, - 101,46,10,10,32,32,32,32,96,111,114,105,103,105,110,96, - 32,105,115,32,116,104,101,32,115,112,101,99,105,102,105,99, - 32,108,111,99,97,116,105,111,110,32,117,115,101,100,32,98, - 121,32,116,104,101,32,108,111,97,100,101,114,32,102,114,111, - 109,32,119,104,105,99,104,32,116,111,10,32,32,32,32,108, - 111,97,100,32,116,104,101,32,109,111,100,117,108,101,44,32, - 105,102,32,116,104,97,116,32,105,110,102,111,114,109,97,116, - 105,111,110,32,105,115,32,97,118,97,105,108,97,98,108,101, - 46,32,32,87,104,101,110,32,102,105,108,101,110,97,109,101, - 32,105,115,10,32,32,32,32,115,101,116,44,32,111,114,105, - 103,105,110,32,119,105,108,108,32,109,97,116,99,104,46,10, - 10,32,32,32,32,96,104,97,115,95,108,111,99,97,116,105, - 111,110,96,32,105,110,100,105,99,97,116,101,115,32,116,104, - 97,116,32,97,32,115,112,101,99,39,115,32,34,111,114,105, - 103,105,110,34,32,114,101,102,108,101,99,116,115,32,97,32, - 108,111,99,97,116,105,111,110,46,10,32,32,32,32,87,104, - 101,110,32,116,104,105,115,32,105,115,32,84,114,117,101,44, - 32,96,95,95,102,105,108,101,95,95,96,32,97,116,116,114, - 105,98,117,116,101,32,111,102,32,116,104,101,32,109,111,100, - 117,108,101,32,105,115,32,115,101,116,46,10,10,32,32,32, - 32,96,99,97,99,104,101,100,96,32,105,115,32,116,104,101, - 32,108,111,99,97,116,105,111,110,32,111,102,32,116,104,101, - 32,99,97,99,104,101,100,32,98,121,116,101,99,111,100,101, - 32,102,105,108,101,44,32,105,102,32,97,110,121,46,32,32, - 73,116,10,32,32,32,32,99,111,114,114,101,115,112,111,110, - 100,115,32,116,111,32,116,104,101,32,96,95,95,99,97,99, - 104,101,100,95,95,96,32,97,116,116,114,105,98,117,116,101, - 46,10,10,32,32,32,32,96,115,117,98,109,111,100,117,108, - 101,95,115,101,97,114,99,104,95,108,111,99,97,116,105,111, - 110,115,96,32,105,115,32,116,104,101,32,115,101,113,117,101, - 110,99,101,32,111,102,32,112,97,116,104,32,101,110,116,114, - 105,101,115,32,116,111,10,32,32,32,32,115,101,97,114,99, - 104,32,119,104,101,110,32,105,109,112,111,114,116,105,110,103, - 32,115,117,98,109,111,100,117,108,101,115,46,32,32,73,102, - 32,115,101,116,44,32,105,115,95,112,97,99,107,97,103,101, - 32,115,104,111,117,108,100,32,98,101,10,32,32,32,32,84, - 114,117,101,45,45,97,110,100,32,70,97,108,115,101,32,111, - 116,104,101,114,119,105,115,101,46,10,10,32,32,32,32,80, - 97,99,107,97,103,101,115,32,97,114,101,32,115,105,109,112, - 108,121,32,109,111,100,117,108,101,115,32,116,104,97,116,32, - 40,109,97,121,41,32,104,97,118,101,32,115,117,98,109,111, - 100,117,108,101,115,46,32,32,73,102,32,97,32,115,112,101, - 99,10,32,32,32,32,104,97,115,32,97,32,110,111,110,45, - 78,111,110,101,32,118,97,108,117,101,32,105,110,32,96,115, - 117,98,109,111,100,117,108,101,95,115,101,97,114,99,104,95, - 108,111,99,97,116,105,111,110,115,96,44,32,116,104,101,32, - 105,109,112,111,114,116,10,32,32,32,32,115,121,115,116,101, - 109,32,119,105,108,108,32,99,111,110,115,105,100,101,114,32, - 109,111,100,117,108,101,115,32,108,111,97,100,101,100,32,102, - 114,111,109,32,116,104,101,32,115,112,101,99,32,97,115,32, - 112,97,99,107,97,103,101,115,46,10,10,32,32,32,32,79, - 110,108,121,32,102,105,110,100,101,114,115,32,40,115,101,101, - 32,105,109,112,111,114,116,108,105,98,46,97,98,99,46,77, - 101,116,97,80,97,116,104,70,105,110,100,101,114,32,97,110, - 100,10,32,32,32,32,105,109,112,111,114,116,108,105,98,46, - 97,98,99,46,80,97,116,104,69,110,116,114,121,70,105,110, - 100,101,114,41,32,115,104,111,117,108,100,32,109,111,100,105, - 102,121,32,77,111,100,117,108,101,83,112,101,99,32,105,110, - 115,116,97,110,99,101,115,46,10,10,32,32,32,32,218,6, - 111,114,105,103,105,110,78,218,12,108,111,97,100,101,114,95, - 115,116,97,116,101,218,10,105,115,95,112,97,99,107,97,103, - 101,99,3,0,0,0,3,0,0,0,6,0,0,0,2,0, - 0,0,67,0,0,0,115,79,0,0,0,124,1,0,124,0, - 0,95,0,0,124,2,0,124,0,0,95,1,0,124,3,0, - 124,0,0,95,2,0,124,4,0,124,0,0,95,3,0,124, - 5,0,114,48,0,103,0,0,110,3,0,100,0,0,124,0, - 0,95,4,0,100,1,0,124,0,0,95,5,0,100,0,0, - 124,0,0,95,6,0,100,0,0,83,41,2,78,70,41,7, - 114,67,0,0,0,114,169,0,0,0,114,217,0,0,0,114, - 218,0,0,0,218,26,115,117,98,109,111,100,117,108,101,95, + 0,114,226,0,0,0,83,3,0,0,115,2,0,0,0,0, + 2,122,23,77,111,100,117,108,101,83,112,101,99,46,104,97, + 115,95,108,111,99,97,116,105,111,110,99,2,0,0,0,0, + 0,0,0,2,0,0,0,2,0,0,0,67,0,0,0,115, + 19,0,0,0,116,0,0,124,1,0,131,1,0,124,0,0, + 95,1,0,100,0,0,83,41,1,78,41,2,218,4,98,111, + 111,108,114,221,0,0,0,41,2,114,71,0,0,0,218,5, + 118,97,108,117,101,114,4,0,0,0,114,4,0,0,0,114, + 5,0,0,0,114,226,0,0,0,87,3,0,0,115,2,0, + 0,0,0,2,41,12,114,57,0,0,0,114,56,0,0,0, + 114,58,0,0,0,114,59,0,0,0,114,72,0,0,0,114, + 101,0,0,0,114,229,0,0,0,218,8,112,114,111,112,101, + 114,116,121,114,225,0,0,0,218,6,115,101,116,116,101,114, + 114,233,0,0,0,114,226,0,0,0,114,4,0,0,0,114, + 4,0,0,0,114,4,0,0,0,114,5,0,0,0,114,216, + 0,0,0,242,2,0,0,115,20,0,0,0,12,35,6,2, + 15,1,15,11,12,10,12,12,18,14,21,4,18,8,18,4, + 114,216,0,0,0,114,217,0,0,0,114,219,0,0,0,99, + 2,0,0,0,2,0,0,0,5,0,0,0,15,0,0,0, + 67,0,0,0,115,190,0,0,0,116,0,0,124,1,0,100, + 1,0,131,2,0,114,83,0,124,3,0,100,2,0,107,8, + 0,114,43,0,116,1,0,124,0,0,100,3,0,124,1,0, + 131,1,1,83,124,3,0,114,55,0,103,0,0,110,3,0, + 100,2,0,125,4,0,116,1,0,124,0,0,100,3,0,124, + 1,0,100,4,0,124,4,0,131,1,2,83,124,3,0,100, + 2,0,107,8,0,114,165,0,116,0,0,124,1,0,100,5, + 0,131,2,0,114,159,0,121,19,0,124,1,0,106,2,0, + 124,0,0,131,1,0,125,3,0,87,113,165,0,4,116,3, + 0,107,10,0,114,155,0,1,1,1,100,2,0,125,3,0, + 89,113,165,0,88,110,6,0,100,6,0,125,3,0,116,4, + 0,124,0,0,124,1,0,100,7,0,124,2,0,100,5,0, + 124,3,0,131,2,2,83,41,8,122,53,82,101,116,117,114, + 110,32,97,32,109,111,100,117,108,101,32,115,112,101,99,32, + 98,97,115,101,100,32,111,110,32,118,97,114,105,111,117,115, + 32,108,111,97,100,101,114,32,109,101,116,104,111,100,115,46, + 218,12,103,101,116,95,102,105,108,101,110,97,109,101,78,114, + 170,0,0,0,114,220,0,0,0,114,219,0,0,0,70,114, + 217,0,0,0,41,5,114,60,0,0,0,218,23,115,112,101, + 99,95,102,114,111,109,95,102,105,108,101,95,108,111,99,97, + 116,105,111,110,114,219,0,0,0,114,154,0,0,0,114,216, + 0,0,0,41,5,114,67,0,0,0,114,170,0,0,0,114, + 217,0,0,0,114,219,0,0,0,90,6,115,101,97,114,99, + 104,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, + 114,174,0,0,0,92,3,0,0,115,28,0,0,0,0,2, + 15,1,12,1,16,1,18,1,15,1,7,2,12,1,15,1, + 3,1,19,1,13,1,14,3,6,2,114,174,0,0,0,114, + 170,0,0,0,114,220,0,0,0,99,2,0,0,0,2,0, + 0,0,9,0,0,0,19,0,0,0,67,0,0,0,115,86, + 1,0,0,124,1,0,100,1,0,107,8,0,114,73,0,100, + 2,0,125,1,0,116,0,0,124,2,0,100,3,0,131,2, + 0,114,73,0,121,19,0,124,2,0,106,1,0,124,0,0, + 131,1,0,125,1,0,87,110,18,0,4,116,2,0,107,10, + 0,114,72,0,1,1,1,89,110,1,0,88,116,3,0,124, + 0,0,124,2,0,100,4,0,124,1,0,131,2,1,125,4, + 0,100,5,0,124,4,0,95,4,0,124,2,0,100,1,0, + 107,8,0,114,191,0,120,73,0,116,5,0,131,0,0,68, + 93,58,0,92,2,0,125,5,0,125,6,0,124,1,0,106, + 6,0,116,7,0,124,6,0,131,1,0,131,1,0,114,125, + 0,124,5,0,124,0,0,124,1,0,131,2,0,125,2,0, + 124,2,0,124,4,0,95,8,0,80,113,125,0,87,100,1, + 0,83,124,3,0,116,9,0,107,8,0,114,20,1,116,0, + 0,124,2,0,100,6,0,131,2,0,114,29,1,121,19,0, + 124,2,0,106,10,0,124,0,0,131,1,0,125,7,0,87, + 110,18,0,4,116,2,0,107,10,0,114,1,1,1,1,1, + 89,113,29,1,88,124,7,0,114,29,1,103,0,0,124,4, + 0,95,11,0,110,9,0,124,3,0,124,4,0,95,11,0, + 124,4,0,106,11,0,103,0,0,107,2,0,114,82,1,124, + 1,0,114,82,1,116,12,0,124,1,0,131,1,0,100,7, + 0,25,125,8,0,124,4,0,106,11,0,106,13,0,124,8, + 0,131,1,0,1,124,4,0,83,41,8,97,61,1,0,0, + 82,101,116,117,114,110,32,97,32,109,111,100,117,108,101,32, + 115,112,101,99,32,98,97,115,101,100,32,111,110,32,97,32, + 102,105,108,101,32,108,111,99,97,116,105,111,110,46,10,10, + 32,32,32,32,84,111,32,105,110,100,105,99,97,116,101,32, + 116,104,97,116,32,116,104,101,32,109,111,100,117,108,101,32, + 105,115,32,97,32,112,97,99,107,97,103,101,44,32,115,101, + 116,10,32,32,32,32,115,117,98,109,111,100,117,108,101,95, 115,101,97,114,99,104,95,108,111,99,97,116,105,111,110,115, - 218,13,95,115,101,116,95,102,105,108,101,97,116,116,114,218, - 7,95,99,97,99,104,101,100,41,6,114,71,0,0,0,114, - 67,0,0,0,114,169,0,0,0,114,217,0,0,0,114,218, - 0,0,0,114,219,0,0,0,114,4,0,0,0,114,4,0, - 0,0,114,5,0,0,0,114,72,0,0,0,12,3,0,0, - 115,14,0,0,0,0,2,9,1,9,1,9,1,9,1,21, - 3,9,1,122,19,77,111,100,117,108,101,83,112,101,99,46, - 95,95,105,110,105,116,95,95,99,1,0,0,0,0,0,0, - 0,2,0,0,0,4,0,0,0,67,0,0,0,115,153,0, - 0,0,100,1,0,106,0,0,124,0,0,106,1,0,131,1, - 0,100,2,0,106,0,0,124,0,0,106,2,0,131,1,0, - 103,2,0,125,1,0,124,0,0,106,3,0,100,0,0,107, - 9,0,114,79,0,124,1,0,106,4,0,100,3,0,106,0, - 0,124,0,0,106,3,0,131,1,0,131,1,0,1,110,0, - 0,124,0,0,106,5,0,100,0,0,107,9,0,114,122,0, - 124,1,0,106,4,0,100,4,0,106,0,0,124,0,0,106, - 5,0,131,1,0,131,1,0,1,110,0,0,100,5,0,106, - 0,0,124,0,0,106,6,0,106,7,0,100,6,0,106,8, - 0,124,1,0,131,1,0,131,2,0,83,41,7,78,122,9, - 110,97,109,101,61,123,33,114,125,122,11,108,111,97,100,101, - 114,61,123,33,114,125,122,11,111,114,105,103,105,110,61,123, - 33,114,125,122,29,115,117,98,109,111,100,117,108,101,95,115, - 101,97,114,99,104,95,108,111,99,97,116,105,111,110,115,61, - 123,125,122,6,123,125,40,123,125,41,122,2,44,32,41,9, - 114,47,0,0,0,114,67,0,0,0,114,169,0,0,0,114, - 217,0,0,0,218,6,97,112,112,101,110,100,114,220,0,0, - 0,218,9,95,95,99,108,97,115,115,95,95,114,57,0,0, - 0,114,26,0,0,0,41,2,114,71,0,0,0,114,80,0, - 0,0,114,4,0,0,0,114,4,0,0,0,114,5,0,0, - 0,114,101,0,0,0,24,3,0,0,115,16,0,0,0,0, - 1,15,1,21,1,15,1,28,1,15,1,6,1,22,1,122, - 19,77,111,100,117,108,101,83,112,101,99,46,95,95,114,101, - 112,114,95,95,99,2,0,0,0,0,0,0,0,3,0,0, - 0,13,0,0,0,67,0,0,0,115,145,0,0,0,124,0, - 0,106,0,0,125,2,0,121,107,0,124,0,0,106,1,0, - 124,1,0,106,1,0,107,2,0,111,114,0,124,0,0,106, - 2,0,124,1,0,106,2,0,107,2,0,111,114,0,124,0, - 0,106,3,0,124,1,0,106,3,0,107,2,0,111,114,0, - 124,2,0,124,1,0,106,0,0,107,2,0,111,114,0,124, - 0,0,106,4,0,124,1,0,106,4,0,107,2,0,111,114, - 0,124,0,0,106,5,0,124,1,0,106,5,0,107,2,0, - 83,87,110,22,0,4,116,6,0,107,10,0,114,140,0,1, - 1,1,100,1,0,83,89,110,1,0,88,100,0,0,83,41, - 2,78,70,41,7,114,220,0,0,0,114,67,0,0,0,114, - 169,0,0,0,114,217,0,0,0,218,6,99,97,99,104,101, - 100,218,12,104,97,115,95,108,111,99,97,116,105,111,110,114, - 209,0,0,0,41,3,114,71,0,0,0,90,5,111,116,104, - 101,114,90,4,115,109,115,108,114,4,0,0,0,114,4,0, - 0,0,114,5,0,0,0,218,6,95,95,101,113,95,95,34, - 3,0,0,115,20,0,0,0,0,1,9,1,3,1,18,1, - 18,1,18,1,15,1,18,1,20,1,13,1,122,17,77,111, - 100,117,108,101,83,112,101,99,46,95,95,101,113,95,95,99, - 1,0,0,0,0,0,0,0,2,0,0,0,12,0,0,0, - 67,0,0,0,115,158,0,0,0,124,0,0,106,0,0,100, - 0,0,107,8,0,114,151,0,124,0,0,106,1,0,100,0, - 0,107,9,0,114,151,0,124,0,0,106,2,0,114,151,0, - 124,0,0,106,1,0,125,1,0,124,1,0,106,3,0,116, - 4,0,116,5,0,131,1,0,131,1,0,114,112,0,121,19, - 0,116,6,0,124,1,0,131,1,0,124,0,0,95,0,0, - 87,113,145,0,4,116,7,0,107,10,0,114,108,0,1,1, - 1,89,113,145,0,88,113,148,0,124,1,0,106,3,0,116, - 4,0,116,8,0,131,1,0,131,1,0,114,148,0,124,1, - 0,124,0,0,95,0,0,113,148,0,113,151,0,110,0,0, - 124,0,0,106,0,0,83,41,1,78,41,9,114,222,0,0, - 0,114,217,0,0,0,114,221,0,0,0,218,8,101,110,100, - 115,119,105,116,104,218,5,116,117,112,108,101,114,134,0,0, - 0,114,132,0,0,0,114,124,0,0,0,218,17,66,89,84, - 69,67,79,68,69,95,83,85,70,70,73,88,69,83,41,2, - 114,71,0,0,0,114,131,0,0,0,114,4,0,0,0,114, - 4,0,0,0,114,5,0,0,0,114,225,0,0,0,46,3, - 0,0,115,22,0,0,0,0,2,15,1,24,1,9,1,21, - 1,3,1,19,1,13,1,8,1,21,1,18,1,122,17,77, - 111,100,117,108,101,83,112,101,99,46,99,97,99,104,101,100, - 99,2,0,0,0,0,0,0,0,2,0,0,0,2,0,0, - 0,67,0,0,0,115,13,0,0,0,124,1,0,124,0,0, - 95,0,0,100,0,0,83,41,1,78,41,1,114,222,0,0, - 0,41,2,114,71,0,0,0,114,225,0,0,0,114,4,0, - 0,0,114,4,0,0,0,114,5,0,0,0,114,225,0,0, - 0,60,3,0,0,115,2,0,0,0,0,2,99,1,0,0, - 0,0,0,0,0,1,0,0,0,2,0,0,0,67,0,0, - 0,115,46,0,0,0,124,0,0,106,0,0,100,1,0,107, - 8,0,114,35,0,124,0,0,106,1,0,106,2,0,100,2, - 0,131,1,0,100,3,0,25,83,124,0,0,106,1,0,83, - 100,1,0,83,41,4,122,32,84,104,101,32,110,97,109,101, - 32,111,102,32,116,104,101,32,109,111,100,117,108,101,39,115, - 32,112,97,114,101,110,116,46,78,114,116,0,0,0,114,84, - 0,0,0,41,3,114,220,0,0,0,114,67,0,0,0,114, - 32,0,0,0,41,1,114,71,0,0,0,114,4,0,0,0, - 114,4,0,0,0,114,5,0,0,0,218,6,112,97,114,101, - 110,116,64,3,0,0,115,6,0,0,0,0,3,15,1,20, - 2,122,17,77,111,100,117,108,101,83,112,101,99,46,112,97, - 114,101,110,116,99,1,0,0,0,0,0,0,0,1,0,0, - 0,1,0,0,0,67,0,0,0,115,7,0,0,0,124,0, - 0,106,0,0,83,41,1,78,41,1,114,221,0,0,0,41, - 1,114,71,0,0,0,114,4,0,0,0,114,4,0,0,0, - 114,5,0,0,0,114,226,0,0,0,72,3,0,0,115,2, - 0,0,0,0,2,122,23,77,111,100,117,108,101,83,112,101, - 99,46,104,97,115,95,108,111,99,97,116,105,111,110,41,12, - 114,57,0,0,0,114,56,0,0,0,114,58,0,0,0,114, - 59,0,0,0,114,72,0,0,0,114,101,0,0,0,114,227, - 0,0,0,218,8,112,114,111,112,101,114,116,121,114,225,0, - 0,0,218,6,115,101,116,116,101,114,114,231,0,0,0,114, - 226,0,0,0,114,4,0,0,0,114,4,0,0,0,114,4, - 0,0,0,114,5,0,0,0,114,216,0,0,0,231,2,0, - 0,115,18,0,0,0,12,35,6,2,15,1,15,11,12,10, - 12,12,18,14,21,4,18,8,114,216,0,0,0,114,217,0, - 0,0,114,219,0,0,0,99,2,0,0,0,2,0,0,0, - 5,0,0,0,15,0,0,0,67,0,0,0,115,193,0,0, - 0,116,0,0,124,1,0,100,1,0,131,2,0,114,83,0, - 124,3,0,100,2,0,107,8,0,114,43,0,116,1,0,124, - 0,0,100,3,0,124,1,0,131,1,1,83,124,3,0,114, - 55,0,103,0,0,110,3,0,100,2,0,125,4,0,116,1, - 0,124,0,0,100,3,0,124,1,0,100,4,0,124,4,0, - 131,1,2,83,124,3,0,100,2,0,107,8,0,114,168,0, - 116,0,0,124,1,0,100,5,0,131,2,0,114,159,0,121, - 19,0,124,1,0,106,2,0,124,0,0,131,1,0,125,3, - 0,87,113,165,0,4,116,3,0,107,10,0,114,155,0,1, - 1,1,100,2,0,125,3,0,89,113,165,0,88,113,168,0, - 100,6,0,125,3,0,110,0,0,116,4,0,124,0,0,124, - 1,0,100,7,0,124,2,0,100,5,0,124,3,0,131,2, - 2,83,41,8,122,53,82,101,116,117,114,110,32,97,32,109, - 111,100,117,108,101,32,115,112,101,99,32,98,97,115,101,100, - 32,111,110,32,118,97,114,105,111,117,115,32,108,111,97,100, - 101,114,32,109,101,116,104,111,100,115,46,218,12,103,101,116, - 95,102,105,108,101,110,97,109,101,78,114,169,0,0,0,114, - 220,0,0,0,114,219,0,0,0,70,114,217,0,0,0,41, - 5,114,60,0,0,0,218,23,115,112,101,99,95,102,114,111, - 109,95,102,105,108,101,95,108,111,99,97,116,105,111,110,114, - 219,0,0,0,114,153,0,0,0,114,216,0,0,0,41,5, - 114,67,0,0,0,114,169,0,0,0,114,217,0,0,0,114, - 219,0,0,0,90,6,115,101,97,114,99,104,114,4,0,0, - 0,114,4,0,0,0,114,5,0,0,0,114,173,0,0,0, - 77,3,0,0,115,28,0,0,0,0,2,15,1,12,1,16, - 1,18,1,15,1,7,2,12,1,15,1,3,1,19,1,13, - 1,14,3,9,2,114,173,0,0,0,114,169,0,0,0,114, - 220,0,0,0,99,2,0,0,0,2,0,0,0,9,0,0, - 0,19,0,0,0,67,0,0,0,115,110,1,0,0,124,1, - 0,100,1,0,107,8,0,114,79,0,100,2,0,125,1,0, - 116,0,0,124,2,0,100,3,0,131,2,0,114,79,0,121, - 19,0,124,2,0,106,1,0,124,0,0,131,1,0,125,1, - 0,87,113,76,0,4,116,2,0,107,10,0,114,72,0,1, - 1,1,89,113,76,0,88,113,79,0,110,0,0,116,3,0, - 124,0,0,124,2,0,100,4,0,124,1,0,131,2,1,125, - 4,0,100,5,0,124,4,0,95,4,0,124,2,0,100,1, - 0,107,8,0,114,203,0,120,79,0,116,5,0,131,0,0, - 68,93,61,0,92,2,0,125,5,0,125,6,0,124,1,0, - 106,6,0,116,7,0,124,6,0,131,1,0,131,1,0,114, - 131,0,124,5,0,124,0,0,124,1,0,131,2,0,125,2, - 0,124,2,0,124,4,0,95,8,0,80,113,131,0,113,131, - 0,87,100,1,0,83,110,0,0,124,3,0,116,9,0,107, - 8,0,114,38,1,116,0,0,124,2,0,100,6,0,131,2, - 0,114,47,1,121,19,0,124,2,0,106,10,0,124,0,0, - 131,1,0,125,7,0,87,110,18,0,4,116,2,0,107,10, - 0,114,13,1,1,1,1,89,113,35,1,88,124,7,0,114, - 35,1,103,0,0,124,4,0,95,11,0,113,35,1,113,47, - 1,110,9,0,124,3,0,124,4,0,95,11,0,124,4,0, - 106,11,0,103,0,0,107,2,0,114,106,1,124,1,0,114, - 106,1,116,12,0,124,1,0,131,1,0,100,7,0,25,125, - 8,0,124,4,0,106,11,0,106,13,0,124,8,0,131,1, - 0,1,113,106,1,110,0,0,124,4,0,83,41,8,97,61, - 1,0,0,82,101,116,117,114,110,32,97,32,109,111,100,117, - 108,101,32,115,112,101,99,32,98,97,115,101,100,32,111,110, - 32,97,32,102,105,108,101,32,108,111,99,97,116,105,111,110, - 46,10,10,32,32,32,32,84,111,32,105,110,100,105,99,97, - 116,101,32,116,104,97,116,32,116,104,101,32,109,111,100,117, - 108,101,32,105,115,32,97,32,112,97,99,107,97,103,101,44, - 32,115,101,116,10,32,32,32,32,115,117,98,109,111,100,117, - 108,101,95,115,101,97,114,99,104,95,108,111,99,97,116,105, - 111,110,115,32,116,111,32,97,32,108,105,115,116,32,111,102, - 32,100,105,114,101,99,116,111,114,121,32,112,97,116,104,115, - 46,32,32,65,110,10,32,32,32,32,101,109,112,116,121,32, - 108,105,115,116,32,105,115,32,115,117,102,102,105,99,105,101, - 110,116,44,32,116,104,111,117,103,104,32,105,116,115,32,110, - 111,116,32,111,116,104,101,114,119,105,115,101,32,117,115,101, - 102,117,108,32,116,111,32,116,104,101,10,32,32,32,32,105, - 109,112,111,114,116,32,115,121,115,116,101,109,46,10,10,32, - 32,32,32,84,104,101,32,108,111,97,100,101,114,32,109,117, - 115,116,32,116,97,107,101,32,97,32,115,112,101,99,32,97, - 115,32,105,116,115,32,111,110,108,121,32,95,95,105,110,105, - 116,95,95,40,41,32,97,114,103,46,10,10,32,32,32,32, - 78,122,9,60,117,110,107,110,111,119,110,62,114,234,0,0, - 0,114,217,0,0,0,84,114,219,0,0,0,114,84,0,0, - 0,41,14,114,60,0,0,0,114,234,0,0,0,114,153,0, - 0,0,114,216,0,0,0,114,221,0,0,0,218,27,95,103, - 101,116,95,115,117,112,112,111,114,116,101,100,95,102,105,108, - 101,95,108,111,97,100,101,114,115,114,228,0,0,0,114,229, - 0,0,0,114,169,0,0,0,218,9,95,80,79,80,85,76, - 65,84,69,114,219,0,0,0,114,220,0,0,0,114,38,0, - 0,0,114,223,0,0,0,41,9,114,67,0,0,0,218,8, - 108,111,99,97,116,105,111,110,114,169,0,0,0,114,220,0, - 0,0,114,177,0,0,0,218,12,108,111,97,100,101,114,95, - 99,108,97,115,115,114,127,0,0,0,114,219,0,0,0,90, - 7,100,105,114,110,97,109,101,114,4,0,0,0,114,4,0, - 0,0,114,5,0,0,0,114,235,0,0,0,102,3,0,0, - 115,60,0,0,0,0,12,12,4,6,1,15,2,3,1,19, - 1,13,1,11,8,21,1,9,3,12,1,22,1,21,1,15, - 1,9,1,8,2,7,3,12,2,15,1,3,1,19,1,13, - 1,5,2,6,1,18,2,9,1,15,1,6,1,16,1,22, - 2,114,235,0,0,0,99,3,0,0,0,0,0,0,0,8, - 0,0,0,53,0,0,0,67,0,0,0,115,124,1,0,0, - 121,13,0,124,0,0,106,0,0,125,3,0,87,110,18,0, - 4,116,1,0,107,10,0,114,33,0,1,1,1,89,110,17, - 0,88,124,3,0,100,0,0,107,9,0,114,50,0,124,3, - 0,83,124,0,0,106,2,0,125,4,0,124,1,0,100,0, - 0,107,8,0,114,108,0,121,13,0,124,0,0,106,3,0, - 125,1,0,87,113,108,0,4,116,1,0,107,10,0,114,104, - 0,1,1,1,89,113,108,0,88,110,0,0,121,13,0,124, - 0,0,106,4,0,125,5,0,87,110,24,0,4,116,1,0, - 107,10,0,114,147,0,1,1,1,100,0,0,125,5,0,89, - 110,1,0,88,124,2,0,100,0,0,107,8,0,114,224,0, - 124,5,0,100,0,0,107,8,0,114,215,0,121,13,0,124, - 1,0,106,5,0,125,2,0,87,113,221,0,4,116,1,0, - 107,10,0,114,211,0,1,1,1,100,0,0,125,2,0,89, - 113,221,0,88,113,224,0,124,5,0,125,2,0,110,0,0, - 121,13,0,124,0,0,106,6,0,125,6,0,87,110,24,0, - 4,116,1,0,107,10,0,114,7,1,1,1,1,100,0,0, - 125,6,0,89,110,1,0,88,121,19,0,116,7,0,124,0, - 0,106,8,0,131,1,0,125,7,0,87,110,24,0,4,116, - 1,0,107,10,0,114,53,1,1,1,1,100,0,0,125,7, - 0,89,110,1,0,88,116,9,0,124,4,0,124,1,0,100, - 1,0,124,2,0,131,2,1,125,3,0,124,5,0,100,0, - 0,107,8,0,114,93,1,100,2,0,110,3,0,100,3,0, - 124,3,0,95,10,0,124,6,0,124,3,0,95,11,0,124, - 7,0,124,3,0,95,12,0,124,3,0,83,41,4,78,114, - 217,0,0,0,70,84,41,13,114,208,0,0,0,114,209,0, - 0,0,114,57,0,0,0,114,204,0,0,0,114,210,0,0, - 0,90,7,95,79,82,73,71,73,78,218,10,95,95,99,97, - 99,104,101,100,95,95,218,4,108,105,115,116,218,8,95,95, - 112,97,116,104,95,95,114,216,0,0,0,114,221,0,0,0, - 114,225,0,0,0,114,220,0,0,0,41,8,114,179,0,0, - 0,114,169,0,0,0,114,217,0,0,0,114,177,0,0,0, - 114,67,0,0,0,114,238,0,0,0,114,225,0,0,0,114, - 220,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5, - 0,0,0,218,17,95,115,112,101,99,95,102,114,111,109,95, - 109,111,100,117,108,101,166,3,0,0,115,72,0,0,0,0, - 2,3,1,13,1,13,1,5,2,12,1,4,2,9,1,12, - 1,3,1,13,1,13,2,8,1,3,1,13,1,13,1,11, - 1,12,1,12,1,3,1,13,1,13,1,14,2,9,1,3, - 1,13,1,13,1,11,1,3,1,19,1,13,1,11,2,21, - 1,27,1,9,1,9,1,114,243,0,0,0,99,0,0,0, - 0,0,0,0,0,0,0,0,0,6,0,0,0,64,0,0, - 0,115,172,0,0,0,101,0,0,90,1,0,100,0,0,90, - 2,0,100,1,0,90,3,0,100,2,0,100,3,0,132,0, - 0,90,4,0,101,5,0,100,4,0,100,5,0,132,0,0, - 131,1,0,90,6,0,100,6,0,100,7,0,132,0,0,90, - 7,0,100,8,0,100,9,0,100,10,0,100,11,0,100,12, - 0,100,13,0,132,0,2,90,8,0,100,14,0,100,15,0, - 132,0,0,90,9,0,100,16,0,100,17,0,132,0,0,90, - 10,0,100,18,0,100,19,0,132,0,0,90,11,0,100,20, - 0,100,21,0,132,0,0,90,12,0,100,22,0,100,23,0, - 132,0,0,90,13,0,100,24,0,100,25,0,132,0,0,90, - 14,0,100,26,0,100,27,0,132,0,0,90,15,0,100,28, - 0,83,41,29,114,174,0,0,0,122,77,67,111,110,118,101, - 110,105,101,110,99,101,32,119,114,97,112,112,101,114,32,97, - 114,111,117,110,100,32,115,112,101,99,32,111,98,106,101,99, - 116,115,32,116,111,32,112,114,111,118,105,100,101,32,115,112, - 101,99,45,115,112,101,99,105,102,105,99,10,32,32,32,32, - 109,101,116,104,111,100,115,46,99,2,0,0,0,0,0,0, - 0,2,0,0,0,2,0,0,0,67,0,0,0,115,13,0, - 0,0,124,1,0,124,0,0,95,0,0,100,0,0,83,41, - 1,78,41,1,114,177,0,0,0,41,2,114,71,0,0,0, - 114,177,0,0,0,114,4,0,0,0,114,4,0,0,0,114, - 5,0,0,0,114,72,0,0,0,216,3,0,0,115,2,0, - 0,0,0,1,122,21,95,83,112,101,99,77,101,116,104,111, - 100,115,46,95,95,105,110,105,116,95,95,99,2,0,0,0, - 0,0,0,0,4,0,0,0,17,0,0,0,67,0,0,0, - 115,144,0,0,0,121,13,0,124,1,0,106,0,0,125,2, - 0,87,110,118,0,4,116,1,0,107,10,0,114,133,0,1, - 1,1,121,13,0,124,2,0,106,2,0,125,3,0,87,110, - 66,0,4,116,1,0,107,10,0,114,110,0,1,1,1,116, - 3,0,124,1,0,106,4,0,131,1,0,125,2,0,124,2, - 0,100,1,0,107,8,0,114,106,0,116,5,0,124,1,0, - 106,4,0,124,3,0,131,2,0,125,2,0,110,0,0,89, - 110,19,0,88,116,5,0,124,1,0,106,4,0,124,3,0, - 131,2,0,125,2,0,89,110,1,0,88,124,0,0,124,2, - 0,131,1,0,83,41,2,122,41,67,114,101,97,116,101,32, - 97,32,115,112,101,99,32,102,114,111,109,32,97,32,109,111, - 100,117,108,101,39,115,32,97,116,116,114,105,98,117,116,101, - 115,46,78,41,6,114,208,0,0,0,114,209,0,0,0,114, - 204,0,0,0,218,10,95,102,105,110,100,95,115,112,101,99, - 114,57,0,0,0,114,173,0,0,0,41,4,218,3,99,108, - 115,114,179,0,0,0,114,177,0,0,0,114,169,0,0,0, - 114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,218, - 11,102,114,111,109,95,109,111,100,117,108,101,219,3,0,0, - 115,22,0,0,0,0,3,3,1,13,1,13,1,3,1,13, - 1,13,1,15,1,12,1,26,2,23,1,122,24,95,83,112, - 101,99,77,101,116,104,111,100,115,46,102,114,111,109,95,109, - 111,100,117,108,101,99,1,0,0,0,0,0,0,0,3,0, - 0,0,3,0,0,0,67,0,0,0,115,158,0,0,0,124, - 0,0,106,0,0,125,1,0,124,1,0,106,1,0,100,1, - 0,107,8,0,114,30,0,100,2,0,110,6,0,124,1,0, - 106,1,0,125,2,0,124,1,0,106,2,0,100,1,0,107, - 8,0,114,104,0,124,1,0,106,3,0,100,1,0,107,8, - 0,114,82,0,100,3,0,106,4,0,124,2,0,131,1,0, - 83,100,4,0,106,4,0,124,2,0,124,1,0,106,3,0, - 131,2,0,83,110,50,0,124,1,0,106,5,0,114,132,0, - 100,5,0,106,4,0,124,2,0,124,1,0,106,2,0,131, - 2,0,83,100,6,0,106,4,0,124,1,0,106,1,0,124, - 1,0,106,2,0,131,2,0,83,100,1,0,83,41,7,122, - 38,82,101,116,117,114,110,32,116,104,101,32,114,101,112,114, - 32,116,111,32,117,115,101,32,102,111,114,32,116,104,101,32, - 109,111,100,117,108,101,46,78,114,206,0,0,0,122,13,60, - 109,111,100,117,108,101,32,123,33,114,125,62,122,20,60,109, - 111,100,117,108,101,32,123,33,114,125,32,40,123,33,114,125, - 41,62,122,23,60,109,111,100,117,108,101,32,123,33,114,125, - 32,102,114,111,109,32,123,33,114,125,62,122,18,60,109,111, - 100,117,108,101,32,123,33,114,125,32,40,123,125,41,62,41, - 6,114,177,0,0,0,114,67,0,0,0,114,217,0,0,0, - 114,169,0,0,0,114,47,0,0,0,114,226,0,0,0,41, - 3,114,71,0,0,0,114,177,0,0,0,114,67,0,0,0, - 114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,114, - 205,0,0,0,235,3,0,0,115,18,0,0,0,0,3,9, - 1,30,1,15,1,15,1,13,2,22,2,9,1,19,2,122, - 24,95,83,112,101,99,77,101,116,104,111,100,115,46,109,111, - 100,117,108,101,95,114,101,112,114,218,9,95,111,118,101,114, - 114,105,100,101,70,218,11,95,102,111,114,99,101,95,110,97, - 109,101,84,99,2,0,0,0,2,0,0,0,6,0,0,0, - 66,0,0,0,67,0,0,0,115,75,2,0,0,124,0,0, - 106,0,0,125,4,0,124,2,0,115,45,0,124,3,0,115, - 45,0,116,1,0,124,1,0,100,1,0,100,2,0,131,3, - 0,100,2,0,107,8,0,114,85,0,121,16,0,124,4,0, - 106,2,0,124,1,0,95,3,0,87,113,85,0,4,116,4, - 0,107,10,0,114,81,0,1,1,1,89,113,85,0,88,110, - 0,0,124,2,0,115,115,0,116,1,0,124,1,0,100,3, - 0,100,2,0,131,3,0,100,2,0,107,8,0,114,221,0, - 124,4,0,106,5,0,125,5,0,124,5,0,100,2,0,107, - 8,0,114,184,0,124,4,0,106,6,0,100,2,0,107,9, - 0,114,184,0,116,7,0,106,8,0,116,7,0,131,1,0, - 125,5,0,124,4,0,106,6,0,124,5,0,95,9,0,113, - 184,0,110,0,0,121,13,0,124,5,0,124,1,0,95,10, - 0,87,113,221,0,4,116,4,0,107,10,0,114,217,0,1, - 1,1,89,113,221,0,88,110,0,0,124,2,0,115,251,0, - 116,1,0,124,1,0,100,4,0,100,2,0,131,3,0,100, - 2,0,107,8,0,114,35,1,121,16,0,124,4,0,106,11, - 0,124,1,0,95,12,0,87,113,35,1,4,116,4,0,107, - 10,0,114,31,1,1,1,1,89,113,35,1,88,110,0,0, - 121,13,0,124,4,0,124,1,0,95,13,0,87,110,18,0, - 4,116,4,0,107,10,0,114,68,1,1,1,1,89,110,1, - 0,88,124,2,0,115,99,1,116,1,0,124,1,0,100,5, - 0,100,2,0,131,3,0,100,2,0,107,8,0,114,157,1, - 124,4,0,106,6,0,100,2,0,107,9,0,114,157,1,121, - 16,0,124,4,0,106,6,0,124,1,0,95,14,0,87,113, - 154,1,4,116,4,0,107,10,0,114,150,1,1,1,1,89, - 113,154,1,88,113,157,1,110,0,0,124,4,0,106,15,0, - 114,71,2,124,2,0,115,196,1,116,1,0,124,1,0,100, - 6,0,100,2,0,131,3,0,100,2,0,107,8,0,114,236, - 1,121,16,0,124,4,0,106,16,0,124,1,0,95,17,0, - 87,113,236,1,4,116,4,0,107,10,0,114,232,1,1,1, - 1,89,113,236,1,88,110,0,0,124,2,0,115,10,2,116, - 1,0,124,1,0,100,7,0,100,2,0,131,3,0,100,2, - 0,107,8,0,114,71,2,124,4,0,106,18,0,100,2,0, - 107,9,0,114,68,2,121,16,0,124,4,0,106,18,0,124, - 1,0,95,19,0,87,113,65,2,4,116,4,0,107,10,0, - 114,61,2,1,1,1,89,113,65,2,88,113,68,2,113,71, - 2,110,0,0,100,2,0,83,41,8,97,29,2,0,0,83, - 101,116,32,116,104,101,32,109,111,100,117,108,101,39,115,32, - 97,116,116,114,105,98,117,116,101,115,46,10,10,32,32,32, - 32,32,32,32,32,65,108,108,32,109,105,115,115,105,110,103, - 32,105,109,112,111,114,116,45,114,101,108,97,116,101,100,32, - 109,111,100,117,108,101,32,97,116,116,114,105,98,117,116,101, - 115,32,119,105,108,108,32,98,101,32,115,101,116,46,32,32, - 72,101,114,101,10,32,32,32,32,32,32,32,32,105,115,32, - 104,111,119,32,116,104,101,32,115,112,101,99,32,97,116,116, - 114,105,98,117,116,101,115,32,109,97,112,32,111,110,116,111, - 32,116,104,101,32,109,111,100,117,108,101,58,10,10,32,32, - 32,32,32,32,32,32,115,112,101,99,46,110,97,109,101,32, - 45,62,32,109,111,100,117,108,101,46,95,95,110,97,109,101, - 95,95,10,32,32,32,32,32,32,32,32,115,112,101,99,46, - 108,111,97,100,101,114,32,45,62,32,109,111,100,117,108,101, - 46,95,95,108,111,97,100,101,114,95,95,10,32,32,32,32, - 32,32,32,32,115,112,101,99,46,112,97,114,101,110,116,32, - 45,62,32,109,111,100,117,108,101,46,95,95,112,97,99,107, - 97,103,101,95,95,10,32,32,32,32,32,32,32,32,115,112, - 101,99,32,45,62,32,109,111,100,117,108,101,46,95,95,115, - 112,101,99,95,95,10,10,32,32,32,32,32,32,32,32,79, - 112,116,105,111,110,97,108,58,10,32,32,32,32,32,32,32, - 32,115,112,101,99,46,111,114,105,103,105,110,32,45,62,32, - 109,111,100,117,108,101,46,95,95,102,105,108,101,95,95,32, - 40,105,102,32,115,112,101,99,46,115,101,116,95,102,105,108, - 101,97,116,116,114,32,105,115,32,116,114,117,101,41,10,32, - 32,32,32,32,32,32,32,115,112,101,99,46,99,97,99,104, - 101,100,32,45,62,32,109,111,100,117,108,101,46,95,95,99, - 97,99,104,101,100,95,95,32,40,105,102,32,95,95,102,105, - 108,101,95,95,32,97,108,115,111,32,115,101,116,41,10,32, - 32,32,32,32,32,32,32,115,112,101,99,46,115,117,98,109, - 111,100,117,108,101,95,115,101,97,114,99,104,95,108,111,99, - 97,116,105,111,110,115,32,45,62,32,109,111,100,117,108,101, - 46,95,95,112,97,116,104,95,95,32,40,105,102,32,115,101, - 116,41,10,10,32,32,32,32,32,32,32,32,114,57,0,0, - 0,78,114,204,0,0,0,218,11,95,95,112,97,99,107,97, - 103,101,95,95,114,242,0,0,0,114,210,0,0,0,114,240, - 0,0,0,41,20,114,177,0,0,0,114,62,0,0,0,114, - 67,0,0,0,114,57,0,0,0,114,209,0,0,0,114,169, - 0,0,0,114,220,0,0,0,218,16,95,78,97,109,101,115, - 112,97,99,101,76,111,97,100,101,114,218,7,95,95,110,101, - 119,95,95,218,5,95,112,97,116,104,114,204,0,0,0,114, - 231,0,0,0,114,249,0,0,0,114,208,0,0,0,114,242, - 0,0,0,114,226,0,0,0,114,217,0,0,0,114,210,0, - 0,0,114,225,0,0,0,114,240,0,0,0,41,6,114,71, - 0,0,0,114,179,0,0,0,114,247,0,0,0,114,248,0, - 0,0,114,177,0,0,0,114,169,0,0,0,114,4,0,0, - 0,114,4,0,0,0,114,5,0,0,0,218,17,105,110,105, - 116,95,109,111,100,117,108,101,95,97,116,116,114,115,251,3, - 0,0,115,88,0,0,0,0,17,9,6,12,1,24,1,3, - 1,16,1,13,1,8,3,30,1,9,1,12,2,15,1,15, - 1,18,1,3,1,13,1,13,1,8,3,30,1,3,1,16, - 1,13,1,8,3,3,1,13,1,13,1,5,3,30,1,15, - 1,3,1,16,1,13,1,11,2,9,2,30,1,3,1,16, - 1,13,1,8,3,30,1,15,1,3,1,16,1,13,1,122, - 30,95,83,112,101,99,77,101,116,104,111,100,115,46,105,110, - 105,116,95,109,111,100,117,108,101,95,97,116,116,114,115,99, - 1,0,0,0,0,0,0,0,3,0,0,0,3,0,0,0, - 67,0,0,0,115,101,0,0,0,124,0,0,106,0,0,125, - 1,0,116,1,0,124,1,0,106,2,0,100,1,0,131,2, - 0,114,48,0,124,1,0,106,2,0,106,3,0,124,1,0, - 131,1,0,125,2,0,110,6,0,100,2,0,125,2,0,124, - 2,0,100,2,0,107,8,0,114,84,0,116,4,0,124,1, - 0,106,5,0,131,1,0,125,2,0,110,0,0,124,0,0, - 106,6,0,124,2,0,131,1,0,1,124,2,0,83,41,3, - 122,153,82,101,116,117,114,110,32,97,32,110,101,119,32,109, - 111,100,117,108,101,32,116,111,32,98,101,32,108,111,97,100, - 101,100,46,10,10,32,32,32,32,32,32,32,32,84,104,101, - 32,105,109,112,111,114,116,45,114,101,108,97,116,101,100,32, - 109,111,100,117,108,101,32,97,116,116,114,105,98,117,116,101, - 115,32,97,114,101,32,97,108,115,111,32,115,101,116,32,119, - 105,116,104,32,116,104,101,10,32,32,32,32,32,32,32,32, - 97,112,112,114,111,112,114,105,97,116,101,32,118,97,108,117, - 101,115,32,102,114,111,109,32,116,104,101,32,115,112,101,99, - 46,10,10,32,32,32,32,32,32,32,32,218,13,99,114,101, - 97,116,101,95,109,111,100,117,108,101,78,41,7,114,177,0, - 0,0,114,60,0,0,0,114,169,0,0,0,114,254,0,0, - 0,114,68,0,0,0,114,67,0,0,0,114,253,0,0,0, - 41,3,114,71,0,0,0,114,177,0,0,0,114,179,0,0, - 0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, - 218,6,99,114,101,97,116,101,75,4,0,0,115,16,0,0, - 0,0,7,9,2,18,3,21,2,6,1,12,4,18,1,13, - 1,122,19,95,83,112,101,99,77,101,116,104,111,100,115,46, - 99,114,101,97,116,101,99,2,0,0,0,0,0,0,0,2, - 0,0,0,2,0,0,0,67,0,0,0,115,23,0,0,0, - 124,0,0,106,0,0,106,1,0,106,2,0,124,1,0,131, - 1,0,1,100,1,0,83,41,2,122,189,68,111,32,101,118, - 101,114,121,116,104,105,110,103,32,110,101,99,101,115,115,97, - 114,121,32,116,111,32,101,120,101,99,117,116,101,32,116,104, - 101,32,109,111,100,117,108,101,46,10,10,32,32,32,32,32, - 32,32,32,84,104,101,32,110,97,109,101,115,112,97,99,101, - 32,111,102,32,96,109,111,100,117,108,101,96,32,105,115,32, - 117,115,101,100,32,97,115,32,116,104,101,32,116,97,114,103, - 101,116,32,111,102,32,101,120,101,99,117,116,105,111,110,46, - 10,32,32,32,32,32,32,32,32,84,104,105,115,32,109,101, - 116,104,111,100,32,117,115,101,115,32,116,104,101,32,108,111, - 97,100,101,114,39,115,32,96,101,120,101,99,95,109,111,100, - 117,108,101,40,41,96,32,109,101,116,104,111,100,46,10,10, - 32,32,32,32,32,32,32,32,78,41,3,114,177,0,0,0, - 114,169,0,0,0,218,11,101,120,101,99,95,109,111,100,117, - 108,101,41,2,114,71,0,0,0,114,179,0,0,0,114,4, - 0,0,0,114,4,0,0,0,114,5,0,0,0,218,5,95, - 101,120,101,99,98,4,0,0,115,2,0,0,0,0,7,122, - 18,95,83,112,101,99,77,101,116,104,111,100,115,46,95,101, - 120,101,99,99,2,0,0,0,0,0,0,0,4,0,0,0, - 11,0,0,0,67,0,0,0,115,17,1,0,0,124,0,0, - 106,0,0,106,1,0,125,2,0,116,2,0,106,3,0,131, - 0,0,1,116,4,0,124,2,0,131,1,0,143,226,0,1, - 116,5,0,106,6,0,106,7,0,124,2,0,131,1,0,124, - 1,0,107,9,0,114,95,0,100,1,0,106,8,0,124,2, - 0,131,1,0,125,3,0,116,9,0,124,3,0,100,2,0, - 124,2,0,131,1,1,130,1,0,110,0,0,124,0,0,106, - 0,0,106,10,0,100,3,0,107,8,0,114,181,0,124,0, - 0,106,0,0,106,11,0,100,3,0,107,8,0,114,158,0, - 116,9,0,100,4,0,100,2,0,124,0,0,106,0,0,106, - 1,0,131,1,1,130,1,0,110,0,0,124,0,0,106,12, - 0,124,1,0,100,5,0,100,6,0,131,1,1,1,124,1, - 0,83,124,0,0,106,12,0,124,1,0,100,5,0,100,6, - 0,131,1,1,1,116,13,0,124,0,0,106,0,0,106,10, - 0,100,7,0,131,2,0,115,243,0,124,0,0,106,0,0, - 106,10,0,106,14,0,124,2,0,131,1,0,1,110,13,0, - 124,0,0,106,15,0,124,1,0,131,1,0,1,87,100,3, - 0,81,88,116,5,0,106,6,0,124,2,0,25,83,41,8, - 122,51,69,120,101,99,117,116,101,32,116,104,101,32,115,112, - 101,99,32,105,110,32,97,110,32,101,120,105,115,116,105,110, - 103,32,109,111,100,117,108,101,39,115,32,110,97,109,101,115, - 112,97,99,101,46,122,30,109,111,100,117,108,101,32,123,33, - 114,125,32,110,111,116,32,105,110,32,115,121,115,46,109,111, - 100,117,108,101,115,114,67,0,0,0,78,122,14,109,105,115, - 115,105,110,103,32,108,111,97,100,101,114,114,247,0,0,0, - 84,114,0,1,0,0,41,16,114,177,0,0,0,114,67,0, - 0,0,114,106,0,0,0,218,12,97,99,113,117,105,114,101, - 95,108,111,99,107,114,103,0,0,0,114,7,0,0,0,114, - 73,0,0,0,114,93,0,0,0,114,47,0,0,0,114,153, - 0,0,0,114,169,0,0,0,114,220,0,0,0,114,253,0, - 0,0,114,60,0,0,0,218,11,108,111,97,100,95,109,111, - 100,117,108,101,114,1,1,0,0,41,4,114,71,0,0,0, - 114,179,0,0,0,114,67,0,0,0,114,171,0,0,0,114, - 4,0,0,0,114,4,0,0,0,114,5,0,0,0,114,175, - 0,0,0,108,4,0,0,115,32,0,0,0,0,2,12,1, - 10,1,13,1,24,1,15,1,21,1,18,1,18,1,27,2, - 19,1,4,1,19,1,21,2,22,2,19,1,122,17,95,83, - 112,101,99,77,101,116,104,111,100,115,46,101,120,101,99,99, - 1,0,0,0,0,0,0,0,3,0,0,0,27,0,0,0, - 67,0,0,0,115,24,1,0,0,124,0,0,106,0,0,125, - 1,0,124,1,0,106,1,0,106,2,0,124,1,0,106,3, - 0,131,1,0,1,116,4,0,106,5,0,124,1,0,106,3, - 0,25,125,2,0,116,6,0,124,2,0,100,1,0,100,0, - 0,131,3,0,100,0,0,107,8,0,114,108,0,121,16,0, - 124,1,0,106,1,0,124,2,0,95,7,0,87,113,108,0, - 4,116,8,0,107,10,0,114,104,0,1,1,1,89,113,108, - 0,88,110,0,0,116,6,0,124,2,0,100,2,0,100,0, - 0,131,3,0,100,0,0,107,8,0,114,215,0,121,59,0, - 124,2,0,106,9,0,124,2,0,95,10,0,116,11,0,124, - 2,0,100,3,0,131,2,0,115,190,0,124,1,0,106,3, - 0,106,12,0,100,4,0,131,1,0,100,5,0,25,124,2, - 0,95,10,0,110,0,0,87,113,215,0,4,116,8,0,107, - 10,0,114,211,0,1,1,1,89,113,215,0,88,110,0,0, - 116,6,0,124,2,0,100,6,0,100,0,0,131,3,0,100, - 0,0,107,8,0,114,20,1,121,13,0,124,1,0,124,2, - 0,95,13,0,87,113,20,1,4,116,8,0,107,10,0,114, - 16,1,1,1,1,89,113,20,1,88,110,0,0,124,2,0, - 83,41,7,78,114,204,0,0,0,114,249,0,0,0,114,242, - 0,0,0,114,116,0,0,0,114,84,0,0,0,114,208,0, - 0,0,41,14,114,177,0,0,0,114,169,0,0,0,114,3, + 32,116,111,32,97,32,108,105,115,116,32,111,102,32,100,105, + 114,101,99,116,111,114,121,32,112,97,116,104,115,46,32,32, + 65,110,10,32,32,32,32,101,109,112,116,121,32,108,105,115, + 116,32,105,115,32,115,117,102,102,105,99,105,101,110,116,44, + 32,116,104,111,117,103,104,32,105,116,115,32,110,111,116,32, + 111,116,104,101,114,119,105,115,101,32,117,115,101,102,117,108, + 32,116,111,32,116,104,101,10,32,32,32,32,105,109,112,111, + 114,116,32,115,121,115,116,101,109,46,10,10,32,32,32,32, + 84,104,101,32,108,111,97,100,101,114,32,109,117,115,116,32, + 116,97,107,101,32,97,32,115,112,101,99,32,97,115,32,105, + 116,115,32,111,110,108,121,32,95,95,105,110,105,116,95,95, + 40,41,32,97,114,103,46,10,10,32,32,32,32,78,122,9, + 60,117,110,107,110,111,119,110,62,114,238,0,0,0,114,217, + 0,0,0,84,114,219,0,0,0,114,84,0,0,0,41,14, + 114,60,0,0,0,114,238,0,0,0,114,154,0,0,0,114, + 216,0,0,0,114,221,0,0,0,218,27,95,103,101,116,95, + 115,117,112,112,111,114,116,101,100,95,102,105,108,101,95,108, + 111,97,100,101,114,115,114,230,0,0,0,114,231,0,0,0, + 114,170,0,0,0,218,9,95,80,79,80,85,76,65,84,69, + 114,219,0,0,0,114,220,0,0,0,114,38,0,0,0,114, + 223,0,0,0,41,9,114,67,0,0,0,218,8,108,111,99, + 97,116,105,111,110,114,170,0,0,0,114,220,0,0,0,114, + 177,0,0,0,218,12,108,111,97,100,101,114,95,99,108,97, + 115,115,114,126,0,0,0,114,219,0,0,0,90,7,100,105, + 114,110,97,109,101,114,4,0,0,0,114,4,0,0,0,114, + 5,0,0,0,114,239,0,0,0,117,3,0,0,115,60,0, + 0,0,0,12,12,4,6,1,15,2,3,1,19,1,13,1, + 5,8,21,1,9,3,12,1,22,1,21,1,15,1,9,1, + 5,2,4,3,12,2,15,1,3,1,19,1,13,1,5,2, + 6,1,12,2,9,1,15,1,6,1,16,1,16,2,114,239, + 0,0,0,99,3,0,0,0,0,0,0,0,8,0,0,0, + 53,0,0,0,67,0,0,0,115,118,1,0,0,121,13,0, + 124,0,0,106,0,0,125,3,0,87,110,18,0,4,116,1, + 0,107,10,0,114,33,0,1,1,1,89,110,17,0,88,124, + 3,0,100,0,0,107,9,0,114,50,0,124,3,0,83,124, + 0,0,106,2,0,125,4,0,124,1,0,100,0,0,107,8, + 0,114,105,0,121,13,0,124,0,0,106,3,0,125,1,0, + 87,110,18,0,4,116,1,0,107,10,0,114,104,0,1,1, + 1,89,110,1,0,88,121,13,0,124,0,0,106,4,0,125, + 5,0,87,110,24,0,4,116,1,0,107,10,0,114,144,0, + 1,1,1,100,0,0,125,5,0,89,110,1,0,88,124,2, + 0,100,0,0,107,8,0,114,218,0,124,5,0,100,0,0, + 107,8,0,114,212,0,121,13,0,124,1,0,106,5,0,125, + 2,0,87,113,218,0,4,116,1,0,107,10,0,114,208,0, + 1,1,1,100,0,0,125,2,0,89,113,218,0,88,110,6, + 0,124,5,0,125,2,0,121,13,0,124,0,0,106,6,0, + 125,6,0,87,110,24,0,4,116,1,0,107,10,0,114,1, + 1,1,1,1,100,0,0,125,6,0,89,110,1,0,88,121, + 19,0,116,7,0,124,0,0,106,8,0,131,1,0,125,7, + 0,87,110,24,0,4,116,1,0,107,10,0,114,47,1,1, + 1,1,100,0,0,125,7,0,89,110,1,0,88,116,9,0, + 124,4,0,124,1,0,100,1,0,124,2,0,131,2,1,125, + 3,0,124,5,0,100,0,0,107,8,0,114,87,1,100,2, + 0,110,3,0,100,3,0,124,3,0,95,10,0,124,6,0, + 124,3,0,95,11,0,124,7,0,124,3,0,95,12,0,124, + 3,0,83,41,4,78,114,217,0,0,0,70,84,41,13,114, + 207,0,0,0,114,208,0,0,0,114,57,0,0,0,114,203, + 0,0,0,114,210,0,0,0,90,7,95,79,82,73,71,73, + 78,218,10,95,95,99,97,99,104,101,100,95,95,218,4,108, + 105,115,116,218,8,95,95,112,97,116,104,95,95,114,216,0, + 0,0,114,221,0,0,0,114,225,0,0,0,114,220,0,0, + 0,41,8,114,178,0,0,0,114,170,0,0,0,114,217,0, + 0,0,114,177,0,0,0,114,67,0,0,0,114,242,0,0, + 0,114,225,0,0,0,114,220,0,0,0,114,4,0,0,0, + 114,4,0,0,0,114,5,0,0,0,218,17,95,115,112,101, + 99,95,102,114,111,109,95,109,111,100,117,108,101,181,3,0, + 0,115,72,0,0,0,0,2,3,1,13,1,13,1,5,2, + 12,1,4,2,9,1,12,1,3,1,13,1,13,2,5,1, + 3,1,13,1,13,1,11,1,12,1,12,1,3,1,13,1, + 13,1,14,2,6,1,3,1,13,1,13,1,11,1,3,1, + 19,1,13,1,11,2,21,1,27,1,9,1,9,1,114,247, + 0,0,0,218,8,111,118,101,114,114,105,100,101,70,99,2, + 0,0,0,1,0,0,0,4,0,0,0,59,0,0,0,67, + 0,0,0,115,27,2,0,0,124,2,0,115,30,0,116,0, + 0,124,1,0,100,1,0,100,0,0,131,3,0,100,0,0, + 107,8,0,114,67,0,121,16,0,124,0,0,106,1,0,124, + 1,0,95,2,0,87,110,18,0,4,116,3,0,107,10,0, + 114,66,0,1,1,1,89,110,1,0,88,124,2,0,115,97, + 0,116,0,0,124,1,0,100,2,0,100,0,0,131,3,0, + 100,0,0,107,8,0,114,194,0,124,0,0,106,4,0,125, + 3,0,124,3,0,100,0,0,107,8,0,114,160,0,124,0, + 0,106,5,0,100,0,0,107,9,0,114,160,0,116,6,0, + 106,7,0,116,6,0,131,1,0,125,3,0,124,0,0,106, + 5,0,124,3,0,95,8,0,121,13,0,124,3,0,124,1, + 0,95,9,0,87,110,18,0,4,116,3,0,107,10,0,114, + 193,0,1,1,1,89,110,1,0,88,124,2,0,115,224,0, + 116,0,0,124,1,0,100,3,0,100,0,0,131,3,0,100, + 0,0,107,8,0,114,5,1,121,16,0,124,0,0,106,10, + 0,124,1,0,95,11,0,87,110,18,0,4,116,3,0,107, + 10,0,114,4,1,1,1,1,89,110,1,0,88,121,13,0, + 124,0,0,124,1,0,95,12,0,87,110,18,0,4,116,3, + 0,107,10,0,114,38,1,1,1,1,89,110,1,0,88,124, + 2,0,115,69,1,116,0,0,124,1,0,100,4,0,100,0, + 0,131,3,0,100,0,0,107,8,0,114,121,1,124,0,0, + 106,5,0,100,0,0,107,9,0,114,121,1,121,16,0,124, + 0,0,106,5,0,124,1,0,95,13,0,87,110,18,0,4, + 116,3,0,107,10,0,114,120,1,1,1,1,89,110,1,0, + 88,124,0,0,106,14,0,114,23,2,124,2,0,115,160,1, + 116,0,0,124,1,0,100,5,0,100,0,0,131,3,0,100, + 0,0,107,8,0,114,197,1,121,16,0,124,0,0,106,15, + 0,124,1,0,95,16,0,87,110,18,0,4,116,3,0,107, + 10,0,114,196,1,1,1,1,89,110,1,0,88,124,2,0, + 115,227,1,116,0,0,124,1,0,100,6,0,100,0,0,131, + 3,0,100,0,0,107,8,0,114,23,2,124,0,0,106,17, + 0,100,0,0,107,9,0,114,23,2,121,16,0,124,0,0, + 106,17,0,124,1,0,95,18,0,87,110,18,0,4,116,3, + 0,107,10,0,114,22,2,1,1,1,89,110,1,0,88,124, + 1,0,83,41,7,78,114,57,0,0,0,114,203,0,0,0, + 218,11,95,95,112,97,99,107,97,103,101,95,95,114,246,0, + 0,0,114,210,0,0,0,114,244,0,0,0,41,19,114,62, + 0,0,0,114,67,0,0,0,114,57,0,0,0,114,208,0, + 0,0,114,170,0,0,0,114,220,0,0,0,218,16,95,78, + 97,109,101,115,112,97,99,101,76,111,97,100,101,114,218,7, + 95,95,110,101,119,95,95,218,5,95,112,97,116,104,114,203, + 0,0,0,114,233,0,0,0,114,249,0,0,0,114,207,0, + 0,0,114,246,0,0,0,114,226,0,0,0,114,217,0,0, + 0,114,210,0,0,0,114,225,0,0,0,114,244,0,0,0, + 41,4,114,177,0,0,0,114,178,0,0,0,114,248,0,0, + 0,114,170,0,0,0,114,4,0,0,0,114,4,0,0,0, + 114,5,0,0,0,218,18,95,105,110,105,116,95,109,111,100, + 117,108,101,95,97,116,116,114,115,226,3,0,0,115,86,0, + 0,0,0,4,30,1,3,1,16,1,13,1,5,2,30,1, + 9,1,12,2,15,1,15,1,12,1,3,1,13,1,13,1, + 5,2,30,1,3,1,16,1,13,1,5,2,3,1,13,1, + 13,1,5,2,30,1,15,1,3,1,16,1,13,1,5,2, + 9,1,30,1,3,1,16,1,13,1,5,2,30,1,15,1, + 3,1,16,1,13,1,5,1,114,253,0,0,0,99,1,0, + 0,0,0,0,0,0,2,0,0,0,5,0,0,0,67,0, + 0,0,115,129,0,0,0,100,1,0,125,1,0,116,0,0, + 124,0,0,106,1,0,100,2,0,131,2,0,114,45,0,124, + 0,0,106,1,0,106,2,0,124,0,0,131,1,0,125,1, + 0,110,40,0,116,0,0,124,0,0,106,1,0,100,3,0, + 131,2,0,114,85,0,116,3,0,106,4,0,100,4,0,116, + 5,0,100,5,0,100,6,0,131,2,1,1,124,1,0,100, + 1,0,107,8,0,114,112,0,116,6,0,124,0,0,106,7, + 0,131,1,0,125,1,0,116,8,0,124,0,0,124,1,0, + 131,2,0,1,124,1,0,83,41,7,122,43,67,114,101,97, + 116,101,32,97,32,109,111,100,117,108,101,32,98,97,115,101, + 100,32,111,110,32,116,104,101,32,112,114,111,118,105,100,101, + 100,32,115,112,101,99,46,78,218,13,99,114,101,97,116,101, + 95,109,111,100,117,108,101,218,11,101,120,101,99,95,109,111, + 100,117,108,101,122,87,115,116,97,114,116,105,110,103,32,105, + 110,32,80,121,116,104,111,110,32,51,46,54,44,32,108,111, + 97,100,101,114,115,32,100,101,102,105,110,105,110,103,32,101, + 120,101,99,95,109,111,100,117,108,101,40,41,32,109,117,115, + 116,32,97,108,115,111,32,100,101,102,105,110,101,32,99,114, + 101,97,116,101,95,109,111,100,117,108,101,40,41,90,10,115, + 116,97,99,107,108,101,118,101,108,114,115,0,0,0,41,9, + 114,60,0,0,0,114,170,0,0,0,114,254,0,0,0,114, + 167,0,0,0,114,168,0,0,0,218,18,68,101,112,114,101, + 99,97,116,105,111,110,87,97,114,110,105,110,103,114,68,0, + 0,0,114,67,0,0,0,114,253,0,0,0,41,2,114,177, + 0,0,0,114,178,0,0,0,114,4,0,0,0,114,4,0, + 0,0,114,5,0,0,0,218,16,109,111,100,117,108,101,95, + 102,114,111,109,95,115,112,101,99,26,4,0,0,115,20,0, + 0,0,0,3,6,1,18,3,21,1,18,1,9,2,13,1, + 12,1,15,1,13,1,114,1,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,149,0,0,0,124,0,0,106,0,0,100,1,0,107,8, + 0,114,21,0,100,2,0,110,6,0,124,0,0,106,0,0, + 125,1,0,124,0,0,106,1,0,100,1,0,107,8,0,114, + 95,0,124,0,0,106,2,0,100,1,0,107,8,0,114,73, + 0,100,3,0,106,3,0,124,1,0,131,1,0,83,100,4, + 0,106,3,0,124,1,0,124,0,0,106,2,0,131,2,0, + 83,110,50,0,124,0,0,106,4,0,114,123,0,100,5,0, + 106,3,0,124,1,0,124,0,0,106,1,0,131,2,0,83, + 100,6,0,106,3,0,124,0,0,106,0,0,124,0,0,106, + 1,0,131,2,0,83,100,1,0,83,41,7,122,38,82,101, + 116,117,114,110,32,116,104,101,32,114,101,112,114,32,116,111, + 32,117,115,101,32,102,111,114,32,116,104,101,32,109,111,100, + 117,108,101,46,78,114,205,0,0,0,122,13,60,109,111,100, + 117,108,101,32,123,33,114,125,62,122,20,60,109,111,100,117, + 108,101,32,123,33,114,125,32,40,123,33,114,125,41,62,122, + 23,60,109,111,100,117,108,101,32,123,33,114,125,32,102,114, + 111,109,32,123,33,114,125,62,122,18,60,109,111,100,117,108, + 101,32,123,33,114,125,32,40,123,125,41,62,41,5,114,67, + 0,0,0,114,217,0,0,0,114,170,0,0,0,114,47,0, + 0,0,114,226,0,0,0,41,2,114,177,0,0,0,114,67, + 0,0,0,114,4,0,0,0,114,4,0,0,0,114,5,0, + 0,0,114,209,0,0,0,44,4,0,0,115,16,0,0,0, + 0,3,30,1,15,1,15,1,13,2,22,2,9,1,19,2, + 114,209,0,0,0,99,2,0,0,0,0,0,0,0,4,0, + 0,0,12,0,0,0,67,0,0,0,115,252,0,0,0,124, + 0,0,106,0,0,125,2,0,116,1,0,106,2,0,131,0, + 0,1,116,3,0,124,2,0,131,1,0,143,208,0,1,116, + 4,0,106,5,0,106,6,0,124,2,0,131,1,0,124,1, + 0,107,9,0,114,89,0,100,1,0,106,7,0,124,2,0, + 131,1,0,125,3,0,116,8,0,124,3,0,100,2,0,124, + 2,0,131,1,1,130,1,0,124,0,0,106,9,0,100,3, + 0,107,8,0,114,163,0,124,0,0,106,10,0,100,3,0, + 107,8,0,114,140,0,116,8,0,100,4,0,100,2,0,124, + 0,0,106,0,0,131,1,1,130,1,0,116,11,0,124,0, + 0,124,1,0,100,5,0,100,6,0,131,2,1,1,124,1, + 0,83,116,11,0,124,0,0,124,1,0,100,5,0,100,6, + 0,131,2,1,1,116,12,0,124,0,0,106,9,0,100,7, + 0,131,2,0,115,219,0,124,0,0,106,9,0,106,13,0, + 124,2,0,131,1,0,1,110,16,0,124,0,0,106,9,0, + 106,14,0,124,1,0,131,1,0,1,87,100,3,0,81,88, + 116,4,0,106,5,0,124,2,0,25,83,41,8,122,51,69, + 120,101,99,117,116,101,32,116,104,101,32,115,112,101,99,32, + 105,110,32,97,110,32,101,120,105,115,116,105,110,103,32,109, + 111,100,117,108,101,39,115,32,110,97,109,101,115,112,97,99, + 101,46,122,30,109,111,100,117,108,101,32,123,33,114,125,32, + 110,111,116,32,105,110,32,115,121,115,46,109,111,100,117,108, + 101,115,114,67,0,0,0,78,122,14,109,105,115,115,105,110, + 103,32,108,111,97,100,101,114,114,248,0,0,0,84,114,255, + 0,0,0,41,15,114,67,0,0,0,114,106,0,0,0,218, + 12,97,99,113,117,105,114,101,95,108,111,99,107,114,103,0, + 0,0,114,7,0,0,0,114,73,0,0,0,114,93,0,0, + 0,114,47,0,0,0,114,154,0,0,0,114,170,0,0,0, + 114,220,0,0,0,114,253,0,0,0,114,60,0,0,0,218, + 11,108,111,97,100,95,109,111,100,117,108,101,114,255,0,0, + 0,41,4,114,177,0,0,0,114,178,0,0,0,114,67,0, + 0,0,114,172,0,0,0,114,4,0,0,0,114,4,0,0, + 0,114,5,0,0,0,114,175,0,0,0,61,4,0,0,115, + 32,0,0,0,0,2,9,1,10,1,13,1,24,1,15,1, + 18,1,15,1,15,1,21,2,19,1,4,1,19,1,18,4, + 19,2,22,1,114,175,0,0,0,99,1,0,0,0,0,0, + 0,0,2,0,0,0,27,0,0,0,67,0,0,0,115,3, + 1,0,0,124,0,0,106,0,0,106,1,0,124,0,0,106, + 2,0,131,1,0,1,116,3,0,106,4,0,124,0,0,106, + 2,0,25,125,1,0,116,5,0,124,1,0,100,1,0,100, + 0,0,131,3,0,100,0,0,107,8,0,114,96,0,121,16, + 0,124,0,0,106,0,0,124,1,0,95,6,0,87,110,18, + 0,4,116,7,0,107,10,0,114,95,0,1,1,1,89,110, + 1,0,88,116,5,0,124,1,0,100,2,0,100,0,0,131, + 3,0,100,0,0,107,8,0,114,197,0,121,56,0,124,1, + 0,106,8,0,124,1,0,95,9,0,116,10,0,124,1,0, + 100,3,0,131,2,0,115,175,0,124,0,0,106,2,0,106, + 11,0,100,4,0,131,1,0,100,5,0,25,124,1,0,95, + 9,0,87,110,18,0,4,116,7,0,107,10,0,114,196,0, + 1,1,1,89,110,1,0,88,116,5,0,124,1,0,100,6, + 0,100,0,0,131,3,0,100,0,0,107,8,0,114,255,0, + 121,13,0,124,0,0,124,1,0,95,12,0,87,110,18,0, + 4,116,7,0,107,10,0,114,254,0,1,1,1,89,110,1, + 0,88,124,1,0,83,41,7,78,114,203,0,0,0,114,249, + 0,0,0,114,246,0,0,0,114,116,0,0,0,114,84,0, + 0,0,114,207,0,0,0,41,13,114,170,0,0,0,114,3, 1,0,0,114,67,0,0,0,114,7,0,0,0,114,73,0, - 0,0,114,62,0,0,0,114,204,0,0,0,114,209,0,0, + 0,0,114,62,0,0,0,114,203,0,0,0,114,208,0,0, 0,114,57,0,0,0,114,249,0,0,0,114,60,0,0,0, - 114,32,0,0,0,114,208,0,0,0,41,3,114,71,0,0, - 0,114,177,0,0,0,114,179,0,0,0,114,4,0,0,0, - 114,4,0,0,0,114,5,0,0,0,218,25,95,108,111,97, - 100,95,98,97,99,107,119,97,114,100,95,99,111,109,112,97, - 116,105,98,108,101,130,4,0,0,115,42,0,0,0,0,2, - 9,2,19,1,16,1,24,1,3,1,16,1,13,1,8,1, - 24,1,3,4,12,1,15,1,32,1,13,1,8,1,24,1, - 3,1,13,1,13,1,8,1,122,38,95,83,112,101,99,77, - 101,116,104,111,100,115,46,95,108,111,97,100,95,98,97,99, + 114,32,0,0,0,114,207,0,0,0,41,2,114,177,0,0, + 0,114,178,0,0,0,114,4,0,0,0,114,4,0,0,0, + 114,5,0,0,0,218,25,95,108,111,97,100,95,98,97,99, 107,119,97,114,100,95,99,111,109,112,97,116,105,98,108,101, - 99,2,0,0,0,0,0,0,0,3,0,0,0,9,0,0, - 0,67,0,0,0,115,38,0,0,0,116,0,0,124,1,0, - 131,1,0,143,20,0,1,124,0,0,106,1,0,124,1,0, - 131,1,0,125,2,0,87,100,1,0,81,88,124,2,0,83, - 41,2,122,60,69,120,101,99,32,116,104,101,32,115,112,101, - 99,39,101,100,32,109,111,100,117,108,101,32,105,110,116,111, - 32,97,110,32,101,120,105,115,116,105,110,103,32,109,111,100, - 117,108,101,39,115,32,110,97,109,101,115,112,97,99,101,46, - 78,41,2,114,212,0,0,0,114,175,0,0,0,41,3,114, - 71,0,0,0,114,179,0,0,0,90,6,108,111,97,100,101, - 100,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, - 218,14,95,108,111,97,100,95,101,120,105,115,116,105,110,103, - 160,4,0,0,115,6,0,0,0,0,3,13,1,21,1,122, - 27,95,83,112,101,99,77,101,116,104,111,100,115,46,95,108, - 111,97,100,95,101,120,105,115,116,105,110,103,99,1,0,0, - 0,0,0,0,0,2,0,0,0,11,0,0,0,67,0,0, - 0,115,179,0,0,0,124,0,0,106,0,0,106,1,0,100, - 0,0,107,9,0,114,52,0,116,2,0,124,0,0,106,0, - 0,106,1,0,100,1,0,131,2,0,115,52,0,124,0,0, - 106,3,0,131,0,0,83,110,0,0,124,0,0,106,4,0, - 131,0,0,125,1,0,116,5,0,124,1,0,131,1,0,143, - 84,0,1,124,0,0,106,0,0,106,1,0,100,0,0,107, - 8,0,114,143,0,124,0,0,106,0,0,106,6,0,100,0, - 0,107,8,0,114,156,0,116,7,0,100,2,0,100,3,0, - 124,0,0,106,0,0,106,8,0,131,1,1,130,1,0,113, - 156,0,110,13,0,124,0,0,106,9,0,124,1,0,131,1, - 0,1,87,100,0,0,81,88,116,10,0,106,11,0,124,0, - 0,106,0,0,106,8,0,25,83,41,4,78,114,0,1,0, - 0,122,14,109,105,115,115,105,110,103,32,108,111,97,100,101, - 114,114,67,0,0,0,41,12,114,177,0,0,0,114,169,0, - 0,0,114,60,0,0,0,114,4,1,0,0,114,255,0,0, - 0,114,212,0,0,0,114,220,0,0,0,114,153,0,0,0, - 114,67,0,0,0,114,1,1,0,0,114,7,0,0,0,114, - 73,0,0,0,41,2,114,71,0,0,0,114,179,0,0,0, + 86,4,0,0,115,40,0,0,0,0,4,19,2,16,1,24, + 1,3,1,16,1,13,1,5,1,24,1,3,4,12,1,15, + 1,29,1,13,1,5,1,24,1,3,1,13,1,13,1,5, + 1,114,4,1,0,0,99,1,0,0,0,0,0,0,0,2, + 0,0,0,11,0,0,0,67,0,0,0,115,158,0,0,0, + 124,0,0,106,0,0,100,0,0,107,9,0,114,43,0,116, + 1,0,124,0,0,106,0,0,100,1,0,131,2,0,115,43, + 0,116,2,0,124,0,0,131,1,0,83,116,3,0,124,0, + 0,131,1,0,125,1,0,116,4,0,124,1,0,131,1,0, + 143,75,0,1,124,0,0,106,0,0,100,0,0,107,8,0, + 114,122,0,124,0,0,106,5,0,100,0,0,107,8,0,114, + 138,0,116,6,0,100,2,0,100,3,0,124,0,0,106,7, + 0,131,1,1,130,1,0,110,16,0,124,0,0,106,0,0, + 106,8,0,124,1,0,131,1,0,1,87,100,0,0,81,88, + 116,9,0,106,10,0,124,0,0,106,7,0,25,83,41,4, + 78,114,255,0,0,0,122,14,109,105,115,115,105,110,103,32, + 108,111,97,100,101,114,114,67,0,0,0,41,11,114,170,0, + 0,0,114,60,0,0,0,114,4,1,0,0,114,1,1,0, + 0,114,212,0,0,0,114,220,0,0,0,114,154,0,0,0, + 114,67,0,0,0,114,255,0,0,0,114,7,0,0,0,114, + 73,0,0,0,41,2,114,177,0,0,0,114,178,0,0,0, 114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,218, - 14,95,108,111,97,100,95,117,110,108,111,99,107,101,100,167, - 4,0,0,115,20,0,0,0,0,2,18,2,21,1,13,2, - 12,1,13,1,18,1,18,1,30,3,19,5,122,27,95,83, - 112,101,99,77,101,116,104,111,100,115,46,95,108,111,97,100, - 95,117,110,108,111,99,107,101,100,99,1,0,0,0,0,0, - 0,0,1,0,0,0,8,0,0,0,67,0,0,0,115,49, - 0,0,0,116,0,0,106,1,0,131,0,0,1,116,2,0, - 124,0,0,106,3,0,106,4,0,131,1,0,143,15,0,1, - 124,0,0,106,5,0,131,0,0,83,87,100,1,0,81,88, - 100,1,0,83,41,2,122,207,82,101,116,117,114,110,32,97, - 32,110,101,119,32,109,111,100,117,108,101,32,111,98,106,101, - 99,116,44,32,108,111,97,100,101,100,32,98,121,32,116,104, - 101,32,115,112,101,99,39,115,32,108,111,97,100,101,114,46, - 10,10,32,32,32,32,32,32,32,32,84,104,101,32,109,111, - 100,117,108,101,32,105,115,32,110,111,116,32,97,100,100,101, - 100,32,116,111,32,105,116,115,32,112,97,114,101,110,116,46, - 10,10,32,32,32,32,32,32,32,32,73,102,32,97,32,109, - 111,100,117,108,101,32,105,115,32,97,108,114,101,97,100,121, - 32,105,110,32,115,121,115,46,109,111,100,117,108,101,115,44, - 32,116,104,97,116,32,101,120,105,115,116,105,110,103,32,109, - 111,100,117,108,101,32,103,101,116,115,10,32,32,32,32,32, - 32,32,32,99,108,111,98,98,101,114,101,100,46,10,10,32, - 32,32,32,32,32,32,32,78,41,6,114,106,0,0,0,114, - 2,1,0,0,114,103,0,0,0,114,177,0,0,0,114,67, - 0,0,0,114,6,1,0,0,41,1,114,71,0,0,0,114, + 14,95,108,111,97,100,95,117,110,108,111,99,107,101,100,115, + 4,0,0,115,20,0,0,0,0,2,15,2,18,1,10,2, + 12,1,13,1,15,1,15,1,24,3,22,5,114,5,1,0, + 0,99,1,0,0,0,0,0,0,0,1,0,0,0,9,0, + 0,0,67,0,0,0,115,46,0,0,0,116,0,0,106,1, + 0,131,0,0,1,116,2,0,124,0,0,106,3,0,131,1, + 0,143,15,0,1,116,4,0,124,0,0,131,1,0,83,87, + 100,1,0,81,88,100,1,0,83,41,2,122,191,82,101,116, + 117,114,110,32,97,32,110,101,119,32,109,111,100,117,108,101, + 32,111,98,106,101,99,116,44,32,108,111,97,100,101,100,32, + 98,121,32,116,104,101,32,115,112,101,99,39,115,32,108,111, + 97,100,101,114,46,10,10,32,32,32,32,84,104,101,32,109, + 111,100,117,108,101,32,105,115,32,110,111,116,32,97,100,100, + 101,100,32,116,111,32,105,116,115,32,112,97,114,101,110,116, + 46,10,10,32,32,32,32,73,102,32,97,32,109,111,100,117, + 108,101,32,105,115,32,97,108,114,101,97,100,121,32,105,110, + 32,115,121,115,46,109,111,100,117,108,101,115,44,32,116,104, + 97,116,32,101,120,105,115,116,105,110,103,32,109,111,100,117, + 108,101,32,103,101,116,115,10,32,32,32,32,99,108,111,98, + 98,101,114,101,100,46,10,10,32,32,32,32,78,41,5,114, + 106,0,0,0,114,2,1,0,0,114,103,0,0,0,114,67, + 0,0,0,114,5,1,0,0,41,1,114,177,0,0,0,114, 4,0,0,0,114,4,0,0,0,114,5,0,0,0,114,176, - 0,0,0,190,4,0,0,115,6,0,0,0,0,9,10,1, - 19,1,122,17,95,83,112,101,99,77,101,116,104,111,100,115, - 46,108,111,97,100,78,41,16,114,57,0,0,0,114,56,0, - 0,0,114,58,0,0,0,114,59,0,0,0,114,72,0,0, - 0,218,11,99,108,97,115,115,109,101,116,104,111,100,114,246, - 0,0,0,114,205,0,0,0,114,253,0,0,0,114,255,0, - 0,0,114,1,1,0,0,114,175,0,0,0,114,4,1,0, - 0,114,5,1,0,0,114,6,1,0,0,114,176,0,0,0, - 114,4,0,0,0,114,4,0,0,0,114,4,0,0,0,114, - 5,0,0,0,114,174,0,0,0,211,3,0,0,115,24,0, - 0,0,12,3,6,2,12,3,18,16,12,16,24,80,12,23, - 12,10,12,22,12,30,12,7,12,23,114,174,0,0,0,99, - 0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0, - 64,0,0,0,115,181,0,0,0,101,0,0,90,1,0,100, - 0,0,90,2,0,100,1,0,90,3,0,101,4,0,100,2, - 0,100,3,0,132,0,0,131,1,0,90,5,0,101,6,0, - 100,4,0,100,4,0,100,5,0,100,6,0,132,2,0,131, - 1,0,90,7,0,101,6,0,100,4,0,100,7,0,100,8, - 0,132,1,0,131,1,0,90,8,0,101,6,0,101,9,0, - 100,9,0,100,10,0,132,0,0,131,1,0,131,1,0,90, - 10,0,101,6,0,101,9,0,100,11,0,100,12,0,132,0, - 0,131,1,0,131,1,0,90,11,0,101,6,0,101,9,0, - 100,13,0,100,14,0,132,0,0,131,1,0,131,1,0,90, - 12,0,101,6,0,101,9,0,100,15,0,100,16,0,132,0, - 0,131,1,0,131,1,0,90,13,0,100,4,0,83,41,17, - 218,15,66,117,105,108,116,105,110,73,109,112,111,114,116,101, - 114,122,144,77,101,116,97,32,112,97,116,104,32,105,109,112, - 111,114,116,32,102,111,114,32,98,117,105,108,116,45,105,110, - 32,109,111,100,117,108,101,115,46,10,10,32,32,32,32,65, - 108,108,32,109,101,116,104,111,100,115,32,97,114,101,32,101, - 105,116,104,101,114,32,99,108,97,115,115,32,111,114,32,115, - 116,97,116,105,99,32,109,101,116,104,111,100,115,32,116,111, - 32,97,118,111,105,100,32,116,104,101,32,110,101,101,100,32, - 116,111,10,32,32,32,32,105,110,115,116,97,110,116,105,97, - 116,101,32,116,104,101,32,99,108,97,115,115,46,10,10,32, - 32,32,32,99,1,0,0,0,0,0,0,0,1,0,0,0, - 2,0,0,0,67,0,0,0,115,16,0,0,0,100,1,0, - 106,0,0,124,0,0,106,1,0,131,1,0,83,41,2,78, - 122,24,60,109,111,100,117,108,101,32,123,33,114,125,32,40, - 98,117,105,108,116,45,105,110,41,62,41,2,114,47,0,0, - 0,114,57,0,0,0,41,1,114,179,0,0,0,114,4,0, - 0,0,114,4,0,0,0,114,5,0,0,0,114,205,0,0, - 0,215,4,0,0,115,2,0,0,0,0,3,122,27,66,117, - 105,108,116,105,110,73,109,112,111,114,116,101,114,46,109,111, - 100,117,108,101,95,114,101,112,114,78,99,4,0,0,0,0, - 0,0,0,4,0,0,0,5,0,0,0,67,0,0,0,115, - 58,0,0,0,124,2,0,100,0,0,107,9,0,114,16,0, - 100,0,0,83,116,0,0,106,1,0,124,1,0,131,1,0, - 114,50,0,116,2,0,124,1,0,124,0,0,100,1,0,100, - 2,0,131,2,1,83,100,0,0,83,100,0,0,83,41,3, - 78,114,217,0,0,0,122,8,98,117,105,108,116,45,105,110, - 41,3,114,106,0,0,0,90,10,105,115,95,98,117,105,108, - 116,105,110,114,173,0,0,0,41,4,114,245,0,0,0,114, - 158,0,0,0,114,35,0,0,0,218,6,116,97,114,103,101, - 116,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, - 218,9,102,105,110,100,95,115,112,101,99,220,4,0,0,115, - 10,0,0,0,0,2,12,1,4,1,15,1,19,2,122,25, - 66,117,105,108,116,105,110,73,109,112,111,114,116,101,114,46, - 102,105,110,100,95,115,112,101,99,99,3,0,0,0,0,0, - 0,0,4,0,0,0,3,0,0,0,67,0,0,0,115,41, - 0,0,0,124,0,0,106,0,0,124,1,0,124,2,0,131, - 2,0,125,3,0,124,3,0,100,1,0,107,9,0,114,37, - 0,124,3,0,106,1,0,83,100,1,0,83,41,2,122,113, - 70,105,110,100,32,116,104,101,32,98,117,105,108,116,45,105, - 110,32,109,111,100,117,108,101,46,10,10,32,32,32,32,32, - 32,32,32,73,102,32,39,112,97,116,104,39,32,105,115,32, - 101,118,101,114,32,115,112,101,99,105,102,105,101,100,32,116, - 104,101,110,32,116,104,101,32,115,101,97,114,99,104,32,105, - 115,32,99,111,110,115,105,100,101,114,101,100,32,97,32,102, - 97,105,108,117,114,101,46,10,10,32,32,32,32,32,32,32, - 32,78,41,2,114,10,1,0,0,114,169,0,0,0,41,4, - 114,245,0,0,0,114,158,0,0,0,114,35,0,0,0,114, - 177,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5, - 0,0,0,218,11,102,105,110,100,95,109,111,100,117,108,101, - 229,4,0,0,115,4,0,0,0,0,7,18,1,122,27,66, - 117,105,108,116,105,110,73,109,112,111,114,116,101,114,46,102, - 105,110,100,95,109,111,100,117,108,101,99,2,0,0,0,0, - 0,0,0,3,0,0,0,10,0,0,0,67,0,0,0,115, - 59,0,0,0,116,0,0,124,1,0,131,1,0,143,23,0, - 1,116,1,0,116,2,0,106,3,0,124,1,0,131,2,0, - 125,2,0,87,100,1,0,81,88,124,0,0,124,2,0,95, - 4,0,100,2,0,124,2,0,95,5,0,124,2,0,83,41, - 3,122,23,76,111,97,100,32,97,32,98,117,105,108,116,45, - 105,110,32,109,111,100,117,108,101,46,78,114,30,0,0,0, - 41,6,114,69,0,0,0,114,114,0,0,0,114,106,0,0, - 0,90,12,105,110,105,116,95,98,117,105,108,116,105,110,114, - 204,0,0,0,114,249,0,0,0,41,3,114,245,0,0,0, - 114,158,0,0,0,114,179,0,0,0,114,4,0,0,0,114, - 4,0,0,0,114,5,0,0,0,114,3,1,0,0,239,4, - 0,0,115,10,0,0,0,0,4,13,1,24,1,9,1,9, - 1,122,27,66,117,105,108,116,105,110,73,109,112,111,114,116, - 101,114,46,108,111,97,100,95,109,111,100,117,108,101,99,2, - 0,0,0,0,0,0,0,2,0,0,0,1,0,0,0,67, - 0,0,0,115,4,0,0,0,100,1,0,83,41,2,122,57, - 82,101,116,117,114,110,32,78,111,110,101,32,97,115,32,98, - 117,105,108,116,45,105,110,32,109,111,100,117,108,101,115,32, - 100,111,32,110,111,116,32,104,97,118,101,32,99,111,100,101, - 32,111,98,106,101,99,116,115,46,78,114,4,0,0,0,41, - 2,114,245,0,0,0,114,158,0,0,0,114,4,0,0,0, - 114,4,0,0,0,114,5,0,0,0,218,8,103,101,116,95, - 99,111,100,101,249,4,0,0,115,2,0,0,0,0,4,122, - 24,66,117,105,108,116,105,110,73,109,112,111,114,116,101,114, - 46,103,101,116,95,99,111,100,101,99,2,0,0,0,0,0, - 0,0,2,0,0,0,1,0,0,0,67,0,0,0,115,4, - 0,0,0,100,1,0,83,41,2,122,56,82,101,116,117,114, - 110,32,78,111,110,101,32,97,115,32,98,117,105,108,116,45, - 105,110,32,109,111,100,117,108,101,115,32,100,111,32,110,111, - 116,32,104,97,118,101,32,115,111,117,114,99,101,32,99,111, - 100,101,46,78,114,4,0,0,0,41,2,114,245,0,0,0, - 114,158,0,0,0,114,4,0,0,0,114,4,0,0,0,114, - 5,0,0,0,218,10,103,101,116,95,115,111,117,114,99,101, - 255,4,0,0,115,2,0,0,0,0,4,122,26,66,117,105, - 108,116,105,110,73,109,112,111,114,116,101,114,46,103,101,116, - 95,115,111,117,114,99,101,99,2,0,0,0,0,0,0,0, - 2,0,0,0,1,0,0,0,67,0,0,0,115,4,0,0, - 0,100,1,0,83,41,2,122,52,82,101,116,117,114,110,32, - 70,97,108,115,101,32,97,115,32,98,117,105,108,116,45,105, - 110,32,109,111,100,117,108,101,115,32,97,114,101,32,110,101, - 118,101,114,32,112,97,99,107,97,103,101,115,46,70,114,4, - 0,0,0,41,2,114,245,0,0,0,114,158,0,0,0,114, - 4,0,0,0,114,4,0,0,0,114,5,0,0,0,114,219, - 0,0,0,5,5,0,0,115,2,0,0,0,0,5,122,26, - 66,117,105,108,116,105,110,73,109,112,111,114,116,101,114,46, - 105,115,95,112,97,99,107,97,103,101,41,14,114,57,0,0, - 0,114,56,0,0,0,114,58,0,0,0,114,59,0,0,0, - 218,12,115,116,97,116,105,99,109,101,116,104,111,100,114,205, - 0,0,0,114,7,1,0,0,114,10,1,0,0,114,11,1, - 0,0,114,161,0,0,0,114,3,1,0,0,114,12,1,0, - 0,114,13,1,0,0,114,219,0,0,0,114,4,0,0,0, - 114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,114, - 8,1,0,0,206,4,0,0,115,28,0,0,0,12,7,6, - 2,18,5,3,1,21,8,3,1,18,9,3,1,21,9,3, - 1,21,5,3,1,21,5,3,1,114,8,1,0,0,99,0, - 0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,64, - 0,0,0,115,193,0,0,0,101,0,0,90,1,0,100,0, - 0,90,2,0,100,1,0,90,3,0,101,4,0,100,2,0, - 100,3,0,132,0,0,131,1,0,90,5,0,101,6,0,100, - 4,0,100,4,0,100,5,0,100,6,0,132,2,0,131,1, - 0,90,7,0,101,6,0,100,4,0,100,7,0,100,8,0, - 132,1,0,131,1,0,90,8,0,101,4,0,100,9,0,100, - 10,0,132,0,0,131,1,0,90,9,0,101,6,0,100,11, - 0,100,12,0,132,0,0,131,1,0,90,10,0,101,6,0, - 101,11,0,100,13,0,100,14,0,132,0,0,131,1,0,131, - 1,0,90,12,0,101,6,0,101,11,0,100,15,0,100,16, - 0,132,0,0,131,1,0,131,1,0,90,13,0,101,6,0, - 101,11,0,100,17,0,100,18,0,132,0,0,131,1,0,131, - 1,0,90,14,0,100,4,0,83,41,19,218,14,70,114,111, - 122,101,110,73,109,112,111,114,116,101,114,122,142,77,101,116, - 97,32,112,97,116,104,32,105,109,112,111,114,116,32,102,111, - 114,32,102,114,111,122,101,110,32,109,111,100,117,108,101,115, + 0,0,0,138,4,0,0,115,6,0,0,0,0,9,10,1, + 16,1,114,176,0,0,0,99,4,0,0,0,0,0,0,0, + 6,0,0,0,11,0,0,0,67,0,0,0,115,195,0,0, + 0,124,0,0,106,0,0,100,1,0,131,1,0,125,4,0, + 124,0,0,106,0,0,100,2,0,131,1,0,125,5,0,124, + 4,0,115,99,0,124,5,0,114,54,0,124,5,0,106,1, + 0,125,4,0,110,45,0,124,2,0,124,3,0,107,2,0, + 114,84,0,116,2,0,124,1,0,124,2,0,131,2,0,125, + 4,0,110,15,0,116,3,0,124,1,0,124,2,0,131,2, + 0,125,4,0,124,5,0,115,126,0,116,4,0,124,1,0, + 124,2,0,100,3,0,124,4,0,131,2,1,125,5,0,121, + 44,0,124,5,0,124,0,0,100,2,0,60,124,4,0,124, + 0,0,100,1,0,60,124,2,0,124,0,0,100,4,0,60, + 124,3,0,124,0,0,100,5,0,60,87,110,18,0,4,116, + 5,0,107,10,0,114,190,0,1,1,1,89,110,1,0,88, + 100,0,0,83,41,6,78,114,203,0,0,0,114,207,0,0, + 0,114,170,0,0,0,114,210,0,0,0,114,244,0,0,0, + 41,6,114,93,0,0,0,114,170,0,0,0,218,20,83,111, + 117,114,99,101,108,101,115,115,70,105,108,101,76,111,97,100, + 101,114,218,16,83,111,117,114,99,101,70,105,108,101,76,111, + 97,100,101,114,114,239,0,0,0,114,206,0,0,0,41,6, + 90,2,110,115,114,67,0,0,0,90,8,112,97,116,104,110, + 97,109,101,90,9,99,112,97,116,104,110,97,109,101,114,170, + 0,0,0,114,177,0,0,0,114,4,0,0,0,114,4,0, + 0,0,114,5,0,0,0,218,14,95,102,105,120,95,117,112, + 95,109,111,100,117,108,101,152,4,0,0,115,34,0,0,0, + 0,2,15,1,15,1,6,1,6,1,12,1,12,1,18,2, + 15,1,6,1,21,1,3,1,10,1,10,1,10,1,14,1, + 13,2,114,8,1,0,0,99,0,0,0,0,0,0,0,0, + 0,0,0,0,5,0,0,0,64,0,0,0,115,181,0,0, + 0,101,0,0,90,1,0,100,0,0,90,2,0,100,1,0, + 90,3,0,101,4,0,100,2,0,100,3,0,132,0,0,131, + 1,0,90,5,0,101,6,0,100,4,0,100,4,0,100,5, + 0,100,6,0,132,2,0,131,1,0,90,7,0,101,6,0, + 100,4,0,100,7,0,100,8,0,132,1,0,131,1,0,90, + 8,0,101,6,0,101,9,0,100,9,0,100,10,0,132,0, + 0,131,1,0,131,1,0,90,10,0,101,6,0,101,9,0, + 100,11,0,100,12,0,132,0,0,131,1,0,131,1,0,90, + 11,0,101,6,0,101,9,0,100,13,0,100,14,0,132,0, + 0,131,1,0,131,1,0,90,12,0,101,6,0,101,9,0, + 100,15,0,100,16,0,132,0,0,131,1,0,131,1,0,90, + 13,0,100,4,0,83,41,17,218,15,66,117,105,108,116,105, + 110,73,109,112,111,114,116,101,114,122,144,77,101,116,97,32, + 112,97,116,104,32,105,109,112,111,114,116,32,102,111,114,32, + 98,117,105,108,116,45,105,110,32,109,111,100,117,108,101,115, 46,10,10,32,32,32,32,65,108,108,32,109,101,116,104,111, 100,115,32,97,114,101,32,101,105,116,104,101,114,32,99,108, 97,115,115,32,111,114,32,115,116,97,116,105,99,32,109,101, @@ -2181,691 +1956,890 @@ const unsigned char _Py_M__importlib[] = { 108,97,115,115,46,10,10,32,32,32,32,99,1,0,0,0, 0,0,0,0,1,0,0,0,2,0,0,0,67,0,0,0, 115,16,0,0,0,100,1,0,106,0,0,124,0,0,106,1, - 0,131,1,0,83,41,2,78,122,22,60,109,111,100,117,108, - 101,32,123,33,114,125,32,40,102,114,111,122,101,110,41,62, - 41,2,114,47,0,0,0,114,57,0,0,0,41,1,218,1, - 109,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, - 114,205,0,0,0,22,5,0,0,115,2,0,0,0,0,3, - 122,26,70,114,111,122,101,110,73,109,112,111,114,116,101,114, - 46,109,111,100,117,108,101,95,114,101,112,114,78,99,4,0, - 0,0,0,0,0,0,4,0,0,0,5,0,0,0,67,0, - 0,0,115,42,0,0,0,116,0,0,106,1,0,124,1,0, - 131,1,0,114,34,0,116,2,0,124,1,0,124,0,0,100, - 1,0,100,2,0,131,2,1,83,100,0,0,83,100,0,0, - 83,41,3,78,114,217,0,0,0,90,6,102,114,111,122,101, - 110,41,3,114,106,0,0,0,114,162,0,0,0,114,173,0, - 0,0,41,4,114,245,0,0,0,114,158,0,0,0,114,35, - 0,0,0,114,9,1,0,0,114,4,0,0,0,114,4,0, - 0,0,114,5,0,0,0,114,10,1,0,0,27,5,0,0, - 115,6,0,0,0,0,2,15,1,19,2,122,24,70,114,111, - 122,101,110,73,109,112,111,114,116,101,114,46,102,105,110,100, - 95,115,112,101,99,99,3,0,0,0,0,0,0,0,3,0, - 0,0,2,0,0,0,67,0,0,0,115,23,0,0,0,116, - 0,0,106,1,0,124,1,0,131,1,0,114,19,0,124,0, - 0,83,100,1,0,83,41,2,122,21,70,105,110,100,32,97, - 32,102,114,111,122,101,110,32,109,111,100,117,108,101,46,78, - 41,2,114,106,0,0,0,114,162,0,0,0,41,3,114,245, - 0,0,0,114,158,0,0,0,114,35,0,0,0,114,4,0, - 0,0,114,4,0,0,0,114,5,0,0,0,114,11,1,0, - 0,34,5,0,0,115,2,0,0,0,0,3,122,26,70,114, + 0,131,1,0,83,41,2,122,115,82,101,116,117,114,110,32, + 114,101,112,114,32,102,111,114,32,116,104,101,32,109,111,100, + 117,108,101,46,10,10,32,32,32,32,32,32,32,32,84,104, + 101,32,109,101,116,104,111,100,32,105,115,32,100,101,112,114, + 101,99,97,116,101,100,46,32,32,84,104,101,32,105,109,112, + 111,114,116,32,109,97,99,104,105,110,101,114,121,32,100,111, + 101,115,32,116,104,101,32,106,111,98,32,105,116,115,101,108, + 102,46,10,10,32,32,32,32,32,32,32,32,122,24,60,109, + 111,100,117,108,101,32,123,33,114,125,32,40,98,117,105,108, + 116,45,105,110,41,62,41,2,114,47,0,0,0,114,57,0, + 0,0,41,1,114,178,0,0,0,114,4,0,0,0,114,4, + 0,0,0,114,5,0,0,0,114,204,0,0,0,186,4,0, + 0,115,2,0,0,0,0,7,122,27,66,117,105,108,116,105, + 110,73,109,112,111,114,116,101,114,46,109,111,100,117,108,101, + 95,114,101,112,114,78,99,4,0,0,0,0,0,0,0,4, + 0,0,0,5,0,0,0,67,0,0,0,115,58,0,0,0, + 124,2,0,100,0,0,107,9,0,114,16,0,100,0,0,83, + 116,0,0,106,1,0,124,1,0,131,1,0,114,50,0,116, + 2,0,124,1,0,124,0,0,100,1,0,100,2,0,131,2, + 1,83,100,0,0,83,100,0,0,83,41,3,78,114,217,0, + 0,0,122,8,98,117,105,108,116,45,105,110,41,3,114,106, + 0,0,0,90,10,105,115,95,98,117,105,108,116,105,110,114, + 174,0,0,0,41,4,218,3,99,108,115,114,159,0,0,0, + 114,35,0,0,0,218,6,116,97,114,103,101,116,114,4,0, + 0,0,114,4,0,0,0,114,5,0,0,0,218,9,102,105, + 110,100,95,115,112,101,99,195,4,0,0,115,10,0,0,0, + 0,2,12,1,4,1,15,1,19,2,122,25,66,117,105,108, + 116,105,110,73,109,112,111,114,116,101,114,46,102,105,110,100, + 95,115,112,101,99,99,3,0,0,0,0,0,0,0,4,0, + 0,0,3,0,0,0,67,0,0,0,115,41,0,0,0,124, + 0,0,106,0,0,124,1,0,124,2,0,131,2,0,125,3, + 0,124,3,0,100,1,0,107,9,0,114,37,0,124,3,0, + 106,1,0,83,100,1,0,83,41,2,122,175,70,105,110,100, + 32,116,104,101,32,98,117,105,108,116,45,105,110,32,109,111, + 100,117,108,101,46,10,10,32,32,32,32,32,32,32,32,73, + 102,32,39,112,97,116,104,39,32,105,115,32,101,118,101,114, + 32,115,112,101,99,105,102,105,101,100,32,116,104,101,110,32, + 116,104,101,32,115,101,97,114,99,104,32,105,115,32,99,111, + 110,115,105,100,101,114,101,100,32,97,32,102,97,105,108,117, + 114,101,46,10,10,32,32,32,32,32,32,32,32,84,104,105, + 115,32,109,101,116,104,111,100,32,105,115,32,100,101,112,114, + 101,99,97,116,101,100,46,32,32,85,115,101,32,102,105,110, + 100,95,115,112,101,99,40,41,32,105,110,115,116,101,97,100, + 46,10,10,32,32,32,32,32,32,32,32,78,41,2,114,12, + 1,0,0,114,170,0,0,0,41,4,114,10,1,0,0,114, + 159,0,0,0,114,35,0,0,0,114,177,0,0,0,114,4, + 0,0,0,114,4,0,0,0,114,5,0,0,0,218,11,102, + 105,110,100,95,109,111,100,117,108,101,204,4,0,0,115,4, + 0,0,0,0,9,18,1,122,27,66,117,105,108,116,105,110, + 73,109,112,111,114,116,101,114,46,102,105,110,100,95,109,111, + 100,117,108,101,99,2,0,0,0,0,0,0,0,3,0,0, + 0,10,0,0,0,67,0,0,0,115,59,0,0,0,116,0, + 0,124,1,0,131,1,0,143,23,0,1,116,1,0,116,2, + 0,106,3,0,124,1,0,131,2,0,125,2,0,87,100,1, + 0,81,88,124,0,0,124,2,0,95,4,0,100,2,0,124, + 2,0,95,5,0,124,2,0,83,41,3,122,23,76,111,97, + 100,32,97,32,98,117,105,108,116,45,105,110,32,109,111,100, + 117,108,101,46,78,114,30,0,0,0,41,6,114,69,0,0, + 0,114,114,0,0,0,114,106,0,0,0,90,12,105,110,105, + 116,95,98,117,105,108,116,105,110,114,203,0,0,0,114,249, + 0,0,0,41,3,114,10,1,0,0,114,159,0,0,0,114, + 178,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5, + 0,0,0,114,3,1,0,0,216,4,0,0,115,10,0,0, + 0,0,6,13,1,24,1,9,1,9,1,122,27,66,117,105, + 108,116,105,110,73,109,112,111,114,116,101,114,46,108,111,97, + 100,95,109,111,100,117,108,101,99,2,0,0,0,0,0,0, + 0,2,0,0,0,1,0,0,0,67,0,0,0,115,4,0, + 0,0,100,1,0,83,41,2,122,57,82,101,116,117,114,110, + 32,78,111,110,101,32,97,115,32,98,117,105,108,116,45,105, + 110,32,109,111,100,117,108,101,115,32,100,111,32,110,111,116, + 32,104,97,118,101,32,99,111,100,101,32,111,98,106,101,99, + 116,115,46,78,114,4,0,0,0,41,2,114,10,1,0,0, + 114,159,0,0,0,114,4,0,0,0,114,4,0,0,0,114, + 5,0,0,0,218,8,103,101,116,95,99,111,100,101,228,4, + 0,0,115,2,0,0,0,0,4,122,24,66,117,105,108,116, + 105,110,73,109,112,111,114,116,101,114,46,103,101,116,95,99, + 111,100,101,99,2,0,0,0,0,0,0,0,2,0,0,0, + 1,0,0,0,67,0,0,0,115,4,0,0,0,100,1,0, + 83,41,2,122,56,82,101,116,117,114,110,32,78,111,110,101, + 32,97,115,32,98,117,105,108,116,45,105,110,32,109,111,100, + 117,108,101,115,32,100,111,32,110,111,116,32,104,97,118,101, + 32,115,111,117,114,99,101,32,99,111,100,101,46,78,114,4, + 0,0,0,41,2,114,10,1,0,0,114,159,0,0,0,114, + 4,0,0,0,114,4,0,0,0,114,5,0,0,0,218,10, + 103,101,116,95,115,111,117,114,99,101,234,4,0,0,115,2, + 0,0,0,0,4,122,26,66,117,105,108,116,105,110,73,109, + 112,111,114,116,101,114,46,103,101,116,95,115,111,117,114,99, + 101,99,2,0,0,0,0,0,0,0,2,0,0,0,1,0, + 0,0,67,0,0,0,115,4,0,0,0,100,1,0,83,41, + 2,122,52,82,101,116,117,114,110,32,70,97,108,115,101,32, + 97,115,32,98,117,105,108,116,45,105,110,32,109,111,100,117, + 108,101,115,32,97,114,101,32,110,101,118,101,114,32,112,97, + 99,107,97,103,101,115,46,70,114,4,0,0,0,41,2,114, + 10,1,0,0,114,159,0,0,0,114,4,0,0,0,114,4, + 0,0,0,114,5,0,0,0,114,219,0,0,0,240,4,0, + 0,115,2,0,0,0,0,4,122,26,66,117,105,108,116,105, + 110,73,109,112,111,114,116,101,114,46,105,115,95,112,97,99, + 107,97,103,101,41,14,114,57,0,0,0,114,56,0,0,0, + 114,58,0,0,0,114,59,0,0,0,218,12,115,116,97,116, + 105,99,109,101,116,104,111,100,114,204,0,0,0,218,11,99, + 108,97,115,115,109,101,116,104,111,100,114,12,1,0,0,114, + 13,1,0,0,114,162,0,0,0,114,3,1,0,0,114,14, + 1,0,0,114,15,1,0,0,114,219,0,0,0,114,4,0, + 0,0,114,4,0,0,0,114,4,0,0,0,114,5,0,0, + 0,114,9,1,0,0,177,4,0,0,115,28,0,0,0,12, + 7,6,2,18,9,3,1,21,8,3,1,18,11,3,1,21, + 11,3,1,21,5,3,1,21,5,3,1,114,9,1,0,0, + 99,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0, + 0,64,0,0,0,115,211,0,0,0,101,0,0,90,1,0, + 100,0,0,90,2,0,100,1,0,90,3,0,101,4,0,100, + 2,0,100,3,0,132,0,0,131,1,0,90,5,0,101,6, + 0,100,4,0,100,4,0,100,5,0,100,6,0,132,2,0, + 131,1,0,90,7,0,101,6,0,100,4,0,100,7,0,100, + 8,0,132,1,0,131,1,0,90,8,0,101,6,0,100,9, + 0,100,10,0,132,0,0,131,1,0,90,9,0,101,4,0, + 100,11,0,100,12,0,132,0,0,131,1,0,90,10,0,101, + 6,0,100,13,0,100,14,0,132,0,0,131,1,0,90,11, + 0,101,6,0,101,12,0,100,15,0,100,16,0,132,0,0, + 131,1,0,131,1,0,90,13,0,101,6,0,101,12,0,100, + 17,0,100,18,0,132,0,0,131,1,0,131,1,0,90,14, + 0,101,6,0,101,12,0,100,19,0,100,20,0,132,0,0, + 131,1,0,131,1,0,90,15,0,100,4,0,83,41,21,218, + 14,70,114,111,122,101,110,73,109,112,111,114,116,101,114,122, + 142,77,101,116,97,32,112,97,116,104,32,105,109,112,111,114, + 116,32,102,111,114,32,102,114,111,122,101,110,32,109,111,100, + 117,108,101,115,46,10,10,32,32,32,32,65,108,108,32,109, + 101,116,104,111,100,115,32,97,114,101,32,101,105,116,104,101, + 114,32,99,108,97,115,115,32,111,114,32,115,116,97,116,105, + 99,32,109,101,116,104,111,100,115,32,116,111,32,97,118,111, + 105,100,32,116,104,101,32,110,101,101,100,32,116,111,10,32, + 32,32,32,105,110,115,116,97,110,116,105,97,116,101,32,116, + 104,101,32,99,108,97,115,115,46,10,10,32,32,32,32,99, + 1,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0, + 67,0,0,0,115,16,0,0,0,100,1,0,106,0,0,124, + 0,0,106,1,0,131,1,0,83,41,2,122,115,82,101,116, + 117,114,110,32,114,101,112,114,32,102,111,114,32,116,104,101, + 32,109,111,100,117,108,101,46,10,10,32,32,32,32,32,32, + 32,32,84,104,101,32,109,101,116,104,111,100,32,105,115,32, + 100,101,112,114,101,99,97,116,101,100,46,32,32,84,104,101, + 32,105,109,112,111,114,116,32,109,97,99,104,105,110,101,114, + 121,32,100,111,101,115,32,116,104,101,32,106,111,98,32,105, + 116,115,101,108,102,46,10,10,32,32,32,32,32,32,32,32, + 122,22,60,109,111,100,117,108,101,32,123,33,114,125,32,40, + 102,114,111,122,101,110,41,62,41,2,114,47,0,0,0,114, + 57,0,0,0,41,1,218,1,109,114,4,0,0,0,114,4, + 0,0,0,114,5,0,0,0,114,204,0,0,0,0,5,0, + 0,115,2,0,0,0,0,7,122,26,70,114,111,122,101,110, + 73,109,112,111,114,116,101,114,46,109,111,100,117,108,101,95, + 114,101,112,114,78,99,4,0,0,0,0,0,0,0,4,0, + 0,0,5,0,0,0,67,0,0,0,115,42,0,0,0,116, + 0,0,106,1,0,124,1,0,131,1,0,114,34,0,116,2, + 0,124,1,0,124,0,0,100,1,0,100,2,0,131,2,1, + 83,100,0,0,83,100,0,0,83,41,3,78,114,217,0,0, + 0,90,6,102,114,111,122,101,110,41,3,114,106,0,0,0, + 114,163,0,0,0,114,174,0,0,0,41,4,114,10,1,0, + 0,114,159,0,0,0,114,35,0,0,0,114,11,1,0,0, + 114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,114, + 12,1,0,0,9,5,0,0,115,6,0,0,0,0,2,15, + 1,19,2,122,24,70,114,111,122,101,110,73,109,112,111,114, + 116,101,114,46,102,105,110,100,95,115,112,101,99,99,3,0, + 0,0,0,0,0,0,3,0,0,0,2,0,0,0,67,0, + 0,0,115,23,0,0,0,116,0,0,106,1,0,124,1,0, + 131,1,0,114,19,0,124,0,0,83,100,1,0,83,41,2, + 122,93,70,105,110,100,32,97,32,102,114,111,122,101,110,32, + 109,111,100,117,108,101,46,10,10,32,32,32,32,32,32,32, + 32,84,104,105,115,32,109,101,116,104,111,100,32,105,115,32, + 100,101,112,114,101,99,97,116,101,100,46,32,32,85,115,101, + 32,102,105,110,100,95,115,112,101,99,40,41,32,105,110,115, + 116,101,97,100,46,10,10,32,32,32,32,32,32,32,32,78, + 41,2,114,106,0,0,0,114,163,0,0,0,41,3,114,10, + 1,0,0,114,159,0,0,0,114,35,0,0,0,114,4,0, + 0,0,114,4,0,0,0,114,5,0,0,0,114,13,1,0, + 0,16,5,0,0,115,2,0,0,0,0,7,122,26,70,114, 111,122,101,110,73,109,112,111,114,116,101,114,46,102,105,110, - 100,95,109,111,100,117,108,101,99,1,0,0,0,0,0,0, - 0,3,0,0,0,4,0,0,0,67,0,0,0,115,95,0, - 0,0,124,0,0,106,0,0,106,1,0,125,1,0,116,2, - 0,106,3,0,124,1,0,131,1,0,115,57,0,116,4,0, - 100,1,0,106,5,0,124,1,0,131,1,0,100,2,0,124, - 1,0,131,1,1,130,1,0,110,0,0,116,6,0,116,2, - 0,106,7,0,124,1,0,131,2,0,125,2,0,116,8,0, - 124,2,0,124,0,0,106,9,0,131,2,0,1,100,0,0, - 83,41,3,78,122,27,123,33,114,125,32,105,115,32,110,111, - 116,32,97,32,102,114,111,122,101,110,32,109,111,100,117,108, - 101,114,67,0,0,0,41,10,114,208,0,0,0,114,67,0, - 0,0,114,106,0,0,0,114,162,0,0,0,114,153,0,0, - 0,114,47,0,0,0,114,114,0,0,0,218,17,103,101,116, - 95,102,114,111,122,101,110,95,111,98,106,101,99,116,114,175, - 0,0,0,114,63,0,0,0,41,3,114,179,0,0,0,114, - 67,0,0,0,114,194,0,0,0,114,4,0,0,0,114,4, - 0,0,0,114,5,0,0,0,114,0,1,0,0,39,5,0, - 0,115,12,0,0,0,0,2,12,1,15,1,18,1,12,1, - 18,1,122,26,70,114,111,122,101,110,73,109,112,111,114,116, - 101,114,46,101,120,101,99,95,109,111,100,117,108,101,99,2, - 0,0,0,0,0,0,0,2,0,0,0,3,0,0,0,67, - 0,0,0,115,13,0,0,0,116,0,0,124,0,0,124,1, - 0,131,2,0,83,41,1,122,21,76,111,97,100,32,97,32, - 102,114,111,122,101,110,32,109,111,100,117,108,101,46,41,1, - 114,180,0,0,0,41,2,114,245,0,0,0,114,158,0,0, - 0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, - 114,3,1,0,0,48,5,0,0,115,2,0,0,0,0,3, - 122,26,70,114,111,122,101,110,73,109,112,111,114,116,101,114, - 46,108,111,97,100,95,109,111,100,117,108,101,99,2,0,0, - 0,0,0,0,0,2,0,0,0,2,0,0,0,67,0,0, - 0,115,13,0,0,0,116,0,0,106,1,0,124,1,0,131, - 1,0,83,41,1,122,45,82,101,116,117,114,110,32,116,104, - 101,32,99,111,100,101,32,111,98,106,101,99,116,32,102,111, - 114,32,116,104,101,32,102,114,111,122,101,110,32,109,111,100, - 117,108,101,46,41,2,114,106,0,0,0,114,17,1,0,0, - 41,2,114,245,0,0,0,114,158,0,0,0,114,4,0,0, - 0,114,4,0,0,0,114,5,0,0,0,114,12,1,0,0, - 53,5,0,0,115,2,0,0,0,0,4,122,23,70,114,111, - 122,101,110,73,109,112,111,114,116,101,114,46,103,101,116,95, - 99,111,100,101,99,2,0,0,0,0,0,0,0,2,0,0, - 0,1,0,0,0,67,0,0,0,115,4,0,0,0,100,1, - 0,83,41,2,122,54,82,101,116,117,114,110,32,78,111,110, - 101,32,97,115,32,102,114,111,122,101,110,32,109,111,100,117, - 108,101,115,32,100,111,32,110,111,116,32,104,97,118,101,32, - 115,111,117,114,99,101,32,99,111,100,101,46,78,114,4,0, - 0,0,41,2,114,245,0,0,0,114,158,0,0,0,114,4, - 0,0,0,114,4,0,0,0,114,5,0,0,0,114,13,1, - 0,0,59,5,0,0,115,2,0,0,0,0,4,122,25,70, - 114,111,122,101,110,73,109,112,111,114,116,101,114,46,103,101, - 116,95,115,111,117,114,99,101,99,2,0,0,0,0,0,0, - 0,2,0,0,0,2,0,0,0,67,0,0,0,115,13,0, - 0,0,116,0,0,106,1,0,124,1,0,131,1,0,83,41, - 1,122,46,82,101,116,117,114,110,32,84,114,117,101,32,105, - 102,32,116,104,101,32,102,114,111,122,101,110,32,109,111,100, - 117,108,101,32,105,115,32,97,32,112,97,99,107,97,103,101, - 46,41,2,114,106,0,0,0,90,17,105,115,95,102,114,111, - 122,101,110,95,112,97,99,107,97,103,101,41,2,114,245,0, - 0,0,114,158,0,0,0,114,4,0,0,0,114,4,0,0, - 0,114,5,0,0,0,114,219,0,0,0,65,5,0,0,115, - 2,0,0,0,0,4,122,25,70,114,111,122,101,110,73,109, - 112,111,114,116,101,114,46,105,115,95,112,97,99,107,97,103, - 101,41,15,114,57,0,0,0,114,56,0,0,0,114,58,0, - 0,0,114,59,0,0,0,114,14,1,0,0,114,205,0,0, - 0,114,7,1,0,0,114,10,1,0,0,114,11,1,0,0, - 114,0,1,0,0,114,3,1,0,0,114,164,0,0,0,114, - 12,1,0,0,114,13,1,0,0,114,219,0,0,0,114,4, - 0,0,0,114,4,0,0,0,114,4,0,0,0,114,5,0, - 0,0,114,15,1,0,0,13,5,0,0,115,28,0,0,0, - 12,7,6,2,18,5,3,1,21,6,3,1,18,4,18,9, - 18,5,3,1,21,5,3,1,21,5,3,1,114,15,1,0, - 0,99,0,0,0,0,0,0,0,0,0,0,0,0,5,0, - 0,0,64,0,0,0,115,121,0,0,0,101,0,0,90,1, - 0,100,0,0,90,2,0,100,1,0,90,3,0,100,2,0, - 90,4,0,100,3,0,90,5,0,100,4,0,90,6,0,101, - 7,0,100,5,0,100,6,0,132,0,0,131,1,0,90,8, - 0,101,7,0,100,7,0,100,8,0,132,0,0,131,1,0, - 90,9,0,101,7,0,100,9,0,100,9,0,100,10,0,100, - 11,0,132,2,0,131,1,0,90,10,0,101,7,0,100,9, - 0,100,12,0,100,13,0,132,1,0,131,1,0,90,11,0, - 100,9,0,83,41,14,218,21,87,105,110,100,111,119,115,82, - 101,103,105,115,116,114,121,70,105,110,100,101,114,122,62,77, - 101,116,97,32,112,97,116,104,32,102,105,110,100,101,114,32, - 102,111,114,32,109,111,100,117,108,101,115,32,100,101,99,108, - 97,114,101,100,32,105,110,32,116,104,101,32,87,105,110,100, - 111,119,115,32,114,101,103,105,115,116,114,121,46,122,59,83, - 111,102,116,119,97,114,101,92,80,121,116,104,111,110,92,80, - 121,116,104,111,110,67,111,114,101,92,123,115,121,115,95,118, - 101,114,115,105,111,110,125,92,77,111,100,117,108,101,115,92, - 123,102,117,108,108,110,97,109,101,125,122,65,83,111,102,116, - 119,97,114,101,92,80,121,116,104,111,110,92,80,121,116,104, - 111,110,67,111,114,101,92,123,115,121,115,95,118,101,114,115, - 105,111,110,125,92,77,111,100,117,108,101,115,92,123,102,117, - 108,108,110,97,109,101,125,92,68,101,98,117,103,70,99,2, - 0,0,0,0,0,0,0,2,0,0,0,11,0,0,0,67, - 0,0,0,115,67,0,0,0,121,23,0,116,0,0,106,1, - 0,116,0,0,106,2,0,124,1,0,131,2,0,83,87,110, - 37,0,4,116,3,0,107,10,0,114,62,0,1,1,1,116, - 0,0,106,1,0,116,0,0,106,4,0,124,1,0,131,2, - 0,83,89,110,1,0,88,100,0,0,83,41,1,78,41,5, - 218,7,95,119,105,110,114,101,103,90,7,79,112,101,110,75, - 101,121,90,17,72,75,69,89,95,67,85,82,82,69,78,84, - 95,85,83,69,82,114,40,0,0,0,90,18,72,75,69,89, - 95,76,79,67,65,76,95,77,65,67,72,73,78,69,41,2, - 114,245,0,0,0,218,3,107,101,121,114,4,0,0,0,114, - 4,0,0,0,114,5,0,0,0,218,14,95,111,112,101,110, - 95,114,101,103,105,115,116,114,121,84,5,0,0,115,8,0, - 0,0,0,2,3,1,23,1,13,1,122,36,87,105,110,100, - 111,119,115,82,101,103,105,115,116,114,121,70,105,110,100,101, - 114,46,95,111,112,101,110,95,114,101,103,105,115,116,114,121, - 99,2,0,0,0,0,0,0,0,6,0,0,0,16,0,0, - 0,67,0,0,0,115,142,0,0,0,124,0,0,106,0,0, - 114,21,0,124,0,0,106,1,0,125,2,0,110,9,0,124, - 0,0,106,2,0,125,2,0,124,2,0,106,3,0,100,1, - 0,124,1,0,100,2,0,116,4,0,106,5,0,100,0,0, - 100,3,0,133,2,0,25,131,0,2,125,3,0,121,46,0, - 124,0,0,106,6,0,124,3,0,131,1,0,143,25,0,125, - 4,0,116,7,0,106,8,0,124,4,0,100,4,0,131,2, - 0,125,5,0,87,100,0,0,81,88,87,110,22,0,4,116, - 9,0,107,10,0,114,137,0,1,1,1,100,0,0,83,89, - 110,1,0,88,124,5,0,83,41,5,78,114,158,0,0,0, - 90,11,115,121,115,95,118,101,114,115,105,111,110,114,136,0, - 0,0,114,30,0,0,0,41,10,218,11,68,69,66,85,71, - 95,66,85,73,76,68,218,18,82,69,71,73,83,84,82,89, - 95,75,69,89,95,68,69,66,85,71,218,12,82,69,71,73, - 83,84,82,89,95,75,69,89,114,47,0,0,0,114,7,0, - 0,0,218,7,118,101,114,115,105,111,110,114,21,1,0,0, - 114,19,1,0,0,90,10,81,117,101,114,121,86,97,108,117, - 101,114,40,0,0,0,41,6,114,245,0,0,0,114,158,0, - 0,0,90,12,114,101,103,105,115,116,114,121,95,107,101,121, - 114,20,1,0,0,90,4,104,107,101,121,218,8,102,105,108, - 101,112,97,116,104,114,4,0,0,0,114,4,0,0,0,114, - 5,0,0,0,218,16,95,115,101,97,114,99,104,95,114,101, - 103,105,115,116,114,121,91,5,0,0,115,22,0,0,0,0, - 2,9,1,12,2,9,1,15,1,22,1,3,1,18,1,28, - 1,13,1,9,1,122,38,87,105,110,100,111,119,115,82,101, - 103,105,115,116,114,121,70,105,110,100,101,114,46,95,115,101, - 97,114,99,104,95,114,101,103,105,115,116,114,121,78,99,4, - 0,0,0,0,0,0,0,8,0,0,0,14,0,0,0,67, - 0,0,0,115,155,0,0,0,124,0,0,106,0,0,124,1, - 0,131,1,0,125,4,0,124,4,0,100,0,0,107,8,0, - 114,31,0,100,0,0,83,121,14,0,116,1,0,124,4,0, - 131,1,0,1,87,110,22,0,4,116,2,0,107,10,0,114, - 69,0,1,1,1,100,0,0,83,89,110,1,0,88,120,78, - 0,116,3,0,131,0,0,68,93,67,0,92,2,0,125,5, - 0,125,6,0,124,4,0,106,4,0,116,5,0,124,6,0, - 131,1,0,131,1,0,114,80,0,116,6,0,124,1,0,124, - 5,0,124,1,0,124,4,0,131,2,0,100,1,0,124,4, - 0,131,2,1,125,7,0,124,7,0,83,113,80,0,87,100, - 0,0,83,41,2,78,114,217,0,0,0,41,7,114,27,1, - 0,0,114,39,0,0,0,114,40,0,0,0,114,236,0,0, - 0,114,228,0,0,0,114,229,0,0,0,114,173,0,0,0, - 41,8,114,245,0,0,0,114,158,0,0,0,114,35,0,0, - 0,114,9,1,0,0,114,26,1,0,0,114,169,0,0,0, - 114,127,0,0,0,114,177,0,0,0,114,4,0,0,0,114, - 4,0,0,0,114,5,0,0,0,114,10,1,0,0,106,5, - 0,0,115,24,0,0,0,0,3,15,1,12,1,4,1,3, - 1,14,1,13,1,9,1,22,1,21,1,21,1,9,1,122, - 31,87,105,110,100,111,119,115,82,101,103,105,115,116,114,121, - 70,105,110,100,101,114,46,102,105,110,100,95,115,112,101,99, - 99,3,0,0,0,0,0,0,0,4,0,0,0,3,0,0, - 0,67,0,0,0,115,45,0,0,0,116,0,0,106,1,0, - 124,1,0,124,2,0,131,2,0,125,3,0,124,3,0,100, - 1,0,107,9,0,114,37,0,124,3,0,106,2,0,83,100, - 1,0,83,100,1,0,83,41,2,122,34,70,105,110,100,32, - 109,111,100,117,108,101,32,110,97,109,101,100,32,105,110,32, - 116,104,101,32,114,101,103,105,115,116,114,121,46,78,41,3, - 114,71,0,0,0,114,10,1,0,0,114,169,0,0,0,41, - 4,114,245,0,0,0,114,158,0,0,0,114,35,0,0,0, - 114,177,0,0,0,114,4,0,0,0,114,4,0,0,0,114, - 5,0,0,0,114,11,1,0,0,122,5,0,0,115,8,0, - 0,0,0,3,18,1,12,1,7,2,122,33,87,105,110,100, - 111,119,115,82,101,103,105,115,116,114,121,70,105,110,100,101, - 114,46,102,105,110,100,95,109,111,100,117,108,101,41,12,114, - 57,0,0,0,114,56,0,0,0,114,58,0,0,0,114,59, - 0,0,0,114,24,1,0,0,114,23,1,0,0,114,22,1, - 0,0,114,7,1,0,0,114,21,1,0,0,114,27,1,0, - 0,114,10,1,0,0,114,11,1,0,0,114,4,0,0,0, + 100,95,109,111,100,117,108,101,99,2,0,0,0,0,0,0, + 0,2,0,0,0,1,0,0,0,67,0,0,0,115,4,0, + 0,0,100,1,0,83,41,2,122,42,85,115,101,32,100,101, + 102,97,117,108,116,32,115,101,109,97,110,116,105,99,115,32, + 102,111,114,32,109,111,100,117,108,101,32,99,114,101,97,116, + 105,111,110,46,78,114,4,0,0,0,41,2,114,10,1,0, + 0,114,177,0,0,0,114,4,0,0,0,114,4,0,0,0, + 114,5,0,0,0,114,254,0,0,0,25,5,0,0,115,0, + 0,0,0,122,28,70,114,111,122,101,110,73,109,112,111,114, + 116,101,114,46,99,114,101,97,116,101,95,109,111,100,117,108, + 101,99,1,0,0,0,0,0,0,0,3,0,0,0,4,0, + 0,0,67,0,0,0,115,92,0,0,0,124,0,0,106,0, + 0,106,1,0,125,1,0,116,2,0,106,3,0,124,1,0, + 131,1,0,115,54,0,116,4,0,100,1,0,106,5,0,124, + 1,0,131,1,0,100,2,0,124,1,0,131,1,1,130,1, + 0,116,6,0,116,2,0,106,7,0,124,1,0,131,2,0, + 125,2,0,116,8,0,124,2,0,124,0,0,106,9,0,131, + 2,0,1,100,0,0,83,41,3,78,122,27,123,33,114,125, + 32,105,115,32,110,111,116,32,97,32,102,114,111,122,101,110, + 32,109,111,100,117,108,101,114,67,0,0,0,41,10,114,207, + 0,0,0,114,67,0,0,0,114,106,0,0,0,114,163,0, + 0,0,114,154,0,0,0,114,47,0,0,0,114,114,0,0, + 0,218,17,103,101,116,95,102,114,111,122,101,110,95,111,98, + 106,101,99,116,218,4,101,120,101,99,114,63,0,0,0,41, + 3,114,178,0,0,0,114,67,0,0,0,114,193,0,0,0, 114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,114, - 18,1,0,0,72,5,0,0,115,20,0,0,0,12,2,6, - 3,6,3,6,2,6,2,18,7,18,15,3,1,21,15,3, - 1,114,18,1,0,0,99,0,0,0,0,0,0,0,0,0, - 0,0,0,2,0,0,0,64,0,0,0,115,52,0,0,0, - 101,0,0,90,1,0,100,0,0,90,2,0,100,1,0,90, - 3,0,100,2,0,100,3,0,132,0,0,90,4,0,100,4, - 0,100,5,0,132,0,0,90,5,0,101,6,0,90,7,0, - 100,6,0,83,41,7,218,13,95,76,111,97,100,101,114,66, - 97,115,105,99,115,122,83,66,97,115,101,32,99,108,97,115, - 115,32,111,102,32,99,111,109,109,111,110,32,99,111,100,101, - 32,110,101,101,100,101,100,32,98,121,32,98,111,116,104,32, - 83,111,117,114,99,101,76,111,97,100,101,114,32,97,110,100, - 10,32,32,32,32,83,111,117,114,99,101,108,101,115,115,70, - 105,108,101,76,111,97,100,101,114,46,99,2,0,0,0,0, - 0,0,0,5,0,0,0,3,0,0,0,67,0,0,0,115, - 88,0,0,0,116,0,0,124,0,0,106,1,0,124,1,0, - 131,1,0,131,1,0,100,1,0,25,125,2,0,124,2,0, - 106,2,0,100,2,0,100,1,0,131,2,0,100,3,0,25, - 125,3,0,124,1,0,106,3,0,100,2,0,131,1,0,100, - 4,0,25,125,4,0,124,3,0,100,5,0,107,2,0,111, - 87,0,124,4,0,100,5,0,107,3,0,83,41,6,122,141, - 67,111,110,99,114,101,116,101,32,105,109,112,108,101,109,101, - 110,116,97,116,105,111,110,32,111,102,32,73,110,115,112,101, - 99,116,76,111,97,100,101,114,46,105,115,95,112,97,99,107, - 97,103,101,32,98,121,32,99,104,101,99,107,105,110,103,32, - 105,102,10,32,32,32,32,32,32,32,32,116,104,101,32,112, - 97,116,104,32,114,101,116,117,114,110,101,100,32,98,121,32, - 103,101,116,95,102,105,108,101,110,97,109,101,32,104,97,115, - 32,97,32,102,105,108,101,110,97,109,101,32,111,102,32,39, - 95,95,105,110,105,116,95,95,46,112,121,39,46,114,29,0, - 0,0,114,116,0,0,0,114,84,0,0,0,114,115,0,0, - 0,114,72,0,0,0,41,4,114,38,0,0,0,114,234,0, - 0,0,114,34,0,0,0,114,32,0,0,0,41,5,114,71, - 0,0,0,114,158,0,0,0,114,131,0,0,0,90,13,102, - 105,108,101,110,97,109,101,95,98,97,115,101,90,9,116,97, - 105,108,95,110,97,109,101,114,4,0,0,0,114,4,0,0, - 0,114,5,0,0,0,114,219,0,0,0,138,5,0,0,115, - 8,0,0,0,0,3,25,1,22,1,19,1,122,24,95,76, - 111,97,100,101,114,66,97,115,105,99,115,46,105,115,95,112, - 97,99,107,97,103,101,99,2,0,0,0,0,0,0,0,3, - 0,0,0,4,0,0,0,67,0,0,0,115,80,0,0,0, - 124,0,0,106,0,0,124,1,0,106,1,0,131,1,0,125, - 2,0,124,2,0,100,1,0,107,8,0,114,57,0,116,2, - 0,100,2,0,106,3,0,124,1,0,106,1,0,131,1,0, - 131,1,0,130,1,0,110,0,0,116,4,0,116,5,0,124, - 2,0,124,1,0,106,6,0,131,3,0,1,100,1,0,83, - 41,3,122,19,69,120,101,99,117,116,101,32,116,104,101,32, - 109,111,100,117,108,101,46,78,122,52,99,97,110,110,111,116, - 32,108,111,97,100,32,109,111,100,117,108,101,32,123,33,114, - 125,32,119,104,101,110,32,103,101,116,95,99,111,100,101,40, - 41,32,114,101,116,117,114,110,115,32,78,111,110,101,41,7, - 114,12,1,0,0,114,57,0,0,0,114,153,0,0,0,114, - 47,0,0,0,114,114,0,0,0,114,175,0,0,0,114,63, - 0,0,0,41,3,114,71,0,0,0,114,179,0,0,0,114, - 194,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5, - 0,0,0,114,0,1,0,0,146,5,0,0,115,10,0,0, - 0,0,2,18,1,12,1,3,1,24,1,122,25,95,76,111, - 97,100,101,114,66,97,115,105,99,115,46,101,120,101,99,95, - 109,111,100,117,108,101,78,41,8,114,57,0,0,0,114,56, - 0,0,0,114,58,0,0,0,114,59,0,0,0,114,219,0, - 0,0,114,0,1,0,0,114,180,0,0,0,114,3,1,0, - 0,114,4,0,0,0,114,4,0,0,0,114,4,0,0,0, - 114,5,0,0,0,114,28,1,0,0,132,5,0,0,115,8, - 0,0,0,12,3,6,3,12,8,12,8,114,28,1,0,0, - 99,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0, - 0,64,0,0,0,115,106,0,0,0,101,0,0,90,1,0, - 100,0,0,90,2,0,100,1,0,100,2,0,132,0,0,90, - 3,0,100,3,0,100,4,0,132,0,0,90,4,0,100,5, - 0,100,6,0,132,0,0,90,5,0,100,7,0,100,8,0, - 132,0,0,90,6,0,100,9,0,100,10,0,132,0,0,90, - 7,0,100,11,0,100,18,0,100,13,0,100,14,0,132,0, - 1,90,8,0,100,15,0,100,16,0,132,0,0,90,9,0, - 100,17,0,83,41,19,218,12,83,111,117,114,99,101,76,111, - 97,100,101,114,99,2,0,0,0,0,0,0,0,2,0,0, - 0,1,0,0,0,67,0,0,0,115,10,0,0,0,116,0, - 0,130,1,0,100,1,0,83,41,2,122,178,79,112,116,105, - 111,110,97,108,32,109,101,116,104,111,100,32,116,104,97,116, - 32,114,101,116,117,114,110,115,32,116,104,101,32,109,111,100, - 105,102,105,99,97,116,105,111,110,32,116,105,109,101,32,40, - 97,110,32,105,110,116,41,32,102,111,114,32,116,104,101,10, - 32,32,32,32,32,32,32,32,115,112,101,99,105,102,105,101, - 100,32,112,97,116,104,44,32,119,104,101,114,101,32,112,97, - 116,104,32,105,115,32,97,32,115,116,114,46,10,10,32,32, - 32,32,32,32,32,32,82,97,105,115,101,115,32,73,79,69, - 114,114,111,114,32,119,104,101,110,32,116,104,101,32,112,97, - 116,104,32,99,97,110,110,111,116,32,98,101,32,104,97,110, - 100,108,101,100,46,10,32,32,32,32,32,32,32,32,78,41, - 1,218,7,73,79,69,114,114,111,114,41,2,114,71,0,0, - 0,114,35,0,0,0,114,4,0,0,0,114,4,0,0,0, - 114,5,0,0,0,218,10,112,97,116,104,95,109,116,105,109, - 101,159,5,0,0,115,2,0,0,0,0,6,122,23,83,111, - 117,114,99,101,76,111,97,100,101,114,46,112,97,116,104,95, - 109,116,105,109,101,99,2,0,0,0,0,0,0,0,2,0, - 0,0,3,0,0,0,67,0,0,0,115,20,0,0,0,105, - 1,0,124,0,0,106,0,0,124,1,0,131,1,0,100,1, - 0,54,83,41,2,97,170,1,0,0,79,112,116,105,111,110, - 97,108,32,109,101,116,104,111,100,32,114,101,116,117,114,110, - 105,110,103,32,97,32,109,101,116,97,100,97,116,97,32,100, - 105,99,116,32,102,111,114,32,116,104,101,32,115,112,101,99, - 105,102,105,101,100,32,112,97,116,104,10,32,32,32,32,32, - 32,32,32,116,111,32,98,121,32,116,104,101,32,112,97,116, - 104,32,40,115,116,114,41,46,10,32,32,32,32,32,32,32, - 32,80,111,115,115,105,98,108,101,32,107,101,121,115,58,10, - 32,32,32,32,32,32,32,32,45,32,39,109,116,105,109,101, - 39,32,40,109,97,110,100,97,116,111,114,121,41,32,105,115, - 32,116,104,101,32,110,117,109,101,114,105,99,32,116,105,109, - 101,115,116,97,109,112,32,111,102,32,108,97,115,116,32,115, - 111,117,114,99,101,10,32,32,32,32,32,32,32,32,32,32, - 99,111,100,101,32,109,111,100,105,102,105,99,97,116,105,111, - 110,59,10,32,32,32,32,32,32,32,32,45,32,39,115,105, - 122,101,39,32,40,111,112,116,105,111,110,97,108,41,32,105, - 115,32,116,104,101,32,115,105,122,101,32,105,110,32,98,121, - 116,101,115,32,111,102,32,116,104,101,32,115,111,117,114,99, - 101,32,99,111,100,101,46,10,10,32,32,32,32,32,32,32, - 32,73,109,112,108,101,109,101,110,116,105,110,103,32,116,104, - 105,115,32,109,101,116,104,111,100,32,97,108,108,111,119,115, - 32,116,104,101,32,108,111,97,100,101,114,32,116,111,32,114, - 101,97,100,32,98,121,116,101,99,111,100,101,32,102,105,108, - 101,115,46,10,32,32,32,32,32,32,32,32,82,97,105,115, - 101,115,32,73,79,69,114,114,111,114,32,119,104,101,110,32, - 116,104,101,32,112,97,116,104,32,99,97,110,110,111,116,32, - 98,101,32,104,97,110,100,108,101,100,46,10,32,32,32,32, - 32,32,32,32,114,183,0,0,0,41,1,114,31,1,0,0, - 41,2,114,71,0,0,0,114,35,0,0,0,114,4,0,0, - 0,114,4,0,0,0,114,5,0,0,0,218,10,112,97,116, - 104,95,115,116,97,116,115,167,5,0,0,115,2,0,0,0, - 0,11,122,23,83,111,117,114,99,101,76,111,97,100,101,114, - 46,112,97,116,104,95,115,116,97,116,115,99,4,0,0,0, - 0,0,0,0,4,0,0,0,3,0,0,0,67,0,0,0, - 115,16,0,0,0,124,0,0,106,0,0,124,2,0,124,3, - 0,131,2,0,83,41,1,122,228,79,112,116,105,111,110,97, - 108,32,109,101,116,104,111,100,32,119,104,105,99,104,32,119, - 114,105,116,101,115,32,100,97,116,97,32,40,98,121,116,101, - 115,41,32,116,111,32,97,32,102,105,108,101,32,112,97,116, - 104,32,40,97,32,115,116,114,41,46,10,10,32,32,32,32, - 32,32,32,32,73,109,112,108,101,109,101,110,116,105,110,103, - 32,116,104,105,115,32,109,101,116,104,111,100,32,97,108,108, - 111,119,115,32,102,111,114,32,116,104,101,32,119,114,105,116, - 105,110,103,32,111,102,32,98,121,116,101,99,111,100,101,32, - 102,105,108,101,115,46,10,10,32,32,32,32,32,32,32,32, - 84,104,101,32,115,111,117,114,99,101,32,112,97,116,104,32, - 105,115,32,110,101,101,100,101,100,32,105,110,32,111,114,100, - 101,114,32,116,111,32,99,111,114,114,101,99,116,108,121,32, - 116,114,97,110,115,102,101,114,32,112,101,114,109,105,115,115, - 105,111,110,115,10,32,32,32,32,32,32,32,32,41,1,218, - 8,115,101,116,95,100,97,116,97,41,4,114,71,0,0,0, - 114,141,0,0,0,90,10,99,97,99,104,101,95,112,97,116, - 104,114,53,0,0,0,114,4,0,0,0,114,4,0,0,0, - 114,5,0,0,0,218,15,95,99,97,99,104,101,95,98,121, - 116,101,99,111,100,101,180,5,0,0,115,2,0,0,0,0, - 8,122,28,83,111,117,114,99,101,76,111,97,100,101,114,46, - 95,99,97,99,104,101,95,98,121,116,101,99,111,100,101,99, - 3,0,0,0,0,0,0,0,3,0,0,0,1,0,0,0, - 67,0,0,0,115,4,0,0,0,100,1,0,83,41,2,122, - 150,79,112,116,105,111,110,97,108,32,109,101,116,104,111,100, - 32,119,104,105,99,104,32,119,114,105,116,101,115,32,100,97, - 116,97,32,40,98,121,116,101,115,41,32,116,111,32,97,32, - 102,105,108,101,32,112,97,116,104,32,40,97,32,115,116,114, - 41,46,10,10,32,32,32,32,32,32,32,32,73,109,112,108, - 101,109,101,110,116,105,110,103,32,116,104,105,115,32,109,101, - 116,104,111,100,32,97,108,108,111,119,115,32,102,111,114,32, - 116,104,101,32,119,114,105,116,105,110,103,32,111,102,32,98, - 121,116,101,99,111,100,101,32,102,105,108,101,115,46,10,32, - 32,32,32,32,32,32,32,78,114,4,0,0,0,41,3,114, - 71,0,0,0,114,35,0,0,0,114,53,0,0,0,114,4, - 0,0,0,114,4,0,0,0,114,5,0,0,0,114,33,1, - 0,0,190,5,0,0,115,0,0,0,0,122,21,83,111,117, - 114,99,101,76,111,97,100,101,114,46,115,101,116,95,100,97, - 116,97,99,2,0,0,0,0,0,0,0,5,0,0,0,16, - 0,0,0,67,0,0,0,115,105,0,0,0,124,0,0,106, - 0,0,124,1,0,131,1,0,125,2,0,121,19,0,124,0, - 0,106,1,0,124,2,0,131,1,0,125,3,0,87,110,58, - 0,4,116,2,0,107,10,0,114,94,0,1,125,4,0,1, - 122,26,0,116,3,0,100,1,0,100,2,0,124,1,0,131, - 1,1,124,4,0,130,2,0,87,89,100,3,0,100,3,0, - 125,4,0,126,4,0,88,110,1,0,88,116,4,0,124,3, - 0,131,1,0,83,41,4,122,52,67,111,110,99,114,101,116, + 255,0,0,0,29,5,0,0,115,12,0,0,0,0,2,12, + 1,15,1,18,1,9,1,18,1,122,26,70,114,111,122,101, + 110,73,109,112,111,114,116,101,114,46,101,120,101,99,95,109, + 111,100,117,108,101,99,2,0,0,0,0,0,0,0,2,0, + 0,0,3,0,0,0,67,0,0,0,115,13,0,0,0,116, + 0,0,124,0,0,124,1,0,131,2,0,83,41,1,122,95, + 76,111,97,100,32,97,32,102,114,111,122,101,110,32,109,111, + 100,117,108,101,46,10,10,32,32,32,32,32,32,32,32,84, + 104,105,115,32,109,101,116,104,111,100,32,105,115,32,100,101, + 112,114,101,99,97,116,101,100,46,32,32,85,115,101,32,101, + 120,101,99,95,109,111,100,117,108,101,40,41,32,105,110,115, + 116,101,97,100,46,10,10,32,32,32,32,32,32,32,32,41, + 1,114,179,0,0,0,41,2,114,10,1,0,0,114,159,0, + 0,0,114,4,0,0,0,114,4,0,0,0,114,5,0,0, + 0,114,3,1,0,0,38,5,0,0,115,2,0,0,0,0, + 7,122,26,70,114,111,122,101,110,73,109,112,111,114,116,101, + 114,46,108,111,97,100,95,109,111,100,117,108,101,99,2,0, + 0,0,0,0,0,0,2,0,0,0,2,0,0,0,67,0, + 0,0,115,13,0,0,0,116,0,0,106,1,0,124,1,0, + 131,1,0,83,41,1,122,45,82,101,116,117,114,110,32,116, + 104,101,32,99,111,100,101,32,111,98,106,101,99,116,32,102, + 111,114,32,116,104,101,32,102,114,111,122,101,110,32,109,111, + 100,117,108,101,46,41,2,114,106,0,0,0,114,20,1,0, + 0,41,2,114,10,1,0,0,114,159,0,0,0,114,4,0, + 0,0,114,4,0,0,0,114,5,0,0,0,114,14,1,0, + 0,47,5,0,0,115,2,0,0,0,0,4,122,23,70,114, + 111,122,101,110,73,109,112,111,114,116,101,114,46,103,101,116, + 95,99,111,100,101,99,2,0,0,0,0,0,0,0,2,0, + 0,0,1,0,0,0,67,0,0,0,115,4,0,0,0,100, + 1,0,83,41,2,122,54,82,101,116,117,114,110,32,78,111, + 110,101,32,97,115,32,102,114,111,122,101,110,32,109,111,100, + 117,108,101,115,32,100,111,32,110,111,116,32,104,97,118,101, + 32,115,111,117,114,99,101,32,99,111,100,101,46,78,114,4, + 0,0,0,41,2,114,10,1,0,0,114,159,0,0,0,114, + 4,0,0,0,114,4,0,0,0,114,5,0,0,0,114,15, + 1,0,0,53,5,0,0,115,2,0,0,0,0,4,122,25, + 70,114,111,122,101,110,73,109,112,111,114,116,101,114,46,103, + 101,116,95,115,111,117,114,99,101,99,2,0,0,0,0,0, + 0,0,2,0,0,0,2,0,0,0,67,0,0,0,115,13, + 0,0,0,116,0,0,106,1,0,124,1,0,131,1,0,83, + 41,1,122,46,82,101,116,117,114,110,32,84,114,117,101,32, + 105,102,32,116,104,101,32,102,114,111,122,101,110,32,109,111, + 100,117,108,101,32,105,115,32,97,32,112,97,99,107,97,103, + 101,46,41,2,114,106,0,0,0,90,17,105,115,95,102,114, + 111,122,101,110,95,112,97,99,107,97,103,101,41,2,114,10, + 1,0,0,114,159,0,0,0,114,4,0,0,0,114,4,0, + 0,0,114,5,0,0,0,114,219,0,0,0,59,5,0,0, + 115,2,0,0,0,0,4,122,25,70,114,111,122,101,110,73, + 109,112,111,114,116,101,114,46,105,115,95,112,97,99,107,97, + 103,101,41,16,114,57,0,0,0,114,56,0,0,0,114,58, + 0,0,0,114,59,0,0,0,114,16,1,0,0,114,204,0, + 0,0,114,17,1,0,0,114,12,1,0,0,114,13,1,0, + 0,114,254,0,0,0,114,255,0,0,0,114,3,1,0,0, + 114,165,0,0,0,114,14,1,0,0,114,15,1,0,0,114, + 219,0,0,0,114,4,0,0,0,114,4,0,0,0,114,4, + 0,0,0,114,5,0,0,0,114,18,1,0,0,247,4,0, + 0,115,30,0,0,0,12,7,6,2,18,9,3,1,21,6, + 3,1,18,8,18,4,18,9,18,9,3,1,21,5,3,1, + 21,5,3,1,114,18,1,0,0,99,0,0,0,0,0,0, + 0,0,0,0,0,0,5,0,0,0,64,0,0,0,115,121, + 0,0,0,101,0,0,90,1,0,100,0,0,90,2,0,100, + 1,0,90,3,0,100,2,0,90,4,0,100,3,0,90,5, + 0,100,4,0,90,6,0,101,7,0,100,5,0,100,6,0, + 132,0,0,131,1,0,90,8,0,101,7,0,100,7,0,100, + 8,0,132,0,0,131,1,0,90,9,0,101,7,0,100,9, + 0,100,9,0,100,10,0,100,11,0,132,2,0,131,1,0, + 90,10,0,101,7,0,100,9,0,100,12,0,100,13,0,132, + 1,0,131,1,0,90,11,0,100,9,0,83,41,14,218,21, + 87,105,110,100,111,119,115,82,101,103,105,115,116,114,121,70, + 105,110,100,101,114,122,62,77,101,116,97,32,112,97,116,104, + 32,102,105,110,100,101,114,32,102,111,114,32,109,111,100,117, + 108,101,115,32,100,101,99,108,97,114,101,100,32,105,110,32, + 116,104,101,32,87,105,110,100,111,119,115,32,114,101,103,105, + 115,116,114,121,46,122,59,83,111,102,116,119,97,114,101,92, + 80,121,116,104,111,110,92,80,121,116,104,111,110,67,111,114, + 101,92,123,115,121,115,95,118,101,114,115,105,111,110,125,92, + 77,111,100,117,108,101,115,92,123,102,117,108,108,110,97,109, + 101,125,122,65,83,111,102,116,119,97,114,101,92,80,121,116, + 104,111,110,92,80,121,116,104,111,110,67,111,114,101,92,123, + 115,121,115,95,118,101,114,115,105,111,110,125,92,77,111,100, + 117,108,101,115,92,123,102,117,108,108,110,97,109,101,125,92, + 68,101,98,117,103,70,99,2,0,0,0,0,0,0,0,2, + 0,0,0,11,0,0,0,67,0,0,0,115,67,0,0,0, + 121,23,0,116,0,0,106,1,0,116,0,0,106,2,0,124, + 1,0,131,2,0,83,87,110,37,0,4,116,3,0,107,10, + 0,114,62,0,1,1,1,116,0,0,106,1,0,116,0,0, + 106,4,0,124,1,0,131,2,0,83,89,110,1,0,88,100, + 0,0,83,41,1,78,41,5,218,7,95,119,105,110,114,101, + 103,90,7,79,112,101,110,75,101,121,90,17,72,75,69,89, + 95,67,85,82,82,69,78,84,95,85,83,69,82,114,40,0, + 0,0,90,18,72,75,69,89,95,76,79,67,65,76,95,77, + 65,67,72,73,78,69,41,2,114,10,1,0,0,218,3,107, + 101,121,114,4,0,0,0,114,4,0,0,0,114,5,0,0, + 0,218,14,95,111,112,101,110,95,114,101,103,105,115,116,114, + 121,78,5,0,0,115,8,0,0,0,0,2,3,1,23,1, + 13,1,122,36,87,105,110,100,111,119,115,82,101,103,105,115, + 116,114,121,70,105,110,100,101,114,46,95,111,112,101,110,95, + 114,101,103,105,115,116,114,121,99,2,0,0,0,0,0,0, + 0,6,0,0,0,16,0,0,0,67,0,0,0,115,142,0, + 0,0,124,0,0,106,0,0,114,21,0,124,0,0,106,1, + 0,125,2,0,110,9,0,124,0,0,106,2,0,125,2,0, + 124,2,0,106,3,0,100,1,0,124,1,0,100,2,0,116, + 4,0,106,5,0,100,0,0,100,3,0,133,2,0,25,131, + 0,2,125,3,0,121,46,0,124,0,0,106,6,0,124,3, + 0,131,1,0,143,25,0,125,4,0,116,7,0,106,8,0, + 124,4,0,100,4,0,131,2,0,125,5,0,87,100,0,0, + 81,88,87,110,22,0,4,116,9,0,107,10,0,114,137,0, + 1,1,1,100,0,0,83,89,110,1,0,88,124,5,0,83, + 41,5,78,114,159,0,0,0,90,11,115,121,115,95,118,101, + 114,115,105,111,110,114,137,0,0,0,114,30,0,0,0,41, + 10,218,11,68,69,66,85,71,95,66,85,73,76,68,218,18, + 82,69,71,73,83,84,82,89,95,75,69,89,95,68,69,66, + 85,71,218,12,82,69,71,73,83,84,82,89,95,75,69,89, + 114,47,0,0,0,114,7,0,0,0,218,7,118,101,114,115, + 105,111,110,114,25,1,0,0,114,23,1,0,0,90,10,81, + 117,101,114,121,86,97,108,117,101,114,40,0,0,0,41,6, + 114,10,1,0,0,114,159,0,0,0,90,12,114,101,103,105, + 115,116,114,121,95,107,101,121,114,24,1,0,0,90,4,104, + 107,101,121,218,8,102,105,108,101,112,97,116,104,114,4,0, + 0,0,114,4,0,0,0,114,5,0,0,0,218,16,95,115, + 101,97,114,99,104,95,114,101,103,105,115,116,114,121,85,5, + 0,0,115,22,0,0,0,0,2,9,1,12,2,9,1,15, + 1,22,1,3,1,18,1,28,1,13,1,9,1,122,38,87, + 105,110,100,111,119,115,82,101,103,105,115,116,114,121,70,105, + 110,100,101,114,46,95,115,101,97,114,99,104,95,114,101,103, + 105,115,116,114,121,78,99,4,0,0,0,0,0,0,0,8, + 0,0,0,14,0,0,0,67,0,0,0,115,155,0,0,0, + 124,0,0,106,0,0,124,1,0,131,1,0,125,4,0,124, + 4,0,100,0,0,107,8,0,114,31,0,100,0,0,83,121, + 14,0,116,1,0,124,4,0,131,1,0,1,87,110,22,0, + 4,116,2,0,107,10,0,114,69,0,1,1,1,100,0,0, + 83,89,110,1,0,88,120,78,0,116,3,0,131,0,0,68, + 93,67,0,92,2,0,125,5,0,125,6,0,124,4,0,106, + 4,0,116,5,0,124,6,0,131,1,0,131,1,0,114,80, + 0,116,6,0,124,1,0,124,5,0,124,1,0,124,4,0, + 131,2,0,100,1,0,124,4,0,131,2,1,125,7,0,124, + 7,0,83,113,80,0,87,100,0,0,83,41,2,78,114,217, + 0,0,0,41,7,114,31,1,0,0,114,39,0,0,0,114, + 40,0,0,0,114,240,0,0,0,114,230,0,0,0,114,231, + 0,0,0,114,174,0,0,0,41,8,114,10,1,0,0,114, + 159,0,0,0,114,35,0,0,0,114,11,1,0,0,114,30, + 1,0,0,114,170,0,0,0,114,126,0,0,0,114,177,0, + 0,0,114,4,0,0,0,114,4,0,0,0,114,5,0,0, + 0,114,12,1,0,0,100,5,0,0,115,24,0,0,0,0, + 2,15,1,12,1,4,1,3,1,14,1,13,1,9,1,22, + 1,21,1,21,1,9,1,122,31,87,105,110,100,111,119,115, + 82,101,103,105,115,116,114,121,70,105,110,100,101,114,46,102, + 105,110,100,95,115,112,101,99,99,3,0,0,0,0,0,0, + 0,4,0,0,0,3,0,0,0,67,0,0,0,115,45,0, + 0,0,124,0,0,106,0,0,124,1,0,124,2,0,131,2, + 0,125,3,0,124,3,0,100,1,0,107,9,0,114,37,0, + 124,3,0,106,1,0,83,100,1,0,83,100,1,0,83,41, + 2,122,108,70,105,110,100,32,109,111,100,117,108,101,32,110, + 97,109,101,100,32,105,110,32,116,104,101,32,114,101,103,105, + 115,116,114,121,46,10,10,32,32,32,32,32,32,32,32,84, + 104,105,115,32,109,101,116,104,111,100,32,105,115,32,100,101, + 112,114,101,99,97,116,101,100,46,32,32,85,115,101,32,101, + 120,101,99,95,109,111,100,117,108,101,40,41,32,105,110,115, + 116,101,97,100,46,10,10,32,32,32,32,32,32,32,32,78, + 41,2,114,12,1,0,0,114,170,0,0,0,41,4,114,10, + 1,0,0,114,159,0,0,0,114,35,0,0,0,114,177,0, + 0,0,114,4,0,0,0,114,4,0,0,0,114,5,0,0, + 0,114,13,1,0,0,115,5,0,0,115,8,0,0,0,0, + 7,18,1,12,1,7,2,122,33,87,105,110,100,111,119,115, + 82,101,103,105,115,116,114,121,70,105,110,100,101,114,46,102, + 105,110,100,95,109,111,100,117,108,101,41,12,114,57,0,0, + 0,114,56,0,0,0,114,58,0,0,0,114,59,0,0,0, + 114,28,1,0,0,114,27,1,0,0,114,26,1,0,0,114, + 17,1,0,0,114,25,1,0,0,114,31,1,0,0,114,12, + 1,0,0,114,13,1,0,0,114,4,0,0,0,114,4,0, + 0,0,114,4,0,0,0,114,5,0,0,0,114,22,1,0, + 0,66,5,0,0,115,20,0,0,0,12,2,6,3,6,3, + 6,2,6,2,18,7,18,15,3,1,21,14,3,1,114,22, + 1,0,0,99,0,0,0,0,0,0,0,0,0,0,0,0, + 2,0,0,0,64,0,0,0,115,64,0,0,0,101,0,0, + 90,1,0,100,0,0,90,2,0,100,1,0,90,3,0,100, + 2,0,100,3,0,132,0,0,90,4,0,100,4,0,100,5, + 0,132,0,0,90,5,0,100,6,0,100,7,0,132,0,0, + 90,6,0,101,7,0,90,8,0,100,8,0,83,41,9,218, + 13,95,76,111,97,100,101,114,66,97,115,105,99,115,122,83, + 66,97,115,101,32,99,108,97,115,115,32,111,102,32,99,111, + 109,109,111,110,32,99,111,100,101,32,110,101,101,100,101,100, + 32,98,121,32,98,111,116,104,32,83,111,117,114,99,101,76, + 111,97,100,101,114,32,97,110,100,10,32,32,32,32,83,111, + 117,114,99,101,108,101,115,115,70,105,108,101,76,111,97,100, + 101,114,46,99,2,0,0,0,0,0,0,0,5,0,0,0, + 3,0,0,0,67,0,0,0,115,88,0,0,0,116,0,0, + 124,0,0,106,1,0,124,1,0,131,1,0,131,1,0,100, + 1,0,25,125,2,0,124,2,0,106,2,0,100,2,0,100, + 1,0,131,2,0,100,3,0,25,125,3,0,124,1,0,106, + 3,0,100,2,0,131,1,0,100,4,0,25,125,4,0,124, + 3,0,100,5,0,107,2,0,111,87,0,124,4,0,100,5, + 0,107,3,0,83,41,6,122,141,67,111,110,99,114,101,116, 101,32,105,109,112,108,101,109,101,110,116,97,116,105,111,110, 32,111,102,32,73,110,115,112,101,99,116,76,111,97,100,101, - 114,46,103,101,116,95,115,111,117,114,99,101,46,122,39,115, - 111,117,114,99,101,32,110,111,116,32,97,118,97,105,108,97, - 98,108,101,32,116,104,114,111,117,103,104,32,103,101,116,95, - 100,97,116,97,40,41,114,67,0,0,0,78,41,5,114,234, - 0,0,0,218,8,103,101,116,95,100,97,116,97,114,40,0, - 0,0,114,153,0,0,0,114,203,0,0,0,41,5,114,71, - 0,0,0,114,158,0,0,0,114,35,0,0,0,114,201,0, - 0,0,218,3,101,120,99,114,4,0,0,0,114,4,0,0, - 0,114,5,0,0,0,114,13,1,0,0,197,5,0,0,115, - 14,0,0,0,0,2,15,1,3,1,19,1,18,1,9,1, - 31,1,122,23,83,111,117,114,99,101,76,111,97,100,101,114, - 46,103,101,116,95,115,111,117,114,99,101,218,9,95,111,112, - 116,105,109,105,122,101,114,29,0,0,0,99,3,0,0,0, - 1,0,0,0,4,0,0,0,9,0,0,0,67,0,0,0, - 115,31,0,0,0,116,0,0,116,1,0,124,1,0,124,2, - 0,100,1,0,100,2,0,100,3,0,100,4,0,124,3,0, - 131,4,2,83,41,5,122,130,82,101,116,117,114,110,32,116, - 104,101,32,99,111,100,101,32,111,98,106,101,99,116,32,99, - 111,109,112,105,108,101,100,32,102,114,111,109,32,115,111,117, - 114,99,101,46,10,10,32,32,32,32,32,32,32,32,84,104, - 101,32,39,100,97,116,97,39,32,97,114,103,117,109,101,110, - 116,32,99,97,110,32,98,101,32,97,110,121,32,111,98,106, - 101,99,116,32,116,121,112,101,32,116,104,97,116,32,99,111, - 109,112,105,108,101,40,41,32,115,117,112,112,111,114,116,115, - 46,10,32,32,32,32,32,32,32,32,114,175,0,0,0,218, - 12,100,111,110,116,95,105,110,104,101,114,105,116,84,114,118, - 0,0,0,41,2,114,114,0,0,0,218,7,99,111,109,112, - 105,108,101,41,4,114,71,0,0,0,114,53,0,0,0,114, - 35,0,0,0,114,37,1,0,0,114,4,0,0,0,114,4, - 0,0,0,114,5,0,0,0,218,14,115,111,117,114,99,101, - 95,116,111,95,99,111,100,101,207,5,0,0,115,4,0,0, - 0,0,5,18,1,122,27,83,111,117,114,99,101,76,111,97, - 100,101,114,46,115,111,117,114,99,101,95,116,111,95,99,111, - 100,101,99,2,0,0,0,0,0,0,0,10,0,0,0,45, - 0,0,0,67,0,0,0,115,177,1,0,0,124,0,0,106, - 0,0,124,1,0,131,1,0,125,2,0,100,1,0,125,3, - 0,121,16,0,116,1,0,124,2,0,131,1,0,125,4,0, - 87,110,24,0,4,116,2,0,107,10,0,114,63,0,1,1, - 1,100,1,0,125,4,0,89,110,202,0,88,121,19,0,124, - 0,0,106,3,0,124,2,0,131,1,0,125,5,0,87,110, - 18,0,4,116,4,0,107,10,0,114,103,0,1,1,1,89, - 110,162,0,88,116,5,0,124,5,0,100,2,0,25,131,1, - 0,125,3,0,121,19,0,124,0,0,106,6,0,124,4,0, - 131,1,0,125,6,0,87,110,18,0,4,116,7,0,107,10, - 0,114,159,0,1,1,1,89,110,106,0,88,121,34,0,116, - 8,0,124,6,0,100,3,0,124,5,0,100,4,0,124,1, - 0,100,5,0,124,4,0,131,1,3,125,7,0,87,110,24, - 0,4,116,9,0,116,10,0,102,2,0,107,10,0,114,220, - 0,1,1,1,89,110,45,0,88,116,11,0,100,6,0,124, - 4,0,124,2,0,131,3,0,1,116,12,0,124,7,0,100, - 4,0,124,1,0,100,7,0,124,4,0,100,8,0,124,2, - 0,131,1,3,83,124,0,0,106,6,0,124,2,0,131,1, - 0,125,8,0,124,0,0,106,13,0,124,8,0,124,2,0, - 131,2,0,125,9,0,116,11,0,100,9,0,124,2,0,131, - 2,0,1,116,14,0,106,15,0,12,114,173,1,124,4,0, - 100,1,0,107,9,0,114,173,1,124,3,0,100,1,0,107, - 9,0,114,173,1,116,16,0,124,9,0,124,3,0,116,17, - 0,124,8,0,131,1,0,131,3,0,125,6,0,121,36,0, - 124,0,0,106,18,0,124,2,0,124,4,0,124,6,0,131, - 3,0,1,116,11,0,100,10,0,124,4,0,131,2,0,1, - 87,113,173,1,4,116,2,0,107,10,0,114,169,1,1,1, - 1,89,113,173,1,88,110,0,0,124,9,0,83,41,11,122, - 190,67,111,110,99,114,101,116,101,32,105,109,112,108,101,109, - 101,110,116,97,116,105,111,110,32,111,102,32,73,110,115,112, - 101,99,116,76,111,97,100,101,114,46,103,101,116,95,99,111, - 100,101,46,10,10,32,32,32,32,32,32,32,32,82,101,97, - 100,105,110,103,32,111,102,32,98,121,116,101,99,111,100,101, - 32,114,101,113,117,105,114,101,115,32,112,97,116,104,95,115, - 116,97,116,115,32,116,111,32,98,101,32,105,109,112,108,101, - 109,101,110,116,101,100,46,32,84,111,32,119,114,105,116,101, - 10,32,32,32,32,32,32,32,32,98,121,116,101,99,111,100, - 101,44,32,115,101,116,95,100,97,116,97,32,109,117,115,116, - 32,97,108,115,111,32,98,101,32,105,109,112,108,101,109,101, - 110,116,101,100,46,10,10,32,32,32,32,32,32,32,32,78, - 114,183,0,0,0,114,187,0,0,0,114,67,0,0,0,114, - 35,0,0,0,122,13,123,125,32,109,97,116,99,104,101,115, - 32,123,125,114,140,0,0,0,114,141,0,0,0,122,19,99, - 111,100,101,32,111,98,106,101,99,116,32,102,114,111,109,32, - 123,125,122,10,119,114,111,116,101,32,123,33,114,125,41,19, - 114,234,0,0,0,114,132,0,0,0,114,124,0,0,0,114, - 32,1,0,0,114,30,1,0,0,114,14,0,0,0,114,35, - 1,0,0,114,40,0,0,0,114,190,0,0,0,114,153,0, - 0,0,114,186,0,0,0,114,152,0,0,0,114,195,0,0, - 0,114,40,1,0,0,114,7,0,0,0,218,19,100,111,110, - 116,95,119,114,105,116,101,95,98,121,116,101,99,111,100,101, - 114,198,0,0,0,114,31,0,0,0,114,34,1,0,0,41, - 10,114,71,0,0,0,114,158,0,0,0,114,141,0,0,0, - 114,188,0,0,0,114,140,0,0,0,218,2,115,116,114,53, - 0,0,0,218,10,98,121,116,101,115,95,100,97,116,97,114, - 201,0,0,0,90,11,99,111,100,101,95,111,98,106,101,99, - 116,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, - 114,12,1,0,0,215,5,0,0,115,78,0,0,0,0,7, - 15,1,6,1,3,1,16,1,13,1,11,2,3,1,19,1, - 13,1,5,2,16,1,3,1,19,1,13,1,5,2,3,1, - 9,1,12,1,13,1,19,1,5,2,9,1,7,1,15,1, - 6,1,7,1,15,1,18,1,13,1,22,1,12,1,9,1, - 15,1,3,1,19,1,17,1,13,1,8,1,122,21,83,111, - 117,114,99,101,76,111,97,100,101,114,46,103,101,116,95,99, - 111,100,101,78,114,138,0,0,0,41,10,114,57,0,0,0, - 114,56,0,0,0,114,58,0,0,0,114,31,1,0,0,114, - 32,1,0,0,114,34,1,0,0,114,33,1,0,0,114,13, - 1,0,0,114,40,1,0,0,114,12,1,0,0,114,4,0, + 114,46,105,115,95,112,97,99,107,97,103,101,32,98,121,32, + 99,104,101,99,107,105,110,103,32,105,102,10,32,32,32,32, + 32,32,32,32,116,104,101,32,112,97,116,104,32,114,101,116, + 117,114,110,101,100,32,98,121,32,103,101,116,95,102,105,108, + 101,110,97,109,101,32,104,97,115,32,97,32,102,105,108,101, + 110,97,109,101,32,111,102,32,39,95,95,105,110,105,116,95, + 95,46,112,121,39,46,114,29,0,0,0,114,116,0,0,0, + 114,84,0,0,0,114,115,0,0,0,114,72,0,0,0,41, + 4,114,38,0,0,0,114,238,0,0,0,114,34,0,0,0, + 114,32,0,0,0,41,5,114,71,0,0,0,114,159,0,0, + 0,114,131,0,0,0,90,13,102,105,108,101,110,97,109,101, + 95,98,97,115,101,90,9,116,97,105,108,95,110,97,109,101, + 114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,114, + 219,0,0,0,134,5,0,0,115,8,0,0,0,0,3,25, + 1,22,1,19,1,122,24,95,76,111,97,100,101,114,66,97, + 115,105,99,115,46,105,115,95,112,97,99,107,97,103,101,99, + 2,0,0,0,0,0,0,0,2,0,0,0,1,0,0,0, + 67,0,0,0,115,4,0,0,0,100,1,0,83,41,2,122, + 42,85,115,101,32,100,101,102,97,117,108,116,32,115,101,109, + 97,110,116,105,99,115,32,102,111,114,32,109,111,100,117,108, + 101,32,99,114,101,97,116,105,111,110,46,78,114,4,0,0, + 0,41,2,114,71,0,0,0,114,177,0,0,0,114,4,0, + 0,0,114,4,0,0,0,114,5,0,0,0,114,254,0,0, + 0,142,5,0,0,115,0,0,0,0,122,27,95,76,111,97, + 100,101,114,66,97,115,105,99,115,46,99,114,101,97,116,101, + 95,109,111,100,117,108,101,99,2,0,0,0,0,0,0,0, + 3,0,0,0,4,0,0,0,67,0,0,0,115,77,0,0, + 0,124,0,0,106,0,0,124,1,0,106,1,0,131,1,0, + 125,2,0,124,2,0,100,1,0,107,8,0,114,54,0,116, + 2,0,100,2,0,106,3,0,124,1,0,106,1,0,131,1, + 0,131,1,0,130,1,0,116,4,0,116,5,0,124,2,0, + 124,1,0,106,6,0,131,3,0,1,100,1,0,83,41,3, + 122,19,69,120,101,99,117,116,101,32,116,104,101,32,109,111, + 100,117,108,101,46,78,122,52,99,97,110,110,111,116,32,108, + 111,97,100,32,109,111,100,117,108,101,32,123,33,114,125,32, + 119,104,101,110,32,103,101,116,95,99,111,100,101,40,41,32, + 114,101,116,117,114,110,115,32,78,111,110,101,41,7,114,14, + 1,0,0,114,57,0,0,0,114,154,0,0,0,114,47,0, + 0,0,114,114,0,0,0,114,21,1,0,0,114,63,0,0, + 0,41,3,114,71,0,0,0,114,178,0,0,0,114,193,0, 0,0,114,4,0,0,0,114,4,0,0,0,114,5,0,0, - 0,114,29,1,0,0,157,5,0,0,115,14,0,0,0,12, - 2,12,8,12,13,12,10,12,7,12,10,18,8,114,29,1, - 0,0,99,0,0,0,0,0,0,0,0,0,0,0,0,4, - 0,0,0,0,0,0,0,115,88,0,0,0,101,0,0,90, - 1,0,100,0,0,90,2,0,100,1,0,90,3,0,100,2, - 0,100,3,0,132,0,0,90,4,0,101,5,0,135,0,0, - 102,1,0,100,4,0,100,5,0,134,0,0,131,1,0,90, - 6,0,101,5,0,100,6,0,100,7,0,132,0,0,131,1, - 0,90,7,0,100,8,0,100,9,0,132,0,0,90,8,0, - 135,0,0,83,41,10,218,10,70,105,108,101,76,111,97,100, - 101,114,122,103,66,97,115,101,32,102,105,108,101,32,108,111, - 97,100,101,114,32,99,108,97,115,115,32,119,104,105,99,104, - 32,105,109,112,108,101,109,101,110,116,115,32,116,104,101,32, - 108,111,97,100,101,114,32,112,114,111,116,111,99,111,108,32, - 109,101,116,104,111,100,115,32,116,104,97,116,10,32,32,32, - 32,114,101,113,117,105,114,101,32,102,105,108,101,32,115,121, - 115,116,101,109,32,117,115,97,103,101,46,99,3,0,0,0, - 0,0,0,0,3,0,0,0,2,0,0,0,67,0,0,0, - 115,22,0,0,0,124,1,0,124,0,0,95,0,0,124,2, - 0,124,0,0,95,1,0,100,1,0,83,41,2,122,75,67, - 97,99,104,101,32,116,104,101,32,109,111,100,117,108,101,32, - 110,97,109,101,32,97,110,100,32,116,104,101,32,112,97,116, - 104,32,116,111,32,116,104,101,32,102,105,108,101,32,102,111, - 117,110,100,32,98,121,32,116,104,101,10,32,32,32,32,32, - 32,32,32,102,105,110,100,101,114,46,78,41,2,114,67,0, - 0,0,114,35,0,0,0,41,3,114,71,0,0,0,114,158, - 0,0,0,114,35,0,0,0,114,4,0,0,0,114,4,0, - 0,0,114,5,0,0,0,114,72,0,0,0,16,6,0,0, - 115,4,0,0,0,0,3,9,1,122,19,70,105,108,101,76, - 111,97,100,101,114,46,95,95,105,110,105,116,95,95,99,2, - 0,0,0,0,0,0,0,2,0,0,0,3,0,0,0,3, - 0,0,0,115,22,0,0,0,116,0,0,116,1,0,124,0, - 0,131,2,0,106,2,0,124,1,0,131,1,0,83,41,1, - 122,26,76,111,97,100,32,97,32,109,111,100,117,108,101,32, - 102,114,111,109,32,97,32,102,105,108,101,46,41,3,218,5, - 115,117,112,101,114,114,44,1,0,0,114,3,1,0,0,41, - 2,114,71,0,0,0,114,158,0,0,0,41,1,114,224,0, - 0,0,114,4,0,0,0,114,5,0,0,0,114,3,1,0, - 0,22,6,0,0,115,2,0,0,0,0,7,122,22,70,105, - 108,101,76,111,97,100,101,114,46,108,111,97,100,95,109,111, - 100,117,108,101,99,2,0,0,0,0,0,0,0,2,0,0, - 0,1,0,0,0,67,0,0,0,115,7,0,0,0,124,0, - 0,106,0,0,83,41,1,122,58,82,101,116,117,114,110,32, - 116,104,101,32,112,97,116,104,32,116,111,32,116,104,101,32, - 115,111,117,114,99,101,32,102,105,108,101,32,97,115,32,102, - 111,117,110,100,32,98,121,32,116,104,101,32,102,105,110,100, - 101,114,46,41,1,114,35,0,0,0,41,2,114,71,0,0, - 0,114,158,0,0,0,114,4,0,0,0,114,4,0,0,0, - 114,5,0,0,0,114,234,0,0,0,31,6,0,0,115,2, - 0,0,0,0,3,122,23,70,105,108,101,76,111,97,100,101, - 114,46,103,101,116,95,102,105,108,101,110,97,109,101,99,2, - 0,0,0,0,0,0,0,3,0,0,0,8,0,0,0,67, - 0,0,0,115,41,0,0,0,116,0,0,106,1,0,124,1, - 0,100,1,0,131,2,0,143,17,0,125,2,0,124,2,0, - 106,2,0,131,0,0,83,87,100,2,0,81,88,100,2,0, - 83,41,3,122,39,82,101,116,117,114,110,32,116,104,101,32, - 100,97,116,97,32,102,114,111,109,32,112,97,116,104,32,97, - 115,32,114,97,119,32,98,121,116,101,115,46,218,1,114,78, - 41,3,114,49,0,0,0,114,50,0,0,0,90,4,114,101, - 97,100,41,3,114,71,0,0,0,114,35,0,0,0,114,54, - 0,0,0,114,4,0,0,0,114,4,0,0,0,114,5,0, - 0,0,114,35,1,0,0,36,6,0,0,115,4,0,0,0, - 0,2,21,1,122,19,70,105,108,101,76,111,97,100,101,114, - 46,103,101,116,95,100,97,116,97,41,9,114,57,0,0,0, - 114,56,0,0,0,114,58,0,0,0,114,59,0,0,0,114, - 72,0,0,0,114,156,0,0,0,114,3,1,0,0,114,234, - 0,0,0,114,35,1,0,0,114,4,0,0,0,114,4,0, - 0,0,41,1,114,224,0,0,0,114,5,0,0,0,114,44, - 1,0,0,11,6,0,0,115,10,0,0,0,12,3,6,2, - 12,6,24,9,18,5,114,44,1,0,0,99,0,0,0,0, - 0,0,0,0,0,0,0,0,4,0,0,0,64,0,0,0, - 115,64,0,0,0,101,0,0,90,1,0,100,0,0,90,2, - 0,100,1,0,90,3,0,100,2,0,100,3,0,132,0,0, - 90,4,0,100,4,0,100,5,0,132,0,0,90,5,0,100, - 6,0,100,7,0,100,8,0,100,9,0,132,0,1,90,6, - 0,100,10,0,83,41,11,218,16,83,111,117,114,99,101,70, - 105,108,101,76,111,97,100,101,114,122,62,67,111,110,99,114, - 101,116,101,32,105,109,112,108,101,109,101,110,116,97,116,105, - 111,110,32,111,102,32,83,111,117,114,99,101,76,111,97,100, - 101,114,32,117,115,105,110,103,32,116,104,101,32,102,105,108, - 101,32,115,121,115,116,101,109,46,99,2,0,0,0,0,0, - 0,0,3,0,0,0,3,0,0,0,67,0,0,0,115,36, - 0,0,0,116,0,0,124,1,0,131,1,0,125,2,0,105, - 2,0,124,2,0,106,1,0,100,1,0,54,124,2,0,106, - 2,0,100,2,0,54,83,41,3,122,33,82,101,116,117,114, - 110,32,116,104,101,32,109,101,116,97,100,97,116,97,32,102, - 111,114,32,116,104,101,32,112,97,116,104,46,114,183,0,0, - 0,114,184,0,0,0,41,3,114,39,0,0,0,218,8,115, - 116,95,109,116,105,109,101,90,7,115,116,95,115,105,122,101, - 41,3,114,71,0,0,0,114,35,0,0,0,114,42,1,0, + 0,114,255,0,0,0,145,5,0,0,115,10,0,0,0,0, + 2,18,1,12,1,9,1,15,1,122,25,95,76,111,97,100, + 101,114,66,97,115,105,99,115,46,101,120,101,99,95,109,111, + 100,117,108,101,78,41,9,114,57,0,0,0,114,56,0,0, + 0,114,58,0,0,0,114,59,0,0,0,114,219,0,0,0, + 114,254,0,0,0,114,255,0,0,0,114,179,0,0,0,114, + 3,1,0,0,114,4,0,0,0,114,4,0,0,0,114,4, + 0,0,0,114,5,0,0,0,114,32,1,0,0,129,5,0, + 0,115,10,0,0,0,12,3,6,2,12,8,12,3,12,8, + 114,32,1,0,0,99,0,0,0,0,0,0,0,0,0,0, + 0,0,4,0,0,0,64,0,0,0,115,106,0,0,0,101, + 0,0,90,1,0,100,0,0,90,2,0,100,1,0,100,2, + 0,132,0,0,90,3,0,100,3,0,100,4,0,132,0,0, + 90,4,0,100,5,0,100,6,0,132,0,0,90,5,0,100, + 7,0,100,8,0,132,0,0,90,6,0,100,9,0,100,10, + 0,132,0,0,90,7,0,100,11,0,100,18,0,100,13,0, + 100,14,0,132,0,1,90,8,0,100,15,0,100,16,0,132, + 0,0,90,9,0,100,17,0,83,41,19,218,12,83,111,117, + 114,99,101,76,111,97,100,101,114,99,2,0,0,0,0,0, + 0,0,2,0,0,0,1,0,0,0,67,0,0,0,115,10, + 0,0,0,116,0,0,130,1,0,100,1,0,83,41,2,122, + 178,79,112,116,105,111,110,97,108,32,109,101,116,104,111,100, + 32,116,104,97,116,32,114,101,116,117,114,110,115,32,116,104, + 101,32,109,111,100,105,102,105,99,97,116,105,111,110,32,116, + 105,109,101,32,40,97,110,32,105,110,116,41,32,102,111,114, + 32,116,104,101,10,32,32,32,32,32,32,32,32,115,112,101, + 99,105,102,105,101,100,32,112,97,116,104,44,32,119,104,101, + 114,101,32,112,97,116,104,32,105,115,32,97,32,115,116,114, + 46,10,10,32,32,32,32,32,32,32,32,82,97,105,115,101, + 115,32,73,79,69,114,114,111,114,32,119,104,101,110,32,116, + 104,101,32,112,97,116,104,32,99,97,110,110,111,116,32,98, + 101,32,104,97,110,100,108,101,100,46,10,32,32,32,32,32, + 32,32,32,78,41,1,218,7,73,79,69,114,114,111,114,41, + 2,114,71,0,0,0,114,35,0,0,0,114,4,0,0,0, + 114,4,0,0,0,114,5,0,0,0,218,10,112,97,116,104, + 95,109,116,105,109,101,158,5,0,0,115,2,0,0,0,0, + 6,122,23,83,111,117,114,99,101,76,111,97,100,101,114,46, + 112,97,116,104,95,109,116,105,109,101,99,2,0,0,0,0, + 0,0,0,2,0,0,0,3,0,0,0,67,0,0,0,115, + 20,0,0,0,105,1,0,124,0,0,106,0,0,124,1,0, + 131,1,0,100,1,0,54,83,41,2,97,170,1,0,0,79, + 112,116,105,111,110,97,108,32,109,101,116,104,111,100,32,114, + 101,116,117,114,110,105,110,103,32,97,32,109,101,116,97,100, + 97,116,97,32,100,105,99,116,32,102,111,114,32,116,104,101, + 32,115,112,101,99,105,102,105,101,100,32,112,97,116,104,10, + 32,32,32,32,32,32,32,32,116,111,32,98,121,32,116,104, + 101,32,112,97,116,104,32,40,115,116,114,41,46,10,32,32, + 32,32,32,32,32,32,80,111,115,115,105,98,108,101,32,107, + 101,121,115,58,10,32,32,32,32,32,32,32,32,45,32,39, + 109,116,105,109,101,39,32,40,109,97,110,100,97,116,111,114, + 121,41,32,105,115,32,116,104,101,32,110,117,109,101,114,105, + 99,32,116,105,109,101,115,116,97,109,112,32,111,102,32,108, + 97,115,116,32,115,111,117,114,99,101,10,32,32,32,32,32, + 32,32,32,32,32,99,111,100,101,32,109,111,100,105,102,105, + 99,97,116,105,111,110,59,10,32,32,32,32,32,32,32,32, + 45,32,39,115,105,122,101,39,32,40,111,112,116,105,111,110, + 97,108,41,32,105,115,32,116,104,101,32,115,105,122,101,32, + 105,110,32,98,121,116,101,115,32,111,102,32,116,104,101,32, + 115,111,117,114,99,101,32,99,111,100,101,46,10,10,32,32, + 32,32,32,32,32,32,73,109,112,108,101,109,101,110,116,105, + 110,103,32,116,104,105,115,32,109,101,116,104,111,100,32,97, + 108,108,111,119,115,32,116,104,101,32,108,111,97,100,101,114, + 32,116,111,32,114,101,97,100,32,98,121,116,101,99,111,100, + 101,32,102,105,108,101,115,46,10,32,32,32,32,32,32,32, + 32,82,97,105,115,101,115,32,73,79,69,114,114,111,114,32, + 119,104,101,110,32,116,104,101,32,112,97,116,104,32,99,97, + 110,110,111,116,32,98,101,32,104,97,110,100,108,101,100,46, + 10,32,32,32,32,32,32,32,32,114,182,0,0,0,41,1, + 114,35,1,0,0,41,2,114,71,0,0,0,114,35,0,0, 0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, - 114,32,1,0,0,46,6,0,0,115,4,0,0,0,0,2, - 12,1,122,27,83,111,117,114,99,101,70,105,108,101,76,111, - 97,100,101,114,46,112,97,116,104,95,115,116,97,116,115,99, - 4,0,0,0,0,0,0,0,5,0,0,0,5,0,0,0, - 67,0,0,0,115,34,0,0,0,116,0,0,124,1,0,131, - 1,0,125,4,0,124,0,0,106,1,0,124,2,0,124,3, - 0,100,1,0,124,4,0,131,2,1,83,41,2,78,218,5, - 95,109,111,100,101,41,2,114,144,0,0,0,114,33,1,0, - 0,41,5,114,71,0,0,0,114,141,0,0,0,114,140,0, - 0,0,114,53,0,0,0,114,42,0,0,0,114,4,0,0, - 0,114,4,0,0,0,114,5,0,0,0,114,34,1,0,0, - 51,6,0,0,115,4,0,0,0,0,2,12,1,122,32,83, - 111,117,114,99,101,70,105,108,101,76,111,97,100,101,114,46, - 95,99,97,99,104,101,95,98,121,116,101,99,111,100,101,114, - 49,1,0,0,105,182,1,0,0,99,3,0,0,0,1,0, - 0,0,9,0,0,0,18,0,0,0,67,0,0,0,115,53, - 1,0,0,116,0,0,124,1,0,131,1,0,92,2,0,125, - 4,0,125,5,0,103,0,0,125,6,0,120,54,0,124,4, - 0,114,80,0,116,1,0,124,4,0,131,1,0,12,114,80, - 0,116,0,0,124,4,0,131,1,0,92,2,0,125,4,0, - 125,7,0,124,6,0,106,2,0,124,7,0,131,1,0,1, - 113,27,0,87,120,132,0,116,3,0,124,6,0,131,1,0, - 68,93,118,0,125,7,0,116,4,0,124,4,0,124,7,0, - 131,2,0,125,4,0,121,17,0,116,5,0,106,6,0,124, - 4,0,131,1,0,1,87,113,94,0,4,116,7,0,107,10, - 0,114,155,0,1,1,1,119,94,0,89,113,94,0,4,116, - 8,0,107,10,0,114,211,0,1,125,8,0,1,122,25,0, - 116,9,0,100,1,0,124,4,0,124,8,0,131,3,0,1, - 100,2,0,83,87,89,100,2,0,100,2,0,125,8,0,126, - 8,0,88,113,94,0,88,113,94,0,87,121,33,0,116,10, - 0,124,1,0,124,2,0,124,3,0,131,3,0,1,116,9, - 0,100,3,0,124,1,0,131,2,0,1,87,110,53,0,4, - 116,8,0,107,10,0,114,48,1,1,125,8,0,1,122,21, - 0,116,9,0,100,1,0,124,1,0,124,8,0,131,3,0, - 1,87,89,100,2,0,100,2,0,125,8,0,126,8,0,88, - 110,1,0,88,100,2,0,83,41,4,122,27,87,114,105,116, - 101,32,98,121,116,101,115,32,100,97,116,97,32,116,111,32, - 97,32,102,105,108,101,46,122,27,99,111,117,108,100,32,110, - 111,116,32,99,114,101,97,116,101,32,123,33,114,125,58,32, - 123,33,114,125,78,122,12,99,114,101,97,116,101,100,32,123, - 33,114,125,41,11,114,38,0,0,0,114,46,0,0,0,114, - 223,0,0,0,114,33,0,0,0,114,28,0,0,0,114,3, - 0,0,0,90,5,109,107,100,105,114,218,15,70,105,108,101, - 69,120,105,115,116,115,69,114,114,111,114,114,40,0,0,0, - 114,152,0,0,0,114,55,0,0,0,41,9,114,71,0,0, - 0,114,35,0,0,0,114,53,0,0,0,114,49,1,0,0, - 114,231,0,0,0,114,131,0,0,0,114,27,0,0,0,114, - 23,0,0,0,114,36,1,0,0,114,4,0,0,0,114,4, - 0,0,0,114,5,0,0,0,114,33,1,0,0,56,6,0, - 0,115,38,0,0,0,0,2,18,1,6,2,22,1,18,1, - 17,2,19,1,15,1,3,1,17,1,13,2,7,1,18,3, - 16,1,27,1,3,1,16,1,17,1,18,2,122,25,83,111, - 117,114,99,101,70,105,108,101,76,111,97,100,101,114,46,115, - 101,116,95,100,97,116,97,78,41,7,114,57,0,0,0,114, - 56,0,0,0,114,58,0,0,0,114,59,0,0,0,114,32, - 1,0,0,114,34,1,0,0,114,33,1,0,0,114,4,0, + 218,10,112,97,116,104,95,115,116,97,116,115,166,5,0,0, + 115,2,0,0,0,0,11,122,23,83,111,117,114,99,101,76, + 111,97,100,101,114,46,112,97,116,104,95,115,116,97,116,115, + 99,4,0,0,0,0,0,0,0,4,0,0,0,3,0,0, + 0,67,0,0,0,115,16,0,0,0,124,0,0,106,0,0, + 124,2,0,124,3,0,131,2,0,83,41,1,122,228,79,112, + 116,105,111,110,97,108,32,109,101,116,104,111,100,32,119,104, + 105,99,104,32,119,114,105,116,101,115,32,100,97,116,97,32, + 40,98,121,116,101,115,41,32,116,111,32,97,32,102,105,108, + 101,32,112,97,116,104,32,40,97,32,115,116,114,41,46,10, + 10,32,32,32,32,32,32,32,32,73,109,112,108,101,109,101, + 110,116,105,110,103,32,116,104,105,115,32,109,101,116,104,111, + 100,32,97,108,108,111,119,115,32,102,111,114,32,116,104,101, + 32,119,114,105,116,105,110,103,32,111,102,32,98,121,116,101, + 99,111,100,101,32,102,105,108,101,115,46,10,10,32,32,32, + 32,32,32,32,32,84,104,101,32,115,111,117,114,99,101,32, + 112,97,116,104,32,105,115,32,110,101,101,100,101,100,32,105, + 110,32,111,114,100,101,114,32,116,111,32,99,111,114,114,101, + 99,116,108,121,32,116,114,97,110,115,102,101,114,32,112,101, + 114,109,105,115,115,105,111,110,115,10,32,32,32,32,32,32, + 32,32,41,1,218,8,115,101,116,95,100,97,116,97,41,4, + 114,71,0,0,0,114,142,0,0,0,90,10,99,97,99,104, + 101,95,112,97,116,104,114,53,0,0,0,114,4,0,0,0, + 114,4,0,0,0,114,5,0,0,0,218,15,95,99,97,99, + 104,101,95,98,121,116,101,99,111,100,101,179,5,0,0,115, + 2,0,0,0,0,8,122,28,83,111,117,114,99,101,76,111, + 97,100,101,114,46,95,99,97,99,104,101,95,98,121,116,101, + 99,111,100,101,99,3,0,0,0,0,0,0,0,3,0,0, + 0,1,0,0,0,67,0,0,0,115,4,0,0,0,100,1, + 0,83,41,2,122,150,79,112,116,105,111,110,97,108,32,109, + 101,116,104,111,100,32,119,104,105,99,104,32,119,114,105,116, + 101,115,32,100,97,116,97,32,40,98,121,116,101,115,41,32, + 116,111,32,97,32,102,105,108,101,32,112,97,116,104,32,40, + 97,32,115,116,114,41,46,10,10,32,32,32,32,32,32,32, + 32,73,109,112,108,101,109,101,110,116,105,110,103,32,116,104, + 105,115,32,109,101,116,104,111,100,32,97,108,108,111,119,115, + 32,102,111,114,32,116,104,101,32,119,114,105,116,105,110,103, + 32,111,102,32,98,121,116,101,99,111,100,101,32,102,105,108, + 101,115,46,10,32,32,32,32,32,32,32,32,78,114,4,0, + 0,0,41,3,114,71,0,0,0,114,35,0,0,0,114,53, + 0,0,0,114,4,0,0,0,114,4,0,0,0,114,5,0, + 0,0,114,37,1,0,0,189,5,0,0,115,0,0,0,0, + 122,21,83,111,117,114,99,101,76,111,97,100,101,114,46,115, + 101,116,95,100,97,116,97,99,2,0,0,0,0,0,0,0, + 5,0,0,0,16,0,0,0,67,0,0,0,115,105,0,0, + 0,124,0,0,106,0,0,124,1,0,131,1,0,125,2,0, + 121,19,0,124,0,0,106,1,0,124,2,0,131,1,0,125, + 3,0,87,110,58,0,4,116,2,0,107,10,0,114,94,0, + 1,125,4,0,1,122,26,0,116,3,0,100,1,0,100,2, + 0,124,1,0,131,1,1,124,4,0,130,2,0,87,89,100, + 3,0,100,3,0,125,4,0,126,4,0,88,110,1,0,88, + 116,4,0,124,3,0,131,1,0,83,41,4,122,52,67,111, + 110,99,114,101,116,101,32,105,109,112,108,101,109,101,110,116, + 97,116,105,111,110,32,111,102,32,73,110,115,112,101,99,116, + 76,111,97,100,101,114,46,103,101,116,95,115,111,117,114,99, + 101,46,122,39,115,111,117,114,99,101,32,110,111,116,32,97, + 118,97,105,108,97,98,108,101,32,116,104,114,111,117,103,104, + 32,103,101,116,95,100,97,116,97,40,41,114,67,0,0,0, + 78,41,5,114,238,0,0,0,218,8,103,101,116,95,100,97, + 116,97,114,40,0,0,0,114,154,0,0,0,114,202,0,0, + 0,41,5,114,71,0,0,0,114,159,0,0,0,114,35,0, + 0,0,114,200,0,0,0,218,3,101,120,99,114,4,0,0, + 0,114,4,0,0,0,114,5,0,0,0,114,15,1,0,0, + 196,5,0,0,115,14,0,0,0,0,2,15,1,3,1,19, + 1,18,1,9,1,31,1,122,23,83,111,117,114,99,101,76, + 111,97,100,101,114,46,103,101,116,95,115,111,117,114,99,101, + 218,9,95,111,112,116,105,109,105,122,101,114,29,0,0,0, + 99,3,0,0,0,1,0,0,0,4,0,0,0,9,0,0, + 0,67,0,0,0,115,31,0,0,0,116,0,0,116,1,0, + 124,1,0,124,2,0,100,1,0,100,2,0,100,3,0,100, + 4,0,124,3,0,131,4,2,83,41,5,122,130,82,101,116, + 117,114,110,32,116,104,101,32,99,111,100,101,32,111,98,106, + 101,99,116,32,99,111,109,112,105,108,101,100,32,102,114,111, + 109,32,115,111,117,114,99,101,46,10,10,32,32,32,32,32, + 32,32,32,84,104,101,32,39,100,97,116,97,39,32,97,114, + 103,117,109,101,110,116,32,99,97,110,32,98,101,32,97,110, + 121,32,111,98,106,101,99,116,32,116,121,112,101,32,116,104, + 97,116,32,99,111,109,112,105,108,101,40,41,32,115,117,112, + 112,111,114,116,115,46,10,32,32,32,32,32,32,32,32,114, + 21,1,0,0,218,12,100,111,110,116,95,105,110,104,101,114, + 105,116,84,114,118,0,0,0,41,2,114,114,0,0,0,218, + 7,99,111,109,112,105,108,101,41,4,114,71,0,0,0,114, + 53,0,0,0,114,35,0,0,0,114,41,1,0,0,114,4, + 0,0,0,114,4,0,0,0,114,5,0,0,0,218,14,115, + 111,117,114,99,101,95,116,111,95,99,111,100,101,206,5,0, + 0,115,4,0,0,0,0,5,18,1,122,27,83,111,117,114, + 99,101,76,111,97,100,101,114,46,115,111,117,114,99,101,95, + 116,111,95,99,111,100,101,99,2,0,0,0,0,0,0,0, + 10,0,0,0,43,0,0,0,67,0,0,0,115,174,1,0, + 0,124,0,0,106,0,0,124,1,0,131,1,0,125,2,0, + 100,1,0,125,3,0,121,16,0,116,1,0,124,2,0,131, + 1,0,125,4,0,87,110,24,0,4,116,2,0,107,10,0, + 114,63,0,1,1,1,100,1,0,125,4,0,89,110,202,0, + 88,121,19,0,124,0,0,106,3,0,124,2,0,131,1,0, + 125,5,0,87,110,18,0,4,116,4,0,107,10,0,114,103, + 0,1,1,1,89,110,162,0,88,116,5,0,124,5,0,100, + 2,0,25,131,1,0,125,3,0,121,19,0,124,0,0,106, + 6,0,124,4,0,131,1,0,125,6,0,87,110,18,0,4, + 116,7,0,107,10,0,114,159,0,1,1,1,89,110,106,0, + 88,121,34,0,116,8,0,124,6,0,100,3,0,124,5,0, + 100,4,0,124,1,0,100,5,0,124,4,0,131,1,3,125, + 7,0,87,110,24,0,4,116,9,0,116,10,0,102,2,0, + 107,10,0,114,220,0,1,1,1,89,110,45,0,88,116,11, + 0,100,6,0,124,4,0,124,2,0,131,3,0,1,116,12, + 0,124,7,0,100,4,0,124,1,0,100,7,0,124,4,0, + 100,8,0,124,2,0,131,1,3,83,124,0,0,106,6,0, + 124,2,0,131,1,0,125,8,0,124,0,0,106,13,0,124, + 8,0,124,2,0,131,2,0,125,9,0,116,11,0,100,9, + 0,124,2,0,131,2,0,1,116,14,0,106,15,0,12,114, + 170,1,124,4,0,100,1,0,107,9,0,114,170,1,124,3, + 0,100,1,0,107,9,0,114,170,1,116,16,0,124,9,0, + 124,3,0,116,17,0,124,8,0,131,1,0,131,3,0,125, + 6,0,121,36,0,124,0,0,106,18,0,124,2,0,124,4, + 0,124,6,0,131,3,0,1,116,11,0,100,10,0,124,4, + 0,131,2,0,1,87,110,18,0,4,116,2,0,107,10,0, + 114,169,1,1,1,1,89,110,1,0,88,124,9,0,83,41, + 11,122,190,67,111,110,99,114,101,116,101,32,105,109,112,108, + 101,109,101,110,116,97,116,105,111,110,32,111,102,32,73,110, + 115,112,101,99,116,76,111,97,100,101,114,46,103,101,116,95, + 99,111,100,101,46,10,10,32,32,32,32,32,32,32,32,82, + 101,97,100,105,110,103,32,111,102,32,98,121,116,101,99,111, + 100,101,32,114,101,113,117,105,114,101,115,32,112,97,116,104, + 95,115,116,97,116,115,32,116,111,32,98,101,32,105,109,112, + 108,101,109,101,110,116,101,100,46,32,84,111,32,119,114,105, + 116,101,10,32,32,32,32,32,32,32,32,98,121,116,101,99, + 111,100,101,44,32,115,101,116,95,100,97,116,97,32,109,117, + 115,116,32,97,108,115,111,32,98,101,32,105,109,112,108,101, + 109,101,110,116,101,100,46,10,10,32,32,32,32,32,32,32, + 32,78,114,182,0,0,0,114,186,0,0,0,114,67,0,0, + 0,114,35,0,0,0,122,13,123,125,32,109,97,116,99,104, + 101,115,32,123,125,114,141,0,0,0,114,142,0,0,0,122, + 19,99,111,100,101,32,111,98,106,101,99,116,32,102,114,111, + 109,32,123,125,122,10,119,114,111,116,101,32,123,33,114,125, + 41,19,114,238,0,0,0,114,132,0,0,0,114,123,0,0, + 0,114,36,1,0,0,114,34,1,0,0,114,14,0,0,0, + 114,39,1,0,0,114,40,0,0,0,114,189,0,0,0,114, + 154,0,0,0,114,185,0,0,0,114,153,0,0,0,114,194, + 0,0,0,114,44,1,0,0,114,7,0,0,0,218,19,100, + 111,110,116,95,119,114,105,116,101,95,98,121,116,101,99,111, + 100,101,114,197,0,0,0,114,31,0,0,0,114,38,1,0, + 0,41,10,114,71,0,0,0,114,159,0,0,0,114,142,0, + 0,0,114,187,0,0,0,114,141,0,0,0,218,2,115,116, + 114,53,0,0,0,218,10,98,121,116,101,115,95,100,97,116, + 97,114,200,0,0,0,90,11,99,111,100,101,95,111,98,106, + 101,99,116,114,4,0,0,0,114,4,0,0,0,114,5,0, + 0,0,114,14,1,0,0,214,5,0,0,115,78,0,0,0, + 0,7,15,1,6,1,3,1,16,1,13,1,11,2,3,1, + 19,1,13,1,5,2,16,1,3,1,19,1,13,1,5,2, + 3,1,9,1,12,1,13,1,19,1,5,2,9,1,7,1, + 15,1,6,1,7,1,15,1,18,1,13,1,22,1,12,1, + 9,1,15,1,3,1,19,1,17,1,13,1,5,1,122,21, + 83,111,117,114,99,101,76,111,97,100,101,114,46,103,101,116, + 95,99,111,100,101,78,114,139,0,0,0,41,10,114,57,0, + 0,0,114,56,0,0,0,114,58,0,0,0,114,35,1,0, + 0,114,36,1,0,0,114,38,1,0,0,114,37,1,0,0, + 114,15,1,0,0,114,44,1,0,0,114,14,1,0,0,114, + 4,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5, + 0,0,0,114,33,1,0,0,156,5,0,0,115,14,0,0, + 0,12,2,12,8,12,13,12,10,12,7,12,10,18,8,114, + 33,1,0,0,99,0,0,0,0,0,0,0,0,0,0,0, + 0,4,0,0,0,0,0,0,0,115,112,0,0,0,101,0, + 0,90,1,0,100,0,0,90,2,0,100,1,0,90,3,0, + 100,2,0,100,3,0,132,0,0,90,4,0,100,4,0,100, + 5,0,132,0,0,90,5,0,100,6,0,100,7,0,132,0, + 0,90,6,0,101,7,0,135,0,0,102,1,0,100,8,0, + 100,9,0,134,0,0,131,1,0,90,8,0,101,7,0,100, + 10,0,100,11,0,132,0,0,131,1,0,90,9,0,100,12, + 0,100,13,0,132,0,0,90,10,0,135,0,0,83,41,14, + 218,10,70,105,108,101,76,111,97,100,101,114,122,103,66,97, + 115,101,32,102,105,108,101,32,108,111,97,100,101,114,32,99, + 108,97,115,115,32,119,104,105,99,104,32,105,109,112,108,101, + 109,101,110,116,115,32,116,104,101,32,108,111,97,100,101,114, + 32,112,114,111,116,111,99,111,108,32,109,101,116,104,111,100, + 115,32,116,104,97,116,10,32,32,32,32,114,101,113,117,105, + 114,101,32,102,105,108,101,32,115,121,115,116,101,109,32,117, + 115,97,103,101,46,99,3,0,0,0,0,0,0,0,3,0, + 0,0,2,0,0,0,67,0,0,0,115,22,0,0,0,124, + 1,0,124,0,0,95,0,0,124,2,0,124,0,0,95,1, + 0,100,1,0,83,41,2,122,75,67,97,99,104,101,32,116, + 104,101,32,109,111,100,117,108,101,32,110,97,109,101,32,97, + 110,100,32,116,104,101,32,112,97,116,104,32,116,111,32,116, + 104,101,32,102,105,108,101,32,102,111,117,110,100,32,98,121, + 32,116,104,101,10,32,32,32,32,32,32,32,32,102,105,110, + 100,101,114,46,78,41,2,114,67,0,0,0,114,35,0,0, + 0,41,3,114,71,0,0,0,114,159,0,0,0,114,35,0, 0,0,114,4,0,0,0,114,4,0,0,0,114,5,0,0, - 0,114,47,1,0,0,42,6,0,0,115,8,0,0,0,12, - 2,6,2,12,5,12,5,114,47,1,0,0,99,0,0,0, - 0,0,0,0,0,0,0,0,0,2,0,0,0,64,0,0, - 0,115,46,0,0,0,101,0,0,90,1,0,100,0,0,90, - 2,0,100,1,0,90,3,0,100,2,0,100,3,0,132,0, - 0,90,4,0,100,4,0,100,5,0,132,0,0,90,5,0, - 100,6,0,83,41,7,218,20,83,111,117,114,99,101,108,101, - 115,115,70,105,108,101,76,111,97,100,101,114,122,45,76,111, - 97,100,101,114,32,119,104,105,99,104,32,104,97,110,100,108, - 101,115,32,115,111,117,114,99,101,108,101,115,115,32,102,105, - 108,101,32,105,109,112,111,114,116,115,46,99,2,0,0,0, - 0,0,0,0,5,0,0,0,6,0,0,0,67,0,0,0, - 115,76,0,0,0,124,0,0,106,0,0,124,1,0,131,1, - 0,125,2,0,124,0,0,106,1,0,124,2,0,131,1,0, - 125,3,0,116,2,0,124,3,0,100,1,0,124,1,0,100, - 2,0,124,2,0,131,1,2,125,4,0,116,3,0,124,4, - 0,100,1,0,124,1,0,100,3,0,124,2,0,131,1,2, - 83,41,4,78,114,67,0,0,0,114,35,0,0,0,114,140, - 0,0,0,41,4,114,234,0,0,0,114,35,1,0,0,114, - 190,0,0,0,114,195,0,0,0,41,5,114,71,0,0,0, - 114,158,0,0,0,114,35,0,0,0,114,53,0,0,0,114, - 43,1,0,0,114,4,0,0,0,114,4,0,0,0,114,5, - 0,0,0,114,12,1,0,0,89,6,0,0,115,8,0,0, - 0,0,1,15,1,15,1,24,1,122,29,83,111,117,114,99, - 101,108,101,115,115,70,105,108,101,76,111,97,100,101,114,46, - 103,101,116,95,99,111,100,101,99,2,0,0,0,0,0,0, - 0,2,0,0,0,1,0,0,0,67,0,0,0,115,4,0, - 0,0,100,1,0,83,41,2,122,39,82,101,116,117,114,110, - 32,78,111,110,101,32,97,115,32,116,104,101,114,101,32,105, - 115,32,110,111,32,115,111,117,114,99,101,32,99,111,100,101, - 46,78,114,4,0,0,0,41,2,114,71,0,0,0,114,158, + 0,114,72,0,0,0,15,6,0,0,115,4,0,0,0,0, + 3,9,1,122,19,70,105,108,101,76,111,97,100,101,114,46, + 95,95,105,110,105,116,95,95,99,2,0,0,0,0,0,0, + 0,2,0,0,0,2,0,0,0,67,0,0,0,115,34,0, + 0,0,124,0,0,106,0,0,124,1,0,106,0,0,107,2, + 0,111,33,0,124,0,0,106,1,0,124,1,0,106,1,0, + 107,2,0,83,41,1,78,41,2,114,224,0,0,0,114,63, + 0,0,0,41,2,114,71,0,0,0,114,227,0,0,0,114, + 4,0,0,0,114,4,0,0,0,114,5,0,0,0,114,229, + 0,0,0,21,6,0,0,115,4,0,0,0,0,1,18,1, + 122,17,70,105,108,101,76,111,97,100,101,114,46,95,95,101, + 113,95,95,99,1,0,0,0,0,0,0,0,1,0,0,0, + 3,0,0,0,67,0,0,0,115,26,0,0,0,116,0,0, + 124,0,0,106,1,0,131,1,0,116,0,0,124,0,0,106, + 2,0,131,1,0,65,83,41,1,78,41,3,218,4,104,97, + 115,104,114,67,0,0,0,114,35,0,0,0,41,1,114,71, 0,0,0,114,4,0,0,0,114,4,0,0,0,114,5,0, - 0,0,114,13,1,0,0,95,6,0,0,115,2,0,0,0, - 0,2,122,31,83,111,117,114,99,101,108,101,115,115,70,105, - 108,101,76,111,97,100,101,114,46,103,101,116,95,115,111,117, - 114,99,101,78,41,6,114,57,0,0,0,114,56,0,0,0, - 114,58,0,0,0,114,59,0,0,0,114,12,1,0,0,114, - 13,1,0,0,114,4,0,0,0,114,4,0,0,0,114,4, - 0,0,0,114,5,0,0,0,114,51,1,0,0,85,6,0, - 0,115,6,0,0,0,12,2,6,2,12,6,114,51,1,0, - 0,99,0,0,0,0,0,0,0,0,0,0,0,0,3,0, - 0,0,64,0,0,0,115,106,0,0,0,101,0,0,90,1, + 0,0,218,8,95,95,104,97,115,104,95,95,25,6,0,0, + 115,2,0,0,0,0,1,122,19,70,105,108,101,76,111,97, + 100,101,114,46,95,95,104,97,115,104,95,95,99,2,0,0, + 0,0,0,0,0,2,0,0,0,3,0,0,0,3,0,0, + 0,115,22,0,0,0,116,0,0,116,1,0,124,0,0,131, + 2,0,106,2,0,124,1,0,131,1,0,83,41,1,122,100, + 76,111,97,100,32,97,32,109,111,100,117,108,101,32,102,114, + 111,109,32,97,32,102,105,108,101,46,10,10,32,32,32,32, + 32,32,32,32,84,104,105,115,32,109,101,116,104,111,100,32, + 105,115,32,100,101,112,114,101,99,97,116,101,100,46,32,32, + 85,115,101,32,101,120,101,99,95,109,111,100,117,108,101,40, + 41,32,105,110,115,116,101,97,100,46,10,10,32,32,32,32, + 32,32,32,32,41,3,218,5,115,117,112,101,114,114,48,1, + 0,0,114,3,1,0,0,41,2,114,71,0,0,0,114,159, + 0,0,0,41,1,114,224,0,0,0,114,4,0,0,0,114, + 5,0,0,0,114,3,1,0,0,28,6,0,0,115,2,0, + 0,0,0,10,122,22,70,105,108,101,76,111,97,100,101,114, + 46,108,111,97,100,95,109,111,100,117,108,101,99,2,0,0, + 0,0,0,0,0,2,0,0,0,1,0,0,0,67,0,0, + 0,115,7,0,0,0,124,0,0,106,0,0,83,41,1,122, + 58,82,101,116,117,114,110,32,116,104,101,32,112,97,116,104, + 32,116,111,32,116,104,101,32,115,111,117,114,99,101,32,102, + 105,108,101,32,97,115,32,102,111,117,110,100,32,98,121,32, + 116,104,101,32,102,105,110,100,101,114,46,41,1,114,35,0, + 0,0,41,2,114,71,0,0,0,114,159,0,0,0,114,4, + 0,0,0,114,4,0,0,0,114,5,0,0,0,114,238,0, + 0,0,40,6,0,0,115,2,0,0,0,0,3,122,23,70, + 105,108,101,76,111,97,100,101,114,46,103,101,116,95,102,105, + 108,101,110,97,109,101,99,2,0,0,0,0,0,0,0,3, + 0,0,0,8,0,0,0,67,0,0,0,115,41,0,0,0, + 116,0,0,106,1,0,124,1,0,100,1,0,131,2,0,143, + 17,0,125,2,0,124,2,0,106,2,0,131,0,0,83,87, + 100,2,0,81,88,100,2,0,83,41,3,122,39,82,101,116, + 117,114,110,32,116,104,101,32,100,97,116,97,32,102,114,111, + 109,32,112,97,116,104,32,97,115,32,114,97,119,32,98,121, + 116,101,115,46,218,1,114,78,41,3,114,49,0,0,0,114, + 50,0,0,0,90,4,114,101,97,100,41,3,114,71,0,0, + 0,114,35,0,0,0,114,54,0,0,0,114,4,0,0,0, + 114,4,0,0,0,114,5,0,0,0,114,39,1,0,0,45, + 6,0,0,115,4,0,0,0,0,2,21,1,122,19,70,105, + 108,101,76,111,97,100,101,114,46,103,101,116,95,100,97,116, + 97,41,11,114,57,0,0,0,114,56,0,0,0,114,58,0, + 0,0,114,59,0,0,0,114,72,0,0,0,114,229,0,0, + 0,114,50,1,0,0,114,157,0,0,0,114,3,1,0,0, + 114,238,0,0,0,114,39,1,0,0,114,4,0,0,0,114, + 4,0,0,0,41,1,114,224,0,0,0,114,5,0,0,0, + 114,48,1,0,0,10,6,0,0,115,14,0,0,0,12,3, + 6,2,12,6,12,4,12,3,24,12,18,5,114,48,1,0, + 0,99,0,0,0,0,0,0,0,0,0,0,0,0,4,0, + 0,0,64,0,0,0,115,64,0,0,0,101,0,0,90,1, 0,100,0,0,90,2,0,100,1,0,90,3,0,100,2,0, - 100,3,0,132,0,0,90,4,0,101,5,0,100,4,0,100, - 5,0,132,0,0,131,1,0,90,6,0,100,6,0,100,7, - 0,132,0,0,90,7,0,100,8,0,100,9,0,132,0,0, - 90,8,0,100,10,0,100,11,0,132,0,0,90,9,0,101, - 5,0,100,12,0,100,13,0,132,0,0,131,1,0,90,10, - 0,100,14,0,83,41,15,218,19,69,120,116,101,110,115,105, + 100,3,0,132,0,0,90,4,0,100,4,0,100,5,0,132, + 0,0,90,5,0,100,6,0,100,7,0,100,8,0,100,9, + 0,132,0,1,90,6,0,100,10,0,83,41,11,114,7,1, + 0,0,122,62,67,111,110,99,114,101,116,101,32,105,109,112, + 108,101,109,101,110,116,97,116,105,111,110,32,111,102,32,83, + 111,117,114,99,101,76,111,97,100,101,114,32,117,115,105,110, + 103,32,116,104,101,32,102,105,108,101,32,115,121,115,116,101, + 109,46,99,2,0,0,0,0,0,0,0,3,0,0,0,3, + 0,0,0,67,0,0,0,115,36,0,0,0,116,0,0,124, + 1,0,131,1,0,125,2,0,105,2,0,124,2,0,106,1, + 0,100,1,0,54,124,2,0,106,2,0,100,2,0,54,83, + 41,3,122,33,82,101,116,117,114,110,32,116,104,101,32,109, + 101,116,97,100,97,116,97,32,102,111,114,32,116,104,101,32, + 112,97,116,104,46,114,182,0,0,0,114,183,0,0,0,41, + 3,114,39,0,0,0,218,8,115,116,95,109,116,105,109,101, + 90,7,115,116,95,115,105,122,101,41,3,114,71,0,0,0, + 114,35,0,0,0,114,46,1,0,0,114,4,0,0,0,114, + 4,0,0,0,114,5,0,0,0,114,36,1,0,0,55,6, + 0,0,115,4,0,0,0,0,2,12,1,122,27,83,111,117, + 114,99,101,70,105,108,101,76,111,97,100,101,114,46,112,97, + 116,104,95,115,116,97,116,115,99,4,0,0,0,0,0,0, + 0,5,0,0,0,5,0,0,0,67,0,0,0,115,34,0, + 0,0,116,0,0,124,1,0,131,1,0,125,4,0,124,0, + 0,106,1,0,124,2,0,124,3,0,100,1,0,124,4,0, + 131,2,1,83,41,2,78,218,5,95,109,111,100,101,41,2, + 114,145,0,0,0,114,37,1,0,0,41,5,114,71,0,0, + 0,114,142,0,0,0,114,141,0,0,0,114,53,0,0,0, + 114,42,0,0,0,114,4,0,0,0,114,4,0,0,0,114, + 5,0,0,0,114,38,1,0,0,60,6,0,0,115,4,0, + 0,0,0,2,12,1,122,32,83,111,117,114,99,101,70,105, + 108,101,76,111,97,100,101,114,46,95,99,97,99,104,101,95, + 98,121,116,101,99,111,100,101,114,54,1,0,0,105,182,1, + 0,0,99,3,0,0,0,1,0,0,0,9,0,0,0,17, + 0,0,0,67,0,0,0,115,53,1,0,0,116,0,0,124, + 1,0,131,1,0,92,2,0,125,4,0,125,5,0,103,0, + 0,125,6,0,120,54,0,124,4,0,114,80,0,116,1,0, + 124,4,0,131,1,0,12,114,80,0,116,0,0,124,4,0, + 131,1,0,92,2,0,125,4,0,125,7,0,124,6,0,106, + 2,0,124,7,0,131,1,0,1,113,27,0,87,120,132,0, + 116,3,0,124,6,0,131,1,0,68,93,118,0,125,7,0, + 116,4,0,124,4,0,124,7,0,131,2,0,125,4,0,121, + 17,0,116,5,0,106,6,0,124,4,0,131,1,0,1,87, + 113,94,0,4,116,7,0,107,10,0,114,155,0,1,1,1, + 119,94,0,89,113,94,0,4,116,8,0,107,10,0,114,211, + 0,1,125,8,0,1,122,25,0,116,9,0,100,1,0,124, + 4,0,124,8,0,131,3,0,1,100,2,0,83,87,89,100, + 2,0,100,2,0,125,8,0,126,8,0,88,113,94,0,88, + 113,94,0,87,121,33,0,116,10,0,124,1,0,124,2,0, + 124,3,0,131,3,0,1,116,9,0,100,3,0,124,1,0, + 131,2,0,1,87,110,53,0,4,116,8,0,107,10,0,114, + 48,1,1,125,8,0,1,122,21,0,116,9,0,100,1,0, + 124,1,0,124,8,0,131,3,0,1,87,89,100,2,0,100, + 2,0,125,8,0,126,8,0,88,110,1,0,88,100,2,0, + 83,41,4,122,27,87,114,105,116,101,32,98,121,116,101,115, + 32,100,97,116,97,32,116,111,32,97,32,102,105,108,101,46, + 122,27,99,111,117,108,100,32,110,111,116,32,99,114,101,97, + 116,101,32,123,33,114,125,58,32,123,33,114,125,78,122,12, + 99,114,101,97,116,101,100,32,123,33,114,125,41,11,114,38, + 0,0,0,114,46,0,0,0,114,223,0,0,0,114,33,0, + 0,0,114,28,0,0,0,114,3,0,0,0,90,5,109,107, + 100,105,114,218,15,70,105,108,101,69,120,105,115,116,115,69, + 114,114,111,114,114,40,0,0,0,114,153,0,0,0,114,55, + 0,0,0,41,9,114,71,0,0,0,114,35,0,0,0,114, + 53,0,0,0,114,54,1,0,0,114,233,0,0,0,114,131, + 0,0,0,114,27,0,0,0,114,23,0,0,0,114,40,1, + 0,0,114,4,0,0,0,114,4,0,0,0,114,5,0,0, + 0,114,37,1,0,0,65,6,0,0,115,38,0,0,0,0, + 2,18,1,6,2,22,1,18,1,17,2,19,1,15,1,3, + 1,17,1,13,2,7,1,18,3,16,1,27,1,3,1,16, + 1,17,1,18,2,122,25,83,111,117,114,99,101,70,105,108, + 101,76,111,97,100,101,114,46,115,101,116,95,100,97,116,97, + 78,41,7,114,57,0,0,0,114,56,0,0,0,114,58,0, + 0,0,114,59,0,0,0,114,36,1,0,0,114,38,1,0, + 0,114,37,1,0,0,114,4,0,0,0,114,4,0,0,0, + 114,4,0,0,0,114,5,0,0,0,114,7,1,0,0,51, + 6,0,0,115,8,0,0,0,12,2,6,2,12,5,12,5, + 114,7,1,0,0,99,0,0,0,0,0,0,0,0,0,0, + 0,0,2,0,0,0,64,0,0,0,115,46,0,0,0,101, + 0,0,90,1,0,100,0,0,90,2,0,100,1,0,90,3, + 0,100,2,0,100,3,0,132,0,0,90,4,0,100,4,0, + 100,5,0,132,0,0,90,5,0,100,6,0,83,41,7,114, + 6,1,0,0,122,45,76,111,97,100,101,114,32,119,104,105, + 99,104,32,104,97,110,100,108,101,115,32,115,111,117,114,99, + 101,108,101,115,115,32,102,105,108,101,32,105,109,112,111,114, + 116,115,46,99,2,0,0,0,0,0,0,0,5,0,0,0, + 6,0,0,0,67,0,0,0,115,76,0,0,0,124,0,0, + 106,0,0,124,1,0,131,1,0,125,2,0,124,0,0,106, + 1,0,124,2,0,131,1,0,125,3,0,116,2,0,124,3, + 0,100,1,0,124,1,0,100,2,0,124,2,0,131,1,2, + 125,4,0,116,3,0,124,4,0,100,1,0,124,1,0,100, + 3,0,124,2,0,131,1,2,83,41,4,78,114,67,0,0, + 0,114,35,0,0,0,114,141,0,0,0,41,4,114,238,0, + 0,0,114,39,1,0,0,114,189,0,0,0,114,194,0,0, + 0,41,5,114,71,0,0,0,114,159,0,0,0,114,35,0, + 0,0,114,53,0,0,0,114,47,1,0,0,114,4,0,0, + 0,114,4,0,0,0,114,5,0,0,0,114,14,1,0,0, + 98,6,0,0,115,8,0,0,0,0,1,15,1,15,1,24, + 1,122,29,83,111,117,114,99,101,108,101,115,115,70,105,108, + 101,76,111,97,100,101,114,46,103,101,116,95,99,111,100,101, + 99,2,0,0,0,0,0,0,0,2,0,0,0,1,0,0, + 0,67,0,0,0,115,4,0,0,0,100,1,0,83,41,2, + 122,39,82,101,116,117,114,110,32,78,111,110,101,32,97,115, + 32,116,104,101,114,101,32,105,115,32,110,111,32,115,111,117, + 114,99,101,32,99,111,100,101,46,78,114,4,0,0,0,41, + 2,114,71,0,0,0,114,159,0,0,0,114,4,0,0,0, + 114,4,0,0,0,114,5,0,0,0,114,15,1,0,0,104, + 6,0,0,115,2,0,0,0,0,2,122,31,83,111,117,114, + 99,101,108,101,115,115,70,105,108,101,76,111,97,100,101,114, + 46,103,101,116,95,115,111,117,114,99,101,78,41,6,114,57, + 0,0,0,114,56,0,0,0,114,58,0,0,0,114,59,0, + 0,0,114,14,1,0,0,114,15,1,0,0,114,4,0,0, + 0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, + 114,6,1,0,0,94,6,0,0,115,6,0,0,0,12,2, + 6,2,12,6,114,6,1,0,0,99,0,0,0,0,0,0, + 0,0,0,0,0,0,3,0,0,0,64,0,0,0,115,130, + 0,0,0,101,0,0,90,1,0,100,0,0,90,2,0,100, + 1,0,90,3,0,100,2,0,100,3,0,132,0,0,90,4, + 0,100,4,0,100,5,0,132,0,0,90,5,0,100,6,0, + 100,7,0,132,0,0,90,6,0,101,7,0,100,8,0,100, + 9,0,132,0,0,131,1,0,90,8,0,100,10,0,100,11, + 0,132,0,0,90,9,0,100,12,0,100,13,0,132,0,0, + 90,10,0,100,14,0,100,15,0,132,0,0,90,11,0,101, + 7,0,100,16,0,100,17,0,132,0,0,131,1,0,90,12, + 0,100,18,0,83,41,19,218,19,69,120,116,101,110,115,105, 111,110,70,105,108,101,76,111,97,100,101,114,122,93,76,111, 97,100,101,114,32,102,111,114,32,101,120,116,101,110,115,105, 111,110,32,109,111,100,117,108,101,115,46,10,10,32,32,32, @@ -2878,922 +2852,984 @@ const unsigned char _Py_M__importlib[] = { 0,124,0,0,95,1,0,100,0,0,83,41,1,78,41,2, 114,67,0,0,0,114,35,0,0,0,41,3,114,71,0,0, 0,114,67,0,0,0,114,35,0,0,0,114,4,0,0,0, - 114,4,0,0,0,114,5,0,0,0,114,72,0,0,0,112, + 114,4,0,0,0,114,5,0,0,0,114,72,0,0,0,121, 6,0,0,115,4,0,0,0,0,1,9,1,122,28,69,120, 116,101,110,115,105,111,110,70,105,108,101,76,111,97,100,101, 114,46,95,95,105,110,105,116,95,95,99,2,0,0,0,0, + 0,0,0,2,0,0,0,2,0,0,0,67,0,0,0,115, + 34,0,0,0,124,0,0,106,0,0,124,1,0,106,0,0, + 107,2,0,111,33,0,124,0,0,106,1,0,124,1,0,106, + 1,0,107,2,0,83,41,1,78,41,2,114,224,0,0,0, + 114,63,0,0,0,41,2,114,71,0,0,0,114,227,0,0, + 0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, + 114,229,0,0,0,125,6,0,0,115,4,0,0,0,0,1, + 18,1,122,26,69,120,116,101,110,115,105,111,110,70,105,108, + 101,76,111,97,100,101,114,46,95,95,101,113,95,95,99,1, + 0,0,0,0,0,0,0,1,0,0,0,3,0,0,0,67, + 0,0,0,115,26,0,0,0,116,0,0,124,0,0,106,1, + 0,131,1,0,116,0,0,124,0,0,106,2,0,131,1,0, + 65,83,41,1,78,41,3,114,49,1,0,0,114,67,0,0, + 0,114,35,0,0,0,41,1,114,71,0,0,0,114,4,0, + 0,0,114,4,0,0,0,114,5,0,0,0,114,50,1,0, + 0,129,6,0,0,115,2,0,0,0,0,1,122,28,69,120, + 116,101,110,115,105,111,110,70,105,108,101,76,111,97,100,101, + 114,46,95,95,104,97,115,104,95,95,99,2,0,0,0,0, 0,0,0,4,0,0,0,11,0,0,0,67,0,0,0,115, - 183,0,0,0,116,0,0,124,1,0,131,1,0,143,29,0, + 177,0,0,0,116,0,0,124,1,0,131,1,0,143,29,0, 1,116,1,0,116,2,0,106,3,0,124,1,0,124,0,0, 106,4,0,131,3,0,125,2,0,87,100,1,0,81,88,116, 5,0,100,2,0,124,0,0,106,4,0,131,2,0,1,124, 0,0,106,6,0,124,1,0,131,1,0,125,3,0,124,3, - 0,114,124,0,116,7,0,124,2,0,100,3,0,131,2,0, - 12,114,124,0,116,8,0,124,0,0,106,4,0,131,1,0, - 100,4,0,25,103,1,0,124,2,0,95,9,0,110,0,0, - 124,0,0,124,2,0,95,10,0,124,2,0,106,11,0,124, - 2,0,95,12,0,124,3,0,115,179,0,124,2,0,106,12, - 0,106,13,0,100,5,0,131,1,0,100,4,0,25,124,2, - 0,95,12,0,110,0,0,124,2,0,83,41,6,122,25,76, - 111,97,100,32,97,110,32,101,120,116,101,110,115,105,111,110, - 32,109,111,100,117,108,101,46,78,122,33,101,120,116,101,110, - 115,105,111,110,32,109,111,100,117,108,101,32,108,111,97,100, - 101,100,32,102,114,111,109,32,123,33,114,125,114,242,0,0, - 0,114,84,0,0,0,114,116,0,0,0,41,14,114,69,0, - 0,0,114,114,0,0,0,114,106,0,0,0,90,12,108,111, - 97,100,95,100,121,110,97,109,105,99,114,35,0,0,0,114, - 152,0,0,0,114,219,0,0,0,114,60,0,0,0,114,38, - 0,0,0,114,242,0,0,0,114,204,0,0,0,114,57,0, - 0,0,114,249,0,0,0,114,32,0,0,0,41,4,114,71, - 0,0,0,114,158,0,0,0,114,179,0,0,0,114,219,0, - 0,0,114,4,0,0,0,114,4,0,0,0,114,5,0,0, - 0,114,3,1,0,0,116,6,0,0,115,24,0,0,0,0, - 3,13,1,9,1,21,1,16,1,15,1,22,1,28,1,9, - 1,12,1,6,1,28,1,122,31,69,120,116,101,110,115,105, - 111,110,70,105,108,101,76,111,97,100,101,114,46,108,111,97, - 100,95,109,111,100,117,108,101,99,2,0,0,0,0,0,0, - 0,2,0,0,0,4,0,0,0,3,0,0,0,115,48,0, - 0,0,116,0,0,124,0,0,106,1,0,131,1,0,100,1, - 0,25,137,0,0,116,2,0,135,0,0,102,1,0,100,2, - 0,100,3,0,134,0,0,116,3,0,68,131,1,0,131,1, - 0,83,41,4,122,49,82,101,116,117,114,110,32,84,114,117, - 101,32,105,102,32,116,104,101,32,101,120,116,101,110,115,105, - 111,110,32,109,111,100,117,108,101,32,105,115,32,97,32,112, - 97,99,107,97,103,101,46,114,29,0,0,0,99,1,0,0, - 0,0,0,0,0,2,0,0,0,4,0,0,0,51,0,0, - 0,115,31,0,0,0,124,0,0,93,21,0,125,1,0,136, - 0,0,100,0,0,124,1,0,23,107,2,0,86,1,113,3, - 0,100,1,0,83,41,2,114,72,0,0,0,78,114,4,0, - 0,0,41,2,114,22,0,0,0,218,6,115,117,102,102,105, - 120,41,1,218,9,102,105,108,101,95,110,97,109,101,114,4, - 0,0,0,114,5,0,0,0,114,77,0,0,0,135,6,0, - 0,115,2,0,0,0,6,1,122,49,69,120,116,101,110,115, - 105,111,110,70,105,108,101,76,111,97,100,101,114,46,105,115, - 95,112,97,99,107,97,103,101,46,60,108,111,99,97,108,115, - 62,46,60,103,101,110,101,120,112,114,62,41,4,114,38,0, - 0,0,114,35,0,0,0,114,78,0,0,0,218,18,69,88, - 84,69,78,83,73,79,78,95,83,85,70,70,73,88,69,83, - 41,2,114,71,0,0,0,114,158,0,0,0,114,4,0,0, - 0,41,1,114,54,1,0,0,114,5,0,0,0,114,219,0, - 0,0,132,6,0,0,115,6,0,0,0,0,2,19,1,18, - 1,122,30,69,120,116,101,110,115,105,111,110,70,105,108,101, - 76,111,97,100,101,114,46,105,115,95,112,97,99,107,97,103, - 101,99,2,0,0,0,0,0,0,0,2,0,0,0,1,0, - 0,0,67,0,0,0,115,4,0,0,0,100,1,0,83,41, - 2,122,63,82,101,116,117,114,110,32,78,111,110,101,32,97, - 115,32,97,110,32,101,120,116,101,110,115,105,111,110,32,109, - 111,100,117,108,101,32,99,97,110,110,111,116,32,99,114,101, - 97,116,101,32,97,32,99,111,100,101,32,111,98,106,101,99, - 116,46,78,114,4,0,0,0,41,2,114,71,0,0,0,114, - 158,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5, - 0,0,0,114,12,1,0,0,138,6,0,0,115,2,0,0, - 0,0,2,122,28,69,120,116,101,110,115,105,111,110,70,105, - 108,101,76,111,97,100,101,114,46,103,101,116,95,99,111,100, - 101,99,2,0,0,0,0,0,0,0,2,0,0,0,1,0, - 0,0,67,0,0,0,115,4,0,0,0,100,1,0,83,41, - 2,122,53,82,101,116,117,114,110,32,78,111,110,101,32,97, - 115,32,101,120,116,101,110,115,105,111,110,32,109,111,100,117, - 108,101,115,32,104,97,118,101,32,110,111,32,115,111,117,114, - 99,101,32,99,111,100,101,46,78,114,4,0,0,0,41,2, - 114,71,0,0,0,114,158,0,0,0,114,4,0,0,0,114, - 4,0,0,0,114,5,0,0,0,114,13,1,0,0,142,6, - 0,0,115,2,0,0,0,0,2,122,30,69,120,116,101,110, - 115,105,111,110,70,105,108,101,76,111,97,100,101,114,46,103, - 101,116,95,115,111,117,114,99,101,99,2,0,0,0,0,0, - 0,0,2,0,0,0,1,0,0,0,67,0,0,0,115,7, - 0,0,0,124,0,0,106,0,0,83,41,1,122,58,82,101, - 116,117,114,110,32,116,104,101,32,112,97,116,104,32,116,111, - 32,116,104,101,32,115,111,117,114,99,101,32,102,105,108,101, - 32,97,115,32,102,111,117,110,100,32,98,121,32,116,104,101, - 32,102,105,110,100,101,114,46,41,1,114,35,0,0,0,41, - 2,114,71,0,0,0,114,158,0,0,0,114,4,0,0,0, - 114,4,0,0,0,114,5,0,0,0,114,234,0,0,0,146, - 6,0,0,115,2,0,0,0,0,3,122,32,69,120,116,101, - 110,115,105,111,110,70,105,108,101,76,111,97,100,101,114,46, - 103,101,116,95,102,105,108,101,110,97,109,101,78,41,11,114, - 57,0,0,0,114,56,0,0,0,114,58,0,0,0,114,59, - 0,0,0,114,72,0,0,0,114,156,0,0,0,114,3,1, - 0,0,114,219,0,0,0,114,12,1,0,0,114,13,1,0, - 0,114,234,0,0,0,114,4,0,0,0,114,4,0,0,0, - 114,4,0,0,0,114,5,0,0,0,114,52,1,0,0,104, - 6,0,0,115,14,0,0,0,12,6,6,2,12,4,18,16, - 12,6,12,4,12,4,114,52,1,0,0,99,0,0,0,0, - 0,0,0,0,0,0,0,0,2,0,0,0,64,0,0,0, - 115,130,0,0,0,101,0,0,90,1,0,100,0,0,90,2, - 0,100,1,0,90,3,0,100,2,0,100,3,0,132,0,0, - 90,4,0,100,4,0,100,5,0,132,0,0,90,5,0,100, - 6,0,100,7,0,132,0,0,90,6,0,100,8,0,100,9, - 0,132,0,0,90,7,0,100,10,0,100,11,0,132,0,0, - 90,8,0,100,12,0,100,13,0,132,0,0,90,9,0,100, - 14,0,100,15,0,132,0,0,90,10,0,100,16,0,100,17, - 0,132,0,0,90,11,0,100,18,0,100,19,0,132,0,0, - 90,12,0,100,20,0,83,41,21,218,14,95,78,97,109,101, - 115,112,97,99,101,80,97,116,104,97,38,1,0,0,82,101, - 112,114,101,115,101,110,116,115,32,97,32,110,97,109,101,115, - 112,97,99,101,32,112,97,99,107,97,103,101,39,115,32,112, - 97,116,104,46,32,32,73,116,32,117,115,101,115,32,116,104, - 101,32,109,111,100,117,108,101,32,110,97,109,101,10,32,32, - 32,32,116,111,32,102,105,110,100,32,105,116,115,32,112,97, - 114,101,110,116,32,109,111,100,117,108,101,44,32,97,110,100, - 32,102,114,111,109,32,116,104,101,114,101,32,105,116,32,108, - 111,111,107,115,32,117,112,32,116,104,101,32,112,97,114,101, - 110,116,39,115,10,32,32,32,32,95,95,112,97,116,104,95, - 95,46,32,32,87,104,101,110,32,116,104,105,115,32,99,104, - 97,110,103,101,115,44,32,116,104,101,32,109,111,100,117,108, - 101,39,115,32,111,119,110,32,112,97,116,104,32,105,115,32, - 114,101,99,111,109,112,117,116,101,100,44,10,32,32,32,32, - 117,115,105,110,103,32,112,97,116,104,95,102,105,110,100,101, - 114,46,32,32,70,111,114,32,116,111,112,45,108,101,118,101, - 108,32,109,111,100,117,108,101,115,44,32,116,104,101,32,112, - 97,114,101,110,116,32,109,111,100,117,108,101,39,115,32,112, - 97,116,104,10,32,32,32,32,105,115,32,115,121,115,46,112, - 97,116,104,46,99,4,0,0,0,0,0,0,0,4,0,0, - 0,2,0,0,0,67,0,0,0,115,52,0,0,0,124,1, - 0,124,0,0,95,0,0,124,2,0,124,0,0,95,1,0, - 116,2,0,124,0,0,106,3,0,131,0,0,131,1,0,124, - 0,0,95,4,0,124,3,0,124,0,0,95,5,0,100,0, - 0,83,41,1,78,41,6,114,70,0,0,0,114,252,0,0, - 0,114,229,0,0,0,218,16,95,103,101,116,95,112,97,114, - 101,110,116,95,112,97,116,104,218,17,95,108,97,115,116,95, - 112,97,114,101,110,116,95,112,97,116,104,218,12,95,112,97, - 116,104,95,102,105,110,100,101,114,41,4,114,71,0,0,0, - 114,67,0,0,0,114,35,0,0,0,218,11,112,97,116,104, - 95,102,105,110,100,101,114,114,4,0,0,0,114,4,0,0, - 0,114,5,0,0,0,114,72,0,0,0,159,6,0,0,115, - 8,0,0,0,0,1,9,1,9,1,21,1,122,23,95,78, - 97,109,101,115,112,97,99,101,80,97,116,104,46,95,95,105, - 110,105,116,95,95,99,1,0,0,0,0,0,0,0,4,0, - 0,0,3,0,0,0,67,0,0,0,115,53,0,0,0,124, - 0,0,106,0,0,106,1,0,100,1,0,131,1,0,92,3, - 0,125,1,0,125,2,0,125,3,0,124,2,0,100,2,0, - 107,2,0,114,43,0,100,6,0,83,124,1,0,100,5,0, - 102,2,0,83,41,7,122,62,82,101,116,117,114,110,115,32, - 97,32,116,117,112,108,101,32,111,102,32,40,112,97,114,101, - 110,116,45,109,111,100,117,108,101,45,110,97,109,101,44,32, - 112,97,114,101,110,116,45,112,97,116,104,45,97,116,116,114, - 45,110,97,109,101,41,114,116,0,0,0,114,30,0,0,0, - 114,7,0,0,0,114,35,0,0,0,114,242,0,0,0,41, - 2,122,3,115,121,115,122,4,112,97,116,104,41,2,114,70, - 0,0,0,114,32,0,0,0,41,4,114,71,0,0,0,114, - 231,0,0,0,218,3,100,111,116,114,94,0,0,0,114,4, - 0,0,0,114,4,0,0,0,114,5,0,0,0,218,23,95, - 102,105,110,100,95,112,97,114,101,110,116,95,112,97,116,104, - 95,110,97,109,101,115,165,6,0,0,115,8,0,0,0,0, - 2,27,1,12,2,4,3,122,38,95,78,97,109,101,115,112, - 97,99,101,80,97,116,104,46,95,102,105,110,100,95,112,97, - 114,101,110,116,95,112,97,116,104,95,110,97,109,101,115,99, - 1,0,0,0,0,0,0,0,3,0,0,0,3,0,0,0, - 67,0,0,0,115,38,0,0,0,124,0,0,106,0,0,131, - 0,0,92,2,0,125,1,0,125,2,0,116,1,0,116,2, - 0,106,3,0,124,1,0,25,124,2,0,131,2,0,83,41, - 1,78,41,4,114,62,1,0,0,114,62,0,0,0,114,7, - 0,0,0,114,73,0,0,0,41,3,114,71,0,0,0,90, - 18,112,97,114,101,110,116,95,109,111,100,117,108,101,95,110, - 97,109,101,90,14,112,97,116,104,95,97,116,116,114,95,110, - 97,109,101,114,4,0,0,0,114,4,0,0,0,114,5,0, - 0,0,114,57,1,0,0,175,6,0,0,115,4,0,0,0, - 0,1,18,1,122,31,95,78,97,109,101,115,112,97,99,101, - 80,97,116,104,46,95,103,101,116,95,112,97,114,101,110,116, - 95,112,97,116,104,99,1,0,0,0,0,0,0,0,3,0, - 0,0,3,0,0,0,67,0,0,0,115,127,0,0,0,116, - 0,0,124,0,0,106,1,0,131,0,0,131,1,0,125,1, - 0,124,1,0,124,0,0,106,2,0,107,3,0,114,120,0, - 124,0,0,106,3,0,124,0,0,106,4,0,124,1,0,131, - 2,0,125,2,0,124,2,0,100,0,0,107,9,0,114,108, - 0,124,2,0,106,5,0,100,0,0,107,8,0,114,108,0, - 124,2,0,106,6,0,114,108,0,124,2,0,106,6,0,124, - 0,0,95,7,0,113,108,0,110,0,0,124,1,0,124,0, - 0,95,2,0,110,0,0,124,0,0,106,7,0,83,41,1, - 78,41,8,114,229,0,0,0,114,57,1,0,0,114,58,1, - 0,0,114,59,1,0,0,114,70,0,0,0,114,169,0,0, - 0,114,220,0,0,0,114,252,0,0,0,41,3,114,71,0, - 0,0,90,11,112,97,114,101,110,116,95,112,97,116,104,114, - 177,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5, - 0,0,0,218,12,95,114,101,99,97,108,99,117,108,97,116, - 101,179,6,0,0,115,16,0,0,0,0,2,18,1,15,1, - 21,3,27,1,9,1,18,1,12,1,122,27,95,78,97,109, - 101,115,112,97,99,101,80,97,116,104,46,95,114,101,99,97, - 108,99,117,108,97,116,101,99,1,0,0,0,0,0,0,0, - 1,0,0,0,2,0,0,0,67,0,0,0,115,16,0,0, - 0,116,0,0,124,0,0,106,1,0,131,0,0,131,1,0, - 83,41,1,78,41,2,218,4,105,116,101,114,114,63,1,0, - 0,41,1,114,71,0,0,0,114,4,0,0,0,114,4,0, - 0,0,114,5,0,0,0,218,8,95,95,105,116,101,114,95, - 95,192,6,0,0,115,2,0,0,0,0,1,122,23,95,78, - 97,109,101,115,112,97,99,101,80,97,116,104,46,95,95,105, - 116,101,114,95,95,99,1,0,0,0,0,0,0,0,1,0, - 0,0,2,0,0,0,67,0,0,0,115,16,0,0,0,116, - 0,0,124,0,0,106,1,0,131,0,0,131,1,0,83,41, - 1,78,41,2,114,31,0,0,0,114,63,1,0,0,41,1, - 114,71,0,0,0,114,4,0,0,0,114,4,0,0,0,114, - 5,0,0,0,218,7,95,95,108,101,110,95,95,195,6,0, - 0,115,2,0,0,0,0,1,122,22,95,78,97,109,101,115, - 112,97,99,101,80,97,116,104,46,95,95,108,101,110,95,95, - 99,1,0,0,0,0,0,0,0,1,0,0,0,2,0,0, - 0,67,0,0,0,115,16,0,0,0,100,1,0,106,0,0, - 124,0,0,106,1,0,131,1,0,83,41,2,78,122,20,95, - 78,97,109,101,115,112,97,99,101,80,97,116,104,40,123,33, - 114,125,41,41,2,114,47,0,0,0,114,252,0,0,0,41, - 1,114,71,0,0,0,114,4,0,0,0,114,4,0,0,0, - 114,5,0,0,0,114,101,0,0,0,198,6,0,0,115,2, - 0,0,0,0,1,122,23,95,78,97,109,101,115,112,97,99, - 101,80,97,116,104,46,95,95,114,101,112,114,95,95,99,2, - 0,0,0,0,0,0,0,2,0,0,0,2,0,0,0,67, - 0,0,0,115,16,0,0,0,124,1,0,124,0,0,106,0, - 0,131,0,0,107,6,0,83,41,1,78,41,1,114,63,1, - 0,0,41,2,114,71,0,0,0,218,4,105,116,101,109,114, - 4,0,0,0,114,4,0,0,0,114,5,0,0,0,218,12, - 95,95,99,111,110,116,97,105,110,115,95,95,201,6,0,0, - 115,2,0,0,0,0,1,122,27,95,78,97,109,101,115,112, - 97,99,101,80,97,116,104,46,95,95,99,111,110,116,97,105, - 110,115,95,95,99,2,0,0,0,0,0,0,0,2,0,0, - 0,2,0,0,0,67,0,0,0,115,20,0,0,0,124,0, - 0,106,0,0,106,1,0,124,1,0,131,1,0,1,100,0, - 0,83,41,1,78,41,2,114,252,0,0,0,114,223,0,0, - 0,41,2,114,71,0,0,0,114,67,1,0,0,114,4,0, - 0,0,114,4,0,0,0,114,5,0,0,0,114,223,0,0, - 0,204,6,0,0,115,2,0,0,0,0,1,122,21,95,78, - 97,109,101,115,112,97,99,101,80,97,116,104,46,97,112,112, - 101,110,100,78,41,13,114,57,0,0,0,114,56,0,0,0, - 114,58,0,0,0,114,59,0,0,0,114,72,0,0,0,114, - 62,1,0,0,114,57,1,0,0,114,63,1,0,0,114,65, - 1,0,0,114,66,1,0,0,114,101,0,0,0,114,68,1, - 0,0,114,223,0,0,0,114,4,0,0,0,114,4,0,0, - 0,114,4,0,0,0,114,5,0,0,0,114,56,1,0,0, - 152,6,0,0,115,20,0,0,0,12,5,6,2,12,6,12, - 10,12,4,12,13,12,3,12,3,12,3,12,3,114,56,1, - 0,0,99,0,0,0,0,0,0,0,0,0,0,0,0,3, - 0,0,0,64,0,0,0,115,94,0,0,0,101,0,0,90, - 1,0,100,0,0,90,2,0,100,1,0,100,2,0,132,0, - 0,90,3,0,101,4,0,100,3,0,100,4,0,132,0,0, - 131,1,0,90,5,0,100,5,0,100,6,0,132,0,0,90, - 6,0,100,7,0,100,8,0,132,0,0,90,7,0,100,9, - 0,100,10,0,132,0,0,90,8,0,100,11,0,100,12,0, - 132,0,0,90,9,0,100,13,0,83,41,14,114,250,0,0, - 0,99,4,0,0,0,0,0,0,0,4,0,0,0,4,0, - 0,0,67,0,0,0,115,25,0,0,0,116,0,0,124,1, - 0,124,2,0,124,3,0,131,3,0,124,0,0,95,1,0, - 100,0,0,83,41,1,78,41,2,114,56,1,0,0,114,252, - 0,0,0,41,4,114,71,0,0,0,114,67,0,0,0,114, - 35,0,0,0,114,60,1,0,0,114,4,0,0,0,114,4, - 0,0,0,114,5,0,0,0,114,72,0,0,0,210,6,0, - 0,115,2,0,0,0,0,1,122,25,95,78,97,109,101,115, - 112,97,99,101,76,111,97,100,101,114,46,95,95,105,110,105, - 116,95,95,99,2,0,0,0,0,0,0,0,2,0,0,0, - 2,0,0,0,67,0,0,0,115,16,0,0,0,100,1,0, - 106,0,0,124,1,0,106,1,0,131,1,0,83,41,2,78, - 122,25,60,109,111,100,117,108,101,32,123,33,114,125,32,40, - 110,97,109,101,115,112,97,99,101,41,62,41,2,114,47,0, - 0,0,114,57,0,0,0,41,2,114,245,0,0,0,114,179, - 0,0,0,114,4,0,0,0,114,4,0,0,0,114,5,0, - 0,0,114,205,0,0,0,214,6,0,0,115,2,0,0,0, - 0,2,122,28,95,78,97,109,101,115,112,97,99,101,76,111, - 97,100,101,114,46,109,111,100,117,108,101,95,114,101,112,114, - 99,2,0,0,0,0,0,0,0,2,0,0,0,1,0,0, - 0,67,0,0,0,115,4,0,0,0,100,1,0,83,41,2, - 78,84,114,4,0,0,0,41,2,114,71,0,0,0,114,158, + 0,114,121,0,116,7,0,124,2,0,100,3,0,131,2,0, + 12,114,121,0,116,8,0,124,0,0,106,4,0,131,1,0, + 100,4,0,25,103,1,0,124,2,0,95,9,0,124,0,0, + 124,2,0,95,10,0,124,2,0,106,11,0,124,2,0,95, + 12,0,124,3,0,115,173,0,124,2,0,106,12,0,106,13, + 0,100,5,0,131,1,0,100,4,0,25,124,2,0,95,12, + 0,124,2,0,83,41,6,122,25,76,111,97,100,32,97,110, + 32,101,120,116,101,110,115,105,111,110,32,109,111,100,117,108, + 101,46,78,122,33,101,120,116,101,110,115,105,111,110,32,109, + 111,100,117,108,101,32,108,111,97,100,101,100,32,102,114,111, + 109,32,123,33,114,125,114,246,0,0,0,114,84,0,0,0, + 114,116,0,0,0,41,14,114,69,0,0,0,114,114,0,0, + 0,114,106,0,0,0,90,12,108,111,97,100,95,100,121,110, + 97,109,105,99,114,35,0,0,0,114,153,0,0,0,114,219, + 0,0,0,114,60,0,0,0,114,38,0,0,0,114,246,0, + 0,0,114,203,0,0,0,114,57,0,0,0,114,249,0,0, + 0,114,32,0,0,0,41,4,114,71,0,0,0,114,159,0, + 0,0,114,178,0,0,0,114,219,0,0,0,114,4,0,0, + 0,114,4,0,0,0,114,5,0,0,0,114,3,1,0,0, + 132,6,0,0,115,24,0,0,0,0,5,13,1,9,1,21, + 1,16,1,15,1,22,1,25,1,9,1,12,1,6,1,25, + 1,122,31,69,120,116,101,110,115,105,111,110,70,105,108,101, + 76,111,97,100,101,114,46,108,111,97,100,95,109,111,100,117, + 108,101,99,2,0,0,0,0,0,0,0,2,0,0,0,4, + 0,0,0,3,0,0,0,115,48,0,0,0,116,0,0,124, + 0,0,106,1,0,131,1,0,100,1,0,25,137,0,0,116, + 2,0,135,0,0,102,1,0,100,2,0,100,3,0,134,0, + 0,116,3,0,68,131,1,0,131,1,0,83,41,4,122,49, + 82,101,116,117,114,110,32,84,114,117,101,32,105,102,32,116, + 104,101,32,101,120,116,101,110,115,105,111,110,32,109,111,100, + 117,108,101,32,105,115,32,97,32,112,97,99,107,97,103,101, + 46,114,29,0,0,0,99,1,0,0,0,0,0,0,0,2, + 0,0,0,4,0,0,0,51,0,0,0,115,31,0,0,0, + 124,0,0,93,21,0,125,1,0,136,0,0,100,0,0,124, + 1,0,23,107,2,0,86,1,113,3,0,100,1,0,83,41, + 2,114,72,0,0,0,78,114,4,0,0,0,41,2,114,22, + 0,0,0,218,6,115,117,102,102,105,120,41,1,218,9,102, + 105,108,101,95,110,97,109,101,114,4,0,0,0,114,5,0, + 0,0,114,77,0,0,0,153,6,0,0,115,2,0,0,0, + 6,1,122,49,69,120,116,101,110,115,105,111,110,70,105,108, + 101,76,111,97,100,101,114,46,105,115,95,112,97,99,107,97, + 103,101,46,60,108,111,99,97,108,115,62,46,60,103,101,110, + 101,120,112,114,62,41,4,114,38,0,0,0,114,35,0,0, + 0,114,78,0,0,0,218,18,69,88,84,69,78,83,73,79, + 78,95,83,85,70,70,73,88,69,83,41,2,114,71,0,0, + 0,114,159,0,0,0,114,4,0,0,0,41,1,114,58,1, + 0,0,114,5,0,0,0,114,219,0,0,0,150,6,0,0, + 115,6,0,0,0,0,2,19,1,18,1,122,30,69,120,116, + 101,110,115,105,111,110,70,105,108,101,76,111,97,100,101,114, + 46,105,115,95,112,97,99,107,97,103,101,99,2,0,0,0, + 0,0,0,0,2,0,0,0,1,0,0,0,67,0,0,0, + 115,4,0,0,0,100,1,0,83,41,2,122,63,82,101,116, + 117,114,110,32,78,111,110,101,32,97,115,32,97,110,32,101, + 120,116,101,110,115,105,111,110,32,109,111,100,117,108,101,32, + 99,97,110,110,111,116,32,99,114,101,97,116,101,32,97,32, + 99,111,100,101,32,111,98,106,101,99,116,46,78,114,4,0, + 0,0,41,2,114,71,0,0,0,114,159,0,0,0,114,4, + 0,0,0,114,4,0,0,0,114,5,0,0,0,114,14,1, + 0,0,156,6,0,0,115,2,0,0,0,0,2,122,28,69, + 120,116,101,110,115,105,111,110,70,105,108,101,76,111,97,100, + 101,114,46,103,101,116,95,99,111,100,101,99,2,0,0,0, + 0,0,0,0,2,0,0,0,1,0,0,0,67,0,0,0, + 115,4,0,0,0,100,1,0,83,41,2,122,53,82,101,116, + 117,114,110,32,78,111,110,101,32,97,115,32,101,120,116,101, + 110,115,105,111,110,32,109,111,100,117,108,101,115,32,104,97, + 118,101,32,110,111,32,115,111,117,114,99,101,32,99,111,100, + 101,46,78,114,4,0,0,0,41,2,114,71,0,0,0,114, + 159,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5, + 0,0,0,114,15,1,0,0,160,6,0,0,115,2,0,0, + 0,0,2,122,30,69,120,116,101,110,115,105,111,110,70,105, + 108,101,76,111,97,100,101,114,46,103,101,116,95,115,111,117, + 114,99,101,99,2,0,0,0,0,0,0,0,2,0,0,0, + 1,0,0,0,67,0,0,0,115,7,0,0,0,124,0,0, + 106,0,0,83,41,1,122,58,82,101,116,117,114,110,32,116, + 104,101,32,112,97,116,104,32,116,111,32,116,104,101,32,115, + 111,117,114,99,101,32,102,105,108,101,32,97,115,32,102,111, + 117,110,100,32,98,121,32,116,104,101,32,102,105,110,100,101, + 114,46,41,1,114,35,0,0,0,41,2,114,71,0,0,0, + 114,159,0,0,0,114,4,0,0,0,114,4,0,0,0,114, + 5,0,0,0,114,238,0,0,0,164,6,0,0,115,2,0, + 0,0,0,3,122,32,69,120,116,101,110,115,105,111,110,70, + 105,108,101,76,111,97,100,101,114,46,103,101,116,95,102,105, + 108,101,110,97,109,101,78,41,13,114,57,0,0,0,114,56, + 0,0,0,114,58,0,0,0,114,59,0,0,0,114,72,0, + 0,0,114,229,0,0,0,114,50,1,0,0,114,157,0,0, + 0,114,3,1,0,0,114,219,0,0,0,114,14,1,0,0, + 114,15,1,0,0,114,238,0,0,0,114,4,0,0,0,114, + 4,0,0,0,114,4,0,0,0,114,5,0,0,0,114,56, + 1,0,0,113,6,0,0,115,18,0,0,0,12,6,6,2, + 12,4,12,4,12,3,18,18,12,6,12,4,12,4,114,56, + 1,0,0,99,0,0,0,0,0,0,0,0,0,0,0,0, + 2,0,0,0,64,0,0,0,115,130,0,0,0,101,0,0, + 90,1,0,100,0,0,90,2,0,100,1,0,90,3,0,100, + 2,0,100,3,0,132,0,0,90,4,0,100,4,0,100,5, + 0,132,0,0,90,5,0,100,6,0,100,7,0,132,0,0, + 90,6,0,100,8,0,100,9,0,132,0,0,90,7,0,100, + 10,0,100,11,0,132,0,0,90,8,0,100,12,0,100,13, + 0,132,0,0,90,9,0,100,14,0,100,15,0,132,0,0, + 90,10,0,100,16,0,100,17,0,132,0,0,90,11,0,100, + 18,0,100,19,0,132,0,0,90,12,0,100,20,0,83,41, + 21,218,14,95,78,97,109,101,115,112,97,99,101,80,97,116, + 104,97,38,1,0,0,82,101,112,114,101,115,101,110,116,115, + 32,97,32,110,97,109,101,115,112,97,99,101,32,112,97,99, + 107,97,103,101,39,115,32,112,97,116,104,46,32,32,73,116, + 32,117,115,101,115,32,116,104,101,32,109,111,100,117,108,101, + 32,110,97,109,101,10,32,32,32,32,116,111,32,102,105,110, + 100,32,105,116,115,32,112,97,114,101,110,116,32,109,111,100, + 117,108,101,44,32,97,110,100,32,102,114,111,109,32,116,104, + 101,114,101,32,105,116,32,108,111,111,107,115,32,117,112,32, + 116,104,101,32,112,97,114,101,110,116,39,115,10,32,32,32, + 32,95,95,112,97,116,104,95,95,46,32,32,87,104,101,110, + 32,116,104,105,115,32,99,104,97,110,103,101,115,44,32,116, + 104,101,32,109,111,100,117,108,101,39,115,32,111,119,110,32, + 112,97,116,104,32,105,115,32,114,101,99,111,109,112,117,116, + 101,100,44,10,32,32,32,32,117,115,105,110,103,32,112,97, + 116,104,95,102,105,110,100,101,114,46,32,32,70,111,114,32, + 116,111,112,45,108,101,118,101,108,32,109,111,100,117,108,101, + 115,44,32,116,104,101,32,112,97,114,101,110,116,32,109,111, + 100,117,108,101,39,115,32,112,97,116,104,10,32,32,32,32, + 105,115,32,115,121,115,46,112,97,116,104,46,99,4,0,0, + 0,0,0,0,0,4,0,0,0,2,0,0,0,67,0,0, + 0,115,52,0,0,0,124,1,0,124,0,0,95,0,0,124, + 2,0,124,0,0,95,1,0,116,2,0,124,0,0,106,3, + 0,131,0,0,131,1,0,124,0,0,95,4,0,124,3,0, + 124,0,0,95,5,0,100,0,0,83,41,1,78,41,6,114, + 70,0,0,0,114,252,0,0,0,114,231,0,0,0,218,16, + 95,103,101,116,95,112,97,114,101,110,116,95,112,97,116,104, + 218,17,95,108,97,115,116,95,112,97,114,101,110,116,95,112, + 97,116,104,218,12,95,112,97,116,104,95,102,105,110,100,101, + 114,41,4,114,71,0,0,0,114,67,0,0,0,114,35,0, + 0,0,218,11,112,97,116,104,95,102,105,110,100,101,114,114, + 4,0,0,0,114,4,0,0,0,114,5,0,0,0,114,72, + 0,0,0,177,6,0,0,115,8,0,0,0,0,1,9,1, + 9,1,21,1,122,23,95,78,97,109,101,115,112,97,99,101, + 80,97,116,104,46,95,95,105,110,105,116,95,95,99,1,0, + 0,0,0,0,0,0,4,0,0,0,3,0,0,0,67,0, + 0,0,115,53,0,0,0,124,0,0,106,0,0,106,1,0, + 100,1,0,131,1,0,92,3,0,125,1,0,125,2,0,125, + 3,0,124,2,0,100,2,0,107,2,0,114,43,0,100,6, + 0,83,124,1,0,100,5,0,102,2,0,83,41,7,122,62, + 82,101,116,117,114,110,115,32,97,32,116,117,112,108,101,32, + 111,102,32,40,112,97,114,101,110,116,45,109,111,100,117,108, + 101,45,110,97,109,101,44,32,112,97,114,101,110,116,45,112, + 97,116,104,45,97,116,116,114,45,110,97,109,101,41,114,116, + 0,0,0,114,30,0,0,0,114,7,0,0,0,114,35,0, + 0,0,114,246,0,0,0,41,2,122,3,115,121,115,122,4, + 112,97,116,104,41,2,114,70,0,0,0,114,32,0,0,0, + 41,4,114,71,0,0,0,114,233,0,0,0,218,3,100,111, + 116,114,94,0,0,0,114,4,0,0,0,114,4,0,0,0, + 114,5,0,0,0,218,23,95,102,105,110,100,95,112,97,114, + 101,110,116,95,112,97,116,104,95,110,97,109,101,115,183,6, + 0,0,115,8,0,0,0,0,2,27,1,12,2,4,3,122, + 38,95,78,97,109,101,115,112,97,99,101,80,97,116,104,46, + 95,102,105,110,100,95,112,97,114,101,110,116,95,112,97,116, + 104,95,110,97,109,101,115,99,1,0,0,0,0,0,0,0, + 3,0,0,0,3,0,0,0,67,0,0,0,115,38,0,0, + 0,124,0,0,106,0,0,131,0,0,92,2,0,125,1,0, + 125,2,0,116,1,0,116,2,0,106,3,0,124,1,0,25, + 124,2,0,131,2,0,83,41,1,78,41,4,114,66,1,0, + 0,114,62,0,0,0,114,7,0,0,0,114,73,0,0,0, + 41,3,114,71,0,0,0,90,18,112,97,114,101,110,116,95, + 109,111,100,117,108,101,95,110,97,109,101,90,14,112,97,116, + 104,95,97,116,116,114,95,110,97,109,101,114,4,0,0,0, + 114,4,0,0,0,114,5,0,0,0,114,61,1,0,0,193, + 6,0,0,115,4,0,0,0,0,1,18,1,122,31,95,78, + 97,109,101,115,112,97,99,101,80,97,116,104,46,95,103,101, + 116,95,112,97,114,101,110,116,95,112,97,116,104,99,1,0, + 0,0,0,0,0,0,3,0,0,0,3,0,0,0,67,0, + 0,0,115,118,0,0,0,116,0,0,124,0,0,106,1,0, + 131,0,0,131,1,0,125,1,0,124,1,0,124,0,0,106, + 2,0,107,3,0,114,111,0,124,0,0,106,3,0,124,0, + 0,106,4,0,124,1,0,131,2,0,125,2,0,124,2,0, + 100,0,0,107,9,0,114,102,0,124,2,0,106,5,0,100, + 0,0,107,8,0,114,102,0,124,2,0,106,6,0,114,102, + 0,124,2,0,106,6,0,124,0,0,95,7,0,124,1,0, + 124,0,0,95,2,0,124,0,0,106,7,0,83,41,1,78, + 41,8,114,231,0,0,0,114,61,1,0,0,114,62,1,0, + 0,114,63,1,0,0,114,70,0,0,0,114,170,0,0,0, + 114,220,0,0,0,114,252,0,0,0,41,3,114,71,0,0, + 0,90,11,112,97,114,101,110,116,95,112,97,116,104,114,177, 0,0,0,114,4,0,0,0,114,4,0,0,0,114,5,0, - 0,0,114,219,0,0,0,218,6,0,0,115,2,0,0,0, - 0,1,122,27,95,78,97,109,101,115,112,97,99,101,76,111, - 97,100,101,114,46,105,115,95,112,97,99,107,97,103,101,99, - 2,0,0,0,0,0,0,0,2,0,0,0,1,0,0,0, - 67,0,0,0,115,4,0,0,0,100,1,0,83,41,2,78, - 114,30,0,0,0,114,4,0,0,0,41,2,114,71,0,0, - 0,114,158,0,0,0,114,4,0,0,0,114,4,0,0,0, - 114,5,0,0,0,114,13,1,0,0,221,6,0,0,115,2, - 0,0,0,0,1,122,27,95,78,97,109,101,115,112,97,99, - 101,76,111,97,100,101,114,46,103,101,116,95,115,111,117,114, - 99,101,99,2,0,0,0,0,0,0,0,2,0,0,0,6, - 0,0,0,67,0,0,0,115,22,0,0,0,116,0,0,100, - 1,0,100,2,0,100,3,0,100,4,0,100,5,0,131,3, - 1,83,41,6,78,114,30,0,0,0,122,8,60,115,116,114, - 105,110,103,62,114,175,0,0,0,114,38,1,0,0,84,41, - 1,114,39,1,0,0,41,2,114,71,0,0,0,114,158,0, - 0,0,114,4,0,0,0,114,4,0,0,0,114,5,0,0, - 0,114,12,1,0,0,224,6,0,0,115,2,0,0,0,0, - 1,122,25,95,78,97,109,101,115,112,97,99,101,76,111,97, - 100,101,114,46,103,101,116,95,99,111,100,101,99,2,0,0, - 0,0,0,0,0,2,0,0,0,3,0,0,0,67,0,0, - 0,115,29,0,0,0,116,0,0,100,1,0,124,0,0,106, - 1,0,131,2,0,1,116,2,0,124,0,0,124,1,0,131, - 2,0,83,41,2,122,24,76,111,97,100,32,97,32,110,97, - 109,101,115,112,97,99,101,32,109,111,100,117,108,101,46,122, - 38,110,97,109,101,115,112,97,99,101,32,109,111,100,117,108, - 101,32,108,111,97,100,101,100,32,119,105,116,104,32,112,97, - 116,104,32,123,33,114,125,41,3,114,152,0,0,0,114,252, - 0,0,0,114,180,0,0,0,41,2,114,71,0,0,0,114, - 158,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5, - 0,0,0,114,3,1,0,0,228,6,0,0,115,4,0,0, - 0,0,2,16,1,122,28,95,78,97,109,101,115,112,97,99, - 101,76,111,97,100,101,114,46,108,111,97,100,95,109,111,100, - 117,108,101,78,41,10,114,57,0,0,0,114,56,0,0,0, - 114,58,0,0,0,114,72,0,0,0,114,7,1,0,0,114, - 205,0,0,0,114,219,0,0,0,114,13,1,0,0,114,12, - 1,0,0,114,3,1,0,0,114,4,0,0,0,114,4,0, - 0,0,114,4,0,0,0,114,5,0,0,0,114,250,0,0, - 0,209,6,0,0,115,12,0,0,0,12,1,12,4,18,4, - 12,3,12,3,12,4,114,250,0,0,0,99,0,0,0,0, - 0,0,0,0,0,0,0,0,5,0,0,0,64,0,0,0, - 115,160,0,0,0,101,0,0,90,1,0,100,0,0,90,2, - 0,100,1,0,90,3,0,101,4,0,100,2,0,100,3,0, - 132,0,0,131,1,0,90,5,0,101,4,0,100,4,0,100, - 5,0,132,0,0,131,1,0,90,6,0,101,4,0,100,6, - 0,100,7,0,132,0,0,131,1,0,90,7,0,101,4,0, - 100,8,0,100,9,0,132,0,0,131,1,0,90,8,0,101, - 4,0,100,10,0,100,11,0,100,12,0,132,1,0,131,1, - 0,90,9,0,101,4,0,100,10,0,100,10,0,100,13,0, - 100,14,0,132,2,0,131,1,0,90,10,0,101,4,0,100, - 10,0,100,15,0,100,16,0,132,1,0,131,1,0,90,11, - 0,100,10,0,83,41,17,218,10,80,97,116,104,70,105,110, - 100,101,114,122,62,77,101,116,97,32,112,97,116,104,32,102, - 105,110,100,101,114,32,102,111,114,32,115,121,115,46,112,97, - 116,104,32,97,110,100,32,112,97,99,107,97,103,101,32,95, - 95,112,97,116,104,95,95,32,97,116,116,114,105,98,117,116, - 101,115,46,99,1,0,0,0,0,0,0,0,2,0,0,0, - 4,0,0,0,67,0,0,0,115,58,0,0,0,120,51,0, - 116,0,0,106,1,0,106,2,0,131,0,0,68,93,34,0, - 125,1,0,116,3,0,124,1,0,100,1,0,131,2,0,114, - 16,0,124,1,0,106,4,0,131,0,0,1,113,16,0,113, - 16,0,87,100,2,0,83,41,3,122,125,67,97,108,108,32, - 116,104,101,32,105,110,118,97,108,105,100,97,116,101,95,99, - 97,99,104,101,115,40,41,32,109,101,116,104,111,100,32,111, - 110,32,97,108,108,32,112,97,116,104,32,101,110,116,114,121, - 32,102,105,110,100,101,114,115,10,32,32,32,32,32,32,32, - 32,115,116,111,114,101,100,32,105,110,32,115,121,115,46,112, - 97,116,104,95,105,109,112,111,114,116,101,114,95,99,97,99, - 104,101,115,32,40,119,104,101,114,101,32,105,109,112,108,101, - 109,101,110,116,101,100,41,46,218,17,105,110,118,97,108,105, - 100,97,116,101,95,99,97,99,104,101,115,78,41,5,114,7, - 0,0,0,218,19,112,97,116,104,95,105,109,112,111,114,116, - 101,114,95,99,97,99,104,101,218,6,118,97,108,117,101,115, - 114,60,0,0,0,114,70,1,0,0,41,2,114,245,0,0, - 0,218,6,102,105,110,100,101,114,114,4,0,0,0,114,4, - 0,0,0,114,5,0,0,0,114,70,1,0,0,240,6,0, - 0,115,6,0,0,0,0,4,22,1,15,1,122,28,80,97, - 116,104,70,105,110,100,101,114,46,105,110,118,97,108,105,100, - 97,116,101,95,99,97,99,104,101,115,99,2,0,0,0,0, - 0,0,0,3,0,0,0,12,0,0,0,67,0,0,0,115, - 94,0,0,0,116,0,0,106,1,0,115,28,0,116,2,0, - 106,3,0,100,1,0,116,4,0,131,2,0,1,110,0,0, - 120,59,0,116,0,0,106,1,0,68,93,44,0,125,2,0, - 121,14,0,124,2,0,124,1,0,131,1,0,83,87,113,38, - 0,4,116,5,0,107,10,0,114,81,0,1,1,1,119,38, - 0,89,113,38,0,88,113,38,0,87,100,2,0,83,100,2, - 0,83,41,3,122,113,83,101,97,114,99,104,32,115,101,113, - 117,101,110,99,101,32,111,102,32,104,111,111,107,115,32,102, - 111,114,32,97,32,102,105,110,100,101,114,32,102,111,114,32, - 39,112,97,116,104,39,46,10,10,32,32,32,32,32,32,32, - 32,73,102,32,39,104,111,111,107,115,39,32,105,115,32,102, - 97,108,115,101,32,116,104,101,110,32,117,115,101,32,115,121, - 115,46,112,97,116,104,95,104,111,111,107,115,46,10,10,32, - 32,32,32,32,32,32,32,122,23,115,121,115,46,112,97,116, - 104,95,104,111,111,107,115,32,105,115,32,101,109,112,116,121, - 78,41,6,114,7,0,0,0,218,10,112,97,116,104,95,104, - 111,111,107,115,114,166,0,0,0,114,167,0,0,0,114,168, - 0,0,0,114,153,0,0,0,41,3,114,245,0,0,0,114, - 35,0,0,0,90,4,104,111,111,107,114,4,0,0,0,114, - 4,0,0,0,114,5,0,0,0,218,11,95,112,97,116,104, - 95,104,111,111,107,115,248,6,0,0,115,16,0,0,0,0, - 7,9,1,19,1,16,1,3,1,14,1,13,1,12,2,122, - 22,80,97,116,104,70,105,110,100,101,114,46,95,112,97,116, - 104,95,104,111,111,107,115,99,2,0,0,0,0,0,0,0, - 3,0,0,0,11,0,0,0,67,0,0,0,115,97,0,0, - 0,124,1,0,100,1,0,107,2,0,114,27,0,116,0,0, - 106,1,0,131,0,0,125,1,0,110,0,0,121,17,0,116, - 2,0,106,3,0,124,1,0,25,125,2,0,87,110,46,0, - 4,116,4,0,107,10,0,114,92,0,1,1,1,124,0,0, - 106,5,0,124,1,0,131,1,0,125,2,0,124,2,0,116, - 2,0,106,3,0,124,1,0,60,89,110,1,0,88,124,2, - 0,83,41,2,122,210,71,101,116,32,116,104,101,32,102,105, - 110,100,101,114,32,102,111,114,32,116,104,101,32,112,97,116, - 104,32,101,110,116,114,121,32,102,114,111,109,32,115,121,115, - 46,112,97,116,104,95,105,109,112,111,114,116,101,114,95,99, - 97,99,104,101,46,10,10,32,32,32,32,32,32,32,32,73, - 102,32,116,104,101,32,112,97,116,104,32,101,110,116,114,121, - 32,105,115,32,110,111,116,32,105,110,32,116,104,101,32,99, - 97,99,104,101,44,32,102,105,110,100,32,116,104,101,32,97, - 112,112,114,111,112,114,105,97,116,101,32,102,105,110,100,101, - 114,10,32,32,32,32,32,32,32,32,97,110,100,32,99,97, - 99,104,101,32,105,116,46,32,73,102,32,110,111,32,102,105, - 110,100,101,114,32,105,115,32,97,118,97,105,108,97,98,108, - 101,44,32,115,116,111,114,101,32,78,111,110,101,46,10,10, - 32,32,32,32,32,32,32,32,114,30,0,0,0,41,6,114, - 3,0,0,0,114,45,0,0,0,114,7,0,0,0,114,71, - 1,0,0,114,79,0,0,0,114,75,1,0,0,41,3,114, - 245,0,0,0,114,35,0,0,0,114,73,1,0,0,114,4, - 0,0,0,114,4,0,0,0,114,5,0,0,0,218,20,95, - 112,97,116,104,95,105,109,112,111,114,116,101,114,95,99,97, - 99,104,101,9,7,0,0,115,16,0,0,0,0,8,12,1, - 15,1,3,1,17,1,13,1,15,1,18,1,122,31,80,97, - 116,104,70,105,110,100,101,114,46,95,112,97,116,104,95,105, - 109,112,111,114,116,101,114,95,99,97,99,104,101,99,3,0, - 0,0,0,0,0,0,6,0,0,0,3,0,0,0,67,0, - 0,0,115,113,0,0,0,116,0,0,124,2,0,100,1,0, - 131,2,0,114,39,0,124,2,0,106,1,0,124,1,0,131, - 1,0,92,2,0,125,3,0,125,4,0,110,21,0,124,2, - 0,106,2,0,124,1,0,131,1,0,125,3,0,100,0,0, - 125,4,0,124,3,0,100,0,0,107,9,0,114,85,0,116, - 3,0,124,1,0,124,3,0,131,2,0,83,116,4,0,124, - 1,0,100,0,0,131,2,0,125,5,0,124,4,0,124,5, - 0,95,5,0,124,5,0,83,41,2,78,114,165,0,0,0, - 41,6,114,60,0,0,0,114,165,0,0,0,114,11,1,0, - 0,114,173,0,0,0,114,216,0,0,0,114,220,0,0,0, - 41,6,114,245,0,0,0,114,158,0,0,0,114,73,1,0, - 0,114,169,0,0,0,114,170,0,0,0,114,177,0,0,0, - 114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,218, - 16,95,108,101,103,97,99,121,95,103,101,116,95,115,112,101, - 99,26,7,0,0,115,18,0,0,0,0,2,15,1,24,2, - 15,1,6,1,12,1,13,1,15,1,9,1,122,27,80,97, - 116,104,70,105,110,100,101,114,46,95,108,101,103,97,99,121, - 95,103,101,116,95,115,112,101,99,78,99,4,0,0,0,0, - 0,0,0,9,0,0,0,5,0,0,0,67,0,0,0,115, - 252,0,0,0,103,0,0,125,4,0,120,239,0,124,2,0, - 68,93,203,0,125,5,0,116,0,0,124,5,0,116,1,0, - 116,2,0,102,2,0,131,2,0,115,46,0,113,13,0,110, - 0,0,124,0,0,106,3,0,124,5,0,131,1,0,125,6, - 0,124,6,0,100,1,0,107,9,0,114,13,0,116,4,0, - 124,6,0,100,2,0,131,2,0,114,109,0,124,6,0,106, - 5,0,124,1,0,124,3,0,131,2,0,125,7,0,110,18, - 0,124,0,0,106,6,0,124,1,0,124,6,0,131,2,0, - 125,7,0,124,7,0,100,1,0,107,8,0,114,145,0,113, - 13,0,110,0,0,124,7,0,106,7,0,100,1,0,107,9, - 0,114,164,0,124,7,0,83,124,7,0,106,8,0,125,8, - 0,124,8,0,100,1,0,107,8,0,114,200,0,116,9,0, - 100,3,0,131,1,0,130,1,0,110,0,0,124,4,0,106, - 10,0,124,8,0,131,1,0,1,113,13,0,113,13,0,87, - 116,11,0,124,1,0,100,1,0,131,2,0,125,7,0,124, - 4,0,124,7,0,95,8,0,124,7,0,83,100,1,0,83, - 41,4,122,63,70,105,110,100,32,116,104,101,32,108,111,97, - 100,101,114,32,111,114,32,110,97,109,101,115,112,97,99,101, - 95,112,97,116,104,32,102,111,114,32,116,104,105,115,32,109, - 111,100,117,108,101,47,112,97,99,107,97,103,101,32,110,97, - 109,101,46,78,114,10,1,0,0,122,19,115,112,101,99,32, - 109,105,115,115,105,110,103,32,108,111,97,100,101,114,41,12, - 114,192,0,0,0,218,3,115,116,114,218,5,98,121,116,101, - 115,114,76,1,0,0,114,60,0,0,0,114,10,1,0,0, - 114,77,1,0,0,114,169,0,0,0,114,220,0,0,0,114, - 153,0,0,0,114,197,0,0,0,114,216,0,0,0,41,9, - 114,245,0,0,0,114,158,0,0,0,114,35,0,0,0,114, - 9,1,0,0,218,14,110,97,109,101,115,112,97,99,101,95, - 112,97,116,104,90,5,101,110,116,114,121,114,73,1,0,0, - 114,177,0,0,0,114,170,0,0,0,114,4,0,0,0,114, - 4,0,0,0,114,5,0,0,0,218,9,95,103,101,116,95, - 115,112,101,99,39,7,0,0,115,40,0,0,0,0,5,6, - 1,13,1,21,1,6,1,15,1,12,1,15,1,21,2,18, - 1,12,1,6,1,15,1,4,1,9,1,12,1,15,5,20, - 2,15,1,9,1,122,20,80,97,116,104,70,105,110,100,101, - 114,46,95,103,101,116,95,115,112,101,99,99,4,0,0,0, - 0,0,0,0,6,0,0,0,4,0,0,0,67,0,0,0, - 115,143,0,0,0,124,2,0,100,1,0,107,8,0,114,24, - 0,116,0,0,106,1,0,125,2,0,110,0,0,124,0,0, - 106,2,0,124,1,0,124,2,0,124,3,0,131,3,0,125, - 4,0,124,4,0,100,1,0,107,8,0,114,61,0,100,1, - 0,83,124,4,0,106,3,0,100,1,0,107,8,0,114,135, - 0,124,4,0,106,4,0,125,5,0,124,5,0,114,128,0, - 100,2,0,124,4,0,95,5,0,116,6,0,124,1,0,124, - 5,0,124,0,0,106,2,0,131,3,0,124,4,0,95,4, - 0,124,4,0,83,100,1,0,83,110,4,0,124,4,0,83, - 100,1,0,83,41,3,122,98,102,105,110,100,32,116,104,101, - 32,109,111,100,117,108,101,32,111,110,32,115,121,115,46,112, - 97,116,104,32,111,114,32,39,112,97,116,104,39,32,98,97, - 115,101,100,32,111,110,32,115,121,115,46,112,97,116,104,95, - 104,111,111,107,115,32,97,110,100,10,32,32,32,32,32,32, - 32,32,115,121,115,46,112,97,116,104,95,105,109,112,111,114, - 116,101,114,95,99,97,99,104,101,46,78,90,9,110,97,109, - 101,115,112,97,99,101,41,7,114,7,0,0,0,114,35,0, - 0,0,114,81,1,0,0,114,169,0,0,0,114,220,0,0, - 0,114,217,0,0,0,114,56,1,0,0,41,6,114,245,0, - 0,0,114,158,0,0,0,114,35,0,0,0,114,9,1,0, - 0,114,177,0,0,0,114,80,1,0,0,114,4,0,0,0, - 114,4,0,0,0,114,5,0,0,0,114,10,1,0,0,71, - 7,0,0,115,26,0,0,0,0,4,12,1,12,1,21,1, - 12,1,4,1,15,1,9,1,6,3,9,1,24,1,4,2, - 7,2,122,20,80,97,116,104,70,105,110,100,101,114,46,102, - 105,110,100,95,115,112,101,99,99,3,0,0,0,0,0,0, - 0,4,0,0,0,3,0,0,0,67,0,0,0,115,41,0, - 0,0,124,0,0,106,0,0,124,1,0,124,2,0,131,2, - 0,125,3,0,124,3,0,100,1,0,107,8,0,114,34,0, - 100,1,0,83,124,3,0,106,1,0,83,41,2,122,98,102, - 105,110,100,32,116,104,101,32,109,111,100,117,108,101,32,111, - 110,32,115,121,115,46,112,97,116,104,32,111,114,32,39,112, - 97,116,104,39,32,98,97,115,101,100,32,111,110,32,115,121, - 115,46,112,97,116,104,95,104,111,111,107,115,32,97,110,100, - 10,32,32,32,32,32,32,32,32,115,121,115,46,112,97,116, - 104,95,105,109,112,111,114,116,101,114,95,99,97,99,104,101, - 46,78,41,2,114,10,1,0,0,114,169,0,0,0,41,4, - 114,245,0,0,0,114,158,0,0,0,114,35,0,0,0,114, - 177,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5, - 0,0,0,114,11,1,0,0,93,7,0,0,115,8,0,0, - 0,0,5,18,1,12,1,4,1,122,22,80,97,116,104,70, - 105,110,100,101,114,46,102,105,110,100,95,109,111,100,117,108, - 101,41,12,114,57,0,0,0,114,56,0,0,0,114,58,0, - 0,0,114,59,0,0,0,114,7,1,0,0,114,70,1,0, - 0,114,75,1,0,0,114,76,1,0,0,114,77,1,0,0, - 114,81,1,0,0,114,10,1,0,0,114,11,1,0,0,114, - 4,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5, - 0,0,0,114,69,1,0,0,236,6,0,0,115,22,0,0, - 0,12,2,6,2,18,8,18,17,18,17,18,13,3,1,18, - 31,3,1,21,21,3,1,114,69,1,0,0,99,0,0,0, - 0,0,0,0,0,0,0,0,0,3,0,0,0,64,0,0, - 0,115,133,0,0,0,101,0,0,90,1,0,100,0,0,90, - 2,0,100,1,0,90,3,0,100,2,0,100,3,0,132,0, - 0,90,4,0,100,4,0,100,5,0,132,0,0,90,5,0, - 101,6,0,90,7,0,100,6,0,100,7,0,132,0,0,90, - 8,0,100,8,0,100,9,0,132,0,0,90,9,0,100,10, - 0,100,11,0,100,12,0,132,1,0,90,10,0,100,13,0, - 100,14,0,132,0,0,90,11,0,101,12,0,100,15,0,100, - 16,0,132,0,0,131,1,0,90,13,0,100,17,0,100,18, - 0,132,0,0,90,14,0,100,10,0,83,41,19,218,10,70, - 105,108,101,70,105,110,100,101,114,122,172,70,105,108,101,45, - 98,97,115,101,100,32,102,105,110,100,101,114,46,10,10,32, - 32,32,32,73,110,116,101,114,97,99,116,105,111,110,115,32, - 119,105,116,104,32,116,104,101,32,102,105,108,101,32,115,121, - 115,116,101,109,32,97,114,101,32,99,97,99,104,101,100,32, - 102,111,114,32,112,101,114,102,111,114,109,97,110,99,101,44, - 32,98,101,105,110,103,10,32,32,32,32,114,101,102,114,101, - 115,104,101,100,32,119,104,101,110,32,116,104,101,32,100,105, - 114,101,99,116,111,114,121,32,116,104,101,32,102,105,110,100, - 101,114,32,105,115,32,104,97,110,100,108,105,110,103,32,104, - 97,115,32,98,101,101,110,32,109,111,100,105,102,105,101,100, - 46,10,10,32,32,32,32,99,2,0,0,0,0,0,0,0, - 5,0,0,0,5,0,0,0,7,0,0,0,115,122,0,0, - 0,103,0,0,125,3,0,120,52,0,124,2,0,68,93,44, - 0,92,2,0,137,0,0,125,4,0,124,3,0,106,0,0, - 135,0,0,102,1,0,100,1,0,100,2,0,134,0,0,124, - 4,0,68,131,1,0,131,1,0,1,113,13,0,87,124,3, - 0,124,0,0,95,1,0,124,1,0,112,79,0,100,3,0, - 124,0,0,95,2,0,100,6,0,124,0,0,95,3,0,116, - 4,0,131,0,0,124,0,0,95,5,0,116,4,0,131,0, - 0,124,0,0,95,6,0,100,5,0,83,41,7,122,154,73, - 110,105,116,105,97,108,105,122,101,32,119,105,116,104,32,116, - 104,101,32,112,97,116,104,32,116,111,32,115,101,97,114,99, - 104,32,111,110,32,97,110,100,32,97,32,118,97,114,105,97, - 98,108,101,32,110,117,109,98,101,114,32,111,102,10,32,32, - 32,32,32,32,32,32,50,45,116,117,112,108,101,115,32,99, - 111,110,116,97,105,110,105,110,103,32,116,104,101,32,108,111, - 97,100,101,114,32,97,110,100,32,116,104,101,32,102,105,108, - 101,32,115,117,102,102,105,120,101,115,32,116,104,101,32,108, - 111,97,100,101,114,10,32,32,32,32,32,32,32,32,114,101, - 99,111,103,110,105,122,101,115,46,99,1,0,0,0,0,0, - 0,0,2,0,0,0,3,0,0,0,51,0,0,0,115,27, - 0,0,0,124,0,0,93,17,0,125,1,0,124,1,0,136, - 0,0,102,2,0,86,1,113,3,0,100,0,0,83,41,1, - 78,114,4,0,0,0,41,2,114,22,0,0,0,114,53,1, - 0,0,41,1,114,169,0,0,0,114,4,0,0,0,114,5, - 0,0,0,114,77,0,0,0,119,7,0,0,115,2,0,0, - 0,6,0,122,38,70,105,108,101,70,105,110,100,101,114,46, - 95,95,105,110,105,116,95,95,46,60,108,111,99,97,108,115, - 62,46,60,103,101,110,101,120,112,114,62,114,116,0,0,0, - 114,29,0,0,0,78,114,138,0,0,0,41,7,114,197,0, - 0,0,218,8,95,108,111,97,100,101,114,115,114,35,0,0, - 0,218,11,95,112,97,116,104,95,109,116,105,109,101,218,3, - 115,101,116,218,11,95,112,97,116,104,95,99,97,99,104,101, - 218,19,95,114,101,108,97,120,101,100,95,112,97,116,104,95, - 99,97,99,104,101,41,5,114,71,0,0,0,114,35,0,0, - 0,218,14,108,111,97,100,101,114,95,100,101,116,97,105,108, - 115,90,7,108,111,97,100,101,114,115,114,127,0,0,0,114, - 4,0,0,0,41,1,114,169,0,0,0,114,5,0,0,0, - 114,72,0,0,0,113,7,0,0,115,16,0,0,0,0,4, - 6,1,19,1,36,1,9,2,15,1,9,1,12,1,122,19, - 70,105,108,101,70,105,110,100,101,114,46,95,95,105,110,105, - 116,95,95,99,1,0,0,0,0,0,0,0,1,0,0,0, - 2,0,0,0,67,0,0,0,115,13,0,0,0,100,3,0, - 124,0,0,95,0,0,100,2,0,83,41,4,122,31,73,110, - 118,97,108,105,100,97,116,101,32,116,104,101,32,100,105,114, - 101,99,116,111,114,121,32,109,116,105,109,101,46,114,29,0, - 0,0,78,114,138,0,0,0,41,1,114,84,1,0,0,41, - 1,114,71,0,0,0,114,4,0,0,0,114,4,0,0,0, - 114,5,0,0,0,114,70,1,0,0,127,7,0,0,115,2, - 0,0,0,0,2,122,28,70,105,108,101,70,105,110,100,101, - 114,46,105,110,118,97,108,105,100,97,116,101,95,99,97,99, - 104,101,115,99,2,0,0,0,0,0,0,0,3,0,0,0, - 3,0,0,0,67,0,0,0,115,59,0,0,0,124,0,0, - 106,0,0,124,1,0,131,1,0,125,2,0,124,2,0,100, - 1,0,107,8,0,114,37,0,100,1,0,103,0,0,102,2, - 0,83,124,2,0,106,1,0,124,2,0,106,2,0,112,55, - 0,103,0,0,102,2,0,83,41,2,122,125,84,114,121,32, - 116,111,32,102,105,110,100,32,97,32,108,111,97,100,101,114, - 32,102,111,114,32,116,104,101,32,115,112,101,99,105,102,105, - 101,100,32,109,111,100,117,108,101,44,32,111,114,32,116,104, - 101,32,110,97,109,101,115,112,97,99,101,10,32,32,32,32, - 32,32,32,32,112,97,99,107,97,103,101,32,112,111,114,116, - 105,111,110,115,46,32,82,101,116,117,114,110,115,32,40,108, - 111,97,100,101,114,44,32,108,105,115,116,45,111,102,45,112, - 111,114,116,105,111,110,115,41,46,78,41,3,114,10,1,0, - 0,114,169,0,0,0,114,220,0,0,0,41,3,114,71,0, - 0,0,114,158,0,0,0,114,177,0,0,0,114,4,0,0, - 0,114,4,0,0,0,114,5,0,0,0,114,165,0,0,0, - 133,7,0,0,115,8,0,0,0,0,3,15,1,12,1,10, - 1,122,22,70,105,108,101,70,105,110,100,101,114,46,102,105, - 110,100,95,108,111,97,100,101,114,99,6,0,0,0,0,0, - 0,0,8,0,0,0,13,0,0,0,67,0,0,0,115,97, - 0,0,0,124,1,0,124,2,0,124,3,0,131,2,0,125, - 6,0,121,13,0,124,6,0,106,0,0,125,7,0,87,110, - 43,0,4,116,1,0,107,10,0,114,73,0,1,1,1,116, - 2,0,124,2,0,124,3,0,100,1,0,124,6,0,100,2, - 0,124,4,0,131,2,2,83,89,110,20,0,88,124,7,0, - 124,2,0,124,3,0,124,4,0,124,5,0,131,4,0,83, - 100,0,0,83,41,3,78,114,169,0,0,0,114,220,0,0, - 0,41,3,114,81,1,0,0,114,209,0,0,0,114,235,0, - 0,0,41,8,114,71,0,0,0,114,239,0,0,0,114,158, - 0,0,0,114,35,0,0,0,114,220,0,0,0,114,9,1, - 0,0,114,169,0,0,0,90,8,103,101,116,95,115,112,101, - 99,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, - 114,81,1,0,0,141,7,0,0,115,14,0,0,0,0,1, - 15,1,3,1,13,1,13,1,18,1,12,2,122,20,70,105, - 108,101,70,105,110,100,101,114,46,95,103,101,116,95,115,112, - 101,99,78,99,3,0,0,0,0,0,0,0,14,0,0,0, - 15,0,0,0,67,0,0,0,115,240,1,0,0,100,1,0, - 125,3,0,124,1,0,106,0,0,100,2,0,131,1,0,100, - 3,0,25,125,4,0,121,34,0,116,1,0,124,0,0,106, - 2,0,112,49,0,116,3,0,106,4,0,131,0,0,131,1, - 0,106,5,0,125,5,0,87,110,24,0,4,116,6,0,107, - 10,0,114,85,0,1,1,1,100,10,0,125,5,0,89,110, - 1,0,88,124,5,0,124,0,0,106,7,0,107,3,0,114, - 123,0,124,0,0,106,8,0,131,0,0,1,124,5,0,124, - 0,0,95,7,0,110,0,0,116,9,0,131,0,0,114,156, - 0,124,0,0,106,10,0,125,6,0,124,4,0,106,11,0, - 131,0,0,125,7,0,110,15,0,124,0,0,106,12,0,125, - 6,0,124,4,0,125,7,0,124,7,0,124,6,0,107,6, - 0,114,51,1,116,13,0,124,0,0,106,2,0,124,4,0, - 131,2,0,125,8,0,120,103,0,124,0,0,106,14,0,68, - 93,77,0,92,2,0,125,9,0,125,10,0,100,5,0,124, - 9,0,23,125,11,0,116,13,0,124,8,0,124,11,0,131, - 2,0,125,12,0,116,15,0,124,12,0,131,1,0,114,211, - 0,124,0,0,106,16,0,124,10,0,124,1,0,124,12,0, - 124,8,0,103,1,0,124,2,0,131,5,0,83,113,211,0, - 87,116,17,0,124,8,0,131,1,0,125,3,0,110,0,0, - 120,126,0,124,0,0,106,14,0,68,93,115,0,92,2,0, - 125,9,0,125,10,0,116,13,0,124,0,0,106,2,0,124, - 4,0,124,9,0,23,131,2,0,125,12,0,116,18,0,100, - 6,0,106,19,0,124,12,0,131,1,0,100,7,0,100,3, - 0,131,1,1,1,124,7,0,124,9,0,23,124,6,0,107, - 6,0,114,61,1,116,15,0,124,12,0,131,1,0,114,176, - 1,124,0,0,106,16,0,124,10,0,124,1,0,124,12,0, - 100,8,0,124,2,0,131,5,0,83,113,61,1,113,61,1, - 87,124,3,0,114,236,1,116,18,0,100,9,0,106,19,0, - 124,8,0,131,1,0,131,1,0,1,116,20,0,124,1,0, - 100,8,0,131,2,0,125,13,0,124,8,0,103,1,0,124, - 13,0,95,21,0,124,13,0,83,100,8,0,83,41,11,122, - 125,84,114,121,32,116,111,32,102,105,110,100,32,97,32,108, - 111,97,100,101,114,32,102,111,114,32,116,104,101,32,115,112, - 101,99,105,102,105,101,100,32,109,111,100,117,108,101,44,32, - 111,114,32,116,104,101,32,110,97,109,101,115,112,97,99,101, - 10,32,32,32,32,32,32,32,32,112,97,99,107,97,103,101, - 32,112,111,114,116,105,111,110,115,46,32,82,101,116,117,114, - 110,115,32,40,108,111,97,100,101,114,44,32,108,105,115,116, - 45,111,102,45,112,111,114,116,105,111,110,115,41,46,70,114, - 116,0,0,0,114,115,0,0,0,114,29,0,0,0,114,72, - 0,0,0,122,9,116,114,121,105,110,103,32,123,125,114,145, - 0,0,0,78,122,25,112,111,115,115,105,98,108,101,32,110, - 97,109,101,115,112,97,99,101,32,102,111,114,32,123,125,114, - 138,0,0,0,41,22,114,32,0,0,0,114,39,0,0,0, - 114,35,0,0,0,114,3,0,0,0,114,45,0,0,0,114, - 48,1,0,0,114,40,0,0,0,114,84,1,0,0,218,11, - 95,102,105,108,108,95,99,97,99,104,101,114,6,0,0,0, - 114,87,1,0,0,114,139,0,0,0,114,86,1,0,0,114, - 28,0,0,0,114,83,1,0,0,114,44,0,0,0,114,81, - 1,0,0,114,46,0,0,0,114,152,0,0,0,114,47,0, - 0,0,114,216,0,0,0,114,220,0,0,0,41,14,114,71, - 0,0,0,114,158,0,0,0,114,9,1,0,0,90,12,105, - 115,95,110,97,109,101,115,112,97,99,101,90,11,116,97,105, - 108,95,109,111,100,117,108,101,114,183,0,0,0,90,5,99, - 97,99,104,101,90,12,99,97,99,104,101,95,109,111,100,117, - 108,101,90,9,98,97,115,101,95,112,97,116,104,114,53,1, - 0,0,114,239,0,0,0,90,13,105,110,105,116,95,102,105, - 108,101,110,97,109,101,90,9,102,117,108,108,95,112,97,116, - 104,114,177,0,0,0,114,4,0,0,0,114,4,0,0,0, - 114,5,0,0,0,114,10,1,0,0,151,7,0,0,115,68, - 0,0,0,0,3,6,1,19,1,3,1,34,1,13,1,11, - 1,15,1,10,1,12,2,9,1,9,1,15,2,9,1,6, - 2,12,1,18,1,22,1,10,1,15,1,12,1,32,4,15, - 2,22,1,22,1,25,1,16,1,12,1,32,1,6,1,19, - 1,15,1,12,1,4,1,122,20,70,105,108,101,70,105,110, - 100,101,114,46,102,105,110,100,95,115,112,101,99,99,1,0, - 0,0,0,0,0,0,9,0,0,0,13,0,0,0,67,0, - 0,0,115,14,1,0,0,124,0,0,106,0,0,125,1,0, - 121,31,0,116,1,0,106,2,0,124,1,0,112,33,0,116, - 1,0,106,3,0,131,0,0,131,1,0,125,2,0,87,110, - 33,0,4,116,4,0,116,5,0,116,6,0,102,3,0,107, - 10,0,114,75,0,1,1,1,103,0,0,125,2,0,89,110, - 1,0,88,116,7,0,106,8,0,106,9,0,100,1,0,131, - 1,0,115,112,0,116,10,0,124,2,0,131,1,0,124,0, - 0,95,11,0,110,111,0,116,10,0,131,0,0,125,3,0, - 120,90,0,124,2,0,68,93,82,0,125,4,0,124,4,0, - 106,12,0,100,2,0,131,1,0,92,3,0,125,5,0,125, - 6,0,125,7,0,124,6,0,114,191,0,100,3,0,106,13, - 0,124,5,0,124,7,0,106,14,0,131,0,0,131,2,0, - 125,8,0,110,6,0,124,5,0,125,8,0,124,3,0,106, - 15,0,124,8,0,131,1,0,1,113,128,0,87,124,3,0, - 124,0,0,95,11,0,116,7,0,106,8,0,106,9,0,116, - 16,0,131,1,0,114,10,1,100,4,0,100,5,0,132,0, - 0,124,2,0,68,131,1,0,124,0,0,95,17,0,110,0, - 0,100,6,0,83,41,7,122,68,70,105,108,108,32,116,104, - 101,32,99,97,99,104,101,32,111,102,32,112,111,116,101,110, - 116,105,97,108,32,109,111,100,117,108,101,115,32,97,110,100, - 32,112,97,99,107,97,103,101,115,32,102,111,114,32,116,104, - 105,115,32,100,105,114,101,99,116,111,114,121,46,114,0,0, - 0,0,114,116,0,0,0,122,5,123,125,46,123,125,99,1, - 0,0,0,0,0,0,0,2,0,0,0,3,0,0,0,83, - 0,0,0,115,28,0,0,0,104,0,0,124,0,0,93,18, - 0,125,1,0,124,1,0,106,0,0,131,0,0,146,2,0, - 113,6,0,83,114,4,0,0,0,41,1,114,139,0,0,0, - 41,2,114,22,0,0,0,90,2,102,110,114,4,0,0,0, - 114,4,0,0,0,114,5,0,0,0,250,9,60,115,101,116, - 99,111,109,112,62,225,7,0,0,115,2,0,0,0,9,0, - 122,41,70,105,108,101,70,105,110,100,101,114,46,95,102,105, - 108,108,95,99,97,99,104,101,46,60,108,111,99,97,108,115, - 62,46,60,115,101,116,99,111,109,112,62,78,41,18,114,35, - 0,0,0,114,3,0,0,0,90,7,108,105,115,116,100,105, - 114,114,45,0,0,0,218,17,70,105,108,101,78,111,116,70, - 111,117,110,100,69,114,114,111,114,218,15,80,101,114,109,105, - 115,115,105,111,110,69,114,114,111,114,218,18,78,111,116,65, - 68,105,114,101,99,116,111,114,121,69,114,114,111,114,114,7, - 0,0,0,114,8,0,0,0,114,9,0,0,0,114,85,1, - 0,0,114,86,1,0,0,114,121,0,0,0,114,47,0,0, - 0,114,139,0,0,0,218,3,97,100,100,114,10,0,0,0, - 114,87,1,0,0,41,9,114,71,0,0,0,114,35,0,0, - 0,90,8,99,111,110,116,101,110,116,115,90,21,108,111,119, - 101,114,95,115,117,102,102,105,120,95,99,111,110,116,101,110, - 116,115,114,67,1,0,0,114,67,0,0,0,114,61,1,0, - 0,114,53,1,0,0,90,8,110,101,119,95,110,97,109,101, + 0,0,218,12,95,114,101,99,97,108,99,117,108,97,116,101, + 197,6,0,0,115,16,0,0,0,0,2,18,1,15,1,21, + 3,27,1,9,1,12,1,9,1,122,27,95,78,97,109,101, + 115,112,97,99,101,80,97,116,104,46,95,114,101,99,97,108, + 99,117,108,97,116,101,99,1,0,0,0,0,0,0,0,1, + 0,0,0,2,0,0,0,67,0,0,0,115,16,0,0,0, + 116,0,0,124,0,0,106,1,0,131,0,0,131,1,0,83, + 41,1,78,41,2,218,4,105,116,101,114,114,67,1,0,0, + 41,1,114,71,0,0,0,114,4,0,0,0,114,4,0,0, + 0,114,5,0,0,0,218,8,95,95,105,116,101,114,95,95, + 210,6,0,0,115,2,0,0,0,0,1,122,23,95,78,97, + 109,101,115,112,97,99,101,80,97,116,104,46,95,95,105,116, + 101,114,95,95,99,1,0,0,0,0,0,0,0,1,0,0, + 0,2,0,0,0,67,0,0,0,115,16,0,0,0,116,0, + 0,124,0,0,106,1,0,131,0,0,131,1,0,83,41,1, + 78,41,2,114,31,0,0,0,114,67,1,0,0,41,1,114, + 71,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5, + 0,0,0,218,7,95,95,108,101,110,95,95,213,6,0,0, + 115,2,0,0,0,0,1,122,22,95,78,97,109,101,115,112, + 97,99,101,80,97,116,104,46,95,95,108,101,110,95,95,99, + 1,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0, + 67,0,0,0,115,16,0,0,0,100,1,0,106,0,0,124, + 0,0,106,1,0,131,1,0,83,41,2,78,122,20,95,78, + 97,109,101,115,112,97,99,101,80,97,116,104,40,123,33,114, + 125,41,41,2,114,47,0,0,0,114,252,0,0,0,41,1, + 114,71,0,0,0,114,4,0,0,0,114,4,0,0,0,114, + 5,0,0,0,114,101,0,0,0,216,6,0,0,115,2,0, + 0,0,0,1,122,23,95,78,97,109,101,115,112,97,99,101, + 80,97,116,104,46,95,95,114,101,112,114,95,95,99,2,0, + 0,0,0,0,0,0,2,0,0,0,2,0,0,0,67,0, + 0,0,115,16,0,0,0,124,1,0,124,0,0,106,0,0, + 131,0,0,107,6,0,83,41,1,78,41,1,114,67,1,0, + 0,41,2,114,71,0,0,0,218,4,105,116,101,109,114,4, + 0,0,0,114,4,0,0,0,114,5,0,0,0,218,12,95, + 95,99,111,110,116,97,105,110,115,95,95,219,6,0,0,115, + 2,0,0,0,0,1,122,27,95,78,97,109,101,115,112,97, + 99,101,80,97,116,104,46,95,95,99,111,110,116,97,105,110, + 115,95,95,99,2,0,0,0,0,0,0,0,2,0,0,0, + 2,0,0,0,67,0,0,0,115,20,0,0,0,124,0,0, + 106,0,0,106,1,0,124,1,0,131,1,0,1,100,0,0, + 83,41,1,78,41,2,114,252,0,0,0,114,223,0,0,0, + 41,2,114,71,0,0,0,114,71,1,0,0,114,4,0,0, + 0,114,4,0,0,0,114,5,0,0,0,114,223,0,0,0, + 222,6,0,0,115,2,0,0,0,0,1,122,21,95,78,97, + 109,101,115,112,97,99,101,80,97,116,104,46,97,112,112,101, + 110,100,78,41,13,114,57,0,0,0,114,56,0,0,0,114, + 58,0,0,0,114,59,0,0,0,114,72,0,0,0,114,66, + 1,0,0,114,61,1,0,0,114,67,1,0,0,114,69,1, + 0,0,114,70,1,0,0,114,101,0,0,0,114,72,1,0, + 0,114,223,0,0,0,114,4,0,0,0,114,4,0,0,0, + 114,4,0,0,0,114,5,0,0,0,114,60,1,0,0,170, + 6,0,0,115,20,0,0,0,12,5,6,2,12,6,12,10, + 12,4,12,13,12,3,12,3,12,3,12,3,114,60,1,0, + 0,99,0,0,0,0,0,0,0,0,0,0,0,0,3,0, + 0,0,64,0,0,0,115,118,0,0,0,101,0,0,90,1, + 0,100,0,0,90,2,0,100,1,0,100,2,0,132,0,0, + 90,3,0,101,4,0,100,3,0,100,4,0,132,0,0,131, + 1,0,90,5,0,100,5,0,100,6,0,132,0,0,90,6, + 0,100,7,0,100,8,0,132,0,0,90,7,0,100,9,0, + 100,10,0,132,0,0,90,8,0,100,11,0,100,12,0,132, + 0,0,90,9,0,100,13,0,100,14,0,132,0,0,90,10, + 0,100,15,0,100,16,0,132,0,0,90,11,0,100,17,0, + 83,41,18,114,250,0,0,0,99,4,0,0,0,0,0,0, + 0,4,0,0,0,4,0,0,0,67,0,0,0,115,25,0, + 0,0,116,0,0,124,1,0,124,2,0,124,3,0,131,3, + 0,124,0,0,95,1,0,100,0,0,83,41,1,78,41,2, + 114,60,1,0,0,114,252,0,0,0,41,4,114,71,0,0, + 0,114,67,0,0,0,114,35,0,0,0,114,64,1,0,0, 114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,114, - 89,1,0,0,196,7,0,0,115,34,0,0,0,0,2,9, - 1,3,1,31,1,22,3,11,3,18,1,18,7,9,1,13, - 1,24,1,6,1,27,2,6,1,17,1,9,1,18,1,122, - 22,70,105,108,101,70,105,110,100,101,114,46,95,102,105,108, - 108,95,99,97,99,104,101,99,1,0,0,0,0,0,0,0, - 3,0,0,0,3,0,0,0,7,0,0,0,115,25,0,0, - 0,135,0,0,135,1,0,102,2,0,100,1,0,100,2,0, - 134,0,0,125,2,0,124,2,0,83,41,3,97,20,1,0, - 0,65,32,99,108,97,115,115,32,109,101,116,104,111,100,32, - 119,104,105,99,104,32,114,101,116,117,114,110,115,32,97,32, - 99,108,111,115,117,114,101,32,116,111,32,117,115,101,32,111, - 110,32,115,121,115,46,112,97,116,104,95,104,111,111,107,10, - 32,32,32,32,32,32,32,32,119,104,105,99,104,32,119,105, - 108,108,32,114,101,116,117,114,110,32,97,110,32,105,110,115, - 116,97,110,99,101,32,117,115,105,110,103,32,116,104,101,32, - 115,112,101,99,105,102,105,101,100,32,108,111,97,100,101,114, - 115,32,97,110,100,32,116,104,101,32,112,97,116,104,10,32, - 32,32,32,32,32,32,32,99,97,108,108,101,100,32,111,110, - 32,116,104,101,32,99,108,111,115,117,114,101,46,10,10,32, - 32,32,32,32,32,32,32,73,102,32,116,104,101,32,112,97, - 116,104,32,99,97,108,108,101,100,32,111,110,32,116,104,101, - 32,99,108,111,115,117,114,101,32,105,115,32,110,111,116,32, - 97,32,100,105,114,101,99,116,111,114,121,44,32,73,109,112, - 111,114,116,69,114,114,111,114,32,105,115,10,32,32,32,32, - 32,32,32,32,114,97,105,115,101,100,46,10,10,32,32,32, - 32,32,32,32,32,99,1,0,0,0,0,0,0,0,1,0, - 0,0,4,0,0,0,19,0,0,0,115,46,0,0,0,116, - 0,0,124,0,0,131,1,0,115,33,0,116,1,0,100,1, - 0,100,2,0,124,0,0,131,1,1,130,1,0,110,0,0, - 136,0,0,124,0,0,136,1,0,140,1,0,83,41,3,122, - 45,80,97,116,104,32,104,111,111,107,32,102,111,114,32,105, - 109,112,111,114,116,108,105,98,46,109,97,99,104,105,110,101, - 114,121,46,70,105,108,101,70,105,110,100,101,114,46,122,30, - 111,110,108,121,32,100,105,114,101,99,116,111,114,105,101,115, - 32,97,114,101,32,115,117,112,112,111,114,116,101,100,114,35, - 0,0,0,41,2,114,46,0,0,0,114,153,0,0,0,41, - 1,114,35,0,0,0,41,2,114,245,0,0,0,114,88,1, - 0,0,114,4,0,0,0,114,5,0,0,0,218,24,112,97, - 116,104,95,104,111,111,107,95,102,111,114,95,70,105,108,101, - 70,105,110,100,101,114,237,7,0,0,115,6,0,0,0,0, - 2,12,1,21,1,122,54,70,105,108,101,70,105,110,100,101, - 114,46,112,97,116,104,95,104,111,111,107,46,60,108,111,99, - 97,108,115,62,46,112,97,116,104,95,104,111,111,107,95,102, - 111,114,95,70,105,108,101,70,105,110,100,101,114,114,4,0, - 0,0,41,3,114,245,0,0,0,114,88,1,0,0,114,95, - 1,0,0,114,4,0,0,0,41,2,114,245,0,0,0,114, - 88,1,0,0,114,5,0,0,0,218,9,112,97,116,104,95, - 104,111,111,107,227,7,0,0,115,4,0,0,0,0,10,21, - 6,122,20,70,105,108,101,70,105,110,100,101,114,46,112,97, - 116,104,95,104,111,111,107,99,1,0,0,0,0,0,0,0, - 1,0,0,0,2,0,0,0,67,0,0,0,115,16,0,0, - 0,100,1,0,106,0,0,124,0,0,106,1,0,131,1,0, - 83,41,2,78,122,16,70,105,108,101,70,105,110,100,101,114, - 40,123,33,114,125,41,41,2,114,47,0,0,0,114,35,0, - 0,0,41,1,114,71,0,0,0,114,4,0,0,0,114,4, - 0,0,0,114,5,0,0,0,114,101,0,0,0,245,7,0, - 0,115,2,0,0,0,0,1,122,19,70,105,108,101,70,105, - 110,100,101,114,46,95,95,114,101,112,114,95,95,41,15,114, - 57,0,0,0,114,56,0,0,0,114,58,0,0,0,114,59, - 0,0,0,114,72,0,0,0,114,70,1,0,0,114,172,0, - 0,0,114,11,1,0,0,114,165,0,0,0,114,81,1,0, - 0,114,10,1,0,0,114,89,1,0,0,114,7,1,0,0, - 114,96,1,0,0,114,101,0,0,0,114,4,0,0,0,114, - 4,0,0,0,114,4,0,0,0,114,5,0,0,0,114,82, - 1,0,0,104,7,0,0,115,20,0,0,0,12,7,6,2, - 12,14,12,4,6,2,12,8,12,10,15,45,12,31,18,18, - 114,82,1,0,0,99,0,0,0,0,0,0,0,0,0,0, - 0,0,2,0,0,0,64,0,0,0,115,46,0,0,0,101, - 0,0,90,1,0,100,0,0,90,2,0,100,1,0,90,3, - 0,100,2,0,100,3,0,132,0,0,90,4,0,100,4,0, - 100,5,0,132,0,0,90,5,0,100,6,0,83,41,7,218, - 18,95,73,109,112,111,114,116,76,111,99,107,67,111,110,116, - 101,120,116,122,36,67,111,110,116,101,120,116,32,109,97,110, - 97,103,101,114,32,102,111,114,32,116,104,101,32,105,109,112, - 111,114,116,32,108,111,99,107,46,99,1,0,0,0,0,0, - 0,0,1,0,0,0,1,0,0,0,67,0,0,0,115,14, - 0,0,0,116,0,0,106,1,0,131,0,0,1,100,1,0, - 83,41,2,122,24,65,99,113,117,105,114,101,32,116,104,101, - 32,105,109,112,111,114,116,32,108,111,99,107,46,78,41,2, - 114,106,0,0,0,114,2,1,0,0,41,1,114,71,0,0, + 72,0,0,0,228,6,0,0,115,2,0,0,0,0,1,122, + 25,95,78,97,109,101,115,112,97,99,101,76,111,97,100,101, + 114,46,95,95,105,110,105,116,95,95,99,2,0,0,0,0, + 0,0,0,2,0,0,0,2,0,0,0,67,0,0,0,115, + 16,0,0,0,100,1,0,106,0,0,124,1,0,106,1,0, + 131,1,0,83,41,2,122,115,82,101,116,117,114,110,32,114, + 101,112,114,32,102,111,114,32,116,104,101,32,109,111,100,117, + 108,101,46,10,10,32,32,32,32,32,32,32,32,84,104,101, + 32,109,101,116,104,111,100,32,105,115,32,100,101,112,114,101, + 99,97,116,101,100,46,32,32,84,104,101,32,105,109,112,111, + 114,116,32,109,97,99,104,105,110,101,114,121,32,100,111,101, + 115,32,116,104,101,32,106,111,98,32,105,116,115,101,108,102, + 46,10,10,32,32,32,32,32,32,32,32,122,25,60,109,111, + 100,117,108,101,32,123,33,114,125,32,40,110,97,109,101,115, + 112,97,99,101,41,62,41,2,114,47,0,0,0,114,57,0, + 0,0,41,2,114,10,1,0,0,114,178,0,0,0,114,4, + 0,0,0,114,4,0,0,0,114,5,0,0,0,114,204,0, + 0,0,231,6,0,0,115,2,0,0,0,0,7,122,28,95, + 78,97,109,101,115,112,97,99,101,76,111,97,100,101,114,46, + 109,111,100,117,108,101,95,114,101,112,114,99,2,0,0,0, + 0,0,0,0,2,0,0,0,1,0,0,0,67,0,0,0, + 115,4,0,0,0,100,1,0,83,41,2,78,84,114,4,0, + 0,0,41,2,114,71,0,0,0,114,159,0,0,0,114,4, + 0,0,0,114,4,0,0,0,114,5,0,0,0,114,219,0, + 0,0,240,6,0,0,115,2,0,0,0,0,1,122,27,95, + 78,97,109,101,115,112,97,99,101,76,111,97,100,101,114,46, + 105,115,95,112,97,99,107,97,103,101,99,2,0,0,0,0, + 0,0,0,2,0,0,0,1,0,0,0,67,0,0,0,115, + 4,0,0,0,100,1,0,83,41,2,78,114,30,0,0,0, + 114,4,0,0,0,41,2,114,71,0,0,0,114,159,0,0, 0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, - 114,75,0,0,0,255,7,0,0,115,2,0,0,0,0,2, - 122,28,95,73,109,112,111,114,116,76,111,99,107,67,111,110, - 116,101,120,116,46,95,95,101,110,116,101,114,95,95,99,4, - 0,0,0,0,0,0,0,4,0,0,0,1,0,0,0,67, - 0,0,0,115,14,0,0,0,116,0,0,106,1,0,131,0, - 0,1,100,1,0,83,41,2,122,60,82,101,108,101,97,115, - 101,32,116,104,101,32,105,109,112,111,114,116,32,108,111,99, - 107,32,114,101,103,97,114,100,108,101,115,115,32,111,102,32, - 97,110,121,32,114,97,105,115,101,100,32,101,120,99,101,112, - 116,105,111,110,115,46,78,41,2,114,106,0,0,0,114,107, - 0,0,0,41,4,114,71,0,0,0,90,8,101,120,99,95, - 116,121,112,101,90,9,101,120,99,95,118,97,108,117,101,90, - 13,101,120,99,95,116,114,97,99,101,98,97,99,107,114,4, - 0,0,0,114,4,0,0,0,114,5,0,0,0,114,81,0, - 0,0,3,8,0,0,115,2,0,0,0,0,2,122,27,95, - 73,109,112,111,114,116,76,111,99,107,67,111,110,116,101,120, - 116,46,95,95,101,120,105,116,95,95,78,41,6,114,57,0, - 0,0,114,56,0,0,0,114,58,0,0,0,114,59,0,0, - 0,114,75,0,0,0,114,81,0,0,0,114,4,0,0,0, + 114,15,1,0,0,243,6,0,0,115,2,0,0,0,0,1, + 122,27,95,78,97,109,101,115,112,97,99,101,76,111,97,100, + 101,114,46,103,101,116,95,115,111,117,114,99,101,99,2,0, + 0,0,0,0,0,0,2,0,0,0,6,0,0,0,67,0, + 0,0,115,22,0,0,0,116,0,0,100,1,0,100,2,0, + 100,3,0,100,4,0,100,5,0,131,3,1,83,41,6,78, + 114,30,0,0,0,122,8,60,115,116,114,105,110,103,62,114, + 21,1,0,0,114,42,1,0,0,84,41,1,114,43,1,0, + 0,41,2,114,71,0,0,0,114,159,0,0,0,114,4,0, + 0,0,114,4,0,0,0,114,5,0,0,0,114,14,1,0, + 0,246,6,0,0,115,2,0,0,0,0,1,122,25,95,78, + 97,109,101,115,112,97,99,101,76,111,97,100,101,114,46,103, + 101,116,95,99,111,100,101,99,2,0,0,0,0,0,0,0, + 2,0,0,0,1,0,0,0,67,0,0,0,115,4,0,0, + 0,100,1,0,83,41,2,122,42,85,115,101,32,100,101,102, + 97,117,108,116,32,115,101,109,97,110,116,105,99,115,32,102, + 111,114,32,109,111,100,117,108,101,32,99,114,101,97,116,105, + 111,110,46,78,114,4,0,0,0,41,2,114,71,0,0,0, + 114,177,0,0,0,114,4,0,0,0,114,4,0,0,0,114, + 5,0,0,0,114,254,0,0,0,249,6,0,0,115,0,0, + 0,0,122,30,95,78,97,109,101,115,112,97,99,101,76,111, + 97,100,101,114,46,99,114,101,97,116,101,95,109,111,100,117, + 108,101,99,2,0,0,0,0,0,0,0,2,0,0,0,1, + 0,0,0,67,0,0,0,115,4,0,0,0,100,0,0,83, + 41,1,78,114,4,0,0,0,41,2,114,71,0,0,0,114, + 178,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5, + 0,0,0,114,255,0,0,0,252,6,0,0,115,2,0,0, + 0,0,1,122,28,95,78,97,109,101,115,112,97,99,101,76, + 111,97,100,101,114,46,101,120,101,99,95,109,111,100,117,108, + 101,99,2,0,0,0,0,0,0,0,2,0,0,0,3,0, + 0,0,67,0,0,0,115,29,0,0,0,116,0,0,100,1, + 0,124,0,0,106,1,0,131,2,0,1,116,2,0,124,0, + 0,124,1,0,131,2,0,83,41,2,122,98,76,111,97,100, + 32,97,32,110,97,109,101,115,112,97,99,101,32,109,111,100, + 117,108,101,46,10,10,32,32,32,32,32,32,32,32,84,104, + 105,115,32,109,101,116,104,111,100,32,105,115,32,100,101,112, + 114,101,99,97,116,101,100,46,32,32,85,115,101,32,101,120, + 101,99,95,109,111,100,117,108,101,40,41,32,105,110,115,116, + 101,97,100,46,10,10,32,32,32,32,32,32,32,32,122,38, + 110,97,109,101,115,112,97,99,101,32,109,111,100,117,108,101, + 32,108,111,97,100,101,100,32,119,105,116,104,32,112,97,116, + 104,32,123,33,114,125,41,3,114,153,0,0,0,114,252,0, + 0,0,114,179,0,0,0,41,2,114,71,0,0,0,114,159, + 0,0,0,114,4,0,0,0,114,4,0,0,0,114,5,0, + 0,0,114,3,1,0,0,255,6,0,0,115,4,0,0,0, + 0,7,16,1,122,28,95,78,97,109,101,115,112,97,99,101, + 76,111,97,100,101,114,46,108,111,97,100,95,109,111,100,117, + 108,101,78,41,12,114,57,0,0,0,114,56,0,0,0,114, + 58,0,0,0,114,72,0,0,0,114,17,1,0,0,114,204, + 0,0,0,114,219,0,0,0,114,15,1,0,0,114,14,1, + 0,0,114,254,0,0,0,114,255,0,0,0,114,3,1,0, + 0,114,4,0,0,0,114,4,0,0,0,114,4,0,0,0, + 114,5,0,0,0,114,250,0,0,0,227,6,0,0,115,16, + 0,0,0,12,1,12,3,18,9,12,3,12,3,12,3,12, + 3,12,3,114,250,0,0,0,99,0,0,0,0,0,0,0, + 0,0,0,0,0,5,0,0,0,64,0,0,0,115,160,0, + 0,0,101,0,0,90,1,0,100,0,0,90,2,0,100,1, + 0,90,3,0,101,4,0,100,2,0,100,3,0,132,0,0, + 131,1,0,90,5,0,101,4,0,100,4,0,100,5,0,132, + 0,0,131,1,0,90,6,0,101,4,0,100,6,0,100,7, + 0,132,0,0,131,1,0,90,7,0,101,4,0,100,8,0, + 100,9,0,132,0,0,131,1,0,90,8,0,101,4,0,100, + 10,0,100,11,0,100,12,0,132,1,0,131,1,0,90,9, + 0,101,4,0,100,10,0,100,10,0,100,13,0,100,14,0, + 132,2,0,131,1,0,90,10,0,101,4,0,100,10,0,100, + 15,0,100,16,0,132,1,0,131,1,0,90,11,0,100,10, + 0,83,41,17,218,10,80,97,116,104,70,105,110,100,101,114, + 122,62,77,101,116,97,32,112,97,116,104,32,102,105,110,100, + 101,114,32,102,111,114,32,115,121,115,46,112,97,116,104,32, + 97,110,100,32,112,97,99,107,97,103,101,32,95,95,112,97, + 116,104,95,95,32,97,116,116,114,105,98,117,116,101,115,46, + 99,1,0,0,0,0,0,0,0,2,0,0,0,4,0,0, + 0,67,0,0,0,115,55,0,0,0,120,48,0,116,0,0, + 106,1,0,106,2,0,131,0,0,68,93,31,0,125,1,0, + 116,3,0,124,1,0,100,1,0,131,2,0,114,16,0,124, + 1,0,106,4,0,131,0,0,1,113,16,0,87,100,2,0, + 83,41,3,122,125,67,97,108,108,32,116,104,101,32,105,110, + 118,97,108,105,100,97,116,101,95,99,97,99,104,101,115,40, + 41,32,109,101,116,104,111,100,32,111,110,32,97,108,108,32, + 112,97,116,104,32,101,110,116,114,121,32,102,105,110,100,101, + 114,115,10,32,32,32,32,32,32,32,32,115,116,111,114,101, + 100,32,105,110,32,115,121,115,46,112,97,116,104,95,105,109, + 112,111,114,116,101,114,95,99,97,99,104,101,115,32,40,119, + 104,101,114,101,32,105,109,112,108,101,109,101,110,116,101,100, + 41,46,218,17,105,110,118,97,108,105,100,97,116,101,95,99, + 97,99,104,101,115,78,41,5,114,7,0,0,0,218,19,112, + 97,116,104,95,105,109,112,111,114,116,101,114,95,99,97,99, + 104,101,218,6,118,97,108,117,101,115,114,60,0,0,0,114, + 74,1,0,0,41,2,114,10,1,0,0,218,6,102,105,110, + 100,101,114,114,4,0,0,0,114,4,0,0,0,114,5,0, + 0,0,114,74,1,0,0,16,7,0,0,115,6,0,0,0, + 0,4,22,1,15,1,122,28,80,97,116,104,70,105,110,100, + 101,114,46,105,110,118,97,108,105,100,97,116,101,95,99,97, + 99,104,101,115,99,2,0,0,0,0,0,0,0,3,0,0, + 0,12,0,0,0,67,0,0,0,115,107,0,0,0,116,0, + 0,106,1,0,100,1,0,107,9,0,114,41,0,116,0,0, + 106,1,0,12,114,41,0,116,2,0,106,3,0,100,2,0, + 116,4,0,131,2,0,1,120,59,0,116,0,0,106,1,0, + 68,93,44,0,125,2,0,121,14,0,124,2,0,124,1,0, + 131,1,0,83,87,113,51,0,4,116,5,0,107,10,0,114, + 94,0,1,1,1,119,51,0,89,113,51,0,88,113,51,0, + 87,100,1,0,83,100,1,0,83,41,3,122,113,83,101,97, + 114,99,104,32,115,101,113,117,101,110,99,101,32,111,102,32, + 104,111,111,107,115,32,102,111,114,32,97,32,102,105,110,100, + 101,114,32,102,111,114,32,39,112,97,116,104,39,46,10,10, + 32,32,32,32,32,32,32,32,73,102,32,39,104,111,111,107, + 115,39,32,105,115,32,102,97,108,115,101,32,116,104,101,110, + 32,117,115,101,32,115,121,115,46,112,97,116,104,95,104,111, + 111,107,115,46,10,10,32,32,32,32,32,32,32,32,78,122, + 23,115,121,115,46,112,97,116,104,95,104,111,111,107,115,32, + 105,115,32,101,109,112,116,121,41,6,114,7,0,0,0,218, + 10,112,97,116,104,95,104,111,111,107,115,114,167,0,0,0, + 114,168,0,0,0,114,169,0,0,0,114,154,0,0,0,41, + 3,114,10,1,0,0,114,35,0,0,0,90,4,104,111,111, + 107,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, + 218,11,95,112,97,116,104,95,104,111,111,107,115,24,7,0, + 0,115,16,0,0,0,0,7,25,1,16,1,16,1,3,1, + 14,1,13,1,12,2,122,22,80,97,116,104,70,105,110,100, + 101,114,46,95,112,97,116,104,95,104,111,111,107,115,99,2, + 0,0,0,0,0,0,0,3,0,0,0,19,0,0,0,67, + 0,0,0,115,123,0,0,0,124,1,0,100,1,0,107,2, + 0,114,53,0,121,16,0,116,0,0,106,1,0,131,0,0, + 125,1,0,87,110,22,0,4,116,2,0,107,10,0,114,52, + 0,1,1,1,100,2,0,83,89,110,1,0,88,121,17,0, + 116,3,0,106,4,0,124,1,0,25,125,2,0,87,110,46, + 0,4,116,5,0,107,10,0,114,118,0,1,1,1,124,0, + 0,106,6,0,124,1,0,131,1,0,125,2,0,124,2,0, + 116,3,0,106,4,0,124,1,0,60,89,110,1,0,88,124, + 2,0,83,41,3,122,210,71,101,116,32,116,104,101,32,102, + 105,110,100,101,114,32,102,111,114,32,116,104,101,32,112,97, + 116,104,32,101,110,116,114,121,32,102,114,111,109,32,115,121, + 115,46,112,97,116,104,95,105,109,112,111,114,116,101,114,95, + 99,97,99,104,101,46,10,10,32,32,32,32,32,32,32,32, + 73,102,32,116,104,101,32,112,97,116,104,32,101,110,116,114, + 121,32,105,115,32,110,111,116,32,105,110,32,116,104,101,32, + 99,97,99,104,101,44,32,102,105,110,100,32,116,104,101,32, + 97,112,112,114,111,112,114,105,97,116,101,32,102,105,110,100, + 101,114,10,32,32,32,32,32,32,32,32,97,110,100,32,99, + 97,99,104,101,32,105,116,46,32,73,102,32,110,111,32,102, + 105,110,100,101,114,32,105,115,32,97,118,97,105,108,97,98, + 108,101,44,32,115,116,111,114,101,32,78,111,110,101,46,10, + 10,32,32,32,32,32,32,32,32,114,30,0,0,0,78,41, + 7,114,3,0,0,0,114,45,0,0,0,218,17,70,105,108, + 101,78,111,116,70,111,117,110,100,69,114,114,111,114,114,7, + 0,0,0,114,75,1,0,0,114,79,0,0,0,114,79,1, + 0,0,41,3,114,10,1,0,0,114,35,0,0,0,114,77, + 1,0,0,114,4,0,0,0,114,4,0,0,0,114,5,0, + 0,0,218,20,95,112,97,116,104,95,105,109,112,111,114,116, + 101,114,95,99,97,99,104,101,41,7,0,0,115,22,0,0, + 0,0,8,12,1,3,1,16,1,13,3,9,1,3,1,17, + 1,13,1,15,1,18,1,122,31,80,97,116,104,70,105,110, + 100,101,114,46,95,112,97,116,104,95,105,109,112,111,114,116, + 101,114,95,99,97,99,104,101,99,3,0,0,0,0,0,0, + 0,6,0,0,0,3,0,0,0,67,0,0,0,115,113,0, + 0,0,116,0,0,124,2,0,100,1,0,131,2,0,114,39, + 0,124,2,0,106,1,0,124,1,0,131,1,0,92,2,0, + 125,3,0,125,4,0,110,21,0,124,2,0,106,2,0,124, + 1,0,131,1,0,125,3,0,103,0,0,125,4,0,124,3, + 0,100,0,0,107,9,0,114,85,0,116,3,0,124,1,0, + 124,3,0,131,2,0,83,116,4,0,124,1,0,100,0,0, + 131,2,0,125,5,0,124,4,0,124,5,0,95,5,0,124, + 5,0,83,41,2,78,114,166,0,0,0,41,6,114,60,0, + 0,0,114,166,0,0,0,114,13,1,0,0,114,174,0,0, + 0,114,216,0,0,0,114,220,0,0,0,41,6,114,10,1, + 0,0,114,159,0,0,0,114,77,1,0,0,114,170,0,0, + 0,114,171,0,0,0,114,177,0,0,0,114,4,0,0,0, + 114,4,0,0,0,114,5,0,0,0,218,16,95,108,101,103, + 97,99,121,95,103,101,116,95,115,112,101,99,63,7,0,0, + 115,18,0,0,0,0,4,15,1,24,2,15,1,6,1,12, + 1,13,1,15,1,9,1,122,27,80,97,116,104,70,105,110, + 100,101,114,46,95,108,101,103,97,99,121,95,103,101,116,95, + 115,112,101,99,78,99,4,0,0,0,0,0,0,0,9,0, + 0,0,5,0,0,0,67,0,0,0,115,240,0,0,0,103, + 0,0,125,4,0,120,227,0,124,2,0,68,93,191,0,125, + 5,0,116,0,0,124,5,0,116,1,0,116,2,0,102,2, + 0,131,2,0,115,43,0,113,13,0,124,0,0,106,3,0, + 124,5,0,131,1,0,125,6,0,124,6,0,100,1,0,107, + 9,0,114,13,0,116,4,0,124,6,0,100,2,0,131,2, + 0,114,106,0,124,6,0,106,5,0,124,1,0,124,3,0, + 131,2,0,125,7,0,110,18,0,124,0,0,106,6,0,124, + 1,0,124,6,0,131,2,0,125,7,0,124,7,0,100,1, + 0,107,8,0,114,139,0,113,13,0,124,7,0,106,7,0, + 100,1,0,107,9,0,114,158,0,124,7,0,83,124,7,0, + 106,8,0,125,8,0,124,8,0,100,1,0,107,8,0,114, + 191,0,116,9,0,100,3,0,131,1,0,130,1,0,124,4, + 0,106,10,0,124,8,0,131,1,0,1,113,13,0,87,116, + 11,0,124,1,0,100,1,0,131,2,0,125,7,0,124,4, + 0,124,7,0,95,8,0,124,7,0,83,100,1,0,83,41, + 4,122,63,70,105,110,100,32,116,104,101,32,108,111,97,100, + 101,114,32,111,114,32,110,97,109,101,115,112,97,99,101,95, + 112,97,116,104,32,102,111,114,32,116,104,105,115,32,109,111, + 100,117,108,101,47,112,97,99,107,97,103,101,32,110,97,109, + 101,46,78,114,12,1,0,0,122,19,115,112,101,99,32,109, + 105,115,115,105,110,103,32,108,111,97,100,101,114,41,12,114, + 191,0,0,0,218,3,115,116,114,218,5,98,121,116,101,115, + 114,81,1,0,0,114,60,0,0,0,114,12,1,0,0,114, + 82,1,0,0,114,170,0,0,0,114,220,0,0,0,114,154, + 0,0,0,114,196,0,0,0,114,216,0,0,0,41,9,114, + 10,1,0,0,114,159,0,0,0,114,35,0,0,0,114,11, + 1,0,0,218,14,110,97,109,101,115,112,97,99,101,95,112, + 97,116,104,90,5,101,110,116,114,121,114,77,1,0,0,114, + 177,0,0,0,114,171,0,0,0,114,4,0,0,0,114,4, + 0,0,0,114,5,0,0,0,218,9,95,103,101,116,95,115, + 112,101,99,78,7,0,0,115,40,0,0,0,0,5,6,1, + 13,1,21,1,3,1,15,1,12,1,15,1,21,2,18,1, + 12,1,3,1,15,1,4,1,9,1,12,1,12,5,17,2, + 15,1,9,1,122,20,80,97,116,104,70,105,110,100,101,114, + 46,95,103,101,116,95,115,112,101,99,99,4,0,0,0,0, + 0,0,0,6,0,0,0,4,0,0,0,67,0,0,0,115, + 140,0,0,0,124,2,0,100,1,0,107,8,0,114,21,0, + 116,0,0,106,1,0,125,2,0,124,0,0,106,2,0,124, + 1,0,124,2,0,124,3,0,131,3,0,125,4,0,124,4, + 0,100,1,0,107,8,0,114,58,0,100,1,0,83,124,4, + 0,106,3,0,100,1,0,107,8,0,114,132,0,124,4,0, + 106,4,0,125,5,0,124,5,0,114,125,0,100,2,0,124, + 4,0,95,5,0,116,6,0,124,1,0,124,5,0,124,0, + 0,106,2,0,131,3,0,124,4,0,95,4,0,124,4,0, + 83,100,1,0,83,110,4,0,124,4,0,83,100,1,0,83, + 41,3,122,98,102,105,110,100,32,116,104,101,32,109,111,100, + 117,108,101,32,111,110,32,115,121,115,46,112,97,116,104,32, + 111,114,32,39,112,97,116,104,39,32,98,97,115,101,100,32, + 111,110,32,115,121,115,46,112,97,116,104,95,104,111,111,107, + 115,32,97,110,100,10,32,32,32,32,32,32,32,32,115,121, + 115,46,112,97,116,104,95,105,109,112,111,114,116,101,114,95, + 99,97,99,104,101,46,78,90,9,110,97,109,101,115,112,97, + 99,101,41,7,114,7,0,0,0,114,35,0,0,0,114,86, + 1,0,0,114,170,0,0,0,114,220,0,0,0,114,217,0, + 0,0,114,60,1,0,0,41,6,114,10,1,0,0,114,159, + 0,0,0,114,35,0,0,0,114,11,1,0,0,114,177,0, + 0,0,114,85,1,0,0,114,4,0,0,0,114,4,0,0, + 0,114,5,0,0,0,114,12,1,0,0,110,7,0,0,115, + 26,0,0,0,0,4,12,1,9,1,21,1,12,1,4,1, + 15,1,9,1,6,3,9,1,24,1,4,2,7,2,122,20, + 80,97,116,104,70,105,110,100,101,114,46,102,105,110,100,95, + 115,112,101,99,99,3,0,0,0,0,0,0,0,4,0,0, + 0,3,0,0,0,67,0,0,0,115,41,0,0,0,124,0, + 0,106,0,0,124,1,0,124,2,0,131,2,0,125,3,0, + 124,3,0,100,1,0,107,8,0,114,34,0,100,1,0,83, + 124,3,0,106,1,0,83,41,2,122,170,102,105,110,100,32, + 116,104,101,32,109,111,100,117,108,101,32,111,110,32,115,121, + 115,46,112,97,116,104,32,111,114,32,39,112,97,116,104,39, + 32,98,97,115,101,100,32,111,110,32,115,121,115,46,112,97, + 116,104,95,104,111,111,107,115,32,97,110,100,10,32,32,32, + 32,32,32,32,32,115,121,115,46,112,97,116,104,95,105,109, + 112,111,114,116,101,114,95,99,97,99,104,101,46,10,10,32, + 32,32,32,32,32,32,32,84,104,105,115,32,109,101,116,104, + 111,100,32,105,115,32,100,101,112,114,101,99,97,116,101,100, + 46,32,32,85,115,101,32,102,105,110,100,95,115,112,101,99, + 40,41,32,105,110,115,116,101,97,100,46,10,10,32,32,32, + 32,32,32,32,32,78,41,2,114,12,1,0,0,114,170,0, + 0,0,41,4,114,10,1,0,0,114,159,0,0,0,114,35, + 0,0,0,114,177,0,0,0,114,4,0,0,0,114,4,0, + 0,0,114,5,0,0,0,114,13,1,0,0,132,7,0,0, + 115,8,0,0,0,0,8,18,1,12,1,4,1,122,22,80, + 97,116,104,70,105,110,100,101,114,46,102,105,110,100,95,109, + 111,100,117,108,101,41,12,114,57,0,0,0,114,56,0,0, + 0,114,58,0,0,0,114,59,0,0,0,114,17,1,0,0, + 114,74,1,0,0,114,79,1,0,0,114,81,1,0,0,114, + 82,1,0,0,114,86,1,0,0,114,12,1,0,0,114,13, + 1,0,0,114,4,0,0,0,114,4,0,0,0,114,4,0, + 0,0,114,5,0,0,0,114,73,1,0,0,12,7,0,0, + 115,22,0,0,0,12,2,6,2,18,8,18,17,18,22,18, + 15,3,1,18,31,3,1,21,21,3,1,114,73,1,0,0, + 99,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0, + 0,64,0,0,0,115,133,0,0,0,101,0,0,90,1,0, + 100,0,0,90,2,0,100,1,0,90,3,0,100,2,0,100, + 3,0,132,0,0,90,4,0,100,4,0,100,5,0,132,0, + 0,90,5,0,101,6,0,90,7,0,100,6,0,100,7,0, + 132,0,0,90,8,0,100,8,0,100,9,0,132,0,0,90, + 9,0,100,10,0,100,11,0,100,12,0,132,1,0,90,10, + 0,100,13,0,100,14,0,132,0,0,90,11,0,101,12,0, + 100,15,0,100,16,0,132,0,0,131,1,0,90,13,0,100, + 17,0,100,18,0,132,0,0,90,14,0,100,10,0,83,41, + 19,218,10,70,105,108,101,70,105,110,100,101,114,122,172,70, + 105,108,101,45,98,97,115,101,100,32,102,105,110,100,101,114, + 46,10,10,32,32,32,32,73,110,116,101,114,97,99,116,105, + 111,110,115,32,119,105,116,104,32,116,104,101,32,102,105,108, + 101,32,115,121,115,116,101,109,32,97,114,101,32,99,97,99, + 104,101,100,32,102,111,114,32,112,101,114,102,111,114,109,97, + 110,99,101,44,32,98,101,105,110,103,10,32,32,32,32,114, + 101,102,114,101,115,104,101,100,32,119,104,101,110,32,116,104, + 101,32,100,105,114,101,99,116,111,114,121,32,116,104,101,32, + 102,105,110,100,101,114,32,105,115,32,104,97,110,100,108,105, + 110,103,32,104,97,115,32,98,101,101,110,32,109,111,100,105, + 102,105,101,100,46,10,10,32,32,32,32,99,2,0,0,0, + 0,0,0,0,5,0,0,0,5,0,0,0,7,0,0,0, + 115,122,0,0,0,103,0,0,125,3,0,120,52,0,124,2, + 0,68,93,44,0,92,2,0,137,0,0,125,4,0,124,3, + 0,106,0,0,135,0,0,102,1,0,100,1,0,100,2,0, + 134,0,0,124,4,0,68,131,1,0,131,1,0,1,113,13, + 0,87,124,3,0,124,0,0,95,1,0,124,1,0,112,79, + 0,100,3,0,124,0,0,95,2,0,100,6,0,124,0,0, + 95,3,0,116,4,0,131,0,0,124,0,0,95,5,0,116, + 4,0,131,0,0,124,0,0,95,6,0,100,5,0,83,41, + 7,122,154,73,110,105,116,105,97,108,105,122,101,32,119,105, + 116,104,32,116,104,101,32,112,97,116,104,32,116,111,32,115, + 101,97,114,99,104,32,111,110,32,97,110,100,32,97,32,118, + 97,114,105,97,98,108,101,32,110,117,109,98,101,114,32,111, + 102,10,32,32,32,32,32,32,32,32,50,45,116,117,112,108, + 101,115,32,99,111,110,116,97,105,110,105,110,103,32,116,104, + 101,32,108,111,97,100,101,114,32,97,110,100,32,116,104,101, + 32,102,105,108,101,32,115,117,102,102,105,120,101,115,32,116, + 104,101,32,108,111,97,100,101,114,10,32,32,32,32,32,32, + 32,32,114,101,99,111,103,110,105,122,101,115,46,99,1,0, + 0,0,0,0,0,0,2,0,0,0,3,0,0,0,51,0, + 0,0,115,27,0,0,0,124,0,0,93,17,0,125,1,0, + 124,1,0,136,0,0,102,2,0,86,1,113,3,0,100,0, + 0,83,41,1,78,114,4,0,0,0,41,2,114,22,0,0, + 0,114,57,1,0,0,41,1,114,170,0,0,0,114,4,0, + 0,0,114,5,0,0,0,114,77,0,0,0,161,7,0,0, + 115,2,0,0,0,6,0,122,38,70,105,108,101,70,105,110, + 100,101,114,46,95,95,105,110,105,116,95,95,46,60,108,111, + 99,97,108,115,62,46,60,103,101,110,101,120,112,114,62,114, + 116,0,0,0,114,29,0,0,0,78,114,139,0,0,0,41, + 7,114,196,0,0,0,218,8,95,108,111,97,100,101,114,115, + 114,35,0,0,0,218,11,95,112,97,116,104,95,109,116,105, + 109,101,218,3,115,101,116,218,11,95,112,97,116,104,95,99, + 97,99,104,101,218,19,95,114,101,108,97,120,101,100,95,112, + 97,116,104,95,99,97,99,104,101,41,5,114,71,0,0,0, + 114,35,0,0,0,218,14,108,111,97,100,101,114,95,100,101, + 116,97,105,108,115,90,7,108,111,97,100,101,114,115,114,126, + 0,0,0,114,4,0,0,0,41,1,114,170,0,0,0,114, + 5,0,0,0,114,72,0,0,0,155,7,0,0,115,16,0, + 0,0,0,4,6,1,19,1,36,1,9,2,15,1,9,1, + 12,1,122,19,70,105,108,101,70,105,110,100,101,114,46,95, + 95,105,110,105,116,95,95,99,1,0,0,0,0,0,0,0, + 1,0,0,0,2,0,0,0,67,0,0,0,115,13,0,0, + 0,100,3,0,124,0,0,95,0,0,100,2,0,83,41,4, + 122,31,73,110,118,97,108,105,100,97,116,101,32,116,104,101, + 32,100,105,114,101,99,116,111,114,121,32,109,116,105,109,101, + 46,114,29,0,0,0,78,114,139,0,0,0,41,1,114,89, + 1,0,0,41,1,114,71,0,0,0,114,4,0,0,0,114, + 4,0,0,0,114,5,0,0,0,114,74,1,0,0,169,7, + 0,0,115,2,0,0,0,0,2,122,28,70,105,108,101,70, + 105,110,100,101,114,46,105,110,118,97,108,105,100,97,116,101, + 95,99,97,99,104,101,115,99,2,0,0,0,0,0,0,0, + 3,0,0,0,2,0,0,0,67,0,0,0,115,59,0,0, + 0,124,0,0,106,0,0,124,1,0,131,1,0,125,2,0, + 124,2,0,100,1,0,107,8,0,114,37,0,100,1,0,103, + 0,0,102,2,0,83,124,2,0,106,1,0,124,2,0,106, + 2,0,112,55,0,103,0,0,102,2,0,83,41,2,122,197, + 84,114,121,32,116,111,32,102,105,110,100,32,97,32,108,111, + 97,100,101,114,32,102,111,114,32,116,104,101,32,115,112,101, + 99,105,102,105,101,100,32,109,111,100,117,108,101,44,32,111, + 114,32,116,104,101,32,110,97,109,101,115,112,97,99,101,10, + 32,32,32,32,32,32,32,32,112,97,99,107,97,103,101,32, + 112,111,114,116,105,111,110,115,46,32,82,101,116,117,114,110, + 115,32,40,108,111,97,100,101,114,44,32,108,105,115,116,45, + 111,102,45,112,111,114,116,105,111,110,115,41,46,10,10,32, + 32,32,32,32,32,32,32,84,104,105,115,32,109,101,116,104, + 111,100,32,105,115,32,100,101,112,114,101,99,97,116,101,100, + 46,32,32,85,115,101,32,102,105,110,100,95,115,112,101,99, + 40,41,32,105,110,115,116,101,97,100,46,10,10,32,32,32, + 32,32,32,32,32,78,41,3,114,12,1,0,0,114,170,0, + 0,0,114,220,0,0,0,41,3,114,71,0,0,0,114,159, + 0,0,0,114,177,0,0,0,114,4,0,0,0,114,4,0, + 0,0,114,5,0,0,0,114,166,0,0,0,175,7,0,0, + 115,8,0,0,0,0,7,15,1,12,1,10,1,122,22,70, + 105,108,101,70,105,110,100,101,114,46,102,105,110,100,95,108, + 111,97,100,101,114,99,6,0,0,0,0,0,0,0,7,0, + 0,0,7,0,0,0,67,0,0,0,115,40,0,0,0,124, + 1,0,124,2,0,124,3,0,131,2,0,125,6,0,116,0, + 0,124,2,0,124,3,0,100,1,0,124,6,0,100,2,0, + 124,4,0,131,2,2,83,41,3,78,114,170,0,0,0,114, + 220,0,0,0,41,1,114,239,0,0,0,41,7,114,71,0, + 0,0,114,243,0,0,0,114,159,0,0,0,114,35,0,0, + 0,114,228,0,0,0,114,11,1,0,0,114,170,0,0,0, 114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,114, - 97,1,0,0,251,7,0,0,115,6,0,0,0,12,2,6, - 2,12,4,114,97,1,0,0,99,3,0,0,0,0,0,0, - 0,5,0,0,0,4,0,0,0,67,0,0,0,115,91,0, - 0,0,124,1,0,106,0,0,100,1,0,124,2,0,100,2, - 0,24,131,2,0,125,3,0,116,1,0,124,3,0,131,1, - 0,124,2,0,107,0,0,114,55,0,116,2,0,100,3,0, - 131,1,0,130,1,0,110,0,0,124,3,0,100,4,0,25, - 125,4,0,124,0,0,114,87,0,100,5,0,106,3,0,124, - 4,0,124,0,0,131,2,0,83,124,4,0,83,41,6,122, - 50,82,101,115,111,108,118,101,32,97,32,114,101,108,97,116, - 105,118,101,32,109,111,100,117,108,101,32,110,97,109,101,32, - 116,111,32,97,110,32,97,98,115,111,108,117,116,101,32,111, - 110,101,46,114,116,0,0,0,114,29,0,0,0,122,50,97, - 116,116,101,109,112,116,101,100,32,114,101,108,97,116,105,118, - 101,32,105,109,112,111,114,116,32,98,101,121,111,110,100,32, - 116,111,112,45,108,101,118,101,108,32,112,97,99,107,97,103, - 101,114,84,0,0,0,122,5,123,125,46,123,125,41,4,114, - 34,0,0,0,114,31,0,0,0,114,133,0,0,0,114,47, - 0,0,0,41,5,114,67,0,0,0,218,7,112,97,99,107, - 97,103,101,218,5,108,101,118,101,108,90,4,98,105,116,115, - 90,4,98,97,115,101,114,4,0,0,0,114,4,0,0,0, - 114,5,0,0,0,218,13,95,114,101,115,111,108,118,101,95, - 110,97,109,101,8,8,0,0,115,10,0,0,0,0,2,22, - 1,18,1,15,1,10,1,114,100,1,0,0,99,3,0,0, - 0,0,0,0,0,10,0,0,0,27,0,0,0,67,0,0, - 0,115,49,1,0,0,116,0,0,106,1,0,115,28,0,116, - 2,0,106,3,0,100,1,0,116,4,0,131,2,0,1,110, - 0,0,124,0,0,116,0,0,106,5,0,107,6,0,125,3, - 0,120,255,0,116,0,0,106,1,0,68,93,240,0,125,4, - 0,116,6,0,131,0,0,143,108,0,1,121,13,0,124,4, - 0,106,7,0,125,5,0,87,110,69,0,4,116,8,0,107, - 10,0,114,153,0,1,1,1,124,4,0,106,9,0,124,0, - 0,124,1,0,131,2,0,125,6,0,124,6,0,100,2,0, - 107,8,0,114,134,0,119,53,0,110,0,0,116,10,0,124, - 0,0,124,6,0,131,2,0,125,7,0,89,110,19,0,88, - 124,5,0,124,0,0,124,1,0,124,2,0,131,3,0,125, - 7,0,87,100,2,0,81,88,124,7,0,100,2,0,107,9, - 0,114,53,0,124,3,0,12,114,30,1,124,0,0,116,0, - 0,106,5,0,107,6,0,114,30,1,116,0,0,106,5,0, - 124,0,0,25,125,8,0,121,13,0,124,8,0,106,11,0, - 125,9,0,87,110,22,0,4,116,8,0,107,10,0,114,6, - 1,1,1,1,124,7,0,83,89,113,34,1,88,124,9,0, - 100,2,0,107,8,0,114,23,1,124,7,0,83,124,9,0, - 83,113,37,1,124,7,0,83,113,53,0,113,53,0,87,100, - 2,0,83,100,2,0,83,41,3,122,23,70,105,110,100,32, - 97,32,109,111,100,117,108,101,39,115,32,108,111,97,100,101, - 114,46,122,22,115,121,115,46,109,101,116,97,95,112,97,116, - 104,32,105,115,32,101,109,112,116,121,78,41,12,114,7,0, - 0,0,218,9,109,101,116,97,95,112,97,116,104,114,166,0, - 0,0,114,167,0,0,0,114,168,0,0,0,114,73,0,0, - 0,114,97,1,0,0,114,10,1,0,0,114,209,0,0,0, - 114,11,1,0,0,114,173,0,0,0,114,208,0,0,0,41, - 10,114,67,0,0,0,114,35,0,0,0,114,9,1,0,0, - 90,9,105,115,95,114,101,108,111,97,100,114,73,1,0,0, - 114,10,1,0,0,114,169,0,0,0,114,177,0,0,0,114, - 179,0,0,0,114,208,0,0,0,114,4,0,0,0,114,4, - 0,0,0,114,5,0,0,0,114,244,0,0,0,17,8,0, - 0,115,50,0,0,0,0,2,9,1,19,4,15,1,16,1, - 10,1,3,1,13,1,13,1,18,1,12,1,6,1,20,2, - 24,1,12,2,22,1,13,1,3,1,13,1,13,4,9,2, - 12,1,4,2,7,2,11,2,114,244,0,0,0,99,3,0, - 0,0,0,0,0,0,4,0,0,0,4,0,0,0,67,0, - 0,0,115,194,0,0,0,116,0,0,124,0,0,116,1,0, - 131,2,0,115,45,0,116,2,0,100,1,0,106,3,0,116, - 4,0,124,0,0,131,1,0,131,1,0,131,1,0,130,1, - 0,110,0,0,124,2,0,100,2,0,107,0,0,114,72,0, - 116,5,0,100,3,0,131,1,0,130,1,0,110,0,0,124, - 1,0,114,156,0,116,0,0,124,1,0,116,1,0,131,2, - 0,115,108,0,116,2,0,100,4,0,131,1,0,130,1,0, - 113,156,0,124,1,0,116,6,0,106,7,0,107,7,0,114, - 156,0,100,5,0,125,3,0,116,8,0,124,3,0,106,3, - 0,124,1,0,131,1,0,131,1,0,130,1,0,113,156,0, - 110,0,0,124,0,0,12,114,190,0,124,2,0,100,2,0, - 107,2,0,114,190,0,116,5,0,100,6,0,131,1,0,130, - 1,0,110,0,0,100,7,0,83,41,8,122,28,86,101,114, + 86,1,0,0,187,7,0,0,115,6,0,0,0,0,1,15, + 1,18,1,122,20,70,105,108,101,70,105,110,100,101,114,46, + 95,103,101,116,95,115,112,101,99,78,99,3,0,0,0,0, + 0,0,0,14,0,0,0,15,0,0,0,67,0,0,0,115, + 231,1,0,0,100,1,0,125,3,0,124,1,0,106,0,0, + 100,2,0,131,1,0,100,3,0,25,125,4,0,121,34,0, + 116,1,0,124,0,0,106,2,0,112,49,0,116,3,0,106, + 4,0,131,0,0,131,1,0,106,5,0,125,5,0,87,110, + 24,0,4,116,6,0,107,10,0,114,85,0,1,1,1,100, + 10,0,125,5,0,89,110,1,0,88,124,5,0,124,0,0, + 106,7,0,107,3,0,114,120,0,124,0,0,106,8,0,131, + 0,0,1,124,5,0,124,0,0,95,7,0,116,9,0,131, + 0,0,114,153,0,124,0,0,106,10,0,125,6,0,124,4, + 0,106,11,0,131,0,0,125,7,0,110,15,0,124,0,0, + 106,12,0,125,6,0,124,4,0,125,7,0,124,7,0,124, + 6,0,107,6,0,114,45,1,116,13,0,124,0,0,106,2, + 0,124,4,0,131,2,0,125,8,0,120,100,0,124,0,0, + 106,14,0,68,93,77,0,92,2,0,125,9,0,125,10,0, + 100,5,0,124,9,0,23,125,11,0,116,13,0,124,8,0, + 124,11,0,131,2,0,125,12,0,116,15,0,124,12,0,131, + 1,0,114,208,0,124,0,0,106,16,0,124,10,0,124,1, + 0,124,12,0,124,8,0,103,1,0,124,2,0,131,5,0, + 83,113,208,0,87,116,17,0,124,8,0,131,1,0,125,3, + 0,120,123,0,124,0,0,106,14,0,68,93,112,0,92,2, + 0,125,9,0,125,10,0,116,13,0,124,0,0,106,2,0, + 124,4,0,124,9,0,23,131,2,0,125,12,0,116,18,0, + 100,6,0,106,19,0,124,12,0,131,1,0,100,7,0,100, + 3,0,131,1,1,1,124,7,0,124,9,0,23,124,6,0, + 107,6,0,114,55,1,116,15,0,124,12,0,131,1,0,114, + 55,1,124,0,0,106,16,0,124,10,0,124,1,0,124,12, + 0,100,8,0,124,2,0,131,5,0,83,113,55,1,87,124, + 3,0,114,227,1,116,18,0,100,9,0,106,19,0,124,8, + 0,131,1,0,131,1,0,1,116,20,0,124,1,0,100,8, + 0,131,2,0,125,13,0,124,8,0,103,1,0,124,13,0, + 95,21,0,124,13,0,83,100,8,0,83,41,11,122,125,84, + 114,121,32,116,111,32,102,105,110,100,32,97,32,108,111,97, + 100,101,114,32,102,111,114,32,116,104,101,32,115,112,101,99, + 105,102,105,101,100,32,109,111,100,117,108,101,44,32,111,114, + 32,116,104,101,32,110,97,109,101,115,112,97,99,101,10,32, + 32,32,32,32,32,32,32,112,97,99,107,97,103,101,32,112, + 111,114,116,105,111,110,115,46,32,82,101,116,117,114,110,115, + 32,40,108,111,97,100,101,114,44,32,108,105,115,116,45,111, + 102,45,112,111,114,116,105,111,110,115,41,46,70,114,116,0, + 0,0,114,115,0,0,0,114,29,0,0,0,114,72,0,0, + 0,122,9,116,114,121,105,110,103,32,123,125,114,146,0,0, + 0,78,122,25,112,111,115,115,105,98,108,101,32,110,97,109, + 101,115,112,97,99,101,32,102,111,114,32,123,125,114,139,0, + 0,0,41,22,114,32,0,0,0,114,39,0,0,0,114,35, + 0,0,0,114,3,0,0,0,114,45,0,0,0,114,53,1, + 0,0,114,40,0,0,0,114,89,1,0,0,218,11,95,102, + 105,108,108,95,99,97,99,104,101,114,6,0,0,0,114,92, + 1,0,0,114,140,0,0,0,114,91,1,0,0,114,28,0, + 0,0,114,88,1,0,0,114,44,0,0,0,114,86,1,0, + 0,114,46,0,0,0,114,153,0,0,0,114,47,0,0,0, + 114,216,0,0,0,114,220,0,0,0,41,14,114,71,0,0, + 0,114,159,0,0,0,114,11,1,0,0,90,12,105,115,95, + 110,97,109,101,115,112,97,99,101,90,11,116,97,105,108,95, + 109,111,100,117,108,101,114,182,0,0,0,90,5,99,97,99, + 104,101,90,12,99,97,99,104,101,95,109,111,100,117,108,101, + 90,9,98,97,115,101,95,112,97,116,104,114,57,1,0,0, + 114,243,0,0,0,90,13,105,110,105,116,95,102,105,108,101, + 110,97,109,101,90,9,102,117,108,108,95,112,97,116,104,114, + 177,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5, + 0,0,0,114,12,1,0,0,192,7,0,0,115,68,0,0, + 0,0,3,6,1,19,1,3,1,34,1,13,1,11,1,15, + 1,10,1,9,2,9,1,9,1,15,2,9,1,6,2,12, + 1,18,1,22,1,10,1,15,1,12,1,32,4,12,2,22, + 1,22,1,25,1,16,1,12,1,29,1,6,1,19,1,15, + 1,12,1,4,1,122,20,70,105,108,101,70,105,110,100,101, + 114,46,102,105,110,100,95,115,112,101,99,99,1,0,0,0, + 0,0,0,0,9,0,0,0,13,0,0,0,67,0,0,0, + 115,11,1,0,0,124,0,0,106,0,0,125,1,0,121,31, + 0,116,1,0,106,2,0,124,1,0,112,33,0,116,1,0, + 106,3,0,131,0,0,131,1,0,125,2,0,87,110,33,0, + 4,116,4,0,116,5,0,116,6,0,102,3,0,107,10,0, + 114,75,0,1,1,1,103,0,0,125,2,0,89,110,1,0, + 88,116,7,0,106,8,0,106,9,0,100,1,0,131,1,0, + 115,112,0,116,10,0,124,2,0,131,1,0,124,0,0,95, + 11,0,110,111,0,116,10,0,131,0,0,125,3,0,120,90, + 0,124,2,0,68,93,82,0,125,4,0,124,4,0,106,12, + 0,100,2,0,131,1,0,92,3,0,125,5,0,125,6,0, + 125,7,0,124,6,0,114,191,0,100,3,0,106,13,0,124, + 5,0,124,7,0,106,14,0,131,0,0,131,2,0,125,8, + 0,110,6,0,124,5,0,125,8,0,124,3,0,106,15,0, + 124,8,0,131,1,0,1,113,128,0,87,124,3,0,124,0, + 0,95,11,0,116,7,0,106,8,0,106,9,0,116,16,0, + 131,1,0,114,7,1,100,4,0,100,5,0,132,0,0,124, + 2,0,68,131,1,0,124,0,0,95,17,0,100,6,0,83, + 41,7,122,68,70,105,108,108,32,116,104,101,32,99,97,99, + 104,101,32,111,102,32,112,111,116,101,110,116,105,97,108,32, + 109,111,100,117,108,101,115,32,97,110,100,32,112,97,99,107, + 97,103,101,115,32,102,111,114,32,116,104,105,115,32,100,105, + 114,101,99,116,111,114,121,46,114,0,0,0,0,114,116,0, + 0,0,122,5,123,125,46,123,125,99,1,0,0,0,0,0, + 0,0,2,0,0,0,3,0,0,0,83,0,0,0,115,28, + 0,0,0,104,0,0,124,0,0,93,18,0,125,1,0,124, + 1,0,106,0,0,131,0,0,146,2,0,113,6,0,83,114, + 4,0,0,0,41,1,114,140,0,0,0,41,2,114,22,0, + 0,0,90,2,102,110,114,4,0,0,0,114,4,0,0,0, + 114,5,0,0,0,250,9,60,115,101,116,99,111,109,112,62, + 10,8,0,0,115,2,0,0,0,9,0,122,41,70,105,108, + 101,70,105,110,100,101,114,46,95,102,105,108,108,95,99,97, + 99,104,101,46,60,108,111,99,97,108,115,62,46,60,115,101, + 116,99,111,109,112,62,78,41,18,114,35,0,0,0,114,3, + 0,0,0,90,7,108,105,115,116,100,105,114,114,45,0,0, + 0,114,80,1,0,0,218,15,80,101,114,109,105,115,115,105, + 111,110,69,114,114,111,114,218,18,78,111,116,65,68,105,114, + 101,99,116,111,114,121,69,114,114,111,114,114,7,0,0,0, + 114,8,0,0,0,114,9,0,0,0,114,90,1,0,0,114, + 91,1,0,0,114,134,0,0,0,114,47,0,0,0,114,140, + 0,0,0,218,3,97,100,100,114,10,0,0,0,114,92,1, + 0,0,41,9,114,71,0,0,0,114,35,0,0,0,90,8, + 99,111,110,116,101,110,116,115,90,21,108,111,119,101,114,95, + 115,117,102,102,105,120,95,99,111,110,116,101,110,116,115,114, + 71,1,0,0,114,67,0,0,0,114,65,1,0,0,114,57, + 1,0,0,90,8,110,101,119,95,110,97,109,101,114,4,0, + 0,0,114,4,0,0,0,114,5,0,0,0,114,94,1,0, + 0,237,7,0,0,115,34,0,0,0,0,2,9,1,3,1, + 31,1,22,3,11,3,18,1,18,7,9,1,13,1,24,1, + 6,1,27,2,6,1,17,1,9,1,18,1,122,22,70,105, + 108,101,70,105,110,100,101,114,46,95,102,105,108,108,95,99, + 97,99,104,101,99,1,0,0,0,0,0,0,0,3,0,0, + 0,3,0,0,0,7,0,0,0,115,25,0,0,0,135,0, + 0,135,1,0,102,2,0,100,1,0,100,2,0,134,0,0, + 125,2,0,124,2,0,83,41,3,97,20,1,0,0,65,32, + 99,108,97,115,115,32,109,101,116,104,111,100,32,119,104,105, + 99,104,32,114,101,116,117,114,110,115,32,97,32,99,108,111, + 115,117,114,101,32,116,111,32,117,115,101,32,111,110,32,115, + 121,115,46,112,97,116,104,95,104,111,111,107,10,32,32,32, + 32,32,32,32,32,119,104,105,99,104,32,119,105,108,108,32, + 114,101,116,117,114,110,32,97,110,32,105,110,115,116,97,110, + 99,101,32,117,115,105,110,103,32,116,104,101,32,115,112,101, + 99,105,102,105,101,100,32,108,111,97,100,101,114,115,32,97, + 110,100,32,116,104,101,32,112,97,116,104,10,32,32,32,32, + 32,32,32,32,99,97,108,108,101,100,32,111,110,32,116,104, + 101,32,99,108,111,115,117,114,101,46,10,10,32,32,32,32, + 32,32,32,32,73,102,32,116,104,101,32,112,97,116,104,32, + 99,97,108,108,101,100,32,111,110,32,116,104,101,32,99,108, + 111,115,117,114,101,32,105,115,32,110,111,116,32,97,32,100, + 105,114,101,99,116,111,114,121,44,32,73,109,112,111,114,116, + 69,114,114,111,114,32,105,115,10,32,32,32,32,32,32,32, + 32,114,97,105,115,101,100,46,10,10,32,32,32,32,32,32, + 32,32,99,1,0,0,0,0,0,0,0,1,0,0,0,4, + 0,0,0,19,0,0,0,115,43,0,0,0,116,0,0,124, + 0,0,131,1,0,115,30,0,116,1,0,100,1,0,100,2, + 0,124,0,0,131,1,1,130,1,0,136,0,0,124,0,0, + 136,1,0,140,1,0,83,41,3,122,45,80,97,116,104,32, + 104,111,111,107,32,102,111,114,32,105,109,112,111,114,116,108, + 105,98,46,109,97,99,104,105,110,101,114,121,46,70,105,108, + 101,70,105,110,100,101,114,46,122,30,111,110,108,121,32,100, + 105,114,101,99,116,111,114,105,101,115,32,97,114,101,32,115, + 117,112,112,111,114,116,101,100,114,35,0,0,0,41,2,114, + 46,0,0,0,114,154,0,0,0,41,1,114,35,0,0,0, + 41,2,114,10,1,0,0,114,93,1,0,0,114,4,0,0, + 0,114,5,0,0,0,218,24,112,97,116,104,95,104,111,111, + 107,95,102,111,114,95,70,105,108,101,70,105,110,100,101,114, + 22,8,0,0,115,6,0,0,0,0,2,12,1,18,1,122, + 54,70,105,108,101,70,105,110,100,101,114,46,112,97,116,104, + 95,104,111,111,107,46,60,108,111,99,97,108,115,62,46,112, + 97,116,104,95,104,111,111,107,95,102,111,114,95,70,105,108, + 101,70,105,110,100,101,114,114,4,0,0,0,41,3,114,10, + 1,0,0,114,93,1,0,0,114,99,1,0,0,114,4,0, + 0,0,41,2,114,10,1,0,0,114,93,1,0,0,114,5, + 0,0,0,218,9,112,97,116,104,95,104,111,111,107,12,8, + 0,0,115,4,0,0,0,0,10,21,6,122,20,70,105,108, + 101,70,105,110,100,101,114,46,112,97,116,104,95,104,111,111, + 107,99,1,0,0,0,0,0,0,0,1,0,0,0,2,0, + 0,0,67,0,0,0,115,16,0,0,0,100,1,0,106,0, + 0,124,0,0,106,1,0,131,1,0,83,41,2,78,122,16, + 70,105,108,101,70,105,110,100,101,114,40,123,33,114,125,41, + 41,2,114,47,0,0,0,114,35,0,0,0,41,1,114,71, + 0,0,0,114,4,0,0,0,114,4,0,0,0,114,5,0, + 0,0,114,101,0,0,0,30,8,0,0,115,2,0,0,0, + 0,1,122,19,70,105,108,101,70,105,110,100,101,114,46,95, + 95,114,101,112,114,95,95,41,15,114,57,0,0,0,114,56, + 0,0,0,114,58,0,0,0,114,59,0,0,0,114,72,0, + 0,0,114,74,1,0,0,114,173,0,0,0,114,13,1,0, + 0,114,166,0,0,0,114,86,1,0,0,114,12,1,0,0, + 114,94,1,0,0,114,17,1,0,0,114,100,1,0,0,114, + 101,0,0,0,114,4,0,0,0,114,4,0,0,0,114,4, + 0,0,0,114,5,0,0,0,114,87,1,0,0,146,7,0, + 0,115,20,0,0,0,12,7,6,2,12,14,12,4,6,2, + 12,12,12,5,15,45,12,31,18,18,114,87,1,0,0,99, + 0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0, + 64,0,0,0,115,46,0,0,0,101,0,0,90,1,0,100, + 0,0,90,2,0,100,1,0,90,3,0,100,2,0,100,3, + 0,132,0,0,90,4,0,100,4,0,100,5,0,132,0,0, + 90,5,0,100,6,0,83,41,7,218,18,95,73,109,112,111, + 114,116,76,111,99,107,67,111,110,116,101,120,116,122,36,67, + 111,110,116,101,120,116,32,109,97,110,97,103,101,114,32,102, + 111,114,32,116,104,101,32,105,109,112,111,114,116,32,108,111, + 99,107,46,99,1,0,0,0,0,0,0,0,1,0,0,0, + 1,0,0,0,67,0,0,0,115,14,0,0,0,116,0,0, + 106,1,0,131,0,0,1,100,1,0,83,41,2,122,24,65, + 99,113,117,105,114,101,32,116,104,101,32,105,109,112,111,114, + 116,32,108,111,99,107,46,78,41,2,114,106,0,0,0,114, + 2,1,0,0,41,1,114,71,0,0,0,114,4,0,0,0, + 114,4,0,0,0,114,5,0,0,0,114,75,0,0,0,40, + 8,0,0,115,2,0,0,0,0,2,122,28,95,73,109,112, + 111,114,116,76,111,99,107,67,111,110,116,101,120,116,46,95, + 95,101,110,116,101,114,95,95,99,4,0,0,0,0,0,0, + 0,4,0,0,0,1,0,0,0,67,0,0,0,115,14,0, + 0,0,116,0,0,106,1,0,131,0,0,1,100,1,0,83, + 41,2,122,60,82,101,108,101,97,115,101,32,116,104,101,32, + 105,109,112,111,114,116,32,108,111,99,107,32,114,101,103,97, + 114,100,108,101,115,115,32,111,102,32,97,110,121,32,114,97, + 105,115,101,100,32,101,120,99,101,112,116,105,111,110,115,46, + 78,41,2,114,106,0,0,0,114,107,0,0,0,41,4,114, + 71,0,0,0,90,8,101,120,99,95,116,121,112,101,90,9, + 101,120,99,95,118,97,108,117,101,90,13,101,120,99,95,116, + 114,97,99,101,98,97,99,107,114,4,0,0,0,114,4,0, + 0,0,114,5,0,0,0,114,81,0,0,0,44,8,0,0, + 115,2,0,0,0,0,2,122,27,95,73,109,112,111,114,116, + 76,111,99,107,67,111,110,116,101,120,116,46,95,95,101,120, + 105,116,95,95,78,41,6,114,57,0,0,0,114,56,0,0, + 0,114,58,0,0,0,114,59,0,0,0,114,75,0,0,0, + 114,81,0,0,0,114,4,0,0,0,114,4,0,0,0,114, + 4,0,0,0,114,5,0,0,0,114,101,1,0,0,36,8, + 0,0,115,6,0,0,0,12,2,6,2,12,4,114,101,1, + 0,0,99,3,0,0,0,0,0,0,0,5,0,0,0,4, + 0,0,0,67,0,0,0,115,88,0,0,0,124,1,0,106, + 0,0,100,1,0,124,2,0,100,2,0,24,131,2,0,125, + 3,0,116,1,0,124,3,0,131,1,0,124,2,0,107,0, + 0,114,52,0,116,2,0,100,3,0,131,1,0,130,1,0, + 124,3,0,100,4,0,25,125,4,0,124,0,0,114,84,0, + 100,5,0,106,3,0,124,4,0,124,0,0,131,2,0,83, + 124,4,0,83,41,6,122,50,82,101,115,111,108,118,101,32, + 97,32,114,101,108,97,116,105,118,101,32,109,111,100,117,108, + 101,32,110,97,109,101,32,116,111,32,97,110,32,97,98,115, + 111,108,117,116,101,32,111,110,101,46,114,116,0,0,0,114, + 29,0,0,0,122,50,97,116,116,101,109,112,116,101,100,32, + 114,101,108,97,116,105,118,101,32,105,109,112,111,114,116,32, + 98,101,121,111,110,100,32,116,111,112,45,108,101,118,101,108, + 32,112,97,99,107,97,103,101,114,84,0,0,0,122,5,123, + 125,46,123,125,41,4,114,34,0,0,0,114,31,0,0,0, + 114,133,0,0,0,114,47,0,0,0,41,5,114,67,0,0, + 0,218,7,112,97,99,107,97,103,101,218,5,108,101,118,101, + 108,90,4,98,105,116,115,114,128,0,0,0,114,4,0,0, + 0,114,4,0,0,0,114,5,0,0,0,218,13,95,114,101, + 115,111,108,118,101,95,110,97,109,101,49,8,0,0,115,10, + 0,0,0,0,2,22,1,18,1,12,1,10,1,114,104,1, + 0,0,99,3,0,0,0,0,0,0,0,4,0,0,0,3, + 0,0,0,67,0,0,0,115,47,0,0,0,124,0,0,106, + 0,0,124,1,0,124,2,0,131,2,0,125,3,0,124,3, + 0,100,0,0,107,8,0,114,34,0,100,0,0,83,116,1, + 0,124,1,0,124,3,0,131,2,0,83,41,1,78,41,2, + 114,13,1,0,0,114,174,0,0,0,41,4,114,77,1,0, + 0,114,67,0,0,0,114,35,0,0,0,114,170,0,0,0, + 114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,218, + 17,95,102,105,110,100,95,115,112,101,99,95,108,101,103,97, + 99,121,58,8,0,0,115,8,0,0,0,0,3,18,1,12, + 1,4,1,114,105,1,0,0,99,3,0,0,0,0,0,0, + 0,9,0,0,0,26,0,0,0,67,0,0,0,115,41,1, + 0,0,116,0,0,106,1,0,100,1,0,107,9,0,114,41, + 0,116,0,0,106,1,0,12,114,41,0,116,2,0,106,3, + 0,100,2,0,116,4,0,131,2,0,1,124,0,0,116,0, + 0,106,5,0,107,6,0,125,3,0,120,234,0,116,0,0, + 106,1,0,68,93,219,0,125,4,0,116,6,0,131,0,0, + 143,90,0,1,121,13,0,124,4,0,106,7,0,125,5,0, + 87,110,51,0,4,116,8,0,107,10,0,114,148,0,1,1, + 1,116,9,0,124,4,0,124,0,0,124,1,0,131,3,0, + 125,6,0,124,6,0,100,1,0,107,8,0,114,144,0,119, + 66,0,89,110,19,0,88,124,5,0,124,0,0,124,1,0, + 124,2,0,131,3,0,125,6,0,87,100,1,0,81,88,124, + 6,0,100,1,0,107,9,0,114,66,0,124,3,0,12,114, + 25,1,124,0,0,116,0,0,106,5,0,107,6,0,114,25, + 1,116,0,0,106,5,0,124,0,0,25,125,7,0,121,13, + 0,124,7,0,106,10,0,125,8,0,87,110,22,0,4,116, + 8,0,107,10,0,114,1,1,1,1,1,124,6,0,83,89, + 113,29,1,88,124,8,0,100,1,0,107,8,0,114,18,1, + 124,6,0,83,124,8,0,83,113,66,0,124,6,0,83,113, + 66,0,87,100,1,0,83,100,1,0,83,41,3,122,23,70, + 105,110,100,32,97,32,109,111,100,117,108,101,39,115,32,108, + 111,97,100,101,114,46,78,122,22,115,121,115,46,109,101,116, + 97,95,112,97,116,104,32,105,115,32,101,109,112,116,121,41, + 11,114,7,0,0,0,218,9,109,101,116,97,95,112,97,116, + 104,114,167,0,0,0,114,168,0,0,0,114,169,0,0,0, + 114,73,0,0,0,114,101,1,0,0,114,12,1,0,0,114, + 208,0,0,0,114,105,1,0,0,114,207,0,0,0,41,9, + 114,67,0,0,0,114,35,0,0,0,114,11,1,0,0,90, + 9,105,115,95,114,101,108,111,97,100,114,77,1,0,0,114, + 12,1,0,0,114,177,0,0,0,114,178,0,0,0,114,207, + 0,0,0,114,4,0,0,0,114,4,0,0,0,114,5,0, + 0,0,218,10,95,102,105,110,100,95,115,112,101,99,67,8, + 0,0,115,48,0,0,0,0,2,25,1,16,4,15,1,16, + 1,10,1,3,1,13,1,13,1,18,1,12,1,8,2,24, + 1,12,2,22,1,13,1,3,1,13,1,13,4,9,2,12, + 1,4,2,7,2,8,2,114,107,1,0,0,99,3,0,0, + 0,0,0,0,0,4,0,0,0,4,0,0,0,67,0,0, + 0,115,179,0,0,0,116,0,0,124,0,0,116,1,0,131, + 2,0,115,42,0,116,2,0,100,1,0,106,3,0,116,4, + 0,124,0,0,131,1,0,131,1,0,131,1,0,130,1,0, + 124,2,0,100,2,0,107,0,0,114,66,0,116,5,0,100, + 3,0,131,1,0,130,1,0,124,1,0,114,144,0,116,0, + 0,124,1,0,116,1,0,131,2,0,115,102,0,116,2,0, + 100,4,0,131,1,0,130,1,0,110,42,0,124,1,0,116, + 6,0,106,7,0,107,7,0,114,144,0,100,5,0,125,3, + 0,116,8,0,124,3,0,106,3,0,124,1,0,131,1,0, + 131,1,0,130,1,0,124,0,0,12,114,175,0,124,2,0, + 100,2,0,107,2,0,114,175,0,116,5,0,100,6,0,131, + 1,0,130,1,0,100,7,0,83,41,8,122,28,86,101,114, 105,102,121,32,97,114,103,117,109,101,110,116,115,32,97,114, 101,32,34,115,97,110,101,34,46,122,31,109,111,100,117,108, 101,32,110,97,109,101,32,109,117,115,116,32,98,101,32,115, @@ -3806,322 +3842,316 @@ const unsigned char _Py_M__importlib[] = { 100,101,100,44,32,99,97,110,110,111,116,32,112,101,114,102, 111,114,109,32,114,101,108,97,116,105,118,101,32,105,109,112, 111,114,116,122,17,69,109,112,116,121,32,109,111,100,117,108, - 101,32,110,97,109,101,78,41,9,114,192,0,0,0,114,78, + 101,32,110,97,109,101,78,41,9,114,191,0,0,0,114,83, 1,0,0,218,9,84,121,112,101,69,114,114,111,114,114,47, 0,0,0,114,66,0,0,0,114,133,0,0,0,114,7,0, 0,0,114,73,0,0,0,218,11,83,121,115,116,101,109,69, - 114,114,111,114,41,4,114,67,0,0,0,114,98,1,0,0, - 114,99,1,0,0,114,171,0,0,0,114,4,0,0,0,114, + 114,114,111,114,41,4,114,67,0,0,0,114,102,1,0,0, + 114,103,1,0,0,114,172,0,0,0,114,4,0,0,0,114, 4,0,0,0,114,5,0,0,0,218,13,95,115,97,110,105, - 116,121,95,99,104,101,99,107,58,8,0,0,115,24,0,0, - 0,0,2,15,1,30,1,12,1,15,1,6,1,15,1,15, - 1,15,1,6,2,27,1,19,1,114,104,1,0,0,122,16, + 116,121,95,99,104,101,99,107,107,8,0,0,115,24,0,0, + 0,0,2,15,1,27,1,12,1,12,1,6,1,15,1,15, + 1,15,1,6,2,21,1,19,1,114,110,1,0,0,122,16, 78,111,32,109,111,100,117,108,101,32,110,97,109,101,100,32, 122,4,123,33,114,125,99,2,0,0,0,0,0,0,0,8, - 0,0,0,12,0,0,0,67,0,0,0,115,52,1,0,0, + 0,0,0,12,0,0,0,67,0,0,0,115,40,1,0,0, 100,0,0,125,2,0,124,0,0,106,0,0,100,1,0,131, - 1,0,100,2,0,25,125,3,0,124,3,0,114,178,0,124, - 3,0,116,1,0,106,2,0,107,7,0,114,62,0,116,3, - 0,124,1,0,124,3,0,131,2,0,1,110,0,0,124,0, - 0,116,1,0,106,2,0,107,6,0,114,88,0,116,1,0, - 106,2,0,124,0,0,25,83,116,1,0,106,2,0,124,3, - 0,25,125,4,0,121,13,0,124,4,0,106,4,0,125,2, - 0,87,113,178,0,4,116,5,0,107,10,0,114,174,0,1, - 1,1,116,6,0,100,3,0,23,106,7,0,124,0,0,124, - 3,0,131,2,0,125,5,0,116,8,0,124,5,0,100,4, - 0,124,0,0,131,1,1,130,1,0,89,113,178,0,88,110, - 0,0,116,9,0,124,0,0,124,2,0,131,2,0,125,6, - 0,124,6,0,100,0,0,107,8,0,114,235,0,116,8,0, - 116,6,0,106,7,0,124,0,0,131,1,0,100,4,0,124, - 0,0,131,1,1,130,1,0,110,18,0,116,10,0,124,6, - 0,131,1,0,106,11,0,131,0,0,125,7,0,124,3,0, - 114,48,1,116,1,0,106,2,0,124,3,0,25,125,4,0, - 116,12,0,124,4,0,124,0,0,106,0,0,100,1,0,131, - 1,0,100,5,0,25,124,7,0,131,3,0,1,110,0,0, - 124,7,0,83,41,6,78,114,116,0,0,0,114,84,0,0, - 0,122,23,59,32,123,33,114,125,32,105,115,32,110,111,116, - 32,97,32,112,97,99,107,97,103,101,114,67,0,0,0,114, - 115,0,0,0,41,13,114,32,0,0,0,114,7,0,0,0, - 114,73,0,0,0,114,114,0,0,0,114,242,0,0,0,114, - 209,0,0,0,218,8,95,69,82,82,95,77,83,71,114,47, - 0,0,0,114,153,0,0,0,114,244,0,0,0,114,174,0, - 0,0,114,6,1,0,0,114,61,0,0,0,41,8,114,67, - 0,0,0,218,7,105,109,112,111,114,116,95,114,35,0,0, - 0,114,231,0,0,0,90,13,112,97,114,101,110,116,95,109, - 111,100,117,108,101,114,171,0,0,0,114,177,0,0,0,114, - 179,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5, - 0,0,0,218,23,95,102,105,110,100,95,97,110,100,95,108, - 111,97,100,95,117,110,108,111,99,107,101,100,78,8,0,0, - 115,42,0,0,0,0,1,6,1,19,1,6,1,15,1,16, - 2,15,1,11,1,13,1,3,1,13,1,13,1,22,1,26, - 1,15,1,12,1,30,2,18,1,6,2,13,1,32,1,114, - 107,1,0,0,99,2,0,0,0,0,0,0,0,2,0,0, - 0,10,0,0,0,67,0,0,0,115,36,0,0,0,116,0, - 0,124,0,0,131,1,0,143,18,0,1,116,1,0,124,0, - 0,124,1,0,131,2,0,83,87,100,1,0,81,88,100,1, - 0,83,41,2,122,54,70,105,110,100,32,97,110,100,32,108, - 111,97,100,32,116,104,101,32,109,111,100,117,108,101,44,32, - 97,110,100,32,114,101,108,101,97,115,101,32,116,104,101,32, - 105,109,112,111,114,116,32,108,111,99,107,46,78,41,2,114, - 103,0,0,0,114,107,1,0,0,41,2,114,67,0,0,0, - 114,106,1,0,0,114,4,0,0,0,114,4,0,0,0,114, - 5,0,0,0,218,14,95,102,105,110,100,95,97,110,100,95, - 108,111,97,100,105,8,0,0,115,4,0,0,0,0,2,13, - 1,114,108,1,0,0,99,3,0,0,0,0,0,0,0,5, - 0,0,0,4,0,0,0,67,0,0,0,115,172,0,0,0, - 116,0,0,124,0,0,124,1,0,124,2,0,131,3,0,1, - 124,2,0,100,1,0,107,4,0,114,49,0,116,1,0,124, - 0,0,124,1,0,124,2,0,131,3,0,125,0,0,110,0, - 0,116,2,0,106,3,0,131,0,0,1,124,0,0,116,4, - 0,106,5,0,107,7,0,114,87,0,116,6,0,124,0,0, - 116,7,0,131,2,0,83,116,4,0,106,5,0,124,0,0, - 25,125,3,0,124,3,0,100,2,0,107,8,0,114,158,0, - 116,2,0,106,8,0,131,0,0,1,100,3,0,106,9,0, - 124,0,0,131,1,0,125,4,0,116,10,0,124,4,0,100, - 4,0,124,0,0,131,1,1,130,1,0,110,0,0,116,11, - 0,124,0,0,131,1,0,1,124,3,0,83,41,5,97,50, - 1,0,0,73,109,112,111,114,116,32,97,110,100,32,114,101, - 116,117,114,110,32,116,104,101,32,109,111,100,117,108,101,32, - 98,97,115,101,100,32,111,110,32,105,116,115,32,110,97,109, - 101,44,32,116,104,101,32,112,97,99,107,97,103,101,32,116, - 104,101,32,99,97,108,108,32,105,115,10,32,32,32,32,98, - 101,105,110,103,32,109,97,100,101,32,102,114,111,109,44,32, - 97,110,100,32,116,104,101,32,108,101,118,101,108,32,97,100, - 106,117,115,116,109,101,110,116,46,10,10,32,32,32,32,84, - 104,105,115,32,102,117,110,99,116,105,111,110,32,114,101,112, - 114,101,115,101,110,116,115,32,116,104,101,32,103,114,101,97, - 116,101,115,116,32,99,111,109,109,111,110,32,100,101,110,111, - 109,105,110,97,116,111,114,32,111,102,32,102,117,110,99,116, - 105,111,110,97,108,105,116,121,10,32,32,32,32,98,101,116, - 119,101,101,110,32,105,109,112,111,114,116,95,109,111,100,117, - 108,101,32,97,110,100,32,95,95,105,109,112,111,114,116,95, - 95,46,32,84,104,105,115,32,105,110,99,108,117,100,101,115, - 32,115,101,116,116,105,110,103,32,95,95,112,97,99,107,97, - 103,101,95,95,32,105,102,10,32,32,32,32,116,104,101,32, - 108,111,97,100,101,114,32,100,105,100,32,110,111,116,46,10, - 10,32,32,32,32,114,84,0,0,0,78,122,40,105,109,112, - 111,114,116,32,111,102,32,123,125,32,104,97,108,116,101,100, - 59,32,78,111,110,101,32,105,110,32,115,121,115,46,109,111, - 100,117,108,101,115,114,67,0,0,0,41,12,114,104,1,0, - 0,114,100,1,0,0,114,106,0,0,0,114,2,1,0,0, - 114,7,0,0,0,114,73,0,0,0,114,108,1,0,0,218, - 11,95,103,99,100,95,105,109,112,111,114,116,114,107,0,0, - 0,114,47,0,0,0,114,153,0,0,0,114,112,0,0,0, - 41,5,114,67,0,0,0,114,98,1,0,0,114,99,1,0, - 0,114,179,0,0,0,114,151,0,0,0,114,4,0,0,0, - 114,4,0,0,0,114,5,0,0,0,114,109,1,0,0,111, - 8,0,0,115,26,0,0,0,0,9,16,1,12,1,21,1, - 10,1,15,1,13,1,13,1,12,1,10,2,15,1,21,1, - 10,1,114,109,1,0,0,99,3,0,0,0,0,0,0,0, - 6,0,0,0,17,0,0,0,67,0,0,0,115,1,1,0, - 0,116,0,0,124,0,0,100,1,0,131,2,0,114,253,0, - 100,2,0,124,1,0,107,6,0,114,89,0,116,1,0,124, - 1,0,131,1,0,125,1,0,124,1,0,106,2,0,100,2, - 0,131,1,0,1,116,0,0,124,0,0,100,3,0,131,2, - 0,114,89,0,124,1,0,106,3,0,124,0,0,106,4,0, - 131,1,0,1,113,89,0,110,0,0,120,161,0,124,1,0, - 68,93,150,0,125,3,0,116,0,0,124,0,0,124,3,0, - 131,2,0,115,96,0,100,4,0,106,5,0,124,0,0,106, - 6,0,124,3,0,131,2,0,125,4,0,121,17,0,116,7, - 0,124,2,0,124,4,0,131,2,0,1,87,113,246,0,4, - 116,8,0,107,10,0,114,242,0,1,125,5,0,1,122,53, - 0,116,9,0,124,5,0,131,1,0,106,10,0,116,11,0, - 131,1,0,114,221,0,124,5,0,106,12,0,124,4,0,107, - 2,0,114,221,0,119,96,0,113,221,0,110,0,0,130,0, - 0,87,89,100,5,0,100,5,0,125,5,0,126,5,0,88, - 113,246,0,88,113,96,0,113,96,0,87,110,0,0,124,0, - 0,83,41,6,122,238,70,105,103,117,114,101,32,111,117,116, - 32,119,104,97,116,32,95,95,105,109,112,111,114,116,95,95, - 32,115,104,111,117,108,100,32,114,101,116,117,114,110,46,10, - 10,32,32,32,32,84,104,101,32,105,109,112,111,114,116,95, - 32,112,97,114,97,109,101,116,101,114,32,105,115,32,97,32, - 99,97,108,108,97,98,108,101,32,119,104,105,99,104,32,116, - 97,107,101,115,32,116,104,101,32,110,97,109,101,32,111,102, - 32,109,111,100,117,108,101,32,116,111,10,32,32,32,32,105, - 109,112,111,114,116,46,32,73,116,32,105,115,32,114,101,113, - 117,105,114,101,100,32,116,111,32,100,101,99,111,117,112,108, - 101,32,116,104,101,32,102,117,110,99,116,105,111,110,32,102, - 114,111,109,32,97,115,115,117,109,105,110,103,32,105,109,112, - 111,114,116,108,105,98,39,115,10,32,32,32,32,105,109,112, - 111,114,116,32,105,109,112,108,101,109,101,110,116,97,116,105, - 111,110,32,105,115,32,100,101,115,105,114,101,100,46,10,10, - 32,32,32,32,114,242,0,0,0,250,1,42,218,7,95,95, - 97,108,108,95,95,122,5,123,125,46,123,125,78,41,13,114, - 60,0,0,0,114,241,0,0,0,218,6,114,101,109,111,118, - 101,114,197,0,0,0,114,111,1,0,0,114,47,0,0,0, - 114,57,0,0,0,114,114,0,0,0,114,153,0,0,0,114, - 78,1,0,0,114,9,0,0,0,218,15,95,69,82,82,95, - 77,83,71,95,80,82,69,70,73,88,114,67,0,0,0,41, - 6,114,179,0,0,0,218,8,102,114,111,109,108,105,115,116, - 114,106,1,0,0,114,16,0,0,0,90,9,102,114,111,109, - 95,110,97,109,101,114,36,1,0,0,114,4,0,0,0,114, - 4,0,0,0,114,5,0,0,0,218,16,95,104,97,110,100, - 108,101,95,102,114,111,109,108,105,115,116,135,8,0,0,115, - 34,0,0,0,0,10,15,1,12,1,12,1,13,1,15,1, - 22,1,13,1,15,1,21,1,3,1,17,1,18,4,21,1, - 15,1,9,1,32,1,114,115,1,0,0,99,1,0,0,0, - 0,0,0,0,2,0,0,0,2,0,0,0,67,0,0,0, - 115,78,0,0,0,124,0,0,106,0,0,100,1,0,131,1, - 0,125,1,0,124,1,0,100,2,0,107,8,0,114,74,0, - 124,0,0,100,3,0,25,125,1,0,100,4,0,124,0,0, - 107,7,0,114,74,0,124,1,0,106,1,0,100,5,0,131, - 1,0,100,6,0,25,125,1,0,113,74,0,110,0,0,124, - 1,0,83,41,7,122,167,67,97,108,99,117,108,97,116,101, - 32,119,104,97,116,32,95,95,112,97,99,107,97,103,101,95, - 95,32,115,104,111,117,108,100,32,98,101,46,10,10,32,32, - 32,32,95,95,112,97,99,107,97,103,101,95,95,32,105,115, - 32,110,111,116,32,103,117,97,114,97,110,116,101,101,100,32, - 116,111,32,98,101,32,100,101,102,105,110,101,100,32,111,114, - 32,99,111,117,108,100,32,98,101,32,115,101,116,32,116,111, - 32,78,111,110,101,10,32,32,32,32,116,111,32,114,101,112, - 114,101,115,101,110,116,32,116,104,97,116,32,105,116,115,32, - 112,114,111,112,101,114,32,118,97,108,117,101,32,105,115,32, - 117,110,107,110,111,119,110,46,10,10,32,32,32,32,114,249, - 0,0,0,78,114,57,0,0,0,114,242,0,0,0,114,116, - 0,0,0,114,84,0,0,0,41,2,114,93,0,0,0,114, - 32,0,0,0,41,2,218,7,103,108,111,98,97,108,115,114, - 98,1,0,0,114,4,0,0,0,114,4,0,0,0,114,5, - 0,0,0,218,17,95,99,97,108,99,95,95,95,112,97,99, - 107,97,103,101,95,95,167,8,0,0,115,12,0,0,0,0, - 7,15,1,12,1,10,1,12,1,25,1,114,117,1,0,0, - 99,0,0,0,0,0,0,0,0,3,0,0,0,3,0,0, - 0,67,0,0,0,115,55,0,0,0,116,0,0,116,1,0, - 106,2,0,131,0,0,102,2,0,125,0,0,116,3,0,116, - 4,0,102,2,0,125,1,0,116,5,0,116,6,0,102,2, - 0,125,2,0,124,0,0,124,1,0,124,2,0,103,3,0, - 83,41,1,122,95,82,101,116,117,114,110,115,32,97,32,108, - 105,115,116,32,111,102,32,102,105,108,101,45,98,97,115,101, - 100,32,109,111,100,117,108,101,32,108,111,97,100,101,114,115, - 46,10,10,32,32,32,32,69,97,99,104,32,105,116,101,109, - 32,105,115,32,97,32,116,117,112,108,101,32,40,108,111,97, - 100,101,114,44,32,115,117,102,102,105,120,101,115,41,46,10, - 32,32,32,32,41,7,114,52,1,0,0,114,106,0,0,0, - 218,18,101,120,116,101,110,115,105,111,110,95,115,117,102,102, - 105,120,101,115,114,47,1,0,0,114,134,0,0,0,114,51, - 1,0,0,114,230,0,0,0,41,3,90,10,101,120,116,101, - 110,115,105,111,110,115,90,6,115,111,117,114,99,101,90,8, - 98,121,116,101,99,111,100,101,114,4,0,0,0,114,4,0, - 0,0,114,5,0,0,0,114,236,0,0,0,182,8,0,0, - 115,8,0,0,0,0,5,18,1,12,1,12,1,114,236,0, - 0,0,99,5,0,0,0,0,0,0,0,9,0,0,0,5, - 0,0,0,67,0,0,0,115,227,0,0,0,124,4,0,100, - 1,0,107,2,0,114,27,0,116,0,0,124,0,0,131,1, - 0,125,5,0,110,54,0,124,1,0,100,2,0,107,9,0, - 114,45,0,124,1,0,110,3,0,105,0,0,125,6,0,116, - 1,0,124,6,0,131,1,0,125,7,0,116,0,0,124,0, - 0,124,7,0,124,4,0,131,3,0,125,5,0,124,3,0, - 115,207,0,124,4,0,100,1,0,107,2,0,114,122,0,116, - 0,0,124,0,0,106,2,0,100,3,0,131,1,0,100,1, - 0,25,131,1,0,83,124,0,0,115,132,0,124,5,0,83, - 116,3,0,124,0,0,131,1,0,116,3,0,124,0,0,106, - 2,0,100,3,0,131,1,0,100,1,0,25,131,1,0,24, - 125,8,0,116,4,0,106,5,0,124,5,0,106,6,0,100, - 2,0,116,3,0,124,5,0,106,6,0,131,1,0,124,8, - 0,24,133,2,0,25,25,83,110,16,0,116,7,0,124,5, - 0,124,3,0,116,0,0,131,3,0,83,100,2,0,83,41, - 4,97,214,1,0,0,73,109,112,111,114,116,32,97,32,109, - 111,100,117,108,101,46,10,10,32,32,32,32,84,104,101,32, - 39,103,108,111,98,97,108,115,39,32,97,114,103,117,109,101, - 110,116,32,105,115,32,117,115,101,100,32,116,111,32,105,110, - 102,101,114,32,119,104,101,114,101,32,116,104,101,32,105,109, - 112,111,114,116,32,105,115,32,111,99,99,117,114,105,110,103, - 32,102,114,111,109,10,32,32,32,32,116,111,32,104,97,110, - 100,108,101,32,114,101,108,97,116,105,118,101,32,105,109,112, - 111,114,116,115,46,32,84,104,101,32,39,108,111,99,97,108, - 115,39,32,97,114,103,117,109,101,110,116,32,105,115,32,105, - 103,110,111,114,101,100,46,32,84,104,101,10,32,32,32,32, - 39,102,114,111,109,108,105,115,116,39,32,97,114,103,117,109, - 101,110,116,32,115,112,101,99,105,102,105,101,115,32,119,104, - 97,116,32,115,104,111,117,108,100,32,101,120,105,115,116,32, - 97,115,32,97,116,116,114,105,98,117,116,101,115,32,111,110, - 32,116,104,101,32,109,111,100,117,108,101,10,32,32,32,32, - 98,101,105,110,103,32,105,109,112,111,114,116,101,100,32,40, - 101,46,103,46,32,96,96,102,114,111,109,32,109,111,100,117, - 108,101,32,105,109,112,111,114,116,32,60,102,114,111,109,108, - 105,115,116,62,96,96,41,46,32,32,84,104,101,32,39,108, - 101,118,101,108,39,10,32,32,32,32,97,114,103,117,109,101, - 110,116,32,114,101,112,114,101,115,101,110,116,115,32,116,104, - 101,32,112,97,99,107,97,103,101,32,108,111,99,97,116,105, - 111,110,32,116,111,32,105,109,112,111,114,116,32,102,114,111, - 109,32,105,110,32,97,32,114,101,108,97,116,105,118,101,10, - 32,32,32,32,105,109,112,111,114,116,32,40,101,46,103,46, - 32,96,96,102,114,111,109,32,46,46,112,107,103,32,105,109, - 112,111,114,116,32,109,111,100,96,96,32,119,111,117,108,100, - 32,104,97,118,101,32,97,32,39,108,101,118,101,108,39,32, - 111,102,32,50,41,46,10,10,32,32,32,32,114,84,0,0, - 0,78,114,116,0,0,0,41,8,114,109,1,0,0,114,117, - 1,0,0,114,121,0,0,0,114,31,0,0,0,114,7,0, - 0,0,114,73,0,0,0,114,57,0,0,0,114,115,1,0, - 0,41,9,114,67,0,0,0,114,116,1,0,0,218,6,108, - 111,99,97,108,115,114,114,1,0,0,114,99,1,0,0,114, - 179,0,0,0,90,8,103,108,111,98,97,108,115,95,114,98, - 1,0,0,90,7,99,117,116,95,111,102,102,114,4,0,0, - 0,114,4,0,0,0,114,5,0,0,0,218,10,95,95,105, - 109,112,111,114,116,95,95,193,8,0,0,115,26,0,0,0, - 0,11,12,1,15,2,24,1,12,1,18,1,6,3,12,1, - 23,1,6,1,4,4,35,3,40,2,114,120,1,0,0,99, - 1,0,0,0,0,0,0,0,3,0,0,0,3,0,0,0, - 67,0,0,0,115,68,0,0,0,116,0,0,106,1,0,124, - 0,0,131,1,0,125,1,0,124,1,0,100,0,0,107,8, - 0,114,46,0,116,2,0,100,1,0,124,0,0,23,131,1, - 0,130,1,0,110,0,0,116,3,0,124,1,0,131,1,0, - 125,2,0,124,2,0,106,4,0,131,0,0,83,41,2,78, - 122,25,110,111,32,98,117,105,108,116,45,105,110,32,109,111, - 100,117,108,101,32,110,97,109,101,100,32,41,5,114,8,1, - 0,0,114,10,1,0,0,114,153,0,0,0,114,174,0,0, - 0,114,6,1,0,0,41,3,114,67,0,0,0,114,177,0, - 0,0,114,178,0,0,0,114,4,0,0,0,114,4,0,0, - 0,114,5,0,0,0,218,18,95,98,117,105,108,116,105,110, - 95,102,114,111,109,95,110,97,109,101,228,8,0,0,115,10, - 0,0,0,0,1,15,1,12,1,19,1,12,1,114,121,1, - 0,0,99,2,0,0,0,0,0,0,0,19,0,0,0,12, - 0,0,0,67,0,0,0,115,232,2,0,0,124,1,0,97, - 0,0,124,0,0,97,1,0,116,1,0,106,2,0,106,3, - 0,114,33,0,116,4,0,97,5,0,110,6,0,116,6,0, - 97,5,0,116,7,0,116,1,0,131,1,0,125,2,0,120, - 138,0,116,1,0,106,8,0,106,9,0,131,0,0,68,93, - 121,0,92,2,0,125,3,0,125,4,0,116,10,0,124,4, - 0,124,2,0,131,2,0,114,67,0,124,3,0,116,1,0, - 106,11,0,107,6,0,114,118,0,116,12,0,125,5,0,110, - 27,0,116,0,0,106,13,0,124,3,0,131,1,0,114,67, - 0,116,14,0,125,5,0,110,3,0,113,67,0,116,15,0, - 124,4,0,124,5,0,131,2,0,125,6,0,116,16,0,124, - 6,0,131,1,0,125,7,0,124,7,0,106,17,0,124,4, - 0,131,1,0,1,113,67,0,113,67,0,87,116,1,0,106, - 8,0,116,18,0,25,125,8,0,120,73,0,100,26,0,68, - 93,65,0,125,9,0,124,9,0,116,1,0,106,8,0,107, - 7,0,114,248,0,116,19,0,124,9,0,131,1,0,125,10, - 0,110,13,0,116,1,0,106,8,0,124,9,0,25,125,10, - 0,116,20,0,124,8,0,124,9,0,124,10,0,131,3,0, - 1,113,212,0,87,100,5,0,100,6,0,103,1,0,102,2, - 0,100,7,0,100,8,0,100,6,0,103,2,0,102,2,0, - 102,2,0,125,11,0,120,146,0,124,11,0,68,93,126,0, - 92,2,0,125,12,0,125,13,0,116,21,0,100,9,0,100, - 10,0,132,0,0,124,13,0,68,131,1,0,131,1,0,115, - 108,1,116,22,0,130,1,0,124,13,0,100,11,0,25,125, - 14,0,124,12,0,116,1,0,106,8,0,107,6,0,114,150, - 1,116,1,0,106,8,0,124,12,0,25,125,15,0,80,113, - 65,1,121,17,0,116,19,0,124,12,0,131,1,0,125,15, - 0,80,87,113,65,1,4,116,23,0,107,10,0,114,190,1, - 1,1,1,119,65,1,89,113,65,1,88,113,65,1,87,116, - 23,0,100,12,0,131,1,0,130,1,0,116,20,0,124,8, - 0,100,13,0,124,15,0,131,3,0,1,116,20,0,124,8, - 0,100,14,0,124,14,0,131,3,0,1,116,20,0,124,8, - 0,100,15,0,100,16,0,106,24,0,124,13,0,131,1,0, - 131,3,0,1,121,16,0,116,19,0,100,17,0,131,1,0, - 125,16,0,87,110,24,0,4,116,23,0,107,10,0,114,50, - 2,1,1,1,100,18,0,125,16,0,89,110,1,0,88,116, - 20,0,124,8,0,100,17,0,124,16,0,131,3,0,1,116, - 19,0,100,19,0,131,1,0,125,17,0,116,20,0,124,8, - 0,100,19,0,124,17,0,131,3,0,1,124,12,0,100,7, - 0,107,2,0,114,138,2,116,19,0,100,20,0,131,1,0, - 125,18,0,116,20,0,124,8,0,100,21,0,124,18,0,131, - 3,0,1,110,0,0,116,20,0,124,8,0,100,22,0,116, - 25,0,131,0,0,131,3,0,1,116,26,0,106,27,0,116, - 0,0,106,28,0,131,0,0,131,1,0,1,124,12,0,100, - 7,0,107,2,0,114,228,2,116,29,0,106,30,0,100,23, - 0,131,1,0,1,100,24,0,116,26,0,107,6,0,114,228, - 2,100,25,0,116,31,0,95,32,0,113,228,2,110,0,0, + 1,0,100,2,0,25,125,3,0,124,3,0,114,175,0,124, + 3,0,116,1,0,106,2,0,107,7,0,114,59,0,116,3, + 0,124,1,0,124,3,0,131,2,0,1,124,0,0,116,1, + 0,106,2,0,107,6,0,114,85,0,116,1,0,106,2,0, + 124,0,0,25,83,116,1,0,106,2,0,124,3,0,25,125, + 4,0,121,13,0,124,4,0,106,4,0,125,2,0,87,110, + 61,0,4,116,5,0,107,10,0,114,174,0,1,1,1,116, + 6,0,100,3,0,23,106,7,0,124,0,0,124,3,0,131, + 2,0,125,5,0,116,8,0,124,5,0,100,4,0,124,0, + 0,131,1,1,100,0,0,130,2,0,89,110,1,0,88,116, + 9,0,124,0,0,124,2,0,131,2,0,125,6,0,124,6, + 0,100,0,0,107,8,0,114,232,0,116,8,0,116,6,0, + 106,7,0,124,0,0,131,1,0,100,4,0,124,0,0,131, + 1,1,130,1,0,110,12,0,116,10,0,124,6,0,131,1, + 0,125,7,0,124,3,0,114,36,1,116,1,0,106,2,0, + 124,3,0,25,125,4,0,116,11,0,124,4,0,124,0,0, + 106,0,0,100,1,0,131,1,0,100,5,0,25,124,7,0, + 131,3,0,1,124,7,0,83,41,6,78,114,116,0,0,0, + 114,84,0,0,0,122,23,59,32,123,33,114,125,32,105,115, + 32,110,111,116,32,97,32,112,97,99,107,97,103,101,114,67, + 0,0,0,114,115,0,0,0,41,12,114,32,0,0,0,114, + 7,0,0,0,114,73,0,0,0,114,114,0,0,0,114,246, + 0,0,0,114,208,0,0,0,218,8,95,69,82,82,95,77, + 83,71,114,47,0,0,0,114,154,0,0,0,114,107,1,0, + 0,114,5,1,0,0,114,61,0,0,0,41,8,114,67,0, + 0,0,218,7,105,109,112,111,114,116,95,114,35,0,0,0, + 114,233,0,0,0,90,13,112,97,114,101,110,116,95,109,111, + 100,117,108,101,114,172,0,0,0,114,177,0,0,0,114,178, + 0,0,0,114,4,0,0,0,114,4,0,0,0,114,5,0, + 0,0,218,23,95,102,105,110,100,95,97,110,100,95,108,111, + 97,100,95,117,110,108,111,99,107,101,100,127,8,0,0,115, + 42,0,0,0,0,1,6,1,19,1,6,1,15,1,13,2, + 15,1,11,1,13,1,3,1,13,1,13,1,22,1,26,1, + 15,1,12,1,30,2,12,1,6,2,13,1,29,1,114,113, + 1,0,0,99,2,0,0,0,0,0,0,0,2,0,0,0, + 10,0,0,0,67,0,0,0,115,36,0,0,0,116,0,0, + 124,0,0,131,1,0,143,18,0,1,116,1,0,124,0,0, + 124,1,0,131,2,0,83,87,100,1,0,81,88,100,1,0, + 83,41,2,122,54,70,105,110,100,32,97,110,100,32,108,111, + 97,100,32,116,104,101,32,109,111,100,117,108,101,44,32,97, + 110,100,32,114,101,108,101,97,115,101,32,116,104,101,32,105, + 109,112,111,114,116,32,108,111,99,107,46,78,41,2,114,103, + 0,0,0,114,113,1,0,0,41,2,114,67,0,0,0,114, + 112,1,0,0,114,4,0,0,0,114,4,0,0,0,114,5, + 0,0,0,218,14,95,102,105,110,100,95,97,110,100,95,108, + 111,97,100,154,8,0,0,115,4,0,0,0,0,2,13,1, + 114,114,1,0,0,99,3,0,0,0,0,0,0,0,5,0, + 0,0,4,0,0,0,67,0,0,0,115,166,0,0,0,116, + 0,0,124,0,0,124,1,0,124,2,0,131,3,0,1,124, + 2,0,100,1,0,107,4,0,114,46,0,116,1,0,124,0, + 0,124,1,0,124,2,0,131,3,0,125,0,0,116,2,0, + 106,3,0,131,0,0,1,124,0,0,116,4,0,106,5,0, + 107,7,0,114,84,0,116,6,0,124,0,0,116,7,0,131, + 2,0,83,116,4,0,106,5,0,124,0,0,25,125,3,0, + 124,3,0,100,2,0,107,8,0,114,152,0,116,2,0,106, + 8,0,131,0,0,1,100,3,0,106,9,0,124,0,0,131, + 1,0,125,4,0,116,10,0,124,4,0,100,4,0,124,0, + 0,131,1,1,130,1,0,116,11,0,124,0,0,131,1,0, + 1,124,3,0,83,41,5,97,50,1,0,0,73,109,112,111, + 114,116,32,97,110,100,32,114,101,116,117,114,110,32,116,104, + 101,32,109,111,100,117,108,101,32,98,97,115,101,100,32,111, + 110,32,105,116,115,32,110,97,109,101,44,32,116,104,101,32, + 112,97,99,107,97,103,101,32,116,104,101,32,99,97,108,108, + 32,105,115,10,32,32,32,32,98,101,105,110,103,32,109,97, + 100,101,32,102,114,111,109,44,32,97,110,100,32,116,104,101, + 32,108,101,118,101,108,32,97,100,106,117,115,116,109,101,110, + 116,46,10,10,32,32,32,32,84,104,105,115,32,102,117,110, + 99,116,105,111,110,32,114,101,112,114,101,115,101,110,116,115, + 32,116,104,101,32,103,114,101,97,116,101,115,116,32,99,111, + 109,109,111,110,32,100,101,110,111,109,105,110,97,116,111,114, + 32,111,102,32,102,117,110,99,116,105,111,110,97,108,105,116, + 121,10,32,32,32,32,98,101,116,119,101,101,110,32,105,109, + 112,111,114,116,95,109,111,100,117,108,101,32,97,110,100,32, + 95,95,105,109,112,111,114,116,95,95,46,32,84,104,105,115, + 32,105,110,99,108,117,100,101,115,32,115,101,116,116,105,110, + 103,32,95,95,112,97,99,107,97,103,101,95,95,32,105,102, + 10,32,32,32,32,116,104,101,32,108,111,97,100,101,114,32, + 100,105,100,32,110,111,116,46,10,10,32,32,32,32,114,84, + 0,0,0,78,122,40,105,109,112,111,114,116,32,111,102,32, + 123,125,32,104,97,108,116,101,100,59,32,78,111,110,101,32, + 105,110,32,115,121,115,46,109,111,100,117,108,101,115,114,67, + 0,0,0,41,12,114,110,1,0,0,114,104,1,0,0,114, + 106,0,0,0,114,2,1,0,0,114,7,0,0,0,114,73, + 0,0,0,114,114,1,0,0,218,11,95,103,99,100,95,105, + 109,112,111,114,116,114,107,0,0,0,114,47,0,0,0,114, + 154,0,0,0,114,112,0,0,0,41,5,114,67,0,0,0, + 114,102,1,0,0,114,103,1,0,0,114,178,0,0,0,114, + 152,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5, + 0,0,0,114,115,1,0,0,160,8,0,0,115,28,0,0, + 0,0,9,16,1,12,1,18,1,10,1,15,1,13,1,13, + 1,12,1,10,1,6,1,9,1,18,1,10,1,114,115,1, + 0,0,99,3,0,0,0,0,0,0,0,6,0,0,0,17, + 0,0,0,67,0,0,0,115,239,0,0,0,116,0,0,124, + 0,0,100,1,0,131,2,0,114,235,0,100,2,0,124,1, + 0,107,6,0,114,83,0,116,1,0,124,1,0,131,1,0, + 125,1,0,124,1,0,106,2,0,100,2,0,131,1,0,1, + 116,0,0,124,0,0,100,3,0,131,2,0,114,83,0,124, + 1,0,106,3,0,124,0,0,106,4,0,131,1,0,1,120, + 149,0,124,1,0,68,93,141,0,125,3,0,116,0,0,124, + 0,0,124,3,0,131,2,0,115,90,0,100,4,0,106,5, + 0,124,0,0,106,6,0,124,3,0,131,2,0,125,4,0, + 121,17,0,116,7,0,124,2,0,124,4,0,131,2,0,1, + 87,113,90,0,4,116,8,0,107,10,0,114,230,0,1,125, + 5,0,1,122,47,0,116,9,0,124,5,0,131,1,0,106, + 10,0,116,11,0,131,1,0,114,209,0,124,5,0,106,12, + 0,124,4,0,107,2,0,114,209,0,119,90,0,130,0,0, + 87,89,100,5,0,100,5,0,125,5,0,126,5,0,88,113, + 90,0,88,113,90,0,87,124,0,0,83,41,6,122,238,70, + 105,103,117,114,101,32,111,117,116,32,119,104,97,116,32,95, + 95,105,109,112,111,114,116,95,95,32,115,104,111,117,108,100, + 32,114,101,116,117,114,110,46,10,10,32,32,32,32,84,104, + 101,32,105,109,112,111,114,116,95,32,112,97,114,97,109,101, + 116,101,114,32,105,115,32,97,32,99,97,108,108,97,98,108, + 101,32,119,104,105,99,104,32,116,97,107,101,115,32,116,104, + 101,32,110,97,109,101,32,111,102,32,109,111,100,117,108,101, + 32,116,111,10,32,32,32,32,105,109,112,111,114,116,46,32, + 73,116,32,105,115,32,114,101,113,117,105,114,101,100,32,116, + 111,32,100,101,99,111,117,112,108,101,32,116,104,101,32,102, + 117,110,99,116,105,111,110,32,102,114,111,109,32,97,115,115, + 117,109,105,110,103,32,105,109,112,111,114,116,108,105,98,39, + 115,10,32,32,32,32,105,109,112,111,114,116,32,105,109,112, + 108,101,109,101,110,116,97,116,105,111,110,32,105,115,32,100, + 101,115,105,114,101,100,46,10,10,32,32,32,32,114,246,0, + 0,0,250,1,42,218,7,95,95,97,108,108,95,95,122,5, + 123,125,46,123,125,78,41,13,114,60,0,0,0,114,245,0, + 0,0,218,6,114,101,109,111,118,101,114,196,0,0,0,114, + 117,1,0,0,114,47,0,0,0,114,57,0,0,0,114,114, + 0,0,0,114,154,0,0,0,114,83,1,0,0,114,9,0, + 0,0,218,15,95,69,82,82,95,77,83,71,95,80,82,69, + 70,73,88,114,67,0,0,0,41,6,114,178,0,0,0,218, + 8,102,114,111,109,108,105,115,116,114,112,1,0,0,114,16, + 0,0,0,90,9,102,114,111,109,95,110,97,109,101,114,40, + 1,0,0,114,4,0,0,0,114,4,0,0,0,114,5,0, + 0,0,218,16,95,104,97,110,100,108,101,95,102,114,111,109, + 108,105,115,116,184,8,0,0,115,34,0,0,0,0,10,15, + 1,12,1,12,1,13,1,15,1,16,1,13,1,15,1,21, + 1,3,1,17,1,18,4,21,1,15,1,3,1,26,1,114, + 121,1,0,0,99,1,0,0,0,0,0,0,0,2,0,0, + 0,2,0,0,0,67,0,0,0,115,72,0,0,0,124,0, + 0,106,0,0,100,1,0,131,1,0,125,1,0,124,1,0, + 100,2,0,107,8,0,114,68,0,124,0,0,100,3,0,25, + 125,1,0,100,4,0,124,0,0,107,7,0,114,68,0,124, + 1,0,106,1,0,100,5,0,131,1,0,100,6,0,25,125, + 1,0,124,1,0,83,41,7,122,167,67,97,108,99,117,108, + 97,116,101,32,119,104,97,116,32,95,95,112,97,99,107,97, + 103,101,95,95,32,115,104,111,117,108,100,32,98,101,46,10, + 10,32,32,32,32,95,95,112,97,99,107,97,103,101,95,95, + 32,105,115,32,110,111,116,32,103,117,97,114,97,110,116,101, + 101,100,32,116,111,32,98,101,32,100,101,102,105,110,101,100, + 32,111,114,32,99,111,117,108,100,32,98,101,32,115,101,116, + 32,116,111,32,78,111,110,101,10,32,32,32,32,116,111,32, + 114,101,112,114,101,115,101,110,116,32,116,104,97,116,32,105, + 116,115,32,112,114,111,112,101,114,32,118,97,108,117,101,32, + 105,115,32,117,110,107,110,111,119,110,46,10,10,32,32,32, + 32,114,249,0,0,0,78,114,57,0,0,0,114,246,0,0, + 0,114,116,0,0,0,114,84,0,0,0,41,2,114,93,0, + 0,0,114,32,0,0,0,41,2,218,7,103,108,111,98,97, + 108,115,114,102,1,0,0,114,4,0,0,0,114,4,0,0, + 0,114,5,0,0,0,218,17,95,99,97,108,99,95,95,95, + 112,97,99,107,97,103,101,95,95,216,8,0,0,115,12,0, + 0,0,0,7,15,1,12,1,10,1,12,1,19,1,114,123, + 1,0,0,99,0,0,0,0,0,0,0,0,3,0,0,0, + 3,0,0,0,67,0,0,0,115,55,0,0,0,116,0,0, + 116,1,0,106,2,0,131,0,0,102,2,0,125,0,0,116, + 3,0,116,4,0,102,2,0,125,1,0,116,5,0,116,6, + 0,102,2,0,125,2,0,124,0,0,124,1,0,124,2,0, + 103,3,0,83,41,1,122,95,82,101,116,117,114,110,115,32, + 97,32,108,105,115,116,32,111,102,32,102,105,108,101,45,98, + 97,115,101,100,32,109,111,100,117,108,101,32,108,111,97,100, + 101,114,115,46,10,10,32,32,32,32,69,97,99,104,32,105, + 116,101,109,32,105,115,32,97,32,116,117,112,108,101,32,40, + 108,111,97,100,101,114,44,32,115,117,102,102,105,120,101,115, + 41,46,10,32,32,32,32,41,7,114,56,1,0,0,114,106, + 0,0,0,218,18,101,120,116,101,110,115,105,111,110,95,115, + 117,102,102,105,120,101,115,114,7,1,0,0,114,135,0,0, + 0,114,6,1,0,0,114,232,0,0,0,41,3,90,10,101, + 120,116,101,110,115,105,111,110,115,90,6,115,111,117,114,99, + 101,90,8,98,121,116,101,99,111,100,101,114,4,0,0,0, + 114,4,0,0,0,114,5,0,0,0,114,240,0,0,0,231, + 8,0,0,115,8,0,0,0,0,5,18,1,12,1,12,1, + 114,240,0,0,0,99,5,0,0,0,0,0,0,0,9,0, + 0,0,5,0,0,0,67,0,0,0,115,227,0,0,0,124, + 4,0,100,1,0,107,2,0,114,27,0,116,0,0,124,0, + 0,131,1,0,125,5,0,110,54,0,124,1,0,100,2,0, + 107,9,0,114,45,0,124,1,0,110,3,0,105,0,0,125, + 6,0,116,1,0,124,6,0,131,1,0,125,7,0,116,0, + 0,124,0,0,124,7,0,124,4,0,131,3,0,125,5,0, + 124,3,0,115,207,0,124,4,0,100,1,0,107,2,0,114, + 122,0,116,0,0,124,0,0,106,2,0,100,3,0,131,1, + 0,100,1,0,25,131,1,0,83,124,0,0,115,132,0,124, + 5,0,83,116,3,0,124,0,0,131,1,0,116,3,0,124, + 0,0,106,2,0,100,3,0,131,1,0,100,1,0,25,131, + 1,0,24,125,8,0,116,4,0,106,5,0,124,5,0,106, + 6,0,100,2,0,116,3,0,124,5,0,106,6,0,131,1, + 0,124,8,0,24,133,2,0,25,25,83,110,16,0,116,7, + 0,124,5,0,124,3,0,116,0,0,131,3,0,83,100,2, + 0,83,41,4,97,214,1,0,0,73,109,112,111,114,116,32, + 97,32,109,111,100,117,108,101,46,10,10,32,32,32,32,84, + 104,101,32,39,103,108,111,98,97,108,115,39,32,97,114,103, + 117,109,101,110,116,32,105,115,32,117,115,101,100,32,116,111, + 32,105,110,102,101,114,32,119,104,101,114,101,32,116,104,101, + 32,105,109,112,111,114,116,32,105,115,32,111,99,99,117,114, + 105,110,103,32,102,114,111,109,10,32,32,32,32,116,111,32, + 104,97,110,100,108,101,32,114,101,108,97,116,105,118,101,32, + 105,109,112,111,114,116,115,46,32,84,104,101,32,39,108,111, + 99,97,108,115,39,32,97,114,103,117,109,101,110,116,32,105, + 115,32,105,103,110,111,114,101,100,46,32,84,104,101,10,32, + 32,32,32,39,102,114,111,109,108,105,115,116,39,32,97,114, + 103,117,109,101,110,116,32,115,112,101,99,105,102,105,101,115, + 32,119,104,97,116,32,115,104,111,117,108,100,32,101,120,105, + 115,116,32,97,115,32,97,116,116,114,105,98,117,116,101,115, + 32,111,110,32,116,104,101,32,109,111,100,117,108,101,10,32, + 32,32,32,98,101,105,110,103,32,105,109,112,111,114,116,101, + 100,32,40,101,46,103,46,32,96,96,102,114,111,109,32,109, + 111,100,117,108,101,32,105,109,112,111,114,116,32,60,102,114, + 111,109,108,105,115,116,62,96,96,41,46,32,32,84,104,101, + 32,39,108,101,118,101,108,39,10,32,32,32,32,97,114,103, + 117,109,101,110,116,32,114,101,112,114,101,115,101,110,116,115, + 32,116,104,101,32,112,97,99,107,97,103,101,32,108,111,99, + 97,116,105,111,110,32,116,111,32,105,109,112,111,114,116,32, + 102,114,111,109,32,105,110,32,97,32,114,101,108,97,116,105, + 118,101,10,32,32,32,32,105,109,112,111,114,116,32,40,101, + 46,103,46,32,96,96,102,114,111,109,32,46,46,112,107,103, + 32,105,109,112,111,114,116,32,109,111,100,96,96,32,119,111, + 117,108,100,32,104,97,118,101,32,97,32,39,108,101,118,101, + 108,39,32,111,102,32,50,41,46,10,10,32,32,32,32,114, + 84,0,0,0,78,114,116,0,0,0,41,8,114,115,1,0, + 0,114,123,1,0,0,114,134,0,0,0,114,31,0,0,0, + 114,7,0,0,0,114,73,0,0,0,114,57,0,0,0,114, + 121,1,0,0,41,9,114,67,0,0,0,114,122,1,0,0, + 218,6,108,111,99,97,108,115,114,120,1,0,0,114,103,1, + 0,0,114,178,0,0,0,90,8,103,108,111,98,97,108,115, + 95,114,102,1,0,0,90,7,99,117,116,95,111,102,102,114, + 4,0,0,0,114,4,0,0,0,114,5,0,0,0,218,10, + 95,95,105,109,112,111,114,116,95,95,242,8,0,0,115,26, + 0,0,0,0,11,12,1,15,2,24,1,12,1,18,1,6, + 3,12,1,23,1,6,1,4,4,35,3,40,2,114,126,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,53,0,0,0,116,0,0,106, + 1,0,124,0,0,131,1,0,125,1,0,124,1,0,100,0, + 0,107,8,0,114,43,0,116,2,0,100,1,0,124,0,0, + 23,131,1,0,130,1,0,116,3,0,124,1,0,131,1,0, + 83,41,2,78,122,25,110,111,32,98,117,105,108,116,45,105, + 110,32,109,111,100,117,108,101,32,110,97,109,101,100,32,41, + 4,114,9,1,0,0,114,12,1,0,0,114,154,0,0,0, + 114,5,1,0,0,41,2,114,67,0,0,0,114,177,0,0, + 0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, + 218,18,95,98,117,105,108,116,105,110,95,102,114,111,109,95, + 110,97,109,101,21,9,0,0,115,8,0,0,0,0,1,15, + 1,12,1,16,1,114,127,1,0,0,99,2,0,0,0,0, + 0,0,0,18,0,0,0,12,0,0,0,67,0,0,0,115, + 208,2,0,0,124,1,0,97,0,0,124,0,0,97,1,0, + 116,1,0,106,2,0,106,3,0,114,33,0,116,4,0,97, + 5,0,110,6,0,116,6,0,97,5,0,116,7,0,116,1, + 0,131,1,0,125,2,0,120,123,0,116,1,0,106,8,0, + 106,9,0,131,0,0,68,93,106,0,92,2,0,125,3,0, + 125,4,0,116,10,0,124,4,0,124,2,0,131,2,0,114, + 67,0,124,3,0,116,1,0,106,11,0,107,6,0,114,118, + 0,116,12,0,125,5,0,110,27,0,116,0,0,106,13,0, + 124,3,0,131,1,0,114,67,0,116,14,0,125,5,0,110, + 3,0,113,67,0,116,15,0,124,4,0,124,5,0,131,2, + 0,125,6,0,116,16,0,124,6,0,124,4,0,131,2,0, + 1,113,67,0,87,116,1,0,106,8,0,116,17,0,25,125, + 7,0,120,73,0,100,26,0,68,93,65,0,125,8,0,124, + 8,0,116,1,0,106,8,0,107,7,0,114,233,0,116,18, + 0,124,8,0,131,1,0,125,9,0,110,13,0,116,1,0, + 106,8,0,124,8,0,25,125,9,0,116,19,0,124,7,0, + 124,8,0,124,9,0,131,3,0,1,113,197,0,87,100,5, + 0,100,6,0,103,1,0,102,2,0,100,7,0,100,8,0, + 100,6,0,103,2,0,102,2,0,102,2,0,125,10,0,120, + 146,0,124,10,0,68,93,126,0,92,2,0,125,11,0,125, + 12,0,116,20,0,100,9,0,100,10,0,132,0,0,124,12, + 0,68,131,1,0,131,1,0,115,93,1,116,21,0,130,1, + 0,124,12,0,100,11,0,25,125,13,0,124,11,0,116,1, + 0,106,8,0,107,6,0,114,135,1,116,1,0,106,8,0, + 124,11,0,25,125,14,0,80,113,50,1,121,17,0,116,18, + 0,124,11,0,131,1,0,125,14,0,80,87,113,50,1,4, + 116,22,0,107,10,0,114,175,1,1,1,1,119,50,1,89, + 113,50,1,88,113,50,1,87,116,22,0,100,12,0,131,1, + 0,130,1,0,116,19,0,124,7,0,100,13,0,124,14,0, + 131,3,0,1,116,19,0,124,7,0,100,14,0,124,13,0, + 131,3,0,1,116,19,0,124,7,0,100,15,0,100,16,0, + 106,23,0,124,12,0,131,1,0,131,3,0,1,121,16,0, + 116,18,0,100,17,0,131,1,0,125,15,0,87,110,24,0, + 4,116,22,0,107,10,0,114,35,2,1,1,1,100,18,0, + 125,15,0,89,110,1,0,88,116,19,0,124,7,0,100,17, + 0,124,15,0,131,3,0,1,116,18,0,100,19,0,131,1, + 0,125,16,0,116,19,0,124,7,0,100,19,0,124,16,0, + 131,3,0,1,124,11,0,100,7,0,107,2,0,114,120,2, + 116,18,0,100,20,0,131,1,0,125,17,0,116,19,0,124, + 7,0,100,21,0,124,17,0,131,3,0,1,116,19,0,124, + 7,0,100,22,0,116,24,0,131,0,0,131,3,0,1,116, + 25,0,106,26,0,116,0,0,106,27,0,131,0,0,131,1, + 0,1,124,11,0,100,7,0,107,2,0,114,204,2,116,28, + 0,106,29,0,100,23,0,131,1,0,1,100,24,0,116,25, + 0,107,6,0,114,204,2,100,25,0,116,30,0,95,31,0, 100,18,0,83,41,27,122,250,83,101,116,117,112,32,105,109, 112,111,114,116,108,105,98,32,98,121,32,105,109,112,111,114, 116,105,110,103,32,110,101,101,100,101,100,32,98,117,105,108, @@ -4138,124 +4168,127 @@ const unsigned char _Py_M__importlib[] = { 115,101,32,116,119,111,32,109,111,100,117,108,101,115,32,109, 117,115,116,32,98,101,32,101,120,112,108,105,99,105,116,108, 121,32,112,97,115,115,101,100,32,105,110,46,10,10,32,32, - 32,32,114,49,0,0,0,114,166,0,0,0,218,8,98,117, - 105,108,116,105,110,115,114,191,0,0,0,90,5,112,111,115, + 32,32,114,49,0,0,0,114,167,0,0,0,218,8,98,117, + 105,108,116,105,110,115,114,190,0,0,0,90,5,112,111,115, 105,120,250,1,47,218,2,110,116,250,1,92,99,1,0,0, 0,0,0,0,0,2,0,0,0,3,0,0,0,115,0,0, 0,115,33,0,0,0,124,0,0,93,23,0,125,1,0,116, 0,0,124,1,0,131,1,0,100,0,0,107,2,0,86,1, 113,3,0,100,1,0,83,41,2,114,29,0,0,0,78,41, - 1,114,31,0,0,0,41,2,114,22,0,0,0,114,130,0, + 1,114,31,0,0,0,41,2,114,22,0,0,0,114,129,0, 0,0,114,4,0,0,0,114,4,0,0,0,114,5,0,0, - 0,114,77,0,0,0,24,9,0,0,115,2,0,0,0,6, + 0,114,77,0,0,0,71,9,0,0,115,2,0,0,0,6, 0,122,25,95,115,101,116,117,112,46,60,108,111,99,97,108, 115,62,46,60,103,101,110,101,120,112,114,62,114,84,0,0, 0,122,30,105,109,112,111,114,116,108,105,98,32,114,101,113, 117,105,114,101,115,32,112,111,115,105,120,32,111,114,32,110, 116,114,3,0,0,0,114,25,0,0,0,114,21,0,0,0, 114,30,0,0,0,114,85,0,0,0,78,114,111,0,0,0, - 90,6,119,105,110,114,101,103,114,19,1,0,0,114,6,0, + 90,6,119,105,110,114,101,103,114,23,1,0,0,114,6,0, 0,0,122,4,46,112,121,119,122,6,95,100,46,112,121,100, 84,41,4,122,3,95,105,111,122,9,95,119,97,114,110,105, 110,103,115,122,8,98,117,105,108,116,105,110,115,122,7,109, - 97,114,115,104,97,108,41,33,114,106,0,0,0,114,7,0, + 97,114,115,104,97,108,41,32,114,106,0,0,0,114,7,0, 0,0,114,117,0,0,0,114,118,0,0,0,114,120,0,0, - 0,114,230,0,0,0,114,119,0,0,0,114,66,0,0,0, - 114,73,0,0,0,218,5,105,116,101,109,115,114,192,0,0, - 0,114,157,0,0,0,114,8,1,0,0,114,162,0,0,0, - 114,15,1,0,0,114,243,0,0,0,114,174,0,0,0,114, - 253,0,0,0,114,57,0,0,0,114,121,1,0,0,114,61, - 0,0,0,218,3,97,108,108,114,100,0,0,0,114,153,0, - 0,0,114,26,0,0,0,114,11,0,0,0,114,55,1,0, - 0,114,197,0,0,0,114,118,1,0,0,114,134,0,0,0, - 114,223,0,0,0,114,18,1,0,0,114,22,1,0,0,41, - 19,218,10,115,121,115,95,109,111,100,117,108,101,218,11,95, - 105,109,112,95,109,111,100,117,108,101,90,11,109,111,100,117, - 108,101,95,116,121,112,101,114,67,0,0,0,114,179,0,0, - 0,114,169,0,0,0,114,177,0,0,0,114,178,0,0,0, - 90,11,115,101,108,102,95,109,111,100,117,108,101,90,12,98, - 117,105,108,116,105,110,95,110,97,109,101,90,14,98,117,105, - 108,116,105,110,95,109,111,100,117,108,101,90,10,111,115,95, - 100,101,116,97,105,108,115,90,10,98,117,105,108,116,105,110, - 95,111,115,114,21,0,0,0,114,25,0,0,0,90,9,111, - 115,95,109,111,100,117,108,101,90,13,116,104,114,101,97,100, - 95,109,111,100,117,108,101,90,14,119,101,97,107,114,101,102, - 95,109,111,100,117,108,101,90,13,119,105,110,114,101,103,95, - 109,111,100,117,108,101,114,4,0,0,0,114,4,0,0,0, - 114,5,0,0,0,218,6,95,115,101,116,117,112,236,8,0, - 0,115,108,0,0,0,0,9,6,1,6,2,12,1,9,2, - 6,3,12,1,28,1,15,1,15,1,9,1,15,1,9,2, - 3,1,15,1,12,1,20,3,13,1,13,1,15,1,15,2, - 13,1,20,3,33,1,19,2,31,1,10,1,15,1,13,1, - 4,2,3,1,12,1,5,1,13,1,12,2,12,1,16,1, - 16,1,25,3,3,1,16,1,13,2,11,1,16,3,12,1, - 16,3,12,1,12,1,19,3,19,1,19,1,12,1,13,1, - 12,1,114,130,1,0,0,99,2,0,0,0,0,0,0,0, - 3,0,0,0,3,0,0,0,67,0,0,0,115,136,0,0, - 0,116,0,0,124,0,0,124,1,0,131,2,0,1,116,1, - 0,131,0,0,125,2,0,116,2,0,106,3,0,106,4,0, - 116,5,0,106,6,0,124,2,0,140,0,0,103,1,0,131, - 1,0,1,116,2,0,106,7,0,106,8,0,116,9,0,131, - 1,0,1,116,2,0,106,7,0,106,8,0,116,10,0,131, - 1,0,1,116,11,0,106,12,0,100,1,0,107,2,0,114, - 116,0,116,2,0,106,7,0,106,8,0,116,13,0,131,1, - 0,1,110,0,0,116,2,0,106,7,0,106,8,0,116,14, - 0,131,1,0,1,100,2,0,83,41,3,122,50,73,110,115, - 116,97,108,108,32,105,109,112,111,114,116,108,105,98,32,97, - 115,32,116,104,101,32,105,109,112,108,101,109,101,110,116,97, - 116,105,111,110,32,111,102,32,105,109,112,111,114,116,46,114, - 124,1,0,0,78,41,15,114,130,1,0,0,114,236,0,0, - 0,114,7,0,0,0,114,74,1,0,0,114,197,0,0,0, - 114,82,1,0,0,114,96,1,0,0,114,101,1,0,0,114, - 223,0,0,0,114,8,1,0,0,114,15,1,0,0,114,3, - 0,0,0,114,57,0,0,0,114,18,1,0,0,114,69,1, - 0,0,41,3,114,128,1,0,0,114,129,1,0,0,90,17, - 115,117,112,112,111,114,116,101,100,95,108,111,97,100,101,114, - 115,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, - 218,8,95,105,110,115,116,97,108,108,67,9,0,0,115,16, - 0,0,0,0,2,13,1,9,1,28,1,16,1,16,1,15, - 1,19,1,114,131,1,0,0,41,3,122,3,119,105,110,114, - 1,0,0,0,114,2,0,0,0,41,90,114,59,0,0,0, - 114,10,0,0,0,114,11,0,0,0,114,17,0,0,0,114, - 19,0,0,0,114,28,0,0,0,114,38,0,0,0,114,39, - 0,0,0,114,43,0,0,0,114,44,0,0,0,114,46,0, - 0,0,114,55,0,0,0,114,65,0,0,0,114,68,0,0, - 0,114,66,0,0,0,218,8,95,95,99,111,100,101,95,95, - 114,193,0,0,0,114,69,0,0,0,114,109,0,0,0,114, - 92,0,0,0,114,99,0,0,0,114,82,0,0,0,114,83, - 0,0,0,114,102,0,0,0,114,103,0,0,0,114,105,0, - 0,0,114,112,0,0,0,114,114,0,0,0,114,15,0,0, - 0,114,185,0,0,0,114,14,0,0,0,114,18,0,0,0, - 90,17,95,82,65,87,95,77,65,71,73,67,95,78,85,77, - 66,69,82,114,125,0,0,0,114,134,0,0,0,114,119,0, - 0,0,114,120,0,0,0,114,132,0,0,0,114,135,0,0, - 0,114,142,0,0,0,114,144,0,0,0,114,152,0,0,0, - 114,156,0,0,0,114,161,0,0,0,114,164,0,0,0,114, - 172,0,0,0,114,180,0,0,0,114,190,0,0,0,114,195, - 0,0,0,114,198,0,0,0,114,203,0,0,0,114,211,0, - 0,0,114,212,0,0,0,114,216,0,0,0,114,173,0,0, - 0,218,6,111,98,106,101,99,116,114,237,0,0,0,114,235, - 0,0,0,114,243,0,0,0,114,174,0,0,0,114,8,1, - 0,0,114,15,1,0,0,114,18,1,0,0,114,28,1,0, - 0,114,29,1,0,0,114,44,1,0,0,114,47,1,0,0, - 114,51,1,0,0,114,55,1,0,0,114,52,1,0,0,114, - 56,1,0,0,114,250,0,0,0,114,69,1,0,0,114,82, - 1,0,0,114,97,1,0,0,114,100,1,0,0,114,244,0, - 0,0,114,104,1,0,0,114,113,1,0,0,114,105,1,0, - 0,114,107,1,0,0,114,108,1,0,0,114,109,1,0,0, - 114,115,1,0,0,114,117,1,0,0,114,236,0,0,0,114, - 120,1,0,0,114,121,1,0,0,114,130,1,0,0,114,131, - 1,0,0,114,4,0,0,0,114,4,0,0,0,114,4,0, - 0,0,114,5,0,0,0,218,8,60,109,111,100,117,108,101, - 62,8,0,0,0,115,166,0,0,0,6,17,6,3,12,12, - 12,5,12,5,12,6,12,12,12,10,12,9,12,5,12,7, - 15,22,12,8,12,4,15,4,19,20,6,2,6,3,22,4, - 19,68,19,21,19,19,12,19,12,20,12,113,22,1,18,2, - 6,2,9,2,9,1,9,2,15,27,12,23,12,19,12,12, - 18,8,12,18,12,11,12,11,12,13,12,13,21,55,21,12, - 18,10,12,14,12,34,19,27,19,102,24,22,9,3,12,1, - 15,63,18,45,19,251,19,63,19,59,19,60,19,25,22,110, - 19,31,25,43,25,16,6,3,19,48,19,57,19,27,19,124, - 19,147,19,13,12,9,15,41,12,17,6,1,10,2,12,27, - 12,6,18,24,12,32,12,15,12,11,24,35,12,8,12,87, + 0,114,232,0,0,0,114,119,0,0,0,114,66,0,0,0, + 114,73,0,0,0,218,5,105,116,101,109,115,114,191,0,0, + 0,114,158,0,0,0,114,9,1,0,0,114,163,0,0,0, + 114,18,1,0,0,114,247,0,0,0,114,253,0,0,0,114, + 57,0,0,0,114,127,1,0,0,114,61,0,0,0,218,3, + 97,108,108,114,100,0,0,0,114,154,0,0,0,114,26,0, + 0,0,114,11,0,0,0,114,59,1,0,0,114,196,0,0, + 0,114,124,1,0,0,114,135,0,0,0,114,223,0,0,0, + 114,22,1,0,0,114,26,1,0,0,41,18,218,10,115,121, + 115,95,109,111,100,117,108,101,218,11,95,105,109,112,95,109, + 111,100,117,108,101,90,11,109,111,100,117,108,101,95,116,121, + 112,101,114,67,0,0,0,114,178,0,0,0,114,170,0,0, + 0,114,177,0,0,0,90,11,115,101,108,102,95,109,111,100, + 117,108,101,90,12,98,117,105,108,116,105,110,95,110,97,109, + 101,90,14,98,117,105,108,116,105,110,95,109,111,100,117,108, + 101,90,10,111,115,95,100,101,116,97,105,108,115,90,10,98, + 117,105,108,116,105,110,95,111,115,114,21,0,0,0,114,25, + 0,0,0,90,9,111,115,95,109,111,100,117,108,101,90,13, + 116,104,114,101,97,100,95,109,111,100,117,108,101,90,14,119, + 101,97,107,114,101,102,95,109,111,100,117,108,101,90,13,119, + 105,110,114,101,103,95,109,111,100,117,108,101,114,4,0,0, + 0,114,4,0,0,0,114,5,0,0,0,218,6,95,115,101, + 116,117,112,28,9,0,0,115,106,0,0,0,0,9,6,1, + 6,2,12,1,9,2,6,3,12,1,28,1,15,1,15,1, + 9,1,15,1,9,2,3,1,15,1,17,3,13,1,13,1, + 15,1,15,2,13,1,20,3,33,1,19,2,31,1,10,1, + 15,1,13,1,4,2,3,1,12,1,5,1,13,1,12,2, + 12,1,16,1,16,1,25,3,3,1,16,1,13,2,11,1, + 16,3,12,1,16,3,12,1,12,1,16,3,19,1,19,1, + 12,1,13,1,12,1,114,136,1,0,0,99,2,0,0,0, + 0,0,0,0,3,0,0,0,3,0,0,0,67,0,0,0, + 115,133,0,0,0,116,0,0,124,0,0,124,1,0,131,2, + 0,1,116,1,0,131,0,0,125,2,0,116,2,0,106,3, + 0,106,4,0,116,5,0,106,6,0,124,2,0,140,0,0, + 103,1,0,131,1,0,1,116,2,0,106,7,0,106,8,0, + 116,9,0,131,1,0,1,116,2,0,106,7,0,106,8,0, + 116,10,0,131,1,0,1,116,11,0,106,12,0,100,1,0, + 107,2,0,114,113,0,116,2,0,106,7,0,106,8,0,116, + 13,0,131,1,0,1,116,2,0,106,7,0,106,8,0,116, + 14,0,131,1,0,1,100,2,0,83,41,3,122,50,73,110, + 115,116,97,108,108,32,105,109,112,111,114,116,108,105,98,32, + 97,115,32,116,104,101,32,105,109,112,108,101,109,101,110,116, + 97,116,105,111,110,32,111,102,32,105,109,112,111,114,116,46, + 114,130,1,0,0,78,41,15,114,136,1,0,0,114,240,0, + 0,0,114,7,0,0,0,114,78,1,0,0,114,196,0,0, + 0,114,87,1,0,0,114,100,1,0,0,114,106,1,0,0, + 114,223,0,0,0,114,9,1,0,0,114,18,1,0,0,114, + 3,0,0,0,114,57,0,0,0,114,22,1,0,0,114,73, + 1,0,0,41,3,114,134,1,0,0,114,135,1,0,0,90, + 17,115,117,112,112,111,114,116,101,100,95,108,111,97,100,101, + 114,115,114,4,0,0,0,114,4,0,0,0,114,5,0,0, + 0,218,8,95,105,110,115,116,97,108,108,114,9,0,0,115, + 16,0,0,0,0,2,13,1,9,1,28,1,16,1,16,1, + 15,1,16,1,114,137,1,0,0,41,3,122,3,119,105,110, + 114,1,0,0,0,114,2,0,0,0,41,98,114,59,0,0, + 0,114,10,0,0,0,114,11,0,0,0,114,17,0,0,0, + 114,19,0,0,0,114,28,0,0,0,114,38,0,0,0,114, + 39,0,0,0,114,43,0,0,0,114,44,0,0,0,114,46, + 0,0,0,114,55,0,0,0,114,65,0,0,0,114,68,0, + 0,0,114,66,0,0,0,218,8,95,95,99,111,100,101,95, + 95,114,192,0,0,0,114,69,0,0,0,114,109,0,0,0, + 114,92,0,0,0,114,99,0,0,0,114,82,0,0,0,114, + 83,0,0,0,114,102,0,0,0,114,103,0,0,0,114,105, + 0,0,0,114,112,0,0,0,114,114,0,0,0,114,15,0, + 0,0,114,184,0,0,0,114,14,0,0,0,114,18,0,0, + 0,90,17,95,82,65,87,95,77,65,71,73,67,95,78,85, + 77,66,69,82,114,124,0,0,0,114,135,0,0,0,114,119, + 0,0,0,114,120,0,0,0,114,132,0,0,0,114,136,0, + 0,0,114,143,0,0,0,114,145,0,0,0,114,153,0,0, + 0,114,157,0,0,0,114,162,0,0,0,114,165,0,0,0, + 114,173,0,0,0,114,179,0,0,0,114,189,0,0,0,114, + 194,0,0,0,114,197,0,0,0,114,202,0,0,0,114,211, + 0,0,0,114,212,0,0,0,114,216,0,0,0,114,174,0, + 0,0,218,6,111,98,106,101,99,116,114,241,0,0,0,114, + 239,0,0,0,114,247,0,0,0,114,253,0,0,0,114,1, + 1,0,0,114,209,0,0,0,114,175,0,0,0,114,4,1, + 0,0,114,5,1,0,0,114,176,0,0,0,114,8,1,0, + 0,114,9,1,0,0,114,18,1,0,0,114,22,1,0,0, + 114,32,1,0,0,114,33,1,0,0,114,48,1,0,0,114, + 7,1,0,0,114,6,1,0,0,114,59,1,0,0,114,56, + 1,0,0,114,60,1,0,0,114,250,0,0,0,114,73,1, + 0,0,114,87,1,0,0,114,101,1,0,0,114,104,1,0, + 0,114,105,1,0,0,114,107,1,0,0,114,110,1,0,0, + 114,119,1,0,0,114,111,1,0,0,114,113,1,0,0,114, + 114,1,0,0,114,115,1,0,0,114,121,1,0,0,114,123, + 1,0,0,114,240,0,0,0,114,126,1,0,0,114,127,1, + 0,0,114,136,1,0,0,114,137,1,0,0,114,4,0,0, + 0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, + 218,8,60,109,111,100,117,108,101,62,8,0,0,0,115,182, + 0,0,0,6,17,6,3,12,12,12,5,12,5,12,6,12, + 12,12,10,12,9,12,5,12,7,15,22,12,8,12,4,15, + 4,19,20,6,2,6,3,22,4,19,68,19,21,19,19,12, + 19,12,20,12,115,22,1,18,2,6,2,9,2,9,1,9, + 2,15,27,12,23,12,19,12,12,18,8,12,18,12,11,12, + 11,12,18,12,15,21,55,21,12,18,10,12,14,12,36,19, + 27,19,106,24,22,9,3,12,1,15,63,18,45,18,56,12, + 18,12,17,12,25,12,29,12,23,12,14,15,25,19,70,19, + 75,19,63,19,27,22,110,19,41,25,43,25,16,6,3,19, + 57,19,57,19,41,19,134,19,146,19,13,12,9,12,9,15, + 40,12,17,6,1,10,2,12,27,12,6,18,24,12,32,12, + 15,12,11,24,35,12,7,12,86, }; diff --git a/Python/marshal.c b/Python/marshal.c index dc5411c1ff76..93d9d1d477f8 100644 --- a/Python/marshal.c +++ b/Python/marshal.c @@ -12,8 +12,7 @@ #include "longintrepr.h" #include "code.h" #include "marshal.h" - -#define ABS(x) ((x) < 0 ? -(x) : (x)) +#include "../Modules/hashtable.h" /* High water mark to determine when the marshalled object is dangerously deep * and risks coring the interpreter. When the object stack gets this deep, @@ -21,7 +20,7 @@ * On Windows debug builds, reduce this value. */ #if defined(MS_WINDOWS) && defined(_DEBUG) -#define MAX_MARSHAL_STACK_DEPTH 1500 +#define MAX_MARSHAL_STACK_DEPTH 1000 #else #define MAX_MARSHAL_STACK_DEPTH 2000 #endif @@ -66,54 +65,83 @@ typedef struct { FILE *fp; int error; /* see WFERR_* values */ int depth; - /* If fp == NULL, the following are valid: */ - PyObject *readable; /* Stream-like object being read from */ PyObject *str; - PyObject *current_filename; char *ptr; char *end; char *buf; - Py_ssize_t buf_size; - PyObject *refs; /* dict on marshal, list on unmarshal */ + _Py_hashtable_t *hashtable; int version; } WFILE; -#define w_byte(c, p) if (((p)->fp)) putc((c), (p)->fp); \ - else if ((p)->ptr != (p)->end) *(p)->ptr++ = (c); \ - else w_more((c), p) +#define w_byte(c, p) do { \ + if ((p)->ptr != (p)->end || w_reserve((p), 1)) \ + *(p)->ptr++ = (c); \ + } while(0) static void -w_more(char c, WFILE *p) +w_flush(WFILE *p) +{ + assert(p->fp != NULL); + fwrite(p->buf, 1, p->ptr - p->buf, p->fp); + p->ptr = p->buf; +} + +static int +w_reserve(WFILE *p, Py_ssize_t needed) { - Py_ssize_t size, newsize; - if (p->str == NULL) - return; /* An error already occurred */ + Py_ssize_t pos, size, delta; + if (p->ptr == NULL) + return 0; /* An error already occurred */ + if (p->fp != NULL) { + w_flush(p); + return needed <= p->end - p->ptr; + } + assert(p->str != NULL); + pos = p->ptr - p->buf; size = PyBytes_Size(p->str); - newsize = size + size + 1024; - if (newsize > 32*1024*1024) { - newsize = size + (size >> 3); /* 12.5% overallocation */ + if (size > 16*1024*1024) + delta = (size >> 3); /* 12.5% overallocation */ + else + delta = size + 1024; + delta = Py_MAX(delta, needed); + if (delta > PY_SSIZE_T_MAX - size) { + p->error = WFERR_NOMEMORY; + return 0; } - if (_PyBytes_Resize(&p->str, newsize) != 0) { - p->ptr = p->end = NULL; + size += delta; + if (_PyBytes_Resize(&p->str, size) != 0) { + p->ptr = p->buf = p->end = NULL; + return 0; } else { - p->ptr = PyBytes_AS_STRING((PyBytesObject *)p->str) + size; - p->end = - PyBytes_AS_STRING((PyBytesObject *)p->str) + newsize; - *p->ptr++ = c; + p->buf = PyBytes_AS_STRING(p->str); + p->ptr = p->buf + pos; + p->end = p->buf + size; + return 1; } } static void w_string(const char *s, Py_ssize_t n, WFILE *p) { + Py_ssize_t m; + if (!n || p->ptr == NULL) + return; + m = p->end - p->ptr; if (p->fp != NULL) { - fwrite(s, 1, n, p->fp); + if (n <= m) { + Py_MEMCPY(p->ptr, s, n); + p->ptr += n; + } + else { + w_flush(p); + fwrite(s, 1, n, p->fp); + } } else { - while (--n >= 0) { - w_byte(*s, p); - s++; + if (n <= m || w_reserve(p, n - m)) { + Py_MEMCPY(p->ptr, s, n); + p->ptr += n; } } } @@ -192,7 +220,7 @@ w_PyLong(const PyLongObject *ob, char flag, WFILE *p) } /* set l to number of base PyLong_MARSHAL_BASE digits */ - n = ABS(Py_SIZE(ob)); + n = Py_ABS(Py_SIZE(ob)); l = (n-1) * PyLong_MARSHAL_RATIO; d = ob->ob_digit[n-1]; assert(d != 0); /* a PyLong is always normalized */ @@ -225,46 +253,38 @@ w_PyLong(const PyLongObject *ob, char flag, WFILE *p) static int w_ref(PyObject *v, char *flag, WFILE *p) { - PyObject *id; - PyObject *idx; + _Py_hashtable_entry_t *entry; + int w; - if (p->version < 3 || p->refs == NULL) + if (p->version < 3 || p->hashtable == NULL) return 0; /* not writing object references */ /* if it has only one reference, it definitely isn't shared */ if (Py_REFCNT(v) == 1) return 0; - id = PyLong_FromVoidPtr((void*)v); - if (id == NULL) - goto err; - idx = PyDict_GetItem(p->refs, id); - if (idx != NULL) { + entry = _Py_hashtable_get_entry(p->hashtable, v); + if (entry != NULL) { /* write the reference index to the stream */ - long w = PyLong_AsLong(idx); - Py_DECREF(id); - if (w == -1 && PyErr_Occurred()) { - goto err; - } + _Py_HASHTABLE_ENTRY_READ_DATA(p->hashtable, &w, sizeof(w), entry); /* we don't store "long" indices in the dict */ assert(0 <= w && w <= 0x7fffffff); w_byte(TYPE_REF, p); w_long(w, p); return 1; } else { - int ok; - Py_ssize_t s = PyDict_Size(p->refs); + size_t s = p->hashtable->entries; /* we don't support long indices */ if (s >= 0x7fffffff) { PyErr_SetString(PyExc_ValueError, "too many objects"); goto err; } - idx = PyLong_FromSsize_t(s); - ok = idx && PyDict_SetItem(p->refs, id, idx) == 0; - Py_DECREF(id); - Py_XDECREF(idx); - if (!ok) + w = (int)s; + Py_INCREF(v); + if (_Py_HASHTABLE_SET(p->hashtable, v, w) < 0) { + Py_DECREF(v); goto err; + } *flag |= FLAG_REF; return 0; } @@ -529,7 +549,7 @@ w_complex_object(PyObject *v, char flag, WFILE *p) w_object(co->co_lnotab, p); } else if (PyObject_CheckBuffer(v)) { - /* Write unknown buffer-style objects as a string */ + /* Write unknown bytes-like objects as a byte string */ Py_buffer view; if (PyObject_GetBuffer(v, &view, PyBUF_SIMPLE) != 0) { w_byte(TYPE_UNKNOWN, p); @@ -547,37 +567,81 @@ w_complex_object(PyObject *v, char flag, WFILE *p) } } +static int +w_init_refs(WFILE *wf, int version) +{ + if (version >= 3) { + wf->hashtable = _Py_hashtable_new(sizeof(int), _Py_hashtable_hash_ptr, + _Py_hashtable_compare_direct); + if (wf->hashtable == NULL) { + PyErr_NoMemory(); + return -1; + } + } + return 0; +} + +static int +w_decref_entry(_Py_hashtable_entry_t *entry, void *Py_UNUSED(data)) +{ + Py_XDECREF(entry->key); + return 0; +} + +static void +w_clear_refs(WFILE *wf) +{ + if (wf->hashtable != NULL) { + _Py_hashtable_foreach(wf->hashtable, w_decref_entry, NULL); + _Py_hashtable_destroy(wf->hashtable); + } +} + /* version currently has no effect for writing ints. */ void PyMarshal_WriteLongToFile(long x, FILE *fp, int version) { + char buf[4]; WFILE wf; + memset(&wf, 0, sizeof(wf)); wf.fp = fp; + wf.ptr = wf.buf = buf; + wf.end = wf.ptr + sizeof(buf); wf.error = WFERR_OK; - wf.depth = 0; - wf.refs = NULL; wf.version = version; w_long(x, &wf); + w_flush(&wf); } void PyMarshal_WriteObjectToFile(PyObject *x, FILE *fp, int version) { + char buf[BUFSIZ]; WFILE wf; + memset(&wf, 0, sizeof(wf)); wf.fp = fp; + wf.ptr = wf.buf = buf; + wf.end = wf.ptr + sizeof(buf); wf.error = WFERR_OK; - wf.depth = 0; - if (version >= 3) { - if ((wf.refs = PyDict_New()) == NULL) - return; /* caller mush check PyErr_Occurred() */ - } else - wf.refs = NULL; wf.version = version; + if (w_init_refs(&wf, version)) + return; /* caller mush check PyErr_Occurred() */ w_object(x, &wf); - Py_XDECREF(wf.refs); + w_clear_refs(&wf); + w_flush(&wf); } -typedef WFILE RFILE; /* Same struct with different invariants */ +typedef struct { + FILE *fp; + int depth; + PyObject *readable; /* Stream-like object being read from */ + PyObject *current_filename; + char *ptr; + char *end; + char *buf; + Py_ssize_t buf_size; + PyObject *refs; /* a list */ +} RFILE; static char * r_string(Py_ssize_t n, RFILE *p) @@ -727,8 +791,8 @@ r_PyLong(RFILE *p) return NULL; } - size = 1 + (ABS(n) - 1) / PyLong_MARSHAL_RATIO; - shorts_in_top_digit = 1 + (ABS(n) - 1) % PyLong_MARSHAL_RATIO; + size = 1 + (Py_ABS(n) - 1) / PyLong_MARSHAL_RATIO; + shorts_in_top_digit = 1 + (Py_ABS(n) - 1) % PyLong_MARSHAL_RATIO; ob = _PyLong_New(size); if (ob == NULL) return NULL; @@ -1417,16 +1481,20 @@ PyMarshal_ReadLongFromFile(FILE *fp) return res; } -#ifdef HAVE_FSTAT -/* Return size of file in bytes; < 0 if unknown. */ +#if defined(HAVE_FSTAT) || defined(MS_WINDOWS) +/* Return size of file in bytes; < 0 if unknown or INT_MAX if too big */ static off_t getfilesize(FILE *fp) { - struct stat st; - if (fstat(fileno(fp), &st) != 0) + struct _Py_stat_struct st; + if (_Py_fstat(fileno(fp), &st) != 0) return -1; +#if SIZEOF_OFF_T == 4 + else if (st.st_size >= INT_MAX) + return (off_t)INT_MAX; +#endif else - return st.st_size; + return (off_t)st.st_size; } #endif @@ -1441,7 +1509,7 @@ PyMarshal_ReadLastObjectFromFile(FILE *fp) { /* REASONABLE_FILE_LIMIT is by defn something big enough for Tkinter.pyc. */ #define REASONABLE_FILE_LIMIT (1L << 18) -#ifdef HAVE_FSTAT +#if defined(HAVE_FSTAT) || defined(MS_WINDOWS) off_t filesize; filesize = getfilesize(fp); if (filesize > 0 && filesize <= REASONABLE_FILE_LIMIT) { @@ -1511,23 +1579,20 @@ PyMarshal_WriteObjectToString(PyObject *x, int version) { WFILE wf; - wf.fp = NULL; - wf.readable = NULL; + memset(&wf, 0, sizeof(wf)); wf.str = PyBytes_FromStringAndSize((char *)NULL, 50); if (wf.str == NULL) return NULL; - wf.ptr = PyBytes_AS_STRING((PyBytesObject *)wf.str); + wf.ptr = wf.buf = PyBytes_AS_STRING((PyBytesObject *)wf.str); wf.end = wf.ptr + PyBytes_Size(wf.str); wf.error = WFERR_OK; - wf.depth = 0; wf.version = version; - if (version >= 3) { - if ((wf.refs = PyDict_New()) == NULL) - return NULL; - } else - wf.refs = NULL; + if (w_init_refs(&wf, version)) { + Py_DECREF(wf.str); + return NULL; + } w_object(x, &wf); - Py_XDECREF(wf.refs); + w_clear_refs(&wf); if (wf.str != NULL) { char *base = PyBytes_AS_STRING((PyBytesObject *)wf.str); if (wf.ptr - base > PY_SSIZE_T_MAX) { diff --git a/Python/modsupport.c b/Python/modsupport.c index 428914f3788a..6c938ddd797e 100644 --- a/Python/modsupport.c +++ b/Python/modsupport.c @@ -161,7 +161,17 @@ do_mktuple(const char **p_format, va_list *p_va, int endchar, int n, int flags) /* Note that we can't bail immediately on error as this will leak refcounts on any 'N' arguments. */ for (i = 0; i < n; i++) { - PyObject *w = do_mkvalue(p_format, p_va, flags); + PyObject *w; + + if (itemfailed) { + PyObject *exception, *value, *tb; + PyErr_Fetch(&exception, &value, &tb); + w = do_mkvalue(p_format, p_va, flags); + PyErr_Restore(exception, value, tb); + } + else { + w = do_mkvalue(p_format, p_va, flags); + } if (w == NULL) { itemfailed = 1; Py_INCREF(Py_None); diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h index f90a17a7ee27..1553a7a32f77 100644 --- a/Python/opcode_targets.h +++ b/Python/opcode_targets.h @@ -15,8 +15,8 @@ static void *opcode_targets[256] = { &&_unknown_opcode, &&_unknown_opcode, &&TARGET_UNARY_INVERT, - &&_unknown_opcode, - &&_unknown_opcode, + &&TARGET_BINARY_MATRIX_MULTIPLY, + &&TARGET_INPLACE_MATRIX_MULTIPLY, &&_unknown_opcode, &&TARGET_BINARY_POWER, &&TARGET_BINARY_MULTIPLY, diff --git a/Python/peephole.c b/Python/peephole.c index 4185462b34af..2f8f0e5b679b 100644 --- a/Python/peephole.c +++ b/Python/peephole.c @@ -18,7 +18,11 @@ || op==JUMP_IF_FALSE_OR_POP || op==JUMP_IF_TRUE_OR_POP) #define JUMPS_ON_TRUE(op) (op==POP_JUMP_IF_TRUE || op==JUMP_IF_TRUE_OR_POP) #define GETJUMPTGT(arr, i) (GETARG(arr,i) + (ABSOLUTE_JUMP(arr[i]) ? 0 : i+3)) -#define SETARG(arr, i, val) arr[i+2] = val>>8; arr[i+1] = val & 255 +#define SETARG(arr, i, val) do { \ + assert(0 <= val && val <= 0xffff); \ + arr[i+2] = (unsigned char)(((unsigned int)val)>>8); \ + arr[i+1] = (unsigned char)(((unsigned int)val) & 255); \ +} while(0) #define CODESIZE(op) (HAS_ARG(op) ? 3 : 1) #define ISBASICBLOCK(blocks, start, bytes) \ (blocks[start]==blocks[start+bytes-1]) @@ -290,7 +294,7 @@ fold_unaryops_on_constants(unsigned char *codestr, PyObject *consts, PyObject *v static unsigned int * markblocks(unsigned char *code, Py_ssize_t len) { - unsigned int *blocks = (unsigned int *)PyMem_Malloc(len*sizeof(int)); + unsigned int *blocks = PyMem_New(unsigned int, len); int i,j, opcode, blockcnt = 0; if (blocks == NULL) { @@ -355,7 +359,8 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names, unsigned char *codestr = NULL; unsigned char *lineno; int *addrmap = NULL; - int new_line, cum_orig_line, last_line, tabsiz; + int new_line, cum_orig_line, last_line; + Py_ssize_t tabsiz; PyObject **const_stack = NULL; Py_ssize_t *load_const_stack = NULL; Py_ssize_t const_stack_top = -1; @@ -398,7 +403,7 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names, goto exitUnchanged; /* Mapping to new jump targets after NOPs are removed */ - addrmap = (int *)PyMem_Malloc(codelen * sizeof(int)); + addrmap = PyMem_New(int, codelen); if (addrmap == NULL) { PyErr_NoMemory(); goto exitError; @@ -660,7 +665,8 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names, /* Fixup linenotab */ for (i=0, nops=0 ; i + +#ifdef HAVE_SIGNAL_H +#include +#endif + +#ifdef MS_WINDOWS +#include "malloc.h" /* for alloca */ +#endif + +#ifdef HAVE_LANGINFO_H +#include +#endif + +#ifdef MS_WINDOWS +#undef BYTE +#include "windows.h" +#endif + +_Py_IDENTIFIER(flush); +_Py_IDENTIFIER(name); +_Py_IDENTIFIER(stdin); +_Py_IDENTIFIER(stdout); +_Py_IDENTIFIER(stderr); + +#ifdef __cplusplus +extern "C" { +#endif + +extern wchar_t *Py_GetPath(void); + +extern grammar _PyParser_Grammar; /* From graminit.c */ + +/* Forward */ +static void initmain(PyInterpreterState *interp); +static int initfsencoding(PyInterpreterState *interp); +static void initsite(void); +static int initstdio(void); +static void initsigs(void); +static void call_py_exitfuncs(void); +static void wait_for_thread_shutdown(void); +static void call_ll_exitfuncs(void); +extern int _PyUnicode_Init(void); +extern int _PyStructSequence_Init(void); +extern void _PyUnicode_Fini(void); +extern int _PyLong_Init(void); +extern void PyLong_Fini(void); +extern int _PyFaulthandler_Init(void); +extern void _PyFaulthandler_Fini(void); +extern void _PyHash_Fini(void); +extern int _PyTraceMalloc_Init(void); +extern int _PyTraceMalloc_Fini(void); + +#ifdef WITH_THREAD +extern void _PyGILState_Init(PyInterpreterState *, PyThreadState *); +extern void _PyGILState_Fini(void); +#endif /* WITH_THREAD */ + +/* Global configuration variable declarations are in pydebug.h */ +/* XXX (ncoghlan): move those declarations to pylifecycle.h? */ +int Py_DebugFlag; /* Needed by parser.c */ +int Py_VerboseFlag; /* Needed by import.c */ +int Py_QuietFlag; /* Needed by sysmodule.c */ +int Py_InteractiveFlag; /* Needed by Py_FdIsInteractive() below */ +int Py_InspectFlag; /* Needed to determine whether to exit at SystemExit */ +int Py_OptimizeFlag = 0; /* Needed by compile.c */ +int Py_NoSiteFlag; /* Suppress 'import site' */ +int Py_BytesWarningFlag; /* Warn on str(bytes) and str(buffer) */ +int Py_UseClassExceptionsFlag = 1; /* Needed by bltinmodule.c: deprecated */ +int Py_FrozenFlag; /* Needed by getpath.c */ +int Py_IgnoreEnvironmentFlag; /* e.g. PYTHONPATH, PYTHONHOME */ +int Py_DontWriteBytecodeFlag; /* Suppress writing bytecode files (*.py[co]) */ +int Py_NoUserSiteDirectory = 0; /* for -s and site.py */ +int Py_UnbufferedStdioFlag = 0; /* Unbuffered binary std{in,out,err} */ +int Py_HashRandomizationFlag = 0; /* for -R and PYTHONHASHSEED */ +int Py_IsolatedFlag = 0; /* for -I, isolate from user's env */ + +PyThreadState *_Py_Finalizing = NULL; + +/* Hack to force loading of object files */ +int (*_PyOS_mystrnicmp_hack)(const char *, const char *, Py_ssize_t) = \ + PyOS_mystrnicmp; /* Python/pystrcmp.o */ + +/* PyModule_GetWarningsModule is no longer necessary as of 2.6 +since _warnings is builtin. This API should not be used. */ +PyObject * +PyModule_GetWarningsModule(void) +{ + return PyImport_ImportModule("warnings"); +} + +static int initialized = 0; + +/* API to access the initialized flag -- useful for esoteric use */ + +int +Py_IsInitialized(void) +{ + return initialized; +} + +/* Helper to allow an embedding application to override the normal + * mechanism that attempts to figure out an appropriate IO encoding + */ + +static char *_Py_StandardStreamEncoding = NULL; +static char *_Py_StandardStreamErrors = NULL; + +int +Py_SetStandardStreamEncoding(const char *encoding, const char *errors) +{ + if (Py_IsInitialized()) { + /* This is too late to have any effect */ + return -1; + } + /* Can't call PyErr_NoMemory() on errors, as Python hasn't been + * initialised yet. + * + * However, the raw memory allocators are initialised appropriately + * as C static variables, so _PyMem_RawStrdup is OK even though + * Py_Initialize hasn't been called yet. + */ + if (encoding) { + _Py_StandardStreamEncoding = _PyMem_RawStrdup(encoding); + if (!_Py_StandardStreamEncoding) { + return -2; + } + } + if (errors) { + _Py_StandardStreamErrors = _PyMem_RawStrdup(errors); + if (!_Py_StandardStreamErrors) { + if (_Py_StandardStreamEncoding) { + PyMem_RawFree(_Py_StandardStreamEncoding); + } + return -3; + } + } + return 0; +} + +/* Global initializations. Can be undone by Py_Finalize(). Don't + call this twice without an intervening Py_Finalize() call. When + initializations fail, a fatal error is issued and the function does + not return. On return, the first thread and interpreter state have + been created. + + Locking: you must hold the interpreter lock while calling this. + (If the lock has not yet been initialized, that's equivalent to + having the lock, but you cannot use multiple threads.) + +*/ + +static int +add_flag(int flag, const char *envs) +{ + int env = atoi(envs); + if (flag < env) + flag = env; + if (flag < 1) + flag = 1; + return flag; +} + +static char* +get_codec_name(const char *encoding) +{ + char *name_utf8, *name_str; + PyObject *codec, *name = NULL; + + codec = _PyCodec_Lookup(encoding); + if (!codec) + goto error; + + name = _PyObject_GetAttrId(codec, &PyId_name); + Py_CLEAR(codec); + if (!name) + goto error; + + name_utf8 = _PyUnicode_AsString(name); + if (name_utf8 == NULL) + goto error; + name_str = _PyMem_RawStrdup(name_utf8); + Py_DECREF(name); + if (name_str == NULL) { + PyErr_NoMemory(); + return NULL; + } + return name_str; + +error: + Py_XDECREF(codec); + Py_XDECREF(name); + return NULL; +} + +static char* +get_locale_encoding(void) +{ +#ifdef MS_WINDOWS + char codepage[100]; + PyOS_snprintf(codepage, sizeof(codepage), "cp%d", GetACP()); + return get_codec_name(codepage); +#elif defined(HAVE_LANGINFO_H) && defined(CODESET) + char* codeset = nl_langinfo(CODESET); + if (!codeset || codeset[0] == '\0') { + PyErr_SetString(PyExc_ValueError, "CODESET is not set or empty"); + return NULL; + } + return get_codec_name(codeset); +#else + PyErr_SetNone(PyExc_NotImplementedError); + return NULL; +#endif +} + +static void +import_init(PyInterpreterState *interp, PyObject *sysmod) +{ + PyObject *importlib; + PyObject *impmod; + PyObject *sys_modules; + PyObject *value; + + /* Import _importlib through its frozen version, _frozen_importlib. */ + if (PyImport_ImportFrozenModule("_frozen_importlib") <= 0) { + Py_FatalError("Py_Initialize: can't import _frozen_importlib"); + } + else if (Py_VerboseFlag) { + PySys_FormatStderr("import _frozen_importlib # frozen\n"); + } + importlib = PyImport_AddModule("_frozen_importlib"); + if (importlib == NULL) { + Py_FatalError("Py_Initialize: couldn't get _frozen_importlib from " + "sys.modules"); + } + interp->importlib = importlib; + Py_INCREF(interp->importlib); + + /* Install _importlib as __import__ */ + impmod = PyInit_imp(); + if (impmod == NULL) { + Py_FatalError("Py_Initialize: can't import imp"); + } + else if (Py_VerboseFlag) { + PySys_FormatStderr("import imp # builtin\n"); + } + sys_modules = PyImport_GetModuleDict(); + if (Py_VerboseFlag) { + PySys_FormatStderr("import sys # builtin\n"); + } + if (PyDict_SetItemString(sys_modules, "_imp", impmod) < 0) { + Py_FatalError("Py_Initialize: can't save _imp to sys.modules"); + } + + value = PyObject_CallMethod(importlib, "_install", "OO", sysmod, impmod); + if (value == NULL) { + PyErr_Print(); + Py_FatalError("Py_Initialize: importlib install failed"); + } + Py_DECREF(value); + Py_DECREF(impmod); + + _PyImportZip_Init(); +} + + +void +_Py_InitializeEx_Private(int install_sigs, int install_importlib) +{ + PyInterpreterState *interp; + PyThreadState *tstate; + PyObject *bimod, *sysmod, *pstderr; + char *p; + extern void _Py_ReadyTypes(void); + + if (initialized) + return; + initialized = 1; + _Py_Finalizing = NULL; + +#if defined(HAVE_LANGINFO_H) && defined(HAVE_SETLOCALE) + /* Set up the LC_CTYPE locale, so we can obtain + the locale's charset without having to switch + locales. */ + setlocale(LC_CTYPE, ""); +#endif + + if ((p = Py_GETENV("PYTHONDEBUG")) && *p != '\0') + Py_DebugFlag = add_flag(Py_DebugFlag, p); + if ((p = Py_GETENV("PYTHONVERBOSE")) && *p != '\0') + Py_VerboseFlag = add_flag(Py_VerboseFlag, p); + if ((p = Py_GETENV("PYTHONOPTIMIZE")) && *p != '\0') + Py_OptimizeFlag = add_flag(Py_OptimizeFlag, p); + if ((p = Py_GETENV("PYTHONDONTWRITEBYTECODE")) && *p != '\0') + Py_DontWriteBytecodeFlag = add_flag(Py_DontWriteBytecodeFlag, p); + /* The variable is only tested for existence here; _PyRandom_Init will + check its value further. */ + if ((p = Py_GETENV("PYTHONHASHSEED")) && *p != '\0') + Py_HashRandomizationFlag = add_flag(Py_HashRandomizationFlag, p); + + _PyRandom_Init(); + + interp = PyInterpreterState_New(); + if (interp == NULL) + Py_FatalError("Py_Initialize: can't make first interpreter"); + + tstate = PyThreadState_New(interp); + if (tstate == NULL) + Py_FatalError("Py_Initialize: can't make first thread"); + (void) PyThreadState_Swap(tstate); + +#ifdef WITH_THREAD + /* We can't call _PyEval_FiniThreads() in Py_Finalize because + destroying the GIL might fail when it is being referenced from + another running thread (see issue #9901). + Instead we destroy the previously created GIL here, which ensures + that we can call Py_Initialize / Py_Finalize multiple times. */ + _PyEval_FiniThreads(); + + /* Auto-thread-state API */ + _PyGILState_Init(interp, tstate); +#endif /* WITH_THREAD */ + + _Py_ReadyTypes(); + + if (!_PyFrame_Init()) + Py_FatalError("Py_Initialize: can't init frames"); + + if (!_PyLong_Init()) + Py_FatalError("Py_Initialize: can't init longs"); + + if (!PyByteArray_Init()) + Py_FatalError("Py_Initialize: can't init bytearray"); + + if (!_PyFloat_Init()) + Py_FatalError("Py_Initialize: can't init float"); + + interp->modules = PyDict_New(); + if (interp->modules == NULL) + Py_FatalError("Py_Initialize: can't make modules dictionary"); + + /* Init Unicode implementation; relies on the codec registry */ + if (_PyUnicode_Init() < 0) + Py_FatalError("Py_Initialize: can't initialize unicode"); + if (_PyStructSequence_Init() < 0) + Py_FatalError("Py_Initialize: can't initialize structseq"); + + bimod = _PyBuiltin_Init(); + if (bimod == NULL) + Py_FatalError("Py_Initialize: can't initialize builtins modules"); + _PyImport_FixupBuiltin(bimod, "builtins"); + interp->builtins = PyModule_GetDict(bimod); + if (interp->builtins == NULL) + Py_FatalError("Py_Initialize: can't initialize builtins dict"); + Py_INCREF(interp->builtins); + + /* initialize builtin exceptions */ + _PyExc_Init(bimod); + + sysmod = _PySys_Init(); + if (sysmod == NULL) + Py_FatalError("Py_Initialize: can't initialize sys"); + interp->sysdict = PyModule_GetDict(sysmod); + if (interp->sysdict == NULL) + Py_FatalError("Py_Initialize: can't initialize sys dict"); + Py_INCREF(interp->sysdict); + _PyImport_FixupBuiltin(sysmod, "sys"); + PySys_SetPath(Py_GetPath()); + PyDict_SetItemString(interp->sysdict, "modules", + interp->modules); + + /* Set up a preliminary stderr printer until we have enough + infrastructure for the io module in place. */ + pstderr = PyFile_NewStdPrinter(fileno(stderr)); + if (pstderr == NULL) + Py_FatalError("Py_Initialize: can't set preliminary stderr"); + _PySys_SetObjectId(&PyId_stderr, pstderr); + PySys_SetObject("__stderr__", pstderr); + Py_DECREF(pstderr); + + _PyImport_Init(); + + _PyImportHooks_Init(); + + /* Initialize _warnings. */ + _PyWarnings_Init(); + + if (!install_importlib) + return; + + import_init(interp, sysmod); + + /* initialize the faulthandler module */ + if (_PyFaulthandler_Init()) + Py_FatalError("Py_Initialize: can't initialize faulthandler"); + + if (_PyTime_Init() < 0) + Py_FatalError("Py_Initialize: can't initialize time"); + + if (initfsencoding(interp) < 0) + Py_FatalError("Py_Initialize: unable to load the file system codec"); + + if (install_sigs) + initsigs(); /* Signal handling stuff, including initintr() */ + + if (_PyTraceMalloc_Init() < 0) + Py_FatalError("Py_Initialize: can't initialize tracemalloc"); + + initmain(interp); /* Module __main__ */ + if (initstdio() < 0) + Py_FatalError( + "Py_Initialize: can't initialize sys standard streams"); + + /* Initialize warnings. */ + if (PySys_HasWarnOptions()) { + PyObject *warnings_module = PyImport_ImportModule("warnings"); + if (warnings_module == NULL) { + fprintf(stderr, "'import warnings' failed; traceback:\n"); + PyErr_Print(); + } + Py_XDECREF(warnings_module); + } + + if (!Py_NoSiteFlag) + initsite(); /* Module site */ +} + +void +Py_InitializeEx(int install_sigs) +{ + _Py_InitializeEx_Private(install_sigs, 1); +} + +void +Py_Initialize(void) +{ + Py_InitializeEx(1); +} + + +#ifdef COUNT_ALLOCS +extern void dump_counts(FILE*); +#endif + +/* Flush stdout and stderr */ + +static int +file_is_closed(PyObject *fobj) +{ + int r; + PyObject *tmp = PyObject_GetAttrString(fobj, "closed"); + if (tmp == NULL) { + PyErr_Clear(); + return 0; + } + r = PyObject_IsTrue(tmp); + Py_DECREF(tmp); + if (r < 0) + PyErr_Clear(); + return r > 0; +} + +static void +flush_std_files(void) +{ + PyObject *fout = _PySys_GetObjectId(&PyId_stdout); + PyObject *ferr = _PySys_GetObjectId(&PyId_stderr); + PyObject *tmp; + + if (fout != NULL && fout != Py_None && !file_is_closed(fout)) { + tmp = _PyObject_CallMethodId(fout, &PyId_flush, ""); + if (tmp == NULL) + PyErr_WriteUnraisable(fout); + else + Py_DECREF(tmp); + } + + if (ferr != NULL && ferr != Py_None && !file_is_closed(ferr)) { + tmp = _PyObject_CallMethodId(ferr, &PyId_flush, ""); + if (tmp == NULL) + PyErr_Clear(); + else + Py_DECREF(tmp); + } +} + +/* Undo the effect of Py_Initialize(). + + Beware: if multiple interpreter and/or thread states exist, these + are not wiped out; only the current thread and interpreter state + are deleted. But since everything else is deleted, those other + interpreter and thread states should no longer be used. + + (XXX We should do better, e.g. wipe out all interpreters and + threads.) + + Locking: as above. + +*/ + +void +Py_Finalize(void) +{ + PyInterpreterState *interp; + PyThreadState *tstate; + + if (!initialized) + return; + + wait_for_thread_shutdown(); + + /* The interpreter is still entirely intact at this point, and the + * exit funcs may be relying on that. In particular, if some thread + * or exit func is still waiting to do an import, the import machinery + * expects Py_IsInitialized() to return true. So don't say the + * interpreter is uninitialized until after the exit funcs have run. + * Note that Threading.py uses an exit func to do a join on all the + * threads created thru it, so this also protects pending imports in + * the threads created via Threading. + */ + call_py_exitfuncs(); + + /* Get current thread state and interpreter pointer */ + tstate = PyThreadState_GET(); + interp = tstate->interp; + + /* Remaining threads (e.g. daemon threads) will automatically exit + after taking the GIL (in PyEval_RestoreThread()). */ + _Py_Finalizing = tstate; + initialized = 0; + + /* Flush stdout+stderr */ + flush_std_files(); + + /* Disable signal handling */ + PyOS_FiniInterrupts(); + + /* Collect garbage. This may call finalizers; it's nice to call these + * before all modules are destroyed. + * XXX If a __del__ or weakref callback is triggered here, and tries to + * XXX import a module, bad things can happen, because Python no + * XXX longer believes it's initialized. + * XXX Fatal Python error: Interpreter not initialized (version mismatch?) + * XXX is easy to provoke that way. I've also seen, e.g., + * XXX Exception exceptions.ImportError: 'No module named sha' + * XXX in ignored + * XXX but I'm unclear on exactly how that one happens. In any case, + * XXX I haven't seen a real-life report of either of these. + */ + PyGC_Collect(); +#ifdef COUNT_ALLOCS + /* With COUNT_ALLOCS, it helps to run GC multiple times: + each collection might release some types from the type + list, so they become garbage. */ + while (PyGC_Collect() > 0) + /* nothing */; +#endif + /* Destroy all modules */ + PyImport_Cleanup(); + + /* Flush stdout+stderr (again, in case more was printed) */ + flush_std_files(); + + /* Collect final garbage. This disposes of cycles created by + * class definitions, for example. + * XXX This is disabled because it caused too many problems. If + * XXX a __del__ or weakref callback triggers here, Python code has + * XXX a hard time running, because even the sys module has been + * XXX cleared out (sys.stdout is gone, sys.excepthook is gone, etc). + * XXX One symptom is a sequence of information-free messages + * XXX coming from threads (if a __del__ or callback is invoked, + * XXX other threads can execute too, and any exception they encounter + * XXX triggers a comedy of errors as subsystem after subsystem + * XXX fails to find what it *expects* to find in sys to help report + * XXX the exception and consequent unexpected failures). I've also + * XXX seen segfaults then, after adding print statements to the + * XXX Python code getting called. + */ +#if 0 + PyGC_Collect(); +#endif + + /* Disable tracemalloc after all Python objects have been destroyed, + so it is possible to use tracemalloc in objects destructor. */ + _PyTraceMalloc_Fini(); + + /* Destroy the database used by _PyImport_{Fixup,Find}Extension */ + _PyImport_Fini(); + + /* Cleanup typeobject.c's internal caches. */ + _PyType_Fini(); + + /* unload faulthandler module */ + _PyFaulthandler_Fini(); + + /* Debugging stuff */ +#ifdef COUNT_ALLOCS + dump_counts(stdout); +#endif + /* dump hash stats */ + _PyHash_Fini(); + + _PY_DEBUG_PRINT_TOTAL_REFS(); + +#ifdef Py_TRACE_REFS + /* Display all objects still alive -- this can invoke arbitrary + * __repr__ overrides, so requires a mostly-intact interpreter. + * Alas, a lot of stuff may still be alive now that will be cleaned + * up later. + */ + if (Py_GETENV("PYTHONDUMPREFS")) + _Py_PrintReferences(stderr); +#endif /* Py_TRACE_REFS */ + + /* Clear interpreter state and all thread states. */ + PyInterpreterState_Clear(interp); + + /* Now we decref the exception classes. After this point nothing + can raise an exception. That's okay, because each Fini() method + below has been checked to make sure no exceptions are ever + raised. + */ + + _PyExc_Fini(); + + /* Sundry finalizers */ + PyMethod_Fini(); + PyFrame_Fini(); + PyCFunction_Fini(); + PyTuple_Fini(); + PyList_Fini(); + PySet_Fini(); + PyBytes_Fini(); + PyByteArray_Fini(); + PyLong_Fini(); + PyFloat_Fini(); + PyDict_Fini(); + PySlice_Fini(); + _PyGC_Fini(); + _PyRandom_Fini(); + + /* Cleanup Unicode implementation */ + _PyUnicode_Fini(); + + /* reset file system default encoding */ + if (!Py_HasFileSystemDefaultEncoding && Py_FileSystemDefaultEncoding) { + PyMem_RawFree((char*)Py_FileSystemDefaultEncoding); + Py_FileSystemDefaultEncoding = NULL; + } + + /* XXX Still allocated: + - various static ad-hoc pointers to interned strings + - int and float free list blocks + - whatever various modules and libraries allocate + */ + + PyGrammar_RemoveAccelerators(&_PyParser_Grammar); + + /* Cleanup auto-thread-state */ +#ifdef WITH_THREAD + _PyGILState_Fini(); +#endif /* WITH_THREAD */ + + /* Delete current thread. After this, many C API calls become crashy. */ + PyThreadState_Swap(NULL); + PyInterpreterState_Delete(interp); + +#ifdef Py_TRACE_REFS + /* Display addresses (& refcnts) of all objects still alive. + * An address can be used to find the repr of the object, printed + * above by _Py_PrintReferences. + */ + if (Py_GETENV("PYTHONDUMPREFS")) + _Py_PrintReferenceAddresses(stderr); +#endif /* Py_TRACE_REFS */ +#ifdef PYMALLOC_DEBUG + if (Py_GETENV("PYTHONMALLOCSTATS")) + _PyObject_DebugMallocStats(stderr); +#endif + + call_ll_exitfuncs(); +} + +/* Create and initialize a new interpreter and thread, and return the + new thread. This requires that Py_Initialize() has been called + first. + + Unsuccessful initialization yields a NULL pointer. Note that *no* + exception information is available even in this case -- the + exception information is held in the thread, and there is no + thread. + + Locking: as above. + +*/ + +PyThreadState * +Py_NewInterpreter(void) +{ + PyInterpreterState *interp; + PyThreadState *tstate, *save_tstate; + PyObject *bimod, *sysmod; + + if (!initialized) + Py_FatalError("Py_NewInterpreter: call Py_Initialize first"); + + interp = PyInterpreterState_New(); + if (interp == NULL) + return NULL; + + tstate = PyThreadState_New(interp); + if (tstate == NULL) { + PyInterpreterState_Delete(interp); + return NULL; + } + + save_tstate = PyThreadState_Swap(tstate); + + /* XXX The following is lax in error checking */ + + interp->modules = PyDict_New(); + + bimod = _PyImport_FindBuiltin("builtins"); + if (bimod != NULL) { + interp->builtins = PyModule_GetDict(bimod); + if (interp->builtins == NULL) + goto handle_error; + Py_INCREF(interp->builtins); + } + + /* initialize builtin exceptions */ + _PyExc_Init(bimod); + + sysmod = _PyImport_FindBuiltin("sys"); + if (bimod != NULL && sysmod != NULL) { + PyObject *pstderr; + + interp->sysdict = PyModule_GetDict(sysmod); + if (interp->sysdict == NULL) + goto handle_error; + Py_INCREF(interp->sysdict); + PySys_SetPath(Py_GetPath()); + PyDict_SetItemString(interp->sysdict, "modules", + interp->modules); + /* Set up a preliminary stderr printer until we have enough + infrastructure for the io module in place. */ + pstderr = PyFile_NewStdPrinter(fileno(stderr)); + if (pstderr == NULL) + Py_FatalError("Py_Initialize: can't set preliminary stderr"); + _PySys_SetObjectId(&PyId_stderr, pstderr); + PySys_SetObject("__stderr__", pstderr); + Py_DECREF(pstderr); + + _PyImportHooks_Init(); + + import_init(interp, sysmod); + + if (initfsencoding(interp) < 0) + goto handle_error; + + if (initstdio() < 0) + Py_FatalError( + "Py_Initialize: can't initialize sys standard streams"); + initmain(interp); + if (!Py_NoSiteFlag) + initsite(); + } + + if (!PyErr_Occurred()) + return tstate; + +handle_error: + /* Oops, it didn't work. Undo it all. */ + + PyErr_PrintEx(0); + PyThreadState_Clear(tstate); + PyThreadState_Swap(save_tstate); + PyThreadState_Delete(tstate); + PyInterpreterState_Delete(interp); + + return NULL; +} + +/* Delete an interpreter and its last thread. This requires that the + given thread state is current, that the thread has no remaining + frames, and that it is its interpreter's only remaining thread. + It is a fatal error to violate these constraints. + + (Py_Finalize() doesn't have these constraints -- it zaps + everything, regardless.) + + Locking: as above. + +*/ + +void +Py_EndInterpreter(PyThreadState *tstate) +{ + PyInterpreterState *interp = tstate->interp; + + if (tstate != PyThreadState_GET()) + Py_FatalError("Py_EndInterpreter: thread is not current"); + if (tstate->frame != NULL) + Py_FatalError("Py_EndInterpreter: thread still has a frame"); + + wait_for_thread_shutdown(); + + if (tstate != interp->tstate_head || tstate->next != NULL) + Py_FatalError("Py_EndInterpreter: not the last thread"); + + PyImport_Cleanup(); + PyInterpreterState_Clear(interp); + PyThreadState_Swap(NULL); + PyInterpreterState_Delete(interp); +} + +#ifdef MS_WINDOWS +static wchar_t *progname = L"python"; +#else +static wchar_t *progname = L"python3"; +#endif + +void +Py_SetProgramName(wchar_t *pn) +{ + if (pn && *pn) + progname = pn; +} + +wchar_t * +Py_GetProgramName(void) +{ + return progname; +} + +static wchar_t *default_home = NULL; +static wchar_t env_home[MAXPATHLEN+1]; + +void +Py_SetPythonHome(wchar_t *home) +{ + default_home = home; +} + +wchar_t * +Py_GetPythonHome(void) +{ + wchar_t *home = default_home; + if (home == NULL && !Py_IgnoreEnvironmentFlag) { + char* chome = Py_GETENV("PYTHONHOME"); + if (chome) { + size_t size = Py_ARRAY_LENGTH(env_home); + size_t r = mbstowcs(env_home, chome, size); + if (r != (size_t)-1 && r < size) + home = env_home; + } + + } + return home; +} + +/* Create __main__ module */ + +static void +initmain(PyInterpreterState *interp) +{ + PyObject *m, *d, *loader; + m = PyImport_AddModule("__main__"); + if (m == NULL) + Py_FatalError("can't create __main__ module"); + d = PyModule_GetDict(m); + if (PyDict_GetItemString(d, "__builtins__") == NULL) { + PyObject *bimod = PyImport_ImportModule("builtins"); + if (bimod == NULL) { + Py_FatalError("Failed to retrieve builtins module"); + } + if (PyDict_SetItemString(d, "__builtins__", bimod) < 0) { + Py_FatalError("Failed to initialize __main__.__builtins__"); + } + Py_DECREF(bimod); + } + /* Main is a little special - imp.is_builtin("__main__") will return + * False, but BuiltinImporter is still the most appropriate initial + * setting for its __loader__ attribute. A more suitable value will + * be set if __main__ gets further initialized later in the startup + * process. + */ + loader = PyDict_GetItemString(d, "__loader__"); + if (loader == NULL || loader == Py_None) { + PyObject *loader = PyObject_GetAttrString(interp->importlib, + "BuiltinImporter"); + if (loader == NULL) { + Py_FatalError("Failed to retrieve BuiltinImporter"); + } + if (PyDict_SetItemString(d, "__loader__", loader) < 0) { + Py_FatalError("Failed to initialize __main__.__loader__"); + } + Py_DECREF(loader); + } +} + +static int +initfsencoding(PyInterpreterState *interp) +{ + PyObject *codec; + + if (Py_FileSystemDefaultEncoding == NULL) + { + Py_FileSystemDefaultEncoding = get_locale_encoding(); + if (Py_FileSystemDefaultEncoding == NULL) + Py_FatalError("Py_Initialize: Unable to get the locale encoding"); + + Py_HasFileSystemDefaultEncoding = 0; + interp->fscodec_initialized = 1; + return 0; + } + + /* the encoding is mbcs, utf-8 or ascii */ + codec = _PyCodec_Lookup(Py_FileSystemDefaultEncoding); + if (!codec) { + /* Such error can only occurs in critical situations: no more + * memory, import a module of the standard library failed, + * etc. */ + return -1; + } + Py_DECREF(codec); + interp->fscodec_initialized = 1; + return 0; +} + +/* Import the site module (not into __main__ though) */ + +static void +initsite(void) +{ + PyObject *m; + m = PyImport_ImportModule("site"); + if (m == NULL) { + fprintf(stderr, "Failed to import the site module\n"); + PyErr_Print(); + Py_Finalize(); + exit(1); + } + else { + Py_DECREF(m); + } +} + +static PyObject* +create_stdio(PyObject* io, + int fd, int write_mode, char* name, + char* encoding, char* errors) +{ + PyObject *buf = NULL, *stream = NULL, *text = NULL, *raw = NULL, *res; + const char* mode; + const char* newline; + PyObject *line_buffering; + int buffering, isatty; + _Py_IDENTIFIER(open); + _Py_IDENTIFIER(isatty); + _Py_IDENTIFIER(TextIOWrapper); + _Py_IDENTIFIER(mode); + + /* stdin is always opened in buffered mode, first because it shouldn't + make a difference in common use cases, second because TextIOWrapper + depends on the presence of a read1() method which only exists on + buffered streams. + */ + if (Py_UnbufferedStdioFlag && write_mode) + buffering = 0; + else + buffering = -1; + if (write_mode) + mode = "wb"; + else + mode = "rb"; + buf = _PyObject_CallMethodId(io, &PyId_open, "isiOOOi", + fd, mode, buffering, + Py_None, Py_None, Py_None, 0); + if (buf == NULL) + goto error; + + if (buffering) { + _Py_IDENTIFIER(raw); + raw = _PyObject_GetAttrId(buf, &PyId_raw); + if (raw == NULL) + goto error; + } + else { + raw = buf; + Py_INCREF(raw); + } + + text = PyUnicode_FromString(name); + if (text == NULL || _PyObject_SetAttrId(raw, &PyId_name, text) < 0) + goto error; + res = _PyObject_CallMethodId(raw, &PyId_isatty, ""); + if (res == NULL) + goto error; + isatty = PyObject_IsTrue(res); + Py_DECREF(res); + if (isatty == -1) + goto error; + if (isatty || Py_UnbufferedStdioFlag) + line_buffering = Py_True; + else + line_buffering = Py_False; + + Py_CLEAR(raw); + Py_CLEAR(text); + +#ifdef MS_WINDOWS + /* sys.stdin: enable universal newline mode, translate "\r\n" and "\r" + newlines to "\n". + sys.stdout and sys.stderr: translate "\n" to "\r\n". */ + newline = NULL; +#else + /* sys.stdin: split lines at "\n". + sys.stdout and sys.stderr: don't translate newlines (use "\n"). */ + newline = "\n"; +#endif + + stream = _PyObject_CallMethodId(io, &PyId_TextIOWrapper, "OsssO", + buf, encoding, errors, + newline, line_buffering); + Py_CLEAR(buf); + if (stream == NULL) + goto error; + + if (write_mode) + mode = "w"; + else + mode = "r"; + text = PyUnicode_FromString(mode); + if (!text || _PyObject_SetAttrId(stream, &PyId_mode, text) < 0) + goto error; + Py_CLEAR(text); + return stream; + +error: + Py_XDECREF(buf); + Py_XDECREF(stream); + Py_XDECREF(text); + Py_XDECREF(raw); + return NULL; +} + +static int +is_valid_fd(int fd) +{ + int dummy_fd; + if (fd < 0 || !_PyVerify_fd(fd)) + return 0; + dummy_fd = dup(fd); + if (dummy_fd < 0) + return 0; + close(dummy_fd); + return 1; +} + +/* Initialize sys.stdin, stdout, stderr and builtins.open */ +static int +initstdio(void) +{ + PyObject *iomod = NULL, *wrapper; + PyObject *bimod = NULL; + PyObject *m; + PyObject *std = NULL; + int status = 0, fd; + PyObject * encoding_attr; + char *pythonioencoding = NULL, *encoding, *errors; + + /* Hack to avoid a nasty recursion issue when Python is invoked + in verbose mode: pre-import the Latin-1 and UTF-8 codecs */ + if ((m = PyImport_ImportModule("encodings.utf_8")) == NULL) { + goto error; + } + Py_DECREF(m); + + if (!(m = PyImport_ImportModule("encodings.latin_1"))) { + goto error; + } + Py_DECREF(m); + + if (!(bimod = PyImport_ImportModule("builtins"))) { + goto error; + } + + if (!(iomod = PyImport_ImportModule("io"))) { + goto error; + } + if (!(wrapper = PyObject_GetAttrString(iomod, "OpenWrapper"))) { + goto error; + } + + /* Set builtins.open */ + if (PyObject_SetAttrString(bimod, "open", wrapper) == -1) { + Py_DECREF(wrapper); + goto error; + } + Py_DECREF(wrapper); + + encoding = _Py_StandardStreamEncoding; + errors = _Py_StandardStreamErrors; + if (!encoding || !errors) { + if (!errors) { + /* When the LC_CTYPE locale is the POSIX locale ("C locale"), + stdin and stdout use the surrogateescape error handler by + default, instead of the strict error handler. */ + char *loc = setlocale(LC_CTYPE, NULL); + if (loc != NULL && strcmp(loc, "C") == 0) + errors = "surrogateescape"; + } + + pythonioencoding = Py_GETENV("PYTHONIOENCODING"); + if (pythonioencoding) { + char *err; + pythonioencoding = _PyMem_Strdup(pythonioencoding); + if (pythonioencoding == NULL) { + PyErr_NoMemory(); + goto error; + } + err = strchr(pythonioencoding, ':'); + if (err) { + *err = '\0'; + err++; + if (*err && !_Py_StandardStreamErrors) { + errors = err; + } + } + if (*pythonioencoding && !encoding) { + encoding = pythonioencoding; + } + } + } + + /* Set sys.stdin */ + fd = fileno(stdin); + /* Under some conditions stdin, stdout and stderr may not be connected + * and fileno() may point to an invalid file descriptor. For example + * GUI apps don't have valid standard streams by default. + */ + if (!is_valid_fd(fd)) { + std = Py_None; + Py_INCREF(std); + } + else { + std = create_stdio(iomod, fd, 0, "", encoding, errors); + if (std == NULL) + goto error; + } /* if (fd < 0) */ + PySys_SetObject("__stdin__", std); + _PySys_SetObjectId(&PyId_stdin, std); + Py_DECREF(std); + + /* Set sys.stdout */ + fd = fileno(stdout); + if (!is_valid_fd(fd)) { + std = Py_None; + Py_INCREF(std); + } + else { + std = create_stdio(iomod, fd, 1, "", encoding, errors); + if (std == NULL) + goto error; + } /* if (fd < 0) */ + PySys_SetObject("__stdout__", std); + _PySys_SetObjectId(&PyId_stdout, std); + Py_DECREF(std); + +#if 1 /* Disable this if you have trouble debugging bootstrap stuff */ + /* Set sys.stderr, replaces the preliminary stderr */ + fd = fileno(stderr); + if (!is_valid_fd(fd)) { + std = Py_None; + Py_INCREF(std); + } + else { + std = create_stdio(iomod, fd, 1, "", encoding, "backslashreplace"); + if (std == NULL) + goto error; + } /* if (fd < 0) */ + + /* Same as hack above, pre-import stderr's codec to avoid recursion + when import.c tries to write to stderr in verbose mode. */ + encoding_attr = PyObject_GetAttrString(std, "encoding"); + if (encoding_attr != NULL) { + const char * std_encoding; + std_encoding = _PyUnicode_AsString(encoding_attr); + if (std_encoding != NULL) { + PyObject *codec_info = _PyCodec_Lookup(std_encoding); + Py_XDECREF(codec_info); + } + Py_DECREF(encoding_attr); + } + PyErr_Clear(); /* Not a fatal error if codec isn't available */ + + if (PySys_SetObject("__stderr__", std) < 0) { + Py_DECREF(std); + goto error; + } + if (_PySys_SetObjectId(&PyId_stderr, std) < 0) { + Py_DECREF(std); + goto error; + } + Py_DECREF(std); +#endif + + if (0) { + error: + status = -1; + } + + /* We won't need them anymore. */ + if (_Py_StandardStreamEncoding) { + PyMem_RawFree(_Py_StandardStreamEncoding); + _Py_StandardStreamEncoding = NULL; + } + if (_Py_StandardStreamErrors) { + PyMem_RawFree(_Py_StandardStreamErrors); + _Py_StandardStreamErrors = NULL; + } + PyMem_Free(pythonioencoding); + Py_XDECREF(bimod); + Py_XDECREF(iomod); + return status; +} + + +/* Print fatal error message and abort */ + +void +Py_FatalError(const char *msg) +{ + const int fd = fileno(stderr); + PyThreadState *tstate; + + fprintf(stderr, "Fatal Python error: %s\n", msg); + fflush(stderr); /* it helps in Windows debug build */ + if (PyErr_Occurred()) { + PyErr_PrintEx(0); + } + else { + tstate = (PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current); + if (tstate != NULL) { + fputc('\n', stderr); + fflush(stderr); + _Py_DumpTracebackThreads(fd, tstate->interp, tstate); + } + _PyFaulthandler_Fini(); + } + +#ifdef MS_WINDOWS + { + size_t len = strlen(msg); + WCHAR* buffer; + size_t i; + + /* Convert the message to wchar_t. This uses a simple one-to-one + conversion, assuming that the this error message actually uses ASCII + only. If this ceases to be true, we will have to convert. */ + buffer = alloca( (len+1) * (sizeof *buffer)); + for( i=0; i<=len; ++i) + buffer[i] = msg[i]; + OutputDebugStringW(L"Fatal Python error: "); + OutputDebugStringW(buffer); + OutputDebugStringW(L"\n"); + } +#ifdef _DEBUG + DebugBreak(); +#endif +#endif /* MS_WINDOWS */ + abort(); +} + +/* Clean up and exit */ + +#ifdef WITH_THREAD +#include "pythread.h" +#endif + +static void (*pyexitfunc)(void) = NULL; +/* For the atexit module. */ +void _Py_PyAtExit(void (*func)(void)) +{ + pyexitfunc = func; +} + +static void +call_py_exitfuncs(void) +{ + if (pyexitfunc == NULL) + return; + + (*pyexitfunc)(); + PyErr_Clear(); +} + +/* Wait until threading._shutdown completes, provided + the threading module was imported in the first place. + The shutdown routine will wait until all non-daemon + "threading" threads have completed. */ +static void +wait_for_thread_shutdown(void) +{ +#ifdef WITH_THREAD + _Py_IDENTIFIER(_shutdown); + PyObject *result; + PyThreadState *tstate = PyThreadState_GET(); + PyObject *threading = PyMapping_GetItemString(tstate->interp->modules, + "threading"); + if (threading == NULL) { + /* threading not imported */ + PyErr_Clear(); + return; + } + result = _PyObject_CallMethodId(threading, &PyId__shutdown, ""); + if (result == NULL) { + PyErr_WriteUnraisable(threading); + } + else { + Py_DECREF(result); + } + Py_DECREF(threading); +#endif +} + +#define NEXITFUNCS 32 +static void (*exitfuncs[NEXITFUNCS])(void); +static int nexitfuncs = 0; + +int Py_AtExit(void (*func)(void)) +{ + if (nexitfuncs >= NEXITFUNCS) + return -1; + exitfuncs[nexitfuncs++] = func; + return 0; +} + +static void +call_ll_exitfuncs(void) +{ + while (nexitfuncs > 0) + (*exitfuncs[--nexitfuncs])(); + + fflush(stdout); + fflush(stderr); +} + +void +Py_Exit(int sts) +{ + Py_Finalize(); + + exit(sts); +} + +static void +initsigs(void) +{ +#ifdef SIGPIPE + PyOS_setsig(SIGPIPE, SIG_IGN); +#endif +#ifdef SIGXFZ + PyOS_setsig(SIGXFZ, SIG_IGN); +#endif +#ifdef SIGXFSZ + PyOS_setsig(SIGXFSZ, SIG_IGN); +#endif + PyOS_InitInterrupts(); /* May imply initsignal() */ + if (PyErr_Occurred()) { + Py_FatalError("Py_Initialize: can't import signal"); + } +} + + +/* Restore signals that the interpreter has called SIG_IGN on to SIG_DFL. + * + * All of the code in this function must only use async-signal-safe functions, + * listed at `man 7 signal` or + * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html. + */ +void +_Py_RestoreSignals(void) +{ +#ifdef SIGPIPE + PyOS_setsig(SIGPIPE, SIG_DFL); +#endif +#ifdef SIGXFZ + PyOS_setsig(SIGXFZ, SIG_DFL); +#endif +#ifdef SIGXFSZ + PyOS_setsig(SIGXFSZ, SIG_DFL); +#endif +} + + +/* + * The file descriptor fd is considered ``interactive'' if either + * a) isatty(fd) is TRUE, or + * b) the -i flag was given, and the filename associated with + * the descriptor is NULL or "" or "???". + */ +int +Py_FdIsInteractive(FILE *fp, const char *filename) +{ + if (isatty((int)fileno(fp))) + return 1; + if (!Py_InteractiveFlag) + return 0; + return (filename == NULL) || + (strcmp(filename, "") == 0) || + (strcmp(filename, "???") == 0); +} + + +/* Wrappers around sigaction() or signal(). */ + +PyOS_sighandler_t +PyOS_getsig(int sig) +{ +#ifdef HAVE_SIGACTION + struct sigaction context; + if (sigaction(sig, NULL, &context) == -1) + return SIG_ERR; + return context.sa_handler; +#else + PyOS_sighandler_t handler; +/* Special signal handling for the secure CRT in Visual Studio 2005 */ +#if defined(_MSC_VER) && _MSC_VER >= 1400 + switch (sig) { + /* Only these signals are valid */ + case SIGINT: + case SIGILL: + case SIGFPE: + case SIGSEGV: + case SIGTERM: + case SIGBREAK: + case SIGABRT: + break; + /* Don't call signal() with other values or it will assert */ + default: + return SIG_ERR; + } +#endif /* _MSC_VER && _MSC_VER >= 1400 */ + handler = signal(sig, SIG_IGN); + if (handler != SIG_ERR) + signal(sig, handler); + return handler; +#endif +} + +/* + * All of the code in this function must only use async-signal-safe functions, + * listed at `man 7 signal` or + * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html. + */ +PyOS_sighandler_t +PyOS_setsig(int sig, PyOS_sighandler_t handler) +{ +#ifdef HAVE_SIGACTION + /* Some code in Modules/signalmodule.c depends on sigaction() being + * used here if HAVE_SIGACTION is defined. Fix that if this code + * changes to invalidate that assumption. + */ + struct sigaction context, ocontext; + context.sa_handler = handler; + sigemptyset(&context.sa_mask); + context.sa_flags = 0; + if (sigaction(sig, &context, &ocontext) == -1) + return SIG_ERR; + return ocontext.sa_handler; +#else + PyOS_sighandler_t oldhandler; + oldhandler = signal(sig, handler); +#ifdef HAVE_SIGINTERRUPT + siginterrupt(sig, 1); +#endif + return oldhandler; +#endif +} + +#ifdef __cplusplus +} +#endif diff --git a/Python/pystate.c b/Python/pystate.c index 6be71de2ae0b..32a635c789ea 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -72,6 +72,7 @@ PyInterpreterState_New(void) interp->modules_by_index = NULL; interp->sysdict = NULL; interp->builtins = NULL; + interp->builtins_copy = NULL; interp->tstate_head = NULL; interp->codec_search_path = NULL; interp->codec_search_cache = NULL; @@ -115,6 +116,7 @@ PyInterpreterState_Clear(PyInterpreterState *interp) Py_CLEAR(interp->modules_by_index); Py_CLEAR(interp->sysdict); Py_CLEAR(interp->builtins); + Py_CLEAR(interp->builtins_copy); Py_CLEAR(interp->importlib); } @@ -401,7 +403,7 @@ tstate_delete_common(PyThreadState *tstate) void PyThreadState_Delete(PyThreadState *tstate) { - if (tstate == _Py_atomic_load_relaxed(&_PyThreadState_Current)) + if (tstate == (PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current)) Py_FatalError("PyThreadState_Delete: tstate is still current"); #ifdef WITH_THREAD if (autoInterpreterState && PyThread_get_key_value(autoTLSkey) == tstate) @@ -660,7 +662,7 @@ PyThreadState_IsCurrent(PyThreadState *tstate) { /* Must be the tstate for this thread */ assert(PyGILState_GetThisThreadState()==tstate); - return tstate == _Py_atomic_load_relaxed(&_PyThreadState_Current); + return tstate == (PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current); } /* Internal initialization/finalization functions called by @@ -723,18 +725,18 @@ _PyGILState_NoteThreadState(PyThreadState* tstate) The only situation where you can legitimately have more than one thread state for an OS level thread is when there are multiple - interpreters, when: + interpreters. - a) You shouldn't really be using the PyGILState_ APIs anyway, - and: + You shouldn't really be using the PyGILState_ APIs anyway (see issues + #10915 and #15751). - b) The slightly odd way PyThread_set_key_value works (see - comments by its implementation) means that the first thread - state created for that given OS level thread will "win", - which seems reasonable behaviour. + The first thread state created for that given OS level thread will + "win", which seems reasonable behaviour. */ - if (PyThread_set_key_value(autoTLSkey, (void *)tstate) < 0) - Py_FatalError("Couldn't create autoTLSkey mapping"); + if (PyThread_get_key_value(autoTLSkey) == NULL) { + if (PyThread_set_key_value(autoTLSkey, (void *)tstate) < 0) + Py_FatalError("Couldn't create autoTLSkey mapping"); + } /* PyGILState_Release must not try to delete this thread state. */ tstate->gilstate_counter = 1; @@ -771,6 +773,11 @@ PyGILState_Ensure(void) assert(autoInterpreterState); /* Py_Initialize() hasn't been called! */ tcur = (PyThreadState *)PyThread_get_key_value(autoTLSkey); if (tcur == NULL) { + /* At startup, Python has no concrete GIL. If PyGILState_Ensure() is + called from a new thread for the first time, we need the create the + GIL. */ + PyEval_InitThreads(); + /* Create a new thread state for this thread */ tcur = PyThreadState_New(autoInterpreterState); if (tcur == NULL) diff --git a/Python/pystrtod.c b/Python/pystrtod.c index b8dd919a26e7..209c9086c87b 100644 --- a/Python/pystrtod.c +++ b/Python/pystrtod.c @@ -325,7 +325,7 @@ _PyOS_ascii_strtod(const char *nptr, char **endptr) On overflow (e.g., when trying to convert '1e500' on an IEEE 754 machine), if overflow_exception is NULL then +-Py_HUGE_VAL is returned, and no Python - exception is raised. Otherwise, overflow_exception should point to a + exception is raised. Otherwise, overflow_exception should point to a Python exception, this exception will be raised, -1.0 will be returned, and *endptr will point just past the end of the converted value. diff --git a/Python/pythonrun.c b/Python/pythonrun.c index ccf82af36bad..992a5a3ed09c 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -15,6 +15,7 @@ #include "ast.h" #include "marshal.h" #include "osdefs.h" +#include #ifdef HAVE_SIGNAL_H #include @@ -25,14 +26,12 @@ #endif #ifdef HAVE_LANGINFO_H -#include #include #endif #ifdef MS_WINDOWS #undef BYTE #include "windows.h" -#define PATH_MAX MAXPATHLEN #endif _Py_IDENTIFIER(builtins); @@ -41,7 +40,6 @@ _Py_IDENTIFIER(flush); _Py_IDENTIFIER(last_traceback); _Py_IDENTIFIER(last_type); _Py_IDENTIFIER(last_value); -_Py_IDENTIFIER(name); _Py_IDENTIFIER(ps1); _Py_IDENTIFIER(ps2); _Py_IDENTIFIER(stdin); @@ -49,43 +47,13 @@ _Py_IDENTIFIER(stdout); _Py_IDENTIFIER(stderr); _Py_static_string(PyId_string, ""); -#ifdef Py_REF_DEBUG -static -void _print_total_refs(void) { - PyObject *xoptions, *value; - _Py_IDENTIFIER(showrefcount); - - xoptions = PySys_GetXOptions(); - if (xoptions == NULL) - return; - value = _PyDict_GetItemId(xoptions, &PyId_showrefcount); - if (value == Py_True) - fprintf(stderr, - "[%" PY_FORMAT_SIZE_T "d refs, " - "%" PY_FORMAT_SIZE_T "d blocks]\n", - _Py_GetRefTotal(), _Py_GetAllocatedBlocks()); -} -#endif - -#ifndef Py_REF_DEBUG -#define PRINT_TOTAL_REFS() -#else /* Py_REF_DEBUG */ -#define PRINT_TOTAL_REFS() _print_total_refs() -#endif - #ifdef __cplusplus extern "C" { #endif -extern wchar_t *Py_GetPath(void); - extern grammar _PyParser_Grammar; /* From graminit.c */ /* Forward */ -static void initmain(PyInterpreterState *interp); -static int initfsencoding(PyInterpreterState *interp); -static void initsite(void); -static int initstdio(void); static void flush_io(void); static PyObject *run_mod(mod_ty, PyObject *, PyObject *, PyObject *, PyCompilerFlags *, PyArena *); @@ -93,1192 +61,6 @@ static PyObject *run_pyc_file(FILE *, const char *, PyObject *, PyObject *, PyCompilerFlags *); static void err_input(perrdetail *); static void err_free(perrdetail *); -static void initsigs(void); -static void call_py_exitfuncs(void); -static void wait_for_thread_shutdown(void); -static void call_ll_exitfuncs(void); -extern int _PyUnicode_Init(void); -extern int _PyStructSequence_Init(void); -extern void _PyUnicode_Fini(void); -extern int _PyLong_Init(void); -extern void PyLong_Fini(void); -extern int _PyFaulthandler_Init(void); -extern void _PyFaulthandler_Fini(void); -extern void _PyHash_Fini(void); -extern int _PyTraceMalloc_Init(void); -extern int _PyTraceMalloc_Fini(void); - -#ifdef WITH_THREAD -extern void _PyGILState_Init(PyInterpreterState *, PyThreadState *); -extern void _PyGILState_Fini(void); -#endif /* WITH_THREAD */ - -int Py_DebugFlag; /* Needed by parser.c */ -int Py_VerboseFlag; /* Needed by import.c */ -int Py_QuietFlag; /* Needed by sysmodule.c */ -int Py_InteractiveFlag; /* Needed by Py_FdIsInteractive() below */ -int Py_InspectFlag; /* Needed to determine whether to exit at SystemExit */ -int Py_NoSiteFlag; /* Suppress 'import site' */ -int Py_BytesWarningFlag; /* Warn on str(bytes) and str(buffer) */ -int Py_DontWriteBytecodeFlag; /* Suppress writing bytecode files (*.py[co]) */ -int Py_UseClassExceptionsFlag = 1; /* Needed by bltinmodule.c: deprecated */ -int Py_FrozenFlag; /* Needed by getpath.c */ -int Py_IgnoreEnvironmentFlag; /* e.g. PYTHONPATH, PYTHONHOME */ -int Py_NoUserSiteDirectory = 0; /* for -s and site.py */ -int Py_UnbufferedStdioFlag = 0; /* Unbuffered binary std{in,out,err} */ -int Py_HashRandomizationFlag = 0; /* for -R and PYTHONHASHSEED */ -int Py_IsolatedFlag = 0; /* for -I, isolate from user's env */ - -PyThreadState *_Py_Finalizing = NULL; - -/* Hack to force loading of object files */ -int (*_PyOS_mystrnicmp_hack)(const char *, const char *, Py_ssize_t) = \ - PyOS_mystrnicmp; /* Python/pystrcmp.o */ - -/* PyModule_GetWarningsModule is no longer necessary as of 2.6 -since _warnings is builtin. This API should not be used. */ -PyObject * -PyModule_GetWarningsModule(void) -{ - return PyImport_ImportModule("warnings"); -} - -static int initialized = 0; - -/* API to access the initialized flag -- useful for esoteric use */ - -int -Py_IsInitialized(void) -{ - return initialized; -} - -/* Helper to allow an embedding application to override the normal - * mechanism that attempts to figure out an appropriate IO encoding - */ - -static char *_Py_StandardStreamEncoding = NULL; -static char *_Py_StandardStreamErrors = NULL; - -int -Py_SetStandardStreamEncoding(const char *encoding, const char *errors) -{ - if (Py_IsInitialized()) { - /* This is too late to have any effect */ - return -1; - } - /* Can't call PyErr_NoMemory() on errors, as Python hasn't been - * initialised yet. - * - * However, the raw memory allocators are initialised appropriately - * as C static variables, so _PyMem_RawStrdup is OK even though - * Py_Initialize hasn't been called yet. - */ - if (encoding) { - _Py_StandardStreamEncoding = _PyMem_RawStrdup(encoding); - if (!_Py_StandardStreamEncoding) { - return -2; - } - } - if (errors) { - _Py_StandardStreamErrors = _PyMem_RawStrdup(errors); - if (!_Py_StandardStreamErrors) { - if (_Py_StandardStreamEncoding) { - PyMem_RawFree(_Py_StandardStreamEncoding); - } - return -3; - } - } - return 0; -} - -/* Global initializations. Can be undone by Py_Finalize(). Don't - call this twice without an intervening Py_Finalize() call. When - initializations fail, a fatal error is issued and the function does - not return. On return, the first thread and interpreter state have - been created. - - Locking: you must hold the interpreter lock while calling this. - (If the lock has not yet been initialized, that's equivalent to - having the lock, but you cannot use multiple threads.) - -*/ - -static int -add_flag(int flag, const char *envs) -{ - int env = atoi(envs); - if (flag < env) - flag = env; - if (flag < 1) - flag = 1; - return flag; -} - -static char* -get_codec_name(const char *encoding) -{ - char *name_utf8, *name_str; - PyObject *codec, *name = NULL; - - codec = _PyCodec_Lookup(encoding); - if (!codec) - goto error; - - name = _PyObject_GetAttrId(codec, &PyId_name); - Py_CLEAR(codec); - if (!name) - goto error; - - name_utf8 = _PyUnicode_AsString(name); - if (name_utf8 == NULL) - goto error; - name_str = _PyMem_RawStrdup(name_utf8); - Py_DECREF(name); - if (name_str == NULL) { - PyErr_NoMemory(); - return NULL; - } - return name_str; - -error: - Py_XDECREF(codec); - Py_XDECREF(name); - return NULL; -} - -static char* -get_locale_encoding(void) -{ -#ifdef MS_WINDOWS - char codepage[100]; - PyOS_snprintf(codepage, sizeof(codepage), "cp%d", GetACP()); - return get_codec_name(codepage); -#elif defined(HAVE_LANGINFO_H) && defined(CODESET) - char* codeset = nl_langinfo(CODESET); - if (!codeset || codeset[0] == '\0') { - PyErr_SetString(PyExc_ValueError, "CODESET is not set or empty"); - return NULL; - } - return get_codec_name(codeset); -#else - PyErr_SetNone(PyExc_NotImplementedError); - return NULL; -#endif -} - -static void -import_init(PyInterpreterState *interp, PyObject *sysmod) -{ - PyObject *importlib; - PyObject *impmod; - PyObject *sys_modules; - PyObject *value; - - /* Import _importlib through its frozen version, _frozen_importlib. */ - if (PyImport_ImportFrozenModule("_frozen_importlib") <= 0) { - Py_FatalError("Py_Initialize: can't import _frozen_importlib"); - } - else if (Py_VerboseFlag) { - PySys_FormatStderr("import _frozen_importlib # frozen\n"); - } - importlib = PyImport_AddModule("_frozen_importlib"); - if (importlib == NULL) { - Py_FatalError("Py_Initialize: couldn't get _frozen_importlib from " - "sys.modules"); - } - interp->importlib = importlib; - Py_INCREF(interp->importlib); - - /* Install _importlib as __import__ */ - impmod = PyInit_imp(); - if (impmod == NULL) { - Py_FatalError("Py_Initialize: can't import imp"); - } - else if (Py_VerboseFlag) { - PySys_FormatStderr("import imp # builtin\n"); - } - sys_modules = PyImport_GetModuleDict(); - if (Py_VerboseFlag) { - PySys_FormatStderr("import sys # builtin\n"); - } - if (PyDict_SetItemString(sys_modules, "_imp", impmod) < 0) { - Py_FatalError("Py_Initialize: can't save _imp to sys.modules"); - } - - value = PyObject_CallMethod(importlib, "_install", "OO", sysmod, impmod); - if (value == NULL) { - PyErr_Print(); - Py_FatalError("Py_Initialize: importlib install failed"); - } - Py_DECREF(value); - Py_DECREF(impmod); - - _PyImportZip_Init(); -} - - -void -_Py_InitializeEx_Private(int install_sigs, int install_importlib) -{ - PyInterpreterState *interp; - PyThreadState *tstate; - PyObject *bimod, *sysmod, *pstderr; - char *p; - extern void _Py_ReadyTypes(void); - - if (initialized) - return; - initialized = 1; - _Py_Finalizing = NULL; - -#if defined(HAVE_LANGINFO_H) && defined(HAVE_SETLOCALE) - /* Set up the LC_CTYPE locale, so we can obtain - the locale's charset without having to switch - locales. */ - setlocale(LC_CTYPE, ""); -#endif - - if ((p = Py_GETENV("PYTHONDEBUG")) && *p != '\0') - Py_DebugFlag = add_flag(Py_DebugFlag, p); - if ((p = Py_GETENV("PYTHONVERBOSE")) && *p != '\0') - Py_VerboseFlag = add_flag(Py_VerboseFlag, p); - if ((p = Py_GETENV("PYTHONOPTIMIZE")) && *p != '\0') - Py_OptimizeFlag = add_flag(Py_OptimizeFlag, p); - if ((p = Py_GETENV("PYTHONDONTWRITEBYTECODE")) && *p != '\0') - Py_DontWriteBytecodeFlag = add_flag(Py_DontWriteBytecodeFlag, p); - /* The variable is only tested for existence here; _PyRandom_Init will - check its value further. */ - if ((p = Py_GETENV("PYTHONHASHSEED")) && *p != '\0') - Py_HashRandomizationFlag = add_flag(Py_HashRandomizationFlag, p); - - _PyRandom_Init(); - - interp = PyInterpreterState_New(); - if (interp == NULL) - Py_FatalError("Py_Initialize: can't make first interpreter"); - - tstate = PyThreadState_New(interp); - if (tstate == NULL) - Py_FatalError("Py_Initialize: can't make first thread"); - (void) PyThreadState_Swap(tstate); - -#ifdef WITH_THREAD - /* We can't call _PyEval_FiniThreads() in Py_Finalize because - destroying the GIL might fail when it is being referenced from - another running thread (see issue #9901). - Instead we destroy the previously created GIL here, which ensures - that we can call Py_Initialize / Py_Finalize multiple times. */ - _PyEval_FiniThreads(); - - /* Auto-thread-state API */ - _PyGILState_Init(interp, tstate); -#endif /* WITH_THREAD */ - - _Py_ReadyTypes(); - - if (!_PyFrame_Init()) - Py_FatalError("Py_Initialize: can't init frames"); - - if (!_PyLong_Init()) - Py_FatalError("Py_Initialize: can't init longs"); - - if (!PyByteArray_Init()) - Py_FatalError("Py_Initialize: can't init bytearray"); - - if (!_PyFloat_Init()) - Py_FatalError("Py_Initialize: can't init float"); - - interp->modules = PyDict_New(); - if (interp->modules == NULL) - Py_FatalError("Py_Initialize: can't make modules dictionary"); - - /* Init Unicode implementation; relies on the codec registry */ - if (_PyUnicode_Init() < 0) - Py_FatalError("Py_Initialize: can't initialize unicode"); - if (_PyStructSequence_Init() < 0) - Py_FatalError("Py_Initialize: can't initialize structseq"); - - bimod = _PyBuiltin_Init(); - if (bimod == NULL) - Py_FatalError("Py_Initialize: can't initialize builtins modules"); - _PyImport_FixupBuiltin(bimod, "builtins"); - interp->builtins = PyModule_GetDict(bimod); - if (interp->builtins == NULL) - Py_FatalError("Py_Initialize: can't initialize builtins dict"); - Py_INCREF(interp->builtins); - - /* initialize builtin exceptions */ - _PyExc_Init(bimod); - - sysmod = _PySys_Init(); - if (sysmod == NULL) - Py_FatalError("Py_Initialize: can't initialize sys"); - interp->sysdict = PyModule_GetDict(sysmod); - if (interp->sysdict == NULL) - Py_FatalError("Py_Initialize: can't initialize sys dict"); - Py_INCREF(interp->sysdict); - _PyImport_FixupBuiltin(sysmod, "sys"); - PySys_SetPath(Py_GetPath()); - PyDict_SetItemString(interp->sysdict, "modules", - interp->modules); - - /* Set up a preliminary stderr printer until we have enough - infrastructure for the io module in place. */ - pstderr = PyFile_NewStdPrinter(fileno(stderr)); - if (pstderr == NULL) - Py_FatalError("Py_Initialize: can't set preliminary stderr"); - _PySys_SetObjectId(&PyId_stderr, pstderr); - PySys_SetObject("__stderr__", pstderr); - Py_DECREF(pstderr); - - _PyImport_Init(); - - _PyImportHooks_Init(); - - /* Initialize _warnings. */ - _PyWarnings_Init(); - - if (!install_importlib) - return; - - import_init(interp, sysmod); - - /* initialize the faulthandler module */ - if (_PyFaulthandler_Init()) - Py_FatalError("Py_Initialize: can't initialize faulthandler"); - - _PyTime_Init(); - - if (initfsencoding(interp) < 0) - Py_FatalError("Py_Initialize: unable to load the file system codec"); - - if (install_sigs) - initsigs(); /* Signal handling stuff, including initintr() */ - - if (_PyTraceMalloc_Init() < 0) - Py_FatalError("Py_Initialize: can't initialize tracemalloc"); - - initmain(interp); /* Module __main__ */ - if (initstdio() < 0) - Py_FatalError( - "Py_Initialize: can't initialize sys standard streams"); - - /* Initialize warnings. */ - if (PySys_HasWarnOptions()) { - PyObject *warnings_module = PyImport_ImportModule("warnings"); - if (warnings_module == NULL) { - fprintf(stderr, "'import warnings' failed; traceback:\n"); - PyErr_Print(); - } - Py_XDECREF(warnings_module); - } - - if (!Py_NoSiteFlag) - initsite(); /* Module site */ -} - -void -Py_InitializeEx(int install_sigs) -{ - _Py_InitializeEx_Private(install_sigs, 1); -} - -void -Py_Initialize(void) -{ - Py_InitializeEx(1); -} - - -#ifdef COUNT_ALLOCS -extern void dump_counts(FILE*); -#endif - -/* Flush stdout and stderr */ - -static int -file_is_closed(PyObject *fobj) -{ - int r; - PyObject *tmp = PyObject_GetAttrString(fobj, "closed"); - if (tmp == NULL) { - PyErr_Clear(); - return 0; - } - r = PyObject_IsTrue(tmp); - Py_DECREF(tmp); - if (r < 0) - PyErr_Clear(); - return r > 0; -} - -static void -flush_std_files(void) -{ - PyObject *fout = _PySys_GetObjectId(&PyId_stdout); - PyObject *ferr = _PySys_GetObjectId(&PyId_stderr); - PyObject *tmp; - - if (fout != NULL && fout != Py_None && !file_is_closed(fout)) { - tmp = _PyObject_CallMethodId(fout, &PyId_flush, ""); - if (tmp == NULL) - PyErr_WriteUnraisable(fout); - else - Py_DECREF(tmp); - } - - if (ferr != NULL && ferr != Py_None && !file_is_closed(ferr)) { - tmp = _PyObject_CallMethodId(ferr, &PyId_flush, ""); - if (tmp == NULL) - PyErr_Clear(); - else - Py_DECREF(tmp); - } -} - -/* Undo the effect of Py_Initialize(). - - Beware: if multiple interpreter and/or thread states exist, these - are not wiped out; only the current thread and interpreter state - are deleted. But since everything else is deleted, those other - interpreter and thread states should no longer be used. - - (XXX We should do better, e.g. wipe out all interpreters and - threads.) - - Locking: as above. - -*/ - -void -Py_Finalize(void) -{ - PyInterpreterState *interp; - PyThreadState *tstate; - - if (!initialized) - return; - - wait_for_thread_shutdown(); - - /* The interpreter is still entirely intact at this point, and the - * exit funcs may be relying on that. In particular, if some thread - * or exit func is still waiting to do an import, the import machinery - * expects Py_IsInitialized() to return true. So don't say the - * interpreter is uninitialized until after the exit funcs have run. - * Note that Threading.py uses an exit func to do a join on all the - * threads created thru it, so this also protects pending imports in - * the threads created via Threading. - */ - call_py_exitfuncs(); - - /* Get current thread state and interpreter pointer */ - tstate = PyThreadState_GET(); - interp = tstate->interp; - - /* Remaining threads (e.g. daemon threads) will automatically exit - after taking the GIL (in PyEval_RestoreThread()). */ - _Py_Finalizing = tstate; - initialized = 0; - - /* Destroy the state of all threads except of the current thread: in - practice, only daemon threads should still be alive. Clear frames of - other threads to call objects destructor. Destructors will be called in - the current Python thread. Since _Py_Finalizing has been set, no other - Python threads can lock the GIL at this point (if they try, they will - exit immediately). */ - _PyThreadState_DeleteExcept(tstate); - - /* Collect garbage. This may call finalizers; it's nice to call these - * before all modules are destroyed. - * XXX If a __del__ or weakref callback is triggered here, and tries to - * XXX import a module, bad things can happen, because Python no - * XXX longer believes it's initialized. - * XXX Fatal Python error: Interpreter not initialized (version mismatch?) - * XXX is easy to provoke that way. I've also seen, e.g., - * XXX Exception exceptions.ImportError: 'No module named sha' - * XXX in ignored - * XXX but I'm unclear on exactly how that one happens. In any case, - * XXX I haven't seen a real-life report of either of these. - */ - PyGC_Collect(); - -#ifdef COUNT_ALLOCS - /* With COUNT_ALLOCS, it helps to run GC multiple times: - each collection might release some types from the type - list, so they become garbage. */ - while (PyGC_Collect() > 0) - /* nothing */; -#endif - - /* Flush stdout+stderr */ - flush_std_files(); - - /* Disable signal handling */ - PyOS_FiniInterrupts(); - - /* Destroy all modules */ - PyImport_Cleanup(); - - /* Flush stdout+stderr (again, in case more was printed) */ - flush_std_files(); - - /* Collect final garbage. This disposes of cycles created by - * class definitions, for example. - * XXX This is disabled because it caused too many problems. If - * XXX a __del__ or weakref callback triggers here, Python code has - * XXX a hard time running, because even the sys module has been - * XXX cleared out (sys.stdout is gone, sys.excepthook is gone, etc). - * XXX One symptom is a sequence of information-free messages - * XXX coming from threads (if a __del__ or callback is invoked, - * XXX other threads can execute too, and any exception they encounter - * XXX triggers a comedy of errors as subsystem after subsystem - * XXX fails to find what it *expects* to find in sys to help report - * XXX the exception and consequent unexpected failures). I've also - * XXX seen segfaults then, after adding print statements to the - * XXX Python code getting called. - */ -#if 0 - PyGC_Collect(); -#endif - - /* Disable tracemalloc after all Python objects have been destroyed, - so it is possible to use tracemalloc in objects destructor. */ - _PyTraceMalloc_Fini(); - - /* Destroy the database used by _PyImport_{Fixup,Find}Extension */ - _PyImport_Fini(); - - /* Cleanup typeobject.c's internal caches. */ - _PyType_Fini(); - - /* unload faulthandler module */ - _PyFaulthandler_Fini(); - - /* Debugging stuff */ -#ifdef COUNT_ALLOCS - dump_counts(stdout); -#endif - /* dump hash stats */ - _PyHash_Fini(); - - PRINT_TOTAL_REFS(); - -#ifdef Py_TRACE_REFS - /* Display all objects still alive -- this can invoke arbitrary - * __repr__ overrides, so requires a mostly-intact interpreter. - * Alas, a lot of stuff may still be alive now that will be cleaned - * up later. - */ - if (Py_GETENV("PYTHONDUMPREFS")) - _Py_PrintReferences(stderr); -#endif /* Py_TRACE_REFS */ - - /* Clear interpreter state and all thread states. */ - PyInterpreterState_Clear(interp); - - /* Now we decref the exception classes. After this point nothing - can raise an exception. That's okay, because each Fini() method - below has been checked to make sure no exceptions are ever - raised. - */ - - _PyExc_Fini(); - - /* Sundry finalizers */ - PyMethod_Fini(); - PyFrame_Fini(); - PyCFunction_Fini(); - PyTuple_Fini(); - PyList_Fini(); - PySet_Fini(); - PyBytes_Fini(); - PyByteArray_Fini(); - PyLong_Fini(); - PyFloat_Fini(); - PyDict_Fini(); - PySlice_Fini(); - _PyGC_Fini(); - _PyRandom_Fini(); - - /* Cleanup Unicode implementation */ - _PyUnicode_Fini(); - - /* reset file system default encoding */ - if (!Py_HasFileSystemDefaultEncoding && Py_FileSystemDefaultEncoding) { - PyMem_RawFree((char*)Py_FileSystemDefaultEncoding); - Py_FileSystemDefaultEncoding = NULL; - } - - /* XXX Still allocated: - - various static ad-hoc pointers to interned strings - - int and float free list blocks - - whatever various modules and libraries allocate - */ - - PyGrammar_RemoveAccelerators(&_PyParser_Grammar); - - /* Cleanup auto-thread-state */ -#ifdef WITH_THREAD - _PyGILState_Fini(); -#endif /* WITH_THREAD */ - - /* Delete current thread. After this, many C API calls become crashy. */ - PyThreadState_Swap(NULL); - PyInterpreterState_Delete(interp); - -#ifdef Py_TRACE_REFS - /* Display addresses (& refcnts) of all objects still alive. - * An address can be used to find the repr of the object, printed - * above by _Py_PrintReferences. - */ - if (Py_GETENV("PYTHONDUMPREFS")) - _Py_PrintReferenceAddresses(stderr); -#endif /* Py_TRACE_REFS */ -#ifdef PYMALLOC_DEBUG - if (Py_GETENV("PYTHONMALLOCSTATS")) - _PyObject_DebugMallocStats(stderr); -#endif - - call_ll_exitfuncs(); -} - -/* Create and initialize a new interpreter and thread, and return the - new thread. This requires that Py_Initialize() has been called - first. - - Unsuccessful initialization yields a NULL pointer. Note that *no* - exception information is available even in this case -- the - exception information is held in the thread, and there is no - thread. - - Locking: as above. - -*/ - -PyThreadState * -Py_NewInterpreter(void) -{ - PyInterpreterState *interp; - PyThreadState *tstate, *save_tstate; - PyObject *bimod, *sysmod; - - if (!initialized) - Py_FatalError("Py_NewInterpreter: call Py_Initialize first"); - - interp = PyInterpreterState_New(); - if (interp == NULL) - return NULL; - - tstate = PyThreadState_New(interp); - if (tstate == NULL) { - PyInterpreterState_Delete(interp); - return NULL; - } - - save_tstate = PyThreadState_Swap(tstate); - - /* XXX The following is lax in error checking */ - - interp->modules = PyDict_New(); - - bimod = _PyImport_FindBuiltin("builtins"); - if (bimod != NULL) { - interp->builtins = PyModule_GetDict(bimod); - if (interp->builtins == NULL) - goto handle_error; - Py_INCREF(interp->builtins); - } - - /* initialize builtin exceptions */ - _PyExc_Init(bimod); - - sysmod = _PyImport_FindBuiltin("sys"); - if (bimod != NULL && sysmod != NULL) { - PyObject *pstderr; - - interp->sysdict = PyModule_GetDict(sysmod); - if (interp->sysdict == NULL) - goto handle_error; - Py_INCREF(interp->sysdict); - PySys_SetPath(Py_GetPath()); - PyDict_SetItemString(interp->sysdict, "modules", - interp->modules); - /* Set up a preliminary stderr printer until we have enough - infrastructure for the io module in place. */ - pstderr = PyFile_NewStdPrinter(fileno(stderr)); - if (pstderr == NULL) - Py_FatalError("Py_Initialize: can't set preliminary stderr"); - _PySys_SetObjectId(&PyId_stderr, pstderr); - PySys_SetObject("__stderr__", pstderr); - Py_DECREF(pstderr); - - _PyImportHooks_Init(); - - import_init(interp, sysmod); - - if (initfsencoding(interp) < 0) - goto handle_error; - - if (initstdio() < 0) - Py_FatalError( - "Py_Initialize: can't initialize sys standard streams"); - initmain(interp); - if (!Py_NoSiteFlag) - initsite(); - } - - if (!PyErr_Occurred()) - return tstate; - -handle_error: - /* Oops, it didn't work. Undo it all. */ - - PyErr_PrintEx(0); - PyThreadState_Clear(tstate); - PyThreadState_Swap(save_tstate); - PyThreadState_Delete(tstate); - PyInterpreterState_Delete(interp); - - return NULL; -} - -/* Delete an interpreter and its last thread. This requires that the - given thread state is current, that the thread has no remaining - frames, and that it is its interpreter's only remaining thread. - It is a fatal error to violate these constraints. - - (Py_Finalize() doesn't have these constraints -- it zaps - everything, regardless.) - - Locking: as above. - -*/ - -void -Py_EndInterpreter(PyThreadState *tstate) -{ - PyInterpreterState *interp = tstate->interp; - - if (tstate != PyThreadState_GET()) - Py_FatalError("Py_EndInterpreter: thread is not current"); - if (tstate->frame != NULL) - Py_FatalError("Py_EndInterpreter: thread still has a frame"); - - wait_for_thread_shutdown(); - - if (tstate != interp->tstate_head || tstate->next != NULL) - Py_FatalError("Py_EndInterpreter: not the last thread"); - - PyImport_Cleanup(); - PyInterpreterState_Clear(interp); - PyThreadState_Swap(NULL); - PyInterpreterState_Delete(interp); -} - -#ifdef MS_WINDOWS -static wchar_t *progname = L"python"; -#else -static wchar_t *progname = L"python3"; -#endif - -void -Py_SetProgramName(wchar_t *pn) -{ - if (pn && *pn) - progname = pn; -} - -wchar_t * -Py_GetProgramName(void) -{ - return progname; -} - -static wchar_t *default_home = NULL; -static wchar_t env_home[MAXPATHLEN+1]; - -void -Py_SetPythonHome(wchar_t *home) -{ - default_home = home; -} - -wchar_t * -Py_GetPythonHome(void) -{ - wchar_t *home = default_home; - if (home == NULL && !Py_IgnoreEnvironmentFlag) { - char* chome = Py_GETENV("PYTHONHOME"); - if (chome) { - size_t size = Py_ARRAY_LENGTH(env_home); - size_t r = mbstowcs(env_home, chome, size); - if (r != (size_t)-1 && r < size) - home = env_home; - } - - } - return home; -} - -/* Create __main__ module */ - -static void -initmain(PyInterpreterState *interp) -{ - PyObject *m, *d, *loader; - m = PyImport_AddModule("__main__"); - if (m == NULL) - Py_FatalError("can't create __main__ module"); - d = PyModule_GetDict(m); - if (PyDict_GetItemString(d, "__builtins__") == NULL) { - PyObject *bimod = PyImport_ImportModule("builtins"); - if (bimod == NULL) { - Py_FatalError("Failed to retrieve builtins module"); - } - if (PyDict_SetItemString(d, "__builtins__", bimod) < 0) { - Py_FatalError("Failed to initialize __main__.__builtins__"); - } - Py_DECREF(bimod); - } - /* Main is a little special - imp.is_builtin("__main__") will return - * False, but BuiltinImporter is still the most appropriate initial - * setting for its __loader__ attribute. A more suitable value will - * be set if __main__ gets further initialized later in the startup - * process. - */ - loader = PyDict_GetItemString(d, "__loader__"); - if (loader == NULL || loader == Py_None) { - PyObject *loader = PyObject_GetAttrString(interp->importlib, - "BuiltinImporter"); - if (loader == NULL) { - Py_FatalError("Failed to retrieve BuiltinImporter"); - } - if (PyDict_SetItemString(d, "__loader__", loader) < 0) { - Py_FatalError("Failed to initialize __main__.__loader__"); - } - Py_DECREF(loader); - } -} - -static int -initfsencoding(PyInterpreterState *interp) -{ - PyObject *codec; - - if (Py_FileSystemDefaultEncoding == NULL) - { - Py_FileSystemDefaultEncoding = get_locale_encoding(); - if (Py_FileSystemDefaultEncoding == NULL) - Py_FatalError("Py_Initialize: Unable to get the locale encoding"); - - Py_HasFileSystemDefaultEncoding = 0; - interp->fscodec_initialized = 1; - return 0; - } - - /* the encoding is mbcs, utf-8 or ascii */ - codec = _PyCodec_Lookup(Py_FileSystemDefaultEncoding); - if (!codec) { - /* Such error can only occurs in critical situations: no more - * memory, import a module of the standard library failed, - * etc. */ - return -1; - } - Py_DECREF(codec); - interp->fscodec_initialized = 1; - return 0; -} - -/* Import the site module (not into __main__ though) */ - -static void -initsite(void) -{ - PyObject *m; - m = PyImport_ImportModule("site"); - if (m == NULL) { - fprintf(stderr, "Failed to import the site module\n"); - PyErr_Print(); - Py_Finalize(); - exit(1); - } - else { - Py_DECREF(m); - } -} - -static PyObject* -create_stdio(PyObject* io, - int fd, int write_mode, char* name, - char* encoding, char* errors) -{ - PyObject *buf = NULL, *stream = NULL, *text = NULL, *raw = NULL, *res; - const char* mode; - const char* newline; - PyObject *line_buffering; - int buffering, isatty; - _Py_IDENTIFIER(open); - _Py_IDENTIFIER(isatty); - _Py_IDENTIFIER(TextIOWrapper); - _Py_IDENTIFIER(mode); - - /* stdin is always opened in buffered mode, first because it shouldn't - make a difference in common use cases, second because TextIOWrapper - depends on the presence of a read1() method which only exists on - buffered streams. - */ - if (Py_UnbufferedStdioFlag && write_mode) - buffering = 0; - else - buffering = -1; - if (write_mode) - mode = "wb"; - else - mode = "rb"; - buf = _PyObject_CallMethodId(io, &PyId_open, "isiOOOi", - fd, mode, buffering, - Py_None, Py_None, Py_None, 0); - if (buf == NULL) - goto error; - - if (buffering) { - _Py_IDENTIFIER(raw); - raw = _PyObject_GetAttrId(buf, &PyId_raw); - if (raw == NULL) - goto error; - } - else { - raw = buf; - Py_INCREF(raw); - } - - text = PyUnicode_FromString(name); - if (text == NULL || _PyObject_SetAttrId(raw, &PyId_name, text) < 0) - goto error; - res = _PyObject_CallMethodId(raw, &PyId_isatty, ""); - if (res == NULL) - goto error; - isatty = PyObject_IsTrue(res); - Py_DECREF(res); - if (isatty == -1) - goto error; - if (isatty || Py_UnbufferedStdioFlag) - line_buffering = Py_True; - else - line_buffering = Py_False; - - Py_CLEAR(raw); - Py_CLEAR(text); - -#ifdef MS_WINDOWS - /* sys.stdin: enable universal newline mode, translate "\r\n" and "\r" - newlines to "\n". - sys.stdout and sys.stderr: translate "\n" to "\r\n". */ - newline = NULL; -#else - /* sys.stdin: split lines at "\n". - sys.stdout and sys.stderr: don't translate newlines (use "\n"). */ - newline = "\n"; -#endif - - stream = _PyObject_CallMethodId(io, &PyId_TextIOWrapper, "OsssO", - buf, encoding, errors, - newline, line_buffering); - Py_CLEAR(buf); - if (stream == NULL) - goto error; - - if (write_mode) - mode = "w"; - else - mode = "r"; - text = PyUnicode_FromString(mode); - if (!text || _PyObject_SetAttrId(stream, &PyId_mode, text) < 0) - goto error; - Py_CLEAR(text); - return stream; - -error: - Py_XDECREF(buf); - Py_XDECREF(stream); - Py_XDECREF(text); - Py_XDECREF(raw); - return NULL; -} - -static int -is_valid_fd(int fd) -{ - int dummy_fd; - if (fd < 0 || !_PyVerify_fd(fd)) - return 0; - dummy_fd = dup(fd); - if (dummy_fd < 0) - return 0; - close(dummy_fd); - return 1; -} - -/* Initialize sys.stdin, stdout, stderr and builtins.open */ -static int -initstdio(void) -{ - PyObject *iomod = NULL, *wrapper; - PyObject *bimod = NULL; - PyObject *m; - PyObject *std = NULL; - int status = 0, fd; - PyObject * encoding_attr; - char *pythonioencoding = NULL, *encoding, *errors; - - /* Hack to avoid a nasty recursion issue when Python is invoked - in verbose mode: pre-import the Latin-1 and UTF-8 codecs */ - if ((m = PyImport_ImportModule("encodings.utf_8")) == NULL) { - goto error; - } - Py_DECREF(m); - - if (!(m = PyImport_ImportModule("encodings.latin_1"))) { - goto error; - } - Py_DECREF(m); - - if (!(bimod = PyImport_ImportModule("builtins"))) { - goto error; - } - - if (!(iomod = PyImport_ImportModule("io"))) { - goto error; - } - if (!(wrapper = PyObject_GetAttrString(iomod, "OpenWrapper"))) { - goto error; - } - - /* Set builtins.open */ - if (PyObject_SetAttrString(bimod, "open", wrapper) == -1) { - Py_DECREF(wrapper); - goto error; - } - Py_DECREF(wrapper); - - encoding = _Py_StandardStreamEncoding; - errors = _Py_StandardStreamErrors; - if (!encoding || !errors) { - pythonioencoding = Py_GETENV("PYTHONIOENCODING"); - if (pythonioencoding) { - char *err; - pythonioencoding = _PyMem_Strdup(pythonioencoding); - if (pythonioencoding == NULL) { - PyErr_NoMemory(); - goto error; - } - err = strchr(pythonioencoding, ':'); - if (err) { - *err = '\0'; - err++; - if (*err && !errors) { - errors = err; - } - } - if (*pythonioencoding && !encoding) { - encoding = pythonioencoding; - } - } - } - - /* Set sys.stdin */ - fd = fileno(stdin); - /* Under some conditions stdin, stdout and stderr may not be connected - * and fileno() may point to an invalid file descriptor. For example - * GUI apps don't have valid standard streams by default. - */ - if (!is_valid_fd(fd)) { - std = Py_None; - Py_INCREF(std); - } - else { - std = create_stdio(iomod, fd, 0, "", encoding, errors); - if (std == NULL) - goto error; - } /* if (fd < 0) */ - PySys_SetObject("__stdin__", std); - _PySys_SetObjectId(&PyId_stdin, std); - Py_DECREF(std); - - /* Set sys.stdout */ - fd = fileno(stdout); - if (!is_valid_fd(fd)) { - std = Py_None; - Py_INCREF(std); - } - else { - std = create_stdio(iomod, fd, 1, "", encoding, errors); - if (std == NULL) - goto error; - } /* if (fd < 0) */ - PySys_SetObject("__stdout__", std); - _PySys_SetObjectId(&PyId_stdout, std); - Py_DECREF(std); - -#if 1 /* Disable this if you have trouble debugging bootstrap stuff */ - /* Set sys.stderr, replaces the preliminary stderr */ - fd = fileno(stderr); - if (!is_valid_fd(fd)) { - std = Py_None; - Py_INCREF(std); - } - else { - std = create_stdio(iomod, fd, 1, "", encoding, "backslashreplace"); - if (std == NULL) - goto error; - } /* if (fd < 0) */ - - /* Same as hack above, pre-import stderr's codec to avoid recursion - when import.c tries to write to stderr in verbose mode. */ - encoding_attr = PyObject_GetAttrString(std, "encoding"); - if (encoding_attr != NULL) { - const char * std_encoding; - std_encoding = _PyUnicode_AsString(encoding_attr); - if (std_encoding != NULL) { - PyObject *codec_info = _PyCodec_Lookup(std_encoding); - Py_XDECREF(codec_info); - } - Py_DECREF(encoding_attr); - } - PyErr_Clear(); /* Not a fatal error if codec isn't available */ - - if (PySys_SetObject("__stderr__", std) < 0) { - Py_DECREF(std); - goto error; - } - if (_PySys_SetObjectId(&PyId_stderr, std) < 0) { - Py_DECREF(std); - goto error; - } - Py_DECREF(std); -#endif - - if (0) { - error: - status = -1; - } - - /* We won't need them anymore. */ - if (_Py_StandardStreamEncoding) { - PyMem_RawFree(_Py_StandardStreamEncoding); - _Py_StandardStreamEncoding = NULL; - } - if (_Py_StandardStreamErrors) { - PyMem_RawFree(_Py_StandardStreamErrors); - _Py_StandardStreamErrors = NULL; - } - PyMem_Free(pythonioencoding); - Py_XDECREF(bimod); - Py_XDECREF(iomod); - return status; -} /* Parse input from a file and execute it */ @@ -1328,7 +110,7 @@ PyRun_InteractiveLoopFlags(FILE *fp, const char *filename_str, PyCompilerFlags * err = -1; for (;;) { ret = PyRun_InteractiveOneObject(fp, filename, flags); - PRINT_TOTAL_REFS(); + _PY_DEBUG_PRINT_TOTAL_REFS(); if (ret == E_EOF) { err = 0; break; @@ -1450,12 +232,13 @@ PyRun_InteractiveOneObject(FILE *fp, PyObject *filename, PyCompilerFlags *flags) d = PyModule_GetDict(m); v = run_mod(mod, filename, d, d, flags, arena); PyArena_Free(arena); - flush_io(); if (v == NULL) { PyErr_Print(); + flush_io(); return -1; } Py_DECREF(v); + flush_io(); return 0; } @@ -1734,7 +517,7 @@ print_error_text(PyObject *f, int offset, PyObject *text_obj) return; if (offset >= 0) { - if (offset > 0 && offset == strlen(text) && text[offset - 1] == '\n') + if (offset > 0 && (size_t)offset == strlen(text) && text[offset - 1] == '\n') offset--; for (;;) { nl = strchr(text, '\n'); @@ -1792,6 +575,11 @@ handle_system_exit(void) exitcode = (int)PyLong_AsLong(value); else { PyObject *sys_stderr = _PySys_GetObjectId(&PyId_stderr); + /* We clear the exception here to avoid triggering the assertion + * in PyObject_Str that ensures it won't silently lose exception + * details. + */ + PyErr_Clear(); if (sys_stderr != NULL && sys_stderr != Py_None) { PyFile_WriteObject(value, sys_stderr, Py_PRINT_RAW); } else { @@ -1888,9 +676,11 @@ print_exception(PyObject *f, PyObject *value) _Py_IDENTIFIER(print_file_and_line); if (!PyExceptionInstance_Check(value)) { - PyFile_WriteString("TypeError: print_exception(): Exception expected for value, ", f); - PyFile_WriteString(Py_TYPE(value)->tp_name, f); - PyFile_WriteString(" found\n", f); + err = PyFile_WriteString("TypeError: print_exception(): Exception expected for value, ", f); + err += PyFile_WriteString(Py_TYPE(value)->tp_name, f); + err += PyFile_WriteString(" found\n", f); + if (err) + PyErr_Clear(); return; } @@ -2468,6 +1258,7 @@ err_input(perrdetail *err) PyObject *v, *w, *errtype, *errtext; PyObject *msg_obj = NULL; char *msg = NULL; + int offset = err->offset; errtype = PyExc_SyntaxError; switch (err->error) { @@ -2552,11 +1343,20 @@ err_input(perrdetail *err) errtext = Py_None; Py_INCREF(Py_None); } else { - errtext = PyUnicode_DecodeUTF8(err->text, strlen(err->text), + errtext = PyUnicode_DecodeUTF8(err->text, err->offset, "replace"); + if (errtext != NULL) { + Py_ssize_t len = strlen(err->text); + offset = (int)PyUnicode_GET_LENGTH(errtext); + if (len != err->offset) { + Py_DECREF(errtext); + errtext = PyUnicode_DecodeUTF8(err->text, len, + "replace"); + } + } } v = Py_BuildValue("(OiiN)", err->filename, - err->lineno, err->offset, errtext); + err->lineno, offset, errtext); if (v != NULL) { if (msg_obj) w = Py_BuildValue("(OO)", msg_obj, v); @@ -2575,192 +1375,6 @@ err_input(perrdetail *err) } } -/* Print fatal error message and abort */ - -void -Py_FatalError(const char *msg) -{ - const int fd = fileno(stderr); - PyThreadState *tstate; - - fprintf(stderr, "Fatal Python error: %s\n", msg); - fflush(stderr); /* it helps in Windows debug build */ - if (PyErr_Occurred()) { - PyErr_PrintEx(0); - } - else { - tstate = _Py_atomic_load_relaxed(&_PyThreadState_Current); - if (tstate != NULL) { - fputc('\n', stderr); - fflush(stderr); - _Py_DumpTracebackThreads(fd, tstate->interp, tstate); - } - _PyFaulthandler_Fini(); - } - -#ifdef MS_WINDOWS - { - size_t len = strlen(msg); - WCHAR* buffer; - size_t i; - - /* Convert the message to wchar_t. This uses a simple one-to-one - conversion, assuming that the this error message actually uses ASCII - only. If this ceases to be true, we will have to convert. */ - buffer = alloca( (len+1) * (sizeof *buffer)); - for( i=0; i<=len; ++i) - buffer[i] = msg[i]; - OutputDebugStringW(L"Fatal Python error: "); - OutputDebugStringW(buffer); - OutputDebugStringW(L"\n"); - } -#ifdef _DEBUG - DebugBreak(); -#endif -#endif /* MS_WINDOWS */ - abort(); -} - -/* Clean up and exit */ - -#ifdef WITH_THREAD -#include "pythread.h" -#endif - -static void (*pyexitfunc)(void) = NULL; -/* For the atexit module. */ -void _Py_PyAtExit(void (*func)(void)) -{ - pyexitfunc = func; -} - -static void -call_py_exitfuncs(void) -{ - if (pyexitfunc == NULL) - return; - - (*pyexitfunc)(); - PyErr_Clear(); -} - -/* Wait until threading._shutdown completes, provided - the threading module was imported in the first place. - The shutdown routine will wait until all non-daemon - "threading" threads have completed. */ -static void -wait_for_thread_shutdown(void) -{ -#ifdef WITH_THREAD - _Py_IDENTIFIER(_shutdown); - PyObject *result; - PyThreadState *tstate = PyThreadState_GET(); - PyObject *threading = PyMapping_GetItemString(tstate->interp->modules, - "threading"); - if (threading == NULL) { - /* threading not imported */ - PyErr_Clear(); - return; - } - result = _PyObject_CallMethodId(threading, &PyId__shutdown, ""); - if (result == NULL) { - PyErr_WriteUnraisable(threading); - } - else { - Py_DECREF(result); - } - Py_DECREF(threading); -#endif -} - -#define NEXITFUNCS 32 -static void (*exitfuncs[NEXITFUNCS])(void); -static int nexitfuncs = 0; - -int Py_AtExit(void (*func)(void)) -{ - if (nexitfuncs >= NEXITFUNCS) - return -1; - exitfuncs[nexitfuncs++] = func; - return 0; -} - -static void -call_ll_exitfuncs(void) -{ - while (nexitfuncs > 0) - (*exitfuncs[--nexitfuncs])(); - - fflush(stdout); - fflush(stderr); -} - -void -Py_Exit(int sts) -{ - Py_Finalize(); - - exit(sts); -} - -static void -initsigs(void) -{ -#ifdef SIGPIPE - PyOS_setsig(SIGPIPE, SIG_IGN); -#endif -#ifdef SIGXFZ - PyOS_setsig(SIGXFZ, SIG_IGN); -#endif -#ifdef SIGXFSZ - PyOS_setsig(SIGXFSZ, SIG_IGN); -#endif - PyOS_InitInterrupts(); /* May imply initsignal() */ - if (PyErr_Occurred()) { - Py_FatalError("Py_Initialize: can't import signal"); - } -} - - -/* Restore signals that the interpreter has called SIG_IGN on to SIG_DFL. - * - * All of the code in this function must only use async-signal-safe functions, - * listed at `man 7 signal` or - * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html. - */ -void -_Py_RestoreSignals(void) -{ -#ifdef SIGPIPE - PyOS_setsig(SIGPIPE, SIG_DFL); -#endif -#ifdef SIGXFZ - PyOS_setsig(SIGXFZ, SIG_DFL); -#endif -#ifdef SIGXFSZ - PyOS_setsig(SIGXFSZ, SIG_DFL); -#endif -} - - -/* - * The file descriptor fd is considered ``interactive'' if either - * a) isatty(fd) is TRUE, or - * b) the -i flag was given, and the filename associated with - * the descriptor is NULL or "" or "???". - */ -int -Py_FdIsInteractive(FILE *fp, const char *filename) -{ - if (isatty((int)fileno(fp))) - return 1; - if (!Py_InteractiveFlag) - return 0; - return (filename == NULL) || - (strcmp(filename, "") == 0) || - (strcmp(filename, "???") == 0); -} - #if defined(USE_STACKCHECK) #if defined(WIN32) && defined(_MSC_VER) @@ -2799,73 +1413,6 @@ PyOS_CheckStack(void) #endif /* USE_STACKCHECK */ - -/* Wrappers around sigaction() or signal(). */ - -PyOS_sighandler_t -PyOS_getsig(int sig) -{ -#ifdef HAVE_SIGACTION - struct sigaction context; - if (sigaction(sig, NULL, &context) == -1) - return SIG_ERR; - return context.sa_handler; -#else - PyOS_sighandler_t handler; -/* Special signal handling for the secure CRT in Visual Studio 2005 */ -#if defined(_MSC_VER) && _MSC_VER >= 1400 - switch (sig) { - /* Only these signals are valid */ - case SIGINT: - case SIGILL: - case SIGFPE: - case SIGSEGV: - case SIGTERM: - case SIGBREAK: - case SIGABRT: - break; - /* Don't call signal() with other values or it will assert */ - default: - return SIG_ERR; - } -#endif /* _MSC_VER && _MSC_VER >= 1400 */ - handler = signal(sig, SIG_IGN); - if (handler != SIG_ERR) - signal(sig, handler); - return handler; -#endif -} - -/* - * All of the code in this function must only use async-signal-safe functions, - * listed at `man 7 signal` or - * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html. - */ -PyOS_sighandler_t -PyOS_setsig(int sig, PyOS_sighandler_t handler) -{ -#ifdef HAVE_SIGACTION - /* Some code in Modules/signalmodule.c depends on sigaction() being - * used here if HAVE_SIGACTION is defined. Fix that if this code - * changes to invalidate that assumption. - */ - struct sigaction context, ocontext; - context.sa_handler = handler; - sigemptyset(&context.sa_mask); - context.sa_flags = 0; - if (sigaction(sig, &context, &ocontext) == -1) - return SIG_ERR; - return ocontext.sa_handler; -#else - PyOS_sighandler_t oldhandler; - oldhandler = signal(sig, handler); -#ifdef HAVE_SIGINTERRUPT - siginterrupt(sig, 1); -#endif - return oldhandler; -#endif -} - /* Deprecated C API functions still provided for binary compatiblity */ #undef PyParser_SimpleParseFile diff --git a/Python/pytime.c b/Python/pytime.c index beeab87e2c73..a8460c686795 100644 --- a/Python/pytime.c +++ b/Python/pytime.c @@ -3,29 +3,24 @@ #include #endif -#if defined(__APPLE__) && defined(HAVE_GETTIMEOFDAY) && defined(HAVE_FTIME) - /* - * _PyTime_gettimeofday falls back to ftime when getttimeofday fails because the latter - * might fail on some platforms. This fallback is unwanted on MacOSX because - * that makes it impossible to use a binary build on OSX 10.4 on earlier - * releases of the OS. Therefore claim we don't support ftime. - */ -# undef HAVE_FTIME +#if defined(__APPLE__) +#include /* mach_absolute_time(), mach_timebase_info() */ #endif -#if defined(HAVE_FTIME) && !defined(MS_WINDOWS) -#include -extern int ftime(struct timeb *); +#ifdef MS_WINDOWS +static OSVERSIONINFOEX winver; #endif -static void -pygettimeofday(_PyTime_timeval *tp, _Py_clock_info_t *info) +static int +pygettimeofday(_PyTime_timeval *tp, _Py_clock_info_t *info, int raise) { #ifdef MS_WINDOWS FILETIME system_time; ULARGE_INTEGER large; ULONGLONG microseconds; + assert(info == NULL || raise); + GetSystemTimeAsFileTime(&system_time); large.u.LowPart = system_time.dwLowDateTime; large.u.HighPart = system_time.dwHighDateTime; @@ -37,80 +32,244 @@ pygettimeofday(_PyTime_timeval *tp, _Py_clock_info_t *info) tp->tv_usec = microseconds % 1000000; if (info) { DWORD timeAdjustment, timeIncrement; - BOOL isTimeAdjustmentDisabled; + BOOL isTimeAdjustmentDisabled, ok; info->implementation = "GetSystemTimeAsFileTime()"; info->monotonic = 0; - (void) GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement, - &isTimeAdjustmentDisabled); + ok = GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement, + &isTimeAdjustmentDisabled); + if (!ok) { + PyErr_SetFromWindowsErr(0); + return -1; + } info->resolution = timeIncrement * 1e-7; info->adjustable = 1; } -#else - /* There are three ways to get the time: - (1) gettimeofday() -- resolution in microseconds - (2) ftime() -- resolution in milliseconds - (3) time() -- resolution in seconds - In all cases the return value in a timeval struct. - Since on some systems (e.g. SCO ODT 3.0) gettimeofday() may - fail, so we fall back on ftime() or time(). - Note: clock resolution does not imply clock accuracy! */ - -#ifdef HAVE_GETTIMEOFDAY + +#else /* MS_WINDOWS */ int err; +#ifdef HAVE_CLOCK_GETTIME + struct timespec ts; +#endif + + assert(info == NULL || raise); + +#ifdef HAVE_CLOCK_GETTIME + err = clock_gettime(CLOCK_REALTIME, &ts); + if (err) { + if (raise) + PyErr_SetFromErrno(PyExc_OSError); + return -1; + } + tp->tv_sec = ts.tv_sec; + tp->tv_usec = ts.tv_nsec / 1000; + + if (info) { + struct timespec res; + info->implementation = "clock_gettime(CLOCK_REALTIME)"; + info->monotonic = 0; + info->adjustable = 1; + if (clock_getres(CLOCK_REALTIME, &res) == 0) + info->resolution = res.tv_sec + res.tv_nsec * 1e-9; + else + info->resolution = 1e-9; + } +#else /* HAVE_CLOCK_GETTIME */ + + /* test gettimeofday() */ #ifdef GETTIMEOFDAY_NO_TZ err = gettimeofday(tp); #else err = gettimeofday(tp, (struct timezone *)NULL); #endif - if (err == 0) { - if (info) { - info->implementation = "gettimeofday()"; - info->resolution = 1e-6; - info->monotonic = 0; - info->adjustable = 1; - } - return; - } -#endif /* HAVE_GETTIMEOFDAY */ - -#if defined(HAVE_FTIME) - { - struct timeb t; - ftime(&t); - tp->tv_sec = t.time; - tp->tv_usec = t.millitm * 1000; - if (info) { - info->implementation = "ftime()"; - info->resolution = 1e-3; - info->monotonic = 0; - info->adjustable = 1; - } + if (err) { + if (raise) + PyErr_SetFromErrno(PyExc_OSError); + return -1; } -#else /* !HAVE_FTIME */ - tp->tv_sec = time(NULL); - tp->tv_usec = 0; + if (info) { - info->implementation = "time()"; - info->resolution = 1.0; + info->implementation = "gettimeofday()"; + info->resolution = 1e-6; info->monotonic = 0; info->adjustable = 1; } -#endif /* !HAVE_FTIME */ - -#endif /* MS_WINDOWS */ +#endif /* !HAVE_CLOCK_GETTIME */ +#endif /* !MS_WINDOWS */ + assert(0 <= tp->tv_usec && tp->tv_usec < 1000 * 1000); + return 0; } void _PyTime_gettimeofday(_PyTime_timeval *tp) { - pygettimeofday(tp, NULL); + if (pygettimeofday(tp, NULL, 0) < 0) { + /* cannot happen, _PyTime_Init() checks that pygettimeofday() works */ + assert(0); + tp->tv_sec = 0; + tp->tv_usec = 0; + } } -void +int _PyTime_gettimeofday_info(_PyTime_timeval *tp, _Py_clock_info_t *info) { - pygettimeofday(tp, info); + return pygettimeofday(tp, info, 1); +} + +static int +pymonotonic(_PyTime_timeval *tp, _Py_clock_info_t *info, int raise) +{ +#ifdef Py_DEBUG + static _PyTime_timeval last = {0, -1}; +#endif +#if defined(MS_WINDOWS) + static ULONGLONG (*GetTickCount64) (void) = NULL; + static ULONGLONG (CALLBACK *Py_GetTickCount64)(void); + static int has_gettickcount64 = -1; + ULONGLONG result; + + assert(info == NULL || raise); + + if (has_gettickcount64 == -1) { + /* GetTickCount64() was added to Windows Vista */ + has_gettickcount64 = (winver.dwMajorVersion >= 6); + if (has_gettickcount64) { + HINSTANCE hKernel32; + hKernel32 = GetModuleHandleW(L"KERNEL32"); + *(FARPROC*)&Py_GetTickCount64 = GetProcAddress(hKernel32, + "GetTickCount64"); + assert(Py_GetTickCount64 != NULL); + } + } + + if (has_gettickcount64) { + result = Py_GetTickCount64(); + } + else { + static DWORD last_ticks = 0; + static DWORD n_overflow = 0; + DWORD ticks; + + ticks = GetTickCount(); + if (ticks < last_ticks) + n_overflow++; + last_ticks = ticks; + + result = (ULONGLONG)n_overflow << 32; + result += ticks; + } + + tp->tv_sec = result / 1000; + tp->tv_usec = (result % 1000) * 1000; + + if (info) { + DWORD timeAdjustment, timeIncrement; + BOOL isTimeAdjustmentDisabled, ok; + if (has_gettickcount64) + info->implementation = "GetTickCount64()"; + else + info->implementation = "GetTickCount()"; + info->monotonic = 1; + ok = GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement, + &isTimeAdjustmentDisabled); + if (!ok) { + PyErr_SetFromWindowsErr(0); + return -1; + } + info->resolution = timeIncrement * 1e-7; + info->adjustable = 0; + } + +#elif defined(__APPLE__) + static mach_timebase_info_data_t timebase; + uint64_t time; + + if (timebase.denom == 0) { + /* According to the Technical Q&A QA1398, mach_timebase_info() cannot + fail: https://developer.apple.com/library/mac/#qa/qa1398/ */ + (void)mach_timebase_info(&timebase); + } + + time = mach_absolute_time(); + + /* nanoseconds => microseconds */ + time /= 1000; + /* apply timebase factor */ + time *= timebase.numer; + time /= timebase.denom; + tp->tv_sec = time / (1000 * 1000); + tp->tv_usec = time % (1000 * 1000); + + if (info) { + info->implementation = "mach_absolute_time()"; + info->resolution = (double)timebase.numer / timebase.denom * 1e-9; + info->monotonic = 1; + info->adjustable = 0; + } + +#else + struct timespec ts; +#ifdef CLOCK_HIGHRES + const clockid_t clk_id = CLOCK_HIGHRES; + const char *implementation = "clock_gettime(CLOCK_HIGHRES)"; +#else + const clockid_t clk_id = CLOCK_MONOTONIC; + const char *implementation = "clock_gettime(CLOCK_MONOTONIC)"; +#endif + + assert(info == NULL || raise); + + if (clock_gettime(clk_id, &ts) != 0) { + if (raise) { + PyErr_SetFromErrno(PyExc_OSError); + return -1; + } + tp->tv_sec = 0; + tp->tv_usec = 0; + return -1; + } + + if (info) { + struct timespec res; + info->monotonic = 1; + info->implementation = implementation; + info->adjustable = 0; + if (clock_getres(clk_id, &res) != 0) { + PyErr_SetFromErrno(PyExc_OSError); + return -1; + } + info->resolution = res.tv_sec + res.tv_nsec * 1e-9; + } + tp->tv_sec = ts.tv_sec; + tp->tv_usec = ts.tv_nsec / 1000; +#endif + assert(0 <= tp->tv_usec && tp->tv_usec < 1000 * 1000); +#ifdef Py_DEBUG + /* monotonic clock cannot go backward */ + assert(last.tv_usec == -1 + || tp->tv_sec > last.tv_sec + || (tp->tv_sec == last.tv_sec && tp->tv_usec >= last.tv_usec)); + last = *tp; +#endif + return 0; +} + +void +_PyTime_monotonic(_PyTime_timeval *tp) +{ + if (pymonotonic(tp, NULL, 0) < 0) { + /* cannot happen, _PyTime_Init() checks that pymonotonic() works */ + assert(0); + tp->tv_sec = 0; + tp->tv_usec = 0; + } +} + +int +_PyTime_monotonic_info(_PyTime_timeval *tp, _Py_clock_info_t *info) +{ + return pymonotonic(tp, info, 1); } static void @@ -152,7 +311,7 @@ _PyLong_FromTime_t(time_t t) static int _PyTime_ObjectToDenominator(PyObject *obj, time_t *sec, long *numerator, - double denominator) + double denominator, _PyTime_round_t round) { assert(denominator <= LONG_MAX); if (PyFloat_Check(obj)) { @@ -167,6 +326,20 @@ _PyTime_ObjectToDenominator(PyObject *obj, time_t *sec, long *numerator, intpart -= 1.0; } + floatpart *= denominator; + if (round == _PyTime_ROUND_UP) { + if (intpart >= 0) { + floatpart = ceil(floatpart); + if (floatpart >= denominator) { + floatpart = 0.0; + intpart += 1.0; + } + } + else { + floatpart = floor(floatpart); + } + } + *sec = (time_t)intpart; err = intpart - (double)*sec; if (err <= -1.0 || err >= 1.0) { @@ -174,7 +347,6 @@ _PyTime_ObjectToDenominator(PyObject *obj, time_t *sec, long *numerator, return -1; } - floatpart *= denominator; *numerator = (long)floatpart; return 0; } @@ -188,12 +360,18 @@ _PyTime_ObjectToDenominator(PyObject *obj, time_t *sec, long *numerator, } int -_PyTime_ObjectToTime_t(PyObject *obj, time_t *sec) +_PyTime_ObjectToTime_t(PyObject *obj, time_t *sec, _PyTime_round_t round) { if (PyFloat_Check(obj)) { double d, intpart, err; d = PyFloat_AsDouble(obj); + if (round == _PyTime_ROUND_UP) { + if (d >= 0) + d = ceil(d); + else + d = floor(d); + } (void)modf(d, &intpart); *sec = (time_t)intpart; @@ -213,19 +391,38 @@ _PyTime_ObjectToTime_t(PyObject *obj, time_t *sec) } int -_PyTime_ObjectToTimespec(PyObject *obj, time_t *sec, long *nsec) +_PyTime_ObjectToTimespec(PyObject *obj, time_t *sec, long *nsec, + _PyTime_round_t round) { - return _PyTime_ObjectToDenominator(obj, sec, nsec, 1e9); + return _PyTime_ObjectToDenominator(obj, sec, nsec, 1e9, round); } int -_PyTime_ObjectToTimeval(PyObject *obj, time_t *sec, long *usec) +_PyTime_ObjectToTimeval(PyObject *obj, time_t *sec, long *usec, + _PyTime_round_t round) { - return _PyTime_ObjectToDenominator(obj, sec, usec, 1e6); + return _PyTime_ObjectToDenominator(obj, sec, usec, 1e6, round); } -void -_PyTime_Init() +int +_PyTime_Init(void) { - /* Do nothing. Needed to force linking. */ + _PyTime_timeval tv; + +#ifdef MS_WINDOWS + winver.dwOSVersionInfoSize = sizeof(winver); + if (!GetVersionEx((OSVERSIONINFO*)&winver)) { + PyErr_SetFromWindowsErr(0); + return -1; + } +#endif + + /* ensure that the system clock works */ + if (_PyTime_gettimeofday_info(&tv, NULL) < 0) + return -1; + + /* ensure that the operating system provides a monotonic clock */ + if (_PyTime_monotonic_info(&tv, NULL) < 0) + return -1; + return 0; } diff --git a/Python/random.c b/Python/random.c index de8e9e72c74c..031d8875c973 100644 --- a/Python/random.c +++ b/Python/random.c @@ -3,6 +3,9 @@ #include #else #include +#ifdef HAVE_SYS_STAT_H +#include +#endif #endif #ifdef Py_DEBUG @@ -12,8 +15,6 @@ static int _Py_HashSecret_Initialized = 0; #endif #ifdef MS_WINDOWS -/* This handle is never explicitly released. Instead, the operating - system will release it when the process terminates. */ static HCRYPTPROV hCryptProv = 0; static int @@ -35,7 +36,7 @@ win32_urandom_init(int raise) } /* Fill buffer with size pseudo-random bytes generated by the Windows CryptoGen - API. Return 0 on success, or -1 on error. */ + API. Return 0 on success, or raise an exception and return -1 on error. */ static int win32_urandom(unsigned char *buffer, Py_ssize_t size, int raise) { @@ -65,32 +66,40 @@ win32_urandom(unsigned char *buffer, Py_ssize_t size, int raise) } return 0; } -#endif /* MS_WINDOWS */ +#elif HAVE_GETENTROPY +/* Fill buffer with size pseudo-random bytes generated by getentropy(). + Return 0 on success, or raise an exception and return -1 on error. -#ifdef __VMS -/* Use openssl random routine */ -#include + If fatal is nonzero, call Py_FatalError() instead of raising an exception + on error. */ static int -vms_urandom(unsigned char *buffer, Py_ssize_t size, int raise) +py_getentropy(unsigned char *buffer, Py_ssize_t size, int fatal) { - if (RAND_pseudo_bytes(buffer, size) < 0) { - if (raise) { - PyErr_Format(PyExc_ValueError, - "RAND_pseudo_bytes"); - } else { - Py_FatalError("Failed to initialize the randomized hash " - "secret using RAND_pseudo_bytes"); + while (size > 0) { + Py_ssize_t len = Py_MIN(size, 256); + int res = getentropy(buffer, len); + if (res < 0) { + if (fatal) { + Py_FatalError("getentropy() failed"); + } + else { + PyErr_SetFromErrno(PyExc_OSError); + return -1; + } } - return -1; + buffer += len; + size -= len; } return 0; } -#endif /* __VMS */ - -#if !defined(MS_WINDOWS) && !defined(__VMS) -static int urandom_fd = -1; +#else +static struct { + int fd; + dev_t st_dev; + ino_t st_ino; +} urandom_cache = { -1 }; /* Read size bytes from /dev/urandom into buffer. Call Py_FatalError() on error. */ @@ -130,12 +139,24 @@ dev_urandom_python(char *buffer, Py_ssize_t size) { int fd; Py_ssize_t n; + struct _Py_stat_struct st; if (size <= 0) return 0; - if (urandom_fd >= 0) - fd = urandom_fd; + if (urandom_cache.fd >= 0) { + /* Does the fd point to the same thing as before? (issue #21207) */ + if (_Py_fstat(urandom_cache.fd, &st) + || st.st_dev != urandom_cache.st_dev + || st.st_ino != urandom_cache.st_ino) { + /* Something changed: forget the cached fd (but don't close it, + since it probably points to something important for some + third-party code). */ + urandom_cache.fd = -1; + } + } + if (urandom_cache.fd >= 0) + fd = urandom_cache.fd; else { Py_BEGIN_ALLOW_THREADS fd = _Py_open("/dev/urandom", O_RDONLY); @@ -150,14 +171,24 @@ dev_urandom_python(char *buffer, Py_ssize_t size) PyErr_SetFromErrno(PyExc_OSError); return -1; } - if (urandom_fd >= 0) { + if (urandom_cache.fd >= 0) { /* urandom_fd was initialized by another thread while we were not holding the GIL, keep it. */ close(fd); - fd = urandom_fd; + fd = urandom_cache.fd; + } + else { + if (_Py_fstat(fd, &st)) { + PyErr_SetFromErrno(PyExc_OSError); + close(fd); + return -1; + } + else { + urandom_cache.fd = fd; + urandom_cache.st_dev = st.st_dev; + urandom_cache.st_ino = st.st_ino; + } } - else - urandom_fd = fd; } Py_BEGIN_ALLOW_THREADS @@ -189,13 +220,13 @@ dev_urandom_python(char *buffer, Py_ssize_t size) static void dev_urandom_close(void) { - if (urandom_fd >= 0) { - close(urandom_fd); - urandom_fd = -1; + if (urandom_cache.fd >= 0) { + close(urandom_cache.fd); + urandom_cache.fd = -1; } } -#endif /* !defined(MS_WINDOWS) && !defined(__VMS) */ +#endif /* HAVE_GETENTROPY */ /* Fill buffer with pseudo-random bytes generated by a linear congruent generator (LCG): @@ -219,7 +250,7 @@ lcg_urandom(unsigned int x0, unsigned char *buffer, size_t size) } /* Fill buffer with size pseudo-random bytes from the operating system random - number generator (RNG). It is suitable for for most cryptographic purposes + number generator (RNG). It is suitable for most cryptographic purposes except long living private keys for asymmetric encryption. Return 0 on success, raise an exception and return -1 on error. */ @@ -236,12 +267,10 @@ _PyOS_URandom(void *buffer, Py_ssize_t size) #ifdef MS_WINDOWS return win32_urandom((unsigned char *)buffer, size, 1); +#elif HAVE_GETENTROPY + return py_getentropy(buffer, size, 0); #else -# ifdef __VMS - return vms_urandom((unsigned char *)buffer, size, 1); -# else return dev_urandom_python((char*)buffer, size); -# endif #endif } @@ -285,12 +314,10 @@ _PyRandom_Init(void) else { #ifdef MS_WINDOWS (void)win32_urandom(secret, secret_size, 0); -#else /* #ifdef MS_WINDOWS */ -# ifdef __VMS - vms_urandom(secret, secret_size, 0); -# else +#elif HAVE_GETENTROPY + (void)py_getentropy(secret, secret_size, 1); +#else dev_urandom_noraise(secret, secret_size); -# endif #endif } } @@ -298,7 +325,14 @@ _PyRandom_Init(void) void _PyRandom_Fini(void) { -#if !defined(MS_WINDOWS) && !defined(__VMS) +#ifdef MS_WINDOWS + if (hCryptProv) { + CryptReleaseContext(hCryptProv, 0); + hCryptProv = 0; + } +#elif HAVE_GETENTROPY + /* nothing to clean */ +#else dev_urandom_close(); #endif } diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 4028a01dab77..292830bc25f2 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -32,10 +32,6 @@ extern void *PyWin_DLLhModule; extern const char *PyWin_DLLVersionString; #endif -#ifdef __VMS -#include -#endif - #ifdef HAVE_LANGINFO_H #include #include @@ -367,7 +363,7 @@ trace_init(void) static PyObject * -call_trampoline(PyThreadState *tstate, PyObject* callback, +call_trampoline(PyObject* callback, PyFrameObject *frame, int what, PyObject *arg) { PyObject *args; @@ -405,12 +401,11 @@ static int profile_trampoline(PyObject *self, PyFrameObject *frame, int what, PyObject *arg) { - PyThreadState *tstate = frame->f_tstate; PyObject *result; if (arg == NULL) arg = Py_None; - result = call_trampoline(tstate, self, frame, what, arg); + result = call_trampoline(self, frame, what, arg); if (result == NULL) { PyEval_SetProfile(NULL, NULL); return -1; @@ -423,7 +418,6 @@ static int trace_trampoline(PyObject *self, PyFrameObject *frame, int what, PyObject *arg) { - PyThreadState *tstate = frame->f_tstate; PyObject *callback; PyObject *result; @@ -433,11 +427,10 @@ trace_trampoline(PyObject *self, PyFrameObject *frame, callback = frame->f_trace; if (callback == NULL) return 0; - result = call_trampoline(tstate, callback, frame, what, arg); + result = call_trampoline(callback, frame, what, arg); if (result == NULL) { PyEval_SetTrace(NULL, NULL); - Py_XDECREF(frame->f_trace); - frame->f_trace = NULL; + Py_CLEAR(frame->f_trace); return -1; } if (result != Py_None) { @@ -803,6 +796,10 @@ sys_getwindowsversion(PyObject *self) PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wSuiteMask)); PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wProductType)); + if (PyErr_Occurred()) { + Py_DECREF(version); + return NULL; + } return version; } @@ -866,29 +863,16 @@ sys_mdebug(PyObject *self, PyObject *args) } #endif /* USE_MALLOPT */ -static PyObject * -sys_getsizeof(PyObject *self, PyObject *args, PyObject *kwds) +size_t +_PySys_GetSizeOf(PyObject *o) { PyObject *res = NULL; - static PyObject *gc_head_size = NULL; - static char *kwlist[] = {"object", "default", 0}; - PyObject *o, *dflt = NULL; PyObject *method; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:getsizeof", - kwlist, &o, &dflt)) - return NULL; - - /* Initialize static variable for GC head size */ - if (gc_head_size == NULL) { - gc_head_size = PyLong_FromSsize_t(sizeof(PyGC_Head)); - if (gc_head_size == NULL) - return NULL; - } + Py_ssize_t size; /* Make sure the type is initialized. float gets initialized late */ if (PyType_Ready(Py_TYPE(o)) < 0) - return NULL; + return (size_t)-1; method = _PyObject_LookupSpecial(o, &PyId___sizeof__); if (method == NULL) { @@ -902,24 +886,50 @@ sys_getsizeof(PyObject *self, PyObject *args, PyObject *kwds) Py_DECREF(method); } - /* Has a default value been given */ - if ((res == NULL) && (dflt != NULL) && - PyErr_ExceptionMatches(PyExc_TypeError)) - { - PyErr_Clear(); - Py_INCREF(dflt); - return dflt; + if (res == NULL) + return (size_t)-1; + + size = PyLong_AsSsize_t(res); + Py_DECREF(res); + if (size == -1 && PyErr_Occurred()) + return (size_t)-1; + + if (size < 0) { + PyErr_SetString(PyExc_ValueError, "__sizeof__() should return >= 0"); + return (size_t)-1; } - else if (res == NULL) - return res; /* add gc_head size */ - if (PyObject_IS_GC(o)) { - PyObject *tmp = res; - res = PyNumber_Add(tmp, gc_head_size); - Py_DECREF(tmp); + if (PyObject_IS_GC(o)) + return ((size_t)size) + sizeof(PyGC_Head); + return (size_t)size; +} + +static PyObject * +sys_getsizeof(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"object", "default", 0}; + size_t size; + PyObject *o, *dflt = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:getsizeof", + kwlist, &o, &dflt)) + return NULL; + + size = _PySys_GetSizeOf(o); + + if (size == (size_t)-1 && PyErr_Occurred()) { + /* Has a default value been given */ + if (dflt != NULL && PyErr_ExceptionMatches(PyExc_TypeError)) { + PyErr_Clear(); + Py_INCREF(dflt); + return dflt; + } + else + return NULL; } - return res; + + return PyLong_FromSize_t(size); } PyDoc_STRVAR(getsizeof_doc, @@ -1111,6 +1121,16 @@ PyDoc_STRVAR(sys_clear_type_cache__doc__, "_clear_type_cache() -> None\n\ Clear the internal type lookup cache."); +static PyObject * +sys_is_finalizing(PyObject* self, PyObject* args) +{ + return PyBool_FromLong(_Py_Finalizing != NULL); +} + +PyDoc_STRVAR(is_finalizing_doc, +"is_finalizing()\n\ +Return True if Python is exiting."); + static PyMethodDef sys_methods[] = { /* Might as well keep this in alphabetic order */ @@ -1157,6 +1177,7 @@ static PyMethodDef sys_methods[] = { getwindowsversion_doc}, #endif /* MS_WINDOWS */ {"intern", sys_intern, METH_VARARGS, intern_doc}, + {"is_finalizing", sys_is_finalizing, METH_NOARGS, is_finalizing_doc}, #ifdef USE_MALLOPT {"mdebug", sys_mdebug, METH_VARARGS}, #endif @@ -1184,7 +1205,7 @@ static PyMethodDef sys_methods[] = { {"settrace", sys_settrace, METH_O, settrace_doc}, {"gettrace", sys_gettrace, METH_NOARGS, gettrace_doc}, {"call_tracing", sys_call_tracing, METH_VARARGS, call_tracing_doc}, - {"_debugmallocstats", sys_debugmallocstats, METH_VARARGS, + {"_debugmallocstats", sys_debugmallocstats, METH_NOARGS, debugmallocstats_doc}, {NULL, NULL} /* sentinel */ }; @@ -1358,7 +1379,7 @@ hexversion -- version information encoded as a single integer\n\ implementation -- Python implementation information.\n\ int_info -- a struct sequence with information about the int implementation.\n\ maxsize -- the largest supported length of containers.\n\ -maxunicode -- the value of the largest Unicode codepoint\n\ +maxunicode -- the value of the largest Unicode code point\n\ platform -- platform identifier\n\ prefix -- prefix used to find the Python library\n\ thread_info -- a struct sequence with information about the thread implementation.\n\ @@ -1467,6 +1488,7 @@ make_flags(void) #undef SetFlag if (PyErr_Occurred()) { + Py_DECREF(seq); return NULL; } return seq; @@ -1548,7 +1570,7 @@ const char *_PySys_ImplName = NAME; #define STRIFY(name) QUOTE(name) #define MAJOR STRIFY(PY_MAJOR_VERSION) #define MINOR STRIFY(PY_MINOR_VERSION) -#define TAG NAME "-" MAJOR MINOR; +#define TAG NAME "-" MAJOR MINOR const char *_PySys_ImplCacheTag = TAG; #undef NAME #undef QUOTE @@ -1624,6 +1646,7 @@ PyObject * _PySys_Init(void) { PyObject *m, *sysdict, *version_info; + int res; m = PyModule_Create(&sysmodule); if (m == NULL) @@ -1631,7 +1654,6 @@ _PySys_Init(void) sysdict = PyModule_GetDict(m); #define SET_SYS_FROM_STRING_BORROW(key, value) \ do { \ - int res; \ PyObject *v = (value); \ if (v == NULL) \ return NULL; \ @@ -1642,7 +1664,6 @@ _PySys_Init(void) } while (0) #define SET_SYS_FROM_STRING(key, value) \ do { \ - int res; \ PyObject *v = (value); \ if (v == NULL) \ return NULL; \ @@ -1660,8 +1681,8 @@ _PySys_Init(void) the shell already prevents that. */ #if !defined(MS_WINDOWS) { - struct stat sb; - if (fstat(fileno(stdin), &sb) == 0 && + struct _Py_stat_struct sb; + if (_Py_fstat(fileno(stdin), &sb) == 0 && S_ISDIR(sb.st_mode)) { /* There's nothing more we can do. */ /* Py_FatalError() will core dump, so just exit. */ @@ -1671,7 +1692,7 @@ _PySys_Init(void) } #endif - /* stdin/stdout/stderr are now set by pythonrun.c */ + /* stdin/stdout/stderr are set in pylifecycle.c */ SET_SYS_FROM_STRING_BORROW("__displayhook__", PyDict_GetItemString(sysdict, "displayhook")); @@ -1761,6 +1782,9 @@ _PySys_Init(void) /* prevent user from creating new instances */ VersionInfoType.tp_init = NULL; VersionInfoType.tp_new = NULL; + res = PyDict_DelItemString(VersionInfoType.tp_dict, "__new__"); + if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) + PyErr_Clear(); /* implementation */ SET_SYS_FROM_STRING("implementation", make_impl_info(version_info)); @@ -1774,7 +1798,9 @@ _PySys_Init(void) /* prevent user from creating new instances */ FlagsType.tp_init = NULL; FlagsType.tp_new = NULL; - + res = PyDict_DelItemString(FlagsType.tp_dict, "__new__"); + if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) + PyErr_Clear(); #if defined(MS_WINDOWS) /* getwindowsversion */ @@ -1785,6 +1811,9 @@ _PySys_Init(void) /* prevent user from creating new instances */ WindowsVersionType.tp_init = NULL; WindowsVersionType.tp_new = NULL; + res = PyDict_DelItemString(WindowsVersionType.tp_dict, "__new__"); + if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) + PyErr_Clear(); #endif /* float repr style: 0.03 (short) vs 0.029999999999999999 (legacy) */ @@ -1801,6 +1830,7 @@ _PySys_Init(void) #endif #undef SET_SYS_FROM_STRING +#undef SET_SYS_FROM_STRING_BORROW if (PyErr_Occurred()) return NULL; return m; @@ -1864,22 +1894,7 @@ makeargvobject(int argc, wchar_t **argv) if (av != NULL) { int i; for (i = 0; i < argc; i++) { -#ifdef __VMS - PyObject *v; - - /* argv[0] is the script pathname if known */ - if (i == 0) { - char* fn = decc$translate_vms(argv[0]); - if ((fn == (char *)0) || fn == (char *)-1) - v = PyUnicode_FromString(argv[0]); - else - v = PyUnicode_FromString( - decc$translate_vms(argv[0])); - } else - v = PyUnicode_FromString(argv[i]); -#else PyObject *v = PyUnicode_FromWideChar(argv[i], -1); -#endif if (v == NULL) { Py_DECREF(av); av = NULL; diff --git a/Python/thread.c b/Python/thread.c index 8540942e28a1..44c071eafe6a 100644 --- a/Python/thread.c +++ b/Python/thread.c @@ -205,7 +205,7 @@ static int nkeys = 0; /* PyThread_create_key() hands out nkeys+1 next */ * segfaults. Now we lock the whole routine. */ static struct key * -find_key(int key, void *value) +find_key(int set_value, int key, void *value) { struct key *p, *prev_p; long id = PyThread_get_thread_ident(); @@ -215,10 +215,13 @@ find_key(int key, void *value) PyThread_acquire_lock(keymutex, 1); prev_p = NULL; for (p = keyhead; p != NULL; p = p->next) { - if (p->id == id && p->key == key) + if (p->id == id && p->key == key) { + if (set_value) + p->value = value; goto Done; + } /* Sanity check. These states should never happen but if - * they do we must abort. Otherwise we'll end up spinning in + * they do we must abort. Otherwise we'll end up spinning * in a tight loop with the lock held. A similar check is done * in pystate.c tstate_delete_common(). */ if (p == prev_p) @@ -227,7 +230,7 @@ find_key(int key, void *value) if (p->next == keyhead) Py_FatalError("tls find_key: circular list(!)"); } - if (value == NULL) { + if (!set_value && value == NULL) { assert(p == NULL); goto Done; } @@ -279,19 +282,12 @@ PyThread_delete_key(int key) PyThread_release_lock(keymutex); } -/* Confusing: If the current thread has an association for key, - * value is ignored, and 0 is returned. Else an attempt is made to create - * an association of key to value for the current thread. 0 is returned - * if that succeeds, but -1 is returned if there's not enough memory - * to create the association. value must not be NULL. - */ int PyThread_set_key_value(int key, void *value) { struct key *p; - assert(value != NULL); - p = find_key(key, value); + p = find_key(1, key, value); if (p == NULL) return -1; else @@ -304,7 +300,7 @@ PyThread_set_key_value(int key, void *value) void * PyThread_get_key_value(int key) { - struct key *p = find_key(key, NULL); + struct key *p = find_key(0, key, NULL); if (p == NULL) return NULL; @@ -435,7 +431,7 @@ PyThread_GetInfo(void) && defined(_CS_GNU_LIBPTHREAD_VERSION)) value = NULL; len = confstr(_CS_GNU_LIBPTHREAD_VERSION, buffer, sizeof(buffer)); - if (1 < len && len < sizeof(buffer)) { + if (1 < len && (size_t)len < sizeof(buffer)) { value = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1); if (value == NULL) PyErr_Clear(); diff --git a/Python/thread_foobar.h b/Python/thread_foobar.h index d2b78c5caed0..ea96f9c9d79f 100644 --- a/Python/thread_foobar.h +++ b/Python/thread_foobar.h @@ -1,4 +1,3 @@ - /* * Initialization. */ @@ -60,11 +59,19 @@ PyThread_free_lock(PyThread_type_lock lock) int PyThread_acquire_lock(PyThread_type_lock lock, int waitflag) +{ + return PyThread_acquire_lock_timed(lock, waitflag ? -1 : 0, 0); +} + +PyLockStatus +PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds, + int intr_flag) { int success; - dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag)); - dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success)); + dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n", lock, microseconds, intr_flag)); + dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n", + lock, microseconds, intr_flag, success)); return success; } @@ -73,3 +80,53 @@ PyThread_release_lock(PyThread_type_lock lock) { dprintf(("PyThread_release_lock(%p) called\n", lock)); } + +/* The following are only needed if native TLS support exists */ +#define Py_HAVE_NATIVE_TLS + +#ifdef Py_HAVE_NATIVE_TLS +int +PyThread_create_key(void) +{ + int result; + return result; +} + +void +PyThread_delete_key(int key) +{ + +} + +int +PyThread_set_key_value(int key, void *value) +{ + int ok; + + /* A failure in this case returns -1 */ + if (!ok) + return -1; + return 0; +} + +void * +PyThread_get_key_value(int key) +{ + void *result; + + return result; +} + +void +PyThread_delete_key_value(int key) +{ + +} + +void +PyThread_ReInitTLS(void) +{ + +} + +#endif diff --git a/Python/thread_nt.h b/Python/thread_nt.h index ab5a08168f7d..84452cdac4ec 100644 --- a/Python/thread_nt.h +++ b/Python/thread_nt.h @@ -77,7 +77,7 @@ EnterNonRecursiveMutex(PNRMUTEX mutex, DWORD milliseconds) /* wait at least until the target */ DWORD now, target = GetTickCount() + milliseconds; while (mutex->locked) { - if (PyCOND_TIMEDWAIT(&mutex->cv, &mutex->cs, milliseconds*1000) < 0) { + if (PyCOND_TIMEDWAIT(&mutex->cv, &mutex->cs, (PY_LONG_LONG)milliseconds*1000) < 0) { result = WAIT_FAILED; break; } @@ -389,20 +389,11 @@ PyThread_delete_key(int key) TlsFree(key); } -/* We must be careful to emulate the strange semantics implemented in thread.c, - * where the value is only set if it hasn't been set before. - */ int PyThread_set_key_value(int key, void *value) { BOOL ok; - void *oldvalue; - assert(value != NULL); - oldvalue = TlsGetValue(key); - if (oldvalue != NULL) - /* ignore value if already set */ - return 0; ok = TlsSetValue(key, value); if (!ok) return -1; diff --git a/Python/thread_pthread.h b/Python/thread_pthread.h index 20f85358968b..27e0dc84bcb5 100644 --- a/Python/thread_pthread.h +++ b/Python/thread_pthread.h @@ -608,7 +608,15 @@ PyThread_create_key(void) { pthread_key_t key; int fail = pthread_key_create(&key, NULL); - return fail ? -1 : key; + if (fail) + return -1; + if (key > INT_MAX) { + /* Issue #22206: handle integer overflow */ + pthread_key_delete(key); + errno = ENOMEM; + return -1; + } + return (int)key; } void @@ -627,9 +635,6 @@ int PyThread_set_key_value(int key, void *value) { int fail; - void *oldValue = pthread_getspecific(key); - if (oldValue != NULL) - return 0; fail = pthread_setspecific(key, value); return fail ? -1 : 0; } diff --git a/Python/traceback.c b/Python/traceback.c index e9169ce5e060..e3adc96ae89a 100644 --- a/Python/traceback.c +++ b/Python/traceback.c @@ -142,6 +142,39 @@ PyTraceBack_Here(PyFrameObject *frame) return 0; } +/* Insert a frame into the traceback for (funcname, filename, lineno). */ +void _PyTraceback_Add(char *funcname, char *filename, int lineno) +{ + PyObject *globals = NULL; + PyCodeObject *code = NULL; + PyFrameObject *frame = NULL; + PyObject *exception, *value, *tb; + + /* Save and clear the current exception. Python functions must not be + called with an exception set. Calling Python functions happens when + the codec of the filesystem encoding is implemented in pure Python. */ + PyErr_Fetch(&exception, &value, &tb); + + globals = PyDict_New(); + if (!globals) + goto done; + code = PyCode_NewEmpty(filename, funcname, lineno); + if (!code) + goto done; + frame = PyFrame_New(PyThreadState_Get(), code, globals, NULL); + if (!frame) + goto done; + frame->f_lineno = lineno; + + PyErr_Restore(exception, value, tb); + PyTraceBack_Here(frame); + +done: + Py_XDECREF(globals); + Py_XDECREF(code); + Py_XDECREF(frame); +} + static PyObject * _Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject *io) { @@ -198,7 +231,7 @@ _Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject * } strcpy(namebuf, PyBytes_AS_STRING(path)); Py_DECREF(path); - if (strlen(namebuf) != len) + if (strlen(namebuf) != (size_t)len) continue; /* v contains '\0' */ if (len > 0 && namebuf[len-1] != SEP) namebuf[len++] = SEP; @@ -264,6 +297,8 @@ _Py_DisplaySourceLine(PyObject *f, PyObject *filename, int lineno, int indent) return 0; } found_encoding = PyTokenizer_FindEncodingFilename(fd, filename); + if (found_encoding == NULL) + PyErr_Clear(); encoding = (found_encoding != NULL) ? found_encoding : "utf-8"; /* Reset position */ if (lseek(fd, 0, SEEK_SET) == (off_t)-1) { @@ -287,6 +322,7 @@ _Py_DisplaySourceLine(PyObject *f, PyObject *filename, int lineno, int indent) Py_XDECREF(lineobj); lineobj = PyFile_GetLine(fob, -1); if (!lineobj) { + PyErr_Clear(); err = -1; break; } @@ -539,15 +575,16 @@ dump_ascii(int fd, PyObject *text) ch = PyUnicode_READ(kind, data, i); else ch = wstr[i]; - if (ch < 128) { + if (' ' <= ch && ch <= 126) { + /* printable ASCII character */ char c = (char)ch; write(fd, &c, 1); } - else if (ch < 0xff) { + else if (ch <= 0xff) { PUTS(fd, "\\x"); dump_hexadecimal(fd, ch, 2); } - else if (ch < 0xffff) { + else if (ch <= 0xffff) { PUTS(fd, "\\u"); dump_hexadecimal(fd, ch, 4); } @@ -642,7 +679,7 @@ write_thread_id(int fd, PyThreadState *tstate, int is_current) PUTS(fd, "Current thread 0x"); else PUTS(fd, "Thread 0x"); - dump_hexadecimal(fd, (unsigned long)tstate->thread_id, sizeof(long)*2); + dump_hexadecimal(fd, (unsigned long)tstate->thread_id, sizeof(unsigned long)*2); PUTS(fd, " (most recent call first):\n"); } diff --git a/README b/README index 6a78046d9fa4..c3e41a393ce1 100644 --- a/README +++ b/README @@ -1,8 +1,8 @@ -This is Python version 3.4.0 beta 1 -=================================== +This is Python version 3.5.0 alpha 1 +==================================== Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, -2012, 2013 Python Software Foundation. All rights reserved. +2012, 2013, 2014, 2015 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 @@ -52,9 +52,9 @@ What's New ---------- We try to have a comprehensive overview of the changes in the "What's New in -Python 3.4" document, found at +Python 3.5" document, found at - http://docs.python.org/3.4/whatsnew/3.4.html + http://docs.python.org/3.5/whatsnew/3.5.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 @@ -67,9 +67,9 @@ entitled "Installing multiple versions". Documentation ------------- -Documentation for Python 3.4 is online, updated daily: +Documentation for Python 3.5 is online, updated daily: - http://docs.python.org/3.4/ + http://docs.python.org/3.5/ It can also be downloaded in many formats for faster access. The documentation is downloadable in HTML, PDF, and reStructuredText formats; the latter version @@ -94,7 +94,7 @@ 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 -http://docs.python.org/3.4/library/2to3.html for more information. +http://docs.python.org/3.5/library/2to3.html for more information. Testing @@ -132,7 +132,7 @@ 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.6, 2.7 and 3.4 with 2.7 being the +For example, if you want to install Python 2.6, 2.7 and 3.5 with 2.7 being the primary version, you would execute "make install" in your 2.7 build directory and "make altinstall" in the others. @@ -168,14 +168,14 @@ http://www.python.org/dev/peps/. Release Schedule ---------------- -See PEP 429 for release details: http://www.python.org/dev/peps/pep-0429/ +See PEP 478 for release details: http://www.python.org/dev/peps/pep-0478/ Copyright and License Information --------------------------------- Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, -2012, 2013 Python Software Foundation. All rights reserved. +2012, 2013, 2014, 2015 Python Software Foundation. All rights reserved. Copyright (c) 2000 BeOpen.com. All rights reserved. diff --git a/Tools/buildbot/README.tcltk-AMD64 b/Tools/buildbot/README.tcltk-AMD64 deleted file mode 100644 index edc89eba9e66..000000000000 --- a/Tools/buildbot/README.tcltk-AMD64 +++ /dev/null @@ -1,36 +0,0 @@ -Comments on building tcl/tk for AMD64 with the MS SDK compiler -============================================================== - -I did have to build tcl/tk manually. - -First, I had to build the nmakehlp.exe helper utility manually by executing - cl nmakehlp.c /link bufferoverflowU.lib -in both the tcl8.4.12\win and tk8.4.12\win directories. - -Second, the AMD64 compiler refuses to compile the file -tcl8.4.12\generic\tclExecute.c because it insists on using intrinsics -for the 'ceil' and 'floor' functions: - - ..\generic\tclExecute.c(394) : error C2099: initializer is not a constant - ..\generic\tclExecute.c(398) : error C2099: initializer is not a constant - -I did comment out these lines; an alternative would have been to use -the /Oi- compiler flag to disable the intrinsic functions. -The commands then used were these: - - svn export http://svn.python.org/projects/external/tcl8.4.12 - cd tcl8.4.12\win - REM - echo patch the tcl8.4.12\generic\tclExecute.c file - pause - REM - cl nmakehlp.c /link bufferoverflowU.lib - nmake -f makefile.vc MACHINE=AMD64 - nmake -f makefile.vc INSTALLDIR=..\..\tcltk install - cd ..\.. - svn export http://svn.python.org/projects/external/tk8.4.12 - cd tk8.4.12\win - cl nmakehlp.c /link bufferoverflowU.lib - nmake -f makefile.vc TCLDIR=..\..\tcl8.4.12 MACHINE=AMD64 - nmake -f makefile.vc TCLDIR=..\..\tcl8.4.12 INSTALLDIR=..\..\tcltk install - cd ..\.. diff --git a/Tools/buildbot/build-amd64.bat b/Tools/buildbot/build-amd64.bat index 493e74de5a3e..115e111f76db 100644 --- a/Tools/buildbot/build-amd64.bat +++ b/Tools/buildbot/build-amd64.bat @@ -1,6 +1,2 @@ @rem Used by the buildbot "compile" step. -cmd /c Tools\buildbot\external-amd64.bat -call "%VS100COMNTOOLS%\..\..\VC\vcvarsall.bat" x86_amd64 -cmd /c Tools\buildbot\clean-amd64.bat - -msbuild PCbuild\pcbuild.sln /p:Configuration=Debug /p:Platform=x64 +call "%~dp0build.bat" -p x64 %* diff --git a/Tools/buildbot/build.bat b/Tools/buildbot/build.bat index be79b10726d7..83a5dfd101c7 100644 --- a/Tools/buildbot/build.bat +++ b/Tools/buildbot/build.bat @@ -1,7 +1,20 @@ @rem Used by the buildbot "compile" step. -cmd /c Tools\buildbot\external.bat -call "%VS100COMNTOOLS%vsvars32.bat" -cmd /c Tools\buildbot\clean.bat -msbuild PCbuild\pcbuild.sln /p:Configuration=Debug /p:Platform=Win32 +@rem Clean up +set PLAT= +if '%1' EQU '-p' if '%2' EQU 'x64' (set PLAT=-amd64) +call "%~dp0clean%PLAT%.bat" + +@rem If you need the buildbots to start fresh (such as when upgrading to +@rem a new version of an external library, especially Tcl/Tk): +@rem 1) uncomment the following line: + +@rem call "%~dp0..\..\PCbuild\get_externals.bat" --clean-only + +@rem 2) commit and push +@rem 3) wait for all Windows bots to start a build with that changeset +@rem 4) re-comment, commit and push again + +@rem Do the build +call "%~dp0..\..\PCbuild\build.bat" -e -d -v %* diff --git a/Tools/buildbot/buildmsi.bat b/Tools/buildbot/buildmsi.bat index ae93e6729565..6804d7947995 100644 --- a/Tools/buildbot/buildmsi.bat +++ b/Tools/buildbot/buildmsi.bat @@ -1,21 +1,9 @@ @rem Used by the buildbot "buildmsi" step. +setlocal -cmd /c Tools\buildbot\external.bat -@rem build release versions of things -call "%VS100COMNTOOLS%vsvars32.bat" +pushd -@rem build Python -msbuild /p:useenv=true PCbuild\pcbuild.sln /p:Configuration=Release /p:Platform=Win32 - -@rem build the documentation -bash.exe -c 'cd Doc;make PYTHON=python2.5 update htmlhelp' -"%ProgramFiles%\HTML Help Workshop\hhc.exe" Doc\build\htmlhelp\python26a3.hhp - -@rem build the MSI file -cd PC -nmake /f icons.mak -cd ..\Tools\msi -del *.msi -nmake /f msisupport.mak -%HOST_PYTHON% msi.py +@rem build both snapshot MSIs +call "%~dp0..\msi\build.bat" -x86 -x64 +popd \ No newline at end of file diff --git a/Tools/buildbot/clean-amd64.bat b/Tools/buildbot/clean-amd64.bat index 24660af012a2..b4882c294689 100644 --- a/Tools/buildbot/clean-amd64.bat +++ b/Tools/buildbot/clean-amd64.bat @@ -1,10 +1,2 @@ @rem Used by the buildbot "clean" step. -call "%VS100COMNTOOLS%\..\..\VC\vcvarsall.bat" x86_amd64 -@echo Deleting .pyc/.pyo files ... -del /s Lib\*.pyc Lib\*.pyo -@echo Deleting test leftovers ... -rmdir /s /q build -cd PCbuild -msbuild /target:clean pcbuild.sln /p:Configuration=Release /p:PlatformTarget=x64 -msbuild /target:clean pcbuild.sln /p:Configuration=Debug /p:PlatformTarget=x64 -cd .. +@call "%~dp0clean.bat" x64 diff --git a/Tools/buildbot/clean.bat b/Tools/buildbot/clean.bat index 218facc3b179..09328bcc9c1e 100644 --- a/Tools/buildbot/clean.bat +++ b/Tools/buildbot/clean.bat @@ -1,8 +1,29 @@ -@rem Used by the buildbot "clean" step. -call "%VS100COMNTOOLS%vsvars32.bat" -@echo Deleting test leftovers ... -rmdir /s /q build -cd PCbuild -msbuild /target:clean pcbuild.sln /p:Configuration=Release /p:PlatformTarget=x86 -msbuild /target:clean pcbuild.sln /p:Configuration=Debug /p:PlatformTarget=x86 -cd .. +@echo off +rem Used by the buildbot "clean" step. + +setlocal +set root=%~dp0..\.. +set pcbuild=%root%\PCbuild + +if "%1" == "x64" ( + set vcvars_target=x86_amd64 + set platform=x64 +) else ( + set vcvars_target=x86 + set platform=Win32 +) + +call "%pcbuild%\env.bat" %vcvars_target% + +echo.Attempting to kill Pythons... +msbuild /v:m /nologo /target:KillPython "%pcbuild%\pythoncore.vcxproj" /p:Configuration=Release /p:Platform=%platform% /p:KillPython=true + +echo Deleting .pyc/.pyo files ... +del /s "%root%\Lib\*.pyc" "%root%\Lib\*.pyo" + +echo Deleting test leftovers ... +rmdir /s /q "%root%\build" + +echo Deleting build +msbuild /v:m /nologo /target:clean "%pcbuild%\pcbuild.proj" /p:Configuration=Release /p:Platform=%platform% +msbuild /v:m /nologo /target:clean "%pcbuild%\pcbuild.proj" /p:Configuration=Debug /p:Platform=%platform% diff --git a/Tools/buildbot/external-amd64.bat b/Tools/buildbot/external-amd64.bat index 4c3b67b55f32..7a570d92ba12 100644 --- a/Tools/buildbot/external-amd64.bat +++ b/Tools/buildbot/external-amd64.bat @@ -1,21 +1,2 @@ -@rem Fetches (and builds if necessary) external dependencies - -@rem Assume we start inside the Python source directory -call "Tools\buildbot\external-common.bat" -call "%VS100COMNTOOLS%\..\..\VC\vcvarsall.bat" x86_amd64 - -if not exist tcltk64\bin\tcl86tg.dll ( - cd tcl-8.6.1.0\win - nmake -f makefile.vc DEBUG=1 MACHINE=AMD64 INSTALLDIR=..\..\tcltk64 clean all - nmake -f makefile.vc DEBUG=1 MACHINE=AMD64 INSTALLDIR=..\..\tcltk64 install - cd ..\.. -) - -if not exist tcltk64\bin\tk86tg.dll ( - cd tk-8.6.1.0\win - nmake -f makefile.vc OPTS=noxp DEBUG=1 MACHINE=AMD64 INSTALLDIR=..\..\tcltk64 TCLDIR=..\..\tcl-8.6.1.0 clean - nmake -f makefile.vc OPTS=noxp DEBUG=1 MACHINE=AMD64 INSTALLDIR=..\..\tcltk64 TCLDIR=..\..\tcl-8.6.1.0 all - nmake -f makefile.vc OPTS=noxp DEBUG=1 MACHINE=AMD64 INSTALLDIR=..\..\tcltk64 TCLDIR=..\..\tcl-8.6.1.0 install - cd ..\.. -) - +@echo Please use PCbuild\get_externals.bat instead. +@"%~dp0..\..\PCbuild\get_externals.bat" %* diff --git a/Tools/buildbot/external-common.bat b/Tools/buildbot/external-common.bat deleted file mode 100644 index 244abd2d932d..000000000000 --- a/Tools/buildbot/external-common.bat +++ /dev/null @@ -1,49 +0,0 @@ -@rem Common file shared between external.bat and external-amd64.bat. Responsible for -@rem fetching external components into the root\.. buildbot directories. - -cd .. -@rem XXX: If you need to force the buildbots to start from a fresh environment, uncomment -@rem the following, check it in, then check it out, comment it out, then check it back in. -@rem if exist bzip2-1.0.6 rd /s/q bzip2-1.0.6 -@rem if exist tcltk rd /s/q tcltk -@rem if exist tcltk64 rd /s/q tcltk64 -@rem if exist tcl8.4.12 rd /s/q tcl8.4.12 -@rem if exist tcl8.4.16 rd /s/q tcl8.4.16 -@rem if exist tcl-8.4.18.1 rd /s/q tcl-8.4.18.1 -@rem if exist tk8.4.12 rd /s/q tk8.4.12 -@rem if exist tk8.4.16 rd /s/q tk8.4.16 -@rem if exist tk-8.4.18.1 rd /s/q tk-8.4.18.1 -@rem if exist db-4.4.20 rd /s/q db-4.4.20 -@rem if exist openssl-1.0.1e rd /s/q openssl-1.0.1e -@rem if exist sqlite-3.7.12 rd /s/q sqlite-3.7.12 - -@rem bzip -if not exist bzip2-1.0.6 ( - rd /s/q bzip2-1.0.5 - svn export http://svn.python.org/projects/external/bzip2-1.0.6 -) - -@rem OpenSSL -if not exist openssl-1.0.1e ( - rd /s/q openssl-1.0.1d - svn export http://svn.python.org/projects/external/openssl-1.0.1e -) - -@rem tcl/tk -if not exist tcl-8.6.1.0 ( - rd /s/q tcltk tcltk64 tcl-8.5.11.0 tk-8.5.11.0 - svn export http://svn.python.org/projects/external/tcl-8.6.1.0 -) -if not exist tk-8.6.1.0 svn export http://svn.python.org/projects/external/tk-8.6.1.0 - -@rem sqlite3 -if not exist sqlite-3.8.1 ( - rd /s/q sqlite-source-3.7.12 - svn export http://svn.python.org/projects/external/sqlite-3.8.1 -) - -@rem lzma -if not exist xz-5.0.5 ( - rd /s/q xz-5.0.3 - svn export http://svn.python.org/projects/external/xz-5.0.5 -) diff --git a/Tools/buildbot/external.bat b/Tools/buildbot/external.bat index c580a149705f..7a570d92ba12 100644 --- a/Tools/buildbot/external.bat +++ b/Tools/buildbot/external.bat @@ -1,21 +1,2 @@ -@rem Fetches (and builds if necessary) external dependencies - -@rem Assume we start inside the Python source directory -call "Tools\buildbot\external-common.bat" -call "%VS100COMNTOOLS%\vsvars32.bat" - -if not exist tcltk\bin\tcl86tg.dll ( - @rem all and install need to be separate invocations, otherwise nmakehlp is not found on install - cd tcl-8.6.1.0\win - nmake -f makefile.vc DEBUG=1 INSTALLDIR=..\..\tcltk clean all - nmake -f makefile.vc DEBUG=1 INSTALLDIR=..\..\tcltk install - cd ..\.. -) - -if not exist tcltk\bin\tk86tg.dll ( - cd tk-8.6.1.0\win - nmake -f makefile.vc OPTS=noxp DEBUG=1 INSTALLDIR=..\..\tcltk TCLDIR=..\..\tcl-8.6.1.0 clean - nmake -f makefile.vc OPTS=noxp DEBUG=1 INSTALLDIR=..\..\tcltk TCLDIR=..\..\tcl-8.6.1.0 all - nmake -f makefile.vc OPTS=noxp DEBUG=1 INSTALLDIR=..\..\tcltk TCLDIR=..\..\tcl-8.6.1.0 install - cd ..\.. -) +@echo Please use PCbuild\get_externals.bat instead. +@"%~dp0..\..\PCbuild\get_externals.bat" %* diff --git a/Tools/buildbot/test-amd64.bat b/Tools/buildbot/test-amd64.bat index 1bf124cd9215..7a241f50ab9b 100644 --- a/Tools/buildbot/test-amd64.bat +++ b/Tools/buildbot/test-amd64.bat @@ -1,3 +1,7 @@ @rem Used by the buildbot "test" step. -cd PCbuild -call rt.bat -d -q -x64 -uall -rwW -n %1 %2 %3 %4 %5 %6 %7 %8 %9 + +setlocal +rem The following line should be removed before #20035 is closed +set TCL_LIBRARY=%~dp0..\..\externals\tcltk64\lib\tcl8.6 + +call "%~dp0..\..\PCbuild\rt.bat" -d -q -x64 -uall -rwW -n --timeout=3600 %* diff --git a/Tools/buildbot/test.bat b/Tools/buildbot/test.bat index 4f4c6aa9e1f1..6a6448c3ae89 100644 --- a/Tools/buildbot/test.bat +++ b/Tools/buildbot/test.bat @@ -1,3 +1,7 @@ @rem Used by the buildbot "test" step. -cd PCbuild -call rt.bat -d -q -uall -rwW -n %1 %2 %3 %4 %5 %6 %7 %8 %9 + +setlocal +rem The following line should be removed before #20035 is closed +set TCL_LIBRARY=%~dp0..\..\externals\tcltk\lib\tcl8.6 + +call "%~dp0..\..\PCbuild\rt.bat" -d -q -uall -rwW -n --timeout=3600 %* diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py index c332b0cb5a5c..23f664859561 100755 --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -8,20 +8,25 @@ import abc import ast import atexit -import clinic import collections import contextlib +import copy +import cpp import functools import hashlib import inspect import io import itertools import os +import pprint import re import shlex +import string import sys import tempfile import textwrap +import traceback +import uuid # TODO: # @@ -39,6 +44,7 @@ _empty = inspect._empty _void = inspect._void +NoneType = type(None) class Unspecified: def __repr__(self): @@ -54,6 +60,13 @@ def __repr__(self): NULL = Null() +class Unknown: + def __repr__(self): + return '' + +unknown = Unknown() + + def _text_accumulator(): text = [] def output(): @@ -78,14 +91,17 @@ def text_accumulator(): return append, output -def fail(*args, filename=None, line_number=None): +def warn_or_fail(fail=False, *args, filename=None, line_number=None): joined = " ".join([str(a) for a in args]) add, output = text_accumulator() - add("Error") + if fail: + add("Error") + else: + add("Warning") if clinic: if filename is None: filename = clinic.filename - if clinic.block_parser and (line_number is None): + if getattr(clinic, 'block_parser', None) and (line_number is None): line_number = clinic.block_parser.line_number if filename is not None: add(' in file "' + filename + '"') @@ -94,29 +110,42 @@ def fail(*args, filename=None, line_number=None): add(':\n') add(joined) print(output()) - sys.exit(-1) + if fail: + sys.exit(-1) + +def warn(*args, filename=None, line_number=None): + return warn_or_fail(False, *args, filename=filename, line_number=line_number) + +def fail(*args, filename=None, line_number=None): + return warn_or_fail(True, *args, filename=filename, line_number=line_number) def quoted_for_c_string(s): for old, new in ( + ('\\', '\\\\'), # must be first! ('"', '\\"'), ("'", "\\'"), ): s = s.replace(old, new) return s +def c_repr(s): + return '"' + s + '"' + + is_legal_c_identifier = re.compile('^[A-Za-z_][A-Za-z0-9_]*$').match def is_legal_py_identifier(s): return all(is_legal_c_identifier(field) for field in s.split('.')) -# added "module", "self", "cls", and "null" just to be safe -# (clinic will generate variables with these names) +# identifiers that are okay in Python but aren't a good idea in C. +# so if they're used Argument Clinic will add "_value" to the end +# of the name in C. c_keywords = set(""" -asm auto break case char cls const continue default do double -else enum extern float for goto if inline int long module null -register return self short signed sizeof static struct switch +asm auto break case char const continue default do double +else enum extern float for goto if inline int long +register return short signed sizeof static struct switch typedef typeof union unsigned void volatile while """.strip().split()) @@ -144,6 +173,8 @@ def linear_format(s, **kwargs): themselves. (This line is the "source line".) * If the substitution text is empty, the source line is removed in the output. + * If the field is not recognized, the original line + is passed unmodified through to the output. * If the substitution text is not empty: * Each line of the substituted text is indented by the indent of the source line. @@ -179,6 +210,47 @@ def linear_format(s, **kwargs): return output()[:-1] +def indent_all_lines(s, prefix): + """ + Returns 's', with 'prefix' prepended to all lines. + + If the last line is empty, prefix is not prepended + to it. (If s is blank, returns s unchanged.) + + (textwrap.indent only adds to non-blank lines.) + """ + split = s.split('\n') + last = split.pop() + final = [] + for line in split: + final.append(prefix) + final.append(line) + final.append('\n') + if last: + final.append(prefix) + final.append(last) + return ''.join(final) + +def suffix_all_lines(s, suffix): + """ + Returns 's', with 'suffix' appended to all lines. + + If the last line is empty, suffix is not appended + to it. (If s is blank, returns s unchanged.) + """ + split = s.split('\n') + last = split.pop() + final = [] + for line in split: + final.append(line) + final.append(suffix) + final.append('\n') + if last: + final.append(last) + final.append(suffix) + return ''.join(final) + + def version_splitter(s): """Splits a version string into a tuple of integers. @@ -193,7 +265,7 @@ def version_splitter(s): accumulator = [] def flush(): if not accumulator: - raise ValueError('Malformed version string: ' + repr(s)) + raise ValueError('Unsupported version string: ' + repr(s)) version.append(int(''.join(accumulator))) accumulator.clear() @@ -231,6 +303,10 @@ def __init__(self): # Should be full lines with \n eol characters. self.initializers = [] + # The C statements needed to dynamically modify the values + # parsed by the parse call, before calling the impl. + self.modifications = [] + # The entries for the "keywords" array for PyArg_ParseTuple. # Should be individual strings representing the names. self.keywords = [] @@ -262,6 +338,22 @@ def __init__(self): self.cleanup = [] +class FormatCounterFormatter(string.Formatter): + """ + This counts how many instances of each formatter + "replacement string" appear in the format string. + + e.g. after evaluating "string {a}, {b}, {c}, {a}" + the counts dict would now look like + {'a': 2, 'b': 1, 'c': 1} + """ + def __init__(self): + self.counts = collections.Counter() + + def get_value(self, key, args, kwargs): + self.counts[key] += 1 + return '' + class Language(metaclass=abc.ABCMeta): start_line = "" @@ -269,33 +361,80 @@ class Language(metaclass=abc.ABCMeta): stop_line = "" checksum_line = "" + def __init__(self, filename): + pass + @abc.abstractmethod - def render(self, block): + def render(self, clinic, signatures): + pass + + def parse_line(self, line): pass def validate(self): - def assert_only_one(field, token='dsl_name'): - line = getattr(self, field) - token = '{' + token + '}' - if len(line.split(token)) != 2: - fail(self.__class__.__name__ + " " + field + " must contain " + token + " exactly once!") + def assert_only_one(attr, *additional_fields): + """ + Ensures that the string found at getattr(self, attr) + contains exactly one formatter replacement string for + each valid field. The list of valid fields is + ['dsl_name'] extended by additional_fields. + + e.g. + self.fmt = "{dsl_name} {a} {b}" + + # this passes + self.assert_only_one('fmt', 'a', 'b') + + # this fails, the format string has a {b} in it + self.assert_only_one('fmt', 'a') + + # this fails, the format string doesn't have a {c} in it + self.assert_only_one('fmt', 'a', 'b', 'c') + + # this fails, the format string has two {a}s in it, + # it must contain exactly one + self.fmt2 = '{dsl_name} {a} {a}' + self.assert_only_one('fmt2', 'a') + + """ + fields = ['dsl_name'] + fields.extend(additional_fields) + line = getattr(self, attr) + fcf = FormatCounterFormatter() + fcf.format(line) + def local_fail(should_be_there_but_isnt): + if should_be_there_but_isnt: + fail("{} {} must contain {{{}}} exactly once!".format( + self.__class__.__name__, attr, name)) + else: + fail("{} {} must not contain {{{}}}!".format( + self.__class__.__name__, attr, name)) + + for name, count in fcf.counts.items(): + if name in fields: + if count > 1: + local_fail(True) + else: + local_fail(False) + for name in fields: + if fcf.counts.get(name) != 1: + local_fail(True) + assert_only_one('start_line') assert_only_one('stop_line') - assert_only_one('checksum_line') - assert_only_one('checksum_line', 'checksum') - if len(self.body_prefix.split('{dsl_name}')) >= 3: - fail(self.__class__.__name__ + " body_prefix may contain " + token + " once at most!") + field = "arguments" if "{arguments}" in self.checksum_line else "checksum" + assert_only_one('checksum_line', field) class PythonLanguage(Language): language = 'Python' - start_line = "#/*[{dsl_name}]" + start_line = "#/*[{dsl_name} input]" body_prefix = "#" - stop_line = "#[{dsl_name}]*/" - checksum_line = "#/*[{dsl_name} checksum: {checksum}]*/" + stop_line = "#[{dsl_name} start generated code]*/" + checksum_line = "#/*[{dsl_name} end generated code: {arguments}]*/" def permute_left_option_groups(l): @@ -358,22 +497,55 @@ def permute_optional_groups(left, required, right): return tuple(accumulator) +def strip_leading_and_trailing_blank_lines(s): + lines = s.rstrip().split('\n') + while lines: + line = lines[0] + if line.strip(): + break + del lines[0] + return '\n'.join(lines) + +@functools.lru_cache() +def normalize_snippet(s, *, indent=0): + """ + Reformats s: + * removes leading and trailing blank lines + * ensures that it does not end with a newline + * dedents so the first nonwhite character on any line is at column "indent" + """ + s = strip_leading_and_trailing_blank_lines(s) + s = textwrap.dedent(s) + if indent: + s = textwrap.indent(s, ' ' * indent) + return s + + class CLanguage(Language): + body_prefix = "#" language = 'C' - start_line = "/*[{dsl_name}]" + start_line = "/*[{dsl_name} input]" body_prefix = "" - stop_line = "[{dsl_name}]*/" - checksum_line = "/*[{dsl_name} checksum: {checksum}]*/" + stop_line = "[{dsl_name} start generated code]*/" + checksum_line = "/*[{dsl_name} end generated code: {arguments}]*/" - def render(self, signatures): + def __init__(self, filename): + super().__init__(filename) + self.cpp = cpp.Monitor(filename) + self.cpp.fail = fail + + def parse_line(self, line): + self.cpp.writeline(line) + + def render(self, clinic, signatures): function = None for o in signatures: if isinstance(o, Function): if function: fail("You may specify at most one function per block.\nFound a block containing at least two:\n\t" + repr(function) + " and " + repr(o)) function = o - return self.render_function(function) + return self.render_function(clinic, function) def docstring_for_c_string(self, f): text, add, output = _text_accumulator() @@ -387,159 +559,311 @@ def docstring_for_c_string(self, f): add('"') return ''.join(text) - impl_prototype_template = "{c_basename}_impl({impl_parameters})" + def output_templates(self, f): + parameters = list(f.parameters.values()) + assert parameters + assert isinstance(parameters[0].converter, self_converter) + del parameters[0] + converters = [p.converter for p in parameters] - @staticmethod - def template_base(*args): - flags = '|'.join(f for f in args if f) - return """ -PyDoc_STRVAR({c_basename}__doc__, -{docstring}); - -#define {methoddef_name} \\ - {{"{name}", (PyCFunction){c_basename}, {methoddef_flags}, {c_basename}__doc__}}, -""".replace('{methoddef_flags}', flags) - - def meth_noargs_pyobject_template(self, methoddef_flags=""): - return self.template_base("METH_NOARGS", methoddef_flags) + """ -static PyObject * -{c_basename}({impl_parameters}) -""" + has_option_groups = parameters and (parameters[0].group or parameters[-1].group) + default_return_converter = (not f.return_converter or + f.return_converter.type == 'PyObject *') - def meth_noargs_template(self, methoddef_flags=""): - return self.template_base("METH_NOARGS", methoddef_flags) + """ -static {impl_return_type} -{impl_prototype}; + positional = parameters and (parameters[-1].kind == inspect.Parameter.POSITIONAL_ONLY) + all_boring_objects = False # yes, this will be false if there are 0 parameters, it's fine + first_optional = len(parameters) + for i, p in enumerate(parameters): + c = p.converter + if type(c) != object_converter: + break + if c.format_unit != 'O': + break + if p.default is not unspecified: + first_optional = min(first_optional, i) + else: + all_boring_objects = True -static PyObject * -{c_basename}({self_type}{self_name}) -{{ - PyObject *return_value = NULL; - {declarations} - {initializers} + new_or_init = f.kind in (METHOD_NEW, METHOD_INIT) - {return_value} = {c_basename}_impl({impl_arguments}); - {return_conversion} + meth_o = (len(parameters) == 1 and + parameters[0].kind == inspect.Parameter.POSITIONAL_ONLY and + not converters[0].is_optional() and + isinstance(converters[0], object_converter) and + converters[0].format_unit == 'O' and + not new_or_init) -{exit_label} - {cleanup} - return return_value; -}} + # we have to set these things before we're done: + # + # docstring_prototype + # docstring_definition + # impl_prototype + # methoddef_define + # parser_prototype + # parser_definition + # impl_definition + # cpp_if + # cpp_endif + # methoddef_ifndef + + return_value_declaration = "PyObject *return_value = NULL;" + + methoddef_define = normalize_snippet(""" + #define {methoddef_name} \\ + {{"{name}", (PyCFunction){c_basename}, {methoddef_flags}, {c_basename}__doc__}}, + """) + if new_or_init and not f.docstring: + docstring_prototype = docstring_definition = '' + else: + docstring_prototype = normalize_snippet(""" + PyDoc_VAR({c_basename}__doc__); + """) + docstring_definition = normalize_snippet(""" + PyDoc_STRVAR({c_basename}__doc__, + {docstring}); + """) + impl_definition = normalize_snippet(""" + static {impl_return_type} + {c_basename}_impl({impl_parameters}) + """) + impl_prototype = parser_prototype = parser_definition = None + + parser_prototype_keyword = normalize_snippet(""" + static PyObject * + {c_basename}({self_type}{self_name}, PyObject *args, PyObject *kwargs) + """) + + parser_prototype_varargs = normalize_snippet(""" + static PyObject * + {c_basename}({self_type}{self_name}, PyObject *args) + """) + + # parser_body_fields remembers the fields passed in to the + # previous call to parser_body. this is used for an awful hack. + parser_body_fields = () + def parser_body(prototype, *fields): + nonlocal parser_body_fields + add, output = text_accumulator() + add(prototype) + parser_body_fields = fields + + fields = list(fields) + fields.insert(0, normalize_snippet(""" + {{ + {return_value_declaration} + {declarations} + {initializers} + """) + "\n") + # just imagine--your code is here in the middle + fields.append(normalize_snippet(""" + {modifications} + {return_value} = {c_basename}_impl({impl_arguments}); + {return_conversion} + + {exit_label} + {cleanup} + return return_value; + }} + """)) + for field in fields: + add('\n') + add(field) + return output() -static {impl_return_type} -{impl_prototype} -""" + def insert_keywords(s): + return linear_format(s, declarations="static char *_keywords[] = {{{keywords}, NULL}};\n{declarations}") - def meth_o_template(self, methoddef_flags=""): - return self.template_base("METH_O", methoddef_flags) + """ -static PyObject * -{c_basename}({impl_parameters}) -""" + if not parameters: + # no parameters, METH_NOARGS - def meth_o_return_converter_template(self, methoddef_flags=""): - return self.template_base("METH_O", methoddef_flags) + """ -static {impl_return_type} -{impl_prototype}; - -static PyObject * -{c_basename}({impl_parameters}) -{{ - PyObject *return_value = NULL; - {declarations} - {initializers} - _return_value = {c_basename}_impl({impl_arguments}); - {return_conversion} - -{exit_label} - {cleanup} - return return_value; -}} - -static {impl_return_type} -{impl_prototype} -""" + flags = "METH_NOARGS" - def option_group_template(self, methoddef_flags=""): - return self.template_base("METH_VARARGS", methoddef_flags) + """ -static {impl_return_type} -{impl_prototype}; - -static PyObject * -{c_basename}({self_type}{self_name}, PyObject *args) -{{ - PyObject *return_value = NULL; - {declarations} - {initializers} - - {option_group_parsing} - {return_value} = {c_basename}_impl({impl_arguments}); - {return_conversion} - -{exit_label} - {cleanup} - return return_value; -}} - -static {impl_return_type} -{impl_prototype} -""" + parser_prototype = normalize_snippet(""" + static PyObject * + {c_basename}({self_type}{self_name}, PyObject *Py_UNUSED(ignored)) + """) + parser_definition = parser_prototype - def keywords_template(self, methoddef_flags=""): - return self.template_base("METH_VARARGS|METH_KEYWORDS", methoddef_flags) + """ -static {impl_return_type} -{impl_prototype}; - -static PyObject * -{c_basename}({self_type}{self_name}, PyObject *args, PyObject *kwargs) -{{ - PyObject *return_value = NULL; - static char *_keywords[] = {{{keywords}, NULL}}; - {declarations} - {initializers} - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, - "{format_units}:{name}", _keywords, - {parse_arguments})) - goto exit; - {return_value} = {c_basename}_impl({impl_arguments}); - {return_conversion} - -{exit_label} - {cleanup} - return return_value; -}} - -static {impl_return_type} -{impl_prototype} -""" + if default_return_converter: + parser_definition = parser_prototype + '\n' + normalize_snippet(""" + {{ + return {c_basename}_impl({impl_arguments}); + }} + """) + else: + parser_definition = parser_body(parser_prototype) - def positional_only_template(self, methoddef_flags=""): - return self.template_base("METH_VARARGS", methoddef_flags) + """ -static {impl_return_type} -{impl_prototype}; - -static PyObject * -{c_basename}({self_type}{self_name}, PyObject *args) -{{ - PyObject *return_value = NULL; - {declarations} - {initializers} - - if (!PyArg_ParseTuple(args, - "{format_units}:{name}", - {parse_arguments})) - goto exit; - {return_value} = {c_basename}_impl({impl_arguments}); - {return_conversion} - -{exit_label} - {cleanup} - return return_value; -}} - -static {impl_return_type} -{impl_prototype} -""" + elif meth_o: + flags = "METH_O" + + meth_o_prototype = normalize_snippet(""" + static PyObject * + {c_basename}({impl_parameters}) + """) + + if default_return_converter: + # maps perfectly to METH_O, doesn't need a return converter. + # so we skip making a parse function + # and call directly into the impl function. + impl_prototype = parser_prototype = parser_definition = '' + impl_definition = meth_o_prototype + else: + # SLIGHT HACK + # use impl_parameters for the parser here! + parser_prototype = meth_o_prototype + parser_definition = parser_body(parser_prototype) + + elif has_option_groups: + # positional parameters with option groups + # (we have to generate lots of PyArg_ParseTuple calls + # in a big switch statement) + + flags = "METH_VARARGS" + parser_prototype = parser_prototype_varargs + + parser_definition = parser_body(parser_prototype, ' {option_group_parsing}') + + elif positional and all_boring_objects: + # positional-only, but no option groups, + # and nothing but normal objects: + # PyArg_UnpackTuple! + + flags = "METH_VARARGS" + parser_prototype = parser_prototype_varargs + + parser_definition = parser_body(parser_prototype, normalize_snippet(""" + if (!PyArg_UnpackTuple(args, "{name}", + {unpack_min}, {unpack_max}, + {parse_arguments})) + goto exit; + """, indent=4)) + + elif positional: + # positional-only, but no option groups + # we only need one call to PyArg_ParseTuple + + flags = "METH_VARARGS" + parser_prototype = parser_prototype_varargs + + parser_definition = parser_body(parser_prototype, normalize_snippet(""" + if (!PyArg_ParseTuple(args, + "{format_units}:{name}", + {parse_arguments})) + goto exit; + """, indent=4)) + + else: + # positional-or-keyword arguments + flags = "METH_VARARGS|METH_KEYWORDS" + + parser_prototype = parser_prototype_keyword + + body = normalize_snippet(""" + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "{format_units}:{name}", _keywords, + {parse_arguments})) + goto exit; + """, indent=4) + parser_definition = parser_body(parser_prototype, normalize_snippet(""" + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "{format_units}:{name}", _keywords, + {parse_arguments})) + goto exit; + """, indent=4)) + parser_definition = insert_keywords(parser_definition) + + + if new_or_init: + methoddef_define = '' + + if f.kind == METHOD_NEW: + parser_prototype = parser_prototype_keyword + else: + return_value_declaration = "int return_value = -1;" + parser_prototype = normalize_snippet(""" + static int + {c_basename}({self_type}{self_name}, PyObject *args, PyObject *kwargs) + """) + + fields = list(parser_body_fields) + parses_positional = 'METH_NOARGS' not in flags + parses_keywords = 'METH_KEYWORDS' in flags + if parses_keywords: + assert parses_positional + + if not parses_keywords: + fields.insert(0, normalize_snippet(""" + if ({self_type_check}!_PyArg_NoKeywords("{name}", kwargs)) + goto exit; + """, indent=4)) + if not parses_positional: + fields.insert(0, normalize_snippet(""" + if ({self_type_check}!_PyArg_NoPositional("{name}", args)) + goto exit; + """, indent=4)) + + parser_definition = parser_body(parser_prototype, *fields) + if parses_keywords: + parser_definition = insert_keywords(parser_definition) + + + if f.methoddef_flags: + flags += '|' + f.methoddef_flags + + methoddef_define = methoddef_define.replace('{methoddef_flags}', flags) + + methoddef_ifndef = '' + conditional = self.cpp.condition() + if not conditional: + cpp_if = cpp_endif = '' + else: + cpp_if = "#if " + conditional + cpp_endif = "#endif /* " + conditional + " */" + + if methoddef_define: + methoddef_ifndef = normalize_snippet(""" + #ifndef {methoddef_name} + #define {methoddef_name} + #endif /* !defined({methoddef_name}) */ + """) + + + # add ';' to the end of parser_prototype and impl_prototype + # (they mustn't be None, but they could be an empty string.) + assert parser_prototype is not None + if parser_prototype: + assert not parser_prototype.endswith(';') + parser_prototype += ';' + + if impl_prototype is None: + impl_prototype = impl_definition + if impl_prototype: + impl_prototype += ";" + + parser_definition = parser_definition.replace("{return_value_declaration}", return_value_declaration) + + d = { + "docstring_prototype" : docstring_prototype, + "docstring_definition" : docstring_definition, + "impl_prototype" : impl_prototype, + "methoddef_define" : methoddef_define, + "parser_prototype" : parser_prototype, + "parser_definition" : parser_definition, + "impl_definition" : impl_definition, + "cpp_if" : cpp_if, + "cpp_endif" : cpp_endif, + "methoddef_ifndef" : methoddef_ifndef, + } + + # make sure we didn't forget to assign something, + # and wrap each non-empty value in \n's + d2 = {} + for name, value in d.items(): + assert value is not None, "got a None value for template " + repr(name) + if value: + value = '\n' + value + '\n' + d2[name] = value + return d2 @staticmethod def group_to_variable_name(group): @@ -567,6 +891,8 @@ def render_option_group_parsing(self, f, template_dict): add, output = text_accumulator() parameters = list(f.parameters.values()) + if isinstance(parameters[0].converter, self_converter): + del parameters[0] groups = [] group = None @@ -591,12 +917,18 @@ def render_option_group_parsing(self, f, template_dict): count_min = sys.maxsize count_max = -1 - add("switch (PyTuple_Size(args)) {{\n") + add("switch (PyTuple_GET_SIZE(args)) {{\n") for subset in permute_optional_groups(left, required, right): count = len(subset) count_min = min(count_min, count) count_max = max(count_max, count) + if count == 0: + add(""" case 0: + break; +""") + continue + group_ids = {p.group for p in subset} # eliminate duplicates d = {} d['count'] = count @@ -616,7 +948,7 @@ def render_option_group_parsing(self, f, template_dict): s = """ case {count}: if (!PyArg_ParseTuple(args, "{format_units}:{name}", {parse_arguments})) - return NULL; + goto exit; {group_booleans} break; """[1:] @@ -627,29 +959,90 @@ def render_option_group_parsing(self, f, template_dict): add(" default:\n") s = ' PyErr_SetString(PyExc_TypeError, "{} requires {} to {} arguments");\n' add(s.format(f.full_name, count_min, count_max)) - add(' return NULL;\n') + add(' goto exit;\n') add("}}") template_dict['option_group_parsing'] = output() - def render_function(self, f): + def render_function(self, clinic, f): if not f: return "" add, output = text_accumulator() data = CRenderData() - parameters = list(f.parameters.values()) + assert f.parameters, "We should always have a 'self' at this point!" + parameters = f.render_parameters converters = [p.converter for p in parameters] + templates = self.output_templates(f) + + f_self = parameters[0] + selfless = parameters[1:] + assert isinstance(f_self.converter, self_converter), "No self parameter in " + repr(f.full_name) + "!" + + last_group = 0 + first_optional = len(selfless) + positional = selfless and selfless[-1].kind == inspect.Parameter.POSITIONAL_ONLY + new_or_init = f.kind in (METHOD_NEW, METHOD_INIT) + default_return_converter = (not f.return_converter or + f.return_converter.type == 'PyObject *') + has_option_groups = False + + # offset i by -1 because first_optional needs to ignore self + for i, p in enumerate(parameters, -1): + c = p.converter + + if (i != -1) and (p.default is not unspecified): + first_optional = min(first_optional, i) + + # insert group variable + group = p.group + if last_group != group: + last_group = group + if group: + group_name = self.group_to_variable_name(group) + data.impl_arguments.append(group_name) + data.declarations.append("int " + group_name + " = 0;") + data.impl_parameters.append("int " + group_name) + has_option_groups = True + + c.render(p, data) + + if has_option_groups and (not positional): + fail("You cannot use optional groups ('[' and ']')\nunless all parameters are positional-only ('/').") + + # HACK + # when we're METH_O, but have a custom return converter, + # we use "impl_parameters" for the parsing function + # because that works better. but that means we must + # suppress actually declaring the impl's parameters + # as variables in the parsing function. but since it's + # METH_O, we have exactly one anyway, so we know exactly + # where it is. + if ("METH_O" in templates['methoddef_define'] and + not default_return_converter): + data.declarations.pop(0) + template_dict = {} full_name = f.full_name template_dict['full_name'] = full_name - name = full_name.rpartition('.')[2] + if new_or_init: + name = f.cls.name + else: + name = f.name + template_dict['name'] = name - c_basename = f.c_basename or full_name.replace(".", "_") + if f.c_basename: + c_basename = f.c_basename + else: + fields = full_name.split(".") + if fields[-1] == '__new__': + fields.pop() + c_basename = "_".join(fields) + template_dict['c_basename'] = c_basename methoddef_name = "{}_METHODDEF".format(c_basename.upper()) @@ -657,47 +1050,15 @@ def render_function(self, f): template_dict['docstring'] = self.docstring_for_c_string(f) - positional = has_option_groups = False - - if parameters: - last_group = 0 - - for p in parameters: - c = p.converter - - # insert group variable - group = p.group - if last_group != group: - last_group = group - if group: - group_name = self.group_to_variable_name(group) - data.impl_arguments.append(group_name) - data.declarations.append("int " + group_name + " = 0;") - data.impl_parameters.append("int " + group_name) - has_option_groups = True - c.render(p, data) - - positional = parameters[-1].kind == inspect.Parameter.POSITIONAL_ONLY - if has_option_groups: - assert positional - - # now insert our "self" (or whatever) parameters - # (we deliberately don't call render on self converters) - stock_self = self_converter('self', f) - template_dict['self_name'] = stock_self.name - template_dict['self_type'] = stock_self.type - data.impl_parameters.insert(0, f.self_converter.type + ("" if f.self_converter.type.endswith('*') else " ") + f.self_converter.name) - if f.self_converter.type != stock_self.type: - self_cast = '(' + f.self_converter.type + ')' - else: - self_cast = '' - data.impl_arguments.insert(0, self_cast + stock_self.name) + template_dict['self_name'] = template_dict['self_type'] = template_dict['self_type_check'] = '' + f_self.converter.set_template_dict(template_dict) f.return_converter.render(f, data) template_dict['impl_return_type'] = f.return_converter.type template_dict['declarations'] = "\n".join(data.declarations) template_dict['initializers'] = "\n\n".join(data.initializers) + template_dict['modifications'] = '\n\n'.join(data.modifications) template_dict['keywords'] = '"' + '", "'.join(data.keywords) + '"' template_dict['format_units'] = ''.join(data.format_units) template_dict['parse_arguments'] = ', '.join(data.parse_arguments) @@ -707,66 +1068,48 @@ def render_function(self, f): template_dict['cleanup'] = "".join(data.cleanup) template_dict['return_value'] = data.return_value - template_dict['impl_prototype'] = self.impl_prototype_template.format_map(template_dict) + # used by unpack tuple code generator + ignore_self = -1 if isinstance(converters[0], self_converter) else 0 + unpack_min = first_optional + unpack_max = len(selfless) + template_dict['unpack_min'] = str(unpack_min) + template_dict['unpack_max'] = str(unpack_max) - default_return_converter = (not f.return_converter or - f.return_converter.type == 'PyObject *') - - if not parameters: - if default_return_converter: - template = self.meth_noargs_pyobject_template(f.methoddef_flags) - else: - template = self.meth_noargs_template(f.methoddef_flags) - elif (len(parameters) == 1 and - parameters[0].kind == inspect.Parameter.POSITIONAL_ONLY and - not converters[0].is_optional() and - isinstance(converters[0], object_converter) and - converters[0].format_unit == 'O'): - if default_return_converter: - template = self.meth_o_template(f.methoddef_flags) - else: - # HACK - # we're using "impl_parameters" for the - # non-impl function, because that works - # better for METH_O. but that means we - # must supress actually declaring the - # impl's parameters as variables in the - # non-impl. but since it's METH_O, we - # only have one anyway, so - # we don't have any problem finding it. - declarations_copy = list(data.declarations) - before, pyobject, after = declarations_copy[0].partition('PyObject *') - assert not before, "hack failed, see comment" - assert pyobject, "hack failed, see comment" - assert after and after[0].isalpha(), "hack failed, see comment" - del declarations_copy[0] - template_dict['declarations'] = "\n".join(declarations_copy) - template = self.meth_o_return_converter_template(f.methoddef_flags) - elif has_option_groups: + if has_option_groups: self.render_option_group_parsing(f, template_dict) - template = self.option_group_template(f.methoddef_flags) + + for name, destination in clinic.field_destinations.items(): + template = templates[name] + if has_option_groups: + template = linear_format(template, + option_group_parsing=template_dict['option_group_parsing']) template = linear_format(template, - option_group_parsing=template_dict['option_group_parsing']) - elif positional: - template = self.positional_only_template(f.methoddef_flags) - else: - template = self.keywords_template(f.methoddef_flags) + declarations=template_dict['declarations'], + return_conversion=template_dict['return_conversion'], + initializers=template_dict['initializers'], + modifications=template_dict['modifications'], + cleanup=template_dict['cleanup'], + ) + + # Only generate the "exit:" label + # if we have any gotos + need_exit_label = "goto exit;" in template + template = linear_format(template, + exit_label="exit:" if need_exit_label else '' + ) + + s = template.format_map(template_dict) - template = linear_format(template, - declarations=template_dict['declarations'], - return_conversion=template_dict['return_conversion'], - initializers=template_dict['initializers'], - cleanup=template_dict['cleanup'], - ) + if clinic.line_prefix: + s = indent_all_lines(s, clinic.line_prefix) + if clinic.line_suffix: + s = suffix_all_lines(s, clinic.line_suffix) + + destination.append(s) + + return clinic.get_destination('block').dump() - # Only generate the "exit:" label - # if we have any gotos - need_exit_label = "goto exit;" in template - template = linear_format(template, - exit_label="exit:" if need_exit_label else '' - ) - return template.format_map(template_dict) @contextlib.contextmanager @@ -780,10 +1123,14 @@ def OverrideStdioWith(stdout): sys.stdout = saved_stdout -def create_regex(before, after): +def create_regex(before, after, word=True, whole_line=True): """Create an re object for matching marker lines.""" - pattern = r'^{}(\w+){}$' - return re.compile(pattern.format(re.escape(before), re.escape(after))) + group_re = "\w+" if word else ".+" + pattern = r'{}({}){}' + if whole_line: + pattern = '^' + pattern + '$' + pattern = pattern.format(re.escape(before), group_re, re.escape(after)) + return re.compile(pattern) class Block: @@ -841,6 +1188,16 @@ def __init__(self, input, dsl_name=None, signatures=None, output=None, indent='' self.indent = indent self.preindent = preindent + def __repr__(self): + dsl_name = self.dsl_name or "text" + def summarize(s): + s = repr(s) + if len(s) > 30: + return s[:26] + "..." + s[0] + return s + return "".join(( + "")) + class BlockParser: """ @@ -863,32 +1220,44 @@ def __init__(self, input, language, *, verify=True): self.language = language before, _, after = language.start_line.partition('{dsl_name}') assert _ == '{dsl_name}' + self.find_start_re = create_regex(before, after, whole_line=False) self.start_re = create_regex(before, after) self.verify = verify self.last_checksum_re = None self.last_dsl_name = None self.dsl_name = None + self.first_block = True def __iter__(self): return self def __next__(self): - if not self.input: - raise StopIteration + while True: + if not self.input: + raise StopIteration + + if self.dsl_name: + return_value = self.parse_clinic_block(self.dsl_name) + self.dsl_name = None + self.first_block = False + return return_value + block = self.parse_verbatim_block() + if self.first_block and not block.input: + continue + self.first_block = False + return block - if self.dsl_name: - return_value = self.parse_clinic_block(self.dsl_name) - self.dsl_name = None - return return_value - return self.parse_verbatim_block() def is_start_line(self, line): match = self.start_re.match(line.lstrip()) return match.group(1) if match else None - def _line(self): + def _line(self, lookahead=False): self.line_number += 1 - return self.input.pop() + line = self.input.pop() + if not lookahead: + self.language.parse_line(line) + return line def parse_verbatim_block(self): add, output = text_accumulator() @@ -907,13 +1276,21 @@ def parse_verbatim_block(self): def parse_clinic_block(self, dsl_name): input_add, input_output = text_accumulator() self.block_start_line_number = self.line_number + 1 - stop_line = self.language.stop_line.format(dsl_name=dsl_name) + '\n' + stop_line = self.language.stop_line.format(dsl_name=dsl_name) body_prefix = self.language.body_prefix.format(dsl_name=dsl_name) + def is_stop_line(line): + # make sure to recognize stop line even if it + # doesn't end with EOL (it could be the very end of the file) + if not line.startswith(stop_line): + return False + remainder = line[len(stop_line):] + return (not remainder) or remainder.isspace() + # consume body of program while self.input: line = self._line() - if line == stop_line or self.is_start_line(line): + if is_stop_line(line) or self.is_start_line(line): break if body_prefix: line = line.lstrip() @@ -925,35 +1302,54 @@ def parse_clinic_block(self, dsl_name): if self.last_dsl_name == dsl_name: checksum_re = self.last_checksum_re else: - before, _, after = self.language.checksum_line.format(dsl_name=dsl_name, checksum='{checksum}').partition('{checksum}') - assert _ == '{checksum}' - checksum_re = create_regex(before, after) + before, _, after = self.language.checksum_line.format(dsl_name=dsl_name, arguments='{arguments}').partition('{arguments}') + assert _ == '{arguments}' + checksum_re = create_regex(before, after, word=False) self.last_dsl_name = dsl_name self.last_checksum_re = checksum_re # scan forward for checksum line output_add, output_output = text_accumulator() - checksum = None + arguments = None while self.input: - line = self._line() + line = self._line(lookahead=True) match = checksum_re.match(line.lstrip()) - checksum = match.group(1) if match else None - if checksum: + arguments = match.group(1) if match else None + if arguments: break output_add(line) if self.is_start_line(line): break output = output_output() - if checksum: + if arguments: + d = {} + for field in shlex.split(arguments): + name, equals, value = field.partition('=') + if not equals: + fail("Mangled Argument Clinic marker line: {!r}".format(line)) + d[name.strip()] = value.strip() + if self.verify: - computed = compute_checksum(output) + if 'input' in d: + checksum = d['output'] + input_checksum = d['input'] + else: + checksum = d['checksum'] + input_checksum = None + + computed = compute_checksum(output, len(checksum)) if checksum != computed: - fail("Checksum mismatch!\nExpected: {}\nComputed: {}".format(checksum, computed)) + fail("Checksum mismatch!\nExpected: {}\nComputed: {}\n" + "Suggested fix: remove all generated code including " + "the end marker,\n" + "or use the '-f' option." + .format(checksum, computed)) else: # put back output - self.input.extend(reversed(output.splitlines(keepends=True))) - self.line_number -= len(output) + output_lines = output.splitlines(keepends=True) + self.line_number -= len(output_lines) + self.input.extend(reversed(output_lines)) output = None return Block(input_output(), dsl_name, output=output) @@ -992,21 +1388,77 @@ def print_block(self, block): write(self.language.stop_line.format(dsl_name=dsl_name)) write("\n") - output = block.output + input = ''.join(block.input) + output = ''.join(block.output) if output: - write(output) if not output.endswith('\n'): - write('\n') + output += '\n' + write(output) - write(self.language.checksum_line.format(dsl_name=dsl_name, checksum=compute_checksum(output))) + arguments="output={} input={}".format(compute_checksum(output, 16), compute_checksum(input, 16)) + write(self.language.checksum_line.format(dsl_name=dsl_name, arguments=arguments)) write("\n") + def write(self, text): + self.f.write(text) + + +class Destination: + def __init__(self, name, type, clinic, *args): + self.name = name + self.type = type + self.clinic = clinic + valid_types = ('buffer', 'file', 'suppress', 'two-pass') + if type not in valid_types: + fail("Invalid destination type " + repr(type) + " for " + name + " , must be " + ', '.join(valid_types)) + extra_arguments = 1 if type == "file" else 0 + if len(args) < extra_arguments: + fail("Not enough arguments for destination " + name + " new " + type) + if len(args) > extra_arguments: + fail("Too many arguments for destination " + name + " new " + type) + if type =='file': + d = {} + filename = clinic.filename + d['path'] = filename + dirname, basename = os.path.split(filename) + if not dirname: + dirname = '.' + d['dirname'] = dirname + d['basename'] = basename + d['basename_root'], d['basename_extension'] = os.path.splitext(filename) + self.filename = args[0].format_map(d) + if type == 'two-pass': + self.id = None + + self.text, self.append, self._dump = _text_accumulator() + + def __repr__(self): + if self.type == 'file': + file_repr = " " + repr(self.filename) + else: + file_repr = '' + return "".join(("")) + + def clear(self): + if self.type != 'buffer': + fail("Can't clear destination" + self.name + " , it's not of type buffer") + self.text.clear() + + def dump(self): + if self.type == 'two-pass': + if self.id is None: + self.id = str(uuid.uuid4()) + return self.id + fail("You can only dump a two-pass buffer exactly once!") + return self._dump() + # maps strings to Language objects. # "languages" maps the name of the language ("C", "Python"). # "extensions" maps the file extension ("c", "py"). languages = { 'C': CLanguage, 'Python': PythonLanguage } -extensions = { 'c': CLanguage, 'h': CLanguage, 'py': PythonLanguage } +extensions = { name: CLanguage for name in "c cc cpp cxx h hh hpp hxx".split() } +extensions['py'] = PythonLanguage # maps strings to callables. @@ -1031,21 +1483,135 @@ def print_block(self, block): # The callable should not call builtins.print. return_converters = {} +clinic = None class Clinic: - def __init__(self, language, printer=None, *, verify=True, filename=None): + + presets_text = """ +preset block +everything block +docstring_prototype suppress +parser_prototype suppress +cpp_if suppress +cpp_endif suppress +methoddef_ifndef buffer + +preset original +everything block +docstring_prototype suppress +parser_prototype suppress +cpp_if suppress +cpp_endif suppress +methoddef_ifndef buffer + +preset file +everything file +docstring_prototype suppress +parser_prototype suppress +impl_definition block + +preset buffer +everything buffer +docstring_prototype suppress +impl_prototype suppress +parser_prototype suppress +impl_definition block + +preset partial-buffer +everything buffer +docstring_prototype block +impl_prototype suppress +methoddef_define block +parser_prototype block +impl_definition block + +preset two-pass +everything buffer +docstring_prototype two-pass +impl_prototype suppress +methoddef_define two-pass +parser_prototype two-pass +impl_definition block + +""" + + def __init__(self, language, printer=None, *, force=False, verify=True, filename=None): # maps strings to Parser objects. # (instantiated from the "parsers" global.) self.parsers = {} self.language = language + if printer: + fail("Custom printers are broken right now") self.printer = printer or BlockPrinter(language) self.verify = verify + self.force = force self.filename = filename self.modules = collections.OrderedDict() self.classes = collections.OrderedDict() + self.functions = [] + + self.line_prefix = self.line_suffix = '' + + self.destinations = {} + self.add_destination("block", "buffer") + self.add_destination("suppress", "suppress") + self.add_destination("buffer", "buffer") + self.add_destination("two-pass", "two-pass") + if filename: + self.add_destination("file", "file", "{dirname}/clinic/{basename}.h") + + d = self.destinations.get + self.field_destinations = collections.OrderedDict(( + ('cpp_if', d('suppress')), + ('docstring_prototype', d('suppress')), + ('docstring_definition', d('block')), + ('methoddef_define', d('block')), + ('impl_prototype', d('block')), + ('parser_prototype', d('suppress')), + ('parser_definition', d('block')), + ('cpp_endif', d('suppress')), + ('methoddef_ifndef', d('buffer')), + ('impl_definition', d('block')), + )) + + self.field_destinations_stack = [] + + self.presets = {} + preset = None + for line in self.presets_text.strip().split('\n'): + line = line.strip() + if not line: + continue + name, value = line.split() + if name == 'preset': + self.presets[value] = preset = collections.OrderedDict() + continue + + destination = self.get_destination(value) + + if name == 'everything': + for name in self.field_destinations: + preset[name] = destination + continue + + assert name in self.field_destinations + preset[name] = destination global clinic clinic = self + def get_destination(self, name, default=unspecified): + d = self.destinations.get(name) + if not d: + if default is not unspecified: + return default + fail("Destination does not exist: " + repr(name)) + return d + + def add_destination(self, name, type, *args): + if name in self.destinations: + fail("Destination already exists: " + repr(name)) + self.destinations[name] = Destination(name, type, self, *args) + def parse(self, input): printer = self.printer self.block_parser = BlockParser(input, self.language, verify=self.verify) @@ -1056,9 +1622,81 @@ def parse(self, input): assert dsl_name in parsers, "No parser to handle {!r} block.".format(dsl_name) self.parsers[dsl_name] = parsers[dsl_name](self) parser = self.parsers[dsl_name] - parser.parse(block) + try: + parser.parse(block) + except Exception: + fail('Exception raised during parsing:\n' + + traceback.format_exc().rstrip()) printer.print_block(block) - return printer.f.getvalue() + + second_pass_replacements = {} + + for name, destination in self.destinations.items(): + if destination.type == 'suppress': + continue + output = destination._dump() + + if destination.type == 'two-pass': + if destination.id: + second_pass_replacements[destination.id] = output + elif output: + fail("Two-pass buffer " + repr(name) + " not empty at end of file!") + continue + + if output: + + block = Block("", dsl_name="clinic", output=output) + + if destination.type == 'buffer': + block.input = "dump " + name + "\n" + warn("Destination buffer " + repr(name) + " not empty at end of file, emptying.") + printer.write("\n") + printer.print_block(block) + continue + + if destination.type == 'file': + try: + dirname = os.path.dirname(destination.filename) + try: + os.makedirs(dirname) + except FileExistsError: + if not os.path.isdir(dirname): + fail("Can't write to destination {}, " + "can't make directory {}!".format( + destination.filename, dirname)) + if self.verify: + with open(destination.filename, "rt") as f: + parser_2 = BlockParser(f.read(), language=self.language) + blocks = list(parser_2) + if (len(blocks) != 1) or (blocks[0].input != 'preserve\n'): + fail("Modified destination file " + repr(destination.filename) + ", not overwriting!") + except FileNotFoundError: + pass + + block.input = 'preserve\n' + printer_2 = BlockPrinter(self.language) + printer_2.print_block(block) + with open(destination.filename, "wt") as f: + f.write(printer_2.f.getvalue()) + continue + text = printer.f.getvalue() + + if second_pass_replacements: + printer_2 = BlockPrinter(self.language) + parser_2 = BlockParser(text, self.language) + changed = False + for block in parser_2: + if block.dsl_name: + for id, replacement in second_pass_replacements.items(): + if id in block.output: + changed = True + block.output = block.output.replace(id, replacement) + printer_2.print_block(block) + if changed: + text = printer_2.f.getvalue() + + return text + def _module_and_class(self, fields): """ @@ -1091,23 +1729,27 @@ def _module_and_class(self, fields): return module, cls -def parse_file(filename, *, verify=True, output=None, encoding='utf-8'): +def parse_file(filename, *, force=False, verify=True, output=None, encoding='utf-8'): extension = os.path.splitext(filename)[1][1:] if not extension: fail("Can't extract file type for file " + repr(filename)) try: - language = extensions[extension]() + language = extensions[extension](filename) except KeyError: fail("Can't identify file type for file " + repr(filename)) - clinic = Clinic(language, verify=verify, filename=filename) - with open(filename, 'r', encoding=encoding) as f: raw = f.read() + # exit quickly if there are no clinic markers in the file + find_start_re = BlockParser("", language).find_start_re + if not find_start_re.search(raw): + return + + clinic = Clinic(language, force=force, verify=verify, filename=filename) cooked = clinic.parse(raw) - if cooked == raw: + if (cooked == raw) and not force: return directory = os.path.dirname(filename) or '.' @@ -1120,9 +1762,12 @@ def parse_file(filename, *, verify=True, output=None, encoding='utf-8'): os.replace(tmpfilename, output or filename) -def compute_checksum(input): +def compute_checksum(input, length=None): input = input or '' - return hashlib.sha1(input.encode('utf-8')).hexdigest() + s = hashlib.sha1(input.encode('utf-8')).hexdigest() + if length: + s = s[:length] + return s @@ -1151,10 +1796,12 @@ def __repr__(self): return "" class Class: - def __init__(self, name, module=None, cls=None): + def __init__(self, name, module=None, cls=None, typedef=None, type_object=None): self.name = name self.module = module self.cls = cls + self.typedef = typedef + self.type_object = type_object self.parent = cls or module self.classes = collections.OrderedDict() @@ -1163,8 +1810,83 @@ def __init__(self, name, module=None, cls=None): def __repr__(self): return "" +unsupported_special_methods = set(""" + +__abs__ +__add__ +__and__ +__bytes__ +__call__ +__complex__ +__delitem__ +__divmod__ +__eq__ +__float__ +__floordiv__ +__ge__ +__getattr__ +__getattribute__ +__getitem__ +__gt__ +__hash__ +__iadd__ +__iand__ +__idivmod__ +__ifloordiv__ +__ilshift__ +__imod__ +__imul__ +__index__ +__int__ +__invert__ +__ior__ +__ipow__ +__irshift__ +__isub__ +__iter__ +__itruediv__ +__ixor__ +__le__ +__len__ +__lshift__ +__lt__ +__mod__ +__mul__ +__neg__ +__new__ +__next__ +__or__ +__pos__ +__pow__ +__radd__ +__rand__ +__rdivmod__ +__repr__ +__rfloordiv__ +__rlshift__ +__rmod__ +__rmul__ +__ror__ +__round__ +__rpow__ +__rrshift__ +__rshift__ +__rsub__ +__rtruediv__ +__rxor__ +__setattr__ +__setitem__ +__str__ +__sub__ +__truediv__ +__xor__ + +""".strip().split()) -DATA, CALLABLE, METHOD, STATIC_METHOD, CLASS_METHOD = range(5) + +INVALID, CALLABLE, STATIC_METHOD, CLASS_METHOD, METHOD_INIT, METHOD_NEW = """ +INVALID, CALLABLE, STATIC_METHOD, CLASS_METHOD, METHOD_INIT, METHOD_NEW +""".replace(",", "").strip().split() class Function: """ @@ -1182,7 +1904,8 @@ def __init__(self, parameters=None, *, name, module, cls=None, c_basename=None, full_name=None, return_converter, return_annotation=_empty, - docstring=None, kind=CALLABLE, coexist=False): + docstring=None, kind=CALLABLE, coexist=False, + docstring_only=False): self.parameters = parameters or collections.OrderedDict() self.return_annotation = return_annotation self.name = name @@ -1196,9 +1919,29 @@ def __init__(self, parameters=None, *, name, self.kind = kind self.coexist = coexist self.self_converter = None + # docstring_only means "don't generate a machine-readable + # signature, just a normal docstring". it's True for + # functions with optional groups because we can't represent + # those accurately with inspect.Signature in 3.4. + self.docstring_only = docstring_only + + self.rendered_parameters = None + + __render_parameters__ = None + @property + def render_parameters(self): + if not self.__render_parameters__: + self.__render_parameters__ = l = [] + for p in self.parameters.values(): + p = p.copy() + p.converter.pre_render() + l.append(p) + return self.__render_parameters__ @property def methoddef_flags(self): + if self.kind in (METHOD_INIT, METHOD_NEW): + return None flags = [] if self.kind == CLASS_METHOD: flags.append('METH_CLASS') @@ -1213,6 +1956,25 @@ def methoddef_flags(self): def __repr__(self): return '' + def copy(self, **overrides): + kwargs = { + 'name': self.name, 'module': self.module, 'parameters': self.parameters, + 'cls': self.cls, 'c_basename': self.c_basename, + 'full_name': self.full_name, + 'return_converter': self.return_converter, 'return_annotation': self.return_annotation, + 'docstring': self.docstring, 'kind': self.kind, 'coexist': self.coexist, + 'docstring_only': self.docstring_only, + } + kwargs.update(overrides) + f = Function(**kwargs) + + parameters = collections.OrderedDict() + for name, value in f.parameters.items(): + value = value.copy(function=f) + parameters[name] = value + f.parameters = parameters + return f + class Parameter: """ @@ -1237,29 +1999,38 @@ def __repr__(self): def is_keyword_only(self): return self.kind == inspect.Parameter.KEYWORD_ONLY -py_special_values = { - NULL: "None", -} + def is_positional_only(self): + return self.kind == inspect.Parameter.POSITIONAL_ONLY -def py_repr(o): - special = py_special_values.get(o) - if special: - return special - return repr(o) + def copy(self, **overrides): + kwargs = { + 'name': self.name, 'kind': self.kind, 'default':self.default, + 'function': self.function, 'converter': self.converter, 'annotation': self.annotation, + 'docstring': self.docstring, 'group': self.group, + } + kwargs.update(overrides) + if 'converter' not in overrides: + converter = copy.copy(self.converter) + converter.function = kwargs['function'] + kwargs['converter'] = converter + return Parameter(**kwargs) -c_special_values = { - NULL: "NULL", - None: "Py_None", -} -def c_repr(o): - special = c_special_values.get(o) - if special: - return special - if isinstance(o, str): - return '"' + quoted_for_c_string(o) + '"' - return repr(o) +class LandMine: + # try to access any + def __init__(self, message): + self.__message__ = message + + def __repr__(self): + return '" + + def __getattribute__(self, name): + if name in ('__repr__', '__message__'): + return super().__getattribute__(name) + # raise RuntimeError(repr(name)) + fail("Stepped on a land mine, trying to access attribute " + repr(name) + ":\n" + self.__message__) + def add_c_converter(f, name=None): if not name: @@ -1274,7 +2045,7 @@ def add_default_legacy_c_converter(cls): # automatically add converter for default format unit # (but without stomping on the existing one if it's already # set, in case you subclass) - if ((cls.format_unit != 'O&') and + if ((cls.format_unit not in ('O&', '')) and (cls.format_unit not in legacy_converters)): legacy_converters[cls.format_unit] = cls return cls @@ -1288,7 +2059,8 @@ def closure(f): added_f = f else: added_f = functools.partial(f, **kwargs) - legacy_converters[format_unit] = added_f + if format_unit: + legacy_converters[format_unit] = added_f return f return closure @@ -1301,28 +2073,39 @@ class CConverter(metaclass=CConverterAutoRegister): """ For the init function, self, name, function, and default must be keyword-or-positional parameters. All other - parameters (including "required" and "doc_default") - must be keyword-only. + parameters must be keyword-only. """ + # The C name to use for this variable. + name = None + + # The Python name to use for this variable. + py_name = None + + # The C type to use for this variable. + # 'type' should be a Python string specifying the type, e.g. "int". + # If this is a pointer type, the type string should end with ' *'. type = None - format_unit = 'O&' # The Python default value for this parameter, as a Python value. - # Or "unspecified" if there is no default. + # Or the magic value "unspecified" if there is no default. + # Or the magic value "unknown" if this value is a cannot be evaluated + # at Argument-Clinic-preprocessing time (but is presumed to be valid + # at runtime). default = unspecified - # "default" as it should appear in the documentation, as a string. - # Or None if there is no default. - doc_default = None - - # "default" converted into a str for rendering into Python code. - py_default = None + # If not None, default must be isinstance() of this type. + # (You can also specify a tuple of types.) + default_type = None # "default" converted into a C value, as a string. # Or None if there is no default. c_default = None + # "default" converted into a Python value, as a string. + # Or None if there is no default. + py_default = None + # The default value used to initialize the C variable when # there is no default, but not specifying a default may # result in an "uninitialized variable" warning. This can @@ -1339,40 +2122,110 @@ class CConverter(metaclass=CConverterAutoRegister): # (If this is not None, format_unit must be 'O&'.) converter = None - encoding = None + # Should Argument Clinic add a '&' before the name of + # the variable when passing it into the _impl function? impl_by_reference = False + + # Should Argument Clinic add a '&' before the name of + # the variable when passing it into PyArg_ParseTuple (AndKeywords)? parse_by_reference = True + + ############################################################# + ############################################################# + ## You shouldn't need to read anything below this point to ## + ## write your own converter functions. ## + ############################################################# + ############################################################# + + # The "format unit" to specify for this variable when + # parsing arguments using PyArg_ParseTuple (AndKeywords). + # Custom converters should always use the default value of 'O&'. + format_unit = 'O&' + + # What encoding do we want for this variable? Only used + # by format units starting with 'e'. + encoding = None + + # Should this object be required to be a subclass of a specific type? + # If not None, should be a string representing a pointer to a + # PyTypeObject (e.g. "&PyUnicode_Type"). + # Only used by the 'O!' format unit (and the "object" converter). + subclass_of = None + + # Do we want an adjacent '_length' variable for this variable? + # Only used by format units ending with '#'. length = False - def __init__(self, name, function, default=unspecified, *, doc_default=None, required=False, annotation=unspecified, **kwargs): - self.function = function + # Should we show this parameter in the generated + # __text_signature__? This is *almost* always True. + # (It's only False for __new__, __init__, and METH_STATIC functions.) + show_in_signature = True + + # Overrides the name used in a text signature. + # The name used for a "self" parameter must be one of + # self, type, or module; however users can set their own. + # This lets the self_converter overrule the user-settable + # name, *just* for the text signature. + # Only set by self_converter. + signature_name = None + + # keep in sync with self_converter.__init__! + def __init__(self, name, py_name, function, default=unspecified, *, c_default=None, py_default=None, annotation=unspecified, **kwargs): self.name = name + self.py_name = py_name if default is not unspecified: + if self.default_type and not isinstance(default, (self.default_type, Unknown)): + if isinstance(self.default_type, type): + types_str = self.default_type.__name__ + else: + types_str = ', '.join((cls.__name__ for cls in self.default_type)) + fail("{}: default value {!r} for field {} is not of type {}".format( + self.__class__.__name__, default, name, types_str)) self.default = default - self.py_default = py_repr(default) - self.doc_default = doc_default if doc_default is not None else self.py_default - self.c_default = c_repr(default) - elif doc_default is not None: - fail(function.fullname + " argument " + name + " specified a 'doc_default' without having a 'default'") + + if c_default: + self.c_default = c_default + if py_default: + self.py_default = py_default + if annotation != unspecified: fail("The 'annotation' parameter is not currently permitted.") - self.required = required + + # this is deliberate, to prevent you from caching information + # about the function in the init. + # (that breaks if we get cloned.) + # so after this change we will noisily fail. + self.function = LandMine("Don't access members of self.function inside converter_init!") self.converter_init(**kwargs) + self.function = function def converter_init(self): pass def is_optional(self): - return (self.default is not unspecified) and (not self.required) + return (self.default is not unspecified) - def render(self, parameter, data): - """ - parameter is a clinic.Parameter instance. - data is a CRenderData instance. - """ + def _render_self(self, parameter, data): self.parameter = parameter - name = ensure_legal_c_identifier(self.name) + original_name = self.name + name = ensure_legal_c_identifier(original_name) + + # impl_arguments + s = ("&" if self.impl_by_reference else "") + name + data.impl_arguments.append(s) + if self.length: + data.impl_arguments.append(self.length_name()) + + # impl_parameters + data.impl_parameters.append(self.simple_declaration(by_reference=self.impl_by_reference)) + if self.length: + data.impl_parameters.append("Py_ssize_clean_t " + self.length_name()) + + def _render_non_self(self, parameter, data): + self.parameter = parameter + original_name = self.name + name = ensure_legal_c_identifier(original_name) # declarations d = self.declaration() @@ -1383,14 +2236,13 @@ def render(self, parameter, data): if initializers: data.initializers.append('/* initializers for ' + name + ' */\n' + initializers.rstrip()) - # impl_arguments - s = ("&" if self.impl_by_reference else "") + name - data.impl_arguments.append(s) - if self.length: - data.impl_arguments.append(self.length_name()) + # modifications + modifications = self.modify() + if modifications: + data.modifications.append('/* modifications for ' + name + ' */\n' + modifications.rstrip()) # keywords - data.keywords.append(name) + data.keywords.append(parameter.name) # format_units if self.is_optional() and '|' not in data.format_units: @@ -1402,16 +2254,19 @@ def render(self, parameter, data): # parse_arguments self.parse_argument(data.parse_arguments) - # impl_parameters - data.impl_parameters.append(self.simple_declaration(by_reference=self.impl_by_reference)) - if self.length: - data.impl_parameters.append("Py_ssize_clean_t " + self.length_name()) - # cleanup cleanup = self.cleanup() if cleanup: data.cleanup.append('/* Cleanup for ' + name + ' */\n' + cleanup.rstrip() + "\n") + def render(self, parameter, data): + """ + parameter is a clinic.Parameter instance. + data is a CRenderData instance. + """ + self._render_self(parameter, data) + self._render_non_self(parameter, data) + def length_name(self): """Computes the name of the associated "length" variable.""" if not self.length: @@ -1428,7 +2283,9 @@ def parse_argument(self, list): list.append(self.converter) if self.encoding: - list.append(self.encoding) + list.append(c_repr(self.encoding)) + elif self.subclass_of: + list.append(self.subclass_of) legal_name = ensure_legal_c_identifier(self.name) s = ("&" if self.parse_by_reference else "") + legal_name @@ -1471,7 +2328,12 @@ def declaration(self): declaration.append('\nPy_ssize_clean_t ') declaration.append(self.length_name()) declaration.append(';') - return "".join(declaration) + s = "".join(declaration) + # double up curly-braces, this string will be used + # as part of a format_map() template later + s = s.replace("{", "{{") + s = s.replace("}", "}}") + return s def initialize(self): """ @@ -1481,6 +2343,14 @@ def initialize(self): """ return "" + def modify(self): + """ + The C statements required to modify this variable after parsing. + Returns a string containing this code indented at column 0. + If no initialization is necessary, returns an empty string. + """ + return "" + def cleanup(self): """ The C statements required to clean up after this variable. @@ -1489,24 +2359,41 @@ def cleanup(self): """ return "" + def pre_render(self): + """ + A second initialization function, like converter_init, + called just before rendering. + You are permitted to examine self.function here. + """ + pass + class bool_converter(CConverter): type = 'int' + default_type = bool format_unit = 'p' c_ignored_default = '0' def converter_init(self): - self.default = bool(self.default) - self.c_default = str(int(self.default)) + if self.default is not unspecified: + self.default = bool(self.default) + self.c_default = str(int(self.default)) class char_converter(CConverter): type = 'char' + default_type = str format_unit = 'c' c_ignored_default = "'\0'" + def converter_init(self): + if isinstance(self.default, str) and (len(self.default) != 1): + fail("char_converter: illegal default value " + repr(self.default)) + + @add_legacy_c_converter('B', bitwise=True) -class byte_converter(CConverter): - type = 'byte' +class unsigned_char_converter(CConverter): + type = 'unsigned char' + default_type = int format_unit = 'b' c_ignored_default = "'\0'" @@ -1514,13 +2401,17 @@ def converter_init(self, *, bitwise=False): if bitwise: self.format_unit = 'B' +class byte_converter(unsigned_char_converter): pass + class short_converter(CConverter): type = 'short' + default_type = int format_unit = 'h' c_ignored_default = "0" class unsigned_short_converter(CConverter): type = 'unsigned short' + default_type = int format_unit = 'H' c_ignored_default = "0" @@ -1531,17 +2422,21 @@ def converter_init(self, *, bitwise=False): @add_legacy_c_converter('C', types='str') class int_converter(CConverter): type = 'int' + default_type = int format_unit = 'i' c_ignored_default = "0" - def converter_init(self, *, types='int'): + def converter_init(self, *, types='int', type=None): if types == 'str': self.format_unit = 'C' elif types != 'int': fail("int_converter: illegal 'types' argument") + if type != None: + self.type = type class unsigned_int_converter(CConverter): type = 'unsigned int' + default_type = int format_unit = 'I' c_ignored_default = "0" @@ -1551,11 +2446,13 @@ def converter_init(self, *, bitwise=False): class long_converter(CConverter): type = 'long' + default_type = int format_unit = 'l' c_ignored_default = "0" class unsigned_long_converter(CConverter): type = 'unsigned long' + default_type = int format_unit = 'k' c_ignored_default = "0" @@ -1565,11 +2462,13 @@ def converter_init(self, *, bitwise=False): class PY_LONG_LONG_converter(CConverter): type = 'PY_LONG_LONG' + default_type = int format_unit = 'L' c_ignored_default = "0" class unsigned_PY_LONG_LONG_converter(CConverter): type = 'unsigned PY_LONG_LONG' + default_type = int format_unit = 'K' c_ignored_default = "0" @@ -1579,23 +2478,27 @@ def converter_init(self, *, bitwise=False): class Py_ssize_t_converter(CConverter): type = 'Py_ssize_t' + default_type = int format_unit = 'n' c_ignored_default = "0" class float_converter(CConverter): type = 'float' + default_type = float format_unit = 'f' c_ignored_default = "0.0" class double_converter(CConverter): type = 'double' + default_type = float format_unit = 'd' c_ignored_default = "0.0" class Py_complex_converter(CConverter): type = 'Py_complex' + default_type = complex format_unit = 'D' c_ignored_default = "{0.0, 0.0}" @@ -1604,38 +2507,37 @@ class object_converter(CConverter): type = 'PyObject *' format_unit = 'O' - def converter_init(self, *, type=None): - if type: - assert isinstance(type, str) - assert type.isidentifier() - try: - type = eval(type) - # need more of these! - type = { - str: '&PyUnicode_Type', - }[type] - except NameError: - type = type + def converter_init(self, *, converter=None, type=None, subclass_of=None): + if converter: + if subclass_of: + fail("object: Cannot pass in both 'converter' and 'subclass_of'") + self.format_unit = 'O&' + self.converter = converter + elif subclass_of: self.format_unit = 'O!' - self.encoding = type + self.subclass_of = subclass_of + + if type is not None: + self.type = type @add_legacy_c_converter('s#', length=True) -@add_legacy_c_converter('y', type="bytes") -@add_legacy_c_converter('y#', type="bytes", length=True) +@add_legacy_c_converter('y', types="bytes") +@add_legacy_c_converter('y#', types="bytes", length=True) @add_legacy_c_converter('z', nullable=True) @add_legacy_c_converter('z#', nullable=True, length=True) class str_converter(CConverter): type = 'const char *' + default_type = (str, Null, NoneType) format_unit = 's' def converter_init(self, *, encoding=None, types="str", length=False, nullable=False, zeroes=False): types = set(types.strip().split()) - bytes_type = set(("bytes",)) - str_type = set(("str",)) - all_3_type = set(("bytearray",)) | bytes_type | str_type + bytes_type = {"bytes"} + str_type = {"str"} + all_3_type = {"bytearray"} | bytes_type | str_type is_bytes = types == bytes_type is_str = types == str_type is_all_3 = types == all_3_type @@ -1656,7 +2558,7 @@ def converter_init(self, *, encoding=None, types="str", format_unit = 'et#' if format_unit.endswith('#'): - print("Warning: code using format unit ", repr(format_unit), "probably doesn't work properly.") + fail("Sorry: code using format unit ", repr(format_unit), "probably doesn't work properly yet.\nGive Larry your test case and he'll it.") # TODO set pointer to NULL # TODO add cleanup for buffer pass @@ -1693,6 +2595,7 @@ class PyByteArrayObject_converter(CConverter): class unicode_converter(CConverter): type = 'PyObject *' + default_type = (str, Null, NoneType) format_unit = 'U' @add_legacy_c_converter('u#', length=True) @@ -1700,6 +2603,7 @@ class unicode_converter(CConverter): @add_legacy_c_converter('Z#', nullable=True, length=True) class Py_UNICODE_converter(CConverter): type = 'Py_UNICODE *' + default_type = (str, Null, NoneType) format_unit = 'u' def converter_init(self, *, nullable=False, length=False): @@ -1722,16 +2626,19 @@ class Py_buffer_converter(CConverter): type = 'Py_buffer' format_unit = 'y*' impl_by_reference = True - c_ignored_default = "{NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL}" + c_ignored_default = "{NULL, NULL}" def converter_init(self, *, types='bytes bytearray buffer', nullable=False): + if self.default not in (unspecified, None): + fail("The only legal default value for Py_buffer is None.") + self.c_default = self.c_ignored_default types = set(types.strip().split()) - bytes_type = set(('bytes',)) - bytearray_type = set(('bytearray',)) - buffer_type = set(('buffer',)) - rwbuffer_type = set(('rwbuffer',)) - robuffer_type = set(('robuffer',)) - str_type = set(('str',)) + bytes_type = {'bytes'} + bytearray_type = {'bytearray'} + buffer_type = {'buffer'} + rwbuffer_type = {'rwbuffer'} + robuffer_type = {'robuffer'} + str_type = {'str'} bytes_bytearray_buffer_type = bytes_type | bytearray_type | buffer_type format_unit = None @@ -1742,7 +2649,7 @@ def converter_init(self, *, types='bytes bytearray buffer', nullable=False): fail('Py_buffer_converter: illegal combination of arguments (nullable=True)') elif types == (bytes_bytearray_buffer_type): format_unit = 'y*' - elif types == (bytearray_type | rwuffer_type): + elif types == (bytearray_type | rwbuffer_type): format_unit = 'w*' if not format_unit: fail("Py_buffer_converter: illegal combination of arguments") @@ -1751,7 +2658,25 @@ def converter_init(self, *, types='bytes bytearray buffer', nullable=False): def cleanup(self): name = ensure_legal_c_identifier(self.name) - return "".join(["if (", name, ".buf)\n PyBuffer_Release(&", name, ");\n"]) + return "".join(["if (", name, ".obj)\n PyBuffer_Release(&", name, ");\n"]) + + +def correct_name_for_self(f): + if f.kind in (CALLABLE, METHOD_INIT): + if f.cls: + return "PyObject *", "self" + return "PyModuleDef *", "module" + if f.kind == STATIC_METHOD: + return "void *", "null" + if f.kind in (CLASS_METHOD, METHOD_NEW): + return "PyTypeObject *", "type" + raise RuntimeError("Unhandled type of function f: " + repr(f.kind)) + +def required_type_for_self_for_parser(f): + type, _ = correct_name_for_self(f) + if f.kind in (METHOD_INIT, METHOD_NEW, STATIC_METHOD, CLASS_METHOD): + return type + return None class self_converter(CConverter): @@ -1759,24 +2684,103 @@ class self_converter(CConverter): A special-case converter: this is the default converter used for "self". """ - type = "PyObject *" - def converter_init(self): + type = None + format_unit = '' + + def converter_init(self, *, type=None): + self.specified_type = type + + def pre_render(self): f = self.function - if f.kind == CALLABLE: - if f.cls: - self.name = "self" - else: - self.name = "module" - self.type = "PyModuleDef *" - elif f.kind == STATIC_METHOD: - self.name = "null" - self.type = "void *" - elif f.kind == CLASS_METHOD: - self.name = "cls" - self.type = "PyTypeObject *" + default_type, default_name = correct_name_for_self(f) + self.signature_name = default_name + self.type = self.specified_type or self.type or default_type + + kind = self.function.kind + new_or_init = kind in (METHOD_NEW, METHOD_INIT) + + if (kind == STATIC_METHOD) or new_or_init: + self.show_in_signature = False + + # tp_new (METHOD_NEW) functions are of type newfunc: + # typedef PyObject *(*newfunc)(struct _typeobject *, PyObject *, PyObject *); + # PyTypeObject is a typedef for struct _typeobject. + # + # tp_init (METHOD_INIT) functions are of type initproc: + # typedef int (*initproc)(PyObject *, PyObject *, PyObject *); + # + # All other functions generated by Argument Clinic are stored in + # PyMethodDef structures, in the ml_meth slot, which is of type PyCFunction: + # typedef PyObject *(*PyCFunction)(PyObject *, PyObject *); + # However! We habitually cast these functions to PyCFunction, + # since functions that accept keyword arguments don't fit this signature + # but are stored there anyway. So strict type equality isn't important + # for these functions. + # + # So: + # + # * The name of the first parameter to the impl and the parsing function will always + # be self.name. + # + # * The type of the first parameter to the impl will always be of self.type. + # + # * If the function is neither tp_new (METHOD_NEW) nor tp_init (METHOD_INIT): + # * The type of the first parameter to the parsing function is also self.type. + # This means that if you step into the parsing function, your "self" parameter + # is of the correct type, which may make debugging more pleasant. + # + # * Else if the function is tp_new (METHOD_NEW): + # * The type of the first parameter to the parsing function is "PyTypeObject *", + # so the type signature of the function call is an exact match. + # * If self.type != "PyTypeObject *", we cast the first parameter to self.type + # in the impl call. + # + # * Else if the function is tp_init (METHOD_INIT): + # * The type of the first parameter to the parsing function is "PyObject *", + # so the type signature of the function call is an exact match. + # * If self.type != "PyObject *", we cast the first parameter to self.type + # in the impl call. + + @property + def parser_type(self): + return required_type_for_self_for_parser(self.function) or self.type def render(self, parameter, data): - fail("render() should never be called on self_converter instances") + """ + parameter is a clinic.Parameter instance. + data is a CRenderData instance. + """ + if self.function.kind == STATIC_METHOD: + return + + self._render_self(parameter, data) + + if self.type != self.parser_type: + # insert cast to impl_argument[0], aka self. + # we know we're in the first slot in all the CRenderData lists, + # because we render parameters in order, and self is always first. + assert len(data.impl_arguments) == 1 + assert data.impl_arguments[0] == self.name + data.impl_arguments[0] = '(' + self.type + ")" + data.impl_arguments[0] + + def set_template_dict(self, template_dict): + template_dict['self_name'] = self.name + template_dict['self_type'] = self.parser_type + kind = self.function.kind + cls = self.function.cls + + if ((kind in (METHOD_NEW, METHOD_INIT)) and cls and cls.typedef): + if kind == METHOD_NEW: + passed_in_type = self.name + else: + passed_in_type = 'Py_TYPE({})'.format(self.name) + + line = '({passed_in_type} == {type_object}) &&\n ' + d = { + 'type_object': self.function.cls.type_object, + 'passed_in_type': passed_in_type + } + template_dict['self_type_check'] = line.format_map(d) @@ -1796,11 +2800,17 @@ def __init__(cls, name, bases, classdict): class CReturnConverter(metaclass=CReturnConverterAutoRegister): + # The C type to use for this variable. + # 'type' should be a Python string specifying the type, e.g. "int". + # If this is a pointer type, the type string should end with ' *'. type = 'PyObject *' + + # The Python default value for this parameter, as a Python value. + # Or the magic value "unspecified" if there is no default. default = None - def __init__(self, *, doc_default=None, **kwargs): - self.doc_default = doc_default + def __init__(self, *, py_default=None, **kwargs): + self.py_default = py_default try: self.return_converter_init(**kwargs) except TypeError as e: @@ -1835,34 +2845,83 @@ def render(self, function, data): add_c_return_converter(CReturnConverter, 'object') -class int_return_converter(CReturnConverter): +class NoneType_return_converter(CReturnConverter): + def render(self, function, data): + self.declare(data) + data.return_conversion.append(''' +if (_return_value != Py_None) + goto exit; +return_value = Py_None; +Py_INCREF(Py_None); +'''.strip()) + +class bool_return_converter(CReturnConverter): type = 'int' def render(self, function, data): self.declare(data) self.err_occurred_if("_return_value == -1", data) - data.return_conversion.append( - 'return_value = PyLong_FromLong((long)_return_value);\n') - + data.return_conversion.append('return_value = PyBool_FromLong((long)_return_value);\n') class long_return_converter(CReturnConverter): type = 'long' + conversion_fn = 'PyLong_FromLong' + cast = '' + unsigned_cast = '' def render(self, function, data): self.declare(data) - self.err_occurred_if("_return_value == -1", data) + self.err_occurred_if("_return_value == {}-1".format(self.unsigned_cast), data) data.return_conversion.append( - 'return_value = PyLong_FromLong(_return_value);\n') + ''.join(('return_value = ', self.conversion_fn, '(', self.cast, '_return_value);\n'))) + +class int_return_converter(long_return_converter): + type = 'int' + cast = '(long)' + +class init_return_converter(long_return_converter): + """ + Special return converter for __init__ functions. + """ + type = 'int' + cast = '(long)' + def render(self, function, data): + pass + +class unsigned_long_return_converter(long_return_converter): + type = 'unsigned long' + conversion_fn = 'PyLong_FromUnsignedLong' + unsigned_cast = '(unsigned long)' -class Py_ssize_t_return_converter(CReturnConverter): +class unsigned_int_return_converter(unsigned_long_return_converter): + type = 'unsigned int' + cast = '(unsigned long)' + unsigned_cast = '(unsigned int)' + +class Py_ssize_t_return_converter(long_return_converter): type = 'Py_ssize_t' + conversion_fn = 'PyLong_FromSsize_t' + +class size_t_return_converter(long_return_converter): + type = 'size_t' + conversion_fn = 'PyLong_FromSize_t' + unsigned_cast = '(size_t)' + + +class double_return_converter(CReturnConverter): + type = 'double' + cast = '' def render(self, function, data): self.declare(data) - self.err_occurred_if("_return_value == -1", data) + self.err_occurred_if("_return_value == -1.0", data) data.return_conversion.append( - 'return_value = PyLong_FromSsize_t(_return_value);\n') + 'return_value = PyFloat_FromDouble(' + self.cast + '_return_value);\n') + +class float_return_converter(double_return_converter): + type = 'float' + cast = '(double)' class DecodeFSDefault_return_converter(CReturnConverter): @@ -1889,7 +2948,7 @@ def measure(self, line): Returns the length of the line's margin. """ if '\t' in line: - fail('Tab characters are illegal in the Clinic DSL.') + fail('Tab characters are illegal in the Argument Clinic DSL.') stripped = line.lstrip() if not len(stripped): # we can't tell anything from an empty line @@ -1980,9 +3039,12 @@ def reset(self): self.keyword_only = False self.group = 0 self.parameter_state = self.ps_start + self.seen_positional_with_default = False self.indent = IndentStack() self.kind = CALLABLE self.coexist = False + self.parameter_continuation = '' + self.preserve_output = False def directive_version(self, required): global version @@ -1995,11 +3057,15 @@ def directive_module(self, name): module, cls = self.clinic._module_and_class(fields) if cls: fail("Can't nest a module inside a class!") + + if name in module.classes: + fail("Already defined module " + repr(name) + "!") + m = Module(name, module) module.modules[name] = m self.block.signatures.append(m) - def directive_class(self, name): + def directive_class(self, name, typedef, type_object): fields = name.split('.') in_classes = False parent = self @@ -2007,29 +3073,105 @@ def directive_class(self, name): so_far = [] module, cls = self.clinic._module_and_class(fields) - c = Class(name, module, cls) - if cls: - cls.classes[name] = c - else: - module.classes[name] = c + parent = cls or module + if name in parent.classes: + fail("Already defined class " + repr(name) + "!") + + c = Class(name, module, cls, typedef, type_object) + parent.classes[name] = c self.block.signatures.append(c) + def directive_set(self, name, value): + if name not in ("line_prefix", "line_suffix"): + fail("unknown variable", repr(name)) + + value = value.format_map({ + 'block comment start': '/*', + 'block comment end': '*/', + }) + + self.clinic.__dict__[name] = value + + def directive_destination(self, name, command, *args): + if command == 'new': + self.clinic.add_destination(name, *args) + return + + if command == 'clear': + self.clinic.get_destination(name).clear() + fail("unknown destination command", repr(command)) + + + def directive_output(self, field, destination=''): + fd = self.clinic.field_destinations + + if field == "preset": + preset = self.clinic.presets.get(destination) + if not preset: + fail("Unknown preset " + repr(destination) + "!") + fd.update(preset) + return + + if field == "push": + self.clinic.field_destinations_stack.append(fd.copy()) + return + + if field == "pop": + if not self.clinic.field_destinations_stack: + fail("Can't 'output pop', stack is empty!") + previous_fd = self.clinic.field_destinations_stack.pop() + fd.update(previous_fd) + return + + # secret command for debugging! + if field == "print": + self.block.output.append(pprint.pformat(fd)) + self.block.output.append('\n') + return + + d = self.clinic.get_destination(destination) + + if field == "everything": + for name in list(fd): + fd[name] = d + return + + if field not in fd: + fail("Invalid field " + repr(field) + ", must be one of:\n preset push pop print everything " + " ".join(fd)) + fd[field] = d + + def directive_dump(self, name): + self.block.output.append(self.clinic.get_destination(name).dump()) + + def directive_print(self, *args): + self.block.output.append(' '.join(args)) + self.block.output.append('\n') + + def directive_preserve(self): + if self.preserve_output: + fail("Can't have preserve twice in one block!") + self.preserve_output = True + def at_classmethod(self): - assert self.kind is CALLABLE + if self.kind is not CALLABLE: + fail("Can't set @classmethod, function is not a normal callable") self.kind = CLASS_METHOD def at_staticmethod(self): - assert self.kind is CALLABLE + if self.kind is not CALLABLE: + fail("Can't set @staticmethod, function is not a normal callable") self.kind = STATIC_METHOD def at_coexist(self): - assert self.coexist == False + if self.coexist: + fail("Called @coexist twice!") self.coexist = True - def parse(self, block): self.reset() self.block = block + self.saved_output = self.block.output + block.output = [] block_start = self.clinic.block_parser.line_number lines = block.input.split('\n') for line_number, line in enumerate(lines, self.clinic.block_parser.block_start_line_number): @@ -2040,7 +3182,12 @@ def parse(self, block): self.next(self.state_terminal) self.state(None) - block.output = self.clinic.language.render(block.signatures) + block.output.extend(self.clinic.language.render(clinic, block.signatures)) + + if self.preserve_output: + if block.output: + fail("'preserve' only works for blocks that don't produce any output!") + block.output = self.saved_output @staticmethod def ignore_line(line): @@ -2069,6 +3216,18 @@ def state_dsl_start(self, line): # self.block = self.ClinicOutputBlock(self) if self.ignore_line(line): return + + # is it a directive? + fields = shlex.split(line) + directive_name = fields[0] + directive = self.directives.get(directive_name, None) + if directive: + try: + directive(*fields[1:]) + except TypeError as e: + fail(str(e)) + return + self.next(self.state_modulename_name, line) def state_modulename_name(self, line): @@ -2077,6 +3236,12 @@ def state_modulename_name(self, line): # modulename.fnname [as c_basename] [-> return annotation] # square brackets denote optional syntax. # + # alternatively: + # modulename.fnname [as c_basename] = modulename.existing_fn_name + # clones the parameters and return converter from that + # function. you can't modify them. you must enter a + # new docstring. + # # (but we might find a directive first!) # # this line is permitted to start with whitespace. @@ -2087,13 +3252,43 @@ def state_modulename_name(self, line): self.indent.infer(line) - # is it a directive? - fields = shlex.split(line) - directive_name = fields[0] - directive = self.directives.get(directive_name, None) - if directive: - directive(*fields[1:]) - return + # are we cloning? + before, equals, existing = line.rpartition('=') + if equals: + full_name, _, c_basename = before.partition(' as ') + full_name = full_name.strip() + c_basename = c_basename.strip() + existing = existing.strip() + if (is_legal_py_identifier(full_name) and + (not c_basename or is_legal_c_identifier(c_basename)) and + is_legal_py_identifier(existing)): + # we're cloning! + fields = [x.strip() for x in existing.split('.')] + function_name = fields.pop() + module, cls = self.clinic._module_and_class(fields) + + for existing_function in (cls or module).functions: + if existing_function.name == function_name: + break + else: + existing_function = None + if not existing_function: + print("class", cls, "module", module, "existing", existing) + print("cls. functions", cls.functions) + fail("Couldn't find existing function " + repr(existing) + "!") + + fields = [x.strip() for x in full_name.split('.')] + function_name = fields.pop() + module, cls = self.clinic._module_and_class(fields) + + if not (existing_function.kind == self.kind and existing_function.coexist == self.coexist): + fail("'kind' of function and cloned function don't match! (@classmethod/@staticmethod/@coexist)") + self.function = existing_function.copy(name=function_name, full_name=full_name, module=module, cls=cls, c_basename=c_basename, docstring='') + + self.block.signatures.append(self.function) + (cls or module).functions.append(self.function) + self.next(self.state_function_docstring) + return line, _, returns = line.partition('->') @@ -2106,9 +3301,8 @@ def state_modulename_name(self, line): if c_basename and not is_legal_c_identifier(c_basename): fail("Illegal C basename: {}".format(c_basename)) - if not returns: - return_converter = CReturnConverter() - else: + return_converter = None + if returns: ast_input = "def x() -> {}: pass".format(returns) module = None try: @@ -2119,9 +3313,11 @@ def state_modulename_name(self, line): fail("Badly-formed annotation for " + full_name + ": " + returns) try: name, legacy, kwargs = self.parse_converter(module.body[0].returns) - assert not legacy + if legacy: + fail("Legacy converter {!r} not allowed as a return converter" + .format(name)) if name not in return_converters: - fail("Error: No available return converter called " + repr(name)) + fail("No available return converter called " + repr(name)) return_converter = return_converters[name](**kwargs) except ValueError: fail("Badly-formed annotation for " + full_name + ": " + returns) @@ -2130,11 +3326,39 @@ def state_modulename_name(self, line): function_name = fields.pop() module, cls = self.clinic._module_and_class(fields) + fields = full_name.split('.') + if fields[-1] == '__new__': + if (self.kind != CLASS_METHOD) or (not cls): + fail("__new__ must be a class method!") + self.kind = METHOD_NEW + elif fields[-1] == '__init__': + if (self.kind != CALLABLE) or (not cls): + fail("__init__ must be a normal method, not a class or static method!") + self.kind = METHOD_INIT + if not return_converter: + return_converter = init_return_converter() + elif fields[-1] in unsupported_special_methods: + fail(fields[-1] + " is a special method and cannot be converted to Argument Clinic! (Yet.)") + + if not return_converter: + return_converter = CReturnConverter() + if not module: fail("Undefined module used in declaration of " + repr(full_name.strip()) + ".") self.function = Function(name=function_name, full_name=full_name, module=module, cls=cls, c_basename=c_basename, return_converter=return_converter, kind=self.kind, coexist=self.coexist) self.block.signatures.append(self.function) + + # insert a self converter automatically + type, name = correct_name_for_self(self.function) + kwargs = {} + if cls and type == "PyObject *": + kwargs['type'] = cls.typedef + sc = self.function.self_converter = self_converter(name, name, self.function, **kwargs) + p_self = Parameter(sc.name, inspect.Parameter.POSITIONAL_ONLY, function=self.function, converter=sc) + self.function.parameters[sc.name] = p_self + + (cls or module).functions.append(self.function) self.next(self.state_parameters_start) # Now entering the parameters section. The rules, formally stated: @@ -2164,8 +3388,6 @@ def state_modulename_name(self, line): # with X spaces such that F < X < P. (As before, F is the indent # of the function declaration.) # - ############## - # # Also, currently Argument Clinic places the following restrictions on groups: # * Each group must contain at least one parameter. # * Each group may contain at most one group, which must be the furthest @@ -2193,18 +3415,21 @@ def state_modulename_name(self, line): # "parameter_state". (Previously the code was a miasma of ifs and # separate boolean state variables.) The states are: # - # [ [ a, b, ] c, ] d, e, f, [ g, h, [ i ] ] / <- line - # 01 2 3 4 5 6 <- state transitions + # [ [ a, b, ] c, ] d, e, f=3, [ g, h, [ i ] ] / <- line + # 01 2 3 4 5 6 7 <- state transitions # # 0: ps_start. before we've seen anything. legal transitions are to 1 or 3. # 1: ps_left_square_before. left square brackets before required parameters. # 2: ps_group_before. in a group, before required parameters. - # 3: ps_required. required parameters. (renumber left groups!) - # 4: ps_group_after. in a group, after required parameters. - # 5: ps_right_square_after. right square brackets after required parameters. - # 6: ps_seen_slash. seen slash. + # 3: ps_required. required parameters, positional-or-keyword or positional-only + # (we don't know yet). (renumber left groups!) + # 4: ps_optional. positional-or-keyword or positional-only parameters that + # now must have default values. + # 5: ps_group_after. in a group, after required parameters. + # 6: ps_right_square_after. right square brackets after required parameters. + # 7: ps_seen_slash. seen slash. ps_start, ps_left_square_before, ps_group_before, ps_required, \ - ps_group_after, ps_right_square_after, ps_seen_slash = range(7) + ps_optional, ps_group_after, ps_right_square_after, ps_seen_slash = range(8) def state_parameters_start(self, line): if self.ignore_line(line): @@ -2214,6 +3439,7 @@ def state_parameters_start(self, line): if not self.indent.infer(line): return self.next(self.state_function_docstring, line) + self.parameter_continuation = '' return self.next(self.state_parameter, line) @@ -2227,6 +3453,10 @@ def to_required(self): p.group = -p.group def state_parameter(self, line): + if self.parameter_continuation: + line = self.parameter_continuation + ' ' + line.lstrip() + self.parameter_continuation = '' + if self.ignore_line(line): return @@ -2240,6 +3470,11 @@ def state_parameter(self, line): # we indented, must be to new parameter docstring column return self.next(self.state_parameter_docstring_start, line) + line = line.rstrip() + if line.endswith('\\'): + self.parameter_continuation = line[:-1] + return + line = line.lstrip() if line in ('*', '/', '[', ']'): @@ -2253,54 +3488,199 @@ def state_parameter(self, line): elif self.parameter_state == self.ps_group_before: if not self.group: self.to_required() - elif self.parameter_state == self.ps_group_after: + elif self.parameter_state in (self.ps_group_after, self.ps_optional): pass else: - fail("Function " + self.function.name + " has an unsupported group configuration. (Unexpected state " + str(self.parameter_state) + ")") + fail("Function " + self.function.name + " has an unsupported group configuration. (Unexpected state " + str(self.parameter_state) + ".a)") + + # handle "as" for parameters too + c_name = None + name, have_as_token, trailing = line.partition(' as ') + if have_as_token: + name = name.strip() + if ' ' not in name: + fields = trailing.strip().split(' ') + if not fields: + fail("Invalid 'as' clause!") + c_name = fields[0] + if c_name.endswith(':'): + name += ':' + c_name = c_name[:-1] + fields[0] = name + line = ' '.join(fields) + + base, equals, default = line.rpartition('=') + if not equals: + base = default + default = None - ast_input = "def x({}): pass".format(line) module = None try: + ast_input = "def x({}): pass".format(base) module = ast.parse(ast_input) except SyntaxError: - pass + try: + # the last = was probably inside a function call, like + # i: int(nullable=True) + # so assume there was no actual default value. + default = None + ast_input = "def x({}): pass".format(line) + module = ast.parse(ast_input) + except SyntaxError: + pass if not module: fail("Function " + self.function.name + " has an invalid parameter declaration:\n\t" + line) function_args = module.body[0].args parameter = function_args.args[0] - if function_args.defaults: - expr = function_args.defaults[0] - # mild hack: explicitly support NULL as a default value - if isinstance(expr, ast.Name) and expr.id == 'NULL': - value = NULL - else: - value = ast.literal_eval(expr) - else: - value = unspecified - parameter_name = parameter.arg name, legacy, kwargs = self.parse_converter(parameter.annotation) + + if not default: + if self.parameter_state == self.ps_optional: + fail("Can't have a parameter without a default (" + repr(parameter_name) + ")\nafter a parameter with a default!") + value = unspecified + if 'py_default' in kwargs: + fail("You can't specify py_default without specifying a default value!") + else: + if self.parameter_state == self.ps_required: + self.parameter_state = self.ps_optional + default = default.strip() + bad = False + ast_input = "x = {}".format(default) + bad = False + try: + module = ast.parse(ast_input) + + if 'c_default' not in kwargs: + # we can only represent very simple data values in C. + # detect whether default is okay, via a blacklist + # of disallowed ast nodes. + class DetectBadNodes(ast.NodeVisitor): + bad = False + def bad_node(self, node): + self.bad = True + + # inline function call + visit_Call = bad_node + # inline if statement ("x = 3 if y else z") + visit_IfExp = bad_node + + # comprehensions and generator expressions + visit_ListComp = visit_SetComp = bad_node + visit_DictComp = visit_GeneratorExp = bad_node + + # literals for advanced types + visit_Dict = visit_Set = bad_node + visit_List = visit_Tuple = bad_node + + # "starred": "a = [1, 2, 3]; *a" + visit_Starred = bad_node + + # allow ellipsis, for now + # visit_Ellipsis = bad_node + + blacklist = DetectBadNodes() + blacklist.visit(module) + bad = blacklist.bad + else: + # if they specify a c_default, we can be more lenient about the default value. + # but at least make an attempt at ensuring it's a valid expression. + try: + value = eval(default) + if value == unspecified: + fail("'unspecified' is not a legal default value!") + except NameError: + pass # probably a named constant + except Exception as e: + fail("Malformed expression given as default value\n" + "{!r} caused {!r}".format(default, e)) + if bad: + fail("Unsupported expression as default value: " + repr(default)) + + expr = module.body[0].value + # mild hack: explicitly support NULL as a default value + if isinstance(expr, ast.Name) and expr.id == 'NULL': + value = NULL + py_default = 'None' + c_default = "NULL" + elif (isinstance(expr, ast.BinOp) or + (isinstance(expr, ast.UnaryOp) and not isinstance(expr.operand, ast.Num))): + c_default = kwargs.get("c_default") + if not (isinstance(c_default, str) and c_default): + fail("When you specify an expression (" + repr(default) + ") as your default value,\nyou MUST specify a valid c_default.") + py_default = default + value = unknown + elif isinstance(expr, ast.Attribute): + a = [] + n = expr + while isinstance(n, ast.Attribute): + a.append(n.attr) + n = n.value + if not isinstance(n, ast.Name): + fail("Unsupported default value " + repr(default) + " (looked like a Python constant)") + a.append(n.id) + py_default = ".".join(reversed(a)) + + c_default = kwargs.get("c_default") + if not (isinstance(c_default, str) and c_default): + fail("When you specify a named constant (" + repr(py_default) + ") as your default value,\nyou MUST specify a valid c_default.") + + try: + value = eval(py_default) + except NameError: + value = unknown + else: + value = ast.literal_eval(expr) + py_default = repr(value) + if isinstance(value, (bool, None.__class__)): + c_default = "Py_" + py_default + elif isinstance(value, str): + c_default = c_repr(value) + else: + c_default = py_default + + except SyntaxError as e: + fail("Syntax error: " + repr(e.text)) + except (ValueError, AttributeError): + value = unknown + c_default = kwargs.get("c_default") + py_default = default + if not (isinstance(c_default, str) and c_default): + fail("When you specify a named constant (" + repr(py_default) + ") as your default value,\nyou MUST specify a valid c_default.") + + kwargs.setdefault('c_default', c_default) + kwargs.setdefault('py_default', py_default) + dict = legacy_converters if legacy else converters legacy_str = "legacy " if legacy else "" if name not in dict: fail('{} is not a valid {}converter'.format(name, legacy_str)) - converter = dict[name](parameter_name, self.function, value, **kwargs) + # if you use a c_name for the parameter, we just give that name to the converter + # but the parameter object gets the python name + converter = dict[name](c_name or parameter_name, parameter_name, self.function, value, **kwargs) + + kind = inspect.Parameter.KEYWORD_ONLY if self.keyword_only else inspect.Parameter.POSITIONAL_OR_KEYWORD - # special case: if it's the self converter, - # don't actually add it to the parameter list if isinstance(converter, self_converter): - if self.function.parameters or (self.parameter_state != self.ps_required): - fail("The 'self' parameter, if specified, must be the very first thing in the parameter block.") - if self.function.self_converter: - fail("You can't specify the 'self' parameter more than once.") - self.function.self_converter = converter - self.parameter_state = self.ps_start - return + if len(self.function.parameters) == 1: + if (self.parameter_state != self.ps_required): + fail("A 'self' parameter cannot be marked optional.") + if value is not unspecified: + fail("A 'self' parameter cannot have a default value.") + if self.group: + fail("A 'self' parameter cannot be in an optional group.") + kind = inspect.Parameter.POSITIONAL_ONLY + self.parameter_state = self.ps_start + self.function.parameters.clear() + else: + fail("A 'self' parameter, if specified, must be the very first thing in the parameter block.") - kind = inspect.Parameter.KEYWORD_ONLY if self.keyword_only else inspect.Parameter.POSITIONAL_OR_KEYWORD p = Parameter(parameter_name, kind, function=self.function, converter=converter, default=value, group=self.group) + + if parameter_name in self.function.parameters: + fail("You can't have two parameters named " + repr(parameter_name) + "!") self.function.parameters[parameter_name] = p def parse_converter(self, annotation): @@ -2310,7 +3690,8 @@ def parse_converter(self, annotation): if isinstance(annotation, ast.Name): return annotation.id, False, {} - assert isinstance(annotation, ast.Call) + if not isinstance(annotation, ast.Call): + fail("Annotations must be either a name, a function call, or a string.") name = annotation.func.id kwargs = {node.arg: ast.literal_eval(node.value) for node in annotation.keywords} @@ -2330,8 +3711,9 @@ def parse_special_symbol(self, symbol): elif self.parameter_state in (self.ps_required, self.ps_group_after): self.parameter_state = self.ps_group_after else: - fail("Function " + self.function.name + " has an unsupported group configuration. (Unexpected state " + str(self.parameter_state) + ")") + fail("Function " + self.function.name + " has an unsupported group configuration. (Unexpected state " + str(self.parameter_state) + ".b)") self.group += 1 + self.function.docstring_only = True elif symbol == ']': if not self.group: fail("Function " + self.function.name + " has a ] without a matching [.") @@ -2343,18 +3725,18 @@ def parse_special_symbol(self, symbol): elif self.parameter_state in (self.ps_group_after, self.ps_right_square_after): self.parameter_state = self.ps_right_square_after else: - fail("Function " + self.function.name + " has an unsupported group configuration. (Unexpected state " + str(self.parameter_state) + ")") + fail("Function " + self.function.name + " has an unsupported group configuration. (Unexpected state " + str(self.parameter_state) + ".c)") elif symbol == '/': - # ps_required is allowed here, that allows positional-only without option groups + # ps_required and ps_optional are allowed here, that allows positional-only without option groups # to work (and have default values!) - if (self.parameter_state not in (self.ps_required, self.ps_right_square_after, self.ps_group_before)) or self.group: - fail("Function " + self.function.name + " has an unsupported group configuration. (Unexpected state " + str(self.parameter_state) + ")") + if (self.parameter_state not in (self.ps_required, self.ps_optional, self.ps_right_square_after, self.ps_group_before)) or self.group: + fail("Function " + self.function.name + " has an unsupported group configuration. (Unexpected state " + str(self.parameter_state) + ".d)") if self.keyword_only: fail("Function " + self.function.name + " mixes keyword-only and positional-only parameters, which is unsupported.") self.parameter_state = self.ps_seen_slash - # fixup preceeding parameters + # fixup preceding parameters for p in self.function.parameters.values(): - if p.kind != inspect.Parameter.POSITIONAL_OR_KEYWORD: + if (p.kind != inspect.Parameter.POSITIONAL_OR_KEYWORD and not isinstance(p.converter, self_converter)): fail("Function " + self.function.name + " mixes keyword-only and positional-only parameters, which is unsupported.") p.kind = inspect.Parameter.POSITIONAL_ONLY @@ -2395,9 +3777,6 @@ def state_parameter_docstring(self, line): # the final stanza of the DSL is the docstring. def state_function_docstring(self, line): - if not self.function.self_converter: - self.function.self_converter = self_converter("self", self.function) - if self.group: fail("Function " + self.function.name + " has a ] without a matching [.") @@ -2418,28 +3797,46 @@ def state_function_docstring(self, line): def format_docstring(self): f = self.function - add, output = text_accumulator() - parameters = list(f.parameters.values()) + new_or_init = f.kind in (METHOD_NEW, METHOD_INIT) + if new_or_init and not f.docstring: + # don't render a docstring at all, no signature, nothing. + return f.docstring + + text, add, output = _text_accumulator() + parameters = f.render_parameters ## ## docstring first line ## - add(f.name) + if new_or_init: + # classes get *just* the name of the class + # not __new__, not __init__, and not module.classname + assert f.cls + add(f.cls.name) + else: + add(f.name) add('(') # populate "right_bracket_count" field for every parameter - if parameters: + assert parameters, "We should always have a self parameter. " + repr(f) + assert isinstance(parameters[0].converter, self_converter) + parameters[0].right_bracket_count = 0 + parameters_after_self = parameters[1:] + if parameters_after_self: # for now, the only way Clinic supports positional-only parameters - # is if all of them are positional-only. - positional_only_parameters = [p.kind == inspect.Parameter.POSITIONAL_ONLY for p in parameters] - if parameters[0].kind == inspect.Parameter.POSITIONAL_ONLY: + # is if all of them are positional-only... + # + # ... except for self! self is always positional-only. + + positional_only_parameters = [p.kind == inspect.Parameter.POSITIONAL_ONLY for p in parameters_after_self] + if parameters_after_self[0].kind == inspect.Parameter.POSITIONAL_ONLY: assert all(positional_only_parameters) for p in parameters: p.right_bracket_count = abs(p.group) else: # don't put any right brackets around non-positional-only parameters, ever. - for p in parameters: + for p in parameters_after_self: p.right_bracket_count = 0 right_bracket_count = 0 @@ -2455,36 +3852,122 @@ def fix_right_bracket_count(desired): right_bracket_count -= 1 return s + need_slash = False + added_slash = False + need_a_trailing_slash = False + + # we only need a trailing slash: + # * if this is not a "docstring_only" signature + # * and if the last *shown* parameter is + # positional only + if not f.docstring_only: + for p in reversed(parameters): + if not p.converter.show_in_signature: + continue + if p.is_positional_only(): + need_a_trailing_slash = True + break + + added_star = False - add_comma = False + + first_parameter = True + last_p = parameters[-1] + line_length = len(''.join(text)) + indent = " " * line_length + def add_parameter(text): + nonlocal line_length + nonlocal first_parameter + if first_parameter: + s = text + first_parameter = False + else: + s = ' ' + text + if line_length + len(s) >= 72: + add('\n') + add(indent) + line_length = len(indent) + s = text + line_length += len(s) + add(s) for p in parameters: + if not p.converter.show_in_signature: + continue assert p.name + is_self = isinstance(p.converter, self_converter) + if is_self and f.docstring_only: + # this isn't a real machine-parsable signature, + # so let's not print the "self" parameter + continue + + if p.is_positional_only(): + need_slash = not f.docstring_only + elif need_slash and not (added_slash or p.is_positional_only()): + added_slash = True + add_parameter('/,') + if p.is_keyword_only() and not added_star: added_star = True - if add_comma: - add(', ') - add('*') + add_parameter('*,') + + p_add, p_output = text_accumulator() + p_add(fix_right_bracket_count(p.right_bracket_count)) + + if isinstance(p.converter, self_converter): + # annotate first parameter as being a "self". + # + # if inspect.Signature gets this function, + # and it's already bound, the self parameter + # will be stripped off. + # + # if it's not bound, it should be marked + # as positional-only. + # + # note: we don't print "self" for __init__, + # because this isn't actually the signature + # for __init__. (it can't be, __init__ doesn't + # have a docstring.) if this is an __init__ + # (or __new__), then this signature is for + # calling the class to construct a new instance. + p_add('$') + + name = p.converter.signature_name or p.name + p_add(name) - a = [p.name] if p.converter.is_optional(): - a.append('=') - value = p.converter.default - a.append(p.converter.doc_default) - s = fix_right_bracket_count(p.right_bracket_count) - s += "".join(a) - if add_comma: - add(', ') - add(s) - add_comma = True + p_add('=') + value = p.converter.py_default + if not value: + value = repr(p.converter.default) + p_add(value) + + if (p != last_p) or need_a_trailing_slash: + p_add(',') + + add_parameter(p_output()) add(fix_right_bracket_count(0)) + if need_a_trailing_slash: + add_parameter('/') add(')') - # if f.return_converter.doc_default: + # PEP 8 says: + # + # The Python standard library will not use function annotations + # as that would result in a premature commitment to a particular + # annotation style. Instead, the annotations are left for users + # to discover and experiment with useful annotation styles. + # + # therefore this is commented out: + # + # if f.return_converter.py_default: # add(' -> ') - # add(f.return_converter.doc_default) + # add(f.return_converter.py_default) + + if not f.docstring_only: + add("\n--\n") docstring_first_line = output() @@ -2588,6 +4071,8 @@ def state_terminal(self, line): self.function.docstring = self.format_docstring() + + # maps strings to callables. # the callable should return an object # that implements the clinic parser @@ -2613,6 +4098,7 @@ def main(argv): cmdline = argparse.ArgumentParser() cmdline.add_argument("-f", "--force", action='store_true') cmdline.add_argument("-o", "--output", type=str) + cmdline.add_argument("-v", "--verbose", action='store_true') cmdline.add_argument("--converters", action='store_true') cmdline.add_argument("--make", action='store_true') cmdline.add_argument("filename", type=str, nargs="*") @@ -2674,23 +4160,9 @@ def main(argv): s = parameter_name parameters.append(s) print(' {}({})'.format(short_name, ', '.join(parameters))) - # add_comma = False - # for parameter_name, parameter in signature.parameters.items(): - # if parameter.kind == inspect.Parameter.KEYWORD_ONLY: - # if add_comma: - # parameters.append(', ') - # else: - # add_comma = True - # s = parameter_name - # if parameter.default != inspect.Parameter.empty: - # s += '=' + repr(parameter.default) - # parameters.append(s) - # parameters.append(')') - - # print(" ", short_name + "".join(parameters)) print() - print("All converters also accept (doc_default=None, required=False).") - print("All return converters also accept (doc_default=None).") + print("All converters also accept (c_default=None, py_default=None, annotation=None).") + print("All return converters also accept (py_default=None).") sys.exit(0) if ns.make: @@ -2700,14 +4172,16 @@ def main(argv): cmdline.print_usage() sys.exit(-1) for root, dirs, files in os.walk('.'): - for rcs_dir in ('.svn', '.git', '.hg'): + for rcs_dir in ('.svn', '.git', '.hg', 'build'): if rcs_dir in dirs: dirs.remove(rcs_dir) for filename in files: - if not filename.endswith('.c'): + if not (filename.endswith('.c') or filename.endswith('.h')): continue path = os.path.join(root, filename) - parse_file(path, verify=not ns.force) + if ns.verbose: + print(path) + parse_file(path, force=ns.force, verify=not ns.force) return if not ns.filename: @@ -2721,7 +4195,9 @@ def main(argv): sys.exit(-1) for filename in ns.filename: - parse_file(filename, output=ns.output, verify=not ns.force) + if ns.verbose: + print(filename) + parse_file(filename, output=ns.output, force=ns.force, verify=not ns.force) if __name__ == "__main__": diff --git a/Tools/clinic/clinic_test.py b/Tools/clinic/clinic_test.py index 7baf3801bdac..cd21000c050c 100644 --- a/Tools/clinic/clinic_test.py +++ b/Tools/clinic/clinic_test.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 -# # Argument Clinic # Copyright 2012-2013 by Larry Hastings. # Licensed to the PSF under a contributor agreement. @@ -11,9 +9,11 @@ import collections import inspect from test import support +import sys import unittest from unittest import TestCase + class FakeConverter: def __init__(self, name, args): self.name = name @@ -35,16 +35,46 @@ def __init__(self): def get(self, name, default): return self.used_converters.setdefault(name, FakeConverterFactory(name)) +clinic.Clinic.presets_text = '' +c = clinic.Clinic(language='C') + class FakeClinic: def __init__(self): self.converters = FakeConvertersDict() self.legacy_converters = FakeConvertersDict() - self.language = clinic.CLanguage() + self.language = clinic.CLanguage(None) self.filename = None self.block_parser = clinic.BlockParser('', self.language) self.modules = collections.OrderedDict() + self.classes = collections.OrderedDict() clinic.clinic = self self.name = "FakeClinic" + self.line_prefix = self.line_suffix = '' + self.destinations = {} + self.add_destination("block", "buffer") + self.add_destination("file", "buffer") + self.add_destination("suppress", "suppress") + d = self.destinations.get + self.field_destinations = collections.OrderedDict(( + ('docstring_prototype', d('suppress')), + ('docstring_definition', d('block')), + ('methoddef_define', d('block')), + ('impl_prototype', d('block')), + ('parser_prototype', d('suppress')), + ('parser_definition', d('block')), + ('impl_definition', d('block')), + )) + + def get_destination(self, name): + d = self.destinations.get(name) + if not d: + sys.exit("Destination does not exist: " + repr(name)) + return d + + def add_destination(self, name, type, *args): + if name in self.destinations: + sys.exit("Destination already exists: " + repr(name)) + self.destinations[name] = clinic.Destination(name, type, self, *args) def is_directive(self, name): return name == "module" @@ -54,6 +84,25 @@ def directive(self, name, args): _module_and_class = clinic.Clinic._module_and_class +class ClinicWholeFileTest(TestCase): + def test_eol(self): + # regression test: + # clinic's block parser didn't recognize + # the "end line" for the block if it + # didn't end in "\n" (as in, the last) + # byte of the file was '/'. + # so it woudl spit out an end line for you. + # and since you really already had one, + # the last line of the block got corrupted. + c = clinic.Clinic(clinic.CLanguage(None)) + raw = "/*[clinic]\nfoo\n[clinic]*/" + cooked = c.parse(raw).splitlines() + end_line = cooked[2].rstrip() + # this test is redundant, it's just here explicitly to catch + # the regression test so we don't forget what it looked like + self.assertNotEqual(end_line, "[clinic]*/[clinic]*/") + self.assertEqual(end_line, "[clinic]*/") + class ClinicGroupPermuterTest(TestCase): @@ -173,7 +222,7 @@ def parse(self, block): class ClinicBlockParserTest(TestCase): def _test(self, input, output): - language = clinic.CLanguage() + language = clinic.CLanguage(None) blocks = list(clinic.BlockParser(input, language)) writer = clinic.BlockPrinter(language) @@ -203,7 +252,7 @@ def test_round_trip_2(self): """) def _test_clinic(self, input, output): - language = clinic.CLanguage() + language = clinic.CLanguage(None) c = clinic.Clinic(language) c.parsers['inert'] = InertParser(c) c.parsers['copy'] = CopyParser(c) @@ -214,20 +263,20 @@ def test_clinic_1(self): self._test_clinic(""" verbatim text here lah dee dah -/*[copy] +/*[copy input] def -[copy]*/ +[copy start generated code]*/ abc -/*[copy checksum: 03cfd743661f07975fa2f1220c5194cbaff48451]*/ +/*[copy end generated code: output=03cfd743661f0797 input=7b18d017f89f61cf]*/ xyz """, """ verbatim text here lah dee dah -/*[copy] +/*[copy input] def -[copy]*/ +[copy start generated code]*/ def -/*[copy checksum: 7b18d017f89f61cf17d47f92749ea6930a3f1deb]*/ +/*[copy end generated code: output=7b18d017f89f61cf input=7b18d017f89f61cf]*/ xyz """) @@ -250,7 +299,7 @@ def test_ignore_line(self): def test_param(self): function = self.parse_function("module os\nos.access\n path: int") self.assertEqual("access", function.name) - self.assertEqual(1, len(function.parameters)) + self.assertEqual(2, len(function.parameters)) p = function.parameters['path'] self.assertEqual('path', p.name) self.assertIsInstance(p.converter, clinic.int_converter) @@ -260,32 +309,46 @@ def test_param_default(self): p = function.parameters['follow_symlinks'] self.assertEqual(True, p.default) + def test_param_with_continuations(self): + function = self.parse_function("module os\nos.access\n follow_symlinks: \\\n bool \\\n =\\\n True") + p = function.parameters['follow_symlinks'] + self.assertEqual(True, p.default) + + def test_param_default_expression(self): + function = self.parse_function("module os\nos.access\n follow_symlinks: int(c_default='MAXSIZE') = sys.maxsize") + p = function.parameters['follow_symlinks'] + self.assertEqual(sys.maxsize, p.default) + self.assertEqual("MAXSIZE", p.converter.c_default) + + s = self.parse_function_should_fail("module os\nos.access\n follow_symlinks: int = sys.maxsize") + self.assertEqual(s, "Error on line 0:\nWhen you specify a named constant ('sys.maxsize') as your default value,\nyou MUST specify a valid c_default.\n") + def test_param_no_docstring(self): function = self.parse_function(""" module os os.access follow_symlinks: bool = True - something_else: str""") + something_else: str = ''""") p = function.parameters['follow_symlinks'] - self.assertEqual(2, len(function.parameters)) + self.assertEqual(3, len(function.parameters)) self.assertIsInstance(function.parameters['something_else'].converter, clinic.str_converter) + def test_param_default_parameters_out_of_order(self): + s = self.parse_function_should_fail(""" +module os +os.access + follow_symlinks: bool = True + something_else: str""") + self.assertEqual(s, """Error on line 0: +Can't have a parameter without a default ('something_else') +after a parameter with a default! +""") + def disabled_test_converter_arguments(self): function = self.parse_function("module os\nos.access\n path: path_t(allow_fd=1)") p = function.parameters['path'] self.assertEqual(1, p.converter.args['allow_fd']) - def test_param_docstring(self): - function = self.parse_function(""" -module os -os.stat as os_stat_fn -> object(doc_default='stat_result') - - path: str - Path to be examined""") - p = function.parameters['path'] - self.assertEqual("Path to be examined", p.docstring) - self.assertEqual(function.return_converter.doc_default, 'stat_result') - def test_function_docstring(self): function = self.parse_function(""" module os @@ -296,9 +359,11 @@ def test_function_docstring(self): Perform a stat system call on the given path.""") self.assertEqual(""" +stat($module, /, path) +-- + Perform a stat system call on the given path. -os.stat(path) path Path to be examined """.strip(), function.docstring) @@ -316,9 +381,11 @@ def test_explicit_parameters_in_docstring(self): Okay, we're done here. """) self.assertEqual(""" +bar($module, /, x, y) +-- + This is the documentation for foo. -foo.bar(x, y) x Documentation for x. @@ -332,7 +399,7 @@ def test_parser_regression_special_character_in_parameter_column_of_docstring_fi path: str This/used to break Clinic! """) - self.assertEqual("os.stat(path)\n\nThis/used to break Clinic!", function.docstring) + self.assertEqual("stat($module, /, path)\n--\n\nThis/used to break Clinic!", function.docstring) def test_c_name(self): function = self.parse_function("module os\nos.stat as os_stat_fn") @@ -356,7 +423,7 @@ def test_group(self): def test_left_group(self): function = self.parse_function(""" module curses -curses.window.addch +curses.addch [ y: int Y-coordinate. @@ -380,7 +447,9 @@ def test_left_group(self): self.assertEqual(p.group, group) self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY) self.assertEqual(function.docstring.strip(), """ -curses.window.addch([y, x,] ch, [attr]) +addch([y, x,] ch, [attr]) + + y Y-coordinate. x @@ -394,7 +463,7 @@ def test_left_group(self): def test_nested_groups(self): function = self.parse_function(""" module curses -curses.window.imaginary +curses.imaginary [ [ y1: int @@ -439,7 +508,10 @@ def test_nested_groups(self): self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY) self.assertEqual(function.docstring.strip(), """ -curses.window.imaginary([[y1, y2,] x1, x2,] ch, [attr1, attr2, attr3, [attr4, attr5, attr6]]) +imaginary([[y1, y2,] x1, x2,] ch, [attr1, attr2, attr3, [attr4, attr5, + attr6]]) + + y1 Y-coordinate. y2 @@ -484,7 +556,7 @@ def test_disallowed_grouping__two_top_groups_on_left(self): """) self.assertEqual(s, ('Error on line 0:\n' - 'Function two_top_groups_on_left has an unsupported group configuration. (Unexpected state 2)\n')) + 'Function two_top_groups_on_left has an unsupported group configuration. (Unexpected state 2.b)\n')) def test_disallowed_grouping__two_top_groups_on_right(self): self.parse_function_should_fail(""" @@ -557,8 +629,22 @@ def test_no_parameters(self): Docstring """) - self.assertEqual("Docstring\n\nfoo.bar()", function.docstring) - self.assertEqual(0, len(function.parameters)) + self.assertEqual("bar($module, /)\n--\n\nDocstring", function.docstring) + self.assertEqual(1, len(function.parameters)) # self! + + def test_init_with_no_parameters(self): + function = self.parse_function(""" +module foo +class foo.Bar "unused" "notneeded" +foo.Bar.__init__ + +Docstring + +""", signatures_in_block=3, function_index=2) + # self is not in the signature + self.assertEqual("Bar()\n--\n\nDocstring", function.docstring) + # but it *is* a parameter + self.assertEqual(1, len(function.parameters)) def test_illegal_module_line(self): self.parse_function_should_fail(""" @@ -652,9 +738,11 @@ def test_function_not_at_column_0(self): Not at column 0! """) self.assertEqual(""" +bar($module, /, x, *, y) +-- + Not at column 0! -foo.bar(x, *, y) x Nested docstring here, goeth. """.strip(), function.docstring) @@ -666,7 +754,7 @@ def test_parser_regression_special_character_in_parameter_column_of_docstring_fi path: str This/used to break Clinic! """) - self.assertEqual("This/used to break Clinic!\n\nos.stat(path)", function.docstring) + self.assertEqual("stat($module, /, path)\n--\n\nThis/used to break Clinic!", function.docstring) def test_directive(self): c = FakeClinic() @@ -689,13 +777,13 @@ def parse(self, text): parser.parse(block) return block - def parse_function(self, text): + def parse_function(self, text, signatures_in_block=2, function_index=1): block = self.parse(text) s = block.signatures - assert len(s) == 2 + self.assertEqual(len(s), signatures_in_block) assert isinstance(s[0], clinic.Module) - assert isinstance(s[1], clinic.Function) - return s[1] + assert isinstance(s[function_index], clinic.Function) + return s[function_index] def test_scaffolding(self): # test repr on special values diff --git a/Tools/clinic/cpp.py b/Tools/clinic/cpp.py new file mode 100644 index 000000000000..e099590a3326 --- /dev/null +++ b/Tools/clinic/cpp.py @@ -0,0 +1,191 @@ +import re +import sys + +def negate(condition): + """ + Returns a CPP conditional that is the opposite of the conditional passed in. + """ + if condition.startswith('!'): + return condition[1:] + return "!" + condition + +class Monitor: + """ + A simple C preprocessor that scans C source and computes, line by line, + what the current C preprocessor #if state is. + + Doesn't handle everything--for example, if you have /* inside a C string, + without a matching */ (also inside a C string), or with a */ inside a C + string but on another line and with preprocessor macros in between... + the parser will get lost. + + Anyway this implementation seems to work well enough for the CPython sources. + """ + + is_a_simple_defined = re.compile(r'^defined\s*\(\s*[A-Za-z0-9_]+\s*\)$').match + + def __init__(self, filename=None, *, verbose=False): + self.stack = [] + self.in_comment = False + self.continuation = None + self.line_number = 0 + self.filename = filename + self.verbose = verbose + + def __repr__(self): + return ''.join(( + '")) + + def status(self): + return str(self.line_number).rjust(4) + ": " + self.condition() + + def condition(self): + """ + Returns the current preprocessor state, as a single #if condition. + """ + return " && ".join(condition for token, condition in self.stack) + + def fail(self, *a): + if self.filename: + filename = " " + self.filename + else: + filename = '' + print("Error at" + filename, "line", self.line_number, ":") + print(" ", ' '.join(str(x) for x in a)) + sys.exit(-1) + + def close(self): + if self.stack: + self.fail("Ended file while still in a preprocessor conditional block!") + + def write(self, s): + for line in s.split("\n"): + self.writeline(line) + + def writeline(self, line): + self.line_number += 1 + line = line.strip() + + def pop_stack(): + if not self.stack: + self.fail("#" + token + " without matching #if / #ifdef / #ifndef!") + return self.stack.pop() + + if self.continuation: + line = self.continuation + line + self.continuation = None + + if not line: + return + + if line.endswith('\\'): + self.continuation = line[:-1].rstrip() + " " + return + + # we have to ignore preprocessor commands inside comments + # + # we also have to handle this: + # /* start + # ... + # */ /* <-- tricky! + # ... + # */ + # and this: + # /* start + # ... + # */ /* also tricky! */ + if self.in_comment: + if '*/' in line: + # snip out the comment and continue + # + # GCC allows + # /* comment + # */ #include + # maybe other compilers too? + _, _, line = line.partition('*/') + self.in_comment = False + + while True: + if '/*' in line: + if self.in_comment: + self.fail("Nested block comment!") + + before, _, remainder = line.partition('/*') + comment, comment_ends, after = remainder.partition('*/') + if comment_ends: + # snip out the comment + line = before.rstrip() + ' ' + after.lstrip() + continue + # comment continues to eol + self.in_comment = True + line = before.rstrip() + break + + # we actually have some // comments + # (but block comments take precedence) + before, line_comment, comment = line.partition('//') + if line_comment: + line = before.rstrip() + + if not line.startswith('#'): + return + + line = line[1:].lstrip() + assert line + + fields = line.split() + token = fields[0].lower() + condition = ' '.join(fields[1:]).strip() + + if_tokens = {'if', 'ifdef', 'ifndef'} + all_tokens = if_tokens | {'elif', 'else', 'endif'} + + if token not in all_tokens: + return + + # cheat a little here, to reuse the implementation of if + if token == 'elif': + pop_stack() + token = 'if' + + if token in if_tokens: + if not condition: + self.fail("Invalid format for #" + token + " line: no argument!") + if token == 'if': + if not self.is_a_simple_defined(condition): + condition = "(" + condition + ")" + else: + fields = condition.split() + if len(fields) != 1: + self.fail("Invalid format for #" + token + " line: should be exactly one argument!") + symbol = fields[0] + condition = 'defined(' + symbol + ')' + if token == 'ifndef': + condition = '!' + condition + + self.stack.append(("if", condition)) + if self.verbose: + print(self.status()) + return + + previous_token, previous_condition = pop_stack() + + if token == 'else': + self.stack.append(('else', negate(previous_condition))) + elif token == 'endif': + pass + if self.verbose: + print(self.status()) + +if __name__ == '__main__': + for filename in sys.argv[1:]: + with open(filename, "rt") as f: + cpp = Monitor(filename, verbose=True) + print() + print(filename) + for line_number, line in enumerate(f.read().split('\n'), 1): + cpp.writeline(line) diff --git a/Tools/freeze/freeze.py b/Tools/freeze/freeze.py index 479ca3c14b47..e0c6c2c580a7 100755 --- a/Tools/freeze/freeze.py +++ b/Tools/freeze/freeze.py @@ -219,6 +219,7 @@ def main(): # locations derived from options version = sys.version[:3] + flagged_version = version + sys.abiflags if win: extensions_c = 'frozen_extensions.c' if ishome: @@ -233,10 +234,11 @@ def main(): frozendllmain_c = os.path.join(exec_prefix, 'Pc\\frozen_dllmain.c') else: binlib = os.path.join(exec_prefix, - 'lib', 'python%s' % version, 'config') - incldir = os.path.join(prefix, 'include', 'python%s' % version) + 'lib', 'python%s' % version, + 'config-%s' % flagged_version) + incldir = os.path.join(prefix, 'include', 'python%s' % flagged_version) config_h_dir = os.path.join(exec_prefix, 'include', - 'python%s' % version) + 'python%s' % flagged_version) config_c_in = os.path.join(binlib, 'config.c.in') frozenmain_c = os.path.join(binlib, 'frozenmain.c') makefile_in = os.path.join(binlib, 'Makefile') @@ -363,6 +365,10 @@ def main(): else: mf.load_file(mod) + # Alias "importlib._bootstrap" to "_frozen_importlib" so that the + # import machinery can bootstrap. + mf.modules["_frozen_importlib"] = mf.modules["importlib._bootstrap"] + # Add the main script as either __main__, or the actual module name. if python_entry_is_main: mf.run_script(scriptfile) @@ -455,7 +461,7 @@ def main(): cflags = ['$(OPT)'] cppflags = defines + includes - libs = [os.path.join(binlib, 'libpython$(VERSION).a')] + libs = [os.path.join(binlib, '$(LDLIBRARY)')] somevars = {} if os.path.exists(makefile_in): diff --git a/Tools/freeze/makeconfig.py b/Tools/freeze/makeconfig.py index 018992c75347..fabaace07a83 100644 --- a/Tools/freeze/makeconfig.py +++ b/Tools/freeze/makeconfig.py @@ -3,7 +3,7 @@ # Write the config.c file -never = ['marshal', 'imp', '_ast', '__main__', 'builtins', +never = ['marshal', '_imp', '_ast', '__main__', 'builtins', 'sys', 'gc', '_warnings'] def makeconfig(infp, outfp, modules, with_ifdef=0): diff --git a/Tools/freeze/test/Makefile b/Tools/freeze/test/Makefile new file mode 100644 index 000000000000..1679f723e7ac --- /dev/null +++ b/Tools/freeze/test/Makefile @@ -0,0 +1,11 @@ +# Makefile to test freeze +# set PYTHON to path of Python interpreter to test +PYTHON=python +# set OUTDIR to the temp directory for freeze +OUTDIR=outdir + +test: + $(PYTHON) ../freeze.py -o $(OUTDIR) ok.py + make -C $(OUTDIR) + $(OUTDIR)/ok + diff --git a/Tools/freeze/test/ok.py b/Tools/freeze/test/ok.py new file mode 100644 index 000000000000..e15e0b45032e --- /dev/null +++ b/Tools/freeze/test/ok.py @@ -0,0 +1,2 @@ +import sys +sys.exit(0) diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py old mode 100644 new mode 100755 diff --git a/Tools/hg/hgtouch.py b/Tools/hg/hgtouch.py index cf139202ea24..119d81214826 100644 --- a/Tools/hg/hgtouch.py +++ b/Tools/hg/hgtouch.py @@ -36,12 +36,16 @@ def parse_config(repo): result[o] = inputs return result -def check_rule(ui, repo, modified, output, inputs): +def check_rule(ui, repo, modified, basedir, output, inputs): """Verify that the output is newer than any of the inputs. Return (status, stamp), where status is True if the update succeeded, and stamp is the newest time stamp assigned to any file (might be in - the future).""" - f_output = repo.wjoin(output) + the future). + + If basedir is nonempty, it gives a directory in which the tree is to + be checked. + """ + f_output = repo.wjoin(os.path.join(basedir, output)) try: o_time = os.stat(f_output).st_mtime except OSError: @@ -51,7 +55,7 @@ def check_rule(ui, repo, modified, output, inputs): backdate = None backdate_source = None for i in inputs: - f_i = repo.wjoin(i) + f_i = repo.wjoin(os.path.join(basedir, i)) try: i_time = os.stat(f_i).st_mtime except OSError: @@ -79,8 +83,14 @@ def check_rule(ui, repo, modified, output, inputs): # Nothing to update return True, 0 -def do_touch(ui, repo): - modified = repo.status()[0] +def do_touch(ui, repo, basedir): + if basedir: + if not os.path.isdir(repo.wjoin(basedir)): + ui.warn("Abort: basedir %r does not exist\n" % basedir) + return + modified = [] + else: + modified = repo.status()[0] dependencies = parse_config(repo) success = True tstamp = 0 # newest time stamp assigned @@ -93,8 +103,8 @@ def do_touch(ui, repo): if i in dependencies: hold_back[output] = inputs continue - _success, _tstamp = check_rule(ui, repo, modified, output, inputs) - sucess = success and _success + _success, _tstamp = check_rule(ui, repo, modified, basedir, output, inputs) + success = success and _success tstamp = max(tstamp, _tstamp) # put back held back rules dependencies.update(hold_back) @@ -109,11 +119,12 @@ def do_touch(ui, repo): return False return success -def touch(ui, repo): +def touch(ui, repo, basedir): "touch generated files that are older than their sources after an update." - do_touch(ui, repo) + do_touch(ui, repo, basedir) cmdtable = { - "touch": (touch, [], - "touch generated files according to the .hgtouch configuration") + "touch": (touch, + [('b', 'basedir', '', 'base dir of the tree to apply touching')], + "hg touch [-b BASEDIR]") } diff --git a/Tools/i18n/makelocalealias.py b/Tools/i18n/makelocalealias.py old mode 100644 new mode 100755 index 68544ac27b9b..c7ecacec3877 --- a/Tools/i18n/makelocalealias.py +++ b/Tools/i18n/makelocalealias.py @@ -7,14 +7,18 @@ """ import locale +import sys +_locale = locale -# Location of the alias file +# Location of the X11 alias file. LOCALE_ALIAS = '/usr/share/X11/locale/locale.alias' +# Location of the glibc SUPPORTED locales file. +SUPPORTED = '/usr/share/i18n/SUPPORTED' def parse(filename): - f = open(filename) - lines = f.read().splitlines() + with open(filename, encoding='latin1') as f: + lines = list(f) data = {} for line in lines: line = line.strip() @@ -23,6 +27,12 @@ def parse(filename): if line[:1] == '#': continue locale, alias = line.split() + # Fix non-standard locale names, e.g. ks_IN@devanagari.UTF-8 + if '@' in alias: + alias_lang, _, alias_mod = alias.partition('@') + if '.' in alias_mod: + alias_mod, _, alias_enc = alias_mod.partition('.') + alias = alias_lang + '.' + alias_enc + '@' + alias_mod # Strip ':' if locale[-1] == ':': locale = locale[:-1] @@ -37,31 +47,102 @@ def parse(filename): encoding = encoding.replace('-', '') encoding = encoding.replace('_', '') locale = lang + '.' + encoding - if encoding.lower() == 'utf8': - # Ignore UTF-8 mappings - this encoding should be - # available for all locales - continue + data[locale] = alias + return data + +def parse_glibc_supported(filename): + + with open(filename, encoding='latin1') as f: + lines = list(f) + data = {} + for line in lines: + line = line.strip() + if not line: + continue + if line[:1] == '#': + continue + line = line.replace('/', ' ').strip() + line = line.rstrip('\\').rstrip() + words = line.split() + if len(words) != 2: + continue + alias, alias_encoding = words + # Lower-case locale + locale = alias.lower() + # Normalize encoding, if given + if '.' in locale: + lang, encoding = locale.split('.')[:2] + encoding = encoding.replace('-', '') + encoding = encoding.replace('_', '') + locale = lang + '.' + encoding + # Add an encoding to alias + alias, _, modifier = alias.partition('@') + alias = _locale._replace_encoding(alias, alias_encoding) + if modifier and not (modifier == 'euro' and alias_encoding == 'ISO-8859-15'): + alias += '@' + modifier data[locale] = alias return data def pprint(data): items = sorted(data.items()) for k, v in items: - print(' %-40s%r,' % ('%r:' % k, v)) + print(' %-40s%a,' % ('%a:' % k, v)) def print_differences(data, olddata): items = sorted(olddata.items()) for k, v in items: if k not in data: - print('# removed %r' % k) + print('# removed %a' % k) elif olddata[k] != data[k]: - print('# updated %r -> %r to %r' % \ + print('# updated %a -> %a to %a' % \ (k, olddata[k], data[k])) # Additions are not mentioned +def optimize(data): + locale_alias = locale.locale_alias + locale.locale_alias = data.copy() + for k, v in data.items(): + del locale.locale_alias[k] + if locale.normalize(k) != v: + locale.locale_alias[k] = v + newdata = locale.locale_alias + errors = check(data) + locale.locale_alias = locale_alias + if errors: + sys.exit(1) + return newdata + +def check(data): + # Check that all alias definitions from the X11 file + # are actually mapped to the correct alias locales. + errors = 0 + for k, v in data.items(): + if locale.normalize(k) != v: + print('ERROR: %a -> %a != %a' % (k, locale.normalize(k), v), + file=sys.stderr) + errors += 1 + return errors + if __name__ == '__main__': + import argparse + parser = argparse.ArgumentParser() + parser.add_argument('--locale-alias', default=LOCALE_ALIAS, + help='location of the X11 alias file ' + '(default: %a)' % LOCALE_ALIAS) + parser.add_argument('--glibc-supported', default=SUPPORTED, + help='location of the glibc SUPPORTED locales file ' + '(default: %a)' % SUPPORTED) + args = parser.parse_args() + data = locale.locale_alias.copy() - data.update(parse(LOCALE_ALIAS)) + data.update(parse_glibc_supported(args.glibc_supported)) + data.update(parse(args.locale_alias)) + while True: + # Repeat optimization while the size is decreased. + n = len(data) + data = optimize(data) + if len(data) == n: + break print_differences(data, locale.locale_alias) print() print('locale_alias = {') diff --git a/Tools/i18n/pygettext.py b/Tools/i18n/pygettext.py index 79d976bc01fe..9ffeb17d6b12 100755 --- a/Tools/i18n/pygettext.py +++ b/Tools/i18n/pygettext.py @@ -1,6 +1,6 @@ #! /usr/bin/env python3 # -*- coding: iso-8859-1 -*- -# Originally written by Barry Warsaw +# Originally written by Barry Warsaw # # Minimally patched to make it even more xgettext compatible # by Peter Funk diff --git a/Tools/msi/README.txt b/Tools/msi/README.txt index dc4ae90cf2b9..1e41cc1f6caa 100644 --- a/Tools/msi/README.txt +++ b/Tools/msi/README.txt @@ -1,25 +1,488 @@ -Packaging Python as a Microsoft Installer Package (MSI) -======================================================= - -Using this library, Python can be packaged as a MS-Windows -MSI file. To generate an installer package, you need -a build tree. By default, the build tree root directory -is assumed to be in "../..". This location can be changed -by adding a file config.py; see the beginning of msi.py -for additional customization options. - -The packaging process assumes that binaries have been -generated according to the instructions in PCBuild/README.txt, -and that you have either Visual Studio or the Platform SDK -installed. In addition, you need the Python COM extensions, -either from PythonWin, or from ActivePython. - -To invoke the script, open a cmd.exe window which has -cabarc.exe in its PATH (e.g. "Visual Studio .NET 2003 -Command Prompt"). Then invoke - - msi.py - -If everything succeeds, pythonX.Y.Z.msi is generated -in the current directory. +Quick Build Info +================ + +For testing, the installer should be built with the Tools/msi/build.bat +script: + + build.bat [-x86] [-x64] [--doc] + +For an official release, the installer should be built with the +Tools/msi/buildrelease.bat script and environment variables: + + set PYTHON= + set SPHINXBUILD= + set PATH=; + ;%PATH% + + buildrelease.bat [-x86] [-x64] [-D] [-B] + [-o ] [-c ] + +See the Building the Installer section for more information. + +Overview +======== + +Python is distributed on Windows as an installer that will configure the +user's system. This allows users to have a functioning copy of Python +without having to build it themselves. + +The main tasks of the installer are: + +* copy required files into the expected layout +* configure system settings so the installation can be located by + other programs +* add entry points for modifying, repairing and uninstalling Python +* make it easy to launch Python, its documentation, and IDLE + +Each of these is discussed in a later section of this document. + +Structure of the Installer +========================== + +The installer is structured as a 'layout', which consists of a number of +CAB and MSI files and a single EXE. + +The EXE is the main entry point into the installer. It contains the UI +and command-line logic, as well as the ability to locate and optionally +download other parts of the layout. + +Each MSI contains the logic required to install a component or feature +of Python. These MSIs should not be launched directly by users. MSIs can +be embedded into the EXE or automatically downloaded as needed. + +Each CAB contains the files making up a Python installation. CABs are +embedded into their associated MSI and are never seen by users. + +MSIs are only required when the related feature or component is being +installed. When components are not selected for installation, the +associated MSI is not downloaded. This allows the installer to offer +options to install debugging symbols and binaries without increasing +the initial download size by separating them into their own MSIs. + +Building the Installer +====================== + +For testing, the installer should be built with the Tools/msi/build.bat +script: + + build.bat [-x86] [-x64] [--doc] + +This script will build the required configurations of Python and +generate an installer layout in PCBuild/(win32|amd64)/en-us. + +Specify -x86 and/or -x64 to build for each platform. If neither is +specified, both platforms will be built. Currently, both the debug and +release versions of Python are required for the installer. + +Specify --doc to build the documentation (.chm) file. If the file is not +available, it will simply be excluded from the installer. Ensure +%PYTHON% and %SPHINXBUILD% are set when passing this option. You may +also set %HTMLHELP% to the Html Help Compiler (hhc.exe), or put HHC on +your PATH or in externals/. + +If WiX is not found on your system, it will be automatically downloaded +and extracted to the externals/ directory. + + +For an official release, the installer should be built with the +Tools/msi/buildrelease.bat script: + + set PYTHON= + set SPHINXBUILD= + set PATH=; + ;%PATH% + + buildrelease.bat [-x86] [-x64] [-D] [-B] + [-o ] [-c ] + +Specify -x86 and/or -x64 to build for each platform. If neither is +specified, both platforms will be built. Currently, both the debug and +release versions of Python are required for the installer. + +Specify -D to skip rebuilding the documentation. The documentation is +required for a release and the build will fail if it is not available. + +Specify -B to skip rebuilding Python. This is useful to only rebuild the +installer layout after a previous call to buildrelease.bat. + +Specify -o to set an output directory. The installer layouts will be +copied to platform-specific subdirectories of this path. + +Specify -c to choose a code-signing certificate to be used for all the +signable binaries in Python as well as each file making up the +installer. Official releases of Python must be signed. + +Ensure %PYTHON% and %SPHINXBUILD% are set when passing this option. You +may also set %HTMLHELP% to the Html Help Compiler (hhc.exe), or put HHC +on your PATH or in externals/. You will also need Mercurial (hg.exe) on +your PATH. + +If WiX is not found on your system, it will be automatically downloaded +and extracted to the externals/ directory. + +To manually build layouts of the installer, build one of the projects in +the bundle folder. + + msbuild bundle\snapshot.wixproj + msbuild bundle\releaseweb.wixproj + msbuild bundle\releaselocal.wixproj + msbuild bundle\full.wixproj + +snapshot.wixproj produces a test installer versioned based on the date. + +releaseweb.wixproj produces a release installer that does not embed any +of the layout. + +releaselocal.wixproj produces a release installer that embeds the files +required for a default installation. + +full.wixproj produces a test installer that embeds the entire layout. + +The following properties may be passed when building these projects. + + /p:BuildForRelease=(true|false) + When true, adds extra verification to ensure a complete installer is + produced. For example, binutils is required when building for a release + to generate MinGW-compatible libraries, and the build will be aborted if + this fails. Defaults to false. + + /p:ReleaseUri=(any URI) + Used to generate unique IDs for the installers to allow side-by-side + installation. Forks of Python can use the same installer infrastructure + by providing a unique URI for this property. It does not need to be an + active internet address. Defaults to $(ComputerName). + + Official releases use http://www.python.org/(architecture name) + + /p:DownloadUrlBase=(any URI) + Specifies the base of a URL where missing parts of the installer layout + can be downloaded from. The build version and architecture will be + appended to create the full address. If omitted, missing components will + not be automatically downloaded. + + /p:DownloadUrl=(any URI) + Specifies the full URL where missing parts of the installer layout can + be downloaded from. Should normally include '{2}', which will be + substituted for the filename. If omitted, missing components will not be + automatically downloaded. If specified, this value overrides + DownloadUrlBase. + + /p:SigningCertificate=(certificate name) + Specifies the certificate to sign the installer layout with. If omitted, + the layout will not be signed. + + /p:RebuildAll=(true|false) + When true, rebuilds all of the MSIs making up the layout. Defaults to + true. + +Modifying the Installer +======================= + +The code for the installer is divided into three main groups: packages, +the bundle and the bootstrap application. + +Packages +-------- + +Packages appear as subdirectories of Tools/msi (other than the bundle/ +directory). The project file is a .wixproj and the build output is a +single MSI. Packages are built with the WiX Toolset. Some project files +share source files and use preprocessor directives to enable particular +features. These are typically used to keep the sources close when the +files are related, but produce multiple independent packages. + +A package is the smallest element that may be independently installed or +uninstalled (as used in this installer). For example, the test suite has +its own package, as users can choose to add or remove it after the +initial installation. + +All the files installed by a single package should be related, though +some packages may not install any files. For example, the pip package +executes the ensurepip package, but does not add or remove any of its +own files. (It is represented as a package because of its +installed/uninstalled nature, as opposed to the "precompile standard +library" option, for example.) Dependencies between packages are handled +by the bundle, but packages should detect when dependencies are missing +and raise an error. + +Packages that include a lot of files may use an InstallFiles element in +the .wixproj file to generate sources. See lib/lib.wixproj for an +example, and msi.targets and csv_to_wxs.py for the implementation. This +element is also responsible for generating the code for cleaning up and +removing __pycache__ folders in any directory containing .py files. + +All packages are built with the Tools/msi/common.wxs file, and so any +directory or property in this file may be referenced. Of particular +interest: + + REGISTRYKEY (property) + The registry key for the current installation. + + InstallDirectory (directory) + The root install directory for the current installation. Subdirectories + are also specified in this file (DLLs, Lib, etc.) + + MenuDir (directory) + The Start Menu folder for the current installation. + + UpgradeTable (property) + Every package should reference this property to include upgrade + information. + +The .wxl_template file is specially handled by the build system for this +project to perform {{substitutions}} as defined in msi.targets. They +should be included in projects as items, where .wxl files +are normally included as items. + +Bundle +------ + +The bundle is compiled to the main EXE entry point that for most users +will represent the Python installer. It is built from Tools/msi/bundle +with packages references in Tools/msi/bundle/packagegroups. + +Build logic for the bundle is in bundle.targets, but should be invoked +through one of the .wixproj files as described in Building the +Installer. + +The UI is separated between Default.thm (UI layout), Default.wxl +(strings), bundle.wxs (properties) and the bootstrap application. +Bundle.wxs also contains the chain, which is the list of packages to +install and the order they should be installed in. These refer to named +package groups in bundle/packagegroups. + +Each package group specifies one or more packages to install. Most +packages require two separate entries to support both per-user and +all-users installations. Because these reuse the same package, it does +not increase the overall size of the package. + +Package groups refer to payload groups, which allow better control over +embedding and downloading files than the default settings. Whether files +are embedded and where they are downloaded from depends on settings +created by the project files. + +Package references can include install conditions that determine when to +install the package. When a package is a dependency for others, the +condition should be crafted to ensure it is installed. + +MSI packages are installed or uninstalled based on their current state +and the install condition. This makes them most suitable for features +that are clearly present or absent from the user's machine. + +EXE packages are executed based on a customisable condition that can be +omitted. This makes them suitable for pre- or post-install tasks that +need to run regardless of whether features have been added or removed. + +Bootstrap Application +--------------------- + +The bootstrap application is a C++ application that controls the UI and +installation. While it does not directly compile into the main EXE of +the installer, it forms the main active component. Most of the +installation functionality is provided by WiX, and so the bootstrap +application is predominantly responsible for the code behind the UI that +is defined in the Default.thm file. The bootstrap application code is in +bundle/bootstrap and is built automatically when building the bundle. + +Installation Layout +=================== + +There are two installation layouts for Python on Windows, with the only +differences being supporting files. A layout is selected implicitly +based on whether the install is for all users of the machine or just for +the user performing the installation. + +The default installation location when installing for all users is +"%ProgramFiles%\Python 3.X" for the 64-bit interpreter and +"%ProgramFiles(x86)%\Python 3.X" for the 32-bit interpreter. (Note that +the latter path is equivalent to "%ProgramFiles%\Python 3.X" when +running a 32-bit version of Windows.) This location requires +administrative privileges to install or later modify the installation. + +The default installation location when installing for the current user +is "%LocalAppData%\Programs\Python\Python3X" for the 64-bit interpreter +and "%LocalAppData%\Programs\Python\Python3X-32" for the 32-bit +interpreter. Only the current user can access this location. This +provides a suitable level of protection against malicious modification +of Python's files. + +Within this install directory is the following approximate layout: + +.\python[w].exe The core executable files +.\DLLs Stdlib extensions (*.pyd) and dependencies +.\Doc Documentation (*.chm) +.\include Development headers (*.h) +.\Lib Standard library +.\Lib\test Test suite +.\libs Development libraries (*.lib) +.\Scripts Launcher scripts (*.exe, *.py) +.\tcl Tcl dependencies (*.dll, *.tcl and others) +.\Tools Tool scripts (*.py) + +When installed for all users, the following files are installed to +either "%SystemRoot%\System32" or "%SystemRoot%\SysWOW64" as +appropriate. For the current user, they are installed in the Python +install directory. + +.\python3x.dll The core interpreter +.\python3.dll The stable ABI reference +.\appcrt140.dll Microsoft Visual C Runtime +.\desktopcrt140.dll Microsoft Visual C Runtime +.\vcruntime140.dll Microsoft Visual C Runtime + +When installed for all users, the following files are installed to +"%SystemRoot%" (typically "C:\Windows") to ensure they are always +available on PATH. (See Launching Python below.) For the current user, +they are installed in the Python install directory. + +.\py[w].exe PEP 397 launcher + +System Settings +=============== + +On installation, registry keys are created so that other applications +can locate and identify installations of Python. The locations of these +keys vary based on the install type. + +For 64-bit interpreters installed for all users, the root key is: + HKEY_LOCAL_MACHINE\Software\Python\PythonCore\3.X + +For 32-bit interpreters installed for all users on a 64-bit operating +system, the root key is: + HKEY_LOCAL_MACHINE\Software\Wow6432Node\Python\PythonCore\3.X-32 + +For 32-bit interpreters installed for all users on a 32-bit operating +system, the root key is: + HKEY_LOCAL_MACHINE\Software\Python\PythonCore\3.X-32 + +For 64-bit interpreters installed for the current user: + HKEY_CURRENT_USER\Software\Python\PythonCore\3.X + +For 32-bit interpreters installed for the current user: + HKEY_CURRENT_USER\Software\Python\PythonCore\3.X-32 + +When the core Python executables are installed, a key "InstallPath" is +created within the root key with its default value set to the +executable's install directory. Within this key, a key "InstallGroup" is +created with its default value set to the product name "Python 3.X". + +When the Python standard library is installed, a key "PythonPath" is +created within the root key with its default value set to the full path +to the Lib folder followed by the path to the DLLs folder, separated by +a semicolon. + +When the documentation is installed, a key "Help" is created within the +root key, with a subkey "Main Python Documentation" with its default +value set to the full path to the installed CHM file. + + +The py.exe launcher is installed as part of a regular Python install, +but using a separate mechanism that allows it to more easily span +versions of Python. As a result, it has different root keys for its +registry entries: + +When installed for all users on a 64-bit operating system, the +launcher's root key is: + HKEY_LOCAL_MACHINE\Software\Wow6432Node\Python\Launcher + +When installed for all users on a 32-bit operating system, the +launcher's root key is: + HKEY_LOCAL_MACHINE\Software\Python\Launcher + +When installed for the current user: + HKEY_CURRENT_USER\Software\Python\Launcher + +When the launcher is installed, a key "InstallPath" is created within +its root key with its default value set to the launcher's install +directory. File associations are also created for .py, .pyw, .pyc and +.pyo files. + +Launching Python +================ + +When a feature offering user entry points in the Start Menu is +installed, a folder "Python 3.X" is created. Every shortcut should be +created within this folder, and each shortcut should include the version +and platform to allow users to identify the shortcut in a search results +page. + +The core Python executables creates a shortcut "Python 3.X (32-bit)" or +"Python 3.X (64-bit)" depending on the interpreter. + +The documentation creates a shortcut "Python 3.X 32-bit Manuals" or +"Python 3.X 64-bit Manuals". The documentation is identical for all +platforms, but the shortcuts need to be separate to avoid uninstallation +conflicts. + +Installing IDLE creates a shortcut "IDLE (Python 3.X 32-bit)" or "IDLE +(Python 3.X 64-bit)" depending on the interpreter. + + +For users who often launch Python from a Command Prompt, an option is +provided to add the directory containing python.exe to the user or +system PATH variable. If the option is selected, the install directory +and the Scripts directory will be added at the start of the system PATH +for an all users install and the user PATH for a per-user install. + +When the user only has one version of Python installed, this will behave +as expected. However, because Windows searches the system PATH before +the user PATH, users cannot override a system-wide installation of +Python on their PATH. Further, because the installer can only prepend to +the path, later installations of Python will take precedence over +earlier installations, regardless of interpreter version. + +Because it is not possible to automatically create a sensible PATH +configuration, users are recommended to use the py.exe launcher and +manually modify their PATH variable to add Scripts directories in their +preferred order. System-wide installations of Python should consider not +modifying PATH, or using an alternative technology to modify their +users' PATH variables. + + +The py.exe launcher is recommended because it uses a consistent and +sensible search order for Python installations. User installations are +preferred over system-wide installs, and later versions are preferred +regardless of installation order (with the exception that py.exe +currently prefers 2.x versions over 3.x versions without the -3 command +line argument). + +For both 32-bit and 64-bit interpreters, the 32-bit version of the +launcher is installed. This ensures that the search order is always +consistent (as the 64-bit launcher is subtly different from the 32-bit +launcher) and also avoids the need to install it multiple times. Future +versions of Python will upgrade the launcher in-place, using Windows +Installer's upgrade functionality to avoid conflicts with earlier +installed versions. + +When installed, file associations are created for .py, .pyc and .pyo +files to launch with py.exe and .pyw files to launch with pyw.exe. This +makes Python files respect shebang lines by default and also avoids +conflicts between multiple Python installations. + + +Repair, Modify and Uninstall +============================ + +After installation, Python may be modified, repaired or uninstalled by +running the original EXE again or via the Programs and Features applet +(formerly known as Add or Remove Programs). + +Modifications allow features to be added or removed. The install +directory and kind (all users/single user) cannot be modified. Because +Windows Installer caches installation packages, removing features will +not require internet access unless the package cache has been corrupted +or deleted. Adding features that were not previously installed and are +not embedded or otherwise available will require internet access. + +Repairing will rerun the installation for all currently installed +features, restoring files and registry keys that have been modified or +removed. This operation generally will not redownload any files unless +the cached packages have been corrupted or deleted. + +Removing Python will clean up all the files and registry keys that were +created by the installer, as well as __pycache__ folders that are +explicitly handled by the installer. Python packages installed later +using a tool like pip will not be removed. Some components may be +installed by other installers (such as the MSVCRT) and these will not be +removed if another product has a dependency on them. diff --git a/Tools/msi/build.bat b/Tools/msi/build.bat new file mode 100644 index 000000000000..efee66bc254c --- /dev/null +++ b/Tools/msi/build.bat @@ -0,0 +1,46 @@ +@echo off +setlocal +set D=%~dp0 +set PCBUILD=%D%..\..\PCBuild\ + +set BUILDX86= +set BUILDX64= +set BUILDDOC= + +:CheckOpts +if '%1'=='-x86' (set BUILDX86=1) && shift && goto CheckOpts +if '%1'=='-x64' (set BUILDX64=1) && shift && goto CheckOpts +if '%1'=='--doc' (set BUILDDOC=1) && shift && goto CheckOpts + +if not defined BUILDX86 if not defined BUILDX64 (set BUILDX86=1) && (set BUILDX64=1) + +call "%PCBUILD%env.bat" x86 + +if defined BUILDX86 ( + call "%PCBUILD%build.bat" -d + if errorlevel 1 goto :eof + call "%PCBUILD%build.bat" + if errorlevel 1 goto :eof +) +if defined BUILDX64 ( + call "%PCBUILD%build.bat" -p x64 -d + if errorlevel 1 goto :eof + call "%PCBUILD%build.bat" -p x64 + if errorlevel 1 goto :eof +) + +if defined BUILDDOC ( + call "%PCBUILD%..\Doc\make.bat" htmlhelp + if errorlevel 1 goto :eof +) + +if defined BUILDX86 ( + "%PCBUILD%win32\python.exe" "%D%get_wix.py" + msbuild "%D%bundle\snapshot.wixproj" + if errorlevel 1 goto :eof +) +if defined BUILDX64 ( + "%PCBUILD%amd64\python.exe" "%D%get_wix.py" + msbuild "%D%bundle\snapshot.wixproj" /p:Platform=x64 + if errorlevel 1 goto :eof +) diff --git a/Tools/msi/buildrelease.bat b/Tools/msi/buildrelease.bat new file mode 100644 index 000000000000..3f2a94ad74da --- /dev/null +++ b/Tools/msi/buildrelease.bat @@ -0,0 +1,163 @@ +@setlocal +@echo off + +rem This script is intended for building official releases of Python. +rem To use it to build alternative releases, you should clone this file +rem and modify the following three URIs. +rem +rem The first two will ensure that your release can be installed +rem alongside an official Python release, while the second specifies +rem the URL that will be used to download installation files. The +rem files available from this URL *will* conflict with your installer. +rem Trust me, you don't want them, even if it seems like a good idea. + +set RELEASE_URI_X86=http://www.python.org/win32 +set RELEASE_URI_X64=http://www.python.org/amd64 +set DOWNLOAD_URL_BASE=https://www.python.org/ftp/python +set DOWNLOAD_URL= + +set D=%~dp0 +set PCBUILD=%D%..\..\PCBuild\ + +set BUILDX86= +set BUILDX64= +set TARGET=Rebuild +set TESTTARGETDIR= + + +:CheckOpts +if "%1" EQU "-h" goto Help +if "%1" EQU "-c" (set CERTNAME=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "--certificate" (set CERTNAME=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "-o" (set OUTDIR=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "--out" (set OUTDIR=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "-D" (set SKIPDOC=1) && shift && goto CheckOpts +if "%1" EQU "--skip-doc" (set SKIPDOC=1) && shift && goto CheckOpts +if "%1" EQU "-B" (set SKIPBUILD=1) && shift && goto CheckOpts +if "%1" EQU "--skip-build" (set SKIPBUILD=1) && shift && goto CheckOpts +if "%1" EQU "--download" (set DOWNLOAD_URL=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "--test" (set TESTTARGETDIR=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "-b" (set TARGET=Build) && shift && goto CheckOpts +if "%1" EQU "--build" (set TARGET=Build) && shift && goto CheckOpts +if "%1" EQU "-x86" (set BUILDX86=1) && shift && goto CheckOpts +if "%1" EQU "-x64" (set BUILDX64=1) && shift && goto CheckOpts + +if not defined BUILDX86 if not defined BUILDX64 (set BUILDX86=1) && (set BUILDX64=1) + +:builddoc +if "%SKIPBUILD%" EQU "1" goto skipdoc +if "%SKIPDOC%" EQU "1" goto skipdoc + +if not defined PYTHON where py -q || echo Cannot find py on path and PYTHON is not set. && exit /B 1 +if not defined SPHINXBUILD where sphinx-build -q || echo Cannot find sphinx-build on path and SPHINXBUILD is not set. && exit /B 1 +call "%D%..\..\doc\make.bat" htmlhelp +if errorlevel 1 goto :eof +:skipdoc + +where hg /q || echo Cannot find Mercurial on PATH && exit /B 1 + +where dlltool /q && goto skipdlltoolsearch +set _DLLTOOL_PATH= +where /R "%D%..\..\externals" dlltool > "%TEMP%\dlltool.loc" 2> nul && set /P _DLLTOOL_PATH= < "%TEMP%\dlltool.loc" & del "%TEMP%\dlltool.loc" +if not exist "%_DLLTOOL_PATH%" echo Cannot find binutils on PATH or in external && exit /B 1 +for %%f in (%_DLLTOOL_PATH%) do set PATH=%PATH%;%%~dpf +set _DLLTOOL_PATH= +:skipdlltoolsearch + +if defined BUILDX86 ( + call :build x86 + if errorlevel 1 exit /B +) + +if defined BUILDX64 ( + call :build x64 + if errorlevel 1 exit /B +) + +if defined TESTTARGETDIR ( + call "%D%testrelease.bat" -t "%TESTTARGETDIR%" +) + +exit /B 0 + +:build +@setlocal +@echo off + +if "%1" EQU "x86" ( + call "%PCBUILD%env.bat" x86 + set BUILD=%PCBUILD%win32\ + set BUILD_PLAT=Win32 + set OUTDIR_PLAT=win32 + set OBJDIR_PLAT=x86 + set RELEASE_URI=%RELEASE_URI_X86% +) ELSE ( + call "%PCBUILD%env.bat" x86_amd64 + set BUILD=%PCBUILD%amd64\ + set BUILD_PLAT=x64 + set OUTDIR_PLAT=amd64 + set OBJDIR_PLAT=x64 + set RELEASE_URI=%RELEASE_URI_X64% +) + +if exist "%BUILD%en-us" ( + echo Deleting %BUILD%en-us + rmdir /q/s "%BUILD%en-us" + if errorlevel 1 exit /B +) + +if exist "%D%obj\Release_%OBJDIR_PLAT%" ( + echo Deleting "%D%obj\Release_%OBJDIR_PLAT%" + rmdir /q/s "%D%obj\Release_%OBJDIR_PLAT%" + if errorlevel 1 exit /B +) + +if not "%CERTNAME%" EQU "" ( + set CERTOPTS="/p:SigningCertificate=%CERTNAME%" +) else ( + set CERTOPTS= +) + +if not "%SKIPBUILD%" EQU "1" ( + call "%PCBUILD%build.bat" -e -p %BUILD_PLAT% -d -t %TARGET% %CERTOPTS% + if errorlevel 1 exit /B + call "%PCBUILD%build.bat" -p %BUILD_PLAT% -t %TARGET% %CERTOPTS% + if errorlevel 1 exit /B + @rem build.bat turns echo back on, so we disable it again + @echo off +) + +"%BUILD%python.exe" "%D%get_wix.py" + +set BUILDOPTS=/p:Platform=%1 /p:BuildForRelease=true /p:DownloadUrl=%DOWNLOAD_URL% /p:DownloadUrlBase=%DOWNLOAD_URL_BASE% /p:ReleaseUri=%RELEASE_URI% +msbuild "%D%bundle\releaselocal.wixproj" /t:Rebuild %BUILDOPTS% %CERTOPTS% /p:RebuildAll=true +if errorlevel 1 exit /B +msbuild "%D%bundle\releaseweb.wixproj" /t:Rebuild %BUILDOPTS% %CERTOPTS% /p:RebuildAll=false +if errorlevel 1 exit /B + +if not "%OUTDIR%" EQU "" ( + mkdir "%OUTDIR%\%OUTDIR_PLAT%" + copy /Y "%BUILD%en-us\*.cab" "%OUTDIR%\%OUTDIR_PLAT%" + copy /Y "%BUILD%en-us\*.exe" "%OUTDIR%\%OUTDIR_PLAT%" + copy /Y "%BUILD%en-us\*.msi" "%OUTDIR%\%OUTDIR_PLAT%" +) + +exit /B 0 + +:Help +echo buildrelease.bat [--out DIR] [-x86] [-x64] [--certificate CERTNAME] [--build] [--skip-build] +echo [--skip-doc] [--download DOWNLOAD URL] [--test TARGETDIR] [-h] +echo. +echo --out (-o) Specify an additional output directory for installers +echo -x86 Build x86 installers +echo -x64 Build x64 installers +echo --build (-b) Incrementally build Python rather than rebuilding +echo --skip-build (-B) Do not build Python (just do the installers) +echo --skip-doc (-D) Do not build documentation +echo --download Specify the full download URL for MSIs (should include {2}) +echo --test Specify the test directory to run the installer tests +echo -h Display this help information +echo. +echo If no architecture is specified, all architectures will be built. +echo If --test is not specified, the installer tests are not run. +echo. \ No newline at end of file diff --git a/Tools/msi/bundle/Default.thm b/Tools/msi/bundle/Default.thm new file mode 100644 index 000000000000..3d7523a04548 --- /dev/null +++ b/Tools/msi/bundle/Default.thm @@ -0,0 +1,123 @@ + + + #(loc.Caption) + Segoe UI + Segoe UI + Segoe UI + Segoe UI + Segoe UI + Segoe UI + + + #(loc.HelpHeader) + + + #(loc.HelpText) + + + + #(loc.InstallHeader) + + + #(loc.InstallMessage) + + + + + + #(loc.ShortPrependPathLabel) + + + + + #(loc.InstallHeader) + + + + + + + + #(loc.Custom1Header) + + + #(loc.Include_docLabel) + #(loc.Include_docHelpLabel) + + #(loc.Include_pipLabel) + #(loc.Include_pipHelpLabel) + + #(loc.Include_tcltkLabel) + #(loc.Include_tcltkHelpLabel) + + #(loc.Include_testLabel) + #(loc.Include_testHelpLabel) + + #(loc.Include_launcherLabel) + #(loc.Include_launcherHelpLabel) + + + + + + + #(loc.Custom2Header) + + + #(loc.AssociateFilesLabel) + #(loc.PrependPathLabel) + #(loc.InstallAllUsersLabel) + #(loc.PrecompileLabel) + #(loc.Include_symbolsLabel) + #(loc.Include_debugLabel) + + #(loc.CustomLocationLabel) + + + #(loc.CustomLocationHelpLabel) + + + + + + + #(loc.ProgressHeader) + + + #(loc.ProgressLabel) + #(loc.OverallProgressPackageText) + + + + + #(loc.ModifyHeader) + + + + + + + + + + #(loc.SuccessHeader) + + + + + #(loc.SuccessRestartText) + + + + + + #(loc.FailureHeader) + + + #(loc.FailureHyperlinkLogText) + Failure Message + #(loc.FailureRestartText) + + + + \ No newline at end of file diff --git a/Tools/msi/bundle/Default.wxl b/Tools/msi/bundle/Default.wxl new file mode 100644 index 000000000000..6efd614770bf --- /dev/null +++ b/Tools/msi/bundle/Default.wxl @@ -0,0 +1,103 @@ + + + [WixBundleName] Setup + [WixBundleName] + Installing + Setup + Updating + Modify + Repairing + Repair + Removing + Uninstall + + &Cancel + &Close + Install [WixBundleName] + Select to location to install Python, or choose Customize to enable or disable features. + Version [WixBundleVersion] + Are you sure you want to cancel? + Previous version + Setup Help + /uninstall + Uninstalls Python without prompting for confirmation. + +/layout [\[]directory[\]] + Downloads all components for offline installation. + +/passive + Displays progress without requiring user interaction. + +/quiet + Performs the requested action without displaying any UI. + +/log [\[]filename[\]] + Logs to a specific file. By default, log files are created in %TEMP%. + [WixBundleName] <a href="#">license terms</a>. + I &agree to the license terms and conditions + Install for &All Users + [DefaultAllUsersTargetDir] + Install &Just for Me + [DefaultJustForMeTargetDir] + C&ustomize installation + Choose location and features + &Install + Uses setting preselected by your administrator + Optional Features + Advanced Options + Customize install location + If not installing as administrator, you will require write permissions for this location. + &Install + &Next + &Back + B&rowse + &Documentation + Installs the Python documentation file. + &pip + Installs pip, which can download and install other Python packages. + tcl/tk and &IDLE + Installs tkinter and the IDLE development environment. + Python &test suite + Installs the standard library test suite. + py &launcher + Installs the global 'py' launcher to make it easier to start Python. + + Associate &files with Python (requires the py launcher) + Add Python to &environment variables + Add &Python [ShortVersion] to PATH + Install as &Administrator + &Precompile standard library + Install debugging &symbols + Install debu&g binaries + + [ActionLikeInstallation] Progress + [ActionLikeInstalling]: + Initializing... + Modify Setup + &Modify + Add or remove individual features. + &Repair + Ensure all current features are correctly installed. + &Uninstall + Remove the entire [WixBundleName] installation. + [ActionLikeInstallation] was successful + &Launch + You may need to restart your computer to finish updating files. + &Restart + Special thanks to Mark Hammond, without whose years of freely shared Windows expertise, Python for Windows would still be Python for DOS. + +New to Python? Start with the <a href="https://docs.python.org/[ShortVersion]/tutorial/index.html">online tutorial</a> and <a href="https://docs.python.org/[ShortVersion]/index.html">documentation</a>. + +See <a href="https://docs.python.org/[ShortVersion]/whatsnew/[ShortVersion].html">what's new</a> in this release. + Thank you for using [WixBundleName]. + Thank you for using [WixBundleName]. + +Feel free to email <a href="mailto:python-list@python.org">python-list@python.org</a> if you continue to encounter issues. + Thank you for using [WixBundleName]. + +Feel free to email <a href="mailto:python-list@python.org">python-list@python.org</a> if you encountered problems. + Setup failed + One or more issues caused the setup to fail. Please fix the issues and then retry setup. For more information see the <a href="#">log file</a>. + You must restart your computer to complete the rollback of the software. + &Restart + diff --git a/Tools/msi/bundle/SideBar.png b/Tools/msi/bundle/SideBar.png new file mode 100644 index 000000000000..9c18fff33a6e Binary files /dev/null and b/Tools/msi/bundle/SideBar.png differ diff --git a/Tools/msi/bundle/bootstrap/LICENSE.txt b/Tools/msi/bundle/bootstrap/LICENSE.txt new file mode 100644 index 000000000000..5791a7e81d74 --- /dev/null +++ b/Tools/msi/bundle/bootstrap/LICENSE.txt @@ -0,0 +1,25 @@ +This license applies to the bootstrapper application that is embedded within the installer. It has no impact on the licensing for the rest of the installer or Python itself, as no code covered by this license exists in any other part of the product. + +--- + +Microsoft Reciprocal License (MS-RL) + +This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software. + +1. Definitions + The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law. + A "contribution" is the original software, or any additions or changes to the software. + A "contributor" is any person that distributes its contribution under this license. + "Licensed patents" are a contributor's patent claims that read directly on its contribution. + +2. Grant of Rights + (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create. + (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software. + +3. Conditions and Limitations + (A) Reciprocal Grants- For any file you distribute that contains code from the software (in source code or binary format), you must provide recipients the source code to that file along with a copy of this license, which license will govern that file. You may license other files that are entirely your own work and do not contain code from the software under any terms you choose. + (B) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks. + (C) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically. + (D) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software. + (E) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license. + (F) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement. diff --git a/Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp b/Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp new file mode 100644 index 000000000000..5eda3f75caf5 --- /dev/null +++ b/Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp @@ -0,0 +1,2652 @@ +//------------------------------------------------------------------------------------------------- +// +// Copyright (c) 2004, Outercurve Foundation. +// This software is released under Microsoft Reciprocal License (MS-RL). +// The license and further copyright text can be found in the file +// LICENSE.TXT at the root directory of the distribution. +// +//------------------------------------------------------------------------------------------------- + + +#include "pch.h" + +static const LPCWSTR WIXBUNDLE_VARIABLE_ELEVATED = L"WixBundleElevated"; + +static const LPCWSTR PYBA_WINDOW_CLASS = L"PythonBA"; +static const LPCWSTR PYBA_VARIABLE_LAUNCH_TARGET_PATH = L"LaunchTarget"; +static const LPCWSTR PYBA_VARIABLE_LAUNCH_TARGET_ELEVATED_ID = L"LaunchTargetElevatedId"; +static const LPCWSTR PYBA_VARIABLE_LAUNCH_ARGUMENTS = L"LaunchArguments"; +static const LPCWSTR PYBA_VARIABLE_LAUNCH_HIDDEN = L"LaunchHidden"; +static const DWORD PYBA_ACQUIRE_PERCENTAGE = 30; +static const LPCWSTR PYBA_VARIABLE_BUNDLE_FILE_VERSION = L"WixBundleFileVersion"; + +enum PYBA_STATE { + PYBA_STATE_INITIALIZING, + PYBA_STATE_INITIALIZED, + PYBA_STATE_HELP, + PYBA_STATE_DETECTING, + PYBA_STATE_DETECTED, + PYBA_STATE_PLANNING, + PYBA_STATE_PLANNED, + PYBA_STATE_APPLYING, + PYBA_STATE_CACHING, + PYBA_STATE_CACHED, + PYBA_STATE_EXECUTING, + PYBA_STATE_EXECUTED, + PYBA_STATE_APPLIED, + PYBA_STATE_FAILED, +}; + +static const int WM_PYBA_SHOW_HELP = WM_APP + 100; +static const int WM_PYBA_DETECT_PACKAGES = WM_APP + 101; +static const int WM_PYBA_PLAN_PACKAGES = WM_APP + 102; +static const int WM_PYBA_APPLY_PACKAGES = WM_APP + 103; +static const int WM_PYBA_CHANGE_STATE = WM_APP + 104; +static const int WM_PYBA_SHOW_FAILURE = WM_APP + 105; + +// This enum must be kept in the same order as the PAGE_NAMES array. +enum PAGE { + PAGE_LOADING, + PAGE_HELP, + PAGE_INSTALL, + PAGE_SIMPLE_INSTALL, + PAGE_CUSTOM1, + PAGE_CUSTOM2, + PAGE_MODIFY, + PAGE_PROGRESS, + PAGE_PROGRESS_PASSIVE, + PAGE_SUCCESS, + PAGE_FAILURE, + COUNT_PAGE, +}; + +// This array must be kept in the same order as the PAGE enum. +static LPCWSTR PAGE_NAMES[] = { + L"Loading", + L"Help", + L"Install", + L"SimpleInstall", + L"Custom1", + L"Custom2", + L"Modify", + L"Progress", + L"ProgressPassive", + L"Success", + L"Failure", +}; + +enum CONTROL_ID { + // Non-paged controls + ID_CLOSE_BUTTON = THEME_FIRST_ASSIGN_CONTROL_ID, + ID_MINIMIZE_BUTTON, + + // Welcome page + ID_INSTALL_ALL_USERS_BUTTON, + ID_INSTALL_JUST_FOR_ME_BUTTON, + ID_INSTALL_CUSTOM_BUTTON, + ID_INSTALL_SIMPLE_BUTTON, + ID_INSTALL_CANCEL_BUTTON, + + // Customize Page + ID_TARGETDIR_EDITBOX, + ID_CUSTOM_ASSOCIATE_FILES_CHECKBOX, + ID_CUSTOM_INSTALL_ALL_USERS_CHECKBOX, + ID_CUSTOM_BROWSE_BUTTON, + ID_CUSTOM_INSTALL_BUTTON, + ID_CUSTOM_NEXT_BUTTON, + ID_CUSTOM1_BACK_BUTTON, + ID_CUSTOM2_BACK_BUTTON, + ID_CUSTOM1_CANCEL_BUTTON, + ID_CUSTOM2_CANCEL_BUTTON, + + // Modify page + ID_MODIFY_BUTTON, + ID_REPAIR_BUTTON, + ID_UNINSTALL_BUTTON, + ID_MODIFY_CANCEL_BUTTON, + + // Progress page + ID_CACHE_PROGRESS_PACKAGE_TEXT, + ID_CACHE_PROGRESS_BAR, + ID_CACHE_PROGRESS_TEXT, + + ID_EXECUTE_PROGRESS_PACKAGE_TEXT, + ID_EXECUTE_PROGRESS_BAR, + ID_EXECUTE_PROGRESS_TEXT, + ID_EXECUTE_PROGRESS_ACTIONDATA_TEXT, + + ID_OVERALL_PROGRESS_PACKAGE_TEXT, + ID_OVERALL_PROGRESS_BAR, + ID_OVERALL_CALCULATED_PROGRESS_BAR, + ID_OVERALL_PROGRESS_TEXT, + + ID_PROGRESS_CANCEL_BUTTON, + + // Success page + ID_LAUNCH_BUTTON, + ID_SUCCESS_TEXT, + ID_SUCCESS_RESTART_TEXT, + ID_SUCCESS_RESTART_BUTTON, + ID_SUCCESS_CANCEL_BUTTON, + + // Failure page + ID_FAILURE_LOGFILE_LINK, + ID_FAILURE_MESSAGE_TEXT, + ID_FAILURE_RESTART_TEXT, + ID_FAILURE_RESTART_BUTTON, + ID_FAILURE_CANCEL_BUTTON +}; + +static THEME_ASSIGN_CONTROL_ID CONTROL_ID_NAMES[] = { + { ID_CLOSE_BUTTON, L"CloseButton" }, + { ID_MINIMIZE_BUTTON, L"MinimizeButton" }, + + { ID_INSTALL_ALL_USERS_BUTTON, L"InstallAllUsersButton" }, + { ID_INSTALL_JUST_FOR_ME_BUTTON, L"InstallJustForMeButton" }, + { ID_INSTALL_CUSTOM_BUTTON, L"InstallCustomButton" }, + { ID_INSTALL_SIMPLE_BUTTON, L"InstallSimpleButton" }, + { ID_INSTALL_CANCEL_BUTTON, L"InstallCancelButton" }, + + { ID_TARGETDIR_EDITBOX, L"TargetDir" }, + { ID_CUSTOM_ASSOCIATE_FILES_CHECKBOX, L"AssociateFiles" }, + { ID_CUSTOM_INSTALL_ALL_USERS_CHECKBOX, L"InstallAllUsers" }, + { ID_CUSTOM_BROWSE_BUTTON, L"CustomBrowseButton" }, + { ID_CUSTOM_INSTALL_BUTTON, L"CustomInstallButton" }, + { ID_CUSTOM_NEXT_BUTTON, L"CustomNextButton" }, + { ID_CUSTOM1_BACK_BUTTON, L"Custom1BackButton" }, + { ID_CUSTOM2_BACK_BUTTON, L"Custom2BackButton" }, + { ID_CUSTOM1_CANCEL_BUTTON, L"Custom1CancelButton" }, + { ID_CUSTOM2_CANCEL_BUTTON, L"Custom2CancelButton" }, + + { ID_MODIFY_BUTTON, L"ModifyButton" }, + { ID_REPAIR_BUTTON, L"RepairButton" }, + { ID_UNINSTALL_BUTTON, L"UninstallButton" }, + { ID_MODIFY_CANCEL_BUTTON, L"ModifyCancelButton" }, + + { ID_CACHE_PROGRESS_PACKAGE_TEXT, L"CacheProgressPackageText" }, + { ID_CACHE_PROGRESS_BAR, L"CacheProgressbar" }, + { ID_CACHE_PROGRESS_TEXT, L"CacheProgressText" }, + { ID_EXECUTE_PROGRESS_PACKAGE_TEXT, L"ExecuteProgressPackageText" }, + { ID_EXECUTE_PROGRESS_BAR, L"ExecuteProgressbar" }, + { ID_EXECUTE_PROGRESS_TEXT, L"ExecuteProgressText" }, + { ID_EXECUTE_PROGRESS_ACTIONDATA_TEXT, L"ExecuteProgressActionDataText" }, + { ID_OVERALL_PROGRESS_PACKAGE_TEXT, L"OverallProgressPackageText" }, + { ID_OVERALL_PROGRESS_BAR, L"OverallProgressbar" }, + { ID_OVERALL_CALCULATED_PROGRESS_BAR, L"OverallCalculatedProgressbar" }, + { ID_OVERALL_PROGRESS_TEXT, L"OverallProgressText" }, + { ID_PROGRESS_CANCEL_BUTTON, L"ProgressCancelButton" }, + + { ID_LAUNCH_BUTTON, L"LaunchButton" }, + { ID_SUCCESS_TEXT, L"SuccessText" }, + { ID_SUCCESS_RESTART_TEXT, L"SuccessRestartText" }, + { ID_SUCCESS_RESTART_BUTTON, L"SuccessRestartButton" }, + { ID_SUCCESS_CANCEL_BUTTON, L"SuccessCancelButton" }, + + { ID_FAILURE_LOGFILE_LINK, L"FailureLogFileLink" }, + { ID_FAILURE_MESSAGE_TEXT, L"FailureMessageText" }, + { ID_FAILURE_RESTART_TEXT, L"FailureRestartText" }, + { ID_FAILURE_RESTART_BUTTON, L"FailureRestartButton" }, + { ID_FAILURE_CANCEL_BUTTON, L"FailureCancelButton" }, +}; + +class PythonBootstrapperApplication : public CBalBaseBootstrapperApplication { + void ShowPage(DWORD newPageId) { + // Process each control for special handling in the new page. + ProcessPageControls(ThemeGetPage(_theme, newPageId)); + + // Enable disable controls per-page. + if (_pageIds[PAGE_INSTALL] == newPageId || _pageIds[PAGE_SIMPLE_INSTALL] == newPageId) { + InstallPage_Show(); + } else if (_pageIds[PAGE_CUSTOM1] == newPageId) { + Custom1Page_Show(); + } else if (_pageIds[PAGE_CUSTOM2] == newPageId) { + Custom2Page_Show(); + } else if (_pageIds[PAGE_MODIFY] == newPageId) { + ModifyPage_Show(); + } else if (_pageIds[PAGE_SUCCESS] == newPageId) { + SuccessPage_Show(); + } else if (_pageIds[PAGE_FAILURE] == newPageId) { + FailurePage_Show(); + } + + // Prevent repainting while switching page to avoid ugly flickering + _suppressPaint = TRUE; + ThemeShowPage(_theme, newPageId, SW_SHOW); + ThemeShowPage(_theme, _visiblePageId, SW_HIDE); + _suppressPaint = FALSE; + InvalidateRect(_theme->hwndParent, nullptr, TRUE); + _visiblePageId = newPageId; + + // On the install page set the focus to the install button or + // the next enabled control if install is disabled + if (_pageIds[PAGE_INSTALL] == newPageId) { + ThemeSetFocus(_theme, ID_INSTALL_ALL_USERS_BUTTON); + } else if (_pageIds[PAGE_SIMPLE_INSTALL] == newPageId) { + ThemeSetFocus(_theme, ID_INSTALL_SIMPLE_BUTTON); + } + } + + // + // Handles control clicks + // + void OnCommand(CONTROL_ID id) { + LPWSTR defaultDir = nullptr; + LPWSTR targetDir = nullptr; + LONGLONG elevated; + BOOL checked; + WCHAR wzPath[MAX_PATH] = { }; + BROWSEINFOW browseInfo = { }; + PIDLIST_ABSOLUTE pidl = nullptr; + HRESULT hr = S_OK; + + switch(id) { + case ID_CLOSE_BUTTON: + OnClickCloseButton(); + break; + + // Install commands + case ID_INSTALL_SIMPLE_BUTTON: + hr = BalGetStringVariable(L"TargetDir", &targetDir); + if (FAILED(hr) || !targetDir || !*targetDir) { + LONGLONG installAll; + if (SUCCEEDED(BalGetNumericVariable(L"InstallAllUsers", &installAll)) && installAll) { + hr = BalGetStringVariable(L"DefaultAllUsersTargetDir", &defaultDir); + BalExitOnFailure(hr, "Failed to get the default all users install directory"); + } else { + hr = BalGetStringVariable(L"DefaultJustForMeTargetDir", &defaultDir); + BalExitOnFailure(hr, "Failed to get the default per-user install directory"); + } + + if (!defaultDir || !*defaultDir) { + BalLogError(E_INVALIDARG, "Default install directory is blank"); + } + + hr = BalFormatString(defaultDir, &targetDir); + BalExitOnFailure1(hr, "Failed to format '%ls'", defaultDir); + + hr = _engine->SetVariableString(L"TargetDir", targetDir); + ReleaseStr(targetDir); + BalExitOnFailure(hr, "Failed to set install target directory"); + } else { + ReleaseStr(targetDir); + } + + OnPlan(BOOTSTRAPPER_ACTION_INSTALL); + break; + + case ID_INSTALL_ALL_USERS_BUTTON: + SavePageSettings(); + + hr = _engine->SetVariableNumeric(L"InstallAllUsers", 1); + ExitOnFailure(hr, L"Failed to set install scope"); + + hr = _engine->SetVariableNumeric(L"CompileAll", 1); + ExitOnFailure(hr, L"Failed to set compile all setting"); + + hr = BalGetStringVariable(L"DefaultAllUsersTargetDir", &defaultDir); + BalExitOnFailure(hr, "Failed to get the default all users install directory"); + + if (!defaultDir || !*defaultDir) { + BalLogError(E_INVALIDARG, "Default install directory is blank"); + } + + hr = BalFormatString(defaultDir, &targetDir); + BalExitOnFailure1(hr, "Failed to format '%ls'", defaultDir); + + hr = _engine->SetVariableString(L"TargetDir", targetDir); + ReleaseStr(targetDir); + BalExitOnFailure(hr, "Failed to set install target directory"); + + OnPlan(BOOTSTRAPPER_ACTION_INSTALL); + break; + + case ID_INSTALL_JUST_FOR_ME_BUTTON: + SavePageSettings(); + + hr = _engine->SetVariableNumeric(L"InstallAllUsers", 0); + ExitOnFailure(hr, L"Failed to set install scope"); + + hr = BalGetStringVariable(L"DefaultJustForMeTargetDir", &defaultDir); + BalExitOnFailure(hr, "Failed to get the default per-user install directory"); + + if (!defaultDir || !*defaultDir) { + BalLogError(E_INVALIDARG, "Default install directory is blank"); + } + + hr = BalFormatString(defaultDir, &targetDir); + BalExitOnFailure1(hr, "Failed to format '%ls'", defaultDir); + + hr = _engine->SetVariableString(L"TargetDir", targetDir); + ReleaseStr(targetDir); + BalExitOnFailure(hr, "Failed to set install target directory"); + + OnPlan(BOOTSTRAPPER_ACTION_INSTALL); + break; + + case ID_CUSTOM1_BACK_BUTTON: + SavePageSettings(); + if (_modifying) { + GoToPage(PAGE_MODIFY); + } else { + GoToPage(PAGE_INSTALL); + } + break; + + case ID_INSTALL_CUSTOM_BUTTON: __fallthrough; + case ID_CUSTOM2_BACK_BUTTON: + SavePageSettings(); + GoToPage(PAGE_CUSTOM1); + break; + + case ID_CUSTOM_NEXT_BUTTON: + SavePageSettings(); + GoToPage(PAGE_CUSTOM2); + break; + + case ID_CUSTOM_INSTALL_BUTTON: + SavePageSettings(); + + hr = BalGetStringVariable(L"TargetDir", &targetDir); + if (SUCCEEDED(hr)) { + // TODO: Check whether directory exists and contains another installation + ReleaseStr(targetDir); + } + + OnPlan(_command.action); + break; + + case ID_CUSTOM_INSTALL_ALL_USERS_CHECKBOX: + hr = BalGetNumericVariable(L"WixBundleElevated", &elevated); + checked = ThemeIsControlChecked(_theme, ID_CUSTOM_INSTALL_ALL_USERS_CHECKBOX); + ThemeControlElevates(_theme, ID_CUSTOM_INSTALL_BUTTON, checked && (FAILED(hr) || !elevated)); + ThemeGetTextControl(_theme, ID_TARGETDIR_EDITBOX, &targetDir); + if (targetDir) { + // Check the current value against the default to see + // if we should switch it automatically. + hr = BalGetStringVariable( + checked ? L"DefaultJustForMeTargetDir" : L"DefaultAllUsersTargetDir", + &defaultDir + ); + + if (SUCCEEDED(hr) && defaultDir) { + LPWSTR formatted = nullptr; + if (defaultDir[0] && SUCCEEDED(BalFormatString(defaultDir, &formatted))) { + if (wcscmp(formatted, targetDir) == 0) { + ReleaseStr(defaultDir); + defaultDir = nullptr; + ReleaseStr(formatted); + formatted = nullptr; + + hr = BalGetStringVariable( + checked ? L"DefaultAllUsersTargetDir" : L"DefaultJustForMeTargetDir", + &defaultDir + ); + if (SUCCEEDED(hr) && defaultDir && defaultDir[0] && SUCCEEDED(BalFormatString(defaultDir, &formatted))) { + ThemeSetTextControl(_theme, ID_TARGETDIR_EDITBOX, formatted); + ReleaseStr(formatted); + } + } else { + ReleaseStr(formatted); + } + } + + ReleaseStr(defaultDir); + } + } + break; + + case ID_CUSTOM_BROWSE_BUTTON: + browseInfo.hwndOwner = _hWnd; + browseInfo.pszDisplayName = wzPath; + browseInfo.lpszTitle = _theme->sczCaption; + browseInfo.ulFlags = BIF_RETURNONLYFSDIRS | BIF_USENEWUI; + pidl = ::SHBrowseForFolderW(&browseInfo); + if (pidl && ::SHGetPathFromIDListW(pidl, wzPath)) { + ThemeSetTextControl(_theme, ID_TARGETDIR_EDITBOX, wzPath); + } + + if (pidl) { + ::CoTaskMemFree(pidl); + } + break; + + // Modify commands + case ID_MODIFY_BUTTON: + // Some variables cannot be modified + _engine->SetVariableString(L"InstallAllUsersState", L"disable"); + _engine->SetVariableString(L"TargetDirState", L"disable"); + _engine->SetVariableString(L"CustomBrowseButtonState", L"disable"); + _modifying = TRUE; + GoToPage(PAGE_CUSTOM1); + break; + + case ID_REPAIR_BUTTON: + OnPlan(BOOTSTRAPPER_ACTION_REPAIR); + break; + + case ID_UNINSTALL_BUTTON: + OnPlan(BOOTSTRAPPER_ACTION_UNINSTALL); + break; + } + + LExit: + return; + } + + void InstallPage_Show() { + // Ensure the All Users install button has a UAC shield + LONGLONG elevated, installAll; + + if (FAILED(BalGetNumericVariable(L"WixBundleElevated", &elevated))) { + elevated = 0; + } + + ThemeControlElevates(_theme, ID_INSTALL_ALL_USERS_BUTTON, !elevated); + + if (SUCCEEDED(BalGetNumericVariable(L"InstallAllUsers", &installAll)) && installAll) { + ThemeControlElevates(_theme, ID_INSTALL_SIMPLE_BUTTON, !elevated); + } + } + + void Custom1Page_Show() { + } + + void Custom2Page_Show() { + HRESULT hr; + LONGLONG installAll, elevated, includeLauncher; + + if (FAILED(BalGetNumericVariable(L"WixBundleElevated", &elevated))) { + elevated = 0; + } + if (SUCCEEDED(BalGetNumericVariable(L"InstallAllUsers", &installAll))) { + ThemeControlElevates(_theme, ID_CUSTOM_INSTALL_BUTTON, installAll && !elevated); + } else { + installAll = 0; + } + + if (SUCCEEDED(BalGetNumericVariable(L"Include_launcher", &includeLauncher)) && includeLauncher) { + ThemeControlEnable(_theme, ID_CUSTOM_ASSOCIATE_FILES_CHECKBOX, TRUE); + } else { + ThemeSendControlMessage(_theme, ID_CUSTOM_ASSOCIATE_FILES_CHECKBOX, BM_SETCHECK, BST_UNCHECKED, 0); + ThemeControlEnable(_theme, ID_CUSTOM_ASSOCIATE_FILES_CHECKBOX, FALSE); + } + + LPWSTR targetDir = nullptr; + hr = BalGetStringVariable(L"TargetDir", &targetDir); + if (SUCCEEDED(hr) && targetDir && targetDir[0]) { + ThemeSetTextControl(_theme, ID_TARGETDIR_EDITBOX, targetDir); + StrFree(targetDir); + } else if (SUCCEEDED(hr)) { + StrFree(targetDir); + targetDir = nullptr; + + LPWSTR defaultTargetDir = nullptr; + hr = BalGetStringVariable(L"DefaultCustomTargetDir", &defaultTargetDir); + if (SUCCEEDED(hr) && defaultTargetDir && !defaultTargetDir[0]) { + StrFree(defaultTargetDir); + defaultTargetDir = nullptr; + + hr = BalGetStringVariable( + installAll ? L"DefaultAllUsersTargetDir" : L"DefaultJustForMeTargetDir", + &defaultTargetDir + ); + } + if (SUCCEEDED(hr) && defaultTargetDir) { + if (defaultTargetDir[0] && SUCCEEDED(BalFormatString(defaultTargetDir, &targetDir))) { + ThemeSetTextControl(_theme, ID_TARGETDIR_EDITBOX, targetDir); + StrFree(targetDir); + } + StrFree(defaultTargetDir); + } + } + } + + void ModifyPage_Show() { + ThemeControlEnable(_theme, ID_REPAIR_BUTTON, !_suppressRepair); + } + + void SuccessPage_Show() { + // on the "Success" page, check if the restart or launch button should be enabled. + BOOL showRestartButton = FALSE; + BOOL launchTargetExists = FALSE; + LOC_STRING *successText = nullptr; + HRESULT hr = S_OK; + + if (_restartRequired) { + if (BOOTSTRAPPER_RESTART_PROMPT == _command.restart) { + showRestartButton = TRUE; + } + } else if (ThemeControlExists(_theme, ID_LAUNCH_BUTTON)) { + launchTargetExists = BalStringVariableExists(PYBA_VARIABLE_LAUNCH_TARGET_PATH); + } + + switch (_plannedAction) { + case BOOTSTRAPPER_ACTION_INSTALL: + hr = LocGetString(_wixLoc, L"#(loc.SuccessInstallMessage)", &successText); + break; + case BOOTSTRAPPER_ACTION_MODIFY: + hr = LocGetString(_wixLoc, L"#(loc.SuccessModifyMessage)", &successText); + break; + case BOOTSTRAPPER_ACTION_REPAIR: + hr = LocGetString(_wixLoc, L"#(loc.SuccessRepairMessage)", &successText); + break; + case BOOTSTRAPPER_ACTION_UNINSTALL: + hr = LocGetString(_wixLoc, L"#(loc.SuccessRemoveMessage)", &successText); + break; + } + + if (successText) { + LPWSTR formattedString = nullptr; + BalFormatString(successText->wzText, &formattedString); + if (formattedString) { + ThemeSetTextControl(_theme, ID_SUCCESS_TEXT, formattedString); + StrFree(formattedString); + } + } + + ThemeControlEnable(_theme, ID_LAUNCH_BUTTON, launchTargetExists && BOOTSTRAPPER_ACTION_UNINSTALL < _plannedAction); + ThemeControlEnable(_theme, ID_SUCCESS_RESTART_TEXT, showRestartButton); + ThemeControlEnable(_theme, ID_SUCCESS_RESTART_BUTTON, showRestartButton); + } + + void FailurePage_Show() { + // on the "Failure" page, show error message and check if the restart button should be enabled. + + // if there is a log file variable then we'll assume the log file exists. + BOOL showLogLink = (_bundle.sczLogVariable && *_bundle.sczLogVariable); + BOOL showErrorMessage = FALSE; + BOOL showRestartButton = FALSE; + + if (FAILED(_hrFinal)) { + LPWSTR unformattedText = nullptr; + LPWSTR text = nullptr; + + // If we know the failure message, use that. + if (_failedMessage && *_failedMessage) { + StrAllocString(&unformattedText, _failedMessage, 0); + } else { + // try to get the error message from the error code. + StrAllocFromError(&unformattedText, _hrFinal, nullptr); + if (!unformattedText || !*unformattedText) { + StrAllocFromError(&unformattedText, E_FAIL, nullptr); + } + } + + if (E_WIXSTDBA_CONDITION_FAILED == _hrFinal) { + if (unformattedText) { + StrAllocString(&text, unformattedText, 0); + } + } else { + StrAllocFormatted(&text, L"0x%08x - %ls", _hrFinal, unformattedText); + } + + if (text) { + ThemeSetTextControl(_theme, ID_FAILURE_MESSAGE_TEXT, text); + showErrorMessage = TRUE; + } + + ReleaseStr(text); + ReleaseStr(unformattedText); + } + + if (_restartRequired && BOOTSTRAPPER_RESTART_PROMPT == _command.restart) { + showRestartButton = TRUE; + } + + ThemeControlEnable(_theme, ID_FAILURE_LOGFILE_LINK, showLogLink); + ThemeControlEnable(_theme, ID_FAILURE_MESSAGE_TEXT, showErrorMessage); + ThemeControlEnable(_theme, ID_FAILURE_RESTART_TEXT, showRestartButton); + ThemeControlEnable(_theme, ID_FAILURE_RESTART_BUTTON, showRestartButton); + } + + +public: // IBootstrapperApplication + virtual STDMETHODIMP OnStartup() { + HRESULT hr = S_OK; + DWORD dwUIThreadId = 0; + + // create UI thread + _hUiThread = ::CreateThread(nullptr, 0, UiThreadProc, this, 0, &dwUIThreadId); + if (!_hUiThread) { + ExitWithLastError(hr, "Failed to create UI thread."); + } + + LExit: + return hr; + } + + + virtual STDMETHODIMP_(int) OnShutdown() { + int nResult = IDNOACTION; + + // wait for UI thread to terminate + if (_hUiThread) { + ::WaitForSingleObject(_hUiThread, INFINITE); + ReleaseHandle(_hUiThread); + } + + // If a restart was required. + if (_restartRequired && _allowRestart) { + nResult = IDRESTART; + } + + return nResult; + } + + + virtual STDMETHODIMP_(int) OnDetectRelatedBundle( + __in LPCWSTR wzBundleId, + __in BOOTSTRAPPER_RELATION_TYPE relationType, + __in LPCWSTR /*wzBundleTag*/, + __in BOOL fPerMachine, + __in DWORD64 /*dw64Version*/, + __in BOOTSTRAPPER_RELATED_OPERATION operation + ) { + BalInfoAddRelatedBundleAsPackage(&_bundle.packages, wzBundleId, relationType, fPerMachine); + + // Remember when our bundle would cause a downgrade. + if (BOOTSTRAPPER_RELATED_OPERATION_DOWNGRADE == operation) { + _downgrading = TRUE; + } + + return CheckCanceled() ? IDCANCEL : IDOK; + } + + + virtual STDMETHODIMP_(void) OnDetectPackageComplete( + __in LPCWSTR wzPackageId, + __in HRESULT /*hrStatus*/, + __in BOOTSTRAPPER_PACKAGE_STATE state + ) { } + + + virtual STDMETHODIMP_(void) OnDetectComplete(__in HRESULT hrStatus) { + if (SUCCEEDED(hrStatus) && _baFunction) { + BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Running detect complete BA function"); + _baFunction->OnDetectComplete(); + } + + if (SUCCEEDED(hrStatus)) { + hrStatus = EvaluateConditions(); + } + + SetState(PYBA_STATE_DETECTED, hrStatus); + + // If we're not interacting with the user or we're doing a layout or we're just after a force restart + // then automatically start planning. + if (BOOTSTRAPPER_DISPLAY_FULL > _command.display || + BOOTSTRAPPER_ACTION_LAYOUT == _command.action || + BOOTSTRAPPER_ACTION_UNINSTALL == _command.action || + BOOTSTRAPPER_RESUME_TYPE_REBOOT == _command.resumeType) { + if (SUCCEEDED(hrStatus)) { + ::PostMessageW(_hWnd, WM_PYBA_PLAN_PACKAGES, 0, _command.action); + } + } + } + + + virtual STDMETHODIMP_(int) OnPlanRelatedBundle( + __in_z LPCWSTR /*wzBundleId*/, + __inout_z BOOTSTRAPPER_REQUEST_STATE* pRequestedState + ) { + return CheckCanceled() ? IDCANCEL : IDOK; + } + + + virtual STDMETHODIMP_(int) OnPlanPackageBegin( + __in_z LPCWSTR wzPackageId, + __inout BOOTSTRAPPER_REQUEST_STATE *pRequestState + ) { + HRESULT hr = S_OK; + BAL_INFO_PACKAGE* pPackage = nullptr; + + if (_nextPackageAfterRestart) // after force restart, skip packages until after the package that caused the restart. + { + // After restart we need to finish the dependency registration for our package so allow the package + // to go present. + if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, wzPackageId, -1, _nextPackageAfterRestart, -1)) { + // Do not allow a repair because that could put us in a perpetual restart loop. + if (BOOTSTRAPPER_REQUEST_STATE_REPAIR == *pRequestState) { + *pRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT; + } + + ReleaseNullStr(_nextPackageAfterRestart); // no more skipping now. + } else { + // not the matching package, so skip it. + BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Skipping package: %ls, after restart because it was applied before the restart.", wzPackageId); + + *pRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE; + } + } + + return CheckCanceled() ? IDCANCEL : IDOK; + } + + virtual STDMETHODIMP_(int) OnPlanMsiFeature( + __in_z LPCWSTR wzPackageId, + __in_z LPCWSTR wzFeatureId, + __inout BOOTSTRAPPER_FEATURE_STATE* pRequestedState + ) { + LONGLONG install; + + if (wcscmp(wzFeatureId, L"AssociateFiles") == 0) { + if (SUCCEEDED(_engine->GetVariableNumeric(L"AssociateFiles", &install)) && install) { + *pRequestedState = BOOTSTRAPPER_FEATURE_STATE_LOCAL; + } else { + *pRequestedState = BOOTSTRAPPER_FEATURE_STATE_ABSENT; + } + } + return CheckCanceled() ? IDCANCEL : IDNOACTION; + } + + virtual STDMETHODIMP_(void) OnPlanComplete(__in HRESULT hrStatus) { + if (SUCCEEDED(hrStatus) && _baFunction) { + BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Running plan complete BA function"); + _baFunction->OnPlanComplete(); + } + + SetState(PYBA_STATE_PLANNED, hrStatus); + + if (SUCCEEDED(hrStatus)) { + ::PostMessageW(_hWnd, WM_PYBA_APPLY_PACKAGES, 0, 0); + } + + _startedExecution = FALSE; + _calculatedCacheProgress = 0; + _calculatedExecuteProgress = 0; + } + + + virtual STDMETHODIMP_(int) OnCachePackageBegin( + __in_z LPCWSTR wzPackageId, + __in DWORD cCachePayloads, + __in DWORD64 dw64PackageCacheSize + ) { + if (wzPackageId && *wzPackageId) { + BAL_INFO_PACKAGE* pPackage = nullptr; + HRESULT hr = BalInfoFindPackageById(&_bundle.packages, wzPackageId, &pPackage); + LPCWSTR wz = (SUCCEEDED(hr) && pPackage->sczDisplayName) ? pPackage->sczDisplayName : wzPackageId; + + ThemeSetTextControl(_theme, ID_CACHE_PROGRESS_PACKAGE_TEXT, wz); + + // If something started executing, leave it in the overall progress text. + if (!_startedExecution) { + ThemeSetTextControl(_theme, ID_OVERALL_PROGRESS_PACKAGE_TEXT, wz); + } + } + + return __super::OnCachePackageBegin(wzPackageId, cCachePayloads, dw64PackageCacheSize); + } + + + virtual STDMETHODIMP_(int) OnCacheAcquireProgress( + __in_z LPCWSTR wzPackageOrContainerId, + __in_z_opt LPCWSTR wzPayloadId, + __in DWORD64 dw64Progress, + __in DWORD64 dw64Total, + __in DWORD dwOverallPercentage + ) { + WCHAR wzProgress[5] = { }; + +#ifdef DEBUG + BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "PYBA: OnCacheAcquireProgress() - container/package: %ls, payload: %ls, progress: %I64u, total: %I64u, overall progress: %u%%", wzPackageOrContainerId, wzPayloadId, dw64Progress, dw64Total, dwOverallPercentage); +#endif + + ::StringCchPrintfW(wzProgress, countof(wzProgress), L"%u%%", dwOverallPercentage); + ThemeSetTextControl(_theme, ID_CACHE_PROGRESS_TEXT, wzProgress); + + ThemeSetProgressControl(_theme, ID_CACHE_PROGRESS_BAR, dwOverallPercentage); + + _calculatedCacheProgress = dwOverallPercentage * PYBA_ACQUIRE_PERCENTAGE / 100; + ThemeSetProgressControl(_theme, ID_OVERALL_CALCULATED_PROGRESS_BAR, _calculatedCacheProgress + _calculatedExecuteProgress); + + SetTaskbarButtonProgress(_calculatedCacheProgress + _calculatedExecuteProgress); + + return __super::OnCacheAcquireProgress(wzPackageOrContainerId, wzPayloadId, dw64Progress, dw64Total, dwOverallPercentage); + } + + + virtual STDMETHODIMP_(int) OnCacheAcquireComplete( + __in_z LPCWSTR wzPackageOrContainerId, + __in_z_opt LPCWSTR wzPayloadId, + __in HRESULT hrStatus, + __in int nRecommendation + ) { + SetProgressState(hrStatus); + return __super::OnCacheAcquireComplete(wzPackageOrContainerId, wzPayloadId, hrStatus, nRecommendation); + } + + + virtual STDMETHODIMP_(int) OnCacheVerifyComplete( + __in_z LPCWSTR wzPackageId, + __in_z LPCWSTR wzPayloadId, + __in HRESULT hrStatus, + __in int nRecommendation + ) { + SetProgressState(hrStatus); + return __super::OnCacheVerifyComplete(wzPackageId, wzPayloadId, hrStatus, nRecommendation); + } + + + virtual STDMETHODIMP_(void) OnCacheComplete(__in HRESULT /*hrStatus*/) { + ThemeSetTextControl(_theme, ID_CACHE_PROGRESS_PACKAGE_TEXT, L""); + SetState(PYBA_STATE_CACHED, S_OK); // we always return success here and let OnApplyComplete() deal with the error. + } + + + virtual STDMETHODIMP_(int) OnError( + __in BOOTSTRAPPER_ERROR_TYPE errorType, + __in LPCWSTR wzPackageId, + __in DWORD dwCode, + __in_z LPCWSTR wzError, + __in DWORD dwUIHint, + __in DWORD /*cData*/, + __in_ecount_z_opt(cData) LPCWSTR* /*rgwzData*/, + __in int nRecommendation + ) { + int nResult = nRecommendation; + LPWSTR sczError = nullptr; + + if (BOOTSTRAPPER_DISPLAY_EMBEDDED == _command.display) { + HRESULT hr = _engine->SendEmbeddedError(dwCode, wzError, dwUIHint, &nResult); + if (FAILED(hr)) { + nResult = IDERROR; + } + } else if (BOOTSTRAPPER_DISPLAY_FULL == _command.display) { + // If this is an authentication failure, let the engine try to handle it for us. + if (BOOTSTRAPPER_ERROR_TYPE_HTTP_AUTH_SERVER == errorType || BOOTSTRAPPER_ERROR_TYPE_HTTP_AUTH_PROXY == errorType) { + nResult = IDTRYAGAIN; + } else // show a generic error message box. + { + BalRetryErrorOccurred(wzPackageId, dwCode); + + if (!_showingInternalUIThisPackage) { + // If no error message was provided, use the error code to try and get an error message. + if (!wzError || !*wzError || BOOTSTRAPPER_ERROR_TYPE_WINDOWS_INSTALLER != errorType) { + HRESULT hr = StrAllocFromError(&sczError, dwCode, nullptr); + if (FAILED(hr) || !sczError || !*sczError) { + StrAllocFormatted(&sczError, L"0x%x", dwCode); + } + } + + nResult = ::MessageBoxW(_hWnd, sczError ? sczError : wzError, _theme->sczCaption, dwUIHint); + } + } + + SetProgressState(HRESULT_FROM_WIN32(dwCode)); + } else { + // just take note of the error code and let things continue. + BalRetryErrorOccurred(wzPackageId, dwCode); + } + + ReleaseStr(sczError); + return nResult; + } + + + virtual STDMETHODIMP_(int) OnExecuteMsiMessage( + __in_z LPCWSTR wzPackageId, + __in INSTALLMESSAGE mt, + __in UINT uiFlags, + __in_z LPCWSTR wzMessage, + __in DWORD cData, + __in_ecount_z_opt(cData) LPCWSTR* rgwzData, + __in int nRecommendation + ) { +#ifdef DEBUG + BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "PYBA: OnExecuteMsiMessage() - package: %ls, message: %ls", wzPackageId, wzMessage); +#endif + if (BOOTSTRAPPER_DISPLAY_FULL == _command.display && (INSTALLMESSAGE_WARNING == mt || INSTALLMESSAGE_USER == mt)) { + int nResult = ::MessageBoxW(_hWnd, wzMessage, _theme->sczCaption, uiFlags); + return nResult; + } + + if (INSTALLMESSAGE_ACTIONSTART == mt) { + ThemeSetTextControl(_theme, ID_EXECUTE_PROGRESS_ACTIONDATA_TEXT, wzMessage); + } + + return __super::OnExecuteMsiMessage(wzPackageId, mt, uiFlags, wzMessage, cData, rgwzData, nRecommendation); + } + + + virtual STDMETHODIMP_(int) OnProgress(__in DWORD dwProgressPercentage, __in DWORD dwOverallProgressPercentage) { + WCHAR wzProgress[5] = { }; + +#ifdef DEBUG + BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "PYBA: OnProgress() - progress: %u%%, overall progress: %u%%", dwProgressPercentage, dwOverallProgressPercentage); +#endif + + ::StringCchPrintfW(wzProgress, countof(wzProgress), L"%u%%", dwOverallProgressPercentage); + ThemeSetTextControl(_theme, ID_OVERALL_PROGRESS_TEXT, wzProgress); + + ThemeSetProgressControl(_theme, ID_OVERALL_PROGRESS_BAR, dwOverallProgressPercentage); + SetTaskbarButtonProgress(dwOverallProgressPercentage); + + return __super::OnProgress(dwProgressPercentage, dwOverallProgressPercentage); + } + + + virtual STDMETHODIMP_(int) OnExecutePackageBegin(__in_z LPCWSTR wzPackageId, __in BOOL fExecute) { + LPWSTR sczFormattedString = nullptr; + + _startedExecution = TRUE; + + if (wzPackageId && *wzPackageId) { + BAL_INFO_PACKAGE* pPackage = nullptr; + BalInfoFindPackageById(&_bundle.packages, wzPackageId, &pPackage); + + LPCWSTR wz = wzPackageId; + if (pPackage) { + LOC_STRING* pLocString = nullptr; + + switch (pPackage->type) { + case BAL_INFO_PACKAGE_TYPE_BUNDLE_ADDON: + LocGetString(_wixLoc, L"#(loc.ExecuteAddonRelatedBundleMessage)", &pLocString); + break; + + case BAL_INFO_PACKAGE_TYPE_BUNDLE_PATCH: + LocGetString(_wixLoc, L"#(loc.ExecutePatchRelatedBundleMessage)", &pLocString); + break; + + case BAL_INFO_PACKAGE_TYPE_BUNDLE_UPGRADE: + LocGetString(_wixLoc, L"#(loc.ExecuteUpgradeRelatedBundleMessage)", &pLocString); + break; + } + + if (pLocString) { + // If the wix developer is showing a hidden variable in the UI, then obviously they don't care about keeping it safe + // so don't go down the rabbit hole of making sure that this is securely freed. + BalFormatString(pLocString->wzText, &sczFormattedString); + } + + wz = sczFormattedString ? sczFormattedString : pPackage->sczDisplayName ? pPackage->sczDisplayName : wzPackageId; + } + + _showingInternalUIThisPackage = pPackage && pPackage->fDisplayInternalUI; + + ThemeSetTextControl(_theme, ID_EXECUTE_PROGRESS_PACKAGE_TEXT, wz); + ThemeSetTextControl(_theme, ID_OVERALL_PROGRESS_PACKAGE_TEXT, wz); + } else { + _showingInternalUIThisPackage = FALSE; + } + + ReleaseStr(sczFormattedString); + return __super::OnExecutePackageBegin(wzPackageId, fExecute); + } + + + virtual int __stdcall OnExecuteProgress( + __in_z LPCWSTR wzPackageId, + __in DWORD dwProgressPercentage, + __in DWORD dwOverallProgressPercentage + ) { + WCHAR wzProgress[8] = { }; + +#ifdef DEBUG + BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "PYBA: OnExecuteProgress() - package: %ls, progress: %u%%, overall progress: %u%%", wzPackageId, dwProgressPercentage, dwOverallProgressPercentage); +#endif + + ::StringCchPrintfW(wzProgress, countof(wzProgress), L"%u%%", dwOverallProgressPercentage); + ThemeSetTextControl(_theme, ID_EXECUTE_PROGRESS_TEXT, wzProgress); + + ThemeSetProgressControl(_theme, ID_EXECUTE_PROGRESS_BAR, dwOverallProgressPercentage); + + _calculatedExecuteProgress = dwOverallProgressPercentage * (100 - PYBA_ACQUIRE_PERCENTAGE) / 100; + ThemeSetProgressControl(_theme, ID_OVERALL_CALCULATED_PROGRESS_BAR, _calculatedCacheProgress + _calculatedExecuteProgress); + + SetTaskbarButtonProgress(_calculatedCacheProgress + _calculatedExecuteProgress); + + return __super::OnExecuteProgress(wzPackageId, dwProgressPercentage, dwOverallProgressPercentage); + } + + + virtual STDMETHODIMP_(int) OnExecutePackageComplete( + __in_z LPCWSTR wzPackageId, + __in HRESULT hrExitCode, + __in BOOTSTRAPPER_APPLY_RESTART restart, + __in int nRecommendation + ) { + SetProgressState(hrExitCode); + + if (_wcsnicmp(wzPackageId, L"path_", 5) == 0 && SUCCEEDED(hrExitCode)) { + SendMessageTimeoutW( + HWND_BROADCAST, + WM_SETTINGCHANGE, + 0, + reinterpret_cast(L"Environment"), + SMTO_ABORTIFHUNG, + 1000, + nullptr + ); + } + + int nResult = __super::OnExecutePackageComplete(wzPackageId, hrExitCode, restart, nRecommendation); + + return nResult; + } + + + virtual STDMETHODIMP_(void) OnExecuteComplete(__in HRESULT hrStatus) { + ThemeSetTextControl(_theme, ID_EXECUTE_PROGRESS_PACKAGE_TEXT, L""); + ThemeSetTextControl(_theme, ID_EXECUTE_PROGRESS_ACTIONDATA_TEXT, L""); + ThemeSetTextControl(_theme, ID_OVERALL_PROGRESS_PACKAGE_TEXT, L""); + ThemeControlEnable(_theme, ID_PROGRESS_CANCEL_BUTTON, FALSE); // no more cancel. + + SetState(PYBA_STATE_EXECUTED, S_OK); // we always return success here and let OnApplyComplete() deal with the error. + SetProgressState(hrStatus); + } + + + virtual STDMETHODIMP_(int) OnResolveSource( + __in_z LPCWSTR wzPackageOrContainerId, + __in_z_opt LPCWSTR wzPayloadId, + __in_z LPCWSTR wzLocalSource, + __in_z_opt LPCWSTR wzDownloadSource + ) { + int nResult = IDERROR; // assume we won't resolve source and that is unexpected. + + if (BOOTSTRAPPER_DISPLAY_FULL == _command.display) { + if (wzDownloadSource) { + nResult = IDDOWNLOAD; + } else { + // prompt to change the source location. + OPENFILENAMEW ofn = { }; + WCHAR wzFile[MAX_PATH] = { }; + + ::StringCchCopyW(wzFile, countof(wzFile), wzLocalSource); + + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = _hWnd; + ofn.lpstrFile = wzFile; + ofn.nMaxFile = countof(wzFile); + ofn.lpstrFilter = L"All Files\0*.*\0"; + ofn.nFilterIndex = 1; + ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; + ofn.lpstrTitle = _theme->sczCaption; + + if (::GetOpenFileNameW(&ofn)) { + HRESULT hr = _engine->SetLocalSource(wzPackageOrContainerId, wzPayloadId, ofn.lpstrFile); + nResult = SUCCEEDED(hr) ? IDRETRY : IDERROR; + } else { + nResult = IDCANCEL; + } + } + } else if (wzDownloadSource) { + // If doing a non-interactive install and download source is available, let's try downloading the package silently + nResult = IDDOWNLOAD; + } + // else there's nothing more we can do in non-interactive mode + + return CheckCanceled() ? IDCANCEL : nResult; + } + + + virtual STDMETHODIMP_(int) OnApplyComplete(__in HRESULT hrStatus, __in BOOTSTRAPPER_APPLY_RESTART restart) { + _restartResult = restart; // remember the restart result so we return the correct error code no matter what the user chooses to do in the UI. + + // If a restart was encountered and we are not suppressing restarts, then restart is required. + _restartRequired = (BOOTSTRAPPER_APPLY_RESTART_NONE != restart && BOOTSTRAPPER_RESTART_NEVER < _command.restart); + // If a restart is required and we're not displaying a UI or we are not supposed to prompt for restart then allow the restart. + _allowRestart = _restartRequired && (BOOTSTRAPPER_DISPLAY_FULL > _command.display || BOOTSTRAPPER_RESTART_PROMPT < _command.restart); + + // If we are showing UI, wait a beat before moving to the final screen. + if (BOOTSTRAPPER_DISPLAY_NONE < _command.display) { + ::Sleep(250); + } + + SetState(PYBA_STATE_APPLIED, hrStatus); + SetTaskbarButtonProgress(100); // show full progress bar, green, yellow, or red + + return IDNOACTION; + } + + virtual STDMETHODIMP_(void) OnLaunchApprovedExeComplete(__in HRESULT hrStatus, __in DWORD /*processId*/) { + if (HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED) == hrStatus) { + //try with ShelExec next time + OnClickLaunchButton(); + } else { + ::PostMessageW(_hWnd, WM_CLOSE, 0, 0); + } + } + + +private: + // + // UiThreadProc - entrypoint for UI thread. + // + static DWORD WINAPI UiThreadProc(__in LPVOID pvContext) { + HRESULT hr = S_OK; + PythonBootstrapperApplication* pThis = (PythonBootstrapperApplication*)pvContext; + BOOL comInitialized = FALSE; + BOOL ret = FALSE; + MSG msg = { }; + + // Initialize COM and theme. + hr = ::CoInitialize(nullptr); + BalExitOnFailure(hr, "Failed to initialize COM."); + comInitialized = TRUE; + + hr = ThemeInitialize(pThis->_hModule); + BalExitOnFailure(hr, "Failed to initialize theme manager."); + + hr = pThis->InitializeData(); + BalExitOnFailure(hr, "Failed to initialize data in bootstrapper application."); + + // Create main window. + pThis->InitializeTaskbarButton(); + hr = pThis->CreateMainWindow(); + BalExitOnFailure(hr, "Failed to create main window."); + + if (FAILED(pThis->_hrFinal)) { + pThis->SetState(PYBA_STATE_FAILED, hr); + ::PostMessageW(pThis->_hWnd, WM_PYBA_SHOW_FAILURE, 0, 0); + } else { + // Okay, we're ready for packages now. + pThis->SetState(PYBA_STATE_INITIALIZED, hr); + ::PostMessageW(pThis->_hWnd, BOOTSTRAPPER_ACTION_HELP == pThis->_command.action ? WM_PYBA_SHOW_HELP : WM_PYBA_DETECT_PACKAGES, 0, 0); + } + + // message pump + while (0 != (ret = ::GetMessageW(&msg, nullptr, 0, 0))) { + if (-1 == ret) { + hr = E_UNEXPECTED; + BalExitOnFailure(hr, "Unexpected return value from message pump."); + } else if (!ThemeHandleKeyboardMessage(pThis->_theme, msg.hwnd, &msg)) { + ::TranslateMessage(&msg); + ::DispatchMessageW(&msg); + } + } + + // Succeeded thus far, check to see if anything went wrong while actually + // executing changes. + if (FAILED(pThis->_hrFinal)) { + hr = pThis->_hrFinal; + } else if (pThis->CheckCanceled()) { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + + LExit: + // destroy main window + pThis->DestroyMainWindow(); + + // initiate engine shutdown + DWORD dwQuit = HRESULT_CODE(hr); + if (BOOTSTRAPPER_APPLY_RESTART_INITIATED == pThis->_restartResult) { + dwQuit = ERROR_SUCCESS_REBOOT_INITIATED; + } else if (BOOTSTRAPPER_APPLY_RESTART_REQUIRED == pThis->_restartResult) { + dwQuit = ERROR_SUCCESS_REBOOT_REQUIRED; + } + pThis->_engine->Quit(dwQuit); + + ReleaseTheme(pThis->_theme); + ThemeUninitialize(); + + // uninitialize COM + if (comInitialized) { + ::CoUninitialize(); + } + + return hr; + } + + + // + // InitializeData - initializes all the package information. + // + HRESULT InitializeData() { + HRESULT hr = S_OK; + LPWSTR sczModulePath = nullptr; + IXMLDOMDocument *pixdManifest = nullptr; + + hr = BalManifestLoad(_hModule, &pixdManifest); + BalExitOnFailure(hr, "Failed to load bootstrapper application manifest."); + + hr = ParseOverridableVariablesFromXml(pixdManifest); + BalExitOnFailure(hr, "Failed to read overridable variables."); + + hr = ProcessCommandLine(&_language); + ExitOnFailure(hr, "Unknown commandline parameters."); + + hr = PathRelativeToModule(&sczModulePath, nullptr, _hModule); + BalExitOnFailure(hr, "Failed to get module path."); + + hr = LoadLocalization(sczModulePath, _language); + ExitOnFailure(hr, "Failed to load localization."); + + hr = LoadTheme(sczModulePath, _language); + ExitOnFailure(hr, "Failed to load theme."); + + hr = BalInfoParseFromXml(&_bundle, pixdManifest); + BalExitOnFailure(hr, "Failed to load bundle information."); + + hr = BalConditionsParseFromXml(&_conditions, pixdManifest, _wixLoc); + BalExitOnFailure(hr, "Failed to load conditions from XML."); + + hr = LoadBootstrapperBAFunctions(); + BalExitOnFailure(hr, "Failed to load bootstrapper functions."); + + GetBundleFileVersion(); + // don't fail if we couldn't get the version info; best-effort only + + LExit: + ReleaseObject(pixdManifest); + ReleaseStr(sczModulePath); + + return hr; + } + + + // + // ProcessCommandLine - process the provided command line arguments. + // + HRESULT ProcessCommandLine(__inout LPWSTR* psczLanguage) { + HRESULT hr = S_OK; + int argc = 0; + LPWSTR* argv = nullptr; + LPWSTR sczVariableName = nullptr; + LPWSTR sczVariableValue = nullptr; + + if (_command.wzCommandLine && *_command.wzCommandLine) { + argv = ::CommandLineToArgvW(_command.wzCommandLine, &argc); + ExitOnNullWithLastError(argv, hr, "Failed to get command line."); + + for (int i = 0; i < argc; ++i) { + if (argv[i][0] == L'-' || argv[i][0] == L'/') { + if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"lang", -1)) { + if (i + 1 >= argc) { + hr = E_INVALIDARG; + BalExitOnFailure(hr, "Must specify a language."); + } + + ++i; + + hr = StrAllocString(psczLanguage, &argv[i][0], 0); + BalExitOnFailure(hr, "Failed to copy language."); + } + } else if (_overridableVariables) { + int value; + const wchar_t* pwc = wcschr(argv[i], L'='); + if (pwc) { + hr = StrAllocString(&sczVariableName, argv[i], pwc - argv[i]); + BalExitOnFailure(hr, "Failed to copy variable name."); + + hr = DictKeyExists(_overridableVariables, sczVariableName); + if (E_NOTFOUND == hr) { + BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Ignoring attempt to set non-overridable variable: '%ls'.", sczVariableName); + hr = S_OK; + continue; + } + ExitOnFailure(hr, "Failed to check the dictionary of overridable variables."); + + hr = StrAllocString(&sczVariableValue, ++pwc, 0); + BalExitOnFailure(hr, "Failed to copy variable value."); + + if (::StrToIntEx(sczVariableValue, STIF_DEFAULT, &value)) { + hr = _engine->SetVariableNumeric(sczVariableName, value); + } else { + hr = _engine->SetVariableString(sczVariableName, sczVariableValue); + } + BalExitOnFailure(hr, "Failed to set variable."); + } else { + BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Ignoring unknown argument: %ls", argv[i]); + } + } + } + } + + LExit: + if (argv) { + ::LocalFree(argv); + } + + ReleaseStr(sczVariableName); + ReleaseStr(sczVariableValue); + + return hr; + } + + HRESULT LoadLocalization(__in_z LPCWSTR wzModulePath, __in_z_opt LPCWSTR wzLanguage) { + HRESULT hr = S_OK; + LPWSTR sczLocPath = nullptr; + LPCWSTR wzLocFileName = L"Default.wxl"; + + hr = LocProbeForFile(wzModulePath, wzLocFileName, wzLanguage, &sczLocPath); + BalExitOnFailure2(hr, "Failed to probe for loc file: %ls in path: %ls", wzLocFileName, wzModulePath); + + hr = LocLoadFromFile(sczLocPath, &_wixLoc); + BalExitOnFailure1(hr, "Failed to load loc file from path: %ls", sczLocPath); + + if (WIX_LOCALIZATION_LANGUAGE_NOT_SET != _wixLoc->dwLangId) { + ::SetThreadLocale(_wixLoc->dwLangId); + } + + hr = StrAllocString(&_confirmCloseMessage, L"#(loc.ConfirmCancelMessage)", 0); + ExitOnFailure(hr, "Failed to initialize confirm message loc identifier."); + + hr = LocLocalizeString(_wixLoc, &_confirmCloseMessage); + BalExitOnFailure1(hr, "Failed to localize confirm close message: %ls", _confirmCloseMessage); + + LExit: + ReleaseStr(sczLocPath); + + return hr; + } + + + HRESULT LoadTheme(__in_z LPCWSTR wzModulePath, __in_z_opt LPCWSTR wzLanguage) { + HRESULT hr = S_OK; + LPWSTR sczThemePath = nullptr; + LPCWSTR wzThemeFileName = L"Default.thm"; + LPWSTR sczCaption = nullptr; + + hr = LocProbeForFile(wzModulePath, wzThemeFileName, wzLanguage, &sczThemePath); + BalExitOnFailure2(hr, "Failed to probe for theme file: %ls in path: %ls", wzThemeFileName, wzModulePath); + + hr = ThemeLoadFromFile(sczThemePath, &_theme); + BalExitOnFailure1(hr, "Failed to load theme from path: %ls", sczThemePath); + + hr = ThemeLocalize(_theme, _wixLoc); + BalExitOnFailure1(hr, "Failed to localize theme: %ls", sczThemePath); + + // Update the caption if there are any formatted strings in it. + // If the wix developer is showing a hidden variable in the UI, then + // obviously they don't care about keeping it safe so don't go down the + // rabbit hole of making sure that this is securely freed. + hr = BalFormatString(_theme->sczCaption, &sczCaption); + if (SUCCEEDED(hr)) { + ThemeUpdateCaption(_theme, sczCaption); + } + + LExit: + ReleaseStr(sczCaption); + ReleaseStr(sczThemePath); + + return hr; + } + + + HRESULT ParseOverridableVariablesFromXml(__in IXMLDOMDocument* pixdManifest) { + HRESULT hr = S_OK; + IXMLDOMNode* pNode = nullptr; + IXMLDOMNodeList* pNodes = nullptr; + DWORD cNodes = 0; + LPWSTR scz = nullptr; + BOOL hidden = FALSE; + + // get the list of variables users can override on the command line + hr = XmlSelectNodes(pixdManifest, L"/BootstrapperApplicationData/WixStdbaOverridableVariable", &pNodes); + if (S_FALSE == hr) { + ExitFunction1(hr = S_OK); + } + ExitOnFailure(hr, "Failed to select overridable variable nodes."); + + hr = pNodes->get_length((long*)&cNodes); + ExitOnFailure(hr, "Failed to get overridable variable node count."); + + if (cNodes) { + hr = DictCreateStringList(&_overridableVariables, 32, DICT_FLAG_NONE); + ExitOnFailure(hr, "Failed to create the string dictionary."); + + for (DWORD i = 0; i < cNodes; ++i) { + hr = XmlNextElement(pNodes, &pNode, nullptr); + ExitOnFailure(hr, "Failed to get next node."); + + // @Name + hr = XmlGetAttributeEx(pNode, L"Name", &scz); + ExitOnFailure(hr, "Failed to get @Name."); + + hr = XmlGetYesNoAttribute(pNode, L"Hidden", &hidden); + + if (!hidden) { + hr = DictAddKey(_overridableVariables, scz); + ExitOnFailure1(hr, "Failed to add \"%ls\" to the string dictionary.", scz); + } + + // prepare next iteration + ReleaseNullObject(pNode); + } + } + + LExit: + ReleaseObject(pNode); + ReleaseObject(pNodes); + ReleaseStr(scz); + return hr; + } + + + // + // Get the file version of the bootstrapper and record in bootstrapper log file + // + HRESULT GetBundleFileVersion() { + HRESULT hr = S_OK; + ULARGE_INTEGER uliVersion = { }; + LPWSTR sczCurrentPath = nullptr; + + hr = PathForCurrentProcess(&sczCurrentPath, nullptr); + BalExitOnFailure(hr, "Failed to get bundle path."); + + hr = FileVersion(sczCurrentPath, &uliVersion.HighPart, &uliVersion.LowPart); + BalExitOnFailure(hr, "Failed to get bundle file version."); + + hr = _engine->SetVariableVersion(PYBA_VARIABLE_BUNDLE_FILE_VERSION, uliVersion.QuadPart); + BalExitOnFailure(hr, "Failed to set WixBundleFileVersion variable."); + + LExit: + ReleaseStr(sczCurrentPath); + + return hr; + } + + + // + // CreateMainWindow - creates the main install window. + // + HRESULT CreateMainWindow() { + HRESULT hr = S_OK; + HICON hIcon = reinterpret_cast(_theme->hIcon); + WNDCLASSW wc = { }; + DWORD dwWindowStyle = 0; + int x = CW_USEDEFAULT; + int y = CW_USEDEFAULT; + POINT ptCursor = { }; + HMONITOR hMonitor = nullptr; + MONITORINFO mi = { }; + + // If the theme did not provide an icon, try using the icon from the bundle engine. + if (!hIcon) { + HMODULE hBootstrapperEngine = ::GetModuleHandleW(nullptr); + if (hBootstrapperEngine) { + hIcon = ::LoadIconW(hBootstrapperEngine, MAKEINTRESOURCEW(1)); + } + } + + // Register the window class and create the window. + wc.lpfnWndProc = PythonBootstrapperApplication::WndProc; + wc.hInstance = _hModule; + wc.hIcon = hIcon; + wc.hCursor = ::LoadCursorW(nullptr, (LPCWSTR)IDC_ARROW); + wc.hbrBackground = _theme->rgFonts[_theme->dwFontId].hBackground; + wc.lpszMenuName = nullptr; + wc.lpszClassName = PYBA_WINDOW_CLASS; + if (!::RegisterClassW(&wc)) { + ExitWithLastError(hr, "Failed to register window."); + } + + _registered = TRUE; + + // Calculate the window style based on the theme style and command display value. + dwWindowStyle = _theme->dwStyle; + if (BOOTSTRAPPER_DISPLAY_NONE >= _command.display) { + dwWindowStyle &= ~WS_VISIBLE; + } + + // Don't show the window if there is a splash screen (it will be made visible when the splash screen is hidden) + if (::IsWindow(_command.hwndSplashScreen)) { + dwWindowStyle &= ~WS_VISIBLE; + } + + // Center the window on the monitor with the mouse. + if (::GetCursorPos(&ptCursor)) { + hMonitor = ::MonitorFromPoint(ptCursor, MONITOR_DEFAULTTONEAREST); + if (hMonitor) { + mi.cbSize = sizeof(mi); + if (::GetMonitorInfoW(hMonitor, &mi)) { + x = mi.rcWork.left + (mi.rcWork.right - mi.rcWork.left - _theme->nWidth) / 2; + y = mi.rcWork.top + (mi.rcWork.bottom - mi.rcWork.top - _theme->nHeight) / 2; + } + } + } + + _hWnd = ::CreateWindowExW( + 0, + wc.lpszClassName, + _theme->sczCaption, + dwWindowStyle, + x, + y, + _theme->nWidth, + _theme->nHeight, + HWND_DESKTOP, + nullptr, + _hModule, + this + ); + ExitOnNullWithLastError(_hWnd, hr, "Failed to create window."); + + hr = S_OK; + + LExit: + return hr; + } + + + // + // InitializeTaskbarButton - initializes taskbar button for progress. + // + void InitializeTaskbarButton() { + HRESULT hr = S_OK; + + hr = ::CoCreateInstance(CLSID_TaskbarList, nullptr, CLSCTX_ALL, __uuidof(ITaskbarList3), reinterpret_cast(&_taskbarList)); + if (REGDB_E_CLASSNOTREG == hr) { + // not supported before Windows 7 + ExitFunction1(hr = S_OK); + } + BalExitOnFailure(hr, "Failed to create ITaskbarList3. Continuing."); + + _taskbarButtonCreatedMessage = ::RegisterWindowMessageW(L"TaskbarButtonCreated"); + BalExitOnNullWithLastError(_taskbarButtonCreatedMessage, hr, "Failed to get TaskbarButtonCreated message. Continuing."); + + LExit: + return; + } + + // + // DestroyMainWindow - clean up all the window registration. + // + void DestroyMainWindow() { + if (::IsWindow(_hWnd)) { + ::DestroyWindow(_hWnd); + _hWnd = nullptr; + _taskbarButtonOK = FALSE; + } + + if (_registered) { + ::UnregisterClassW(PYBA_WINDOW_CLASS, _hModule); + _registered = FALSE; + } + } + + + // + // WndProc - standard windows message handler. + // + static LRESULT CALLBACK WndProc( + __in HWND hWnd, + __in UINT uMsg, + __in WPARAM wParam, + __in LPARAM lParam + ) { +#pragma warning(suppress:4312) + auto pBA = reinterpret_cast(::GetWindowLongPtrW(hWnd, GWLP_USERDATA)); + + switch (uMsg) { + case WM_NCCREATE: { + LPCREATESTRUCT lpcs = reinterpret_cast(lParam); + pBA = reinterpret_cast(lpcs->lpCreateParams); +#pragma warning(suppress:4244) + ::SetWindowLongPtrW(hWnd, GWLP_USERDATA, reinterpret_cast(pBA)); + break; + } + + case WM_NCDESTROY: { + LRESULT lres = ThemeDefWindowProc(pBA ? pBA->_theme : nullptr, hWnd, uMsg, wParam, lParam); + ::SetWindowLongPtrW(hWnd, GWLP_USERDATA, 0); + return lres; + } + + case WM_CREATE: + if (!pBA->OnCreate(hWnd)) { + return -1; + } + break; + + case WM_QUERYENDSESSION: + return IDCANCEL != pBA->OnSystemShutdown(static_cast(lParam), IDCANCEL); + + case WM_CLOSE: + // If the user chose not to close, do *not* let the default window proc handle the message. + if (!pBA->OnClose()) { + return 0; + } + break; + + case WM_DESTROY: + ::PostQuitMessage(0); + break; + + case WM_PAINT: __fallthrough; + case WM_ERASEBKGND: + if (pBA && pBA->_suppressPaint) { + return TRUE; + } + break; + + case WM_PYBA_SHOW_HELP: + pBA->OnShowHelp(); + return 0; + + case WM_PYBA_DETECT_PACKAGES: + pBA->OnDetect(); + return 0; + + case WM_PYBA_PLAN_PACKAGES: + pBA->OnPlan(static_cast(lParam)); + return 0; + + case WM_PYBA_APPLY_PACKAGES: + pBA->OnApply(); + return 0; + + case WM_PYBA_CHANGE_STATE: + pBA->OnChangeState(static_cast(lParam)); + return 0; + + case WM_PYBA_SHOW_FAILURE: + pBA->OnShowFailure(); + return 0; + + case WM_COMMAND: + switch (LOWORD(wParam)) { + // Customize commands + // Success/failure commands + case ID_LAUNCH_BUTTON: + pBA->OnClickLaunchButton(); + return 0; + + case ID_SUCCESS_RESTART_BUTTON: __fallthrough; + case ID_FAILURE_RESTART_BUTTON: + pBA->OnClickRestartButton(); + return 0; + + case IDCANCEL: __fallthrough; + case ID_INSTALL_CANCEL_BUTTON: __fallthrough; + case ID_CUSTOM1_CANCEL_BUTTON: __fallthrough; + case ID_CUSTOM2_CANCEL_BUTTON: __fallthrough; + case ID_MODIFY_CANCEL_BUTTON: __fallthrough; + case ID_PROGRESS_CANCEL_BUTTON: __fallthrough; + case ID_SUCCESS_CANCEL_BUTTON: __fallthrough; + case ID_FAILURE_CANCEL_BUTTON: __fallthrough; + case ID_CLOSE_BUTTON: + pBA->OnCommand(ID_CLOSE_BUTTON); + return 0; + + default: + pBA->OnCommand((CONTROL_ID)LOWORD(wParam)); + } + break; + + case WM_NOTIFY: + if (lParam) { + LPNMHDR pnmhdr = reinterpret_cast(lParam); + switch (pnmhdr->code) { + case NM_CLICK: __fallthrough; + case NM_RETURN: + switch (static_cast(pnmhdr->idFrom)) { + case ID_FAILURE_LOGFILE_LINK: + pBA->OnClickLogFileLink(); + return 1; + } + } + } + break; + + case WM_CTLCOLORBTN: + if (pBA) { + HWND button = (HWND)lParam; + DWORD style = GetWindowLong(button, GWL_STYLE) & BS_TYPEMASK; + if (style == BS_COMMANDLINK || style == BS_DEFCOMMANDLINK) { + return (LRESULT)pBA->_theme->rgFonts[pBA->_theme->dwFontId].hBackground; + } + } + break; + } + + if (pBA && pBA->_taskbarList && uMsg == pBA->_taskbarButtonCreatedMessage) { + pBA->_taskbarButtonOK = TRUE; + return 0; + } + + return ThemeDefWindowProc(pBA ? pBA->_theme : nullptr, hWnd, uMsg, wParam, lParam); + } + + // + // OnCreate - finishes loading the theme. + // + BOOL OnCreate(__in HWND hWnd) { + HRESULT hr = S_OK; + + hr = ThemeLoadControls(_theme, hWnd, CONTROL_ID_NAMES, countof(CONTROL_ID_NAMES)); + BalExitOnFailure(hr, "Failed to load theme controls."); + + C_ASSERT(COUNT_PAGE == countof(PAGE_NAMES)); + C_ASSERT(countof(_pageIds) == countof(PAGE_NAMES)); + + ThemeGetPageIds(_theme, PAGE_NAMES, _pageIds, countof(_pageIds)); + + // Initialize the text on all "application" (non-page) controls. + for (DWORD i = 0; i < _theme->cControls; ++i) { + THEME_CONTROL* pControl = _theme->rgControls + i; + LPWSTR text = nullptr; + LPWSTR name = nullptr; + LOC_STRING *locText = nullptr; + + // If a command link has a note, then add it. + if ((pControl->dwStyle & BS_TYPEMASK) == BS_COMMANDLINK || + (pControl->dwStyle & BS_TYPEMASK) == BS_DEFCOMMANDLINK) { + hr = StrAllocFormatted(&name, L"#(loc.%lsNote)", pControl->sczName); + if (SUCCEEDED(hr)) { + hr = LocGetString(_wixLoc, name, &locText); + ReleaseStr(name); + if (SUCCEEDED(hr) && locText && locText->wzText && locText->wzText[0]) { + hr = BalFormatString(locText->wzText, &text); + if (SUCCEEDED(hr) && text && text[0]) { + ThemeSendControlMessage(_theme, pControl->wId, BCM_SETNOTE, 0, (LPARAM)text); + ReleaseStr(text); + text = nullptr; + } + } + } + hr = S_OK; + } + + if (!pControl->wPageId && pControl->sczText && *pControl->sczText) { + HRESULT hrFormat; + + // If the wix developer is showing a hidden variable in the UI, + // then obviously they don't care about keeping it safe so don't + // go down the rabbit hole of making sure that this is securely + // freed. + hrFormat = BalFormatString(pControl->sczText, &text); + if (SUCCEEDED(hrFormat)) { + ThemeSetTextControl(_theme, pControl->wId, text); + ReleaseStr(text); + } + } + } + + LExit: + return SUCCEEDED(hr); + } + + + // + // OnShowFailure - display the failure page. + // + void OnShowFailure() { + SetState(PYBA_STATE_FAILED, S_OK); + + // If the UI should be visible, display it now and hide the splash screen + if (BOOTSTRAPPER_DISPLAY_NONE < _command.display) { + ::ShowWindow(_theme->hwndParent, SW_SHOW); + } + + _engine->CloseSplashScreen(); + + return; + } + + + // + // OnShowHelp - display the help page. + // + void OnShowHelp() { + SetState(PYBA_STATE_HELP, S_OK); + + // If the UI should be visible, display it now and hide the splash screen + if (BOOTSTRAPPER_DISPLAY_NONE < _command.display) { + ::ShowWindow(_theme->hwndParent, SW_SHOW); + } + + _engine->CloseSplashScreen(); + + return; + } + + + // + // OnDetect - start the processing of packages. + // + void OnDetect() { + HRESULT hr = S_OK; + + if (_baFunction) { + BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Running detect BA function"); + hr = _baFunction->OnDetect(); + BalExitOnFailure(hr, "Failed calling detect BA function."); + } + + SetState(PYBA_STATE_DETECTING, hr); + + // If the UI should be visible, display it now and hide the splash screen + if (BOOTSTRAPPER_DISPLAY_NONE < _command.display) { + ::ShowWindow(_theme->hwndParent, SW_SHOW); + } + + _engine->CloseSplashScreen(); + + // Tell the core we're ready for the packages to be processed now. + hr = _engine->Detect(); + BalExitOnFailure(hr, "Failed to start detecting chain."); + + LExit: + if (FAILED(hr)) { + SetState(PYBA_STATE_DETECTING, hr); + } + + return; + } + + + // + // OnPlan - plan the detected changes. + // + void OnPlan(__in BOOTSTRAPPER_ACTION action) { + HRESULT hr = S_OK; + LPCWSTR likeInstalling = nullptr; + LPCWSTR likeInstallation = nullptr; + + _plannedAction = action; + + switch (action) { + case BOOTSTRAPPER_ACTION_INSTALL: + likeInstalling = L"Installing"; + likeInstallation = L"Installation"; + break; + case BOOTSTRAPPER_ACTION_MODIFY: + // For modify, we actually want to pass INSTALL + action = BOOTSTRAPPER_ACTION_INSTALL; + likeInstalling = L"Modifying"; + likeInstallation = L"Modification"; + break; + case BOOTSTRAPPER_ACTION_REPAIR: + likeInstalling = L"Repairing"; + likeInstallation = L"Repair"; + break; + case BOOTSTRAPPER_ACTION_UNINSTALL: + likeInstalling = L"Uninstalling"; + likeInstallation = L"Uninstallation"; + break; + } + + if (likeInstalling) { + LPWSTR locName = nullptr; + LOC_STRING *locText = nullptr; + hr = StrAllocFormatted(&locName, L"#(loc.%ls)", likeInstalling); + if (SUCCEEDED(hr)) { + hr = LocGetString(_wixLoc, locName, &locText); + ReleaseStr(locName); + } + _engine->SetVariableString( + L"ActionLikeInstalling", + SUCCEEDED(hr) && locText ? locText->wzText : likeInstalling + ); + } + + if (likeInstallation) { + LPWSTR locName = nullptr; + LOC_STRING *locText = nullptr; + hr = StrAllocFormatted(&locName, L"#(loc.%ls)", likeInstallation); + if (SUCCEEDED(hr)) { + hr = LocGetString(_wixLoc, locName, &locText); + ReleaseStr(locName); + } + _engine->SetVariableString( + L"ActionLikeInstallation", + SUCCEEDED(hr) && locText ? locText->wzText : likeInstallation + ); + } + + // If we are going to apply a downgrade, bail. + if (_downgrading && BOOTSTRAPPER_ACTION_UNINSTALL < action) { + if (_suppressDowngradeFailure) { + BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "A newer version of this product is installed but downgrade failure has been suppressed; continuing..."); + } else { + hr = HRESULT_FROM_WIN32(ERROR_PRODUCT_VERSION); + BalExitOnFailure(hr, "Cannot install a product when a newer version is installed."); + } + } + + SetState(PYBA_STATE_PLANNING, hr); + + if (_baFunction) { + BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Running plan BA function"); + _baFunction->OnPlan(); + } + + hr = _engine->Plan(action); + BalExitOnFailure(hr, "Failed to start planning packages."); + + LExit: + if (FAILED(hr)) { + SetState(PYBA_STATE_PLANNING, hr); + } + + return; + } + + + // + // OnApply - apply the packages. + // + void OnApply() { + HRESULT hr = S_OK; + + SetState(PYBA_STATE_APPLYING, hr); + SetProgressState(hr); + SetTaskbarButtonProgress(0); + + hr = _engine->Apply(_hWnd); + BalExitOnFailure(hr, "Failed to start applying packages."); + + ThemeControlEnable(_theme, ID_PROGRESS_CANCEL_BUTTON, TRUE); // ensure the cancel button is enabled before starting. + + LExit: + if (FAILED(hr)) { + SetState(PYBA_STATE_APPLYING, hr); + } + + return; + } + + + // + // OnChangeState - change state. + // + void OnChangeState(__in PYBA_STATE state) { + LPWSTR unformattedText = nullptr; + + _state = state; + + // If our install is at the end (success or failure) and we're not showing full UI + // then exit (prompt for restart if required). + if ((PYBA_STATE_APPLIED <= _state && BOOTSTRAPPER_DISPLAY_FULL > _command.display)) { + // If a restart was required but we were not automatically allowed to + // accept the reboot then do the prompt. + if (_restartRequired && !_allowRestart) { + StrAllocFromError(&unformattedText, HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_REQUIRED), nullptr); + + _allowRestart = IDOK == ::MessageBoxW( + _hWnd, + unformattedText ? unformattedText : L"The requested operation is successful. Changes will not be effective until the system is rebooted.", + _theme->sczCaption, + MB_ICONEXCLAMATION | MB_OKCANCEL + ); + } + + // Quietly exit. + ::PostMessageW(_hWnd, WM_CLOSE, 0, 0); + } else { // try to change the pages. + DWORD newPageId = 0; + DeterminePageId(_state, &newPageId); + + if (_visiblePageId != newPageId) { + ShowPage(newPageId); + } + } + + ReleaseStr(unformattedText); + } + + // + // Called before showing a page to handle all controls. + // + void ProcessPageControls(THEME_PAGE *pPage) { + if (!pPage) { + return; + } + + for (DWORD i = 0; i < pPage->cControlIndices; ++i) { + THEME_CONTROL* pControl = _theme->rgControls + pPage->rgdwControlIndices[i]; + + // If this is a named control, try to set its default state. + if (pControl->sczName && *pControl->sczName) { + // If this is a checkable control, try to set its default state + // to the state of a matching named Burn variable. + if (IsCheckable(pControl)) { + LONGLONG llValue = 0; + HRESULT hr = BalGetNumericVariable(pControl->sczName, &llValue); + + // If the control value isn't set then disable it. + if (!SUCCEEDED(hr)) { + ThemeControlEnable(_theme, pControl->wId, FALSE); + } else { + ThemeSendControlMessage( + _theme, + pControl->wId, + BM_SETCHECK, + SUCCEEDED(hr) && llValue ? BST_CHECKED : BST_UNCHECKED, + 0 + ); + } + } + + // Hide or disable controls based on the control name with 'State' appended + LPWSTR controlName = nullptr; + HRESULT hr = StrAllocFormatted(&controlName, L"%lsState", pControl->sczName); + if (SUCCEEDED(hr)) { + LPWSTR controlState = nullptr; + hr = BalGetStringVariable(controlName, &controlState); + if (SUCCEEDED(hr) && controlState && *controlState) { + if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, controlState, -1, L"disable", -1)) { + BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Disable control %ls", pControl->sczName); + ThemeControlEnable(_theme, pControl->wId, FALSE); + } else if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, controlState, -1, L"hide", -1)) { + BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Hide control %ls", pControl->sczName); + // TODO: This doesn't work + ThemeShowControl(_theme, pControl->wId, SW_HIDE); + } + } + StrFree(controlState); + } + StrFree(controlName); + } + + // Format the text in each of the new page's controls + if (pControl->sczText && *pControl->sczText) { + // If the wix developer is showing a hidden variable + // in the UI, then obviously they don't care about + // keeping it safe so don't go down the rabbit hole + // of making sure that this is securely freed. + LPWSTR text = nullptr; + HRESULT hr = BalFormatString(pControl->sczText, &text); + if (SUCCEEDED(hr)) { + ThemeSetTextControl(_theme, pControl->wId, text); + } + } + } + } + + // + // OnClose - called when the window is trying to be closed. + // + BOOL OnClose() { + BOOL close = FALSE; + + // If we've already succeeded or failed or showing the help page, just close (prompts are annoying if the bootstrapper is done). + if (PYBA_STATE_APPLIED <= _state || PYBA_STATE_HELP == _state) { + close = TRUE; + } else { + // prompt the user or force the cancel if there is no UI. + close = PromptCancel( + _hWnd, + BOOTSTRAPPER_DISPLAY_FULL != _command.display, + _confirmCloseMessage ? _confirmCloseMessage : L"Are you sure you want to cancel?", + _theme->sczCaption + ); + } + + // If we're doing progress then we never close, we just cancel to let rollback occur. + if (PYBA_STATE_APPLYING <= _state && PYBA_STATE_APPLIED > _state) { + // If we canceled disable cancel button since clicking it again is silly. + if (close) { + ThemeControlEnable(_theme, ID_PROGRESS_CANCEL_BUTTON, FALSE); + } + + close = FALSE; + } + + return close; + } + + // + // OnClickCloseButton - close the application. + // + void OnClickCloseButton() { + ::SendMessageW(_hWnd, WM_CLOSE, 0, 0); + } + + + // + // OnClickLaunchButton - launch the app from the success page. + // + void OnClickLaunchButton() { + HRESULT hr = S_OK; + LPWSTR sczUnformattedLaunchTarget = nullptr; + LPWSTR sczLaunchTarget = nullptr; + LPWSTR sczLaunchTargetElevatedId = nullptr; + LPWSTR sczUnformattedArguments = nullptr; + LPWSTR sczArguments = nullptr; + int nCmdShow = SW_SHOWNORMAL; + + hr = BalGetStringVariable(PYBA_VARIABLE_LAUNCH_TARGET_PATH, &sczUnformattedLaunchTarget); + BalExitOnFailure1(hr, "Failed to get launch target variable '%ls'.", PYBA_VARIABLE_LAUNCH_TARGET_PATH); + + hr = BalFormatString(sczUnformattedLaunchTarget, &sczLaunchTarget); + BalExitOnFailure1(hr, "Failed to format launch target variable: %ls", sczUnformattedLaunchTarget); + + if (BalStringVariableExists(PYBA_VARIABLE_LAUNCH_TARGET_ELEVATED_ID)) { + hr = BalGetStringVariable(PYBA_VARIABLE_LAUNCH_TARGET_ELEVATED_ID, &sczLaunchTargetElevatedId); + BalExitOnFailure1(hr, "Failed to get launch target elevated id '%ls'.", PYBA_VARIABLE_LAUNCH_TARGET_ELEVATED_ID); + } + + if (BalStringVariableExists(PYBA_VARIABLE_LAUNCH_ARGUMENTS)) { + hr = BalGetStringVariable(PYBA_VARIABLE_LAUNCH_ARGUMENTS, &sczUnformattedArguments); + BalExitOnFailure1(hr, "Failed to get launch arguments '%ls'.", PYBA_VARIABLE_LAUNCH_ARGUMENTS); + } + + if (BalStringVariableExists(PYBA_VARIABLE_LAUNCH_HIDDEN)) { + nCmdShow = SW_HIDE; + } + + if (sczLaunchTargetElevatedId && !_triedToLaunchElevated) { + _triedToLaunchElevated = TRUE; + hr = _engine->LaunchApprovedExe(_hWnd, sczLaunchTargetElevatedId, sczUnformattedArguments, 0); + if (FAILED(hr)) { + BalLogError(hr, "Failed to launch elevated target: %ls", sczLaunchTargetElevatedId); + + //try with ShelExec next time + OnClickLaunchButton(); + } + } else { + if (sczUnformattedArguments) { + hr = BalFormatString(sczUnformattedArguments, &sczArguments); + BalExitOnFailure1(hr, "Failed to format launch arguments variable: %ls", sczUnformattedArguments); + } + + hr = ShelExec(sczLaunchTarget, sczArguments, L"open", nullptr, nCmdShow, _hWnd, nullptr); + BalExitOnFailure1(hr, "Failed to launch target: %ls", sczLaunchTarget); + + ::PostMessageW(_hWnd, WM_CLOSE, 0, 0); + } + + LExit: + StrSecureZeroFreeString(sczArguments); + ReleaseStr(sczUnformattedArguments); + ReleaseStr(sczLaunchTargetElevatedId); + StrSecureZeroFreeString(sczLaunchTarget); + ReleaseStr(sczUnformattedLaunchTarget); + + return; + } + + + // + // OnClickRestartButton - allows the restart and closes the app. + // + void OnClickRestartButton() { + AssertSz(_restartRequired, "Restart must be requested to be able to click on the restart button."); + + _allowRestart = TRUE; + ::SendMessageW(_hWnd, WM_CLOSE, 0, 0); + + return; + } + + + // + // OnClickLogFileLink - show the log file. + // + void OnClickLogFileLink() { + HRESULT hr = S_OK; + LPWSTR sczLogFile = nullptr; + + hr = BalGetStringVariable(_bundle.sczLogVariable, &sczLogFile); + BalExitOnFailure1(hr, "Failed to get log file variable '%ls'.", _bundle.sczLogVariable); + + hr = ShelExec(L"notepad.exe", sczLogFile, L"open", nullptr, SW_SHOWDEFAULT, _hWnd, nullptr); + BalExitOnFailure1(hr, "Failed to open log file target: %ls", sczLogFile); + + LExit: + ReleaseStr(sczLogFile); + + return; + } + + + // + // SetState + // + void SetState(__in PYBA_STATE state, __in HRESULT hrStatus) { + if (FAILED(hrStatus)) { + _hrFinal = hrStatus; + } + + if (FAILED(_hrFinal)) { + state = PYBA_STATE_FAILED; + } + + if (_state != state) { + ::PostMessageW(_hWnd, WM_PYBA_CHANGE_STATE, 0, state); + } + } + + // + // GoToPage + // + void GoToPage(__in PAGE page) { + _installPage = page; + ::PostMessageW(_hWnd, WM_PYBA_CHANGE_STATE, 0, _state); + } + + void DeterminePageId(__in PYBA_STATE state, __out DWORD* pdwPageId) { + LONGLONG simple; + + if (BOOTSTRAPPER_DISPLAY_PASSIVE == _command.display) { + switch (state) { + case PYBA_STATE_INITIALIZED: + *pdwPageId = BOOTSTRAPPER_ACTION_HELP == _command.action + ? _pageIds[PAGE_HELP] + : _pageIds[PAGE_LOADING]; + break; + + case PYBA_STATE_HELP: + *pdwPageId = _pageIds[PAGE_HELP]; + break; + + case PYBA_STATE_DETECTING: + *pdwPageId = _pageIds[PAGE_LOADING] + ? _pageIds[PAGE_LOADING] + : _pageIds[PAGE_PROGRESS_PASSIVE] + ? _pageIds[PAGE_PROGRESS_PASSIVE] + : _pageIds[PAGE_PROGRESS]; + break; + + case PYBA_STATE_DETECTED: __fallthrough; + case PYBA_STATE_PLANNING: __fallthrough; + case PYBA_STATE_PLANNED: __fallthrough; + case PYBA_STATE_APPLYING: __fallthrough; + case PYBA_STATE_CACHING: __fallthrough; + case PYBA_STATE_CACHED: __fallthrough; + case PYBA_STATE_EXECUTING: __fallthrough; + case PYBA_STATE_EXECUTED: + *pdwPageId = _pageIds[PAGE_PROGRESS_PASSIVE] + ? _pageIds[PAGE_PROGRESS_PASSIVE] + : _pageIds[PAGE_PROGRESS]; + break; + + default: + *pdwPageId = 0; + break; + } + } else if (BOOTSTRAPPER_DISPLAY_FULL == _command.display) { + switch (state) { + case PYBA_STATE_INITIALIZING: + *pdwPageId = 0; + break; + + case PYBA_STATE_INITIALIZED: + *pdwPageId = BOOTSTRAPPER_ACTION_HELP == _command.action + ? _pageIds[PAGE_HELP] + : _pageIds[PAGE_LOADING]; + break; + + case PYBA_STATE_HELP: + *pdwPageId = _pageIds[PAGE_HELP]; + break; + + case PYBA_STATE_DETECTING: + *pdwPageId = _pageIds[PAGE_LOADING]; + break; + + case PYBA_STATE_DETECTED: + if (_installPage == PAGE_LOADING) { + switch (_command.action) { + case BOOTSTRAPPER_ACTION_INSTALL: + if (SUCCEEDED(BalGetNumericVariable(L"SimpleInstall", &simple)) && simple) { + _installPage = PAGE_SIMPLE_INSTALL; + } else { + _installPage = PAGE_INSTALL; + } + break; + + case BOOTSTRAPPER_ACTION_MODIFY: __fallthrough; + case BOOTSTRAPPER_ACTION_REPAIR: __fallthrough; + case BOOTSTRAPPER_ACTION_UNINSTALL: + _installPage = PAGE_MODIFY; + break; + } + } + *pdwPageId = _pageIds[_installPage]; + break; + + case PYBA_STATE_PLANNING: __fallthrough; + case PYBA_STATE_PLANNED: __fallthrough; + case PYBA_STATE_APPLYING: __fallthrough; + case PYBA_STATE_CACHING: __fallthrough; + case PYBA_STATE_CACHED: __fallthrough; + case PYBA_STATE_EXECUTING: __fallthrough; + case PYBA_STATE_EXECUTED: + *pdwPageId = _pageIds[PAGE_PROGRESS]; + break; + + case PYBA_STATE_APPLIED: + *pdwPageId = _pageIds[PAGE_SUCCESS]; + break; + + case PYBA_STATE_FAILED: + *pdwPageId = _pageIds[PAGE_FAILURE]; + break; + } + } + } + + + HRESULT EvaluateConditions() { + HRESULT hr = S_OK; + BOOL result = FALSE; + + for (DWORD i = 0; i < _conditions.cConditions; ++i) { + BAL_CONDITION* pCondition = _conditions.rgConditions + i; + + hr = BalConditionEvaluate(pCondition, _engine, &result, &_failedMessage); + BalExitOnFailure(hr, "Failed to evaluate condition."); + + if (!result) { + // Hope they didn't have hidden variables in their message, because it's going in the log in plaintext. + BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "%ls", _failedMessage); + + hr = E_WIXSTDBA_CONDITION_FAILED; + // todo: remove in WiX v4, in case people are relying on v3.x logging behavior + BalExitOnFailure1(hr, "Bundle condition evaluated to false: %ls", pCondition->sczCondition); + } + } + + ReleaseNullStrSecure(_failedMessage); + + LExit: + return hr; + } + + + void SetTaskbarButtonProgress(__in DWORD dwOverallPercentage) { + HRESULT hr = S_OK; + + if (_taskbarButtonOK) { + hr = _taskbarList->SetProgressValue(_hWnd, dwOverallPercentage, 100UL); + BalExitOnFailure1(hr, "Failed to set taskbar button progress to: %d%%.", dwOverallPercentage); + } + + LExit: + return; + } + + + void SetTaskbarButtonState(__in TBPFLAG tbpFlags) { + HRESULT hr = S_OK; + + if (_taskbarButtonOK) { + hr = _taskbarList->SetProgressState(_hWnd, tbpFlags); + BalExitOnFailure1(hr, "Failed to set taskbar button state.", tbpFlags); + } + + LExit: + return; + } + + + void SetProgressState(__in HRESULT hrStatus) { + TBPFLAG flag = TBPF_NORMAL; + + if (IsCanceled() || HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT) == hrStatus) { + flag = TBPF_PAUSED; + } else if (IsRollingBack() || FAILED(hrStatus)) { + flag = TBPF_ERROR; + } + + SetTaskbarButtonState(flag); + } + + + HRESULT LoadBootstrapperBAFunctions() { + HRESULT hr = S_OK; + LPWSTR sczBafPath = nullptr; + + hr = PathRelativeToModule(&sczBafPath, L"bafunctions.dll", _hModule); + BalExitOnFailure(hr, "Failed to get path to BA function DLL."); + +#ifdef DEBUG + BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "PYBA: LoadBootstrapperBAFunctions() - BA function DLL %ls", sczBafPath); +#endif + + _hBAFModule = ::LoadLibraryW(sczBafPath); + if (_hBAFModule) { + auto pfnBAFunctionCreate = reinterpret_cast(::GetProcAddress(_hBAFModule, "CreateBootstrapperBAFunction")); + BalExitOnNullWithLastError1(pfnBAFunctionCreate, hr, "Failed to get CreateBootstrapperBAFunction entry-point from: %ls", sczBafPath); + + hr = pfnBAFunctionCreate(_engine, _hBAFModule, &_baFunction); + BalExitOnFailure(hr, "Failed to create BA function."); + } +#ifdef DEBUG + else { + BalLogError(HRESULT_FROM_WIN32(::GetLastError()), "PYBA: LoadBootstrapperBAFunctions() - Failed to load DLL %ls", sczBafPath); + } +#endif + + LExit: + if (_hBAFModule && !_baFunction) { + ::FreeLibrary(_hBAFModule); + _hBAFModule = nullptr; + } + ReleaseStr(sczBafPath); + + return hr; + } + + BOOL IsCheckable(THEME_CONTROL* pControl) { + if (!pControl->sczName || !pControl->sczName[0]) { + return FALSE; + } + + if (pControl->type == THEME_CONTROL_TYPE_CHECKBOX) { + return TRUE; + } + + if (pControl->type == THEME_CONTROL_TYPE_BUTTON) { + if ((pControl->dwStyle & BS_TYPEMASK) == BS_AUTORADIOBUTTON) { + return TRUE; + } + } + + return FALSE; + } + + void SavePageSettings() { + DWORD pageId = 0; + THEME_PAGE* pPage = nullptr; + + DeterminePageId(_state, &pageId); + pPage = ThemeGetPage(_theme, pageId); + if (!pPage) { + return; + } + + for (DWORD i = 0; i < pPage->cControlIndices; ++i) { + // Loop through all the checkable controls and set a Burn variable + // with that name to true or false. + THEME_CONTROL* pControl = _theme->rgControls + pPage->rgdwControlIndices[i]; + if (IsCheckable(pControl) && ThemeControlEnabled(_theme, pControl->wId)) { + BOOL checked = ThemeIsControlChecked(_theme, pControl->wId); + _engine->SetVariableNumeric(pControl->sczName, checked ? 1 : 0); + } + + // Loop through all the editbox controls with names and set a + // Burn variable with that name to the contents. + if (THEME_CONTROL_TYPE_EDITBOX == pControl->type && pControl->sczName && *pControl->sczName) { + LPWSTR sczValue = nullptr; + ThemeGetTextControl(_theme, pControl->wId, &sczValue); + _engine->SetVariableString(pControl->sczName, sczValue); + } + } + } + + +public: + // + // Constructor - initialize member variables. + // + PythonBootstrapperApplication( + __in HMODULE hModule, + __in BOOL fPrereq, + __in HRESULT hrHostInitialization, + __in IBootstrapperEngine* pEngine, + __in const BOOTSTRAPPER_COMMAND* pCommand + ) : CBalBaseBootstrapperApplication(pEngine, pCommand, 3, 3000) { + _hModule = hModule; + memcpy_s(&_command, sizeof(_command), pCommand, sizeof(BOOTSTRAPPER_COMMAND)); + + LONGLONG llInstalled = 0; + HRESULT hr = BalGetNumericVariable(L"WixBundleInstalled", &llInstalled); + if (SUCCEEDED(hr) && BOOTSTRAPPER_RESUME_TYPE_REBOOT != _command.resumeType && 0 < llInstalled && BOOTSTRAPPER_ACTION_INSTALL == _command.action) { + _command.action = BOOTSTRAPPER_ACTION_MODIFY; + } else if (0 == llInstalled && (BOOTSTRAPPER_ACTION_MODIFY == _command.action || BOOTSTRAPPER_ACTION_REPAIR == _command.action)) { + _command.action = BOOTSTRAPPER_ACTION_INSTALL; + } + + _plannedAction = BOOTSTRAPPER_ACTION_UNKNOWN; + + + // When resuming from restart doing some install-like operation, try to find the package that forced the + // restart. We'll use this information during planning. + _nextPackageAfterRestart = nullptr; + + if (BOOTSTRAPPER_RESUME_TYPE_REBOOT == _command.resumeType && BOOTSTRAPPER_ACTION_UNINSTALL < _command.action) { + // Ensure the forced restart package variable is null when it is an empty string. + HRESULT hr = BalGetStringVariable(L"WixBundleForcedRestartPackage", &_nextPackageAfterRestart); + if (FAILED(hr) || !_nextPackageAfterRestart || !*_nextPackageAfterRestart) { + ReleaseNullStr(_nextPackageAfterRestart); + } + } + + _wixLoc = nullptr; + memset(&_bundle, 0, sizeof(_bundle)); + memset(&_conditions, 0, sizeof(_conditions)); + _confirmCloseMessage = nullptr; + _failedMessage = nullptr; + + _language = nullptr; + _theme = nullptr; + memset(_pageIds, 0, sizeof(_pageIds)); + _hUiThread = nullptr; + _registered = FALSE; + _hWnd = nullptr; + + _state = PYBA_STATE_INITIALIZING; + _visiblePageId = 0; + _installPage = PAGE_LOADING; + _hrFinal = hrHostInitialization; + + _downgrading = FALSE; + _restartResult = BOOTSTRAPPER_APPLY_RESTART_NONE; + _restartRequired = FALSE; + _allowRestart = FALSE; + + _suppressDowngradeFailure = FALSE; + _suppressRepair = FALSE; + _modifying = FALSE; + + _overridableVariables = nullptr; + _taskbarList = nullptr; + _taskbarButtonCreatedMessage = UINT_MAX; + _taskbarButtonOK = FALSE; + _showingInternalUIThisPackage = FALSE; + _triedToLaunchElevated = FALSE; + + _suppressPaint = FALSE; + + pEngine->AddRef(); + _engine = pEngine; + + _hBAFModule = nullptr; + _baFunction = nullptr; + } + + + // + // Destructor - release member variables. + // + ~PythonBootstrapperApplication() { + AssertSz(!::IsWindow(_hWnd), "Window should have been destroyed before destructor."); + AssertSz(!_theme, "Theme should have been released before destructor."); + + ReleaseObject(_taskbarList); + ReleaseDict(_overridableVariables); + ReleaseStr(_failedMessage); + ReleaseStr(_confirmCloseMessage); + BalConditionsUninitialize(&_conditions); + BalInfoUninitialize(&_bundle); + LocFree(_wixLoc); + + ReleaseStr(_language); + ReleaseStr(_nextPackageAfterRestart); + ReleaseNullObject(_engine); + + if (_hBAFModule) { + ::FreeLibrary(_hBAFModule); + _hBAFModule = nullptr; + } + } + +private: + HMODULE _hModule; + BOOTSTRAPPER_COMMAND _command; + IBootstrapperEngine* _engine; + BOOTSTRAPPER_ACTION _plannedAction; + + LPWSTR _nextPackageAfterRestart; + + WIX_LOCALIZATION* _wixLoc; + BAL_INFO_BUNDLE _bundle; + BAL_CONDITIONS _conditions; + LPWSTR _failedMessage; + LPWSTR _confirmCloseMessage; + + LPWSTR _language; + THEME* _theme; + DWORD _pageIds[countof(PAGE_NAMES)]; + HANDLE _hUiThread; + BOOL _registered; + HWND _hWnd; + + PYBA_STATE _state; + HRESULT _hrFinal; + DWORD _visiblePageId; + PAGE _installPage; + + BOOL _startedExecution; + DWORD _calculatedCacheProgress; + DWORD _calculatedExecuteProgress; + + BOOL _downgrading; + BOOTSTRAPPER_APPLY_RESTART _restartResult; + BOOL _restartRequired; + BOOL _allowRestart; + + BOOL _suppressDowngradeFailure; + BOOL _suppressRepair; + BOOL _modifying; + + STRINGDICT_HANDLE _overridableVariables; + + ITaskbarList3* _taskbarList; + UINT _taskbarButtonCreatedMessage; + BOOL _taskbarButtonOK; + BOOL _showingInternalUIThisPackage; + BOOL _triedToLaunchElevated; + + BOOL _suppressPaint; + + HMODULE _hBAFModule; + IBootstrapperBAFunction* _baFunction; +}; + +// +// CreateBootstrapperApplication - creates a new IBootstrapperApplication object. +// +HRESULT CreateBootstrapperApplication( + __in HMODULE hModule, + __in BOOL fPrereq, + __in HRESULT hrHostInitialization, + __in IBootstrapperEngine* pEngine, + __in const BOOTSTRAPPER_COMMAND* pCommand, + __out IBootstrapperApplication** ppApplication + ) { + HRESULT hr = S_OK; + + if (fPrereq) { + hr = E_INVALIDARG; + ExitWithLastError(hr, "Failed to create UI thread."); + } + + PythonBootstrapperApplication* pApplication = nullptr; + + pApplication = new PythonBootstrapperApplication(hModule, fPrereq, hrHostInitialization, pEngine, pCommand); + ExitOnNull(pApplication, hr, E_OUTOFMEMORY, "Failed to create new standard bootstrapper application object."); + + *ppApplication = pApplication; + pApplication = nullptr; + +LExit: + ReleaseObject(pApplication); + return hr; +} diff --git a/Tools/msi/bundle/bootstrap/pch.cpp b/Tools/msi/bundle/bootstrap/pch.cpp new file mode 100644 index 000000000000..1d9f38c57d63 --- /dev/null +++ b/Tools/msi/bundle/bootstrap/pch.cpp @@ -0,0 +1 @@ +#include "pch.h" diff --git a/Tools/msi/bundle/bootstrap/pch.h b/Tools/msi/bundle/bootstrap/pch.h new file mode 100644 index 000000000000..0956413d5c99 --- /dev/null +++ b/Tools/msi/bundle/bootstrap/pch.h @@ -0,0 +1,59 @@ +//------------------------------------------------------------------------------------------------- +// +// Copyright (c) 2004, Outercurve Foundation. +// This software is released under Microsoft Reciprocal License (MS-RL). +// The license and further copyright text can be found in the file +// LICENSE.TXT at the root directory of the distribution. +// +// +//

+// Precompiled header for standard bootstrapper application. +// +//------------------------------------------------------------------------------------------------- + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dutil.h" +#include "memutil.h" +#include "dictutil.h" +#include "dirutil.h" +#include "fileutil.h" +#include "locutil.h" +#include "logutil.h" +#include "pathutil.h" +#include "resrutil.h" +#include "shelutil.h" +#include "strutil.h" +#include "thmutil.h" +#include "uriutil.h" +#include "xmlutil.h" + +#include "IBootstrapperEngine.h" +#include "IBootstrapperApplication.h" + +#include "BalBaseBootstrapperApplication.h" +#include "balinfo.h" +#include "balcondition.h" + +HRESULT CreateBootstrapperApplication( + __in HMODULE hModule, + __in BOOL fPrereq, + __in HRESULT hrHostInitialization, + __in IBootstrapperEngine* pEngine, + __in const BOOTSTRAPPER_COMMAND* pCommand, + __out IBootstrapperApplication** ppApplication +); + +#include "IBootstrapperBAFunction.h" + diff --git a/Tools/msi/bundle/bootstrap/pythonba.cpp b/Tools/msi/bundle/bootstrap/pythonba.cpp new file mode 100644 index 000000000000..0ce45ad31d95 --- /dev/null +++ b/Tools/msi/bundle/bootstrap/pythonba.cpp @@ -0,0 +1,76 @@ +//------------------------------------------------------------------------------------------------- +// +// Copyright (c) 2004, Outercurve Foundation. +// This software is released under Microsoft Reciprocal License (MS-RL). +// The license and further copyright text can be found in the file +// LICENSE.TXT at the root directory of the distribution. +// +// +// +// Setup chainer/bootstrapper standard UI for WiX toolset. +// +//------------------------------------------------------------------------------------------------- + +#include "pch.h" + +static HINSTANCE vhInstance = NULL; + +extern "C" BOOL WINAPI DllMain( + IN HINSTANCE hInstance, + IN DWORD dwReason, + IN LPVOID /* pvReserved */ + ) +{ + switch(dwReason) + { + case DLL_PROCESS_ATTACH: + ::DisableThreadLibraryCalls(hInstance); + vhInstance = hInstance; + break; + + case DLL_PROCESS_DETACH: + vhInstance = NULL; + break; + } + + return TRUE; +} + + +extern "C" HRESULT WINAPI BootstrapperApplicationCreate( + __in IBootstrapperEngine* pEngine, + __in const BOOTSTRAPPER_COMMAND* pCommand, + __out IBootstrapperApplication** ppApplication + ) +{ + HRESULT hr = S_OK; + + BalInitialize(pEngine); + + hr = CreateBootstrapperApplication(vhInstance, FALSE, S_OK, pEngine, pCommand, ppApplication); + BalExitOnFailure(hr, "Failed to create bootstrapper application interface."); + +LExit: + return hr; +} + + +extern "C" void WINAPI BootstrapperApplicationDestroy() +{ + BalUninitialize(); +} + + +extern "C" HRESULT WINAPI MbaPrereqBootstrapperApplicationCreate( + __in HRESULT hrHostInitialization, + __in IBootstrapperEngine* pEngine, + __in const BOOTSTRAPPER_COMMAND* pCommand, + __out IBootstrapperApplication** ppApplication + ) +{ + return E_NOTIMPL; +} + + +extern "C" void WINAPI MbaPrereqBootstrapperApplicationDestroy() +{ } diff --git a/Tools/msi/bundle/bootstrap/pythonba.def b/Tools/msi/bundle/bootstrap/pythonba.def new file mode 100644 index 000000000000..29b3fa50dfa9 --- /dev/null +++ b/Tools/msi/bundle/bootstrap/pythonba.def @@ -0,0 +1,18 @@ +;------------------------------------------------------------------------------------------------- +; +; Copyright (c) 2004, Outercurve Foundation. +; This software is released under Microsoft Reciprocal License (MS-RL). +; The license and further copyright text can be found in the file +; LICENSE.TXT at the root directory of the distribution. +; +; +; +; WiX Standard Bootstrapper Application DLL entry points. +; +;------------------------------------------------------------------------------------------------- + +EXPORTS + BootstrapperApplicationCreate + BootstrapperApplicationDestroy + MbaPrereqBootstrapperApplicationCreate + MbaPrereqBootstrapperApplicationDestroy diff --git a/Tools/msi/bundle/bootstrap/pythonba.sln b/Tools/msi/bundle/bootstrap/pythonba.sln new file mode 100644 index 000000000000..bf43fed9018e --- /dev/null +++ b/Tools/msi/bundle/bootstrap/pythonba.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.30501.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythonba", "pythonba.vcxproj", "{7A09B132-B3EE-499B-A700-A4B2157FEA3D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7A09B132-B3EE-499B-A700-A4B2157FEA3D}.Debug|Win32.ActiveCfg = Debug|Win32 + {7A09B132-B3EE-499B-A700-A4B2157FEA3D}.Debug|Win32.Build.0 = Debug|Win32 + {7A09B132-B3EE-499B-A700-A4B2157FEA3D}.Release|Win32.ActiveCfg = Release|Win32 + {7A09B132-B3EE-499B-A700-A4B2157FEA3D}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Tools/msi/bundle/bootstrap/pythonba.vcxproj b/Tools/msi/bundle/bootstrap/pythonba.vcxproj new file mode 100644 index 000000000000..5d8337c13494 --- /dev/null +++ b/Tools/msi/bundle/bootstrap/pythonba.vcxproj @@ -0,0 +1,69 @@ + + + + + + Debug + Win32 + + + Release + Win32 + + + + Release + Win32 + v140 + v120 + {7A09B132-B3EE-499B-A700-A4B2157FEA3D} + PythonBA + + + + + DynamicLibrary + Unicode + $(ProjectDir)..\..\obj\$(Configuration)_Bootstrap\ + $(IntDir) + + + + + _CRT_STDIO_LEGACY_WIDE_SPECIFIERS=1;%(PreprocessorDefinitions) + $(WixInstallPath)sdk\inc + Use + pch.h + MultiThreaded + + + comctl32.lib;gdiplus.lib;msimg32.lib;shlwapi.lib;wininet.lib;dutil.lib;balutil.lib;version.lib;uxtheme.lib;%(AdditionalDependencies) + $(WixInstallPath)sdk\vs2015\lib\x86 + $(WixInstallPath)sdk\vs2013\lib\x86 + pythonba.def + true + + + + + + + Create + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/bundle/bootstrap/resource.h b/Tools/msi/bundle/bootstrap/resource.h new file mode 100644 index 000000000000..53c03c319f09 --- /dev/null +++ b/Tools/msi/bundle/bootstrap/resource.h @@ -0,0 +1,25 @@ +//------------------------------------------------------------------------------------------------- +// +// Copyright (c) 2004, Outercurve Foundation. +// This software is released under Microsoft Reciprocal License (MS-RL). +// The license and further copyright text can be found in the file +// LICENSE.TXT at the root directory of the distribution. +// +//------------------------------------------------------------------------------------------------- + +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// +#define IDC_STATIC -1 + + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1003 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Tools/msi/bundle/bundle.ico b/Tools/msi/bundle/bundle.ico new file mode 100644 index 000000000000..1ab629eff269 Binary files /dev/null and b/Tools/msi/bundle/bundle.ico differ diff --git a/Tools/msi/bundle/bundle.targets b/Tools/msi/bundle/bundle.targets new file mode 100644 index 000000000000..7697af726bde --- /dev/null +++ b/Tools/msi/bundle/bundle.targets @@ -0,0 +1,99 @@ + + + + 2.0 + Bundle + + Release + 1132;1135;1140 + $(OutputName)-$(PythonVersion) + $(OutputName)-$(MajorVersionNumber).$(MinorVersionNumber).$(MicroVersionNumber).$(RevisionNumber) + $(OutputName)-amd64 + $(OutputName)-$(OutputSuffix) + + $(OutputPath)en-us\ + $(OutputPath) + + $(DownloadUrlBase.TrimEnd(`/`))/$(MajorVersionNumber).$(MinorVersionNumber).$(MicroVersionNumber)/$(ArchName)$(ReleaseLevelName)/ + $(DefineConstants);DownloadUrl=$(DownloadUrl){2} + $(DefineConstants);DownloadUrl={2} + + + + + WixUtilExtension + WixUtilExtension + + + WixDependencyExtension + WixDependencyExtension + + + WixBalExtension + WixBalExtension + + + + + + + + + + + + + + + + + + + + + + + BuildForRelease=$(BuildForRelease) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $(DefineConstants);BootstrapApp=$(BootstrapAppPath) + + + + + \ No newline at end of file diff --git a/Tools/msi/bundle/bundle.wxs b/Tools/msi/bundle/bundle.wxs new file mode 100644 index 000000000000..4892ebb8387b --- /dev/null +++ b/Tools/msi/bundle/bundle.wxs @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/msi/bundle/full.wixproj b/Tools/msi/bundle/full.wixproj new file mode 100644 index 000000000000..bdbdd8e175c0 --- /dev/null +++ b/Tools/msi/bundle/full.wixproj @@ -0,0 +1,21 @@ + + + + {3E204ADD-238D-4D10-852C-4F859325C839} + python + full + + + + + + + $(DefineConstants); + CompressMSI=yes; + CompressPDB=yes; + CompressMSI_D=yes; + + + + + \ No newline at end of file diff --git a/Tools/msi/bundle/packagegroups/core.wxs b/Tools/msi/bundle/packagegroups/core.wxs new file mode 100644 index 000000000000..9df6b7919422 --- /dev/null +++ b/Tools/msi/bundle/packagegroups/core.wxs @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/bundle/packagegroups/crt.wxs b/Tools/msi/bundle/packagegroups/crt.wxs new file mode 100644 index 000000000000..e19b4f9c4058 --- /dev/null +++ b/Tools/msi/bundle/packagegroups/crt.wxs @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/bundle/packagegroups/dev.wxs b/Tools/msi/bundle/packagegroups/dev.wxs new file mode 100644 index 000000000000..f2ea29b611a3 --- /dev/null +++ b/Tools/msi/bundle/packagegroups/dev.wxs @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/bundle/packagegroups/doc.wxs b/Tools/msi/bundle/packagegroups/doc.wxs new file mode 100644 index 000000000000..24b9ff18837f --- /dev/null +++ b/Tools/msi/bundle/packagegroups/doc.wxs @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/bundle/packagegroups/exe.wxs b/Tools/msi/bundle/packagegroups/exe.wxs new file mode 100644 index 000000000000..046b90ec2c60 --- /dev/null +++ b/Tools/msi/bundle/packagegroups/exe.wxs @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/bundle/packagegroups/launcher.wxs b/Tools/msi/bundle/packagegroups/launcher.wxs new file mode 100644 index 000000000000..d09175f7dc2b --- /dev/null +++ b/Tools/msi/bundle/packagegroups/launcher.wxs @@ -0,0 +1,23 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/bundle/packagegroups/lib.wxs b/Tools/msi/bundle/packagegroups/lib.wxs new file mode 100644 index 000000000000..47a97f16d0f7 --- /dev/null +++ b/Tools/msi/bundle/packagegroups/lib.wxs @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/bundle/packagegroups/postinstall.wxs b/Tools/msi/bundle/packagegroups/postinstall.wxs new file mode 100644 index 000000000000..b20cc501b767 --- /dev/null +++ b/Tools/msi/bundle/packagegroups/postinstall.wxs @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/bundle/packagegroups/tcltk.wxs b/Tools/msi/bundle/packagegroups/tcltk.wxs new file mode 100644 index 000000000000..e0e3958d560a --- /dev/null +++ b/Tools/msi/bundle/packagegroups/tcltk.wxs @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/bundle/packagegroups/test.wxs b/Tools/msi/bundle/packagegroups/test.wxs new file mode 100644 index 000000000000..b64e8ff94292 --- /dev/null +++ b/Tools/msi/bundle/packagegroups/test.wxs @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/bundle/packagegroups/tools.wxs b/Tools/msi/bundle/packagegroups/tools.wxs new file mode 100644 index 000000000000..06af5b588f6d --- /dev/null +++ b/Tools/msi/bundle/packagegroups/tools.wxs @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/bundle/postinstall_en-US.wxl_template b/Tools/msi/bundle/postinstall_en-US.wxl_template new file mode 100644 index 000000000000..5f54aefb3dd7 --- /dev/null +++ b/Tools/msi/bundle/postinstall_en-US.wxl_template @@ -0,0 +1,4 @@ + + + Precompiling standard library + diff --git a/Tools/msi/bundle/releaselocal.wixproj b/Tools/msi/bundle/releaselocal.wixproj new file mode 100644 index 000000000000..0c3dee7ad81e --- /dev/null +++ b/Tools/msi/bundle/releaselocal.wixproj @@ -0,0 +1,21 @@ + + + + {FCD43AC9-969F-49A1-8AC5-EDC27599D1EB} + python + + + + + + + + $(DefineConstants); + CompressMSI=yes; + CompressPDB=no; + CompressMSI_D=no + + + + + \ No newline at end of file diff --git a/Tools/msi/bundle/releaseweb.wixproj b/Tools/msi/bundle/releaseweb.wixproj new file mode 100644 index 000000000000..350c735878c0 --- /dev/null +++ b/Tools/msi/bundle/releaseweb.wixproj @@ -0,0 +1,21 @@ + + + + {71CDE213-CB39-4BD9-B89D-BBB878689144} + python + webinstall + + + + + + + $(DefineConstants); + CompressMSI=no; + CompressPDB=no; + CompressMSI_D=no + + + + + \ No newline at end of file diff --git a/Tools/msi/bundle/snapshot.wixproj b/Tools/msi/bundle/snapshot.wixproj new file mode 100644 index 000000000000..8fe95a8d6923 --- /dev/null +++ b/Tools/msi/bundle/snapshot.wixproj @@ -0,0 +1,21 @@ + + + + {8A4A1162-4BF9-4FF6-9A98-315F01E44932} + python + + + + + + + + $(DefineConstants); + CompressMSI=no; + CompressPDB=no; + CompressMSI_D=no; + + + + + \ No newline at end of file diff --git a/Tools/msi/common.wxs b/Tools/msi/common.wxs new file mode 100644 index 000000000000..2e50c1202343 --- /dev/null +++ b/Tools/msi/common.wxs @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + Installed OR NOT DOWNGRADE + Installed OR NOT MISSING_CORE + Installed OR TARGETDIR OR Suppress_TARGETDIR_Check + + + UPGRADE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/msi/common_en-US.wxl_template b/Tools/msi/common_en-US.wxl_template new file mode 100644 index 000000000000..8d0352688207 --- /dev/null +++ b/Tools/msi/common_en-US.wxl_template @@ -0,0 +1,17 @@ + + + 1033 + en-us + Python {{ShortVersion}} + Python {{LongVersion}} ({{Bitness}}) + Python {{LongVersion}} !(loc.Descriptor) ({{Bitness}}) + Python {{LongVersion}} !(loc.Descriptor) ({{Bitness}}) + Python {{LongVersion}} !(loc.Descriptor) ({{Bitness}} symbols) + Python {{LongVersion}} !(loc.Descriptor) ({{Bitness}} symbols) + Python {{LongVersion}} !(loc.Descriptor) ({{Bitness}} debug) + Python {{LongVersion}} !(loc.Descriptor) ({{Bitness}} debug) + Python Software Foundation + A newer version of !(loc.ProductName) is already installed. + An incorrect version of a prerequisite package is installed. Please uninstall any other versions of !(loc.ProductName) and try installing this again. + The TARGETDIR variable must be provided when invoking this installer. + diff --git a/Tools/msi/core/core.wixproj b/Tools/msi/core/core.wixproj new file mode 100644 index 000000000000..68e8bab3109d --- /dev/null +++ b/Tools/msi/core/core.wixproj @@ -0,0 +1,19 @@ + + + + {1B4502D5-B627-4F50-ABEA-4CC5A8E88265} + 2.0 + core + Package + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/core/core.wxs b/Tools/msi/core/core.wxs new file mode 100644 index 000000000000..0d4fbde9787c --- /dev/null +++ b/Tools/msi/core/core.wxs @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/Tools/msi/core/core_d.wixproj b/Tools/msi/core/core_d.wixproj new file mode 100644 index 000000000000..5b296bf35f95 --- /dev/null +++ b/Tools/msi/core/core_d.wixproj @@ -0,0 +1,19 @@ + + + + {D3677DCF-098A-4398-9FA5-8E74AC37E0DF} + 2.0 + core_d + Package + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/core/core_d.wxs b/Tools/msi/core/core_d.wxs new file mode 100644 index 000000000000..8422117db99b --- /dev/null +++ b/Tools/msi/core/core_d.wxs @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/Tools/msi/core/core_en-US.wxl b/Tools/msi/core/core_en-US.wxl new file mode 100644 index 000000000000..7977470d7c1c --- /dev/null +++ b/Tools/msi/core/core_en-US.wxl @@ -0,0 +1,5 @@ + + + Core Interpreter + core + diff --git a/Tools/msi/core/core_files.wxs b/Tools/msi/core/core_files.wxs new file mode 100644 index 000000000000..145e1471247a --- /dev/null +++ b/Tools/msi/core/core_files.wxs @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/msi/core/core_pdb.wixproj b/Tools/msi/core/core_pdb.wixproj new file mode 100644 index 000000000000..9c8838970b6f --- /dev/null +++ b/Tools/msi/core/core_pdb.wixproj @@ -0,0 +1,19 @@ + + + + {E98E7539-64E7-4DCE-AACD-01E3ADE40EFD} + 2.0 + core_pdb + Package + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/core/core_pdb.wxs b/Tools/msi/core/core_pdb.wxs new file mode 100644 index 000000000000..c9a558d2c79d --- /dev/null +++ b/Tools/msi/core/core_pdb.wxs @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/Tools/msi/crt/crt.wixproj b/Tools/msi/crt/crt.wixproj new file mode 100644 index 000000000000..8389b3a09f36 --- /dev/null +++ b/Tools/msi/crt/crt.wixproj @@ -0,0 +1,20 @@ + + + + {91C99298-8E2E-4422-A5AF-CC4FFF9A58D3} + 2.0 + crt + Package + ICE71 + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/crt/crt.wxs b/Tools/msi/crt/crt.wxs new file mode 100644 index 000000000000..5b100956affa --- /dev/null +++ b/Tools/msi/crt/crt.wxs @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/msi/crt/crt_en-US.wxl b/Tools/msi/crt/crt_en-US.wxl new file mode 100644 index 000000000000..cee3c8acf57a --- /dev/null +++ b/Tools/msi/crt/crt_en-US.wxl @@ -0,0 +1,5 @@ + + + C Runtime + crt + diff --git a/Tools/msi/crt/crt_files.12.0.wxs b/Tools/msi/crt/crt_files.12.0.wxs new file mode 100644 index 000000000000..f62593faf4a9 --- /dev/null +++ b/Tools/msi/crt/crt_files.12.0.wxs @@ -0,0 +1,20 @@ + + + + + + + + + + + ALLUSERS=1 + + + + NOT ALLUSERS=1 + + + + + diff --git a/Tools/msi/crt/crt_files.14.0.wxs b/Tools/msi/crt/crt_files.14.0.wxs new file mode 100644 index 000000000000..be682c937bde --- /dev/null +++ b/Tools/msi/crt/crt_files.14.0.wxs @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + ALLUSERS=1 + + + + ALLUSERS=1 + + + + ALLUSERS=1 + + + + NOT ALLUSERS=1 + + + + NOT ALLUSERS=1 + + + + NOT ALLUSERS=1 + + + + + diff --git a/Tools/msi/crt/crtlicense.txt b/Tools/msi/crt/crtlicense.txt new file mode 100644 index 000000000000..1f0f1f9eff3f --- /dev/null +++ b/Tools/msi/crt/crtlicense.txt @@ -0,0 +1,47 @@ + + +Additional Conditions for this Windows binary build +--------------------------------------------------- + +This program is linked with and uses Microsoft Distributable Code, +copyrighted by Microsoft Corporation. The Microsoft Distributable Code +includes the following files: + +appcrt140.dll +desktopcrt140.dll +vcruntime140.dll +msvcp140.dll +concrt140.dll +vccorlib140.dll + +If you further distribute programs that include the Microsoft +Distributable Code, you must comply with the restrictions on +distribution specified by Microsoft. In particular, you must require +distributors and external end users to agree to terms that protect the +Microsoft Distributable Code at least as much as Microsoft's own +requirements for the Distributable Code. See Microsoft's documentation +(included in its developer tools and on its website at microsoft.com) +for specific details. + +Redistribution of the Windows binary build of the Python interpreter +complies with this agreement, provided that you do not: + +- alter any copyright, trademark or patent notice in Microsoft's +Distributable Code; + +- use Microsoft's trademarks in your programs' names or in a way that +suggests your programs come from or are endorsed by Microsoft; + +- distribute Microsoft's Distributable Code to run on a platform other +than Microsoft operating systems, run-time technologies or application +platforms; or + +- include Microsoft Distributable Code in malicious, deceptive or +unlawful programs. + +These restrictions apply only to the Microsoft Distributable Code as +defined above, not to Python itself or any programs running on the +Python interpreter. The redistribution of the Python interpreter and +libraries is governed by the Python Software License included with this +file, or by other licenses as marked. + diff --git a/Tools/msi/csv_to_wxs.py b/Tools/msi/csv_to_wxs.py new file mode 100644 index 000000000000..235c8f8b0be5 --- /dev/null +++ b/Tools/msi/csv_to_wxs.py @@ -0,0 +1,127 @@ +''' +Processes a CSV file containing a list of files into a WXS file with +components for each listed file. + +The CSV columns are: + source of file, target for file, group name + +Usage:: + py txt_to_wxs.py [path to file list .csv] [path to destination .wxs] + +This is necessary to handle structures where some directories only +contain other directories. MSBuild is not able to generate the +Directory entries in the WXS file correctly, as it operates on files. +Python, however, can easily fill in the gap. +''' + +__author__ = "Steve Dower " + +import csv +import re +import sys + +from collections import defaultdict +from itertools import chain, zip_longest +from pathlib import PureWindowsPath +from uuid import uuid1 + +ID_CHAR_SUBS = { + '-': '_', + '+': '_P', +} + +def make_id(path): + return re.sub( + r'[^A-Za-z0-9_.]', + lambda m: ID_CHAR_SUBS.get(m.group(0), '_'), + str(path).rstrip('/\\'), + flags=re.I + ) + +DIRECTORIES = set() + +def main(file_source, install_target): + with open(file_source, 'r', newline='') as f: + files = list(csv.reader(f)) + + assert len(files) == len(set(make_id(f[1]) for f in files)), "Duplicate file IDs exist" + + directories = defaultdict(set) + cache_directories = defaultdict(set) + groups = defaultdict(list) + for source, target, group, disk_id, condition in files: + target = PureWindowsPath(target) + groups[group].append((source, target, disk_id, condition)) + + if target.suffix.lower() in {".py", ".pyw"}: + cache_directories[group].add(target.parent) + + for dirname in target.parents: + parent = make_id(dirname.parent) + if parent and parent != '.': + directories[parent].add(dirname.name) + + lines = [ + '', + ' ', + ] + for dir_parent in sorted(directories): + lines.append(' '.format(dir_parent)) + for dir_name in sorted(directories[dir_parent]): + lines.append(' '.format(dir_parent, make_id(dir_name), dir_name)) + lines.append(' ') + for dir_parent in (make_id(d) for group in cache_directories.values() for d in group): + lines.append(' '.format(dir_parent)) + lines.append(' '.format(dir_parent)) + lines.append(' ') + lines.append(' ') + + for group in sorted(groups): + lines.extend([ + ' ', + ' '.format(group), + ]) + for source, target, disk_id, condition in groups[group]: + lines.append(' '.format(make_id(target), make_id(target.parent))) + if condition: + lines.append(' {}'.format(condition)) + + if disk_id: + lines.append(' '.format(make_id(target), target.name, source, disk_id)) + else: + lines.append(' '.format(make_id(target), target.name, source)) + lines.append(' ') + + create_folders = {make_id(p) + "___pycache__" for p in cache_directories[group]} + remove_folders = {make_id(p2) for p1 in cache_directories[group] for p2 in chain((p1,), p1.parents)} + create_folders.discard(".") + remove_folders.discard(".") + if create_folders or remove_folders: + lines.append(' '.format(group, uuid1())) + lines.extend(' '.format(p) for p in create_folders) + lines.extend(' '.format(p) for p in create_folders) + lines.extend(' '.format(p) for p in create_folders | remove_folders) + lines.append(' ') + + lines.extend([ + ' ', + ' ', + ]) + lines.append('') + + # Check if the file matches. If so, we don't want to touch it so + # that we can skip rebuilding. + try: + with open(install_target, 'r') as f: + if all(x.rstrip('\r\n') == y for x, y in zip_longest(f, lines)): + print('File is up to date') + return + except IOError: + pass + + with open(install_target, 'w') as f: + f.writelines(line + '\n' for line in lines) + print('Wrote {} lines to {}'.format(len(lines), install_target)) + +if __name__ == '__main__': + main(sys.argv[1], sys.argv[2]) diff --git a/Tools/msi/dev/dev.wixproj b/Tools/msi/dev/dev.wixproj new file mode 100644 index 000000000000..e144878a53ca --- /dev/null +++ b/Tools/msi/dev/dev.wixproj @@ -0,0 +1,49 @@ + + + + {5F23F608-D74B-4259-A0CE-8DC65CC7FE53} + 2.0 + dev + Package + + + + + $(DefineConstants); + IncludeMinGWLib=1; + + + + + + + + + + + + $(PySourcePath) + !(bindpath.src) + $(PySourcePath) + + dev_include + + + + + + + <_GenDefPlatform>i386 + <_GenDefPlatform Condition="$(Platform) == 'x64'">i386:x86-64 + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/dev/dev.wxs b/Tools/msi/dev/dev.wxs new file mode 100644 index 000000000000..f8af9aab5cbe --- /dev/null +++ b/Tools/msi/dev/dev.wxs @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/Tools/msi/dev/dev_d.wixproj b/Tools/msi/dev/dev_d.wixproj new file mode 100644 index 000000000000..b3b05326d419 --- /dev/null +++ b/Tools/msi/dev/dev_d.wixproj @@ -0,0 +1,19 @@ + + + + {C11B4945-76BD-4137-B2E3-649460117A77} + 2.0 + dev_d + Package + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/dev/dev_d.wxs b/Tools/msi/dev/dev_d.wxs new file mode 100644 index 000000000000..c3cb2ea89fa7 --- /dev/null +++ b/Tools/msi/dev/dev_d.wxs @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/Tools/msi/dev/dev_en-US.wxl b/Tools/msi/dev/dev_en-US.wxl new file mode 100644 index 000000000000..2546e13e47a0 --- /dev/null +++ b/Tools/msi/dev/dev_en-US.wxl @@ -0,0 +1,5 @@ + + + Development Libraries + dev + diff --git a/Tools/msi/dev/dev_files.wxs b/Tools/msi/dev/dev_files.wxs new file mode 100644 index 000000000000..9654d2e3e600 --- /dev/null +++ b/Tools/msi/dev/dev_files.wxs @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/msi/doc/doc.wixproj b/Tools/msi/doc/doc.wixproj new file mode 100644 index 000000000000..ea9929acd05f --- /dev/null +++ b/Tools/msi/doc/doc.wixproj @@ -0,0 +1,30 @@ + + + + {0D62A2BB-5F71-4447-8C8C-9708407B3674} + 2.0 + doc + Package + + ICE43 + + + + python$(MajorVersionNumber)$(MinorVersionNumber)$(MicroVersionNumber)$(ReleaseLevelName).chm + false + true + + + $(DefineConstants);DocFilename=$(DocFilename); + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/doc/doc.wxs b/Tools/msi/doc/doc.wxs new file mode 100644 index 000000000000..ddab83b5ea5a --- /dev/null +++ b/Tools/msi/doc/doc.wxs @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/msi/doc/doc_en-US.wxl_template b/Tools/msi/doc/doc_en-US.wxl_template new file mode 100644 index 000000000000..09df5829ef58 --- /dev/null +++ b/Tools/msi/doc/doc_en-US.wxl_template @@ -0,0 +1,7 @@ + + + doc + Documentation + Python {{ShortVersion}} {{Bitness}} Manuals + View the !(loc.ProductName) documentation. + diff --git a/Tools/msi/doc/doc_files.wxs b/Tools/msi/doc/doc_files.wxs new file mode 100644 index 000000000000..b2aabfb8ce55 --- /dev/null +++ b/Tools/msi/doc/doc_files.wxs @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/Tools/msi/doc/doc_no_files.wxs b/Tools/msi/doc/doc_no_files.wxs new file mode 100644 index 000000000000..7ab7c2690689 --- /dev/null +++ b/Tools/msi/doc/doc_no_files.wxs @@ -0,0 +1,17 @@ + + + + + + + + + + + + diff --git a/Tools/msi/crtlicense.txt b/Tools/msi/exe/crtlicense.txt similarity index 100% rename from Tools/msi/crtlicense.txt rename to Tools/msi/exe/crtlicense.txt diff --git a/Tools/msi/exe/exe.wixproj b/Tools/msi/exe/exe.wixproj new file mode 100644 index 000000000000..d26a603268b4 --- /dev/null +++ b/Tools/msi/exe/exe.wixproj @@ -0,0 +1,43 @@ + + + + {6BD53305-B03E-49DC-85FB-5551B8CCC843} + 2.0 + exe + Package + + + + ICE43 + + + + + + + + + + + + + + + <_LicenseFiles Include="@(LicenseFiles)"> + $([System.IO.File]::ReadAllText(%(FullPath))) + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/exe/exe.wxs b/Tools/msi/exe/exe.wxs new file mode 100644 index 000000000000..9696c899410a --- /dev/null +++ b/Tools/msi/exe/exe.wxs @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/msi/exe/exe_d.wixproj b/Tools/msi/exe/exe_d.wixproj new file mode 100644 index 000000000000..27545caf7d16 --- /dev/null +++ b/Tools/msi/exe/exe_d.wixproj @@ -0,0 +1,20 @@ + + + + {B1CA739C-8DB0-403B-9010-D79507507CE9} + 2.0 + exe_d + Package + + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/exe/exe_d.wxs b/Tools/msi/exe/exe_d.wxs new file mode 100644 index 000000000000..abcb0126612b --- /dev/null +++ b/Tools/msi/exe/exe_d.wxs @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/Tools/msi/exe/exe_en-US.wxl_template b/Tools/msi/exe/exe_en-US.wxl_template new file mode 100644 index 000000000000..577fbe51a52a --- /dev/null +++ b/Tools/msi/exe/exe_en-US.wxl_template @@ -0,0 +1,7 @@ + + + Executables + executable + Python {{ShortVersion}} ({{Bitness}}) + Launches the !(loc.ProductName) interpreter. + diff --git a/Tools/msi/exe/exe_files.wxs b/Tools/msi/exe/exe_files.wxs new file mode 100644 index 000000000000..409139829735 --- /dev/null +++ b/Tools/msi/exe/exe_files.wxs @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/msi/exe/exe_pdb.wixproj b/Tools/msi/exe/exe_pdb.wixproj new file mode 100644 index 000000000000..4f4c86992606 --- /dev/null +++ b/Tools/msi/exe/exe_pdb.wixproj @@ -0,0 +1,20 @@ + + + + {4A1F7045-8EE2-4276-ABB8-5E0C40E5F38B} + 2.0 + exe_pdb + Package + + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/exe/exe_pdb.wxs b/Tools/msi/exe/exe_pdb.wxs new file mode 100644 index 000000000000..5129ec00b16a --- /dev/null +++ b/Tools/msi/exe/exe_pdb.wxs @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/Tools/msi/get_wix.py b/Tools/msi/get_wix.py new file mode 100644 index 000000000000..da36a2e54a17 --- /dev/null +++ b/Tools/msi/get_wix.py @@ -0,0 +1,49 @@ +''' +Downloads and extracts WiX to a local directory +''' + +__author__ = 'Steve Dower ' + +import io +import os +import sys + +from pathlib import Path +from subprocess import Popen +from zipfile import ZipFile + +EXTERNALS_DIR = None +for p in Path(__file__).parents: + if any(p.glob("PCBuild/*.vcxproj")): + EXTERNALS_DIR = p / "externals" + break + +if not EXTERNALS_DIR: + print("Cannot find project root") + sys.exit(1) + +WIX_BINARIES_ZIP = 'http://wixtoolset.org/downloads/v3.10.0.1403/wix310-binaries.zip' +TARGET_BIN_ZIP = EXTERNALS_DIR / "wix.zip" +TARGET_BIN_DIR = EXTERNALS_DIR / "wix" + +POWERSHELL_COMMAND = "[IO.File]::WriteAllBytes('{}', (Invoke-WebRequest {} -UseBasicParsing).Content)" + +if __name__ == '__main__': + if TARGET_BIN_DIR.exists() and any(TARGET_BIN_DIR.glob("*")): + print('WiX is already installed') + sys.exit(0) + + try: + TARGET_BIN_DIR.mkdir() + except FileExistsError: + pass + + print('Downloading WiX to', TARGET_BIN_ZIP) + p = Popen(["powershell.exe", "-Command", POWERSHELL_COMMAND.format(TARGET_BIN_ZIP, WIX_BINARIES_ZIP)]) + p.wait() + print('Extracting WiX to', TARGET_BIN_DIR) + with ZipFile(str(TARGET_BIN_ZIP)) as z: + z.extractall(str(TARGET_BIN_DIR)) + TARGET_BIN_ZIP.unlink() + + print('Extracted WiX') diff --git a/Tools/msi/launcher/launcher.wixproj b/Tools/msi/launcher/launcher.wixproj new file mode 100644 index 000000000000..73f26a8e1979 --- /dev/null +++ b/Tools/msi/launcher/launcher.wixproj @@ -0,0 +1,20 @@ + + + + {921CF0E6-AEBC-4376-BA1D-CD46EBFE6DA5} + 2.0 + launcher + Package + + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/launcher/launcher.wxs b/Tools/msi/launcher/launcher.wxs new file mode 100644 index 000000000000..b20cff859d23 --- /dev/null +++ b/Tools/msi/launcher/launcher.wxs @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + NOT Installed AND NOT ALLUSERS=1 + NOT Installed AND ALLUSERS=1 + + + diff --git a/Tools/msi/launcher/launcher_en-US.wxl b/Tools/msi/launcher/launcher_en-US.wxl new file mode 100644 index 000000000000..a88f221cf0be --- /dev/null +++ b/Tools/msi/launcher/launcher_en-US.wxl @@ -0,0 +1,8 @@ + + + Launcher + launcher + Python File + Python File (no console) + Compiled Python File + diff --git a/Tools/msi/launcher/launcher_files.wxs b/Tools/msi/launcher/launcher_files.wxs new file mode 100644 index 000000000000..9606dc6dd2c5 --- /dev/null +++ b/Tools/msi/launcher/launcher_files.wxs @@ -0,0 +1,24 @@ + + + + + + + + + + + + + NOT ALLUSERS=1 + + + + + + ALLUSERS=1 + + + + + diff --git a/Tools/msi/launcher/launcher_reg.wxs b/Tools/msi/launcher/launcher_reg.wxs new file mode 100644 index 000000000000..aab3d11bf8f2 --- /dev/null +++ b/Tools/msi/launcher/launcher_reg.wxs @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/msi/lib/lib.wixproj b/Tools/msi/lib/lib.wixproj new file mode 100644 index 000000000000..64e58787b88e --- /dev/null +++ b/Tools/msi/lib/lib.wixproj @@ -0,0 +1,34 @@ + + + + {11367E76-3337-4602-8F1E-77DB4F370D7E} + 2.0 + lib + Package + + + + + + + + + + + + + $(PySourcePath)Lib + !(bindpath.src)Lib\ + $(PySourcePath)Lib + Lib\ + lib_py + + + + + \ No newline at end of file diff --git a/Tools/msi/lib/lib.wxs b/Tools/msi/lib/lib.wxs new file mode 100644 index 000000000000..b1aec75a7c77 --- /dev/null +++ b/Tools/msi/lib/lib.wxs @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/Tools/msi/lib/lib_d.wixproj b/Tools/msi/lib/lib_d.wixproj new file mode 100644 index 000000000000..587a82c1929d --- /dev/null +++ b/Tools/msi/lib/lib_d.wixproj @@ -0,0 +1,19 @@ + + + + {6C443CD3-8258-4335-BA03-49DA9C34CE4D} + 2.0 + lib_d + Package + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/lib/lib_d.wxs b/Tools/msi/lib/lib_d.wxs new file mode 100644 index 000000000000..5a5cf70c3fe6 --- /dev/null +++ b/Tools/msi/lib/lib_d.wxs @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/Tools/msi/lib/lib_en-US.wxl b/Tools/msi/lib/lib_en-US.wxl new file mode 100644 index 000000000000..305bcc73afc8 --- /dev/null +++ b/Tools/msi/lib/lib_en-US.wxl @@ -0,0 +1,5 @@ + + + Standard Library + lib + diff --git a/Tools/msi/lib/lib_files.wxs b/Tools/msi/lib/lib_files.wxs new file mode 100644 index 000000000000..fa79a8d692d3 --- /dev/null +++ b/Tools/msi/lib/lib_files.wxs @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + SYMBOLS=1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/msi/lib/lib_pdb.wixproj b/Tools/msi/lib/lib_pdb.wixproj new file mode 100644 index 000000000000..db1b5bb316cf --- /dev/null +++ b/Tools/msi/lib/lib_pdb.wixproj @@ -0,0 +1,19 @@ + + + + {5E0BCE93-D1AC-4591-BBCB-3A2BE5A4B3D1} + 2.0 + lib_pdb + Package + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/lib/lib_pdb.wxs b/Tools/msi/lib/lib_pdb.wxs new file mode 100644 index 000000000000..a2be0c9c2ca8 --- /dev/null +++ b/Tools/msi/lib/lib_pdb.wxs @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/Tools/msi/msi.props b/Tools/msi/msi.props new file mode 100644 index 000000000000..16839cc25220 --- /dev/null +++ b/Tools/msi/msi.props @@ -0,0 +1,160 @@ + + + + false + false + $(SuppressIces);ICE03;ICE57;ICE61 + 1026 + false + true + Release + x86 + perUser + + $(ComputerName) + $(ReleaseUri)/ + + + + + + + + + + WixUtilExtension + WixUtilExtension + + + + + $(MSBuildThisFileDirectory)\obj\$(Configuration)_$(Platform)\$(OutputName) + $(IntermediateOutputPath)_$(OutputSuffix) + $(BuildPath) + $(OutputPath)\ + $(OutputPath) + true + $(CommonProgramFiles)\Merge Modules\Microsoft_VC120_CRT_$(Platform).msm + $(CommonProgramFiles)\Merge Modules\Microsoft_VC140_CRT_$(Platform).msm + $([System.IO.Path]::GetFullPath(`$(VS120COMNTOOLS)\..\..\VC\redist\$(Platform)\Microsoft.VC120.CRT`)) + $([System.IO.Path]::GetFullPath(`$(VS140COMNTOOLS)\..\..\VC\redist\$(Platform)\Microsoft.VC140.CRT`)) + + + $(ReleaseLevelNumber) + $([System.Math]::Floor($([System.DateTime]::Now.Subtract($([System.DateTime]::new(2001, 1, 1))).TotalDays))) + + + + 32-bit + 64-bit + + $(DefineConstants); + Version=$(MajorVersionNumber).$(MinorVersionNumber).$(MicroVersionNumber).$(RevisionNumber); + ShortVersion=$(MajorVersionNumber).$(MinorVersionNumber); + LongVersion=$(PythonVersion); + MajorVersionNumber=$(MajorVersionNumber); + MinorVersionNumber=$(MinorVersionNumber); + UpgradeMinimumVersion=$(MajorVersionNumber).$(MinorVersionNumber).0.0; + NextMajorVersionNumber=$(MajorVersionNumber).$([msbuild]::Add($(MinorVersionNumber), 1)).0.0; + PyDebugExt=$(PyDebugExt); + + + $(DefineConstants);CRTModule=$(CRTModule); + + + $(DefineConstants);CRTRedist=$(CRTRedist); + + + $(DefineConstants);TestPrefix=;FileExtension=py; + + + $(DefineConstants);TestPrefix=x;FileExtension=px; + + + $(DefineConstants);Suffix32=-32; + + + $(DefineConstants);Suffix32=; + + + + + + generated_filelist + + + + + false + + + + + + + + src + + + tcltk + + + crt + + + + + + + + + <_Uuid Include="CoreUpgradeCode"> + upgradecode + + <_Uuid Include="UpgradeCode"> + upgradecode/$(OutputName) + + <_Uuid Include="InstallDirectoryGuidSeed"> + installdirectoryseed + + <_Uuid Include="PythonExeComponentGuid"> + python.exe + + <_Uuid Include="PythonwExeComponentGuid"> + pythonw.exe + + <_Uuid Include="RemoveLib2to3PickleComponentGuid"> + lib2to3/pickles + + + + + <_Uuids>@(_Uuid->'("%(Identity)", "%(Uri)")',',') + <_GenerateCommand>import uuid; print('\n'.join('{}={}'.format(i, uuid.uuid5(uuid.UUID('c8d9733e-a70c-43ff-ab0c-e26456f11083'), '$(ReleaseUri)' + j)) for i,j in [$(_Uuids.Replace(`"`,`'`))])) + + + + + + + + + + $(DefineConstants);@(_UuidValue,';'); + + + \ No newline at end of file diff --git a/Tools/msi/msi.py b/Tools/msi/msi.py deleted file mode 100644 index 694875a682ec..000000000000 --- a/Tools/msi/msi.py +++ /dev/null @@ -1,1444 +0,0 @@ -# Python MSI Generator -# (C) 2003 Martin v. Loewis -# See "FOO" in comments refers to MSDN sections with the title FOO. -import msilib, schema, sequence, os, glob, time, re, shutil, zipfile -import subprocess, tempfile -from msilib import Feature, CAB, Directory, Dialog, Binary, add_data -import uisample -from win32com.client import constants -from distutils.spawn import find_executable - -# Settings can be overridden in config.py below -# 0 for official python.org releases -# 1 for intermediate releases by anybody, with -# a new product code for every package. -snapshot = 1 -# 1 means that file extension is px, not py, -# and binaries start with x -testpackage = 0 -# Location of build tree -srcdir = os.path.abspath("../..") -# Text to be displayed as the version in dialogs etc. -# goes into file name and ProductCode. Defaults to -# current_version.day for Snapshot, current_version otherwise -full_current_version = None -# Is Tcl available at all? -have_tcl = True -# path to PCbuild directory -PCBUILD="PCbuild" -# msvcrt version -MSVCR = "100" -# Name of certificate in default store to sign MSI with -certname = None -# Make a zip file containing the PDB files for this build? -pdbzip = True - -try: - from config import * -except ImportError: - pass - -# Extract current version from Include/patchlevel.h -lines = open(srcdir + "/Include/patchlevel.h").readlines() -major = minor = micro = level = serial = None -levels = { - 'PY_RELEASE_LEVEL_ALPHA':0xA, - 'PY_RELEASE_LEVEL_BETA': 0xB, - 'PY_RELEASE_LEVEL_GAMMA':0xC, - 'PY_RELEASE_LEVEL_FINAL':0xF - } -for l in lines: - if not l.startswith("#define"): - continue - l = l.split() - if len(l) != 3: - continue - _, name, value = l - if name == 'PY_MAJOR_VERSION': major = value - if name == 'PY_MINOR_VERSION': minor = value - if name == 'PY_MICRO_VERSION': micro = value - if name == 'PY_RELEASE_LEVEL': level = levels[value] - if name == 'PY_RELEASE_SERIAL': serial = value - -short_version = major+"."+minor -# See PC/make_versioninfo.c -FIELD3 = 1000*int(micro) + 10*level + int(serial) -current_version = "%s.%d" % (short_version, FIELD3) - -# This should never change. The UpgradeCode of this package can be -# used in the Upgrade table of future packages to make the future -# package replace this one. See "UpgradeCode Property". -# upgrade_code gets set to upgrade_code_64 when we have determined -# that the target is Win64. -upgrade_code_snapshot='{92A24481-3ECB-40FC-8836-04B7966EC0D5}' -upgrade_code='{65E6DE48-A358-434D-AA4F-4AF72DB4718F}' -upgrade_code_64='{6A965A0C-6EE6-4E3A-9983-3263F56311EC}' - -if snapshot: - current_version = "%s.%s.%s" % (major, minor, int(time.time()/3600/24)) - -if full_current_version is None: - full_current_version = current_version - -extensions = [ - 'pyexpat.pyd', - 'select.pyd', - 'unicodedata.pyd', - 'winsound.pyd', - '_bz2.pyd', - '_elementtree.pyd', - '_socket.pyd', - '_ssl.pyd', - '_testcapi.pyd', - '_tkinter.pyd', - '_msi.pyd', - '_ctypes.pyd', - '_ctypes_test.pyd', - '_sqlite3.pyd', - '_hashlib.pyd', - '_multiprocessing.pyd', - '_lzma.pyd', - '_decimal.pyd', - '_testbuffer.pyd', - '_sha3.pyd', - '_testimportmultiple.pyd', - '_overlapped.pyd', -] - -# Well-known component UUIDs -# These are needed for SharedDLLs reference counter; if -# a different UUID was used for each incarnation of, say, -# python24.dll, an upgrade would set the reference counter -# from 1 to 2 (due to what I consider a bug in MSI) -# Using the same UUID is fine since these files are versioned, -# so Installer will always keep the newest version. -# NOTE: All uuids are self generated. -pythondll_uuid = { - "24":"{9B81E618-2301-4035-AC77-75D9ABEB7301}", - "25":"{2e41b118-38bd-4c1b-a840-6977efd1b911}", - "26":"{34ebecac-f046-4e1c-b0e3-9bac3cdaacfa}", - "27":"{4fe21c76-1760-437b-a2f2-99909130a175}", - "30":"{6953bc3b-6768-4291-8410-7914ce6e2ca8}", - "31":"{4afcba0b-13e4-47c3-bebe-477428b46913}", - "32":"{3ff95315-1096-4d31-bd86-601d5438ad5e}", - "33":"{f7581ca4-d368-4eea-8f82-d48c64c4f047}", - "34":"{7A0C5812-2583-40D9-BCBB-CD7485F11377}", - } [major+minor] - -# Compute the name that Sphinx gives to the docfile -docfile = micro -if level < 0xf: - if level == 0xC: - docfile += "rc%s" % (serial,) - else: - docfile += '%x%s' % (level, serial) -docfile = 'python%s%s%s.chm' % (major, minor, docfile) - -# Build the mingw import library, libpythonXY.a -# This requires 'nm' and 'dlltool' executables on your PATH -def build_mingw_lib(lib_file, def_file, dll_file, mingw_lib): - warning = "WARNING: %s - libpythonXX.a not built" - nm = find_executable('nm') - dlltool = find_executable('dlltool') - - if not nm or not dlltool: - print(warning % "nm and/or dlltool were not found") - return False - - nm_command = '%s -Cs %s' % (nm, lib_file) - dlltool_command = "%s --dllname %s --def %s --output-lib %s" % \ - (dlltool, dll_file, def_file, mingw_lib) - export_match = re.compile(r"^_imp__(.*) in python\d+\.dll").match - - f = open(def_file,'w') - f.write("LIBRARY %s\n" % dll_file) - f.write("EXPORTS\n") - - nm_pipe = os.popen(nm_command) - for line in nm_pipe.readlines(): - m = export_match(line) - if m: - f.write(m.group(1)+"\n") - f.close() - exit = nm_pipe.close() - - if exit: - print(warning % "nm did not run successfully") - return False - - if os.system(dlltool_command) != 0: - print(warning % "dlltool did not run successfully") - return False - - return True - -# Target files (.def and .a) go in PCBuild directory -lib_file = os.path.join(srcdir, PCBUILD, "python%s%s.lib" % (major, minor)) -def_file = os.path.join(srcdir, PCBUILD, "python%s%s.def" % (major, minor)) -dll_file = "python%s%s.dll" % (major, minor) -mingw_lib = os.path.join(srcdir, PCBUILD, "libpython%s%s.a" % (major, minor)) - -have_mingw = build_mingw_lib(lib_file, def_file, dll_file, mingw_lib) - -# Determine the target architecture -if os.system("nmake /nologo /c /f msisupport.mak") != 0: - raise RuntimeError("'nmake /f msisupport.mak' failed") -dll_path = os.path.join(srcdir, PCBUILD, dll_file) -msilib.set_arch_from_file(dll_path) -if msilib.pe_type(dll_path) != msilib.pe_type("msisupport.dll"): - raise SystemError("msisupport.dll for incorrect architecture") - -if msilib.Win64: - upgrade_code = upgrade_code_64 - -if snapshot: - product_code = msilib.gen_uuid() -else: - # official release: generate UUID from the download link that the file will have - import uuid - product_code = uuid.uuid3(uuid.NAMESPACE_URL, - 'http://www.python.org/ftp/python/%s.%s.%s/python-%s%s.msi' % - (major, minor, micro, full_current_version, msilib.arch_ext)) - product_code = '{%s}' % product_code - -if testpackage: - ext = 'px' - testprefix = 'x' -else: - ext = 'py' - testprefix = '' - -if msilib.Win64: - SystemFolderName = "[System64Folder]" - registry_component = 4|256 -else: - SystemFolderName = "[SystemFolder]" - registry_component = 4 - -msilib.reset() - -# condition in which to install pythonxy.dll in system32: -# a) it is Windows 9x or -# b) it is NT, the user is privileged, and has chosen per-machine installation -sys32cond = "(Windows9x or (Privileged and ALLUSERS))" - -def build_database(): - """Generate an empty database, with just the schema and the - Summary information stream.""" - if snapshot: - uc = upgrade_code_snapshot - else: - uc = upgrade_code - if msilib.Win64: - productsuffix = " (64-bit)" - else: - productsuffix = "" - # schema represents the installer 2.0 database schema. - # sequence is the set of standard sequences - # (ui/execute, admin/advt/install) - msiname = "python-%s%s.msi" % (full_current_version, msilib.arch_ext) - db = msilib.init_database(msiname, - schema, ProductName="Python "+full_current_version+productsuffix, - ProductCode=product_code, - ProductVersion=current_version, - Manufacturer=u"Python Software Foundation", - request_uac = True) - # The default sequencing of the RemoveExistingProducts action causes - # removal of files that got just installed. Place it after - # InstallInitialize, so we first uninstall everything, but still roll - # back in case the installation is interrupted - msilib.change_sequence(sequence.InstallExecuteSequence, - "RemoveExistingProducts", 1510) - msilib.add_tables(db, sequence) - # We cannot set ALLUSERS in the property table, as this cannot be - # reset if the user choses a per-user installation. Instead, we - # maintain WhichUsers, which can be "ALL" or "JUSTME". The UI manages - # this property, and when the execution starts, ALLUSERS is set - # accordingly. - add_data(db, "Property", [("UpgradeCode", uc), - ("WhichUsers", "ALL"), - ("ProductLine", "Python%s%s" % (major, minor)), - ]) - db.Commit() - return db, msiname - -def remove_old_versions(db): - "Fill the upgrade table." - start = "%s.%s.0" % (major, minor) - # This requests that feature selection states of an older - # installation should be forwarded into this one. Upgrading - # requires that both the old and the new installation are - # either both per-machine or per-user. - migrate_features = 1 - # See "Upgrade Table". We remove releases with the same major and - # minor version. For an snapshot, we remove all earlier snapshots. For - # a release, we remove all snapshots, and all earlier releases. - if snapshot: - add_data(db, "Upgrade", - [(upgrade_code_snapshot, start, - current_version, - None, # Ignore language - migrate_features, - None, # Migrate ALL features - "REMOVEOLDSNAPSHOT")]) - props = "REMOVEOLDSNAPSHOT" - else: - add_data(db, "Upgrade", - [(upgrade_code, start, current_version, - None, migrate_features, None, "REMOVEOLDVERSION"), - (upgrade_code_snapshot, start, "%s.%d.0" % (major, int(minor)+1), - None, migrate_features, None, "REMOVEOLDSNAPSHOT")]) - props = "REMOVEOLDSNAPSHOT;REMOVEOLDVERSION" - - props += ";TARGETDIR;DLLDIR;LAUNCHERDIR" - # Installer collects the product codes of the earlier releases in - # these properties. In order to allow modification of the properties, - # they must be declared as secure. See "SecureCustomProperties Property" - add_data(db, "Property", [("SecureCustomProperties", props)]) - -class PyDialog(Dialog): - """Dialog class with a fixed layout: controls at the top, then a ruler, - then a list of buttons: back, next, cancel. Optionally a bitmap at the - left.""" - def __init__(self, *args, **kw): - """Dialog(database, name, x, y, w, h, attributes, title, first, - default, cancel, bitmap=true)""" - Dialog.__init__(self, *args) - ruler = self.h - 36 - bmwidth = 152*ruler/328 - if kw.get("bitmap", True): - self.bitmap("Bitmap", 0, 0, bmwidth, ruler, "PythonWin") - self.line("BottomLine", 0, ruler, self.w, 0) - - def title(self, title): - "Set the title text of the dialog at the top." - # name, x, y, w, h, flags=Visible|Enabled|Transparent|NoPrefix, - # text, in VerdanaBold10 - self.text("Title", 135, 10, 220, 60, 0x30003, - r"{\VerdanaBold10}%s" % title) - - def back(self, title, next, name = "Back", active = 1): - """Add a back button with a given title, the tab-next button, - its name in the Control table, possibly initially disabled. - - Return the button, so that events can be associated""" - if active: - flags = 3 # Visible|Enabled - else: - flags = 1 # Visible - return self.pushbutton(name, 180, self.h-27 , 56, 17, flags, title, next) - - def cancel(self, title, next, name = "Cancel", active = 1): - """Add a cancel button with a given title, the tab-next button, - its name in the Control table, possibly initially disabled. - - Return the button, so that events can be associated""" - if active: - flags = 3 # Visible|Enabled - else: - flags = 1 # Visible - return self.pushbutton(name, 304, self.h-27, 56, 17, flags, title, next) - - def next(self, title, next, name = "Next", active = 1): - """Add a Next button with a given title, the tab-next button, - its name in the Control table, possibly initially disabled. - - Return the button, so that events can be associated""" - if active: - flags = 3 # Visible|Enabled - else: - flags = 1 # Visible - return self.pushbutton(name, 236, self.h-27, 56, 17, flags, title, next) - - def xbutton(self, name, title, next, xpos): - """Add a button with a given title, the tab-next button, - its name in the Control table, giving its x position; the - y-position is aligned with the other buttons. - - Return the button, so that events can be associated""" - return self.pushbutton(name, int(self.w*xpos - 28), self.h-27, 56, 17, 3, title, next) - -def add_ui(db): - x = y = 50 - w = 370 - h = 300 - title = "[ProductName] Setup" - - # see "Dialog Style Bits" - modal = 3 # visible | modal - modeless = 1 # visible - track_disk_space = 32 - - add_data(db, 'ActionText', uisample.ActionText) - add_data(db, 'UIText', uisample.UIText) - - # Bitmaps - if not os.path.exists(srcdir+r"\PC\python_icon.exe"): - raise RuntimeError("Run icons.mak in PC directory") - add_data(db, "Binary", - [("PythonWin", msilib.Binary(r"%s\PCbuild\installer.bmp" % srcdir)), # 152x328 pixels - ("py.ico",msilib.Binary(srcdir+r"\PC\py.ico")), - ]) - add_data(db, "Icon", - [("python_icon.exe", msilib.Binary(srcdir+r"\PC\python_icon.exe"))]) - - # Scripts - # CheckDir sets TargetExists if TARGETDIR exists. - # UpdateEditIDLE sets the REGISTRY.tcl component into - # the installed/uninstalled state according to both the - # Extensions and TclTk features. - add_data(db, "Binary", [("Script", msilib.Binary("msisupport.dll"))]) - # See "Custom Action Type 1" - if msilib.Win64: - CheckDir = "CheckDir" - UpdateEditIDLE = "UpdateEditIDLE" - else: - CheckDir = "_CheckDir@4" - UpdateEditIDLE = "_UpdateEditIDLE@4" - add_data(db, "CustomAction", - [("CheckDir", 1, "Script", CheckDir)]) - if have_tcl: - add_data(db, "CustomAction", - [("UpdateEditIDLE", 1, "Script", UpdateEditIDLE)]) - - # UI customization properties - add_data(db, "Property", - # See "DefaultUIFont Property" - [("DefaultUIFont", "DlgFont8"), - # See "ErrorDialog Style Bit" - ("ErrorDialog", "ErrorDlg"), - ("Progress1", "Install"), # modified in maintenance type dlg - ("Progress2", "installs"), - ("MaintenanceForm_Action", "Repair")]) - - # Fonts, see "TextStyle Table" - add_data(db, "TextStyle", - [("DlgFont8", "Tahoma", 9, None, 0), - ("DlgFontBold8", "Tahoma", 8, None, 1), #bold - ("VerdanaBold10", "Verdana", 10, None, 1), - ("VerdanaRed9", "Verdana", 9, 255, 0), - ]) - - compileargs = r'-Wi "[TARGETDIR]Lib\compileall.py" -f -x "bad_coding|badsyntax|site-packages|py2_|lib2to3\\tests|venv\\scripts" "[TARGETDIR]Lib"' - lib2to3args = r'-c "import lib2to3.pygram, lib2to3.patcomp;lib2to3.patcomp.PatternCompiler()"' - updatepipargs = r'-m ensurepip -U' - removepipargs = r'-m ensurepip -r' # does not yet work - # See "CustomAction Table" - add_data(db, "CustomAction", [ - # msidbCustomActionTypeFirstSequence + msidbCustomActionTypeTextData + msidbCustomActionTypeProperty - # See "Custom Action Type 51", - # "Custom Action Execution Scheduling Options" - ("InitialTargetDir", 307, "TARGETDIR", - "[WindowsVolume]Python%s%s" % (major, minor)), - ("SetDLLDirToTarget", 307, "DLLDIR", "[TARGETDIR]"), - ("SetDLLDirToSystem32", 307, "DLLDIR", SystemFolderName), - ("SetLauncherDirToTarget", 307, "LAUNCHERDIR", "[TARGETDIR]"), - ("SetLauncherDirToWindows", 307, "LAUNCHERDIR", "[WindowsFolder]"), - # msidbCustomActionTypeExe + msidbCustomActionTypeSourceFile - # See "Custom Action Type 18" - ("CompilePyc", 18, "python.exe", compileargs), - ("CompilePyo", 18, "python.exe", "-O "+compileargs), - ("CompileGrammar", 18, "python.exe", lib2to3args), - # msidbCustomActionTypeInScript (1024); run during actual installation - ("UpdatePip", 18+1024, "python.exe", updatepipargs), - #("RemovePip", 18, "python.exe", removepipargs), - ]) - - # UI Sequences, see "InstallUISequence Table", "Using a Sequence Table" - # Numbers indicate sequence; see sequence.py for how these action integrate - add_data(db, "InstallUISequence", - [("PrepareDlg", "Not Privileged or Windows9x or Installed", 140), - ("WhichUsersDlg", "Privileged and not Windows9x and not Installed", 141), - ("InitialTargetDir", 'TARGETDIR=""', 750), - # In the user interface, assume all-users installation if privileged. - ("SetDLLDirToSystem32", 'DLLDIR="" and ' + sys32cond, 751), - ("SetDLLDirToTarget", 'DLLDIR="" and not ' + sys32cond, 752), - ("SetLauncherDirToWindows", 'LAUNCHERDIR="" and ' + sys32cond, 753), - ("SetLauncherDirToTarget", 'LAUNCHERDIR="" and not ' + sys32cond, 754), - ("SelectDirectoryDlg", "Not Installed", 1230), - # XXX no support for resume installations yet - #("ResumeDlg", "Installed AND (RESUME OR Preselected)", 1240), - ("MaintenanceTypeDlg", "Installed AND NOT RESUME AND NOT Preselected", 1250), - ("ProgressDlg", None, 1280)]) - add_data(db, "AdminUISequence", - [("InitialTargetDir", 'TARGETDIR=""', 750), - ("SetDLLDirToTarget", 'DLLDIR=""', 751), - ("SetLauncherDirToTarget", 'LAUNCHERDIR=""', 752), - ]) - - # Prepend TARGETDIR to the system path, and remove it on uninstall. - add_data(db, "Environment", - [("PathAddition", "=-*Path", "[TARGETDIR];[TARGETDIR]Scripts;[~]", "REGISTRY.path")]) - - # Execute Sequences - add_data(db, "InstallExecuteSequence", - [("InitialTargetDir", 'TARGETDIR=""', 750), - ("SetDLLDirToSystem32", 'DLLDIR="" and ' + sys32cond, 751), - ("SetDLLDirToTarget", 'DLLDIR="" and not ' + sys32cond, 752), - ("SetLauncherDirToWindows", 'LAUNCHERDIR="" and ' + sys32cond, 753), - ("SetLauncherDirToTarget", 'LAUNCHERDIR="" and not ' + sys32cond, 754), - ("UpdateEditIDLE", None, 1050), - # run command if install state of pip changes to INSTALLSTATE_LOCAL - # run after InstallFiles - ("UpdatePip", "&pip=3", 4001), - # remove pip when state changes to INSTALLSTATE_ABSENT - # run before RemoveFiles - #("RemovePip", "&pip=2", 3499), - ("CompilePyc", "COMPILEALL", 6800), - ("CompilePyo", "COMPILEALL", 6801), - ("CompileGrammar", "COMPILEALL", 6802), - ]) - add_data(db, "AdminExecuteSequence", - [("InitialTargetDir", 'TARGETDIR=""', 750), - ("SetDLLDirToTarget", 'DLLDIR=""', 751), - ("SetLauncherDirToTarget", 'LAUNCHERDIR=""', 752), - ("CompilePyc", "COMPILEALL", 6800), - ("CompilePyo", "COMPILEALL", 6801), - ("CompileGrammar", "COMPILEALL", 6802), - ]) - - ##################################################################### - # Standard dialogs: FatalError, UserExit, ExitDialog - fatal=PyDialog(db, "FatalError", x, y, w, h, modal, title, - "Finish", "Finish", "Finish") - fatal.title("[ProductName] Installer ended prematurely") - fatal.back("< Back", "Finish", active = 0) - fatal.cancel("Cancel", "Back", active = 0) - fatal.text("Description1", 135, 70, 220, 80, 0x30003, - "[ProductName] setup ended prematurely because of an error. Your system has not been modified. To install this program at a later time, please run the installation again.") - fatal.text("Description2", 135, 155, 220, 20, 0x30003, - "Click the Finish button to exit the Installer.") - c=fatal.next("Finish", "Cancel", name="Finish") - # See "ControlEvent Table". Parameters are the event, the parameter - # to the action, and optionally the condition for the event, and the order - # of events. - c.event("EndDialog", "Exit") - - user_exit=PyDialog(db, "UserExit", x, y, w, h, modal, title, - "Finish", "Finish", "Finish") - user_exit.title("[ProductName] Installer was interrupted") - user_exit.back("< Back", "Finish", active = 0) - user_exit.cancel("Cancel", "Back", active = 0) - user_exit.text("Description1", 135, 70, 220, 80, 0x30003, - "[ProductName] setup was interrupted. Your system has not been modified. " - "To install this program at a later time, please run the installation again.") - user_exit.text("Description2", 135, 155, 220, 20, 0x30003, - "Click the Finish button to exit the Installer.") - c = user_exit.next("Finish", "Cancel", name="Finish") - c.event("EndDialog", "Exit") - - exit_dialog = PyDialog(db, "ExitDialog", x, y, w, h, modal, title, - "Finish", "Finish", "Finish") - exit_dialog.title("Complete the [ProductName] Installer") - exit_dialog.back("< Back", "Finish", active = 0) - exit_dialog.cancel("Cancel", "Back", active = 0) - exit_dialog.text("Acknowledgements", 135, 95, 220, 120, 0x30003, - "Special Windows thanks to:\n" - " Mark Hammond, without whose years of freely \n" - " shared Windows expertise, Python for Windows \n" - " would still be Python for DOS.") - - c = exit_dialog.text("warning", 135, 200, 220, 40, 0x30003, - "{\\VerdanaRed9}Warning: Python 2.5.x is the last " - "Python release for Windows 9x.") - c.condition("Hide", "NOT Version9X") - - exit_dialog.text("Description", 135, 235, 220, 20, 0x30003, - "Click the Finish button to exit the Installer.") - c = exit_dialog.next("Finish", "Cancel", name="Finish") - c.event("EndDialog", "Return") - - ##################################################################### - # Required dialog: FilesInUse, ErrorDlg - inuse = PyDialog(db, "FilesInUse", - x, y, w, h, - 19, # KeepModeless|Modal|Visible - title, - "Retry", "Retry", "Retry", bitmap=False) - inuse.text("Title", 15, 6, 200, 15, 0x30003, - r"{\DlgFontBold8}Files in Use") - inuse.text("Description", 20, 23, 280, 20, 0x30003, - "Some files that need to be updated are currently in use.") - inuse.text("Text", 20, 55, 330, 50, 3, - "The following applications are using files that need to be updated by this setup. Close these applications and then click Retry to continue the installation or Cancel to exit it.") - inuse.control("List", "ListBox", 20, 107, 330, 130, 7, "FileInUseProcess", - None, None, None) - c=inuse.back("Exit", "Ignore", name="Exit") - c.event("EndDialog", "Exit") - c=inuse.next("Ignore", "Retry", name="Ignore") - c.event("EndDialog", "Ignore") - c=inuse.cancel("Retry", "Exit", name="Retry") - c.event("EndDialog","Retry") - - - # See "Error Dialog". See "ICE20" for the required names of the controls. - error = Dialog(db, "ErrorDlg", - 50, 10, 330, 101, - 65543, # Error|Minimize|Modal|Visible - title, - "ErrorText", None, None) - error.text("ErrorText", 50,9,280,48,3, "") - error.control("ErrorIcon", "Icon", 15, 9, 24, 24, 5242881, None, "py.ico", None, None) - error.pushbutton("N",120,72,81,21,3,"No",None).event("EndDialog","ErrorNo") - error.pushbutton("Y",240,72,81,21,3,"Yes",None).event("EndDialog","ErrorYes") - error.pushbutton("A",0,72,81,21,3,"Abort",None).event("EndDialog","ErrorAbort") - error.pushbutton("C",42,72,81,21,3,"Cancel",None).event("EndDialog","ErrorCancel") - error.pushbutton("I",81,72,81,21,3,"Ignore",None).event("EndDialog","ErrorIgnore") - error.pushbutton("O",159,72,81,21,3,"Ok",None).event("EndDialog","ErrorOk") - error.pushbutton("R",198,72,81,21,3,"Retry",None).event("EndDialog","ErrorRetry") - - ##################################################################### - # Global "Query Cancel" dialog - cancel = Dialog(db, "CancelDlg", 50, 10, 260, 85, 3, title, - "No", "No", "No") - cancel.text("Text", 48, 15, 194, 30, 3, - "Are you sure you want to cancel [ProductName] installation?") - cancel.control("Icon", "Icon", 15, 15, 24, 24, 5242881, None, - "py.ico", None, None) - c=cancel.pushbutton("Yes", 72, 57, 56, 17, 3, "Yes", "No") - c.event("EndDialog", "Exit") - - c=cancel.pushbutton("No", 132, 57, 56, 17, 3, "No", "Yes") - c.event("EndDialog", "Return") - - ##################################################################### - # Global "Wait for costing" dialog - costing = Dialog(db, "WaitForCostingDlg", 50, 10, 260, 85, modal, title, - "Return", "Return", "Return") - costing.text("Text", 48, 15, 194, 30, 3, - "Please wait while the installer finishes determining your disk space requirements.") - costing.control("Icon", "Icon", 15, 15, 24, 24, 5242881, None, - "py.ico", None, None) - c = costing.pushbutton("Return", 102, 57, 56, 17, 3, "Return", None) - c.event("EndDialog", "Exit") - - ##################################################################### - # Preparation dialog: no user input except cancellation - prep = PyDialog(db, "PrepareDlg", x, y, w, h, modeless, title, - "Cancel", "Cancel", "Cancel") - prep.text("Description", 135, 70, 220, 40, 0x30003, - "Please wait while the Installer prepares to guide you through the installation.") - prep.title("Welcome to the [ProductName] Installer") - c=prep.text("ActionText", 135, 110, 220, 20, 0x30003, "Pondering...") - c.mapping("ActionText", "Text") - c=prep.text("ActionData", 135, 135, 220, 30, 0x30003, None) - c.mapping("ActionData", "Text") - prep.back("Back", None, active=0) - prep.next("Next", None, active=0) - c=prep.cancel("Cancel", None) - c.event("SpawnDialog", "CancelDlg") - - ##################################################################### - # Target directory selection - seldlg = PyDialog(db, "SelectDirectoryDlg", x, y, w, h, modal, title, - "Next", "Next", "Cancel") - seldlg.title("Select Destination Directory") - c = seldlg.text("Existing", 135, 25, 235, 30, 0x30003, - "{\VerdanaRed9}This update will replace your existing [ProductLine] installation.") - c.condition("Hide", 'REMOVEOLDVERSION="" and REMOVEOLDSNAPSHOT=""') - seldlg.text("Description", 135, 50, 220, 40, 0x30003, - "Please select a directory for the [ProductName] files.") - - seldlg.back("< Back", None, active=0) - c = seldlg.next("Next >", "Cancel") - c.event("DoAction", "CheckDir", "TargetExistsOk<>1", order=1) - # If the target exists, but we found that we are going to remove old versions, don't bother - # confirming that the target directory exists. Strictly speaking, we should determine that - # the target directory is indeed the target of the product that we are going to remove, but - # I don't know how to do that. - c.event("SpawnDialog", "ExistingDirectoryDlg", 'TargetExists=1 and REMOVEOLDVERSION="" and REMOVEOLDSNAPSHOT=""', 2) - c.event("SetTargetPath", "TARGETDIR", 'TargetExists=0 or REMOVEOLDVERSION<>"" or REMOVEOLDSNAPSHOT<>""', 3) - c.event("SpawnWaitDialog", "WaitForCostingDlg", "CostingComplete=1", 4) - c.event("NewDialog", "SelectFeaturesDlg", 'TargetExists=0 or REMOVEOLDVERSION<>"" or REMOVEOLDSNAPSHOT<>""', 5) - - c = seldlg.cancel("Cancel", "DirectoryCombo") - c.event("SpawnDialog", "CancelDlg") - - seldlg.control("DirectoryCombo", "DirectoryCombo", 135, 70, 172, 80, 393219, - "TARGETDIR", None, "DirectoryList", None) - seldlg.control("DirectoryList", "DirectoryList", 135, 90, 208, 136, 3, "TARGETDIR", - None, "PathEdit", None) - seldlg.control("PathEdit", "PathEdit", 135, 230, 206, 16, 3, "TARGETDIR", None, "Next", None) - c = seldlg.pushbutton("Up", 306, 70, 18, 18, 3, "Up", None) - c.event("DirectoryListUp", "0") - c = seldlg.pushbutton("NewDir", 324, 70, 30, 18, 3, "New", None) - c.event("DirectoryListNew", "0") - - ##################################################################### - # SelectFeaturesDlg - features = PyDialog(db, "SelectFeaturesDlg", x, y, w, h, modal|track_disk_space, - title, "Tree", "Next", "Cancel") - features.title("Customize [ProductName]") - features.text("Description", 135, 35, 220, 15, 0x30003, - "Select the way you want features to be installed.") - features.text("Text", 135,45,220,30, 3, - "Click on the icons in the tree below to change the way features will be installed.") - - c=features.back("< Back", "Next") - c.event("NewDialog", "SelectDirectoryDlg") - - c=features.next("Next >", "Cancel") - c.mapping("SelectionNoItems", "Enabled") - c.event("SpawnDialog", "DiskCostDlg", "OutOfDiskSpace=1", order=1) - c.event("EndDialog", "Return", "OutOfDiskSpace<>1", order=2) - - c=features.cancel("Cancel", "Tree") - c.event("SpawnDialog", "CancelDlg") - - # The browse property is not used, since we have only a single target path (selected already) - features.control("Tree", "SelectionTree", 135, 75, 220, 95, 7, "_BrowseProperty", - "Tree of selections", "Back", None) - - #c=features.pushbutton("Reset", 42, 243, 56, 17, 3, "Reset", "DiskCost") - #c.mapping("SelectionNoItems", "Enabled") - #c.event("Reset", "0") - - features.control("Box", "GroupBox", 135, 170, 225, 90, 1, None, None, None, None) - - c=features.xbutton("DiskCost", "Disk &Usage", None, 0.10) - c.mapping("SelectionNoItems","Enabled") - c.event("SpawnDialog", "DiskCostDlg") - - c=features.xbutton("Advanced", "Advanced", None, 0.30) - c.event("SpawnDialog", "AdvancedDlg") - - c=features.text("ItemDescription", 140, 180, 210, 40, 3, - "Multiline description of the currently selected item.") - c.mapping("SelectionDescription","Text") - - c=features.text("ItemSize", 140, 225, 210, 33, 3, - "The size of the currently selected item.") - c.mapping("SelectionSize", "Text") - - ##################################################################### - # Disk cost - cost = PyDialog(db, "DiskCostDlg", x, y, w, h, modal, title, - "OK", "OK", "OK", bitmap=False) - cost.text("Title", 15, 6, 200, 15, 0x30003, - "{\DlgFontBold8}Disk Space Requirements") - cost.text("Description", 20, 20, 280, 20, 0x30003, - "The disk space required for the installation of the selected features.") - cost.text("Text", 20, 53, 330, 60, 3, - "The highlighted volumes (if any) do not have enough disk space " - "available for the currently selected features. You can either " - "remove some files from the highlighted volumes, or choose to " - "install less features onto local drive(s), or select different " - "destination drive(s).") - cost.control("VolumeList", "VolumeCostList", 20, 100, 330, 150, 393223, - None, "{120}{70}{70}{70}{70}", None, None) - cost.xbutton("OK", "Ok", None, 0.5).event("EndDialog", "Return") - - ##################################################################### - # WhichUsers Dialog. Only available on NT, and for privileged users. - # This must be run before FindRelatedProducts, because that will - # take into account whether the previous installation was per-user - # or per-machine. We currently don't support going back to this - # dialog after "Next" was selected; to support this, we would need to - # find how to reset the ALLUSERS property, and how to re-run - # FindRelatedProducts. - # On Windows9x, the ALLUSERS property is ignored on the command line - # and in the Property table, but installer fails according to the documentation - # if a dialog attempts to set ALLUSERS. - whichusers = PyDialog(db, "WhichUsersDlg", x, y, w, h, modal, title, - "AdminInstall", "Next", "Cancel") - whichusers.title("Select whether to install [ProductName] for all users of this computer.") - # A radio group with two options: allusers, justme - g = whichusers.radiogroup("AdminInstall", 135, 60, 235, 80, 3, - "WhichUsers", "", "Next") - g.condition("Disable", "VersionNT=600") # Not available on Vista and Windows 2008 - g.add("ALL", 0, 5, 150, 20, "Install for all users") - g.add("JUSTME", 0, 25, 235, 20, "Install just for me (not available on Windows Vista)") - - whichusers.back("Back", None, active=0) - - c = whichusers.next("Next >", "Cancel") - c.event("[ALLUSERS]", "1", 'WhichUsers="ALL"', 1) - c.event("EndDialog", "Return", order = 2) - - c = whichusers.cancel("Cancel", "AdminInstall") - c.event("SpawnDialog", "CancelDlg") - - ##################################################################### - # Advanced Dialog. - advanced = PyDialog(db, "AdvancedDlg", x, y, w, h, modal, title, - "CompilePyc", "Ok", "Ok") - advanced.title("Advanced Options for [ProductName]") - - # A checkbox whether to build pyc files - advanced.checkbox("CompilePyc", 135, 60, 230, 50, 3, - "COMPILEALL", "Compile .py files to byte code after installation", "Ok") - - c = advanced.cancel("Ok", "CompilePyc", name="Ok") # Button just has location of cancel button. - c.event("EndDialog", "Return") - - ##################################################################### - # Existing Directory dialog - dlg = Dialog(db, "ExistingDirectoryDlg", 50, 30, 200, 80, modal, title, - "No", "No", "No") - dlg.text("Title", 10, 20, 180, 40, 3, - "[TARGETDIR] exists. Are you sure you want to overwrite existing files?") - c=dlg.pushbutton("Yes", 30, 60, 55, 17, 3, "Yes", "No") - c.event("[TargetExists]", "0", order=1) - c.event("[TargetExistsOk]", "1", order=2) - c.event("EndDialog", "Return", order=3) - c=dlg.pushbutton("No", 115, 60, 55, 17, 3, "No", "Yes") - c.event("EndDialog", "Return") - - ##################################################################### - # Installation Progress dialog (modeless) - progress = PyDialog(db, "ProgressDlg", x, y, w, h, modeless, title, - "Cancel", "Cancel", "Cancel", bitmap=False) - progress.text("Title", 20, 15, 200, 15, 0x30003, - "{\DlgFontBold8}[Progress1] [ProductName]") - progress.text("Text", 35, 65, 300, 30, 3, - "Please wait while the Installer [Progress2] [ProductName]. " - "This may take several minutes.") - progress.text("StatusLabel", 35, 100, 35, 20, 3, "Status:") - - c=progress.text("ActionText", 70, 100, w-70, 20, 3, "Pondering...") - c.mapping("ActionText", "Text") - - #c=progress.text("ActionData", 35, 140, 300, 20, 3, None) - #c.mapping("ActionData", "Text") - - c=progress.control("ProgressBar", "ProgressBar", 35, 120, 300, 10, 65537, - None, "Progress done", None, None) - c.mapping("SetProgress", "Progress") - - progress.back("< Back", "Next", active=False) - progress.next("Next >", "Cancel", active=False) - progress.cancel("Cancel", "Back").event("SpawnDialog", "CancelDlg") - - # Maintenance type: repair/uninstall - maint = PyDialog(db, "MaintenanceTypeDlg", x, y, w, h, modal, title, - "Next", "Next", "Cancel") - maint.title("Welcome to the [ProductName] Setup Wizard") - maint.text("BodyText", 135, 63, 230, 42, 3, - "Select whether you want to repair or remove [ProductName].") - g=maint.radiogroup("RepairRadioGroup", 135, 108, 230, 60, 3, - "MaintenanceForm_Action", "", "Next") - g.add("Change", 0, 0, 200, 17, "&Change [ProductName]") - g.add("Repair", 0, 18, 200, 17, "&Repair [ProductName]") - g.add("Remove", 0, 36, 200, 17, "Re&move [ProductName]") - - maint.back("< Back", None, active=False) - c=maint.next("Finish", "Cancel") - # Change installation: Change progress dialog to "Change", then ask - # for feature selection - c.event("[Progress1]", "Change", 'MaintenanceForm_Action="Change"', 1) - c.event("[Progress2]", "changes", 'MaintenanceForm_Action="Change"', 2) - - # Reinstall: Change progress dialog to "Repair", then invoke reinstall - # Also set list of reinstalled features to "ALL" - c.event("[REINSTALL]", "ALL", 'MaintenanceForm_Action="Repair"', 5) - c.event("[Progress1]", "Repairing", 'MaintenanceForm_Action="Repair"', 6) - c.event("[Progress2]", "repairs", 'MaintenanceForm_Action="Repair"', 7) - c.event("Reinstall", "ALL", 'MaintenanceForm_Action="Repair"', 8) - - # Uninstall: Change progress to "Remove", then invoke uninstall - # Also set list of removed features to "ALL" - c.event("[REMOVE]", "ALL", 'MaintenanceForm_Action="Remove"', 11) - c.event("[Progress1]", "Removing", 'MaintenanceForm_Action="Remove"', 12) - c.event("[Progress2]", "removes", 'MaintenanceForm_Action="Remove"', 13) - c.event("Remove", "ALL", 'MaintenanceForm_Action="Remove"', 14) - - # Close dialog when maintenance action scheduled - c.event("EndDialog", "Return", 'MaintenanceForm_Action<>"Change"', 20) - c.event("NewDialog", "SelectFeaturesDlg", 'MaintenanceForm_Action="Change"', 21) - - maint.cancel("Cancel", "RepairRadioGroup").event("SpawnDialog", "CancelDlg") - - -# See "Feature Table". The feature level is 1 for all features, -# and the feature attributes are 0 for the DefaultFeature, and -# FollowParent for all other features. The numbers are the Display -# column. -def add_features(db): - # feature attributes: - # msidbFeatureAttributesFollowParent == 2 - # msidbFeatureAttributesDisallowAdvertise == 8 - # Features that need to be installed with together with the main feature - # (i.e. additional Python libraries) need to follow the parent feature. - # Features that have no advertisement trigger (e.g. the test suite) - # must not support advertisement - global default_feature, tcltk, htmlfiles, tools, testsuite - global ext_feature, private_crt, prepend_path, update_pip - default_feature = Feature(db, "DefaultFeature", "Python", - "Python Interpreter and Libraries", - 1, directory = "TARGETDIR") - shared_crt = Feature(db, "SharedCRT", "MSVCRT", "C Run-Time (system-wide)", 0, - level=0) - private_crt = Feature(db, "PrivateCRT", "MSVCRT", "C Run-Time (private)", 0, - level=0) - add_data(db, "Condition", [("SharedCRT", 1, sys32cond), - ("PrivateCRT", 1, "not "+sys32cond)]) - # We don't support advertisement of extensions - ext_feature = Feature(db, "Extensions", "Register Extensions", - "Make this Python installation the default Python installation", 3, - parent = default_feature, attributes=2|8) - if have_tcl: - tcltk = Feature(db, "TclTk", "Tcl/Tk", "Tkinter, IDLE, pydoc", 5, - parent = default_feature, attributes=2) - htmlfiles = Feature(db, "Documentation", "Documentation", - "Python HTMLHelp File", 7, parent = default_feature) - tools = Feature(db, "Tools", "Utility Scripts", - "Python utility scripts (Tools/)", 9, - parent = default_feature, attributes=2) - # pip installation isn't enabled by default until a clean uninstall procedure - # becomes possible - update_pip = Feature(db, "pip", "pip", - "Install (or upgrade from an earlier version) pip, " - "a tool for installing and managing Python packages.", 11, - parent = default_feature, attributes=2|8, level=2) - testsuite = Feature(db, "Testsuite", "Test suite", - "Python test suite (Lib/test/)", 13, - parent = default_feature, attributes=2|8) - # prepend_path is an additional feature which is to be off by default. - # Since the default level for the above features is 1, this needs to be - # at least level higher. - prepend_path = Feature(db, "PrependPath", "Add python.exe to Path", - "Prepend [TARGETDIR] to the system Path variable. " - "This allows you to type 'python' into a command " - "prompt without needing the full path.", 15, - parent = default_feature, attributes=2|8, - level=2) - -def extract_msvcr100(): - # Find the redistributable files - if msilib.Win64: - arch = "x64" - else: - arch = "x86" - dir = os.path.join(os.environ['VS100COMNTOOLS'], r"..\..\VC\redist\%s\Microsoft.VC100.CRT" % arch) - - result = [] - installer = msilib.MakeInstaller() - # At least for VS2010, manifests are no longer provided - name = "msvcr100.dll" - path = os.path.join(dir, name) - kw = {'src':path} - kw['version'] = installer.FileVersion(path, 0) - kw['language'] = installer.FileVersion(path, 1) - return name, kw - -def generate_license(): - import shutil, glob - out = open("LICENSE.txt", "w") - shutil.copyfileobj(open(os.path.join(srcdir, "LICENSE")), out) - shutil.copyfileobj(open("crtlicense.txt"), out) - for name, pat, file in (("bzip2","bzip2-*", "LICENSE"), - ("openssl", "openssl-*", "LICENSE"), - ("Tcl", "tcl8*", "license.terms"), - ("Tk", "tk8*", "license.terms"), - ("Tix", "tix-*", "license.terms")): - out.write("\nThis copy of Python includes a copy of %s, which is licensed under the following terms:\n\n" % name) - dirs = glob.glob(srcdir+"/../"+pat) - if not dirs: - raise ValueError, "Could not find "+srcdir+"/../"+pat - if len(dirs) > 2 and not snapshot: - raise ValueError, "Multiple copies of "+pat - dir = dirs[0] - shutil.copyfileobj(open(os.path.join(dir, file)), out) - out.close() - - -class PyDirectory(Directory): - """By default, all components in the Python installer - can run from source.""" - def __init__(self, *args, **kw): - if "componentflags" not in kw: - kw['componentflags'] = 2 #msidbComponentAttributesOptional - Directory.__init__(self, *args, **kw) - -def hgmanifest(): - # Fetch file list from Mercurial - process = subprocess.Popen(['hg', 'manifest'], stdout=subprocess.PIPE) - stdout, stderr = process.communicate() - # Create nested directories for file tree - result = {} - for line in stdout.splitlines(): - components = line.split('/') - d = result - while len(components) > 1: - d1 = d.setdefault(components[0], {}) - d = d1 - del components[0] - d[components[0]] = None - return result - - -# See "File Table", "Component Table", "Directory Table", -# "FeatureComponents Table" -def add_files(db): - installer = msilib.MakeInstaller() - hgfiles = hgmanifest() - cab = CAB("python") - tmpfiles = [] - # Add all executables, icons, text files into the TARGETDIR component - root = PyDirectory(db, cab, None, srcdir, "TARGETDIR", "SourceDir") - default_feature.set_current() - root.add_file("README.txt", src="README") - root.add_file("NEWS.txt", src="Misc/NEWS") - generate_license() - root.add_file("LICENSE.txt", src=os.path.abspath("LICENSE.txt")) - root.start_component("python.exe", keyfile="python.exe") - root.add_file("%s/python.exe" % PCBUILD) - root.start_component("pythonw.exe", keyfile="pythonw.exe") - root.add_file("%s/pythonw.exe" % PCBUILD) - - # msidbComponentAttributesSharedDllRefCount = 8, see "Component Table" - dlldir = PyDirectory(db, cab, root, srcdir, "DLLDIR", ".") - launcherdir = PyDirectory(db, cab, root, srcdir, "LAUNCHERDIR", ".") - - # msidbComponentAttributes64bit = 256; this disables registry redirection - # to allow setting the SharedDLLs key in the 64-bit portion even for a - # 32-bit installer. - # XXX does this still allow to install the component on a 32-bit system? - # Pick up 32-bit binary always - launchersrc = PCBUILD - if launchersrc.lower() == 'pcbuild\\x64-pgo': - launchersrc = 'PCBuild\\win32-pgo' - if launchersrc.lower() == 'pcbuild\\amd64': - launchersrc = 'PCBuild' - launcher = os.path.join(srcdir, launchersrc, "py.exe") - launcherdir.start_component("launcher", flags = 8+256, keyfile="py.exe") - launcherdir.add_file(launcher, - version=installer.FileVersion(launcher, 0), - language=installer.FileVersion(launcher, 1)) - launcherw = os.path.join(srcdir, launchersrc, "pyw.exe") - launcherdir.start_component("launcherw", flags = 8+256, keyfile="pyw.exe") - launcherdir.add_file(launcherw, - version=installer.FileVersion(launcherw, 0), - language=installer.FileVersion(launcherw, 1)) - - pydll = "python%s%s.dll" % (major, minor) - pydllsrc = os.path.join(srcdir, PCBUILD, pydll) - dlldir.start_component("DLLDIR", flags = 8, keyfile = pydll, uuid = pythondll_uuid) - pyversion = installer.FileVersion(pydllsrc, 0) - if not snapshot: - # For releases, the Python DLL has the same version as the - # installer package. - assert pyversion.split(".")[:3] == current_version.split(".") - dlldir.add_file("%s/python%s%s.dll" % (PCBUILD, major, minor), - version=pyversion, - language=installer.FileVersion(pydllsrc, 1)) - DLLs = PyDirectory(db, cab, root, srcdir + "/" + PCBUILD, "DLLs", "DLLS|DLLs") - - # msvcr90.dll: Need to place the DLL and the manifest into the root directory, - # plus another copy of the manifest in the DLLs directory, with the manifest - # pointing to the root directory - root.start_component("msvcr90", feature=private_crt) - # Results are ID,keyword pairs - crtdll, kwds = extract_msvcr100() - root.add_file(crtdll, **kwds) - # Copy the manifest - # Actually, don't do that anymore - no DLL in DLLs should have a manifest - # dependency on msvcr90.dll anymore, so this should not be necessary - #manifest_dlls = manifest[0]+".root" - #open(manifest_dlls, "w").write(open(manifest[1]['src']).read().replace("msvcr","../msvcr")) - #DLLs.start_component("msvcr90_dlls", feature=private_crt) - #DLLs.add_file(manifest[0], src=os.path.abspath(manifest_dlls)) - - # Now start the main component for the DLLs directory; - # no regular files have been added to the directory yet. - DLLs.start_component() - - # Check if _ctypes.pyd exists - have_ctypes = os.path.exists(srcdir+"/%s/_ctypes.pyd" % PCBUILD) - if not have_ctypes: - print("WARNING: _ctypes.pyd not found, ctypes will not be included") - extensions.remove("_ctypes.pyd") - - # Add all .py files in Lib, except tkinter, test - dirs = [] - pydirs = [(root, "Lib", hgfiles["Lib"], default_feature)] - while pydirs: - # Commit every now and then, or else installer will complain - db.Commit() - parent, dir, files, feature = pydirs.pop() - if dir.startswith("plat-"): - continue - if dir in ["tkinter", "idlelib", "turtledemo"]: - if not have_tcl: - continue - feature = tcltk - tcltk.set_current() - elif dir in ('test', 'tests'): - feature = testsuite - elif not have_ctypes and dir == "ctypes": - continue - feature.set_current() - lib = PyDirectory(db, cab, parent, dir, dir, "%s|%s" % (parent.make_short(dir), dir)) - dirs.append(lib) - has_py = False - for name, subdir in files.items(): - if subdir is None: - assert os.path.isfile(os.path.join(lib.absolute, name)) - if name == 'README': - lib.add_file("README.txt", src="README") - else: - lib.add_file(name) - has_py = has_py or name.endswith(".py") or name.endswith(".pyw") - else: - assert os.path.isdir(os.path.join(lib.absolute, name)) - pydirs.append((lib, name, subdir, feature)) - - if has_py: - lib.remove_pyc() - # Add DLLs - default_feature.set_current() - lib = DLLs - lib.add_file("py.ico", src=srcdir+"/PC/py.ico") - lib.add_file("pyc.ico", src=srcdir+"/PC/pyc.ico") - dlls = [] - tclfiles = [] - for f in extensions: - if f=="_tkinter.pyd": - continue - if not os.path.exists(srcdir + "/" + PCBUILD + "/" + f): - print("WARNING: Missing extension", f) - continue - dlls.append(f) - lib.add_file(f) - lib.add_file('python3.dll') - # Add sqlite - if msilib.msi_type=="Intel64;1033": - sqlite_arch = "/ia64" - elif msilib.msi_type=="x64;1033": - sqlite_arch = "/amd64" - tclsuffix = "64" - else: - sqlite_arch = "" - tclsuffix = "" - lib.add_file("sqlite3.dll") - if have_tcl: - if not os.path.exists("%s/%s/_tkinter.pyd" % (srcdir, PCBUILD)): - print("WARNING: Missing _tkinter.pyd") - else: - lib.start_component("TkDLLs", tcltk) - lib.add_file("_tkinter.pyd") - dlls.append("_tkinter.pyd") - tcldir = os.path.normpath(srcdir+("/../tcltk%s/bin" % tclsuffix)) - for f in glob.glob1(tcldir, "*.dll"): - lib.add_file(f, src=os.path.join(tcldir, f)) - # check whether there are any unknown extensions - for f in glob.glob1(srcdir+"/"+PCBUILD, "*.pyd"): - if f.endswith("_d.pyd"): continue # debug version - if f in dlls: continue - print("WARNING: Unknown extension", f) - - # Add headers - default_feature.set_current() - lib = PyDirectory(db, cab, root, "include", "include", "INCLUDE|include") - lib.glob("*.h") - lib.add_file("pyconfig.h", src="../PC/pyconfig.h") - # Add import libraries - lib = PyDirectory(db, cab, root, PCBUILD, "libs", "LIBS|libs") - for f in dlls: - lib.add_file(f.replace('pyd','lib')) - lib.add_file('python%s%s.lib' % (major, minor)) - lib.add_file('python3.lib') - # Add the mingw-format library - if have_mingw: - lib.add_file('libpython%s%s.a' % (major, minor)) - if have_tcl: - # Add Tcl/Tk - tcldirs = [(root, '../tcltk%s/lib' % tclsuffix, 'tcl')] - tcltk.set_current() - while tcldirs: - parent, phys, dir = tcldirs.pop() - lib = PyDirectory(db, cab, parent, phys, dir, "%s|%s" % (parent.make_short(dir), dir)) - if not os.path.exists(lib.absolute): - continue - for f in os.listdir(lib.absolute): - if os.path.isdir(os.path.join(lib.absolute, f)): - tcldirs.append((lib, f, f)) - else: - lib.add_file(f) - # Add tools - tools.set_current() - tooldir = PyDirectory(db, cab, root, "Tools", "Tools", "TOOLS|Tools") - for f in ['i18n', 'pynche', 'Scripts']: - lib = PyDirectory(db, cab, tooldir, f, f, "%s|%s" % (tooldir.make_short(f), f)) - lib.glob("*.py") - lib.glob("*.pyw", exclude=['pydocgui.pyw']) - lib.remove_pyc() - lib.glob("*.txt") - if f == "pynche": - x = PyDirectory(db, cab, lib, "X", "X", "X|X") - x.glob("*.txt") - if os.path.exists(os.path.join(lib.absolute, "README")): - lib.add_file("README.txt", src="README") - if f == 'Scripts': - lib.add_file("2to3.py", src="2to3") - lib.add_file("pydoc3.py", src="pydoc3") - lib.add_file("pyvenv.py", src="pyvenv") - if have_tcl: - lib.start_component("pydocgui.pyw", tcltk, keyfile="pydocgui.pyw") - lib.add_file("pydocgui.pyw") - # Add documentation - htmlfiles.set_current() - lib = PyDirectory(db, cab, root, "Doc", "Doc", "DOC|Doc") - lib.start_component("documentation", keyfile=docfile) - lib.add_file(docfile, src="build/htmlhelp/"+docfile) - - cab.commit(db) - - for f in tmpfiles: - os.unlink(f) - -# See "Registry Table", "Component Table" -def add_registry(db): - # File extensions, associated with the REGISTRY.def component - # IDLE verbs depend on the tcltk feature. - # msidbComponentAttributesRegistryKeyPath = 4 - # -1 for Root specifies "dependent on ALLUSERS property" - tcldata = [] - if have_tcl: - tcldata = [ - ("REGISTRY.tcl", msilib.gen_uuid(), "TARGETDIR", registry_component, None, - "py.IDLE")] - add_data(db, "Component", - # msidbComponentAttributesRegistryKeyPath = 4 - [("REGISTRY", msilib.gen_uuid(), "TARGETDIR", registry_component, None, - "InstallPath"), - ("REGISTRY.doc", msilib.gen_uuid(), "TARGETDIR", registry_component, None, - "Documentation"), - ("REGISTRY.path", msilib.gen_uuid(), "TARGETDIR", registry_component, None, - None), - ("REGISTRY.def", msilib.gen_uuid(), "TARGETDIR", registry_component, - None, None)] + tcldata) - # See "FeatureComponents Table". - # The association between TclTk and pythonw.exe is necessary to make ICE59 - # happy, because the installer otherwise believes that the IDLE and PyDoc - # shortcuts might get installed without pythonw.exe being install. This - # is not true, since installing TclTk will install the default feature, which - # will cause pythonw.exe to be installed. - # REGISTRY.tcl is not associated with any feature, as it will be requested - # through a custom action - tcldata = [] - if have_tcl: - tcldata = [(tcltk.id, "pythonw.exe")] - add_data(db, "FeatureComponents", - [(default_feature.id, "REGISTRY"), - (htmlfiles.id, "REGISTRY.doc"), - (prepend_path.id, "REGISTRY.path"), - (ext_feature.id, "REGISTRY.def")] + - tcldata - ) - # Extensions are not advertised. For advertised extensions, - # we would need separate binaries that install along with the - # extension. - pat = r"Software\Classes\%sPython.%sFile\shell\%s\command" - ewi = "Edit with IDLE" - pat2 = r"Software\Classes\%sPython.%sFile\DefaultIcon" - pat3 = r"Software\Classes\%sPython.%sFile" - pat4 = r"Software\Classes\%sPython.%sFile\shellex\DropHandler" - tcl_verbs = [] - if have_tcl: - tcl_verbs=[ - ("py.IDLE", -1, pat % (testprefix, "", ewi), "", - r'"[TARGETDIR]pythonw.exe" "[TARGETDIR]Lib\idlelib\idle.pyw" -e "%1"', - "REGISTRY.tcl"), - ("pyw.IDLE", -1, pat % (testprefix, "NoCon", ewi), "", - r'"[TARGETDIR]pythonw.exe" "[TARGETDIR]Lib\idlelib\idle.pyw" -e "%1"', - "REGISTRY.tcl"), - ] - add_data(db, "Registry", - [# Extensions - ("py.ext", -1, r"Software\Classes\."+ext, "", - "Python.File", "REGISTRY.def"), - ("pyw.ext", -1, r"Software\Classes\."+ext+'w', "", - "Python.NoConFile", "REGISTRY.def"), - ("pyc.ext", -1, r"Software\Classes\."+ext+'c', "", - "Python.CompiledFile", "REGISTRY.def"), - ("pyo.ext", -1, r"Software\Classes\."+ext+'o', "", - "Python.CompiledFile", "REGISTRY.def"), - # MIME types - ("py.mime", -1, r"Software\Classes\."+ext, "Content Type", - "text/plain", "REGISTRY.def"), - ("pyw.mime", -1, r"Software\Classes\."+ext+'w', "Content Type", - "text/plain", "REGISTRY.def"), - #Verbs - ("py.open", -1, pat % (testprefix, "", "open"), "", - r'"[LAUNCHERDIR]py.exe" "%1" %*', "REGISTRY.def"), - ("pyw.open", -1, pat % (testprefix, "NoCon", "open"), "", - r'"[LAUNCHERDIR]pyw.exe" "%1" %*', "REGISTRY.def"), - ("pyc.open", -1, pat % (testprefix, "Compiled", "open"), "", - r'"[LAUNCHERDIR]py.exe" "%1" %*', "REGISTRY.def"), - ] + tcl_verbs + [ - #Icons - ("py.icon", -1, pat2 % (testprefix, ""), "", - r'[DLLs]py.ico', "REGISTRY.def"), - ("pyw.icon", -1, pat2 % (testprefix, "NoCon"), "", - r'[DLLs]py.ico', "REGISTRY.def"), - ("pyc.icon", -1, pat2 % (testprefix, "Compiled"), "", - r'[DLLs]pyc.ico', "REGISTRY.def"), - # Descriptions - ("py.txt", -1, pat3 % (testprefix, ""), "", - "Python File", "REGISTRY.def"), - ("pyw.txt", -1, pat3 % (testprefix, "NoCon"), "", - "Python File (no console)", "REGISTRY.def"), - ("pyc.txt", -1, pat3 % (testprefix, "Compiled"), "", - "Compiled Python File", "REGISTRY.def"), - # Drop Handler - ("py.drop", -1, pat4 % (testprefix, ""), "", - "{60254CA5-953B-11CF-8C96-00AA00B8708C}", "REGISTRY.def"), - ("pyw.drop", -1, pat4 % (testprefix, "NoCon"), "", - "{60254CA5-953B-11CF-8C96-00AA00B8708C}", "REGISTRY.def"), - ("pyc.drop", -1, pat4 % (testprefix, "Compiled"), "", - "{60254CA5-953B-11CF-8C96-00AA00B8708C}", "REGISTRY.def"), - ]) - - # PATHEXT - add_data(db, "Environment", - [("PathExtAddition", "=-*PathExt", "[~];.PY", "REGISTRY.def")]) - - # Registry keys - prefix = r"Software\%sPython\PythonCore\%s" % (testprefix, short_version) - add_data(db, "Registry", - [("InstallPath", -1, prefix+r"\InstallPath", "", "[TARGETDIR]", "REGISTRY"), - ("InstallGroup", -1, prefix+r"\InstallPath\InstallGroup", "", - "Python %s" % short_version, "REGISTRY"), - ("PythonPath", -1, prefix+r"\PythonPath", "", - r"[TARGETDIR]Lib;[TARGETDIR]DLLs", "REGISTRY"), - ("Documentation", -1, prefix+r"\Help\Main Python Documentation", "", - "[TARGETDIR]Doc\\"+docfile , "REGISTRY.doc"), - ("Modules", -1, prefix+r"\Modules", "+", None, "REGISTRY"), - ("AppPaths", -1, r"Software\Microsoft\Windows\CurrentVersion\App Paths\Python.exe", - "", r"[TARGETDIR]Python.exe", "REGISTRY.def"), - ("DisplayIcon", -1, - r"Software\Microsoft\Windows\CurrentVersion\Uninstall\%s" % product_code, - "DisplayIcon", "[TARGETDIR]python.exe", "REGISTRY") - ]) - # Shortcuts, see "Shortcut Table" - add_data(db, "Directory", - [("ProgramMenuFolder", "TARGETDIR", "."), - ("MenuDir", "ProgramMenuFolder", "PY%s%s|%sPython %s.%s" % (major,minor,testprefix,major,minor))]) - add_data(db, "RemoveFile", - [("MenuDir", "TARGETDIR", None, "MenuDir", 2)]) - tcltkshortcuts = [] - if have_tcl: - tcltkshortcuts = [ - ("IDLE", "MenuDir", "IDLE|IDLE (Python GUI)", "pythonw.exe", - tcltk.id, r'"[TARGETDIR]Lib\idlelib\idle.pyw"', None, None, "python_icon.exe", 0, None, "TARGETDIR"), - ("PyDoc", "MenuDir", "MODDOCS|Module Docs", "pythonw.exe", - tcltk.id, r'"[TARGETDIR]Tools\scripts\pydocgui.pyw"', None, None, "python_icon.exe", 0, None, "TARGETDIR"), - ] - add_data(db, "Shortcut", - tcltkshortcuts + - [# Advertised shortcuts: targets are features, not files - ("Python", "MenuDir", "PYTHON|Python (command line)", "python.exe", - default_feature.id, None, None, None, "python_icon.exe", 2, None, "TARGETDIR"), - # Advertising the Manual breaks on (some?) Win98, and the shortcut lacks an - # icon first. - #("Manual", "MenuDir", "MANUAL|Python Manuals", "documentation", - # htmlfiles.id, None, None, None, None, None, None, None), - ## Non-advertised shortcuts: must be associated with a registry component - ("Manual", "MenuDir", "MANUAL|Python Manuals", "REGISTRY.doc", - "[#%s]" % docfile, None, - None, None, None, None, None, None), - ("Uninstall", "MenuDir", "UNINST|Uninstall Python", "REGISTRY", - SystemFolderName+"msiexec", "/x%s" % product_code, - None, None, None, None, None, None), - ]) - db.Commit() - -def build_pdbzip(): - pdbexclude = ['kill_python.pdb', 'make_buildinfo.pdb', - 'make_versioninfo.pdb'] - path = "python-%s%s-pdb.zip" % (full_current_version, msilib.arch_ext) - pdbzip = zipfile.ZipFile(path, 'w') - for f in glob.glob1(os.path.join(srcdir, PCBUILD), "*.pdb"): - if f not in pdbexclude and not f.endswith('_d.pdb'): - pdbzip.write(os.path.join(srcdir, PCBUILD, f), f) - pdbzip.close() - -db,msiname = build_database() -try: - add_features(db) - add_ui(db) - add_files(db) - add_registry(db) - remove_old_versions(db) - db.Commit() -finally: - del db - -# Merge CRT into MSI file. This requires the database to be closed. -mod_dir = os.path.join(os.environ["ProgramFiles"], "Common Files", "Merge Modules") -if msilib.Win64: - modules = ["Microsoft_VC100_CRT_x64.msm"] -else: - modules = ["Microsoft_VC100_CRT_x86.msm"] - -for i, n in enumerate(modules): - modules[i] = os.path.join(mod_dir, n) - -def merge(msi, feature, rootdir, modules): - cab_and_filecount = [] - # Step 1: Merge databases, extract cabfiles - m = msilib.MakeMerge2() - m.OpenLog("merge.log") - m.OpenDatabase(msi) - for module in modules: - print module - m.OpenModule(module,0) - m.Merge(feature, rootdir) - print "Errors:" - for e in m.Errors: - print e.Type, e.ModuleTable, e.DatabaseTable - print " Modkeys:", - for s in e.ModuleKeys: print s, - print - print " DBKeys:", - for s in e.DatabaseKeys: print s, - print - cabname = tempfile.mktemp(suffix=".cab") - m.ExtractCAB(cabname) - cab_and_filecount.append((cabname, len(m.ModuleFiles))) - m.CloseModule() - m.CloseDatabase(True) - m.CloseLog() - - # Step 2: Add CAB files - i = msilib.MakeInstaller() - db = i.OpenDatabase(msi, constants.msiOpenDatabaseModeTransact) - - v = db.OpenView("SELECT LastSequence FROM Media") - v.Execute(None) - maxmedia = -1 - while 1: - r = v.Fetch() - if not r: break - seq = r.IntegerData(1) - if seq > maxmedia: - maxmedia = seq - print "Start of Media", maxmedia - - for cabname, count in cab_and_filecount: - stream = "merged%d" % maxmedia - msilib.add_data(db, "Media", - [(maxmedia+1, maxmedia+count, None, "#"+stream, None, None)]) - msilib.add_stream(db, stream, cabname) - os.unlink(cabname) - maxmedia += count - # The merge module sets ALLUSERS to 1 in the property table. - # This is undesired; delete that - v = db.OpenView("DELETE FROM Property WHERE Property='ALLUSERS'") - v.Execute(None) - v.Close() - db.Commit() - -merge(msiname, "SharedCRT", "TARGETDIR", modules) - -# certname (from config.py) should be (a substring of) -# the certificate subject, e.g. "Python Software Foundation" -if certname: - os.system('signtool sign /n "%s" ' - '/t http://timestamp.verisign.com/scripts/timestamp.dll ' - '/d "Python %s" ' - '%s' % (certname, full_current_version, msiname)) - -if pdbzip: - build_pdbzip() diff --git a/Tools/msi/msi.targets b/Tools/msi/msi.targets new file mode 100644 index 000000000000..b507dc3a8367 --- /dev/null +++ b/Tools/msi/msi.targets @@ -0,0 +1,62 @@ + + + + + + <_FileListTarget>$(IntermediateOutputPath)$(MSBuildProjectName).g.csv + <_InstallFilesTarget>$(IntermediateOutputPath)$(MSBuildProjectName).g.wxs + + + + + <_Source>%(Source)$([msbuild]::MakeRelative(%(SourceBase), %(FullPath))) + <_Target>%(Target_)$([msbuild]::MakeRelative(%(TargetBase), %(FullPath))) + + + + + + + + + + + + + + + <_Content>$([System.IO.File]::ReadAllText(%(WxlTemplate.FullPath)).Replace(`{{ShortVersion}}`, `$(MajorVersionNumber).$(MinorVersionNumber)`).Replace(`{{LongVersion}}`, `$(PythonVersion)`).Replace(`{{Bitness}}`, `$(Bitness)`)) + <_ExistingContent Condition="Exists('$(IntermediateOutputPath)%(WxlTemplate.Filename).wxl')">$([System.IO.File]::ReadAllText($(IntermediateOutputPath)%(WxlTemplate.Filename).wxl)) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/msilib.py b/Tools/msi/msilib.py deleted file mode 100644 index c208b9107494..000000000000 --- a/Tools/msi/msilib.py +++ /dev/null @@ -1,679 +0,0 @@ -# Microsoft Installer Library -# (C) 2003 Martin v. Loewis - -import win32com.client.gencache -import win32com.client -import pythoncom, pywintypes -from win32com.client import constants -import re, string, os, sets, glob, subprocess, sys, _winreg, struct, _msi - -try: - basestring -except NameError: - basestring = (str, unicode) - -# Partially taken from Wine -datasizemask= 0x00ff -type_valid= 0x0100 -type_localizable= 0x0200 - -typemask= 0x0c00 -type_long= 0x0000 -type_short= 0x0400 -type_string= 0x0c00 -type_binary= 0x0800 - -type_nullable= 0x1000 -type_key= 0x2000 -# XXX temporary, localizable? -knownbits = datasizemask | type_valid | type_localizable | \ - typemask | type_nullable | type_key - -# Summary Info Property IDs -PID_CODEPAGE=1 -PID_TITLE=2 -PID_SUBJECT=3 -PID_AUTHOR=4 -PID_KEYWORDS=5 -PID_COMMENTS=6 -PID_TEMPLATE=7 -PID_LASTAUTHOR=8 -PID_REVNUMBER=9 -PID_LASTPRINTED=11 -PID_CREATE_DTM=12 -PID_LASTSAVE_DTM=13 -PID_PAGECOUNT=14 -PID_WORDCOUNT=15 -PID_CHARCOUNT=16 -PID_APPNAME=18 -PID_SECURITY=19 - -def reset(): - global _directories - _directories = sets.Set() - -def EnsureMSI(): - win32com.client.gencache.EnsureModule('{000C1092-0000-0000-C000-000000000046}', 1033, 1, 0) - -def EnsureMSM(): - try: - win32com.client.gencache.EnsureModule('{0ADDA82F-2C26-11D2-AD65-00A0C9AF11A6}', 0, 1, 0) - except pywintypes.com_error: - win32com.client.gencache.EnsureModule('{0ADDA82F-2C26-11D2-AD65-00A0C9AF11A6}', 0, 2, 0) - -_Installer=None -def MakeInstaller(): - global _Installer - if _Installer is None: - EnsureMSI() - _Installer = win32com.client.Dispatch('WindowsInstaller.Installer', - resultCLSID='{000C1090-0000-0000-C000-000000000046}') - return _Installer - -_Merge=None -def MakeMerge2(): - global _Merge - if _Merge is None: - EnsureMSM() - _Merge = win32com.client.Dispatch("Msm.Merge2.1") - return _Merge - -class Table: - def __init__(self, name): - self.name = name - self.fields = [] - - def add_field(self, index, name, type): - self.fields.append((index,name,type)) - - def sql(self): - fields = [] - keys = [] - self.fields.sort() - fields = [None]*len(self.fields) - for index, name, type in self.fields: - index -= 1 - unk = type & ~knownbits - if unk: - print "%s.%s unknown bits %x" % (self.name, name, unk) - size = type & datasizemask - dtype = type & typemask - if dtype == type_string: - if size: - tname="CHAR(%d)" % size - else: - tname="CHAR" - elif dtype == type_short: - assert size==2 - tname = "SHORT" - elif dtype == type_long: - assert size==4 - tname="LONG" - elif dtype == type_binary: - assert size==0 - tname="OBJECT" - else: - tname="unknown" - print "%s.%sunknown integer type %d" % (self.name, name, size) - if type & type_nullable: - flags = "" - else: - flags = " NOT NULL" - if type & type_localizable: - flags += " LOCALIZABLE" - fields[index] = "`%s` %s%s" % (name, tname, flags) - if type & type_key: - keys.append("`%s`" % name) - fields = ", ".join(fields) - keys = ", ".join(keys) - return "CREATE TABLE %s (%s PRIMARY KEY %s)" % (self.name, fields, keys) - - def create(self, db): - v = db.OpenView(self.sql()) - v.Execute(None) - v.Close() - -class Binary: - def __init__(self, fname): - self.name = fname - def __repr__(self): - return 'msilib.Binary(os.path.join(dirname,"%s"))' % self.name - -def gen_schema(destpath, schemapath): - d = MakeInstaller() - schema = d.OpenDatabase(schemapath, - win32com.client.constants.msiOpenDatabaseModeReadOnly) - - # XXX ORBER BY - v=schema.OpenView("SELECT * FROM _Columns") - curtable=None - tables = [] - v.Execute(None) - f = open(destpath, "wt") - f.write("from msilib import Table\n") - while 1: - r=v.Fetch() - if not r:break - name=r.StringData(1) - if curtable != name: - f.write("\n%s = Table('%s')\n" % (name,name)) - curtable = name - tables.append(name) - f.write("%s.add_field(%d,'%s',%d)\n" % - (name, r.IntegerData(2), r.StringData(3), r.IntegerData(4))) - v.Close() - - f.write("\ntables=[%s]\n\n" % (", ".join(tables))) - - # Fill the _Validation table - f.write("_Validation_records = [\n") - v = schema.OpenView("SELECT * FROM _Validation") - v.Execute(None) - while 1: - r = v.Fetch() - if not r:break - # Table, Column, Nullable - f.write("(%s,%s,%s," % - (`r.StringData(1)`, `r.StringData(2)`, `r.StringData(3)`)) - def put_int(i): - if r.IsNull(i):f.write("None, ") - else:f.write("%d," % r.IntegerData(i)) - def put_str(i): - if r.IsNull(i):f.write("None, ") - else:f.write("%s," % `r.StringData(i)`) - put_int(4) # MinValue - put_int(5) # MaxValue - put_str(6) # KeyTable - put_int(7) # KeyColumn - put_str(8) # Category - put_str(9) # Set - put_str(10)# Description - f.write("),\n") - f.write("]\n\n") - - f.close() - -def gen_sequence(destpath, msipath): - dir = os.path.dirname(destpath) - d = MakeInstaller() - seqmsi = d.OpenDatabase(msipath, - win32com.client.constants.msiOpenDatabaseModeReadOnly) - - v = seqmsi.OpenView("SELECT * FROM _Tables"); - v.Execute(None) - f = open(destpath, "w") - print >>f, "import msilib,os;dirname=os.path.dirname(__file__)" - tables = [] - while 1: - r = v.Fetch() - if not r:break - table = r.StringData(1) - tables.append(table) - f.write("%s = [\n" % table) - v1 = seqmsi.OpenView("SELECT * FROM `%s`" % table) - v1.Execute(None) - info = v1.ColumnInfo(constants.msiColumnInfoTypes) - while 1: - r = v1.Fetch() - if not r:break - rec = [] - for i in range(1,r.FieldCount+1): - if r.IsNull(i): - rec.append(None) - elif info.StringData(i)[0] in "iI": - rec.append(r.IntegerData(i)) - elif info.StringData(i)[0] in "slSL": - rec.append(r.StringData(i)) - elif info.StringData(i)[0]=="v": - size = r.DataSize(i) - bytes = r.ReadStream(i, size, constants.msiReadStreamBytes) - bytes = bytes.encode("latin-1") # binary data represented "as-is" - if table == "Binary": - fname = rec[0]+".bin" - open(os.path.join(dir,fname),"wb").write(bytes) - rec.append(Binary(fname)) - else: - rec.append(bytes) - else: - raise "Unsupported column type", info.StringData(i) - f.write(repr(tuple(rec))+",\n") - v1.Close() - f.write("]\n\n") - v.Close() - f.write("tables=%s\n" % repr(map(str,tables))) - f.close() - -class _Unspecified:pass -def change_sequence(seq, action, seqno=_Unspecified, cond = _Unspecified): - "Change the sequence number of an action in a sequence list" - for i in range(len(seq)): - if seq[i][0] == action: - if cond is _Unspecified: - cond = seq[i][1] - if seqno is _Unspecified: - seqno = seq[i][2] - seq[i] = (action, cond, seqno) - return - raise ValueError, "Action not found in sequence" - -def add_data(db, table, values): - d = MakeInstaller() - v = db.OpenView("SELECT * FROM `%s`" % table) - count = v.ColumnInfo(0).FieldCount - r = d.CreateRecord(count) - for value in values: - assert len(value) == count, value - for i in range(count): - field = value[i] - if isinstance(field, (int, long)): - r.SetIntegerData(i+1,field) - elif isinstance(field, basestring): - r.SetStringData(i+1,field) - elif field is None: - pass - elif isinstance(field, Binary): - r.SetStream(i+1, field.name) - else: - raise TypeError, "Unsupported type %s" % field.__class__.__name__ - v.Modify(win32com.client.constants.msiViewModifyInsert, r) - r.ClearData() - v.Close() - -def add_stream(db, name, path): - d = MakeInstaller() - v = db.OpenView("INSERT INTO _Streams (Name, Data) VALUES ('%s', ?)" % name) - r = d.CreateRecord(1) - r.SetStream(1, path) - v.Execute(r) - v.Close() - -def init_database(name, schema, - ProductName, ProductCode, ProductVersion, - Manufacturer, - request_uac = False): - try: - os.unlink(name) - except OSError: - pass - ProductCode = ProductCode.upper() - d = MakeInstaller() - # Create the database - db = d.OpenDatabase(name, - win32com.client.constants.msiOpenDatabaseModeCreate) - # Create the tables - for t in schema.tables: - t.create(db) - # Fill the validation table - add_data(db, "_Validation", schema._Validation_records) - # Initialize the summary information, allowing at most 20 properties - si = db.GetSummaryInformation(20) - si.SetProperty(PID_TITLE, "Installation Database") - si.SetProperty(PID_SUBJECT, ProductName) - si.SetProperty(PID_AUTHOR, Manufacturer) - si.SetProperty(PID_TEMPLATE, msi_type) - si.SetProperty(PID_REVNUMBER, gen_uuid()) - if request_uac: - wc = 2 # long file names, compressed, original media - else: - wc = 2 | 8 # +never invoke UAC - si.SetProperty(PID_WORDCOUNT, wc) - si.SetProperty(PID_PAGECOUNT, 200) - si.SetProperty(PID_APPNAME, "Python MSI Library") - # XXX more properties - si.Persist() - add_data(db, "Property", [ - ("ProductName", ProductName), - ("ProductCode", ProductCode), - ("ProductVersion", ProductVersion), - ("Manufacturer", Manufacturer), - ("ProductLanguage", "1033")]) - db.Commit() - return db - -def add_tables(db, module): - for table in module.tables: - add_data(db, table, getattr(module, table)) - -def make_id(str): - #str = str.replace(".", "_") # colons are allowed - str = str.replace(" ", "_") - str = str.replace("-", "_") - str = str.replace("+", "_") - if str[0] in string.digits: - str = "_"+str - assert re.match("^[A-Za-z_][A-Za-z0-9_.]*$", str), "FILE"+str - return str - -def gen_uuid(): - return str(pythoncom.CreateGuid()) - -class CAB: - def __init__(self, name): - self.name = name - self.files = [] - self.filenames = sets.Set() - self.index = 0 - - def gen_id(self, dir, file): - logical = _logical = make_id(file) - pos = 1 - while logical in self.filenames: - logical = "%s.%d" % (_logical, pos) - pos += 1 - self.filenames.add(logical) - return logical - - def append(self, full, file, logical = None): - if os.path.isdir(full): - return - if not logical: - logical = self.gen_id(dir, file) - self.index += 1 - self.files.append((full, logical)) - return self.index, logical - - def commit(self, db): - try: - os.unlink(self.name+".cab") - except OSError: - pass - _msi.FCICreate(self.name+".cab", self.files) - add_data(db, "Media", - [(1, self.index, None, "#"+self.name, None, None)]) - add_stream(db, self.name, self.name+".cab") - os.unlink(self.name+".cab") - db.Commit() - -_directories = sets.Set() -class Directory: - def __init__(self, db, cab, basedir, physical, _logical, default, componentflags=None): - """Create a new directory in the Directory table. There is a current component - at each point in time for the directory, which is either explicitly created - through start_component, or implicitly when files are added for the first - time. Files are added into the current component, and into the cab file. - To create a directory, a base directory object needs to be specified (can be - None), the path to the physical directory, and a logical directory name. - Default specifies the DefaultDir slot in the directory table. componentflags - specifies the default flags that new components get.""" - index = 1 - _logical = make_id(_logical) - logical = _logical - while logical in _directories: - logical = "%s%d" % (_logical, index) - index += 1 - _directories.add(logical) - self.db = db - self.cab = cab - self.basedir = basedir - self.physical = physical - self.logical = logical - self.component = None - self.short_names = {} - self.ids = sets.Set() - self.keyfiles = {} - self.componentflags = componentflags - if basedir: - self.absolute = os.path.join(basedir.absolute, physical) - blogical = basedir.logical - else: - self.absolute = physical - blogical = None - # initially assume that all files in this directory are unpackaged - # as files from self.absolute get added, this set is reduced - self.unpackaged_files = set() - for f in os.listdir(self.absolute): - if os.path.isfile(os.path.join(self.absolute, f)): - self.unpackaged_files.add(f) - add_data(db, "Directory", [(logical, blogical, default)]) - - def start_component(self, component = None, feature = None, flags = None, keyfile = None, uuid=None): - """Add an entry to the Component table, and make this component the current for this - directory. If no component name is given, the directory name is used. If no feature - is given, the current feature is used. If no flags are given, the directory's default - flags are used. If no keyfile is given, the KeyPath is left null in the Component - table.""" - if flags is None: - flags = self.componentflags - if uuid is None: - uuid = gen_uuid() - else: - uuid = uuid.upper() - if component is None: - component = self.logical - self.component = component - if Win64: - flags |= 256 - if keyfile: - keyid = self.cab.gen_id(self.absolute, keyfile) - self.keyfiles[keyfile] = keyid - else: - keyid = None - add_data(self.db, "Component", - [(component, uuid, self.logical, flags, None, keyid)]) - if feature is None: - feature = current_feature - add_data(self.db, "FeatureComponents", - [(feature.id, component)]) - - def make_short(self, file): - long = file - file = re.sub(r'[\?|><:/*"+,;=\[\]]', '_', file) # restrictions on short names - parts = file.split(".", 1) - if len(parts)>1: - suffix = parts[1].upper() - else: - suffix = '' - prefix = parts[0].upper() - if len(prefix) <= 8 and '.' not in suffix and len(suffix) <= 3: - if suffix: - file = prefix+"."+suffix - else: - file = prefix - assert file not in self.short_names, (file, self.short_names[file]) - else: - prefix = prefix[:6] - if suffix: - # last three characters of last suffix - suffix = suffix.rsplit('.')[-1][:3] - pos = 1 - while 1: - if suffix: - file = "%s~%d.%s" % (prefix, pos, suffix) - else: - file = "%s~%d" % (prefix, pos) - if file not in self.short_names: break - pos += 1 - assert pos < 10000 - if pos in (10, 100, 1000): - prefix = prefix[:-1] - self.short_names[file] = long - return file - - def add_file(self, file, src=None, version=None, language=None): - """Add a file to the current component of the directory, starting a new one - if there is no current component. By default, the file name in the source - and the file table will be identical. If the src file is specified, it is - interpreted relative to the current directory. Optionally, a version and a - language can be specified for the entry in the File table.""" - if not self.component: - self.start_component(self.logical, current_feature) - if not src: - # Allow relative paths for file if src is not specified - src = file - file = os.path.basename(file) - absolute = os.path.join(self.absolute, src) - if absolute.startswith(self.absolute): - # mark file as packaged - relative = absolute[len(self.absolute)+1:] - if relative in self.unpackaged_files: - self.unpackaged_files.remove(relative) - assert not re.search(r'[\?|><:/*]"', file) # restrictions on long names - if self.keyfiles.has_key(file): - logical = self.keyfiles[file] - else: - logical = None - sequence, logical = self.cab.append(absolute, file, logical) - assert logical not in self.ids - self.ids.add(logical) - short = self.make_short(file) - full = "%s|%s" % (short, file) - filesize = os.stat(absolute).st_size - # constants.msidbFileAttributesVital - # Compressed omitted, since it is the database default - # could add r/o, system, hidden - attributes = 512 - add_data(self.db, "File", - [(logical, self.component, full, filesize, version, - language, attributes, sequence)]) - if not version: - # Add hash if the file is not versioned - filehash = MakeInstaller().FileHash(absolute, 0) - add_data(self.db, "MsiFileHash", - [(logical, 0, filehash.IntegerData(1), - filehash.IntegerData(2), filehash.IntegerData(3), - filehash.IntegerData(4))]) - # Automatically remove .pyc/.pyo files on uninstall (2) - # XXX: adding so many RemoveFile entries makes installer unbelievably - # slow. So instead, we have to use wildcard remove entries - # if file.endswith(".py"): - # add_data(self.db, "RemoveFile", - # [(logical+"c", self.component, "%sC|%sc" % (short, file), - # self.logical, 2), - # (logical+"o", self.component, "%sO|%so" % (short, file), - # self.logical, 2)]) - - def glob(self, pattern, exclude = None): - """Add a list of files to the current component as specified in the - glob pattern. Individual files can be excluded in the exclude list.""" - files = glob.glob1(self.absolute, pattern) - for f in files: - if exclude and f in exclude: continue - self.add_file(f) - return files - - def remove_pyc(self): - "Remove .pyc/.pyo files from __pycache__ on uninstall" - directory = self.logical + "_pycache" - add_data(self.db, "Directory", [(directory, self.logical, "__PYCA~1|__pycache__")]) - flags = 256 if Win64 else 0 - add_data(self.db, "Component", - [(directory, gen_uuid(), directory, flags, None, None)]) - add_data(self.db, "FeatureComponents", [(current_feature.id, directory)]) - add_data(self.db, "CreateFolder", [(directory, directory)]) - add_data(self.db, "RemoveFile", - [(self.component, self.component, "*.*", directory, 2), - ]) - - def removefile(self, key, pattern): - "Add a RemoveFile entry" - add_data(self.db, "RemoveFile", [(self.component+key, self.component, pattern, self.logical, 2)]) - - -class Feature: - def __init__(self, db, id, title, desc, display, level = 1, - parent=None, directory = None, attributes=0): - self.id = id - if parent: - parent = parent.id - add_data(db, "Feature", - [(id, parent, title, desc, display, - level, directory, attributes)]) - def set_current(self): - global current_feature - current_feature = self - -class Control: - def __init__(self, dlg, name): - self.dlg = dlg - self.name = name - - def event(self, ev, arg, cond = "1", order = None): - add_data(self.dlg.db, "ControlEvent", - [(self.dlg.name, self.name, ev, arg, cond, order)]) - - def mapping(self, ev, attr): - add_data(self.dlg.db, "EventMapping", - [(self.dlg.name, self.name, ev, attr)]) - - def condition(self, action, condition): - add_data(self.dlg.db, "ControlCondition", - [(self.dlg.name, self.name, action, condition)]) - -class RadioButtonGroup(Control): - def __init__(self, dlg, name, property): - self.dlg = dlg - self.name = name - self.property = property - self.index = 1 - - def add(self, name, x, y, w, h, text, value = None): - if value is None: - value = name - add_data(self.dlg.db, "RadioButton", - [(self.property, self.index, value, - x, y, w, h, text, None)]) - self.index += 1 - -class Dialog: - def __init__(self, db, name, x, y, w, h, attr, title, first, default, cancel): - self.db = db - self.name = name - self.x, self.y, self.w, self.h = x,y,w,h - add_data(db, "Dialog", [(name, x,y,w,h,attr,title,first,default,cancel)]) - - def control(self, name, type, x, y, w, h, attr, prop, text, next, help): - add_data(self.db, "Control", - [(self.name, name, type, x, y, w, h, attr, prop, text, next, help)]) - return Control(self, name) - - def text(self, name, x, y, w, h, attr, text): - return self.control(name, "Text", x, y, w, h, attr, None, - text, None, None) - - def bitmap(self, name, x, y, w, h, text): - return self.control(name, "Bitmap", x, y, w, h, 1, None, text, None, None) - - def line(self, name, x, y, w, h): - return self.control(name, "Line", x, y, w, h, 1, None, None, None, None) - - def pushbutton(self, name, x, y, w, h, attr, text, next): - return self.control(name, "PushButton", x, y, w, h, attr, None, text, next, None) - - def radiogroup(self, name, x, y, w, h, attr, prop, text, next): - add_data(self.db, "Control", - [(self.name, name, "RadioButtonGroup", - x, y, w, h, attr, prop, text, next, None)]) - return RadioButtonGroup(self, name, prop) - - def checkbox(self, name, x, y, w, h, attr, prop, text, next): - return self.control(name, "CheckBox", x, y, w, h, attr, prop, text, next, None) - -def pe_type(path): - header = open(path, "rb").read(1000) - # offset of PE header is at offset 0x3c - pe_offset = struct.unpack(" + + + {91C99298-8E2E-4422-A5AF-CC4FFF9A58D3} + 2.0 + path + Package + ICE71 + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/path/path.wxs b/Tools/msi/path/path.wxs new file mode 100644 index 000000000000..7e462e26e9c1 --- /dev/null +++ b/Tools/msi/path/path.wxs @@ -0,0 +1,35 @@ + + + + + + + + + + + NOT ALLUSERS=1 + + + + + + + + + + ALLUSERS=1 + + + + + + + + + + + + + + diff --git a/Tools/msi/path/path_en-US.wxl b/Tools/msi/path/path_en-US.wxl new file mode 100644 index 000000000000..33a7886fe2d6 --- /dev/null +++ b/Tools/msi/path/path_en-US.wxl @@ -0,0 +1,6 @@ + + + Add to Path + Path + No !(loc.ProductName) installation was detected. + diff --git a/Tools/msi/pip/pip.wixproj b/Tools/msi/pip/pip.wixproj new file mode 100644 index 000000000000..718c02c032b7 --- /dev/null +++ b/Tools/msi/pip/pip.wixproj @@ -0,0 +1,19 @@ + + + + {91C99298-8E2E-4422-A5AF-CC4FFF9A58D3} + 2.0 + pip + Package + ICE71 + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/pip/pip.wxs b/Tools/msi/pip/pip.wxs new file mode 100644 index 000000000000..4c3dc59ec3b1 --- /dev/null +++ b/Tools/msi/pip/pip.wxs @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + PYTHON_EXE + + + + + + + + + + + + + + + + + + + (&DefaultFeature=3) AND NOT (!DefaultFeature=3) + (&DefaultFeature=2) AND (!DefaultFeature=3) + + UpdatePip + + + + diff --git a/Tools/msi/pip/pip_en-US.wxl b/Tools/msi/pip/pip_en-US.wxl new file mode 100644 index 000000000000..cd0d9edf3a6b --- /dev/null +++ b/Tools/msi/pip/pip_en-US.wxl @@ -0,0 +1,6 @@ + + + pip Bootstrap + pip + No !(loc.ProductName) installation was detected. + diff --git a/Tools/msi/schema.py b/Tools/msi/schema.py deleted file mode 100644 index 1f72e5ac78b7..000000000000 --- a/Tools/msi/schema.py +++ /dev/null @@ -1,1007 +0,0 @@ -from msilib import Table - -_Validation = Table('_Validation') -_Validation.add_field(1,'Table',11552) -_Validation.add_field(2,'Column',11552) -_Validation.add_field(3,'Nullable',3332) -_Validation.add_field(4,'MinValue',4356) -_Validation.add_field(5,'MaxValue',4356) -_Validation.add_field(6,'KeyTable',7679) -_Validation.add_field(7,'KeyColumn',5378) -_Validation.add_field(8,'Category',7456) -_Validation.add_field(9,'Set',7679) -_Validation.add_field(10,'Description',7679) - -ActionText = Table('ActionText') -ActionText.add_field(1,'Action',11592) -ActionText.add_field(2,'Description',7936) -ActionText.add_field(3,'Template',7936) - -AdminExecuteSequence = Table('AdminExecuteSequence') -AdminExecuteSequence.add_field(1,'Action',0x2DFF) -AdminExecuteSequence.add_field(2,'Condition',7679) -AdminExecuteSequence.add_field(3,'Sequence',5378) - -Condition = Table('Condition') -Condition.add_field(1,'Feature_',11558) -Condition.add_field(2,'Level',9474) -Condition.add_field(3,'Condition',7679) - -AdminUISequence = Table('AdminUISequence') -AdminUISequence.add_field(1,'Action',0x2DFF) -AdminUISequence.add_field(2,'Condition',7679) -AdminUISequence.add_field(3,'Sequence',5378) - -AdvtExecuteSequence = Table('AdvtExecuteSequence') -AdvtExecuteSequence.add_field(1,'Action',0x2DFF) -AdvtExecuteSequence.add_field(2,'Condition',7679) -AdvtExecuteSequence.add_field(3,'Sequence',5378) - -AdvtUISequence = Table('AdvtUISequence') -AdvtUISequence.add_field(1,'Action',11592) -AdvtUISequence.add_field(2,'Condition',7679) -AdvtUISequence.add_field(3,'Sequence',5378) - -AppId = Table('AppId') -AppId.add_field(1,'AppId',11558) -AppId.add_field(2,'RemoteServerName',7679) -AppId.add_field(3,'LocalService',7679) -AppId.add_field(4,'ServiceParameters',7679) -AppId.add_field(5,'DllSurrogate',7679) -AppId.add_field(6,'ActivateAtStorage',5378) -AppId.add_field(7,'RunAsInteractiveUser',5378) - -AppSearch = Table('AppSearch') -AppSearch.add_field(1,'Property',11592) -AppSearch.add_field(2,'Signature_',11592) - -Property = Table('Property') -Property.add_field(1,'Property',11592) -Property.add_field(2,'Value',3840) - -BBControl = Table('BBControl') -BBControl.add_field(1,'Billboard_',11570) -BBControl.add_field(2,'BBControl',11570) -BBControl.add_field(3,'Type',3378) -BBControl.add_field(4,'X',1282) -BBControl.add_field(5,'Y',1282) -BBControl.add_field(6,'Width',1282) -BBControl.add_field(7,'Height',1282) -BBControl.add_field(8,'Attributes',4356) -BBControl.add_field(9,'Text',7986) - -Billboard = Table('Billboard') -Billboard.add_field(1,'Billboard',11570) -Billboard.add_field(2,'Feature_',3366) -Billboard.add_field(3,'Action',7474) -Billboard.add_field(4,'Ordering',5378) - -Feature = Table('Feature') -Feature.add_field(1,'Feature',11558) -Feature.add_field(2,'Feature_Parent',7462) -Feature.add_field(3,'Title',8000) -Feature.add_field(4,'Description',8191) -Feature.add_field(5,'Display',5378) -Feature.add_field(6,'Level',1282) -Feature.add_field(7,'Directory_',0x1DFF) -Feature.add_field(8,'Attributes',1282) - -Binary = Table('Binary') -Binary.add_field(1,'Name',11592) -Binary.add_field(2,'Data',2304) - -BindImage = Table('BindImage') -BindImage.add_field(1,'File_',0x2DFF) -BindImage.add_field(2,'Path',7679) - -File = Table('File') -File.add_field(1,'File',0x2DFF) -File.add_field(2,'Component_',0xDFF) -File.add_field(3,'FileName',4095) -File.add_field(4,'FileSize',260) -File.add_field(5,'Version',0x1DFF) -File.add_field(6,'Language',7444) -File.add_field(7,'Attributes',5378) -File.add_field(8,'Sequence',1282) - -CCPSearch = Table('CCPSearch') -CCPSearch.add_field(1,'Signature_',11592) - -CheckBox = Table('CheckBox') -CheckBox.add_field(1,'Property',11592) -CheckBox.add_field(2,'Value',7488) - -Class = Table('Class') -Class.add_field(1,'CLSID',11558) -Class.add_field(2,'Context',11552) -Class.add_field(3,'Component_',0x2DFF) -Class.add_field(4,'ProgId_Default',7679) -Class.add_field(5,'Description',8191) -Class.add_field(6,'AppId_',7462) -Class.add_field(7,'FileTypeMask',7679) -Class.add_field(8,'Icon_',7496) -Class.add_field(9,'IconIndex',5378) -Class.add_field(10,'DefInprocHandler',7456) -Class.add_field(11,'Argument',7679) -Class.add_field(12,'Feature_',3366) -Class.add_field(13,'Attributes',5378) - -Component = Table('Component') -Component.add_field(1,'Component',0x2DFF) -Component.add_field(2,'ComponentId',7462) -Component.add_field(3,'Directory_',0xDFF) -Component.add_field(4,'Attributes',1282) -Component.add_field(5,'Condition',7679) -Component.add_field(6,'KeyPath',0x1DFF) - -Icon = Table('Icon') -Icon.add_field(1,'Name',11592) -Icon.add_field(2,'Data',2304) - -ProgId = Table('ProgId') -ProgId.add_field(1,'ProgId',11775) -ProgId.add_field(2,'ProgId_Parent',7679) -ProgId.add_field(3,'Class_',7462) -ProgId.add_field(4,'Description',8191) -ProgId.add_field(5,'Icon_',7496) -ProgId.add_field(6,'IconIndex',5378) - -ComboBox = Table('ComboBox') -ComboBox.add_field(1,'Property',11592) -ComboBox.add_field(2,'Order',9474) -ComboBox.add_field(3,'Value',3392) -ComboBox.add_field(4,'Text',8000) - -CompLocator = Table('CompLocator') -CompLocator.add_field(1,'Signature_',11592) -CompLocator.add_field(2,'ComponentId',3366) -CompLocator.add_field(3,'Type',5378) - -Complus = Table('Complus') -Complus.add_field(1,'Component_',0x2DFF) -Complus.add_field(2,'ExpType',13570) - -Directory = Table('Directory') -Directory.add_field(1,'Directory',0x2DFF) -Directory.add_field(2,'Directory_Parent',0x1DFF) -Directory.add_field(3,'DefaultDir',4095) - -Control = Table('Control') -Control.add_field(1,'Dialog_',11592) -Control.add_field(2,'Control',11570) -Control.add_field(3,'Type',3348) -Control.add_field(4,'X',1282) -Control.add_field(5,'Y',1282) -Control.add_field(6,'Width',1282) -Control.add_field(7,'Height',1282) -Control.add_field(8,'Attributes',4356) -Control.add_field(9,'Property',7474) -Control.add_field(10,'Text',7936) -Control.add_field(11,'Control_Next',7474) -Control.add_field(12,'Help',7986) - -Dialog = Table('Dialog') -Dialog.add_field(1,'Dialog',11592) -Dialog.add_field(2,'HCentering',1282) -Dialog.add_field(3,'VCentering',1282) -Dialog.add_field(4,'Width',1282) -Dialog.add_field(5,'Height',1282) -Dialog.add_field(6,'Attributes',4356) -Dialog.add_field(7,'Title',8064) -Dialog.add_field(8,'Control_First',3378) -Dialog.add_field(9,'Control_Default',7474) -Dialog.add_field(10,'Control_Cancel',7474) - -ControlCondition = Table('ControlCondition') -ControlCondition.add_field(1,'Dialog_',11592) -ControlCondition.add_field(2,'Control_',11570) -ControlCondition.add_field(3,'Action',11570) -ControlCondition.add_field(4,'Condition',11775) - -ControlEvent = Table('ControlEvent') -ControlEvent.add_field(1,'Dialog_',11592) -ControlEvent.add_field(2,'Control_',11570) -ControlEvent.add_field(3,'Event',11570) -ControlEvent.add_field(4,'Argument',11775) -ControlEvent.add_field(5,'Condition',15871) -ControlEvent.add_field(6,'Ordering',5378) - -CreateFolder = Table('CreateFolder') -CreateFolder.add_field(1,'Directory_',0x2DFF) -CreateFolder.add_field(2,'Component_',0x2DFF) - -CustomAction = Table('CustomAction') -CustomAction.add_field(1,'Action',0x2DFF) -CustomAction.add_field(2,'Type',1282) -CustomAction.add_field(3,'Source',0x1DFF) -CustomAction.add_field(4,'Target',7679) - -DrLocator = Table('DrLocator') -DrLocator.add_field(1,'Signature_',11592) -DrLocator.add_field(2,'Parent',15688) -DrLocator.add_field(3,'Path',15871) -DrLocator.add_field(4,'Depth',5378) - -DuplicateFile = Table('DuplicateFile') -DuplicateFile.add_field(1,'FileKey',11592) -DuplicateFile.add_field(2,'Component_',0xDFF) -DuplicateFile.add_field(3,'File_',0xDFF) -DuplicateFile.add_field(4,'DestName',8191) -DuplicateFile.add_field(5,'DestFolder',7496) - -Environment = Table('Environment') -Environment.add_field(1,'Environment',11592) -Environment.add_field(2,'Name',4095) -Environment.add_field(3,'Value',8191) -Environment.add_field(4,'Component_',0xDFF) - -Error = Table('Error') -Error.add_field(1,'Error',9474) -Error.add_field(2,'Message',7936) - -EventMapping = Table('EventMapping') -EventMapping.add_field(1,'Dialog_',11592) -EventMapping.add_field(2,'Control_',11570) -EventMapping.add_field(3,'Event',11570) -EventMapping.add_field(4,'Attribute',3378) - -Extension = Table('Extension') -Extension.add_field(1,'Extension',11775) -Extension.add_field(2,'Component_',0x2DFF) -Extension.add_field(3,'ProgId_',7679) -Extension.add_field(4,'MIME_',7488) -Extension.add_field(5,'Feature_',3366) - -MIME = Table('MIME') -MIME.add_field(1,'ContentType',11584) -MIME.add_field(2,'Extension_',3583) -MIME.add_field(3,'CLSID',7462) - -FeatureComponents = Table('FeatureComponents') -FeatureComponents.add_field(1,'Feature_',11558) -FeatureComponents.add_field(2,'Component_',0x2DFF) - -FileSFPCatalog = Table('FileSFPCatalog') -FileSFPCatalog.add_field(1,'File_',0x2DFF) -FileSFPCatalog.add_field(2,'SFPCatalog_',11775) - -SFPCatalog = Table('SFPCatalog') -SFPCatalog.add_field(1,'SFPCatalog',11775) -SFPCatalog.add_field(2,'Catalog',2304) -SFPCatalog.add_field(3,'Dependency',7424) - -Font = Table('Font') -Font.add_field(1,'File_',0x2DFF) -Font.add_field(2,'FontTitle',7552) - -IniFile = Table('IniFile') -IniFile.add_field(1,'IniFile',11592) -IniFile.add_field(2,'FileName',4095) -IniFile.add_field(3,'DirProperty',7496) -IniFile.add_field(4,'Section',3936) -IniFile.add_field(5,'Key',3968) -IniFile.add_field(6,'Value',4095) -IniFile.add_field(7,'Action',1282) -IniFile.add_field(8,'Component_',0xDFF) - -IniLocator = Table('IniLocator') -IniLocator.add_field(1,'Signature_',11592) -IniLocator.add_field(2,'FileName',3583) -IniLocator.add_field(3,'Section',3424) -IniLocator.add_field(4,'Key',3456) -IniLocator.add_field(5,'Field',5378) -IniLocator.add_field(6,'Type',5378) - -InstallExecuteSequence = Table('InstallExecuteSequence') -InstallExecuteSequence.add_field(1,'Action',0x2DFF) -InstallExecuteSequence.add_field(2,'Condition',7679) -InstallExecuteSequence.add_field(3,'Sequence',5378) - -InstallUISequence = Table('InstallUISequence') -InstallUISequence.add_field(1,'Action',0x2DFF) -InstallUISequence.add_field(2,'Condition',7679) -InstallUISequence.add_field(3,'Sequence',5378) - -IsolatedComponent = Table('IsolatedComponent') -IsolatedComponent.add_field(1,'Component_Shared',0x2DFF) -IsolatedComponent.add_field(2,'Component_Application',0x2DFF) - -LaunchCondition = Table('LaunchCondition') -LaunchCondition.add_field(1,'Condition',11775) -LaunchCondition.add_field(2,'Description',4095) - -ListBox = Table('ListBox') -ListBox.add_field(1,'Property',11592) -ListBox.add_field(2,'Order',9474) -ListBox.add_field(3,'Value',3392) -ListBox.add_field(4,'Text',8000) - -ListView = Table('ListView') -ListView.add_field(1,'Property',11592) -ListView.add_field(2,'Order',9474) -ListView.add_field(3,'Value',3392) -ListView.add_field(4,'Text',8000) -ListView.add_field(5,'Binary_',7496) - -LockPermissions = Table('LockPermissions') -LockPermissions.add_field(1,'LockObject',11592) -LockPermissions.add_field(2,'Table',11552) -LockPermissions.add_field(3,'Domain',15871) -LockPermissions.add_field(4,'User',11775) -LockPermissions.add_field(5,'Permission',4356) - -Media = Table('Media') -Media.add_field(1,'DiskId',9474) -Media.add_field(2,'LastSequence',1282) -Media.add_field(3,'DiskPrompt',8000) -Media.add_field(4,'Cabinet',7679) -Media.add_field(5,'VolumeLabel',7456) -Media.add_field(6,'Source',7496) - -MoveFile = Table('MoveFile') -MoveFile.add_field(1,'FileKey',11592) -MoveFile.add_field(2,'Component_',0xDFF) -MoveFile.add_field(3,'SourceName',8191) -MoveFile.add_field(4,'DestName',8191) -MoveFile.add_field(5,'SourceFolder',7496) -MoveFile.add_field(6,'DestFolder',3400) -MoveFile.add_field(7,'Options',1282) - -MsiAssembly = Table('MsiAssembly') -MsiAssembly.add_field(1,'Component_',0x2DFF) -MsiAssembly.add_field(2,'Feature_',3366) -MsiAssembly.add_field(3,'File_Manifest',0x1DFF) -MsiAssembly.add_field(4,'File_Application',0x1DFF) -MsiAssembly.add_field(5,'Attributes',5378) - -MsiAssemblyName = Table('MsiAssemblyName') -MsiAssemblyName.add_field(1,'Component_',0x2DFF) -MsiAssemblyName.add_field(2,'Name',11775) -MsiAssemblyName.add_field(3,'Value',3583) - -MsiDigitalCertificate = Table('MsiDigitalCertificate') -MsiDigitalCertificate.add_field(1,'DigitalCertificate',11592) -MsiDigitalCertificate.add_field(2,'CertData',2304) - -MsiDigitalSignature = Table('MsiDigitalSignature') -MsiDigitalSignature.add_field(1,'Table',11552) -MsiDigitalSignature.add_field(2,'SignObject',11592) -MsiDigitalSignature.add_field(3,'DigitalCertificate_',3400) -MsiDigitalSignature.add_field(4,'Hash',6400) - -MsiFileHash = Table('MsiFileHash') -MsiFileHash.add_field(1,'File_',0x2DFF) -MsiFileHash.add_field(2,'Options',1282) -MsiFileHash.add_field(3,'HashPart1',260) -MsiFileHash.add_field(4,'HashPart2',260) -MsiFileHash.add_field(5,'HashPart3',260) -MsiFileHash.add_field(6,'HashPart4',260) - -MsiPatchHeaders = Table('MsiPatchHeaders') -MsiPatchHeaders.add_field(1,'StreamRef',11558) -MsiPatchHeaders.add_field(2,'Header',2304) - -ODBCAttribute = Table('ODBCAttribute') -ODBCAttribute.add_field(1,'Driver_',11592) -ODBCAttribute.add_field(2,'Attribute',11560) -ODBCAttribute.add_field(3,'Value',8191) - -ODBCDriver = Table('ODBCDriver') -ODBCDriver.add_field(1,'Driver',11592) -ODBCDriver.add_field(2,'Component_',0xDFF) -ODBCDriver.add_field(3,'Description',3583) -ODBCDriver.add_field(4,'File_',0xDFF) -ODBCDriver.add_field(5,'File_Setup',0x1DFF) - -ODBCDataSource = Table('ODBCDataSource') -ODBCDataSource.add_field(1,'DataSource',0x2DFF) -ODBCDataSource.add_field(2,'Component_',0xDFF) -ODBCDataSource.add_field(3,'Description',3583) -ODBCDataSource.add_field(4,'DriverDescription',3583) -ODBCDataSource.add_field(5,'Registration',1282) - -ODBCSourceAttribute = Table('ODBCSourceAttribute') -ODBCSourceAttribute.add_field(1,'DataSource_',11592) -ODBCSourceAttribute.add_field(2,'Attribute',11552) -ODBCSourceAttribute.add_field(3,'Value',8191) - -ODBCTranslator = Table('ODBCTranslator') -ODBCTranslator.add_field(1,'Translator',11592) -ODBCTranslator.add_field(2,'Component_',0xDFF) -ODBCTranslator.add_field(3,'Description',3583) -ODBCTranslator.add_field(4,'File_',0xDFF) -ODBCTranslator.add_field(5,'File_Setup',0x1DFF) - -Patch = Table('Patch') -Patch.add_field(1,'File_',11592) -Patch.add_field(2,'Sequence',9474) -Patch.add_field(3,'PatchSize',260) -Patch.add_field(4,'Attributes',1282) -Patch.add_field(5,'Header',6400) -Patch.add_field(6,'StreamRef_',7462) - -PatchPackage = Table('PatchPackage') -PatchPackage.add_field(1,'PatchId',11558) -PatchPackage.add_field(2,'Media_',1282) - -PublishComponent = Table('PublishComponent') -PublishComponent.add_field(1,'ComponentId',11558) -PublishComponent.add_field(2,'Qualifier',11775) -PublishComponent.add_field(3,'Component_',0x2DFF) -PublishComponent.add_field(4,'AppData',8191) -PublishComponent.add_field(5,'Feature_',3366) - -RadioButton = Table('RadioButton') -RadioButton.add_field(1,'Property',11592) -RadioButton.add_field(2,'Order',9474) -RadioButton.add_field(3,'Value',3392) -RadioButton.add_field(4,'X',1282) -RadioButton.add_field(5,'Y',1282) -RadioButton.add_field(6,'Width',1282) -RadioButton.add_field(7,'Height',1282) -RadioButton.add_field(8,'Text',8000) -RadioButton.add_field(9,'Help',7986) - -Registry = Table('Registry') -Registry.add_field(1,'Registry',0x2DFF) -Registry.add_field(2,'Root',1282) -Registry.add_field(3,'Key',4095) -Registry.add_field(4,'Name',8191) -Registry.add_field(5,'Value',7936) -Registry.add_field(6,'Component_',0xDFF) - -RegLocator = Table('RegLocator') -RegLocator.add_field(1,'Signature_',11592) -RegLocator.add_field(2,'Root',1282) -RegLocator.add_field(3,'Key',3583) -RegLocator.add_field(4,'Name',7679) -RegLocator.add_field(5,'Type',5378) - -RemoveFile = Table('RemoveFile') -RemoveFile.add_field(1,'FileKey',11592) -RemoveFile.add_field(2,'Component_',0xDFF) -RemoveFile.add_field(3,'FileName',8191) -RemoveFile.add_field(4,'DirProperty',3400) -RemoveFile.add_field(5,'InstallMode',1282) - -RemoveIniFile = Table('RemoveIniFile') -RemoveIniFile.add_field(1,'RemoveIniFile',11592) -RemoveIniFile.add_field(2,'FileName',4095) -RemoveIniFile.add_field(3,'DirProperty',7496) -RemoveIniFile.add_field(4,'Section',3936) -RemoveIniFile.add_field(5,'Key',3968) -RemoveIniFile.add_field(6,'Value',8191) -RemoveIniFile.add_field(7,'Action',1282) -RemoveIniFile.add_field(8,'Component_',0xDFF) - -RemoveRegistry = Table('RemoveRegistry') -RemoveRegistry.add_field(1,'RemoveRegistry',11592) -RemoveRegistry.add_field(2,'Root',1282) -RemoveRegistry.add_field(3,'Key',4095) -RemoveRegistry.add_field(4,'Name',8191) -RemoveRegistry.add_field(5,'Component_',0xDFF) - -ReserveCost = Table('ReserveCost') -ReserveCost.add_field(1,'ReserveKey',11592) -ReserveCost.add_field(2,'Component_',0xDFF) -ReserveCost.add_field(3,'ReserveFolder',7496) -ReserveCost.add_field(4,'ReserveLocal',260) -ReserveCost.add_field(5,'ReserveSource',260) - -SelfReg = Table('SelfReg') -SelfReg.add_field(1,'File_',0x2DFF) -SelfReg.add_field(2,'Cost',5378) - -ServiceControl = Table('ServiceControl') -ServiceControl.add_field(1,'ServiceControl',11592) -ServiceControl.add_field(2,'Name',4095) -ServiceControl.add_field(3,'Event',1282) -ServiceControl.add_field(4,'Arguments',8191) -ServiceControl.add_field(5,'Wait',5378) -ServiceControl.add_field(6,'Component_',0xDFF) - -ServiceInstall = Table('ServiceInstall') -ServiceInstall.add_field(1,'ServiceInstall',11592) -ServiceInstall.add_field(2,'Name',3583) -ServiceInstall.add_field(3,'DisplayName',8191) -ServiceInstall.add_field(4,'ServiceType',260) -ServiceInstall.add_field(5,'StartType',260) -ServiceInstall.add_field(6,'ErrorControl',260) -ServiceInstall.add_field(7,'LoadOrderGroup',7679) -ServiceInstall.add_field(8,'Dependencies',7679) -ServiceInstall.add_field(9,'StartName',7679) -ServiceInstall.add_field(10,'Password',7679) -ServiceInstall.add_field(11,'Arguments',7679) -ServiceInstall.add_field(12,'Component_',0xDFF) -ServiceInstall.add_field(13,'Description',8191) - -Shortcut = Table('Shortcut') -Shortcut.add_field(1,'Shortcut',11592) -Shortcut.add_field(2,'Directory_',0xDFF) -Shortcut.add_field(3,'Name',3968) -Shortcut.add_field(4,'Component_',0xDFF) -Shortcut.add_field(5,'Target',3400) -Shortcut.add_field(6,'Arguments',7679) -Shortcut.add_field(7,'Description',8191) -Shortcut.add_field(8,'Hotkey',5378) -Shortcut.add_field(9,'Icon_',7496) -Shortcut.add_field(10,'IconIndex',5378) -Shortcut.add_field(11,'ShowCmd',5378) -Shortcut.add_field(12,'WkDir',7496) - -Signature = Table('Signature') -Signature.add_field(1,'Signature',11592) -Signature.add_field(2,'FileName',3583) -Signature.add_field(3,'MinVersion',7444) -Signature.add_field(4,'MaxVersion',7444) -Signature.add_field(5,'MinSize',4356) -Signature.add_field(6,'MaxSize',4356) -Signature.add_field(7,'MinDate',4356) -Signature.add_field(8,'MaxDate',4356) -Signature.add_field(9,'Languages',7679) - -TextStyle = Table('TextStyle') -TextStyle.add_field(1,'TextStyle',11592) -TextStyle.add_field(2,'FaceName',3360) -TextStyle.add_field(3,'Size',1282) -TextStyle.add_field(4,'Color',4356) -TextStyle.add_field(5,'StyleBits',5378) - -TypeLib = Table('TypeLib') -TypeLib.add_field(1,'LibID',11558) -TypeLib.add_field(2,'Language',9474) -TypeLib.add_field(3,'Component_',0x2DFF) -TypeLib.add_field(4,'Version',4356) -TypeLib.add_field(5,'Description',8064) -TypeLib.add_field(6,'Directory_',0x1DFF) -TypeLib.add_field(7,'Feature_',3366) -TypeLib.add_field(8,'Cost',4356) - -UIText = Table('UIText') -UIText.add_field(1,'Key',11592) -UIText.add_field(2,'Text',8191) - -Upgrade = Table('Upgrade') -Upgrade.add_field(1,'UpgradeCode',11558) -Upgrade.add_field(2,'VersionMin',15636) -Upgrade.add_field(3,'VersionMax',15636) -Upgrade.add_field(4,'Language',15871) -Upgrade.add_field(5,'Attributes',8452) -Upgrade.add_field(6,'Remove',7679) -Upgrade.add_field(7,'ActionProperty',3400) - -Verb = Table('Verb') -Verb.add_field(1,'Extension_',11775) -Verb.add_field(2,'Verb',11552) -Verb.add_field(3,'Sequence',5378) -Verb.add_field(4,'Command',8191) -Verb.add_field(5,'Argument',8191) - -tables=[_Validation, ActionText, AdminExecuteSequence, Condition, AdminUISequence, AdvtExecuteSequence, AdvtUISequence, AppId, AppSearch, Property, BBControl, Billboard, Feature, Binary, BindImage, File, CCPSearch, CheckBox, Class, Component, Icon, ProgId, ComboBox, CompLocator, Complus, Directory, Control, Dialog, ControlCondition, ControlEvent, CreateFolder, CustomAction, DrLocator, DuplicateFile, Environment, Error, EventMapping, Extension, MIME, FeatureComponents, FileSFPCatalog, SFPCatalog, Font, IniFile, IniLocator, InstallExecuteSequence, InstallUISequence, IsolatedComponent, LaunchCondition, ListBox, ListView, LockPermissions, Media, MoveFile, MsiAssembly, MsiAssemblyName, MsiDigitalCertificate, MsiDigitalSignature, MsiFileHash, MsiPatchHeaders, ODBCAttribute, ODBCDriver, ODBCDataSource, ODBCSourceAttribute, ODBCTranslator, Patch, PatchPackage, PublishComponent, RadioButton, Registry, RegLocator, RemoveFile, RemoveIniFile, RemoveRegistry, ReserveCost, SelfReg, ServiceControl, ServiceInstall, Shortcut, Signature, TextStyle, TypeLib, UIText, Upgrade, Verb] - -_Validation_records = [ -(u'_Validation',u'Table',u'N',None, None, None, None, u'Identifier',None, u'Name of table',), -(u'_Validation',u'Column',u'N',None, None, None, None, u'Identifier',None, u'Name of column',), -(u'_Validation',u'Description',u'Y',None, None, None, None, u'Text',None, u'Description of column',), -(u'_Validation',u'Set',u'Y',None, None, None, None, u'Text',None, u'Set of values that are permitted',), -(u'_Validation',u'Category',u'Y',None, None, None, None, None, u'Text;Formatted;Template;Condition;Guid;Path;Version;Language;Identifier;Binary;UpperCase;LowerCase;Filename;Paths;AnyPath;WildCardFilename;RegPath;KeyFormatted;CustomSource;Property;Cabinet;Shortcut;URL',u'String category',), -(u'_Validation',u'KeyColumn',u'Y',1,32,None, None, None, None, u'Column to which foreign key connects',), -(u'_Validation',u'KeyTable',u'Y',None, None, None, None, u'Identifier',None, u'For foreign key, Name of table to which data must link',), -(u'_Validation',u'MaxValue',u'Y',-2147483647,2147483647,None, None, None, None, u'Maximum value allowed',), -(u'_Validation',u'MinValue',u'Y',-2147483647,2147483647,None, None, None, None, u'Minimum value allowed',), -(u'_Validation',u'Nullable',u'N',None, None, None, None, None, u'Y;N;@',u'Whether the column is nullable',), -(u'ActionText',u'Description',u'Y',None, None, None, None, u'Text',None, u'Localized description displayed in progress dialog and log when action is executing.',), -(u'ActionText',u'Action',u'N',None, None, None, None, u'Identifier',None, u'Name of action to be described.',), -(u'ActionText',u'Template',u'Y',None, None, None, None, u'Template',None, u'Optional localized format template used to format action data records for display during action execution.',), -(u'AdminExecuteSequence',u'Action',u'N',None, None, None, None, u'Identifier',None, u'Name of action to invoke, either in the engine or the handler DLL.',), -(u'AdminExecuteSequence',u'Condition',u'Y',None, None, None, None, u'Condition',None, u'Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.',), -(u'AdminExecuteSequence',u'Sequence',u'Y',-4,32767,None, None, None, None, u'Number that determines the sort order in which the actions are to be executed. Leave blank to suppress action.',), -(u'Condition',u'Condition',u'Y',None, None, None, None, u'Condition',None, u'Expression evaluated to determine if Level in the Feature table is to change.',), -(u'Condition',u'Feature_',u'N',None, None, u'Feature',1,u'Identifier',None, u'Reference to a Feature entry in Feature table.',), -(u'Condition',u'Level',u'N',0,32767,None, None, None, None, u'New selection Level to set in Feature table if Condition evaluates to TRUE.',), -(u'AdminUISequence',u'Action',u'N',None, None, None, None, u'Identifier',None, u'Name of action to invoke, either in the engine or the handler DLL.',), -(u'AdminUISequence',u'Condition',u'Y',None, None, None, None, u'Condition',None, u'Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.',), -(u'AdminUISequence',u'Sequence',u'Y',-4,32767,None, None, None, None, u'Number that determines the sort order in which the actions are to be executed. Leave blank to suppress action.',), -(u'AdvtExecuteSequence',u'Action',u'N',None, None, None, None, u'Identifier',None, u'Name of action to invoke, either in the engine or the handler DLL.',), -(u'AdvtExecuteSequence',u'Condition',u'Y',None, None, None, None, u'Condition',None, u'Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.',), -(u'AdvtExecuteSequence',u'Sequence',u'Y',-4,32767,None, None, None, None, u'Number that determines the sort order in which the actions are to be executed. Leave blank to suppress action.',), -(u'AdvtUISequence',u'Action',u'N',None, None, None, None, u'Identifier',None, u'Name of action to invoke, either in the engine or the handler DLL.',), -(u'AdvtUISequence',u'Condition',u'Y',None, None, None, None, u'Condition',None, u'Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.',), -(u'AdvtUISequence',u'Sequence',u'Y',-4,32767,None, None, None, None, u'Number that determines the sort order in which the actions are to be executed. Leave blank to suppress action.',), -(u'AppId',u'AppId',u'N',None, None, None, None, u'Guid',None, None, ), -(u'AppId',u'ActivateAtStorage',u'Y',0,1,None, None, None, None, None, ), -(u'AppId',u'DllSurrogate',u'Y',None, None, None, None, u'Text',None, None, ), -(u'AppId',u'LocalService',u'Y',None, None, None, None, u'Text',None, None, ), -(u'AppId',u'RemoteServerName',u'Y',None, None, None, None, u'Formatted',None, None, ), -(u'AppId',u'RunAsInteractiveUser',u'Y',0,1,None, None, None, None, None, ), -(u'AppId',u'ServiceParameters',u'Y',None, None, None, None, u'Text',None, None, ), -(u'AppSearch',u'Property',u'N',None, None, None, None, u'Identifier',None, u'The property associated with a Signature',), -(u'AppSearch',u'Signature_',u'N',None, None, u'Signature;RegLocator;IniLocator;DrLocator;CompLocator',1,u'Identifier',None, u'The Signature_ represents a unique file signature and is also the foreign key in the Signature, RegLocator, IniLocator, CompLocator and the DrLocator tables.',), -(u'Property',u'Property',u'N',None, None, None, None, u'Identifier',None, u'Name of property, uppercase if settable by launcher or loader.',), -(u'Property',u'Value',u'N',None, None, None, None, u'Text',None, u'String value for property. Never null or empty.',), -(u'BBControl',u'Type',u'N',None, None, None, None, u'Identifier',None, u'The type of the control.',), -(u'BBControl',u'Y',u'N',0,32767,None, None, None, None, u'Vertical coordinate of the upper left corner of the bounding rectangle of the control.',), -(u'BBControl',u'Text',u'Y',None, None, None, None, u'Text',None, u'A string used to set the initial text contained within a control (if appropriate).',), -(u'BBControl',u'BBControl',u'N',None, None, None, None, u'Identifier',None, u'Name of the control. This name must be unique within a billboard, but can repeat on different billboard.',), -(u'BBControl',u'Attributes',u'Y',0,2147483647,None, None, None, None, u'A 32-bit word that specifies the attribute flags to be applied to this control.',), -(u'BBControl',u'Billboard_',u'N',None, None, u'Billboard',1,u'Identifier',None, u'External key to the Billboard table, name of the billboard.',), -(u'BBControl',u'Height',u'N',0,32767,None, None, None, None, u'Height of the bounding rectangle of the control.',), -(u'BBControl',u'Width',u'N',0,32767,None, None, None, None, u'Width of the bounding rectangle of the control.',), -(u'BBControl',u'X',u'N',0,32767,None, None, None, None, u'Horizontal coordinate of the upper left corner of the bounding rectangle of the control.',), -(u'Billboard',u'Action',u'Y',None, None, None, None, u'Identifier',None, u'The name of an action. The billboard is displayed during the progress messages received from this action.',), -(u'Billboard',u'Billboard',u'N',None, None, None, None, u'Identifier',None, u'Name of the billboard.',), -(u'Billboard',u'Feature_',u'N',None, None, u'Feature',1,u'Identifier',None, u'An external key to the Feature Table. The billboard is shown only if this feature is being installed.',), -(u'Billboard',u'Ordering',u'Y',0,32767,None, None, None, None, u'A positive integer. If there is more than one billboard corresponding to an action they will be shown in the order defined by this column.',), -(u'Feature',u'Description',u'Y',None, None, None, None, u'Text',None, u'Longer descriptive text describing a visible feature item.',), -(u'Feature',u'Attributes',u'N',None, None, None, None, None, u'0;1;2;4;5;6;8;9;10;16;17;18;20;21;22;24;25;26;32;33;34;36;37;38;48;49;50;52;53;54',u'Feature attributes',), -(u'Feature',u'Feature',u'N',None, None, None, None, u'Identifier',None, u'Primary key used to identify a particular feature record.',), -(u'Feature',u'Directory_',u'Y',None, None, u'Directory',1,u'UpperCase',None, u'The name of the Directory that can be configured by the UI. A non-null value will enable the browse button.',), -(u'Feature',u'Level',u'N',0,32767,None, None, None, None, u'The install level at which record will be initially selected. An install level of 0 will disable an item and prevent its display.',), -(u'Feature',u'Title',u'Y',None, None, None, None, u'Text',None, u'Short text identifying a visible feature item.',), -(u'Feature',u'Display',u'Y',0,32767,None, None, None, None, u'Numeric sort order, used to force a specific display ordering.',), -(u'Feature',u'Feature_Parent',u'Y',None, None, u'Feature',1,u'Identifier',None, u'Optional key of a parent record in the same table. If the parent is not selected, then the record will not be installed. Null indicates a root item.',), -(u'Binary',u'Name',u'N',None, None, None, None, u'Identifier',None, u'Unique key identifying the binary data.',), -(u'Binary',u'Data',u'N',None, None, None, None, u'Binary',None, u'The unformatted binary data.',), -(u'BindImage',u'File_',u'N',None, None, u'File',1,u'Identifier',None, u'The index into the File table. This must be an executable file.',), -(u'BindImage',u'Path',u'Y',None, None, None, None, u'Paths',None, u'A list of ; delimited paths that represent the paths to be searched for the import DLLS. The list is usually a list of properties each enclosed within square brackets [] .',), -(u'File',u'Sequence',u'N',1,32767,None, None, None, None, u'Sequence with respect to the media images; order must track cabinet order.',), -(u'File',u'Attributes',u'Y',0,32767,None, None, None, None, u'Integer containing bit flags representing file attributes (with the decimal value of each bit position in parentheses)',), -(u'File',u'File',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized token, must match identifier in cabinet. For uncompressed files, this field is ignored.',), -(u'File',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key referencing Component that controls the file.',), -(u'File',u'FileName',u'N',None, None, None, None, u'Filename',None, u'File name used for installation, may be localized. This may contain a "short name|long name" pair.',), -(u'File',u'FileSize',u'N',0,2147483647,None, None, None, None, u'Size of file in bytes (long integer).',), -(u'File',u'Language',u'Y',None, None, None, None, u'Language',None, u'List of decimal language Ids, comma-separated if more than one.',), -(u'File',u'Version',u'Y',None, None, u'File',1,u'Version',None, u'Version string for versioned files; Blank for unversioned files.',), -(u'CCPSearch',u'Signature_',u'N',None, None, u'Signature;RegLocator;IniLocator;DrLocator;CompLocator',1,u'Identifier',None, u'The Signature_ represents a unique file signature and is also the foreign key in the Signature, RegLocator, IniLocator, CompLocator and the DrLocator tables.',), -(u'CheckBox',u'Property',u'N',None, None, None, None, u'Identifier',None, u'A named property to be tied to the item.',), -(u'CheckBox',u'Value',u'Y',None, None, None, None, u'Formatted',None, u'The value string associated with the item.',), -(u'Class',u'Description',u'Y',None, None, None, None, u'Text',None, u'Localized description for the Class.',), -(u'Class',u'Attributes',u'Y',None, 32767,None, None, None, None, u'Class registration attributes.',), -(u'Class',u'Feature_',u'N',None, None, u'Feature',1,u'Identifier',None, u'Required foreign key into the Feature Table, specifying the feature to validate or install in order for the CLSID factory to be operational.',), -(u'Class',u'AppId_',u'Y',None, None, u'AppId',1,u'Guid',None, u'Optional AppID containing DCOM information for associated application (string GUID).',), -(u'Class',u'Argument',u'Y',None, None, None, None, u'Formatted',None, u'optional argument for LocalServers.',), -(u'Class',u'CLSID',u'N',None, None, None, None, u'Guid',None, u'The CLSID of an OLE factory.',), -(u'Class',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Required foreign key into the Component Table, specifying the component for which to return a path when called through LocateComponent.',), -(u'Class',u'Context',u'N',None, None, None, None, u'Identifier',None, u'The numeric server context for this server. CLSCTX_xxxx',), -(u'Class',u'DefInprocHandler',u'Y',None, None, None, None, u'Filename',u'1;2;3',u'Optional default inproc handler. Only optionally provided if Context=CLSCTX_LOCAL_SERVER. Typically "ole32.dll" or "mapi32.dll"',), -(u'Class',u'FileTypeMask',u'Y',None, None, None, None, u'Text',None, u'Optional string containing information for the HKCRthis CLSID) key. If multiple patterns exist, they must be delimited by a semicolon, and numeric subkeys will be generated: 0,1,2...',), -(u'Class',u'Icon_',u'Y',None, None, u'Icon',1,u'Identifier',None, u'Optional foreign key into the Icon Table, specifying the icon file associated with this CLSID. Will be written under the DefaultIcon key.',), -(u'Class',u'IconIndex',u'Y',-32767,32767,None, None, None, None, u'Optional icon index.',), -(u'Class',u'ProgId_Default',u'Y',None, None, u'ProgId',1,u'Text',None, u'Optional ProgId associated with this CLSID.',), -(u'Component',u'Condition',u'Y',None, None, None, None, u'Condition',None, u"A conditional statement that will disable this component if the specified condition evaluates to the 'True' state. If a component is disabled, it will not be installed, regardless of the 'Action' state associated with the component.",), -(u'Component',u'Attributes',u'N',None, None, None, None, None, None, u'Remote execution option, one of irsEnum',), -(u'Component',u'Component',u'N',None, None, None, None, u'Identifier',None, u'Primary key used to identify a particular component record.',), -(u'Component',u'ComponentId',u'Y',None, None, None, None, u'Guid',None, u'A string GUID unique to this component, version, and language.',), -(u'Component',u'Directory_',u'N',None, None, u'Directory',1,u'Identifier',None, u'Required key of a Directory table record. This is actually a property name whose value contains the actual path, set either by the AppSearch action or with the default setting obtained from the Directory table.',), -(u'Component',u'KeyPath',u'Y',None, None, u'File;Registry;ODBCDataSource',1,u'Identifier',None, u'Either the primary key into the File table, Registry table, or ODBCDataSource table. This extract path is stored when the component is installed, and is used to detect the presence of the component and to return the path to it.',), -(u'Icon',u'Name',u'N',None, None, None, None, u'Identifier',None, u'Primary key. Name of the icon file.',), -(u'Icon',u'Data',u'N',None, None, None, None, u'Binary',None, u'Binary stream. The binary icon data in PE (.DLL or .EXE) or icon (.ICO) format.',), -(u'ProgId',u'Description',u'Y',None, None, None, None, u'Text',None, u'Localized description for the Program identifier.',), -(u'ProgId',u'Icon_',u'Y',None, None, u'Icon',1,u'Identifier',None, u'Optional foreign key into the Icon Table, specifying the icon file associated with this ProgId. Will be written under the DefaultIcon key.',), -(u'ProgId',u'IconIndex',u'Y',-32767,32767,None, None, None, None, u'Optional icon index.',), -(u'ProgId',u'ProgId',u'N',None, None, None, None, u'Text',None, u'The Program Identifier. Primary key.',), -(u'ProgId',u'Class_',u'Y',None, None, u'Class',1,u'Guid',None, u'The CLSID of an OLE factory corresponding to the ProgId.',), -(u'ProgId',u'ProgId_Parent',u'Y',None, None, u'ProgId',1,u'Text',None, u'The Parent Program Identifier. If specified, the ProgId column becomes a version independent prog id.',), -(u'ComboBox',u'Text',u'Y',None, None, None, None, u'Formatted',None, u'The visible text to be assigned to the item. Optional. If this entry or the entire column is missing, the text is the same as the value.',), -(u'ComboBox',u'Property',u'N',None, None, None, None, u'Identifier',None, u'A named property to be tied to this item. All the items tied to the same property become part of the same combobox.',), -(u'ComboBox',u'Value',u'N',None, None, None, None, u'Formatted',None, u'The value string associated with this item. Selecting the line will set the associated property to this value.',), -(u'ComboBox',u'Order',u'N',1,32767,None, None, None, None, u'A positive integer used to determine the ordering of the items within one list.\tThe integers do not have to be consecutive.',), -(u'CompLocator',u'Type',u'Y',0,1,None, None, None, None, u'A boolean value that determines if the registry value is a filename or a directory location.',), -(u'CompLocator',u'Signature_',u'N',None, None, None, None, u'Identifier',None, u'The table key. The Signature_ represents a unique file signature and is also the foreign key in the Signature table.',), -(u'CompLocator',u'ComponentId',u'N',None, None, None, None, u'Guid',None, u'A string GUID unique to this component, version, and language.',), -(u'Complus',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key referencing Component that controls the ComPlus component.',), -(u'Complus',u'ExpType',u'Y',0,32767,None, None, None, None, u'ComPlus component attributes.',), -(u'Directory',u'Directory',u'N',None, None, None, None, u'Identifier',None, u'Unique identifier for directory entry, primary key. If a property by this name is defined, it contains the full path to the directory.',), -(u'Directory',u'DefaultDir',u'N',None, None, None, None, u'DefaultDir',None, u"The default sub-path under parent's path.",), -(u'Directory',u'Directory_Parent',u'Y',None, None, u'Directory',1,u'Identifier',None, u'Reference to the entry in this table specifying the default parent directory. A record parented to itself or with a Null parent represents a root of the install tree.',), -(u'Control',u'Type',u'N',None, None, None, None, u'Identifier',None, u'The type of the control.',), -(u'Control',u'Y',u'N',0,32767,None, None, None, None, u'Vertical coordinate of the upper left corner of the bounding rectangle of the control.',), -(u'Control',u'Text',u'Y',None, None, None, None, u'Formatted',None, u'A string used to set the initial text contained within a control (if appropriate).',), -(u'Control',u'Property',u'Y',None, None, None, None, u'Identifier',None, u'The name of a defined property to be linked to this control. ',), -(u'Control',u'Attributes',u'Y',0,2147483647,None, None, None, None, u'A 32-bit word that specifies the attribute flags to be applied to this control.',), -(u'Control',u'Height',u'N',0,32767,None, None, None, None, u'Height of the bounding rectangle of the control.',), -(u'Control',u'Width',u'N',0,32767,None, None, None, None, u'Width of the bounding rectangle of the control.',), -(u'Control',u'X',u'N',0,32767,None, None, None, None, u'Horizontal coordinate of the upper left corner of the bounding rectangle of the control.',), -(u'Control',u'Control',u'N',None, None, None, None, u'Identifier',None, u'Name of the control. This name must be unique within a dialog, but can repeat on different dialogs. ',), -(u'Control',u'Control_Next',u'Y',None, None, u'Control',2,u'Identifier',None, u'The name of an other control on the same dialog. This link defines the tab order of the controls. The links have to form one or more cycles!',), -(u'Control',u'Dialog_',u'N',None, None, u'Dialog',1,u'Identifier',None, u'External key to the Dialog table, name of the dialog.',), -(u'Control',u'Help',u'Y',None, None, None, None, u'Text',None, u'The help strings used with the button. The text is optional. ',), -(u'Dialog',u'Attributes',u'Y',0,2147483647,None, None, None, None, u'A 32-bit word that specifies the attribute flags to be applied to this dialog.',), -(u'Dialog',u'Height',u'N',0,32767,None, None, None, None, u'Height of the bounding rectangle of the dialog.',), -(u'Dialog',u'Width',u'N',0,32767,None, None, None, None, u'Width of the bounding rectangle of the dialog.',), -(u'Dialog',u'Dialog',u'N',None, None, None, None, u'Identifier',None, u'Name of the dialog.',), -(u'Dialog',u'Control_Cancel',u'Y',None, None, u'Control',2,u'Identifier',None, u'Defines the cancel control. Hitting escape or clicking on the close icon on the dialog is equivalent to pushing this button.',), -(u'Dialog',u'Control_Default',u'Y',None, None, u'Control',2,u'Identifier',None, u'Defines the default control. Hitting return is equivalent to pushing this button.',), -(u'Dialog',u'Control_First',u'N',None, None, u'Control',2,u'Identifier',None, u'Defines the control that has the focus when the dialog is created.',), -(u'Dialog',u'HCentering',u'N',0,100,None, None, None, None, u'Horizontal position of the dialog on a 0-100 scale. 0 means left end, 100 means right end of the screen, 50 center.',), -(u'Dialog',u'Title',u'Y',None, None, None, None, u'Formatted',None, u"A text string specifying the title to be displayed in the title bar of the dialog's window.",), -(u'Dialog',u'VCentering',u'N',0,100,None, None, None, None, u'Vertical position of the dialog on a 0-100 scale. 0 means top end, 100 means bottom end of the screen, 50 center.',), -(u'ControlCondition',u'Action',u'N',None, None, None, None, None, u'Default;Disable;Enable;Hide;Show',u'The desired action to be taken on the specified control.',), -(u'ControlCondition',u'Condition',u'N',None, None, None, None, u'Condition',None, u'A standard conditional statement that specifies under which conditions the action should be triggered.',), -(u'ControlCondition',u'Dialog_',u'N',None, None, u'Dialog',1,u'Identifier',None, u'A foreign key to the Dialog table, name of the dialog.',), -(u'ControlCondition',u'Control_',u'N',None, None, u'Control',2,u'Identifier',None, u'A foreign key to the Control table, name of the control.',), -(u'ControlEvent',u'Condition',u'Y',None, None, None, None, u'Condition',None, u'A standard conditional statement that specifies under which conditions an event should be triggered.',), -(u'ControlEvent',u'Ordering',u'Y',0,2147483647,None, None, None, None, u'An integer used to order several events tied to the same control. Can be left blank.',), -(u'ControlEvent',u'Argument',u'N',None, None, None, None, u'Formatted',None, u'A value to be used as a modifier when triggering a particular event.',), -(u'ControlEvent',u'Dialog_',u'N',None, None, u'Dialog',1,u'Identifier',None, u'A foreign key to the Dialog table, name of the dialog.',), -(u'ControlEvent',u'Control_',u'N',None, None, u'Control',2,u'Identifier',None, u'A foreign key to the Control table, name of the control',), -(u'ControlEvent',u'Event',u'N',None, None, None, None, u'Formatted',None, u'An identifier that specifies the type of the event that should take place when the user interacts with control specified by the first two entries.',), -(u'CreateFolder',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key into the Component table.',), -(u'CreateFolder',u'Directory_',u'N',None, None, u'Directory',1,u'Identifier',None, u'Primary key, could be foreign key into the Directory table.',), -(u'CustomAction',u'Type',u'N',1,16383,None, None, None, None, u'The numeric custom action type, consisting of source location, code type, entry, option flags.',), -(u'CustomAction',u'Action',u'N',None, None, None, None, u'Identifier',None, u'Primary key, name of action, normally appears in sequence table unless private use.',), -(u'CustomAction',u'Source',u'Y',None, None, None, None, u'CustomSource',None, u'The table reference of the source of the code.',), -(u'CustomAction',u'Target',u'Y',None, None, None, None, u'Formatted',None, u'Excecution parameter, depends on the type of custom action',), -(u'DrLocator',u'Signature_',u'N',None, None, None, None, u'Identifier',None, u'The Signature_ represents a unique file signature and is also the foreign key in the Signature table.',), -(u'DrLocator',u'Path',u'Y',None, None, None, None, u'AnyPath',None, u'The path on the user system. This is a either a subpath below the value of the Parent or a full path. The path may contain properties enclosed within [ ] that will be expanded.',), -(u'DrLocator',u'Depth',u'Y',0,32767,None, None, None, None, u'The depth below the path to which the Signature_ is recursively searched. If absent, the depth is assumed to be 0.',), -(u'DrLocator',u'Parent',u'Y',None, None, None, None, u'Identifier',None, u'The parent file signature. It is also a foreign key in the Signature table. If null and the Path column does not expand to a full path, then all the fixed drives of the user system are searched using the Path.',), -(u'DuplicateFile',u'File_',u'N',None, None, u'File',1,u'Identifier',None, u'Foreign key referencing the source file to be duplicated.',), -(u'DuplicateFile',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key referencing Component that controls the duplicate file.',), -(u'DuplicateFile',u'DestFolder',u'Y',None, None, None, None, u'Identifier',None, u'Name of a property whose value is assumed to resolve to the full pathname to a destination folder.',), -(u'DuplicateFile',u'DestName',u'Y',None, None, None, None, u'Filename',None, u'Filename to be given to the duplicate file.',), -(u'DuplicateFile',u'FileKey',u'N',None, None, None, None, u'Identifier',None, u'Primary key used to identify a particular file entry',), -(u'Environment',u'Name',u'N',None, None, None, None, u'Text',None, u'The name of the environmental value.',), -(u'Environment',u'Value',u'Y',None, None, None, None, u'Formatted',None, u'The value to set in the environmental settings.',), -(u'Environment',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key into the Component table referencing component that controls the installing of the environmental value.',), -(u'Environment',u'Environment',u'N',None, None, None, None, u'Identifier',None, u'Unique identifier for the environmental variable setting',), -(u'Error',u'Error',u'N',0,32767,None, None, None, None, u'Integer error number, obtained from header file IError(...) macros.',), -(u'Error',u'Message',u'Y',None, None, None, None, u'Template',None, u'Error formatting template, obtained from user ed. or localizers.',), -(u'EventMapping',u'Dialog_',u'N',None, None, u'Dialog',1,u'Identifier',None, u'A foreign key to the Dialog table, name of the Dialog.',), -(u'EventMapping',u'Control_',u'N',None, None, u'Control',2,u'Identifier',None, u'A foreign key to the Control table, name of the control.',), -(u'EventMapping',u'Event',u'N',None, None, None, None, u'Identifier',None, u'An identifier that specifies the type of the event that the control subscribes to.',), -(u'EventMapping',u'Attribute',u'N',None, None, None, None, u'Identifier',None, u'The name of the control attribute, that is set when this event is received.',), -(u'Extension',u'Feature_',u'N',None, None, u'Feature',1,u'Identifier',None, u'Required foreign key into the Feature Table, specifying the feature to validate or install in order for the CLSID factory to be operational.',), -(u'Extension',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Required foreign key into the Component Table, specifying the component for which to return a path when called through LocateComponent.',), -(u'Extension',u'Extension',u'N',None, None, None, None, u'Text',None, u'The extension associated with the table row.',), -(u'Extension',u'MIME_',u'Y',None, None, u'MIME',1,u'Text',None, u'Optional Context identifier, typically "type/format" associated with the extension',), -(u'Extension',u'ProgId_',u'Y',None, None, u'ProgId',1,u'Text',None, u'Optional ProgId associated with this extension.',), -(u'MIME',u'CLSID',u'Y',None, None, None, None, u'Guid',None, u'Optional associated CLSID.',), -(u'MIME',u'ContentType',u'N',None, None, None, None, u'Text',None, u'Primary key. Context identifier, typically "type/format".',), -(u'MIME',u'Extension_',u'N',None, None, u'Extension',1,u'Text',None, u'Optional associated extension (without dot)',), -(u'FeatureComponents',u'Feature_',u'N',None, None, u'Feature',1,u'Identifier',None, u'Foreign key into Feature table.',), -(u'FeatureComponents',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key into Component table.',), -(u'FileSFPCatalog',u'File_',u'N',None, None, u'File',1,u'Identifier',None, u'File associated with the catalog',), -(u'FileSFPCatalog',u'SFPCatalog_',u'N',None, None, u'SFPCatalog',1,u'Filename',None, u'Catalog associated with the file',), -(u'SFPCatalog',u'SFPCatalog',u'N',None, None, None, None, u'Filename',None, u'File name for the catalog.',), -(u'SFPCatalog',u'Catalog',u'N',None, None, None, None, u'Binary',None, u'SFP Catalog',), -(u'SFPCatalog',u'Dependency',u'Y',None, None, None, None, u'Formatted',None, u'Parent catalog - only used by SFP',), -(u'Font',u'File_',u'N',None, None, u'File',1,u'Identifier',None, u'Primary key, foreign key into File table referencing font file.',), -(u'Font',u'FontTitle',u'Y',None, None, None, None, u'Text',None, u'Font name.',), -(u'IniFile',u'Action',u'N',None, None, None, None, None, u'0;1;3',u'The type of modification to be made, one of iifEnum',), -(u'IniFile',u'Value',u'N',None, None, None, None, u'Formatted',None, u'The value to be written.',), -(u'IniFile',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key into the Component table referencing component that controls the installing of the .INI value.',), -(u'IniFile',u'FileName',u'N',None, None, None, None, u'Filename',None, u'The .INI file name in which to write the information',), -(u'IniFile',u'IniFile',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized token.',), -(u'IniFile',u'DirProperty',u'Y',None, None, None, None, u'Identifier',None, u'Foreign key into the Directory table denoting the directory where the .INI file is.',), -(u'IniFile',u'Key',u'N',None, None, None, None, u'Formatted',None, u'The .INI file key below Section.',), -(u'IniFile',u'Section',u'N',None, None, None, None, u'Formatted',None, u'The .INI file Section.',), -(u'IniLocator',u'Type',u'Y',0,2,None, None, None, None, u'An integer value that determines if the .INI value read is a filename or a directory location or to be used as is w/o interpretation.',), -(u'IniLocator',u'Signature_',u'N',None, None, None, None, u'Identifier',None, u'The table key. The Signature_ represents a unique file signature and is also the foreign key in the Signature table.',), -(u'IniLocator',u'FileName',u'N',None, None, None, None, u'Filename',None, u'The .INI file name.',), -(u'IniLocator',u'Key',u'N',None, None, None, None, u'Text',None, u'Key value (followed by an equals sign in INI file).',), -(u'IniLocator',u'Section',u'N',None, None, None, None, u'Text',None, u'Section name within in file (within square brackets in INI file).',), -(u'IniLocator',u'Field',u'Y',0,32767,None, None, None, None, u'The field in the .INI line. If Field is null or 0 the entire line is read.',), -(u'InstallExecuteSequence',u'Action',u'N',None, None, None, None, u'Identifier',None, u'Name of action to invoke, either in the engine or the handler DLL.',), -(u'InstallExecuteSequence',u'Condition',u'Y',None, None, None, None, u'Condition',None, u'Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.',), -(u'InstallExecuteSequence',u'Sequence',u'Y',-4,32767,None, None, None, None, u'Number that determines the sort order in which the actions are to be executed. Leave blank to suppress action.',), -(u'InstallUISequence',u'Action',u'N',None, None, None, None, u'Identifier',None, u'Name of action to invoke, either in the engine or the handler DLL.',), -(u'InstallUISequence',u'Condition',u'Y',None, None, None, None, u'Condition',None, u'Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.',), -(u'InstallUISequence',u'Sequence',u'Y',-4,32767,None, None, None, None, u'Number that determines the sort order in which the actions are to be executed. Leave blank to suppress action.',), -(u'IsolatedComponent',u'Component_Application',u'N',None, None, u'Component',1,u'Identifier',None, u'Key to Component table item for application',), -(u'IsolatedComponent',u'Component_Shared',u'N',None, None, u'Component',1,u'Identifier',None, u'Key to Component table item to be isolated',), -(u'LaunchCondition',u'Description',u'N',None, None, None, None, u'Formatted',None, u'Localizable text to display when condition fails and install must abort.',), -(u'LaunchCondition',u'Condition',u'N',None, None, None, None, u'Condition',None, u'Expression which must evaluate to TRUE in order for install to commence.',), -(u'ListBox',u'Text',u'Y',None, None, None, None, u'Text',None, u'The visible text to be assigned to the item. Optional. If this entry or the entire column is missing, the text is the same as the value.',), -(u'ListBox',u'Property',u'N',None, None, None, None, u'Identifier',None, u'A named property to be tied to this item. All the items tied to the same property become part of the same listbox.',), -(u'ListBox',u'Value',u'N',None, None, None, None, u'Formatted',None, u'The value string associated with this item. Selecting the line will set the associated property to this value.',), -(u'ListBox',u'Order',u'N',1,32767,None, None, None, None, u'A positive integer used to determine the ordering of the items within one list..The integers do not have to be consecutive.',), -(u'ListView',u'Text',u'Y',None, None, None, None, u'Text',None, u'The visible text to be assigned to the item. Optional. If this entry or the entire column is missing, the text is the same as the value.',), -(u'ListView',u'Property',u'N',None, None, None, None, u'Identifier',None, u'A named property to be tied to this item. All the items tied to the same property become part of the same listview.',), -(u'ListView',u'Value',u'N',None, None, None, None, u'Identifier',None, u'The value string associated with this item. Selecting the line will set the associated property to this value.',), -(u'ListView',u'Order',u'N',1,32767,None, None, None, None, u'A positive integer used to determine the ordering of the items within one list..The integers do not have to be consecutive.',), -(u'ListView',u'Binary_',u'Y',None, None, u'Binary',1,u'Identifier',None, u'The name of the icon to be displayed with the icon. The binary information is looked up from the Binary Table.',), -(u'LockPermissions',u'Table',u'N',None, None, None, None, u'Identifier',u'Directory;File;Registry',u'Reference to another table name',), -(u'LockPermissions',u'Domain',u'Y',None, None, None, None, u'Formatted',None, u'Domain name for user whose permissions are being set. (usually a property)',), -(u'LockPermissions',u'LockObject',u'N',None, None, None, None, u'Identifier',None, u'Foreign key into Registry or File table',), -(u'LockPermissions',u'Permission',u'Y',-2147483647,2147483647,None, None, None, None, u'Permission Access mask. Full Control = 268435456 (GENERIC_ALL = 0x10000000)',), -(u'LockPermissions',u'User',u'N',None, None, None, None, u'Formatted',None, u'User for permissions to be set. (usually a property)',), -(u'Media',u'Source',u'Y',None, None, None, None, u'Property',None, u'The property defining the location of the cabinet file.',), -(u'Media',u'Cabinet',u'Y',None, None, None, None, u'Cabinet',None, u'If some or all of the files stored on the media are compressed in a cabinet, the name of that cabinet.',), -(u'Media',u'DiskId',u'N',1,32767,None, None, None, None, u'Primary key, integer to determine sort order for table.',), -(u'Media',u'DiskPrompt',u'Y',None, None, None, None, u'Text',None, u'Disk name: the visible text actually printed on the disk. This will be used to prompt the user when this disk needs to be inserted.',), -(u'Media',u'LastSequence',u'N',0,32767,None, None, None, None, u'File sequence number for the last file for this media.',), -(u'Media',u'VolumeLabel',u'Y',None, None, None, None, u'Text',None, u'The label attributed to the volume.',), -(u'ModuleComponents',u'Component',u'N',None, None, u'Component',1,u'Identifier',None, u'Component contained in the module.',), -(u'ModuleComponents',u'Language',u'N',None, None, u'ModuleSignature',2,None, None, u'Default language ID for module (may be changed by transform).',), -(u'ModuleComponents',u'ModuleID',u'N',None, None, u'ModuleSignature',1,u'Identifier',None, u'Module containing the component.',), -(u'ModuleSignature',u'Language',u'N',None, None, None, None, None, None, u'Default decimal language of module.',), -(u'ModuleSignature',u'Version',u'N',None, None, None, None, u'Version',None, u'Version of the module.',), -(u'ModuleSignature',u'ModuleID',u'N',None, None, None, None, u'Identifier',None, u'Module identifier (String.GUID).',), -(u'ModuleDependency',u'ModuleID',u'N',None, None, u'ModuleSignature',1,u'Identifier',None, u'Module requiring the dependency.',), -(u'ModuleDependency',u'ModuleLanguage',u'N',None, None, u'ModuleSignature',2,None, None, u'Language of module requiring the dependency.',), -(u'ModuleDependency',u'RequiredID',u'N',None, None, None, None, None, None, u'String.GUID of required module.',), -(u'ModuleDependency',u'RequiredLanguage',u'N',None, None, None, None, None, None, u'LanguageID of the required module.',), -(u'ModuleDependency',u'RequiredVersion',u'Y',None, None, None, None, u'Version',None, u'Version of the required version.',), -(u'ModuleExclusion',u'ModuleID',u'N',None, None, u'ModuleSignature',1,u'Identifier',None, u'String.GUID of module with exclusion requirement.',), -(u'ModuleExclusion',u'ModuleLanguage',u'N',None, None, u'ModuleSignature',2,None, None, u'LanguageID of module with exclusion requirement.',), -(u'ModuleExclusion',u'ExcludedID',u'N',None, None, None, None, None, None, u'String.GUID of excluded module.',), -(u'ModuleExclusion',u'ExcludedLanguage',u'N',None, None, None, None, None, None, u'Language of excluded module.',), -(u'ModuleExclusion',u'ExcludedMaxVersion',u'Y',None, None, None, None, u'Version',None, u'Maximum version of excluded module.',), -(u'ModuleExclusion',u'ExcludedMinVersion',u'Y',None, None, None, None, u'Version',None, u'Minimum version of excluded module.',), -(u'MoveFile',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'If this component is not "selected" for installation or removal, no action will be taken on the associated MoveFile entry',), -(u'MoveFile',u'DestFolder',u'N',None, None, None, None, u'Identifier',None, u'Name of a property whose value is assumed to resolve to the full path to the destination directory',), -(u'MoveFile',u'DestName',u'Y',None, None, None, None, u'Filename',None, u'Name to be given to the original file after it is moved or copied. If blank, the destination file will be given the same name as the source file',), -(u'MoveFile',u'FileKey',u'N',None, None, None, None, u'Identifier',None, u'Primary key that uniquely identifies a particular MoveFile record',), -(u'MoveFile',u'Options',u'N',0,1,None, None, None, None, u'Integer value specifying the MoveFile operating mode, one of imfoEnum',), -(u'MoveFile',u'SourceFolder',u'Y',None, None, None, None, u'Identifier',None, u'Name of a property whose value is assumed to resolve to the full path to the source directory',), -(u'MoveFile',u'SourceName',u'Y',None, None, None, None, u'Text',None, u"Name of the source file(s) to be moved or copied. Can contain the '*' or '?' wildcards.",), -(u'MsiAssembly',u'Attributes',u'Y',None, None, None, None, None, None, u'Assembly attributes',), -(u'MsiAssembly',u'Feature_',u'N',None, None, u'Feature',1,u'Identifier',None, u'Foreign key into Feature table.',), -(u'MsiAssembly',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key into Component table.',), -(u'MsiAssembly',u'File_Application',u'Y',None, None, u'File',1,u'Identifier',None, u'Foreign key into File table, denoting the application context for private assemblies. Null for global assemblies.',), -(u'MsiAssembly',u'File_Manifest',u'Y',None, None, u'File',1,u'Identifier',None, u'Foreign key into the File table denoting the manifest file for the assembly.',), -(u'MsiAssemblyName',u'Name',u'N',None, None, None, None, u'Text',None, u'The name part of the name-value pairs for the assembly name.',), -(u'MsiAssemblyName',u'Value',u'N',None, None, None, None, u'Text',None, u'The value part of the name-value pairs for the assembly name.',), -(u'MsiAssemblyName',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key into Component table.',), -(u'MsiDigitalCertificate',u'CertData',u'N',None, None, None, None, u'Binary',None, u'A certificate context blob for a signer certificate',), -(u'MsiDigitalCertificate',u'DigitalCertificate',u'N',None, None, None, None, u'Identifier',None, u'A unique identifier for the row',), -(u'MsiDigitalSignature',u'Table',u'N',None, None, None, None, None, u'Media',u'Reference to another table name (only Media table is supported)',), -(u'MsiDigitalSignature',u'DigitalCertificate_',u'N',None, None, u'MsiDigitalCertificate',1,u'Identifier',None, u'Foreign key to MsiDigitalCertificate table identifying the signer certificate',), -(u'MsiDigitalSignature',u'Hash',u'Y',None, None, None, None, u'Binary',None, u'The encoded hash blob from the digital signature',), -(u'MsiDigitalSignature',u'SignObject',u'N',None, None, None, None, u'Text',None, u'Foreign key to Media table',), -(u'MsiFileHash',u'File_',u'N',None, None, u'File',1,u'Identifier',None, u'Primary key, foreign key into File table referencing file with this hash',), -(u'MsiFileHash',u'Options',u'N',0,32767,None, None, None, None, u'Various options and attributes for this hash.',), -(u'MsiFileHash',u'HashPart1',u'N',None, None, None, None, None, None, u'Size of file in bytes (long integer).',), -(u'MsiFileHash',u'HashPart2',u'N',None, None, None, None, None, None, u'Size of file in bytes (long integer).',), -(u'MsiFileHash',u'HashPart3',u'N',None, None, None, None, None, None, u'Size of file in bytes (long integer).',), -(u'MsiFileHash',u'HashPart4',u'N',None, None, None, None, None, None, u'Size of file in bytes (long integer).',), -(u'MsiPatchHeaders',u'StreamRef',u'N',None, None, None, None, u'Identifier',None, u'Primary key. A unique identifier for the row.',), -(u'MsiPatchHeaders',u'Header',u'N',None, None, None, None, u'Binary',None, u'Binary stream. The patch header, used for patch validation.',), -(u'ODBCAttribute',u'Value',u'Y',None, None, None, None, u'Text',None, u'Value for ODBC driver attribute',), -(u'ODBCAttribute',u'Attribute',u'N',None, None, None, None, u'Text',None, u'Name of ODBC driver attribute',), -(u'ODBCAttribute',u'Driver_',u'N',None, None, u'ODBCDriver',1,u'Identifier',None, u'Reference to ODBC driver in ODBCDriver table',), -(u'ODBCDriver',u'Description',u'N',None, None, None, None, u'Text',None, u'Text used as registered name for driver, non-localized',), -(u'ODBCDriver',u'File_',u'N',None, None, u'File',1,u'Identifier',None, u'Reference to key driver file',), -(u'ODBCDriver',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Reference to associated component',), -(u'ODBCDriver',u'Driver',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized.internal token for driver',), -(u'ODBCDriver',u'File_Setup',u'Y',None, None, u'File',1,u'Identifier',None, u'Optional reference to key driver setup DLL',), -(u'ODBCDataSource',u'Description',u'N',None, None, None, None, u'Text',None, u'Text used as registered name for data source',), -(u'ODBCDataSource',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Reference to associated component',), -(u'ODBCDataSource',u'DataSource',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized.internal token for data source',), -(u'ODBCDataSource',u'DriverDescription',u'N',None, None, None, None, u'Text',None, u'Reference to driver description, may be existing driver',), -(u'ODBCDataSource',u'Registration',u'N',0,1,None, None, None, None, u'Registration option: 0=machine, 1=user, others t.b.d.',), -(u'ODBCSourceAttribute',u'Value',u'Y',None, None, None, None, u'Text',None, u'Value for ODBC data source attribute',), -(u'ODBCSourceAttribute',u'Attribute',u'N',None, None, None, None, u'Text',None, u'Name of ODBC data source attribute',), -(u'ODBCSourceAttribute',u'DataSource_',u'N',None, None, u'ODBCDataSource',1,u'Identifier',None, u'Reference to ODBC data source in ODBCDataSource table',), -(u'ODBCTranslator',u'Description',u'N',None, None, None, None, u'Text',None, u'Text used as registered name for translator',), -(u'ODBCTranslator',u'File_',u'N',None, None, u'File',1,u'Identifier',None, u'Reference to key translator file',), -(u'ODBCTranslator',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Reference to associated component',), -(u'ODBCTranslator',u'File_Setup',u'Y',None, None, u'File',1,u'Identifier',None, u'Optional reference to key translator setup DLL',), -(u'ODBCTranslator',u'Translator',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized.internal token for translator',), -(u'Patch',u'Sequence',u'N',0,32767,None, None, None, None, u'Primary key, sequence with respect to the media images; order must track cabinet order.',), -(u'Patch',u'Attributes',u'N',0,32767,None, None, None, None, u'Integer containing bit flags representing patch attributes',), -(u'Patch',u'File_',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized token, foreign key to File table, must match identifier in cabinet.',), -(u'Patch',u'Header',u'Y',None, None, None, None, u'Binary',None, u'Binary stream. The patch header, used for patch validation.',), -(u'Patch',u'PatchSize',u'N',0,2147483647,None, None, None, None, u'Size of patch in bytes (long integer).',), -(u'Patch',u'StreamRef_',u'Y',None, None, None, None, u'Identifier',None, u'Identifier. Foreign key to the StreamRef column of the MsiPatchHeaders table.',), -(u'PatchPackage',u'Media_',u'N',0,32767,None, None, None, None, u'Foreign key to DiskId column of Media table. Indicates the disk containing the patch package.',), -(u'PatchPackage',u'PatchId',u'N',None, None, None, None, u'Guid',None, u'A unique string GUID representing this patch.',), -(u'PublishComponent',u'Feature_',u'N',None, None, u'Feature',1,u'Identifier',None, u'Foreign key into the Feature table.',), -(u'PublishComponent',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key into the Component table.',), -(u'PublishComponent',u'ComponentId',u'N',None, None, None, None, u'Guid',None, u'A string GUID that represents the component id that will be requested by the alien product.',), -(u'PublishComponent',u'AppData',u'Y',None, None, None, None, u'Text',None, u'This is localisable Application specific data that can be associated with a Qualified Component.',), -(u'PublishComponent',u'Qualifier',u'N',None, None, None, None, u'Text',None, u'This is defined only when the ComponentId column is an Qualified Component Id. This is the Qualifier for ProvideComponentIndirect.',), -(u'RadioButton',u'Y',u'N',0,32767,None, None, None, None, u'The vertical coordinate of the upper left corner of the bounding rectangle of the radio button.',), -(u'RadioButton',u'Text',u'Y',None, None, None, None, u'Text',None, u'The visible title to be assigned to the radio button.',), -(u'RadioButton',u'Property',u'N',None, None, None, None, u'Identifier',None, u'A named property to be tied to this radio button. All the buttons tied to the same property become part of the same group.',), -(u'RadioButton',u'Height',u'N',0,32767,None, None, None, None, u'The height of the button.',), -(u'RadioButton',u'Width',u'N',0,32767,None, None, None, None, u'The width of the button.',), -(u'RadioButton',u'X',u'N',0,32767,None, None, None, None, u'The horizontal coordinate of the upper left corner of the bounding rectangle of the radio button.',), -(u'RadioButton',u'Value',u'N',None, None, None, None, u'Formatted',None, u'The value string associated with this button. Selecting the button will set the associated property to this value.',), -(u'RadioButton',u'Order',u'N',1,32767,None, None, None, None, u'A positive integer used to determine the ordering of the items within one list..The integers do not have to be consecutive.',), -(u'RadioButton',u'Help',u'Y',None, None, None, None, u'Text',None, u'The help strings used with the button. The text is optional.',), -(u'Registry',u'Name',u'Y',None, None, None, None, u'Formatted',None, u'The registry value name.',), -(u'Registry',u'Value',u'Y',None, None, None, None, u'Formatted',None, u'The registry value.',), -(u'Registry',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key into the Component table referencing component that controls the installing of the registry value.',), -(u'Registry',u'Key',u'N',None, None, None, None, u'RegPath',None, u'The key for the registry value.',), -(u'Registry',u'Registry',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized token.',), -(u'Registry',u'Root',u'N',-1,3,None, None, None, None, u'The predefined root key for the registry value, one of rrkEnum.',), -(u'RegLocator',u'Name',u'Y',None, None, None, None, u'Formatted',None, u'The registry value name.',), -(u'RegLocator',u'Type',u'Y',0,18,None, None, None, None, u'An integer value that determines if the registry value is a filename or a directory location or to be used as is w/o interpretation.',), -(u'RegLocator',u'Signature_',u'N',None, None, None, None, u'Identifier',None, u'The table key. The Signature_ represents a unique file signature and is also the foreign key in the Signature table. If the type is 0, the registry values refers a directory, and _Signature is not a foreign key.',), -(u'RegLocator',u'Key',u'N',None, None, None, None, u'RegPath',None, u'The key for the registry value.',), -(u'RegLocator',u'Root',u'N',0,3,None, None, None, None, u'The predefined root key for the registry value, one of rrkEnum.',), -(u'RemoveFile',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key referencing Component that controls the file to be removed.',), -(u'RemoveFile',u'FileKey',u'N',None, None, None, None, u'Identifier',None, u'Primary key used to identify a particular file entry',), -(u'RemoveFile',u'FileName',u'Y',None, None, None, None, u'WildCardFilename',None, u'Name of the file to be removed.',), -(u'RemoveFile',u'DirProperty',u'N',None, None, None, None, u'Identifier',None, u'Name of a property whose value is assumed to resolve to the full pathname to the folder of the file to be removed.',), -(u'RemoveFile',u'InstallMode',u'N',None, None, None, None, None, u'1;2;3',u'Installation option, one of iimEnum.',), -(u'RemoveIniFile',u'Action',u'N',None, None, None, None, None, u'2;4',u'The type of modification to be made, one of iifEnum.',), -(u'RemoveIniFile',u'Value',u'Y',None, None, None, None, u'Formatted',None, u'The value to be deleted. The value is required when Action is iifIniRemoveTag',), -(u'RemoveIniFile',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key into the Component table referencing component that controls the deletion of the .INI value.',), -(u'RemoveIniFile',u'FileName',u'N',None, None, None, None, u'Filename',None, u'The .INI file name in which to delete the information',), -(u'RemoveIniFile',u'DirProperty',u'Y',None, None, None, None, u'Identifier',None, u'Foreign key into the Directory table denoting the directory where the .INI file is.',), -(u'RemoveIniFile',u'Key',u'N',None, None, None, None, u'Formatted',None, u'The .INI file key below Section.',), -(u'RemoveIniFile',u'Section',u'N',None, None, None, None, u'Formatted',None, u'The .INI file Section.',), -(u'RemoveIniFile',u'RemoveIniFile',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized token.',), -(u'RemoveRegistry',u'Name',u'Y',None, None, None, None, u'Formatted',None, u'The registry value name.',), -(u'RemoveRegistry',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key into the Component table referencing component that controls the deletion of the registry value.',), -(u'RemoveRegistry',u'Key',u'N',None, None, None, None, u'RegPath',None, u'The key for the registry value.',), -(u'RemoveRegistry',u'Root',u'N',-1,3,None, None, None, None, u'The predefined root key for the registry value, one of rrkEnum',), -(u'RemoveRegistry',u'RemoveRegistry',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized token.',), -(u'ReserveCost',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Reserve a specified amount of space if this component is to be installed.',), -(u'ReserveCost',u'ReserveFolder',u'Y',None, None, None, None, u'Identifier',None, u'Name of a property whose value is assumed to resolve to the full path to the destination directory',), -(u'ReserveCost',u'ReserveKey',u'N',None, None, None, None, u'Identifier',None, u'Primary key that uniquely identifies a particular ReserveCost record',), -(u'ReserveCost',u'ReserveLocal',u'N',0,2147483647,None, None, None, None, u'Disk space to reserve if linked component is installed locally.',), -(u'ReserveCost',u'ReserveSource',u'N',0,2147483647,None, None, None, None, u'Disk space to reserve if linked component is installed to run from the source location.',), -(u'SelfReg',u'File_',u'N',None, None, u'File',1,u'Identifier',None, u'Foreign key into the File table denoting the module that needs to be registered.',), -(u'SelfReg',u'Cost',u'Y',0,32767,None, None, None, None, u'The cost of registering the module.',), -(u'ServiceControl',u'Name',u'N',None, None, None, None, u'Formatted',None, u'Name of a service. /, \\, comma and space are invalid',), -(u'ServiceControl',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Required foreign key into the Component Table that controls the startup of the service',), -(u'ServiceControl',u'Event',u'N',0,187,None, None, None, None, u'Bit field: Install: 0x1 = Start, 0x2 = Stop, 0x8 = Delete, Uninstall: 0x10 = Start, 0x20 = Stop, 0x80 = Delete',), -(u'ServiceControl',u'ServiceControl',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized token.',), -(u'ServiceControl',u'Arguments',u'Y',None, None, None, None, u'Formatted',None, u'Arguments for the service. Separate by [~].',), -(u'ServiceControl',u'Wait',u'Y',0,1,None, None, None, None, u'Boolean for whether to wait for the service to fully start',), -(u'ServiceInstall',u'Name',u'N',None, None, None, None, u'Formatted',None, u'Internal Name of the Service',), -(u'ServiceInstall',u'Description',u'Y',None, None, None, None, u'Text',None, u'Description of service.',), -(u'ServiceInstall',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Required foreign key into the Component Table that controls the startup of the service',), -(u'ServiceInstall',u'Arguments',u'Y',None, None, None, None, u'Formatted',None, u'Arguments to include in every start of the service, passed to WinMain',), -(u'ServiceInstall',u'ServiceInstall',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized token.',), -(u'ServiceInstall',u'Dependencies',u'Y',None, None, None, None, u'Formatted',None, u'Other services this depends on to start. Separate by [~], and end with [~][~]',), -(u'ServiceInstall',u'DisplayName',u'Y',None, None, None, None, u'Formatted',None, u'External Name of the Service',), -(u'ServiceInstall',u'ErrorControl',u'N',-2147483647,2147483647,None, None, None, None, u'Severity of error if service fails to start',), -(u'ServiceInstall',u'LoadOrderGroup',u'Y',None, None, None, None, u'Formatted',None, u'LoadOrderGroup',), -(u'ServiceInstall',u'Password',u'Y',None, None, None, None, u'Formatted',None, u'password to run service with. (with StartName)',), -(u'ServiceInstall',u'ServiceType',u'N',-2147483647,2147483647,None, None, None, None, u'Type of the service',), -(u'ServiceInstall',u'StartName',u'Y',None, None, None, None, u'Formatted',None, u'User or object name to run service as',), -(u'ServiceInstall',u'StartType',u'N',0,4,None, None, None, None, u'Type of the service',), -(u'Shortcut',u'Name',u'N',None, None, None, None, u'Filename',None, u'The name of the shortcut to be created.',), -(u'Shortcut',u'Description',u'Y',None, None, None, None, u'Text',None, u'The description for the shortcut.',), -(u'Shortcut',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key into the Component table denoting the component whose selection gates the shortcut creation/deletion.',), -(u'Shortcut',u'Icon_',u'Y',None, None, u'Icon',1,u'Identifier',None, u'Foreign key into the File table denoting the external icon file for the shortcut.',), -(u'Shortcut',u'IconIndex',u'Y',-32767,32767,None, None, None, None, u'The icon index for the shortcut.',), -(u'Shortcut',u'Directory_',u'N',None, None, u'Directory',1,u'Identifier',None, u'Foreign key into the Directory table denoting the directory where the shortcut file is created.',), -(u'Shortcut',u'Target',u'N',None, None, None, None, u'Shortcut',None, u'The shortcut target. This is usually a property that is expanded to a file or a folder that the shortcut points to.',), -(u'Shortcut',u'Arguments',u'Y',None, None, None, None, u'Formatted',None, u'The command-line arguments for the shortcut.',), -(u'Shortcut',u'Shortcut',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized token.',), -(u'Shortcut',u'Hotkey',u'Y',0,32767,None, None, None, None, u'The hotkey for the shortcut. It has the virtual-key code for the key in the low-order byte, and the modifier flags in the high-order byte. ',), -(u'Shortcut',u'ShowCmd',u'Y',None, None, None, None, None, u'1;3;7',u'The show command for the application window.The following values may be used.',), -(u'Shortcut',u'WkDir',u'Y',None, None, None, None, u'Identifier',None, u'Name of property defining location of working directory.',), -(u'Signature',u'FileName',u'N',None, None, None, None, u'Filename',None, u'The name of the file. This may contain a "short name|long name" pair.',), -(u'Signature',u'Signature',u'N',None, None, None, None, u'Identifier',None, u'The table key. The Signature represents a unique file signature.',), -(u'Signature',u'Languages',u'Y',None, None, None, None, u'Language',None, u'The languages supported by the file.',), -(u'Signature',u'MaxDate',u'Y',0,2147483647,None, None, None, None, u'The maximum creation date of the file.',), -(u'Signature',u'MaxSize',u'Y',0,2147483647,None, None, None, None, u'The maximum size of the file. ',), -(u'Signature',u'MaxVersion',u'Y',None, None, None, None, u'Text',None, u'The maximum version of the file.',), -(u'Signature',u'MinDate',u'Y',0,2147483647,None, None, None, None, u'The minimum creation date of the file.',), -(u'Signature',u'MinSize',u'Y',0,2147483647,None, None, None, None, u'The minimum size of the file.',), -(u'Signature',u'MinVersion',u'Y',None, None, None, None, u'Text',None, u'The minimum version of the file.',), -(u'TextStyle',u'TextStyle',u'N',None, None, None, None, u'Identifier',None, u'Name of the style. The primary key of this table. This name is embedded in the texts to indicate a style change.',), -(u'TextStyle',u'Color',u'Y',0,16777215,None, None, None, None, u'A long integer indicating the color of the string in the RGB format (Red, Green, Blue each 0-255, RGB = R + 256*G + 256^2*B).',), -(u'TextStyle',u'FaceName',u'N',None, None, None, None, u'Text',None, u'A string indicating the name of the font used. Required. The string must be at most 31 characters long.',), -(u'TextStyle',u'Size',u'N',0,32767,None, None, None, None, u'The size of the font used. This size is given in our units (1/12 of the system font height). Assuming that the system font is set to 12 point size, this is equivalent to the point size.',), -(u'TextStyle',u'StyleBits',u'Y',0,15,None, None, None, None, u'A combination of style bits.',), -(u'TypeLib',u'Description',u'Y',None, None, None, None, u'Text',None, None, ), -(u'TypeLib',u'Feature_',u'N',None, None, u'Feature',1,u'Identifier',None, u'Required foreign key into the Feature Table, specifying the feature to validate or install in order for the type library to be operational.',), -(u'TypeLib',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Required foreign key into the Component Table, specifying the component for which to return a path when called through LocateComponent.',), -(u'TypeLib',u'Directory_',u'Y',None, None, u'Directory',1,u'Identifier',None, u'Optional. The foreign key into the Directory table denoting the path to the help file for the type library.',), -(u'TypeLib',u'Language',u'N',0,32767,None, None, None, None, u'The language of the library.',), -(u'TypeLib',u'Version',u'Y',0,16777215,None, None, None, None, u'The version of the library. The minor version is in the lower 8 bits of the integer. The major version is in the next 16 bits. ',), -(u'TypeLib',u'Cost',u'Y',0,2147483647,None, None, None, None, u'The cost associated with the registration of the typelib. This column is currently optional.',), -(u'TypeLib',u'LibID',u'N',None, None, None, None, u'Guid',None, u'The GUID that represents the library.',), -(u'UIText',u'Text',u'Y',None, None, None, None, u'Text',None, u'The localized version of the string.',), -(u'UIText',u'Key',u'N',None, None, None, None, u'Identifier',None, u'A unique key that identifies the particular string.',), -(u'Upgrade',u'Attributes',u'N',0,2147483647,None, None, None, None, u'The attributes of this product set.',), -(u'Upgrade',u'Language',u'Y',None, None, None, None, u'Language',None, u'A comma-separated list of languages for either products in this set or products not in this set.',), -(u'Upgrade',u'ActionProperty',u'N',None, None, None, None, u'UpperCase',None, u'The property to set when a product in this set is found.',), -(u'Upgrade',u'Remove',u'Y',None, None, None, None, u'Formatted',None, u'The list of features to remove when uninstalling a product from this set. The default is "ALL".',), -(u'Upgrade',u'UpgradeCode',u'N',None, None, None, None, u'Guid',None, u'The UpgradeCode GUID belonging to the products in this set.',), -(u'Upgrade',u'VersionMax',u'Y',None, None, None, None, u'Text',None, u'The maximum ProductVersion of the products in this set. The set may or may not include products with this particular version.',), -(u'Upgrade',u'VersionMin',u'Y',None, None, None, None, u'Text',None, u'The minimum ProductVersion of the products in this set. The set may or may not include products with this particular version.',), -(u'Verb',u'Sequence',u'Y',0,32767,None, None, None, None, u'Order within the verbs for a particular extension. Also used simply to specify the default verb.',), -(u'Verb',u'Argument',u'Y',None, None, None, None, u'Formatted',None, u'Optional value for the command arguments.',), -(u'Verb',u'Extension_',u'N',None, None, u'Extension',1,u'Text',None, u'The extension associated with the table row.',), -(u'Verb',u'Verb',u'N',None, None, None, None, u'Text',None, u'The verb for the command.',), -(u'Verb',u'Command',u'Y',None, None, None, None, u'Formatted',None, u'The command text.',), -] diff --git a/Tools/msi/sequence.py b/Tools/msi/sequence.py deleted file mode 100644 index 1138f7a2345b..000000000000 --- a/Tools/msi/sequence.py +++ /dev/null @@ -1,126 +0,0 @@ -AdminExecuteSequence = [ -(u'InstallInitialize', None, 1500), -(u'InstallFinalize', None, 6600), -(u'InstallFiles', None, 4000), -(u'InstallAdminPackage', None, 3900), -(u'FileCost', None, 900), -(u'CostInitialize', None, 800), -(u'CostFinalize', None, 1000), -(u'InstallValidate', None, 1400), -] - -AdminUISequence = [ -(u'FileCost', None, 900), -(u'CostInitialize', None, 800), -(u'CostFinalize', None, 1000), -(u'ExecuteAction', None, 1300), -(u'ExitDialog', None, -1), -(u'FatalError', None, -3), -(u'UserExit', None, -2), -] - -AdvtExecuteSequence = [ -(u'InstallInitialize', None, 1500), -(u'InstallFinalize', None, 6600), -(u'CostInitialize', None, 800), -(u'CostFinalize', None, 1000), -(u'InstallValidate', None, 1400), -(u'CreateShortcuts', None, 4500), -(u'MsiPublishAssemblies', None, 6250), -(u'PublishComponents', None, 6200), -(u'PublishFeatures', None, 6300), -(u'PublishProduct', None, 6400), -(u'RegisterClassInfo', None, 4600), -(u'RegisterExtensionInfo', None, 4700), -(u'RegisterMIMEInfo', None, 4900), -(u'RegisterProgIdInfo', None, 4800), -] - -InstallExecuteSequence = [ -(u'InstallInitialize', None, 1500), -(u'InstallFinalize', None, 6600), -(u'InstallFiles', None, 4000), -(u'FileCost', None, 900), -(u'CostInitialize', None, 800), -(u'CostFinalize', None, 1000), -(u'InstallValidate', None, 1400), -(u'CreateShortcuts', None, 4500), -(u'MsiPublishAssemblies', None, 6250), -(u'PublishComponents', None, 6200), -(u'PublishFeatures', None, 6300), -(u'PublishProduct', None, 6400), -(u'RegisterClassInfo', None, 4600), -(u'RegisterExtensionInfo', None, 4700), -(u'RegisterMIMEInfo', None, 4900), -(u'RegisterProgIdInfo', None, 4800), -(u'AllocateRegistrySpace', u'NOT Installed', 1550), -(u'AppSearch', None, 400), -(u'BindImage', None, 4300), -(u'CCPSearch', u'NOT Installed', 500), -(u'CreateFolders', None, 3700), -(u'DeleteServices', u'VersionNT', 2000), -(u'DuplicateFiles', None, 4210), -(u'FindRelatedProducts', None, 200), -(u'InstallODBC', None, 5400), -(u'InstallServices', u'VersionNT', 5800), -(u'IsolateComponents', None, 950), -(u'LaunchConditions', None, 100), -(u'MigrateFeatureStates', None, 1200), -(u'MoveFiles', None, 3800), -(u'PatchFiles', None, 4090), -(u'ProcessComponents', None, 1600), -(u'RegisterComPlus', None, 5700), -(u'RegisterFonts', None, 5300), -(u'RegisterProduct', None, 6100), -(u'RegisterTypeLibraries', None, 5500), -(u'RegisterUser', None, 6000), -(u'RemoveDuplicateFiles', None, 3400), -(u'RemoveEnvironmentStrings', None, 3300), -(u'RemoveExistingProducts', None, 6700), -(u'RemoveFiles', None, 3500), -(u'RemoveFolders', None, 3600), -(u'RemoveIniValues', None, 3100), -(u'RemoveODBC', None, 2400), -(u'RemoveRegistryValues', None, 2600), -(u'RemoveShortcuts', None, 3200), -(u'RMCCPSearch', u'NOT Installed', 600), -(u'SelfRegModules', None, 5600), -(u'SelfUnregModules', None, 2200), -(u'SetODBCFolders', None, 1100), -(u'StartServices', u'VersionNT', 5900), -(u'StopServices', u'VersionNT', 1900), -(u'MsiUnpublishAssemblies', None, 1750), -(u'UnpublishComponents', None, 1700), -(u'UnpublishFeatures', None, 1800), -(u'UnregisterClassInfo', None, 2700), -(u'UnregisterComPlus', None, 2100), -(u'UnregisterExtensionInfo', None, 2800), -(u'UnregisterFonts', None, 2500), -(u'UnregisterMIMEInfo', None, 3000), -(u'UnregisterProgIdInfo', None, 2900), -(u'UnregisterTypeLibraries', None, 2300), -(u'ValidateProductID', None, 700), -(u'WriteEnvironmentStrings', None, 5200), -(u'WriteIniValues', None, 5100), -(u'WriteRegistryValues', None, 5000), -] - -InstallUISequence = [ -(u'FileCost', None, 900), -(u'CostInitialize', None, 800), -(u'CostFinalize', None, 1000), -(u'ExecuteAction', None, 1300), -(u'ExitDialog', None, -1), -(u'FatalError', None, -3), -(u'UserExit', None, -2), -(u'AppSearch', None, 400), -(u'CCPSearch', u'NOT Installed', 500), -(u'FindRelatedProducts', None, 200), -(u'IsolateComponents', None, 950), -(u'LaunchConditions', None, 100), -(u'MigrateFeatureStates', None, 1200), -(u'RMCCPSearch', u'NOT Installed', 600), -(u'ValidateProductID', None, 700), -] - -tables=['AdminExecuteSequence', 'AdminUISequence', 'AdvtExecuteSequence', 'InstallExecuteSequence', 'InstallUISequence'] diff --git a/Tools/msi/tcltk/tcltk.wixproj b/Tools/msi/tcltk/tcltk.wixproj new file mode 100644 index 000000000000..4d1d74c99e89 --- /dev/null +++ b/Tools/msi/tcltk/tcltk.wixproj @@ -0,0 +1,49 @@ + + + + {DB350600-186C-4E52-BA98-26A7CECB067F} + 2.0 + tcltk + Package + + + + ICE43 + + + + + + + + + + + + $(tcltkDir) + !(bindpath.tcltk) + $(tcltkDir)bin + DLLs\ + tcltk_dlls + + + + $(tcltkDir) + !(bindpath.tcltk) + $(tcltkDir)lib + tcl\ + tcltk_lib + + + + $(PySourcePath) + !(bindpath.src) + $(PySourcePath) + + tkinter_lib + + + + + \ No newline at end of file diff --git a/Tools/msi/tcltk/tcltk.wxs b/Tools/msi/tcltk/tcltk.wxs new file mode 100644 index 000000000000..819fccb9c32a --- /dev/null +++ b/Tools/msi/tcltk/tcltk.wxs @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + PYTHON_EXE + + + + + + + + + + + + + + + + + + diff --git a/Tools/msi/tcltk/tcltk_d.wixproj b/Tools/msi/tcltk/tcltk_d.wixproj new file mode 100644 index 000000000000..3266190da0c9 --- /dev/null +++ b/Tools/msi/tcltk/tcltk_d.wixproj @@ -0,0 +1,28 @@ + + + + {EDA1FA5A-E2AA-4EAF-B49B-87D981CD0F16} + 2.0 + tcltk_d + Package + + + + + + + + + + + + $(tcltkDir) + !(bindpath.tcltk) + $(tcltkDir)bin + DLLs\ + tcltk_dlls_d + + + + + \ No newline at end of file diff --git a/Tools/msi/tcltk/tcltk_d.wxs b/Tools/msi/tcltk/tcltk_d.wxs new file mode 100644 index 000000000000..7f5048f04a69 --- /dev/null +++ b/Tools/msi/tcltk/tcltk_d.wxs @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/Tools/msi/tcltk/tcltk_en-US.wxl_template b/Tools/msi/tcltk/tcltk_en-US.wxl_template new file mode 100644 index 000000000000..d0f8c1049729 --- /dev/null +++ b/Tools/msi/tcltk/tcltk_en-US.wxl_template @@ -0,0 +1,8 @@ + + + Tcl/Tk Support + tcltk + No !(loc.ProductName) installation was detected. + IDLE (Python {{ShortVersion}} {{Bitness}}) + Launches IDLE, the interactive environment for !(loc.ProductName). + diff --git a/Tools/msi/tcltk/tcltk_files.wxs b/Tools/msi/tcltk/tcltk_files.wxs new file mode 100644 index 000000000000..0d1b4a93a3a4 --- /dev/null +++ b/Tools/msi/tcltk/tcltk_files.wxs @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/msi/tcltk/tcltk_pdb.wixproj b/Tools/msi/tcltk/tcltk_pdb.wixproj new file mode 100644 index 000000000000..3370798a0559 --- /dev/null +++ b/Tools/msi/tcltk/tcltk_pdb.wixproj @@ -0,0 +1,19 @@ + + + + {02053AFA-1831-499A-B3EA-D8B223D3C40D} + 2.0 + tcltk_pdb + Package + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/tcltk/tcltk_pdb.wxs b/Tools/msi/tcltk/tcltk_pdb.wxs new file mode 100644 index 000000000000..75c62bb4293f --- /dev/null +++ b/Tools/msi/tcltk/tcltk_pdb.wxs @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/Tools/msi/test/test.wixproj b/Tools/msi/test/test.wixproj new file mode 100644 index 000000000000..8347e3f1d3db --- /dev/null +++ b/Tools/msi/test/test.wixproj @@ -0,0 +1,29 @@ + + + + {DE0B7CC2-4358-4131-B3F4-C31C7F2CD468} + 2.0 + test + Package + + + + + + + + + + + + $(PySourcePath) + !(bindpath.src) + $(PySourcePath) + + test_py + + + + + \ No newline at end of file diff --git a/Tools/msi/test/test.wxs b/Tools/msi/test/test.wxs new file mode 100644 index 000000000000..de477858eb33 --- /dev/null +++ b/Tools/msi/test/test.wxs @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/Tools/msi/test/test_d.wixproj b/Tools/msi/test/test_d.wixproj new file mode 100644 index 000000000000..33b04be1fe60 --- /dev/null +++ b/Tools/msi/test/test_d.wixproj @@ -0,0 +1,19 @@ + + + + {41F5AE8D-24CD-4D03-BE75-AA6F7FAB4097} + 2.0 + test_d + Package + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/test/test_d.wxs b/Tools/msi/test/test_d.wxs new file mode 100644 index 000000000000..a25afdda92a5 --- /dev/null +++ b/Tools/msi/test/test_d.wxs @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/Tools/msi/test/test_en-US.wxl b/Tools/msi/test/test_en-US.wxl new file mode 100644 index 000000000000..e615c7a6b7f7 --- /dev/null +++ b/Tools/msi/test/test_en-US.wxl @@ -0,0 +1,7 @@ + + + Test Suite + test + !(loc.FullProductName) native libtest + !(loc.ProductName) Native Test Modules + diff --git a/Tools/msi/test/test_files.wxs b/Tools/msi/test/test_files.wxs new file mode 100644 index 000000000000..2d5f593344cf --- /dev/null +++ b/Tools/msi/test/test_files.wxs @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/msi/test/test_pdb.wixproj b/Tools/msi/test/test_pdb.wixproj new file mode 100644 index 000000000000..965f0edd9b49 --- /dev/null +++ b/Tools/msi/test/test_pdb.wixproj @@ -0,0 +1,19 @@ + + + + {7CF48ADD-CFAA-499F-9A05-BA18440A3344} + 2.0 + test_pdb + Package + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/test/test_pdb.wxs b/Tools/msi/test/test_pdb.wxs new file mode 100644 index 000000000000..1510a6f8ec1c --- /dev/null +++ b/Tools/msi/test/test_pdb.wxs @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/Tools/msi/testrelease.bat b/Tools/msi/testrelease.bat new file mode 100644 index 000000000000..5c9e01581a9b --- /dev/null +++ b/Tools/msi/testrelease.bat @@ -0,0 +1,100 @@ +@setlocal +@echo off + +set D=%~dp0 +set PCBUILD=%D%..\..\PCBuild\ + +set TARGETDIR=%TEMP% +set TESTX86= +set TESTX64= +set TESTALLUSER= +set TESTPERUSER= + +:CheckOpts +if "%1" EQU "-h" goto Help +if "%1" EQU "-x86" (set TESTX86=1) && shift && goto CheckOpts +if "%1" EQU "-x64" (set TESTX64=1) && shift && goto CheckOpts +if "%1" EQU "-t" (set TARGETDIR=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "--target" (set TARGETDIR=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "-a" (set TESTALLUSER=1) && shift && goto CheckOpts +if "%1" EQU "--alluser" (set TESTALLUSER=1) && shift && goto CheckOpts +if "%1" EQU "-p" (set TESTPERUSER=1) && shift && goto CheckOpts +if "%1" EQU "--peruser" (set TESTPERUSER=1) && shift && goto CheckOpts + +if not defined TESTX86 if not defined TESTX64 (set TESTX86=1) && (set TESTX64=1) +if not defined TESTALLUSER if not defined TESTPERUSER (set TESTALLUSER=1) && (set TESTPERUSER=1) + + +if defined TESTX86 ( + for %%f in ("%PCBUILD%win32\en-us\*.exe") do ( + if defined TESTALLUSER call :test "%%~ff" "%TARGETDIR%\%%~nf-alluser" "InstallAllUsers=1 CompileAll=1" + if errorlevel 1 exit /B + if defined TESTPERUSER call :test "%%~ff" "%TARGETDIR%\%%~nf-peruser" "InstallAllUsers=0 CompileAll=0" + if errorlevel 1 exit /B + ) +) + +if defined TESTX64 ( + for %%f in ("%PCBUILD%amd64\en-us\*.exe") do ( + if defined TESTALLUSER call :test "%%~ff" "%TARGETDIR%\%%~nf-alluser" "InstallAllUsers=1 CompileAll=1" + if errorlevel 1 exit /B + if defined TESTPERUSER call :test "%%~ff" "%TARGETDIR%\%%~nf-peruser" "InstallAllUsers=0 CompileAll=0" + if errorlevel 1 exit /B + ) +) + +exit /B 0 + +:test +@setlocal +@echo on + +@if not exist "%~1" exit /B 1 + +@set EXITCODE=0 +@echo Installing %1 into %2 +"%~1" /passive /log "%~2\install\log.txt" TargetDir="%~2\Python" Include_debug=1 Include_symbols=1 %~3 + +@if not errorlevel 1 ( + @echo Printing version + "%~2\Python\python.exe" -c "import sys; print(sys.version)" > "%~2\version.txt" 2>&1 +) +@if not errorlevel 1 ( + @echo Installing package + "%~2\Python\python.exe" -m pip install azure > "%~2\pip.txt" 2>&1 + @if not errorlevel 1 ( + "%~2\Python\python.exe" -m pip uninstall -y azure python-dateutil six >> "%~2\pip.txt" 2>&1 + ) +) +@if not errorlevel 1 ( + @echo Testing Tcl/tk + @set TCL_LIBRARY=%~2\Python\tcl\tcl8.6 + "%~2\Python\python.exe" -m test -uall -v test_ttk_guionly test_tk test_idle > "%~2\tcltk.txt" 2>&1 + @set TCL_LIBRARY= +) + +@set EXITCODE=%ERRORLEVEL% + +@for /d %%f in ("%PROGRAMDATA%\Microsoft\Windows\Start Menu\Programs\Python*") do @dir "%%~ff\*.lnk" /s/b > "%~2\startmenu.txt" 2>&1 +@for /d %%f in ("%APPDATA%\Microsoft\Windows\Start Menu\Programs\Python*") do @dir "%%~ff\*.lnk" /s/b >> "%~2\startmenu.txt" 2>&1 + +@echo Result was %EXITCODE% +@echo Removing %1 +"%~1" /passive /uninstall /log "%~2\uninstall\log.txt" + +@echo off +exit /B %EXITCODE% + +:Help +echo testrelease.bat [--target TARGET] [-x86] [-x64] [--alluser] [--peruser] [-h] +echo. +echo --target (-t) Specify the target directory for installs and logs +echo -x86 Run tests for x86 installers +echo -x64 Run tests for x64 installers +echo --alluser (-a) Run tests for all-user installs (requires Administrator) +echo --peruser (-p) Run tests for per-user installs +echo -h Display this help information +echo. +echo If no test architecture is specified, all architectures will be tested. +echo If no install type is selected, all install types will be tested. +echo. diff --git a/Tools/msi/tools/tools.wixproj b/Tools/msi/tools/tools.wixproj new file mode 100644 index 000000000000..f43cf3309e9b --- /dev/null +++ b/Tools/msi/tools/tools.wixproj @@ -0,0 +1,43 @@ + + + + {24CBEB95-BC1E-4EA9-AEA9-33834BCCD0EC} + 2.0 + tools + Package + + + + + + + + + + + + + + + $(PySourcePath) + !(bindpath.src) + $(PySourcePath) + + tools_py + + + + + \ No newline at end of file diff --git a/Tools/msi/tools/tools.wxs b/Tools/msi/tools/tools.wxs new file mode 100644 index 000000000000..366d4c68f30e --- /dev/null +++ b/Tools/msi/tools/tools.wxs @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/Tools/msi/tools/tools_en-US.wxl b/Tools/msi/tools/tools_en-US.wxl new file mode 100644 index 000000000000..a1384177ea26 --- /dev/null +++ b/Tools/msi/tools/tools_en-US.wxl @@ -0,0 +1,5 @@ + + + Utility Scripts + tools + diff --git a/Tools/msi/tools/tools_files.wxs b/Tools/msi/tools/tools_files.wxs new file mode 100644 index 000000000000..3ae0db2e1fd3 --- /dev/null +++ b/Tools/msi/tools/tools_files.wxs @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/Tools/msi/uisample.py b/Tools/msi/uisample.py deleted file mode 100644 index 543080554e87..000000000000 --- a/Tools/msi/uisample.py +++ /dev/null @@ -1,1400 +0,0 @@ - -import msilib,os;dirname=os.path.dirname(__file__) -AdminExecuteSequence = [ -(u'InstallValidate', None, 1400), -(u'InstallInitialize', None, 1500), -(u'InstallFinalize', None, 6600), -(u'InstallFiles', None, 4000), -(u'InstallAdminPackage', None, 3900), -(u'FileCost', None, 900), -(u'CostInitialize', None, 800), -(u'CostFinalize', None, 1000), -] - -AdminUISequence = [ -(u'AdminWelcomeDlg', None, 1230), -(u'FileCost', None, 900), -(u'CostInitialize', None, 800), -(u'CostFinalize', None, 1000), -(u'ExecuteAction', None, 1300), -(u'ExitDialog', None, -1), -(u'FatalError', None, -3), -(u'PrepareDlg', None, 140), -(u'ProgressDlg', None, 1280), -(u'UserExit', None, -2), -] - -AdvtExecuteSequence = [ -(u'InstallValidate', None, 1400), -(u'InstallInitialize', None, 1500), -(u'InstallFinalize', None, 6600), -(u'CostInitialize', None, 800), -(u'CostFinalize', None, 1000), -(u'CreateShortcuts', None, 4500), -(u'PublishComponents', None, 6200), -(u'PublishFeatures', None, 6300), -(u'PublishProduct', None, 6400), -(u'RegisterClassInfo', None, 4600), -(u'RegisterExtensionInfo', None, 4700), -(u'RegisterMIMEInfo', None, 4900), -(u'RegisterProgIdInfo', None, 4800), -] - -BBControl = [ -] - -Billboard = [ -] - -Binary = [ -(u'bannrbmp', msilib.Binary(os.path.join(dirname,"bannrbmp.bin"))), -(u'completi', msilib.Binary(os.path.join(dirname,"completi.bin"))), -(u'custicon', msilib.Binary(os.path.join(dirname,"custicon.bin"))), -(u'dlgbmp', msilib.Binary(os.path.join(dirname,"dlgbmp.bin"))), -(u'exclamic', msilib.Binary(os.path.join(dirname,"exclamic.bin"))), -(u'info', msilib.Binary(os.path.join(dirname,"info.bin"))), -(u'insticon', msilib.Binary(os.path.join(dirname,"insticon.bin"))), -(u'New', msilib.Binary(os.path.join(dirname,"New.bin"))), -(u'removico', msilib.Binary(os.path.join(dirname,"removico.bin"))), -(u'repairic', msilib.Binary(os.path.join(dirname,"repairic.bin"))), -(u'Up', msilib.Binary(os.path.join(dirname,"Up.bin"))), -] - -CheckBox = [ -] - -Property = [ -(u'BannerBitmap', u'bannrbmp'), -(u'IAgree', u'No'), -(u'ProductID', u'none'), -(u'ARPHELPLINK', u'http://www.microsoft.com/management'), -(u'ButtonText_Back', u'< &Back'), -(u'ButtonText_Browse', u'Br&owse'), -(u'ButtonText_Cancel', u'Cancel'), -(u'ButtonText_Exit', u'&Exit'), -(u'ButtonText_Finish', u'&Finish'), -(u'ButtonText_Ignore', u'&Ignore'), -(u'ButtonText_Install', u'&Install'), -(u'ButtonText_Next', u'&Next >'), -(u'ButtonText_No', u'&No'), -(u'ButtonText_OK', u'OK'), -(u'ButtonText_Remove', u'&Remove'), -(u'ButtonText_Repair', u'&Repair'), -(u'ButtonText_Reset', u'&Reset'), -(u'ButtonText_Resume', u'&Resume'), -(u'ButtonText_Retry', u'&Retry'), -(u'ButtonText_Return', u'&Return'), -(u'ButtonText_Yes', u'&Yes'), -(u'CompleteSetupIcon', u'completi'), -(u'ComponentDownload', u'ftp://anonymous@microsoft.com/components/'), -(u'CustomSetupIcon', u'custicon'), -(u'DefaultUIFont', u'DlgFont8'), -(u'DialogBitmap', u'dlgbmp'), -(u'DlgTitleFont', u'{&DlgFontBold8}'), -(u'ErrorDialog', u'ErrorDlg'), -(u'ExclamationIcon', u'exclamic'), -(u'InfoIcon', u'info'), -(u'InstallerIcon', u'insticon'), -(u'INSTALLLEVEL', u'3'), -(u'InstallMode', u'Typical'), -(u'PIDTemplate', u'12345<###-%%%%%%%>@@@@@'), -#(u'ProductLanguage', u'1033'), -(u'Progress1', u'Installing'), -(u'Progress2', u'installs'), -(u'PROMPTROLLBACKCOST', u'P'), -(u'RemoveIcon', u'removico'), -(u'RepairIcon', u'repairic'), -(u'Setup', u'Setup'), -(u'ShowUserRegistrationDlg', u'1'), -(u'Wizard', u'Setup Wizard'), -] - -ComboBox = [ -] - -Control = [ -(u'AdminWelcomeDlg', u'Bitmap', u'Bitmap', 0, 0, 370, 234, 1, None, u'[DialogBitmap]', u'Back', None), -(u'AdminWelcomeDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'AdminWelcomeDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'Bitmap', None), -(u'AdminWelcomeDlg', u'Description', u'Text', 135, 70, 220, 30, 196611, None, u'The [Wizard] will create a server image of [ProductName], at a specified network location. Click Next to continue or Cancel to exit the [Wizard].', None, None), -(u'AdminWelcomeDlg', u'Title', u'Text', 135, 20, 220, 60, 196611, None, u'{\\VerdanaBold13}Welcome to the [ProductName] [Wizard]', None, None), -(u'AdminWelcomeDlg', u'Back', u'PushButton', 180, 243, 56, 17, 1, None, u'[ButtonText_Back]', u'Next', None), -(u'AdminWelcomeDlg', u'Next', u'PushButton', 236, 243, 56, 17, 3, None, u'[ButtonText_Next]', u'Cancel', None), -(u'ExitDialog', u'Bitmap', u'Bitmap', 0, 0, 370, 234, 1, None, u'[DialogBitmap]', u'Back', None), -(u'ExitDialog', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'ExitDialog', u'Cancel', u'PushButton', 304, 243, 56, 17, 1, None, u'[ButtonText_Cancel]', u'Bitmap', None), -(u'ExitDialog', u'Description', u'Text', 135, 70, 220, 20, 196611, None, u'Click the Finish button to exit the [Wizard].', None, None), -(u'ExitDialog', u'Title', u'Text', 135, 20, 220, 60, 196611, None, u'{\\VerdanaBold13}Completing the [ProductName] [Wizard]', None, None), -(u'ExitDialog', u'Back', u'PushButton', 180, 243, 56, 17, 1, None, u'[ButtonText_Back]', u'Finish', None), -(u'ExitDialog', u'Finish', u'PushButton', 236, 243, 56, 17, 3, None, u'[ButtonText_Finish]', u'Cancel', None), -(u'FatalError', u'Bitmap', u'Bitmap', 0, 0, 370, 234, 1, None, u'[DialogBitmap]', u'Back', None), -(u'FatalError', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'FatalError', u'Cancel', u'PushButton', 304, 243, 56, 17, 1, None, u'[ButtonText_Cancel]', u'Bitmap', None), -(u'FatalError', u'Title', u'Text', 135, 20, 220, 60, 196611, None, u'{\\VerdanaBold13}[ProductName] [Wizard] ended prematurely', None, None), -(u'FatalError', u'Back', u'PushButton', 180, 243, 56, 17, 1, None, u'[ButtonText_Back]', u'Finish', None), -(u'FatalError', u'Finish', u'PushButton', 236, 243, 56, 17, 3, None, u'[ButtonText_Finish]', u'Cancel', None), -(u'FatalError', u'Description1', u'Text', 135, 70, 220, 40, 196611, None, u'[ProductName] setup ended prematurely because of an error. Your system has not been modified. To install this program at a later time, please run the installation again.', None, None), -(u'FatalError', u'Description2', u'Text', 135, 115, 220, 20, 196611, None, u'Click the Finish button to exit the [Wizard].', None, None), -(u'PrepareDlg', u'Bitmap', u'Bitmap', 0, 0, 370, 234, 1, None, u'[DialogBitmap]', u'Cancel', None), -(u'PrepareDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'PrepareDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'Bitmap', None), -(u'PrepareDlg', u'Description', u'Text', 135, 70, 220, 20, 196611, None, u'Please wait while the [Wizard] prepares to guide you through the installation.', None, None), -(u'PrepareDlg', u'Title', u'Text', 135, 20, 220, 60, 196611, None, u'{\\VerdanaBold13}Welcome to the [ProductName] [Wizard]', None, None), -(u'PrepareDlg', u'Back', u'PushButton', 180, 243, 56, 17, 1, None, u'[ButtonText_Back]', None, None), -(u'PrepareDlg', u'Next', u'PushButton', 236, 243, 56, 17, 1, None, u'[ButtonText_Next]', None, None), -(u'PrepareDlg', u'ActionData', u'Text', 135, 125, 220, 30, 196611, None, None, None, None), -(u'PrepareDlg', u'ActionText', u'Text', 135, 100, 220, 20, 196611, None, None, None, None), -(u'ProgressDlg', u'Text', u'Text', 35, 65, 300, 20, 3, None, u'Please wait while the [Wizard] [Progress2] [ProductName]. This may take several minutes.', None, None), -(u'ProgressDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'Back', None), -(u'ProgressDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None), -(u'ProgressDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'ProgressDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'BannerBitmap', None), -(u'ProgressDlg', u'Title', u'Text', 20, 15, 200, 15, 196611, None, u'[DlgTitleFont][Progress1] [ProductName]', None, None), -(u'ProgressDlg', u'Back', u'PushButton', 180, 243, 56, 17, 1, None, u'[ButtonText_Back]', u'Next', None), -(u'ProgressDlg', u'Next', u'PushButton', 236, 243, 56, 17, 1, None, u'[ButtonText_Next]', u'Cancel', None), -(u'ProgressDlg', u'ActionText', u'Text', 70, 100, 265, 10, 3, None, None, None, None), -(u'ProgressDlg', u'ProgressBar', u'ProgressBar', 35, 115, 300, 10, 65537, None, u'Progress done', None, None), -(u'ProgressDlg', u'StatusLabel', u'Text', 35, 100, 35, 10, 3, None, u'Status:', None, None), -(u'UserExit', u'Bitmap', u'Bitmap', 0, 0, 370, 234, 1, None, u'[DialogBitmap]', u'Back', None), -(u'UserExit', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'UserExit', u'Cancel', u'PushButton', 304, 243, 56, 17, 1, None, u'[ButtonText_Cancel]', u'Bitmap', None), -(u'UserExit', u'Title', u'Text', 135, 20, 220, 60, 196611, None, u'{\\VerdanaBold13}[ProductName] [Wizard] was interrupted', None, None), -(u'UserExit', u'Back', u'PushButton', 180, 243, 56, 17, 1, None, u'[ButtonText_Back]', u'Finish', None), -(u'UserExit', u'Finish', u'PushButton', 236, 243, 56, 17, 3, None, u'[ButtonText_Finish]', u'Cancel', None), -(u'UserExit', u'Description1', u'Text', 135, 70, 220, 40, 196611, None, u'[ProductName] setup was interrupted. Your system has not been modified. To install this program at a later time, please run the installation again.', None, None), -(u'UserExit', u'Description2', u'Text', 135, 115, 220, 20, 196611, None, u'Click the Finish button to exit the [Wizard].', None, None), -(u'AdminBrowseDlg', u'Up', u'PushButton', 298, 55, 19, 19, 3670019, None, u'Up', u'NewFolder', u'Up One Level|'), -(u'AdminBrowseDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'PathEdit', None), -(u'AdminBrowseDlg', u'PathEdit', u'PathEdit', 84, 202, 261, 17, 3, u'TARGETDIR', None, u'OK', None), -(u'AdminBrowseDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None), -(u'AdminBrowseDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'AdminBrowseDlg', u'Cancel', u'PushButton', 240, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'ComboLabel', None), -(u'AdminBrowseDlg', u'ComboLabel', u'Text', 25, 58, 44, 10, 3, None, u'&Look in:', u'DirectoryCombo', None), -(u'AdminBrowseDlg', u'DirectoryCombo', u'DirectoryCombo', 70, 55, 220, 80, 458755, u'TARGETDIR', None, u'Up', None), -(u'AdminBrowseDlg', u'Description', u'Text', 25, 23, 280, 15, 196611, None, u'Browse to the destination folder', None, None), -(u'AdminBrowseDlg', u'DirectoryList', u'DirectoryList', 25, 83, 320, 110, 7, u'TARGETDIR', None, u'PathLabel', None), -(u'AdminBrowseDlg', u'PathLabel', u'Text', 25, 205, 59, 10, 3, None, u'&Folder name:', u'BannerBitmap', None), -(u'AdminBrowseDlg', u'NewFolder', u'PushButton', 325, 55, 19, 19, 3670019, None, u'New', u'DirectoryList', u'Create A New Folder|'), -(u'AdminBrowseDlg', u'OK', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_OK]', u'Cancel', None), -(u'AdminBrowseDlg', u'Title', u'Text', 15, 6, 200, 15, 196611, None, u'[DlgTitleFont]Change current destination folder', None, None), -(u'AdminInstallPointDlg', u'Text', u'Text', 25, 80, 320, 10, 3, None, u'&Enter a new network location or click Browse to browse to one.', u'PathEdit', None), -(u'AdminInstallPointDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'Text', None), -(u'AdminInstallPointDlg', u'PathEdit', u'PathEdit', 25, 93, 320, 18, 3, u'TARGETDIR', None, u'Browse', None), -(u'AdminInstallPointDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None), -(u'AdminInstallPointDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'AdminInstallPointDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'BannerBitmap', None), -(u'AdminInstallPointDlg', u'Description', u'Text', 25, 20, 280, 20, 196611, None, u'Please specify a network location for the server image of [ProductName] product', None, None), -(u'AdminInstallPointDlg', u'Title', u'Text', 15, 6, 200, 15, 196611, None, u'[DlgTitleFont]Network Location', None, None), -(u'AdminInstallPointDlg', u'Back', u'PushButton', 180, 243, 56, 17, 3, None, u'[ButtonText_Back]', u'Next', None), -(u'AdminInstallPointDlg', u'Next', u'PushButton', 236, 243, 56, 17, 3, None, u'[ButtonText_Next]', u'Cancel', None), -(u'AdminInstallPointDlg', u'Browse', u'PushButton', 289, 119, 56, 17, 3, None, u'[ButtonText_Browse]', u'Back', None), -(u'AdminRegistrationDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'OrganizationLabel', None), -(u'AdminRegistrationDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None), -(u'AdminRegistrationDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'AdminRegistrationDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'BannerBitmap', None), -(u'AdminRegistrationDlg', u'Description', u'Text', 25, 23, 280, 15, 196611, None, u'Please enter your company information', None, None), -(u'AdminRegistrationDlg', u'Title', u'Text', 15, 6, 200, 15, 196611, None, u'[DlgTitleFont]Company Information', None, None), -(u'AdminRegistrationDlg', u'Back', u'PushButton', 180, 243, 56, 17, 65539, None, u'[ButtonText_Back]', u'Next', None), -(u'AdminRegistrationDlg', u'Next', u'PushButton', 236, 243, 56, 17, 3, None, u'[ButtonText_Next]', u'Cancel', None), -(u'AdminRegistrationDlg', u'OrganizationLabel', u'Text', 45, 71, 285, 30, 3, None, u'&Please enter the name of your organization in the box below. This will be used as default company name for subsequent installations of [ProductName]:', u'OrganizationEdit', None), -(u'AdminRegistrationDlg', u'CDKeyEdit', u'MaskedEdit', 45, 143, 250, 16, 3, u'PIDKEY', u'[PIDTemplate]', u'Back', None), -(u'AdminRegistrationDlg', u'CDKeyLabel', u'Text', 45, 130, 50, 10, 3, None, u'CD &Key:', u'CDKeyEdit', None), -(u'AdminRegistrationDlg', u'OrganizationEdit', u'Edit', 45, 105, 220, 18, 3, u'COMPANYNAME', u'{80}', u'CDKeyLabel', None), -(u'BrowseDlg', u'Up', u'PushButton', 298, 55, 19, 19, 3670019, None, u'Up', u'NewFolder', u'Up One Level|'), -(u'BrowseDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'PathEdit', None), -(u'BrowseDlg', u'PathEdit', u'PathEdit', 84, 202, 261, 18, 11, u'_BrowseProperty', None, u'OK', None), -(u'BrowseDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None), -(u'BrowseDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'BrowseDlg', u'Cancel', u'PushButton', 240, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'ComboLabel', None), -(u'BrowseDlg', u'ComboLabel', u'Text', 25, 58, 44, 10, 3, None, u'&Look in:', u'DirectoryCombo', None), -(u'BrowseDlg', u'DirectoryCombo', u'DirectoryCombo', 70, 55, 220, 80, 393227, u'_BrowseProperty', None, u'Up', None), -(u'BrowseDlg', u'Description', u'Text', 25, 23, 280, 15, 196611, None, u'Browse to the destination folder', None, None), -(u'BrowseDlg', u'DirectoryList', u'DirectoryList', 25, 83, 320, 110, 15, u'_BrowseProperty', None, u'PathLabel', None), -(u'BrowseDlg', u'PathLabel', u'Text', 25, 205, 59, 10, 3, None, u'&Folder name:', u'BannerBitmap', None), -(u'BrowseDlg', u'NewFolder', u'PushButton', 325, 55, 19, 19, 3670019, None, u'New', u'DirectoryList', u'Create A New Folder|'), -(u'BrowseDlg', u'OK', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_OK]', u'Cancel', None), -(u'BrowseDlg', u'Title', u'Text', 15, 6, 200, 15, 196611, None, u'[DlgTitleFont]Change current destination folder', None, None), -(u'CancelDlg', u'Text', u'Text', 48, 15, 194, 30, 3, None, u'Are you sure you want to cancel [ProductName] installation?', None, None), -(u'CancelDlg', u'Icon', u'Icon', 15, 15, 24, 24, 5242881, None, u'[InfoIcon]', None, u'Information icon|'), -(u'CancelDlg', u'No', u'PushButton', 132, 57, 56, 17, 3, None, u'[ButtonText_No]', u'Yes', None), -(u'CancelDlg', u'Yes', u'PushButton', 72, 57, 56, 17, 3, None, u'[ButtonText_Yes]', u'No', None), -(u'CustomizeDlg', u'Text', u'Text', 25, 55, 320, 20, 3, None, u'Click on the icons in the tree below to change the way features will be installed.', None, None), -(u'CustomizeDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'Tree', None), -(u'CustomizeDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None), -(u'CustomizeDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'CustomizeDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'BannerBitmap', None), -(u'CustomizeDlg', u'Description', u'Text', 25, 23, 280, 15, 196611, None, u'Select the way you want features to be installed.', None, None), -(u'CustomizeDlg', u'Title', u'Text', 15, 6, 200, 15, 196611, None, u'[DlgTitleFont]Custom Setup', None, None), -(u'CustomizeDlg', u'Back', u'PushButton', 180, 243, 56, 17, 3, None, u'[ButtonText_Back]', u'Next', None), -(u'CustomizeDlg', u'Next', u'PushButton', 236, 243, 56, 17, 3, None, u'[ButtonText_Next]', u'Cancel', None), -(u'CustomizeDlg', u'Browse', u'PushButton', 304, 200, 56, 17, 3, None, u'[ButtonText_Browse]', u'Reset', None), -(u'CustomizeDlg', u'Tree', u'SelectionTree', 25, 85, 175, 95, 7, u'_BrowseProperty', u'Tree of selections', u'Browse', None), -(u'CustomizeDlg', u'Box', u'GroupBox', 210, 81, 140, 98, 1, None, None, None, None), -(u'CustomizeDlg', u'Reset', u'PushButton', 42, 243, 56, 17, 3, None, u'[ButtonText_Reset]', u'DiskCost', None), -(u'CustomizeDlg', u'DiskCost', u'PushButton', 111, 243, 56, 17, 3, None, u'Disk &Usage', u'Back', None), -(u'CustomizeDlg', u'ItemDescription', u'Text', 215, 90, 131, 30, 3, None, u'Multiline description of the currently selected item.', None, None), -(u'CustomizeDlg', u'ItemSize', u'Text', 215, 130, 131, 45, 3, None, u'The size of the currently selected item.', None, None), -(u'CustomizeDlg', u'Location', u'Text', 75, 200, 215, 20, 3, None, u"", None, None), -(u'CustomizeDlg', u'LocationLabel', u'Text', 25, 200, 50, 10, 3, None, u'Location:', None, None), -(u'DiskCostDlg', u'Text', u'Text', 20, 53, 330, 40, 3, None, u'The highlighted volumes (if any) do not have enough disk space available for the currently selected features. You can either remove some files from the highlighted volumes, or choose to install less features onto local drive(s), or select different destination drive(s).', None, None), -(u'DiskCostDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'OK', None), -(u'DiskCostDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None), -(u'DiskCostDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'DiskCostDlg', u'Description', u'Text', 20, 20, 280, 20, 196611, None, u'The disk space required for the installation of the selected features.', None, None), -(u'DiskCostDlg', u'OK', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_OK]', u'BannerBitmap', None), -(u'DiskCostDlg', u'Title', u'Text', 15, 6, 200, 15, 196611, None, u'[DlgTitleFont]Disk Space Requirements', None, None), -(u'DiskCostDlg', u'VolumeList', u'VolumeCostList', 20, 100, 330, 120, 393223, None, u'{120}{70}{70}{70}{70}', None, None), -(u'ErrorDlg', u'Y', u'PushButton', 100, 80, 56, 17, 3, None, u'[ButtonText_Yes]', None, None), -(u'ErrorDlg', u'A', u'PushButton', 100, 80, 56, 17, 3, None, u'[ButtonText_Cancel]', None, None), -(u'ErrorDlg', u'C', u'PushButton', 100, 80, 56, 17, 3, None, u'[ButtonText_Cancel]', None, None), -(u'ErrorDlg', u'ErrorIcon', u'Icon', 15, 15, 24, 24, 5242881, None, u'[InfoIcon]', None, u'Information icon|'), -(u'ErrorDlg', u'ErrorText', u'Text', 48, 15, 205, 60, 3, None, u'Information text', None, None), -(u'ErrorDlg', u'I', u'PushButton', 100, 80, 56, 17, 3, None, u'[ButtonText_Ignore]', None, None), -(u'ErrorDlg', u'N', u'PushButton', 100, 80, 56, 17, 3, None, u'[ButtonText_No]', None, None), -(u'ErrorDlg', u'O', u'PushButton', 100, 80, 56, 17, 3, None, u'[ButtonText_OK]', None, None), -(u'ErrorDlg', u'R', u'PushButton', 100, 80, 56, 17, 3, None, u'[ButtonText_Retry]', None, None), -(u'FilesInUse', u'Text', u'Text', 20, 55, 330, 30, 3, None, u'The following applications are using files that need to be updated by this setup. Close these applications and then click Retry to continue the installation or Cancel to exit it.', None, None), -(u'FilesInUse', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'Retry', None), -(u'FilesInUse', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None), -(u'FilesInUse', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'FilesInUse', u'Description', u'Text', 20, 23, 280, 20, 196611, None, u'Some files that need to be updated are currently in use.', None, None), -(u'FilesInUse', u'Title', u'Text', 15, 6, 200, 15, 196611, None, u'[DlgTitleFont]Files in Use', None, None), -(u'FilesInUse', u'Retry', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Retry]', u'Ignore', None), -(u'FilesInUse', u'Exit', u'PushButton', 166, 243, 56, 17, 3, None, u'[ButtonText_Exit]', u'BannerBitmap', None), -(u'FilesInUse', u'Ignore', u'PushButton', 235, 243, 56, 17, 3, None, u'[ButtonText_Ignore]', u'Exit', None), -(u'FilesInUse', u'List', u'ListBox', 20, 87, 330, 130, 7, u'FileInUseProcess', None, None, None), -(u'LicenseAgreementDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'AgreementText', None), -(u'LicenseAgreementDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None), -(u'LicenseAgreementDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'LicenseAgreementDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'BannerBitmap', None), -(u'LicenseAgreementDlg', u'Description', u'Text', 25, 23, 280, 15, 196611, None, u'Please read the following license agreement carefully', None, None), -(u'LicenseAgreementDlg', u'Title', u'Text', 15, 6, 200, 15, 196611, None, u'[DlgTitleFont]End-User License Agreement', None, None), -(u'LicenseAgreementDlg', u'Back', u'PushButton', 180, 243, 56, 17, 3, None, u'[ButtonText_Back]', u'Next', None), -(u'LicenseAgreementDlg', u'Next', u'PushButton', 236, 243, 56, 17, 3, None, u'[ButtonText_Next]', u'Cancel', None), -(u'LicenseAgreementDlg', u'AgreementText', u'ScrollableText', 20, 60, 330, 120, 7, None, u'{\\rtf1\\ansi\\ansicpg1252\\deff0\\deftab720{\\fonttbl{\\f0\\froman\\fprq2 Times New Roman;}}{\\colortbl\\red0\\green0\\blue0;} \\deflang1033\\horzdoc{\\*\\fchars }{\\*\\lchars }\\pard\\plain\\f0\\fs20 \\par }', u'Buttons', None), -(u'LicenseAgreementDlg', u'Buttons', u'RadioButtonGroup', 20, 187, 330, 40, 3, u'IAgree', None, u'Back', None), -(u'MaintenanceTypeDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'ChangeLabel', None), -(u'MaintenanceTypeDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None), -(u'MaintenanceTypeDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'MaintenanceTypeDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'BannerBitmap', None), -(u'MaintenanceTypeDlg', u'Description', u'Text', 25, 23, 280, 20, 196611, None, u'Select the operation you wish to perform.', None, None), -(u'MaintenanceTypeDlg', u'Title', u'Text', 15, 6, 240, 15, 196611, None, u'[DlgTitleFont]Modify, Repair or Remove installation', None, None), -(u'MaintenanceTypeDlg', u'Back', u'PushButton', 180, 243, 56, 17, 3, None, u'[ButtonText_Back]', u'Next', None), -(u'MaintenanceTypeDlg', u'Next', u'PushButton', 236, 243, 56, 17, 1, None, u'[ButtonText_Next]', u'Cancel', None), -(u'MaintenanceTypeDlg', u'ChangeLabel', u'Text', 105, 65, 100, 10, 3, None, u'[DlgTitleFont]&Modify', u'ChangeButton', None), -(u'MaintenanceTypeDlg', u'ChangeButton', u'PushButton', 50, 65, 38, 38, 5767171, None, u'[CustomSetupIcon]', u'RepairLabel', u'Modify Installation|'), -(u'MaintenanceTypeDlg', u'RepairLabel', u'Text', 105, 114, 100, 10, 3, None, u'[DlgTitleFont]Re&pair', u'RepairButton', None), -(u'MaintenanceTypeDlg', u'ChangeText', u'Text', 105, 78, 230, 20, 3, None, u'Allows users to change the way features are installed.', None, None), -(u'MaintenanceTypeDlg', u'RemoveButton', u'PushButton', 50, 163, 38, 38, 5767171, None, u'[RemoveIcon]', u'Back', u'Remove Installation|'), -(u'MaintenanceTypeDlg', u'RemoveLabel', u'Text', 105, 163, 100, 10, 3, None, u'[DlgTitleFont]&Remove', u'RemoveButton', None), -(u'MaintenanceTypeDlg', u'RemoveText', u'Text', 105, 176, 230, 20, 3, None, u'Removes [ProductName] from your computer.', None, None), -(u'MaintenanceTypeDlg', u'RepairButton', u'PushButton', 50, 114, 38, 38, 5767171, None, u'[RepairIcon]', u'RemoveLabel', u'Repair Installation|'), -(u'MaintenanceTypeDlg', u'RepairText', u'Text', 105, 127, 230, 30, 3, None, u'Repairs errors in the most recent installation state - fixes missing or corrupt files, shortcuts and registry entries.', None, None), -(u'MaintenanceWelcomeDlg', u'Bitmap', u'Bitmap', 0, 0, 370, 234, 1, None, u'[DialogBitmap]', u'Back', None), -(u'MaintenanceWelcomeDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'MaintenanceWelcomeDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'Bitmap', None), -(u'MaintenanceWelcomeDlg', u'Description', u'Text', 135, 70, 220, 60, 196611, None, u'The [Wizard] will allow you to change the way [ProductName] features are installed on your computer or even to remove [ProductName] from your computer. Click Next to continue or Cancel to exit the [Wizard].', None, None), -(u'MaintenanceWelcomeDlg', u'Title', u'Text', 135, 20, 220, 60, 196611, None, u'{\\VerdanaBold13}Welcome to the [ProductName] [Wizard]', None, None), -(u'MaintenanceWelcomeDlg', u'Back', u'PushButton', 180, 243, 56, 17, 1, None, u'[ButtonText_Back]', u'Next', None), -(u'MaintenanceWelcomeDlg', u'Next', u'PushButton', 236, 243, 56, 17, 3, None, u'[ButtonText_Next]', u'Cancel', None), -(u'OutOfDiskDlg', u'Text', u'Text', 20, 53, 330, 40, 3, None, u'The highlighted volumes do not have enough disk space available for the currently selected features. You can either remove some files from the highlighted volumes, or choose to install less features onto local drive(s), or select different destination drive(s).', None, None), -(u'OutOfDiskDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'OK', None), -(u'OutOfDiskDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None), -(u'OutOfDiskDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'OutOfDiskDlg', u'Description', u'Text', 20, 20, 280, 20, 196611, None, u'Disk space required for the installation exceeds available disk space.', None, None), -(u'OutOfDiskDlg', u'OK', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_OK]', u'BannerBitmap', None), -(u'OutOfDiskDlg', u'Title', u'Text', 15, 6, 200, 15, 196611, None, u'[DlgTitleFont]Out of Disk Space', None, None), -(u'OutOfDiskDlg', u'VolumeList', u'VolumeCostList', 20, 100, 330, 120, 393223, None, u'{120}{70}{70}{70}{70}', None, None), -(u'OutOfRbDiskDlg', u'Text', u'Text', 20, 53, 330, 40, 3, None, u'The highlighted volumes do not have enough disk space available for the currently selected features. You can either remove some files from the highlighted volumes, or choose to install less features onto local drive(s), or select different destination drive(s).', None, None), -(u'OutOfRbDiskDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'No', None), -(u'OutOfRbDiskDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None), -(u'OutOfRbDiskDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'OutOfRbDiskDlg', u'Description', u'Text', 20, 20, 280, 20, 196611, None, u'Disk space required for the installation exceeds available disk space.', None, None), -(u'OutOfRbDiskDlg', u'Title', u'Text', 15, 6, 200, 15, 196611, None, u'[DlgTitleFont]Out of Disk Space', None, None), -(u'OutOfRbDiskDlg', u'No', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_No]', u'Yes', None), -(u'OutOfRbDiskDlg', u'Yes', u'PushButton', 240, 243, 56, 17, 3, None, u'[ButtonText_Yes]', u'BannerBitmap', None), -(u'OutOfRbDiskDlg', u'VolumeList', u'VolumeCostList', 20, 140, 330, 80, 4587527, None, u'{120}{70}{70}{70}{70}', None, None), -(u'OutOfRbDiskDlg', u'Text2', u'Text', 20, 94, 330, 40, 3, None, u"Alternatively, you may choose to disable the installer's rollback functionality. This allows the installer to restore your computer's original state should the installation be interrupted in any way. Click Yes if you wish to take the risk to disable rollback.", None, None), -(u'ResumeDlg', u'Bitmap', u'Bitmap', 0, 0, 370, 234, 1, None, u'[DialogBitmap]', u'Back', None), -(u'ResumeDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'ResumeDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'Bitmap', None), -(u'ResumeDlg', u'Description', u'Text', 135, 70, 220, 30, 196611, None, u'The [Wizard] will complete the installation of [ProductName] on your computer. Click Install to continue or Cancel to exit the [Wizard].', None, None), -(u'ResumeDlg', u'Title', u'Text', 135, 20, 220, 60, 196611, None, u'{\\VerdanaBold13}Resuming the [ProductName] [Wizard]', None, None), -(u'ResumeDlg', u'Back', u'PushButton', 180, 243, 56, 17, 1, None, u'[ButtonText_Back]', u'Install', None), -(u'ResumeDlg', u'Install', u'PushButton', 236, 243, 56, 17, 3, None, u'[ButtonText_Install]', u'Cancel', None), -(u'SetupTypeDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'TypicalLabel', None), -(u'SetupTypeDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None), -(u'SetupTypeDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'SetupTypeDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'BannerBitmap', None), -(u'SetupTypeDlg', u'Description', u'Text', 25, 23, 280, 15, 196611, None, u'Choose the setup type that best suits your needs', None, None), -(u'SetupTypeDlg', u'Title', u'Text', 15, 6, 200, 15, 196611, None, u'[DlgTitleFont]Choose Setup Type', None, None), -(u'SetupTypeDlg', u'Back', u'PushButton', 180, 243, 56, 17, 3, None, u'[ButtonText_Back]', u'Next', None), -(u'SetupTypeDlg', u'Next', u'PushButton', 236, 243, 56, 17, 1, None, u'[ButtonText_Next]', u'Cancel', None), -(u'SetupTypeDlg', u'TypicalLabel', u'Text', 105, 65, 100, 10, 3, None, u'[DlgTitleFont]&Typical', u'TypicalButton', None), -(u'SetupTypeDlg', u'CompleteButton', u'PushButton', 50, 171, 38, 38, 5767171, None, u'[CompleteSetupIcon]', u'Back', u'Complete Installation|'), -(u'SetupTypeDlg', u'CompleteLabel', u'Text', 105, 171, 100, 10, 3, None, u'[DlgTitleFont]C&omplete', u'CompleteButton', None), -(u'SetupTypeDlg', u'CompleteText', u'Text', 105, 184, 230, 20, 3, None, u'All program features will be installed. (Requires most disk space)', None, None), -(u'SetupTypeDlg', u'CustomButton', u'PushButton', 50, 118, 38, 38, 5767171, None, u'[CustomSetupIcon]', u'CompleteLabel', u'Custom Installation|'), -(u'SetupTypeDlg', u'CustomLabel', u'Text', 105, 118, 100, 10, 3, None, u'[DlgTitleFont]C&ustom', u'CustomButton', None), -(u'SetupTypeDlg', u'CustomText', u'Text', 105, 131, 230, 30, 3, None, u'Allows users to choose which program features will be installed and where they will be installed. Recommended for advanced users.', None, None), -(u'SetupTypeDlg', u'TypicalButton', u'PushButton', 50, 65, 38, 38, 5767171, None, u'[InstallerIcon]', u'CustomLabel', u'Typical Installation|'), -(u'SetupTypeDlg', u'TypicalText', u'Text', 105, 78, 230, 20, 3, None, u'Installs the most common program features. Recommended for most users.', None, None), -(u'UserRegistrationDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'NameLabel', None), -(u'UserRegistrationDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None), -(u'UserRegistrationDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'UserRegistrationDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'BannerBitmap', None), -(u'UserRegistrationDlg', u'Description', u'Text', 25, 23, 280, 15, 196611, None, u'Please enter your customer information', None, None), -(u'UserRegistrationDlg', u'Title', u'Text', 15, 6, 200, 15, 196611, None, u'[DlgTitleFont]Customer Information', None, None), -(u'UserRegistrationDlg', u'Back', u'PushButton', 180, 243, 56, 17, 3, None, u'[ButtonText_Back]', u'Next', None), -(u'UserRegistrationDlg', u'Next', u'PushButton', 236, 243, 56, 17, 3, None, u'[ButtonText_Next]', u'Cancel', None), -(u'UserRegistrationDlg', u'OrganizationLabel', u'Text', 45, 110, 100, 15, 3, None, u'&Organization:', u'OrganizationEdit', None), -(u'UserRegistrationDlg', u'CDKeyEdit', u'MaskedEdit', 45, 159, 250, 16, 3, u'PIDKEY', u'[PIDTemplate]', u'Back', None), -(u'UserRegistrationDlg', u'CDKeyLabel', u'Text', 45, 147, 50, 10, 3, None, u'CD &Key:', u'CDKeyEdit', None), -(u'UserRegistrationDlg', u'OrganizationEdit', u'Edit', 45, 122, 220, 18, 3, u'COMPANYNAME', u'{80}', u'CDKeyLabel', None), -(u'UserRegistrationDlg', u'NameLabel', u'Text', 45, 73, 100, 15, 3, None, u'&User Name:', u'NameEdit', None), -(u'UserRegistrationDlg', u'NameEdit', u'Edit', 45, 85, 220, 18, 3, u'USERNAME', u'{80}', u'OrganizationLabel', None), -(u'VerifyReadyDlg', u'Text', u'Text', 25, 70, 320, 20, 3, None, u'Click Install to begin the installation. If you want to review or change any of your installation settings, click Back. Click Cancel to exit the wizard.', None, None), -(u'VerifyReadyDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'Back', None), -(u'VerifyReadyDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None), -(u'VerifyReadyDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'VerifyReadyDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'BannerBitmap', None), -(u'VerifyReadyDlg', u'Description', u'Text', 25, 23, 280, 15, 196611, None, u'The [Wizard] is ready to begin the [InstallMode] installation', None, None), -(u'VerifyReadyDlg', u'Title', u'Text', 15, 6, 200, 15, 196611, None, u'[DlgTitleFont]Ready to Install', None, None), -(u'VerifyReadyDlg', u'Back', u'PushButton', 180, 243, 56, 17, 3, None, u'[ButtonText_Back]', u'Install', None), -(u'VerifyReadyDlg', u'Install', u'PushButton', 236, 243, 56, 17, 3, None, u'[ButtonText_Install]', u'Cancel', None), -(u'VerifyRemoveDlg', u'Text', u'Text', 25, 70, 320, 30, 3, None, u'Click Remove to remove [ProductName] from your computer. If you want to review or change any of your installation settings, click Back. Click Cancel to exit the wizard.', None, None), -(u'VerifyRemoveDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'Back', None), -(u'VerifyRemoveDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None), -(u'VerifyRemoveDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'VerifyRemoveDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'BannerBitmap', None), -(u'VerifyRemoveDlg', u'Description', u'Text', 25, 23, 280, 15, 196611, None, u'You have chosen to remove the program from your computer.', None, None), -(u'VerifyRemoveDlg', u'Title', u'Text', 15, 6, 200, 15, 196611, None, u'[DlgTitleFont]Remove [ProductName]', None, None), -(u'VerifyRemoveDlg', u'Back', u'PushButton', 180, 243, 56, 17, 3, None, u'[ButtonText_Back]', u'Remove', None), -(u'VerifyRemoveDlg', u'Remove', u'PushButton', 236, 243, 56, 17, 3, None, u'[ButtonText_Remove]', u'Cancel', None), -(u'VerifyRepairDlg', u'Text', u'Text', 25, 70, 320, 30, 3, None, u'Click Repair to repair the installation of [ProductName]. If you want to review or change any of your installation settings, click Back. Click Cancel to exit the wizard.', None, None), -(u'VerifyRepairDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'Back', None), -(u'VerifyRepairDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None), -(u'VerifyRepairDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'VerifyRepairDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'BannerBitmap', None), -(u'VerifyRepairDlg', u'Description', u'Text', 25, 23, 280, 15, 196611, None, u'The [Wizard] is ready to begin the repair of [ProductName].', None, None), -(u'VerifyRepairDlg', u'Title', u'Text', 15, 6, 200, 15, 196611, None, u'[DlgTitleFont]Repair [ProductName]', None, None), -(u'VerifyRepairDlg', u'Back', u'PushButton', 180, 243, 56, 17, 3, None, u'[ButtonText_Back]', u'Repair', None), -(u'VerifyRepairDlg', u'Repair', u'PushButton', 236, 243, 56, 17, 3, None, u'[ButtonText_Repair]', u'Cancel', None), -(u'WaitForCostingDlg', u'Text', u'Text', 48, 15, 194, 30, 3, None, u'Please wait while the installer finishes determining your disk space requirements.', None, None), -(u'WaitForCostingDlg', u'Icon', u'Icon', 15, 15, 24, 24, 5242881, None, u'[ExclamationIcon]', None, u'Exclamation icon|'), -(u'WaitForCostingDlg', u'Return', u'PushButton', 102, 57, 56, 17, 3, None, u'[ButtonText_Return]', None, None), -(u'WelcomeDlg', u'Bitmap', u'Bitmap', 0, 0, 370, 234, 1, None, u'[DialogBitmap]', u'Back', None), -(u'WelcomeDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'WelcomeDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'Bitmap', None), -(u'WelcomeDlg', u'Description', u'Text', 135, 70, 220, 30, 196611, None, u'The [Wizard] will install [ProductName] on your computer. Click Next to continue or Cancel to exit the [Wizard].', None, None), -(u'WelcomeDlg', u'Title', u'Text', 135, 20, 220, 60, 196611, None, u'{\\VerdanaBold13}Welcome to the [ProductName] [Wizard]', None, None), -(u'WelcomeDlg', u'Back', u'PushButton', 180, 243, 56, 17, 1, None, u'[ButtonText_Back]', u'Next', None), -(u'WelcomeDlg', u'Next', u'PushButton', 236, 243, 56, 17, 3, None, u'[ButtonText_Next]', u'Cancel', None), -] - -ListBox = [ -] - -ActionText = [ -(u'InstallValidate', u'Validating install', None), -(u'InstallFiles', u'Copying new files', u'File: [1], Directory: [9], Size: [6]'), -(u'InstallAdminPackage', u'Copying network install files', u'File: [1], Directory: [9], Size: [6]'), -(u'FileCost', u'Computing space requirements', None), -(u'CostInitialize', u'Computing space requirements', None), -(u'CostFinalize', u'Computing space requirements', None), -(u'CreateShortcuts', u'Creating shortcuts', u'Shortcut: [1]'), -(u'PublishComponents', u'Publishing Qualified Components', u'Component ID: [1], Qualifier: [2]'), -(u'PublishFeatures', u'Publishing Product Features', u'Feature: [1]'), -(u'PublishProduct', u'Publishing product information', None), -(u'RegisterClassInfo', u'Registering Class servers', u'Class Id: [1]'), -(u'RegisterExtensionInfo', u'Registering extension servers', u'Extension: [1]'), -(u'RegisterMIMEInfo', u'Registering MIME info', u'MIME Content Type: [1], Extension: [2]'), -(u'RegisterProgIdInfo', u'Registering program identifiers', u'ProgId: [1]'), -(u'AllocateRegistrySpace', u'Allocating registry space', u'Free space: [1]'), -(u'AppSearch', u'Searching for installed applications', u'Property: [1], Signature: [2]'), -(u'BindImage', u'Binding executables', u'File: [1]'), -(u'CCPSearch', u'Searching for qualifying products', None), -(u'CreateFolders', u'Creating folders', u'Folder: [1]'), -(u'DeleteServices', u'Deleting services', u'Service: [1]'), -(u'DuplicateFiles', u'Creating duplicate files', u'File: [1], Directory: [9], Size: [6]'), -(u'FindRelatedProducts', u'Searching for related applications', u'Found application: [1]'), -(u'InstallODBC', u'Installing ODBC components', None), -(u'InstallServices', u'Installing new services', u'Service: [2]'), -(u'LaunchConditions', u'Evaluating launch conditions', None), -(u'MigrateFeatureStates', u'Migrating feature states from related applications', u'Application: [1]'), -(u'MoveFiles', u'Moving files', u'File: [1], Directory: [9], Size: [6]'), -(u'PatchFiles', u'Patching files', u'File: [1], Directory: [2], Size: [3]'), -(u'ProcessComponents', u'Updating component registration', None), -(u'RegisterComPlus', u'Registering COM+ Applications and Components', u'AppId: [1]{{, AppType: [2], Users: [3], RSN: [4]}}'), -(u'RegisterFonts', u'Registering fonts', u'Font: [1]'), -(u'RegisterProduct', u'Registering product', u'[1]'), -(u'RegisterTypeLibraries', u'Registering type libraries', u'LibID: [1]'), -(u'RegisterUser', u'Registering user', u'[1]'), -(u'RemoveDuplicateFiles', u'Removing duplicated files', u'File: [1], Directory: [9]'), -(u'RemoveEnvironmentStrings', u'Updating environment strings', u'Name: [1], Value: [2], Action [3]'), -(u'RemoveExistingProducts', u'Removing applications', u'Application: [1], Command line: [2]'), -(u'RemoveFiles', u'Removing files', u'File: [1], Directory: [9]'), -(u'RemoveFolders', u'Removing folders', u'Folder: [1]'), -(u'RemoveIniValues', u'Removing INI files entries', u'File: [1], Section: [2], Key: [3], Value: [4]'), -(u'RemoveODBC', u'Removing ODBC components', None), -(u'RemoveRegistryValues', u'Removing system registry values', u'Key: [1], Name: [2]'), -(u'RemoveShortcuts', u'Removing shortcuts', u'Shortcut: [1]'), -(u'RMCCPSearch', u'Searching for qualifying products', None), -(u'SelfRegModules', u'Registering modules', u'File: [1], Folder: [2]'), -(u'SelfUnregModules', u'Unregistering modules', u'File: [1], Folder: [2]'), -(u'SetODBCFolders', u'Initializing ODBC directories', None), -(u'StartServices', u'Starting services', u'Service: [1]'), -(u'StopServices', u'Stopping services', u'Service: [1]'), -(u'UnpublishComponents', u'Unpublishing Qualified Components', u'Component ID: [1], Qualifier: [2]'), -(u'UnpublishFeatures', u'Unpublishing Product Features', u'Feature: [1]'), -(u'UnregisterClassInfo', u'Unregister Class servers', u'Class Id: [1]'), -(u'UnregisterComPlus', u'Unregistering COM+ Applications and Components', u'AppId: [1]{{, AppType: [2]}}'), -(u'UnregisterExtensionInfo', u'Unregistering extension servers', u'Extension: [1]'), -(u'UnregisterFonts', u'Unregistering fonts', u'Font: [1]'), -(u'UnregisterMIMEInfo', u'Unregistering MIME info', u'MIME Content Type: [1], Extension: [2]'), -(u'UnregisterProgIdInfo', u'Unregistering program identifiers', u'ProgId: [1]'), -(u'UnregisterTypeLibraries', u'Unregistering type libraries', u'LibID: [1]'), -(u'WriteEnvironmentStrings', u'Updating environment strings', u'Name: [1], Value: [2], Action [3]'), -(u'WriteIniValues', u'Writing INI files values', u'File: [1], Section: [2], Key: [3], Value: [4]'), -(u'WriteRegistryValues', u'Writing system registry values', u'Key: [1], Name: [2], Value: [3]'), -(u'Advertise', u'Advertising application', None), -(u'GenerateScript', u'Generating script operations for action:', u'[1]'), -(u'InstallSFPCatalogFile', u'Installing system catalog', u'File: [1], Dependencies: [2]'), -(u'MsiPublishAssemblies', u'Publishing assembly information', u'Application Context:[1], Assembly Name:[2]'), -(u'MsiUnpublishAssemblies', u'Unpublishing assembly information', u'Application Context:[1], Assembly Name:[2]'), -(u'Rollback', u'Rolling back action:', u'[1]'), -(u'RollbackCleanup', u'Removing backup files', u'File: [1]'), -(u'UnmoveFiles', u'Removing moved files', u'File: [1], Directory: [9]'), -(u'UnpublishProduct', u'Unpublishing product information', None), -] - -ControlCondition = [ -(u'CustomizeDlg', u'Browse', u'Hide', u'Installed'), -(u'CustomizeDlg', u'Location', u'Hide', u'Installed'), -(u'CustomizeDlg', u'LocationLabel', u'Hide', u'Installed'), -(u'LicenseAgreementDlg', u'Next', u'Disable', u'IAgree <> "Yes"'), -(u'LicenseAgreementDlg', u'Next', u'Enable', u'IAgree = "Yes"'), -] - -ControlEvent = [ -(u'AdminWelcomeDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None), -(u'AdminWelcomeDlg', u'Next', u'NewDialog', u'AdminRegistrationDlg', u'1', 2), -(u'AdminWelcomeDlg', u'Next', u'[InstallMode]', u'Server Image', u'1', 1), -(u'ExitDialog', u'Finish', u'EndDialog', u'Return', u'1', None), -(u'FatalError', u'Finish', u'EndDialog', u'Exit', u'1', None), -(u'PrepareDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None), -(u'ProgressDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None), -(u'UserExit', u'Finish', u'EndDialog', u'Exit', u'1', None), -(u'AdminBrowseDlg', u'Up', u'DirectoryListUp', u'0', u'1', None), -(u'AdminBrowseDlg', u'Cancel', u'Reset', u'0', u'1', 1), -(u'AdminBrowseDlg', u'Cancel', u'EndDialog', u'Return', u'1', 2), -(u'AdminBrowseDlg', u'NewFolder', u'DirectoryListNew', u'0', u'1', None), -(u'AdminBrowseDlg', u'OK', u'EndDialog', u'Return', u'1', 2), -(u'AdminBrowseDlg', u'OK', u'SetTargetPath', u'TARGETDIR', u'1', 1), -(u'AdminInstallPointDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None), -(u'AdminInstallPointDlg', u'Back', u'NewDialog', u'AdminRegistrationDlg', u'1', None), -(u'AdminInstallPointDlg', u'Next', u'SetTargetPath', u'TARGETDIR', u'1', 1), -(u'AdminInstallPointDlg', u'Next', u'NewDialog', u'VerifyReadyDlg', u'1', 2), -(u'AdminInstallPointDlg', u'Browse', u'SpawnDialog', u'AdminBrowseDlg', u'1', None), -(u'AdminRegistrationDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None), -(u'AdminRegistrationDlg', u'Back', u'NewDialog', u'AdminWelcomeDlg', u'1', None), -(u'AdminRegistrationDlg', u'Next', u'NewDialog', u'AdminInstallPointDlg', u'ProductID', 2), -(u'AdminRegistrationDlg', u'Next', u'ValidateProductID', u'0', u'0', 1), -(u'BrowseDlg', u'Up', u'DirectoryListUp', u'0', u'1', None), -(u'BrowseDlg', u'Cancel', u'Reset', u'0', u'1', 1), -(u'BrowseDlg', u'Cancel', u'EndDialog', u'Return', u'1', 2), -(u'BrowseDlg', u'NewFolder', u'DirectoryListNew', u'0', u'1', None), -(u'BrowseDlg', u'OK', u'EndDialog', u'Return', u'1', 2), -(u'BrowseDlg', u'OK', u'SetTargetPath', u'[_BrowseProperty]', u'1', 1), -(u'CancelDlg', u'No', u'EndDialog', u'Return', u'1', None), -(u'CancelDlg', u'Yes', u'EndDialog', u'Exit', u'1', None), -(u'CustomizeDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None), -(u'CustomizeDlg', u'Back', u'NewDialog', u'MaintenanceTypeDlg', u'InstallMode = "Change"', None), -(u'CustomizeDlg', u'Back', u'NewDialog', u'SetupTypeDlg', u'InstallMode = "Custom"', None), -(u'CustomizeDlg', u'Next', u'NewDialog', u'VerifyReadyDlg', u'1', None), -(u'CustomizeDlg', u'Browse', u'SelectionBrowse', u'BrowseDlg', u'1', None), -(u'CustomizeDlg', u'Reset', u'Reset', u'0', u'1', None), -(u'CustomizeDlg', u'DiskCost', u'SpawnDialog', u'DiskCostDlg', u'1', 2), -(u'DiskCostDlg', u'OK', u'EndDialog', u'Return', u'1', None), -(u'ErrorDlg', u'Y', u'EndDialog', u'ErrorYes', u'1', None), -(u'ErrorDlg', u'A', u'EndDialog', u'ErrorAbort', u'1', None), -(u'ErrorDlg', u'C', u'EndDialog', u'ErrorCancel', u'1', None), -(u'ErrorDlg', u'I', u'EndDialog', u'ErrorIgnore', u'1', None), -(u'ErrorDlg', u'N', u'EndDialog', u'ErrorNo', u'1', None), -(u'ErrorDlg', u'O', u'EndDialog', u'ErrorOk', u'1', None), -(u'ErrorDlg', u'R', u'EndDialog', u'ErrorRetry', u'1', None), -(u'FilesInUse', u'Retry', u'EndDialog', u'Retry', u'1', None), -(u'FilesInUse', u'Exit', u'EndDialog', u'Exit', u'1', None), -(u'FilesInUse', u'Ignore', u'EndDialog', u'Ignore', u'1', None), -(u'LicenseAgreementDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None), -(u'LicenseAgreementDlg', u'Back', u'NewDialog', u'WelcomeDlg', u'1', None), -(u'LicenseAgreementDlg', u'Next', u'NewDialog', u'SetupTypeDlg', u'IAgree = "Yes" AND ShowUserRegistrationDlg <> 1', 3), -(u'LicenseAgreementDlg', u'Next', u'NewDialog', u'UserRegistrationDlg', u'IAgree = "Yes" AND ShowUserRegistrationDlg = 1', 1), -(u'LicenseAgreementDlg', u'Next', u'SpawnWaitDialog', u'WaitForCostingDlg', u'CostingComplete = 1', 2), -(u'MaintenanceTypeDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None), -(u'MaintenanceTypeDlg', u'Back', u'NewDialog', u'MaintenanceWelcomeDlg', u'1', None), -(u'MaintenanceTypeDlg', u'ChangeButton', u'NewDialog', u'CustomizeDlg', u'1', 4), -(u'MaintenanceTypeDlg', u'ChangeButton', u'[InstallMode]', u'Change', u'1', 1), -(u'MaintenanceTypeDlg', u'ChangeButton', u'[Progress1]', u'Changing', u'1', 2), -(u'MaintenanceTypeDlg', u'ChangeButton', u'[Progress2]', u'changes', u'1', 3), -(u'MaintenanceTypeDlg', u'RemoveButton', u'NewDialog', u'VerifyRemoveDlg', u'1', 4), -(u'MaintenanceTypeDlg', u'RemoveButton', u'[InstallMode]', u'Remove', u'1', 1), -(u'MaintenanceTypeDlg', u'RemoveButton', u'[Progress1]', u'Removing', u'1', 2), -(u'MaintenanceTypeDlg', u'RemoveButton', u'[Progress2]', u'removes', u'1', 3), -(u'MaintenanceTypeDlg', u'RepairButton', u'NewDialog', u'VerifyRepairDlg', u'1', 4), -(u'MaintenanceTypeDlg', u'RepairButton', u'[InstallMode]', u'Repair', u'1', 1), -(u'MaintenanceTypeDlg', u'RepairButton', u'[Progress1]', u'Repairing', u'1', 2), -(u'MaintenanceTypeDlg', u'RepairButton', u'[Progress2]', u'repairs', u'1', 3), -(u'MaintenanceWelcomeDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None), -(u'MaintenanceWelcomeDlg', u'Next', u'NewDialog', u'MaintenanceTypeDlg', u'1', 2), -(u'MaintenanceWelcomeDlg', u'Next', u'SpawnWaitDialog', u'WaitForCostingDlg', u'CostingComplete = 1', 1), -(u'OutOfDiskDlg', u'OK', u'EndDialog', u'Return', u'1', None), -(u'OutOfRbDiskDlg', u'No', u'EndDialog', u'Return', u'1', None), -(u'OutOfRbDiskDlg', u'Yes', u'EndDialog', u'Return', u'1', 2), -(u'OutOfRbDiskDlg', u'Yes', u'EnableRollback', u'False', u'1', 1), -(u'ResumeDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None), -(u'ResumeDlg', u'Install', u'EndDialog', u'Return', u'OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"', 4), -(u'ResumeDlg', u'Install', u'EndDialog', u'Return', u'OutOfDiskSpace <> 1', 2), -(u'ResumeDlg', u'Install', u'SpawnDialog', u'OutOfDiskDlg', u'(OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 1) OR (OutOfDiskSpace = 1 AND PROMPTROLLBACKCOST="F")', 6), -(u'ResumeDlg', u'Install', u'SpawnDialog', u'OutOfRbDiskDlg', u'OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND (PROMPTROLLBACKCOST="P" OR NOT PROMPTROLLBACKCOST)', 3), -(u'ResumeDlg', u'Install', u'SpawnWaitDialog', u'WaitForCostingDlg', u'CostingComplete = 1', 1), -(u'ResumeDlg', u'Install', u'EnableRollback', u'False', u'OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"', 5), -(u'SetupTypeDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None), -(u'SetupTypeDlg', u'Back', u'NewDialog', u'LicenseAgreementDlg', u'ShowUserRegistrationDlg <> 1', None), -(u'SetupTypeDlg', u'Back', u'NewDialog', u'UserRegistrationDlg', u'ShowUserRegistrationDlg = 1', None), -(u'SetupTypeDlg', u'CompleteButton', u'NewDialog', u'VerifyReadyDlg', u'1', 3), -(u'SetupTypeDlg', u'CompleteButton', u'[InstallMode]', u'Complete', u'1', 1), -(u'SetupTypeDlg', u'CompleteButton', u'SetInstallLevel', u'1000', u'1', 2), -(u'SetupTypeDlg', u'CustomButton', u'NewDialog', u'CustomizeDlg', u'1', 2), -(u'SetupTypeDlg', u'CustomButton', u'[InstallMode]', u'Custom', u'1', 1), -(u'SetupTypeDlg', u'TypicalButton', u'NewDialog', u'VerifyReadyDlg', u'1', 3), -(u'SetupTypeDlg', u'TypicalButton', u'[InstallMode]', u'Typical', u'1', 1), -(u'SetupTypeDlg', u'TypicalButton', u'SetInstallLevel', u'3', u'1', 2), -(u'UserRegistrationDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None), -(u'UserRegistrationDlg', u'Back', u'NewDialog', u'LicenseAgreementDlg', u'1', None), -(u'UserRegistrationDlg', u'Next', u'NewDialog', u'SetupTypeDlg', u'ProductID', 3), -(u'UserRegistrationDlg', u'Next', u'ValidateProductID', u'0', u'0', 1), -(u'UserRegistrationDlg', u'Next', u'SpawnWaitDialog', u'WaitForCostingDlg', u'CostingComplete = 1', 2), -(u'VerifyReadyDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None), -(u'VerifyReadyDlg', u'Back', u'NewDialog', u'AdminInstallPointDlg', u'InstallMode = "Server Image"', None), -(u'VerifyReadyDlg', u'Back', u'NewDialog', u'CustomizeDlg', u'InstallMode = "Custom" OR InstallMode = "Change"', None), -(u'VerifyReadyDlg', u'Back', u'NewDialog', u'MaintenanceTypeDlg', u'InstallMode = "Repair"', None), -(u'VerifyReadyDlg', u'Back', u'NewDialog', u'SetupTypeDlg', u'InstallMode = "Typical" OR InstallMode = "Complete"', None), -(u'VerifyReadyDlg', u'Install', u'EndDialog', u'Return', u'OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"', 3), -(u'VerifyReadyDlg', u'Install', u'EndDialog', u'Return', u'OutOfDiskSpace <> 1', 1), -(u'VerifyReadyDlg', u'Install', u'SpawnDialog', u'OutOfDiskDlg', u'(OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 1) OR (OutOfDiskSpace = 1 AND PROMPTROLLBACKCOST="F")', 5), -(u'VerifyReadyDlg', u'Install', u'SpawnDialog', u'OutOfRbDiskDlg', u'OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND (PROMPTROLLBACKCOST="P" OR NOT PROMPTROLLBACKCOST)', 2), -(u'VerifyReadyDlg', u'Install', u'EnableRollback', u'False', u'OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"', 4), -(u'VerifyRemoveDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None), -(u'VerifyRemoveDlg', u'Back', u'NewDialog', u'MaintenanceTypeDlg', u'1', None), -(u'VerifyRemoveDlg', u'Remove', u'Remove', u'All', u'OutOfDiskSpace <> 1', 1), -(u'VerifyRemoveDlg', u'Remove', u'EndDialog', u'Return', u'OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"', 4), -(u'VerifyRemoveDlg', u'Remove', u'EndDialog', u'Return', u'OutOfDiskSpace <> 1', 2), -(u'VerifyRemoveDlg', u'Remove', u'SpawnDialog', u'OutOfDiskDlg', u'(OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 1) OR (OutOfDiskSpace = 1 AND PROMPTROLLBACKCOST="F")', 6), -(u'VerifyRemoveDlg', u'Remove', u'SpawnDialog', u'OutOfRbDiskDlg', u'OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND (PROMPTROLLBACKCOST="P" OR NOT PROMPTROLLBACKCOST)', 3), -(u'VerifyRemoveDlg', u'Remove', u'EnableRollback', u'False', u'OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"', 5), -(u'VerifyRepairDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None), -(u'VerifyRepairDlg', u'Back', u'NewDialog', u'MaintenanceTypeDlg', u'1', None), -(u'VerifyRepairDlg', u'Repair', u'EndDialog', u'Return', u'OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"', 5), -(u'VerifyRepairDlg', u'Repair', u'EndDialog', u'Return', u'OutOfDiskSpace <> 1', 3), -(u'VerifyRepairDlg', u'Repair', u'SpawnDialog', u'OutOfDiskDlg', u'(OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 1) OR (OutOfDiskSpace = 1 AND PROMPTROLLBACKCOST="F")', 7), -(u'VerifyRepairDlg', u'Repair', u'SpawnDialog', u'OutOfRbDiskDlg', u'OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND (PROMPTROLLBACKCOST="P" OR NOT PROMPTROLLBACKCOST)', 4), -(u'VerifyRepairDlg', u'Repair', u'EnableRollback', u'False', u'OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"', 6), -(u'VerifyRepairDlg', u'Repair', u'Reinstall', u'All', u'OutOfDiskSpace <> 1', 2), -(u'VerifyRepairDlg', u'Repair', u'ReinstallMode', u'ecmus', u'OutOfDiskSpace <> 1', 1), -(u'WaitForCostingDlg', u'Return', u'EndDialog', u'Exit', u'1', None), -(u'WelcomeDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None), -(u'WelcomeDlg', u'Next', u'NewDialog', u'LicenseAgreementDlg', u'1', None), -] - -Dialog = [ -(u'AdminWelcomeDlg', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'Next', u'Next', u'Cancel'), -(u'ExitDialog', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'Finish', u'Finish', u'Finish'), -(u'FatalError', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'Finish', u'Finish', u'Finish'), -(u'PrepareDlg', 50, 50, 370, 270, 1, u'[ProductName] [Setup]', u'Cancel', u'Cancel', u'Cancel'), -(u'ProgressDlg', 50, 50, 370, 270, 1, u'[ProductName] [Setup]', u'Cancel', u'Cancel', u'Cancel'), -(u'UserExit', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'Finish', u'Finish', u'Finish'), -(u'AdminBrowseDlg', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'PathEdit', u'OK', u'Cancel'), -(u'AdminInstallPointDlg', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'Text', u'Next', u'Cancel'), -(u'AdminRegistrationDlg', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'OrganizationLabel', u'Next', u'Cancel'), -(u'BrowseDlg', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'PathEdit', u'OK', u'Cancel'), -(u'CancelDlg', 50, 10, 260, 85, 3, u'[ProductName] [Setup]', u'No', u'No', u'No'), -(u'CustomizeDlg', 50, 50, 370, 270, 35, u'[ProductName] [Setup]', u'Tree', u'Next', u'Cancel'), -(u'DiskCostDlg', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'OK', u'OK', u'OK'), -(u'ErrorDlg', 50, 10, 270, 105, 65539, u'Installer Information', u'ErrorText', None, None), -(u'FilesInUse', 50, 50, 370, 270, 19, u'[ProductName] [Setup]', u'Retry', u'Retry', u'Retry'), -(u'LicenseAgreementDlg', 50, 50, 370, 270, 3, u'[ProductName] License Agreement', u'Buttons', u'Next', u'Cancel'), -(u'MaintenanceTypeDlg', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'ChangeLabel', u'ChangeButton', u'Cancel'), -(u'MaintenanceWelcomeDlg', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'Next', u'Next', u'Cancel'), -(u'OutOfDiskDlg', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'OK', u'OK', u'OK'), -(u'OutOfRbDiskDlg', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'No', u'No', u'No'), -(u'ResumeDlg', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'Install', u'Install', u'Cancel'), -(u'SetupTypeDlg', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'TypicalLabel', u'TypicalButton', u'Cancel'), -(u'UserRegistrationDlg', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'NameLabel', u'Next', u'Cancel'), -(u'VerifyReadyDlg', 50, 50, 370, 270, 35, u'[ProductName] [Setup]', u'Install', u'Install', u'Cancel'), -(u'VerifyRemoveDlg', 50, 50, 370, 270, 35, u'[ProductName] [Setup]', u'Back', u'Back', u'Cancel'), -(u'VerifyRepairDlg', 50, 50, 370, 270, 35, u'[ProductName] [Setup]', u'Repair', u'Repair', u'Cancel'), -(u'WaitForCostingDlg', 50, 10, 260, 85, 3, u'[ProductName] [Setup]', u'Return', u'Return', u'Return'), -(u'WelcomeDlg', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'Next', u'Next', u'Cancel'), -] - -EventMapping = [ -(u'PrepareDlg', u'ActionData', u'ActionData', u'Text'), -(u'PrepareDlg', u'ActionText', u'ActionText', u'Text'), -(u'ProgressDlg', u'ActionText', u'ActionText', u'Text'), -(u'ProgressDlg', u'ProgressBar', u'SetProgress', u'Progress'), -(u'AdminBrowseDlg', u'DirectoryCombo', u'IgnoreChange', u'IgnoreChange'), -(u'BrowseDlg', u'DirectoryCombo', u'IgnoreChange', u'IgnoreChange'), -(u'CustomizeDlg', u'Next', u'SelectionNoItems', u'Enabled'), -(u'CustomizeDlg', u'Reset', u'SelectionNoItems', u'Enabled'), -(u'CustomizeDlg', u'DiskCost', u'SelectionNoItems', u'Enabled'), -(u'CustomizeDlg', u'ItemDescription', u'SelectionDescription', u'Text'), -(u'CustomizeDlg', u'ItemSize', u'SelectionSize', u'Text'), -(u'CustomizeDlg', u'Location', u'SelectionPath', u'Text'), -(u'CustomizeDlg', u'Location', u'SelectionPathOn', u'Visible'), -(u'CustomizeDlg', u'LocationLabel', u'SelectionPathOn', u'Visible'), -] - -InstallExecuteSequence = [ -(u'InstallValidate', None, 1400), -(u'InstallInitialize', None, 1500), -(u'InstallFinalize', None, 6600), -(u'InstallFiles', None, 4000), -(u'FileCost', None, 900), -(u'CostInitialize', None, 800), -(u'CostFinalize', None, 1000), -(u'CreateShortcuts', None, 4500), -(u'PublishComponents', None, 6200), -(u'PublishFeatures', None, 6300), -(u'PublishProduct', None, 6400), -(u'RegisterClassInfo', None, 4600), -(u'RegisterExtensionInfo', None, 4700), -(u'RegisterMIMEInfo', None, 4900), -(u'RegisterProgIdInfo', None, 4800), -(u'ValidateProductID', None, 700), -(u'AllocateRegistrySpace', u'NOT Installed', 1550), -(u'AppSearch', None, 400), -(u'BindImage', None, 4300), -(u'CCPSearch', u'NOT Installed', 500), -(u'CreateFolders', None, 3700), -(u'DeleteServices', u'VersionNT', 2000), -(u'DuplicateFiles', None, 4210), -(u'FindRelatedProducts', None, 200), -(u'InstallODBC', None, 5400), -(u'InstallServices', u'VersionNT', 5800), -(u'LaunchConditions', None, 100), -(u'MigrateFeatureStates', None, 1200), -(u'MoveFiles', None, 3800), -(u'PatchFiles', None, 4090), -(u'ProcessComponents', None, 1600), -(u'RegisterComPlus', None, 5700), -(u'RegisterFonts', None, 5300), -(u'RegisterProduct', None, 6100), -(u'RegisterTypeLibraries', None, 5500), -(u'RegisterUser', None, 6000), -(u'RemoveDuplicateFiles', None, 3400), -(u'RemoveEnvironmentStrings', None, 3300), -(u'RemoveExistingProducts', None, 6700), -(u'RemoveFiles', None, 3500), -(u'RemoveFolders', None, 3600), -(u'RemoveIniValues', None, 3100), -(u'RemoveODBC', None, 2400), -(u'RemoveRegistryValues', None, 2600), -(u'RemoveShortcuts', None, 3200), -(u'RMCCPSearch', u'NOT Installed', 600), -(u'SelfRegModules', None, 5600), -(u'SelfUnregModules', None, 2200), -(u'SetODBCFolders', None, 1100), -(u'StartServices', u'VersionNT', 5900), -(u'StopServices', u'VersionNT', 1900), -(u'UnpublishComponents', None, 1700), -(u'UnpublishFeatures', None, 1800), -(u'UnregisterClassInfo', None, 2700), -(u'UnregisterComPlus', None, 2100), -(u'UnregisterExtensionInfo', None, 2800), -(u'UnregisterFonts', None, 2500), -(u'UnregisterMIMEInfo', None, 3000), -(u'UnregisterProgIdInfo', None, 2900), -(u'UnregisterTypeLibraries', None, 2300), -(u'WriteEnvironmentStrings', None, 5200), -(u'WriteIniValues', None, 5100), -(u'WriteRegistryValues', None, 5000), -] - -InstallUISequence = [ -#(u'FileCost', None, 900), -#(u'CostInitialize', None, 800), -#(u'CostFinalize', None, 1000), -#(u'ExecuteAction', None, 1300), -#(u'ExitDialog', None, -1), -#(u'FatalError', None, -3), -(u'PrepareDlg', None, 140), -(u'ProgressDlg', None, 1280), -#(u'UserExit', None, -2), -(u'MaintenanceWelcomeDlg', u'Installed AND NOT RESUME AND NOT Preselected', 1250), -(u'ResumeDlg', u'Installed AND (RESUME OR Preselected)', 1240), -(u'WelcomeDlg', u'NOT Installed', 1230), -#(u'AppSearch', None, 400), -#(u'CCPSearch', u'NOT Installed', 500), -#(u'FindRelatedProducts', None, 200), -#(u'LaunchConditions', None, 100), -#(u'MigrateFeatureStates', None, 1200), -#(u'RMCCPSearch', u'NOT Installed', 600), -] - -ListView = [ -] - -RadioButton = [ -(u'IAgree', 1, u'Yes', 5, 0, 250, 15, u'{\\DlgFont8}I &accept the terms in the License Agreement', None), -(u'IAgree', 2, u'No', 5, 20, 250, 15, u'{\\DlgFont8}I &do not accept the terms in the License Agreement', None), -] - -TextStyle = [ -(u'DlgFont8', u'Tahoma', 8, None, 0), -(u'DlgFontBold8', u'Tahoma', 8, None, 1), -(u'VerdanaBold13', u'Verdana', 13, None, 1), -] - -UIText = [ -(u'AbsentPath', None), -(u'bytes', u'bytes'), -(u'GB', u'GB'), -(u'KB', u'KB'), -(u'MB', u'MB'), -(u'MenuAbsent', u'Entire feature will be unavailable'), -(u'MenuAdvertise', u'Feature will be installed when required'), -(u'MenuAllCD', u'Entire feature will be installed to run from CD'), -(u'MenuAllLocal', u'Entire feature will be installed on local hard drive'), -(u'MenuAllNetwork', u'Entire feature will be installed to run from network'), -(u'MenuCD', u'Will be installed to run from CD'), -(u'MenuLocal', u'Will be installed on local hard drive'), -(u'MenuNetwork', u'Will be installed to run from network'), -(u'ScriptInProgress', u'Gathering required information...'), -(u'SelAbsentAbsent', u'This feature will remain uninstalled'), -(u'SelAbsentAdvertise', u'This feature will be set to be installed when required'), -(u'SelAbsentCD', u'This feature will be installed to run from CD'), -(u'SelAbsentLocal', u'This feature will be installed on the local hard drive'), -(u'SelAbsentNetwork', u'This feature will be installed to run from the network'), -(u'SelAdvertiseAbsent', u'This feature will become unavailable'), -(u'SelAdvertiseAdvertise', u'Will be installed when required'), -(u'SelAdvertiseCD', u'This feature will be available to run from CD'), -(u'SelAdvertiseLocal', u'This feature will be installed on your local hard drive'), -(u'SelAdvertiseNetwork', u'This feature will be available to run from the network'), -(u'SelCDAbsent', u"This feature will be uninstalled completely, you won't be able to run it from CD"), -(u'SelCDAdvertise', u'This feature will change from run from CD state to set to be installed when required'), -(u'SelCDCD', u'This feature will remain to be run from CD'), -(u'SelCDLocal', u'This feature will change from run from CD state to be installed on the local hard drive'), -(u'SelChildCostNeg', u'This feature frees up [1] on your hard drive.'), -(u'SelChildCostPos', u'This feature requires [1] on your hard drive.'), -(u'SelCostPending', u'Compiling cost for this feature...'), -(u'SelLocalAbsent', u'This feature will be completely removed'), -(u'SelLocalAdvertise', u'This feature will be removed from your local hard drive, but will be set to be installed when required'), -(u'SelLocalCD', u'This feature will be removed from your local hard drive, but will be still available to run from CD'), -(u'SelLocalLocal', u'This feature will remain on you local hard drive'), -(u'SelLocalNetwork', u'This feature will be removed from your local hard drive, but will be still available to run from the network'), -(u'SelNetworkAbsent', u"This feature will be uninstalled completely, you won't be able to run it from the network"), -(u'SelNetworkAdvertise', u'This feature will change from run from network state to set to be installed when required'), -(u'SelNetworkLocal', u'This feature will change from run from network state to be installed on the local hard drive'), -(u'SelNetworkNetwork', u'This feature will remain to be run from the network'), -(u'SelParentCostNegNeg', u'This feature frees up [1] on your hard drive. It has [2] of [3] subfeatures selected. The subfeatures free up [4] on your hard drive.'), -(u'SelParentCostNegPos', u'This feature frees up [1] on your hard drive. It has [2] of [3] subfeatures selected. The subfeatures require [4] on your hard drive.'), -(u'SelParentCostPosNeg', u'This feature requires [1] on your hard drive. It has [2] of [3] subfeatures selected. The subfeatures free up [4] on your hard drive.'), -(u'SelParentCostPosPos', u'This feature requires [1] on your hard drive. It has [2] of [3] subfeatures selected. The subfeatures require [4] on your hard drive.'), -(u'TimeRemaining', u'Time remaining: {[1] minutes }{[2] seconds}'), -(u'VolumeCostAvailable', u'Available'), -(u'VolumeCostDifference', u'Difference'), -(u'VolumeCostRequired', u'Required'), -(u'VolumeCostSize', u'Disk Size'), -(u'VolumeCostVolume', u'Volume'), -] - -_Validation = [ -(u'AdminExecuteSequence', u'Action', u'N', None, None, None, None, u'Identifier', None, u'Name of action to invoke, either in the engine or the handler DLL.'), -(u'AdminExecuteSequence', u'Sequence', u'Y', -4, 32767, None, None, None, None, u'Number that determines the sort order in which the actions are to be executed. Leave blank to suppress action.'), -(u'AdminExecuteSequence', u'Condition', u'Y', None, None, None, None, u'Condition', None, u'Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.'), -(u'AdminUISequence', u'Action', u'N', None, None, None, None, u'Identifier', None, u'Name of action to invoke, either in the engine or the handler DLL.'), -(u'AdminUISequence', u'Sequence', u'Y', -4, 32767, None, None, None, None, u'Number that determines the sort order in which the actions are to be executed. Leave blank to suppress action.'), -(u'AdminUISequence', u'Condition', u'Y', None, None, None, None, u'Condition', None, u'Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.'), -(u'Condition', u'Condition', u'Y', None, None, None, None, u'Condition', None, u'Expression evaluated to determine if Level in the Feature table is to change.'), -(u'Condition', u'Feature_', u'N', None, None, u'Feature', 1, u'Identifier', None, u'Reference to a Feature entry in Feature table.'), -(u'Condition', u'Level', u'N', 0, 32767, None, None, None, None, u'New selection Level to set in Feature table if Condition evaluates to TRUE.'), -(u'AdvtExecuteSequence', u'Action', u'N', None, None, None, None, u'Identifier', None, u'Name of action to invoke, either in the engine or the handler DLL.'), -(u'AdvtExecuteSequence', u'Sequence', u'Y', -4, 32767, None, None, None, None, u'Number that determines the sort order in which the actions are to be executed. Leave blank to suppress action.'), -(u'AdvtExecuteSequence', u'Condition', u'Y', None, None, None, None, u'Condition', None, u'Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.'), -(u'BBControl', u'Type', u'N', None, None, None, None, u'Identifier', None, u'The type of the control.'), -(u'BBControl', u'BBControl', u'N', None, None, None, None, u'Identifier', None, u'Name of the control. This name must be unique within a billboard, but can repeat on different billboard.'), -(u'BBControl', u'Billboard_', u'N', None, None, u'Billboard', 1, u'Identifier', None, u'External key to the Billboard table, name of the billboard.'), -(u'BBControl', u'X', u'N', 0, 32767, None, None, None, None, u'Horizontal coordinate of the upper left corner of the bounding rectangle of the control.'), -(u'BBControl', u'Y', u'N', 0, 32767, None, None, None, None, u'Vertical coordinate of the upper left corner of the bounding rectangle of the control.'), -(u'BBControl', u'Width', u'N', 0, 32767, None, None, None, None, u'Width of the bounding rectangle of the control.'), -(u'BBControl', u'Height', u'N', 0, 32767, None, None, None, None, u'Height of the bounding rectangle of the control.'), -(u'BBControl', u'Attributes', u'Y', 0, 2147483647, None, None, None, None, u'A 32-bit word that specifies the attribute flags to be applied to this control.'), -(u'BBControl', u'Text', u'Y', None, None, None, None, u'Text', None, u'A string used to set the initial text contained within a control (if appropriate).'), -(u'Billboard', u'Action', u'Y', None, None, None, None, u'Identifier', None, u'The name of an action. The billboard is displayed during the progress messages received from this action.'), -(u'Billboard', u'Billboard', u'N', None, None, None, None, u'Identifier', None, u'Name of the billboard.'), -(u'Billboard', u'Feature_', u'N', None, None, u'Feature', 1, u'Identifier', None, u'An external key to the Feature Table. The billboard is shown only if this feature is being installed.'), -(u'Billboard', u'Ordering', u'Y', 0, 32767, None, None, None, None, u'A positive integer. If there is more than one billboard corresponding to an action they will be shown in the order defined by this column.'), -(u'Binary', u'Name', u'N', None, None, None, None, u'Identifier', None, u'Unique key identifying the binary data.'), -(u'Binary', u'Data', u'N', None, None, None, None, u'Binary', None, u'The unformatted binary data.'), -(u'CheckBox', u'Property', u'N', None, None, None, None, u'Identifier', None, u'A named property to be tied to the item.'), -(u'CheckBox', u'Value', u'Y', None, None, None, None, u'Formatted', None, u'The value string associated with the item.'), -(u'Property', u'Property', u'N', None, None, None, None, u'Identifier', None, u'Name of property, uppercase if settable by launcher or loader.'), -(u'Property', u'Value', u'N', None, None, None, None, u'Text', None, u'String value for property. Never null or empty.'), -(u'ComboBox', u'Text', u'Y', None, None, None, None, u'Formatted', None, u'The visible text to be assigned to the item. Optional. If this entry or the entire column is missing, the text is the same as the value.'), -(u'ComboBox', u'Property', u'N', None, None, None, None, u'Identifier', None, u'A named property to be tied to this item. All the items tied to the same property become part of the same combobox.'), -(u'ComboBox', u'Value', u'N', None, None, None, None, u'Formatted', None, u'The value string associated with this item. Selecting the line will set the associated property to this value.'), -(u'ComboBox', u'Order', u'N', 1, 32767, None, None, None, None, u'A positive integer used to determine the ordering of the items within one list.\tThe integers do not have to be consecutive.'), -(u'Control', u'Type', u'N', None, None, None, None, u'Identifier', None, u'The type of the control.'), -(u'Control', u'X', u'N', 0, 32767, None, None, None, None, u'Horizontal coordinate of the upper left corner of the bounding rectangle of the control.'), -(u'Control', u'Y', u'N', 0, 32767, None, None, None, None, u'Vertical coordinate of the upper left corner of the bounding rectangle of the control.'), -(u'Control', u'Width', u'N', 0, 32767, None, None, None, None, u'Width of the bounding rectangle of the control.'), -(u'Control', u'Height', u'N', 0, 32767, None, None, None, None, u'Height of the bounding rectangle of the control.'), -(u'Control', u'Attributes', u'Y', 0, 2147483647, None, None, None, None, u'A 32-bit word that specifies the attribute flags to be applied to this control.'), -(u'Control', u'Text', u'Y', None, None, None, None, u'Formatted', None, u'A string used to set the initial text contained within a control (if appropriate).'), -(u'Control', u'Property', u'Y', None, None, None, None, u'Identifier', None, u'The name of a defined property to be linked to this control. '), -(u'Control', u'Control', u'N', None, None, None, None, u'Identifier', None, u'Name of the control. This name must be unique within a dialog, but can repeat on different dialogs. '), -(u'Control', u'Dialog_', u'N', None, None, u'Dialog', 1, u'Identifier', None, u'External key to the Dialog table, name of the dialog.'), -(u'Control', u'Control_Next', u'Y', None, None, u'Control', 2, u'Identifier', None, u'The name of an other control on the same dialog. This link defines the tab order of the controls. The links have to form one or more cycles!'), -(u'Control', u'Help', u'Y', None, None, None, None, u'Text', None, u'The help strings used with the button. The text is optional. '), -(u'Icon', u'Name', u'N', None, None, None, None, u'Identifier', None, u'Primary key. Name of the icon file.'), -(u'Icon', u'Data', u'N', None, None, None, None, u'Binary', None, u'Binary stream. The binary icon data in PE (.DLL or .EXE) or icon (.ICO) format.'), -(u'ListBox', u'Text', u'Y', None, None, None, None, u'Text', None, u'The visible text to be assigned to the item. Optional. If this entry or the entire column is missing, the text is the same as the value.'), -(u'ListBox', u'Property', u'N', None, None, None, None, u'Identifier', None, u'A named property to be tied to this item. All the items tied to the same property become part of the same listbox.'), -(u'ListBox', u'Value', u'N', None, None, None, None, u'Formatted', None, u'The value string associated with this item. Selecting the line will set the associated property to this value.'), -(u'ListBox', u'Order', u'N', 1, 32767, None, None, None, None, u'A positive integer used to determine the ordering of the items within one list..The integers do not have to be consecutive.'), -(u'ActionText', u'Action', u'N', None, None, None, None, u'Identifier', None, u'Name of action to be described.'), -(u'ActionText', u'Description', u'Y', None, None, None, None, u'Text', None, u'Localized description displayed in progress dialog and log when action is executing.'), -(u'ActionText', u'Template', u'Y', None, None, None, None, u'Template', None, u'Optional localized format template used to format action data records for display during action execution.'), -(u'ControlCondition', u'Action', u'N', None, None, None, None, None, u'Default;Disable;Enable;Hide;Show', u'The desired action to be taken on the specified control.'), -(u'ControlCondition', u'Condition', u'N', None, None, None, None, u'Condition', None, u'A standard conditional statement that specifies under which conditions the action should be triggered.'), -(u'ControlCondition', u'Dialog_', u'N', None, None, u'Dialog', 1, u'Identifier', None, u'A foreign key to the Dialog table, name of the dialog.'), -(u'ControlCondition', u'Control_', u'N', None, None, u'Control', 2, u'Identifier', None, u'A foreign key to the Control table, name of the control.'), -(u'ControlEvent', u'Condition', u'Y', None, None, None, None, u'Condition', None, u'A standard conditional statement that specifies under which conditions an event should be triggered.'), -(u'ControlEvent', u'Ordering', u'Y', 0, 2147483647, None, None, None, None, u'An integer used to order several events tied to the same control. Can be left blank.'), -(u'ControlEvent', u'Dialog_', u'N', None, None, u'Dialog', 1, u'Identifier', None, u'A foreign key to the Dialog table, name of the dialog.'), -(u'ControlEvent', u'Control_', u'N', None, None, u'Control', 2, u'Identifier', None, u'A foreign key to the Control table, name of the control'), -(u'ControlEvent', u'Event', u'N', None, None, None, None, u'Formatted', None, u'An identifier that specifies the type of the event that should take place when the user interacts with control specified by the first two entries.'), -(u'ControlEvent', u'Argument', u'N', None, None, None, None, u'Formatted', None, u'A value to be used as a modifier when triggering a particular event.'), -(u'Dialog', u'Width', u'N', 0, 32767, None, None, None, None, u'Width of the bounding rectangle of the dialog.'), -(u'Dialog', u'Height', u'N', 0, 32767, None, None, None, None, u'Height of the bounding rectangle of the dialog.'), -(u'Dialog', u'Attributes', u'Y', 0, 2147483647, None, None, None, None, u'A 32-bit word that specifies the attribute flags to be applied to this dialog.'), -(u'Dialog', u'Title', u'Y', None, None, None, None, u'Formatted', None, u"A text string specifying the title to be displayed in the title bar of the dialog's window."), -(u'Dialog', u'Dialog', u'N', None, None, None, None, u'Identifier', None, u'Name of the dialog.'), -(u'Dialog', u'HCentering', u'N', 0, 100, None, None, None, None, u'Horizontal position of the dialog on a 0-100 scale. 0 means left end, 100 means right end of the screen, 50 center.'), -(u'Dialog', u'VCentering', u'N', 0, 100, None, None, None, None, u'Vertical position of the dialog on a 0-100 scale. 0 means top end, 100 means bottom end of the screen, 50 center.'), -(u'Dialog', u'Control_First', u'N', None, None, u'Control', 2, u'Identifier', None, u'Defines the control that has the focus when the dialog is created.'), -(u'Dialog', u'Control_Default', u'Y', None, None, u'Control', 2, u'Identifier', None, u'Defines the default control. Hitting return is equivalent to pushing this button.'), -(u'Dialog', u'Control_Cancel', u'Y', None, None, u'Control', 2, u'Identifier', None, u'Defines the cancel control. Hitting escape or clicking on the close icon on the dialog is equivalent to pushing this button.'), -(u'EventMapping', u'Dialog_', u'N', None, None, u'Dialog', 1, u'Identifier', None, u'A foreign key to the Dialog table, name of the Dialog.'), -(u'EventMapping', u'Control_', u'N', None, None, u'Control', 2, u'Identifier', None, u'A foreign key to the Control table, name of the control.'), -(u'EventMapping', u'Event', u'N', None, None, None, None, u'Identifier', None, u'An identifier that specifies the type of the event that the control subscribes to.'), -(u'EventMapping', u'Attribute', u'N', None, None, None, None, u'Identifier', None, u'The name of the control attribute, that is set when this event is received.'), -(u'InstallExecuteSequence', u'Action', u'N', None, None, None, None, u'Identifier', None, u'Name of action to invoke, either in the engine or the handler DLL.'), -(u'InstallExecuteSequence', u'Sequence', u'Y', -4, 32767, None, None, None, None, u'Number that determines the sort order in which the actions are to be executed. Leave blank to suppress action.'), -(u'InstallExecuteSequence', u'Condition', u'Y', None, None, None, None, u'Condition', None, u'Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.'), -(u'AppSearch', u'Property', u'N', None, None, None, None, u'Identifier', None, u'The property associated with a Signature'), -(u'AppSearch', u'Signature_', u'N', None, None, u'Signature;RegLocator;IniLocator;DrLocator;CompLocator', 1, u'Identifier', None, u'The Signature_ represents a unique file signature and is also the foreign key in the Signature, RegLocator, IniLocator, CompLocator and the DrLocator tables.'), -(u'BindImage', u'File_', u'N', None, None, u'File', 1, u'Identifier', None, u'The index into the File table. This must be an executable file.'), -(u'BindImage', u'Path', u'Y', None, None, None, None, u'Paths', None, u'A list of ; delimited paths that represent the paths to be searched for the import DLLS. The list is usually a list of properties each enclosed within square brackets [] .'), -(u'CCPSearch', u'Signature_', u'N', None, None, u'Signature;RegLocator;IniLocator;DrLocator;CompLocator', 1, u'Identifier', None, u'The Signature_ represents a unique file signature and is also the foreign key in the Signature, RegLocator, IniLocator, CompLocator and the DrLocator tables.'), -(u'InstallUISequence', u'Action', u'N', None, None, None, None, u'Identifier', None, u'Name of action to invoke, either in the engine or the handler DLL.'), -(u'InstallUISequence', u'Sequence', u'Y', -4, 32767, None, None, None, None, u'Number that determines the sort order in which the actions are to be executed. Leave blank to suppress action.'), -(u'InstallUISequence', u'Condition', u'Y', None, None, None, None, u'Condition', None, u'Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.'), -(u'ListView', u'Text', u'Y', None, None, None, None, u'Text', None, u'The visible text to be assigned to the item. Optional. If this entry or the entire column is missing, the text is the same as the value.'), -(u'ListView', u'Property', u'N', None, None, None, None, u'Identifier', None, u'A named property to be tied to this item. All the items tied to the same property become part of the same listview.'), -(u'ListView', u'Value', u'N', None, None, None, None, u'Identifier', None, u'The value string associated with this item. Selecting the line will set the associated property to this value.'), -(u'ListView', u'Order', u'N', 1, 32767, None, None, None, None, u'A positive integer used to determine the ordering of the items within one list..The integers do not have to be consecutive.'), -(u'ListView', u'Binary_', u'Y', None, None, u'Binary', 1, u'Identifier', None, u'The name of the icon to be displayed with the icon. The binary information is looked up from the Binary Table.'), -(u'RadioButton', u'X', u'N', 0, 32767, None, None, None, None, u'The horizontal coordinate of the upper left corner of the bounding rectangle of the radio button.'), -(u'RadioButton', u'Y', u'N', 0, 32767, None, None, None, None, u'The vertical coordinate of the upper left corner of the bounding rectangle of the radio button.'), -(u'RadioButton', u'Width', u'N', 0, 32767, None, None, None, None, u'The width of the button.'), -(u'RadioButton', u'Height', u'N', 0, 32767, None, None, None, None, u'The height of the button.'), -(u'RadioButton', u'Text', u'Y', None, None, None, None, u'Text', None, u'The visible title to be assigned to the radio button.'), -(u'RadioButton', u'Property', u'N', None, None, None, None, u'Identifier', None, u'A named property to be tied to this radio button. All the buttons tied to the same property become part of the same group.'), -(u'RadioButton', u'Value', u'N', None, None, None, None, u'Formatted', None, u'The value string associated with this button. Selecting the button will set the associated property to this value.'), -(u'RadioButton', u'Order', u'N', 1, 32767, None, None, None, None, u'A positive integer used to determine the ordering of the items within one list..The integers do not have to be consecutive.'), -(u'RadioButton', u'Help', u'Y', None, None, None, None, u'Text', None, u'The help strings used with the button. The text is optional.'), -(u'TextStyle', u'TextStyle', u'N', None, None, None, None, u'Identifier', None, u'Name of the style. The primary key of this table. This name is embedded in the texts to indicate a style change.'), -(u'TextStyle', u'FaceName', u'N', None, None, None, None, u'Text', None, u'A string indicating the name of the font used. Required. The string must be at most 31 characters long.'), -(u'TextStyle', u'Size', u'N', 0, 32767, None, None, None, None, u'The size of the font used. This size is given in our units (1/12 of the system font height). Assuming that the system font is set to 12 point size, this is equivalent to the point size.'), -(u'TextStyle', u'Color', u'Y', 0, 16777215, None, None, None, None, u'A long integer indicating the color of the string in the RGB format (Red, Green, Blue each 0-255, RGB = R + 256*G + 256^2*B).'), -(u'TextStyle', u'StyleBits', u'Y', 0, 15, None, None, None, None, u'A combination of style bits.'), -(u'UIText', u'Text', u'Y', None, None, None, None, u'Text', None, u'The localized version of the string.'), -(u'UIText', u'Key', u'N', None, None, None, None, u'Identifier', None, u'A unique key that identifies the particular string.'), -(u'_Validation', u'Table', u'N', None, None, None, None, u'Identifier', None, u'Name of table'), -(u'_Validation', u'Description', u'Y', None, None, None, None, u'Text', None, u'Description of column'), -(u'_Validation', u'Column', u'N', None, None, None, None, u'Identifier', None, u'Name of column'), -(u'_Validation', u'Nullable', u'N', None, None, None, None, None, u'Y;N;@', u'Whether the column is nullable'), -(u'_Validation', u'MinValue', u'Y', -2147483647, 2147483647, None, None, None, None, u'Minimum value allowed'), -(u'_Validation', u'MaxValue', u'Y', -2147483647, 2147483647, None, None, None, None, u'Maximum value allowed'), -(u'_Validation', u'KeyTable', u'Y', None, None, None, None, u'Identifier', None, u'For foreign key, Name of table to which data must link'), -(u'_Validation', u'KeyColumn', u'Y', 1, 32, None, None, None, None, u'Column to which foreign key connects'), -(u'_Validation', u'Category', u'Y', None, None, None, None, None, u'Text;Formatted;Template;Condition;Guid;Path;Version;Language;Identifier;Binary;UpperCase;LowerCase;Filename;Paths;AnyPath;WildCardFilename;RegPath;KeyFormatted;CustomSource;Property;Cabinet;Shortcut;URL', u'String category'), -(u'_Validation', u'Set', u'Y', None, None, None, None, u'Text', None, u'Set of values that are permitted'), -(u'AdvtUISequence', u'Action', u'N', None, None, None, None, u'Identifier', None, u'Name of action to invoke, either in the engine or the handler DLL.'), -(u'AdvtUISequence', u'Sequence', u'Y', -4, 32767, None, None, None, None, u'Number that determines the sort order in which the actions are to be executed. Leave blank to suppress action.'), -(u'AdvtUISequence', u'Condition', u'Y', None, None, None, None, u'Condition', None, u'Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.'), -(u'AppId', u'AppId', u'N', None, None, None, None, u'Guid', None, None), -(u'AppId', u'ActivateAtStorage', u'Y', 0, 1, None, None, None, None, None), -(u'AppId', u'DllSurrogate', u'Y', None, None, None, None, u'Text', None, None), -(u'AppId', u'LocalService', u'Y', None, None, None, None, u'Text', None, None), -(u'AppId', u'RemoteServerName', u'Y', None, None, None, None, u'Formatted', None, None), -(u'AppId', u'RunAsInteractiveUser', u'Y', 0, 1, None, None, None, None, None), -(u'AppId', u'ServiceParameters', u'Y', None, None, None, None, u'Text', None, None), -(u'Feature', u'Attributes', u'N', None, None, None, None, None, u'0;1;2;4;5;6;8;9;10;16;17;18;20;21;22;24;25;26;32;33;34;36;37;38;48;49;50;52;53;54', u'Feature attributes'), -(u'Feature', u'Description', u'Y', None, None, None, None, u'Text', None, u'Longer descriptive text describing a visible feature item.'), -(u'Feature', u'Title', u'Y', None, None, None, None, u'Text', None, u'Short text identifying a visible feature item.'), -(u'Feature', u'Feature', u'N', None, None, None, None, u'Identifier', None, u'Primary key used to identify a particular feature record.'), -(u'Feature', u'Directory_', u'Y', None, None, u'Directory', 1, u'UpperCase', None, u'The name of the Directory that can be configured by the UI. A non-null value will enable the browse button.'), -(u'Feature', u'Level', u'N', 0, 32767, None, None, None, None, u'The install level at which record will be initially selected. An install level of 0 will disable an item and prevent its display.'), -(u'Feature', u'Display', u'Y', 0, 32767, None, None, None, None, u'Numeric sort order, used to force a specific display ordering.'), -(u'Feature', u'Feature_Parent', u'Y', None, None, u'Feature', 1, u'Identifier', None, u'Optional key of a parent record in the same table. If the parent is not selected, then the record will not be installed. Null indicates a root item.'), -(u'File', u'Sequence', u'N', 1, 32767, None, None, None, None, u'Sequence with respect to the media images; order must track cabinet order.'), -(u'File', u'Attributes', u'Y', 0, 32767, None, None, None, None, u'Integer containing bit flags representing file attributes (with the decimal value of each bit position in parentheses)'), -(u'File', u'File', u'N', None, None, None, None, u'Identifier', None, u'Primary key, non-localized token, must match identifier in cabinet. For uncompressed files, this field is ignored.'), -(u'File', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Foreign key referencing Component that controls the file.'), -(u'File', u'FileName', u'N', None, None, None, None, u'Filename', None, u'File name used for installation, may be localized. This may contain a "short name|long name" pair.'), -(u'File', u'FileSize', u'N', 0, 2147483647, None, None, None, None, u'Size of file in bytes (long integer).'), -(u'File', u'Language', u'Y', None, None, None, None, u'Language', None, u'List of decimal language Ids, comma-separated if more than one.'), -(u'File', u'Version', u'Y', None, None, u'File', 1, u'Version', None, u'Version string for versioned files; Blank for unversioned files.'), -(u'Class', u'Attributes', u'Y', None, 32767, None, None, None, None, u'Class registration attributes.'), -(u'Class', u'Feature_', u'N', None, None, u'Feature', 1, u'Identifier', None, u'Required foreign key into the Feature Table, specifying the feature to validate or install in order for the CLSID factory to be operational.'), -(u'Class', u'Description', u'Y', None, None, None, None, u'Text', None, u'Localized description for the Class.'), -(u'Class', u'Argument', u'Y', None, None, None, None, u'Formatted', None, u'optional argument for LocalServers.'), -(u'Class', u'AppId_', u'Y', None, None, u'AppId', 1, u'Guid', None, u'Optional AppID containing DCOM information for associated application (string GUID).'), -(u'Class', u'CLSID', u'N', None, None, None, None, u'Guid', None, u'The CLSID of an OLE factory.'), -(u'Class', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Required foreign key into the Component Table, specifying the component for which to return a path when called through LocateComponent.'), -(u'Class', u'Context', u'N', None, None, None, None, u'Identifier', None, u'The numeric server context for this server. CLSCTX_xxxx'), -(u'Class', u'DefInprocHandler', u'Y', None, None, None, None, u'Filename', u'1;2;3', u'Optional default inproc handler. Only optionally provided if Context=CLSCTX_LOCAL_SERVER. Typically "ole32.dll" or "mapi32.dll"'), -(u'Class', u'FileTypeMask', u'Y', None, None, None, None, u'Text', None, u'Optional string containing information for the HKCRthis CLSID) key. If multiple patterns exist, they must be delimited by a semicolon, and numeric subkeys will be generated: 0,1,2...'), -(u'Class', u'Icon_', u'Y', None, None, u'Icon', 1, u'Identifier', None, u'Optional foreign key into the Icon Table, specifying the icon file associated with this CLSID. Will be written under the DefaultIcon key.'), -(u'Class', u'IconIndex', u'Y', -32767, 32767, None, None, None, None, u'Optional icon index.'), -(u'Class', u'ProgId_Default', u'Y', None, None, u'ProgId', 1, u'Text', None, u'Optional ProgId associated with this CLSID.'), -(u'Component', u'Condition', u'Y', None, None, None, None, u'Condition', None, u"A conditional statement that will disable this component if the specified condition evaluates to the 'True' state. If a component is disabled, it will not be installed, regardless of the 'Action' state associated with the component."), -(u'Component', u'Attributes', u'N', None, None, None, None, None, None, u'Remote execution option, one of irsEnum'), -(u'Component', u'Component', u'N', None, None, None, None, u'Identifier', None, u'Primary key used to identify a particular component record.'), -(u'Component', u'ComponentId', u'Y', None, None, None, None, u'Guid', None, u'A string GUID unique to this component, version, and language.'), -(u'Component', u'Directory_', u'N', None, None, u'Directory', 1, u'Identifier', None, u'Required key of a Directory table record. This is actually a property name whose value contains the actual path, set either by the AppSearch action or with the default setting obtained from the Directory table.'), -(u'Component', u'KeyPath', u'Y', None, None, u'File;Registry;ODBCDataSource', 1, u'Identifier', None, u'Either the primary key into the File table, Registry table, or ODBCDataSource table. This extract path is stored when the component is installed, and is used to detect the presence of the component and to return the path to it.'), -(u'ProgId', u'Description', u'Y', None, None, None, None, u'Text', None, u'Localized description for the Program identifier.'), -(u'ProgId', u'Icon_', u'Y', None, None, u'Icon', 1, u'Identifier', None, u'Optional foreign key into the Icon Table, specifying the icon file associated with this ProgId. Will be written under the DefaultIcon key.'), -(u'ProgId', u'IconIndex', u'Y', -32767, 32767, None, None, None, None, u'Optional icon index.'), -(u'ProgId', u'ProgId', u'N', None, None, None, None, u'Text', None, u'The Program Identifier. Primary key.'), -(u'ProgId', u'Class_', u'Y', None, None, u'Class', 1, u'Guid', None, u'The CLSID of an OLE factory corresponding to the ProgId.'), -(u'ProgId', u'ProgId_Parent', u'Y', None, None, u'ProgId', 1, u'Text', None, u'The Parent Program Identifier. If specified, the ProgId column becomes a version independent prog id.'), -(u'CompLocator', u'Type', u'Y', 0, 1, None, None, None, None, u'A boolean value that determines if the registry value is a filename or a directory location.'), -(u'CompLocator', u'Signature_', u'N', None, None, None, None, u'Identifier', None, u'The table key. The Signature_ represents a unique file signature and is also the foreign key in the Signature table.'), -(u'CompLocator', u'ComponentId', u'N', None, None, None, None, u'Guid', None, u'A string GUID unique to this component, version, and language.'), -(u'Complus', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Foreign key referencing Component that controls the ComPlus component.'), -(u'Complus', u'ExpType', u'Y', 0, 32767, None, None, None, None, u'ComPlus component attributes.'), -(u'Directory', u'Directory', u'N', None, None, None, None, u'Identifier', None, u'Unique identifier for directory entry, primary key. If a property by this name is defined, it contains the full path to the directory.'), -(u'Directory', u'DefaultDir', u'N', None, None, None, None, u'DefaultDir', None, u"The default sub-path under parent's path."), -(u'Directory', u'Directory_Parent', u'Y', None, None, u'Directory', 1, u'Identifier', None, u'Reference to the entry in this table specifying the default parent directory. A record parented to itself or with a Null parent represents a root of the install tree.'), -(u'CreateFolder', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Foreign key into the Component table.'), -(u'CreateFolder', u'Directory_', u'N', None, None, u'Directory', 1, u'Identifier', None, u'Primary key, could be foreign key into the Directory table.'), -(u'CustomAction', u'Type', u'N', 1, 16383, None, None, None, None, u'The numeric custom action type, consisting of source location, code type, entry, option flags.'), -(u'CustomAction', u'Action', u'N', None, None, None, None, u'Identifier', None, u'Primary key, name of action, normally appears in sequence table unless private use.'), -(u'CustomAction', u'Source', u'Y', None, None, None, None, u'CustomSource', None, u'The table reference of the source of the code.'), -(u'CustomAction', u'Target', u'Y', None, None, None, None, u'Formatted', None, u'Excecution parameter, depends on the type of custom action'), -(u'DrLocator', u'Signature_', u'N', None, None, None, None, u'Identifier', None, u'The Signature_ represents a unique file signature and is also the foreign key in the Signature table.'), -(u'DrLocator', u'Path', u'Y', None, None, None, None, u'AnyPath', None, u'The path on the user system. This is a either a subpath below the value of the Parent or a full path. The path may contain properties enclosed within [ ] that will be expanded.'), -(u'DrLocator', u'Depth', u'Y', 0, 32767, None, None, None, None, u'The depth below the path to which the Signature_ is recursively searched. If absent, the depth is assumed to be 0.'), -(u'DrLocator', u'Parent', u'Y', None, None, None, None, u'Identifier', None, u'The parent file signature. It is also a foreign key in the Signature table. If null and the Path column does not expand to a full path, then all the fixed drives of the user system are searched using the Path.'), -(u'DuplicateFile', u'File_', u'N', None, None, u'File', 1, u'Identifier', None, u'Foreign key referencing the source file to be duplicated.'), -(u'DuplicateFile', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Foreign key referencing Component that controls the duplicate file.'), -(u'DuplicateFile', u'DestFolder', u'Y', None, None, None, None, u'Identifier', None, u'Name of a property whose value is assumed to resolve to the full pathname to a destination folder.'), -(u'DuplicateFile', u'DestName', u'Y', None, None, None, None, u'Filename', None, u'Filename to be given to the duplicate file.'), -(u'DuplicateFile', u'FileKey', u'N', None, None, None, None, u'Identifier', None, u'Primary key used to identify a particular file entry'), -(u'Environment', u'Name', u'N', None, None, None, None, u'Text', None, u'The name of the environmental value.'), -(u'Environment', u'Value', u'Y', None, None, None, None, u'Formatted', None, u'The value to set in the environmental settings.'), -(u'Environment', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Foreign key into the Component table referencing component that controls the installing of the environmental value.'), -(u'Environment', u'Environment', u'N', None, None, None, None, u'Identifier', None, u'Unique identifier for the environmental variable setting'), -(u'Error', u'Error', u'N', 0, 32767, None, None, None, None, u'Integer error number, obtained from header file IError(...) macros.'), -(u'Error', u'Message', u'Y', None, None, None, None, u'Template', None, u'Error formatting template, obtained from user ed. or localizers.'), -(u'Extension', u'Feature_', u'N', None, None, u'Feature', 1, u'Identifier', None, u'Required foreign key into the Feature Table, specifying the feature to validate or install in order for the CLSID factory to be operational.'), -(u'Extension', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Required foreign key into the Component Table, specifying the component for which to return a path when called through LocateComponent.'), -(u'Extension', u'Extension', u'N', None, None, None, None, u'Text', None, u'The extension associated with the table row.'), -(u'Extension', u'MIME_', u'Y', None, None, u'MIME', 1, u'Text', None, u'Optional Context identifier, typically "type/format" associated with the extension'), -(u'Extension', u'ProgId_', u'Y', None, None, u'ProgId', 1, u'Text', None, u'Optional ProgId associated with this extension.'), -(u'MIME', u'CLSID', u'Y', None, None, None, None, u'Guid', None, u'Optional associated CLSID.'), -(u'MIME', u'ContentType', u'N', None, None, None, None, u'Text', None, u'Primary key. Context identifier, typically "type/format".'), -(u'MIME', u'Extension_', u'N', None, None, u'Extension', 1, u'Text', None, u'Optional associated extension (without dot)'), -(u'FeatureComponents', u'Feature_', u'N', None, None, u'Feature', 1, u'Identifier', None, u'Foreign key into Feature table.'), -(u'FeatureComponents', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Foreign key into Component table.'), -(u'FileSFPCatalog', u'File_', u'N', None, None, u'File', 1, u'Identifier', None, u'File associated with the catalog'), -(u'FileSFPCatalog', u'SFPCatalog_', u'N', None, None, u'SFPCatalog', 1, u'Filename', None, u'Catalog associated with the file'), -(u'SFPCatalog', u'SFPCatalog', u'N', None, None, None, None, u'Filename', None, u'File name for the catalog.'), -(u'SFPCatalog', u'Catalog', u'N', None, None, None, None, u'Binary', None, u'SFP Catalog'), -(u'SFPCatalog', u'Dependency', u'Y', None, None, None, None, u'Formatted', None, u'Parent catalog - only used by SFP'), -(u'Font', u'File_', u'N', None, None, u'File', 1, u'Identifier', None, u'Primary key, foreign key into File table referencing font file.'), -(u'Font', u'FontTitle', u'Y', None, None, None, None, u'Text', None, u'Font name.'), -(u'IniFile', u'Action', u'N', None, None, None, None, None, u'0;1;3', u'The type of modification to be made, one of iifEnum'), -(u'IniFile', u'Value', u'N', None, None, None, None, u'Formatted', None, u'The value to be written.'), -(u'IniFile', u'Key', u'N', None, None, None, None, u'Formatted', None, u'The .INI file key below Section.'), -(u'IniFile', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Foreign key into the Component table referencing component that controls the installing of the .INI value.'), -(u'IniFile', u'FileName', u'N', None, None, None, None, u'Filename', None, u'The .INI file name in which to write the information'), -(u'IniFile', u'IniFile', u'N', None, None, None, None, u'Identifier', None, u'Primary key, non-localized token.'), -(u'IniFile', u'DirProperty', u'Y', None, None, None, None, u'Identifier', None, u'Foreign key into the Directory table denoting the directory where the .INI file is.'), -(u'IniFile', u'Section', u'N', None, None, None, None, u'Formatted', None, u'The .INI file Section.'), -(u'IniLocator', u'Type', u'Y', 0, 2, None, None, None, None, u'An integer value that determines if the .INI value read is a filename or a directory location or to be used as is w/o interpretation.'), -(u'IniLocator', u'Key', u'N', None, None, None, None, u'Text', None, u'Key value (followed by an equals sign in INI file).'), -(u'IniLocator', u'Signature_', u'N', None, None, None, None, u'Identifier', None, u'The table key. The Signature_ represents a unique file signature and is also the foreign key in the Signature table.'), -(u'IniLocator', u'FileName', u'N', None, None, None, None, u'Filename', None, u'The .INI file name.'), -(u'IniLocator', u'Section', u'N', None, None, None, None, u'Text', None, u'Section name within in file (within square brackets in INI file).'), -(u'IniLocator', u'Field', u'Y', 0, 32767, None, None, None, None, u'The field in the .INI line. If Field is null or 0 the entire line is read.'), -(u'IsolatedComponent', u'Component_Application', u'N', None, None, u'Component', 1, u'Identifier', None, u'Key to Component table item for application'), -(u'IsolatedComponent', u'Component_Shared', u'N', None, None, u'Component', 1, u'Identifier', None, u'Key to Component table item to be isolated'), -(u'LaunchCondition', u'Condition', u'N', None, None, None, None, u'Condition', None, u'Expression which must evaluate to TRUE in order for install to commence.'), -(u'LaunchCondition', u'Description', u'N', None, None, None, None, u'Formatted', None, u'Localizable text to display when condition fails and install must abort.'), -(u'LockPermissions', u'Table', u'N', None, None, None, None, u'Identifier', u'Directory;File;Registry', u'Reference to another table name'), -(u'LockPermissions', u'Domain', u'Y', None, None, None, None, u'Formatted', None, u'Domain name for user whose permissions are being set. (usually a property)'), -(u'LockPermissions', u'LockObject', u'N', None, None, None, None, u'Identifier', None, u'Foreign key into Registry or File table'), -(u'LockPermissions', u'Permission', u'Y', -2147483647, 2147483647, None, None, None, None, u'Permission Access mask. Full Control = 268435456 (GENERIC_ALL = 0x10000000)'), -(u'LockPermissions', u'User', u'N', None, None, None, None, u'Formatted', None, u'User for permissions to be set. (usually a property)'), -(u'Media', u'Source', u'Y', None, None, None, None, u'Property', None, u'The property defining the location of the cabinet file.'), -(u'Media', u'Cabinet', u'Y', None, None, None, None, u'Cabinet', None, u'If some or all of the files stored on the media are compressed in a cabinet, the name of that cabinet.'), -(u'Media', u'DiskId', u'N', 1, 32767, None, None, None, None, u'Primary key, integer to determine sort order for table.'), -(u'Media', u'DiskPrompt', u'Y', None, None, None, None, u'Text', None, u'Disk name: the visible text actually printed on the disk. This will be used to prompt the user when this disk needs to be inserted.'), -(u'Media', u'LastSequence', u'N', 0, 32767, None, None, None, None, u'File sequence number for the last file for this media.'), -(u'Media', u'VolumeLabel', u'Y', None, None, None, None, u'Text', None, u'The label attributed to the volume.'), -(u'ModuleComponents', u'Component', u'N', None, None, u'Component', 1, u'Identifier', None, u'Component contained in the module.'), -(u'ModuleComponents', u'Language', u'N', None, None, u'ModuleSignature', 2, None, None, u'Default language ID for module (may be changed by transform).'), -(u'ModuleComponents', u'ModuleID', u'N', None, None, u'ModuleSignature', 1, u'Identifier', None, u'Module containing the component.'), -(u'ModuleSignature', u'Language', u'N', None, None, None, None, None, None, u'Default decimal language of module.'), -(u'ModuleSignature', u'Version', u'N', None, None, None, None, u'Version', None, u'Version of the module.'), -(u'ModuleSignature', u'ModuleID', u'N', None, None, None, None, u'Identifier', None, u'Module identifier (String.GUID).'), -(u'ModuleDependency', u'ModuleID', u'N', None, None, u'ModuleSignature', 1, u'Identifier', None, u'Module requiring the dependency.'), -(u'ModuleDependency', u'ModuleLanguage', u'N', None, None, u'ModuleSignature', 2, None, None, u'Language of module requiring the dependency.'), -(u'ModuleDependency', u'RequiredID', u'N', None, None, None, None, None, None, u'String.GUID of required module.'), -(u'ModuleDependency', u'RequiredLanguage', u'N', None, None, None, None, None, None, u'LanguageID of the required module.'), -(u'ModuleDependency', u'RequiredVersion', u'Y', None, None, None, None, u'Version', None, u'Version of the required version.'), -(u'ModuleExclusion', u'ModuleID', u'N', None, None, u'ModuleSignature', 1, u'Identifier', None, u'String.GUID of module with exclusion requirement.'), -(u'ModuleExclusion', u'ModuleLanguage', u'N', None, None, u'ModuleSignature', 2, None, None, u'LanguageID of module with exclusion requirement.'), -(u'ModuleExclusion', u'ExcludedID', u'N', None, None, None, None, None, None, u'String.GUID of excluded module.'), -(u'ModuleExclusion', u'ExcludedLanguage', u'N', None, None, None, None, None, None, u'Language of excluded module.'), -(u'ModuleExclusion', u'ExcludedMaxVersion', u'Y', None, None, None, None, u'Version', None, u'Maximum version of excluded module.'), -(u'ModuleExclusion', u'ExcludedMinVersion', u'Y', None, None, None, None, u'Version', None, u'Minimum version of excluded module.'), -(u'MoveFile', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'If this component is not "selected" for installation or removal, no action will be taken on the associated MoveFile entry'), -(u'MoveFile', u'DestFolder', u'N', None, None, None, None, u'Identifier', None, u'Name of a property whose value is assumed to resolve to the full path to the destination directory'), -(u'MoveFile', u'DestName', u'Y', None, None, None, None, u'Filename', None, u'Name to be given to the original file after it is moved or copied. If blank, the destination file will be given the same name as the source file'), -(u'MoveFile', u'FileKey', u'N', None, None, None, None, u'Identifier', None, u'Primary key that uniquely identifies a particular MoveFile record'), -(u'MoveFile', u'Options', u'N', 0, 1, None, None, None, None, u'Integer value specifying the MoveFile operating mode, one of imfoEnum'), -(u'MoveFile', u'SourceFolder', u'Y', None, None, None, None, u'Identifier', None, u'Name of a property whose value is assumed to resolve to the full path to the source directory'), -(u'MoveFile', u'SourceName', u'Y', None, None, None, None, u'Text', None, u"Name of the source file(s) to be moved or copied. Can contain the '*' or '?' wildcards."), -(u'MsiAssembly', u'Attributes', u'Y', None, None, None, None, None, None, u'Assembly attributes'), -(u'MsiAssembly', u'Feature_', u'N', None, None, u'Feature', 1, u'Identifier', None, u'Foreign key into Feature table.'), -(u'MsiAssembly', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Foreign key into Component table.'), -(u'MsiAssembly', u'File_Application', u'Y', None, None, u'File', 1, u'Identifier', None, u'Foreign key into File table, denoting the application context for private assemblies. Null for global assemblies.'), -(u'MsiAssembly', u'File_Manifest', u'Y', None, None, u'File', 1, u'Identifier', None, u'Foreign key into the File table denoting the manifest file for the assembly.'), -(u'MsiAssemblyName', u'Name', u'N', None, None, None, None, u'Text', None, u'The name part of the name-value pairs for the assembly name.'), -(u'MsiAssemblyName', u'Value', u'N', None, None, None, None, u'Text', None, u'The value part of the name-value pairs for the assembly name.'), -(u'MsiAssemblyName', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Foreign key into Component table.'), -(u'MsiDigitalCertificate', u'CertData', u'N', None, None, None, None, u'Binary', None, u'A certificate context blob for a signer certificate'), -(u'MsiDigitalCertificate', u'DigitalCertificate', u'N', None, None, None, None, u'Identifier', None, u'A unique identifier for the row'), -(u'MsiDigitalSignature', u'Table', u'N', None, None, None, None, None, u'Media', u'Reference to another table name (only Media table is supported)'), -(u'MsiDigitalSignature', u'DigitalCertificate_', u'N', None, None, u'MsiDigitalCertificate', 1, u'Identifier', None, u'Foreign key to MsiDigitalCertificate table identifying the signer certificate'), -(u'MsiDigitalSignature', u'Hash', u'Y', None, None, None, None, u'Binary', None, u'The encoded hash blob from the digital signature'), -(u'MsiDigitalSignature', u'SignObject', u'N', None, None, None, None, u'Text', None, u'Foreign key to Media table'), -(u'MsiFileHash', u'File_', u'N', None, None, u'File', 1, u'Identifier', None, u'Primary key, foreign key into File table referencing file with this hash'), -(u'MsiFileHash', u'Options', u'N', 0, 32767, None, None, None, None, u'Various options and attributes for this hash.'), -(u'MsiFileHash', u'HashPart1', u'N', None, None, None, None, None, None, u'Size of file in bytes (long integer).'), -(u'MsiFileHash', u'HashPart2', u'N', None, None, None, None, None, None, u'Size of file in bytes (long integer).'), -(u'MsiFileHash', u'HashPart3', u'N', None, None, None, None, None, None, u'Size of file in bytes (long integer).'), -(u'MsiFileHash', u'HashPart4', u'N', None, None, None, None, None, None, u'Size of file in bytes (long integer).'), -(u'MsiPatchHeaders', u'StreamRef', u'N', None, None, None, None, u'Identifier', None, u'Primary key. A unique identifier for the row.'), -(u'MsiPatchHeaders', u'Header', u'N', None, None, None, None, u'Binary', None, u'Binary stream. The patch header, used for patch validation.'), -(u'ODBCAttribute', u'Value', u'Y', None, None, None, None, u'Text', None, u'Value for ODBC driver attribute'), -(u'ODBCAttribute', u'Attribute', u'N', None, None, None, None, u'Text', None, u'Name of ODBC driver attribute'), -(u'ODBCAttribute', u'Driver_', u'N', None, None, u'ODBCDriver', 1, u'Identifier', None, u'Reference to ODBC driver in ODBCDriver table'), -(u'ODBCDriver', u'Description', u'N', None, None, None, None, u'Text', None, u'Text used as registered name for driver, non-localized'), -(u'ODBCDriver', u'File_', u'N', None, None, u'File', 1, u'Identifier', None, u'Reference to key driver file'), -(u'ODBCDriver', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Reference to associated component'), -(u'ODBCDriver', u'Driver', u'N', None, None, None, None, u'Identifier', None, u'Primary key, non-localized.internal token for driver'), -(u'ODBCDriver', u'File_Setup', u'Y', None, None, u'File', 1, u'Identifier', None, u'Optional reference to key driver setup DLL'), -(u'ODBCDataSource', u'Description', u'N', None, None, None, None, u'Text', None, u'Text used as registered name for data source'), -(u'ODBCDataSource', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Reference to associated component'), -(u'ODBCDataSource', u'DataSource', u'N', None, None, None, None, u'Identifier', None, u'Primary key, non-localized.internal token for data source'), -(u'ODBCDataSource', u'DriverDescription', u'N', None, None, None, None, u'Text', None, u'Reference to driver description, may be existing driver'), -(u'ODBCDataSource', u'Registration', u'N', 0, 1, None, None, None, None, u'Registration option: 0=machine, 1=user, others t.b.d.'), -(u'ODBCSourceAttribute', u'Value', u'Y', None, None, None, None, u'Text', None, u'Value for ODBC data source attribute'), -(u'ODBCSourceAttribute', u'Attribute', u'N', None, None, None, None, u'Text', None, u'Name of ODBC data source attribute'), -(u'ODBCSourceAttribute', u'DataSource_', u'N', None, None, u'ODBCDataSource', 1, u'Identifier', None, u'Reference to ODBC data source in ODBCDataSource table'), -(u'ODBCTranslator', u'Description', u'N', None, None, None, None, u'Text', None, u'Text used as registered name for translator'), -(u'ODBCTranslator', u'File_', u'N', None, None, u'File', 1, u'Identifier', None, u'Reference to key translator file'), -(u'ODBCTranslator', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Reference to associated component'), -(u'ODBCTranslator', u'File_Setup', u'Y', None, None, u'File', 1, u'Identifier', None, u'Optional reference to key translator setup DLL'), -(u'ODBCTranslator', u'Translator', u'N', None, None, None, None, u'Identifier', None, u'Primary key, non-localized.internal token for translator'), -(u'Patch', u'Sequence', u'N', 0, 32767, None, None, None, None, u'Primary key, sequence with respect to the media images; order must track cabinet order.'), -(u'Patch', u'Attributes', u'N', 0, 32767, None, None, None, None, u'Integer containing bit flags representing patch attributes'), -(u'Patch', u'File_', u'N', None, None, None, None, u'Identifier', None, u'Primary key, non-localized token, foreign key to File table, must match identifier in cabinet.'), -(u'Patch', u'Header', u'Y', None, None, None, None, u'Binary', None, u'Binary stream. The patch header, used for patch validation.'), -(u'Patch', u'PatchSize', u'N', 0, 2147483647, None, None, None, None, u'Size of patch in bytes (long integer).'), -(u'Patch', u'StreamRef_', u'Y', None, None, None, None, u'Identifier', None, u'Identifier. Foreign key to the StreamRef column of the MsiPatchHeaders table.'), -(u'PatchPackage', u'Media_', u'N', 0, 32767, None, None, None, None, u'Foreign key to DiskId column of Media table. Indicates the disk containing the patch package.'), -(u'PatchPackage', u'PatchId', u'N', None, None, None, None, u'Guid', None, u'A unique string GUID representing this patch.'), -(u'PublishComponent', u'Feature_', u'N', None, None, u'Feature', 1, u'Identifier', None, u'Foreign key into the Feature table.'), -(u'PublishComponent', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Foreign key into the Component table.'), -(u'PublishComponent', u'ComponentId', u'N', None, None, None, None, u'Guid', None, u'A string GUID that represents the component id that will be requested by the alien product.'), -(u'PublishComponent', u'AppData', u'Y', None, None, None, None, u'Text', None, u'This is localisable Application specific data that can be associated with a Qualified Component.'), -(u'PublishComponent', u'Qualifier', u'N', None, None, None, None, u'Text', None, u'This is defined only when the ComponentId column is an Qualified Component Id. This is the Qualifier for ProvideComponentIndirect.'), -(u'Registry', u'Name', u'Y', None, None, None, None, u'Formatted', None, u'The registry value name.'), -(u'Registry', u'Value', u'Y', None, None, None, None, u'Formatted', None, u'The registry value.'), -(u'Registry', u'Key', u'N', None, None, None, None, u'RegPath', None, u'The key for the registry value.'), -(u'Registry', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Foreign key into the Component table referencing component that controls the installing of the registry value.'), -(u'Registry', u'Registry', u'N', None, None, None, None, u'Identifier', None, u'Primary key, non-localized token.'), -(u'Registry', u'Root', u'N', -1, 3, None, None, None, None, u'The predefined root key for the registry value, one of rrkEnum.'), -(u'RegLocator', u'Name', u'Y', None, None, None, None, u'Formatted', None, u'The registry value name.'), -(u'RegLocator', u'Type', u'Y', 0, 18, None, None, None, None, u'An integer value that determines if the registry value is a filename or a directory location or to be used as is w/o interpretation.'), -(u'RegLocator', u'Key', u'N', None, None, None, None, u'RegPath', None, u'The key for the registry value.'), -(u'RegLocator', u'Signature_', u'N', None, None, None, None, u'Identifier', None, u'The table key. The Signature_ represents a unique file signature and is also the foreign key in the Signature table. If the type is 0, the registry values refers a directory, and _Signature is not a foreign key.'), -(u'RegLocator', u'Root', u'N', 0, 3, None, None, None, None, u'The predefined root key for the registry value, one of rrkEnum.'), -(u'RemoveFile', u'InstallMode', u'N', None, None, None, None, None, u'1;2;3', u'Installation option, one of iimEnum.'), -(u'RemoveFile', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Foreign key referencing Component that controls the file to be removed.'), -(u'RemoveFile', u'FileKey', u'N', None, None, None, None, u'Identifier', None, u'Primary key used to identify a particular file entry'), -(u'RemoveFile', u'FileName', u'Y', None, None, None, None, u'WildCardFilename', None, u'Name of the file to be removed.'), -(u'RemoveFile', u'DirProperty', u'N', None, None, None, None, u'Identifier', None, u'Name of a property whose value is assumed to resolve to the full pathname to the folder of the file to be removed.'), -(u'RemoveIniFile', u'Action', u'N', None, None, None, None, None, u'2;4', u'The type of modification to be made, one of iifEnum.'), -(u'RemoveIniFile', u'Value', u'Y', None, None, None, None, u'Formatted', None, u'The value to be deleted. The value is required when Action is iifIniRemoveTag'), -(u'RemoveIniFile', u'Key', u'N', None, None, None, None, u'Formatted', None, u'The .INI file key below Section.'), -(u'RemoveIniFile', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Foreign key into the Component table referencing component that controls the deletion of the .INI value.'), -(u'RemoveIniFile', u'FileName', u'N', None, None, None, None, u'Filename', None, u'The .INI file name in which to delete the information'), -(u'RemoveIniFile', u'DirProperty', u'Y', None, None, None, None, u'Identifier', None, u'Foreign key into the Directory table denoting the directory where the .INI file is.'), -(u'RemoveIniFile', u'Section', u'N', None, None, None, None, u'Formatted', None, u'The .INI file Section.'), -(u'RemoveIniFile', u'RemoveIniFile', u'N', None, None, None, None, u'Identifier', None, u'Primary key, non-localized token.'), -(u'RemoveRegistry', u'Name', u'Y', None, None, None, None, u'Formatted', None, u'The registry value name.'), -(u'RemoveRegistry', u'Key', u'N', None, None, None, None, u'RegPath', None, u'The key for the registry value.'), -(u'RemoveRegistry', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Foreign key into the Component table referencing component that controls the deletion of the registry value.'), -(u'RemoveRegistry', u'Root', u'N', -1, 3, None, None, None, None, u'The predefined root key for the registry value, one of rrkEnum'), -(u'RemoveRegistry', u'RemoveRegistry', u'N', None, None, None, None, u'Identifier', None, u'Primary key, non-localized token.'), -(u'ReserveCost', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Reserve a specified amount of space if this component is to be installed.'), -(u'ReserveCost', u'ReserveFolder', u'Y', None, None, None, None, u'Identifier', None, u'Name of a property whose value is assumed to resolve to the full path to the destination directory'), -(u'ReserveCost', u'ReserveKey', u'N', None, None, None, None, u'Identifier', None, u'Primary key that uniquely identifies a particular ReserveCost record'), -(u'ReserveCost', u'ReserveLocal', u'N', 0, 2147483647, None, None, None, None, u'Disk space to reserve if linked component is installed locally.'), -(u'ReserveCost', u'ReserveSource', u'N', 0, 2147483647, None, None, None, None, u'Disk space to reserve if linked component is installed to run from the source location.'), -(u'SelfReg', u'File_', u'N', None, None, u'File', 1, u'Identifier', None, u'Foreign key into the File table denoting the module that needs to be registered.'), -(u'SelfReg', u'Cost', u'Y', 0, 32767, None, None, None, None, u'The cost of registering the module.'), -(u'ServiceControl', u'Name', u'N', None, None, None, None, u'Formatted', None, u'Name of a service. /, \\, comma and space are invalid'), -(u'ServiceControl', u'Event', u'N', 0, 187, None, None, None, None, u'Bit field: Install: 0x1 = Start, 0x2 = Stop, 0x8 = Delete, Uninstall: 0x10 = Start, 0x20 = Stop, 0x80 = Delete'), -(u'ServiceControl', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Required foreign key into the Component Table that controls the startup of the service'), -(u'ServiceControl', u'ServiceControl', u'N', None, None, None, None, u'Identifier', None, u'Primary key, non-localized token.'), -(u'ServiceControl', u'Arguments', u'Y', None, None, None, None, u'Formatted', None, u'Arguments for the service. Separate by [~].'), -(u'ServiceControl', u'Wait', u'Y', 0, 1, None, None, None, None, u'Boolean for whether to wait for the service to fully start'), -(u'ServiceInstall', u'Name', u'N', None, None, None, None, u'Formatted', None, u'Internal Name of the Service'), -(u'ServiceInstall', u'Description', u'Y', None, None, None, None, u'Text', None, u'Description of service.'), -(u'ServiceInstall', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Required foreign key into the Component Table that controls the startup of the service'), -(u'ServiceInstall', u'Arguments', u'Y', None, None, None, None, u'Formatted', None, u'Arguments to include in every start of the service, passed to WinMain'), -(u'ServiceInstall', u'ServiceInstall', u'N', None, None, None, None, u'Identifier', None, u'Primary key, non-localized token.'), -(u'ServiceInstall', u'Dependencies', u'Y', None, None, None, None, u'Formatted', None, u'Other services this depends on to start. Separate by [~], and end with [~][~]'), -(u'ServiceInstall', u'DisplayName', u'Y', None, None, None, None, u'Formatted', None, u'External Name of the Service'), -(u'ServiceInstall', u'ErrorControl', u'N', -2147483647, 2147483647, None, None, None, None, u'Severity of error if service fails to start'), -(u'ServiceInstall', u'LoadOrderGroup', u'Y', None, None, None, None, u'Formatted', None, u'LoadOrderGroup'), -(u'ServiceInstall', u'Password', u'Y', None, None, None, None, u'Formatted', None, u'password to run service with. (with StartName)'), -(u'ServiceInstall', u'ServiceType', u'N', -2147483647, 2147483647, None, None, None, None, u'Type of the service'), -(u'ServiceInstall', u'StartName', u'Y', None, None, None, None, u'Formatted', None, u'User or object name to run service as'), -(u'ServiceInstall', u'StartType', u'N', 0, 4, None, None, None, None, u'Type of the service'), -(u'Shortcut', u'Name', u'N', None, None, None, None, u'Filename', None, u'The name of the shortcut to be created.'), -(u'Shortcut', u'Description', u'Y', None, None, None, None, u'Text', None, u'The description for the shortcut.'), -(u'Shortcut', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Foreign key into the Component table denoting the component whose selection gates the shortcut creation/deletion.'), -(u'Shortcut', u'Icon_', u'Y', None, None, u'Icon', 1, u'Identifier', None, u'Foreign key into the File table denoting the external icon file for the shortcut.'), -(u'Shortcut', u'IconIndex', u'Y', -32767, 32767, None, None, None, None, u'The icon index for the shortcut.'), -(u'Shortcut', u'Directory_', u'N', None, None, u'Directory', 1, u'Identifier', None, u'Foreign key into the Directory table denoting the directory where the shortcut file is created.'), -(u'Shortcut', u'Target', u'N', None, None, None, None, u'Shortcut', None, u'The shortcut target. This is usually a property that is expanded to a file or a folder that the shortcut points to.'), -(u'Shortcut', u'Arguments', u'Y', None, None, None, None, u'Formatted', None, u'The command-line arguments for the shortcut.'), -(u'Shortcut', u'Shortcut', u'N', None, None, None, None, u'Identifier', None, u'Primary key, non-localized token.'), -(u'Shortcut', u'Hotkey', u'Y', 0, 32767, None, None, None, None, u'The hotkey for the shortcut. It has the virtual-key code for the key in the low-order byte, and the modifier flags in the high-order byte. '), -(u'Shortcut', u'ShowCmd', u'Y', None, None, None, None, None, u'1;3;7', u'The show command for the application window.The following values may be used.'), -(u'Shortcut', u'WkDir', u'Y', None, None, None, None, u'Identifier', None, u'Name of property defining location of working directory.'), -(u'Signature', u'FileName', u'N', None, None, None, None, u'Filename', None, u'The name of the file. This may contain a "short name|long name" pair.'), -(u'Signature', u'Signature', u'N', None, None, None, None, u'Identifier', None, u'The table key. The Signature represents a unique file signature.'), -(u'Signature', u'Languages', u'Y', None, None, None, None, u'Language', None, u'The languages supported by the file.'), -(u'Signature', u'MaxDate', u'Y', 0, 2147483647, None, None, None, None, u'The maximum creation date of the file.'), -(u'Signature', u'MaxSize', u'Y', 0, 2147483647, None, None, None, None, u'The maximum size of the file. '), -(u'Signature', u'MaxVersion', u'Y', None, None, None, None, u'Text', None, u'The maximum version of the file.'), -(u'Signature', u'MinDate', u'Y', 0, 2147483647, None, None, None, None, u'The minimum creation date of the file.'), -(u'Signature', u'MinSize', u'Y', 0, 2147483647, None, None, None, None, u'The minimum size of the file.'), -(u'Signature', u'MinVersion', u'Y', None, None, None, None, u'Text', None, u'The minimum version of the file.'), -(u'TypeLib', u'Feature_', u'N', None, None, u'Feature', 1, u'Identifier', None, u'Required foreign key into the Feature Table, specifying the feature to validate or install in order for the type library to be operational.'), -(u'TypeLib', u'Description', u'Y', None, None, None, None, u'Text', None, None), -(u'TypeLib', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Required foreign key into the Component Table, specifying the component for which to return a path when called through LocateComponent.'), -(u'TypeLib', u'Directory_', u'Y', None, None, u'Directory', 1, u'Identifier', None, u'Optional. The foreign key into the Directory table denoting the path to the help file for the type library.'), -(u'TypeLib', u'Language', u'N', 0, 32767, None, None, None, None, u'The language of the library.'), -(u'TypeLib', u'Version', u'Y', 0, 16777215, None, None, None, None, u'The version of the library. The minor version is in the lower 8 bits of the integer. The major version is in the next 16 bits. '), -(u'TypeLib', u'Cost', u'Y', 0, 2147483647, None, None, None, None, u'The cost associated with the registration of the typelib. This column is currently optional.'), -(u'TypeLib', u'LibID', u'N', None, None, None, None, u'Guid', None, u'The GUID that represents the library.'), -(u'Upgrade', u'Attributes', u'N', 0, 2147483647, None, None, None, None, u'The attributes of this product set.'), -(u'Upgrade', u'Remove', u'Y', None, None, None, None, u'Formatted', None, u'The list of features to remove when uninstalling a product from this set. The default is "ALL".'), -(u'Upgrade', u'Language', u'Y', None, None, None, None, u'Language', None, u'A comma-separated list of languages for either products in this set or products not in this set.'), -(u'Upgrade', u'ActionProperty', u'N', None, None, None, None, u'UpperCase', None, u'The property to set when a product in this set is found.'), -(u'Upgrade', u'UpgradeCode', u'N', None, None, None, None, u'Guid', None, u'The UpgradeCode GUID belonging to the products in this set.'), -(u'Upgrade', u'VersionMax', u'Y', None, None, None, None, u'Text', None, u'The maximum ProductVersion of the products in this set. The set may or may not include products with this particular version.'), -(u'Upgrade', u'VersionMin', u'Y', None, None, None, None, u'Text', None, u'The minimum ProductVersion of the products in this set. The set may or may not include products with this particular version.'), -(u'Verb', u'Sequence', u'Y', 0, 32767, None, None, None, None, u'Order within the verbs for a particular extension. Also used simply to specify the default verb.'), -(u'Verb', u'Argument', u'Y', None, None, None, None, u'Formatted', None, u'Optional value for the command arguments.'), -(u'Verb', u'Extension_', u'N', None, None, u'Extension', 1, u'Text', None, u'The extension associated with the table row.'), -(u'Verb', u'Verb', u'N', None, None, None, None, u'Text', None, u'The verb for the command.'), -(u'Verb', u'Command', u'Y', None, None, None, None, u'Formatted', None, u'The command text.'), -] - -Error = [ -(0, u'{{Fatal error: }}'), -(1, u'{{Error [1]. }}'), -(2, u'Warning [1]. '), -(3, None), -(4, u'Info [1]. '), -(5, u'The installer has encountered an unexpected error installing this package. This may indicate a problem with this package. The error code is [1]. {{The arguments are: [2], [3], [4]}}'), -(6, None), -(7, u'{{Disk full: }}'), -(8, u'Action [Time]: [1]. [2]'), -(9, u'[ProductName]'), -(10, u'{[2]}{, [3]}{, [4]}'), -(11, u'Message type: [1], Argument: [2]'), -(12, u'=== Logging started: [Date] [Time] ==='), -(13, u'=== Logging stopped: [Date] [Time] ==='), -(14, u'Action start [Time]: [1].'), -(15, u'Action ended [Time]: [1]. Return value [2].'), -(16, u'Time remaining: {[1] minutes }{[2] seconds}'), -(17, u'Out of memory. Shut down other applications before retrying.'), -(18, u'Installer is no longer responding.'), -(19, u'Installer stopped prematurely.'), -(20, u'Please wait while Windows configures [ProductName]'), -(21, u'Gathering required information...'), -(22, u'Removing older versions of this application...'), -(23, u'Preparing to remove older versions of this application...'), -(32, u'{[ProductName] }Setup completed successfully.'), -(33, u'{[ProductName] }Setup failed.'), -(1101, u'Error reading from file: [2]. {{ System error [3].}} Verify that the file exists and that you can access it.'), -(1301, u"Cannot create the file '[2]'. A directory with this name already exists. Cancel the install and try installing to a different location."), -(1302, u'Please insert the disk: [2]'), -(1303, u'The installer has insufficient privileges to access this directory: [2]. The installation cannot continue. Log on as administrator or contact your system administrator.'), -(1304, u'Error writing to file: [2]. Verify that you have access to that directory.'), -(1305, u'Error reading from file [2]. {{ System error [3].}} Verify that the file exists and that you can access it.'), -(1306, u"Another application has exclusive access to the file '[2]'. Please shut down all other applications, then click Retry."), -(1307, u'There is not enough disk space to install this file: [2]. Free some disk space and click Retry, or click Cancel to exit.'), -(1308, u'Source file not found: [2]. Verify that the file exists and that you can access it.'), -(1309, u'Error reading from file: [3]. {{ System error [2].}} Verify that the file exists and that you can access it.'), -(1310, u'Error writing to file: [3]. {{ System error [2].}} Verify that you have access to that directory.'), -(1311, u'Source file not found{{(cabinet)}}: [2]. Verify that the file exists and that you can access it.'), -(1312, u"Cannot create the directory '[2]'. A file with this name already exists. Please rename or remove the file and click retry, or click Cancel to exit."), -(1313, u'The volume [2] is currently unavailable. Please select another.'), -(1314, u"The specified path '[2]' is unavailable."), -(1315, u'Unable to write to the specified folder: [2].'), -(1316, u'A network error occurred while attempting to read from the file: [2]'), -(1317, u'An error occurred while attempting to create the directory: [2]'), -(1318, u'A network error occurred while attempting to create the directory: [2]'), -(1319, u'A network error occurred while attempting to open the source file cabinet: [2]'), -(1320, u'The specified path is too long: [2]'), -(1321, u'The Installer has insufficient privileges to modify this file: [2].'), -(1322, u"A portion of the folder path '[2]' is invalid. It is either empty or exceeds the length allowed by the system."), -(1323, u"The folder path '[2]' contains words that are not valid in folder paths."), -(1324, u"The folder path '[2]' contains an invalid character."), -(1325, u"'[2]' is not a valid short file name."), -(1326, u'Error getting file security: [3] GetLastError: [2]'), -(1327, u'Invalid Drive: [2]'), -(1328, u'Error applying patch to file [2]. It has probably been updated by other means, and can no longer be modified by this patch. For more information contact your patch vendor. {{System Error: [3]}}'), -(1329, u'A file that is required cannot be installed because the cabinet file [2] is not digitally signed. This may indicate that the cabinet file is corrupt.'), -(1330, u'A file that is required cannot be installed because the cabinet file [2] has an invalid digital signature. This may indicate that the cabinet file is corrupt.{{ Error [3] was returned by WinVerifyTrust.}}'), -(1331, u'Failed to correctly copy [2] file: CRC error.'), -(1332, u'Failed to correctly move [2] file: CRC error.'), -(1333, u'Failed to correctly patch [2] file: CRC error.'), -(1334, u"The file '[2]' cannot be installed because the file cannot be found in cabinet file '[3]'. This could indicate a network error, an error reading from the CD-ROM, or a problem with this package."), -(1335, u"The cabinet file '[2]' required for this installation is corrupt and cannot be used. This could indicate a network error, an error reading from the CD-ROM, or a problem with this package."), -(1336, u'There was an error creating a temporary file that is needed to complete this installation.{{ Folder: [3]. System error code: [2]}}'), -(1401, u'Could not create key: [2]. {{ System error [3].}} Verify that you have sufficient access to that key, or contact your support personnel. '), -(1402, u'Could not open key: [2]. {{ System error [3].}} Verify that you have sufficient access to that key, or contact your support personnel. '), -(1403, u'Could not delete value [2] from key [3]. {{ System error [4].}} Verify that you have sufficient access to that key, or contact your support personnel. '), -(1404, u'Could not delete key [2]. {{ System error [3].}} Verify that you have sufficient access to that key, or contact your support personnel. '), -(1405, u'Could not read value [2] from key [3]. {{ System error [4].}} Verify that you have sufficient access to that key, or contact your support personnel. '), -(1406, u'Could not write value [2] to key [3]. {{ System error [4].}} Verify that you have sufficient access to that key, or contact your support personnel.'), -(1407, u'Could not get value names for key [2]. {{ System error [3].}} Verify that you have sufficient access to that key, or contact your support personnel.'), -(1408, u'Could not get sub key names for key [2]. {{ System error [3].}} Verify that you have sufficient access to that key, or contact your support personnel.'), -(1409, u'Could not read security information for key [2]. {{ System error [3].}} Verify that you have sufficient access to that key, or contact your support personnel.'), -(1410, u'Could not increase the available registry space. [2] KB of free registry space is required for the installation of this application.'), -(1500, u'Another installation is in progress. You must complete that installation before continuing this one.'), -(1501, u'Error accessing secured data. Please make sure the Windows Installer is configured properly and try the install again.'), -(1502, u"User '[2]' has previously initiated an install for product '[3]'. That user will need to run that install again before they can use that product. Your current install will now continue."), -(1503, u"User '[2]' has previously initiated an install for product '[3]'. That user will need to run that install again before they can use that product."), -(1601, u"Out of disk space -- Volume: '[2]'; required space: [3] KB; available space: [4] KB. Free some disk space and retry."), -(1602, u'Are you sure you want to cancel?'), -(1603, u"The file [2][3] is being held in use{ by the following process: Name: [4], Id: [5], Window Title: '[6]'}. Close that application and retry."), -(1604, u"The product '[2]' is already installed, preventing the installation of this product. The two products are incompatible."), -(1605, u"There is not enough disk space on the volume '[2]' to continue the install with recovery enabled. [3] KB are required, but only [4] KB are available. Click Ignore to continue the install without saving recovery information, click Retry to check for available space again, or click Cancel to quit the installation."), -(1606, u'Could not access network location [2].'), -(1607, u'The following applications should be closed before continuing the install:'), -(1608, u'Could not find any previously installed compliant products on the machine for installing this product.'), -(1609, u"An error occurred while applying security settings. [2] is not a valid user or group. This could be a problem with the package, or a problem connecting to a domain controller on the network. Check your network connection and click Retry, or Cancel to end the install. {{Unable to locate the user's SID, system error [3]}}"), -(1701, u'The key [2] is not valid. Verify that you entered the correct key.'), -(1702, u'The installer must restart your system before configuration of [2] can continue. Click Yes to restart now or No if you plan to manually restart later.'), -(1703, u'You must restart your system for the configuration changes made to [2] to take effect. Click Yes to restart now or No if you plan to manually restart later.'), -(1704, u'An installation for [2] is currently suspended. You must undo the changes made by that installation to continue. Do you want to undo those changes?'), -(1705, u'A previous installation for this product is in progress. You must undo the changes made by that installation to continue. Do you want to undo those changes?'), -(1706, u"An installation package for the product [2] cannot be found. Try the installation again using a valid copy of the installation package '[3]'."), -(1707, u'Installation completed successfully.'), -(1708, u'Installation failed.'), -(1709, u'Product: [2] -- [3]'), -(1710, u'You may either restore your computer to its previous state or continue the install later. Would you like to restore?'), -(1711, u'An error occurred while writing installation information to disk. Check to make sure enough disk space is available, and click Retry, or Cancel to end the install.'), -(1712, u'One or more of the files required to restore your computer to its previous state could not be found. Restoration will not be possible.'), -(1713, u'[2] cannot install one of its required products. Contact your technical support group. {{System Error: [3].}}'), -(1714, u'The older version of [2] cannot be removed. Contact your technical support group. {{System Error [3].}}'), -(1715, u'Installed [2]'), -(1716, u'Configured [2]'), -(1717, u'Removed [2]'), -(1718, u'File [2] was rejected by digital signature policy.'), -(1719, u'The Windows Installer Service could not be accessed. This can occur if you are running Windows in safe mode, or if the Windows Installer is not correctly installed. Contact your support personnel for assistance.'), -(1720, u'There is a problem with this Windows Installer package. A script required for this install to complete could not be run. Contact your support personnel or package vendor. {{Custom action [2] script error [3], [4]: [5] Line [6], Column [7], [8] }}'), -(1721, u'There is a problem with this Windows Installer package. A program required for this install to complete could not be run. Contact your support personnel or package vendor. {{Action: [2], location: [3], command: [4] }}'), -(1722, u'There is a problem with this Windows Installer package. A program run as part of the setup did not finish as expected. Contact your support personnel or package vendor. {{Action [2], location: [3], command: [4] }}'), -(1723, u'There is a problem with this Windows Installer package. A DLL required for this install to complete could not be run. Contact your support personnel or package vendor. {{Action [2], entry: [3], library: [4] }}'), -(1724, u'Removal completed successfully.'), -(1725, u'Removal failed.'), -(1726, u'Advertisement completed successfully.'), -(1727, u'Advertisement failed.'), -(1728, u'Configuration completed successfully.'), -(1729, u'Configuration failed.'), -(1730, u'You must be an Administrator to remove this application. To remove this application, you can log on as an Administrator, or contact your technical support group for assistance.'), -(1801, u'The path [2] is not valid. Please specify a valid path.'), -(1802, u'Out of memory. Shut down other applications before retrying.'), -(1803, u'There is no disk in drive [2]. Please insert one and click Retry, or click Cancel to go back to the previously selected volume.'), -(1804, u'There is no disk in drive [2]. Please insert one and click Retry, or click Cancel to return to the browse dialog and select a different volume.'), -(1805, u'The folder [2] does not exist. Please enter a path to an existing folder.'), -(1806, u'You have insufficient privileges to read this folder.'), -(1807, u'A valid destination folder for the install could not be determined.'), -(1901, u'Error attempting to read from the source install database: [2].'), -(1902, u'Scheduling reboot operation: Renaming file [2] to [3]. Must reboot to complete operation.'), -(1903, u'Scheduling reboot operation: Deleting file [2]. Must reboot to complete operation.'), -(1904, u'Module [2] failed to register. HRESULT [3]. Contact your support personnel.'), -(1905, u'Module [2] failed to unregister. HRESULT [3]. Contact your support personnel.'), -(1906, u'Failed to cache package [2]. Error: [3]. Contact your support personnel.'), -(1907, u'Could not register font [2]. Verify that you have sufficient permissions to install fonts, and that the system supports this font.'), -(1908, u'Could not unregister font [2]. Verify that you that you have sufficient permissions to remove fonts.'), -(1909, u'Could not create Shortcut [2]. Verify that the destination folder exists and that you can access it.'), -(1910, u'Could not remove Shortcut [2]. Verify that the shortcut file exists and that you can access it.'), -(1911, u'Could not register type library for file [2]. Contact your support personnel.'), -(1912, u'Could not unregister type library for file [2]. Contact your support personnel.'), -(1913, u'Could not update the ini file [2][3]. Verify that the file exists and that you can access it.'), -(1914, u'Could not schedule file [2] to replace file [3] on reboot. Verify that you have write permissions to file [3].'), -(1915, u'Error removing ODBC driver manager, ODBC error [2]: [3]. Contact your support personnel.'), -(1916, u'Error installing ODBC driver manager, ODBC error [2]: [3]. Contact your support personnel.'), -(1917, u'Error removing ODBC driver: [4], ODBC error [2]: [3]. Verify that you have sufficient privileges to remove ODBC drivers.'), -(1918, u'Error installing ODBC driver: [4], ODBC error [2]: [3]. Verify that the file [4] exists and that you can access it.'), -(1919, u'Error configuring ODBC data source: [4], ODBC error [2]: [3]. Verify that the file [4] exists and that you can access it.'), -(1920, u"Service '[2]' ([3]) failed to start. Verify that you have sufficient privileges to start system services."), -(1921, u"Service '[2]' ([3]) could not be stopped. Verify that you have sufficient privileges to stop system services."), -(1922, u"Service '[2]' ([3]) could not be deleted. Verify that you have sufficient privileges to remove system services."), -(1923, u"Service '[2]' ([3]) could not be installed. Verify that you have sufficient privileges to install system services."), -(1924, u"Could not update environment variable '[2]'. Verify that you have sufficient privileges to modify environment variables."), -(1925, u'You do not have sufficient privileges to complete this installation for all users of the machine. Log on as administrator and then retry this installation.'), -(1926, u"Could not set file security for file '[3]'. Error: [2]. Verify that you have sufficient privileges to modify the security permissions for this file."), -(1927, u'Component Services (COM+ 1.0) are not installed on this computer. This installation requires Component Services in order to complete successfully. Component Services are available on Windows 2000.'), -(1928, u'Error registering COM+ Application. Contact your support personnel for more information.'), -(1929, u'Error unregistering COM+ Application. Contact your support personnel for more information.'), -(1930, u"The description for service '[2]' ([3]) could not be changed."), -(1931, u'The Windows Installer service cannot update the system file [2] because the file is protected by Windows. You may need to update your operating system for this program to work correctly. {{Package version: [3], OS Protected version: [4]}}'), -(1932, u'The Windows Installer service cannot update the protected Windows file [2]. {{Package version: [3], OS Protected version: [4], SFP Error: [5]}}'), -(1933, u'The Windows Installer service cannot update one or more protected Windows files. {{SFP Error: [2]. List of protected files:\\r\\n[3]}}'), -(1934, u'User installations are disabled via policy on the machine.'), -(1935, u'An error occurred during the installation of assembly component [2]. HRESULT: [3]. {{assembly interface: [4], function: [5], assembly name: [6]}}'), -] - -tables=['AdminExecuteSequence', 'AdminUISequence', 'AdvtExecuteSequence', 'BBControl', 'Billboard', 'Binary', 'CheckBox', 'Property', 'ComboBox', 'Control', 'ListBox', 'ActionText', 'ControlCondition', 'ControlEvent', 'Dialog', 'EventMapping', 'InstallExecuteSequence', 'InstallUISequence', 'ListView', 'RadioButton', 'TextStyle', 'UIText', '_Validation', 'Error'] diff --git a/Tools/msi/wix.props b/Tools/msi/wix.props new file mode 100644 index 000000000000..35492f9b8dd1 --- /dev/null +++ b/Tools/msi/wix.props @@ -0,0 +1,12 @@ + + + + + + $(MSBuildThisFileDirectory)\Wix\ + $(ExternalsDir)\Wix\ + $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Installer XML\3.9@InstallRoot) + $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows Installer XML\3.9@InstallRoot) + $(WixInstallPath)\Wix.targets + + \ No newline at end of file diff --git a/Tools/parser/unparse.py b/Tools/parser/unparse.py index 837cd81aaf85..258c648b6bbc 100644 --- a/Tools/parser/unparse.py +++ b/Tools/parser/unparse.py @@ -401,7 +401,7 @@ def _UnaryOp(self, t): self.dispatch(t.operand) self.write(")") - binop = { "Add":"+", "Sub":"-", "Mult":"*", "Div":"/", "Mod":"%", + binop = { "Add":"+", "Sub":"-", "Mult":"*", "MatMult":"@", "Div":"/", "Mod":"%", "LShift":"<<", "RShift":">>", "BitOr":"|", "BitXor":"^", "BitAnd":"&", "FloorDiv":"//", "Pow": "**"} def _BinOp(self, t): diff --git a/Tools/pybench/systimes.py b/Tools/pybench/systimes.py old mode 100644 new mode 100755 diff --git a/Tools/scripts/checkpip.py b/Tools/scripts/checkpip.py old mode 100644 new mode 100755 index 835101e7b540..8a64eda34af6 --- a/Tools/scripts/checkpip.py +++ b/Tools/scripts/checkpip.py @@ -1,4 +1,4 @@ -#/usr/bin/env python3 +#!/usr/bin/env python3 """ Checks that the version of the projects bundled in ensurepip are the latest versions available. diff --git a/Tools/scripts/diff.py b/Tools/scripts/diff.py index 8be527fd6276..9720a431557a 100755 --- a/Tools/scripts/diff.py +++ b/Tools/scripts/diff.py @@ -8,7 +8,7 @@ """ -import sys, os, time, difflib, optparse +import sys, os, time, difflib, argparse from datetime import datetime, timezone def file_mtime(path): @@ -18,23 +18,25 @@ def file_mtime(path): def main(): - usage = "usage: %prog [options] fromfile tofile" - parser = optparse.OptionParser(usage) - parser.add_option("-c", action="store_true", default=False, help='Produce a context format diff (default)') - parser.add_option("-u", action="store_true", default=False, help='Produce a unified format diff') - parser.add_option("-m", action="store_true", default=False, help='Produce HTML side by side diff (can use -c and -l in conjunction)') - parser.add_option("-n", action="store_true", default=False, help='Produce a ndiff format diff') - parser.add_option("-l", "--lines", type="int", default=3, help='Set number of context lines (default 3)') - (options, args) = parser.parse_args() - - if len(args) == 0: - parser.print_help() - sys.exit(1) - if len(args) != 2: - parser.error("need to specify both a fromfile and tofile") + parser = argparse.ArgumentParser() + parser.add_argument('-c', action='store_true', default=False, + help='Produce a context format diff (default)') + parser.add_argument('-u', action='store_true', default=False, + help='Produce a unified format diff') + parser.add_argument('-m', action='store_true', default=False, + help='Produce HTML side by side diff ' + '(can use -c and -l in conjunction)') + parser.add_argument('-n', action='store_true', default=False, + help='Produce a ndiff format diff') + parser.add_argument('-l', '--lines', type=int, default=3, + help='Set number of context lines (default 3)') + parser.add_argument('fromfile') + parser.add_argument('tofile') + options = parser.parse_args() n = options.lines - fromfile, tofile = args + fromfile = options.fromfile + tofile = options.tofile fromdate = file_mtime(fromfile) todate = file_mtime(tofile) diff --git a/Tools/scripts/findnocoding.py b/Tools/scripts/findnocoding.py index c0997d6598e4..5f3795e65754 100755 --- a/Tools/scripts/findnocoding.py +++ b/Tools/scripts/findnocoding.py @@ -33,6 +33,7 @@ def walk_python_files(self, paths, *args, **kwargs): decl_re = re.compile(rb'^[ \t\f]*#.*coding[:=][ \t]*([-\w.]+)') +blank_re = re.compile(rb'^[ \t\f]*(?:[#\r\n]|$)') def get_declaration(line): match = decl_re.match(line) @@ -58,7 +59,8 @@ def needs_declaration(fullpath): line1 = infile.readline() line2 = infile.readline() - if get_declaration(line1) or get_declaration(line2): + if (get_declaration(line1) or + blank_re.match(line1) and get_declaration(line2)): # the file does have an encoding declaration, so trust it return False diff --git a/Tools/scripts/ftpmirror.py b/Tools/scripts/ftpmirror.py deleted file mode 100755 index a1b683a319ad..000000000000 --- a/Tools/scripts/ftpmirror.py +++ /dev/null @@ -1,405 +0,0 @@ -#! /usr/bin/env python3 - -"""Mirror a remote ftp subtree into a local directory tree. - -usage: ftpmirror [-v] [-q] [-i] [-m] [-n] [-r] [-s pat] - [-l username [-p passwd [-a account]]] - hostname[:port] [remotedir [localdir]] --v: verbose --q: quiet --i: interactive mode --m: macintosh server (NCSA telnet 2.4) (implies -n -s '*.o') --n: don't log in --r: remove local files/directories no longer pertinent --l username [-p passwd [-a account]]: login info (default .netrc or anonymous) --s pat: skip files matching pattern -hostname: remote host w/ optional port separated by ':' -remotedir: remote directory (default initial) -localdir: local directory (default current) -""" - -import os -import sys -import time -import getopt -import ftplib -import netrc -from fnmatch import fnmatch - -# Print usage message and exit -def usage(*args): - sys.stdout = sys.stderr - for msg in args: print(msg) - print(__doc__) - sys.exit(2) - -verbose = 1 # 0 for -q, 2 for -v -interactive = 0 -mac = 0 -rmok = 0 -nologin = 0 -skippats = ['.', '..', '.mirrorinfo'] - -# Main program: parse command line and start processing -def main(): - global verbose, interactive, mac, rmok, nologin - try: - opts, args = getopt.getopt(sys.argv[1:], 'a:bil:mnp:qrs:v') - except getopt.error as msg: - usage(msg) - login = '' - passwd = '' - account = '' - if not args: usage('hostname missing') - host = args[0] - port = 0 - if ':' in host: - host, port = host.split(':', 1) - port = int(port) - try: - auth = netrc.netrc().authenticators(host) - if auth is not None: - login, account, passwd = auth - except (netrc.NetrcParseError, IOError): - pass - for o, a in opts: - if o == '-l': login = a - if o == '-p': passwd = a - if o == '-a': account = a - if o == '-v': verbose = verbose + 1 - if o == '-q': verbose = 0 - if o == '-i': interactive = 1 - if o == '-m': mac = 1; nologin = 1; skippats.append('*.o') - if o == '-n': nologin = 1 - if o == '-r': rmok = 1 - if o == '-s': skippats.append(a) - remotedir = '' - localdir = '' - if args[1:]: - remotedir = args[1] - if args[2:]: - localdir = args[2] - if args[3:]: usage('too many arguments') - # - f = ftplib.FTP() - if verbose: print("Connecting to '%s%s'..." % (host, - (port and ":%d"%port or ""))) - f.connect(host,port) - if not nologin: - if verbose: - print('Logging in as %r...' % (login or 'anonymous')) - f.login(login, passwd, account) - if verbose: print('OK.') - pwd = f.pwd() - if verbose > 1: print('PWD =', repr(pwd)) - if remotedir: - if verbose > 1: print('cwd(%s)' % repr(remotedir)) - f.cwd(remotedir) - if verbose > 1: print('OK.') - pwd = f.pwd() - if verbose > 1: print('PWD =', repr(pwd)) - # - mirrorsubdir(f, localdir) - -# Core logic: mirror one subdirectory (recursively) -def mirrorsubdir(f, localdir): - pwd = f.pwd() - if localdir and not os.path.isdir(localdir): - if verbose: print('Creating local directory', repr(localdir)) - try: - makedir(localdir) - except OSError as msg: - print("Failed to establish local directory", repr(localdir)) - return - infofilename = os.path.join(localdir, '.mirrorinfo') - try: - text = open(infofilename, 'r').read() - except IOError as msg: - text = '{}' - try: - info = eval(text) - except (SyntaxError, NameError): - print('Bad mirror info in', repr(infofilename)) - info = {} - subdirs = [] - listing = [] - if verbose: print('Listing remote directory %r...' % (pwd,)) - f.retrlines('LIST', listing.append) - filesfound = [] - for line in listing: - if verbose > 1: print('-->', repr(line)) - if mac: - # Mac listing has just filenames; - # trailing / means subdirectory - filename = line.strip() - mode = '-' - if filename[-1:] == '/': - filename = filename[:-1] - mode = 'd' - infostuff = '' - else: - # Parse, assuming a UNIX listing - words = line.split(None, 8) - if len(words) < 6: - if verbose > 1: print('Skipping short line') - continue - filename = words[-1].lstrip() - i = filename.find(" -> ") - if i >= 0: - # words[0] had better start with 'l'... - if verbose > 1: - print('Found symbolic link %r' % (filename,)) - linkto = filename[i+4:] - filename = filename[:i] - infostuff = words[-5:-1] - mode = words[0] - skip = 0 - for pat in skippats: - if fnmatch(filename, pat): - if verbose > 1: - print('Skip pattern', repr(pat), end=' ') - print('matches', repr(filename)) - skip = 1 - break - if skip: - continue - if mode[0] == 'd': - if verbose > 1: - print('Remembering subdirectory', repr(filename)) - subdirs.append(filename) - continue - filesfound.append(filename) - if filename in info and info[filename] == infostuff: - if verbose > 1: - print('Already have this version of',repr(filename)) - continue - fullname = os.path.join(localdir, filename) - tempname = os.path.join(localdir, '@'+filename) - if interactive: - doit = askabout('file', filename, pwd) - if not doit: - if filename not in info: - info[filename] = 'Not retrieved' - continue - try: - os.unlink(tempname) - except OSError: - pass - if mode[0] == 'l': - if verbose: - print("Creating symlink %r -> %r" % (filename, linkto)) - try: - os.symlink(linkto, tempname) - except IOError as msg: - print("Can't create %r: %s" % (tempname, msg)) - continue - else: - try: - fp = open(tempname, 'wb') - except IOError as msg: - print("Can't create %r: %s" % (tempname, msg)) - continue - if verbose: - print('Retrieving %r from %r as %r...' % (filename, pwd, fullname)) - if verbose: - fp1 = LoggingFile(fp, 1024, sys.stdout) - else: - fp1 = fp - t0 = time.time() - try: - f.retrbinary('RETR ' + filename, - fp1.write, 8*1024) - except ftplib.error_perm as msg: - print(msg) - t1 = time.time() - bytes = fp.tell() - fp.close() - if fp1 != fp: - fp1.close() - try: - os.unlink(fullname) - except OSError: - pass # Ignore the error - try: - os.rename(tempname, fullname) - except OSError as msg: - print("Can't rename %r to %r: %s" % (tempname, fullname, msg)) - continue - info[filename] = infostuff - writedict(info, infofilename) - if verbose and mode[0] != 'l': - dt = t1 - t0 - kbytes = bytes / 1024.0 - print(int(round(kbytes)), end=' ') - print('Kbytes in', end=' ') - print(int(round(dt)), end=' ') - print('seconds', end=' ') - if t1 > t0: - print('(~%d Kbytes/sec)' % \ - int(round(kbytes/dt),)) - print() - # - # Remove files from info that are no longer remote - deletions = 0 - for filename in list(info.keys()): - if filename not in filesfound: - if verbose: - print("Removing obsolete info entry for", end=' ') - print(repr(filename), "in", repr(localdir or ".")) - del info[filename] - deletions = deletions + 1 - if deletions: - writedict(info, infofilename) - # - # Remove local files that are no longer in the remote directory - try: - if not localdir: names = os.listdir(os.curdir) - else: names = os.listdir(localdir) - except OSError: - names = [] - for name in names: - if name[0] == '.' or name in info or name in subdirs: - continue - skip = 0 - for pat in skippats: - if fnmatch(name, pat): - if verbose > 1: - print('Skip pattern', repr(pat), end=' ') - print('matches', repr(name)) - skip = 1 - break - if skip: - continue - fullname = os.path.join(localdir, name) - if not rmok: - if verbose: - print('Local file', repr(fullname), end=' ') - print('is no longer pertinent') - continue - if verbose: print('Removing local file/dir', repr(fullname)) - remove(fullname) - # - # Recursively mirror subdirectories - for subdir in subdirs: - if interactive: - doit = askabout('subdirectory', subdir, pwd) - if not doit: continue - if verbose: print('Processing subdirectory', repr(subdir)) - localsubdir = os.path.join(localdir, subdir) - pwd = f.pwd() - if verbose > 1: - print('Remote directory now:', repr(pwd)) - print('Remote cwd', repr(subdir)) - try: - f.cwd(subdir) - except ftplib.error_perm as msg: - print("Can't chdir to", repr(subdir), ":", repr(msg)) - else: - if verbose: print('Mirroring as', repr(localsubdir)) - mirrorsubdir(f, localsubdir) - if verbose > 1: print('Remote cwd ..') - f.cwd('..') - newpwd = f.pwd() - if newpwd != pwd: - print('Ended up in wrong directory after cd + cd ..') - print('Giving up now.') - break - else: - if verbose > 1: print('OK.') - -# Helper to remove a file or directory tree -def remove(fullname): - if os.path.isdir(fullname) and not os.path.islink(fullname): - try: - names = os.listdir(fullname) - except OSError: - names = [] - ok = 1 - for name in names: - if not remove(os.path.join(fullname, name)): - ok = 0 - if not ok: - return 0 - try: - os.rmdir(fullname) - except OSError as msg: - print("Can't remove local directory %r: %s" % (fullname, msg)) - return 0 - else: - try: - os.unlink(fullname) - except OSError as msg: - print("Can't remove local file %r: %s" % (fullname, msg)) - return 0 - return 1 - -# Wrapper around a file for writing to write a hash sign every block. -class LoggingFile: - def __init__(self, fp, blocksize, outfp): - self.fp = fp - self.bytes = 0 - self.hashes = 0 - self.blocksize = blocksize - self.outfp = outfp - def write(self, data): - self.bytes = self.bytes + len(data) - hashes = int(self.bytes) / self.blocksize - while hashes > self.hashes: - self.outfp.write('#') - self.outfp.flush() - self.hashes = self.hashes + 1 - self.fp.write(data) - def close(self): - self.outfp.write('\n') - -def raw_input(prompt): - sys.stdout.write(prompt) - sys.stdout.flush() - return sys.stdin.readline() - -# Ask permission to download a file. -def askabout(filetype, filename, pwd): - prompt = 'Retrieve %s %s from %s ? [ny] ' % (filetype, filename, pwd) - while 1: - reply = raw_input(prompt).strip().lower() - if reply in ['y', 'ye', 'yes']: - return 1 - if reply in ['', 'n', 'no', 'nop', 'nope']: - return 0 - print('Please answer yes or no.') - -# Create a directory if it doesn't exist. Recursively create the -# parent directory as well if needed. -def makedir(pathname): - if os.path.isdir(pathname): - return - dirname = os.path.dirname(pathname) - if dirname: makedir(dirname) - os.mkdir(pathname, 0o777) - -# Write a dictionary to a file in a way that can be read back using -# rval() but is still somewhat readable (i.e. not a single long line). -# Also creates a backup file. -def writedict(dict, filename): - dir, fname = os.path.split(filename) - tempname = os.path.join(dir, '@' + fname) - backup = os.path.join(dir, fname + '~') - try: - os.unlink(backup) - except OSError: - pass - fp = open(tempname, 'w') - fp.write('{\n') - for key, value in dict.items(): - fp.write('%r: %r,\n' % (key, value)) - fp.write('}\n') - fp.close() - try: - os.rename(filename, backup) - except OSError: - pass - os.rename(tempname, filename) - - -if __name__ == '__main__': - main() diff --git a/Tools/scripts/generate_opcode_h.py b/Tools/scripts/generate_opcode_h.py new file mode 100644 index 000000000000..efa18a1e8727 --- /dev/null +++ b/Tools/scripts/generate_opcode_h.py @@ -0,0 +1,54 @@ +# This script generates the opcode.h header file. + +from __future__ import with_statement + +import sys +header = """/* Auto-generated by Tools/scripts/generate_opcode_h.py */ +#ifndef Py_OPCODE_H +#define Py_OPCODE_H +#ifdef __cplusplus +extern "C" { +#endif + + + /* Instruction opcodes for compiled code */ +""" + +footer = """ +/* EXCEPT_HANDLER is a special, implicit block type which is created when + entering an except handler. It is not an opcode but we define it here + as we want it to be available to both frameobject.c and ceval.c, while + remaining private.*/ +#define EXCEPT_HANDLER 257 + + +enum cmp_op {PyCmp_LT=Py_LT, PyCmp_LE=Py_LE, PyCmp_EQ=Py_EQ, PyCmp_NE=Py_NE, + PyCmp_GT=Py_GT, PyCmp_GE=Py_GE, PyCmp_IN, PyCmp_NOT_IN, + PyCmp_IS, PyCmp_IS_NOT, PyCmp_EXC_MATCH, PyCmp_BAD}; + +#define HAS_ARG(op) ((op) >= HAVE_ARGUMENT) + +#ifdef __cplusplus +} +#endif +#endif /* !Py_OPCODE_H */ +""" + + +def main(opcode_py, outfile='Include/opcode.h'): + opcode = {} + exec(open(opcode_py).read(), opcode) + opmap = opcode['opmap'] + with open(outfile, 'w') as fobj: + fobj.write(header) + for name in opcode['opname']: + if name in opmap: + fobj.write("#define %-20s\t%-3s\n" % (name, opmap[name])) + if name == 'POP_EXCEPT': # Special entry for HAVE_ARGUMENT + fobj.write("#define %-20s\t%-3d\n" % + ('HAVE_ARGUMENT', opcode['HAVE_ARGUMENT'])) + fobj.write(footer) + + +if __name__ == '__main__': + main(sys.argv[1], sys.argv[2]) diff --git a/Tools/scripts/gprof2html.py b/Tools/scripts/gprof2html.py index ad828358c148..4ca705c3c61c 100755 --- a/Tools/scripts/gprof2html.py +++ b/Tools/scripts/gprof2html.py @@ -2,7 +2,11 @@ """Transform gprof(1) output into useful HTML.""" -import re, os, sys, cgi, webbrowser +import html +import os +import re +import sys +import webbrowser header = """\ @@ -22,7 +26,7 @@ def add_escapes(filename): with open(filename) as fp: for line in fp: - yield cgi.escape(line) + yield html.escape(line) def main(): diff --git a/Tools/scripts/highlight.py b/Tools/scripts/highlight.py index aff5caebdf63..66ad868ec3fe 100755 --- a/Tools/scripts/highlight.py +++ b/Tools/scripts/highlight.py @@ -3,11 +3,12 @@ __author__ = 'Raymond Hettinger' -import keyword, tokenize, cgi, re, functools -try: - import builtins -except ImportError: - import __builtin__ as builtins +import builtins +import functools +import html as html_module +import keyword +import re +import tokenize #### Analyze Python Source ################################# @@ -101,7 +102,7 @@ def html_highlight(classified_text,opener='
\n', closer='' % kind)
-        result.append(cgi.escape(text))
+        result.append(html_module.escape(text))
         if kind:
             result.append('')
     result.append(closer)
@@ -140,7 +141,7 @@ def build_html_page(classified_text, title='python',
     'Create a complete HTML page with colorized source code'
     css_str = '\n'.join(['%s %s' % item for item in css.items()])
     result = html_highlight(classified_text)
-    title = cgi.escape(title)
+    title = html_module.escape(title)
     return html.format(title=title, css=css_str, body=result)
 
 #### LaTeX Output ##########################################
@@ -193,7 +194,11 @@ def latex_highlight(classified_text, title = 'python',
 
 
 if __name__ == '__main__':
-    import sys, argparse, webbrowser, os, textwrap
+    import argparse
+    import os.path
+    import sys
+    import textwrap
+    import webbrowser
 
     parser = argparse.ArgumentParser(
             description = 'Add syntax highlighting to Python source code',
diff --git a/Tools/scripts/md5sum.py b/Tools/scripts/md5sum.py
index 521960c17dc5..9cf4bdc9c691 100755
--- a/Tools/scripts/md5sum.py
+++ b/Tools/scripts/md5sum.py
@@ -9,7 +9,7 @@
 rmode = 'rb'
 
 usage = """
-usage: sum5 [-b] [-t] [-l] [-s bufsize] [file ...]
+usage: md5sum.py [-b] [-t] [-l] [-s bufsize] [file ...]
 -b        : read files in binary mode (default)
 -t        : read files in text mode (you almost certainly don't want this!)
 -l        : print last pathname component only
@@ -17,6 +17,7 @@
 file ...  : files to sum; '-' or no files means stdin
 """ % bufsize
 
+import io
 import sys
 import os
 import getopt
@@ -24,7 +25,7 @@
 
 def sum(*files):
     sts = 0
-    if files and isinstance(files[-1], file):
+    if files and isinstance(files[-1], io.IOBase):
         out, files = files[-1], files[:-1]
     else:
         out = sys.stdout
@@ -53,12 +54,14 @@ def printsum(filename, out=sys.stdout):
     return sts
 
 def printsumfp(fp, filename, out=sys.stdout):
-    m = md5.new()
+    m = md5()
     try:
         while 1:
             data = fp.read(bufsize)
             if not data:
                 break
+            if isinstance(data, str):
+                data = data.encode(fp.encoding)
             m.update(data)
     except IOError as msg:
         sys.stderr.write('%s: I/O error: %s\n' % (filename, msg))
diff --git a/Tools/scripts/patchcheck.py b/Tools/scripts/patchcheck.py
index 6f9821bdd658..1b515201a8d0 100755
--- a/Tools/scripts/patchcheck.py
+++ b/Tools/scripts/patchcheck.py
@@ -152,7 +152,8 @@ def main():
     file_paths = changed_files()
     python_files = [fn for fn in file_paths if fn.endswith('.py')]
     c_files = [fn for fn in file_paths if fn.endswith(('.c', '.h'))]
-    doc_files = [fn for fn in file_paths if fn.startswith('Doc')]
+    doc_files = [fn for fn in file_paths if fn.startswith('Doc') and
+                 fn.endswith(('.rst', '.inc'))]
     misc_files = {os.path.join('Misc', 'ACKS'), os.path.join('Misc', 'NEWS')}\
             & set(file_paths)
     # PEP 8 whitespace rules enforcement.
diff --git a/Tools/scripts/pydocgui.pyw b/Tools/scripts/pydocgui.pyw
deleted file mode 100644
index 8e9a3d682ed0..000000000000
--- a/Tools/scripts/pydocgui.pyw
+++ /dev/null
@@ -1,7 +0,0 @@
-# Note:  this file must not be named pydoc.pyw, lest it just end up
-# importing itself (Python began allowing import of .pyw files
-# between 2.2a1 and 2.2a2).
-import pydoc
-
-if __name__ == '__main__':
-   pydoc.gui()
diff --git a/Tools/scripts/run_tests.py b/Tools/scripts/run_tests.py
old mode 100755
new mode 100644
index e2a205097812..b582e1325093
--- a/Tools/scripts/run_tests.py
+++ b/Tools/scripts/run_tests.py
@@ -32,6 +32,10 @@ def main(regrtest_args):
             ]
     # Allow user-specified interpreter options to override our defaults.
     args.extend(test.support.args_from_interpreter_flags())
+
+    # Workaround for issue #20361
+    args.extend(['-W', 'error::BytesWarning'])
+
     args.extend(['-m', 'test',    # Run the test suite
                  '-r',            # Randomize test order
                  '-w',            # Re-run failed tests in verbose mode
@@ -44,7 +48,11 @@ def main(regrtest_args):
         args.extend(['-u', 'all,-largefile,-audio,-gui'])
     args.extend(regrtest_args)
     print(' '.join(args))
-    os.execv(sys.executable, args)
+    if sys.platform == 'win32':
+        from subprocess import call
+        sys.exit(call(args))
+    else:
+        os.execv(sys.executable, args)
 
 
 if __name__ == '__main__':
diff --git a/Tools/scripts/serve.py b/Tools/scripts/serve.py
index 68c25f057f32..dae21f2260ff 100755
--- a/Tools/scripts/serve.py
+++ b/Tools/scripts/serve.py
@@ -22,7 +22,7 @@ def app(environ, respond):
         return util.FileWrapper(open(fn, "rb"))
     else:
         respond('404 Not Found', [('Content-Type', 'text/plain')])
-        return ['not found']
+        return [b'not found']
 
 if __name__ == '__main__':
     path = sys.argv[1]
diff --git a/Tools/scripts/win_add2path.py b/Tools/scripts/win_add2path.py
old mode 100755
new mode 100644
index c85bea576fe8..1c9aedc5ed8d
--- a/Tools/scripts/win_add2path.py
+++ b/Tools/scripts/win_add2path.py
@@ -22,7 +22,8 @@ def modify():
     scripts = os.path.join(pythonpath, "Scripts")
     appdata = os.environ["APPDATA"]
     if hasattr(site, "USER_SITE"):
-        userpath = site.USER_SITE.replace(appdata, "%APPDATA%")
+        usersite = site.USER_SITE.replace(appdata, "%APPDATA%")
+        userpath = os.path.dirname(usersite)
         userscripts = os.path.join(userpath, "Scripts")
     else:
         userscripts = None
diff --git a/Tools/ssl/make_ssl_data.py b/Tools/ssl/make_ssl_data.py
old mode 100644
new mode 100755
index 10244d106f02..3fb49852f4c2
--- a/Tools/ssl/make_ssl_data.py
+++ b/Tools/ssl/make_ssl_data.py
@@ -5,8 +5,7 @@
 `library` and `reason` mnemnonics to a more recent OpenSSL version.
 
 It takes two arguments:
-- the path to the OpenSSL include files' directory
-  (e.g. openssl-1.0.1-beta3/include/openssl/)
+- the path to the OpenSSL source tree (e.g. git checkout)
 - the path to the C file to be generated
   (probably Modules/_ssl_data.h)
 """
@@ -15,9 +14,10 @@
 import os
 import re
 import sys
+import _ssl
 
 
-def parse_error_codes(h_file, prefix):
+def parse_error_codes(h_file, prefix, libcode):
     pat = re.compile(r"#define\W+(%s([\w]+))\W+(\d+)\b" % re.escape(prefix))
     codes = []
     with open(h_file, "r", encoding="latin1") as f:
@@ -26,7 +26,8 @@ def parse_error_codes(h_file, prefix):
             if match:
                 code, name, num = match.groups()
                 num = int(num)
-                codes.append((code, name, num))
+                # e.g. ("SSL_R_BAD_DATA", ("ERR_LIB_SSL", "BAD_DATA", 390))
+                codes.append((code, (libcode, name, num)))
     return codes
 
 if __name__ == "__main__":
@@ -34,12 +35,32 @@ def parse_error_codes(h_file, prefix):
     outfile = sys.argv[2]
     use_stdout = outfile == '-'
     f = sys.stdout if use_stdout else open(outfile, "w")
-    error_libraries = (
-        # (library code, mnemonic, error prefix, header file)
-        ('ERR_LIB_PEM', 'PEM', 'PEM_R_', 'pem.h'),
-        ('ERR_LIB_SSL', 'SSL', 'SSL_R_', 'ssl.h'),
-        ('ERR_LIB_X509', 'X509', 'X509_R_', 'x509.h'),
-        )
+    error_libraries = {
+        # mnemonic -> (library code, error prefix, header file)
+        'PEM': ('ERR_LIB_PEM', 'PEM_R_', 'crypto/pem/pem.h'),
+        'SSL': ('ERR_LIB_SSL', 'SSL_R_', 'ssl/ssl.h'),
+        'X509': ('ERR_LIB_X509', 'X509_R_', 'crypto/x509/x509.h'),
+        }
+
+    # Read codes from libraries
+    new_codes = []
+    for libcode, prefix, h_file in sorted(error_libraries.values()):
+        new_codes += parse_error_codes(os.path.join(openssl_inc, h_file),
+                                       prefix, libcode)
+    new_code_nums = set((libcode, num)
+                        for (code, (libcode, name, num)) in new_codes)
+
+    # Merge with existing codes (in case some old codes disappeared).
+    codes = {}
+    for errname, (libnum, errnum) in _ssl.err_names_to_codes.items():
+        lib = error_libraries[_ssl.lib_codes_to_names[libnum]]
+        libcode = lib[0]              # e.g. ERR_LIB_PEM
+        errcode = lib[1] + errname    # e.g. SSL_R_BAD_SSL_SESSION_ID_LENGTH
+        # Only keep it if the numeric codes weren't reused
+        if (libcode, errnum) not in new_code_nums:
+            codes[errcode] = libcode, errname, errnum
+    codes.update(dict(new_codes))
+
     def w(l):
         f.write(l + "\n")
     w("/* File generated by Tools/ssl/make_ssl_data.py */")
@@ -47,21 +68,19 @@ def w(l):
     w("")
 
     w("static struct py_ssl_library_code library_codes[] = {")
-    for libcode, mnemo, _, _ in error_libraries:
+    for mnemo, (libcode, _, _) in sorted(error_libraries.items()):
         w('    {"%s", %s},' % (mnemo, libcode))
     w('    { NULL }')
     w('};')
     w("")
 
     w("static struct py_ssl_error_code error_codes[] = {")
-    for libcode, _, prefix, h_file in error_libraries:
-        codes = parse_error_codes(os.path.join(openssl_inc, h_file), prefix)
-        for code, name, num in sorted(codes):
-            w('  #ifdef %s' % (code))
-            w('    {"%s", %s, %s},' % (name, libcode, code))
-            w('  #else')
-            w('    {"%s", %s, %d},' % (name, libcode, num))
-            w('  #endif')
+    for errcode, (libcode, name, num) in sorted(codes.items()):
+        w('  #ifdef %s' % (errcode))
+        w('    {"%s", %s, %s},' % (name, libcode, errcode))
+        w('  #else')
+        w('    {"%s", %s, %d},' % (name, libcode, num))
+        w('  #endif')
     w('    { NULL }')
     w('};')
     if not use_stdout:
diff --git a/Tools/ssl/sslspeed.vcxproj b/Tools/ssl/sslspeed.vcxproj
new file mode 100644
index 000000000000..8ec410681efa
--- /dev/null
+++ b/Tools/ssl/sslspeed.vcxproj
@@ -0,0 +1,70 @@
+
+
+  
+    
+      Debug
+      Win32
+    
+    
+      Release
+      Win32
+    
+    
+      Debug
+      x64
+    
+    
+      Release
+      x64
+    
+  
+  
+  
+    {F068BCCF-C0D6-478D-A2C5-26BA3237C992}
+    sslspeed
+  
+  
+  
+  
+  
+  
+  
+    $(OutDir)
+    $(MSBuildProjectDirectory)\$(ArchName)\
+    $(MSBuildProjectDirectory)\$(ArchName)\obj\
+    Application
+    MultiByte
+  
+  
+  
+  
+  
+    
+    
+  
+  
+  
+    
+      _CONSOLE;%(PreprocessorDefinitions)
+      $(opensslIncDir);%(AdditionalIncludeDirectories)
+    
+    
+      ws2_32.lib;crypt32.lib;libeay$(PyDebugExt).lib;ssleay$(PyDebugExt).lib;%(AdditionalDependencies)
+      $(OriginalOutDir);%(AdditionalLibraryDirectories)
+      Console
+    
+  
+
+  
+    
+      {10615b24-73bf-4efa-93aa-236916321317}
+      false
+    
+    
+      {e5b04cc0-eb4c-42ab-b4dc-18ef95f864b0}
+      false
+    
+  
+
+  
+
\ No newline at end of file
diff --git a/Tools/ssl/test_multiple_versions.py b/Tools/ssl/test_multiple_versions.py
new file mode 100644
index 000000000000..dd57dcf18b82
--- /dev/null
+++ b/Tools/ssl/test_multiple_versions.py
@@ -0,0 +1,241 @@
+#./python
+"""Run Python tests with multiple installations of OpenSSL
+
+The script
+
+  (1) downloads OpenSSL tar bundle
+  (2) extracts it to ../openssl/src/openssl-VERSION/
+  (3) compiles OpenSSL
+  (4) installs OpenSSL into ../openssl/VERSION/
+  (5) forces a recompilation of Python modules using the
+      header and library files from ../openssl/VERSION/
+  (6) runs Python's test suite
+
+The script must be run with Python's build directory as current working
+directory:
+
+    ./python Tools/ssl/test_multiple_versions.py
+
+The script uses LD_RUN_PATH, LD_LIBRARY_PATH, CPPFLAGS and LDFLAGS to bend
+search paths for header files and shared libraries. It's known to work on
+Linux with GCC 4.x.
+
+(c) 2013 Christian Heimes 
+"""
+import logging
+import os
+import tarfile
+import shutil
+import subprocess
+import sys
+from urllib.request import urlopen
+
+log = logging.getLogger("multissl")
+
+OPENSSL_VERSIONS = [
+    "0.9.7m", "0.9.8i", "0.9.8l", "0.9.8m", "0.9.8y", "1.0.0k", "1.0.1e"
+]
+FULL_TESTS = [
+    "test_asyncio", "test_ftplib", "test_hashlib", "test_httplib",
+    "test_imaplib", "test_nntplib", "test_poplib", "test_smtplib",
+    "test_smtpnet", "test_urllib2_localnet", "test_venv"
+]
+MINIMAL_TESTS = ["test_ssl", "test_hashlib"]
+CADEFAULT = True
+HERE = os.path.abspath(os.getcwd())
+DEST_DIR = os.path.abspath(os.path.join(HERE, os.pardir, "openssl"))
+
+
+class BuildSSL:
+    url_template = "https://www.openssl.org/source/openssl-{}.tar.gz"
+
+    module_files = ["Modules/_ssl.c",
+                    "Modules/socketmodule.c",
+                    "Modules/_hashopenssl.c"]
+
+    def __init__(self, version, openssl_compile_args=(), destdir=DEST_DIR):
+        self._check_python_builddir()
+        self.version = version
+        self.openssl_compile_args = openssl_compile_args
+        # installation directory
+        self.install_dir = os.path.join(destdir, version)
+        # source file
+        self.src_file = os.path.join(destdir, "src",
+                                     "openssl-{}.tar.gz".format(version))
+        # build directory (removed after install)
+        self.build_dir = os.path.join(destdir, "src",
+                                      "openssl-{}".format(version))
+
+    @property
+    def openssl_cli(self):
+        """openssl CLI binary"""
+        return os.path.join(self.install_dir, "bin", "openssl")
+
+    @property
+    def openssl_version(self):
+        """output of 'bin/openssl version'"""
+        env = os.environ.copy()
+        env["LD_LIBRARY_PATH"] = self.lib_dir
+        cmd = [self.openssl_cli, "version"]
+        return self._subprocess_output(cmd, env=env)
+
+    @property
+    def pyssl_version(self):
+        """Value of ssl.OPENSSL_VERSION"""
+        env = os.environ.copy()
+        env["LD_LIBRARY_PATH"] = self.lib_dir
+        cmd = ["./python", "-c", "import ssl; print(ssl.OPENSSL_VERSION)"]
+        return self._subprocess_output(cmd, env=env)
+
+    @property
+    def include_dir(self):
+        return os.path.join(self.install_dir, "include")
+
+    @property
+    def lib_dir(self):
+        return os.path.join(self.install_dir, "lib")
+
+    @property
+    def has_openssl(self):
+        return os.path.isfile(self.openssl_cli)
+
+    @property
+    def has_src(self):
+        return os.path.isfile(self.src_file)
+
+    def _subprocess_call(self, cmd, stdout=subprocess.DEVNULL, env=None,
+                         **kwargs):
+        log.debug("Call '{}'".format(" ".join(cmd)))
+        return subprocess.check_call(cmd, stdout=stdout, env=env, **kwargs)
+
+    def _subprocess_output(self, cmd, env=None, **kwargs):
+        log.debug("Call '{}'".format(" ".join(cmd)))
+        out = subprocess.check_output(cmd, env=env)
+        return out.strip().decode("utf-8")
+
+    def _check_python_builddir(self):
+        if not os.path.isfile("python") or not os.path.isfile("setup.py"):
+            raise ValueError("Script must be run in Python build directory")
+
+    def _download_openssl(self):
+        """Download OpenSSL source dist"""
+        src_dir = os.path.dirname(self.src_file)
+        if not os.path.isdir(src_dir):
+            os.makedirs(src_dir)
+        url = self.url_template.format(self.version)
+        log.info("Downloading OpenSSL from {}".format(url))
+        req = urlopen(url, cadefault=CADEFAULT)
+        # KISS, read all, write all
+        data = req.read()
+        log.info("Storing {}".format(self.src_file))
+        with open(self.src_file, "wb") as f:
+            f.write(data)
+
+    def _unpack_openssl(self):
+        """Unpack tar.gz bundle"""
+        # cleanup
+        if os.path.isdir(self.build_dir):
+            shutil.rmtree(self.build_dir)
+        os.makedirs(self.build_dir)
+
+        tf = tarfile.open(self.src_file)
+        base = "openssl-{}/".format(self.version)
+        # force extraction into build dir
+        members = tf.getmembers()
+        for member in members:
+            if not member.name.startswith(base):
+                raise ValueError(member.name)
+            member.name = member.name[len(base):]
+        log.info("Unpacking files to {}".format(self.build_dir))
+        tf.extractall(self.build_dir, members)
+
+    def _build_openssl(self):
+        """Now build openssl"""
+        log.info("Running build in {}".format(self.install_dir))
+        cwd = self.build_dir
+        cmd = ["./config", "shared", "--prefix={}".format(self.install_dir)]
+        cmd.extend(self.openssl_compile_args)
+        self._subprocess_call(cmd, cwd=cwd)
+        self._subprocess_call(["make"], cwd=cwd)
+
+    def _install_openssl(self, remove=True):
+        self._subprocess_call(["make", "install"], cwd=self.build_dir)
+        if remove:
+            shutil.rmtree(self.build_dir)
+
+    def install_openssl(self):
+        if not self.has_openssl:
+            if not self.has_src:
+                self._download_openssl()
+            else:
+                log.debug("Already has src {}".format(self.src_file))
+            self._unpack_openssl()
+            self._build_openssl()
+            self._install_openssl()
+        else:
+            log.info("Already has installation {}".format(self.install_dir))
+        # validate installation
+        version = self.openssl_version
+        if self.version not in version:
+            raise ValueError(version)
+
+    def touch_pymods(self):
+        # force a rebuild of all modules that use OpenSSL APIs
+        for fname in self.module_files:
+            os.utime(fname)
+
+    def recompile_pymods(self):
+        log.info("Using OpenSSL build from {}".format(self.build_dir))
+        # overwrite header and library search paths
+        env = os.environ.copy()
+        env["CPPFLAGS"] = "-I{}".format(self.include_dir)
+        env["LDFLAGS"] = "-L{}".format(self.lib_dir)
+        # set rpath
+        env["LD_RUN_PATH"] = self.lib_dir
+
+        log.info("Rebuilding Python modules")
+        self.touch_pymods()
+        cmd = ["./python", "setup.py", "build"]
+        self._subprocess_call(cmd, env=env)
+
+    def check_pyssl(self):
+        version = self.pyssl_version
+        if self.version not in version:
+            raise ValueError(version)
+
+    def run_pytests(self, *args):
+        cmd = ["./python", "-m", "test"]
+        cmd.extend(args)
+        self._subprocess_call(cmd, stdout=None)
+
+    def run_python_tests(self, *args):
+        self.recompile_pymods()
+        self.check_pyssl()
+        self.run_pytests(*args)
+
+
+def main(*args):
+    builders = []
+    for version in OPENSSL_VERSIONS:
+        if version in ("0.9.8i", "0.9.8l"):
+            openssl_compile_args = ("no-asm",)
+        else:
+            openssl_compile_args = ()
+        builder = BuildSSL(version, openssl_compile_args)
+        builder.install_openssl()
+        builders.append(builder)
+
+    for builder in builders:
+        builder.run_python_tests(*args)
+    # final touch
+    builder.touch_pymods()
+
+
+if __name__ == "__main__":
+    logging.basicConfig(level=logging.INFO,
+                        format="*** %(levelname)s %(message)s")
+    args = sys.argv[1:]
+    if not args:
+        args = ["-unetwork", "-v"]
+        args.extend(FULL_TESTS)
+    main(*args)
diff --git a/Tools/stringbench/stringbench.py b/Tools/stringbench/stringbench.py
old mode 100755
new mode 100644
diff --git a/Tools/unicode/comparecodecs.py b/Tools/unicode/comparecodecs.py
old mode 100644
new mode 100755
diff --git a/Tools/unicode/gencodec.py b/Tools/unicode/gencodec.py
index f4c7c038c41a..98b39758f9d9 100644
--- a/Tools/unicode/gencodec.py
+++ b/Tools/unicode/gencodec.py
@@ -34,7 +34,7 @@
 # Standard undefined Unicode code point
 UNI_UNDEFINED = chr(0xFFFE)
 
-# Placeholder for a missing codepoint
+# Placeholder for a missing code point
 MISSING_CODE = -1
 
 mapRE = re.compile('((?:0x[0-9a-fA-F]+\+?)+)'
diff --git a/Tools/unicode/makeunicodedata.py b/Tools/unicode/makeunicodedata.py
index 0942508dff1c..b7d31e880665 100644
--- a/Tools/unicode/makeunicodedata.py
+++ b/Tools/unicode/makeunicodedata.py
@@ -37,7 +37,12 @@
 VERSION = "3.2"
 
 # The Unicode Database
-UNIDATA_VERSION = "6.3.0"
+# --------------------
+# When changing UCD version please update
+#   * Doc/library/stdtypes.rst, and
+#   * Doc/library/unicodedata.rst
+#   * Doc/reference/lexical_analysis.rst (two occurrences)
+UNIDATA_VERSION = "7.0.0"
 UNICODE_DATA = "UnicodeData%s.txt"
 COMPOSITION_EXCLUSIONS = "CompositionExclusions%s.txt"
 EASTASIAN_WIDTH = "EastAsianWidth%s.txt"
diff --git a/Tools/unittestgui/unittestgui.py b/Tools/unittestgui/unittestgui.py
old mode 100644
new mode 100755
index 09a20e28e78e..c3b5fa458420
--- a/Tools/unittestgui/unittestgui.py
+++ b/Tools/unittestgui/unittestgui.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 """
 GUI framework and application for use with Python unit testing framework.
 Execute tests written using the framework provided by the 'unittest' module.
diff --git a/config.guess b/config.guess
index b79252d6b103..1f5c50c0d152 100755
--- a/config.guess
+++ b/config.guess
@@ -1,8 +1,8 @@
 #! /bin/sh
 # Attempt to guess a canonical system name.
-#   Copyright 1992-2013 Free Software Foundation, Inc.
+#   Copyright 1992-2014 Free Software Foundation, Inc.
 
-timestamp='2013-06-10'
+timestamp='2014-03-23'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -50,7 +50,7 @@ version="\
 GNU config.guess ($timestamp)
 
 Originally written by Per Bothner.
-Copyright 1992-2013 Free Software Foundation, Inc.
+Copyright 1992-2014 Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -149,7 +149,7 @@ Linux|GNU|GNU/*)
 	LIBC=gnu
 	#endif
 	EOF
-	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
 	;;
 esac
 
@@ -826,7 +826,7 @@ EOF
     *:MINGW*:*)
 	echo ${UNAME_MACHINE}-pc-mingw32
 	exit ;;
-    i*:MSYS*:*)
+    *:MSYS*:*)
 	echo ${UNAME_MACHINE}-pc-msys
 	exit ;;
     i*:windows32*:*)
@@ -969,10 +969,10 @@ EOF
 	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
 	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
 	;;
-    or1k:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+    openrisc*:Linux:*:*)
+	echo or1k-unknown-linux-${LIBC}
 	exit ;;
-    or32:Linux:*:*)
+    or32:Linux:*:* | or1k*:Linux:*:*)
 	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
 	exit ;;
     padre:Linux:*:*)
@@ -1260,16 +1260,26 @@ EOF
 	if test "$UNAME_PROCESSOR" = unknown ; then
 	    UNAME_PROCESSOR=powerpc
 	fi
-	if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
-	    if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
-		(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
-		grep IS_64BIT_ARCH >/dev/null
-	    then
-		case $UNAME_PROCESSOR in
-		    i386) UNAME_PROCESSOR=x86_64 ;;
-		    powerpc) UNAME_PROCESSOR=powerpc64 ;;
-		esac
+	if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
+	    if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+		if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+		    (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+		    grep IS_64BIT_ARCH >/dev/null
+		then
+		    case $UNAME_PROCESSOR in
+			i386) UNAME_PROCESSOR=x86_64 ;;
+			powerpc) UNAME_PROCESSOR=powerpc64 ;;
+		    esac
+		fi
 	    fi
+	elif test "$UNAME_PROCESSOR" = i386 ; then
+	    # Avoid executing cc on OS X 10.9, as it ships with a stub
+	    # that puts up a graphical alert prompting to install
+	    # developer tools.  Any system running Mac OS X 10.7 or
+	    # later (Darwin 11 and later) is required to have a 64-bit
+	    # processor. This is not true of the ARM version of Darwin
+	    # that Apple uses in portable devices.
+	    UNAME_PROCESSOR=x86_64
 	fi
 	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
 	exit ;;
@@ -1361,154 +1371,6 @@ EOF
 	exit ;;
 esac
 
-eval $set_cc_for_build
-cat >$dummy.c <
-# include 
-#endif
-main ()
-{
-#if defined (sony)
-#if defined (MIPSEB)
-  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
-     I don't know....  */
-  printf ("mips-sony-bsd\n"); exit (0);
-#else
-#include 
-  printf ("m68k-sony-newsos%s\n",
-#ifdef NEWSOS4
-	"4"
-#else
-	""
-#endif
-	); exit (0);
-#endif
-#endif
-
-#if defined (__arm) && defined (__acorn) && defined (__unix)
-  printf ("arm-acorn-riscix\n"); exit (0);
-#endif
-
-#if defined (hp300) && !defined (hpux)
-  printf ("m68k-hp-bsd\n"); exit (0);
-#endif
-
-#if defined (NeXT)
-#if !defined (__ARCHITECTURE__)
-#define __ARCHITECTURE__ "m68k"
-#endif
-  int version;
-  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
-  if (version < 4)
-    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
-  else
-    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
-  exit (0);
-#endif
-
-#if defined (MULTIMAX) || defined (n16)
-#if defined (UMAXV)
-  printf ("ns32k-encore-sysv\n"); exit (0);
-#else
-#if defined (CMU)
-  printf ("ns32k-encore-mach\n"); exit (0);
-#else
-  printf ("ns32k-encore-bsd\n"); exit (0);
-#endif
-#endif
-#endif
-
-#if defined (__386BSD__)
-  printf ("i386-pc-bsd\n"); exit (0);
-#endif
-
-#if defined (sequent)
-#if defined (i386)
-  printf ("i386-sequent-dynix\n"); exit (0);
-#endif
-#if defined (ns32000)
-  printf ("ns32k-sequent-dynix\n"); exit (0);
-#endif
-#endif
-
-#if defined (_SEQUENT_)
-    struct utsname un;
-
-    uname(&un);
-
-    if (strncmp(un.version, "V2", 2) == 0) {
-	printf ("i386-sequent-ptx2\n"); exit (0);
-    }
-    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
-	printf ("i386-sequent-ptx1\n"); exit (0);
-    }
-    printf ("i386-sequent-ptx\n"); exit (0);
-
-#endif
-
-#if defined (vax)
-# if !defined (ultrix)
-#  include 
-#  if defined (BSD)
-#   if BSD == 43
-      printf ("vax-dec-bsd4.3\n"); exit (0);
-#   else
-#    if BSD == 199006
-      printf ("vax-dec-bsd4.3reno\n"); exit (0);
-#    else
-      printf ("vax-dec-bsd\n"); exit (0);
-#    endif
-#   endif
-#  else
-    printf ("vax-dec-bsd\n"); exit (0);
-#  endif
-# else
-    printf ("vax-dec-ultrix\n"); exit (0);
-# endif
-#endif
-
-#if defined (alliant) && defined (i860)
-  printf ("i860-alliant-bsd\n"); exit (0);
-#endif
-
-  exit (1);
-}
-EOF
-
-$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
-	{ echo "$SYSTEM_NAME"; exit; }
-
-# Apollos put the system type in the environment.
-
-test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
-
-# Convex versions that predate uname can use getsysinfo(1)
-
-if [ -x /usr/convex/getsysinfo ]
-then
-    case `getsysinfo -f cpu_type` in
-    c1*)
-	echo c1-convex-bsd
-	exit ;;
-    c2*)
-	if getsysinfo -f scalar_acc
-	then echo c32-convex-bsd
-	else echo c2-convex-bsd
-	fi
-	exit ;;
-    c34*)
-	echo c34-convex-bsd
-	exit ;;
-    c38*)
-	echo c38-convex-bsd
-	exit ;;
-    c4*)
-	echo c4-convex-bsd
-	exit ;;
-    esac
-fi
-
 cat >&2 <."
 version="\
 GNU config.sub ($timestamp)
 
-Copyright 1992-2013 Free Software Foundation, Inc.
+Copyright 1992-2014 Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -265,6 +265,7 @@ case $basic_machine in
 	| hexagon \
 	| i370 | i860 | i960 | ia64 \
 	| ip2k | iq2000 \
+	| k1om \
 	| le32 | le64 \
 	| lm32 \
 	| m32c | m32r | m32rle | m68000 | m68k | m88k \
@@ -282,8 +283,10 @@ case $basic_machine in
 	| mips64vr5900 | mips64vr5900el \
 	| mipsisa32 | mipsisa32el \
 	| mipsisa32r2 | mipsisa32r2el \
+	| mipsisa32r6 | mipsisa32r6el \
 	| mipsisa64 | mipsisa64el \
 	| mipsisa64r2 | mipsisa64r2el \
+	| mipsisa64r6 | mipsisa64r6el \
 	| mipsisa64sb1 | mipsisa64sb1el \
 	| mipsisa64sr71k | mipsisa64sr71kel \
 	| mipsr5900 | mipsr5900el \
@@ -295,8 +298,7 @@ case $basic_machine in
 	| nds32 | nds32le | nds32be \
 	| nios | nios2 | nios2eb | nios2el \
 	| ns16k | ns32k \
-	| open8 \
-	| or1k | or32 \
+	| open8 | or1k | or1knd | or32 \
 	| pdp10 | pdp11 | pj | pjl \
 	| powerpc | powerpc64 | powerpc64le | powerpcle \
 	| pyramid \
@@ -324,7 +326,7 @@ case $basic_machine in
 	c6x)
 		basic_machine=tic6x-unknown
 		;;
-	m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)
+	m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
 		basic_machine=$basic_machine-unknown
 		os=-none
 		;;
@@ -381,6 +383,7 @@ case $basic_machine in
 	| hexagon-* \
 	| i*86-* | i860-* | i960-* | ia64-* \
 	| ip2k-* | iq2000-* \
+	| k1om-* \
 	| le32-* | le64-* \
 	| lm32-* \
 	| m32c-* | m32r-* | m32rle-* \
@@ -400,8 +403,10 @@ case $basic_machine in
 	| mips64vr5900-* | mips64vr5900el-* \
 	| mipsisa32-* | mipsisa32el-* \
 	| mipsisa32r2-* | mipsisa32r2el-* \
+	| mipsisa32r6-* | mipsisa32r6el-* \
 	| mipsisa64-* | mipsisa64el-* \
 	| mipsisa64r2-* | mipsisa64r2el-* \
+	| mipsisa64r6-* | mipsisa64r6el-* \
 	| mipsisa64sb1-* | mipsisa64sb1el-* \
 	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
 	| mipsr5900-* | mipsr5900el-* \
@@ -413,6 +418,7 @@ case $basic_machine in
 	| nios-* | nios2-* | nios2eb-* | nios2el-* \
 	| none-* | np1-* | ns16k-* | ns32k-* \
 	| open8-* \
+	| or1k*-* \
 	| orion-* \
 	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
 	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
@@ -1374,7 +1380,7 @@ case $os in
 	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
 	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
 	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
-	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
+	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*)
 	# Remember, each alternative MUST END IN *, to match a version number.
 		;;
 	-qnx*)
@@ -1592,9 +1598,6 @@ case $basic_machine in
 	mips*-*)
 		os=-elf
 		;;
-	or1k-*)
-		os=-elf
-		;;
 	or32-*)
 		os=-coff
 		;;
diff --git a/configure b/configure
index 5d666ed93eb4..35a31bb991d8 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for python 3.4.
+# Generated by GNU Autoconf 2.69 for python 3.5.
 #
 # Report bugs to .
 #
@@ -580,8 +580,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='python'
 PACKAGE_TARNAME='python'
-PACKAGE_VERSION='3.4'
-PACKAGE_STRING='python 3.4'
+PACKAGE_VERSION='3.5'
+PACKAGE_STRING='python 3.5'
 PACKAGE_BUGREPORT='http://bugs.python.org/'
 PACKAGE_URL=''
 
@@ -650,6 +650,8 @@ USE_SIGNAL_MODULE
 TCLTK_LIBS
 TCLTK_INCLUDES
 LIBFFI_INCLUDEDIR
+PKG_CONFIG_LIBDIR
+PKG_CONFIG_PATH
 PKG_CONFIG
 SHLIBS
 CFLAGSFORSHARED
@@ -662,6 +664,7 @@ SHLIB_SUFFIX
 LIBTOOL_CRUFT
 OTHER_LIBTOOL_OPT
 UNIVERSAL_ARCH_FLAGS
+CFLAGS_NODIST
 BASECFLAGS
 OPT
 ABIFLAGS
@@ -670,6 +673,7 @@ MKDIR_P
 INSTALL_DATA
 INSTALL_SCRIPT
 INSTALL_PROGRAM
+OPCODEHGEN
 PYTHON
 ASDLGEN
 ac_ct_READELF
@@ -795,6 +799,7 @@ enable_shared
 enable_profiling
 with_pydebug
 with_hash_algorithm
+with_address_sanitizer
 with_libs
 with_system_expat
 with_system_ffi
@@ -827,7 +832,10 @@ CFLAGS
 LDFLAGS
 LIBS
 CPPFLAGS
-CPP'
+CPP
+PKG_CONFIG
+PKG_CONFIG_PATH
+PKG_CONFIG_LIBDIR'
 
 
 # Initialize some variables set by options.
@@ -1368,7 +1376,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures python 3.4 to adapt to many kinds of systems.
+\`configure' configures python 3.5 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1433,7 +1441,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of python 3.4:";;
+     short | recursive ) echo "Configuration of python 3.5:";;
    esac
   cat <<\_ACEOF
 
@@ -1471,6 +1479,8 @@ Optional Packages:
   --with-pydebug          build with Py_DEBUG defined
   --with-hash-algorithm=[fnv|siphash24]
                           select hash algorithm
+  --with-address-sanitizer
+                          enable AddressSanitizer
   --with-libs='lib1 ...'  link against additional libs
   --with-system-expat     build pyexpat module using an installed expat
                           library
@@ -1513,6 +1523,11 @@ Some influential environment variables:
   CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I if
               you have headers in a nonstandard directory 
   CPP         C preprocessor
+  PKG_CONFIG  path to pkg-config utility
+  PKG_CONFIG_PATH
+              directories to add to pkg-config's search path
+  PKG_CONFIG_LIBDIR
+              path overriding pkg-config's built-in search path
 
 Use these variables to override the choices made by `configure' or to help
 it to find libraries and programs with nonstandard names/locations.
@@ -1580,7 +1595,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-python configure 3.4
+python configure 3.5
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2419,7 +2434,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by python $as_me 3.4, which was
+It was created by python $as_me 3.5, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2949,6 +2964,9 @@ case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
 
 
 
+# pybuilddir.txt will be created by --generate-posix-vars in the Makefile
+rm -f pybuilddir.txt
+
 if test "$cross_compiling" = yes; then
     { $as_echo "$as_me:${as_lineno-$LINENO}: checking for python interpreter for cross build" >&5
 $as_echo_n "checking for python interpreter for cross build... " >&6; }
@@ -2989,7 +3007,7 @@ rm confdefs.h
 mv confdefs.h.new confdefs.h
 
 
-VERSION=3.4
+VERSION=3.5
 
 # Version number of Python's own shared library file.
 
@@ -3445,6 +3463,21 @@ $as_echo "#define _POSIX_C_SOURCE 200809L" >>confdefs.h
 
 fi
 
+# On HP-UX mbstate_t requires _INCLUDE__STDC_A1_SOURCE
+case $ac_sys_system in
+  hp*|HP*)
+    define_stdc_a1=yes;;
+  *)
+    define_stdc_a1=no;;
+esac
+
+if test $define_stdc_a1 = yes
+then
+
+$as_echo "#define _INCLUDE__STDC_A1_SOURCE 1" >>confdefs.h
+
+fi
+
 #
 # SGI compilers allow the specification of the both the ABI and the
 # ISA on the command line.  Depending on the values of these switches,
@@ -5590,7 +5623,7 @@ $as_echo_n "checking LDLIBRARY... " >&6; }
 if test "$enable_framework"
 then
   LDLIBRARY='$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)'
-  RUNSHARED=DYLD_FRAMEWORK_PATH="`pwd`:$DYLD_FRAMEWORK_PATH"
+  RUNSHARED=DYLD_FRAMEWORK_PATH=`pwd`${DYLD_FRAMEWORK_PATH:+:${DYLD_FRAMEWORK_PATH}}
   BLDLIBRARY=''
 else
   BLDLIBRARY='$(LDLIBRARY)'
@@ -5610,7 +5643,7 @@ $as_echo "#define Py_ENABLE_SHARED 1" >>confdefs.h
     SunOS*)
 	  LDLIBRARY='libpython$(LDVERSION).so'
 	  BLDLIBRARY='-Wl,-R,$(LIBDIR) -L. -lpython$(LDVERSION)'
-	  RUNSHARED=LD_LIBRARY_PATH=`pwd`:${LD_LIBRARY_PATH}
+	  RUNSHARED=LD_LIBRARY_PATH=`pwd`${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}
 	  INSTSONAME="$LDLIBRARY".$SOVERSION
 	  if test "$with_pydebug" != yes
 	  then
@@ -5620,7 +5653,7 @@ $as_echo "#define Py_ENABLE_SHARED 1" >>confdefs.h
     Linux*|GNU*|NetBSD*|FreeBSD*|DragonFly*|OpenBSD*)
 	  LDLIBRARY='libpython$(LDVERSION).so'
 	  BLDLIBRARY='-L. -lpython$(LDVERSION)'
-	  RUNSHARED=LD_LIBRARY_PATH=`pwd`:${LD_LIBRARY_PATH}
+	  RUNSHARED=LD_LIBRARY_PATH=`pwd`${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}
 	  case $ac_sys_system in
 	      FreeBSD*)
 		SOVERSION=`echo $SOVERSION|cut -d "." -f 1`
@@ -5642,16 +5675,16 @@ $as_echo "#define Py_ENABLE_SHARED 1" >>confdefs.h
 			;;
 	  esac
 	  BLDLIBRARY='-Wl,+b,$(LIBDIR) -L. -lpython$(LDVERSION)'
-	  RUNSHARED=SHLIB_PATH=`pwd`:${SHLIB_PATH}
+	  RUNSHARED=SHLIB_PATH=`pwd`${SHLIB_PATH:+:${SHLIB_PATH}}
 	  ;;
     Darwin*)
     	LDLIBRARY='libpython$(LDVERSION).dylib'
 	BLDLIBRARY='-L. -lpython$(LDVERSION)'
-	RUNSHARED='DYLD_LIBRARY_PATH=`pwd`:${DYLD_LIBRARY_PATH}'
+	RUNSHARED=DYLD_LIBRARY_PATH=`pwd`${DYLD_LIBRARY_PATH:+:${DYLD_LIBRARY_PATH}}
 	;;
     AIX*)
 	LDLIBRARY='libpython$(LDVERSION).so'
-	RUNSHARED=LIBPATH=`pwd`:${LIBPATH}
+	RUNSHARED=LIBPATH=`pwd`${LIBPATH:+:${LIBPATH}}
 	;;
 
   esac
@@ -6033,6 +6066,57 @@ else
 fi
 
 
+for ac_prog in python$PACKAGE_VERSION python3 python
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; 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_PYTHON+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$PYTHON"; then
+  ac_cv_prog_PYTHON="$PYTHON" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_PYTHON="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+PYTHON=$ac_cv_prog_PYTHON
+if test -n "$PYTHON"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON" >&5
+$as_echo "$PYTHON" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$PYTHON" && break
+done
+test -n "$PYTHON" || PYTHON="not-found"
+
+if test "$PYTHON" = not-found; then
+    OPCODEHGEN="@echo python: $PYTHON! cannot run Tools/scripts/generate_opcode_h.py"
+else
+    OPCODEHGEN="$PYTHON"
+fi
+
+
+
 case $MACHDEP in
 bsdos*|hp*|HP*)
 	# install -d does not work on BSDI or HP-UX
@@ -6254,7 +6338,11 @@ then
 	    if test "$Py_DEBUG" = 'true' ; then
 		# Optimization messes up debuggers, so turn it off for
 		# debug builds.
-		OPT="-g -O0 -Wall $STRICT_PROTO"
+                if "$CC" -v --help 2>/dev/null |grep -- -Og > /dev/null; then
+                    OPT="-g -Og -Wall $STRICT_PROTO"
+                else
+                    OPT="-g -O0 -Wall $STRICT_PROTO"
+                fi
 	    else
 		OPT="-g $WRAP -O3 -Wall $STRICT_PROTO"
 	    fi
@@ -6277,6 +6365,7 @@ fi
 
 
 
+
 # The -arch flags for universal builds on OSX
 UNIVERSAL_ARCH_FLAGS=
 
@@ -6437,7 +6526,95 @@ $as_echo "$ac_cv_declaration_after_statement_warning" >&6; }
 
     if test $ac_cv_declaration_after_statement_warning = yes
     then
-      BASECFLAGS="$BASECFLAGS -Werror=declaration-after-statement"
+      CFLAGS_NODIST="$CFLAGS_NODIST -Werror=declaration-after-statement"
+    fi
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can turn on $CC mixed sign comparison warning" >&5
+$as_echo_n "checking if we can turn on $CC mixed sign comparison warning... " >&6; }
+     ac_save_cc="$CC"
+     CC="$CC -Wsign-compare"
+     save_CFLAGS="$CFLAGS"
+     if ${ac_cv_enable_sign_compare_warning+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+           ac_cv_enable_sign_compare_warning=yes
+
+else
+
+           ac_cv_enable_sign_compare_warning=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+     CFLAGS="$save_CFLAGS"
+     CC="$ac_save_cc"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_enable_sign_compare_warning" >&5
+$as_echo "$ac_cv_enable_sign_compare_warning" >&6; }
+
+    if test $ac_cv_enable_sign_compare_warning = yes
+    then
+      BASECFLAGS="$BASECFLAGS -Wsign-compare"
+    fi
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can turn on $CC unreachable code warning" >&5
+$as_echo_n "checking if we can turn on $CC unreachable code warning... " >&6; }
+     ac_save_cc="$CC"
+     CC="$CC -Wunreachable-code"
+     save_CFLAGS="$CFLAGS"
+     if ${ac_cv_enable_unreachable_code_warning+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+           ac_cv_enable_unreachable_code_warning=yes
+
+else
+
+           ac_cv_enable_unreachable_code_warning=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+     CFLAGS="$save_CFLAGS"
+     CC="$ac_save_cc"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_enable_unreachable_code_warning" >&5
+$as_echo "$ac_cv_enable_unreachable_code_warning" >&6; }
+
+    # Don't enable unreachable code warning in debug mode, since it usually
+    # results in non-standard code paths.
+    if test $ac_cv_enable_unreachable_code_warning = yes && test "$Py_DEBUG" != "true"
+    then
+      BASECFLAGS="$BASECFLAGS -Wunreachable-code"
     fi
 
     # if using gcc on alpha, use -mieee to get (near) full IEEE 754
@@ -6536,10 +6713,16 @@ $as_echo "$CC" >&6; }
 
         { $as_echo "$as_me:${as_lineno-$LINENO}: checking which MACOSX_DEPLOYMENT_TARGET to use" >&5
 $as_echo_n "checking which MACOSX_DEPLOYMENT_TARGET to use... " >&6; }
-        cur_target=`sw_vers -productVersion | sed 's/\(10\.[0-9]*\).*/\1/'`
-        if test ${cur_target} '>' 10.2 && \
-           test ${cur_target} '<' 10.6
+        cur_target_major=`sw_vers -productVersion | \
+                sed 's/\([0-9]*\)\.\([0-9]*\).*/\1/'`
+        cur_target_minor=`sw_vers -productVersion | \
+                sed 's/\([0-9]*\)\.\([0-9]*\).*/\2/'`
+        cur_target="${cur_target_major}.${cur_target_minor}"
+        if test ${cur_target_major} -eq 10 && \
+           test ${cur_target_minor} -ge 3 && \
+           test ${cur_target_minor} -le 5
         then
+            # OS X 10.3 through 10.5
             cur_target=10.3
             if test ${enable_universalsdk}
             then
@@ -6954,11 +7137,9 @@ $as_echo "#define STDC_HEADERS 1" >>confdefs.h
 
 fi
 
-ac_save_cppflags="$CPPFLAGS"
-CPPFLAGS="$CPPFLAGS -I/usr/include/ncursesw"
-for ac_header in asm/types.h conio.h curses.h direct.h dlfcn.h errno.h \
+for ac_header in asm/types.h conio.h direct.h dlfcn.h errno.h \
 fcntl.h grp.h \
-ieeefp.h io.h langinfo.h libintl.h ncurses.h process.h pthread.h \
+ieeefp.h io.h langinfo.h libintl.h process.h pthread.h \
 sched.h shadow.h signal.h stdint.h stropts.h termios.h \
 unistd.h utime.h \
 poll.h sys/devpoll.h sys/epoll.h sys/poll.h \
@@ -6982,7 +7163,6 @@ fi
 
 done
 
-CPPFLAGS=$ac_save_cppflags
 ac_header_dirent=no
 for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do
   as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh`
@@ -7219,26 +7399,6 @@ fi
 done
 
 
-
-# On Solaris, term.h requires curses.h
-for ac_header in term.h
-do :
-  ac_fn_c_check_header_compile "$LINENO" "term.h" "ac_cv_header_term_h" "
-#ifdef HAVE_CURSES_H
-#include 
-#endif
-
-"
-if test "x$ac_cv_header_term_h" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_TERM_H 1
-_ACEOF
-
-fi
-
-done
-
-
 # On Linux, netlink.h requires asm/types.h
 for ac_header in linux/netlink.h
 do :
@@ -8548,12 +8708,14 @@ then
 		# Use -undefined dynamic_lookup whenever possible (10.3 and later).
 		# This allows an extension to be used in any Python
 
-		if test ${MACOSX_DEPLOYMENT_TARGET} '>' 10.2
+		dep_target_major=`echo ${MACOSX_DEPLOYMENT_TARGET} | \
+				sed 's/\([0-9]*\)\.\([0-9]*\).*/\1/'`
+		dep_target_minor=`echo ${MACOSX_DEPLOYMENT_TARGET} | \
+				sed 's/\([0-9]*\)\.\([0-9]*\).*/\2/'`
+		if test ${dep_target_major} -eq 10 && \
+		   test ${dep_target_minor} -le 2
 		then
-			LDSHARED='$(CC) -bundle -undefined dynamic_lookup'
-			LDCXXSHARED='$(CXX) -bundle -undefined dynamic_lookup'
-			BLDSHARED="$LDSHARED"
-		else
+			# building for OS X 10.0 through 10.2
 			LDSHARED='$(CC) -bundle'
 			LDCXXSHARED='$(CXX) -bundle'
 			if test "$enable_framework" ; then
@@ -8567,6 +8729,11 @@ then
 				LDSHARED="$LDSHARED "'-bundle_loader $(BINDIR)/python$(VERSION)$(EXE)'
 				LDCXXSHARED="$LDCXXSHARED "'-bundle_loader $(BINDIR)/python$(VERSION)$(EXE)'
 			fi
+		else
+			# building for OS X 10.3 and later
+			LDSHARED='$(CC) -bundle -undefined dynamic_lookup'
+			LDCXXSHARED='$(CXX) -bundle -undefined dynamic_lookup'
+			BLDSHARED="$LDSHARED"
 		fi
 		;;
 	Linux*|GNU*|QNX*)
@@ -8893,6 +9060,48 @@ _ACEOF
 
 fi
 	# Dynamic linking for HP-UX
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for RAND_egd in -lcrypto" >&5
+$as_echo_n "checking for RAND_egd in -lcrypto... " >&6; }
+if ${ac_cv_lib_crypto_RAND_egd+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcrypto  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char RAND_egd ();
+int
+main ()
+{
+return RAND_egd ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_crypto_RAND_egd=yes
+else
+  ac_cv_lib_crypto_RAND_egd=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_RAND_egd" >&5
+$as_echo "$ac_cv_lib_crypto_RAND_egd" >&6; }
+if test "x$ac_cv_lib_crypto_RAND_egd" = xyes; then :
+
+$as_echo "#define HAVE_RAND_EGD 1" >>confdefs.h
+
+fi
+
 
 # only check for sem_init if thread support is requested
 if test "$with_threads" = "yes" -o -z "$with_threads"; then
@@ -9110,6 +9319,23 @@ $as_echo "default" >&6; }
 fi
 
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-address-sanitizer" >&5
+$as_echo_n "checking for --with-address-sanitizer... " >&6; }
+
+# Check whether --with-address_sanitizer was given.
+if test "${with_address_sanitizer+set}" = set; then :
+  withval=$with_address_sanitizer;
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $withval" >&5
+$as_echo "$withval" >&6; }
+BASECFLAGS="-fsanitize=address -fno-omit-frame-pointer $BASECFLAGS"
+LDFLAGS="-fsanitize=address $LDFLAGS"
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
 # Most SVR4 platforms (e.g. Solaris) need -lsocket and -lnsl.
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for t_open in -lnsl" >&5
 $as_echo_n "checking for t_open in -lnsl... " >&6; }
@@ -9208,7 +9434,15 @@ $as_echo "no" >&6; }
 fi
 
 
-if test -n "$ac_tool_prefix"; then
+
+
+
+
+
+
+
+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+	if test -n "$ac_tool_prefix"; then
   # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
 set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
@@ -9306,6 +9540,20 @@ else
   PKG_CONFIG="$ac_cv_path_PKG_CONFIG"
 fi
 
+fi
+if test -n "$PKG_CONFIG"; then
+	_pkg_min_version=0.9.0
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5
+$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; }
+	if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+		{ $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; }
+		PKG_CONFIG=""
+	fi
+fi
 
 # Check for use of the system expat library
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-system-expat" >&5
@@ -10453,7 +10701,7 @@ fi
 for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
  clock confstr ctermid dup3 execv faccessat fchmod fchmodat fchown fchownat \
  fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
- futimens futimes gai_strerror \
+ futimens futimes gai_strerror getentropy \
  getgrouplist getgroups getlogin getloadavg getpeername getpgid getpid \
  getpriority getresuid getresgid getpwent getspnam getspent getsid getwd \
  if_nameindex \
@@ -11734,6 +11982,7 @@ fi
 $as_echo "$ac_cv_lib_rt_clock_gettime" >&6; }
 if test "x$ac_cv_lib_rt_clock_gettime" = xyes; then :
 
+        LIBS="$LIBS -lrt"
         $as_echo "#define HAVE_CLOCK_GETTIME 1" >>confdefs.h
 
 
@@ -13177,6 +13426,38 @@ $as_echo "#define HAVE_GCC_ASM_FOR_X87 1" >>confdefs.h
 
 fi
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we can use gcc inline assembler to get and set mc68881 fpcr" >&5
+$as_echo_n "checking whether we can use gcc inline assembler to get and set mc68881 fpcr... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  unsigned int fpcr;
+  __asm__ __volatile__ ("fmove.l %%fpcr,%0" : "=g" (fpcr));
+  __asm__ __volatile__ ("fmove.l %0,%%fpcr" : : "g" (fpcr));
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  have_gcc_asm_for_mc68881=yes
+else
+  have_gcc_asm_for_mc68881=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_gcc_asm_for_mc68881" >&5
+$as_echo "$have_gcc_asm_for_mc68881" >&6; }
+if test "$have_gcc_asm_for_mc68881" = yes
+then
+
+$as_echo "#define HAVE_GCC_ASM_FOR_MC68881 1" >>confdefs.h
+
+fi
+
 # Detect whether system arithmetic is subject to x87-style double
 # rounding issues.  The result of this test has little meaning on non
 # IEEE 754 platforms.  On IEEE 754, test should return 1 if rounding
@@ -14326,6 +14607,49 @@ rm -f conftest*
 
 fi
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for append_history in -lreadline" >&5
+$as_echo_n "checking for append_history in -lreadline... " >&6; }
+if ${ac_cv_lib_readline_append_history+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lreadline $READLINE_LIBS $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char append_history ();
+int
+main ()
+{
+return append_history ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_readline_append_history=yes
+else
+  ac_cv_lib_readline_append_history=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_append_history" >&5
+$as_echo "$ac_cv_lib_readline_append_history" >&6; }
+if test "x$ac_cv_lib_readline_append_history" = xyes; then :
+
+$as_echo "#define HAVE_RL_APPEND_HISTORY 1" >>confdefs.h
+
+fi
+
+
 # End of readline checks: restore LIBS
 LIBS=$LIBS_no_readline
 
@@ -14662,8 +14986,43 @@ $as_echo "#define HAVE_STAT_TV_NSEC2 1" >>confdefs.h
 
 fi
 
+# first curses header check
 ac_save_cppflags="$CPPFLAGS"
 CPPFLAGS="$CPPFLAGS -I/usr/include/ncursesw"
+
+for ac_header in curses.h ncurses.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+# On Solaris, term.h requires curses.h
+for ac_header in term.h
+do :
+  ac_fn_c_check_header_compile "$LINENO" "term.h" "ac_cv_header_term_h" "
+#ifdef HAVE_CURSES_H
+#include 
+#endif
+
+"
+if test "x$ac_cv_header_term_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_TERM_H 1
+_ACEOF
+
+fi
+
+done
+
+
 # On HP/UX 11.0, mvwdelch is a block with a return statement
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether mvwdelch is an expression" >&5
 $as_echo_n "checking whether mvwdelch is an expression... " >&6; }
@@ -15207,7 +15566,7 @@ do
 done
 
 
-SRCDIRS="Parser Grammar Objects Python Modules Mac"
+SRCDIRS="Parser Grammar Objects Python Modules Mac Programs"
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for build directories" >&5
 $as_echo_n "checking for build directories... " >&6; }
 for dir in $SRCDIRS; do
@@ -15348,6 +15707,72 @@ $as_echo "#define HAVE_IPA_PURE_CONST_BUG 1" >>confdefs.h
     esac
 fi
 
+# Check for stdatomic.h
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdatomic.h" >&5
+$as_echo_n "checking for stdatomic.h... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+
+    #include 
+    atomic_int value = ATOMIC_VAR_INIT(1);
+    _Atomic void *py_atomic_address = (void*) &value;
+    int main() {
+      int loaded_value = atomic_load(&value);
+      return 0;
+    }
+
+
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  have_stdatomic_h=yes
+else
+  have_stdatomic_h=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_stdatomic_h" >&5
+$as_echo "$have_stdatomic_h" >&6; }
+
+if test "$have_stdatomic_h" = yes; then
+
+$as_echo "#define HAVE_STD_ATOMIC 1" >>confdefs.h
+
+fi
+
+# Check for GCC >= 4.7 __atomic builtins
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GCC >= 4.7 __atomic builtins" >&5
+$as_echo_n "checking for GCC >= 4.7 __atomic builtins... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+
+    volatile int val = 1;
+    int main() {
+      __atomic_load_n(&val, __ATOMIC_SEQ_CST);
+      return 0;
+    }
+
+
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  have_builtin_atomic=yes
+else
+  have_builtin_atomic=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_builtin_atomic" >&5
+$as_echo "$have_builtin_atomic" >&6; }
+
+if test "$have_builtin_atomic" = yes; then
+
+$as_echo "#define HAVE_BUILTIN_ATOMIC 1" >>confdefs.h
+
+fi
+
 # ensurepip option
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ensurepip" >&5
 $as_echo_n "checking for ensurepip... " >&6; }
@@ -15885,7 +16310,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by python $as_me 3.4, which was
+This file was extended by python $as_me 3.5, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -15947,7 +16372,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-python config.status 3.4
+python config.status 3.5
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
diff --git a/configure.ac b/configure.ac
index 14b3aef6046c..a2c5eb463204 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3,7 +3,7 @@ dnl * Please run autoreconf to test your changes! *
 dnl ***********************************************
 
 # Set VERSION so we only need to edit in one place (i.e., here)
-m4_define(PYTHON_VERSION, 3.4)
+m4_define(PYTHON_VERSION, 3.5)
 
 AC_PREREQ(2.65)
 
@@ -53,6 +53,9 @@ AC_CANONICAL_HOST
 AC_SUBST(build)
 AC_SUBST(host)
 
+# pybuilddir.txt will be created by --generate-posix-vars in the Makefile
+rm -f pybuilddir.txt
+
 if test "$cross_compiling" = yes; then
     AC_MSG_CHECKING([for python interpreter for cross build])
     if test -z "$PYTHON_FOR_BUILD"; then
@@ -522,6 +525,19 @@ then
   AC_DEFINE(_POSIX_C_SOURCE, 200809L, Define to activate features from IEEE Stds 1003.1-2008)
 fi
 
+# On HP-UX mbstate_t requires _INCLUDE__STDC_A1_SOURCE
+case $ac_sys_system in
+  hp*|HP*)
+    define_stdc_a1=yes;;
+  *)
+    define_stdc_a1=no;;
+esac
+
+if test $define_stdc_a1 = yes
+then
+  AC_DEFINE(_INCLUDE__STDC_A1_SOURCE, 1, Define to include mbstate_t for mbrtowc)
+fi
+
 #
 # SGI compilers allow the specification of the both the ABI and the
 # ISA on the command line.  Depending on the values of these switches,
@@ -915,7 +931,7 @@ AC_MSG_CHECKING(LDLIBRARY)
 if test "$enable_framework"
 then
   LDLIBRARY='$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)'
-  RUNSHARED=DYLD_FRAMEWORK_PATH="`pwd`:$DYLD_FRAMEWORK_PATH"
+  RUNSHARED=DYLD_FRAMEWORK_PATH=`pwd`${DYLD_FRAMEWORK_PATH:+:${DYLD_FRAMEWORK_PATH}}
   BLDLIBRARY=''
 else
   BLDLIBRARY='$(LDLIBRARY)'
@@ -933,7 +949,7 @@ if test $enable_shared = "yes"; then
     SunOS*)
 	  LDLIBRARY='libpython$(LDVERSION).so'
 	  BLDLIBRARY='-Wl,-R,$(LIBDIR) -L. -lpython$(LDVERSION)'
-	  RUNSHARED=LD_LIBRARY_PATH=`pwd`:${LD_LIBRARY_PATH}
+	  RUNSHARED=LD_LIBRARY_PATH=`pwd`${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}
 	  INSTSONAME="$LDLIBRARY".$SOVERSION
 	  if test "$with_pydebug" != yes
 	  then
@@ -943,7 +959,7 @@ if test $enable_shared = "yes"; then
     Linux*|GNU*|NetBSD*|FreeBSD*|DragonFly*|OpenBSD*)
 	  LDLIBRARY='libpython$(LDVERSION).so'
 	  BLDLIBRARY='-L. -lpython$(LDVERSION)'
-	  RUNSHARED=LD_LIBRARY_PATH=`pwd`:${LD_LIBRARY_PATH}
+	  RUNSHARED=LD_LIBRARY_PATH=`pwd`${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}
 	  case $ac_sys_system in
 	      FreeBSD*)
 		SOVERSION=`echo $SOVERSION|cut -d "." -f 1`
@@ -965,16 +981,16 @@ if test $enable_shared = "yes"; then
 			;;
 	  esac
 	  BLDLIBRARY='-Wl,+b,$(LIBDIR) -L. -lpython$(LDVERSION)'
-	  RUNSHARED=SHLIB_PATH=`pwd`:${SHLIB_PATH}
+	  RUNSHARED=SHLIB_PATH=`pwd`${SHLIB_PATH:+:${SHLIB_PATH}}
 	  ;;
     Darwin*)
     	LDLIBRARY='libpython$(LDVERSION).dylib'
 	BLDLIBRARY='-L. -lpython$(LDVERSION)'
-	RUNSHARED='DYLD_LIBRARY_PATH=`pwd`:${DYLD_LIBRARY_PATH}'
+	RUNSHARED=DYLD_LIBRARY_PATH=`pwd`${DYLD_LIBRARY_PATH:+:${DYLD_LIBRARY_PATH}}
 	;;
     AIX*)
 	LDLIBRARY='libpython$(LDVERSION).so'
-	RUNSHARED=LIBPATH=`pwd`:${LIBPATH}
+	RUNSHARED=LIBPATH=`pwd`${LIBPATH:+:${LIBPATH}}
 	;;
 
   esac
@@ -1023,6 +1039,15 @@ else
     ASDLGEN="$PYTHON"
 fi
 
+AC_SUBST(OPCODEHGEN)
+AC_CHECK_PROGS(PYTHON, python$PACKAGE_VERSION python3 python, not-found)
+if test "$PYTHON" = not-found; then
+    OPCODEHGEN="@echo python: $PYTHON! cannot run Tools/scripts/generate_opcode_h.py"
+else
+    OPCODEHGEN="$PYTHON"
+fi
+
+
 
 case $MACHDEP in
 bsdos*|hp*|HP*)
@@ -1103,7 +1128,11 @@ then
 	    if test "$Py_DEBUG" = 'true' ; then
 		# Optimization messes up debuggers, so turn it off for
 		# debug builds.
-		OPT="-g -O0 -Wall $STRICT_PROTO"
+                if "$CC" -v --help 2>/dev/null |grep -- -Og > /dev/null; then
+                    OPT="-g -Og -Wall $STRICT_PROTO"
+                else
+                    OPT="-g -O0 -Wall $STRICT_PROTO"
+                fi
 	    else
 		OPT="-g $WRAP -O3 -Wall $STRICT_PROTO"
 	    fi
@@ -1125,6 +1154,7 @@ then
 fi
 
 AC_SUBST(BASECFLAGS)
+AC_SUBST(CFLAGS_NODIST)
 
 # The -arch flags for universal builds on OSX
 UNIVERSAL_ARCH_FLAGS=
@@ -1209,7 +1239,53 @@ yes)
 
     if test $ac_cv_declaration_after_statement_warning = yes
     then
-      BASECFLAGS="$BASECFLAGS -Werror=declaration-after-statement"
+      CFLAGS_NODIST="$CFLAGS_NODIST -Werror=declaration-after-statement"
+    fi
+
+    AC_MSG_CHECKING(if we can turn on $CC mixed sign comparison warning)
+     ac_save_cc="$CC"
+     CC="$CC -Wsign-compare"
+     save_CFLAGS="$CFLAGS"
+     AC_CACHE_VAL(ac_cv_enable_sign_compare_warning,
+       AC_COMPILE_IFELSE(
+         [
+	   AC_LANG_PROGRAM([[]], [[]])
+	 ],[
+           ac_cv_enable_sign_compare_warning=yes
+	 ],[
+           ac_cv_enable_sign_compare_warning=no
+	 ]))
+     CFLAGS="$save_CFLAGS"
+     CC="$ac_save_cc"
+    AC_MSG_RESULT($ac_cv_enable_sign_compare_warning)
+
+    if test $ac_cv_enable_sign_compare_warning = yes
+    then
+      BASECFLAGS="$BASECFLAGS -Wsign-compare"
+    fi
+
+    AC_MSG_CHECKING(if we can turn on $CC unreachable code warning)
+     ac_save_cc="$CC"
+     CC="$CC -Wunreachable-code"
+     save_CFLAGS="$CFLAGS"
+     AC_CACHE_VAL(ac_cv_enable_unreachable_code_warning,
+       AC_COMPILE_IFELSE(
+         [
+	   AC_LANG_PROGRAM([[]], [[]])
+	 ],[
+           ac_cv_enable_unreachable_code_warning=yes
+	 ],[
+           ac_cv_enable_unreachable_code_warning=no
+	 ]))
+     CFLAGS="$save_CFLAGS"
+     CC="$ac_save_cc"
+    AC_MSG_RESULT($ac_cv_enable_unreachable_code_warning)
+
+    # Don't enable unreachable code warning in debug mode, since it usually
+    # results in non-standard code paths.
+    if test $ac_cv_enable_unreachable_code_warning = yes && test "$Py_DEBUG" != "true"
+    then
+      BASECFLAGS="$BASECFLAGS -Wunreachable-code"
     fi
 
     # if using gcc on alpha, use -mieee to get (near) full IEEE 754
@@ -1305,10 +1381,16 @@ yes)
         # 4. If we are running on OS X 10.2 or earlier, good luck!
 
         AC_MSG_CHECKING(which MACOSX_DEPLOYMENT_TARGET to use)
-        cur_target=`sw_vers -productVersion | sed 's/\(10\.[[0-9]]*\).*/\1/'`
-        if test ${cur_target} '>' 10.2 && \
-           test ${cur_target} '<' 10.6
+        cur_target_major=`sw_vers -productVersion | \
+                sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'`
+        cur_target_minor=`sw_vers -productVersion | \
+                sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'`
+        cur_target="${cur_target_major}.${cur_target_minor}"
+        if test ${cur_target_major} -eq 10 && \
+           test ${cur_target_minor} -ge 3 && \
+           test ${cur_target_minor} -le 5
         then
+            # OS X 10.3 through 10.5
             cur_target=10.3
             if test ${enable_universalsdk}
             then
@@ -1533,11 +1615,9 @@ dnl AC_MSG_RESULT($cpp_type)
 
 # checks for header files
 AC_HEADER_STDC
-ac_save_cppflags="$CPPFLAGS"
-CPPFLAGS="$CPPFLAGS -I/usr/include/ncursesw"
-AC_CHECK_HEADERS(asm/types.h conio.h curses.h direct.h dlfcn.h errno.h \
+AC_CHECK_HEADERS(asm/types.h conio.h direct.h dlfcn.h errno.h \
 fcntl.h grp.h \
-ieeefp.h io.h langinfo.h libintl.h ncurses.h process.h pthread.h \
+ieeefp.h io.h langinfo.h libintl.h process.h pthread.h \
 sched.h shadow.h signal.h stdint.h stropts.h termios.h \
 unistd.h utime.h \
 poll.h sys/devpoll.h sys/epoll.h sys/poll.h \
@@ -1549,7 +1629,6 @@ sys/times.h sys/types.h sys/uio.h sys/un.h sys/utsname.h sys/wait.h pty.h \
 libutil.h sys/resource.h netpacket/packet.h sysexits.h bluetooth.h \
 bluetooth/bluetooth.h linux/tipc.h spawn.h util.h alloca.h endian.h \
 sys/endian.h)
-CPPFLAGS=$ac_save_cppflags
 AC_HEADER_DIRENT
 AC_HEADER_MAJOR
 
@@ -1569,14 +1648,6 @@ AC_CHECK_HEADERS([net/if.h], [], [],
 #endif
 ])
 
-
-# On Solaris, term.h requires curses.h
-AC_CHECK_HEADERS(term.h,,,[
-#ifdef HAVE_CURSES_H
-#include 
-#endif
-])
-
 # On Linux, netlink.h requires asm/types.h
 AC_CHECK_HEADERS(linux/netlink.h,,,[
 #ifdef HAVE_ASM_TYPES_H
@@ -2015,12 +2086,14 @@ then
 		# Use -undefined dynamic_lookup whenever possible (10.3 and later).
 		# This allows an extension to be used in any Python
 
-		if test ${MACOSX_DEPLOYMENT_TARGET} '>' 10.2
+		dep_target_major=`echo ${MACOSX_DEPLOYMENT_TARGET} | \
+				sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'`
+		dep_target_minor=`echo ${MACOSX_DEPLOYMENT_TARGET} | \
+				sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'`
+		if test ${dep_target_major} -eq 10 && \
+		   test ${dep_target_minor} -le 2
 		then
-			LDSHARED='$(CC) -bundle -undefined dynamic_lookup'
-			LDCXXSHARED='$(CXX) -bundle -undefined dynamic_lookup'
-			BLDSHARED="$LDSHARED"
-		else
+			# building for OS X 10.0 through 10.2
 			LDSHARED='$(CC) -bundle'
 			LDCXXSHARED='$(CXX) -bundle'
 			if test "$enable_framework" ; then
@@ -2034,6 +2107,11 @@ then
 				LDSHARED="$LDSHARED "'-bundle_loader $(BINDIR)/python$(VERSION)$(EXE)'
 				LDCXXSHARED="$LDCXXSHARED "'-bundle_loader $(BINDIR)/python$(VERSION)$(EXE)'
 			fi
+		else
+			# building for OS X 10.3 and later
+			LDSHARED='$(CC) -bundle -undefined dynamic_lookup'
+			LDCXXSHARED='$(CXX) -bundle -undefined dynamic_lookup'
+			BLDSHARED="$LDSHARED"
 		fi
 		;;
 	Linux*|GNU*|QNX*)
@@ -2219,6 +2297,9 @@ AC_MSG_RESULT($SHLIBS)
 AC_CHECK_LIB(sendfile, sendfile)
 AC_CHECK_LIB(dl, dlopen)	# Dynamic linking for SunOS/Solaris and SYSV
 AC_CHECK_LIB(dld, shl_load)	# Dynamic linking for HP-UX
+AC_CHECK_LIB(crypto, RAND_egd,
+             AC_DEFINE(HAVE_RAND_EGD, 1,
+             [Define if the libcrypto has RAND_egd]))
 
 # only check for sem_init if thread support is requested
 if test "$with_threads" = "yes" -o -z "$with_threads"; then
@@ -2303,6 +2384,17 @@ esac
 ],
 [AC_MSG_RESULT(default)])
 
+AC_MSG_CHECKING(for --with-address-sanitizer)
+AC_ARG_WITH(address_sanitizer,
+            AS_HELP_STRING([--with-address-sanitizer],
+                           [enable AddressSanitizer]),
+[
+AC_MSG_RESULT($withval)
+BASECFLAGS="-fsanitize=address -fno-omit-frame-pointer $BASECFLAGS"
+LDFLAGS="-fsanitize=address $LDFLAGS"
+],
+[AC_MSG_RESULT(no)])
+
 # Most SVR4 platforms (e.g. Solaris) need -lsocket and -lnsl.
 AC_CHECK_LIB(nsl, t_open, [LIBS="-lnsl $LIBS"]) # SVR4
 AC_CHECK_LIB(socket, socket, [LIBS="-lsocket $LIBS"], [], $LIBS) # SVR4 sockets
@@ -2316,7 +2408,7 @@ LIBS="$withval $LIBS"
 ],
 [AC_MSG_RESULT(no)])
 
-AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
+PKG_PROG_PKG_CONFIG
 
 # Check for use of the system expat library
 AC_MSG_CHECKING(for --with-system-expat)
@@ -2916,7 +3008,7 @@ fi
 AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
  clock confstr ctermid dup3 execv faccessat fchmod fchmodat fchown fchownat \
  fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
- futimens futimes gai_strerror \
+ futimens futimes gai_strerror getentropy \
  getgrouplist getgroups getlogin getloadavg getpeername getpgid getpid \
  getpriority getresuid getresgid getpwent getspnam getspent getsid getwd \
  if_nameindex \
@@ -3234,6 +3326,7 @@ AC_CHECK_FUNCS(gettimeofday,
 
 AC_CHECK_FUNCS(clock_gettime, [], [
     AC_CHECK_LIB(rt, clock_gettime, [
+        LIBS="$LIBS -lrt"
         AC_DEFINE(HAVE_CLOCK_GETTIME, 1)
         AC_DEFINE(TIMEMODULE_LIB, [rt],
                   [Library needed by timemodule.c: librt may be needed for clock_gettime()])
@@ -3788,6 +3881,19 @@ then
     [Define if we can use gcc inline assembler to get and set x87 control word])
 fi
 
+AC_MSG_CHECKING(whether we can use gcc inline assembler to get and set mc68881 fpcr)
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[
+  unsigned int fpcr;
+  __asm__ __volatile__ ("fmove.l %%fpcr,%0" : "=g" (fpcr));
+  __asm__ __volatile__ ("fmove.l %0,%%fpcr" : : "g" (fpcr));
+]])],[have_gcc_asm_for_mc68881=yes],[have_gcc_asm_for_mc68881=no])
+AC_MSG_RESULT($have_gcc_asm_for_mc68881)
+if test "$have_gcc_asm_for_mc68881" = yes
+then
+    AC_DEFINE(HAVE_GCC_ASM_FOR_MC68881, 1,
+    [Define if we can use gcc inline assembler to get and set mc68881 fpcr])
+fi
+
 # Detect whether system arithmetic is subject to x87-style double
 # rounding issues.  The result of this test has little meaning on non
 # IEEE 754 platforms.  On IEEE 754, test should return 1 if rounding
@@ -4209,6 +4315,10 @@ then
   [Define if you can turn off readline's signal handling.]), )
 fi
 
+AC_CHECK_LIB(readline, append_history,
+	AC_DEFINE(HAVE_RL_APPEND_HISTORY, 1,
+        [Define if readline supports append_history]), ,$READLINE_LIBS)
+
 # End of readline checks: restore LIBS
 LIBS=$LIBS_no_readline
 
@@ -4378,8 +4488,19 @@ then
   [Define if you have struct stat.st_mtimensec])
 fi
 
+# first curses header check
 ac_save_cppflags="$CPPFLAGS"
 CPPFLAGS="$CPPFLAGS -I/usr/include/ncursesw"
+
+AC_CHECK_HEADERS(curses.h ncurses.h)
+
+# On Solaris, term.h requires curses.h
+AC_CHECK_HEADERS(term.h,,,[
+#ifdef HAVE_CURSES_H
+#include 
+#endif
+])
+
 # On HP/UX 11.0, mvwdelch is a block with a return statement
 AC_MSG_CHECKING(whether mvwdelch is an expression)
 AC_CACHE_VAL(ac_cv_mvwdelch_is_expression,
@@ -4675,7 +4796,7 @@ do
 done
 
 AC_SUBST(SRCDIRS)
-SRCDIRS="Parser Grammar Objects Python Modules Mac"
+SRCDIRS="Parser Grammar Objects Python Modules Mac Programs"
 AC_MSG_CHECKING(for build directories)
 for dir in $SRCDIRS; do
     if test ! -d $dir; then
@@ -4767,6 +4888,47 @@ if test "$have_gcc_asm_for_x87" = yes; then
     esac
 fi
 
+# Check for stdatomic.h
+AC_MSG_CHECKING(for stdatomic.h)
+AC_LINK_IFELSE(
+[
+  AC_LANG_SOURCE([[
+    #include 
+    atomic_int value = ATOMIC_VAR_INIT(1);
+    _Atomic void *py_atomic_address = (void*) &value;
+    int main() {
+      int loaded_value = atomic_load(&value);
+      return 0;
+    }
+  ]])
+],[have_stdatomic_h=yes],[have_stdatomic_h=no])
+
+AC_MSG_RESULT($have_stdatomic_h)
+
+if test "$have_stdatomic_h" = yes; then
+    AC_DEFINE(HAVE_STD_ATOMIC, 1,
+              [Has stdatomic.h, atomic_int and _Atomic void* types work])
+fi
+
+# Check for GCC >= 4.7 __atomic builtins
+AC_MSG_CHECKING(for GCC >= 4.7 __atomic builtins)
+AC_LINK_IFELSE(
+[
+  AC_LANG_SOURCE([[
+    volatile int val = 1;
+    int main() {
+      __atomic_load_n(&val, __ATOMIC_SEQ_CST);
+      return 0;
+    }
+  ]])
+],[have_builtin_atomic=yes],[have_builtin_atomic=no])
+
+AC_MSG_RESULT($have_builtin_atomic)
+
+if test "$have_builtin_atomic" = yes; then
+    AC_DEFINE(HAVE_BUILTIN_ATOMIC, 1, [Has builtin atomics])
+fi
+
 # ensurepip option
 AC_MSG_CHECKING(for ensurepip)
 AC_ARG_WITH(ensurepip,
diff --git a/pyconfig.h.in b/pyconfig.h.in
index 29e1bfa89afe..507a7ab18326 100644
--- a/pyconfig.h.in
+++ b/pyconfig.h.in
@@ -101,6 +101,9 @@
 /* Define if `unsetenv` does not return an int. */
 #undef HAVE_BROKEN_UNSETENV
 
+/* Has builtin atomics */
+#undef HAVE_BUILTIN_ATOMIC
+
 /* Define this if you have the type _Bool. */
 #undef HAVE_C99_BOOL
 
@@ -313,6 +316,9 @@
 /* Define to 1 if you have the `gamma' function. */
 #undef HAVE_GAMMA
 
+/* Define if we can use gcc inline assembler to get and set mc68881 fpcr */
+#undef HAVE_GCC_ASM_FOR_MC68881
+
 /* Define if we can use x64 gcc inline assembler */
 #undef HAVE_GCC_ASM_FOR_X64
 
@@ -329,6 +335,9 @@
 /* Define this if you have flockfile(), getc_unlocked(), and funlockfile() */
 #undef HAVE_GETC_UNLOCKED
 
+/* Define to 1 if you have the `getentropy' function. */
+#undef HAVE_GETENTROPY
+
 /* Define to 1 if you have the `getgrouplist' function. */
 #undef HAVE_GETGROUPLIST
 
@@ -672,6 +681,9 @@
 /* Define to 1 if you have the `pwrite' function. */
 #undef HAVE_PWRITE
 
+/* Define if the libcrypto has RAND_egd */
+#undef HAVE_RAND_EGD
+
 /* Define to 1 if you have the `readlink' function. */
 #undef HAVE_READLINK
 
@@ -687,6 +699,9 @@
 /* Define to 1 if you have the `renameat' function. */
 #undef HAVE_RENAMEAT
 
+/* Define if readline supports append_history */
+#undef HAVE_RL_APPEND_HISTORY
+
 /* Define if you have readline 2.1 */
 #undef HAVE_RL_CALLBACK
 
@@ -865,6 +880,9 @@
 /* Define to 1 if you have the  header file. */
 #undef HAVE_STDLIB_H
 
+/* Has stdatomic.h, atomic_int and _Atomic void* types work */
+#undef HAVE_STD_ATOMIC
+
 /* Define to 1 if you have the `strdup' function. */
 #undef HAVE_STRDUP
 
@@ -1382,6 +1400,9 @@
 /* Define on Linux to activate all library features */
 #undef _GNU_SOURCE
 
+/* Define to include mbstate_t for mbrtowc */
+#undef _INCLUDE__STDC_A1_SOURCE
+
 /* This must be defined on some systems to enable large file support. */
 #undef _LARGEFILE_SOURCE
 
diff --git a/setup.py b/setup.py
index d7f52afc81b5..0f88e78c6164 100644
--- a/setup.py
+++ b/setup.py
@@ -3,6 +3,8 @@
 
 import sys, os, importlib.machinery, re, optparse
 from glob import glob
+import importlib._bootstrap
+import importlib.util
 import sysconfig
 
 from distutils import log
@@ -17,6 +19,17 @@
 
 cross_compiling = "_PYTHON_HOST_PLATFORM" in os.environ
 
+# Add special CFLAGS reserved for building the interpreter and the stdlib
+# modules (Issue #21121).
+cflags = sysconfig.get_config_var('CFLAGS')
+py_cflags_nodist = sysconfig.get_config_var('PY_CFLAGS_NODIST')
+sysconfig.get_config_vars()['CFLAGS'] = cflags + ' ' + py_cflags_nodist
+
+class Dummy:
+    """Hack for parallel build"""
+    ProcessPoolExecutor = None
+sys.modules['concurrent.futures.process'] = Dummy
+
 def get_platform():
     # cross build
     if "_PYTHON_HOST_PLATFORM" in os.environ:
@@ -165,6 +178,9 @@ class PyBuildExt(build_ext):
     def __init__(self, dist):
         build_ext.__init__(self, dist)
         self.failed = []
+        self.failed_on_import = []
+        if '-j' in os.environ.get('MAKEFLAGS', ''):
+            self.parallel = True
 
     def build_extensions(self):
 
@@ -244,9 +260,13 @@ def build_extensions(self):
 
         build_ext.build_extensions(self)
 
-        longest = max([len(e.name) for e in self.extensions])
-        if self.failed:
-            longest = max(longest, max([len(name) for name in self.failed]))
+        for ext in self.extensions:
+            self.check_extension_import(ext)
+
+        longest = max([len(e.name) for e in self.extensions], default=0)
+        if self.failed or self.failed_on_import:
+            all_failed = self.failed + self.failed_on_import
+            longest = max(longest, max([len(name) for name in all_failed]))
 
         def print_three_column(lst):
             lst.sort(key=str.lower)
@@ -274,6 +294,14 @@ def print_three_column(lst):
             print_three_column(failed)
             print()
 
+        if self.failed_on_import:
+            failed = self.failed_on_import[:]
+            print()
+            print("Following modules built successfully"
+                  " but were removed because they could not be imported:")
+            print_three_column(failed)
+            print()
+
     def build_extension(self, ext):
 
         if ext.name == '_ctypes':
@@ -287,6 +315,15 @@ def build_extension(self, ext):
                           (ext.name, sys.exc_info()[1]))
             self.failed.append(ext.name)
             return
+
+    def check_extension_import(self, ext):
+        # Don't try to import an extension that has failed to compile
+        if ext.name in self.failed:
+            self.announce(
+                'WARNING: skipping import check for failed build "%s"' %
+                ext.name, level=1)
+            return
+
         # Workaround for Mac OS X: The Carbon-based modules cannot be
         # reliably imported into a command-line Python
         if 'Carbon' in ext.extra_link_args:
@@ -327,10 +364,12 @@ def build_extension(self, ext):
             return
 
         loader = importlib.machinery.ExtensionFileLoader(ext.name, ext_filename)
+        spec = importlib.util.spec_from_file_location(ext.name, ext_filename,
+                                                      loader=loader)
         try:
-            loader.load_module()
+            importlib._bootstrap._load(spec)
         except ImportError as why:
-            self.failed.append(ext.name)
+            self.failed_on_import.append(ext.name)
             self.announce('*** WARNING: renaming "%s" since importing it'
                           ' failed: %s' % (ext.name, why), level=3)
             assert not self.inplace
@@ -340,17 +379,6 @@ def build_extension(self, ext):
                 os.remove(newname)
             os.rename(ext_filename, newname)
 
-            # XXX -- This relies on a Vile HACK in
-            # distutils.command.build_ext.build_extension().  The
-            # _built_objects attribute is stored there strictly for
-            # use here.
-            # If there is a failure, _built_objects may not be there,
-            # so catch the AttributeError and move on.
-            try:
-                for filename in self._built_objects:
-                    os.remove(filename)
-            except AttributeError:
-                self.announce('unable to remove files (ignored)')
         except:
             exc_type, why, tb = sys.exc_info()
             self.announce('*** WARNING: importing extension "%s" '
@@ -693,7 +721,9 @@ def detect_modules(self):
         if host_platform == 'darwin':
             os_release = int(os.uname()[2].split('.')[0])
             dep_target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET')
-            if dep_target and dep_target.split('.') < ['10', '5']:
+            if (dep_target and
+                    (tuple(int(n) for n in dep_target.split('.')[0:2])
+                        < (10, 5) ) ):
                 os_release = 8
             if os_release < 9:
                 # MacOSX 10.4 has a broken readline. Don't try to build
@@ -827,15 +857,6 @@ def detect_modules(self):
         exts.append( Extension('_sha1', ['sha1module.c'],
                                depends=['hashlib.h']) )
 
-        # SHA-3 (Keccak) module
-        sha3_depends = ['hashlib.h']
-        keccak = os.path.join(os.getcwd(), srcdir, 'Modules', '_sha3',
-                              'keccak')
-        for pattern in ('*.c', '*.h', '*.macros'):
-            sha3_depends.extend(glob(os.path.join(keccak, pattern)))
-        exts.append(Extension("_sha3", ["_sha3/sha3module.c"],
-                              depends=sha3_depends))
-
         # Modules that provide persistent dictionary-like semantics.  You will
         # probably want to arrange for at least one of them to be available on
         # your machine, though none are defined by default because of library
@@ -1027,8 +1048,16 @@ class db_found(Exception): pass
             if db_setup_debug:
                 print("bsddb using BerkeleyDB lib:", db_ver, dblib)
                 print("bsddb lib dir:", dblib_dir, " inc dir:", db_incdir)
-            db_incs = [db_incdir]
             dblibs = [dblib]
+            # Only add the found library and include directories if they aren't
+            # already being searched. This avoids an explicit runtime library
+            # dependency.
+            if db_incdir in inc_dirs:
+                db_incs = None
+            else:
+                db_incs = [db_incdir]
+            if dblib_dir[0] in lib_dirs:
+                dblib_dir = None
         else:
             if db_setup_debug: print("db: no appropriate library found")
             db_incs = None
@@ -1139,11 +1168,13 @@ class db_found(Exception): pass
             # can end up with a bad search path order.
             if sqlite_incdir not in self.compiler.include_dirs:
                 include_dirs.append(sqlite_incdir)
+            # avoid a runtime library path for a system library dir
+            if sqlite_libdir and sqlite_libdir[0] in lib_dirs:
+                sqlite_libdir = None
             exts.append(Extension('_sqlite3', sqlite_srcs,
                                   define_macros=sqlite_defines,
                                   include_dirs=include_dirs,
                                   library_dirs=sqlite_libdir,
-                                  runtime_library_dirs=sqlite_libdir,
                                   extra_link_args=sqlite_extra_link_args,
                                   libraries=["sqlite3",]))
         else:
@@ -1208,7 +1239,7 @@ class db_found(Exception): pass
                                 libraries = gdbm_libs)
                             break
                 elif cand == "bdb":
-                    if db_incs is not None:
+                    if dblibs:
                         if dbm_setup_debug: print("building dbm using bdb")
                         dbmext = Extension('_dbm', ['_dbmmodule.c'],
                                            library_dirs=dblib_dir,
@@ -1544,7 +1575,7 @@ class db_found(Exception): pass
 
         if 'd' not in sys.abiflags:
             ext = Extension('xxlimited', ['xxlimited.c'],
-                            define_macros=[('Py_LIMITED_API', 1)])
+                            define_macros=[('Py_LIMITED_API', '0x03040000')])
             self.extensions.append(ext)
 
         return missing